xine-lib-1.2/0000755000175000017500000000000014647725303010662 5ustar memexine-lib-1.2/misc/0000755000175000017500000000000014647725152011617 5ustar memexine-lib-1.2/misc/fonts/0000755000175000017500000000000014647725152012750 5ustar memexine-lib-1.2/misc/fonts/mono-16.xinefont.gz0000644000175000017500000002460114647725152016342 0ustar meme]}IY fK.% ( t*ҥ46, ؉bw]ι=g{y33O|7[u\ nn6^6yG[(cZX..EyZOwmS!AOcp%Ӄ0}}sI!D.G11%!7t>K'{~ X،JJLW IGosL0[d1~NfJޅ2Y#|Cm&2wOVY7G r*8GxPә tcA>ϞHuͻ.^Z>&':@f}I$.rNaGlue~9WdO7 Sv',й`a0/AF@P^(+EI~ ;F 7C˘#dIilEx[Jm,w%V^wqd3:fUJ$3}hx敽|(挲# EuKmۙDxPz;Ǖ2:IH3MQG}wyDnhxk}+ ^.a90y|QZyQV/9)̋b.^V=#piq_(f߳z?{^g+u 7pzvoՑf,HkuVI"5"J:/1,^4M14s0@qYfAxxm*Y8Q%" Eɬ.+vcy;*̥/2JKlבX}""3dLtNE1##NQeLSIkg@>ynRh7ã:+ ||GڳXة)N>L[Tf]nTf=%CYU*m(` ;]y1LA1׼:PQWYPqf=oA^,D h/{7+Xls̶=o7)<+>VTU Kl#ξt =Km׸/ۡc?vÅi2hݙ': ;Ny" W+-nXXTaThA9 v;ҨZC۟AVuۈ[o~v'Tq#ɞ$ztM3l,:  ~^zRx)zt*SLV2,1ѯ!~Eez6um|12(DlwDWdZ+ Tz5L!>$yדꌹHlK If"5zRY9d-'olZ\J>-$#[FY=U4p>0bK}41q!-?=`|ܠ" _ĢV_X)O=ofj3a%: =♿]mӎ jٿO Y48uFyT G`]v=ȭA؀ȪLW}rDs*3<*3G/?%ӡ4]~`4d0v[~Μ#8FQR f < +6.*V_Ygm㛹 0~K:֙}7\ ٟ[vh1ό0ř ;u'A#a{[ !~L.6KZ~,IC7ӃAO(͑1Fo5TTԴH^/= 9K{ i$*FE`SrB|/;} v f"chn?$B֫ij7|+m mʼniʰGB[ٍcêQؠy/=iT&6Ƽ`JlK?@j"d׭njĚgE'7b.M_@FуAwBi:P<Τ#7BaNmPqenӨNը:ojYf|@r f2{V8b o̟U~<f3:g\3-'1mA+‚a{jF`gvpթw8E#sH]VNg#мgfrutN]uΤb`NOォM1{i!=yěOt&:æ  VDd$26Ÿ qzu|oI#B6O6ɼ (?czk]'* HF7Cd7 &kj'Yg˖C'*[L׽F*Yr zM" \OX@ḋ~ 8 Bh}f5K A[x}7U,E= +Bg?d@_k OCxAb5ṎfD7#sOME0hzSs ˌjp"O\;_x!6"UH)a &ٍ"r~Nd\Pbr:Irf5fklFvZO86C*.@ 6cNidV^1jLrCh,"Nzc^+GZ5A㸙,KggϘ ^6+%hF.Irp9헝LnCκ-+ 7}^)i|WW,%֔ŸAQ^'"dG%wL8&+^Z9%4& c@"3NUĻ1ŸJ C\z %FQ$BN0-þjG@d ȣA-ɢ&4X!s67q-7v|$J5}zTA]$@V+ Ƞ$a'f!DW0-fw~fZs9XQDkE,ZxI^r0X#LREOu9b1k K:aT@1s8qЙX`o yi e"0X p^S(NS> 0)Aw8gEd.T-{oo: eq8b|Dث|gs%5n S~KmFX(U]W`B/m]MeA(]8S8_"f͜ۻlQB(T2rn߱W;ϲ^R;)6HMմXMLhrFݵBRФc1$a}(`Z 1Q{FX>vJreSsL"4xqVw^Z CHK4ŦKKQ r#oj\R8Vfurl(@!C-Vh$0ث5x>Lo8 LxAZKSVb+C *e*riS-kHBU$ JT0JB# 4qǘYPGbA"0lͬ<&0ntȜ8Ip  yU Y!0Y?|`ke;ia5LRZK$Y9TΒx&#=oفJAGeRx27{;~Y+$!2"ԸNjPgI1%Udg]Q)t"6Ǽ$ݞB;uRX8'޵R&HvR% k D.%c.S0u8(3ң!QD ֹo, @: b*.=2ga>_]%Y9/zF Lf'i7Ía9TӢLiV^EϨuRXX_(rY8WjiYMnX-R5hK\mH܅I}sSdh+xޥ w5 \Ks~tS$H*iŮJBbz "qh{á^~\{Wzk!7\Lڈ爹5X0wJdz^ EFjUh3rG bxU¿fsڸCPDzWIۯ"`S >`(;p_Ρ1T"\5m&C:6,R+O]coъV2aL8ʄ6'ld:9|Łpgt+ `˕Ww׮g\LI?4%a=%@fKT՛h$(&i]vPws`؇BD63ss޹x~(+ϭYCOy2Kx\s]w qa ,}'8 |GOq&"`ȾCM@;p1(Iʖf7f1^B[L '̇bh{o R|Ο{15,ht"z\ c%'ff%dٵB'z"~Ŵ{9C!X8$jN:ûvOĦ!<ĜY1]T]T}YT/vCb]To6C#XW{b|[O!l<1sϮǮY %O.I+mM^{.fcR9`3'q'FZoFd3 (D{qN6>h6pe=Q06/G(M}8Șx'OE {!mcS6q W|NaDT,_uҞ0!)'Qx|{fI̤jE: bK1*3 _e;[%1J0`Og `# ȀGbQ >8&J#XjďaRd!u$eim u?ㄺc}) j_Xl"%UK?rZH40 G \Uȱse-lk# szL4qulV1yzRDy¤SOܮ3ʙx͙xr+2-kgTb%?6)[kZkj#oFQ÷QZO [ꍔ|Ά|ļSz]wQ,փmȝPj=p~cw8ak>u[*mߒ>~>[rUl}՗v]6߫ijM(wh ~y i3 -O<nDRrr [>/;+Xz%F5Yܥ4JtoC_sg `w-[^,e@JzQzJwz6;IFU2q-J.jə-jQ>{-mK[ R&JI/9hη/\n kFt##!K6R{yʨ'NJg6\F01VSvܲN-[,a,}+'@I$ҷ+IAI]'d;@{Q9 &!mwtͺYVb|{ ՞|YYؒ;1=nO K⽝wF=zz]zߝl>tt2&'I {uq2MوaW7v[(mۘѻr x"|٦.,5 /`ĈXưڋ ,kh 4gVRk9BӤv ظL*V0v8=(!mOq'vQmo#r8oӦ1[p]xc4FseG{ 32ѲMqHӑU&Iy$ r  "#L7UbJ3'{ Ǔ gI\ll{Oo; DʔD.zG6uǐ*Lm@HBP*S 3v8Amʓ-Hˉȴ"{u F@p!7k :PN6UxO| y+L*@hqX<+6{ O%|$++Mdҍ%7bҝeuǰŠZ-R`"Ϫr0Ld#N]nӾ҉;m&bڸ&y;\Fe $hnSu#7.t19„@ɔFܥx.towݴL;S7N%Q >֩Q*NI-o?~FXANKT~i {@b*:< w;>XŘxKR;O&nuNjm؁D"uH1`TػmS\|+"ك5 j31ΙB=E&.D<%K!ljH"Q i=~m"Լi*y3)lQsi ӑRhMLH";flc J<ȑv O5LN۴ e<<۾SfkMQ- . k}i~h=rkɈsޙw1[d_Dvh$'xo_{Ӊ%+,(˛gqm"M3@nh.?,B{T2,0tq(>'JGA͂]aBu]FL,-=C $ P*l3?nttܠ2}-1F}V2@$cPk׈,iQôR+khpL;Ib'TSә"hVA u8L6Kd\~XrN*,Q?F=J9k ]f2Ԣ3K@5s$w mMQM% haf0OS9pxi;@g>⧼X#||K$ z,z+à,& S5?~L(l:|3>btV F;mxw_ ` tOo vy2>QgZV$!IC l> ~QH@ ]B@vc7kGdL5Jqy L}wġ2*G<)ia~e6=3wB}7wVSfiN]ǞS Vel#)E|;*΅C\<ji u4✌ 8+~Z;o1pbGd$7a@+}yJ։h#^ gl.Uuijmً;~\8:*J p,Iމ(]t.ގg:L)B+.-bIH>E.†4L=|KRbsCHY^iTA.21O sG~8~T<"B:@)EKnU3c2nganR) "F]26qNIzPQ<m^YG< bE/}&=(i0'e+7lD&.sR3i"F#t䌱MGk]5zhkfYzj3M4M2CAb4ݿ^b",۟}™v,qPi26 ts,}"(x;hEeb$&("OYg}r :L؞ƚHvRJ9F (d'Io>ZI溜P]d$sm$9R@} #sγ4O -Du} *GeZ[Уuvx=XHmB/yDs(o- MB*I"VJ/a/T2Wk{ᬜS8ņWvK[EKTۺ}R?< mHo!V h!"MCŊ{!T0y諺p;=i @Z6i"0SEc)MRY{bp 7y^`wqvݹ^;j:ٓ?ym~ QqB^M!N}Gq%p.|V)7ʵkjО&IW™b@J0Na]tj{AB*׭ƮL/ xحh.o4;jTn*]s865hekxl=x#8b] dP4j#1 gqkItl56 %d b!σ]Rd6Qzq|qASwAvTRS즲:XqK92))jq\H+&ODL> >h 'sPn;pߴ dRO1h[}~\HaaFđjb5<#+ sy}a z[#@*KJ%#e6xine-lib-1.2/misc/fonts/sans-24.xinefont.gz0000644000175000017500000005357414647725152016350 0ustar meme}4Kv.lV}Mx H$AH  N !@p X uTwϝ;w|~S3u~myMoݴ"?Zʲ,2HqCmip RaiRJ2S؛p'u7,l>+bN?s_ݣ90 VN?,2i9 fu/ֲcJ4|`}C'r{LTOpj:5 2 :oV蛭Wm^2r7jNO4ֻQޥ#^_麴} z+D=D#5.nQRG-k7KWjn楂&Z4^\\WpfDa]:|^<.I?/蚥o{-( f~FjCv0"3w ź~0BU|)EpWj^(]W [_Ȭ%|5 CkR 0(pH:sߵU`©}p#|KeGw߼q_)kGd00Krخz/j-K3o0~rɡw/aƐ?Y+d h0D!1xFu6ܸ:\6d_?mY~7ySgܒ_ p7Fhr@>Vtal{nt^ $q,0fD?>rI=Ĵ n."dYrR_YV aFe$\^f.v]?I'+ϝeGf:.;}BA)UJ붲qމ-jD;g HmH*!x>~G>V0{Hve; ~Xq PvѺpAgts*>aU>*^w #sTB@@}x9Ff}w?[ym[ U->SՖU@_}[¨Sw׀aIv'c&}p3.$󐤛I(+]l$8dh gs D{􌚜ݵ.H:m6[о%T2z[c&|l>U5Z <6ڣn]\""np,a?dٵ}SFC O^7 lUI?)sF%X@ѵǨ3_w`E$0Nκ"Q/&Ms}eaUhI/B\7"_ƶYonKUJ~;g@*Ž]Ԑr[ oº]C}8mk !k Q{I ӊ dR3V;\dnXT^Qր'=@2cff%1j={vŽU1gvOᆰA욍ϖ`Dh224z-;&`1HDcSiEVNy VBFUquGN Ȅe}`~ $@@/8I bJ&5r'~FZ|eYUR\y22-)*(lXܚUCZ4`@+ ):ĺ0U.ܓ,A.[^XUib%& c^$ޮ`rKύ$-EqU5ȤA־WA`c|K<jD: cF+ ];q3Vx- s6*9:wҀ*Y4[F}ںh[8dwlm ׼o.r,M]-V|/ ;#dcQ@s4&4EF -߹\6EM)oy)Wv11Ю6^ˈ)}K )=@pD ojqR7\׷fmN@ͫln=n8_wQ\:,8+'ү#3}4Ӻc0?#`b4Ɩ&AHy>AM6A7^4z|!S7 a0ȧLR:E"%c ̱TX:gGfX[ U VK򊸺Cx~@@x+KQKN+cքi5O>~Rw6}5dioVfn"=S+0 wM5RFw$cH fהh[$6]@^!&BgaFa"Hרsrܫ_j$vq{f\uh?"v"B!{f9݅83CF}lS@cJmC6"-phԇۨ< Jl+LAA0CmAr#Mr#8T_a=ݷʓbÔ lFXw*A^K")BW+7l lQ(e-7y 7 G)d SMAQ=:Hf`I&fBReEh/lK  &߈e [th^^ (.{B$;UJU12#'Pf4 z80> V$/9 aB+d8&;mhsRozA)m ex=۸fDF8J NGЛ!pŽ DiShMve~ȷ&҈IhLjBr[܁MNT^s?*M=dڶTy;xCp2,$Gnno!1oSrqWQ{ᅅpe({a2IdŲZ#Wf_PŸ,Wc156>f6l`lKz^DB´s7fyv(MLT2CY I3T&N?IuHw5/NZ|'6A4zERJ D^YfwaY$ӵ䆈̘"9kG=_b[bQ\&A<4Q8)!㳲GѪ_x;7$R 18adƛ> ǻ;b&ŏiF#ڑ| 5-W 6&VFcAŗr6s-Rs[r7X&`#b gkoӘD.| ZKv/ /76 " r^A1QDs܋/Yas #"ٍlQ+ ׽Z'ؐ9G S柁Q')(kV02 ư^[Je$ԒP}U5D--O%L#d{9ڗ^,(`m ߭rB$3(5K1"[Y-9Ll>\rFtvbAyhHH H:12 s:] M挿Aow~80ꌥɖ u̒TpVMW ]c YY8VfrQ'J/VReTˈfIoC&w{.j67~m%HnE"\d!QsoT!\;/|mY7ղh)i!L4Mfb=6^'/ Q̉h# (+i}])wH×?m3W]34Wl5ËLgdpH,+{Jb>9/gЅ]̜]1 fx`\@YӐw1{NqA& zIH/[h4Y5L GV zy|Ʉ]#4J=xdE]9[ΑIB2!uRE^/x[hd=;H=eSj.2hz!f/ 'BJubT:Ҙ8ҧb$d&ӊsujE<_/ -?G)Fk/CK}6}b$ILfTYQ T;V4 c)nCv4cͫu>gU(a |(ɭ(̦xkZgbJ#CiV~B#RN!N_d EK+ڬx$7o6+`I7+9m4h BBt0׏Xx7^ "ۙTM][dՅɰ1xA$j2A>ӆ b>1ڳߋG{c׷8![6B{=N Q%@6 DqV72~vQ[]h+{IH*Y$^FDPlhǿ%Q~y+</EJP2-(7u-h,SkQpw > YSt<9{p_L0MCUqaG8f꯲߼[7MBuOrY/@1g솒A lI.zMO|&ZaKOkAQ?@hFR&NY$>{mINFw$-Ik)kOS_߇OyۣpLqshU3,zm:8_&drHs*}Tdz|)mcVh^gh熖n+J} én^F.Q)Vt qx%out~]r^L1m2ą&'&9M4bb3>ĉi,ܸDLκQg"0Ծ䘑EDE^"#GZSV-{meDcj֏{ AS>aڈ$vh;&zd [hi35r} ߼Yf)b6p\$REY..e|K ];j ʛpew1mr,&Y^CV! \.|&?. &TVB5H7xxR=CtirHmHN[~R GI9ĘS_湁N8Q ? ǝO y @"Lm`HC$&jr3yh 4WLI*,K H|CŽqFERl%2Y3yI(KG `]6QQ6$Cyac A(L1hq9HAӋeǜocftMXMy94;-* i(.? epi{ g2FYʐ.*O,6WZc]ǘ8]- Yմfi1TFCYvc[L 9O{mmvyQV&[9¥[fy/ӟJ.t)%:ʛޭN>r+lw ǺD39%(yai`בIsʀ\]ECEaGBiF+4BPOI{D1T*#9Dbr|++Wu_a46ke6kiYV~Ƶg;n,>.5[4Tx kd K骠1uHҌK ZePt>:L.K8 }(R!OV?4o]*6U5*j6r0}U9:ZRi#H9݌7=]Un8>3JLWj"D&-IRPT 'hj߹ @gDN[u KYν,}/,;c>g >F]βbg|i^uօls* R$?F6F lK$7L58K>͎%W;irzhϊW)ew%x1:/s1?M|9yyA`@ϝ 2%߱;2Cp#Z9"蜤b P]L@KqtǸܹs?[\*8尲#[ʋC%>ÓL7TeCx/hNe7H!l`tSʌ Ǻ}W P1l$ n<|D!+44T /)^$|/nYHVپAW }39.pHOn&gF9ot8׬[#!5ѿ[(g2Ɉ2>6b}Xnk) EΦ,ɄYng X\>Da0iа\Ln.1X[3\1,+egp@_w5\~u&^=PNҌox??! ;g>& uAk:laNh ':NC9cG{D{ Rj&{I$]9=q9 D֒c,cQtd8֝r]99C_):~([7@' fm"ŁnB#!ܹX[7æЄE9ǿfY1]9fmr8yopZW[I֋'r!,760[iN𓲚ɵ.yyUBÞ㷭ڻ☤BdW;wPF/oz˨4T25LL c 1uqGoeZrfsf& `&qY ֲJ4¢1jjoÈw_B 1rB7J0v H`Px,FY FELL9 2q 9Si1}B؞8*8Yd3  FܧC5>WuLA sTL0f>f^|m{`1 '@g$wGXGB<"z9@ ֜ $uCf$szPx=`Cmzr!Е?',e0´ߣ#N{Na Ͳs/Da2؉2bKU 3;t",%I ډANA*Mq rS WAS@\)8pF)&)̾p)~߳IUbl;EW-v I,ڝL>* pzW2 +̙]~5sri!/w$kCe,no¡%ױ.a~;k:5\LN*otk1~T[7`&N85kD ,HARֱbdb+ua{g;y4i7g_x 4@3J1Hm\O_H (As@+tՒ AL0԰A>d>m-S4 4~dIu1M; z / q91IyΕoģc"I8C,YNț)ճh G4Xh`J-0܄SH|4X'VA8t <.AGAo kp239+?b2$HTj>qRLgqڣL eg  Ub9c uR!N"MC΅"(Nmx%ሁqDť0ћ7$ߺ曜qybu H3Ӹdu pRpDkwL DHZ_5խWp&̾H)mx} ߵ5&_0(DZ(l k?ISf"CǂӿeG{~I )43F\U|amΡp'IuK3@yHQ:Ʉ}pN1ˮ9Po6FHph@VcUk0. $ye :yǫs7hw,Q85#u#@k@OAvzm]]L\0 vyU:6F3?2%0a l^si9U_+Nh>:zP,4Phg\b *|mB~G$W*aT9+2H '>?CsXƧKF ; 4f߼0| MJwvд^y14B$V{}Aّ`v2I|AݼqjHKXS)! O# -(2fY }k K*|J]Ũ td3o:ȍE| Lt .-1S`"t݅!b?pZKL5&l0-Ն`zs-anަ$J\`t?z0Óm2y[f[ v[V^a%)RC"Jb_vP:Wz'g1EDHdSK.K%_k r{q{I0v[zW0.m)u lͪ9('Q)VbRxXlw aKd$Y$\v."2D e9 AH:'h|>+i÷gOr.4N@mP2s҃Qs,vdʋ䤇O6Eِ  vs-TT%rbNI\O(Zt.+l.)j2ZzsfCѣI " T2SxLLވlzM(t.h'0q^K G/SM`]Db//YUߡĻ,cb婂&4EV\uUBQL:FYjgꆱUlRE*@1 6sƹϲBv\>U+& qUawߎ1+K VL$3yw;J558mЈzrVL{HIR2/!5H1maPJ {CZ1I(%*p"QZăD$)ף^pA1|&eN$ēv#B\C_x ;e=G(NTa6r !Hd.RFoc?\Qx?Z0|}Mm5'4RJ=׈"n.fZȓBi!ލXb-`$ֽh?]۸edϤ!ONn}:^cnD5 d ^¬B33Ǔe҃}=b7 R(iSّ[&c? 1B/=38v3X4+*}FX-QML:`vŮXbm4X 5Q VwXT7bQL0A&krX}:Z\M+ c2X1 e^=},5}J/T݆-|om AؠX jN\:B]O C-YgyZ4W  R( c&{l1./ˈ J",j0ifc&_]a2*9gҦ~!)V"L #aA@ &[r5Ws-hbA7|{1=FXF ) wwc(.B6\gԇX)QgUH #|9}2>]tvh|ƀ,߈CEdUn_ 3J鄨L&&BDwIA#b$E!PSnHrH$"Y|,l&Vͼ 9l,}Fё"'j]8`lՠ^dd+#Af]@DD#GOLXB2#i,-c ŀ7?$V0Ud <4ץ鹜BGix1\{׶!|!,d5"C"楓᠟-Go?I^Np2K35VYGy9l蛬2/)&@$ǶPȜ-Gsvr#jɑ5!>B,cEGXx aS{$eFyc Ղ'k(40PF)+*Q>-IhVȴhD@i&"{>5!CPLI Ƹ!d` ; b nd׏xZep }K3&.]W=|I9jzBm'K8q^n(/ʉ,M߆ (1 \'jc$׫4\fO.}$=(D վ̕^m΃B&EX#cw e)fY3΋67߷lS\uj _~?ɮy8gpr# |-{F]!\dd*C=?5=V8%*Si7vh:5="M =>B΀66cx̐R.Y+k`"0w !8dso!62tKkERxw:W3-ٔգ%['kb:eNm]u}b MB&#ˠ%=q)9^gxP12f" :4Z6ͩ{1DwIoeًMdad!kr&@9E`f;U|G+Ó-S౤?Ohz]xHib6Ĩg$`X{:YQYTfX>O9 N$c(ʈ^pQqh]/C$饈Rv K(d)s%Ә^2&}G1I&6C{СoEKq+L` bi $jIv_&{ O~u/؂?\9z1B#M1Um%&m*jrHcۗPTss1))V:Ǩ2{;#gPg%2&]Rpg`f 0KbqW^+~_Z(gi} -$Y2%,CǮ#2-DT[2-;-9u}HETB !z 9-~tIk66GVֹ""1OVlhx⚡E=tKa>g0@tz=w ּ '&/}W_Z:"":.Vؘ}* Fbo}MyL JI4,#jbVRe~.qwuf>`n}l?ӽfR БT.uIb epE.!(N |,έs-dfuØn|^ ̻̌w!#o1 B+Gȯ=j؝20w/;"X3F GX-<ٔ;|yI|%!Ķc>zyCpfDExzީazf$1;R6#M.=92| ĩ`.>V39ڹط5߂ ,9"10[-IRI@>9DO4,itVZCnn7UXyzǡty|:M4>$uZ7:DA@O[۟!# ije#=GF/<q3gvFs2`1L/54,Y- ~,ΥIʌ㎜ FB7GԪO15TL;Lۤf*|m(4K{}!Ⰵ[Z[!z=dt {f-IQ (60i2Nvz"K#5F\OhϐHT:_-M 'N8O{@m0D\9$+VxĿSx ހܺIF(5ozK Uo2z<}략ǴB{izXTkYLB!:?ar/YoK%Kv/åɊI.a)ݛK&-cA[_\f8SCn4&ba^>ޫ2A*F$,$B0q5NH<(68ӮL_cf˱#yA*%Bγ Ls}=lbJ͑(A]}:;G7}z1Q<KͯYLHv۷FNpy׺yx1;rjc=>W f(Yq ':XgM]}UTu7[YL Cnf Iv a iCnҹ!s; c56K:XNr~]U8 =|bߪb@@@Rv] \!ݞ_lܗظ?~][<7 k̯tEF4|0~5dQUG`VXa1d]XMxNgk)'騕h@]^%-B8 rn rp٩ԴP,(f2!|ĩɄ/ok,6*,HuHx~/g,OrV7?cc1Hȍ"7r{śW!N?6j VkA]i楘W'j; fi+U2l4g Ե sCuHfXR!$ZaIϛ':XF, >XT]_yJ3z6 ;熛=g>^ߍ,c A ||a?;]G_6Éž>c*(N.!6)X,*e״3⠊NS+Q]P2z"/g[*1ICMSg)C<} C@(tnH$ VĨ儩nQQGqy1=qC7Z{rÀ7R 8pS҉xIy<_%h!`K~}񃏠!X7Pΐʣ]`kJo :kwta48$/+qg>C5NY0 pm;O ]Y ?+nW [_ظQ`d Tٿ9ܠvV6{rp!\KM=M,tJ·eQ6}q#ۜ-_uq-2-ز-2-=g-|Gan5 ]qx R%0^ ^ @~)c9}$b'/Rjј2kսъhB V7sX8Yx|zZTսdxw"6zmh,}oP 2t*^Yr֤xtL+ | .-I_['`o՜@r|wP;eB6͜ tkxMPGA֊ Sta&yd]9ˁffggL܁rDɏlb ,R+^`tH߆AAz}.5&qʤ1@̯QsAR#[ZJ-ӑ]b`%VtI2> 됨!)✄ϳ뻼.G'oJK3XLX%m%x`LZ" >!AShW%ԊOSs(pU>XRɶ< ybKT,Rֿicy1| %oYz:ЬI'N&OssR

#W?`7o1?agEЎOlt(Tqx^''; +mAfgF:L Uv}_=bym{dzWXQft0i4ņQ\}hQ/DžS*{N6l.jiuԑN=Fm)ti7AwjJlBzDqdqZ!I]o=jlݨfPDKMԎA@?J''͡Ϛ"bBBX*$T6x>1dt=hm^Q6h?}9^Ru-Td("H$449TrI&oqkO/b҄iB)6(Ok%46ݚuGbPҨd5 &qPdat"#-"Ij-|ޝ9,~4,}QfYzs7g-Yw~< kCq5-M=~8WcF^BkyIj^`wg _7B~n8a &~iͿdl6yO%BTлw΍=1R9) qBn/N^>>pJ+ ~#`{q>WyGgvK9y)hpA9ff77֧~SY9'Qgu$T$|C`9K1'xp>aهR31Od6V7Ќ2zL~H<$!o.-ۉA,5(,P ֡$}ܛo1kFx9gf{|aq[J'^"GH?bK7ٹRWʀ3ΰЦ ..R[/TH.aP&_M/nS7=77*~w*Zs/\M|S wݰsKa'X_ߴ IؒaO}\j˭|7ww)[;lљ-P8H vpRwR ||z)T@l*yI}`h6+ ?|M̯~rO nQ6ЗTG1z9 xSلi3( Z{ȹH-z_#)ކ,~hGbsW0p24`Fލy>`{J7DZ5{&ljZHL~K[+Jvcu`/f!Al,7\Or-ڈn,;Ey-oSO\ ߬ΥPޞw^z,;vB_#7($R>Cy4f$e oAvnC  I(mPɷ]iޕ v`(K{cMWpWHwxine-lib-1.2/misc/fonts/mono-32.xinefont.gz0000644000175000017500000007557314647725152016356 0ustar meme4Krx++3 hFY2Kd ll-JeK7e23z*#2>S*3*227~OO~pƑ>胟>K?xӇ}^en^K8 y$pSng ۍvvO[5 S90Μ՗m[[= h''8C!?q0v$Sd :Vkб LkqJ2[qJ 'VU׎SpmFCڿukT:>ӟrJԄʰrp:C8f5!I_?Ppgui?PO'Z4yrwܒ?xJ/V[[J*!~4}:TanJsvCu?XF&ۣYĠbp'ȥ8jsUY2L kYa3.EbV`T#jɳ]QPQvCY&%WU1d^T,3Zp隉y/eU0er&fK})9]i>qn̷~0a3!0_XKl{Eq)vJsnǯY/Ɩv&vn+.yb%JT/DWdm?s ]uG<AOJmwxg6޵Gq=cTÍ;˳׽̶#ËK4a͹.ëB|fN㏆wzK!:hxk񎎫+.7.>Bw)/o6B2ߩqovs{uA_[=8}l+Z{a˵AHaѓ¨R0[m4hzힺ}jK}n-cefj5+:8r[6NS.^qa!j]Lm=- o lWg4c{:2)>N}$>u"j2Թ?PZQ&d|Nt!@6ï/DAo~&2#C˲ ^:o.J Učj7 '1X*pa #t5iێMԏ#v3ze)pNacoxhF{~ qfL(#0 vc$~;y Y(,˃mٞQC?ZVp-#cN#rqJv'xNr݉?Pߕc AǯΗ qMWd‘벮CxC4*&upfm*B6L1ҹ4 ܟ'wWsb7WM: 7p}BSͤW[XfnDؘ\&C ӽsK[rPD 9HHr<gȝgX^T-J v6lIbI:mKBw3mfo1a i;.cL?ŬYY-bTT/td?5%(]Dfl !{{HFX١xRRno_pC}8)`qUpUXNx }^Vywgil BrVR85Sm΄fDo_g0?2ʭdYoy!,=ȸ,3-<}mv?|B^(^aBix!9N 'u" BLy!0 ѡNH{섴qQqK GBZH5M vonW2 ?!r:XFP(fB噶#%̈́/̅pÙ*7;˷7LPC[ 39~c=25OЎ;>ҕTWD+xEjFAtG ulmXQfniȧGL* :K}SEB tޅ%^.{`T2yHFH! a3("7~UOR#sѹEaxO .B!̜]9QqMorʼn9K ]ǫL[+C~=kP>ѧG!Ɩ?awi^xjW:nPXqR;v&?(kUZf&l"1M*65)iU=(Cr4{S7oO5!qŃպ< |[#sܣ۰Fѝy(4S&5uïEEW?>ms4[F9ZT& f^^I%8e -:2&ĦґtƄoot}3X8~^P^Hׇ7k,fMяKQƹf^;Ǚ\3O]*c.]ybpn$s':F/S:k",-* ӱ'n~K/;򣗊%k-L`4Sn5k3X k՝iaLr=$ ֲrt* esȝp (/F.+S .bsW0,UEeZFcI}p&E7vSFA0p$+*cbنx&cE115C3K>Ub}Q[)^+v21ژȈoq3ƒ/V+kVfiyղ~VVU>"`a%Q4Y+6&*/=o y':]du6ޜOM'#L^l^@5(M߰ 3,Til{vlW. /|- z(I[cIQ+ps72[;C**`PKeaCw֘oE*&٥ pEUDӯU[e2 V2egӥKسP֎B {%Z)@ݩb$R}#VؖYf5TfqLIgdCߎOY_b W[RJ ol$ _5{<t6乊iwӣfvw i\dCRhb;z/LfXN6JF>v[=(VXPp7suV6vAcSNU|*$YeHOnثso| NoKvDj)-mew"IT av*';zO~ݭ? =t2dAOpR7MTj阫,ec/'lJLq¦oLP_ȞrI<3>b8E@h{)ˌP<3CY Ou]#Sܼx^gɻ+7!Va$wdޞk&RcX1;PK%.ᒦ׫Cz`ePY܊] V%ɓadU2'J|{MkC::SfoiWXfk*pZdY_<&?H!22Z Ro!fk!S-$tXM)Bm=[+VUԳ K#A9XmlZ\ĀSˮ] d{{">Y c9 C,nM?6޴+5S=*;~gjA*4hAZ kP<98е&Dkeދ71XGMUIX sCܧ0`lJ ZQu34,Iޤ4%<ѯ׎t~4kR?|g4Nj-1mQ"MlFJ`D”?Glin,[\i^kuJ|@ ` ?}-M݋ D+-fmS -%@Zv>7Vx?"v{)rI{WPG' ; {bg0]+4%Y8=g0L>t-\ͮ9^uˈv?*rߙseK_4yGJizw-cp6ٝhS Y/cҖ7,i;: HN&6 zE$E(BΓNeQ/F34 g막p. b5)4 L>qzq)5HCC3]S+NJ#GFx)#0#o>K/>$ JgwBW/B|ÌmTȌ!Fb,X]Pv[E] Q`$x4٫1$MbB+ESv+Y*҆$Sfy,7\Ž4X3re#cXFm2S@UhB3}ۙv6;Pm}gܙ7/2?VFR XLF'Nڹ kG0w*;4Bykîj{ͼ,ݻgm_c]f,.%S}?@**/ 2A%[:Ef[6d(uB=sx87W}S)x*(Q-"kVLˆAB0A*`R#y@0KKxHc<+{4xf Md:DŽS{Bv)3ktwļbN Ɵ3t۶UP#{ Vhe\%6:lbRǹƜX;ʆ|8p eph8SoIY5Tj(gP?LI/R?Sb)H=$Y 3R#V֍;JH=6 ݋ʳB[?ud k$BlXym/LEy)42NoS 6XS+@+DҺu'J9zt8BS4,fv~bHߖ)~ZO9/Xqg&ȪFY;B8`xҍ̭aIm:ld ؘ8;nKd.qB#(]#;܈ GژDif:nrB4'f]SFzǼC `tRIxSʀ\b?2J~eg]2.e/e-+CM&ՕQґECR` ch05Z{g#yצ/b2)ש4Cɿ iъ-iPi扤Dn&#\޹(2dKF/{S1+:GXF~yx akIϺ4mV?sMrαKFPwD:u0 Can~>%up-u#1<OC{>2#6D b#v=15v @@ts}NM>*$[~GGVd !Ѹ9o>daD5}V#3fȃ #\y@hԼ!Q[I yu7 u/ 1}yVf-ne3cn]9'e.OnO͵D b!-™Ů|ռc4.W.}!\BڱU7k$ߛx2A6s/l;*e{QD]+|D9Y:.y(g&o4}buBuz& ~#sKc[GHՏԼD_s]C2[J dU _Zu9 S ; dfRT=7-h7U.]Deov]-2us,A)|wC֓\0oosܳ JO!p0 \@ B8ib4tkg逅0uJiU7#Tv^>d)snGNpR^'uBoT0NUz\UlG.Tk-B^Mh} , @fغ vT~sJ ڂ>n>m-9U1֡ V7*-|9ٺbl\_P-~OsQC)?ɒĸm׭p"0Gia3e2N Hbo8nƃ!*aB`>`w{FUFјF f@vϱZ}ޢ)|XJt\0 ('UWؕUWc +9F|PXqTgݷW>3SxkpMՐc =EϞp7Rb+r|->Q9F*o;t/7Z8XiuXh haA[+KuQ-[ B{敎4/1SDL!U|aGv鈳OQc%0ͱi=H/@;HO)6޶-;߉izbj/gs,^hWz`i\=7wISA2Uݒd sx\d%B1W)&L@xB4K'\Wvr^N鹄ɏD I8df=|v遵C7;NƯk~9s~02ݝո"k^ kv[KYޗn4;^BΛ]_I- 6^;fꋟ{`c)waҺ8G.5XS*L;5Ewgo7g;ݧ// մlAPQh-46t73X8|%MdH_E iIKQ| PcrEF>gbΥaL- ᄔڐ lq𨥞c޼1F`uk,gNZ{LIG4HDD(&%Lj2P6H0’s) .] 7<|!T!s cWʼnܭ^Q_lQ/ebih!".`%"•k3Sm~ B#6--QB/g (yJP*V0~:1QjPa? g=͜GHGg aQRذɜ5[&kcBfHjVVyid&U\bZA=4dc| J"`G SeXͷH{ϔ\v ռ>jXK\͗yrau[[$Jc:fuRJ~QjslZͬz*XVT{o3&v@cy mz;@##1'?Lj<ہJ:WAjH@ `6+U&Xq6k&H : S.F<-v) EQ$J9CG1z~ȗ4,Z»{Vvu*Y璤s3l+_ ʳfj^9c7!Rd^PÜ#[4h+61x@Y@ >݄s|mIjO˙#];& ŵ0X!5C(M+/k4ϫ}vB+ȑh~Uv;_k/Eg/4&̄]nV-ɇɧs+Uǝl*0B"Co:v eA;薀R ^_Dm54-UsgO e3>ژ#kcXF&|MU{a0P3~/{t/P0j\:F9 {;v.Id[WNRU@Eًp ~F>|l§п}Yً $Bȗ 99qau'WfMb@iyx~9`.Dedqr_ZKC糐{`!]G']!YMF-h"^QA8pi=x 9$#댄љ3~, z<0 Qҗ!(|0fUݳ|]"oܠM} QR]zu{{K '`G N`0ҹ:ҁoIK[&;*i{/{ݳA{?"> 918ɘGvOvdpCK{t <͂oi趧w uՠ6Њ݁v;V0m@Ԁt +MЪ;gbc (Y6>Wu~U%,7P`<]sr"26E rHqHו vKKT0i$hCdB*)ES0hLNL**38v-jEH@o#LfC(CZ}ɟ[ jZSJ8˭Te$2AQ6 ʪ'eb|(&vb vo56J(Z3IBQS+ X2#7Ecd4<.#ohx.13%(]c AXj.Qx:򮐷+IƬ]D(bltADK]k_Q>^/-ϚXh+b\!b"f}kq%[^!BQqm_V 0t ^F Tl2zdpׁBj[UO!Bx-D 5 1[v'qq9!̻7n?91f1&q߭/J$,U77ZɾI\wãN=ʢ+7p,GCY–QlHM11H291Y% k0R~gm؇FHW*[ -RTr'?vPyc>8PڽgD8$%$Ƿ$&l.ԗ<%?SI ٥̌Cq<aȨ@-Ņ%RdnÇ`r|ÞjG!9D>UQ=bYTGŀ `ҥ?YcqA,a=0lvsNsz:!Q#LbȢG j*Y8fFpD;tvX #;w%z!;D[Sg)Rw&7rR!Dgz?JYx08d+]fc u|Z(=ey_8^GaUY(+V$E}V2_Dy!D]r;W:Su_m ͉:׾b0'l V[fS(N4t[ٍT"Ǒ&Z9A[I;j5vV]FYׁuvIp]WE"\50/ȑ3gu%+<Ͷ.&wL:/~G!E&WCBMe 6 U'MX9p\^Ùfac?)@+j['pbm:yWSbc\G(Xf*3mϛ^مF{'FZ,8y׶~ -鱕27bmʆڦlUPosUaNwY瓆xj{yCEӇ/i1A 4FsU s#F ٷNxmذؤ В :6' yn>h~a+o3iPCrkTXbXyh#!hmu?&D tPBd,۟ZEK($ƒ)ͳ9D>v]K qoz=I*0ѷj\WEde,:I 'k!2`!Ti:7ng6%yˉY*$d+Ox:1Ud!%!BYάs g*_+d8nE@URLאʗ@aK Aot#pMI, !Y`sy&ǐrȋ7hB >ڈp @wpIzV4*@%_tƅ\Jc8i]gp8͡st}ӭxu% |ӽXE  mw"@ F妔bs g VoGT޼1zVIB"lleeC~.5C2.C6_^Bapu#)13JYi=q#+1MukIr>?dk,Dr( -$>&NwUtay %م`ygwQ[FFb!CVifi7 v6~,?UN{5$-W΂pAR n-{4-ou>]|l*,# RKIVwk_z Be1By!Vy.A(IcgDL\AoߩEޙJ jkVN X.{,vo5jUfDT'-y zowK [uKdj?18Ǒ!Ւa=G ja2,qvBWؽyb,oZ(6x--Z>xoݻ%<<,CiEW'<{ /x`- ` LՂp9 h"0TКaQ59R[!0My|UP?Kˆj%'8&}b|Qfz2pEKaa2 Uk%9W}ӳk l5o.xs|=/v/|+{ozmP=lHH eBb73l$RV/0_g*Ip' 5`}ȧ;wY黎-6PNk#ĘE1r>ٵ0㰤ј1_wNsv]V 0X/7Q8KdYFa@5G %n Xyƻ 90I碾Rd&TWr+a;E;"he'Z,H!<5ah FtC7r؋{ϵC|QF%[)kE~`+'s!)| J*|VOs'(RHHp[W]}eWWdbO -F<V.FJ.ˢVu|kُ|QCAhq;adrjzkHC" r a;v:io*lۿ6aYq<ِVr).ǘVc0ҏB|IA3%tk{]u?"!УD n|Y:o YJn^EZY*m Wo-*SC}\Td݃ v@Lm¦1o7xBʠ=cO[c.Oe!-d~ >s[8p,$yYyZ[/]-u]B+%Ku;Oqg30}# 4el x \ 3sʛ@8d,uX>跈gB*u*`!`izw@YJqB; */& LW?Uƅ],C1pZ ߨ[DY2^[U||!lą v͇S1LWĜKa瓜Bbks;\)~TW)~lWQ;LPȯIߠvG A։˄t L4f_vt$q:2f:h`rr(]a9Ía13# # A@@_7aku;tnu,_% /_Y:4 -*F/N(%CR'm *KW~AD|L94*wNpyR݌ 74kU[C1a.JLy-{Hom}4AMKQ7mh_l^ ȟ2Я>T@n{,׼qoOd9dfnk C JLcNjWQڅ:*\+-2W}Q(a R+ WOWrpBo4dX B,o﬙-6/QQZZߋk?Vffi~PT\= ک~5{~sq E"'\hk&#"T32<3Iwb(Ta(kqf֪PXRĠ:rrBnh`b2.ڻ̗tͬt9"GZ[۵]h N"-Č=L [^{5-dJ*|S^mmb``!"A2g ڨn:[z5J0mn`bt6H ys>Myt82x;NK}6j*7%؎biw?`p*$G'hjG>ٻ(첋f!eަ4{ (Z(%,ޑ6=C{p;m Yvom"UX(ZZq5\۫t\/ͯ;{i^UA7*(Ԭ2wK_g{w;vowv/Gӗ~ϻ撫 }2BSxgod`C/<1N cpa]Uq͞8e' nXgX}r/0l;6lhPFCJgc 1$ĉ'4nikstgoAt #sշAs∟)c ]?AvBL`e5LPMYpDPz&H*ˀ0LA*DD$m Tp!OXoX'X+w;_EoRr`I+G-smkBM+Kf7U59Ɖ>dWr kF]P*ݪ{gcy7G9qNƍPK‡-mM;bsg:X$wBL0 ,@fֽYtoB,< ]+1|"nM-`{ȰR+튓Jմ]"5鉷Iil%ZbcuPHodÙ+Mb(j$4m>n5J]9mu(|[cE\~#5ab' ؏^mŗpQ\9 ڜ՝TڂTJ t%RR- giDp sՆU٢xpV 7Jy8n\5RER( ɨۆ>cǒw^b@ oftDfnYltT;8+!9W~|CIMu/?Vw|DnUeٍٻ/83LOYL~^zí+Z ?Q $@ˆww4mY AlN_x"Z$:vۆ&2ƅ:mx2ë%곋 !,\1]_/ff-=p0RI_xpuEB.f vϦP=tE7!z"|[lCL탱ʍ&,%Q/Թ*nE.J[J+wwL!"NAS7{CgwĹ7n/~W!nVitkPگ); e%)7'NQ=geFPpe}mqOY?Gޗܪy.w?od$⏋ ف贯lUArfw6 y LbtH޼&CFw3C*`a^­ϗެ}2X2rATe*2"5(tK+%l*XRCBhT']DP&[=22، gВP[rfǏۦlV2&B|J'nGƺ+9i׫h)ꙆN`r `H6nwWߣnz>S; ߹npU2E&&zbBu)"L1œw" _=ڬcbs6YG11Yb2h7@} 7;L.e2CNZ9miĭUl.+LjtU`Ƥ9I~6־8oZpf"RMZ BR5'j&Uյ`vN\ѿ^xpPsg€ffffw|~ͼ,7n36YGLh(T#.#w1jXZհmj9ݯjjC6:jKGPx1aQ_+y:_^-(fبbޚ2fnRO}V.n!TYK(c:`YpyQ]4w<Ս66jrYwW*k $8{ oD xt e4]뫆ޮպ<45+Wݪum8ֵᨂ&d7"49! Y T fpㅙ46({o ?Y5LU(^m &!ų!cro4 ^'FԸ6"F:^$'ycyXfҳϧo{!R +)'dKƼЪ23.kĚY IBng͇/i~>)x$YLBVKce24?&|WAʥø FU?F|#jiDj IIk; *eJk\&RLMרTKWTra%|[\+>{ư5v&Tؽd,*_&/j=@+CX 9K6eA{gY+V.2Ն#DEm.Nߧѝ4s7Jir&rha˥HݪͪtQJYMU@c [Hb$OPDHB0B ʉ_#q؊{L/MSڷ&[3͊)In`Uɽo6Wbl_#b1=P^'Ya)UJFApXָc^6q4γt ok:>E]ɽN]Ά™9$+-nRA9[r?\ocZoZ}(P Xs Gx4z>eRJEnt= %j]jvlǫIW(?@yo7ढ़CncpS'o;#&: u9c舥l5(0-& eg.ퟯ_SGVFɼKmqu6>.=d+n)¦'4ݮFh]aH2bml3o5eDU<; x+B 8r}-[G$(U\8n4 (A/ΣX<tbI8\%^rLxk"6Gf,4fn]3t;%w9NWۧg8= ʄ' V+o*DQpGWX8Sv4TYɵ^ b$i:KT =@Ŗ2D2\3"b|&cN9*gI*T c.ޞ.ck[] ť0x_Cjj#(>R#ҹ;:*- ľ&W+,J5\LuL)_&pY(Ui`l2Cw[Dqфv. >}.OsN|4*"-:  O:"/lcSi7dsw͢(w ~Q!jp6!>(9WĘhb~C !THdnny'-F&NbBA*8E4r/ 6x4QTy'8CzHiM&(¿C:7(4LΟ: on+XR>_ [9:?%9a2n}1qς{nQgC@2+|#-o6)myu2‘*L"!lF'1LT{IhrLY؜ -ki_wJN.p*)dK#_`{T:!6>LH3:,<=x/_5n9}4d>>7klƱSlqYܪ^L)H4CJl4+&l_# ,n&]p;:̴ˍ/zKд#d )EȦ|EHkims$|b Рb dy!\< ?8&uL=ßIe;Iu/Q)SkQ-܌ 7}zwS-o" .Xxӊ0W2\.B HܨBPUۺ<8&'V 'V #T}9$Yߵc4 fR5v" |P:p&QJty7.y>Dsp658"6KR yD~<{bӋ{bg[9"X?;%cŋQ#Iɪ _`9gK2ij}eZ /` !,~i35_9u5oQ g%~ 6E˯ZEUs td>}|[=A˽1bGg e*4\q&|=lB`s $_#wJ73rGVWyA E.B,I;92Uo7Ǘ"sLg ,}$t, Bgo f̺G7pLޮ߄e^H"s"jLGtH[Sѷ'5ޯȄg1`qu[)%o(2vr3y]:_̂wpɤ,/^{np.ܪt4{!K'ʥĺE $aVwߔ vG}SETA6HJj(|eˮ5WV&#o0&D/Vcا_e4yAdUl6,[fsa xɜhP_!M|yFHƉϒkI+L70(xtv6MY[œ*T|ri@i$0MB"[\OA*Nq~mWOƬZxĝ/NyUo09TuMw"Ͷ51i.ƤޒήgN8AbsECGz(tpQ+JƲ, ZZ(t+uאԖTWr^$eJvf4†!9?~t%3(5LJc8PT4M 5Tбnļa4JWzQ/e zgX1lj8$\$cX !Ҝ~[VxvvN! PUw62iJCǤIOed(-yM_r;#Luq+T"H_PPk[upP됫--&̈eߣ} *aKŽEélIX϶ _ -/} n C0e GR{pgg!iSl03uhUV[*+BqtP*4ETFlťjGɄ&"8ysee0wt[kieXd ޡ>4r;` ¹ZzV Zc`]w.Mm ~LaA]A? *\-_*fB_V=i:?|x1T*n _,$_C.6o)dʚ`CvgH%poPq¶)j qe [g*vF2*WWìغfjkfQ&-qr}l\=<<"ZSBj{`ٹӺ:W %ڶpL\;su1fs>BPZY-/pEwTDe7wڱ;Ɲv~N;q's7tOL>'*Pҭ^5v)\!MܑEB7" ׁpixyh?~k=qJޣ'٣_K=%e&&|T8}wEA{S'IzvYmxLў)@$ SVU!#;']_&%e #?$8P 1 vad?FJ-JKi2Q(V:dp)܀4%ȋO&1AFRg(ب|Ţ+7W"'cd3rdr%*u MZR8sbJЏ>W/٢'?(o!)z74潔N;B(3 @v$ei qBڥsYkM'숬g֒y?Yk/U{ZJvؒVO pELDj<{L躅Xñ!Ɍs@p@8 {{>:9 ~Mra]x1tDG(YJ/ȵ7s xLt%E*`^w-<%k7h$8 "!'͉SMb<_J🏣ס{_ї~+н8(G\[uf/~#/q`A2x{?q#3*w<)iwe|.N#dݩ=pE8ixS3mu럺B Q/)Ɵ\:fM?P&0Nf! EPU+-~=hQT?W=O<979cUPk#jcm ꉯ.:HtPw*&>_,ĩ/xov|Go)|ioMu+Qd,`^HB>r@?u̡zc^<>PEЂ1KҶ0>.uKɲ/WM'.F`~Go FcLXȲl р$8ĸ/ŠC y=sr٨B=j/RBޕ >0KNX: x5 $,^hF*eE(&ձB"3yvudI9%Pbf9c&{vcR*<1pJ q& Miu̦Y7UC)s큡X+u܂St^r#X< O+=dV[ J9U Wɣ{'TFL?rۮ,L>C2hs"уlLH B[%R_.ϛ$}"h΁w mz龾Տ 'J$P!/,` QtBU6/?QL(vO >$'o+E (AGhgۙj{/k+Å'bo}4(\6[(I =3>E$Cay$9U3\⚦|'3xH ђpF.yC17Ht72~Hf*&mVjk*ˍ{N VrBB9Ȏm8"7 %}..xine-lib-1.2/misc/fonts/cci-48.xinefont.gz0000644000175000017500000007553014647725152016144 0ustar memee4˖%{Ν;ƶ(3Әdfe[2ʒ-33333Sef~Oww֜7"3###ر?3R~<}_4<ʣ<ʣ<(^>6i$ʘne]v\K-UOk.N͗î|Law|tV/{M﵅KI:7WZ^k9G{Cv^{ɽz_xv%$_m˘rZZX?kMuɀӐv:y{t޵lXkt̂+toS,3RV:/] ȶFE «~-QuW~kxOe+#3c'lD#*Lef}[ 3r|nÙeYa +jiW~(S}kq9aZd9kaݖ vG#-w! j aql;+ ˵񺱶Mms2iow}%Fv4x|e)ZNb|UD}P{կ/_ցqNCr`R[[ۻ l]Uigi:ㄷOpޒP 펛E._7eV><ﻺX A[!?]sii9(gȓP\Q߲1. *?UyQ RC@je^B@n[/~ڙp*"j ^4QcV=UR @;v]$h`4m$6qgw_pm ׅҖ*ġQ`G a}vK?_p[2-px̠zIKUfI/фhyΗiM'/ܛ/ ?B4(S,O_+R ,EpXiԻiﺀpu`R`Kg!u{=j҈|Fb77Gs[hJziQޘ7 ej枵ep]ŪKh*uS15ڨ ͷp.h࿠gL>éR|?60>9cW<7O|ѹQv}Y/Z?>MO3g wΟN,4Ƀ 1Fnuv!@Bڵ^uvoaɫ3{0iٜ ]];ӈNåi~7O?lMعZ{j܎"%{8~pXza=TiiT*|cݽN;xyX=剿f0=*+Gԟ% |x{]T<$A-$ݥMo:@~cg鉷t `@۝4J3r$V_p>.1t{I-{oGWLG݅Xu ~quI"n޲hk-'/FV?jd?3:1&u37V&8ԣd\/.5)㉃ .|y}(}|GS8>Lm򔚵ֶ 6vR/Pix3c tVZY,TZswFmhk4s",x3C~;/ʏ]W#`\KG\}Sz2S-%}|G>x{ 1v;>BU'B3ƾٝ|R׻JJ?@GySh dl`puqϱq(ywG:H:$Ds<\mgSzz]k5rg0=SCb5B("(9'^4G=c18~{[OQS2%?:EQ&rON.}p;]f^3sRM hGoH ة{SO N0}wx@j7fH1(|(XRd~dv~a?+OY[OU'pTA#íw"SڶzeM5w #)XU7\.oMiҋ^ ͣ*tZ2P]͡l]4GMs|zQ|]堎i26NG!cZ"it7k,?uf@;ρF w]䊆fLdrO/ނ1-"+,w~#ߖqD(1/:XYkaFfz^Z圠 Aa%on~8~IXK@e*WlU'=+g]]7yqA_6 7~G)W➰BųS\kp'{ɃN?1/&sAҵ9ML"70%ѻ։FS68+y߉r#GC|W}7BOXy%?qGb pɁ9,3{QrVډF~'qw j'f9[itvcnj \\ij8{ц#N~˹0&b ^<шG_;rBn V@PoJMFqZʴE(ё\#$<|%(, ), x7")?QM)FXp.?@#RSBjuc6?N"W['~q=tJ$zh~VbAkiR$q~o>y DtQ[`RK,Ԛh37whTm2Ab"}484n2ViA1GF?(Fbpc&wd4T18Y;r&{QGddcׄЧaK51Gy58kRm\롽La&~D?WDw >U5}7ɖ-\oO$9|pe VhkG~k*CP h'BB'̕2~IHK\ +Cv] \F8 B y;kZBoB٩q8V{X] ғ́^HjĄ}"%uN.xz⾋ߔno`)#μJ^YQӾ]h,h7oS bxAfP.~?k 2'`'iSԼ]{a$Ԑ7 T o u~d]އS'45sB[GJMUYpB\=A!vx9U%/ 1}{-ʏ4z.z՗$g!1RG{lN#"ݐ9Drq6~ P|.us9[.T3cو*.LYe͢y0E@̀S]_}a@4HGge UTP) h AQ@i lU.h5f-N`4qb\?:Ф H?.{nѺ)_M>` veez"uo 0j\ OND-.@Hm…Xn:-fBڍ샺~hN5 J"z9gOlϦG]H ~v NkOۥ( <` |&M}4$s4lO(A#X6w\Q;1oz&9񣼛r;ήo9ua%OHcIؖO-Rt/JZK9x; :-nNzgzDgTzl][Z_jIT'U u2G]ڃX8Ol|>G6zZId@8M =SCZ 7"tc?:5ioqEeJ{u6Z~oa\hgc1cC&-MRђ_[[ĥv;r4Mħ wѠ'x =5A[ ` l\ d"k:(JA`u/o;8h Q p0!@:h:Gd-n|9:8Ҭx_r! KcHdgaq1FƱXKcdo̝d~rt e:fE |LX3fk !ڡp>ǘxd7u]UY&DieHCu7L2!Ť> $_I4x]_sRd)pl4Dѫ>ϢGOLXf)(Zq=g8J7OnjÛˈ""P(dYNzSPʼ`K=zz]6Acr\ >q+ 专 xvɘ"T'cRu?YɉOR_ނp$GuŁ8Ыz\"2fl>Op;NR ':&K"&-a-Q=YIҽO_@3DV~-VgrEA"@&R.&m9D2 P[&!ٴa`N)=d{I.qW,8[y!!6(a2~W#uDaZg{ҁĐNbŶl <:_N&SGbuBvرLoND=v =H^8dh-B!L8Q4129=Gi.FdTRWӑ^Jo"?9/ 4ȜXL'ԇq=mSk؂A=VkU5:*&V#f)21CLX@VnQݘtV k~'h!$@QT\J6m-YHhe+-0|˜..x/C C? l M;h}&% uX%bg J o쨁vWM[#w|h"?'O?@f ޫ7!ue9{CyFF~p~rJ!{ALJ|`)Cуan*5 8D3=ʈZh= (փHN2;)bc(N6A<;pK@^㝤ta|&>mE7"iݰ`{h01im 01iBiu hBu@tGC.IQ58LN/phWVM?8[DMl`3%\|sXZnvba|a=жtI V^/h!uVa 1ӶEXU  Y@*/. }aFߴA=FxglAoY-{oS2 WZ3Z6Hi;ߗvL/ltQqlD]GE-O?Τ9 n"3>QVۛ^*Q^*Q:?=R׸Tuxx/KEy;?|T(\iP1\\{yX<{|>ejס<l9A.O?MkVP,g.\)>+"2Arv$p9 f:" `(] tpW>7]ƌ~(M}oa Pd<5EP Pj/2u<$Zy|  z! t>!Dԓ0w%Ѯ>Dt^1y-!*Z5C $.+JLu(G0[#Ek\07{_bp- [0'H1<:O~3wǭ/L!;| >R{R2h>3Q2ytJɍ.wdF_l99nc6(sȼl*2$hrbrᨯ,{-ͷ3k^=8E"fVDGv < ߩ]"'% ITHBT[zh(ހռFO%Ia] i j GN{V^& X$l*:ge$ dLhceGY1NL]#G7GGE.<< << ~|_rG | H$`($=#Y o h 8u$,GYJtO%`TvLL%`!#GVn}#"lן P d%-qZSꆳrք#uxHg"^WΖ1իҳ:"Xi wT9Z@%c/BDS]-vuɚ[/*'L\)QKw}HHb}<`ߙ}"7F\}g^xA(S%I@۠Ŧa_G#//m&WEWdxy+ Y"ﲗ6:sNO~{GR5qdrb5=6< i#+me^[rBBD ~ЛbD=/aE;ר|Oh"S`MgvP1wҋ#"B箳8Y](oQ΂AWR){/}U o)4Mz4y^QH:1z7{n࿎%W0  ZH=r5eL #c0HDJ:m C|ZARbLg=2Z!ߗXϣ 7Dɚ#JޕF@GqI /X#698j@!:'~O?%-AOGu\h]#@a9\u(RO{o8c@9#sSΣG%Eu0@ O@Ñl.wF)~16t|9 dֆAAgJ ߬}m 1DQDnc8 #,$"*ac;d@;9YB8i%؈C'v:VoMxX >LoKc\& +CP1UitoXب5rO\m{ LM.aM4>L"O +<;5P((|f~W`O~ NcXhrğD#π솅ec|X΋}{>ݚ( MۓA5MF7K-Wn1Nl!|fZl3Zc6{R_ȗ"maLI}V Y :GU&PBT-BI[[(3Ə-ȫvN[OIQ ]9g,Ov~jtFmĨ\G!me_ PUoC]> ϋ`$p)anu;÷E+<7%7~#]iWML_Q7H۰AƉnC (9A\~vns1AtͷOc)*dksUsq &@mty;8ld8m,Ll~%. Y* l''0Ec1g%dfk8U| j- cԀYrEիiP v)(6FAGe 4˾$b\bt"OXtc IJSTva[s%;p(}`qL(r7 Oa|v l: 鯖^QZWJ#?$=z=z=/s=z :'۳yRyA{vx"{v셟=>' ?׉#'M%saz9uz׽͍uea^|DZѫW/-z w-ғcVJ6(~8qw'd[óWl8yj>*͸/|3죾}fTjdH)9nzK[TR}&Y]y)LtV6qɬX `䪔pkޗ@ǺkG^wav*͹wMg!zQ/E_Eה?:g &KT 5Z$B&5×ДK& ԿPrQSǎ(V(QkH8/Fj;NF$8}Ht)迖d5h߰Tgt` 䤺J\.argj]]D"f6.ѭ1ldΆ P 'ek%Bdnho4B$ǻ䭍II0rJ^uD$ cy ̍P̯X`vAbGK)JqԽb=S<男yL6ٽMo\dR$|NvG_I#Stin$fDt' _љ"r8;Ȍȍ948PmiBF鈩rӷe充pnC~%x !vU'HoL^@ QACQi$}h? J嬜A`+y  @ dq4a|~QV}d@`\Z0c/"F0M#Ix.tc%v.k檕~gg.q_0Ѣ.w8/2Ձ!Gm )aPż )`SWRV)=#slR[L‘BuG$ʎɪD="q"͎G%É#QN[W)ٟ[m,犉R!ZϕpeŒ+N(rqx叿bO%(/)By>պ+c hJⴺ̽]xQ\B" ]6qncGj2k$xaXm ?Cbl5V[jCŸu=_ԙ*ZIܘGFmO+8 _̎[ %ׅ dK.LWF]ʸM--upgO[K`me[$ cOxާ8IOJ:3U'3rdym@fD YEs NG.,T w&fʍ*gM5or@u,T4fH̪$tf(O3f_ϸgphR7Y)z4jxfRSisl.׫՟6&S]]5ӑʪ?_1K? 6bт+3w",{/zثAݐpb;9.Kv\kn{i\UQ1͎ {A@uKv~6G{m{e{ J~9эg6Ԭ''=*Z%R܇Ob'Ӭ8>AIBIoD||2;rFZhy;J; #F7eNnlXsՅ3/=g}nvpW[gP3(TQ \ƒȎSX*,>V.\q:Z9Iiwxii.+'5'5'q5'a5'Q5'A5yHM v+63{:^6ȴLn{2Ş>X3v!E'S3Fo+gGk?GT:(#z'LՓI1:q2z9|f_&xDf8Z߈j63QZ/!7˝ɟ睪8Uw),O]ÝK?}{\}M,}h"?ς́;Ė XM!_СKhr`_[0K n m es6xjWU(tn~0B@&eǫ,"~\w2<[k_sG?;2$ V`_ <S?,(zEz_>ݰz .{ dsZ%-YsUec@QҸRq10?EVidopUό@{k1xrc@{ dpӟjt9TGWP"eS֠אYԺPޯΩsWT'? vfl#5,<b7y pvvzO CE5kfWDWvѵ6(3;n&6%k"fCn<&YyF@caOG2#RM?} DRfLKU# r\0]/}gj(+*\ڀ,$%mWQVz,\ͳcɮ7RT8~z #$G_m! V}| MS s8H($X޾<$HԿJ֌~1d~g9#]Ase9Nu{G ^˟.(Q5)`\<x:\£?n!%PD2Ӎ,sDJ[h k* IDK5HAd $c鼵ZmYV$LXkؙٕc ^˱]gN=4xws[OaEȈ'L@) jwẊQhQa28mU(RʥV4 ԉ D-!?ƍOnҀ{M LW:,aՎ6viJY1Sfl_i,B{鱭NYII1OŸ:j} 4\ 6R{1MuY 2%&ɽ+&'|ez= ŀO[m@kX& 2dK^X5(1755-ۧgUy12IdDI G#^8>Ikeḓ_ex&~2y݁1F);rx̾x}Kq .x֮8Y2UuAoUn8QAD= #2 } :]E$WT-4s}h kgzBڙ]?fFwms"ZGk:][˵^܃ L]kª#*4iw.³5Q1#[Į*䭢*L2p)MP48>h21H|+-ErDǏ~mI2Ш#򵓎Wv~1C:;a*ș{`(cHRr*D#0|>2Vmm(NN#Sk"q<ԄQ96a;>yM5vMXt7I\7 w!N69MD߄r0Ds6)pÛq$59&7XeD旅fR厶ԨPp,bb:b%W>cW֤FG=镏<}o(7+l :׉N=C[7 h޹WD7v CopJxgwj|{A+8EhѵꔯD hur\$IidƬ:I'TM%"Y8sWbUCEhIf+PXO{|Pzk@i= z,סS5a8!_n[DӐfj+_tƟls&!l~lXA,8gOi+r=lz%}7^hG>۳7R@TDIv*\D"i`(`]NR3,Ք2q,Ϋ^\4``l^S ¼:ͳuχ쓭 )şPL+I"/GEnR\}ԛNIrR[ŏG~>Ag25O ӝs%I!Dw%;*ro+HjK$zx7w=,&A-!߄ћX,׌e ڎoS_6n_x;9/{fީ/P]cd2~Y>}GKA}lW@=+co7ֿ*] WԪXwf0`sp ٵF,P-&&T#P!/^}{uO%= d((/<]q5r@2=%ݫ3:2kNQl\me@IJ5޻W}"!ѸOF{q5pgK I5ɷzVsC<*r?I/'+=˝ 7Ϣۑ?k.%WÎ?kU(ײ,}e Qe"͸ %_e=PbFVDx˄CI%Td#ej'ma@aٜM9$r[Z17F&3|քLQV?ɝdBzerqBn ջ#{]RzԫJp!5)W4-Qc\{`QYns' `Z4L `ť]ZJ0$q]sHǜۜ)٦uZn\jX_g3o]!^,ZSWShX'Ns !p"Y.īS[ʄAm!B8L=G$-ӷO?+wT&0ԿufLqR J6%/̱40q"2DnʋG ֏A,)^(i G͝I% aS:5g0P .^RJP"AR؍tԗJ' =!pӴ~Zw1EJF}ݿ9(GCXY]SU>O'Vd 8,>!mp")ƄҢTY0aUHbaܬMR2-ohpj´d=H!fRZ#2#Zt?(yaCa 4{Sj3=A^&P뎉z(۴ѿL|O E6:E7ѿ5D%aEE;9v7y.UE}Bӑ]H"\ 0X#Oݍuy?e0efEDLT #fѩm1]Y:@X>,${B9Qxh˰/_>euHi  la= 0#]k{RbU38*Vi*? sLx *C_~R:}94їE5r1yi˵P[} D6/GD3՗7C'ܯ-79N_-evrG{kӦחӻ4 U+ZKZ}i`nSnHy$ח-/i[~ =A2ŬGRm%'zD=%ro*Qqݭ;z^ %9Q%A Vg57rS5tCІ9#b1vK/Vl6M3 BEqxW~[&@^h1lF(KެKc eVQڽRuNTؽlQap:Ec89꟡ʟ\9T r.NѣrRHy~(W>Xyũ1cT~JJL;>? 8f)#s>9čh!ch]I!=4`G?厖-y-0\l7Y;Co&F2y(޲(D}G: UՀ}-`ɛon}c-*6T4?( )|ZmZiyt3@3|`@ࢎ+u<!s2l`z>VgY# V@ ŻLb3jrrˊ~ Yo.q(0OKxi2k@8L'ՠ]D╎[xj#J{+|*^[W[BQ{@VO Z+.E:$@Y$.zx4gXSyplؐ֜MBM.ɜLBoOk:?g߳Ѻ!׉C> uWhDDD-Ѯf5$1w^mm.k=kƊꥎzr)fF5(s/b"eD, H-,J+)Rm'eۮfF(noݮ&nc[q#wT }҆c 7S0 ;J;ܖu%ҺF>K e\`2^܈; K&}_˽8ham7-‡'x٘ /N":)nŘO>A} `+W=EXIzu?(qi N:tAWEc J= 46?M}WS<\} aM݀uN` r8}u6 0Hr+"pSj }#m-]%g{+n9WL{<ܙ ՈTŠF VVG lxpH\j^^, 3º5 }C1ɕK2M!@B0:e%2RU"t zŹ'<i,g;GܘJRLl# XƗ'8AvI`~@/}LIWB `8 e^ukl IVH]P1/yA Ǝ7X< żSƷ宷J= @|(uNs4).>}-b#yGNXtPtnjRoqS ! @?ssrr8# )d K# "ӜE,voxbg7g/G93yUr>/&HƇ̽܃za ߡprWuv|R:vĶj ,r (i=z E%Ev]a{Ci1G((Pt`0xPFu4@(#Pd(ʱ1PTnRGQ(J?EWv?hȘq`LLb4k}W೚z]Y#1 Pʾ+#. },D9E=j(kQ40r*Yԣ,ɢ)*ddQ"dHhSPVɢ~dQ}@Eע(i]5^Amm\&dQvr(V]:x,EP Pt* _mEf{X|U7IMw f3^ɮ #ܘ:KNVR j 5Z(eBy[ y54=[5 < :vۿA(t\N*=>EǨ_ҼD/@<1n'''zOOk~XDrzv(:_̘B٧/uˊ/]ʴE}sPԩJ>WVbz=~pԋkQezL/ɪ_^Tʢ^dL/ZzѥOshHxCgmbu[ Z of^8 ɗD}^t=ы[D7Nä ;(4a⻯B/@qN Ӛ=ޖRAEQ#i#lVNNa6R}EG(pEdPTEcYzwG~y~ImUFDQ z^Fl|ٔ )jr5a"".@K?yFF#]Nq*7Uڃ*w SPIK[b <>QcЍ$66:5`1@}78) ^M*7w:W]oZH2[i2^$7@2n7"+}>I7KPەcx;Y7}7 =} 7͕;՗xsaz!E ܇fu&,Gم`SUgْk=eJ5t#l>~*x G+]~M$kx Nt|sȩ 9dG|N.~ \:\Up {Ҡ|# .u'm]HB<ˍ;=P701@ -aGQeMv4xŁ'-̰Ay*UI>W:e'yPx~֊PvM .N ZoۏQXۣ;x::v2fvro$C$zTq[R"gɽ.SaG GXyeșd'2׍3nx$ɑ5}n7@!3n`!%L1XxDzʜp6Ѽ(!+mN08 Q|[ж"!3RdF͑0Gf؉̼Cqef xpא O<;iDOy!dv/#:{)fx"si*y//TK !/?lHpEHރe[,K!wrusy2_4j1H:dFmD1D%VFfVFG 2#1VdE.̉d*s.yȼ12[ȼ_$Rx^;:yplj<֠\.}t`%NѼ^0BTl"_l* x`ye<*g͈&vwO |/}ڬM ̗{#`\D!$ x-jjNkI.5"gתH%Kna*}%U4TEE+9݌UEߺ{u=Qt}QE6Q2E@V5fqp +[$!Qc5%:[@Pc!Q4E[E&jEEo\&u|&fNPӽ Fu/ۑm 6Qդ} 珒E[Yڀ}DZaj.@#D|r7գl1dFVr{޴1ӫJ/"cI+&Xp79ރY\`Lʧ2"Ex'V#K  3DdJ/ogD Ӵ~(RՆzgDN2G$9df7|"w$g_xAȊ2Գ>8HM֭6!Ǣ5Y cI[`:xi6Y"SQAy:R-Ɇ2VSښ.{Ro tdycb |:v]At9^Z$d0l~GC|9n ;:d,%dq^B*g]x;kFc ӿyFirUiA<dA#Ts4 ׯ7ZO^k^8b2lnw)Ǻ >fM,ϲ{ 9G0`EB>9&@re [?r҄&d7!G#qN\γPd LEtA)aʘbt+g8{BѲ\(1J:Aa8|x#%l܁ @/ar8fr8z1-Hp5TNwBx] FTEBH=[=@3q #(NŁH|sÕ>b.f< Yԑf9n198zAjRDR]'+K˿`)& ׇiM r5TzI,]tJݵ~`mSo^z4UWOTD;sey/lޫh= ]ZF݀<<~Wb4e*xZw.yqKO)c+>>!r7O5llޮX7v?^oj_]ti ?=~=}>|?r|05GTɰ2xCMбL B:X2Ò_mJ&U2ob7 jN$F{[)Fkpa1E7 =dD*KYM% ngv$*)>jDI_ǫO?Ji`EMa(Q&ªZXay7An&^lEx!G"'L2q^Żj2&ZM)W/61Z§,=Ա -ɦA ^XH!T4Qm*(bI Mt aq7PMHTلQM@"hRfF AZ,U`*=*۸ 6ޑL8euZ{1"*Ķ vYL]bh3U9u~#sVD"mʿq}xݴL wiyCnr;uF3Smo{0ڑ߶uYuϢD~۴-t@m{ %RH=OI|w ;}Q=mwAu9PpIq!Aa0O'{#F dЊBW HBT OқEٴd.ݤݎP|#,;u`vgw^ zGV#pn4BZ +acG4j$XB>v|NhC_[pPY(nG`H;+JzF]>?#O7k` g]5ngyai}zFg;;ahsaCrmNbbcnt镏#R3 g)Й`3BRhtg;#8)uFxQ_sF]% &ז[Z?y MMkd`hO|Lu9ゟ#Q2NyeDˬЂmL?K'n .ja&ۨ!baqV^&Cqglj=ONH>S'>AD<<^up/}ƚb:09p$iigͩph_ /Z~_ܧHU?L>Γ([0N#[48bhPCٰn6miޗ52cdNʫ^QxTmFA~?G9Rj}$ef-+nGރ\}f0Jr#$F~ P_9Mȸ~ooo{%qrt̵{/[,2&XH6S H2bFyK]f(\H孧{9.tT;N^2't!:ʮBiHWKȬyEi@+֖z&b)zM.NԔ6z阹)@ޚI=ȸ'g|\YRNF":0&jL \dP=O8nA[E*@$b(f 8 hUF Qݛ{19jJf2ۃgnɑfEsX hs-Ӑ'ȒJXy1eKme"'çʩkᠳq>ԪYm%zRBjp&pכXх(Ɇy(Pij>t:i.йl{%tF0Hns$NB'"aLJN[S}1?"tS^Z:Yq/> 灛$"S:o:@d:R'iFcDdMeЩcAt>9;N.}Bؓ/p%Jv3sրfW:3gyG{>EX/t9cZ5t^zй3DjգoI: @gVЩwwglW;-t*tyZWD6OͿdmcBDiKy/Yf,e/p<_Q4R KˇNrXΠsyCYb%Y䃂ͶPZ”ǵĚйG\Ƅ#P B0vΏEE߿Js9_=Ky'3QD؍V]'nӷ:b©P%1n,J "|eh! `gmІנ1nV F`=Ȝ;MGW_9؀{"4 ㊷80^e.nz,rg;6d@spQ:^bxc/ҏjkCKNˌn 3Rͥbʽ ?䯻 Z-MȻYjrE}Xx"%.&J;.5w#s@YjŖEOk2dA'qM:rȡ ړdfO[Nt&2HM('t-LWZR7\.9$FKՓɭ0έ'u6H \keε_-q?Υ8(!u}ĀՏ\a\A-U8L*|3g6~Ii)~0kHER|dr9i p77jَyE|Nm `X>ROp4XN=:U^{? fwbu q5Xw |YXJ!ۉ<eef"&JU"GR|C@\Ul1*rEq"c>:tS Ɓ?{3 bcP!Ju7WBg@%#{}t!NFAA~#=lIʉf>1B(cjIq9ۄpD8+QދO= ::H /mNbZn Ĥt\//E0=cH{4ed &_ C(Bbظa#QEvE+R 6ssI~2)Lz`Koq&9XYnIsbc?&zٳF/w}| IO`W4(㡶ӒbSUüUu#ջJ dƸ{P\ 4ӢߋKQ6[.YO)ػY'WBoib-Q]Pj'CvĜ("~L)f06hZYF̵oEarϊ{& &'sL2ඳuV/T8c+}!ƿAu ЪTë񜅎3&tTՀRU[OfwDK-~e%R"p#.Ӄp]xM! elԁؖDQXx/J;[2r Bk4d/ /:_^Ď8 mD][GOGﵙubҙ>"}t1hM{?|~_&|0?|@}WdBz'^xsj Y7o^ߵG%`Q,jr*=Q) HM\ $ d5wbB7gU/%?ڑ_#(tӏ<L= [-3Mw iV-JZJ`~MdjY-"%vʘY RY/׳`jn!IrmMi@5Cnol‚.j&؍eqjNFW>Q^E 3?Ği߈ gtXCR?cBBZdyJ*٪Qݸ1'g٦uLM?z Sw>0u{\-ܟ50k0Sh~ A*z@gyls,&z[5KKQ20FȐR lNa9 )bB8{VĝxNxjJu3\.8*2廧b\\-sܽ2.{ "E _+ޖM+;ׇ{?P+xZ@PxNΝK="G>s9:1:Q: ÁP-\*=Y_e2 PceLŠCIQ?(EEIGx==^,gQ_eᘵ4S((k3ԿE(;Ma4ԲgA.DIY:[1,BqKê{X;U_' %(V;\kCe>P-LhYա,0A,RU/AVe+uPc%YM@V[&* %C$:&ns{, E9t,` {=S|V=DըzRz%^JhCTJ3(uy7Fqc(4r8.E?;gkQƷkw8C[}SS4eG!L]O__ϻ# ǓT7+*hE<%uzISx遣._WIvӧ\L^ 5SޫT I]G;ff4fnE܊b#>řDu:uk]t^zK>ՙ8`m H}ځ[, $ǝ"Ne<9 q#s0IAG\X>$UO?e[3&'9纗SL{r[xine-lib-1.2/misc/fonts/cc-24.xinefont.gz0000644000175000017500000002411014647725152015751 0ustar meme]$Knު}.Lg033333?33L{jwf޸"vf5R >)O>c~zL\zХ t͝,Kq<\_ɤ\%d^}9;u*j㹖܏ |ڵҗR<[WxA'xnHLHK)-~VlE긞9ytBGd\M|%69&`\_4m`a ;>LmsckR%m\ݨ}c8HF5:|E{AnO,f' Yq|Qó7.J'@CsgU1T$^VDW j/ΥR/\ڦo 1I|5eympt#xUNcCq9b)Waht+xReU.re%V]7UKQrjyva4ˇKW?q##6 :sUDMy P9)h;=<~W%00jiK_f'C0hY֯^9A v_%,S~`iq>ϝO:= 9/{¼s]scT#jl5eiPrOo^ 0#9|/@9v?DuW8-5hpo">lYLEYѦ󀆻؉5`ܣ]VN8G pl+^(VM4~1`l \о| ;xc#֧?u2Y2L@[1]B .2jҷNg<+uܢv6aӳ : t=ɩF @ X 9eЗk/@%Ѓ( H K 3r|9t85382` P8pߓ@ <[@vaq^|NsY8&QJ**<+Ň(A^=낍 ,*N'G֛G(M h _b=X ]j1HTHPt$HQ9&svQO[~K?Ee5~i1_"8<=\!̓dR qL7YERLr"rwCqÑFM3i. B`>,~8[Pb4 l@p ckU),7ۙYu"6ɓKb'm*άG҉ C5_:gDP{2*8x$x>pFS_laCxGG/Ck:4" _D㇚?;Зs%"0e %D Y1_ni=&^)1pkqzc<ǰa+.TCWh^agPՕ( ;́1?3S?q[׾Q7uש |Ǐ<<.pVҮzL}E`$>)gcq4)#J=5w"Q",f6ρnŽ]FtV,긍U>}߼A@O{x%/OCIZD^}n^_~ øOrgu<~}<oԐ9 ,IQ0GD'k6iTqRx}yj(nN}x;ӆy ƴ /La@~E,jUԹCalc`VpF9H,XiH+٢ 6-F%3]9!2HicQ_c!+|-9}S4DʊuM93G&z8=0.dk]O}u_f80d0,3 -0f$ZGuj hqЙ6I1l.MLfgpMՑ&o1֍MѐF ,;A%"+ j0Da"ItSc!g16M!Y6E1M@쌌:`Ip11BE1Lh2urzsbDۦ!kMo^ytL:>)b%aPSi-D&¥Z3V@J:qvZRkw4"b9X`1 q)UWAvb4"[^[17T H$:W v#@$~Ml1 p]?S7bZ3%1Q*9^-wDqG,@OT6S`ʝyp)EtdDҒl1o jueʬ_Ew+YֻL,V-'9xn{1P$Wm2 foL.cPa4&P-6@;e]IWzL%@""h)m))=[':Evo EHIT_hSiӲAh{w&z|D>$ŷz3$+/d!]unѿݎb 8b( 3S'ALKh4"~gp"7%3 Mڡ/i M>#?4Oo- RYΔxl3p/m2Hw m2NbN'1-$cqaZ)@i+{IR9Î">R L3w[=CZ 1 !g=Ao̒6l8F~%`+gUǽ1 :AܬL, rGd08V%(Q0? Tש,Oɺ@GIX.0EȶG("ȭ@u $ jٞpW8WgfebDT2SI/DrL0#vy;, `_~ cÀ> FA&|5y+b*M߽'>{O,>9ktť;KUN*˾a8kQbryyL O NR)3g'u:(ct/-V$tG[巨UNV}hp K&,cq!( E~` 4@Yi+}4If ˜!/Ыiд`7P~QQl+4A8 LJ>J:(CXhNh!~wP| A'N[$Z"ix8u٦B Uf  T-CxjEQ# $}-d]O-EP=/o͡sM.(#=~Vq,E '^&Bm˶,p2W_aՕ:"-Ϥ2 ,#%qAe{kJO43\W-12vS &aILt?|e|rwZ8XiH,ϐdkJ2`n98\{*s5[E6y 8Dz,Lz.ힼ@&8۪1B$VrPx(#r揼q"ԧ\|* .ZNdEYp hsYӿnE mQkKYhtVUu -"dpz᤻I2&$zp#` yt s$!yH&D634Ze 3nలi%#c1*?x8XP ܈ L=@`Z5pSoEǠ3x/#37H*C$z6*3")̑$l!(Jc$uGX C^/0 ;no 70 >^OmH%8MnCLveqL85LR&(K!G UmH"-RmaWt ^ Rue|Y2w"/L[P8mlWk[i ]٬u2C =@5~?d!=L|ciy%:{BdeUS`G0 @p*pjR/̫'m5q=96؎>e/@s2mY H)cNX .tGg*\4r r7@mpOBڠCW,)fc<58 x'rYDu'=[E}9pڼe'Kzf~by1TZ^JHk?Qxsl㜹ñw,tY7XBӁJxjMY77";tfJ8u>{2Ђkڒ %Φ%*bz)\^VhE|)[ 1Ll-zMӖ^mT~ƍka$q4^#<]ΝOV2b|V1gD qGf #0#︺ 0ɱfo9t#UF5OH' HK;xɲI]5}"RmS84$bB&*lTB*RU7IZk;v9ٗ3vKLPx ֝D)]uUC=}Υ_Uj㹱^=e}e_49Pů|{șY;diz;.g>ԁ\J1PG~+{=>,}aj[U#z8!u/ I[ pM͇ϿO[= njc("1`5*u@.f 2Uǫ%"s>y sxbS5w*DhCn 4.7uJ6y=p!|[ ^4svuA\;m;{*A x/^oh:fT9dsl)|݌sԨ_\j\ʽpOfK )X vNX3`+)&­e !/ITD\s>QPG@1ECv79o* mIX'eXi-s RjK_1(M+=r~My;÷ mZX7׫WDQ 5甝';,ZBX`Rc@,ǃC } vz Ph kp-jT-NcR[Sʌ?; k^C_! мO_y̎\ }}]vn7LT܏u8 X7[-Cuj;\}ZK{yɪ•ò eLJDUEdCMlp++VwZ^;Lw9o#*FW݆jӥ_}Y?jE3h#Cd {v@PFz_b!W q7&`jc ccFu)/ԱV~݃'{YZ큰VI*U6`ܕq F7'oȒ=W1}(G!gK̼*CaN}ҹI=7Tp>I澖TY7^id!WZ7"'ؕS@>>=S5}ԫ.-&"Zs}=0}% L!Y >#pS`/ l#@gxv~x ռ@!o4(\$UM.HT!Ƿ^ȊBgTƑpnJ9ђvR] Cb3#(^&IύD6f'5J9Fm}jli3oߧS2)mFL@|?sџby 2i'1v ਓ'I$V}o[+O' 6imTk/< p{h>>s="'p1{aρ-7,f^jƥ(]3Q%rO w6pwp`w>)uqpN$J/ %N h0 *- =Iȶ#fk2 TV` 2iP{N]0f|'0r75H'L],jKۺCj(瑽1rS@Hb|U¸ֲPoD6sqIKryP`(cEVKUlld5V,]VdY7Q+1K2V0(j(J"LkUEIQ&G?T"jVDYYy2N}O{I%%#/2$wPDC.L:r-Mö`~ SԶmK[jo[-Toƶm[ٶ6hl E6KجFo %1W wF$6 j^(W13 @Ig('<00w6Y4 ̊=Cm: Af`l]Nʷa]XňW20c>@%@w>kH_@сİց:0Z4ӵ aeDشS^]hEJ-La[\VC\#bMc[ū#{0YM(PyM%TuDTEJ \\pG*.k,mIx*ɰOt1H~(VMq4Z{/ޮ֬3fIiT:qvPiw~t噣lɝJ-^]1}$ܐ].%;pJD@h%ۍd*(|rXh=~LUX{= ǻ.jw3]׊~2'r7qw vn#F&40pGG0pAx?ȗjTH`3x"wTHvO] ZEXƟ@},Mҽfсv;og3WQ,3\f2XrmɕKf 9)d<%?瞱@Q:V ,مmЇCkUS$[=wR[-t^}`L]Zoҏz T`Ӆ:߸9g3P8Ͽ [Ĕrz?l ~m6:h5X$RL$HDe/3[|~ ~|f30_: v3<#月4b_.ǣsk(~9{fwYspv=Z1pkEs.5I`Jjk{HHA=PLbe$?f 2)2"GOB݁NJwו߲<ЈA`}绻oh%j _P[v| .[V}YBP>IPn5uʹ6u[XЛ޽-gG,<3W@֨0z/>NۻKeHHkXsJ!-y^@cpz<T[RDƅL K-p *2р^9•C*-/xdg^-?EXɴ ShŌI'i* 3\mQw?gH &PZ)&} a`@[[\yPDj*D6(xw=;= #a5 <)?$z?H>UUYu3[iya:9!7%Kj {So(HviN /euu+sSGD6>|ԋ6 љf7z{Ô? 38 [Ixp4"A?pB`^toCq5m㲔NjϪŽ)ֽuArMeX?a UKS'ӟ(k:Dc(Ii1^ڪVtn(n 5+j3z̡vC>$ D1XKqiAsJϓC,)n{@truz| + z i ,(k Qٌ5p_O+hnS=w3f{ 72hb_ z4ڱDhx/O;^iuz~3.c*V P A·Bn͟dM1묖`,N/`RŒ%ƣڐ Ow 1&aJ" XKpTCEVp*7,o`i#x,4[ *&QLr ji v8""⢗ ;#; ֶu NOy4рC9Y ȃgf^OS ~,wNz%.*9BBo͞ [mmvP @{  "Pz{4gꗝ`p)/sWZ?_] G3kvVڄ]akLﺬ^+|Ȯqv 24nO,B1|>y:8cjb`r򷙁g_ٔK6N}F:7vd[yO`\Gkr m<a!,~]z-RK(/k?BI66mgcҟj }:::2X,/?I*ɃG`n@p2]9Ùj*CzleT2E-U,o<[oĢ՜^ϋ^{ʼPo켰MsV,f^xine-lib-1.2/misc/fonts/cci-20.xinefont.gz0000644000175000017500000002207714647725152016130 0ustar meme=e$qS eK:۲?effff3l3(33333SGVl>דn3")|7Gp̛޼nfsAxC׹,c*6EޤykMzoM})7Kg[jpiuXy@k͹aI^ҿQȜb_XEŜ u_SV,*tF8͵o Æ![%'\i5%Zp`[R:tcsK#w]_'X.}qY7^b-Bj9 *3|8{ \̅?㠣Ix{cR_ -IV=mm^cJ[,O*RmB*iF#Ns_tA` ώqxvu㳅o L/ugk\L"ފl B(c Ĭ;̷rɠF LVH> ܗ9XfGv9 _ G;kVy}[!mai]mƒtC˾r_jN(:[yiR%ͪ}"Gj"PdyWW:rT^j;EθXwx7;a$}U!+0\Y8$pDB^Rtttd4THoVE)K! Jl\/ Z[8_sFi髏Y/|G߿pwى<`T"IHbSBߏ_a˲0*w]$0 ȰTssv+9&9DdeoӠL0s^g-d33]Ƴ?@+nug{/vǴ.ҲyئezB]Nx|ּ9mĻgHzz-VnlH$n)/DjSg{~u%ޠcj R#/z1{0 v.h{[dakX/l_Bѿad~<XɇZnх>< ޚk7bify䁦ˈ0F0뭽+Lo% g%rf=ϳ3ki m748o|_;620ρh^6871j=83v/֊M.~g /ļ()O._aswo1 dKXQ(BbqcX׳4g xF3 #;h@aˢ0@{r=>1z:oē^@ L*tڟy"#B#7}3.g  '/G RE+Ym)$1q'Y> HM:ݚ7TUYS!F/!rmBpPbzj3R$Hh;5r\jkd-4 gTF) ̰EP$Ty %9Rn5mR\yeiDL0 ۿbgLb]I/.Ζ.0>"g bY^ע so703(mBR 'y5BiցxֵUpcDu3v)Q5M}<L0&%\4;} >gx#3$xép\(QGХ܂u}jحR=#Z諣צd1xF}/6 !,UV"(hxUM]*ugRZЂ?\k~]ZHpIs`h2d?ˍZP^wj?!"zV)rk471 Ɂᦱg]ē ttRgo`'f,y3Gt}i*&R 6ȹ q_g3n}P_ ?fr]%vuf7{,eW\ޓ-&(M_!W3VFs%;A*A2XzN !IM6|a/!htsϭG'E&*a1X AjԀ9QLkC[iA A9+!2jO>uHk/H=}"RX6 A+@J61hq2mi;&;nn VJdV (ܜpm gr@X)> ïjL|lV `H[sEvAp. 4v~|9E P"MKԐv\!6NՅeyrF)LQ|V0; i/tE}"fr.kdOU:ߘ {M@W3 K#Q+,窕DuhK[ؔƛ9d#Mu( ( U%srџ}HZr^9{+ۼ u+e#xcsZAN6Vh^A B}UEksL@Y X$7n#``#(>[1p0l$nNx܌[}8MΗ[$EbO Wkz (1: ,ۆs؉_S$J~ga(yڙ]k|&_gRU ƝXYϒvcZr=!HRTUrk;\I6jQ9yFzQӎv4*V=}mv^;b_y(R;ǾaT5@+@ƀO"Y|rr%ܶcYI⾦uɗBBh]v9kM](YnMrCH"7wK9o?Ww'6tښftl@ZPp]/<:!uA+2y#9ŷ,5C6676|4d( H <`Ҫ=RΊq7 fC ZG ^:{x/ח]YxnUATgCMt VᵢNM@14BEn}`!|Ԕ-R+>>AcE+HɝXq*M˃ة$k֒٫Q_zy3;ՏlMj\ Hճ;<8 U.LIyeOQk_<%?ח?`[G4QV:6M:4e&:kƙ5ј׊d苉EH5>f9ϳӈh [\_щ"P]jsk^r1 II 'LFOxfJ+*)M,-)߅:4>_"Y ~R뜚)bW.*I NW*Ku3jTM'@7_*QH!Vڅ}%(5nYeBD/jt5&uPV3yC<ᵓWp@pԺŃF@,1Fwx-_mk)_(% )G'I>$jkXaH% €0aIҰ3]$ I扛|3Դ ńy1ptN&^GT0YMtcb0x%?7pL$%_} 2Q4`UIYn0qQ> <zAŝDl! T]:e]W\f%2Eu Rv7uNn׿- .l5YAy:tQI/ذ :t,c5Oe@ t'Oy ׷vE{tB`qd-t2^8?vx+[JI. VOI@跪r^2e_913/pJOiEgWpaiH`2u%AGsDK@J`\0@=~aoM==ab- W4Z#:4q{`.2M| oZm O%$WS$ɒRO^Ƈ(7Wqk KLQpXqU֯j1QM]nx 4\f?fcTcüz[R8WlX*Ajg | ّˏe-zdy_y0 @t͜UA,1we ^@B#VtH )*Hz  =<&8HIPJ=E3_Osb)0 >wEc`{ÀƏ1 =W)C<),&*`՝ek \Z#dq$1V\0/VfyZT&LQi/RdG9Gȥxab݄'z): РYLgldJă52K9wOΦ>1 +M gT߷S?- O =& cx9& 78&aW#" R;9V6xYp'J4ow ѵBÏ&Bgq8a @0P ;` YiL aCOf= Z40o@0$?G0 ?YHA,=:q*Nƒ~XqTbJr#3]` S?6*b@L_2/`> Mv&~f@:Pw 8;  <̳~vh6.jIMt>)EYBrX +ARHmq ϻWJR)PƬ lz0Vd-W4Ld̞[S+*vw@vrl4ɔZ^)@?8a <rU0,pr9+5r4ØgK:s4dyd*3S| o?S/KCK*3ִH1/ : I890a\;~0o{'L g)G<2&t /~ yR0\u.>MK{ dJ 7Xs̝0r &ḑTϞ'-:]ziGV4_ôN!N| &ID7W HpdP9⤌8No'aI$lj:8'C̨(%"2!X@c8t 72//()]E?bS} ɱ!NF ukp D eG:cG B_Iq=ɂq2I٦߾KHQiA֒_ a!`Rӣq c#Z;XYD.[-;ac%{~X}3bvέOl<WfQT~HP",[L >Ð5+9B蠂x ,ֱqK3Mrӣq.^ǧLJ6$()TZ 0uԍ(GAX8C ӑq6J[vkMqes;_^Sɫ{Du%%Tnp${"'Jiv{b?6GFգ.{CЅuOxPpF"~p2r:/0 Y3Mc&~b_bt%˨,&0pϹ_<̡SS~_wQe?퓟ȗ J 2:*7*)B⁤xIBnlM1 dGI,3Û5]aI9_o;?b `2o›v:hʪ|Ub@LFoaQs$!n7r" ,~[)>k)|\F9"xYW+;.>Ba>y)}3\8/Uj4*0 B[ >e|P0[FB~uE2ks [sXi^Ԅ\FnL&\,asg"K}+s ( d ^]5 JBsU8~M!y/+KP%2! >lV7P- "#{ hBv*VvCNmi2Ed]rz;6L)ɢN/o^6%ϱHYkDwQpٿ۾̼3ͺV|#Eai} Ss>S# ϳO՟~WIZ{'d KZ|LY{Pg,Ju04z+dޤ+aKBv?Ρ,$0!x=%8gjtIL"* ࠱?/? p.rT'ꃎSG%ɛo^\N;ˠhgҳ,HovLJg+ O (|x|Ϲ HzDT!Ѓf1[)S(bE$XƪnV{O{DC:U&dY_wW QOaʊW~vN[bqmnW/ѣ2 j4^3,]-Gm"2U֊.8*-sܾIdʞW1XڅVb/k$a:CP܍@ŗbEgXeImS $ $2@Ό9Kڠ h%5 "H]ч1?/b`0`\% %EOmy^6(v6ʺ#_h)"7qtЏ9TseyV[!O\[[d hxC@=oP)wco`θ||"誠M NDh$zsU ,q;oF)R'Lٓ_$jœ<'hC;т@1Q:n;tfr0eb ڍʢEd7Eڠ[J;_D عc{#pot?~񅗞BpVCòѼ$b+[ӈ`Y3V,0Ƿ6/)z?D'd%۰5).Q@"9ru*yUoQW'~]@ƝE 'y =S`8w1_uġdXMⱶdN$+ٝ\z ̹Hq}nV"Ȇڭ=)åWDWny6]eAi\"un .UCճ&^u+KC wG$v?3#187NƁ6mesw)Ɂ~j ):5G'ۗ9jd14Ƽ~Mu'vRED f ]$5FAqm}D60>҂VG(ZdsN;nL>yA3 ZVQ<'"SNz# ļ%g#B|.-gO} ƔnwPyMfwO}mIx3YpGx<0*Vn]OZuGf CW9jЮ([5;BnC u1M3 9Y՟y֭vZx3QV*iPQOZQWNW<8\ݵF=]崒FLAKZ m] oXٷ|_btmd,V(R T  Xx^~oNeȄӌhEz }{sb2MxRNjFle?4G'u@B" E)dL> ;/w2U5yEyZw ϻI z2y ͉+2]6K@bT֓2(cR fn'VDoufČw>zMacͽPglAp7}I_n2$B6R7'5Pj/V`ev"6,Jj>7@_.KH5&:zF^i0_w.YRt+H~`\(hЀܿJ2jEVd!}ń8zvDMx8P#a.i}䌁ЍjP yvCiVn=@AT+xD"j`NԁyG)$O<P);tߐ=h߼ ԐJF fXB&  AzXdɄI RA0Qw+*$Y9I88;J+n}uXHUn&[`1X3kb2 ADj0n5fKj$h~Fd)ʉV*j/% }"ж*lz CI,2|Ҏ!L>Dozy] WrR?znmG,dp f*ȂǮH#p2 ^ =+,&1%Ko_HzI+("6̾Z2u_ p6Xjʇf% 7hfm([(|YHF2 N՘NhUyYw~ Nj$a܆3O ڌ"Ms໮vѺX *b7-VI^9 )ߕIM_{e|Ȟ_}+hF%;0D H!Wf4&ibv%4{'y&5}A~rEV}G@XlmGN%{"Zw1,Xw(m2|}9?RK;F||*?*&ucX)/ÏH"ד/O;7,/T*g;fdljEcHU[$/c߸ɞ?Vi]x--6Rȅ#қ}No^T"hMZa/BA2#G C3)[CPt!Vf:-vk˽ L)J09޻ѶUK I6O( 4cbhVPsv7v("Wz=io}pmࡡHb DflidqϹo 6Yv "4ĜNێ xڮVUҪ1Y[IUY$}ZWmn^jݓ!QZ:kF7QLm~/3\W9bt^fSlB{n좟~h{ BXJT21[*|pQaJ-}̘~w}jQn۸? #K+`8u4PD & @PI! Ļ |ׯOؘX("y31 'ȩ:f2.3jm)N^8j=OF y1ʤclmmyD%"Kmy6/JWrȦ hRr)iEZ%Tڻ;?d栾1lhqK3c9p᩻;dW9ˤ;dc>u 2Z-ER[ 8X0Ce`\^IT'0?C;W=UlTIv;1OO5~HE'!"T(i8޻;#2Rw8餋 t"k&ǕvE X3(HڼF7=S7 m<<#h;PQLcA9슶 qMXxJ Wތ|&`p0"S(lBz?n9m&;CC{ &rIZL '"X= w~᥇vQQ۰|ԯ,I!$9 ɃQvB~; ;o8L:EYgE(la$W"V k(WYnrC2՝A?UV\L  gW"T^dO/ >ƹCʻtMA0LV~m%cț⚣cNX+^`Nð!|ˁ^<]Šlq:R {*ЦNIHTt*MrЕRY f犵X("E!꒖|gR{ԭ%6)no/^p IENse+ Eٮ"=l9`M8)O t($.q٦bŗ?$VIy+/}z+о K*K gVRKNψh!+S h z/^` _ddqut1CNU}|6Pcx˖nYGb+"03.;+ȯȻbvQ-Uu8,ym٪L3!'c5>I$& yJZ)nN"C@ aOJ+tVYHeC*ڧcv^s]=yLwlU]3>l̶?& .gmyghQLx `{G[$Ar <]uyhb m n~!zY9H`$XŁMdEBw72c !'S "a|ȓ aW|ǛkJdʛMYxPF(#8< GKJIurA:duiZ=U+꩕"9ck, ݄ư,yܥP=}S3 pd9m_/-zsUkaVdh@\AH(C m9 $캁KrNn&Ty},1܃eUy0Qs9RK @ˤ[=佱I2XHq^Yz5>)K~2I ;n>˂G|rҳ~a(u}:flN=he_lzwwIcC4!j2U$zu={m&v "+*`{aNV)Q- ځvW~!.mH(`#.U{sS#_ S"v=nP 1V'Q=vE'a& !Y FQBQ5M3݅3q3G!?O?܌IViW[܅˶\λML]l4{^qwfRIz%{ 2csPa뮜k̑W]UG^Ssj7oҢzLlQX/ɩي9RwXIO5~Sk!JV.Ҥ/B5}6{O 'ؖ}'MZNn8]Mv,0bыdLi`=0o?}]HS1^X@BDzױo.վ4 (t!쪨w\oe^{zd'1e!OU $+4HXTp=#:U3l+ Mf:SY.Z]6ٓWVҜ ~FJ3$f/i:́ >~o ۨ gD~WN8`6φ&s̋3)a/[S8NNuroiL&ίn垄ꏜt]d,cq'˥fY^3)7?/#<vœ&A3aвik@;E"X |YJzH;]j`"N@\+Kv^Q오ju\P$gltH^xdHbHwN1i%jhz?jUǜY߱lw''~=`*j-+䕟ٗ=UiSQ@DM?s5QX!L v6b \2:~fxgTj{.0#?O:/'#jM̿'?9~S49yO3|'gv©n'U>QVg/?>i=[jRx&rh &^ .ݏطz/~q f3q:hP& Nc$`qGKhMs!'2YXvQǞk@2&$hA?[[}L\LhÝI<큽/v2 :qM1Qqs~RT|hϪ/3U^s=3-l<.xܼ^?-ze=} ԴcDh}=N7''-O/Lѕn'3BkXWN$v/9xuӧ>`/rC9gSsO{VM?9U[V⬀EA(J-1!U$803haVF9s2̎g|:hN{@^$^k^L@ bnP!Tʳ[A$0iEz\`gGX݁hš> c7皟Q u ϦDuO wgI~>A`o䄟Jk앂sQ3 }ɳ%# fiBQboői}oIzPD"ג"tҭ= CbϮ@rf%T+f@V}+eǖ%d} ]]n|'(ODtLt  Y wwc2iW *# TYZGb BZ>[gj%:vPOa{n4Lܘ1Ҹ &l_(01IS#ɯ%xS ! .("nj>5/zkv9GSsϿn# }~7e%ڻܗHD~dqB/?sϿuBGiK ]/FV>eB3?+G -g2؄l;1[9.qN](H F[ ÍXH@M$j"r8I!TAŃ@`ihi$ ?qV9B(x68mV18֎Am kKhHJve9P`@wIdJ"Ƚl8R7?ϟ8@NO26h+FuYmqf[ԴgH|5,a/4fKڳalA^6[pm76vuo$A6.dszi)*Gpa ?B%(" xfJNUI+=U|1j-n/ғgC;SEQ@ktiMd HJx2kᡅc&Eeμ^avjhjQ{y_9 X͵M69hDJڷ? ,,[d( V%묙t3 }FUR0GL5O\\ק6ܙ/w.I*ՑU MSY1pwE%tfU%9aA"ˈ-$񹮋d*DP14 *x%݇7j4X0>N!&4L8/@$nP6c P}c)6@|Ёh9xfqh I|BxFS1[ 7C6bwZvE<6'T6qWd8u5]]:1xXbFuLŠ>7s?3]c"W`EmmH  ͇Kޯ~JpPIbN/.T|S+ vy~.@~l٣֖X5Q[?&+j$2WJX9v7~]lu[ ,R[ ̬%I؋ٙrz7ygJggsg|œjg}ج\+h@eO租;o41%?)8$S~?>i^*X9u‘ނDU.Lt)b8odL=fM f ^EAi ?WEOljQhɆpL@)j=Ws.3]deN,.?}b[ߛi~wx[HB$BkC[Ml{b:?o>oO%=#O ],i1:ULљ-~(ؔwJɧ!ˣld,T0)3š3 ml\6Y"p*_(ǀ8gA%.a,${sI]S D#6E6MCڍZ_֥?˅ߓsI(ˣ$r<$xQzGم7;5!.x|ӽ:A/ؿ5jp3;1?PQG3-k*U^*\c%@kr:2^sUx]{X_ctj1Ib\y|T{v!nvz#fFkWy}˼\X&]y|2w~6[amqX6t]uZfW^8[9#3xtB`7ytUd!VЫTB.;w`H-{ ]#N O8-?c*W28\U$!*zaFu1PdQ;<<l{ʄpjVґj1P,=1 O 7yB,v*6@K]XlS̛'ճOc竝\v\V+dly]!X؅ݚCS/*GѪ͑{o0!`+4ϣ. ȷaEBv0ۅ(,(]r]`R||FB%2L='4bw Iy%( Hf)4.zs )7O8џftO 2(ΌQY(|'CgԷO=q_}NZj AP օVN3a`BJ޿sՊnON/eci5p?(f)]Gˊw{GUY,'zfϰɞ\F^MuDϖ|1.峏 UavWBUWVPU*}ē,|^UQ&y"u|)j2 4-.ђc|—\-+]/k͞KUYv_ըSB* T6XH94i8SQ- OFA4NFI- N^xD$u#vYE ,f*mi3BA䡊 /{ z]:Z/KId.^0Z ggi\;*Zŗ(э!*Mzk ]f:rfS~͇tTLgg-? B0C~K^?ḟ|F/>Z3n)P>V>E a4g=%(D>#ع&©jZ HObv8=tg >qηw,{p'L7I6y50 %23zeq.j8L]\j!3[~~f9d>N'Cd_,Vrleioƿe;̑mzAY jJV\/bCDRCT= p I$ejs[lNWnQ;M84xӲ5s=` uB/h2Cwx'e 2vZC!<"/KWgr& 8,~|).&fɣ@o}>&?^;PQDCG#:J~y#vlWfI.*,:Q@=}n k *TbI2Yp;:=iPbmtAR~B1{_8 ,95Im8*ØU@_g;dLg:d_>ȧ՟y? =eKH@d{V2Cn$?^|mi@dF[FU!WO:쮖qo\4zŗ*qiPj2l- =O?~յ\>3Y uFfN.縸'3ѬYxooɚA!jh\{D:]9 u({z2{t w>gx0p2C~D"V7Uؒz"H&|9cV$Ntz8Q#!aIcMe߳l4w{5сy; ~d3tvЍn+H(5CbO,sc 'CِTv>g;ǣjoAW[p8QЩb?3u0 H 7Q{ Ɠ®|'nGR0%y6nQa`zN+Đ9ժ6F8s^4TTLjU*ZmźSIkZiXQ"\g3<[a? ,&_SmsAQo\F,,͍Uo9\mlM] ON^: C @ @8IE{M)uW0 eo6bM[iJ]: 4b! J; x#5fEʦ*D>3 0.]$Lbq?v WߐT~֡Qj\KӦy,82Ƣtg5y~?Y~s`|ǣ7/Y}Wz,P]8cBGJ|1I-_YǖFַE>IgP L6~*;ݫٜwFZPWAFÿ3LBOn`\A[ mlc~ egY{ƉM $h pKC*]Z cs9d$UNHd(&a`|;oD;`h=%"=2C2iڵ@ ic |58LEbWJ2c2n\`NBwG( [,Gg#Q,Kśxer`cqe.<DRˠ݆qyOqM|X<4q:%t;i\'Z'|\$1M\7ͺu>[ˡxMb9,a!JC}~L;tOK/LO8pP?5NFD74q,YpFyyۊEoBgUǯRFJC Ō]1f Gui((~V OzdsC&Xc=g㩆6HdA" O1KqG>_!?1IMu᳓'5E0%f#c*U&Y]ߙ*.pcf5%φjpS=P =|,X,뎣N W="!Usպ9}%,X( p~~?g- ~F*d jG6JeSxFm|!pT0MU\T X l6f!SU/>lmhӃ€HSMS2jTonhqs"Bd4p$H1* *H=lM-#hU++&:\'m->?nsLQq.F#~O4kưEh ]|D;}o$5񳣳&f#7Yq0=aպxƖ^4NjuEv(>&֊y"fD(hl•69/ 昏TK! M%Lw7)04t(%;QwΌuoY="].qw* x9 O%>~6$JcqCL3g1Q\Q%?VOn'r-HKq18r4*^:[ćjU4r^K#c&c*MuJ,J$_55 R Ǵpexd$Vd63>Uh]kI8-A3p\Ƙ&YCFI ˑe%~eCC?. M` ' Su1zX<++f|L-פulJs]!UO@"%'&#.4Дn(YLCQ7݄f~cxRʼ4Ã},ٳhLi\# `_rm.9v?ExfFOID6*:04@3Vr?́P`+ ,qReۆv; T>O6]b EN0ƿ|h= n65N:{[`:]z?pXd@Fqx6=;O&CmmYZSOu4Mzd`9$`A)['LKMTr~y(z)bx f`fNcsr>>-'[zQaH;psxJFqhw}Q{C1(6RxҤILdֈxPk/jUcyT'ҒG*Ȥ]`GJg1tBK9ިrsԿaF@d*fYsn?s)<(掂V Lp(aR#22|d%ZLTMTRA>+1d/<9F>|? GADn(SMfy ~QWM ]hKdRЃիdCENFd~\CQcOƉi/qUf /UH!;Đ75Sq ~=gO +Hw<˾FbK paTXc݀mI£;rs{- mdć%ڏg}&'= ]ɕ:8 ʥ5;ʍg{b3s@?9bB]`]|0 _iHsy zlDYltݝLLvU{6E)ϡpw3uX<>周9a0-v68Q` _ Fu4 jwH݀2P(`TǮVKm( Mf!|Y^G|{)ni'IpbB[6!(N!xՍP-.`\Rb?m0l2Y@!zO@ޖ4 u-7K38pB* faZq%|?ǵ0Cx (5i`O,id",e 8˂`iܫA 8]{튣߻:yݥǣC_=YA/r mP%m*TnlYJ=k6Ͼ!#wV[ |?QhwB~~+w[=0IOܴKj7-X  loZfQh-EFTR1C4`4ٸY<ɣjvym4N{&u 'zCAA|d ՞r)x2BtG`XKC`&^ ,iᆞ Bޢ\Aʅ\1@.Un1Kc}}Ԋ聉<,˹ê;LU1 S[ ; /=a KؿK]a?5x.xKrտ΃.6>xxPdmV)}p9)Х>k}䨒ݽZ3d=]N.04jC9$c2C.?2,*x0僘?gjO|)C_vXs4DŽ/'@0_40ލo\V;~wpS.GΎ 6 xt"+md2/LǻYqO(W%]cx8dgő[!*QXHƠ"TK*x!vr]x]Cx<^2hQʧ+3qفVN9ҫ4P=\gk;[?NJSS*1d,+['iiqPz.7'.&#d]Y}νnL|ꂤտ_{_]~G._;,_PϿV粮^s)?oVʟfoOиo~hJχ})F#@[_^R+. om,myߤ xXU(`ڗŶnm_2 @>}IX,8\}ɮ۾ I^̗֩!on!ln/i9 |>I{ѧu/y[Koۮy%kCp\: 7;zs룞*?h鵥VE/[z(1>\K`Y'># E\W,r[5lTqif*Tz㠦ס/Ah}f%{|pIK-_d$j,MHJLM/M17-w\ښ$MWlX@c"^wmمd rퟹ 4I^!T7 4jib@܇ذ 'g, @U~ hW1spWBc9h]5n;r^6\\tHt3D6PMILti-n'N'& ܆f': MM@Vzr@BWZ2Ot_Xd1w7 !W|mLr5nhI1O ~˳ )ʌ;(Xu5v~V/aK32}s/= QVzbHW!u^y@7q!3iZj۽{y T!DƦ XPOR1AGCR&9xrGs R5`yHb1fh6@/0m;F^@ -d\D2v 7TEAٯ7 {J9vRvV(gPp%h҆/. "l5Fig3h֋ۆ^((q:Z{٧ mQw&XSG:CAI]fINDF]/ſ%JNV})t&pyuŹ׹Ԏ~yWzwO5p9`7z+hjeP#J31P749QVy6s5H1(o{ԗўȶNP\QnqEc^p3Vd'9|m1ԇ,fqtM#9_)GH>VN꜔%ˍr)PGF)@%9m*|d*BIՌCdd_+RO,Paf O <4%;?ޟķ>#u_zHe<0xK2X!G6(P_Seն(?yM.?(Ý"|ࡱ2>)!Ie5{ofyEp68olb}ԉ3wQӖ =["y M Ralr'U9ʝj]`pc"ץrnb}T _pv<˗R=hs342PeAD4GWAu6ݫ¥q p=_x嗟T,Pl6I^MhMʐ6%YXZp)Z=e5.?uSww[f]&ynyqm/:WGEs%򟳮ѕ[\<n?xCzyfAgFRo\IifwX_0W!o o<$dT>͢ eȝO ׶X:iq1 Ё @1)B!)Kf_$'┋e AIc4'zM|d nQg]!X+-̬ "ԈWZIRp%/9avDQcU#V0@HIԡ )gF"^R{@əi@ga@lYsKYXcvt6H.h?wHإkϨlji  #yOB䔵g^-9!p!!gRN(Ga4iBW0y(( P S U+ܨTP.q![b~-OAxPR=`xUf3)UJٰR D ȡQ8zf0'B$*WbC+-ȕNYVX`6si=_ihXZUC?pYCE[.ÝMC|ANABS`R4+eJs[ut/1&gfu&J9f_ihA| H6h!4s#(" 4'Yei#֋.ځM^c^[&IZ+،B(vO,EG.B(SNq X6.d Q+/n<X(w;kcb]Fғ$"M>,M&_$8!DWdf >Man\Y! v V9JEjlja7*HtJ #LK@ ydUH&sjfaΊFJ@["HEER,dF7va' {>["- b˕D*3XQ Շi?E^pgYmpcor;x Jic۠竭։$Cl?8N` pxh|0# ci΀DjLGYJ4tV!7秃q{Ÿr"ыm<t'>7wG2r\pspHԈAMja=A~$rtdJ)U+Rc'xo ;-?Gs<TR!uG`ΔؤdAyCf0ټ}:Yf-$;\T HŮS$$NaduJ0ԅBBkX3[D,d qKwkJjUq??qh84E["Ib  .fÄny{c+ϴ0ay{3v+_Z ~ ;*cV/q[%3 =?P~&-1bDCqn`}y).߾䛢g9#e|{t{|{|t{>巾7&7~p){BGݣƋ V=T9uaHk_1]CTN "sG[*@f  :1A=BTLjpr@$͊Bl'`yp\=W{]>"*/=R#q(Wx<63j2Sp<SfFyA 2E^6Uy<]6㮫Neۿp.졤v[f+Y{`WA^[0_ia((G /AG'7upW{<ney%Δ%Go]R6Mo{ϠJwSpe ;|?=A|=WCJR[;Dpg}  #gnvy9hoˠ%Մ-{Wӽ7iuaK䋖m ȓϱ d'4CCP% Sܒ! (J~zݟu2VniDKY1qE0uUDAԠhgJ9 RJR-g^5 xu04,HTwދoѓ+&|UF0T;21Ȉ[''~CNDG#ra;DHZ(BN"`<@9YʑmxLl&g0/1͞<ߑr G:F~1B 2Za1p$ 4bRwmGkܦ c^y?o{6?@ЅN$3)NcJ8;^;CGdl.1t*Ί#{CQ2sL$:H.;`#}| (JVHL ;_ι̘t[0Eت< e'ɗ2h>SYMf'γ'\hLUU 2׹X"}[(&Cԫ+2O0 mKlz`b0(%B?BHv˂ tEZ;n_hYmZX:OO|)_ =唂&jU|s8Nu3$tãD,oX3=.vrx<xc`B܁aǖ@?bA {}y?o9 B% ʶ#'KsgK G,#xԲC4mSQtj-o>7mĈmmh9@4mCچ#E-Gml9@ml9!Ɩd Xl9Gk*Z'n*m u&2@w] "YmjyHmOc؃6jyV^ET2) {WcDlH}%@TPitj4+!=)?xOW,X"i9cf!6#$sHm0DPh"42H&5De)XPe1H*HS5BrFHL=DB>XC$v\Pxx` M#$JqDʇHdv;D" <#s񎐸#$j"`Ԉ٩ hxZဆ`#[-M&C5< hmD@COJ{I%⴨+TzJ3k+DtQ榔TWOa=YC1OdZ"ʧZŬ m"QV-S"]|(Oq#PmiFt2]ĸabsr!/d |&  Iq?ܧ|ØDM-ˠ(zd2}"Q*k¿4J!6(ihx*=@%2;)A}X+WV%"D\pq@k_s;19eXE,~8VuAVy&A8brFskUx}˛6Uj g.'gXIJ1l-TwS~eR^ExqiXI?7?_׽SE*vGœUDs)-xisJwermzVoaiބQ2.M*ڢ*+wڨx5a MdhI]j=Q9 gUMEfUvvl\x rGwҘRy՜Cˏ C%L;fxvl6@ԉcƊ]USewFV R}©E6n21q}UG}lR޻cUrzHk7֏.%g֏[\of4>G8O[?5N_lj$XJ'1R8WG8 2E ا,N<u.?2UTX} .8ҨV r*qh4At%Hj rFpD6 QK Phhkc-9@#Y0E7bΣPvk`T EX]B?ڪ`DDZUL;h΋>zT늯&4;"G>{i0d*Her.%# aIvglW{@WH\WAM'*P'Y3l-KbL>‡0kj^D̳e6Za*Dv#Nc@n<2QczS n*JUO&ь?3Xs>Hs+DHs+~OAPOmkTOmHP|#&Ajʋ-Du$Hd[u!HdOIѶ*T)9i:txN\S7?,5ʮ]151^ǥ{b2M_brTМTU)PP3?۾oD͘RԌ|oiɽ\3JXfT،n| EQM M)P9I0bEaS>cdTKi5wpty~å Y(,,bfqL 4eejF>Dޖ.H:^2iFL;YnAL5Lqbc}aulqA,{ى羛z稛jP62{z;vSuwXψ R;6Dg:ģrϧLEy ؛|]sc#͝[rw2OWE\P!qHt>&e*ΐa1JR7 n Gyxni xTAb% 7wo84VeMñuW[q~ߕZ| q@sY|@9ѭXnYB#!cPȜ>UrA!P!Ȫ19  896FT! T8cTGe5>nxF.=<^GK4| vJTvERߧu(Wl̕? +[=0,)$V?_Gx)YtMJ'D{U]h4Ѯw:S_;Yi{j<|gybi\,wG:]U˛vW}Lއ gZtaCEiVgȎ̂!:!C 61rylˏ !AoB!̥ E5c(=VyE`UOLC2'g.!aHo43rg?p(e]; ׻RnSu6MK @ \ҋXTLZ!D@DmLT[y~z(L+#8&̎%Վ~eOX& l叿3%ϟ%0L3@:j֡Y^@]VEhA;W$* aR}؁b)Le?hd3i^r@yTkCeo9S;Uؽ!bV@M$2=]eQ5ptN`P4^Kj+IaeoW_y/h^%K?z-Awmȿ}/-ML @V.@wY7oDd=bIFaÄ#a,/36WL;,̜m'PF싻hip5a\Q]T1;%HAfÔN>W#`H2'"Qe*i Ҷ2_^@ T鹔Hb{9D L;NfDSt\2fJR M*a`plF^<'y:%.ʼĹS׫ҩEI){0MdK}".$Ƀ Y.fq]f&*3єoԓg{75̿eӚ |U[Aĵ_~ϐ`Q@TDɿfnyQnϜ}@oME-/a5\3kQGiًPxl /Fhb@KYGۯM2mhݪIa@&Llf[hu'kG5N1EΎf3p0d%Jr(͑Qj+Ϫ тA`6hU4&ϝ]n' wKR!Γ{N}M6;c3.vA2Vb*iH1j"ՙ=(Ԥ.DU' f-ZYTt Yf7,p0(ȶu @^8@/89:#jIڥeLkBOx\CdLm W @P㐀 mVq6ƭP˅[k `}v0滮凾t%@= Eʌ֓+])!2g9MK>_%ekEm.闟i$Grο?UKi {d8baFg\~gyEd{Cђ:("\aNZݤm˃ ؔIoրveM x RG4\gNR)qD'SDwtW:2Wl2k1PiTgFD3%bJ 0k11f>1'?!.˟yoIA3F~*=dwf-#XLIr S{$cTT) %p#$\ld|R>O@ad]TX& CTw\6 bT%jilo&ѱK/eaxD㧑>9Vˀ:ӧXOݐU[dlk#,kd4rڤj"#1FQkEx*g*7ev>7IPJ]E%։DW,}K q0 k6ܵ/L _mɑ â2Ehl0PwkcyumDUFQ"@0dUAK9 ^N+6j0{&;ztzPBA3Z{ n}j`˟sw[FIn&!ee!dMaXuFF "jglXkZHR_qpi36$Ya$2jLFs<4GbOVj Tq 9B@>櫓CLcKӷ$2RF)쨌yfS>T)I!'Yݓ@KI#?s΃OZP|Y7Ƿ 8-xF"%? ).[{Jvz: V}Jϔd)ݳ@}k/?t2ed,\%Qf͎"m4):_)A ـpP 7aQI )f^bHK.K`I3,c#A2L[ K)n 9 "@) |]F# T]HY9Z" B{~sA]ț=Ӆ aM]}qvS6|r3Ĥ4̽/J2VyOT`<"1?MGT~bUi)wZO?WX`lg`31+j6l}G]j}D>/yň4⍸z8w>!,reu su6jIcl$Uj,|6o*:ߗbjm4sivӅ (*%hi2O{9N+tVuB Q^\a!e礡^`m%^[Nx[4%G [Et]MOL#K7[UAFQhpWp Mޙ;5ԕ"bm胝Bh&AddRf٨ϋAIA"7J}uuv0hv U#~\՝'[ż7лT}[qli/.ޟ"PGRoCo)#MB%#na)\bY.+rh!5`>ɠʆ3cpt5Оep_Fn+j?.~Jh2"ٕvѤh!GY,Mad̻QFTI!TMJ} 'OxS ^XnF[f'K0 JIeUaX5%`. Юg7Y&dUrkުjEQ:T1߶]KIt(C',U$@)BG #ą}(@G(ߒ%ʪK- #!-ءȗ)GtUz_T8kUl尶 ΛF-#X7$@7UĜ2}It& C;5Y0Q6o{iYk_b 1}y_[42II'RY_Q}wHIbPX! aT-@Jc[_G/uGIZ]*?HĭC-^td^SR ">/Ƞ\_(xc/c/G^P_8{/8B  CCtt]t\c0BRİF=,oslXyFe=?p^>vK>ӵ}ɋh}39Kߥ?OW\.߹w',@` n1 **΃DlhoQ6,q?~|3dvsBy鯸|N)"X6rXGS,j0H.Lq 2aOc~X;oL6b?vο(WIѾR4emtiK9ZvX F5uѮ9[i@+Oq$9CR,G:XCrC&rSF ~:Ix(‡/ݠ\;!/=ԯ rcm}'T^[KEUlBJ*PAY!FyaE`3Gi.d~(iżsXB=Jw~DlDzoPi/-|@٩w(J De2x92tyͷ)_U৺f课0ӹuϓ٭pT+¾{zQ*.IkPX2Z9W76߫+&Im."(Bdѹv7es*@E OuAQy߄*YťM]]Ri`W:W*( \L2Y}7 Ie◻oB'uլk*)kA@JBA.){qˤR:,N^Ug( =Ըz{ %j X`R`pCYL&FQW`@M5o^ND$oAubǻN̩oM8]ei FoxJ~&}+z2)Dv%'@&s߆8 в,+Km3lv#4?Mj*(/ÕDCpDjֲvǧzOҡe4iYO`G HOZO'l1=}+\ULLsɒUabAL/ \06HiNoLK; vc"k+WNBםJUizߍz$8 DV5_L8^'2P 34ٖ'۷cJ +X47\3V3؇+zCc~k8_(&2`xxp21\Wg8cđጾ(S1ݓxmXj$w m~sE9( :;"=*\~RbbTV¬Tfn- q`\P6{x9ؤ'z=jZWz𳥯T]x:wWZ͟PY #k{RDI;uf}oˑQ{ o_~[gyo&2c,J_Tk3KԊR뜅 h lJhgY:6 w 5jkP "As/3WI xI NwfV'W΋xtwSH A訬O~-?F݂]Ph|UN{|퉫hOe#{̯1Ri X*bޞ0M*,8Ξv:{0lIau'Nc'2V/˕cغXnA\RXjXIK"ꞪҞze멶'2$cE*^=Q}_0s=11Vw+ =Qc"fY,'=CI?ߞ7_}:9X >T(.a2M1^ rtV&$Im*ggkffo|coJgwVY'5JNb3,)8jX2zc[$|m#*),.2~nU{.-&-VoJ[Ų귪u5h?%Y km \e gz*q2o`oyM{rzOB?!m<de6pt9_Δne4L00*oN\&E\" BŲ@$YggiThJ)lFHÿ3YdŞ6G}0E@v<8㋋R< r( :,WJ?r\A|%rl ~'dj;ɑ|*q/4ƋKb/4-CHW! q'ZM~U Q_5"d hg່$=4Ԍk "w <[#P{w N z2njyBjEw^~_8#x'h%%(oU֎~ NLMt|+UwTMvzJ?jE ȼ-7i碤o2.*ZPȜ士QjI ^9R*,LQحDM/at-'&eG:",D? *눡$ H!_Ow߸Z6ϨJ~lz[:8n>*e. _ġJ#' ӽGC~ZbxW?4iPМgւIW';E&)+u,A!j8`5a. z=gY>gIt2cY.+_=eוt2{9Vc/_LA׃Ú{}_Y<={[G/N"ۧQj{zڹHb|5ggXurq[bIv';HnŠm^Q:h>BmGjX>g4"&4ު3ZP<:dCCT̮i1*i>[,}& Ǩ{! $mO0QF4(WiHP݊!s4[14v&>Bo P韥3Gdo hZcS6b4snb~]~ >V dn}pk‹=A/ tO"5t9 X{[1 䃑gH@H(+Ll;dc.1K9&}IU",cPz.-\~еzLd>ځCbmcj1s(:?%:fG$q [[vl(PuN4k`O* <#?s>Mdl2{H&Ka%Fzn23EW3L#AʾB}5i Cvu+ֵz/`7.%4$֤jdxv1֤v(]%ܘ|  : XP찤n۽Z'uQ<91fRV͢Q)ss־酈yim;1 4;C;@h{Ib" ##}֭*l-;bx)1w/^w̡NbFPKu RÎ^+;g$Y^]0p^=ѐO>uN7kedQzVD/wq.6C!qH :Ćr "&h9 hP5#\cęCʋ[ mVN;n6k5hf3XE ƋtMQZ-!彎 ,^p@Fq[/g\-Pzu]b\-ѝ.̲CSt@ٖе$WR74G-Ѡ롡A`2M'H yI^`ӲA!MQ6544(у5]RpI"Pjve>̼jv߸a j)$)mǶ|B4rG^T!͕ci;8:H7,]M8萩P1D )/.1-\iɕA9ɕN;Aܦ9bBJ9k˔nk,HSG-Fu nE[@}ɕ\)+\J(JO Af;gայmѐ? z\5z6 a!-tIkɕ\)+\J(WǭKF.qg€Tv/w1xѐC-;QH'pЌ q3 EL1ѹ"0a7@Hd"'DЮKIf$ 1'`D/9$8 /kTftnLQhH"ȫt) 'I1%7JvÀal8ۈP3a24'~"QsWY%fܾ6[Ӟ@y!!ϵxJQP{z0Eݿjo mb;h_Z\iԒ @m9a(t8lգaKvA#Fb# Ġ%;-IB^En Qؒx0x4 -  PLJhhhUQ ȧBĬ&>CnE]IF QK;d Ǣ {[*څ:<.{Q/?x9ܚ$SexAL!=``ZOFo&ؐ#H=MAn7肟7|"Co(2YQGި-:pzeZ -vFB@ӎWްj7^~5`,No`̘'qoH A=/AoDj{F(G;t X ujvM5߈?mV5MģQ?qޙݖDa{(o򓸲B~NK!N6i; G.Da:-&fwl{fDpt)(^٘Ϩܙ(>:R_uːXIv|[XQӒit8|/+NC6F냑)ӑq')L lz^ϝ9_ayLa:tUUR+g¬', ,ň-_xa2ޯ;]J:9GAnh_( O!1jÜ Wjl_g+a%&XHf9Tȗ2Ңe8n.bu Aq}CPիn|xQ'q7ګd6Q*!B#ƴ,GX+Nۑ/Lcs26QB|F$/ #zPKXk|h5F4㭌W#I`$~ HAgs)T <^]zAGiPຖ,=d'A˨.1N.sba\O[.6;;vj @ `vd Z1? E5`HO.˻8̉qqr? &M'OԆ cr)trr]%eN#IϟLM2 #c\g3$E%Pv{(nb+]&V5HJᣔY QMSydA tHӄ\fU"x<(R<!avn02iHP`r1Ն .O{Kn`x fb$>ZjwH?o*TG\e֓ڜ 48(3&=.ˡwmfT 9FX?cd߁q@{b/[pn6TTEzBwdUr@JiGerL шWpМq;%U-ۏG8HƷaH:I=Bll z}h$LD21Ҭ"HbuHLSd1d5+fRddu$bwi:@:@uD-GHtO!zC!Dc$aJ:@ kl:BABLHH䤏˗pm'xP*x IJ1nM;n8o/'=}W|Ո"úl7Xx@MO(pyqՔ^eۅ ǝ|O{d'=23G[|㶁\[s:J^/G4҃"ddN{2_Q#=zhώv>@@{h@N d'v2ߓ18= ,~9_c~Wt$͔1,o#&6x@5z$+jI!I-Ϭ$JM$^jdѦ66uM퐙,t`Yih8Uc+0#ls>(׭[1D 3 DX4i '7V,b>aA~-V0oDqN\z=Ɏ-0!QM>K.e"h1E>rPrv9b.Xdd.3nS'>їL$l> БkB &sǀ(U⡘7w_M(Zm0(rNa'mQV'~? dWڏgRދmGuSxu~@ka3HB+'l:cTif'+;e$h2ׂ\[z=3Q L 뫢۫uJ'>'I_T`6b(s_񱀘5 ׀O(ѧIî:כ׽!^XzZtu} .^G^OFCg_^_~Ϝ"W g4IqY+lpԷv,-ogN!#th$Lu oy5(W"v.={bj!?8B7L 8 6  ?!!68 8dϦ,<qprܚ=bka;vQ/Ye/KEj]`R0cjze7  IWiCUWV;LbLn27xѦ d~w9l#\ [Rz;"} $eCWeC 2T@ݦ;E9kR$ֈul2&Iڂ Np&I04;S2eQrJLt2CM-2 ?ZJUd`%< NE3AHo+Yl)6Lić^s" uUl{:=L犵.d>wى+N8V{P]z`F.PK02b zℚHH=Mc6>yz_yQBXn lE?BUCo&~`SMdl+ST8F0\,e`::aXue& _d݉$AslF P6eYEU:6q׊/]dsL~}I({Ml\&N=2=EdDEe~)AP7MN@S卧mդmq"m*;7`H/ (40'NG:EMvZqTAS `Ջ6|UT'ZG}i.(eoQh1gA|^U>*,9RR]<\qIXsB]߈^'r`{N,K鑞h) Ye:)c6$UA «k YA?:e 5u,' J#ʼӹ[Ysa4tagC$*Z};& I-5:II? I_d9.8t%s$ uW*-\b׫'q?״wbCkQ&sNwHKH:IF'I>I'!L)ͦs@H[˪"k?jt3nLobzNtmU뵻.p$*{ݖ ׻H&$'I>I2ʧ#{'ɮ+k.E)1N4:l?$$'I~K$,+oMS--J|TSEZy+*2+[i/OW"=M=VZ|&7ŭiFDQ^f&ʩ/U B$9/[w*+3%=:mWÑ"@`QC41gZאLXqޞ t(|%G]s jp2A}6sx~7\oW OTTB8NZ1*';pAR5 1_'ut;L*jWZE!TGYH Π aQai&6 +=3d7QY-Ϥ;X@r{SV(e|#!,FOgסG1(e}I}(I}Jzgץib̅X#s/r8_+xt𚔠N^!t'5(9JC 'ZIi}R/ vR߯}U״j(IQ=a5J7~Q@}W})wR]X|_EnpQ7'xk(u?Q%[X&cl&\q),4l!l)k[:KWeL4."NV.okIU&Zdl>CfVq"S﫟2ٟiTi>lRu22VFɲzNmzzEȘlb*M Εۢz=$1鯸Į۞V,3Y0mm]pAot#bz\G˷JXdeF H_uI\Uj 8PtZ

>wGló Qh)&1H=ҐIV wzOtv9G,?7koßlnUxlOӨW?ɺͧ_>~mLyI!{h݉"}(m.+M ^EU|JspXޞstp ILaINjϾ/M&oZ:MHR6k 잍.Mn5ߧC06 _Mn7\ZޠcIyb_p5?swBPks|ڰ.~n嘅ǤR~b>+HǬ#<^ƹ`O^j5\sALv-`:(~2qH @-T}' P'\kirxoF SՈ5Rdf]d)j7[bVMB_zşq%3s>6T odZ&J^ZոS_eŵP|Jgl]DvѠG%Is=Vo)n}ii-/8 0V,moa|.QH^ޜgl/AY,fyIt*+2@Wók}o#ٮhWj]dD6ƞ /W}S AH<.L{,fPvwE E P~Aw鵃b=+v.A;1(B? uh6(eil1kk `+*?PX%A0*Uňf*d#b+0j 4xɛh;.ow1 5J)+P vWKō}M-LӋ5v{Q$٨T {]kXɗrHԶYt:R;Vaf!TƓZqv)j b4Z3b4f$FJqqgh.4~YŬ%4p!3áF^=ΑKhy6"+(J38B/ϴT3.$Z,JJn5gޜVO )xͦc2 <`|/ȇ/E/x)C:A D O=Y6)|y᳁*x P1VN'178u?Úp ʸ13Gat0sdzy:!d|ʚf3ĥl$-hP[=Pۨn@m>DCO >yyy ycu>Zȓ$|tkfb# {]o>d m ׄ|5ϳ t[X˄_r&00Y{YƉ="ܙMP,9|U':4VS*gnwӄ]Q17 r@,si r_Wxwa ˷0(!n'ԝ#[AIP4"/G7#?nVE Yk4{J~F|h<ݽS/*W,o#3{_jboTo\ɒi(DtiP>ڤ֐ѧlz<woX/b ogO}Rj\|an9u_׸r`3[Ӥ* TL OO=wA_ 8 'KԿSg?|!c s.h\X‘#ĵ f ssg=?=dgDM;3h{ =v3QQK~7}}g1bh;4EEbc^ n^̬pjdܶb"\.iž&\gq$?$WuŘ.pM{պwZ;{Oj>D {RkEb{e ?SZR#I6Q a#JRpTuE;ثS(qatR `nhyBݽ9r >sW1|g.B XܡȬu cO'3Zp9;uz+X**բYeIri0WS l)ɽ׭f-nmëO}#tmt[rH'X `l{M=\$MKkm?o:zKr +Į_ L N&U[/20'I{nC2(>'aedZϯS N{&})$Ǽ7s;t H}rn`eIdIP`-2Gq;~v;OyD'fԞN]aͯ҄*G4_4IqX,^Xˡ,]8k\QGy\hRl3n%~O%DDT"ԱŖ:p o}YhQūRf«K -ڴVT!U/>|ʯY*+x8?TA}W__c:q2 &2QwP9v* ʖ#]g7R"Nڱ#l4(rm[Cg%<0dvR: ?'p=:Q~o{_ezV4 1U*pߤ@t7b ֋:"~SUA5xiͦF.J?E6XEb.wOwr'Msڰ ?#U1ZEc09׿SϿ*DҨOQ59d0}m.sibWY7p 4> 'n8Fi5~ٚ⫝,?J${K6bOHQESII9M%_=w$y#m6'm{7N5}[~4>.x46؆vWp@3,%-3=/A.e.5P'RaB.T0Xd$#|+&9iEV#\|a e/VgEixy%y"[qaM^jJq^S;Ӱh᪈1XvTI+hwrTI9,ÈȌBS0_L=I`@":EРuQFTQ,2jHۼF;JnQ]ܔ1elW>-*F#Fe7ý 7AZ+)\ޫ\Mg᭚fgEpoMWs W ]zxrsS5^mqĴP,6hs=ZwXт+yݱڡ sH@=\QZqh۴onm6Dy`7utӗG CQH`J~(/3KRoyE'?cժ)rȪ2Krx@ҼD%9HE5vE\8.,qX;R䎪!Lf]rHXD́TɥWˬdG` 1GBL~ (Ǯ1«4쓧 8R5V(`3eUϮ>Xb$+eVc^XVKl-`Fcഈ\4m6Ɩ}7Zjps̯ _:F*0|=*F7{I]#H޸H\MSD)OrxQ,q|(T`RwQ'Hڔ=m6s*nB4ݔ(pfv3,bc'ώje~n .n]`,.#ƽ-Nϡ&c(ה Ju`8wKzi T Q[\SpD _ a;7IBZϜPVqb3͍7ki)n}0/`@ߐL1{e+s骿\ Z"v0&dng#gy]V}Z]akdRcv-h$Pn@};I6EоJ}оJ_9)~-'}γxb1Bs'%TSNT ~A їE G '=D 0UhD+ r*NJzupB̍GDy}gYcn/;Yqgqg#1w~1et<4d M;`wfM;5y:Ɋ<wy/ `b1LF0pFAN!o82x%;K u2TBDSי.T.4$_.6B@3v]h?a v U⠮GP tB&%P=^𨺄픮:%MW-eqՠD"^lnkl$},9R*ED y`d5?P4=BFW, ~9ԅuJ[]BHgo7%vg҃巛]᯾Yo78k) t]B9 X~Ibk|Uj'/}yuG NO -8wz=%qnS[]Wx[_9/pG/,Eb,vU䐶QO藵h_𻁯C_X~E%dR;VgR Nwq>\,fǧ q `q뾻$zr[Qycn:Z8'ҺO򤧧ɆujbF׻(=8-#^,bȵ]&צVUҪ o2|d6;}EЩ SШC]۟(hN(,S4f#>4Qf> `dGCO:9MjI`p bu&,J6u +wiSJID-w6eW߀ޤnlD%ip-;L1qy+T0TCΟ6pVyvj+x%~NO-;"_$>j8|~kFp @p+ZoBMSO,vN0(/GPVU=7rXC+i'SԲ}EbxLĘƈwizd݋JNpxMBb(~U=/u\,p 0 UPY~H,Z=v#X-Zj qV NYJ`ӨmOgU#ZUګ_FRDwm08*x؍ ?E4_ $݊vF8ĿDZ^BqfA_zmf;  :L5F$ ӽobI1Q~:'EtIOR5vRIpiRCV&=Ԥs1ioV՚)Y'T${׭r[ ~k<.JYv'O(wM{Pm}u5^FhvxߠMZ{DJS J(ዲ=?'a}E^o52LF0:,+B\"W%r}ǿuNcSmNki`Xo2"͎]*(ҁFܐ3s||CPZ~~<>FQ Nt:^Ei6G`'-Fu2C^^A~,J*czYd}.<)5.Gxh8,LGZuاY*"<ŒI91'Yυ8#D!aDqjk둹^{"d)LAp`4eBPQu ,SLܚ7VGdK3e.*'vTOD9Dd@^T^"[NU1@ˀحTj%f'8 \0g ijI0ju"4|]z7mu( ?W&w[ |Mo]^U-1c*ˣ#* FĠ"x},s§5źU3oB=H`` oFŕ^tRӄoN5ΝDҹ)'%R7ëV2"D,? 󳡜MY h^P77dIgjˀ܊+Bxdᜪ-ҙ 4"Ƚ7G}(g#x 膜;LlY/q9A{U;e֫i&S_)#)߈SCPA8FgS `1򙙳+U()p>oy,fn>pC1YP=IX%={9, n%-a)#/ ]]0"L:j/dNjb&I&Ze¤" !JM4w a!\Irh \?cE܌XgR`!1q:,,yn[JgW[5Kސv70Ѯg^8FGɳ/1ʳ6i.rB/) Zx ҳP?1ULIC5o,#[0'rL+!V304I%uacfju7joq8 TWnZdl U @dZk#9C>X8Rc$ʌ'YӅjC(Y8?QX|bL)W(ZŮcx*POR4Ew W-&N¥i2luM&a9lֻ/)N`w8X:Χbd?̾.,Qfp欫踖Gvw}m>@|"P;u'Ϋ2=U:(q+ [aUb vm$e;&2LE"%ܫ+}XqaDuټފx_H~VTjCxtsGU#OUJ(]d@E)ӥ&P^QJgB)~?ze8tH{))%gD$6 hdAQfac7wvl W9-಺0MEpa FMX^Oe{c7-M4;9->Ǽ_l͢1=iqz#X'Uoj5_mfyUDQ5SmU8Uq)Ieʠ*fPZG>1ƒIs":2T|uw$- .=Zp!9Q[a7-x5pָ**p׾#Ldx|l0[AZ;tw m8fI8()1W8AˏVwe6, Ux X2W~!d8]1kN0k,? GB ņTlHp_ [J޺ke+geam|,]Qykz9<`7D.ЇBY⊎UT;ֱjaɕjQ`iX*fPb%⻛,j8,jTQR9~'cXc7$/[rB9ʳ\}yz-՟'dF%CKgv^o+X@)`=$ k@!2ׂ*x$V΅R!ҾB 8'ao.'Dn,B=>Q8#q} ܹe {nBv@Ϙ[z0f&1Sׄׄ|z2l5B qN<(57Tte1ݍN.)Ip[r޽H30kW$"I#ǰ9:C)'=+4w\*/-FwYӸ#x~u'U{foP3=@2pB, ==ۥL(_>5}k5K+_-8AީQ$=*J~҇Cep>a96~B*`[eD9|ێ391L3 kn.sܓ֩.Y]~299i:KVաߦa z"EKWf\{_ֳ҂Gf$:NrLcKvhBZ2I8sl.+)WFiw97Q*=[g[csgOXgq`řrӈ>0;n֤þ P9(hc,9X7塌 l֛3a{Nse\HyqK /|E Yj/kj)wQSf$Hz"-;6܄f"~ t^~.mZ$8jzv泟5J|R^(ABi!; BԆUmrqmi/rK/pVDLɶ·f!Ç6 91U{»:zFDFg^bNX4ep[nZ>}pkDFcU.D肐#B9VдU0v1pP5X6_5W[ױֽ;^oC4< z'gF)< =z ^qr w&gXE $do3Y /-aLy"W@,|<]cƚ3GM#uǠZRˢA`qB6#\^AiR]* q~UA=Tu%s{gh72S|+EOgU)|OO$~f;Z "7q~& Q'SH'(R*e<%cqZz cۑt7;KًZ/CE8X,l`$kt>Z&++~xE Q,:esWi@s6m(a21qlˡ<{̂WŏA֒j= څ+n|ЀN?*P&1o"1_寻T(YDE KY [ Ԧ*lb*Ym3 i6lbwMY!`hvn[V*l+jݵ fh^%ÙB ծV*lZ [>Z;U*l21*l,M~w*li5t/_x6kcBM24;#N+y#QotW[`H)mWx?]Đ!Ozga6ѿGZQ&.FFKzVUX-P*cx?Uo|W祺xmA$yE$rdq$fbkqo>E[ _̈K }Ohqu[h 1ӝ:λ/XHQŋ1HEČ na{& t Uk+s/?En`4ldfdot(Yؚ*v?:j{,goה̴s/( yI3~'T°A\/qFW;x*ʼn'F.mx(7+=  *za "E3O nvKl {voϴ!fZ/M}èjojJhw:82;\ =<0L^+U\IE [1䌃3KƭtQ6AT)մobG ܒ?Avg;_#&ZH>2ACjK cٿؖ50>"!(X],Ŷ:2Mo$ɫ615Gc릂ua_ L$c8{(  8f+)+'az);1L4.1r0ц0&T:Oa0B%ʡ's8nO+S9 .};F9GJS~WweW> o}X]@-LdTcu[W7?a~m쥂C 㤰>WU26oysEרv'1ӛ<)<9%OV&vz|(=޿XZI[tY ##Z}:uxhU+e`Ozo7sBRWRuqMs ڛ|Q[oׇɇ`&RXL*K/KߠȡCeʮe6boƤ7`=L1b9*t6?$ބ^Hʇq!p 6.?9"wRÏrЉr5c֙sa(gE8I38 fG3;|-qg4bbٟPJf R2-C(sS'>rFUjg񑛌{)1WL^"v{UKDq,ԘѸ\F M7hy/cv收')sBx)E#^) rW@9dcJX,LvC?V:pHTdw4+XnDb4E^ʢ(&r+p訲VсA*UދE68`-}(ԍjE^+C~Ï@\Q:i̴G1s?6rN`9RC ~j:By?H|w%Ei]޽SGS<%jk[q&K:OqwySzuc"i M?̩q`A/OKV&E6N7Xv0!@Gɤr},KbPu HJm;Rۺ`5s"Kې%ȫ)=_Z!N /]rl^gt$D0Z(YBȞKiTɶ7o0Ɉzv,BNHYw (7q MU"ȳ MՍIT˘#R 0Fe1Pܯ`Pe,z'PZ%j\!,WP* qL]"׼61˲7=DmoZWhUf%O1t̫j0x6uU5Ino4riVZi;O::,\ymmGm*$h%i LOƙݣ w)" ai|}rJBJ% A=)|Ih_( tE!H;6h\FP~-M\%`h ħ@'` N!m~LZdqqP~Ҽ;/o)UD] ?ɍV0ب?8oe}|a8knudR5w\kXC:K5!Q , צ~XՐnZIDW5c0EQ>4mg pkS %Ѷ^hM뼴Xz' k W҃ s9v~/2WO?7'xFydxC}R 'T,/.`I ,Y֐H+,K/DׁGW{ՐHe1+YVd `ax{ŲYEՐT髠IJd!ewb/eRfGMQrwljܞ57 7?X.h]kYr7ϲM>}!eXrb٧oe@sx}V5 2HRQFͰh-ha2>xK 4AD Ǔ:U'K3Y6 Űa-Ju$iX֫` ˺&0o>Q>5d!sRTCͲ5˂\dhpg,p1Y˲tt[At>CU/Y,P1I@l݈|;z~rIyg,}ebd@elXS]ӴdHe,kp,57eY,;n,:gYl)˒1/XeUG,K^q y?wPl#omL+|EQfNOasL$. ,KSy,L1bY"&caY8OكBC <;9cU3EjsdҲ\أn0X޵Rfu,K'Y\%8BrDC-׾X3F/=i?Ќ{񙰽BKOɭ^ӫBwljBjA|UMF S¸* V=)w\)x`f5"f-7 +ZCo=o$R(@s×>Mc"$V3,(҅u9J5!WjG4AebܜyAVyXvB0`tp Fe#KR|gl8d>z@q;_EW?!UͧKuQEu^Q'$/mC ;/B36g\%KcWu[\y%Ey>*uS:YƟ,Od('j'/6,u^yQEa#]gƿf0#+/e/ޞt#eu{{덜$Hay0 ͊1Z/kow#He(J0*yDpoy7S O{>P: eyO"uARI^5mIV \ E/,y΂ͬ1 -B:w1uBͧ ؄sk o|QgC\?9us^y̞~z_ĸnW1~}_E/7?ɋʷM;Bb)\G 14cp:WdBu:~: o:>["-oǝys.ဩfRs2%~Lɕ ѿ˧襳QȽhq1L wG[J`( [&>;ϐ; ( `ۤE;DlbT=m5 Cw i<=ARm8g?sh#b¬ ƹ]L<9]ki(;Ym|i1[bczTrf&LZQ EƽehVCh_i9S#ll`o?.}N{16C j]dxS@ov nN!å0+.` 3 BC))-^d9G 'hM}g=kP>@nΗ}7ˍ0|xsq8VMiXŌI/ީnj}fl>&CSܩLtbdb| ߲iYrn"I9>*댴2m;a(ǧ_4!Fs[-"sm$kKq^mR , ? <3"U!KP%P.,a^H, WY,u] aEqw;i[ 7*vJS7Svhm-t3F;E9 Ppl53{peJ~?b'KYozOsщ҉ә$ͷI(ґުQLܲ^z1+tŬ*e1<#%nG45qwCtPBViZϑؚi0-v1Ŭx1k+YԖԃ+(+ SԩF* 0*VIufZVF蚧[J6B[T.b֋Y/f}VWs럤?r0<٩4= b֋YQ;oCsqdwL-adҒ۔&oBTyIij&ZŽƽZ_?KJzFv* 4pBh j٨+풖ETp_Oo.Zpys":E9.f_O|>:ԗq^ 9kv-DV0N^0S rʼns[(! dVk/>w/R `(h`H&P)?@ǣT%}d@0$Yu]’ T`HC`(o/`mN0KsS(clE @-ν`((O^0,1TlǟLl`Ȝ\ ֎-r IN8/SCq}fۣLSA/>1=F5iflĭ([>15_g. >F궶mͽ:Ʃ\NEK'/%r`iY)7"B>e;oy㭀< i90)>Dg0e afNb6d`xM´<)mĐ |,޾,i4.#^fG5/m86jK6i({fZKnx[o55r/w?&JH꡷64Cc0X|̃+[QJ?mj5PvA+q% eziRV{t(=ZyiRii3ltj j7&_8d=K/̮˂θcwBQ";b!9,(R^]E=8BG^.Hó6խiH'I |@ԛWmߛj#yrfj4 `4pt/7Ĭ)%@ T}2OMǦ*`vM̪HqUtȫr Y5j쟶#egMݔX|{ۏn+އJVK8\xU.ޭqi=_A[Z/*?hݙ.fą~8-FjUiS֓#l"ct4lAj88ZH&aI4dvdPH"&5! 9a4J~vI2vџ<yzEbƚҔdYOi%%uTa{kX2tC8 ]>e q?O_# !vd]`y|ȧX~ܐ<- m-%}T|Y=xf6t: Őё:\ZP_&M$W;o2z ՚܂SH|.7(łR(V1)/(<Dm`N^"yW6el_`7br)n jKH,SAIw#9D@Ļ4!^I()~+#,A  /> BKF x?/>>bV;f{~f5Jַ0v1YhYg־fP3n Y.Y$K̪D;|Ĭ(>Vͬ kYYoC1\G% ; fȬZ:ɬp`V+Y/^+_H$WQ31Gx{4Ԭ@Sl ]2Aggoj&6)lidŰiTG0?ۣth' 8*G&t5@ݖ ra>wtp*wLϐ:׋:_DԹ CSqsX8vv['~*g)=)6 `ImO:Ţ/K'byQץP\?+@5ĝ !:c`̈IDoͮb2%Y®#0]hWw6|&r \dB(rk`> ~9:v\UZN ~yK $ Kw4%/=F FRiڴ7%PIO]>L55 c" ;8ts!Vg:E测Y/fuP̚ҩ_Hh:OD'o0258?$n)@sYv:/70Щe@'n^z1+}L>,!7w`ANCf s"ʫ8S!<V=˫=e b֋Y/f}e_?^CHϵn -fOfˬQì 1l~'YM1kOUVpǬ3+ÊYx%,:b 2z̬B:ͤ <ᘕtbY1fVnňYel5jTOpì~f}_D99$pPsx| '8'_ %v1DA#DŽscC|:%|R4o<~ё:7?ɋwE4!%2](DUlh` (V:ZA"Q" ʒSP:d(U ._A,I:fh,eR!UB@ŖdR򆝄NKT(2*xƖV$̪;:*InPsC^Kj}@+nlB)yUMBڜQ3Nsq@|3q/-NoKnQB8J4Jq>iA5LҶIJOK+ao,THf`-Xu gwp p&炗v/هj,T"sxm P ?6h^!X62DAZөRy^7ì+y~HQ<`Az(.]h^ $wi aҕì~ Y0kyeY0Ye#1qdi`[= . 8(8 9Y .3[G ȁîl WuԸadbKf57/Y'2kΏLuX/+Y/~fY,Ԡ0Hk XUg[%҉6`y@rk̛KpնA#_/KRN!FVJ!ߋYfržr7^]i;D,䃅̢Jsc'zzV|/%X^\|;b&FņŊ>0mqy8Z#["~r|z#LO$rEgDqq^onsyࡴ[pL2+Z& 7 ^ a-eҨ<^B/bZŰ[;^Rc# ڵqL+8ᝩG$,݄es$`<:+^>Fw~X8Rt͖͊].vj`+0C1pF%?`54KV+5R߱=gӰYP&c-@tG/+z#zD;6G,ۆ{ e[\Rv@DaQ#|ӟ^Npw8~R7s/LiZAxine-lib-1.2/misc/fonts/cc-16.xinefont.gz0000644000175000017500000001337014647725152015760 0ustar meme]%9n2˕M'ɳyÜnb}ߩ}T,}"SO=:“g>y}2?y'x1ȣ2eg亹F)dE;/h[4yCS/]/BޔJ(y0'v;Pgk!n~ 逈gv])sd&R ^8[ގ_Fe.)D{u6e0(ȚtL2W9xKf3K4^VDžkr!:Q7D`IY&OQTN\r]`+SϘvOqd4vDƪ< -ž-y)bxF=__8@*#^*δ@ 3W8[eY)joK,{WG6EIsKeh#LJc7vD9Toj:Jw+?pC4lB>Dkz/v+OJ/Ob`'TV2/+XUx$d#hDiR N):w;xyҖy vH8ӎH2`?ӯ>D[#"YDm^rYJr.ycxp@LxUY4l?*8ZLSpsXkΩsR:3 LTx43YrN_k6f8| kh"|_jIngCo>;>+enJk$>? DxHD,SXkEF,M>]3)` 5B}ڊ!uUjci\$/u p-MA~{!%$F΅x-4x-4qjb!ۂ 7~{9E~&Q,QKKȳWلt1 .~Rܦ׿[k׹;`cߠ; eڗ7A-@m$e`x|֟ ;ɣ캧]/$ jP.|xŸ㥴MΜ`:k3S}ME+%3 thAЇ1Fͬb۟\q$RkW MzS5VHjf8G$ (FN%tw:T+2Q| [R^GG@Ko3MJ~-~f#İ$%.U$ £d3K|h (% ($Zet)*e|h+;h aqF55sX7"5JIYm>+٢`;G"A/^?vFHE3Yb[i`⏨F&Υ5VTƵv0#lE#/HXV3Ffg*-7 mPZ2IŴ`מC$&NHbLSz\E3s`fdiP:"E4>=c50Tcsx48x#Wz*Ĩo[4 F9Gw8?KFńn?'hFlr6?;>j5nJܫ^C@ߛirL!Y-b1/jj<% $> HЙh6raevJtr5[a9r{EqָV ^p{a>FpPO,2 OTѓv((Wk4,aԬlgo3ÒmQle(UsR̫F#!@g)j?41ԹO/gBy* 9[R#JkM};-F 5a`rvvx dv$-k=n_vIWk ^:GY%n'*bĻ9n=xc^z5G"ʨJ}eh-Lϰ8[GUGCVg-kX4^gnyO1z#d.O`bJ4KP@+T3Q;~3Pu-s%NԒюF㫏2=_cŨXaZv,|*ys_~U)UMQ65C*J8䑱E a^\N%N*TMU%e14'U1Ӓc@ (9ǃ;NY`i.QkR@QװZzn',(l4z *M p:?f\$ؾ4"H=)LSY }`9JviCS8k6oQ]˅3U%2X:NkgII?ndh'-m=h'x[oQHt>VӅhC Xސ2P=J2lscHY `Y`XDڇVqGwRdtmn}ĘG^\wuEL?A~K=ce3 QdQH(z[X{_0\YF\m^fO\1ZMktO a ϴGUJj3PU E[RgZV;=ToTuJEIEU 0qGo7Sfb&NeՓUaYa `3o8/f :s N MR@5U/ZJ\Ep,[ok36>F޳k$d.t2WXCWZ-󃭖еZw@'o")KDy/.'T[C !sRHI &*X~¢kH o#yCP #OvTĽc^}ZC0#\.K\P6/ qYF 5dSe{i\P?zy7Wn~H3·H؍x,G54PYԺ473miߌ r&T֡W[zmsq0 A 1EAjtt TU(*|ڊtSF^kq >igcNYxJlmU 0oO|鍼..%%{-ڱ9$Mx>&m?;$ofD~+[b$ySvxGTChɟC~ҒBTzD4p%)mCN ΅l^@O6k,qY0uC;K6wv$yMF K|N;TUhc{봪'XԆGW6NWCbش9Hl=&mviZx5IZ NI 8\RHPQ#6.>-*XQ"{*s $naWp[Qp*^^<7l)烙;ԅxtySРdu6LցYǥZ'i˜]֒ v<[1wrqh;^h;KvTnS:0i'}lt@ws :o h9$l$n 7__ u+bh>_WY?'9  xZ-|jYjAu6“+icڔqH;[XџN]ZTچ3ċ{c{K"IPM=Kbt5mr @%)jzI +PeLL3p- L{V!y/}ЫT??E3,I[/+Q*6lk]SrmJm>Tվ i@26 l:cYwkl3/W֞^{rqɮe/ǬLCaOnLjH#ENvu_Ѷk"Q z-zfd7eeF-튛}=!i#noFF[oʷ W(i2[l *l˺ PLAY [ |< ] >| { EJECT } STOP $ > The original cetus font was downloaded from www.fontfreak.com and is marked there as "Freeware by Gregfonts!" xine-lib-1.2/misc/fonts/sans-64.xinefont.gz0000644000175000017500000022461114647725152016344 0ustar memeg%͒wA`;h$@ f9Bނ$o{/:U&'2sw>tFԎHoe=`'nvСC5U|s /~߷y}Mg}>ر G=Тd@}#Ð!bsOB!] 0]4~/ύr_OW2Sd'\*v|w]o=_)Uyyx aG `_Fl`+40+40lo?b?%S1_fyCіeNXX9[KL$X@2"6hگ*-m(-`SMNK5JqWʆ"eYI?|bΦdIGy;!ҟNG> ކ ́uI[yF.U$UVQ wh,{Z_'bTGz+W=py_ZoxVQ֔^Ei>sZba:=PRm_PbPoun4Kz8CZD) vRi!ډdη]V+>:H'(r=6gX$EaJ>^I_ҩG-?%,uNKc߶sRYfk=P>%<%v=ɾ:pG'@89#I*=`ŭRQsaC51>GW008dzV_Ts~uH9r߾~I~ WVȯdəZr D{e7^4\(4n(o2bAܛ0hD{,.F*k FHi 4h QfU~vS\h⡴nk2ِ҆1lMO| f0ʹCɒ?#LHF19OKuKT֯DSY^bHi|8L:aq{8hs]Xrl8֦a,ئY \)}70\,<,Qb,ZFD}$RApGܱEZ5c=j`Yjv͂_"kԖ'64_.&|Fsܝ4蟁EǻU#Gh^у gj7QS\r@NF1;1);?TduT_l;l4ZUDoVRi!6êɲCw[7A+D+G85u VE:4{F8_Dy?*ZhB3[1ł-[jn֝ t[ӇϢlQ=ܔBUqR퇝:pndtL*j ZӪmO<`IY(XO PfDmb&:hz>f:zmqUwv\SGdblPt2.fG"v%y!H Id[C΅ك)^!iou^_ev`XJb] q76niLNn2aiAdGP1Ӷ=^XYPY ,<ބS!@ht$ &]vZl w1|(*i3o[Ze6 =>l|K|Aف,V]lw?Izv7'~+現dO H ?~p^>?$/u캪p ҒQ |jYgHʵcFHEHs~nߟ2 k|#LR{+{n(l։tI^ 0ȗfyxBbI<ڬpf%5P.V4W¨(=!z-֧d6W[3wK4p %IZ( [hyS,+N tuc}5KqZhι+k91k}p4ouC/RϥL57j~QKgW+(:ĩA6!XV<MT}T^R ^CG6d3k'>kLr҆ҳ0Vx%974HlW -Toj+ԼВyJ 4Ӱbt!j gƉEB g 1l[<{.^왪t{ vΟtwoVSQV k+׃'Dl-.])$Κ"=^|YeM|^%MSBBE܈T|T9¹[L^SUEKTĩ)͉ {QKb[vf+XyRq1Roe!]d_K*ic1}#5^P{qEYs -nK&^'/ܚBEBa+ibB)aw%Lּ)6O)I(5oPj)T:+:Z KLW_i2ƥJr,y۬jP%$' |Sf/桩sT g.5aB7yv'iA]1 J􂚮)m.$"C<_yC1^z)2%ˢE8ØdD.LG=,RR󒽊E(ػXZY~q4gC-Or~+lʏɉ t#=dy.mTD"$)c~џe5- (aUY Q0[A(I]֐M- ErEdWx"O5e8k˞2yqoǶ^op%RS#ň`w׶zvφ_l7wx0cmŐrڔU%ƆjCN5<o1ʚ|0$TP=p UdJE*rG\-,UcY!m_o*dwnO׻fzY|nϚͫXl0j%ǹm cM#˄F j%*tu&pfɝXrfcnCۅ`{t^r[L-]>@xnV2sa,ޣffut\+߂MsT&4CUmq0?f4W}pܑۡ:Ea|c](xPygIbU z$4Ãj*M\%ZZyk#Z8>El5⳼QRZ'XT{N05*MvCQ!B-=["{xn^K2qp N@. ޳5˫ZNԶE+!ٝ8[T-ʕ#| ?=sa ԫ[~,yENlH2=7 ӓ}m65y'Pi0W^qS+@H }h [Tyj&+,-qɻx zΝeQv2c\|MU$w'89" eG(={oӉ+n͘U*<%>7tLRO"+ hEFujJ#zO.4Z~ԣQ`E5]>2MSgkvrRiuP|D H,(fU݄2)ޢ쁩xaS; yU'~X'0O=?KU'pU wv» <{!K@6{g'P9-gU)/˴1^_s!n9s.:`#0+WO OkT_bjw&!²0eͨNZ!l^:`ڵO4N?Mġ@ʹ| h~r*k^P1vnuJNJU-ƞ] e.Pd/fyg%K5ht-_(p?cr0ߋP~ Z"iS+ tFYb5e{c{cb?7;b۱- Ǧ]ؿ;#&t竿5Dٰ ֎tNf^h֎# {YcL? B=+x&$BnHvm8d#!VU8 xMD)m1Z6hLuZ!XE>!YЛ ~\!eE \8`.9$֌v5p*gީG]-M1y#1!ͨƆly2f5'(+#ߊO[v8]B2ּI qoB2IZ 鳶9<ʄ2s0BI"b0wvF8y],N. S.EpON-:akycB's a VK]N*!tRtJE9UBI:b06P. E% [uME'BQna$+%E'Eyau5W]lJΎY9:9=BhNl!4<έBJm=]U'fAF» ;NKື05kk(*ͫ"L3EN>?;/}̇0]0)b+e4 73GW{,ʷP`(M6j&bim rVb&l&L:N;_ȷg|Sd|sP8Ȧp&]bVobU 6lE .: tpTg{{B;4P]E LL:_`P(lkU *|º.U)g\B%.I3J> ;&o@ޅ+4x@I5<"$c]8${d^76r$'dreBP,o VtSow'p('°sɉX*y`BV4yH:t\<8i՗H AQhj34~q948I Kl%3^;p!y'at-$BrlJ*! xy _=@r~^? gIMv]0E#f 6v>;V:bZNצxj>'7si9-/=FzpGr_ oNJNٻ6tp؊*bZb~ l %js)~csv 7( NW˨c;[]K!Ӈ mBP=d@Ýk5c&]:v^Ÿ~\-Ϲ]FUlu;A[]j|c5"x;if{ԑhe: XƱeT:GWeL6UJ I2Dy'ɐbP'z–?s[^fj`Z޹f_d>͖A-Ct]ofA×e 'vZ穖@0hʩzs|F dGy9Y-C$\53~f9"#bw׼џ/wz¯zy.roHc6Y&c!uiģ޾Rdlњ՘nC]^^hkepoe<%TՄMHUOHyn(%`w;W\JMe{ݜ>GvRi O!&׫WW7ΡOv>)lvN|~S4 FEP:Uv_'+B ʟۍԤ|r| c((-gZ& -pS4W :MAMCfZn ؈9$:4:<٤J+QBAc g'N^Ky Ҹ8ժu=1s~=G1}ug C/U7~zѰ vEطj\Ӹ.jTwJ.JU%Pږ@ 8'K^NJ?_ץwKHvZtA½㟐("ڐ/ ɮwaYXU'})A4df55dFNBzM')ՓN Eߜ1Z f!v6Ѹ1FK`Suj7>NIn5 ^CAWE殱MsN9a:qcZ!j_:nGy|=Ͷ?` 2ޛ}Gg~ܹ :''WJfGC^#"Mx#"BiG#v7(U$ݣC!jCTmc?}OtN=7lh$S^+ucx_3(sIJI B y$o"\ٌVo@POَa;BsoDۜ8;Fp>*YIoT ~gTxৼc.XemL֥itSF4d())ՈZ|RjnuSTC&$MuV)5^j)!Ӕ6DPʺ+{El؆L!țBL2 H4ijd<{hz;))-,Ҳ?@5Y@PRCBҙˇ#  ")ņ/RIS b%jt/F?@-#i70 )~CW!g/44-?)`ӦMAɥTRn}\a b">so .IɵrJjt)yb9U32kcsGu*R͘KC56(ij0/ܴI tL ]EFM|3c>q} R N= H&v?q )*f~,-vtնp Y1#-ΔM h c(#.УЎ,Bûc-IEw"ed%S[TE`{,k k E֦i a.a5sE{f™߆ C"AN>c m)DL[IEOi֎Hhtw!,5B#G{moZ8oy[֬-:;f-: ۡv1]Q]Dby}xۓNW֖o | k]9Uet;P Npթ2O3 -bA9Y Dlp3wCL+Q_tb;.p; wF͠\*쩣f;G}҈.Ór=BO]!ÛNrbdP4)>}b#uaAP.t0 Z;u0)FVm٠h:_H1d"b;LGP{V :*RwYxYm/'Vgz }]E}s| ̥ '1U*՝ϜNC@VI.0FX9V6rw.^#umFސF:C 9G$ ' {C0vnl9Uh޴5odSoLoHy撚[6+{|P̖@u4ncf]b޿{w|~n?ޣQ_6 tbqYC0'Zڀ f,tk(tΟYJ Iz KZ^gYf s|GY-t\*?9qlYÑ3›{ [!e0oSk_rۏ?-(A(tϏ(MҧT JuݎYP+*DMrY5^d^@S/P'^K۱^j[$^c@2y=(Eq5@M.&Owt[ 2Z\;iB^PՀFӱ9yf83 \=7,|ÀWGY&СC:tx3Pt xhZ de~̭CLt~4z)C$$ jT0Na[&TPXg?jds{tBMa/XWYZƳ] 8j}|gcU#Z@pHYQzMOM9"p  pp=LAԩ:@%X⍜_ۏ;mK yfwįx9u@I$;Eij40Y}yK=DBJh<煘(#%!^2V7K1*ή#~. уO5D'ČcX шA@ZwQ$_a{#eƖ)Dٙb#x+G2Y3gk(Ne>XRv&CpHm. 9kM*5l$]K,p1a !VJ4h8g̽,qua1FZXfw{:[r;6UUH?Sw/9nTҗxnHQ&ӗaғ%&Jh,MӾ0X`..u6$%fLH?M߶Ș].cUfʜY*g'-ywf^dwL1굺FH=bܢAqe\w];'_EAkHV:gn}Knع0fTv/Nn>ҘUz\<w?ٔ'HRp%o]<^˿ kb @.~J] dmSOzx|?i_sC/ ;pQ93>[ V1a1e-{RLb:&b&{BՄuMe kn6a%r`SMXi R 3˘2fabRT̈́U1LlA q SpV-dtWwwʃO,ܢFxljOK L04a.ɇz~hZ4;LcGyLr0S h$͵iD\љ1o׽>3~] r 3  ZLW:y0L0'7f?/; [3?~3n?!xKʞ=3)eA#H?;>?Y+Bj HD+^ Z^Wp>>v1J>F|[, E@ː~5VoCoU B3}ۣ ]M0A‘8,ѻSh+p9O\,D[cU&h 2ֺx!,%K=4eh6?#EC . ڦuKC`C/b%A4ڹd/!G s$5G&|Foq`vСç6*0.83\WcUVo(A#D=8So͞db}\.jN%0J7"W!Cs  ^U#Wspno2ډe%҇Z?֫}|E #Nq(F{Y- kiS ,o8-{g~[]_c괞vNViS4oo 5hЦC7CW|"m2ĀC͉>YɅ۷ Ti6&1 ںGLlN'z,o&+^-}gaxdzay`RK%EO`v S V`:RA@KB ޔ.) .QjMzQHwo}!b \s$O(I{ByQ"8s GqaNy ؘ. 7MI^EFa FVTr?1-|ȴ*#UK|!vSג[-c^{3չNa8٬GpP < uw*kvr ={v:|t=cw_fd'@3:k!5G*CoMJk>bb6Kp$ {%I($3!1_?I `>$1d;Iʧ9'v[!Ip ^Z2<IʩZ4`ye~v:&)5S*vT.SrQߒ络N0Mj)&=vXL)S390r0M2N!3^&B|_ۯ^2ҙw"lNK~Wڇg#$Q? (Ս?JX4bj_Juy4M= GauQ&9?$j4+\~F^Tf?^_ǂlۏ{i U=0GmJ= ́Iw2BܣO4|,itJ.5ǠU  m˥eDi""ڥW8JK5x2Tl*}TƽkVo߭n1)IdJ..DToRd@eC \b1?^u<Yp\zbK50FriSM: ?zj] :V}{'CjGx+=u<~H3[ $㘽5nG8kb7od0#N/~aZ|4BDt~O?| uQEa?}h`kG!0KdżK>!z{?*Ӎ0sQ7IK,io}唀7 &{^ޟvƁg'iMt`s;f|wŤ'fQ\ETff)HЬ5\=5~aɈ8eJN 楆>e`z\4`ND!RL|RqUPK.B9)X1+zwClw̓yL# C/nz;LtOgBIUkg3*¬ ΰz7:wf`J*D2菬V5ZlFjɆlB /;ޫNhf]`;ewT2N+ +T1YDWuw.O "ƫHt_~w@;;f#P::`CN8PVzrNsyΞuhk߀ @~?™ L  P*(BD6۳mK5tlߨlz>Klpq-IHMѾA:DQu~y70~mC.}cr͒mģI֞?:x{[yL֖/wʶN/:W[ERX뎥o)1#FR^m2oq^4`=X5+ׯ&4~y\h/r݃BX= m|O%\/X7-`8Zɹj@h ;ŖCOJZ?Mܴxi7 WWwҔ?bxo#d$6T4)=Wi>#b&H_NA2EԔb u!X-ɱ').?G6)<*Y}fmb,:Y #$5UjWW`r;*z,MW6;rZ2 dh,g[-.N)>1cwP r=BsOO4YXj\r͹bU8m ۋWjvy&)qao1ž8t:|ANpH~'I 8C9\<6 >(:v?ꢴ0ZݒJjbt'pՊFrfuZl`5R h;V1[|(~=( 0i +[m@4͉MgM:c0fz_:C0TgȂj?m|dX\W-4-(_ ۯΕ4 ]__ 2zvw_ޭ1?9VHFD~Ψ&~\8d8yhhu^Dpo ݏCDZTC膵J]\ GtlW_j襬]lp"1,/0B_ iAK2cU`!P'sFZWxJY8/󃗘pЦ hN?R$$ʸeԮ2=_X$2dh9K#Ó4.bb.yD\X +`91Rc2 J2M^F9gXQ׶AwAxȻ||$wjXs!DEqnnXu|&"`)[?r;g5`o+[kt>o]8 qUI] hm,=1zH'>\>dfdǶ*.5LBY_kꞰ$0N',S.AHXS`7hJ:4&3,:qt a`N{gQ Go?Ϋux0Lnx2f}j믧^;dMz9ׄ ~}MxI'=!#l+*͟":3-M,ҳQiȌQvQց y&- Em w#$}eHZeH.^CrZdr'k0&e)㹈gc. N*a*dN̬N/TE 7FbM٢ghO_Lѷ=nVּ,hR ~4FgܱxԿ}o_= Snkدu1s<{vK7@oM &yF<ߏofTI\"LdzVNC!=h ). dיUzz/\3z .RQV,^驧*zS w%znB3eR/%<5`5^yM^ur<)? .ʈt~@%ZU@m(bդ'9GMRgg#DU_.;Yk 7둏l fm$=5E.l%q%ݔI NA6P7v?)gn0!.\S0aP7CjYn[A#5H& A ^F&΃p##]6-d/kpw::s nz5y'j ѳ|ZCOg ֭RlyœB+g}/>*,#Cy`pԦ}tE`nv2@fG|?j\ )bU_B *Vͯ0>!\oR̰Y8ur80֙fĨwL4Tuz$4/kCo U_dԟ P^S0?a!ϤA=Zt8}Ҩ̉Q֘F;oE#0eW]/$8ɱKbߢ_ ~i'bud#p$kqMqA1>.!fZn)KFG}:GR<ysʤ/XReHʼn5SSxl(MX7q>ŽsvAtn=Uaa:VU*s S!DaU,V)C^ 7W1*R5N\;B nR'̈́6M #4S īdrLW3L >8QS%@dUY!MN$cDKr*6 j/Ƿ U_8D|T;GlzqUOE#~Ù*ڮ3 :< ޥϮw{Gʭ OVߣOa>u |}QŧMb٧Ξg >uL㫤9E KCX'wE|| e!] x8=L2cv% 3} {ג1=lҏR:F"6It'>u2(P:9bi*]S D r$y&e< &a:>ur%5qЪyO\3y>u$m0קVf>u":Ţ?qw٧P S#ݧN@n}ۏnE< ދO xh5 p@{U&_ۯ.]Wd)mIy(By.ŝl~HJb?{`FYE\?FD JQM^ӏ T|ō?&\! xE51K6jps  ʢ˟ >YI}fnAYz@\f;:+!CF_928Z4}jО,,?yPڀ*=lE _h(lD u.?oů ,Tv8wL+ՠ)!j]NP.:A:BT Lj+L=iӢ_>Q$QFOB i?̂t{$9q@3:^\Wn?;g0 HwJ<|ݔ5&aM;<;uH.J`f!XR#gD h7e|ԡ #)74?YYv,D[/ϖ09ihEBDes ք 'a(D\,A _,F<?$:C`;l 9_=7yOeebK7N+փw%9G8"d>6QmcGh_m.e sVamBSH!Lŗ=6n.E+"` ڊMop\_s_\;`3p0"ťi")֋ŏX4mX~_h,ު%#+b9Ud,״~#1 ,>C϶+GcG+EC,b%_KlV,c]N Z;VXc-9J@a٪ 'ns^¦{x&?]СCv`L%Z x;s{H|&T%z!Mv(~tɵCѐR t{``ӫѥDGNq8c_. Ϣ8xBo}T7`OfBAD?0A? WQu+V"Ipq? Y#=Sn[Zj٬v?k+D'<3\ީ\~Ƌ3>0"Cn3f,|Yz&fWSu32Ot8J?>cԛd]p'KFm_D *`ΉӈYңZ0 x&!i"~vB2@()CwRѝ7&L3JUpY0DDyA*8Ípw3BeA^Kpߵj1.04SV72,9V'yd/C28j,B1Ihq맔ֶƞ[,Xe,L-%0,zJIU)Cg0Y$EUMå1Y"489 obg> E[?(Jjt[AgcW,s8ʱ\OOyf*TʵsFʷ=ytS\kN ̅ #+4/N]]=|W9xO\]a{ZaI8S!NbL8s_$,}0NEBCXaq Sq lqʹwP8 Hs0N$s?K#$s/si1Ula~KGPM)vp+O`~dGܧs/9p40_LZ;9Vh"\ { >@}D}!Mrkww">m \-v{h\LK93]2.} ^??&dO?DwOA"g>?ED?)o Ygg.]#t e(TO_*_V?M"mBsiwpH8ާUegm]"~ɻ2[SHblܛƓK|ņdS"4`&Q:3ې.] q}2adO/.}4e6Нfd6 \N6/<TlC4gCt`VHDdR ehS9tv*Џ 6;6)*Ps\ TH~ F&~sN$ÿj=5*~]b_G˒p + ְѕcefi3@Pvqڈ+W[ 5,KXTE /X1\T VK苑pU[])rEp&E 'r]!fP,+4luw:W}2Oa*5 =T‹,]Ri|ɯCMVPtv*ڭjWY?ɮh#$'b!ZͦDl~ #g:\N-SE.˧ygc9SDt_=>H#]D}S:0B1߿l[f̱snWMLTo|KjDA,%VP_V׺m}*UX]őek#4 ۲-.v[NŠW.ڦqA3] bI=!2εn?ty4L8h3ʠV" ]un..$>3v[΁Avj_8ݶvKӥXbULT 6%~Uu!&o[:vC[k6|(o^3d+*4n}GgM#n#=͕Q;r;X|p50o  N1rٷqΏ=u Pz5 |QAħkBUsџ_m](BoBAK PL.t M]("s@u5 @7ހ2ewV&B"_|*W2--9~`"0 ̠<](B.t  PЅ䬁.uu?BA~yw}vwx7 ,Eu/bz% uo.2(dzF#w"8:,=ي,MJ~aYBM1& 3ӌ۳3@liq.ӎ*ԕT"ԕT"̕Tkjݶd r Mnb-\:-\6\I FQKFW˺8bR"Q gSfmN G]"X3XьP"T;c.Φ(EOP@>oxmA߄LL^UpԲc G-ラ(nKԑ]oi@ˌe߰fbR>af-ELCTu{kZ^<>Wlm?5B(p@о; .A֦u). '΁f4-4VyܡoZixPBgM LWY].s,{=ur[]oh#vAt͊)wyWmԓF_1Vx|ȿ+֌,J<;(I\sR6/d)nbłjn)K@ƈ Ph)Ɗ_RΓXK9˖rKA^JROKv ΛO7RIC/5M.s<]ˁ2HDYk(kWJg=+ij͵xmu[ٚ8|iPc5H-BڜAXanj%ރ|\ݽg}ιWQ-ܿf,ZbBn0nFեA-j죫5!Y("b}lN*nLچ ǸaCJHƾ71Ь&jVH2G{Бyv˪|ͲE}"yX=욯2aӽ*}\?8۴*QMQ92EuZJt[vu3hx PD%^*F"k/BvzC"4--y5mT}h jS̊}A|xtЈx Y,% ~#Dj$T[6 gd$!OW傇On<rQw !q;k1vT %U,ǽ%8I~ "9f=6ifLfeɲL;zS?[r ~z}$*UF-=0l`{cb?7;b۱-cYˊS3u{ l%KnO~_Y-5I55dYt=PԑE )fr~CҪ{9k, K mNwB|:v#s,۹v? s,YbwawZoK< f+[e-lRz:ۑ2M&UN[Ic%2³[1۱nsiOQ=,(Ν~ύo|;؝(γogvl7jϧc7_bVub?7b{`w`?7;b۱-vv_W2-3"38dc~ph]׈G"HPTÐQLMtom'wx; e4!-=@q`ɂY,0'^ֿo_ouIg)01> o_F~slWJ=>cg.OFsaH=h y\˲Eos; E?o8Gk{nj-r4;/{hbx'\1 `k*:_өh:rC$ŠdENp Y:u4(pQU @E\[|-0b'Py * 17 +@'ApA=-ڴfRAn~& J0 Iv2O艫% MM-:Æ3x2OQmm9w0FS\ރջP*P#X~T"Q"QƎ yqL{^?\|t A"FB1䝓?B~nإpRd)h B?f '/k# ~E%9=@ӐBOĘcAKbz!~,Pf?U9!$C;F*!IL!:4R AdGYؒPR+ڀvj3K>C1pG?i0ٔ䞍 vaSb0)WK0z?YI(¥3<>@=K597ȊiDE41hɷ34=Kޥ.Eu)ѥ4y]*ԥ uR.Eu)IQk vM>8X M]@ѡ]/RMDMeK0vZ$Ma/'>,Ry2Miлե(ZQ]D]* DbE]RRT^7*EwBSp](iѮ>: ]d* L\fTff:W"k<Ѯ΢,^iXq_ehң n'&P'9MUqMSouH카~]'9(&5HQ$rT-RzX՗O(E]*u)*wRU]Х(HQr0XO$`N>srV(ߘmU ɮZHפ(${'R󶨏+E}-['IQեQ|w)*Uե(]rKQQ?n?u=u 1U*O+|#م`O{a] _W޹7 ubo _ɎȺ~}V8,IQj0jGrY.kbUpTNDdV4tMOD4MI4doLŀy?4c[0jo&JVlu:}- ABUd(N4pN\vA܋WDC m㽜EuVİԎP8,M(~wݡcw{4aQB uO߃kk*ߧk'<.q Fa+ M3ilZr e*6Yu^Q쨸$)\73a(qk(_M,}Ş`_jðþ<-񖀑-vޗ*fރ*cK jX mARzk>ݷ xWil ۷>ž&q\~ >{=ZY;MX³w.O* ] RبjRl+mr_qY)lSbLV 3`̢ CIa/j$!o'.}i[pzKXyKq @IAi1wLI hgc*h竔"qmQJSkmszX~r6I/@\EME~eOs0$I=1J4;zidAM7̐z^h$׷ߢǠoٜ"rě1E)4N-|65{FvV(m-9Wd\520B$J!RO?] `0cS~kGFˮZHgDJxIw)kRM))8Y#)Fa UˊBk ~(UQڅtd8NE`0":-mvj`EYϱh-^H"y.L_>sA╢N9Zj"ޒ&kBْi2Ye`\HZ$IawJ۪swWrj JU+fKm2+uRr:,yq㬌0nri^&DrXdpJ{ǚgSU*ϡ/8h/tN>\+4 N`^alpF} ?^B_ڂF+ό9QH +Lo.%+hOhžK(dp 8 8Im[%ä"LAr.Vޞ%(TK}v3'3+i v {KV7 Hhi%Kݳa|>Yg؈Dn|jv!`BYv!yy㥱-,1ׅZ`jbk45s1qrjcjL[X|SC0\-wꊯ2/QYGqH#9v/c[ eb/Kte|YIz/(}䩍ͮ*՜$d!UB:ZIB-88o2֥{ XfRX Rط"] Jp=ˬL*6w{)'7QGJ3,@hJ6m [iez)k";k+\ǿKa] w)l.E.}+Rե/ =zԗ%aj V, 7f+RXإ0쏼)?&@}X)lmV)L0W C>-Ka;[ |K<~o` |Uztk.U|WݔʻuF҂;}X#|;غ_ͧ_ fIC#uΨcL2 5kb¿![8$8h Q>Tjj?ʎ)$|z_SW||%,o?7o4M]yJ6Z4&z\ 7R%zrO$q4+ȗ3`Y|h/Lb|?B;[{|g>z!߽PܭY_sA{#8_^W|}Wqh_ 0 ]/k{2܏I8nTvY9J/sP6o;9xsbE7]hpo<+2GYtPҴKs K"fP:*nLw1˖w~ԙ"Z <`!wk Ȇ803$:|z/16&߁a'tX_y_v~weiHcGL=i10Ŧ`Gvޣ0xʬrȫ8OC.R(RуrH(Y tЉB<7`)dGB}] dޔ즸ߑz}c2;yՀ#()[?>t7b^dhP%ʠckSN{rlDrne9)s[̙":dG'殶Nvy6qRLB&8#ƊN8*KlBs`J ).r0 W…MjQZqfS lBAyYY%r0 bB1cG- 3,%b=b!I4fXlHaAl:f|_̝aVܨ]˘cp> 49R>ZFLbjsPp].P$kSuV "CCLz2 šJzr:dNK[QQSʾ\_c* 6D%٥&X2TGDz Uj0St)_(?𶶞]ȵYZŇv\aگX8EMrXwi1Doc,{p%l3c .+[8j 'JU+%fXl i-SBQ]Bm eYJ'%%EŭMQʈֆ:xRFѺ٥.!Jzޥ. .+] }*h61YJ ،З,O:Bf=^N qJV4 I5NYs2Y 6dLe M񾚺r`] e] Rhc] M] MUw)ҥ 6>(ؕ!8d0\b;Xs{[R;%D ȋD٢E\2KBw)֥PK*v)9-H+Ko VbƭBK#ߊޥP KBO] qkRhBbBO?] %6׌yG g`h`ϖ /[B y} .t<͓Q WڀeBj1`Y=mjQ 3;y\LtMgJN^cY!jEMg!ΈaЦeR=ZәDc:HDddY:JЉ A]̵n91nD,bn/S3ݣ"13әhXD_ƕ2>;ļ9Y>tP%4ҚaALRdXQbqt]yotV t6D4%YfALgѸ6*Epd{k ~)$+JrX( .*&P F2R$P7?F ʨkTQ QG`ůt\ɘ1;Ü/``c3%s5 /Ƈ׏ڽ`;an C[t;,3/olިd3W!}NEb(λS=u OFmKGBO?l0ʣ.ԊJ QrdQd%O.'3ZFT{26| =ϊL+e;fZ"9t̎٥[B BB ɥKPLS[$OMX=OăSS`-R,1N " {j0͊ϳ4"*ݏ<0] ՘] 1z"v)ݥЧ|]z+n0LI.3+#ߊ:mcv)4@B8XgB0{o-N)txj)Oߥ7tOɱ |ɩa.ֱdad>c X ؞{r6(bݦykNmKW&$qEzAx 䰂a]oW\\):bd,yV>X 2:ZU6VQgcIe n8k68ywYA=ygymB^aȱL٪5# @NZE'x2jikurR;oJkuJ-Ahd5X4q’ZsƗ&LיOWu>ˋ̾po&jb64fVFo< D39L;l+FPLfػG]2h~ w(6fG|#x%ADMgXB $BDx *%dˈ<5Sڎ,T[?8)83D0xNTh#m9Hl EF) ʬhDr뙚IIKF6Jڪv{M1?}/c^RI sEpÖެGp[\ڴg PEQ9q)QhnJEx83o7qhL֑:Ħ8e_B{'>k ]VZW ۍ&Q1(.i U(*A`Ǚڧ=;.mڞJ[!*Ih$>Zˬ֖>!UF.nJf͕mk;=S$\&JnBPe]) 0LE)v1{.UmmYW!53k352ߺJnT&0~ wMexVt%^"{Fbyvfjc<9"e1/"HlDVJ''FdCD6~?^RD'q: }"~a^tYHp.Gg㞣-"LNS!Lc5,`s9  'ZlҏLBƃRsWѡ*`9BzwTW>NEC#[$ffڥ~j:Aw{^W 1.U 8̭84g3Jڛ[ 3N.`wzQcIi%uy70Ժƪ¢ҦeA#ݶ.2Wt{BoIWj$l&6nUmvin[bj"*j[0+\v#eB; molnlP޼PMsMz_i|}FDUF$MnOs#qGiutAi-0W2;6q$CiTf\+K$ec[kY6R(dwQx "$W3[YO+YNԬ8vǀ? QbHp'3؜u;+iQj4l8-'➌g!rW$K  C4Zg؋9g4yK忤sUd]O 9`]8RH8X2Kg 挗f'A6$@̟ė|ʁ'H:D@?q0L1jd`KrkIYX) ql4-y@`ωJQ옞<;lwte;)W7 {nYeKtQڦ5Ud Qh|E%9jcUm\Xln-zQ~QӿŜ\pQ(pƍ37 fɽ j| 2lE bcm Jv70G(yb@\V6؂3LkEmX6c,U q<@Z;Ql6ұi:wc(ݮCeC rJMqEb57$E p4{a*yMюQ 8'k9BhLӴ&2=q趷-8l[)D\*wkrs Vh0He#|;t|hxYr)rk5^oGn$;[5ɭzYrk/^ZoMn'ۥ[ ʭxrkJަ/Tw*fx*7[ .ʭ ,Xu;Sk^Zn\R^,v!s.`y{t}rv>GlJ^(X$) T͐FeYieS)Rk-nqϷ/ ب4k"GѮh\.EXn?DkPa 0I6 ʉ#mM&|ӆ?H|=A| &":] .z>RglJ\(UQwds*,ŸϲUSBU3 zZ 4OЁ$D/(A-O0NjbMTd>byg! h$ $cK\g&9:JX̐<𨘢20v" N4aԪ8H#a[\\Vc\҂ޞr.vja1[l x\﬊ZO+4E2GJqv*=i5##%>6LI:&ֿhg xzas_츧Ԅný#N:Kr2INKV Ӏ.X1jK\ԭ)BTN*ײ)$Ew)S6xXtQ8Sqʞِ.8>}~ǘdZ=V%̕? `aN$VAKS3p(7A+UJp&x\OkpKpⶊUz B3v wQSz6h+4ջ B*-tgZqHsS:mY.$\+90>-84X*71y%}%*j @6W4vA 5Mih-Xmn Dmmm|Rhu$-$bAbCdmZiHeM =ׯg$wWgS6YI!y%; `u[0n νm{VCQߝ-bh?X_fvTpK36|8ރ;PP*~T#021N}efi"X| XÇ?Y F ޔ`JJL0pI -f\Yc8?˼c z/m\"XcAA*$UO\X92b,pǒ6=J0'mp,oa 'nQgI4P$ @= '!P?MC} +Q$>o-U5Pm_bW&w]v<hW+le^p#K۪#f#PeKĥ@@(Hpଳ0z\a)+pcP"y*6kk\_(B RW {ZW A)~sE͋=” uZi &X5Z*%zDv2 Bj{mZ7f/rZr(~% O“C9V55Orڌ&CLc\rhpǕ8sT4WRUZ),dQ'Ժ~\ec]rPQ~TVH֛>؉N sl.eM*YNd 8ţKR:o  @e&6[rK. ڄ˗iQ/  *e(7eWL䎇;cW4ʙ&yzg~scoMjɓz{=G "V~\ck+JFؕ6vvc7c_ϳb;Ů2Wc_¾w;+!9QMʼUjZac~zs"([#!`Y:(I`9Q,k7msm,%8[+lmG}|G؄['ol]9LNcT6.BͦYبJ 2 '+Rpd[xPĚ9rM~ (I!՝>0q>q$LθZ¾r3͏xM.]Lo() hD|mHg9k&^C47ɭTe"g"%MD'0p>'\ϲy4Fwd}"A+NX`cK"l`6:S$*lF *0* |}`!<;܄o.fHTy,Et)H\Gq<=J w/c\O3.GmwIVwPQÞ,Cc.K3dz+6W`؀eU S&xJmc'4Ѩ6hT)p}C(Sn][DqLpDq hbXgi==`D0GU Ud$rå=4:eIKv$2f%丣lhW0ZAko \9_n_n Keח~8FF0c smK̥BcbX!zlœn ح(_󻴢C}5S~dYfxLz'_OYH_j"X`]%Koljią#M*CVzU?:z6Ӭcq/_&|5忾Gsubv1~6h#UKz(%my׀&R(sh5&z~]NdF7܂+o(M& |^h R|#|+E|+E|3ŞW{#E|;E|¤u$]u Jq"otYj oPAn|bԝRě:0cܝ:j$` '}I Ar R!}ʲ Y`5vFa;_JMU :||A_oѕʼn-H*L?~{&~逋`] ^,S췊J cAEV3{cw\Abzb^ V2hg=JojDfk瀺L}/#I! L\ߞ{c06Q:Z?9;K}#  I97.Vb#Y{ 1q3J:__l鿅QZx㐕gk[͂)H%kn`I옢B2sWBUeF.@(U{) _EW_nW۫I^MV[W_K^]>/u{fhS0A:2Q- !IdRod*U" ؝'*u@Prj]Q 7@^0cv̧.7>9"[Jqzf` y*G@-4"_91x5 A/C ̓"}2;9r5kĻ({2!t!yU\T{L#NjKaTJ̓L#Ze|f%%(Q6W@`0d5OHyoJ2C4w\D&l*ײ#2^3#qzRYnB;| ,  `OH:0%[1!Hw{{ XBᖡ|)-W %8αJAlf{aEAv\hWWUa$aZ@3u~4QNM(g/S:SCڅ*Os &(w𺝢GwN~ƴxr+=A-t%&$Y|u|Rv  rxzf}Kv-Nq{ nEu[655"{|^mVԗW$RIw, /% S@"*M:Uy=n "JVT/BڮaƊʹܠܬ|-`!>>ϩiN`7KհH@U Ufq;SSn iQ]T!A]m.n\6v%/h+j\ijaEI*JǨeQQEv42*nT@5*e@^HYN0G{:gi*q}(32 0-/|M=y8ooijO3ټp9x4p(FXg#pe#RYG e5c4pWzi1#U3&͑4c! <"jG?%$1>+-T64t h)cA5VK0[:?h_8/il*6F&CSrv@8znn6 nn\nnˍ6Jm'ܾ7s[)sf!A)$n;Gʼ}BL90qŇQ"HpPEMr-w@Ɖ Zl*,8m+@7us~(8KٖjvOrt*}%Lί;K2v\qSxwqaL9LvwLâ%|#q(><`PpQ,GSg|hx C㆙P_ C% ]hNsF\xI@VՄť?ۍ2"DIV$g+{M4dNxm(&VZ<DYENA7aَ2k"-+B_=S2yNAB6aAA#2f+ϝӜH`WL9H0 ĺD!SqmOnzW?~><"m(лB̩B1g [g ΐ7h;)<[f JXol 5 A~ NQX7d[Uel 75e[B9b܅uj W `I;MK&/#lET0Z[ll6BIo:A2e xF22Q%Iιg }zOt\JĹ :$-|iM`4RaAbT8#<3nB/HJi,6s$9hD!V+9B+tЮЙN5E{lMptiCաB5P8mBM(k.!a5'vhwZ)ɳ8剠&F$Bë k0Z(-Y8=(ŧ,aRqN>69깔`eM]Nڨ!*̄_fq@$1q5L +1FOK oi?Ηt~tnRtΑʙKD )e!ƒ.5r9Q{~.Í~(˵^EFaQWh(/ \_hwB| d wD"6 RXqclv=EO~qBߺ~ n6a~~nпE?5@o \,Q VjyPzjK#K\St˕t]m'J4vR,Oũw?8~YI܅OKq c#TfêXO5ĚnozQ:bG#>9EV(8PltFlܨٵxjB+*桉Ur5OkvH%Ψ$Z9H̩fi#vĎ;"+۟no3yxbD1`$*!ƪ1F!\{cUۯcbD3=}ㄨ|n##Ymq6ry umi舉MP3c|Tu73@> Ͻfx 轄6 F6T ,yW!qbXD/֢M&FƒoQyWaA8竣$^_}`~ШGO2_C ^tm!R904^ `jWדԧ9NCba2#sk_egWeN*ܖ}زy:-~w0?ӖMfBV[N-D:hɖ}eҖ.2(C&˦O(~)BG Mpl1E|C]b)Qv`~AZ WL!U@!Ei&5nj_E׳QO6 !)T;@/ʐfBD(QFݟIuqѶl جrYlfpz!46n[6Ithgj-yt$YqS-:ϐ;#؂h>)X;v-@vMʔۏQ>d2+UQY*,#`0,q\d1;rTJ`!NJ'LEc E{:3RhXKRp׹KP'c)SLFP:a7mϊ!t| CU#ިF!txجF5տH7m$U#}!F~v`- $ci[1ۯٲ+|0rV0W1 i"勲Nas2(ē[$xż B)A/ `D1zXɧhY[h?(?wG ՘E= %Ð婄"A&̦3,C{t`ZM:C\vu`άVRc=`G) rӡ4-(_ j-}p nzLhjU}!ѭZ y/-7j/M+:,2@uݚnjaE"oB Af{}ae_nPБHN^kn[{i\4]vXS!-n n-uڏsn(5x&׿/(\,OPNJYYuB2y#S'OK*|.ƴ*ʜ=b9.bt^ǤнWnoW&Ոݚn x&\&{CBYRDtB]7GS0i<`LF$'srWzȘgu(K`t(ߘ~/"+f 8DydE0%Q%L3h3|[M>("""aOZJp ~G%Ŧ?㸅 H}NXR"1\+t*<" I>Qb*dz@ӗ6ҺOvڶ#_l;͡dic*XB+|a aM/2 ~*Ѫ8 %$Fݐ XZմ;~F?cT\Mi>5YYρvf{ag>jv`Ro#$NCKR5Hm 9*ĦsJ/Kē){T .VT0UѤg.H@sX" ,˙EEz2ŅGD{OHa{PAȌ"jn#^Dl jEG#v@&O3*Evh=P T4af >tHcS0uJyT=CTu~ovi ϘRX Qc921[=h2"[Ơ󹄆sPS%0-MrGwz-\b=˘  ?j,TkF^/jمjAô(6fo82~ ,jjg9Fҩ{ۋoi'aZiVe }GZ[ Ϻ^fΞy~4lz]ӯv-f}zdV4Qn S(,)n!xm&dO5rePW$a1,?&-)a%\j07CcDN_Eu,9cd90H+i]YcmqcfɈ2Ǜّdil#0t@l M'쫢lNpl[`d?cMZX[zƇO_6҈(o8Ga!ژ兽8Ϫ'f)-ES 01xrqLp?Mǟּf'Lƿ}lm+#X՚7,垑` {? ' "Eaڋqo3kdWH5+ĺyA7tp;8_#/W H!O(t2GDžYP :]rȏpqe*i r:6k0y Vpb7tx&ˆʯ~b~n֋bz1׊IreNEM$^"u7m"?3޼5mrQF`ŸoP4|F1`sqy뫘kTY8f72Ҽ 4odXE~55Lc1 aYx;&_] "=0Ŝܹ!$! Z1߉毚~{@wb?Sh{\fb{&i|Zް6^OK6[(VW*٘3 "0P7^(6NM^K [h.K(~"B e'Wa{&F_ÎMYh,B#&;1a S=+'xg 81_Q3vq7! yI:`PC9ױQ'=x(9A݃$OuI\_ժDR# 3\=`&yc C~<KZ6/n-m@уdVAMY+ 31kj1^q], % NfjTFPdabQ>PNP?Nʜ}VC}!qajD&ȴ*VoWjMܗo $jS,RL= ?+)X2R^uVIBm ?/95IbO fpɘBVmSzz[A!>fcjPXZ'OP)@u{/f9QJ1x~BqO-.ߞtN :A'O@mGU Z!(@'͕zIФ8tK.Au LZFth}UST r@mjTzh*:v{Z鶽&TAb|`Ë#;84xM2)< F[,nJ貼$w[]Tۤ.ҹ?|LЗGZQ֞1a-MREE#o~4ݞ}^p6n[))zNhm愠-JXULW*nȶtPN\ Y]ZN}(oQ%oSe+* TȈ!k$LTiMBش4W8wv([G?)v, tCC|JxUCpy^Ab ¹U&=&Dt!FXǕ)܃˫ Gǭ(Z67Hq1>ZC$)>k+qa0fxT7Y>/AIeU՚0_aRFZ ̉AHC!NRo".p4kW_&EbÀ0"\|x|횭A, :g j@q1j)$fA |uh]>TB fO>" 58Q`\x@RH ◖~ .K5֕ tͶ- -bBG=ysEE1A+g}-Y~,)B*@FYODZ FaNܘRpYI^.` ( @EA)nFo_I2ŧva|LP+i@~ hm$OixV:ZGho&ў~n٧RG-RZ̯ W|!'ps(n]"T6B0KnVv &pܿHPט'ycD0;+%XyoT=$X;`."NS 'Uax99.q|tU2AIy+.\&vI@ p.88 ??{|_b= b߫бU*ǚqe ^VInž6;Wgvl^qkV}h›`w7^ owC ~5B'0smӲɋc"TF&z>=r[" tlYS&oi'8&|Ckb[ih'Ɗ ]`BŚvR8Ae2дᄼ^0 !MVhE+6 & 5m1>NE*f*LUۀ- LR%>3#i`:GatpR&.ǟ`D RoO k-.:R؎V# uͯ-5ٰ&#VՓ{.wU~1g5P_y굈哳[g,}-)P㻦y ֩2CM%Ve]qs:0`DMT>OVKIo&Ð`L3X.?ȷξ) c65 "(U/a{uYxw{<;qb$cw: -a .¨@;pA ]D'2wk@WfgQ9*y0bNh;jdzǒpR3([(uМa di4Lrm aK PFtP͛By\jP^)pEIނ Q |zSwH!6)@jX|.^Q7P˩ )i£:,J?̼=LN|LKD3ZN_GZ`{&ձJX)Εq(A,gby]*NyL+'f9B glU)~F./۟S4StS)Nu&StRt~yqxo/xT,/ 0 *Ib{FsXajY42idGzF11jt/Ot/͂ ?b >&>|L9 h*`VZC#76P ( G#&nc2 8 2V -ŕ^xʋ]P4^~-7OF*ZaeL?-5n5N[g %Nڳw}צƵBcDTFLvj3q|G_凅+4Y tW w jd@1V#~H 4+'}Vl{^ JQ[o%;#UO-+d9L?Rn'?6f;P ZQ_\Ҩ9 IZ Kl.]trhtሿNGPttH(:iX$̝]N^˄efC_0UG:USbU?IֺF;9CI*!trT E'!rwPtRvNɸ-[Dv0w ]'aPtr,jD/ޱ 8p]慽ǪW‡ ؔ4`'~5q_t1Nhx%5`-m^VÀk惉4B[7NFpwc# nZv|NKP T W%*pBQ'cϜxgέoS|*8}BAW(J)> 9W{߾|t'@O y&ej' 7C=' A\2/Ҩ'L䀃TVbzo x9.ܝ7w-QW5JL_~~H@'Uι vqϑ wYLVvA)"f^}P_rM}L,.=pG#{UM[HCћ'oPdZ[ XVcuU6d,S W-Ѩ81d\nP0V\E2ĥ9Dx9x71e0oѳ@yfR7$J5 6 FJG|S6Fam|}?(ؾ~>_ @׭+>Hy{,0!Zg*6y'FUvJ%Y.W緇H#)_|ݹr6e2.(EZķRél"`GG$Q JO ӮK>=i؏,z;'Jy-A?4,l- ۩s6CѤY{'Q:?*C+zjΦFJZf{5 ⶃ΄"VkӴ0g95™0`bѶvpERlӖu0m)[rӖ[%-mޒ#†"moZ0^[q}[ڢ#ۂT@_bv1e.S'XpF-PE(淃$v֝*#陏 k]9Uet;$j'8mٙY ē_ (JћJu{~+L~* 秗=RП SStN!(?PhP? BPFfJ$N~)j5_bL oGӯ +U:ᢷOx _ O-iK`9<+|LuĂ )~P @HK\Z ߦ?Rț1Ӟ<|/˧;Sh.Xz:~< Λu?ߥ kK}y{u5#e2z^F/˸זϼ QYq z_ ϵ2^ oZ7?Bo1-lobxkƛs?s?skσ.uz!_W>W)  O <)x;Q5~iIe/K6>5JS8~tB),dqQ.N֪uah[TGjZ;ghӕhwI nm1_Ù$Fhv8S Pү@J,ft+Z!ՕZ&j|VH]&U 8Kfi9O4w-$N&/e[xdg:@r.0zz]eqaUoQBb3 %0^B/]PQJ bLIU-RWK4Wp,N=JKZg(!WQůI_Y\17A?_SUӯ_/A+Kк _T&^Oz߸/ и7}>?D%$V^H'g:) ځKbd%|xu./BTu1N =ڪZ- ZJ :quFN /Wä㊲f Z.MU{sAzEѪ+jT_|^Q,A%HT5MPZ}H'ȂEՃ^E:JǸ W_?וo Q!x\r;29mStCMF=˖釻]-E%<)w<7w[üLIgygW]edYÙs  ´H5ɯb!]$ Nera=>U\ZU9yqRV}x>Evc]N-bsA(pVȀGMN < T81Cz?[g:a5d-MGzy/ ]97w܈4r_18\cԙNCSGߥ.XpRΧV㭚?LV.Am8PTfNk,530h#VrSgS ]tuQH<ɗ N"} Nk:x.Vaw! oB!zdf70+j~I H~xGr=}VHԣk`,<`MN=@ͫ|U%X+dCa>%sow7<uVoSy`*sR*+CǓ"_~zeq:N r .9 5~e#FɄMaxxҳLo ~f6AHjv@]7 KPqKI+k L?j)Hmfs&|I%PbZbK=pAҘ֬0KעZu 0,zV-SA`(5J1]x40~nS>`~m}T]%0f0=90԰7\*lcILUgbasjU'ca@P?Á2ft.2 +39aŽÙ3)\YMxT&cő{F5(ˑпmW2$6g񘀉axHDCprfTcId(K_vkQ>56UnUyлn;G͝lE^Xyfp=@8#\u.aϦt)}`wOVVaBe̸% tKШƉ+:]eD }BcP~͵[*Yhr, c ZH- -\'%|Xfr;BEK,'˄9*N)1Ug` F;Eqj#@Ńj [:<:$IRcd.y΋.cQÖzny$si 3SZ֬.PwC0`M_hTSHո动Ҽ[XOP'ZnuKPK)(E@zdKh"k-@L;z^o Ki?9H(k44*>%Qkdvbצ;%)|cV߉]x:_b{Ȩ> \P]S/p:W7 jd݂s|$ӆ(BCNq.B36VWyzɬICUFS6Q瓂IlF+k[o@r /E;[/ RaDVBgٽ2#*ۀ,E-@7qS@AXq: t.F.wYL'-ӟO oWE[FB~p?;_p ̵C E=A٨@-vujG͗ՐJo`/MBACCUUW /CcwP0V@ WC-\kjm.CG.LT*~{5epPP_~?ET\3v5` <> 3D3=a`2!$WAx#A>Hp!>*Yai9`]|36.") U2[GwE?>T! Wugc/6&) Z|SGH|JaXJmY3jMj<( i+aTeo4uRT7yH'mn]ʒ4ـiP3#4'>NMFMkRؚA[y42[Q,OEC(%y-+pX%wC Eĝnc k1̒Xb㰰t8$6ؑ.d}0ns~ IEÙpӅ+FF8=ë=b)II0:RX *d7K+WX]}C'rpV|'!$ QHZ':M9V }z!nᩡl2_ďʾp|L[œU [0囏/\LjT Vu0I;7L嘹n`&_*fVf fvakٵ)`ص\qܬU\]b,0\]%R3)oUd3afmH,0ovI`x/oDQ!W+LHno?RU Ч)3m($t%GEhePx9w=_P⽮@'iX'Nf?&juP)Dfie˖5.[vٲe.[~k3]A8q3^c8e(5,Q}gR  wt8oɕppr7}{rYV%RKU c"tI GCs3PE}8" Ogtqk8J lzPh/8 1s4b+mgmpK>PYHBb_ ~$3m[#g9̙Wz{2Ƚsx :T2)ȰAQ3z~lRaui;:E<ض)*q^)R!5ZbO}O(qsO5W(?ΗwȵEzHAyPS ӫeXG_(JE5(X}"&2SϺɢ˪C=O Y` pN!_0(ٕo kѨ{a k]  X?5*u?0?=Ã/7 GFu#b贋XHK=U!8bika>:FwK 8~.D!Tй@BCr\kRwpj'.5;NaW8 h!.YB,<%Y: daI) #e!,Z:e~$.{\*7X&gg4աD9#ab*Ta\ 4izr{剟Sg]d>4; %髗}ʨ{R'S2Kl CPY߳Ϡςߑ_bmMK\iӇ~0gTVs@[-A]ߚ_~E~~VÃ]*?=Q<0ρ87z7>y#T75~Y˯ upx[Xfz$n W&U8eϰ f,zqA;XP;(<LQģ$R4IjX\dK,id,osFAgF}:{Xۤ.BT!K<^Cɛ!3S0W0"XYmcKTs !uR%a@%{P'fUQuI6 1j);y&\>iڸ+G^rZd-oA |M xXFr#T%0+@p;ZSkѲ@9%s0WߢtNl/UB2Ep3dDApW6s4e}zvYeU܋2Kӆ+E펒=&dD G+ ~b'/mt+ G R; ?0.8\Bj/g?vpx%`'Hk_``go *N-]lNHO/gn.D2ԫS?ګpŪWgviR'u^9aX{% D=L%w+ex/σ3M< S|4{ѧ:֫Ōck Zσp!Y}Jw&4m0UKDXYޫѧ}BGAi4bAH'RvQJeEEgY s._TP !TMHh mFr+qδ:ic.GBa|Wrv#  횟W9"9"wܽ`j~$4΍x*%E:(7$RƲod~+z]6J_iʼng"Kh5 "MC=rz$RW\QSXu2+Mf H#oo@cD6Q\ՠ R&t7 i !#ßϞV(Z#[Y}azUK6(E[ۣ2~+7/Hg&{aYmɚ!6o"t7Oއ3M-KV+{n3;B(_YG/T,ZvT]&&;g(DnMrz|kvs",G&I@&NO0GM7jVpסk5ݛn.Ûн#2dfUZ(u l8@n:6~Mm(:٣`U$$w杭JU+yF$;vY⃺%G1NtG}E,a%+gy>֙dRڟ[!twW]Pk2Z_ 8B S)D,6%@rJ+ڧvU(% rH/L5}Ik+rvd6o[OO$>MU3}BhCuv[Y-'eS(5[N#P1!凁_^#BOz.R'%`hjG}2LA\ps \\pr*\pr G'4Ϸ-s`nYN FoB+g0w^~榩C+Pt44j!%QJ*iUۊP5iN5 &KXP:Һn듡Q`\$G-]v}",ܷŇUBCKN[Vm3* -d`mX-A0+tg\DW.L?O,ǣo{}#;^Ϝ uj6𡧹Sl9.jLH*hGИ=Ih8+j$|TIֿ\,wv)M[a_Nv 7-ļIW±X2$,whZȗ0Dk3b[DZF zU2Բ]8ŊW^v T֦^m&srv^g {WX"0q&YmG(]fю܂o$=hR cuby}P%~W'zDL/9{-FLTf:`ёл.LZ6Wn,R{۽u-7mlgFݒC7hΰojuݚsJPZW{U2n`yh };;< `%*Uq(;Lm{E«PE54w^nZJXA=mꑅE5Q -r.t24@N >kൾ0 6DkxlhsAˤ1 .k?A6E"@<%}Dl; =.e=&mHN F" MȯX$ȻȜf<Lf M-XvCEBG6>@o> ne4K]zˁͪ.6tODbժ吙qprNЋ%tHYO9'6Ν % Ճ,yݡu`ıuJU#%;HCPc ÆUGJn] x+C%HNZɇ{,_p WEҦ jz2W2+_ ˆd0<.<6suǽ3[ی`kV1isC;+36bVOL/Ƙh  ibx;bȈ \@&M0 n$r[1?XJ,TqQpi3 ϗl62%G1AukбW/k?қEQ䏔TOb`?R0 )1D:#Hmۗ?n/ӏ>rqG3 ~EYۯ?*p;pGV_CJt=عJ7ԅedC&.%v@حײ]'n3H$),^"; 2' fyݳL4MO:}}z&Bd KԏTL*oi3dD9c=;pm>O/&ٺ,>hMq+4AQG˻ȇGz/%t{r+vط $dҚDfd*9:SDw'VxYmq򾵚q,4AѶn2 ZѦ­\/C'um\Wxaen1$fHnx}B˳y|U1ANj6bq,:\y îd8 |Z+ťa}[B1GXCır9w]w)c,Xb9UJz5֗H-7nQuMN9kmz|qy|6^ +q8[T9888<&Z) ;08V|4~ pPL{ P*:uע|;¿ǟ<͹{շo!Ϋk!VMN 3Ө3-rД ,v@B + x6˲ՈSE_N|% 8Z'DϰNl5~v涞=s1̰Vb8[}11-|)1+Q; 2ʗlۉ{~gbP1]Rub D`zsPfhade{0Lywk} pFP=rBF|뎦G|% <3/MIV13pہVXvvuddq nƚU،;( %gbE0 ($Ā,#R:ij#C/VӴsqxr ke\ڼc &dʧ'p{3)1&KٔOOP=xny p3guHAJ& lïr4zE@ _G{'IVEkR9^p9fƛN7HOEPSJjj^-f|k6^I+d~C>eMhz;*dJhJtO>O-yFRt#RY%f`hNŌ@(>Pжy@^ LBhF˲B3udԡ9&֬OkH@PI w/2wpx(ŏ׍Q7ƒGtDG|/Ēp@NW!<+b%3GrƪAۑO8dhbMxb*[oIa `g($fӡt4ʠA£eW_<5u(:8<݀ wv T}>7;f+ѳ V"}r?}S=AL9LC,2%}Po^t˕:w]A3}3+ }Vؼ{0ݓ0[ϴyW!kk֨Q /mM%[sœ ָfn5lb mZæa װҠ ewjGy{}{LP!1a %O(U3F9ğ{JWbvBW7=]>2ɄA3a!cMjrv2qχ;n#~w?:Qz:_ >}6CBcB:oCnDR&Kh,`/Dh;p QMh<mnCUF ܖ~p47_͍dGhT{3Mwh:|\9<5O7p/NgQ$sion^NJ*5 WAK;$Vܮeֺ=0Tաڇ*:o9A$7_Veޗ7[ʤb1*Z^Χ/^~zK 8<­jFXh:'e1#h} x ^ojke&P n.); ,^=Fq@r+,vF(Y#vF[˄Id.a9%\d0# .01S$"LU7aZu@5^`UK7 ,0q0Ѫ#_&Z`P`(XPaU"LƊ0C[c Ј&^`P%fw  Lj Aj^` 3X h4i.0gX`"iS!Lwi;cXXHaRBj,M92,bS/0 N5_H+ }xx?՗#n`\;!/ ENO/ٴhHQe,<HNIS$pr B):ݕG"l0+~`ql &d2^!G^$HB@8E҄d8OVL_ е=pI[Jw* T d™ q"SdsPL 1!Y',UD8AIh'B j715]kŐ'#{=~_}+ _1%euЏex'9;/?swvwG> dM?NezMi׫U]eT끒`1$(]Xd"?DHU2,uI\Խ@ v!t{W]\z0 N>p8ccdF6*1V,Kl2ese,~z{;X #]VhZÎ7]jUjUjUy叿5WE!E܁;%OLV!&sc-*vTOs6v`>jʯIe^Gqqʮ4(SB#N_~uh4p|(xuNP#nᤫWK`E<BA>+\ɉ&F`6p[8A‰/p;ޛ8Ař(:lσ-tɉ)Kچ7ʙV"t)5tU٠k8Ư4#kNyPSfue̖?d7U˟lccUeD[`Ұc'9Qg1ͩBíć&2DH-)i09Es*7Ȉ# \9n[=Nbnq c"L9븜4!d{c$Sc\^Ǣ1t4| K\֨A؎Ɖ6gE~R/ can' 5] 2UJiZwiR̩‹*tUʊ0]` +琷Ow会S[@C*Я$GMN0h*Nz&\Ḯ98əp'1n$6?8$t' 6z!o~㋗!4B,j'ru-,BE5V& gk ,R>zǭX.|fҭ` 0,M=bYmV{;ya1nXao W؄%$ : ]bDq%iWTkY 1^"Ojt- ,EX{+׳(ٮd\"f{,fbG+UBV8O#rxine-lib-1.2/misc/fonts/cci-32.xinefont.gz0000644000175000017500000004552414647725152016135 0ustar meme},KrTVfcd[effffdfYfffff 73wzFwHt~E~=dO?r%醴6}|Ƴ`o.R]}-VپW+,[ MEBwԅK5٫l'upk;!CvC~=GCNx{sK.] #?||w ^meTx<.#=PUCBWej$\-lh䕒gx>:g<ǘqI 纮u*˶E mbf%ms}+M6\jJHTa7uT( U⁧+/U |UajJgt]Vຒ\W᪐Ү}ki>uU{]MsUu]=L>К_So:u3ʳ!:_6>q5S*5Hዛ_r\#eep(/bmnλ|c_:T9"s}HP׮@3782sӜ|aj??/$O%ӯg[pv ̍ՐѴl_Qhۿ޲F;6ghWMլBShanmg7GJ(,A]CfQ tx<}>HCWBtͨ@A`nӉC ?t?}[-.ݗ9٫ 5MDwo.ߗzPս!N7cv6af؅VUl,.S:9ClJrYu:\&/m<(4Ԁj qLvTGE]a h취͈/f4E|=j.LVTՊԗ9څ"%A:/(_%bhҡ46C¢@i:l~闌 ɒ:fF_iԊ5mb3w)| N\o*Ǘl棏Jzjᕑ4kWc2ψ %mb R 0\*(N-&CG2H>L-ذt,xg4b$%Q.(n7xekXߒTSؿ,ޅfhVD,CBE6I4Nbw fqIR͢w-΃'"0N=WgAgΛ+Z:Ϯ8EkP+η1TX_Ц;*8h q{Iu`xAaN e:6M @2CvC($vxV٥3[j6cYV$nȼei+Y^p|=J-5>HWsm)hφ,O3|4F}6۳%jsiAZ5)"xe,1BVɮMt%&ʼn!BG1֦OKdeWx4*yvO۫6׺-nLvl1E.\1vV^zD2 (VV wї !_+v'RwGGe{#:/i\&6v J ZߑqVXZNœRJz :]&5RLRVҹzCJPAfܯ82 fSOA:\N¦i@rZ*e>B~2n|.Psvuf }UOO@fRۢF]Wmqk16 8op ,tJk8G9e LЫ54}߿|(6Y 5pW/weZҙp¶Pm>n2zsOFû xA!78p׈'T?Bi=fںg*޺/B.cM)dнSyچ{'gCO$T-c&U4/4+iu]ݔP->?%f}2 ,^aV2vpH8LyhpUҥ[ve&^0E{d3S~1 5fpx'9θNY\,T6X`y]}ҧoswA@ޝ:vXTnR!e_16¶WX ԋTjFjrO;H\Y*JMgRV}zކ>(i.3YI=U@(xx>KWu" d'^RZT,$1}״%҆++" ("&t).H23; Dcvwd6uO|3=3P<o;PT댊>ϚB>ki$WRJ雾"Bz~GUD!sW. A!1O_HI{&z\6X{nǑ[<>4Eb;)2SXRbr,#/ebm Żq7Mk{CZ2^. mׁ֫!RIU&Il=lGj.G;LTrpDYT-HaM,uǠzyDŽ雿tT(eJ}X2j+!넞qY2U_3kdknTsBtr.:EѬ@Mf**;0te,NX4tj+8R.j1C<&A>&2&o9iZ#mAW[M %+ LG1Uf~iBY{ ipuA ^ֆ]rsX |kz|=V!Z1Gqt;?wPmG~ =R"5Ë"}Kji9vX'l:Pހ(sr-Z+49Dmp֍Z_)/8u6H.?Ǻ 8 k/BrˊV/w/dSYWR*Ύcc Fw DM]hJf;-GC#Dkmq4xN1``݉,<#+Ler&5z؊P+RUg8WA[b+c7@ί*zk oH yð-d*ݡ:6t_^"{4#\Ӣ`\la3i \fj`qço-E>Bxm^bDoh̢6ZF5kXQExlf6 FF77v>(4DSr(n/ĸ :L4Nq̳r˹W*$fJ \q ^r6V#덭hTh*Zgzh7h7h<H,8gj4m ;ȼ 6FS噗!{hr 1Ggm)LW]_MG❎?#\ӫQzz^k5&J<&;jWoO`@A޺!{`QBl4\9n)z9VX A̷wbؚ"cUVVa]_|ٝ/a#K֌~c%\>{ N4#G.땮mτӉp:40޷z,g9fy X˺=B¬ӻF?,H~:83sZS8a f%kpd:#6Be%?ɤ(_4]g&x?;#ڛ̟q\է.}|r! =V,b "nMSK ՝s^h*+i\jqW qYv^1] SQ'fETf0ˇba?}^@9 [b2YTs0Q f>!1{_38# Tʅ8C )Nn5^{5=>!lf7ӌK-ݥj'wաz/~7ݛzrl`Mj~@ȋ1>Gbu[}6' 5rIl뢲8¨rEPXeKٰ]UDA.P<_F\z܊C=ywgsxi/ĺ lTm k?p)ygN xg+zlw/|0ɆdݗH9/J1T3r>dM6M]mN:--x.Tcd|P';9>hDLA fׅl<@'ig=1ca<1 O!1'l?z&TKyg}7<3LD ÑÔ\}6ͯp_݃ܗS貺4ױ$mJ4Tɥr3O t(G&$3ԋ2pH9\GG/+g9m6޳1#M8}-PTI7M2QZN?hMC#?^x?=l|թOTF-U5B, ݚ\1Vz4-{OES_MKG]PU8\9 [xY{o0TjB ~Wҹ3ihk{5M?d"q"3سX~ ?Bl3;ވۈg]33"dp(13CWv)C؝f WTnۺ\c|~5ur̬6q!gj_JMa wjMGz$U#lOW6|w7G2Hp=y}ݮ3JO gJZ0kAW`}<#>( 7䁣դ;U=SXu{a,i+E3 UV(cEЀ.B6>F jMY԰g=*tZlD[n7R h, YEB<xbㇿ/Y!$'Q›ωRF6qw׫.`MPٽ's]ی=1j7Y<ׄ.:86*Z#^;pe\f$މ' Fk%5_}a:1r$+})6€)yӄuIA_Ϟr[ #g nl3𦹆"qJISVΘfKUx6Ȃc)?,qN>b_j @uD@+2cX(S+\qRrO8 z-iSFe:eM񣞿Y춄( wRQW B6왶@` -\,koY3.;D" HQ"3?%>T qPk-+4y77'Q 0qJ(#!qlUy̑\qh\B1g(Vhi\_e\{2(RYSi5_spX~0QL;Uhbk*"0^;=!癃`r_ol`yA4(h9XPV1$tAT̗{#uz:m֪Z#ex퍴"5D$ <:zlb$dЊz -{y0+}pr917z1/H#X(  4bkB&/TK:U"}'jd>Pt FZVϘpI8$|>4+{w~ޗK..cM=G2CK4vga" VM=4M}bor$ %KEX5[UjM=nIT-ß%al٦@k̐ЙDUy X+nȵ1trLT 4D>1Cf`t%$yefv2 zIaB},h/T8IkfXxxL:" ,KF$ qLKyWȚϼ! ʻ(â| 3)) ]m@)rgϨb-wۘ 1϶\7'Wa{,oۜ UyezM{Ln5;<NoC̖Jq8 N1A6=tK i6HѻInifDSagau6:& +?&z}ܤغQlU8m{4o>xG Gb.)ggBZ[V͉zړL@k^xHtޢ!'C"Rƀ!rB 9BSGJX$NۮXAKDLPW^ZDf?!0H:h۴VڰW*Ll>Yd8_(R&ײEd /;! "k; Zm]~ʬм@)QփȪ=(6+B>a1[!Ak&FtF,Jȃ&ʖg0?$녑̟tDQ%cQԱEᒮvp4 !(ZBE-¤f)wHڪFa>OLɉ`,S/fH+T>Tv6C/B%ߎhӤkcM=Ri^H{E˦pY|{bZI4C CքY\=~k,|..|?§F"sW@e6Ti_PaIr"yN QNBkѶX&t/C9ՄYX՜K5'"%]I)/3 mXj `B[]J-0Yh(r*-yweJ(;ʹhK`5St0d;OPDcZxZ4xCGq}C)9BlV+s϶fi;Ol"'Xm X8θ ݊63=e B3o|v&䑎RIn/\o~8),](nt*gђ'O&*Ne[^ m(&^f$|X~, -Q$xDF G'2ܦh#>Oe?C+j2l7*&{!1_)1! vT]7F\9rW>sk:po-\axc +;ѼÚބ_=TbkaitǢ,G7a]mOYYk51ޒ"%{|[NGhvQi/edn,%WcR}plU{7x $*92ݬו l)I 2Dŷ]o~W.iz_:iϹ-^qW9m o-}Ñƭ30`u_,l'-0;@yib~8b+r#8>|BK1=ny>9@mD_<{зܳTx(;HfmS>'n ҕa*ԍu8Co iB8@ue"Rţwu&Lw̜v$ɣq_6(͇_l4 ҊάNQq&]|L\*Sm1|zW|X;) TW9WU{9څ}S.'K-: xd&ba+w'I, t^{%n勿=~4pP? AwU{ŽV:aXWQ2M yҙP7AiB%d}t5{uQҵŀ~5 x:AVCcVAV 3.5SbZZK|S[AU4Ye)6 z޶~Z[|!vok[3ӈR%⾑#1CZ%8A\-@r7TO>ȑQ`ź5WGfL.祪4.Tu7UlP||/5Brf: *77ն+en"[Sh5%vx_{aCj/Pl[x b6#<$0d^.z4ߜ=IL֞^1mOgTn-׾4R=Mf-d&*tah{uڞFr=SiԻM25fU߮')^O᯺5jWo84jVb!Lю7 2ns$D{E1Y(̎JOh [zٺ>4"ciȰ3bVn{ $i֓(S`AR`J%.Hz#mv:ƽC!=]V{Bx;<x_:1?0Wӷ ~İNK ODBTczs MSԇ="7~myfB_8a?gc$>#,A0yڰa!*ro9'β8Xj ~ZjpוW,eGO^~26MQkm'iQg^ `nM[Sҩv]tI10\@J>%4- zǓ%p ;FT h tP!!/p^ sEL.>6bUVY='^n /:vtU,dGFJl=GBت mB~kK ЃzED-70eg-z`z ApL+9n ݌3݌՗3܌:?m<#,aQJP!>Xi2";oFԫbMZaN`/ qF\29VB&ti0-*u/zVT(f,D.AuSeɚh͢H oó;\%&[Y;'n|E\99F5s9a.ԔmV39 US_6D'̐mxeIϪوi cuLb'sΩq+.d'n2w9 YB3vC;"O'-N&;@$ظ'Ko/ :}+]ލ}}vٷ[losh{Mؾ6mi)':q=MѱwiJ&/Ͼ=ӷ5ַ׷]./3`Fߪl؏ǩaF۷Kl߮}ӷSnx3 ^4&H}&$wBu2q; ֫:!\ [iֱZ t(1B'O}3*&/ }H^֕OS4l2uɕ2GZ_#$j'>8r͔5KK:=h-8ދkj]ʊŖ,aDF׊鿇G,. tB&,ʆ49R,-l31ԧtRW@ˑGa\Ī4ۺ6yY*r[OkaGJS*9hyܪeW (]޼|#D#4^]I n]q Y@26q"ȿ ڲR@w,X&;uUu\$D.5\7`0v=&'[RmHĈl{)o9.XykO" gSs6G|6=ܥ}sT: Qz9AuQ=%UךdڟrDIYc1vw N .N[ 禈ʳ=x,Strߧ=8Ze&sj#m'8I$q1ns® OpKb㖵p"o]_$n3%L2SObH],1Qe xk%Rf cֶ3N=4uFi,6pW-nN8A 7vXtEгT7ܾt}+]0f%SleJEW@,A~̙0w̦D:cF%wEG܊qj'qj|aݽ94.cT""A`ˬQq!6ր>V<ֱV_/aOX[w􇭯?}{P;|0oUMPϯJ ̣Ѫ䔰|07jW0ЎNؙBWK;v?{z>N}ޏsǹ$7ۙ_63yf)z~ |!=ϫN@Jzw|dfQ^GFzC7}9גOKU0qMdHV?3mP|o>cٟphel1:xRDUyeg s;U*qA\W݋%8VS 9kT}|ܨ>fAB4M#?-;/~sQ[ׯhV5IVhe٩f? oo[sTC.A wKץeSǒ,<˦f(L$(1%cfCΆtͦf%{lOars|J}-ٷ䆚a0C `R?W}nI5" xpw~WsȩW%#58T^IvվjFW_ hsju%5W7=:es*qO ,ENVӵ}pbJJ٤b2-7*Cc'Dҷļ)MX=AɈH(4D;. (AF@v"NԄz2TE@%2vYL@|3^J3Jͺ"'g>N=K=WvKb-P=|Z1/.j , ۢFrG G{mitG>̌Y9˓bkL-C*z-` qwH P1 g21 ӫ|@ΣK5(#c'|ĥT×F} Tf:-! `?@xV3Ð{C 9oc4d_0Hn=24dL_|95X裿!C6R y4 kc\*)܆}.X%V,g z#Ð=>"߅}ƾǖ+Uݤ΢8ZhٽEF 0h-Nnm/ZV_۷OML3Y"Dg`VV#|JN 5 -f0D`"o{㈲ {EOT&lg3+[ F`fZ/LI{}R<b꽋nڀ}zW@Fk-T[ܚ yRӝk "{4O d]:]Ew5Xjn;dxT>I ^)'VQuᕏgi^Rgӕa%&u,EL^u<7};E/n0&ENĜHIu}d,"E'S 1-$d'ξpYF +p%cas+OϹlLG\m'OMnA%۝ 5`I,p.:<&57N/{xDwxkr*1JȘwq +&^_,^-NꝄJ'); -hRRGEXjU&KP/r܇U& . ;0Wv0iG~}їm5S#J]35<Տ}%Vt}wq2;YnѰ+Qp ery2*#E@}tԆv?:~t-FG.-\ۿ*,|Ԣ90Q`D9ƫFΔY\ |3.RH o&XIEydOhvBqL;zX!0ң3GƩ<=>SK7|z t1uИQg;mb- X;flTkJ L-Ln#?p2QC\fHxm=^G֤Kx픷[ȝW!4 w`i^4^^f  q#:NiyH}Bݒi,֕兵UVZ<0yGҾIWSXݜWL!hJӯLѯeJse}C u Z@xx2FVhT=ӯK9^Js>:4EУ{ʼnEhGG岧9_T UT{ H8rKqIj{= ="9(|"-l(?O,e9I(!q#c8sjv/n|a>l[1i/E#k6<.fϩV{wk]9eVd:ϒX;$49M1zZQfY!'00eT3i YG9]}r-/yY2%7exine-lib-1.2/misc/fonts/sans-16.xinefont.gz0000644000175000017500000002544714647725152016347 0ustar meme=,Kqupw{Ńߐww#uiά7}gVwbFxr_wvuӽ撽se+y(N^59_b}QۿmtoU}1:e u]n֡g2P+1CC1v_6Wڷm,uWhv/ THh5al}/~N<.61Vw\Y:~'y<5hb>C{Gӡq {g6dKm(q6A>Bڢ5">7(?g@77\ܼ Ar_MJ&TYiG?0"q-#B  ' c?V*6BNns{@%7,bO=B?k &LmĀuDO?Rzq@{PYSCaDݔ Ѐc灶>ýn5 K1FF HDTTxLN):q#BI2jD=");n+ Q6i 0^R0@zްCl3Ae?["/ eZB7b0 rqяS葍;S]AԧFnꕗlދe4$ܣffoLV7^e upn+#t`{Q!DKk) Q` >f^D,B@PH^<`) c+?d&f!P`AR6s >Zy#X>ve0H9^gTijVd<)+\Q)՘N=n Љ 0EՏQ1BYӪ{/<4a3b dƄG{ݢ"IL'ءHA>k6*xhO3-hO?a(,[#ޡ^E.Fli+}>{z0{ړ4%0#$5! լD&X+bunA, Mѱ$yXOM/9ny$o}p"3ߌ&,LQyeplhpg(7Hlӏs,/l|XdGM"RTAbE+&^ݴZ\DE hmO@7Y!AGQn_ޓPlinPvښ|(37g iP{M t(gdblL"m,kɠ:*P]ZYQ`c ĝBf'Jf8;MvqY WRmY $T b^SpE), a&,g1YDgE1"A$hż{a}{ҵI| Fgdp^] R'=s&v@L(+3:XА5mG(Y aM;*={! d9TZ-[3*)Ik͝xE)]ޅR2Ěᬠ{v;l[":0aǽv =wbk9qb܋ xz*݄]/C]ĭμ + 5j"rЂ&A*=B'v`r3rY/G={D88‹!)ŸPfł1BU:V xAXV`_e(LOGy`k f-ⅱ~OwYqG4q*}00A%Z}:M(k"P;H;߁lǴK2 GM2'(]hɨdɏIDD %IockTao֊Z{i[%NU?-R2;hmB fmi UAȬP f/[H'.fu{HIvdQ-mkt[{F_@c Hը r3-q:AbCm'['`xja#bQY hfY?yIeer[xT:էD֯= ќ[/qԳ2ԆxxwQX`#^ 4eB U-b%En#V Z`l|b#''``9D4eHhmx>c{1}acf)c(M`0N@~YyVH9Wɟ3+`i`ãsJGnK Q7=8+ĈPYB͐OR/tFgF4C^ E6#Cw1M|d=X3>_pb0 #XjC{֯jz1ĩ6~ Zџ/Mpi+#CάrPs,U9nARbpl,4B#{&h_ 6w]z88#%+C,>_4p8E^7Zp6޽mUzLP =1-4'_j#('eU) %bPI&&I ]t S(^R0}xQ QY dž[,LSiLK.EWz7Xu JC-fK*D&z(4%6P ӳe$_3iI0 5nmm&IA 2P@ɞC IgX2[LQdI-GNaCv 2ܯ?A*7 M+F0b pqVhdѴ!{L7Ѵ76JfVs$-L<2`CD Ld<127/fD̔IR}ΚRc`;SdmҰh9L 4Ɇ2!p7$[j]Dиpmj_Ϸm򴒽Haɕ}C8HcUkHՄ;!j_%’r9~(2C G"gmѯUk~ƺ5֚]UES lM{mlTF<`˓)0\= SF *c7=X8YOhA06m${'LD<"1/=K„ B2ob B2*G`zIEQjMwT# Tz GsUANUCV4Tf X*IRH+;VDѠ#,4_qBƈnT/anh{d&]VQzIE ~%weaM]~hM1=785Y'&Pgc CM&*k##td5 ]j"x|MGtVt/^KI!"#2CϨX ̥"* ç' k(l0(_,^+N~lrVZ>7Z^ؠÏ"35"3fWfyV+2O+w!Dp f$;˹ ֍HN Ʋ1MISeb Y d)J6s8Cr^c i.IZM\IK7iQ%FJ ,4NmOr jNݠ6@ԱdynL9~R\|23J|) 1HO˨U0Do6uV0($YMbnŨiO_h^=%?h)+vGב?O=RgA8XRL'$o,C "%Ũ)<4,lrhzĕ8[9wMemxm.H}<*Emݹ)8`c+vRȡJu)b8pө\j~޼>dtuߟTmӏfv9R/g86vEr&{"| `ee^eFG3K‹Y4e*[aYVFح[>|%x^e~(AqS'nrvqm j.Ra% ~\V^T%K9D\HI2CY:Cc#UZaKi@*j^3{]wE\F 8l,FFDhY/a93| ;(ahMGK'Yj]6lxJ8܆m@ɍbkim"$npHDB)%Ŗ/L%٤{cܙ9L5RY"ɕl=^.iXek!H%U8552Sq~aIaEȿQQ^/[d`2GϳG \$إJDt:ޗ49iO* QE"%P#iBz2EQ.m@KZ'=- Gt 1@p}CRR7F1 սR4PCCN>mM*^.a@fK*h`ye=SH?gͰsgfFk8 =Mp2pb{+ 5cYt7.6όGQƮ;v`8 LëtHG%#VMJ9ZPwc1YMi?jƔ]CΘ1/:cJXߪn)1]uN]m!wT6ٞ%g2++^Q.rw;a-okN:(a}#:cPcEJ.}Ƨ§~r~ 7HԽ|c^2vQ03YB'5:n?rC>".4(:Gʁui9,n*wMWOscM5ZuԆA?]cwsGԓ2'@w|-]9 BuIu?EU)SBr{r40Db8Q;J#fn6tIY~nȵ,3n8qdfI[&UпS#_:E6glx `jOC PAѤ*f96x\ e'4!(t>s3 qgdylجϏG)AB/7&m [ga+<F:ۦKs3fiԵȟ-FsLT"&\aYNbY5=./q&&= [bIQ5JzxU:Ju(tQsz^$J&aM|BL8D=Qg1Jey,Ss݌w^/6^YȒ=jS 3[pe d g(@]+炾8'+%^x<Ǥ2wYk[IjwyWU|O~}LҢIDœ#Z҈ {* [5 :XJ?sp B-T݁|=*9tKh@K͜q;3}řysh6;e/DNn Vm+ъV7Đh!hxԮ"}jV* T"0naJږ|LƀeȖ898Xd4Ѷ=fzn5\iOP $I C!_6 2i#MOCRIř+nB 㷖Y|ed^M56ɍ1hTęN$q(Ė`ze:XXf&mAo/MOzpTv( ^IІà8JqTPߡ4= CIfA@>vqc7pk n J:e MO׫ 8Ws=CQ?hW%%#da U0@}6Y~\tF0R,rv!_hÐ3MO_,6i+e _aIX+UѨ04WuFs9`G`ߏ-y]9[Umz~, QucKMcx=7ZZbAN> ax:H+ CYDDmɘ J s-uqߣoi(΀R*DvAT ^{8C﯐De?$RN}ua!C_K"-_|?/Bv}d4%dSņ!9ށ9;!k Cr&.GH5++#3WJz-=wԻcf6JcʨV!\;(QG=꾣]W v{HH-9'TH+,hf@4v;g==v 6A',. oBZZF/3r~;0Pi%d0+jC \Od p(HIac[z3\A qA-`kMwQ="y.Gr F+ 'ڃ/PW6XV&|c_T[vczE3/r9rF e#+TaY^ы᫲  Mj%#oI[4䮭O:_:W/z{02|1`+=z_&`8 4b@"7{.&-O=p~:OK` ?+Gt_氂=cۖ} i( {&#"./(ЯދF%ԟc3̃x0x/$-B  :b@j>ʫ?Xڋu;ˁxTO9'A1IVw"!ls,ȵ*vݾ(W1K(=8Z%͒\o`M[/=ko0rz J?˹K%/nGXZ:C!;ehzwA-C*) gtk|2nJc{`>#aQȽ$MShBQ>JH=*$TGzߋ[APSTosb^%e&mJ$Uug~c½85sǡS]Y8 $wEbQXM/P} snk9&i9);*Qq4+NqNQ8xYD(_y,vR[ڑ :j6\Hj/}vog>+|PBXtaj,qr 5+eaQpubwx ֧\SrУ|s=8nxX@TBމ{DE50ào qִ>AI9eᜟE<[9=MvwduhEcJO ;-ˣzXehJCGڨxeTN%'ǁM6Im8w+b"cIx@D+nͥ`栌ݯL $<AR7Mjj:QNX'=ٿޢ@(HgG߫VUU#Rʕv⩺vR*>/ -3ȡqԃw\}庋^TȕU:_95HD;J{]yeOŅ89<Xq$:Œ{#^4 @v CӒ*|.Hp3 ~ nmxLx3ɇ n?")rʯJӱع2@WNT"ǜ0Q.EŸ %sׄ(Nç<ι*J rڡey#Ic9H5FA0v+^L%|/; (H H6QY)e6ȵv[n~Pgs }ZNjtg,$ ?<3bHyɻ.xine-lib-1.2/misc/fonts/sans-32.xinefont.gz0000644000175000017500000007454414647725152016347 0ustar memew4Mr8Yվw_I+@ /2 NB' 3p8 ywY==3O >>aks}I˺}Ηl_2|YKˢ_36`}𱇯xc{Gdڰ/XKg++f e;}ǯG[2#݆ ʓ@Vyb9qkJ[8-ֶw7wTfmH;EOFHF<:}":,DWP6G" 1'AoʩAv~3_pN^KXޞFϼjښ̿]i{9puv :Iƶ&lVViEvZvŞ2[\u#gmoȔJB?~+i4mML3˺> *3(ΗrlĿ俟Ͻk1Y-w^w ^H#2}҃T:Xv(φMGg?*yR&|_UE #o;ϰIlNXgi7o>f"(yzUλ9@kS+²NgQaq6-S O1ò:Er{`'H^3(mS%0LVBV&LɄwx-$`*%F7dMjV_1hqA8T <#ԫ 4Z^(쁐(!rA-eځMU;;1sl,$LwHh'hm_3NL9d+u…zx2BJK$M/ qPy ؂oaLKw <*f_@(qidIݎ,9faĢ*h?YZ$45V7ީ%m~5DfvqF=~T3'P002hO12bF)OOU~i[z| T0h&^(̚)qї<%}7ueְƬG3/I%G9hfKnCa 5K 2E^44[ZpҢ3.=:ϓ V *ZPl@d.8X^Xs~s^HL~/vvvb ZT~n@?QwƧL;n}ͫuc>=ea Kȴ&d4LYy/& of8! Xx9]ˋ8(wՙQ|ud~=G\:%Bv^Lg%]`TApfII{$ ḭQb%`e| ,{Hs/e4{u5 S݁̀y4EX`+7ՠwt.^%ȗW%KpR[{|c೸AóNM[}{6 )Ojߺa+%Y=Qi7@3N>f3kDI^ܥQ裌"yO/'JO$;J.3,Af5C+m+0t{#bkM9AGeӾ37{M,M87NkvZ b9J0<82UYz>8"&LG!|K}E\|0m ceG1,g+G'>4ajrgNԃs\Uz0F ~7S5/v:dhN}"JC)aV&{FIh5I{/ V uazI^wĝ|uxs9pqSέ+Gv7_5RupHu灵Cm?qه=Dު HU$|cY*K_fԈ,fSB)Kl%Kv-4W{pc,/8c>caeݠ`̳~kdD*&\־󦷏g>+eZR>\H69$ "8Rkf#DC;b=:?>_3Fq;s iga kw͝w>O8 Oimӱ] ^@jI_v1y#uDX[|uv GGRa\n۹~'n( k.6áY._}t8o }AT3z ~NnD ȔR`].',FwGW(n.mMH~>3p@,վFHd Pu׺eVhW݄"s6.w-zvYry7|܃^mM=CeYVR"- | >}QZ=ʭÙj#5ܵwne^?_lm`<0wqiW@]iqğw9i8;5Vz| #NR<u1?k^N>vz4 dwxu;᜴hvs.,.Pi CRg3FϪ Z)Yf|Uo.#6@oQy72/^G3Zs KKuf!`ٛߓAA $_{C::>@T m0T{p8 lpzu_y{zw k“Ḃ }5}#<'&M}`<)~kG9)UvW~0Q]^3r_>씟oHc퓙\:}4}r.ߌl\w,^|<_l gp^~.!Z?aDft{CŌr}h:ĞbMGOԦCbzPUy9?-:ov)0װ7UnquG]n۽5ףZ')m;'X"';/\-Rg#is'RL7Zx=W V ' o?7p|;l\fL&TS3i߳1)ifG XG`O\u4Y/\/.s1b0͜޸z>sia.%rDe}D@k\aTŬ[X P\itg&\Z>ˢM"i K>'nHNXlj,Щ``rTvh {Haǯ߽ o.{IP!`]}]vuփ4WP39y.d'#"NUA ! LW5JiQo:Q+Ca(:K!{!`N_/UjˆIB%@Pw2TފmsODmЉ|| js 2i:Ɇo'D&9tӸ_X4 0M_~C@.Ryt^؋¼wHwQ&Z?BAǛAyl%UE3^P+GfUZR\M7K: R%X:5q;"5Xp>~2@z܍MGRшXqz65_ŗ6'rZo &97ߨq(UiT7rncbm}hR" \voZ㜂#J'tRcD|IMȃ |? ఠbzI#kaH^G.e7 =ʇ@N =r NRL<ÑDpQF#1:&>to.*21R Dr<;eXYPaib%=UoJ/ʄ` ~so{Rglyqhto u[`rgBt # 85/Zy)׫rNG\,pF:ѿr:SH"*-N($^՝rQ:>]F#iD:P$ 0 7ݘjK#|&bbˀȈ04ꬮ^k/I!1qFŎ;K+$WO ju7'!wMq;NA̳Lٲ'}쎖p&=Ç_ ӫ &Ɲ%K՞~׾{UkB1%@)KFYH(UTx9΢ڗqQW:in9efSLqU 1Z_rإ~3kDWa'6ioŞHD(NW@Uo=ܭEau,O2t͌bE &@ gWZ"NP<_,Z괎49 {[7Ͻ#"4aSJtɒ7=5| o57U#Nц FJقB.Xw+\>\jRZfPs4b uE24xnZ\<}+撌?xEP@x%Ӥ9`eVV ZX$WU-e\s.,@0..Ns;\TI OJ`Xkod;EUC҉KHH II"~ocz lȩѿEZbªz&x9(Z,`^0ksVjeJ ܺ%m\QGhqz촉h.C;nGk\>9C#8pgAz<^l: ZR-A湴 p=tm.l Ut7Kuj^Z#ݿ xQ)Jzx K$nȒ!Dj J⥑Ydc!0mk{nNVh&P2x <$NjjNIy| bf_$i$5{L&8U}c,DHNzN틻'fX'!>X օ9H${6%'{7K/܀n6b 3-IZ,ZRQJSz@tkfurT&y8D<ޖU^sOFlV[mG6'nw7O1. 5h&ޡw+Q!k,1;"ǽnn.bԛ gX2UVBDd)9UDX Qe&0Dv7{ZJ`RDNh%$B%f FUWք?e<[xKG _Me4g.?(т_IVRstgzW=|B[rʩef1:75'9[mIA`)ĽXVs";pTF.#1_|WkƆ#zi}бB7R"F"@x L=O*&;^$%$D՜TLl`,X#P(G#,zUh1=\5 07A65˽Z~(9ӱrQT(I2fӓOP?׷.:{1%Ea?E=>XO4!|Z8X<Y0e3i- ɔ㤏C\P?aPC3hM/Yu5\~/┬7a:UHw\'-5IOI{I%i:3$E,_E ,g79[uSYZ69KW1o_Z^S_rZB]!Dz7}uK7&yu@\ 6姵N@#`FZX:pDV - -ŗZh؏ZFy' -m#S>{Ցh),ܸyt g1蝮.Ozޝ(jCc<:`եytxA؄Zjcu#upnt*?dFXz^YPgZOi#/J9Pro z3UAD ls ~ksrSrnCiyn/ּPp׉2*QPoW)3-&`Y,`LKAˑf1/h{;/Z8vgp&`3T"뾔͗r.r\Wnk#U\:u~fh@k7mjJHydUl QKlZ#tk$7y #[Ą< J8tF :;塻PY冚RaX :鹡JnCC+eݶ_mܵ@;x{ຨ>*5M62hfWDrhғA'6jQw yGC'TdQ)j6{YRڶy컫eU)&2Nʑ㩅 s7l­sslYђ 2ne2Iy6lhW@K \6Qֺs2);=&;J 69PqFr[n!I{>vba4*u ƼbA.Yota!ݘK1#͔ 1@Q'\&`&C&j6a݅YL#eAJnX3X ;Ks,폾3fU "#4{*jc:>l@BIc DJ=r~KvNܢ/PxTCYP(LoV$QQVSKȔ+ɖ6(OyAlaJfyFyAk \fZafCm\uq`˄JVyZ/ ,n@5ΉtI&ܭ~3ߑ/D2٢ᳯC/bj0@Pf 5#կʔy(Zz&dJ*{򣘊vbK\JMx2d.=EӏÊT, _;hY=>P쿉wilQm;mgf)oBt2rY$`;R'dnG>B JW.NHB9QU,N e Y  3nC6飡f ((s;]>XAw?/Wԁ&y-5JO%@k!Kl ywe6nHx”>syXJܪIQWbcΐJO8ҳaOMM5咵g I?5]=j>-z6%~N0Uѿ?>Lԣ|rbt=;hvmIs^–u<x&'- ǹ/XYGܷ}K.kD7)$A2VgrOp>O (ql[1*YiljlMK@5Q*AR}}_FEM R^گW錁Qi cj)t{yz~q`1W>-S.cn1vPOGf{jB6|EL1& <@=oHŽ-_&yU ң1s;ˍADjCJh=RLMIݒW\AR4z_P1pTs.u)}Ik%EASduzkzvqYgV[r-;(Te4Ò&;N4ԩ9bgΜkiY$GV=ț&Y[]jQ{03DƏo9V1]wlʅ"7ˆF#.csƹ|SdL3|jDY-Ww-5XҮW3CvPbϧاcmG:t^>~rKȅ0K:vz)_u.y`)H$]Km;WxglKޱk6 W4FpGwYD~&+=>3* neA3DQ_Txf͸#Y;_+ gwTw?|G/eˏT<5@JtWJ43~rOm9/2xFH_@.*\<~҄*Zvp DEe+VCRp̟/%^k_`6yk Ϗȿ|: 7݄V5+:Hn+^+Ċt2]@56?t31zq LV3N}7 eSRǪ)$-r6wq|(pq]]a,!-B,K7ߺf5W]uNt5V$tFH=C޿k_+oClmhN Lc*dq ͚u;$w8m*q΍ž~zN 󤥮nHB|V+3h)CS9h)(}l=,g8#ઝ2yà5OՀv8)^gF}APKQ,Yt= 7چCjƎIs(|E2-9h Ǥr$^JҖ;' ђaB?l>{Ak{ghg߳AxW]=ݸa@MD'uVC2!U㾿uŎ=*yf®O kcoUG"}=c:\qf4u?ީojRZo1?C܃`CGkz[xjןR8&{|ÓVZ jA"2][X=s\0ׅGga lE(H60~"2~y:e`VϜs$Ab-\Fo6Bq1gYwo2/FEɦP!!n鍣KC5R)IPrE۹cR.;Z'KGCۥ#4[|-T;ݽt~ ] ׺jphbQhUz渚:n_Y}V98K^*{6\oZlGqCF:}pE.a5so3vN\fZ6e-Os`-uw.jRyYTSQJ lwSId`m]Hk.u|ĤgJ+N'x[]' ~FP|`ysOmq ݴ,ӏZuI,>cfn=1B[q$J_a5莙 `f/:9f"x*t"x[,mr %˭Tiy;]3#पbUAтL!RTacmi4ӹIfGsCbQ|vpTc9fND fni0sہ2YژS:4':9n8+ $g iz̊f̱C3{9`l0p$fvRrҷVs]7(g|rlGR d(ٜ,!z{Kɿgk9?a0}?- eh<;bbYfPf|Tmb$66;M ͞,1c;# gZ早%ifYV3$..wi|glV8*Aj-Xy *9q-re;@b*m>lp ͸F=nlٺ՛^kl2Ejn?N~K]Us쨚~E~R+ȉRR:'Iqq?)C`ule:~Ms˱= z|=aW)gSmV"<7ꘙU3Ff_],”nw̼e/o3/rMiKO;QgCGXռ U3o3kczwyۘ_K6'62w,GdNH$ I"0Pw 7y ; G"@*NAwb&Zi<3{m1j e HLLǗckݳrBmS}cob&؊\4:C ̣3NV4+A6,RC;1EQCMܲ5L WT"9s*-'J>U#WŮ*0۟5ʐY.NtPwLۦb_n4)? rvgt`} iYlNXw祑9e99Njc؋|U2NIB^ X<,V,oPF X5@0 ?6h1;]nXL/'vD<Н )HbyV_D+ѲCuyTPQ].@uu_ەQyKnO^la7W8VĐZG|GWnq%X4j/=8cs~kVuQQ8.w=]y/ּSׇ덠nҵpCv!w}}=N3?Ʀ 9dmv[siFo6? ((%̃|qsN^UryϤzq6[l!;@N&jRȪN0`5kJa\)F~h~Ơz6,8X^-Mc˜OystACCg?n+C?PDm>\[u[Cߛ[eQ| 녎5t5/BKՠ."jd[,,pBHBՊ.8?np;>~_MLhV&vq5bh*nMd,O+fR0[}+o3}Zo *fąY~:n n\ꬴ$q;z^KK>q;ݾ@M@ُR݌G Mէ`5vOVs܄Ohw%tuBd$<QL )"h@.>:ʛ[KX&6Um4XdD zJuEMO* Y~WEdB`9LU:HĦ\@exoDZiK;O0*K(UlUc8%@m|!z` .H:WVJX6s}T͒^D);8WB_hV.Ҋkԏgѱy<u$R=^dq; 13>3>3<`oC-"O0 +O-}s;6 hiJF旅OmGc't,ZQRY jyWD_zg 2I"|]9䂼sR7! r%ϰuұ:3F}zrn(-p;]fҹMh+#.TЏ#qشyvsH.6٪cO>혅ZOJkԔ){ŧd* qy!5R&21)#&q4BPQ%2g>tD|1χk>.WK7Fƿ;Ƶ:v4WQJBy*f!mϫ(4|`])Q7E j{ueq+?af UE~C͊v GXRqp4{,mǜ0W)gkWЭyVCV>hkMcEԵzGX:bƋ!F.^vLR sB;1Ѡl(r(UMR5wݺ F9@: gNG7 HPP[q=*۸&׬Rq̓W1hMM8} qX%Z/D:NB y+ wAXE/wbB8BY<(l2u?Sc!g7|gGDfޚB%3B8UڑL4ϕN^Qbq2vIѣ9E^͹3ILUGBUaKLp"(Sixmm- ]ٍ1LQ": ҆&Էl&6TFY<] AƔy 7aLvs7˩eN%p*[=T4宸kp MӍ.9Le[%v} yD'a 9ƈMpy!I]~ӜMsea\Ba sbTHbv(,# "6K. Tyݼ--JOj0V]B7.4ۘXQį,6.#/*]V>oRQ /iW5 m'9r|͢Y j46j"VACS Rԁ5a E ),Þ?h@UY0yhcع_tx+%ԞmB\CQQfo}Y4Fa\zfqA`=9%;ӊo ˦ 2ʀ1 r],^XErS}U 8'Ju r[:|P#^\<<gO.cq&fV"F\ oǩon(`e~v t;C 4Zh@L*{U\ݷC7Vρc<6IKo;Ʃ;ǫVhiQP)6E|dkyGn]g2y`ٳVŮ+CCw\\X@+.J5;ٚWQV(MR6줐Tb}AO6jxХNw;4[b4XT%v!E^u;_&ʪ=܏UR8|QH_n .a){Xċ4Lo G˛VU.;2#7eJ9 |iS"HBwu r phn%`zioR7k{DlU}i0{ϥ`KE&(;pjw <ɖ{/`ɝ0pO[a L݆f(MXl,v͸{^o~6ζ  )?k JaB$-\o$:J' `Q3a-jH6Wx yq<3 W ?c~3s捩KЛS ͩf;veYu:ys}[Ig^a귚 D2 \>eo[N:Kr̍ c0)`d0ŗMb3#TjLRx" l.Mj7-@S,绌#e,:S,~pd0K9d)ȨRk3R G6~-$3}- 9O(__>ofq;,92Ur.GEp6g}N [b5|S;d ~Jެn:]q#S(7 S^2g{GP"ľҾ %PLH5K󤳴f% @Il@Yh 6 %oD?HkPrhߛ(ӱhyy@sv(Ld`673w;Х>J:ڢU!5aA]pEܷbyCuD)J=>!'D%iPR)Tpe(4*J$s\˺3ey`e$<xm@͉6ČH._ vv^PǠ\â(^ 3~g rj&[AS UI#1b [~-eĭd8=]tRK Rl[h} Eېkhm].g S5yY>n3Emژv VQnu ' ,G S=,`Be }^.]$stc.àneާ ܩ5t'3917x +a^GKXSQA{ %jn SpWQ e!jqT%h#ݨ5PdHܺnq:Q'!wMq5$3X'Iɤcu,7ho5vkv;NLgDž B>q-'+Z U͠67 pnln| z19>7t5~~4ښ pB9bP+9ut8տ-'nhR_QW%q#Nw5MQk.s$ѶqUG\cq[UHMTW%Pj?+e>Kjm@o%IoGT;YF=jzTO\?>όx\y3 8bETN/"%B|@~^ǩ6^3/ȃ4SVv:)?G8 CGE~SChx `4ϲbǻY$F yΔF 7y"Ld/ȩ;?>۫8G U72 ɮ"KNwc"dF8Mc?[fb[Cj5Krk\쎹fuЌy;Y0:ChvnS_)#?cw׵YQgwr.6`O!U{v砬M%Bu$NSY`wZլGGLkK2C=,{$Rtztk.Ǧם]¥){m.|/ؖ=:w( , 䘀>35{26-^#T1B k],$V4(u8lKʪ 1Bj4jR톴ZސO+]!+_۠yvowd( O!ADn>G9d4AK}>*1]KңGk4y4ΣyE>aԄ/! \ yT,y<=|rކ)\q8㇪ GIAV}F]xKJӣQi7?Ԟ0BI$3?e%ءV bd$+$sIs؈j )VVnE)* g5~m`˶Hۭɵ zV\_Dg .ěHh/Cɲ`"k!;rQ/}xW[miұ)KW ,ן;GV7D>p^҄g"``zw]a9R[8Tv9N>mPNn?8LNq%ë&I] ~V- ΢L4{fH *\58 SЀgx6(^<(Dd^/GEXfb♈]܄}C"UϜMI[_ߕc'0-<~&fۺoΧdܵ[~֑h^4I37P lS`u76fWM`31ejx'ZˁBW;aZ+vwsִ2ipxnzHkT~C⚖8uf{P{g Lpv؍:e:w9yuG?G7R^Pشza;,LνW: j>x_s/㧀qIy8̹X=7\%}Rb]v:U4vTL{v/q}l; jy~ӿTf^w_Щ}߀NmooTqODlD&Zz oy喝ǽZIzq:@C)W 7vģZ~Ax 9cw̝yj1tqSAN4u |*qo,+iQOtQnáw SG9}\z>G ;YW%LoH΁(f.a)}/ܭyޤҭ֧fY%heɵ8RqIjK[4٦C_Tgטy$0l)j|Sfm$[5ʖl7-5i yEKI[OeIU-(!: t`!5vh%äa*k|SESDgOśJAdUHAdI2z狦?+P.-o59g-CPIߎ+b{EOxTXBG3; Jr>d+۠c8AWS=}sZ#QdiM:82#UuUF}e:8 zt;7 qh:آQgnGнҏN;ᔖᔖA9_ lSL 5O׶kݑGW< Y,QGR I=P:E~u>q>uUgoBwgpiQSOC՞(=6;wu ;Q%ㅇkWO0zcWƯoUZ+>>EϽ}:}N_~>+c#\շRCW G+?(ESOҙ6׭m֧򓵌G퓙\:}4}rڻ!H朞i U'|Ս/'Mu~WS.zv+9}>~&wG$^\+![|Et/8F>I>`~{BOD.q@sh +[^ogt=xۓ4WD56vNM&A =*CRsl| l/Z2$䃹># |kU5^8([5?gE}ᦹO{zzVjC{ï}޿m,5iOti̬~9{/Z܂.J|8-K"i߉4GG$,4L,̓/k_i$~~c2?mP/q ]t-VkvvgA5>~|%ZHI4ܣUZ[ӵFzb=cԧ'cĿql\:We<%nY!lj%') 7SYnj)i b7<<ϛ'kWn_Ԏnah4-`U}/>>|Hߜy׆ʽ@HħD(2k?H ;OhFtbN}bQHSQi8cJDɼrdzw󰒂,TKBdZdQ$""wΧX}m*{Gvxt#Q@[H!IGV]J:ٓ#h|}G/l>gܩZs)+V&cs.@ UwbU=]]_]9'˨l nݓGsHSе~ꯧ/t nOwx[@w*͞n6`HDžnT!+`p" $5g5U7'/袪u'ң0<\۫_=~Z&wS, CWܯx+LE$`W`W3^q=r] ֧3;8`ܯ_qtG9 pVm;fҶ G9"@ߜvY'XLNg8H^53}N-ue~F1[+pUʪWɚ{މ5}|r ЦsTʰtb{J=_~S^`wz OG.2Qf55yM  :윑B;"KyX OGHP K5t3_n_+^uޫyϼzI:v'#p4Z Tq\e˨@ΫjK[e$8 9$jMӢ>'RD0Ϯp~l$6RPcASra`f=j/>}<^7;nZwpÄ?v kxeAvRȊFa$փ"xJG{J OА4a'cҙE݁gZ^so"EuWĎFKR\ <ɉyR ,iӤ- ֭o{ZP b{v?[yo:Lͧ~@Y JZTg??~kx6UM~>SjUPbE>;L TI6v`X#!1U uj{0. a/Z+3~;{* ` bR ~*H]PhQIfJƓZ)ݤQzFyX2%i\|'Zܝ;T 4.ȴEP]Hug 8$B9&\g;Blo]qح )$;O :9 ;ʽVQI@\"LM+MXwhnƺCxMIAK6j"sir7S2vի~ufHHf7F'{3j;:8PG‰Vڊkl5IH%4,jJ^1L~S݂2݊1ލqҧk$RHA8 ~u2sZW{> uS!Hv+FZ,Xf+_ij/L BnY͇v>?Ns%yVܶSBv5HG\Dwĵ 9e9`XWc!틫6Pi|Jf/d*"b?0Lk){ vΎ~RFX*!9P]NC*gmч9Za ѡNPB.j&k#2ze" Bd g=/e&.+TC )e!h(됸r$IE/Bw*lZ=l؝=y&]@Z~lfVP 3(<4\^(;_8Nr^R\Z)RnEX?> +hU  ZE;@IQ̩i,>;RHR1MbPPD>HKd5R6 #jeŎyUt̓JA ^P3+[AHt e̢FWsk̽{WV\c U m qq UVa)|6*OfS+GI0*uߚ7$D̬6 xDQ&~ۯ$ʸy)WOc5o]%ݻ 37g6Ȇ ?|B]w-&L!$ rW̒RT`]9p§T;=s9eWm[.lov^פ:/yۯ{v)a䎽+W]ќ?NwUrG ZlyFB#7:/v/g*IʞC?uU]?K>~regj;b! \C:Ź{=]^=T)a Gl2w['HlvO-S%SKA;Z.{~,~K7"f\^=VCi]8cy,b33*0(l__TwFx+e׭f_y %Ǒ >}šW,=|goNnMáܻ Sܱ@Gq瘏Oxw^vo)e&*R'Ag)S P|';73;w0Gğech\Kh"mn:v+3z;ջ\kZ = @+tlSUœ蹍G*e'C&!t ?C`Wbtfm,:ӡFK}~w-5SAPtՄ'*i s/x]Nsq< =򜣿S?T8XD _,b/:/+~q  _zq{{H_,ё>}[Hg—׆٧ؽL G&kFR{Ɣ+?T_,Aߌ^3(c}ޣ;NGN+:bsaP TZbBa4NXH|VoUV}l14d8v#ҁRf6G-0|wVp?8+܃taFs445:\! bH%A1Mk39oxU W/#&['xs%#܀/=z٩;O:_̳v]"Y$kl%ո8leHKW3L7.\fr@+b%x9eѳfJ1M3UWd *}W J^FWiy*x𩷇MuK|zVs`P |veI.pޜ6{ۧK7ksA;>L,yG.`" SwA,#,K5, E:xine-lib-1.2/misc/fonts/cetus-16.xinefont.gz0000644000175000017500000001466114647725152016522 0ustar meme],qD؎afffffaNpRLffp_wKpw/ّZj5wﳞ=gw g^{݋^l7=G zmmkoMA^Zr4|tDЃ#^~"PZHsfm4[+:ZMڜ999jkkfk32K,pO%OMv,ey.2;3Gy5:Ov3t8sAKy 1[~ dځff!DR>V 7p +5v4ҙYqG&Ы8bi8I{'  E'v{2__>']Dct0I)3ި'#0Q-Ţ1TDhI7(ӛ"NĪ% ^I^`n9LFHմ/۴]rO;D?-+*b)l,DwN!)#eŅ1k_23>837Od87jq\N CfcTj^7،-wM,HmĜJFi-$Ԙș"TaR bny%x0E`1*,ɺ`b졼IıþX\7ڸ,u b!M!A# ylRaN:KpD_ 4*'L7*#IͤP.4W|of;Cpg_oqlF[l$̲0M[SI[gVvk<17`gt<"10jn"w3 \Yf[C u7PB UGn:ɱ'3p mrvz) $"7|P[ґvCEN7v/ Ě8 ^lI) ={kC1NUu$\)GзF:i\UWr}j[+$KkXZ +=c/x]b@Omz+[1rbL~N܅D`j D/)x0]o&H"T na@ @uO`mjC]Szk10>)_c R8wkXGpCؾJ<IdxYQj`ȿ QS/%|s{NoŦ9ڌzNy%ýevL21RLlbo[luOտod?|Kri퐥qrøG,[ T0HǾv73]|Idl*N|B$-ddI,X_41k(} lĝWlDD8&s`~kNb =߉(motnO;ѽ]ދ7w;'@^Վ!am/r_y1 L%UcұlqUwlG!O7!2/t1pyJˠ+P3[7S &\l-LhzH \ps2YR;{iard8хa .l{,u:gM3':j0̯2}ҜQt:Bx6-3D<3m_ v<ج"*Oߠ6t UFɳrS'] ~5G44J+XǗ V‥ ڬa̷ְlDsɳ-RTcQ"gqK*qF#Z,gR6?͏nk<Bo ;Vd>VIea%-*^* Dp-,4gⴑ l#-fو|X 8D?ߊ3.>e{bsZi6FљC/,K,ےEhK2L23}-fffBU fL;3Z?]tT%EFFSM?~OO?ӯ1hРA /|~~~JkѼn7K[Jk+3f&~gТu; |`wg/ǣ.Ff3I> V G"AxaPì;A\cxމ=yɨ\ލ\ojѷ4'jqc7[ )Mk^cf-XWC3mqAX͡z{IhIOOAJq@R X- Z[ő~Ző׍j˱35h"Vkbw~TSks*;۹ !,:d٩!r;Sm`V;y9r,ҳ3u3~`E7}z^.; 4X]Oo*{p܈c~Vv?3aqR_JyLG^gNvHCl8DR`s܍fuu@W1±~9q| ?ٹ) :K . @:FivbEy8=ɬ@Xo.KO<3W7aMhmrK CЪYٻhY`[,ҘisڋgjOk\8Kl&&ωEګg}pwO\B0xW:t ҞceȦ.0`q@z뼙`9P4u-Mi#Xb<9q]> 䤦m.95FjY\Gc?bvY5gdlN)=CeiNu::$g+X{h5q5=w6Գ+yvfGr!aj;-/Z.667#Uh%E}h W/F}4cQi7ͥ]a:qo[k& \1'V2(PlNmtB4G.i.5_G\5u8g-hrr${BGݶ!n'{MU00w){^p3r'xtKQze58(c3£[i#Όd(w`xs/=v1cƲ5vxBɰl lMan,[GiQs6ՠAxTe"k=ԤATxΠǂj +qٲ9 l2XȺ)-Uu6G64v ]R5X/Gcg_* \S,0=<5hPi+O^yy{hjhkr}a[:|^l(j}&MEL3-׉/Mڝ#_7q3te)s1Wqp*Ž9nNݮMIjDgx=TRwRFq沉{!!=Jϫ􋇚3rg6H&ZϲR[au-JbrwX !h qniuc6m)8K9ݎnhY11JU_9[C?lxybkW< *fLAܴV1xE #Nvi/N>2젥3 >kQlX™˰ /ʤĽ@H1MTTzV2n euӒ9#;XC}C~,,̥Wdp+C}w N!Tr\(ܻL[f ||^ۏkuYzc ^3 HN% 9OdaW nU{WV~!p>ܯtCkݧ+^sC/b4amO}tS0o !_8Y@/ǀSJ(t˿Sx;g!wg@/\'X/ Bw<i:27DvISRz\*'MZ8GܳYi m o4;[Lt3VFaCǒ`i[J.iKѷ[ݒjQY`P'U,eQ3|˄,5l=$pJq)9yyNzP<=5Rܓ.sl^9nc碣p\T2EǼ=ĦO;;QheiРAzcHRD/wui/'^Gul_] E^!$nP(~:4{7c.P(24rv1>+T!eW~OcGŠACZB҄%+o63`w?v?~ߑ6eРA=3U׎x=وT̙S48OR(b9ɔ;+r4Oi tIS_=5j_A^ؽR/mD0'"pr$k0+K^Ωzey#9jz Sofvlx!va'J'jF@vmy"(\|.PT7f5-!'BK,bKBP mx.)x.pE}cs͜!K[?kZ͗6fٍMh:#d۸Vt2wí,xL[7ǰcPYDYev//˞F!4Ns'P.0GʫϕA@)?j1)R=Ec 'N:XqZ⒩vgd~0kP@ 1>+TV1/懏U .vs0 {,Ǒl_Bzh {lu= lBOpw0 sCŕR+s2K MRql72@ƛ%\;LD}S"lyEjsiܕfwT8n&;&%WQyFEaL& P9<776ZWr禇Hqp"ʶ3G̣Yc=I CרKcԎR2GTrkd(6+:"*iFۮi"dGTR@4U[' ، 611Sgtq)c8g{}ck4s&a"՞߫tɯ[aZõ9v87۴놚IߝQN"wE=)MKkVk/j曱dk'{{`\h7LԈݏs7 D*$%y28JDWr78'1w[f&Y40*O\#E 5q]U'Ft1ibPp'+ñ$*ι8 yy񀮢$^'f\qVs) 1=p$.Om"ݦkVct|߼pl#]0Tݭ\%r:XIRhSb3VTlhfZ~LIOwPB遗hϣ"]뇚4hл(d Y>BV9?J\eqAjojҠAAC!̟:`Lwow{›305!Gt[F7K͍UPhI}snZysG!a1{C&ydtp `c̾(UN@|'7Ak 5\6ƼO.5ʱ#Fnɣ \t.mNXsGxc:4O1Jʕr|NfS)C5:;Y$]US e7j?bh?}A%>~ߙ~O?;Lt֝ɃeoZ/pE 2w ZL=LظЌ䞰JnHG[nh#4?s;$Դ%\\/]ƚC<,QFqL^R}mض2g)+9B %/iD\G^X"|@vF Y7 o8@`׌~P`X>bF$X,:ΰvY|/HY.I'Nv fUc/0ldal298dr7[ bLXI, TJN rb.b6ЭU*JF ^UXF{Ee7m:@܊DMYsVZ%i[Gޱl t^n o'cw_ZY18Q7IaIzH0Z*DЁ2"[`o.]3a5xO wؙT)/,kld ʮ_Ds)1ͬ9]T}UoM8Q*{7 Mҿ:M9*:cC=Cw9됷e7{d~Wlbk⁝M 铙3%L3/vJD@o]p\`Ht8uB vկR_:߄Pz,o=wO#.ڮwv&pęN 5 lK}4 *['O ӝ0:MѰ̻(Q7S$#[ `hQ`G9U\ČVaV (3 ;5ǖQ#F/<:P$'jxw#2V6jw* Aq9.0! f&{iq.C3 Y; 4#=;%U.nQwx'K~'=&=أl_ {S''YMuxW}S^-gq-R | 퇨E^ߺxe,sNhۥ5$q dE%{mz |{s!N`OO 6ր6 XlJ]ޖMYs^: 4tLYʴ8E;74;!䫛ݱ~<0  ;=ЩB,Hg^5'Uonb<70>vX؏̒),'Woaݚ.tC3 .I~~L'Y3hSmC0BHBIz<~0}7d m7kvc-x%^~=v@Ƨ8-g<$%}Z@q-㉇aڸQµ20)t xxΈnz ].\9s/pzw`Vv+\wgb.To }WTtzMb/?!-#Q)$b#HH(I}SU=R}q+RTWCn$/{_[C TֶcG%_&ŶEfY9_|m|l[Vrz7_ܒn [mUۚn)^6Y.jӱ;N}LJ0뺘٘%H 1͎j*Wf}5JsE,|фWdb/=:C`[U+±ʹM ;+mSʹM_|Gx֦GOxܕ? 6qlo3]`ЎrpE\_;!; X@3eZi˭- 5xo1,X IͱT-Qg~4vdL(Y8@d@cduYcYgEhx aQ1cdp52 ~љ M%SiZXB;=+vW TF|?A(ҩ*p @A= !Ӝ pwZPu4 ;YN#tO@ DB>AhRdkbƦr@) >Mϭw_ c]|h2CoI-y.vf 0JkB]Ke70U6t!$I|=7p2~e'2يvxEbeOLm)5ou 8JDCf}>dL٤ȕī k&JyF'Ksr^gl5լN2G#'[-l8I;cliPrAL/_LYE3!Z8 5'NiR:Зʰj>+=V\lB?WExH48V!yଇ87sNu!4I{cT!42|Tt~lEH= Z۲J H8B:Ut#~CŽ،ZM|^Z뎽qqZGQ3,G!@ȞX!zf[S'G𫍀zVR}TRӢ&Iri>&O#kyCk|[Vtmh4 RPi4ad dͼ?˝=_WP4<\uj!W]YZ`_՚:۪l;H 0ibGxEdž.z $*p6ųeՔwW0'imE;t9^"xwu~]ERr^48-*, C.˄)O<\ֻw8V:vCjrY|W0?Gh*G4As͑#լ#vkK#[k!UQ7MY6̀8 ՒuyuJ &ĜϓO` Y%ݳSYrtcV *ç/ ]fOkS@;û5eXH Mr0ڌc th?LeG^MQ xzn`}WѮy\sq*q9Zڽ';SIHݐN`>"hTJ33׊ gv̎6FVb,Ƨy#]Y$ \Oph- lV=lr3(")WF6ԋHE`Y5[nLWDbyMYVl]E=g1t1/7=H)g*Tp-'{-\R*K}zy,륞{XjD=T,f[2NTz?geQYx)V:,VnY C(̉3] S `5o*V?,0{fkTmk~ы &BȔO{"ynOinOɆQxΠLq2RP9lY-2}oĔv{J7,dd6ꢺpž AT'%k >)J;![Ԫun[֦unM[r U\?" 4BQ eN\w11w] n6@BcI $Qȟ|h ;ljaw"LA,Kt#H6*`[nĎ,Pʫp#WIy}ޟD h$y'=%UyVD;>/By_-^NfF7L 1|+:aek[+-XcOCTnP:Mi#Ӣ UǴ')_°IVI`Ӗd,0-IFA`ӎtw̆f tQ+2wA0} WH2#1!@<İTpop"NfCxDAEƎ@+!V{\$*m˧M91<KUWU:}ALћhb8РiKffZ(ۮx^j#& K Oz0v WӆfJ~= ݠ͍ŞN u}?ޠM< h 1zZD yѠ1:-82-8F@!rB ^2W'Z,4G5_:*#dr(]tä_-}_, ʴy?8mefKJ_ eKI/ʗٯz/ziZ4>t5KUYUB|JپbjWteB :VXmSأܟ~_ݟt:Fבb pӾtÍקz}ߣ&猍Vd0ՑfGI+T &D<oݤ.ޖ55Z&KQBlРZw lvYW[锐e%^i䴎bl'NNSI)"v7U[\LU<;Zρj]GX̬繊},|\L {/ t8^ <Zk8@cul 2 ϱvxc{)7o) 1yB`pLX9{uj fs=pqΫU79^Z̵Lpk!gsTt7S_5<%֮{.Ī=O&/?TD#wH_Ƥt\x )J"6 ;"xOJht_RT _ .E^ Ys/(G *dXh:c^1tW:jtT8`3s(C^ ࡽA&JMFf#Pu[1I*%Z D'Jm4kKYS)m]*;4{^[L22=eC~"e+XR(vF*<ZCM4(5IX^W4L{uǥA=1ʕ2F2L7#'ytyh@|%t[ rRp@uw$%))XܨnH%H .[m&FUޏ^MOA\}gc[,wu[%I|cgU=ϣB/7:E?{, :Qof殛jYg1`S8T}߳LOӵ7r48`It$y$$fKIq63@+O$]j+k_5Qom}HoBv}oQѩTt8&5" DNYw*= C6jm7z~ 4llxx'nؙ) C gЫ,K!^m. yBҵ6-MJ@rNHS"D'S 0#t55)[@ɧajgjsn:UjDnSZoЍz/{h-mXI:mFWu0wBKW؞/fAІ/G P⣳Ls+R,%eӦE>+j # ֫wǮ!ePE(~dS ^xV@kq L@2D+ f4/D)HE~gG-G=A߬9Gy>B/ס_zY - @B7!b.y$ЕiƕJOH^ t$J7Ub4Tb4ap։$WZ (E3$}2|ݼPquø4VE߸ SwF.1`dAw f6MJv ߂@nsZE-gܽJ7NZroj )ss@J:9|.BV{5z*lj$ c͑pz/& _X&;R"f+p}`*h߆NZZ%q8L54=_ Ag/HSdbh?_׼"*и":4Pʟ~nh?}PnQp*%䧥̚Cnɲ=e({Y&Ek G.TlG@CWle9 t][Av~cPؔiN ։AAWMPGC0Oܲi7۝̲~`Ў?ay2ߞPNH7lnZP  _5lM5Ȯt( < ;͜<Ļ5.r rq `2etN"݃3կImɜXo{k~$s} @#P(L_n)EjiOm)=K;(\dՑ9H&5^M>@}*a߫JAzjqӖlKR9z|$#]AIջf<T|hyΥ"ʔʬaiMm/ g)ZѿD%!Yyp1rKbիKi*3anb60є>*iٲJٻd]b?`MDzYj s Pسh ”~!,z6?8FʗFz)aG P7W/\v6'S&JK[̤փ';_3" hrD^E)J}٪Kn /S'!^di^͜e^ic[x˕VJqRo`*.Ui?Nu Jwx&TcsP{9 ?reOVZ{‹Suxue3`+VFzԽVJ(5L~ zoNVXP fOfFk5NY:VP)5Ϣw2Ud赘([ O&Gks4[YEcHьni{ G C%4#Wf$jyE aFnO.C855y7 &S*v/|+R`B\rF^{ߊe52eBLjb tb7z|4նBl5T HX ً>뀫eE,4KའU*eW\eQ4"_hq6И 6ИB6И6PɇYZYɎ0p%4lBLG+f4. o ^Ec=In 䪌H\mE󰜕2DC.֫5/0Ԥi(8&  VE[YFgIm*;SU=QY!#jV o# rp/s`PxS7;jy R1bݭOD^EUrËP;) Uo9~ؚ0*_Ѡ=YXI3k*oU82}Dt#XSJP D2Z$ ܝQ_.,\PXP5+L~nZXź:HJJk:(BV7qco DGVXxϊ4Fa:֕j|'H[M_UFX:DԻy;J$sʬ$$W7jd>O-lOnN"u\aj硿i idVCs}Pyh؇t6^j1|inq`*Qйy/Ky)}SY{ڊ w4{a߸ %K%.K`Y{K3,]~eYR˳OJ帄 yW YF -4˘!?مVSz i*DŽbIEn8smʹ}k_$P:Yl'P*M;bIAilo\ke}EBV UMP3V@[7x\cꟲQzT'@l'|bxҾY=&g#o͑PV1 sQU˫YT<J$ gРO$KV*G*e:[:[2~ :գ-q|O͔Z!ڬGFt@#ep#*;WgڼiV6qJE|X…W&ViRYl:0kgxyAQll\k7&4P#B~9wEٕ:U܂4KpM|u(/U&`z^_/E=48^=߭drztf)D#ԠAFc<45롩XMMzʊSD?tX ! ?L߮g퇰W8EY!ROPqpJ.Cg(X ˀ`3DgȐ8Teep]JԻ.b,'`yOScP gh ^CdRJ:8~`:-htޢ oҲ,3/ hJ%.qi4 7Vw^SL=`Q;t198I{Ksupv|%\_-s,8cUċwű@ax|(gv7SJu?WeY 1hܒc-W|:\_2 +.|o-| i<מ(G!#1,: |LЮ-)%Cmsax_DDцL7pܑej D~dBè170qW`cAM@4?= dlE4J8t:SW2H3x0@+1/M]Z=VgPJ[.YWv&ST} ې88Ygސ7ͬ; hqU'}s_6!@3i6k$]1+MvgP.4Y}&ֱ1V,.&kɕ'^-o1Do熚p$污z97b.FBЏ02fR=k>8#Aڶ˶Y41wƏ8[f_ oWSp;ccT+$ew꥿|襃}4͉<3M/S~ 6]&"5rUN*u +$Vq*,E= 4hРA?=##ȠA_[SнBp;5ળő ɼۺγuxKz2Z eYֶ!Rb3Mhk4{+0eB-CaGnKaB`x ̵qϘ6BqǻX`e /α1;< 2'u%SܐE>ӅoT%0mw{Lϝ8-pp# a#1>K;ߩӳ qcr'7LItnKN7sr&j- ya5<V sJSp8d}T"~Ll !>2ےhj,Z߽3MWԑ_Qc0>vRf'U$22o|gEfio}Y΍8ɿF>7.X)*@3;{DZ İ,Pﴑ@ݭZim^Y%G:'Yqj?6uyMcRrOH/ -^TLE7fkd9c"ֹɪmoi,}XFc"Iǹ3(>;cX>A}hF<όs/EVZr~gԥZ}] L kɿI1c~8^qܵWz+rS̪ g͠';j?jh?"١o kBd~U)`rE\8W t4TB`$ثC>V7"!_IR 3Q" Lh4Uo)adж&侚 Nc%ꌾ.o{}^t8Dl`D2yJ8Ă6nv(,4p qb85 IK>,#'$|74/0i{xG2B΁4ZrZY|B4[pHnwȰUpH.NU[(^7:x)^%+fR1g v信S:+nį__Xqj|Gx@'2jenuK,r*{w==wi 8&q5F٭Vx+MHkűw\:9B-ۊVJm 4KO> r<)~`Y꥿q_f}l 39=zq h4ek) ]`~\Yx9xH`K,AA=arm= 9i|Re%땔9I ?ß'%;~nzvR}-g/T]0Ci0 IbXFR6ޏyy(C] F55>em9ީB.olj[ 6zaY{a9]6Nt'>|/Ki Ds2H$X;JLkAGM+Yߴm7`7HE`vZ~9@+kM)cffv&}@OU~~}bL~xfYȓiYy*:\xB[^}6~A`IҘ ._77Di̞i3E `-y"h)֗ }&B+ Cm]vDy4;I wsįz:%/X)nS]^5+ F[W}ωk9\ؤrwUf9W+=,vlKe]O%7=dE}K$/ vqt)5?JpE6xwCyw.I*d[I|~4t3xH 'WYKc-'e,&\KB629N*:uҼg>Qe]g" nۗLK_yenN<2&!2,TPHQA*˖9 2QߏdaG1w `lƢcD̛38;als\LهyO~}U~PH=TZsgj+)̴9]Ћ]/!U䀲2  &Њ@7n: | 7omc'; #zJPtMkzbBW?;Hur0\EHқWqk84ۥ),'IzP|rz;|BAw]#{:O R|2.评\it#Q܈w0Uq@sf|X8odc"oJtd50bO(˷zH"@巈+H$m0'!m kbk>W*l`駝kCar%DS:AHA;A0tk0OՊݢ7!< ͺ!0ȺÁ! OFҰ8-@F[ Z5tsgAo"-r"ؕ+W5؇;m)*/y.J:(PDIo1T6Xty3B=pwL*rR;VJ':YM mn,7&DG֤XWyc ':aԗϫ^(j?~5l]z-if_mM}!M_WIK$3i!d{0Ǩ,H||xO1m66%[L,?} ) )JT&qL` b K7C1~St#(pO,C~6BD!.k\ԩ@'+&jIyLAeV؟C޿?*DŲ*\.kWF,+#9Bg3}jI 6" M+9,f5vpЍLnf$"uu z;1ߙdr:FI;ؕRy> πUEHG(*(Qg8 CҌuGV:1]Q.g`d90G6"OUe,!]`چ2g+@@A aمTbuiNqMM: 6r|9FK,CXOp7.MւRGu/J=ՉfSd$_m%ݘlBx0 Cs^pcR=!4YaX-aA<@.ѭ5QGob|`yeb`I\4澕ꞤWD@ 4g D_-ZqsKU\Y\}[l4?9DM6$ڍx|:\6WR~QfYS5\w60K:/:ߠA?co\۠k\t:Еh _ nb_c,4\?υ/6u6 4hgR>wmUݢ3mϦڕIKj #4o/R. 40pk|9w0+)R{DG찶.zvh 5et}M-Ĺ{!H<+}!P{|.pLZWݳko a \,J۝4 š ., bm(VE6l # 8gWGO ^[xz%+[s F=wbd ǚV& K!wVud#EYZKkL5cjZ403ا|3^]jxqtOuޙB'=Ԏ*KY'= \S)fK!rLO_{zAOש<+VrP[jw d@%Ǎ2Uܔ؇vD8reHQtc ࡐI3!O|e!N*E0J):+|0CA]uC'LYD6Wjǚ8^w8 Î \?UR>#(lN/++HgX<~B`aRT%|IsR>#Mmn*{|w0gPZ k@R x8jLiڦ\7-,׺̹! VRCDU1 ++peERa#vmW)Qt'm>NmlY4k6LN*Ν7F]u=鎳  jv ~}gtDݔBIT.nv `Z,TWrq2^ыZK[fy1DTkȼW2ȴ$A/>(_{@9o{uH3  ,U3N ҿ uyz(1 &󦾻̛^FAoQޠEkU R"'u٭$P=B'(euˉ,F+I`r ŢGީ6ɒ6C}Q, gy js%bӑ%w$U,Ã,'SZ׿&P rt ]%˺(5,A>\aQ'Ae/< |Tt5CXZ`ږ k^DLR!5FKHӭ ^DweO A˓uWq{0<ΐaQIg?Sձ}.Ԡφ~E7 4Ś_b-6Vg~L0c.|+RoL˸re&gѷ>1eU G'ubXnD8bՖ?9b7ᯔ-]Z޴5HviR7 IgIEge:#U#`AEۤ ;P\Tm1;cWYf\=+IdQ`%7b6i>NKִd^LZ!ϋ5ylgDxduРIt-"ԸKfNhcoop$^ps! ∊taG9b^K?o2>1mp-p<~-^d4lf;$NLzMbv737n m&\X}c7H염IEâDZcR:i4tcm[&WI| mkҿVi Grߓ֐ely@mƌ 虡6b{TTn׾geڍ%ֳh[=:ж8k_ۢmi[6"t{?-~[\ۈ-vQB>KmX2 C ~[amVC~[lmk~[߅7VL?4tӠ$G{Kҭf獹)ք޻YKXN6k̯luxYݟY [7\dնakh[?U#74m[mJܛ VJM׃5s+]ĭB 02)mK6이-ްPzқD)Dy$Bm˽I<ao27C#IwJES* rk@ҍMMD6Y^$;[4Pq D&xGdPpd GWm6E,oM[-@=} Hȥ"sK }fWdad` ?IfݷxRd_iBd ^#iZ@HzH xQlZ媣Y:H #\Ԭߗg#B pwRđ:AWqH!MezIȢAjR5RP"-,}Y[NB҂Ҫ =>ß~6ojfy.;-TMdSc4}5uLjS4LUu^r$#DH*\i?4pHaV_s|2;ΥɁ`ohV+p« qr"p? &"IMB.$"+RrКx PK)EșBmi\qnGN2Iiz32]aRT_my3|F6dɻY5AiY5(+4j_[[:QR%*I xoAe{, M} I [L<dg!su'ɠx&dѪ'Mg}|ap ۣVgG|!IqK9tXSԌ `u8?3pQԝcA=+ !OY1gCd(k */UAh±#(,.\1b|1Ħ \$nR DXqA M i?wV nZ3OQ8@(] þ:X;Ne\W=+47jw1f.)X S ~ZbːyB!-*ǖث[ʱ{n݈*J22!?K8f[aEX\Yq} ѷXEaˋχ@,>-lh?!ph?CO7c^Чf'58 '¡ ǥOOR=DyX(ZolgB(K{` l,CaA,C%v,C C~!|Oxgh?1? ~Zp:v$ Ds?+Ok@ʵHz CQW8vs CYcQP"0znw]Xh|YbO-W{ė{8bO'8=CVkP =~? j%'VѺv d_ 5&}bT~p?~B~l/"0 ~?V ~H}ѧ+4苁SJ {rBgw~n[ڏY7_|~l/rci5snX]}J2OfrtbH>%yU>ӽCL6O ]}qAߺ :@o l\P>=[~jpG}rʾ p&_|U2dءp7v4IDKfʭ- S 朤` K}t,X¯L{3/[c vʳ~'ӼL99.&tD)v@.aOYs1_mc>BU֗b5=i|&7{}>p!J9b>sXU"^~Vf(*JUb p "\f}'kLG*qI,.jOZi?5}cZ8vh.W]iM7A$3y&6(zE>hΓn3|g!̾h}󵥠k\is#77ZLLIcQH(?abR /=-^ٳXt$!<$eR`$U"IJ;U II=mc!_=E4ԗ\sCj{h]LݶըT1О`Qԙ̺_wb9@X>vx!HIcXڳ@R8G@(w,q@xA~&&;#|y ggrϺg~ʶuJ%6 4Dk3ktC]Km8Jc*w-[+a+(9l67ϯcZ5_8"+x=xQs0|!_qDž|&iaCY;&eP3q_JnҡךuuP#H[׷/>M*L203a-Q|ݫe&p$+Kup$xw_~4zrͪZ~'˄OA5ZU䟦h*Ẃ-qf`7cv8tf2a/0 Tb!:0o+P 98ŗp,бlL+v@nWZh̙ q;ZuúI@>]EMKiZ Cj< h:Q8)AK^l51`#\ԤVVj+8Ÿ0QphSqT~ѐɣԤJpX)↚jR&=4ԤjP:3Ԥ p@]s-f/:nvyp%,ȭ> 80)P8ϡ&7 51Ԥ& 0Ԥ:?K5Ix-wMq^-a҆]CC4GqTLg~eץBmn{Xʭ9ۤ5Q`y5)aI& 56PH&ձQԤI㩫q$ߤq6Ԥ&I?4Ԥ&j&?G!Yah {\J_dN Zj03 ?< IiE LH*% $IwcyHOsk2YHQ"}H <('Ӹ8)qRl3+_6l,b R.R\_$G68F#|h|+a|QRDLXj^?* a( K 8}&@ΔaoZZ@ +ĿZXB`ڰrҶLJRV}mG,݆a$cXAʰrr2) Êh\n 7Lm5:ʬ:~2Lh ++lou_X' Qڙ+7L0 F}s*7_xOo&@d>3oȊFXtًp'.|_yPk7|aE,p +z!a納[ S~`hX-n + N{aXZƈ>+ RU6lMZX$z͡ o{= [, n`[fko!|?}3D;JT4ϼDEX!*mVfxfr40xa({Ef2TnǮ3p1fx` )nF` /*65mEP](E`˴)3(^y82U+6'5ĩacy܍bwd)ǣ-'tAU΅}e_7Ќ'&q+^EAu[=zT5>vvIj6Ԥ|P^[w5դRr,ˈ)NQz3ecjG} sˮڞt*H_'TmOQ>huVnEj%5 a5hI8CMjB5I&Ԥv /z~T&ܞc]Aq,P .NK'~ 9b 9uiT kR5i8ԤCM~t57ʂM\) ]a@sUZaYWsov!7TG-̡rTrf;F"HëOT`PRG=Tu|(դQ>4x8n&([m&eu. ;\RD2I%E:Ӡ yar3nO*si/\/LP{/./2p D^e<{~bGri_D=X~-ª~)9h5JAinm Ƞ0Rq5GZs$G'0.˫ٻU\Gaj?Q6NNda2E+hm 4e! |fGYW<| [9@@Vpޞ" *jL&Y . - ,&pZ- uW02:@ Owp5Oa~&[+ (`-O3g_q/q_o{Ş&gsh>wqIHdXj &IpJVciXll(u Agm}9E~~Ks.ˍk LgnW p}`ÀL zQX@R$G85 II@6JC!MRZXoR^¬`B}3n) UIl:Tf]+9k:"/jHe8V:S3-d^6nrTSk<2s#5T5(Nq)B|\nK2)*J3P:kuQ*BjR5u+)DkMُ2獭Cs9ߊ@,Y32+8\žkf#D Z=,ّbTORzjJG }Ubr$kOtĹ8?X\/T/Rt+++2܍z8^Qz* z*l55y1VO"V@Ceʌ{9X: ȯgI8@!H@`pLY*S|," S]f;+ :<h{ho:^~S$LaNfF⒒9=zTj'r qaeo( P^F8U`xt [d/&! 51ԤÙ5CM 5S(7GjqNp6v/cڙ/UێAjƢAԐXb3h KjuQX{qߘ:IjIbqCMCMjjPE,*l#}_Ǝf1$P?3.08ꚳl1ۘ$)aq92+'W8i=UW"YC1j& 5)&y&}uTvRR2"s$Μ ~P@Xwʖe+WD’eIN O1 Oxݾz]M}MLopOG ~Xl e~&_OI &LtI} &58IX \&-]qC ՃtUuE f<@ݑ(p:m/*)W.߮3k?Kқ=pEیXޏopk7)392J4`H&I&)kI>Lb_aM*?dMmy pax]֭I/n>L4*8¦|8\IjUMu01Rq8H> j;d|􉴭^F&c.w>(5x͛"{]/*K>.(![a-&R$fUzO`cud/zא=_y  QgszcD0};5 cI<`nѽJ[L^0 zȤ冓 XyCV9eyn7smg [";Ub54gq{C?tb)4@4S|({S&O-w9=uپaN(v; < רm4QĀHL~:/^FM*Īj< " iwp݌-?"qXvd\6=i|_Ӥ@`=)t+/~ C.; oˌiޅs]Rb nSoqvZl+gӯLt#0p4 E׆[ sb83ue)"zPr%fރ"|(J?&1`rʿW`재 cI]0)1L:H4)"&(QIΙI%œl݅IiAq,MXEL~[ltUo&zwP^HEQ3]w 5Y\:.35h` ;ҋq6S%?_-tF h6%҈]KDd<`P՚px[ҔhZ)mM*aMzLj\F9[5*1}5IĀIL̀I_Hc,\%Dɗ(ݤma#Xo܎WȚՏ1.=23v7=I?3ȸJb4vMX^_1'eu!ƌKRKkvX\r*p162l8c~ })ƦYgO5Ӛtdi>_t3>|VXd2Dmr^ )y\ :@-H>$!f;Etӝ7RǤ(ePumG(* z Vd Qgƚz5tmi0vxg02}W? |g8ܣji[+b"*2FHs69fc˃֕\6W0i} 4g1Y >4FQa`Z" L3j ˸4zKdK ހn<1_Vv tVPBtlJ_9ۉ}X74ktCQěqH`ʌFzI415`-cܱbBa@fi~cn̾IMH6\8ṵt8{3BEuξ*ļ0U j['+Ժ蕥- s 4~"]P_˿ #NqPxiDp1 5uMɨ i=5n63% H1LrNd tw[hT_# w zMfg֩BMлA.}<@rQ;Cds=TFzKWgj0mC4& $*gn㿵imC(4̘šqFfE^`Td"JOQ(>(s1oXԓZ2=ԓe"$'7S⦟%F$ZFFa"ϲ0-ų0hMVa$" E6:#b{gꯌK^@~,y5po=!֟1?o6$52WVuyMfrX87ҔTg⧺MGd=f`)!)7l{S!ij'lGbebm S0Zp)"7dߒM$bÃG{jciՂ*=h~m;1faE !N5E a,jg 79b8f~;ɣ{\CjVka%w(k(BC%+g1_Qْ0X<`HfvP@d ;>eÓyL&aL07`3/&zWϼϺ;ݪP"V@քN" _L9xq+qu6e]9 8:WlkKcy8ݜշ%:0IrM$0i:߀IϠ0]>G]&|ϑ\ӵ(%\I~H>OE[9˪0`*L 4`ҀIqI1`Qy(ƹɛh]4Ls~ρV^{V{XN=t"c)gs4?{.+FoK=+lIn}(K&V}JJ|)%7nTZ^()\p 0ظwxgd7D?t[Xe &q=Tnq1ML:]`TЏg} XOH92 q,kI`zwxfE+r._,=4`WDBص+T?QңK͋A 6:}f\>m\R)1k316%I4%^DQ!-+*$Z|?:P|Pf9IAk'_tY#"cGղ'M7D揉",e7N]#J{Y\ơ lA&[+xWtـ\Poϧ]1ܦ fr;@^}I^ Y[;zUZޗ9 #Hڢ64l,m4U-v){ ҌJ6 8 IlV|weWC͢L?_Q󭚑1$_3mWiO|v#Y*<'=kiD6D?HSK.͹]_pR`~=eC+h)qCRؕ& Y [{~ǭnbuuknYb^O}Ks|%]wd7(ử/G4:Ͼ+ AP{N۸"/ E~ͬ޷LzBy>;wrDP)>H\ՅjER"Z6f"XkcgRK"K0OX.O Z6)YWG13<`kYLzA^&=bMI>L}~^ZMT%!Ik2È6vhaձ.>c p{ʎQu"A(g!ΰ kҰ& N^& ka Yy$r\ۦVLi5oЭƕnMnutZlNY m :bNجy~?RURJk+ʇRTDUp݌RTas3>~޵"H(WւMi4'-"PX "Ⱥ@%.Pt*u(t @TȦ"YEV*@)(DjbH4?Q`«XsQ $Z8B*hx/޲ckH4D4zQ90}!q ʁSULߓ ?:#3~FԠiMk[Rq%Hْ8=qXEU0m7\SQ*ŒJghKQY6D.%}[ $'gJeD FrgƔ(֙-ȕɌ"R};\E>Oeb]u/vYmbV[w,+F#P_ňSȺNի&NQvxZCxܶ` sݑtfNĵFu"rౖ'tO=PPRϤ:JVa[ɌPJ2g&+RڧXTOuXՔhM~%odJ@Rp^Iq[,~H^Wy$w|( a%=+0CzVERwXaZhUlEuRXϱp6T n]JmԭO8XHV:)J9xine-lib-1.2/misc/fonts/mono-48.xinefont.gz0000644000175000017500000014732514647725152016360 0ustar meme-Ujf0 6 sz NdGMr &s9&]kI{st{wT Vү_cQo͏M{LWUr˷o:\A۶⹬OGYKVJ Sk ҽp{s2G=vǭBrǭBrrZ+ށ|xzyvlխ޹ux|S}fhiUWN}cBY*ԳurE&MmZn`cnD7'p4\B3YiDiV.$$n~m}Cʹhr(+Zל[CxsZ:>) Ƌ5./8` "^=8὇ w_hՙ.Ú,<|vyt/m=S`Š^杻&\zCy4Xi:v8ᖦ8LVq}5~c;Ga3sdx|Bt5XgKYOZpѡrBcG=^݀}FO<d|VmN+xch!OXH_33(XPЙv'QwhQ+?&|뽯 |9ςs86LZEoq`-~ j `lpde'"&Obp'6Bj\V?K֡ѴRCq3إhc4suW*<0tp}PVf.e'uʥVM&$^ /.?QZX׷ީ DnQ"+WMb_ͳG&ž>4:}#?3\Y8-sJE6z»9ˬ1xۚ5}0X'~G b^N3: ,l@XoH ҈;xk iy~lk,c/g[/2i-;Tm?xœB&5E CM C aʠ,JUZ3nͥzZTCxЪiӯg~f NE8wU~PAWywLɇ5w;\eAٲl^*>PXI;R`FawR^mpk^Һ ? 5a2n{uѣwy汷UiMS7 m#J. |^J+ G!xhga|iش{7ߵhU`Pn>oZ ҏu VѸ+ꝼIӜ6hCHUuVkQXy|Y7u^E(ZuskM~߆{?w~Kgݪ\,/ja|>CCQ@ G9<@?ZU|C"}uxFi)q*8)6ĺ{6nmOƉosge&?n# |h&wKLOK`2(Ó 0!vzċ\_p,2ẏbEV#\|a e/VgEixyLr븰Ȧ /5i)MliX4^wU,y;9*nDdBgɨ/DO}j} n7wA"oh:TU*Ix5mPFG%J.OXHn2GTaЃy?-*F#Fe7 w0VR%0 ,[1p֚.ljֵ∩ˡX*V5lz"X뱬McήC]g̱"=XsFFS;hymvzMr)hҗG CQHTgɚQs.eRoyY'?cժ)rȪ2Kpx@RD%9HE5vE\8.,qX;R䎪!Lf]rHX˫~WˬdG` 1GBL~ (Ǯ1«4쓧 xfKQfZW/EF]-|{HVˬǼ R6GfAn&@S<>yvTs.sULvq0cqa1m1 Okt}=, \S*(M}X /%E%w7PY.DYnrM!&|M&疟 R9TǭBi%2f6-on/ ҒyS")B`I!^ _"&!lV2LU{@6/ۃD`LݦwrɳӸVE?>@d.521KHaJav7_MY6EоJ}оJ .h?e ġSg?DϹ '#4wRB6y~O=DU gt+0iKߏ?~}jYLn|}}CSՎ{ދA] R^q ^- GI w(}DGyz~~476{Yߑuʈ;ˈ;+y) p!O'i9w&*pgSqmqgaG׃;;0rg-wjy˝ƑEK~ oρ77|,w>V /U(ԅFP -]hO]GPА|NgPڤ )at ,.2ہ.TB3Ѕ eg+;;B:L6{Sw6]67UNixAhefqc4lҚs!biXH@kޚy0 v9KVuLCc.jt@]]hMQJGE -#%PڜAķI o]᯾Y8oW&jw C']ltP=u+֬_Cy $``S>+|Rmh<=SB`h =]`,~aɹjZU-8juKE- KQ0py0#]}+9mԻzi-fgV TلG@T <]ܟO!B-:<%e˨t:A 1nc4{ww kOvq|6>6YN]^zߴ&~ĈfGf~e)\krjU%&wMfoqk ^0?Z 1Ե`iP^R;En:^L5 =l-OFzDx:*N9ĩ}>JAάOWzkE3^AQAO* 럕1릜׿Ȉa vpFՇU|ŤH%{_jQ IMҞOܩonfn͝˷1jt,ꗀSSSOēpWjÍeS@5NQQ_,.>zG/E*Q2-Um71Lt%nx0*.[(w~i+$n8Kl7!{m"HJ(vHi+ :G]q|ppN!N7XCp))`48m5Mc~"f,U{ZQ߅E/j~ jqUWWqpkjɒwnc uu[Ѧ [y@2Ӯjw8i_GCo(|rt7Gz}_1kKJ9ņdY ë<$E;HQ򯔭H١w|SJij7pg&3m^,JWS %QsjTچPrm9cNY=C=@$NiG7N_̪G)o| jSJ%˳ռv+r/AS': "{S[:qf(QOYi|u<ګ;:Km E<j`[d_,[~ɍ:{Qky(.z}P ҹ'IJq3)ҝo^B)7,.BPR1{B_o/'$ہPJWVjW\qDCNA{s iqE문:0S:9i"@HL0"zs^@~K%N?R+=~ & kE#T4TX>zG?4$)lL]Oޅ2xq2(/\B|r?oפ_`p!df%bI|BMMjI`p bu& ,J65 +wiS_KID-w6eW߀ޤnlD%p-;L1qy+TbqPOjTd5 #߳~)܁ P.mkj|t Yk(}9!^q㴑njYƾ˵C1l&bLccD; R4|Ek'j=fFb(F~Q._,p 0 UPY~H,Z-vo#X-jJ qV NYJ_aӨmOgU#jUڋ_fl_m"k?V^X@~^ OzHR9d)6 s\3"A)ظ.Vz˵HX$xQq=ƒ :W8 Du#.<ؤU<>IվG%+gcvcTݱi\9v?/- R뎟.&:OKj[74se k'N+o5O)ڣ?&|狯 6))ٺ[5fnHNՒS^2˷{.dHϸg]uy1]Ɨ_د'UAGy"_;d]tyWTO::*:FpFG-OZ-tF:4To d_hxVEpj᳛ yT(͹_Xۚ=fM8ɖ٣VfoxM51(z"IRig1sV}2%05omn(& Q`Vb"^v#+8hkfb0^̔k&خO{i&x2'IUvy$J2a~%&Oz_Qun$94w.dzEZW"nMb,3)0^H芸aC^-%ȳM}oH y yhW˳/Yڗgp\MR9ߑg^ܑgVU5a|mg9CVi5y*Vminwz:E\=U|4bRA |hf}hєʳG0f)sW ks$|aIǤ\$j'xH2L))zmihIj]X|Zl&wmzOGUc!A ʤE֛6 9Y[ nHNObE,/!2c" eVgmxtP=JN?R&g~+b)|jb1<(' )`S"țYlc'@Ii2lMrh7l%٬w_@|"^QuΫ2 FMX^Oe{c7-M4;9->Ǽ_laEwziq:]ꓳ7f638mbĩ6M8ǿs2dPJ`3(-=0äs{LMfʏ7!lZ&+.D*JӑYi$5Ms@UeUZY梄w#(lX!ܳ*UsQ"XpGJ `96FFi] Tliz VĪ9Tl<)✜UOz9 rm/1xn5ױW68M<(`e !C~Ô '<6޳`Tu[)e92vןrr$γ$9$[ySIwقOeZ$<>gGvm;zIxȦkկUF"9L_i)?"N"whK<Ʌ$g. U[pW-Hkx0[{`L ͓wah##lS. P슁%bN”k2WU A icϹguWm _Z(Pm s!3FB*a2xB2zOfFf5g>Tֺ )~lݘ"wMIʣG[TB61f'86?y8\%,s eRHG80mz6tdDdn]$֍RJ (ul7tS7Td'NU#J` "XC'<)Ik&NLފavaD "dG )9!&Ar)Zm@(8r"lL$aVJc+[MMq}\iTjݮJ" NAK9%v-U#\IUSsܭ's+~?^yFS/]U2/jFbuB;{4R5 A3Deq>ݝt| X:S@JUXQab'h˓~~T&N+s?5H[o85#>1ƒIs":2T|uw$- .=Zp!9Q[a7-x5pָ**p־#Ldx|l0[AZ;tw m8fI8()1W8AӶˏV7MŬGYmu ff^; "%NWG )Os;摐B!A:3A4ρ޺}ke geam|,]Qykz9<`71\1^vcο+ο½0`iX*&Pb%⻛_-j:;,jTQ+R9~'<뮳 ұG[F$wmYw/?$ևug^ԫbaw|W}fۯb&^ʩz5CDr+aa5ސoiBbyyp1-],/.Sw<:!~wYu^Im"mJ/*R uZ1Pvcykp:\nne-L3Eb+uXeqau<16Soҵ]IN hؘd=b%ʮ"1}c]v:˅ Bqcr(r(rɂe^\Ħ<$,8HKv)_]:&OG*jtTQJm7%upNf,*4i<g-Fba"~җEW8m.UdÄt/pOe C9W@U\\i[4-W0U34-WJ%[Jdɤ;EIjΛiD~xsp<>-I \[V-?(],/.&[]]tmeȇ9袜- sΝ/D 8 QkJ3x{ E>3qw?F0 0hD82PËR>]-D7^@=8F0<5Nf ~)20IqAfj&6~6:k.'΍ܡ;\4K/|34lW qbuo7M8kBSBt-]SW6B9]< v2HGw4Q|Iҙ_1PJ6a(AFZPʱP*Dox""}{/غlN,8`jL[Ν[*am (d􌉹}f@3u+mM&\jv'.h-ƈsAz%-n,`tZp M!O,8ۺE^`.2>Rq +ӕrGr_tr\/2*uwX#o` jܬMjcב&vS%p:m>ee_ʸA9fA l>;Asq'UF~}m]%_S MClH )pc N"'l8O~O`ߗGQRx@[\roxC1(mM&8}gp RL!hF@_Z˜D(4.Yx205'7jG>AlDN8lF>(T*"zB.XBşfdL7=T <z&>aS\23j8eV`3D%O#16QvF=R) .mӢKn\\9^ ^l4z*ڞ`a#Yi9Z\4_ui[ K:R$D_ u:Ɏa{s\pLIƬmz,1 xe^18cD^"^4" hw *gR8x&X{~E8Һ!^6tbv@}J}U8M*{dޫ2.ݵ-9aG[uuʙ>-a/S10lfYWěw&n BncWV:Ub"VvvH8WrH]e^Xdi2\Tsc,#6!;}jN'ѣY|TBt(AZħ2 P QADٔ&.lڠZ<(ƕҩ~G0f?+ &(P*>U(rQ/[n%HY=`0J>]hO|q'Uu7EWJ7 yTmb//¾g,*dU\UbVmVaP)*laHap+hz̪KYt ooRa#\PU ޷6SY\n.R-*lxv{zRasZ٨ua*C_&S9hw&VN*liRawͷΉw!&<-aД(MCk>ⴒgQJ[|T&lq(ލ%@O { y'P |FfK`qDQebaT}YתʶKؠr!r Og|QޔfT/.n" +"##ȍ Y0V3x|N(ڢbF~{]r7>aXs4Zܒ;궊bu7C5Yu%+bLæ)E< /0н3.TΕ׾=>`ғѡdaRرgl:Ch7]q\}w{*Y^Rw3Ӫ+У4@I$IS ۚ;}zsĽVs7]n$r‡'QGG̭v4_hCyYn{oIPP [Y,ryr\p3ж^g[mw1ZIuu\,1ɩT996qZOɣ no^ŕ9K!A~3&q0vbR<ظ.&:vMI<[G8Hv{DD gP}p3hhZmia9"W۲G7?$+kEV:i$4z n̅s sn!L Uwtw0b̃1rhp[!TN9sm~ΑTxGդ]#٫Twh{?m_-dP>fFVO}s=x={)y38)MUr/^J]gp׎\?Xtj(s0iMCj£ShUbk3/ލy]@ˆ@0o{ϼVd}c ZZry8͜Ԕ;uf\\;f7_Ana0}tYq,&%}koPPfá2u~` e21N7cқŏy0 gP0CXwjUesv,ބ^Hʇqg!p֏ 6.?9"7RÏrЉr%c֙sa(gE8I38 &G39|qg4bbٟPJf R2-C(sS'>rFUjg񑛌{)1WL^"v{TdA+PPMqڊ,@$_X3%KsV2*&S/1_EH f)Vn>c[`[QJeyDIA(*Y :,= n4Y) hYV8ˢ}Rp UAJ帝ҪzIِg%rkIa,+ q}CdٺIe ʨA#nyUuOݦμ7?J#wf=뾉sȥw \ƽצBVrs8ѵ{>.E!06lp8D 0ڦ7zmA>< 炓I{/V7e~\:4o6š[D}QWOr*5603ttjj&甆[E:Ta ֐A=vy kJTÅ.K8Rp?jH7-$1bk8GQ>4mg p)kS ͢m>h#њxiOWY9ϯk10sݟp_d~/Nr)0sIZՃ;<;2<1C,];aY^]J2Yv"3!8)/W\K YnD%5!8 pbv5[\e!!5WA ewB$Q1+^,;ÆeRGMQrwljܞ57u 7?X:.h]kYrWϲUe>2],z9@xWH 9lC$wUHfXN4Y0X]U/Y,P1I@l݈|;z~rIyc,%O1 ɦ#˲^6ƀiZl$˲^5Pe+,{ˎ˲N/jY@ʲddYU1-˒WxCOu=.oȫbJ_Q8gSXT+ ɺ Te&"SX(Xfa"4[Xe݂=5\jȵ#I&1,4܆JcNo_~?CcaYY8\VYF; _pC=upAw\.S VB$TY˅qLjSAǏdI6A}G.ݛч|qbߌb `?W@"h}Ǫ r` 1.NHفmZE8hlF98?t]°:/꼨ΰӎ:.' xiR؉|xq?zQ5R<4/\uy(dUⲐ"?Hğ̯ Sxx󓪝X\yQEu埍t")C<_x{uuN=i9I"|`Tqہ2&N/cvtoF 2Q`U^9}7S O{>P:ǹ eyO"uARI^ 5mIV \ipQKgQ8gAf!u:_ Ǝw!dlB 4u{Qg!uu: [m֯^τ7?ɋM;Bb)\{ 14e܃u0*tt:_%u|ϛY[ެ;.]SH'2t8dK D;+g:}OKg{ֲ=b)0LQ~MT}w!34l47xm {\g70ճ5SH[/5poϘh f<)sI8m#F!J`3l5ot x ν@YԉMu*sh(:QfW s;'kot ɓӵ*Rզ.QE/6֪E!ghBYdkf56 #V;56c;@q$O6FOnp{8\r /1bbXJ04BBbhoaEFy~əo·Gw ȭ2o(^ˇ7ct._̈4WFo,#cK1jN'f#X=c%E(#b]H .>ݖr|*Eb i4׾Q#9&H8`U/\ RɂO0$R%QYq굏0|R'ص?6^4W\~|fl_%sb4uLZCqxEsuD!쌵czT@nk'j ̞6܃l|GY1 a։Wwi?4>:]:|:Zd6E:[U[b֋Y/f.Zf]0CAa0 `Q&"NapUH4 @9[mL]z1Ŭm$^Z˿e~!ti ݩjTfwszTx 3|k3+#tim@0'\2ŬB_zWs럤?r0<٩T= b֋YQo]sqdwL͘ad< ) 8M|酨T"P=L{{#FTh+"=i' >QiW(p%5Χ+*.\*Er9.tݳr\ʿyxu/ s&Z0l}G0`Ý`( 娋碷 $uCX`߽`(6?K)z!=BDRE^d]t K~B0^0R!VH!89,ClTrϝC `#.`XjtCEyaqe=D`jdC"fv̮`xOr‘}/Co3c%fou0$E)9KnFn[ۖ3X `%n@1U_7:rA15bV_mntZs9-qV_@ˍq.e`|hN2E,Ev4ڱK`v!<&;Qt^ہssIԏ45 51sk/Xid>2m+N5/_)Я:Kmsqeѹz0t xN z$<6 9ϋ:$}EʩUg排Ȓ?=6 s%? O 'r\"WFyƈj\.꼨g/ذ5'Le1q$c]LN%*+KsR%ut,:`Mr>nn`{9}ߪ6-(5 ]ȄЊ+Fn HVsO|{8/m H$O2@3XDRbb/tjN-E E⻉|xƂ1j{/r3uQo3b>6gZ43Ɂ@4Oh!,v~WE4)^3s6w!ynvfǛo -LK˓IoQG I'qbFUjv\\iK& ExoL9sR놛1D[}͢n]nď2$J[b͡|~,ti>_ïYi(k5(IQ{٠eθ2yc!Jo_|xFڌfi4:: s^rA5Ul/s%g_2fWeA`g\Aı_(uуÐCDwdX3)/E``– WD!#bY4u?W$Uw[ڹvv=לZ61 <G"1=%T!æb81w(I|xj͊OE K>iŬ^+f~@ wң;$taSLO6-Ȍ j,kD҅gYiUNHͬT3P 0k0k0ťKu~ mA^[ڜRGZ]@dȱ7G!DM۹9ү(Kx1ŬY~SlA蓕7 ! npp@PY8X(&d[lhjh_Z[dȬŬOWĬ&5~Cz:T2zHƪ̝P& )kn>1lU[zZa!V Y-!fˬYbf}0NWĬWyl \N*i5/ɰksi,#Sg5ĩ+jtĬ Em*%ƻUU"h+:3"yǽhVGҝJ n5dըbx&e__ mʂ7oJsSz b]?{L{rn*Y-lpEWjzj5<|Amk%T$_AƬ?|1.i1RLbUlf Eg[wR2Djw0K!$Okp"b[Dfb"X3ǵ&]>ZwTs]'B^فboT%Y7GpIIb|k:eQ:R!e q?ONސ}\;s<]RM,BvnH`怆݃f}T|4EVOu)¹u΂z1$wd-z.='ԧ8 #kgы^Ch=('9{U$ UlbA)NRH60'G/c\ \0vۧA $W _&^14V t 3TPRoFzH'.f# qR+p_D7Jx KfPƒ)C¬Pzә?6Ż`V{̊v|owFf.f]1qT`m|3kSڷϬrjfݭD1k%d Yh=0k̊JڀY{uuwŬren앹mU0@f=eLf?Zezɬ߾$^qB*'?Յ1?ۣfgKh::uVO?{S3y '1aнL#(M҃ &*%@A`Sأ:v<~jƳe?j}5}w_uǑ&'uC@HocIX"nbEC3ݓ׾v:]2F Nf:__e9(nJ["D)@;,E;TYM&n&W9f5i6 ټs8 }yԹ^Kq La-n}z)|Z<+Ϥ΋:?/uRcXr!n< ySgFL"~v.zfvoE_]y@Dю+<;YjI:hבR @Qm7;1ASt,8ЉZ8;mI>Hl1\3DkbfhgX6" rȜѹji<ՂmUNт9+M" Aג*"P0X9N\L5xHCUi ?}@iܪkW;v.b^z.u4zxypZzi g2[_%k. q{aIswuD.76VRd$b4ZȰ8!U=HQVjy/Y5%:,2:bUKf ž:=< 9TUJ2@äsni!WLN-?0)(џ:qxFf P:r/ƚtm,31)Pm$CBw\Lv!]\H89Щ-tDXr:]n`%Xt`K M|o.{Jg>~ӡǜ(y׈\X*\6&zJ#4#kÔbaZ0F.{d^D!{aNq0DÊbswSd^b֋Y_VwŬ|ZǁNI"L20E^}`2ˮ@E:lb֋Y/f}aY_\ ܧC&`m1 wT2;dVpd]P^qmZyu剰M^m1-k؟/fb!:4Bz 0pK1{j4[f ̌fNuWugC=Ҟ(f'Ŭ-(VYbC ^Ϭn +fE╰%s> X t7`V2;cV7S̊}fŘY#f-_aR-6? Y"Q2p@m@̓\YNWBE6^͍ - h{2rOӼyDVIGjj'/ߨ;uR D6{IoBis$fxFeElYPZ Eٯ mpq g-cf^JR&R5o)TlI&(oIhD%2)rglkEb?MJ[ vH^+vI^m{{-R(%¾#I(U*Wj8{bI:6б%$[[N=w=t\ݤ*uM,;M>-5P!%{{c%*o|!5Xp8‰ ^$e҃kҮ\ᵑ /,BħظU{:"d@D`XC[iNJ:lgx_ W|`y*pB)7.Q]мA$]nä+oY=fm!*0kyeY0Ye=1qdfi`[!&u8hq0؝9Y Δ3[G ȁîl WuԸadIbKf5W/Y2kJLZ[+Y/~fn#Y(Ԡ0H XUg[%ҁ6y@rk̛KUA=_/KRN!FJ!߳L(|3pwͥW}@$ `)#x~?}<ˋgzzV|/9X^\<Pp1ZbbEQ<lڭaQ ?wb>='"e^Alρ779_ΊϮэ0Eb%kݴ)J1L4/@aGf1~P \.QX͒$;-ŊmwlO=4lyj zXG}/8P.ʛ1L;H`G&(QypѾlKkr^bHRRp0(leYbT#WZCs6U;,t =RHL:;=\ne^;tMfm clnC?Lq 崞hAۄDK0u|{&,||9z]E&C(B[!??*Gy_Aez&a<>͋1&k[|z˚[l(&FKepm0bK^/5pɺ2/Y}Hdl6sn%CՄ%2$,1>LAGŽx&8afjSPNV'x}SQ!AR[Z0-={0;Q^ʯ$z$b {4}7?3)gL{.՞˵lKh[E|+htʂ{뢥\_W!InKB9Ee=I v tUKQ]HB7JdJ Q!/5$d/By:RS9_?+ '01D{/_ } $Rk aJ" gR* "'&m f?` / (߂"ۀ6F!4ޢ^5Vl8[1֋txJQB=+rSڌY.WO";|Gr":VQthf9A0&iaR?Uyj~}К:_wE$IB#°gNZ_-Hwz9\vu$oDFmGo1ăcWB^'96Ar4:Pp,J*, Sx% -@7fw&(a9tPG_d1@jZ#6s'nVhIYeɛD+sh YR$Fئ{],9Cٚl &1/ Vp?MCE?$aS`՛Z2~GN _XS3yd# δ7AFVƋ%̬2dIMѤAxH%ޖKA 6WadМôMx+RQf|7=̂XBUg_t2~֝1wb/(4i+9BVT"p"mVäK '\&,tEZxǺkX3 -pyg"mcN-ҪjDZ1ͬH{LC4&v'zZZh(*^$GHL<fOO4 (:U G7w(e^3[7Lk{CWuX-TB#/Cssm vO]=o|XN\Tv;i׻EpIyH hSi =v?EVH@eD4i[hxW틴Ъ^.V~{O 5 H S/Ҷ!:F0r)ޠG0b5HP`HvH%s<.1Lɥx'bR.$d [^E^bLt7Ȭxp)(O `:a<٪tgq߶gNA>RX&P)aeEJd.pd~aޣ#h*p# 'oSUXڜ̓qJNU&~a\ՕbphCX~6ЏSxZTX6 ܁KtF.NU]K D0K"uf(=ڒŲ;KaU[Z`DN CS"uI ~,xK;O(ApQd6VTe\G4ճ&Ujl eh#AkۦiVmÁN~|ز)LJ)Ɠ#DuBZ~ P)$uP4ӫ`}$< $ҷ.,*z̎u(ӳ%q-Fq 'B{"ܞ'B@{"̞'BX=^Ou 0z*BGPf ܔ@@-ozEiJ1;ͮObE:j" fA3[J4a 7`"X~w䋂)Za1uv 0UhyV{1Țex||mͩx}F=`KOC`6"EyA{n'lx|b@ۋlifJI+YINImZ6v>*Sּ'OBz-p"MԏFn^2-.ߖ=4KAtuc0sCco巒-T9LX^w)&YؿD $[1nqzёFk6J8) L_8w(ipQw5ⴸ[pہ qSxXo1"> 3r1CJ{YGDgyeP,Qz=6ʎmv/š,ȇ X:aUdzn`YH0>E-(d}mfahόH'alj":0 =x(vNcsKX>M;>s?u؊tcef:ZNXYކG+}Bxcӡ"8wv 3j4}2L9_K6j܄xؼqV޺](J]۰PZ.?/GB#;?Ȯxɹd98ȹjSpp)bk~ɯ vکNxX=(mn]^-JO9ELy nCTFpaX0p&shS|\ sN%uaJ Yˣ!rG9 Xq+28px#ę=,^.a|1-Mcdi_yzocO6{IßbbǓ;q:XO<*] Ni qA*\Z#vAXvDS:F?]Bp7$F {57:~9xy,*e¾©ZI%"LQsXLTU#Jze/Tԉ\H^{$۰I{OSvQ*w$:K꼤KKOgRgy/R/ ΰCFL-l=% ͒>04٪`vQUyN/S}tIw_Ѵ5Uۻ&t2ޑ*VݹWg>9߼b5DL}75I4E5WkW!ZCڧ0ՋIp-L"ZlU$X&{Ȫ!dGΡ)\fLL"81mƑl'vR}B&mo 6ɪ893a77z1c;iD%Oـ2mxEf3ʚB`?h!F.^طɛzH}ZFvs8ޠ.mIYSv/y/)T[R`ێ~cyHZ[/;}ae QZuKAu%tYRhqIqf~7.d 'OrE᫤+oHW"/O={. ĪEwozemK 6-Y 6e UHg';,[dPvQ6$ 6&z $'})ܠcL8p ՇKog)K]Үy qMx//n&0XAdž˄!TTC6v4ױ4%^eI "J}[Y*7m'*`9Z&SOf#,kl-qb?oYX\Jlu`)Wffh ៙9A% aL={6n7c V^d~r." }fuZ`%xKh3¿ OFYu:j$rrUPau(cYMxN(ľ^?˧o;u,ә驓)x?'ΦݜN!G{D& lJT%׈,=Wf;w@p/ƛz<ϘY[EO*=нK~ZF$ ؙ"[C-\ 7q? YIEznVnrhOR}-Z$WԢζj$i lQBa~4[/^rgDџ&>W|CչƊPìش z hh#2ft|Zɴ;Lͭ]"V7CdiW+0&Zp6|Aw'慰A-,Óz{z XQ f`aZ!P& <67BuhLpfIn2f8G8ORʲiim(6Ў-t]=w^p9 n&K,{ɲOe"Idʲge(P}AA(seEęɹIBzH1]beD#T\$tD g,?[hnѕH;BX̋/-ˮN ;emʔ.,}٣]0'XH_ap.ޗn[#gŃd{bH4@B0y<0e| pŽ-Tda9ZkؖeT*U=u;7e ]3E.;YۤHF͙&m̫>5G^fIj J"q$reyqNEk~cOf[xZ0tμ.y!--GNHN2enN~F)^19WTպ=*lmkF宫TbR>>g&XXuujE&$+>~󺺟O#]}_>ե3Є3]};quu:T&ukD0b޳ޜAs+xgs0slxfghѝ9f9/%6b7$`5;2l}b]/ۭF/XwF~3ӫ([oW7.!k(/_dX(+]4>ϮN$ iϮH )\>Ɗg9(;IyD :-G[EG+USaHIf̿1C(Ìco/OGY)6/:@ Pd ޑ7t2kLHpS+/;=6KjKD`wFA^@* fK7k[_5M]'a1,:*^}&Ҷ}B !YT\O%Y!%B}'s9Fʹe8cC%I&\7ⴌve >ڸWNݱ {=ubXI=s8) SXDpκps\=A{\&.g}yW2Y뉘Ƚy Sk^ҳ[|5;ݰ^mo(=KQݦ}kv-ᏽt{~w?~Y57 o i8\@A ڪIARrҠs^}濯R!X Yػ˅4tph8_6t{,eBt)[LL(^N.(%!ƍKr8]Xc(_WR3|6/s{#6¦|Nk.MftiݩZ){ox$RENƎL+GW* 23MJ45f bK/?YX.ʙqh9ϐ?[ړIУn*IehC1C[Ar'H!>%fxXg0 <3K؄sM)M tK0~Zt/xy&lF8TX3fƨ59Y~wwfZr:i~Jє"Bo&~5[tHe)2kw]F1Tʹo,'qxXw yq@`/"T>ɼ,uژ9p Ѳ ߷j!1ҴX Ff-9*e.]C/שڽ]RJ}JKJPmB/5PCt<[pAڂqieܘFATn^={tv’hu %SuZZ_Oށ<.ϳ<6uOkH: 5vm ow켮]{}SICeHO!kM<7`қCs3YLrm}K|sω|,ϽKRP>b:4Xߜ{3WUl1 T%Jt$9MX] <ށ)2*otO74H9aSI ;=:A{G+餁jZњ:i!پTejPr C=k1@. 澼y\^[&6 4j 9C\F)X2葁Yy \OÛTźF7Ա7 /!m{*1 чB}\߉[LnB`p}ai`,#~6O2~b TmoQbd}nOvV{Es&A)RgԢokv}z! w; olgyK"w؛Ujǒ 3J\+;0-;H[2\V:@,n[b݅uĴiWwm @_Te K?k!%AbeTuRjᚐrj彫@߹k[5!v:WfԱ$4ғӻ717>eR:ϸϘiҳLJRO]@K47O a8 \nm8rG(w 'F#4iDA?~hUNz^/p>}֋.(=x4_p%v=³W{cJ!z_]r7y}||s6 R>F4_Ji-S]w<*i~\+)-#-O~6= E +c8N0ezޜAk,'eDZf!>ə(zm3#2{mj&)ݡ듯jvo^L۠6K7䯮>"'i_Õ\2.8қ7L9N39kmN!>^D(\yЀ81nAĸ>0&tIZFam;Vz9p,P'- X:D$ZǜX]f%}3oRkޞEǷhm[207ȻɎA~ǒ]eGQok)~ ;hOf)%$bg`wK>a]YZv+lk68*XIQU ~1 _Xo]UYggmW:ü.ƭd6 yd@pl{ze?*B6Y,DPX/Em"/cѹȸ6mKiD'ko2ZȧPmg<_\o.%&6Gh}n=+.9,9ڷ;mBܺ6L !˗>?`׭j/`;iVM*sĖ)#q 6y|*DEf|hJXB u$U[cyCghŔ%Os^0VwsYw8bs6LvӠfuM^_kJ-TINBl*m_r' e|-H.z#qf2rA`\a׌)>4{<Ὕť!R[.S8ۘnF;8kнG}?J9lf:X-QɈ~`I4|ryj >N.vD'\. Qr~ |SRz6^vYM7pbIuu/UV;56/%K$c$< &#_#VqRdgꁬ'km)F-M;5ZEIsnW4ɝՔ3"ӢG2SMݬAV1GcYU;Kh+0)wp&٨'SnQtDay,4g׶z۹&4_uFp}}m,SqVV5g#2~^ 5#UTy@0wj8ՐTpnFs#m IhJXZ1[~2vwBw3vL'S-$pasVWM JCZA< h3`u[)ٖeW a4c1N Qmپ,ڳe>\־26f%Yntɂ=(XVE18q }1&*i?PO r<(vD'ڕBѩ>.Dn;:jD'u^tHiISK#`a3=Y餺^G6NX ۪i6'6tDd]E9 o(:s=+Ep :'?tΣUo eo_gk/tg-{3x< ,7q0\` ((Qw!a3Ѓ8v97=p lt{ԇ+1u [}Qi!4[gK~=[l#JdWuJ+S+ 4ϧ^~/?|~X3ۉ?HfYMԠ{+<DN(o˜I56}(4b]+ԸU'22$*U2HF=wd[ލcj$s]} ZDz 뢊t6 rqoFR$ b2ojr*ɱX`{gлhyb;yKA݄R2 lȊI3טô[l9va\_w)a<+Q<'4 nYv'[@ZXɋ7q4lr!mS#31N{ovuMy7z,NzM7-r3EL*5Πq"_!7ffBlH!g(_S((273&)[<,'!@+*߄m دQ ~m}Bq{O(jx#繍npmh%ӹwN&KK4g]gXIyQYc?jێy"qն:8IupUb?+}7|:<)3|ӽr<~[Kt J]z^W' Y][eտuve;f?Rvy\*x#q*[IB0n 3ڐZ\m߄z,<6%e/)w3˷/]I13 ;`)6|F&|We9ܮv?m4:8yqlhSX(>7h'.{ܠS@={ =5V {dKm+}VVNl>qUeahl=G?ws;s;)$ N  ==w)v"N"%t9cR=ffQ}3Xz^-XOj@VY[mjs~z\ HW Vq!3Ynڸ6^p, \GxZY&YDez㦱џvoGEpf{5&CAfLSj\,W|pv qҰ3x# y!ekq2o Hy٦록Hh0Y\Mkx5ˏ]nXG6laC(l][Nl2*۳A /6CSs.!6yUs.\=/NiȦ=k;1]i0 S \-5]0Gj,; [Q3Y8YӡY"oNbZaGejkxvqd_c {$ٸPGuƎu{lf`ɪVX{~5/GI>&p^Z8biFVd.&0*+:) )នb aKoJXbXTA9V mތ.n}y&uXx^e[ Q͵ .(}qapr_HUcxOkqUE3*$1s_ Nx>V[r V\MZMRk΁Uwmң[e; ēqbUQ,O 6Gʐ&ogr 2ơ&ěy^o GòB_LfբZ/X!g7T)^/mRKt;N@QvQb0j섐kf'ct!+Ԇxy\RG d'lݬe'ȞWe'ƇyDsS'DN.y^'S S nu>( SPW DQEGe]O.~[/@?x2drxk3^U!g0´4>6;:&BTx_G* V?xUkA'/ CUS9<.ErX!*=HY~nD. x:?E3E{3aYd#!\=g:BZ/3ř?6a0cOͲ;X;#C;>ͷl^PV$/-RЩS}fcD=zT5A4%7 rc &x9 á z.UZSM٦ppg79 o7 w6P!$P!S|al'FݽˌbĦGPi'lǠpaAnAݲ1ezP>$"؄M ,Ŏ1rά?^:+]}.=>/GxQDT!~C\%$RՎa4lIDƼ9T-s5[Jc9֗}j|a[z_ Ay/OLsЗknf ^D Pƣ#^Q?<8Knq_= )cM5 wf"#lW| yo[<,[NG޽պM ?{"UwrWu!6i,7ǰpAlʓc9:<n (Ith|Y9r!.M=p:17SA S<M>*hf8VbR 8V Cf=pz.mNafyG,d^@ǠӸEg 3&)BșzV1DZe|$RxR&m1Xc$3pbm%a_% 1fTҹɾT ƞ.yR6fK6Ż.4P~$W Jgs~Ž쓯?7W Ʀ}HN Eϳm#}!7ͺ=riׇ/_6f=qij:lDyYt@6(tN?w8 B =,o}8xC9k{h Ir%>dC$P5.yE,wVM5[GL7ꗪ~h (8.Q4$m ^̄YcMHZӨ3ĸF%"V{<tvi?#g#!@D*ufA'RT,eaQWHuq _]XU&g&%l4 mV`ir쁡!*0#W.< OklwbP.U'4&3#j<[O mX+5:?e%E!\<'OjTba/nSG}y [U`cw^ G{D8I Gf1_xuu6|o#v׮[c8ܑ\<<%Px}S i@Lڠ+@MŨ2Ǟ[Wfw`$o.pyQD|.ƨS3uUkqv(wr ͌g5l@Cus5W\fcMlC/2f O4yC`LX;$fx(kDq D"Z1"o6+$@: d,Z) $Xh6u? `2$lZtYCVOf<9!`D(.\W1=O]O2S}BO_*mg˕IUҐW֋@-@UR]v䥈[ t쾟·V9 lHqլϪQi| 1/^^W KOzjJOQ-;D\/m B)6BDTx0xy +Ifg'?MwʖӆQr'›놲{0E ?x6\f^5! Z˃X#`Kψ{,|h/&Ţ}o0yʖ/fI4C#zw.X(ŵPSvڪ\9xyT2UbbM]J-BF-ĺkzڹtObZ6G&T8PBm"Ed%\%4^jT/,,iXFB°>&Y']yOl |`VfqYnUDNi[DzohۅaҜ'Ev4c<2BqPI#&&=21V_ҫ9e,7XnRQ.lH8:q0Bu'`jWč8ky-ĉ Af=Ea1 6.y]fUUEPIZ,lf4Uhjɟ#gJp14< Hsk诼9ާRJrv6o`P^~XSMଁE7/fYnlR.H?Kt^gW߇cK#<% 3969<0|s7 iXѭ@mTm/W-})qFCkn-~ sZlJޫM(FmrFO5uJ_kY4>9l d `ܱ77 ;V6sƐ,iW!:rz%t)*QdqT͋|ȿ׼7gfDڐ@{~*Q4G+_uk W$0x {!ujUeSmf.p\CNXOt̡uAZZ=J˟ҫRU8z^2HH33\̬Jع*16}R eDS4kX?fjVk\3ö<8-LU="+yrod [u{U$]pcתz7}}\4a[xKq/ʭr ~Ӎǽ /3inm0l^L5kInL /AS[noqs C@F/ܽZ $*BDfg`_~Wom Op 4`tꕥ1Ixw_7̜((7 &6~mcwfQ`f9/{Mn\xR518g5X^CWbER쉬NsC=!,8vߤ)]O~&pz^l$]s3K\g0h %ҙxˆr|樬6:R4W9 \ܲZB_3X%Έ-Po㫽Ϟ {VVݐ2~oܶl}AL GXGxW@xVG)u0 eQ0/WVN-6>śAsKt^GpT!R` 0Srs#,U 2b^T!^91te*m؋/~_EEn,& _WRJ\]-c2Ut}q2Ts\ )*=#' AkJyx:n?QE6ki e9Op jRO'g3 ƙ ̆#0ˌq_::=c| |x|`q?p%7SȂ[%I0xAUpk@'i/ؿ{R.6%!ݟN޹Lڰ{W pld {D0{ #N?.y_\_I΋;H>Y{a@*چzq0pqp98@T#ǖ1|.hʳ*à򱼨ͦ'uQ{!{xƿl#7 ')u[<2!`V]߻>|o{buCp$>xOY$|;%:Ҕ@vb d(+@va,miJ ;]k:&o`BHO^ɻM~ -A%cP:5Iޅ/.7E}̯9EZ|mZ-ךvmqqL|ңgJ1a%lWbb"+SF%2l@W勧g^֌Rh ;j!Nj0d;0` (n{/ Fk\P$^Ը:c%4 idkl&6E%KGHG!"38Pn&ݵ 8{URv+A·G>Sf?׎O vléd2r ذG3Rq2>!iobHOj pJyRd$\F5}\=$cω3O6ElY,xal<:.vp[JUVa6%>M֭_GQה uծ6U7  3'm,,ܡpv*iPتЖPb1ْb@lWΣXTjQ?X+9D-,rci5wHpHwf}M c(%H m xz>B ^I{u1Fǔ~K Q/ʐœ@b/i֢='p,j-t9pl2pP5* R2'2i@Rll-mcj RRZD)ZJc'/bl&HZw+F">Sj@).Ly⾄kY<nYf:q[hm,,0s;<2c F{1h=ti6 3jNcdL3;p|&aÞvE\ BbN %ªץ8,4( CӈZ9g؛/^ضk Cv3+Ȕ"{ͤ}hʻ;O4쩢tՖ+ K7߹q}]in+e'Sb*Jw`*m=;Ci(RFISwtgO`<[UDEhHj"(^πo"@b09'⃗ 2~gGEJCGa q 1`ͬ BK!S!H]ٍ1jOD(nŭ/$ZȈ 2%&6k-`٤'"+ P.]EQȇVYEVT5I dpnc+l~h'|g7zvh0(Yy8 Q f%Yլ$ hi4ۚW'mQÿ^zXPt/oc[PŠ瑩=ϓy-Lx:9kn`AU%Z"\WR۔Uz+Gwf Xˆ7BbQZ9bXv$bǢAm6ch,pkb4fWV hLf!f*1PBcgY-3v1*NGPA#Bc!$ 3\ 7^Z>t}+ЇǮ&>5zC˅[jdi܏,m99gqEc|(K = x &yBGhm͟=JhsQ"M n%2p7%"4qǎ쩋)=FN[p?.kجyW{6xZZ8k14FZK"Fyt˴c}Lu#Mm*%ePSF! ǬŃGšHhR%!V5Iai9cqծ aaAI]lկ%I¦R(cgQJRuA!| `77 *n|sN9Ӧ8cM#e_7{HtƥTq^4Uc +ˮA7(\rlj sZWWTpnj÷i<27ebzbY#+V4S \1KE _M=ᵶk>Zmoaʋt"-R'EL*Kݛ|w$_o( [Db/eN;qEXo[@{1&VejMSdE3@i6敄*MjeӲЫ7|İf ߷<6Y[gN0m IAy%ASn !<*lOCXV-Lg=xH6-PAm\ msq@ĦG?s's'l k~w ugijxg7Pt6eϏ_S5e\*D}?%:vJ1qa*q}w{M7߽FUe<r=r,NqXb:{׷u\RL1g,p8AECe] onӣyv=G֏M+k/;Ɨ^w_ܐnzyj`^.nta}}iWʇ(_~I)#3]2z*z$GL=ýyp82&ms2Y7A7w%_V/Bo.nښ9^ݙc X;A^%=x|ܠyzdo=tމn|n_aIӚ̑='#z<؇+$t$LБ6I*I̽y,\&YjLѢb>#S [#eҙ"QovZG=jFWa5.D%IU927Y%_&U$o.ޫ\彔KByB1Q-܅} s2EZ>Kؗ<$@qh zL=J{KAUd_'G¯'ğ廗خ۶|,VF}}m퟼b*Qv]9IMt|7JB-s̏'{''`}%|l+v M!m}߳t85SOsq_*W9,I6t$r4&$B= tk- n͏vb)?ͻMncJel};F~< /jR]._D+8E.5gGnߩ V䴭U>j;ފaTʽNQ.eDҎeJzU^' F^V!P]E38YE;V<(-a qqҳ@raXbS;J60ժ\´k޵nZGW?|[;5?yoi5l5ڜ_Wg޷ʧ.#P"SU';Ȝk o΄pf׫T<LC9K:k#f7ʕcRh0ȴڃClK!MP ֪ngr?8ދws{.ֺ$?m)ѳa%AnߛԪ%5ǎIdLI;Zq .0!A14TФx%/v}퍜}=J6cՁs AcRo*|s3_Q/4;H> ҿ\ /K2cΘ }丮#vj|SH UE/ [w2²lx;o'҅)Kj^l3/f6KX>HԨ딱 ]?_U>k.2$6NH ˢvj3Oc&kv%h٩./[/IdŤwcWtPg&AJRX{0kib}^gobmX.WUHԡ_Wgr7vUi(GƲ-Q5]ݏº0R6W$>ZW1Ur{e$ۂ$zc?X]jQL?3{ż1xine-lib-1.2/misc/fonts/cetus-24.xinefont.gz0000644000175000017500000002644014647725152016517 0ustar meme}-v^{$pww $8/kA-\.j>s=g|j->s? >.|+^\w}K}ƿ{_%ыE|WOy"5z_c,~8}˧)BGj[5=oy|Z_mu|8km{ﭖžkw2ZrxO𞈏 cD}ǟ[B'COiWnx] {9xkKN[W|1O4Y5GAsCߢ%h 0PɝI;-d]jxk*0A_kF Ī.}=s&b\07x *d`22}ЅĆ߇O2x 3Ӓ/F.T kOJ<_W|"QP(Ҍ[.-i/-Ld@/e xEY8хBcTuH%9|iDTg478;zN)W~5D f Ax \Dj&kS× &>+_EȌW2;h}K|`A;1q񝈹c.掱D8G8URg5( ~ګDYl^[t䍻j m1^\_s'7%:WƣY1khy27p[Q$ T!1-!!98,P874s퍚[<*q9Dgf 78@5 Php117y/},0k_}2ۑ#B,P(\AQ]2|NȊ_*۩w~1Otf{Jn0>YC3d;#Rxr f5u=CϽ%lBb9HZ*&}<ɤT2ĖQ(Sx5.6n@mtT(OxC0{2ʺ"cՌZ'n M̵ot9Yűcb(!G@;}G|zPc!:v+8͌C$Ŝa`-כ"Rv@]Q'#22Mm E`,rz'GٙdhIPQ:.B>qCp1Ǡ]sZNӀݮ{ :iϢP#󑡰LOA3 iZuVTWx78 |qr$Ʀ +㸴9=xL1%9R%URV AIv<Evԏn(Β059bB}w,qЗh8 "P+1@@n@棏#^ѝEIŠL 7'2`6$ňDa (փ |&{{YWg~ $?> ~6a"028*1$6]։E#"3} 7 {ӕKt)ʅtwcdj im-m}XpnLU*_c YLլ85!ހ¯_ZOe&T]%sVIA1ouID`"bk$3[\4L50gтFㆋqLH7:8FĒʨٖFy[Fkȩ{ʼ=QZ{W+?GG==FAb*5!}aWC~X؎UN}nL''pG}'ސߜK=gE[\^"k_iӗ3>4z>EµX=;tУ}`:8C~kw\͇F`FYHU9Ѣ"+6]h ؙIٶ)&3Ϣ,Nك=+1mj>/3+|3NO{ ٿ:ueAiD>ZY']I@Q3dza֔E9GXʆфr/l5!]Kput]"*E$$$n4UhrlRĊbʴ^.uGkᅌ#Fd*q4|Y<  UIevQ$4PLENTviSX oQM=Jy{&,VtE1.I@4(9{Aa#m0 % #LE\ٮV}׻ы~Ԕh,$JS@XQ05 ӑBZ\rs+Yh3 }컄NVd85^3OԭUDmv0?#:Eo^۸ôط8<^9\Z5) V9ϽQ7V/_| 蔵VqI.UMvOi0(tm6(u.8đ,6C@ڇoAgfDg0A CV#<[꩑T^e$ a.d% p|\ѭGM֥l¬ E˸{^lqg<pGI9Z4'ɳH! 莫@~;O mCs;qxMT40 ox=y)#شH,aa*Lxg&{؝kC3Nw R"u</ҀԨ%_Oj5q:Q4`܌oB&A6'QpdA$\$ $NMq~o1C;貶[[gFUȥP1!]S)⻬A %MI L}sp`mPEØ,#Fuzuj3POV%gE8!j1mo*Ñ0.{c3^5HHN.b4 tRjpʳmAd &/?>KiĠgi6ޅQIIG`DO4Kk'Um pH^*D&XRR!;5<>+ Hxg^#%MqT}3w+ĴJu[Ïz% qݜ:6O&9d,|/ëf8?>%Rl?71I.WMxіKh3 |Mi!ۜi雾7s+ׇ1DgQ&Y!H2gC/KNR< iβԥqMsZLJpmTF`6|-3aCjĪ9uH";qԪWtuOw9k/]~8޽ޖOz+' .V 起0^?;;ΓνifcC?ѻTŚJ֫dhS4UZ^U,P͖M 5|hM^1g}Si&'OCOcCYftd!WzZ6 5.ă"Mx p= i|5niOlijpEL Jsp̊/qhVZi?s&QL6u*VRѳ%sL8$6VT9VE+ݎB9߇b=7asz#)J, I%?%'GM=##" d=@0q5!uG}V瓇5YFT9/35?yurNğu#hj@&\13# ;lmXVP +xv%]bfj/#c?emlĔF &RlKe9崄)-?eM6)\,s`0>({d5` P^boQBd 0,A $t5+ό5^X0d4(:|q'#ftgS'ia].; Hxpz#LMz%#UL/BњC4r9oXZ] DW,Q ()QX/l/kegV\ HBQ^dBV*l΄3'_LD>%A4K3#V4 DNՊ>tg)._g( 1\Ui@z /|5NjD-RpHd ͅobH}^/zD4-sM@AWV LךV1b,T9H wgJp3(Im?wkȟsCJxKҮ' 5fVhfj584K @:5H '| uw\(;lU PvWaۮW%oQbs3S]pf>x1S]e_-[nM#viP)LwRd‰n`\C+4wNXt'|;1w뉵OD8FSx’8X^{|z94_2^+7%]}Px&fV1h@'7"B12+>/VmKCc1u%|gļ<cRhYh,5p{Y0{ڊ)!k Vht+Ġe' =a~ݍNI+W 2.I00\(VZ(pSU!1FjY{t7I6ҕ$~$zT44YT{@`5rQۛ=_IE֯@5!%;%+c`Utp  2}XILҵaqEaF!Ȑ(_W4pIX#KVڹNJ ))6Ȋp8`8+Y8*U;P3b3 !0NC:>eo|M#Ģj )  tH W6ao Dޥ )+BBܙ6InF~yggC#٨`Ȋ % /Ӫ¹s}3]my}y6b6UZ b79,Ro 2]Cn"5ǐqDM1MccE1=I2Ų$)CMK5}/Xwtd A'&UeȍzXSA@imaȉ>Őˊ=hFbOb8øŠ'OCORzݭf^{5^M"t{'Oٞst9,9"F%B' T:9>O{M!SUW]ke9mQXZL6Y14nΕKu2 _EO~ױo/wxKKSCSBR]Irݦ 2^}zyc12WBbJ,4(_= 2ԀULp/ͅK|-Pgv.Zz#-pnD`߸%dϼ DAWW'/ IJK)~ϛnpxDf=HuVuvIeoL ®PbFibFP:'>^@DKyxWam!1zn#W3SJ ^ VeR9IaHu{W"B)=ZEZdSwW/1|AZJFGʾqfHic]9 _>nO3m\Vс@IzThڙJ9T/*>T{"xsj.dHZ׃\I"8AB;9F;;>@_?BAHkgt\?JhobYA/S{q#6n Κ.3\N,:I*p+ei9pV}dk/r[X6 l6]??S)=} eV!fרV_82ϟdyAo^]=n ? s[vj~Phj!x`5!y{\4$ThҐ=n ?q,D6|U-Tlʓ ?ic¼ٓ,6$I9 6ľs_ݒLftَ(&J6!䠻g4п,{nSSЭx+̫HPj\BoUFإ6|K7K5D%\U(u=n=E'[9.ZO]'CxY_vE樂J5c;YXZd#)PiNdDZEgZV<*r]Q`|j} iwq4:=v}O]aԅElm_|aB'!Rkj=/r(by"jre2OP7@6\ۉZF#CVpgۤ`זּ/9s|>' $ sz{.oTg!EdR1Xʆ@t=_})gdny'/핐ϹiLX -4E'/A>랚]%{ iRp{QoXTޣ4=_ag~&l6S!2 7_߶dʚ <>ϸ-SS[rb?]Tsh?_`O{( GWDQ*6:iwðʿ=Srs@hq38ʾM{.Ovpl08yNǿJ_`Ğ`]/ˉY.x.sɜQ|M~k 1E뢚#ɺɥ9`6 b:ٕQ릍Rp;1"_CHRI;`Sx/=Zg{ǎR 6/HPZ] 3w*ł5\Wߓb>#bن2],66&Rc׬[JyUK],n+GZx0a:uםF݋fW;_xd$v`^r?XapӒ@5@[ / >Vxc*Me4EPjtGk$Kz+AH`XI &ϬY,$ݼĝrsfmy9wcCd=VDeT+~x}` U2م.sZ b1e6s /dsl9gcn9V996BONmx= 3(]V[9n>2j8kq=Pak;|}_y2t&'CMSZm6Ffht`RM*ٙ2tIl A=}unKLZ8czmtU@Kz$k43T^Y\9(@@Xďv1`nĢ+V eSy}jF2_m}7朳,s"K!G>9p4MDMu剪LM*!ͪ"HqR CMFTglwǹgs-ԑ i R~a9l'l$ʊJ= x9.4hs9~k8G<lj3qs|[3(C{$>뎉8o%э΅x# ן F,ԊFjI5u*bAhkuRmʙc `H+M|1 BbVh#f+@ԚV&1@\=MEJ$@;TڞRACb8Rbuf2)hu8w%?3646ėȈ{u.NYr=d FN U tC3/Y*ߢ!'FV[KYnYwrtGnv5n:_^N(,J&]xOcmӨGȸ a]FEW/3^lx~ 4"es;MTyYZh.LP`b0@:F[ X3op.H<\0 T(GM]BٱԎ:R^x(_g5/ds K&@vك%HFR?E, ss*}p&?Nߟ2>?~ŢbZ>8 wd3)x}$>(n:WsxL`b1օBW iwahv:.6N9Vʢ!Q2:g+h`BhRf8٨.|cǘmY+Nmt+v9JmEo2`bQJt( 22$QӑC4 .[l'Jdd!m,_׎7OMF0QfRMcٿ9   (:nn5`^Q$;f"Gv$PBk|wRJ1 a@P51Q)8?#8i xine-lib-1.2/misc/fonts/cetus.ttf0000644000175000017500000157741714647725152014640 0ustar memeFFTMCLGDEFl`GPOS`S/GSUBP.OS/2㢕cVcmapr< cvt !yEgaspdglyfm70eheadB 6hheafD$hmtx|:0locaE:N ,$569h"*(.<*$()$($9,,ZZcY00d8SSOOSOOcO,"Z?0OOO!AKS &O[0c@OO<OROQhOO0S ,*,$ FFZ,(E,"7F7FF-FjF.F,$-F,6<=BFFFF9F(FF,(,(8F"BHFRF8A7F,F &,$([,6cZFccZF?E0"OFO:Q9S,FSF%S:F0c< 5 5<OFOFOF/*/*d?E,O:!-FS,FS.FOFAKjF,*,* y"Z,(/,(/,(?E,0"c  O7FO7F &,$ &,$ &,$0OFhOFOOSROTJ?C?]UB#JL3O/-o1 [(JBJ*JOJ-Jo<L*~$ 0'MO5MMMMAA,J<#EI&<L*^,?8DF0!B-<B,+*GB$(('(+ I I5,E#AA&#P@bGwI,E! `LU+LC2*!FZM FOIIFFIFF&>FnF:O:V&n?>_'o?`=:&&9X%o?m0>z3_=K$?98? N3^>#%<#X8423,jjjrTrW>>>#9>kkmIdspXakk>>~Ikc>1>=E#X<E X  Kk8c_4*O( 8A*2T|L!M,^iG ,   e*qqwqws?Y?q?X?d?M?e?d???mj,U,"R%RtD#s#e:+ O3} ?- Hy+w@ya/d  Rt9(AM191`$yy(! m+e@_0\@eYZzuzvqpelrf]B-" ! |!nn@S r <L3 b obYfz #hYs lN;l?l%5 <, &-r)t.O_) >, .0xv)\<:D5D4?55 <l055! &,L3XXXXX08/S} D P - - - P  :1_ ie [ ey ( $ }TT     Mv[  qlVlOXr>:DMUq5F\c Kb= H #=H ` ` = m l l @&O=@7O2 -@2@7`-@-PK<l<</<X<S<<}Pn<U<<Z<[PPK<o<YP<O<W<,<[<NP<T<P<TPx<Q<tKoxv,*O,6O,6O,60Y,Y,Y,U,V,Z,(Z,(Z,(Z,(Z,(cZ ,,S,;S,FS,-,S,FO:O:O:,P:,,P,PAKAFAKAFAKAFL,FL,FL,FL,F &,$ &,$ &,$ &,$[,6[,6]ME]M;]M;]M0"0"0"0"0"ccccU,AU,AU,AU,AU,A   ccc,F,*,*,*,*,*,*,*,*,*,*,*,*Z,(Z,(Z,(Z,(N,(Z,(Z,(Z,(d]_9 &,$ &,$ &,$ &,$ &,$ &,$ &,$ &,$ &,$ &,$ &,$ &,$U,AU,AU,AU,AU,AU,AU,A    T0T0T0T0T0T0T0T0AAAAAA'''''' 0 1 )   08CGccEc<cHc%c-,$,$,$,$,$,$AA WWW)W((((((((A$$$$$$$$AA'WWT0T0'',$,$(($$T0T0T0T0T0T0T0T0ss$$$$$$$$'T0T0T0T0T0T0T0sSMxM M AAS(*M 8 ),M ((((6969((  AA MM $$$$$AAAA4MRMy@M.M.,,A@@@M0M1M/M1,&,&^2^FWs P 111111M[MUnb,|,MRNyNXMBMB|0__________=___a____[]e<,!!g):j LR? 4 O"o2-ccZ8e=ee=eeee=ee=eeee=d,dBddd,P0YAKBBBB    BD,AF [-1[-['-[,,+Z,+  H7H-H-H7-7i7i$)H(H2H2HkH[[((,ddd,__%HKHHHHH$ H-H-HHH7H7+++7',,d,,|||||||k,j!+7+QfPdMX22PVwYzvZsb_?R1(~`ja:aMU{__rUU@L++{__XmNae)`Wz MM8kLvzSMmkMiK}mR1_?nsVqRlNZ9yrvcl2N..nnaajLLI((ZdtQ]o_]oW]LL,+,", ,,#,+,.,%,&Mt,f,   , ":1:K%z:P&h? 9R%i?%#H2<<<<:::O:V&n?_`= &&9X%m0z3_=?98?N3^>#%<#>O:&98?H#)&NS'pA/iM' 24 G&-!# T 5 0MK/:w#2"5xFxY|O   } +8:8:r+++++KG]q!:!VwX X  ,1`?n?++!-Z-PP@@  nmq  Dh~3   gHk[[+yy+.VX_HjjezSCO O/Hhh0%%   .F:+O} ?--  +pq+t+ rq    ? q  x _CoJ$3* CGt:+ O3} ?- Hy+ yyWaa n2FHcq8|ULL& a \vuo?]c')B'iN)g'>>|)C|2bxjjrtJ**jUU  5]Jj5](u# = &!|||LLLU,LD([8c?z]s*U QY)*; b(.&bNE9EoE8c(EE9E3E[b& A  r H uK;,(v,/./6h[Q*^KXh[[u2 Bm+*%5)L\33\, NL42,G:<01,T$q0`.^)V2[/X1*K*Kb obYfz #hYs lN;l?p% a T 1 @ > [ B g RQ1rr{uojmugZ hZ]Cl aa_a~3Y\j 3>QWauz~_sV_ ,J 9 M U v   ( 0 3 6 9 < B H M \ ^ t        ! + 0 3 9 C G ` o EMWY[]}  $ & 7 = I K q y ! !!!!"!(!-!3!!!!""" " """"" "."4"<">"C"I"`"e"s"""##!#$"%K%l%%%%%%&,&j'A00000000jA6<>ADO $P[^m"9QWatz~r1Ya0  ; O X     * 2 5 8 < > G K Y ^ f         * / 2 6 > G ` f  HPY[]_   & 0 9 D K p t ! !!!!"!&!*!0!S!!!"""" """"" "'"4"<">"A"H"`"d"r"""## #$"%%P%%%%%%&,&j'@00000A000h98>@CF{ztpNMH61( sqpoJI>)'$nmlj`_][ZYVTRPHDCA;:643210.-)'|yvuqmlca^}yxrqMKE('&gM"!  T56YUBA=<ٿٺٹٴ!K}    !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abctfgkzrmxl I 7u J Kiy # / - =n~ep 5V G &od < {ALsHIJ|MKB!y,,,,,,X <\D`x\d| @h $\  X P l 4 d T H l @l4PlT`\ pPH(\ $tX|0ThtlD| d !(!<!T!l!!!!"""""##,#D#\#t###$ $$$<$T$$%%,%D%\%t%&$&<&T&l&&&'t(((4(L(d(|((()H)`)x))))* ******+L+d+|++++,,,,,---4-L-d-|-.0.H.`.x..../l/////00000H0`0x00101H1`1x1111122$2<2T2l2222233,3D3\3t33344 484P4h44445L5d5|55556`677 787P7h7777789\9t99999::l::::::;;,;D;\;<0\>l>??p??@\@l@A$A|AAABTBBClCDDDxDDE4E`EF4FxFGGGHXHI0IIJJK(KKL(LLMMlMMN(NNNOTOOPtPQ8QQQRRR(R@RXRpRRRRRSSS0SHS`SxSSSSSTT T8TPThT|TTTTTU UVV(V@VXVpVVVVVWWW0WHW`WxWWWWWXX X8XPXhXXXXXXYY(Y@YXYpYYYYYZZZ0ZHZ`ZxZ[8[\\h\\\](]@]X]p]]]]]^^^0^H^`^x^^_ _t_```aPadaabPbc cddpeeelef f@flffggtghDhhi ilijjjLjjkkDk\ktkllXllmhm|mnnnno o oHoopDpppqPqhqxqr\rlrrsspst(tu8uuv,vPvtvvvvvvww\wwwx x x4xHx\xxxxxxyyy0yPyyyyyzz0z@zTzhzzzz{8{X{x{{{{{{||0|D|d||}} }4}H}\}p}}}~~<~~T$Xhx(@P`4DTxL\l8,D4|`H,<hDd 8P|8HX,<D\0@P`,<lPP HX0Hx$4Xhx@P|`P 8(8P`h ` th\@@tDxDp L8p0`P$<THP8x$|(@Xp x,D\thP88PD°Ôd8Ũ`pd$ɴʀ,Tp˰@̬lͼdΐp$DМ dѬDҐӄ4԰ՄְPלdـdHlۜۼ,`xܜH`xݔݬ $ތ@߀ߘ߼0 (l4 P t@lTd \ `d@<l,Pl@xL$X \$\4XpT|@l,d   \  @ 4 4H@  pH@t(p(   !!@!!"D""#d##$$($x$%%<%X%t&x&&&','p( )L)**+0+, -..///0`01 12023334\455X56$677l78H89\:;;<=(=>\? ?@AABBCDCD\EEFG(GH(HHIhIJDJKKLLhLM\MN4NOHOPPPQ(QdQR(RRSS@STUTVVW`WXlXYdZ[P[]]X]^4^_<_`T`apbbhbcchccdde eefTfg,gghh(h@hXhphi@iXijLjk<kl0lm mn`noHoptpqqrHrssxttxuutuv0vwLwx<xxyy@yyzzdz{{x{|$|},}~4~ XpLX\LD`LXL,HHL x,8( `H$|0T$\ h 0h ph<xdX |4Hl tÔĄňlhPDʨ,ˌ͠μPϼtМDtҜ,XH $dpx@@h`x4ߤ$h8@\pp04$x@,x@xdttxXtXHt,<@D, H  `  \  l   8x`P\t$00,x@ pD0H`x 8Ph  ( @ X p     !!!0!H!`!x!!!!!"" "8"P"h""""""##(#@#X#p#####$$$0$H$`$x$$$$$%% %8%P%h%%%%%%&&(&@&X&p&&&&&'''0'H'`'x'''''(( (8(P(h(((((())()@)X)p)))))***0*H*`*x*****++ +8+P+h++++++,,(,@,X,p,,,,,---0-H-`-x-----.. .8.P.h......//(/@/X/p/////00000H0`0x0000011 181P1h11111122(2@2X2p2222233303H3`3x3333344 484P4h44444455(5@5X5p5555566646P6h66666677(7@7X7p7777788808H8`8x8888899(9@9X9p99999:::0:H:d::::::;;(;@;X;p;;;;;<<<0>0>L>d>|>>>>>? ?$?<?T?l??????@@,@D@\@t@@@@@AAA4ALAdA|AAAAAB B$B<BTBlBBBBBBCC,CDC\CtCCCCCDDD4DLDdD|DDDDDE E$E<EPEdExEEEEEFFF0FHF`FxFFFFFGG G8GPGhGGGGGGHH(H@HXHpHHHHHIII4ILIdI|IIIIIJJJ4JLJdJ|JJJJJKK$K4KPKlK|KKKL LhLLM(MTMMMMNNOP PDPPPQ8QXQ|R(RxRRS\SSTTTU U@UdUUV`VWWtWWWWWWXXX(X<YYZLZ[<\]^p_h`X`aLbdTdddeefgXhijjHklkkkkll$l<l\ltlllllmm4mLm\mtmmmmmnn,n<nLn\nlnnnnnoo,oDoTolooooopp8plpqqqqr<rrs,sDsstDtpttu@uuuuuv4vPvdvwxwwx\y$yHylyyzzPzhz{({x{||x||}H}~~@~t~$\p T (D`|P$D`|$8L`t@l$8L`|$@\x PLhDl4Pl,`4Pll (D`|0HT`t4H\xh LH `$p,@$<\ld(T(<¬à Ũƈ,lɌt|hh@LDӐP֬ װPDhی܌TP(|$X40h@P0hL|@d044\,Dh ``$80($|l4Dd \ $   @     H   T    d  P4(@Xpx8`p<LH@th\TL$p` (  ! !"""#D##$\$$%8%& &|&'T'p'(@())**h*++|+,--.../H/0012L23@334t45T56667l78`8|89|9:l:;<<|<==>>T>??P@@ABdC$CDEFGHDHIJdK8KLM0MNOP(PQRHRSTlU,VVWlX,YXZ4[,\p]L^D_L`pabcde`fHg,h<i\jjklmno(opxqTrtsu|vtwdxDytzX{H{|}~40L@L Pp(8$Ld h,h ttDT (|T\D< |P8$ĨXl@\HDxTѤҀӤh8L xT0@ |XH`@hLt4L(XtP   p    t<`P|0XLdh\X 8 !"#$`%\&D'\(`)*+,l-./H0,01234<4567|89:;<=t>T?0@@ABD$EF<FH<I,J@K<LpMNPTQ8RRSTUpVX\Z[\]^D^_`(`abdc@cdldetf@fgxhLhijpk kkltmmnnnopp|qqrrsst0tu0uvw w|xxy0yzzz{4{p{|8||}<}~8P,@pL,880H4x0lt d(dx,h< DtLP`l|X@`l|d<\<,\xDD(ĀXPƨ,ǼP8ɔʬ8˄l̈́0LΔ(hψ`4Ѽ0҈Ҹx@ԼՌ ָX׼@pڌPۤ4T ސ@Dd``L0` ,,p0P8h @<l(x ,\LLl( p|     T  0  ,   8 DH$\`l|X@ X!!"#D$ $% %l& &x&'H'(8()D)**d*+H+,@,-.8.T/$/|/0T0t1D12344|5556p778 8x89d9:@:; ;t;<,<>>?<?X??@h@AB(BCDLDEF<FGtHHIHIJlJKL(LMdMNOOP8PQhQRSST\TUUVLVVWLWXXpXXYPYZ,ZtZ[H[[\\]__` `$`<`T`l``````aa,aDa\ataaaaabbb,bDb\b|bbbbcc<cTctccddee\eC!!!oN /C| #'#5'STRhh41 3#'73#'4]']'ooo3#3##7##7#537#537337#3$]jiu'L&|'L&erly$L$}#0| }DDDD 3# pp[ $02"&46"32654&%3#2#"&46"32654&HcdedF)<<*)<;oBuBHceEGddF)<<*)<;dIEdeeF;*)<;)+;^'VdHEdedF;)*;;(+;4} ,5%#"&5467.54626=3#>54&#"'32 '*= \qE]/"d\?2Eljp&;Y$]]$Y;&2 ##5#5353FF FFWmh 73#5>=#Wii#32#"& 3265+.@;!wqrvvJFWYM0ܐf[#5>73#f>:X? .R;"632!!>?654&#"2e~dA8u(Ro\`P< t\R6#B-Wu?47U9L $"#632#"'332654##5>54&L9Xesc@8mXHHEN% _OCxSEh[l'ODexMJKCK,A8A %!533##5GBAiiXު]4O6#!!632#".'332654&#"#;Hfk)E-%XrHSTG):Q5W+ip)/wXLO[%+%4>32#.#"632#""32654&+"3G?#Qk X >.LQ:i_zeARR>=PJC^R3bW38O~chSBD[WCGS. #67!5x^(|JϪ W%("&547.5462&"32654"32654z҅y6*ww*spCC87D9RQACSu:waz{av:"@1SjjS2@=32=<24M|NM?>&##"&'33267"&54632"2654&"3G@#Qk X >.LQBze=PJSRk^R3bW38O~chMXCGSTAE[n 7#5#5hhhhhhhhnm #53#5>=#hii#< hh\x&&4 3#!#  2oa!5!5aFFFF  p M#54>54&#"#4632#5%45%Z%54%F:I8UolatZ%.J1-9 /7%B00=#3?RJswhhh 3#  %!#3# Mcxhepx')LOo%#!!2&4+32>54&+ova(=Z-eF?}/1>D?^r$;;p/T+49E04>32#.#"32673!".00GyL+_^Wj{mZ``!KwG/d2bjO4NNej3Ni`Y3!2#'32654&+YlpplRZe !!!!!dLRRRZC #!!!]t\LRR,$326=#5!#'#"&54>32#.#"$9^]!#&=4&+#!2'4&+3262/q:>]Pks6+LCJEhGNLG.IAC?e^>RH6<0m0%2>54/&54632#.#"#".'3V8N%x~X^WJY6BJQ(>gA)KN8%X+U;*)S#0%cswkGMD7*01`C9=. #7\<64Q##5!b]<yRRU3#"&533265(]]eUXdnoOOTJ!#33ddci !# #333ffhdhWPP # #33sqqov0vc #33]socG !!5!5ELfTRR5Rc  3I  #/7c  #Icp  ,I3# #IEzyE,PB!5B~22P#'`<䔔*)4632327#"&'#"&54>7>=4&#"26=Aad- #()T^O] -<$1&=8:<SEXeJ<6qIF)? %(MTG& &(-0I*^  -P,6 3632#"'#"32654&6S9ihx|hk;KBPPBDUSVZCoooY^p#.#"3273#"&54632T@4DMNEkTp^k}j[m\7;ob]j~`kb#5#"&54632"32654&J"O6jz{fl5DTTEBPP'E1+}Qp[\on[^o(%!3273#"&632!654&#"~+Sf#TvZnmJq&T=?RH(DiV`J@7,AYW###5354632&#"WSFFA: : D8DY8?E5R&("&5463253#"&'3326="32654&\|{db>M0_I\nUqT>#K!CNNDBLK}[LJKeV*TJX_a2,n^_mk^bmF4&#"#3>32#C)@NSS%K8LYSk70aP0'MBtB#5#TTSii &#53#"'53265SS &iimG': 73##kgQSU޵PD#T'F!3>32>32#4&#"#4&#"#FM"K4a,%H4IOT3.3HT3.3HT J/*P,$KGwi27P9i27P9F3>32#4&#"#FM#Q:LZS:2@NT X70NAtk/8aP$ 2#"&6"32654&q}np}~oFPPFEQOMmmm\an6& 3632#"'"32654&6M;lhy{ea@BPPBDTSO^}NoooY^p&##"&5463253"32654&S9ihx|hk32ATTTM$C( Jg _;3"$732654&/.5462#&#"#"'z5E7C&+N]InbXf3<.3PNFuc/7-%" C>IWTMT+$# E:LZ#327#"&5#5353V'14GGS DF+(DA !#5#"&5332653K%P:L[S:2ANSI4,NA/8aP)  !#33[^^ W !# #333*_je^\kdfgh^e hh #'#373$a__~~^ & 3#"'5326?3Z)^ Y l KSh !!5!5EV9 JIKxI 1!5!5![.ȅd,3#d<<S 1!!W K "#>32326=3#"/&/571u590'*bsNFKE!%:E?z3 J 4t673#5.546753#.8`TjW*euue*XcT9XEg tZmab wz ZYcV254'#53.54632#&#"&3C;?!h(+*9J+#580E8nQ"e5>,X@M ,> 7+'RD'B8.%B;V.&(791![{ 1W9FC'&%'#"''7&547'76327'"32654&:5(<5)380 687,5:(;97,>?,+?>65391+;9-7575:7)42/>V==*,> !#3##5#535#5333着XUUb3M33M3cBd,3#3#d<<<<oo++4?32654/.5467&5462#54&#"#".57654/=)+571+27,kaT5,&3 =0mkP.4'oII' E50&2&u"J12G33E`bO/70%"^'J6s)"4 H`*J0{'?=3m-<(d(#5!#5h hgggg%0#"&54632#.#"327 #"&54$ 32654(!@(VlmX#G -(9DE8V<ᢚ8@$fi2+]OHb|ߞ✞%/M#-!5%#"'#"&5467>=4#"#63232'3265@"/1808DYC";~zTS.9%6b33_,++4,11 , l^z /(bj 757757bjj5jjYzSSSSyYzSSSS(V w!#5!(FNw.8#58HH)4#&?4&+#32'3254&+& #"&54$ 32654O"F΍K#(=<ᢚh;35 &'($ ~"*C# ߞ✞w.!5.FF 2#"&46"32654/>YY@=YYfN87&(8Y>@XZ|Y98&'87('2o ##5#5353!5FFFFFFF"#6323!>?654&$>@R`?! 3H:;1 F8R/ #:IL& / +B%"#632#"&5332654&'춮&.#?@K9GUFHO>,-*0 3@.)-,@8;L=IJD.++&'3# $\P-3#q<A$  %#"'#"'#33265332 !S;h6$SS:1ANS-1? SS/8aP)L)0O .546;####an^9@R@^e@JW.#5|}}'*2654#"'73632#"'<2.. *& &)B9/N %\8# +2"= #57>73#c6$ +>D.0W(/D!52"&546"2654&:DJKKKC'--N-,b33ZTOZZRQZ4@78@?79@bj 57'557'5llall=YzSSSSyYzSSSS=Q #57>73#3#%#533##=c6$ +>:<:.CC>D.0W'x; 5d=L *#57>73#3#"#6323!>?654&c6$ +>:<:$>@R`?! 3H:;1D.0W' F8R/ #:IL& / +Q%)47"#632#"&5332654&'춮&%3#%#533##=.#?@K9GUFHO>,-*0 3@.):<:.CC>-,@8;L=IJD.++&'3# $5'x; 5d`' $] #E&#D&#A&#L&#l&#J& %!#!!!!!!#Ug+n`dRRR(_0*5%2673!632#"'732654#"'7.'.54>32#.#"zZ_`! &)B90M6. 8[h 7#332#'3264&+]]hxrYAIIA½xqc[uRDxDC;%254&#"#462#"'53254+&OIP>Xy܁!4@r!q3=HFYkbR"6$ f2zK*"EsF*"DsF*"ApF*"LqF*"lpF*"JlF"M0<C%3273#"&'&'#"&54>=4#"#632>3226=%!4&#"01e%TvY:^ 8e;L\*FGf$vp Tʀ/\6IpFZgG86&P@?R4K%iUa,':4TG&9$ N]R&,J@7pQe  ,('-GYW*3.54632#.#"3273#632#"'732654#"'5N&j[mT@4DMNEkTt\ %*B9/N6.  8=P,b]7;oc]j^m!# +2!) %("EvJ("DxJ("A{J("luJ"EA"D"A "l$*4>32&''7&'77"&"32654&$-<8'';a$U4,%Ja(Z*F+"||FPPFEQO@e<' (1-'(,/-%)#MLs>Rmmm\anF"LtS$"EmT$"DnT$"AnT$"LnT$"lmT2 !5#5#5&hhhFFhhphh##"''7&54632732654&#"?,}og<= B0~oeA:\+?FP)EFPGIm>EJGsAA0m_B 4m_DA"ElZA"DlZA"AoZA"lnZ&"DQ^6& 3632#"'"32654&6S8ifz{ea@BPPBDTSP}NoooY^p&"lV^g#C&*"CnF#H&*"HnF3#K&+3T4?632327327#".5467&'#"&54>763>=4#"26=Cad- LH&*:1%9QaO]%(@5)1%u:;QEXeJ<6qIF)?=7 - ,!( CMTG"3" N-0I*^  -P,0#D("DnH0#A("AcH0i#I("I\H0#B("BgHY#B)#qI #53!2#!326&+3YEE]kppkSCCSC-!3##5#"&546325#5353"32654&??JFbf|{ea@SDTTDBPO5;R|N5LnnlY\mZeg#C*("CsJZe#H*("HrJZe#I*("IqJZ3#K*(4+3%327#"&54>7#"&632!32?54&#"&)(&"&)?L(pmJq~01e%T=?R)B,(0 - 0($J@6b4K%iAYWIZe#B*("B|J,cA@7 ,&"AXL,#H,&"HaL,i#I,&"IXL,#E,&#`LS#A-#AM'!5%53!533##!##5w,]w],,]^,ZZHFLF4&#"##53533#>32#C)@NS??S%K8LYSk70aPX5LL50'MBt0i#L.%"L g#C."C*#H."H3"K.3"KN_#I.^ #S  dr#/.B&1#ON #A/&"A O#\0:#\P: 73 #%#k0gS  F#D1@#DQP#\19#\QP#}1D1#qqQP#{1D#{Q( 7!!573{(PP]yLzR9M8u 7#573BBS??S3@392@2`L#D3F"DzSL#\3F#\SL#B3F"BtS0s#S L&%3#"'53=#3.XMG DvXeT58Q=1jF&#"'532654&#"#3>32 &:2@NTM#Q:LZmG'/8aP X70N&g#C4$"CkT&#H4$"HlT&#M/4$#MT+-4>325!!!!!!5#".7327&#"+(=RM'y>HUNCu(MR<'])94};;|59'dXT6XLRRRJ^5QZIn?' xex'@n(*1%3273#"'#"&54632>32$"32654!4&#"01f#TvY>?q||q=e=Jq،PPFEQX&P@?R4K%iV`ggj28J@7pm^`ml^a3GYW]#D7EK"DW]#\7;A#\W]#B71P"BW0m#D8""DWX0m#A8""AVX0*mH%2>54/&54632#.#"632#"'732654#"'7&#'.=3V8N%x~X^WJY6BJQ;wT&)B9/N6.  ,YgX+U;*)S#0%cswkGMD7*01`C(ED+ # +2"( %E[64"*>732654&/.5462#&#"632#"'732654#"'7&'z5E7C&+N]InbXf3<.3PNF4.&O&)B9/N6. /7-%" C>IWTMT+$# E:/N # +2"( %G0m#B8""BTX*Q#|9%"|YQ#B9#4YQ 5!##5!xw]<eHH"yRR 3##327#"&5#5353 V'14GGS8HDF+(DUi#L:A"LpZUg#C:A"ClZU#H:A"HlZU#J:A"JjZU#M :A#MZU3#"&5467#"&53326533279L"'9,]eUXd]%44%H%04)/ pOOTJ4W9046 - A4  $327#"&547#5#"&533265#*$'>J`%P:L[S:2AN ; -2+>1I4,NA/8aP)#A8<#A\ #A>&"AV^ #l>G#D?"DZ_G#I?"IP_G#B?"BX_3##5354632&#"SFFA: :DY8?E5-!533#632#"'##5"3264&YS@ae{|fbFJ?$COPBDTTLL5N|R;X5m\Ylnn0* 0%2>54&+4+3%"5463!2#!#"3263J1>D?F{=G~=Z-eF?vaR1 R+49EM!1N$;;p/TB^r:OOo6  "32654&!!632#"'BPPBDUS9ihx|hk;oooY^p3IVZCo732654&+332#!'@RQA]]dƀRR=@PhxfcË  "32654&3632#"'#'BPPBDUSS9ihx|hk;K]oooY^p VZCË0 (0(4>32632&#"#.#"32673!".00GyLHP _^Wj{mZ``!KwG/d2bjO4O;ORNNej3Ni`.,"632&#"#.#"3273#"&54632R T@4DMNEkTp^k}jT>ER7;ob]j~`k0L!%32654&+"5463!2#!#"3263glppl{=GoR1 Rǚ1N:OOo754!35!5!!".6;#"Ot=Y-] 8''8R'+EF:.)-,6  "3264&#5#"&546325!5!&FSUDBPPK;kh|xhi9p^Yooo3CZVI%;$ 6Ze !5!5!5!!5!sdLRR'R/0m/".547&54632#.#";#"32>=3MQv<ix~X^WJY_?XlC`%N8;U+X6Y\+GG&}1-lcswkGMD7.[RT.)+47Ji5&C!!!!#"'532Zt\QH DL%RRG58Q&##"'53265#5354632&#"W &FFA: : DmG'DY8?E5R,.326=#5!#'#"&54>32632&#"#.#"$9^[cEgI>K57FA+#"&54&#"#3>3232>54&'7/714C)@NSS%K8LYI-F&5Hf1?';d+(/70aP0'MB/#1=+.t3&}; Pv:34632&#"73#:A: :kgQe8?E5޵PM #5333##|||T}}TSCCC,"273267#".' #'527.#76*:o0!! z`%6 !$5_LMFb\tMbR @ !#5#"'#"&533265332653S"K4a,%H4JT_/-3C_[3C_J/*P,$LFV27O: iO: &33##"'532Le}XiMG DL%T'OD58LF83>32#4&#"#FM#Q:LZS:2@NT X70NA3/8aP& #"&632.#"!26^pm ԌaVԐ}|Fu& ""2654&#"&63232>54'7t菎>lB @%k=򥤄΢V$$ 6+8]a$5w !"32654&7#"&63232654'FPPFEQO%\%np}~n8R mmm\an+8VEg# & #"2654&#"&632632#4&#"t菎qVT`SI^%&*X򥤄΢V8=gTM5i$8 #"32654&#4&#"#"&632632FPPFEQOHT"'#4np}~nT8@>F@mmm\an]M'*I|))I0#3264&++##"3263#"5463!2gCKKCq[]R1 {=GluDxD]q:O1No6&  ""32654&'632#"'#4632&#"BPPBDTS;lhy{ea@T>9 :oooY^p^}N?9>E[!3264&+#332#&=4&#AIIA]]hxV%"q;=DxDxqct:JOL> .IAC?0m0%2>=3#".546?>54&#"#>32G;U+X%8NK)Ag>(QJB6YJW^X~x%N;46<\7# .=9C`10*7DMGkwsc%0#S)*"$%3#"&546?>54&#"#>2326sXcuFNP3.<3fXbnI]N+&C7E4ZL:E #$+TMTWI>C "%-7G 5!!!!5 fmTRRR&= "2654&#"&4632327#"5i%%2%$2II29B& $$$#IdHD8T'Gm&.5#53533#327#"'53265),GGSVV &+$DDmG'Q4>7!##+"327#"?2]+R16 {Z4+RytO3#327#"&5#5354632&#"VV'14GGA: :^RDF+(DY8?E&Q#5!#327#"&54'%]eUXd]X+8f SnoOOTJ Ao#5#"&5332653>54'J%K%P:L[S:2AN]+8kHI4,NA/8aP)  U".5332>54.'3N7MM(]((2WP.4)+l,aJ - ;qN8ciDA'>323#.#"% !A-s]  iO @cE"&$!#"'5326?3632&#")^ Yr)^l KU hAl KG3#!!5#537!5EMWfTCRRCR 3#!!57#537!5{SEV]} JCIKCI E7!5!#"'332654#52>Ef '57|X Qj ҵRT .P8dyMAK  E3"3273#"&'4>7'5!! jQ X|75' f KAMyd8P. TR q '5!!#"32673#"&546Ə܏0NEHHXmaJIKCKJMxeXc"6 ,#"&#"327#"&543232654&+57!5!,aW=6Wb $%.aa`\0aSH0Pb &E LBO40+;KIJ"632'!!>7'57654&#"2e~W(A8u(I_S'`P< t\{O$MD#B-Wo|9"MB7U9L@#%#"&5332654.=#53533#x]hsO?H?H&66&GGSVV&66&]c|nD^8:)5=.DD-"&D6&  ">54&#"#3>32#O'? 7*haTT=_NBW".5:97/h9$A6F"))P;%^N#E<;10&$d,ad,"ana2,33#3###535#53<<FfFCFfF|Y#A)Y#B)#B,IP#/,1P&#O,1D&w#OQLn#/3L&k#O3F&#O,S#B&*"BpF"#B."B&#B4$"BnTU#B:A"BoZU#sCA9"sm|UN#xjA#xUP#BkA#BpUN#EjA#EI( J)#sC*9"sl|#s&*"sn\ #s"M#s,-3267#536=#5!3##'#"&54>32#.#"$9^M $5kL\nn^_mk^bmX(4$@2,}[LJ[3468TJ,#B,&"BZLO#B0#BP&##K4$#"KTT&#S#s$#"sk E#B{ q"BU,&"B Y#?)Y#_)#_,I,#x,&#xLL#E3F"ENSu#x*#x #x"M#x=#x #x#]&*#]F#_&*#_FZe#]*(#]JZe#_*(#_J/#] .##]*#_;.#_/&#]4$#]T&#_-4$#_T]#]7h#]YW]#_7-Z#_kWU#]:A#]ZU#_:A#_Z0m0<%2>54/&54632#.#"#".'33+52=#V8N%x~X^WJY6BJQ(>gA)KN8%X+Ud4.77;*)S#0%cswkGMD7*01`C9=. #7\<64wg8A&N"$0732654&/.5462#&#"#"'3+52=#z5E7C&+N]InbXf3<.3PNFucd4.77/7-%" C>IWTMT+$# E:LZg8A&NQ##5!3+52=#b]&"sT^* FA$ #4&#"326"&5463253327#"&'OF?HUC@DKplZBS- #(+&JWySQxwvzPBL)? %+$"# ) 6  ""32654&4632&#"632#"'BPPBDUSA: :9ihx|hk;oooY^p3e8?E5VZC H  /%265.#"7#"''7&54632#.#">328D-][mN800D0j[mT@4DM++-6 M,0I)*<6Ilb]7;obN0#  7&L $"32654&#"&546323327#"5 DTTEBPPY"O6jz{fl5S"' p[\on[^ox1+}Q&GmF $"32654&7#5#"&5463254632&#" DTTEBPPJ"O6jz{fl5A: :p[\on[^oE1+}Q8?E(747>32#"&'332767'.#"(qJmnZvT#fS+R?=Tp7@J`ViD(HDIWYA( J)"#%3#"&547&5462#&#";#"326sXcuVAnbXf3<10>J+;@6E4ZLV&%KIWTMT+$!5L6%-7"!&>32#"&"32654&+532654&"az\p",*rczoG?GO6=;+5)01?WI(5;-LZ_Ysm_-%6L5!$+& 33##"'53265#53FSMM &NN HmG'#K1\|{db><9 0_I\nUn^_mk^bm^b2,}[S9>EJKeV*TJX& /"32654&"&54632>2&#"#"&'3326=CNNDBLKT\|{db<$> 0_I\nUqT>#Kn^_mk^bm}Y#. H%KeV*TJX_a2, !326=#53#'#"&54>32#.#"vMb.`,Lln$8^;]vV C?UVajUB=HV|#HO;'ZR3,k 254''47&'33". `4 ZZ&47L0#/(*/P^N`(F<+4  #/2632#4&'&#"&5467&#>32>54&4:;5>`L2,+<-.=^8)/#LbE-! ,??Ad5@%6O)Zf)?;OT}mG?3'1gF3  M, F4&#"#4632&#">32#C)@NSA: :%K8LYSk70aPe8?E50'MBtF&%4&#"#4632&#">32#"'53265C)@NSA: :%K8LY &k70aPe8?E50'MBmG'#5533##5#5TSPPSKii_HHB 327#"&5'14 UF+(  3#3#53# IIRR HHH|D& 3327#"DT& mF'GDqJ#"'732654#+57!#3!Yam5I7)EN% TT cXexg.KCK=JF  R@ F8 !##"'#"&533265332653M"K4a,%H4IOT3.3HT3.3HT/*P,$KG27P9I27P9IF&*3>32>32#"'532654&#"#4&#"#FM"K4a,%H4IO &3.3HT3.3HT J/*P,$KG mG'27P9i27P9&3>32#4&#"#"'53265FM#Q:LZS:2@N & X70NAtk/8aPrmG'F&@3>323327#"54&#"#FM#Q:LZ& :2@NT X70NA'Gm/8aPF C7@$ 2#"&6."!26q}np}~MN)N|NRZ[QFNXX$ "3275&#3#3!5#"&6325!FPPF_&$n7Np}~nN8Jmmbb LL&%/%4.#"326=332>%4>2#"'#"&c-EA*x3:7,T/3(4,G|{G,$<=!`0.b^`:T1 qsIc9!"85H5)JU=('=SL*Fh4ZZ98EA  W EA 7>53#5#"'ETTTM$C( IJg'_;3E& 7>53327#"=#"'ETTT& $C( IJg'Gm;3E8A #3>32ATTTM$C( Jg(_;3E&A327#"53>32ATT& M$C( Jg'Gmy_;3Tt 3#4 #4&'T T""mm!%%EeC@6 C(@6  ( "(0332654&/.5462#&#"#"'327#""X5E7C&+N]InbXf3<.3PNFucN/& k/7-%" C>IWTMT+$# E:LZL'G& #"'532654632&#" &A: :^5mG'8?E&##"'53265#534632&#"W &FFA: :8DmG'@D-8?E5& 4#"5632327#"5_: :A& 5E?8'Gm& &3265&#"4>324632&#"&'#"&S#(0#<"#M/8 31A: :"SGVLg  *5 e8?E5 HpI Y &#327#"&5#5353V'14GGS DF+(OD0 !#5#"&=#53533533#!326=K%P:L[IISSNN:2ANI4,NAxHHW/8aP "F *#".5467#5332>54&'531?';d>Af9& ?1nH5%N4,E'5H&};54&'7714SI-F&5Hf1?';d+(U/#1=+.t3&};54SNH9rB4+Ht &"_6)``KxIJ->5    q #"'332654+57!5!,YamXHHEN0 cXexMJKCKIJ/"#632#>54&L9XesC8T_OCxSEh[9f,A8A/.#"#&'.54632=H:CO_T8CseJNA8A,pJf9[h/ -0+4>32#.#"32673!".500GyL+_^Wj{mZ``!KwG/d2bjO4NNej3Nh`1&&4kF  "$.#"3262#"&546;5#"&546az\pAVrczoG?GO6=;+5)01?WIK%&VLZ_Ysm_-%6L5!$+[ *326=#53#'#"&54>32632&#"#.#"vMb.`,Lln$8^;c;N :V C?UVajUB=HV|#HO;'27E533,kF &!#54>323&'#"&73265&#"DS/8 31S"SGVLM#(0#<"#ii*5  HpI* :7 P0F| C  @&F $"32654&54632&#"##"&54632 ETTEBPOU<9 S9ihx|hgp[\onZ^pI9>ES/"#6323##5#535>54&L9XesC8mmTii_OCxSEh[9fHHX,A8A/.#"3##5#535&'.54632=H:CO_iiTmm8CseJNA8A,XHHf9[h #"32654&%!!5#"&546323 DTTEBPP'E$"O6jz{fl5S!p[\on[^o?JIE1+}QI[q+7#"'732654#+57!#5#"&546323!%"32654&Yam5I7)EN% J"O6jz{fl5SDTTEBPP cXexg.KCK=E1+}QJ p[\on[^o 7:"32654&"32>54##5!5#"&546323!354632 DTTEBPP &"ISNH"O6jz{fl5SrB4+HV#p[\on[^o   )6)``E1+}QJ->5'^C@<5OC "3"&546$44,,4$#4O33#'#t_`?QO@``O2#'373_`?QO@O``w.s\P-xPEl@<Ol@zU< 332673#".;T(0; $<4B" @sd#5hhhOC 2"&546"2654&%34H44$$3%$34$#4,93 "&546733278L3.F7'H%04*$:,6 - e?23273#"&#"#>[X :Jd :-%%h&%16N\3#%3#=q<q<䖖PEPxOAeLws,w!5FFUH&dIdl): #532654&#"'62,, J34q7e 3%$3CJNMOB%OD3#'^(DoOD 3#'73#']']'DoooN#'##'Q`<=`<䖖U/#IcHU H1,G} a+6G 3#532>5#QQ  )EX*/GCa@/Ga0E0x3#5#53HH54'%-I+8pT #"&5462&"327h#%34H $3%$3  )53533SHSHSSH)##5#5.SHS ''7'7j3;;3;;3;;3;3;;3;;3;;3;!FR4&5475>w%%h&%16e  , 7g ,"C#"&5462&"327N#%34H $\3%$3  C632#"'732654&#"#%34$"3%$3  U>"#>7632#.'&r ;ENjjNE;)/r >44> 'D '7j B̈@>7j B@2673#"=3!1JL *Oc2( nm  RP#xdU#2lUY/ 2"&54v((/b`dr"5|"&Oo'R6!#!6|`{5)3!bt{;Ze*G?S-&!5!#"&632%"2654&)Pt菎@R1VԂ򥤄d.O03#3#tcxh'uK2L3Ac !5!!5!!5!S9gI"SsSaS&4P!#!#!^^0y[i5(^ )55!!!^t*U#RR0Q9 >%"&5463532##4&'>={|Q}{SoVWnVon_}yQQx|_vVk c r{ lUYq=4%##5#"&5;332657"^"zvZKWVWKZlaaQA7AQ7kb4!%>54&#"!53.546323!;D.qmiMOZhTL /MwAqnc#LH.ei,H #l #l0G#'"{J#8"(|"`0G(4>353327#"&=&5#"4&#"3260 1S4o3H +%#_BxRBJFHN!CJ9%FRW E  8Nni[f2:)4>32#"&'#4&#"32654+53262*Q;_iho_;F!VH?4;)qAE2*?G7RE$dXw%_w$3?)jTJDJI: #5&#"'4632 V $.'v F #7~%(74632'5!!#".7";27>54&%v_ &*"y =A1FRPD/ %RsHH /4S1$8]gO[]]5Rb'$%#"547&546732#.#";#"267 mgffpf ch LV;@@..?AHrXPB_`Q?CO'%U/(;(/,(%'&>".5467#5!'654&&7L=+gdqED&L" .T6BH<@ℎ.A7aE!#J4&#"#4#"'632632'.>X  $CaR[Xn{lLH6SU.v8 7327#"&53 .,<@XQHEB !##373l>XXr < ,.#76323267#".' #  6 !'=! 0!! z`') R &:H"JFb\N8"&'#332676=3#5 +6XX 8)*=VP; "x##*17j>%%  [>/%2'654&+".54>7.5467#5!#";#"jI'J#&8Ca1'3"6D, dt*@LXRnJd^F*C=^V"!78.H) K9+HFFT0+E@RxD$T5i %27#"&5###5!#; 0.,^G(@@ >0FT:FF98"4>32#"'#2654."90B>!r>D+Gc5X>\11410/1=_8% wlm&G\l8Q)*RpR*J&4632#4&#"'>54&'.'.tc|[JB01(H;/H@0Z -(FI2.9vu_@F'L4.B%  -<,n P %p"N4>32!##"&732654&"",KO,@qsZ[=IOLLMo9RRf{|k[lZVpr* "&5#5!#327HI1! #CQ3II+O ( 7327>53#".531S<# XjnEZ.XbHD<$~V:H7F.8 #"&5467;32+#54&+3267yZF*3CiNXyn X]OK] nZ$D!d;NiŘznOhf,=+"&/#.##56323327=$=ah   B `Ã$ 3&hN<$*8l %##5"&53332653luVtZGUVUGZlljn6YQNQY$'%2>54'7#"'#"&54673>=3.4(4lP*F$<=!`0.b^`<4Pl3:7,T"55H/u"NFh4ZZj<)lIc7 "l("l`$#("q$#98!463532##5"&73"4&#269Xz?nJXzTa_b^_ae[uy8^M+xSk|oOSki(  2733#"'5326=&5#7654&# cgjϐ &Ɣh:ka Tc}NqmG'OFc8*0!>3273327#"&5#7654&#"Z1;Ocgj-#/,6]1=Oh:%.+(9_e}NFZe#E*Ze#ll2+53254+##5!#)J[ 54Rc9B]WE,? BBK9PPYB#D 0 .#"!!32673!".54>327^W^x lgZ``!KwG/0GyL+NNsR~ej3Ni`12bjO40m8d.#l./S&!##52>=!32#'2>54&+,F.* ua 1>M@{Ch_T,^4OvVtY^rR+48FS!!#3!332#'2>54&+^]1]|w` 1>M@L;uZ\rR+48F2#4+##5!#)J[]B]WE;9PPOm#DO#Ek#HSy !#5#3!3P^v^y'&Oo%#!!!3 4.+32>o-Y=t] 8''8$FE+R.*,-Oo'O83#!!]tR"y %!!>=!3#5!#5KE*[PPR5hv ٥qчZe*? # 333 ##nEt]tEv]Dwb44D0m1%2>54&+532654&#"#>32#".'3V8N%`ClX?_YJW^X~xi(>gA)KN8%X+U;*).TR[.7DMGkwscl-1}9=. #7\<64O 33##OX}eXi['VO#HOm 3#33 #]]1oz|2M!R!#52>=!#,F.* ^RDjaV-^6QwW'K2S-&4O!#!#"^1^y'[i50(Q9k3#733qqo{@=#/;32##5".54>;532>4.#" &CcF3'?6K._.K6?'3FcC& _0H5''5H0_0H5''5H0|7jH6W8( ^^ (8W6Hj7]%JdJ%z%JdJ%=Oy %33#5!3"^CP^RqчyO9#"&53;3#MX]L]]\A)9t'O %33!333^b^^R'yOy0)333333#o^^^CPyyqQX !#5!32#'32654&+8Dd@RQARxfcRR=@PO %#!33232654&+#od]=@RQAm^cxfR=@Ph'Oo %#!33232654&+od]=@RQAcxfR=@P0 3267!5!.#"#632# `Zgl x^W^_+LyG0/GwK! je~RsMO4Ojb21`iN3!S#"&'##33>32%"32654&v^]yq}}rq~|aŗ좡 o 463!###"&6;5#"OvaI]oneqQ7>53"32654&u,oq}np}$F2?)/J,m](:FPPFEQOFLU  A7 N=mmm\anF 2+4&+3264+3265!RFE2.TG.;bb;.[*1 P4Q"5!3#5!#573#W0"S@FnFݬ@4xx t;(J, #'#373537#SkjSjk "#732654&+532654&#"#>2#"'z5E6@;+J>01<3fXbnAVuc/7-%6L5!$+TMTWIK%&VLZF 33##FTlSm ccF"HvF 73#'#`jS  F !###52>5ST !2  b%F$ 33###FhhT2T FkCF 3353#5##FTTTT $TF !###FTT @6& UH< !###<tT L@& ^=&R&2632#"&'##"&5463253"32654&!"32654&-dflmd1>#S?5egke^1S@CC@CFFdCBBC@CB^#+-&^lll\`nm^_lk]am ]F$ 33333#5FTT=F @4xF 3;53#5#"&5FT"TT;V B9Fn %33!333TTTL @F )333333#dTTT32#"&'33267#53.#"%m[j}k^pTkAM I:4@\\ck`~^TMIP;7F#4>32#".5##3%"32654& 1W7q}n7W2! ^TTJFPPFEQO51D8'&8H> יmmm\an 4>;#5##7.7;5#"F!@,TEgCR[[*1w/0L=F+$("EtJ("l{J]'4&#"##53533#>32#"'5>5B*BKSTTS *;#KZ7PP 5{\70bNT@EE@!JD?k@#(|\F|"D %#3273#"&54632#.#"3XMAkTp^k}j[mT@4:I T^~`kb]7;PI"XBN "l&OF0 72>=!32+##%#32654&FSqmkaF'B8||:81P,yCXEVa6,+(F1 !#5##335332'#32654&TTTqmkbk||;72 BXEW.))4&#"##53533#>32#B*BKSTTS *;#KZS\70bNT@EE@!JDA"D<F#E&"HS^F !#5#333:FTTxx @&"cc4$#LofTo %4&+32>7#!#53533#32]vaYY]\\1M+4^rFxxF| %4+32657#!#53533#32[2)[UF>>THHvphN3CS~FHHFKL[i 654&+327'7+#!2KC62L$0]-lu<:2!6a@TM;lhys7U^poo@2?2CNO^ZC93#!53!]]t`Fmu353##FTT i@8 3###535!!jj]KKtFYFR| 5!#3###5F6DDT>HLxFFZRC3#!!32+532654&+]t\]]\40+55+RfZZfR/-'-/Fq 26=4&#"#!#>32+)C$*=3T'A9I>YLF079.[Vd L0'IFBM?y%3#5### 333t@P]nEx]xJчDDwb443 %3#5#%#5# 35373JF!Sg0kSk@x03m:%#"'53254&'.'332>54&+532654&#"#>32mv6L80%H!uX+U;8N%`ClX?_YJW^X~xi\x "7*4 - 6% t64*).TR[.7DMGkwscl-1"32732654&+532654&#"#>2#"'53254&'&'z5E6@;+J>01<3fXbnAV_S6L80%H!/7-%6L5!$+TMTWIK%&VDX%5*4 - 6&Oym%3#5##33$IP,]]1oJчM2F %3#5#'#373@F$SS`@x O'#375373#%#0]]0FxvtF)*MR?: 7'#375373#'#1SS1FgkgF) 1k%gqt*3#3 ###5353``kxdn]UU]oF;D)Fj 533#73 #%##5:SGGk0gS<..FjFQ{ #5!3 ##8Dkxdn]R;D9 #5!73 #%# k0gSLSy%3#5#!#3!3CPQ^]v^JчL;F$ %3#5#5##335332+9)C$*=3TTA9I>YLF079.[Vd@ 0'IFBM03,#"'53254&'.54>32#.#"32673L80%H!Hm:$ 0GyL+_^Wj{mZ`` 5o*4 - 6&CUlL"2bjO4NNej$3'#"'53254&'.54632#.#"3273cL80%H#Xfj[mT@4DMNEkT\N7o*4 - 6&qb]7;ob]j~Vh $yQ %3#5##5!#bCPP32!&T=?R01f#TvZj~OO3*L"+C cJq.AYW4K%iV`xY:4>L.-'%+mJ@7p/3r E.#"#"'53254&'.=.54632#&#";6763 !32673 &C-Vu=L80%H!>c=*fgM?7A2 A)./)JIR,{jW^_(5!-9"f[*4 - 6&1INX=uSN];7DB;8@tJUMO$*3@!654&#"#"'53254&'.'.54632#&#";>32!3273!&T=?RL80%H#UdOO3*L"+C cJq~01f#TeL6.AYW*4 - 6'jY:4>L.-'%+mJ@7p4K%iM_#d#^'?#HT,#HOR2+5326=4&+#33\]]\40+55+]]kxdwfZZfR/--/;:q %4&+#37372+5265eC)lSSkMLYYL)CY70 MBzBMI07!y!#52>=!3#5#,F.* GPURDjaV-^6QwWqчF$ !3#5###52>5S=FK !2  4x0)CXDG.PAAqQDSR!!#3!3+5326&^]v^^\40+5L;9ZfR/Fq 26=##3353+)*ATTTYLF07 BMSy!#3!33#5#'^]w]GPTL;qчF% 33533#5#5##FTT=FKT 4xOy9!#535#"&53;3PC\]]5+]ѺfZ-/'F !#535#"&=3;3wF=AZTDTxLCFKy@!##333#5#bXԁGPOc{qчcFa 333#5###Fhh=FK2T F4xkC#H*"Hn #l*"lp  %!#!!!!!!#Ug+n`dRRR(_"M.:A%3273#"&'&'#"&5467>=4#"#632>3226=%!4&#"01e%TvY:^ 8e;L\s3$vp Tʀ/\6IpFZgG86&P@?R4K%iUa,':4TGQN N]R&,J@7pQe  ,('-GYWZe#H("Hr/ #7326?# !654&#"#632 &C-Vui/GwK{jW^_+LyG0!-9"f[h1`iN3eMO4Ojb(.#"#>32#"&'&5!32601f#TvZnmJqT=?R4K%iV`J@7pDAYW/#l("lp?#lV,#l0m#l""lJ E{ q ,Og#CF"CvO#lF"lx&#l$"lm& #"&632.#"!26^pm ԌaVԐ}|Fu$ 2#"&6."!26q}np}~MN)N|NRZ[QFNXX&#l$"lm0#l"lQ&kg#C&"CTk#l&"lVk#M&#M O9#lF"la O#lFl#l$O%2653'#"&53brO_W;[ 1z^/+Ipv]De$$c\WO2#54.'"!!#4>jRp=_'O=%/^&>e-XlIRQ:KA\1X];ZR4S.%##5#"&/46763234&'"37554'k_O~ 0@Ag= n_KJk ";;#[aZo{((P ( n;I85=B[,n R23##4.'"#54676jSq=RR_ #K:rO_0@@+VmL^8HC"pvQRo{')O%26=3".53!!bsN_%=dDSr=^//+[ovQQ9XR6!+XlL][V<32'4'!#533267>754.+7!&5%322{(4+{),SEYZZX';,GF"t % 4p-!:hH=! :*767#:,B=Y-o(Q G60cT %#33#N`OOMJ!#54.'"%4>32o_'O=9I% &>eD3S7' )%$A9KBAL:W;ZR4"#-? 5"2=+"'"'"'.546;54&'#"'#"#4>;23#E.4Y_k  F:Wx?U |_.KL)i66p8^U8^r _]iBAE :U+q\KNC~$%"&=4673533#2675#"#"/"mjm\c`EH6 %'[po^~\oK~:O =,k?q4.#"#3>32#%I8Jg ^b y/Ts>^8MA45%:"-ZlKG]u33]_]B%%2>74746=3#".5465#3 -_xoIh=# l__ %II:. 6ᩑ"8]_DN@9KA # .3!2.#'2#"&546767'"=4&"276v\^$ A~ *ebP?) Q|PLKIGbeMK7-?]Ć[[T-QkpRRj`IGJGJ}%".532>76=3#5hTr>^/)>-E%_a \,XmL[W$)KL$72'&'"#.'%6, %' /t-g.0" 83P2;"'5467632&'"&/4672>=4."27.LD[_S>0=teV I/H.;E A: D+?U)2#'>+# 7WG=BEko?c< ( "''&-!>CG(Y,+D%:!#)O23#4&'"#54653#".53M8J%j>qSRp=_NU BL7]MmV*-XlIbvo1*3#"'".53327654'&+53274&#"#4>32)Bn.aI];E'<<450X45G`.[?5T2! cOds.b=H Ms:35,77"&31M#"  ".''53326=3o=/+32o_'O=9I% ^&>eD3S7' )%$Ab9KBAL:c;ZR4"#-BG#%5>=4.'"547632G-JT-n61!GW_@Ks>c5$ 32o_,+'_F^&>eD3S7' )%$AbBV0 p**+;ZR4"#-*A 674&'.+%32'4'!#53326=&#'"'"'54>;22J-)o&4O)(4+{AESEYZZDkP*?g@ 4p-!UH0@&"&-3C&#:hH=! HC76793 iY%JN;&60cJ#34.'"#4>32oKO]'O=9I% ^&>eD3S7' )%$AP9KBAL:c;ZR4"#-O%2653#"&53brO_:sTz^/+IpvbFh\0c\WJ%".=32>76=33#5hTr>^/)>-E%_Z \,XmLed[W$)K^$-g3%4.'4632&'"#".5726 0M^`O6k-L3*[ JZCipm qW~@Y Hi(3'O9\i$, 75'15)$\z/LN)?J}#54.'"#4>32o_'O=9I% ^&>eD3S7' )%$Ayx9KBAL:c;ZR4"#-<9*54>32#"&'32>54&/"'67&'&62654.#"O.bFX)Dsr]j")-"6)" h#jJYRxP1;!: 9<$e% fSb}qfY)6#:F 5A w`@79(3L_33##L__Pu*!*0%.54>75332#3674&'Y<^E42D]=^?Y*C!9@H4^,=/"^ob0,?tIGp>,77 1,F54. =E2"n)OM0!3C=eϚz '?pI~5;275#'"#"'&533'".546;32B/,..--Ym flC)]-48#ih_.j~0D ?+hHF_{I-Bmp ;)X=pbOC@5 53'65=^35mfP9G"NL73X)hLI.>;27+" 6"<,0$N" x"0- PES,>2#"532674.#"#%Gh.4,Z,  59/*.-6+-Z  9IT3'73! T8TT9 A #%2653#5#"'#"5332>53(E;XOT4t=cX()X*B_ZI$0[[h4, A.19<J-%#54'.#"!!#3632X5(*BJXO323##4'"#3 !5 BLddVPGGVSD>>?[_K <%2=3#5#"'&57!WO:k YQ/AaJU~-(\DG*9B7"&54632533#2674&#"Wrqf7GRc1HC:CACEAmu+6g:LTitKVtr^e %/#33#>KVJwM?0"!%3632#4'.!H_O?23#26=#"OCDTRBS}&: QN?# t-310(*_"$2I[KB>WAq&0 A,08=P<6/@4( )0F'7".546;533#+"&'"72>54&=#" %3+mbYbb}_ ,'4 z&9c]dOX4"H3GhaI?><0 #3W}SwB.%253#5"'&54654&5##33XO8mUU+?"JT~37&'4734.#"32"t`e}-P/=U3;^}+ZJBIy\Ldv98A/*C=64(6@@8I1ce[mG-%2>53'"&'3 *-XX=_fKXG"H3!Eia ~B"#3632#4&#*-XX>]dOX4"H3GhaI?>(%42#5#"&54>74.'473"265474&#J*!(KVM D9dx1HJ>@D)H([EF=GH9*_?3v4bH;0 -.  tQUrpK Un'823#4'"#3>)=dQyVRB*)?2\ W$+ 747'767!&4%&'&#+@1>fh1'R^=z[-/(1@2{T0'[x0,x%GU=I/4.54>;2'"#5#"&'332>7,4,-,@ T1 T8%HAQVP,; 6&@&$D 1 O8$G6X1,. 2>=3#"'7  X9I* &^X KI%%273#5"/&/4676;"2`WP5+&)'-HAAEP?FS -!'S*=11P5B)4&#"'672;6;#"/"&'&'4>?6=:)3.+53(E;XOT4t=cX()X*B_Z$0[[h4, A.19<&--B463236;263#.'4>54'&'.5744.#"6?>54*tQ! (8/#7Np  =>3'%+%*)"]B-4&#"#36323# GE<4XO533'"&'3 *-XX=_fKXG"H3KEiaG~I@)%253632#4'.#"#5#"&'&53 U) O]aD9Zf;S([hgL 3#~ 2> +2"(72673632#4'.#"##"&'&53M;T32'"272654&7umQ15VddQ E;%HG+4LE:><@g}A:UU:NA47kvU_HffJV^2%".54>32"32>54.%+NL. 1C>!m"1E; 1/\=1/10 9pM>b;&wDh:$ )S9k[*S98Q(*/o(07"&54>;32##5"+'"/.533332654#'35"Ia!=I//=Yl*:7-W  4HNW%DD5638PC*; ߆i<_9% C7JnlS-%!F!".53326=335+> VPGHVP>-# `XKDDR$Z5353Zdddee^dd & 27"':2 '0AU+Y  "G3#53#GGGGFGO 3#73#3#73#53#GGGG@FFFFFF3>Wd 3#GGGF3#FGGGn G3#GGG:FX ##5467'367>=3>Q;f(WPX33>WX'(X##5!WW  LL?;X.'##!2#AZW+<+/:WtQ: Xb:=:X3%>75.#"5632#".'3<1    1*&.PMH/H81 W -L  (# R./'5%(+-V:z :X3:WWX#&8X #.'#5{lWAZXam7Pk7 "F:<4 sS7LG(5&+7!,/L"3-%!#54>7>=!53!!'.2W%,4 [W5V+, *b0?Rn(*@5 ?;X 2!.'&'#Ak>**!9GX%4A2X+"? @0:X4&+##532!53uWA:X:N{wAT L`L>8X3>W 3FX2!534.'G/H81  -X-V:L( =9X&!".'!2.'#>7;5H:--PM_BY%# 1   -U6z/.'5%(+tP:-9  $X737>737xYs# W +C:C  &!X5:9'LO98 X.'#3'&'.=32#AZy !!"(P .|!WtQ:  L 3!./'5%?X*2+532>=4.+3'&'&=Aj=*;%aF753 [UWc#WKc/6 +3X!5!3>=3 f<&Fd0-W@jL 4'>8&X#53>7!5!#&l|>7$5#ooWlbL)Lr%X #.'#5{mWAZXamtQ: L<X$6753+;2673#.=3bW57J` x>RCW|R}W,YB128\iQR[ZR#{X.'#+532>=#5!#$AZi 1A:"=3<{mWtR8.J, L:.)Lam 87 #/;GR]hs~%2#"&54632#"&5463"32654&'2#"&54632#"&5463"32654&$2#"&5462#"&546"32654$2#"&5462#"&546"32654@" ! " !  ! "" ! " !  ! "c.!!! .!!!N. !!.! ! .! !N. ! q ! " ! "" ! ! " ! "" !  "!" "!""!" ! " ! "" !4c 72#"&546k" ! ! "2 2#"&546i" !  ! "3d  ,8D62#"&5462#"&546"326542#"&54632#"&5463"32654&S.! ! .! !N. ! 8" ! " !  ! " ! " ! "" ! ! " ! "" ! ,p #/;G2#"&54632#"&5463"32654&'2#"&54632#"&5463"32654&d" ! " !  ! "" "!" "!!" " ! " ! "" ! ! " ! "" ! jq #/;G%2#"&54632#"&5463"32654&'2#"&54632#"&5463"32654&R" ! " !  ! "" ! " !  ! "p ! " ! "" !  ! " ! "" ! jq #/;G%2#"&54632#"&5463"32654&'2#"&54632#"&5463"32654&R" ! " !  ! "" ! " !  ! " ! " ! "" ! p ! " ! "" ! jp #/;G%2#"&54632#"&5463"32654&2#"&54632#"&5463"32654&R" ! " !  ! "" ! " !  ! "p ! " ! "" ! n ! " ! "" ! Ta5 #.9D72#"&54632#"&5463"32654.2#"&5462#"&546"32654! "!! "!!" !.! ! .! !N. ! ! " ! "" ! ! " ! "" !W9p #.9D2#"&54632#"&5463"32654.2#"&5462#"&546"32654" ! " !  ! ".! ! .! !N. ! ! " ! "" ! ! " ! "" ! $  ,8DP\ht2#"&5462#"&546"32654'2#"&54632#"&5463"32654&2#"&54632#"&5463"32654&'2#"&54632#"&5463"32654&7!5b.!!! .!!!N. !!" ! " !  ! "A" ! " !  ! "" ! " !  ! " "!" "!""!" ! " ! "" ! ! " ! "" ! ! " ! "" ! \\$  $2#"&5462#"&546"326547!5 .! ! .! !N. ! d ! " ! "" !\\m7'7702M~Y-$  ,8DHLXdptx2#"&5462#"&546"326542#"&546%2#"&5462#"&546#3!52#"&546%2#"&5462#"&546#3!5"32654&%"32654&"32654&#!!.!!! .!!!N. !!6! "!" ! " ! ee! "!" ! " ! ee!" ! ! " ! "e3  "!" "!""!" "!" ! ". ! "4\\ "!" ! ". ! "4\\"!" " ! ." ! 4(\#wz>=474/&'33##0aU !,C?*M2Z2%,@57OZN;9t23##>54'*#S*IC25^'HZ !$,MuG)5!5!5!ZXa!#"&547'!5!73#""&5'2633 tmM  6?'f  #Z-=Z#} a$#"&547'!537373#""&5'2633 tmb(M  6?'f  #Z-=Z#} kq#532!5!4654&#yyB\oF(TS 1)Z a Q/k2!5!4654&#\oF(T 1)Z a Q/m".5463##'2654&#"2>+_UdY /\&44*&>9'X<_,EX!gOI14XY+6Ld !"&54632"3264@bz|`ay{1bNQ43J~WZ|}Y[zQK/2KHbV[s.547632'>K"c 6 : 3_2Ds1O"!#'#'!53547O$JzppssZ\r_ '!5!73#_J.DZ,>Z__ '!5!73_JZ,>%'!5!5jieO`ZpS #/1=W2#"&5462#"&54632#"&546'2#"&54672654&#"".546335'##" ! K" ! " ! K" ! &44*&>9.2>*_Udj[ /> ! " ! " ! " ! "OI14XY+6LO)V;_?ObD,EX!ga(%#654#"%632Z\@DtaE\I;@ؕWHO]qZU;I@np)5!7pHfUJZCkv )##5!5#=SO^Xk?ks'54&#"3">=4&5! 5-AAWT< ("/%7&$ "&/.(# 1  #xO_JUUZ-_1`(#+M Y :1 0#`(22$4C2632#"&+"''7.'&54676>54&#"3">=4&5! 5-AAWT<  "dH*h "/%7&$ "&/.(# 1  #xO_J.2 H+".1`(#+M Y :1 0#`(2%#"&'!5%277327kF3C$&8,A(E,71D1Z)m+>CK@ %"&546?!5!'7327SdVF9? >"pA0(F)OL8F3Z!."$@ #"'!!32654'&/;Vd%>  ?)F(0FFLOZ@3*$"$*!5!".'&547;635'#"&'i)h1,D< i #% ^h I Z*Ei6 +_aD >O] O7C'!& 3"&'#53!'5#@F5AdGUdk`#532!5!4654&#{{n\oF(TR 1)Z a Q/!#"'!5!'#5!3/\  ;;ZZYck%"#"&54>732632&\ n69KN(Gn*i :((/C9Ee*lSJ*+99&''7'77''7' &%Y(,$"5'=d+jA!5 77''7'77m &$Y(+#"5(>j+jA!5O 3#3#,####s /'K7K{ //K7Kq 2#"&54'2#"&546.! !n! "! ! ~ ! " '7''7'78!8 8KK7R^_`]_g 77'7'!9 8 8KK7^_`]_ 3#'3#'r####K //|KiK}@K[ 535#53#3HHIIL"< <"D 535#53#3% HHII."< <"Ov 2#"&546%>" ! B ! "C{ 2"&546/537$/++U y!;9= 2#"&467#'7%yi.++-$ w";8v 2#"&546>" !  ! "(fq#53%qbb]>v 2#"&546>" !  ! "(Ov 2#"&546%>" ! B ! "Cx 2#"&5472#"&546).! !7" ! V !  ! "w 2#"&54672#"&546%?" ! ! "! ! " ! "7 #%2#"&54632#"&546'2#"&546" ! " ! K" ! t ! " ! " ! " !#4632#"&74632#"&2#"&546%"! "! ," ! n! 0"! 0"E ! " %N,`H%' RHfS7!#7777''7''7''7''7'$"$$#"  ; ; ;> ? ? @ @ ( D C C C B @ B A   '09@IRY`ik533##'#62#"&542#"&54"342#'42#"&<32#42#'42#"&<32#"3265&"326=4&#"326V'SR'U, , ,,,,  o,,  , ,  PO%QQg,,, z,  o, z,  o, N,,y, J'72673&'&'3&IDI+FIDap)7G*!AICI-6;U $2I+>M'7[TZ\T\>,'7'7[TZX[T[\U\\T\XS'54&&'&=3766327275#53##"#"'&'754&#"'22674'"'4>r@1!+?8'A1IMi9T98!%hGJ)R;&6;SC*,7@HG5;6\c1$! -M5% ;*TS>A* II 6#'8@$R;2 <50CI, 0+f:2675#5!###"''&'754&#"'22676#"'4>: hVJ,\_J;3T(SC*,7AJI3;vR9 8@ II lV)#4IFR;2 <7.EI,RR>A* <fC6327275#5!####"#"'".'754&#"'22674'"'4>9U96!%fMGLK):M:&6<S=2,6BGK1;6ZeR?A* FG ^n#(7@$R1< <6/CI, /,ie3%&#"&'&6;5!5!##"7"632&/"'46362674&C Z -p"ZJi"0d-UB",%+3)N4 `IIN; ,R?5G#['58+iB.67>'"&#"&'&6;5!5!##"7"632&/"'46362674&5--"E2D,"%6* Z -p"ZJi"0d-UB",%+3)Nh6bU ;&'&+'326 ~Fr+730(1J->^J@05#/aHDEEIIC2A(lr"*] %*a*:<&I$e;6'>&'&'"&?2>&'&+'32654&'!5!!6{6Po:%  #<aP->^J@05#/aHDE ~$+7BgP:Y#!>'-G#DZ] %*a*:<&I*EIIC2A(Le9%267#".6767'#5'%&'"'>765!5!!674'432")::P1E(J,b QK-,5|{F7 %,?>:0DK# *?ԟ;o&(8 TII4 J)!-d$Ae?%32?#&54?"%.'&632675!5!#'>74&"#54&#&*($))QHk$:+h2-@sZ@Q+K_>9 H::%U7K4J4.*! =)N=9%+-@@VDa73cIIfZjl +b0 )0!FU!>{?02673&'&'32674'%#5!#'>75#'4>Iq67H2.R) *%U<175/O^02I&1 7IIF3 (  ={[6'54&&'&?762674'%#5!#'>75#'@2 +?8)A1INhz) *%U<17c1$ ,P5% <)7IIF3 (  ={e!2674'%#5!#'>75#') *%U<17M7IIF3 (  ={%#'72674'%#5!#'>75#'K<|) *%U<17f:%7IIF3 (  =W4V2673&'&'3###53%6327275#53##"#"'&'754&#"'22674'"'4>,FIFbn&9G2/MGN9T98!%hGJ)R;&6;SC*,7@HG5;6\-6;V#2I&0 GS>A* II 6#'8@$R;2 <50CI, 0+;XZ'54&&'&=376###53%6327275#53##"#"'".'754&#"'22674'"'4>?3+>9(A1INhSMGM9T:7!%fGK(=I;2b9T=2-6BGN/;6\c1$! -M5% ;*GS>A* II dm#UlQ1< <6/CI, 0+ E H#'7###53%6327275#53##"#"'".'754&#"'22674'"'4>K>HMHN8V:7"$gII(7N:p]SD*,6AHI3:6[f:GQ@A* II ]n#R:3 <7.CI, 0+WM#%7'7###53%6327275#53##"#"'&'754&#"'22674'"'4>>1d?MGN9T98!%hGJ)R;&6;SC*,7@HG5;6\c6$vGS>A* II 6#'8@$R;2 <50CI, 0+e57267!5!!>'>74&#&#5&'.>767"&3&#&%H$ZK<gFT.#4II .DV&$ .DV &&3>(  II3$5u0m1!,w " OE/ 2 P 5+4- e?%#".'&5775#5!##&>32&'"375!#'675#"&{";9_A:"< /* HI#4* =JKG*0/6Z5';4D1O5+#:=!4lRB$3c4p" H6y/O# `II;;I 4M'6MQ7.vople%675!5!##5"&547#5!#/j$$lGIt5@NEiY&;,\AIIEF69 uIIg)9PCA*Yie-B%&#"&'&6;5!5!##5#"'&/"'46362674&7##"7"63222C Z -p"HI8(d-UB",%+3)NέJi'-4 `II|-R?5G#['58+.N(e)6363275!5!##5"'"'7754&#"pN'*'II.3%D*Ur0P/iK4 & II!2&V:,p 95 8e746;5!5!##"327#"'&Ag68z)5,A7_3DV{jMNMmpIIL(/I#V*tGGe'7356'7&'.676;5!5!##"s(2&;6LTv-  2Fl$ %;#n5)1*iBZ . '?@M!2}II#ce-&6;5!5!##?2#".57276'""&2>cY1O5+#:=!4lRB$3c4p" H6yy# `II;;I 4M'6MQ7.vope&/74>;5!5!##"&'4636#"'&>74'&1A+m)2YM>4#5 #:=hSR>&2.7@,hII>.?i%/5A-%)= LLP)961`e###&=#5!26=#`GJMCAT*`[-$>WV>I)1V4e4>3!5!5!###""'&*1'\4GI?IP4O^84+hIIr;,xR6ap*e-%275#53##5"'&'3254&'"327"'&>360rahHI:GQ_G_(15.B; ==J_dd-II0/CRC {)6.0Cs)9fEP]Ae&46;5!5!##"34'476#/".*E4H!(F(,: b!In?' &?W`II+!B(1e>B)93(Qf/%675#53##5#".5&7.7636#54'"6;"d:`HJ_r$: :H)2$3-DI(1:-4" ư8:II_ & 9,25%I(%0"R ES48e463!5!5!####"*JY8GJ B(%IIOX 8e#53463!5!5!####"``JY8GJ Y(%IIOX e 7"&=#5!##5'275#Mh*IH*I<7;X@II'J7%-e'7"&=#5!!636'>56&#"#5'3275#Mh*D1E\{E"S<55H2;-;8ۦX@II?ZDV0j2('&1#%-0e%%67!5!##5".5&672&'"37'M HIA=+C%ZG G8+'7. ' IIܮ/(1$ Eg PN,6vBe(635#53###&546;54&#"#4/46.IhHI b )/ NFc08II c s!/ 0=e46;5#5!###&%5# )^HI _d "II N pJ,e4'#5!##5#"&'22675#9,HJ=Q`)5LOE)A54)II5xd,R,30ZLe+'"'&/7=!5!#dK6"H% 3_W;K>O3B1U-6`|)-'0IIe!7'7+'"'&/7=!5!#~847K6"H% 3_W;K>O5958#3B1U-6`|)-'0IIe$73"'.7636675!5!##'47&'"s4F?%75!5!#"'#"&'&63232>'..#"3>P >%A,RK^'(`GR_DWR:-+ 9=V3)RW( `4kIIn 1;,UfY]fWOj'NBS& /*Amu. e!.:#53>75!5!#"'#"&'&63232>'..#"3>bb >%A,RK^'(`GR_DWR:-+ 9=V3)RW( P\T4kIIn 1;,UfY]fWOj'NBS& /*Amu. e&'"67!5!##5.'&67202//5]+^IQXYHFlCN+!IIܮ<c;Dh e#.###53#%72>7&'&5&7#5!&'"327MGM(5`62./6@,"L;-bpE&)%GG4~eE45( =(73IINM)!e 7"&=#5!##575#327'Mh*IH**:.EʚXAII'&,)e$###'#"'&/7=!5!5#GK&D "H% 3_W;K>&%,1U-6`|)-'0Ie17#"'&'&7.76;5!5!#!"632'674&#&{Y &fC5 K&: 88";,=07X{7K6#6m7:5d`II ; 8('.! Ae,.'&632675!5!#'>74&#5'&#&sh2-@sZ@Q+K_>9 H::%U7E J.*@@VDa73cIIfZjl +b0*!FU.>#53eeRcK!&'&'727654/&546;#"?ZZ?9\?F3,_N%)PQ>3 T(BWkSMHMKmfhej'nHH6Nd;AW23###53654&#"#&546F]xMMHMOR= &/N)eWs_HH >N +;470W2"'>#"33276k@ 6$_R+7J\G wBwA!.# HS$`]L527&'.67632#.#"B6%aP,8I=cB*G wBv.$FV#.SQ4a^M267&'&'46;#" 0 &!hK:E9aTA:<" %@8IG6&A!)46;#"32?&'&'46;#"32?&'&F8A>"#'!fL=*E9aTA:&!&!hK:7IH6 ! ;! '8IG6& <" %J;2673&'&'3q+FIDap)7G*!-6;U $2I+cEX'54&&'&=376E?3->7'B1INgc1$! -M5% >(|Kt#'7LK=K;LL#%7'7H?1c>L7#-H###53'2673&'&'3MHMj3@HEao)6G1/H6.;U #2I%1!\###53/54&&'&=376MGMX?/#+?9(B1INgH2$ -M5% <*M ###53'73MHM==YH:,###53%7'73MHMB1d>|RH7#^9'39!W iKZt#ZK9)9Y#53"&53767232>76#"'732654'"#'#'&5726&'&'#'2676&'476{RR}zFMh52;P5C7EARQB:* %!+Q23N& 02ks$9{P0(1$2[1G"&8GLTqqT3G!$9ZAF&  1;2q[Ys1G0@/1:1-@ 7 !@LG5)/, #(B 6#5D6*2!5!&3,M2'&'#5'"6?22, 11(! -5RC1$E6?672&/0)# -+" ;9K- 1#!s<L#532673#&'3YY1%;>\CA\=*(V(0CTX@"+ e9#537267!5!!>'>74&#&#5&'.>767"&3&#&JJ %H$ZK<gFT.#4II .DV&$ .DV &&3>@D(  II3$5u0m1!,w " OE/ 2 P 5+4-s e%)j375675#5!##5##"./.'&57#533675#"'#&75'&5&6;632&'+#;>75!##A  HI 3F)0 -.-,%< JJD0T60'"4L C & B**8( & d  IIy .U^< $. Dc8N@#3 % D@F %7 Λ"  e7#537#"&'&6735#5!###JJ& 'c; GH7Bo II$e##5376.'5!5!5!###"'&5732\JJ,GJ#T9c;A>>E69 uIIg)9PCA*Yfe0#537"&5&6;5!5!##?2#".'7276'"II8w+>dY1P5*":="@Y82SHq! HvC8)`II;;H!4M'QgQ. Mpxe*3#534>;5!5!##"&'4636#"'&>74'&3JJA+m)2YM>4#5 #:=hSR>&2.D@7@,hII>.?i%/5A-%)= LLP)961e#+7#53'"&=#5!!636'>56&#"#5'3275#IIMh*D1E\{E"S<55H2;-;8CUX@II?ZDV0j2('&1#%-0,e##534'#5!##5#"&'22675#JJ>9,HJ=Q`)5LOE)A5D4)II5xd,R,30ZLEeK46;"32?&'&"67#".6767'#5'%&'"'>765!5!!7'432\F8 A8(!&"hJ<+M(!&88O1D *H+bOJ+QC?|B58IG6% <# %T-&"=80CH" )=ϛ9l&'7 RIBHH5J* -e)W%32?&'&5473#46;#"2?&'&.7632675!5!#'>74&#54&,1!'#iH<,8 0E8A>D'"fL9g0,7h5+?O,Jhr9>/%,9$S5IG6A'. <# %?47*7JH5" =! &=>C161`HHd Uw7+*`/)DR ! w@fA%32?&'&5473#6;#".763267'>54'"#54&'"$"P5-"* , 2J& )O(".=65;#69+@K'6%#1# , 0%* h6.a/hy2%*' er J"4"3>'w9Sf*O%32?&'&5473#46;#"32?&'&.763267'>54'"#54&'"$"P5-"* $3+ 1+N7+J& )O(".=65;#69+@K'6%#1# , 0%* *76( . w.a/hy2%*' er J"4"3>'s'C;eE''2DEKeDDeDY\ &5&6762>56.#&mYWmpV.I* $6 -% #3 E'RvxSXq!1=- 0'$5 *+6Kqf 6##"&'463254&"L^I#9J\i9"a?D7ehRX7YFI^/,\'2<Xf">36'"".'472>74&'"X}/Z|"91< &B;/0SN?5^#.qV4W7 + 4/q97D/de+%6&+'3254'"'7632'&5&626d6A,kpf[->B.66!@&W?P7os@P/B.BKMDB ;(T!"8!HX t0>1+%EMe#,#"&547.5&67>74.'3254k_GE[eZD-?&e,CJX$9X]eDTjWI@OOCHW?L3 B $=]+L ) FKK9ef2#'#.737.54'%XML-0Nh ?D E.* ?D/f{"f0G=8^df0;#"3274'432'"#"&'47.67636&#"X$HZ/>B0 @""8C8" RjV>2$4;D%)G #DIG*'8 V4L#_K`2!`V#E \,2.547473327"&5464&'"57q5C8Y7$D&B+oKcH~)5,3FT0AgH" AyeC}oRF_@?]$5 Ec%.54733552{MZ^ :(*-zv+Cef$6#"'&674'&5&62>74&#"2L#fP).+ YS"+ 2'^-e%7-H_3G  1BY%%/Y,jQ)(2""/&54753>332654&#"/ #  * !  "(,!%  3  !5 m ",!,###53%7'737#53MHMB1d>|R'H7#hxU#53###53'73߁MHM==YxH:f#53#4&'&#"3###53&54>mT(BWkSMHMKmfhxj'nHH6Nd;A1W##53%23###53654&#"#&5461]xMMHMOR= &/N)ex*s_HH >N +;470W~$'"#4&'&#"3###53&54>'46D;1!T'BWhSMHMKQQ{K3 nF'l'nHH6E[7CA@ ~(#53/"#4&'&#"3###53&54>'46QQD;1!T'BWhSMHMKQQ{KJ; nF'l'nHH6E[7CA@ x#"&'3274632#".: @#,M0& !8GVN#h " +( 3254&#"'7#"&54632V&/"2*$;(1C9%5D&)!6*_1)@42&C"0 !-72654&#"7#"&54632'2654&#"7#"&54632 3%k4&(AA"D_ 3!o,.90@#(8c80$?3;'1080FB,$4@t.%!5!##5'#".'732654&#"'632>G3R4C;aA* 3{F(7?()/S<^2 [?33\~I:bi:=-'N< ek!{6&'##5'#".'732654&#"'632!5!533##4-3R4C;aA* 3{F(7?()/S<^>   3JJ3:\~I:bi:=-'N< ek9 [?3 M3"B3!5!654.#"#'"&5473?632'&/32654&#"'>;2nX $ j6J0 42D" 9HR@$M% ;+*9)DA1T&547#"'732754.#"'4>732>3'23!5!4&#&+"&=4673;63636G)..4# :G"3'!=2%3$ /\ J(c>.] !E1*$M' hkUUkr:d (!%#d1[22 &M*#,8=33 ,< %>#F23!32?67#".'32>54'"&=#5!6=4&#"5473J-Bg' 'fP9^8)32R.(< " 7.>f- 7W6E3)2 (/!ZoD_|V'!jwU#3)*%( +-3 f01@7B23!327#".'&'32>54'#"&=!5!65654&'"5473h.D]2@S'AA#QE3313-$B'2"<>)&Bf- 7W7H3"p9u2J%VL^R#/ >*4S:3!f21X.72675333##54&'#5&/67.'#"&547^O>393TT3 632$eo$L&*'"$pC; #8"6#'%y\3j;D+t`N8H4 &21& G/3$ t5y;2>54.'&547#"'7>54.#"&54>:F55&8,7 F.6R^R6d,* , %* &-#gK>!+;%4 2J.1&6($*R8Mi*1+ %'/!9-#;02#.#"#"&547326324&#"327#"&546(23GG* RR,BI>F, #;3O9H_5A@1:'+Sz %/9#LYH#4/&#"#"&547;26324&#"327#"&54632654/&546?LW3b =TQ,2BAD. #7Z%\Z $*IhiIW(uG_A5@1/1+Tx"+'8k0:&9(D)!*"I>2#".'732654''254&#"&54632/ "2)(H75%)3 5Q]L#".'732654''2654#"&54632654.'&547QP5,"2)(H75%)3354&+#5.+"7zw6H0/")( ^03@ %+)()C`*.33.&N4#B%'7LfX/X/+33##5./>4'"&54732677W$Ld3TT3:3:*4(%1( &'=5FaV3R,1-45)*%/DJ+{,2533##&#"32632'>54#"#"&5469M.3CC3V^!F O",E**I '  W15HM3`7#)"!E( O  %1^.$27#'47#5!##5./7##"&& !.K&AtO=3JN&H $ 5)a133AAZ (R8  :D>32#"'326?#".'732654'#"547&'7&#"325 I4 '.',59(#)ZJ>g@&3"5R0<3% =!o#>(5<$UE$)  W<P-JcM|B @ykAE.0,"4!W>&1 5.72>54.'&'#5!!2#{#bDLgc"L6: G5Yi 33=.(L.5@.+532654./#"&=#5!!;26722654'#"'%8/?R/."C`z;GWw\304*= "12 NC1  ;)3/)$7='3\2?^.33 @ZK&a.E7".547#5!!327&547".'32?#"&'&5332654'(3 KzK9<0 #BP2$*%,SAH3'B%"@(2.a1337'!>_;HTjN]X !!# B!-"')!3_x+F! ?E06'$&?"+675!5!33##5'&/.'#5.+"7py 63VV33?#q#)Ca,+3AX3= W2;V1:F\#"&'#4&#&+&547;636;24&#""327#".54632>32'"2654&#"532654&0g,[3B^#H}/69 ":, %n  "#! *7%,=j7_-X83%'/(240gCL3E9 C<9*#S x $ $>Ab>-4lxE49!,3%F'323!32654#"'632#"&5#5!654'".54736A/;d&!"-:c4,'d[[ #,!*aF636D$"1'6vS?'O3 2 / ) .T".3##"&54>7>54'#53&5472654'/2Ư2@fHFV2 ʬP6&):4I<"G0,N73Pr^HZD N=%3]G54#"'62,'x 35% *>.9d?'33q 6Y1&"!=8[?$327+"&54>32533##4&#"r, )F>)3& 3__3Y$5@?3^+1:('c3W+w=&U.&*&54>32#"./332654&#"%5!, 8&KcfS)E/(3XYBLF57va '" '{y$?+JV\IFa!w33433##5./>54&#"32727+"&54624\%jI3QQ3";,C&,(*("7) ? (V~Q8P)YX3I% 58 ""*$3- 2DJ.'#5!!67&54Mc3Og,./j2"33!PO_ Lcb-5%"753##5./7&54632&#yR3GkMp^),*' yU-J1& DJ3VGK)[F=8Y325!5!##5.#"c4#4,b3P3B$&3"&D/F"f33BE--,   s(>32533##4/&'654&#"72767&#" n6F4UU4 $%.% # 3#43B1PE3:."&!$ 9 ,+2&) Y.*3254&##5./67&'#5!!6;2#"' I<38b($fNr3>(69vK Zr7 #1?ZFA_ %M#6@33*8&1,'aNaP'% .%.+'675!5!##*9!~A3H''%Y.6b++33$X,GA.,0#".'32654'#"&54632&#"326%5!%`K9bC:"9%T,P"5R3O)4! K%3oX #!9 @s1Jm_:Q?3Z7?#00:233.!.'5#5!##54&#"#"&5475>NB93`#B2U)D>=79.&!"33C+P,],82N.67/.+5!##5.')9Y KU?3)9?IY7;G&4#9C 233LCR :F7""5j.#675!5!##5.+"754632#"&G3>09twF&A^6&33Y/, \'" .-;27#"&46326325!5!##4&#"4&#"L0&;GG;1.+&S.N3@'9#.%)90QR0+ 33Y&0)54#"'73>54&#"56;263533##4&#"327#" 4$I5N$3QQ3Q$!, <X&)-1=8k_&W3^s/6 +.&'#5!##5./6&'5-~"F3BdE*I;0|UL#A33@]G:%3(?+7qc{.&6325.'5#5!##5.#"#"'7326s@5"'2 B_853 :'30A,  -84EK7"33N4?4j#E.#2&/32>54&#"&546'5!6lY&_:&: M$B0dY:o2[p!H9!(# $<"%*9+K33_ 4632#"&"i2".$5!&/32>54&#"&54635)-AY&_:&: M$B0d/3NK+o2[p!H9!(# $<"%*9+K{&'#53533##L2Rb  3YY3:3 M33###53'>32&#"B_Y3m_* DXV#BUe33:IdNJ&Ww)$23###53.#"'67."&546ц TT3ccf,[o -@Hi)m33Rv$ *!$%H*iL#'274'7&'#"&5463267&#"0 *#= (0M9< */) ?IBA9/"9S @$463'7&#"327'#"&B1. !+1( )3&0b)5?"!#&r/%)?+dsj2QG~8Q%) 7'?'/+dZi!j2QG~8l@~8/.7267#"&5467#5! CL^O<V[rD3  :fK$31n5q807467#534&+"&47327273633#3267#".GA-Y)*3,2 XLG>=0 C0H"Q/342H #4M3j@~  :9TD {%06<GQWi%#"&5467#5!3267&'#"'727/&5477'67'67'654/7632&"'&'77&'#53533##BL^O<VZsD)B!* ($5G!,+!,4 0 !+s2Rb 3JJ3W:fK$31s6p #,*d3s #),%*u  44%+):3 M3 w4%/9?Vw%&'27#"/7'&477'67'677'654/62'&#"&'7267#"&5467#5!26323###5374&#"#"&547."*0  44K%,+!,342  !,OCM]P<VYsB&K /?hh4yy2@`S)$+*544 < u )+$* 4O#+' :gK#31s5q~;!,33$63$)7/Z'7+{({ 1/"'654.'&54632#".'732654+9.'!)0 J[g7_G:OC# & /8-.$Li 4 ,#H/5.PBTA4(84'  >426323###5374&"#"&547c)B&Gdd3yy3(B`T*4(,33$63!,7.0;%"&=#5!!6?6?67#".'32>54'4632#"& %.   (4wY=a9'3Q)=#$B 6(33 p"YoIg]$$6-2((4 a.+3"&5#5!!>54#"'6324632#".#4Z.M#"(Lj!- /733h]d# "mL_-!.&&+5!##5&/674632#"&eU I3C,=,E$Q(/K+) %&]23Lp/8B*5G# $#%fX '&Y;2675333##54&''75&/67.'#"&547HpC; #0O>393UU37ds42$eo$L&8!$/3$ ,8"6#'%y\3i=C+GT*8jU`N8H4 &2!$& tyt2>54/&'#"'7>54.#"&54>32>54.'&547#"'732654&#"&5465,".]-b ,* , %) &-# :F55&8,7 F.6R^R6BC&C=$ .8(!*4F2!$19"#.*1+ &&0!9-K>!+;%4 2J.1&6($*R83W );" 3 %1   #&$,62654.5467#"'732654&#"&54632R=2GG2 )(0;/D7#!+45,$/",(  &6#'9 &-  #("2(O4j2654.547#"'732654&#"&546322654/&5467#"'732654&#"&54632>2HG2# Cm/D7!"+45-=].g  ((4/D7! "+/5{#/!,) .Z': &0   "("2eB/"4'#4  0': &/  # *AA 4&#"326'2#"&54>pA4>I@4O<8DR^IXncK*8. Ml,%%#"&546332654.'&547ls=.A?1  19O+$==* 1EE1Mc09/ M=4/!1 40 +0=b1#"#'&/&/33254./&'7^2a"HC39@!* R'uH:''*"6E@~$@;#''=.V$*!&#-?,'2#"73>54&#"&54>&/;1!)BD$a3+mG$6O>$1: 3 #4X7A^/z C!*4#Dz%1= &,9C 262654'7>=&#"#"&5467.54>32\>s(>h%:r"B+%3~aGER'D@=&7/43(J/#C.@ $:O0", *1b8JL?'13M/%8 8&+61%03&5467."&546?6?&'>32#".'732654 Z $+) .!>cI>jF+3=o@1BL226J+#3-(8.!(!KOZwEo? Hm]E?`0;6363637&54&#"+"./57"#"'4632375' 89/"NF 6 l6(,x&CWL),*&v=g 4X:7 $  0"32>54&%#"#"'4'76326323;2?*-,;3N#dJ/%,$/-9/'   18#@>/#  JOg3"# >4%>5.'.547?654&#"3"&54632H('E6Q &1$&\xwR:)&:?G;7Kp I4%  - " *#/=pN` 3 0=+!7.258El: . '.+'675!5!##*9V$ %9!~A3@>e X,X.6b++33.!7.'77.+'675!5!##`:,n69!~A3H''%&&Q . I7 .6b++33$X,ba %.#529{M]M/b3=aOIf$ 3#2654'7#"&=#5354'80AA/F-,4_D99VV1$19F3Z/&R*."'<=sJXB3KNba 72673#w63/M]MOa=(K&$ %>75>54.#"&54>32%< 3@" '%*8(1[,Z :3+$'$. 4)34P: <1732>73#"&5463232654&#"&54>32#'"@8K}S5 3AR-2BY., " .9(7, ,!L;h7H# V]nѫ"D8#3(#3'(?=8N/'7;#"54#62i %*L9TG&7N#V.(7"&=4#563232>323#"&=4#"l + 2" *1&3 N?M?)" 34)51e+%72654.#"".=4>321K)! 2,# 1G$#G/98#`P(#3 $ "3 3 554<)"C.Qdt $326?63"#".'#"546326.,O+&?4344&#"3262#"&54>4&#"3262GC84F.e2&$ "!)C #+C86D 6k.  )("mD86DD8 ${&"3 ( 6%5CC8 #,| ) #'+h@26?53###"&54>=&'#"&54>54'4&+532676 &6+;džAN/7 '$+$BJ;&  &8\ ">]P1hF'Ai JE>&:*C$ &WI]7/$;" 7%!2"'"!##"&'&7#54&#"#7>}xJ[J0Ctlp\=Z5%biMFv'L5DY-!fKE7E@/F(50NCA4*H8*AXo#Ej64 ϳJtA 8[4h"?s,7"&546>7!5!##&/'327'.#"Pnz\gj-p*)2C)3 .% jZ5A%7H7rSYouEAA@1:tGP!|3UD'9 5J %2675!4.'#532!53##5#"'763%T )@E ikY ȇABcL%0@Z=1& AA54'#53232>54&54632'*ʉA$0EA 3:p <>2SFFJ&)4)! A"Bd#'KAMF4J3A'+c 'TZz.}'074>327654&#!5#5!!32#&'#"&7327&#"<>*>\4+B:M/E"_6,E")Y^D]@;*L;KHY+)265-"AAv/.NM1mH4SL8(?L!4632!5!5!##".'#"5!32>F3#<’pZ1MG*9#]O!;1S.?6AAsOd?zY~~f3(094>3!5!5!#!";632#".'4>'&>54&'#;$ 6 -  ^q%snrn+"54&#"3"&5467'32>7;4=q86:;kb 2 ; (K'' &% )3!W-'"'(l*";%=KAAATW2OQ? &8, - 3M1  KA!4%,;5&'#5!#!"3!#327#"&'./.54[ K l>2O+#! ;+)X/)@=;xx7AAA$,@ )70 A%h#%#"&'>?5!5!#&#"32>32zM>6Pp6w1 H|"_B)/#>"! euCJMA AA=Y3L *%4&#"32>".74>75!5!!wWPu=W)HEJ6#/[<4(5,0A1 4$#-4>32!5!5!#!632#"'&'#"254#"77%!$ EaG>M=h4:}YK"3#"(u(7AAAV=!mO07:K}9@(,-7>5'&'#5!!&'#.#"632#".&%ZYR'>Q"P-G2$i!HGW Bn0 PiWYiW<',AA'4 < @5(N9 3-"N/#"&54232'.#"#"543232>7!5! 69x$2/P(HjZ*LM?l"'  @Mq.?e(>% [ ?{:@5/  AA 7>54'#5!##5#"!5275!0% `AXeb !Jh >,(,>AA=G!.R=4<Q!4632!5!5!#!32632#".5#"[+#Si(~ kMId6H>5RJAAoz0N*QdE7>54'#5!##5#"3270 g@Y_b >YEhB-+2AA=3.5fKQ<\%".54675!5!!5>54&&Ay!3%,.PR!(%3 wm]H1=A.B/[AAY+E& A=1H]#32>73##5#"&'&654&+532+"OW75͍@LbPM%* 6H AEQ('7!5!5!#!">3274#"26wEl1#B2 *)A$?Ta!W+ZQ>90MO%;tAA>&. '&G8;IB1)+*}#!#5#".'6?'&'#5!#!352675#Az&Q^!\'!WI?>0m 9_Vv3E3GGDyAA?S-.;oJz/9!".543232>54'#".54>3265!5!#3267&#"*pP6`A(; -hi); $K4^HK-p00y!)1I,=Ij+!1'=*a-'+,JPaAA;v/:!WqO!&(<74>54&+532!3##!#"+"[giʊ@&)5YD?o?WEAB)Av"4'#5!####"&'76732=35!f `?''D'@9g+5s RAAi$5 m*O|Lq#K_x".54;5!5!#'26=#"t;eH~K7$LZ]i=lAAeYM?0&(=bb&*%2654&##'"3"&5467'#5!##!BZS>]\?T%/! \}iINMGj|_Q|{;[AGY^B%; >}][p AA qZXD 157#"&546322654&##'"3"&5467'#5!##!R3BZT>\\?T%/! \~jHMNHj|_Q{|*!& [AFZ^B%; >~\Zq AA sYXD+!5!5!#!"3!#327#".'.54> ?$'+N +6%8 ;*)H/"+)=xAA.0@.= 1*?5 4% #)%74>4'#5!##!#"&!54632#"&3/.$sA  )z$!Z]wpAAEtv!74>4'#5!##!#"&!53/.$sA  )z$Z]wpAAEtvt 325!5!##".54>;#"v!6U.]I~01;^ 7$1(LDG3`AAc.D"LF #*@]d 2#"&54}&2%57##5!#@dBFAA.#"3###535463298G6@}}kc64L:cA@A:g)Q5!B23###534&#"#&>;am@\\2JC*@#Dg:A@Af>H!@=%@h #"'5327 $%.Y_cUX^  (A('h #"'5327#".'5327 $%.Y_cUX^iY$G%cUX^  (A('' A(' z2.'.&547=}!h%X7 J-J&x)2Z!'|#4632.##"54326.#"&+#4hL=`-3;TB4="+[6:T\HG)&# j] !m!"&'&5&#"#*.54327   -U    1++ 4 9*#".54."&547232632#"'67&#"  2]$I/a3E& C!+2+ 5/)8?4&5$&K, 53& #?1&#il8# 10  $.%2675!4.'#532!53##5#"&'76#"546323%\*q  ik0' ɈAY"=" !32 /^) A[\A33X[0  !*7#"&54632746;5!5!####".73275#"_\Hv@7!5!#<^TA8,h322#"&547#".7"32>54 0W8eh  8M5w-I+ FW#4)29',3%e] r)E8/aRb?(0$?2. ,p+"463 #"&/&543232>54#"#"i(>;h2!^H*l{\%t4;7[5~H2=DJP1+2)[-3?YI.,t9 $ !*)),632654'5".54>76.5474&#"32SZ]`Uj) +GGJGG,"jUNPQN5ZX7Z@">1 -.C!!C.#3 !!@%"@m<..<`3273#5#"&'&654&+532*$WOMe@@LcOM%*=/<(8HFEP)'5.54632&54632#"&#"yH; ]#<`VJ9p1!AO mY%47CHK @ -(/("=$7@0 G/V" ^F#7" *1#BO D DB )$< G*2#"54?>7>54&#"#"546Qi *"9(E*&u8:Fb%kJ+U  ,z_!;4,*!$"4*|+Y C`% 3=YX"4632!!32632#".547#"V*M-IS%/k4dmQ4@2TG@"6`jK1 #=]c j@4632!.54636#"&#"#"'!32632#".547#"V*  @KH @ !-.#%&-IS%/k4dmQ4@2TG0H  (*7  "6`jK1 #=]c 2#"54>&'&#"#"&546(; $  (+>1M'%+&(%/5$<I 5Bq@#"&732>753YHJY 8J7 UimQ$1 4AA %767&'#5!#'&32>2&35-wZ_49C=<K$>! b0lE-{T[gnAA7$!f# &^rќ *0<.#"#4>323##"&/47#532674&##326@^v7R/ @ &=kFTv8cbLEt'L4Ozy29Z,kaA6Fjn+=5%EO9&5ZW2AZn"Dk65 в$AAQb7[5 <Vbhs2#".#"#.'&#"!##"&/#53>32>#"&547#"&54632'2>54#"%3>74.##32>sI, %4\;@z  ! 3G! ) !:$fT// {yM" & +\FMOdhihW,4$@tu4.?,^>+ )=*:A)405EkI]ϳA]ELw=3353###"'#'32654+732+ (/ kyssyi8%I9C[G !? 5"xDPcW( BRUDFTV-#32>=3353###"'#'32654+732+pp[)/ jyssvi8%I9C[G !,X 5"xDPcW( BRUDFTV*726546;#"#"'47&546;#";#"(J8&d)_FCOX7 1UL/I#,  ?0W CU>1!Y8GS6'X.! /,46;#"#"'4?&546;#";;265a4!c*&z^;PX!>ULN5/-F1>5H2/ES5 'S7IS1?F< &/ ;5"3674&+'32654&+532#'.5467.44@F1Z[('d3B> p8Yl|7eF= Sd B0AM*'V( !SK7k1#GX k<KqRD;34632#4&#"32674+'325&+532##"&5qtpj'IH+P;8JHXYIHd3C>_olmEGe 3l!B-#@-'OSK=SK7C?eJUfP62#"'732654.'#5'74&'"'4>327537&54S.L6fEX29#(<)1sNR#*O?*Y08]+AsP9OAB@OT12. 0%:OܠMd"c @Bdq&": I'30'8'='1 '9'9 B)4>32&#"3%#"/732654&#'7"&G"9; M^ 6?f0 ՆSVL^b-6KXb. P/!'P8Y+.D;/%*G3UH "#3232=33#+"&='&+7gg!1>Cklj"I1Lg:-+2=;g\(3"V?TJ/#34.#"5632#"./4'7326Jhh 3#L->u9  !-Q22"WB'9;-)( X :$9*<- # ?M9'#33267#"&547.54632&#";#"9qp53nYg-,,L~}K. :j.[JC*9':60Ac^#//LN)<(,'(G2& "'7[<+!'75N'=<B-+;2673#5#".'#53267'&/#532j!7: l ,r qrr52%! 8 * 9P].B!g@;p.  T# TNY0<747"&54>;#";#"27#"'4672#".32654&#"X#G(! J<)I&(?TA44 S\PxRp'"%'}H/D3"4 S4#X.\}Of0dE pV]P ;/#&51046327+.5467'&'&#"3265#".WFAy."L $@(3:(1N-" .,/:(EOaY@. R aG>I<f 7]($'0X #JS;653##".'532654&#"#"'532>7'.#"763632uD, 76 ".4*,;;W*@-%6 6..B$9CH4MQ=He0ZYD7G(7_JMW')=/AFRX*a353###"&'7327'.#"'6gxjoojr_,o )P N-L"=kQ"Ij;[ /&0;[&4&#"7633267#".54>0+:1C-K%C?&0c9wX+NJ->YZ>f c9'.91(XF*]&>)P8*>!#*2&#"#".5467&5462654&'"$@-)E[>YY>-JM*@b8# X77p?*NGgIVYCGnO)$4/AR)@N+=,%1;&7C&73265'.'&=472&#"#"'&'X j2:N Kz(=<4.Bd^#//LN)iV;}G2& "'7[<+!'75N'8&% 54>54#"7633274632>XY>l2C/Kvc=XW=@-H/{:-@ "3 gQ92:*%-9K9_3Dd+#3%#"'53674&#""76"&53327dooG]$H1$%(M-# %%srO;T@h+bN99"Pa+5RՆe:CT%\ ".54763753##"327;F5$=:Rqq9D . 1T6R7:lSF;{X44#5#.54637654&#"#&54>32'";26734p,z-o0C;_/5-a3 :%1H$WI6J1 :o.""bSH&06 , "13HS 7F+'7";27#"&547"&54632&#";& $ LJB[gN;t[=Y=+,  !TTXgVJ/;+?MUDP46.#5'.547.547654';#"326734pKW=:0A*b-< Z)1):~LG9,o4v!" ?)A,H)L &&RM'G+N 72654#"'463!53###".>%!QK"$HDSqO*5G>7".=4+53237673#56O$%[<%"(? rrF7%6+T,/ 5 _C34>32&#"3%2#"'#'&'7;>7'&''7&\ 553b!>9>& 6g|fkKCWb" ._ Q,  J( 'YU.HO~5A"'58d#726=3353##+"&54>32&#".;osoosqY(ch!77,.9IA/T)Eal9S) Lu+".54>32353##+.56354&'2"-&RN3RT,8@,kooi4(8,U)$O6+-BNr: A*: $5A+]<#4&#"5632353#5##"&543s#%=jppj;.8+bQ, X rj$ &;&`+)#5#"'&=46;2654+532"&#"32673+qW\fQW `+EX7I|* 8,3uq/t99=a(;UT@#2:7265&+7!2;!"&/#5/>lIe (V-%MT\D%y \ TU$#5#535327#".54632&#"po"6*7E9't)0"53 51-SJW&9a32&'3654Mhs %! 2QV~ ?+  (2(XVHl#45V]_8l+QO1 R b4F_#5#".54672&#32673pVYB[,jY5-'64+Wp,>*GC&P`N/9k*'K2#3"27+.54>32#.'&+'32>74&Kpoh,&1(54&#";27) O+?.-Lz%=M`YC$ YB@K cIwNOYw0&SP'?=A Q %.A<)8R6[(+#53ggOe #46;#"#"&54323254/&=8*$6e6 :%Mn 0p6g50>$,S3- +$_*#a47W/<#3qq,^4>3'&#"#,JM)g9_HFUpKl8R.,)!^`N,2#4.'#"#&=6>@{Hp 7&8 XdC?O7B*#0 #'2#"&'73>54#"'6I][KGh<7P$'%H'%78YI;)7v2=.CaXx$, 6)\-Q*_H%: Q\#+)46;#"32?'&46;#"2?#'.G:C 4#'%R-5G:dWD8>'(O->IpKI7 =( =9KH7 =* Lr #".'3327=#D&>22`-x)"-[=t#3` O'7#%7uh]Q"G_ #".'3327#3"F&=12a,y) oo.Z=f)#3#3_oo  '7#%7#3 ]P\MLoo:& 2#'32g =g2#"&54+"/3;674&#"#"=32?672#"/7326%327'.+7327'&#"'63#".'* %? T=o-gv *#)5#Z0-O)H<9$p]W8*+R"4H`4a db;Tb c32?37&54S.Q  56* e)0n^,rOR#$U>.E#6^-AsS6(8F,j1J_OݠMd"~c +2&fn!: !I>#3oo,,T#3#3Tppqq,"&5476;54.#"3265_B@X`=?# (78+'4_\EB@B\_&7 P9:JJ:&463227#"='.7"37>=4&hSNg+3,t)"8>"*' $#ANgI<#"d g Z/) ]!7432654.#"'632327#"&5&XF7c =*=?Q0k6,7H2M^T[Q 'OiU,)Z[J ,#"'7;26=4'"7367'&'#"'6Zod}]lk6OA1C@ ~TI cNA( lH`FL82)HV;+P!#"&=47&/7'327'.#Ml}N`@Y*MEb #B0L5]E[\Gp+"Lu/Ga SB?!%;#"&=#"&=4+5323273 "i!44E[P "$* 4nE TqT:T -"#!.57467.54632&'327'##'26=4/. B&.C`v90!P)=%o$#)fq-H/\!:3HA#AD N  8Rb '  2N=NL& '*%.54632#"54732>"3674&j*LE)`CSf "5V:O @4+@ 0*#`, +)R9HJiX>b]>%]%7 6)2&!,-3?h,'"&547%327_BI>0;AI+k5hVY4P1%1Qc)"%#53'"327#"'&547632&=o ^E"#0.nPOSVp"0'Q[M*9Y^POrmNMW "&5476;54.#"3265_B@X`=?# (78+'4_\EB@B\_&7 P9:JJ:RK E%2#"&5464&#"326%54&+'3254'"'7632'&576326e0<.-0=As"%'!#%*g5A.luk].@K(N`B&Y@R:qv *8*J@,(5?-0=m342'/BKPDEOCU$"8"JY x1 A#2?OR 2#"&464&#"326 %77%&44]  2'%54L3Y !,#!-#"&54767.54632'4&#"632654'i b!%-/%8)?32653#5#"&54>7>54&#"#54654#""&4632632U9PQ9d;Fu..o7Ru8,&%J -5,::),0(3.B'$9'/7>54&#"#54654#""&46326324+-9PQ9d;Fu..o7Ru8,&%J -5,::),0(3d.B'$9'/4&"26'4&#"326u+K8K%`Vh()*)++#1U'7C3}.,}y`:usE0*`|hM7# J68IO.9c4R. a#:"B>!"56(>%#"&547&54>32#'>54&#"7326=4&''7n(:/H^ 3);G8y+K8L }d9W+B1 D13DB"",,A YC,T2R/ {NFtwU)d~*>5"A2 *1E=/ C  %8D#'3254&'654.#"632#"&547&546322654&#")47F O(!+ .9)2L& &45MJ85N Pa4F9( ,- -+=3+>":v?%%O)A$+>6(#O59KO5&0Q_ .R4# 21!$3!#3#"&54>7??C3  #slz   &\65#"&547332654&#"'7632654&#"&54632/LiM|yP:@>I9., #$&09$# /C-0A1C$dFU{oH76/< %4/ 3 !,@N7C"7632632#5&#"#5#"&=7'&54632'654&2654&#"+F) ,,(:. &-" 01`k+z'1%04%9!5E7 %-'_l  Uxe1!+/ 0/:26753##"&5477632#"&547&5463224&#"264 4..860;!$7GH29NUb-# +#"/,J)q5-?B3.3.,J75SO9#[aL #,."&/.#/253#4&#">32#"&547&5464&#"326-{--qVGe37GH28J P)#!-,"#)-'Kt\hG%)J75SN:#]fzh$.2!%337%#"&54>7&5463253#5#".#"367326=332?6-H  UfU]/-"5z,O8Pm6+$a&"0&')1@*& m`pIB",*\H/.#%CP$'QP#%% '14632'654'&#">32#"&5.4&#"26ZqMO 0+2?kG1&?*5JJ54K 1N,! ..@-;^MKj5:+KG>NdH2N"+I56IH2 /F!-.@--=2'654&#"63'"3267&54632#5&#"#"&547.546q 1 ZMn+#0 $% '@-:%.$",;3D m0 (UzhJ<#.8'$20-69?U7-"_?5@4#"&=7"7632'#"&547&54632"264&#"26,00L4ON?I2K45IK9 -:@-.! , 4632#"&72654&#"bfDCfe/fkjTRg rnjUTn^\[/4&#">732753#5#"&547.54632'76r[Cm#"`.; --%<4B'/\m- VxiF#.D+AC%H5?,\iH)1%".54747.5463253#5"6;"&#"326754& 7R%-)`pT-/ASi$%#"4P73i w%5, ;5ZpYRLJ]B5 "./AG)"Ws +C%".547.5463253>32#"'#54&#"326"326754&#"63&7R% -*_pT.('99'00B"5P73lvKPm$%(!%5,;6ZpYR(DTA*LJ%'6&)+/AI'"WZE5 "&!;%".547#"&54?&5463253#5"6;"&#"326754&V7R%\)f:`kY.0ASi$%!4P73i w%5,8 -<VZpYRLJ]B5 "./AG)"W$/2#'654&#"632#"&=7&5462654&#"vDI8LNsdJn &46ML75N Q@,+! -zFWqvVEfwiI(#O58LO5&0Q_4#"01!#48%#'>54&#"7632672#5&#"#5&#"#5"&54632 %G7I'zd ) ($3  30Fu}$[os T(^'   Y;ky@2'654'&#">32672#54&#"#5.#"#5&5469M?- .?>\Uk2% 3 3   1Y !4\:A2P==s[7 !    ;dm/;!#&#"/"3632#"&5?&546;4632534&#"326-Rd+*A%+,)86LL68M dC;F;PH-.!"/0!"-sw'&!%:$".&O67LK7S8<:SCVa"44"$45#.%#"&547&5463253#4&#" 32?32?'[o?`W]pT..qP7.\I2a*-sSVL9 *!N]YRs\#:)- @%+03L"#253#%7.546"32>?&%;) //nBGb1K%L.  S 6"TeXB;[r/%6.+=:!N932'654&#"67;2753#5+%7&=&5.546j, lPB]$5-+,+#2 Gx1(,}[F4JeQA# )!,$"'p@4+&5_)1.QnA7#3@+-&A .#"'>32G %N;6E)!+Z>GY`!""%&$3#'7.]>"k5#$267#".'#"&5463253'.#"32 ,>-*;-::'!3+En0 :3&1 96+'9Ki/"1,=26532?#"'#"&546353'"c1IA -;&S'0D=.+*#(iU:<7:,&6<%L8"3254&#"?2#"&5467 H.O ".B31FC/\#('%)(7, V R&2#"&54632&#">4&#326k4U1! J6bvmd88' ?,C! *y@$-=,6*5Wrs0/K+@68M<?J"632#"&=7&54632##'32674'654&#"7654&2654&#"2L& &46ML75N Q`b # "54X#99r@,+! -+>6(#O58LO5&0Q_|`)*#,P#1Id?4#"01!#462#".%4.#"276y??|X+>2$+5&E342155rMNps %9hB4S. ?@^_CDDCe/.54632#"'4&#"26#Oq4]LC`YC<1'mPA.0AC\A+wuY#OaZAFc,Ko00@A/.CCi/'>7#"&546324&#"326i5$%HdeEL[/F24GI21G(S`ECXa@3GF42HI/,2#4&#"#&#"3274'7#"&546326u"4.;'!:-"=1?0%% F, 50TL@0./,L/,DC`:v%(5"3WDYu373%>7"&546?.'74'3262r;^IZ[].""Hd&4Ls-8@03@bpI@_3t6J[_H&Q/_?IM$871AD -(2<./#"&547.'7'&546324&#"64'326'u3Cu3&-21" %").54&#"#"&'7326 &.&X:Sj2BeŅU8&:6M/5R'#)2;)6DmTu61RW;](! +:> #05&0"7632#"&546325267>54&4&"3260G ?+8;(D`U^U!PWbJ, !'8.&=7*(9gEP|^l*.4,fRNh*85!#!.n 5/{8'3"'.54>753{=/0/AZ  -=P9Er!&4T#>,( S> 2654&#"72#"&546(43)*43+;[[;<[[F8(*88*,4];32#"&"&546324&#"322T42,)3=2+)11)+Y@;[`6+@$,# 7_a5BV7`Y>;[a14)*21+*B*87V57X46T7b5aY=CV%5."8!WT`NV@=[\{B#&$?QLI6FXh20TZm,Y:1-:Ly A*0>s Y32654#"!3264>3233632!".54;#3254&#"#5##".543!654&#"#"&) 6' ai!0:,d7!5B/UR0< /"71{%k~WNmgH$.@14=3%&>/?QLB%;!h20TRK7 *777"- Zm,Y:1-:Ly 9(3EH[ IR\e4&#"26467&54632#4&#"632654.##".54632#"'#"&&#">2654'%327&'-#+*B*#A]C08N9'O43F5%8 wQn"jsNlht9M`0=w<[AuBJLdvL7-RvV?~i73%#'*5KDvkЩ{fV66?I3/>5C /(GUt??AIa>[N&LX?#x2Bb/T&)-"LA[L 2"&546!2"&546###!#(P(d=<uX< )34>32+"3!!"546;2654&#"2#"&7"32654 +EF$VxC=Ns66ls;,.]TE6)$*5+-:g/90F#nSK417T(.G,CN6R26[ / 0'PZc4>32>;####54&#"632#"&%4>32+"3!!"546;2654&#"2#"&2654#"3254#"-A55O?#7%Y7H7&Q/@B2.E+FF$UxNt66/s;,2YTE6)$*5+-:b.!3;2@]+0( 27)e3@A+=-1=]k0F#pQIg7T(.F-CN6R26 00/8%%#"&5463!###"6324&#"326m"3+[tj*(ŁPq;3:5M6#11#BB.4-#K4L d:;k5+%xuj]E82M%:%%(  ]72654&#"2654&#"4632#"&547;#"#"54632>7"&546323254&#"632#"#-* *({# 7ѠVF7F 1G3BB$%H3H,-<+"6*,8UB*%Tx 0(7@H1;###(+ \Pq;3:5M6#11#(84+8;B d:;k5+%xuj]E82M '0%4>32>;####4&#"632#"&73254#"%4632#"&547;#"#"&54632#&#"32767"&546323254&#"632#"7"2654&-A55O?#7%Y7H7&Q/@B2.E=!3;2ѠVF7F 1G3BB$%H3JU:/)=<\C!1,8UB*%Tx 0(7@H1 0*>*('@]+0( 27se 3@A+=-1=]/8Pq;3:5M6#11#BB.4-#K4L d:;k5+%xuj]E82M%:%%(y /35"32="&546;5!#32#"'532654+a2wwS|2$n5JZ; $#*8`Vb+,GsBgO)D6Y9:O=)$[[DM %4&#"###!#63233!53>5&,76",;\765(,"."\)R6Q8[*7 Fs "&546;5!#3#75#"32#3S|1%b,a2wgO+B67[DMB&,Gw  ^32654&"4&"326"&54632632#!"32?632#"&'47#"&5463!2654&"#54&#"632T# ,(<*.F*0$ *PAI`33oWrngA]S8%PPY:MK4/?L;Kv_REYUzN7`B*H :KS&#&#Q#,(D*(`SI_|bb`n~6d?3`4L82BE/"1aGMRkJEq]ADf& R;8G C%32654&#"'463!#632#"$54?232654&#"##"632#"&6(*9;'@hl(8MWN &CP}GD).&=Ot2ZDSU<[t'0/( A;0h=!oUamS^5},O1kKAOB?]3!!6AS7"<HR\74632>3263!###"#"&547&#"#"&547&#"632#"&7"3254&32654''32654ď]L](tAGD:d*0BVPFL^!>9+_:%5,'9`a`5+%<|+))6RROrnJRROroINTJXBDMp-,;`&;17Y_1yAOOKo8Xb.zg)-7#"546;2654&+#"&546;5!#32+"35##"3254>Iev><+bKS|1%+Oat6.[8w.2D:\XBP[DMgO+B6oRsϋ&1Bs&!#632+"#'546;2654&#"###'!DMvca6@FQW91- 776wQg}X. ?7\R;T'R*4@74632>3!###"#"&547&#"632#"&32654254&#"ƒYKS';<`6*dSCAT^5>d*0BVPFL^`5+%9~*6RROroINTJXBDMp Ko8Xb.z`&;-,;'3!3!67S2#!33464&#"3263X7HE6O`J5))/8Xc.UnS.>AY'5T332653!3!5#"56,H457`I&UF(@S7"K 1 !#57## ǐ66XBR8/%+"#'546;2654#"#4&#"#4632>328t4,7AFbq#774'-6F9(A@#b_ř"- "- ?8u>$L(:B R>T), 41=%4&#"632#"&5463232654#52#".=7'"32654&mOD~3JCX]BMfkg40KWp]/E#.=8*,97DywE9WC@Qz[rS7>jQ6f 45 7:-(10)(? @&274632>3!###"#4&#"632#"&%4&#"326 r3]H57C(17f8Su5LDQY>W^;'$;:*(5q:'*76RJ/7ZrP8TE=Ny)>>#'2. <%4&#"3262+;#"#"&546;#"32>3&5!3346P`J5))/3X7HE*8@+Q01:E,sm N4+776OY'5TY8Xc.Un01$C$=707 =&-&NS.>A0".74632!3!5>54&#"632#"&7"32654&udOQN8?9FvQCu -'BTUAO[(14+)37zFJb;1cDQqV;]CAPm5),73),9 1>W%32654+%"32654&%"37674&463232+#7!5>54&#"632#"&5463237"&&bst(14+)37$6O.)3Q@9P #k9F=4a=a9FvQCu -'BTUAO[{dOQN@>]5&C<5),73),9K(!(^ %n:jA3PB76C1cDQqV;]CAPlU{FJb;K =I74632>3232654'52#"54654&#"#4&#"632#"&732654&#" kBu M,IPM;PVlf\ 62087hGD~3JCX]BMfT8*,97%.=r,$".ZG*H7cn%E6BB1/;DwE9WC@Qz(10)(?:MY%#!"#'5463!2654#"#4&#"!5>54&#"632#"&5463234632>32"32654&u107AF6cv"775'+w9FvQCu -'BTUAO[udOQNF9U$>#b`(14+)37Ś#*%- ?8u?#L(:@"1cDQqV;]CAPmTzFJb;>TH,L5),73),9  !#### 766RRL4&#"#&54632VSB`%C]mq7_rQ<4432#".54>32#4&"32654&/j0T@DIT>Uv3=`y7fu*7-)"9-Ôth;JVH=Nnhmq{ ]m!?-*1>"*= a /;"32654&4632#"&547"3&54632#"'&%"32654&$;8,+8C(ϨYXG>U9UPOVz8\A;cbnl)>:*.=C<#)11)$;ƨ`MENX>E/le^e8DAX^8Weuu3C*)58,&A/:D2'>54'&#"#"&547&#"632#"&546326"3254&32654'l`7*8CBW'$dSDAS`7?c (1AVPFL^Ə_GIf+56*a;4+(:b_y}H#o=V9;RPqoIRSKYADMoR},)6+*6`':18X`0sGQ  (4!####">32#".54>32#4&"32654&*76j0T@DIT>Uv3=`y7fu*7-)"9-6RRÔth;JVH=Nnhmq{ ]m!?-*1>"*=  /;E"32654&4632#"&547"3&54632#"'&%"32654&%!####$;8,+8C(ϨYXG>U9UPOVz8\A;cbnl)>:*.=CH76<#)11)$;ƨ`MENX>E/le^e8DAX^8Weuu3C*)58,&A6RR ` &2Q]%4632>3!###"#4&#"632#"&%4&#"326">32#".54>32#4&"32654&*r3]H57C(17f8Su5LDQY>W^;'$;:*(5j0T@DIT>Uv3=`y7fu*7-)"9-q:'*76RJ/7ZrP8TE=Ny)>>#'2.qÔth;JVH=Nnhmq{ ]m!?-*1>"*=v #"54632//1 @&274632>3!###"#4&#"632#"&%4&#"326 r3]H57C(17f8Su5LDQY>W^;'$;:*(5q:'*76RJ/7ZrP8TE=Ny)>>#'2. "%5#"32#3"&546;5!#!53!Va2wwS|1%32327654&#"5>32#"&/####!.) ):ƠydoC6C) C"QY{q75E}K+ ,K DMsBnKC$`]V٩ Q6RR;&*%3#'3#%4>;5!#!!#"&732=#"%#3<<<<$QaLS|<_4w '67[CNgC,GsB&k$%#"&5463!###"6322654&#"m"3+[tj_T,?=  G#*2-/E#)* :'$/DI60A)bf~2( /+O52="&54632>54#"#54&#".54632632#4'7&#"326SjvW%yT9CA&E3=#S7Y/:P@H41;U"x)HF(*c7-;64P'q 8)-1+922kN5 71d6!AH4&#"!2654#"72#654'##"&'#53467#5!2654'73&546265!X(2M E4;T_z~pVrJ@ ;H!%iV=D)PV Q wZa r"y;bV 1 V OQcsLmV9 (?-^y?a232654&54632#"&463"32654&#"#"54654'"#"&54632'654"3254&546*36( p:4mjWU=KK= *(&9cIDX_^|7D YU54T 4 m $<&Ax6; 2`hlcr:l?3 F\J^C= "cjO f40 @&vbW<+ /dnS BX#!7326533254&'7#"'#"5467"VE'@C5':c3$;7rL.G2)K<*.;Dr ??OD&/?@&1%2654&'#"&53327#"&'#"&547&#"32653,\%"&8@D/&,'Q\>;/S*^7654#"&54632`$2XC)-(##C@6i!1WAJ3"(3H4J.74>74#"&54674&47325332654'7#"'#"&.81304/%=N(K( -. 1%XC.(% #5?9i!(`=N"9"1; *9Z8 2C#A$(#8#%!'V(.8EAM@@OjpR2#"533254++53254+5#"&'#"&54?654#"&5463232533254'71QAA ?<89(I !+%3;46323254&'#53#"'#".54632654&#"&327&#"Q6GY*s(>)O61<$E#ffDSJ#E#Gf/:Cr2\2\f=[RY58q B2#"&54#73!5!#"&'#"'#"&5467"3265332654&573275 TE#Z[N/(@QAV$?I-; :F;+fG0D226rAK2#54#"326533254'7#"'#"&54?654&#"&5463262#"'4BWN%G -O(`.4K;(K!*G=g4AWIS-S-W7]:W/<"*! $OAO2/"="!Q2.#*?!"? G,?Q77UJ4"=$)$1 /)8JJ3S@".=4?654#"&5463232533254+535#533##"'(< (L&3M 2J.]VLC3i$."2(78!;)  '$240=9#!'VVHW:r9$: ''8V@@ ?@232653#"'325332654'7#"'#"&54?654#"&546"3A-1EGya;%A!XVE0&1#(A7n3V@J&F%*A>T %#8O37 8V(.F @&8IFFLB66#1  +%1C a%&#"3262#"&5472'654&#"#4&'#".54632654&#"#5&#"&54632>3246y%HbF#H?  22F*3+",!$D4E He4M#vWe4.&9CJU%3EQ9g!:9(ASn**!  w!?,]dB<>'>2Y[*:' 9$ ;6(-U/B +/((K.6.5%&DDrQ#"&##"&'#"&547&546;#&#"32'654&#"3265332654#532654&+532D8FA?'L5M@SPA1"P 12 .;:";-&)9@5#.b"3,$ 8K<\9hKX6pMD85#5+2)4yirr);9_=_;;;K A;%4&#"#4&#"3"3273#"&547.54632632#"&5467326f54UVS5qNWW\EqM3WD eOjQ4xdzkP54&+532654&#!5!#".5473C-=*!!+(J*6^ /Df[n&T"3> "$:!' (;;;5B;J)=-M!2*P o !3"&5467#5!#"'#"&462#73"325332654.3CF0v,]3EE3v0b" D#On"#WDW!&.\N@J%;;,M8V== ! PrN)5VV0&/hN  #"325332654&"&547#5!#"' Sk%!WDW(m3CvvJI2= o &*"325332654."&547#5!#"'3# :A-EWDW1(Q3CllT?0>E3v0!#D.]>]VV14@L4N@H;;-M8V==r %%4&'#5!#".'&#"&5463232]>%U7SF.;'"&(= ^:+<-M=;Yo+Qi>c2+%):G0P0L(7467#53#"&73254&#"5)]k1q[XuCT=K>=M.d;'"r,feI\BZY &&=G2#"'#"&54>323&544&#"3262654'!5.'327"3254#3 R@T))TAN:.S+$@R9O!$$ N8M&)$*?*FI(bqqj4YJy ye!4h6T.'??&/S7gwwO!4 S(%2654&'3#"&54>3'654#"/a~(M#'nSMP+&WK;]7% o0K) ."8G9Wj ?`BL4&'"3254&#"27#"&54632"&54&67"&54632#"'5324&#"32#5vY"#<''C1)< fUH^H McR698,' '!>=m)=77K!<:,6&?? c*$21% `O6T+5#%3?@  "32654&"&47632//H$kAEgc ҆JF_fT"3+:TO?ANr<9o[VO2'654&#".546/2R/ CFFXDAZ&3!%7B3[XrHdfF.EL9^Nc@ %4.#"3&5432#!5!2" CxUXtj-E"39OsjhmFO #-"&5#"&5432654&#"'6323653%"3254&7.5432#64&54#"3>334CF8*CEtyH(UDbf/3883`!?4"/52$ S:k . 0DS@8@7"326'4&#"#4632767'4632#654'#"&5476$">7F5 ,-:8/5A!!0$*=(&))EKDRG%-&'D;&Za9W,.6qH H$2.( ( 1H(12:4T8!at1%5-### @$%".'3!!"&547'7274&#"326&(-?0K_gE OmD;KS/ $)FWEm@rx;9!&W+` 3!!"54?654#"#432.AB.3"%ۛ;l;4H|1Ff'?*%+9pE ;!%3d6@(%4.546;#"#"&54632'4&#"326+,4#U-L44CA[gwB42?=!"EV54.5473vucPPH-?!0::0P 19?2!x{b0310IZ%BG+4N.%#(C, %+!07Z<0%%#"&546765#"&=3;4&#"3260ke=57U P KbPWHJk\KJchoqc:`N -nQGPJGJQM<F-9%#"&54>767654.#"#&546324&#"326Fmi&F3,%)9PeNLN$+*P\KQreHPmj|~g*A)#  H',?) NefM: (F0Ka^OH^X<-9#"'.#"#.#"53.546326324&#"326pXP8$$ ()&$$v(V47LfWY7=jWlP>:=E@<@>Ys/XNH+"#[\2"  P0LYNN~T=YZ>=UR< %#"&547332654&#"#&54632o P QLJEG;NC Py^Zyo ))!Nf]LJ:?cO]e^W<&%#"&54733254ᒐ&#"#4632*+fPPH4D<7#"&546326324&#"264&"326dg{ -@B]oLGg 0CbX{r9)*=:Z5>PTSADPd~zg%UH)'YAJ[YF#Fl)2:*-6>AGRBAX`P-*%#654#"#"&=46326324&"26-1P1\43<322VQW$G01F$1&P$3:dABd9-TR11RT-[YVV>n]77]n<%%#"&54733254.#53254'5++gPQG0# \ADMP0!RNOpeI88CHW#32<qr< aFc,\<oA#654&#"#54#"#54#"#&'&'&!"53&54>32632632o/Q0/0,2AXW@BURPQsa^w>AYeLmrZ>TZA@V\P(%#"&54632327#"&#"6324&#"326cgPgT;@ -va?e\PXA?VSD@WasyfCeIP[>z]AZS?EZVP"%#654#"#54&#"#&54326321P1\34P43\1P1X3/d^yb5I55Iby^(LL<2%#"&547332654.#52>54.5473{\ePSCAH//(5*8QQ8P(=F=(S+(Zdkb#BMMA(1<*"'B, '3?/KT.%#"&547332765#"&547332654'5673sij P RK5--8b7;J(B_PV"6/+Qi|k0)!Lh#$b9)8A? M! 0 < H<9%#654&#"#46.'&#"#&5467>7673632632ASD480"P .29+$ZE{z PNi` -A*J=VWlk_Uo;U"850' K47t*ml64#X(,#K2/+$OnP%#"5332654.'3bPDUP`pVD$8+);<2>J#".547332654&'#"&5467.546322'4&#"3264&#"326&@X`51^W@'OPOpuIB4e=Bc9,)3]EBV!&.1'%15+75'%/+<%#"&547332654&#"#54#"#"&547332>32632')o P QLIC -"*P 34;P*%( +Z>LZNQo ))!Nf^K]15."> A47 $>N><7C#".547332654.+532654&#"#"&46326324&#"326A8opDvWT hSXi-$<9/>>0&> zU[~ZeC?3N`I<5#654&#"#6.'&#"#.#"5&546326325I.79/! P$'9=LCBz|R PLni4sAqh\b6;dQh,c_aO&73 iPTLJEA^Nd#P#I2'( Pxh*01N`]L:_MD@AH1:PR,=(3%#"&5463254#"#6.#"56326324&#"26=zgibDX$ P%#A6IO&-]ROPbGJ^a`zldfn=p!%':3#/"Z3<OXPo(3.#"#6.#"632#"&546326324&#"26oB#%P $XDbig{OR]-(MI6~^JGb`aW!0#3:'%!p=nfdlz2Tb<<3HPOFGPN<w#.'#"&547332=#"&54632537'5&#"32wpn P PMOM;YU;E[PpppBD%5/!I/xm+*)!Pd9@9:E=\GHhO4!"P%#"&537324&#"32^h|P^^~PQ?BVT@?\thwv~XQA@Z<<I%#"/#"&'332654&#"57'&#"&546327654+53232654'7/eCW5a 8t$'~ #L'78DMQ9MTVH+7>-.? 5{G.!E$?>AM_a+Fl&(c*) 4<>#"&547332654&'52>54&'56654.'&53$!?)EJ(YPU>:R0@!,';CB9;JX4P:VW>@ D2 T+@"^V-)=A36("< !<!  Q-$+1; #%#"&547332654.5473oPHqFB02H*;;*F.64"O^OE)!!).4D1*< 0# &B$%"&54675#"=3;4'&#"26|}rUq,F  L]FG*$1@T|SYmlZUz"PuM[1 4S>VV%/#"&54767>=4#"#&546324'326c]' M&)C \B5*aFgBD[HaoiZ/ \X8')*AKJIJ Kcm5(AL[0=%#"&547.#"#.#"53&54>326324&#"326lZMg1 -&BR_XVS C^[-YYk#T?ZkcM7,-":6C[00%'7-C!FO:dGEEtXAY`=QR"#"&54733254&#"#&54632dbQl,F,H74>-9FdFKeKcjaP>=5E7I/@A:-4!&.FTUJ0#"&547332>'4򂂮&#"#&54632RoFF908 :> '.8.5@FiQFg5.>(0cQ@8==9G2IU#<(2C)-6;5PUND1J ]V$0%#"&547#"&54632632$4&#"324&#"326Vg^QpJ,A>QeIG^:2QLP9/.13*/ 9@B?D>?9`ziQf(T>HZUF=.{^=D0*9D]lF?Q^'%#>54&#""&546326324&#"326SF&-:7@(nrv_Q=8SQcC=GCCDE>s])t89P429\wu\_t==nS=RXIFYg%#654&"#&54632;F;@xA;F;mVWkpSNv?[\>tPUnWvv5#"&547332>&7<.+53254&532!*  $L:Us F D<$/   ((A*?*BC2C -9NI%cT@55@'2L-@#654&#"#464.#"#54&#"#&)53&54>32632632-.F.,(  F "(-F"&a DCRTqN:L!%V#>%TATMUKX+D-- :!45)le)<:Q8bIII) I`%%#"&5463254#"#&546324'&#"32\]Zrm\K5uFiSP]F(&-@>A@x_ruZ\y? R_]PX!!`CB[*%#"'&54632327#"&#"6324&#"326k^F:=&%-A@^u01}OIZCn:w[B^V@d##]$%#654&#"#6.#"#&54632632I)S9hj}WOmOOp/%#"&547332654&+532654&/.5473pWOoGB6=D//**%4/"D"/C/DD/[`U^YM0,0(5CT>2K2:&%.  3) $>0[%+.#"&5473325#"&547332654'53273WgSr,F,E9CX4V=;QE($!&,aK<>jp_R@;5E9G) 4;>B9$)("/H@2%#654&#"#6.#"#&54>53632632I)S9hj}pKuG6$".8J*)K7++$Om %#"'&54'332654.54?wXt&% FXW>Q)%W;SR9B.&53R=@%97)+7:Q?#".547332654#"#5<.#"#"&547332>32632Qqm;mL@cEQWK$$< #:%1=&F&#*(!T89#n+[=:/)@CNiSJR4& !+4+;0-$,%$))#@J9.:#"&54733254#52654&#""&54632632%4&#"326xfhA VIz9A//[kjmPf53aDMm76>65C?=;5=5E8H0$5u:N=9%#654&#"#&6&'&#"#.#"53.546326324F4460"< <645U-UP@. VGj]2{[9AfZ(C:dI[=QDF8O"=9 #EG eAdBD (I31C ;,H[{+$Ok$#"&5473326=#"&5473326753a`So,F,H7D>>BJ\3F39/%C=5E8HWG2ZJPHEO0F% $/%#"&5463254&#"#54&#"56326324&#"32dX\mjZQ4$", 1 1?),C='P>9F;@??@A?Z}v][v:"-5-<22:=F)??T@?]^BC]*%#654&#"#4632#6324&#">KFKA9-S |Gi6#E95/Z5%#"&5467332654&+5>54.'&5473Z9.05lE9FAAx~Qk=;?@9(2?=F>?3-< P4jr£XJ[eSOC,y??@;9?B?u=7.2518,#:v[]v{\yAS??)B^]]\%/%'#"&54733265#"&5463237'&#"26wYmQl,F,D9H<3Z=TU@J?=5E9GSKKP=?NP|~TonoY6#&78%#"&537324&#"2mZRl@{7ZunRdw`F`I#"/"'5326549'.#"&546327>54+53232654'7H/@&c+8VHM0*5.$P )11J9M#T 5}$=,] 33<[.:OqB*@F#=.+)#+I$6779LI < 5!':$H>%#"&547332654.53254+53264.5473pVdtFCM6L !'REDST 6LL6AYI:'$*/&(-RKfcNM.4$ <5=<. 1( &/(+ 1$&/ <X=E%#"'&'5767632327654'&'53254'&'532654/54#"6XUC_NC12+V-J3@3 P4E7E6/XmT/;8H)1X+"l[6lSy-W@; 6 :+ 6)7@E5D8#>?*z3^EKDl&'567&5462'4&"6lWPQV1?iXXi=3A6`6ff 56jHZZHj63993Z..x!#"&5467327654#"'7#5!632 (rN_$ 'D5NY$!* 4r/=YL'6)/4A1"W4J#"'&547327654'&527654'&'&'&'&547632'67654#"24ZJ.2*!A1?$!4+^G.5. e!#(I8'*@L-05+sAEFZ8:*,H:+"#1?,(CR7 :#;"4I4:!8H% F(#06,c+ [(3##"&5476;5#"5476323#3'54#"35#"32OUFN^2/S\\0/MHSOOOdr$FNNE$=5dxGUXMO,(HM(&MEn4H|kaf>u@5;#J&*#JFOo#I'6 }#IzGO\o#IL'6E #IGO~o#sN'6g #sG0*#x*#xY#I)}#I^IY\#I>)E#IWIY~#s@)g#sYIU1"|.)"|FIV.#AB)#AZIZeT#Ep(#ETZeT#xp(#xZ.e#A*(#ArJZ\e#L*(E#LtJZ1e#H("HrZC#I+#I,K,g#s,&"sWLS#I-;}#IMS\#I-F\#IoMS#l--|#lM1"|-1"|MS=#H-F=#HpM\0#L.\ #LNA[#xw;#xO#x0:#xPO\#I0:\#IqPO~#s0:~#ssPP\#I1:\#IQ\g#s\[#sP~#s1~#sQP.#A1.#AQK#x(2F#xQRK#I2F#I$RK\#I2F\#IRL#I3F"IpSL\#I3F\#IpSL~#s3F~#srSL.#A3F.#AsS&d#D:$#D&7#ll$p#lt&T#Ep$#EH&T#x p$#x[i#xx56& #xU[i#IJ56& #IU]#I^7EA"IW]\#I7;\A#IW]\g#s`;\P"C"]~#s7~A#sW0m#I8""IQX0Em#I8"E#ILX0mO#I"#I0mP#I$"#IP%0Em#I"E"IQQ#I9@"ItY\Q#I9E#IY~Q#s9gC#sY.Q#A9I#AYUF#l:AF #lEZUE#L:AE #LFZU#A:A #ADZU9#xU,Al#x-U'#l\.A`#lo/#L; "LV[\#I; \ #IH[#E<#E\#xb<#x\#l8<#l\#I4<#I\\#I6<\ #I\#I="IP]#l="lT] #I>&"IR^G#A?"AT_\G#I?\ #IM_~G#s?~ #sO_F~#sqM?"ltY#J\&"JR^#I,C\#I&*E#IF#W&*=#WF|#x*#x|#E*#EJ#W*#WP#L*#Lr\#AO*E"ApPs#x*#xs#E*#EJ#W*#WG#Lz*#Lr\#HO*E"HnPZ\e#I*(E#IoJZe#W*(=#WJZe#L*("LvJZe|#x(#xNe#E8(#EVZe#W(#WZeP#L(#L|Z\e#Ag(E"Athd#W?.]=#W4_\#I.9\#IN&E#I4$E#IjT&#W14$=#WT&|#x $#x&|#E$#EH&#W2$#W&P#L$#Lp&E#A{$E"Al|&#Dd$5#D e&#Ed$5"EKe&#W?d$59#We&#Ld$5"L~e&E#Id$E5w#IjeUE#I:AE #IAZU#W:A=#WZU#DsAo#DtU#EsAo"EmtU#W'sAo)#W tU#LsAo#LtUEX#IsAEo#IAt #E>&"E0^ \#I> #I^ #W>&=#W^ #L>&"LW^0G"Yh0G"r0G"f>0G"sF0G"gK0G"t>0G"hn0G"un"Y"-"f#"s)"g-"t##hq-#u q'"YV'"`'"f,'"s4'"g8'"t,0"Yx1"n "f,"s")"g, "t,J"Yr J"tJ"f=J"sOJ"g|J"t[J"hf J"ux #Ym<"F"f"s"g"t#hq#uq0"Y8""f"s"g"t"h"uCD"YGN""fTE*"sh<"gTH "t^%#hqT- #u$q^$"Yh$"r$"f:$"sB$"gG$"t:"Y2 "20"fJ:"sT)0"gJ0"tJ("YX("b("f-("s5("g:("t-("h\("u\""s@"tJ#uq6$#Y$#$#f$#s$#g$#t$#h$#u"Y<'"<-"fT-"sT"g"t#hq#uz0G#0G"P'#'"=J#J"b""$#$"V(#(">$#$#0G"r0G"r0G"r0G"r0G"r0G"r0G"r0G"r#X#X##Xp#Xf#Xl##Xp#Xf##Xp""""""""#X#X #X#X#X#X#X#X$ #$ #$ #$ #$ #$ #$ #$ ##X0'#X #XX#XR#X #X #X #X 0G"Hn0G"so0G"i 0G"i0G"i0G"Lr0G"iP#Hg#s""#XSXSxGaB lGL dGo#Zl"""J"Lm\h#KY_""V"`"Sz#X(G#Y*Gh"EY GEt#LY "H"sz"h""Lt#L*#H g#C"")Gs#,G"] GCt#L("H^("s^(z"`(k"L98"Y~98#("La(v#Lc #H g#s+"5#w"nd(#ldQz#.l PE $ #$ #$ "$#L$ #""<""<"F"F4#XRP#xyGbJz33u@z'#'7'7#3&,`Z*WSQ+V`)i.8#58HH.81818!518HH8!58HH8A #54673]0-00e;D&N@ 356=#@]]00e{&M@h 7356=#A]^10he{&I @ #&=00]hM&{e0+ #54673#54673]0-00]0-00e;D&Nhe;D&N1. 356=#7356=#1]]00]]00e{&Mhe{&M/,h 7356=#7356=#/]]00]]00he{&Mhe{&M1. #&=3#&=00]00]hM&{ehM&{e&O ###5353XXRUR&O#3##5#53#5353XXRRR3R2, 2#"&4{hIJ34IJ52IIhF,Fss>>}Whsuh 7#5!#5!#5hhhhhhhhhh  $.9C2#"&46"2654&%3#2#"&46"2654&%2#"&46"2654&?WX=>XX=%56J55(BuB?WX=>XX=%55J65B?WX=>XX=%55J65X@=XY|X<5%&55%&5F +X@=XY|X<5J65%&5XX=%55J65B?WX=>XX=%55J65?WX=>XX=%56J55(BuB?WX=>XX=%55J65X@=XY|X<5J65%&5x&FE>EA'F; E <,!74&'5>=4&+532+53265m",,"%.49$.R94.%VE< E ;F'AE>EF&x>EA'M)#$,$M %)#'#5#54>54&#"#4632#5'ST%45%Z%54%F:I8UolatZRhh.J1-9 /7%B00=#3?RJswhhh| %)#'#5#54>54&#"#4632#5'ST%45%Z%54%F:I8UolatZRhh.J1-9 /7%B00=#3?RJswhhh0O ####532 mb@R@9^^LJJ@E4 #""325*LIZ\iog35##5>>>>-:jQ #533##=м.CC>; 5dF#632#".'332654&#"#7.&.BRXE%98I/56.1#4"4wO?CU, G4./7(?$4>32#&#"632#"7"32654&!.)5D8?14&C=OTA*45'(308W1 ;4@SN/L;>Q1()64(+1G #>7#5G$=QR,hm4I*#"&547.54632&"2654"32654NVCDUN#M<=LJH++H+$V44*,4"H:IJ:G"'1@?2&$%%.%&..&%F$#"&'33265#"&54632"32654&F!.)5E9?14)?>NTA'30(*558V1 ;4@SN/K<>Q.5(+23')7*E=8}8Fv*Bw8Q*F*?8G*I*F[|$:EM%32654&/.5462#&#"#"'#327#"&5#5353+#!23264&++4E7C&+N]InbXf3<.3PNFuc:V'14GGSq[]-luOCKKCœ/7-%" C>IWTMT+$# E:LZpDF+(D ]qoDxD]$=F%32654&/.5462#&#"#"/#&?4&+#!2'4&+326L5E7C&+N]InbXf3<.3PNFuc2/q:>]Pks6+LCJE/7-%" C>IWTMT+$# E:LZGNLG4CAC?e^>RH6<<X %>73#32#.#!#V  W jDWCT@W*WL :@Qw E-W)"#73547#7367632.#"!!3#3267Y1S7O?3Fb^ 6I(@Q&$E=M;;_KeCP(_d;;$]/!Z$#5$4>753#.'>73'b;(6N0;lh_8CL=`oy;YP~hd"=H;;*64`sG9DanT> !r{326?6323>3232676;2#"&54?#"#"&54632#"'32767+"?6?#"&54654#"+"54632%"67654#!'\&jaG14tIc9#U( <^$:9L@<.yAP9K0#!$ ?4d+HJ VJ3.)%4$ i'!&j3bP0@73% Տ@6FI?fE3K8 FD60TkY[)& @">YiyW963 kUpD+-Og27#&#"367>32#"&546'&#"327#"&5467673254&#"#"'76232654&54>7>358@ �%-0Me4(,7  , +#$! &@P Q`K%W(2$ %##0R&)$ Y,!+("p)EG,,7 #0#"0(0C/ [nB-A1M+ *)+$!7 9$"1: J>74632"'326?&547>7632>54'4;2#"&>K(DO4Exs"32#4&#"#".  4'!?,<,70; d2,% 6+- .24-6-,# ')#+#N(-.,)5  %<+4+D.@'G AM,4, *4!J2,U;S*!0 ;)"+ F7L$F!&"  ENV4>32#"327>3232676;2#".'+"546;26?#"&"327&"67654%Y:!O`O7\gZ#,-ΰd=dnG1x" M|3'O/'fRIQEWP:V c}11^:H@&U/5sK H16Lrm:)$]U=B/KD2&1:Rz@$ -m%xC.3L##52#"&46"32654%##3u>YY@=YYfN87&(8iXe}HHXY>@XZ|Y98&'87(''OT (##32'3254&+& #"&54$ 32654FEHPŁK#(=<ᢚEG<:G?C# ߞ✞w 2>54'%32676;2#"&54?65##"&54632#"'326?46367&#"3267>=4>32#"&547>3272"#"&#"6dDnnp*"0>+ "K]/ " OQ4""J>U;P/#!# >3;=[<{j@7BF%?&  m1&:8=vJ2 $  m y@'U%E/(+0i(GD2#qHnX'$<" wU f,wZO4 615 K:D()*H)/?NV/ p#"&5332654.'&=4>32>76;23276&/.#"#"&#"'&4>54'3>732>54.#""7654. )!& "* 1.+E u  6 +  n2 !77M 2)'$B0&/ & + a  U (6()*   @;R'+&#68$# /wJF!% 7  =W~@1   10"HL;Uk98( )) 9+8 %.!?$##5!##33#Dw6FyC^[C~77UjKU4 tl"#"&54>32#'.'"654&#"3"&54>3232732>54.#"#4>75.'67332654.9D0  1Z9FQ7S[06%*3&  9 .'++' 6!!  +J.S="1)! :QJg %@j!E-! 2!2D8(.\=Bl 4Q-*A%* .!<&%/ S7 / 4D7'n6  2[G %-%O0"mx74632"'3267>7&#"32>=472#"&547>327632#"&54632#"32>54'#"'#"&>54'632"327&"/"!$( B6;=IRL?yo96K:uA `5,7<" yVgm8'xQL5Any m5#75.546327677'#"&464'3276#"&'&##"&">54&5467&)!!/2  LTs^H) hs!  &L'!,(>AV (] !7"85BQJH  CT!$N% 5  1a3  60!v( /'* -$+-?#+A Y Aqk^1'+.?Q0-Zc74>7&54>2#"&54632#"32654#"632#"'32>54#"#"5>32#"&4#"326-9WGazRe3&Y* !D-#S|+X<%3$?%3R.N=1Y6 a'N _1##>zJ216o+X P ]+J>TP JND3/.@:9^6 =n+/ "2OF< ,#-##"'7327#537>32&#"#!!!~K (H-$JNq} %(0 #, G G^u2[Fs&B.$ TqFh-C"O~FRRZC 3!5!5!5]L'RRj7;>7676332>7>?6332676;2#"&547>7#"=>7#"&5463632#"'B: *Y:s IV<kMH* v-/G-o  Gl'+-?IvF-47B@Ca"Z7!.'>7A82%6/^66^/6%28AA82%6/^66^/6%28DCF @6a00a6@ FCDDCF @6a00a6@ FC!%'>7.'>7.'7DCF @6a00a6@ FCDDCF @6a00a6@ FC]A82%6/^66^/6%28ABA82%6/^66^/6%28Zu3!'7!#7[nuTpoT!!!.'>7QQHM)B\[[\B)M~5PP5b!QaVVaQ!b'7'>7'#'#H!QaVVaQ!b5PP5m)B\[[\B)MHQQ-'7!5!7'!5!'7)MHQQM)B\[[\!b5PP5b!QaVVa,<z.'7373!QaVVaQ!b5PP5)B\[[\B)MQQH!'7'7!.'>7!7'!8L(PXRRXP(LL(PXRRXP(xTToT}_"`^KK^`"__"`^KK^`"VVVC&@+%2#"&54632.#"#>"32654&#@G3!ez_i:QL.> X k]@JP=>RR3R^hc~O83WbSGCW[DBSZT !5!5!5!!5!cdLRR'R+3#4>32#"& 3265u;;I.@;!wqrvvJFYM0ܐ 33 ! &d)'h C &@7!"&546;#!!;~l m c̥FpFwF-+!%746;73#3#;#"''7.%#"37#-It1.#DcWP!)-,,/./]5c]@ cW>66 6MN,Ve6qG-74>;#"!!;#"'&-&5B1*6. l -9%qJ$7W1 6 B/62C 6j27 (I- *&i=!#!#idvvd7i=C -@)= !! !!5 8o%Mug`_Jm(  !5  FF2o uHd2#553533##5XhFFhhCFFk'R&546=6#"4?654./.546323254&54;232>32#".'&(%%*#`$$  0-##*. l$`#*1'C&&D' (>    00+K""J,00   >' u '7$^P.!It{+:>32&#"3267#".'#"&54>32.#"32>d+)H!+.#*"% i)" &6$M,#g7"9|&7H2>32#"&#.#"&54>32>7.#"2654&#"1(' --='<N9 $D!0 3I)9N;3-1$&(2)11-1)3'&$ $#!0*5Y /0!Y5*0 =  ! ^dH! !0Ee3VSZsS BLd " = =d V" =# = =_  6%654&/7#"'732=.546754632&#";P+%U$- 'N8%<>! ^(: BEdH! !0>H W&<  >/&/ zJYpEe3V ,6+7#"&#"'>++. %4 ,'!))736 4 K "#>32326=3#"/&/571u590'*bsNFKE!%:E?232>7#"&#"'>7'++. %4 ,'!))72336 4 N.r FJo.%".#"'632327!5$YLF%()|!YPG(//P0/b:FFK.#%".#"'632327'".#"'632327$YLF%()|!YPG($YLF%()|!YPG(K//P0/b//P/0b.6-%#"'#7&#"'6327.#"'63273327#"'327.5LG6RF%()|!%FF%()|.OG6Q G(#%JGߔ3P ])P2b]+b 7#537#5!73#3!'}9L2;9L3oFfFiFfF- %!55% v8CC3EOO- %!55-5v8CCxEOO.".#"'6323275% $YLF%()|!YPG(v.//P/0bEOO.".#"'6323275-5$YLF%()|!YPG(v.//P/0bEOO7!"&546;#;~sn̥F{F7 NI+ 33##5#53$264&"6  i66A66^M+ !5!$264&"6  ~/6^M+ 77''76  264&"''''╫'&&'%!5!3FFFF\' # 32654 &#"#"''7&54632JVtWq$[\טfa%aYטh*FJuIq#[g[b%bfY 34632&#"dH! !02ZsS BLd ; #"'7325;%<>! ^ Ee3V-;#;U'  !"32654&'632#"'#57537BPPBDUS9ihx|hk;K??SBoooY^p~VZC2@2zN3@T!5TPP|!5|8  Y 8@8D  Z 8@T #5!#5!#5qq}}TPPPPPP| #5!#5!#5qq}}|8  ] 8@8D  ^ 8@T #5##5!#5!#5TTTPPPPPPPP| #5##5!#5!#5TT|8  a 8@8D  b 8@8T!!4P48|!!4D\8T#!!DD\P8|!!D\D\8T e @8| g @8DT f @8D| h @  e 8@  g 8@  f 8@  h 8@  eX  fXD  gXD  hX8 3!!#P4P 4P48 3!!#P4P \\8 #3!!#(4P,4P48 3!!#P\,4P48 #3!!D\4P8 !##34P(|\D\8 33!!(P\D\\8 3!!#\ \\8  uX8  vX8D  xX8D  wX8  yX8D  {X8D  zX8D  |X8T u @8| x @8| w @8| y @8T v @8| { @8| z @8| | @  u 8@  w 8@  x 8@  y 8@  v 8@  z 8@  { 8@  | 8@8 5!3!!#P4PP4P48 %!5!3!!#4P4Pܠ4P48  X8 =!3!!#P4Pܠ\\8   @8   8@8   8@8 3!!##!5!\(P4 4P(\8   @8   8@8  X8 %!5!3!!#44Pܠ\\8  X8   8@8   @8 !#!5!3\\|\\!5!5PPPP|8l   8@8 !!!!#44PPPP|8T !!###|lPPPTP44|8 !!#!#!PPlPl8  @8lT  @8l  @   8@|   8@|   8@  Xl  Xl  X8 3!!!!#P44P PPP|8  3!!#3#P|PPP 4P4|8  3!!!##P|4PPPTPPP8  X8l  X8l  X8  @8T  @8  @   8@   8@   8@8 !#!5!5!5!3!!4P44P4P|PPP|PP8 3!!###!5!33P|PPP|PP 4P44P48  !5!33!!!##!54|PPP|4PPPTP|4PPP4|P, !! 8!!K}825!!285!!8,!!, 8!!8&!!&8!!8 !! 8k !!k 8 !! 8q !!q 8 !!  8w !!w 8 3# 8} 3#}} 8  28 #'+/37;?CGKOSW[_cgkosw{53#53#53#53#5353#53#53#53#5353#53#53#53#5353#53#53#53#5353#53#53#53#5353#53#53#53#5353#53#53#53#5353#53#53#53#5353#53#53#53#5353#53#53#53#532222222222R2222222222R2222222222R2222222222R22222222222222222222d2222222222d2222222222d2222222222d2222222222d2222222222d2222222222d2222222222d2222222222d2222222222d8 #'+/37;?CGKOSW[_cgkosw{ #'+/37;?CGKOSW[_cgkosw{53#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5322222222222222222222 22222222222222222222 22222222222222222222 22222222222222222222 2222222222222222222222222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d222222222222222222228  #'+/37;?CGKOSW[_cgkosw{ #'+/37;?CGKOSW[_cgkosw{ #'+/37;?CGKOSW[_cgkosw{ 53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#5353#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53#53#53#5353#53#53#53#53#53#53&2222222222222R2222222222R2222222222R2222222222R2222222222R2222222222R2222222222R2222222222R2222222222R22222222222222222222R2222222222R2222222222R2222222222R2222222222R2222222222R2222222222R2222222222R2222222222R222222222222222222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222222222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222222222d22222222222222  kk8  k8,!! , 8, ,  8 !!,  8 !!! ,  8   @8  X,  8   8@8   8@R!!DDR!%!!XvDX2DR !%!!!!XvDpX2D&pR !!!5%!5!%5!!5DPD6PPPPPFFpFFR Rj@,d!!,pp !!X # > ttT88!H >.$7654.''#"547&'#"&5475#"&547&'&/.54>75&/&'67.5467.'>7'>54&'_nlf  "V:%!&+Oh'0r2z1=C] " $T3 !58z2r/( !O;*'!'6=B@=2$)r~~o00!"(pgpoa"WY/'m\ * jlA*S78v=?A9p .F%"$|'|  &"AD)p<>@<"D_Q5;R*2`OK<8)' j /ec  ".9!.  fg WVm7"&46323#54'&BZBB-6 T&\%..J.-7mC88m+c~RtT267>7632327&'&/.'&547#"&'>7&'>&54767654'4?&54?&5472>54'#"&'&?632#"'%>7.#"327'&547.'&'6324654.'.#"3263232654."#"'.'&'&'&%32?6'#"'>7>7&547267327"&#&27>32&#"6#"'64&'67>7459'X76z't ! 1F(7;]Z! c#m* "G0Z%;7 1o?>"qr 00,  2  qtUpU//>Cr6  1;e14 9>IM'{x5l0"!13@!!7(_}=%.** "! 3"D G6 "*$     !"Qp-9/,* (j=UG&:)Q   \  '+ b*" !  ) %&  -# 5%:1a'3[?' Aj )V 5z3=Gva2!4A)>_` LX*&^6- # BF. (.In7//R .K!9 $ 7X5j$ X 8w5$&< C 36*$3  %N2S2u ('N>OrC2 c<X1I(S?: U"+& 4B= " % =   QwdCSc{ ".2632#"'#"&'#"&'.547.547&5463>32>"&54>7&"67.'&'&.'&3:>32767#"'32>7&'"%32765<.3254'&'2654'&'72654'&#"#"4&#"632>4&#">36">76.4&#"326)MH(AP_TaZYM 120/B,)KG*?R(5 01[bJGE21*E&'2%#1?0 '-["t=f?67R[F   _;_ H`iy+#I8.#<:P+*]MM5 /,E D/D6) Q $Th',E/ '*a ,S[G* ;3 HR_ M]d|*$G7.#<;Q,!KBD7443 pa)#(('4(DF30RJO>N!AR308)3*\O 4"9+(F.P$:(fXX/".fk.?^/7tDrPe62"&46"2654T<V==V&/"!//!"?]*2#"&7>"54>7>32qu S -~W4gM"*38 b#$%67#547>737#".' YVO~T[1H"  73noJ:[*Z~sj <**  sH"G+:d}k""3>54.".=4>326yjEeV]Y@xNFL62*ݢlq"%#"/#"&54&547&54?632  #45!"&54?'&5432632+"'     )@ #BD M67#"327&'46747#"H32?676327'>54'#"& 5?4! ,R6HBy[: )  + :A 1ly9E627&>O%8@7eOo]O6OA2CEB>\OeEP=M'0>A X+?4)N#:jM3P+" ??Dz T KIZtP67&#"327&'46747+7232767676327'>54&'"5#"&HJ ;*3bAXBd#GF . 98@Dx`A#KF";7/H^*?J>v^@GzQ ?XJ6JRZTn%"_{S_LY*-\A:t j5 ? P']#I{X9[1' ? LQAcS/ SQ 4&'7'6.54767#C3($A; .?,)9-!W^X'<@h<'g-==H!SNVnL/KpI4&'7'.54767&P3$#A'"5?35*9-.Df< ( c']=aYbRIL>'"'>32'>54327#".'3d_S{MJk7SB6vFi9" +&=(&4N,M0+="9="Ax,$&?829%x#AV:""'632'67>54327#"&'vTz?aIC}8M@cCSA+<J$EcK?9>=&?F'L0,(>'&3p*G$A(1#-5%"'#"'7327632327+"&54654.'s!+AO_W VOi{!AN))72t 1N=Qevh]WY1 A=>/&,3AEA ( 2)A+P0b)1'#"'7327632327#"&54654.'lkj+Z[lf AY Y.,!@3 8]Fbv}g-:KM1@=5*1 $:#@KJ 0 .A3(eT7.254&5'46747&'76767632#"&54732>54.#"#"&2C3@FQGU(pyU3y h>A2t |:}YiePE ? 4!(?#%J1V2/2MQ93"))3CW >#h >z&5bAc=@]?)V,nVT~B,0*$- %,0M0C +V<n [.'7254&'5'467547&'73>767632#".54732>54.'&#"#".X-2E$#+]e[TAcE ?@F Lkzq)G9? ?';U'.%!2} 57";038*%: .8jL-h#%'G,8f@"5@f85~^_:-80,@44  9^2H%2wzF.'7'7'4&#"'>7#"'732767632#".'732>B")/-LB7#"'732767632#".'732Y5. ; 'n73'E# 06;8>68.@$Wr!7X/-#"@*o9*%': ,/kKM8'?|??S:Fh~c#RE}I@ TRm["f 7'hE74632&'#"'7327&'#"'7327&'7>767&#"327#"&ڕ6E*&_rZ}JVI-%(>|iH' >$#DWF&PA0^SCvE'JKbFAu0H )- @ J,A9v;>* =33>/3S;�, <14?zZ7.7."&=4>7632&'#"'7327&'#"'7327&'76767&#"327)7(< &o:' <;YEHKCN8'bh}\gL3--AtO*%?!CM+_W/n_JJ*zH7?iGN|9&(&:%(H)J17. @ T0A<}P2>. E96?/3b<)&50%M8?;.'&54>7675 >a/k3  < Fo8sJ>5$2c.n$ <&= P SCAt17.7..'&54>7>75. ; 'n9*%': ,(5k._6'="I 'oJJ!MGv)C"v5b'4%>=#"'73275367%&547AAH50P B8,A)_d8! "&'*)3#@" s*'HWC^+@õ >! &Ut. Yu n1qWVZ7D7.67676=#"'73275&'67%.54787(< &b-@2;b H?0A<+kfD#7N. %A&7d9&(0)R=wr(@ # #! X "=#'73277327#"*r =Xw {J[.dz,$D )7@@A ]#-7.7.".547327327#"'87(< &o:' <=mwU7$<ʠ_bbM~1gP9&(&:%(Q%B+%ZN -=A A >04632&'#"'7327&'767.#"327#".HF4+(2e `*@FDF(;'Z~* 2h.B6,-z'8Y!?#3dsD7.7.4>32&'#"'7327&'767.#"327#".^02; 'n9%=K7ZDRUH(,5v K%-A[JCI-'`Br`8hFRQv9+'':%*'UG/ ^n@Ey vI+?.8gQ45/1S3,:d$@%7k'ib'4654&5332>7#".A):3,FE:+5!%,)3:.WU4D%@@"4P. 7&'46324&5"#"'7327'7675#"'732>7#"&/F,"- a+gMF5 " r* A Z j\FX"I@@ 1!3ea<A=+ WbX7.7.32>7&'46324'#"'7327.'767#"'73:>7#"&9&< &o6+ <`L3%2 l3+CmTM:.{-@S kRF9WTH,* /Qm9%'':)'56.+'E1%K]({@'%K"@"*("W'A #8$ ]_p]U;254'"327#".'&547'76763&532&"'#"'7g  =/NR(cU/ AA6jf20&nNg#6S|z1A28-Jt1AEAF|EdA4'ZM-< ?TrR7.7.2654'#"!263#".'&547'76763&54652&##"'7L7(< &o:' <8 W`/gX2dA@XWp8.:-ra#9&(&:%(+B'@!?5@5;0I|< @MKv2G@F#R\1<*R)wa)%.547>7'%"&+"'73276323icL/ - U DN.bO%)'.G,R 1?@?A+2W04O.1|H7.7."#'#"&+"'73276!2.54>7#"&5. ; 'n A ?A#-:$*>E"@(-:"*H1* (Lfr 7%#".'7327.#"'632%&'76767'>]J&>) ? !7/G>\'!a Z1-bB 1_f/ A 2rwI#qx#+ .E7.7.#".'7327.#"'632%&'736767'>9&< &o6+ <ۿOAS1 ? $=4MCa(.d p&.nG gGX! A OfKEJP8n^?9%'':)'r7?6 .+) I A J@]uhc>&̉#~6e6%4&#"'>7&'76767#632#".'7326$jAm++P> {KAb)XOX*ThD{P/Ql<&7MIDPt1g:}('5DP@1eq%0?  |81JU&5R+=P`F7.4&#"'>7&'7676?&'#632#".'73269&< &!rGt,#9/ L FAj6+ <Bm:81oJU11QY0( ;TOKV4sb9%'A,*6=_u>@5om7,")'"PW?4P[)*H/=ZeRc!"#"'732632'>7>54&bXcB i1g&@+,pHB=Ib&7Li!/A/W-N5 AU,7|%"#"'732>32'>7>54.se;987]b2OC!+=#3ONJPs,@[1d5AZ~>)L2/ Ad4&`Njg67.7."#"'732>32'>7>54.37(< &o:' <n?<>=P~@V.}#/@(6YRMZ}0Fc7m}9&(&:%(9Ah,Q72 A!n9+iTUZ4675$%.@zX; c!*OSA[v`+w`(A@'IQN8+@-$?*B_a6+7.7.4>7#5$%.9&< &o6+ <L8WJ!ΜN k$%YjZaxk19%'':)'G|R0@@*PXU=:P7#?)EiP4>7&=767327#"E0!AE K==|<.T82 }n.?/]\D17&=367327#".02; 'n9%=&5J5$AP hf!=A k}?9+'':%*U2Z<5 u1@"6B)295B&A0Y:U4N%32>7.#"47&'72#"&'#"&54>32."'7367>7'>SO,% !P/+|Y*DtG !?o o%Pk!?(8!B6/  2 AA'/ A8?wA5 )/! | A -H C(E1- ZGBgn soJ,A-X*-, @ !+,@ @yafX V%327&#">7327&'47&'76?632&'#"&54>32654&#"'#".N?-@%W2,< U0%ALO"qA@ Uk$? #Hm?& %F)9<_>n#3)F]yk+*281$Sh$8389# fGU?e7mb\Snd6x o**?.&;RK*hX82+SK7!1 >AVhB*)&7B1MY R%26767&#""#5'>7465#"H32?>767632&'#".54632654&A*:Gb-y=lA.d6SBBZZ@A)R ruW^t":$D g2 *1#G7?nN+'!6ls 6~$%v4> A : HL~^Q&6,/B 9&6N>CL]Um%24&+#"'&54>32'>3276b .7N-H%(7HXp,P:Ik{l^b 9G32767&#"".5463&5465#"'73276767&'&54>7NR`yG'7>_/ZG>?XQXME9AU H: f#M BG A E! @%6/2<5|_ +  @}<8u? Bty A70 &/;xObgSw9_OKU7.3267&#"67.'4632&547#"'7327677>3&'#".&54;5. ; 'UZO:N+<v: # GbJ\t8ID|qJ>E@E@`Z5 $O6Y3# b1A2N&&3)))L)'F 5?;buA" @ C@ L!zT71m'0%֪we,r0;/%".54>7'6732>54&57&'.YW6=eK(a3<=9,j54'77.'&'#".54#'27 B7(< &KmG+@ :' < Cg9\35f^0]\90|%)..-)#*FK29&(.5a}T* '%( !u?/]@7A= &)45>=CAE -A!U SC"2642>54'754632#"'&'#".54#'27 {&&KmG+@,&)*%,h9\35f^0]\90|%)..-)#*FK&&d5a}T* t"()8*u!u?/]@7A= &)45>=CAE -A!@Zs%,%.'7>7%4&'7#"&'73267.vI:I*M@LUH88?R^l{0c#4)&aX%MS ,0]{$STpG@1DLv-Fc pN1M9,C0F .?56+Al+mK78F;!>F7.7..'7>7%4&'7#".'732>7.9&< &o6+ <GJM+=2C7O]M>9ETi$q0EC$, @,'bN%TY*0c$Jd+9%'':)'NqYB162ZX0Lm!wR8Q>,H#O9LE3@+ 566<...+tS70R2;#@H"264'2#"&46.'7>7%4&'7#".'732>7.&&-))))GJM+=2C7O]M>9ETi$q0EC$, @,'bN%TY*0c$Jd+&&2))):(qYB162ZX0Lm!wR8Q>,H#O9LE3@+ 566<...+tS70R2L'7>32&'.#"{/b $$-"?>,E'a?;*UK%2%%,l :3X-_621dH&( +>37.7.'>7632.'.#"5. ; 'n7632.'.#"&&K:)))07_15$FE2G*iD@*BCm,4L3' K-$&&3))),7!D,J3sI*9B\LPg'&PL%$$-UptBV V5r: @"l4&*:>_/V A "&)62=-0 A A@?# >$ M"P7B- %6/b;xObgSw9_OWa7.326765&#"46324&=#"'732?347#"'732767.'767&'#".&54E5. ; '#J12D }Q+ABeMVr8AF400Vy EH 0J./ $= K :".6Y3" c1A29*%& &'< 5@3(@FA#@ G :!,?% n]7Nz(0$֪we,_O[e"264&326765&#"46324&=#"'732?347#"'732767&546;27&'#".&54\&#J12D }Q+ABeMVr8AF400Vy EH 0J8&)' K :".6Y3" c1A2&&' &'< 5@3(@FA#@ G+)+?% n]7Nz(0$֪we,X;# Z732>5&#"7"&5465;263&547'67>7632&#"67&'#"&54632.'aE+.TS=Nbj@ P:KkAJ%r9T+] E\"X*/=#`pZQV)G- >P1 3FE@JEA@O/ @' &p8`('9m7.9"m=G C3>"&54>767#"'732767&''>7&'t9C2!5#%1 '=mF'BSf!!!]v3J&eA `992OB; *N=/ h -3N#;#*$-,$-=5*_A$5] 25s4 $=5QB*!811I/88C:'N6V.'7.6'267#"'73274'76732>54'7#".547#".54>m*7"=4&O! (%$dA3&A:xF$2 @Lŧ?\.),%?-"7$9Kz"%<%#%KAUl^^ &>* \,s]"4*C UAR/26)<0.F#aXF>7327&'".5467&'76?32'>7>54.#"'J< T0%ALL&pT,@ WD @Yi$? KwI0P;/S%/`v$ 1RU0 5'81$QTLT@g8l\eS6Q@T.$ b3,q$9NK(U! A%c4=W-cB*)@N<%"&547&'7>7.'7676727+32>54'7LwCko1-b SGA5c v4!E A{[,G) ]3%!$ %7_@  *<''):*Z^Y\@@ d+4);v(./V)7G9(eDL1.#"&'&''7'7>7&'7632#"'7326 ^H ;VC3m=i !W;V<-7-F40MSq4?uk3GnT 3,&&u-GS7X!2/?(iL5^1,=(\)Y}e4.#"&'&''7'767&'7632#".'7326</N.((;PjCw<{$!g;eP^J,R"=86xY[="Q*0z>S7+/ #*/#!;;9Sc8h,+E0L.2`9;i:=/kx H%232654&'7#"''67.'7654''&54>7>7&'7] ZmTMޓy7!h-$+;0?+H91%  A?2BGYS3Ak|mVQtH$eq:L7?(@</)2 T26!)08=EI(^,>XęGoG4 8:`sI%2674.'%#"''67.'7654''&54>7>7.'7~m'M2JC#&S17!19J!: !L;cJ>+% B@9@ߤ@ y~h.F8+F7v恨?!7P-eI'"d&T $3@JSX[-MACbݜ%Di1$ -%26=&#"'4632&547327#"'&'#"&Y-EID,FRfQ@C A--K_ a[*,R)CgFV|s.; "Je5A_Zx^?o*3j'GSoWG3 1%2654&5&#"'4632.547327#"'&'#"&B8QYO8QbuXIUA =0[jy_54d(JuRc;E''(Z|32#"'7327>54..'7U%VLP?;9>A **0.55:7L=+M;UgM1}D->.C:RI-OxDB(33/$ܭw  ,P3A);A/ m0';  (&A  .+44.#"'&5467>7632'>7>7.,%&"C (>##>T*!032#".54>32.#"32674654.|E'=IBE7:n~ M17Y4# oF.H) "2(':>  !G:X%KC]6 @;!)$3>1I}B(1% "3 '54 E),={?-6$MY@>'%"#'465#"H32?>76323267#"&54654&  wA6BZZ@A)RۍJ^* @1 "7*> &f> A :3gU4&7CL .92":D--@7"wf(4&#"'#"'7327632'>7>5oOPˑ(=IBE7:n~ ǂh=c9''f=?=;[!/<_.bYT4 @;=#3>0o`-?'!WEU@"&5'465#"H32?67>32'>54.A7?7>BG9A )E@4[p ',034A>8* 8bL=M%5 1 A yJ#;s1=]3*$ = "%546#MYB"#'>7465#"H32?>7>32'>54.A%m6SBBZZ@A)RAWg~$,37;;A?:2%#;g($%v4> A :%3[i!:/*  > %)616*8Pi N%3267&#"3>"&54>?'67632#"&54>32654.#"(/" .V7T .LbX+]--dCJh);1#N.(66lIB@7X0 4=#I -2K)%J(\H3ODI" A 28wWJQ/!2 EH!@A( ih#k %a%.'7"67&'232654&#"6&547'67#"'7327632#"'632327#".#"'6w10$*%-:0; 4@ l-#V0#/6 "A.b/#6 A.''lQ'%M'B6&5 A ?wK.,l U #+#[1$#+#J8p+wE"'67&'7673267#"'>3267'54'$&54>7& 6.+3d n:!@! BC c*)-7&F&\Q AFc-9[ok.+?J>7#"&=4&'"'>7636! GG 1 $%/-4F5 SD}03lPG;Md33+&gM$E"* %%#yu-$A<<~3(:W7.7.L9&< &o6+ <{9%'':)' S,#%67>=767 '2$3'(#4Aw>TT]v]*N99 @15_5-HW<- *CAA/A!InGJ**?H&7>54&5767#52%',&! AOx26gH B73r#!#&+5?M/ (  $ 2YAA3.7/HlY>E.(M >7#fds\F5s?ASC05Zna'=}K>RvbG>7#vPXh@VP65MA,tOGy%+>6XfL&I?"C&!*53!'>7!#A4 +8PbAN]V-( A`;fUI>6/,)=&86_lUz#U53!'>7!#Ad'ZXCYX65 A\yEBH>",)=A`kJ(N #5!#!!5!P>1_AAAAS !5!!!!5!ZgAA@AAO41%2654.''>7"'267&'7263"##"'70 7hOR"'#PK\/10:: A(''&T= @8#( -TbKD3CHUABrAU~/)>N?Mif.%2654.''>7"5%'7263"#"'7#< '?MS(*\Vm:tA./..  ]F%H>*0%8f+L[\u@3LShAAc8/EW?w5#"'732>7"&#'>74654&572"/$=3#* (( "0I)//3/L&$DEA3'Jn>J&=HqS+OW-0.43aMp?A@T 3 D>>mZF7.7. #"'732767&#'>7"'53654&572t7(< &o:' <) !,"?96X%,PC;.82T('JA7F9&(&:%(M+xJb=I+.=XJ0K^lJ=.97kS|D@=RDJDDo4'7'77%'%v\:_S:uK;k9V$>7>7'>7k9:?$&? 88,P/Ki1VJC<7444/G77,2DKfM<@LxXFQ;'%(.8EWlC4PI/*M57.7.67>7%'>7>7[9&< &o6+ <( ;3E%,? p,(6_4)aLRbr0Ac53M<;N9%'':)'.+JMtUH@bv6*IE$%<+8^2C9WO3-iJz>7!#'>7>7!iZR#@&$#G?9&26C (yg}hg {DAW~gCJ2*5$+E"6oHK*/7.7.>7!!'>7>7!T5. ; 'n7##KAA&LQI,GGF! ASAA!Am~YA0@Lsg}47.7.#5353!673#'>7!#39&< &o6+ <CA@.$F/.,*/?#(AX9%'':)'AH{aAHxZW9L-*1&-C6NSmBQ."7676767 7.7.'7EpXCZ9":=.@+L1`?>ZWI)3\2<@&I9>@$;sX >bU?;'+&|A ">2-+nRA/55@`m2i!)17.7.676767.'77.'79&< &o6+ <VCx[Pl9*+NN,7idYIMUa^O 5AG'Q@=09%'':)'F!767'6$7DO.|VL#KTv+cPAP&|Q1M{p`I\c1c;262:_-hA@cAHF/1?,7.7..''>767"#56$77(< &o:' <wXy$UV.gQQW[W&-6U(R9&(&:%(Fhp78;g1kAAMY~1ibJ_P','767%'>7327#"'.5A44,20+(- !3VF>A*?/KBv4TzA<,47b?p . EGI  A L ?1p97.7.'767%'>7327#"'.565. ; 'n4UM4d,8;jH{>OTR## AQ"E2&%> 7.'7-23L%8+%? 2B8e\S'+6A-)&2{#$9#:.GGakEuU`F9`L=/*/W=n$$-7.7.>7.'7O02; 'n9%=AH[0@&1)?*2)A5^PD&23J,=P9+'':%*-3K5URx\^}VX;N;/lHH/7lF(s=,67'>7%'>7.'n44P2;MhI+QJ:$?,/LWFt_X!523..)';\4 ),"`Jy>2EYa @pS\=47! "#'(/). V97.7.67'>76%'>7.'O5. ; 'n#*>",3Q^J~g`"JVuY$@vK9*%': ,'?eXtJ21/IQs[U<?zYdB:7-7UZ4.8qVf>7!!'>7!5!54'TەM \ l&Y W[FA7!!'>7!5!4654'B7(< &o:' <_5{[ { t'c ub9&(&:%(/E677&%7&YDMT/8,?$=?]aU-=& A /U%;(g(3IDpc|w[D1xY}s-V][lDY4%>77&%7&CO[`8A3!?42=;[WF;=. A 0_,:/|.77&.'7^8, ; 'n9%=Xci:F6%>&;J?og[D< A $%0e18($':%*4B]S}YaD7QKn&)),(,gvZ3xD%>54'!5!!5!$h@Hq|^vm(AA*vAA9 $7.7.>54'!5!!5!`9&< &o6+ <sDo_tJ|N9%'':)'2o0AA+ AAyd#37.AAQzA=.eh/5=59.cDrD47.7.#37.z7(< &o:' <AA}v.ko9&(&:%( ^.Nt/kFv7jj"#527654'7263"#'>76rsA:9::%7?0-0>A=T1fJ8A7aT7GD,28]+Ec75!5!c(E2AAAAl6-67!5!&''>7".'7-?S%i@"O+/1}F1_|KU!Js`UAAVP05+8;[W/38P]0>02`7&'>7!5!.'#uF?;2Mtըh+mf*BnJKA9&4F*a\Nk;ZAAp"/TV28P(" P'>7>h?6%A3_*7#=A_B 1P bd7"E.C$7(,HD%0cN~7&>735\:is;-9@7DN&>5]hV uZS.p#7.7..'7%>7'5. ; 'n7v&&K:)))CLgt6kQG2@"?-7&&2)8*)&Tbu PqKV3;?327#".=3>7ײ'=9wickGAmH8J<@!FR< 6Cnx-7.7.327#".=3>79&< &o6+ <˯%IFzpblO @?9%'':)'M<t1XK@"CT: ]2OnW-"264&2"&4327#".=3>7N&&K:)):(˯%IFzpblO @?&&3))(:M<t1XK@"CT: ]2Oj85!'>7>75:'Ig;@PSn .7AAWk1%><:'+O):yaL%7.7.5!'>7>7;5. ; 'n7>7f&0:())A6?*)Y[?GcG2=&&):((:AA_t54`.+;$:<"@j"'>32.sN7<4|_0CfD;X(!dxmRNHQ'Z=+n.D4P_R7L<*7.7."'>32.02; 'n9%= +#D (4]g8"LlRIU'uPdf9+'':%*b!$U*6&}u#A5p8B3[=e?1L@+"264'2#"&46"'>32.&&-)))) +#D (4]g8"LlRIU'uPdf(&&2(:)):(!$U*6&}u#A5p8B3[=e?1I^b !.'>7!5!53!!#SH-L]2%1?3-6;,A1A0IlE/I{L.-$FMDITL.1AA(l'37.7..'>7!5!53!!#02; 'n9%=109H,Rf!C90>!838ZHALAl9+'':%*?\KD.MS1<@h]K]R44AA(ly(4"264'2#"&46.'>7!5!53!!#&&-))))W09H,Rf!C90>!838ZHALAx&&2(:)):(r?\KD.MS1<@h]K]R44AAI$%.'7>7!5!_rhw&dEICR'(17sQ5L|]V5G<6767&'7''7A9@ ? 'V>0E0m5U3,im-vuc 7:L,'sG)A^&'767&''>@@A#Dn-b:r`Q) ?:6-((A5!5!4'#5!!!!327#"&=k` %O?5zz( '7'7%'>7X`;d|14-0/;L;0?-i5Cg95-:iDY_dRU'7'7%'>7Bq;v2 &Q;/GYz:C9?6{5 LJh;-E~Tl@z %!5!3!5ahKAtAAts !5!3!5w`A7AA_ 5!5!!5!5!5CqAAA{; 5!5!!5!!5J- A@A A1uV5! '>7%5!(13'6%?(O12@DZ5C5<".AA8ZM;6$'#=-)>MeDAA$%6767654'73#d{/f& A &!;,N4.iAA`2Fo]_NfX>8$'^9Qu# '3>7>54'7uWAAdoI864, A3=9laA,Z)@DD/7'3+BBt4kAA-f0:8T6,3|3 !#!#5 AuAIpAB4>3(#!'>7Aq&$D6j+?Yo]/# GJ26",= /=9^dPHR#!'>7A ' )-34:9<Nka<4 (9~oq+)! =*4,@>_aG]W#3#5!533#!!#!53JHA3A@AAAAoz%3!!55!'67A{mh =AAAAvH8F@GJ67!5!'>7!5G3?) PoCE32X0C**4rAAZi2'C>! ;. 42B%Ag7>7.'7qKT=,<#8B9ROxxXFHRgNF .6n}hSuhB9 F*>!3F_)7.7.53!'>7!#L9&< &o6+ <A!)Z]awl:3 {A{9%'':)'f`IKN=!1FIyk=] 6#"'732>7"&#'>7H654&572 A55+ !!#E@-"=9';;"A;< / @!>5L>7!#'>767#n<? G(2'>M,#ht g9ACRm($G %5-E*L32JPMHNNdF/$ H' ,`MPPD,"%68,+0& eHH]V'$w*g6t3/J. =m=;2R2" Lbm5'"#'.>37#%7'7mmk.I2 S:+ &+I?1c>e= BA];3Z:*6$Lm $###5375'"#'.>37#%7'7MGMNmk.I2 # :+' (4I?1c>Haf< CH*;>i< 7#+" #+.%&& 3#"'53265FS & mG't 3+52=#td4.77IWTMT+$# E:LZ:X33#:WWGGX#BG2-"./#32676?#% GQ@2A G  JO. R:YX 333#WWWW2X#:#BG%X%>53+533"4fW,?L9䥋ZNT<v3R0 L :@X##=47'3>7538}rAZWzFVW{p"zGx)qA&X#!5!W  LL?4X #.'!53:{lWAZ WXamtQ: Lw9X.'!5!#!5!>7Pkb7 "F\:<4 sS7LG(5&+7!,/L"3-%%#467>76=!53!W$9aW:IZ1VVT_1'R #;Hᕙ2O*87?5X 2!.'&'!Ak>* *!9GX%4A2X+"? @%X #.'!5{mWAZ>XamtQ: L#uX.'!+532>=#5!#AZ 1A:"=3<{mWtR8.J, L:.)Lam2!5353F FF<$(6753+;2673#.=33#bW57J` x>RCW|R}WGG,YB128\iQR[ZRG<$(6753+;2673#.=33#bW57J` x>RCW|R}WMGG,YB128\iQR[ZRG<$(,6753+;2673#.=33#3#bW57J` x>RCW|R}W'GGGG,YB128\iQR[ZR9GG<$(,6753+;2673#.=33#3#bW57J` x>RCW|R}W'GGGG,YB128\iQR[ZR9GG:}FX"&##=467'367>=33#>Q;f(WP=3#5#53>Q;f(WP=33#>Q;f(WP75.#"5632#".'33#<1    1*&.PMH/H81 W -GGL  (# R./'5%(+-V:z G X3'3#WWtGGX#wG&8X #.'#53#{lWAZGGXam7'3#Pk7 "F:<4 GGsS7LG(5&+7!,/L"3-pG%!3#%#54>7>=!53!GG?'.2W%,4 [WGk5V+, *b0?Rn(*@5 0:X4&+##532!533#uWA:X:N{ӻGGwAT L`L G3FX2!534.'3#G/H81  -GGX-V:L( G=9X&*!".'!2.'#>7'3#;5H:--PM_BY%# 1  GG -U6z/.'5%(+tP:-9  qG98 X".'#3'&'.=32#3#AZy !!"(P .|!W|GGtQ:  L 3!./'5%bG?X*.2+532>=4.+3'&'&=3#Aj=*;%aF7533# Y;&Fd" WxGGM]L 1(G>8&X#53>7!5!#3#&l|>7$5#ooWGGlbL)LrUG%X #.'#53#{mWAZȿGGXamtQ: LG<X$(6753+;2673#.=33#bW57J` x>RCW|R}W'GG,YB128\iQR[ZR9G#{X!.'#+532>=#5!#3#$AZi 1A:"=3<{mWGGtR8.J, L:.)LamUG>333#>WOGGXG:6.'#533!5!3#Pk!%Q= J[sS7L$(5&LLG9.'#53+53>73#Pk7 "F:<4 sS7LG(5&+7!,/L"3-G?*.2+532>=4.+3'&'&=73#Aj=*;%aF=3>Q;fhW  WD'D #"35467>54&#"34632#3 !!8 #H=5"/$,888hg')# 17A-4'A{hg&/1732?#"&546767Y6! CL_iO!!N\LD :hT'3!eb.4&#&&'&547327273633267#".546&<%B7 ,2 fCO_?/ C/G#^"5 !& $ #Lc/QBx  :8QFY5QM'%  5&&_."&'2'2654&+"#5.+'7>753VG E`\)/$  2'[A!),K?E)#RDP(#;GN70$'(33S{7253#5.#"37#".54>1G33 c$7B  &"1(H$C%c.5L0 5$,@ '(f#2#".'732654&#"&546{ #-Uc7654#"'632C$I1x"t65! )'% aE 165+3#>#k3 I] <r6#53533##5./>54#"32727#"&54>32=>?&&3>>3?[C"/>'" /-% !/ -;P3DD3,HB , :!(,*!.#'3##5./753632&54754G4.'A 491,$r^.3$+1vZKW >>E_/ f$*GD(#<%253#5&#".546V.H$33=_%&+><21_P *1(#CAB%m%'673#5.# 3JIg43Q+0 54'#"&54336?6B5oXO34P- (0" 0!'!C   LE;H_b@L3 4"668& # 90.#"#"&54732?63253#C  YM.9S  2833(W6-( -32*ia''63253#54&#".#"##"&54632 33**!".9E%0 (  $*(-7,*@.)4>5654&##5."#'>75#5!#2#"'7'25"` 5$3 (/RL'; 5'$1@ J B)#&5('33.'*';-q sl)33##5./>4'#"&5473267>;C3<<3 w/4D 5#'+!-$4CU>3+]2-.6-  &- 6 .-253#5&#">32'7>54&#"#"&546(G.33Iq%E!-8)A&2 J&U-.'$8,$&%8K!9 1!'2[>.)275#'47#5!##5./7+"& 0  M 9P3[6 64(    33./@:&p.,547#5!2#"'3267#".573254'#"&72654#y6:1, +":#_5_>%34b6U)2*4'(+"ZMT3,#2940_yHjv1 :jI,=8%E.72654.'"&'#5!#6he0CGW5&)b+ @33! 58h.73265&'.5#5!#3}1rrF #c2!?$~<]'m33 9OP`.-;.+53>54/#"&=#5!!;272'".'32654'CB ,$Q3:JC$6>) 5    m0;   3+R3<%+733- B ./467#5!#3"'327#".'732654'#"&l'f 3 $7=G:'>) 3PE($"("3J 33G* _57T<-0+!,m!675#5!33##5.'#5.#7Ps(3>>3 3l4] ] D 3 /T?3u?"Sc, >%:=Q2#"&'#4.#&547;636;254&#"27#"546327>"3254+532654,!I"?3 4?54'#53&5472654'lF~c :'7G}v4'* 9*13.Q32*9*2=*S-8' 3?6+2 M7<=2Q#Q.$"&=#5!#267#"332654'$8!$^C*3 !:"-?6:!33}6K&4d82R<-G'!3.7"&5#5!#>54#"'632r2ER 6;  & n5#33 s' (0 C %;2.#"37#".54>#> f$8C .- ;;-*Qk.5M/>.,6& mm-33##5./654&#"32727#"&54632:+33::3 #%D+ !=-,;*8R?34"7F 5!$05 W3)"753##5./7.54632&&u  Vm:32L8B*"  d,!6  053=252-"( ?  z.'5#5!#6?#&54C+G1*k`CV? 3 *339 (&+/).1.&#"&546325!5!#<6!(E5<^3 v)2+M3K.K9#>3253##5&''654&#"72767&#"KK;\PƓ2 (+8"?!J_T3:  ( 5 & /.,#"'73254&##5./67&'#5!!52732')3l*<&I8/. ,2%=0g21%11@ /!%033(* #<7.675#5!##5.+"75WmI/3 q(0!Q $KxD!33?c : ".)-4632&#"2>7#".'32654'#"&'5!u ' 0&%4O:-K0* 3h=(1%<)4 1"'(>?P#3SC1 jv:-@:33. /4'#32'4'#5!##".#";27"#"&5467\# '*: ea,)#G7 $*4,#)T!-3309)5))30#L. !##5./767&/.+35b-3h)!,))=.-".36/;)(*) 5QM'%  5&&.%25!5!##5&#".#"&54>326 O3&)+#$$$3 4"*-%Z33>?$7( "E$)/).0263253##5.'27#".'#"'72654&#''/ #!7j3# % 8- #/IK[334 0 +#,1!&30".!327'654.'"47#5!##".x/b1a4rk7 $%Y( MK$33-;X ,J.",#".'#"&'6?32654'4'#5!!3254'"':(4 "<6  $78$=",6(3  @*33$H8$[\.(,&/3;2654&#"&54632%5!) 5O#z  ?55%"H!'.W(&54#"'6324632#"&n -@Y%7+a_ 7 !33 == '$*@EM. $74632#"&&+5!##5&/675O /CA \532{ +/0:>(( B336Q )-m(2(5QM'%  5&&7. 7.'7'675#5!##5.+"75D++DWmI/3 q(/!R $L9 0 6"D!33?c ; "-'233##5./;2654'#"&4732>54'r=Y3ll33P]+ AS?? 9/( 0GC=W3&-!?5JJ3Z0H..)5!4&+##5&/7'7632#"'7326Bpk(y&)djF4Lf< 33#/nAW6P!4#>#=>G83, ;X.7.#'675#5!##5 /AT&yg4,~X:<*6g&+33: N6NFo.4&#"3"&54632#53## R!  *5'72BC3[? (&/733tY.'463&'7#53##54&#""&5& 3>wC3]+ ' )(3 .>3 333oZ((.47#5!#'>54&N2;ACZ+3xK833G@EE0 )! .AE2'65.#"#4&#".547;2727324#";27"&54>326%5!M*9!#)/3=TFRD )7="7-%y#+SaU7uG' &(09+'{9F0/#)( \23,/"2)/# L3 D06`*.33.(L1#B%''7LJ Q4E.#"#"&54732?6325./>54'"&547326733##wC7LZ/EF  4686q4)$1( ,(] (R8,33 $-a0 +.8@.'#".54732?6325+&'#5!!2#2654.'o  &'# "+.*"$ G!*Z#"L6: (3(Lg  ;(.' P1 -833=.(+? 8 7<.U`.#"#".54732?6325&+532654./#"&=#5!!;2672&'#2654'#"'}C0E#._;Ac'L.##"&547326325#"&5#5!654'"&5473723!32654#"'62#m#<'2D.*"?I,'Z3G!*`4B0:d$D-3h'P9.' ('3 K@&O33 ?/). D836E$"1'-4TAM.##"&547326325#"&54>7>54'!53&5473##2654'r g 2C.)# 3=EV2 Q6& 00Ư2A 3r7F<"G/ P90% L3:ZD N= 3\H8J",O63Pt\!"x@TV>NAqY.E.#"#"&54732?6325#"&'332654'#"&=#5!!32?67#D LZ.9S56*3m3b[;RR%(F4 K3r'M@'. *32+[3'&?.33-2lF&.@.##".547326325#"&5#5!!>75654#"'632#p#&% "+.)# ?D 3 Q,.3' :&.' (&3M/733q >14;&"!<5>.3!!4632#4&#""#"&547372&#"327"&5͘6 3.* !>L, V'&w  >%.39!-]B4]I/A*3$"m&$ -VU.IM.#"#".54732?6325#"./332654&#"&54>32#5!B 6/D#.DG 83%. 9*& 3XYBLF57 + 8&Kc33Mvu',.), '<)*l$*-+)! V\IFa!#'" '}>33N.#"#"&54732?6325'./>54&#"32727+"&546233##xCLZ.EG (46A1]A,$%#  7) ? (V~Q]$iJ4QQ4<(M@*+ .;)+BF11 8 "*$3- 2DJ=7Q(ZX3.23".547;26;2&547'#5!!67&'#"# '0!1-$ i#* d.e,-.(5 P@*/:!3:gV2"33!S|^P 59D.#"3"&54732?6325./7&54632&#"753##yE0YM.EF 46FkMq_<+( $yR3yU-$&2)W6), .<)+EFL)[E/(8 DJ3325!5!##{B )YM.DG65"5- "!4>)b3|P3m'W6), *<)*/:'' , '&D2;(f33c.G732?6325.#"&54>323>54'!5!##5'.##".5472*" K9; ))&)H2 $k>j3   %+ "*.'3 -" !2% ,,>33-&54  ;'0%   s8F.#"#"&54732?6324/&'654&#"'>32533##2767&#&#"C LZ.EG 46 $%.# n6F3VV3 # 3#2$ ?2(M@!4 -<)+)."&!$ $1PE3 ,+2&(!.E.#"#"&54732?6325./67&'#5!!6;2#"'73254&##xC!LZ.EG (199b($fp3@&69tM Zr," K94F'M@$1 *;)*IA] %M#6@33)9&1,&bNbO2 1 #3=.,5726325.+'675!5!##5.##".547  8"z@4#:/ #*.) H''2" H,6`-+335 ;'+* (&3{$`!!.26"32?#.#"##".5473725#"&54632&%5! 9/:81- -!  9;$1C17aD0;3%: 388]#"J5214B "U>0!+$+_33hA.IM.##"&54732?6325#".'32654'#"&54632&#"3267#5!A 6LZ-EG 38 %9bC:"9%T,P"5R3O)4! K%3!%33MXc'M@*+ .;)+w1Jm_:Q?3Z7?#00):2G #!9 D833=.4;.#"#"&5473263254&#"#"&547.'5#5!##5|C YM.EF :56`#/*U)D AML93?59.(W6+* *;) +5+P,],%""33B73N.-7.#"3"&54732?6325./67&/&+5!##zE0LZ.EG  46)9-9Y- n>4Ia/vB$2)M@!4 .<)+;CR 89C!33b:N/!F%jN.#"3"&547326324&#"327#"'#"'7;>54&#"56;263533##E0YM.EF 2 56P%!, <" 4#I5N$3QQ32)W6), .<) +Ms/6 +:')-1=8k_&W3.,07.##".54732?6325./67&'#5!##5&'o#g #*.)"0HBdE*g-~IF3LI;0{V2 ;'+* (&3 /]G:%R#A33b{(?+7q\.9B.#"#"&54732?632.#"#"'73267.'5#5!##6325C LZ.EF29 :(20A,  - B_853@5"'2n'M@*+ ';)* N4?4j#EK7"33a84E.AK726325.'#"&'6?32654'4'#5!##5'.##".5473254'"'} !2 "<8  $7W33 %, "*.*8$='3  @*33"<4  ;'0% &'3w$H8$P.>B.#"3"&54732?6325&/32>54&#"&54632'#5!zD0YM.EG (64_:&9 VB0d/7kY&4y{'W6'. .<)*Uy79!(# )7#$*9,JZ9o2Zq!!33..2:.#"#".54732?6325.+'675!5!##'~C /D#-DG 19:!~oA39V$ %&,-&- /;(*%-6b++33@>e X,q.-5>.##"&547326325.+"'675!5!##'.'7l$%(#2D.)#:!~A3X_:,n6X&'(Z% O:1$ (&3o-6b++33v&Q . I7Q'Y*.Yin.#"#"&54732?6325.#.'4754&#"".'54674'#5!##"'73254&+##25'.5#7#3F6LZ-EG  38Q*  RH6$'j'3 4"  ,4 38a? +">S3 2(M@%0 .<)+h5F 1 ,<&33Y 1&/ &,*4\D8U)0)U.J%'675765254&+"675!5!##"'"'#7254&'#5'&/&/7&',EX.4"kP*-D U(XlGq'%+!O3(')"M.(,"m ?  GZX5-33. Q>" 5$,3#3Y#   )0" [67723##"'7>54';2654#"'632#"&547./675#5!5467&#"#"54732?6c' 'Fy52\,0!K  Y8H%U #'Ks93@<(2 DoW F A/D( kAY)<3!7!H,  F^iH8#M.&%4[54';2654#"'632#67AC K55 .7632632#"'7654&#"%5!'4'911('   e&;$6 .*>,C"<6) 1&,)#.$&<+ :)1050*0!33.Q[2#".'732654&#"&54753.+'>75#5!#2#"'73>5654&#6'25"7!0 "D-7a:#32M*.;!"+&( PT'; 6&$ 5$1@ '@!0'*2"B_OGP85)9+5*33.'*';)#oq O.X\%.#'67.'32?3>54'#72654&#"&54>7632632#"'7654&#""#5!w!%JR, 1+M4/  '433b= >!)0% H]jX  &) 1&,)#.$&<+ :)1050*0!&;:#33.`j2#5.#'67.'732654&#"&54753.+'>75#5!#2#"'73>5654&#6'25"AK !0 3S+!"+.Q132M*.;!"+&( PT'; 6&$ 5$1@ '@!0';2,0#! FVGGP85)9+5*33.'*';)#oq F.im.#"#"&54732?6325#".'32654'#72654&#"&54>7632632#"'7654&#""#5!E)LZ.EG  46371('   '445ʅ)M@!4 .<)+ .*>,C"<6) 1&,)#.$&<+ :)1050*0!&;33.Wa7&546753.+'>75#5!#2#"'73>5654&#632#5&#"#"&54732?63254#"'25"&+&( PT'; 6&$ 5$33)1@)L--"  '-7z1@ '@w ?5*33.'*';)#6&*#F2$6 / * "(<q .mv.#"3"&54732?6325#".'732654&#"&54753.+'>75#5!#2#"'73>54&#6323#25"zC0LZ.EG (643;5^=%32M*-<%++ (XE'< 6&$ 5$ !1 4=<@'M@$1 *;)*&>[SGP86(4+ 5*33.'*';)#!0'iq zT.8?&#".546325.+"'675!5!##"'72>54&+#0?^&+>,RH@zw9F0/")( \22)7! *3&#Cc-/6`*.33.(L1#B%'7L JX/M.?I65654&##2#"'746353.+'6?6?5!5!##4&#""&'25"^*/5Y1[%'&$-&(8+2pV3B#''P1@ '@3 "8@2T=8;$!"5% 33@ )&q T.LS726325.+"'675!5!##"'72>54&+#4&#.#"""""&546x4& (@zw9F0/")( \22,'(#-NS".'54674'#5!##"'73254&+##5.#.'4754&#"725'.5#7#3c$'j'3 4"  ,4 3Q*  RH638a? +">S3 n&33Y 1&/ &,|5F 1 ,<W\D8U)0)x.N^c&#"&546325.#.'4754&#"".'54674'#5!##"'73254&+##25'.5#7#3Gg6)KE#3O-Q*  RH6$'j'3 4"  ,4 38a? +">S3 ?7/G'6:9[5F 1 ,<&33Y 1&/ &, U\D8U)0). )-h25.'#2654&#2#72#"'"/'#3'.'#5!##5.#"327""""&547.'#"&5463.'#"&54 '/"/<3M >)OS)#C  eR<kI3m+  "4!&&+'!A)'*?  i=9)!* 5< 338'^ /)0 -)#!&.9?675!5!##5.#"#"&'732?&'2##"'732654'76!S3973 #5*!/ NS> BG #V%ja]9idR'33l0, )3@ ,R.A/<' <Z'L4&#"7632%4>32533##54&#"632'6?67&#""&546765654#"#"&Zx=U%SB,>*y>3RR3S>`D .H+% !!& $U:)E!?;|e L 5+1!rY3gPlh"%"T/$ #'&9G   .C25!!67&547'5&#">32'7>54&#"#"54>yPG.}e, 7d-Iq%E"*+&A&2  %8-.'3!wC.?Nmx72r8,&(5K!9 D+18{KT4632533#632&5474&#"#5&+'675.#">32'654&#"&25\GaJ1@023Ci2K"0!?)+ (9$f 7 9,gO" 6PnM3 G.CdE) Am@H< -03-1 (!-4"U'  :  %8{Q\f.#'67&+'675.#">32'654&#"&54632533#632&5474&#"#5'=2SU*!9M7J2K"0!?)+ (9$f 7 9\GaJ1@023 JO" ,e-0:.5@H< -03-1 (!-4"U'  =6PnM3 G.CdE)      9+{O2533##5#5&#.#"##"&546326325&#"32632'7674#"#"&5469M.3CC2- .%$ -  -406-,>07#)"!E( 6)%1^+{=2533##5&#""&54632&#"32632'7674#"#"&5469M.3CC3=_%"/>,.H$V^!F O",E**8+ N  W15HM3< *2(#C2107#)"!E( 6)%1^+o{:@4&#"3"&547&#"32632'7674#"#"&54632533##'32#R!  *&V^!F O",E**8+ N  WC9M.3C3l72l[? (&"=7#)"!E( 6)%1^5HM3t7l. 627#'47#5!##5&#".546325./7##"&& !.K&3fO=3=_%&+>,.H$JN&H $ 5)a0 133qP *2'#C21$AZ (R8.9?M#"'#'654&##5./76?4#""&5467&'#5!#572>747474+' ;Wi$:/3+'(~#k%3'4 *nHU cK:d c 2'i ~x50%"*2.3FU&$!334F&Y.V\h.#"#"&54732?6325./76?4#"".546?&'#5!##"'#'654&##572565474+];2QH* ?A  )5+'(~$k&3" * -fU(:Xi$173hK;d c 22(W6%0 ,<)+!.3F U&  33%i ~x60$0{5H%.fo47#5!25!##"'73254&+##5.#&/4>354&#""&=47#"'3267#".573254'#"&72654#725'.5#7#36='3 3#  ,4 3Q* H7$ %7#_5_>%34b6U)2)5'(- 8`B+">R3ZMT33Y 1&/ &,|5F   -;  #2940_yHjv1 ;iI,=9% ^B8U)0).KT.#"#"&'#".573276754'#"&547#5!25!##"'73254&+##2654#"&=47#"'326732?6325.#&/4>354&#"725'.5#7#3A 6?W 5_>%35b5*2)45F'3 3#  ,4 3~())$y$ ":$_,C?38Q* H748`B+">R3"'81Hjv1 54'"'#"'3267#".573254'#"&72654#63.0 *(<44Ld3TT387p4(0 %7#_5_>%34b6U)2)5'(- ZMT34?JJ>`V3R-1C*5)!#2940_yHjv1 ;iI*=9%1MV7>754&#"327#"&5467&'#5!##"'#67'&54?#"&'7326=4'E 8"%(2 k#@64 ( =MHk-4!&)&--"- $G>' 3!+22 %N!@%2kyHY>]'3M:+)2';'-+  .:CP47#5!25!##5./7##"'#"'3267#".573254'#"&72654#27#6B<4MNG%7#_5_>%34b6U)2)5'(- P!M82ZMT33A>] (R@#2940_yHjv1 ;iI,=9%/ $%4a.3<Il.#"#"&'#".57;67654'#"&547#5!25!##2654#27##"'3267326325./7##"D)EW5_>%34b6  .)2)56=<4'(- P!M82*%7#_HD? 2 46MNG2'?6Hjv1 ;i& !,=9+MT33)%/ $%4a#2940_U, +0>] (R."O2654#7567.'#"'326'47#5!##54&#"#"'#".573254'#"&('(+"?4<+/"O $. >":#684`#$%T3%#O5_>%34b6U)2)5%963M$3 !#0 9MT33 .!O,B%Hjv1 ;iI,=9nP.1:V47#5!##54&#""&54>3&'#".573254'#"&72654#7#"'3267y6hC3]+ '+(+5_>%34b6U)2)5'(+",*":#_ ZMT33s;Z(* / Hjv1 ;iI,=9%9 * #2940_7(  .!*07265&'&5#5!!2+&'52654/&/#2qoJAb!;'9(G"`&$,\4 i7k}=]$3&0m33=,'+J 3C8 $ 3H +.6AIO.+532654./#"'#&5#5!!;26722654'#"'3265&'5#_AmS."C`z;GVx _1u?AbD=#) NC1 1rrFe2]&S)$7='4[2@]Eg&0m33@ZK&z$~<]< /H +.DOW].#'67&+532654./#"'#&5#5!!;2672&'#2654'#"'3265&'5#G$.JP, AYlhGVx _1u?AbD=#) N_AmS."!/4C1 1rrFe > *0C0<4[2@]Eg&0m33@D2]&S)$$$K&z$~<]< /H7+.Q\dj.#"#".547326325&+532654./#"'#&5#5!!;2672&'#2654'#"'3265&'5#xC L55 .32>32#"&'#4&'#&'%4&#"32654&#""5;26if0CG;6&5:":,5o "#!)=b*7%.;- ,0g*^3=c}o H$5a/W2%  '/b+ @33% @?9*#S x$ )!`QE].+' 4&7-gBO-yQ xE67"+3%.,5.#"&54632+&'#5!!#2>54.': +="6(K=+4K/+n+c=2-* 4#bDLg*9#7 /G =7<09N33=&(Yi $.k%2654'##"'&57"'327467#5!!327327.547#".'327#"'#".'&'73254'#"&(.',~4 $7/%:)>! @l7J 22.! 7$:@C1cF 8!;& 3/L$&B!$",4`M8>.K 33GQ =Gf%=#`O (!+(Z2Bm#-!@z)2K..M"67$. (}%&5''2654'##"'&57"'327467#5!!327327#5.#'67&5&547#".'327#"'#".'&'73254'#"&)J(.',~4 $7/%:)>! @l7J 3Q,!K\2.! 7$:@C1cF 8!;& 3/L$&B   !$",4`M8>.K 33GQ =Gf3 *0K. `O (!+(Z2Bm#-!@z)2K..M"6G{.SY%47"';2?#5&##5654/67.5332654'#".5467#5!!3276 @.29 ,    201#<9S(1$;# ,#2S;?C.9Up+' 0, S) r  !.L7  e38+CMg9%*) ,,*7*33!3# )T.1FO2#"&'#".'&'732654'#"5467!5!!63254#"';2654&#"&'32696)'P S,BQ0L-%)(7 =/e5}2M<^06@%1'B/D61K65k@$2N7> h @#/~&U33)P`CY5:232537632%32654'#"'732654&#"iF$cF.=",M("PG !"3)32#"'24&#"3254'#"'7;26&'32qzVZw8(#ve A1,?66c- @!<^H&4.1.&0"((.l2&?M5E/Q*  )|- *O!@r'B=+E4 *A!= ,B)2+5;HB=!7)-"?9LK6m( (6C)$ !0`x327#"./32>4'#"5?>5'.'#"&54632>32.=467+"'3254'#"'7332654#"> +!- & :]/2 h; !# ,I!  $8&P;+*8#>"#! H$  " X,#<-* .*)[yV/) N*0Pj9]s *B_>7  9 '.1X'(+%%. /^6?($!)++C.  - #8!1- $o%7'72654'#"&5432654&#"2#"'#74'#5&/67&#"#"&5473724&+"&54632>L7U.h*}1 )9d_80:)/4%!*449?[0 ! DT$,A?iP .m &;.))&E! K*+BM #< $ t\A-7/>+5 H/F\9,/oS&C8M; Bw. '6:>f$ 'G%#"'732654'#".=#5!>74#"&5473723!32654#"'632P#?*\.Lq!?6.)y[5G!* a3D/#;T *"))/&-( (*! 3 5 <1) $ / E3 37q9-$!B2H;'d.#"#"&54732?6325#"'732654'#".=#5!>74#"&5473723!32654#"'632#g>2RF* 7I $ .3(:\/KrD6.(\5G"* `4B0#;T (!")$3(V6)+ '30*#%* *" 3 5 <1+ $ / G1 37q9-$!B2L*.o 'I4&#"3".54632!32654#"'632#"&5#5!654'"&5473723##Q"    5'73;d&!"-:c4,'d[[3G!*a6AB3[@ (!/76D$"1'6vS?'O3 2 ?/) . F63t5n{P]%"&=!5!632533##&#"#32?632'7674#"#"'#"&'332654'7&547#32?6!#C9M.4BB4T`2  # #,F)+8+ 0E:qu30M0?32>54''#"=#5!#3267#"&'#".'732>54m !730)%&7 #R^1~ S-6aEH_1W/2MI</5 0 $ȇ975e;"2)%:(7#6333T]4BzH^0IJj !0)"o.=4&#"3"&54632!32?67#"&'332654'#"&=#5!##6Q"  *5&824 K(R6m3b[;RR%(C3[@ (&07-2l7?+[3'&?.33t ='L#".54>3253>74#"&5473723!32654&#"'632#"&=4&#"37 % :&#? [8E!*4/@b  "'KC/(h[B , 5#,6&.,c 5 ;1)  w 3I %"nO=(s_M h'm.#"#".54732?6325#"&=4&#"37#".54>3253>74#"&5473723!32654&#"'632#D6/E#.EF56;5/(h[B  % :&#? [8E!*4/@b  "'K(3c',.*+ *;)+>=(s_M- 5#,6&.,c 5 ;1)  w 3I %"n8F $U4A".546324.5473##"&54747654&#"3732654'y &E3lB99<8ͫwW6ca*#)Z[c2$ET"* 8%327 %N?i4#6K&/ %&)*.$!  "/(" ='(5h49K #`v\ &# XKA>$"/E% 1 )FDZ,!.=46325!!32?67#".'332>54'#"&=&#"&7*.5L4 K .U6RL33 >GV80I$S%#40!(%7;n3-2l->2$Gd_&aM/ *<2#*@3;[h2e.#"#"&54732?6325#"32654'#"&54632654'.+"327+"&54>327#vC L[.DG( 46%3i4#6K&/ %&)*.$!  "/(" ='(5 %3c'LA(- .;)+ #`v\ &# XKA>$"/E% 1 )FDZ*417.IZ%"&=&#"&546325!!32?67#5.#"#".547.'332>54'#"'32?632(4/!(8)02L4 K3C K55 1A3 :FT?/I$SM4FmQ 325!!>54#"'632i 32ZB  &"2(2F` 36% ,./7#6cL0 5",@ H$3q 6X2&"!<Y?r;327+"&54>32533##5.#"37#"&54>3254&#"r, )F>)3& 3__3f[B L!1)1GY$-H>3^+1:('c3w!icM/=B+@ H$+w4?o{B%2335#3&++4&#"327+"&54>32533#37"&546"Q3C45$Y$-H, )F>)3& 3,,%2* @63375W+w4<>3^+1:('c3:/&( J.04#"./732654''254&"&54>32%5! cM 71=71832%5!*"Mm 33R,!(v^7186u) &.X*Y?31 ZD.++  5 %09&h;$ #1U.AE.#"&546325#"./332654&#"&54>32#5!p +="6(KE#3M. 9*& 3XYBLF57 + 8&Kc-(3ov*9#7 /I'69:$*-+)! V\IFa!#'" '}];c33E.F"&54632!5!##54&#"".5463&'#"732654& +0& )1"@B \H2}#(/  ].  ,!.,  !1 7%f*336!U  )+ #<*D%8o.D4&#"3"&54632!5!##&54>32#"./332654&#"6Q"  *5&82C3 + 8&KceT 9*& 3XYBLF57[@ (&0733t'" '}]\|$*-+)! V\IFa!GU.PT!25#"./332654&#"&54>32#4&#.#"##"&5463265!["# 9*& 3XYBLF57 + 8&KcA2,'(#-9+ &*/6-$F133{?2533##&#"2?632'7674#"&547'#5!#6746:M-3BB3T`!F  # "-F)*8' G/d-n\\xZ17FM3`7#  )" F( 6'NkWG LcdY233{4[. 627#'47#>7&&547'#5!##5./7##"'& /L%3f2t2d-n <3KN $ 5(a0 1DEPLcdY233A>] (RMrWG-..?6?'&547'&547'#5!!>7)'!#2")3!#)2>32TZ,k(N!* oZ8`Pc,H#"E (37?6?#5&'R,!EZ!#)2>32TZ,k( '!#2")3 J+0G//1,H#"E (37?6?'&#""#&'73 8+(2C'2hn,k( '!#2")3$EW!- $$Q 02,H 6G (332632'."33 FG! 4F0If.A;s3@32632&=474754'#567#/JQ,!!2! 4F0If.A;."33s% >!)0+wD}*33'I6* '0 <54'#"&5463367&547'5#5!!>?6765qVN43O- (0" 0!&"%   3%#)J &"y?H8G`b?M2 4"75& 0#)#33"!.M%25#"&54632"2?&547'5#5!!>?67#5&#""5473265!'$2&'4##< 3%#)J &"y*38 2:;K -1&%# 8)#33"! 5;,<*7/.h.#"#".54732?6325#"&'332>54'#"&543367&547'5#5!!>?>?>767#B K55 .7!"&547.=47##5!##5&#"27d%* 2- *y%"V$3 ./MQ3U0  80(#z0 $sH5= MK0G33Ap  ' -Y507"753##5&#""&546325./7&54632&#yR3=`#.>-TFGkMp^),*' yU-J1& DJ3^P% )3'#CcLGK)[F=8Y4&+#3"&475./7&54632&#"75!###632R!  *GkMp^),*' #yC3yU-J1&v 72[? (&88GK)[F=8 DJ3t:L654'!53&/&5473##"&54>?654&#"7#"&5432654&'*!F 47! ΰT$4>./U9(-a <- .:8&.MC%!%30%16D<)%4*P23sv5S. G4- *%.$/^.$1kFsM20 /7T3;OA8   '+3k33H^HtBq}I 5Pb?,\F!a".: 0%"(Ee.Z.#"#".547326325#".'732654'#".'&";27#"&546325!5!!327#C /E#.EF :2965FsM20 /7T3;OA8   '+!:~QL3',.%0 &;) *+Bq}I 5Pb?,\F!a".: 0%"(3k33H^-,^.,%"&=&#"&46325!5!!>54#"'62Q,'<6!(9(5< 35%*>.@&vR3L33q 6Y1&"!=Y/.I4'!5!##".'732654&#"&5467.#"&546323>$u>t,+$N71[@43d/&$5I4$)/% )* )-0=!& >33-&3_"142JYG c}@1(7% "&!5  !253..W%.#'67.'732654&#"&5467.#"&54>323>54'!5!##!  JP*!"*6a?(4\=&$7G4$)/% () ))&)H2 $z>y*>3!  >"(0# MdZ! O#A0(7% "&"4  !2% ,,>33-&2 >5S,.L"&5467.#"&54>323>54'!5!##5&#"#"&5473>3254`C$=(+ ))&)H2 $k>j32: O 9J,8'#<(AH %"$P !2% ,,>33-&0'3*V02: >(11I).h#5.#"#"&54732?6325#".'732654&#"&5467.#"&54>323>54'!5!#"* >3C  LZ.EG  55)33-&2a).A%#&/532654#"'63.#"&54>323>54'!5!# %@(}"w66 `SaG1   ))&)H2 $k>j( +#A#m3<)H]   !2% ,,>33-&= 9y.$&547'5&#"&46325!5!!67d.<6!(9(5<e,.Lcb[23vR3L33!PUYy.06"#5&#"&46325!5!!632#7./6754&5'g3<6!(9(5<MN12 -cRTM>}*vR3L33o#+R#E :&.A3".547;26;2&547'5&#"&46325!5!!67&'#"# &/!24 i , d.<6!(9(5<e,./'5P@*81!3:b[23vR3L33!PUY .06#5&/67.#""&546325!5!#632&5455(3=e&=q9"4D$7?".W46#2D&2N;b!35:%&4)0")55*z33f;8lWq>;&!K.6<E.#'67&/67.#""&546325!5!#632&547#5'O+!?J3G&=q9"4D$7?".W46#2 5(3~D&22' J#'0?*635:%&4)0")55*z33f;8lWq>7&!    Y.HN&#"#"&547326325&/67.#""&546325!5!#632&547#=Y22#;]* ?A * '6=e&=q9"3C$"1?".We9 2 5(32LD&1<DL$3 8=* +b!35:%&4)5)55*z33f;8lSu>7eޱ6&p.1.#"&546325.#"&54>325!5!##W +>"5(LD$.J7"5- "!4#4,d1P3G*8#6/J'60C.9'& , '$E/F"e33uov.3:4&+#3"&475.#"&54>325!5!###632R!  *"4'"!4#4,b3C3v 72[? (&8.:& , '&D/F"f33t97.7D%4>3&'".#"&546323>54'!5!##54/&#""&#6'$;E )-07+' $C3)" '*ڏ.' ,, !25#>33o)((U0#,;  ..7"#"'727&#"+"&5463267.'5#5!##.'6325J $": <+,6"K (&0&T1IX`$J01O#,ESEU3:x "&'o)*&"33)<{0!B3'GR#"=74754&''65&#"'>3253>74#"&5473723!>54#"'6267&#"29d4T3 $% .# o5F[5E!*39 9f+<-/@)9 D $E9Z Y"&!? $1P 5 <0)  w 3 J&"!<4+E/" ,K~=I#"&/732654&#"&5475&''654&#"'>32533#2767&#"!0yAJ5$3 E:=)5I1,3e #K;\P0(+8"?=>;J^{XVF* A0!C &%NR  ( $!J_P3 & /y 5?727&#"63%&'4&#"'67654&#"'632533##5&''27&#"6)'kA+E!&/03W!) L&)PwZW5OQ1-&m9)4;Bt2H% *)E '4 ~K3.'`9G os,:@4&#"3"&5474/&'654&#"'>32533##2767&#&#"32#R!  *( $%.# n6F3B42 # 3#2$ ?R72j[? (&#."&!$ $1PE3tI ,+2&(!e7  s.<>32533##5&#".5463254/&'654&#"72767&#&#" n6F3VV3=_%%,>,OK $%.% # 3#2$ ?1PE3O *0($Cd."&!$ 9 ,+2&(!  sDR7463263254/&'654&#"'>32533##4'5&#.#"""""&2767&#&#"YC/5% ( $%.# n6F3VV2,'(#-< # 3#2$ ?!$F1."&!$ $1PE3 = &*/6 ,+2&(!.0:C>3267.'5#5!##.#"#"&'7267&/'654&#"72767&"76325Z.jZLUJ05 V%$( ,%#' ")V[ X(E{)+&"33 E '$*& 5!+`E!#W23!52732#"'73254&#32654#"'632#"&=./67&'#5!654'"5473;{"="w/. ,2%=0')*G *n71l*<&I8Anf-% =,3(* #(69vK Zr8 #1? 8- -407X>0A_ %M#6@33*8&1,'aNaP'% .E'675!5!!327&5467+".'27#"&'&'332654'#"/.', 26S _%+19/"#!9! -@%s$ 20:+.-7'%& .J-* 33., /hx+e s(4  31SZPEl."2("2.'5675#5!!67&54?67'&'Q\[p@f,. 4W59'}h<%2;33!4aQNI Qi "Z7I9&Z0.8>74732632&54?67'&/675#5!!67&#"#"&5S2)0x!0  4W59'}!@f,.)9q%>J\[ ,A,9B "Z7I9&Z082;33!4aQNI -[<%=.*1%&546#5&/67./675!5!#636750_I-);" Y1Ky0%*"(T` $-E^w72+[uo L;T&? *e#+33+W#T`l L d.+.+'675!5!##5&#".5462*H''%9!~A3=_%&+=ZH%$X,X.6b++33iP*1($B21.7=%#"&'332>54'#"&547.+"'675!5!##36?6'55oXN44O- (0" 0!&"9p(\g%,  S]D0,.6b++33<)  +60$X,hA.SW%6325#".'32654'#"&54632&#"3267#4&#.#"""&546325!' (9bC:"9%T,P"5R3O)4! K%3!%(#2,'(".;B05XE1Jm_:Q?3Z7?#00):2G #!9 &R:* &*/7,$F33. O4'#32'4'#5!##".'732654&#"&5467.#";27##"&5467# 6: &f %#hQ1[A43'=[06H-#1)N +%!4,("&T!-33543VD\1JXI V^A@1!>!&. 83+'8Q]`33##5./>54&#"32727+"'#".#";27""&546754'#5!6324'#32?#\%jI4QQ4";,C&,(*("7) ? D#G7 *& e)7?Q# '*:8P)YX3I% 58 ""*$3J))3+'!-3JI4,#)./;&547'5#".#";27""&546754'#5!!674'#32nd.#G7 *& ee,.# '*:Lcb[2[))3+'!-33!Q~UY4,#).2>#5'.#"&546325"&#";7"&546754'#5!#4'#3224L"3 #QA"+c   && oM4#(&:B E1?7 /G%:B|X,#'4335*5* #, .-47254&#"#"&547.'5#5!##5&#""&5465.H$`#B2U)D>NB93=_%#.E-=79.!21C+P,],&!"33P *3(+;82Nbs V2767&#&#"4'#32'4'#5!>32533##4/&'654.#"#".#";27""&54670)3#2$ >`# '*: e N$F3VV3 $%!/,#G7 *& (82&(84,#)T!-33 'E3:."%" "9))3+'bsXeq.#"3"&54732?6324/&'654.#"#".#";27""&546754'#5!>32533##2767&#&#"4'#32C0LZ.EF 46 $%!/,#G7 *& e N$F3VV30)3#2$ >`# '*:2(M@%0 .<)+)."%" "9))3+'!-33 'E3(82&(84,#)`sdr~%263254/&'654.#"#".#";27""&546754'#5!>32533##4'5.#.#"""""&5462767&#&#"4'#32 2) ($%!/,#G7 *& e L#F3UU2- .$#.;DM % 3#1% !?\# '*:1."' "9))3+'!-33&E3 % -3/7,%E--+2&(!54,#). J4'#32%467&'#5!!32732#"'73254&##5./7.#";"&5/ ;*d Z< ^r#%/"(M83'5!ll *" #33 O6GM^O7-&-=ZC;V -VK ,.Zf.#"#"&54732?6325./7.#";"&5467&'#5!!32732#"'73254&##4'#32F6LZ-EG  38'5!ln **d Z< ^r#%/"(M83V *';2(M@%0 .<)+2;V -VK , #33 O6GM^O7-&-=A'.KW#"&'332>54'#"&547.#";27""&546754'#5!##"'36?6'4'#325pWN43O-'9 0!4*O *& ea1$ # '*:NF9FbbAL2,$ 7$'/ 93+'!-3309-/ " \4,#).Q]%25#"&54632"32?#".#";27""&546754'#5!##5&#""5473264'#32!'#7")2# F#G7 *& ea/3: 2 0DR# '*:Y -2%&#  A))3+'!-330985;442B4,#)Z.gs&#3"&547326325#"&'332>54'#"&547.#";27""&546754'#5!##"'36?673#4'#32\7<0LZ.FG 929/=N43O-'9 0!4*O *& ea1$ 5)3# '*:q:M@+* +9, +nbAL2,$ 7$'/ 93+'!-3309-/ " F9:.A4,#).4@O%463&'#".#";27""&546754'#5!##54/&#""&74'#327#7A5&,#G7 *& eC3)" '*# '*:2(&#))3+'!-33o) ()4,#)09 .>  op.8?%2335#3&'+54&#"#"&547.'5#5!##"37"&5465"Q3C*03`#B2U)D>NB &5* =79.@63355C+P,],&!"33:0&( 82N.HT%25#".#";27""&546754'#5!##54&#".#"""&54632674'#32 #G7 *& ea 3 *-#+& .9A).3l# '*:))3+'!-3309*$(  @-7,$G7 4,#)\.;B%254&#"#"&547.'5#5!##4&#.#"##"&5463265;`#B2U)D>NB92- .#%.;K'2( =79.C+P,],&!"337- ,4",07-,=082N(.:FO4'#5!##5.#"#"'73267.'#".#";27""&546?#325476325n e?53 :.10A,  . 0;1$#G7 *& ˵ '*:D@5"'2!-33N+(Tj#F?9!-/))3+'U#)B4,74Eh(.Uaj.#"#"&54732?632.#"#"'73267.'#".#";27""&546754'#5!###325476325A 6K\-EG 38 :.10A,  . 0;1$#G7 *& e?53y '*:D@5"'2c'LA(- ,;)+N+(Tj#F?9!-/))3+'!-33m#)B4,74E[.;C3&54632635!5!#'654.'#5.+'67.#"&#"I!SK'; !u7J 4 :1-'X= !C" +@%"h8-i,L,=!  a33 (3"6!)& ) )K:0O;"_` ;.L46326325!5!##54&#"632'67&#""&5463254&#&#";"&=29- !"s3ZB!AH"+ '%A & 'bEAH"1@#!  %,a1G5&L33œ+\;+$'  %$1&!=QL  ^1,17,U3723!32654#"'632#"&=4/.#"&#"&546326325!5!>54#"&5473C =f*2N$, ,<!8QI(8#%"y{[5E!* z 3 H&"!8#Y:, . ^ ++N,=1&3h3 8 <0 (  U,s.#"#".54732?6325#"&=4/.#"&#"&546326325!5!>54#"&5473723!32654#"'632#@!L'F:.EG 8356$, ,<!8QI(8#%"y{[5E!*3C =f*233v& D4%0 ,<)*2:, . ^ ++N,=1&3h3 8 <0 (   z 3 H&"!8#LT6.B&54>326325!5!#>7#"&'332>54'#"5&#".#">$$3 4"(/& +"OzCRs9>-<)&:M8&)+#$G( " C #*/)$Y33 :<[rSk$&-#3,$*@i>?$7Y.b.#"#"&54732?6325#"&'332>54'#"5&#".#"&54>326325!5!#>7#@!6K\.9S29+,Rs9>-<)&:M8&)+#$$$3 4"(/& +"O33r&LA%0 *32+Sk$&-#3,$*@i>?$7( " C #*/)%Z33 :<[PF8.Q32654&#"&546325#4&#".#"3254'7#"&546326325!5!##".'NM8F40)H5 /+3''=. 1-=C0; .d?gQ326325!5!!67ge.&)+#$$$3 4"(/& e,.R]b[2|>?$7( " C #*/)%Z33!P`N.HM25!5!#632&=656=4'#5./75.#"'.#"&54>326: : ."332767&#"3d/+3''=. 1-=C0; .d?3# Z#' +3'C@"(D!/&9-%C 1 F33a ' $)E] & ,.Q&'.#"""""&54632632&/#5!!3273#"'73254&##5./67d--*"(:-(69vK ;P$ 5 K:/,: %kB-/6-,=0#%33*8&1,'aN %51 &$ 1 #2>ZFFX %.m.#"#"&54732?6325./6?&'.#"""""&54632632&/#5!!3273#"'73254&##E LZ.EF46,: %@--*"(:-(69xM ;P$ 5 L:32(M@%0 ,<)+5FX %3B-/6-,=0#%33*8&1,'aN %52&$ 1 #2>o.M%2335#3&++4&#"4&#;27#"&46326325!5!#37"&546#Q3B46!@'." 0&;GG;1.+&S )&44 ?63375Y&&3))90QR0+ 33:/$( .I%25&#".#"&54>326325!5!##5&5&#".#"##"&546326*&)+#$$$3 4"(/& O3 */",%/8C(.3>?$7( " C #*/)%Z33W) B.9+$F7!.?H%"'.'27#".'#"'72654&#'326325!!'2654/&'\ %# % 8- '/ #!7l/"C  Y{+51-S%G34 0 +#,1 &30/IK[3=#$ 0]3* G.]h4.'#"=47475&'327#"&'#"'7254&+'63632>325!!6632.+732>'2654'#"'` _0P)&%  - ):(   W&2 2'%..?b>g6Q"9mCP6D3*AYwG% +11 &' ,A* %N3M81^(/K$Aw2<J(!-Z32654&#"&5463254&#"327#"'#"#".'7&'7;>54&#"56;263533#Q&54&#"56;263533##5&#".546324&#"327#" 4#I5N$3QQ3=_%&+>,.H$P%!, <X')-1=8k_&W3P *3&$B21s/6 +oS%2335#3&#+4&#"327#"'#"'7;>54&#"56;263533##"37"&546#Q3B45P%!, <" 4#I5N$3&&'54 ?63375^s/6 +:')-1=8k_&W3:/$( Y726324&#"327#"'#"'7;>54&#"56;263533##4'5&#.#"""&5461) (P%!, <" 4#I5N$3QQ2- .$# .;C1s/6 +:')-1=8k_&W3 > ,4/7,$F.8@327'654.'"47#5!#'2654&+"#5.+'767&x1b1a4JPc])/$  2'[A!)7\$ E%Y( MK$33+## P:Q(#;GN70$0#)#g.R[d"&547#".547#5!!>32'654#"#5&#"#".4732?63254'32?'654.'"1G$ $4 '+!0#"1230<  '-()#0,a1WI # ,K$33+9)8-##B2*218#9+01S1':K -A*3F31B % 4 +o< .'Fm'<@67'&/&'#5!654'"&5473723!32654#"'632#"&'.'7#')=[3G"*`4B0;c %!".:c4.r=Ũ4tG5/  3 1 ?/). D836C$"1'6vS %6Vgh'$\dm.#"#"&54732?6325#"&547"&547#5!4#"#"&54732726323#32654'7#4&#"6'327C LZ.DG( 46JN*3^B<:NWJ0 z 5E5g~M[M8,u#=3!N! !0"c'M@*+ ,;)++3&:K37@+3F31< % 4=:35'N6H"#9+/M +o< .'jm'Y].#"3"&547326325#"&'./67'&/&'#5!654'"&5473723!32654#"'632##B 0L[.EF 046*+.r=!)=[3G"*`4B0;c %!".(!32va'LA(- 1 <) + %6V.5/  3 1 ?/). D836C$"1'+b'iT-7C654'#4>7'&5467'#5!&5473##"&7&/62654'  D%,;\P6&+)>0cGEW;9)<&7F<&:3|1 )&N?3]G#x@TV6\8!q.!9@D%"&'#5./67&'#5!!>32'4&#"'>54&#"32%&'5(.g3AcG*g-~"*'0,<+.1'-( $ D20f".H;0{UT]O$@\H:%R#A33)">-5%13gh3.  FDKG(>+7qc#ws GL2767&#&#"327'654.'"47#5!632533##4/&'654&#"#".%67#c # 3#2$ ?1b1a4F3VV3 $%-V) $" ,+2&(!B%Y( MK$3 E3:."&!$ (5 ,y #sERZch.#"#"&54732?6324/&'654.#"'#".547#5!632533##2767&#&#"327'654.'"767#F7LZ.EG  38$%-X* $4F3UU30)3#1% ?1b1 '2(M@!4 .<)+)."'  )7 ,K$3E3(82&(E%Y(  . O327'74&#"26?"&547#5!!632#"'732654&+##5&/67'C&*\ )! :Ahq)diG4Ke$!  (a8N>!  =&7533#&(4#>">>E:%0 ;#/nAW6=&.Q[j.#"#"&54732?6325&/67'#"&547#5!!632#"'732654&+##327'74&#"26?wC7LZ.EG  46=(a8?:Ahq)dgH6Ke$!   @>E:%0 ;#/N>!  :.4A327'654.'"47#5!##54&#""&5463&'#".7#x1b1a4lC3]+ '*5&3: $/%Y( MK$33oZ()!((- ,-<  3+#oR.-48%2335#3&'+5./67&'#5!##"37"&546&'5i"Q3C30BdE*g-~"!'5* I;0|UL@63355@]G:%R#A33:/&( (?+7qc{}.I3254'"'3'2654&+"#5.+'767&'#"&'6?32654'4'#5!hVG?8&h8$=9)IY]&7  2'[A!)CO?"<8  $?E",l$H8$"5 N7P(&4GM80$:Q3  @*33.Yc%&5467&'#"&'6?32654'4'#5!#>32'654&#"#5&#"#".5473263254#"'3254'"'$1#."<8  $)+!0#"231;V%7 (+2R 1,%C8$= # !H?3  @*33"5/8-#B2* #3*)A"8; /I$H8$v}.RXb.#"#".547326325.+'767&'#"&'6?32654'4'#5!#'2654&+"#3254'"'h:B/.) >>2,2'ZA!)CO?"<8  $)IY]&7  3VG?8&h8$=T' ;(*+ *;) +EN70$:Q3  @*33"5 N7P(&4IE",l$H8$S R3254'#3233##5'./;2654'#"&5473274'"&'#"'7327#5!2 '!]*?7X3ll1!%#)(, ?V=A-*-  K10 <"1% $ ?2)> ! ' ,$C=W3&  ?3I0&J 3/6::!)n3EdI'KS%2654#"'632#"&'5.#"#"'73267.'5#5!467474#"&5473723!25!6?a*/6a6 +4-!21@,%. B_2[8E!*a3DC '1`$RK&"!<9Z!-?4?4jOCK7%3 4 <1)  / C73n=EoIC$W4&+3223#32654'7#"&54?.'#"&'6732654'4'#5!4#"#"&54732726%V9#=CE5g~NZN8+v#c',.(- ,;)+3&@R+=*3!A)3F31B % 4=:3<;B70#9+/&%M+$H9*.>G#".'732654&#"&5467&'#"&'67326=.5#5!!3254&#&#"dT7&'#"&'6732654'4'#5!##3254&# JO+!%6b?(3-5N*5I41* +"2"<8  #7W&$"43f9#=B  >!)0NdZ ;PA.@1(7!& #,F3!A)33"#2 UK+$H8 ).JT"&5467&'#"&'6?32654'4'#5!##5&#"#".5473>3254'3254'"'`C$;'6"<8  $7W$30< O $7 ,5*#<(8$=EH%"#OH3  @*33"1 53*!/) 2:;&31$H8$h(.bk.#"#".54732?6325#".'732654&#"&5467&'#"&'67326=.5#5!##3254&#uD6/E#-EG (38)1[?43\>&%5I3$)2(5"<8  $7W% #">3[9#=c',.(- ,;)+b 2HZG S"@1(7%! E3 @* 33"!4 UO.$H8 *q&.>H%#&/536>7654#"'67&'#"&'6?32654'4'#5!#'3254'"'#J1|"v54! )%& `G1z/"<8  $7W.&?8$=+3#B#m3 I] |?3  @*33"%7#$H8$. >2654'#%3267#5!##5.#"&546325.'+"/P ' 4A !:&/.96325.'5#5!##5&#""&546325.#"#"'7326s@5"'2 B_853=_%#.>,-H% :(20A,  -84EK7"33O *1)#C21N4?4j#Es W2767&#&#"'3254'"'3#67632533##4/&'654.#"'#".'#"&'6?32654'4'#5!0)3#2$ >8$=`' B!F3VV3 $%-44 "<8  $7(82&(($H8$)E3:."'  )(3  @*3sWdns.#"#"&54732?6324/&'654.#"'#".'#"&'6?32654'4'#5!632533##2767&#&#"'3254'"'3#6E LZ.EF 46 $%-44 "<8  $7!F3VV30)3#2$ >8$=`' 2(M@%0 .<)+)."'  )(3  @*3E3(82&(($H8$s`nx}%63254/&''654'#".'#"&'6?32654'4'#5!632533##4'5.#.#"""&546322767&#&#"'3254'"'3#6 ( %&214 "<8  $7H3UU2-1$# -3&'#".'#"&'6?32654'4'#".  8$=YC4\+ ' )(% / 4 "<8  $".0< 3$H8$33oZ (+" /!(3  @*o.D63252335#3&'+5.#"#"'73267.'5#5!##"37"&546s@5"'2##Q3B/31 :(20A,  - B_8!'54 84E?63345N4?4j#EK7"33:/$( .IS726325.'#"&'6?32654'4'#5!##54&#".#"##"&5463254'"'10!2 "<8  $7W33** $ .9B8$=6 '3  @*33"<(  %*(-7,$F$H8$.I6325.'5#5!##4&#.#"##"&546326325.#"#"'7326s@5"'2 B_852- 1#! -.#""&546325&/32>54&#"&54632&'#5!K '7!&"/>,-H%z_:&: M$B0d/6lY&&3|"8 *2)#C21Tc09!(# $<#$*9+KZ9o2[p!*33I..22'654&#"&/32654&#"&546326%5!0:.;&A|Z&[,CXK&1++ Q?0a 5'v;1$:*.#a!Yr!G9!@3$=4 %4EF*-V33./=B4'#5!#2?&547#5.#&'>354&#"/46725'.5#7#3f%X9 0D3O+$1J5-+B?YG+DR1!#33]*/On=|6E!+;( h9 ;M52*=.O;27#"&'&/32>54&#"&546326326325!5!##4&#"4&#|/'-@ %CY&_:&: M$B0d/'V":0/+&+VN3@'." %*801+"[p!H9!(# $<#$*9+K4''0+ 33Y&&3)J.FJ%25&/32>54&#"&54632&'#4&#.#"##"&5463265!"z_:&: M$B0d/6lY&&2-+"#! .;J(2( Oc09!(# $<#$*9+KZ9o2[p!*7-  B"07,+?033W~P[g2533##&#"32?632'#".'32654&'#"&=#5!#26754>4632#"654#"+1;K-2AB3S^*= # ,&D(#p[=b7'/Z4(-CP4 %  Y&7, "b,!/0HP3 `:  7(>'WjIe[&$[H4 7!5+33" b (< 2i^ 7hT.,39.#'67.+"'675!5!##"'72>54&+#/P+!AU(w2zw9F0/")( \23)L Kf!*0D,4U6`*.33.(L1#B%'7L2JX/W)  +{2.#'6735&#"32632'7674#"#"&54632533##yQ,!McV^!F O",E**8+ N  WC9M.3CC3 *0M1o7#)"!E( 6)%1^5HM3N.)/.#'67./7##"&547#5!##27#OQ,!ES"q=N&HO=3& !.K&3$.J *0E-0B (R8,33SE $ 5)a0  U. )%.#'7&'#5!!#'2>54.'1JP,! c=2-* 33#bDLgC >!)033=&(4GYi .CN&'#5.#'67&+532654./#"&=#5!!;26722654'#"'\CJ3%80?R/."3O+!B]}GVx _104*= "12 NC1  '  <(3/)$3#'0F/U4[2@].33 @ZK&7a.M.#'67&547#".'32?#"&'&5332654'#".547#5!!32?#Q,!DY #0C( $*%*`4H3m9"@(1'2KzK9# 3!)0F../]X ! B!-"$,!@Rx+F! c6'$&1/a1337'!>_;HTZ'?7523!32654#"'632#5./7.5#5!654'"&5473?+G$6A/;d&!"-33-%&&d[[3G!*ai#%#/GF636D$"1'IM#3* 9 O3 2 ?/) .D.=%"&=#5!!32?67#5.#'67.'332654'S JD(F4 K/14Q, *4)?0+3"'9!;RR2 9.33-2l#`3!)0-"7Q_,M=E.[3'&??,.#'67354&#"327+"&54>32533##dQ,!McY$-H, )F>)3& 3__3 *0M1c+w4<>3^+1:('c3.U.9=%.#'67./332654&#"&54>32#5!`JQ,!-32$ 3XYBLF57 + 8&Kc503v  >!)0."#+-.)# V\IFa!#'" '}]Ai33[7<33##5.#'67./>54&#"32727+"&54624\%jI4QQ4P,  (V~Q2JL8P)YX3`3 *0@*=@ 8 ""*$3- 2DJe&.!'"##5!!632#7./6754&5'g3HLP12 .cRUK>}* 33p#+R#E 9&-5 .5:5%"75!##5.'#5./7&54632&7675#0{&]#yg3C3GkMp^),*' yU-J1&3gw: O4  2 DJ3X/{ VGK)[F=8Y323>f=-D'3$k>j3-$&$z 94 ))&)H2 !'#/>33-&5$3*!L, !2% ,,.$*767.#"&54>325!5!##5.#7JfA&'"!4#4,b3P3Q,CKEN0?C , '&D/F"f333 *q'  s#1.#'6754/&'654&#"'>32533##2767&#&#"P*!Md $%.# n6F3VV3 # 3#2$ ?"(0N0F."&!$ $1PE3 ,+2&(!. ).5.+'675!5!##5.'#675s.{%]U9!~f4D3H''%3on: M6  1.6b++33X/z $X,JL+YA.:>%4632&#"3267#5.#'67.'32654'#"&'5!$.J)4! K%3!%(#2M,!'*:_B*9%T,P"5R3OXG #00:2G #!9 &R3!)0) LukDQ?3Z733.=574'#32'4'#5!##5./67.#";27""&5467(C'G$3# '*: ea3-$&'l$c *& %##/4,#)T!-3309;$3*#CG3+'c .CIV.#".54732?6325./67.#";27##"&546754'#5!##574'#32^;V%B6+@D  .4-%&:Y$c ,+ "a33E%H#3#  6:g' D5'/ /:,+1#3*/7G3*#!-3309B.'!"04, K&h.',5.#'6754&#".547.'5#5!##'5x=79.S+!Jg`#B2U=4>NB93hO/82N +0L1C+P,L/&!"33m+}. J%55>754&#".547.'5#5!##5.#"#".54732?6325.#O/=79.0O2`#B2TB. ALG83B!6/E#-DH (47R,+}73N27 C+O,G1$$"335',.%0 .<)*+, .6.#'6754&#"4&#;27#"&46326325!5!##Q+!Md@'." 0&;GG;1.+&S.N35 *0O/QY&&3))90QR0+ 33=767354&#"327#"'#"'7;>54&#"56;263533##5.#JfP%!, <" 4#I5N$3QQ3Q,EN0s/6 +:')-1=8k_&W33 *&./957#5./67&'#"&'6?32654'4'#5!!3254'"'e=-D'Q33-$&(kK$"<8  $78$=5!'#/"<$3*$B]3  @*33$H8$.%.76735.#"#"'73267.'5#5!##5.#6325Jf :(20A,  - B_853Q,@5"'2EN02N4?4j#EK7"333 *84E. 75%5!##5.#&/32>54&#"&54632675.{%]Hf4H"^Y&_:&: M$B0d/3gnq: M6 133X66 [p!H9!(# $<#$*9+KQ5L+'.26%.#'67&/32>54&#"&54632&'#5!KJR+!EZu_:&: M$B0d/6lY&&3  >!)0F/X,9!(# $<#$*9+KZ9o2[p!*33d#"/#5.#"#"&54732?6325./>54'"&547326733#3274#"3"54632K+9 4C7LZ.EG  4686q4)$1( ,(54'"&547326733#67=/_4C7LZ.EG  4686q4)$1( ,(?>54#"&546#0%s/O;5SKI/ &@b8M 6$,E-/()"9$ &[OYY6#80B:[o ;$YkGO *"%Q[%`;+1># 3 .F{`"&'#5.#"#"&54732?632&#"32632'7674#"#"&54632533#3274#"3"54632KT)3CYM.DG28V^!F O",E**8+ N  WC9M.3  6 *>0#$,96G##6'W6), *;)*<7#)"!E( 6)%1^5HM3G,X'$;(<{{W%&=47#5.#"#"&54732?632&#"32632'7674#"#"&54632533#67=/^3CYM.DG28V^!F O",E**8+ N  WC9M.3@7CB _! 6'W6), *;)*<7#)"!E( 6)%1^5HM3#`%+{j"&'#4'5.#.#"""&54632632&#"32632'7674#"#"&54632533#3274#"3"54632KT)2- .$# .;C/1) (V^!F O",E**8+ N  WC9M.3  6 *>0#$,96G##   ,4/7,$F17#)"!E( 6)%1^5HM3G,X'$;(<+{{a%&=47#4'5.#.#"""&54632632&#"32632'7674#"#"&54632533#67=/^2- .$# .;C/1) (V^!F O",E**8+ N  WC9M.3@7CB _!    ,4/7,$F17#)"!E( 6)%1^5HM3#`%.|.#"#"&=7332632'&547#".'32?#"&'&5332654'#".547#5!!32?3274#"3"54632#".'A t"?O2)/!y '$#0C( $*%*`4H3m9"@(1'2K(K9#  )7 *>0#$,A4   --4XA ,F4 2H']X ! B!-"$,!@Rx+F! c6'$&1/a1337'!#3X'$;(<-,Q ,M6A.q.#"#"&=7332632'&547#".'32?#"&'&5332654'#".547#5!!32?67&/&=47A t"?O2)/!y '$#0C( $*%*`4H3m9"@(1'2KLK9#  ,8/ ]--4XA ,F4 2H']X ! B!-"$,!@Rx+F! c6'$&1/a1337'! #`% 1T .KE/! K5A.LP#"/#4#"#"&547372&#"327#"&546323274#"3"546327!5!L*: .\ =K, V'&w !)7.    5* >0#$,#97F/r]I4<*3$#m'$#*8. )   X'$;(93.<@%&/&=47#4#"#"&547372&#"327#"&5463267!5!b/ ^.\ =K, V'&w !)7. @7?D>G .KE/! r]I4<*3$#m'$#*8. :L3m#"/#5.#"#"&54732?6325'./>54&#"32727+"&546233#3274#"3"54632K+9 4CLZ.EG (46A1]A,$%#  7) ? (V~Q]$iJ4 )6 *  >0#%,94I/5(M@*+ .;)+BF11 8 "*$3- 2DJ=7Q(ZX3 3X'$;(<{`%&=47#5.#"#"&54732?6325'./>54&#"32727+"&546233#67=/^4CLZ.EG (46A1]A,$%#  7) ? (V~Q]$iJ4@7CB _! g5(M@*+ .;)+BF11 8 "*$3- 2DJ=7Q(ZX3#`%.B%&#"3262&'#"&4632654#"#".5467#5!!32>F$ $%3@-   (0M9<("/24:3;-,9 !+0&0\LD4WE BA9908?JV!?-:#&K22O&7(/(.T#"./4&5&'#"+".547;26;2&547'#5!!673274#"3"54632A4)  .(5 P '0!1-$ i#* d.e,  6 *>0#%+9,Q1C^P @*/:!3:jS2"33!F+X'$;(<.E%&=47&'#"+".547;26;2&547'#5!!6767S/[ .(5 P '0!1-$ i#* d.%e, +8CB b! 1C^P @*/:!3:gV2"33! #`%5W%"&547326325./7&54632&#"75!#3274#"3"54632"&'#5.#"yyUDUF`.EF 3 :FkMq_<+( $y$  6 *>0#$,KT)3D = $#&$k>j ,-)=52$.6&6 o& )6')H2 >33,'2 (!4/&QE'+H,' " Q !2!+,,.=74632'.#"&54>323>54'!5!#&#"327'#"&;,  :1 ))&)H2 $k>j(#%" 'o"*E(39- !2% ,,>33-&> S'(.+4'!5!#'7".#"&54>323>$k>jd3b:D  ))&)H2 >33-&1,G (J8g,, !2% ,,.G7467&#"&54>323>54'!5!##"73254'#5>54&#"3&80?' ))&)H2 $k>j!D"4ZIj0(Wp2 89,O*51]$? . !2% ,,>33-&($0426BGC) 1(%'4 Q.c#"./&'&'#"+".547;26;2&547'5&#"&46325!5!!673274#"3"5462$K*)  /'5P &/!24 i , d.<6!(9(5<fe, -7 *>0F-96G5AUY @*81!3:b[23vR3L33! 3X'$;(: .T%&=47'&'#"+".547;26;2&547'5&#"&46325!5!!6767/\ /*2 P(. 24l$) d.<6!(9(5<!%e, +8K: d! 4@UY @*81!3:b[23vR3L33!  sUc#"&'#5.#"#"&54732?6324/&'654&#"'>32533#3274#"3"54632%2767&#&#"A4*)3C LZ.EG 46 $%.# n6F3 )7 * >0#$, # 3#2$ ?9,Q##5(M@!4 -<)+)."&!$ $1PE33X'$;);Q ,+2&(! }sJX%&=47#5.#"#"&54732?6324/&'654&#"'>32533#672767&#&#"?/W3C LZ.EG 46 $%.# n6F3C- # 3#2$ ?CB _! o5(M@!4 -<)+)."&!$ $1PE3#`%# ,+2&(! sao#"&'#4'5&#.#"""""&5463263254/&'654&#"'>32533#3274#"3"54632%2767&#&#"A4*)2,'(#-0#$, # 3#2$ ?9,Q## = &*/6-$F1."&!$ $1PE33X'$;);Q ,+2&(! sVd%&=47#4'5&#.#"""""&5463263254/&'654&#"'>32533#672767&#&#"D/\2,'(#-0#$,A4))4#:/ #*.) H''2" H,6`-+333X'$;(;.,Q"!5 ;'+* (&3{$`!k.>G726325.+'675!5!#67&=47#5.##".547  8"zqA1/Y4#:/ #*.) H''2" H,6`-+33 #`% 1T d! p5 ;'+* (&3{$`!N.Q5#"&'#4&#.#"#"&46326325.#'675!5!#3274#"3"54632g~E0oA4*)2- 1%$ .;J(3' *9!~g  !6 *>0#$,:$e8,Q##<)  +607X>0,.6b++33G-X'$;(<+.DM%&=47#4&#.#"##"&46326325.+'675!5!#67/]2- 1%$ .;J(3' *9!~D"TH''%1T d! <)  +607X>0,.6b++33 #`%$X,.RV#"/#.#"##".547;725#"&54632&#"32?3274#"3"54632%5!A49- -!  9;$1C1*m7aD0;3% 9/:81 )6 *  >0#%+79,Q/#"J5214B "U>0!+$+ 38883X'$;(:33.EI%&=47#.#"##".547;725#"&54632&#"32?675!n/^- -!  9;$1C1*m7aD0;3% 9/:81A6zň1T d! #"J5214B "U>0!+$+ 388E-Y"f33=.PW#"&'#5.#"#"&5473263254&#"#"&547.'5#5!#3274#"3"54632%5L)(*3C YM.EF :56`#/*U)D AML  !6 *>0#$, ?59.97F##;5(W6+* *;) +5+P,],%""33G-X'$;(<73N={.FM%&=47#5.#"#"&5473263254&#"#"&547.'5#5!#675=/[3C YM.EF :56`#/*U)D AML?5T?59.CB _! 5(W6+* *;) +5+P,],%""33#`%f73Nst"&'#5.#"#"&54732?6324/&'654&#"#".#";27""&546754'#5!>32533#3274#"3"54632%2767&#&#"4'#32KT)3E)LZ.EF46 $%!/,#G7 *& eM#F3  -7 *>0#$,3#2$ ?[# '*:96G##5(M@%0 ,<)+)."' $":))3+'!-33 %E3 3X'$;(9O)!2&( 64,#)sgv%&=47#5.#"#"&547326324/&'654&#"#".#";27""&546754'#5!>32533#672767&#&#"4'#32/W3F6YM-DH :38 $%/,#G7 *& eK#F3E+3#1% !?Z# '*:1T d! o5)W6%0 ,<) +) *"' $":))3+'!-33 %E3#)!2&(!54,#)O..4@#"&'#5.+"'675!5!#3274#"3"5463254632#"&6A4*)3>$h )7 *>0#$,09twF&9,Q##Y/4^6&333X'$;(<- \'"'.#)5%&=47#5.+"'675!5!#67%54632#"&/X3>$@B/~9twF&CB _! Y/4^6&33#`% \'"y.%#".'732654'""#"'7332>54&'.#"632'6?654##"&5463275#4&#".#"3254'7#"&546326325!5!# P+@uL.3Sz7%    #;%!,*4.  H"%/+3''=. 1-=C0; .d?1d' ):X}r% Ef$ - @I'D/ "0/  "IGF(D!/&9-%C 1 F33DaJU#"'732654+563632>76?67#"&'732654'#"'673264'.'3>7#"&(  `   M%%- )E$M9m%2Q!?"  '1" 1 G,A#=! ~"Y/Tj&/ *,d%P ( + j#"&'#5.#"3"&547326324&#"327#"'#"'7;>54&#"56;263533#3274#"3"54632A4*)3E0YM.EF 2 56P%!, <" 4#I5N$3  !6 *>0#$,9,Q##5)W6), .<) +Ms/6 +:')-1=8k_&W3G-X'$;(<^%&=47#5.#"3"&547326324&#"327#"'#"'7;>54&#"56;263533#67J/V3E0YM.EF 2 56P%!, <" 4#I5N$3C,>G ^! o5)W6), .<) +Ms/6 +:')-1=8k_&W3u#"&'#4'5&#.#"""&546326324&#"327#"'#"'7;>54&#"56;263533#3274#"3"54632A4*)2- .$# .;C/1) (P%!, <" 4#I5N$3  !6 *>0#$,9,Q## > ,4/7,$F1s/6 +:')-1=8k_&W3G-X'$;(<k%&=47#4'5&#.#"""&546326324&#"327#"'#"'7;>54&#"56;263533#67R/]2- .$# .;C/1) (P%!, <" 4#I5N$3A5CB _!  > ,4/7,$F1s/6 +:')-1=8k_&W3#`%scpx#".'#5.#"#"&54732?6324/&'654.#"'#".547#5!632533#3274#"3"54632%2767&#&#"327'654.'"767#K*) 3F7LZ.EG  38$%-X* $4F3  6 *>0#$,0)3#1% ?1b1 '96G5(M@!4 .<)+)."'  )7 ,K$3E3 1'X'$;(0)3#1% ?1b1 'CB b! r5(M@!4 .<)+)."'  )7 ,K$3E3#`%#(82&(E%Y(  . FP73267&#"&'#"&54632765'&5&'#"&'6?32654'4'#5!!3254'"'(# 8-$A71%-7'9X)"<6  $78$=  ""1 7);(&HM'-"$-' "! j3  @*33$H8$1.;E74632'.'#"&'6?32654'4'#5!#&/&27'#"&3254'"':. #7"<8  $Zz%# '#D 'o:3#8$=&42.'3  @*33" 4 X6G$H8$6.%/?&'#"&'6?32654'4'#5!#3254'"'͑Y)"<8  $7W)!d8$=j k3  @*33D6,G~8$H8$.KU#".'73254'#5>54&#"3&5467&'#"&'6?32654'4'#5!!3254'"'#."4ZI.PDM0)Wp278-F 4+2]17/"<8  $78$="/ ,527B%AYD) 1%-'4NG >3  @*33$H8$\.V_#"&'#5.#"#"&54732?632.#"#"'73267.'5#5!#3274#"3"54632%6325A4*)3C LZ.EF29 :(20A,  - B_8 )7 *>0#$,@5"'29,Q##Z6'M@*+ ';)* N4?4j#EK7"333X'$;(<84E\.KT%&=47#5.#"#"&54732?632.#"#"'73267.'5#5!#676325U/[3C LZ.EF29 :(20A,  - B_8c@5"'21T _! 36'M@*+ ';)* N4?4j#EK7"33#`%f84E;sr"&'#5.#"#"&54732?6324/&'654.#"'#".'#"&'6?32654'4'#5!632533#3274#"3"54632%2767&#&#"'3254'"'3#6"KT)3E LZ.EF 46 $%-44 "<8  $7!F3  6 *>0#$,0)3#2$ >8$=`' 96G##5(M@%0 .<)+)."'  )(3  @*3E3G,X'$;(8$=`' >G ^! p5(M@%0 .<)+)."'  )(3  @*3E3 (82&(($H8$6s#"/#4'5.#.#"""&5463263254/&''654'#".'#"&'6?32654'4'#5!632533#32>74#"3"54632%2767&#&#"'3254'"'3#6K*; 2-1$# -0#$, # 3#2$ !?8$=Z! 96G/ % +5/6-$F1$#"), %(3  @*3 E3F,'#'$;(9O ,+2&(!+$H8$  su%&/&=47#4'5.#.#"""&5463263254/&''654'#".'#"&'6?32654'4'#5!632533#672767&#&#"'3254'"'3#6/ W2-1$# -0#$,@5"'29,Q##:*  +6"06-+?0N4?4j#EK7"333X'$;(<84E.U^%&/&=47#4&#.#"##"&546326325.#"#"'73267.'5#5!#676325X/ ^2- 1#! -54''4&#"3&546327%5!w=3+!*W "h~G29S&+H$+#!&A[G6H&B225GDi&R $j|"F"!0&8%`'2-$02T5FKV!_33!.6:%47""./32>54&#"&54>32632'&5!  o\&D?[>&: L%/,#<(6k :+N@/L$Xs!U?!(# $=4!3 "*W6 39OW ,33N.,08#"&'#5.+'675!5!#3274#"3"54632%'5A4*)39!~g  !6 *>0#$,9V$ %9,Q##Y.6b++33G-X'$;(<7@>e X,&.!%-%&=47#5.+'675!5!#67''/X39!~?B/9V$ %>G _! Y.6b++33#`%@>e X,N.,4=#"&'#5.+'675!5!#3274#"3"54632.'75A4*)39!~g  !6 *>0#$,`:,n6H''%9,Q##Y.6b++33G-X'$;(<&Q . I7Q$X,)."*3%&=47#5.+'675!5!#67.'7/[39!~B?5`:,n6H''%CB _! Y.6b++33#`%o&Q . I7Q$X,.LP#"&'#5.#"#".54732?6325.+'675!5!#3274#"3"54632%A4*)3C /D#-DG 19:!~o 6 *>0#$,9V9,Q##4&,-&- /;(*%-6b++33X'$;(<7@.@DL%&=47#5.#"#".54732?6325.+'675!5!#67'A/]3C /D#-DG 19:!~o6@9V$ %1T d! 4&,-&- /;(*%-6b++33 #`%@>e X,,T.*1'7675!5!##"'72>54&+#5.+"7zw9F0/")( \23@){({`*.33.(L1#B%'7LfX/JX/,w/'733##5./>4'"&5473267ZW$Ld3TT3:3:*4(%1( &'={({R5FaV3R,1-45)*%/DJ+,t{.'72533##&#"32632'7674#"#"&546WQ9M.3CC3V^!F O",E**8+ N  W{({5HM3`7#)"!E( 6)%1^,Q.''727#'47#5!##5./7##"&3a& !.K&3fO=3JN&H{({? $ 5)a0 133AAZ (R8 ,2 <F'7>32#"'326?#".'732654'#"547&'7&#"325k I4M.',59(#)\H>g@&3"5R0<3% =!o#>(5<$U{({TE)+) W<P-JcM|B @ykAE.0,"4!W>&1 5,. "'7%2>54.'&'#5!!#̦#bDLgc=2-* W{/{({Yi 33=&(0^,.9D'7.+532654./#"&=#5!!;26722654'#"'| %80?R/."C`z;GVx _104*= "12 NC1 {({ <(3/)$7='4[2@].33 @ZK&,.I'7".547#5!!32?&547#".'32?#"&'&5332654'zQ'2KzK9# 0 #0C( $*%*`4H3m9"@({({1/a1337'!>_;HTjN]X ! B!-"$,!@Rx+F! c6'$&,"+'7675!5!33##5'&'#5.+"7qpz63VV364?#q#){({a,+3@X3=$W2;V1,:H^'7#"&'#4&#&+&547;636;24&#""327#".546327>32'4&#"2654&#"53260g*\3B^#H}/69 ":, %n  "#! *5'2*,=35a.W83%'/{({40gBL3E9 C<9*#S x $ $>Ba1>-44'xE67!,3%,'5'723!32654#"'632#"&5#5!654'"&5473|6A/;d&!"-:c4,'d[[3G!*a{({\F636D$"1'6vS?'O3 2 ?/) .,T(4'73##"&54>7>54'#53&5472654'|/2Ư2@fHFV2 ʬP6&(:4I<"G0{({,N73Pr^HZD N=%3]G54#"'62|,'x 35% *>.9d{({?'33q 6Y1&"!=8[?,]('7327+"&54>32533##4&#"@, )F>)3& 3__3Y$-H{({5>3^+1:('c3W+w4,U.-1'7&54>32#"./332654&#"%5! + 8&KceT 9*& 3XYBLF57v{({ '" '}]\|$*-+)! V\IFa!w33,]8'733##5./>54&#"32727+"&5462@\%jI4QQ4";,C&,(*("7)!> (V~Q{({S8P)YX3I% 58 ""*$3- 2DJ,-.'7'&547'#5!!67d.Oe,.{({Lcb[2"33!Q~UY-,:5")'7"753##5./7&54632&U#yR3GkMp^),*' yU-J1&{({ DJ3VGK)[F=8Y325!5!##5.#"04#4,b3P3"4'"{({0&D/F"f33.:& ,  ,{s .'7>32533##4/&'654&#"72767&#&#"] n6F3VV3 $%.% # 3#2$ ?{({O1PE3:."&!$ 9 ,+2&(!,Y..'73254&##5./67&'#5!!6;2#"'q I<38b($fNr3>(69vK Zr8{({ #1?ZFA_ %M#6@33*8&1,'aNaP'% , .'7.+'675!5!##9!~A3H''%{({.6b++33$X,,A./3'74632&#"3267#".'32654'#"&'5!)4! K%3!%`K9bC:"9%T,P"5R3OX{({$#00):2G #!9 @s1Jm_:Q?3Z733].%'7.'5#5!##54&#"#"&5475@h>NB93`#B2U)D>=79.{({:&!"33C+P,],82N,J.!'767/.+5!##5.'-9Y KU?3)9?IY7;G&4{({9C 233LCR :F7""5j, .''7675!5!##5.+"754632#"&G3>09twF&{({^6&33Y/, \'",.3'7;27#"&46326325!5!##4&#"4&#c0&;GG;1.+&S.N3@'." {({)90QR0+ 33Y&&3),9'7#"'7;>54&#"56;263533##4&#"327#"q1 4#I5N$3QQ3P%!, <{({')-1=8k_&W3^s/6 +,D.'7&'#5!##5./6&'5&r-~"F3BdE*I;0|UL{({C#A33@]G:%3(?+7qc{,. *'76325.'5#5!##5.#"#"'7326q@5"'2 B_853 :(20A,  -{({84EK7"33N4?4j#E,.#''72&/32>54&#"&546'5!|6lY&_:&: M$B0d{({Z9o2[p!H9!(# $<#$*9+K33,J.6A'7"&=#5!!6?6?67#".'32>54'4632#"&-%.   (4wY=a9'3.EN#)=#$B {({6(33 p"YoIg]$TY2$6-2((4 ,.!/'7%"&5#5!!>54#"'6324632#".#4Z.M#"(Lj!- {({/733h]d# "mL_-!,9.*'7&+5!##5&/674632#"&xeU I3C,=,E$Q(/K+) %&{({K]23Lp/8B*5G# $#%fX '&,#. '7'.+'675!5!##9V$ %9!~A3{({I@>e X,X.6b++33, . %'7%.'77.+'675!5!##`:,n69!~A3H''%{({&Q . I7 .6b++33$X,W.=A'&54632>32'654&#"#5&#"#".5473263254#"753$i.$. +"0$"531;V$6 ()R 3)%Cͫ #3g;- 9+#B2* "2+)A(2  /H33g-2#".'73254'#5>54&#"3&54>5e"4YJ.PDM0(Wp2 88-F 3,2]$5)g9)327B%AYC) 1%.'4N!1 a,"2#".'732654&#"&546s0A\G+N8,3 2L*+>*+3,M9AM*?L?DN64*!.BaR*%&54632#5&#"#"&5473263254#"]*34'2  )M.,#1',7)^6&)# C4$6 3+"(= *%&54632#5&#"#"&5473763254#"f1<31; :I,8'/='$C 2f142*W.2: ;(10I <.#4'!5!##".#"&54>323>$k>j6:D  ))&)H2 >33-&"E,, !2% ,,R&#"&546323#YId6(KE#3M.33e7 /J'69:~'.#'673#bF(B,D<Md33 ) 2L/0/N0!56753#5.'28I"0{33-%&0.&,<)L!#3n?.'25#"&54632"2?#5&#""547326!'# '4##>U$-- ]_sX'. 0',/#Fk".##"&54732?6323#R %,1D.*"$ B 33` O90% %(1  }*"463263253#4&#."##"K'3' (32-+F% .BX=0e7- C",/P#".'732654'""""'732654&'.#"632'>54##"&54632&25F43aF83 T$   #7$%%*+3 < G#&5Y2 !#@:WfXq# -(>IL. ".B  !J)^m23####5.#"3"&547326324&#"327#"'#"'7;>54&#"56;26354&#"&5463.#"B4]XGJJ33E0YM.EF 2 56P%!, <" 4#I5N$6?HHiϑf,[TMG )7eE3b5)W6), .<) +Ms/6 +:')-1=8k_&z"$%HSu$#!.'26=33265#5!##"'67%30" C3X 64YA &)+""*2 FHm33:Q'P w.8%25!;2?63247#5!##"'6?32>54#"#".M,!74?;mwXbpYB' &@2;-%'3:P%7!?D4=?S633]dPCJV!? ;.$/726=&#"&46325!5!##"'>73265(<6!(8)5<;X65YB %0"B3\(evR3L33:Q'P*2 GG:.=H%26=4&#"4&#;27#"&46326325!5!##"'?3265M%@'." 0&;GG;1.+&SW 64YB ' {0"C2)+Y&&3))90QR0+ 33:Q'P  q*2 GGmBM%26=4&#"327#"'#"'7;>54&#"56;263533##"'673265P%P%!, <" 4#I5N$3X 64YB &0"C2)+s/6 +:')-1=8k_&W3:Q'P q*2 GGm. (,7%5./67'&'#5!##"'?3265&'533265 ,$<!!E7.(X 74YA '(90`G8p3/#C30.,8(33;Q'P ' 3$  \g|+2FHJ.1;H%26=#".'#"&'6?32654'4'#5!##"'>?3254'"'33265Z%4 "<8  $W 65YB G8$=90"C2\+ (3  @*33:Q'P$H8$*4DJ:.+4?%26=.#"#"'73267.'5#5!##"'?632533265U% :(20A,  - B_8X 64YA  @5"'230"C3*,N4?4j#EK7"33;Q'P 84Eq*2 GHl^.4#"'&/32>54&#"&54632326=!5!# 65.#Y&_:&: M$B0d/6l8 C3wWt;Q' [p!H9!(# $<#$*9+KZ9D-GH33J.1%"#"'#7>54#"#".547#5!!;2?632"']  &02;-%';m-!74?>L-gV!? ;)T622S%7!?D4cS!I$=23#32654'7#"&54?654#!5!4#"#"&54732726E5g~2HH28,u#218#9+01S1'<[,1L3F31B % 4c"274'7&'#"&5463267&#"5 2  "(0M9<("/"& " $-"BA99:Q. $#"./&'73274#"3"5462%5!K*) "  -6 *>0F-$96G 4 3X'$;(:33.7&=47'6753S/c F@m1T d! 3f33.'6325#.'5#5!##5.#"#"'7326!)*03U/+4/"*)6% &9i;(33bA,4,Z 9 a.$6325.'5#5!##5.#"#"'7326`# #$I'o3)!("+ 0/gn+33<699I *Q.#632.#"#"'73267.'5#5!#!)/"*)6% &3U/b*09RA,4,Z 9;(338e #53'46;5!5!##"327#"'&eSS$g68z)5,A7_3DV{jMNOMmpIIL(/I#V*tGGe+#537356'7&'.676;5!5!##"_SS(2&;6LTv-  2Fl$ O%;#n5)1*iBZ . '?@M!2}II#H'"#'.>76"67#".6767'#5'%&'"'>765!5!!7'4322D!#+(:+ *0%!+M(!&88O1D *H+bOJ+QC?|B> '?W+;2Q2" g-&"=8/CH" )=ϛ9l&'7 RIBHH5J* -E$\'"#'.>7646;"32?&'&"67#".6767'#5'%&'"'>765!5!!7'4322D!#+(:+ *0%!*F8 A8(!&"hJ<+M(!&88O1D *H+bOJ+QC?|B> '?W+;2Q2" R8IG6% <# %T-&"=8/CH" )=ϛ9l&'7 RIBHH5J* -iF#53.67>'"&#"&'&6;5!5!##"7"632&/"'46362674&aa--"E2D,"%6* Z -p"ZJi"0d-UB",%+3)NZ6bU ;37#%7'7CC%-/F11E-3&MGMI2 # :+' (4I?1c>@r$3?A2%H CH*;>i< 7#LJ)#532653#&53#%7'7'"#'.>36CC%,/D31E-*?1c>D!#+(:+*0' @r$2?@2&Y7#i &>V,;3R2! %Kl##532653#&53.>36&'"7DD%!'/E21F- $w:&9*'4 #*(@r$2?A1 ZKq9# : )?V)e5'3'#"'&'&7.76;5!5!#!"632'674&#&~ WY &fC5 K&: 88";,=07X 7K6#6m7:5d`II ; 8('.! A e)=#53'3.67#5!#&'&54654&&75!"7"2USS W+9#Pi1-2.),#B# .!?Q|Z)O RapIIp4({_+3 -5PMOa# DqGtQ%27^HH!v#L / 44=.1JP;"R"0'> aW>G23275#53###"/3274'46.'.'&7.67632'6&'&6*SFeFGKNE0Ae *1 2@,.53!f*%2*= )585x%zHHO;O' *+ -.4 B-GD SB#5=S3&!W :###53!5!463!!"32?2'#"546327654#""&MIMEp/y@D!'5$a5{w&"-+!; 0!7kHHHH63, $X,tB.# rg ###53!5!.67#5!#"MIMBHT (5U8 GJH=yY?HH3)#x.Xg ###53!5!'%&'"'>76XNGMvR+bOJ+* GJHt9l&'7 Re2;46327?#5!##5&'.7'7''6?.74'&6dA58FG\S*#:'E:FG"aZ$)P"U&-0U8.$1089/C5J'?9;8+IEEHHm39]/UAx7'9 ,* ),(xe )4>3275#53##5'7''6?&74'&6w*27FG32&4'&6v AMFI/ ".&O=%5U-.V=*27FGd';J 2*9- 1Z"HHC6"Y/+)9 ,;7&29/C5EF+$3*, * e&#53'-326/5!5!5!###'&5 >>-"C =31*GG# :(`D8YaL7 qHHc(6./?e$,%'%"&'5#5!!>'>76&"#5'3275#C,!iKe)/X?19>E!R8.GG.;,78ց7!U@HH,1="oC.j/'&>""//e(07#53'%"&'5#5!!>'>76&"#5'3275#II5,!iKe)/X?19>E!R8.GG.;,78iE-7!U@HH,1="oC.j/'&>""//e%'%"&'5#5!##5'275#F-"lKe)GG)F;4;7!U@HH&G7"/e%-##'7&"#"'&/7=!5!25!6FG2dM A2 " D!1V[9 H<Cl75U $/0"S& 5U','/H24eoe,!6'>&'.#"'&/7=!5!o#RB-8/71* #C ?- "D!1V[9 H<oq$A%4X/1*L2 ,/S& 5U','0He3'&/7=!5!!3632'>74&'&.7BN"D!1V[9 H<z$9X F= / )%5I0S& 5U','/HHgw'"E0'M%0> |(e:7267!5!!>'>76&#&#5#"&54?.67672'."H$VJwC!P03GG% q@7- -DJ"0 0=*HH2#y/g1!+vM? A )b_$1 N  ;fiK###53#"&'&>32&'"67"&54?&'&5775#5!!#'67MGN7C;K"3)6JHZpR[; /(9'! 5W4$+& "!G1D8&8 E3*"&3?*$"; ", /HH* 3='A$\?  ?e #6"&'47%.547#5!##5#".5&7"67!;p%<D?FG=K:0G 8&DrD"#K)G>)OM? A5&HH # 0%9 ' ',$/I]e ,"&'47%47#5!#67675!5!##5&'&;p%CaW%:/D!-0]FG =R_$&7>*NM@1C;GGR+8HH.&!Ue+7267!5!#6&#&#5&'.>7672'."HFOl)3GG .DS$# -DJ"0 0=*HHn0X v  MB. 1 N  ;f*qe<#"&'&>32&'"67#".'&5775#5!!#'67q7C;K"3)6JHZ?7^@7#; /('! 5W4$+1D8&8 E3*"&<#4QJ0; ", /HH* 3='A$e#.4>735#5!L%28 9(8+Hye&"6767#".5&7.547#5!#; 80T48yM0G 7,*Dd"#K)B'TF 0%9. R!&HH$/Iye!5!47#5!#6767'&}CaW%:+@ 9$ a8&HC;GGR .I{D.!e +"&'47%326/5!5!5!###'&5p& =31*GG# :(`N=*NN?YaL7 qHH^(6./?s&e!5!326/5!#'&5, =31* # :(`HYaL7 H(6./?ze<72674&#"&'&6;5!5!##"7>32227"""'/"'46)L!.+p$\IP%4&`+.9N[0S6+ .^HHM'Qz+N?.PX1)Qe#!5!636327.''&'76&'&#"BG+*!$#3 p'2/V(;7 +3H$L aV0&9/KZ" (e &%"&'47%%463!5!5!###""'&Jr & .8 f(GG*$2?1L\y?)NM@ 1HfHHj7d=O4^s)e <"&'47%'2>75#53##5&'&'3254&'&37"'&6`r%R+8=eGG9;z\&]*-6**:\|)/ab-5?) OM@  8(HH/'""S@ x*4/Cr3@+0FOZ Ae 2"&'47%46;5!5!##"34'476#/".r%B4G)k^B+2_ Xz:?) OM@ =U^HH+ D=@30V<@&A>'Ch ;"&'47%#".5&7.76#54'&6;"75#53##p'~ei,@ 6G&10V=H'(6"8/Au`FGG=)OM? ].% 0322- D$$$=$DRqHHje #&=#5!26=#j#P;y]&]*-6*): [1H\ba-q3'#"R@ y)4/Cr1@bDO\ A+e1747&'&6;5!5!##"7272722&#&'"327#"&M"E23?("   # +=-,:YOETI(''=..THH 'J)%$%E&W'qh+#53#".5&7.76#54'&6;"67o--Jbo,@ 6G&10V=H'(6"8/_>Hnb.% 0322- D$$$=$DR6>e!5!463!##"&>>H iH&GV s.e7#53!5!463!##"&eek>H i.cH&GV sJe27#"&=#5!#>5*FKf6;;X*U@HH"/1e 7"&=#5!#632&#"#5'3275#Kf)GD/43G.;,78U@HH>L &/""//vXe!5!".'&672&>7'27'R(*^L2YDJd/ 8+&HD&K0Fa N},4s)e##534&'4>3#&'46;54#"11 .@F!^ (+0H' &6 0Ga p !2. "qe46;5#5!#3#&'& (\|<'0% HHGO&.:e67#"&'22676&'#5!#=6 7HY'>Q^~)4Cl'/W(+.d7v`,"1HH+e !"&'47%7"&'5#5!##5'275#r %Jf)GG)F;4;'@)NN?U@HH&G7"/e ,4"&'47%7"&'5#5!!>'>76&"#5'3275#r %Jf)/X?19>ES8.GG.;,785?) OM@ U@HH,1="oC.i1'&>""//e"!5!".'&676>7"'4>7&'"Zʏ4$JM9aKWA%<+)g A 1*+HH:=(Ac3E\G%Gj4!.+Fbe*5!5!>32'#"&'&63232>76&'".#">N'EQ @,[''^EQYEVO:*$0% H3(RV!/ H"/aR::$X\fTKh'L' <9#$)@jq5-be.9#53!5!>32'#"&'&63232>76&'".#">#bbN'EQ @,[''^EQYEVO:*$0% H3(RV!/ CYH"/aR::$X\fTKh'L' <9#$)@jq5-vXe!5!267".'&672'.3'R (*^L2YDJ"0 0=HW/U&K0Fa N  ;fe%#%72>7&'.67#5!&'"326V'4^50,.'N>#J:! _nC%(=1{dD24'B,J4 HHLK& $Je 7"&=#53#'327'Kf)u*;,<$ǥU@HH{*"/)e "'&/7=!5!#3#B#D"D1V[9 G<J*0S& 5U',&/HHGQe'3!!3&'&'4>7.5&63!5!5!#!"w+zC0F<5`h'))32"&'46?&/"'"#".#&}}]\#9,06 p%?$ */$H 9@;l8/oI D!21 e #)"&'4?##5.'&672&?!5!'r&FGQTZC Gd/ ȡbE>) wNE?b:`9Fa M} Hus;42e 5"&'47%4&'4>35#53###&'46;54#"p& .@E"eFG^ (,1 >( ~PI? ' &6 0HHa p 2.e $"&'47%46;5#5!###&%5#r & (\FH]\3@)NN?X HHOnGe -"&'4?##5.'&672'.>7!5!r&FGQTZC G"0  @:( E?) wNE?b:`9Fa M  >&  Hbg +4"&'47%.''?.67>5#53##4'&76>q&{ 4u.+5M+1d\MFG9.5?*NM@ Q H9Q!Q@ 'b5.HH&$' e:ER2675!5!!>'>76&#&#5'.6?.67672&#&%>.#&62675"'#G'^D`h #8EC!P.!4FG+;+ */? 7+6%37   4FE#G-N0%$HHo1WQr?+[,&ji+ + WF YF, F/$&/%;#j}Y$-b9ye\#533276&#""&'&6;5!5!##>32>#'2674'"#5#"&'&>&3275.'7xOO`1m=4t'Iyz&-'?&X> h-*&+7.49CG40:I,;A 7,1200aP41MKV NIS d+!^HH"$ 5?Q R "d 1(-9b*J*0)%4.A3 be;X#53%46;5!5!#!26#5#.5732=&/754#"#"&275'7.67632&#"NN6-,}' KBG(%5fB(A#:.ZkVc _-YLV] CU(%(  7K'SHH$%eP!/AZW$3X24E""]&c63 769 nxe59%'.'.>735&'774&#"&'&546;5!5!#!2632##53xa#%" :f(0gf ;$741Gki6T :#HOOq(  #0U.;6x0# 19+ZHHIsKmxe7J#53%46;5!5!#!2632#5#"'&'47.547/776'"&'&"3275#"';xOO=1Gki6 U ;"H|>E4$%."0ff";$74o<O~e9%4'5%5#"''77654'&'76323275!5!##5'732FP("~/Ua%e+0(,%3 O[.d5(/r7GH HHi+*4C81889e0E"34'476#'#"&747&546?&546;5!5!#32?3267'"'A(h`C#+J`%wDGB .f6'5B4sG>E-BGS& "7\-B Ex*!D=A*0o%JhO+!J:,T=U^HH< %*1<dS0f&e:747&'&6;5!5!##"7272722&#&'"7476'#"M"E23K("   # +=&&A&;?F(''=..THH 'J)#$G  0g#y(}eM"34'476#'.547"&5&6'&#"3>73267'".546;5!5!#O(i_B+ ')T^3* ;tk> > #m*!;;^. Xz:A6u<x*!D=@20"TY78+X>>C #&;!+KAeo &A>#767'".546;5!5!# (i_B+ 13Z&&&h ";",A# 0%7FXz;A6=KAx*!D=@20"TXQ_A )  a' /"3 2ua%&@>$f7* "=^HHi fe07"&547&'&6;5!5!##57##"672'&67FZJMMVGGMe -EF'%!;5'.676;5!5!##"7#"674/7'&)'91bQ1$#15,x'5\2A MSSSI<'9~QSFS%#5 A4OI&^HH#W;39++ + &<9(-8eH4>;5!5!##"674/7#"674/7'&54>;5"".)(;/h!%O6'9#%FSSSI<'9~QSFS'91DU:B%5 ^HHV ,&%:"9++ + &<9(-N#5 M Fnke5%'.'.>735&'774&#"&'&546;5!5!#!2632#xa#%" :f(0gf ;$741Gki6T :#Hq(  #0U.;6x0# 19+ZHHIs9VeQ3276&#""&'&6;5!5!##>32'?62#"'732676&#""&'&7&'7Y`1m=4t'IVW&-'?&PVNM8&&M31`1/?=4taC1B NIS d+!^HH"$ 57X"D5$4;) NI4,  f-8Y 9VeGP46;5!5!##?62#"&676#"&'&6;5#"&'732676&#""&>54'&.IVW4%M8&2Wc@".X@fM\TB#\R1`1:4=5u*1,XHH( 59(A1@ O :$0AqR6D'j\  NI$ N(% g=###53!3##"&'4?35#3.54>7&'&63!5!5!#!"MHT{(  \#B?Y5+A"B))7"'4?.I,6!bM9*2:7T=YK  $dB z(y)=A0S;I6#"U 6 &) > N4$!-!"?#66#4k4; +&/^H)4s8$:Y-@O@?_. heK&'.6767>5#!"636'676&'"#"'&'&7.676;5!5!_] )7.M1@6'2I,6!4I#:,298T;WL  %dA  /$- %02) '8  > *)% - "> "56#5j4; *'-^He.7##5'7&'"'67&#""#"'&/7=!5!!632FG5DZCJ[  A2 "D!1V[9 H<Dl鱉) J N$/0S& 5U','/HeVT+e;2>7&'&5467&/".546;5!5!##"34'476#"% '!gL#=U^HH+ D=@30P;6$  8e#5327"'&'515%J0D!A<HHEze!-!5!47#5!#6767&'&'"&%#67>cCzW'8+@ 9$763###536'.\H*-]E1MMHMO YPfMI< (JU$HH>8G"t\E#3335#6.'&3&676HOMHMMXK]  H' ,DeHHU_:S+!g'mI*3###536'.#.76&?>&#"}MMHMPY')6J$-(dV) C;0 6-AHH=7Hr. ,?B, ;Pi-3335#6.3&67>7'"#'.>WPMHMMgC/$ I& /C?D78 D $*)9,*/GCgEG\U&#x*i#%- %=W.;B`-4R.#5357&'&'76#.>763###536'.AA>(/1& P#8G"t\$y-#536757&'&'7#3335#6.'&3&676BBI( 02% P#OMHMMXK]  H' ,D"W^x#;F&YHHU_:S+!g'm9^&3###53.6?63켅SMHMK+)!NaCJFHH\d3%ag#4'&#3###53&676O83DSMHMK#?K9jnZT8f//?AHHF-7I9g#'$3###53.>76`t(! SMHMK :.fI`G=HH?B>:(X5>2327#"/3274'46.'&'&7.67632'6&'&6*TIONE0a22 +1 2A- .E^f*%1 %."0595(O =,('' )+ ,. /VIHDRB 1!8N3" e.!5!463!!"32?2'#"54632654#"".Ep&y>D!'a5{w&B g .!0O$HG5 4+j!X+tC /,#FL e!5!.67#5!#"BHT (5U8H=yY?HH3)#x.:e!5!'%&'"'>76vvR+bOJ+*Ht9m&'7 R#La&/46327?'.7'7''6?&74'&6J-8EG\S*!:(E931(OEU.7V<9+!18080B5J'@96<,KCjM-+Y4VAy6")9-:,)- +Ke"46327'7''6?.74'&6eA57GG<(ـHU.6U8. 10880C5j Q7^HH #v#L / 44=.=''%|-Gm8Kl#53/"#'.>36QQE #*(:+!,/' I< )?V);4S1 e17".'&7.'&3!5!5!#!"632'674''7&pw%19<-A,;=9*@ >?&U9A36&'":&9*'4 #*(KKq9# : )?V)!.#'#73^{aCҔ Q ###53'#532673#&'3MGN8YY1+5=]BB[<+(HV.*CTWA!, M '7###53[TZpMHM\T\H &7>&'"###53Ke\&0+"&6VMHMfI; @m:IH'?'"#'.>###53C&'"3###53654&#"#&eOJ=KP 4AMMHMOR=;3/N)0W,'* ; I>%HH >N1+;4 {/#534>32>&'"3###53654&#"#& QQ%K2J=0;<0AOOGMPR=;3/M)J)(0 ,'  ; I B%HH@L1+;4|Kt#53#'7``FK=[;|K(t'"#'.>36#'7(D!#*)9,+0%!tK=% &>W,;3R1"  ;|K*t#53/"#'.67>#'7*QQC!%*)9+ \%qK=K+ %=V.:+@>;LL #53#%7'7``Z?1c>[ޚ7#LL=#%7'7'"#'.67>H?1c>DC*:+ \%L7#i IS5+@=LL=#535"#'.>37#%7'7=bbI2 ) :+' (4I?1c>[4 Ca2?i;7#U.>36'"###53'73*+* )C-"&7MHM==Yh6Z:, ;>m=KH:,.67>&'"###53%7'73*/$\&5 $*)MHMB1d>|Re5^X ; &>W,HH7#LP $###5375'"#'.>37#%7'7MGM1RPI2 # :+' (4I?1c>HHLo CH*;>i< 7#7e&G#'#73##"327#".'&6;5!5!"'&/7=!5!#3#^{`Dx)3+5)^/BRy7K>+Z?,\#D"D!1V[9 H<UɓI(%=# S)r !2\:?vmH*0S& 5U','/HHGD ###537#53/"#'.>76#'7MHMPPD!#*(9,' -9!$"rK=HdI, &>W-;?_0 :(3!%!!(?(_g 1###53!5!4>32"&'46?&/"'"#".#&_NGM}]\#9,06 p%?$ */$ GJH 9@;l8/oI D!21  e5'3#53&6;5!5!##?2#".57276'""&WESS32>1O5+#:=!4lRB$3c4p" H6y!BO# `II;;I 4M'6MQ7.vop#8e '346;5!5!##"327#"'&p Vg68z)5,A7_3DV{jMN!MmpIIL(/I#V*tGGe+'3356'7&'.676;5!5!##"M VV(2&;6LTv-  2Fl$ !%;#n5)1*iBZ . '?@M!2}II#ce1'3&6;5!5!##?2#".57276'""& W{2>cY1O5+#:=!4lRB$3c4p" H6y!# `II;;I 4M'6MQ7.vope*3'34>;5!5!##"&'4636#"'&>74'& VA+m)2YM>4#5 #:=hSR>&2."7@,hII>.?i%/5A-%)= LLP)961%e*'346;5!5!##"34'476#/".WE4H!(F(,: b!In?' 4?W`II+!B(1e>B)93e07267!5!!>'>76&#&#5'7.67672'."H$VJwC!P03GG-8?(-DJ"0 0=*HH2#y/g1!+v9T^t,1 N  ;fzeB%'%1#"&/&5775#5!##=#"&'&>32&'"675!#'6l,7!9_7; /(GG4A;K"3)6JDW'! 5W4%-97cvI; ", /HH1,D8&8 E3(#ɘ* 3=';e%'%###.4>735#5!u,GG%28 98%(8+H?e-%'-.547#5!##5#".'&7"67!;-",*D?FG=K:.:*8&DrD"#K)i8 R!&HH # 8'9 ' ',$/I4{e 7#'#73#53".'776'""&'&6;5!5!##?2J^{_DPPL!:I:'%S6+ .^HH鎦9 !z+N?.PX1) 0ۥM e+%'-6363275!5!##5&''&'76&'&#",!hG+*!$FH"(,SzH'2/V(;7 +3n9$HHAW &9/KZ" 7,e&#'#73##"327#"'.676;5!5!^{`Ex"- ,A5^0ASxgL"!$/?,ɓ1./F"S)rF4Pc.>mH9e+#'#73"376'7&'.676;5!5!#^{`Er%0'0%85IQq.#$0EhǓK?"$:" i5(0(h@W-:PZ%2yHH-Ve3#'#737".'776'""&'&6;5!5!##?2K^{`C!:;5!5!##".676#"'&>74'& ]{aD?* k(2UM  &TDdOgPQ6(1+Ӕ5@-fHH=,=g7OE1APJKM#951Re%'%###&=#5!26=#-"GG}P76XNGMvR+bOJ+*HHHt9m&'7 R)e3%'%2>75#53##5&'&'3254&'&37"'&6,!+8=eGG9;z\&]*-6**:\|)/ab-8 8(HH/'""S@ x*4/Cr3@+0FOZ Ae*%'-46;5!5!##"34'476#/".e,B4G)k^B+2_ Xz:%9=U^HH+ D=@30V<@&A>h2%'%'#".6767.76#54'&6;"75#53##-"]p2GH%00V=H&, &*5"&)Dq^FH|8]*35#53###&'46;54&#"+!f .@F"eFH ^ '0 u8,&6 0HHa p .e%'-46;5#5!###&%5#p-" (\FH]\ɏ9E HHOnGe'%'-22676&'#5!##5#"&76?5#-!)4FI:P^~=6,;M&#'i8,"1HH3v/W&$+e7'?+'&/775!5!#,˪I6 "D!1V[9 H;L81A0S& 5U','0HHe(%'7".'&676675!5!##'4?&'"-}4$JM9aKWACD GG/^ A 1*+Hc9{ :=(Ac3E\GAxHHXp)!.+eAJ%4632''6?..'636326?654.#"&#64'&6EA58FGd`=HV-6U)+(48Y]6 %) 4#75.4*3 &*Y8-$1@089/C5E + $)9,*d$=&; ' R31# " ; %),3Kb-),( $i'.46;5!5!##"327#"'&'"&'5#53#'327'8Y@,w02*5G^1ARzgLL_Jf)u*<+>"=wnGGTo$1T)rFG U@GG{+#-)g$18"376'7&'.676;5!5!#"&'5#5%'327'%0'1%95JRs,"$.Gh3Jf) *;,<$_@"$:" h7%1)hAW,9O\&1zGGU@HG{*"/)7$h)07%46;5!5!##"327#"'&'"&'5#53#'327'#'#738Y@,w(3+A6]2ASygLL_Jf)u*;,<$^{`E?vnGGI(/G"S)qFG U@HH{*"/)QCg$18?"376'7&'.676;5!5!#"&'5#5%'327'#'#73%0'1%95JRs,"$.Gh3Jf) *;,<$^{_D_@"$:" h7%1)hAW,9O\&1zGGU@HG{*"/)]3e )&'5'5#3""&'&5&7637!5%5##*~7'[)2'@2 46 FG%!H')?" 1O6%"MHG.$e )&54?2''67"&'47%4'&6<"U3JG@CU./r &F9+ 0}:7>)5BB5i#d):?) OM@ *, * e$%26=3/5#"&54;57%3#";#3  &[&G5(rT[.1H "DI^8'/06 `4 e "%"&'4?!5!463!#""'&Op]% O.8*$2?1L\>)aO-? H1HG7d=O4^sEe/774>7&'&63!5!5!#!"!##&'&=3.5#6)B))#5'47&'&.67>635..54m2HT9F -(I_G;@ 1K39> /;"" az%gP/).*j2_^HH/ vX#/D+$M?/  8Y0V=Ee<74>7&'&63!5!5!#!"!#5#"&54;#"'"675#3.)B))3m=10"Uw1FT?.le&#'"&'&5&?63?&'3'55%3l  (: |1#."VL &* 5/NOEe3"&'4?!3.54>7&'&63!5!5!#!"!#5\rBs%53H B))7&'&63!5!5!#!"w(  \#B"0352H!B))5 AB !^HHNe%'%'27#"&=#5!#N.(u>5*FKf6;T;X*U@HH"/e5#53%#53&6;5!5!##?2#".57276'""&SSSS32>1O5+#:=!4lRB$3c4p" H6yOO# `II;;I 4M'6MQ7.vope5#537#"'&'&7.76;5!5!#!"632'674&#&mSSY &fC5 K&: 88";,=07XbO7K6#6m7:5d`II ; 8('.! Ae*#53'46;5!5!##"34'476#/".SSE4H!(F(,: b!In?' O?W`II+!B(1e>B)93#8e$#53'346;5!5!##"327#"'&eSS Vg68z)5,A7_3DV{jMNO!MmpIIL(/I#V*tGGe/#53'3356'7&'.676;5!5!##"USS VV(2&;6LTv-  2Fl$ O!%;#n5)1*iBZ . '?@M!2}II#ce5#53'3&6;5!5!##?2#".57276'""&SS W{2>cY1O5+#:=!4lRB$3c4p" H6yO!# `II;;I 4M'6MQ7.vope.7#53'34>;5!5!##"&'4636#"'&>74'&SS VA+m)2YM>4#5 #:=hSR>&2.2O"7@,hII>.?i%/5A-%)= LLP)961%e.#53'346;5!5!##"34'476#/".SSWE4H!(F(,: b!In?' O 4?W`II+!B(1e>B)93e9#53'3'#"'&'&7.76;5!5!#!"632'674&#&SS WY &fC5 K&: 88";,=07XlO 7K6#6m7:5d`II ; 8('.! A e 9#53'3#53&6;5!5!##?2#".57276'""&SS W`SS32>1O5+#:=!4lRB$3c4p" H6yO!BO# `II;;I 4M'6MQ7.vop$i+2'346;5!5!##"327#"'&'"&'5#53#'327' WY@,w02*5G^1ARzgLL_Jf)u*<+>"!=wnGGTo$1T)rFG U@GG{+#-)g(5<'3"376'7&'.676;5!5!#"&'5#5%'327' W_%0'1%95JRs,"$.Gh3Jf) *;,<$!s@"$:" h7%1)hAW,9O\&1zGGU@HG{*"/)Ee3;'3%4>7&'&63!5!5!#!"!##&'&=3.5#6 WB))7&'&63!5!5!#!"!#5 WrBs%53H B))#5'47&'&.67>635..54 W2HT9F -(I_G;@ 1K39> /;"" az%gP/).*j N2_^HH/ vX#/D+$M?/  8Y0V=Ee@'3%4>7&'&63!5!5!#!"!#5#"&54;#"'"675#3. WB))3m=10"Uw1FT?1e$7#537"&=#5!#632&#"#5'3275#eeKf)GD/43G.;,78.cCU@HH>L &/""//&e7#53!5!326/5!#'&5ee, =31* # :(`cHYaL7 H(6./?L)4>32&#"3!##"'73274&#'7&E!89!m5#73267#"&547.54632&#";#"u2:!8{7pS7#".'#732654+732k 69 j.wv21M* 8!*K9NO,?!eDh1&>!S'754'&'3265+".54632632&#"51k" BI'"' 5 .8&UDnh#3l(1 -PF5#G RY'"%.!_ "I1M^/QPE74"/73>54&#"#"'532>7'&#"7637632  3*,937#"327.!/:*7B}$pp-H(UD9$UUk)7"&54637654&#"#&54632&#7>7i-C8^)3-_2W?ZPTI%"F2*3q SaQ  G$/3*1A\=EQ4>`B%'7267'.547&547654';#"-R:Df`g~Z!H4|{JGMGoC KAB(5OK  ! )QJ&Gm'463!##".%&#"7>^E; ]J >;$BXL&ARR.5C7'&''7&{>Jb&8\%U%;<|Y%OF L)*- NI_$7= : 7G(#3 gl:6$ %+-F4726=33#'&54>32&'".9lrqoY/STC^7P* It &74354.'.54>323#"&V(#-,%PK"4FA!@uih6L@_<" /9--+C>a;&TB:U++0 HI4&#"56323##"&543x '5"|ih;+5-`>*!V qeU#(:%_%%267#"&=46;265&+732"&#"4w UXq ]!(AW8Dx(  "(\2d8{Y';RT=~  %#574632&#"32>7#"'&Vj)0$31315(]GGQ)h O $G16K$ U JM$"&54>32&#>546;&#"a.0  e2PMY2KU!tFf3 K )<*X^kj$)}]74632&+3267#".nY+, 53(W UU4=,PaM.9i+`= -O/#.'&+'32>7'&'767+.54>32m`5f~638. '1#P 1%(:I;G)%HE*6Tb g5(U S 9'#A (? >2.:'K,%"&5754+73'3267'Nn-T|-%9O,^5R#"'-"23##;#"/#73265.+5%0"j6b - %D/, 5%+NH_ R0R.!!(R&632&#";#"&".546776770&:[/$IcW~@$i;nU+/3Cb Q@$GP*DF$%DK=H \q34323#32?672'#"54>7654&#"#&dWtIFB ,?GLE6Fn",>;\#xG.K&)!K%;( 3 ]0}2>%&!#$".547#'!#"327<$DD2 vʐK@L\( +G.i1SSL4 2KV27'75.''4>)C& GM 5=,G,>I3#ZKuCq +5&U/9-1265'.54323265'.5467%&'&#"\5+4 B"+53n88/@b::'Lo+#,1/ WqK>c?,$ D.3 y '1<+f8$%= CE\"4632'%''7"&7"3654@cOPn[N4BQ$> Iy5GL4&#"5632#"'7326 '%'9BG 18D_-~BS&F<7;0H V $><#n3N8wRc)7"767'63.547.54>32&#";I+MPr*  ! S<%>>!d-*,H|?9 DeU: &A)8%$5 S6?N +3267'7.'#732>54+732k 69 p)t+X 8% K9NV,?!`4 SS) D>S :SL'46327#"'767''74&#"327#"H9Aw4;(\ 6qPx-$ld5FYS F'-6Ls,>//P*? +77>7'7&'4637654&##&54632&#sE3*4o )-C8^)3-_2W?75 SJ%"4>TFM  G#03 )1A!?,EP/';#"3267'7&=47.547654'y8|{JG5,4s`+<~Z(0(s$QJ&HfE5)aA)H(J %'463!##"& '%'.#"76[H; ^JdX9%!X'&6@PM-5BX}Jo,"H#27'7'7654&+7h9gv5ɓ +,/O2U[Hgy R326=33##"'4632&#"'%il/8lnmm]\I+-+NX8(z5)ISQYTf JP'+74354&'.54>323##"&'%V4',.OC1PR+6?+ih7'&>+;%_;' .:->z ,?Lp9?*:U),/ewEp J23##"&54354&#"56'%fE6ih;-5,`41 988fU#'9&^9)! V -eF]47265&+732"5'632'74.#"+;#".5'#5$1V?+3",>>B;.I2dQ n (5( RR0-HO>]i<; ;J] R R 72#"&54626546;#"#"'47&546;#";#" !'H9$a( {^EBNW85*(.&`)%t^:IW);&#"3674&+'32654&+532%,#'9[2! .LK( ,D?D~'XZ&%b1B> %!)#+5&DEa/Z;L@L$+T' QJ5h0"GU @2#"&5464+532#"&54632#4'&#"3267'&+'32!!#G`0A9^֍nLS^&HF*9%7H 3XVG,&,$-g?QJ59FcFVdPCj`G:EM!?, #,& ,R?H&5432&"72#"&'73265&'#"&'73254''7&'7>32.#"KR?&r&< ~X1n8W)$0b[fi=r Mc*^SCN;f B`1,@aM "Ge%&R 4+#M. E=R9;*=BW16I15#5P='.+%2654&''7'7"&54>32&#"%2#"&'71>2RAbZ754'&#"2?+"&UC6kD+chie*EO-'"  <]>M^',.u %Z R[2)& __0D73265#"&'7>754'&'327"&54>3273#".53f 1W6g ! W.7" @I( 8ZL A.Wq$qSbO{J/hY2B6&pXJ b.UF:)< MW @ I @F+-/>VJX)?TQ*'46327#"'767''74&#"327#"H9Aw4;(\ 6qPx-$ld5FYS F'-6Ls,>//P*? @%2>54''7&#"#"'532>7'.#"763>32653#"'5"-H*"K9;T*=."3 5-.<'$6;'&-t'F!B-%,%4="9"6]HKV'&;.@BRW H 8 Cy#CA( R FC"&5467654'#"&54>7654.'"76;"267#";267zkbfg &y'{m3$+% B765.#"76;3272>54.##l+e#HYA=1?(Xk"A?[8M3H2:@%Uk  b5Nn5/3' 97! *D=2D@A1(5 8%i! Q8 'P:1 '3JO     "!G2CS47&#"#"'#".5463&'67&5463&2654./32=4./"IQ-!6Si2gJ$ l1PP*Fh4]&  uH! HK-)E#6 Dd\C$%K *.[I)g**  c(; ,,,< 2F)9" 4!,? #FP".5467&'73767'.#&'7632&#"#"'+.'732654#"*L@ 211o2MU'3IIG*G'bA "7]<73>.=?$n?+51=4cJ3-#"H3 ' bUO  :"%  #BQ1J#,FJ4#"#"'7>72.#"32#"32?&5432#"&54325&'&'7326S 5 (M2s ^hnhZ& OQIHL=9KGidGf0n4[D0_  L* ?() #,,!(  RAyPC{  BH1L37&54>367'.#3327&54;'&'#',*=#6&f)TD 4J6%'+.5467"&54>32&+;#"7674&5472 NZ<'$ ^y((=*S:m08 , *B$ I#'A7y' gTK:*-* S; I=#"D S)HO73267".54?654;7632#'&/#"&5467#".467327"&+*i .4'Q%# k'rL:J N-%5B W' >Co1YV +5%<.;*O ,, =#1I(G) )*(' Q(9,N2"+>1d+HNGN7< 8LI <54-<>@\4%&'#"&547327.54?65&/33274632NB')Q1\aN?2L>w *HG*g6e(AQp &2U,4~T) фyYn5645=JS!C.q( (:D;27c50"3%2#"'#'&'732>7'&''7'7&54632&5l% /bzbiHCT[219 )]Sj NKX.`E 'XT2GL{3@* ,$s0W3b@*BJ5%4#";!"/#53265&+7!2632#"/3532kp(!/gK - (U/;j7Y/4 97!K>?++[ R0R,$LR:?!1`BNUO e=3632&'#327#".'#;!"&/#53265&+72;(@$tJr/PK@!  !)(2&N3iN (T/<k?)Nu/  E 8&([  RR,$LR2,%2#73267'.+532654&+5>;8GDPNSZV-"".1:g.u cp 6I4)CzG9[;(U%&V H?! 277>7'7.5467&+9E&9 ,3 iV04341 ZS= $C*Q]M.[(4%2>5#"&'7>7''7"&54>32#76732654#"(c>xiFT <X.W?M-WtlR70-(GP#/<9@{`=6#$> 9fZ;D'*5H<$C1K+O--:",b#+"327#"&547&54672.#"#5'7.?.2v4^n=WTD39Bh7 <Lz>*65N b\Q sA%#"&546354#"327#"&54>7"&56732&#";233#5#>61'0-%;= A"$C!B.8 17)@[%E' oo$!7")2$4L'Wv6++ ,`J*$! J&$ koO472&#"#32327653#'#"&546;254+27#".54>3.jd 68 '#$TV,83#@;.mm]1Mb3L_FRg`= "0X[C*+;3UJ G*& !2( (i$]I#,*YG^oH'=fA7]4*I" <2654&#"'&/#67#"&54?''7&54>32E% =!B= Hp]15L?ARpƨBd%M36P%c$%2.!' -6$1K#4P6I!,B U>_+M6YT.9@ $)!0&3 !74'37>'2%'7"&54>327#"&''%oP :1YZq$% .WAMfIKc{ "$*).BU"D9+ $I<#^BfZ;D'*5&-n <7PTGG2#"'54>7#"'4>7654'726?23276323276grK)@.<CJf ,j+(%?$FB(=Ma9+ tu=X9* &D#,, (;! F (!)  -!&ZB (( 2&Zn[:432353##32?672'#"54>7654.#"#&eUmmtHFA!+?HLE XG$ޱJu+*!;U U'U7265'.543253#53265'.5467%&'&#"R5+4 A"+53q6oo:V-;9'Ll,!-1/ YqJ@a=,$ D.3  1;+f 9&%= CG\ !"365446323#5'%''7"&%> IdMQlZllN3AM+!6.H69CL4&#"5632#"'7326#5'%3'9BG 18D_-~BS&F<7n;2m0H V $><#n3N8OSRIq#-7"7673#5'63.547.54>32&#";J+KQmmr* !!S<&=?!c,*,J|?: C7lU: %A)8%$5 S6?N5%#5'7.'#732654+532+326735n)u"0%7")K9N!69qm(pS)7$S&8SM@+>`2 E'/77>73#5'7&'4637654&##&54632&#jE3*&z oo)-D8^)4-`1W@66 TJ##5;&FM G#03*1A!?,FO+/+;#"32673#5'7&=47.547654'o5|{JG5+np3q_+;} X(0(s*QJ&F%~E5)aA)F*I  %@ #%&#"7>%463!53#5'%5##"&FW&& [H:nn:!]LcYNH# APf[I!33CU273#5'7'56'4+7^8fxoo6ʏ,,.N1ZIfz R!326=3353#5'%5##"'4632&#"/32353#5'%5#"&T3&)3 0PC1PS+5?.imm;%h8L=d;' M>?z ,>Lo9?+:_xEpg),-!2353#5'%5##"&54354&#"56]E6ioo:i;-4,_4288f>eF]j#&8'^9* V 47265&+5326323#7'7.#"+;#"/#5%1U>,3!*4#@ln;5,2cQ n/ (4'!RR03+O]iD  ;J] R0R77>73#5'7.467&+w:C'9 mm-SKiU13441 0~S>V_ M+ 932654#"#5#"&'7>7''7"&54>32#76732673GP#/<n;d,DU BX/W?M-WthR7 +,(< nC-:",P&'>5#(<9fZ;D'*5H^,M6YT.;?1!#!( H$4 $%3/!'.6'%*'4%3275%'7"&5463253#5#"&''%74'37>IIJc|-XfTXs%%mmbDU!C@Q :6%-BfZ;E&3=J;#aq=6PT9+%m''%L-Gd9G2#"&'73>54#"'6'&5467>7'.#3327&54;'&'#'KIZ[HBk86S4&'F(#55clHC3g)4B#'=yMUP +] )2XG;H9<7])5!(7+(G 0&9 " %$"5 & "*!57673736732632'"3#. #  "D2 .:((z *# : 9&H4E5"#53'"3#'.'76737672632QQY19+  &II5& -:%$*  :L@#'#73^{`D3.=E"#".5467&'>72&3265'.'"&5754+73'3267'eX\ '1`A?`7" Z25nZA*(S@)LMA-Ri-V{&,8OC!"(9 =;$$2.>S(@K X6A;+#^5R#-.&5=3267#".54>54&#"7632"&5754+73'3267'"*54&#"7632"&5754+73'3267'^{`E72&32>5'.'"&5754+73'3267' ]{`EX;O\'-JJ'?`6# W54nZ?,'RA11FH-Pj-Wz2 8P쓓D "(:5N'$3.>P(AKX6A2%^5R#(#/#.74676?'"3#3Q#(   () D0 "on.@$ ; 5&.,!57673736732632'"3#. #  "D2 .:((z *# : 9& H4E.#'#734&#"76323267#".54>^{`D*92?-I$@?%;TT;h0d8wV(KJ-=WX=퓓 a :'-70':G%Z#>'N6*= "[T3#32.''#"&563232>7'.'&54Ton+"!*@D5EW*\L] 0LT6  * Dk"= (`%$:Z3,2I4    @4&'&#"#%38xn07 N#BS )~%-#'#73'3265'.'&=472&#"#"'&']{`E k1:N Kz(=<4.Bd^#//LN)iV:퓓آH1' "'7[< +!)45N'8%)5#'#734672&#"#".5467&52654&'"^{aCp^@-(FWFSS7.KM(6V9' [47)OFhIT퓓CL[C G57O(#,'AS%:.#4;'6C3#'#73".54>54#"7633274>32^{aC(>_6! >XY>l4A/Kvc=XW=>/ 2${Md퓓&61.@ !2gS90:)$.9)+`%9  !2#"&4"#4>32'.s4$#1E n6jIGvJ+ if" "67 85.SO/$94(. "4.#"#4>32632&#"&#$WMC w(* T6:+!>H4#/5y O .&[ ,2#"44>32632&#".#"#.- !5^>XLC w( ) S3e>-C nT *T!?G4#/5y O 0$[0B3*>2% 2#".5464&'&#"#%3"-+7yn.; M+! BS )~$".#"#4>3 632&FNI|ro '?oIv$T"O1B3!?G4#y O )2"47".#"#4>3 632&\GMI|r8S*o '?oIv$T*T8T"O2A4 59!?G4#y O 44.#"#&=632632&#"#N 4": UW)g ?54'" XRBV8T<;JC4IV)96( i=x)' 'L; ' <2654+'767+&'71E= 9&%/,-BhM`A,0)8 ;0-8=9514>324.'#;65'.1CQ-=mF*L+_80/; B# [/+01>.E94JN/ > 4T267#".5432#"2>#q ,v6=Y-D*N ,-t(q# 4632#"&#3Y'"!#2^e#)%`"#324&5432&!05Qڑ[*a'0"D m j P^!"#324&5432&2"4!!05PْY*Za'0"D m j P8 *TV= 2#"&546'7#%7#')1qe[N0&&%#E["#%7'7>;)!<[Nrd/"Gm1pE#6&LX! 4632#"&7"#%7'7>;="..""*W#A&<01^-u&"-+*"-Y<K&'#".533275432&#"{4 524^\$#?$%*!-^D} 6b2*#K&'#".533275432&#"{4 524^\$#?$%*!-^D} 6b2*#%!5!^72#".5464&#"326.;& . @p %()2>+- & /;j2)<'"%!5!=©^5B 62#"&5464>32&#"3%#"/732654&#'7"&'"#'$,#9;#n 9Cklj"I0Lg:&*32'"M+2>;g[)1"V>UkJ 92#"&546#34&#"5632#".54'7326h&,($*hh9CL->u9  .Q22" WB'9<*'1+1N X 9$:)<.! " ?LJ9 32#"&546%#33267#"&547.54632&#";#")1)"6qp52;"=~z;qU=nYe/*/L~}K')%"3'! <j-[JA*:':HV8@Q!F ?2#"&5462#"&5463265'.'&=472&#"#"&'( 5,"%-$j j2:N My'>:6/Bc=Pb/.LN*<)P( # "%).)!+G2& #'7\<')45N';<lB 82#"&54%#3#"';267#".'#73267'&/#732I>' &$$qp#:7k /z{7$>)$8 *9P)" 1 0D fGj3*3 U#  TN4Y <H2#"&546'47"&54>;#";#"27#"'4672#".32654&#"( '$5fX#G'! J<#I&)?TAM).S\PyQp!#!-(=*" 1(!G/D3"5 T5#X.Y~Og;=v pV]Q@31)0 872#"&54627+.5467'."3265#".546(')",$1gE-L #>*49*#y<(, -/:(WB*)1*7'.#"7636321 '$5XuCC 66".4*+ ;;W*@.&6 6.-A%6AB"'" 1'"G2O6jHf0YWE8F&7_JMW&(>-@FSX*Fa +2#"&546%#3%3##"&'7327'.#"'6&1($*po5gyjk{M*r )P N-L"=+*&!2+ lQ]#_S:[ /&0;[ 12#"&5464&#"7633267#".54>)205+:2B-Ko^.c9wX*NK->YZ>R+&!(&# dQ8-:2'XE*\&>)Q7+>"" -:2#"&5464672&#"#".5467&52>54&'"' %,,4o_@-(FV FSR7-KM)@b8# X7724HfJTW)2))AMZD F57O($4/AR'3:'7C  22#"&546'3265'.'&=472&#"#"'&''0'$*: j2:N Lz'=<4/Ad^#/.LN*jU9Q)$#2+G2&!"'7\=+!)45N'7$ 52#"&5467 54>54#"7633274>32(!$)"5x>XY>l2C/Kvc,BMB,>/'%{Hcb*31'!9.@ !3 gS8)7(.9(7 `#8d (82#"&54%#3%#"'53674&#""76"&533267c>& '$-poE_$H1#&(M,$ %%jsM=(Xt`*" 1n`P 99!Oc*7Rԅe=&;FZ-*11 );ESS+5G>!QK"$ *72#".546#3".=4+7323767W')  +rp+E&&[<%# (CI&)>' " (MO$,! T-0!  Y 4C ?2#"&5464>32&#"3%2#"'#'&'7;>7'&''7&d&')"* 553b!>9>& 6g|fkKCWb" ._ Q>*)1*,  J( 'ZU.HO~5A"'59e 172#"&546#326=33#'&54>32&#"|&()"*4poF/:osr +M0311'$5kqom8@,lj(dU'%8().%R M#6GC1"'%"2(!\! A*:X  k\=" 48K/,A?c<' (72#"&546#34&#"56323##"&543O' )",qp"&=kj;.8+b!)" 1*H, X rjV$ &;&`+ 972#"&546#3267#".=46;2654+532"&#"N& )"*qp4wW\:PA. `+EX9G|& ",)" 1)A}3f9 ,P3';TU> W +2#"&546265&+7!2;!"./#5>)'/4.>lIeV;K'W*-'(!-%NT\D&H!] U TN 12#"&546%#3#572>7#".54632&#"[(,54popΣ6*7E9's*1"5342#)>(#$'!R W&9a32&'3654r)"$'$6rNgs %! 2QV~ ?+( )2(X*11'" VHm"45V]_8l+QO1 R ^6E`k (2#"&546#3267#".54672&#}& )"*po([ VYA\,kX4.*55)" 1)+b?+GD%Q_N,;lwK :72#"&546#3"27+.54>32#.'&+'32>74&R2165poh+'1(;L5/<fX z%0< V <*91 %72#"&546#3"&5754+73'3267'h()'$5qpUn. V4:Q.*<)2&"UO`6T$(".pM 332#"&54>#3!23##;#"/#7326=4&+5''!* %Mpo&1#m S=. 'F1, *..  # 7&-N5a T1U,!*U# @2#"&5467"&547&54;.'""&=7654&#";27s& "$65̋ O+@-.Oy#=WVWC$5YB?L cIxMON34"%&"w3$SP %@H6 Q  !%.B;)8R7\( ,'%"76;#"'5367'."&533267 >%!)MT#G0"&%M%%hpK<(YqWvQgG88#M_ *,c3@T Y 5!1#3'%"76;#"'5367'."&5332675pon=F%")LU %>'!&%M& pqK;(Zf@>WPhG+0$Ma,-`3?V Y#"&#&54667 .P u5!1.9 E=3#"&5432#W,!;-6BkR<$L4(5Di/E Z#"&'6532=35!5!## D"+7#.)gdAV&B %MAA1|".'#"54632353'32=!/  <1B (G2*)3x.@*H4@x#"&'>753"&#"32>72F.&4qN-(ZA;%\+?J)&9-8\T!1>u$#".54232>54&#"5432767 1"%;.S(d$).kF )0DA,K<$% 2!"@$fZ5654&#"&'&>753&8 i<=20==O 8!& 5nY)!"!<106O '.'3",1;+u , yl&#"&#&54632675! @> t5!1- 8 12-5 P9% ( G;;Be "&'5327%7>=3#"&5432PcSVbfRZ\X+";O2CjR%$2)((C2)LAi/D gc #.'5327'"&547332>+Du_2$fQZ]3P    8)(Wf+)=&6 $N'&z'.'35!"-*P#MLk+Y&6655!5!#"&#&546326788v @> t5!1- 11l0012-5 P9% ( GR2 5!5!7>=3#"&5432VeeO4!;P1HeR11p11nK2*dhLBo$E @"#"&54632#"5464'&1B! &'&#"#"&54632327'7.54675!5!!5>54&#"cOT]h]>4  (-/  3@JKAXZT]M ! |^_| ! ,(zBMl**=! 9#")@ +"3/@),KJ" 8CC$8"NAAO#9%@45Jfq?455X'=k@ =G[#"'5327'4&##3263>7%4>32!!#"&/47#5!.#"%"&547332654'3@kL[]cVX^8Z,kaA6FzajJ" &=kFTv8BLEt'L4OG^v7R/ BUI.5BV((A('7[5!WYA%EO9&5ZW2AZn"Dk65 в$Ajn+=5KX=J;@3  BW &GQe#"'53275#"'5327'4&##3263>7%4>32!!#"&/47#5!.#"%"&547332654'34iYP\cUX^lLY]cUX^,Z,kaA6FzajJ" &=kFTv8BLEt'L4OG^v7R/ BUI.5BV''A('V((A('7[5!WYA%EO9&5ZW2AZn"Dk65 в$Ajn+=5KX=J;@3  BW DO"&547332654'34&#"#7>!2"'"!!#"&'&7#53>7{BUI.5BWBY-!fKE7E@Ctlp\=Z5%WMFv'L5DxJ[J0X=J;@3  CV8[4 4*H8*AXo#Ej64 ϳJtAA/F(50NC&Ija'jfL&Mjc&Nj&Oj+&Qji&Rj&Sjo&Tj\&Vj&Wjl&Xj[&Yj&Zj&[j&\jZ&]j}&_jzz&`jE&aj&bjtx&cj&fjgt&ijXh&?j/##j4"?kt'j<&l'j]&mi@'jz&n'jz&o'j]&ph'j,&?qM&Gjzh'j,&?sSX'=&?k@|53 @AA`M $#".'.'&6;53#";#325!$1.%-#,5& ?V !,  -1Y#(W//`4-5!5!327#".'&/.>76;53#";vQQ>%1 ,5% ''Z''W  ",  &% E#(K#"&#&54667'7 Dv55U,45 @./Q4 )% Vk_B76=3#"&5432'7N3?:O3>gJ%r45p @K|{D9X-=  `60('7'32727".'.'&6;53#";035? <*  .#.",5"LuW  ,"J#)&3h% R FV$,f f    J > 4\   H X $$ $H+$TuCopyleft 2002, 2003, 2005 Free Software Foundation.Copyleft 2002, 2003, 2005 Free Software Foundation.FreeSansFreeSansMediumMediumFontForge 1.0 : Free Sans : 16-8-2006FontForge 1.0 : Free Sans : 16-8-2006Free SansFree SansVersion $Revision: 1.79 $ Version $Revision: 1.4 $ FreeSansFreeSansThe use of this font is granted subject to GNU General Public License.The use of this font is granted subject to GNU General Public License.http://www.gnu.org/copyleft/gpl.htmlhttp://www.gnu.org/copyleft/gpl.htmlThe quick brown fox jumps over the lazy dog.The quick brown fox jumps over the lazy dog.navadnoDovoljena je uporaba v skladu z licenco GNU General Public License.http://www.gnu.org/copyleft/gpl.html`erif bo za vajo spet kuhal doma e ~gance.i2  !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghjikmlnoqprsutvwxzy{}|~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                           ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~                            ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~        !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~glyph2glyph3 softhyphenAmacronamacronAbreveabreveAogonekaogonek Ccircumflex ccircumflex Cdotaccent cdotaccentDcarondcaronDcroatEmacronemacronEbreveebreve Edotaccent edotaccentEogonekeogonekEcaronecaron Gcircumflex gcircumflex Gdotaccent gdotaccent Gcommaaccent gcommaaccent Hcircumflex hcircumflexHbarhbarItildeitildeImacronimacronIbreveibreveIogonekiogonekIJij Jcircumflex jcircumflex Kcommaaccent kcommaaccent kgreenlandicLacutelacute Lcommaaccent lcommaaccentLcaronlcaronLdotldotNacutenacute Ncommaaccent ncommaaccentNcaronncaron napostropheEngengOmacronomacronObreveobreve Ohungarumlaut ohungarumlautRacuteracute Rcommaaccent rcommaaccentRcaronrcaronSacutesacute Scircumflex scircumflexuni0162uni0163TcarontcaronTbartbarUtildeutildeUmacronumacronUbreveubreveUringuring Uhungarumlaut uhungarumlautUogonekuogonek Wcircumflex wcircumflex Ycircumflex ycircumflexZacutezacute Zdotaccent zdotaccentlongsuni0180uni0181uni0182uni0183uni0184uni0185uni0186uni0187uni0188uni0189uni018Auni018Buni018Cuni018Duni018Euni018Funi0190uni0191uni0193uni0194uni0195uni0196uni0197uni0198uni0199uni019Auni019Buni019Cuni019Duni019Euni019FOhornohornuni01A2uni01A3uni01A4uni01A5uni01A6uni01A7uni01A8uni01A9uni01AAuni01ABuni01ACuni01ADuni01AEUhornuhornuni01B1uni01B2uni01B3uni01B4uni01B5uni01B6uni01B7uni01B8uni01B9uni01BAuni01BBuni01BEuni01BFuni01C0uni01C1uni01C2uni01C3uni01C4uni01C5uni01C6uni01C7uni01C8uni01C9uni01CAuni01CBuni01CCuni01CDuni01CEuni01CFuni01D0uni01D1uni01D2uni01D3uni01D4uni01D5uni01D6uni01D7uni01D8uni01D9uni01DAuni01DBuni01DCuni01DDuni01DEuni01DFuni01E0uni01E1uni01E2uni01E3uni01E4uni01E5Gcarongcaronuni01E8uni01E9uni01EAuni01EBuni01ECuni01EDuni01EEuni01EFuni01F0uni01F1uni01F2uni01F3uni01F4uni01F5uni01F8uni01F9 Aringacute aringacuteAEacuteaeacute Oslashacute oslashacuteuni0200uni0201uni0202uni0203uni0204uni0205uni0206uni0207uni0208uni0209uni020Auni020Buni020Cuni020Duni020Euni020Funi0210uni0211uni0212uni0213uni0214uni0215uni0216uni0217 Scommaaccent scommaaccent Tcommaaccent tcommaaccentuni021Euni021Funi0224uni0225uni0226uni0227uni0228uni0229uni022Auni022Buni022Cuni022Duni022Euni022Funi0230uni0231uni0232uni0233uni0250uni0251uni0252uni0253uni0254uni0255uni0256uni0257uni0258uni0259uni025Buni025Cuni025Euni025Funi0260uni0261uni0262uni0263uni0264uni0265uni0266uni0267uni0268uni0269uni026Auni026Duni026Euni026Funi0270uni0271uni0272uni0273uni0274uni0275uni0276uni0277uni0278uni0279uni027Auni027Buni027Cuni027Duni027Euni027Funi0280uni0281uni0282uni0283uni0284uni0285uni0286uni0287uni0288uni0289uni028Auni028Buni028Cuni028Duni028Euni028Funi0290uni0291uni0292uni0294uni0295uni0296uni0297uni0298uni0299uni029Auni029Buni029Cuni029Duni029Euni029Funi02A0uni02A1uni02A2uni02A3uni02A4uni02A5uni02BEuni02BFuni02C9uni02CAuni02CBuni02D2uni02D3 gravecomb acutecombuni0302 tildecombuni0304uni0305uni0306uni0307uni0308 hookabovecombuni030Auni030Buni030Cuni030Duni030Euni030Funi0310uni0311uni0312uni0313uni0314uni0315uni0316uni0317uni0318uni0319uni031Auni031Buni031Cuni031Duni031Euni031Funi0320uni0322 dotbelowcombuni0324uni0325uni0326uni0327uni0328uni0329uni032Auni032Buni032Cuni032Duni032Euni032Funi0330uni0331uni0332uni0333uni0339uni033Auni033Buni033Cuni033Duni033Euni0351uni0357uni0361uni0374uni0375uni037Auni037Etonos dieresistonos Alphatonos anoteleia EpsilontonosEtatonos Iotatonos Omicrontonos Upsilontonos OmegatonosiotadieresistonosAlphaBetaGammauni0394EpsilonZetaEtaThetaIotaKappaLambdaMuNuXiOmicronPiRhoSigmaTauUpsilonPhiChiPsiuni03A9 IotadieresisUpsilondieresis alphatonos epsilontonosetatonos iotatonosupsilondieresistonosalphabetagammadeltaepsilonzetaetathetaiotakappalambdauni03BCnuxiomicronrhosigma1sigmatauupsilonphichipsiomega iotadieresisupsilondieresis omicrontonos upsilontonos omegatonosphi1uni03D7uni03F0uni0400 afii10023 afii10051 afii10052 afii10053 afii10054 afii10055 afii10056 afii10057 afii10058 afii10059 afii10060 afii10061uni040D afii10062 afii10145 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097uni0450 afii10071 afii10099 afii10100 afii10101 afii10102 afii10103 afii10104 afii10105 afii10106 afii10107 afii10108 afii10109uni045D afii10110 afii10193 afii10147 afii10195uni048Cuni048Duni048Euni048F afii10050 afii10098uni0492uni0493uni0494uni0495uni0496uni0497uni0498uni0499uni049Auni049Buni049Cuni049Duni049Euni049Funi04A0uni04A1uni04A2uni04A3uni04A4uni04A5uni04A6uni04A7uni04AAuni04ABuni04ACuni04ADuni04AEuni04AFuni04B0uni04B1uni04B2uni04B3uni04B4uni04B5uni04B6uni04B7uni04B8uni04B9uni04BAuni04BBuni04BCuni04BDuni04BEuni04BFuni04C0uni04C1uni04C2uni04C3uni04C4uni04C5uni04C6uni04C7uni04C8uni04C9uni04CAuni04CBuni04CCuni04CDuni04CEuni04D0uni04D1uni04D2uni04D3uni04D4uni04D5uni04D6uni04D7uni04D8 afii10846uni04DAuni04DBuni04DCuni04DDuni04DEuni04DFuni04E0uni04E1uni04E2uni04E3uni04E4uni04E5uni04E6uni04E7uni04E8uni04E9uni04EAuni04EBuni04ECuni04EDuni04EEuni04EFuni04F0uni04F1uni04F2uni04F3uni04F4uni04F5uni04F8uni04F9uni0531uni0532uni0533uni0534uni0535uni0536uni0537uni0538uni0539uni053Auni053Buni053Cuni053Duni053Euni053Funi0540uni0541uni0542uni0543uni0544uni0545uni0546uni0547uni0548uni0549uni054Auni054Buni054Cuni054Duni054Euni054Funi0550uni0551uni0552uni0553uni0554uni0555uni0556uni0559uni055Auni055Buni055Cuni055Duni055Euni055Funi0561uni0562uni0563uni0564uni0565uni0566uni0567uni0568uni0569uni056Auni056Buni056Cuni056Duni056Euni056Funi0570uni0571uni0572uni0573uni0574uni0575uni0576uni0577uni0578uni0579uni057Auni057Buni057Cuni057Duni057Euni057Funi0580uni0581uni0582uni0583uni0584uni0585uni0586uni0587uni0589uni058A afii57799 afii57801 afii57800 afii57802 afii57793 afii57794 afii57795 afii57798 afii57797 afii57806 afii57796 afii57807 afii57839 afii57645 afii57841 afii57842 afii57804 afii57803 afii57658uni05C4 afii57664 afii57665 afii57666 afii57667 afii57668 afii57669 afii57670 afii57671 afii57672 afii57673 afii57674 afii57675 afii57676 afii57677 afii57678 afii57679 afii57680 afii57681 afii57682 afii57683 afii57684 afii57685 afii57686 afii57687 afii57688 afii57689 afii57690uni0700uni0701uni0702uni0703uni0704uni0705uni0706uni0707uni0708uni0709uni070Auni070Buni070Cuni070Duni0710uni0711uni0712uni0713uni0714uni0715uni0716uni0717uni0718uni0719uni071Auni071Buni071Cuni071Duni071Euni071Funi0720uni0721uni0722uni0723uni0724uni0725uni0726uni0727uni0728uni0729uni072Auni072Buni072Cuni0730uni0731uni0732uni0733uni0734uni0735uni0736uni0737uni0738uni0739uni073Auni073Buni073Cuni073Duni073Euni073Funi0740uni0741uni0742uni0743uni0744uni0745uni0746uni0747uni0748uni0749uni074Auni0901uni0902uni0903uni0904uni0905uni0906uni0907uni0908uni0909uni090Auni090Buni090Cuni090Duni090Euni090Funi0910uni0911uni0912uni0913uni0914uni0915uni0916uni0917uni0918uni0919uni091Auni091Buni091Cuni091Duni091Euni091Funi0920uni0921uni0922uni0923uni0924uni0925uni0926uni0927uni0928uni0929uni092Auni092Buni092Cuni092Duni092Euni092Funi0930uni0931uni0932uni0933uni0934uni0935uni0936uni0937uni0938uni0939uni093Buni093Cuni093Duni093Euni093Funi0940uni0941uni0942uni0943uni0944uni0945uni0946uni0947uni0948uni0949uni094Auni094Buni094Cuni094Duni094Funi0950uni0951uni0952uni0953uni0954uni0955uni0958uni0959uni095Auni095Buni095Cuni095Duni095Euni095Funi0960uni0961uni0962uni0963uni0964uni0965uni0966uni0967uni0968uni0969uni096Auni096Buni096Cuni096Duni096Euni096Funi0970uni0971uni0972uni0973uni0974uni0975uni0976bn_candrabindu bn_anusvara bn_visargabn_abn_aabn_ibn_iibn_ubn_uubn_ribn_libn_ebn_aibn_obn_aubn_kabn_khabn_gabn_ghabn_ngabn_cabn_chabn_jabn_jhabn_nyabn_ttabn_tthabn_ddabn_ddhabn_nnabn_tabn_thabn_dabn_dhabn_nabn_pabn_phabn_babn_bhabn_mabn_yabn_rabn_labn_shabn_ssabn_sabn_habn_nukta bn_avagraha bn_aakaarbn_ikaar bn_iikaarbn_ukaar bn_uukaar bn_rikaar bn_rrikaarbn_ekaar bn_aikaarbn_okaar bn_aukaar bn_hasanta bn_half_ta bn_aumarkbn_rrabn_rhabn_yyabn_rribn_lli bn_likaar bn_llikaarbn_zerobn_onebn_twobn_threebn_fourbn_fivebn_sixbn_sevenbn_eightbn_nine bn_asamira bn_asamiba bn_rupeemark bn_rupeesign bn_currency1 bn_currency2 bn_currency3 bn_currency4bn_currencyless bn_currency16 bn_issharuni0A01uni0A02uni0A03uni0A05uni0A06uni0A07uni0A08uni0A09uni0A0Auni0A0Funi0A10uni0A13uni0A14uni0A15uni0A16uni0A17uni0A18uni0A19uni0A1Auni0A1Buni0A1Cuni0A1Duni0A1Euni0A1Funi0A20uni0A21uni0A22uni0A23uni0A24uni0A25uni0A26uni0A27uni0A28uni0A2Auni0A2Buni0A2Cuni0A2Duni0A2Euni0A2Funi0A30uni0A32uni0A33uni0A35uni0A36uni0A38uni0A39uni0A3Cuni0A3Euni0A3Funi0A40uni0A41uni0A42uni0A47uni0A48uni0A4Buni0A4Cuni0A4Duni0A59uni0A5Auni0A5Buni0A5Cuni0A5Euni0A66uni0A67uni0A68uni0A69uni0A6Auni0A6Buni0A6Cuni0A6Duni0A6Euni0A6Funi0A70uni0A71uni0A72uni0A73uni0A74uni0A81uni0A82uni0A83uni0A85uni0A86uni0A87uni0A88uni0A89uni0A8Auni0A8Buni0A8Duni0A8Funi0A90uni0A91uni0A93uni0A94uni0A95uni0A96uni0A97uni0A98uni0A99uni0A9Auni0A9Buni0A9Cuni0A9Duni0A9Euni0A9Funi0AA0uni0AA1uni0AA2uni0AA3uni0AA4uni0AA5uni0AA6uni0AA7uni0AA8uni0AAAuni0AABuni0AACuni0AADuni0AAEuni0AAFuni0AB0uni0AB2uni0AB3uni0AB5uni0AB6uni0AB7uni0AB8uni0AB9uni0ABAuni0ABCuni0ABDuni0ABEuni0ABFuni0AC0uni0AC1uni0AC2uni0AC3uni0AC4uni0AC5uni0AC7uni0AC8uni0AC9uni0ACBuni0ACCuni0ACDuni0AD0uni0AE0uni0AE4uni0AE5uni0AE6uni0AE7uni0AE8uni0AE9uni0AEAuni0AEBuni0AECuni0AEDuni0AEEuni0AEFuni0AF0uni0AF1uni0B02uni0B03uni0B05uni0B06uni0B07uni0B09uni0B0Buni0B0Funi0B13uni0B15uni0B16uni0B17uni0B18uni0B1Auni0B1Cuni0B1Duni0B1Funi0B20uni0B21uni0B2Auni0B2Buni0B2Funi0B30uni0B32uni0B33uni0B36uni0B37uni0B38uni0B39uni0B3Euni0B3Funi0B40uni0B41uni0B42uni0B43uni0B47uni0B60uni0B66uni0B67uni0B68uni0B69uni0B6Auni0B6Buni0B6Cuni0B6Duni0B6Euni0B6Funi0B82uni0B83uni0B85uni0B86uni0B87uni0B88uni0B89uni0B8Auni0B8Euni0B8Funi0B90uni0B92uni0B93uni0B94uni0B95uni0B99uni0B9Auni0B9Cuni0B9Euni0B9Funi0BA3uni0BA4uni0BA8uni0BA9uni0BAAuni0BAEuni0BAFuni0BB0uni0BB1uni0BB2uni0BB3uni0BB4uni0BB5uni0BB7uni0BB8uni0BB9uni0BBEuni0BBFuni0BC0uni0BC1uni0BC6uni0BC7uni0BC8uni0BCAuni0BCBuni0BCCuni0BCDuni0BD7uni0BDAuni0BDBuni0BDCuni0BDDuni0BE1uni0C83uni0C85uni0C86uni0C87uni0C88uni0C89uni0C8Auni0C8Euni0C8Funi0C90uni0C92uni0C93uni0C94uni0C95uni0C96uni0C97uni0C98uni0C99uni0C9Auni0C9Cuni0C9Euni0C9Funi0CA0uni0CA1uni0CA2uni0CA3uni0CA4uni0CA5uni0CA6uni0CA7uni0CA8uni0CB0uni0CB1uni0CB2uni0CB3uni0CE6uni0CE7uni0CE8uni0CE9uni0CEAuni0CEBuni0CECuni0CEDuni0CEEuni0CEFuni10A0uni10A1uni10A2uni10A3uni10A4uni10A5uni10A6uni10A7uni10A8uni10A9uni10AAuni10ABuni10ACuni10ADuni10AEuni10AFuni10B0uni10B1uni10B2uni10B3uni10B4uni10B5uni10B6uni10B7uni10B8uni10B9uni10BAuni10BBuni10BCuni10BDuni10BEuni10BFuni10C0uni10D0uni10D1uni10D2uni10D3uni10D4uni10D5uni10D6uni10D7uni10D8uni10D9uni10DAuni10DBuni10DCuni10DDuni10DEuni10DFuni10E0uni10E1uni10E2uni10E3uni10E4uni10E5uni10E6uni10E7uni10E8uni10E9uni10EAuni10EBuni10ECuni10EDuni10EEuni10EFuni10F0uni10F1uni10F2uni10F3uni10F4uni10F5uni1E00uni1E01uni1E02uni1E03uni1E04uni1E05uni1E06uni1E07uni1E08uni1E09uni1E0Auni1E0Buni1E0Cuni1E0Duni1E0Euni1E0Funi1E10uni1E11uni1E12uni1E13uni1E14uni1E15uni1E16uni1E17uni1E18uni1E19uni1E1Auni1E1Buni1E1Cuni1E1Duni1E1Euni1E1Funi1E20uni1E21uni1E22uni1E23uni1E24uni1E25uni1E26uni1E27uni1E28uni1E29uni1E2Auni1E2Buni1E2Cuni1E2Duni1E2Euni1E2Funi1E30uni1E31uni1E32uni1E33uni1E34uni1E35uni1E36uni1E37uni1E38uni1E39uni1E3Auni1E3Buni1E3Cuni1E3Duni1E3Euni1E3Funi1E40uni1E41uni1E42uni1E43uni1E44uni1E45uni1E46uni1E47uni1E48uni1E49uni1E4Auni1E4Buni1E4Cuni1E4Duni1E4Euni1E4Funi1E50uni1E51uni1E52uni1E53uni1E54uni1E55uni1E56uni1E57uni1E58uni1E59uni1E5Auni1E5Buni1E5Cuni1E5Duni1E5Euni1E5Funi1E60uni1E61uni1E62uni1E63uni1E64uni1E65uni1E66uni1E67uni1E68uni1E69uni1E6Auni1E6Buni1E6Cuni1E6Duni1E6Euni1E6Funi1E70uni1E71uni1E72uni1E73uni1E74uni1E75uni1E76uni1E77uni1E78uni1E79uni1E7Auni1E7Buni1E7Cuni1E7Duni1E7Euni1E7FWgravewgraveWacutewacute Wdieresis wdieresisuni1E86uni1E87uni1E88uni1E89uni1E8Auni1E8Buni1E8Cuni1E8Duni1E8Euni1E8Funi1E90uni1E91uni1E92uni1E93uni1E94uni1E95uni1E96uni1E97uni1E98uni1E99uni1E9Buni1EA0uni1EA1uni1EA2uni1EA3uni1EA4uni1EA5uni1EA6uni1EA7uni1EA8uni1EA9uni1EAAuni1EABuni1EACuni1EADuni1EAEuni1EAFuni1EB0uni1EB1uni1EB2uni1EB3uni1EB4uni1EB5uni1EB6uni1EB7uni1EB8uni1EB9uni1EBAuni1EBBuni1EBCuni1EBDuni1EBEuni1EBFuni1EC0uni1EC1uni1EC2uni1EC3uni1EC4uni1EC5uni1EC6uni1EC7uni1EC8uni1EC9uni1ECAuni1ECBuni1ECCuni1ECDuni1ECEuni1ECFuni1ED0uni1ED1uni1ED2uni1ED3uni1ED4uni1ED5uni1ED6uni1ED7uni1ED8uni1ED9uni1EDAuni1EDBuni1EDCuni1EDDuni1EDEuni1EDFuni1EE0uni1EE1uni1EE2uni1EE3uni1EE4uni1EE5uni1EE6uni1EE7uni1EE8uni1EE9uni1EEAuni1EEBuni1EECuni1EEDuni1EEEuni1EEFuni1EF0uni1EF1Ygraveygraveuni1EF4uni1EF5uni1EF6uni1EF7uni1EF8uni1EF9uni1F00uni1F01uni1F02uni1F03uni1F04uni1F05uni1F06uni1F07uni1F08uni1F09uni1F0Auni1F0Buni1F0Cuni1F0Duni1F0Euni1F0Funi1F10uni1F11uni1F12uni1F13uni1F14uni1F15uni1F18uni1F19uni1F1Auni1F1Buni1F1Cuni1F1Duni1F20uni1F21uni1F22uni1F23uni1F24uni1F25uni1F26uni1F27uni1F28uni1F29uni1F2Auni1F2Buni1F2Cuni1F2Duni1F2Euni1F2Funi1F30uni1F31uni1F32uni1F33uni1F34uni1F35uni1F36uni1F37uni1F38uni1F39uni1F3Auni1F3Buni1F3Cuni1F3Duni1F3Euni1F3Funi1F40uni1F41uni1F42uni1F43uni1F44uni1F45uni1F48uni1F49uni1F4Auni1F4Buni1F4Cuni1F4Duni1F50uni1F51uni1F52uni1F53uni1F54uni1F55uni1F56uni1F57uni1F59uni1F5Buni1F5Duni1F5Funi1F60uni1F61uni1F62uni1F63uni1F64uni1F65uni1F66uni1F67uni1F68uni1F69uni1F6Auni1F6Buni1F6Cuni1F6Duni1F6Euni1F6Funi1F70uni1F71uni1F72uni1F73uni1F74uni1F75uni1F76uni1F77uni1F78uni1F79uni1F7Auni1F7Buni1F7Cuni1F7Duni1F80uni1F81uni1F82uni1F83uni1F84uni1F85uni1F86uni1F87uni1F88uni1F89uni1F8Auni1F8Buni1F8Cuni1F8Duni1F8Euni1F8Funi1F90uni1F91uni1F92uni1F93uni1F94uni1F95uni1F96uni1F97uni1F98uni1F99uni1F9Auni1F9Buni1F9Cuni1F9Duni1F9Euni1F9Funi1FA0uni1FA1uni1FA2uni1FA3uni1FA4uni1FA5uni1FA6uni1FA7uni1FA8uni1FA9uni1FAAuni1FABuni1FACuni1FADuni1FAEuni1FAFuni1FB0uni1FB1uni1FB2uni1FB3uni1FB4uni1FB6uni1FB7uni1FB8uni1FB9uni1FBAuni1FBBuni1FBCuni1FBDuni1FBEuni1FBFuni1FC0uni1FC1uni1FC2uni1FC3uni1FC4uni1FC6uni1FC7uni1FC8uni1FC9uni1FCAuni1FCBuni1FCCuni1FCDuni1FCEuni1FCFuni1FD0uni1FD1uni1FD2uni1FD3uni1FD6uni1FD7uni1FD8uni1FD9uni1FDAuni1FDBuni1FDDuni1FDEuni1FDFuni1FE0uni1FE1uni1FE2uni1FE3uni1FE4uni1FE5uni1FE6uni1FE7uni1FE8uni1FE9uni1FEAuni1FEBuni1FECuni1FEDuni1FEEuni1FEFuni1FF2uni1FF3uni1FF4uni1FF6uni1FF7uni1FF8uni1FF9uni1FFAuni1FFBuni1FFCuni1FFDuni1FFEuni200BZWNJZWJuni2010uni2011 figuredash afii00208 quotereverseduni201Funi2023onedotenleaderuni2031minuteseconduni2034uni2035uni2036uni2037uni203B exclamdbluni203Duni2045uni2046uni2047uni2048uni2049uni204B zerosuperioruni2071 foursuperior fivesuperior sixsuperior sevensuperior eightsuperior ninesuperior zeroinferior oneinferior twoinferior threeinferior fourinferior fiveinferior sixinferior seveninferior eightinferior nineinferiorpesetauni20A8 afii57636Eurouni20B5uni210Buni210Cuni2110Ifrakturuni2112 afii61352uni2117uni211BRfrakturuni2126uni2127uni2128uni212Auni212Buni212Cuni212Duni2130uni2131uni2132uni2133onethird twothirdsuni2155uni2156uni2157uni2158uni2159uni215A oneeighth threeeighths fiveeighths seveneighthsuni215Funi2160uni2161uni2162uni2163uni2164uni2165uni2166uni2167uni2168uni2169uni216Auni216Buni216Cuni216Duni216Euni216Funi2170uni2171uni2172uni2173uni2174uni2175uni2176uni2177uni2178uni2179uni217Auni217Buni217Cuni217Duni217Euni217F arrowleftarrowup arrowright arrowdown arrowboth arrowupdncarriagereturn arrowdblleft arrowdblup arrowdblright arrowdbldown arrowdblboth universal existentialemptysetgradientelement notelementuni220Asuchthatuni220Duni2210uni2213uni2214 asteriskmathuni2219 proportionalangle logicaland logicalor intersectionunionuni222Cuni222Duni222E thereforesimilaruni223Euni2241uni2242uni2243uni2249uni2272uni2273 propersubsetpropersuperset circleplusuni2296circlemultiply perpendicularuni2300 integraltp integralbtuni23AEuni2422SF100000uni2501SF110000uni2503uni2504uni2505uni2506uni2507uni2508uni2509uni250Auni250BSF010000uni250Duni250Euni250FSF030000uni2511uni2512uni2513SF020000uni2515uni2516uni2517SF040000uni2519uni251Auni251BSF080000uni251Duni251Euni251Funi2520uni2521uni2522uni2523SF090000uni2525uni2526uni2527uni2528uni2529uni252Auni252BSF060000uni252Duni252Euni252Funi2530uni2531uni2532uni2533SF070000uni2535uni2536uni2537uni2538uni2539uni253Auni253BSF050000uni253Duni253Euni253Funi2540uni2541uni2542uni2543uni2544uni2545uni2546uni2547uni2548uni2549uni254Auni254BSF430000SF240000SF510000SF520000SF390000SF220000SF210000SF250000SF500000SF490000SF380000SF280000SF270000SF260000SF360000SF370000SF420000SF190000SF200000SF230000SF470000SF480000SF410000SF450000SF460000SF400000SF540000SF530000SF440000upblockuni2581uni2582uni2583dnblockuni2585uni2586uni2587blockuni2589uni258Auni258Blfblockuni258Duni258Euni258Frtblockltshadeshadedkshadeuni2594uni2595uni2596uni2597uni2598uni2599uni259Auni259Buni259Cuni259Duni259Euni259F filledboxH22073uni25A3uni25A4uni25A5H18543 filledrectuni25CCuni262C musicalnoteuni2740uni2741uni3001uni3002uni3003uni3005uni3007uni3008uni3009uni300Auni300Buni300Cuni300Duni300Euni300Funi3010uni3011uni3014uni3015uni3041uni3042uni3043uni3044uni3045uni3046uni3047uni3048uni3049uni304Auni304Buni304Cuni304Duni304Euni304Funi3050uni3051uni3052uni3053uni3054uni3055uni3056uni3057uni3058uni3059uni305Auni305Buni305Cuni305Duni305Euni305Funi3060uni3061uni3062uni3063uni3064uni3065uni3066uni3067uni3068uni3069uni306Auni306Buni306Cuni306Duni306Euni306Funi3070uni3071uni3072uni3073uni3074uni3075uni3076uni3077uni3078uni3079uni307Auni307Buni307Cuni307Duni307Euni307Funi3080uni3081uni3082uni3083uni3084uni3085uni3086uni3087uni3088uni3089uni308Auni308Buni308Cuni308Duni308Euni308Funi3090uni3091uni3092uni3093uni3099uni309Buni30A1uni30A2uni30A3uni30A4uni30A5uni30A6uni30A7uni30A8uni30A9uni30AAuni30ABuni30ACuni30ADuni30AEuni30AFuni30B0uni30B1uni30B2uni30B3uni30B4uni30B5uni30B6uni30B7uni30B8uni30B9uni30BAuni30BBuni30BCuni30BDuni30BEuni30BFuni30C0uni30C1uni30C2uni30C3uni30C4uni30C5uni30C6uni30C7uni30C8uni30C9uni30CAuni30CBuni30CCuni30CDuni30CEuni30CFuni30D0uni30D1uni30D2uni30D3uni30D4uni30D5uni30D6uni30D7uni30D8uni30D9uni30DAuni30DBuni30DCuni30DDuni30DEuni30DFuni30E0uni30E1uni30E2uni30E3uni30E4uni30E5uni30E6uni30E7uni30E8uni30E9uni30EAuni30EBuni30ECuni30EDuni30EEuni30EFuni30F0uni30F1uni30F2uni30F3uni30F4uni30F5uni30F6uni30F7uni30F8uni30F9uni30FAuni30FBuni30FCuni30FDuni30FEuniE968uniE969uniE96AuniF639uniF63AuniF63BuniF63CuniF63DuniF63EuniF63FuniF640uniF641dotlessj commaaccent onefittedffffiffluniFB05uniFB06uniFB1DuniFB1E afii57705uniFB20uniFB21uniFB22uniFB23uniFB24uniFB25uniFB26uniFB27uniFB28uniFB29 afii57694 afii57695uniFB2CuniFB2DuniFB2EuniFB2FuniFB30uniFB31uniFB32uniFB33uniFB34 afii57723uniFB36uniFB38uniFB39uniFB3AuniFB3BuniFB3CuniFB3EuniFB40uniFB41uniFB43uniFB44uniFB46uniFB47uniFB48uniFB49uniFB4A afii57700uniFB4CuniFB4DuniFB4EuniFB4FuniFFFD bn_initekaar bn_initaikaarbn_reph bn_kaphala bn_nnaphala bn_taphala bn_thaphala bn_thaphala1 bn_dhaphala bn_naphala bn_below_ba bn_bhaphala bn_raphala bn_laphala bn_half_ka bn_half_kha bn_half_ga bn_half_gha bn_half_nga bn_half_ca bn_half_ca1 bn_half_cha bn_half_ja bn_half_jha bn_half_nya bn_half_tta bn_half_ttha bn_half_dda bn_half_ddha bn_half_nna bn_half_tha bn_half_dha bn_half_da bn_half_na bn_half_pa bn_half_pha bn_half_ba bn_half_bha bn_half_ma bn_half_ya bn_half_ra bn_half_la bn_half_sha bn_half_ssa bn_half_sa bn_half_ha bn_half_rra bn_half_rha bn_half_yyabn_half_asamirabn_half_asamiba bn_khaphala bn_phaphala bn_baphala1 bn_maphala bn_maphala1 bn_yaphalabn_k_rabn_k_ra1bn_kh_rabn_g_rabn_gh_rabn_c_rabn_ch_rabn_j_rabn_tt_ra bn_tth_rabn_dd_ra bn_ddh_rabn_t_rabn_t_ra1bn_th_rabn_d_rabn_dh_rabn_n_rabn_n_ra1bn_p_rabn_ph_rabn_b_rabn_bh_ra bn_bh_ra1bn_m_rabn_y_rabn_sh_rabn_ss_rabn_s_rabn_s_ra1bn_h_ra bn_asamir_ra bn_asamib_ra bn_k_ss_rabn_k_kabn_k_tta bn_k_tt_rabn_k_tabn_k_ta1 bn_k_t_ba bn_k_t_ba1 bn_k_t_ra bn_k_t_ra1 bn_k_t_ra2bn_k_nabn_k_mabn_k_labn_k_ssa bn_k_ss_nna bn_k_ss_mabn_k_sabn_g_gabn_g_dabn_g_dha bn_g_dh_babn_g_labn_g_nabn_g_mabn_gh_nabn_ng_ka bn_ng_k_ra bn_ng_k_ssa bn_ng_k_ss_ra bn_ng_khabn_ng_ga bn_ng_gha bn_ng_gh_rabn_ng_ma bn_ng_ma1bn_c_cabn_c_cha bn_c_ch_ba bn_c_ch_rabn_c_nyabn_c_nabn_j_ja bn_j_j_babn_j_jhabn_j_nyabn_ny_ca bn_ny_chabn_ny_ja bn_ny_jha bn_tt_tta bn_tt_tt_rabn_tt_mabn_dd_ga bn_dd_ddabn_dd_ma bn_nn_tta bn_nn_tt_ra bn_nn_ttha bn_nn_dda bn_nn_dda1 bn_nn_dd_ra bn_nn_dd_ra1 bn_nn_ddha bn_nn_nnabn_nn_mabn_t_ta bn_t_t_babn_t_thabn_t_nabn_t_mabn_t_ma1bn_t_labn_d_gabn_d_ghabn_d_da bn_d_d_ba bn_d_d_rabn_d_dha bn_d_dh_babn_d_nabn_d_bha bn_d_bh_ra bn_d_bh_ra1bn_d_mabn_dh_nabn_dh_mabn_n_tta bn_n_tt_ra bn_n_tthabn_n_dda bn_n_dd_ra bn_n_ddhabn_n_ta bn_n_t_ba bn_n_t_ra bn_n_t_ra1bn_n_thabn_n_da bn_n_d_ba bn_n_d_rabn_n_dha bn_n_dh_ba bn_n_dh_rabn_n_nabn_n_mabn_n_ma1bn_n_sabn_p_ttabn_p_tabn_p_pabn_p_mabn_p_nabn_p_labn_p_sa bn_ph_ttabn_ph_labn_b_jabn_b_da bn_b_d_rabn_b_dhabn_b_nabn_b_bhabn_b_labn_bh_labn_m_tabn_m_thabn_m_dabn_m_nabn_m_na1bn_m_pa bn_m_p_ra bn_m_p_labn_m_pha bn_m_ph_rabn_m_bha bn_m_bh_ra bn_m_bh_ra1bn_m_mabn_m_ma1bn_m_labn_m_la1bn_m_sa bn_m_s_rabn_l_kabn_l_gabn_l_tta bn_l_tt_rabn_l_dda bn_l_dd_rabn_l_tabn_l_dabn_l_dhabn_l_pabn_l_pha bn_l_ph_rabn_l_mabn_l_labn_sh_ca bn_sh_chabn_sh_tabn_sh_nabn_sh_mabn_sh_labn_ss_ka bn_ss_k_ra bn_ss_k_ra1 bn_ss_tta bn_ss_tta1 bn_ss_tt_ra bn_ss_tt_ra1 bn_ss_ttha bn_ss_nnabn_ss_pa bn_ss_p_ra bn_ss_pha bn_ss_ph_rabn_ss_ma bn_ss_ma1bn_s_ka bn_s_k_ra bn_s_k_ra1bn_s_khabn_s_tta bn_s_tta1 bn_s_tt_ra bn_s_tt_ra1bn_s_ta bn_s_t_ba bn_s_t_ra bn_s_t_ra1bn_s_thabn_s_nabn_s_na1bn_s_pa bn_s_p_ra bn_s_p_labn_s_pha bn_s_ph_rabn_s_mabn_s_ma1bn_s_labn_s_la1bn_h_nnabn_h_nabn_h_mabn_h_labn_h_la1bn_rr_gabn_k_babn_g_babn_gh_babn_c_babn_ch_babn_j_babn_tt_babn_dd_babn_nn_babn_t_babn_th_babn_d_babn_dh_ba bn_dh_ba1bn_n_babn_n_ba1bn_p_babn_b_babn_bh_babn_m_ba bn_m_b_rabn_m_ba1 bn_m_b_ra1bn_l_babn_sh_babn_s_babn_s_ba1bn_h_babn_h_ba1 bn_kh_r_ukaarbn_kh_r_uukaar bn_g_ukaar bn_g_r_ukaar bn_g_r_uukaar bn_g_l_ukaar bn_g_l_uukaar bn_j_r_ukaar bn_j_r_uukaar bn_t_r_ukaar bn_t_r_uukaar bn_th_r_ukaarbn_th_r_uukaar bn_d_ukaar bn_d_r_ukaar bn_d_r_uukaar bn_dh_r_ukaarbn_dh_r_uukaar bn_n_ukaar bn_n_uukaar bn_n_rikaar bn_n_t_ukaarbn_n_d_r_ukaarbn_n_d_r_uukaar bn_p_r_ukaar bn_p_r_uukaar bn_p_l_ukaar bn_p_l_uukaar bn_b_r_ukaar bn_b_r_uukaar bn_b_l_ukaar bn_b_l_uukaar bn_bh_r_ukaarbn_bh_r_uukaar bn_m_r_ukaar bn_m_r_uukaarbn_m_p_r_ukaarbn_m_p_r_uukaar bn_r_ukaar bn_r_uukaar bn_l_g_ukaar bn_sh_ukaar bn_sh_r_ukaarbn_sh_r_uukaar bn_sh_l_ukaarbn_sh_l_uukaarbn_ss_p_r_ukaarbn_ss_p_r_uukaar bn_s_ukaar bn_s_uukaar bn_s_rikaar bn_s_t_ukaar bn_s_r_ukaar bn_s_r_uukaarbn_s_p_r_ukaarbn_s_p_r_uukaarbn_s_p_l_ukaarbn_s_p_l_uukaar bn_s_l_ukaar bn_s_l_uukaar bn_h_ukaar bn_h_rikaarbn_asamir_ukaarbn_asamir_uukaarbn_asamib_ukaarbn_asamib_uukaarbn_asamib_r_ukaarbn_asamib_r_uukaar bn_k_hasanta bn_kh_hasanta bn_g_hasanta bn_gh_hasanta bn_ng_hasanta bn_c_hasanta bn_ch_hasanta bn_j_hasanta bn_jh_hasanta bn_ny_hasanta bn_tt_hasantabn_tth_hasanta bn_dd_hasantabn_ddh_hasanta bn_nn_hasanta bn_t_hasanta bn_th_hasanta bn_d_hasanta bn_dh_hasanta bn_n_hasanta bn_p_hasanta bn_ph_hasanta bn_b_hasanta bn_bh_hasanta bn_m_hasanta bn_y_hasanta bn_r_hasanta bn_l_hasanta bn_sh_hasanta bn_ss_hasanta bn_s_hasanta bn_h_hasanta bn_rr_hasanta bn_rh_hasanta bn_yy_hasantabn_asamir_hasantabn_asamib_hasanta bn_post_k_raglyph569emdash.1glyph571glyph572glyph57487 bn_baphala bn_below_ba2glyph578glyph579glyph580glyph581glyph582A.001 bn_sh_ra.001bn_yaphala.002bn_d_yabn_n_ya bn_la.001bn_sh_yabn_ss_yabn_s_yaglyph593bn_h_yaglyph595 bn_ss_tta.002glyph597glyph598 bn_uukaar.1glyph600A.002A.003uni091F_uni093C.nuktuni0920_uni093C.nuktglyph240glyph241uni0908_uni0902.abvsuni0947_uni0901.abvsuni094B_uni0901.abvsglyph245glyph246glyph247uni0939_uni094D.halnglyph249uni091B_uni094D.halnuni0939_uni0944.blwsuni0915_uni094D_uni0937.akhnuni091C_uni094D_uni091E.akhn!uni0924_uni094D.half_uni0924.pres!uni0924_uni0930_uni094D.blwf.vatu!uni0936_uni094D.half_uni091A.pres!uni0936_uni0930_uni094D.blwf.vatu!uni0936_uni094D.half_uni0935.pres!uni095B_uni0930_uni094D.blwf.vatu!uni092B_uni0930_uni094D.blwf.vatu!uni095E_uni0930_uni094D.blwf.vatu!uni092A_uni0930_uni094D.blwf.vatu!uni0938_uni0930_uni094D.blwf.vatuuni0930_uni0941.blwsuni0930_uni0942.blws!uni0915_uni094D.half_uni0928.pres!uni0916_uni094D.half_uni0928.pres!uni0918_uni094D.half_uni0928.presglyph269uni0915_uni094D.halfuni0916_uni094D.halfuni0917_uni094D.halfuni0918_uni094D.halfuni091A_uni094D.halfglyph275uni091C_uni094D.halfuni091D_uni094D.halfuni091E_uni094D.half!uni0924_uni094D.half_uni0928.pres!uni0925_uni094D.half_uni0928.pres!uni0926_uni094D.half_uni0928.pres!uni0927_uni094D.half_uni0928.presuni0923_uni094D.halfuni0924_uni094D.halfuni0925_uni094D.half.uni0926_uni094D.half_uni0926_uni094D.half.presuni0927_uni094D.halfuni0928_uni094D.halfglyph289uni092A_uni094D.halfuni092B_uni094D.halfuni092C_uni094D.halfuni092D_uni094D.halfuni092E_uni094D.halfuni092F_uni094D.half!uni092A_uni094D.half_uni0928.presglyph297uni0932_uni094D.halfuni0933_uni094D.halfuni0934_uni094D.halfuni0935_uni094D.halfuni0936_uni094D.halfuni0937_uni094D.halfuni0938_uni094D.halfuni0939_uni094D.halfglyph306!uni092C_uni094D.half_uni0928.presglyph308!uni092E_uni094D.half_uni0928.pres!uni0935_uni094D.half_uni0928.pres!uni0936_uni094D.half_uni0928.pres!uni0915_uni094D.half_uni0915.pres!uni0919_uni094D.half_uni0915.pres!uni0919_uni094D.half_uni0916.pres!uni0919_uni094D.half_uni0917.pres!uni0919_uni094D.half_uni0918.pres!uni091E_uni094D.half_uni091C.pres!uni0926_uni094D.half_uni0918.pres!uni0926_uni094D.half_uni0926.pres!uni0926_uni094D.half_uni0927.pres!uni0926_uni094D.half_uni092C.pres!uni0926_uni094D.half_uni092D.pres!uni0926_uni094D.half_uni092E.pres!uni0926_uni094D.half_uni092F.pres!uni0926_uni094D.half_uni0935.pres!uni091F_uni094D.half_uni091F.pres!uni091F_uni094D.half_uni0920.pres!uni0920_uni094D.half_uni0920.presglyph329glyph330glyph331!uni0939_uni094D.half_uni092E.pres!uni0939_uni094D.half_uni092F.pres!uni0932_uni094D.half_uni0939.presglyph3356uni0938_uni094D.half_uni0924_uni094D_uni0930.pres.presglyph337uni0930_uni094D_afii301.half.uni091A_uni094D.half_uni091A_uni094D.half.half!uni0938_uni0928_uni094D.half.presglyph341glyph342glyph343glyph344glyph345glyph346glyph347glyph348glyph349)uni0915_uni094D_uni0937.akhn_uni094D.half)uni091C_uni094D_uni091E.akhn_uni094D.halfglyph352.uni0924_uni094D.half_uni0930_uni094D.blwf.vatuglyph354glyph355glyph356glyph357glyph358glyph359!uni0939_uni0930_uni094D.blwf.blwsuni0930_uni094D.rphfuni0930_uni094D.blwfuni093E_uni0901.abvsuni093E_uni0902.abvsglyph365glyph366glyph367glyph368glyph369uni0947_uni0902.abvsglyph371glyph372uni0948_uni0902.abvsglyph374glyph375glyph376glyph377glyph378;uni0938_uni094D.half_uni091F_uni0930_uni094D.blwf.vatu.vatuglyph380glyph381!uni0928_uni094D.half_uni0928.presuni0919_uni094D.halfuni091F_uni094D.halfuni0920_uni094D.halfuni0921_uni094D.halfuni0922_uni094D.halfuni0926_uni094D.half!uni0915_uni0930_uni094D.blwf.vatu!uni0916_uni0930_uni094D.blwf.pres!uni0917_uni0930_uni094D.blwf.pres!uni0918_uni0930_uni094D.blwf.vatu!uni0919_uni0930_uni094D.blwf.vatu!uni091A_uni0930_uni094D.blwf.vatu!uni091B_uni0930_uni094D.blwf.vatu!uni091C_uni0930_uni094D.blwf.vatu!uni091D_uni0930_uni094D.blwf.vatu!uni091E_uni0930_uni094D.blwf.vatu!uni091F_uni0930_uni094D.blwf.vatu!uni0920_uni0930_uni094D.blwf.vatu!uni0921_uni0930_uni094D.blwf.vatuglyph402!uni0923_uni0930_uni094D.blwf.vatuuni0924_uni094D_uni0930.pres!uni0925_uni0930_uni094D.blwf.vatu!uni0926_uni0930_uni094D.blwf.vatu!uni0927_uni0930_uni094D.blwf.vatu!uni0928_uni0930_uni094D.blwf.vatu!uni092C_uni0930_uni094D.blwf.vatu!uni092D_uni0930_uni094D.blwf.vatu!uni092E_uni0930_uni094D.blwf.vatu!uni092F_uni0930_uni094D.blwf.vatu!uni0930_uni0930_uni094D.blwf.vatu!uni0932_uni0930_uni094D.blwf.vatu.uni0936_uni094D.half_uni0932_uni094D.half.pres!uni0937_uni094D.half_uni091F.pres!uni0937_uni094D.half_uni0920.presglyph418glyph419glyph420.uni0936_uni094D.half_uni0928_uni094D.half.presHuni0938_uni094D.half_uni0924_uni094D.half_uni0930_uni094D.blwf.vatu.pres.uni0926_uni094D.half_uni092E_uni094D.half.pres.uni0924_uni094D.half_uni0928_uni094D.half.pres!uni0939_uni094D.half_uni0923.pres!uni0939_uni094D.half_uni0932.pres!uni0939_uni094D.half_uni0935.pres.uni092A_uni094D.half_uni0924_uni094D.half.pres!uni0939_uni094D.half_uni0928.pres.uni0939_uni094D.half_uni092E_uni094D.half.pres.uni092A_uni094D.half_uni0930_uni094D.blwf.vatuuni0919_uni093C.nuktuni0939_uni093C.nuktglyph434!uni091F_uni093C.nukt_uni094D.haln!uni0920_uni093C.nukt_uni094D.halnuni095C_uni094D.halnuni095D_uni094D.halnglyph439!uni0939_uni093C.nukt_uni094D.haln!uni0919_uni093C.nukt_uni094D.haln.uni0937_uni094D.half_uni091F.pres_uni094D.haln.uni0937_uni094D.half_uni0920.pres_uni094D.haln.uni0939_uni094D.half_uni0923.pres_uni094D.haln.uni0939_uni094D.half_uni0928.pres_uni094D.haln.uni0939_uni094D.half_uni0932.pres_uni094D.haln.uni0939_uni094D.half_uni0935.pres_uni094D.halnuni092B_uni093C_uni094D.nuktuni091C_uni093C_uni094D.nuktuni0A95_uni0ACD.halfuni0A96_uni0ACD.halfuni0A97_uni0ACD.halfuni0A98_uni0ACD.halfuni0A9A_uni0ACD.halfuni0A9C_uni0ACD.halfuni0A9D_uni0ACD.halfuni0A9E_uni0ACD.halfuni0AA3_uni0ACD.halfuni0AA4_uni0ACD.halfuni0AA5_uni0ACD.halfuni0AA7_uni0ACD.halfuni0AA8_uni0ACD.halfuni0AAA_uni0ACD.halfuni0AAB_uni0ACD.halfuni0AAC_uni0ACD.halfuni0AAD_uni0ACD.halfuni0AAE_uni0ACD.halfuni0AAF_uni0ACD.halfuni0AB2_uni0ACD.halfuni0AB3_uni0ACD.halfuni0AB5_uni0ACD.halfuni0AB6_uni0ACD.halfuni0AB7_uni0ACD.halfuni0AB8_uni0ACD.halfuni0AB9_uni0ACD.half)uni0A95_uni0ACD_uni0AB7.akhn_uni0ACD.half.uni0AA4_uni0ACD.half_uni0AA4_uni0ACD.half.pres)uni0AA4_uni0ACD.half_uni0AB0_uni0ACD.vatu.uni0AA8_uni0ACD.half_uni0AA8.pres_uni0ACD.pres.uni0AB6_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0A96_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0A97_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0A98_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0A9A_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0A9C_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AA5_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AA7_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AA8_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AAA_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AAC_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AAD_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AAE_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu.uni0AB8_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatuuni0A87_uni0A82.abvsuni0A88_uni0A82.abvsuni0A89_uni0A82.abvsuni0A8A_uni0A82.abvs!uni0A95_uni0ACD.half_uni0A95.pres!uni0A95_uni0AB0_uni0ACD.blwf.vatuuni0A9C_uni0ABE.pstsuni0A9C_uni0AC0.psts!uni0A9C_uni0AB0_uni0ACD.blwf.vatu!uni0A9D_uni0AB0_uni0ACD.blwf.vatuuni0A9F_uni0ACD_uni0A9F.presuni0A9F_uni0ACD_uni0AA0.presuni0AA0_uni0ACD_uni0AA0.presuni0AA1_uni0ACD_uni0AA1.presuni0AA1_uni0ACD_uni0AA2.pres!uni0AA6_uni0AB0_uni0ACD.blwf.vatuuni0AA6_uni0ACD_uni0AAE.presuni0AA6_uni0ACD_uni0AA6.presuni0AA6_uni0ACD_uni0AA7.presuni0AA6_uni0ACD_uni0AB5.pres!uni0AAB_uni0AB0_uni0ACD.blwf.vatuuni0AB0_uni0AC1.blwsuni0AB0_uni0AC2.blwsnounicode-3-1-cd.uni0AB5_uni0ACD.half_uni0AB0_uni0ACD.blwf.vatu)uni0AB6_uni0ACD.half_uni0AB5_uni0ACD.pres!uni0AB9_uni0AB0_uni0ACD.blwf.vatu!uni0AB9_uni0ACD.half_uni0AAE.pres!uni0AB9_uni0ACD.half_uni0AAF.pres.uni0AB6_uni0ACD.half_uni0AA8.pres_uni0ACD.pres)uni0AB6_uni0ACD.half_uni0A9A_uni0ACD.presuni0AA2_uni0ACD_uni0AA2.presuni0A95_uni0ACD_uni0AB7.akhn!uni0AA4_uni0ACD.half_uni0AA4.pres!uni0AA4_uni0AB0_uni0ACD.blwf.vatu!uni0AA8_uni0ACD.half_uni0AA8.pres!uni0AB6_uni0AB0_uni0ACD.blwf.vatu!uni0A96_uni0AB0_uni0ACD.blwf.vatu!uni0A97_uni0AB0_uni0ACD.blwf.vatu!uni0A98_uni0AB0_uni0ACD.blwf.vatu!uni0A9A_uni0AB0_uni0ACD.blwf.vatu!uni0AA5_uni0AB0_uni0ACD.blwf.vatu!uni0AA7_uni0AB0_uni0ACD.blwf.vatu!uni0AA8_uni0AB0_uni0ACD.blwf.vatu!uni0AAA_uni0AB0_uni0ACD.blwf.vatu!uni0AAC_uni0AB0_uni0ACD.blwf.vatu!uni0AAD_uni0AB0_uni0ACD.blwf.vatu!uni0AAE_uni0AB0_uni0ACD.blwf.vatu!uni0AB8_uni0AB0_uni0ACD.blwf.vatu!uni0AB5_uni0AB0_uni0ACD.blwf.vatu!uni0AB6_uni0ACD.half_uni0AB5.pres!uni0AB6_uni0ACD.half_uni0AA8.pres!uni0AB6_uni0ACD.half_uni0A9A.presglyph407glyph408glyph409uni0AB0_uni0ACD.rphfglyph411uni0AB0_uni0ACD.blwf!uni0AB7_uni0ACD.half_uni0AA0.pres!uni0AB7_uni0ACD.half_uni0A9F.pres6uni0AB7_uni0ACD.half_uni0A9F_uni0AB0_uni0ACD.blwf.vatu6uni0AB7_uni0ACD.half_uni0AA0_uni0AB0_uni0ACD.blwf.vatuglyph417glyph421!uni0A9F_uni0AB0_uni0ACD.blwf.vatuuni0A9C_uni0ACD_uni0A9E.akhnglyph424!uni0AA1_uni0AB0_uni0ACD.blwf.vatu!uni0AA0_uni0AB0_uni0ACD.blwf.vatu!uni0AA2_uni0AB0_uni0ACD.blwf.vatuglyph428glyph429glyph430glyph431glyph432glyph433glyph435glyph436glyph437glyph438glyph440glyph441uni0AC7_uni0A82.abvsglyph443glyph444glyph445glyph446glyph447glyph448glyph449glyph450glyph451glyph452glyph453uni0A95_uni0ABC.nuktuni0A96_uni0ABC.nuktuni0A97_uni0ABC.nuktuni0A98_uni0ABC.nuktuni0A99_uni0ABC.nuktuni0A9A_uni0ABC.nuktuni0A9B_uni0ABC.nuktuni0A9C_uni0ABC.nuktuni0A9D_uni0ABC.nuktuni0A9E_uni0ABC.nuktuni0A9F_uni0ABC.nuktuni0AA0_uni0ABC.nuktuni0AA1_uni0ABC.nuktuni0AA2_uni0ABC.nuktuni0AA3_uni0ABC.nuktuni0AA4_uni0ABC.nuktuni0AA5_uni0ABC.nuktuni0AA6_uni0ABC.nuktuni0AA7_uni0ABC.nuktuni0AA8_uni0ABC.nuktuni0AAA_uni0ABC.nuktuni0AAB_uni0ABC.nuktuni0AAC_uni0ABC.nuktuni0AAD_uni0ABC.nuktuni0AAE_uni0ABC.nuktuni0AAF_uni0ABC.nuktuni0AB0_uni0ABC.nuktuni0AB2_uni0ABC.nuktuni0AB3_uni0ABC.nuktuni0AB5_uni0ABC.nuktuni0AB6_uni0ABC.nuktuni0AB7_uni0ABC.nuktuni0AB8_uni0ABC.nuktuni0AB9_uni0ABC.nukt)uni0AA3_uni0ACD.half_uni0AB0_uni0ACD.vatuuni0AA3_uni0AB0_uni0ACD.vatuuni0A30_uni0A4D.blwfuni0A35_uni0A4D.blwfuni0A39_uni0A4D.blwfuni0A2F_uni0A4D.pstfglyph152glyph153glyph154glyph155glyph156glyph157!uni0A30_uni0A4D.blwf_uni0A41.blws!uni0A39_uni0A4D.blwf_uni0A41.blwsnounicode-3-1-3glyph161!uni0A30_uni0A4D.blwf_uni0A42.blws!uni0A39_uni0A4D.blwf_uni0A42.blwsnounicode-3-1-2fnounicode-3-1-30uni0A28_uni0A42_uni0A70.abvsuni0A3E_uni0A02.abvsuni0A09_uni0A71.pstsuni0A0A_uni0A71.pstsuni0A13_uni0A71.pstsuni0A15_uni0A3C.nuktuni0A18_uni0A3C.nuktuni0A19_uni0A3C.nuktuni0A1A_uni0A3C.nuktuni0A1B_uni0A3C.nuktuni0A1D_uni0A3C.nuktuni0A1E_uni0A3C.nuktuni0A1F_uni0A3C.nuktuni0A20_uni0A3C.nuktuni0A22_uni0A3C.nuktuni0A23_uni0A3C.nuktuni0A24_uni0A3C.nuktuni0A25_uni0A3C.nuktuni0A26_uni0A3C.nuktuni0A27_uni0A3C.nuktuni0A28_uni0A3C.nuktuni0A2A_uni0A3C.nuktuni0A2C_uni0A3C.nuktuni0A2D_uni0A3C.nuktuni0A2E_uni0A3C.nuktuni0A2F_uni0A3C.nuktuni0A30_uni0A3C.nuktuni0A35_uni0A3C.nuktglyph194uni0A39_uni0A3C.nuktuni0A05_uni0A3C.nuktuni0A06_uni0A3C.nuktuni0A07_uni0A3C.nuktuni0A08_uni0A3C.nuktuni0A09_uni0A3C.nuktuni0A0A_uni0A3C.nuktuni0A0F_uni0A3C.nuktuni0A10_uni0A3C.nuktuni0A13_uni0A3C.nuktuni0A14_uni0A3C.nuktuni0A06_uni0A02.abvsglyph207!uni0A35_uni0A4D.blwf_uni0A41.blws!uni0A35_uni0A4D.blwf_uni0A42.blws!uni0A30_uni0A4D.blwf_uni0A4D.blws!uni0A39_uni0A4D.blwf_uni0A4D.blws!uni0A35_uni0A4D.blwf_uni0A4D.blws (kllm?@@AMNghijnoopstuvoppqqrrs;<=>deeffgghmntuwxxyyz                , - / 0 1 2 2 3 = > > ? B C C D G H H I M N N O O P P Q V W W X X Y Y Z Z [ \ ] f g g h r s s t t u u v y z z {                                                              ! ! " , - - . / 0 0 1 1 2 2 3 6 7 9 : < = = > > ? ? @ Q R T U o p r s                                       % & & ' ) * + , , - - . . / 9 : > ? ? @ A B B C C D E F F G J K M N U V V W X Y Y Z ` a a b z { } ~                       ()PQVWXYZ[\]^_z{{|, $  S  DFLT2armnBbengNdevangujrguruhebrlatn,   "#(- &'*  %)+ !$.aaltabvsabvs"abvs(akhn.akhn4akhn:blwf@blwfFblwfLblwfRblwsXblws^blwsdblwsjccmppdligvdlig|frachalfhalfhalfhalnhalninitliganuktnuktnuktpresprespresprespstfpstfpstspstspstsrephrphfrphfrphf vatuvatuvatu vatu&.(&' $%"#  ,- !*+)/  0bjrz "*2:BJRZbjrz*xPfBdB*xJ*xx`  ( v2jHnxV#b% #%2%%%'&*(("">NONONVXb"JT^hr|&0:DNXblv)*+,-./0123456789:;<=>?@ABCDEFGHIJ",6@J^hr|         (V`jt~&0:DNXblv}j~jjjjjjjjj djdjujvjejfjgjhjwjijjjkjljmjnjojpjqjrjsjtjyjujvjwjxjyjejzjgj|j?TVdff%hi& ` "   "   zJT^h/ "( KQ KN Q N KO Y Y Q N.KNXC      1 E*  MtNtOtcfi F &0:DNXblv              1%PZdnx",6@JT^hr|                           ! " # $ % & ' ( ) * " 12#J<FPZdnx",6@                             *Zdnx",6@JT^hr|     [     \ ] ^ _    `         .         : ; < > ? @ /   " % ( Z Z)&Pf " "*   + , 0 Ptb!HR\fpz$.8BLV`jt~ a F d F e F f F g F h F i F j F k F l F m F o F  F q F r F s F t F  F  F u F v F w F y F z F  F  F  F  F = F  F W k ~ y  y! | }V>HR\fpz$.8BL 1  3  4  5  6  7  8  9  :  ;  <  =  ?  @  A  B  D  E  F  G  I  J  K  L  M  O  Q  R   22 ` `*      )Xblv",6@JT^hr~        L                K               " % x F:d,NhT"T^J|Xz $       &,28>D c _ ^ ] Z = V U 9 T S &, j i h f e d k$*06< t r q p o R n ` m 1 l  { y 7 w v  ~ |        9    $*06<     ;    9   $*06<   G    @   "(.4:@FLRX^djpv|     A   @    =    ;    9 "(.4          &,     @     &,28>DJPV\bhnt  M     G   E    D     $*06<BHNTZ`fl    E       ;   9    &,       $*06<BHNT   E   D     9   1 "(.4:@FLRX^djpv|    E    D     =   9    1       " b a                ! " # $ % & ` $.@Z b F c F   ' & % &,     ) ( # " $  &,28>D   !            \ ] `  4@Vb       "         "(          @:DNZdv  J\n b F c F p 0           ' & %  Z     *  $  {     } |  = , p"(.4       ) (      # " $ $*06<BHNT   !         `    [ \ ] `.    D F Z &@t[oWntont\oXnMNO:z  *4FPbl(:L^p"4FXbt #  B $  %  &  '  (  )  *  +  ,  M .  /  1  3  4  5  6  g f :  i ;  <  } | >   ~   A @ D C H G J I L K O N Q P Y X ] \ a ` c b k j u t   X  F E x  }        U     W V [ Z _ ^ e d h m l o n s   w v y x { z:   12 3 4 8 = ? @ A D F G I K M Q V h w |   &    $ &Jdv p  J Ep I E Hp Go C Ep L Epp  P C O E Np o $ S C R E Qp   C  X C T E op  U E   Cp o Vp v E U, "=_o`=@\kT$.8      *  abcCDGZ*6BN  0  0  0  0  0  0  &0:DNXblv       n F          ' | } %PZdnx",6@JT^hr|                                      " 12#*    E  E Cpy E  NO DFLT2armn>bengHdevaRgujrdgururhebr|latn  abvm>abvmDblwmJblwmPkernVkern\lfbdbmarkhmkmknrtbdt &.6>FPZbL>| "+T)-x-~4B "FLRX^djpv| [ $8+TKt  2"(.|`C]%f6 E "(.4:@FLRX^djpv| $|yfDmJUUkkM_wq)bg.&O L|Q6?.'303h00m_weR; idbE          ! " # $ % & ' ( ) * + , A B D F a p r y | } "(.Xtpk<&J #HNTZ`flrx~T ! *O;$&#0+). - #9TMx *   +"(.zawffz $*06<BHNTZ`flrx~ &,28>DJPV\bhntz "(.4:@FLRX^djpv| $*06<BHNTxaejgdi9jjedce _eqehaXaed ciecgffegaggaeac d hcefa egeiga>>5|7@^^ag[i_didieeYgaeagWi#aeg4cge.e:cc^d^gddigcgg^g;e>>A;D>>kjd^^gdaedaagda aeWchgaj^9ddaddd ceecg ddg|7@jigeadaa*uvx~    #%&) * , - 3 7 8 9 : ;  <  = ?  -@ A AT C EU N SX W W^ [ a_ e ef g gg k nh p pl r rm y yn | o t u x zop"(.4:@FLkUgXdGLiV2@ft F`$ &9;<> &9;<>{&9< >&ITWXY[\^ &9 ;<> &9 ;<>&9;<> &9;<>               L<Xd6d Jdnx      j 8 f N T b x *8FTbp~&(,469:;<>FGHIJLTVYZ[\^o&4;<> &-04 &/9;<=>&/4FJNOTWZ &9;<>&(,489FJTZ^&(,489:;<>Z^$ks&(,FT &9;<=>yy&/FJT(,49:;<>FJTZ^ &9;<>Y/{ &(,/48; <>FHJLNOTWXZ[\^o$% &RSUW& &(,489FJLNTWZ^o$$ &(,489FJLNTWZ^o (46FJTZ^$ &(,489FJLNTUZ[o[^O[\^[\^MPY[\]^FJKNOQTYF^9OFJLTXZ^U[\^9U[\^9Y[\]^Y^HZ+ FHIJKLNPQTUVXYZ[\]^_ Y 8FJMT FHJLTX FHJLTXFHJTV FHJLQTX (,469:;<>(,469:;<>FGHIJLTVYZ[\^o (,469:;<> (,469:;<>(,469:;<>FGHILTVYZ[\^o(,469:;<>FGHIJLTVYZ[\^o&9;>&9;<>9;>9;>&9;<=>&&&RSUW&&GRSUW[\^[\^[\^[\^[\^[\^[\^[\^[\^YY[\]^&-04MP&9;Y[^&)+,/135 7? FHJNP^,238=?BDGH$$JAAK b &,28>DJPV\bhntz "(.4:@FLRX^djpv| :bXXkX.W:lP1mXMW8nX8l88nj:;`xZNX8mc8 p888l8888W8'')>FY+,-.JJ0RT1YY4\\5``6dg7ii;ss<vv=>OP Q  W))X--Y34Z66\:>]dgjnps v rx~ZZZZZZZZZZZZIZZZZZZZZZZZZZZZN>j  &,28>DJPV\bhntz "(.4:@FLRX^djpv| $*06<BHNTZ`flrx~ &,O3}[XXk{Xp3eO4mXMW? nomfodj3;`x^NWXmm?&? oW}OSh2DPd     Y `m&'()*+,-./0123456789:;<=>?FHJLMNOPQRSTUVWXZ\^_JRSTXY\`defgistvx{|}~   )+,-0346:;<=>  $& @@NVXc jpv|UUUUUUUUUUUUUUUUUUUUUUUs[ & :@FLRX^djpv|Z.Z.ZZZZ)Z)ZZ|Z\Z_ZIZZ;Z/Z/Z/Z/Z/Z/ZYZWZZZ;ZZ/dgjnps v dgjnps v rx~ZZZZZZZZZZZZIZZZZZZZZZZZZZZZ 8>DJPV\bhntzUUUUUUUUUUUUUDUDUU0UUUUUU URsZll@@NVXc @@Ncntz UUUUUUUUUUUUUUUUUUUUUUUsZ 3 3]-I fxine-lib-1.2/misc/fonts/serif-32.xinefont.gz0000644000175000017500000010655414647725152016510 0ustar meme5=%فY/q׼؉!Đ׉'3qff#m~[3 Ta?;~oo˷7~|Gj~'_ϐK)9T}6J=-{ڣ Oc Un9PeE_g\qwO*m5Y6oq_ XN\&ڗI-ɿзu|/mZokǖ[Fxh.ox̱ Kt|@ w@L 6Ma^* g#C?^n?k5BۢNt=~-z(F+crBř (ϵFm[gc{ ?UKdOMDSX;lF~j9l%Z@n,W[p(IDGz,bD\tbc~j{5/hdE#"F_h%w}7'AȺB?YhX N?о"Z^-߽\遛{Wp޴{ 0Q]ҪǧUuF\7y{>*`Rlߦ5;f9hnKs[t÷[@[1;xiJ.U3Q+ZPvRZXCYd?:؋,ll=S3D7>z~dޱlzn֘c._@gMV>HOB4~Nqln4sw&>nɪ ?A.)w=M]zR&/o)eK8`ߜH(x=IRAH?Uma$Nټ qu{Tf~" Q`y7Ylo MmY:Z׃K^` Hq4> Q!ꌤA@!m/sR1<^姾,\NUzaAU$&i)^,WP4'$ nJ,ݔJv#46:r *2 5_"72fTz##\M Rk}gcQT,WQ~ݨ|NtK0M炪YJ -I-Ed.wQ6 r,SFhPKFȫTTxlm> v \Yb̓;I=m{- w;xf">fDlfi +Qfyt\! -Q\ 9×?K/_EW_R/=EuMC:J!6 Bq/Ov55]47J"_a vv]~کغ>"C8[>yh}Vv;ֵ".c;\w\~槉 gd^ѤO) 6#<6A1;?IJQf'oLP+#j-}}@5ɻZ}ĩ"B8>Jbmq$AlX2$% b{ړ. ($UH@^Z* 覭+C]j9LWM==kӞyҵLPWOBR34@x`eW6O0WNfse+גhZM(+FQm "~pӦ @}&)T+A<Đ̄Zm*Wb=La FEւ 4赛 Q))vM>]u=JB0BҔwۦPő0l WJ%4 .Vܬ%Xnm>A1ۺ5ƞnKԸBPuMo.2!Zl1֡4tYlU| @EMEO9گ&\A.T70f eƂ-FH *[Q/4a!nHP8lK^h,lr13 u. !'mz9?.+@kvS%/ٳHUQ-1C52!bWQbb!K" K"1^|h^aaѓ M¨I򥩠KB! A# I׏,O7B0v=6{}BRx!>6s[@ ۟t/p< Η!ܳa_ l,LhH?7*qfG:&mdfUcz(sqIԅQ`A1=p *#.iʻvƇR?rpbWs.BlI8#bp~T4=!6DRJrk&H)+֥!{3(XEi5rhdq[C4~KH7 Q?5ұ:V@.{{{r{Hˉ]/8@ҽAQ@t?[ l?V3'IjT7dD4 FC)%j p{8'˻?a=[씴JVmð)u*0P~efLql7ּäZ_of,8,^'Lä;.t39Ebr1#1X9!5ka. G3Mqr|FDZGdctVO7%Hj@4#n@cj~@xYK7\ؾv&}X7 Nk%;`*'ZTu]y:%@+@|_.IN#jץb~Q au k"e,!jM.} h=d(xw?5U8v etIRM׌L6AmRSNt9]:]z[$$a݆wXTl9uăMرt9(d[ Ū kJ_-^g,gen xG[0p[p[]BU(l ^͹0`~YsSXt'揃2uieX\)a~<$fvp)\ی?Te:F 扒x p(ީMVq$w_k6M5s g1+mw2k .Xφ͑]Xl<6Bu:PJ4i۷U%7N];D1h1Crq >(@C հg_W.rbTVm33c9(ccLL,C>Q9)隉=ߤkӕW=Y/i$YYjTB&AsW\;Ԥ۹  ,*M.LX'(ڰsx@DW-+(Uf O嗼`<[(uuRmMY'*lgCѭ"t!F\2s7FZ; 2FwC|G;ϴOsމK{\=U-2RKom,13S1:\gL } ǁ4Gapj~%(7^&/ V=m П.-(|| {, 9*Tt32vf+{dXYX.엶_N_dlĈ1d WUb0#5{ÆZ6Umb peg暙Y736}X5_>va0y2.X381Yep laT`* ֳoFKа_6|uͳQ_6.Sb܆MX흖E*CfX Bf7aU!Vm :ɒo~'j +F!Q^1~l,T6nVa?LqMs_M 0&7|)}@ J^hewoy#fj>T;"6j3V$,ƍS,}`xH[>h1>_8ԡꓣIJƦMR,0GCE= w.H E!#/mЂ6 1$J5m`m?F$.p׫4`!":.PJ5LH%+Yulv߆1GQ_rQӹ6!u:L%qN2,2$#8lhȽ%wф<4 fc s)@`$2op ξIM;>oc~ǧawQDp;| L]3DE>>J3߂3/Zyw Mu%:C%V5Y`ks'bV\;C-dS,8x0 DRԊϦ *@ˎțQfdn> Y3YL23׋iߠ|pc)c+[rq;>,+/8-bdzD IW+a*I31T8KfW_k oPvǜsٯOra RQ tlH4\n8=>RS OxQ~BTtq?{ѓ}Qt*J~`6l1OkRA;`ȥcmi|Pթ4u몶k\\Ͼ5cʘX;| [4(@y[u%tU[4uIuBC{. V[5|V{Fj^ QBR-)US3ȥO^[)U])y_FL *MI,]e+[j6S7i_ 2OmWWukB(*XŲYwSw]sёdV+ "eICePٻg Is cfǑM@Ȏ Ӧ CnKǍ=Ch["||뫀 q-oFƨگz1 nP1=%jBDŢrY9~v4,<^f]'<<Nk|YLRF ЗU{6.ūʠ,(c"%]:Rk]-u%F#u̲1ꑤ]TrxRHϳə" םQ U|㻫&Z$ >+tm*̯Wz^s/K3qO#*} hjhynMM?ͧO@%VW%S@V9Ec7 F -ZDv'rP4Da<7 Q)p@# tlH%<Y4FB~(LmW M.)lE E-]Q=zW (Xgtc@4-ʦǎ@Ku7_ydr"v3[u j Ё5i( فh;5V g,gBR@,\̵p%)C-야ގ5]vK7FY3݃֐QA,)fDVZxYגixË؞ J;@/bV6r,q1#>@%e{_󙛯e2 2FeŜkWBXg}kP |H{O+#8-00Y3!Q>Jՙ̐n,D!j~G$Ȓ~[8p |Q_U)Y왰NyK (!1{7|[>- >vW=ڳ:MBU,;Ҝ j, =$n °nv!\jYĦ QbdrAH"qAt8I[-Dލʢ)Di*X 4&!EC *d.h%z:.x˵PvYf'7nY[¢|r eN~E(Ť'?_qfmoΞbRqb#W CPkZG,46!ͮt\X")Pyt~2J׵n5mCvbk#'J/ N"RQ'e,l+D] v5tT&@ 0ѵ f+~&ͬKqKu<ϓ![rz#2iЪ+ҺX$y<48b.Z@HakHNa$Ns|ɌOܬZ")6_P]Hdr~*ѐ5a:b[AJl#ml#)$T2LQas;曄F#ޥwYIvS0N,\pKQ 0~:6}t8}A.%Bw v{H'd-uyn!'ܸ'oL5U.qzC@#.R*.W6H}R[:L39I1&~Qs:h1d;x4sک&Q{8to'|LfHV7y3BH]þ9B0%3`7wCUvYݛ!t5 d.E(tE(.t鰱qD˻vuTP&=}[.1K̬3EE;L JovlWҎ<r:h=vq:UҎ|9;1絙R^-<׃ T⸺ ڿd7S;J|NY'>(h@\:be7f<1ס  ~o.'~xcnlt`xL=uz:b7'lt4AbAAʡaZt䋺yA.wq:}:H)gNGNG(8=(-e? ӬQv!#㶎p}n?i|=&yƖӎxr:Nit4L;?FR=OxtAP\.1oNA#O;r:laN7T ,fL*ZJLL/h,M.4_XMZf<] )/yRH}+d>q#ceg@-pD=BvpAdI5JL$[vJ Q+jո&@*hZ݋/8',\uNBf1`k$)e $3+2D۠|͛oBd;y$)2 Q6L//˙ I Cb(@d!sI kgKd;6!p> ]&xifb.<=d\feYq;>EpX5X0MFn)4ou!h{ّ^9pӠ`X0M7+sNb|kgo`bσ)zwɧa{5'Cw!2wG &N 3 `RN:dzeR3cb⠽67ۨbmD{n6Վ$O|v/&uhgú<m_=Zx̾9@V !<3Os=8ɞSj$rxgQvW6sDw%{~{} z9]/ySיG0egD23 |<6 ud\GՐu"p<+ Ӭp֝^da,;t{N?_NfnVk-lU߅pnT#`HP]Wsg|a)_vl(Ei׻ρKjR@Xv6LjɘN|ym&%g:7@%܀f p a$crYK7F BH݀L`Zy{I"MQf[n2VG-衉hj<3M;q㹻64;i=Tq%o*Ě|Я}>eoEIPHk1 ^;܏bYL)I8_՞?q4) U$I28 eLx2{ZKeddu+jEx!;6JsS|rI3!ˁr4? \&\[r' }UMvǥP=N-]F 6h)Qz=U$c/Tt$Eg? +4rE?t`|yGΪ)9*gEyUj8+qAjip{̏ MGiQyY5q@P{V |Ҍ3OP>Fq} gYc j8 t 8-7R ;g}ph?lއ1X;Rۉ'_>sEx;5'x2ebuboSmqfgܴ5 _~6%kcdZKr9m -l"i}llBzz n-nNݦkRׯ%ܴm%?0F@@ϫ?>ǧӋ+J{?8 dCl' qm@Gum 97:;S5@^u3݀=>hV{.VP^Gb33D֬Uگ R9߹NR4\EINQ1Mz_بC>'s|;>וI~A#%ݶ,A+ OMOCn895\U\X;3 F;Kp 'A!eӑ3iJ6x%v7pm+Ds]u}o :sH_맟8ESQ1w{ 7GfQOBVc>lD9<%K}+_mh[ i1hc[&}4?Rwش!q$h@O >}uNknUAf*%Ju5m VoMCٶ¦4j]}]ޛIWVUCjvaF4sQ-}u7RmomMp,Kz.,4Vq^nK `>ZmѺ_#7_|~ H|Ns !84Q%?߂;ķLʙYMy ՛-`з\  y0g|[sJq\ 'շP!Y;EVsgHx4^/Wb^m;DOsKY=%Z 3jn<ҧ7GʷzK%`$;OnL,F]WWѫrʌdv_+g숆PD ?S8`wp"ppVBgĠZLH9b:+h G'w W9?yr.0ZlOzl{C]W5,ڒT$1w=;WYȲf0kf9 W#봇z>DA^_Z(gO; W2ڦf+׸*ȅ MJ>y)]0J6tAQ jwE Pn|6Aƪ!#Q㰆醩{Umf5! ɁRx }a }-|r .}vzcS`Uv-ẫd#Qd}c"5/-Β;+-)P I@3oW+&YbUYЫI½('f_eQ"ԔR 8/c4.Z>XQ Uv~/7>y#4vQ˶ 1 kx (cUppƛcN4J϶3a<Ty-^WR%1h!X2Tf[74o>\ϯɤl '^|Qʉ)ShoPuu?Qy5p5c0%qXc;qW WkGs |-NqW+h\ sT^O ( Te)`z x?A3Tȝ, 9q8x[y m> SNRd33A]Yk#%D"^T դ-Cai>Fcjxw URLl,Je0rIfː!axc|]*ԡ7_z2ib:5iZ}">rV޸iطrW,AA9"bFuivaQM_3St.R|?:=# (všV.~ܗulkثdž2j1I{ t}[CT]T>4h.-r!]5gHO VhAlxZ5QĊV`58]1.hσLw# =ԾB{y2 rBJ=\]d4OP`ݕ.}uQIy@Z .E? X*X1S!;}yxLݑ]Ѧ>>Z"-R^H{+j/[u?X[3G+V]ihHzb(q ? XP|b9 I5,yn^<]uRnH6g.k(^Wd Ŕsܻb) ʅ6UNM-x(ȬTZ,f `J}ņYh -S_z\ aQ4N?%^bB0Ŧ4?pup}oǵWmz"JBy˫F\zNNo| zk[/2ˢU^ ݔaVݪxxn62n|6fbszje$Wv{3sґx4o3H] oct1|=;LJ<][v%z3Dܯ; d{Kؽ/)ӳ&<0Ў<պ#2;8Ўګ tlA'#ZW >xھ|Y,r8Gv| jZ$[o({ogpN.{'בuequb K VW փ&X&S>Q+70C7t YTު^ΰ4z I09M#MR6)t"/nTP@:9G+u693w%L4`8hջ^:wkv| W2=ctpׁ_l'u2W_H(v"emB")[0*5*oz,HPr3U fl@]s3 lAURf4Cԗ1xy+]HLZ]`Ki V E#](,u`%;+<iz'o]:u ݐv1lE)?cgU,!{ b7$A$F4L!C)Qp:FF73_:iߺ|5)ZS(> A_#\Hb`%U BZ Wʞ{5H⛂t*޹ݹ.t]/l"G* +faLVUC)l+HE{RǭdH^W$A4H&"z"y>Ri%~N\X,˥dzWPW&̂\}\W2[k4+ό+ 4"omx a`x"(ЍunlA7.W^jӝ0U,KwYR%ݔ NgJMXm γ)uށiMNJ;:&;hKU_6USMwNm9es/۝wekz;Vqu-r)Ϧz CuL 9zY'`4m5(-VjRH(Ưr`]"evjn 7>N%V[CE7 #k( O7NeFJ.q-g5lo!,&jt-4G8h$*P|iLrՆ._ֽSPvfCk#`qJ쑵i=Żyo&>-PhĞ]S,!8 @# ScApJG.}`:0-5FSjV3DBG̳.m_WQ0>m_/`Յ4^`'13 dAoG8'ޛr0'KpyY:9YfYWX%HVHHq޿dtIMM6o";Y4x7u/)^]iu9}v{m&RITAUKel册8`@\##`'Ek<e,qҡbnmr8PEIbqVƷ5jXKUoW$\TbNhZDDrF)gq1 6)lA8VQ8) `xW܄h۩J*3FR~yJ!$I2[TZqJb""h dI#t`; XS0.e Y8|GYMќ~3WV2=`RF3)ҕٵ_2~5ɵZ˒ae7*%œ$&R(.yqhc*ŰaoЌCIЁX>NȎJ ֫4 vV#SLTtkǯbbk͌DO\aXDVOc׽* AA]ut(n?""׷_a=t'xD)ѕd8SY}2ilRI^y+)+]s pw|yߪ¢o@^ 2-Lj cUplٛGHe@ \kot<%kk7Y^TY]/@ڐ3w$Nbx05wHU-=R ~@#U=1|~ E 1yw9+QuOlDߙz^u+Wuöka,h_3d eC@#e*x] IX]byxLHæ.ag,ِ9Jhg+t7L`d#l>Pr*](]K `"03)d\,M(i& W{Bb潤sςcW AI%L,Ĕ!NV MD]0jZa2Zr+pZI$d~|"l#l۴S*N6Rl9l8`}mH3o6$KqmL'c&H.m!vlC`cMM< aA3@ 0`vv"ywH U׊`ӵ &k_}W؂g1 ݊sSm71ooo. ~~k% h?Wc XRt@׵ `MtŀkOki J#[-MSRaQ-|9}{[0ivʧΧgӸENʄYػ8Sa9?VNn1 i4){a>-W4*=夤nJ6pnȩ@ ڂnme/㷭p& xݝ^9tQ,\*g^۾ey$m>1ă Ϻ9u}/bM(4d [#_+ְ\XGK5145_U8pfnDerV Ǝ6 Nݟ%||`7f;%zR~qgI)5J?$'$啟f㘖D՗3G:6oI]*zꟹ7?jf#6]DMQv@-֧H&?ʕ 0clIuVL-,/xzo?FXʟYJ)pHub6M8+hTѠOV8%}͠v4E)k*Y2SMyg%jH|8 }O٨VXۗA'`JGtUf=]R޻ ;(p:=oɤT&kwʓ.[fiZDVy8խ`⚦tMpoC<'fCt9ґɲPR=2"y d\x=oW{x?9۟oSYU0(1*iU\h۳(7"xA!1Wb(LPnimTXxw-t'D{z)\roQ]1ÜMՅ|oq9*qI򎌞>iC]fT( Jہ>qF0bT[ - D)ZU.G0?ſ79\eR~)iȼڶ7@q~y#rbM1*J9uW*L,m8ZP3qܣs `܆fT{Jdk%tUPd6>u>:N:ee @~ZN(((p6H%*q>.elZ'~IUYՇLEq>UU IAj'2dr^eqp@Δp՚6/22{K{`=>xx⛵pjH%4f6v9prHqEPׄuônd(n>/v΄nVPCJmlIhS9 E_x$+%l 0Gt䗁'L!I){D3=p&-L6Sxlg2oHLARDgZg1@sgc,(e8t83qf$|$8Ks>$]ZTG5@س)|OQ83zYgƙۣa=k`C@ޗ y9kyCgq]P|&\eDÈd>L|%τ,+g޾Oʡ%Ytv>)iߧ|&h0dtX }󙛪h, +Lh~_ZO3 LR k)ɋ eqrYKQGͅ״j,3gRe^3)i؀3V>L:G3-,Ù)t|fr8r>qs\`6n Wv[UIÜ W8/53ٛ?7y *t  d!ϸ?_5'|8 NpB%9Ө-45DH z')?x叆=9$R]B>g&& m:S[F( !dvXHUl31f0S 8S03E(^V.hg[VɱH/.I])Kt$^s?=N3#˳8]OzA5H[Dg| mkpYNEܶv(͸/ g^o|R>ѯ D^@tcQyFi(Ylһv$ͷd/>0^;R>)ni= Z6'+$3% (wD_$ +=-<=]oFgd>K_򝑒[2;'ڻ롳h%g Iq& ԄbP([ ߸Of-}kb`^cT8: #[oBX8s]aKf3~K..%~.9f.<_"4ዺ[%]zƻ,v%=h^QvLqua%.` @Ni!7nkZSa/WNQ.%`hy3eiF#e~Y^tkW3":tC ͬ^41Ckա  NCcRbWK=D|qh>}WZ/s_-pimqgug 5g#s5t62+}VeP[s 1½a׍qqi,K?Nw/}QfvHj硶VMPA9vhZ\K/4qQnPwMʙj#'n7Y!NA]>qlRb.ϨҗIݕצc9gY[ EI+4Q540_OZZlg#8Ω,JoU\l}tv/O$\pH3DߟA(zr?} G A swCwy# ҆S/'ϝntWKi(EqI.McUw(**&nwc蹇 fENb rؘ< eKB&HcjkX{J02Fғܝ ]>}-\K=4p?@t{5=/)XMbvktƇtϖ:ݙ2ZuZ|ӝ [v&bnLH^֨hÍ9uwlz̃Z!RGzR }08dG6.7 ]շ\6cJeWAhS!GɬYrXįю-ojhP9jk88`Uw?_ =oV^)-RL Vc '/AKmV`D'T&5, ͌5-[Gq[,sa6;e/q7~D  LXo >ŤOt !_ ֙b"E -AF\UO64 c +dy{4eP"+ 5NSFN{s@,aO61=8̖[wW7[h;'/344\"<QY``WdZ5Yfsg˖sZ `磵o|}2fRsXr r[g1mq!k} `$'֨VbKX(@\tm3}z g"gbM(M1&9'w`~ƋY dj;jVhB/%Vcpj$k ECΜ9 QB\yͨ8@Ӝ _= ރɲ@v$F lF@"4͓#FV?&u6{2'+z>p$6̩k0P ˴o/_v #a\{qGI$/3ꙵeG>˝exLs2u/2CouUP!vizVz]ﻉC-ZSg`5iԼ.? qd+mgڵkg ÍnﰋcNP _gsvnz("9 4>jN1\IF˒Iw$:#h+RyAL faj $L0/E7QiƾʨPl5oNN%m4[*;EzvjR>.9h}{Bb㧍^maVmV 0i |8l|2,Aq85n[soX;6?d6&ÌC{D } AB@>±fðfq-5lp SyڏzD|*$"x ddymG\gtXkJ٬pb-o| $k$;6)$?:FJe]/zKZ|fCDn~sF6D,w.K%Ӑ"$;-U#gou3qtu+J2BVJfa|6j%i!0[Y{Po}k&"QZVouN9ЯOgM)9'̈́vW7 9eb\0' Xƅd')ݨƾáhy1gFK ?CY.f ig[.g0I 5z]&gWIpQAwʷȘO%*OB#wm׍Ltii[qx 9d !9RqorYCMv{%wȬ'o=η޵D1u%9I0yQŔ'H-(鐪%RlQB@ۥރ{Jb>1p`5 #E*\fф<$|3i-mC0$>LCLPA#{ p2nyڔR*WRh ac|w;:֜s[lV*a\A쬑˿bqɒ)Z n߯kwc|)\~f݈άaM֜8gs0qjT+|q?X8欹.-`zb=K6r?,=+0p[6f? raY#3ZTSdfZqIȤ̈́0q6i񦳑p:r|wͻޢ?7ypùE6~96feQI/L̐wsTmZ.(C&3nh$׼59sRwok[}EsI.zCmN% ,Y>?X.5cJaOөヶ-MXqa/߾@eOx>.z]2T[0Ӧi缠4L2uEUw^|E^p-2}߃=mG}Z#W>x>u)1ӖM3@?V5Lߟ4n>Mr|}rLϾqv< ELUoA-5`U}xm?6}>(ZWfڦvJ 3 Gmev!ڷKmJ o N"qޔN))ޏ{6&q)ѩ: ۸ F 3Ǖ6[xȸ)$ڐL,uڌ]>sB%p8t{e:Uq aV?Y,k+f} kr@.6CRW2-]݄# fǧz)xeqWY]x;MIp u`ŬV.NjDOrta]OG\\"@֜d`r tmD5k<|{}<޺:`œ\z.4j%`XP1kKA](jg"'*9m ~.~{\:k3%Eƀ!Qr! hhūXL!;{-#GH%ˤ׾Rѧbt\{X`*q]?yViY×ր]+%1z!ĆGܧ@=_6t_n珙";~3l\RZ&==/EigWي$AH0N䦇-0LUI.-Nl;w!OIZWDk+YRmjDDP L ysA\X)]-ģW 2.[$ s4Id=Mz<XB.dF|5]xtKR&؆yr'6zf~6bl@g z2<Qr@\=beL)N\5-:S`l30Wa\ jeUϊqBۅʻQ35+/o1åT>s,MfJM9|h|O}2:UԧݲPرk=CKcv7{B2 /˕Z4(腺v]E-(䌮~yA_MW*hhzX@&ь]RTDlh{Gy|##Ms*`(^ZS!OH}r ~E`&<7g(%0(T[ tBua)5Ec(i-b7iCze[,3_&NJ:km'fV;ԅ3hv뜡)~LFtX[VI7\~.L&0Pw􆒊 f* ͡ g<.Aw:)ye@wexg)P94A~8_.(]ɒHm)6I a6c\}3v0%>dVfז]qVJUshdgtIt@.^w(KSi<²q _H$29.V]nq$ neoXK7=hG!D'Cʼ ~$V^*CU2V{$#-Gm)LIK5 " E+/XDxIkVuM1FVYP]\S%n'NֵdBR"gbqő~v5pIemi㼖Y8YJ>8βX DU-)ak[3q#kʥpu;0nG&Mδu|uؙA_Y`N߭Zw q(%w5 M`/c avp RFNþS0L8Eߣ9 9Hb)¹p]5ޱ >!= p8yOH[Go]2t![P~ꬸakMF/wQb'c,'p@9;vuLʳB]yh=P6,\c oP ypcAp5jh8W[|MgS[[cںسj ݄aL)H"lItM&S>-G{ۏ/nuEuF2ٵGZFK 2PGD3h-3sL35yg&*&w*-~ B 8TnXX %(.J&oGTkhq% lC\HZћ}bh$RMP81eDUɸU+BshUL9el1J }԰fwy44n^Ӛ&L꼳}H_5-VTCgԟo ▱aFOrj`49SśO f;\$SwA<[l g%сIct 3mRp {6+W4 2LKgi^\mU2 6|(ũv`d.OC >D9a-;  J"28b=ʔgWAJ҇põca]5b}⩩}.kd]q۝BKJŴ^.Z59k/I(LukUvk-5ko`2}^i:C̘K-Py[P/_z~.CSRVwf0DhJU*JXlw2}M 'jqn.򙲨FLKQFn^`^RYD1B~qc%+߼M p-#n,7t;1DGfG+Pf1A;7}P+Ge̻GJ`=3s{XhsYY[\PfwB{x]EbW޼\crYom>oIpVg~Mu2É'^RT^$l)Wq-cW(2~bql$k 8~fCD{%F{Πþ\ș@4gbOn>B{\4?^~6C)sO3S\൛a5%VL#j)<) Fłg6.CitYb!(=D}S@]Ib%2i'oT;\<?w/=a6@pk%BM_=ԡ礞Lo5ȳ /@S7$9by6\ 7 >|S?l`pL3B6Yf;&I1 9fExSvoA{̧˟]aU\NpҜ~jFKdB3Nd*amS1<|Jeiܪנ~u[9jY:Ȣ@2 *]6ǺU'~ Y|n;RQrzb#CGRԎ\qDOuBrb_b9UGY>T]j 6#^jϫjboP-p $AZ~Y/9=$}E`%h~`I-m}Z@ݡ%1h4v\H]=聩y481R+{+ TPRN^=QRQE 'r> :> y-ʧ!|||Ӡ`c _Q>4mOӘ᯼+=iJv̛!0 >qT+} qY Tܸ`C9siiD H%}y~=wԍBѽ2(-)L|DN[M>Ûqb0yzcwL]ۈ ׵^Bm[W2. mK p3 =N,B|՗UyZs̞ӵS~Ûw}myq4umo{NSᄚ\1t .'YHbq{Q,bWÈ !pc["?hʒxx/7n?I\ʬFX,7Q2A7E#9pTu*2JrC} +L9yY?5ChD ٷlV2 '~M  h|X}5OI՜'Q\G~[GdҘ^\\=nbL#7Ä ߜTjL.zE%d˭We~!ڭub/:ICAJUSָ,C̐Bd[m%5bykK T.RAXL.rf:/NZ d|'אY߷)˃9W8#Ia5L#淪Qz# ڑ!P[9'MEW_9դЊd+jwfJmNh- VE49`I2:LldܛR*΁ >n9xA^- h-t6ȟ H-جl*2M$-%Y*%3M%Ђxine-lib-1.2/misc/fonts/cc-32.xinefont.gz0000644000175000017500000004037514647725152015763 0ustar meme},rvQCY$Y-33333o133ԕY5{`Sܞ/3??zH}Gs |>Zxi'}ZJۏpI;x<86!1=SNE/:;%߷HLa>뾯+;&t u w9F~|!?^ai}$^50XK~ZXk`'$n%k%.JlK,q;yJ}ӬT:eL/&l~DZ @ܠ36!fJ;7B"OWW"W_/l JI:OF4˶O'+lVwMi"qx*!Sxh۱ 1 X Uezi?k៚s8rkB|HD<BߧjDAF YҔd[S9fZ?Z3M?** BǦr%fK|19=q>^IW?eTXh1DXneW@VȥKd{&V2RawI9n9ܒ4#vO._mץ+OVlDH>?tC"[3I"ts_>u5AC8ggv'n{>yYTY%_Ǭf>Lz4tb01_LہV=x9#pcFbb#|,obgt)[Fv6Dt$Ze:c,toI{ SK$>J>9M :Z9bTT!t$?H͞iB32=nFP d<9))cw1% qp'=,1?/te3"'bJي 9 ,pl2\ D/Mf"xb:J,:M`2R_sڷ.GJ2qJI9tDN8";1|.rDCGD9".q^ߌf\vDPzb8hzbML4qϸX <%^4骗G#p j+X_HdYN:z,JHYCe!XAޕp_!ah77fgY|q1Kj jXs0C1TL9?k1¿Pu|}g?Wie*@AtfڸoatiqȐ>O3}K[] Wgɺu:>"z s|{f'mqph_r򣐊FZ|439엌T/E_ngZS̕z(Bt4Rrk{a#[:7kCcBR6̹IdrJ9g'8y5rم2rb S%Xׅ iL|!igN:O>#bu۪T}!?}IZDSwqm1Z"nvpY\y ^@TpsYD9zU|h扐21䁸D%/4G+ ]<;ռg-i*YƋd0_VJz{0,  @nA|{|ƒ\NU=pJ=ⱛ A͉.QLTBqat  cS\zD_WbpCr)u`•w!hМ`0}zL!]+]+FKtEh@"NΨY "ܡkܴ68,y\|0"Z_Sd7^BNK,×A}fa5 08xfw+ (c 1FX[YmL` ԙ4RL3&b 2,'}s|9ai9bax'a jNui$OȦ0Q{Cp&phăBmUe>߈Ⱓ5_˵I|z%|Ix1 MxP'|蹅DN-\d.UvpQ5Qe J1UhltZjp}=N@ 6-XդH J=TeV[[Bs"6 ̩x" '*"baH*"fTb]]cKŜ^s*b I"VhXϫ}{EmVh(dgBic*F zc<=DOfTDd;oYVw{LV+H_lM+60#\{żc=l]qaog{EK PK$#!BwXb?f-.ԖR53FrοpjWM,3UYjSJ)+ /ݽ<ܦF(`"0=j0{=PM"범,FCi#1C}9((>*i@:xFܧ'aAv<,сO.R|䜒 B#  [L6q4KwkqDj%%b6r9<6TTb|{=f7)^飓1m ̓zJ?lziW)J 7ak ZM 02:bӘ3Cti,DkBYg2et[xߎ2K5uev86vALؼh&_:.w7!^a0Yh2gAk(ql+忄8\2ysȘPޟ}(XYCT&EkVw%~y6FIJ4x2̵Y'ϸOC @I9:foˮ0jHS!J;..i[<]n?H;C(e& LZ 9R/!Q+!KdR/KHxBZd>Y{6V؏˨g.ƫF w/zKHf5ءX˜ĀS] .wj0;r%l_'ksX]M?6QK5S#;&5wfjAkZ7J=[ƺxJec} I͇wkUZxkeݫ XG UH9uBv=~6\'UwAcJ%iÛL 6Otw&Q[n,~Z͞ =Hi3o?(IaR=EAnw3[W78EYd@ͻCӝa"m`Dz><|N ;:Bt:Z߫0TPOPO(9xn:W>-†V2 #ճ'Z>C1b=\oʍDޚ kTbB=E>!8Y$OV6׷1LBTjэn6y) IԓyhT2/7)W&5saGaGO(g0](h6m|"Lɤwwj9!48w,ZuCS&$u]8v !P!NW nX5$&*ga$+qClQJd0X)](o51APW^& ;UH4ӄ{n 5~{=q]rVEreTM) y^IL(sָh HZSR+k`=qF|Ѡ,kX/[Lg{L1Łf2!M}*;I) 8]Kc3'\ZzH.cE"|Cc)[[O(U#=@c۵ܸf}4ٕ∼HÕ3[y9HFX8ۺNx\KKJ=QYA#*F)nL{+f"R pU֯4~4kkKbǫ8.^!u@}SbO1h׻Py»Vñ‘G ELf)D랢[ghrzLz,G-n 6281Jϭg˝<3q*-pnh{8̢jdjOӿT}ݒlz*uR+%^]L/ڔ/ҘMT*AE`F.P 27W\\,r,lraٳxG+8~AN7>8t80'zOV$?K2':y 9*"{ ,؃CN3(?g<֑ua-_L_'ЬESjlaZ0piUJYVrp>.E~p|!qXJ-!ŁFbBrOǻ=-?!Z}S`T'6rDi;R2IfWAQfkIOd!ie%"g܋=$3ZdaIjEޚ( #2d\j45l$9NWgȗef 3>#^kא DR`%o#]煅xBΞYCLM Ǫ^^E ,\u/ɹeȼMe],Z$u#=[1Xgv mOcɾJjt_ԎH&7,"^i6!fi^,6y' ObuZ@Exh?chyхvT yaQfnb4!+nAC4x]i'SQz`5ihc| bbQ]iX",Q!DF|&̛/ҋ馔jr.c;OB|a拌N<.c8kpjm՛`oRS8AcP>kMRILX)rFTRĊdx^;NyA'qu[+zgPlZ/m 93ymA|2w9q2сf;e`_%‡0 e, HY6Ѥl4&grԆ3[ 59iX##%%TǥjւmU,<"VTOl!{v_ ia'. lRJ`۞upm/D[NMZb∻ \֕[gIa1֌u%P^5ְǵ.E0߆C*W!ʮvyO:f;!Q\km_s]eWp.%K@rkUTc<dP,&h \-Û|۱Ľg F*(R3fq;?(}$xHyQOPi/ěh +cgxX*8"tV6'բeI_d`VR9M x6촬@Bhey5+@ ly>xFT7Z%2]3d ۏ+¶n|*C8sPXZߞߚrœqnҡ]cǥ]3,i /,!xhd%k4J%j0Ze?s$BU7% 0(X%ftmt@M߰F?CRm}CWDZBغJF{,.j6Eˁ.-ͩ)܅|qe;C<&\:V_dA9s=osRȰmwm&QjdxaJ 47t#vWةBR`xQ?si8w:Nٝ=縹rCmka\?uqBx( ^P'r#ZG?a gL]( D(NBebRm݇/!?(O&e.0Za;_wވ@S:a|muN?Takv`E B>;GęM%^dSoce'HUbIKG삺aG+RFG-sNjXy\XI7VN%9 |N{Pz3~峢;a5D'M K ?%}+gXlg]XC1 E|G,'M&dJSgC\C&/}0Wׂ= h )6pɷdb>b5,6,E@R 'vf?çvlo{:/Z=S_T1,S?udhEF$5W7>ݻэۀ`lSQ6[Dt}_8"`eA5ͳ O1^;V'j3iܰWbCrR'u._r_{ܰ*1@6.}`]]9Ge./a+ k -'D,of<]^p L&cW=w+$ޛe7hQ'Lw%5jMI D]+|D1I:.x(Lܲ]i=JBxsKs[}'H'j^u@㗟i/V`BJ Ml*^Vu9S=Lu:$6INp{"f_Qn*?)܉2Uѵژv2Jdp3s࿛I7I!fgx9%\ w0u\@ %pҰγir'~逄I[[JPCd,|+;BMj.դNHyK)HK^.jzWnRՓn+iq/5TgvNX} !@eg@!+WL쯵H X<"hUT_+u;ޜpRsmü1Fl]M(Y!?K2zr-hhO$>iuK!y"QWZxrnqgs4wv aU Z θsA W4jHjh+m V=*W9%+=^B\>_F%E  *Wv5wkLƬ+EwC#vx{{m"=:']~ɩ$fU֍֪*k0ۿ (hUUV4:Ȥ+`QY;qY+:Ee{,*+z*붟fU־S_)m=A}"aӬ35 vWgƧTzw xjacQ5c sOĆR֔0uCxK(qREҷǽ({lt'ֿhege_cv( }7VưA[KKuQw,&.FEfY~kTP3vjxF33lsы4Ӷ|"b9Wr}*I[C3F>S[?$|[a0MTc'4E;^#h4BԶZS0ө^XPta .E6"*sCKQ4a&PW^D_8uEqn N( #qy)bf~ j7D> B_=os];0w(&H nbWw-i?~ۚqLC==pYLܡ4G?*`*^zi;_.hp?FuDAY5@WH{'4'j=:WJa!wk0i^v#hiWJ;Mݕt3=yyߐ`S @E kX3i0#ۜ8|@UUiа|1'y#N}O񮂂] I=/ H{fDQbbLڱ*Q[z"wn{r/D\yKQ$*D(&-d0BnX`#AS:P3Sɗ{8gX4x~GJB@6ĠcydŅԭѕr٢ _NRJU^KU LD'+; j3Km| B=6=^JQqh<%(&Vpnx{agHOG iYa5Z"+E F)<ćE j#$n˺L$3[¥՜t'z%iXɎD|&y NEf$^+24 :)cb}߷pk(88Ý_h#3ȱ[1b'"Mؗ-ji-kR [IK*M*_dv|,?;rK? LX$Z n ]l6|b!Kؚ\+/%-sߥ,m5YWv/᲻d61*vh3[m&Zp]ֆ65:-9P[!=(P||R'<'LE3ی3&ysɡR<ę]3'j\Y ̝{Ѐ)KɧyNΤ#gΤ33=\9 gnS3̉"8 CKDqt; Tno` z.q4OrgW_Kgc8TV#t~G3i>Œk([ y yz+4Tt ʾ8{,{Yϔ\iޞ4?.5q12{eX۷3OB!k2ObHaA~D1I{gɣ򜒔k7)mkeax{^=i=, lT$>2qտ<@GK۰ԁ&E,JNqSGR{߱{uۡ,B[>,7ѮnӼlۙ^#Fp:n~ȿ:^,^hdMٕ lOsOUŝXba!bUw:wCxQz%s)୕x054Uy2f]'ʊk}FeLjc/᜖I@t_ל}{> mr˶-*)$qrĔ 7D|>ȮW̠=2zyGyG}7?xov:Tm lllNm%xs؝VCvxOjϿޟ{#Pʂ9Qzqו/sꢦוC`>=ЋJ|܈5R>xkml?$OIEiQS\XQ.(CD=S]E׳n6.ƇpC'vKo^xQSeI|*z4!/xπW\@Dln "3 QJm(zyUjN>=<Qg1K9=(_){2sUm i:CNA#w,b~L9n*6F_e5ۗdPi3G 0o'OR3*3*Q7 t=2M?0A gPDk<NҤ+IC,EL.E/V/!qO%N8≇gƐƐ1$$Ǩe+(u8>Ev 2{K̎-rXLp:ndz"Ӿn зJG,dL9kƐCUÐ3`>ϻO@W`r љC{EVqCRY7I%"_ypFSIS]ʸS34Du|X#Cb'6B#qƟݟo<ѿ /A_X]٬$iqr0Ի,WxvlKy9KFoQ#ִ-jGWu11a2CfC3>y- Ɍ[!؊Η;LLjyHBP˛|yʐ0tWJǸr0Da}|faCnuR+7%&WVrTT]Lv*_[2n־Gme(껈)[?{ zC*;00, J+'Gp&d앶 Aؽlzt 鈻=cQ]6Pm*#1w=MJ&khI௚Pn:y- j3|3T chn*08YRX][% ipe D~b{xS9{!&zs3J~J쾒z{||kWN^98mv6q3s{AϬV:tgf<;r6;.3iRC<`~QG X(jh"Ơ(KJ¾FԈM^%z'*#!(1^7[beQlG G3ߊ2鲭k^@Bt];#wXQ7oΐ)2@^uq L 8 .!6HƝ C\ Y^^|"49W'N+@ +2d}c;d*FMgZ{l/rXꕶ;ZI.|#!_bH1#Cn'͐W gv+BCA^ԡ_*Ai rX2Ȑv ٝ&O~Eђ< tW? yh@ z9 q#\Bky8>T=&'V;>6(b!@uʸ(c_ x>R@ɥ`oM!2:Aw.uVW՜L=[I:^2KvJbK#tH94#rwߠۣc.Zb(EU=B[}H!jQ7,9=qA,spx-m,S\Oe|(:muNLaܒ 2N-@%;6}<iGc$NW#*KeK֑]v_L5ߦ f՞ҤV%4}rjL )Uu!.o$@}"ܦ ُG dHuC;ϐ i\"!׉ܞABn$d%q_e i_4Xqt_\KӚ/'!BABzdiJd"^ɨ@t u +$C猄ٕKC &)T˰ȓ ,>c|u}M7{w/{u@R8ϊ@뀤$'#8!޿$^"2‹Ch1B=**P;Zh릺oa=PMЦ%.J!dAZznJYnE<<=3[gL тBuc@?o R cL,r9=P4f4ݡdnXSEQ2h^蕺TF%gpyZ 0߉ކ_I49ٸb:ٗ5%A)nP9z4- /EP&k"(3"(Z 1k߃1o"g,6#FQI6  Z`,ŔI,EU>o+'7-12 U^4?\,24ɛP2^C%/P>??;C^Do6O~ECwO4Uܵo _~E7C.N̐ƐwÐCC?=K(*CI!2KRIg`5{ޓQDi0$endֶ )CVgƤZ[v #:q})Cyxn>l8z; e`mjh&Γٓi8&r *jvƖWr[G#7D#h$S 6BKE?ѷ H`E Jtr`RoZ4r.Պ-W0|Zy*%|a?đ$!$15qϮ2K}M\dW*1 $6u0=Q̑X"L1*`4ڥxMvBtsjreoEO̐LѤR@0w,IƷg鮄OJ6O2^i}3$D7CJ55*yg;hUga3L<.Z.3ԁƱ:n\ ^v;x=NMt;$#S;Hf:P;'.uA2=z:6OO=t~ tx臯y:lfxine-lib-1.2/misc/fonts/cetus-32.xinefont.gz0000644000175000017500000004122114647725152016510 0ustar meme}4?r؎FҌRw>lc03330'K+U8Taf '4o޷{Fn%__e%>9|a(tcVx}\aeqUu]s%S~oT8b&d{d%?ü1$x0su :NW6F< g{W|ۿʰOJn|e{s9#<j[tJy lo<\OPArmk ,f訓a&auY q5*[: >b|xEsjY5=,}ućkݱƧ:k6gQ*yY훗 [zDGoĹ?qFp͎Kc+SY6HL`p *m&c "Wm+~ $ɱ B,pJ }CԠ7>hL2 髐d0I3 "U[30d<ԏ *lkԳ hDCD:>Er+k  *~`.'jێ3C \rHnVjs߸uwNphݕay{fۃ`6~RTnbt}նz ;K"u4,yԨR_l>N~-nllǨb!NܷUCŷokmv>/bMO Fh hHv얯~xC'lBY2 a 0,X*)]mD4\ZHZ@iVJy \ݍLV`a"ԅPŷhz2T5bқF,햪h½^Tl\Hz3/ <"qx|}n2CEΛTԫG$<.IpF~ݘ(E u{}ަѻG;Afɵa5[!E7#=2eeRvo!5n$ol|M|iRJecnEuFP(%Q]cNT!!v Pp[@ :K?ALtmeWެ]MVw Lxo76T;bM|QÁTgVE25n@en|+A PDg@Ȋ7m/+/ ?&+Ta[m*;2׻)q]$l,(U,JbSJOΖ%-65'hSm4ԨhتifٕXcKc^:]m?̾ fڮD:Dcd +PY%W-߀0wC514CRB6q3Mlӡ%cHŖز+ v.`,AX/PH'hWXja6᳽ENr!eume7dY &091_lIyq|$+R `܆0t@t`$9">ٴx`O|2;,t+`aqI Kr(>U] T{UJƵ R5~ v)7o2֏6N*aiщ` Y7dKc$৒;&HW$A꧰(Ԥ[^ /f:@d6@Y,<?ҾάC3t1ߓO}FkNjY'2Zm>-`8ٹbFt6+7ߐ.pBƌa YgtO24\}T%>, e¼o҃ଏDխМZ֡S{8cB}Y>h/BIA0:D@o|+Nn$)n-ji$?.WɆ'bsظh- nK:1Q GQ`xM^߲axy3Ļpsd GeT=b"l5Y.ig *EB<8C͆gnhxܡ!M7Y7BVv6y5H 8YIft k‘Qx⛾Pg1{DB2s ~;#fyP¨@ĻHtՇP6Ȳa{$H }Y=N⺑mNE[q7LJܢ#DI(qp|#$9G\@ovKUyxϾdv8zɵyf&Yb=&ВpʾųFE!YY\a l-"z6neܗǾ6kK/zpVOR#66u&QWW juPpuFuDDXvX4`ݫ}cܫ{u)WW:a N3Թ̻5ljZGޭ1:ή Yۭڿ::m|W&zƎ|d*DaQ^RkY`;#"@=%+2P'5J0Em̫Va@9g5-90pFm[6@lv^O (OFK|j L@|P^S$J#>Hlֽ׸!';A$/Җid!/BS^<|o@0cEƂ`.7g-T[ᚡkr :4Bh'  U`1~+/>랬Dcӣ6 DZmîzAO+_#`pP0.alQ'V$6??[1_ѵrMmgq#Hcp1)'S ~زW"Þ ԉis:"/$v<{hN&ىJuQ^l8H.X`t73=ĵYL؏XU`Mr(*FD'<rbqj[w+C6bގ DXQft <쳸x0Q35]h\DM`a3aH#wPGɖpč-B2^aD;;r7ֆu玦F(tFG(AWCI\M xT kLΈԞf=&C'A2lYmk%E%One;:bl0;U^|[4 Cvިէy[2 ;h+ñGCj^]T#C54'BioޞjPAi 2!t5|ߔ&A)ɛ%@pHwIDHf$bҩ* #08ɡe2(^여J}L3֧IfZ՘>H'tV&(Q=8 1OH죥oкۣlᘱXXlfS;6 {̉= Q8!餗 \kYSRjUPQLjyhG&r]ނW˼Ԭ2;ŷ&j؄[w}:ֱ@n_v3}z݃覗!F"#QaI Ǡ YΘ^Wj |7S$Me՟Fu.-FP0 ipʥ+܃ހނ ށރiE74 (LmKohm SS ;ΔjW\&k¹(:D딴%;v엻v'°f2=|g$?]rGQ9F'*ͪM=$di+MĕĨjef|ٴ R@*]L*]<"UJ?+9J˃\bSSIi)aSIeV3ل8J l*1%tIVt40N]%UV_rYJ!$l۠|on7\U 7>\N@҉#D<"W+Y\Pj_1k9_aV 5D>w W w#.q+PAV:mbWLFK+fU6cuv] îa߾wTuaQ났^7 DEtSuHH7aw}1;̝r]%z0_/MmoFjf4>@eQ<%ɃRg-I2%D f=X:J؉h]%/p)d2`ĉF1_݂}nT } m=myD1ZKr$BAMv2Yw{nP&gĺ@Q1i]]29MMPKv+V ǐo-? )G4 %Z):M">-rٺO.it v|[j2[£`QclKpYP?Nte0V t[vU.LtBRCK<<2[C L'dRaGEW=svhkYP˰Ix2 +uaR> ْ̣m!:7kd)+NahfyN$׊iɷ"+[jZіc9{̐|یߞI0M+Kj}la>4jOzLn;:8k+l8ܯW?nyqSx ]H-ܚe&juotzxm(F_FiMtjmu>q:ƒ~ cnAM֒[ j1 9nXF9tYVjU(G}uhS>3ս]s=>3,])YOTFTidDdjd:b5G +.fT'Q$"w/3D8|&8oi>P39s^(n-+j/rzf)D"7-E{l9蔡G>t›{ywKcWl^}?'K|+?z.Ͻ+_Xٌi!ƨU̜_;KoxsƦ ߟInŰW-ܸO"fp%g[eVWNݚoL|D Fȹ5P =EˢI˺mΪ1iBx 3!W9/={PfI^8<¨hۑc+8fFʼnAځqϼ\g&w'ܥVj*2vp..D^ t--뒑tT.v=< n݌;kh |Ua-)p>q}=͹d:8& π\Bx7!Q.I0CNLkDQRMZcmCaW ,?ITV<(I$c>P [Ef:9BN.#sx[%lPk%_fīlKIub CM~=p;!:jĹObg!oC٤% )X8yR6 ZMYXR) %Dypfa7LؙS ~SUQ{*m[5Y rKF=!8a~Th/AFv1i>oT#Ğ-0Y.eg+ѭa~5y&W8|^ȬtY,Cj*zL:羘MG&ݤ-I)U&OgjɒN:iC_KJTh:$><ɛn#TREi3N ކDnpXDܛ = I0Q8grQ¾kdt`B$YY?U2tʪdVA ҉,WFj mOw_@ W٫;ALbᵆ^OAG^鋔MXTq& mcjKvά6!f?D7 ll~Q;F{.XGW$fa)be\PیxHNH4Cپ#pj.Ei#1 $EH٣MeMz#\x ?i"V"k7b9~BN"A) (fya%PLϑFD4iI&ڏw$P򱴝BZv(N'V&Bg x92M=me>wca2YQd&4$w]6.fsUr#s;1mxvVi u|a[7oiN@oinonHGo`oٹAoٽo U0Lb~\hKrO|mymw(ۦW#޻~yr~rb 9/=|7g\7p&_MpwaJql"xU Z Dmk)Ƶ6 qp_vx[wrg?Fy@G>QTת;S}Ǎq xZ]y@79 Tw_[ݚP-:Frp(⺊akzJT]Fs{3KZ=Szn=&'&MoqkvƲ笩؆mpZi^8ΰrpa5]f& qI+ $CƒW~$Jiƅ]\$r^q3q+'L*Ef;Ec&:E:  =•:X1r}0xpÄ}"Wniƀe=׌mK=EZ̓a@Z-bRLpIj]2I&xY(&FȰ( >],cLtE9aZ--<? QRler)NCdۿMxiKşŀ{L&mol-g.k6DLQC&bSI,ay{*p,]S|iHڪnlp6.9Ԋo;L+zV=\p>㑻_}3%}ƪnMԂFeYv*PO\y(,#ˠr pd c6vV2+EOez1tI AʙMS\([S^sZ ҞS0kfC>OxhǦ_(*fWEժnC06bwTFcSw{7v'  ^x}-Uy<㌀_{p;H &Sh8ʒYHH́X \ԏϨX.d“Պ䆲4_Igq5o-QI<+l\DqFH \ wz+Wkd|)3<g\L!4, 48U̡yaW`a '0*'>~#@U+CŒ@krMz߶{B$%I8q;0\֍mUn3Wtx"~H7 @M}Rs VhӶhWsvmsn 9gu롦߰?uC)׬P̻svYJQ"YdA44h]f]C?<;^L,(9/q۫1KKmK+}1#允OaJMwaž[aO/UTZao8!1:NA$<5 *,Hp$+!Dl(4fZa\G}Km e#?G߃a2I {_hWVC [p]7н2{O`T%W^JY:_KY /\x~}q/XD&+2E>QyW9Cʻa\ct]2bf-MhϢ`K [g(mƷ*mQ/1nq%^9H?"hK$'v^-D)}!Cn !I'Rg Um2dGٳq$mOtH+**y0>АX(g5OCih5yn%,")QaKd Y={d0|ܓ7hzr[' u4f'}EdxJ"X>^g0cIqSXp4ZG q]Nyxᓯ|3@eEr1 I'V;%Fw3uEVHF;7ԇ,k֢~3NW><ߔ HVP)XviM?//h+MdC^yR6Rʒ7FܯI%ހVJf^G֞vDfݯDvy!j!bw7YY$/ ȳ5j`VGAZ#ߏFCQ)n4jWG{BϹ)ĥ%ZN5&V]bvc$İ,/4(&+*m'XM攑ڪX[#Ԧrw3pإp#ۊ%.V.m]mRm*`My.AMkS⭁Z͖D+}tI+NjhmFmZ}6mUbD gm)Lg;|,c"..ZƱi'2@1銬G$Vtn$/Jk,x {#`Hj/8@+%J[XY4Y_;%"kc1AձL>c, 4".WadZtuI[[ 72U?ȗFÈS;8=)k-+u&]n"gG2ҫxT3!b*1H eK/s̀ړ^ցfZ41-Ys$uBwC _>\ TEkeW,dÒk_ӵ3b?ӍICZ{GxB¯|Wtxnӿd6ܘ9o ^A5<*\Um}*^"-8ɷC(b>xZ7`Pè,b|z݇jt <͊$/miGwj"K9H>&nL MmT.q"GzxUΏ4TFC}^{lrY4 4>soåkq>w ]* i]FQ;da盆IhȤ-l ]LC&ci]̠p0xUuEͷHd׌&SmN6ljfj*I1ՓH7KO&'^(wS RvTӦy[];buclfX@BjUӝj;K5ld,=d\<6 {s:u(ۢ4&wS RTM aDiQ.﴿_Wwbx00 y{9F{ ;T!E#dY<s0 x,j1h&6dA5m=r_T3Q'}: 7E`LC)ts?$u`]u+*/[:ϔj>2JZ:pJ%{o#v i8W:hPGP bDp,iƠv?__j:xP[ꐵlƠ_kZKE÷4!ҏII- h̗Ń`CC:Wӯ;pHsK+0:\݂M|o"%ytg R8-BfD[voQGբ~[B RiľJ =ؽg:Nb*MeQ{0ؠ [:ŝL:-o&33N>ų'-[,71nr sm.QάQttLW^Mg=,L0$i"!` fpG]jN75sόkȹy"Kp5LJk? ΂$ }Ά lէ7W?6A$MeHV$I꿆&\Vd, |$ =_NubD*FC1HA#w%/SKFi$]eGK΋~!|5Ç>gz{-Š;|.͔;(N57F5QMS8ï {?X;zߩƨܪN5 S͍Q͟=gL )'7[\H;D+NȖkE=_2!x(9RqѻìK 1arL ¶o(y4+54_L5=$`5yµ?8|@{-ߴK}kbwV6#F.Ir;1Ġ\U(j5fNAJS`׹"5gM׹KyNeGb&iY,ݬm Ux8PsP!߉Sx3/#Smd1khQH>~"1 |Ki4[_1ArLF23F_11#޾8f{z>@;=:C.c!KP*% ( <O_`V:qC-vÃ.'2eDt/Y!>AFtPDt={tvMX!^^B~"f8mcmj> v0#Y r8S GtY!Lm=a|%6!>)m&!>iJ6ƿuiGVآ jՄJvhQFP#l̃XlBg, ̐PWxl p^rd0k܄vᩜk [td iȅj *A xr5F0hF%smk1O%$H'qMrݷ7t]H8s2̩0MR|2~WD2؟b7O'\J_>&ԠifwKNĻZܽ aGì\ TpGhM-,RETjg%h]wPfI%d6ZK`ՈLf>TkKqɲޚyn*F/,2fe}@ E=أyoPT!w ~ 4kB~vexol#Êƪ= U{m9 7*$b[:a B6*3\$Z f y]3=; [TI ft .5o0kuϣۊ4=;co36Xgm7:4)o+4H=(MCQ$:FVQ/jVF'-+VxT aHQEꗳs!G=GsdQ ֟)"Ѧ!}bUqA4["σll0l=MLF!mZw \Ppg 2L }QS 0Xk ̤Z\PaM<qOoߎ<:o~Щ-$7<ؿ5^:XeieGږB̆2lCfvy4;ln-I'6NS "nmzG` CtqSgPO{Ugc)Sq j!ϗS9>cF/xcƪqԐ~NAQRI9Iپ6v> ` $tDQp"8"% p1jxr3c8}o. 1>+T .Ez`YW ];qO52cHUnϏ)_eC*:̳̘Yq荨8FL9b̀j[˽,ƥ[P[CP](jFȴ[~Vn\;^Xxine-lib-1.2/misc/fonts/serif-24.xinefont.gz0000644000175000017500000005555414647725152016514 0ustar meme}r${pn $'& 3c030[WZsݫ^]]]#[X޿)/ԇ=mjm-c>%:nN e+aM7%~9~ǜsꛏ|zcMs7ſ^v ²(U"%|Z&+Q!Uqzgd<2=m">m?lk^OOg';1S@y5SZJJS~#zPFh3/kYCZ״ש >NAeeoc'z>-6~nXZZ2]je E%J"ΣfC\1BdW|5C0閞~N^|ןQA\SXiR_OG?lG~{oE%uJoboS h4nfaS[Meފ3kVicaSvDw"9R[tg\ R_Nh3gyp}1~ T?UIܿeg*Y<4 ѱ>5gkn>ED4q>SH֊δx6=3]__m:ǨN94$"PbĀx"e&;"H+96sRy3qvv[$}lěv1j}U[}txI_ݑO(+7ƃ>{1a_]BYZROUh:tG@cMzm]JYI ESCY&PC-{v]n7|$yT_|ћO?gm½8}9j_%# /HBq_1$U[B P7asWأŽ5mNǼ吸e6W˙Ig}΍.sծ2ڵ|цԅҦsb; -$?!!߀]pX:{kOMrW)dz3g߬/HUw2xj݋~ oA7KU)z 1*$q DJm pzb*zY~|нqO@NrƐ;IEA +f׶؉9JQtS`1yHX jVX~F/:ɚwk2o"3'~i~I'$ roYe8P49E(2/=CܩR'IBDZ A`/cmg|Y]zšĸйSWh TSs0,704.0}U AxW:mu^%~ 1/#j%5B%Ub *Sg_uF'2L)*2^FD,?S[.g=`m] )A?!(+l!u .Mi;sjތJl&R+~\y \{ڣ[;ႼPn.@6OqҪWr0 rl礷ܫ0x/:04v`͙OLU;/V٩y+ f%aS-8ݮ;b}?aeJzK{A=%nı}Ω/5tbKoo4;nq2ĺIi8SbR~x5Ͽ*2k̀'++`^bc&nfQ HµA2glW6/f1%X"%pJW$et4}޻aĝiH*k[m}qdfCr-~ &sd*Bd%e ,f7 GdPl{Y_X DI5L UGpa*O@ RULRjfO9 spԷ15; A\\5&oTI7-tNlEtJ6>ڴ&>ÀC7۴y+{#/6z4}QS !Oc%=۞yhZG)J*M-ÈZaٲ&^:=zh_grT;=ذKOZo*k&;_qy^_봯¦;^6CH"YUQA8STlz u,XlC0Ȼ:$CB:1gWf~ʞ{-A-8Yr$h1yܱ=gr'9=n흦LIq~UxAx)+TFεb{@6Eѫ&+P^wZ$C99KĈ+\j8\cTlƯK"JHb{[و4g(pHK }ڌ˳h ) rKʨwkމffx|2i6*xyP0Y:3i6n^aee0TgRy3؜pY$fY~3Z njQA5'yv8K=V-"8@/3l0v歇R$@1TtTt:n|g_S/rl67Ӛ.)Ak>Ú:ٚ?㰴yeћ%C( zGʸu2s+:Mjٶz!:}+Z[QP{@B 'zn+C6}cGtöQ8Ӛ;k\/%!GiAV~bd~ǯ:k-JrƁO B 8fƹ4Ԙ,m ɸ쨸f搱ZCXP>o#ZA;yUhy%L<fCK}#LxHL\$%'!5'S> ʱ/㥎PM7K"}1| ~1hrw8<ָJg/\gGzQ-cҜ`R5Mv5G![=aGvfbPub,@AХ-9Ϣ;z. үU "ٌuq7{\v&ި*>dsć9m:d Pjr3ӺCAC\)U\.f| .5kD?/RuS'VIk`0f"#$ZpKU6SesT|6#vEۭkH-XㅭSJ8ʹte@EvۜIIaݍ(4M1ˊbn"Ly #Ȋ$)λ͠}Կ p,fziW{uͩ<f= ) =)X.N9 : O0cխ\;^OS7k@̬mR5F+l$9&Zn+]K>ش:Ha=u *Mj[hYm"vyGiQi7_|p/IE9EQ 0vMa~c~ã\PUr4o[ߕh?4, 6L_GLjYMlxil-s!Tv8c"F)t4gL V;3"Wur Ugu3%Nj`c?tdeѤ (ţ!7_g+ՉF o>9E8Ћszd4.f,Yr8g:{~.}qdH)\%ʓx8."ُ4G(zתrL*n$Y!sP=#~dɆlBe_]EV;D [l6.9rh"Or53&Þ?49E0oŽQ,A!LoL$&C(ɢ/!x/?0HSu`,,+&G7>.݈Ҁpk7m]$ؒsAu]hq{di"pM+/{^'yZ'$"YOW^ GHmU~K 9 Q} ˂ô^$eJ='M#T?uA7dr Yo 72z|.4Q !Q9+*dSr-ϔ.}oJGXgR"8IxwhFP5BFbd/yiG2㮂@*wpbe;PAH'lQ{P$Vu%*/\}Nowo()jLjHFP-=-G83{_0 -v 6!2IRx7Y}Udn> lh%BN̥T_)9 Td)HAF,D Q CK9C *%=K<:=nYj]5cUU!` _~b?zEg6`Ҋ i6m吗/{U#9\eD>`MƕXKJR2 ZL-&ԼTLRhqDW`# K T׆U0nMn'KKQ'j0 ހjZ \ ]OgJ2A1_dzs E14'n`#Q4̪u? U P@:maĦnJh| qh>gz4pU9gi2TE⋋(6d>uC"Io-2TҍTW %p\DP#:TIc`x5mK38UƒےmvԔb^n΀u*%- 7Ѕ ͌Dž|s/@%M]v<z[EFQ:#Ƽ! $&UK/BST;K4K+KMS-XMK>!i`291b@.8Nz9RoS"bA=TZ0mk4KGI= |sI~.lԘ4, C.fg`ֳ0']OtXat~[X Tn`.\DECrG\F VGAU!CĕSU²bGSȝلAs &2\8PLTMRMhK)JM*σjDE^y_Ҭi(M{LVjRY@"/dc^QG_3VIEܺ<-<$$1$D.%"XQh u~/Y^Uԉпϧ5Ωkhyʿ{ā՝3J3_Y5& moCVD:6MT(݂^"";\yhDod;$3>pŧtD7838xqԄ7 Laa[ 8y.Ɋ|]xi<.|'u8*=D',y܈ca<βqFUnIw5j3ZJlb[K;٬YD!T<ԙHb;=Q0o}.8-Ҍpߡ.Exa$>tַO?p[]`"Dʂ!-tM2B+"ED_6T$ј$.-kޟS|*BE(q,0P&,R,4 Z2r` [aF낅%ŧA1"Ǧ K;28Ϡ;?"G.'k䐛dIH~g [FHJ%ϓ*F AfXemΣ @-.U+Gvm>gSWq%Po#*[%r6175)tOWORX~.?( 򦁬H JaNX?ٱq#pDQY?dZP@j3Vt*A EroV@2 Iaj kT_/*@mɪ*ð`Y5TTeqcYFUexZ\I{*N=t/cq 6K65{/JSjhK95mvG~d|ne뼠VN%[fT~ tA2O UN\iR6̓$u$O'!;gf!,f!0BY8zYg,)@+Jsqw8v(X1>kaݦYxZ.՟]x9b3tlP[E0?la-3Y(Ϻ= <'Mfܟm݄$dX[}sKpexg+\Yÿ0ҟUKg\[ݷu~lAŒj80E}mh^s &ɪ |_ڥ f`BP!MѢ 3Mno+k㥴+]jᔤsQlHd/9ٿփSх@Ia%=.JHs̩Ǵ^$6:тdZuP[W[8ꊼU8:^Iq{׺R`~X5H{jY\cߩ /6iǩ~ޚBIӮ:{9uNdT^r,,$1jmd<PSZ~oa y-+MĠJ6˲\!fY)c$Qx"p{G0?q?Ac9ugߺruk4ͬ)\6TvA g0y1m3SpBZv&nP8)TY( a/|v޻樆CrY//#fҎ Zv*k'} ˘_;N44kw՝ԌiNukGLk'R0kQwd ෺ 3UtNIA˳ggmyfʬì$-͜0I7PDUfbs;x7g8 vae+TwabpsćHC*]SXmi2(X=eǷYʪR<惶/<2ph޵u) FFzg'P`Hk<Ƀujzɱ`/|*10Pe\}?*۲f"GDIiN?x ^b$ IHvduBI /i{XS%F4L6;LP棢H3:.#әD @{3ZG{*(P{ՠb[hJ9&i4] O| NV8bZW7Ө*Ro0I"aa7 e+4*~Uފ-(SD' \j2lUN?Av| [+]-srU^mY8w"7n!jD,#fđKta:ʁt7?k8`Q&Z&aiݎDJ˗]C1r E9\~z̡,4 ͸1ĔOoOe~ǴYsЪi.0BBjY*j梉t0 ׺1>"O[&sQ3mtnmh6ѠM!e6eݬ; c[&EO_vq2<'`e3L~TB[&L[e- \Ŧ>g"̱Mfu1>#S^L&IP):Z^`Ѕ+˵K܀(>mRGCųCۑsk9(u(#Z fA d\|Jj6Z' {D#L@@HHHi([i%TpYaMpB>aˏ]Upc[ġ@$+aO m747s6@EB&ʠJX5Bf f*r~OjX8~C4m=fiTGXƿ^.͍m?Ѽ Q0~-X>2gCfrkuMOwƪ^;ge&F̦^/e̐t%:wkF(9ļE=a$\=\>̢elr+ey79IlzVɼݚ8wZخJڭh䠕~[ܠN)}Jm"cQ!+#j۾}-BO^[..ۮk0 {¡j ؛rS&CIA]ėt$ú.v#Ƃ pDX6 {s;ӳ u2߅⾰H|h0vPY5Nl#? ڄ;? QWIT%7fr#5co&]rKc_jq3"&WcZg';̇c! Gn+\Ų6uH>0qD;Nl~2>;ٛFNz^L5.?ȡoXbh9/|fckhWq*U+kN괚Po˂ DO_ Szc9D$C@RA(=UBd p㝗7WTVF퓌_l{Vd`}D(+%8ZZ(8Fgø d<5cDU͜f͜wsW c`#.EW"J<3ATOI2 VYDKjTLeo7z@K8BNS r!Q*MGnqts,aSS\S% ?q%*~IE63|g=? Xo8t\a֒Hv<&:cđ;γ9ڼ+VL{rR-zը?EV`hk4BIdc ɢ{}~Ќd1Bi&} i{ڣ~CǠ8ˡ8ǹ8η] zOD2g׌""Hw!bnr0']Wq]\>z ㌢Qd>6kH4aAw\C]c/[)R Чj3w) ;/Β ~4H vԅٯ: }<2QHl,j )8ևW5Öl5]mx*HQr(0\]&aÂlU`cj5<^=Ȗ[n(Y'3-Nnxun.Q-WiH;uuo[[2dg$n s <S_ՖPjٙ ~aO,q3PYRpU<ȿK}gu=a]O* Ä$5B቗X%9i۾+{ =F0<,43KM6MK ][r*.߳8spԤfC#[7׃h && &'_~C7.[?mq/uRfT>5qgTQyWChK9o}iLNf"QWw¬teʒ:,{H2d@".D}6Ў12s.\6kLma19{&iLNVn^h{vE39gipԗRjcȢ`@p<=W S%]\Gc܎rTcTnkk,>1`}'[:7C_(CZ+>TI\b7o{z߸/ַT9"cDհU pI]튔1&Ad=0揆?d[N`5֙.V*ErIQMSVQQ19(q̡TVO[VLu:Mj" JȊBhUs",W]yMNpV+AzxuPڠU!=N?;C6D8+|''ҪmS5*Jp%xG0 BHjR0 9$ B'?b eN'upÞ[9皾xnU5*z&6YX&'ueӦ y#䙯  ch^Ǽ (~N (cK%SNjzZAh5?GP /`".@dW:ҀAC{]VX+˯E5^0þ6wȃgYِVAh!ng^7b$fo Dls#ܩEa!,O+K\,#t3] vRf UpKPv0r(78 #,)=7>œ!p((ū ,<}yA;&g5k3gMysMZfHD\X;Ď)I4 `QuCۇ8@> 2N`qP Թ#x/x(u ?t3Xƴp_K_=mk0lRM]I}!Է o$4I߬oqYO>+}qQºʶIt}}ӹ68οRf I3},ǃSlb&elHSg+up B@I-N5pQcb4qϬot2+@IƸmsgy|j8f ktCEyǓF28.!ʷM 8Ԏ#Ej}$Iչ8kXU~y4|yI퓘{RO]ꤜأ*9Kڱ~X 2zZ0\V zTXEVyE=0ʃ&jz ^ܞ%81鬶c;59 ?+['!cvAZ^݋; %ٰ%`úȧ{3+sdt RSA`ǧ|k -,%$ӺS-2 Ojkq2Һ|]v*69_;m{鋯mMm_ݵƑf,̒0|HR<24v&M‹GwhJ^f뻂@CmڻbB N@%M$XF Ҝ*xDeO". *`$Nǽ[V%KC}IܗMSr +w@yP}XK`bI-MF\PJ3`$m[4s.%gμV5@J u3kdu6>hjg1ygC5)K˚y{M?˟eVʌ:0AL=잞B:ٻ]Eޘ5& a}ƢF|"3HCpp֮4k_H/jd{<1N;4d$3M9Zm{#U\\nsZl[Fi uٜEv8a>dd.>̃9}HkujKri.5. .+bWu !ybQx[A*=&Us#:(U,y34s=Emf G`z+#ɂ^}14ypӼ`8F"?ΣŞTRk8N\Gg ө[OkYoM~UKVg0'A.e=Cϙ'{:݋zl^ {>4l2=nM#Pznb7 8U׿sƬ|(f2yp9'kn?S'?Lu'{܅➧l3"8ڎ{㞨loӗ,$m Zql{_6gk@sR DN:.b=D:!zvHra6rj:秸#yH6IJ^?嵽Nr=Ĕ N3\=_gܝ&<ay aflr6B9S9rX\b?-a5y0sjԇ Q$ ΃daF8u(IFx4u[IK_uթos1;Oy<^9-4'E/y/^ꌾ)g m+#a ŽW6Mb.4^Ől;i} z|rmb*; s. KZegclad-#aoImzZ9k63:s,~DңU]0R7ӕua<"@W_@ʉVvPx;zLO .Ր80@4l:z!V zi5ԬMCI#b\WY.`Z5RY}%,g ~\k "\K좔SG~Ҝo_{G6 *pŸ*eZ#7 8d]yYg6rOQ{IYfm4vw@)jW(w8>mEaYl^AM^2S1h?UW)5H)jFD5H~8ج8|KrՃ)BֳÅBS+o3/\f@`UAqM*ⲔEBqV\hgs!%buq"G!.np 3$^fܕ}0gc/+ɵ ?xbDLo͈d+DV&*ʣv$h ]#SRymb mP\(GAU87泴M\I&6n@x067hPE$VS18:x2NATڎ -L(RgtfX:~LW E4;Emq`sg9r8~fRY]pQӰ0]-,B>baija ]eaEod.Ҟ^~q Ngyb-aՔPQͺ0 bMk6ds[ٮ$֦b2{<#=]%h H%ElpkyH# ՂR.oj6\}<qdӗz3}[,8vhk ah:2jMQKn :v7ko8 2|> 4ռa*;9Ϩ-G /Y[|Y8V 14B<U0ˋn92"%PVFRaYG ,;p>\~;ي,.fD H0<[b̳ӳ"?fAaG|(dة+[Q.6ٖi( -H%)wqz YYla gkH8=ׯKA!KkuBR?~qp8WVWPioޥCB/D^"Q2>oR{N+N&f>0輄*>XGu]D t (|NpC PqyBu*|J]_B'zjX@g$A5R@5$9m2UA1 w빓>V]) X'G82O~A 4S6HPˡ4$7?HR&ɓW/ G,8f$b#*a@6u:q5;~#f>Lr,qw$!:]ԛ ϖS}1XWa@у&MDEH?M@XN ?Cq!#Wt9i E@ViElhI ̨X.:PRBrQdw40~e߱6;ƘeJ$L 25y-:eRʝ% &,At|+m~z{Ou50ǵ9x,ny,R HȲC+Z0cݤꋆw˹q"e*3/^ spǾ쳱NQoy vHWp~~whM#D@f ~)nߥ^N5 (9k*N+IYj'lɗ`pk;o/@7]]oj_jTkRIPʬWK|B,sfr<lM-WZ[sOR\U*J3CLAO$GR^Bh+ij&;1,>/߻rbf W!  %X\C#r.Z`%=5q^(y'g"r"ޫ}}Wh>rԥp*^1AS~l](\]AX.UV8 /R&T$IKv 8EY*7߸bs+Ud -+{VA@,2<I|"boCygIy*~lk#@DK,^>TL ,%`VhK{rR@TB/+%7 }~vMT*V^џ3Iћ9df˅CkfRK~ sPO3s [kKH.< K+TPDe:5xine-lib-1.2/misc/fonts/serif-48.xinefont.gz0000644000175000017500000017733314647725152016522 0ustar meme,-8dz ,g<;a1`'N%+[Zڨ>}[{tI%7~q _|ןu_r,f=!Vrm? I*J-y<|RǓ:=^LX8z*[sgh]uswUtHtOxһݴ{Q< 6zl~RPzR1ORJ1SBҿ8L:A}z_ʣ "؊Zt$y> @?6|^a==Ee=MݪJsեOE) SJ ^@o ?:)mz8+km+37-?SI*;RS; m RfoY#O5MlB fڨ8bͤI/1>zקѯn[{v5et߇?*έΘcs=0sk(j/Kއ/?ck &hM9s^{eK--z|n0򾍫W'@'kUlS)CENHĽbW0@gڞsֺ[l`L{[ :ik@>^);Y:*: QQERTܟZe3.Q%&5I Whp yP+}}s,;?L SԌDS! dw>;ej9=vmϙ+ugDè$`Ko}UE)wT]a;䌓W:ԃA-6>~ojkw;7s*J#݊x|YHrWG@BʧW0Oo5/BrwTֻl^7IxB?mGX`R_u9튔j] )F}A3E"=Y3Z47qre W!2C;o#myuHz)qﻬWo-6hT6P75 _~9A9:7b}d=A82~v7 U`~5Dzٕd6_ce8К-h%邱侫k)nx\u buFhP4rpٵX6DvHk,hb3iR_}yݪbѺW=7" Ib|}/PZwy1D.L htY]`7Nٿ!׍lןt*~>T. <ͯT8V\~I}z<,Rq,Rs *Q pkXm>2*- \;EeÃH, (l$\l(QUc;&"Od W18Xҗft1ls! >3Gd3>jXqsHԲuyj)";wv֐o82a0(}wW=ѕg^)>f}}d(kjN"V*8z:6:wVwQ}GۦȁHZr_}Sl$a}L8r1 6הd*_NM4}$; ɇOOO(y7Q_@Ϳ[(ѢZ56*٪fyR&??\~չ zpg%;~[GW$*Rֿ3SdE!zsazS;7C~{?%G=}pR9x܃>aЃk]щxAaPTw,$ShR*j".ΓMTtMT')ܤ8&qqJ#1.>!hr:sM$/¢_PTwY`Vo=11zy&n;*2}<CNkEa8''Hbn4[-xN+Y,#JIQnƠRn"rL$Ͽ>F H_w3i_26QUk;URA%yd(2*D ZiI`78ZUӶ[3AlrߟUU`߾w#)0B}$hQo[OF;ppyANߕ[I)Twrq\Tg|ALd96&Z~tMJzLV9l qM(ZrW_Ӆjw7ݬ7_[OMyicq]gy W![0AםdcQx'lӏ XDI'6f2ZK^Ʉ(de}ETT71[\sRt*<#IƚO=(b}J垫]svηnz19M/|=WZj˶T Z񆔶7}#7oFZ7v9߸oT}~#ްOx#7vK z3o\W`[//|{pnER+hR@w0ĒyıMhrFe\0%C$^t$&p9*7(2Fh(0Tf@Cb~%׊| bw0q+loS\Q-Q2ChE @E6:dsYޜ¨LalAl?K^iJv,}R+|nkdٷ&G~njfwjbd7e5^,kˀ2T71&a[%|{M I1n ϕ VEx _3A$µ>2=T][`tHBqr%r^^MÅh C@Z^,`gfw@TjVSkNU("{iXL#3O$&ax[i5`ƒ5TAwo"jepleˊEB!%)d#;jE 0] zY2~9V~2^;<cao7bXfgo`A 0PM[Kӧ[w,Ӆo)f2r]o![VZ47Ǯ-~BMGSMӔsr0e}6}"48Su(̣RݹJnqMS\;6ȃ B^3]-:$%{Hmdi얅6mZåG!34~dH*2)"i(n){̴dYwY~&t[{~Jk<858$ bkCwճ5TC}}ID))= 52C*"z PWNZ򩒋-eu!$̅i AE[;#Fp9;DžMc jǏa#/y҈ ZqAm.YZUaZ0lCY!X|~  "ИQ@ߜL.tXd^AF1CSPArUuƾɿx67tqWM $iFJRUͮk$N;eb۳?U%srJ %kDĴٔqeJ9UkB_r3jIaDmG:zDxxڸs\K68QMa5ޗR%:O lg8Gi23;>u(V=j˚բ'*E tF*BQftswT0" X8˳5}HRFZӰbX,V_8YŦ($~;^Ȧ goB'2D-ݍuNR+N,kW~켥_FI> ^;4?5*]63Mq\p^x+!vHabE:D>>aRLcSfeҦ_ugonDt9\ R>2}{e}R'dQ'vɂh٨]S2< طPU<itPIe[/?t<]Buהn59נ騣_q.ve=)i'L<C5Cn=m~!kv]Ee]ԇCo4\-O!붪[85Wߪw6yiy~0ꞋKC-o}/8YRjB-i7pZ}kۜYÖ/0A$kgNnZu5M)-KZ%]u]ӣ!ty :1cCЭ@u`[Lju3a`5p#dr֙}VfW2UXj?%`fG]0klj7RJnvކKg j0TZayv(eDBjSjmqfّSR(L] 榬mNMl(MœFu{z'ϼڝB|éҒV7UكSS) f?Fnv؜gY5GURETmi]} 7a]~ K˃|-kp pA"ܭjvv&T9sA.~DϚ/6v}Kz.N4qhq4NVg3n& qKkӍ`Uί|uFdlͷH4ъ,pH #JyM5,SS<0+fh* OhzXrGP'} 7_Pol@o3m.3]R*oghxU.|76%b/k]_'.stk Dv Z%413pYݴ<)%NV F~&}"&D-dK(Q$6c DZ y/"Bj8>0v``|ݪKqn]+ &O#۾;1]؏oL{:4ЕMp+:.J Cdz4`1SgUP9WW\6_6I7:0"B7*@B}Ǧ"͐Ui+y */BNe(ȮBwG5{ [S&yH #(^1mʼ xI`%]i,"b,HoTP봤C0kq h6aDٱΙ1 62DToW~ˏ*֚,ѹ,~4KIEViւA Ά $< ,adj +h+Z\-秴yf*bfE 8d!Ync;sRH䴐*8!T_+bjr~lJpnDh" Bo1?xg&~-]HTC>Q9k*: o DGc sW N{u+nj ڛw)vJ utOJ[H%m$L66PC6$Ac琽lHvDqlD-J#:h#|C'w_sQ6"2FRdЗIû^*Ĥ+ "ͬI͔֩@ek ^f:'=!_K= c\O'F8v 476ǎvˠW\mW5ś⫲j.şYZS`C%}έ)Еt+EZcVM/d {*C\Qޮ}#4sy\b-Mf2cfjiF\r}*,Dt%r}i񞽧FO}SV<≽{tpCFey el2 cWMFG$)!t6Z@ٸB )pbL zvkě38~S`mK* tiL6xZ{ACwGS t)h?䵠UEBp[ جZ-NjZ[F ,%\4;#g[>-z/[쥢IÝe:G}Ђ<9lAknǾts~W̨LP}{o҄"L܊iwSD#rFvU{9ҏ;Pٌ(tY&P\=.I# 5&_'5s2VK$.DzJNEVLE@)( Վ\$"~FKt}N) Teԅljd6SaIW!)2-ƝNלK7nW/f(f$+ºYRDro/|nw| U7L_7XȪגvؗ6`#ұ}V펣ONcc<*|)P^h zuI2|D!tT  &fK]~Vz80w=9=oַ+4- j4G^tDz.i/!琔TD-u!yz>|9dBp7 v˓+bsj;j@kz]Xҋ P7lDoYAn-K^KϚ/~N G 6]4gM:7⚪jb|hؘ k҇0Ra H }'o/|s//vVȿ|E.~g4A=3iƄ/:A#J#GEx$i n ]ˡy34*SdzJVQ+ p+R8fpkV2j*mM;~}F6gއSLVD.pZ 7]4sljчN fJrj-S3xg2-`6s"p9ن=)iǛf&98EOWuͷj%?5X*_op`- V۩-2+dAK{aL.NGR,l: ٵSF v;S/CgŜ혗tLJ{ oj`Ia%DIu"I5C dDhgqīpWl7%r,=@ke{6e9x,$ܿ6[O[@u>݋u{*`,kGwګ8X醣I.i[e\6VёWE_)_%9j/Kpa{2DdF7Of<Vut 1iłDnU^")#ZcM 'L'mGf*3 vtnänmT~37Q|IM~&Lj}IPfUK1LhES?e xS@խU8>2BYo=pNj˖/bzi8{@m%i)~y2n܍'_U]O,'x%$N&-dX8%B 7q(@6/lҼG,'f1gOIzQPfCW鬫zfͿ![{1FO6ӿqz67H/<avxM^]tJ7 -a)DW]"Gv̒ÔS_4ڤeC%ͯ> #)EjXgdE@ ֢y3 ^ yǒ76^11e,)"p'~_cM~UM-(DO+NA@9a"{oGv~o5|NI 7܈Z@bg΁"<.b,i|]^cF,+_MSVTLNp]۸Ytg)NBa4ZfLgERN\NP {M4,ye(O J$N{4O N7V$`s+Oa\0*{(-2xMp7 7E+pre e Y mVcyB߅(g+vY8\]}55V SDt)#v־,3[=twImQ^xcPv$ޠRY+TXVD⛜F`X n;hG㨂=3YHڇ1@*`H 7pN;~^CR7}b}S4tz~{:ؒ9*pvaמZhTJl"Eah1H-M^gKHI1a/<."yPg3H%Z1̭b!-ZF"|*ZX2~)aL ,A9F=tbM>/;.ޛnwtHh2s.X.ZtL9E3m׭ƹ85)3)ߺrP@zm'?5RVQo%xsSKC*&QA֞F[lX$g\GHl+>Gd v ׹̥j&o9;. i|})Ԛ\%ꘒZ?)y'RxlD6ial( 1Xd5-E.o\_Ob+ 2U(ѣ8ɊI+c=3Ӛ-4PQ}%lɚ'c#$ٚZzDD4sH|hHBfɈwY=dY-4$ρ{I#鏷+`(m"@8OZ2! pY0 Zz)r:73o ʒNRXP&L8Ki0nhɻs\$Qb}.B;6΀=7nTf$ftK oD6$]bw蠛WCP{Y^$Wg!h]nSx1D6ťm~w\7T.NTqKh$l=ǰНQIĕd]NPoTx]q(D$ {LW:RxsZ\&#;kdyd(a[ufP:KKy4/3K.fwBԑ'9D+ɡI?:~vóQ,Dr{V9IPη#(Pt<_uZ~/'V̉a7~bj&tkIM3p þtu`+ϸHoZp4ƻ4CIJ43ZD]Q#i.F | iLɥ<"`LXP_ #ݏ_$q3@/#q^~%*]"@R[܄FtzK|r>Ob=wHF9 6G]CY /ą.XoXn~g /НIW`N;Q3kdN^s7g;ɾ޹ww;WΕWL,GI4<'AnU94vn>}>O|DFg8D9 EUysˏ~)}I_9@=&P“S{r]ľҖ^@}5) b4?XiNihh z6fP]#3!R .'ABߟVw.g9Y>x ˲Ee,U[ @zO?Γ}͢(+}JoW"?fA sb 72;k"-0WA۳)\vs叿Ϗ$:˷Yd8,20~h+BY|* 7V ZX]5=Fm!syO=ӑһ!v"( )=X ];荚fJ ,ڒ ^.cX.u&Ul768%/ܩ> xU>Ʀc0-!DR&wIsݙMprxo/W/f^|=L vH Sm輪 b5Ŕʟ|W},oY8vf*3F]Ĩ7*`aLl/ԝz6]u;JyϤt b Mo;()Da(֎  A \j`(Y3bl tRexObc}P)B¨^K;PH]1Df@EJs%P"P#ņpx'+`89]هe$Bmil!`"o4mu\~&rE,ݹ2 v]U J&nq20UdV XdX?u MKh.$YyT9+Z[H* ,z4&ĔTFI4W noA0. @#v⏌:J9,57ZEBlుEkZUh|Q?S^.BsUм'gRA 4 \+ ~2cU~0a9xuEbN,2CD£zF|O:寞~'_|RǓ=Ó?Q?hɮmق z ۢ-?Qޠ=ĉse64b=(5QT*7[)2:H5ZȀ*ri&#챔@G eA :Yuz+U"4X7!*PH,sǢNEL ϶2d8,TֱT"9& «)u\eGj~4QV|-;Qd_&P+ ]mYorJJ ]$C1˯sr/D),Fh˜ǨlvJ,#ax1Cy|kJ1*76dkUgDOp$%.I*SFH šyddғH8{|w-'\IF|TETC['SWru.$i㙜M%m8gK4R)AW"9i&T6J9]@X!J5 3h ˔--4v'MY;ux30gyAa HWgɈKxC &g݂Y[ NI U-y&eAEQdSfo\SܚZfKoEq1B`D;B{HE0Q4l#axY`)M2GPA1AVPk;Ywb#+1ba|, 9 @)7-,HdMro Ve$Fq_5Ŋή6: +a?>S?7ZT&BfE4US -f&<ϝ-C+E.m;+$+41 &DU ܷHiYHh)=U#"Y-͕|ESH-qըTM]9 FHYڹnHHbWW%E*ԕ5FE +kߢpLOY,8mdZwW8ŴIHd < lv@x +e1a>x [YLW$ׂ(ɕG]2xgyXɣ,Uno~OWQI E<!e[R /> FƟc{!ܫ"3&֐l7WyY͔ZP_'SԆ&F֧o+^Por~gS|AHDW?XgE Sq12MzA aqzNYx6R9g%)#ʡ< 3@DZt yC( s{d E<~cӟA%mhߔ0 c2`k©(E3Nr}LϹ󶇔!{> `Z<4~յ~9dCY.b[# :LEFEp0ޗh2oSJΩv^ 8WDh]|e0 ̲?A瞡Vee7I[pu/5&] :ahAe1iH{}~M>("tCE4P$5uV tjCMLZňPy j@]٫T߭yaY^WVnw}cLY8ݰD,en1P%]. ff ġj~}Ag2Xo;l`Gzxfǀ$}|xd,a69&WsE,dxfe*GtTV9x)an6G sز\WZwOx,q -TS,DXjUo0wBpei\2el!OIT#rЊeuNb/&ΒLu3;(*l Fld ,7ڂjbhd?o}}D5TxꜨpBOd* D4pebi Э0&q*cUa 'Éξ`EljB"Q%Hf#\~TKZc,]+ǟ́;W2"רḆ^T!w;)Q ׳HԣMҩA;lr #(c%hx'3K(.u2]vFn pgaYv}ߞ݈ S^어԰)hRK}oooZtNh +/jLS=V HL _NKl+vr\lL. * P4.]\ITʂtyu/w_0 q!]] 5lGUch]3Z8ii< }il 5uv=t?SG@].\HݜB#g Įq~J<>wcS||IdА*h. djJa%E2+/Z|J9ᏘB𷰏<~GG3g~HgꚷjP]x"P `͇>|WO5bZ<: m 21N'';)E>9"2uxGSLlE5z35edU}C( &4_vˏ,gq Gd(#>OJ9b4'b@!,K6 $F?|g oD5`;S%DpcBB2z_R}2ÇlSîPK':+E)YB9hm,45&Q1SXtL lUJHBt=cx 'kzR_S?Ӟ8TNiV|=RWouV Xݟ@R$soEAd(T p  wOxIkGO ʘFv?b;)BE/̲s䟡A-Rw`uE*lZ-˪*EߝJIa_p7"+rO>1PdPnv\iյDߐ %<8>++j]Eb2Zߊq5"HSݱ l59u iW[:JKWƙ.Ec:Wvj;$ صH|6.p"?ɸuP񽔄, {R옝 cЗעI>՝8+ !+'&r`R̪i"Ehi7CX8,J)$_E)w4o Cɕ16Y'1^T'XUQ7\;Q7D [ߝWBDG@2H,rQۂ{P90P^Y`eb8u8&=~U\GDbElCňwhxZ:~J)6p$*+IЄZnXH:BWɾY*N*bn.Ȅ\K2$@F.F\0gXSM U!Ҧҋ,b c7]: fG}&?-(PC P]ߏ߃yR0ߗsH B WDwA>`g$4@Hä&_bKp%O\(cԡe2J1@"c m}f6 (,mh|UOqO;RVH׹tͱ=`q ivpi.yH{VShzu;<< T@*1@acW#מ6IVS{@YYWZB; .u*$hQQ ,{t= u_2{(C៏.s?93DAUFO~҆(hFbt*O| ܽFV?CP&Iqb7^sE *_tJ/H `֪gy@K0NV5F fHg B"zGPR"aCZT̈갿:0lUU4"d)(@N D>$=h_1hgLH+KϤƀZz{uՂJ ٸ0XzƦwJJHnjdgggmW!$B5N>#=FZz=mBcgbNUVJz&'ו ͰQdgrJڻG#NIX]vyq#|A *݈|0 _ QgקgdJg?*=Izdҳ20jNg˗|8-tXZC=3ÿ?HaVSv\Xl8tmhva# [#7+^d{|y6qf0#E 6Ÿ :ˏvgr )S>9\z@_Mb>qw3:j|#EFvpΟ^\~igx. %;x.OGpY/vA25lJ[I謁w&yα;-6 yx+=E̍YAR⃜'aϑ_2'>z!)0TA kyMI>5k RtcݹٶEnDNz,,Cowa&WhPP5>Yܭe&a3l"n- ź;A6Ahfɿ63dWħ;P `+4I9h(gAd~Xx+4,eDрM 8<_3g|"cWIW&euZeXWvyRUEjbRze AV uRѧ&@]<‹`RqdJRБӰI(ky "x{כT 2S*XU'&&C'"@Vi6 xHrEBMk.:v1uWA:[ׅO;ӟ7$T;uNsƩ !rMT}MuCH9YTNBE}MR>*o/J[S/=1(u!Izo`9<˯>YFEFM*i@In Ք /E E9hڐ<7z$PƗ@*O s8(aO1`R1ri H+GZ纫1뭉a^P#Ͼ&ňUXޏ5) =BqEp %M"GLȧܴ>Qo{}gHHy2Y?yZ>gKN;l(U*[fuuD$eR?,zI(ǸFh,"I%;TE=V@Y؉a_8]!CM?NOXܦAgZdjR?'zVQOH <R8t \ S dXṛ2YX4'˲i%7uY!LSR:;A(##hh܈g=d=^#u7 ^#5ڨFS>{"5àG1 rؒVsy>{LfW[̔ve {Wjtgyf&F I͘閽xeg2aEݖFiT*Ǩ;7]1U}Ԭ񨩵i Z*F%& M8ϚtA.H!1\9Uf7}C?,>r5SG¦!JVXYm0k\[ZhqX<<@_WOuPE#pڹ1Թmc/q*hAx|,Ie!%)LqDd&'bE,dbn)nF"j)pFVyէ0rfIVm)9B\%GV',mm3t5!In-ڛpH$) ݷ]/fK7YˏɈ`ɶ9>TiD/?pys[}7czvʽʸU4k,R(Bt&Tl9r"٘RzV6\S1N\@(Sir}=NYÇ1\l࣠ ޡ<| zK6Zzktw(KVz(Z@oͥ4R~^rK ?K{HڝQnyj\503I2m_@P#{GIT"eSTd=js8USl$npC 'u+-[{}sF5wRʯIrޫ(W3 ͞RU <'twL2:J_deL!܀#" SoO큢z5bY<$2i{eu꠸dBQt%O%5З+R:[Hq"h,=r6љ "5ltݾ97с+)=%<?#W쬮g X9_c&Pk~P@yE 4 G˄^+=<6ԙn?X?_UrUH[%*bx sxvFFy"̫ V &̍h*/XIc]UoZ3£e2bDb%xjbJY0h= ȳ&g%c5~Y 6^S%لC3ەLF*oGJt!nx&vX? p?M8Hnu%ܞ ınˬ; xxL&@=Cgڇ]j 5]YԸSe!@NWXj8jQ pA~APc}5jaJԹ1mʼ wI>o'P0q*5PF1Ix}QHY|:5$#v/3>c@) msv` ـcT.p* ;Zm9:uarS֥&KuƓk\„_5*Ը\㧡FkP5N}hF5~ sK G}XEl甚.1ml^Vw;(Fܕys9 Yn)doJYV;k[ a|r, {5p5M'գ0cCvqP\Q|O5;vhn~#GsFqKsʨ?lq0ʑ2*o֡Q@ ʠp5.QbsWiPYL}юȊb`Pӌ=uB*hZ&Mq^k\5q{5jؠFwꓮ[%j',F5DvǨqJ;DEݜvJ0>Kֿ1ۑ jp>;vaO"|:ܪ#+tO{/dL7FR~ h~ 5C8o\ʉ;eFwl|7Խ7FfVFC;Ww?:Gh?{딧70~ˤ[KHU 嗕;wHۂz>@V1Xxo&ąz.*;Y!@y`=W޸, @0o\Ku/bt?jp2C7rBn9XƐW}cxfw`{u`-C/I L@17sO҃{s?E7): 9$ URQen{Ēֈ,)c 9^ˏޣNyur?L;4vMu ڀ[ 'tz8d\>a6HIclـbDxʌ΢ .6*Tj#29q uS }hkgW\Ģe+hmFcI$f~)&zQ|c}tX wQl̒p9ʤ[ay/Zl)D6`碍aG\HHik/2i'xUǎcCKۃ&j](A/<|Hֵ>>r 8ggc]4ҥGo32st~!0$%V6ElTTPia,#ՎlhXb"#U ܇J~ Ę4"lQ0QߢŎuBQXz!t"zrZvdu[n$p~ 8c(3Z@}`4s ы[/!YDchQXa0G:RǪԧ?3[8 ZiI DE̸o4X<>cYѓi* >LsC%.m}-J e*CC_)JP{C!<> CP*2~Ӣ kzf1N#CcoP| :N<,rC u?UVS,9dSuEX?&Vx (;>42a>N.>t7N0;`,/8;z~K tP(+/xA79yvH yӠC"E7H̨Iƕ7^ |Ї-Fufwi9R/?Ld)X"}gMT%y$0 `NAso 6tsø b` l4! ·'U*g,UH dظ1^/*_2% gѥ%.%Xwϼ#u>9~F m{޿'˿ 6g OJ ź{BJn%+sMN&<drJ}2_AA/P 5Kz/ڏN#vqbOoz0D'iyz;N(Oi515b Hx8BLoת>\FWWY㺑>rHN~HL~:W٪FA]iq6{#d7qBwO[('T0);yNF}2t%9[vVRU9L]*=nۍ3N>(}}b̀"]O^].)mID.نU ͖nMh ӴIp44M"0X^&c;BA\z@Arlߙځ`2G!̺ڙFё]ֶT'q^}r]V(:7 ~ B!UݔΟ>WSr7"|TegLR bs"r]"Wn#YkzѠ ѲjzI3GnpFW թٗY_cd[[vy,C90dl{u3zð Ӊd䴲ьn~j?É_`{?&VoՕSX==YJi4;E3w-dcN±/V̳G,,: m˓4{1𛅠v!$U3a/p;XP1wqe%'h@q'nɫʱɫ:5c 2rܩ5g>xԖRꨯt [;^IԖnAxC2KڢzFVm/<=OXvbXK 2rK촑Egɝ,>Jקɢ~CJO5$lL0PIYA:HBꈜ/2A(CVK+~Z?k%Vhd5Zz[tšO޸ݫ秱uIO_oksFbuy (XQ7$|X}"bo_4Vw.?|:bJKYeq3JoP=ﲎw3:r"vk-ѵNNuR8Z['k:g͵R^ *ljgP4AY͊Z7Grme;Dp(;R=Ѵt%N)c˚Wh$RBBBĹ?%>>S4H0ZϐS ]<N%&XSvHjlOg>)>ϊO%D cn7w<^Ivcse{ěC)jY6aŧY)H|:Fħ8j+Ffet,9v4AGۉ:Qħr#P|*Fu--]wL}dQ,aO{弮421VJ|j8(nEsPI6 !%MWY2`GY۲(*Ff:V\9#_ڭ3OyC+!|JsVOy@qCfT:鬍;> [GQG&TbL眕LOx@ʛx 語NBA0=]Xٽ=I $77ǝlt6zԨ rFV6k$&酥6aXiAS+yZTÐuB̑]w7ͼ4k2,[5m ȋX|--5%B2Zۡʕؒq#YN5/:\+85G\QFjOo'Xqv3|@}6z ,o?GFSzx'0c*AN?LA?;<if# weaKP+VKO M16~?YQ\iz F.A'wjDnFoL'C;= Ĺ `-Bc839 G?!`BuO 6}1) LV.r|);[*DvݝB݉zAy7sVp?S>8F/ğҪ1yV} %+? @TnŸ7a#ƟKں.Ɵ:Ӏcl*.|=TC.k= QnI+Jg!O>1Ig?|Sp?qp !Pyǫ.Qj7N'G\- 69j '}{A2] ɵGu59/Q`n9V+ qNXxJ,öH-1w澔j2XU7ZalE6zf 1u:tʁ˖dAsdM_7.g3e{MXn#x\$bSE|.ˀ@։ַSvS/xB7D>}E/l!9pD aD'!qzf:gtt5+L5s]/2'~jO.?~_ia%h򷗙Ϯ><[k,A(%Y{C=M=DLnnhZ%v?H:-!Pʎf7^+H$pӘ=&[w"}Z $+DƓb<MozGuET^?OsB*q\QHb;'-?p5ێ%@@S77Uf|%jBTPpau'^/YrgR",+Ol2CK $%ƴL2I]4$vODWGx2ʀm<\n24C!zfj*L)Gʲ}d*W6PAʪFִ jtUeV<$_6j8l6FvxI \M "$t͠LM{^j2!-Rqv~ڑޑA!# ^$2rI-i{Yv!Fy'd%_:ueF8W:a[Ed=^~1 ?'dϿVȈ繂xx[`Ps0#󣌈bHlD%G aL+)X2K _\B&jDۭdyBeKuXlZa#n*x^PC.Ezc5ĢSYJGZ.ثE9i2~-2d LX/+B'q'; H0[ۜf%=wuښ0˼bS!SLh͏lﶓ .:3jȃ8G/~l6>,g"eǰ 4!:N9d9FZN2bݬ'0YaaI/^VZeZ<)A0d]!/I,IH|4/{QHSHe7;GӁE"oR5"g?T'QmAʤ UIJ&SӣDfFC12] Ƭ Dӊ: aҕc &X L-jt Q:jLMOm܌0 lmnzE5lg( $ ھ $ZW. eQq~,`] 6,N]:!S964 `Tᨥ`ӆZAUu05ڬA>N&)^#KON :YvA[-G{v)P.*=h уز㙤gK`3R|Z,m-bIz&R/ )d7WrAAA .`G4Ң A 7 УNq<|vHz7xcJ(Y{8S ̞B?xG 2tPaP`>`5H8u:H&RljP~.dtrzoTd*?t驀A9tPXWYJ -|o'+.@WM2屖Y4C{LELca^WJkO&M8 c Ϡ/4HvlQqY?]~9N1>o`'1!~'s~0 m`X̡ |)wbξ=O߉os}ވ]{/oS0lP5%IGMCQ(fė[r*'t}+5,=Dv^Le/N .t+;t/;G.~)xF!,Vgƍ! wf=*䟈P]>IOzzQ"屡G!;&$S]΅ݲ_ XN9؍3QL!ѧKVFHnq:F ]ڸ/ܨKo?< '#M)ٮO$"$E5&j8`/,T(s!]-^SS!$*,R=nzU䎶[c6vܐZq UX#7O2RV^gaُV)3UvuhM8sdd|ʒMUFk`XZ<w'~ 1';FUF!T%MRfXza#PO*ky(বP>9GGa%}faE,bV{ -͛<寚/aj!~fb ״=r"wV5 ѷICydK9OCYT^ҠIU%׀JxƹT5L"~m}bv*sLٷS pM^-;ˊ]P_EX A26*,/IW"Vw&VѰw"VbJL&V2}C=ͥ+(—{@ʤ\$jNe>9tVK֍@>z'd  c]ACkkGPV=d;?x0}ŏhSk'HbBW~TUhэ 8G8JT2 Ox})HQqB -ТLfxcD`Ij9(BhQe2J<ٌ&aTCbZf D.ΖP61E< k|Qc<fqx: OH!cTˏ,O4b ]PG5wծD8*n-FI۫_Fn_GZVkv+CKe{um9poS>۹\ s/?pJ8t/x'j؍Æ6dC[ ܍AGélR9 ;¼Ȑ1|}{hD_Fѿ鮊6䑩y"tpPz]՛* BR.;#gi*(h_Z /%3ZLۢ`F0œ mBll8s>rDMgMmYeXMIҕJ.0 T 7 /?g`0xkw眽Oƽ޽2ffFfF̘7T -ZK'=R HHvTҕ7LE^Gۄ-y"2'_9IާBwKH:Ŷry8^11&3X(J':՝~MVä\k*>rB{t%Іk20Hb pSI&Fsdֹ`f??/f|%~n.]ܗ d p8h . Wd)HǫRf+tKi$w[KݸKVXK._E€UTp3lt^9 pX7VOAoy)Rǻ 5T?쫸}-U}߸!/S+ͷk1q&S+CQF{eJͬ:;\LSA,>u5fM%.&% =m-{۲l2a7p?mnu72D~)mŎwGAߌA]Lai[=)괢'41m;zI6SQchd~B=,)F=JL2Qny|CϻSvaмL0Wjbs' ɉ#QV5ᙹ _̉j dݩR6}Z&!PX*Wh53&qUdh3Θrb{({f̉BўFA$JcNL91 ĴfM+.Pֺ|Bϗj^:%OYq[1 s_3ƊˆK88˙("$BŤ.^ U+B!-̎aP\DJUdBcrުnCGȉSԳfX1x?@hܣr@5@XHGOS{G CdiUz|m%D#jk@ly8.'4-)_&N!#5IQD^|ܫ~ƈpʁ,絴7tq0=ko޵Iy#Gk(*J!g:C: \R(&GϤg*핞rLQ)+GϔOurew:(y3`e:CsTɋ"Qo^+5BG>Tqqg(:3&=؋2a.(? x)gS;3hu^dNRs@Vđ'Q O[zw)ൖ:Q8L/4 `O \hsRETw+`ݡ,_՞f(裝(}J&D5`F;iT+>NnuRN| [Vͻ@]p!b'U} D XzU*z t͹ )9IĆi5Թ:Qk 𙒚J^2j*\sGC1;1AHQ]&!N mI=vzP GcD54meu2Y{er#3`e)I*y$ow{yj=Ȣ'[jldXEKYUlgr)_dɵEr (,+P"ȎKq Y_ q"zT@ 9&4՟ʳDut,N#pL~>޵2߯)qaOG߻8 '^(.Xtf n;O^:̟gO^SH#q )L0Y"ش ɐl*JӋǯpHeH u`dEWcrr_~#b.+芖sv Efn(^o4?.Y|tANp"HnUG emђHPNOq,:d,ׇGV1^1I\07cmRS C.Y%? {̪7::I])ΈLޒ]-N0H (EESCWTzἤ2y˓.蟭1^u& ::vdc#& t&9wsnNn;mf4Gz=$r}%_I"|2O2¥E2M߱YP0*E19OO]QB@3;S?K*>vTR(Ӕ>g8R "oT0ԓsr)8ZIjN(&F3jn:QdTx- ˫*?X~J{QFi)#OTw\{ UFIdUT˨tLb@ETz W3? *4zw#~;4E)Ru=`u ĘD++][HwO@*CGH>g31b!]?/ p24LlCI-rKu Ͷz߲ԣ8("i0,O[$bZ}kAV@`[M ʜ-aB~g 4@=~SpЂ/ss\/;s]\;skweܚ\y找qÙZȃл Ch^n<8KOQ4^'՗R`WF`WrUM{<͝Sok="OD$L_!P!Dt gzM0,(-qXzxz>)LcNvb}f=yN4 L/!P\$.aFr_8'$d:2!i~IGYt$/sò7W~ :vhϛUPgR8O2F!f nl.a *.|Sۂ;|aBZo[$V*MO[|#W+4FUZK(l?!W{*nd'XO pt@mK)A|^Ex8+(Jvj˸34 g  "^^u$YCR"4)u:m)bq%]jB@S0bҗN(uBJBф"qȭO+ QmBU("#8F!u9L<"g!DDkDB [?Uޟqg{kw2`)A)]A!lA_A)`(2>8=lRMPa,\3L왐BA}PCIh<l?[v՛`zI \"kܪxnTDRsGLX BI-ςV/tE}tGDYHFQF a^#3-gJYkԧ퐢g&ܳC48ĹHH$"Ӂj3- @$_("v*O&>$Ix8Xh? !K)6M 4-h?)6i:@tX:X2ˀn]H23ElpOr{IA/7A{Bkˏ't`? DmAa:D@t;LR9f\='~] t`#V1 H{Tʎ@ H2KHX-P% *AQ=T$3xK;TqG,@8莂;D! {DzD*RG:DARm"SH`B'׌HOAS">%`T%kǀoy}) # Crt6pcTyxV}&[,Rj};C߮Ւy3Le畁f*g'-1M>oSF2;ػz,.wZ9h_U@Ty]~xi(WC5l/}'Y ^PCW k4כoTH`}~p ]Ws;CV:rk9%m 1ox&"jJYƵaWf 4%H8B4}'zJm8Lb@lYᙱ#9;O% ̀ooB!!'k:3qQBmi`3L0=F[dKz=Ͼ/щ̩ +|"܀ĘVsc=Pr ٰY bv+ɷ xP#IU cW^ĊM&C`2_ S|h!Tw\dGirחWi(`425 2uЬB!<IJ0K .z@SH 5Vf鱽3/A;JBmK]H-8\T* bF޷!lt !AW)nZfc+6FyH&'^bDS6wIƘ@0z-d3 ";k\S Tso/?LPW{j =Q]%Ď|WsVyzi!zՑY2Ʀts3 tшD,aDYFS"8ªE utxu"Xm#؄b-K)3Ku],K\:t?1 Җ{N_g$ . g `a(4 b*VP\4(j_m>:6f&ߗT:lv {ُ{@t* X;)9R+u;zݹoua!,alIaʬPDzb$P."3['O# a E_6M=ñWf(r %k(JsUaXFf}cCdBcu @š>x5+q;E-l Xj۸#".2ppO&Q;S|olⱄHE!ZXrX`vXUU{tdX-)&_iЏYG$sQRO0;A.A~ e8 䯵%pҏNތrv{~xY}]+Q !ќտ31jdMIgIKgisl+{YO=Q@d)Kg0st& @:oOK{t_tƽU:gҙdulӝR:K'ҙtFtow2J,‐Z t}iYtFtImmk]G_ʴM YiVFˀ%4w|F^ڽ3^&Ob]D6ҴuEUru$alcQs )UiDXQ( u |F0s0D͹Io+E+]De!4(52/xDDݟ!FDoFDpIAݯHŁX$[f<-e q0ڭs=q]o,IaC;kbA @m`qpX F? 7#xPC*)~p-<Ky94Z=Le|eY4~5#ta.;l-fq<=hd^^3~ P"gWs0M~=/?/-pZQk&(6U`6yh%kKQpyv _:Fnf!I/^S8~Qdv,EHSUs-E!UU'D C( Y0:a]Y5ot{jhSnm@u;}&u[Ằ0@;^bꂕ]Nvɰ*l=a9'-3SK*)t"] %V"nڲR2!6q ]cك@ dױuhwLg\hMKKɣ"9έD+1Ut]dbAs 1٤{90@'-F]UAw2/IejmC]]1N=smYJէG՜) ֘z:aEtO"B$eP|`I:Q*IQ D>v%FmJCѷzm1~DE3/ 7̊ }4孯:b(_@ը|Rҁ&jD.04T~kEe-zHcs?nۆ%wG^hr(={z;":^^^2a-GF{CQ4ʟpW{yؗw;M(mM,Ao S/s/RPcZ1N+D:*sOHߗ+`{")Gw\\%n`a#SxgR>͑ZL;9,ʃ;ڣ ܘw)QՂ:ˆA=(rf^Dhڋ9ieOtgy=E /^ޛ_yMWkl[rP82VڶNvN}G҄"GyLYԙq@\ATT4>" #I$A(. p[nYғd7圯KW4GXRSaGXVVs5BN3/@Qj=379QtFMgcMgZٴ#A&g2*ν׳32nFLC)Nv(j:ѭBʞ&S"&LsB5;ŔfDBzHH":m'}"2w7 $hjݣcfpP( X5\+i1o5BI(.^2_+/ꞵj5B,j㏯ay >Spz'cowbK*#ߦ,Ѕ9ڇ&zӗ}c+f?-SNdk{3a=oZ\Np-]{gSऱ>!kȚ.Aº8~.v~z~BPeA3.pr;iT̹nf0iP'{6F<agÔۛ;O|PxäaB zsU^bEf`fźtq 3(n4\ͦ:A"VRģhd9jxS %DWpq]Rs0 GG M>CsqƘWpM^1B pf++s'93f֗MvPdxaU>NMp xa Ape %nՋ /Ib-Ҧ_B VO㩷"^/)$;Z\m3fX5-8̅'o3uVo^5LJo?̘Tu5OHFm$u;c] znm![>8 `C7px.!%{mB_*P]!dpVWQ7.л7WGǩBoYɕ4xۇg|A<2 hȣ[zAB޵[}+I@`g^#^W2xBom&9%BA:KbE_{H `l #?cp9YgLf ^-B/Zz=fy57{䄥\ Y}yS4߼)˭ ɇwu^SKX=W s* c'gB}7<w{BA^.~4X4t8 8P#][70?iegc6l\]Pںa%O ʠ-^ 0jcjz1uK1.d5ċnXʱfz}Ko!zfB:Xz3eD 9ONc$3K K7O&a B#fBdxcj7>`DJA{mV"w9!eLF?AzCe_|_[nA}4 E~a%tB p=WDmCT OW73lFpq .T&.i_>՞ZUߗGA/ 3P 4܌"V )n3T )ESj#El&Q)eqGנ؏)X!EJ)R"c6dե>Ec}&tXq$KlN dD,Zr樷,8 \dV`:#?dROK_OjsCWyp/B3 w>Hl ηipq4VBn6sfO:̇<ˆ={x'zOʪp>/6NG6{ٚX-aywZ&J; 1 "fsadH<rdLz0.5CC@ib48]K֋o4_Zr!PnVྈf$ۖ'4Hp\R&4yv~4~/jAMm>4.BqþW%Cby VwCFSo3JS j{Xp! ݔ# @0;ͱ:p"00Z#A`)fNSZ̴Z32{m]ըMz"0h |GVd)T]]?걈j\%઻;]$X_p'hYE2>n5Mhl;o OM 2˱I[Z{/:슺3f"@ȆC d:SݝGJ}%0hѽYBu0䩄:љƊb.:U6A&9wt&d6(&| ;wQqϑ}Hl +T(:nJ\e"3'}Rp>ʫ~+򵸪h_" _k. =}vp~qɭi?**YE)5zᶦ_z1+pyTN']9bNjr8FwiXڸ/b ڟ.͕cu:hpWIVۖ/|5KڜRBkW<_m9zӥ:C&0=1.x&r=XVdۃ}2{qϪzsd}(M}Ќ_U8^wRİHA(C,Ƌ8ojztnɑm~dS=n=!* 貓Z!_c;Y6,, P9YUVd]^=d9:$ügk{)6]̋ mko[3W!8|پyv OyVՓ(0&rT K~ao|Ӎ/d"$To;OL[|/sod,۶,`o{£3KC_Q#0sk?mSBAFZJ {ifJSӄ@kjݸJL!3fx" }lBF:MA^?f\BڔhF Lu;, -I2GΞއvt3avٛ}4HޔetPv/E7& Ie#o1nrUe䨷Lyu#'?>2yx{6\1)1x\F /Y\FsΤ;%&&k^j%@h3Wxfj?wWE2HM = he4C`@53eZ-2U{AuzEv}d.F+4klj*ĺ7!<$mm Ɇ8TU{]!2/u^t@O#;3Ю:d"Y!Sd|-gFZ7VT-udбώE  v|t?b8o!:x J! =wZi>Қ0î!liHzo<-* YV/j=uG`i@+S} }I2[h&&lE+1afu)mEo$sy:\a=93E o| \ooNڽWVպvB ~zQ|k!Naq#"-h㩑~*Z86 t:v WM@: WKHOL#,T\|q%؇N|\.o^mH93)#OtZIpR~'JunnQW-sun7Z=^J;'vNIgxKwa;Rx<\vW9L`&PdU#4?KD#%e ;yiS"{d12uB6Sxi)Y~ 45&g,!_ K&bb]3bڠt|}cNśca<~܍yvҠl76VI֐3ڈldZmdGKv脯Tjw;Y>3"f%bG()5p8zBAS R;SD.ML.|:OեHe];`}Ox] VOCY FFhn Ozh{@'H0Ԑ*a%kZ/{JѴ==-S{Y&`Lj\` ZB}W.Є bP7oח?R8vgԛ*n`؀g |)z/([XUZ84|S>n.iՄDAQ,m t u잸ֵ\dyZO<Ҁ"R*y #PNYpԱB Cn}4FK0S $S iH4n!7N ߭92:Xh/礘7,ݸfLW3Ρ{(늙EyȴQ} |3"xƐi34M̛1 RTSZhG^+uBvΉy%h(3(|+Y,*= j*փ06g3,O8g^ % P; DŽ,,tFqNMl'd},:rF֑mŋ'Wd5kOvO6Vn{݇S=J/_?il!i/XY Y hHø*iw꫶_}{e22Z7s٦V|yt ~ZQNjaf3=77IgWa v|zޫU֪>tsD/6luH!9=R[ۧ缕x&_nM/#?]|#tgZ ]AQwb$^BԬ eڅfS3Csi&,Mu\<));I3 fqYb{Y, T{/J}pg+n::z$YPPZtnER͡TvT]G;&1Z0ڀ99%%GWelm(nGMPl7QhX,(ES*)6(v Xǃz!DbsU8؜*4TS'!Bju CWBg>I)*oI5 yF){ g/Kk6up BVf~^ڲa^^UIdT&]%˳w/mhL Yet _(1Pѽ45n\F=~}edfeK¿(e䨷eKy*\jӉli%my0EƁ].^&kT'r,/ Kd`j3ؠ9{fts+cS4@Ŧ_M1jܥ}5Ϭ,m|FUo%$u~fzU/(}E"<9X :F6rbh k%&l0X.;dL&e&̛LlɐEW}@̼G " ؆$dk]1 @$S& H r]£+naxbOB0=fH0ߧn9Ta=1+b8xl"IZ@ K qWk#C[YC5&RW|[vh?N?/ya&oZvrBsu:hT:zղoq3vۛsCс? @00bo{&G8y e_#n(m~7]|? fgiutHX%d1=!{f=8KBҋyDXPc6AՒwPBSj׃ԛzk6aXDrћ3k~盟][jlqL@iȩXӀ{ʩSxIp]d/%{h:Ue 2(e*]*zkUK[ҶZ)7qL!Ih 3z)B5d~UW#d1!l))dg߹rH]{]Ke>^,*`.p%(oAsd,*H:Ѿzs&d2PrJ9s3rH:!ȼ5MO)'j=&7<$Hڃ.=ڃN=?꿚6Kq 6s*MTՉT@WjPez*Ҏ@+3h reJ;_qig0,#eC 堝e^̇>Odu]R{j,?Ղ᧗GlpF; Ώ4ޣ` K_% /ِMPv:DWlnb L<|,k85mI@~Ϥ߿$4gjP:E8 qm$Ҧ `js>9XkX&}s0~'p܃s|#霜@ĝDEyx!ˤ^@CW?b.0;ڳd22r鳤\,Hx*6G3`?\qfyl zݭff:fh 5Xr!7q(raTIO 1*#x+82JG?䟌<U2! d2QiZݙ-9_6x^dGt<*IA1 aJmSI쉣2VîΛ>;>/YA0GTif r:yYyps}ys^8_fyXB/j:Ubg[12^?Ɏ17i1-ʸkm~!M\KS&x,i[n.&yq/wтll+7332[bښVYHDvV 鄔/Um2ā,%6Ldza| ۝W4/zSK3L|ޔGgTeO!Nr|"%(rm %IH)B`? ‚^dLgT-wW&;0T9[]@hbXs= 57,n/wشhzm >h rS ['D+!)r,W}($wM(#8$lU%z]-<֔c{Q}ֱ:̨ožCq}xWJF<{Z/`>{Op몆tMq< !Vx.ޠ 1CveE,j$]m߼+N" ~#!تKg_^9^44Y^ϵ.̲+̻YBLA+d5o^ NoKD$Ef3 c/U䵨$_3[2"3E/ܬ$B@eC/nsx)閝wi>9#dٛa%/RBA "b/~ngT1iYƸe,Tu`7'ՙarV/t.:3uƣή~g獽}w%:#oݴKy'9bEe1FwvW3g7lRA琚vi^U;=¶`re4wQq~=-K?UfDg<[ϸ%GzVg18(1fB5[uUjce҈:B_J?\AW8TĝBc%| {aLR C2yg-4EvT-DM; *nCiBYTP^ߢ/VB(XT< s(V-` B Br)xRFB6п~nХat*VLo@1I4ZUpLm1u{MuvX^25۟\}S{X&{s; tXͩP=-'sC4|$_@i":(QQMo SpPW&i ֊9CPV d_ ]C4isF{VI82^9vLB_-`!rFW)nZH8Iogy(wm5Do@NAa+[U h='6EI'KXn36jpm0!͞:;Wb TFX:τ<VojC ¼tջ|)Βv䫽qk9cJ6JUfߊuօ lldىX^]bfXP,Vܕ"0sėwͺ#Ω ӘTyሕ :IȪ37d^_HJaYj'kUж߄w@1?`qm&5/^7#^=f9Bfq+*`L; qFcxL}QW. !G$/c;G+#P[;8]&h53"nIZRCy9ZEHp>A̘b:,{0j%C,P|e|5z6#X~|t-ȬҷɃ󈋶ĦWӷ-j-μf1IKF="/OBSMB=&# eZOdOhd-sGXqmL1)@2\2\=6W h J2h*6*)hTa ^^$z8](*Dd--L"1z <ƱE_LƎa X"El`/Q7DcUV 0Af]W[z^֑={6ܶafJ q)Lvl=|X2IͲg!hڇ)/2ŽE(!IB4`w@HU(^Ƨ3inGGɴhk%C;- \L 9 ++)J5W/ vYhWa,7]}4\=iOSQ 0'Z;ޒtL|PeOij`= be1<$d4@נW@Bk0kW؊K6.&/X Aׄx'Vu'%ϧ iQZnY` l)UvpS ^+՞6? z;oUD0>ko.QH_rn[d?*q$KފaQ$ J"ʲ9APrYx(cs(,K3Pbs0E\ 'ctTg"kUU㤖g tOОafMW sUmZa6j~ ~ PF ~v.WI ngWaQNI5­AVW{t&UVot.7[㬳Ы MO]ig,/^=o9F]Do,YރɎ'd*-d$#3/85 !i.7h8hcFT9>Ir罂,3avOݎw#UǷ*QTs%&5"W=5w)mE(}̐5+EU԰@]Uٙ]Z0,JO<̆+0l <w<3EWoa[A̫v ڠhRr;AC gꉓIgD~ОL7J0e3د2RwtbA(]vD틉V㺳øq{΢C%5ZchC3w*h?:8P#nk F;|\Pa̽M;__a'N2ti_w0~sYN: G:h&ɹEA7Gp! ;A@W|: cvLKj1G b{i9h[6AiEj"&ą ; @=RUBv=]C|[lDK]C{ -67P ʉ>M .vtwu$ gG6CȪ*ZWQp5wW) wWGmũxnBO.]}ї .-Q[ S{^TCoxM[sE'ݘrVR&:9N0isv:?3h|<50uFwF:5Z݅sT*~Tjp<~ ^. $,U΢(^aGHcTqnx 8,͖p>hN> R]%8-PkB}(]_jաGԈjK7f`> E,w&c5^:/^_Z{q`o,.%hK&ƮOHvV+瓎e"H \;dEJbBEkѶ/ډPwsdtD[a8`|`Z89c-xS=@ϱ@( ql-NH Yg ;K-w` %qUПwws^ #ڸ9]F!v `2 VsXDnR]'K}2Syܨf%%ATLC"1wjcP m?9'eQ';`t,#ۆS֢[@U+]jNG:{}O.t6_h͌hzo)Lsv]j~Ogm[||3f9>wwrW!HsMK..|wPwWtУpKuO&G>PUnlDفrv@`J8ҭF{b qsW,Gt0N rblT nh2)BP#t ؏~#Oȝ_+uhR$_tyR1o 'jC׷}׿o۔"~(iDPb h+DP XĢ~(EP2CI5o#F?{#~(H0ґ1ILJ^zdUDMhb`~lj+6S()PPۅ Cm IboQ?&~8.}]ծ>友k}[kv,K+Nׇ;j߹yQMmTОR XV'#@sW/5JVH@Oٱo0w.UfRzsr5b@eG5{1<9' jgpR F5Fz+u`[swjG~YE6e;ϵ6`T gCmj$ krXˎKslXaD!~^ev]jW[>R~d׳X퓶 Cc8o U-~?댧O m_(={ o~.I0DW`n5NPI5'6Tp7@H~ P͸/%C@ovp V@8uMi #\d7Ֆ[4_{ݷ-]R*c;_'1%׹>"` )tM`NNh)R3}sS7Zڈ[&=xbqBl?BN3o~jJG'';҃02um*E(ъ_WbG8Y[T!L"Q .W(Ŷ^LrITy7֢VV::M5&0k#B+ܶ?voM4 ]6o7hOL *sy.3ע|>Ă {W$5D7@dn^xu@*jfZ6s h_ڧdvljɗ_kWa bl-ja+ tM'F-6ѾSl%G:;9篏QN HheXO3[IZWȜlG:Ɣ<s/ϺurȰ/E׭KՃ{.,3`zuVy1 2`{kߜADoC؎>+Lo ?0d GlYN#=0`zU:) 6Ss>Òv:'SzzzՇң%piAwA1^m̝w !tn4iH1ql@C5oV-Q< qD<Ϲj W"aFM kmּ9ZT);h1VM1(V*TB]'ʡcT9>7tZS]#_.?c?/\:tO[kH7^5x'ï;wk= AAeV~Cum_6~>囏,t8a#[Ϲ!Zxwцߋ6˾ "_9J#v, fq`gG(YeLr,#r=KАk,jw[OvybuaGm it Ƨ?Nm3kewmW74 דm^z)D0FxIu? {Cޤ|$~9-ے8\Ĕq_x;EStz=/Dqᙉ%b65ޙ*R}FkNޤT I87s`xLy1qѻ<;tx -GY  Ydg0D(iWtݷm,vUR6[4=71Ul8⎹P'ށ{yb}TlgA+MH)2n% {~6f#-A ۝|Y#cÔV3b\x͠2?$Cm~0{_=*Z]}`[c 8?X#3!U-01˽#zibR՗Ĭ bmQo[Qս)vq΅9RNnV'feW*+bbwbC$vwubqe̜8W1lqG o[M6Nԉbw{o6Y'Ŕ-HXv߽|]CeeJC^˭VSUȸ-)aBE^[P\O ޼$.6+atsߞaʥ{Ꚋ^LH>fTeG!f$NJ|r6+}_Ԝ\D)O >2Iz}(lfpܦG0U&{K:FS(pVnI^r 4a9k61`Kqo^Rk_n;D" %a)gg@ u D0|u/񗷶 vC æmx(G}<\=~k.&֓1LlfHیœ\X+i$W =R@H,ੌ.k]bl*3ji*XZ+~5I^d߃~|6~A^opI=0 l^ņ\J魮l(c`/VDI6 m[/d+5:'}^Iy>{TuN>2#v"sAI;f)jVykNtkFlAZĊaaڥnΆAVꝹTqw8;P|5~vy 93t8;慺W-MD^s4|sp=gYfZV䪫*$a '-bȏԊy3Yl&|??`{J0ۇrӏ,:c8\^7qrqk2ǕڐO%j Vے)-4磭/ ftm# g\.o FIf(Hpy\N(tٶcd{;cFR@qv^_\@}~N/2?^Y5=̹Q7>7\Qw Da^<x01RoB`a|~}iF, ('M$au{) YAH/h&gO.V> Y#cu95 ^+y>U, @ɑzR!Ut s>u.V簶F,Gh0,r Wn`NxY‘sBo)f#Ư#"sJ݇D }`[ChayāWEM-BAXI puj4ۯa߬*#W9rU~5Aϑ͛0O2ԆU"֐ijuh镱C`H@vǐDbrX9Wm"ڲxa)7bQ(I`=u^iКF׀vaCՔ my8H] * Q1CVpǍUH2+˿zXP3)2%Pg8rzۡj#wʨǔT+X0׬K6 h1fb8mZ-FrІ64ù,$k3&LNi Cd\7V+B⊑M7Ήcم1ú5zu~Xd48^Qdۈ*({!u#A$M)r۷sXm:Z3Ma^|b2iba)0d ̇:[}4$43Fz*@ ]{]m|;+"ܻZ#@v*c naSuG\ 1oa dS<!zL@:wt,LDU}PXHA#H eXצYj,v9 *YK sMY`Y (k?VNfF,;4<&)㺙z?V}HZS)̛b`qÈr僰aykm#X^\ė$H>0)xm1AQD٦="C؍{XL۾s.tDa=M^â^ Rq|d\vCjȞkI[aeؿ]~BSJ%-XMd)`A+Lhy(0<, yXܩ6V69%,Vfj)`eNJ XX5`}.̼YNoffo6̈́Cx}v~XXbpuP0NH‡ƚ zIqNHX~F_ %<6N5v,jtm:•^ַ )]Ix6\XoO@}#=l͵oMh,JBh<]TDVº09xL)(Ao]?EDʇzia#ni$/ӈ060X7!n #l6iWLNj%ς+̨TZBstQ6)nh2NBT6bMhn ߈fH͙`7"VX7ŎfEf{SEq2Y0MyEwg#gO,!uw|CwPtTǬ^1U%~SFiq]Yct,#^R*o'#*uD\a'2lZ̀=쏹JFsіIC6EJ/L٥#elxO~tOg%8 H8npvYR)ה; ݐ0i>g^ e0bi$@=p U$ݢM{.0f#? c4 KlLE[-W@V[CDk "Rkhk ,ϫcr :3x$3nt&Y𗶞OX`ܭ/=e1}u밹8YOG=E vT!?糃:m-糿Kt JF=u!cYcU}i=oJXYp ܨ]s>(GvJ'󐆖l*',ouYlla=4~(Xݢ+*h%=oϞZB $c@J,#ZU9GWxURd˯p 58,ko}$e7 MnQ.KtT :>JO1F'o߮ix@%miW {t)_l,n08O+Z܍WWfNbj40,f9!/U=BI~cF/N0CѢv[^!EG`jۢ_M,mH;@YE ߮U M0wZ;Z6dtYυ]MeF#6F=dWf4yZg* ^OFH_xwU~[aGP_M0}*odWN(Y}72dvaa֍.^ <{O)wLA^Ҳ6s!&fx֋hvE[Ն zޣAM@Gj>E?Ux#0 ʑTؽZ$)OlҏI̼'McbR {1gErEHzlJws"܊x7gKxQWx (M!33G&x xf)H‘@bÃ9O)9RRro8 RQw vIUp@PۼHfG8! xiA7CnW~WEXʯbٶ8k(J}4]Y?osC|0ݚ95f=Mh>OG{r0a2oX2$Կ+~̯\gԗoͿ͟JgTפ'j*lW&6yM: a`=.]qՋgɂpYiJ{h7?v:ZGh6 M~|^3;.߻':t!AÃccV$o%TV[ %|m_͈_ oT67 S'xM CS3%̌#UWrX~YDv$H{Ad'厴B%k v IaHpx$qIX'3c4a#\d|U CSdi&NY&xbmڞ6Z'p7]Lm+@-بdP!N"VJKV<`U%ALqNӚlcu5NYX!NMDvAldzD$z'g~2ʓIb&س-XD>ZSFBJJ,z%&qG$1 ,q )OEɬyYaes2l`v%۞TQpdp6TBni414A!fA6_5:S8Kr0F@3E&?ex \/:6.OA̅@I˗5G":Uh׭ Q?/A,M ,W*(L{Lg|bb;є)驐LĿg$dbyS8в!Z;1] AZ5lQ#\_ A`Hd,Ҍ#^QՄuS'3;P[>Hm&sle؛*y5^ !Mi6.%0nH{ 8K;$rT&<**P-ї ""6Zh Z/\C  _zlY:Mpd~%y뭍\Osi _N Ȯմ 8o^C-Chleݢo=.:ᑨ:fR@IZC@һ|V;EUޮL.  _"DJ'eȶzo /9CݥCdY`x*vy=πX'֙<2O:nq:lyS<2_?K[K[צT.k9v<-}]oyhl3q/YkjìL~Q/l1? f|\~KUؾ*#okY-(tб[ =X$*CouUR4U`kё9';%]F#yk/;o*cDW;0~~mW8<:CH= \dd'+ Q+b2?ׄqk%a H6+sn.'M"Iݛqu@9}fէ 0O!:UYhx m/@dD<"ie\L<$ z__&]]iN*r6C#3(F#32¡=$y*xJˆR|㐎4vRxn ^)"ym,I Rbxk"+>vWjJG)ac#xVXQg@&ds/7_VXJQG1._:JG(Kuj<E]/fe%_ȻS#ȸ)T $]@%d]Ded]A5d]EF:2udn@W5d]EF". BE^{fК{0gpfc#c] JK{U}†3/GRܱ8g3y @7NW=œx뷥X"6 ۽,XSJ3|ab-o`PD+N5D[vKu:;C+bф.Њ%U: ]~ { %-r2QmfVS}"tҹOlٜ:|3&/$4ye7\>uf@u%+Bm*ͼؼ&NW?kt m^4&Riip5x͜ ^+qZ$ԼET:f6L -SYeB+tXpEAJzW/lE«9( ^Sˁ_+U!d+t%Nkm;wp$^yO:"UBhX4&׌ecZ!^:!6l Y 4Bvš !c6L]Zvy )#MaLXu#xcbeaa",rylج wh6dEY yIsz@RbGe5ιO^t?R!XLȽƆWCl 2sCZ:qd;]|)pq Qi<KtpJaULyQhM_gѹ&;Q7nZ  [MaN׭^j I! ᩲ +841<,?{tYj[TdH8@:X|1\Ê;|/͖Yv*/: Uv֊\#Qk I,;$0n5gDOGVvߡHp<L}\L Qb{jhTŽlRelְUIY;2K@R&`kVN:D oώmD,.`ggz0U_>|0e9SeƂpa =X2R[ v7ܯ["ZAhJ[CinNЂ]}_~;߱;cT~ǒ;)w,Lyw,3=#;rǒy;i}ncqޱ~ǂcXhNܱt{/r2XYy 'X#鬚ܱĀUXy|ҤW_xw,dXˤdž;utpB4꾤E;)!2>)*O؀Oj%;I p]7M2ÜۏcI,}255;CJbz0l/ SJ: ^O ^d(%y6櫥c{kҬv궿 9!IjHHR~FS^q"6M]fҒ,P 1)@~ڒ[h[~A@Oi1Q=3)-l»K~lZVPǐ6f"H"CH7NNa֭k>_+3p ۺV|/)v2TGƁ$̙H#ԃq{4\QS?'|Zey /i{]ȮWJ cž`V1x*dƗNaCtAN߼(r$ݎN7 Fm2 5Jl!̮ﺱ,P`͟Uy]->0cy(QOv_Laʷ~LSyKzRa B5pl,F豹01/Ӽ@b'$Ny@&x?,#TޚaW0""S { Qb1_' dxYZi>e1~IhnQTp) ()+3] qxP UclLje|'mlzWw0M{\5r!I}wR},@GΡĜQ`$8/Ç%p0aRCTCRc^m.y)!y)!y!xya7qh2 k4SٰX{(Z9ض2|T;zsJՊ/)Q./#e5l׼0>&M,^1x|(rw>bm/6E)P(1Z&| 2/xy4|(^ƁGEQFvG<%FZ$' _ Ow#@ENSe.2 ¦,G"y`Z= 쪺AOʪj2ךlF:b:W-Ũl,Ž:׊8mLWk1h3ƣR7VR5166zL6 9..<p`.iF #F"eFfP#@ Hب׵J A d0 n#J !q;rG~ύU/d :$ I[f=U]$Q6'Pƒȇ ?V@Ge]+f{_5њ+fhmMhmd8hk|D@ͭ)nOn([\?T0o 0Vl3_o꫁)[6SfNu4&cv2j=IKJ]>6Dž8M a9Bʴ,)Z NbN:I;a'7:IhduZ?OA6ZhNj-f-BWhC*N*Ӗ;H;+-[J ^tz+@kl S4kK+]V^.Tݯ ]V'.k۽.k:,3N2w]ސ]vNF]vRb\{yY&ӛ}5(#/nFs*c!U O+Rf1"7Q2E6!Z61>[(]ĩE8tfֆZ=a*R'_"fkd5)Wt"t@ Geλ^HBN{kڵasNgo3NVzET6VuYnYV֯֝(-h֬֘(zuVL곴8QNhDy mJ44{S=?vyrqj?6͏'q&YZ\h?E+jk՛]+7ҚJ}zY{~Wi rC$irR"$hrO[G]aԡmmڢ8Wmj"9'Z/4{k/kF9Pg7~3]iOyz&BXz/kشH,f2m)d,B14QNf!0"#7EU T9/t!:'XEBR0),Bb '8Eูg>ǍfPHRc.dZ"r!.w v2RW]~tСC:8=R\R5@;Zۋg2XۗBhLz%yQC5 R)8AAN;($s1hUHIbiLh8 43X{Ct‡̇& /1Sc]tږ65_ݭٛ!o͚oR7( m{L'nw̶lXSpvMAc cr}ZZj=vIzSm{t:WGhb#^Fb4AE={fP:N|E+c[@{>!N-,й逃S:?ظIML0;14Rq4r4L;"ko1mrxh cZ +Rʼ'Ѭ'lj($r H\q ™ Gb`$bjoc񵹲H/.Cl9Ӳ*WblC63V!jм-ܲ (\"#(6|aڂ |˄:H\RO[h,F! nZHXm׎}v|MxE;+kC"cٝ;uDV>sGxm70p7xgmKM}$;oD/(i1Ҍa@ERL^PuZ4W%`dfH<Y  ɀY3 tZZr֩H 4&Tl;a9CkMxošj瞲6YҬ]l#vwjB ĬmFS{w)fhA[ 43 nhO V-ql S'h~ iPآ Er%PF//tH@K&EB1G hPh Wh{Yɖ WeA j 5~o q.č/@Z-2Ǎ&,^uchZ/--;WέP%"иE?qأ!{^9q-XI@4pELs< hn SY2^b(ߔWzNUB+^@&6bq!WJ^-;ުlxj^q c/C*_zC->Ao}p'6h4Y"8Q zӅ ItKf$"^dsb{Ю8[ߥʏ 6fY>YwZɿI *?.gܲ@e(X!6;?.Qn,Q~δ ܟr,cv> ^~U:<3)>DZV`l h8C}8߈tCXגl֡Dp ]xE dX#G?MbC.lMp1WJ"=KXu5Ɉe9mӸ =bк{>,FY_s .פ/[fK+.6L}Ws"[00WtN8䧃ȷ c=&UB$;Ulw`}xX*E$)m]gC6Tnc}~%KU6y6PRJT4 ?k$'; nY>#&]p+uuhzp-< uBm2-cwT(75-Y7=Ѽ44T\g;o6cL4v 40d ͞^އfm:OFW޿$zgœ>&G}N[il[y+u%*r4))l}FfRCCĿw 'esaZ)oZM8E޿lr4ሩq^ GF.7pKOrQ4s1P$Ы|cpH=qQEa8 x(]Ļ)eR'Y3kkѵΖ9pB;F6BvZn;asG|8+W9Ti]286f'0eҞA&ŋE1t+îlOӁ/Z<HFy [ߡ C<adgɺiw|~}"+poywJ: m)%B!4A꫄b= r^noV8JAh G2eteS%1&iuV?9\)r?- Nv3*9Z@H=8SA]݌ru&[ɽ5(`PCP'Aw}Akti'A,zT{-Z/\%1|Do^oR8 E7;G/~?NNt^4$t/+~:/HWn;ZGkD ~=6l%`r"N HW&9+z=wb0nF]d"pW1:9(7#GqU aPҿo.%7|tXdg(A"fcOީGv394@)XC|Gn3;˹OeBdt { apshfMZ&LQx 2g"Jc o?!I±kyМ$7I+u$R:baBYཌྷmRapd7f.@srb(z7XHzٌ-Qƒ@IAТoWy$qFk*3;Zr7ј镏)fzͣ'M^`Lru|L7*(4IǴhʈЮ/wF^ٹ@&-w4N'vw?IRnB?ʛs'unOSY-8+ȪLomZy; gnt 'uaQO'"V8^×t8P^ٙxi'm_R4 X\sxvZĖAkAzaGJtBI%w]&\q*2p*yP[D_"Ą5! 69=a#Dbwwl ~9E]3,K ̑ %`hRфgLdx0иl򐬉} hInp!9&BL_־*0sSLl8u65w pYWwY֓j61ǎ#|S /z ^\?&J~omRQXL6cҶ|Fۢ|dvV\Gn5O ^:|u0Cj3x>1:DӉ-4Dm4L֭y{7m"@ˮQYm">3b14髄PF#{LwӽeN.^MkQ*J@ʢp?4pp32Ήju9j:tpA9,!ڀ1Me=~D͗?].Ӻ9!u2^km=N&<ZaUpRW><^aVqz`UwY;z9IȊU]KᅏZ)ͪxeI\c=eʜBc,hQY%T! gT.:AsRe Ux؝sT&AX('˶kɩ*zjUKJ:tz`Ț Hj 5ae!Ҏ<)-K2HNBY Q|bBH#%:O8' hӕ<) 27Lhl9HPS,@ 1(0sd Pjb4  0%D$ej5CWԌyuf8r3{\r܌a~GX_ efP)(8Ϳbm@6 KQLġ_![%7#@w$FJ@RCH W<@55dQ}77[_h[!_FbCpj} {#Alm[vVM۪IuBz஗j7AդL&?ԍϷ,=]t4pCTJhAD59v?oo p'io&Ś·ASyܣ숺PaK5Af _A8W#Ȗ7Sx)$SꙜNZ)fd6|ےD2`6EGSaVP[(: hYvzl}abޛW.v_-E(7^Eyk g0hKwS1!̠#ÌYj2y: S1צmn`fmaջ~kh,jƪ.^_5w1 :_0y%G*M?UX' Be.AП.Aџ,?UI7ac U.KJkOP/B_*/+. U9z]YzYyz^S豄S 8>~72`3": ?gJ Ǝ*ԅ (qzS@Io*k/;[iZ#dswMF]j_Om tu z^@/ ^n\wM ѡC#Owxcd0]D1/۾Pw't<._̤Wr1Q ô"w=#ABtDԨD|B9]A)vV,_|_Xcg0u*ɘ?21lHs7˯RU:A=o|?.NUߟ]ϭ/wSÛ|zyVsY?A]gm)d to49Ry?&G3?bZLԻeW ߒ౷£^(+SnX-v[ꎛx,2C}T>f}V)`f8đ8AZS;saCJR4DV9N#hh"v0g[Rw@aPm–|R|{`Mu 4oM!ZpdMJ_zFqQbES!ǰ;(~с chp,y8Fwhba0PNx?3w=?Z00Zo.}&ፎҢr`hr߼0Ź#_/&:EX-9`Mp׹$p`!Avo:%Wƻ3=Rlvhl!PR0qd&Y-3QQ2c&*zԮ&dDbfFJ!!o D0i〜]g- BH|`UcDL>V[0T><ʘq6܎+ H5=Α|9\ةY\t>jj-b oS n^rG%ĜBoz f9_LۺL CpvhϏA24=qNF(dQ$--Ey 8%9o#w&7&M %l5<8( dȴb_ZHv$0O; gÏOJs萜Oto1, P"CB3^m hVu,-VZ+mTgX'UX+7Ql"F?8c! !8iǚhOBJycCݰ:<7<{{ZL;)-6 7MJ?ghkָ9< rzO!4y@ibƝɻ_fm yLy5Sjm/ML :kz.ؚqh phEP_'^++I襒Q3(ȩᢉ 2ѲGqU9~ 5\.ha4(/i4G `槄/_NC>+CUb&D#[e]Vy &0/3 #(6ާ&kjALMSGwk=>'C]4@nkfv`Et\If{-Pb S'L,gqM_d-wXD{CfұXsX,dXqOXK=j {rKuE,Zܐ\aei`cq૰ xX)F^ce 43x-[Kؼt)E ` N\X_5a^d޳ !p43oKX]I5]+}EY`KX 6`9,_kN56ba_ˏR5j!g%wCcYXVX,K VwQ04`]/cuVHjr9,]_˷.?eU T*}20¢7 {RǤSXQ~?' e͌yepHo_~o/:t<8T72ܵ(&%\z0at05L HsY'j DIRؙ]sx(u^9`KC?p* m]/V~S _>2iQ ;/.$\3,"3} ȗ¿6&j)J/}ʷ6")C5z7/,G>N1_,u}DsΪ$7%jMv_D9M35=Ii/M!6; ҰzX eW0@3|-w.?ף wW} \ÓwM>|m-<3 ۃ% ƙC' -҄ဳtoݮvʥ~cwB8XvZ8i n"ZuWhzW/@6}uA5lGs<&@GZ>hD[1!UE3@7/T771j0,w'wE8hH̗6F _Dt-t6L_ ͒-DoDֵPS!TЬ0 Z(6+hmiZoLrDHi 9-VDx6*'R-ϸ+Sprw[N&GNƬMnN&wen /l|gsҘtZ>OcOiv?JA WݤqR#8'Βx+#Q@2Xm _y935@CZM yX]u\֯\jtnrZꘆ+W8*3W3+WS73jgNծc̕k9r{5ij'1xsPX]'  IX ~Kwe§Վ{_~gXc*)Tڨ/18hxWƈI`@ Z9,sԉP^4 M.KmT~ȹ[8ZtW@ŕw i\.T`8̊Ϻ,Tv %FvVzCLs^Xf`VE`,)O=h&kA,^f̌2~=ʀ+QGXSټC'/Є.rgڑ܁9zZfkxuĸ}ΑC9˒yQi Ұ.._~G!Go9Wwtb=<1n[=͜E6-6)}=: " AӺ=!0 `.UV0B mµvl[h4meVHjaek'RF:+b 1 SeM 9Q_; +[aĀZc%>Q3+ΚQ/Bwv!+ deTXYQFAǷFe#E!`]9.A.VpX)3"X1Vh #X `M pѭ@-> bde^nLM&&bD?'ω)QRb2NXdx[`2^2#ʖ :FVHҚ6LJfhQ *;2s=OuM)qh[?ݤv'̮2d#]fߡ]fe.Y2d$Q @ڞ 4 [#IE^`2TdGԀ^({P/.y1Ќr7<Ç.kF.2Hw2{kteVk]d0ʃ9N+ %=2˞“-qvD .-{=sap~vj2b쒑.{t}.wJٻ^f_ 姥2[W5 ogO Kx;P0#&^}Jο;~7ܕMqu>u>@X+~䂤#5>*ycC=D@ٓ+m0.1]y([Z!Bv)cR.10-}>z&<䌏t-bE>%[B.'%kSn#je.Ի%vҽZ{f\ZR,.6-O{a4磲2>BM>&0U6bcK` :pnA:^~pG;e1jࣗh*GsCtnEU-}xd:AkP!({_(~SC:-j)I,.^#vL27\Nϲdhl΄nN$t&etnmlٴ+eKqinf#/ʥ+?-n\/"o#P=erî"cZ2-L-'jnd$%7YN˺/e#95ALK K0I%FFV\eUmJZe - Ž@m? SenaZj;3r(vϚ{n<&Q.ch`&7:%g*jXELur 5/u嶺VB$P%b*T?%BHJ>B%1s@KF!B/AK te=[wΖ | Z%vIՏX U,Wϖ`J0d ܶX3%2`}G'ÓJ3 r4.3M~+nn_؈z UwuFXj>]\T\ k,K9%%mDu`;Iӯ:XߜRB6X}+70NmUH_e("&C<_vU^H~lKEty$\ޟ)Ĥ9Ƣ(v|?AsԆAQ%XTqu1Q{G~Ga˿-W1P'noXisDsq!qdu0?SRz#Yx.و^f6k6y5}u3( qCJ)Aߋم0lspioIb"š-ڠ)ga.YKa?@,H1#IVZ8 B‘ھ$cέs`%)GT| J;~d 8s}זıR8z HPa>^ϙ!# =.Bnt-Γ ܱ(>5"Kx~m/t䌑ΏJS_n-rD> ^" Ye]-0<9p~Ec-c- /n %--ka`U8O~ _L`3t:L3217hI堤2 ˨Y><[ʜڧrv;vK[K:]f'̬2,ͲƓYe涬2kcV%qܐUfJLbV$ڃq-g9ϔUf@BV.9.w. 4;bwuN_2;4Zm? Hէo%-]f.˷2@$gj#<29h^*߭_y2_sg1$}e0A1J?f}l 2;7%~p]dv11pGU҃/_G#dֿjʧv/v{IdM% iG:F#+aڄ;:Mzݍpͧҗ 韨N?u?ǯ#w_}ZL ؤolMֆjݘ]ֿoo[ۚ~" nf94F(X@੼=vH2 0kWy )$9,)+=',TXU2xL[eX! D!K.Fyj! ;&D*(wUpW5c}BhGkIOԈ,\/Q (3&D]&LL q8Tn˪Se.g &L),$l#Mkz$kMhf\Q žmڸ 5#;8Y}d"&STE+fnl~8$%#j{H?\~ԎCAB_084!w0#[cdd}aʗ ˂2u"y >A#6co OJ`ܷb ʹ4g@բ6)h0BMk)e +fMpB7J@كRHU J9(%)Haiie  ʪHAaPWA2D$σRT( W J)ਊR\٠ؙ-ŧ N7BBDbAio`&H|5RdiAiZ)Wૅ&K+㫉5& \_rgB PDfPx/%aN&Goj ckzJYqak[$mÿTkA3 ÅjTlgRƳ---*>١5;YϜȝ{5v9)$U9KC&靊lœN9,0m[7 倉rt׎@Ѓ̞sJɞm1VA 2쮅|R<y) Ik4KvU ),d[siQ̮-N҃ Qi \$iLuh\StKT:Tdƣ;9# i-ry߉ ]U-;m}0nG[پgP3/(*8DVL|$^HP;|8%9r,[ά]Q/,vunܻpr 1d$$S@;YRNѩ_v/xbikd׈h49%e}=@|XE+ۖ]שI;77 K z$4%K쵛'|3u2rBEy@v9㮭^@1%B)Ea;rHkX2ΖMzZͥ}Y'> cdLPLbTdJfƇ V9dȐ!_.y] ЌL̞9Z4i;%.$|Lkuާ'2pqaӊ7w|EBEʣ[d,o3/ƥ9 "KX~M*-LJEAV:01or(n D;zK`H^8IŜㅻ5=;SU<<4(w&~?CpiםؽWZ:OBw,WT7=F }egMVp콓MZU:A$ʱnrfq+{}%A|AjEޫ:=79m>Y륖;>ʤu7& 89ì}z7ɽfDQeg (rʍgwI!vqg5EmU:Rkn>;hvj6i/Dnt0Ig"*q[$F¶͆8VOXV%˗_X}%t"6롤WCɅJEhl6}\JgIuT7m6,geIC‰to2=*TxT'3l,^mM908[DZZhuvPMhwJBIq2#GAE/C.[ta$3evUU^ th֜֎)#wa!L#YMT3  KtJ{x{Lfyl5 :#"2tӐmO[}=╂}bQCjNYPHEm@c.}e'jdM7k̴1Lo#H⭛xkAщzw/Ǝc`R*/ĥ T3QDI–i]Q}=ui_ܜoںu/X3.&@ '"]O601R4)WX2 yiig ؁JE>:V:aq}w%|>}InqI\f (MZ}cv)U+ck=/,^[Jٙ101&uj,iTzhRɉv*t39{Bki`w;^L6$JA]׃U$`=Enϴ'\z c][b!#bL¤vZؾ 'ܓ(9מ Z+.>Xw V9X`Bfʷt^' Jpu:>?Fvz,/QͲ5/r&Θ`dn;$˛sˬsfZ'~2g$IwVJr**|WU~ odoY᠉±WZK۹tqr'%| =meUaj`Wه4iJ^nײJ5{B_$eLUj6rU.Yϐ= V}cV]Er}V^f{{i`UjcG*w!,MVY*(&n1aCTX_~?6tIۧzp,]lcÙ8 B|5Qlv=ƃ21hZEgm"ո8.~_-[]Cg.¢A+A +*`Eq! 1h~c;M+kEҎ@YdS@?mYap`qkcp70am ;LR+z(KDSiSݦ&O|)$L78ȭvsx)Ї|ꊵUX{͎#U9N'[3r\'&9mzW.qxp1{{u&Ɣ$c}R}Z ?Xuچ"5ў%` v$:H} @qol$(77:9@n- p0s ïVEi]vlK`r7 #0s"? {X+sH2,^'\y!{dpNEbȋy#–;:YvIYeSXCC"()0ܕz`sюa{GÅ0'6p(Q:9C|2*'ץHr sFU?ɻRcr sCwhӓ\3̥om P.(O׬z?Ż\|`, &g ,DhC PtBQ #nAP)~1.޳*,au[#1߽u?F ұ.$c40Hx-yc\VZ6<"NDCq1IkeYx.h0j0: /ѽ+MXCqT; TD%eF3 %N*bLBb$Kurdqr =u\~n0:~4h0WȿFnV'^uy^ØkD6S9ntob&pWhܩwWtMfGy'>2ڡg?1|˶lN&HO_'c02`tէN{`tL- :!®X=DKoת F7][`t{`tC|1$tka;\Pe^P6I@h3d̩Fs 6l6.Q3"E&N,s܋)}W@r A׮mrH\}j+4l_K#EaeXiu5b 3Uw@<<@tj$kYԒS&m|bhtZ3D9{cW& v=p,v.Sמ1YM|/? ބwA;6?vv"hYqӖXtb.rWF%w-xᅤ +1ni6a.MZS.&R`֚5`5dօׅirKiaеP9069ʴ(,QlG&4N`Ft{].g6T,ng XW(Պ{kk9'+5*`@A߷vE.K(,9 76l.E ;c>AfVCy(@0u{Cؠ: ^l={Y~\m!ɞ0+U;#V^L]~\eJҬA6R&ܒMcXwbEG̑QV]H 8`6㠎:߃:~`#,hϮ6~au{CPPGdN>uL_RGau=̧{ϒ:/^hPo,H"tûQ_3'ٞwGp5.UMb)BG))OϦiN򱣌BvCBvKy=xi 6&2.ߋ$UMx.(|Yg&դ뱅:@4s/hjz_,Nc55ztSNXi7XHX)8rzU?PRMq$~=[ ꁏŨ?r[ӪNj <,4>4PQN+چz"J=F(Tj`Q+rHfç i-~͟yX(wDH }ĠMv{Ι!rV';k}}7r7u}Fŀ}XGalEBZ>W0e[X5N`&RGW2&|wra~MpV=p`6NImLO'0~$ho$[b3bG8~}س~bշMO 7؁I u9!?K;] F O4v9nY%\/$M+uw_#UA4Q&kvei4& ޵=-_nUkfjkwj?QX`LԀZun 9T, *w9Y$z 8}%$7Y\dq>?ݱ$L$|O n>e uT&Mij~ Je۽SAM9n{۰fcމe/1T|_ I:@;E`%rrnG*aUvAy <)%^Q)u9UXH)L39ꏢ&t'D(p4o|Uwl34oJ'*wQUM_RߜQ[7ymJ+μ҈^HHRk 5x!FC R"3%$0v:(M&`o248be/аlŤ+c #3yGN-5|T4D͓<ƣ@ɣ4YF8Fh A~^;mHQsU#\4 h7`dlHIͳKU⵾bsYg94sV8FUB:v[2پm(;RyCpJs%r'|c $1 0Tx>zf| } 7zDsTAzx4HOS `L ()}:c0 LQUDi!δHVv57Om7?y&{3F:> '($aiV04z杣 W6Sb7Ky7rYrg iqd<&}cic# އ# Pزe/G[8p:az4x^%m8[u4i0B@%@/'[+@^rR?MoۯRK,?Eކ Ƃ%TԆMOk`5t?~Ƿg@`K1 pLgFU&[ cQ}E|S5F}* v]B5sa* T3`cej %rlÞ.jFw85Σ'6a`G]J1) l'!Fp(P<A+L!ݝPI"9*hUuAFQիxZQyIY.Q]Gf"_ G*5\} s#7 62*qLmۭK?]2G=Ni7*2w.yRu:FJe02,꽶FC\6{+xK.ad&¯";}5>;]N;ɻ1̦8wdl͢.-.qJ8:zlXXM`Q! Bo6ǚAGHP*ԃLsJ]D&pz Ѣ 4CUoY8s0]Xyguk wLgH$R_2Ϛ*TAK"Gx U bFT1L.* \1#qDP6LssCVIPiJzm&+y+])`@t&9LjGKp1 dEzcdwv&2[$l.Bph\kJZjB^/Na=I?xV6 !s8dN(3ӻ4ODkG5?y4ymAvPmFɇbrNNU (i"9~r!( dǡ6R'v?69B3eq(q}aĦ?DS?֞kA4` Yٵr+}'.a(zXGa8b2Y+_SGuqـՆcr6Ļ=/T={xpq%|=/ZU]rEW=7jyT:s{NJv/r^wJs(YH}tHF P j<$%NSLg }ѻ܃ۻl@;A? j+!zfQ{|p7ED)8CUzHm !Cy Vup8spN75@,8qg%s ǟԝJ#vfEƂ[,vWZ(thOc&n})(9#Ah겘%'-iJh qOqHIV+1^ЅGu9^uc@Ő.4KIN昬G@T"%((s6Мw)&Y&:Ki5]-~ oB#4&&GW8&Rii ]$XzB?ˀG٤O4 k3V)a;ʆB,E%9x>8?pYPr0}$^Lx)ܖ2³IȢ鵣Ż7f,` |."Q(ǮOo)Gw{?dpFbڕkrLf F`BQf%2Hunr./쇋A1-D4jZv;̍7^7I۬|Sd‡#q[IꍣwR޽*:G|3.IZr^J~jILkdՅpu^L"1 Ga&IjZWit!{JM: 9N3.qlz9}քfSjSϾ,]".lb1PNߥSO$]tL+P"B]Q\x*7aSK(: BmĽ#fr2 F(22LBu\dckFX+AJykA¢$V4\nnu Jabi|XL _P >"Xr(de0#*"I֪ޅ hxAqQ_A8E?oLߛ7:X V %\#ϠR`&Q P+?褄Q\_#5ڌ^+PE ^tՁG(E&N$>#c rmRފ#:EjAa=#d{Ac ؘ"G$v|AtoOp#pޏ>2w5c(sUa(/p;`X@ d#('60Z^h4Lb4I9 EdH~"_&|@22CaM3i e( I}Ta9@X@s*o@pHF]TwZ3D1*~I5K,I Ř(Fj83'Vej]+-폰/~SxvdI$Σ+;I 9IY`Y5cp[)~SwrD_HXbRJs)5B̶o}{&36{}D!&/_<Й{~Xf;XdgҟKopқt,bAl w`e/Nt@_*+-S–-b-2jxʼn~긻%Ncc_A_zf^brW }X#,d4\D> U|O a 5c_A߸BT#|2,opq6K8%G̱B{^`GT9$ `ўB@ m1L>ǵ)^gMvqFB :3}piStWT *C+*5ʁS0rL~ʊJ5qTU4`,[ێ!g͍7$ɇJ\a4`r%`|^3rT=gC3<^\<+:KPb;5be,TZx_RQu.?=OtCHnZ txXj/7颳Bvu?̣FNy)j 8fp= cmPX,Wt%QtUiQ%H?yiT=<૤6#mkH9܊c>Q8+2C0h/+!%@* 7]a_kR zaĿ*W9sF{wx&d U4YXA2D/`R#$נ= )\ «PWZɆW+㦚V>?WqqUwC\!P 8<BfaK}y7[,ٔ;o@x)^w} [, ymdja7/B[.dIV>9)h>mh N+0_D:9ߎY uIҪm}~ۚU>Z-שׂb {`[Y}RDܴXecZ6"ˤYmZՆۥQm][6NvۥY-n+oa^C]Vɟ5MmF7`;]^Bw$ZbÍvDh#,0 )'"}*WGmF8E\0g#P :!9lݺ8pX Jnz.}B+ޞo8Egaz_fȡ*7XhG[0̔CO_;_ml n5NԹɂYÜ+t}uvХ{G/? N~^Ouּע\"j(;hgyo~7h>U N97}^ʢˀ 4o2OזagWɀ Sus/Ng5ߘj61W}_c"q2Jc>uS_Aw_X|7!ɘgz{DCcʏȴ4>J68䮧&;qN4Ll*|.hRPˆ-[ $@`ryҸ rȥ`0HkVprޕf2Y1WJSJRJXATPQ ؛fHԢ8M+GGÍUS0-G`KI7f,/% H6ⲕF vH;ރ~ҙ|u%ZG* $18> F@ܦ+.cUەz{-9L]b&$$ݤÑ8#c>cԩ`ng_TT)H"( *W3WJخIx 6@ь[бɛ9(~~Lwx= O,@][8U;g\kY6FAᢔu ڬ ˛V,FR3)+IAIItjYe]>M|e ]j[&uJ`aVZ|J?l_V`` BaB%BpgFDUy Ӕwfum i^hm"V*_bhdTgLFivGV-0g`<l|6 j{3[\ihšCEk>З׀:uګTp>t&EQUaMaMuU9\^skZ6iFbAvF*52\2fMfCX`tW݀E9u3JPE0O0:ڍ`T>^_͑lxsn 𘨣m{:'T(ZҹZR*e?\#h%,#$Q2`AK>5>$ab][ Ȣfk&eOhɜOt^XunշZ;O`rpZ_گ}]'ZsjyyyZO'**j-!(5< {4͖8b~`etq"`Jc( OMnϳ=ÃoyGMn!+c&Ȯ`e4Z WA7boYZ6Eٳٮ%I릪Ӳ$W QoUI_wכCeR0vv `Ɋuѧn*Mf3[-,< s5VKN˘:bpFH 7ш 65(vJl|[zP@ri)yv/04(HX,4tr\?:iou0ۇe1͛ѯA:csِR1ث^+Rjr/+|[N~۞z.#@FhR P+6^1pDZ%{ wڙEageۡхf 2YpA!~X˹ep-(7Ժ%r`oSMo`gH;N5H~ˏgos`N,Abm/) iX1!){Cw)7 ((̀)¹qh ĴQc8gxey=t+< Y>fN4%? ]0qrC_D=zfR+xM Ub> խ3囑Nse(rT?*O9s`p cR=yek4Le!;q˟TN@KB<şf!*j]t1N.OX iXCB$+rh6/.#@t뇔уTˬ/!)rz /A\hzЯmD2׷%/Q%\墱eX=m8E(mèth*}򧄭HN'#*JFKI(N{6|D_8ddիè*k9oQjbX S`O~-@J/i^qFu=D]_z06<6B#p JA{BKQA'Ɩq[k-nL6naekn]5{-F 崽Z#X9e",cLKS3 |~ ܏) ^zY^0&?b(\#/Z0u+ : B0} QZ0Xp)cX <ƒq=d%?̟}Z9N| VZ.?pr^Yg8Z(w5wj ͸0T i" M tFvl.Gc`f b>EJŴ±G]/; F!Ngsl[pCJ[hK^ +NE_A"Tv#J=+kID}9jA4/b xaf5HASt!Ȗ66P8M srYe/? Ծo/zD˹;9z`AKjU& nF;i(e'w^Ziݡx҇}' ;K#؛ilkX Bk$?%h3*"[qgx;u;1 !²h;4}b^>B{X3Ae7mEM"X}nhĵd4銀'j+x9z#^`;gO*C)EEB'\b^`ޢu0rwf)pԷlY[bAUlۢ6jWBqPrܘgP<HM0aP8^E,8 iR1 ڟ$(oћjOd (K5RM:5$ڜQ1V@dohў 77+NJ$Xo(w[iݝ8GL!MŢbuUcG8)巻|r(ț<~?ֈvA\~t3gI'섵`y-eV{kKlCj:UU \@N*6kV%Xkp؂Ll3[YeXe.^f)m˷wo~gsO>'-G9S\90.sBTqi;5 \`w$uq7$ W$_nAK D$uqk Ib˚KIFbz1m!R9b:I]l"R\uQr MZuXfXۤ)j"U/SQmz3/m5qqdn;06} B/pfX-a-t}lHn/f QWqLJqҬkՆqMen@>,mYh84.>.~/+D$<XLBhk[O&J|+4nǹƷԾZNZHshBNŧ&t,>˘ƨŽY$L' J'FvIǷB}OX\j1Op^d'<ŹAR C0=XK ܇2 WQlL%^A4ΐ> x"Gl8G] G-hTZ:(O(LK`%A~'?\z7+v7'~75ܺ.}*9.NY#ϲo9+[A!ܺ!;is Ș(Wv_ȕ{M$WJ`r=:^k X7E^ӱ{^8 My'St_276.ɤ *3"bqJ_־h񟘌$Eȗ UQvOϭV?j%}Պ?UWQr=ojKVRU^1P9}{jz`hdf*PJV*} @"QTnE-BDh}UO@j`jɪZܑթfr9ty$JU+<{DzbwO# Iq>b"岡Hc%0'>neSYuJ壘9qM٦HJ/OoF+rMA|G 6"\]`I9t^; {lɳZ0Rsղ-L{Sdx: DRzL\teItL\hJx1_¥">;tc#.x _(%du|y^{/ѐgQ4o?VD9Q^"ZFF"NւH>B;ٜ7=-MJh4z$nE&|o#Z#v8([1g>X)ǎru" tt&(@>0L5 tl_{Q[藧Dq+ޮu~}c4]g*#ZIQUa]a$wt+HLH Q3OT}WDcrKn puˠU f{uUOv2MO8oɆd$7u1:yN!XCEI-`Ma-`Ma ur|~!Q C"5+:W-S*P<d+ac\[~SՍ3apL< g%88o4:+cf:ϙI𒫲6,[e@QMJ;k~tĘv]倈&l'ڒY#V3`=bnL*@1C{LkEF03^v6 \;p |-Hk]&׎s؃`jnF?My]׭G1U&:c_yf|O4TO$HY} jW֪i H% ҊuT?1?h߽,idO9Kaؙ=z#њFd^Shs'8jAg5>Swd K G`"5xU(鈠+[+'nGtGXG.~==+1ZaQpDk*Ѡ&XNժ4:X/?=U2|D/{ooTılj ? yߔ֙zګ%'Lx]rj\ FM3`-_-櫭rle8akWP4Wrꑩ@OOA HȆ[#j }Io94A)Oֺ~ē e<&~y>ywOt OjCQy򬵺]`w#|7?A;D yDF"@6z1-)ќ6*l?&9xqcWѿH0)xkt-.&v.W ?'Vn> ~r]b3ҁH⩃:Rk?=Yrp[ ]?ظܔo="c85H[ &ae\񁯨#~H8v)"t!< N-}T?IA7ʤyJ88ڇ ˔D =I*fP9.jrE &{|ZE&3Ex,"$>* hp5޳n߻llz 6ZF3EE,yޛ Vt7 6x7 A"RM}%,/Z5 x!2#ҵ+A`b 0J]R<4KtOL5*Qwj ډn,Հ6 VVxw;%3efDcze4x#/xwJ.6}%f^oYG:[^ٴP㠵r{^ mzS}-^gdq(2EVգȖ/929ON$8רbA~nO{^C.姵Ybgs6fўkeMhs_5~AmTӃ9U!Kp`5%RfeB+.e 2mtH@]-FI^A2\p4$4\Fi1ajvs{@#^۴9=#&L~!ڈ. ,O8fi=6ƭ.4]='i\e\:x؁&C:MQ- P%Ö?Kwo-zxO֫??|.ȊO?b'W)gvYSWzq|}ԓ{23y aClMfNu_(pCA k}9]TB6%ma)i ::j>jB#UL$+S28Kna,j H EN7;}\븦l&jYgz/5K8Nˈek<*0S~[*lʯ;)< EK姭jijT -6jFL.ki.RI3sQ~bf@d!κJg6 Q<ӇM3)]ʸ@&Sc^3xMs-VI+J!Rn՗bx</^kMmلNQ\tLҠ;1>73'ި\,e"aZcO q'mLSZo?*5Pѧ0J󱩁0~@ƽٮ]{ٓͽH-f[PI w b݄FGq`:Xj_)#yİ/I;}eyP;a2`Մ9XVH]|f[%Zotl3& OvHr)C?O`jkârۙZQs;%<§cto<~OC #_&5z'E}YΐE%UVNM\Ȟl Ux'Y`,e ^ v(-o|Rim_+20 N/gi՗9b>N8y?Č\AcyR n}SHohd4ACT:ǔF䱵yI~Ũexsfyr'OhawdΙy\x9IP>$)9|QOOˑYd#רWJPhrU7Dy1h&d4nzc?CԀnZdÅ?xbV+U,֮J*1 8DBsm7ј4T]um1f$0Aϡ ß^rYcp1(*OTṈm[ <\)'̨ڡ h|˒G[+sj_d=7+C_A_ 3=)jjf= &I3nJۺEMxezzxLF)&M2,_oh5懭nIT"JtݖȞp弃idO1טf =r$Ba,*3w-*)rY;rD̃C5 ܃-{ư,M!`*o^Nw׶u*K)VEŌӰK~'_pU'2[$@E߲?ifSuY':W4j_vlTD|j;O-ƩXb͇F)ѥe:B 4`$+?@&ڨ4V`#Ot'( ʮ630tgE D֟^ .ܻDcƵN010]0G-Cyna$U *ƄαzTR_p6o; UY3͋ʟygZF 7̋DkC&bM0L0 &5M0JLgV~rL0{D&gKJ-EU%[u>*E[&k1mqyiUٮEy BH}ݓye jz`P[-S?Gm3g]~)ke (SUWTî#j_]{əhr*ZL(c5e>d2QiF=˭8ʣk˟}ە)܋#fI>uj.qBp',_RSX3SLVFL@9丽g4,t2"Y'FKh)}pˋ>)F툀mL}1gޘ o+ hLY{Ε뾬>˱(.ۺvnƓ1qUF>f{0JT|yΟskQN^~eS7xXLdUa(: Puwܐ}%p樾 |0ba*9 *|b2S]s6>`Zh!!Y]b>ec$0wILZK21;L^xpa$fU]Y riY+FWe:OZyo_&IYEa ʰuj[^9yfrUg/q#&Bk,զs5vڶAd h`SYYAJ5|Z Ƭ^Z) MH\7>_pO$.O}Vl?jBx0KPʫEʃʒ{ .p\FzU?G"ewYr*얿t-qep6Bv GYzܭ'CS]I_P4])#b7>X]ȬBe/O&vV5opU0d&ޱ ńK I@pObDsUQS70Xr^lYV2־Le>rǓsO(ERy㶚ӎ0y^~r!Fko'\gj֌t%`R$ zڭ-pb*ۛ|jW羱G U` `× 84cH~2˓he]as-nW̬#pvGټB)/aj8)XL2yT* 0u$. DMn#oz9#؏+òF ߽̄hBw0&^5^*`89BĔ HY6G[U͍KY=+fcoqjʡ r^oHh2E0 y_|G0*+MW~2c^G^uc1%u;x#Zlo@)%˚%5/%o8|% :NYjfț]dwa^ǃK4}g$}"Gd8gF!1>,@}ݝӐZZF;RW+IG0dSN| %7:~DrFXGÄx=KgY3ނn^*a{4/W*I}ќʛիEu۽&$jV-He:=FVÉPk٧<э[TS/;eHm|=w_zr+_坂4ZT,cnWe1}usa7HX_O HTֈ4J~!TcYYͫD\ Oʫ"I1pW]n%L R!c #k_uاk^jTԡ*rfJ++kZ\%-Jt7GazVџ:5&WU&j4͚pH ~/&9"kUJA&W3'SvbV)r$ dhۥl݂x:sN~I>[l}t5U$J bnaO8U)Z+~qI_Rj x3lX$__v p}oף{*?YƂïґ1Ẫwd4fS~`"f#OW:dAm9v5.Ԡ5S5[FBrEkNKQF6N|Fᅾ6+GUMU"Xzig_ř"_u:gϛ2t|wA0掾;5J$ӧdvOyY}.B V1˼F(OδuçyΛF笶k]J deȲZ^l.>3Md13`1 '^Z7ĻsM>Ea &WT ,A(k1$r|njW^qz.\Gy@$zC~hew"{T9 #Lҝ:t˃*}w{ɚĶ]~EE{0{qq|>/_'̐5 ͢*?e͹q+6qBnGRypyA9a|HB | 3*U3ʭolE6dlB7504K@dj@,XnHYE֢̣ϝF6 ҃h({{gqZ/V\:K/GKր(+ 'Vu(?1םo|oUbrMF) $MoVL&+ & QոfGݺKrogVtsԿM.@r6zB?:5KZs\ВGGSн*[(2/ ]U%PW[]bR8N](F18Yč(óz{J dDVjen &_^($,ײ!`m|zٮ(Xf_0c0; fHQBE8`G9a'$n#Jo|K|bػQ?X_eD8.i5{ SRO7 UE;Dç l=m^Agg+s'|y (Ccm@6Ge4*hFrak ?^|mN:Y=)A.awC{60(7 rx.If ?lR5gq/3i+ ;CĐFJU6vU٫Qkf=|enj0VPLq) ]gYZ%ME@qeޣACWSޘM,A0nZ7[+SEp)vaGt2Wg/o|{((x.SP1\QzՊh-Kh?dC?,g.S L|x5|( .VO١[ /-#M}^F1 Xeځ64q >D8*MةP#C"N5#;ihlhC &@4_2-2 ,ۏRj CC"  g(r<4!~PTQCScT5*CR2hXDʰhyWCCN>ɒJ;M 3CS&CC4dJ4W XL' rO_N+NwVk69KkUq_@\:H0ډ7$mpm<{\[,ipR]MwHĵ' n{Cy]ĵ=qy5-D!r^b \{*Gy$koˌ@ka&M│%Qaӈ`)bI+)OSX#NrB #8Y.p£+i2nE ,yMhe͗,e(]%54\+AM2A6\M8xWK&"},uS3O-ފ^ FxeVS&E^u:YΩ"ξ;`p* (_GR<A`,>`H^8Q/јgCa# b`L#\BC ^u0D?1ڄE1A1QzLb^V*1lԘPRT''H,uL*2?Ly2Hc">"r* 3yU;Sٰ:X'uNtnUhɭ xsl75d[@JhV˷Owߦ(2r9lW(xi%0x#z4Lئ37}"AzT (Ҏ gEaLQ̫k|Z%-"6I7(ض^ʸ28ʂz Ӊ:B=֍MCcIɸ ejI$Jw[/ed9nEBy@nzG DGnkrNwj:.Qk{|u2C99T':9C?8Ը4EJLH]cʩ7‘kꉍ\J4f1v,ļP^P\Nur~4"7y$c%(Xrge+@=zTv#{q8QLm5Qh_YRf˶hys6a7 Qbƅ.>ac\6Z k>1?8 pV4CAs ďr?o4}R!-W^C/kT}ī}C^Zxqġ,x X&vIccI!iI[fϛ#iFIMmF'QENǡ8at.GȝOGCЛzrUq񇬡Y# fUGC!eްI:]VZu`&m IȨno\Sʨnme2/C5`}ElPP sB=1E 4T.ݎbFB/Dd 'S8[D8!L5?}ڍ)QbǁpÈ+8E o5,r(q[6T\GΟve|4[]^ͣJi,Wt'0yTeQ42Uu?]1is@ּ_?Ia%eaYPw—/_}FilFJӱz`ar\Zájǹ`t/_Xٗ{%'YmgWYAe=gk%pyxl~089 ir@5LRJ.\M{]!ό$#qrk1kb0U +|T6[Z6TAU6=C#VM!cg*LrX>99rͽaU *T1bq,Z\ Nw+@s[C(o:jݨ!Nnm@ &+Ӧm*[LJpWI[jhjX~x ڤT0ɊDJgxN߉w%o gņT-A:֫n0% Myܼ()uc" !EuX;wqņzɰabL ;ܫ0/Y ħX!}F+!}ŽtҸd\RNUOJ¸*dCZ[0uqdBCM 11{9q`'W=\䪥_WW{uPٺlxvAW6/(;;ܒk.l\CNeȂw\;b,w* Wsgp\u=3NzrU.r`ej- ƍε -tud -Y/UFW tՓ\!\{[9#>pt_˼rwu[vʂ]+h;ʦbg&X|cyo8Z%|ys(ȿq}Li:=ԑ]kPTgն CQ+5G9}Y-t1ub|a\Yg\ fh$ ~Rnd `ItPŐIǸܸWc>d^#[T(Z3h1Ϯ8rZ `a~$"QUZ;+qYؠcL&sCkk>v B'|rs0&k DcFd9z VK;GځjjUh6A;(]1N|J?.Rⵃa)`4_WivQ0퀵ݠ֞X=<A^lLhsK(av05}vG;S5˿qm`EEW;2HBH4ĂOJRe)E|6)R3 s/̉rQ{3P^n"vdQ< x(&͇oD[XcRd݆rQ… b;6^cO5+n?z4\(0jPL-B(Jx?8`((Adv\D('Wo\)|A\r\뷦|[ԎQ|M]&X] Y1WS1)R礑sWeLz ɕN+=rrRɕ\gwo,xk3\>?J'[@9R}J J{ xq .aGQ ||CWvm_1u !M;+SJxml/S\6Yp]"MTN}?_e4JAIHGGت[%eYQk㏆U_Ѝ=z#Wu|{sD.! `lH@;y ?bw'[EI-U]Hq#@Bz)l,+ƈ@Th!0m"Fܨ0eTHS0m" 0h!CWpphM@xWEjpzAdC$7d-վ 6Z3:~@5#!._0/]xpG~JaZeZ9Teίڨn)P~n;%e1:^s24(0Za3BٻNחŮ!`E\6/fܱgтÁUzTu61A5т^NS*y1L,V{#Y_x-4Nud#ZZ7޺,k[scvT4֟; PAny(XUE8\Y`tM2ۭ* ls 1?Xc/(h"))w2Ī2!ODipY6+w/Փ#`C>G[^?]aY~v݅2'Z.f.Mצ[p׆C𱔪TFuwJu{⮽\W8Q1g] X|_rR; >4 G'=Iu_GL-w=2c}r P'sj4ݧTSu%9R]0 ӑ=@uy>3QD_^40.*X=՝< 3RCʧ7nM&RݥCuNLuȢEu.pRAuwNC^Luى.^"K4eRݮ {uZc'/0אuk]}ce]:Yɺ>$$Vےuoel _,^C<^JuCGSݵEuwZTwJ}r+NuC "q%:HsfczYk& w% ܗ|xOfNmN\_h-a=NGXOOu?05IK- E]z&pG9-rId$9E a|>O$Ƹ#)S_|~g  ёje#^B+by"Ipхf}hQs,.ѦlOY=tf 5XdƥRT YƳj yWMFPQW(9ޑQe0jh)G|!ɛK˔K΍ ^R]kIEO*zR}Qю8ʹ=P;mwZ\ :2:\l?IEO*_}QTT|&/XicI;)U`,&{pNNO*.hRQ{k1 8YҜj{Mp> oӖ֜X7p1?>NffS{&+JWBA`"#3/3 $W1OMkѦϚYt$;69k6_^VV}.΋6*w++s]u^[E;VϹIVB.7`}fd"Wj|9yyD;I /1y̞K L,l\$ 1A'EN=Y'~oEmo':>~aYRM:"a,YN&W?»bam}w קʯ;'[~:-bJʩvBƵ͓LLu:c"0h Ye7E~`KAB𝷩m8z.9AfH#aQ;t_n#u\d1\N{!i'&unm=gwֲD'OxUK)u%ߋ^&㋢ݜ/?SVvY +e*jVjZgLU<V)KX$Vt$fҤ򺻱.H\8/{e Zu0< IOkI$p8?u9J7H=g*s 95w޺ WzR/J_4[GCC"h.'AO*|W,Ea%l<94["ˆIi`MP] NJ]<ٚy$)[Y1%K" uD.{ Iw:4W50RȜ;a=Q e%C#ȽaɒJmқU V8 ݦoRgx.y>%џNa I9lעؓ'󊇡':l|pl.xFᅿ>oW!^{~qȰl3H0eJ!e^D0 w g0ycp=4׫M + bpR;ӵT;#ު3v<&^xge.y5<& GFgE+2Srajj[ Mg5Lq#.3odئ.}YyЋHN4LrN'Y|NEJ 캳!~6J% 8%KSRdiJ)Y +P hX-,b)%CI"}z램0k}D!EڙS^P|. A-g:VUeF}HՉ?Ӓ$a֊#JAwFT@PVk$xgGcn"uWf*)\O=f;48_!y֒)jSʏ5oHӦB_ѣ(fe =dI=e66mZךpŽZ4-*?>kHX&|SpEʀAP5ϖH_85Pz M-<ØǙM5(]E)Ez9ћ^s ,jJz^lXTa:XSǺx<Ǎ%%zq׍̟6ȹNȔN^?CU]euqvdTIX f*Eg>eƽZ]i#&)<k( 1E![U92Q@Wc\ <=(lVߤELEY85z|G3ji^<3)씴B3 d# V ْ"."]c2@f% & C`|SQj[װl'3@zZ0 XY:CDSU '{DMIY`:XO;wTml(zA tUE :a(j#!t, Jh U6h! {\k&5.VJe4M8FVmBٶ5hDag]bbԠ~DO=**}=FPxY+ V; KDs91<23JIov8e}*Pu+&h%QMV.hk;]rF(ه ]m EFYߝ;294JG쪓}JW*凞w;zy_쫘}%f;eyGἣrQ:精w@dMZ8h;,hN,|LdLUrB 2w(140;Ls1ûLIo~E9x? aT V>!oM!mŽ,('Z"5R|&kۦ, aBcw[-BY o@[wFRˣd)Yp7nDxY <Q?E&)o)U;Q8'S hmro5~J>LyVrGN)^s4u$k149*R]LܳwLfI#g|GC#U Yr K  a@#NC,x.]7mfV?r_6"uOEawvZ'>w~?Ј+boǩgTv&^hwN5L|].LJ;Q D -^nwJ}dݏ^GF2"$n XK&Ϩ\o<"1-zӭ%9m(4f8HTuiR#Ƚ^ 1 iϢ)HH^]<. YlPdX;Oo%M^ݞxwoer&DIKDĈÎ _)Ӵ*˂MԦVS?e<=eS5'#ٞsuq q1!: O0pBcj7@1S/l'd{׻7X<2eX 8ÌT.̆{jL1"Mѳf$h*N({)Y.TMN"Re٠@@ ' xS Zs eGaXu#GIpF2ttsL۸L3B[ |q(H}r(r2pN}KU"'t7Vtkwߍ2 q8֫vp2?b'M茈z,avlɩU4;e&!#G+ⲓ >>`.9Dtq}]xLXp̛1ѳQH£qS>YȌwi&c|{,8q,N*</Xy p3{֚Ha{RUQ,'G=&UYE$ej)Z81,QgMPQ,Mȵʆ;[PFp+I6SQ &;s g[S ی-ָv,OE4SNViĐ ,ܟwǧ=εmG Z~msP+Y8 _v| iݣJhXڲgT|t%_"ѻA@S慢du0GgA&v}u T> j,W[k@QPF1R_>҇N!4U`uIj}dZ>rG ڴ.*M*$vMV-cg-EH7Y(A,3Rq 3\m#쮬-LuAh'DpaRv,+͕OD|3d}×,Ix;?,ۊ`ʕB[~}6Q>t{A"Zr4b֧I}vCv 4w؜˒6أqG $&4~;_̎Nb+:Qbe'+Rk尦H\1X6"œĶcsfKy9tG8tK8W=\ BT~hҪBч rpzfz\|R94>IS"y[k(5-9IKB#ء#r 91^K{½"PN FS]ƕVhpoa>NwΪv~LxF3K|'nkY``Dn_2asR+ 2rW"JJ<'qC X(V`E Ԋeb1n"" c.L.kurPsoAp/յQ71Ѹ[V, {2w :DVG{ >i|{!CE!&yL+/|>q6LVR˅H$I TXIT3""DtkXX˪C} {d"*!wt.M ""uM4 yTعB BG;}Ch6GsSb{-yy\  CȜ\潲aMV[!թ޾]9Ww+Jnˊa{U%24 ]"n_?epww׶""1&H#/G>^G0&(#"VX9“Ƨ邵rbȕ5nSռv9eΟgwmtʏ2> ?E?sgS~zev>"N+B%yp7ǂ.xm/]"h}d7d', ZJYv%@iyz9wҨRQQ9+V⟻߻jg燚y~yIs3" MIu,4断 d7{%Y _bpVmet8AVLH}ũlu.z8wpo\1qdn&|o#MIZؼ(9r8xIG =Z8đn{Uٮ&L$d0n̥:|FMfH#fetZ@][y&%Y#h?IfflK9-%[Krus~=~{y] ӧu.No@ P(P[ATLւBzh HEkҟ#aUa&؈|Du LMJrȞ(;%ЉtJmPYT f,ӌbTa"m*ZE n:P1dnٙ,f-t8 ^^K&V2xUhQ =L6W6:NL֦D;BC$Ik3,6ēO_| ΍K mXgk4K^8gXς2XȞJiA 3~0v)VhGbv"ҹPjp" L Nv f &Rs;Ńoc*zm{np/}xh8 BjG l٦ @gtz /l;h*;,HE[ܖA:ʎΦTИE9\.@=!ϝZI'LFѽXxQ GQuYZ1{ rQ"։A7ΟWČ{lp9بoCi)bp z#~Z&hey?}׽!LIJH\M 30 potjkBwf A^f-B#\|B^ W :R03DSF#}_T}]ױV$XpN #K'V_& mzdvwCU L!h5 l䀰y3 ,t/4]Z1 yGԇI嶃&薠t#Sc멱^OX_VcOTcMmU:y(Ԭ"|A;NϾE5o#Tu1:jѧxω p!Js<泞֥Y>9m0z[˗ߛmQj] '5AHNp,+bcQK_ ] vW G#dyC) zA#e&W^t*lA.g9,WؖŬGryQH0RxuE-X~<)zU>Z0,8W_feL|܅e\M[q"l(65WK`G|ӽ}IL^e{Ċz@-I:ԽKL]6M{9{_ ׺wV>g =# ʷZά$ѽ(ta[,%a-Jk#|m[`=pCX%A=v6:㖱vuŞ{¶ wdы)D@<{ ЭGtڟ7Bn,TEq12sEmGAMJ"_I\ I5>S_Eijt98D3 cX`6ܠ$I-u`€8,We[@G Z 'gYǔb^>oҨ]W/Zr?3V.kQ9h<׏JTըXV t] qb t|=R.'(TWEgVZ+@yJX0͕&@;J!Aυ grp"J?:QDdG3bfힲhMD└u0*RO`9P:l;,;{ҿ{ 2z RAlRUinQsUl Wq1.3joSWgbtїk/.#K{S6KɺFi:IVu KpQO{lf||.]iTԼ|HT9Sl0.!W!ybd `vj%~L> F ^rD(=>O-f:ā떁¦49rQIg^o :%z~N {&12JY@Jaum.%86=/.@9f)y҄i0GiVmy9nr"Xs }L]Ԃ ~#|#uҏ*KT;<E MŦkdpeCZ+6Zt7lHwkvE/jQբ>P||im|˗>ɌG l܄5ƝZ$[l*fJPBpP[(QF&].:p)XOJۀ8d* K '&D;%<5 lFAB<Yȼ sf捘Ǘm[i|P}48ygtJ)OWCTE-z2mir!:FvCʤ)NMmH۞Ҷż\Im|py3:lݫS/S r>uJCtJ& Z 8~ej»E+⎥hK<픗Nvi(H:{:#c(ȁ?Y+Hh҈!jh]8[/8$j7SvSd_#Y11K@4&i L,]4fq xN ^zx!7G+ۮY#M֗s(ڣC<_MOkٕɵxqR^ho L Ļ+[y} ',u[vY}{vLtԌH/ZBPJR |zseQ 5.adIW]™"l}e n9(4҄kXb@>z >ыW!sYj6A; MBAF:(߳E%YugFeqÌ!=_>?@unҙ S%r3&ɍL%D C:hzRzovӓ1gd ȵ"DA|}A2Oy/L:Sf -$U+CQk ~x|V]9R>mUP vi}ae~VGf[6^Dh,ѝFC"(3~hKaX)d=Lϗr[`j%&!JP$XC70Vs{5s`>`!g@ػѐ.WVr&qAJ R]>Z<֣WIMB] 8 ,f4/ HlP 3ul[C6dY&B8^I&z&f>gv|V30 $.EvYȉOq5%q7MU:F{UnC_GWIgoUę,DlZf"7%='Tdό K,tN# vjI8JQ_c]b;.f(>z*7]!>=RYz?@7S[,kӔ~(Ƭ<!pcGZQ{VA{^8/l_0p%DbgY*+b 򄚲MQq8L3e5$*I~*!KQE 9]:O us߆ >3f=)Ԣ)h'auZE"<3/ޥ꿙 Ӭ&@r2M:QaTgLbu/z>*gM+`Na Bha5Vh]{,i"ٳp4Rƥ<xBzezt-m,sճ.^QR;_]r j}1'/iŠil:S:囂f+ Tb '`=Qe)xGxm뻡hSV=s-f&Kp[ԛNU\T=X:+uWW?S]1W]wwܞsd6mv >X-a^Ē}&[$@TaVy+YɊWAA`.l&q;OQSO RҦɆՋ!q#D *%q1\K2 VOؿ5:Z2UW#iQc2/Ep7 CC/H )^Q؇to5:-f#uae]ptHAef[e%ZJ9im:Q>'lgR韌Au(-8Wõ,= ЏCӷ>vlFwy`+w<'kၼ>-7x"zPX/7m~m',cj^x@ϑn,V+1o{N ~4}_~WDX4#5#X>q!Oo#z<s,[4SR}Φ,} y \W,zm}jg3Gf* {>LݢrDr-FCPD3>5Rq)K6iq9&`IAf~*ȭJu' L85̳@_Ng‚r[ 3K]Nm2yI]=iD+BəI΍/ -ZaVkuǢ!gpFݵgSM$Τ63拘-p{@;u XLzxc=ݭMn4CLxv[wEǁDR}nYfE٣v;̍#kIwCmɭoIwQ6 h'i$> &ddcfAdZ |ƪKAkZsxN0k3 jdUM c.rrvR@6\ݕղlx)tXJX&@ P2ﳌqL*,SYuE0Rf0Prsy$%)@珇}EmUtMF>2Wd_:핔Y)bŀ6R51d\Xf\%d}M'MCIIMbϮM\Hj`ı8R#یgStNMl2R#MFz"ߺ(TXDMl3M_XIɨF^z1ikEŭMF5fĩh? aFsio64rMFcLNvj5>%_r3XSj'om^ݓy$ɣ'Σ1ϑw}y2Oyjwzoq7;ΣYiL.)VQV{XI 9r֐D?fVL"ݨό:1PnC3J`(Էg9t!UHSɟHKlN} cm^4S.a=vCp^q vm(V@'suN颎Oo0YW ݡ\dpO3"ɧLN-SKX'CybwH ֩p碯4nQm@H,#hlH$Dh@<'x$6~ѵOX)M~*DXfU݊e-6؝ޑ#g=0< l 3t{ A .Y'!dؽfhr<w@1bPC2twZG 6E' o ZĴεȼu;U Mz==0X`r3A#Бv2=,:ty97Y_+ϷMS-Ai\ ,<3־ G&IZj~oҴ4]K{<ˁ檗.536*hv$%oT,qzFpQc[̐QWsԃB&n:a677hF.f1y7! ܘz9X'߼ESGV*p:|QyFY .i z0^u(.f VV%Ӱ V CSx_ ywE[ D#7L8t9RCWNJglu%zXYWc!e7Raٮ J8Kqu@LXhT2,P<QoW弱 zT{cogeryE78pv> n[a0܌M\i=6A)Bc<j8%H{RNڃ7fT_2"g نQ^Ф9s8Ӟfvj=řԻjU``FFb16 `ن|RΗ^IԨ1۬xշkg V-P#̜ɛ 3,nĹwvmз7εܡL?Jm8 ļd;'Y5B{sϺ{S@W*ð)Tr$9Ї=þ~u>Ֆ; gF0Fs0'U+SĀV"qC T`;0][:aߦr/>w3F7H3S 5?ܐ`eO5s9NQ=' nPN|' e!"1V}d,.]vqÓd:^=tkȤD15h~L܉bj L-tک}S'J6X,$t26Y$65-,uF.Zhj/6pxDk^ei·l{VGԴKw&Ƶt,u<4q4wv<+˾V?.9v#]N7.5gai1Sc^Re./C?}әNkSg:k5g5.ܡk(:t 83:Qt(D;qDxA;黧(;-n:A4|VAfF۠ΪY <ڙEx 6w8XuZ_ׂeioC8ҟ3? <|A>J%mWCy Q] eo}{$̉|#PG'+iȳ(!7/[R&fnIMٖﭘ{"^!w?jO~d3R🽭PE.0s' "Tll,WE1Y"E1p30cTZCF(`M ~9(3gQfaW .rzB!1mJj4wOaU (}k0hB(3`3KwfȑSQfaϚ5ΝI GL`6F J+*@++丆m&&IsSPs&o2Y++6UAVP⌺%dFυWUƪml6=M]Qmnz|L-5kLk(S]7>Jw=hJLa{JymY. F+2 AMR|Pj2 eP<$ 4Ǧdb# ]QrjyT) I/sMͮ|]]thF83Xup+'/^5y7t9ebswbS]\+ۣGAHkMdǶ/`6?wP5yҊ8 6PdT-I<=̾VYTg<32 %[<(r^(^Y$BfقMŶҏcMe)zUp N$F޾^r~ؘIGt<㉐ O7DO'LORŸ^WN;;!c6 1Z*̺_zM@δ [*F2%I.Ɯi@E'BrWAcE6F,ldvV .*X`^US2 ¥t;/s_hW?KҙU"LC5M% >ǦİxM)eU4HǠs"" (1$1,dETz#A?U۵j 8-^SEN 's)V=#-3zƩJ7Bgdzj;ڵ\ >Ňbu\a#*g@ lz3\ +W1^Ĝ/:팆f{6s̈́!lB+i6WA?ra\FlKvƠdqV璘֞i H|R<4:̣y WkgJs+cIJ:cTѮxM[Շ`C;,6K٘+iԍ]ooը;JU_oN7x1yǽc#|)_ɻ|zU IgffyWC[/OCK4=ct4-Sj-o| I|.{ q9#.-ϑBNbDbh?+t45Z?,WSn T>uS_~)}ٌ+Ճ6նjc:uF9NQ3X ݧ}DP.5ALJ舸n|&)rB1:8 e8Eċ6gMʜ g)ޯ+[L2\`)ReTtA[?^lZѨ;^F~O^ IsqD/_(e@_DSRxPxVӟ(! t}"uؚhf,[@F]jJ(wl[]y+pY ^5rN^:s.Aɤ`} Jܿu)ƈ&jکt/==WBt{EڐWA1NV_ܡC/V(gW%+&v\ƅFqթ[U\G LA-KGUFOO_)6nQl1tNMͬx`ȯbB{Y(~/ 5ϊ֪$Ůt41 ^* A0>*VPZ|)O*>_O_:[%5L$4j1/`2D3%mmJh*/9j2:H; ÈAD4[uР}}U]\S쫓[ jB{cݍ-FJԕoXΟ;F#*(OZ60*O͟ůۧF{ҫ&XQHiSYcxYa{Ղo2-5lmY6&:n0"ؾӄ-y /& 눩(꫟BݙLsymEb&vk)`ϫ ~yz"ofOd16ph1"^7zx97“74IwEZƥ%gȨRzjig.R/p \|ڔ& ]'@J 5lC\9&[u3@{:րUbdL-~ɼf5G>=ed!n'E~8,^ao9]zBop_ ͤyl.4҄fBlGۻS>ii'0`TZ-_or6QFG8C<eCg.V!1l=Kpg}6X+G b1:i ͷnLOrF˫iUFa|3(x-l@h zetqZF%tѬ^s1D>+'$˻!Iٸ+Ag1U¢l)A,A&cJm`scai2INj( 7燯Zv gœ8Y]=9jKf7=- G .`v˗ _`?n:ۯ杒y; hB K!r}&ŭ*d]c'zxHn*u`Nb}`zB?~%tn)Y-A/[_n~2$^#y0du!U;7nq Nv,Jnur%j0`-8&-8ilk6gP6٨D^v ~<+v`~a |.|FEX Aԁ8p]Gre6ئ>t3}Luҽd]ⷃv"wSl)hQ1r"k-/q&HbtgF,.~XȬ>^|ms:TΊykJ2Va(w1"p%rZgIܧ, Fx tEkWR5L;)Oz.z#c~MQ?2U8'2G`e@g9]q`ty;4ҝ\Ow_2~SЎ̌M\=Oz$Ed)l1iF: &#0ٶcηħ}%XbKuII*gc8w$Qљ6Հg;yvjӢ_.~Ctw/vZ v< !4K9'm,*XũNλ8 ҙg8r޻ٟjg@>ji9)nȺgeZ}iu'θXrfΞngo?vvm;5J,a{e*ې_{' jLh*3XEa&"5 L.@tץ’ʴ^۫dVi^fZ{|:ôzLYc-kd&xPYř{VпN(/1|IN2{e%Jȵ?Kw!A]6alaE~,%Xr;=AZ@c(Q7GR+spAx\ժ`UI*n}ә6ZՏYq.|UC=u[97AʟȹP몗Lԅ~i@ȏ^>ߘ& x6/zh7R# Q4>yDF.s?Uk(d{H{x0w>uj?evO8^펌utaXšT*YڶQK>IovtTk4#\z{bR0υ7ZfYbҌRe!ynt `@1neJ,̯1zד3$=~`}k\UbOv?ޖͪw$e^@T? e3/SFMbwأ.qAQǭ.MJQt|6 29:a1vJY ? z  5<e3)șx!^0+4?.ty2. XLZ15szA ~!1"m}<Ğ= ezNN_{;`y;{Y &<$42CAf7_o77' 1ߎ|^e~b5V*v 4d5 \mq6d3|ͮz:#/fҗHnY|9(skjn)v˙c;Y|qb]1N! Cϵ4Z\IjOtBI!H 䕀Ϝdti_>b0,2˶&+'Eb#h՛z:/ILD7Ϋ<~mNڠƱ5*;QEl4\ն *"$F{P1D$6–prgJh1U ۽ydۊ,5ׇb02u*cf!L1Sߵ!PuF=V&Q;~g!)E IV^3ja6k;6 [9}MB.[値5X9=s|u+[EC}uƶ*1`F+v)W{mծ'ca|#Z+ -;fSvփMr2N+ԃF &<[8,J[;d) p_R"D5A##8ݛ]Q\Jr:>!Co)A3R18 ?cޝD0q.rׇMCS֟?ATgViP'\W!3`I\,_Uf<n%ϟѓNz4 j'074ؗP`:neav`o5v9~ '܂q iխ׆[1蠈]j:gh2A%)> 4J!ά|of] Z,nX6vk,+n%ꗢ[ڪ٦J8(4p "ȳz nnP;o*L^Tz*Ru,;fq'ݢ2br;lVj2BY *#OJ,nx511HNrWKB=Ўj4rNS-NV\-ߴ[&cg'F])6//*x,Vpr, 5藣2H*QOH# ׭di2 v,J-@nSY\ -QK }d -U٤[ɳQw̩/iMn>+\A?I_=󳞴MfCafo6vۻ³f*إlz7=,ߩ3N{ !ӏ{;Kɥf[@q]:e-pa_~u _T\u%~#~^!L$yJ=+C:&ĶWwe%^=I^s_^6C [Ԁ2=_Q>[>ϿwJN:]֚qBrrTh/cm]ӏZVA9}czO6C{[?4±DgO!2= ]}^ŏz2kʛ|6gC hy^Wȿ3fZ>0#$6 .ۥ/WN92}/~u֗R:bAZ-K-B5\šYsakc\ `s=<46PA5eQS,54[?p(2NyQ ܒun?#ym)egL_ S8W@}BϿ.}XyGG -R=/PڳI]iOW!/Yx†KX-o5"($>Bp"ޑאUozҳ*sƯ…/F|9=(9-J=wy'-l^e:Zb8M 7|Rp/y+S2/'9O~N:餓hШeyC5,p~_=~N 8E!:#* _k|nl !b{3ۏhS' N9S@7]iQn/ >tRLNʛ5M4zPQӦ0l27+ւڭ#^7_$">ԧ'lsrW|n'~@"ĺ?󄬠 U vs0צ&"'W\Wp@S~S3 OW._hO W[&4};;Smh ad'_M:$?̉*t0sr/$,0+>$k}Ա\a2~$\ëT&_mPgkȚnjP~BJ" ,NS]>~Ԛ(Kx_ƌABʍ&I (Sꃮà̶̓)3,"WKLR-~#_7PMhu6{0Aɵ7dӑ ^jz-P^D#* ]o'x-]½2@5FkEU(j=~~պ&~241D7լ AOBfSMJp2- ?$s&p93l<p}[F}X%Jx]&WTR͜DF^lZc^9^M{rG5u7HL DՠW>BGYM;OTͭ)_gk` VJ *Lv\g¹(B]@<SJy:ɚ+d*ggnӐ$뫙/s+-* y*drBͩV(kT]a=ZqhUy"?uh(U^wBY~_8xine-lib-1.2/misc/fonts/cci-24.xinefont.gz0000644000175000017500000003107314647725152016130 0ustar meme}-rיiGX =%{WޟYsz#ե'>cݧw_}wGǍ/};zqhW}߻:MaYuǹٮ6ε/<°~.49G| 9 svw˼{Hzи7@\<(/pfpfǜ9)FOO$_v{[? r- >8BeP,o'[iڷ ϭ/&G_aÌ;m?^>wU=[F/~6#FwSnͽ;ܽ).r=+k +t?㡁F_4ꞺcVhfuaNlU^ntƴ"3m`l4{nCP6`$tXJ-&r7G2ˁsǒZlM޲ 0L0=a<"SN3Xsmg%xJc߫{<p[quxVJ7.8QeraAq<ɥ /t߁_q.+EvZ x+*mytz ҲT]-_ikF9w0oqT|0k6#V΀%HWmY.W/o4=#F!#[T T7U[M1dXX- c11Ze(1XZ{|;Eg:N EKzKU:S-^"/XϬh%UM{Gq4E%÷@U:*o1IYOt.Mn*?`GTÞn0NSq sup|1ZkP4A,~Ɠ5>/ǖFo*h-9tS q쩅8ޏe H'5Y-~->?ol4]~kTͭNie-`ߙ.e·lʖZ<k(Ts2: /X2dn9*70]ffE\} բfkq.6EG+mQ稶pݜ\S^< iE't !\OF}X_\\+,n4-<0q-rfP#(_5Ȉ%(5Bu ]ޚ~+QQ0O׽y4V ڥbUL ;ZuRpT Gb0"SLX'a:D$ƥfo7Y2(㱝wKDޏ\FBLdWaqTdi,PjgN^D!,3Jtw,yٱ E|8 _\Nɗ#ITC!5↱tӈN66BN|R|cup l*Z& R\*D̶7f|@׻.\B٠W(8Lu.i`aL3We"Ru?N&p6iaZNaڟn7tzXUzvH>M"ԳӵHc Rx'>M6u2d?fF0C1.9;4ǐ!H"䤄.y(Y44԰ݪg~I. @SfRNo9)E&; l=@4 .10}>#ܷ/αUp_d/IIsQ2&A8[߁x\^Zoy4_؟,X'ot0Y} 9Fb#{x`Oyv r!_v:0$n ^*?=|#~ Fq2lq [T<#BVA-ԀbH 9y e Wq!\VӉӫRy&U#i3ڻpa2Fߌ`-&]A080 !zuYbO̤6w4S+rj"dŤTpl]H!۷I|bi8O}D6,Qc"{,o{+O? EvW6h5Zޔ&Tɚ:*ȝCb#a{Z\K"S_C$C+ cyUgEAoZ|//)|/ ~D{=_?78JYc%8BloHp3jBQHkn쬓t" (F|_.owK1\(rL(%d%uQU},)$ev9$r߽%Y8[۸+hq:}7V$wͽ=u8ϟ4Ɩ3'Ld mPlH"Wυfb!V! v&< WOVBzo59ZxK אҠ1 3EI&8,ct%$lD d- Yդ5i= TIaZVB׵wzհ̫_˲D41dNu!IL]&ƀ3IV? ̛F̥IkJb>3qqZe';,aDUwq9Cql t2NfUɲ|wHw8EY ҚR'FZ5fR"=`91TӪh>֜/u·g7Q*gr[.xtށ*Md,gәwO6e#$i4; +2˜=Wɼjc6Q̠x `F&x]z w{%d'tUl4nW%+ L*6ZBRVۓkҮ:^p5 V̘o<9!zG4JV/V5ڊ2A.#D"ɧXo:r&)*Tlbх3`tam |'yL^8MW S$/FRfE Tj9wky6$]̛uMqd)Ia|Sḵz(9d*{u" 6‰dŒQK&g4Adōf&4^WbJ֨ahѧEd8iSl$vBtX.ѽG=dFQ\o>8?ZOs | 0K(ߓ>;R~5Xgx&{ō>- B*W 2_IU6Z㽩oꏜ¿כ\; w^;ͦ>y>;I>jE7W[;XJ!Y*jYA%K^R2IP{5{ szR^<#r!16>L$  D}!~Xo@,=89,$9""X,ǩj>N z˄ZsbJ=7PI&gY Fn7 g]^[3BcrM1^5qZnѿb+9giu֫LY2fjGW9Y]9y+ yJE?2O+Y,?y ?#6tF$ܑtFPA]@0TIX-Ƌro bT/TLЅbqtaAXEұ43qG)T˦wiF4_3b>+D} j|vl. iJ _e1VB4CTsTpiw٫JS͗[Z(;=i&!_UGS?஖Rt T]ڷjSqU!uX+$q{+ QѮq Z؄^۲;&^jIlPOj:G*˧N>queّaLbdkAg.Oʟ>Ы勜)h >QBWՙ7'p5 ml(P:)Q1)(c߮IL nI J$ga 85>:2L+Õ-+9HԷvGFtF1%'ɖ^zzkv_̷:CoҡԆ0`Jz;;)<3svD ] F6Dx\az E1PlWk1j HQf.|YE%R9ʇpYI{8zR?bLb{0,Ǐ788T7WWm KLֹcVN}9%}j׈b̤7[dͰd.n*-4ڐS=Ql$ui tlw$IHd1LEC(Aezz2|PB] &}qP]ŸЗ>]Ҭb:E@,"R%0}$>@Lؼcq*,{AoC#{<_<%5(Ny:*5BqD)Sk '(z`Gw>lE˔y8ܛxNś4 +gƤMB~4Fn+L6!Ep 48#|?N 2o:[Un.>>B ;e5u^)%zˡ#ƓOVqcF[bF҆zº_?c6l!cgj,?WID$kV6nW B." IgwT6;[T!BLaq6agGhdu% m%-|j2D_L H⿝g[T $[ Zy?y`KBt"#b0|PhP*t*4Q,b c2GRIYSGO`LV>/)ﻑUr8Ӛ,E)c{ RQ5ߊ/&ؘMo h*Էʈ3S0Av Aqfҙd/m]p$NTA7$E9(3sEš P > 4)pE0\74C+)ٹO]K:Ǫ,peUXVKصu5a͔T֍:rԀR&ͭA::EzgL6,TUo\)'t7#yNUsKs٧;H)*C6-h#ZQs4B$!$yvW3hE?}ko8B)6}(lf>)7F dLUoU~k9q~֝S[ko#bdH \!+UFS=d쮒M% !n3yBmCAUߊ`S訧WȲ[BWKfAAQa&* Pȯ؃N>ö]I]џ ߦ@wŢ{sVfgP:ѡV B, MK#9p{2ӉFg<^oiF!` +Z.fCŢs|O OZaTc}\b Mu߲4WDA+%v]p%P|[69|{ 14X6 Ӌ?b9@#j`tC/NnF/uL8;'l~ *G%;}0tGvc**qC6'k^H8 #@]B@h&О(,vYW$wOC>w;r ?vs)Ow߇<;1<ϸֆh#e}bV.i`,؍ÉKFxzs/.>;>w_\o.ҌElNN/roHr?tuߺ- ?`Oi&XF$߉ UK&xS \944Z@qP8UPMX̶2 IT|³-Dp>D/!8Gԩ !,1@8,?\cFR#ŅQlA: ڭr*/)x: OaW"f$0$e}i6 "z)x,/[v6ebQ B+ m!jAOeJ /m+%:BPP*. eH k()΃at"dR>bbQrH%w[gB8 ѡZQbM#ude{6u|N 5V% 풖5xGMJߝ xU! }0ʡ\(PK"QLQZ%y+ !pxu7ŸJ8*Ωh/8.ɛ|K\գki<Oǯ #$1@ i.O>L`3;ouKB0 t! hµqMXP? X(E#qM\ @{Jt?ljRl4?5Mk[8 ?x6hMk`qќnvp P^1t?s볂0/kS+a`6k>N Kc` ]9}m:%N4c9@zxW~YY4ÖΣu cu$kL8t^Ȟ7{G`cz x [i`\KW{|yS㳧Wdr#,[N\C<@h%{oxI3Ijcm<$wRC"7~]:H]jeM+U>.gR&&;VxGo >aDgsK ZS^?:84O "5LPaIZsVKoQx-KW >;5XBư5]@9H `|_$&6 v+~r;_˵@=n2ej=U *~3 C TL e,so_}ӶHE #kGWED "xp һMp9rKVmQ ;wQ:";Q˧$~e$!2k eӫ @ )f(bBO2?a7a?RW桘=r}pxP\8!~#Y=rj+\wI$pipr YI9e#$M(\$"67hv(nD9l OMnU0HD#ƶ+mIa>A~R"h lFN@`T%6D Wdx+B)8;bʩ>OR;[ |J?qypU7ͻޭ嘋$P |a[n9OY-'״&V͍m ~n]bTDv EnH>Y91 qȨe5O0IE̋syia4Hs MAb=`o"0)袳@ڦe Y^:B.;7d oy4r9֙|)8}R=sh_E>R"K''ڧֲS(c `e)&o[vZ ;uk#Ug ;j.4P㮛Ѿ?}h$b-LOxN+/,XS%G-|Qic:i̎AA4+0Hu8*eՃ c {ɬ潓|?=x$fpPLL䥅LKo}$ͤrdS;&a$kwjg4I3[t͡ϳ܌Q=Hռ?M*nB?|oef5.ăFQ?ʎ QyNF*?74 z#*@I|߳Tu5ETdxTWyK{Q ï$6hjJ1Hk ͤev9(9ՠt)>BN['n t@bVZqK@6pX5,) Č(pI0;OMN۔͆%2mOO0%en]d MlEE>3G! ջP\5vM| fZVƂuݹuf4#Q3Rm]/% 3HSh|1ԏi#bV t1LdBkX;睛a8e81d& 93zm?/+Wh''\4XQ)*rT"u<ά: c٧QWhW:dcG@c+#oaK`2k2ܫntYW4SQ Fiї č ')vRcׇEF4j=VL@d-HߚV?=|4ɨY?L­^8sRj#Ay2]E"¾6 ˭Ѧ}gC& Ɉ㺮؃}v Pm=Zx/a5r* ljp}lɫ驩^(m#_FԷTL}17g/+C.0AѴ3dFHg$=kF3fd{Ԍߚf$EkSPmij !gHMFֹ̈))ЍqVC&U.\h1"Q[si:GZ#0#:ZB'd \jBX\ͯY#6#7]#/ZLj_.d&,6 Zj2ʴGD) 2!}guݦ5χ[M=Umq4p(ν'&ɢwH,.7B!SDl9T9)r0%m-w2v0[Ԋk!GPU{7khgv4bB}ILodž a LO9.9H*j aƍQf?;暨`Hx ϫekʌqckn`|a1enejEF_m+zv;7v}%y̬n9tk,J )ד_L%T7P그ir )msU`&?ɏh" K9oD*!*w&i^0Mr?*gTΩ+Z [jNq@N^TǷd?OT~mTy;Or<)TXP|/J<^.k3^~;ZY4,ׁR["|޻+OqNT$ltc^EuJ+Z`'^N] O)݁ሎ4iҐ^_#^M =S 8!;DFMlӳ3#%<:W#`v)? Y/w0c}6)sShkZḋy`(8b<7q@Ȓ\2Yho.FP_TǦX̿e(-VyP&*Q_^|`V|{2쥁,rLe~*k/>ʽQy6ͨ}ZCo! B+ J :J Z!Mskyg{Ë:C'PNL0'S)lIң7/慘H Ĉ :):uP鸿c & ='A{hQN] &;L+3ꋩ՟5BrBZ\ݍ$O'q:ISIM.3^ǐ܁ ?6~o4;jk`uLc TR;+sW0ɵR$lZ-RuCRSUKN"Eׯw 06CӦLUf@98 Ca K`(T`Ӣ>eyѴt*Ac`'&Az {VS98K9QX#0U۪͇,uՇ^ \džp"uD^|DoB!j\{bY-z7_,I$IZ*zcm Ω D67P7G[ࡲq"*׷~h^w)\n$w]P}q V%Mwϱ,8Ct?PˎYMU7]:󍶑(aV&vh RFVNsbL800L>%$_UOP<Nģ[U;HjtwvgVTI >ҋ]W1CV|e8 .'ȭV/HeFfD"2l*A V`&5B6 GTG7*/D|NuS9/kaJ_f241мpߛ!&KI_1o q 5ϡ,݀bYZ\ЖVZ4j$x3 ⁺}yo,F+4<|V"oB)U+ԭ++XW[mWPn *vxine-lib-1.2/misc/fonts/mono-20.xinefont.gz0000644000175000017500000003477014647725152016345 0ustar meme}4U%SUM K%@pH@$[?3=w>{ޙSs;>= O >SzxCש֬25AA?=(A*~>wzoy?80*9("`Ȕ̮&ӓ0Y'Pd^D6!dŚE|. _Ɂ_ _xj.yNQSi[ibyF-NSA1ZfXi"lrn qY7: mX܆@acE y< [ܳ9VyZ<&Ҝ>=ڄXDPL q_=վ0Q^y7Ƌ_OxxKmZ6+d8c"]'V,W ^3svۦ5|(Xm+]g7'vv0rn2ܵMT„'ոŖ[[ɧm}y&Z3;6g gn!r7MT{+IUYʪN6 _3):Ief/ wVA^AyJ1-w'Soo Ԍz&̻3{ѓIx'kjYDvfրRlL_ĉUX(k ٔ`RRs$m?s36Zv7kTK'lLP@3WGP$gSE/4= " Ju>t!MK&l)Yj:6J9IŃ|@ L;f 萯.B p9A31qpk9@BysꈦDd\;[>S[$1b="gvf#9/CW^ȟ]GϲĮз2Yr6<ٕ"[ ,ӛxGS6/Ug|-k, <44##Q`MK8vu|n_F  LL6Q`=a%G95r\$"ZA.Bw =2ɆtϨ^$fʃi<@7nYY$ cf8<= }klc8qGab`$7 mIJ2fc)ew4 sB̪B)<8;_0H:HD(ٲziNjc$iN~AWo۝rl\roA'̦L%s=6w{zJIaN =10{`Gg=D&O( 1;dQȱy**R g *hhJH8(S^|HC9-2/h`9xŊEZh,*rܣδBE[]OиdTʹ]Ufw 2~-W@Y*;IX5!!^#A|96A}-Gӽ޷EUsZIe{w⁅`ig1(D>w߂aV8VV=V-J U!UFqVJ@<SR@ l9>0MǕ~iaGwUs-7MWa >41/mo]^"B2&g0lZ}@-"s0 mw(Lh3z3v#߃*kdQ Վ~"6lBfeAo%~d5XMU,b#d C'Apmc<['z|*s4<.B0RIJ'؁ͣt>Ȋ^$hwkGo_y}6;h„,{53eYUC"B5be!84Z"gt-유;(Xq(YT[d٭Ԇ5_(ӋBo'#b7y> 9+xu& 2]'G dcd}?{Cξ2llJ.<_sܔ1rTT@)5;Kϔ HbRٯ?Wֵ[fMJ!E}dْv@tFH;B^ox29s,bӤCO!F=|>JMDH/ۡ-21F@X?=_2;&3c0FS!AF}~OV829Eĵ0h3̬B }jum%޸<\mk r\4~= ./4;ڑiŔWuɘkȠQ͎#D\^Qt<ӛTM, k#y1PMQ?UEA6KPf*L`%}k:83Au&bgĺ0M5iJ5~/ɾ̧NJ3](x)O+]PBm o'̘l 0sPF ,+$6Um"D]˚o}1ʳ `» e,@Q{4gKVj] ^Fr/o3鄦~EmP]6H<$i+D\-^A[G|zSCBvsm 䳨[|r_z;Z2"m=7sU啃JHҷzW_<(dI6Vct8y=~Z}|EAU`d|1 ys_筿zm0[:pXvtpDx̆nvlvv8x)Ca5;)!;Lݑ{'I4$9^.Nxr.%\9,?33$뾌ha6wP䈥 pO -}~#niH DߋaJRb3Sy6FҼ__P; 1|t@HZၢ˄)p[@Dubzb,1ޝt E/5Nـ{N ĭ.=@)WM zp&%1#DwE=癛|r V] ܌@϶gд#gջg1ܥu|kC?ٷdƎ@~*qVc*c~rxok+)R{c|,-ia4U!܂8}@Ws 'qĬ WO@0 & qڄY0Fׄ `4't086A*#&5N@+HܯDK&nmoCWwAv]' 'ؼ%N(Bs92X]ibTm46mYB-%R\T0]xI#evX܈D#_]q%*0 ^?-4Q4n؃~ƔAO53ʓ|xLYN'7/N rztwxA=Wz.f9Rw~BѺe3`2쨫Sm?Jx D~mE j377o/S{n`Y ޿|N&jT_tg 4Ye&L?n }?k3q5*kŦ=]7Y835 v<ow KA( 2l+^/ٻ>>xyxg*w=rvxŃMo.A#H` =L}P-}7$̶{/5 nUW B~φgRIn j|w~F~ڿduxp??7787$&*w(}.;$ӯPWtODy4A;ʣx\'DL2v>5h>yޡgsxK6+yvGp[sяϕPZ9߷7^$|@ɶn0 `h9oZׇS0\\H&kvdGcŻ!ۘu4c>g /z k-C3#2S4sp?C~}Wh }) 8h(Ap.p"BYX-7_nnDuSNG:=SOO>~F MN%ٰZi@H`𷗴f-")JZ r.]Eby9[!hl67%gj}۲/Yߺo3J4Xp/G:=AX'%veB׏.<dG`譚EBR%ٳKK5EXKmtjyp'rPY5FJ\_Dӻ8nrHaF2v -AQ;V<6-t=OK^0lmU4\¿Fyh|={L3gϑ̰\! K_Ec6SwNyɮeqmK/Ll&{pfSK?BMkTFLBSK;65x]FƷWP8NAYuAނ00CR 5`VG t:`Ԙ+x֔ZER`2*ʰeſ9lG~Hm-6=x>hu4^cns$'kvaMH6@F3J;8 ,:kZw݋KkKtzvم-ld3O znoq=G{y:ᗙ =8z6a^?2*BC-jӧt7q+~J&J % K"$fT CM/|,] orfׁ=iq.OO\3~mi&@yF}-XwXTl*UgN W8rcmڿ?ԉTYZ,^uyoCЛs\0#DZ7`m HޜԻJFəvn&y\ȶICvl~&s=$Ęc̸%HMp6(6ٰgOt6`Oht2R" 8޷MjdDr9 qjXDgMgHL -p9D=`7RUy&^Y7%#C77fQz S^+ɳNuM 4)C|y7(fJ3βb$XLttOx: ktD6:9tD^߼5+[q*Պ,dЪhy\Cj4qO|3lk1;Qˤmjm\jTfbyOupK86ΥO:GGD#+5,tnDJ#'QW>N[kHev&QWeA,M 0#'m ] ~Nz)Ne 8B~{_lG*[] e;Յ[?G5W@h`i(y} |%8uoΰC=>]Gz1S3~GovD詾~+sKWoK .psƙźbw{p^~O-)*0ơZ*:̓>[=ȣ'-wZ2貧ͦp F]Ъ69siQ n &B ԔeJ? iGՋi:r%1l{Tz+=&#,Ik>j`jyiJDwvVW41pT_&DGA:86Qm 47Fm1Ps'};3 )+֝NNnuѹBy\sSdWP1AFqg l>tioJjb W Afch5#f#q2MU0 OCÛ9^ v5ssU'ܩwihsNTK&7*Ek 0RP_>ŬKEWG㮒u *HD ] ͺ |% ^KQ.lG ^z=*r$5v; Nj8ڃIz"IuӤ24ZŹw洞A5|ebkLl„_z[#A,")8]a\F!4hC(INBLMBD3R]JT9 UBZ]D4hfZLT6#A> & CXӯ eW|WowPU%nŗseJ^2sr(wMc8DmaTE+mؓВWBnTȦ~'?QI4T2 |aϿgLTՑTHF02s̪2ec4k^]4M߉gFU5u?܌spf߷?0>6z-A@N;k?3+?c=9XL^n7ҚwaeNna]蠹Zl|ABM} E\;#c%Gtѫ>j#Q7K/꟤i6H=օ7'Q1G-YݱH ,WSb ozN>7 ]_]J[p{9Qm _v PrRp;ϖ-74_K14ږ`c2]c﫝& Ϟ"݅6xřyK68E|&fvByA_uKx5\Y<ڊU$=5g3ar EKkl"! n)p& a'5aw_Dg@o=u6kn4]DT#$۰RmFg\RsxFosCq̧y^r 'h_JPI{c[~K彟v˲zBӲ'iIX7֕!75շEZ9Q݄z1gaI>Rfp!ID\IYA&βн-˳ӲpbgGF>sK紗_GY?yϻq.UjFSͻDA[ɾw_*SI cOx{Yxg.$DLJ#|5ac88!J1JBV ?~EZ'A%Oql\k ~$ %5閯n4>fq }U@{?Qc {ˇ;x+w~t7'͒@,E Zrb RҠ ;K =|R? ;˳UK.&pb#sGqcYRmT%|grI@Ӯ ݀ *qe]3) B?Mf.94xiŨC` *C!)ei` r ! &LŨLĄ3\`G>mvѷXxine-lib-1.2/misc/fonts/serif-64.xinefont.gz0000644000175000017500000026446214647725152016520 0ustar memeg-vBBc>Ų#˒Idlr/8dbuU<9{=ٽf4?};p?;o~t\A᯺}s-vBOAs4dVe?`}+r^ayfW(? ?Ӹ">4sAkW7wV4A+=o`PS=4aVU4 SٽCrMCӝڡML&|_nsryOwsꜗE ªKm;/ sѫsq.El}vz_26=q! L~t_uCEj6*"MpCCĿ}a%A_}R}qJ4o`!눏[M (`G! \bll+bϝ_Olz/ ;t16a׍Ҧ 0 cC T{>F?sq /+}s{ %mik,Љ#{C4~BNAp+}/S F`Kբu.+IKT IZR0Vz?CNAT`_V"+ 0@ bYUQ] n3p-i&4ypg=\!:aKiQdш -JDs^- M]alrϪ/-DIyU;<1yB+ KqWu5 Ipj;پe"m) AJ"i,JS*UCZk2> ɢ,Z\7v{ wyM`41  [ZKkiZcmfuY-@(F4 ;{]@Ale(SKp* 3 }P|7/U*k(LC%(&0 t-ݷ; `Do3"]kk2w3P%]XC!xWl(/N"K{ h'\ܦ_Fץ$^<;U ܮF>둠Q>wA ;\ o\Cbׂ EPOjx iE:q%E#|7Fx!/xv·oho r`;yZh]I(7V2f8CV2e)7zDG0*Nw9ّ_n4<*.h#p_֜خ~~tKqZ>]"fv4Uj)y\@֤5E!z8Hm-lGH?&;11DV{JOlzݙ$0qksw:i@NֽAO VwÖŘJ(+t A FR t9nK!Qx(ER3O̧eܤmMrZ-"Z.`pA7hT@q.U ҨBK)2{k %C*P&=NAj:C(R9T#F3\*Ibv^ꍨnm1޶YoE+K;,`DogN8!vK oq9S=xjֳicRMWQHڌ W9oE6=V%d..bT}J*Oz4e!BD [~&W\nfؚܲ27,mE]&:M->&0GnN#& %>[Tёح*5W߾uF^ B.inΚE/i[QvmoMՏJ{DjߦeSTU#L4ԨMÜ5I5tۉsѭpX'c[] J7w@l\+DV3eƙW ~=noOlȞoo~z_}A{Y%0nzh3n'C{`l;wp 1c@lW~Z]v\~{@inPLeKs4"6 g_s1 5KnU+1a6ksjt9!V(a%>;5</2 C}̬4xD}vL,ܻޥL_wEץJxH=ݧء7ΑG'l!ϋvi4DuPwNN^LoҨjEC!לg}G7y"~$۷^ځwqǰhUQX^3 wq TAdEuVbƜ}$Du<7{6*#.:@hޝtow@(jE|ߘZ01m1; sZ$At=e";(]eړu6/k'onas`fX-K8Ԥvalq, Nb,bF~M2zJ_{ >"tm^$%z6tZ^M91%}%л>v~mk>},{H[4W#e^|oE]p[Byq9X,L/\[ɡXUU >~O&Ѐ '4c3qyB7X.oeJs33 CD\EN$L Ŭ 8Z--KoLɋ}s릾B>[w _ܸ^~. .x`tNj'KKx^}]ֿk(U B&SO_7c\!7 %?/e+G1[T lSAx gwT l ש T :Vn[䛷LX2kW}}i?n^w#@6n4k9*͠od`7RA@gzĎyfm?`º^x+ oK'S_ d5[FbVn;:`D^$JIiQoܻ+b(>ƽ\?#J51/6=c8>XZP۸ME7OC4:v1lY[@< x@3o,s`tV[L;2BI>eXvޜl1`yXjkI~?~p}X8&HՄ9{z(Y&ࣴ`nlQZ[$:n- eKG̝k=?R.}D](ʅ(`s_by`=!HU" jfq+逾 @\" dm>GA)I]v~ExK{Q1D/lijwOvT'g\Ly9V_#`$0F %hc@c {*J&SZ-/-(kk(}%ؾE ۫\b54vGR#b<;UM\l֭8^OP|oVv1pm1> ri0Dq R<"GHI}04RP&(%xl[)ap!҂CmgX7:`4٪ġvQ{;ĨM-GCLH1A挗 c ?;:$]3 jlFqw:+ՆDuGfsIJGE\=l^8o\~fFIYZ77]ԉyh97{AűYZD2\eq-"_Ό7P2afٷ,b1H6:acq=蜅y[qAZ NkMq(rˌ QCv rDC >T gCI ( >n^T$o.c$װ7FW#GaaOT3'0 > o4r2VO.٨,ħ.ܦ~SɭNS-\D9DJU x*jAx3z fBN<8aj!LH%Zՠ_QX+yaM+R g}<ĩETQB޵U\&=M nXTkRbmIbEIBz2@87rOux"/2/=8JRsMzGnv P8KN&ʏ7syv>-a]pn\o'=INlRFo]4dJE@;`8L$2V]{,̫qH81Ol'ҳ>ێDs?hٝvq;f`g|sl&uILR{~2 < {Z%o C'ݡ",'m;Wd'QMyfƑ b\9qs~zӌEdN|8O3Xƒ#QAj(MtWʿiCd2jG)F+JI c)&НF(^i9h~RC(뙍{̪INҋ.x'Ιk` uc1زFsi9zh&ᛂ[9*YLm$E$Gډv7ErL&:i:*1,]`)Cw9u`Q zzljsw$alKB7QqN$6.j zq|eĨ*|q+_N`+3FfwƶbIpRF RԄq/ 焞TkNnH,Ut}l382 #!* [˟-Bm"QĽ*'>DU%)X ~O@/Q$G/YP)iË RRRKys za]pIp=T©E?xV{Bz?Q֕9 =4v,xl)sVȊ ou0Ӣ1w9eH!V \B+_&7O1ܓo.B/.M؁ nC2GA/x̾`Z?߫sJ,p]#nr5S79(nC+͗6[n?sǼ#{E$@'̺8vNow.vn'{swo/qYK/vtp$gnI'Ve8|f-Ӥl,+W&N~FWWlDeůf|_UZoցwLІ-CAyKzo? .* w;$ #К"t\. 5"5v @[-IQ[*/c$6w?kM#y]-~]rؚRCw І]zREfkቾi8;dNw mѴͻI71B3HG'ăXÐ(]"7?_ .]E-r@@"kڇ_S˗ > [ͅ]:T/((`o6%|썺䡝:mx4{k*"#oજ]Z[.ُ CYn☙)*4[CIHYF拈=,gVNY(HG$7/;,;(#O%P:DнekPZSӗfUs9"X%2mb^x4Hf~I,Q'sI!: ʏD>ۏeC':(QҰ[{(yNcD:jLzMq~Ava欽Y7EψVQ>}9;BE7q7/g]~Y]pϕAP,3dPwxaYӼap+ִ`3uَHn*[˭w%=h8urWP,c|,&6nXd^XJG&ğy-'ȃ 1ѭƮ9QiLp5vKʛ&Fv޹)WR!_fisFo: o &mi[@ &fZUqԕX:Y.Jg"'p^viA0̚ncN]Mih W\M)8NT@]Tg֠t)Um m)\ AL饖p@3-PsjED5+(,7djA;[dd`#!GCY{ ?;G ]v\*$_nu?7ΎIhz0$|6 !{t^C9F%!axƓl;H]R6޾.x%t\QeXV$rd?p y4~u\ \{ޖrkwԣHr<|*t("W荢f>Ƚګh|a}ɓa(9 ?7˂E!t.(`DoxwI~Pto7p%tz9叐P_P#ٟ?!~:aO0?b]C[!~L|bt pG8s}eG_6Lpy@Kq_5ŘR7BT"#Fo;#, /uo֖r% =x+]1'Nڷ6: c8-R@@q& h)/P . `!FNawu,0 qzV89Ф:@]x:aW.JT}8#FU籜T<ƗI)\vEn2}v?*=Z|MPi).~GvŸV򜯌~XZ8O?Y'΋Lc~>)+/F{[, ɐ $Mյ]R-ߡ/ @2z@fWIb:S@S`XAw߭@~ sLY GGAގ,nؑoz7]g *p'ja ץ'j~lq9[cPB?m\ǸMkT8F;pTɨ4mfyʏpiR9 nƓ;LR8ړ`7fTفO;NsN4vZm4uf+uɵPkKmZ.E<-w~ˁ5:S;S;u 'J| ˆ}@1"X~K2ߓ+}OҦoV&@nlt) '08a>Iɱ"(܍_2I=o.HgMçç ħmPNO[OO"ggMEF|H?uh9uGyyP]~ r#vȝZSr %ƹɕ;o%S 6f{C7aE5Y>QDܖ٦SDؗo]=QD ;7L0U&uCsZҚKˏ:Gx!gDܖ%FGZWҴU@In͎ A=d$4=K~2F0 LnDG?w~`]KOdA*Ղ81HlD8 V3wb0nW.Ͻ|"ړE$(<__' sENK_T$`c3AToז[wQuP -}3 F'-y >azrq1DuB@ {cbRK>O[ \)DeLlA]s9x qXXb+߁}E CF ^hq:J!Iˉ0Tf xZ~x(M!w=Z?~X>͠^쮱0W^N}YZvܳ9ZY6X>Qrʱ$B/c*9\(Pvot׷ e2FN5ߩDxډL͘{01QQYFܻ:W\NJ=0/ab{6 \+|2T,&Xɹar[S?6EP߸EE_p8t׆7ܷ צMFoenLٶBҏۍ xqru\m%:2k2gOZ$5"q廘:g}v GEzC{Zeqi΅KoJ9;Qڛ6g'J{mNv/3m Y>.e6gBPښiD 3ì6{nDoJOz`ΎK|L5o5$>gJ׺uOVV,O'Ky7mxϕi9Y:iEB(w|t5li>ot;&;6gti6osMVܝh%"J}v#E_43+(cAj P׮thmS37Z ?Z:8 \$l d90վ]{J\۶>,wW  VsKWGeN~-+YH‰tO3։/T@w}O4sܹzl/ rxa/slOp$GZTAة]c;|1I|YMr8>ލ_ʘ~uiQs2> c=-07F>_cvoL|;|cu?7to|oc 1C|5IҒWJ1Iŭw$ f+I"|0T $>/ZL^6sJIRQ[V&eJW 6>a3r{jo / #E| y~P`6/^HjT#³5d# gz \_X{_AjٯA~xv]Fsd7b?$*SNeIƠKaJ.&&ꈦ3d>~ur)D--ݤ]ɮ=SٍLV7t6{'@?#E&G:uxƞ^>ȹR;R=vh FIϋ.Kz?}*{༡0U աNcdIV>w'o2qz_bqTLRoW{:/2,5B+D'DGdjEiDO ξ 0fK8 HG{?zeG %~8Z$<%"LB\FQk¨Ԏ&y S?]ur,s;q Dlr ,ق1bJ|aFKwv0 )<eIb1]k 3#QHK9 l|Y=Ֆ{qs"-4~W JmvI׈AK<00s@RwRÄDDZo]ʗ  6)t,|P7ŕc|SWI"oڦ6Vq"Dg4@0%?ue'#wFrf?_ŏjSWȾNh'M!>k[p>QE .%K1 1DEp(5?BRd 5ALeI+?Hl%idvR~NrfRW=ғjϋQ_UHNR T7]]G-4aE= 求Qll&JnYۣu\#VP(G t29i_ۏ.ߓa]HA,t܃tm(\%G_Q/ab-"L»Ǹb0đR}((& alNB(ã/XISiZ$ 2yX¾*Š'KIx1I %W¼R|d/zRO1$*6}4/d MmWpXЫnXGusHgVYji#|ۤoU^Oq,>Gh K bbi.(K&L.֦*CXs2*04a"W.k K)O<{X mш~%g zYݯ&_/ >*ߗW ^XG6{ Ue0ؚisW4=g?N/~2> #ܜ;/ yu?M-<٨ U2*%i[~p]pk~*T/\'kޛwah|'nbk61:嵡<УkN75_`/Hx}.e"Ӻl?`"#֍_<¿/t[ $tB6pY (\v0oTd̂MⳜQAe")Cf(A`6PoƁ˒9HMAyF=>5:9 fz6}3݋|,k?vq =nĩݪkPcAgۡ$۰! ?)!ǯ̭d|8NY({e=]UWXfIZ7"$!ЖM&]ՎrI8_3􈹎KQ؉h/jNr|vv4_;)Ee#1N&C$[ԋ\wo1ɯ tL~gɯ?nGkG|0!)v.G *Ag63 tUg6M &OgcVyzP`@צP ^/(e#cFQg&}h=qN<1t` ||;A>(|i![ GGȎD'ze)(z 5HO#,:`CD'[|'(5Jt5 !<+W ;c{D@f0cY=0} Fe "` M"WljxT1$xMN09w_Nw_?yq= Heyh,M{NYZL>"|ȠVՋH-4}6h2:rLjA5Pj_^4"V2; $y4PiFn ^ JXHmmN>-m-<;(t`q|NMqwco5pD~!SE4jCRG`C_?<,z a)JbkbsEJȝH {x qžiG|xW ^+-|䒗WGq7|aJ 4=d8z壠틼OG&'~¸PZRlKL>tEd}XVh(s4{kȉ FB,ݎI?:CK]gHP5?A3{lp4Gey|'F 2n]q;v95d%tVk[x󊥕RX@hᴁ0$vF]Ɛ0_(r2LFOPy&)uArZC[5-M~sGޢd3ܾEE(޲T紎\,7]U7}~}*){@WҹOYWuJt/~cJ>%; t3u |̫"U$"Ulp\D^K @_/[V[V1ULn[$h0*y|v!ۋGV/,ר:z=~s~pٳJnXy[$@*&qZ\\*ĥ@"m’РA Jh_~RթmtbB!`N͛⽈ 8\Q%EMZS]?X@ J>6_Pǘ !h4h kxB6>7wxy:7 N0v" #c,ZA,NOTk18FLh/a0|F0[b;oc "b+!'{P Rul#hv^|+៼y~.6erpH:nǤX]#Y@̖s yz/4J)CRk*vaY$)K "OS{Zk\EҗFh$s1ؚ#Պ\ݶ>QnsʉEJZby$Зf<[B  +=]ʞ_2D43wne9XLYDa9N l*X12Fr?}WPW"pVSbA*33@w{kSh@1n%KϩBfwP˗ [3Mrdwh~ά%;d^aftyL z=Ֆv9򷻁sm 0}vrS^}EMY1U>nfhs5$k !܌S=E~{h/ nq\^`hﰃCQIuz$WV/BI3ĉi0sةn % 3ĬVp|(;QCD2kb$jBN-Z-v":0AcXWySG;1t^a)"H1suLu(g${a;8mJo\G8BW0A3EV,D)`6ØWňQF xr1冱VESfLVBa5 CiNdoo'Kюj.h0W 3P!DdG)mMڃg.BLktij\qS,kE߀z+J_ۏ. Ny)sS3$󭉂a *)NazXUJFXB .Xt֧:X*iV|Xn-GsI7Kw&oڅl<2싇CgoօuK0DEV|Qb5c_v4IK{+h4LoSc*0`er)?v-s6G@t)X{2ܭKNW:fJeq1qqix ܧ\V,=`$7Ţ?`PyywOܾ#ρ]uc_Zdz-DJ>ť8U}'٨'^.E]j%&,bv=).1|yA=wGO{}7Oh+y)FEET=q]t9MI8W  \OvΒd,GNzC;I<'IiNZo\dv0[3"i޶&Q hV~Pr45ϗ ۏ.2 /&4ԕx޳ GЉ BxX(+)Ikΰx2;HJ1,9B$;=< H)^d$s*2̠h 4»{_SN0D|ʰ AEUWuCm.1.T]vDra`u#=ÿj9 nC ɜv$w=$ [PJbF1ca ۚ$We%קUҿ)@;0!ngfˊ(mmcsDJ2aoUEL.OkG酟Dm;_|UGqdjj=J<J#h]M t06Kc+s7¨ȏYۦЂ6d7j)ŀuiU/t%Ćk">2c6Q B-5PbGn 9XCM{x│ ~ĵO.Sŏ zlgNW!{A҅yZ?׌AV ݄*nýrh8;0r0E_gHBj,l_\6ͣ |dcjݎHQğD8)#UTCIҩh_f8D %1?n(>?w֔PӌcG 7HDMT_*cs . Ѵ#ja+? pvy670$*B޲Tl63xd&͎~Z;qi˃b$vM5k+́\;~{B;0 KPֲQPe4 sPrpe)9LgƼ6mwe'Q7-w)b^yc yyvwon"_M@M.7A\*Ղa^6 †_.#b ߹&M^Զ@p0.T \&?ޯ0ǃIFfXoϠ(&ȍ5` v%9Q!6^̜"bٞfao"9@9?CJBfr.庄<~>2H*X(6fOH)jhʈ6;@q(|+'LLԽ:yTףfl$NhKBuv1"& rOLqٶ6^PlnɒhwNʬ#5J&dw5vk6k- @Ÿ D~B4%"Y2y(вGJot8RofJd. ƛE ؿ1ELr6 NN$-rټk7YL[iBKhdhC]-b6BaES[ vB$T-[w+OGpӌYՁzf)sd t|t>M rF443R2(vW B? >)Bmv}0m7M&!4!ҋk=Gri)eW;2v@B 緟[\hm+pBHbee5qSo_jWc5Qc ,<2ǘsVe&Z )gl&jk5QLvĩTVH fd5֣iD$[؈2>eF{ej`׉zeyCw즰M>Z$p7`.H%k51([MY"J΅Uf*'m:+iɷHL-mXiu`?H ^3X:jp&8(R&I 1Wf`&*U YMSľx 0le@|(Ak2VYJLh xeuvNPsUH"Nxq }:\\̬&$Xrǫz`51TZMuGVxo&6Sjbu <$ye!3B[j(q{^Ʊ8ҏ c6_߾֋oy# v;K]B^Լ_yѵK _P1:PFw*7) 5Ԙ݌(ȟ+]QÝO;PbXJ&U֢31Wk%⸶?juw`vMo=oESc:]*#Oٖ9o_~Eōc\F.,WU\ۖm$I}m:|-UJ)%` YXl|R,w2TIJ?D2|w++hioQ*&I{Nؾ& 2SŖ\Su+蕿+YʿUlBVSqh]M-WRw랰PnIs|#:ږ+'.'Q>GE )'~~vL8'ycw:fj&\g!UzX7 Q)QUfR@r$n+B_.9_BF^+,GwɻYI)saՐ nMvo`mK`cz EiAgW&&h̛O,vynMN<>|T'/ c~nrR> Mzh*~\- i:|x ;pa]X+ZZ1t +ZwL s fl@֣KM M6ahUjlYm 1U`sV,7$CT0aJ"tuTYFv,G,$xBEe.!Mx/==4Br#TFr\A l[N\TБ+IkSHD8g4,ҙl$t$/],EA!H i RN( 3.Rdv]$'`.eH qie.XHPΦD"`H.;BCAJp›`q=+e<\Ԭ$1ƖP2`&( 5M@N3h>g~p7Y]8"5≣=vm"xPVb|>K?߾_p8Jw&K%/>GfeದȮ|-,?. Y\21! *ox9֜E ni콈mӷsxG-Ȟ?qe"h.mWװ.4nL1鯑!_&կB5"4]n!,K\ =CO땏cXܵ'E;Eq,97ex U W) g^2j32`2HjF[G&;:N% rĦ REU&v eXet/q'v壸 PsT/&hIclw{ge^]ۄ$.:Mv|CV.VyRGW3 ĒW E,1o3LMWd^ ᭬BU,d8mw=Z /Z tWBJQk].ܰV'?8yLMΓ'*{'*%v*K/^/xD*?y|i!oQ{%{2-ђSrkYNvy1I+C50W"pΔH&.x]ē$WtdM.Vf^ ;קn g v);г8vK 䗐KOa\v9pN (0;)%rTR +;0Gy|o* tUv%#8)Mc' ؁A,{Qن}Q ?z:2KQGJ%h>*".iG%,˴d3re؁{YAs0inXmiv}%ϔwlN<6y۝@mwq ;k}F Ѭ6e\mT.ý/x{Kw-|18f1?SdrmFKɜ-xvX;g~ląwلdw#oSzRq8 9@Ҝ&Z4e0guI*3N$&jh2M:qݞS&:^0gypl͌Xp6kK4rRW/u[>:NPr2D/o6&dODӨ"x,;ԩ儤w` r„WJ}.-,3KXT 䋛W¨v^>fvt%bb$cR IDQSeQDC}H;A%3Čx!6s9tÙKg9lb\ίmzg3^B #U@3^C [)|د3R7% ;aMNStbCNR@v'fB4K #!- ;ڪW[1JP%Z zW&r(L\/a޶d-e lQ?":MSL#v*|< 6ث$]BL ~N͙>ہө2^2cpپhaσ\fX9wD/ag߾_p@ {B$Ⱥ3I]oyK'Iq`C[XѲzu`Xt@soN9i ~&紦b6O`<F:tAԨ&"x2VЫX/7}B +6AI 27gL=fAOFar~ c:+;Ec:` k Ef{& ]8(,/̨PRr=u}e%lM$J `-^&# ;;#3ׄN[yуL'^^q|Y6к_Ss#.X.Exfĩѻ&FI# ؖ;$i2 _\kf=bAJ.?by־ei ֽpq6"'F  FN $5vA#΢tRomd6P#4mؾ礆P\ZQWCmk1 [䲋!@~M4UZd;0_=iM'yxܵkG;,'R&<_g<AZ?xP=.`rC'_a r,)O ʘa4pt;繀sl4ߢ3S\@xs.`@#Vkp)\xJ_ Mp}.?.9e <]ݗ\߀%!;\7/8#r. #>h71 7r8#Vw5PU `Kssb)fd'<݁O1-qp  :\nH [{wozzvFL'K pxdF=j';@B20:Ii,W,AC(>Ƨv\ .`.r/ 0\ tU.]r>o nQGNT*mݷ'g?) .82-a !ھ֟M-|y6jDt#p|XޓȌH_\_ҺOꥵČvp..;:pqԝ 6pq0_\gNc@:X,1pfzP#ls?6U@/BWMf4]#cc=nf*C7bLT\ A_t+sI. .EwO[nE>o`t4 8h ?hZhJ+}d̡Hal>iTS1 ZLȢ4103xOϓ8;m9KՓwO)JA.@IFqArrA⯆ xas`]\q%Ilc[pcᯰa۸C|Ǐ78tT6`Z7_Z@L=Jx;qG?EBlqcsI. =LOr/gu 5r/Uu< 8l \;RG;\/ MFL){ ]|0F0.\u/0 =V`J]$].@ 8 l \\gOF\pKBxܛ>t^;}56ۧFKYTޫ!i(ES A ;4vqbL7k]B*3R?{sI܉M3u#ޕ-A,.ka%yaX_9{îs4*Vb833̼}s$,VX%Ă5!EVY~3Ve0u [Ɯ& %GWKyDz; #\O \HM<㜋u M`d#~Qeڈ⬋ᰄ/?ލB] d^m+uS[uEI ێ,sEXY՚pcI3Gٴ\ DYЪ-Edrt¤}< *w= Ϣz?6[F9 bv^a7MY Q)6qf0@s-x'}01i8-q?G2w` N!gGZ6U&ߞpyHL(5#Ui%U/D/׵xx`ΐuE7ENkS>s# 6NڦYJb0M Xa Z.yP$]ЂMkF2PTm'\9d5}f2g(FicqK)zN-ccd,hכISh Cٙ)@k}i Zuk}& q4'7.-wi}9z+za>iC 0|zki݌VSZ<%ʭ࿰RnvLN׷E2]st׮]&t1ÌTfN/؆/߾;{?#`VPYjӤkHf!3uBԝei= fd+|_"pkyQ%i|=!37(vH'Jο$iD+R0t^kRT%RpXo)xDK-/햂H w0"3|RYK Χs7SܞΏ4FyU8HɽFa~97YI~4nul…&bG`Yo"n!'1j(Ʋ&.XR˴c|K 7(  V7+c0{L &.vmI`^^Fߺ7Clsc^{2G?㽋ݷ[ J!c~;<UuX0籔z2޺lmܹ%ΐ.'4HRّN:r4OU2eՑ/[Tn/%hh>Yļ\Β܏9`pk$(ݷ[?[o⏧K\2k ޲[aT]5u"q4?&.wkM&%|،,vanZ5W^]uz[ljmi7Huǃ,^JwS!`si ^MzKб(Ji5 By C4Q+9X<|czz)]z>u?G EvҶޞ#_&L" z2eo"oˬsu9 |Xp9RZY׫5N靦7Iu^~1{Iub½D_rJ||/6I/_Z/~?0> EnH^*95)M6qd=ixCv$cDR.h>r+BzߢES>C:'8үSSR^K*$YuvN~IpE9_OdP9O9 (]gFNz> CNvJg)%YKOGՏA}>';rsSDoBՍmbeiL гA}A"}ѫj>K>w飘IՖޥwr&ՐݣW31z<=y@E#zt75H^/ re8'M1W47<;{S OHM+#)lcϐe<_ ;//e}yڋyZZ~;FSEնV1-j~ȲHF$96Yo^u 4/9p,[ DւjJ]t*zQqO> qozU%]&ng5yb')(әpY_P5h`]p ޮy"7f#lHy0,L( lB4p"etX;a94,t Ǐ96Kh0zR$_]VW`XRfr`-aVd3L42"Xs'6ӯw/DQ;2`T˪]Y.X.zb G}6H9ŦR- N$X5CaG2GOy ^}baXP\7DiA= '5["GJT]qlg>21|ά9kS&⣤̅⣳1~s^W|@ ?R|Ϻa_ݸ+>o5',)>+Woa{$Wbh+>%s*>,́1CF Mg**>zO~5ƚL(%4IA`ɸ’s5-riج>9M/Hh:n4hlb%Lpŋh,c )@veS÷Bf.mqs+>V->ͽ| ^~->8_ ,/*re9X1}fP~ Ҧu˾B-IY7Oaoŋv,* ٗA\4k9X[Yc|~fOEJ)]nW[QIs+>3ۭ܊ʭ܊{V|~jϿٳ8r#1h ґ?+2E3(#ł!G1z-Y/yA8t_eGB\?w!J??ˁNi(>TQj^_̟ۭ3zV|&}^nŧV|3SS|O_qF]~%(';U6D^|.*b $%\#LdIDu"%8a *!G:TC%TeSQ][EܳvI !d 3c 2(վKաST&)^F%OFlTnGvҡ]dF_W~ R'\op;=ˑz޾OOLDXOD]\bӛ=vr.V\:0|kHR{zK`{.sxƙֶW\8)(99OpxqiR!Ye3{; :;ofSgf_Khb) H{;pi>ƥqsLmtM1.ݠ9lVZť[*.͊tk_ĥIVq,fmkf->š2f<"KfҒq$i FZXxzt̩K,|nc G.їC0\Z쉴{~n.-.,lKQE}+G,%Yykv$m\:$.m_@_{%oLI:Hlح1:fq_{,"|PR|awa0 ~⚿B)7/y(vA8ֳ_c!ed!UƠKj/3Q M.oLDg2*-o!R MFS!%9zE=z867M 8BOM*+~K_AejsD)h z` '9FF>RWP3 U:(T١`bsR:>|N7(כْGn O\;vVxEEz=\-k+~PIjt ,„>w ]J~V,>JܥI &ͦ5oݼ/«ZߌnK4Pkߑ3Ov=j ڕ,8A"c*Ә8i h$DY5G'ǩ>8j4fꟜ2mewDTYXD~j70Lp>t75rk k =}i ְZ^}I 쾘(릊KLєW>>$PdS۲q(I#o tjg4=\g9.]~s+F~u6c}nߏPOh.[<3BV3PJg Ɩ%DlgT~Ýݲvس >ys]3LS"s?ڥ~ݫ6Bѕ9B.=Wɋ/ $1Μcܳ.wp2X1>VM7'v)ʋ ij#njP0}}˿nYDåDI0C&.\4}l.LUF#ED<4В$]jƂQ-AAHh4j68|A)lZV`ȎDy"QM3? $ 2}R&36IZMҶW%,]hg| OIħ>vn=lD:z=G|$Ė_|4IEBhJL%aFr|,E8.r:9S?`_\ǭHG+s2W],UHWB$2''κP,Z?[4 `ûi=c~2yub£YtF-um8MqGm|KÂ;ȃjg[!SHnATiHab٣R܂-|sA?xb)q'|sK&;6ו,ft GB{9/P< ,%U8YBGa6&,uY-Fp *Y-CPoA= ZnA~[)?MA?i6E#8h; qpIs ;2GT0 9VbZ t`o"/f[1g{sq%/ / =P?3a=nA|j ZnA~[)?MA?jp@a MjOph>u=GZpq_{.㓓 Wl{$A֥1і#9%iμ_}L~t1r[ˊ\"-O} :HnAtrOnAgt-0Iߥ#3YȬ줂aQsBB+eMq#ASKI±k)MZT~`ģ/:ȋZysS+g^`P^.9Mn0{nA,A}A:%8!\M32z:#$d}G(NHFss :<Ȃt˂N{3 :!蜼5MЁNA"Τ0DsNdk9"+JJ;'dC::$ }ↈ> vO-֍fPÈܘ KhF\lK4@LjV5s^~ ُ5)@(Ks3جȇu8$(Oۤ0" a)5@,OE$8 dK/\Xd8\RUXeSA,髏vahgG^xrm}; LbEW-Z_G-#]{.P7)R)Xy!ŦCq'p 3mLq R i`F׳taB%6؛@[?&_ޛ(1RHO,I&)v,bDA+RӪ>-gc) ںl@}IB O_ ӁwEħ-?x|KgW&&uouq3Ei,)goh5;mjf''g'{}_6M!"Tb'ԁ LjpMzvy|;h< 4Q'SGsɯjmx.&&rMEM~5yb!&,CrK^Mjt&D)M6y5{Oo؛_\v4m(&|.qxẃHb͈L.ҜM5hx L?u Iԙrvq/?1pr-0/qH093dvȮ`t9?:q8 ZƵv.d\:YkhlN@%·@ z3^sLj{<;,irHE(;6V+4O#u\K~$d|&=;S>Rَn/Mք9[vn*r-tt@K}99PRCXXį#]H Zs3e꫗>RFϥC7v۫tBm 1!rY'LPd'I[48p[ 8T4߃u/ V*tnb' :p1cM #p&t)MP r>pSh2vuL"ܲHIpPLЗ،bQ@ 4/ޚ/*g@kn"`BLԵǀׁ[pi'y+P[+A-F'±~6$;E?FU|byF-ľԏHEKNΜ沥|x#h;QpfAG-ï #K[Ё߷$c͗[| :cAclw>B6E4 6s֫(jul9Xe켪FүITϞxUqJx8TQĉ$*44:)덏ًGtnAtnA-/Cn1yGPJ^+ EQگja@5L^٭")嶟mO!&dE:qXږ׶@G&툦 BR>*7n-r :z :?ȱb21vE^@U bxXX"YT~AIȏI-mn.!;]б&v'<lA=A'q&قN8t̍ :كUEr :UAҟ#8[9Ei'zN[1=da;v@U :DmAGF 75o}$?-._j \ ptjj "Ƶ.T>>oҎcXFRrzPNMɃm" <{B )رTlǤ|dloqW= %'W=+*gVk@V}a_~_u˄wi2.ʸJ(TS\&x$xHd/4sMQX-U~K:d_†J,)FsV>`\oW1^b1KJi~C_̵~d90=aNz~ەBBp M 7qgOԮ %y3RlRIuJk6.uJ'5.8u6z 6QS&Jn2" :}H2x5ks8ha;Ѿc<&2i>-u͵x\rW51巯RO~%?~J9HPUn0yU,63M֡^ƷRjc(JhRލ3@CK Z05;'fk&`"DS${ҟt~W!TǡphD!B$C R Rѓ)D7Z%Դs9=|ˍԙ,by51*W(ы,GŪ*1MŏK< X6%HX$Aз(xk&_ݕL!ڐq=:%/g_IrگJKVqwjw͊QP`: 9UЦdHYTϐ)jqU^$aE%+AMmMD_:[jMtߢgZZ-jPc> I5 $/Y Kaz8OH nFHWlTKZ&64j n*AKQOQ+|Q3-ӳ{tE! !h祭5A d,*$h5HPk {~Jf xoFЅј'8U |RrY,yyW>v,P]q^ ߫NPJ:4sb9B~J/x/aNȴ%<[~\hkw:%eR'x%u//ӕLJ_9}DnV$'a_̶x:ьmc5ƈluXzs%0NJ+P&Qf0z(C'KfN.8*x:VebO¦i bQ뉑@̮Av7wƷQo'P,LF)|nY1Lҭ*ݚx-mC}D֗DD< deh'1wc}Pq":qa F- 0G"kPD̤]~FMJ~!J.F'5#pVtR8 [= 6 Pi]^nxw`s/sŘ.,N()̤'5LjΦ՟BY)MV8fZ,xyPuVӟM';VMYtoIjII@Qt!D L}A5^Ͼ2hqP~!k$}1㫕YRu؃rvҠ$,/Upy0' qMsr7&/oyЈvuBGc.GkzF[Ar&7d^ s;TZMޥ: o9Ƃ( dYIZՆ)t `xɐ8)!flZGN6Hjqma,ऄYY ACtIS`vόì;Mfm ;.$Qu rg`P5D3V%~9j ~,z>궟m.?^q+dxΦw @OgzrTegTZEݴqA7O! 5v80>++1M)w~4Cx`m"REW#^1:U0Q+pvXddhR 6#J D؝9/h{Z]1hm1y\qp6J ru3_AAJX}&CuRQXkJA~E4gcxSKhlP*|j ='ԉϊNii!Eǃct Pz׏)t-qR{ESXšv"X"AfH9eg쵡O}7C@͇h 9S)$X\ 2\o 6~宁g ͏Tvg{JSh]gCUΊxDd݊~vɉZl(q8 EKq.οBܼɠ9l*CY|$ _Jؙ CCyǛ_!Duw;Gt1}F/ܑx,S;[*[.mn)%hy쬟Z>>SE|_rz/cYcY?0ȊcF.+L /!;,#[6b$ vCɂO.̻g*YKV%+{Ɋdbb26<=2Ǻ&hXECݑ|xnIWInİ5NV'+֓i'+,({=31 ~'=)xHf-5+`d=XVO*j,4)_$a'">.kن;&F#r%sSze|'(NRt cEjdlsW<: ە#<$|smcS9MYa|^ql~ĕҋ4?P ~.bfG(<`g:.D^`{}Ɲ»>Զ q;O#2ˈ2,Qdi\;uuE|%#Ȇ9wזJ F˭D }ЗdzaoTWnZ:7aLSֺ k>lu7ʏmꢫ3խfS\h3SAj6{]nxRf4 Cfd0#]6>gԾ 1#Á O@|V{>ӽ7"C.y Ng" c+ ز)h ۊSCm*YAP#§o3Ȫ 7 ϓ1$u$5K 1-Z"=jʬ?# S,Y<&ٖSo8B-gB #!d{myY퍽^?/t啖`ܓAc_%n~ $} 쉕Emf?/ɳB$褊^څ=ˈYРA 4WN#)@+h0נ"UchP!4ȏ Wg@'74LC4X*4ذ ~ozC_&@F003\>By0rCܦiHqIHtej[-8sõڝ$l61/\UKal[ dƳpN r8G!D_Cε1~ AA3 q"P8g@ IA3,q&fECpb (>*$AsER<1◉)^ )'GCHJqC1 WZşa:j{S;8Rt"!>8D :! ;ؙp9;ɽ'G"G(lJkj5G [ cBN:w҅d'ɇḷ@${UZHP4Ei!6|[2}Z#}9}J!q} NXyr&=;O Tn`zг=z lܨK9nf g:lf[]z~62K|xÂ_X/ zi= go1}oK=JGı !NY;kۑ.`>+D? : .AAGfu}m_@GSO;7&bBjlFu\Ñ<(/&XD Mq2۸#_;wdRC5ߙy|j'D@gZDg3EJHj0CߤY]޻t3w`7G ~Wr2@30Xo4h2JϢ((}Y|k+R0)}j۬B5N]GP.W~1{(^֨Qze/  uT悾FM G T͸R̄m[>{hP?{ٍ˚0aLFM*u%+v~ͻء2J3ϧG :^wU`tjrf;lӦ>Mm}[X@u4Dش)jPNP( >P=އj+T:8r' /+ȱ3 .&v)IG+3@b$'dS jd fbmχdl 65 X}SNCpSzoWtƲ3 عJ=ɤiO 5O B[T!'փR, ф9'L?G|OpK#  O@t<,KO@O|HU#.<Rs?F\~~DhqJ9g:E<M7[}Nٕ've Z X{G/V'^%W/d_?3\Q%Nx96z=YZR;ZlEw< $Jx')o~ 6\;<\u\{z` i.t==xNn]PΜoqcK2XE|d㡾D/<Qמs9؉?-f. #僵fRm` -W0yc9{J?]Rq=~Ur,Jjj:. ')JA y(ټ gP%˳{$lZq-2>'F4 9D,7u:%ƐKM"5^h$E}/w|~y s"ݧ_onGb˿7\*|Q+xh.x"{jm3?pJvh{*Ǒ+ 巻R4q5)[NTyz[G0LDq>,~>~X,`|Kgoqeܒ9=|*?o Fc X̠D< b:r:D`TBF[DWpeQP+ 3ngt3lf bYFZjSGXrjA?JP@yǼA>szSu(} l .&QiGdԱޟEߝLmEr3ڊyBx{5E\0$cZD]-4>1}QKE?\ܱZ N B 6xx8U&HxΟrC;p"z 6~upPo-վ]Cm:\`4/@ͦoUO)]6UBiW2K+{}wZoX ]ŎDWxxT<2,"ө.~9@RԻL&hT SzT`Q:p%G 9^Yq҇Qz[E\c<рy8'XJ IlhA}| $:wOJ(.Y!0DBƟW-ZJrxP}Miֳ!vHO([ƢBqĢ H?xz8ę?\Xr&{My U6}`w&D !cBN~`d55գ[z4{It {/.qLDL9=&o9TeA:4|̴"$ LP# f$c"N瞍a W-SBJԼS|ٜN0}B⾐k[xtL~gW1N@iȟYZkM#ZX( m~ep6~`|Ϥ'E Vf^Mՙ}#BfGd\O`ّGD4$?%[4i'{Li~mK^O&kvD_V=#+|;nv?t@KdS!j=$#rEU3x_13w)*l71ml [yXX!#,mYǕ>¸=y)B=Κ2G`B^RgRR>&* >Xw*X`Ӥ"*2~S>lo EwP6W;sj p]2A-0"E#gUv`j`DyM/ukr4bLe'$F\[A9-"ɽ%[-vr"2eU>枼k\x20 ROA~N+:\X^|(Ϸ_\-;{-90`a5խ [SG]m ו3=8<Ϛ(\d5Nh4Rnm.OܡVJiFtߺonB)wL輦UDks%y`)]O~&K!^/~ .b02+A_K@>R{G7K uk&}_{kRhvdMxj^Gئ/ k_PyxYYܛՃjpFKNLp2OC1R -BV"GFY@T+ЙKmm7nVqNJK޺A[<. EEVGN2}M^1Pɤ͘!Imژ#DvA K^|8Gr 3$8 -Dn=GiXɶhP5.`)/!f|"rmF Zy m hlX{޴u/~閂Bq)5z}tK(GB|Exw1AU N@+#I Jn$={{DRm{ |I[({pLA^F|`]ܑ[ ,;O?:sbSWN0{\H$swaE%+bY '9K M+oscAw2 W +RKoKQ$genH&֧jhANH-2n9V(Ļ-11Gm"[a&ICZ懴yHiO.D {xyp)iEpW)_Jz/|TM}Mt/%C,(_-lm;,{JGԓ.MEa7@m:HĆ^6\Uz*Bk/GdrN}d"8SvwR8Ѯ(pB^f'\5&!~iVk4W9WkPb"z(eCupxu9Dd}>('/vv`t ooG$ %+9;m3YO,S'-8jPG`,@f|"c6SSM) @M^"B(1^хW&険 e*4RH5,[ےkܦ]p-{@&ԍs6醍>{nތ̬ϮAdz4"A'F^ cz>H=zFL^`r6>6vˆ>TmU]z'gRs^ͤ>=_ }o|`D cM >mB/|>0}oϏ  Izkb M 1v^l=}"il.DjOoN=QwAʐϧa`{_h蕸a^q%o?xF,h%r*϶tD_QuQݭu%t6.B7>H́768.+lvhJmVNtEyf&咼3WQ+P_jӳ39O]MQ(#O]F"T-;T%S;7M@eD)Â?Ǫk'ܳ~L Y$ԠQ3ƩBɖ̲}W+}B Q΀Xʱ[FѡD.N-S7^&haG-bܤ5WatYkDHX[3ЦVʗaR3-^nk7&ح/b{cۍ-ح@ۏT $ LMACw}4,wy]+iMs.HMu&h)uhYٵ=ҍĦ:9:/٣[̖Ӧ% ʦ#m+6 nz_*eN WZI^+bƒ_ע+حd8f_VS=!Cϓ;GbԄ;՞_y$301>UD\Kۓv= p ɬm9G|&&J5񌼛΋g躢|yozd8B(oKM9Ž-$Z&j'vi`$.v؀%wbLUdt潍L2FCu=ˍJg3GYG}mՒ8X+ Y1]Ədsh>-ǏJN2z7ٙU) ΘksM^C%NW :l2Of, 秢.GOgHn>_ՎL/8K=~x/8PǕ&P'rohs_]YiV^d㗭l^ Ӡ6feoIaeFx$9̔r\BO5z /1HszBN:ȩ,b\O5 ?W_jJ)M4,'M^(u$1!UHT:0}ȸP(#\TCRrnBJ4noW Aqcs:~@?bPh=IzѢdQHb>|hw|v_EsP w ?sT+5hT|F赨Z.8۵hQs~-F;Q( W֊bpx^& ( htbza2ߔ("η.++èp8JEGZF3n\;OS:H:k'w 7_ MjEc} 9RKh/JDlZ vRL"ED=Ү #˛c'".k'^sׅ,J]: YԷ/ M6PF3z}-oO2X8_ZsH4؟~&kP=i?CX`<ʕproQXlO6&Q= /m~ 1Db ,s; CMjzk23R: ߤE pE|(Y8EϷb @7CN'ٍ䰼x~$,/"?_.}vֽwc],D3"I^卑3{ِ` o7$Nˣ봨I,M<[X ?$;cy}!za3Rd)zYԳjs \h!#|*+-6!qƒ׶DblkOW/5_˻ʛcyÁ`y>{m?i6m=@kHTG[.du뒱jQ߯nɛNPZƞs,rjhVT5y]#6l]tkLg,!P QrdV3 !J9UD9~"; l gU:Nt:%PV8ɩ0P,Fĥ*zt$1pXY8OF55Td#bƼd_'Yѕ!=5]`Yd2.\DCv2W `t0CƂZY (vo/tPQӝ@uP>9|X4 1r}$VMTJ%`R2Gv V Ws-[Fy!Qz1rFEC Q$U4c$#Tt{aǩpv}n0q,y|3<7jot#.oT\5 uD-UvJT=ܹ%em2u֩!rr$ND%^'>H Xqz q *t]yԮ 6^eyDndGF3J12Cj%ƻ<^nJT{)&=O^{^Ră 8._ #l1hpG]$o^qR=LMj@(g-"0zF?ч"ĵ7ƯS>޽ %#Ym*̂nUFc[{1bQv!bU$mp%zY(P 1,ĢkLkXcҟXyA,de6b iX4CTx؈Ea|\ =J*)GE8vЈEm;m| §xo#I l4rc1>ɻRDL*δwSLDjU=`JcL|8>u<姽ͫmS}B~%(;JHS;&U +6|7g7sw-” >*̽S}4mk6dꤢ_``c$7F'W.ل0 B.%YHŴYeXqy5,?R.;\f9+/]2Msg'|_G * f$ĐF+c٤q/l׶4 o&8<&8az8!݁g'=nϦ۳iճ)/l~&O=D=۳]gY;r]' xü a?OB j{!0K0OP=0X(@UHD!F޴X9fBLX"^\foB*=e"fޞM޷l1E LlTl>ӳi=g߳m?ەLN< {DY#`$&N܃7 2Kb9#nWx$nJ#,k,Gd !EL^ͫ"0m&c(2LbJvFۥŒҙM\bwM|L<}HDZw=kJȆ3Aj;r1K+9gpn `'d E@q>)F6;HCd"?!q8a{OWf*H kv.k RGgGH6cap~{_޺ۇ/j))TOr\(` NSr1Ԭ޺L3] s=ѵ!jܵXEom@*\'ׯzCُ!JnH׎$vxN(~-`:GE~`8`(MA'P n8M9ODl(<;Sh٩s6kO{XѢQg ;}or{%sy^ߊLdm!MBBsGvk&YC_͢t%fF0ֹب!QiCƍ ːlD))oFJeyS R*Gîz_ũ@VPZFu&C7zfIO[."1i8H{koNvhFLs ;ĽvOpETw/SSTނ:dÞbƾ,Ss̞~0#{¡c41P.pƌ{X}﹌YBhN%WMz:MnW+˚>07l:r{6vq (܁xnf޳ύEљѮ+8*VY;E_SjJQ_PrzWֿ AI{ ]IuȽa&`t EH5z-7sfU~yu]L5s>;o?;Z*7խf)i5 )PdBN#+!K@/XF[K$7MA;c''NR](Lؔ^IRdP8-/)EJ0)$g1H ݧxhAYlSk½7)HXZTP무NCST 89j=Ϊ?sq=H ϠgzZܰQg;ZCM7rIETDW #FbI+\Rk6%-kt:Z1S̆gv˲rJ)a^헌Qid4WHQqk5Q8hOQ^"AeK^ߌ_Snh(pT zJ`"BϤcЏRt:d4siF $/3M܌$4hЃl=)@󶐒QKDz+s䣖_dtf@UkM2V"a4yٶ)ΉM̚ϻ/"K'%38T#n)AL#\hAes ځlj?Hը|U'iQ`/F9v(oi 6j%D吿m,֯{h+`pX.DZ JKtDӅO"lW`#/rM"3?J7 [gcLGt|ӠbS?*5=,lQքSCrF!VΈHBm,f߈x!AZ<8X0hf`еb܂q F|81{KW8'LXI@ 5[ڃIR3xЗ}WBh^ni\'A7DڷUH]w@?h_0NwxgzW[xQ2/"كWz'ʸw{ˤwz'v"`ލM?lw4/x@fϤwmb] Vлa2KF+[wD"ξ]dSGElPwǬ{svo`U?:w4~Y^q0d01-lGeeK\+amrgIj劉z,-py7/,w5ӽ|MNCO}]4qY0rP7dQ)HHc<@_m덭(ȕ>>5ߖ؛F[OoA<= .vQuki|̞;Xhø=/A>\>\*bPqCw%>fZ'Q>I؟Eß'ѩ+XZ.HeԾnS BtD񫓚 X[-,d=Nnpx'k=?>4R7+AٸC|p6V;'(kc,(cU_&X;od7Jِbk YWfd%dz[s٩ƢYqQX2N&L߃֌2mkcxԥQKQkʵv#զ4t^n0]1c1 ۍ6Bߤw7ƻXca Xϰ06v* ö,`¾S7 ޗ֟1Pc Ž$zetꛘn`a 2+ #RQX +r*)wΜq9 в _o1 ~k0 ^p[6$5\HoS֙"^4zH(V wNζwŎdΣ ݒm06R)n5KgJɓw8J(QR]Z dqAye2x/LQS֝EپOZnFq;*:`y΢3q΂Ґ8Xo~b]jpuL#}Ǵߥ6MԄO.L=m'.w]t酗&)6zuh%CE \K g Fi̻ FJ &#'B= rIx附ws= ǝ6qwExMu?~⾤8ø YԻ EjiN#S-9[ppDOy54#bIo^,Eɡ[#D?al7 Pg+{#ƴP8i,FYj 1 -&%+SR;_˂? %M;?@O.DtmyQM@Oh^>r0Mz6\ɦJ}$=:01bwXhRq^$5֥p>bndOǴh]z>G|wӢ󦊤sby,Ѷ8S3ZZޒ6sΜֿ0fi_Ɛhhϕm0GsX 7 67" ߘ[Dٓo0C7ľDo&xɡc$V`&ow&\. fADRAj;zbd;X+'E?Ň?ԑYڰQsh:8--bFIܘzP NUA3,M 8%v''rJl  ȸqzf0sSXu F,P,ƋXq R(u$R)Ǻф 1_L+<#zĈ'1`ݔC\nAaC yCam+ʰLR֌:z(J^nʛbjgK`k J T6/ʽs:GlI ~r.Er]G%)<;iW]( uQhNBr*AWiKdJNHLN3K/RASw3Hyꘆ䗈B}(%sfJ}mBuD9F!^֑ToL$~5$Hk~1Uzu2z2kh/#6ȶ('5zYL>5>> YiA!Sz6?8yar Eל6Fw/D|?Na yf`$[;I+,b:UOL,Jg#>RFTRX%z."j0bLnH%EkW1 8RBre`.xS*b\S`<h·D(S{HwTޛɲ#a2ϛhHI#Qj)۔fLKc}~%=@n>}A.dDXi+UV<ف;B %\Æ=+{7^N]ֺ:&|4uyUsgr[tM, 9?|ˡ[~H:jh=/~.d2[."ƬG^6{mK1U5?C'~ thy]&~B %Y]4x ;nTȏ94?2-|D/7Rvy(ضNh=lvb;l)_)vW.CA1xQuNZ: vҏ Qg~9XˀLyT X#v1* s*FapJ1P3|n jN8)QGsjD>"^( siYݴtŽP+:"q+ XDVs;q:I&V'DXA7`G߈.s+tinT͡?y?~?GF4NpYvM:lK: 1u0EVSgتcmuc0FЭB3bu䊸X 0ڃ2Pg>):m5&BmV|Z,舯K[:~D$ BIuzu8ҴpRFjS5#G{-j\q?\i֫͢Cy/%NGzGELL:-=;cCC񤎒uʮs•\wgeDY:֔Jcģ' )ʊ3W0{B]udiGMn!o{[1Un_^kop,xؒƩDO!pm-_ڨS$S|F 鄙R߮q FQk%1'TnZ IRl3'|qM՛tUǪ} QvE~σ|loR"l3XғUקׇchfpDZ'6vVnA:uRw-sJһk2\mT^XaM#GX2oGl2@"-K(y$i ? 64h@HnL,IRL QtFutbEbIA| a|"[P=>ͨ&4,Jǂ dbF2PT-OI5PMgq!T\L^cT/)cIRBϞw{-`5vS*b OT΁pwVva[2ydHuGmp4R屏C,ʋAQveQ}}TrCVtg*`!ç0tr$>gY$H99(P5:~!{LXC;ǞnCQ3>UYH3J'9{&m1=W9`^ȐW+-bSL9/]Q68q5۸*q[RD17$4JM.rT &yK3@oIȽ6 pm[});4L)G]45dys_SVۛiA; 2G=Sv7Asvƾ"\]A9-;4@e9h?{P|q1 }!=g61Z=|a*ҾSֻ߀ WY~GUfrH~{'&\b@Fa2iChK:ҋ.cӐ¼<qWEME.C"zNĦ~WPOAӊ@1r@2HQX =g·nM{޲+0>srx g<lNl趐Ot[8 _MGc((^vj%pt1EKTi_?&ƎF%Jnj)F{+>o>ğI.D\N`ظpC)y+zM^0ZΜ~R>D(5]TD6*>#nң}>[m@rބ7`lvvPgDm@ߙBefK>>䰇31lƃD@oo b#ЄcЀhBfL88 ȜKCLp V?ndMPl7N3YQ#)uF@bWo->ĉw ~̒{ՌKKs 8f1Q;S^#wv-\JbaYMZ;u`X$Z6Vk7J,V R2hu,vm6[5>X$d,EqHx vGC^;_QA9ޢ8w,bQf\,VNh{ RĨp"p@bL%Ƥy;e 5~ڬ]a'cD&ِmڤ\{1Mex´ `Ib[) 7!Ι3tК lo~ 9k2uCEp|Lgذ5Ĉ{55bSYa@["߈7t£)VG#N=G\kXm7G\9T;Σݓ̈},s lTKfإ^$@73j{ZCSG+ l;j>Z|Ĕ:ar6)͓cP6TVGQ!#Σ=_d1j2cTE6iD̩$6ٚ8op,r;@W;̠]qMˀKqv\$b!h$H3AR 6P C t/:)<['Fefu3r'ED6o KB xx.[x x~P* e؉`s7N*hb(}Q?7 \a9{Ș,PI8ִYV]El2~nge`bӱdG(hje[S^?-F$θH"&qBҾ}շ$/.$Վv{t(e$1%"H~L$[;]<.IjTQltjK |;ة(jV; wqRLIrPC|2S!9M|:Fr]$%S.+Y}q$yO!İ#LymyF2yJ,~ ZI?k8'+ɔ[ƒ$<[5sh<Oznqc/˂\{xl׸qtBjAQ.8AYb)[~Rrg9^eF.9wgR#ܘ!CjE&^=}V!>}05]{lᾋ[BJ.펍]u-876i`jTkl$V&E5 }ڹA0XMɯ'-NJխz{;S̩z7_\R|'Qԩ\j㖯(Y2:lm6kJCS&tϭ\ ~K0O $cC66_`͋?~fq cn[Eo>D _=jEjy#V嘤`EYL9+_zp]Rpp2x?> ojb&Tb9OR!DDxÝB;y5ur9rG;o^9)̕Rڄ2y%#"rEshH+i˫+`,a,"}Ưװ5E0 )"(hXiVB66B-V`Ifպ dBp*Ȯb:M 6J7~y. {l*N:)Sc}Ȇq;.]Q N "&BCvG0u q H]D3tU!bs-02VY+Mb~X싮Ƭ ++e0̦ueiQ"HUTu3,2 Li۞&& =9,ϒ;$<,ژ 'H0v@Ҝ0fIʛ?I UirϿyPQIR,3o$+:$I(fI@C(HJX!s$b$"qdW).*&I;'b<+2x}xfrG$&S,0Ѓ۬`09p-&V b L`6 ;Dzn1Z Q+YS$DUI ?ge|v[]rEaUL>:GQXZgLd26rphRƁ%|b-fdb-fbfH-fdb[[YGQw[ &'$^(~teű ر/t h,$UڀcD ,z9,+HxM(h Jɨ/ ` =WzTMx/Ga=W IR}e$]8Ʉ_ #qaa$3*anuSmޑh;@O2p"1>j&Ou< uMʮB"=k5c%f}/Y_% T]Swvd8j[_kԃ6û9B(cRy0f7CtOەvZ`Ƃ#h^ tf*j&}T'3$< uYaޠsڈ'e[ZEc@X<ʕ}FAc#L,Qp-"-SH"I^_ )!͒xoLxd1n-@r pUz$+%w'hWI ^nѷ0V&)LSRZ# YU1`@!:ḍnkJ:S'JyojI 9=&gv&7Qb}ojo,Ukޢb!:&uͩM^%9j]Wl$)N:n%i)5m-ˬ݄b5:~4#wnqc(4&>i[lٌS>Ӝ#7:o-Sd ZlL6s6A5 w8CM dfۼVlL伕9 */-9jb>J8NP{Ҷz@{VtǮeκWJy*5io9)j6oyδ _*5⧨ټ9v/}6޾Iju?JJMOKLR7jb Nh h,#QvughXQJ(B2'Ý, CًʭiIr o$BU5 k=xӼCr`'&^_ #I-ޗ n AŚ^ -%0?a46oy=l~ 9דɆ>Y 34< 9xf=YO>Ӫ/B7yPu$pa! dNs!; yqun:"se~YЪʿ0|N$20v}?ۧD@iKOh{"leHsO "R‚P(}jÑMsTಭGd g8 :dg N}Q(Tq`7LA3yQed$j%~ $eJ&@ux޲,]"Btʕ^JI1]rH4a|+|,܌')5Q(IRYS}ݠ:z>6{ooeb^$;h㩙9_b["Uʉ ?O䔞F)fi&L~9XaaQfÒS Ad+Ƃ /h|;lNJ η=Hgd;,!9)0~q{RŽM){AH"Y$K&"#J=+uŋ P5+O^hpy2>*|n1 3)RT6b_RE̦+I}. ވ)ҽ@b%[r?"2KtFiɖq?;:!e]u2ϟEt gGS0 ϶mǸ+D0?%fG0SrjJ9-qiFI`{@jQLl"|"ltM 6r+D,pme'ʩeyio<4{١b~ѥ=UU3tf 9]Wu`[jZ4| dHme3NRJu]1ߦDAn!ȡD_rf^9l Z;k{銹O2&08m [x|_3 /4 =j@ۼ74 z\@"-BMDxalL}(gqS PpxշMR16qb~Uj2 G} J ;@,|uf!e#<NZ +`fáWR`dxQp.!K? l7GOo>7Qn~F&BD'O([cP«D5S#[b3-FRFՑ]; E̅ oB~h|F"eX,Zkn TfMӚSAVGfR>!xbm oq%, a/LcJ1S WT7bsubD )nWDK3cD<=HQA9 R2ߌflͽ"u?&'BS1˽7ƕ==" ݍ}ڄѾS[2CƌkU N1EV4 ֹ"Cmdk9sF1ḇ4=uZ0o(BǦF>s;DfTMM?sIa!K\H lΉVwlf@@B5S%!\PE.?h5Gd7qG#Z<M* bZvt(>G}z#{4΍96h ;e=zv]"Yz xg{E<#pY:c/- }Mҕm/G3E__mGus &o{=* 3֛!-H=|P0q\M(Q\l|\s蟼|A<ܨ7T'G5p) SZ(RwXZ(3$c{E yR|tFO`;v:ے|H"Y$3m|:d;Fx;t# ''Bn땃{:7mP,C#6iND́L]^;[,/\"\LXF9OQŔv0bM%tX"Y$ʃVr^xBҾ&rLNHpeYq(d4QllXXӹpX$QaSlV;$ԐA$ѐR$mL0a55a0!kw>]{oR;$V^,V11ADŽfb,2k[mԮէUzXK rVQŦ>5/v i<6ʟzV=UϪgճb1%DSiPQK,Qފa`v@+9e6]\TF9Hy֟5rP!Cś+f/XeuhIV=UϪgճY|L8L32!tK1[񤯊Qފ_s`Q%^puy]S^WEx}F|jTxƪMy%~:F=MyGW|TxGTxKH:#/ނo&$:O؉:ʺiV8욜nm2kq~跨tw횢R Ҿv )`;t–IAXp2"Ua&aHx< @R^ /oz;s4{LA(exb5Ѥ\9up}yLH$uP^k|нJx{w—q*BS @W)ȭcem"uT ;)s/pR޴]?{Fgwh ʶj~[`zxP\ ~LI_ػ֜j'K/}0_\;~\-4bq}2G޲ N/7uA>DQd &z :s7"k/7sc-8+C_πW蛼˳٫74o?$a7KwA\+/u s&7OMi_M篼Q+` O|Ebib;FFU%J %9 Vtvu>l=Lހ H ϚǮ?hI< O(b/G$5ԭ5=Դ/=m&6z<)v$wGߩd UJ蘑↹ @QܝL B>w#^~a{6ƕxz[EBT>sP]]*LTC7t&֋nɬf/]n>ӷVkhlZFD\c|8ן}._~ky|4.54$>8X|BEZTg^+g9=E-l=‰/`)QgdΆƆBP/t<8e'~䛱#y98C&N,'lhcj+ 2>b==}ɒɹv6z>&8zRo#rg|tSA(ѻ< 99Ӯ-S|Ӑ g~(TG7vek{Z*NW8A P=a_ڑ ڟRkq*ȥ7e1l9CQsޔgNg [護UqK0c=-:[p^?%yԭ"rn,UոWXv-MzݍT~'ְ`kלF&ZDܼ\X&1.qƥMxVA v>zsdEa[v IYB\OyOf-~WwsTAZ<'BV!YWw1$tFY"TQCMOt+~Ke kՊl K51y0646Qc"hgXWQg(۪ѥzVs6$I6nEƾ~Qg߂ESX<޳"Uc/Nh=ŕ-~E&G7TVxTdjElfdEO&SR.+G"DC~>Ez;mf7t I􅼄%?2E<\P96S/eCh.V6Hs*Wu drutϾ1xLR9M0YEB)y|'j"Yfj?"cO-S:*%P1 {6 ~7$%d<[^gݨM.@\>idh@ Zalw  ECh>&ʊ56~ȼϜӞ{;Tb-o/:S աN9#w4j4aer26&&>Pt5c}^8qhJЮԕaC~ix/3P *:+ƎЦZ#C@nJlfN =BqcZ WQ6|A$>+J`Sw!A ;BKH{|/ۈaxHĥ#LJj;lksc`ýC~HSU#ƀU5rk< Xz >"₉[ bxl-xT8ueKi <eybC<\fO"@{Z%r8StalnF$GM@Wj%8Q^7+;(SXfYg{ʌaų."q#oW&.:<1qxX{u~ECCra,+3.bР6p<fԨ? l{=[BژnПm)Q[3gfI_j8pjgTj?~| M=N١Ų>v`O"%, Cx1a"sIŹA04΂Y\'z ,f~%WxTftA3"]-CRgʀB %Wu5|< ꬉu`%O dgq%jnc/CaR#{¿$Qh~"+uSA0 kfIrZ7yp")dn[9 +*_ꭨ`96`i5z`S!G:PggX!E;1rv;e`+ 8P"<gzL)M=n/ȎY%QZ4ߴiol0";b?k(Wg4]ZG,ŮCeξ3ǁ{ :rYr-*y,fIǓA4KG/H%po39$N,l cTHgK `|5]F(SH93M V#17j"غ½DbHy{M hG!^ )XA q@9K"qs?;ta?\3(q#4E{b8AїqW`܁I'5c;8r[$ž'`s! n'YOx Q?No#G΁\5r:zE |0r}!wd8 A\B^7Byc ʜ.|Ro( 8-; '.tY~v?*!۰ *g Lu/40Jcr/zVPB) KN$PLP~!N3GHlQ]i%|>@??Y: ЀP b\d:;Ev#I $F́)6/~'OiN]c,zFXOO;=A:X)nB bu0]Zb|X\uY1qC,p46Qx60T13-CyODLLsX]Z%]lC0.AwXPҵ'ڠfPۅ JN#MLOuQM +`dR E51žC$>esaHJl(562%5goJ\ >D@kke9.L6e>ٞ`HA HLMז4)5Wӹߩ,dRu-eNGϝQxĄ J#~D@\tdW,1 X&| $66cef7 l'#&*G%6؝l4Νya l2΃I6^EkcuD$6Y'q+Ɣ1NFt:8 C"EJ Br.$' 45OdXgQVHMJ/1z_9@\yxy&~MԤV#BaԚpP{sdzRp%, %: n%vY&(`V"nL@?)=$t\9iQ9v7KN@4Iyk=n[e zD7x ~2$=<~?tE}sRa*Ƃ ɬfd'/d5I5XϢ\ Q&'S(bİ?r0ߺr7ٟ%Q G!fPvD ZQ x]]( 9ɽ+'VPw]d*>4yQƂl"2 fעx4/C^ hH5KR .X ҆!*Pq"hœ5YR͹b2v=~_-|bX8HEJbO騆d9J-5҂4N)S)}GbVH6cFh_s*KCh%+<_ %Ve*4u7 UyNUbUFjvVkhl6ӾQ0jbƋ\v+1Wh)nWHr'ā*[8F}!2% NTC!+{Q%SrEZǻ.@ĭ|e EB3e1m[[Qm"XmhR{B`匪U"w +"@"IO 9,˃ymٝ'DG>h5651K 3ڏvI-M_)+,S4@DEijaX$nאBN!8"&aOvo(`R"kQ k=E!2S&Ga]+g:b28\8C%Y*R9fyfR@kVptE9T@Ì$0k@U<ۑSjVp4ViNN1X4 |Dx( +A~$p*hH^gROfћbNenWDR9!y;\`Ɵw%qЮwaX;`j:!C2dK:EP!⠲D&!}l.Ozӧ<{}RX;06|*N4hO:a&2p(w;+fsǻݯ`7CfZkɩI ͔8µST&Mes^zl,v>Є4tQ3*Tυ*_zH"=q,ZG[ j!|1] Z/@ 4!]8 "I6zrjY~=b Rևkx){ =@zkW ̱s♢Lq9EYw2ۊQU ndGQ㹫zXw S.1 uppC#;v$VblWmޞ|_X*GԬY%8*3M,8|B :IRn~ 3XT'21o}2܀G2W+aL ‚jWS]˜8tM?_\ |J>Ss/(!SQ aiP.@Sht L:uR<`꜊"LeEwLLW,a{LVw9U;!Nkm%V]"~ qȏPNgء`O|B'uzz}<e,I9{H" 'CR=Z֙@QƐ`yf`2=9=Ӟ#wKMz1X AT$X͡L^ S h'nw=@10QGq.J:fw?[ƭEr:M)`'Aȩߤ L*@\xH.`#O2Q5z]M$PV#;,'5/'lj5@:2З%QuLmƧz\&dfcC&>n3(ϩ2fg}uus7HGт?s+<zIsc.H G*㈟k#_+_{r X  hC*/O{OͰ8\fQbHiךheAM) [[\N= \1f?An,LH@+ԏF,}m n{`W.|ةσ&~U>c)7hM"Mq칇 UmލQ-Y zFvw{[5^t?qH:N|mQ=+;tYcv唇Ynhf83;|D3V'yH?@jq'MfbRl7؆0 dzjÙYhijjq܁/ٞtxRs ɆNJw/jct󨬐%C=;)VO}V`%#sHEPtq\<2RWXg[)(4o }  F é2>4e_2OX}&ݫ]څ~ '/?*LJzV٧(K(53}w.1jُ7 mʩ~]uC"G3-[3SJhD4IPi|]bm9'KXص7!ℯ΃Ͳ= j;1=2Q*oJ\PS~OssP̮Y(Y̯E"_.L'dDRꍛJ@z:)qkD5}򃕷,fyy!bT{K} zy=|ud1ϫ|rkc ˅qg.GnP2k9QQ9.`ipKZm@51Q4dF̉1~ZBd.X`=۰_0YƠZwGpnLKq-P"8.7"l,Dj>JU2t &5oV #* 84>Qku{(mc"=7L ?~O9,PEd|}vARV"{cF me{ĩy=$8 )ϔr'ѭ&cTʳ be7G\2feD. ,F-KZ*a=qOi{w>Z`zo $JBQ*8ڎ>M_Ò@] 3)RPIJŲ,ߜ:F}14sm`Ƃ$9firGE5MACs#tNSsr|4hFܽ4Ix%!p:l.QZ^Bv3XqT2"]sZ-kߗhߠb ]H4899E& ɺ}k0'KZ_sc.]cY1'C0#`i%8! /zP4E*xDmLJCrтC2~<=6HNR,ԙ6̕FȩJ|iq 'e؀E#kv3lƤH_ϨZYD_VU75"ոt}bѾfKOH܍ڻ>x W;N?yV&7} h2HRC*I!4v`OC@) ډT_O6?_/qol B䀄~suruqup3u/X`͝+pod6Z ,X`73q0Gj5UF5|~_|_XwyW QzDp^9eRy陲bvFt }>dT ]'lVL+),2wT#^XűQi2#iobA\\\YqTݥ=$7S {Ww2|})IOxȨb/[2r G=oSo~-< >'lٓlua]- \^ @~yq'z MK(g^ ҢݪqV ][)/{+P.@9c]YaC~rA3YϜx#h7njE'K:!1p.\  g *WT@{@~ZT\۰@Ў -̣&a0) K>;i.EMa4y!X)?Uk}_>wcg^ ,X`׹Ó0;RFQ~ܡH!\. ; ̷@:k $: {O{)fS^#7su;NPR#pr$&o ӏĖrX (U`1PJfxt%}\n`:J LUEj*@Jܝ3.^dA?vkSnFrW(f3b{w_Q/g޻Qש :;5h:J}2[(%{ 7׋HTRaQ6{6cN80a#<0<}bQq0.}bod۾H1ql/78qQJ$N6ʡZ:;gOgD 3 R$S2lC)ˍ2A,)zppMoQ]kf]Hke wWP8cju=!ZTF/l2jԹj.D Jd]J EM08@asqAneo_ϾwZr X|Ӑ5] Ct1!V#U(9Rnl6A^ZŤùA* QOZlK/$p|EujKi,o?ⳛ5BU79NweG=: `bHse3Ŧ32y&m8-EW@A Rs#wY^Vanח /ݹD4{[c3ggUM<ԝ7f4h7yM xcYZß\2`*v'l B]MJx5JKWtHu4 x ɞn.MI(%6 vloԸ4#U+ԑ]S6.[HDdXY@oؙCh;eZEDh Pkͥڼ(tr6JVdlMm`Kx斫2[u@-e;-Z-f0 F]Xgo5jIWl^{ǣZeZ/3r./VJP_:$sVom3xkWܝj3F,XCL~Nn{ bfV+t5_&wŒ>}\U@|eYժxuA›72C[bH}$ %]V/*+Tp/IxTC!嬝OHn~pk2/[ȩ\+x6)v$N&DEl#kpO\îD67Ry#U!2Sm$ F&%l7-lo|P]@{c\)o9q?qY`8{{߻'Kޫme; A_nod!REų>p%rGZAs̃14[c.%?iD5KP$.'c J1[maQ"w/Ըsd d6#c`flٓn)};q^aHa/[`p{'ʙVPݩdAu-(]JB%YޟGڍ{efcB{m,7г}#Uh$tK gal9rhԝ9]*zh.I+Gx꺮Nt?Z L%!돪i։b8ug/d dz}M}?|v?*U$~\=?OY5u:rC,)oNthUj8.j]o#fq+8!zyOexF_ը%}a!߱y9% m(`@OWQfp'ԉ$yOY>"#Ru40‹]=ySIo}ߟG|!/Ea,e%'V~`:85A6[n5ɛ>`Im~ºxKJ^>z U魳@ 8DL6+N.[YŅɗhJ?#|EljQY> L%'׸tJ$b~Hx0u[SbDydQn5U*} [ǡi{j,}F^_U@ÉblaKyyy]rL>PDuC$%TK^&Cb%z#LS$@Ki!هeab%Z~?wt ,x;0N?$1MS%X " ʑJz`WPu;/)V$H{,=(^8+c`OWRyobfʘm&3W~i\](#ׄYcǟG*Y-,0@r͖.$\A9OӸ s4iLN OV;lm܁+h]xksԼ٥/Tк+=EVоOcA %%B{df&rW7҅U0r/m5z+Ä Vg}2Hi#pa|\X{ _AyPf;kDnfWŬjcy%x1>/|]exine-lib-1.2/misc/fonts/serif-16.xinefont.gz0000644000175000017500000003215314647725152016503 0ustar meme},Q7݃н Ȓq$@dH%PI&; Ή9s`s9ovs<7a[opwO}.޽n眺ȱi<̹T_] 5ɫOW}w݇QmvǶ=SKaޕTLɣ/0/N\朦T2%I|ɮ~Rߗ7O\wvWt ?uR19\QTO|=Is=sm PߚgEFYB*y$דR8J }|L|oȧr@)|mhȕF^ՏɄ%F|ʊx/u*O ~"_(B/S#-7N@9Y$b+eGwv:vT"D*+MNSW\{OE3/mEppk)ޔoD0WיTa|]#6HTV]P{w3}~dd½dP9:F]R p(x✾c/7z3u?@r !eH\.\86GA5q_S@;xOBzԟD,,ZY)\ 18fH 8JkgETzDM _r3!PEᯟW*T7͜>{':Ve E!2) EQ]DĜ i 9V* ydr`*r )rin*n^)WC\F9}nzJ6iGܮ!*3iHG6 钄=\Ιz(W{W8h|fCN`KI)G>˥wR0hQ!zHKB̋t S4*="iFQ/*|2U/UUo O2> KSJV(O,j*;XSn "~щĻ/'9^wߚvUj2~X!|O ^DT`x 1&^KHе2,XJ]t~[DWL5IZa>~ %ݤ+o*='~<,7 lcp+x!)v в2P3#{%;2EP;qK;v⻧eY|mJsn2ppЁ ;WGƅjSws'/QtR|~d!2h)ThQUbjN>JDM&xxSy/@n2%QDaG(BaeM+X7=Ċՙ.rE_xu^B7kF~Eq5] m T:E!|s/\d=eu@-%#q>v*}9>XK{0ڳ:ow1lf^NH{q޾> =K4a-Q |(F:SJӈ,铺Bw镹-ȹg%![ߪbݑ^/$^/A(n: v`U7ljM1o)S5C0W>Dr^y  'J2_!㗓h1Ss~'&09zfî 2a5M-<6.Ey8 Z_۾ `VK$`h΢_v&IF%}yՠ6-E|g8ǓX3+bj`VgRӊql&e@4G8A[P)1P=LMFA@ni'QLG+u%օ0HgsQxOngQjvOͻ'2+p$Xp* eƑR,ΚR0e,Z|Dkj_AW%+^¦8}GYL3?MNYaA3n<ؤ ;Fõ>s8>Rh=[Y_hSTۧ@SUt.T4<ۂǑ[~B;[H|C{8Cih!;TZӣB [qپ!hG%P^!PeIGF8ZSa=wٝq3LJtB:Qd<̛t/N:2=ًe(!gߥ`'L#84e>PQXoU=bc֏o9rCB@'<ȩR jD_qOjN@oeICZJF/މjxEg8d΂6"zqb•!aI`u-L\#>z*;yɌYa֦3+8C D4`Z2dB .w24ۚ & ,k軜WN3lM~C+ӵ3]=[/3ϻGGP=P3iЦ"wtE z@]%Pm4< 0p42/8gN:A0 Oxx:&H 2fNƸLc_Ԭe[J,X7m՘aAN.A;dV~'ѩ 7x^5"}VW28!!7*3MaRt=!r(^4fzPk1mwogVޫ(!K k| 6_S?XYx!3B~I`ݒP~6Du)@S¹4g?B pe8Sa<]`SgH!:Y[j;VF+VkDa:[ /Pdsn[&N<$;1}hQ FDFHQ4o//DpğkXꙍ"@2\|"x&)5Z:OL㱨S=5u^E2Bsq $LD"Y?5晘.TT}њ LDM]"YJ2LCp$`o)a|9n5ORxsU/%Me#8Z@sX#u籾B;;* ]DRxmNqF彅[f 8+ l_)423&-41`n%Yr'f: ˱HY  k0ڿ.-!dHTuo~P$} B<%njtD~ 2M–бHTp"%f#3:BVޠ`7GFWu?ٯ9cl_Iθd\XiY&jŢəYBlV{V'b!fjFwx8J.&X^-.T\GAw*GV.(Uc@Hϐ1ҶMgUw!c$۳j寯zy%0;OG>"TgqCoK5$95P;'LG߸S~Sk ?^K!bi^a,#klhIX|e?)D֓"( T^^'x R 6a/!y_3"׈zZo:k\iO`B a]S2,%"B[g_[Y]D*C/^=~k0RWph//|YJvB jϔ+` d֡|Rd (PmKRYWro7Wb)ۍ?9 (poJSbKڸi{og۹U o H70w Y;5Q'Xea߮v .?*/">}q;A;ӲvQ pQP9[;sFo o?yF2'Y! A: d[ͨ⬧e$9&a]:m6ѡ?ݗcs߱*>fJ$4`uq_4KDzԀV)('km@bsX\c(M"\PNSIH<5UZÊYd{eɏoP E#wr!yVBCU*&zz4ľmucpC\ucjm!l[!輵-b?nkxNCzY zTiLlYBǮOMZV M=65Kne#K2Iq9 (^z:,z-ӛZdzZĺd-twtA,(fbl^2=t'UC"3zZRKFX<\NM ;NlgQIX y6U^ACKRx|̘4kq/,èTB j!kΫ^e}U(Gf%JǣVcicjzym9:8*^:AϪ s?fo& G(e.<0yaWO C>s"u5BkB{`.GhB:n2ޛojt]..s`43wQ1 s; N7&8xd=K ~- b}}-݆J%0_spm3)y$k=Iz=K'V~eZdA(!?8v TZ ʊuJ%fz86Rϛ%>2]-=\:WtEFJz]}ӽ\Uf0 =*oL"Q5:o$e *=,OOb=Mw4&-;ZWZ8ٳmbP091 :UGuL¸ =']df«QYuj Gxo(e?:Rxc@i.4lld Nixз NN^7%x۸Hp9veFLO 2V#$ϾqG"&yᳲnUkVlո#e$Ƒ*mel$p=}9禯7~r p:Pل] 9q$jb6jyjɂڧƒJ/|Ի{;2Mr;V%v%*y0,1.ٔIq;p{_3-ogg.&ٕ3ﶠtScp"}`Yg~gqޏx*5 aIai6 7stә* =3$2?vXfii #m3nlnE_[Ȧ%Q6|iջz"!Fv_O2zq7H ϥ5S;Kz" w]l6Ζj.q@  ރ")vz6^uO39an7٤6hV3O~hõkV|naT''$JCūVVrCk/n0 &*DzDmGH>7lK NuUjAiKJ377a89m0dLDQ2vHiOp'`s j]B9>,\%:,XN@n{ GyJ:] E}_:4nٯ/FTEnzzxu?Z󹾉sYDCPu3%Ǐ?W݈]g;sZu LJ=e޿t>*wO=bڻG uG!.ې{`E?rI,?6hO%GEf+{J{ NG~bi- "叮9h].dM[bkx7Q==Q zuY]4Dm Y]4$iL!n zӞي=޴߶XZr۰TQzu,QZ  -|~ztoOe.0lyk-DMI9L%AEzAN)?(A*Ђ x]hh e3' oT!$+`fyTՂ)co xm]I@zxH'*E2X94?T~('A GiAPTꄭ-EYu` ݸ BC9f7.豓ҐOlb:2j_HYKײhAꆑ|hS $Jd)Xq3щ\GC4)ly++ݞwʟ )S%TdY~/t.$$!"p[ B[T(]/*g=ekX xine-lib-1.2/misc/fonts/serif-20.xinefont.gz0000644000175000017500000004265014647725152016501 0ustar meme}LvިJ5f^L1ۉ'Of8LuuJ}o췫g涤VKS|w)?=jk?2ub[]_[_wI8.1{ӓ=yqZ:T:ʦ>;dxccϱt e`J[mK}r4<)wS"1?H?b/irWi^P߳}V' :^WvVBf>BfL6:z'SnM vt5A/:ð;&^y<"ņv`S"vi%Q t`2EeR4TXF>yi$P*G31*\r]b//_&!J Vmw(`wyQcW~J??xS0MW&%`expݼ\suRJ+ôd:f rKd|r,j-ybŢi͗ݽhGc$LZXv}u2xn`eĴ}`_'.7~RDClx>50Nefn ^u5bc:Gp/eP}9CNv2!cyU$عD:Źkߟ%zP'o~ ]$~`1v~QZ(1ߓ$Q$bh>F Dcy?,fX_cdm!i›{P}P҅~b %+3PW0+d":\EC]7ߩҶ&IHF I`yïa2 2 ^:C0!ʨ*x D3Hc.\հ KSUicc6JGnLE7n3t^<$`f)I,$^ׄ i[\:#/^^UPyHhˤfd2!A6ԅhC`!obQau, e<ѡ2fҢ12*A]xJ?DfzY J}ShmD>!du2DWElVRETe%'^uX{qӡ \63Y"~Բb:UL.klg1D S1U];~aÁ-#=6uMmxSQV6wn+ۿ_*Ɲ.J%3ѨB I:e NqϪ' M쉧_qk!ܰ=Gnf#UᵵǤ;8N,Mj[2Gw|$zyz`&KoNLSUm+Xwv*5wwK3fZu}B˫m!Qpo>A,SYfJGT峀o=ԑ qh5lON4QpIvūXy"-6.)pr3BP&bd0'*6{OupO֪I7אlyWv!:'S6$C!_E K*d^dsMdwfm$⼅lbۑ!ΙN ӄa5 2>KS&3^ZP;~kxF׹2Zdo b>c?(l, s`ldחUBm'/bN]( Lk YVm:R.\!@A ql4 U`MdȐF7MJ8<>V/yꔘ~dJ4EHNv vb+.&=| be $<5o-đ}qU 3.X*}`p LH0uAU[ Z$ s=gf`6"so"ȤG$ѦfGӇG6Q­g0HrYx>mRxg^쌘 yV,`EviMpC(?8(m:Bq2&rN/g=yͤY H:J0ef?*aq& QhP[Vy9Mp?ɫ}tt}M6[Q%=Y?f&E;4 V㓷6tl.tCҷ_lJ'94p!<;^G6ElO-̰ 1t7mPˌUAf1'U:TCheES:Ďou8 yՂN ئ/߄˛+J+:k31 GУX&MSa0k<8jK(&:јyNX#S4N)(ilSojcr*PLLC?-8.;Fj#v +EȼTY~N;(+GA=9b?vOt*$E:} q@fEwFsbj5 i# #i'ccBBwe!$ e,)eؗD?1yUq{%u9 K88}x@ w8I`͢U +#)"|+v(Ucı I@X+C>m}V9;ykp&Y ܺܜ@qIp2WosL|ucbIȩ&tӖ_>(Umx$Q֒@?r@{yCc;Miqt=)OaeD^vm?Ը[@_hH|у%4^C%l~svЮ٭NjlM &2o4]Tʈ 2w `-`{RT+@`H(oF|㓗e~+6K#KC&"V%x<7_:2$~j^IYMA9w7;^ #A]X m\n"dl2+BLL) $UMlJ걿a֐)Ӡbi.,zA&ɐStjPH#&"%F4i/ .Vp9Ӧ388 fE !a10F?s35,Q{P:l9~ !'rxAq0ys^3)E⏂=I'Sf\foPKr윓`ϡ?c!yZ;++FhIƎ,-+6"%QT|)X35U֗߇DF.ܫ"u@困sA6Ӂ%L4ӑLB:.FI~n~#{YVƇeK=?3GmJ3_'3?$]^B+L!y`cCB>[lOke?,K iYb #vlbPpʒ6a׭}Wm+|![^qh DpϐeuR1(.IҔKRUdD+Db/QbeVbIQR8!! $,/J VOTPM̝bEUpd.NS>a\q٦DIF fATi(oܞ/Ap;jf[k lf-bp,p%~,˩1Ta l)_"r()NtB~eib[<{`Gm<2qIlqGc"~.cս~brje uRI<)RfT>iP}%]^{ oCMHeqXKV6N嗟bym@ +<% mƾ !pD ZU|lڬu@V jK B"3a,@ ~/+ lK3՜Nr.*d0t+b Κq6u#-~!ld ,2]/LUtv]2hY~=JE^<٣4 WʬXL7o#EN*D NL }SsfW!e娨_mXo.x̑\φJbQW2(6RK:*ix Ζ^S5)eDă1-R3Exݯk c/T[$ /qAF+c~L8E~ŴWp!GbR*RBn*Tqo!$Hm_yz JVBrL:K(3TMI&-U\ہ"+*Y@B$V*rWZ6i0)9AE)ґbmGq +VJd;a6E V-D='UR2E~coJ4A2:-mV0HUr,!N.2<K`(@3կ}]рb3^{BKOZPKb_C7Q$d1yf1ygg\TsNB ʨ́!}i(d"5{iꁟ*oJí,CGl!Z-S<$$Y$\h$/C UQBlNy^:Ɇ[4 Pr|Q=I;'ƟVSV?id!u8A4nLϢj:1QNl>l ^؀X*uaZwp[E/ qt}6(SGƕ,"S/b#7d0w2@#ՕFI? Ē}]-Aq_D-Q; # gS ' kȥ{+c ι#Y m{bsbR[&#[Kߜoۂ %~"l =X9ց-{R2nG`;~wE ڪ^ .SL{AHU\\,!WCjC'bO- BYV%.n4 ]%޿:,q[l=ka8j6!m_|F=8"`:{GL :z@`BV%˥e,I,;ȆMbQ ̀ڷ8#i2C/(W'n {[\GNAh'D{ULD fҼ 7NA֕nNOFRG Ꙑ=F SIm571}dLLiv@͢D >T43>=PO918]J, *nCxVEÁr"D(ܜɏtdZ02~R1s|դ86fG@'Ja2s@i7X`\%YLP`ϋ@Й"IC^_ zø3AgyС#Vο@gy~fZYsڬXLqcЋ߽ OVD QX\ʽ'4C6x,*zzw3E)(/ zx[ۧ^>2 )< ;&ܥm ZI)ABP K6ZƵXHƒb3jj>!Vq2VXT1yfj%# n|M㝤RK,6?T`M ЪR~f#Ñ?Os~V+ÛY86FONөv gAI1m)2ø2ˣ8Tjc:A&c@AJx?a.u[%k-$SLɜfm"}0 +ZHl3a5"Zaܦj1SrmݥAeYԜFE19M f@p9hD Ϭ2Dꢒ%*7rL͚ 6ЩJ͉XJPN^*c65%HE hf4HtvIGԡѬGPsGclREEQ#TD3~"?O:o4PP:&lx+i<Mj` F#T$1๑* Q6_?RkX eW^ieO~HE䊄P~VB oS"s" Hq rfyC#:a}N蜂"\BGI-u7gb{'0YGnI\{gA1&Q $(djmŭ ^oaAԉm?\,ՋHr`4JjnU WAU^>Z~7@?/ǴOA5k*f\rߧgbu0fv{Hur62"N8Vq`X eUGShi ݫhGo).z{;ݶWY)sIdNmJН0+ƮV)%*`ǥV.;}NC}.6Ϻlƣ>F>LNsBI_='_טu*sv<_8j#=,cW$Bq1 ٨F.1xg1mS)J)KzIڇemphzHW e\] mwL:{;5ם7h8Xc\ jwN5U Jd*fڣ4Y1+GX/yh9d`Ë0*0yn:x']u$W<*xZy\.l!;D8, y0dTZ9y([_M-8zK\iiɧ:CČ{G=Y8w܇OoB r{aBrM)˗cVɌfs8%e7HCWC׺q= -w5ݍywGaUgGm0Tny,7y?|'Mu4$S7ie2eT2u6S7N IF+#SW;T)$*[,48$Ip jߺ +fj=JJUeHRb\If5$eHR.fo ]50gj3g=#S{CͿI]翺Lm>0/;o@%r&.#V]+f+ݗ/,UJnR?H’N8h.#ndj.Gemgv{䣦KtH#,}n* RkU`;TTpPN@)^Ir0:!HAUC͈i{'_u;@q[Q)iR͑0iRjR?8`%Gt˘mO>w! (bˢN#k^2 DKګ"(t.{~Mf*ZU6 ȶC:;Ռ0'-@)1Զu'FkXHs<^i/ݔ ~ITߘ]*RWjA)dp |T\QϕI}0emN!{_ܓh` t lyƛʔz55/gб{bE0 "Q`dX*r!HbbT3nR8jY&R*aWbB§Vs'L| \nd1d᪐Vt+XPϢVoZK"Gzu}yuݨoɣ:za/]kDǪ|XY#$> -KhPJI]$!ݙ=|Z* ⎠U.Ɗ.@iVX9̖ݠ5"P@g –mcQ\'ѳ2''i6x=ξ,o⾙O\Ni.uqS8 ֵXb1YYq%T[HՖSNfUܵaP;Ҽv^ftm6J ^O|T9j5\tEy61C}VQJڌ}kMV0bҖ@mAn{cD n,ͧ_Y|PiAlZ,E?K5:DQiϾ`,9\-v͠d,?p/^\moi>p4H${&zKՅ Т!^i#ҲR-}D;p"oT*|VPɃ0>H00&,3. Fd6ױFTa _2d,#eaS- M,#k%J% Jr(ŐtA'( !\fɆ{ (KM OC1#_w݁?fYX@!L+ T T?GƾP )+YҜ 5&]ȪWi| w|e7_PS mõqMC19.cq9^wQsd5~jFMf)dqG%[ hf?k5{P7j+Hug&u#5|oY^~ MZ@,< YLW(^dm>rѰuD#Rg|?.ȷS_cm1ܵlW>y#~K(TżQQTq%lq ˕Wq c6dPeòv)݀ڥZp ([8}%9u{k4Vrq^sIW#8!`M]'&Gy|6ng4_+[ZXs%_*c[^.%=v6:KƄq-g2){oNW\Ua҅(IF n8!yb(k #hű0uw:c:餮PR`.Cﺥ<&5}f˵"0UG-?g~䈁=f nc1.y(㜷ݶ2 tC "br¤Db_ǨAh41E7IVCWm*9n{! 14a6]zϛPo$9^QSWC˴.FÎq -Ꮻ&g 7}LUP67Cv^;$Q,F]T?*ȏ.ba%EF3:ug8J qT\(p#畡3WSbbˤ;~n2hU=C'oӞ>oEy h 0bjS݃w.)f~L]eq|Xv{߻ƻm;az>VFdquoѿյ2ġ4p]S4v; wCgn7s[o o[j>Mӫoo&|[z̈́5‡P<q=uEt8x"!s9QgvkFuhՉƊَF2ڿ3\([UǚԌghE3$Ma%L} .4.9A[jU9te2n;S 5R90U)7yȑ έ1Sp~ǧe4O`"S4-g+=t[1%%+Kjasrᚧ?+* ScwYDYێf9n [K>=棶%j[t(,ble>d^4Ib&8x 6z`]:zXz;lfgp+/gq 0S<?멨xi]lk,2X,Vfe{(υ&l=T'.?v3ljP9b@qq==߶ܧjd} (9X(jS)! 2lXU=X\J?X]C5BY^ Z@rE RV7A>6G E#13U߷wdJ 10d)^Š/@UuBUSh-)4G誀`tp1Uݲg ou1',l[{qogH̹Lҕ`5(&?3VU7IKb4mj$֜(xѸʤ|iTC9^ԲH]k<$$U˃_kUoxSLG/;n-YIn/T9RuX^wcY0D!XӊaxbZ⤺'1i[J(K0\P^Ү,hGTNQ`WcXLA"RtVjvCpFr) Ʉ4IaѰ3?8Z2~ÙVh(eAH* ϰk{vNs7 j?MJlLe@vB߆##kꆇ>1MsP_+"*XZ`cɻ zs0Nl%n/0ByPy\|>wH^UϜm]խ0}u6@Xs=zlox>yI}">]ɨ @5c OE1fF};p@o.}6{iF3y`vx0ArZl*ӏ*p7T3qZٰՅ!f,NL_ZpswvcDVWtMt_cvI9$#LJcÉ4JOCM/\d2Sa.,W<-B]uw,YI8ZN-F- %. #9kmڻa3aH8tYVO:my$I/pĚ La@;Z615.d^Ǟ:)uҼBaT]qRɱDE;v˳A0%AQ_f :Ltg:LWFm XfR\ @Ųi";C_sDZ~itf`Djڇgnfаfxine-lib-1.2/misc/fonts/cci-16.xinefont.gz0000644000175000017500000001516514647725152016135 0ustar meme]#Kn.8$x03333 m9y0nqL%VOvVT'SO=ё+=z֣>zG{4=-9J[]fw7w⸓ũrN6{}Aѕ 34!ͥ =%%hcbiPszem0j@k o J_>`LE}/-``KsN\2^Mi0Wr$o{!Rk.́ߔvnE?&}m4g^b,icrvV+̃l-s̀A716m+4g2јI )r:ׅ# ^&$]NVGT^{NueE[\1S[ƪ`%zhxC ʻc64Ue Zk]'KcLJ$u: clH+>Jc9Bƾ4Wj߹׻źX+fAoԅ9Q+ۢsqkl a]-ƗP.\o0(;=Ӥ h+yKpw3ok${q3VR҇yj5^ot`$:SP"ݬz5p6gnxz Ʌ$:C7TS+XdVk\X*b[L;7ab B >(3@Sm"Q Q˼ ʹ)®Lf^cA c1dIeoJ[U2ZN<`7Ilqw-Uu$C0ˮ$&QԎO5| oUüj~v%İ iűBB$  q[Hd(2T&01QB&I=6t\!k =] D)UX '%oFZV[(Cb1aX> DB4"`8@S!izMϠ>K,d@yAm&-Q@(7֒$(/~HvLw P$KO0z8 R!5-6dB3 ^7=xsFr57e [2H45K4Ό)|A iUς@?oy5};d #b\ XoM䕧c;Zىo1fu Q( 1#/v0S`ՍH`ZN;pZhWG7R/۪%d (#& 0!7dJTg5XqgBR_%J[^?-ىMyW++m't%jRu1nfbv6c=H?96rСl /e~kmAAL-T4{tV޷l&RZgpYҭ 2hwLx4D:f|1 A*`Ks+!Y=YS\$ :ߪG 6zGBc*,W0d4K(r$GŻ4YV?CfTNII1vBA1!I >xc*oy( [ ~!Ves=rh@]L"A) a ΅N+7cxUL?#7]5EYTȅ{Bڠ4JM^ ƝX^E-;FR qy~0LIbMdz1v5z 5aM$LX @n\J)w͛'ݹL7=fI_qbq&zI O'xUW޽[g<0x#{nqT)n3"W2H&йO!oOR#FT7@bf12U0m.hqb|Gd$IRϼ;swYp VmaVzon!ԽSUП{8 ܭk?(Bi ɯ ~)H1mZqhG\?oB^eוM0Pw=`SA.1,*&VvEbk׷AzIrVWJVq8Hj_)S[[+ήvjwL5}\\C/-$9xXG#OZM8-' @wH j/Fj@꜌Miî֪Aii C6w=;9|Z.@.N[e&'X,c54^c1KVaQ3\g1s J9KʣA;]G->&j|"Jy ׻=={kȬ!KcH{k] f-]Ɩ=3<0:'Fpa!'C EOb)#?TK qrB j$u>F\?r{T+L>AZ߲L&go;:- Mb_zxvݧљb$h"SA0^;qX<ș-4(Dn,ٟ#ss3[K/g ;ܤ N,Eyt輁qy~aɡ$v.a#ȼ_\+IJU,tB(ɑNP+,:i+'t3 Jjh~x 1sVQ%I@'T )L PQWuQ; PcߧhELhsgvķKΘׯ.tmgk 2`Ȏ t͔tl8b:i5W_Jm.CVHazv87+nKeC䝙(Q)XBVAPʓOEN981Q :>iVa'ūĖ3jѵN|*T>\Jڿݰuw|ԯ&wS\5ZNf4JTr%R>(tԊ)JFrVc~Rxb0ZӤHj秚M%TBX+Rn5g4u֕ #ј8Y3>;Y?L"NkY+V: >M 5q4zBpJ7Ch2bAk s츁?DAaþShp(vDu緀[i0/2٣W[țAUQ3,|ۉQڼ(o¤iZ#H0Ygi 7o 6g&ĀI YxIJoICma*yi64IGW$CTGo=gzAz$M =2"b~=#Y[8|l8&Z%1e*tlͨ~Vnf⮴J+ƒȏ9nX;6Xh[*ѱWS1P( ɦG8}Q&QxUN MĪ=*\Z<MZln;T{PT|r- ‰kxo P[=RŸ"}R{~R x{Z ECE|/DWrk5\yNYSh!=#1a~Dt =y}2h9^ P3M$-S.`M#a;p#^QnOh^ cq P_lcE 冭YYoUOcԦLRK\"Htvo3,X,W  DYwcӚtu,|W2]tPM:(]D+L FP&-zڢN^v#3? ԚX`/@*CX@&ٲUc5Av] [JWo:,"s&Tu!<ի`Q=)H0)D>ܘxD`tï^073iв#hDy\z~J2P@3Wg$SEYv^ E|B(/HyKV,eS_v ~_}f^4-\<kq4S@\]$r!>*TJgcPr #5.#N˓eRғro xomS>l$"T^$q CAʙe :v^V!6FZTh_JH'M}B.č*)tAD1)Sday}׾e=ZbAJd8.Y֯s9|q`; T#1oy-FCX))yjc L.B!eM_F~, O+I)ͯ}|pσ7EkNJ_GJSFl(vX#|/sJ!;t!tܡ>Z~n=aQEȖt 9Y.]8 BtR1Z+&4ayv+%Ŭ@^qk朊@N_3Z9՝鏊Z 4!#vƷ)|c~rw6G`y@v&} _ĘЇ`(jɱ;ZXCD g~7U.rwqMy+AH< pKx/ #MaovmF$\P 4(8F.ߞod42Xtȥ`Q65$WA]&6$$DAvi#VGaY3; -9+Hy){N9\Mzm6vxa&gb}PM~ф'?0 Ru%&TC*b@|[\ſA U V2`4`2G l yr-?Ij7'EŞY<9!ȲdA5_Qq$WPV;#"JG5co}-=:X*rI؃ 4a *rt{3S\)E\Gϲ$0:Er1LeX>SJg"H”2xaPeYY$Iߑ`f<<=G;=&p '"Gaa`$7LdmXIF2Vc)e3 9!fՠ@IAb" X( [6/-Hm–1Mi#V% v״/;'\o[u)S 1{\(wϮ X`8{FJIaI #109G|0HH"S$杋dQ(j 2a.W*QgL*hJH8(XS^|HCs4Ŋ\l <`jC2sZ4VJ~Pv`=Ty^GfWZ!Zfh\3Hjfb| 1kaw7C˰/mdb k h )@+bbي8tmVOta(*,ޔrXw? 3QDݪZZ0~5dht3J jv|Pz$ZV  эf-( 0)[D(_8P-%@ V%I].+[]7x4`8P>!] 3Je,UbC}+ @tȝAYښP^W#A|s^]/ZN{SY!K'V`j>#W,K>ՈfGSeөzT:J߆]t1t&-ELEeMab'մq{E T*aAkL#*g2q# v` Yb#ڛ@A!Ϗ|s2+$3n_j#jgsk#yjBqEcB[X#?d{S=9oBRINp7+~Gr- H'Co_{ }5;X„,ؚ9,@jWa7BpiۺEfYi+D[9oRx29 ,aӤCH!'fP F"dE邑F%xc.ycX|~m, 9?As[(J<IBfäMv?Np{Ъ)oa,&qՆbA)1#R/PòGqZyrl1Un2֚%rhԲL$8W([X:^sގIFهUvM,+k#yqЮMQUCA6AamITJ}􉷷sp8&3Mh4AfV+g9HQPWi;tr>&|#)OF3](xN+]T#HFno$'X;NA`כpTڠ^Wpfj}Ǩ΂=rO npց8a1+\wSoO`&/Xuǃ$:m|w qjAПv+x/"Io~H%ސn.m9A|ՙ}Uï#I1"ڢRB2] kZe"0}+@b&̊좻J^BƿEmD|cLj_Shl?VvbHC%`]LX:3Xaf!:6rBnFjh!{%U XDhCZ|C>g0;|goLt:p\#3۲n57}n?fr:DŽ9e諦z}eYW*(}q}4gqítmeyqHP+^BB:`D?m?vv?5jr\YgC'ׁb){]SViH!AY, OĦƒ¢SZJ0 4j&EA⒑ XM_X9'A !@`@*XE(oh ZJ9fO* p?ZS4,BJ\='Ӿau!p`4G2a]?@2x ӆ  H&44Lٕ2:@&~}ͼlhMYQ鮶|kˊObγ# wN Zvn Z[tW\LhWH^['~X ]oxɵV[n~ ))µsHpjw1m`E[dco0S &ya" yq:H7LCKlP+ -ܤT }coYI8n%^zj U[?cˉBJ6ln,_4E^O)} e>Nk̯h2o1@fY6F "%pKa3;N)!8Jݙ{')4$=Q..|J.%\9{߳3"q4l(K pw>Y:tr ~+Aٶ|0A%Gc+Sy>niޯGc3>iS$(H@exȔAdubzbc|x{?1e/N5NՀxե(+Uܤ-c+3Z8~X,vf~l?/M;~V~˺]~ ޺ɾUtȦ3v3V((XU!_>7-qm2Vjt,R X%4<OnAU@(f\Gsؾ?+0칆7qĬ W@0 & , h]*4+}:v irqm$XQUGLM F_Wt_n/LP7߆:sAW`'Ļ=}}@&.prͽMrEȵ|Ǐۥjˤi#JKj R2,>7U5P$&}3rnwv噪55.WDmn}/K鮍 Q(ZP7qAcA``$Y7yoV | ޟxT?j~y;zW{pI7,ӷN 1@[= 9xJ鹘HݡFd36v2T>ޟQx4620DV5scxVx Õe%$?wM&j3xw80UggxEMf~ 7_=fֿ`ٿN)77 Eyͬ禱2yGԴHC}u8i_)˫[O-`7Stzu?DxS (ERahWw7+$&ĩr t0]tmm|TuX嚧l:{up)4;\LgR SmWC}򛧦55벏Û ѧ욙}.gKOnQ=nfrarW2c>.I8u ąJQnz+רC0ˊ6)8 a=^ܱP9| NzqC]h,>4_t.W<вҗutuY7-y&(RFvf놹H'mNq<o.dZ6uXٶx};.û09۠Wk?9dHVt7[]d2ovT[Lo(Yˮ' /5 nUWTBqφgREnd fQ32%'~;G*ykCBR=e]a/~26HɾCR0)*Dg}."xi>zʾzb"|PLČ-WQ)_n{F$~զwE>wm\y;m{yxJA (Dlk~ a nx뛥!r6yƒ(&u)]5oq\x7?ecŗYS5>;Y_eaW|x:-y:嚡 E릭 ʐ]^0(6lС0DQS8Z7W^.ѐ/jbxHǞa0/Y="y5'Xk*նs?.Dn8}לe:3F+(OmX;25P:r Gtdxrw6xine-lib-1.2/misc/fonts/sans-20.xinefont.gz0000644000175000017500000004112414647725152016330 0ustar meme},Y)$/y I!8 N N$A7e`]Yweezz朙9s߽{NW>{npī]իW^wX|+~.K;Yϼ,?3|&K׊y[պټjzu`|ФK-Ɣ?)i$3N8ךS=C^|2R SH56ze~O1s1+r*9Wt;q{`f~hL'^XVa$tZ[2~4BAe ^[hiK9І#ZVs #^:z<{" :=&@9QW@NOʘcJ$G*7CKz^7U^@nG& />Ri:J"e,$ Kx4fس+͐| ,bLct D25񆫗]Eѯqӌ8D!$X{g;#hZb$2쎰/U N?pj͊ I"ɶv9kt$#Pa8 - [r+}̨‹F"ӲVc umeG~<~̢4}NӔ@3|e.x~k(I)URi jڄ<|{co0s8爞IIQ RTL̒JaE.Ȏǭ  ;72N3jqC}n vH+0Ob+s' &:||l˓LOy_EƓ4V'P2Dj! LHČe#"6j ~Ew'jcU M"2!$XMe->4x_ $@fsV:< NC]cwu>Ix|`H\AaEE˨4ŸTLUTSS*swѝNU՛}x* .|&i HrY,cMȝ$_SgN̫!{T4bdfΠSAsj"OZۍ!p~,(!|dx"L)14 tMzr 9I)HH/lO|?Ui(=<Y(*1kLFv@%p9!R\ER4ng O4i~OT $|gVM\bT# !FRsthu$;X fqVMCD"H#FRRp > ,~b_VIute9Sse_<" {dq,(CWIE m0l!wEg&XfG 6|e9Ks>@-!zlBBfcR=eql97ѽjpD֢6$Rb\@}x!HfY"oM| my=ZGid$ lr;~O;XREW[)ʲڼpKt&K?:MW/9xŽFQ_Y^t"ٔ! TRaFyhayR'G˱$_ 5w XB(r[;3C7̃8GH] jбP`R4'(2>XY¨bOlXA#Eȯ""n6 V4-P%:WG$AP/j A'Vxn/.2qyR h`!-W[- Ϧ@XQuT8Jjl?Q%ʏSTU+DtHPk<75憜 LjyG`CU;<9 }0c o?OQQ N&}uC3n^4 7 񡠨R*%u%G=|Rk8JL[R/I/R4nJ;"os࣪OHj.иgZFbYIE"yz&aX0 V ^md:6^aۗ_=w$2 lr;VԆ c9S e!v(*yz kC=.Pi 9vgټb|[ťt &:TV,W 2%O`]au *;>Tev2cDN/$҆.l\aIG&yۄM UN󫜄~~XOl^&k$K/8?F<(Қm4m C:ơwa6s28dpMwS&/4.,GU1kAg#Q-gޫh8R2-X-31ВjqS-w9ieOoE{E[/o@r s.k/XXm'&[I$Ϋ8g啧<¨ 7IQr_ͱ&%yX(YxלP% Y(,M -Fw'hWщ>ҿ_}c[Żh]YƟ0f90ܷ8aYΞC{,䠉3-מ@#6<ˢU_@vK|Q!vʼnnWUX3򊐢 Ԡ~d$Z`{<i ۬)/Oj"vDdɼp`qH)K lN,2FtD+(0 GJB3GR?Is~2(锆{ZM!ZHCbp*Hq9}q#"4u0 'QYS2b1?(#o]<'kIPS8tpLzyEe "ꊡM4ɖ)&Uf@)* (]yc=r]A]n#q -ΎwX!o.q](B7U5(nTZE8b h>kk \$$]~Bz}.MjDB./Y 0Q8\nآ/q?F`&,b7xP}rS_1yu}c֦\,C-{`TPtLP*IDR)Kn:eP8$wun?8 jmiyei8°A+Ĵ( ivZ'Yj otѿAO_J9+ pND:?I-QoFtP{Wdɣ-%Lͪ*&@4g+N Z==,(̀HJgn]ܦRg#p;N.+A)rF$+&x2!"L sF]i~\= yXN>XVrp?Kc2epItHdg̨Rt k*蕨Mp*x 5k"c@9xb7ZH~mܿZ}zu2: j.fpR)Di~U\ϊ$?<@8[Kly?<7}ρ̐KD^Ӫʬ|j xh,M ,&(甘 e[#S,8@?Ȟs@ϻzQ{D%QZ6)WYSV_hQ w}Lg'Jx+ }}b+gs"Aijh*j-e)fwU׬GÖ(.-DX HKOx5|ם2(t֯y dTI:eBC)ڬ ]ųi]3n?{w%W cZJ٪d+\C*~TEFyh8N*I z?fqX]Q}I *MUאr.Qlf~.'-Y?ԴےVJ2!TSn~ѝRWEdGdW9k ![|*Ţk/Kּ^x~T Wv"ld\]$٘%rDF1Rmc/xV8#E "qQ :x&QX+H*SJ ]8lf`_ʠE}ߝtgrBnZ Gn+x%jzbA,hNҁ;\[&Z`Y`~rk8cqrkod OxDÈ"o|J}U.Xes^7QӋr/&m'&T)W] cw7l=4U*gDpW/Qs?4֣zцt[D/bitY*Ċ|< ?|gbK*)Xl0u L/}tTj:g2,o-¬b䝓Ϛl L}]E^.''V8B8iY>'3T: ->va:@Fjmŀ{m&"zhN3N5mR7o=ˑEs+YS@o@ȥaU&N8ހr@{baioHAJ=M 6WK | ju\2t’DtfNI@]T4Ue$ZQ>v=o{iX@JH( ?ΩA8WK[ȚnS5 K$4I).H{$/HCsɝG.H7>zNu]>F}zewtsºT+)l8_O|s^r=\R}Gts_=Z3mAOoXՐ)XN1jp,-:m7;s7>qIO+iV;S,U腕D1I\:v ^ (F!yi҅fD _\0Fn*p9 0nQfXU1-\ (9"S8ZOEFVAM:3 79ɜ ^~6~gASn Y,OW-t߂[-i#JVŶ++I4F.ڠ)7upJ̷-|![P=ݒ%GK( ?t~^gq5.)Νu/|j%B X#clXڀhdaYvL ÔCnol<O:Iȟ!?{ qCܛ\L-clBqQK+=]#3dɺh"QnCμ;#jmOxjdCMYv=aX VP'=]AU?fP80H'A,9+6'4NQ&֤ '9E4yUnF% z*iyԎ?$).JoD߹\*ElW{qJ74@x2Ee*SE9dÕ`OPJr[J\:VB>̆{C$C;A_4XuӥRq-=Mt;H}49&a,߹7=Ǯ^z<5hӎ&= &y*-)&*k3L c w4!,_+;aľ.77 -ZV'tMbL\[0POf dDIy:@K@*&UwVtC>usY̊W,]婃՟uỤׄ~/P =.><2qG5)7(À$|`5 ..w'S/a`*E|k9 ¼J9:oIR$nmT CN]nbIjJ)?6sFdwdӱ_1fQLo_OɕNه^ I³M6|P-dط|k@KD%θVfPݥsw>P u%vh4Yv Yw<̐76)yo*SZ[UuyXBߺz۬БeS[Kvեwk?h\M?~A f8HnG%soG(Xrga3/mmeS1&L,t"C 3{u*ub?OΎ;̮!:OF\k+AE[6o6V{ %3?@*wj-+1?9 H,bJgQ8{n/t'|yFqb.ĥۊ6 ȣOr9,x4`s֊.ipHPlٚcɭ,$p.`Z*w~{J/"P6X@XArCV'@&@sB~@q zX!_pO. <_G'zPAj"zUh1iJQH=7gM "RZ>딟і$Lmx 9|>NB͵|(0+XS=)d$P{ثXiltk@,0EHU tDpҖL Me'E'V(@.M˿<,]|4*30aB*<`WeJbJ2'>1XQ_ރjϛAnB$gc]i"*m>?,DG&A3:=IMm~}v渭g)X[ NHp6@Fh*Mf".vpiCEvШttw1a,9XdQ[ ; +jE ln>Rm>;w[aR%NJ;O#鬍Zi@,HQr >V~]}Q\4Rr ZLͿ!#t kVRSO 鰚{an,54sI5rݣ?w ~I͎HpP%eanO&Cr9ϧA<\zQOTJ0F8?,UQ;;S6E4cّ8;XQsvH1)Ύ',ΝюN()Đ*UK =ɋžʻ>\Frl#zF~F=uG% < q7_A̋[ J׵:XrMĈ;OYmѳaDv. KOZ˵*Y,}59c'2?[685^$^ D3Ъpt) 9y1KBkrm?9oEdHBkǚQ)!t3bt mgVvr3LuYf WÛ. :_ زpYkB'$3/SCX7<@H]"Z8I3{ -0j4 vfܑ}ddj2j4=%FUvNnlqmF&#hMFSFRp=9qaӾmJ0gr ![.^9Mpc(Keqģ[.mFXQ33z7?=wy^zsTa/V ㇊B/aƨ)J( ehPS8>VC $盍 e p_Y7 -\W_fKkP)mu:5qqd,o `uk0XFiWƄ~zI46dab=0ull dLV `<el^J{)ͣ_'ěnB^ &4v^}b }euH1ʱQ]Ji#mfK}mƠ2'p^) &qi_iʆ봯Ầ} YPH(iVoơVb~SOe/8M@S] %x20? [({̩d58SҔU#5zDՒdxߠu[YMΘ,'GTHD Ij[x'ROFSf^LR7wy\I0BXw_ ;pD&=>xCKJux(^9ٵ0-'50~>һvJ1777{yr݇4bdSh7jCcSéIHByBIwI_\f.ݣq-m$ђp5(S (-wuHzٖ"wT>|3%LDO$[2`Ž9Hpœ 5qJ^a<)c89@  3;:l/TyuRWYeW`u#9ɸɵ]rI*I#Y34㚞D񊄋 iXV&ЯGuA;9~H;BW׾7d+B2HW)36NR@Bj y3.XK*|x5y|}'E}0xH5^ NhT#1 ZH 9$o[@9ݶ:MFFkyLsf0`^nei  ]Uyz,:k`PTSk'ӄ lZxUX=Xt ' P+YF6sSz}>lȫ) ooj; -w{MюӖ#)^Ke rz(,lP䞲E6-oP4E^P1>eHBIǕ,lة^7Yn?sNȗ42@}c]k[{CE^JOYdcGU5]?qtFc{m\y8~r ȮݧYN/G@uFFC䠃|*H]~1K+ NLɗ}B'|G»/'ߙb%zP[>;6>܏\9?@ 5>cR^۾ h$Tח׍u9ebgL@/-P-yAla#-݇hPbXNأE6Bck~t].3Zz1/(qnz 5DmY?-e2-!~e3%'܎{,;@8gl,L\!䷕W5] "m N*X <  +P(bՏs;@5Qq+ڕPox/E*hJ}g%%:=fIF C$PHmaTǭԧR.gfG<{G-sdH:iL {i~ɾ1lLg5';!`7rGn;бj齧{ `|umHItKߎk tTQ|}LCx-fքߝk`εư[ ^GX+k`R\GD@˕p\*A_ï+o(b 嗛f o*d٦[X"T5++Y]E0oW'\]RWxo"UL^:3ew+iqţC-W\$w9w VBJ+hCX :+Ougx_/՛u"*vFwO!92{^+]᱐Evas Qx p(<\]"~)>,+McKPIf7x'Nֹ )/.~)Ck?5ztnlۄHM/%%Ύ9aE/m^4[%L~glwa{5ܐW҆3lf7nY!hh%q ڰF43/=f2eYmuoC?n 'g/h_cTyVU Ub7M7 fPPmPJ1T3EЫ4p#aT6a|?/߉ȭR>]h?@. ch(_5sDM=~] 8܅bp4! okt_Pɂf껷8m,xHK|>.Q\}ty#َ`hvDMwS&î/;MֆP^wvx8# VCO$748ybR_~ ޘ L =0_ ?٢IV[%[ A;aqdj}m}\xLi]ft}uNp* JA$> 7E@8jQHH ؙ h m꽰K}B'VBb+f*"}\"STClJ1 g%{J;lzpn&e^eem捵| <6nHxpfKmdL@)lp JW{p?2FA1n/̋63 l7/NKC<wzX-%oG_=ζ6Z'}4Yt.7+iA)m̑;Go4$5'I&^]ȏRXWb!35s>_r.qmyVw EZ EZ*wQR[Ưk`f|q^ö^A/oe*x"5a'@il`SC:mPb6s:@ ٲ4`pU${|a+#Y!7u %6OX(kݐߦ6CZc~khZ).{.y3y,}.Kk{>ˤBAe<f{Fi`Nf_t3o)xo pAiX'FT:wBEsa!$ۜI0R#]qZobCZL9/b㰈Yɱxb]`3GuḆpigt/GsmDFqlujsJ}Bjg ߻S ;)cFϐ9@Y||dEԟ]>N:""?7$w.\>vkƭy\W?zp7O7nZws+Vf- rGs.92Hr+Ff$H* IuYfJߨ8M,DgTdYlTM-T3 Y3szD'cO#RВ=SD,DBdlQ3L +ssRZv6MUeh)w,.% bEwUL V /EWh\c$@awHFdO-[g܋xA95]DC&\`JiJK N2zvM[:z'?)M%\nE#[z,cW7lvo?,nkB%~YTnQL>16@{]FWLw`/|IshƗd^o C/g;S&gvꚌG[t[5։tdg>y<[[]p#JN{ a}L46÷šH$by,M$L{Y1vDKRo0ޘ&4Lzls۷W񻰗!/կH2y; ͋Γ;CZf.5wEo%]JTaI* i xe#B9HLdyt,0/;fg&o>rʲ{& 8Svߗ($hkwQ7>Q/Qco;/n}$Ʃ˔Vc3S Bm?m9Z),̶imcĄ@`UH&Z.rL[}㬕 L:dw 1.UA!BKUv`8`p_]FhEd:pf>tmIF' $JK.  9|0 lچe-2qoVkNS ͼ:]{n8rxR\tB&w帎M'b2訤⛵<&!5R P | iq1`IqD4ȥ͍q#.PotL OWg7(&O7K~%)E}Wx4#I\|ڬG|otG:֊ۀ݄~T^|PH:rF?v~5v䐠;8;[xQE>(G="vU2۠osĹa v|]Ձ  7K0FkK&en:[ "~YlmUq66>x!Q|́aC1v졈Lєu@G!񳱣%v;H`3h&rn;`i4k6742+Xq1̴&9wQzV.74a"QqJsH LJ`UxXwvf)U['< =V LVk2U?܍W25=DLeJI t? onw\p-ҐNȍK9H\yBVp=g^[mW:W60溌)'m#{Ħ/M˸sڸ1|QH.Cr!{剱p\Gg+\[Ysᅠ-ݻ{dZB }u,3wJ)]׽%NK<+tuKl`Nw$#m}qw5gn4M-uqVi ˝?"wEgrM2ϠEvK/oα^Go\̂#gF{'}-.+fE<0`w㡆Y5 v<0؍y{'{|;!"rzr!G_CӜ[7ƍyeߏٚLVLir\3$4kq|hvq-1S94_~]UC~h?ZiniJpCpp4ǃ5Aqd9u{4X735D@%^&=ﮍ.V}s ;韫CJX07;usS;'+ |˃Qj-VOO=r*[p܈c+~1~gNe-NyL^ iNfHLCl+8D})y9FX@usxsNW1±~9q9QX6P -0]Gm{f yI}>gzqY}Wݵ)%GĖڗ&C*7X`Dt Bk]fgRc]l/&kC* @X 큳.v^|"./[{jLf8MA3PpL Tf|a\8^}7 F3'b;{h$Μ>Փa@Njږ3|QH) .Vn Qu`Ku4Y*fֲ`n?(_{}JO}b/@<,xO['$reG2Fs&2Z y~\M$vƏl Jّy\>0ZeΖP6ak P5/66W#h%|HFPO4UO w>k4̈T]v0n=8mU+B RT4k)}Q]6:s#[4oB5u8g-hrr$}BGݶ!n'S=_})=00w){^pZ6l'Sy(gwPu9XυL\ ccv]hug nz3Ԁe[y#FٙjQ[2vʛxBWٰl lMan,[GQsf64CU=z"MkүԠ7Q8Ǔ|/8hT M䅫d7]ЖXGnKF.ȒT%nqdvrR9eض3vI2 m}xM8^{Ɉ(x/^9-l׽Gj XH^| Uݓހ@s@X ;z`E=U=9i|b*lyN|qoҒM޸Y[uLY+p:kY,]pSpbvlMR&&s>`] .gn7~(SwO }[ߙ#X`':3^x% ~rl.tM۳qDk luc60O+y-P #(֞s; w"z''/T Sp.I \3,ʝm3 {Npb 1%;+ `Dn9bF3z7cS?xnQ l)!gW[axyژn`թ.=qUݘga-ݍe\{EŌ"e2j8XD3o/|Ԯ`&} 8@ j:ͼ} QJN $*4[r܌Z wx`vky(Iގ}cyDZ[!]zM4cww Bm[):ͽѴuq.LXwϞw>5Զ^ -D&{zozYYwnz;7oO؟ T'iRyyGp_ f(= r3/QT%op9 ,ջxg@/H#YO 2WyfC_3td>xq=r lT,aCOϛq&hcZc%޿iw8ߘ/&ۯ8,%Qն5miO̧bJˣ9ҞoϹ%F>ӣ8Ġ^CURVSuuf7x"М-~,J#Dkȗ2NrX#%528FIt~ՔL1c@3No8?~f| 4hР i]Wj)8X˪:;l}훛aCl1}ͫ Tм! !dAhhr8rv1{+k~q O vРAHKHBx$F oNЯg 4hwA}gTތ63sjIՓ4| G2Nu=o1Jx4͚ehø<]T5z76 U}1=Mؕ0#5"xzca# ^g 6 Hj*z34 ƌu;^#ێGnmc<Ӈ^7L7F!͚Y .P o ܻRArdiᾳf3 q8^Fv*z [|eVH%D6;Δ _ />D0q88+l>=-+%๰\$w o *w_;BfNϦ}g 3&LόIӬ{2j|-e3}O]*0zǩ!9Q0]sZrB@U">MR )^  ع )n ^8lfZ[rpdII~m]3"kD{צ?hD7ST.@*(iM!@mRG~Iɴ$D23Q)* *8GO^AyD3H弰O@} Bm}2Yj{В&4'nYM#[wPN1)Uԭ8˘$cY^VgyҢC*-j=T;ȓKFF"Ҡ"uGɹ@mI_l`R櫵%1ˑp˜V̰ 58凹y0\p2o{w87zq:|YfВyxsw*_Zuxn^ R x*_f 9Q(3{uL~!v}Åsfzkjsr)v̡OB܃+1a '1ӷőN,'n/iy1\N fܶF9NsE.<A^ܵR/N0'";p$k0+K^*٪zdyǁZԨ ӳPo>flTvѩ(*.G@v~((ܣ|1.P&TT^f5d-!(BK%.bKBUe+..pEd#Μ!v֒/mpyB(2ˢ9F퍁zA PQeqO~[Yq a?<28*<2'c{۹_?NHC ẖCɻ8NJ=F&r(kGىؙJ$/]m 22n_dNb<,g-첈C> ӛXݤ |㆗e 4\pի&R05NydQ W}FXOrPsDsJݱG[8Rn_ |geaG2h-6N;8RHqt`q5QUAF';9F'fOpfǟ2qC}qЗ&NN3gFY J&ﰕ ΦzlwC{iSK=i e2PkM_uYaf貹GY:o k65bcdBVS}2dtg"XIw]4H4-xSiE){jj#;4d<I^XI{üx@W@Si3nWt9Ì~fPu 6L\JE}SczV.v:q^ fQFϮ|N:VnIW~$wi*Zs4S[j_PZܻflRI.uѥC4(Zц?KѲz ?"`ϲ~]O UiH8sRg yx~Oxi{ >7ܙn3Nm}Kf/Ᾱ -on+o(u1,|(Ҥ5,z~DSA]1ʹO' 3?=i["ބM^?)fN2u !펼Paou2lr5MYBۊ038#87;;n}slwp7[r+z5Koy˺o3=1^XNTS-if wӭr_`P>3n+ uoU*½/w55iРgZ^̣:| qVˋV'03 8utqˋ:+/V(rX׊eg~at)k*4-r5 2.p] ioGL,'ی~JtˆHkNh6#]s;M/Դ5'\\/ƚN6QFzƈ^3Uu63g)3+Z9B %/iD\GX" @vY燧wI&@\wjE{M&'tEiJUoh/f {LQak?3`$6P!+V3)o$ e94ӹ~O@t׀CwbH:=/8l]cB8w{!qyXW)|MB, U>Js1)kEwe$aSRfiwu/9-eعr/ y>QtvA1}Գ}凟w,S=oSH>Aj=lMdj>ةjlO@at+k(ƇΦpp6-gӪR6M˥bKC$!4I@tо)?62l Q3BW0@Q=kݡXبݵ{X$-Şfͼ<25=`~oM 9.8Per/@BY'(ZxqK:#>}쳘jro=HŞa|i }ņ.'0m~?#r)widI +籼TH\W@zt6fHmȎhuW}X!O\GSvcN>U 8dGC b2kr9:`)Kga҅)Khs(Rzt76{jD. Ө`_9aHP]3+>f[Dʐ \"Fc Y28M[S'nqgAWPڥ$}t'ӕ׌*#;x=Цn6N,vf'1Mn,a//V.4;՗|d_=3dA;pNo~{;}np`Ll>4 3W8;#q]IgDev2ځTlv %/R1ԤGT0nړ F* J(8 lV* to6)9ckaʉ\$Gm'<<ӷhػt#m}u^f*̸3HyFLo*pQuzD>Y),Ƥxؖ(9q2lW:sMx;,ңSH<^ؼ+[ʱ̀U[{û2`%̀]KCMVpצ[Oμߚ+6qãl3]`(s (qؒMS hw; ,1_˴N[[@jxE,ֻI;Kk[$kGi}˘gPfp*ۇ>,EH)JtcR/8bϊʐzr1=H*JjdLE3É^ӎuilHĴBj'k}NLC%81EW{h:1ĕ}"MN:tb^p)pbIb'K:L 0ߤȉї81MLbUTNh9ΝXzç 4u@aCHY-O9Ό_9CHiM|+picƯJ.HÔVy>'ΰO ֵH7[RoH)<V%Kt;ggjP.t6ZUN΢~_)zG'$fu]Ͱ::VܥpG!|8ޮS&C}=k;,nKN>{>e6etbU]>{IF|TLq0<#j$~;}s0w9av~0>c amS-z7"A@pupK *@aj=\=ėȂb_ŎL*҃q;Ӗ~ $ 0?+6Ǧ-\(2A@jGNm`)MizV$V'h;wn[FZ0̴Vi`X#at5_QL؝b7-f'sd&̜q8攟^<ɢg;.p/>QsT:K/J:s]g:K,=Zͼ3*N)VY'N)4c2)5X"jmsDXڢ @Fy 4J)p,2S}gx[\Є$5o֫@c&ptôq{nS´2OD溞WC:4G'Lu-|;}B3؇z.k#{yCox)τ\ugBbC~Py,1Fq͇d.Tp/arVij}uqE3Aݬk`KmtNJbcƂ}dV Nq!$Pcݲs2IoH%!Է=%!dBI08xJx%0č>>ĝ]R^JUzg6eQDi] &0%Otťk1<+JƂ`!*1 I)9,`5$պy fbKט-[1w62JJ6%3ίG*?q&Įi\, 5-kf5%Ð3˲p_ k,*V閟z>]mlVLE>Ƿ͚^s.+ H5 坼Ȅo`𖑫Z3d`dpu-շ "+LDa^bdK:P1dBS#+kmQ33{(~Y29= _ <]m (2gy/0_5 dTN%q^1 y ):<OY3o5k6N%9n}<4G`89j0;}>#gVږ2[#3;xf?[!v863;"*9a[4 xEMSEoZuv {UV:;/M@ʈ +/#pAZfxWVz&o^gS[Hϥ  $"RY r?,ݧ|>r n枳Ο6%,glҴnv.K2+{ne[7' 椶(mkYՃވpK_7d wT/p&M {]WY-Z,aS6[jX{^\ 4B|"T~I+s{Ju{J6lv= f+oiTf5Dh19#<Sa!Sְ$۰Q '쩋0 wK˂ӟ>? Xխ|u^݊Wխtu\ c#Z)62tSE-ΠTՅ(1 <-7xamp H531 ## IK!y)EarXL]S C:. *!#F,v3zF𵅑exz@^'.Qon<{>fp^K6pOKA8&|5h4`j^{ #э#fﶁg,m/FJK1D=3 uꨮ*ȴReڨC=e=M,U,ڴNY'L۔Q*ڴL"Yk`~* x^ wt%pP `’ޒ$4*Z48!Q+bvN"I }=NK$*t˧M1KU_d: ARћhb8РiKff7j|+xި张<&uL5R ظVt'$Cu4X'Aq4k$Ḃ_ʬH);OCM|"%wy%8YdrZu{Ǵ$H^kPKeL\tXXoҳ lT^Iscp H;yj/./r^R}Dk*+2s$^I{~bG*&2CUq,xV$N$j?Vr.+%[1ȹg 5Sz ,hB`ǀ~9 b 1%^l2P\<;.qɐ(6NlnQҙoDCz?{z9H֝\%k'79:(!,6iEi7v36<@figYJ| xТ ?&P>&N>PN75hS> o}^Z{hx 9?88 v>hN aRwoH}_q*g K Vr ߘt]鯾pѨʇ k=7Xpé@Za$2P%V$,H25,_zY¬^˒uG8~8X~g8?8X~Y@. #8^lgvkHn90~0uZ@Ur`Gb.PS7vZ:}6!!|  tT4c(s/q ~cky^+gptL_5iS{{̺&8"娰]BƧyqDo 4ndEw'^dI`6݈,4ĂV4rY馣f` †$,#^0*V+q=b\cM?ݪsb;9:36EylY3?! 4hРA=%>s#[dqiKjg{55/+,t.lE0r?b uX{#_ MufJR7^W&>n)5!jl #kϏ48H&H4!U/x!&u TAVޛtSȀ;fܠAoBP\TѬ v[ՓJP7/}Z1'=˩gێuE.'/]WkHjt)~%{fK:KM&g3=]C.}MK~O=#uW~O4*dۧu۱ YE[öQǺ i(Y&rZVi!gUlH4V#+H#FW Q 2]r 2^cij\sE ]ҹ 3ذﴍX4.R`t2 B12X2Q06deգc`2PjpYϸaܺ!ܷ[Ԇ&t  UXNNhS2ò5h[P>e0*찡ə֤H*[K[ƭ9^ƢCm u]-#zҶWVXN"HFѪW*q>T}ldj8oJv-ods*5|Yebkm͓WSY׺%CfBĊ&h)Z/8xqGx^8 wЫ^H\Ȱu!ȰImմYM򄆭_6=d[]5T^6wh Ve,D J'Yi}xHFiIOH yC<_ P_l`EzD# pe*$VcE"7٭*/$.KUsKdT/uٍz>'pIV fc! /&#XBy+!EKʆd" O51N@ $ A=C_~W~iI} Ms(~WAmm)Xl7ND"ʐ=Jly4~)"Wqaלa`8 {:sm@Rc\pM'؉ kpO٬|\Gg9*"Y̦|WQ+ (#LHO}1G~d^FE_9ԤpV:FXWʧ[7Ǯ!e<ź6.C>PO(_~dSaxVBkq L@2$DI+ 6冤4bHE. gGW-gBYGJݭ%'`|]_5nbzC/Y t~l T_~|y@h T tEh tD""JWU9T9ap$WZ (E3$2|ݼkXqkøQVMY30װF1`dj wfM}R@ZKʆZE-g\J7NZr"j K1s@JgZG+N|)BV{u*j$ fc͑p{/Fƙ X+#f8it_|/b'-HɒBt"n*ҞoX4wW|_3Ԥq;5o粮4np?!pĆqᧇ4hW"tn* "5.W%TYs%7է "D<`hQo=3h*nTyNhCc|x&$+‚c~PAA}W|GZvN+8`؟?AL ; Vu/aa?Ba4Ȯt( rojޜ͓ċ=.]̷.3;d1WX5M d_ I~\^5Mu{()C\ -KY]m\9=ݪ*?M,=Dj'p)WG"|K=,ުt}*Mf_g5_WI-ˣAoBAV °Z_5T%Mw=%O%Rf<)3k؃[ɦ.VpdMt]m%&̢pc2Kbk Ki4a:h#V0OԔ>Ѫل yd]M7͹/6 `zYj s Pǵ TK`!, 9z/]?8oBF-*a@UP7% \縕7j $CSH'J[zϤNz'_;"3 z 4,$Wx`aqz%z7E~H9yC%ʩ͔ _ 24oJfݲj_AܭnJJjRmY+2u#Ʃ}g{AUj[A%D!+M ]/TanleÏ0ݭyT^z] ؊ݒ4:*u_M0K f5@#YYm"D< 鏕TڏiL荁,`s@:͛;z-y3JJ@4њ3e-Ujj<ǻ +xS}Q_7tA\ř((0P\n"JnU6ޜiyO`96:B^ /ț%#; @B7I!Q1GFNuTCo=W "/5(J?4@Դ꽢YB.'TGKr'Ug/yݘS>\vb\\1ݩ詽QM?>ij,oE՛=yYz o\PJ.CRt2`,ObhzMKsK+ YF -4 ˘!?v$z,& Uդ*5I.Ws<7}a_$P:'Ynl'y ,mE;bIMA(k|l,gkłVW͍Qz@[7x\#럲xYzT'@'|bx򡦳܅LG^*&v;c*pW-7(&#HgcojҠAM߭(֏TuD-t`<)S÷xtqn?WE>5kiݔqdթ\@`qΞ6tRJQXk)5`(LҤcetB( i֞*թtcs׺꘷M6fn3)ts8p]+u6yÉ{i$\P޷0a c势jËzhp4w[e"<6,_ũCRց<^3Y*TJd=4U"SEk5N}Щbq4LO 0If@.+=i^GHr?OwjCe(Y %K`3,Y!C2bh8 KRq*M*X力 Vf ^}MA18u3,Rxe Iab(k~9<^^rbut\3Vʃ릧PLO)28h=hQ@[*Oxep&#b<ڷ*\r;k7ňhi஽Je%pbx}LjiVSh|'ǦA'bݘN) ;j/5IY2ho@7 t`*o +.|/L| UGj()$`ő;: |ԑ..)emsexN6αLWpܑej5D~dB(70qW`cAuN@4?= dlgj8wW^2H4x9L1+9ا.k+6h-լm" 涔)>m"3oHݛfVcd>Β͚x$EP`?DJs@k6<,_1-KLfeh hOcXL@O^[v_cM?4g%" |4L?0cr|oĜlVciadd{5}+sF4nmZhb.u r P:ކNլu.RO]}W`P` t4'jH*p?9O_αZS8ָJUawLk-fV!ǩr7̓S9$*Ghf5k1o1l*; )qV~v% 6/ϩnû =zNS1 ψf4hРA  S zN*Vn;cފ߸[G:68#$rx;m5YukۖQ[[gdY4)G~\:9PZ8. =@5u. M~/R=>cD+dwawP zHDz,Z;V'ƽ {B`6Щ0.9MW* @ǷnpQҳ~x]5ze1lq4FZMRB|d%V?ĝY>L{ٳ_/f7n'1\3Va| ,ؖ߬ȤLefި:e5:~- N'`os ;qG{w5|~T ^ɋ@ُc&sxMi#-ɻ[Kr$9ۻ֌ee txeqmvd"%g7]Ig,]ט͠8cX>V7khAaժ8 :Ш:ui%zzF]:"U+=z8 Sqvr20**8ƸFDu wܜj™9}3 w55i3@j#Wik#.DNA?oLX6.E(~UJUCj4F25y/ A^tfe0f&?`!D&iI]U f-Yfom*iN;V}A@BSvj+h!rg#S)0NóbJKcqw!8X9ɳWgug%tO Һe\}gXGNWEA,HsAJh%ȇ[)55N|ET[5yZ2Y%S=,Ŷ؉oUd˺'$Yyf`X;Rο/Hzދ)8,:W8oaDGU5պݺ=5tNY2-aDvc4s\M]0iu7G~q7^ZpӃӴ&[dbqN6FRVZczpzayAh44R~}'><)>qZ!{>[X''=_D]~<$  esj{GT$898tk W")\V[rtqsgq[pC_# 2pI^AM/*LȐuuM/I TZJ>G)Kg[wԃ-uym?#p~A+mJ Yu,HjKʔ5j% ~L2Z0J//k:ޙxck^?y/B\ G^8Y.z x_=ʴ`5Щ0J4'ӌG2A̴dTu E J!*zc vmT8oz&ܴ2fa3l? gr{#y[i!30Bdg o930Bdg`'踶o xKXM%m$̻?z_?;VH$kLiS `-7)2֗ "+Ce{vD=~4 r<I w֓n.pטfiQ= .͟ڗs2*.9#\>[~A&K??c@.SLK"fEgOfTYx|.Ce/Sq~X h~jJŜ䟕2M'!2,PVl*l`駝kCUar%wѧt 8祃&apa>UzA lC04G 4G--ӄe{Z&7OդjҠA>b ?!0ґW+A+ `w?v?p{NgA g=`zZczvwJU}ȫ]'O6޶e71GʸV^Om5nnZ\^a g \Y/>ݫhg=甀'evig=ɕY%eᬗ+aDd8뱱.!s[]fb=z5X>` gJ,Ŗ鬗jN=8OO3?ҧw:q=Β:Y&V3S?۲P;=DGAL4;?KJ^ϥE-{:kLYE)CRtvgg X<ӗVYmnԗ61#1eV\@5UK/p5&k+-o=1'X:CaH]`3 t$C.u\˻hz+,ݠ~iX( 7׉k@cHCfw# $pZf<Ǽ#:G ]6yK%5l8=I/Z6~?wz#?`W14k$gX s-OQ蟾NspL`8&0O|AUUO!K֘hc*H@yNsy.ˌ@?Y!Os""s{;6N\9Ci,&jIۮ̚AT.:+±Zb%OBfьDӓ// 10h;J ¹gPq"+dֵe`PcNpsYhTu$e(B+5p6aXC\pd5NBDŽ 1hG^W[ ~`^KP=ׄ̉ fcUnX#?-N簺XNqjS@NM_bnuSO7K)N0ֱ\3K@`Q9֬6}l V4a `1āk*+j~i?l5VH-'}\m,o~XIX?h['p\7]ݓz}5l1q^#C4n7D.Y:KJl'o$a'y3Pڳ1[ ̖ DehX.voҠA C ;]˪]zgS?N59\Es??bb{|W 5씫*=5%v xq=;T]qm 2ޓُB֖TtݽD wD']kX YKTD&uI[JfaMfuMfV16G pH6T5RW04 : #h<]|f+Y͐UjZUaiDt%+S J6ΐ+ ')_,fWƤk ^nS붝WbLrIS>*%IaO3W&nr{<왙R 1er7 ;h7Ev9+<-yWV􄟤\jHb9KIn*)OW#6*&qʐ(]I5 8R/BRC!YfB "G rd$a: èYK-}zʺ #nW 8l2#}IxNblǪAV$gszY_ L\>Ē F-)x<FzZga3l[ [_joVNdhwo|$B93jLkV|p[Y q@HVtƀ.MץI?ՐA0jX ,5΁1PR $2jv0Y@./;i8wވ:Lrv~VCT  OHٙY =S'R C%piP S?ɓ9^% ^[ˋ!Wu~'/+UHX"鋁ջF1{W'Z4o@Ȳ5(ߑ~zIJ]7+,@;[/q]}ս } =*.(#ҥbm8Yn}ʆBї:q*CXd w0ZI-U("׎UTwHo bI` b>{YPPc-,$HMd?rB_.t,"e,ve%Jr,PVY Œhi[*ƬyqK= 6i#./x֋#ߣ Wm)-OƠ5aFyН!*/~a ]A_ o{Hk~Ǧ]XP3=,XǕ ]{v[bҺc̕k d=Ŏ`I):Y˺ \-$?})eY~[^+&Qf$yuǣ>¢]FMP/%'l1P>/]|m~Mhw?T@][@3\0jdB~:dIOavZ/(Vk6T6/nH-mQy| wa_v`=Yl'ZCM~_#o `Fɂ- hl'a/ [P ^u[IV#nX邳@T>̥ayf99abذI^VS2~DSq UyL"XDp]-Y3=>Lt7>s5,FL53=rrbCU{ae$;S^"ZP7iis[H""`a I/okAЌ 5fg u iɶJeEÈ1u#1nӡbB1 =CS o\n~w_UoN@"Y"J|~Ha:6,T yd\$f8*fJK B1#Ubl|_!*fEfo11ۻ(f*,D(OUN9:d,>c]50><}C;eG}2Yg|po Y)ZdB-. ̼N13֊+f6*fD;_1C1;Ŭa1Y|Ne(fR1bU< 7FUnR`#)Nþ\dIzfmky7ӼH2 ɤY3[, zjSN(far롘}:m@x;i262'4*3b;ϛՐ᮫Lab|uYn̾LVC=2e]vѰ*֘TN8 -]YjY,2oC13,{~Tڍ|Zk-ˁM.w[fcos5&nr3CmXx봿u<\,( kKÌ?| ٳ(f;P8k_1m)f64(t\{;3 >f\13ŊSP1C>KX13t C1 >fa?N1Cb}Jي6|̾ ?fTzEX4Q,82QfpFYcgJ05׆&N1=/8/=$}Vr ]®,X-D%.*f\6O՘U&MُUB}Uf0PoB}PX1/Vl ib&FoX=UpU 2Hb^e0jWx̡}Uӓe&p2)!.ҒhSg2MN! $IUY*yٵ d[V)5eyr/NCY YeX pd)y/ 4Cˉ@/4@-dpzIQPyf,}$%\Ԭޗg#Bz׏WXđU:A8ytPy^2p$dѵ.Zd|P_rd__l^{ ."@臟n,)Z&*?[O%o6XBW:1' -`MFL1:OT)A[/CUA-0 $K\ꇝ&t'W>'gCia/6b!M"Z$f а*鹤N|7LAԍpjK*G|un?rdETEK,Gv+Y}ZMjb’eD*igU"6earJXAt(Bt^jՉO/UI:H6H@jM|Tr(ϚI0/dAv 3wە$7uUEk(] ~ߤWXUV.Dbԣ`qX l|( 8czȌ/t7v[ya%:@O-=ɁUj+rNY@c}lj{<FOD&54TX.] ]5jz#KC54d&Ia ?7G&YV6vl$i 6 go.(PB//N!/Œ5j" ycpI8_XMnI"h|.jҏCM鿊|r%;RtGz YݑJn2(;RYfytGBHH%ݡyKHWfܑD1oiiI߰bK^,{}'5E1,WКTӹ;b[W'SkmwLdx*$|T$άS+WKDޑ;˸A/e/O"[*?5S2;;ZM8k笰qtue`_{fr  \c6&z6Αb=e?lދ&:R1:S,K{̀Gf'YR9Иde/⯶1cʑK 4u>֛=բGAg1VTa*zMb/?+bӃnbv*SWpSF8{cn@أl *tox(cI2|¦X30Of<6Pt UL1ovƧiabv4p=<;w>Wy4=\n[ 9*?Y_?Ӻ+ebZR;,,XWBKZ跕LyjrObk5 M!zXR\\jXJ\<#^6DVSdH}cn`[mO!k۶KX* ,:Y:3h#N,%e)AlK{H:gMc :/C /1pdVk/@&_^ZMZW jRٶN D^^cvk;~lBЙno)Hr_fIpB% %=&,STikqnWK-݂׋@́W8wfK[Ws槇,uwDˠ>U׉XHD5WjW͎cNa,]iڤD3<.ܵZl$* YdZgIz11ݬ Y6|LhbnXFO(0Z8ET3\CaNn98o6Ьm}^fc %{G+LF]\7T+"O,:(| ~^}3!r5VSz@s}{C܎v.lP|Y4x4[hסi5oRF5f 4yTBeOMSytw Nt&cۨSTx!qeIBfT ā'-(TWH\;C*W cUЧC7Ч>UCT'>E?.Qq{r ^dwm>aNF(VAv+"I] 80{kЧ8ϡO7 }6O 0:E }GyE]tWvj-|{K9pOs^Q%:guWxEq+WTJEkNKir4ݡOqComSC `Su,>>?J}jT[)MO }jSC|Чޔ>FvAi+h/ /ڧX2'k-Aʙ$UW)"B&${ Jkj1q5p2YH+S"}M <'Ӹ8)qRl3+_6l,b R.R\B_$G68F#h|+˩|QD$T/V?5W^ܝ|> SM΢ {TSOL-S 4٦z_-l+lZm9i~&Qmu`)⡶#RxTC1 Cez9j@VF4.jCfVpGjU uV,\(]j&E¿)'Y/7VyC q3oȊFXtq'.|_yP k7ܘ} 7TSpy̡F~6՜L5!MSMg|F,pL5z!納[ sF1~`huoM5 NkxnTսӑVRUU6MZJ[zΡn`E9hụ@9Ypt .`Ig7h ~ ҇:Oʼ2ϬOKi]feHPg&GCn73,ךJe,OUkZIxnB[[@` :,F`HAFyoJ]h"E`δ)*q8 3k'Uh#Ca1c cs)-'?Aυ}e_P׊5c8n@ (d *'pIle*wQ!w^;|n}j> pS/->}v}3sfW/}% ڽ.x g@`=f&n@}qv}֬lݫe73v֬(hu֝.k%} }hS8CB}J.ɨ!l)Ukc-z S{. L?hyűW$8cAs| c`;ҰOЧpCzo=)SSk8wk68Jh@C3>43lG] ,ƭt)eTK;*ElίQwC*ʔѧL*ڲPS{)Ӥwf>T(Yԧ  ¶Ч=e/S"A62IwEzӠ ya3n+cѧJsi/\/MyQ{/./a/2T;~yyxbrŢ؉/~ P,`5s-_)9h5JAini Ƞ0Rq5GZs$G04к,BErYQ}$4&aeZlYaYLY,O0,OV&SVBٞ0ESXʇvhz&Iٗ`4ڹ gY(vX9Z ~0=袜g3-4<Sl0&вil0h(4/`t@d3k  EJL[yQ3/Ş=c{= oXiR #=Ui=DZs)2H4NDT8%4fV:WY6X!$8}?bN?؅OxG-H?3eP pabɀ|D  zX@q$G85 J@6jKC!MRڞXoTR;j^¬`zEVni*UDT{fh9:kZƗvIe8:Tc5nA]V/S 9a ]9y暇*뚩EpWbyQk>U.r%@葅uN *IXR5= =(7u k3Dk跲8=Fs,]zC,\3E+O8i≭#Ds=,$ّbTORjrJ u6Vrllt侜?X Bhj`Zr5`zzyFUE(&\$pǴX=@X!8E@4[K8@cul 2 v;枔!AZ-ůu1Og8uuvwdVvY+̒-!D̜&ŘL}289BЧޛ!̪( hu#n_ L}`K3ZK)()[ } iSOEΔuSWwSJ)@s_N Ǵ3RS#Cy 7՞!e,f 2b7 !&NtracPyLnZ^C3sЧ8NЧ!n`Ee?n$?@?jҦi҃n7B@" U`EpD9Ŝ we2tU5ygzʺ*͚|zI *sN&AYQDgV$ <󌧴΂0y!>M%7Ȣcǂ)o{궧Z~S~xo{giuݾ׳8N Kv?VYR_T[hpO V~`yj{M)6dO9q=Sg:/L?)hӻjޖMd6eBV#Oiʊ|6מCtޔxV5ԓxԔxIzN}HjÉ4f ,V@i*HESO)}=7?e_O=7hSyS/eN=_۞ݾy*0}S \luH^S/2'VJe}Q1n-XBu'y|¼ _ѱZXXɝ7 wkZDq 7xL-![]KY-JjX9&0#ǀϾH!^q횜 R5̮7 +f!ET? 2v\?znѽ7*2N.H^ٴRH;8wy—4YGCэ3ܮrbzl__ݾLipZ45!B2:A^BTSqPB<N ʟLH8󍫎/.b]1wJ2TqeNEЁNr 9Ny;R*Pk %-RZ̙O[IGF>J=Yb1rUfqN7tno>4m[UmUc VǙt736ƙ~-oMɚfXô13RU(1?_%bbJ)kHľ[@[cN ;22fL3}R~k kO;Y"麱bzpfM,N=Y)7n>,3:Q,=h7X>p+btn c]qթtOtWu{4v9c.>)G#]>*ᢝ6߆WH9|wO:;m_# Fģ<;HBvIz7 Ϩ Wy^,wEA$WnqkN ŭ_Ƿ⶧]fՀaՊcZ<n$jVY-U5 <^;/XesЭw>Gͤ.ߕRl-۞bS*S̲wK*S92SDP5 )kN1ڞڄ=e;\'yTPfgO.=uTW~yS߳b4:EasPN1Z r Q!tFq4Yc Ǝ~sEiIuSϺrŘ"qY*8I~J'Hvn1[}SB~T9*COerOYC槾ĞI+5nCԳLT}K~JmO"궧^ !};,joK+Jv^ mV?`{_u^_<ܬɱk_+TU6 ݪ3zxNkG0pnHNNn0(;m<(tu?+'I* .m,7o SG5z IwㅭsSnh.yZso9#fm%0p}Nwjcg?LjĮت2VҳJCjPzI1o3L?yS*#S[SK,wq% ޮS=dqJAƞgmkkN0-8hw÷"T4՚@d>mS"Ԫ@ 01VQWf|la%M;@/76ez 12?ͤ/j_ad6X[.LG횈LdLnՉlq:YͳD:E(TthQ*2vWTKN Sȇ H'n3 t8IwI2VL5ͤ!+uWW~𑽳on&YH1گzeͤ6> pL.l7CoX] 5n#nW1&mU8b6 v3_kvS:OI{ xv  Rĉ}:"Ӈ¬ZD)"m4=% Ca+&l'@nPa=ۡElCʗΘ4.":Dkξ(;ȉq[Dcŀ04 i`n}2Xa؞0t=_ ΢uMw,D0ٷDh>l"4"T+\s4=WQ[HAF$dCJnaNN+Ox1^L]{1^ 'H{Ԛ&쯤1U8 E>[Χ|4:'tȇ>j|W_puHZ>^x@I'fo&eiT/!WARS7MN7\Rn:b xQ_ a{%}N.r4I`Tw)o jN!WuiTOuQ]tCXVz1 R)ìۢ?'`cth]>Dms H =4$`k"A!:n[W?o{K(ޢ]P\w[Wvv$UCI/̼juF\ys=iHBnF;`cˉ c۞z=S%n{궧=s?={lYLk[<۞-wS?D AEIU,tVS'J-ĥG3Qk{zY ?1{xR`V>IEnβo-4hΉ۞z-~궧^xS^Ǟz?5bO&u}S?Gt2Vr +'zG숀>0=c6/s>1N=#e,abJ4.n~o{S@{͞s=mA>+~R[!tiJoͲ4.T6辵x! :?oksRL'J0b)E&{neŠԭgʎًA1O[v^\7옼}0!/[)T_E@ "BZd,P* Jd,EMBdKc 4"CZd(Pl"ȳGq$%?P`«h7ĨYݲzlSFŎDt$ֵYM>m72OPpD+Y ){֥;fcl@T-k5[kv*nZv*j4gXLa# Kc)ʐK>@GJW"rR5ILf_ %͙'$``TTo$'eHJeӝr˅$PU 7Z~w목 ŨˢgeѢ;dġd/d ^*8F>!0'4gOl:[-yѢͷ]%IUWZܧT:)ц.+ k \kت_LZr7^'kxt4`%ouUANu"_ ^L8;׼~^J9T[鶷)x~y/irLOi;MQЭ{lAhC|cʆ/.%RiZv̞q;yVy{(7,"axs'T=M߻NLzt]HuKunu4m_6?ҔI3E&'CgXnZ(=,JP|I2FSTґXU'[P^=}6rH,']19ƀgIߦ1WR=g.6z%.UaŒ kQhb lg, O-+!)' 6P'Rё]:ȞjW+{8pm=[qѺZ7|[NcЩow[G)p Ku򏳸5 2dl"$zjrA@*שR~YĵErԣʻWk֑2 Kz?ozm{.]4ػwQa"Eý9 vsCXW;Ę$|:Ԙ|:_sHzz Rtm,^@5i:A] e>]waLWle WhWlRf֤ofq&_cW-6Hid!Qڜ/!n-_6F[_@$]$T t}NiNKv("Pj'a^+g~\we ƜG ܳ=0.f_&#mrn?$#;wykӤ`DDT\ksһ,=ԱF0Ga{w2|_3Zm{\ * =Oo}/>TY+46vOVʴuu *:_eJBǔ;R@QA iNa8'B uخ V0 ,!@҇A53N^/Cŧy?75WCԫ;/#bୗ*^:p5DN-+3O]:Z QݷQ4,CxxFs$+Um g4XV>_r.-ecW'ale{)QlHyZg|O 1 %jZG(kKues]Z:,/E MIׅ.e+ߵ NX@,IPU׹8KB8H l$+ki=Ҟ"C%0qMSW1*'H\ToP9:w'A:?1 #ʤ!aleBPh[ qfd'?U} \D#??:~ 7~~j姦>g߂tlHJN#\SE jޚZ>;?߂r2ԟSߥ ?+'`= {,H[=PRNY$qͲv+d=v$"\UlL#aX4j`ӴZMq to3N~jvԙpƏ)^up~=~jfkOUOe'~S]hz!C~J]1?UdZ=θO7{&C=/.ecHOnէhv37 $ɞ$iSޢ-}[,zwm6zbq }'΋uƣkk'g[y,qH*Wo%zEte;y*@^aQ`0RB5_Cl!ѣV4b0W'ٺ ŷ5-:[/o==hx|ecb)1p,yfZ5= g)^FFQ~Sjyl=== \/9c77Ux'R7>| αn1f\T\?L >W[>UϹ08#/j*\Jy ap/?~&+Jm͜@:u^atp*X܂ϔ/`lYD;V "sLOLa[k3Z e#::h ٌ1U'.Y_<æzpjO=KYB~_>GvaPPć4y`4̗SN?N,e /+СCC~<RʣOl:ϾHNcu ;ΠL;*0;CqbS67 jir8KiX^t*#][)Gz`_S{o$-k*ƭOCbpYJK";BV-cӸ:H"c3y}m`iSLp JNu\X3й*0hHZ:]i*~h@h{A&n7;S2¬ U$0TpVAH.<) tIz{??#ya6lK_-oh-B鶜bV}˖Jf`:kƣoSf`&g,%V78tZ)UERetEcMlіDa-XD-|(?$V O~KL(:֡XܲlgLG"Ng|޽vO+pg)j@#t7ƃ'NѠ.4AoA-A' :!8 A[irVo4{z pߥ-K?/g.;7T%kٳ4ldzf`yӘ}gg+Wo1ͥjV 2$ga SLܩ=Pg-P7}ȯl8IFyY5R;}]7}4AiF}7 )4}W&8:̬(ұNOߕKw f{p?쩺lsYlN]\\7]:[]]j.ZxFiWKj;͑({n{cQu[?`BPP'5 wSnͩf"DDzY\nB$p>L V"XԚ4DC&ME' T(` !Ga1:}حިdUlUk*L@z~yWoy >]4n{B'"̵f},ÌpZIKV”,Ӷ<<=\sl&iF{˨b- "PI52nx_\- W;A,LRMi֯$:,aiQAG?wS-g?{.EVUX*o+9GK-f'j:%KJ%zF0{FJ -]yE~t R/ MX^-F*ESY ' bvCs==&N }wDwtZtln*:3uK'Dh斏4EXEZѠ3u^7e".hȱb:47X2ma:gtt-jطA80Q?|iN@UwR$PUg#u?rض|NHve"n詣*=e>P)3 ].jeڲ`.[k h r*{Ռ<4$P_oxUKmFRYOA|NjѯNG"S3(El{[%o: tc 2)QxmP Uo/F7@ht^Q_%Rb8'}npړ۟3n?yg Y5%>zXa1o _ˊ7𵀼9fe@X+Tn3'J$Oı:`@`#X nKn |'}3 T-ZMWS"p^RjPk|k0Dsױ i]b<Iyܦu:ζ9PE1f7Tg{cU1TSF&73f7 $Fl8% J5l"ԈQOw٤KK_jWbrOךQlZ\<O^LUdĕX[⺬ݼz}I ٤&fo3cWtf‡&KI jޭ]MIm&}l'OF@Rj>y G?MoҜ00嗰Q, E@NB􁐅ٺl\HkAƲ)w[sW/B ]i!̶cuhbG]5Rhp\s; ߤsIll&vzqwۋ{#96:sW7ί4{PY~^G(Y?KeGLZJM}369ttE>rȦuvyGlZWnV雊ʁ}\C+B]'VG,M]5x`= sgIs@Ȳ=7ӥևݡ)".k#7- g8[@ 7 Z65"*g>VMc+[=ñR̊L$:kh8if\B%3I\h>UfRR[Uu{I=XjUVc0ОPX'YkN3n/< X+p<0xD f %FhBo-6i^E*lMjo6)Iq6ie@leUܼ&l7a&o&M& a٤4E%ʚ4kPU&2Qᩳl2QV B!uChҔ\uؓ)涝wHlDo A?#߼ ~ Iq❞JgUl+g3 z"2T[IHPժqڣ6]if*א;2(U> G7>I9#&0UX[N,ϧelN.?qlgsSƤuz~*d=\y4lҦw>NoTUzT@qϮ^5s2TD ߇'xV-~Rȉq!≠t>m3mA7ڦE(YrL8hdz(.5\LXx1|tw']$ >_Qκ|LڵD ׹y(- yu/!Gj X*nF]ʼnVcq V{GbEktуŵGg>p)Rum*?6Bű>*k;-c]O*k ꩙֬8)ԡ v>G8Ve^;V,uL0QKܔ$K J ΂ۊ.k(bxJ:ͣԪV$(A Ip f5GiăG8kI =s6~:pǺ:>хVxqC}tVmcKY5$pDHg:ƶ⮵6z4D <6Xj*!fI _ 9 E\!SF[QTGY\ ݓ$HbjFϫزtD%;Rꖇhi O۫)1&տ9ho,J\Yi&eT'Е|>eTBb I'b^h hKh㒿Zm6(eZJf%r<ٮIk8#܀ڀ݂%gEdI'r;{y!zyͦn*dX+)nUJhc/cuƒZH-*T6kMɇjBΨ_-1W4 -[y VLv]C$e^% ;2Jd Z6!M0qJ:ЎA[rsmL௮Zx6.UCRU{OҴ00毖_5*毆?|:#I#W$b&`oPA;:9 8zwzUQȳG>A^N}3굲&BP)ziRX^E􈶫ZGy޼řS>hgIys ҍEE9ݚp^&y1bἸ{V>? _LqK'0n„֣~D?bF1vΛ|{zP3)-DZokΈkF_Er/*=PBw/~H"sJCń[m!H.+PJpZ4E?Y)4e @ZO@?#sgE;3rtc-K9lSw hiSlCTqWP"غqv|h:Nlwںh;ƈՀ}$Wj!jPUal $/W@>;T ->n%JqgGn@'oW]Ed]}h͡()|{ꑍ#=4b,̩ɡOSmOZ).~*Uhx/?*O==~ }1?.ߊ:\O.PS t}~jvZuՄ~jiSe9hrLoO)C㧞%᧼YL.52C~ʄ R:!GfOQK:=~O?]~,?50?O}!?U޽O.q`Ц6Y vt4U 㒡uk9}]-E] &_( }óMHB@Ƕ$$ݾe6FQڡכbI1!ђh=` "X7[ib$Wb/A%-e4# R#gVG1֗ϳA1.ɰŘm6M5üMm)IsTDMZ=aېHKэb6 &Q+Vb|o. 캐zxTK<;?ar# h-Hٱmʐe@Yk)!+5ɗe)'-5& 6ɪّDIaHLٳYhS<911꽧A+1Qae93K04L_9ΉsNt7f9(m|s<v;'Oc7~6͞n{sr'4>vڜ~N,Y mQ/(8~=!DJ62Q5юo":t4Pڼv&i%~=hI6}} %nZ9DV=?N4~8Π(_~^coI>֪ :+$HیѣW&\MA>eNImwLIbUQN[1o>i GgҤ܈ ܹ&i),.s/ a2OIxVbV`t^0}'pjg~~ѭHQwhj l4>5$_}cy5]`s[5b`'P,+s έG-݂R;Q& zl7u/tA+vt$x:nͧst>L IAI\@D|'5K72 B#&ogDj?ۿ_S7 p %=[ H aÜِBp!@d2(}pI.V9.IeAe8uX4Då8%u˫D*!^RHkN'(#ئ[W=LHVVC҇fv?˅Da 4x^fUEeVХ.Y%2vcdB' ld^}6{,Q"j)]L &TyE]8.gXՠ6'z+[-L1aME zm`[K5[Kf&mJ,[GCT_b-ߖJ[w %b& df,$h㖴Si w,kv{2cbj5؜X4Z|VʂwK%A^D^jٍ¥tXx+G{@PL |B$Porق6 X|4$ps;TN2"%N q m--Ym6̏RX夽XFHbz_¡t#}(GN7Eɽ} ӶÆYƳc߯]Kݱt[0,;x%Xzpݐgf0;˲\R[M*^xqLf\ŷ%?%uiEk[ܹ&6դXr%U  ;ĦS#mZōЅ%ī7?č ||zs`ljmWMMͣ>jzԸ](o^:=&'$~$ ePFר1y1E(~}(yO7ĭkiUoinK"ϝ{6N[L4Dj $Y$Gxll GyjbGliK@wy5^ R1dbV"FSU-V~/rǥ%D|@gM%B>`8u=mpNEݩ8)ڝN;}_w {^iüs0CZnO[ NYa1 > 7XPjk((%n~P7C3nY Zzk[K5=׈[OA vl(=,Â-X/l6./*<}+&ŀHïK2 t5qê'@1xf˖9pM_ &WSkŕqdZqd&)ĉ@=$ϸ `+ȫ_fPK ?[>bSwVаs`kV?t$:+%:n> ۦļEUd4S|&}{I F^A~H s@&IC6Iχg:t&{z`I?=fM^_ olҫ<[;5%~+ #`o6[;l_IMj{P\MB6wI 7&,fcZ٤GI`VpQ+0"!Jc0 uP87|]z@Z5!`IN%3/d9V],G_KΤM3šP&}fn6>&l/ dݛM.-{-VVEHN*\kAhn&vJL,KI``!Y \+ҦpMYں[3`Yh;/Ȥ9o; muqI7lRManߤdlҿ7ƯL>m%B+`۫MɮnN:gn.]2LU] oBɶ+_7NHQIT: E4'j閝.Ph9y MXv>%ZUe"Բ}T5@û\eƤ[)PbXH'Ċ]u43ҫb]8oNj]LJ*n%PS@k9jE-$OJ?{nw^ٳ1nz0]AC:@"ɶV+wcN=oz,G\ =oK"&qȔӼrD۞p3} ?F50yRYРw^C^{2,cuN@Ƒ78;Fp'ޫF ,>;[8qr!&?rG>-ʫh0pk)X2?!Rfgٍ2?{ŔDfl2[zuisy[Q.M'y _5+%[G襐uk `I!;W?۲j-qXY֜:2p= ?Zv@*/( od ~!NWj\R|5GpOX3(.g;*0;fwqFTh@WvrҨ"54,j/_:C`_Ğ#=IuG3gC ͜?MofҟwḰL81'$9bHgn⒍ 8W[5PDl9͢ģljD2q:?X]/3;W;QKCXB]x`B〳j݌=ZOP-wli* qچ,{N; dS/b k|g?slx{?zy8BcvFv1_0=`o V=^:{M>fW#%eH}DWYyW9⍻Y\5*嶼I}SVCk>*. `_:a-ͱSl=[/e ʋ"zEqWԔ b<5ݶuB՜Ȋ7cw>,D#s|K(=/ aR\^nD9oF*{'곕Tag$1 |~s9IyG-wЗ'4Kg# U 94P&Z"MZzɛҙn[E2iQVESr1b0'(FLRBς.jnHAC%)RWn#T:`Sv]bL{gє4{R`-ټ}^#o_dc{5a.b \+Z+z;64uUw ';pZ|QC;$kV`rxRVx{f'ĥE9*ZSD9( c׏b/,+O`Ei7ooOzOؚvj +OebCH԰O_*u͡5Od^9$;({lg`߭Iix䜢{WiۜlCN;SRt`ud5"oYL)%QH+|S!P;zH5o#o^' V/'vδ,? Orm,!D^RJJd7Owx_IJy۞`-%'uՇ/C[y7k\~cJEelDz \__{a$N ,ڂc06 å6 z>tC`^N'xUSg 0dtٵ429GQe-"`-*DZ#mg2ko^X Nv‘1U`67(ZN՘BJUei΄%?WMƩ חٙ8ɾRD؝i1,i5~ODC t {&j˄{S&woFO[CFl漬1yw>Gbe|| xLԬ.G|)xJ@=a ĂHi vtd'"eJ1R첲ʐ\nɗVֹ{Ê:R)^"kJmGExQZp^ 0H>Kr`;E:'^-1`ZH:ٻG( {i"Oug"})Kӊz$8T HV+PR+/Ҟn.(lӅld=H}stm=#5BTdB^wDjT2UL}#ȐʁV{W)ziY)uӿ+ݦZt\j_s]jWb1Ү0S\|RmWvu1؂ҏzH9s{AaEwCIUnzDekOb\o`Nd<9U튊fWnUlt$JqTڊ՝j.T g/ QV'!r .QK+?EyY*G,H!D½V5;~NB5E9a΄^?Ykj"jOT=#cD-Dz} T$g$pB8-=bkAsF5-)|dvɌ`ԘAӬ!]0ԮSq_uS}tS S0pviJ YGr~z9_Oɥm+¨.G~ӀT0Elv107ϻ}O d/;Sc]^>0=0Tc'g9ays(GL>fϗ#%eN#5]g\JV sRIpV_f&m&}:yŮT:"6uچ 鎮]۸ĭJ2JUmV tGU>!tDŽ'oSƨ!8/ GFb*OZcqFj &Ca L5E/ IG kxPM׵Gէنپ>6=͸R}qQuBZO:uj<iRvdy',G!nWvy]uFj`pxQOâSi<I/aXyYDejYA a/ͤ_LK** \˅Q¹ E[&6Q/"y{9܁BaUǬ?OQQL% p><; |( dàvM~'Mh/q/}~z|z22o Uه~ ^.u1.97OQ{{Qjr2y%[n,f^fqE8c`JAtp-ϺLvda&V,_`$f ɿoN#FH* l>AVX?XʠZ0!.gmP&`jR$fpO[3HǙF.UMtfZ` Bγ*aWwjզN3si^7&0VT}rYfS;uó:bxTwi 5]B!9с;yN#:j@y:6o߁P} vJi@=TT7hB~ۄ;B<#_4,ķ{30 o{.\KAlNus(t+_z"G|Z[|lC:4'5M0ҹ-:k_WY6(Ҷ*oU_JPɲ9@<ֳÅֱsȰ5ִ4TJ =BsxyGm݆ކmavfzfߩ>KJhOc%1VRfR~ mQWB{ßtVS(SW+H/RI-JhDN m2S$jzΡ.K.* iK6TB;SG4)^=p܂AF/9(SG j2x'yo2RuKhPaxFhEО'uKhf  Pb.E ʑQB[}(JhKpWB[]>*=P ?|{x}KHOA$ڸHOOH _u#JO?6SЏ*X%ASR8ʵ5wCoC̵123xx!' +=(xw|ҭ܁Xz{lth$.ٕ$ shi;i)LٍދWI-1FOtzWn3 2)uMf4]\.n"_V!G$RZ)vl6SJ !Be\FRmdyD0-7\\IWEL|GԟAr&&$Q _U|䅐B".X(zv!ҜHH5zH1*G|+A=Hi(gy:U${QW5oj:Tu&.ghDP"}?2W\b߫d ڶ wO {Ul\@Y8"+٥9*=7Jh&fƒ-R^;d= :UFgn})y£!B&(ick;5#0kC"S^# z^R+WQKՙRVU+J1wɣ{ eYW-(Ⱏȩ[Ҁ⥔^Gc_d Mv+j.]vOfͳPS is(G'$kVg꧶K~N^$!b}~0>U=3U6/EᫍUsscy}NU_ Z|Зk:WE<=@P@@3-DY4K`};Q[O3eNSIuO3tAMMiA e)'1UM$a%nNC2ԝ9h*y _9s, TAt W֪`O9#%p<-B6`qp&W5#eZ54k{g/e(KͤuG|/GoN^vmЗV^vhGD={ OU KNK- \ xI6N%h'&;h$zZtNߨ)k(Ya(I>y>G-J*;`ˬIPk qY+TCim(m6NmʱGh%rZ@]mT|BA nI1p୯Z#c2F$w0qvN ^?j!ۦRG1#j<([m B1uQ{[l @ k8[.{$W/ɪB/AZu`Us&6%_)pln!sgO 93@ʈ YD S{T@>*<CY&NS7Iã}"O _?ͬN"s'꓆*{IƩz.Z_^׿oh6~ &V8|ǣ4xV4.*<ǣ԰*\bQ|dX^0z90E0kIuJ+Pq'ML,v0d)T&?(^^l8nmZ,װv|y4WZvp6g`l.5tE\`?|)pn={ #/|281KRcZX8sp$ʬD&z3= U1lˁiV񚻟|ºmeݴiM[չfx?OϚYax"b02:z.E\< KsxՔ'LPq n>mnyfq;^` ˾"F$ۈwLRhⷄy=u$rz|'%>oh乞uRwjyA:që{.bnÔ -wZGnzE[Gnv>̤߹ͤOdܜMlYI9gCmĖ"ۏ UJi4dlBŹ1>5UsZEGtCPITF}ѳpW IL>]qKBV)KTV[>Q^EHщ+7^{'S9PsY&IwڛN"uI7=7codoh+ uͤڛȉ+N>|"H_[z^QGvajH`c2K3NJH<%aNHIWP056N+=@6)o+:'uaeUZByIBy@Vo}6!'摥r6PI%݄W,'eG?=#9,axhذ sN`:PWؤIAcy#},SgC,!~,x Qnagi;f;mG͜xч%nej KkXF4]WL=}h#ai3RYjFډ{>/LZroѵ%v upƖ@\UT,h yc6?@/|BH[d:`UMF^V* >:>Mibˑ}7T "ywlc%K>(yJ=łP3@o.x!Ij~=alK LsN D`;^ke8#[E)0e KDd_lx/=5xej%3Qp0== M bh'@IG Zp: !qvN(gWiE)4OYb!į~ u$GcQ~6v5]\spRom LfʡN.3f<3{Tf2Cj.'+bYb Qٚ3^Q:Ⅰ4Bs_-삷ִ|4z_gZ Ay VA(::,6Sht.M,V N)&m.1"Bx"յSjD)74M]'su$I4¨Iab Ç{/xW),nwtG J e?q_J>p+pis.0g(m>( {$9s΍L6( I\1}"'ΆbF~Vu*MWsXqܓ|4q(&?P@ \ʴsrՑX髎{ۉ;j,UWݓT9%;/MreL:IaSB7ʋ-ۂ_EќfJhYRy-^{/&* 3K Wyʉ0ݒT+%s%!S7ou|.ʇ63y%61,-rTj}Ml,}o  |0FNNe潌[Ql~-s Nz4ca2IdqתU$tB Y}"Z wy.t7.ӺmPA:]2hc6sALjGOU*` _>Xݥj߼&I+&Ύ`L٩J:o权>9Z8I_ "O{#ӏ,:?_-_'ǫʼn`U6 "v5`v+Pxi GD6I!驪륋<О"w\+<ΏvI lùޏvȹ켑gc=OkrA nEr+-ᨣec~'cgb`)AyѦ1-h='FRRvi\sVY:.* >ZCؔZ!89|ԥjYg[,eJ}4;а&(.qeWuԦiSdCaC\##7lؑGGO &i[5nVb%+I὿S/8 Q莐:!X8.l"<_#ES_e ZbryLpnX[ej-j`:*KRCAr;Ų N(N-:`RƺˉT["๋nϊ)ipxו\s?%jGsW9 յn̶*2͑;Knw&]3!d e^ԖI{dQA'm †Q}צ"Xy_U HE-9D@MO=^u!wX³wqC=A! m)49S#Hg@cm# v8K9-U9D }p#0Gg"\TO븝nO@:Z\DX%r H LKa%MXp%۞z6Qc8KG4}Xt}1l4jY ư8|{5仺Wz=yeY)i픆+6n؍DH$_I+~ُ] C7&@SWD H})xg+V0/yoXA's,-J;@TɳcՆ$q$@!>#1ԑ'j[G@p]# L68sXPhT#D_4Yʴ%u^談nl=УʯmN7)iSŨnwm[4Ier¢ z& !;DcWDH+ڡF*®hADۡn; cŕ#v%1?#Q:K lyYG*9Z"bVD&&s8ٓ$AmǷj`+D`75[t*{q|sOѾMwq_+Of()5^oͤ7NVwgWAs\]ܻ÷C@F&Ջ?Wzv.z~z9L=.c$RXƖ@ToQ۸:M07aapz$G%\_#1;;0k'B673.s6jkJ;3E ;o3 [88a=(&$]Bf[vzW: ܤ;UdJ~DsiyM鿫j,"dݤXH?[d_M*WL)Tl5+u} pk=&T]E>tAsYi [Gp7xGLnlEų9H8 `5Cן (svpHo—P )OfJ8C_|3N2( ?C Ǒ֙^#R|I:0)EN(k |z!CTd#:4KbQIRG'.SIr>WzWb>%ռA;I9]Gbb+N^wJ^wc#d6K"yNwnfZ xcECp&CPG*NĎ9iUd*pW^nhOOAC0ҥ{ϴ!(_,f3k&\\ҷb22tFl{_,ɲ\E*  k8<#++&1/IG3SD{W?+k >0[ygȶ~`64uo|GtZ8s™ĵ\i9R&6~O<}ڲ) v]Pjur`U}*>Gګjz||l4]d-P(uÓ!#YE(>oN`^u(ʸȸ#'==U#VslIe{]/j7؜UugHwr_jMVZUń0-I&=M49h*ǫѤ_4d7 pz>Qb]#U,ymtcpX<(E^lqDWDhB8qG$bJ j Gn9U *M0Bd֩P'.ƾxiK sXt")t7ґRMVW"E E2rZ~J NOpJ `4)OnKcg{H!Ly;ܴ.)T{j㵍s*?4p "9ZcR Ea9R0mw<匸g# #Ŝo)Փ-/xSMKNχiȐwl9 a"_S;'P -REop#ՓkǙ4B5՘V;Y\װs16RX}mVըc=;j&rR9+ꐟ5ܕic., JHlr6I–gP:9կ;U Jylu܉3ʬKb0%TF}Ypja_T6:?͌=qkzA漃&bФ!C]QJNy&mt-QJ@sVA+<: nVAb{ 1(hn DI(h:qK&JBAW x$83S:|#?<,y] T2d:=Jc90= hR*y1=}i#ڀnӧInByXz 9sC|I~XxTVlsw*ėvik%b,]n:0>w&buH:vƂTe\@q6XAjFRQ!]dBh݋b)&wjveu.K[9Лph[I"navx `NCp'{J\2iҝi2f$N3~QbR($pF[C4519&Y\kYF~;hҐ!_*5G?"ۄɡH l$tI$Pn1G}|LռN'l%aUӰ$M^qo7dN!٘ Q`Mjj)_+M|1v2n/F1=(? O;̈́lOVS  c$\-05X^L2;Mn .S ܥHYJuUf@~=@I%uM^?l^?E=3G}\լ5Fh)8?*pUF3BYEBnykc.5D &,MޟPqE ڕէS5̌ (sv7@ΕrN$o1r@7S@I=k^zjm˭t6V tvL7zA6j,e9D`訃 =iHNuuPl,QZWY~Ty6|?R)1ydzHO'\%.F Gi῰SV-|HI2g(*r\ Egiۧ}1PL8ݥ:ؾCcG`Iц}"^ Ws 6yKaR]^!w^\LQ l>m Gtc],I^tY򙨩$/BRtx yoqyu"r~]e3EC9966P!7o1i9TBTW=)/x0Pf.HZ08!=G Avyw^g.n}bk0- Z5fؒ#yL*K) &Qӊ>nٰ bɥSuNţ#"kWܲ{'+p>Y/} C#?x4͋P& >B1I8#ϼ:HW&hwh.tGc 4Rt`D̕0f,jMR P 4swAɜP,u1\*p˜Ɔ9cn)+z:.t <}z̰Ϗ&Iǿ^~4iȐo-9XoRoZ](n)+q` T|wOy3p!'\_jm+h },k@{j ځߎh _7.j,X4y寪}Om#ywַFZc,xx= yKP\JEIֵK] >@gEhy Q"Tg+Wr/Vo|.,ٗ`\ S `;x;.hU^Sk[ŇG&RqF 5YްW NFО|t=BB|M]ז@M!.q&qouȐn*MM=0)dIs <:pW ^̡?gz,~N[YPVv2IJN$o\`tj1BSŤ7Qyg;;+!jY3F% GČ^]`Iyz TUCbExn`DXtQ%9B zS'5XKi|@m܃ؠpjY) slWէ|'Nq Z}q_<1J z~`{n=ؐLWRISCx}eMT V+3WU]Q`~e]7CMX]U®fc-ȌG)vȃXؑ0]*}8vRw`Aj gy;`$B9`_ v"lb Y`CgΕma76#isZ{!gߙuHʬ`;k_KmY ].kmNSa( 90 7 8@@  ^5tJ?XSUj*6G`9_Vli~92pȐo'7ʧfER0@f\Uf~(ŶDh K\ XVA1,yW8ε計3]G<aŜ- X 8;,>G,ڭheoAp8%ALG`S'>_MfDg5˅`xpR3K9p.ߎd\yD4xQUlLNq_<`b̬ZNN}lHWyɋ].''Ъ?()ouM\T4BJQ@>xպ?ۧ͗gdR!W%\Q3OUٷJ})n&$@~O: F!HB՘`"9y9,PN-r{cpɑ}V4! Yx(¿;{򬶔nJ](Iܙ3ry뿹WRUEȚ'(8"P|[νJyŸl\3li!F뚮)mEfa+nJOlNìd˞ԏ;oб1VK8)eK]Bv 6ÎyE,2RQcIZ$4Kb R>%QZtKLy3^YV@٬z79%"4B8' |;b;\p1A fs !Y%i1Qw7@'?;3fl551F6l| m&p*'nw&̫L 35K6mx>SYb%lR{$_W6% >5dWSQ, j3ĘOIwh+Y@QuN=" 9@F={F^Uw&4 VNlyz¸(#WP8+\|˝.2I٤0]د ٔ [3rO[>jH,VmzOVؼ9-ݷxIŤH?AWI|x 9m'iEP@ޜ[n (U|}\ccR!P/>2zq {|7 +9I:CO. t6j c#NmVD=vt@6FKfd1zFĽ=%?ޡ?M.-ʌ⃔b-vAKbsaىwswzx'B4$F4htd 4 I-4CjӤ#ާI4FH| ^)54KLJs  vXR,MVg CU#*Zp62ٔplJ˦*MqEٔflJ'ꗐM&kD Mˢ$Tr*^ 捝@ʮ۰n|66q(Vg俌I`r`:M«O:|z#@ L[@LJ^Qu8m>s_d].,c^qM/3ɕ+uzb㿵*p-2)ŀj #sM=DIVѺ+8EQFJ(X~.!C,RYLI%C.RW U}ĢBo#4ycV??|d-_q2<V{/@pE)ϲ"UcC@`^-O{J;F3]xi=$$Jbo ugDݝAIԫ?>a51t6WVk䰡 ޘl=8r.St,Nw'O.&TɭiXR(1P]n~DX<ַ;.1m nԈQ\!>=dvn7q'W[~wMAp,MC6vSQ9JL R$&sTb.(ۉжBQ<1x[P+zRn[xwSFscn\W|Caޢ&OB99p@jǵ$E:9Y R${{yrH?ApBvqA4{'zF|beD׎ Y#{j&e^]VRp"JEA2WXF~3hזk7Dj4$1>#ңw]R +|м3WmwZ1S.l;)t-SF2[jN Ȧ;/<3;=q{l1UW|Јᐲ%\E(Oz!<J9E0^5Zzx@9E|=6gۈxmƙ"L $mO MfI$_f._[ṣ1654qF7C-oi ^', ge91|iK}%ܕRnѠC8^̽cstsȷ9&&g6{(/ P/ҁ0=L%]]k,2EESM^Q 6(bta:{Oz(Cј(Jy)$3L'u{7e:d77A4dG!nM;b]L@gIr0#}sDLo8cf|G7MAR"OD ޙր8i5ɛĮCNNozdA{X_U?NnRCkwT ?dȐ!C^Q>vJcg0ݮSn7Nޙ2ݰC@49m?Ljir΀-sxnB`{s($~J&_7A`?DZnhP+ڟݚ6="8Yx7hea|r&f &c1ls9+s9<ʕ5l4e_MדNGęʅ;+.)Y~rR`= qZd[.bxs=a%99suah~A.MW ;uu:ivbS v:/H. t:mva 0Z$khg'8հ_UWBε:7>WPAvRZKErk\§Z2 bZ[s|O!C 2栛$ަ;yzPH(^vR֙_xw 4,fw{xaQ. 7rO&>xѐb*na&Ie4D0<~Bi]w9dPh@%gEaĈEÚi.k*`SkzTo.3@]9ѽCxz!_VC?~9†*UNyr7rO92ezt:<N(도ul5̻pᘪto K`RS?< nTG$W @R{jbnFKWNDo 0݆D!ԄRcg뱣ھLV䔧dV;'g?kaH_jňhޟrVɃYrV^uuK{b`9i6.K\.嗐†`MOXg9?}yh&N7M2䇑 WC蝯["?z#Nk{ϴ q22..*j:/vmҀ7 mM_Par2+:+ex6OFR10?\\5^p/ V-ר׃ ȼ]o[NwxO;_ж]RϕHvӴ.i/XRg߁_FYǗ4}I` p ȳ52"i^U,(QQp@5o"Zsl[*ƲY)k[PTbz S7B~RA>IFmk*X>_. ;N~-jf\::2Pƶ@V(!-^lCk xh\ޠ0#g;&pMP~4dOnd*n Ǭsn+?!#-䣨ә)Q R1P\EW}jGDx'֙@M܋&3kpWijA!$/sNrVB3zZ%b 4N. |w><&]`5k9O@ S1I="爭;("0FwU'"g9ԓbf_2Eor,kjͮy^F @("גܖPC^G~ q>[ .TC^&Wo4Mj:Er11O˜_f<` Қ4 \3,7;N:y%õNoXhJ1wb <+0W=? :zT ߠ(bx{M-8WL*0INo͛<2 |{Ln ,/O3 `ʴ1~BI'~M*CG, U~P.RyG|dgXu8 xine-lib-1.2/misc/fonts/cci-64.xinefont.gz0000644000175000017500000013013614647725152016134 0ustar memeW%rvvzD8s^$D GyGy9{/y()vUf>+f{ԉ" ;zhx?}o.袋.o~ʅ~~ Z4I7"ƃo?h}M~ϜA?w/Kb~of[qY]-NZEd\X !0Qt0;q Wf'x7f'~3Nft<9z ÏN,cR7cCH<cprN1%I/{p'54&jIO$'u[,>&qًl5^F^[ikmO["^#1yGǖpx`CGqqhTe#g\Řq<Sw|6w <Ƅ֑W~w AKȣ ͿK"`ȣ} O´`Iw?8qE [ _sϽ}kߌQӠrNuE^ߤZ4+!Us ͑Y[6'#o7E,דz%j@:z!$e[JeB纹Ts\ĺy/x.{)#\m7A8W1*ܻ9#Ɲqݼ9?A,X=/;xL#umFH츼;V|wdI%; ɶGH1xw g;3bg;so|;,y+TQ$6>I3?`ϗ\GC!e ۍ 70,Z3$l kG|\ϼ&YFfb;8,޹}@3Ɓ籖㊌ Lf8qņ 3XD\%ce_'4Փ',|4˘vջL=%\gc7Cسɹ+qMbS&!S"=^-̴F cfX[ D 'n>Zme_q8kHזyq_!Cw` {[p,>e{"`.yo5Ձ@qYF5Qk%Ubbi:$%s g3+9Q"{.ONC&®%6t%;OxTQe]9|>c ^L4[]!-)g<ԩ0]xF^q) 1 )kͫD朰넕`|q=K^0&k"rI 㐫~fp6_q=Pw8-R~+=&EA~cB\_|Ϋk2/Q/ֶ|.37uϏDqŚq.>4-g?I=KCk8M::ɋu۪lom%NrբVg1%R'C׷Y!<Vg:&SU;Xl3W{aC=VyIcw>Э{s9c: f𐹧I>\gfx X^,u;_Կu0qWSݾ,P-; u#;t9nXΜ3N>f,pfF|o#x}9cU}gm؛PպM26Y%ANj岖l] OH~`} !ᡠeX}/n?~IA0Apϡ?ԟbC#R}[ȿdl9/6rr6n_R3g6cٸ9"kƎ7͡#2*A#߼$GN?bTWϳ*bnAs")knqaFtB'5vspwoqb$(\N(n2d't$hE 7M6"U;$V#@ZLozȺc7DlLߌDζL{ZsX\Ω`{@5Pn:-j-N^9nCdlBgϩhbly޾ `9;EsT`2j xM )~НLp*^0,LȈjnxc4 ŌxAT82ޏӞ 4mmqXT|DyKD];\9w^y_ 7S}hz> /O#zq|ٽڟnu&| 7q ڑWaMT'l3{s߾ɅK?d3momtsS)*X7[oCv[CyֺYH1tE[}!|\?Hv #f g/rusBR| vIOhzWfDy:I2z1FAP]3!Zie۷2>PTcرx*k^%H'3mp37m@2L!Bx.Nt/Gc9nsȚ%V$Y"4IGba`~! RnZټ~`jR bِɱa*F̅JYy|y-h_F'a뛭ϰk5 i 7jO07bkc,E RCl [Rm%qƨ`~Ng)ݯ]lOJzSM0wy}GPC>M#r~\ 0yHwdH8,ɵxCbgmF[wT&|Lk?p An6%!2ٗN@"f͖6Q,D5F?wO`%տe1%$֖d!;wV7%׎6PQ͓()Dso ӷr#+KI ipHz ٠7 FOd)Ł+,+Xl>_Ƣzf11gVKEF;fxE9,W=݆:Jn;x0:"10f!Fd'|sp0XM1b:K}NǢ_$sF=u;ǻl)UliCfc mnffYͶD+CWݬ 3nWw}r4\s4SY+-HVWۑl 7&kF|@ uz ‡DP Zm94vO&줾ϊç!C(O*7ƈNW1SI-e:ʣrk0V|wUڦEJ5_y&k:*W'"jf7\ 9#-YG-amX]R;*>cw+W~ow3xF%k}]q`ۛ^ :7nV":`n1&I&(?$;X[}-DQ=퓑ׯ/1yi1ޡ[؎8jYEK֌Tc-*|ˆlԿxJ;ZpU1c% ]כ)kp.UYH0~8w}a&;{!MGց<*[zO1BabǤRXKWds.5Jȃ|?Gi#ܑ/E4\x<7鎴7 gGžo/Y: X+c8!js,-8 6tӋawoWz[A(]o_oVw_]N<uڪa%S:^L$⡞ԟks)kf t=S=-;Wѩ< Р`0K8mFF$3 td8k5=•7"l,85J4y6^7uW!n|fV㹒Rx.xn6geg㹦SWfJe` o}Va<+^-&Ld 7~hi8}屺jUR] ~L(&GC: }0:uQs v_J0bDCȳ[C"NFlQA7@nҔ',}j);B)W+n&S!Cl&]b/L@GdOk"= ,:AGeajf4JJSXYz[M`tt+jI7a[ũKwETZ'9HqOX pme. `M#a¦]aƘUJBrϊWFwÅ-j'MʬiP2Qi,v[4vŽ`ڦų”RryLULKCd(]#Wؙy-қD֑GfwҢ #G qj:e]X;/xwzG8)ӸL_ 5oh\ .mV)seutAX/ d -0PjeV P4n25&. t`v6cx-֓BR53ANfȟoK|ʞVs+yң\ ]'A]IC&zH&0lD]򷺿/rq6Xi/^[Ao#|߼HT%p6ή%V@>󇅐8 w +(t&P|M0Њц֙Ed(Q!gP.R`u_1Dg>.FêW>*wo9#߃>,O(9|F@Yh&fA5~3,pLoMdw8Ewf00❣n xDD) Ʃ#Eh(h0 B;7ߏS>nYU2$3.-i4Տ2|!pm\*3.ylNlz(Byps#RMG֡ធ~ᶻB XF"%LCLczENvzܲ omN̘7`MW LIxV`DAsyg2ۊfb )Y@SنYƆ̑rObsWNR`od`qdt ,9"?v|3S`+P+ΌxF=/|٥$yƣl oq8;Lwۈ>tòlr`Z U qbrD;䟢|ħ??%XO5kT3*-m7侂ҢqLXdd c8ϩ:IK)'2O\$iyeYravb:)n,~9 9 (:M.o`vmuJLlDr3)ÜHq{2AO%99W9IrPc:S8f$$:ixm7 OSno6 y9ޒBdr`@9MѾ" aU1'#[7Lhxj@qBM[??tJDʜVd3e+]H?Kfg o(S5^&NR\:_0kEir6koE[5lAVl79`Uv[8{w tK.r bҤLF8U5x^g-hQƍȘdž4H ,t~Cˈ,tdX k7NEƙ;&t*v=μ0b~Uo!5`CYf+X*3fztUJGC:AR|9D#5HHQ|4eQ֓W\b̹ʄ%:ĖxrKJ2bf vN\S7xlM~ȤeP^[Cϧ))( @fU5qمhJv8-YTX9. iBV^dI+n ֽ8UF 0W=E'n)ORpm-mi.ҶYx#glcƭu<; 1ҳԛ)v]i#K5$3"74#Enh6>WSHȌ .Q\iL[y-m B [c6R?`"y𑚗9M)a;QÔp|u4߷k(+ku 's?3a`}Ն E/*̬g:֏]~>k-Vi&QV^0*ithFh=3ICl(V-uZ 3`M.| ̇FC Qcy ^@C@,SvI+`ƲCF@( <$(M<)6[*zPVAB"X r%/1t 1΀+3G/~/r`<- :rehqKP:yAtcq&'+OKꚇy -f6q0R8#(Oj$I͓ c߀ _RAW}Zr5΋62f ШD*5rj-iAah1,tD3PIڃ4E^P:38 Aղ;#B w'ia^32xe&qW7,1T_VW5 C;s/ëڟ3Y.ĎEm"|;K8N~GrGtCt?t;t7?oBM_ FNmp$^ᾜ*9ԫPy4#j:7h6ZU&-qPwRRd#roКn|Ky2|GXDm'?8nxl&gh@!FGc>T0mEnOe)*rN&& EVaZDDLM$dzg9*0We^/OrKY }/:uluq6h9A(KlV^/⼪=9LN|"as2cVjP+۠ncs4tIN jǶdN.nǍ3[G,Y*,UJ=@ɤu\ P RJV_Ax0Aywl n'44\K򛩸VtG_yD96zHm\s> ,Ӟ7*#iO7ȃQW Xq`E&䙫dYEAqaxUD&jZ0Ru#' &!S5{>ݔT0EN$0ueo#__KZU>@IKJ=}3~[ '/7:^CWW}}T<pr*es2[rP nElk4hU'\@&EkfayOuY> `722`U0eX>/0xMqVe4^00 cRSҍO~@йb;›nl} & ׋nw\VFyy!zZ"<`g5WTET'byDG٠8I b7<*)#{N53mID}:PVzGS8! eN `כ68gc=E=ggy]垏Dy~#R+SEMt "a.HINEzS;䥭E=Rʑ-vBQa7#-p2TvnD{9Z,ᤪwvόrf 'G +A>[O3C,E9ZL^b2F7G ׳*)ps4F*nͺm+vڭfNd]Gwم~_d!^bS率qFݤPcnL_Bk$a=`I!ƄVr>H.޻2`P2)+N줬,u~_Kki_/ySQZL/!?-џFnerPEf{d(HB Ae-q |BW<"T+}*5B^͍gxj#^CϡT4C>CAI#>6`Sji: =a}9t TR0x{XCo.z_n oJBζtְb*KLa!lƆӧ0d_>ᾺJқp/B*rK6N'XY$,~NR2FLBēkWTb B\[KgrgA!3ˁp;ZY:;~[2"QyaSA̲}gfw#;?AUgb nwCgwCe]{2O?WI!VDF2&9S׿B4{|-WW9Tu @A.f)Yyj \ԣW7v6Id0$PLbĮm03*ˎ୭Ɍz\d$1Mڐ< Ҳ|F۸qDȱrg |ve~_FHf-;ˆgQE07✙mXkWYP,7n/1۬z6Q|X{F?w0qd-a na>/]9ؼ7֩̃03l2 W8EL04bAA<#bb !FT :䨴!@@v nH!{u1,v`*ѳl:o xCb#k%45遛SMn<T+NseQ{'2JpLThp Gэ0h +aq% zv3`'3~R GJ!*} 벦Ep;1:9d~#~GuǮ' \WA,7 CE"0^]H0X]HuqaN6+c bIa0u`DYz:4X!jci Z%uhzn5ovzȤ6IHxg ZN+m3YՈh6:-1,H%ԜpGhNXh,{ P,:2JdZpr:94PLR`w[yBD\wwxhl)FpZ-.CwoyOM'ϴZ"e1cTc"felme_ל1//ǰL vU=2XcF]{77(\ӵkYz[t%3EmOLD';$}9dsFaև)=}[ l":ſKpi純o˼P-SAԵïʵpm|vWO k ]o0nI̐v*:\ vu̾o''d g'{ :9}N0u:u7䫝ԩt'TR?߇CnUP]oԕCRw!3*VFk`d|^ȗ} Җ,lmi<Ǫ}MZ|Zx5W>7˨Ϡ^u|9ݤe' ;J)=l/:٤?X8w]3'zA܅K?ady)P((8]XHW.ZmǷ(s0_.);/R s2 >s2Yx#UyZ82g"Ζk@s=܅\zCݿx|W1.0N,kyl̜TK.OxtFe8ر ۉLi$k>rr|uhYj%ZDu.\2[l.z(ϘjJU 3`B{Ah~fEJXF6I"0?N`Y1Qӹ-x:XPw;ɺK{2qs%r܀*Y@m2EVn+:[l#[mu 뢋>ip֕|dJjnBP)%RJF.7#P߂\aXiעg+nrɚ 4y/蘡.-{vb #-,OH 4 _wP~xI\Py ,X59"!q>%tm)?TȵOw*_rI!N6dž"/}%ݣUϳlO͗Hm7y߫zVz&jғ]o?tdC<ʧ2O4dfo,AV$ӮG0sk~o5O5ۂq0Yl]VGhE.=ۂ> [1P㋱_WFP!h 'qTyœ`|°L&v F /1 OS#|&@ͦuRkS;6It*nPy؁ʔ+J= #=Eu"|TL1m'Y _iBm=\jU2jmLyH.+ LD *T{CUݗ E)*~ j ro2L6%L::3"| (77YFhJnh.װ/a{~v^x=l<#{:rksM[N H붸-"\->[rܓ}9Ua; I0ȎnOOu|;򉋨;옣/X憢Ms!̾o9ՀOhg~m=跑9!YRE} {/ yEFX)%E`:8հ Zv8p$@fecRW0F-"8j9Bv?\sxJ*8sl)v x[P'P$2DIj>v:`<* 3~v m_dp[3D}¨ , ;ueUUsfC Ҵ2-5D{Fޖh?ѪKJh%_qI1?<~EE y=>rymF1 tNJ|1q|9! X$<뛛0Mk GMnؤ~2=8H/Ι!F^Vc0Kd93L&%r3F`lCN\Ex Ƃ7Q>3]_5gղ|= Al@kŗhC\򙅒3 -gFѢ VG-{V(}̷k}%]_`ҧFH2j88!  g}njUHok.Cd3.ˊ~s=}]֙KT;- >*Ah~ MczZ>_D0{ix=k,&W+gA _Qbj:Іc0AC> $%͡JːbU; ҟzP7BO 6G66tc;D@rE৐{t?ё2ˢ+}J_+ z3TI>OZ,x 珶uK34*hx:a}"Y^}% kP$Y8آVpD.aU"yFDvuٖWmG}-oJSɩS+ݶ8o4˘),aJhKYlSdFmkjSzZ[D]u0de~-kZ_j_ڧkɍX^>t%> Ez>G]w&=Kn%hh汩Ivw.~ctU:ǜEvE\.?U:-cR1g1_Z[ [GmX0xaW/..TDQ |VMo۰+Y戋yh`wq=\+E:1]v- v{C( vn]ڎ{ Jg"?~ț&R%@LEYϠ ì'f4?{(,0A#484DJ9Npĸ-l񖷞?hko{KDnw +#}#+)W_II +Gz }i ĬmFu~^聋.! e mA[f#% $n,d6$mK 5¤, Mݏx(e;EV3ba%.)dQ%f@] L"5]K /?+ќ+6јgbtJP)1S}I0ĠS W7Z[;1,3ە]ڰ*4KUp4,16 "kaJ]9BhŎ/, .X#?uQp7ީX*ڬV+G[?dyEϓWD\ SktT@GԃDd5yABrJ1k+<5e`Q j+*2Jy:Y Qy{LDVKc8-24tM}f#p_\rNLe'-%·jV#O>1V ъg;Uw/ `,G}M'!Ƈq>(< jzc">yh 7҉T/ YK ݥCV*9ik ~jb!D$f˱c5i;! ͒p2Aokʻ~]ZD yԏR[Jl<]cTzE6Ug<'r(~su6,qpJmPj>sqQ8B(!N6pXaEJdYBU>̼;V3dPOYkb4&"孲Gm,i@.>fLO=Ƥ5HM<"Q͖1= pn '5K;Z\S-k[ı#+`7Pwb".կAUčިR)n"ATz GI }oe`˫f.C3v |iW>ڇE$tR-́-?qy^tQ:Z>u#z>BPl;90)qq v5Kk ]?ϕBZ 7pe Be4c_G/ o#To)_]܂;um^>}Vag1|.SW$7÷ h8)u"T?kٕLpp- L{xEW+s0Wo7Ŝ.Yt!2M"ȭzDlC3۲I*w{I@_k'/iU$EUmY4T FxE7ΡOZg|6=tiAJ`Xb%%%[ hƀ&'KQXޱ{,5-{Un!j6k g,cWXs M:N$%Fw1jp@2ʼn_UpdHE?u袏L]In^X@4O* v SV;~ku{&ic)x5dXugOE2Q`LÓYUʅlcZs9|yEI~| z:J(\dwԋM߲ (ݹE135+>'ȀXY;vsCkxXH1cȸ4rB cE7.+G,~`QAǛ/XDJ3D7CW{,"R$:ƛ?v?n vq~Gg.TxEN^tw&*Cj~^3hy~*cy~zOkw[Z˲Y>ܲA%LIF Q84̐Nk&Ms :fiJ Og+?f #-ٱH0;1LdY<_WxE \*$T~[{I =/^a4͸E,,/{a@=}*c*ey(,P^YZ6[x1_3>ۚGO.TxE4Fv&ӜYSaQ֤hf:,4g㸛l[Tӄo,Yh#c;,߱8:U߁rezE-/-Z-Me "^yؔݝUyf۹R5Q6w`<bV;+t|I+q <)v[kb,XlBfܪ mZ%-ea5hLv=,Rvֲ0A#7:6uV#+0c+Ұa27]ƬОK)=ӥ:LW&Q96.B=ZY'4r~%.߃y0E9_qgG¯6^ivW^u5fЌFNx9YIR^[_Տ/G01wGbRFM 6r Q\h,+g -~f1bnqOj[P{}1OO0-pN>~9^]ŹѽL\hu,`]0xN#Vվgf{8r6O0"PŌ@cxuػ |&~M%l ]D9m NA,X"S%-NPbC> QUFUŚ"^V-XD^.vfie:w ǒ`XQ c9 s0X[vYvYDpIqskZȅ[gbQ8fĺpvmwU΢p,Rku#Ↄٺo1޹ /n$83@hWQ.Emi]MLF1bI+ƭKHbb/ƋbMƹSPn]@ ~rӒ֨6芦ۀl +5P@RXqqK[-~:'-UubZ#.n|`un}Pg #tIU{HHB,%hRbFknveХLNXX"`,<)8`?:"l{vf:'MS.ӨrXqWSV.o1QC M}S T0r$CW]BgڗʧOTv#:lPLya8[h.J%Npǫ;OMGL|̕⣺bJݑGEpsS+}%wbLJ'r\tE]tEs%8M}wxU5+O:M]u(!0H#C# \'MIVlOPgxcגbsѤ4'hR ն3.]!-K޹: WEs͍Pmxw{߀y) 8fM8Cg(q`1qň|!#:(ԂƯZl/d`l[ɶly#jHRi;Ϝ16e/S7^qSpqbg<#;YV|Ur쫹X H `b$B(.ǏcbȈ>Tg0rlp->38\<͵3%;BGvVfqB#[('O_X(u.l[N1R/)R^ S8 !t-GJ!L|28*HTo3%.$bN`C 'JĎ jc4-jm3ƦOdb[hƸem^4ݾ뗁e먆 +n붭p.<ǿũ3&%wL5BU;1٤r T!9[dFcY@UHpj{Uw0JeX#A0EʹBN#5-z?U&_w}4ΜVs=S;-E԰ @b &zݲgط* 9'3=S. I_\RʺLizg"jKlcM$n [^bWwQ[1Q9Bv.AN6#Z@+lacW> o?y \jYǶ],YeFlS;OZZV t0֊|BV3 cE Y!e_TBM5iH*P68URuH,Fe¢\yجɊ-ǒUfuuZ}3ʜ^j&^vLɡY 0P.,}§2eu5pNċC>xJcXn\mV֩p閞 *p9t-lAܬ>eZDS[3~lGUTEj2)!Ver&ˤ/GQe&"L;pLC%Ze|مHgv36>HfS |nb hM)0Wx`j xh]0.j8fYm-XlɎc>mnWed2ySL(IҰpTԵiDtmq?”Lmိk-6ۮҷ|ke>@?ۼ8ߙzb謹\?!%oѿueteh/+Kb8^b/|=ovw$h{`rbY-kgPv(m;*XN: rh@_wQ1;ǚE*HtLvcI6v%2}9)*qP; oaн0t:33It!ވuYg,m{8 YPN3t6a4\HEVLݏ%aRX}t?|/ݔ{[ 3Z*ԅ 'x ̻U=Z j *;Uݾe|@[MUtxlt\%yc?sʝ3~Xgtx[N-Wx7uwLֺMy:1o&yt-l.cOR@=-UKf֭ȧv]tM*{ug]nVWX>w멪q1y*#rϗjݏ;;N$B%atŜƢɬqh_5v_@uFˮ\yfl(i*iQܻM9K]\cBT6֕8c/dlH=aBt@]0@3Xm9oSЮVŗ;rxi4W>4nHnCUpޝ[K.|V崩qݻ. `:ds9%¹Y+Nv!A`f5 Iˆ/?2{ѿ?tӋ.h`O&gO#<ܨOQGCѬ>OV2~2CQ t ` ^!՚!H7&)hv.S8wp)L4-/d)T[&AxCRq9~Bv//XOk+/T wU|k歨Fr8QNknS|hL/Ͻj;*`@P׼Arh _к3ߣ̈{Kuw?$= ut]w޻]tWJ18Dj4qEZ qZ[;#ƕ3F42]_]S#Q^wAlvP4~X⪘㠸,مZ8({>=l[u;=4bKn|1NĻ]WOc]&[KˑrPe+DAƶN4qnbx2vPdllb~^J9(R~ٛvnò*A+ bBO9X;9(r~OSۊ<{iԩ}e=;iտ&ӣ'{ܟJ{hO޾{>}LTCͺF^kY |H+8l>T:yyse^wfL_XEJMouR$CfnMz"o3xXqEOG{9 7 4no :ODsҏ=aC p~|%/1IIxy{\?{+ ]wZ>fUW uYFՑѯtsaTF) RFe ?DcnZ Ǝ`DMG-N`m!\k@SFR(+Nz/PX<\Vs}=qzGS^enZue!6;ۖ]}8z7/sO7ȟ*GL1ZJ^Y2..[زRo;J2Ai[9)3-~p)[(I^-kf A }-mx2 *690 6r.efl7nmjyCػ4"-Z`=$$PF̚>CX|ȷ_jxxC=pA@t+E-ބEG8C=A2G7\Nl`ңRL8TMJTXjץ쇕Vi1:Ϥ*H^9d鬦Nki3\0󕼨]G^G-wn6w7h*̞D7 3/6k2uG =©nl[ss*c%^n_}}E ШI'"eAUm]㖲3tokPsV`TKjtm LU87kT1)'wXMP7?nHS3Lq$ߋY=c QEfxci]Z{Ty,%l@jG ?g|xJGX]_7X֫Kv4>j$|Vp|٬\t>7RsόcI>x|m95xI΃qf;Xb[n23KW]3T{61gHiRC FZjG*zz^XKy1t7q@t$vFXqe#syҨkVP 0VK+oqu\tE]tgq:k+q %QA.Ż;\%,g),@ꢩ?-8CfUoV<Vd;@0ؓ)@\ ]hGBMD\yrwDT@F+Fwo߿K^tыSf;R0`ul90, uWbduj|8GJkJhd $cº9ԷswX|aCqYGyo{?9&Q~\M;@3~d( 䲠6% [8ܯc)eA:iJl+Yo56!d;gyHq17F'-ú W[zQ(' lpVu[90_?b^ A-TS6#T6hƹȍ҇>SW4dwImZBtܜu}WO~ԙjMH+Xɿ!z;AtaLxBTeQc%Г=ՑahI^q4/9DUT66ZGIih" }";KEh.9TǫtjA4 |y4O>3KkH UXZX} Q&)|Qf.Vn{lKUu>-26˴ z&N`z=: F&P'lϒk NdmNLPigiB|gCO/!Zk1?מkOB6bmGF; {v. ۶}(7Ȟ6!ZcfU)rECRҍˈBCt!lv_,K5h7_D2TИd"f PRĮ^fsҾAa8;+;qԬ4|(B*0[(לETgI1ϢeY(02s]}w0젳qa֠ED|(KR,f6})D 89 \ԭEc|ALVZt FtAoYpq8JPFQhE/ǡ΢ǷΜ7u|ӝLo"pNq|YK]ݬ/gH.PD@nBDnw׵Y<0&تm6Jc:2STi@d rEZ; * > YhCNVZ&ͻXbdSJ K%GVM.%WVN4V }2K*뛻w \QWئEo_ȭX0[*C^&NKU9]iE EȥXjcPϚ#4uMw׫HRFv&ߜݖglD'm6Տ{: 9Pc$ ޞL `=avd'x{ʃwUpu$7m 1^z-:g޲0:%,bvNinUUΜ:c J/ʫ˸/>,[1t$Լ[=&g`]~&>.u$ZKZfٸ1qјhJ3Ξ8úq`aV|w_R E+a9 Xj<7f ]ϙxn>D("0Y&ލ9^#}#[ݨɞXJ{IoG Y}ojޞfЖ1Wx$h˃{A&򐡅qѴ`bW:.o@(e4=6+XbgαA|PcZFA)=`\wNq Cߟ 9;l-{\ і Ꭼ-ܲ Kh+D[^f|N@[S_3cy(hKM;BF[$N{ E[xnbsR=^TVRws)w"lV(ZꁄjL`v숪rJ,VoɈkWeóߕmyȐ.2m4і4V1Ж9.mٸD[!0|Ta b~Dʥ Nm G&u ̼qneѩ?t[u 8Ir@[޸,eqh/mwظ-WKj-pbu[u\SS%t[1ںt[ynK~Wm໦O ꘼a:OcbS 9wYXj*n[fe[ 6+Fr:P;z݋G1ζ=69{ւnFT;~%уPP mI4 % hy3t-{\|KVr c*G[hKO;s0.Y)=?@eY,@mXҋpD[u\-j@[ Cq(N.,6/UX7mU] ĎOuG=dM zJ`?[j' ?ײEuLUV_}-w_)5-303r 3!;t)`k̈́&*#6jj;2"43^I.ˤ( "QN 7 xHi.sc{)R6$-:I+x^?3@=ۖmKxs>Sٳ OT,HCbL;5Vrp7 M  .eQW[B;Mtb09qeV@.;04`f-E Y_(*(D/f8> D8\ϣq2ϘYPa*ŋ#pQI7F3L%dZZ7􁀎Y(~Nq;`c$ H'}W^ٹ04yS#LЀBr2~3OۑfT5vXN̈UeT=.W tg*V/|MgghWΜEɋTv iLi <%(z;z NJL6uJ,Dv]FN5snF|1-Ep_ZR/8y3Xv J@+vU;A3ݏX'3=j3aZD}ԕX:(g^lef8X,n-w5h}Ђ׃E]{R:4D|RiUC}!M:lpuh淺Ҕ|[uKVu7LU U}Ԅ尕)' u /5J'3][#˭rڕ\<:.x[;+J[Jw;PZp/gykw,A|.ƺk(mmOPZAtmc:!&JDl]ZҔ>.VoJyH̫8[F>Vvۇj3NzgPJ<&a#u/:MfoJ>sbq|Eh{ =۞mO[zeG]gɘkS2{(S$}R C43nRr=%7+qz$,zJ.&2 @3S483~A_;c;\~ki4\87/ En)>-VXtp'YJ<,s 'ޗ~KNЮF=I_XlmMPwvq[ kJH͂ ƕOa7_O[^Ág2MP$Ov|{׵$\?+m^$EB/{$Ltja8 l %U|]btl¡(`V}-fIfw ιbAdtb"F&`JUU~6K>4q+LM55זA P%m)=Fj@I[ 洤-%#q¹!"3tdmV3 4`+ UVfVezvaWqߝ^]T9^mUV mqQzj٠GZ?kk}^"ؙ1Ͻv3OUʲJCL)Kڒ̭mʹ%mm}hgKh Z Ѧ塄qY\ݴlwӼHJ49oqD6dMSp 'GZdcJeuu*vQݲemy6BoKܟS>'^k/|8"¬>${Uז.%:ںh\sza9:%&Qnh >qp_v>g&dZlNdm5$rs.ybO~;7P |RqWM`:@['$a+\AhA&\4 Xr=GM99XmT<1# (q8'j :>rԸ$f{Ꜥ:N(RV+dWqKhhdpzw]EO=,ǁ0U^P<~)n6XQWDnV%5roi(u6`L4 ';T?VVq4/H"{O4Ē("{=`bTvZqAN漘f7" v֙$ R'$=wiV&\T}}+TlA9;rq!Gy&)5*$-7[#{9Y.}%7R>+={j問%GZ-|,ة'+_kOP˙d%J w7a8eӏ>G҂:-.Ln5[:+ dsr!q XP"&S{KP)'B$5ֵ*vwV$V.ak4HʊtXm,awD*^' g .tj@v̐Y<DW^A5t~uA׾Iqy:lNV463Bn'֘!Y0_/8i^ԛ\JEH7X~| tHOY:눮##Xo#_.#ݖx¯f;<[vV_ƫܹ5_; nK2cfIdk KW vElp=KGthGt9m舮#:{+D\/_܄y|1؍@‘OT#%j˦= 2=GзkEj sP]|-9BҎ:.67#:3ޱ#VطGHi.=j;눮#n}מc=J/VN){T=Л5S~ a [rע3b:R1G|UrIs^J0Mȩ,&'wT/g4aO[Aݢ\8M#ɏ[.y4r*Z;pDžU\f]dXcr]`@U 7T%Ɉ&FI6j1z`T|">dfּB(vDŧ%j 3EEDA#KѶU( N j+.Ct-|JSJ ŬIj5Iq&#q4GxBS Y\ @HQ '&I WdHKIo^8JVo,|~aaV$\JXD80I&5c@2Q,3Iif!RQMtIҚm\'\9 ` %yiBi$QA!.vG2@z,ȥB6XpEUQ0Ea qj/8X@ej ة֯V\!tZ+7|!xήCC(U>߶'I;jH2 &jNFKG=(:a#'7x2V#7$yTq?Z? .AnjPذ ٴq;k|-P`vpg($;utYVec^OWͧS^Oy+=^tvݞړt3H/v&^^et}L s ^Gyz8 `Fpx&⸠\FiT€npȤM$"6) G 5;7s';OI !)Mpi_5Hv`ކd.SA2*${jC26nv{jO[S i|^icU|`9gĹZ>Soge8, WtRU< 0 zÛO_|.½؆bX{z‰2Ġ/ /ːajnҌ4O3|3 3>[ \1HfIi@ba |@-vO=>M=-VO d͞{Eք|CMθO9UUq:%>c][.|ZGO|i p%HN-=o{3#kT iHy6+^d+`%#Оq+YAw+ Y@*ݵV~{wmŪ[n6u׶hA2f>ݞsX}jO2ڶ*!Gƫ1 jdOWOB[̧qF~/e>R}+A=N!q(ݬ3_sp&G| AGsef/$$K+\?8WfQk>:CZz콫Uj6Ŷ`6TRHqgu$OFHU[Turڍ7M<â2[zNђ3%l{ЍmpAЗuk%8r'@}\UCu/:dAedJ F 7n Ǩ?#DKc ]5=K#aӍxvй`j˺6|9bY.-QgC3OQE|z2[(q.᧌ K ;jw3* s1h'%ըVup5qV$4(0Ԓ$T #,T$W8Av0U]nm5#2uXlFQj#SZA]|ޫYtuһhP|H Y1Q㚓"y$ro֘WE犐j9d3Ɯ"k\L c@|Ypӆeyf26̌sN`m"C`n΃Z3[jv9A"L-06HHLja6W|Q68of܃CѤ-u$_x,?0el ~AxK]4Z +y{ͶzVzySe^+Id2&*mtDgE_UaLGa 2&Kaұ &z0Ig t>TC4 W`0oIBxjx n&-y=6z6 &E{Za&aI/)|W Kh!\H.ߊ F҂o{0KP3>YW֘^tb5nqM fws35h"_p&*&&}LI&u0:LzvGj7nl՞~kT B1ܼGgb68i"5BdaJ2I,%I'm) 2%0Bc ~Iɩ0 i+rQ~9ko>Z$X{Uw(͂%Ĥ_\'6Hy "-ydi U @V/_n%v`B ~ݱ|ͱcUvK;c҈7unJBt,VռڇF*^suJYr0)K L-Vh 3fä8Wr%l&1_,`یi=$0[IaKJUPbZp-30[a̓7^)ׁV`IN7+KyYJௐX%/CZ\70V(f5IpgZIQ/O, Ia>PRI$-ШW7 5i&iI&UIRXLѷhb1-^XL %R!< a^1-%1-3) #+!ƴ? &IK&q &}V6I&0I ~$*o&y5&II$f) ]IIz<$$J̹ Ia͉~WW<VgƭjB,RCiicTܱ U:دohURDĭe[Q(oϟbX&nv g7 ' 2օexyE2.E켂1,S}%^o:yQ=ϗi,PŜPf:K;B:FZqTaU45hڕRK(ٗʼ}MB RA?!d(s \󕠟K<_?0ב8?pxǺb,֨яSԐ5nBFxWOل~ڂ |&PS!V& 2>K ^')uc QwSa+`3~y_S\o_nNel)i2ΐ̛К}ƌWTEH:y:=eH^:vp97n'@pqs]澅olNșc\I>vz=kI;P_ʝ~?!9ȃL[qܙyDkUݴ$`$Iv&9"3]fhiO$Egj}}2[\3HNLRX~Q;X9moFYunH(#V'mO08QشV)+eXs’e*Sl|kjSk_d۞ hT*v'IΉK mRgArpƓsRc8RGzgV$vg.t*3 yS"#py@c*/(A\/z9N#[ aSHrKAiljQ&{,SeqF${5/f/lO FM_ۍӄtWbzDOv)]YhM=_ sDAkNM<{m, sw *W^$|%ƖQ> KSKg~*:dJR$悶5ILT%JVoHXgɪ%Yu,.Gaz5a/߱L>%cQC,=pDtUs ~Q,R<<{p"& 4$b )S~U #k1 VB&\J2GQf9s Ac[yg62n7ic0uE+b"&mBp~ DY*O1E>A聒SI/+1ukJ̱%;+Ҕ&V8sk |ւ5ڧYyuLOYϮ(}y$*kIi:L0)äIaK檖WUͯtGzK\ղ͏~pU3.9ryc/sRڞ$:NA^7&q0ä &KITڌҪO꽮g|O;cdՈaӈu woCc8&SёQj (HFGiQ&QY;LJaRI&=L0b{fTIҭ&aRI(aR|wIB7^ x)z%-PfCV&%{~7^߄h)Rʉ0eŊzU+ah6,FkDɚ`{ܰ1U`4N㔮OaGMR)1}G:ifd>sNiaMXW G܄Bz@GVHtfN0%y_%d U)˾!O$#dP3c :R(9g-CԠ>[50\3bDr1CGI`DñJ]ص}E(^(ZHă;,r薆aE'}A `BY4iQj T[ F֐aҲHODZMr3NF1-qŊġ]m1 H۽,ޓFkZŖaG}i>7SG2K>]d3FPwQA_Tn8/ǡ9|!M"8\[PpG;84qȢn2;S3h/VPx%WQ:x.&uuf&:[nNv~/O'\Gϯ){y8krħH4z<=Mv8o+rxdnuS_Mqt͎duH8{3z1' `öRe2%EcGW~-Rh5ɐ4 ,[(P)ߡJL-G7WsNv ht"שgWSZfnN=ܚ{9ps T37g S &}_Y `eҏL|ue h->K*"|tubv#f+`U|:q3b;KRH&Hs:5w5!(tHhU=(;!_e.gMt3nqIx|?2: j=Aa(8_zLsP㫗ƭ[7g7n4°wւ/ީ$7&lq<$LJ_gccIDE* Lh5G!4fWS#TjjWj"+\jj#:@ _Bc#cWU$V{xήZau+!Y}uG%|>)mU ,w|`VjnVjnLUgCK(Y[eEUfZ[eEUfZ[e*'&W6:Rg,a' ۨWߡ jCew`~Ɓ$<^ .sn2ܝ9?c@Rxine-lib-1.2/misc/xine-config.in0000644000175000017500000000356414647725152014365 0ustar meme#!/bin/sh # # unset prefix unset exec_prefix unset args usage() { cat <&2 fi while test $# -gt 0; do case "$1" in -*=*) optarg="${1#--*=}" ;; *) optarg= ;; esac case "$1" in --prefix=*) prefix="$optarg" if [ "$exec_prefix" = '' ]; then exec_prefix="$optarg" fi ;; --exec-prefix=*) exec_prefix="$optarg" ;; --version) args="$args${args+ }--modversion" ;; --cflags|--libs) args="$args${args+ }$1" ;; --prefix|--acflags|--bindir|--plugindir|--datadir|--scriptdir|--localedir|--objcflags) args="$args${args+ }--variable=${1#--}" ;; --xine-list) args="$args${args+ }--variable=xine_list" ;; --exec-prefix) args="$args${args+ }--variable=exec_prefix" ;; *) usage 1 1>&2 ;; esac shift done echo 'xine-config is DEPRECATED. Use pkg-config instead.' >&2 # Sigh. When installing 32 and 64 bit libxine simultaneously, # both will write this script to the same location. # Binary package managers like yum only tolerate this when # both files are identical. Thus we cannot add a hardcoded # (at)XINE_PKGCONFIG_DIR(at) to PKG_CONFIG_PATH here safely. # Instead, allow system and/or user to set up correctly, # and print some useful error if that fails. # That should be good enough for a deprecated feature? pkg-config --print-errors --exists libxine >&2 || exit exec pkg-config "${prefix+--define-variable=prefix=}$prefix" \ "${exec_prefix+--define-variable=exec_prefix=}$exec_prefix" \ $args libxine xine-lib-1.2/misc/Makefile.common0000644000175000017500000000403214647725152014545 0ustar memeXINE_LIB = $(top_builddir)/src/xine-engine/libxine.la xineincludedir = $(includedir)/xine xineplugdir = $(XINE_PLUGINDIR) xineplug_ldflags = $(LDFLAGS_NOUNDEFINED) $(GCSECTIONS) -avoid-version -module xinepostdir = $(XINE_PLUGINDIR)/post vidixdir = $(XINE_PLUGINDIR)/vidix MAINTAINERCLEANFILES = Makefile.in $(XINE_LIB): $(MAKE) -C $(top_builddir)/src/xine-engine libxine.la $(top_builddir)/contrib/libxdg-basedir/libxdg-basedir.la: $(MAKE) -C $(top_builddir)/contrib/libxdg-basedir install-data-hook: @if test $$MAKELEVEL -le 4 ; then \ if test -x "$(top_srcdir)/post-install.sh" ; then \ $(top_srcdir)/post-install.sh ; \ fi; \ fi; \ if test -x /usr/bin/chcon -a "`id -u`" -eq 0; then \ list='$(xineplug_LTLIBRARIES)'; \ for p in $$list; do \ p="`echo $$p | sed -e 's/\.la$$/\.so/g;s|^.*/||'`"; \ echo " chcon system_u:object_r:texrel_shlib_t $(DESTDIR)$(xineplugdir)/$$p"; \ chcon system_u:object_r:texrel_shlib_t $(DESTDIR)$(xineplugdir)/$$p || :; \ done; \ list='$(xinepost_LTLIBRARIES)'; \ for p in $$list; do \ p="`echo $$p | sed -e 's/\.la$$/\.so/g;s|^.*/||'`"; \ echo " chcon system_u:object_r:texrel_shlib_t $(DESTDIR)$(xinepostdir)/$$p"; \ chcon system_u:object_r:texrel_shlib_t $(DESTDIR)$(xinepostdir)/$$p || :; \ done; \ fi pass1: @$(MAKE) MULTIPASS_CFLAGS="$(PASS1_CFLAGS)" pass2: @$(MAKE) MULTIPASS_CFLAGS="$(PASS2_CFLAGS)" uninstall-hook: @list='$(xineplug_LTLIBRARIES)'; for p in $$list; do \ p="`echo $$p | sed -e 's/\.la$$/\.so/g;s|^.*/||'`"; \ echo " rm -f $(DESTDIR)$(xineplugdir)/$$p"; \ rm -f $(DESTDIR)$(xineplugdir)/$$p; \ done; @list='$(xinepost_LTLIBRARIES)'; for p in $$list; do \ p="`echo $$p | sed -e 's/\.la$$/\.so/g;s|^.*/||'`"; \ echo " rm -f $(DESTDIR)$(xinepostdir)/$$p"; \ rm -f $(DESTDIR)$(xinepostdir)/$$p; \ done; @list='$(vidix_LTLIBRARIES)'; for p in $$list; do \ p="`echo $$p | sed -e 's/\.la$$/\.so/g;s|^.*/||'`"; \ echo " rm -f $(DESTDIR)$(vidixdir)/$$p"; \ rm -f $(DESTDIR)$(vidixdir)/$$p; \ done; xine-lib-1.2/misc/Makefile.am0000644000175000017500000000360714647725152013661 0ustar memeinclude $(top_srcdir)/misc/Makefile.common EXTRA_DIST = build_rpms.sh \ SlackBuild.in \ SlackBuild \ vga.xinefont.gz \ xine-config \ xine-lib.spec.in \ xine-lib.spec \ libxine.pc.in \ logo/xine_logo_text.svg \ libdvdcss-1.2.6-network.patch \ Makefile.plugins.in \ Makefile.common \ fonts/cetus.ttf bin_SCRIPTS = xine-config bin_PROGRAMS = xine-list-@XINE_SERIES@ pkgconfig_DATA=libxine.pc xine_list_@XINE_SERIES@_SOURCES = xine-list.c xine_list_@XINE_SERIES@_LDADD = $(XINE_LIB) fontdir = $(pkgdatadir)/fonts dist_font_DATA = \ fonts/cetus-16.xinefont.gz \ fonts/cetus-20.xinefont.gz \ fonts/cetus-24.xinefont.gz \ fonts/cetus-32.xinefont.gz \ fonts/cetus-48.xinefont.gz \ fonts/cetus-64.xinefont.gz \ fonts/cc-16.xinefont.gz \ fonts/cc-20.xinefont.gz \ fonts/cc-24.xinefont.gz \ fonts/cc-32.xinefont.gz \ fonts/cc-48.xinefont.gz \ fonts/cc-64.xinefont.gz \ fonts/cci-16.xinefont.gz \ fonts/cci-20.xinefont.gz \ fonts/cci-24.xinefont.gz \ fonts/cci-32.xinefont.gz \ fonts/cci-48.xinefont.gz \ fonts/cci-64.xinefont.gz \ fonts/mono-16.xinefont.gz \ fonts/mono-20.xinefont.gz \ fonts/mono-24.xinefont.gz \ fonts/mono-32.xinefont.gz \ fonts/mono-48.xinefont.gz \ fonts/mono-64.xinefont.gz \ fonts/sans-16.xinefont.gz \ fonts/sans-20.xinefont.gz \ fonts/sans-24.xinefont.gz \ fonts/sans-32.xinefont.gz \ fonts/sans-48.xinefont.gz \ fonts/sans-64.xinefont.gz \ fonts/serif-16.xinefont.gz \ fonts/serif-20.xinefont.gz \ fonts/serif-24.xinefont.gz \ fonts/serif-32.xinefont.gz \ fonts/serif-48.xinefont.gz \ fonts/serif-64.xinefont.gz dist_doc_DATA = fonts/README.cetus EXTRA_PROGRAMS = xine-fontconv cdda_server xine_fontconv_SOURCES = xine-fontconv.c xine_fontconv_CFLAGS = $(FT2_CFLAGS) xine_fontconv_LDFLAGS = $(GCSECTIONS) xine_fontconv_LDADD = -lz $(FT2_LIBS) cdda_server_SOURCES = cdda_server.c cdda_server_LDFLAGS = $(GCSECTIONS) cdda_server_LDADD = $(DYNAMIC_LD_LIBS) xine-lib-1.2/misc/make_release.sh0000755000175000017500000001542514647725152014602 0ustar meme#!/bin/sh # # make_release.sh - make and upload a new xine-lib release this=misc/make_release.sh tmpfile=/tmp/make_release.$$.tmp # first of all: check directory structure ######################################### case "$0" in /*) location="$0" ;; *) location=`pwd`/"$0" ;; esac location=`echo "$location"|sed -e 's|//|/|g' -e 's|/./|/|g'` if test -r "$location"; then topdir=`echo "$location"|sed -e 's|/'$this'$||'` else echo 'Help! Unable to find myself.' echo 1 fi cd "$topdir" if test -r CVS/Root; then cvsroot=`cat CVS/Root` case "$cvsroot" in *cvs.xine.sf.net:/cvsroot/xine*) ;; *cvs.xine.sourceforge.net:/cvsroot/xine*) ;; *) echo "This doesn't look like a xine CVS checkout. aborting..." exit 1 ;; esac else echo "This must be called from a CVS checkout." exit 1 fi #if [ `basename $topdir` = xine-lib ]; then # echo "good, this seems to be a xine-lib CVS checkout." #else # echo "This script is intended to be called from xine-lib CVS trees only." # exit 1 #fi superdir=`dirname "$topdir"` if test -d "$superdir/xine_www"; then echo "okay, found xine_www module. Let's check that..." www_dir="$superdir/xine_www" cd "$www_dir" if test -r CVS/Root && grep cvsroot/xine CVS/Root >/dev/null 2>&1; then echo "okay, looks like a xine_www CVS checkout." else echo "this doesn't seem to be a xine_www CVS checkout. Aborting." echo "please retry after checking out like this:" echo "cd $superdir; cvs -d cvs.xine.sf.net:/cvsroot/xine co xine_www" exit 1 fi else echo "Unable to find a xine_www checkout in $superdir" exit 1 fi # utility function definitions ############################### yesno() { echo "$* (y/n)?" read answer case "$answer" in y*) true;; n*) false;; *) echo "'pardon?? neither yes nor no? assuming no..." false;; esac } cvs_up_check(){ cvs up -dP >$tmpfile 2>&1 merged="`grep ^M\ $tmpfile`" patched="`grep ^P\ $tmpfile`" conflict="`grep ^C\ $tmpfile`" unknown="`grep -v ^M\ $tmpfile|grep -v ^\?\ |grep -v ^cvs\ server:|grep -v ^P\ |grep -v ^C\ `" if test -n "$conflict"; then echo "The following files have had local changes (conflicts) that could" echo "NOT be merged by CVS:" echo "$conflict" echo "This means your local tree is in an inconsistent state." echo "Releasing this doesn't make sense, please try again after resolving" echo "the conflicts! Stopping here." exit 1 fi if test -n "$patched"; then echo "The following files have been updated by CVS:" echo "$patched" echo "This means your local tree hasn't been up to date before this update." echo -n "Do you want to continue anyway" if yesno; then echo "Okay, I will continue on your request." else echo "Okay, stopping here." exit 1 fi fi if test -n "$merged"; then echo "The following files have had local changes that could be merged by CVS:" echo "$merged" echo "This probably means your local tree hasn't been commited to CVS yet." echo -n "Do you want to continue anyway" if yesno; then echo "Okay, I will continue on your request." else echo "Okay, stopping here." exit 1 fi fi if test -n "$unknown"; then echo "Ooops, CVS said something that I didn't understand:" echo "$unknown" echo "I have no clue what this means, so you have to decide:" echo -n "Do you want to continue anyway" if yesno; then echo "Okay, I will continue on your request." else echo "Okay, stopping here." exit 1 fi fi } # the actual work starts here ############################## echo "updating xine_www from CVS..." cd "$www_dir" cvs_up_check echo "fetching download page from xine's web site..." rm -f $tmpfile if wget -nv -O $tmpfile http://xine.sf.net/download.html; then echo "diffing against CVS checkout:" if diff download.html $tmpfile; then echo "Okay, they are the same." else echo "The CVS version is different from that on the web server!" echo "Please fix that and try again!" exit 1 fi else echo "Unable to fetch the download file from http://xine.sf.net; aborting." exit 1 fi lastver=`grep 'href="files/xine-lib-' download.html \ |sed -e 's|^.*href="files/xine-lib-||' -e 's|\.tar\.gz.*$||g' \ |head -n 1` echo "The last release has been $lastver." old_major=`echo $lastver|awk -F. '{print $1}'` old_minor=`echo $lastver|awk -F. '{print $2}'` old_sub=`echo $lastver|awk -F. '{print $3}'` cd "$topdir" echo "updating xine-lib from CVS..." cvs_up_check new_major=`awk -F= '/XINE_MAJOR=/ {print $2}' $tarball
" fi echo "$line" done download.html.new \ && mv download.html.new download.html echo "committing download file to xine_www CVS" cvs commit -m "added $tarball" download.html cd "$topdir" echo "copying the tarball to xine.sf.net..." scp "$tarball" xine.sf.net:/home/groups/x/xi/xine/htdocs/files cd "$www_dir" echo "copying download page to xine.sf.net..." scp download.html xine.sf.net:/home/groups/x/xi/xine/htdocs else echo "Sorry. Please try again after fixing it!" exit 1 fi cd "$topdir" echo "press return to clean up (make maintainer-clean; cvs up)..." read line make maintainer-clean cvs up -dP tag=xine-${new_major}_${new_minor}_${new_sub}-release echo -n "set CVS tag $tag" if yesno; then cvs tag $tag else echo "Okay, but you should probably do something like" echo "cvs tag $tag" fi echo "Well, that's it. xine-lib $new_ver is officially released" echo "You should probably announce it on xine-announce." rm $tmpfile xine-lib-1.2/misc/libdvdcss-1.2.6-network.patch0000644000175000017500000003151414647725152016752 0ustar memediff -u --new-file libdvdcss-1.2.6/src/Makefile.am libdvdcss-1.2.6-network/src/Makefile.am --- libdvdcss-1.2.6/src/Makefile.am 2003-03-10 12:57:09.000000000 -0500 +++ libdvdcss-1.2.6-network/src/Makefile.am 2003-05-06 15:59:47.000000000 -0400 @@ -4,6 +4,7 @@ libdvdcss_la_SOURCES = \ libdvdcss.c libdvdcss.h \ + network.c network.h \ device.c device.h \ css.c css.h csstables.h \ ioctl.c ioctl.h \ diff -u --new-file libdvdcss-1.2.6/src/libdvdcss.c libdvdcss-1.2.6-network/src/libdvdcss.c --- libdvdcss-1.2.6/src/libdvdcss.c 2003-02-01 16:24:49.000000000 -0500 +++ libdvdcss-1.2.6-network/src/libdvdcss.c 2003-05-06 16:28:21.000000000 -0400 @@ -125,6 +125,9 @@ #include "libdvdcss.h" #include "ioctl.h" #include "device.h" +#include "network.h" + +#define MAX_ERR_MSG 300 /** * \brief Symbol for version checks. @@ -204,6 +207,10 @@ } } + dvdcss->i_socket_fd = dvdcss_network_connect( dvdcss->psz_device ); + if( dvdcss->i_socket_fd != -1 ) + return dvdcss; + /* * Find method from DVDCSS_METHOD environment variable */ @@ -439,6 +446,16 @@ */ extern char * dvdcss_error ( dvdcss_t dvdcss ) { + if( dvdcss->i_socket_fd != -1 ) + { + static char buf[MAX_ERR_MSG]; + + if( dvdcss_network_command( dvdcss->i_socket_fd, buf, "dvd_error") < 0 ) + return "(network error)"; + else + return buf; + } + return dvdcss->psz_error; } @@ -468,6 +485,12 @@ */ extern int dvdcss_seek ( dvdcss_t dvdcss, int i_blocks, int i_flags ) { + if( dvdcss->i_socket_fd != -1 ) + { + return dvdcss_network_command( dvdcss->i_socket_fd, NULL, + "dvd_seek %d %d", i_blocks, i_flags); + } + /* title cracking method is too slow to be used at each seek */ if( ( ( i_flags & DVDCSS_SEEK_MPEG ) && ( dvdcss->i_method != DVDCSS_METHOD_TITLE ) ) @@ -512,6 +535,12 @@ { int i_ret, i_index; + if( dvdcss->i_socket_fd != -1 ) + { + return dvdcss_network_command( dvdcss->i_socket_fd, p_buffer, + "dvd_read %d %d", i_blocks, i_flags); + } + i_ret = dvdcss->pf_read( dvdcss, p_buffer, i_blocks ); if( i_ret <= 0 @@ -588,6 +617,12 @@ void *iov_base; size_t iov_len; + if( dvdcss->i_socket_fd != -1 ) + { + printf("error: network dvdcss_readv not implemented\n"); + return -1; + } + i_ret = dvdcss->pf_readv( dvdcss, _p_iovec, i_blocks ); if( i_ret <= 0 @@ -642,20 +677,28 @@ dvd_title_t *p_title; int i_ret; - /* Free our list of keys */ - p_title = dvdcss->p_titles; - while( p_title ) + if( dvdcss->i_socket_fd != -1 ) { - dvd_title_t *p_tmptitle = p_title->p_next; - free( p_title ); - p_title = p_tmptitle; + close(dvdcss->i_socket_fd); } + else + { - i_ret = _dvdcss_close( dvdcss ); + /* Free our list of keys */ + p_title = dvdcss->p_titles; + while( p_title ) + { + dvd_title_t *p_tmptitle = p_title->p_next; + free( p_title ); + p_title = p_tmptitle; + } - if( i_ret < 0 ) - { - return i_ret; + i_ret = _dvdcss_close( dvdcss ); + + if( i_ret < 0 ) + { + return i_ret; + } } free( dvdcss->psz_device ); @@ -670,6 +713,11 @@ #undef dvdcss_title extern int dvdcss_title ( dvdcss_t dvdcss, int i_block ) { + if( dvdcss->i_socket_fd != -1 ) + { + return dvdcss_network_command( dvdcss->i_socket_fd, NULL, + "dvd_title %d", i_block); + } return _dvdcss_title( dvdcss, i_block ); } diff -u --new-file libdvdcss-1.2.6/src/libdvdcss.h libdvdcss-1.2.6-network/src/libdvdcss.h --- libdvdcss-1.2.6/src/libdvdcss.h 2002-12-19 10:36:04.000000000 -0500 +++ libdvdcss-1.2.6-network/src/libdvdcss.h 2003-04-29 05:31:04.000000000 -0400 @@ -34,6 +34,7 @@ int i_fd; int i_read_fd; int i_pos; + int i_socket_fd; /* File handling */ int ( * pf_seek ) ( dvdcss_t, int ); diff -u --new-file libdvdcss-1.2.6/src/network.c libdvdcss-1.2.6-network/src/network.c --- libdvdcss-1.2.6/src/network.c 1969-12-31 19:00:00.000000000 -0500 +++ libdvdcss-1.2.6-network/src/network.c 2003-05-06 16:28:04.000000000 -0400 @@ -0,0 +1,331 @@ +/*************************************************************************** + network.c - description + ------------------- + begin : Wed Mar 19 2003 + copyright : (C) 2003 by miguel + email : miguel@miguel + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define _BUFSIZ 300 + +static int host_connect_attempt (struct in_addr ia, int port) +{ + int s; + struct sockaddr_in sin; + + s=socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (s==-1) { + printf("network: failed to open socket\n"); + return -1; + } + + sin.sin_family = AF_INET; + sin.sin_addr = ia; + sin.sin_port = htons(port); + + if (connect(s, (struct sockaddr *)&sin, sizeof(sin))==-1 && errno != EINPROGRESS) { + printf("network: cannot connect to host\n"); + close(s); + return -1; + } + + return s; +} + +static int host_connect (const char *host, int port) +{ + struct hostent *h; + int i; + int s; + + h=gethostbyname(host); + if (h==NULL) { + printf("network: unable to resolve >%s<\n", host); + return -1; + } + + for(i=0; h->h_addr_list[i]; i++) { + struct in_addr ia; + memcpy(&ia, h->h_addr_list[i], 4); + s=host_connect_attempt(ia, port); + if(s != -1) { + signal( SIGPIPE, SIG_IGN ); + return s; + } + } + + printf("network: unable to connect to >%s<\n", host); + return -1; +} + + +static int parse_url (char *urlbuf, char** host, int *port) { + char *start = NULL; + char *portcolon = NULL; + + if (host != NULL) + *host = NULL; + + if (port != NULL) + *port = 0; + + start = strstr(urlbuf, "://"); + if (start != NULL) + start += 3; + else + start = urlbuf; + + while( *start == '/' ) + start++; + + portcolon = strchr(start, ':'); + + if (host != NULL) + *host = start; + + if (portcolon != NULL) + { + *portcolon = '\0'; + + if (port != NULL) + *port = atoi(portcolon + 1); + } + + return 0; +} + +static int sock_check_opened(int socket) { + fd_set readfds, writefds, exceptfds; + int retval; + struct timeval timeout; + + for(;;) { + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + FD_SET(socket, &exceptfds); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + retval = select(socket + 1, &readfds, &writefds, &exceptfds, &timeout); + + if(retval == -1 && (errno != EAGAIN && errno != EINTR)) + return 0; + + if (retval != -1) + return 1; + } + + return 0; +} + +/* + * read binary data from socket + */ +static int sock_data_read (int socket, char *buf, int nlen) { + int n, num_bytes; + + if((socket < 0) || (buf == NULL)) + return -1; + + if(!sock_check_opened(socket)) + return -1; + + num_bytes = 0; + + while (num_bytes < nlen) { + + n = read (socket, &buf[num_bytes], nlen - num_bytes); + + /* read errors */ + if (n < 0) { + if(errno == EAGAIN) { + fd_set rset; + struct timeval timeout; + + FD_ZERO (&rset); + FD_SET (socket, &rset); + + timeout.tv_sec = 30; + timeout.tv_usec = 0; + + if (select (socket+1, &rset, NULL, NULL, &timeout) <= 0) { + printf ("network: timeout on read\n"); + return 0; + } + continue; + } + printf ("network: read error %d\n", errno); + return 0; + } + + num_bytes += n; + + /* end of stream */ + if (!n) break; + } + + return num_bytes; +} + +/* + * read a line (\n-terminated) from socket + */ +static int sock_string_read(int socket, char *buf, int len) { + char *pbuf; + int r, rr; + void *nl; + + if((socket < 0) || (buf == NULL)) + return -1; + + if(!sock_check_opened(socket)) + return -1; + + if (--len < 1) + return(-1); + + pbuf = buf; + + do { + + if((r = recv(socket, pbuf, len, MSG_PEEK)) <= 0) + return -1; + + if((nl = memchr(pbuf, '\n', r)) != NULL) + r = ((char *) nl) - pbuf + 1; + + if((rr = read(socket, pbuf, r)) < 0) + return -1; + + pbuf += rr; + len -= rr; + + } while((nl == NULL) && len); + + if (pbuf > buf && *(pbuf-1) == '\n'){ + *(pbuf-1) = '\0'; + } + *pbuf = '\0'; + return (pbuf - buf); +} + +/* + * Write to socket. + */ +static int sock_data_write(int socket, char *buf, int len) { + ssize_t size; + int wlen = 0; + + if((socket < 0) || (buf == NULL)) + return -1; + + if(!sock_check_opened(socket)) + return -1; + + while(len) { + size = write(socket, buf, len); + + if(size <= 0) + return -1; + + len -= size; + wlen += size; + buf += size; + } + + return wlen; +} + +int dvdcss_network_command( int socket, char *data_buf, char *msg, ...) +{ + char buf[_BUFSIZ]; + va_list args; + int ret, n; + + va_start(args, msg); + vsnprintf(buf, _BUFSIZ - 1, msg, args); + va_end(args); + + /* Each line sent is '\n' terminated */ + if((buf[strlen(buf)] == '\0') && (buf[strlen(buf) - 1] != '\n')) + strcat(buf, "\n"); + + if( sock_data_write(socket, buf, strlen(buf)) < (int)strlen(buf) ) + { + printf("network: error writing to socket\n"); + return -1; + } + + if( sock_string_read(socket, buf, _BUFSIZ) <= 0 ) + { + printf("network: error reading from socket\n"); + return -1; + } + + sscanf(buf, "%d %d", &ret, &n ); + + if( n ) { + if( !data_buf ) { + printf("network: protocol error, data returned but no buffer provided.\n"); + return -1; + } + if( sock_data_read(socket, data_buf, n) < n ) + return -1; + } + + return ret; +} + +int dvdcss_network_connect( char *url ) +{ + char *host; + int port; + int fd; + + url = strdup(url); + parse_url(url, &host, &port); + + if( !host || !strlen(host) || !port ) + { + free(url); + return -1; + } + + fd = host_connect( host, port ); + free(url); + + if( fd != -1 ) { + if( dvdcss_network_command(fd, NULL, "dvd_open") < 0 ) { + close(fd); + return -1; + } + } + return fd; +} diff -u --new-file libdvdcss-1.2.6/src/network.h libdvdcss-1.2.6-network/src/network.h --- libdvdcss-1.2.6/src/network.h 1969-12-31 19:00:00.000000000 -0500 +++ libdvdcss-1.2.6-network/src/network.h 2003-05-06 16:26:15.000000000 -0400 @@ -0,0 +1,20 @@ +/*************************************************************************** + network.h - description + ------------------- + begin : Wed Mar 19 2003 + copyright : (C) 2003 by miguel + email : miguel@miguel + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +int dvdcss_network_connect( char *url ); + +int dvdcss_network_command( int socket, char *data_buf, char *msg, ...); xine-lib-1.2/misc/xine-fontconv.c0000644000175000017500000004011614647725152014562 0ustar meme/* * Copyright (C) 2001-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * OSD stuff (text and graphic primitives) * * xine-fontconv.c * * converts ttf fonts to xine osd fonts * * compile: * gcc -o xine-fontconv xine-fontconv.c `freetype-config --cflags --libs` -lz * * usage: * xine-fontconv font.ttf fontname [encoding1 [encoding2 [...]]] * * begin : Sat Dec 1 2001 * copyright : (C) 2001 by Miguel Freitas * unicode stuff : (C) 2003 by Frantisek Dvorak */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef HAVE_MALLOC_H #include #endif #include #include #ifndef OLD_FREETYPE2 #include #include FT_FREETYPE_H #include FT_GLYPH_H #else /* freetype 2.0.1 */ #include #include #endif /* we want UCS-2 encoding in the machine endian */ #if BYTE_ORDER == BIG_ENDIAN # define UCS2_ENCODING "UCS-2BE" #else # define UCS2_ENCODING "UCS-2LE" #endif #ifndef MAX # define MAX (a, b) ((a) > (b)? (a) : (b)) #endif #define f266ToInt(x) (((x)+32)>>6) /* round fractional fixed point */ /* coordinates are in 26.6 pixels (i.e. 1/64th of pixels)*/ #define f266CeilToInt(x) (((x)+63)>>6) /* ceiling */ #define f266FloorToInt(x) ((x)>>6) /* floor */ /* #define LOG 1 */ /* xine stuff */ typedef struct osd_fontchar_s osd_fontchar_t; typedef struct osd_font_s osd_font_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; struct osd_fontchar_s { uint16_t code; uint16_t width; uint16_t height; uint8_t *bmp; }; struct osd_font_s { char name[40]; uint16_t version; uint16_t size; uint16_t num_fontchars; osd_fontchar_t *fontchar; osd_font_t *next; }; /* list */ typedef struct item_s item_t; struct item_s { uint16_t code; item_t *next; }; osd_fontchar_t fontchar; osd_font_t font; static int gzwrite_i16(gzFile fp, uint16_t number) { return gzputc(fp, number & 0xFF) != -1 && gzputc(fp, (number >> 8) & 0xFF) != -1; } /* search the item with 'code' in the sorted list */ item_t *list_search(item_t *list, uint16_t code, item_t **parent) { item_t *item; /* searching */ item = list; while(item && item->code < code) { list = item; item = item->next; } /* parent (or future parent) */ if (parent) *parent = list == item ? NULL : list; if (item && item->code == code) return item; else return NULL; } /* add new number into sorted list, returns if code is there already */ int list_insert(item_t **list, uint16_t code) { item_t *item, *parent; if ((item = list_search(*list, code, &parent)) == NULL) { /* insert new item */ if ((item = malloc(sizeof(item_t))) == NULL) { printf("Insufficient memory\n"); abort(); } item->code = code; if (parent) { item->next = parent->next; parent->next = item; } else { item->next = *list; *list = item; } return 0; } else { /* item is there already */ return 1; } } /* free the list */ void list_free(item_t *list) { item_t *item; while(list != NULL) { item = list; list = list->next; free(item); } } /* * generate sorted list with unicodes in all given pages, * returns number of unicodes in the list */ uint16_t generate_unicodes_list(item_t **list, char **pages, int number) { int page; uint16_t codes_count = 0; /* unicode counter */ int32_t z; /* index in the codepage */ iconv_t cd; /* iconv conversion descriptor */ *list = NULL; /* process all given codepages */ for (page = 0; page < number; page++) { /* prepare encoding */ if ((cd = iconv_open(UCS2_ENCODING, pages[page])) == (iconv_t)-1) { printf("Unsupported encoding \"%s\"\n", pages[page]); continue; } printf("Used encoding \"%s\"\n", pages[page]); /* add new unicodes into list */ for (z = 32; z < 0xFFFF; z++) { uint16_t unicode; char *inbuf = (char *)&z; char *outbuf = (char *)&unicode; size_t inbytesleft = z <= 0xFF ? 1 : 2; size_t outbytesleft = 2; size_t count; /* get unicode value from index 'z' in this codepage 'pages[i]' */ count = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); if (count == (size_t)-1 || inbytesleft != 0) { /* unused index 'z' in this codepage */ continue; } if (!list_insert(list, unicode)) codes_count++; } iconv_close(cd); } return codes_count; } #ifdef LOG void print_bitmap (FT_Bitmap *bitmap) { int x,y; for( y = 0; y < bitmap->rows; y++ ) { for( x = 0; x < bitmap->width; x++ ) { if( bitmap->buffer[y*bitmap->width+x] > 1 ) printf("%02x ", bitmap->buffer[y*bitmap->width+x] ); else printf(" "); } printf("\n"); } } #endif FT_Bitmap *create_bitmap (int width, int height) { FT_Bitmap * bitmap; #ifdef LOG printf("Bitmap char %d %d\n",width,height); #endif bitmap = malloc( sizeof( FT_Bitmap ) ); bitmap->rows = height; bitmap->width = width; bitmap->buffer = malloc(width*height); memset( bitmap->buffer, 0, width*height ); return bitmap; } void destroy_bitmap (FT_Bitmap * bitmap) { free(bitmap->buffer); free(bitmap); } /* This function is called to blend a slightly deslocated version of the bitmap. This will produce the border effect. Note that the displacement may be smaller than 1 pixel as the bitmap is generated in freetype 1/64 units. This border is antialiased to the background. */ void add_border_bitmap( FT_Bitmap *dst, FT_Bitmap *src, int left, int top ) { int x,y; int x1, y1; int dstpos, srcpos; for( y = 0; y < src->rows; y++ ) { for( x = 0; x < src->width; x++ ) { srcpos = y * src->width + x; x1 = x + left; if( x1 < 0 || x1 >= dst->width ) continue; y1 = y + top; if( y1 < 0 || y1 >= dst->rows ) continue; dstpos = y1 * dst->width + x1; src->buffer[srcpos] /= 51; if( src->buffer[srcpos] > dst->buffer[dstpos] ) dst->buffer[dstpos] = src->buffer[srcpos]; } } } /* Blend the final version of bitmap (the foreground color) over the already generated border. It will be antialiased to the border. Final palette will be: 0: not used by font, always transparent 1: font background, usually transparent, may be used to implement translucid boxes where the font will be printed. 2-5: transition between background and border (usually only alpha value changes). 6: font border. if the font is to be displayed without border this will probably be adjusted to font background or near. 7-9: transition between border and foreground 10: font color (foreground) */ void add_final_bitmap( FT_Bitmap *dst, FT_Bitmap *src, int left, int top ) { int x,y; int x1, y1; int dstpos, srcpos; for( y = 0; y < src->rows; y++ ) { for( x = 0; x < src->width; x++ ) { srcpos = y * src->width + x; x1 = x + left; if( x1 < 0 || x1 >= dst->width ) continue; y1 = y + top; if( y1 < 0 || y1 >= dst->rows ) continue; dstpos = y1 * dst->width + x1; src->buffer[srcpos] /= 52; if( src->buffer[srcpos] ) dst->buffer[dstpos] = src->buffer[srcpos] + 5; } } for( y = 0; y < dst->rows; y++ ) { for( x = 0; x < dst->width; x++ ) { dstpos = y * dst->width + x; dst->buffer[dstpos]++; } } } void render_font (FT_Face face, char *fontname, int size, int thickness, item_t *unicodes) { char filename[1024]; FT_Bitmap *out_bitmap; gzFile fp; int error; int error_counter; int glyph_index; FT_Glyph glyph; FT_BitmapGlyph glyph_bitmap; FT_Vector origin; int max_bearing_y = 0; int i; int converted; item_t *item, *error_unicodes; static int border_pos[9][2] = { {-1,0},{1,0},{0,-1},{0,1}, {-1,-1},{1,-1},{-1,1},{1,1}, {0,0} }; /* * generate filename, open file */ snprintf (filename, sizeof(filename), "%s-%d.xinefont.gz", fontname, size); fp = gzopen(filename,"w"); if (!fp) { printf ("error opening output file %s\n", filename); return; } /* * set up font */ strncpy(font.name, fontname, sizeof(font.name)); font.name[sizeof(font.name) - 1] = '\0'; /* changes from version 1 to version 2: * 'code' in characters is defined as little endian 16-bit unicode * characters are sorted by 'code' */ font.version = 2; font.num_fontchars = 0; font.size = size; error = FT_Set_Pixel_Sizes( face, /* handle to face object */ 0, /* pixel_width */ size ); /* pixel_height */ if (error) { printf("error setting size\n"); return; } if( !thickness ) thickness = size * 64 / 30; /* * calc max bearing y. * this is needed to align all bitmaps by the upper position. */ error_counter = 0; error_unicodes = NULL; for (item = unicodes; item; item = item->next) { glyph_index = FT_Get_Char_Index( face, item->code); if (!glyph_index) { error_counter++; list_insert(&error_unicodes, item->code); continue; } error = FT_Load_Glyph (face, /* handle to face object */ glyph_index, /* glyph index */ FT_LOAD_DEFAULT ); /* load flags */ if (error) { error_counter++; list_insert(&error_unicodes, item->code); continue; } #ifdef LOG printf("bearing_y %ld\n",face->glyph->metrics.horiBearingY); #endif if( (face->glyph->metrics.horiBearingY >> 6) > max_bearing_y ) max_bearing_y = (face->glyph->metrics.horiBearingY >> 6); font.num_fontchars++; } printf("max_bearing_y: %d\n", max_bearing_y + f266CeilToInt(thickness)); gzwrite(fp, font.name, sizeof(font.name)); gzwrite_i16(fp, font.version); gzwrite_i16(fp, font.size); gzwrite_i16(fp, font.num_fontchars); for (item = unicodes; item; item = item->next) { converted = 0; for( i=0; i < 9; i++ ) { glyph_index = FT_Get_Char_Index( face, item->code); if (glyph_index) { error = FT_Load_Glyph( face, /* handle to face object */ glyph_index, /* glyph index */ FT_LOAD_DEFAULT ); /* load flags */ if (!error) { error = FT_Get_Glyph( face->glyph, &glyph ); if( i == 0 ) { out_bitmap = create_bitmap( f266CeilToInt(thickness + MAX(face->glyph->metrics.horiAdvance, face->glyph->metrics.width + face->glyph->metrics.horiBearingX)), f266CeilToInt((max_bearing_y<<6) - face->glyph->metrics.horiBearingY + face->glyph->metrics.height + thickness) ); } origin.x = thickness + border_pos[i][0]*thickness; origin.y = thickness + border_pos[i][1]*thickness; error = FT_Glyph_Transform(glyph, NULL, &origin) || FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, NULL, 1); if (error) { printf("error generating bitmap [U+%04X]\n", item->code); destroy_bitmap(out_bitmap); return; } glyph_bitmap = (FT_BitmapGlyph)glyph; if( i < 8 ) add_border_bitmap( out_bitmap, &glyph_bitmap->bitmap, glyph_bitmap->left, max_bearing_y - glyph_bitmap->top ); else add_final_bitmap( out_bitmap, &glyph_bitmap->bitmap, glyph_bitmap->left, max_bearing_y - glyph_bitmap->top ); converted = 1; FT_Done_Glyph( glyph ); } } } if( converted ) { #ifdef LOG printf("[U+%04X] bitmap width: %d height: %d\n", item->code, out_bitmap->width, out_bitmap->rows ); /* print_bitmap(out_bitmap); */ #endif fontchar.code = item->code; fontchar.width = out_bitmap->width; fontchar.height = out_bitmap->rows; gzwrite_i16 (fp, fontchar.code); gzwrite_i16 (fp, fontchar.width); gzwrite_i16 (fp, fontchar.height); gzwrite (fp, out_bitmap->buffer, out_bitmap->width*out_bitmap->rows); destroy_bitmap(out_bitmap); } } gzclose(fp); if (error_counter) { printf("error: %d characters couldn't read: ", error_counter); /* this unicodes wasn't readed from .ttf font */ item = error_unicodes; while(item) { printf("U+%04X ", item->code); item = item->next; } printf("\n"); list_free(error_unicodes); } printf ("generated %s (%d characters)\n", filename, font.num_fontchars); } int main(int argc, char *argv[]) { int error; int len; FT_Library library; FT_Face face; int thickness = 0; char *encoding = "iso-8859-1"; item_t *unicodes = NULL; /* unicode list */ #ifdef LOG item_t *item; #endif uint16_t count; /* * command line parsing */ if (argc < 3) { printf ("usage: %s font.ttf fontname [encoding1 [encoding2 [...]]]\n", argv[0]); exit (1); } len = strlen (argv[1]); if (strncasecmp (&argv[1][len-4],".ttf",3)) { printf ("font name must have .ttf suffix (is %s)\n", &argv[1][len-4]); exit (1); } error = FT_Init_FreeType( &library ); if( error ) { printf("error initializing freetype\n"); return 1; } error = FT_New_Face( library, argv[1], 0, &face ); if (error) { printf("error loading font\n"); return 1; } error = FT_Select_Charmap( face, ft_encoding_unicode); if (error) { printf("error selecting unicode charmap\n"); return 1; } if (argc == 3) { count = generate_unicodes_list(&unicodes, &encoding, 1); } else { count = generate_unicodes_list(&unicodes, argv + 3, argc - 3); } #ifdef LOG printf("Prepared %d unicode values: ", count); for (item = unicodes; item; item = item->next) printf("U+%04X ", item->code); printf("\n"); #else printf("Prepared %d unicode values.\n", count); #endif if (count) { render_font (face, argv[2], 16, thickness, unicodes); render_font (face, argv[2], 20, thickness, unicodes); render_font (face, argv[2], 24, thickness, unicodes); render_font (face, argv[2], 32, thickness, unicodes); render_font (face, argv[2], 48, thickness, unicodes); render_font (face, argv[2], 64, thickness, unicodes); } else printf("No font generated\n"); list_free(unicodes); FT_Done_Face(face); FT_Done_FreeType(library); /* * some rgb -> yuv conversion, * can be used to calc new palettes */ /* { float f; for (f=1.0; f<6.0; f+=1.0) { float R=f*40.0; float G=f*40.0; float B=f*42.0; float Y, Cb, Cr; Y = 0.29900 * R + 0.58700 * G + 0.11400 * B ; Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + 128.0; Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + 128.0; printf ("CLUT_Y_CR_CB_INIT(0x%x, 0x%x, 0x%x),\n", (int) Y, (int) Cr, (int) Cb); } } */ return 0; } xine-lib-1.2/misc/vga.xinefont.gz0000644000175000017500000000566514647725152014603 0ustar memeC<vga.xinefont\-E3O@@;V;səyླ9޽:{C a ~ێ=߾}'qPPot<8_E\K1 x8DEֈmEq<#UX=39 EΙ@Tg9bX!H*6lyB*^*78#2l͔첉~Ep,]\LSt.qRNbBmnzNčINq/&GkJ2(fh=딑)rr&Z:N500V-hg6kh^lC( QI!:>) .$W`ɱXбyL?Bt$梳Ýnbຘu.ZX2$`*ǕG,mHPZ-FBעAAԍ{Fo\Ks:1˙s-`R5gn-h,,^.)0|C 8ԼubM( :{Sߔ=^9jUZNu1;:99'JV9aݯ9gD%.:8x:58fqE˘#Y Pirn.]τҜ)P0r^#t4O'\|Gvx~_ϙS5C].h倌v\pti uhՔrzCqkᢦItXZŤe!Q..ܳg0.Unl(.FV=dot P;90DY.Esnrrqi5G$D4΅ij)#eM](..ׁB2$>H\aa60WQXi+yg|;WV 2W\ŕ#\t4Lj4ƲE= `,?~Rjo2'Bn1:4ia!T4tPGt\ERv޸ sŅ x fud.tP'U|>b3s^戙J3JtOĚKn(`:Bsf7j90kkh.iE5vs!gԛiBk\\|55k6hf6mCQ1SܪEu)2-\ڄ,G|sM;J9DmMO`v語ir;eLLB[xZV[(Fڼ wL-+)b}iӖpkBQ;sy\Y\ϝ;d i7ju3v}\(( uᑻtr*}~/c{Yz m՛#:?~m>A8xW1Hf T3G! m=]92 f.ohrEq{r>"hX/$\C%liܷfJ"Gy~7VP繫\StzėYm2\uA|lT6^hBP;SnfQ!›RBJ iS>=L90bEL(M!aeb dC~ONB=}Jm-%>Y @YrG(H#-@ţ]Y c_0 Kxl 쉸%(g8sp2'\ G ~KSB(P&WD 7m(]Yœ|Yœ|̙AhM(Z+.iGYGliMaBta'{@(YemZGtV1(YǠxPt bYb)qŅ#ϕ+3Zy"V^g:;^1@o^ạĹ(^h{/ם\н>Xp[|R_~H%ɂӎґ.^{r/ƨm2?*f/w+\Һ,\f -djUuF*l-FyZD "Fu ]qk5$f/OB!Bp@y}=˩ty:#(a X΀^{nX&g\dB\fB)o߰oI^&)æo/(. *wPVGxW~H-O}P`rGH9u(@Fsn;SGШ%G U #lCi.E|bT\tqI?bot XPGcbic- b뎋(>|;.FpE,g.4b׍ˣ%2W|mTO풯{=HgF/7ejoV-rU{ӵ.N_w;W7v;C q3+.Z=Yѭ jxM~~?s,%y܅Q'&0hmTDQr,c~6B! + "5S8US~p1uho`Z[ owP ~`rHmGEɖH~g@Eܓ9 @E~/x@5YHrϴhMf99[]yU+V-mT"YB6&,8Pz2ֆyK[[Kh]wv-rl䟽(J4M/wdQ45uNGNJX!TɜgP#;Q[meju PK0YnEۃmqmPǭl6F}Ag 06R dQ56Cm0@\q(`/cYPjFM(5F ZlȪ7 6l dI_|xine-lib-1.2/misc/xine-list.c0000644000175000017500000001060714647725152013703 0ustar meme/* * Copyright (C) 2008-2020 the xine-project * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define XINE_LIST_VERSION_N(x,y) #x"."#y #define XINE_LIST_VERSION XINE_LIST_VERSION_N(XINE_MAJOR_VERSION,XINE_MINOR_VERSION) int main (int argc, char *argv[]) { int optstate = 0; int which = 'm'; int lf = 0; for (;;) { #define OPTS "hvaemp" #ifdef HAVE_GETOPT_LONG static const struct option longopts[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "mime-types", no_argument, NULL, 'm' }, { "extensions", no_argument, NULL, 'e' }, { "all", no_argument, NULL, 'a' }, { NULL, no_argument, NULL, 0 } }; int index = 0; int opt = getopt_long (argc, argv, OPTS, longopts, &index); #else int opt = getopt(argc, argv, OPTS); #endif if (opt == -1) break; switch (opt) { case 'h': optstate |= 1; break; case 'v': optstate |= 4; break; case 'a': case 'e': case 'm': which = opt; break; case 'p': lf = 1; break; default: optstate |= 2; break; } } if (optstate & 1) printf ("\ xine-list-"XINE_LIST_VERSION" %s\n\ using xine-lib %s\n\ usage: %s [options]\n\ options:\n\ -h, --help this help text\n\ -m, --mime-types list just the supported MIME types\n\ -e, --extensions list just the recognised filename extensions\n\ -a, --all list everything\n\ -p, --pretty-print add line feeds\n\ \n", XINE_VERSION, xine_get_version_string (), argv[0]); else if (optstate & 4) printf ("\ xine-list %s\n\ using xine-lib %s\n\ (c) 2008 the xine project team\n\ This is free software; see the source for copying conditions. There is NO\n\ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,\n\ to the extent permitted by law.\n", XINE_VERSION, xine_get_version_string ()); if (optstate & 2) { fputs ("xine-list: invalid option (try -h or --help)\n", stderr); return 1; } if (optstate) return 0; xine_t *xine = xine_new (); /* Avoid writing catalog.cache if possible */ int major, minor, sub; xine_get_version (&major, &minor, &sub); if ((major == 1 && minor == 1 && sub > 20) || (major == 1 && minor == 2 && sub > 0) || (major == 1 && minor > 2) || (major > 1)) if (xine_set_flags) xine_set_flags (xine, XINE_FLAG_NO_WRITE_CACHE); xine_init (xine); char *text = NULL, *freeme = NULL; char *sep, *sep2; switch (which) { case 'a': case 'm': freeme = text = xine_get_mime_types (xine); if (!text || !*text) goto read_fail; sep = sep2 = text - 1; for (;;) { text = sep + 1; sep = strchr (text, ';'); if (!sep) sep = text + strlen (text); sep2 = which == 'a' ? sep : strchr (text, ':'); if (!sep2) sep2 = sep; if (!*sep) break; if (printf ("%.*s;", (int)(sep2 - text), text) < 0 || (lf && puts ("") < 0)) goto write_fail; } break; case 'e': freeme = text = xine_get_file_extensions (xine); if (!text || !*text) goto read_fail; sep = text - 1; do { text = sep + 1; sep = strchr (text, ' '); if (!sep) sep = text + strlen (text); if (sep[-1] != '/' && printf ("%.*s%s", (int)(sep - text), text, lf ? "\n" : *sep ? " " : "") < 0) goto write_fail; } while (*sep); break; } xine_exit(xine); free(freeme); return 0; read_fail: fputs ("xine-list: failed to read types info\n", stderr); return 1; write_fail: perror ("xine-list"); return 1; } xine-lib-1.2/misc/relchk.sh.in0000755000175000017500000000261114647725152014033 0ustar meme#!/bin/sh ## ## A simple compare directory content utility. ## topdir="`pwd`" distdir="@PACKAGE_TARNAME@" log="$topdir/dist-log" logerror="$topdir/dist-errors" getdir() { for file in `ls`; do if test -d $file -a $file != "CVS" -a $file != $distdir -a $file != "autom4te.cache"; then (cd $file && getdir) || (cd ..) else if test ! -d $file -a \ $file != $log -a \ $file != $logerror -a \ $file != ${0##*/} -a \ $file != "$distdir.tar.gz" -a \ $file != "config.status"; then orifile=`pwd`/$file distfile=$topdir/$distdir${orifile##*$topdir} echo -e "check:\t$orifile\nand\t$distfile" >> $log if test ! -e $distfile; then missingfile=${orifile##$topdir} echo "${missingfile#/} is missing in tarball" >> $logerror fi fi fi done } main() { rm -f $log $logerror make config.status && make dist && mv $distdir.tar.gz $distdir.tmp.tar.gz && \ cp config.status config.tmp.status && make clean && make distclean && \ mv $distdir.tmp.tar.gz $distdir.tar.gz && mv config.tmp.status config.status && \ tar -xzf $distdir.tar.gz echo "Check is running, be patient..." getdir rm -rf $distdir rm -f $distdir.tar.gz ./config.status --recheck ./config.status echo " * Log is ${log##*/}" echo " * Error log is ${logerror##*/}" } main xine-lib-1.2/misc/logo/0000755000175000017500000000000014647725152012557 5ustar memexine-lib-1.2/misc/logo/xine_logo.png0000644000175000017500000013213414647725152015254 0ustar memePNG  IHDRX 3sRGBIDATx e>}UG&Qx !" xA]w +͡$ĶyO@ xC)@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@P !B@ @ "@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @ D(@ B@  @P !B@ @ "@P !B@ @ "@P !B@ @ "@P !מpB2ڴ`~'6+ZNs7ny9 ^Ui<0W̟հtJgoڵǢE?9㌅W?sחҥҥ}ח`xr zCms3~}7 |kJ(~~䑽~ҞիGxUas-7-¿h%v>|L8cAWc=_ĘrZ\0Ur*< Lxq2/zxx3 w0 ⳱j+wqsɒ_ e1! jǹ(m#=8X[ qPX"_KmxmXjpsσ円|ռ~wh8`۴ѧAשqTt6 l Z!ah o7No/l ڵ^ehW  n=2{|챠GB>CpL_~Qؐ7o6F7}/ `6Þi |{| .6dsxڵuEx~vqy[щ-iGS 1MߚB'ϫ]kUVB]k%@t]Z.^M2Nbټ-|ˑy Ў̚$N`\ҝE#P6h(Y3ɯhnrxL{Ii[ _ȭh gSFnߴW'uG;ysxwȨMðMl.m>#xW%" 1&Inxrx$-BiU,iysO?mwF RTVYFT*mnx*uR+o`O"ur#W^΢w.̀s=幍LDz_ bL00!-E2pAZ=d;%Y>x`<c#^veedT'k(6Fki,Raě@ gN@;P'pvXqc!@&/68ڊp'AeJ7 xe\lُ9W|Z1m:3fR??n5&uu(4}2s`]^W?C;Lb#{攉DIƯ%)c_&Jբz"2.4n fF?6%V4!3OS$Ծ,Udlt-ɖ|d2J4 - n=wvDB5߹Cҩ"IUbf $/6v6&FNˡo ) 6|Z#Sَ\} gN: :}[Б9t7; "5Lxٖ\k֜=gMBV|䢋^8Xc͒%e==L<_GDZ6Ap8MI0v1bLjs#Q̱Q)$E")!Ml/r,5&;V {`3?޿ *BƊ>HN3@N<%i\演ď[ٲnxxPaϭÂqI5 2k׾c{/߻(v ɻl$oL]C. H,n'nit:Db#^ .zz}u;t:c3 z6L4mF7^AH'Wspױd5g3ZwU y BЅ+W,>мn6Zo6)KѴڗ & ơxTooZg묛"t#"z_}hh0=]֨JDm#lZ1Ԣ5ӭH(烁e/ 2i|L*U<p'p-7>Fq Է̢lq+(* C(?/tkP(M$+ð6dI-cbK THHlV٠08mйKn(1lèikB"n]9X {$7waIj=ߵ6SfD:!}31*&B'"BiF?,g\{M/O\xtx=bvYP> +W.QQgG?Z9:c[[ۙg E6"2iVy(fJժQrՍuA4IrogrZuASe0 ֐ Bn3&ƴ*Ifք1aB+(.DZc{^2'WqLLGiR.z m Ljy W=yg +PGe94s t74ym4 MۈU3eAQDvwGT?<2%K.E5UYDFcvw)?ǂ*iL&Y[ Q7›"͖L0ȋlxLK)dߔJ^jL,J%M'$6f7"BO `]>j S*ىA7Z8yD5fSɒQu gS )^ƍT=PvttZ\h͏?vn=5Uj`,DX(=vs%XFDa/8j̦:c[ڛƿOJkm0`(L 7]Zz$%.9EL-6ŽZa˚--$5kS-Ʃ>~ڬNz]-!iSgh3a% %*.SsHoTܣ0_:o]=EȢm"U ;/x֣[wn٤=m .'^_fa[B-;xk=̉I^px[*44}ߍ*'--#tQ+,i)64scKSI5Zvȩ>Nys Gc SFfh3k%ȯ9b*eB5\-?ַN(rjhȌo=+L~*ƒ+(*1d N|:T&MQlvҙvQ5U/'kmIMu44Scjb1l$bdm[kÎgQk݉,L|[v.|%g,MXt/Cm7Ku]\4O#GS-zoX-&BNGg{Q&Bi0)v_nj$`=ݙwoJKlŶJ|rH4+j;Jy~5|Wzm{cY?HJض&Y֯NrmY)hFJ6XD siT!91T'|3R T\ Oa\-<Œ-q|.h]ƍp)sLBfLg.fbs cglq4 aԒm壈FIs-8+bonZa$Tp~ j8fc5|FWVMF dMd3vl\&ʯw`_/v͟泌|l9;FѦTgTGQ47n&hk_{x|fM#JRަMM_wҥ*-5x{MX" 5lXytsՂ"1&MHe c:+s-?x`Gm$KN7QD( 8oԆZ` fW*(XuЦSLXMQ52Ԙv۸f8@e8qYoIƍ/q7Uk&Ou;C^zP4(}fp+( k5$BMR7`rᩧpѢ(&q8UPn(DOSjilevTM`رO=(P0% OSo!`dy15^rݿ]+w7@U{e/= -NI$&G \ڢ̈́aXVr%4QALCob= O(6FemkXo?nJƈjO  he'`4ʷ ~iTNXG]m`-z8%}U*M*d#˧nUiO9卻9^|pOӼp"ϝȔ ƮAP.5EE-u; ԝ[iw8=}$H$=mic[>J?zq6)Nϼ\zXbqM,|DzUԳWŝ{>lB-p%̈́`7DQx|kB %H`A89pz:3~$caD棶Q~Ok=7юFM:07 ]_V4LƁ M>IJ89~F ZdQ'K_Zn|&DiL _~i ^Uy记3a+nd%2;:L.kz{u.=/~`F)hCukd]hE"KG^6H"t;WQ-7ֈ\ΕPQM8|~Lh8ŶL0#q\6Ω!]2vQ"D^щH.fg $R43\N;C|Kd(KI*z~!݀j^,7/^!`^^7Y>p[ETչ|S\N;SkE}۱QRR&n[zpMe8Nf}/S0tY^uA^t ?2ʳ i԰q:YQ,Px.98Kp_ٞ]܉D(ppR "h6߿&ezѝUcXlƶko~C[sߟO?NL8wkŊ.Xqn7gekQbIc뮙n*ې%$.u 6MQ=S-lwL~LQ̔0<+<ۿDM2F)B9T^k>&VðGNtg !L\:QgKQoa"- h<ĥWyA7$ 5*PpQɧ|!BmS7q_Qjp8w'ixMk4 CMkj$Y/ i'sȬc_#8ڰVAE{Q__*yVfO!Ql@t=8 BVESk' 32&cf\աf/Y NҷqcoXRX>o'*d)7\rh+-}?woP Ok.[a\㲯٦A#hjf&|:eCWturH͍BBo᪣ GY0RFA5淃U% /z{S~ӓt{#vuzua%{+O/z>|{ ׿VBu),Ѝ3iX =h A|Lmmh)NHKuw{fNvۋB_XH! (wuiv`.ܙhiw7nq3lk-Ǫɴ %oK%CF|x^"g/'G ACg?q KRѼ'sd: $8˹0q Jڵ`HN&O}ꠞp&HP!PBKSNܧލ'ZcptݏkiZ 0: [86:yKn޸il'jG5%0-=Jql-[>x;uk}vOWꠃFj%B^ $w4?Q2\jkz\sQ؀LCC^pf,Ҕ CMqVB3Q BSf$ȯv kLMo<0[+x r޵~af XhR=4+XMba͒=b-[4՚>0$zF{}FY[Wxhx| nkwI:9d"- 9Lʳ@_-1!ۏɩCLuQg-D~0m]e-agy+:7mc.tGG߹㇎NWSNN - 'qX7u͏gqlB!llIz._O>1{o6^Wŏ<0ժ RF0;/r HjU=5:`Uh*PѷWz9bcD]p EAlO6x:1좻gJ"\B`V"/ a>9/Mug0ą?)gf8y5~NˠFLyd_?|Yv`Q(8PХ;v:DO?=k[#Y&R E)v>A^O7~ m /qLahy0֋+ܲ~.\ؖ!r8FUsP(:k2jnkS9B . &VAu=?>+~2, BZ "K8>Saįzk|G[[X,28ZLQk-,o'f?_JZ-V0޷ 1HL~z?-{Q9GߠsP/Bo}5yYGz}\h`0,鼢|Cea"h&UA[iof:_$Zɯ ]_K +_oКޱ `\o#|ߢz,{K$F1^ﳔPbk$$̯@* *D))[*\}"se8%̨=j(53p/z'i]PXԋ_Xu{!F5J2FUMj"@ↀwY/"o,}}Fgr{DDxCGٻsMy(~զqDk9C@3U8C[Z[5lxyZa "r?8uC`TW3: Ҥ΀+eՇ4 S\*`yCЂp\؉ &aCyaJ^ưGr0Adc5%"+,KrvTPs*' W-`WUMi dR)g}CEa Bͪ~E7z>07?sŊgtE4֟q\;o9w"zhr~k_x+VM6m|Zvע+1ߏ{`F &5U_=59@Ĩ2uʩtD$kag@8pᨣnYϣ,=JV6@kyr5qJn"gЇ٦Zxyy`j4<)NR"KTe(/)X"-h>DxێfmlV0tj55D. x`:`HI q(ssϹEzW*D(D88?6(CuH0"kS yRڰ3yK'ӯcX>!>l&ܲIzbcSp!, K 'sf0y~v}s?ZPyHq~#\LA[LS<9#pIxEukecp'0]5F +*^r3#"Uy%vrSxRV*xSX{$cڮQXTĀ $t'. c1qp秞2>}`[z'Q/'If8G>i@2 xVHǠJuD䶢$*-* l?GkW‘ KR},Xq3ߟ1-`ڊOzQ-ҍ4rO:t4="&pJ\@W]+^93"N(P0&JKhc8 aaԌ: +`AUx8;-ŏ6iJmPB->ŀ%br՗_&d#D88.8ESQ wz}q`J9 0rŕݭ.?FT;V2 qFiTecc>Mt݌sY"G.CˋC -$,C-*: O?sÍ?,%~z٫]6Rja.#nTJremXmC؎?)FxQ,yA3#P@ '< jf2XB2Z1S9V1kYhafU6(:Aq033@lPSEb({ 8m Oѝ%XfatD[Is|y*/AWr%̋f0{xTZ,L5%۩orgD +emE8S)dbfG80kX$?L:yX^G8>,M!0XU1ccx- B}J!B!톏}쇯:*DbR2G]uwc(&ꪚAj,Lr6^̼y)2`*SP:g4EfMQ|.猏-,p}|+2pi*ʠgWy%bLIX'vs7aMF=_),(yE?-DX*ca56f{*8:͡4 AܡZ/}^rK_=8P(LIA40oF(+ҔJ%c;⺆p8ԁx3]/2BЏ>&[Hlkijبr/[f> #56xݞxtx٩Ī[`fRR!fRiGIPCBK%xñk6|?%Xpg!+WΌoGL _W|Dr#SNS\+bBֵgtNvXĜ2TpÆ3/d6 º.53 [p_?s 5/G&hAj'9VLKCOl޴nw̌/?!%9nD᠉b`H%l`QmT92>7)HS!U.kz n.ͯ>&uyt4^rap"Fl:L~g2 3񢍂)Uw.0v"vuq)Qk&Ja6ړ \ r4vYAm6f2a6yn@o?3Lӂ/|aE:GP7_tٱ.gnu=)SRgGq{5DRx6NDgW'BB>eZP`K}ز=5k(ⷮ6o\rEyvhiw  EtU(cVyr|moG;m:~:-m +!dC¾> ax\->s 5ipp@0cyqP\y@[ |6ᶂ&HQ֪E MmmI~a2 }%@5PQڵ  Jq bKB3\v;1u6b#QQy3z`Z')YV5e:;/)fQf9lvW62I1&ZqAL̠ ֠7\ï&&Fw-;םyщd\++5-ȷ3M9!"}d/Hd ;jVeg=7,GFgc-AȲL[z^*Uj|O|66CIUgz)Mtp.|]o"F|#7﹧A*b5KM^SEl`& q@A݁<Ƅ{+ĄʆrXL@b3a坝5 ϐIPzO\ʻGFv>].#\d7/ƅQprmU0lF FbG?r_o0N3b5Edԏby먑@(o=p&6p wg,ml቞TBAc5K%:C/~BPD!f#K_`i}rDOAk Z6y11aa$RXӶ2:Ry<ꨙ'?y1G#!Z<ŞP4QiL+qYɏS: h[BS-'rW)þX"+e$ .JrVu*ǔ[ {FHJh`9C!*lf+cM#EBݫ(X ×˅4]PiD,n"MhpiC4@8qr'HFi_M7&D\q7wvM6[ 'hts'`Ij\wM\zT\0iHX 1a9$Ƽ sʳ9ΓO%khF ?=:y KֿpPcى +s')JW.ܢ@kAd7Vnj@ƯtπoϡWޛ:n$yZqXzӠR^+Iŋ~)'}㏟oDh]ԆBw d1:u@6B%<괍 cd]<\Y+Qcd "BոTOɍRՀ9W N)QYw9ƥf= &*g( a:e 9a''x樗K6:hcf3? ʄ<ǩK6q@:'\1cX֧YXj;kvsB_uxc(\xsV2?3Jfj4w=3֎T/['{-Uf(k S)ݐA(n{e ݖ'7m*|F1Ω|9z!bt^qPH1ozzt.\,'`YX18nlԖ;p O)<`>=TxD Vu܏sd[XN!Syd:6c"z&Jlb>z׿nD̋-ѕaD5P*Eq\'ݫ;U I4~hRЩR 1m5x #e-f+r!Z ;pb:mhf3Vەʆ[MLШ`Ni!*l&ڍ}/ŢἎr˒`tBC4JSH7D9@!NR'ܴ1|𡳄>p  G\bpuyFRE4{!/#zU4wÙ"%M.?cCNRJ>al |6mzk,(jhu&lD'W0y0'8Wk[*-1b.v\9΀W\cdxa\ĄkZócp0_BM%W3%;9JبXጄ I!$)5Qի ׆ŪUUhnJy .c^ixA`5(p'iJg Q1m7Xm\BceWʭE Z^eEDv{C3Iӓe( `YsV@K{EZL4ls7F ބTi߆*3¹rR0Y%AY(ʼnhk%RhwCJ[|hMxUo"v|?SįŜmR5FԔXxÆ`<=1SjdI1l5 nwRG\aF,0P>NEswpt*;ׇ3or)TcTn1qx}R48t::?xJe'սn.|~Ѿ悴pPCyh!Kpl^6m*M~әL)xַ37/o~X]=ۍp@M<ƥFˇ>^s͆7qMT Xm| 8ṅo$0jQa 1AʞKXI:vl)`E1vV"u C-v_BajT,E=[,N?is^myL=TTxu"'Гu {aW"U0EyĮ;LhlX*+5Y8>d=G>׀r9bcF(ho^ ftTO팙"l5ݺ!ҍVk0w%ZFѐ)CeHF`:)b8އ8 lư=?52B8mT uU,3sw] *. NLT{R1Z ;AE=r.U"0-n\l3B򛣔}MUɫr%} ;N * SvJe58颣񑤱Qk<>2 q^`|皞9 g%0dƶASU؜2ȢGNDO!j8iDQF[-<[S/ybJ>6,b Tʌa< ie.;8jD97cCYf'!/]@V"l.YL5z !L{Fa-}r0I1~ GF؋f M lq8}P9_W4(8ZՖ96|Ҧ^IEs2 av>0)wBYfH$`8Hb; )QN8S ŗ!4a{EaQV[#e`*j}2YOT!N9'_Vk'jrøLC3.'LDutd1vL9# Fqѣ"%VsFlC`d,:@Ԯ@Y*ba´aP0Vƽ{裗,\8X'RYuvTN?xBWPN>hOE`F=o TQ*j5 `abr0z9a!Z@$0(.Z~m0|&yءì§:.L:f9Ph0bP.:yP(%fn;e4@5yr[6x2Q: FJ-R:zq(*i+* t}˹v~6` гہ9Xm.]ndՅLtf U|F=P~ǜG.]@طj3y>oCX.̑Cޜ)nVSdžx)e뮓ٺ)ۍZvƁW*e~ X F"&G!ZF 拤~(]Cqp!20+GeGg5z)~>c,wvh4ۺ\)9ܴ KHud2 684̤y8&1U0= B Tp!aU(G۠@ h400j[ㆲBv=SOQEa֕*Vm8zPǯc$ D Ka_ü k!86Zuv)vq;|.̉ Cul51#ԟj` +,WpGc$%Qm|, NvN nn ӠSi!顛.puL`:2*;£4GS'7txJuzpr}LÊ`Ut:sIy4ƕk:p.GWNf,eS̅ms9.ܓ'vAgȗKp\]]K|~s@NVTaVlb&8xno>L1^v)EFDvl^(~RQ֎&5Lz~ Qf|x(L`H!]؁%? O_Hk ^j0ȼf~@mose-xS.U:rRT9hOUUʼnZwO[\:edχTVFT}`PAN32^zp=o`==…zi' S<'6U+rarAξ'+gB1>K3 :`gtwc~[!WdCxÀK^6:ϛ6mmO:]mm0,ֲ,< 紷F A&,C[k#}ᴐ~4ytixt## :aI}m[ws0-N8[~[jpM7?d }/2[5ʩ-TwrRz EJ):8+FIRnLCk%󲗾tqfBT&[y*t226jv,4ޠ;ao2Y<ɝz/{ժ'~W? 4\|.@PV𸛡`B546P@y7A쌍Q`ac .vp7|[`#B6u84Bh8Xq Or)AJEӗ Y!fP{@0fl, I6uSoD|!x|Pw7dG$0H4 @l?XUڱii ~Ϲ0o!8d]s$6X+`ŋN%p1 E Ap-v{0q\͘j-PXl~>66¸TZ1y2S(PVwui*͋} N>Eՠ/q?: "5*&ӎJ1jfaeВ,6#;+qn~䐤BF\.VFElsI{vtAP* 0쓉ң fNtYLV݃;  +rRLڥ Pop8O):שT&"LaT$EO2F襰8 N;, VBRwxHD72[EG./Kc QqI|{@wt&z( cXPa0tuN0OӍX dbӺ1x$lgxpʦ챇nF[g ȫ9ݕ{SQK6EIa"?15vN3{<,pLN9(^O?\=:|^nӲe=Idp̨KⲶ1tM `  `x$$L'$_BPmZ LMN ƽmoU/3sVJ3zA;FwscgًBfYFFQg,]9I)1]ǖN%fT,* )l@ &"3'D({Rahч 7]pAj1DMVT@k: FbS8.AJR6{{S<(=N%tFiK/ fXXӏ%JX o@TR qXÅ'vN` j4ho تp07}_g_xbo/xJJHq<B"qM7J$Qeй vUlZޞ>^u̓SCf%>Dj4a N"ara3 uYgMBKUղC,͘*ww[?p8S=R8=).-{"_ 6ٸ[Ȍ kKXc k/bۍpXpe|00t$_YgTXs4鑛lGG ?ʤ@@ FWj3# ҭ^^_]xl9vSعS-.Pm 2+! dΨW9=_X!ܼF~0ҍR@/^4& M~85Vظ B,,<@'v@#n2rL"q0)G8@A; OFTbM1T6v{н휳?y"/F e)xxa!x#A*{*zBVfzWFYiMBPNx1e7nM$dykafShpcCt)XQ;c :rM0:p/ZДo,NS~:MMۛ2tw/brI *pTGDʆJM=H8ڰ}EޡVW;:^TxY9e$F *3 X,i9\&0Z BC^F.B$ĶBUގU'}Wk N8 0 xZ$Xu&4ӆ1}n8l񶆛M) N`0H"~1ܽ,?`3P2ntu)Z^ɕNjۃ< l, Q2% VUhazfm6je>@ ehWN'N+vh(k&Q`"!n%Ex0$|#}h˖P]k꣏W2^6LcV>)9X)eI`b#)iGM嬀Cz1g,-FtĤٹ'y=+p'_Ԏ%Ƃks/ /H `a(n<>뮝)MxXr<g|B4FġyL;; N0ޓd16¼-,)Y9{0Bx }ゲAJI0@yF_߸ҊE_^diаCקl^/tBwu55`(vK?muuVk(SXMl8hg{l RsJp_X<j2!BCĩGyJ,ш̓. B(Jb(=UUV&N d}T؉[RVr-V0~sO;t [|߲%UW'C IX]2\@]twu ToB r;ŧc84 ;P Cpqq#1bh yљ$|;OF@UX -6x_^ف.Ѣhmڞ6۷%Ob ;VmpXTch4cqƍ@U[ O#z߰KxFD\AO{6{c]"a@@O6/*/^8,E$d|h蛓3~/{oV%U^`N"P@')r:d .e8]Ɔ@;*8,[@Zd'ma@\(8rel4 * E Ga'55Шqb)hvAeg)kTK}h8CKH$ +9Yٜl<@,ШY;r{{Ym7jG|әQ5>g&h^xg^DWS=Jc#}IJED.`m;|ۚZuMDkarca|nqS8?k|R̋?r4LwYfDP2XMPMdXI%+z=0C_t >'52}en—2׼Sx}B:РRyUXp3<C{6 FA,=I`^{0T<8hO?z",¯vэ8i΢*dhb;g^%ot99 CR,8֭)xԄdqnVR~='ܹ.S(twɕR2%y܊fSa]U%͘9ݗ`Eʄ[VRb(& G;*aowju j eJ{n.kS8X]+J*UUNI!)|>9G $VrI۶ D$1e1 p+>tX9L.|y|*;X4?=:UBs3t/  hT~wEzCB8sΓg傛2iC+lۺ5iv5}>tS*΢oˉJ筧[lmA`Xiij2y[u֬Xdq52 a6pz*,ջ~dOX.(ЇS[ol8MdӌX"ab:CI)f"dڰO*m:L[A jˋ.*ncQFs#wx`NT;v2:9oeyc {";urBm 9g{9aZQ,@ E2n2uO-)8۶]#U6B`PKXOK󭟼ByN#`Bc9aBbem^yٻnr_ymuu86YS c BXV&)gxS"0aKBkuZzg G:;qnLAy7)XE ufjn.yc)UgisSAiy= zhDbҴ+O#lg%St),se|lJ`a0%<qDRZE_&ƢUեVVu8(vA63˦X(Ix 8a g~_?ܼvXAY/9>H3't]RMM.%<55؏caft]jy1 `ciu[OOkzIoHEsҟ+VԌʒ4ۣ8-}`ɑ!44XCa m<}:R8 56X)zEULzRY%Y@CU-`uu g{i O>N͞mݺU1pNfB,E"d?46)[7lHC%|ESYٺUU3HD-`@MIb'/V AmUG͎t[4*0ǖxe2a7(Y>'e&F}%a( Tפ^< !|ނH %`V`/|f"|ZQ9e\&~acŢ *,+lg\8AC ^xKKE.DN어bȊpD mU%t١C*~r\:+ ɔ#J@{G#e{{Ɏp2ˡfL56b-l ǼroWؽ$74#ǣDvh 64C IoHΑG>ţ Loml9:*뵷Κ%vv*xvVW۠du6P/8˧W&g*aS;;RKCԹ+SЬs+`#B{6FwM8ڷkkڶM"xScdm-R@@-)CO+(E<"YY_̲vaL n{($\7P9 v'H(JP_AۧE")hvu*d;mp*DQ3L8goG$i?V 64ArYv۶.F@*fCA'mEBKM,緤'8l~`u[\V,'_4|f7 ӣPa Il0CGJtx-g=%RBM"Y <(9.hO S-xʄaZ9pg` =BA%0ЙÉ!nN)6;:R^o۷W£jmb0 $š[~/e/SPtt(ӧKMu:}l}r&IhY{{q2yK Eq[/?pTT,>(b3>0 *6㱴Noٌf%%իMMb_JՁgxD 55B"iuTI F OGnivXY1O@451g}v^PJ̀[SyPt&ZZ`'5k,Y iZ -[`ɡ!Kc[ft=PX).n DZ:x6xڊGOFs|A;pv&t bZYܴ J_YdWXU)ttfC }}hšxQQЫSjpѢV*B(XmYnО@Q_\.!&AN݉X^&4@48Drǔp߅ΎUnwpUa?<ԦF4@ݝjhB)6ОE%J"+CloOVUY0F+U.pR\K,w#/ATI%|"Q` &Qi65u޾<% *ޤ؄QqxgV24lq1< Y$crɲe$<qZ@ZC~LZ=bcjn,R!XiӬ@ eeJ_X]pVDEFsؼ~rO[hp:̙4;Q0+|u!e~gi)MSŵkFKc`KFY>8 _\@YGP(J!I_LX,TyKS,-Ncsn6nPπ%Ćzk2eј jmz;;7`8he̦PHo&#̫ !ptyU*J`"r[bG0%%VB+Md3YNsfHаzS*|#|sˡc(f'>Ќ@s.laxy/iP`M}N8'c|p zOR\/h:]1ګtaPx6zԈ>?4 J1(rj&>mj[6Dtu0 3hd$˒B*X`.tŊ#ª| ZN4`mƹK0B[-qxիدՅ 5Ūn;54xX8uPPW@G8-tUGސ~!jkmۺ;q*"۷XnFƍ'dp0zI T94Km<&͒pBvtK $PX.-qvP_+DQf#(ˎR{0,ɠ ߏsm67CkÂwMT,P(c8=-mmݘ 14 g ,ϰjq 󩵵pVI a]bM) *[}PWC5C.[4 ޕ L+L<%6jFQT|(a:@Qa7 '`f w&r˭N{:k'1RVAљ>S FKJ,,ٚwK>z1B# $&Kh]ǠapAsGQLq*X*O4zD 7<􆄰h;S3e1shB,I#AGmd)LTY^0jЫm>+g⍍ ø9]hZXU>s'_ӧ9xEOL֡Z<`a7O">۷ m346\z}f?Z:ֱボ|6ksQւ%ã -X1j|?~/:y~J*b /f}_WHoH>*8^_\K1.gKsMW#WHA | D8lJWd\'_-%OQgEC5qi,Ÿ\}[i/ O-!BAS5 /{wN̔a=0}y@-h AF--BB¢{;kj"F(f1P:̑p8Փ_ԆZxPC F*6TZ03LXhŃ{Y履Ʌ?eeVQϰ3@-EBskWYls&:)$$ۯZ4*;0WFoKʕ'!(aM G~5JBh@#yV߸tœ `_fimVkKKE"105Fsk|yQ_Ha''t F<>p#G\9Z;+eZڗVS¼]=,#[nZ;{vI!42 b M?ʩ*VʼFM)̕As*VL<=>26N#K CMka~vef U*k^f Y98Ʉ(? uꛆWj=~ fwq9o3.DAe` O:j Ƿ̜t?Q& {gE<;u[ѵy(GxԜNNPݡAZ^ ^>˥D"iZ1/N/KNa?HeH5a=*#%0-l,sP`NDta I,;l c Jh$evp.[? Y\B2eZJ٭x^-XqLTFSbb%SnEc͎>Ϛ5?jB`F(,G*rGgwA[0r plݤ:݄\MRP୰|ʆϚ z<֐qO}_ Md aioP PqK.'Z=e ;ڃΊ˯mm} Y9ĭ,BAj}KκilǂQl7mzyN|jdH{7mє¦ƻ݉Fa+bggw,/@r0 c\(F  &%r bS6bc(֭N\kӟ=Dм 4Q@J4<崚* ۧiDXql!H'AS -Bs>1!E럞fD(Wr;&G(ыyVUݳ^9rM/yao_8)@"uw-<6(Eu&5өdQz-, xZ1!Bc5pml&&tdtMCk&/wv1 =wM&?Y"T,zzTBP_BUpd_ª'S|>E8PAc'7ZԂ!9Xm J]m3T=EB4EEH2i_Z0q 5RA9B$Bf#,4֭=hmvꪢcO|2/wvjDѺhaֺӿ\7U𸅍ӧymQ-K|SvyKK>Κj9pۏS";E5>韾N9':n<0oepWN!ۯY0ߪ=b(dS[ ӊD9c̰nHdQmE҅AjjP۶6s{K]xYY ?=Vv呁phL3ώ7m#iQXpY?2TC͘unKAoa_BKs9AwԴ7 §('fcev@smV]/ӄ1W`m2ś=9(LQpb4CeWQH$R\ԱlwX({Lôi'@͈h~ӣ,BYm ò xSVDG:E1Ș4 ߮k S"¡7`~=2Fa ؂E`GGso 6X09spUnON} .`pN r6 u\6/]IL踲f`dB4̳sti:^fWj~=WE9%i,{nxhk75YG5&Vz댭" c Fgy6b`}R&L:C5h囘NQS>2o晆c5s^M B8c/׌(,RVʲ_-X ̉aA:6c1rզ̘+B#e]!T Ol򋋽7-~K,Ք@'#Ï'\B*ӶuxϽ%{T"\CEC!̼cyz*GY atQ:jugO+y[߾{=AW $Δ ]wn؝,Νk[i:+`e(4̎mh"B/Ԅ֪r!{ji' =͛g }g'dTV F942Z[b#l>}q9~ƘįL 4J,[_qeVSBB/:SU<@ qѣ׀jP;:>u8^<~CO+0„N\GݦkTpJT,(,ntP0J!JwOo 9- 9ak`Y 75zcɤ a2B[Zw!>Zx_,IǠ>r\Ge+~3FB( =V|m L5_p0͠tde!RAhoWykdΜvE8C OK>&ss6wق=F:R3jL&=bD rکܡ&F*"לpA=ahx .`oho.y^+3nN3S`c-\WWǟJ"+DFoP(5@LRAfBI:bOzPhPeҌBD2ڂf~x]jCY)dXQ A 6O(ܷžA݉]g@ܱfa-"E(:- PЏ&,lQ(/knnm;~5]qױC c 6qQu͗k E={{Dʞ5F`ba$ C΄L0C㌮"wZEQt[,+"\2_o W*5e>Ԗ,›P &k'OW{NU!\0ɕk>XVSBȈbI]Yƌ嘆FY$&STH]u-9sn ZlKaG9i څ=ܜP(3FkjIGUU㌁^}6575Fs4GQ`jFyyE5Up}}g4 ' ϯH j)DD_SSU  ȘC Aݻiw-!ύ11 ĝ2ɤ='6X"K&BH 'G 5"Z[đԺ L_yDW]'Ïlʔ!֭;/25'`2_{jakb免@Ֆ=c1堩;w>Qv?n(6j M_x,YL4+~YbveR_~ h 5 x(28%_hdӤbᇅipg+b0jB!|] ֏>wwk;^u_L+~. r8lS H䌂A-yB%Ah:_0/s9hYcKX2lC}/藍]9lhHM&WW)DDMw ;Gf}dRGǮdΙ} 5^8A/iK$PkV(MMK?,$p"5j s^•U8_~iUYVqaF()k&v!P=#STH$;.'QV#!W| 9ٷ9xܒ)s=ⱕ!C/ηa/>4mX5W,nhM**y܊ۭDX`xZU%YMdJ$,RvF5%!NW%%˺!݅KJP(RDN|k`Lmy﫱K]zJexVt m\t|^i۶' M֭R~XRzxekJq4[GY{/p~5HGZYr<}c8px?#p0]]64zXkރRמ`zMv _miY

4]6% ƪbVk*\b-.ߒo 1t0HqS!AG0]k  vSH B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H   H B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B x Lt$A5^{Cvi+2ё &1rrE]zO?7l䁎t7=;~&!$#<74^I n^5s1P`%ABgB0U5~g}G}t]w]6g2 :蠳: ~hڴiDO?}衇}]E=#_|7V wg}7~I'‹/xsYdIGGǩ:+83zzz?G}g馛4kp׾v衇>̯Y뭷!f-O;V o3>p`x?O>)U&?fP>駟~ܥ/ϟ?_: v}ӦM=SO={@&'!$'|*H[N5i6z4@EsCoW_ 5ѯ~+K/',ޜx|%Ԫ</oe ,إ^L&af~/Թ2Ja ~vm 9s=&3׎o lϔ3ϼ%Iމ(7|>kpMwQ^^w+A*ށ_r99мI b2Pe|? Κ5 ނc[̧T7߄jdtkҾϜ9sq8. x.Zf91y@0[nQ1OS3wkǷ|Asvr5׀+^Gm.Ͳm1ܥ,n6%MԜh$1IBMfnC'L)3B}mժUΝ F֭[8 rP+2hѢEP-:nzow}М?s>o*]0A <Ƨ%<쳳mn䭷5C\;%666ϙ۶mmGj6mZA(!,"ݬc07s y?$ a~`1f!?~"^+n0,X`\N.3`| bG?ѹ z3-{Ō;\ we˖yc9~mG +H*h v|C9D圽}N~wwRla';,M[h$Ba%|dPHI^RˆX 'K,پ};Jx.Py]ve>oGtzX]z9=ccB^#I!̾vdw!,P~&!$)%cg}~gwFfo?\r%A+ /J&[z5k˫׿!"577x===Cwjz݌{?l5j5ZcջI bB޶V0Zz,% nV о~ꫯ;~%{N!|'|>(4T֭upP23wkg;7J;2_~' %%%:,|_`e>kBMYE[[,|Ώh39>:dKKKf!1;P`^wq P3x/獃 ,e'K}eFsB=}q1I bWBZ.kkkm6[QfǠ~Mx_? U.Z( 7߄"Aef=GP+uQ|+xH6.:x@ v^3<#{<0nlМ+;̵+87o<0L!|p93S~~MMMpE>hddR_sY`{(/@c-x?T[3g?Wr>+]$I`=f꜒!x]web vʔOE W\i݅>裧){8=II VeJp\|;sgyvܹs/袃:(yݓPB !$vkqO]xs=7N`TJ2 !\{l&0tw/Z]]*#%KDO%!$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ B  !$ H 0ٔ#IENDB`xine-lib-1.2/misc/logo/xine_logo_text.svg0000644000175000017500000000565314647725152016340 0ustar meme image/svg+xml xine-lib-1.2/misc/build_rpms.sh.in0000644000175000017500000000537114647725152014726 0ustar meme#!/bin/sh #DATE=`date +%y%m%d` DATE=1 PKGNAME=libxine1 # Some rpm checks RPMVERSION=`rpm --version | tr [A-Z] [a-z] | sed -e 's/[a-z]//g' -e 's/\.//g' -e 's/ //g'` # rpm version 4 return 40 if [ `expr $RPMVERSION` -lt 100 ]; then RPMVERSION=`expr $RPMVERSION \* 10` fi if [ `expr $RPMVERSION` -lt 400 ]; then RPM_BA="rpm -ba -ta ./@PACKAGE@-@VERSION@.tar.bz2" RPM_BB="rpm -bb -ta ./@PACKAGE@-@VERSION@.tar.bz2" elif [ `expr $RPMVERSION` -lt 420 ]; then RPM_BA="rpm -ta ./@PACKAGE@-@VERSION@.tar.bz2 -ba" RPM_BB="rpm -ta ./@PACKAGE@-@VERSION@.tar.bz2 -bb" else RPM_BA="rpmbuild -ta ./@PACKAGE@-@VERSION@.tar.bz2 -ba" RPM_BB="rpmbuild -ta ./@PACKAGE@-@VERSION@.tar.bz2 -bb" fi ##VERSION="@XINE_MAJOR@.@XINE_MINOR@.@XINE_SUB@" echo "Creating tarball..." rm -f config.cache && ./autogen.sh && make dist rm -rf rpms mkdir rpms echo "*****************************************************" echo echo "building rpm for @PACKAGE@ @VERSION@" echo echo "current architecture:pentium" echo "rpms will be copied to ./rpms directory" echo echo "*****************************************************" export XINE_BUILD=i586-pc-linux-gnu eval $RPM_BA mv /usr/src/redhat/SRPMS/libxine-@PACKAGE_VERSION@-$DATE.src.rpm ./rpms/ mv /usr/src/redhat/RPMS/i386/$PKGNAME-@PACKAGE_VERSION@-$DATE.i386.rpm ./rpms/$PKGNAME-@PACKAGE_VERSION@-$DATE.i586.rpm mv /usr/src/redhat/RPMS/i386/$PKGNAME-devel-@PACKAGE_VERSION@-$DATE.i386.rpm ./rpms/$PKGNAME-devel-@PACKAGE_VERSION@-$DATE.i586.rpm echo "*****************************************************" echo echo "building rpm for @PACKAGE@ @VERSION@" echo echo "current architecture:pentiumpro" echo "rpms will be copied to ./rpms directory" echo echo "*****************************************************" export XINE_BUILD=i686-pc-linux-gnu eval $RPM_BB mv /usr/src/redhat/RPMS/i386/$PKGNAME-@PACKAGE_VERSION@-$DATE.i386.rpm ./rpms/$PKGNAME-@PACKAGE_VERSION@-$DATE.i686.rpm echo "*****************************************************" echo echo "building rpm for @PACKAGE@ @VERSION@" echo echo "current architecture:k6" echo "rpms will be copied to ./rpms directory" echo echo "*****************************************************" export XINE_BUILD=k6-pc-linux-gnu eval $RPM_BB mv /usr/src/redhat/RPMS/i386/$PKGNAME-@PACKAGE_VERSION@-$DATE.i386.rpm ./rpms/$PKGNAME-@PACKAGE_VERSION@-$DATE.k6.rpm echo "*****************************************************" echo echo "building rpm for @PACKAGE@ @VERSION@" echo echo "current architecture:k7" echo "rpms will be copied to ./rpms directory" echo echo "*****************************************************" export XINE_BUILD=athlon-pc-linux-gnu eval $RPM_BB mv /usr/src/redhat/RPMS/i386/$PKGNAME-@PACKAGE_VERSION@-$DATE.i386.rpm ./rpms/$PKGNAME-@PACKAGE_VERSION@-$DATE.k7.rpm echo "Done." xine-lib-1.2/misc/.hgignore0000644000175000017500000000007414647725152013423 0ustar memeSlackBuild build_rpms.sh libxine.pc relchk.sh xine-lib.spec xine-lib-1.2/misc/cdda_server.c0000644000175000017500000004157614647725152014261 0ustar meme/* * CDDA / DVD server * * Copyright (C) 2003-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * This is a TCP server that can be used with xine's cdda input plugin to * play audio CDs over the network. It also supports playing DVDs with a * patched version of libdvdcss. * * quick howto: * - compile it: * gcc -o cdda_server cdda_server.c -ldl * * - start the server: * ./cdda_server /dev/cdrom 3000 * * - start the client: * xine cdda://server:3000/1 * * to play the entire cd (using GUI's "CD" button) just change * media.audio_cd.device to the server's mrl. * * 6 May 2003 - Miguel Freitas * This feature was sponsored by 1Control * * note: see also libdvdcss-1.2.6-network.patch */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H # include #endif #ifdef HAVE_NETINET_IN_H # include #endif #ifdef HAVE_ARPA_INET_H 1 # include #endif #ifdef HAVE_NETDB_H # include #endif #ifdef HAVE_DLFCN_H # include #endif #define QLEN 5 /* maximum connection queue length */ #define _BUFSIZ 300 /* CD-relevant defines and data structures */ #define CD_SECONDS_PER_MINUTE 60 #define CD_FRAMES_PER_SECOND 75 #define CD_RAW_FRAME_SIZE 2352 #define CD_LEADOUT_TRACK 0xAA #define DVD_BLOCK_SIZE 2048 /* functions from external DVD lib */ typedef struct dvd_s *dvd_handle; static dvd_handle (*dvd_open) (const char *); static int (*dvd_close) (dvd_handle); static int (*dvd_seek) (dvd_handle, int, int); static int (*dvd_title) (dvd_handle, int); static int (*dvd_read) (dvd_handle, void *, int, int); static char * (*dvd_error) (dvd_handle); static int dvd_support; static int msock; static int cdda_fd; static dvd_handle dvd; static char *cdrom_device; #if defined (__linux__) #include static int read_cdrom_toc_header(int fd, int *first_track, int *last_track) { struct cdrom_tochdr tochdr; /* fetch the table of contents */ if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1) { perror("CDROMREADTOCHDR"); return -1; } *first_track = tochdr.cdth_trk0; *last_track = tochdr.cdth_trk1; return 0; } static int read_cdrom_toc_entry(int fd, int track, int *track_mode, int *first_frame_minute, int *first_frame_second, int *first_frame_frame ) { struct cdrom_tocentry tocentry; memset(&tocentry, 0, sizeof(tocentry)); tocentry.cdte_track = track; tocentry.cdte_format = CDROM_MSF; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) == -1) { perror("CDROMREADTOCENTRY"); return -1; } *track_mode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0; *first_frame_minute = tocentry.cdte_addr.msf.minute; *first_frame_second = tocentry.cdte_addr.msf.second; *first_frame_frame = tocentry.cdte_addr.msf.frame; return 0; } static int read_cdrom_frames(int fd, int frame, int num_frames, unsigned char *data) { struct cdrom_msf msf; while( num_frames ) { /* read from starting frame... */ msf.cdmsf_min0 = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND; msf.cdmsf_sec0 = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE; msf.cdmsf_frame0 = frame % CD_FRAMES_PER_SECOND; /* read until ending track (starting frame + 1)... */ msf.cdmsf_min1 = (frame + 1) / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND; msf.cdmsf_sec1 = ((frame + 1) / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE; msf.cdmsf_frame1 = (frame + 1) % CD_FRAMES_PER_SECOND; /* MSF structure is the input to the ioctl */ memcpy(data, &msf, sizeof(msf)); /* read a frame */ if(ioctl(fd, CDROMREADRAW, data, data) < 0) { perror("CDROMREADRAW"); return -1; } data += CD_RAW_FRAME_SIZE; frame++; num_frames--; } return 0; } #endif /* network functions */ static int sock_has_data(int socket){ fd_set readfds; fd_set writefds; fd_set exceptfds; struct timeval tv; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(socket, &readfds); return (select(socket+1, &readfds, &writefds, &exceptfds, &tv) > 0); } static int sock_check_opened(int socket) { fd_set readfds, writefds, exceptfds; int retval; struct timeval timeout; for(;;) { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(socket, &exceptfds); timeout.tv_sec = 0; timeout.tv_usec = 0; retval = select(socket + 1, &readfds, &writefds, &exceptfds, &timeout); if(retval == -1 && (errno != EAGAIN && errno != EINTR)) return 0; if (retval != -1) return 1; } return 0; } #if 0 /* * read binary data from socket */ static int sock_data_read (int socket, char *buf, int nlen) { int n, num_bytes; if((socket < 0) || (buf == NULL)) return -1; if(!sock_check_opened(socket)) return -1; num_bytes = 0; while (num_bytes < nlen) { n = read (socket, &buf[num_bytes], nlen - num_bytes); /* read errors */ if (n < 0) { if(errno == EAGAIN) { fd_set rset; struct timeval timeout; FD_ZERO (&rset); FD_SET (socket, &rset); timeout.tv_sec = 30; timeout.tv_usec = 0; if (select (socket+1, &rset, NULL, NULL, &timeout) <= 0) { printf ("network: timeout on read\n"); return 0; } continue; } printf ("network: read error %d\n", errno); return 0; } num_bytes += n; /* end of stream */ if (!n) break; } return num_bytes; } #endif /* * read a line (\n-terminated) from socket */ static int sock_string_read(int socket, char *buf, int len) { char *pbuf; int r, rr; void *nl; if((socket < 0) || (buf == NULL)) return -1; if(!sock_check_opened(socket)) return -1; if (--len < 1) return(-1); pbuf = buf; do { if((r = recv(socket, pbuf, len, MSG_PEEK)) <= 0) return -1; if((nl = memchr(pbuf, '\n', r)) != NULL) r = ((char *) nl) - pbuf + 1; if((rr = read(socket, pbuf, r)) < 0) return -1; pbuf += rr; len -= rr; } while((nl == NULL) && len); if (pbuf > buf && *(pbuf-1) == '\n'){ *(pbuf-1) = '\0'; } *pbuf = '\0'; return (pbuf - buf); } /* * Write to socket. */ static int sock_data_write(int socket, char *buf, int len) { ssize_t size; int wlen = 0; if((socket < 0) || (buf == NULL)) return -1; if(!sock_check_opened(socket)) return -1; while(len) { size = write(socket, buf, len); if(size <= 0) { printf("error writing to socket %d\n",socket); return -1; } len -= size; wlen += size; buf += size; } return wlen; } int sock_string_write(int socket, char *msg, ...) { char buf[_BUFSIZ]; va_list args; va_start(args, msg); vsnprintf(buf, _BUFSIZ - 1, msg, args); va_end(args); /* Each line sent is '\n' terminated */ if((buf[strlen(buf)] == '\0') && (buf[strlen(buf) - 1] != '\n')) strcat(buf, "\n"); return sock_data_write(socket, buf, strlen(buf)); } /** * Setup dvd read functions */ int dvdinput_setup(void) { void *dvdcss_library = NULL; char **dvdcss_version = NULL; /* dlopening libdvdcss */ #ifdef HOST_OS_DARWIN dvdcss_library = dlopen("libdvdcss.2.dylib", RTLD_LAZY); #elif defined(WIN32) dvdcss_library = dlopen("libdvdcss.dll", RTLD_LAZY); #else dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY); #endif if(dvdcss_library != NULL) { #if defined(__OpenBSD__) && !defined(__ELF__) #define U_S "_" #else #define U_S #endif dvd_open = (dvd_handle (*)(const char*)) dlsym(dvdcss_library, U_S "dvdcss_open"); dvd_close = (int (*)(dvd_handle)) dlsym(dvdcss_library, U_S "dvdcss_close"); dvd_title = (int (*)(dvd_handle, int)) dlsym(dvdcss_library, U_S "dvdcss_title"); dvd_seek = (int (*)(dvd_handle, int, int)) dlsym(dvdcss_library, U_S "dvdcss_seek"); dvd_read = (int (*)(dvd_handle, void*, int, int)) dlsym(dvdcss_library, U_S "dvdcss_read"); dvd_error = (char* (*)(dvd_handle)) dlsym(dvdcss_library, U_S "dvdcss_error"); dvdcss_version = (char **)dlsym(dvdcss_library, U_S "dvdcss_interface_2"); if(dlsym(dvdcss_library, U_S "dvdcss_crack")) { fprintf(stderr, "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n" "libdvdread: You should get the latest version from " "http://www.videolan.org/\n" ); dlclose(dvdcss_library); dvdcss_library = NULL; } else if(!dvd_open || !dvd_close || !dvd_title || !dvd_seek || !dvd_read || !dvd_error || !dvdcss_version) { fprintf(stderr, "libdvdread: Missing symbols in libdvdcss, " "this shouldn't happen !\n"); dlclose(dvdcss_library); } } if(dvdcss_library != NULL) { printf("Using libdvdcss version %s for DVD access\n", *dvdcss_version); return 1; } else { printf("No libdvdcss: DVD support unavailable.\n"); return 0; } } #define CMD_CDDA_OPEN "cdda_open" #define CMD_CDDA_READ "cdda_read" #define CMD_CDDA_TOCHDR "cdda_tochdr" #define CMD_CDDA_TOCENTRY "cdda_tocentry" #define CMD_DVD_OPEN "dvd_open" #define CMD_DVD_ERROR "dvd_error" #define CMD_DVD_SEEK "dvd_seek" #define CMD_DVD_READ "dvd_read" #define CMD_DVD_TITLE "dvd_title" static int process_commands( int socket ) { char cmd[_BUFSIZ]; int start_frame, num_frames, i; int blocks, flags; int ret, n; while( sock_has_data(socket) ) { if( sock_string_read(socket, cmd, _BUFSIZ) <= 0 ) return -1; if( !strncmp(cmd, CMD_CDDA_OPEN, strlen(CMD_CDDA_OPEN)) ) { if( cdda_fd != -1 ) close(cdda_fd); cdda_fd = open ( cdrom_device, O_RDONLY); if( cdda_fd == -1 ) { printf( "argh ! couldn't open CD (%s)\n", cdrom_device ); if( sock_string_write(socket,"-1 0") < 0 ) return -1; } else { if( sock_string_write(socket,"0 0") < 0 ) return -1; } continue; } if( dvd_support && !strncmp(cmd, CMD_DVD_OPEN, strlen(CMD_DVD_OPEN)) ) { if( dvd != NULL ) dvd_close(dvd); dvd = dvd_open ( cdrom_device ); if( !dvd ) { printf( "argh ! couldn't open DVD (%s)\n", cdrom_device ); if( sock_string_write(socket,"-1 0") < 0 ) return -1; } else { if( sock_string_write(socket,"0 0") < 0 ) return -1; } continue; } if( cdda_fd != -1 ) { if( !strncmp(cmd, CMD_CDDA_READ, strlen(CMD_CDDA_READ)) ) { char *buf; sscanf(cmd,"%*s %d %d", &start_frame, &num_frames); if (num_frames > INT_MAX / CD_RAW_FRAME_SIZE) { printf ("fatal error: integer overflow\n"); exit (1); } n = num_frames * CD_RAW_FRAME_SIZE; buf = malloc( n ); if( !buf ) { printf("fatal error: could not allocate memory\n"); exit(1); } ret = read_cdrom_frames(cdda_fd, start_frame, num_frames, buf ); if( sock_string_write(socket,"%d %d", ret, n) < 0 ) return -1; if( sock_data_write(socket,buf,n) < 0 ) return -1; free(buf); continue; } if( !strncmp(cmd, CMD_CDDA_TOCHDR, strlen(CMD_CDDA_TOCHDR)) ) { int first_track, last_track; ret = read_cdrom_toc_header(cdda_fd, &first_track, &last_track); if( sock_string_write(socket,"%d 0 %d %d", ret, first_track, last_track) < 0 ) return -1; continue; } if( !strncmp(cmd, CMD_CDDA_TOCENTRY, strlen(CMD_CDDA_TOCENTRY)) ) { int track_mode, first_frame_minute, first_frame_second, first_frame_frame; sscanf(cmd,"%*s %d", &i); ret = read_cdrom_toc_entry(cdda_fd, i, &track_mode, &first_frame_minute, &first_frame_second, &first_frame_frame ); if( sock_string_write(socket,"%d 0 %d %d %d %d", ret, track_mode, first_frame_minute, first_frame_second, first_frame_frame) < 0 ) return -1; continue; } } else if ( dvd != NULL ) { if( !strncmp(cmd, CMD_DVD_ERROR, strlen(CMD_DVD_ERROR)) ) { char *errmsg = dvd_error( dvd ); n = strlen(errmsg)+1; if( sock_string_write(socket,"0 %d", n) < 0 ) return -1; if( sock_data_write(socket,errmsg,n) < 0 ) return -1; continue; } if( !strncmp(cmd, CMD_DVD_SEEK, strlen(CMD_DVD_SEEK)) ) { sscanf(cmd,"%*s %d %d", &blocks, &flags); ret = dvd_seek(dvd, blocks, flags); if( sock_string_write(socket,"%d 0", ret) < 0 ) return -1; continue; } if( !strncmp(cmd, CMD_DVD_READ, strlen(CMD_DVD_READ)) ) { char *buf; sscanf(cmd,"%*s %d %d", &blocks, &flags); if (blocks > INT_MAX / DVD_BLOCK_SIZE) { printf ("fatal error: integer overflow\n"); exit (1); } n = blocks * DVD_BLOCK_SIZE; buf = malloc( n ); if( !buf ) { printf("fatal error: could not allocate memory\n"); exit(1); } ret = dvd_read(dvd, buf, blocks, flags); if( sock_string_write(socket,"%d %d", ret, n) < 0 ) return -1; if( sock_data_write(socket,buf,n) < 0 ) return -1; free(buf); continue; } if( !strncmp(cmd, CMD_DVD_TITLE, strlen(CMD_DVD_TITLE)) ) { sscanf(cmd,"%*s %d", &blocks); ret = dvd_title(dvd, blocks); if( sock_string_write(socket,"%d 0", ret) < 0 ) return -1; continue; } } /* no device open, or unknown command. return error */ if( sock_string_write(socket,"-1 0") < 0 ) return -1; } return 0; } static void server_loop() { struct sockaddr_in fsin; /* the from address of a client */ int alen; /* from-address length */ int fd, nfds; fd_set rfds; /* read file descriptor set */ fd_set afds; /* active file descriptor set */ /* SIGPIPE when connection closed during write call */ signal( SIGPIPE, SIG_IGN ); nfds = getdtablesize(); FD_ZERO(&afds); FD_SET(msock, &afds); while (1) { memcpy( &rfds, &afds, sizeof(rfds) ); if (select(nfds, &rfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0) < 0) continue; /* erro?? */ if (FD_ISSET(msock, &rfds)) { int ssock; alen = sizeof(fsin); ssock = accept(msock, (struct sockaddr *)&fsin, &alen); if (ssock < 0) continue; /* erro?? */ FD_SET(ssock, &afds); printf("new connection socket %d\n", ssock); } for (fd=0; fd \n", argv[0] ); return -1; } port = atoi( argv[2] ); cdda_fd = -1; dvd = NULL; cdrom_device = argv[1]; msock = socket(PF_INET, SOCK_STREAM, 0); if( msock < 0 ) { printf("error opening master socket.\n"); return 0; } servAddr.sin_family = AF_INET; servAddr.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.sin_port = htons(port); if(bind(msock, (struct sockaddr *) &servAddr, sizeof(servAddr))<0) { printf("bind port %d error\n", port); return 0; } listen(msock,QLEN); printf("listening on port %d...\n", port); server_loop(); close(msock); return 0; } xine-lib-1.2/misc/libxine.pc.in0000644000175000017500000000125114647725152014201 0ustar memeprefix=@prefix@ exec_prefix=@exec_prefix@ bindir=@bindir@ libdir=@libdir@ includedir=@includedir@ datarootdir=@datarootdir@ datadir=@datadir@ xinelibdir=@xinelibdir@ xinedatadir=@xinedatadir@ acflags=@XINE_ACFLAGS@ plugindir=@XINE_PLUGINDIR@ scriptdir=@XINE_SCRIPTPATH@ localedir=@XINE_LOCALEDIR@ objcflags=@OBJCFLAGS@ xine_list=${bindir}/xine-list-@XINE_SERIES@@EXEEXT@ Name: libxine Description: The xine engine library Version: @XINE_MAJOR@.@XINE_MINOR@.@XINE_SUB@@XINE_PATCH@ Requires.private: @XDG_BASEDIR_REQUIRES@ Libs: -L${libdir} -lxine Libs.private: @ZLIB_LIBS@ @NET_LIBS@ @PTHREAD_LIBS@ @LIBICONV@ @RT_LIBS@ Cflags: -I${includedir} Cflags.private: @PTHREAD_CFLAGS@ xine-lib-1.2/misc/SlackBuild.in0000644000175000017500000001156314647725152014172 0ustar meme#!/bin/sh # # This script generate some valid Slackware packages # # # Some variables. # CWD=`pwd` PACKAGE=@PACKAGE@.tgz SLCK=$CWD/slack PREFIX=${PREFIX:-"@prefix@"} PKG=$CWD/slktmp TMPBUILD=$CWD/tmpbuild #DOINSTDIR=/install # # Create the post-install script # do_install_sh() { cat > doinst.sh < package_descriptions << EOF @PACKAGE@: @PACKAGE@ @PACKAGE_VERSION@. @PACKAGE@: @PACKAGE@: xine-lib is the beating heart of xine (a free gpl-licensed @PACKAGE@: video player for unix-like systems) which among others provides @PACKAGE@: support for decoding (and playing back) of many today available @PACKAGE@: audio/video codecs, like mpeg-4 (DivX), mpeg-2 (DVD, SVCD), @PACKAGE@: mpeg-1 (VCD), Quicktime and RealMedia just to name a few. @PACKAGE@: This library contains (and uses) numerous processor specific @PACKAGE@: optimizations to provide a smooth playback and to minimize the @PACKAGE@: overall demand of CPU power. @PACKAGE@: @PACKAGE@: Don't hesitate to use %{name} in your own projects as long as @PACKAGE@: your usage complies to the GPL. More information about @PACKAGE@: GPL-license can be found at http://www.gnu.org/licenses/gpl.html @PACKAGE@: @PACKAGE@: EOF } # # Building binaries process, then install and move package in right place # do_build() { cd $CWD rm -rf $TMPBUILD mkdir -p $TMPBUILD cd $TMPBUILD && tar -xzf $CWD/@PACKAGE_TARNAME@.tar.gz do_install_sh; cd @PACKAGE_TARNAME@ DIE=1 echo "./configure --prefix=$PREFIX $CONFIG_OPT && make && make install-strip DESTDIR=$PKG LIBRARY_PATH=$TMPBUILD/@PACKAGE_TARNAME@/src/xine-engine/.libs" && \ ./configure --prefix=$PREFIX $CONFIG_OPT && make && make install-strip DESTDIR=$PKG LIBRARY_PATH=$TMPBUILD/@PACKAGE_TARNAME@/src/xine-engine/.libs && \ mkdir -p $PKG/install && cp $TMPBUILD/doinst.sh $PKG/install && \ cd $PKG && \ echo "n" | /sbin/makepkg $PACKAGE && \ mv $PACKAGE $SLCK && \ cd $SLCK && DIE=0 do_descr } # # Cleaning building directory # do_clean() { rm -rf $TMPBUILD rm -f $PACKAGE package_descriptions rm -rf $PKG cd $CWD } # # Build for PPro # build_pentiumpro() { echo "*****************************************************" echo echo "building slack for @PACKAGE@ @VERSION@" echo echo "current architecture:pentiumpro" echo "slackware package will be copied to ./slack directory" echo echo "*****************************************************" rm -rf $PKG export XINE_BUILD=i686-pc-linux-gnu do_build if test "$DIE" -eq 0; then tar -czvf @PACKAGE@-@VERSION@-i686.tar.gz $PACKAGE package_descriptions fi do_clean } # # Build for Pentium # build_pentium() { echo "*****************************************************" echo echo "building slack for @PACKAGE@ @VERSION@" echo echo "current architecture:pentium" echo "slackware package will be copied to ./slack directory" echo echo "*****************************************************" rm -rf $PKG export XINE_BUILD=i586-pc-linux-gnu do_build if test "$DIE" -eq 0; then tar -czvf @PACKAGE@-@VERSION@-i586.tar.gz $PACKAGE package_descriptions fi do_clean } # # Build for K6 # build_k6() { echo "*****************************************************" echo echo "building slack for @PACKAGE@ @VERSION@" echo echo "current architecture:k6" echo "slackware package will be copied to ./slack directory" echo echo "*****************************************************" rm -rf $PKG export XINE_BUILD=k6-pc-linux-gnu do_build if test "$DIE" -eq 0; then tar -czvf @PACKAGE@-@VERSION@-k6.tar.gz $PACKAGE package_descriptions fi do_clean } # # Build for K7 # build_k7() { echo "*****************************************************" echo echo "building slack for @PACKAGE@ @VERSION@" echo echo "current architecture:k7" echo "slackware package will be copied to ./slack directory" echo echo "*****************************************************" rm -rf $PKG export XINE_BUILD=athlon-pc-linux-gnu do_build if test "$DIE" -eq 0; then tar -czvf @PACKAGE@-@VERSION@-k7.tar.gz $PACKAGE package_descriptions fi do_clean } # # Main function # main() { rm -rf $SLCK mkdir -p $SLCK rm -f config.cache && ./autogen.sh && make dist build_pentiumpro build_pentium build_k6 build_k7 mv -f $CWD/@PACKAGE_TARNAME@.tar.gz $SLCK } # # Handle arguments if available. # build_arch() { rm -rf $SLCK mkdir -p $SLCK rm -f config.cache && ./autogen.sh && make dist $barch mv -f $CWD/@PACKAGE_TARNAME@.tar.gz $SLCK } case "$1" in pentiumpro | ppro | i686 | 686) barch=build_pentiumpro build_arch ;; pentium | i586 | 586) barch=build_pentium build_arch ;; k6) barch=build_k6 build_arch ;; k7 | athlon) barch=build_k7 build_arch ;; *) main ;; esac xine-lib-1.2/misc/Makefile.plugins.in0000644000175000017500000000007714647725152015350 0ustar memeDESTDIR:=$(if $(DESTDIR),$(DESTDIR),@LIBTOOL_DESTDIR_DEFAULT@) xine-lib-1.2/misc/xine-lib.spec.in0000644000175000017500000013245014647725152014614 0ustar meme%define shortname libxine %define name libxine1 %define version @PACKAGE_VERSION@ %define release 0 %define major 1 %define libname %{shortname}%{major} # Build separat packages: # 1 create a sparate package # 0 include files in main package %if %{?BUILD_AA:0}%{!?BUILD_AA:1} %define BUILD_AA 0 %endif %if %{?BUILD_ALSA:0}%{!?BUILD_ALSA:1} %define BUILD_ALSA 0 %endif %if %{?BUILD_ARTS:0}%{!?BUILD_ARTS:1} %define BUILD_ARTS 0 %endif %if %{?BUILD_DEVEL:0}%{!?BUILD_DEVEL:1} %define BUILD_DEVEL 1 %endif %if %{?BUILD_DVB:0}%{!?BUILD_DVB:1} %define BUILD_DVB 0 %endif %if %{?BUILD_DVD:0}%{!?BUILD_DVD:1} %define BUILD_DVD 0 %endif %if %{?BUILD_DXR3:0}%{!?BUILD_DXR3:1} %define BUILD_DXR3 0 %endif %if %{?BUILD_ESD:0}%{!?BUILD_ESD:1} %define BUILD_ESD 0 %endif %if %{?BUILD_FLAC:0}%{!?BUILD_FLAC:1} %define BUILD_FLAC 0 %endif %if %{?BUILD_GNOME_VFS:0}%{!?BUILD_GNOME_VFS:1} %define BUILD_GNOME_VFS 0 %endif %if %{?BUILD_OGG:0}%{!?BUILD_OGG:1} %define BUILD_OGG 0 %endif %if %{?BUILD_OPENGL:0}%{!?BUILD_OPENGL:1} %define BUILD_OPENGL 0 %endif %if %{?BUILD_SDL:0}%{!?BUILD_SDL:1} %define BUILD_SDL 0 %endif %if %{?BUILD_DIRECTFB:0}%{!?BUILD_DIRECTFB:1} %define BUILD_DIRECTFB 0 %endif %if %{?BUILD_SYNCFB:0}%{!?BUILD_SYNCFB:1} %define BUILD_SYNCFB 0 %endif %if %{?BUILD_W32DLL:0}%{!?BUILD_W32DLL:1} %define BUILD_W32DLL 0 %endif %if %{?BUILD_XVMC:0}%{!?BUILD_XVMC:1} %define BUILD_XVMC 0 %endif %if %{?BUILD_STK:0}%{!?BUILD_STK:1} %define BUILD_STK 0 %endif %if %{?BUILD_JACK:0}%{!?BUILD_JACK:1} %define BUILD_JACK 0 %endif %if %{?BUILD_PULSE:0}%{!?BUILD_PULSE:1} %define BUILD_PULSE 0 %endif Name: %{name} Summary: A portable video/audio library for unix-like systems. Summary(cs): Přenositelná video a audio knihovna pro unixovské systémy Summary(de): Eine portabele Audio-/Video-Bibliothek für unixartige Systeme. Summary(fi): Joustava video- ja ääniohjelmointikirjasto Unix-tyylisille käyttöjärjestelmille. Version: %{version} Release: %{release} License: GPL Group: Development/Libraries URL: http://www.xine-project.org Source: http://prdownloads.sourceforge.net/xine/@PACKAGE@-@VERSION@.tar.bz2 Packager: Manfred Tremmel Obsoletes: xine Obsoletes: xine-lib Obsoletes: xine-lib-oss Obsoletes: xine-lib-xv Obsoletes: libxine0 Obsoletes: %{shortname} Obsoletes: xine-vcdx Provides: xine Provides: xine-lib Provides: %{shortname} = %{version}-%{release} Provides: xine-vcdx BuildRoot: %{_tmppath}/%{name}-buildroot %description libxine is the beating heart of xine (a free gpl-licensed video player for unix-like systems) which among others provides support for decoding (and playing back) of many today available audio/video codecs, like mpeg-4 (DivX), mpeg-2 (DVD, SVCD), mpeg-1 (VCD), Quicktime and RealMedia just to name a few. This library contains (and uses) numerous processor specific optimizations to provide a smooth playback and to minimize the overall demand of CPU power. Don't hesitate to use libxine in your own projects as long as your usage complies to the GPL. More information about GPL-license can be found at http://www.gnu.org/licenses/gpl.html %description -l cs libxine je tepající srdce xine (svobodného videopřehrávače pod licencí GPL pro unixovské systémy). Mimo jiné poskytuje podporu pro dekódování (a přehrávání) mnoha dnes dostupnými audio a video kodeky jako jsou např. mpeg-4 (DivX), mpeg-2 (DVD, SVCD), mpeg-1 (VCD), Quicktime a RealMedia. Tato knihovna používá četné procesorově závislé optimalizace k dosažení plynulého přehrávání a zmenšení celkového nároku na výkon procesoru. Dokud to bude ve shodě s GPL, neváhejte použít libxine ve vašich vlastních projektech. Více informací o GPL licenci můžete nalézt na http://www.gnu.org/licenses/gpl.html. %description -l de libxine ist das Herzstück von xine (einem freien, GPL lizensiertem Audio- und Video-Abspielprogramm für unixartige Systeme). libxine stellt die Funktionen zur Dekodierung und Wiedergabe vieler aktueller Audio- und Videocodecs zur Verfügung, wie z.B. MPEG-4 (DivX), MPEG-2 (DVD, SVCD) und MPEG-1 (VCD), Quicktime und RealMedia um nur einige zu nennen. Die Bibliothek enthält und benutzt eine Vielzahl von prozessorspezifischen Optimierungen, um eine flüssige Wiedergabe mit minimaler Prozessorbelastung gewährleisten zu könnnen. Zögern Sie nicht libxine in Ihren eigenen Projekten zu nutzen. Beachten Sie hierzu jedoch die in der GPL Lizenz vereinbarten Bestimmungen. Weitere Informationen zur GPL-Lizenz finden Sie unter http://www.gnu.org/licenses/gpl.html %description -l fi libxine on xinen sydän (vapaa GPL-linsensoitu videosoitinohjelma Unix-tyylisille käyttöjärjestelmille), joka muun muassa tarjoaa mahdollisuudet pakatun videon ja äänen purkamiseen (sekä näyttämiseen) suurimmalla osalla nykyaikaista äänen- ja kuvanpakkausformaateista. Tällaisia ovat mpeg-4 (DivX;-)), mpeg-2 (DVD, SVCD), mpeg-1 (VCD) muutamia mainitaksemme. xinen purkukirjasto käyttää monia matalan tason prosessoripohjaisia optimisaatiomenetelmiä tarjotakseen sulavan kuvantoistokokemuksen. Tämä on tarpeen myös minimoimaan tarvittavaa prosessoritehoa. Olet tervetullut käyttämään libxine:a omissa projekteissasi kunhan ne ovat GPL- lisenssin kanssa yhteensopivia. lisätietoja GPL-lisenssistä löytyy osoitteesta: http://www.gnu.org/licenses/gpl.html %if %BUILD_DEVEL %package -n %{shortname}-devel Summary: Header files and documentation to develope programs with libxine. Summary(cs): Hlavičkové soubory a dokumentace pro vývoj programů používající libxine Summary(de): Headerdateien und Dokumentationen, um Programme mit libxine entwickeln zu können. Summary(fi): Header-tiedostot ja dokumentaatio, joita tarvitset kehittäessäsi ohjelmia libxine:n kanssa. Group: Development/Libraries Obsoletes: xine-lib-devel Obsoletes: xine-devel Obsoletes: libxine0-devel Obsoletes: %{name}-devel Provides: %{name}-devel = %{version}-%{release} Provides: xine-devel Requires: %{libname} = %{version}-%{release} %description -n %{shortname}-devel This package contains header files and documentation required to develope programs with libxine. libxine is the beating heart of xine (a free gpl-licensed video player for unix-like systems) which among others provides support for decoding (and playing back) of many today available audio/video codecs, like mpeg-4 (DivX), mpeg-2 (DVD, SVCD), mpeg-1 (VCD), Quicktime and RealMedia just to name a few. This library contains (and uses) numerous processor specific optimizations to provide a smooth playback and to minimize the overall demand of CPU power. Don't hesitate to use libxine in your own projects as long as your usage complies to the GPL. More information about GPL-license can be found at http://www.gnu.org/licenses/gpl.html %description -n %{shortname}-devel -l cs Tento balíček obsahuje hlavičkové soubory a dokumentaci potřebnou pro vývoj programů, které používají libxine. libxine je tepající srdce xine (svobodného videopřehrávače pod licencí GPL pro unixovské systémy). Mimo jiné poskytuje podporu pro dekódování (a přehrávání) mnoha dnes dostupnými audio a video kodeky jako jsou např. mpeg-4 (DivX), mpeg-2 (DVD, SVCD), mpeg-1 (VCD), Quicktime a RealMedia. Tato knihovna používá četné procesorově závislé optimalizace k dosažení plynulého přehrávání a zmenšení celkového nároku na výkon procesoru. Dokud to bude ve shodě s GPL, neváhejte použít libxine ve vašich vlastních projektech. Více informací o GPL licenci můžete nalézt na http://www.gnu.org/licenses/gpl.html. %description -n %{shortname}-devel -l de Dieses Paket enthält die Headerdateien und Dokumentationen, um Programme mit libxine entwickeln zu können. libxine ist das Herzstück von xine (einem freien, GPL lizensiertem Audio- und Video-Abspielprogramm für unixartige Systeme). libxine stellt die Funktionen zur Dekodierung und Wiedergabe vieler aktueller Audio- und Videocodecs zur Verfügung, wie z.B. MPEG-4 (DivX), MPEG-2 (DVD, SVCD) und MPEG-1 (VCD), Quicktime und RealMedia um nur einige zu nennen. Die Bibliothek enthält und benutzt eine Vielzahl von prozessorspezifischen Optimierungen, um eine flüssige Wiedergabe mit minimaler Prozessorbelastung gewährleisten zu könnnen. Zögern Sie nicht libxine in Ihren eigenen Projekten zu nutzen. Beachten Sie hierzu jedoch die in der GPL Lizenz vereinbarten Bestimmungen. Weitere Informationen zur GPL-Lizenz finden Sie unter http://www.gnu.org/licenses/gpl.html %description -n %{shortname}-devel -l fi libxine on xinen sydän (vapaa GPL-linsensoitu videosoitinohjelma Unix-tyylisille käyttöjärjestelmille), joka muun muassa tarjoaa mahdollisuudet pakatun videon ja äänen purkamiseen (sekä näyttämiseen) suurimmalla osalla nykyaikaista äänen- ja kuvanpakkausformaateista. Tällaisia ovat mpeg-4 (DivX;-)), mpeg-2 (DVD, SVCD), mpeg-1 (VCD) muutamia mainitaksemme. xinen purkukirjasto käyttää monia matalan tason prosessoripohjaisia optimisaatiomenetelmiä tarjotakseen sulavan kuvantoistokokemuksen. Tämä on tarpeen myös minimoimaan tarvittavaa prosessoritehoa. Olet tervetullut käyttämään libxine:a omissa projekteissasi kunhan ne ovat GPL- lisenssin kanssa yhteensopivia. lisätietoja GPL-lisenssistä löytyy osoitteesta: http://www.gnu.org/licenses/gpl.html %endif %if %BUILD_ALSA %package alsa Summary: libxine sound output plugin for alsa >= 0.9 Summary(cs): Zvukový výstupní modul libxine pro ALSA >= 0.9 Summary(de): libxine Soundausgabeplguin für Alsa >= 0.9 Summary(fi): libxine-Ddnilisdke uudelle Linux:n ddniarkkitehtuurille (ALSA >= 0.9) Group: Development/Libraries Obsoletes: xine-lib-alsa09 Obsoletes: libxine0-alsa09 Obsoletes: %{libname}-alsa09 Provides: %{libname}-alsa09 Requires: %{libname} = %{version}-%{release} %description alsa libxine sound output plugin for alsa >= 0.9 %description alsa -l cs Zvukový výstupní modul libxine pro ALSA >= 0.9. %description alsa -l de libxine Soundausgabe Plugin für alsa >= 0.9 %description alsa -l fi libxine-ddnilisdke uudelle Linux:n ddniarkkitehtuurille (ALSA >= 0.9) %endif %if %BUILD_ARTS %package arts Summary: libxine sound output plugin for arts (KDE-soundserver) Summary(cs): Zvukový výstupní modul libxine pro ARTS (zvukový server KDE) Summary(de): libxine Soundausgabeplugin für arts (KDE-Soundserver) Summary(fi): libxine-Ddnilisdke Arts ddnipalvelimelle (KDE:n ddnipalvelin) Group: Development/Libraries Obsoletes: xine-lib-arts Obsoletes: libxine0-arts Requires: %{libname} = %{version}-%{release} %description arts libxine sound output plugin for arts (KDE-soundserver) %description arts -l cs Zvukový výstupní modul libxine pro ARTS (zvukový server KDE). %description arts -l de libxine Soundausgabeplugin für arts (KDE-Soundserver) %description arts -l fi libxine-Ddnilisdke Arts ddnipalvelimelle (KDE:n ddnipalvelin) %endif %if %BUILD_ESD %package esd Summary: libxine sound output plugin for enlightmend sound daemon Summary(cs): Zvukový výstupní modul libxine pro Enlightmend Sound Daemon Summary(de): libxine Soundausgabeplugin für den Enlightmend Sound Daemon Summary(fi): libxine-ddnilisdke Enlightmend ddnipalvelimelle Group: Development/Libraries Obsoletes: xine-lib-esd Obsoletes: libxine0-esd Requires: %{libname} = %{version}-%{release} %description esd libxine sound output plugin for enlightmend sound daemon (Gnome and Enlightment) %description esd -l cs Zvukový výstupní modul libxine pro Enlightmend Sound Daemon. %description esd -l de libxine Soundausgabeplugin für den Enlightmend Sound Daemon (Gnome und Enlightment) %description esd -l fi libxine-ddnilisdke Enlightmend ddnipalvelimelle %endif %if %BUILD_SDL %package sdl Summary: libxine video output plugin for SDL-library (Simple DirectMedia Layer) Summary(cs): Videovýstupní modul libxine pro knihovnu SDL (Simple DirectMedia Layer) Summary(de): libxine Videoausgabeplguin für SDL-Bibliothek (Simple DirectMedia Layer) Summary(fi): libxine-Videolisdke SDL grafiikkakirjastolle (Simple DirectMedia Layer) Group: Development/Libraries Obsoletes: xine-lib-sdl Obsoletes: libxine0-sdl Requires: %{libname} = %{version}-%{release} %description sdl libxine video output plugin for SDL-library (Simple DirectMedia Layer) %description sdl -l cs Videovýstupní modul libxine pro knihovnu SDL (Simple DirectMedia Layer). %description sdl -l de libxine Videoausgabeplguin für SDL-Bibliothek (Simple DirectMedia Layer) %description sdl -l fi libxine-Videolisdke SDL-grafiikkakirjastolle (Simple DirectMedia Layer) %endif %if %BUILD_AA %package aa Summary: libxine video output plugin for aa-library (ASCII Art) Summary(cs): Videovýstupní modul libxine pro knihovnu aa (ASCII Art) Summary(de): libxine Videoausgabeplugin für aa-Bibliothek (ASCII Art) Summary(fi): libxine-Videolisdke aa-grafiikkakirjastolle (ASCII Art) Group: Development/Libraries Obsoletes: xine-lib-aa Obsoletes: libxine0-aa Obsoletes: xine-extra Provides: xine-extra Requires: %{libname} = %{version}-%{release} %description aa libxine video output plugin for aa-library (ASCII Art) %description aa -l cs Videovýstupní modul libxine pro knihovnu aa (ASCII Art). %description aa -l de libxine Videoausgabeplugin für aa-Bibliothek (ASCII Art) %description aa -l fi libxine-Videolisdke aa-grafiikkakirjastolle (ASCII Art) %endif %if %BUILD_OPENGL %package opengl Summary: libxine video output plugin using OpenGL (3D graphic cards) Summary(cs): Videovýstupní modul libxine používající OpenGL (3D grafické karty) Summary(de): libxine Videoausgabeplugin per OpenGL (3D Grafikkarte) Group: Development/Libraries Obsoletes: xine-lib-opengl Obsoletes: libxine0-opengl Requires: %{libname} = %{version}-%{release} %description opengl libxine video output plugin using OpenGL (3D graphic cards) %description opengl -l cs Videovýstupní modul libxine, který používá OpenGL (3D grafické karty). %description opengl -l de libxine Videoausgabeplugin per OpenGL (3D Grafikkarte) %endif %if %BUILD_SYNCFB %package syncfb Summary: libxine video output plugin using synchroniced framebuffer (Matrox cards) Summary(cs): Videovýstupní modul libxine používající framebuffer (karty Matrox) Summary(de): libxine Videoausgabeplugin per synchronisiertem Framebuffer (Matrox Karten) Summary(fi): libxine-Videolisdke Matrox-ndyttvkorttien synkronisoitua ndyttvmuistia varten. Group: Development/Libraries Obsoletes: libxine0-syncfb Requires: %{libname} = %{version}-%{release} %description syncfb libxine video output plugin using synchroniced framebuffer (Matrox cards) %description syncfb -l cs Videovýstupní modul libxine, který používá synchronizovaný framebuffer (karty Matrox). %description syncfb -l de libxine Videoausgabeplugin per synchronisiertem Framebuffer (Matrox Karten) %description syncfb -l fi libxine-Videolisdke Matrox-ndyttvkorttien synkronisoitua ndyttvmuistia varten. %endif %if %BUILD_DVD %package dvd Summary: libxine input plugin for playing video-dvd's with dvd-navigation Summary(cs): Vstupní modul libxine na přehrávání VideoDVD s DVD navigací Summary(de): libxine Inputplugin zum abspielen von Video-DVDs mit DVD-Navigation Summary(fi): libxine-Lukulisdke, jolla kdyttdjd voi soittaa DVD-levyjd Group: Development/Libraries Obsoletes: xine-dvdnav Requires: %{libname} = %{version}-%{release} %description dvd libxine input plugin for playing video-dvd's with dvd-navigation %description dvd -l cs Vstupní modul libxine na přehrávání VideoDVD s DVD navigací. %description dvd -l de libxine Inputplugin zum abspielen von Video-DVDs mit DVD-Navigation %description dvd -l fi libxine-Lukulisdke, jolla kdyttdjd voi soittaa DVD-levyjd %endif %if %BUILD_DVB %package dvb Summary: libxine input plugin for DigitalTV devices Summary(cs): Vstupní modul libxine pro karty digitální TV Summary(de): libxine Einabeplugin für digitale TV-Karten Summary(fi): libxine-Lukulisdke, jolla kdyttdjd voi katsella DigitalTV-korttien ohjelmia Group: Development/Libraries Requires: %{libname} = %{version}-%{release} %description dvb libxine input plugin for Digital TV (Digital Video Broadcast - DVB) devices e.g. Hauppauge WinTV Nova supported by DVB drivers from Convergence %description dvb -l cs Vstupní modul libxine pro karty digitální televize (Digital Video Broadcast - DVB) jako je např. Hauppauge WinTV Nova podporovaná ovladači DVB od Convergence. %description dvb -l de libxine Eingabeplugin für digitale TV-Karten (Digital Video Broadcast - DVB) z.B. wird die Hauppauge WinTV Nova von Convergence unterstützt. %description dvb -l fi libxine-Lukulisdke, jolla kdyttdjd voi katsella DigitalTV-korttien ohjelmia Esimerkiksi Haupaugen WinTV kortit ovat tuettuja DVB ajureilla. %endif %if %BUILD_GNOME_VFS %package gnome-vfs Summary: libxine input plugin for totem (a gnome frontend) Summary(cs): Vstupní modul libxine pro totem (frontend GNOME) Summary(de): libxine Einabeplugin für totem (ein Gnome Frontend) Summary(fi): libxine-Lukulisdke Totem ohjelmaa varten, joka on libxine:n Gnome2 kdyttvliittymd Group: Development/Libraries Requires: %{libname} = %{version}-%{release} %description gnome-vfs libxine input plugin for totem (a gnome frontend) %description gnome-vfs -l cs Vstupní modul libxine pro totem (frontend GNOME). %description gnome-vfs -l de libxine Einabeplugin für totem (ein Gnome Frontend) %description gnome-vfs -l fi libxine-Lukulisdke Totem ohjelmaa varten, joka on libxine Gnome2 kdyttvliittymd %endif %if %BUILD_FLAC %package flac Summary: libxine sound input plugin for flac-files (Free Lossless Audio Codec) Summary(cs): Zvukový modul libxine pro dekódování souborů FLAC (Free Lossless Audio Codec) Summary(de): libxine Soundeinabeplugin für flac-Dateien (Free Lossless Audio Codec) Summary(fi): libxine-Ddnilisdke flac-tiedostojen toistamiseen (Free Lossless Audio Codec) Group: Development/Libraries Requires: %{libname} = %{version}-%{release} %description flac libxine sound input plugin for flac-files (Free Lossless Audio Codec) %description flac -l cs Zvukový modul libxine pro dekódování souborů FLAC (Free Lossless Audio Codec). %description flac -l de libxine Soundeinabeplugin für flac-Dateien (Free Lossless Audio Codec == Freier, verlustfreier Audio-Codec) %description flac -l fi libxine-Ddnilisdke flac-tiedostojen toistamiseen (Free Lossless Audio Codec) %endif %if %BUILD_OGG %package ogg Summary: libxine sound/video input plugin for ogg/ogm-files Summary(cs): Zvukový modul libxine pro dekódování souborů OGG a OGM Summary(de): libxine Sound-/Videoeinabeplugin für ogg/ogm-Dateien Summary(fi): libxine-Ddni/Videolisdke Ogg/Ogm tiedostojen toistamiseen Group: Development/Libraries Requires: %{libname} = %{version}-%{release} Obsoletes: xine-lib-oggvorbis Obsoletes: %{libname}-oggvorbis Obsoletes: %{libname}-oggtheora Provides: xine-lib-oggvorbis Provides: %{libname}-oggvorbis Provides: %{libname}-oggtheora %description ogg libxine sound/video input plugin for ogg/ogm-files %description ogg -l cs Zvukový modul libxine pro dekódování souborů OGG a OGM. %description ogg -l de libxine Sound-/Videoeinabeplugin für ogg/ogm-Dateien %description ogg -l fi libxine-Ddni/Videolisdke Ogg/Ogm tiedostojen toistamiseen %endif %if %BUILD_DIRECTFB %package directfb Summary: libxine video output plugin using libdirectfb Summary(cs): Videovýstupní modul libxine používající libdirectfb Summary(de): libxine Videoausgabeplugin per libdirectfb Group: Development/Libraries Requires: %{libname} = %{version}-%{release} %description directfb libxine video output plugin using libdirectfb %description directfb -l cs Videovýstupní modul libxine, který používá libdirectfb. %description directfb -l de libxine Videoausgabeplugin per libdirectfb %endif %if %BUILD_STK %package stk Summary: libxine video output plugin using libstk Summary(cs): Videovýstupní modul libxine používající libstk Summary(de): libxine Videoausgabeplugin per libstk Group: Development/Libraries Requires: %{libname} = %{version}-%{release} %description stk libxine video output plugin using libstk (Set-top Toolkit) %description stk -l cs Videovýstupní modul libxine, který používá libstk. %description stk -l de libxine Videoausgabeplugin per libstk (Set-top Toolkit) %endif %if %BUILD_DXR3 %package dxr3 Summary: libxine video output plugin using mpeg2 decoding cards with dxr3 decoder-chip Summary(cs): Videovýstupní modul libxine používající karty s čipem DXR3 Summary(de): libxine Videoausgabeplugin, nutzt MPEG2-decoder-Karten mit dxr3 Decoder-Chip Summary(fi): libxine-Videolisdke MPEG2-videopurkukorteille, joissa on DXR3 purkusiru Group: Development/Libraries Obsoletes: xine-lib-dxr3 Obsoletes: libxine0-dxr3 Requires: %{libname} = %{version}-%{release} %description dxr3 libxine video output plugin using mpeg2 decoding cards with dxr3 decoder-chip %description dxr3 -l cs Videovýstupní modul libxine používající karty, které dekódují MPEG2 pomocí čipu DXR3. %description dxr3 -l de libxine Videoausgabeplugin, nutzt MPEG2-decoder-Karten mit dxr3 Decoder-Chip %description dxr3 -l fi libxine-Videolisdke MPEG2-videopurkukorteille, joissa on DXR3 purkusiru %endif %if %BUILD_XVMC %package xvmc Summary: libxine video output plugin using XVideo-extension with motion compensation Summary(cs): Videovýstupní modul libxine používající rozšíření XVideo MC Summary(de): libxine Videoausgabeplugin per XVideo-Erweiterung mit Motion Compensation Group: Development/Libraries Obsoletes: libxine0-xvmc Autoreqprov: Off Requires: %{libname} = %{version}-%{release} %description xvmc libxine video output plugin using XVideo-extension with motion compensation %description xvmc -l cs Videovýstupní modul libxine, který používá rozšíření XVideo s kompenzací pohybu. %description xvmc -l de libxine Videoausgabeplugin per XVideo-Erweiterung mit Motion Compensation %endif %if %BUILD_W32DLL %ifarch i386 i486 i586 i686 i786 i868 i986 k6 k7 athlon %package w32dll Summary: libxine decoding plugin using win32 dlls for native not supported formats Summary(cs): Dekódovací modul libxine, který používá DLL knihovny WIN32 Summary(de): libxine Dekodierplugin, nutzt Win32 dlls für natvie nicht unterstützte Formate Summary(fi): libxine-Purkulisdke, joka mahdollistaa Win32 DLL:n kdytvn. Group: Development/Libraries Obsoletes: xine-lib-w32dll Obsoletes: libxine0-w32dll Requires: %{libname} = %{version}-%{release} %description w32dll libxine decoding plugin using win32 dlls for native not supported formats %description w32dll -l cs Dekódovací modul libxine, který používá DLL knihovny WIN32 pro formáty nepodporované přímo. %description w32dll -l de libxine Dekodierplugin, nutzt Win32 dlls für native nicht unterstützte Formate %description w32dll -l fi libxine-Purkulisdke, joka mahdollistaa Win32 DLL:n kdytvn. %endif %endif %if %BUILD_JACK %package jack Summary: libxine sound output plugin for the jack soundserver Summary(de): libxine Soundausgabeplugin für den jack-Soundserver Group: Development/Libraries Obsoletes: xine-lib-jack Obsoletes: libxine0-jack Requires: %{libname} = %{version}-%{release} %description jack libxine sound output plugin for the jack soundserver %description jack -l cs Zvukový výstupní modul libxine pro zvukový server jack. %description jack -l de libxine Soundausgabeplugin für den jack-Soundserver %endif %if %BUILD_PULSE %package pulse Summary: libxine sound output plugin for the pulseaudio soundserver Summary(de): libxine Soundausgabeplugin für den pulseaudio-Soundserver Group: Development/Libraries Obsoletes: xine-lib-pulse Obsoletes: libxine0-pulse Requires: %{libname} = %{version}-%{release} %description pulse libxine sound output plugin for the pulseaudio soundserver %description pulse -l cs Zvukový výstupní modul libxine pro zvukový server pulseaudio. %description pulse -l de libxine Soundausgabeplugin für den pulseaudio-Soundserver %endif %prep %setup -q -n @PACKAGE_TARNAME@-@PACKAGE_VERSION@ %build export CFLAGS="${RPM_OPT_FLAGS}" export XINE_DOCPATH="%{_docdir}/%{name}" export PKG_CONFIG="%{_bindir}/pkg-config" if [ ! -f configure ]; then NO_CONFIGURE=1 ./autogen.sh fi # # currently we do not use %%configure as it seems to cause trouble with # certain automake produced configure scripts - depending on automake version. # Use BUILD_ARGS envvar to pass extra parameters to configure (like --enable-dha-mod/etc...) # ./configure --build=%{_target_platform} --prefix=%{_prefix} \ --exec-prefix=%{_exec_prefix} --bindir=%{_bindir} \ --sbindir=%{_sbindir} --sysconfdir=%{_sysconfdir} \ --datadir=%{_datadir} --includedir=%{_includedir} \ --libdir=%{_libdir} --libexecdir=%{_libexecdir} \ --localstatedir=%{_localstatedir} \ --sharedstatedir=%{_sharedstatedir} --mandir=%{_mandir} \ --infodir=%{_infodir} --enable-directfb --enable-modplug \ %if %BUILD_STK --with-libstk \ %endif --without-internal-vcdlibs # Error in libfaad when compiling with mmx or sse enabled, remove it %{__mv} contrib/libfaad/Makefile contrib/libfaad/Makefile_save %{__cat} contrib/libfaad/Makefile_save | %{__sed} -e "s/-mmmx/-mno-mmx/g" -e "s/-msse/-mno-sse/g" > contrib/libfaad/Makefile %{__make} %{?jobs:-j%{jobs}} %install [ "${RPM_BUILD_ROOT}" != "/" ] && %{__rm} -rf ${RPM_BUILD_ROOT} make DESTDIR=%{?buildroot:%{buildroot}} LIBRARY_PATH=%{?buildroot:%{buildroot}}%{_libdir} install cd ${RPM_BUILD_ROOT} echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_zw %if %BUILD_DEVEL echo "%doc README TODO AUTHORS COPYING ChangeLog" >> ${RPM_BUILD_DIR}/filelist_%{name}_zw %else echo "%doc README TODO AUTHORS COPYING ChangeLog doc/hackersguide/*.html doc/hackersguide/*.png doc/hackersguide/README" >> ${RPM_BUILD_DIR}/filelist_%{name}_zw %endif find . -type f | %{__sed} 's,^\.%{_datadir}/doc,\%doc %{_datadir}/doc,' | %{__sed} 's,^\.,,' >> ${RPM_BUILD_DIR}/filelist_%{name}_zw find . -type l | %{__sed} 's,^\.%{_datadir}/doc,\%doc %{_datadir}/doc,' | %{__sed} 's,^\.,,' >> ${RPM_BUILD_DIR}/filelist_%{name}_zw find . -type d | %{__grep} xine | %{__sed} 's,^\.,\%dir ,' >> ${RPM_BUILD_DIR}/filelist_%{name}_zw %{__grep} -v "/man/" ${RPM_BUILD_DIR}/filelist_%{name}_zw | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__grep} "/man/" ${RPM_BUILD_DIR}/filelist_%{name}_zw | %{__sed} -e 's/$/\*/g' | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_zw %if %BUILD_DEVEL echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_devel echo "%doc doc/hackersguide/*.html doc/hackersguide/*.png doc/hackersguide/README" >> ${RPM_BUILD_DIR}/filelist_%{name}_devel %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "/include/|dhahelper\.o|libxine*\.(so|la)$|\.m4$" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_devel %{__grep} -v -E "/include/|dhahelper\.o|libxine*\.(so|la)$|\.m4$" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_ALSA echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_alsa %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_ao_out_alsa\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_alsa %{__grep} -v "xineplug_ao_out_alsa\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_ESD echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_esd %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_ao_out_esd\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_esd %{__grep} -v "xineplug_ao_out_esd\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_DXR3 echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_dxr3 %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "dxr3" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_dxr3 %{__grep} -v "dxr3" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_SDL echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_sdl %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_vo_out_sdl\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_sdl %{__grep} -v "xineplug_vo_out_sdl\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_AA echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_aa %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_vo_out_aa\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_aa %{__grep} -v "xineplug_vo_out_aa\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_OPENGL echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_opengl %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_vo_out_opengl\.|README.opengl" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_opengl %{__grep} -v -E "xineplug_vo_out_opengl\.|README.opengl" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_SYNCFB echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_syncfb %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_vo_out_syncfb\.|README\.syncfb" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_syncfb %{__grep} -v -E "xineplug_vo_out_syncfb\.|README\.syncfb" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_DIRECTFB echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_directfb %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_vo_out_(xd|d)irectfb\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_directfb %{__grep} -v -E "xineplug_vo_out_(xd|d)irectfb\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_STK echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_stk %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_vo_out_stk\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_stk %{__grep} -v -E "xineplug_vo_out_stk\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_XVMC echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_xvmc %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_vo_out_x[x|v]mc\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_xvmc %{__grep} -v "xineplug_vo_out_x[x|v]mc\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_W32DLL %ifarch i386 i486 i586 i686 i786 i868 i986 k6 k7 athlon echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_w32dll %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_decode_qt\.|xineplug_decode_w32dll\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_w32dll %{__grep} -v -E "xineplug_decode_qt\.|xineplug_decode_w32dll\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %endif %if %BUILD_DVB echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_dvb %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_inp_dvb\.|README\.dvb" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_dvb %{__grep} -v -E "xineplug_inp_dvb\.|README\.dvb" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_DVD echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_dvd %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_inp_dvd\.|README\.network_dvd" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_dvd %{__grep} -v -E "xineplug_inp_dvd\.|README\.network_dvd" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_GNOME_VFS echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_gnome_vfs %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_inp_gnome_vfs\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_gnome_vfs %{__grep} -v "xineplug_inp_gnome_vfs\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_FLAC echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_flac %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_flac\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_flac %{__grep} -v "xineplug_flac\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_OGG echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_ogg %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} -E "xineplug_decode_vorbis\.|xineplug_dmx_ogg\.|xineplug_decode_theora\.|xineplug_decode_speex\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_ogg %{__grep} -v -E "xineplug_decode_vorbis\.|xineplug_dmx_ogg\.|xineplug_decode_theora\.|xineplug_decode_speex\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_JACK echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_jack %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_ao_out_jack\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_jack %{__grep} -v "xineplug_ao_out_jack\." ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %if %BUILD_PULSE echo "%defattr(-,root,root)" > ${RPM_BUILD_DIR}/filelist_%{name}_pulse %{__mv} ${RPM_BUILD_DIR}/filelist_%{name} ${RPM_BUILD_DIR}/filelist_%{name}_old %{__grep} "xineplug_ao_out_pulse" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - >> ${RPM_BUILD_DIR}/filelist_%{name}_pulse %{__grep} -v "xineplug_ao_out_pulse" ${RPM_BUILD_DIR}/filelist_%{name}_old | %{__cat} - > ${RPM_BUILD_DIR}/filelist_%{name} %{__rm} ${RPM_BUILD_DIR}/filelist_%{name}_old %endif %clean [ "${RPM_BUILD_ROOT}" != "/" ] && %{__rm} -rf ${RPM_BUILD_ROOT} %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files -f ../filelist_%{name} %if %BUILD_DEVEL %files -n %{shortname}-devel -f ../filelist_%{name}_devel %endif %if %BUILD_ALSA %files alsa -f ../filelist_%{name}_alsa %endif %if %BUILD_ARTS %files arts -f ../filelist_%{name}_arts %endif %if %BUILD_ESD %files esd -f ../filelist_%{name}_esd %endif %if %BUILD_DXR3 %files dxr3 -f ../filelist_%{name}_dxr3 %endif %if %BUILD_SDL %files sdl -f ../filelist_%{name}_sdl %endif %if %BUILD_AA %files aa -f ../filelist_%{name}_aa %endif %if %BUILD_OPENGL %files opengl -f ../filelist_%{name}_opengl %endif %if %BUILD_SYNCFB %files syncfb -f ../filelist_%{name}_syncfb %endif %if %BUILD_DIRECTFB %files directfb -f ../filelist_%{name}_directfb %endif %if %BUILD_STK %files stk -f ../filelist_%{name}_stk %endif %if %BUILD_XVMC %files xvmc -f ../filelist_%{name}_xvmc %endif %if %BUILD_W32DLL %ifarch i386 i486 i586 i686 i786 i868 i986 k6 k7 athlon %files w32dll -f ../filelist_%{name}_w32dll %endif %endif %if %BUILD_DVB %files dvb -f ../filelist_%{name}_dvb %endif %if %BUILD_DVD %files dvd -f ../filelist_%{name}_dvd %endif %if %BUILD_GNOME_VFS %files gnome-vfs -f ../filelist_%{name}_gnome_vfs %endif %if %BUILD_FLAC %files flac -f ../filelist_%{name}_flac %endif %if %BUILD_OGG %files ogg -f ../filelist_%{name}_ogg %endif %if %BUILD_JACK %files jack -f ../filelist_%{name}_jack %endif %if %BUILD_PULSE %files pulse -f ../filelist_%{name}_pulse %endif %changelog * Sun Dec 09 2007 Manfred Tremmel - stk and arts plugins are no longer build by default, enable them, when subpackages are selected - added optional subpackage for pulseaudio - switched to external vcdlibs - using macros for shell commands, when rpm provides them - some other cleanups * Sun Oct 15 2006 Manfred Tremmel - some little changes to enable caca plugin * Sat Aug 26 2006 František Dvořák - tiny translation update - fixed rpmbuild * Mon Aug 14 2006 Manfred Tremmel - added jack subpackage for the jack soundserver plugin - renamed alsa09 subpackage to alsa * Wed Feb 15 2006 Manfred Tremmel - added dirs to filelist * Tue Feb 14 2006 Manfred Tremmel - i386 section of libavcodec doesn't work with -O2 or -O3 * Thu Jan 06 2005 Manfred Tremmel - enabled defining build or not to build subpackages at runtime using '--define "BUILD_XYZ 1"', you can find possible BUILD_ defines at the top of the spec-file * Tue Dec 07 2004 Manfred Tremmel - included xxmc video out plugin into xvmc sub-rpm * Sat Sep 11 2004 Manfred Tremmel - added missing Requires-Statements in the subpackages * Fri Sep 03 2004 František Dvořák - Czech translation update * Thu Sep 02 2004 Manfred Tremmel - konverted to UTF8 - some fixes for non IA32 systems (especialy Athlon64/Opteron) * Sat May 01 2004 Manfred Tremmel - activated opengl plugin * Tue Apr 06 2004 Manfred Tremmel - removed xvid modules from -devel package and put it back to main package. * Fri Feb 13 2004 Manfred Tremmel - added new sub-rpm for stk videoout plugin * Fri Nov 21 2003 Manfred Tremmel - use internal vcdlibs to keep dependencies low * Sun Oct 19 2003 Manfred Tremmel - added separate directfb-package to solve dependendies * Tue Oct 07 2003 Manfred Tremmel - activated separte xvmc package, when this is wanted. * Sun Jul 20 2003 Manfred Tremmel - made ogg-package out of oggvorbis, oggtheora and the new oggspeex xine-plugins * Sat May 24 2003 Manfred Tremmel - complete rework of the specfile * Wed May 14 2003 Manfred Tremmel - Update for > 1-beta13 * Sat Mar 08 2003 Manfred Tremmel - added missing doc-files * Wed Jan 15 2003 Manfred Tremmel - removed man3 manpages in devel-filelist * Tue Dec 24 2002 Manfred Tremmel - Update for libxine 1.0beta1 added pkgconfig-directory * Wed Dec 11 2002 Manfred Tremmel - Update for libxine 1.0beta0, fonts-directory has been changed * Sat Dec 07 2002 Manfred Tremmel - added translation for finnish by Tuukka Pasanen - some updates to german and english descriptions - added post-directory to file-list * Sat Nov 09 2002 Manfred Tremmel - Final changes for libxine 1.0alpha1 * Mon Nov 04 2002 Manfred Tremmel - another change to make it run with next version * Sat Nov 02 2002 Manfred Tremmel - Changes for next xine version * Sun Oct 27 2002 Manfred Tremmel - Update of the german descriptions. * Thu Jun 06 2002 Daniel Caujolle-Bert - ability to pass args to configure. Fix vidix/dhahelper inclusion. * Mon May 27 2002 Matthias Dahl - added passing of build parameter to configure * Sun May 26 2002 Matthias Dahl - added german translations by Manfred Tremmel - added fixes (missing -l cs) by Manfred Tremmel * Sat May 18 2002 Matthias Dahl - added czech translations by valtri@atlas.cz * Thu May 16 2002 Matthias Dahl - replaced %configure because it was causing trouble on certain configurations * Sat May 11 2002 Matthias Dahl - reworked/revamped spec file, still needs some tuning (BuildPreReq, ...) * Thu May 2 2002 Daniel Caujolle-Bert - sync with new logo stuff. * Wed May 1 2002 Matthias Dahl - added cinepak, cyuv and msvc decode plugins - commented out sdl related parts because this is currently broken in xine-lib - added 'cs,pl_PL' translation catalogs * Sun Mar 31 2002 Matthias Dahl - added mms input plugin, spucc decoder and missing xine_logo.zyuy2. - commented out video fill decoder for now as it seems to be no longer built * Wed Feb 6 2002 Daniel Caujolle-Bert - added 'de,fr,pt_BR' translation catalogs. * Sat Dec 26 2001 Matthias Dahl - added sputext decode plugin and fonts. * Sat Dec 8 2001 Daniel Caujolle-Bert - ASF plugin is optional. * Thu Dec 6 2001 Daniel Caujolle-Bert - Add cda plugins. * Wed Nov 14 2001 Daniel Caujolle-Bert - fixed dxr3 header files inclusion, aalib deps: thanks to Andrew Meredith . * Mon Oct 29 2001 Matthias Dahl - added http input plugin * Thu Oct 18 2001 Matthias Dahl - added asf demuxer plugin * Sun Oct 14 2001 Daniel Caujolle-Bert - move vorbis in separate package. Add DivX4 decoder plugin. * Wed Oct 10 2001 Matthias Dahl - added vorbis files and missing man pages to filelist. * Thu Sep 27 2001 Daniel Caujolle-Bert - Add desktop stuff from patches by Miguel Freitas - Fixed xine.m4 installation from Andrew Meredith * Fri Sep 21 2001 Matthias Dahl - added two missing files (xine-config man page and xine.m4) * Sun Sep 16 2001 Daniel Caujolle-Bert - Merge patch from Jos�Carlos Monteiro : - Filelist and other minor updates, - Fixed some SuSE compatibility issues, - Added Portuguese summary. * Sun Sep 16 2001 Daniel Caujolle-Bert - Add missing files. * Sun Aug 19 2001 Matthias Dahl - The usual update to the filelist :) - temporarily removed mpg123 decoder plugin from filelist cause it is not built with the recent CVS tree * Thu Jul 26 2001 Daniel Caujolle-Bert - Made oss, aa, xv, esd, w32dll, documentation as separate packages. * Thu Jul 26 2001 Matthias Dahl - added seperate arts package and one missing demuxer plugin to filelist * Wed Jul 18 2001 Daniel Caujolle-Bert - list all plugins to avoid *strange* inclusion ;-). * Sun Jun 10 2001 Matthias Dahl - updated filelist - re-activated execution of /sbin/ldconfig as post install script * Thu Mar 28 2001 Daniel Caujolle-Bert - add korean summary, patch from Louis JANG * Thu Jan 11 2001 Daniel Caujolle-Bert - patch from Sung-Hyun Nam applied. * Fri Oct 17 2000 Daniel Caujolle-Bert - first spec file. xine-lib-1.2/m4/0000755000175000017500000000000014647725152011204 5ustar memexine-lib-1.2/m4/misc.m40000644000175000017500000000412414647725152012402 0ustar memednl Miscellaneous M4 macros for configure dnl Copyright (c) 2008 Diego Pettenò dnl Copyright (c) 2008 xine project dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2, or (at your option) dnl any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA dnl 02110-1301, USA. dnl dnl As a special exception, the copyright owners of the dnl macro gives unlimited permission to copy, distribute and modify the dnl configure scripts that are the output of Autoconf when processing the dnl Macro. You need not follow the terms of the GNU General Public dnl License when using or distributing such scripts, even though portions dnl of the text of the Macro appear in them. The GNU General Public dnl License (GPL) does govern all other use of the material that dnl constitutes the Autoconf Macro. dnl dnl This special exception to the GPL applies to versions of the dnl Autoconf Macro released by this project. When you make and dnl distribute a modified version of the Autoconf Macro, you may extend dnl this special exception to the GPL to apply to your modified version as dnl well. AC_DEFUN([XINE_CHECK_MINMAX], [ AC_CHECK_HEADERS([sys/param.h]) AC_CACHE_CHECK([for MIN()/MAX() macros], xine_cv_minmax, [ AC_LINK_IFELSE([ AC_LANG_PROGRAM([ #ifdef HAVE_SYS_PARAM_H # include #endif ], [ int a = MIN(1, 3); int b = MAX(2, 3); ])], [xine_cv_minmax=yes], [xine_cv_minmax=no]) ]) AS_IF([test x$xine_cv_minmax = xyes], [$1], [$2]) ]) xine-lib-1.2/m4/directx.m40000644000175000017500000000345314647725152013115 0ustar memednl dnl autoconf script for DirectX dnl dnl written by Frantisek Dvorak dnl dnl dnl AM_PATH_DIRECTX([ACTION IF FOUND [, ACTION IF NOT FOUND]])) dnl dnl It looks for DirectX, defines DIRECTX_CPPFLAGS, DIRECTX_AUDIO_LIBS and dnl DIRECTX_VIDEO_LIBS. dnl AC_DEFUN([AM_PATH_DIRECTX], [ AC_ARG_WITH([dxheaders], [AS_HELP_STRING([--with-dxheaders], [specify location of DirectX headers])], [dxheaders_prefix="$withval"], [dxheaders_prefix="no"]) if test x"$dxheaders_prefix" != x"no"; then DIRECTX_CPPFLAGS="-I$dxheaders_prefix $DIRECTX_CPPFLAGS" fi AC_MSG_CHECKING([for DirectX]) DIRECTX_AUDIO_LIBS="$DIRECTX_LIBS -ldsound" DIRECTX_VIDEO_LIBS="$DIRECTX_LIBS -lgdi32 -lddraw" AC_LANG_PUSH([C]) ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $DIRECTX_CPPFLAGS" ac_save_LIBS="$LIBS" LIBS="$LIBS $DIRECTX_VIDEO_LIBS $DIRECTX_AUDIO_LIBS" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include #include #include ]], [[DirectDrawCreate(0, NULL, 0); DirectSoundCreate(0, NULL, 0)]])], [have_directx=yes], [have_directx=no]) CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" AC_LANG_POP([C]) AC_SUBST(DIRECTX_CPPFLAGS) AC_SUBST(DIRECTX_AUDIO_LIBS) AC_SUBST(DIRECTX_VIDEO_LIBS) AM_CONDITIONAL([ENABLE_DIRECTX], [test x"$have_directx" = x"yes"]) AC_MSG_RESULT([$have_directx]) if test x"$have_directx" = x"yes"; then AC_DEFINE([HAVE_DIRECTX], 1, [Define this if you have DirectX]) ifelse([$1], , :, [$1]) else ifelse([$2], , :, [$2]) fi ]) xine-lib-1.2/m4/xine.m40000644000175000017500000001602214647725152012412 0ustar memednl Configure paths for XINE dnl dnl Copyright (C) 2001 Daniel Caujolle-Bert dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2 of the License, or dnl (at your option) any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. dnl dnl dnl As a special exception to the GNU General Public License, if you dnl distribute this file as part of a program that contains a configuration dnl script generated by Autoconf, you may include it under the same dnl distribution terms that you use for the rest of that program. dnl dnl _XINE_VERSION_PARSE(version) AC_DEFUN([_XINE_VERSION_PARSE], [`echo $1 | perl -e 'my $v = <>; chomp $v; my @v = split(" ", $v); $v = $v[[@S|@#v]]; $v =~ s/[[^0-9.]].*$//; @v = split (/\./, $v); push @v, 0 while $[#v] < 2; print $v[[0]] * 10000 + $v[[1]] * 100 + $v[[2]], "\n"'`]) dnl _XINE_VERSION_CHECK(required, actual) AC_DEFUN([_XINE_VERSION_CHECK], [ required_version=ifelse([$1], , [0.0.0], [$1]) required_version_parsed=_XINE_VERSION_PARSE([$required_version]) actual_version=ifelse([$2], , [0.0.0], [$2]) actual_version_parsed=_XINE_VERSION_PARSE([$actual_version]) if test $required_version_parsed -le $actual_version_parsed; then ifelse([$3], , [:], [$3]) else ifelse([$4], , [:], [$4]) fi ]) dnl AM_PATH_XINE([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]]) dnl Test for XINE, and define XINE_CFLAGS and XINE_LIBS dnl AC_DEFUN([AM_PATH_XINE], [ if test -z "$PKG_CONFIG"; then AC_PATH_PROG(PKG_CONFIG, pkg-config, no) fi AC_ARG_VAR([XINE_CONFIG], [Full path to xine-config (xine-lib < 1.2)]) AC_ARG_WITH([xine-prefix], [AS_HELP_STRING([--with-xine-prefix], [prefix where xine-lib is installed (optional, xine-lib < 1.2)])]) AC_ARG_WITH([xine-exec-prefix], [AS_HELP_STRING([--with-xine-exec-prefix], [exec prefix where xine-lib is installed (optional, xine-lib < 1.2)])]) xine_config_args="" if test x"$with_xine_exec_prefix" != x""; then xine_config_args="$xine_config_args --exec-prefix=$with_xine_exec_prefix" test x"$XINE_CONFIG" != x"" && XINE_CONFIG="$with_xine_exec_prefix/bin/xine-config" fi if test x"$with_xine_prefix" != x""; then xine_config_args="$xine_config_args --prefix=$with_xine_prefix" test x"$XINE_CONFIG" = x"" && XINE_CONFIG="$with_xine_prefix/bin/xine-config" fi if "$PKG_CONFIG" --atleast-version 1.1.90 libxine; then min_xine_version=ifelse([$1], , [1.2.0], [$1]) PKG_CHECK_MODULES([XINE], [libxine >= $min_xine_version], [XINE_VERSION="`"$PKG_CONFIG" --modversion libxine`" XINE_ACFLAGS="`"$PKG_CONFIG" --variable=acflags libxine`" xine_data_dir="`"$PKG_CONFIG" --variable=datadir libxine`" xine_script_dir="`"$PKG_CONFIG" --variable=scriptdir libxine`" xine_plugin_dir="`"$PKG_CONFIG" --variable=plugindir libxine`" xine_locale_dir="`"$PKG_CONFIG" --variable=localedir libxine`" $2], [$3]) else min_xine_version=ifelse([$1], , [0.5.0], [$1]) AC_PATH_TOOL([XINE_CONFIG], [xine-config], [no]) AC_MSG_CHECKING([for XINE-LIB version >= $min_xine_version]) XINE_CFLAGS="`$XINE_CONFIG $xine_config_args --cflags 2>/dev/null`" XINE_LIBS="`$XINE_CONFIG $xine_config_args --libs 2>/dev/null`" XINE_VERSION="`$XINE_CONFIG $xine_config_args --version 2>/dev/null`" XINE_ACFLAGS="`$XINE_CONFIG $xine_config_args --acflags 2>/dev/null`" xine_data_dir="`$XINE_CONFIG $xine_config_args --datadir 2>/dev/null`" xine_script_dir="`$XINE_CONFIG $xine_config_args --scriptdir 2>/dev/null`" xine_plugin_dir="`$XINE_CONFIG $xine_config_args --plugindir 2>/dev/null`" xine_locale_dir="`$XINE_CONFIG $xine_config_args --localedir 2>/dev/null`" _XINE_VERSION_CHECK([$min_xine_version], [$XINE_VERSION], [xine_version_ok=yes; AC_MSG_RESULT([yes, $XINE_VERSION])], [xine_version_ok=no; AC_MSG_RESULT([no, $XINE_VERSION])]) if test x"$xine_version_ok" = x"yes"; then ifelse([$2], , [:], [$2]) else AC_MSG_NOTICE([ *** You need a version of xine-lib newer than $XINE_VERSION. *** The latest version of xine-lib is always available from: *** http://www.xine-project.org *** *** If you have already installed a sufficiently new version, this error *** probably means that the wrong copy of the xine-config shell script is *** being found. The easiest way to fix this is to remove the old version *** of xine-lib, but you can also set the XINE_CONFIG environment variable *** to point to the correct copy of xine-config. In this case, you will have *** to modify your LD_LIBRARY_PATH enviroment variable, or edit *** /etc/ld.so.conf so that the correct libraries are found at run-time. ]) ifelse([$3], , [:], [$3]) fi fi AC_SUBST(XINE_CFLAGS) AC_SUBST(XINE_LIBS) AC_SUBST(XINE_ACFLAGS) ]) dnl XINE_ARG_WITH(VARIABLE, HELP-TEXT) dnl Like AC_ARG_WITH but strictly sets variables dnl hard_with_VARIABLE = "yes" or "no" if the option is present, else undefined dnl with_VARIABLE = "yes" or "no" if the option is enabled or disabled dnl (falls back on default_with_VARIABLE) dnl if both = yes, error is permissible if missing requirement(s) AC_DEFUN([XINE_ARG_WITH], [ if test "x$default_with_[]m4_translit([[$1]], [-], [_])" = x; then AC_MSG_ERROR([default_with_[]m4_translit([[$1]], [-], [_]) is not set]) fi AC_ARG_WITH([$1], [AS_HELP_STRING([--with-$1], [$2])], [test x"$withval" != xno && with_[]m4_translit([[$1]], [-], [_])=yes || with_[]m4_translit([[$1]], [-], [_])=no; hard_with_[]m4_translit([[$1]], [-], [_])="$with_[]m4_translit([[$1]], [-], [_])"], [with_[]m4_translit([[$1]], [-], [_])="$default_with_[]m4_translit([[$1]], [-], [_])"; hard_with_[]m4_translit([[$1]], [-], [_])=''])]) dnl XINE_ARG_ENABLE(VARIABLE, HELP-TEXT) dnl Like AC_ARG_WITH_X but wrapping AC_ARG_ENABLE AC_DEFUN([XINE_ARG_ENABLE], [ if test "x$default_enable_[]m4_translit([[$1]], [-], [_])" = x; then AC_MSG_ERROR([default_enable_[]m4_translit([[$1]], [-], [_]) is not set]) fi AC_ARG_ENABLE([$1], [AS_HELP_STRING([--enable-$1], [$2])], [test x"$enableval" != xno && enable_[]m4_translit([[$1]], [-], [_])=yes || enable_[]m4_translit([[$1]], [-], [_])=no; hard_enable_[]m4_translit([[$1]], [-], [_])="$enable_[]m4_translit([[$1]], [-], [_])"], [enable_[]m4_translit([[$1]], [-], [_])="$default_enable_[]m4_translit([[$1]], [-], [_])"; hard_enable_[]m4_translit([[$1]], [-], [_])=''])]) xine-lib-1.2/m4/gas.m40000644000175000017500000001060014647725152012215 0ustar memednl Copyright 2007, 2018 xine project dnl Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 dnl Free Software Foundation, Inc. dnl Originally by Gordon Matzigkeit , 1996 dnl dnl This file is free software; the Free Software Foundation gives dnl unlimited permission to copy and/or distribute it, with or without dnl modifications, as long as this notice is preserved. dnl AC_PROG_AS dnl ---------- dnl find the pathname to the GNU or non-GNU assembler dnl based on AC_PROG_LD from libtool AC_DEFUN([CC_PROG_AS], [ AC_REQUIRE([AC_PROG_SED])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AM_PROG_AS])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_ARG_WITH([gnu-as], [AS_HELP_STRING([--with-gnu-as], [assume the C compiler uses GNU as @<:@default=no@:>@])], [test "$withval" = no || with_gnu_as=yes], [with_gnu_as=unknown]) if test x"$with_gnu_as" = x"unknown"; then dnl If CCAS is not the same as CC, check to see if it's GCC. if test x"$CCAS" = x"$CC"; then ccas_is_gnu="$GCC" else AC_CACHE_CHECK([whether $CCAS is a GNU compiler], [ac_cv_CCAS_compiler_gnu], [saved_CC="$CC" CC="$CCAS" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[#ifndef __GNUC__ choke me #endif]])], [ac_cv_CCAS_compiler_gnu=yes], [ac_cv_CCAS_compiler_gnu=no]) CC="$saved_CC"]) ccas_is_gnu="$ac_cv_CCAS_compiler_gnu" fi dnl Try to figure out the assembler command. Fallback to as. ac_prog="" if test x"$AS" = x""; then AC_MSG_CHECKING([for as used by $CCAS]) if test x"$ccas_is_gnu" = x"yes"; then # Check if gcc -print-prog-name=as gives a path. case "$host_or_hostalias" in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CCAS -print-prog-name=as) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CCAS -print-prog-name=as) 2>&5` ;; esac case "$ac_prog" in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of as ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` done ;; *) ac_prog="" ;; esac fi fi if test x"$ac_prog" = x""; then # If it fails, then pretend we aren't using GCC. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/as" || test -f "$ac_dir/as$ac_exeext"; then ac_prog="$ac_dir/as" break fi done IFS="$lt_save_ifs" fi if test x"$ac_prog" = x""; then AC_MSG_RESULT([unknown]) else AS="$ac_prog" AC_MSG_RESULT([$AS]) fi fi if test -z "$AS" ; then AC_MSG_WARN([no acceptable as found in \$PATH]) else AC_CACHE_CHECK([if the assembler ($AS) is GNU as], [cc_cv_prog_gnu_as], [ # I'd rather use --version here, but apparently some GNU as's only accept -v. case `"$AS" -v 2>&1 $1/inttypes.h << EOF #ifndef _INTTYPES_H #define _INTTYPES_H /* helper inttypes.h for people who do not have it on their system */ #include EOF ], [AC_COMPILE_CHECK_SIZEOF([char],[1]) AC_COMPILE_CHECK_SIZEOF([short],[2]) AC_COMPILE_CHECK_SIZEOF([int],[4]) AC_COMPILE_CHECK_SIZEOF([long long],[8]) cat >$1/inttypes.h << EOF #ifndef _INTTYPES_H #define _INTTYPES_H /* default inttypes.h for people who do not have it on their system */ #if (!defined __int8_t_defined) && (!defined __BIT_TYPES_DEFINED__) #define __int8_t_defined typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; #ifdef ARCH_X86 typedef signed long long int64_t; #endif #endif #if (!defined __uint8_t_defined) && (!defined _LINUX_TYPES_H) #define __uint8_t_defined typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; #ifdef ARCH_X86 typedef unsigned long long uint64_t; #endif #endif EOF ]) cat >>$1/inttypes.h << EOF #ifdef WIN32 # define PRI64_PREFIX "I64" #else # define PRI64_PREFIX "l" #endif #ifndef PRId8 # define PRId8 "d" #endif #ifndef PRId16 # define PRId16 "d" #endif #ifndef PRId32 # define PRId32 "d" #endif #ifndef PRId64 # define PRId64 PRI64_PREFIX "d" #endif #ifndef PRIu8 # define PRIu8 "u" #endif #ifndef PRIu16 # define PRIu16 "u" #endif #ifndef PRIu32 # define PRIu32 "u" #endif #ifndef PRIu64 # define PRIu64 PRI64_PREFIX "u" #endif #ifndef PRIx8 # define PRIx8 "x" #endif #ifndef PRIx16 # define PRIx16 "x" #endif #ifndef PRIx32 # define PRIx32 "x" #endif #ifndef PRIx64 # define PRIx64 PRI64_PREFIX "x" #endif #ifndef PRIX8 # define PRIX8 "X" #endif #ifndef PRIX16 # define PRIX16 "X" #endif #ifndef PRIX32 # define PRIX32 "X" #endif #ifndef PRIX64 # define PRIX64 PRI64_PREFIX "X" #endif #ifndef PRIdFAST8 # define PRIdFAST8 "d" #endif #ifndef PRIdFAST16 # define PRIdFAST16 "d" #endif #ifndef PRIdFAST32 # define PRIdFAST32 "d" #endif #ifndef PRIdFAST64 # define PRIdFAST64 "d" #endif #ifndef PRIuFAST8 # define PRIuFAST8 "u" #endif #ifndef PRIuFAST16 # define PRIuFAST16 "u" #endif #ifndef PRIuFAST32 # define PRIuFAST32 "u" #endif #ifndef PRIuFAST64 # define PRIuFAST64 PRI64_PREFIX "u" #endif #ifndef PRIxFAST8 # define PRIxFAST8 "x" #endif #ifndef PRIxFAST16 # define PRIxFAST16 "x" #endif #ifndef PRIxFAST32 # define PRIxFAST32 "x" #endif #ifndef PRIxFAST64 # define PRIxFAST64 PRI64_PREFIX "x" #endif #ifndef SCNd8 # define SCNd8 "hhd" #endif #ifndef SCNd16 # define SCNd16 "hd" #endif #ifndef SCNd32 # define SCNd32 "d" #endif #ifndef SCNd64 # define SCNd64 PRI64_PREFIX "d" #endif #ifndef SCNu8 # define SCNu8 "hhu" #endif #ifndef SCNu16 # define SCNu16 "hu" #endif #ifndef SCNu32 # define SCNu32 "u" #endif #ifndef SCNu64 # define SCNu64 PRI64_PREFIX "u" #endif #ifndef PRIdMAX # define PRIdMAX PRId64 #endif #ifndef PRIuMAX # define PRIuMAX PRIu64 #endif #ifndef PRIxMAX # define PRIxMAX PRIx64 #endif #ifndef SCNdMAX # define SCNdMAX SCNd64 #endif #endif EOF ])]) dnl Check for the type of the third argument of getsockname AC_DEFUN([AC_CHECK_SOCKLEN_T], [ AC_MSG_CHECKING([for socklen_t]) AC_LANG_PUSH([C]) AC_CACHE_VAL([ac_cv_socklen_t], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #ifdef _WIN32 # include # include #else # include #endif]], [[socklen_t a=0; getsockname(0,(struct sockaddr*)0, &a)]])], [ac_cv_socklen_t=socklen_t], [ac_cv_socklen_t='']) if test x"$ac_cv_socklen_t" = x""; then AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #ifdef _WIN32 # include # include #else # include #endif]], [[int a=0; getsockname(0,(struct sockaddr*)0, &a);]])], [ac_cv_socklen_t=int], [ac_cv_socklen_t=size_t]) fi]) AC_LANG_POP([C]) AC_MSG_RESULT([$ac_cv_socklen_t]) if test x"$ac_cv_socklen_t" != x"socklen_t"; then AC_DEFINE_UNQUOTED([socklen_t], [$ac_cv_socklen_t], [Define the real type of socklen_t]) fi ]) xine-lib-1.2/m4/libFLAC.m40000644000175000017500000001125014647725152012641 0ustar meme# Configure paths for libFLAC # "Inspired" by ogg.m4 dnl AM_PATH_LIBFLAC([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) dnl Test for libFLAC, and define LIBFLAC_CFLAGS and LIBFLAC_LIBS dnl AC_DEFUN([AM_PATH_LIBFLAC], [dnl dnl Get the cflags and libraries dnl AC_ARG_WITH(libFLAC-prefix, AS_HELP_STRING([--with-libFLAC-prefix=DIR], [prefix where libFLAC is installed (optional)]), libFLAC_prefix="$withval", libFLAC_prefix="") AC_ARG_WITH(libFLAC-libraries, AS_HELP_STRING([--with-libFLAC-libraries=DIR], [directory where libFLAC library is installed (optional)]), libFLAC_libraries="$withval", libFLAC_libraries="") AC_ARG_WITH(libFLAC-includes, AS_HELP_STRING([--with-libFLAC-includes=DIR], [directory where libFLAC header files are installed (optional)]), libFLAC_includes="$withval", libFLAC_includes="") AC_ARG_ENABLE(libFLACtest, AS_HELP_STRING([--disable-libFLACtest], [do not try to compile and run a test libFLAC program]), enable_libFLACtest=$enableval, enable_libFLACtest=yes) AC_MSG_CHECKING([libdir name]) case $host_or_hostalias in *-*-linux*) # Test if the compiler is 64bit echo 'int i;' > conftest.$ac_ext xine_cv_cc_64bit_output=no if AC_TRY_EVAL(ac_compile); then case `"$MAGIC_CMD" conftest.$ac_objext` in *"ELF 64"*) xine_cv_cc_64bit_output=yes ;; esac fi rm -rf conftest* ;; esac case $host_cpu:$xine_cv_cc_64bit_output in powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes) XINE_LIBNAME="lib64" ;; *:*) XINE_LIBNAME="lib" ;; esac AC_MSG_RESULT([$XINE_LIBNAME]) if test "x$libFLAC_libraries" != "x" ; then LIBFLAC_LIBS="-L$libFLAC_libraries" elif test "x$libFLAC_prefix" != "x" ; then LIBFLAC_LIBS="-L$libFLAC_prefix/$XINE_LIBNAME" elif test "x$prefix" != "xNONE" ; then LIBFLAC_LIBS="-L$prefix/$XINE_LIBNAME" fi LIBFLAC_LIBS="$LIBFLAC_LIBS -lFLAC -lm" if test "x$libFLAC_includes" != "x" ; then LIBFLAC_CFLAGS="-I$libFLAC_includes" elif test "x$libFLAC_prefix" != "x" ; then LIBFLAC_CFLAGS="-I$libFLAC_prefix/include" elif test "$prefix" != "xNONE"; then LIBFLAC_CFLAGS="-I$prefix/include" fi AC_MSG_CHECKING(for libFLAC) no_libFLAC="" if test "x$enable_libFLACtest" = "xyes" ; then ac_save_CFLAGS="$CFLAGS" ac_save_CXXFLAGS="$CXXFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $LIBFLAC_CFLAGS" CXXFLAGS="$CXXFLAGS $LIBFLAC_CFLAGS" LIBS="$LIBS $LIBFLAC_LIBS" dnl dnl Now check if the installed libFLAC is sufficiently new. dnl rm -f conf.libFLACtest AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include #include #include int main () { system("touch conf.libFLACtest"); return 0; } ]])],[],[no_libFLAC=yes],[no_libFLAC=cc]) if test "x$no_libFLAC" = xcc; then AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ return 0; ]])],[no_libFLAC=''],[no_libFLAC=yes]) fi CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi if test "x$no_libFLAC" = "x" ; then AC_MSG_RESULT(yes) ifelse([$1], , :, [$1]) else AC_MSG_RESULT(no) if test -f conf.libFLACtest ; then : else echo "*** Could not run libFLAC test program, checking why..." CFLAGS="$CFLAGS $LIBFLAC_CFLAGS" LIBS="$LIBS $LIBFLAC_LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ return 0; ]])], [ echo "*** The test program compiled, but did not run. This usually means" echo "*** that the run-time linker is not finding libFLAC or finding the wrong" echo "*** version of libFLAC. If it is not finding libFLAC, you'll need to set your" echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" echo "*** to the installed location Also, make sure you have run ldconfig if that" echo "*** is required on your system" echo "***" echo "*** If you have an old version installed, it is best to remove it, although" echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], [ echo "*** The test program failed to compile or link. See the file config.log for the" echo "*** exact error that occured. This usually means libFLAC was incorrectly installed" echo "*** or that you have moved libFLAC since it was installed. In the latter case, you" echo "*** may want to edit the libFLAC-config script: $LIBFLAC_CONFIG" ]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" fi LIBFLAC_CFLAGS="" LIBFLAC_LIBS="" ifelse([$2], , :, [$2]) fi AC_SUBST(LIBFLAC_CFLAGS) AC_SUBST(LIBFLAC_LIBS) rm -f conf.libFLACtest ]) xine-lib-1.2/m4/programs.m40000644000175000017500000000700414647725152013301 0ustar memednl AC_PROG_GMSGFMT_PLURAL dnl ---------------------- dnl Validate the GMSGFMT program found by gettext.m4; reject old versions dnl of GNU msgfmt that do not support the "msgid_plural" extension. AC_DEFUN([AC_PROG_GMSGFMT_PLURAL], [dnl AC_REQUIRE(AM_GNU_GETTEXT) if test "$GMSGFMT" != ":"; then AC_MSG_CHECKING([for plural forms in GNU msgfmt]) changequote(,)dnl We use [ and ] in in .po test input dnl If the GNU msgfmt does not accept msgid_plural we define it dnl as : so that the Makefiles still can work. cat >conftest.po <<_ACEOF msgid "channel" msgid_plural "channels" msgstr[0] "canal" msgstr[1] "canal" _ACEOF changequote([,])dnl if $GMSGFMT -o /dev/null conftest.po >/dev/null 2>&1; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) AC_MSG_RESULT( [found GNU msgfmt program is too old, it does not support plural forms; ignore it]) GMSGFMT=":" fi rm -f conftest.po fi ])dnl AC_PROG_GMSGFMT_PLURAL # AC_PROG_LIBTOOL_SANITYCHECK # ---------------------- # Default configuration of libtool on solaris produces non-working # plugin modules, when gcc is used as compiler, and gcc does not # use gnu-ld AC_DEFUN([AC_PROG_LIBTOOL_SANITYCHECK], [dnl AC_REQUIRE(AC_PROG_CC) dnl AC_REQUIRE(AC_PROG_LD) dnl AC_REQUIRE(AC_PROG_LIBTOOL) case $host in *-*-solaris*) if test "$GCC" = yes && test "$with_gnu_ld" != yes; then AC_MSG_CHECKING([if libtool can build working modules]) cat > conftest1.c <<_ACEOF #undef NDEBUG #include int shlib_func(long long a, long long b) { assert(b); switch (a&3) { case 0: return a/b; case 1: return a%b; case 2: return (unsigned long long)a/b; case 3: return (unsigned long long)a%b; } } _ACEOF cat > conftest2.c <<_ACEOF #include int main(){ void *dl = dlopen(".libs/libconftest.so", RTLD_NOW); if (!dl) printf("%s\n", dlerror()); exit(dl ? 0 : 1); } _ACEOF if ./libtool $CC -c conftest1.c >/dev/null 2>&1 && \ ./libtool $CC -o libconftest.la conftest1.lo \ -module -avoid-version -rpath /tmp >/dev/null 2>&1 && \ ./libtool $CC -o conftest2 conftest2.c -ldl >/dev/null 2>&1 then if ./conftest2 >/dev/null 2>&1; then AC_MSG_RESULT(yes) else dnl typical problem: dlopen'ed module not self contained, because dnl it wasn't linked with -lgcc AC_MSG_RESULT(no) if grep '^archive_cmds=.*$LD -G' libtool >/dev/null; then AC_MSG_CHECKING([if libtool can be fixed]) dnl first try to update gcc2's spec file to add the dnl gcc3 -mimpure-text flag libtool_specs="" if $CC -dumpspecs | grep -- '-G -dy -z text' >/dev/null; then $CC -dumpspecs | \ sed 's/-G -dy -z text/-G -dy %{!mimpure-text:-z text}/g' \ > gcc-libtool-specs libtool_specs=" -specs=`pwd`/gcc-libtool-specs" fi sed -e "s,\$LD -G,\$CC${libtool_specs} -shared -mimpure-text,g" \ -e 's/ -M / -Wl,-M,/' libtool >libtool-fixed chmod +x libtool-fixed if ./libtool-fixed $CC -o libconftest.la conftest1.lo \ -module -avoid-version -rpath /tmp >/dev/null 2>&1 && \ ./conftest2 >/dev/null 2>&1; then dnl the fixed libtool works AC_MSG_RESULT(yes) mv -f libtool-fixed libtool else AC_MSG_RESULT(no) fi fi fi else AC_MSG_RESULT(no) fi rm -f conftest1.c conftest1.lo conftest1.o conftest2.c \ libconftest.la conftest libtool-fixed rm -rf .libs fi ;; esac ])# AC_PROG_LIBTOOL_SANITYCHECK xine-lib-1.2/m4/audio_out.m40000644000175000017500000002337714647725152013452 0ustar memednl ----------------- dnl Audio out plugins dnl ----------------- AC_DEFUN([XINE_AUDIO_OUT_PLUGINS], [ dnl Setup defaults for the target operating system. For example, alsa is dnl only ever available on Linux, so don't bother checking for it unless dnl explicitly requested to do so on other operating systems. dnl Notes: dnl - Alsa is Linux only dnl - CoreAudio is Mac OS X only dnl - EsounD is reported to be available on most platforms dnl - FusionSound is Linux only, but don't enable it by default dnl - Jack is Linux and Mac OS X primarily dnl - OSS is most unix variants dnl - PulseAudio has been tested on Linux, Solaris, FreeBSD, Windows dnl - SunAudio is NetBSD, Solaris (anything else?) dnl - sndio is *BSD, Linux default_enable_coreaudio=no default_enable_irixal=no default_enable_oss=yes default_enable_sunaudio=no default_enable_sndio=no default_with_alsa=no default_with_esound=yes default_with_fusionsound=no default_with_jack=no default_with_pulseaudio=no default_with_opensles=no case "$host_os" in cygwin* | mingw*) default_enable_oss=no default_with_pulseaudio=yes ;; darwin*) default_enable_coreaudio=yes default_with_jack=yes default_enable_oss=no ;; freebsd*|kfreebsd*) default_with_pulseaudio=yes default_with_jack=yes default_enable_sndio=yes ;; gnu*) default_with_pulseaudio=yes default_with_jack=yes ;; irix*) default_enable_irixal=yes default_enable_oss=no ;; linux-android*) default_with_alsa=yes default_enable_oss=no default_enable_esound=no default_with_opensles=yes ;; linux*) default_with_alsa=yes default_with_jack=yes default_with_pulseaudio=yes default_enable_sndio=yes ;; netbsd*) default_enable_sunaudio=yes default_enable_sndio=yes ;; openbsd*) default_enable_oss=no default_enable_sndio=yes ;; solaris*) default_with_pulseaudio=yes default_enable_sunaudio=yes ;; esac dnl Alsa support XINE_ARG_WITH([alsa], [Build with ALSA audio output support]) if test x"$with_alsa" != x"no"; then PKG_CHECK_MODULES([ALSA], [alsa >= 0.9.0], [have_alsa=yes], [have_alsa=no]) if test x"$hard_with_alsa" = x"yes" && test x"$have_alsa" != x"yes"; then AC_MSG_ERROR([ALSA support requested but not found.]) elif test x"$have_alsa" = x"yes"; then dnl This is needed by src/input/input_v4l.c AC_DEFINE([HAVE_ALSA], 1, [Define this if you have ALSA installed]) fi fi AM_CONDITIONAL([ENABLE_ALSA], [test x"$have_alsa" = x"yes"]) dnl CoreAudio for Mac OS X XINE_ARG_ENABLE([coreaudio], [Enable support for Mac OS X CoreAudio]) if test x"$enable_coreaudio" != x"no"; then AC_MSG_CHECKING([for CoreAudio frameworks]) ac_save_LIBS="$LIBS" LIBS="$LIBS -framework CoreAudio -framework AudioUnit" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[return 0]])], [have_coreaudio=yes], [have_coreaudio=no]) LIBS="$ac_save_LIBS" AC_MSG_RESULT([$have_coreaudio]) if test x"hard_$enable_coreaudio" = x"yes" && test x"$have_coreaudio" != x"yes"; then AC_MSG_ERROR([CoreAudio support requested, but CoreAudio not found]) fi fi AM_CONDITIONAL([ENABLE_COREAUDIO], [test x"$have_coreaudio" = x"yes"]) dnl EsounD support XINE_ARG_WITH([esound], [Build with EsounD audio output support]) if test x"$with_esound" != x"no"; then PKG_CHECK_MODULES([ESD], [esound], [have_esound=yes], [have_esound=no]) if test x"$hard_with_esound" = x"yes" && test x"$have_esound" != x"yes"; then AC_MSG_ERROR([EsounD support requested, but EsounD not found]) fi fi AM_CONDITIONAL([ENABLE_ESD], [test x"$have_esound" = x"yes"]) dnl FusionSound support XINE_ARG_WITH([fusionsound], [Build with FusionSound audio output support]) if test x"$with_fusionsound" != x"no"; then PKG_CHECK_MODULES([FUSIONSOUND], [fusionsound >= 0.9.23], [have_fusionsound=yes], [have_fusionsound=no]) if test x"$hard_with_fusionsound" = x"yes" && test x"$have_fusionsound" != x"yes"; then AC_MSG_ERROR([FusionSound support requested, but FusionSound not found]) fi fi AM_CONDITIONAL([ENABLE_FUSIONSOUND], [test x"$have_fusionsound" = x"yes"]) dnl IRIX style audio interface XINE_ARG_ENABLE([irixal], [Enable support for IRIX libaudio]) if test x"$enable_irixal" != x"no"; then AC_CACHE_CHECK([for IRIX libaudio support], [am_cv_have_irixal], [AC_CHECK_HEADER([dmedia/audio.h], [am_cv_have_irixal=yes], [am_cv_have_irixal=no])]) if test x"$am_cv_have_irixal" = x"yes"; then AC_DEFINE([HAVE_IRIXAL], 1, [Define this if you have a usable IRIX al interface available]) IRIXAL_LIBS="-laudio" IRIXAL_STATIC_LIB="/usr/lib/libaudio.a" AC_SUBST(IRIXAL_LIBS) AC_SUBST(IRIXAL_STATIC_LIB) fi fi AM_CONDITIONAL([ENABLE_IRIXAL], [test x"$am_cv_have_irixal" = x"yes"]) dnl JACK support XINE_ARG_WITH([jack], [Build with Jack support]) if test x"$with_jack" != x"no"; then PKG_CHECK_MODULES([JACK], [jack >= 0.100], [have_jack=yes], [have_jack=no]) if test x"$hard_with_jack" = x"yes" && test x"$have_jack" != x"yes"; then AC_MSG_ERROR([Jack support requested, but Jack not found]) fi fi AM_CONDITIONAL([ENABLE_JACK], [test x"$have_jack" = x"yes"]) dnl OSS (Open Sound System) XINE_ARG_ENABLE([oss], [Enable OSS (Open Sound System) support]) if test x"$enable_oss" != x"no"; then case "$host" in *-*-netbsd*) OSS_LIBS="-lossaudio" ;; *) OSS_LIBS="" ;; esac AC_CHECK_HEADERS([sys/soundcard.h], [break]) AC_CHECK_DECL([SNDCTL_DSP_SETFRAGMENT], [have_oss=yes], [have_oss=no], [#ifdef __NetBSD__ #include #endif #ifdef HAVE_SYS_SOUNDCARD_H # include #endif]) if test x"$hard_enable_oss" = x"yes" && test x"$have_oss" != x"yes"; then AC_MSG_ERROR([OSS support requested, but OSS not found]) fi fi AM_CONDITIONAL([ENABLE_OSS], [test x"$have_oss" = x"yes"]) AC_SUBST(OSS_LIBS) dnl PulseAudio XINE_ARG_WITH([pulseaudio], [Build with PulseAudio support]) if test x"$with_pulseaudio" != x"no"; then PKG_CHECK_MODULES([PULSEAUDIO], [libpulse], [have_pulseaudio="yes"], [have_pulseaudio="no"]) if test x"$hard_with_pulseaudio" = x"yes" && test x"$have_pulseaudio" != x"yes"; then AC_MSG_ERROR([PulseAudio support requested, but PulseAudio not found]) fi if test x"$have_pulseaudio" = xyes; then AC_MSG_CHECKING([for pulseaudio >= 0.9.7]) PKG_CHECK_EXISTS([libpulse >= 0.9.7], [have_pulseaudio_0_9_7="yes"], [have_pulseaudio_0_9_7="no"]) AC_MSG_RESULT([$have_pulseaudio_0_9_7]) if test x"$have_pulseaudio_0_9_7" = xyes; then AC_DEFINE([HAVE_PULSEAUDIO_0_9_7], 1, [define this if you have pulseaudio >= 0.9.7]) fi fi fi AM_CONDITIONAL([ENABLE_PULSEAUDIO], [test x"$have_pulseaudio" = x"yes"]) dnl SUN style audio interface XINE_ARG_ENABLE([sunaudio], [Enable Sun audio support]) if test x"$enable_sunaudio" != x"no"; then AC_MSG_CHECKING([for Sun audio support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[audio_info_t audio_info; AUDIO_INITINFO(&audio_info)]])], [have_sunaudio=yes], [have_sunaudio=no]) AC_MSG_RESULT([$have_sunaudio]) if test x"$hard_enable_sunaudio" = x"yes" && test x"$have_sunaudio" != x"yes"; then AC_MSG_ERROR([Sun audio support requested, but Sun audio not found]) elif test x"$have_sunaudio" = x"yes"; then dnl NetBSD doesn't have this, but check for it rather than dnl assuming that it doesn't happen elsewhere. AC_CHECK_MEMBERS([audio_info_t.output_muted]) fi fi AM_CONDITIONAL([ENABLE_SUNAUDIO], [test x"$have_sunaudio" = x"yes"]) dnl sndio support XINE_ARG_ENABLE([sndio], [Enable sndio support]) if test x"$enable_sndio" != "xno"; then PKG_CHECK_MODULES([SNDIO], [sndio], [have_sndio=yes], [have_sndio=no]) if test x"$hard_enable_sndio" = x"yes" && test x"$have_sndio" != x"yes"; then AC_MSG_ERROR([sndio support requested, but sndio not found]) fi fi AM_CONDITIONAL([ENABLE_SNDIO], [test "x$have_sndio" = "xyes"]) dnl OpenSL ES XINE_ARG_WITH([opensles], [Build with OpenSL ES audio output support]) if test x"$with_opensles" != x"no"; then AC_CHECK_HEADERS([SLES/OpenSLES.h], [have_opensles=yes], [have_opensles=no]) AC_CHECK_HEADERS([SLES/OpenSLES_Android.h]) if test "x$hard_with_opensles" = "xyes" && test "x$have_opensles" = "xno"; then AC_MSG_ERROR([OpenSL ES support requested, but headers not found]) fi fi AM_CONDITIONAL([ENABLE_OPENSLES], [test x"$have_opensles" = x"yes"]) AC_SUBST([OPENSLES_CFLAGS]) ])dnl XINE_AUDIO_OUT_PLUGINS xine-lib-1.2/m4/input.m40000644000175000017500000002760114647725152012613 0ustar memednl ------------- dnl Input Plugins dnl ------------- AC_DEFUN([XINE_INPUT_PLUGINS], [ dnl Setup defaults for the target operating system. For example, v4l is dnl only ever available on Linux, so don't bother checking for it unless dnl explicitly requested to do so on other operating systems. dnl Notes: dnl - dvb is Linux only dnl - v4l is Linux only default_enable_dvb=no default_enable_dvd=yes default_enable_gnomevfs=yes default_enable_mms=yes default_enable_samba=yes default_enable_v4l=no default_enable_v4l2=no default_enable_libv4l=no default_enable_vcd=yes default_enable_vcdo=no default_enable_vdr=yes default_enable_bluray=yes default_enable_avformat=yes default_enable_sftp=yes default_enable_nfs=yes default_enable_tls=yes default_enable_crypto=yes default_with_external_dvdnav=yes default_with_openssl=yes default_with_gnutls=yes case "$host_os" in cygwin* | mingw*) default_enable_gnomevfs=no default_enable_samba=no default_enable_vdr=no ;; darwin*) default_enable_gnomevfs=no default_enable_samba=no ;; freebsd*|kfreebsd*) default_enable_vcdo=yes ;; netbsd* | openbsd*) default_enable_v4l2=yes default_enable_libv4l=yes ;; linux-android*) default_enable_gnomevfs=no ;; linux*) default_enable_dvb=yes default_enable_v4l=yes default_enable_v4l2=yes default_enable_libv4l=yes default_enable_vcdo=yes ;; solaris*) default_enable_vcdo=yes default_enable_v4l2=yes ;; esac dnl default_enable_libv4l="$default_enable_v4l2" dnl dvb XINE_ARG_ENABLE([dvb], [Enable support for the DVB plugin (Linux only)]) if test x"$enable_dvb" != x"no"; then case "$host_os" in linux*) have_dvb=yes ;; *) have_dvb=no ;; esac if test x"$hard_enable_dvb" = x"yes" && test x"$have_dvb" != x"yes"; then AC_MSG_ERROR([DVB support requested, but DVB not found]) fi fi AM_CONDITIONAL([ENABLE_DVB], [test x"$have_dvb" = x"yes"]) dnl gnome-vfs XINE_ARG_ENABLE([gnomevfs], [Enable support for the Gnome-VFS plugin]) if test x"$enable_gnomevfs" != x"no"; then PKG_CHECK_MODULES([GNOME_VFS], [gnome-vfs-2.0], [have_gnomevfs=yes], [have_gnome_vfs=no]) if test x"$hard_enable_gnomevfs" = x"yes" && test x"$have_gnomevfs" != x"yes"; then AC_MSG_ERROR([Gnome-VFS support requested, but Gnome-VFS not found]) fi fi AM_CONDITIONAL([ENABLE_GNOME_VFS], [test x"$have_gnomevfs" = x"yes"]) dnl libsmbclient XINE_ARG_ENABLE([samba], [Enable support for the Samba plugin]) if test x"$enable_samba" != x"no"; then PKG_CHECK_MODULES([LIBSMBCLIENT], [smbclient], [have_samba=yes], AC_MSG_RESULT(*** All libsmbclient dependent parts will be disabled ***)) AC_SUBST(LIBSMBCLIENT_CFLAGS) AC_SUBST(LIBSMBCLIENT_LIBS) if test x"$hard_enable_samba" = x"yes" && test x"$have_samba" != x"yes"; then AC_MSG_ERROR([Samba support requested, but Samba not found]) fi fi AM_CONDITIONAL([ENABLE_LIBSMBCLIENT], [test x"$have_samba" = x"yes"]) dnl video-for-linux (v4l) XINE_ARG_ENABLE([v4l], [Enable Video4Linux support]) if test x"$enable_v4l" != x"no"; then have_v4l=yes AC_CHECK_HEADERS([linux/videodev.h], , [have_v4l=no]) AC_CHECK_HEADERS([asm/types.h]) if test x"$hard_enable_v4l" = x"yes" && test x"$have_v4l" != x"yes"; then AC_MSG_ERROR([Video4Linux support requested, but prerequisite headers not found.]) fi fi AM_CONDITIONAL([ENABLE_V4L], [test x"$have_v4l" = x"yes"]) XINE_ARG_ENABLE([v4l2], [Enable Video4Linux 2 support]) if test x"$enable_v4l2" != x"no"; then have_v4l2=yes AC_CHECK_HEADERS([linux/videodev2.h sys/videoio.h sys/videodev2.h], [have_v4l2=yes], []) AC_CHECK_HEADERS([asm/types.h]) if test x"$hard_enable_v4l2" = x"yes" && test x"$have_v4l2" != x"yes"; then AC_MSG_ERROR([Video4Linux 2 support requested, but prerequisite headers not found.]) fi XINE_ARG_ENABLE([libv4l], [Enable libv4l support]) if test "x$enable_libv4l" != "xno"; then PKG_CHECK_MODULES([V4L2], [libv4l2], [have_libv4l=yes AC_DEFINE([HAVE_LIBV4L2_H], [1], [Define this if you have libv4l installed])], [have_libv4l=no]) if test "x$hard_enable_libv4l" = "xyes" && test "x$have_libv4l" = "xno"; then AC_MSG_ERROR([libv4l requested, but libv4l not found]) fi fi fi AM_CONDITIONAL([ENABLE_V4L2], [test x"$have_v4l2" = x"yes"]) dnl dvdnav XINE_ARG_ENABLE([dvd], [Disable DVD support]) AM_CONDITIONAL([ENABLE_DVD], [test x"$enable_dvd" != x"no"]) dnl mms XINE_ARG_ENABLE([mms], [Disable MMS support]) AM_CONDITIONAL([ENABLE_MMS], [test x"$enable_mms" != x"no"]) dnl XXX: This could be cleaned up so that code does not have to ifdef so much XINE_ARG_WITH([external-dvdnav], [Use external dvdnav library]) if test x"$with_external_dvdnav" != x"no"; then PKG_CHECK_MODULES([DVDREAD], [dvdread], [], [with_external_dvdnav=no]) if test x"$with_external_dvdnav" != x"no" ; then PKG_CHECK_MODULES([DVDNAV], [dvdnav], [], [with_external_dvdnav=no]) if test x"$with_external_dvdnav" != x"no" ; then AC_DEFINE([HAVE_DVDNAV], 1, [Define this if you have a suitable version of libdvdnav]) else AC_MSG_RESULT([*** no usable version of libdvdnav found, using internal copy ***]) fi else AC_MSG_RESULT([*** no usable version of libdvdread found, using internal libdvdnav ***]) fi else AC_MSG_RESULT([Using included DVDNAV support]) fi AM_CONDITIONAL([WITH_EXTERNAL_DVDNAV], [test x"$with_external_dvdnav" != x"no"]) dnl Video CD dnl XXX: This could be cleaned up so that code does not have it ifdef so much XINE_ARG_ENABLE([vcd], [Enable VCD (VideoCD) support]) if test x"$enable_vcd" != x"no"; then no_vcd=no PKG_CHECK_MODULES([LIBCDIO], [libcdio >= 0.71], [PKG_CHECK_MODULES([LIBVCDINFO], [libvcdinfo >= 0.7.23], [], [no_vcd=yes])], [if test x"$hard_enable_vcd" = 'xyes'; then AC_MSG_ERROR([$LIBCDIO_PKG_ERRORS]) fi no_vcd=yes] ) if test "$no_vcd" = 'no'; then AC_DEFINE([HAVE_VCDNAV], 1, [Define this if you use external libcdio/libvcdinfo]) else dnl Internal libcdio/libvcd have gone officially in 2007. dnl Just in case someone still or again has them, test for them here. AC_MSG_CHECKING([for internal libcdio/libvcd]) enable_vcd=no test -f "contrib/libvcd/files.h" -a -f "contrib/cdio/iso9660.h" && enable_vcd=yes test -f "src/input/vcd/libvcd/files.h" -a -f "src/input/vcd/cdio/iso9660.h" && enable_vcd=yes AC_MSG_RESULT([$enable_vcd]) fi fi enable_vcdo=no test $default_enable_vcdo = yes && test x"$enable_vcd" != x"no" && enable_vcdo=yes AC_DEFINE([LIBCDIO_CONFIG_H], 1, [Get of rid system libcdio build configuration]) AC_DEFINE([EXTERNAL_LIBCDIO_CONFIG_H], 1, [Get of rid system libcdio build configuration]) AC_SUBST(LIBCDIO_CFLAGS) AC_SUBST(LIBCDIO_LIBS) AC_SUBST(LIBVCD_CFLAGS) AC_SUBST(LIBVCD_LIBS) AM_CONDITIONAL([ENABLE_VCD], [test x"$enable_vcd" != x"no"]) AM_CONDITIONAL([ENABLE_VCDO], [test x"$enable_vcdo" != x"no"]) dnl vdr XINE_ARG_ENABLE([vdr], [Enable support for the VDR plugin (default: enabled)]) AM_CONDITIONAL([ENABLE_VDR], [test x"$enable_vdr" != x"no"]) dnl bluray XINE_ARG_ENABLE([bluray], [Enable BluRay support]) if test "x$enable_bluray" != "xno"; then PKG_CHECK_MODULES([LIBBLURAY], [libbluray >= 0.2.1], [have_libbluray=yes], [have_libbluray=no]) if test x"$hard_enable_bluray" = x"yes" && test x"$have_libbluray" != x"yes"; then AC_MSG_ERROR([BluRay support requested, but libbluray not found]) fi AC_SUBST(LIBBLURAY_CFLAGS) AC_SUBST(LIBBLURAY_LIBS) fi AM_CONDITIONAL(ENABLE_BLURAY, test "x$have_libbluray" = "xyes") dnl libavformat XINE_ARG_ENABLE([avformat], [Enable libavformat support]) if test "x$enable_avformat" != "xno"; then PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 53.21.1], [have_avformat=yes], [have_avformat=no]) if test x"$hard_enable_avformat" = x"yes" && test x"$have_avformat" != x"yes"; then AC_MSG_ERROR([libavformat support requested, but library not found]) fi if test x"$have_avformat" = x"yes"; then AC_DEFINE([HAVE_AVFORMAT], 1, [Define this if you have libavformat installed]) AC_CHECK_HEADERS([libavformat/avformat.h]) fi fi AM_CONDITIONAL([ENABLE_AVFORMAT], [test x"$have_avformat" = x"yes"]) dnl libssh2 XINE_ARG_ENABLE([sftp], [Enable SFTP support using libssh2]) if test "x$enable_sftp" != "xno"; then PKG_CHECK_MODULES([LIBSSH2], [libssh2], [have_libssh2=yes], [have_libssh2=no]) if test x"$hard_enable_sftp" = x"yes" && test x"$have_libssh2" != x"yes"; then AC_MSG_ERROR([SFTP support requested, but libssh2 not found]) fi AC_SUBST(LIBSSH2_CFLAGS) AC_SUBST(LIBSSH2_LIBS) fi AM_CONDITIONAL(ENABLE_SSH, test "x$have_libssh2" = "xyes") dnl libnfs XINE_ARG_ENABLE([nfs], [Enable NFS support using libnfs]) if test "x$enable_nfs" != "xno"; then PKG_CHECK_MODULES([LIBNFS], [libnfs], [have_libnfs=yes], [have_libnfs=no]) if test x"$hard_enable_nfs" = x"yes" && test x"$have_libnfs" != x"yes"; then AC_MSG_ERROR([NFS support requested, but libnfs not found]) fi AC_SUBST(LIBNFS_CFLAGS) AC_SUBST(LIBNFS_LIBS) fi AM_CONDITIONAL(ENABLE_NFS, test "x$have_libnfs" = "xyes") dnl TLS support (ftps, https) XINE_ARG_ENABLE([tls], [Enable TLS support (enables secure http (https) and ftp (ftps)]) XINE_ARG_WITH([openssl], [Use openssl library for tls]) XINE_ARG_WITH([gnutls], [Use gnutls library for tls]) if test "x$enable_tls" != "xno"; then if test "x$with_gnutls" != "xno"; then PKG_CHECK_MODULES([GNUTLS], [gnutls >= 2.8.6], [have_gnutls=yes], [have_gnutls=no]) if test x"$have_gnutls" != x"yes" && test x"$hard_with_gnutls" = x"yes"; then AC_MSG_ERROR([gnutls support requested, but gnutls not found]) fi fi if test "x$with_openssl" != "xno"; then PKG_CHECK_MODULES([OPENSSL], [openssl >= 1.0.0], [have_openssl=yes], [have_openssl=no]) if test x"$have_openssl" != x"yes" && test x"$hard_with_openssl" = x"yes"; then AC_MSG_ERROR([openssl support requested, but openssl not found]) fi fi if test x"$have_gnutls" = x"yes" || test x"$have_openssl" = x"yes"; then have_tls=yes elif test x"$hard_enable_tls" = x"yes"; then AC_MSG_ERROR([TLS support requested, but openssl or gnutls not found]) fi fi AC_SUBST(OPENSSL_CFLAGS) AC_SUBST(OPENSSL_LIBS) AC_SUBST(GNUTLS_CFLAGS) AC_SUBST(GNUTLS_LIBS) AM_CONDITIONAL([ENABLE_GNUTLS], [test x"$have_gnutls" = x"yes"]) AM_CONDITIONAL([ENABLE_OPENSSL], [test x"$have_openssl" = x"yes"]) dnl crypto input support XINE_ARG_ENABLE([crypto], [Enable crypto support using libgcrypt]) if test "x$enable_crypto" != "xno"; then PKG_CHECK_MODULES([GCRYPT], [libgcrypt], [have_gcrypt=yes], [have_gcrypt=no]) if test x"$hard_enable_crypto" = x"yes" && test x"$have_gcrypt" != x"yes"; then AC_MSG_ERROR([crypto support requested, but libgcrypt not found]) fi fi AM_CONDITIONAL([ENABLE_CRYPTO], [test x"$have_gcrypt" = x"yes"]) ]) xine-lib-1.2/m4/video_out.m40000644000175000017500000007001514647725152013446 0ustar memednl ----------------- dnl Video out plugins dnl ----------------- AC_DEFUN([XINE_VIDEO_OUT_PLUGINS], [ dnl Setup defaults for the target operating system. For example, linuxfb is dnl only ever available on Linux, so don't bother checking for it unless dnl explicitly requested to do so on other operating systems. dnl Notes: dnl - dha_kmod is Linux only, but disabled by default dnl - directx is Windows only dnl - dxr3 is Linux only dnl - Mac OS X video is Mac OS X only dnl - Vidix is FreeBSD and Linux only dnl - XvMC and xxmc depend on Xv default_enable_aalib=yes default_enable_dha_kmod=no default_enable_directfb=no default_enable_directx=no default_enable_dxr3=no default_enable_glu=yes default_enable_fb=no default_enable_macosx_video=no default_enable_opengl=yes default_enable_vidix=no default_enable_xinerama=yes default_enable_xvmc=yes default_enable_vdpau=no default_enable_vaapi=no default_enable_wayland=yes default_with_caca=yes default_with_libstk=no default_with_sdl=yes default_with_xcb=yes case "$host_os" in cygwin* | mingw*) default_enable_directx=yes ;; darwin*) default_enable_macosx_video=yes ;; freebsd*|kfreebsd*) default_enable_vidix=yes default_enable_vdpau=yes default_enable_vaapi=yes ;; gnu*) default_enable_vdpau=yes ;; linux-android*) default_enable_aalib=no default_enable_xinerama=no default_enable_xvmc=no default_with_caca=no default_with_libstk=no default_with_sdl=no default_with_xcb=no enable_linux=yes no_x=yes ;; linux*) default_enable_dxr3=yes default_enable_fb=yes default_enable_vidix=yes default_enable_vdpau=yes default_enable_vaapi=yes enable_linux=yes ;; esac dnl Ascii-Art XINE_ARG_ENABLE([aalib], [enable support for AALIB]) if test x"$enable_aalib" != x"no"; then ACX_PACKAGE_CHECK([AALIB], [1.4], [aalib-config], [have_aalib=yes], [have_aalib=no]) if test x"$hard_enable_aalib" = x"yes" && test x"$have_aalib" != x"yes"; then AC_MSG_ERROR([aalib support requested, but aalib not found]) fi fi AM_CONDITIONAL([ENABLE_AA], [test x"$have_aalib" = x"yes"]) dnl Color AsCii Art XINE_ARG_WITH([caca], [enable support for CACA]) if test x"$with_caca" != x"no"; then have_cucul=yes PKG_CHECK_MODULES([CACA], [caca >= 0.99beta19], [have_caca="yes" have_cucul="no"], [PKG_CHECK_MODULES([CACA], [caca >= 0.99beta14 cucul >= 0.99beta14], [have_caca="yes"], [have_caca="no"])]) if test x"$hard_with_caca" = x"yes" && test x"$have_caca" != x"yes"; then AC_MSG_ERROR([CACA support requested, but libcaca 0.99 not found]) fi fi AM_CONDITIONAL([ENABLE_CACA], [test x"$have_caca" = x"yes"]) if test x"$have_caca$have_cucul" = x"yesyes"; then HAVE_CUCUL=1 AC_SUBST([HAVE_CUCUL]) AC_DEFINE([HAVE_CUCUL], [], [Define this if you have the legacy libcaca with separate libcucul.]) fi dnl dha (Linux only) XINE_ARG_ENABLE([dha-kmod], [build Linux DHA kernel module]) if test x"$enable_dha_kmod" != x"no"; then AC_ARG_WITH([linux-path], [AS_HELP_STRING([--with-linux-path=PATH], [where the linux sources are located])], [linux_path="$withval"], [linux_path="/usr/src/linux"]) LINUX_INCLUDE="-I$linux_path/include" AC_SUBST(LINUX_INCLUDE) AC_CHECK_PROG([MKNOD], [mknod], [mknod], [no]) AC_CHECK_PROG([DEPMOD], [depmod], [depmod], [no], ["$PATH:/sbin"]) fi AM_CONDITIONAL([HAVE_LINUX], [test x"$enable_linux" = x"yes"]) AM_CONDITIONAL([BUILD_DHA_KMOD], [test x"$enable_dha_kmod" != x"no"]) dnl DirectFB XINE_ARG_ENABLE([directfb], [enable use of DirectFB]) if test "x$enable_directfb" = "xyes"; then PKG_CHECK_MODULES([DIRECTFB], [directfb >= 0.9.22], [have_directfb=yes], [have_directfb=no]) if test x"$hard_enable_directfb" = x"yes" && test x"$have_directfb" != x"yes"; then AC_MSG_ERROR([DirectFB support requested, but DirectFB not found]) fi fi AM_CONDITIONAL([ENABLE_DIRECTFB], [test x"$have_directfb" = x"yes"]) dnl DirectX (see directx.m4) AM_PATH_DIRECTX dnl dxr3 / hollywood plus card XINE_ARG_ENABLE([dxr3], [enable support for DXR3/HW+]) if test x"$enable_dxr3" != x"no"; then have_dxr3=yes AC_MSG_RESULT([*** checking for a supported mpeg encoder]) AC_CHECK_LIB([fame], [fame_open], [AC_CHECK_HEADERS([fame.h], [have_libfame=yes], [have_libfame=no])], [have_libfame=no]) if test x"$have_libfame" = x"yes"; then have_encoder=yes AC_DEFINE([HAVE_LIBFAME], 1, [Define this if you have libfame mpeg encoder installed (fame.sf.net)]) ACX_PACKAGE_CHECK([LIBFAME], [0.8.10], [libfame-config], [AC_DEFINE([HAVE_NEW_LIBFAME], 1, [Define this if you have libfame 0.8.10 or above])]) fi AC_CHECK_LIB([rte], [rte_init], [AC_CHECK_HEADERS([rte.h], [have_librte=yes], [have_librte=no])], [have_librte=no]) if test x"$have_librte" = x"yes"; then have_encoder=yes AC_MSG_WARN([this will probably only work with rte version 0.4!]) AC_DEFINE([HAVE_LIBRTE], 1, [Define this if you have librte mpeg encoder installed (zapping.sf.net)]) fi if test "$have_encoder" = "yes"; then AC_MSG_RESULT([*** found one or more external mpeg encoders]) else AC_MSG_RESULT([*** no external mpeg encoder found]) fi else have_dxr3=no have_libfame=no have_librte=no have_encoder=no fi AM_CONDITIONAL([ENABLE_DXR3], [test x"$have_dxr3" = x"yes"]) AM_CONDITIONAL([HAVE_LIBFAME], [test x"$have_libfame" = x"yes"]) AM_CONDITIONAL([HAVE_LIBRTE], [test x"$have_librte" = x"yes"]) dnl LibSTK - http://www.libstk.net (project appears to be dead) XINE_ARG_WITH([libstk], [Build with STK surface video driver]) if test x"$with_libstk" != x"no"; then PKG_CHECK_MODULES([LIBSTK], [libstk >= 0.2.0], [have_libstk=yes], [have_libstk=no]) if test x"$hard_with_libstk" = x"yes" && test x"$have_libstk" != x"yes"; then AC_MSG_ERROR([libstk support requested, but libstk not found]) fi fi AM_CONDITIONAL([ENABLE_STK], [test x"$have_libstk" = x"yes"]) dnl Linux framebuffer device XINE_ARG_ENABLE([fb], [enable Linux framebuffer support]) if test x"$enable_fb" != x"no"; then AC_CHECK_HEADERS([linux/fb.h], [have_fb=yes], [have_fb=no]) if test x"$hard_enable_fb" = x"yes" && test x"$have_fb" != x"yes"; then AC_MSG_ERROR([Linux framebuffer support requested, but required header file(s) not found]) elif test x"$have_fb" = x"yes"; then dnl This define is needed by src/video_out/video_out_vidix.c AC_DEFINE([HAVE_FB], 1, [Define this if you have linux framebuffer support]) fi fi AM_CONDITIONAL([ENABLE_FB], [test x"$have_fb" = x"yes"]) dnl Mac OS X OpenGL video output XINE_ARG_ENABLE([macosx-video], [enable support for Mac OS X OpenGL video output]) if test x"$enable_macosx_video" != x"no"; then AC_MSG_CHECKING([for Mac OS X video output frameworks]) ac_save_LIBS="$LIBS" LIBS="$LIBS -framework Cocoa -framework OpenGL" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[return 0]])], [have_macosx_video=yes], [have_macosx_video=no]) LIBS="$ac_save_LIBS" AC_MSG_RESULT([$have_macosx_video]) if test x"$hard_enable_macosx_video" = x"yes" && test x"$have_macosx_video" != x"yes"; then AC_MSG_ERROR([Mac OS X OpenGL video output support requested, but required frameworks not found]) fi fi AM_CONDITIONAL([ENABLE_MACOSX_VIDEO], [test x"$have_macosx_video" = x"yes"]) dnl Wayland (used only in opengl2) XINE_ARG_ENABLE([wayland], [Disable native Wayland support]) if test x"$enable_wayland" != x"no"; then PKG_CHECK_MODULES([WAYLAND], [wayland-egl egl], [ have_wayland=yes ], [ have_wayland=no AS_IF([test x"$hard_enable_wayland" = x"yes"], [ AC_MSG_ERROR([${WAYLAND_PKG_ERRORS}.])], [ AC_MSG_WARN([${WAYLAND_PKG_ERRORS}.])])]) fi AM_CONDITIONAL([ENABLE_WAYLAND], test x"$have_wayland" = x"yes") dnl OpenGL, including GLut and/or GLU XINE_ARG_ENABLE([opengl], [enable support for X-based OpenGL video output]) XINE_ARG_ENABLE([glu], [enable support for GLU in the OpenGL plugin]) if test x"$enable_opengl" != x"no"; then if test x"$no_x" = x"yes" && test x"$have_wayland" != x"yes"; then if test x"$hard_enable_opengl" = x"yes"; then AC_MSG_ERROR([OpenGL support requires X11 or Wayland]) fi enable_opengl=no fi fi if test x"$enable_opengl" != x"no"; then ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $X_CFLAGS" AC_CHECK_LIB([GL], [glBegin], [AC_CHECK_HEADERS([GL/gl.h], [have_opengl=yes], [have_opengl=no])], [have_opengl=no], [$X_LIBS -lm]) if test x"$hard_enable_opengl" = x"yes" && test x"$have_opengl" != x"yes"; then AC_MSG_ERROR([OpenGL support requested, but OpenGL not found]) fi if test x"$have_opengl" = x"yes"; then OPENGL_LIBS="-lGL -lm" if test x"$enable_glu" != x"no"; then have_glu=no AC_CHECK_LIB([GLU], [gluPerspective], [AC_CHECK_HEADERS([GL/glu.h], [AC_MSG_CHECKING([if GLU is sane]) ac_save_LIBS="$LIBS" LIBS="-lGLU $X_LIBS $OPENGL_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[gluPerspective(45.0f, 1.33f, 1.0f, 1000.0f); glBegin(GL_POINTS); glEnd()]])], [have_glu=yes], [have_glu=no]) LIBS="$ac_save_LIBS" AC_MSG_RESULT([$have_glu])], [have_glu=no])], [have_glu=no], [$X_LIBS $OPENGL_LIBS]) if test x"$hard_enable_glu" = x"yes" && test x"$have_glu" != x"yes"; then AC_MSG_ERROR([OpenGL GLU support requested, but GLU not found]) elif test x"$have_glu" = x"yes"; then AC_DEFINE([HAVE_GLU], 1, [Define this if you have GLU support available]) GLU_LIBS="-lGLU" fi fi fi CPPFLAGS="$ac_save_CPPFLAGS" fi AC_SUBST(OPENGL_CFLAGS) AC_SUBST(OPENGL_LIBS) AC_SUBST(GLU_LIBS) AM_CONDITIONAL([ENABLE_OPENGL], [test x"$have_opengl" = x"yes" && test x"$no_x" != x"yes"]) if test x"$have_opengl" = x"yes"; then AC_DEFINE([HAVE_OPENGL], 1, [Define this if you have OpenGL support available]) fi dnl OpenGL 2.0 if test x"$have_opengl" = x"yes" ; then AC_MSG_CHECKING([for OpenGL 2.0]) ac_save_LIBS="$LIBS" LIBS="$LIBS $X_LIBS -lGL -lm" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #define GL_GLEXT_PROTOTYPES #include #include ]],[[ GLint i = 0; /* GL_VERSION_1_5 */ glDeleteBuffers (1024, &i); /* GL_VERSION_2_0 */ glCreateProgram (); glCompileShader (1); /* GL_ARB_framebuffer_object */ glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, 2, 0); /* GL_ARB_shader_objects */ glGetUniformLocationARB (3, "tex");]])], [have_opengl2=yes], [have_opengl2=no]) LIBS="$ac_save_LIBS" AC_MSG_RESULT($have_opengl2) fi if test x"$have_opengl2" = x"yes" ; then PKG_CHECK_MODULES([EGL], [egl], [have_egl=yes], [have_egl=no]) AC_MSG_CHECKING([for OpenGL GLX 2.0]) ac_save_LIBS="$LIBS" LIBS="$LIBS $X_LIBS -lGL -lm" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ /* GLX ARB 2.0 */ glXGetProcAddressARB ("proc");]])], [have_glx=yes], [have_glx=no]) LIBS="$ac_save_LIBS" AC_MSG_RESULT($have_glx) if test x"$have_glx" != x"yes" && test x"$have_egl" != x"yes" && test x"$have_wayland" != x"yes"; then AC_MSG_WARN([OpenGL 2.0 requires GLX, EGL or Wayland.]) have_opengl2=no fi else if test x"$hard_enable_wayland" = x"yes" ; then AC_MSG_ERROR([GLX, EGL and Wayland require OpenGL2]) fi have_glx=have_egl=no; fi AM_CONDITIONAL([ENABLE_OPENGL2], [test x"$have_opengl2" = x"yes"]) AM_CONDITIONAL([ENABLE_GLX], [test x"$have_glx" = x"yes"]) AM_CONDITIONAL([ENABLE_EGL], [test x"$have_egl" = x"yes"]) dnl SDL XINE_ARG_WITH([sdl], [Enable support for SDL video output]) if test x"$with_sdl" != x"no"; then PKG_CHECK_MODULES([SDL], [sdl], [have_sdl=yes], [have_sdl=no]) if test x"$hard_with_sdl" = x"yes" && test x"$have_sdl" != x"yes"; then AC_MSG_ERROR([SDL support requested, but SDL not found]) fi fi AM_CONDITIONAL([ENABLE_SDL], [test x"$have_sdl" = x"yes"]) dnl Solaris framebuffer device support (exists for more than just Solaris) AC_CHECK_HEADERS([sys/fbio.h], [have_sunfb=yes], [have_sunfb=no]) if test x"$have_sunfb" = x"yes"; then saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I/usr/openwin/include" saved_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -L/usr/openwin/lib" AC_CHECK_LIB([dga], [XDgaGrabDrawable], [AC_CHECK_HEADER([dga/dga.h], [SUNDGA_CPPFLAGS="-I/usr/openwin/include" SUNDGA_LIBS="-L/usr/openwin/lib -R/usr/openwin/lib -ldga" have_sundga=yes])]) CPPFLAGS="$saved_CPPFLAGS" LDFLAGS="$saved_LDFLAGS" AC_SUBST(SUNDGA_CPPFLAGS) AC_SUBST(SUNDGA_LIBS) fi AM_CONDITIONAL([ENABLE_SUNDGA], [test x"$have_sundga" = x"yes"]) AM_CONDITIONAL([ENABLE_SUNFB], [test x"$have_sunfb" = x"yes"]) dnl xcb XINE_ARG_WITH([xcb], [Enable support for XCB video out plugins]) if test x"$with_xcb" != x"no"; then PKG_CHECK_MODULES([XCB], [xcb xcb-shape >= 1.0], [have_xcb=yes], [have_xcb=no]) if test x"$hard_enable_xcb" = x"yes" && test x"$have_xcb" != x"yes"; then AC_MSG_ERROR([XCB support requested, but XCB not found]) elif test x"$have_xcb" = x"yes"; then PKG_CHECK_MODULES([XCBSHM], [xcb-shm], [have_xcbshm=yes], [have_xcbshm=no]) PKG_CHECK_MODULES([XCBXV], [xcb-xv], [have_xcbxv=yes], [have_xcbxv=no]) fi fi AM_CONDITIONAL([ENABLE_XCB], [test x"$have_xcb" = x"yes"]) AM_CONDITIONAL([ENABLE_XCBSHM], [test x"$have_xcbshm" = x"yes"]) AM_CONDITIONAL([ENABLE_XCBXV], [test x"$have_xcbxv" = x"yes"]) dnl vidix/libdha dnl Requires X11 or Linux framebuffer XINE_ARG_ENABLE([vidix], [enable support for Vidix]) if test x"$enable_vidix" != x"no"; then have_vidix=yes if test x"$ac_cv_prog_AWK" = x"no"; then have_vidix=no else if test x"$no_x" = x"yes" -o x"$have_fb" != x"yes"; then have_vidix=no else case "$host_or_hostalias" in i?86-*-linux* | k?-*-linux* | athlon-*-linux*) ;; i?86-*-freebsd* | k?-*-freebsd* | athlon-*-freebsd* | i?86-*-kfreebsd*) ;; *) have_vidix="no" ;; esac fi fi if test x"$hard_enable_vidix" = x"yes" && test x"$have_vidix" != x"yes"; then AC_MSG_ERROR([Vidix support requested, but not all requirements are met]) fi fi AM_CONDITIONAL([ENABLE_VIDIX], test x"$have_vidix" = x"yes") dnl Xinerama XINE_ARG_ENABLE([xinerama], [enable support for Xinerama]) if test x"$enable_xinerama" != x"no"; then if test x"$no_x" != x"yes"; then PKG_CHECK_MODULES([XINERAMA], [xinerama], [have_xinerama=yes], [AC_CHECK_LIB([Xinerama], [XineramaQueryExtension], [XINERAMA_LIBS="-lXinerama" have_xinerama="yes"], [], [$X_LIBS])]) fi if test x"$hard_enable_xinerama" = x"yes" && test x"$have_xinerama" != x"yes"; then AC_MSG_ERROR([Xinerama support requested, but Xinerama not found or X disabled]) elif test x"$have_xinerama" = x"yes"; then AC_DEFINE([HAVE_XINERAMA], 1, [Define this if you have libXinerama installed]) X_LIBS="$X_LIBS $XINERAMA_LIBS" fi fi AM_CONDITIONAL([ENABLE_XINERAMA], [test x"$have_xinerama" = x"yes"]) dnl xv AC_ARG_WITH([xv-path], [AS_HELP_STRING([--with-xv-path=path], [where libXv is installed])]) dnl With recent XFree86 or Xorg, dynamic linking is preferred! dnl Only dynamic linking is possible when using libtool < 1.4.0 AC_ARG_ENABLE([static-xv], [AS_HELP_STRING([--enable-static-xv], [Enable this to force linking against libXv.a])], [test x"$enableval" != x"no" && xv_prefer_static="yes"], [xv_prefer_static="no"]) case "$host_or_hostalias" in hppa*) xv_libexts="$acl_cv_shlibext" ;; *) if test x"$xv_prefer_static" = x"yes"; then xv_libexts="$acl_cv_libext $acl_cv_shlibext" else xv_libexts="$acl_cv_shlibext $acl_cv_libext" fi ;; esac if test x"$no_x" != x"yes"; then PKG_CHECK_MODULES([XV], [xv], [have_xv=yes], [have_xv=no]) if test x"$have_xv" = x"no"; then dnl No Xv package -- search for it for xv_libext in $xv_libexts; do xv_lib="libXv.$xv_libext" AC_MSG_CHECKING([for $xv_lib]) for xv_try_path in "$with_xv_path" "$x_libraries" /usr/X11R6/lib /usr/lib; do if test x"$xv_try_path" != x"" && test -f "$xv_try_path/$xv_lib"; then case $xv_lib in *.$acl_cv_libext) have_xv_static=yes xv_try_libs="$xv_try_path/$xv_lib" ;; *.$acl_cv_shlibext) have_xv_static=no xv_try_libs="${xv_try_path:+-L}$xv_try_path -lXv" ;; esac ac_save_LIBS="$LIBS" LIBS="$xv_try_libs $X_PRE_LIBS $X_LIBS $X_EXTRA_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[XvShmCreateImage()]])], [have_xv=yes], []) LIBS="$ac_save_LIBS" if test x"$have_xv" = x"yes"; then AC_MSG_RESULT([$xv_try_path]) XV_LIBS="$xv_try_libs" break fi fi done test x"$have_xv" = x"yes" && break AC_MSG_RESULT([no]) done fi if test x"$have_xv" = x"yes"; then AC_DEFINE([HAVE_XV], 1, [Define this if you have libXv installed]) fi fi AM_CONDITIONAL([HAVE_XV], [test x"$have_xv" = x"yes"]) dnl XvMC XINE_ARG_ENABLE([xvmc], [Enable xxmc and XvMC outplut plugins]) AC_ARG_WITH([xvmc-path], [AS_HELP_STRING([--with-xvmc-path=PATH], [where libXvMC for the xvmc plugin are installed])], [], [with_xvmc_path="$x_libraries"]) AC_ARG_WITH([xvmc-lib], [AS_HELP_STRING([--with-xvmc-lib=LIBNAME], [The name of the XvMC library libLIBNAME.so for the xvmc plugin])], [], [with_xvmc_lib="XvMCW"]) AC_ARG_WITH([xxmc-path], [AS_HELP_STRING([--with-xxmc-path=PATH], [Where libXvMC for the xxmc plugin are installed])], [], [with_xxmc_path="$x_libraries"]) AC_ARG_WITH([xxmc-lib], [AS_HELP_STRING([--with-xxmc-lib=LIBNAME], [The name of the XvMC library libLIBNAME.so for the xxmc plugin])], [], [with_xxmc_lib="XvMCW"]) if test x"$enable_xvmc" != x"no"; then if test x"$have_xv" != x"yes"; then have_xvmc=no have_xxmc=no have_xvmc_or_xxmc=no else ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $X_CFLAGS" ac_save_LIBS="$LIBS" dnl Check for xxmc XXMC_LIBS="${with_xxmc_path:+-L}$with_xxmc_path -l$with_xxmc_lib" AC_SUBST(XXMC_LIBS) AC_MSG_CHECKING([whether to enable the xxmc plugin with VLD extensions]) AC_MSG_RESULT([]) LIBS="$XXMC_LIBS $X_LIBS $XV_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCPutSlice(void);]], [[XvMCPutSlice()]])], [have_xxmc=yes], [LIBS="$XXMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS $DYNAMIC_LD_LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCPutSlice(void);]], [[XvMCPutSlice()]])], [have_xxmc=yes XXMC_LIBS="$XXMC_LIBS -lXvMC"])]) if test x"$have_xxmc" = x"yes"; then AC_CHECK_HEADERS([X11/extensions/vldXvMC.h], [have_vldexts=yes AC_DEFINE([HAVE_VLDXVMC], 1, [Define if you have vldXvMC.h])], [have_vldexts=no]) else AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])], [have_xxmc=yes], [LIBS="$XXMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])], [have_xxmc=yes XXMC_LIBS="$XXMC_LIBS -lXvMC"])]) fi if test x"$have_xxmc" = x"yes"; then AC_CHECK_HEADERS([X11/extensions/XvMC.h], [], [have_xxmc=no]) fi dnl Check for xvmc XVMC_LIBS="${with_xvmc_path:+-L}$with_xvmc_path -l$with_xvmc_lib" AC_SUBST(XVMC_LIBS) AC_MSG_CHECKING([whether to enable the xvmc plugin]) AC_MSG_RESULT([]) LIBS="$XVMC_LIBS $X_LIBS $XV_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])], [have_xvmc=yes], [LIBS="$XVMC_LIBS -lXvMC $X_LIBS $XV_LIBS $LIBS $DYNAMIC_LD_LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[char XvMCCreateContext(void);]], [[XvMCCreateContext()]])], [have_xvmc=yes XVMC_LIBS="$XVMC_LIBS -lXvMC"])]) if test x"$have_xvmc" = x"yes"; then AC_CHECK_HEADERS([X11/extensions/XvMC.h], [], [have_xvmc=no]) fi CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" fi have_xvmc_or_xxmc="$have_xvmc"; test x"$have_xxmc" = x"yes" && have_xvmc_or_xxmc=yes if test x"$hard_enable_xvmc" = x"yes" && test x"$have_xvmc_or_xxmc" != x"yes"; then AC_MSG_ERROR([XvMC support requested, but neither XvMC nor xxmc could be found, or X is disabled]) else if test x"$have_xvmc" = x"yes"; then AC_DEFINE([HAVE_XVMC], 1, [Define this if you have an XvMC library and XvMC.h installed.]) AC_MSG_RESULT([*** Enabling old xvmc plugin.]) else AC_MSG_RESULT([*** Disabling old xvmc plugin.]) fi if test x"$have_xxmc" = x"yes"; then if test x"$have_vldexts" = x"yes"; then AC_MSG_RESULT([*** Enabling xxmc plugin with vld extensions.]) else AC_MSG_RESULT([*** Enabling xxmc plugin for standard XvMC *only*.]) fi else AC_MSG_RESULT([*** Disabling xxmc plugin.]) fi fi fi AM_CONDITIONAL([ENABLE_XVMC], [test x"$have_xvmc" = x"yes"]) AM_CONDITIONAL([ENABLE_XXMC], [test x"$have_xxmc" = x"yes"]) dnl VDPAU XINE_ARG_ENABLE([vdpau], [Disable VDPAU output plugin]) if test x"$no_x" != x"yes" && test x"$enable_vdpau" != x"no"; then PKG_CHECK_MODULES([VDPAU], [vdpau], [have_vdpau=yes], [have_vdpau=no]) if test x"$have_vdpau" = xno; then saved_CFLAGS="$CFLAGS" saved_LIBS="$LIBS" CFLAGS= LIBS= dnl likely defaults dnl if these are bad, blame nVidia for not supplying vdpau.pc VDPAU_CFLAGS= VDPAU_LIBS=-lvdpau AC_CHECK_HEADERS([vdpau/vdpau_x11.h], [have_vdpau=yes], [have_vdpau=no]) if test x"$have_vdpau" = x"yes"; then AC_CHECK_LIB([vdpau], [vdp_device_create_x11], [], [have_vdpau=no], [$X_LIBS $X_PRE_LIBS -lXext $X_EXTRA_LIBS]) fi if test x"$hard_enable_vdpau" = x"yes" && test x"$have_vdpau" != x"yes"; then AC_MSG_ERROR([VDPAU support requested, but not all requirements are met]) fi CFLAGS="$saved_CFLAGS" LIBS="$saved_LIBS" AC_SUBST([VDPAU_CFLAGS]) AC_SUBST([VDPAU_LIBS]) fi fi AM_CONDITIONAL([ENABLE_VDPAU], test x"$have_vdpau" = x"yes") dnl VAAPI XINE_ARG_ENABLE([vaapi], [Disable VAAPI output plugin]) if test x"$enable_vaapi" != x"no"; then PKG_CHECK_MODULES([LIBVA], [libva], [have_vaapi=yes], [ have_vaapi=no AS_IF([test x"$hard_enable_vaapi" = x"yes"], [ AC_MSG_ERROR([${LIBVA_PKG_ERRORS}.]) ], [ AC_MSG_WARN([${LIBVA_PKG_ERRORS}.]) ]) ]) AC_CHECK_HEADERS([va/va.h], , [have_vaapi=no]) fi if test x"$have_vaapi" = x"yes"; then dnl vaapi display providers AC_CHECK_HEADERS([va/va_glx.h va/va_x11.h va/va_wayland.h va/va_drm.h va/va_drmcommon.h]) PKG_CHECK_MODULES([LIBVA_X11], [libva libva-x11], [have_vaapi_x11=yes], [have_vaapi_x11=no]) PKG_CHECK_MODULES([LIBVA_GLX], [libva libva-glx], [have_vaapi_glx=yes], [have_vaapi_glx=no]) PKG_CHECK_MODULES([LIBVA_WAYLAND], [libva libva-wayland], [have_vaapi_wayland=yes],[have_vaapi_wayland=no]) PKG_CHECK_MODULES([LIBVA_DRM], [libva libva-drm], [have_vaapi_drm=yes], [have_vaapi_drm=no]) if test x"$have_vaapi_x11" != x"yes" && test x"$have_vaapi_glx" != x"yes" && test x"$have_vaapi_wayland" != x"yes" && test x"$have_vaapi_drm" != x"yes"; then if test x"$hard_enable_vaapi" = x"yes"; then AC_MSG_ERROR([No VAAPI display providers found.]) else AC_MSG_WARN([No VAAPI display providers found.]) have_vaapi=no fi fi fi AM_CONDITIONAL([ENABLE_VAAPI], test x"$have_vaapi" = x"yes") AM_CONDITIONAL([ENABLE_VAAPI_X11], test x"$have_vaapi_x11" = x"yes") AM_CONDITIONAL([ENABLE_VAAPI_GLX], test x"$have_vaapi_glx" = x"yes") AM_CONDITIONAL([ENABLE_VAAPI_DRM], test x"$have_vaapi_drm" = x"yes") AM_CONDITIONAL([ENABLE_VAAPI_WAYLAND], test x"$have_vaapi_wayland" = x"yes") ])dnl XINE_VIDEO_OUT_PLUGIN xine-lib-1.2/m4/attributes.m40000644000175000017500000002536214647725152013644 0ustar memednl Macros to check the presence of generic (non-typed) symbols. dnl Copyright (c) 2006-2008 Diego Pettenò dnl Copyright (c) 2006-2008 xine project dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2, or (at your option) dnl any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA dnl 02110-1301, USA. dnl dnl As a special exception, the copyright owners of the dnl macro gives unlimited permission to copy, distribute and modify the dnl configure scripts that are the output of Autoconf when processing the dnl Macro. You need not follow the terms of the GNU General Public dnl License when using or distributing such scripts, even though portions dnl of the text of the Macro appear in them. The GNU General Public dnl License (GPL) does govern all other use of the material that dnl constitutes the Autoconf Macro. dnl dnl This special exception to the GPL applies to versions of the dnl Autoconf Macro released by this project. When you make and dnl distribute a modified version of the Autoconf Macro, you may extend dnl this special exception to the GPL to apply to your modified version as dnl well. dnl Check if the flag is supported by compiler dnl CC_CHECK_CFLAGS_SILENT([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) AC_DEFUN([CC_CHECK_CFLAGS_SILENT], [ AC_CACHE_VAL(AS_TR_SH([cc_cv_cflags_$1]), [ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $1" AC_COMPILE_IFELSE([AC_LANG_SOURCE([int a;])], [eval "AS_TR_SH([cc_cv_cflags_$1])='yes'"], [eval "AS_TR_SH([cc_cv_cflags_$1])='no'"]) CFLAGS="$ac_save_CFLAGS" ]) AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], [$2], [$3]) ]) dnl Check if the flag is supported by compiler (cacheable) dnl CC_CHECK_CFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) AC_DEFUN([CC_CHECK_CFLAGS], [ AC_CACHE_CHECK([if $CC supports $1 flag], AS_TR_SH([cc_cv_cflags_$1]), CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! ) AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], [$2], [$3]) ]) dnl CC_CHECK_CFLAG_APPEND(FLAG, [action-if-found], [action-if-not-found]) dnl Check for CFLAG and appends them to CFLAGS if supported AC_DEFUN([CC_CHECK_CFLAG_APPEND], [ AC_CACHE_CHECK([if $CC supports $1 flag], AS_TR_SH([cc_cv_cflags_$1]), CC_CHECK_CFLAGS_SILENT([$1]) dnl Don't execute actions here! ) AS_IF([eval test x$]AS_TR_SH([cc_cv_cflags_$1])[ = xyes], [CFLAGS="$CFLAGS $1"; DEBUG_CFLAGS="$DEBUG_CFLAGS $1"; $2], [$3]) ]) dnl CC_CHECK_CFLAGS_APPEND([FLAG1 FLAG2], [action-if-found], [action-if-not]) AC_DEFUN([CC_CHECK_CFLAGS_APPEND], [ for flag in $1; do CC_CHECK_CFLAG_APPEND($flag, [$2], [$3]) done ]) dnl Check if the flag is supported by linker (cacheable) dnl CC_CHECK_LDFLAGS([FLAG], [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND]) AC_DEFUN([CC_CHECK_LDFLAGS], [ AC_CACHE_CHECK([if $CC supports $1 flag], AS_TR_SH([cc_cv_ldflags_$1]), [ac_save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $1" AC_LINK_IFELSE([AC_LANG_SOURCE([int main() { return 1; }])], [eval "AS_TR_SH([cc_cv_ldflags_$1])='yes'"], [eval "AS_TR_SH([cc_cv_ldflags_$1])="]) LDFLAGS="$ac_save_LDFLAGS" ]) AS_IF([eval test x$]AS_TR_SH([cc_cv_ldflags_$1])[ = xyes], [$2], [$3]) ]) dnl define the LDFLAGS_NOUNDEFINED variable with the correct value for dnl the current linker to avoid undefined references in a shared object. AC_DEFUN([CC_NOUNDEFINED], [ dnl We check $host for which systems to enable this for. AC_REQUIRE([AC_CANONICAL_HOST]) case $host in dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads dnl are requested, as different implementations are present; to avoid problems dnl use -Wl,-z,defs only for those platform not behaving this way. dnl dnl MinGW platforms: for libraries required -no-undefined, dnl use it only for libraries in mingw32-w64 *-freebsd* | *-openbsd*) ;; *-mingw* | *-cygwin*) LDFLAGS_NOUNDEFINED="-no-undefined" ;; *) dnl First of all check for the --no-undefined variant of GNU ld. This allows dnl for a much more readable commandline, so that people can understand what dnl it does without going to look for what the heck -z defs does. for possible_flags in "-Wl,--no-undefined" "-Wl,-z,defs"; do CC_CHECK_LDFLAGS([$possible_flags], [LDFLAGS_NOUNDEFINED="$possible_flags"]) if test "x$LDFLAGS_NOUNDEFINED" = "x"; then break; fi done ;; esac AC_SUBST([LDFLAGS_NOUNDEFINED]) ]) dnl Check for a -Werror flag or equivalent. -Werror is the GCC dnl and ICC flag that tells the compiler to treat all the warnings dnl as fatal. We usually need this option to make sure that some dnl constructs (like attributes) are not simply ignored. dnl dnl Other compilers don't support -Werror per se, but they support dnl an equivalent flag: dnl - Sun Studio compiler supports -errwarn=%all AC_DEFUN([CC_CHECK_WERROR], [ AC_CACHE_CHECK( [for $CC way to treat warnings as errors], [cc_cv_werror], [CC_CHECK_CFLAGS_SILENT([-Werror], [cc_cv_werror=-Werror], [CC_CHECK_CFLAGS_SILENT([-errwarn=%all], [cc_cv_werror=-errwarn=%all])]) ]) ]) AC_DEFUN([CC_CHECK_ATTRIBUTE], [ AC_REQUIRE([CC_CHECK_WERROR]) AC_CACHE_CHECK([if $CC supports __attribute__(( ifelse([$2], , [$1], [$2]) ))], AS_TR_SH([cc_cv_attribute_$1]), [ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $cc_cv_werror" AC_COMPILE_IFELSE([AC_LANG_SOURCE([$3])], [eval "AS_TR_SH([cc_cv_attribute_$1])='yes'"], [eval "AS_TR_SH([cc_cv_attribute_$1])='no'"]) CFLAGS="$ac_save_CFLAGS" ]) AS_IF([eval test x$]AS_TR_SH([cc_cv_attribute_$1])[ = xyes], [AC_DEFINE( AS_TR_CPP([SUPPORT_ATTRIBUTE_$1]), 1, [Define this if the compiler supports __attribute__(( ifelse([$2], , [$1], [$2]) ))] ) $4], [$5]) ]) AC_DEFUN([CC_ATTRIBUTE_CONSTRUCTOR], [ CC_CHECK_ATTRIBUTE( [constructor],, [void __attribute__((constructor)) ctor() { int a; }], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_FORMAT], [ CC_CHECK_ATTRIBUTE( [format], [format(printf, n, n)], [void __attribute__((format(printf, 1, 2))) printflike(const char *fmt, ...) { fmt = (void *)0; }], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_FORMAT_ARG], [ CC_CHECK_ATTRIBUTE( [format_arg], [format_arg(printf)], [char *__attribute__((format_arg(1))) gettextlike(const char *fmt) { fmt = (void *)0; }], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_VISIBILITY], [ CC_CHECK_ATTRIBUTE( [visibility_$1], [visibility("$1")], [void __attribute__((visibility("$1"))) $1_function() { }], [$2], [$3]) ]) AC_DEFUN([CC_ATTRIBUTE_NONNULL], [ CC_CHECK_ATTRIBUTE( [nonnull], [nonnull()], [void __attribute__((nonnull())) some_function(void *foo, void *bar) { foo = (void*)0; bar = (void*)0; }], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_UNUSED], [ CC_CHECK_ATTRIBUTE( [unused], , [void some_function(void *foo, __attribute__((unused)) void *bar);], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_WARN_UNUSED_RESULT], [ CC_CHECK_ATTRIBUTE( [warn_unused_result], , [void *some_function(void) __attribute__((warn_unused_result));], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_SENTINEL], [ CC_CHECK_ATTRIBUTE( [sentinel], , [void some_function(void *foo, ...) __attribute__((sentinel));], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_WEAK], [ CC_CHECK_ATTRIBUTE( [weak], , [void some_function(void *, int) __attribute__((weak));], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_DEPRECATED], [ CC_CHECK_ATTRIBUTE( [deprecated], , [void some_function(void *foo, ...) __attribute__((deprecated));], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_ALIAS], [ CC_CHECK_ATTRIBUTE( [alias], [weak, alias], [void other_function(void *foo) { } void some_function(void *foo) __attribute__((weak, alias("other_function")));], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_MALLOC], [ CC_CHECK_ATTRIBUTE( [malloc], , [void * __attribute__((malloc)) my_alloc(int n);], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_PACKED], [ CC_CHECK_ATTRIBUTE( [packed], , [struct astructure { char a; int b; long c; void *d; } __attribute__((packed));], [$1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_CONST], [ CC_CHECK_ATTRIBUTE( [const], , [int __attribute__((const)) twopow(int n) { return 1 << n; } ], [$1], [$2]) ]) AC_DEFUN([CC_FLAG_VISIBILITY], [ AC_REQUIRE([CC_CHECK_WERROR]) AC_CACHE_CHECK([if $CC supports -fvisibility=hidden], [cc_cv_flag_visibility], [cc_flag_visibility_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $cc_cv_werror" CC_CHECK_CFLAGS_SILENT([-fvisibility=hidden], cc_cv_flag_visibility='yes', cc_cv_flag_visibility='no') CFLAGS="$cc_flag_visibility_save_CFLAGS"]) AS_IF([test "x$cc_cv_flag_visibility" = "xyes"], [AC_DEFINE([SUPPORT_FLAG_VISIBILITY], 1, [Define this if the compiler supports the -fvisibility flag]) $1], [$2]) ]) AC_DEFUN([CC_FUNC_EXPECT], [ AC_REQUIRE([CC_CHECK_WERROR]) AC_CACHE_CHECK([if compiler has __builtin_expect function], [cc_cv_func_expect], [ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $cc_cv_werror" AC_COMPILE_IFELSE( [int some_function() { int a = 3; return (int)__builtin_expect(a, 3); }], [cc_cv_func_expect=yes], [cc_cv_func_expect=no]) CFLAGS="$ac_save_CFLAGS" ]) AS_IF([test "x$cc_cv_func_expect" = "xyes"], [AC_DEFINE([SUPPORT__BUILTIN_EXPECT], 1, [Define this if the compiler supports __builtin_expect() function]) $1], [$2]) ]) AC_DEFUN([CC_ATTRIBUTE_ALIGNED], [ AC_REQUIRE([CC_CHECK_WERROR]) AC_CACHE_CHECK([highest __attribute__ ((aligned ())) supported], [cc_cv_attribute_aligned], [ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $cc_cv_werror" for cc_attribute_align_try in 64 32 16 8 4 2; do AC_COMPILE_IFELSE([AC_LANG_SOURCE([ int main() { static char c __attribute__ ((aligned($cc_attribute_align_try))) = 0; return c; }])], [cc_cv_attribute_aligned=$cc_attribute_align_try; break]) done CFLAGS="$ac_save_CFLAGS" ]) if test "x$cc_cv_attribute_aligned" != "x"; then AC_DEFINE_UNQUOTED([ATTRIBUTE_ALIGNED_MAX], [$cc_cv_attribute_aligned], [Define the highest alignment supported]) fi ]) xine-lib-1.2/m4/objc.m40000644000175000017500000002152314647725152012366 0ustar meme# Extracted from autoconf 2.61 to obtain Objective C macros. # Only expand if the version of autoconf in use doesn't have the macro itself. m4_ifdef([AC_PROG_OBJC], [], [ # This file is part of Autoconf. -*- Autoconf -*- # Programming languages support. # Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Free Software # Foundation, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception, the Free Software Foundation gives unlimited # permission to copy, distribute and modify the configure scripts that # are the output of Autoconf. You need not follow the terms of the GNU # General Public License when using or distributing such scripts, even # though portions of the text of Autoconf appear in them. The GNU # General Public License (GPL) does govern all other use of the material # that constitutes the Autoconf program. # # Certain portions of the Autoconf source text are designed to be copied # (in certain cases, depending on the input) into the output of # Autoconf. We call these the "data" portions. The rest of the Autoconf # source text consists of comments plus executable code that decides which # of the data portions to output in any given case. We call these # comments and executable code the "non-data" portions. Autoconf never # copies any of the non-data portions into its output. # # This special exception to the GPL applies to versions of Autoconf # released by the Free Software Foundation. When you make and # distribute a modified version of Autoconf, you may extend this special # exception to the GPL to apply to your modified version as well, *unless* # your modified version has the potential to copy into its output some # of the text that was the non-data portion of the version that you started # with. (In other words, unless your change moves or copies text from # the non-data portions to the data portions.) If your modification has # such potential, you must delete any notice of this special exception # to the GPL from your modified version. # # Written by David MacKenzie, with help from # Akim Demaille, Paul Eggert, # Franc,ois Pinard, Karl Berry, Richard Pixley, Ian Lance Taylor, # Roland McGrath, Noah Friedman, david d zuhn, and many others. # ------------------------------ # # 1d. The Objective C language. # # ------------------------------ # # AC_LANG(Objective C) # -------------------- m4_define([AC_LANG(Objective C)], [ac_ext=m ac_cpp='$OBJCPP $CPPFLAGS' ac_compile='$OBJC -c $OBJCFLAGS $CPPFLAGS conftest.$ac_ext >&AS_MESSAGE_LOG_FD' ac_link='$OBJC -o conftest$ac_exeext $OBJCFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&AS_MESSAGE_LOG_FD' ac_compiler_gnu=$ac_cv_objc_compiler_gnu ]) # AC_LANG_OBJC # ------------ AU_DEFUN([AC_LANG_OBJC], [AC_LANG(Objective C)]) # _AC_LANG_ABBREV(Objective C) # ---------------------------- m4_define([_AC_LANG_ABBREV(Objective C)], [objc]) # _AC_LANG_PREFIX(Objective C) # ---------------------------- m4_define([_AC_LANG_PREFIX(Objective C)], [OBJC]) # ------------------------- # # 2d. Objective C sources. # # ------------------------- # # AC_LANG_SOURCE(Objective C)(BODY) # --------------------------------- m4_copy([AC_LANG_SOURCE(C)], [AC_LANG_SOURCE(Objective C)]) # AC_LANG_PROGRAM(Objective C)([PROLOGUE], [BODY]) # ------------------------------------------------ m4_copy([AC_LANG_PROGRAM(C)], [AC_LANG_PROGRAM(Objective C)]) # AC_LANG_CALL(Objective C)(PROLOGUE, FUNCTION) # --------------------------------------------- m4_copy([AC_LANG_CALL(C)], [AC_LANG_CALL(Objective C)]) # AC_LANG_FUNC_LINK_TRY(Objective C)(FUNCTION) # -------------------------------------------- m4_copy([AC_LANG_FUNC_LINK_TRY(C)], [AC_LANG_FUNC_LINK_TRY(Objective C)]) # AC_LANG_BOOL_COMPILE_TRY(Objective C)(PROLOGUE, EXPRESSION) # ----------------------------------------------------------- m4_copy([AC_LANG_BOOL_COMPILE_TRY(C)], [AC_LANG_BOOL_COMPILE_TRY(Objective C)]) # AC_LANG_INT_SAVE(Objective C)(PROLOGUE, EXPRESSION) # --------------------------------------------------- m4_copy([AC_LANG_INT_SAVE(C)], [AC_LANG_INT_SAVE(Objective C)]) # ------------------------------ # # 3d. The Objective C compiler. # # ------------------------------ # # AC_LANG_PREPROC(Objective C) # ---------------------------- # Find the Objective C preprocessor. Must be AC_DEFUN'd to be AC_REQUIRE'able. m4_defun([AC_LANG_PREPROC(Objective C)], [AC_REQUIRE([AC_PROG_OBJCPP])]) # AC_PROG_OBJCPP # -------------- # Find a working Objective C preprocessor. AC_DEFUN([AC_PROG_OBJCPP], [AC_REQUIRE([AC_PROG_OBJC])dnl AC_ARG_VAR([OBJCPP], [Objective C preprocessor])dnl _AC_ARG_VAR_CPPFLAGS()dnl AC_LANG_PUSH(Objective C)dnl AC_MSG_CHECKING([how to run the Objective C preprocessor]) if test -z "$OBJCPP"; then AC_CACHE_VAL(ac_cv_prog_OBJCPP, [dnl # Double quotes because OBJCPP needs to be expanded for OBJCPP in "$OBJC -E" "/lib/cpp" do _AC_PROG_PREPROC_WORKS_IFELSE([break]) done ac_cv_prog_OBJCPP=$OBJCPP ])dnl OBJCPP=$ac_cv_prog_OBJCPP else ac_cv_prog_OBJCPP=$OBJCPP fi AC_MSG_RESULT([$OBJCPP]) _AC_PROG_PREPROC_WORKS_IFELSE([], [AC_MSG_FAILURE([Objective C preprocessor "$OBJCPP" fails sanity check])]) AC_SUBST(OBJCPP)dnl AC_LANG_POP(Objective C)dnl ])# AC_PROG_OBJCPP # AC_LANG_COMPILER(Objective C) # ----------------------------- # Find the Objective C compiler. Must be AC_DEFUN'd to be AC_REQUIRE'able. m4_defun([AC_LANG_COMPILER(Objective C)], [AC_REQUIRE([AC_PROG_OBJC])]) # AC_PROG_OBJC([LIST-OF-COMPILERS]) # --------------------------------- # LIST-OF-COMPILERS is a space separated list of Objective C compilers to # search for (if not specified, a default list is used). This just gives # the user an opportunity to specify an alternative search list for the # Objective C compiler. # objcc StepStone Objective-C compiler (also "standard" name for OBJC) # objc David Stes' POC. If you installed this, you likely want it. # cc Native C compiler (for instance, Apple). # CC You never know. AN_MAKEVAR([OBJC], [AC_PROG_OBJC]) AN_PROGRAM([objcc], [AC_PROG_OBJC]) AN_PROGRAM([objc], [AC_PROG_OBJC]) AC_DEFUN([AC_PROG_OBJC], [AC_LANG_PUSH(Objective C)dnl AC_ARG_VAR([OBJC], [Objective C compiler command])dnl AC_ARG_VAR([OBJCFLAGS], [Objective C compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl dnl _AC_ARG_VAR_LIBS()dnl _AC_ARG_VAR_CPPFLAGS()dnl _AC_ARG_VAR_PRECIOUS([OBJC])dnl AC_CHECK_TOOLS(OBJC, [m4_default([$1], [gcc objcc objc cc CC])], gcc) # Provide some information about the compiler. echo "$as_me:$LINENO:" \ "checking for _AC_LANG compiler version" >&AS_MESSAGE_LOG_FD ac_compiler=`set X $ac_compile; echo $[2]` _AC_EVAL([$ac_compiler --version &AS_MESSAGE_LOG_FD]) _AC_EVAL([$ac_compiler -v &AS_MESSAGE_LOG_FD]) _AC_EVAL([$ac_compiler -V &AS_MESSAGE_LOG_FD]) m4_expand_once([_AC_COMPILER_EXEEXT])[]dnl m4_expand_once([_AC_COMPILER_OBJEXT])[]dnl _AC_LANG_COMPILER_GNU GOBJC=`test $ac_compiler_gnu = yes && echo yes` _AC_PROG_OBJC_G AC_LANG_POP(Objective C)dnl ])# AC_PROG_OBJC # _AC_PROG_OBJC_G # --------------- # Check whether -g works, even if OBJCFLAGS is set, in case the package # plays around with OBJCFLAGS (such as to build both debugging and # normal versions of a library), tasteless as that idea is. # Don't consider -g to work if it generates warnings when plain compiles don't. m4_define([_AC_PROG_OBJC_G], [ac_test_OBJCFLAGS=${OBJCFLAGS+set} ac_save_OBJCFLAGS=$OBJCFLAGS AC_CACHE_CHECK(whether $OBJC accepts -g, ac_cv_prog_objc_g, [ac_save_objc_werror_flag=$ac_objc_werror_flag ac_objc_werror_flag=yes ac_cv_prog_objc_g=no OBJCFLAGS="-g" _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [ac_cv_prog_objc_g=yes], [OBJCFLAGS="" _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [], [ac_objc_werror_flag=$ac_save_objc_werror_flag OBJCFLAGS="-g" _AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], [ac_cv_prog_objc_g=yes])])]) ac_objc_werror_flag=$ac_save_objc_werror_flag]) if test "$ac_test_OBJCFLAGS" = set; then OBJCFLAGS=$ac_save_OBJCFLAGS elif test $ac_cv_prog_objc_g = yes; then if test "$GOBJC" = yes; then OBJCFLAGS="-g -O2" else OBJCFLAGS="-g" fi else if test "$GOBJC" = yes; then OBJCFLAGS="-O2" else OBJCFLAGS= fi fi[]dnl ])# _AC_PROG_OBJC_G ])dnl m4_ifdef([AC_PROG_OBJC]) xine-lib-1.2/m4/pkg.m40000644000175000017500000001216614647725152012235 0ustar meme# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # # Copyright © 2004 Scott James Remnant . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # PKG_PROG_PKG_CONFIG([MIN-VERSION]) # ---------------------------------- AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) fi if test -n "$PKG_CONFIG"; then _pkg_min_version=m4_default([$1], [0.9.0]) AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) PKG_CONFIG="" fi fi[]dnl ])# PKG_PROG_PKG_CONFIG # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) # # Check to see whether a particular set of modules exists. Similar # to PKG_CHECK_MODULES(), but does not set variables or print errors. # # # Similar to PKG_CHECK_MODULES, make sure that the first instance of # this or PKG_CHECK_MODULES is called, or make sure to call # PKG_CHECK_EXISTS manually # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_EXISTS], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl if test -n "$PKG_CONFIG" && \ AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then m4_ifval([$2], [$2], [:]) m4_ifvaln([$3], [else $3])dnl fi]) # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) # --------------------------------------------- m4_define([_PKG_CONFIG], [if test -n "$PKG_CONFIG"; then if test -n "$$1"; then pkg_cv_[]$1="$$1" else PKG_CHECK_EXISTS([$3], [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], [pkg_failed=yes]) fi else pkg_failed=untried fi[]dnl ])# _PKG_CONFIG # _PKG_SHORT_ERRORS_SUPPORTED # ----------------------------- AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi[]dnl ])# _PKG_SHORT_ERRORS_SUPPORTED # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], # [ACTION-IF-NOT-FOUND]) # # # Note that if there is a possibility the first call to # PKG_CHECK_MODULES might not happen, you should be sure to include an # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac # # # -------------------------------------------------------------- AC_DEFUN([PKG_CHECK_MODULES], [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no AC_MSG_CHECKING([for $1]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS and $1[]_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details.]) if test $pkg_failed = yes; then _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"` else $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` fi # Put the nasty error message in config.log where it belongs echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD ifelse([$4], , [AC_MSG_ERROR(dnl [Package requirements ($2) were not met: $$1_PKG_ERRORS Consider adjusting the PKG_CONFIG_PATH environment variable if you installed software in a non-standard prefix. _PKG_TEXT ])], [AC_MSG_RESULT([no]) $4]) elif test $pkg_failed = untried; then ifelse([$4], , [AC_MSG_FAILURE(dnl [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. _PKG_TEXT To get pkg-config, see .])], [AC_MSG_RESULT([no]) $4]) else $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) ifelse([$3], , :, [$3]) fi[]dnl ])# PKG_CHECK_MODULES xine-lib-1.2/m4/symbol.m40000644000175000017500000000652314647725152012761 0ustar memednl Macros to check the presence of generic (non-typed) symbols. dnl Copyright (c) 2007 xine project dnl dnl This program is free software; you can redistribute it and/or modify dnl it under the terms of the GNU General Public License as published by dnl the Free Software Foundation; either version 2, or (at your option) dnl any later version. dnl dnl This program is distributed in the hope that it will be useful, dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. dnl dnl You should have received a copy of the GNU General Public License dnl along with this program; if not, write to the Free Software dnl Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA dnl 02110-1301, USA. dnl dnl As a special exception, the xine project, as copyright owner of the dnl macro gives unlimited permission to copy, distribute and modify the dnl configure scripts that are the output of Autoconf when processing the dnl Macro. You need not follow the terms of the GNU General Public dnl License when using or distributing such scripts, even though portions dnl of the text of the Macro appear in them. The GNU General Public dnl License (GPL) does govern all other use of the material that dnl constitutes the Autoconf Macro. dnl dnl This special exception to the GPL applies to versions of the dnl Autoconf Macro released by the xine project. When you make and dnl distribute a modified version of the Autoconf Macro, you may extend dnl this special exception to the GPL to apply to your modified version as dnl well. dnl AC_CHECK_SYMBOL - Check for a single symbol dnl Usage: AC_CHECK_SYMBOL([symbol], [action-if-found], [action-if-not-found]) dnl Default action, defines HAVE_SYMBOL (with symbol capitalised) if the dnl symbol is present at link time. AC_DEFUN([AC_CHECK_SYMBOL], [ AC_CACHE_CHECK([for $1 symbol presence], AS_TR_SH([ac_cv_symbol_$1]), [AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern void *$1;]], [[void *tmp = $1;]])], [eval "AS_TR_SH([ac_cv_symbol_$1])=yes"], [eval "AS_TR_SH([ac_cv_symbol_$1])=no"]) ]) if eval test [x$]AS_TR_SH([ac_cv_symbol_$1]) = xyes; then ifelse([$2], , [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$1]), [1], [Define to 1 if you have the $1 symbol.])], [$2]) else ifelse([$3], , [:], [$3]) fi ]) dnl AC_CHECK_SYMBOLS - Check for multiple symbols dnl Usage: AC_CHECK_SYMBOLS([symbol1 symbol2], [action-if-found], [action-if-not-found]) AC_DEFUN([AC_CHECK_SYMBOLS], [ AH_CHECK_SYMBOLS([$1]) for ac_symbol in $1 do AC_CHECK_SYMBOL($ac_symbol, [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_$ac_symbol])) $2], [$3]) done ]) m4_ifdef([m4_foreach_w], [], [ # m4_foreach_w(VARIABLE, LIST, EXPRESSION) # ---------------------------------------- # # Like m4_foreach, but the list is whitespace separated. # # This macro is robust to active symbols: # m4_foreach_w([Var], [ active # b act\ # ive ], [-Var-])end # => -active--b--active-end # m4_define([m4_foreach_w], [m4_foreach([$1], m4_split(m4_normalize([$2])), [$3])]) m4_define([m4_foreach_w_is_compatibility]) ]) m4_define([AH_CHECK_SYMBOLS], [ m4_foreach_w([AC_Symbol], [$1], [AH_TEMPLATE(AS_TR_CPP([HAVE_]m4_defn([AC_Symbol])), [Define to 1 if you have the ]m4_defn([AC_Symbol])[ symbol.])]) ]) xine-lib-1.2/m4/package.m40000644000175000017500000000720614647725152013046 0ustar memednl _ACX_VERSION_PARSE(version) AC_DEFUN([_ACX_VERSION_PARSE], [`echo $1 | perl -e 'my $v = <>; chomp $v; my @v = split(" ", $v); $v = $v[[@S|@#v]]; $v =~ s/[[^0-9.]].*$//; @v = split (/\./, $v); push @v, 0 while $[#v] < 2; print $v[[0]] * 10000 + $v[[1]] * 100 + $v[[2]], "\n"'`]) dnl ACX_VERSION_CHECK(required, actual) AC_DEFUN([ACX_VERSION_CHECK], [ required_version=ifelse([$1], , [0.0.0], [$1]) required_version_parsed=_ACX_VERSION_PARSE([$required_version]) actual_version=ifelse([$2], , [0.0.0], [$2]) actual_version_parsed=_ACX_VERSION_PARSE([$actual_version]) if test $required_version_parsed -le $actual_version_parsed; then ifelse([$3], , [:], [$3]) else ifelse([$4], , [:], [$4]) fi ]) AC_DEFUN([ASX_TR_LOWER], [m4_translit([[$1]], [ABCDEFGHIJKLMNOPQRSTUVWXYZ], [abcdefghijklmnopqrstuvwxyz])]) dnl ACX_PACKAGE_CHECK(VARIABLE-PREFIX, MINIMUM-VERSION, CONFIG-SCRIPT, dnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) AC_DEFUN([ACX_PACKAGE_CHECK], [ AC_ARG_VAR($1_CONFIG, [Full path to $3]) AC_ARG_WITH(ASX_TR_LOWER([$1][-prefix]), [AS_HELP_STRING(ASX_TR_LOWER([--with-][$1][-prefix])[=PATH], [prefix where $3 is installed (optional)])], [package_config_prefix="$withval"], [package_config_prefix=""]) AC_ARG_WITH(ASX_TR_LOWER([$1][-exec-prefix]), [AS_HELP_STRING(ASX_TR_LOWER([--with-][$1][-exec-prefix])[=PATH], [exec prefix where $3 is installed (optional)])], [package_config_exec_prefix="$withval"], [package_config_exec_prefix=""]) package_config_args="" if test x"$package_config_exec_prefix" != x""; then package_config_args="$package_config_args --exec-prefix=$package_config_exec_prefix" test x"${$1_CONFIG+set}" != x"set" && $1_CONFIG="$package_config_exec_prefix/bin/$3" fi if test x"$package_config_prefix" != x""; then package_config_args="$package_config_args --prefix=$package_config_prefix" test x"${$1_CONFIG+set}" != x"set" && $1_CONFIG="$package_config_prefix/bin/$3" fi min_package_version=ifelse([$2], , [0.0.0], [$2]) AC_PATH_TOOL([$1_CONFIG], [$3], [no]) AC_MSG_CHECKING([for $1 version >= $min_package_version]) if test x"$$1_CONFIG" = x"no"; then AC_MSG_RESULT([unknown]) AC_MSG_NOTICE([The $3 script installed by $1 could not be found. *** If $1 was installed in PREFIX, make sure PREFIX/bin is in your path, or *** set the $1_CONFIG environment variable to the full path to the program.]) else [$1][_CFLAGS]="`$$1_CONFIG $package_config_args --cflags`" [$1][_LIBS]="`$$1_CONFIG $package_config_args --libs`" [$1][_VERSION]="`$$1_CONFIG $package_config_args --version`" ACX_VERSION_CHECK([$min_package_version], [$[$1][_VERSION]], [package_version_ok=yes; AC_MSG_RESULT([yes -- $[$1][_VERSION]])], [[$1][_CFLAGS]="" [$1][_LIBS]=""; AC_MSG_RESULT([no -- $[$1][_VERSION]]) AC_MSG_NOTICE([If you have already installed a sufficiently new version, *** this error probably means that the wrong copy of the $3 *** shell script is being found. The easiest way to fix this is to remove the *** old version, but you can also set the $1_CONFIG environment *** variable to point to the correct copy. In this case, you will have to *** modify your LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf *** so that the correct libraries are found at run-time.])]) fi if test x"$package_version_ok" = x"yes"; then ifelse([$4], , [:], [$4]) else ifelse([$5], , [:], [$5]) fi AC_SUBST([$1][_CFLAGS]) AC_SUBST([$1][_LIBS]) ]) xine-lib-1.2/m4/decoders.m40000644000175000017500000011423514647725152013244 0ustar memednl --------------------------- dnl Decoder and Demuxer Plugins dnl --------------------------- AC_DEFUN([XINE_DECODER_PLUGINS], [ dnl a52dec (optional; enabled by default; external version allowed) AC_ARG_ENABLE([a52dec], [AS_HELP_STRING([--enable-a52dec], [Enable support for a52dec decoding library (default: enabled, internal: use internal copy)])]) if test x"$enable_a52dec" != x"no"; then dnl SIGH. There are 3 major forks of liba52: dnl 1. The original liba52 who stopped development in 2002. dnl 2. Our internal version who adds fixed point mode, warning fixes and avoids writable static data. dnl 3. The VideoLAN version from 2003 who adds pkgconfig file, accelerations, fixed point mode, dnl and an a52_init () with no args. This is found in some distros like OpenSUSE Leap 15.0. AC_ARG_WITH([a52dec-math], AS_HELP_STRING([--with-a52dec-math=float|double|fixed], [Select the type of calculatons an external liba52 does use, or the internal liba52 shall use. Defaults to "float".]), [my_a52dec_math="$withval"], [my_a52dec_math=""]) A52DEC_MATH="" test x"$my_a52dec_math" = x"fixed" && A52DEC_MATH="-DLIBA52_FIXED" test x"$my_a52dec_math" = x"double" && A52DEC_MATH="-DLIBA52_DOUBLE" have_external_a52dec="no" a52_libname="MY_SHARED_LIB_NAME([a52])" if test x"$enable_a52dec" != x"internal" ; then dnl Try to get A52DEC_CFLAGS like -DA52_FIXED A52DEC_CFLAGS='' A52DEC_LIBS='' PKG_CHECK_MODULES([A52DEC], [liba52], [have_external_a52dec="yes"], [have_external_a52dec="no"]) dnl Always test for _shared_ lib. AC_CHECK_LIB([$a52_libname], [a52_init], [AC_CHECK_HEADERS([a52dec/a52.h], [have_external_a52dec="yes"], [have_external_a52dec="no"], [ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #include ])], [have_external_a52dec="no"], [-lm]) if test x"$have_external_a52dec" = x"no"; then AC_MSG_RESULT([*** no usable version of a52dec found, using internal copy ***]) fi else AC_MSG_RESULT([Using included a52dec support]) fi if test x"$have_external_a52dec" = x"yes"; then A52DEC_DEPS='' test x"$A52DEC_LIBS" = x"" && A52DEC_LIBS=-l"$a52_libname" dnl a52_init (uint32_t mm_accel) went a52_init (void) somewhen. AC_MSG_CHECKING([whether a52_init takes no args]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #include ]],[[ a52_init (); ]])], [have_a52_init_void=yes], [have_a52_init_void=no]) AC_MSG_RESULT([$have_a52_init_void]) test x"$have_a52_init_void" = x"yes" && AC_DEFINE([HAVE_A52_INIT_VOID], [1], [Define to 1 if a52_init () takes no args.]) else A52DEC_CFLAGS='-I$(top_srcdir)/contrib/a52dec' A52DEC_LIBS='$(top_builddir)/contrib/a52dec/liba52.la' A52DEC_DEPS='$(top_builddir)/contrib/a52dec/liba52.la' fi AC_SUBST(A52DEC_MATH) AC_SUBST(A52DEC_CFLAGS) AC_SUBST(A52DEC_DEPS) AC_SUBST(A52DEC_LIBS) fi AM_CONDITIONAL([ENABLE_A52DEC], [test x"$enable_a52dec" != x"no"]) AM_CONDITIONAL([WITH_EXTERNAL_A52DEC], [test x"$have_external_a52dec" = x"yes"]) dnl ASF (optional; enabled by default) AC_ARG_ENABLE([asf], [AS_HELP_STRING([--enable-asf], [Enable support for ASF demuxer (default: enabled)])], [test x"$enableval" != x"no" && enable_asf="yes"]) AM_CONDITIONAL([ENABLE_ASF], [test x"$enable_asf" != x"no"]) dnl Nosefart (optional, enabled by default) AC_ARG_ENABLE([nosefart], [AS_HELP_STRING([--enable-nosefart], [Enable support for nosefart player (default: enabled)])], [test x"$enableval" != x"no" && enable_nosefart="yes"]) AM_CONDITIONAL([ENABLE_NOSEFART], [test "x$enable_nosefart" != "xno"]) dnl FAAD (optional; enabled by default) AC_ARG_ENABLE([faad], [AS_HELP_STRING([--enable-faad], [Enable support for FAAD decoder (default: enabled, internal: use internal copy)])]) if test x"$enable_faad" != x"no"; then if test x"$enable_faad" != x"internal"; then AC_CHECK_LIB([faad], [NeAACDecInit], [AC_CHECK_HEADERS([neaacdec.h], [have_external_faad=yes], [have_external_faad=no], [#include ])], [have_external_faad=no], [-lm]) if test x"$have_external_faad" = x"no"; then AC_MSG_RESULT([*** no usable version of libfaad found, using internal copy ***]) fi else AC_MSG_RESULT([Using included libfaad support]) fi if test x"$have_external_faad" = x"yes"; then FAAD_CFLAGS='' FAAD_LIBS='-lfaad' FAAD_DEPS='' else FAAD_CFLAGS='-I$(top_srcdir)/contrib/libfaad' FAAD_LIBS='$(top_builddir)/contrib/libfaad/libfaad.la' FAAD_DEPS='$(top_builddir)/contrib/libfaad/libfaad.la' fi AC_SUBST(FAAD_CFLAGS) AC_SUBST(FAAD_DEPS) AC_SUBST(FAAD_LIBS) fi AM_CONDITIONAL([ENABLE_FAAD], [test x"$enable_faad" != x"no"]) AM_CONDITIONAL([WITH_EXTERNAL_FAAD], [test x"$have_external_faad" = x"yes"]) dnl ffmpeg (optional, enabled by default) dnl this also affects dxr3 AC_ARG_ENABLE([ffmpeg], [AS_HELP_STRING([--disable-ffmpeg], [Disable support for FFmpeg decoders (default: enabled)])]) if test x"$enable_ffmpeg" != x"no" ; then PKG_CHECK_MODULES([FFMPEG], [libavcodec >= 51.68.0], [], [enable_ffmpeg=no]) PKG_CHECK_MODULES([AVUTIL], [libavutil >= 49.6.0], [], [enable_ffmpeg=no]) if test x"$enable_ffmpeg" != x"no" ; then AC_DEFINE([HAVE_FFMPEG], 1, [Define this if you have the ffmpeg library]) dnl Check presence of ffmpeg/avutil.h to see if it's old or new dnl style for headers. The new style would be preferred actually... dnl Sigh. at least some 09/2022 ffmpeg version does violate the basic dnl "get directly what you use directly" rule. especially, dnl libavformat/avformat.h includes libavcodec/packet.h which uses dnl (but not includes) libavutil/avutil.h. this means that a mere dnl AC_CHECK_HEADERS([libavformat/avformat.h]) will fail strangely :-/ ac_save_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $FFMPEG_CFLAGS" ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CFLAGS $FFMPEG_CFLAGS $AVUTIL_CFLAGS" AC_CHECK_HEADERS([ffmpeg/avutil.h libavutil/avutil.h libavutil/sha1.h libavutil/mem.h libavutil/sha.h]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include ]],[[]])], [have_avutil_avcodec_h=yes], [have_avutil_avcodec_h=no]) test x"$have_avutil_avcodec_h" == x"yes" && AC_DEFINE([HAVE_AVUTIL_AVCODEC_H],[1], [Define this if you have libavutil/avutil.h and libavcodec/avcodec.h.]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]],[[]])], [have_avformat_avformat_h=yes], [have_avformat_avformat_h=no]) test x"$have_avformat_avformat_h" == x"yes" && AC_DEFINE([HAVE_AVFORMAT_AVFORMAT_H],[1], [Define this if you have libavformat/avformat.h.]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include #include #include #include ]],[[]])], [have_avformat_avio_h=yes], [have_avformat_avio_h=no]) test x"$have_avformat_avio_h" == x"yes" && AC_DEFINE([HAVE_AVFORMAT_AVIO_H],[1], [Define this if you have libavformat/avformat.h.]) if test "$ac_cv_header_ffmpeg_avutil_h" = "yes" && test "$ac_cv_header_libavutil_avutil_h" = "yes"; then AC_MSG_ERROR([old & new ffmpeg headers found - you need to clean up!]) fi CPPFLAGS="$ac_save_CPPFLAGS" CFLAGS="$ac_save_CFLAGS" else AC_MSG_WARN([*** no suitable FFmpeg found, disabling ffmpeg / vaapi / dxr3 ***]) fi fi AM_CONDITIONAL([ENABLE_FFMPEG], [test x"$enable_ffmpeg" != x"no"]) dnl postproc (optional, enabled by default) AC_ARG_ENABLE([postproc], [AS_HELP_STRING([--disable-postproc], [Disable support for libpostproc video filtering (default: enabled)])]) if test x"$enable_postproc" != x"no" ; then PKG_CHECK_MODULES([POSTPROC], [libpostproc >= 51.2.0], [], [enable_postproc=no]) if test x"$enable_postproc" != x"no" ; then AC_DEFINE([HAVE_POSTPROC], 1, [Define this if you have the postproc library]) else AC_MSG_WARN([*** no suitable libpostproc found, disabling ffmpeg / vaapi / post:pp ***]) fi fi AM_CONDITIONAL([ENABLE_POSTPROC], [test x"$enable_postproc" != x"no"]) dnl gdk-pixbuf (optional; enabled by default) AC_ARG_ENABLE([gdkpixbuf], [AS_HELP_STRING([--enable-gdkpixbuf], [Enable GdkPixbuf support (default: enabled)])], [test x"$enableval" != x"no" && enable_gdkpixbuf="yes"]) if test x"$enable_gdkpixbuf" != x"no"; then PKG_CHECK_MODULES([GDK_PIXBUF], [gdk-pixbuf-2.0], [have_gdkpixbuf=yes], [have_gdkpixbuf=no]) if test x"$enable_gdkpixbuf" = x"yes" && test x"$have_gdkpixbuf" != x"yes"; then AC_MSG_ERROR([GdkPixbuf support requested, but GdkPixbuf not found]) fi fi AM_CONDITIONAL([ENABLE_GDK_PIXBUF], [test x"$have_gdkpixbuf" = x"yes"]) test x"$have_gdkpixbuf" = x"yes" && AC_DEFINE([HAVE_GDK_PIXBUF], [1], [Define to 1 if you have gdkpixbuf.]) dnl libjpeg (optional; enabled by default) AC_ARG_ENABLE([libjpeg], [AS_HELP_STRING([--enable-libjpeg], [Enable libjpeg support (default: enabled)])], [test x"$enableval" != x"no" && enable_libjpeg="yes"]) if test x"$enable_libjpeg" != x"no"; then AC_CHECK_LIB([jpeg], [jpeg_start_decompress], [AC_CHECK_HEADERS([jpeglib.h], [have_libjpeg=yes], [have_libjpeg=no])], [have_libjpeg=no]) if test x"$enable_libjpeg" = x"yes" && test x"$have_libjpeg" != x"yes"; then AC_MSG_ERROR([libjpeg support requested, but libjpeg not found]) elif test x"$have_libjpeg" = x"yes"; then JPEG_LIBS="-ljpeg" AC_SUBST(JPEG_LIBS) fi fi AM_CONDITIONAL([ENABLE_LIBJPEG], [test x"$have_libjpeg" = x"yes"]) test x"$have_libjpeg" = x"yes" && AC_DEFINE([HAVE_LIBJPEG], [1], [Define to 1 if you have libjpg.]) dnl libpng (optional; enabled by default) AC_ARG_ENABLE([libpng], [AS_HELP_STRING([--enable-libpng], [Enable libpng support (default: enabled)])], [test x"$enableval" != x"no" && enable_libpng="yes"]) if test x"$enable_libpng" != x"no"; then PKG_CHECK_MODULES([LIBPNG], [libpng >= 1.6.0], [have_libpng=yes], [have_libpng=no]) if test x"$enable_libpng" = x"yes" && test x"$have_libpng" != x"yes"; then AC_MSG_ERROR([libpng support requested, but libpng not found]) fi fi AM_CONDITIONAL([ENABLE_LIBPNG], [test x"$have_libpng" = x"yes"]) test x"$have_libpng" = x"yes" && AC_DEFINE([HAVE_LIBPNG], [1], [Define to 1 if you have libpng.]) dnl ImageMagick (optional; enabled by default) AC_ARG_WITH([imagemagick], [AS_HELP_STRING([--with-imagemagick], [Enable ImageMagick image decoder support (default: enabled)])], [test x"$withval" != x"no" && with_imagemagick="yes"]) if test x"$with_imagemagick" != x"no"; then PKG_CHECK_MODULES([WAND], [Wand], [have_imagemagick=yes], [have_imagemagick=no]) if test "x$have_imagemagick" = 'xno'; then PKG_CHECK_MODULES([MAGICKWAND], [MagickWand], [have_imagemagick=yes], [have_imagemagick=no]) dnl Avoid $(WAND_FLAGS) $(MAGICKWAND_FLAGS) ... WAND_CFLAGS="$MAGICKWAND_CFLAGS" WAND_LIBS="$MAGICKWAND_LIBS" fi if test "x$have_imagemagick" = 'xno'; then PKG_CHECK_MODULES([GRAPHICSMAGICK], [ImageMagick], [have_imagemagick=yes], [have_imagemagick=no]) PKG_CHECK_MODULES([GRAPHICSMAGICKWAND], [GraphicsMagickWand], [have_imagemagick=yes], [have_imagemagick=no]) dnl The following assignments are safe, since they include dnl the flags for plain GraphicsMagick WAND_CFLAGS="$GRAPHICSMAGICKWAND_CFLAGS" WAND_LIBS="$GRAPHICSMAGICKWAND_LIBS" AC_DEFINE([HAVE_GRAPHICSMAGICK], [1], [Define this if you have GraphicsMagick installed]) fi if test x"$with_imagemagick" = x"yes" && test x"$have_imagemagick" = x"no"; then AC_MSG_ERROR([ImageMagick support requested, but neither Wand, MagickWand, nor GraphicsMagick were found]) fi dnl header was changed in ImageMagick 7+ ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $WAND_CFLAGS" AC_CHECK_HEADERS([MagickWand/MagickWand.h]) dnl ImageMagick 7+ AC_CHECK_HEADERS([wand/magick_wand.h]) dnl ImageMagick <7 CPPFLAGS="$ac_save_CPPFLAGS" fi AM_CONDITIONAL([ENABLE_IMAGEMAGICK], [test x"$have_imagemagick" = x"yes"]) test x"$have_imagemagick" = x"yes" && AC_DEFINE([HAVE_IMAGEMAGICK], [1], [Define to 1 if you have ImageMagick.]) dnl libdts (optional; enabled by default; external version allowed) AC_ARG_ENABLE([dts], [AS_HELP_STRING([--enable-dts], [Enable support for DTS decoding library (default: enabled, internal: use internal copy)])]) if test x"$enable_dts" != x"no"; then if test x"$enable_dts" != x"internal"; then PKG_CHECK_MODULES([LIBDTS], [libdts], [have_external_dts=yes], [have_external_dts=no]) if test x"$have_external_dts" != x"yes"; then AC_MSG_RESULT([*** no usable version of libdts found, using internal copy ***]) fi else AC_MSG_RESULT([Using included libdts support]) fi if test x"$have_external_dts" != x"yes"; then LIBDTS_CFLAGS='-I$(top_srcdir)/contrib/libdca/include' LIBDTS_DEPS='$(top_builddir)/contrib/libdca/libdca.la' LIBDTS_LIBS='$(top_builddir)/contrib/libdca/libdca.la' AC_SUBST(LIBDTS_DEPS) fi fi AM_CONDITIONAL([ENABLE_DTS], [test x"$enable_dts" != x"no"]) AM_CONDITIONAL([WITH_EXTERNAL_LIBDTS], [test x"$have_external_dts" = x"yes"]) dnl libFLAC (optional; enabled by default) AC_ARG_WITH([libflac], [AS_HELP_STRING([--with-libflac], [build libFLAC-based decoder and demuxer (default: enabled)])], [test x"$withval" != x"no" && with_libflac="yes"]) AC_ARG_WITH([libFLAC-prefix], [AS_HELP_STRING([--with-libFLAC-prefix=DIR], [prefix where libFLAC is installed (optional)])]) AC_ARG_WITH([libFLAC-libraries], [AS_HELP_STRING([--with-libFLAC-libraries=DIR], [directory where libFLAC library is installed (optional)])]) AC_ARG_WITH([libFLAC-includes], [AS_HELP_STRING([--with-libFLAC-includes=DIR], [directory where libFLAC header files are installed (optional)])]) if test x"$with_libflac" != x"no"; then AC_MSG_CHECKING([libdir name]) case "$host_or_hostalias" in *-*-linux*) # Test if the compiler is 64bit echo 'int i;' > conftest.$ac_ext xine_cv_cc_64bit_output=no if AC_TRY_EVAL(ac_compile); then case `"$MAGIC_CMD" conftest.$ac_objext` in *"ELF 64"*) xine_cv_cc_64bit_output=yes ;; esac fi rm -rf conftest* ;; esac case "$host_cpu:$xine_cv_cc_64bit_output" in powerpc64:yes | s390x:yes | sparc64:yes | x86_64:yes) XINE_LIBDIRNAME="lib64" ;; *:*) XINE_LIBDIRNAME="lib" ;; esac AC_MSG_RESULT([$XINE_LIBDIRNAME]) dnl try to get automatic defaults, and dont abort when failing. dnl we need to do this before setting LIBFLAC_LIBS manually, or it will always succeed. PKG_CHECK_MODULES([LIBFLAC], [flac], [have_libflac=yes], [have_libflac=no]) dnl user overrides if test x"$with_libFLAC_includes" != x""; then have_libflac=user LIBFLAC_CFLAGS="-I$with_libFLAC_includes" elif test x"$with_libFLAC_prefix" != x""; then have_libflac=user LIBFLAC_CFLAGS="-I$with_libFLAC_prefix/include" elif test x"$have_libflac" != x"yes" -a x"$prefix" != x"NONE"; then have_libflac=user LIBFLAC_CFLAGS="-I$prefix/include" fi if test x"$with_libFLAC_libraries" != x""; then have_libflac=user LIBFLAC_LIBS="-L$with_libFLAC_libraries" elif test x"$with_libFLAC_prefix" != x""; then have_libflac=user LIBFLAC_LIBS="-L$with_libFLAC_prefix/$XINE_LIBDIRNAME" elif test x"$have_libflac" != x"yes" -a x"$prefix" != x"NONE"; then have_libflac=user LIBFLAC_LIBS="-L$prefix/$XINE_LIBDIRNAME" fi dnl now test for usability if test x"have_libflac" = x"user" ; then ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $LIBFLAC_CFLAGS" AC_CHECK_LIB([FLAC], [FLAC__stream_decoder_new], [AC_CHECK_HEADERS([FLAC/stream_decoder.h], [have_libflac=yes LIBFLAC_LIBS="$LIBFLAC_LIBS -lFLAC -lm"], [have_libflac=no])], [have_libflac=no], [-lm]) CPPFLAGS="$ac_save_CPPFLAGS" fi if test x"$with_libflac" = x"yes" && test x"$have_libflac" != x"yes"; then AC_MSG_WARN([libFLAC-based decoder support requested, but libFLAC not found]) elif test x"$have_libflac" != x"yes"; then LIBFLAC_CFLAGS="" LIBFLAC_LIBS="" fi AC_SUBST(LIBFLAC_CFLAGS) AC_SUBST(LIBFLAC_LIBS) fi AM_CONDITIONAL([ENABLE_LIBFLAC], [test x"$have_libflac" = x"yes"]) dnl libmad (optional; enabled by default; external version allowed) AC_ARG_ENABLE([mad], [AS_HELP_STRING([--enable-mad], [Enable support for MAD decoding library (default: enabled, internal: use external copy)])]) if test x"$enable_mad" != x"no"; then if test x"$enable_mad" != x"internal"; then PKG_CHECK_MODULES([LIBMAD], [mad], [AC_CHECK_HEADERS([mad.h], [have_external_libmad=yes], [have_external_libmad=no])], [have_external_libmad=no]) if test x"$have_external_libmad" != x"yes"; then AC_MSG_RESULT([*** no usable version of libmad found, using internal copy ***]) fi else AC_MSG_RESULT([Using included libmad support]) fi if test x"$have_external_libmad" != x"yes"; then case "$host_or_hostalias" in i?86-* | k?-* | athlon-* | pentium*-) AC_DEFINE([FPM_INTEL], 1, [Define to select libmad fixed point arithmetic implementation]) ;; x86_64-*) AC_DEFINE([FPM_64BIT], 1, [Define to select libmad fixed point arithmetic implementation]) ;; ppc-* | powerpc-*) AC_DEFINE([FPM_PPC], 1, [Define to select libmad fixed point arithmetic implementation]) ;; sparc*-*) if test "$GCC" = yes; then AC_DEFINE([FPM_SPARC], 1, [Define to select libmad fixed point arithmetic implementation]) else AC_DEFINE([FPM_64BIT], 1, [Define to select libmad fixed point arithmetic implementation]) fi ;; mips-*) AC_DEFINE([FPM_MIPS], 1, [Define to select libmad fixed point arithmetic implementation]) ;; alphaev56-* | alpha* | ia64-* | hppa*-linux-*) AC_DEFINE([FPM_64BIT], 1, [Define to select libmad fixed point arithmetic implementation]) ;; arm*-*) AC_DEFINE([FPM_ARM], 1, [Define to select libmad fixed point arithmetic implementation]) ;; universal-*) ;; *) AC_DEFINE([FPM_DEFAULT], 1, [Define to select libmad fixed point arithmetic implementation]) ;; esac LIBMAD_CFLAGS='-I$(top_srcdir)/contrib/libmad' LIBMAD_LIBS='$(top_builddir)/contrib/libmad/libmad.la' LIBMAD_DEPS='$(top_builddir)/contrib/libmad/libmad.la' fi AC_SUBST(LIBMAD_CFLAGS) AC_SUBST(LIBMAD_DEPS) AC_SUBST(LIBMAD_LIBS) fi AM_CONDITIONAL([ENABLE_MAD], [test x"$enable_mad" != x"no"]) AM_CONDITIONAL([WITH_EXTERNAL_MAD], [test x"$have_external_libmad" = x"yes"]) dnl libmodplug (optional; enabled by default) AC_ARG_ENABLE([modplug], [AS_HELP_STRING([--enable-modplug], [Enable MODPlug support (default: enabled)])], [test x"$enableval" != x"no" && enable_modplug="yes"]) if test x"$enable_modplug" != x"no"; then PKG_CHECK_MODULES([LIBMODPLUG], [libmodplug >= 0.7], [have_modplug=yes], [have_modplug=no]) if test x"$enable_modplug" = x"yes" && test x"$have_modplug" != x"yes"; then AC_MSG_ERROR([MODPlug support requested, but MODPlug not found]) fi if test "`"$PKG_CONFIG" --modversion libmodplug`" = 0.8.8; then AC_MSG_ERROR([you have a broken version of libmodplug (0.8.8); cowardly refusing to use it]) fi fi AM_CONDITIONAL([ENABLE_MODPLUG], [test x"$have_modplug" = x"yes"]) dnl raw video (rgb, yuv, ...) (optional; enabled by default) AC_ARG_ENABLE([rawvideo], AS_HELP_STRING([--disable-rawvideo], [disable internal raw video decoders])) AM_CONDITIONAL([ENABLE_RAWVIDEO], [test x"$enable_rawvideo" != x"no"]) dnl libmpeg2 (optional; enabled by default) AC_ARG_ENABLE([libmpeg2], AS_HELP_STRING([--disable-libmpeg2], [disable internal libmpeg2 decoder])) AM_CONDITIONAL([ENABLE_LIBMPEG2], [test x"$enable_libmpeg2" != x"no"]) dnl gsm610 (optional; enabled by default) AC_ARG_ENABLE([gsm610], AS_HELP_STRING([--disable-gsm610], [disable internal GSM 06.10 decoder])) AM_CONDITIONAL([ENABLE_GSM610], [test x"$enable_gsm610" != x"no"]) dnl lpcm (optional; enabled by default) AC_ARG_ENABLE([lpcm], AS_HELP_STRING([--disable-lpcm], [disable internal LPCM decoder])) AM_CONDITIONAL([ENABLE_LPCM], [test x"$enable_lpcm" != x"no"]) dnl dvaudio (optional; enabled by default) AC_ARG_ENABLE([dvaudio], AS_HELP_STRING([--disable-dvaudio], [disable internal dvaudio decoder])) AM_CONDITIONAL([ENABLE_DVAUDIO], [test x"$enable_dvaudio" != x"no"]) dnl libmpeg2new (optional; disabled by default) AC_ARG_ENABLE([libmpeg2new], AS_HELP_STRING([--enable-libmpeg2new], [build the newer MPEG2 decoder (buggy)])) AM_CONDITIONAL([ENABLE_MPEG2NEW], [test "x$enable_libmpeg2new" = "xyes"]) dnl libmpcdec (optional; enabled by default; external version allowed) AC_ARG_ENABLE([musepack], [AS_HELP_STRING([--enable-musepack], [Enable support for Musepack decoding (default: enabled, internal: use external copy)])]) if test x"$enable_musepack" != x"no"; then if test x"$enable_musepack" != x"internal"; then AC_CHECK_LIB([mpcdec], [mpc_demux_decode], [AC_CHECK_HEADERS([mpc/mpcdec.h], [have_external_libmpcdec=yes], [have_external_libmpcdec=no])], [AC_CHECK_LIB([mpcdec], [mpc_decoder_decode], [AC_CHECK_HEADERS([mpcdec/mpcdec.h], [have_external_libmpcdec=yes], [have_external_libmpcdec=no])], [have_external_libmpcdec=no], [-lm])], [-lm]) if test x"$have_external_libmpcdec" != x"yes"; then AC_MSG_RESULT([*** no usable version of libmpcdec found, using internal copy ***]) else MPCDEC_CFLAGS="" MPCDEC_DEPS="" MPCDEC_LIBS="-lmpcdec" fi else AC_MSG_RESULT([Using included libmpcdec (Musepack)]) fi if test x"$have_external_libmpcdec" != x"yes"; then MPCDEC_CFLAGS='-I$(top_srcdir)/contrib/libmpcdec' MPCDEC_LIBS='$(top_builddir)/contrib/libmpcdec/libmpcdec.la' MPCDEC_DEPS='$(top_builddir)/contrib/libmpcdec/libmpcdec.la' fi AC_SUBST(MPCDEC_CFLAGS) AC_SUBST(MPCDEC_DEPS) AC_SUBST(MPCDEC_LIBS) fi AM_CONDITIONAL([ENABLE_MUSEPACK], [test x"$enable_musepack" != x"no"]) AM_CONDITIONAL([WITH_EXTERNAL_LIBMPCDEC], [test x"$have_external_libmpcdec" = x"yes"]) dnl mlib AC_ARG_ENABLE([mlib], [AS_HELP_STRING([--enable-mlib], [build Sun mediaLib support (default: disabled)])], [test x"$enableval" != x"no" && enable_mlib="yes"], [enable_lib="no"]) AC_ARG_ENABLE([mlib-lazyload], [AS_HELP_STRING([--enable-mlib-lazyload], [check for Sun mediaLib at runtime])], [test x"$enableval" != x"no" && enable_mlib_lazyload="yes"], [enable_mlib_lazyload="no"]) if test x"$enable_mlib" != x"no"; then mlibhome="$MLIBHOME" test x"$mlibhome" = x"" && mlibhome="/opt/SUNWmlib" AC_CHECK_LIB([mlib], [mlib_VideoAddBlock_U8_S16], [saved_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I$mlibhome/include" AC_CHECK_HEADERS([mlib_video.h], [if test x"$enable_mlib_lazyload" != x"no"; then if test "$GCC" = yes; then MLIB_LIBS="-L$mlibhome/lib -Wl,-z,lazyload,-lmlib,-z,nolazyload" else MLIB_LIBS="-L$mlibhome/lib -z lazyload -lmlib -z nolazyload" fi AC_DEFINE([MLIB_LAZYLOAD], 1, [Define this if you want to load mlib lazily]) else MLIB_LIBS="-L$mlibhome/lib -lmlib" fi MLIB_CFLAGS="-I$mlibhome/include" AC_SUBST(MLIB_LIBS) AC_SUBST(MLIB_CFLAGS) dnl TODO: src/video_out/yuv2rgb.c and src/xine-utils/cpu_accel.c should be changed to use LIBMPEG2_MLIB dnl and HAVE_MLIB should go away. AC_DEFINE([HAVE_MLIB], 1, [Define this if you have mlib installed]) AC_DEFINE([LIBMPEG2_MLIB], 1, [Define this if you have mlib installed]) have_mlib=yes]) CPPFLAGS="$saved_CPPFLAGS"], [], ["-L$mlibhome/lib"]) fi AM_CONDITIONAL([HAVE_MLIB], [test x"$have_mlib" = x"yes"]) dnl mng (optional; enabled by default) AC_ARG_ENABLE([mng], [AS_HELP_STRING([--enable-mng], [Enable MNG decoder support (default: enabled)])], [test x"$enableval" != x"no" && enable_mng="yes"]) if test x"$enable_mng" != x"no"; then AC_CHECK_LIB([mng], [mng_initialize], [AC_CHECK_HEADERS([libmng.h], [have_mng=yes], [have_mng=no])], [have_mng=no]) if test x"$enable_mng" = x"yes" && test x"$have_mng" != x"yes"; then AC_MSG_ERROR([MNG support requested, but libmng not found]) elif test x"$have_mng" = x"yes"; then MNG_LIBS="-lmng" AC_SUBST(MNG_LIBS) fi fi AM_CONDITIONAL([ENABLE_MNG], [test x"$have_mng" = x"yes"]) dnl Ogg/Speex (optional; enabled by default; external) AC_ARG_WITH([speex], [AS_HELP_STRING([--with-speex], [Enable Speex audio decoder support (default: enabled)])], [], [with_speex="try"]) if test x"$with_speex" != x"no"; then PKG_CHECK_MODULES([SPEEX], [ogg speex], [with_speex=yes], [test x"$with_speex" = x"yes" && with_speex=fail]) if test x"$with_speex" = x"fail" ; then AC_MSG_ERROR([Speex support requested, but libspeex and/or libogg not found]) fi fi test x"$with_speex" = x"yes" && AC_DEFINE([HAVE_SPEEX], 1, [Define this if you have speex]) AM_CONDITIONAL([ENABLE_SPEEX], [test x"$with_speex" = x"yes"]) dnl Ogg/Theora (optional; enabled by default; external) AC_ARG_WITH([theora], [AS_HELP_STRING([--with-theora], [Enable Theora video decoder support (default: enabled)])], [], [with_theora="try"]) if test x"$with_theora" != x"no"; then PKG_CHECK_MODULES([THEORA], [ogg theora], [with_theora=yes], [test x"$with_theora" = x"yes" && with_theora=fail]) if test x"$with_theora" = x"fail" ; then AC_MSG_ERROR([Theora support requested, but libtheora and/or libogg not found]) fi fi test x"$with_theora" = x"yes" && AC_DEFINE([HAVE_THEORA], 1, [Define this if you have theora]) AM_CONDITIONAL([ENABLE_THEORA], [test x"$with_theora" = x"yes"]) dnl Ogg/Vorbis (optional; enabled by default; external) AC_ARG_WITH([vorbis], [AS_HELP_STRING([--with-vorbis], [Enable Vorbis audio decoder support (default: enabled)])], [], [with_vorbis="try"]) if test x"$with_vorbis" != x"no" ; then PKG_CHECK_MODULES([VORBIS], [ogg vorbis], [with_vorbis=yes], [test x"$with_vorbis" = x"yes" && with_vorbis=fail]) if test x"$with_vorbis" = x"fail" ; then AC_MSG_ERROR([Vorbis support requested, but libvorbis and/or libogg not found]) fi fi test x"$with_vorbis" = x"yes" && AC_DEFINE([HAVE_VORBIS], 1, [Define this if you have vorbis]) AM_CONDITIONAL([ENABLE_VORBIS], [test x"$with_vorbis" = x"yes"]) dnl real (optional; enabled by default) dnl On some systems, we cannot enable Real codecs support to begin with. dnl This includes Darwin, because it uses Mach-O rather than ELF. AC_ARG_ENABLE([real-codecs], [AS_HELP_STRING([--enable-real-codecs], [Enable Real binary codecs support (default: enabled)])], [test x"$enableval" != x"no" && enable_real_codecs="yes"]) AC_ARG_WITH([real-codecs-path], [AS_HELP_STRING([--with-real-codecs-path=PATH], [Specify directory for Real binary codecs])]) if test x"$enable_real_codecs" != x"no"; then case "$host_os" in darwin*) have_real_codecs=no ;; *) have_real_codecs=yes dnl For those that have a replacement, break at the first one found AC_CHECK_SYMBOLS([__environ _environ environ], [break], [need_weak_aliases=yes]) AC_CHECK_SYMBOLS([stderr __stderrp], [break], [need_weak_aliases=yes]) dnl For these there are no replacements AC_CHECK_SYMBOLS([___brk_addr __ctype_b]) if test x"$need_weak_aliases" = x"yes"; then CC_ATTRIBUTE_ALIAS([], [have_real_codecs=no]) fi ;; esac if test x"$enable_real_codecs" = x"yes" && test x"$have_real_codecs" != x"yes"; then AC_MSG_ERROR([Binary Real codec support requested, but it is not available]) elif test x"$have_real_codecs" = x"yes"; then if test "${with_real_codecs_path+set}" = "set"; then AC_DEFINE_UNQUOTED([REAL_CODEC_PATH], ["$with_real_codecs_path"], [Default path in which to find Real binary codecs]) fi fi fi AM_CONDITIONAL([ENABLE_REAL], [test x"$have_real_codecs" = x"yes"]) dnl w32dll (optional; x86 only; enabled if using GNU as; GNU as required) AC_ARG_ENABLE([w32dll], [AS_HELP_STRING([--enable-w32dll], [Enable Win32 DLL support (default: enabled)])], [test x"$enableval" != x"no" && enable_w32dll="yes"], [test x"$with_gnu_as" != x"yes" && enable_w32dll="no"]) AC_ARG_WITH([w32-path], [AS_HELP_STRING([--with-w32-path=PATH], [location of Win32 binary codecs])], [w32_path="$withval"], [w32_path="/usr/lib/codecs"]) if test x"$enable_w32dll" != x"no"; then case "$host_or_hostalias" in *-mingw* | *-cygwin) have_w32dll=no ;; i?86-* | k?-* | athlon-* | pentium*-) have_w32dll="$with_gnu_as" ;; *) enable_w32dll=no ;; esac if test x"$enable_w32dll" = x"yes" && test x"$have_w32dll" != x"yes"; then AC_MSG_ERROR([Win32 DLL support requested, but Win32 DLL support is not available]) fi fi AC_SUBST(w32_path) AM_CONDITIONAL([ENABLE_W32DLL], [test x"$have_w32dll" = x"yes"]) dnl wavpack (optional; disabled by default) AC_ARG_WITH([wavpack], [AS_HELP_STRING([--with-wavpack], [Enable Wavpack decoder (requires libwavpack)])], [], [with_wavpack="no"]) if test x"$with_wavpack" = x"yes"; then PKG_CHECK_MODULES([WAVPACK], [wavpack], [], [with_wavpack=fail]) if test x"$with_wavpack" = x"fail" ; then AC_MSG_ERROR([Wavpack decoder support requested, but libwavpack not found]) fi fi AM_CONDITIONAL([ENABLE_WAVPACK], [test x"$with_wavpack" = x"yes"]) dnl libvpx decoder plugin AC_ARG_ENABLE([vpx], [AS_HELP_STRING([--enable-vpx], [Enable libvpx VP8/VP9 decoder support (default: enabled)])], [test x"$enableval" != x"no" && enable_vpx="yes"]) if test x"$enable_vpx" != x"no"; then PKG_CHECK_MODULES([VPX], [vpx] , [have_vpx=yes], [have_vpx=no]) if test x"$enable_vpx" = x"yes" && test x"$have_vpx" != x"yes"; then AC_MSG_ERROR([VP8/VP9 support requested, but libvpx not found]) fi AC_CHECK_LIB([vpx],[vpx_codec_vp9_dx], [ AC_DEFINE([HAVE_VPX_VP9_DECODER], 1, [Define this if you have VP9 support in libvpx]) ], [], [${VPX_LIBS}]) fi AM_CONDITIONAL([ENABLE_VPX], [test x"$have_vpx" = x"yes"]) dnl libOpenHevc decoder plugin AC_ARG_WITH([openhevc], [AS_HELP_STRING([--with-openhevc], [Enable libOpenHevc HEVC decoder support (default: enabled)])], [], [with_openhevc="try"]) if test x"$with_openhevc" != x"no"; then AC_CHECK_LIB([LibOpenHevcWrapper], [libOpenHevcInit], [], [test x"$with_openhevc" = x"yes" && with_openhevc=fail]) if test x"$with_openhevc" = x"fail" ; then AC_MSG_ERROR([openhevc support requested, but LibOpenHevcWrapper not found]) else AC_CHECK_HEADERS([openHevcWrapper.h], [with_openhevc=yes], [test x"$with_openhevc" = x"yes" && with_openhevc=fail]) if test x"$with_openhevc" = x"fail" ; then AC_MSG_ERROR([openhevc support requested, but openHevcWrapper.h not found]) fi fi fi if test x"$with_openhevc" = x"yes" ; then OPENHEVC_CFLAGS='' OPENHEVC_LIBS='-lLibOpenHevcWrapper' AC_SUBST(OPENHEVC_CFLAGS) AC_SUBST(OPENHEVC_LIBS) fi AM_CONDITIONAL([ENABLE_OPENHEVC], [test x"$with_openhevc" = x"yes"]) dnl libaom AV1 decoder plugin AC_ARG_WITH([libaom], [AS_HELP_STRING([--with-libaom], [Enable libaom AV1 decoder support (default: enabled)])], [], [with_libaom="try"]) if test x"$with_libaom" != x"no"; then PKG_CHECK_MODULES([AOM], [aom >= 1.0] , [with_libaom=yes], [test x"$with_libaom" = x"yes" && with_libaom=fail]) if test x"$with_libaom" = x"fail" ; then AC_MSG_ERROR([libaom AV1 support requested, but libaom not found]) fi fi AM_CONDITIONAL([ENABLE_LIBAOM], [test x"$with_libaom" = x"yes"]) dnl dav1d AV1 decoder plugin AC_ARG_WITH([dav1d], [AS_HELP_STRING([--with-dav1d], [Enable dav1d AV1 decoder support (default: enabled)])], [], [with_dav1d=try]) if test x"$with_dav1d" != x"no"; then PKG_CHECK_MODULES([DAV1D], [dav1d >= 0.3.1] , [with_dav1d=yes], [test x"$with_dav1d" = x"yes" && with_dav1d=fail]) if test x"$with_dav1d" = x"fail" ; then AC_MSG_ERROR([dav1d AV1 support requested, but dav1d not found]) fi fi AM_CONDITIONAL([ENABLE_DAV1D], [test x"$with_dav1d" = x"yes"]) dnl Broadcom MMAL (Multi Media Abstraction Layer) decoder plugin for RPi AC_ARG_ENABLE([mmal], [AS_HELP_STRING([--enable-mmal], [Enable libmmal HW decoder and video output plugin for Raspberry Pi (default: enabled)])], [test x"$enableval" != x"no" && enable_mmal="yes"]) if test x"$enable_mmal" != "no"; then saved_CPPFLAGS="$CPPFLAGS" saved_LDFLAGS="$LDFLAGS" LDFLAGS="${LDFLAGS} -L/opt/vc/lib" CPPFLAGS="${CPPFLAGS} -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads" AC_CHECK_LIB([bcm_host], [bcm_host_init], [have_mmal=yes], [have_mmal=no]) if test x"$enable_mmal" = x"yes" && test x"$have_mmal" != x"yes"; then AC_MSG_ERROR([Cannot find bcm library]) else AC_CHECK_HEADERS([interface/mmal/mmal.h], [have_mmal=yes], [have_mmal=no]) if test x"$enable_mmal" = x"yes" && test x"$have_mmal" != x"yes"; then AC_MSG_ERROR([Cannot find MMAL headers]) fi fi if test x"$have_mmal" = x"yes"; then MMAL_LIBS="-lbcm_host -lmmal -lmmal_core -lmmal_util" MMAL_LDFLAGS="-L/opt/vc/lib" MMAL_CFLAGS="-I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads -I/opt/vc/include/interface/vmcs_host/linux" AC_SUBST(MMAL_LIBS) AC_SUBST(MMAL_LDFLAGS) AC_SUBST(MMAL_CFLAGS) AC_DEFINE([HAVE_MMAL], 1, [Define this if you have MMAL installed]) fi CPPFLAGS="$saved_CPPFLAGS" LDFLAGS="$saved_LDFLAGS" fi AM_CONDITIONAL([ENABLE_MMAL], [test x"$have_mmal" = x"yes"]) dnl Only enable building dmx image if at least 1 image decoder is available. AM_CONDITIONAL([BUILD_DMX_IMAGE], [test x"$have_imagemagick" = x"yes" || test x"$have_gdkpixbuf" = x"yes" || test x"$have_libjpeg" = x"yes" || test x"$have_libpng" = x"yes"]) ]) xine-lib-1.2/m4/macosx.m40000644000175000017500000000373614647725152012751 0ustar memeAC_DEFUN([MACOSX_UNIVERSAL_BINARIES], [ AC_ARG_ENABLE([macosx-universal], AS_HELP_STRING([--enable-macosx-universal], [build universal binaries for Mac OS X)]), [], [enable_macosx_universal="no"]) if test x"$enable_macosx_universal" != x"no" ; then case "$host_os" in *darwin*) dnl x64_64 and ppc64 binaries could also be built, but there is no dnl version of Mac OS X currently shipping that can run them, so dnl do not enable them by default for now. if test x"$enable_macosx_universal" = x"yes" ; then UNIVERSAL_ARCHES="i386 ppc" else UNIVERSAL_ARCHES=`echo "$enable_macosx_universal" | sed -e 's/,/ /g'` fi ;; *) AC_MSG_ERROR([Universal binaries can only be built on Darwin]) ;; esac AC_SUBST(UNIVERSAL_ARCHES) CFLAGS="$CFLAGS -isysroot /Developer/SDKs/MacOSX10.4u.sdk" LDFLAGS="$LDFLAGS -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk" if test x"$UNIVERSAL_ARCHES" != x"" ; then # Forcibly disable dependency tracking for Universal builds, because -M # does not work with multiple -arch arguments on the gcc command-line. ac_tool_warned=yes cross_compiling=yes enable_dependency_tracking=no host="`echo $host | sed -e s/$host_cpu/universal/g`" host_cpu=universal AC_DEFINE([XINE_MACOSX_UNIVERSAL_BINARY], 1, [Define this if a universal binary is being built for Mac OS X]) for arch in $UNIVERSAL_ARCHES ; do UNIVERSAL_CFLAGS="$UNIVERSAL_CFLAGS -arch $arch" UNIVERSAL_LDFLAGS="$UNIVERSAL_LDFLAGS -arch $arch" done fi fi AM_CONDITIONAL([MACOSX_UNIVERSAL_BINARY], [test x"$enable_macosx_universal" = x"yes"]) ])dnl MACOSX_UNIVERSAL_BINARIES xine-lib-1.2/m4/getopt_long.m40000644000175000017500000000164514647725152013775 0ustar memednl --------------------------------------------- dnl Check for GNU getopt_long() dnl --------------------------------------------- AC_DEFUN([AC_GETOPT_LONG], [ AC_MSG_CHECKING(for GNU getopt_long) AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include #include static struct option long_options[] = { {"help" , no_argument, 0, 1 }, {"version" , no_argument, 0, 2 }, {0 , no_argument, 0, 0 } }; int main (int argc, char **argv) { int option_index = 0; int c; opterr = 0; while ((c = getopt_long (argc, argv, "?hv", long_options, &option_index)) != EOF) ; return 0; } ]])], [AC_MSG_RESULT(yes); ac_getopt_long=yes; AC_DEFINE(HAVE_GETOPT_LONG,,[Define this if you have GNU getopt_long() implemented])], [AC_MSG_RESULT(no); ac_getopt_long=no], [AC_MSG_RESULT(no); ac_getopt_long=no]) AM_CONDITIONAL(HAVE_GETOPT_LONG, test x"$ac_getopt_long" = "xyes") ]) xine-lib-1.2/m4/summary.m40000644000175000017500000004723714647725152013160 0ustar memeAC_DEFUN([XINE_LIB_SUMMARY], [ dnl --------------------------------------------- dnl Some infos: dnl --------------------------------------------- echo "xine-lib summary:" echo "----------------" dnl Input dis="" echo " * input plugins:" echo " - file - stdin_fifo" dnl network echo " * Network:" echo " - rtsp - rtp" echo " - net - pnm" echo " - http - ftp" test x"$have_tls" = x"yes" && echo " - https - ftpes" || dis="$dis https ftpes" test x"$have_libssh2" = x"yes" && echo " - sftp - scp" || dis="$dis sftp scp" echo " - gopher" test x"$have_tls" = x"yes" && echo " - tls" || dis="$dis tls" test x"$have_libnfs" = x"yes" && echo " - nfs" || dis="$dis nfs" test x"$enable_mms" != x"no" && echo " - mms" || dis="$dis mms" test x"$have_samba" = x"yes" && echo " - smb" || dis="$dis smb" test x"$enable_ipv6" = x"yes" && echo " - IPv6" || dis="$dis IPv6" test x"$dis" != x"" && echo " (disabled plugins:$dis)" dnl optical discs dis="" echo " * Optical discs:" echo " - cdda" if test x"$enable_vcd" != x"no"; then test x"$enable_vcdo" != x"no" && echo " - vcdo" || dis="$dis vcdo" echo " - vcd" else dis="$dis vcd" fi if test x"$enable_dvd" != x"no"; then if test x"$with_external_dvdnav" != x"no"; then echo " - dvd (external libs)" else echo " - dvd (*INTERNAL* libs)" fi else dis="$dis dvd" fi test x"$have_libbluray" = x"yes" && echo " - bluray" || disc="$dis bluray" test x"$dis" != x"" && echo " (disabled plugins:$disc)" dnl devices dis="" echo " * Devices:" test x"$have_dvb" = x"yes" && echo " - dvb" || dis="$dis dvb" test x"$have_v4l" = x"yes" && echo " - v4l" || dis="$dis v4l" test x"$have_v4l2" = x"yes" && echo " - v4l2" || dis="$dis v4l2" test x"$dis" != x"" && echo " (disabled plugins:$dis)" dnl misc dis="" echo " * Misc:" test x"$enable_vdr" != x"no" && echo " - vdr" || dis="$dis vdr" test x"$have_gnomevfs" = x"yes" && echo " - gnome-vfs" || dis="$dis gnome-vfs" test x"$enable_ffmpeg" != x"no" -a x"$have_avformat" = x"yes" && echo " - avio (libavformat)" || dis="$dis avio" echo " - test" test x"$have_gcrypt" = x"yes" && echo " - crypto" || dis="$dis crypto" test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "" dnl Demuxers dis="" echo " * demultiplexer plugins:" echo " - 4xm - aac" echo " - ac3 - aiff" test x"$enable_asf" != x"no" && echo " - asf" || dis="$dis asf" test x"$enable_ffmpeg" != x"no" -a x"$have_avformat" = x"yes" && echo " - avformat (with libavformat)" || dis="$dis avformat" echo " - avi - cdda" echo " - ea wve - film" echo " - FLAC" test x"$have_libflac" = x"yes" && echo " - FLAC (with libFLAC)" || dis="$dis libFLAC" echo " - fli - flv" echo " - idcin - iff" if test x"$have_imagemagick" = x"yes" || test x"$have_gdkpixbuf" = x"yes" || test x"$have_libjpeg" = x"yes" || test x"$have_libpng" = x"yes" ; then echo " - image" else dis="$dis image" fi echo " - interplay mve - ivf" echo " - matroska" test x"$enable_mng" != x"no" && echo " - mng" || dis="$dis mng" test x"$have_modplug" = x"yes" && echo " - mod" || dis="$dis mod" echo " - mpeg - mpeg_audio" echo " - mpeg_block - mpeg_elem" echo " - mpeg_pes - mpeg_ts" test x"$enable_nosefart" != xno && echo " - Nosefart (NSF)" || dis="$dis nosefart" echo " - nsf - nsv" if test x"$have_vorbis" = x"yes" || test x"$with_theora" = x"yes" || test x"$with_speex" = x"yes" ; then echo " - ogg" else dis="$dis ogg" fi echo " - psx str - pva" echo " - qt/mpeg-4 - raw dv" echo " - real/realaudio - roq" echo " - smjpeg - snd/au" echo " - vmd - voc" echo " - vox - vqa" echo " - wav" test x"$with_wavpack" = x"yes" && echo " - WavPack" || dis="$dis WavPack" echo " - wc3 mve - ws aud" echo " - yuv4mpeg2" test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "" dnl video decoders dis="" echo " * video decoder plugins:" test x"$enable_libmpeg2" != x"no" && echo " - MPEG 1,2 (libmpeg2)" if test x"$enable_rawvideo" != x"no"; then echo " - Amiga Bitplane" echo " - Raw RGB" echo " - Raw YUV" fi test x"$have_dxr3" = x"yes" && echo " - dxr3_video" || dis="$dis dxr3" test x"$have_gdkpixbuf" = x"yes" && echo " - gdk-pixbuf" || dis="$dis gdk-pixbuf" test x"$have_imagemagick" = x"yes" && echo " - image" || dis="$dis image" test x"$have_libjpeg" = x"yes" && echo " - libjpeg" || dis="$dis libjpeg" test x"$have_libpng" = x"yes" && echo " - libpng" || dis="$dis libpng" test x"$with_theora" = x"yes" && echo " - theora" || dis="$dis theora" test x"$have_w32dll" = x"yes" && echo " - w32dll" || dis="$dis w32dll" test x"$have_vdpau" = x"yes" && echo " - vdpau" || dis="$dis vdpau" test x"$have_mmal" = x"yes" && echo " - mmal (Broadcom HW)" || dis="$dis mmal" test x"$have_vpx" = x"yes" && echo " - libvpx (VP8/VP9)" || dis="$dis libvpx" test x"$with_openhevc" = x"yes" && echo " - OpenHEVC" || dis="$dis OpenHEVC" test x"$with_libaom" = x"yes" && echo " - libaom (AV1)" || dis="$dis libaom" test x"$with_dav1d" = x"yes" && echo " - dav1d (AV1)" || dis="$dis dav1d" test x"$enable_ffmpeg" != x"no" && echo " - ffmpeg" || dis="$dis ffmpeg" test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "" dnl audio decoders dis="" echo " * audio decoder plugins:" test x"$enable_lpcm" != x"no" && echo " - linear PCM" || dis="$dis LPCM" test x"$enable_dvaudio" != x"no" && echo " - dvaudio" || dis="$dis DV" test x"$enable_gsm610" != x"no" && echo " - GSM 06.10" || dis="$dis GSM" test x"$enable_faad" != x"no" && echo " - faad" || dis="$dis faad" test x"$enable_nosefart" != xno && echo " - Nosefart (NSF)" || dis="$dis nosefart" test x"$have_libflac" = x"yes" && echo " - FLAC (with libFLAC)" || dis="$dis flac" test x"$with_speex" = x"yes" && echo " - speex" || dis="$dis speex" test x"$with_vorbis" = x"yes" && echo " - vorbis" || dis="$dis vorbis" test x"$have_w32dll" = x"yes" && echo " - w32dll" || dis="$dis w32dll" test x"$with_wavpack" = x"yes" && echo " - WavPack" || dis="$dis WavPack" if test x"$enable_mad" != x"no"; then if test x"$have_external_libmad" = x"yes"; then echo " - MAD (MPG 1/2/3) (external library)" else echo " - MAD (MPG 1/2/3) (*INTERNAL* library)" fi else dis="$dis mad" fi if test x"$enable_libdts" != x"no"; then if test x"$have_external_dts" = x"yes"; then echo " - DTS (external library)" else echo " - DTS (*INTERNAL* library)" fi else dis="$dis dts" fi if test x"$enable_a52dec" != x"no"; then test x"$my_a52dec_math" != x"fixed" && test x"$my_a52dec_math" != x"double" && my_a52dec_math="float" if test x"$have_external_a52dec" = x"yes"; then echo " - A52/ra-dnet (external library, $my_a52dec_math math)" else echo " - A52/ra-dnet (*INTERNAL* library, $my_a52dec_math math)" fi else dis="$dis a52" fi if test x"$enable_musepack" != x"no"; then if test x"$have_external_libmpcdec" = x"yes"; then echo " - Musepack (external library)" else echo " - Musepack (*INTERNAL* library)" fi else dis="$dis musepack" fi test x"$enable_ffmpeg" != x"no" && echo " - ffmpeg" || dis="$dis ffmpeg" test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "" dnl spu decoders dis="" echo " * subtitle decoder plugins:" echo " - spu - spucc" echo " - spucmml - sputext" echo " - spudvb" echo " - PGS (BluRay) - TextST (BluRay)" test x"$have_dxr3" = x"yes" && echo " - dxr3_spu" || dis="$dis dxr3" test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "" dnl post plugins dis="" echo " * post effect plugins:" echo " * planar video effects:" echo " - invert - expand" echo " - eq - eq2" echo " - boxblur - denoise3d" echo " - unsharp - tvtime" test x"$enable_postproc" != x"no" && echo " - postproc" || dis="$dis postproc" test x"$enable_vdr" != x"no" && echo " - vdr" || dis="$dis vdr" echo " * SFX:" echo " - goom - oscope" echo " - fftscope - mosaico" echo " - tdaudioanalyzer" echo " * Audio:" echo " - upmix - upmix_mono" echo " - volnorm - scretch" test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "" dnl Video plugins dis="" echo " * video driver plugins:" if test x"$have_opengl2" = x"yes"; then echo " - OpenGL 2.0 (with bicubic scaling)" disgl="" test x"$have_glx" = x"yes" -a x"$no_x" != x"yes" && echo " - X11 (GLX) backend" || disgl="$disgl GLX" test x"$have_egl" = x"yes" -a x"$no_x" != x"yes" && echo " - X11 (EGL) backend" || disgl="$disgl EGL-X11" test x"$have_egl" = x"yes" -a x"$have_wayland" = x"yes" && echo " - Wayland (EGL) backend" || disgl="$disgl EGL-Wayland" test x"$disgl" != x"" && echo " (disabled plugins:$disgl)" else dis="$dis OpenGL2" fi if test x"$no_x" != x"yes"; then echo " - XShm (X11 shared memory)" if test x"$have_xv" = x"yes"; then if test x"$have_xv_static" = x"yes"; then echo " - Xv (XVideo *static*)" else echo " - Xv (XVideo *shared*)" fi else dis="$dis xv" fi if test x"$have_xxmc" = x"yes"; then if test x"$have_vldexts" = x"yes"; then echo " - XxMC (XVideo extended motion compensation)" else echo " - XxMC (XVideo motion compensation - vld extensions DISABLED)" fi else dis="$dis xxmc" fi if test x"$have_opengl" = x"yes"; then if test x"$have_glu" = x"yes"; then echo " - OpenGL (with GLU support)" else echo " - OpenGL" fi else dis="$dis OpenGL" fi if test x"$have_vaapi" = x"yes" -a x"$enable_ffmpeg" != x"no"; then echo " - vaapi (Video Acceleration (VA) API for Linux)" dis_va="" ena_va="" test x"$have_vaapi_x11" = x"yes" && ena_va="$ena_va x11" || dis_va="$dis_va x11" test x"$have_vaapi_glx" = x"yes" && ena_va="$ena_va glx" || dis_va="$dis_va glx" test x"$have_vaapi_drm" = x"yes" && ena_va="$ena_va drm" || dis_va="$dis_va drm" test x"$have_vaapi_wayland" = x"yes" && ena_va="$ena_va wayland" || dis_va="$dis_va wayland" ena_va=" - display plugins:$ena_va" test x"$dis_va" != x"" && ena_va="$ena_va (disabled plugins:$dis_va)" echo "$ena_va" else dis="$dis vaapi" fi test x"$have_vdpau" = x"yes" && echo " - vdpau (X11 Video Decode and Presentation API for Unix)" || dis="$dis vdpau" test x"$have_xvmc" = x"yes" && echo " - XvMC (XVideo motion compensation)" || dis="$dis xvmc" if test x"$have_sunfb" = x"yes" -a x"$have_sundga" = x"yes"; then echo " - PGX64 (for Sun XVR100/PGX64/PGX24 cards)" echo " - PGX32 (for Sun PGX32 cards)" else dis="$dis sunfb" fi else dis="$dis X11" fi if test x"$have_xcb" = x"yes"; then test x"$have_xcbshm" = x"yes" && echo " - xcb-shm (X shared memory using XCB)" || dis="$dis xcb-shm" test x"$have_xcbxv" = x"yes" && echo " - xcb-xv (XVideo using XCB)" || dis="$dis xcb-xv" else dis="$dis xcb" fi test x"$have_aalib" = x"yes" && echo " - aa (Ascii ART)" || dis="$dis aa" test x"$have_caca" = x"yes" && echo " - caca (Color AsCii Art)" || dis="$dis caca" test x"$have_directfb" = x"yes" && echo " - directfb (DirectFB driver)" || dis="$dis directfb" test x"$have_directx" = x"yes" && echo " - directx (DirectX video driver)" || dis="$dis directx" test x"$have_fb" = x"yes" && echo " - fb (Linux framebuffer device)" || dis="$dis fb" test x"$have_libstk" = x"yes" && echo " - stk (Libstk Set-top Toolkit)" || dis="$dis stk" test x"$have_macosx_video" = x"yes" && echo " - Mac OS X OpenGL" || dis="$dis macos" test x"$have_sdl" = x"yes" && echo " - sdl (Simple DirectMedia Layer)" || dis="$dis sdl" test x"$have_mmal" = x"yes" && echo " - mmal (Broadcom MultiMedia Abstraction Layer)" || dis="$dis mmal" echo " - none (dummy output plugin)" echo " - raw" if test x"$have_dxr3" = x"yes"; then if test x"$have_encoder" = x"yes"; then echo " - dxr3 (Hollywood+ and Creative dxr3, both mpeg and non-mpeg video)" else echo " - dxr3 (Hollywood+ and Creative dxr3, mpeg video only)" fi else dis="$dis dxr3" fi if test x"$have_vidix" = x"yes"; then echo $ECHO_N " - vidix (" if test x"$no_x" != x"yes"; then echo $ECHO_N "X11" if test x"$have_fb" = x"yes"; then echo $ECHO_N " and " fi fi if test x"$have_fb" = x"yes"; then echo $ECHO_N "framebuffer" fi echo $ECHO_N " support" if test x"$enable_dha_kmod" != x"no"; then echo " with dhahelper)" else echo ")" fi else dis="$dis vidix" fi test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "" dnl Audio plugins dis="" echo " * audio driver plugins:" test x"$have_alsa" = x"yes" && echo " - alsa (ALSA - Advanced Linux Sound Architecture)" || dis="$dis alsa" test x"$have_coreaudio" = x"yes" && echo " - CoreAudio (Mac OS X audio driver)" || dis="$dis CoreAudio" test x"$have_directx" = x"yes" && echo " - directx (DirectX audio driver)" || dis="$dis directx" test x"$have_esound" = x"yes" && echo " - esd (Enlightened Sound Daemon)" || dis="$dis esd" test x"$have_fusionsound" = x"yes" && echo " - fusionsound (FusionSound driver)" || dis="$dis fusionsound" test x"$am_cv_have_irixal" = x"yes" && echo " - irixal (Irix audio library)" || dis="$dis irixal" test x"$have_jack" = x"yes" && echo " - Jack" || dis="$dis jack" test x"$have_oss" = x"yes" && echo " - oss (Open Sound System)" || dis="$dis oss" test x"$have_pulseaudio" = x"yes" && echo " - pulseaudio (PulseAudio sound server)" || dis="$dis pulse" test x"$have_sunaudio" = x"yes" && echo " - sun (Sun audio interface)" || dis="$dis sun" test "x$have_sndio" = "xyes" && echo " - sndio" || dis="$dis sndio" test "x$have_opensles" = "xyes" && echo " - OpenSL ES" || dis="$dis opensles" echo " - none (dummy output plugin)" echo " - file" test x"$dis" != x"" && echo " (disabled plugins:$dis)" echo "---" dnl --------------------------------------------- dnl some user warnings dnl --------------------------------------------- dnl some levels of variable expansion to get final install paths final_libdir="`eval eval eval eval echo $libdir`" final_bindir="`eval eval eval eval echo $bindir`" if test -r /etc/ld.so.conf && ! grep -x "$final_libdir" /etc/ld.so.conf >/dev/null ; then if test "$final_libdir" != "/lib" -a "$final_libdir" != "/usr/lib" ; then if ! echo "$LD_LIBRARY_PATH" | egrep "(:|^)$final_libdir(/?:|/?$)" >/dev/null ; then echo echo "****************************************************************" echo "xine-lib will be installed to $final_libdir" echo echo "This path is not mentioned among the linker search paths in your" echo "/etc/ld.so.conf. This means it is possible that xine-lib will" echo "not be found when you try to compile or run a program using it." echo "If this happens, you should add $final_libdir to" echo "the environment variable LD_LIBRARY_PATH like that:" echo echo "export LD_LIBRARY_PATH=$final_libdir:\$LD_LIBRARY_PATH" echo echo "Alternatively you can add a line \"$final_libdir\"" echo "to your /etc/ld.so.conf." echo "****************************************************************" echo fi fi fi if ! echo "$PATH" | egrep "(:|^)$final_bindir(/?:|/?$)" >/dev/null ; then echo echo "****************************************************************" echo "xine-config will be installed to $final_bindir" echo echo "This path is not in your search path. This means it is possible" echo "that xine-config will not be found when you try to compile a" echo "program using xine-lib. This will result in build failures." echo "If this happens, you should add $final_bindir to" echo "the environment variable PATH like that:" echo echo "export PATH=$final_bindir:\$PATH" echo echo "Note that this is only needed for compilation. It is not needed" echo "to have xine-config in your search path at runtime. (Although" echo "it will not cause any harm either.)" echo "****************************************************************" echo fi dnl warn if no X11 plugins will be built if test "x$no_x" = "xyes"; then case $host in *mingw*|*-cygwin) ;; *-darwin*) ;; *) echo echo "****************************************************************" echo "WARNING! No X11 output plugins will be built." echo echo "For some reason, the requirements for building the X11 video" echo "output plugins are not met. That means, that you will NOT be" echo "able to use the resulting xine-lib to watch videos in a window" echo "on any X11-based display (e.g. your desktop)." echo echo "If this is not what you want, provide the necessary X11 build" echo "dependencies (usually done by installing a package called" echo "XFree86-devel or similar) and run configure again." echo "****************************************************************" echo ;; esac fi ]) xine-lib-1.2/m4/pthreads.m40000644000175000017500000000646314647725152013271 0ustar memednl Detection of the Pthread implementation flags and libraries dnl Diego Pettenò 2006-11-03 dnl dnl CC_PTHREAD_FLAGS([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) dnl This macro checks for the Pthread flags to use to build dnl with support for PTHREAD_LIBS and PTHREAD_CFLAGS variables dnl used in FreeBSD ports. dnl dnl This macro is released as public domain, but please mail dnl to flameeyes@gmail.com if you want to add support for a dnl new case, or if you're going to use it, so that there will dnl always be a version available. AC_DEFUN([CC_PTHREAD_FLAGS], [ AC_REQUIRE([CC_CHECK_WERROR]) AC_ARG_VAR([PTHREAD_CFLAGS], [C compiler flags for Pthread support]) AC_ARG_VAR([PTHREAD_LIBS], [linker flags for Pthread support]) dnl if PTHREAD_* are not set, default to -pthread (GCC) if test "${PTHREAD_CFLAGS-unset}" = "unset"; then case $host in *-mingw*) PTHREAD_CFLAGS="" ;; *-cygwin*) PTHREAD_CFLAGS="" ;; *-hpux11*) PTHREAD_CFLAGS="" ;; *-darwin*) PTHREAD_CFLAGS="" ;; *-solaris*|*-linux-gnu) dnl Handle Sun Studio compiler (also on Linux) CC_CHECK_CFLAGS([-mt], [PTHREAD_CFLAGS="-mt"]);; *) PTHREAD_CFLAGS="-pthread" ;; esac fi if test "${PTHREAD_LIBS-unset}" = "unset"; then case $host in *-mingw*) PTHREAD_LIBS="-lpthreadGC2" ;; *-cygwin*) PTHREAD_LIBS="-lpthread" ;; *-hpux11*) PTHREAD_LIBS="-lpthread" ;; *-darwin*) PTHREAD_LIBS="" ;; *-solaris*) dnl Use the same libraries for gcc and Sun Studio cc PTHREAD_LIBS="-lpthread -lposix4 -lrt";; *) PTHREAD_LIBS="-pthread" ;; esac dnl Again, handle Sun Studio compiler if test "x${PTHREAD_CFLAGS}" = "x-mt"; then PTHREAD_LIBS="-mt" fi fi AC_CACHE_CHECK([if $CC supports Pthread], AS_TR_SH([cc_cv_pthreads]), [ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $cc_cv_werror $PTHREAD_CFLAGS" LIBS="$LIBS $PTHREAD_LIBS" AC_LINK_IFELSE( [AC_LANG_PROGRAM( [[#include void *fakethread(void *arg) { (void)arg; return NULL; } pthread_t fakevariable; ]], [[pthread_create(&fakevariable, NULL, &fakethread, NULL);]] )], [cc_cv_pthreads=yes], [cc_cv_pthreads=no]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" ]) AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) if test x$cc_cv_pthreads = xyes; then ifelse([$1], , [:], [$1]) else ifelse([$2], , [:], [$2]) fi ]) AC_DEFUN([CC_PTHREAD_RECURSIVE_MUTEX], [ AC_REQUIRE([CC_PTHREAD_FLAGS]) AC_CACHE_CHECK( [for recursive mutex support in pthread], [cc_cv_pthread_recursive_mutex], [ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $cc_cv_werror $PTHREAD_CFLAGS" LIBS="$LIBS $PTHREAD_LIBS" AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([ #include ], [ pthread_mutexattr_t attr; pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); ]) ], [cc_cv_pthread_recursive_mutex=yes], [cc_cv_pthread_recursive_mutex=no]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" ]) AS_IF([test x"$cc_cv_pthread_recursive_mutex" = x"yes"], [$1], [$2]) ]) xine-lib-1.2/Makefile.am0000644000175000017500000001261714647725151012726 0ustar meme### ## Process this file with automake to produce Makefile.in ## AUTOMAKE_OPTIONS = 1.11 no-dist-gzip dist-xz ACLOCAL_AMFLAGS = -I m4 SUBDIRS = doc po lib src contrib misc DEBFILES = debian/README.Debian debian/changelog debian/control \ debian/copyright debian/rules debian/compat \ debian/shlibdeps.sh debian/libxine2-dev.install debian/libxine1.install EXTRA_DIST = \ autogen.sh \ config.rpath \ configure \ config.guess \ config.sub \ depcomp \ INSTALL \ install-sh \ libtool \ ltmain.sh \ missing \ \ include/xine/version.h.in \ m4/attributes.m4 \ m4/audio_out.m4 \ m4/decoders.m4 \ m4/directx.m4 \ m4/gas.m4 \ m4/gettext.m4 \ m4/getopt_long.m4 \ m4/glibc21.m4 \ m4/glibc2.m4 \ m4/intmax.m4 \ m4/codeset.m4 \ m4/iconv.m4 \ m4/input.m4 \ m4/intldir.m4 \ m4/intl.m4 \ m4/intlmacosx.m4 \ m4/inttypes_h.m4 \ m4/inttypes-pri.m4 \ m4/intdiv0.m4 \ m4/lcmessage.m4 \ m4/lib-ld.m4 \ m4/lib-link.m4 \ m4/lib-prefix.m4 \ m4/libFLAC.m4 \ m4/libtool.m4 \ m4/lock.m4 \ m4/longlong.m4 \ m4/lt~obsolete.m4 \ m4/ltoptions.m4 \ m4/ltsugar.m4 \ m4/ltversion.m4 \ m4/macosx.m4 \ m4/misc.m4 \ m4/nls.m4 \ m4/objc.m4 \ m4/package.m4 \ m4/pkg.m4 po.m4 \ m4/pthreads.m4 \ m4/printf-posix.m4 \ m4/programs.m4 \ m4/progtest.m4 \ m4/size_max.m4 \ m4/stdint_h.m4 \ m4/summary.m4 \ m4/symbol.m4 \ m4/types.m4 \ m4/uintmax_t.m4 \ m4/video_out.m4 \ m4/visibility.m4 \ m4/wchar_t.m4 \ m4/wint_t.m4 \ m4/xine.m4 \ m4/xsize.m4 \ win32/scripts/post_install.bat \ win32/scripts/ffmpeg_win32.patch \ win32/include/msvc/sys/time.h \ win32/include/msvc/config.h \ win32/include/msvc/inttypes.h \ win32/include/msvc/stdint.h \ win32/include/msvc/unistd.h \ win32/include/dlfcn.h \ win32/config.h \ win32/README \ win32/libdvdnav.def \ win32/libxine.def \ win32/libxinesupport.def \ win32/xine_plugin.def \ win32/xine.dsw if INSTALL_M4 m4datadir = $(ACLOCAL_DIR) else m4datadir = $(datadir)/aclocal endif m4data_DATA = m4/xine.m4 if GENERATED_INTTYPES_H inttypes_h = include/inttypes.h endif noinst_HEADERS = include/config.h nodist_noinst_HEADERS = include/configure.h nodist_include_HEADERS = $(inttypes_h) include_HEADERS = include/xine.h xineincludedir = $(includedir)/xine xineinclude_HEADERS = \ include/xine/alphablend.h \ include/xine/array.h \ include/xine/attributes.h \ include/xine/audio_decoder.h \ include/xine/audio_out.h \ include/xine/broadcaster.h \ include/xine/buffer.h \ include/xine/compat.h \ include/xine/configfile.h \ include/xine/demux.h \ include/xine/info_helper.h \ include/xine/input_plugin.h \ include/xine/io_helper.h \ include/xine/list.h \ include/xine/metronom.h \ include/xine/mfrag.h \ include/xine/os_types.h \ include/xine/osd.h \ include/xine/plugin_catalog.h \ include/xine/pool.h \ include/xine/post.h \ include/xine/refcounter.h \ include/xine/resample.h \ include/xine/ring_buffer.h \ include/xine/scratch.h \ include/xine/sorted_array.h \ include/xine/spu.h \ include/xine/spu_decoder.h \ include/xine/stree.h \ include/xine/tickets.h \ include/xine/vdr.h \ include/xine/version.h \ include/xine/video_decoder.h \ include/xine/video_out.h \ include/xine/video_overlay.h \ include/xine/vo_scale.h \ include/xine/xine_buffer.h \ include/xine/xine_internal.h \ include/xine/xine_module.h \ include/xine/xine_plugin.h \ include/xine/xineintl.h \ include/xine/xineutils.h \ include/xine/xmllexer.h \ include/xine/xmlparser.h CLEANFILES = a.out DISTCLEANFILES = include/xine/version.h CONFIG_CLEAN_FILES = \ libtool \ po/Makevars.extra \ $(inttypes_h) MAINTAINERCLEANFILES = \ Makefile.in configure acinclude.m4 aclocal.m4 \ stamp-h.in ltconfig ltmain.sh \ config.guess config.sub install-sh missing mkinstalldirs \ depcomp config.log dist_doc_DATA = COPYING NEWS README TODO CREDITS ChangeLog docs clean-docs: @cd doc && $(MAKE) $@ distcheck-lax: @$(MAKE) distcheck_lax=true distcheck pass1: @$(MAKE) MULTIPASS_CFLAGS='$(PASS1_CFLAGS)' pass2: @$(MAKE) MULTIPASS_CFLAGS='$(PASS2_CFLAGS)' prune-cache: -rm -rf config.cache autom4te.cache release-check: @./config.status misc/relchk.sh @mv -f .cvsversion .cvsversion.tmp @./autogen.sh noconfig && $(SHELL) misc/relchk.sh @mv -f .cvsversion.tmp .cvsversion slackbuild: @(cd misc && $(MAKE) SlackBuild) && \ PREFIX="/usr" misc/SlackBuild install-exec-hook: find $(top_builddir) -name \*.so | \ xargs $(STRINGS) -a | \ $(EGREP) '^([-a-z]+/[-+.a-z0-9]+:[^:]+:[^;]+;[ \t]*)+' | \ sed -e 's/:[^;]\+;/\n/g' | \ sort -u | \ sed -e '1 d' >$(DESTDIR)$(XINE_PLUGINDIR)/mime.types uninstall-hook: rm -f $(DESTDIR)$(XINE_PLUGINDIR)/mime.types install-data-hook: @rm -f $(DESTDIR)$(XINE_PLUGINDIR)/*.la @rm -f $(DESTDIR)$(XINE_PLUGINDIR)/*/*.la @rm -f $(DESTDIR)$(XINE_PLUGINDIR)/*.dll.a @rm -f $(DESTDIR)$(XINE_PLUGINDIR)/*/*.dll.a @if test -x "$(top_srcdir)/post-install.sh" ; then \ $(top_srcdir)/post-install.sh ; \ fi dist-hook: cp -p $(srcdir)/version.sh $(distdir) mkdir $(distdir)/win32/ cp -p $(srcdir)/win32/*.dsp $(distdir)/win32/ MOSTLYCLEANFILES = \ $(PACKAGE)_$(VERSION).tar.gz \ $(PACKAGE)_$(VERSION).tar.bz2 \ $(PACKAGE)-$(VERSION).tar.xz \ $(distdir).tar.gz \ $(PACKAGE).tgz \ package_descriptions mostlyclean-local: -rm -rf $(distdir) maintainer-clean-generic-hook: rm -f config.status $(top_srcdir)/configure: $(am__configure_deps) cd $(srcdir) && $(AUTOCONF) && $(SED) -i -e '/gnu_ld/,/;;/ s/--rpath \$${wl}/--rpath,/' $@ xine-lib-1.2/AUTHORS0000644000175000017500000004354214647725151011743 0ustar memeproject administrator ===================== Siegfried Langauf Debian package, user support, project administration, plugin loader Diego 'Flameeyes' Pettenò build system improvements, LE_64/BE_64 macro fixes, lots of clean-up project admin / release manager =============================== Darren Salt Debian packaging, bug fixes, some clean-up, various minor features, patch handler developers ========== Petri Hintukainen avformat plugin, libvpx and MMAL video decoding, bluray support, matroska demux improvements, maintenance, fixes Miguel Freitas many bug and deadlock fixes, engine maintenance, soft deinterlacer, massive libwin32 updates, 'former' project leader Michael Roitzsch several dxr3 fixes, massive engine contributions, multistream and post plugin architecture, DVD navigation, 'former' project leader Mike Melanson a whole bunch of file demuxers, lots of audio and video decoders, assorted other input sources and utilities, 'former' project leader Thibaut Mattern demuxer cleanups and fixes, mms input plugin fixes, xml parser, mmsh protocol support, 'former' project leader Guenter Bartsch xine founder, former project leader Daniel Caujolle-Bert various suggestions, bug and build fixes, alsa plugin, main xine-ui programming Heiko Schaefer FreeBSD support, testing, ideas Rich Wareham subtitle support, navigation, libdvdnav Rocky Bernstein ~/ Enhanced VCD support James Courtier-Dutton AC3 direct out via spdif on oss, subtitle interface, audio_output interface Juergen Keil Solaris port and other bugfixes Matthias Hopf IRIX port, video out interface, opengl video output Robin KAY xvr100, pgx64/pgx24, and pgx32 video output plugins, WVE demuxer, MNG demuxer, EA ADPCM decoder, Solaris port improvements and bugfixes, various video_out, misc bugfixes Stephen Torri Automake, autoconf, libtool development, and build fixes, health check Stefan Holst real media streaming support, input_net fixes, image demuxer/decoder frontend programming Manfred Tremmel iff support, spec-file James Stembridge VIDIX driver, real media and ffmpeg interface fixes and improvements mpeg-4 postprocessing, initial software DTS decoding František Dvořák czech translations and multilanguage support (xine lib/ui), RIP Input Plugin, WIN32 porting, lots of other improvements and bugfixes Reinhard Tartler Debian packaging, bug fixes xine is using ============= mpeg2dec - a free MPEG-2 video stream decoder liba52 - a free A/52 audio stream decoder Written by Aaron Holtzman maintained and massively enhanced by Michel Lespinasse libmpg123 - a free MPEG audio decoder Written by Michael Hipp FFmpeg - Streaming Multimedia System Written by Fabrice Bellard libmad - MPEG audio decoder Written by Robert Leslie avifile (Win32 codecs and DirectShow support) Written by Eugene Kuznetsov and Zdenek Kabelac FAAD2 - Freeware Advanced Audio Decoder version 2 Written by M. Bakker libdts - a free DTS Coherent Acoustics decoder Written by Gildas Bazin GSM 06.10 Lossy Speech Compression Library Written by Jutta Degener and Carsten Bormann http://kbs.cs.tu-berlin.de/~jutta/toast.html win32 codec support (windows media / quicktime / real codecs) is based on work from: avifile http://avifile.sf.net MPlayer http://www.mplayerhq.hu/ wine http://www.winehq.com some demuxers and decoders (especially the real demuxer) and MMX/MMX2/SSE memcpy methods (among other things) are based on work from MPlayer http://www.mplayerhq.hu/ the vidix video system from MPlayerXP http://mplayerxp.sf.net/ VCD interpretation code in the extended VCD plugin from VCDImager by Herbert Valerio Riedel http://vcdimager.org CD I/O routines for the above from GNU libcdio by Rocky Bernstein and Herbert Valerio Riedel http://www.gnu.org/software/libcdio Goom - visual effects generator Written by Jean-Christophe Hoelt et. al. http://ios.free.fr/?page=projet&quoi=1 Nosefart v1.92 - NES Music Simulator Written by Matt Conte http://www.baisoku.org/ PCM time-domain equalizer Copyright (C) 2002 Felipe Rivera http://equ.sf.net Contributions ============= many thanks to the Linux Video and DVD Project "LiViD" (http://www.linuxvideo.org/), where the original ideas for the xine video player came from. Alan Cox bug fixes, net-input-plugin Alexander G. Rubio many thanks for those great skins to Marc Bufe web design Hugo Trippaers Xinerama support Roland Barmettler NTSC aspect ratio patches nakamura Liner PCM patch Bruno Schwander Soren Schmidt input_vcd code for FreeBSD Christoph Pittracher pitt skin Dave Gilbert alpha support Bastien Nocera gnome-vfs input plugin, powerpc patch, bug fixes Philip Stadermann arts audio server support, kde frontend Jérôme Villette 'xinetic', 'CelomaGold', 'CelomaMdk', 'CelomaChrome', 'Centori' and 'Keramic' skins. Bill Fink powerpc patches, oss output softsync, "skip by chapter" feature Gert Vervoort LPCM audio decoder plugin, ffmpeg aspect ratio Peter Weissgerber alsa 05 plugin fixes Alfredo J. Delaiti alfredodelaiti@netscape.net FAQ spanish translation Marco Solari FAQ and README italian translation Luis Silva xine about movie Harm van der Heijden libdivx4 plugin, dxr3 support and encoding Chris Rankin configurable VCD device patch, rv40 support, build fixes, bugfixes, bug reporting Andrew Meredith Snapshot feature Stefan Reinauer ia64, s/390 patches Bartlomiej Muryn README.dxr3 and .po Polish translations, dxr3 testing Damien Clermonte http input plugin patches Matthias Dahl syncfb video-out plugin, XF86VidMode support, FAQ/README overhaul, bugfixes Marcelo Roberto Jimenez w32dll audio and xine-ui bugfixes George Staikos xinerama bugfixes Juan Manuel García Molina spanish internationalization files. Jeffrey W. Baker altivec support for libmpeg2 Gurer Ozen gtk+ frontend Tommi Asiala Readme in Finnish Daniel Erat 'cloudy' skin. Ewald Snel metronom sync loop fix, safe ffmpeg multithread init, memleak fixes Bruno Pinaud french translation updates/fixes. Philipp Matthias Hahn many translation files and man pages updates/fixes Tomas Kovar slovak internationalization files (xine lib), xvid support Daniel Bena slovak internationalization files (xine ui, xine lib). Scott Smith yuv2rgb optimizations and downscaling support Jirka Novak font encoding support for avi subtitles Michael Jochum avi multiple audio stream support Andrei Lahun mms/browser plugin enhancements, asf fixes Sergiy Kudryk ukrainian internationalization files (xine ui). Ian Goldberg streaming AVI support (plays growing files), >2GB AVI files Rogerio Brito C version for linear blend deinterlacer Tim Ferguson CYUV, RoQ, and Id CIN video decoders Andrew Patrikalakis powerpc assembly memcpy() implementaions with assistance from Rogerio Brito Benjamin Herrenschmidt Michel Dänzer Others Giovanni Baronetti and Mauro Borghi demux_ts fixes and improvements Carsten Weinhold patch to improve quality of linearblend filter, new AV sync method by resampling audio, fixed pthread starvation in audio out, improved audio vpts precision Claire Griffin demux_ts fixes for ATSC streams Staszek Pasko binary index search for avi demuxer Dan Lindstrom 64-bit Quicktime fixes Andres Salomon memory leakage fixes Pierre Lombard patch to avoid loss of first line in linearblend deinterlacer Igor Mokrushin Software stereo volume control for aRts Roberto Togni RPZA video decoder Mario Brito Wing Commander III video decoder Howdy Pierce pgx64 memory corruption patch, xshm bounds check patch demux_ts bugfixes James Slorach fix for wrong abs() macro, deinterlacing fix, reported problem with estimation used by video_out to discard frames. Steffen Lorscheider gui programming Paul Flinders stdin/net plugin testing/bugfixes, audio downsampling Joachim Koenig teletux/syncfb video output module, various bugfixes/reviews, alsa Christian Bauer gui bugfixes (wm support, clean exit) Eduard Hasenleithner dxr3 support Christian Vogler closed caption decoding, osd fixes Dennis Bjorklund configurable size of avi subtitles, patch to fix flashing subtitles in libsputext Xavier Izard Xinerama fullscreen bugfix. Anders D. Wiehe OSD stream informations patch. Zoltán Böszörményi tremendous help in porting sputext to 1.0 API Micael Beronius Chris Purnell DVB plugin port to new API, DVB-C support, updates, fixes Mattias Eriksson ported nvtv/tvmode code John McCutchan flac demuxer and decoder Fredrik Noring linux fb frontend. improved fb driver with zero copy Marco Zühlke visualization improvements, demuxer cleanups Julio Sánchez patch for drawing OSD bitmaps Stuart Caie Playstation STR file demuxer, CD-ROM/XA ADPCM decoder Markus Plail DTS passthrough improvements Dilb (?) demux_ogg.c strongarm patch Dan Dennedy rawdv demuxer fixes, dvaudio patch, stdin input fixes Andreas Heinchen theora support, subtitles in ogm streams, OGM subtitles support, xvid/divx/mpeg4 testing, patches and bugfixes Mariusz Pekala vplayer subtitle format fixes Tim Champagne Matthew Grooms msvc win32 port Conrad Parker speex, Annodex and CMML support Marcel Janssen libavcodec MPEG encoder for DXR3 Dirk Meyer stdctl patches for xine-ui and fbxine. post filter support for fbxine. Darren Vincent Hart libstk video out plugin Philip Jägenstedt rework of aspect ratio to support float values Laurent Aimar MPEG demuxer fixes Adrian Schroeter AMD64 support Simon Truss metronom fix for duplicated pts Jeroen Asselman v4l improvements, audio support Njål T. Borch Ipv6 patch Ramon van der Aar Network Buffer Controler patch, RTP/UDP plugin improvements Jack Steven Kelliher XvMC support ATSC support for the DVB plugin Wang WenRui encoding of URL with multibyte characters in MMS Giovanni Venturi .po Italian translations Drew 'dantealiegri' Ogle xitk fixes, xitk Xft support. Stephen Birch RTP/UDP plugin fixes and improvements Debian woody backport autoprobe devfs in OSS audio output plugin Tilmann Bitterberg OpenDML (AVI2.0) support Paul Eggleton Amiga MOD support Jeff Smith CACA video output plugin Yann Vernier Via Ezra cpu detection, colorkey overlay support for OSD David Woodhouse file (wave) audio out plugin endian fixes in the pnm and rtsp input plugins Koos Vriezen asx ENTRYREF tag handling Ian MacIntosh Video resizing using mediaLib Mike Lampard Overlay support for the DXR3 MPEG decoder Pan & Scan support for the DXR3 MPEG decoder DVB plugin DVB subtitle plugin Moritz Bunkus Seeking support for the Matroska demuxer. Szymon Stefanek Improved DVB mrls and dvbs, dvbc and dvbt support Vincent Pelletier Word wrap and other improvements in libsputext. Daniel Mack native Mac OS X video and audio output plugins André Pang Mac OS X fixes and framework/frontend work Annodex and CMML support Stefan Kristiansson moved Xv initialization from class to plugin context Ryan Tadlock compensation for the field delay of some deinterlacing algorithms Casper Boemann reuse stubs for unresolved exports of win32 dlls Thomas Hellström XxMC driver with reworked XvMC support, including VIA CLE266 vld extensions. Frank van Viegen libsmbclient input plugin Sylvain Colinet mpl2 subtitle support Barry Scott fix V4l source selection code by MRL Reinhard Nißl contributions for VDR interoperability, bugfixes, overlay blending quality improvements, audio post plugin support for xine-ui, upmix_mono post plugin Pekka Jääskeläinen DVB mouse-control and EPG enhancements Assaf Gillat CDDB protocol 6 support (UTF-8 and multiple cd entries) Tadashi Jokagi Japanese translation of xine-ui Piarres Beobide Basque translations (xine-lib and xine-ui) Keenan Pepper gcc4 patches Dams Nadé gcc4 patches Jason Tackaberry plugin loader fixes, expand plugin fixes and non-4/3 display support Claudio Ciccani completely rewritten DirectFB video out plugin Maximilian Schwerin support for Vorbis-style comments in FLAC files Chris Cannam JACK audio driver Christoph Pfister XCB output plugins Reinhard Nißl build fix, bugfixes Christopher Martin CD and 24bit audio improvements, WMAPro support Christian Ruppert build fixes Lorenzo Desole audio fixes Kevin Kofler build fixes Pino Toscano build fix Ulrich Müller OSD bugfix Andreas Auras Continuous video frame grabbing feature, VDPAU out fixes, video out fixes, dvb subtitle fix Jose Alberto Reguero EAC3 fixes Albert Lee Solaris portability fixes (and other miscellaneous fixes) Mikko Rasa HDMV subtitle fix Roland Scheidegger MMX(ext), SSE(2) and AVX assembly improvements Anton Khirnov DXR3 fix Alan Barrett MMX assembly fixes Thomas Klausner BSD port improvements and bugfixes Carlo Bramini cygwin related fixes, ffmpeg compatibility Brad Smith Build fixes, bugfixes Torsten Jager Test card input plugin, Time Domain Audio Analyzer Plugin, Xshm video crop support, color matrix and fullrange video support, ffmpeg compatibility, rgb to yuy2 converter, faad and ffmpeg audio channel mixer, demux improvements, dependency reduction, plugin joining, german translation, optimizations, bugfixes, build fixes Christophe Thommeret OpenGL 2.0 video out plugin, new VDPAU h264 decoder, VDPAU bugfixes Edgar Hucek VAAPI Support, ffmpeg compatibility Xavier Bachelot Build fixes, Fedora port, french translation Dominique Leuenberger Build fixes (let us know if we've forgotten anyone) xine-lib-1.2/NEWS0000644000175000017500000000024214647725151011360 0ustar memexine-lib 1.2.0 ============== As of this release, xine-config is deprecated. You should use pkg-config libxine instead - see xine-config's man page for details. xine-lib-1.2/autogen.sh0000755000175000017500000001672014647725151012672 0ustar meme#!/bin/sh -e # # Copyright (C) 2000-2003 the xine project # # This file is part of xine, a unix video player. # # xine is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # xine is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA # # Maintained by Stephen Torri # # run this to generate all the initial makefiles, etc. PROG=xine-lib # Minimum value required to build export WANT_AUTOMAKE_1_11=1 export WANT_AUTOMAKE=1.11 AUTOMAKE_MIN=1.11.0 AUTOCONF_MIN=2.59 LIBTOOL_MIN=1.5.20 # Check how echo works in this /bin/sh case `echo -n` in -n) _echo_n= _echo_c='\c';; *) _echo_n=-n _echo_c=;; esac srcdir="`dirname "$0"`" detect_configure_ac() { test -z "$srcdir" && srcdir=. (test -f "$srcdir"/configure.ac) || { echo $_echo_n "*** Error ***: Directory "\`$srcdir\`" does not look like the" echo " top-level directory" exit 1 } } parse_version_no() { # version no. is extended/truncated to three parts; only digits are handled perl -e 'my $v = <>; chomp $v; my @v = split (" ", $v); $v = $v[$#v]; $v =~ s/[^0-9.].*$//; @v = split (/\./, $v); push @v, 0 while $#v < 2; print $v[0] * 10000 + $v[1] * 100 + $v[2], "\n"' } #-------------------- # AUTOCONF #------------------- detect_autoconf() { set -- `type autoconf 2>/dev/null` RETVAL=$? NUM_RESULT=$# RESULT_FILE=$3 if [ $RETVAL -eq 0 -a $NUM_RESULT -eq 3 -a -f "$RESULT_FILE" ]; then AC="`autoconf --version | parse_version_no`" if [ `expr $AC` -ge "`echo $AUTOCONF_MIN | parse_version_no`" ]; then autoconf_ok=yes fi else echo echo "**Error**: You must have \`autoconf' >= $AUTOCONF_MIN installed to" echo " compile $PROG. Download the appropriate package" echo " for your distribution or source from ftp.gnu.org." exit 1 fi } run_autoheader () { if test x"$autoconf_ok" != x"yes"; then echo echo "**Warning**: Version of autoconf is less than $AUTOCONF_MIN." echo " Some warning message might occur from autoconf" echo fi echo $_echo_n " + Running autoheader: $_echo_c"; autoheader; echo "done." } run_autoconf () { if test x"$autoconf_ok" != x"yes"; then echo echo "**Warning**: Version of autoconf is less than $AUTOCONF_MIN." echo " Some warning message might occur from autoconf" echo fi echo $_echo_n " + Running autoconf: $_echo_c"; autoconf; sed -i -e '/gnu_ld/,/;;/ s/--rpath \${wl}/--rpath,/' configure echo "done." } #-------------------- # LIBTOOL #------------------- try_libtool_executable() { libtool=$1 set -- `type $libtool 2>/dev/null` RETVAL=$? NUM_RESULT=$# RESULT_FILE=$3 if [ $RETVAL -eq 0 -a $NUM_RESULT -eq 3 -a -f "$RESULT_FILE" ]; then LT="`$libtool --version | awk '{ print $4 }' | parse_version_no`" if [ `expr $LT` -ge "`echo $LIBTOOL_MIN | parse_version_no`" ]; then libtool_ok=yes fi fi } detect_libtool() { # try glibtool first, then libtool try_libtool_executable 'glibtool' if [ "x$libtool_ok" != "xyes" ]; then try_libtool_executable 'libtool' if [ "x$libtool_ok" != "xyes" ]; then echo echo "**Error**: You must have \`libtool' >= $LIBTOOL_MIN installed to" echo " compile $PROG. Download the appropriate package" echo " for your distribution or source from ftp.gnu.org." exit 1 fi fi } run_libtoolize() { if test x"$libtool_ok" != x"yes"; then echo echo "**Warning**: Version of libtool is less than $LIBTOOL_MIN." echo " Some warning message might occur from libtool" echo fi echo $_echo_n " + Running libtoolize: $_echo_c"; "${libtool}ize" --force --copy >/dev/null 2>&1; echo "done." } #-------------------- # AUTOMAKE #-------------------- detect_automake() { # # expected output from 'type' is # automake is /usr/local/bin/automake # set -- `type automake 2>/dev/null` RETVAL=$? NUM_RESULT=$# RESULT_FILE=$3 if [ $RETVAL -eq 0 -a $NUM_RESULT -eq 3 -a -f "$RESULT_FILE" ]; then AM="`automake --version | parse_version_no`" if [ `expr $AM` -ge "`echo $AUTOMAKE_MIN | parse_version_no`" ]; then automake_ok=yes fi else echo echo "**Error**: You must have \`automake' >= $AUTOMAKE_MIN installed to" echo " compile $PROG. Download the appropriate package" echo " for your distribution or source from ftp.gnu.org." exit 1 fi } run_automake () { if test x"$automake_ok" != x"yes"; then echo echo "**Warning**: Version of automake is less than $AUTOMAKE_MIN." echo " Some warning message might occur from automake" echo fi echo $_echo_n " + Running automake: $_echo_c"; automake --gnu --add-missing --copy -Wno-portability; echo "done." } #-------------------- # ACLOCAL #------------------- detect_aclocal() { # if no automake, don't bother testing for aclocal set -- `type aclocal 2>/dev/null` RETVAL=$? NUM_RESULT=$# RESULT_FILE=$3 if [ $RETVAL -eq 0 -a $NUM_RESULT -eq 3 -a -f "$RESULT_FILE" ]; then AC="`aclocal --version | parse_version_no`" if [ `expr $AC` -ge "`echo $AUTOMAKE_MIN | parse_version_no`" ]; then aclocal_ok=yes fi else echo echo "**Error**: You must have \`aclocal' >= $AUTOMAKE_MIN installed to" echo " compile $PROG. Download the appropriate package" echo " for your distribution or source from ftp.gnu.org." exit 1 fi } run_aclocal () { if test x"$aclocal_ok" != x"yes"; then echo echo "**Warning**: Version of aclocal is less than $AUTOMAKE_MIN." echo " Some warning message might occur from aclocal" echo fi echo $_echo_n " + Running autopoint: $_echo_c" autopoint echo "done." echo $_echo_n " + Running aclocal: $_echo_c" aclocal -I m4 echo "done." } #-------------------- # CONFIGURE #------------------- run_configure () { rm -f config.cache echo " + Running 'configure $@':" if [ -z "$*" ]; then echo " ** If you wish to pass arguments to ./configure, please" echo " ** specify them on the command line." fi if test -f configure; then ./configure "$@" else "$srcdir"/configure "$@" fi } #--------------- # MAIN #--------------- detect_configure_ac cd "$srcdir" detect_autoconf detect_libtool detect_automake detect_aclocal # help: print out usage message # *) run aclocal, autoheader, automake, autoconf, configure case "$1" in aclocal) run_aclocal ;; autoheader) run_autoheader ;; automake) run_aclocal run_automake ;; autoconf) run_aclocal run_autoconf ;; libtoolize) run_libtoolize ;; noconfig) run_libtoolize run_aclocal run_autoheader run_automake run_autoconf ;; *) run_libtoolize run_aclocal run_autoheader run_automake run_autoconf # return to our original directory cd - >/dev/null run_configure "$@" ;; esac xine-lib-1.2/win32/0000755000175000017500000000000014647725152011626 5ustar memexine-lib-1.2/win32/libdvdnav.dsp0000644000175000017500000001350114647725152014307 0ustar meme# Microsoft Developer Studio Project File - Name="libdvdnav" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=libdvdnav - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libdvdnav.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libdvdnav.mak" CFG="libdvdnav - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libdvdnav - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "libdvdnav - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "libdvdnav - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Target_Dir "" LINK32=link.exe # ADD BASE LINK32 /machine:IX86 # ADD LINK32 /machine:IX86 MTL=midl.exe # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src/xine-utils" /I "../src/input/libdvdcss/src" /I "../src" /D "WIN32" /D "NDEBUG" /D "_LIB" /D "DVDNAV_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Release\libdvdnav\libdvdnav.lib" !ELSEIF "$(CFG)" == "libdvdnav - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LINK32=link.exe # ADD BASE LINK32 /machine:IX86 # ADD LINK32 /debug /machine:IX86 /out:"Debug/libdvdnav.lib" /implib:"Debug/libdvdnav.lib" # SUBTRACT LINK32 /pdb:none /nodefaultlib MTL=midl.exe # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src/xine-utils" /I "../src/input/libdvdcss/src" /I "../src" /D "WIN32" /D "_DEBUG" /D "_LIB" /D "DVDNAV_COMPILE" /D "HAVE_CONFIG_H" /FR"Debug/libdvdnav/" /Fp"Debug/libdvdnav/libdvdnav.pch" /YX /Fo"Debug/libdvdnav/" /Fd"Debug/libdvdnav/" /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo /out:"Debug\libdvdnav\libdvdnav.lib" !ENDIF # Begin Target # Name "libdvdnav - Win32 Release" # Name "libdvdnav - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\input\libdvdnav\decoder.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\dvd_input.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\dvd_reader.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\dvd_udf.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\dvdnav.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\highlight.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\ifo_read.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\md5.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\nav_print.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\nav_read.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\navigation.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\read_cache.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\remap.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\searching.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\settings.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\vm.c # End Source File # Begin Source File SOURCE=..\src\input\libdvdnav\vmcmd.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\dvdread\bswap.h # End Source File # Begin Source File SOURCE=..\dvdread\dvd_input.h # End Source File # Begin Source File SOURCE=..\dvdread\dvd_reader.h # End Source File # Begin Source File SOURCE=..\dvdread\dvd_udf.h # End Source File # Begin Source File SOURCE=..\dvdread\ifo_print.h # End Source File # Begin Source File SOURCE=..\dvdread\ifo_read.h # End Source File # Begin Source File SOURCE=..\dvdread\ifo_types.h # End Source File # Begin Source File SOURCE=..\dvdread\nav_print.h # End Source File # Begin Source File SOURCE=..\dvdread\nav_read.h # End Source File # Begin Source File SOURCE=..\dvdread\nav_types.h # End Source File # Begin Source File SOURCE=..\dvdread\types.h # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\libdvdnav.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_asf.dsp0000644000175000017500000001050314647725152015671 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_asf" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_asf - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_asf.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_asf.mak" CFG="xineplug_dmx_asf - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_asf - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_asf - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_asf - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_asf" # PROP Intermediate_Dir "Release/xineplug_dmx_asf" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_ASF_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_ASF_EXPORTS" /D "XINE_COMPILE" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_asf.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_asf - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_asf" # PROP Intermediate_Dir "Debug/xineplug_dmx_asf" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_ASF_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_ASF_EXPORTS" /D "XINE_COMPILE" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_asf.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_asf - Win32 Release" # Name "xineplug_dmx_asf - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_asf.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_mpeg_ts.dsp0000644000175000017500000001062614647725152016564 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_mpeg_ts" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_mpeg_ts - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_ts.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_ts.mak" CFG="xineplug_dmx_mpeg_ts - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_mpeg_ts - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_mpeg_ts - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_mpeg_ts - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_mpeg_ts" # PROP Intermediate_Dir "Release/xineplug_dmx_mpeg_ts" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_TS_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_TS_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_mpeg_ts.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_mpeg_ts - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_mpeg_ts" # PROP Intermediate_Dir "Debug/xineplug_dmx_mpeg_ts" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_TS_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_TS_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_mpeg_ts.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_mpeg_ts - Win32 Release" # Name "xineplug_dmx_mpeg_ts - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_ts.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_inp_net.dsp0000644000175000017500000001073714647725152015715 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_inp_net" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_inp_net - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_net.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_net.mak" CFG="xineplug_inp_net - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_inp_net - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_inp_net - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_inp_net - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_inp_net" # PROP Intermediate_Dir "Release/xineplug_inp_net" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_NET_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_NET_EXPORTS" /D "XINE_COMPILE" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_inp_net.dll" !ELSEIF "$(CFG)" == "xineplug_inp_net - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_inp_net" # PROP Intermediate_Dir "Debug/xineplug_inp_net" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_NET_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_NET_EXPORTS" /D "XINE_COMPILE" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_inp_net.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "xineplug_inp_net - Win32 Release" # Name "xineplug_inp_net - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\input\input_net.c # End Source File # Begin Source File SOURCE=..\src\input\net_buf_ctrl.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_inp_http.dsp0000644000175000017500000001110214647725152016071 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_inp_http" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_inp_http - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_http.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_http.mak" CFG="xineplug_inp_http - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_inp_http - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_inp_http - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_inp_http - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_inp_http" # PROP Intermediate_Dir "Release/xineplug_inp_http" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_HTTP_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_HTTP_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_inp_http.dll" !ELSEIF "$(CFG)" == "xineplug_inp_http - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_inp_http" # PROP Intermediate_Dir "Debug/xineplug_inp_http" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_HTTP_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_HTTP_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_inp_http.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "xineplug_inp_http - Win32 Release" # Name "xineplug_inp_http - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\input\http_helper.c # End Source File # Begin Source File SOURCE=..\src\input\input_http.c # End Source File # Begin Source File SOURCE=..\src\input\net_buf_ctrl.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_ao_out_directx2.dsp0000644000175000017500000001120114647725152017336 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_ao_out_directx2" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_ao_out_directx2 - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_ao_out_directx2.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_ao_out_directx2.mak" CFG="xineplug_ao_out_directx2 - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_ao_out_directx2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_ao_out_directx2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_ao_out_directx2 - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_ao_out_directx2" # PROP Intermediate_Dir "Release/xineplug_ao_out_directx2" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib dsound.lib dxguid.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_ao_out_directx2.dll" !ELSEIF "$(CFG)" == "xineplug_ao_out_directx2 - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_ao_out_directx2" # PROP Intermediate_Dir "Debug/xineplug_ao_out_directx2" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib dsound.lib dxguid.lib pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_ao_out_directx2.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_ao_out_directx2 - Win32 Release" # Name "xineplug_ao_out_directx2 - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\audio_out\audio_directx2_out.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_sputext.dsp0000644000175000017500000001063514647725152016642 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_sputext" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_sputext - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_sputext.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_sputext.mak" CFG="xineplug_dmx_sputext - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_sputext - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_sputext - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_sputext - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_sputext" # PROP Intermediate_Dir "Release/xineplug_dmx_sputext" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SPUTEXT_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SPUTEXT_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_sputext.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_sputext - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_sputext" # PROP Intermediate_Dir "Debug/xineplug_dmx_sputext" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SPUTEXT_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SPUTEXT_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_sputext.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_sputext - Win32 Release" # Name "xineplug_dmx_sputext - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libsputext\demux_sputext.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_audio.dsp0000644000175000017500000001331714647725152016227 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_audio" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_audio - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_audio.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_audio.mak" CFG="xineplug_dmx_audio - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_audio - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_audio - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_audio - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_audio" # PROP Intermediate_Dir "Release/xineplug_dmx_audio" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AUDIO_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /I "../src/libflac" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AUDIO_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_audio.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_audio - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_audio" # PROP Intermediate_Dir "Debug/xineplug_dmx_audio" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AUDIO_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /I "../src/libflac" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AUDIO_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_audio.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_audio - Win32 Release" # Name "xineplug_dmx_audio - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_aac.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_ac3.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_aiff.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_aud.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_cdda.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_dts.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_flac.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_mpc.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_mpgaudio.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_nsf.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_realaudio.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_shn.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_snd.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_voc.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_vox.c # End Source File # Begin Source File SOURCE=..\src\demuxers\demux_wav.c # End Source File # Begin Source File SOURCE=..\src\demuxers\group_audio.c # End Source File # Begin Source File SOURCE=..\src\demuxers\id3.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_vo_out_directx.dsp0000644000175000017500000001122014647725152017302 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_vo_out_directx" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_vo_out_directx - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_vo_out_directx.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_vo_out_directx.mak" CFG="xineplug_vo_out_directx - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_vo_out_directx - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_vo_out_directx - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_vo_out_directx - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_vo_out_directx" # PROP Intermediate_Dir "Release/xineplug_vo_out_directx" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_DIRECTX_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 user32.lib ddraw.lib dxguid.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_vo_out_directx.dll" !ELSEIF "$(CFG)" == "xineplug_vo_out_directx - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_vo_out_directx" # PROP Intermediate_Dir "Debug/xineplug_vo_out_directx" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_DIRECTX_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 user32.lib ddraw.lib dxguid.lib pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_vo_out_directx.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_vo_out_directx - Win32 Release" # Name "xineplug_vo_out_directx - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\video_out\video_out_directx.c # End Source File # Begin Source File SOURCE=..\src\video_out\yuv2rgb.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_mpeg.dsp0000644000175000017500000001053114647725152016051 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_mpeg" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_mpeg - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg.mak" CFG="xineplug_dmx_mpeg - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_mpeg - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_mpeg - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_mpeg - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_mpeg" # PROP Intermediate_Dir "Release/xineplug_dmx_mpeg" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_mpeg.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_mpeg - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_mpeg" # PROP Intermediate_Dir "Debug/xineplug_dmx_mpeg" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_mpeg.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_mpeg - Win32 Release" # Name "xineplug_dmx_mpeg - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_mpeg.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_sputext.dsp0000644000175000017500000001073314647725152017274 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_sputext" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_sputext - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_sputext.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_sputext.mak" CFG="xineplug_decode_sputext - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_sputext - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_sputext - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_sputext - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_sputext" # PROP Intermediate_Dir "Release/xineplug_decode_sputext" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUTEXT_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUTEXT_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_sputext.dll" !ELSEIF "$(CFG)" == "xineplug_decode_sputext - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_sputext" # PROP Intermediate_Dir "Debug/xineplug_decode_sputext" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUTEXT_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUTEXT_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_sputext.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_sputext - Win32 Release" # Name "xineplug_decode_sputext - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libsputext\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_mpeg_pes.dsp0000644000175000017500000001066114647725152016724 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_mpeg_pes" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_mpeg_pes - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_pes.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_pes.mak" CFG="xineplug_dmx_mpeg_pes - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_mpeg_pes - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_mpeg_pes - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_mpeg_pes - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_mpeg_pes" # PROP Intermediate_Dir "Release/xineplug_dmx_mpeg_pes" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_PES_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_PES_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_mpeg_pes.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_mpeg_pes - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_mpeg_pes" # PROP Intermediate_Dir "Debug/xineplug_dmx_mpeg_pes" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_PES_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_PES_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_mpeg_pes.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_mpeg_pes - Win32 Release" # Name "xineplug_dmx_mpeg_pes - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_mpeg_pes.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/libdvdnav.def0000644000175000017500000000303214647725152014255 0ustar meme;------------------------------------------------------------ ; LIBDVDNAV DLL DEFINITIONS FILE EXPORTS DVDOpen DVDClose DVDOpenFile DVDCloseFile DVDReadBlocks navRead_DSI navRead_PCI ifoClose ifoRead_VOBU_ADMAP ifoRead_VTS_ATRT ifoRead_PTL_MAIT ifoRead_PGCI_UT ifoRead_TT_SRPT ifoRead_FP_PGC ifoOpenVMGI ifoRead_TITLE_VOBU_ADMAP ifoRead_PGCIT ifoRead_VTS_PTT_SRPT ifoOpenVTSI ifoPrint dvdnav_set_readahead_flag dvdnav_set_region_mask dvdnav_spu_language_select dvdnav_audio_language_select dvdnav_menu_language_select dvdnav_get_angle_info dvdnav_current_title_info dvdnav_title_play dvdnav_part_play dvdnav_get_number_of_titles dvdnav_get_title_string dvdnav_open dvdnav_close dvdnav_wait_skip dvdnav_get_video_scale_permission dvdnav_get_video_aspect dvdnav_still_skip dvdnav_err_to_string dvdnav_get_next_cache_block dvdnav_free_cache_block dvdnav_get_position dvdnav_sector_search dvdnav_get_current_highlight dvdnav_button_select_and_activate dvdnav_right_button_select dvdnav_left_button_select dvdnav_lower_button_select dvdnav_upper_button_select dvdnav_mouse_select dvdnav_button_select dvdnav_mouse_activate dvdnav_button_activate dvdnav_angle_change dvdnav_prev_pg_search dvdnav_next_pg_search dvdnav_menu_call dvdnav_spu_stream_to_lang dvdnav_get_spu_logical_stream dvdnav_audio_stream_to_lang dvdnav_get_audio_logical_stream dvdnav_is_domain_vts dvdnav_set_PGC_positioning_flag dvdnav_get_number_of_parts dvdnav_reset ;------------------------------------------------------------ ; timer exports gettimeofday setitimer pause sleep nanosleep xine-lib-1.2/win32/xineplug_decode_mpeg2.dsp0000644000175000017500000001324614647725152016574 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_mpeg2" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_mpeg2 - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_mpeg2.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_mpeg2.mak" CFG="xineplug_decode_mpeg2 - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_mpeg2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_mpeg2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_mpeg2 - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_mpeg2" # PROP Intermediate_Dir "Release/xineplug_decode_mpeg2" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MPEG2_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MPEG2_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_mpeg2.dll" !ELSEIF "$(CFG)" == "xineplug_decode_mpeg2 - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_mpeg2" # PROP Intermediate_Dir "Debug/xineplug_decode_mpeg2" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MPEG2_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MPEG2_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_mpeg2.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_mpeg2 - Win32 Release" # Name "xineplug_decode_mpeg2 - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libmpeg2\cpu_state.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\decode.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\header.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\idct.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\idct_altivec.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\idct_mlib.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\idct_mmx.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\libmpeg2_accel.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\motion_comp.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\motion_comp_altivec.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\motion_comp_mlib.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\motion_comp_mmx.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\slice.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\slice_xvmc.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\stats.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\slice_xvmc_vld.c # End Source File # Begin Source File SOURCE=..\src\libmpeg2\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xine_plugin.def0000644000175000017500000000007614647725152014632 0ustar meme; XINE PLUGIN DLL DEFINITIONS FILE EXPORTS xine_plugin_info xine-lib-1.2/win32/xineplug_dmx_avi.dsp0000644000175000017500000001050314647725152015677 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_avi" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_avi - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_avi.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_avi.mak" CFG="xineplug_dmx_avi - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_avi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_avi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_avi - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_avi" # PROP Intermediate_Dir "Release/xineplug_dmx_avi" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AVI_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AVI_EXPORTS" /D "XINE_COMPILE" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_avi.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_avi - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_avi" # PROP Intermediate_Dir "Debug/xineplug_dmx_avi" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AVI_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_AVI_EXPORTS" /D "XINE_COMPILE" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_avi.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_avi - Win32 Release" # Name "xineplug_dmx_avi - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_avi.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_a52.dsp0000644000175000017500000001147614647725152016154 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_a52" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_a52 - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_a52.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_a52.mak" CFG="xineplug_decode_a52 - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_a52 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_a52 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_a52 - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_a52" # PROP Intermediate_Dir "Release/xineplug_decode_a52" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_A52_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_A52_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_a52.dll" !ELSEIF "$(CFG)" == "xineplug_decode_a52 - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_a52" # PROP Intermediate_Dir "Debug/xineplug_decode_a52" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_A52_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_A52_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_a52.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_a52 - Win32 Release" # Name "xineplug_decode_a52 - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\liba52\bit_allocate.c # End Source File # Begin Source File SOURCE=..\src\liba52\bitstream.c # End Source File # Begin Source File SOURCE=..\src\liba52\crc.c # End Source File # Begin Source File SOURCE=..\src\liba52\downmix.c # End Source File # Begin Source File SOURCE=..\src\liba52\imdct.c # End Source File # Begin Source File SOURCE=..\src\liba52\parse.c # End Source File # Begin Source File SOURCE=..\src\liba52\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_real.dsp0000644000175000017500000001053114647725152016044 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_real" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_real - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_real.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_real.mak" CFG="xineplug_dmx_real - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_real - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_real - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_real - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_real" # PROP Intermediate_Dir "Release/xineplug_dmx_real" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_REAL_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_REAL_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_real.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_real - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_real" # PROP Intermediate_Dir "Debug/xineplug_dmx_real" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_REAL_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_REAL_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_real.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_real - Win32 Release" # Name "xineplug_dmx_real - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_real.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_ao_out_none.dsp0000644000175000017500000001066514647725152016566 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_ao_out_none" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_ao_out_none - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_ao_out_none.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_ao_out_none.mak" CFG="xineplug_ao_out_none - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_ao_out_none - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_ao_out_none - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_ao_out_none - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_ao_out_none" # PROP Intermediate_Dir "Release/xineplug_ao_out_none" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_ao_out_none.dll" !ELSEIF "$(CFG)" == "xineplug_ao_out_none - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_ao_out_none" # PROP Intermediate_Dir "Debug/xineplug_ao_out_none" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_ao_out_none.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_ao_out_none - Win32 Release" # Name "xineplug_ao_out_none - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\audio_out\audio_none_out.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_pva.dsp0000644000175000017500000001050314647725152015706 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_pva" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_pva - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_pva.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_pva.mak" CFG="xineplug_dmx_pva - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_pva - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_pva - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_pva - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_pva" # PROP Intermediate_Dir "Release/xineplug_dmx_pva" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_PVA_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_PVA_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_pva.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_pva - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_pva" # PROP Intermediate_Dir "Debug/xineplug_dmx_pva" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_PVA_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_PVA_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_pva.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_pva - Win32 Release" # Name "xineplug_dmx_pva - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_pva.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_lpcm.dsp0000644000175000017500000001066114647725152016513 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_lpcm" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_lpcm - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_lpcm.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_lpcm.mak" CFG="xineplug_decode_lpcm - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_lpcm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_lpcm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_lpcm - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_lpcm" # PROP Intermediate_Dir "Release/xineplug_decode_lpcm" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_LPCM_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_LPCM_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_lpcm.dll" !ELSEIF "$(CFG)" == "xineplug_decode_lpcm - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_lpcm" # PROP Intermediate_Dir "Debug/xineplug_decode_lpcm" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_LPCM_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_LPCM_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_lpcm.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_lpcm - Win32 Release" # Name "xineplug_decode_lpcm - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\liblpcm\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_dts.dsp0000644000175000017500000001114114647725152016344 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_dts" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_dts - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_dts.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_dts.mak" CFG="xineplug_decode_dts - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_dts - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_dts - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_dts - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_dts" # PROP Intermediate_Dir "Release/xineplug_decode_dts" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_DTS_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_DTS_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_dts.dll" !ELSEIF "$(CFG)" == "xineplug_decode_dts - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_dts" # PROP Intermediate_Dir "Debug/xineplug_decode_dts" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_DTS_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_DTS_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_dts.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_dts - Win32 Release" # Name "xineplug_decode_dts - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libdts\bitstream.c # End Source File # Begin Source File SOURCE=..\src\libdts\downmix.c # End Source File # Begin Source File SOURCE=..\src\libdts\parse.c # End Source File # Begin Source File SOURCE=..\src\libdts\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/libxine.dsp0000644000175000017500000001741214647725152013775 0ustar meme# Microsoft Developer Studio Project File - Name="libxine" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=libxine - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libxine.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libxine.mak" CFG="libxine - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libxine - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "libxine - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libxine - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/libxine" # PROP Intermediate_Dir "Release/libxine" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINE_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "include" /I "include/msvc" /I "../include" /I "../intl" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINE_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /D "__WINE_WINDEF_H" /D "__WINE_WINGDI_H" /D "__WINE_VFW_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib pthread.lib zdll.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/bin/libxine-1.dll" # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Moving Xine Fonts PostBuild_Cmds=scripts\post_install.bat Release # End Special Build Tool !ELSEIF "$(CFG)" == "libxine - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/libxine" # PROP Intermediate_Dir "Debug/libxine" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINE_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "include" /I "include/msvc" /I "../include" /I "../intl" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINE_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /D "__WINE_WINDEF_H" /D "__WINE_WINGDI_H" /D "__WINE_VFW_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib pthread.lib zdll.lib /nologo /dll /debug /machine:I386 /out:"Debug/bin/libxine-1.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none # Begin Special Build Tool SOURCE="$(InputPath)" PostBuild_Desc=Moving Xine Fonts PostBuild_Cmds=scripts\post_install.bat Debug # End Special Build Tool !ENDIF # Begin Target # Name "libxine - Win32 Release" # Name "libxine - Win32 Debug" # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\libxine.def # End Source File # End Group # Begin Group "xine-engine" # PROP Default_Filter "" # Begin Source File SOURCE="..\src\xine-engine\audio_decoder.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\alphablend.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\audio_out.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\broadcaster.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\buffer.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\buffer_types.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\configfile.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\demux.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\events.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\info_helper.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\input_cache.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\input_rip.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\io_helper.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\load_plugins.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\metronom.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\osd.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\post.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\refcounter.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\resample.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\scratch.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\tvmode.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\video_decoder.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\video_out.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\video_overlay.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\vo_scale.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\xine.c" # End Source File # Begin Source File SOURCE="..\src\xine-engine\xine_interface.c" # End Source File # End Group # Begin Group "xine-utils" # PROP Default_Filter "" # Begin Source File SOURCE="..\src\xine-utils\color.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\copy.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\cpu_accel.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\list.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\memcpy.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\monitor.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\utils.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\xine_buffer.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\xine_check.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\xine_mutex.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\xmllexer.c" # End Source File # Begin Source File SOURCE="..\src\xine-utils\xmlparser.c" # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_ao_out_directx.dsp0000644000175000017500000001112714647725152017263 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_ao_out_directx" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_ao_out_directx - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_ao_out_directx.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_ao_out_directx.mak" CFG="xineplug_ao_out_directx - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_ao_out_directx - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_ao_out_directx - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_ao_out_directx - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_ao_out_directx" # PROP Intermediate_Dir "Release/xineplug_ao_out_directx" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib dsound.lib dxguid.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_ao_out_directx.dll" !ELSEIF "$(CFG)" == "xineplug_ao_out_directx - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_ao_out_directx" # PROP Intermediate_Dir "Debug/xineplug_ao_out_directx" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib dsound.lib dxguid.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_ao_out_directx.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_ao_out_directx - Win32 Release" # Name "xineplug_ao_out_directx - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\audio_out\audio_directx_out.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_inp_dvd.dsp0000644000175000017500000001115214647725152015674 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_inp_dvd" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_inp_dvd - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_dvd.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_dvd.mak" CFG="xineplug_inp_dvd - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_inp_dvd - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_inp_dvd - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_inp_dvd - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_DVD_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /I "../src/input/libdvdnav" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_DVD_EXPORTS." /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 libdvdnav.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_inp_dvd.dll" /libpath:"Release\libdvdnav" # SUBTRACT LINK32 /incremental:yes !ELSEIF "$(CFG)" == "xineplug_inp_dvd - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_DVD_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /I "../src/input/libdvdnav" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_DVD_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 libdvdnav.lib pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_inp_dvd.dll" /pdbtype:sept /libpath:"Debug\libdvdnav" !ENDIF # Begin Target # Name "xineplug_inp_dvd - Win32 Release" # Name "xineplug_inp_dvd - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\input\input_dvd.c # End Source File # Begin Source File SOURCE=..\src\input\media_helper.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_inp_mms.dsp0000644000175000017500000001127114647725152015715 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_inp_mms" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_inp_mms - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_mms.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_mms.mak" CFG="xineplug_inp_mms - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_inp_mms - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_inp_mms - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_inp_mms - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_inp_mms" # PROP Intermediate_Dir "Release/xineplug_inp_mms" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_MMS_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_MMS_EXPORTS" /D "XINE_COMPILE" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_inp_mms.dll" !ELSEIF "$(CFG)" == "xineplug_inp_mms - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_inp_mms" # PROP Intermediate_Dir "Debug/xineplug_inp_mms" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_MMS_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "HAVE_CONFIG_H" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_MMS_EXPORTS" /D "XINE_COMPILE" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_inp_mms.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "xineplug_inp_mms - Win32 Release" # Name "xineplug_inp_mms - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\input\input_mms.c # End Source File # Begin Source File SOURCE=..\src\input\net_buf_ctrl.c # End Source File # Begin Source File SOURCE=..\src\input\mms.c # End Source File # Begin Source File SOURCE=..\src\input\mmsh.c # End Source File # Begin Source File SOURCE=..\src\input\http_helper.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_mpeg_block.dsp0000644000175000017500000001074114647725152017226 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_mpeg_block" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_mpeg_block - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_block.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_block.mak" CFG="xineplug_dmx_mpeg_block - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_mpeg_block - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_mpeg_block - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_mpeg_block - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_mpeg_block" # PROP Intermediate_Dir "Release/xineplug_dmx_mpeg_block" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_BLOCK_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_BLOCK_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_mpeg_block.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_mpeg_block - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_mpeg_block" # PROP Intermediate_Dir "Debug/xineplug_dmx_mpeg_block" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_BLOCK_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_BLOCK_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_mpeg_block.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_mpeg_block - Win32 Release" # Name "xineplug_dmx_mpeg_block - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_mpeg_block.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_yuv4mpeg2.dsp0000644000175000017500000001070714647725152016770 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_yuv4mpeg2" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_yuv4mpeg2 - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_yuv4mpeg2.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_yuv4mpeg2.mak" CFG="xineplug_dmx_yuv4mpeg2 - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_yuv4mpeg2 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_yuv4mpeg2 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_yuv4mpeg2 - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_yuv4mpeg2" # PROP Intermediate_Dir "Release/xineplug_dmx_yuv4mpeg2" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV4MPEG2_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV4MPEG2_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_yuv4mpeg2.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_yuv4mpeg2 - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_yuv4mpeg2" # PROP Intermediate_Dir "Debug/xineplug_dmx_yuv4mpeg2" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV4MPEG2_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV4MPEG2_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_yuv4mpeg2.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_yuv4mpeg2 - Win32 Release" # Name "xineplug_dmx_yuv4mpeg2 - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_yuv4mpeg2.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_spu.dsp0000644000175000017500000001115714647725152016370 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_spu" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_spu - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_spu.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_spu.mak" CFG="xineplug_decode_spu - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_spu - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_spu - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_spu - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_spu" # PROP Intermediate_Dir "Release/xineplug_decode_spu" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPU_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /I "../src/input/libdvdnav" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPU_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_spu.dll" !ELSEIF "$(CFG)" == "xineplug_decode_spu - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_spu" # PROP Intermediate_Dir "Debug/xineplug_decode_spu" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPU_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /I "../src/input/libdvdnav" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPU_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_spu.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_spu - Win32 Release" # Name "xineplug_decode_spu - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libspudec\nav_read.c # End Source File # Begin Source File SOURCE=..\src\libspudec\spu.c # End Source File # Begin Source File SOURCE=..\src\libspudec\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/libxinesuppt.dsp0000644000175000017500000001134614647725152015071 0ustar meme# Microsoft Developer Studio Project File - Name="libxinesuppt" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=libxinesuppt - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "libxinesuppt.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "libxinesuppt.mak" CFG="libxinesuppt - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "libxinesuppt - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "libxinesuppt - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "libxinesuppt - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/libxinesuppt" # PROP Intermediate_Dir "Release/libxinesuppt" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINESUPPT_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src/xine-engine" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINESUPPT_EXPORTS" /D "__CLEANUP_C" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 winmm.lib /nologo /dll /machine:I386 /out:"Release/bin/libxinesuppt.dll" !ELSEIF "$(CFG)" == "libxinesuppt - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/libxinesuppt" # PROP Intermediate_Dir "Debug/libxinesuppt" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINESUPPT_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../include" /I "../lib" /I "include" /I "include/msvc" /I "../src/xine-engine" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBXINESUPPT_EXPORTS" /D "__CLEANUP_C" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 winmm.lib /nologo /dll /debug /machine:I386 /out:"Debug/bin/libxinesuppt.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "libxinesuppt - Win32 Release" # Name "libxinesuppt - Win32 Debug" # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\libxinesupport.def # End Source File # End Group # Begin Group "Source Files ( posix )" # PROP Default_Filter "" # Begin Source File SOURCE=..\lib\basename.c # End Source File # Begin Source File SOURCE=..\lib\gettimeofday.c # End Source File # Begin Source File SOURCE=..\lib\dirent_msvc.c # End Source File # Begin Source File SOURCE=..\lib\hstrerror.c # End Source File # Begin Source File SOURCE=..\lib\setenv.c # End Source File # Begin Source File SOURCE=..\lib\strndup.c # End Source File # Begin Source File SOURCE=..\lib\strsep.c # End Source File # Begin Source File SOURCE=..\lib\strtok_r.c # End Source File # Begin Source File SOURCE=..\lib\timegm.c # End Source File # Begin Source File SOURCE=..\lib\unsetenv.c # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_nsv.dsp0000644000175000017500000001050314647725152015726 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_nsv" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_nsv - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_nsv.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_nsv.mak" CFG="xineplug_dmx_nsv - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_nsv - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_nsv - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_nsv - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_nsv" # PROP Intermediate_Dir "Release/xineplug_dmx_nsv" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_NSV_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_NSV_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_nsv.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_nsv - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_nsv" # PROP Intermediate_Dir "Debug/xineplug_dmx_nsv" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_NSV_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_NSV_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_nsv.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_nsv - Win32 Release" # Name "xineplug_dmx_nsv - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_nsv.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_inp_cdda.dsp0000644000175000017500000001115314647725152016013 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_inp_cdda" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_inp_cdda - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_cdda.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_cdda.mak" CFG="xineplug_inp_cdda - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_inp_cdda - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_inp_cdda - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_inp_cdda - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_inp_cdda" # PROP Intermediate_Dir "Release/xineplug_inp_cdda" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_CDDA_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_CDDA_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_inp_cdda.dll" !ELSEIF "$(CFG)" == "xineplug_inp_cdda - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_inp_cdda" # PROP Intermediate_Dir "Debug/xineplug_inp_cdda" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_CDDA_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_CDDA_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_inp_cdda.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "xineplug_inp_cdda - Win32 Release" # Name "xineplug_inp_cdda - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\input\base64.c # End Source File # Begin Source File SOURCE=..\src\input\input_cdda.c # End Source File # Begin Source File SOURCE=..\src\input\media_helper.c # End Source File # Begin Source File SOURCE=..\src\input\sha1.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_mpeg_elem.dsp0000644000175000017500000001070214647725152017053 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_mpeg_elem" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_mpeg_elem - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_elem.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_mpeg_elem.mak" CFG="xineplug_dmx_mpeg_elem - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_mpeg_elem - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_mpeg_elem - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_mpeg_elem - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_mpeg_elem" # PROP Intermediate_Dir "Release/xineplug_dmx_mpeg_elem" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_ELEM_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_ELEM_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_mpeg_elem.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_mpeg_elem - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_mpeg_elem" # PROP Intermediate_Dir "Debug/xineplug_dmx_mpeg_elem" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_ELEM_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_MPEG_ELEM_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_mpeg_elem.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_mpeg_elem - Win32 Release" # Name "xineplug_dmx_mpeg_elem - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_elem.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_real.dsp0000644000175000017500000001066114647725152016503 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_real" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_real - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_real.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_real.mak" CFG="xineplug_decode_real - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_real - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_real - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_real - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_real" # PROP Intermediate_Dir "Release/xineplug_decode_real" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_REAL_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_REAL_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_real.dll" !ELSEIF "$(CFG)" == "xineplug_decode_real - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_real" # PROP Intermediate_Dir "Debug/xineplug_decode_real" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_REAL_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_REAL_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_real.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_real - Win32 Release" # Name "xineplug_decode_real - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libreal\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/README0000755000175000017500000000251214647725152012511 0ustar memeCheckout CVS source code: ------------------------ - Using Cygwin or another cvs tool checkout the xine-lib source code from CVS. (If you are using Cygwin make sure that the drive in which you are checking out to is mounted in textmode) Steps for building Xine using MSVC: ---------------------------------- - The autogen/make feature does not work for MSVC. You must generate the proper auto-generated using the autogen.sh script. This script can be run from a Cygwin/MinGW shell window. This script will generate the proper files including xine.h, config.h (a hand generated config.h file exists for MSVC in the win32 dir) - Open up the xine.dsw workspace/project in MSVC. - Unless you have a project file to build css you must select Cancel when prompted for the libdvdcss.dsp file. - Click on the FileView tab. - Build the following projects in this order: libxinesuppt libxine libdvdnav - Next build any desired plugins (decoders/demuxers ...). The ao_out_directx and vo_out_directx are required for Win32. There is an option to use the vo_out_sdl but a sdl.dll must be present for that to take place. There have also been some issues observed with the directX video driver on some machines. NOTE: Project xineplug_dmx_asf currently does not build correctly. - Lastly build the xineui project. - You are now ready to run/debug Xine. xine-lib-1.2/win32/include/0000755000175000017500000000000014647725152013251 5ustar memexine-lib-1.2/win32/include/msvc/0000755000175000017500000000000014647725152014221 5ustar memexine-lib-1.2/win32/include/msvc/inttypes.h0000644000175000017500000001226414647725152016256 0ustar meme/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * WIN32 PORT, * by Matthew Grooms * * inttypes.h - Standard integer definitions. * */ #ifndef _SYS_INTTYPES_H_ #define _SYS_INTTYPES_H_ #include typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; typedef int intptr_t; typedef unsigned int uintptr_t; typedef __int64 intmax_t; typedef unsigned __int64 uintmax_t; typedef signed __int64 intmax_t; typedef unsigned __int64 uintmax_t; #define __WORDSIZE 32 /* The ISO C99 standard specifies that these macros must only be defined if explicitly requested. */ #if !defined __cplusplus || defined __STDC_FORMAT_MACROS # if __WORDSIZE == 64 # define __PRI64_PREFIX "l" # define __PRIPTR_PREFIX "l" # else # define __PRI64_PREFIX "I64" # define __PRIPTR_PREFIX # endif /* Macros for printing format specifiers. */ /* Decimal notation. */ # define PRId8 "d" # define PRId16 "d" # define PRId32 "d" # define PRId64 __PRI64_PREFIX "d" # define PRIdLEAST8 "d" # define PRIdLEAST16 "d" # define PRIdLEAST32 "d" # define PRIdLEAST64 __PRI64_PREFIX "d" # define PRIdFAST8 "d" # define PRIdFAST16 "d" # define PRIdFAST32 "d" # define PRIdFAST64 __PRI64_PREFIX "d" # define PRIi8 "i" # define PRIi16 "i" # define PRIi32 "i" # define PRIi64 __PRI64_PREFIX "i" # define PRIiLEAST8 "i" # define PRIiLEAST16 "i" # define PRIiLEAST32 "i" # define PRIiLEAST64 __PRI64_PREFIX "i" # define PRIiFAST8 "i" # define PRIiFAST16 "i" # define PRIiFAST32 "i" # define PRIiFAST64 __PRI64_PREFIX "i" /* Octal notation. */ # define PRIo8 "o" # define PRIo16 "o" # define PRIo32 "o" # define PRIo64 __PRI64_PREFIX "o" # define PRIoLEAST8 "o" # define PRIoLEAST16 "o" # define PRIoLEAST32 "o" # define PRIoLEAST64 __PRI64_PREFIX "o" # define PRIoFAST8 "o" # define PRIoFAST16 "o" # define PRIoFAST32 "o" # define PRIoFAST64 __PRI64_PREFIX "o" /* Unsigned integers. */ # define PRIu8 "u" # define PRIu16 "u" # define PRIu32 "u" # define PRIu64 __PRI64_PREFIX "u" # define PRIuLEAST8 "u" # define PRIuLEAST16 "u" # define PRIuLEAST32 "u" # define PRIuLEAST64 __PRI64_PREFIX "u" # define PRIuFAST8 "u" # define PRIuFAST16 "u" # define PRIuFAST32 "u" # define PRIuFAST64 __PRI64_PREFIX "u" /* lowercase hexadecimal notation. */ # define PRIx8 "x" # define PRIx16 "x" # define PRIx32 "x" # define PRIx64 __PRI64_PREFIX "x" # define PRIxLEAST8 "x" # define PRIxLEAST16 "x" # define PRIxLEAST32 "x" # define PRIxLEAST64 __PRI64_PREFIX "x" # define PRIxFAST8 "x" # define PRIxFAST16 "x" # define PRIxFAST32 "x" # define PRIxFAST64 __PRI64_PREFIX "x" /* UPPERCASE hexadecimal notation. */ # define PRIX8 "X" # define PRIX16 "X" # define PRIX32 "X" # define PRIX64 __PRI64_PREFIX "X" # define PRIXLEAST8 "X" # define PRIXLEAST16 "X" # define PRIXLEAST32 "X" # define PRIXLEAST64 __PRI64_PREFIX "X" # define PRIXFAST8 "X" # define PRIXFAST16 "X" # define PRIXFAST32 "X" # define PRIXFAST64 __PRI64_PREFIX "X" /* Macros for printing `intmax_t' and `uintmax_t'. */ # define PRIdMAX __PRI64_PREFIX "d" # define PRIiMAX __PRI64_PREFIX "i" # define PRIoMAX __PRI64_PREFIX "o" # define PRIuMAX __PRI64_PREFIX "u" # define PRIxMAX __PRI64_PREFIX "x" # define PRIXMAX __PRI64_PREFIX "X" /* Macros for printing `intptr_t' and `uintptr_t'. */ # define PRIdPTR __PRIPTR_PREFIX "d" # define PRIiPTR __PRIPTR_PREFIX "i" # define PRIoPTR __PRIPTR_PREFIX "o" # define PRIuPTR __PRIPTR_PREFIX "u" # define PRIxPTR __PRIPTR_PREFIX "x" # define PRIXPTR __PRIPTR_PREFIX "X" /* Macros for scanning `intmax_t' and `uintmax_t'. */ #define SCNdMAX __PRI64_PREFIX "d" #define SCNiMAX __PRI64_PREFIX "i" #define SCNoMAX __PRI64_PREFIX "o" #define SCNuMAX __PRI64_PREFIX "u" #define SCNxMAX __PRI64_PREFIX "x" #define SCNXMAX __PRI64_PREFIX "X" #endif /* !defined __cplusplus || defined __STDC_FORMAT_MACROS */ #endif xine-lib-1.2/win32/include/msvc/unistd.h0000644000175000017500000000032014647725152015673 0ustar meme#ifndef UNISTD_H #define UNISTD_H #ifndef STDIN_FILENO # define STDIN_FILENO 0 #endif #ifndef STDOUT_FILENO # define STDOUT_FILENO 1 #endif #ifndef STDERR_FILENO # define STDERR_FILENO 2 #endif #endif xine-lib-1.2/win32/include/msvc/stdint.h0000644000175000017500000000772114647725152015706 0ustar meme/* stdint.h - integer types Copyright 2003 Red Hat, Inc. This file is part of Cygwin. This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ /* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with self program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* Modified original CygWin version for using by MSVC port. */ #ifndef _STDINT_H #define _STDINT_H /* Macros for minimum-width integer constant expressions */ #define INT8_C(x) x #define INT16_C(x) x #define INT32_C(x) x ## L #define INT64_C(x) x ## I64 #define UINT8_C(x) x ## U #define UINT16_C(x) x ## U #define UINT32_C(x) x ## UL #define UINT64_C(x) x ## UI64 /* Macros for greatest-width integer constant expressions */ #define INTMAX_C(x) x ## I64 #define UINTMAX_C(x) x ## UI64 /* Limits of exact-width integer types */ #define INT8_MIN (-128) #define INT16_MIN (-32768) #define INT32_MIN (-2147483647 - 1) #define INT64_MIN (-INT64_C(9223372036854775807) - 1) #define INT8_MAX (127) #define INT16_MAX (32767) #define INT32_MAX (2147483647) #define INT64_MAX (INT64_C(9223372036854775807)) #define UINT8_MAX (255) #define UINT16_MAX (65535) #define UINT32_MAX (4294967295UL) #define UINT64_MAX (UINT64_C(18446744073709551615)) /* Limits of minimum-width integer types */ #define INT_LEAST8_MIN (-128) #define INT_LEAST16_MIN (-32768) #define INT_LEAST32_MIN (-2147483647 - 1) #define INT_LEAST64_MIN (-INT64_C(9223372036854775807) - 1) #define INT_LEAST8_MAX (127) #define INT_LEAST16_MAX (32767) #define INT_LEAST32_MAX (2147483647) #define INT_LEAST64_MAX (INT64_C(9223372036854775807)) #define UINT_LEAST8_MAX (255) #define UINT_LEAST16_MAX (65535) #define UINT_LEAST32_MAX (4294967295UL) #define UINT_LEAST64_MAX (UINT64_C(18446744073709551615)) /* Limits of fastest minimum-width integer types */ #define INT_FAST8_MIN (-128) #define INT_FAST16_MIN (-2147483647 - 1) #define INT_FAST32_MIN (-2147483647 - 1) #define INT_FAST64_MIN (-INT64_C(9223372036854775807) - 1) #define INT_FAST8_MAX (127) #define INT_FAST16_MAX (2147483647) #define INT_FAST32_MAX (2147483647) #define INT_FAST64_MAX (INT64_C(9223372036854775807)) #define UINT_FAST8_MAX (255) #define UINT_FAST16_MAX (4294967295UL) #define UINT_FAST32_MAX (4294967295UL) #define UINT_FAST64_MAX (UINT64_C(18446744073709551615)) /* Limits of integer types capable of holding object pointers */ #define INTPTR_MIN (-2147483647 - 1) #define INTPTR_MAX (2147483647) #define UINTPTR_MAX (4294967295UL) /* Limits of greatest-width integer types */ #define INTMAX_MIN (-INT64_C(9223372036854775807) - 1) #define INTMAX_MAX (INT64_C(9223372036854775807)) #define UINTMAX_MAX (UINT64_C(18446744073709551615)) /* Limits of other integer types */ #ifndef PTRDIFF_MIN #define PTRDIFF_MIN (-2147483647 - 1) #define PTRDIFF_MAX (2147483647) #endif #ifndef SIG_ATOMIC_MIN #define SIG_ATOMIC_MIN (-2147483647 - 1) #endif #ifndef SIG_ATOMIC_MAX #define SIG_ATOMIC_MAX (2147483647) #endif #ifndef SIZE_MAX #define SIZE_MAX (4294967295UL) #endif #ifndef WCHAR_MIN #ifdef __WCHAR_MIN__ #define WCHAR_MIN __WCHAR_MIN__ #define WCHAR_MAX __WCHAR_MAX__ #else #define WCHAR_MIN (0) #define WCHAR_MAX (65535) #endif #endif #ifndef WINT_MIN #define WINT_MIN (-2147483647 - 1) #define WINT_MAX (2147483647) #endif #endif /* _STDINT_H */ xine-lib-1.2/win32/include/msvc/sys/0000755000175000017500000000000014647725152015037 5ustar memexine-lib-1.2/win32/include/msvc/sys/time.h0000644000175000017500000000207214647725152016147 0ustar meme/* * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * WIN32 PORT, * by Matthew Grooms * * sys/time.h - There is no seperate sys/time.h for win32 so we simply * include the standard time header as well as our xine * timer functions. */ #include xine-lib-1.2/win32/include/msvc/config.h0000644000175000017500000004224114647725152015642 0ustar meme/* config.h. Generated by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Adjusting for MSVC from MinGW: * NLS disabled * x86 disabled * inline defined to __inline * HAVE_SYS_PARAM_H disabled * HAVE_DLFCN_H 1 * HAVE_ERRNO_H 1 * HAVE_FCNTL_H 1 * HAVE_ISOC99_PRAGMA 1 * HAVE_MEMCPY 1 * HAVE_STDBOOL_H * HAVE_STDIO_H 1 * HAVE_VSNPRINTF 1 * HAVE_WIN32_CDROM 1 * X_DISPLAY_MISSING 1 * HAVE_MEMCPY 1 * XINE_REL_PLUGINDIR "lib\\xine\\plugins" * HAVE__SNPRINTF 1 * HAVE__VSNPRINTF 1 * HAVE__STRICMP 1 * HAVE__STRNICMP 1 * Disable: * esd, arts, alsa, gnome_vfs, png, sdl, speex, x11, theora */ #ifdef inline /* the strange formatting below is needed to prevent config.status from rewriting it */ # undef \ inline #endif /* Define this if you're running PowerPC architecture */ /* #undef ARCH_PPC */ /* Define this if you're running SPARC architecture */ /* #undef ARCH_SPARC */ /* Define this if you're running x86 architecture */ /* #undef ARCH_X86 */ /* Define this if you're running x86 architecture */ /* #undef ARCH_X86_64 */ /* maximum supported data alignment */ #define ATTRIBUTE_ALIGNED_MAX 64 /* compiler does lsbf in struct bitfields */ /* #undef BITFIELD_LSBF */ /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define 1 if you are compiling using cygwin */ /* #undef CYGWIN */ /* Define to 1 if using `alloca.c'. */ /* #undef C_ALLOCA */ /* what to put between the brackets for empty arrays */ /* #undef EMPTY_ARRAY_SIZE */ /* Define this if you have a Motorola 74xx CPU */ /* #undef ENABLE_ALTIVEC */ /* Define to 1 if translation of program messages to the user's native language is requested. */ /* #undef ENABLE_NLS */ /* Define this if you have Sun UltraSPARC CPU */ /* #undef ENABLE_VIS */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_64BIT */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_ARM */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_DEFAULT */ /* Define to select libmad fixed point arithmetic implementation */ #define FPM_INTEL 1 /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_MIPS */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_PPC */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_SPARC */ /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ /* #undef HAVE_ALLOCA_H */ /* Define this if you have Alsa (libasound) installed */ /* #undef HAVE_ALSA */ /* Define this if you have alsa 0.9.x and more installed */ /* #undef HAVE_ALSA09 */ /* Define this if your asoundlib.h is installed in alsa/ */ /* #undef HAVE_ALSA_ASOUNDLIB_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_ARGZ_H */ /* Define this if you have ARTS (libartsc) installed */ /* #undef HAVE_ARTS */ /* Define to 1 if you have the header file. */ /* #undef HAVE_AVCODEC_H */ /* Define to 1 if you have the `basename' function. */ /* #undef HAVE_BASENAME */ /* Define 1 if you have BSDI-type CD-ROM support */ /* #undef HAVE_BSDI_CDROM */ /* Define to 1 if you have the header file. */ /* #undef HAVE_BYTESWAP_H */ /* Define to 1 if you have the `bzero' function. */ /* #undef HAVE_BZERO */ /* Define this if you have CDROM ioctls */ /* #undef HAVE_CDROM_IOCTLS */ /* Define to 1 if you have the header file. */ /* #undef HAVE_COREFOUNDATION_CFBASE_H */ /* Define 1 if you have Darwin OS X-type CD-ROM support */ /* #undef HAVE_DARWIN_CDROM */ /* Define to 1 if you have the `dcgettext' function. */ /* #undef HAVE_DCGETTEXT */ /* Define this if you have DirectX */ #define HAVE_DIRECTX 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define this if you have a suitable version of libdvdnav */ /* #undef HAVE_DVDNAV */ /* Define to 1 if you have the header file. */ /* #undef HAVE_DVD_H */ /* Define to 1 if you have the header file. */ #define HAVE_ERRNO_H 1 /* Define this if you have ESD (libesd) installed */ /* #undef HAVE_ESD */ /* Define to 1 if you have the header file. */ /* #undef HAVE_EXECINFO_H */ /* Define this if you have linux framebuffer support */ /* #undef HAVE_FB */ /* Define to 1 if you have the header file. */ #define HAVE_FCNTL_H 1 /* Define to 1 if you have the `feof_unlocked' function. */ /* #undef HAVE_FEOF_UNLOCKED */ /* Define this if you have ffmpeg library */ /* #undef HAVE_FFMPEG */ /* Define to 1 if you have the `fgets_unlocked' function. */ /* #undef HAVE_FGETS_UNLOCKED */ /* Define 1 if you have FreeBSD CD-ROM support */ /* #undef HAVE_FREEBSD_CDROM */ /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ /* #undef HAVE_FSEEKO */ /* Define this if you have freetype2 library */ /* #undef HAVE_FT2 */ /* Define to 1 if you have the `getcwd' function. */ #define HAVE_GETCWD 1 /* Define to 1 if you have the `getegid' function. */ /* #undef HAVE_GETEGID */ /* Define to 1 if you have the `geteuid' function. */ /* #undef HAVE_GETEUID */ /* Define to 1 if you have the `getgid' function. */ /* #undef HAVE_GETGID */ /* Define to 1 if you have the `getpagesize' function. */ #define HAVE_GETPAGESIZE 1 /* Define to 1 if you have the `getpwuid_r' function. */ /* #undef HAVE_GETPWUID_R */ /* Define if the GNU gettext() function is already present or preinstalled. */ /* #undef HAVE_GETTEXT */ /* Define to 1 if you have the `getuid' function. */ /* #undef HAVE_GETUID */ /* Define to 1 if you have the header file. */ /* #undef HAVE_GLOB_H */ /* Define this if you have GLU support available */ /* #undef HAVE_GLU */ /* Define this if you have GLut support available */ /* #undef HAVE_GLUT */ /* Define this if you have gnome-vfs installed */ /* #undef HAVE_GNOME_VFS */ /* Define to 1 if you have the `hstrerror' function. */ /* #undef HAVE_HSTRERROR */ /* Define if you have the iconv() function. */ /* #undef HAVE_ICONV */ /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if the system has the type `int_fast8_t'. */ #define HAVE_INT_FAST8_T 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_IOKIT_IOKITLIB_H */ /* Define this if you have ip_mreqn in netinet/in.h */ /* #undef HAVE_IP_MREQN */ /* Define this if you have a usable IRIX al interface available */ /* #undef HAVE_IRIXAL */ /* Supports ISO _Pragma() macro */ #define HAVE_ISOC99_PRAGMA 1 /* Define this if you have kernel statistics available via kstat interface */ /* #undef HAVE_KSTAT */ /* Define if you have and nl_langinfo(CODESET). */ /* #undef HAVE_LANGINFO_CODESET */ /* Define if your file defines LC_MESSAGES. */ /* #undef HAVE_LC_MESSAGES */ /* Define this if you have libfame mpeg encoder installed (fame.sf.net) */ /* #undef HAVE_LIBFAME */ /* Define to 1 if you have the header file. */ /* #undef HAVE_LIBGEN_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_LIBINTL_H */ /* Define this if you have png library */ /* #undef HAVE_LIBPNG */ /* Define to 1 if you have the `posix4' library (-lposix4). */ /* #undef HAVE_LIBPOSIX4 */ /* Define this if you have librte mpeg encoder installed (zapping.sf.net) */ /* #undef HAVE_LIBRTE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define 1 if you have Linux-type CD-ROM support */ /* #undef HAVE_LINUX_CDROM */ /* Define to 1 if you have the header file. */ /* #undef HAVE_LINUX_CDROM_H */ /* Define 1 if timeout is in cdrom_generic_command struct */ /* #undef HAVE_LINUX_CDROM_TIMEOUT */ /* Define to 1 if you have the header file. */ /* #undef HAVE_LINUX_VERSION_H */ /* Define to 1 if you have the header file. */ #define HAVE_LOCALE_H 1 /* Define this if the 'lrintf' function is declared in math.h */ #define HAVE_LRINTF 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the `memcpy' function. */ #define HAVE_MEMCPY 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `mempcpy' function. */ #define HAVE_MEMPCPY 1 /* Define to 1 if you have the `memset' function. */ #define HAVE_MEMSET 1 /* Define this if you have mlib installed */ /* #undef HAVE_MLIB */ /* Define to 1 if you have a working `mmap' system call. */ /* #undef HAVE_MMAP */ /* define this if you have libmodplug installed */ /* #undef HAVE_MODPLUG */ /* Define to 1 if you have the `munmap' function. */ /* #undef HAVE_MUNMAP */ /* Define to 1 if you have the `nanosleep' function. */ /* #undef HAVE_NANOSLEEP */ /* Define this if you have libfame 0.8.10 or above */ /* #undef HAVE_NEW_LIBFAME */ /* Define to 1 if you have the header file. */ /* #undef HAVE_NL_TYPES_H */ /* Define this if you have OpenGL support available */ /* #undef HAVE_OPENGL */ /* Define to 1 if you have the header file. */ /* #undef HAVE_POSTPROCESS_H */ /* Define to 1 if you have the `putenv' function. */ #define HAVE_PUTENV 1 /* Define this if you have SDL library installed */ /* #undef HAVE_SDL */ /* Define to 1 if you have the `setenv' function. */ /* #undef HAVE_SETENV */ /* Define to 1 if you have the `setlocale' function. */ #define HAVE_SETLOCALE 1 /* Define to 1 if you have the `sigaction' function. */ /* #undef HAVE_SIGACTION */ /* Define to 1 if you have the `sigset' function. */ /* #undef HAVE_SIGSET */ /* Define to 1 if you have the `snprintf' function. */ /* #undef HAVE_SNPRINTF */ /* Define 1 if you have Solaris CD-ROM support */ /* #undef HAVE_SOLARIS_CDROM */ /* Define this if you have speex */ /* #undef HAVE_SPEEX */ /* Define to 1 if speex headers are eg. */ /* #undef HAVE_SPEEX_SUBDIR */ /* Define to 1 if you have the header file. */ #define HAVE_STDBOOL_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDDEF_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDIO_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `stpcpy' function. */ /* #undef HAVE_STPCPY */ /* Define to 1 if you have the `strcasecmp' function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the `strchr' function. */ #define HAVE_STRCHR 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strpbrk' function. */ #define HAVE_STRPBRK 1 /* Define to 1 if you have the `strsep' function. */ /* #undef HAVE_STRSEP */ /* Define to 1 if you have the `strtoul' function. */ #define HAVE_STRTOUL 1 /* Define this if your asoundlib.h is installed in sys/ */ /* #undef HAVE_SYS_ASOUNDLIB_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_CDIO_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_IOCTL_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_MIXER_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_MMAN_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_PARAM_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_TIMES_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define this if you have theora */ /* #undef HAVE_THEORA */ /* Define if struct tm has the tm_gmtoff member. */ /* #undef HAVE_TM_GMTOFF */ /* Define to 1 if you have the `tsearch' function. */ /* #undef HAVE_TSEARCH */ /* Define to 1 if you have the header file. */ /* #undef HAVE_UCONTEXT_H */ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define this if you have a suitable version of libcdio/libvcd */ /* #undef HAVE_VCDNAV */ /* Define to 1 if you have the `vsnprintf' function. */ #define HAVE_VSNPRINTF 1 /* Define to 1 if you have the `vsscanf' function. */ #define HAVE_VSSCANF 1 /* Define 1 if you have MinGW CD-ROM support */ #define HAVE_WIN32_CDROM 1 /* Define this if you have X11R6 installed */ /* #undef HAVE_X11 */ /* Define this if you have libXinerama installed */ /* #undef HAVE_XINERAMA */ /* Define this if you have libXv installed */ /* #undef HAVE_XV */ /* Define this if you have libXvMC installed */ /* #undef HAVE_XVMC */ /* Define this if you have libXvMC.a */ /* #undef HAVE_XVMC_STATIC */ /* Define this if you have libXv.a */ /* #undef HAVE_XV_STATIC */ /* Define to 1 if you have the `__argz_count' function. */ /* #undef HAVE___ARGZ_COUNT */ /* Define to 1 if you have the `__argz_next' function. */ /* #undef HAVE___ARGZ_NEXT */ /* Define to 1 if you have the `__argz_stringify' function. */ /* #undef HAVE___ARGZ_STRINGIFY */ /* host os/cpu identifier */ /* #undef HOST_ARCH */ /* Define this if built on Mac OS X/Darwin */ /* #undef HOST_OS_DARWIN */ /* Define as const if the declaration of iconv() needs const. */ /* #undef ICONV_CONST */ /* Define this if you have mlib installed */ /* #undef LIBMPEG2_MLIB */ /* Define 1 if you are compiling using MinGW */ /* #undef MINGW32 */ /* Define this if you want to load mlib lazily */ /* #undef MLIB_LAZYLOAD */ /* Name of package */ #define PACKAGE "xine-lib" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "" /* Define to the version of this package. */ #define PACKAGE_VERSION "" /* The size of a `int', as computed by sizeof. */ /* #undef SIZEOF_INT */ /* The size of a `long', as computed by sizeof. */ #define SIZEOF_LONG 4 /* The size of a `long long', as computed by sizeof. */ /* #undef SIZEOF_LONG_LONG */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1-rc6" /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ /* #undef WORDS_BIGENDIAN */ /* Path where aclocal m4 files will be. */ #define XINE_ACFLAGS "-I ${prefix}/share/aclocal" /* Define this to osd fonts dir location */ #define XINE_FONTDIR xine_get_fontdir() /* Path where catalog files will be. */ #define XINE_LOCALEDIR xine_get_localedir() /* xine major version number */ #define XINE_MAJOR 1 /* xine minor version number */ #define XINE_MINOR 0 /* Define this to plugins directory location */ #define XINE_PLUGINDIR xine_get_plugindir() /* xine sub version number */ #define XINE_SUB 0 /* Define to 1 if the X Window System is missing or not being used. */ #define X_DISPLAY_MISSING 1 /* enable warnings about being development release */ /* #undef _DEVELOPMENT_ */ /* enable GNU libc extension */ /* #undef _GNU_SOURCE */ /* Define this if you are ISO C9X compliant */ #define _ISOC9X_SOURCE 1 /* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ /* #undef _LARGEFILE_SOURCE */ /* Define this if you're running x86 architecture */ #define __i386__ 1 /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define to `__inline__' or `__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #define inline __inline /* Define to `long' if does not define. */ /* #undef off_t */ /* Define to `unsigned' if does not define. */ /* #undef size_t */ /* Define the real type of socklen_t */ #define socklen_t size_t /* define ssize_t to __int64 if it's missing in default includes */ #define ssize_t __int64 /* Define this to font directory relative to prefix */ #define XINE_REL_FONTDIR "share\\xine\\libxine1\\fonts" /* Define this to font directory relative to prefix */ #define XINE_REL_LOCALEDIR "share\\locale" /* Define this to plugin directory relative to execution prefix */ #define XINE_REL_PLUGINDIR "lib\\xine\\plugins" #define HAVE__SNPRINTF 1 #define HAVE__VSNPRINTF 1 #define HAVE__STRICMP 1 #define HAVE__STRNICMP 1 #include "os_internal.h" xine-lib-1.2/win32/include/dlfcn.h0000644000175000017500000000236314647725152014514 0ustar meme/* * Copyright (C) 2000-2007 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * WIN32 PORT, * by Matthew Grooms * * dlfcn.h - Mimic the dl functions of a *nix system * */ #ifndef _DLFCN_H #define _DLFCN_H #include #define RTLD_LAZY 0 #define RTLD_GLOBAL 0 #define dlopen( A, B ) ( void * )LoadLibrary( A ) #define dlclose( A ) FreeLibrary( (HMODULE)A ) #define dlsym( A, B ) ( void * ) GetProcAddress( (HMODULE)A, B ) #define dlerror() "dlerror" #endif xine-lib-1.2/win32/libxine.def0000644000175000017500000001332414647725152013743 0ustar meme;------------------------------------------------------------ ; LIBXINE DLL DEFINITIONS FILE EXPORTS ;---- xine-utils ---- xine_mm_accel xine_fast_memcpy xine_probe_fast_memcpy xine_profiler_init xine_profiler_allocate_slot xine_profiler_start_count xine_profiler_stop_count xine_profiler_print_results xine_xmalloc xine_xmalloc_aligned xine_get_homedir xine_chomp xine_usec_sleep xine_hexdump xine_list_new xine_list_free xine_list_is_empty xine_buffer_init _xine_buffer_free xine_buffer_dup _xine_buffer_copyin xine_buffer_copyout _xine_buffer_set _xine_buffer_strcat _xine_buffer_strcpy xine_buffer_get_size _xine_buffer_ensure_size xml_parser_init xml_parser_build_tree xml_parser_free_tree xml_parser_get_property xml_parser_get_property_int xml_parser_dump_tree lexer_init lexer_get_token xine_guess_spu_encoding xine_xprintf ; ---- xine posix exports ---- _xine_private_basename _xine_private_gettimeofday _xine_private_hstrerror _xine_private_setenv _xine_private_strcasestr _xine_private_strndup _xine_private_strsep _xine_private_strtok_r ;---- xine-engine ---- xine_init xine_exit xine_play xine_stop xine_eject xine_open xine_close xine_new xine_dispose xine_stream_new xine_stream_master_slave xine_trick_mode xine_engine_set_param xine_engine_get_param xine_get_status _x_get_audio_channel xine_get_audio_lang ;get_audio_decoder ;xine_get_spu_channel xine_get_spu_lang ;xine_select_spu_channel _x_get_spu_decoder xine_get_browsable_input_plugin_ids xine_get_browse_mrls xine_get_autoplay_input_plugin_ids xine_get_autoplay_mrls xine_get_file_extensions xine_get_mime_types xine_get_demux_for_mime_type xine_get_input_plugin_description xine_list_video_output_plugins xine_list_audio_output_plugins xine_get_current_frame xine_get_meta_info xine_open_video_driver xine_open_audio_driver xine_close_audio_driver xine_close_video_driver xine_log xine_get_log xine_get_error xine_port_send_gui_data xine_get_version_string xine_get_version xine_check_version xine_set_param xine_get_param xine_get_current_frame xine_get_current_vpts ;xine_get_current_info xine_get_stream_info xine_get_pos_length ;xine_set_speed xine_post_init xine_list_post_plugins xine_list_post_plugins_typed xine_post_list_inputs xine_post_list_outputs xine_post_input xine_post_output xine_post_wire xine_post_wire_video_port xine_post_wire_audio_port xine_get_video_source xine_get_audio_source xine_post_dispose xine_get_log_section_count xine_get_log_names xine_register_log_cb xine_event_create_listener_thread xine_event_new_queue xine_event_send xine_event_free xine_event_get xine_event_wait xine_event_dispose_queue xine_osd_new xine_osd_draw_point xine_osd_draw_line xine_osd_draw_rect xine_osd_draw_text xine_osd_draw_bitmap xine_osd_get_text_size xine_osd_set_font xine_osd_set_encoding xine_osd_set_position xine_osd_show xine_osd_hide xine_osd_clear xine_osd_set_text_palette xine_osd_get_palette xine_osd_set_palette xine_osd_free xine_tvmode_init xine_tvmode_use xine_tvmode_set_tvsystem xine_tvmode_switch xine_tvmode_size xine_tvmode_exit _x_handle_stream_end _x_message _x_find_input_plugin _x_find_demux_plugin _x_find_demux_plugin_by_name _x_find_demux_plugin_last_probe _x_rip_plugin_get_instance _x_video_decoder_init _x_video_decoder_shutdown _x_audio_decoder_init _x_audio_decoder_shutdown _x_extra_info_reset _x_extra_info_merge _x_get_current_info _x_demux_flush_engine _x_demux_control_nop _x_demux_control_newpts _x_demux_control_headers_done _x_demux_control_start _x_demux_control_end _x_demux_start_thread _x_demux_stop_thread _x_demux_read_header _x_demux_check_extension _x_demux_send_data _x_demux_read_send_data _x_demux_send_mrl_reference _x_read_abort _x_action_pending _x_get_video_decoder _x_free_video_decoder _x_get_audio_decoder _x_free_audio_decoder _x_get_spu_decoder _x_free_spu_decoder _x_set_speed _x_select_spu_channel _x_get_audio_channel _x_get_spu_channel xine_config_register_string xine_config_register_range xine_config_register_enum xine_config_register_num xine_config_register_bool xine_config_get_first_entry xine_config_get_next_entry xine_config_lookup_entry xine_config_update_entry xine_config_load xine_config_save xine_config_reset xine_config_update_entry _x_fourcc_to_buf_video _x_buf_video_name _x_formattag_to_buf_audio _x_buf_audio_name _x_bmiheader_le2me _x_waveformatex_le2me _x_vo_scale_init _x_vo_scale_compute_output_size _x_vo_scale_compute_ideal_size _x_vo_scale_aspect_ratio_name _x_io_select _x_io_tcp_connect _x_io_tcp_read _x_io_tcp_write _x_io_tcp_read_line _x_io_tcp_connect_finish _x_io_file_read _x_io_file_write _x_stream_info_set _x_stream_info_reset _x_stream_info_public_reset _x_stream_info_get _x_stream_info_get_public _x_meta_info_set _x_meta_info_set_utf8 _x_meta_info_set_generic _x_meta_info_set_multi _x_meta_info_n_set _x_meta_info_reset _x_meta_info_public_reset _x_meta_info_get _x_meta_info_get_public _x_get_current_info _x_spu_decoder_sleep init_yuv_conversion init_yuv_planes free_yuv_planes yuv444_to_yuy2 yuv9_to_yv12 yuv411_to_yv12 yv12_to_yuy2 yuy2_to_yv12 y_r_table y_g_table y_b_table u_r_table u_g_table u_b_table v_r_table v_g_table v_b_table yv12_to_yv12 yuy2_to_yuy2 _x_cache_plugin_get_instance _x_new_refcounter _x_refcounter_inc _x_refcounter_dec _x_refcounter_dispose _x_alphablend_free _x_alphablend_init _x_blend_rgb16 _x_blend_rgb24 _x_blend_rgb32 _x_blend_xx44 _x_blend_yuv _x_blend_yuy2 _x_init_xx44_palette _x_clear_xx44_palette _x_dispose_xx44_palette _x_xx44_to_xvmc_palette xine-lib-1.2/win32/xineplug_dmx_slave.dsp0000644000175000017500000001055714647725152016243 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_slave" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_slave - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_slave.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_slave.mak" CFG="xineplug_dmx_slave - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_slave - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_slave - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_slave - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_slave" # PROP Intermediate_Dir "Release/xineplug_dmx_slave" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SLAVE_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SLAVE_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_slave.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_slave - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_slave" # PROP Intermediate_Dir "Debug/xineplug_dmx_slave" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SLAVE_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_SLAVE_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_slave.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_slave - Win32 Release" # Name "xineplug_dmx_slave - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_slave.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_vo_out_sdl.dsp0000644000175000017500000001067114647725152016433 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_vo_out_sdl" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_vo_out_sdl - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_vo_out_sdl.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_vo_out_sdl.mak" CFG="xineplug_vo_out_sdl - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_vo_out_sdl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_vo_out_sdl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_vo_out_sdl - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_vo_out_sdl" # PROP Intermediate_Dir "Release/xineplug_vo_out_sdl" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_SDL_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_SDL_EXPORTS" /D "XINE_COMPILE" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 SDL.lib SDLmain.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_vo_out_sdl.dll" !ELSEIF "$(CFG)" == "xineplug_vo_out_sdl - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_vo_out_sdl" # PROP Intermediate_Dir "Debug/xineplug_vo_out_sdl" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_SDL_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_VO_OUT_SDL_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 SDL.lib SDLmain.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_vo_out_sdl.dll" /pdbtype:sept /libpath:"lib" !ENDIF # Begin Target # Name "xineplug_vo_out_sdl - Win32 Release" # Name "xineplug_vo_out_sdl - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\video_out\video_out_sdl.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/libxinesupport.def0000644000175000017500000000105114647725152015372 0ustar meme;------------------------------------------------------------ ; LIBXINESUPPORT DLL DEFINITIONS FILE EXPORTS ;------------------------------------------------------------ ; dirent exports _xine_private_opendir _xine_private_closedir _xine_private_readdir _xine_private_rewinddir ;------------------------------------------------------------ ; xine posix exports _xine_private_basename _xine_private_gettimeofday _xine_private_hstrerror _xine_private_setenv _xine_private_strcasestr _xine_private_strndup _xine_private_strsep _xine_private_strtok_r xine-lib-1.2/win32/xine.dsw0000644000175000017500000003174114647725152013316 0ustar memeMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "libdvdnav"=".\libdvdnav.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency }}} ############################################################################### Project: "libxine"=".\libxine.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency }}} ############################################################################### Project: "libxinesuppt"=".\libxinesuppt.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "xineplug_ao_out_directx"=".\xineplug_ao_out_directx.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_ao_out_none"=".\xineplug_ao_out_none.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_a52"=".\xineplug_decode_a52.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_ao_out_directx2"=".\xineplug_ao_out_directx2.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency }}} ############################################################################### Project: "xineplug_decode_dts"=".\xineplug_decode_dts.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_ff"=".\xineplug_decode_ff.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency }}} ############################################################################### Project: "xineplug_decode_lpcm"=".\xineplug_decode_lpcm.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_mad"=".\xineplug_decode_mad.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_mpeg2"=".\xineplug_decode_mpeg2.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_real"=".\xineplug_decode_real.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_spu"=".\xineplug_decode_spu.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_spucc"=".\xineplug_decode_spucc.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_decode_sputext"=".\xineplug_decode_sputext.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_asf"=".\xineplug_dmx_asf.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_audio"=".\xineplug_dmx_audio.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_avi"=".\xineplug_dmx_avi.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_lpcm"=".\xineplug_dmx_lpcm.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_mpeg"=".\xineplug_dmx_mpeg.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_mpeg_elem"=".\xineplug_dmx_mpeg_elem.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_mpeg_block"=".\xineplug_dmx_mpeg_block.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_mpeg_pes"=".\xineplug_dmx_mpeg_pes.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_mpeg_ts"=".\xineplug_dmx_mpeg_ts.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_nsv"=".\xineplug_dmx_nsv.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_pva"=".\xineplug_dmx_pva.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_real"=".\xineplug_dmx_real.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_slave"=".\xineplug_dmx_slave.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_sputext"=".\xineplug_dmx_sputext.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_yuv4mpeg2"=".\xineplug_dmx_yuv4mpeg2.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_dmx_yuv_frames"=".\xineplug_dmx_yuv_frames.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_inp_cdda"=".\xineplug_inp_cdda.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_inp_dvd"=".\xineplug_inp_dvd.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency Begin Project Dependency Project_Dep_Name libdvdnav End Project Dependency }}} ############################################################################### Project: "xineplug_inp_file"=".\xineplug_inp_file.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_inp_http"=".\xineplug_inp_http.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_inp_net"=".\xineplug_inp_net.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_vo_out_directx"=".\xineplug_vo_out_directx.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_vo_out_none"=".\xineplug_vo_out_none.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency }}} ############################################################################### Project: "xineplug_vo_out_sdl"=".\xineplug_vo_out_sdl.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name libxine End Project Dependency Begin Project Dependency Project_Dep_Name libxinesuppt End Project Dependency }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### xine-lib-1.2/win32/xineconsole.dsp0000644000175000017500000001071714647725152014672 0ustar meme# Microsoft Developer Studio Project File - Name="xineconsole" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=xineconsole - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineconsole.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineconsole.mak" CFG="xineconsole - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineconsole - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "xineconsole - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "xineconsole - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/console" # PROP Intermediate_Dir "Release/console" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "source" /I "include" /I "../src/video_out" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"Release/bin/xineconsole.exe" !ELSEIF "$(CFG)" == "xineconsole - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineconsole" # PROP Intermediate_Dir "Debug/xineconsole" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I ".." /I "include" /I "../include" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /I "../src/video_out" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /map /debug /machine:I386 /out:"Debug/bin/xineconsole.exe" /pdbtype:sept !ENDIF # Begin Target # Name "xineconsole - Win32 Release" # Name "xineconsole - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\source\xineconsole.cpp # End Source File # Begin Source File SOURCE=.\source\xineint.cpp # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/.hgignore0000644000175000017500000000001414647725152013424 0ustar meme*.plg *.ncb xine-lib-1.2/win32/xineplug_dmx_lpcm.dsp0000644000175000017500000001062314647725152016056 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_lpcm" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_lpcm - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_lpcm.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_lpcm.mak" CFG="xineplug_dmx_lpcm - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_lpcm - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_lpcm - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_lpcm - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_lpcm" # PROP Intermediate_Dir "Release/xineplug_dmx_lpcm" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_LPCM_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_LPCM_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_lpcm.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_lpcm - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_lpcm" # PROP Intermediate_Dir "Debug/xineplug_dmx_lpcm" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_LPCM_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_LPCM_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_lpcm.dll" /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "xineplug_dmx_lpcm - Win32 Release" # Name "xineplug_dmx_lpcm - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\liblpcm\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_mad.dsp0000644000175000017500000001206114647725152016315 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_mad" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_mad - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_mad.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_mad.mak" CFG="xineplug_decode_mad - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_mad - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_mad - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_mad - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_mad" # PROP Intermediate_Dir "Release/xineplug_decode_mad" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MAD_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MAD_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /D "FPM_DEFAULT" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_mad.dll" !ELSEIF "$(CFG)" == "xineplug_decode_mad - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_mad" # PROP Intermediate_Dir "Debug/xineplug_decode_mad" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MAD_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_MAD_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /D "FPM_DEFAULT" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_mad.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_mad - Win32 Release" # Name "xineplug_decode_mad - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libmad\bit.c # End Source File # Begin Source File SOURCE=..\src\libmad\fixed.c # End Source File # Begin Source File SOURCE=..\src\libmad\frame.c # End Source File # Begin Source File SOURCE=..\src\libmad\huffman.c # End Source File # Begin Source File SOURCE=..\src\libmad\layer12.c # End Source File # Begin Source File SOURCE=..\src\libmad\layer3.c # End Source File # Begin Source File SOURCE=..\src\libmad\stream.c # End Source File # Begin Source File SOURCE=..\src\libmad\synth.c # End Source File # Begin Source File SOURCE=..\src\libmad\timer.c # End Source File # Begin Source File SOURCE=..\src\libmad\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_inp_file.dsp0000644000175000017500000001053214647725152016037 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_inp_file" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_inp_file - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_file.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_inp_file.mak" CFG="xineplug_inp_file - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_inp_file - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_inp_file - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_inp_file - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_inp_file" # PROP Intermediate_Dir "Release/xineplug_inp_file" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_FILE_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_FILE_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_inp_file.dll" !ELSEIF "$(CFG)" == "xineplug_inp_file - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_inp_file" # PROP Intermediate_Dir "Debug/xineplug_inp_file" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_FILE_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_INP_FILE_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_inp_file.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_inp_file - Win32 Release" # Name "xineplug_inp_file - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\input\input_file.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/scripts/0000755000175000017500000000000014647725152013315 5ustar memexine-lib-1.2/win32/scripts/post_install.bat0000644000175000017500000000137714647725152016530 0ustar memeECHO copying fonts to %1\share\xine\libxine1\fonts ... mkdir %1\share mkdir %1\share\xine mkdir %1\share\xine\libxine1 mkdir %1\share\xine\libxine1\fonts xcopy /Y /s ..\misc\fonts\*.gz %1\share\xine\libxine1\fonts ECHO copying headers to %1\include\xine mkdir %1\include mkdir %1\include\xine xcopy /Y /s ..\include\xine.h %1\include xcopy /Y /s ..\lib\os_types.h %1\include\xine xcopy /Y /s ..\src\xine-engine\*.h %1\include\xine xcopy /Y /s ..\src\xine-utils\*.h %1\include\xine xcopy /Y /s ..\src\demuxers\demux.h %1\include\xine xcopy /Y /s ..\src\input\input_plugin.h %1\include\xine del %1\include\xine\accel_xvmc.h del %1\include\xine\bswap.h del %1\include\xine\lrb.h del %1\include\xine\ppcasm_string.h del %1\include\xine\xine_check.h xine-lib-1.2/win32/scripts/ffmpeg_win32.patch0000644000175000017500000000551514647725152016632 0ustar meme#! /bin/sh # # Fix cross build with SDL. # Install also dvdata.h. # Patching script for M$VC clients. # patch -p0 < $0 cp libavcodec/avcodec.h libavcodec/avcodec.h.dllimports; sed libavcodec/avcodec.h.dllimports -e 's/extern AVCodec/_DL_IMPORT extern AVCodec/' > libavcodec/avcodec.h exit 0 Index: configure =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/configure,v retrieving revision 1.159 diff -u -p -u -p -r1.159 configure --- configure 21 Jan 2005 22:16:04 -0000 1.159 +++ configure 19 Feb 2005 16:15:29 -0000 @@ -942,9 +942,10 @@ EOF sdl_too_old=no sdl=no -if (sdl-config --version) >/dev/null 2>&1 ; then -if $cc -o $TMPE `sdl-config --cflags` $TMPC `sdl-config --libs` > /dev/null 2>&1 ; then -_sdlversion=`sdl-config --version | sed 's/[^0-9]//g'` +SDL_CONFIG="${cross_prefix}sdl-config" +if ("${SDL_CONFIG}" --version) >/dev/null 2>&1 ; then +if $cc -o $TMPE `"${SDL_CONFIG}" --cflags` $TMPC `"${SDL_CONFIG}" --libs` > /dev/null 2>&1 ; then +_sdlversion=`"${SDL_CONFIG}" --version | sed 's/[^0-9]//g'` if test "$_sdlversion" -lt 121 ; then sdl_too_old=yes else @@ -1225,8 +1226,8 @@ if test "$pthreads" = "yes" ; then fi if test "$sdl" = "yes" ; then echo "CONFIG_SDL=yes" >> config.mak - echo "SDL_LIBS=`sdl-config --libs`" >> config.mak - echo "SDL_CFLAGS=`sdl-config --cflags`" >> config.mak + echo "SDL_LIBS=`"${SDL_CONFIG}" --libs`" >> config.mak + echo "SDL_CFLAGS=`"${SDL_CONFIG}" --cflags`" >> config.mak fi if test "$texi2html" = "yes"; then echo "BUILD_DOC=yes" >> config.mak Index: libavcodec/Makefile =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/Makefile,v retrieving revision 1.167 --- libavcodec/Makefile.orig 2005-10-29 15:07:40.000000000 +0200 +++ libavcodec/Makefile 2005-10-29 15:22:47.000000000 +0200 @@ -487,6 +487,7 @@ installlib: all install-headers install-headers: mkdir -p "$(prefix)/include/ffmpeg" install -m 644 $(SRC_PATH)/libavcodec/avcodec.h \ + $(SRC_PATH)/libavcodec/dvdata.h \ "$(prefix)/include/ffmpeg" install -d $(libdir)/pkgconfig install -m 644 ../libavcodec.pc $(libdir)/pkgconfig Index: libavutil/common.h =================================================================== RCS file: /cvsroot/ffmpeg/ffmpeg/libavcodec/common.h,v retrieving revision 1.145 diff -u -p -u -p -r1.145 common.h --- libavutil/common.h 12 Jan 2005 01:44:01 -0000 1.145 +++ libavutil/common.h 19 Feb 2005 16:15:29 -0000 @@ -64,6 +64,13 @@ extern const struct AVOption avoptions_w #endif /* HAVE_AV_CONFIG_H */ +/* for MSVC clients */ +#if !defined(HAVE_AV_CONFIG_H) && defined(_MSC_VER) +# define _DL_IMPORT __declspec(dllimport) +#else +# define _DL_IMPORT +#endif + /* Suppress restrict if it was not defined in config.h. */ #ifndef restrict # define restrict xine-lib-1.2/win32/xineplug_decode_ff.dsp0000644000175000017500000001223714647725152016154 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_ff" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_ff - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_ff.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_ff.mak" CFG="xineplug_decode_ff - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_ff - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_ff - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_ff - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_ff" # PROP Intermediate_Dir "Release/xineplug_decode_ff" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_FF_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src/xine-engine" /I "../src" /I "../src/xine-utils" /I "../../ffmpeg/include/ffmpeg" /I "../../ffmpeg/include/postproc" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /D "HAVE_FFMPEG" /D "XINEPLUG_DECODE_FF_EXPORTS" /D "XINE_COMPILE" /D "SIMPLE_IDCT" /D "RUNTIME_CPUDETECT" /D "USE_FASTMEMCPY" /D "CONFIG_RISKY" /D "CONFIG_DECODERS" /D "XINE_MPEG_ENCODER" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 avcodec.lib pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_ff.dll" /libpath:"Release" /libpath:"../../ffmpeg/" !ELSEIF "$(CFG)" == "xineplug_decode_ff - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_ff" # PROP Intermediate_Dir "Debug/xineplug_decode_ff" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_FF_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src/xine-engine" /I "../src" /I "../src/xine-utils" /I "../../ffmpeg/include/ffmpeg" /I "../../ffmpeg/include/postproc" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "HAVE_CONFIG_H" /D "HAVE_FFMPEG" /D "XINEPLUG_DECODE_FF_EXPORTS" /D "XINE_COMPILE" /D "SIMPLE_IDCT" /D "RUNTIME_CPUDETECT" /D "USE_FASTMEMCPY" /D "CONFIG_RISKY" /D "CONFIG_DECODERS" /D "XINE_MPEG_ENCODER" /FD /GZ /c # SUBTRACT CPP /X /YX # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 avcodec.lib pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_ff.dll" /pdbtype:sept /libpath:"Debug" /libpath:"../../ffmpeg/" !ENDIF # Begin Target # Name "xineplug_decode_ff - Win32 Release" # Name "xineplug_decode_ff - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libffmpeg\audio_decoder.c # End Source File # Begin Source File SOURCE=..\src\libffmpeg\mpeg_parser.c # End Source File # Begin Source File SOURCE=..\src\libffmpeg\video_decoder.c # End Source File # Begin Source File SOURCE=..\src\libffmpeg\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_vo_out_none.dsp0000644000175000017500000001071514647725152016607 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_vo_out_none" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_vo_out_none - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_vo_out_none.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_vo_out_none.mak" CFG="xineplug_vo_out_none - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_vo_out_none - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_vo_out_none - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_vo_out_none - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_vo_out_none" # PROP Intermediate_Dir "Release/xineplug_vo_out_none" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 pthread.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_vo_out_none.dll" !ELSEIF "$(CFG)" == "xineplug_vo_out_none - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_vo_out_none" # PROP Intermediate_Dir "Debug/xineplug_vo_out_none" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_AO_OUT_DIRECTX_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /FR /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 pthread.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_vo_out_none.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_vo_out_none - Win32 Release" # Name "xineplug_vo_out_none - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\video_out\video_out_none.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_decode_spucc.dsp0000644000175000017500000001114514647725152016673 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_decode_spucc" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_decode_spucc - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_spucc.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_decode_spucc.mak" CFG="xineplug_decode_spucc - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_decode_spucc - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_decode_spucc - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_decode_spucc - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_decode_spucc" # PROP Intermediate_Dir "Release/xineplug_decode_spucc" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUCC_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUCC_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 wsock32.lib /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_decode_spucc.dll" !ELSEIF "$(CFG)" == "xineplug_decode_spucc - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_decode_spucc" # PROP Intermediate_Dir "Debug/xineplug_decode_spucc" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUCC_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DECODE_SPUCC_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 wsock32.lib /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_decode_spucc.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_decode_spucc - Win32 Release" # Name "xineplug_decode_spucc - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\libspucc\cc_decoder.c # End Source File # Begin Source File SOURCE=..\src\libspucc\cc_decoder.h # End Source File # Begin Source File SOURCE=..\src\libspucc\xine_decoder.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/xineplug_dmx_yuv_frames.dsp0000644000175000017500000001073514647725152017307 0ustar meme# Microsoft Developer Studio Project File - Name="xineplug_dmx_yuv_frames" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=xineplug_dmx_yuv_frames - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_yuv_frames.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "xineplug_dmx_yuv_frames.mak" CFG="xineplug_dmx_yuv_frames - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "xineplug_dmx_yuv_frames - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "xineplug_dmx_yuv_frames - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "xineplug_dmx_yuv_frames - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release/xineplug_dmx_yuv_frames" # PROP Intermediate_Dir "Release/xineplug_dmx_yuv_frames" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV_FRAMES_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /GX /O2 /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV_FRAMES_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 /nologo /dll /machine:I386 /out:"Release/lib/xine/plugins/xineplug_dmx_yuv_frames.dll" !ELSEIF "$(CFG)" == "xineplug_dmx_yuv_frames - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug/xineplug_dmx_yuv_frames" # PROP Intermediate_Dir "Debug/xineplug_dmx_yuv_frames" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" LIB32=link.exe # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV_FRAMES_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "../lib" /I "../include" /I "include" /I "include/msvc" /I "../src" /I "../src/xine-engine" /I "../src/xine-utils" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "XINEPLUG_DMX_YUV_FRAMES_EXPORTS" /D "XINE_COMPILE" /D "HAVE_CONFIG_H" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 /nologo /dll /debug /machine:I386 /out:"Debug/lib/xine/plugins/xineplug_dmx_yuv_frames.dll" /pdbtype:sept !ENDIF # Begin Target # Name "xineplug_dmx_yuv_frames - Win32 Release" # Name "xineplug_dmx_yuv_frames - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\src\demuxers\demux_yuv_frames.c # End Source File # End Group # Begin Group "DLL Defs" # PROP Default_Filter "" # Begin Source File SOURCE=.\xine_plugin.def # End Source File # End Group # End Target # End Project xine-lib-1.2/win32/config.h0000755000175000017500000003221214647725152013247 0ustar meme/* config.h. Generated by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ #ifndef _CONFIG_H_ #define _CONFIG_H_ #if defined(WIN32) #include #include #include #endif /* Define this if you're running PowerPC architecture */ /* #undef ARCH_PPC */ /* Define this if you're running x86 architecture */ /*define ARCH_X86*/ /* maximum supported data alignment */ #define ATTRIBUTE_ALIGNED_MAX 64 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP systems. This function is required for `alloca.c' support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define to 1 if using `alloca.c'. */ /* #undef C_ALLOCA */ /* Define this if you have a Motorola 74xx CPU */ /* #undef ENABLE_ALTIVEC */ /* Define to 1 if translation of program messages to the user's native language is requested. */ #undef ENABLE_NLS /* Define this if you have Sun UltraSPARC CPU */ /* #undef ENABLE_VIS */ /* Define to select libmad fixed pointarithmetic implementation */ /* #undef FPM_64BIT */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_ARM */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_DEFAULT */ /* Define to select libmad fixed point arithmetic implementation */ #define FPM_INTEL 1 /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_MIPS */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_PPC */ /* Define to select libmad fixed point arithmetic implementation */ /* #undef FPM_SPARC */ /* Define to 1 if you have `alloca', as a function or macro. */ #define HAVE_ALLOCA 1 /* Define to 1 if you have and it should be used (not on Ultrix). */ #define HAVE_ALLOCA_H 1 /* Define this if you have Alsa (libasound) installed */ /* #undef HAVE_ALSA */ /* Define this if you have alsa 0.9.x and more installed */ /* #undef HAVE_ALSA09 */ /* Define this if your asoundlib.h is installed in alsa/ */ /* #undef HAVE_ALSA_ASOUNDLIB_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_ARGZ_H */ /* Define this if you have ARTS (libartsc) installed */ /* #undef HAVE_ARTS */ /* Define to 1 if you have the header file. */ /* #undef HAVE_BYTESWAP_H */ /* Define this if you have CDROM ioctls */ /* #undef HAVE_CDROM_IOCTLS */ /* Define to 1 if you have the `dcgettext' function. */ #define HAVE_DCGETTEXT 1 /* Define to 1 if you have the header file. */ #define HAVE_DLFCN_H 1 /* Define this if you have a suitable version of libdvdnav */ /* #undef HAVE_DVDNAV */ /* Define this if you have ESD (libesd) installed */ /* #undef HAVE_ESD */ /* Define this if you have linux framebuffer support */ /* #undef HAVE_FB */ /* Define to 1 if you have the `feof_unlocked' function. */ /* #undef HAVE_FEOF_UNLOCKED */ /* Define to 1 if you have the `fgets_unlocked' function. */ /* #undef HAVE_FGETS_UNLOCKED */ /* Define to 1 if you have the `getcwd' function. */ #define HAVE_GETCWD 1 /* Define to 1 if you have the `getegid' function. */ #define HAVE_GETEGID 1 /* Define to 1 if you have the `geteuid' function. */ #define HAVE_GETEUID 1 /* Define to 1 if you have the `getgid' function. */ #define HAVE_GETGID 1 /* Define to 1 if you have the `getpagesize' function. */ #define HAVE_GETPAGESIZE 1 /* Define to 1 if you have the `getpwuid_r' function. */ #define HAVE_GETPWUID_R 1 /* Define if the GNU gettext() function is already present or preinstalled. */ #define HAVE_GETTEXT 1 /* Define to 1 if you have the `getuid' function. */ #define HAVE_GETUID 1 /* Define this if you have GLU support available */ /* #undef HAVE_GLU */ /* Define this if you have GLut support available */ /* #undef HAVE_GLUT */ /* Define this if you have gnome-vfs installed */ /* #undef HAVE_GNOME_VFS */ /* Define if you have the iconv() function. */ /* #undef HAVE_ICONV */ /* Define to 1 if you have the header file. */ /* #undef HAVE_INTTYPES_H */ /* Define this if you have ip_mreqn in netinet/in.h */ /* #undef HAVE_IP_MREQN */ /* Define this if you have a usable IRIX al interface available */ /* #undef HAVE_IRIXAL */ /* Define this if you have kernel statistics available via kstat interface */ /* #undef HAVE_KSTAT */ /* Define if you have and nl_langinfo(CODESET). */ /* #undef HAVE_LANGINFO_CODESET */ /* Define if your file defines LC_MESSAGES. */ #define HAVE_LC_MESSAGES 1 /* Define this if you have libfame mpeg encoder installed (fame.sf.net) */ /* #undef HAVE_LIBFAME */ /* Define to 1 if you have the `posix4' library (-lposix4). */ /* #undef HAVE_LIBPOSIX4 */ /* Define this if you have librte mpeg encoder installed (zapping.sf.net) */ /* #undef HAVE_LIBRTE */ /* Define to 1 if you have the header file. */ #define HAVE_LIMITS_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_LINUX_CDROM_H */ /* Define to 1 if you have the header file. */ #define HAVE_LOCALE_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MALLOC_H 1 /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `mempcpy' function. */ /* #undef HAVE_MEMPCPY */ /* Define this if you have mlib installed */ /* #undef HAVE_MLIB */ /* Define to 1 if you have a working `mmap' system call. */ /* #undef HAVE_MMAP */ /* Define to 1 if you have the `munmap' function. */ #define HAVE_MUNMAP 1 /* Define to 1 if you have the `nanosleep' function. */ /* #undef HAVE_NANOSLEEP */ /* Define this if you have libfame 0.8.10 or above */ /* #undef HAVE_NEW_LIBFAME */ /* Define to 1 if you have the header file. */ /* #undef HAVE_NL_TYPES_H */ /* Define this if you have OpenGL support available */ /* #undef HAVE_OPENGL */ /* Define to 1 if you have the `putenv' function. */ #define HAVE_PUTENV 1 /* Define this if you have SDL library installed */ /* #undef HAVE_SDL */ /* Define to 1 if you have the `setenv' function. */ #define HAVE_SETENV 1 /* Define to 1 if you have the `setlocale' function. */ #define HAVE_SETLOCALE 1 /* Define to 1 if you have the `sigaction' function. */ #define HAVE_SIGACTION 1 /* Define to 1 if you have the `sigset' function. */ /* #undef HAVE_SIGSET */ /* Define to 1 if you have the header file. */ #define HAVE_STDDEF_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_STDINT_H */ /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the `stpcpy' function. */ /* #undef HAVE_STPCPY */ /* Define to 1 if you have the `strcasecmp' function. */ #define HAVE_STRCASECMP 1 /* Define to 1 if you have the `strchr' function. */ #define HAVE_STRCHR 1 /* Define to 1 if you have the `strdup' function. */ #define HAVE_STRDUP 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if you have the `strpbrk' function. */ #define HAVE_STRPBRK 1 /* Define to 1 if you have the `strsep' function. */ #define HAVE_STRSEP 1 /* Define to 1 if you have the `strtoul' function. */ #define HAVE_STRTOUL 1 /* Define this if your asoundlib.h is installed in sys/ */ /* #undef HAVE_SYS_ASOUNDLIB_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_CDIO_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_MIXER_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_MMAN_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_PARAM_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the `tsearch' function. */ /* #undef HAVE_TSEARCH */ /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Define to 1 if you have the `vsscanf' function. */ #define HAVE_VSSCANF 1 /* Define this if you have X11R6 installed */ /* #undef HAVE_X11 */ /* Define this if you have libXinerama installed */ /* #undef HAVE_XINERAMA */ /* Define this if you have libXv installed */ /* #undef HAVE_XV */ /* Define this if you have libXv.a */ /* #undef HAVE_XV_STATIC */ /* Define to 1 if you have the `__argz_count' function. */ /* #undef HAVE___ARGZ_COUNT */ /* Define to 1 if you have the `__argz_next' function. */ /* #undef HAVE___ARGZ_NEXT */ /* Define to 1 if you have the `__argz_stringify' function. */ /* #undef HAVE___ARGZ_STRINGIFY */ /* Define as const if the declaration of iconv() needs const. */ /* #undef ICONV_CONST */ /* Define this if you have mlib installed */ /* #undef LIBA52_MLIB */ /* Define this if you have mlib installed */ /* #undef LIBMPEG2_MLIB */ /* Name of package */ #define PACKAGE "xine-lib" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "" /* Define to the version of this package. */ #define PACKAGE_VERSION "" /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1-beta12" /* xine major version number */ #define XINE_MAJOR 1 /* xine minor version number */ #define XINE_MINOR 0 /* xine sub version number */ #define XINE_SUB 0 /* Define to 1 if the X Window System is missing or not being used. */ #define X_DISPLAY_MISSING 1 /* Define to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel and VAX). */ /* #undef WORDS_BIGENDIAN */ /* Define this if you want nvtvd tvmode support */ /* #undef XINE_HAVE_NVTV */ /*#undef HAVE_DVDCSS_DVDCSS_H */ #if defined(WIN32) #define ssize_t __int64 #ifndef PATH_MAX #define PATH_MAX MAX_PATH #endif /* Ridiculous hack to return valid xine support * directories. These should be read from * a registry entry set at install time. */ static char tmp_win32_path[ 1024 ]; static char * exec_path_append_subdir( char * string ) { char * tmpchar; char * cmdline; char * back_slash; char * fore_slash; char * last_slash; // get program exec command line cmdline = GetCommandLine(); // check for " at beginning of string if( *cmdline == '\"' ) { // copy command line, skip first quote strcpy( tmp_win32_path, cmdline + 1 ); // terminate at second set of quotes tmpchar = strchr( tmp_win32_path, '\"' ); *tmpchar = 0; } else { // copy command line strcpy( tmp_win32_path, cmdline ); // terminate at first space tmpchar = strchr( tmp_win32_path, ' ' ); if (tmpchar) *tmpchar = 0; } // find the last occurance of a back // slash or fore slash back_slash = strrchr( tmp_win32_path, '\\' ); fore_slash = strrchr( tmp_win32_path, '/' ); // make sure the last back slash was not // after a drive letter if( back_slash > tmp_win32_path ) if( *( back_slash - 1 ) == ':' ) back_slash = 0; // which slash was the latter slash if( back_slash > fore_slash ) last_slash = back_slash; else last_slash = fore_slash; // detect if we had a relative or // distiguished path ( had a slash ) if( last_slash ) { // we had a slash charachter in our // command line *( last_slash + 1 ) = 0; // if had a string to append to the path if( string ) strcat( tmp_win32_path, string ); } else { // no slash, assume local directory strcpy( tmp_win32_path, "./" ); // if had a string to append to the path if( string ) strcat( tmp_win32_path, string ); } return tmp_win32_path; } #define XINE_PLUGINDIR exec_path_append_subdir( "plugins" ) #define XINE_FONTDIR exec_path_append_subdir( "fonts" ) #define XINE_LOCALEDIR exec_path_append_subdir( "locale" ) #define S_ISDIR(m) ((m) & _S_IFDIR) #define S_ISREG(m) ((m) & _S_IFREG) #define S_ISBLK(m) 0 #define S_ISCHR(m) 0 #else /* Path where catalog files will be. */ #define XINE_LOCALEDIR "/usr/local/share/locale" /* Define this to plugins directory location */ #define XINE_PLUGINDIR "/usr/local/lib/xine/plugins/1.0.0" /* Define this if you're running x86 architecture */ #define __i386__ 1 /* Path where aclocal m4 files will be. */ #define XINE_ACFLAGS "-I ${prefix}/share/aclocal" #endif /* Define to empty if `const' does not conform to ANSI C. */ /* #undef const */ /* Define as `__inline' if that's what the C compiler calls it, or to nothing if it is not supported. */ /* #undef inline */ /* Define to `long' if does not define. */ /* #undef off_t */ /* Define to `unsigned' if does not define. */ /* #undef size_t */ #endif /* defined CONFIG_H */ xine-lib-1.2/doc/0000755000175000017500000000000014647725152011431 5ustar memexine-lib-1.2/doc/man/0000755000175000017500000000000014647725152012204 5ustar memexine-lib-1.2/doc/man/en/0000755000175000017500000000000014647725152012606 5ustar memexine-lib-1.2/doc/man/en/xine.50000644000175000017500000002357314647725152013651 0ustar meme.\" -*-Nroff-*- .\"" .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .TH XINE 5 2005-06-15 "The xine project" .\" NAME should be all caps, SECTION should be 1-8, maybe w/ subsection .\" other parms are allowed: see man(7), man(1) .\"" .SH NAME xine \- a free video player .SH MRL (media resource locator) MRLs are similar to URLs in your web browser. They describe the media to read from. Valid MRLs may be plain file names or one of the following (see also the notes below): .TP \(bu Filesystem: .br .BI file: .br .BI fifo: .br .BI stdin:/ .LP .TP \(bu CD and DVD: .br .BI dvd:/[ device_name ][/ title [. part ]] .br .BI dvd:/ DVD_image_file [/ title [. part ]] .br .BI dvd:/ DVD_directory [/ title [. part ]] .br (use the path of the directory which contains VIDEO_TS) .br .BI vcd://[ CD_image_or_device_name ][@[ letter ] number ] .br .BI vcdo:// track_number .br .BI cdda:/[ device ][/ track_number ] .LP .TP \(bu Video devices: .br .BI v4l://[ tuner_device / frequency ] .br .BI v4l2:// tuner_device .br .BI dvb:// channel_number .br (nth channel in your channels.conf) .br .BI dvb:// channel_name .br .BI dvbc:// channel_name : tuning_parameters .br .BI dvbs:// channel_name : tuning_parameters .br .BI dvbt:// channel_name : tuning_parameters .br .BI dvba:// channel_name : tuning_parameters .br .BI pvr:/ tmp_files_path ! saved_files_path ! max_page_age .br (for WinTV PVR 250 and 350) .LP .TP \(bu Network: .br .BI http:// host... .br .BI tcp:// host [: port ] .br .BI udp:// host [: port [?iface= interface ]] .br .BI rtp:// host [: port [?iface= interface ]] .br (default port for tcp, udp and rtp is 7658) .br .BI smb://... .br .BI mms:// host... .br .BI pnm:// host... .br .BI rtsp:// host... "\fR (requires Real codecs)" .br .LP Additional input plugins will provide additional MRL types. The ones listed above are available with stock libxine. \fBNOTE:\fP where a file name is required, the \fIfull path must be provided\fP - from a shell, you can normally use \fB"$PWD/file"\fP or \fB"$(pwd)/file"\fP or \fB"\`pwd\`/file"\fP if the file is in the current directory. (Which one depends on your shell; all three work in bash. Also, normal URL encoding rules apply; `%', in particular, must be encoded as `%25'.) As of xine-lib 1.1.3, the DVD title number may be 0 (select navigation) and the chapter number may be 0 (full title). .SS VCD MRL Syntax A simple \fBvcd:/\fP runs the default item (e.g. perhaps track 1 or entry 0) using the default VCD device (perhaps /dev/cdrom). Both the default item and default device are user-configurable. It is however also possible to specify both Video CD device/filename and item explicitly in the MRL. For example \fBvcd:/dev/dvd\fP specifies the default entry using device /dev/dvd which might useful if this is your DVD which is different than your CD-ROM device and your DVD drive can play CD's. And \fBvcd://test_svcd_ntsc.cue\fP specifies the cue file for CD image on disk. (test_svcd_ntsc.bin is the corresponding bin file, but using that won't work.) After the optional device name or file name, you can name the kind of unit, preceded by a colon. An MRL which ends in a colon is like not adding it at all: the default entry type and number is used. Items come in 4 flavours: "\fBTrack\fP", "\fBEntry\fP", "\fBPlayback\fP" and "\fBSegment\fP". These units are indicated with the capital first letter of each type: \fBT\fP, \fBE\fP, \fBP\fP, \fBS\fP, \fBs\fP. An uppercase \fBS\fP in the MRL display indicates a NTSC segment while a lowercase \fBs\fP indicates a PAL segment. However, when you enter an MRL, the case of these letters is insignificant. Depending on the Video CD, you might not have any playable segments (\fBS\fP,\fBs\fP) or playback control (\fBP\fP). If you give a MRL that refers to a playback control entry but there is no playback control, your playback number will silently be converted into the corresponding entry number. You can configure various things that affect MRLs are selected when there is some ambiguity in the MRL name. \fImedia.vcd.autoplay\fP sets what kind of unit to to use in a MRL is none is given. Another configuration setting, \fIvcd.device\fP, determines what device to use if that part is not given. When you hit the VCD button, that is equivalent to entering \fBvcd:/\fP and thus these two configuration settings are used to expand the MRL. Some examples of MRLs are given below. In the examples, we assume the following configuration settings: .TP .BI vcd:// Play (navigate) default item (in this case Entry ID 0) from the default device (in this case set to /dev/cdrom) .TP .BI vcd://@ Same as above .TP .BI vcd:///dev/cdrom@ Same effect as above since the default device is set to /dev/cdrom. .TP .BI vcd:///dev/cdrom@E0 Same as above. But note that this is because we have autoplay:entry which is no longer the default value. .TP .BI vcd:///dev/cdrom2@ Play (navigate) the default item of /dev/cdrom2 .TP .BI vcd:///dev/cdrom2 should be same as above but is currently broken? .TP .BI vcd:///dev/cdrom2@T1 Play Track 1 from /dev/cdrom2 .TP .BI vcd:///dev/cdrom@S1 Play segment 1 from /dev/cdrom. This assumes that there *is* a segment 1. Check the MRL list to see if that is the case. .TP .BI vcd://@P1 Play playlist item 1 from default device. If there is no playback control, the MRL will be converted into vcd:/@E0. Again check the MRL list to see if there is a P1. .TP .BI vcd://@P1* Probably same as above. .TP .BI vcd:///dev/cdrom@E1 Play Entry id 1 from default device. .TP .BI vcd://@S0 Play segment 0 from default device. .TP .BI vcd://@3 Play track 3 from default device. .TP .BI vcd:///dev/cdrom2:1 Play track 1 from /dev/cdrom2. .TP .BI vcd:///tmp/ntsc.cue@ Play default item (E0) of /tmp/ntsc.bin. Note trailing \fB@\fP. .TP .BI vcd://ntsc.cue/@E0 Play entry 0 of ntsc.bin. .TP .BI vcd:///tmp/ntsc.nrg/@E0 Play entry 0 of /tmp/ntsc.nrg (Nero file). Works for some simple Nero images. .br .SS DVB .PP DVB MRLs require that xine-lib/channels.conf exists in $XDG_CONFIG_HOME/ or ~/.config/ and contains valid data. This can be obtained by generating a tuning file using the LinuxTV DVB apps utility "scan" (or "dvbscan" if you're using a version newer than 1.1.0): .PP .B scan -o zap /usr/share/doc/dvb-utils/examples/scan/dvb-t/uk-PontopPike >~/.config/xine-lib/channels.conf .PP (This example is for the writer's local transmitter, using a file from the Debian dvb-utils package.) .PP For the dvbc, dvbs and dvbt MRLs, tuning parameters are expected, taking one of the following forms: .TP .B DVB-S :::::: .TP .B DVB-C ::::::: .TP .B DVB-T ::::::::::: .TP .B DVB-A :::: .PP The individual parameters are: .TP 20 .B frequency number, usually in kHz .TP 20 .B polarisation `v' or `h' .TP 20 .B sat-no unsigned long, usually 0 .TP 20 .B sym-rate symbol rate in MSyms/sec .TP 20 .B inversion INVERSION_ON, INVERSION_OFF, INVERSION_AUTO .TP 20 .B fec, fec-hp, fec-lp FEC_1_2, FEC_2_3, FEC_3_4 ... FEC_8_9, FEC_AUTO, FEC_NONE .TP 20 .B qam QPSK, QAM_128, QAM_16 ... .TP 20 .B bw BANDWIDTH_6_MHZ, BANDWIDTH_7_MHZ, BANDWIDTH_8_MHZ .TP 20 .B transmission-mode TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K .TP 20 .B guardlist GUARD_INTERVAL_1_4, GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_32, .TP 20 .B hierarchy-info HIERARCHY_1, HIERARCHY_2, HIERARCHY_4, HIERARCHY_NONE .TP 20 .B vpid video program ID .TP 20 .B apid audio program ID .TP 20 .B service-id service ID (needed for now/next information etc.) .PP The following keyboard & mouse inputs may be accepted: .TP 24 .B Menu 2 Start/stop recording .TP 24 .B Menu 3 Toggle zoom .TP 24 .B Menu 7 Toggle now/next display .TP 24 .B Previous/Next Chapter Previous/next channel .TP 24 .B Mouse wheel & button 1 Scroll through channel list & select the highlighted channel .SH SUBTITLE .B external subtitle files (any mrl) .br Text subtitle files may be appended to the MRL:. .TP .BI #subtitle: This is the normal way to define the subtitle file to use. The frontend will not take any notice of the subtitle file. For example: .br .I file://home/user/wibble.mpg#subtitle:/home/user/wibble.sub .br (Note that some front ends can detect subtitles files where the name differs as shown in the example.) .br .SH STREAM OPTIONS .br After a delimiting \fB#\fP you can add several stream parameters: .TP .B novideo Video will be ignored. .TP .B noaudio Audio will be ignored. .TP .B nospu Subpictures will be ignored. .TP .BI demux: Specify the demux plugin to use. .TP .BI volume: Set audio volume. .TP .BI compression: Set audio dynamic range compression. .TP .BI : Assign a new value to any config entry. .TP .BI save: Save the stream (if allowed) to the named file, relative to the directory given by the option "media.capture.save_dir". .TP .B change configuration option 'on the fly': .br You can change a configuration option at any time, using the special .B cfg:/ MRL style. The syntax is: .br cfg:/ : .br Unlike stream config option, you can change anything \fIbefore\fP playing the stream. .SH "SEE ALSO" \fBxine\fP(1), \fBaaxine\fP(1), \fBgxine\fP(1), \fBtoxine\fP(1), \fBtotem\fP(1), \fBkaffeine\fP(1) ... .br The programs are documented fully on the xine home page: .UR http://www.xine-project.org/ .IR "http://www.xine-project.org/" .UE .SH AUTHOR This text was extracted from the xine man page by Darren Salt . The xine man page was written by Siggi Langauf for the xine project. Lots of additions by Guenter Bartsch , Daniel Caujolle-Bert , Rocky Bernstein , and Philipp Hahn . xine-lib-1.2/doc/man/en/Makefile.am0000644000175000017500000000055214647725152014644 0ustar memeinclude $(top_srcdir)/misc/Makefile.common STATICMANS = xine-config.1 xine.5 DYNAMICMANS = xine-list-@XINE_SERIES@.1 man_MANS = $(STATICMANS) $(DYNAMICMANS) BUILT_SOURCES = $(DYNAMICMANS) DISTCLEANFILES = $(DYNAMICMANS) EXTRA_DIST = $(STATICMANS) xine-list.1.in xine-list-@XINE_SERIES@.1: xine-list.1.in $(SED) -e 's/@XL@/xine\-list\-@XINE_SERIES@/' $< >$@ xine-lib-1.2/doc/man/en/xine-config.10000644000175000017500000000443114647725152015100 0ustar meme.de TQ .br .ns .TP \\$1 .. .TH XINE 1 2001-08-28 "The xine project" .SH NAME xine\-config - script to get information about the installed version of libxine .SH SYNOPSIS .B xine\-config [\-\-prefix\fI[=DIR]\fP] [\-\-exec\-prefix\fI[=DIR]\fP] [\-\-version] [\-\-libs] [\-\-cflags] [\-\-objcflags] [\-\-plugindir] [\-\-datadir] [\-\-scriptdir] [\-\-localedir] .SH DESCRIPTION .PP \fIxine\-config is DEPRECATED. Use pkg\-config instead.\fP .PP \fIxine\-config\fP is a tool that is used to determine the compiler and linker flags that should be used to compile and link programs that use \fIlibxine\fP. It can also be used to determine the directories where \fIlibxine\fP expects plugins. .SH OPTIONS \fIxine\-config\fP accepts the following options, passing them on (possibly modified) to \fIpkg\-config libxine\fP: .TP 8 .B \-\-version \-\-modversion .br Print the currently installed version of \fIlibxine\fP on the standard output. .TP 8 .B \-\-libs .TQ 8 .B \-\-cflags .TQ 8 .B \-\-objcflags Passed on unmodified. .br Print the compiler flags (for C and Objective C, respectively) that are necessary to compile a program that uses \fIlibxine\fP. .TP 8 .B \-\-bindir .TQ 8 .B \-\-plugindir .TQ 8 .B \-\-datadir .TQ 8 .B \-\-scriptdir .TQ 8 .B \-\-localedir \-\-variable=... .br Print the directory where, respectively, \fIlibxine\fP binaries, plugins, data files, scripts and locale data are stored/expected. .TP 8 .B \-\-prefix=PREFIX \-\-define\-variable=prefix=PREFIX .br If specified, use PREFIX instead of the installation prefix that \fIxine-lib\fP was built with. This option is also used for the exec prefix if \-\-exec\-prefix was not specified. .TP 8 .B \-\-exec\-prefix=PREFIX \-\-define\-variable=exec_prefix=PREFIX .br If specified, use PREFIX instead of the installation exec prefix that \fIxine-lib\fP was built with. .SH SEE ALSO .BR xine-lib (3), .BR xine (1) .SH COPYRIGHT Copyright \(co 2001 Siggi Langauf, \(co 2001-2008 the xine project. Based on the man page for gtk-config, \(co 1998 Owen Taylor. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. xine-lib-1.2/doc/man/en/xine-list.1.in0000644000175000017500000000226614647725152015217 0ustar meme.TH XINE 1 2001-08-28 "The xine project" .SH NAME @XL@ - get supported filetype information from xine-lib .SH SYNOPSIS .B @XL@ [\fPoptions...\fI] .SH DESCRIPTION .PP \fI@XL@\fP is a tool that is used to list the MIME type and filename extension information known and supported by the installed \fIxine-lib\fP. It is of use in filling in MIME information in front ends' desktop files. . .SH OPTIONS \fI@XL@\fP accepts the following options: .TP 8 .B \-m .B \-\-mime\-types List the MIME types known to \fIxine-lib\fP. (This is the default action.) .TP 8 .B \-e .B \-\-extensions List the file types (filename extensions) known to \fIxine-lib\fP. .TP 8 .B \-a .B \-\-all List the MIME types known to \fIxine-lib\fP, along with their filename extensions and descriptions. .TP 8 .B \-p .B \-\-pretty\-print Add line feeds; print each item on a line of its own. .SH COPYRIGHT Copyright \(co 2008 the xine project. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. xine-lib-1.2/doc/faq/0000755000175000017500000000000014647725152012200 5ustar memexine-lib-1.2/doc/faq/Makefile.am0000644000175000017500000000171214647725152014235 0ustar memeinclude $(top_srcdir)/misc/Makefile.common doc_DATA = faq.txt html_DATA = faq.html EXTRA_DIST = README faq.docbook faq.xsl $(doc_DATA) $(html_DATA) DISTCLEANFILES = $(doc_DATA) $(html_DATA) docs: $(doc_DATA) $(html_DATA) clean-docs: rm -f $(doc_DATA) $(html_DATA) dist-hook: @if test x"$(distcheck_lax)" = x ; then \ $(MAKE) fail_if_missing=yes docs ; \ else \ $(MAKE) docs ; \ fi distclean-local: clean-docs AM_V_FAKE = $(am__v_FAKE_@AM_V@) am__v_FAKE_ = $(am__v_FAKE_@AM_DEFAULT_V@) am__v_FAKE_0 = @echo " FAKE " $@; if HAVE_XMLTO faq.html: faq.docbook faq.xsl $(AM_V_GEN)xmlto -m "$(srcdir)/faq.xsl" xhtml-nochunks $< faq.txt: faq.docbook faq.xsl $(AM_V_GEN)xmlto -m "$(srcdir)/faq.xsl" txt $< else faq.html faq.txt: faq.docbook $(AM_V_FAKE)if test x"$(fail_if_missing)" = x"yes"; then \ echo "Please install xmlto."; \ exit 1; \ fi if test x"$(fail_if_missing)" != x"yes"; then \ touch $@; \ sleep 1; \ touch $^; \ fi endif xine-lib-1.2/doc/faq/README0000644000175000017500000000044714647725152013065 0ustar memeThis directory contains the new sgml xine engine FAQ. use a command like sgmltools -b onehtml faq.sgml or sgmltools -b txt faq.sgml to transform it into html/txt (sgmltools-lite package in debian). Alternatively, you can simply run "make docs" here. guenter Sat Jan 4 22:59:33 CET 2003 xine-lib-1.2/doc/faq/faq.docbook0000644000175000017500000030413314647725152014315 0ustar meme The xine engine FAQ list xine FAQs 2001-2010 the xine project team

General questions about xine and this document What is the xine engine? The xine engine is a free media player engine. It comes in the form of a shared libarary and is typically used by media player frontends and other multimedia applications for playback of multimedia streams such as movies, radio/tv network streams, DVDs, VCDs. Since there are several frontends for the xine library available, this document has a problem when it comes to examples. The two most common frontends xine-ui and gxine are mixed in command line examples throughout this FAQ. When you use a different frontend, some of these will not work for you. The filename of the config file also varies amongst frontends. If you get confused, I recommend you try with one of xine-ui or gxine. What's the aim and scope of this text? The primary goal of this FAQ is to cover all recurring questions related to the xine engine. Frontend specific questions are usually not covered here. My question is not yet covered here – where can I ask for help? First of all be sure that your question is really not covered here and that you haven't just been a bit too lazy to read through all of this text. ;-). Also check out the documentation specific to the frontend (e.g. xine-ui or gxine or totem). That said – you are welcome to mail to our user mailing list: xine-user@lists.sourceforge.net Please provide some info about your setup so people have a chance to help you, e.g. include information about your audio/video hardware and drivers you use, operating system, cpu type and some console output/any error messages. Also include command line parameters you have specified and information about the type of stream you're trying to play back. Also very important is the version of xine you're using and information about any additional plugins you may have installed on your system. How do I pronounce "xine"? As long as people know what you are talking about, you are free to pronounce it the way you like, but the official pronounciation is [ksi:n], like the name "Maxine" with the "Ma" removed. What are those xine-lib, xine-ui, gxine, … Mercurial repositories for? Some time ago xine just became too complex to be just one big program. Therefore it was split into two major parts. xine-lib is simply speaking the engine of xine. It contains all basic plugins and is necessary to run anything that relies on xine. (This is the part that is covered in this FAQ.) Then there are frontends – applications that use xine. The most common frontend is that of a media player. There are currently three frontends being developed in the xine project: xine-ui, a skinned dvd-player style frontend directly based on xlib; gxine, a desktop media-player style frontend using the standard GTK widget set; and xine-plugin, a plugin for browsers such as Firefox. External projects like kaffeine, sinek and totem develop additional frontends. In the future you will likely see more and different types of applications being developed which will use the xine engine for video processing and other multimedia purposes. If you simply want a media/dvd player, you'll need to install xine-lib first and then choose and install a player frontend like xine-ui or gxine. Other repositories include xine-project-www, which contains the xine project website sources, and various packaging and development branches. Where and how do I get the latest development version? Be advised that end-users should stick to the official xine releases. The Mercurial repositories are only intended for developers and for others who know why they use it. The repositories are listed at http://hg.debian.org/hg/; however, this is a list of all repositories which are kept there, not just the xine project's (which are the ones which begin with xine-lib/). To check one out:    hg clone http://hg.debian.org/hg/repository local_copy e.g.    hg clone http://hg.debian.org/hg/xine-lib/xine-lib xine-lib You can see a full list of repositories by visiting http://hg.debian.org/hg/xine-lib/. Don't you use CVS? We used to, but there are some significant problems with CVS. Merging is easier with Mercurial (and, for that matter, git); and we can commit changes locally, change them if mistakes have been made, then make them public whenever we're ready. How do I submit patches? See the xine Hackers' Guide, chapter 3, "How to contribute". (This is available online at http://www.xine-project.org/hackersguide#contribute.) Where can I find pre-compiled binaries, e.g. RPMs? The xine project does not provide pre-compiled binaries for legal reasons (some parts of xine may be covered by patents in some countries). Some OS projects/vendors (e.g. Debian, FreeBSD, …) offer binaries for their distributions – please contact them or use their package search tools for further info. You can also find links to third parties providing xine RPMs on the xine homepage at http://www.xine-project.org/releases. See the next section of this FAQ for instructions on how to build xine from source. Building and installing xine from source What do I need to compile everything properly? First of all an official and stable release of gcc. Also be aware that patched gcc versions may break parts of xine and are therefore not supported by the xine project. Furthermore you'll have to use GNU make to compile xine. On most GNU/Linux systems "make" is GNU make – on other platforms use "gmake" instead. Also, zlib is required (including the appropriate header files, which are often found in a package called zlib-devel or similar.) If you want to compile xine from Mercurial, you'll need to have the autobuild tools installed (automake, autoconf and libtool – in recent versions). Frontends might need additional libraries, e.g. for gxine you'll need to have GTK2 installed. Make sure you have not only the shared libraries themselves but also the header files (often packaged seperately as so-called -dev packages) on your system. Some plugins that come with the xine engine need additional libraries (otherwise they will not be built). For example, libogg and libvorbis (plus their include files) are needed for ogg/vorbis support. Most notably, if you want to see any video on your X11 desktop (and that's what you're here for, isn't it?), you need the X developer packages as well. Don't worry about this too much right now, xine's configure (see below) will check for all the stuff needed and will tell you what's missing (which means that you should check the output it produces carefully ;) ). How do I compile xine? Simple build instructions for beginners Download the latest xine-lib and gxine/xine-ui tarballs, then follow these instruction. To unpack a tarball, use:    tar xfvz tarballname.tar.gz The following instructions will install xine in /usr/local where it will be visible for all users. You need root privileges to do this on most systems. After unpacking xine-lib, issue:    ./configure    make install Make sure your /etc/ld.so.conf contains /usr/local/lib and continue with:    ldconfig Now unpack your frontend (gxine or xine-ui or …), then:    ./configure    make install Complete build instructions The build process is the same for all of the xine modules. You have to start with xine-lib. If built and installed successfully, you can continue with the frontend(s). If you have installed xine-lib to a non-standard prefix, make sure that you have $prefix/bin in your PATH and that your linker finds libs in $prefix/lib – otherwise trying to build modules that rely on xine-lib will fail with configure complaining about not finding certain parts of libxine. Using bash you can do something like:    export PATH="$prefix/bin:$PATH"    export LD_LIBRARY_PATH="$prefix/lib:$LD_LIBRARY_PATH" to make sure libxine can be found by the frontend(s). Last but not least. Here the build instructions. As stated earlier, those are the same for every xine module.    ./autogen.sh [→ only if you're building from hg]    ./configure    make    make install Making your own RPM packages (xine-lib, xine-ui, gxine) Basically you will only have to issue one command, if you have just downloaded a source tarball from our web site:    rpmbuild -ta <THE_NAME_OF_YOUR_SOURCE_TAR_BALL> (Older versions of RPM use rpm instead of rpmbuild.) This will start the binary and source RPM building. After compiling is finished, a binary rpm is placed in your rpm binary directory which is something like /usr/src/RPM/RPMS/<YOUR_ARCHITECTURE> and a source RPM is written to your rpm source dir (e.g. /usr/src/RPM/SRPMS). In case that you have an up-to-date hg repository, you will need to do the following first in order to get a tarball release out of it which you can later use with the rpmbuild -ta command above:    ./autogen.sh && make clean && make dist In any case, please keep in mind that you have to build and install xine-lib first before you can proceed with xine-ui. Making your own .deb packages (xine-lib, xine-ui, gxine) You'll need an HG snapshot tarball or source checked out from the repository. First, make sure that the "devscripts" and "build-essential" packages are installed. You'll then need the following commands (the first one isn't needed unless you're using a snapshot tarball):    tar xzf <PACKAGE-VER.tar.gz>    cd <PACKAGE-VER>    ./autogen.sh noconfig    debuild binary (If debuild complains about unmet dependencies, then install them using aptitude install <PACKAGES> (as root) then re-run debuild binary. Once the build has been successfully completed, you'll have some new .debs.    cd ..    ls *.deb    su - -c 'cd '"`pwd`"' && dpkg -i <DEB_PACKAGES>' Ubuntu users will probably want to use this instead of that su:    sudo dpkg -i <DEB_PACKAGES> In any case, please keep in mind that you have to build and install xine-lib first before you can proceed with xine-ui or gxine. Can I provide additional CFLAGS for compilation? Yes, you can do so by setting the CFLAGS variable and then running configure again. You can even pass them to configure directly. Example:    ./configure CFLAGS="-march=i686" Other user variables configure respects are: CC to specify the compiler executable CPP to specify the C preprocessor executable LD to specify the linker executable CPPFLAGS to pass additional include paths or other preprocessor options LDFLAGS to pass additional library paths or other linker options An example combining some of these would look like:    ./configure CC="/opt/intel/bin/icc" LD="/opt/intel/bin/xild" \    CPPFLAGS="-I/usr/local/include/dvdnav" LDFLAGS="-L/home/guenter/xine_libs" Are there binaries for my AMD K7 (Athlon™) available? Can I build them? If you have a recent gcc you can try to compile "more" k7 support in (esp. better instruction scheduling). If the configure script should fail to detect your processor/gcc correctly, try passing the canonical system name for your machine to configure with the --host option, e.g.    ./configure --host=k7-pc-linux-gnu Build problems: xine engine (xine-lib) The package doesn't compile at all! In order to be able to compile xine-lib, you need (amongst other things) the zlib compression library plus the appropriate headers, which are often found in a package called zlib-devel or similar. Read again carefully the output ./configure produced and/or compiler warnings and error reports, they often contain helpful information to find out what's going on. If you're stuck here and decide to post your problem on the xine-user mailing list, make sure you include these outputs. The Xv video-out plugin fails to compile! If you want to have Xv support compiled in, make sure you either have a shared Xv library on your system, e.g. ls /usr/X11R6/lib/libXv* should give you some .so libs, like this:    /usr/X11R6/lib/libXv.a    /usr/X11R6/lib/libXv.so    /usr/X11R6/lib/libXv.so.1 Alternatively you need to have libtool 1.4 or newer installed, then libXv.a is sufficient. Otherwise you can create the shared versions yourself:    ld --whole-archive -shared -o libXv.so.1 libXv.a    ln -s libXv.so.1 libXv.so    ldconfig Now you should be ready to build the Xv video-out plugin on your system. Build problems in frontends (gxine/xine-ui/…) I have installed xine-lib but the frontend complains about not finding it! First of all take a closer look at the compilation instructions above again. You will probably find your answer there right away. As stated there (there again that hint *grin*), make sure that you have $prefix/bin in your path and that your linker is able to find libraries installed in $prefix/lib By the way, $prefix is where you installed your xine-lib to earlier (yes, installing xine-lib with make install or installing the corresponding distribution-provided -dev or -devel package would be a good idea before trying to compile the frontend ;) ). Can I install xine in my home directory (without being root)? Sure. First set up a subdir where you install your private software, eg.    mkdir ~/xine Then you have to set a few environment variables – it's probably a good idea to add this to your ~/.bashrc (or somewhere similar):    export PATH="$HOME/xine/bin:$PATH"    export LD_LIBRARY_PATH="$HOME/xine/lib:$LD_LIBRARY_PATH" Now you can unpack tarballs e.g. in ~/xine/src (mkdir ~/xine/src if necessary) and do a    ./configure --prefix=$HOME/xine    make install You also need to tell frontends using xine-lib, where to find it:    ./configure --prefix=$HOME/xine --with-xine-prefix=$HOME/xine How to compile xine for Windows? For compiling xine under Windows with MinGW, CygWin or MS Visual C see README.WIN32. For cross-compiling xine under comfortable unix-like environment with MinGW see README.MINGWCROSS. Playback of various stream types DVD Playback with xine How do I play back DVDs with xine? Newer xine (1.0.x) releases come with a full-featured DVD plugin that should be able to handle any unencrypted, non-locked DVD with full menu navigation support. No external plugins are required anymore here. To get DVD playback working, first make sure you have a symlink /dev/dvd pointing to your DVD device on your system. For example, if your DVD drive is the master ide drive on the second IDE channel, /dev/dvd should point to /dev/hdc. Please note that if you are using the ide-scsi emulation on your system, it is likely that your DVD drive got mapped to a scsi device node even though it is an ide drive. In that case first check out you boot/kernel logs (or run cdrecord -scanbus) to find out which device it got mapped to and set the symlink accordingly (should be something like /dev/scd0, /dev/scd1, … in that case). Also make sure you (as a user) have sufficient (read and write) permissions on your DVD drive. This could mean you either have to change the device permissions or add your user to a special group (e.g. addgroup cdrom username), depending on your setup and/or distribution. It is highly recommended to switch DMA mode on for your DVD drive (without it even very recent machines will have trouble producing smooth video output). Use a command like hdparm -d 1 <device> on your DVD device. Please note that even if you're using ide-scsi you will have to set the dma flag on the ide device node (e.g. /dev/hdc), not the mapped /dev/scd scsi device. To be able to play back encrypted DVDs you need to have libdvdcss installed on your system (please check if this is legal where you live). If you do not understand what the term "encrypted DVD" means here: As a rule of thumb, every DVD you have to pay money for is most likely encrypted. To make matters worse, apart from encryption, there is another obstacle to take: the region code. The DVD authorities decided to divide the world into eight geographical regions. Have a look at http://www.dvdforum.gr.jp/RegionMap.pdf if you want to know which number has been assigned to your country. It is now their idea, that you shall only play DVDs, which have been produced for your region. If you take a DVD off the shelf in your local store, you should find a little globe-like icon which shows the region code the disc is for. Newer (post-2000) DVD drives (so-called RPC-2 drives) check the DVD region, which means they'll prevent you from playing back DVDs that have a different region code from what the drive is set up for. Some drives come with a factory setting of region 0 so they can play back any DVD until a region code is set. Others refuse to play any DVD at all until they are told a region. The easiest way to handle this is to use the regionset utility from http://sourceforge.net/project/showfiles.php?group_id=31346&release_id=168415 . Once you have everything set up, try something like gxine dvd:/ or xine -p dvd:/ to start dvd playback. Some frontend also offer so-called autoplay buttons or menu entries that start dvd playback immediately. Important: do not try to mount the DVD. Just insert it and hit the DVD autoplay button or start xine from the command line. If things do not work as expected, try running the xine-check shellscript that comes with xine to see if this gives you further hints on what could be wrong. DVD playback works, but it takes a long time until playback starts This points to a region code problem. Some versions of libdvdcss can play back DVDs from other regions than the RPC-2 DVD drive is set up for, but this usually means a cryptographic attack (which takes time) has to be used to access the DVD. You can download a tool to set the region code of RPC-Drives here: http://sourceforge.net/project/showfiles.php?group_id=31346&release_id=168415 . Warning: Please be aware that the number of region code changes in RPC-2 drives is limited (usually about 5 times), after that your drive will stay locked to the region you last set it up for. I have problems setting up my RPC-2 drive for the right region! You can download a tool to set the region code of RPC-Drives here: http://sourceforge.net/project/showfiles.php?group_id=31346&release_id=168415 . Warning: Please be aware that the number of region code changes in RPC-2 drives is limited (usually about 5 times), after that your drive will stay locked to the region you last set it up for. Can I watch Video CDs (VCDs)? SVCDS ? CD-i? xine supports VCD and SVCD playback out-of-the box. Similar to DVDs, make sure you have a /dev/cdrom alias pointing to your CDROM drive which you will use to play back the (S)VCD. At the moment, CD-i formats are not supported by xine. Do not try to mount the (S)VCD. Simply insert it into your CDROM drive and hit the VCD autoplay button or start something like gxine vcd:/ or xine vcd:/ from the command line. VideoCD troubleshooting guide This gives higher-level troubleshooting. More lower-level information is given in the next section. When you open the configuration dialog of your frontend, you should see a vcd config section. An important setting is default_device. If this is set to the empty string, the VCD plugin will try to scan your drives for a suitable device if the driver has the capability to scan for drives. However you can set the device to something of your choosing. On GNU/Linux, this may be /dev/cdrom and on Solaris it may be /vol/dev/aliases/cdrom0. If you set this field, make sure these are correct for your particular setup. For example, I generally play out of the DVD device and this is called /dev/dvd rather than /dev/cdrom. Your frontend should offer a VCD autoscan button or menu item. If you select this, you should see your CD disk light go on if you have one. And the CD should be read. You should get a playlist of what's on the VideoCD. If not something's wrong, possibly you configured the wrong drive. You might try to read a disk image of a VideoCD and thus elimate any problems with hardware. You can get a test VideoCD disk image to test here: http://www.vcdimager.org/pub/vcdimager/examples/test_svcd/test_svcd_pal.zip . After unzipping this there should be files test_svcd_pal.cue and test_svcd_pal.bin. Run xine with the MRL vcd:/test_svcd_pal.cue:E0. If you see something playing then this is a hardware problem. You might also want to try starting playback-control with vcd:/test_svcd_pal.cue:P1. There should be at least one "track", and one "entry" listed for the VideoCD and the names of these in the MRL list will end with "T1" and "E0" respectively. Often there are other playlist items, and if you have menus or still frames there will be "segments" as well. The simplest things to check are probably "entries" and "tracks". If there are no entries listed or none of the tracks or entries play, then there may be a problem with that particular medium. So as in the step above, you can try a known good sample and perhaps burn a CD from that. More likely if you get this far, some of the items listed work and some do not. There are a number of debugging switches that you can dynamically turn on and off that may be able to help in isolating more specific problems. See the section below. Something plays now, but you do not get any menus? Well, first is there supposed to be a menu? In the last step you should have seen what is on the VideoCD. Still frames are always "segments" so see if you can find one in the MRL list and select that. If there are no segments listed, there aren't any still-frame menus. It's also possible to have menus in looping MPEG's. Use the vcddump tool to find loops. vcddump is also part of VCDImager. Another program that can help you examine the contents of a VideoCD is vcdxrip. To troubleshoot, start out with the known SVCD example that has a still-frame menu at the beginning: http://www.vcdimager.org/pub/vcdimager/examples/test_svcd/test_svcd_pal.zip Inside this is a largish file called test_svcd_pal.bin and another short text file called test_svcd_ntsc.cue. These are CD disk images; that is, something that could be burned to a CD drive such as with cdrdao. However you don't have to create a CD to view these with the xine VCD plugin. You should be able to play the VideoCD by running the MRL vcd:/test_svcd_pal.cue. If you see a still frame on startup. Great! If instead you see what looks like the beginning of a movie (Blue Streak with Martin Lawrence) then go to the next step. You have a VideoCD with menu and can see it, but there is no menu on startup? If you have the VideoCD from the last step, then run the MRL vcd:/test_svcd_pal.cue:P1 If this shows a still frame, but it just does not show when you hit either the "VCD" autoscan button or give a MRL without the P1 at the end then go to the next step. If you have another VideoCD, from the MRL list, you should also see "playlist" entries. Try selecting the one that ends "P1". If you don't see an entry with P1, then your VideoCD does not have playback control (PBC) and although there may be a still frame on the VideoCD it may have been authored so it is not easily accessed. Again vcddump or vcdxrip can help here. You have a VideoCD with menu at beginning and can see it using an MRL with P1 at the end, but you want to see it by hitting the "VCD" autoscan button as well? Check to see that you have the configuration entry media.vcd.autoplay set to playlist. VideoCD debugging To facilitate tracking down problems we let you see what's going on dynamically. Various debugging settings will cause output to appear on xine's plugin log and/or on standard error output. See the config entry media.vcd.debug for details. The tool vcd-info from the cdio branch of vcdimager can be used to show the entire contents of a VideoCD or selected portions of that. Until the cdio branch of vcdimager is completely merged with vcdimager, the cd-info branch version has a few more features. (However consult vcdimager for complete version of the program.) vcdxrip can be used to extract portions of a VideoCD and or create an XML description file of the VideoCD. This XML file and the extracted files can be used by vcdxbuild to recreate another VideoCD. And finally see also tools cd-info and cd-read from libcdio. Can I watch Quicktime (.mov, .mp4) files using xine? Quicktime is just a system layer (container format) which can contain various different audio and video formats. The system layer itself is fully supported in xine. However, some quicktime audio/video codecs are not natively supported yet. Luckily, if you are using a x86 compatible machine (any recent PC hardware should do) you can install and use the original Quicktime DLLs and watch most streams (trailers) that can be downloaded from the net. Possibly the most convenient way to get the Quicktime DLLs is to download them from the MPlayer website http://www.mplayerhq.hu/design7/dload.html . The package is called "essential". Unpack it and move everything you find inside to /usr/lib/codecs (actually you can place them anywhere you want, e.g. someplace in your home directory, but then you'll have to set decoder.external.win32_codecs_path in your xine config file accordingly). Restart xine then and you should be able to watch Quicktime trailers. Real Network files/streams Can I watch Real (.rm, .ram) files using xine? The situation with real files and streams is pretty similar to the situation with Quicktime Streams (see above). The newer real audio and video formats are only supported by using binary-only codecs which are not included in xine. Possibly the most convenient way to get the Real codecs is to install RealPlayer 9 or RealPlayer 10 and set the decoder.external.real_codecs_path in your xine config file to the name of the directory which contains the codecs (look for drvc.so); it's probably something like /opt/real/RealPlayer/codecs/. Restart xine then and you should be able to watch Real files/streams. Another way to get the Real codecs is to download them from the MPlayer website http://www.mplayerhq.hu/design7/dload.html . The package is called "essential". Unpack it and move everything you find inside to /usr/lib/codecs and set the decoder.external.real_codecs_path in your xine config file to /usr/lib/codecs (actually you can place them anywhere you want, e.g. someplace in your home directory, but then you'll have to set decoder.external.real_codecs_path accordingly). Restart xine then and you should be able to watch Real files/streams. What about (live) network streams (pnm://, rtsp:// style urls)? xine supports both pnm and rtsp streaming. However, digging out the actual pnm/rtsp url can be tricky as they're often packed into heavy JavaScript and HTML code on most websites. You can either use a combination of your browser's "save source" function and wget or use a xine browser plugin (currently the gxine frontend comes with a simple mozilla plugin, for example). When you decided to dig out the url by hand don't get fooled by the many redirectors that are often placed around the actual url. Use wget to download any http://-style urls and use less to look inside the downloaded .ra/.ram files where you will find the actual pnm/rtsp url which can be opened using xine. Can I watch Windows Media (.asf/.wmv/.wma) files using xine? While the container format (system layer) ASF (wmv is just an alias) is fully supported in xine, for newer windows media 9 based streams you'll need to install windows binary codecs (.DLLs). Possibly the most convenient way to get the Windows DLLs is to download them from the MPlayer website http://www.mplayerhq.hu/design7/dload.html . The package is called "essential". Unpack it and move everything you find inside to /usr/lib/codecs (actually you can place them anywhere you want, e.g. someplace in your home directory, but then you'll have to set decoder.external.win32_codecs_path in your xine config file accordingly). Restart xine then and you should be able to watch windows media streams. Can I watch Digital TV (Digital Video Broadcast) using xine? At the time of this writing DVB support is a very new and experimental feature in xine. The number of supported cards is pretty limited at the moment. See doc/README.dvb (in the xine-lib tarball) for details. How do I play streams from STDIN? Use something like:    cat stream.mpg | gxine stdin:/ How can I watch files with external AVI subtitles? In xine 0.9.13 this used to be:    xine foo.avi%bar.sub Latest xine-lib modules (1-beta3 or newer) support external subtitles for any media file, not only AVI. In order to use it you can pass a special MRL construction like:    xine file://path/to/test.mpg#subtitle:/path/to/file.sub The external subtitles support can also be used by any xine frontend. Currently xine-ui and kaffeine implement this feature with a subtitle selection dialog. Running xine I have a lot of dropped frames – what can I do? Your hardware might be too slow for xine. Make sure you turn on all speed optimizing options. A few things you should check (in order of importance): First of all, run the xine-check script included in xine package (probably already installed in your system). xine-check will report several of the most common problems listed here. Sample output from xine-check:    xine-check    Please be patient, this script may take a while to run...    [ good ] you're using Linux, doing specific tests    [ good ] looks like you have a /proc filesystem mounted.    [ good ] You seem to have a reasonable kernel version (2.4.18)    [ good ] intel compatible processor, checking MTRR support    [ good ] you have MTRR support and there are some ranges set.    [ good ] found the player at /usr/local/bin/xine    [ good ] /usr/local/bin/xine is in your PATH    [ good ] found /usr/local/bin/xine-config in your PATH    [ good ] plugin directory /usr/local/lib/xine/plugins exists.    [ good ] found input plugins    [ good ] found demux plugins    [ good ] found decoder plugins    [ good ] found video_out plugins    [ good ] found audio_out plugins    [ good ] skin directory /usr/local/share/xine/skins exists.    [ good ] found logo in /usr/local/share/xine/skins    [ good ] I even found some skins.    [ good ] /dev/cdrom points to /dev/hdc    [ good ] /dev/dvd points to /dev/hdc    [ good ] DMA is enabled for your DVD drive    [ good ] found xvinfo: X-Video Extension version 2.2    [ good ] your Xv extension supports YUV overlays (improves MPEG performance)    [ good ] your Xv extension supports packed YUV overlays    [ good ] Xv ports: YUY2 YV12 I420 UYVY Try to use the Xv driver, it greatly improves performance and quality because your graphics card does image scaling and colourspace conversion. The video section contains important information about several Xv drivers. If Xv cannot be used for some reason, make sure your display is set up to 16bpp, not 24 or higher (reduces memory bandwith). Some Xv drivers may also have better performance with 16bpp. Make sure the hard drive (or cdrom/dvd drive) which supplies the video data is in DMA mode (if supported). On most linux-based systems, you can use hdparm to check this:    hdparm /dev/hda    [...]    using_dma = 1 (on)    [...] You can enable DMA mode with the following command:    hdparm -d1 device_of_your_drive_that_supplies_video_data In some cases where this fails it helps to specify the dma mode to use, for example:    hdparm -d1 -X 66 device_of_your_drive_that_supplies_video_data In RedHat 8.0 an additional entry in /etc/modules.conf    options ide-cd dma=1 should help (reboot for this change to take effect). More information about this may be found here: http://oreilly.linux.com/pub/a/linux/2000/06/29/hdparm.html . Use a recent kernel which is optimized for your hardware. Old kernels may lack support for accelerated instructions like SSE, for example. Close other applications (use a tool like "top" to find out what applications are using up CPU power). Programs that update the system clock like ntp should also be disabled. Enable MTRR support in your kernel. If you are still using XFree 3.x, you'll have to tell the kernel yourself where the graphics memory is. You'll find details about that in the linux dvd howto. If you're using X.org or XFree 4.x, enabling MTRR support in your kernel should be enough (use a recent kernel!). Try a cat /proc/mtrr – if the file exists and you find an entry corresponding to the amount of graphics memory you have, everything should be fine. Have your X-server (usually X.org or XFree86) running with higher priority. Most recent linux distributions (like RedHat 8.0 or Mandrake 9.0) should do that for you, improving not only xine but desktop responsiveness in general. Use the "top" utility and verify under the "NI" column if the X process has a negative value, this indicates a higher priority. See "The X Window User HOWTO – Performance considerations" for further instructions http://www.tldp.org/HOWTO/XWindow-User-HOWTO/performance.html . Use the latest or a known-good gcc version and build an optimized xine-lib for your architecture. Besides boosting X-server priority, sometimes it's possible to avoid discarding frames by making xine itself higher priority. This is not a recommended pratice since it will require to run xine as root, but you may give it a try if you want:    nice --5 xine xine needs high speed memory access which depends on your chip set. Make sure you enable all speed-improving options. Especially the via apollo pro chipset is known to be quite weird, (most of all on my gigabyte board). If you can't configure the ram access thoroughly using the bios you might want to try some really nasty tricks, as explained on (for example): http://www.overclockers.com/tips105/index03.asp This website centers around a windows-tool to tweak the chipset, you can do the same on FreeBSD with pciconf. On some linux distributions there are similar tools. a nice performance tuning tool can be found here: http://powertweak.sourceforge.net Set up and use raw devices for DVD access. Please note that the actual performance gain during playback is very small if any, but since raw devices are bypassing the kernel's buffer cache, Linux will not try to cache the DVDs you play. This would not be useful, because xine does its own caching and you usually play DVDs sequentially, which means you won't reuse anything from the cache. But the problem would be that Linux throws everything out of the cache that might be in there. Raw devices should be available in linux kernel 2.4.x and there are patches for older kernels available from: ftp://ftp.kernel.org/pub/linux/kernel/people/sct/raw-io/ For recent kernels (2.6.x series) the raw devices are neither needed nor supported anymore, so don't bother. To use raw devices, first connect a free raw device to your dvd device, use something like:    raw /dev/raw1 /dev/dvd Then create a link named "rdvd" pointing to that raw device:    ln -s raw1 /dev/rdvd For slow / high-latency dvd drives it might help to increase the number of video buffers xine allocates. Try setting engine.buffers.video_num_buffers:500 to a higher value (e.g. 1000 or 2500). Oki, xine doesn't drop frames now but video output still is not really smooth! Video output can be further improved by tuning your linux kernel: Set HZ to 1000 in /usr/src/linux/include/asm-i386/param.h Try applying scheduler patches, especially the O(1) and the preemptive patches have proven useful at the time of this writing (spring 2003). Linux 2.5/2.6 will probably have these improvements out of the box. Miguel Freitas has written a nice article about his kernel multimedia experiments . I have problems when using xine on FreeBSD, Solaris, … ! Check out the the corresponding README files in the directory xine-lib/doc. What is aalib? How do I use it in xine? aalib is an ascii art library. xine comes with an aalib video output plugin so you can watch movies in your xterm, on the console or on your old vt100 – very cool ;> … another nice option is to preview movies on a remote server in your shell over ssh. To use it make sure you have aalib installed correctly before you configure/build xine-lib and xine-ui. In addition to the xine binary a binary named aaxine should get built and installed. You can then use something like:    aaxine foo.mpg to use aalib video output. Does xine support my dxr3 / hollywood+ card? While xine's focus is clearly on software decoding, the dxr3 is supported. You can find more information about using xine with the dxr3 here (also covers how to do tv output using the dxr3). Audio related questions What audio drivers does xine support? OSS? Alsa? Arts? Esd? Currently xine support audio output via OSS (Linux 2.4 and most *BSD audio drivers), ALSA 0.9 and 1.0 (ALSA 0.5.x is no longer supported), aRTs (KDE 3's sound daemon), ESounD (esd, gnome's sound daemon not recommended because it has serious issues with a/v sync), JACK, PulseAudio, plus platform-specific output through Sun devices for Solaris and NetBSD and Irix output. When I'm watching a movie, the sound effects are much higher in volume than the voices! Congratulations, you seem to have an original movie audio track there. Uhm. So you don't like it. Well, there are two things you can do: You can enable xine's audio compressor. Most frontends have a settings window and in that you'll find a slider for the compressor setting. The values are percent values, so a slider setting of 200 means that xine will double the volume of silent parts of the movie (loud parts stay the same). If your frontend does not have such a compression slider, you can pass the value with the MRL:    xine dvd:/#compression:150 If you have a dolby digital (AC3) soundtrack, you can try to enable liba52's dynamic range compression setting audio.a52.dynamic_range:1 in your xine config file (or use some gui config dialog). When I play this stream, xine shows video but there's no audio! If this happens with any video, first try a different audio driver (gxine -A oss, gxine -A arts, xine -A alsa …). If this problem only occurs with one specific stream, maybe switching to a different audio channel (using the gui) helps. Some DVD streams have audio on strange channels. If all this doesn't help, maybe you're missing an audio codec or you found a bug. If you decide to post your problem on the xine-user mailing list, make sure to include all console output xine produced and also clearly state what type of stream you tried to play back or, even better, make a test stream available somewhere for developers to download and try. Can xine produce 4-/5-channel surround audio output? Yep, it can do that using OSS or ALSA drivers, provided that the driver supports it. However, since xine cannot detect if there are actually speakers connected to the additional channels, you'll have to activate that feature manually. You can do this either in the config dialog while xine is running (press the config button on the xine panel and go to the AUDIO tab) or have it the complicated way by editing the config file yourself which is located in your home directory in .config/gxine or .xine:    audio.output.speaker_arrangement:Surround 4.0    audio.output.speaker_arrangement:Surround 4.1    audio.output.speaker_arrangement:Surround 5.1 What about ac3 output via spdif to an external ac3 decoder? xine can do that too. Pretty much the same story as for 4-/5-channel surround (see above). You can either use the config dialog or edit the config file (~/.xine/config or ~/.config/gxine/config) yourself:    audio.output.speaker_arrangement:Pass Through Getting SPDIF output from a SBLive 5.1 using OSS drivers The following explains how to get the above configuration going with xine. Some parts of it may applicable to other configurations (cards that use the EMU10k1 chip) as well. Requirements xine-lib >= 1.x.x OSS driver an external decoder a cable to connect the SBLive to the external decoder The configuration described was tested using a Soundblaster live 5.1 (rev 7) with a Yamaha DSP-AX620 external decoder. Retrieving the driver The OSS driver is maintained by creative and can be downloaded at http://opensource.creative.com/. The driver package contains documentation on how to install it. Besides that I'd like to add the following notes. In order to compile and install these drivers, you need a valid kernel configuration file. For RedHat Linux's pre-compiled kernels these configuration files can be found in /usr/src/linux/configs. After you've located the correct config file for your kernel, you need to copy it to /usr/src/linux/.config For example, when you run the 2.4.18-i686 kernel do :    cp /usr/src/linux/configs/kernel-2.4.18-i686.config /usr/src/linux/.config Make sure that the emu10k1 module that is currently installed is not loaded. To unload the modules:    /sbin/modprobe -rv emu10k1.o ac97_codec.o If this mentions that the device is busy, some program is using the driver. Some example could be a mixer application or sound daemon like artsd. You'll need to close down the applications before continuing. At success it should print something like:    # delete emu10k1    # delete ac97_codec    # delete soundcore Run make in the directory where you unpacked the driver and follow the instructions printed at the end of each step. The last step should be:    make install-tools As the README of the driver package mentions the SPDIF AC3 output doesn't work by default. In the directory utils/scripts an emu10k1.conf file can be found which need to be placed in the default installation directory (/usr/local/etc). After this the emu10k1.conf needs to be modified. The following settings worked fine for me (I don't use the analog outputs of the card):    CARD_IS_5_1=yes    USE_DIGITAL_OUTPUT=yes    ENABLE_TONE_CONTROL=yes    AC3PASSTHROUGH=yes    ENABLE_LIVEDRIVE_IR=no    INVERT_REAR=no    MULTICHANNEL=yes    ROUTE_ALL_TO_SUB=no    ANALOG_FRONT_BOOST=no    SURROUND=no    PROLOGIC=no    ENABLE_CD_Spdif=yes    ENABLE_OPTICAL_SPDIF=no    ENABLE_LINE2_MIC2=no    ENABLE_RCA_SPDIF=no    ENABLE_RCA_AUX=no After modifying the emu10k1.conf, you need to modify your /etc/modules.conf and make sure the following lines are in there.    alias sound-slot-0 emu10k1    post-install emu10k1 /usr/local/etc/emu-script After saving the changes to modules.conf, run    /sbin/depmod -a Now, you're ready to load the new modules and set the correct options for it. To load the modules run:    /sbin/modprobe emu10k1 Setting up xine for SPDIF (AC3 passthrough) output You can either use the config dialog of your frontend or edit the config file (~/.xine/config) yourself:    audio.output.speaker_arrangement:Pass Through In case the setting is not in the file you can add it. The cable used for the SBLive can easily be self-made or buy a stereo 3.5mm jack to dual RCA cable. What you need to make the cable yourself: stereo 3.5mm jack plug RCA plug shielded cable (video coax 75 Ohm will do) Connect them as follows :    center pin jackplug ------|----- center pin RCA plug     GND __|__ GND In order to test it use a DVD with AC3 or DTS track start xine and select the right audio track from user interface or start xine as:    xine dvd:/1 -a 0 The external decoder should display something like "Dolby Digital" in case the selected audio track contains AC3 data or "DTS" in case the selected audio track contains DTS data. Of course stereo audio also goes through the SPDIF output, so the analog outputs of the SBLive 5.1 are not needed anymore. Changing the volume with the GUI control has no effect! What's up!? Some xine drivers do not support volume changing although the GUI will show the volume bar. Usually this is not xine's fault: aRts C API, for example, doesn't offer any volume property to applications. Similarly, with ac3 pass through it is not possible to set the volume. Note that recently we added support to "simulate" volume in aRts by changing sample values on-the-fly before delivering them to the driver. Not as good as having access to sound card's mixer but at least users will not complain about lacking of volume bar anymore! :) Audio is stuttering and i see a lot of "metronom: fixing sound card drift by -2115 pts" on the console output Might be a soundcard problem, if it only comes in longer intervals. Your soundcard does not keep it's sampling frequency accurately enough, which results in audio and video getting out of sync and xine has to compensate. If you see the message only from time to time, you might remedy it by using the resampling sync method. You can do this by setting the configuration entry audio.synchronization.av_sync_method to resample. If you receive the metronom message more often, maybe switching to different drivers (alsa to oss or vise-versa) can help here. It has also been reported that setting the configuration entry audio.synchronization.force_rate to the native sampling rate of your soundcard (try 44100 and 48000) helps sometimes. Another, whole different possibility is that you have some background process running which is messing with the clock (like some ntp client – chrony, ntpd, …). Occasional messages of "fixing sound card drift" may happen on start and when playing a long stream (like a movie). This is normal behaviour, nothing to worry about. xine seems to lose sound arbitrarily during playback, especially with DVDs You are using the OSS audio output plugin, right? In order to keep video and audio in sync, xine regularly queries the audio driver for the amount of delay induced by the current length of the driver's audio buffer. Unfortunately some OSS drivers seem to be broken because the can return strange values here. This confuses the xine audio subsystem and makes it drop audio. You should try the various settings of the configuration entry audio.oss_sync_method. The options getodelay and getoptr ask the driver and might therefore show the problem. But chances are that only one is broken and the other works, so you should try them both first, since they are the most accurate. The option probebuffer does not ask the driver directly but tries to determine the buffer length from outside. This should work with any driver and is the way to go, of the driver dependent methods fail. softsync is the least accurate and should be used only in emergency situations. Video related questions I can hear the audio – but I don't see a picture! Probably your hardware is simply too slow – see above for some hints on how to speed things up. Another possibility is that you using a buggy Xv driver, see the next questions. I only see a blue (or green or black) video image most of the time. You are either watching a very boring video (just kidding) or you are suffering from a bug in the Xorg 6.7 implementation of X11. The workaround is to add the line    Option "XaaNoOffscreenPixmaps" in the Device section of your X server configuration (usually /etc/X11/xorg.conf or /etc/X11/XF86Config). The image looks strange, it is shifted, cropped or shows weird lines! This points to a problem with the Xv extension, which is used by xine to display the video image. To verify this, try running xine with the XShm video output plugin:    xine -V XShm If that works fine, you just proved, that the Xv extension is buggy. xine will remember the last used video output plugin, so the setting will stay at XShm. You could simply continue using this, but XShm is a lot slower than Xv, so read on and see if you can get it working. Usually you should look for updated versions of the X driver module that belongs to your graphics card. Other possibilites are limitations in either your X driver module or your graphics hardware. If your card could somehow be running out of ressources (graphics RAM perhaps) and displays an incorrect Xv overlay because of that, try reducing the display resolution and/or colour depth. Consult the next question for more details on Xv. How can I make xine use the Xv extension and what drivers do I need? xine will normally use Xv by default if it is available. In some cases you might need to choose Xv playback manually (when the ~/.xine/config file for some reason says that you want to use XShm):    xine -V Xv If this doesn't work for you, it may be possible that Xv is not present on your system. First you need to install/use X.org or XFree 4.x. Once you got that you have to make sure the X drivers you're using are supporting Xv on your hardware. Here are some hints for individual gfx chips: 3Dfx: if all you get is a solid black window, upgrade to X.org or XFree 4.1.0 or later. ATI: if you only get "half a picture", try lowering your resolution or bit depth, disable DRI (looks like you ran out of video RAM) Trident card: If you see vertical bands jumbled, upgrade to the latest xfree/experimental trident drivers (for the CyberBlade XP a driver exists here: http://www.xfree86.org/~alanh/ ) nVidia: With newer GeForce cards, Xv should work with XFree 4.2.0 or newer, for older RivaTNT cards use the binary drivers from nvidia (of course the binary drivers work as well for GeForce cards) Mach64/Rage3D (not Rage128/Radeon) cards/chips get no XVideo with standard drivers, try GATOS drivers instead intel: i815 has Xv support in XFree 4.x, others unknown Permedia 2/3 has Xv support in XFree 4.x Savage: at least some older drivers tend to lock up the whole machine, try the drivers available from http://www.probo.com/timr/savage40.html . SIS: certain controllers (more info needed!) have Xv support in XFree 4.x Chips and Tech 6555x, 68554, 69000, 69030 have Xv support in XFree 4.x NeoMagic: certain controllers (more info needed!) have Xv support in Xfree 4.x SiliconMotion: certain controllers (more info needed!) have Xv support in Xfree 4.x Matrox: G200 or newer (but not Parhelia) have Xv support in XFree 4.x. For Parhelia, use the binary only drivers available from matrox' website. Some parts of my X Desktop get transparent when xine plays the video! Looks like some colours on your GUI match the colour key which Xv uses. You can change the colour key value to avoid this. There should be a line like:    video.device.xv_colorkey:2110 in your ~/.xine/config file where you can change the colour that's used by xine for the video overlay. How do I get Xv working with compiz? Tell xine to prefer textured video. There should be a line like:    video.device.xv_preferred_method:Any in your ~/.xine/config file where you can change the preferred method used by xine for the video overlay. It may be that your graphics card or driver doesn't have the necessary support for textured video, or the video is rendered too slowly. ATI: you are likely to need xf86-video-ati later than 6.8.0; 6.9.0.91 or newer is recommended for slower/older hardware (< X1300) because the rendering speed has been improved a lot. Intel: 945 and later, at least, should be fine with xf86-video-intel 2.0 or later. Certainly with 2.2 or later. nVidia: will probably be fine. (FIXME) If you find that textured video is significantly slower or isn't supported, you should either not use compiz or tell xine to use the xshm video output driver. The aspect ratio of the video is wrong! Usually xine discovers the screen aspect ratio by querying the X-server and then adjusts the video automatically to make it look right. However, if that doesn't work try pressing "a" to manually change the aspect ratio. If you have a wide screen monitor, make sure the X-server is correctly configured. The X-server must know the physical size of the screen, which is independent of the resolution being used. For X.org, the screen size should be set in the "Monitor" section in the file /etc/X11/xorg.conf, as in the example below:    Section "Monitor"       Identifier "Monitor0"       VendorName "Monitor Vendor"       ModelName "DDC Probed Monitor - ViewSonic G773-2"       DisplaySize 320 240       HorizSync 30.0 - 70.0       VertRefresh 50.0 - 180.0    EndSection For XFree86, the filename is normally /etc/X11/XF86Config. Where DisplaySize specifies, in millimeters, the physical size of the monitor's picture area. What is the difference between discarded and skipped frames? Sometimes xine will output a message like that:    200 frames delivered, XX frames skipped, YY frames discarded The difference between these counters is a little subtle for the non developer. There are two threads running in order to display video: the decoder thread will deliver frames to the video output thread. The latter is responsible for scheduling the frames to be displayed at the right time. If your system can't keep up with decoding requirements, decoder will deliver overdue frames. Imagine if it finished decoding the frame tagged for displaying at 11:30 but xine clock marks 11:31. When this situation is detected, xine will try to skip decoding a few frames to recover. Not every decoder may support this feature. When the frame is decoded to be shown somewhere in future but the output thread doesn't get scheduled in time by the operating system to complete the operation, the frame is discarded. One cause might be the disk access operation, which may halt the system for a few miliseconds without DMA. See performance section tips above. Note that if a decoder can't skip frames for some reason, you would never see frames skipped (they would be all discarded). My xine is runing in black and white! / I only get a grey video output! This frequently happens with new Xv drivers or when switching to a different video card. Background is that different Xv drivers often use different ranges for the contrast/brightness/saturation settings. To fix this, try opening the xine settings window and try adjusting the sliders for contrast, brightness and saturation. Please note that some frontends save these settings in their config file so when you have found a working combination, make sure you exit xine cleanly so the values are saved. Which is the best video driver to use? xine supports several video drivers for outputing the image. These will differ on how the frames are copied to the video card memory, whether colourspace conversion and scaling is done in software or hardware, among other things. They may also differ on ease of use and stability. Most of the time, Xv should give the users a good trade-off between quality, compatibility and ease of use. This is why xine tries to use Xv by default. However some users may want to explore better the available hardware capabilities (eg. syncing frame drawing with monitor refresh). Also some Xv drivers contain slow copies and accessing the video card directly may yield performance gains. Drivers that access hardware directly includes VIDIX (warning: requires root priviledges or kernel helper). User may try one of those, but should be warned that with root access they can cause the system to crash hard. The support is also limited to a couple of graphics cards only. Graphic workstations like SGI have usually a good support for OpenGL. In that case, using OpenGL may be a better choice than XShm. However for most desktop systems the performance of OpenGL will be quite bad. OSD and overlay related questions What is this "unscaled" OSD about? Since version 1-rc3 of xine-lib supports a new method for rendering OSD (On Screen Display) and subtitles. This method uses a X11 extension called XShape that allows using screen resolution instead of stream resolution. It is called "unscaled" OSD because it does not scales with the video being played. Suppose you are watching a 320x200 video in full screen. Normal OSD would be blended at 320x200 and then scaled to full screen (lets say, 1024x768), resulting in big and ugly fonts. The unscaled overlay is drawn directly to screen, creating a sharper and better looking OSD. There are side effects too. Sometimes the unscaled overlay show some glitch just before disappearing. Some people may be annoyed enough by that and might want to disable the usage of unscaled overlay altogether. Unscaled OSD usage by subtitles and xine-ui is controlled by the following settings (~/.xine/config or ~/.config/gxine/config):    gui.osd_use_unscaled:0    subtitles.separate.use_unscaled_osd:0 I can't see the OSD or it leaves a black box over the image! If you are using xine-lib version 1-rc3 or newer, this is probably due buggy XV drivers that do not support unscaled OSD (the XShape extension) properly. There have being reports of some ATI drivers that don't allow displaying anything over the video. The VIA Epia binary drivers is reported to leave a black box where the OSD was displayed. The problem may be fixed by either updating the video driver, or disabling xine unscaled OSD support. Why colours of overlays/subtitles seem to be "leaking"? xine blends most overlays, specially the ones from DVD discs, directly over the image (scaled OSD). Unfortunately most codecs (like MPEG2) use a subsampled image format (YV12) that makes properly blending an interesting challenge. In short, this is a known xine bug. There have being discussions on improving the blending quality but, so far, nobody implemented a better (scaled) overlay renderer. Contact developers if you want to try doing something about it. Why external subtitles look so ugly? You are probably using a xine-lib version older than 1-rc3. Try upgrading your copy and read the section about unscaled osd. Why subtitles can't be displayed outside the video? It is possible, but older xine versions may not support it. There are two alternatives for rendering the subtitles outside the video image: Use the "expand" post plugin to increase frame height adding black bars to it. This will allow blending the subtitles over the black bars, since they will be part of the video now. Use unscaled OSD, as it does not requires any video to render the subtitles on. Also notice that DVD overlays (including subtitles) are meant to be displayed in a fixed position, this is how the DVD menu highlighting works. xine does not support moving them. What kinds of subtitle fonts does xine use? xine can use two kinds of fonts: TTF fonts If xine is compiled with freetype library xine recognizes and uses TTF fonts directly. xine fonts This is xine's native format. It's better because the font generator utility implements more features than the "on the fly" TTF renderer. The font for text subtitles is selected via config option subtitles.separate.font. You can specify xine font name (sans, serif, …) or file name of the TTF font. The directories $prefix/share/xine/libxine1/fonts and ~/.xine/fonts are searched for the fonts, with $prefix being the place xine-lib was installed to. Usually this is /usr/local or /usr. TTF fonts are also searched for in the current directory. How to create own xine subtitle fonts? xine's native subtitle fonts can be generated from TTF fonts with the utility xine-fontconv. It isn't compiled and installed by default but you can make it manually. You'll need freetype and zlib packages together with their versions for development plus a compiler, of course ;) Here's how you build xine-fontconv: Get the source of xine-fontconv utility from the misc directory within the xine-lib sources. Compile it:    gcc xine-fontconv.c -o xine-fontconv `freetype-config --cflags --libs` -lz You'll need some TTF font for generating. Characters in this font should cover all codepages you want supported, otherwise you'll have missing characters. Syntax is:    ./xine-fontconf font.ttf font_name [encoding1 [encoding2 […]]] For example default font sans was generated with following command:    ./xine-fontconv Aril_Bold.ttf sans iso-8859-1 iso-8859-2 iso-8859-5 \     iso-8859-9 iso-8859-15 cp1250 cp1251 There are displayed messages about missing characters on the screen during generating. It's OK if the missing characters are U+007f..U+009F. These characters come from iso-8859-1 and they aren't displayable. Encoding of external subtitles is bad. What is wrong? The encoding of the external subtitles is expected to be iso-8859-1 by default. You need to set an appropriate encoding in the config option subtitles.separate.src_encoding. Note that you also need a font which contains all characters from the given encoding. The default font sans and fonts serif and mono cover these encodings: iso-8859-1 iso-8859-2 iso-8859-5 iso-8859-9 iso-8859-15 windows-1250 windows-1251 Error Messages: What they mean and what you can do Starting xine crashes X, I am logged out of my desktop! xine itself is unable to crash X, so when your X server just shuts down or restarts with the login screen, there is something wrong with your X setup. Most common are problems with the Xv extension. Try running xine with the XShm video output plugin:    xine -V XShm If that works fine, you just proved, that the Xv extension is buggy. xine will remember the last used video output plugin, so the setting will stay at XShm. You could simply continue using this, but XShm is a lot slower than Xv, so consult the section on Xv and see if you can get it working. Usually you should look for updated versions of the X driver module that belongs to your graphics card. Starting xine fails with complains about audio drivers/devices! You can select the audio driver using the -A option. So try:    xine -A null If you have ALSA drivers installed, try:    xine -A alsa If you run ESD (not recommended), try:    xine -A esd If you run artsd, try:    xine -A arts "no video port found" You got the Xv extension, but your video card driver doesn't support it. First try to find a driver that does support Xv on your hardware (check your graphics card vendor). If your driver has Xv support but you can't get it working, try at a lower resolution (1024x768 is enough even for anamorphic DVDs). If all that fails, you can still use plain X11/XShm:    gxine -V XShm foo.vob "Unable to open dvd drive (/dev/dvd)" You probably don't have /dev/dvd (check that). If so, simply create a link /dev/dvd that points to your DVD device. Something like…    ln -s hdc /dev/dvd … should do the job. Also make sure you have read and write access on the device the symlink points to. See the dvd playback section for more information. My drive doesn't work and the kernel says "status=0x51 { DriveReady SeekComplete Error }" This error can be fixed by recompiling your kernel with the option "Use multi-mode by default" enabled in the IDE settings. "demux error! 00 00 00 (should be 0x000001)" Probably xine can't access your input source. Most commonly this happens when you're trying to play locked/encrypted DVDs. Remember that xine can't play such DVDs out-of-the box for legal reasons (see above). If it is legal where you live, you can try to install libdvdcss. Once you have done that and re-start xine, it should automatically detect and use it to play back encrypted DVDs. Another reason could be that your (RPC-2) DVD drive isn't set up for the right region (see above). "audio driver 'oss' failed, using null driver instead" First of all, make sure that your OSS Audio drivers are working (i.e. you can play music with other software). Maybe you're using alsa? If so, try gxine -A alsa to see if this helps. The most common reason for oss not working is that some other program is accesing your audio device. If you're using linux, the command fuser /dev/dsp should give you the PID of the process. If you are using GNOME, chances are that this is caused by ESD. Now you have two possibilities. Either deactivate ESD (temporarily) by right clicking on the sound monitor applet and selecting "Place Esound in standby" or just kill it. Then xine will use OSS audio output. The other method is to make xine use ESD for audio output with:    gxine -A esd This may result in worse playback – exact syncronization is not possible with esd, so using oss should be preferred. If you are using KDE, there is the possibility that the aRts sound daemon is currently running and thus blocking your sound device. You can check that by starting the aRts control (in your KDE menu it should be under Multimedia). If it is running, you can either use the aRts audio output plugin:    gxine -A arts Or you suspend the aRts daemon by checking the appropriate option in your aRts control. (recommended) Newer versions of arts have an auto-suspend mode – this can lead to some nondeterministic behaviour of xine if it is set up to use the audio device directly. Using arts is recommended in that case; however, you will lose the ability to do four/five channel audio output. "video_out: throwing away image with pts xxx because it's too old" This is a performance related problem. If you have a fast computer and this message is shown from time to time when playing a DVD or CD, it's very likely that DMA is not enabled for your drive. "No video plugin available to decode 'xxxxxx'." You have tried to play a stream using a unknown or unhandled codec. Possibly the file uses some obscure proprietary format and no information is available on how to decode it. If you're on an x86 platform (e.g. PC hardware) you might want to try installing binary-only windows medial, real networks and quicktime codecs (see above). "w32codec: decoder failed to start. Is 'xxxxxx' installed?" You probably don't have the win32 dll needed to decode this file. xine just crashed on me – i didn't get any error message OK, yes, that shouldn't happen and you're upset. We can understand that. But, to help you and of course to fix this, we need some information. So, let's go through the checklist and maybe prepare a nice bug report for the xine bug tracker: Did xine really crash (segfault) or did it hang (deadlock)? Can you reproduce the bug? (e.g. do you remember what you did and when you do it again it crashes again?) Is that a specific media file or format which crashes xine? (Have you tried other files types?) Check the console output (and include it in a bug report), maybe earlier there is some output that points to the problem. Your X server just froze on you? unfortunately that's a known problem with some chipsets and drivers (most commonly Savage chipsets) when using Xv. You might want to try running gxine -V XShm to see if the problem is related to the Xv driver. This will unfortunately be much slower, as lots of things are now done in software instead of hardware scaling/colour space conversion. Maybe at the time you read this, there's an X upgrade which fixes this for the Savage driver. If that works for you, please notify the xine crew at xine-user@lists.sourceforge.net, so they can update this FAQ! Even though we try to make each release as bug free as possible, xine is still under heavy development (nice excuse, isn't it? *grin*). If you write to the xine bug tracker make sure you include a the above information (when applicable) and also some information about your machine (operating system, cpu type and speed, gfx card, sound card, …) and please use a meaningfull subject line ("xine bug" is bad, "xine fails to play this quicktime trailer in fullscreen mode" ist much better). Thanks for taking the time to help improve xine.
xine-lib-1.2/doc/faq/faq.xsl0000644000175000017500000000036614647725152013504 0ustar meme xine-lib-1.2/doc/faq/.hgignore0000644000175000017500000000002114647725152013774 0ustar memefaq.html faq.txt xine-lib-1.2/doc/README.dxr30000644000175000017500000001541114647725152013172 0ustar meme ---------------------- xine ---------------------- a free video player Introduction ============ This documentation is intended for users of a dxr3 decoder card from creative labs or a hollywood plus decoder card from sigma designs. This version of xine contains a plugin for the mentioned hardware decoders "out of the box". The missing part is the linux kernel driver. The driver can be obtained from the main dxr3/hw+ linux development site at http://dxr3.sourceforge.net/ The various release formats (tarball, RPMs) are listed on http://dxr3.sourceforge.net/download.html As setting up the dxr3/hw+ driver is a little bit tricky, please consult also the HOWTO: http://dxr3.sourceforge.net/howto.html The xine dxr3 plugin requires at least the version em8300-0.8.1 of the linux drivers. Additional information on using xine with the dxr3 and on how to setup the kernel module along with precompiled RPMs can be found here: http://www.amalthea.de/xine/ XINE dxr3 plugin ================= There are two different ways in which xine can make use of the dxr3 card. 1. mpeg-1/mpeg-2 (DVD, VCD, ...) decoding and displaying. This is the normal use. Instead of doing the mpeg decoding in software, xine sets up the display (TV or overlay) and sends the mpeg data via the kernel driver to the mpeg decoder on the dxr3 card, very much like the Windows player that you problably got with the card. In this mode, you should be using the dxr3 video decoder plugin together with the dxr3 video out plugin. Xine should select the dxr3 video decoder plugin automatically when it encounters an mpeg stream, but it is possible it does not use the dxr3 video out plugin by default. In that case, start xine with the "-V dxr3" argument to specify the dxr3 video out plugin. If you use another video out driver, such as Xv or XShm, xine won't be able to use the mpeg decoding capability of the dxr3 hardware and will use libmpeg2 instead. Here's a short overview what happens when you play a dvd with xine using the dxr3 video out driver: DVD -> split mpeg video and audio and audio streams -> send mpeg video to dxr3 -> image appears on screen 2. displaying non-mpeg video on dxr3 hardware. Non-mpeg video may be AVI, quicktime, windows media files or whatever else xine can decode. This option must be compiled in and requires a supported mpeg encoder. At the moment there are three: - libavcodec from xine-lib's ffmpeg plugin (good quality, quite fast) - libfame from fame.sourceforge.net (very fast, good quality) (currently the 0.9 versions of libfame don't work, use the 0.8 versions) - librte (version 0.4) from zapping.sourceforge.net (fast, very good quality) If configure finds one or both it will compile in encoding support into the dxr3 driver. In order to use this driver for output instead of, say, Xv, just start xine with the command line option "-V dxr3", for example % xine -V dxr3 my_movie.avi Unlike in case 1), where the card does the video decoding, in this case Xine does the decoding in software, as usual, and sends the decompressed image to the video out driver. The dxr3 video out driver encodes, in real time, this image as an mpeg-1 intra frame and sends it to the mpeg decoder on the card. Using this trick, we can display arbitrary video formats via the tv out port of the dxr3 card. Nifty huh? The only downside is that it requires extra computational power, because we have to both decode the original video and encode to mpeg-1 in software. The cpu power needed depends of course on the resolution and the source format, but as a rule of thumb it is recommended to do this on a system with at least 128 MB of RAM and a P-III/Athlon at 800 MHz. Here's an overview what happens when you play an AVI this way (compare this with the previous overview!) -> split video and audio streams -> decode video stream -> encode video as mpeg-1 -> send mpeg-1 stream to dxr3 -> image appears on screen XINE configuration ================== The dxr3 video driver can be forced using the "-V dxr3" command line option. Only the tvmode value has to be edited if the default driver setting is not correct. Of course you can also use xine-ui's setup dialog to edit your configuration. Have a look at the DXR3 section of the configuration. Here are some additional settings interesting for the DXR3: video.driver: dxr3 The dxr3 video driver does all the necessary card setup and the mpeg encoding when playing non-mpeg video. (see above) audio.driver: oss The em8300 audio output is available as an usual OSS device. Therefore the audio driver must be set to oss. Can also be specified using "-A oss" on the command line. audio.device.oss_device_number: 0-16 Machines with a dxr3 installed often have a usual soundcard too. If audio playback occurs on the wrong device, the demanded device can be set using this option. engine.decoder_priorities.dxr3-mpeg2: 10 Priority of the dxr3 video decoder plugin. <5 means that hardware decoding by the card will be disabled and libmpeg2 will be used instead. Therefore all video material including mpeg will pass the software decoding and mpeg re-encoding stages. (see also above explanation of the encoding mode) Zooming Feature (TVout Only) ============================ Pressing the 'z' key enables another tv-only mode which zooms into the centre of a 16:9 video to display much smaller (or none) black bars top & bottom. It crops the video on the left and right sides to maintain the correct aspect ratio. Use SHIFT-z to disable. TV mode Cycling Feature ====================== Pressing CTRL-o repeatedly will allow you to cycle between tv modes PAL, PAL60, & NTSC. The format selected will only remain valid for the current xine session, on startup the tv mode will revert to the default in .xine/config VGA overlay feature =================== In previous versions of xine support, one had to use dxr3view in order to use the em8300 overlay mechanism. Now, since the xine 0.5 version, it is possible to output the em8300 overlay directly in the video out window. In order to activate it, "dxr3.output.mode" must be set to "overlay". But it won't work until the old dxr3view works too (just a check). Before a first use, "autocal" has to be run. This will store the right overlay parameters in "~/.overlay". For more information, please consult the dxr3 howto too. As of version 0.9.5, you can now switch between overlay and tv-out modes on-the-fly, simply by hiding the video_out window ('h' key by default, see the README file). If you want to start xine with video on the tv, you can run xine with the -H option to auto-hide the vo window, instead of changing the configuration (although you can still do that instead if you prefer, of course). Have a look at the previous explained configuration options dxr3.output.keycolor and dxr3.output.keycolor_interval too. xine-lib-1.2/doc/README.MINGWCROSS0000644000175000017500000001326014647725152014005 0ustar memeIntroduction ------------ MinGW is short for the Minimalist GNU Windows. It's package which allows you to use GCC and other GNU tools to compile native windows programs. In this case "native" means programs which don't require extra DLLs like cygwin DLL. Mingw32 programs use DLLs supplied with all current Win32 platforms. Thus the programs are light weight and easy to distribute. This document describes by shell commands how to compile and install MinGW cross development tools on Unix host and how to use it for building windows version of xine. See README.WIN32 how to use it to build xine. For creating 64bit version of Mingw32 toolchain, see mingw/mingw-w64-doc/howto-build/mingw-w64-howto-build.txt in mingw32-w64 sources. Download -------- MinGW packages: http://mingw.org, or http://mingw-w64.sourceforge.net 1) binutils (sources), binutils-build.sh 2) gcc-core, gcc-c++ (sources), gcc-build.sh 3) w32api, mingw-runtime (binaries and sources) DirectX headers (tested with version 7): http://www.google.com/search?hl=cs&q=win32-dx7headers.tgz http://www.google.com/search?q=dx7adxf.exe Pthread Win32: ftp://sources.redhat.com/pub/pthreads-win32/ (plus 64bit external patches for mingw32-w64) zlib: http://www.zlib.net Build ----- In the following text are used symbols $PREFIX and $USER with this meaning: $PREFIX .... directory of the mingw cross environtment $USER ...... current user 1. compile binutils tar xzf binutils-2.13.90-20030111-1-src.tar.gz mkdir bin cd bin ../binutils-2.13.90-20030111-1-src/configure \ --target=i686-pc-mingw32 \ --prefix=$PREFIX make su make install exit 2. add $PREFIX/bin into PATH ... 3. compile compiler (gcc-core, gcc-c++) # # prepare runtime environment from binaries # mkdir runtime cd runtime tar xzf ../w32api-2.5.tar.gz tar xzf ../mingw-runtime-3.3.tar.gz cd .. # # compile and install the compiler # # if you'll want rerun this step, I recommend delete # $PREFIX/i686-pc-mingw32/sys-include # tar xzf gcc-core-3.3.1-20030804-1-src.tar.gz tar xzf gcc-g++-3.3.1-20030804-1-src.tar.gz mkdir gcc-bin cd gcc-bin # needed for the copying header files su # more option may be needed for successfull compilation, # see gcc-3.3.1-1-build.sh ../gcc-3.3.1-20030804-1/configure \ --disable-shared \ --target=i686-pc-mingw32 \ --with-headers=../runtime/include \ --with-libs=../runtime/lib \ --prefix=$PREFIX exit make #or recommended: make CFLAGS=-O2 LDFLAGS=-s su make install exit 4. recompile w32api and mingw-runtime from sources (optional) # # installing must be into $PREFIX/i686-pc-mingw32 # tar xzf w32api-2.5-src.tar.gz cd w32api-2.5 ./configure --prefix=$PREFIX/i686-pc-mingw32 --host=i686-pc-mingw32 make su make install exit # # installing must be into $PREFIX/i686-pc-mingw32 # tar xzf mingw-runtime-3.3-src.tar.gz cd mingw-runtime-3.3 # copying w32api headers into ./include (because of a bug in runtime # package) ... # compiling CC=i686-pc-mingw32-gcc \ DLLTOOL=i686-pc-mingw32-dlltool \ AR=i686-pc-mingw32-ar \ AS=i686-pc-mingw32-as \ RANLIB=i686-pc-mingw32-ranlib \ ./configure --prefix=$PREFIX/i686-pc-mingw32 --target=i686-pc-mingw32 make su make install exit 5. install DirectX headers and other libraries su cd $PREFIX/include # untar dx7headers.tar.gz (maybe to a subdirectory) ... exit 6. compile and install pthreads-win32 tar xzf pthreads-w32-2-8-0-release.tar.gz cd pthreads-w32-2-8-0-release/ make CROSS=i686-pc-mingw32- clean GC # # possibility to use pthread library in M$ Visual C (optional) # mv pthread.def pthreadGC2.def wine LIB.EXE /machine:i686 /def:pthreadGC2.def # # installing # su mkdir -p $PREFIX/pthreads-win32/bin mkdir -p $PREFIX/pthreads-win32/include mkdir -p $PREFIX/pthreads-win32/lib cp pthreadGC2.dll $PREFIX/pthreads-win32/bin/ cp libpthreadGC2.a pthreadGC2.lib $PREFIX/pthreads-win32/lib/ ln -s libpthreadGC2.a $PREFIX/pthreads-win32/lib/libpthread.a ln -s pthreadGC2.lib $PREFIX/pthreads-win32/lib/pthread.lib cp pthread.h semaphore.h sched.h $PREFIX/pthreads-win32/include/ exit 7. compile and install zlib tar xzf zlib-1.2.5.tar.gz cd zlib-1.2.5 make -f win32/Makefile.gcc PREFIX=i686-pc-mingw32- STATICLIB=libz-static.a IMPLIB=libz.a # # possibility to use zlib library in M$ Visual C (optional) # cp win32/zlib.def zlib1.def wine LIB.EXE /machine:i386 /def:zlib1.def # # installing # su mkdir -p $PREFIX/zlib/{include,lib,bin} cp zconf.h zlib.h $PREFIX/zlib/include/ cp libz.a libz-static.a zlib1.lib $PREFIX/zlib/lib/ cp zlib1.dll $PREFIX/zlib/bin/ exit Using MinGW cross development tools ----------------------------------- Now we can build xine library for Windows by this way: # # configure for mingw cross compiling # (the build option is needed only for forcing cross compilation mode) # ./configure \ --host=i686-pc-mingw32 \ --build=i686-debian-linux \ --disable-freetype \ --disable-vcd \ --with-dxheaders=$PREFIX/include/dx7headers \ --with-zlib-prefix=$PREFIX/zlib \ --with-pthread-prefix=$PREFIX/pthreads-win32 # # compile # make # # install # make install DESTDIR=/tmp/xine-lib-mingwcross rm /tmp/xine-lib-mingwcross/lib/xine/plugins/1.1.0{/,/post}/*.a # # create libxine-1.lib file (optional, when we want to use xine library in # M$ compilers) # # we will need wine and some tools from M$ Visual C: LIB.EXE, LINK.EXE, # MSPDB60.DLL # cd /lib cp ../bin/libxine-1.dll . wine LIB.EXE /machine:i386 /def:libxine-1.def rm libxine-1.dll xine-lib-1.2/doc/internal/0000755000175000017500000000000014647725152013245 5ustar memexine-lib-1.2/doc/internal/HOWTO.release0000644000175000017500000001762714647725152015524 0ustar memeA step-by-step guide to xine releases ===================================== Siggi Langauf, 2003-12-17 This guide provides a simple "recipe-like" guide to making releases. While only strictly covering releases of the "xine-lib" module, the procedure is almost the same for all the other modules. You only have to substitute the module name, and probably make other tests. ;-) Okay, so let's describe your starting point: You're going to be the release manager. The last release has been a long time ago. By now, many important bug fixes have accumulated in CVS while users (who are not aware of any mailing list besides xine-announce) are wondering if xine is still a maintained project. However, everybody's committing wildly to CVS, preferrably redesigning the core xine engine and often forgetting to make notes about their work in the ChangeLog. Currently, best practice to get a release out looks like this: 1) announce the upcoming release on xine-devel! Ask developers: - if they think CVS is ready for a release - if there are any important known bugs - to double-check and update the ChangeLog 2) make pre-release checks (many of these should be already done, but now is the time to go through the whole checklist: - does it build? (probably best: check nightly build logs) note: test at least on an ia32 machine _and_ any big endian box - does it run? (again: play a simple file on at least intel+any BE platform using the new library) - is it feature-complete? Ideally, you'd test all demuxers, decoders and post plugins, along with all audio and video drivers. As this is totally unrealistic, you'll have to restrict yourself to a practical subset. This should include the [standard test parcours] (see below) note: We're going to collect all features in a strategical overview and identify at least one dedicatet tester for each feature. So check that overview! Ask testers to test if their feature is marked "untested". - you might want to run "make release-check", it will tell you about files from CVS missing in the release; be sure to check these AND you might want to run "make distcheck", this will test the packaging, building, and testing of all xine-lib. This will alert you to any missing files from the tarball or problems in the Makefile rules. - does "make dist" produce a complete (ie. compilable) tarball (note: nightly build logs will tell you this.) 3) Versioning You should already know by now, from which branch of CVS the release is going to be made. The current scheme is to have a stable branch from which the subminor releases like 1.0.1, 1.0.2,... are made and an unstable branch in CVS head, which is going to become the next minor (1.1) or major (2.0) xine-lib version. Make sure you know - what the new release should be called (the "marketing version" part of the tarball name, for example) - if any _internal_ structures (like xine_t) have changed - if any _external_ interfaces (include/xine.h) have been added or changed Then check our 3 version systems: If any internal structures have changed, you may have to increase some (or all) of the plugin IFACE_VERSIONs. In that case, you might want to ask for help, so this doesn't take the whole day... Then, edit configure.ac: - set XINE_MAJOR, XINE_MINOR, XINE_SUB according to the marketing version - set the XINE_LT_* constants according to the comments. DO _NOT_ mess with these! If you're not sure about changed/added interfaces diff include/xine.h against the previous release and/or ask! 4) cvs commit your changes, and update CVS. Double-check CVS logs. Be sure people have stopped comitting wildly. If they haven't: mail to xine-devel and waitl till the dust settles! 5) make a candidate tarball: make maintainer-clean; rm .cvsversion; ./autogen.sh; make dist (this is the time to make some tea, or better some strong coffee ;) 6) check the candidate tarball: - does it have the right name? - does it unpack, compile and install correctly? note: make sure to build with as many features as possible on a Debian box, "apt-get build-dep xine-lib" and "dpkg-buildpackage -rfakeroot" are a good way to do that - test the candidate (and make sure you are running exactly the new version!) This should at least cover the [standard test parcours] If you find any errors: fix them (get help on xine-devel or #xine) and go back to step 4) The tests have now all passed. you've got the release tarball in your hands. 7) Tag the release: cvs tag -R xine-1_2_3-release (this would be the tag for xine-lib-1.2.3, for example) 8) upload the tarball to ftp://upload.sf.net/incoming note: you can start the upload while CVS is tagging 9) Write release notes: Read through the ChangeLog, try to look at any changes from a "what would users note" perspective: - How would you classify the release (bugfixes, new features, ...)? - Has anything visibly changed from previous releases? - Are there any pitfalls/tricks for this upgrade? - Which are the most obvious improvements? Include the output of "md5sum xine-lib-1.2.3.tar.gz" in the release notes and "gpg --clearsign" them. 10) Click your way through the file release system on http://sf.net! Copy&Paste both the (signed!) release notes and ChangeLog in there. Make sure to check the "keep my preformatted text" box 11) write the announcement for xine-announce: You start with the release notes from step 9, without the signature, but including the MD5 sum. rewrite it to look like an email announcing the release. Copy&paste all ChangeLog entries for this release into the announcement. Make sure you have GPG clearsigned the announcement when sending it! (also make sure it gets immediately approved by the xine-announce moderator!) 12) write the announcement for xine-project.org: You need to have an account on alioth.debian.org and a checked-out copy of ssh://hg.debian.org//hg/xine-lib/xine-project-www/ (using Mercurial). Add the new news item near the top of pages/news/items.xml (use the provided template), run update.sh (requires xsltproc; if this fails, re-edit), check that it looks fine in a convenient browser, then commit and push the change. At present, you will need to request a web site update via #xine on irc.oftc.net or by contacting a site admin. You should include a link to the SourceForge Release notes/Changelog page and one to the download page. Warning: triple-check that you get the XML correct! 13) write the Freshmeat announcement: use your freshmeat account to log into their website, if you aren't permanently logged in, anyway. go to the xine project, click "add new release" and work your way through. This announcement must be a bit more terse version of what you wrote in step 9). And it should make people interested in the release. That's it. Finally. At this point, you have probably earned your sleep ;-) The [standard test parcours] ---------------------------- There are a few things that simply _must_ work. So take a few minutes to test at least: - an MPEG1 video file - a DivX AVI file (with AAC sound, alternatively test _any_ file with AAC sound in addition) - a DVD (test menu navigation, button highlighting, subtitles and video playback) - a VCD (preferrably with menu) - an MP3 file, with goom visualization (does Ctrl+i overlay correct info?) - a QuickTime or mp4 file For all those files, check: - if audio/video are in sync - video looks good - audio sounds correct - there is no visible jitter or stuttering - try to seek a bit (more, yes, stress it!) If you find any anomalies: mail to xine-devel immediately! If you're lucky, somebody will fix it before you're throught with the rest of your release preparations. Asking on #xine may also help. xine-lib-1.2/doc/internal/README0000644000175000017500000000044214647725152014125 0ustar memeThis directory holds some documentation which is "internal to the xine project". These files should not be distributed, not even with released tarballs, as they are only useful in their most recent version, and only for a few core developers who are supposed to have a CVS tree, anyway... xine-lib-1.2/doc/Makefile.am0000644000175000017500000000054414647725152013470 0ustar memeinclude $(top_srcdir)/misc/Makefile.common SUBDIRS = man/en hackersguide faq dist_doc_DATA = README README.dvb README.dxr3 \ README.freebsd README.irix README.network_dvd README.opengl \ README.solaris README_xxmc.html README.MINGWCROSS \ README.WIN32 README.macosx docs clean-docs: @cd faq && $(MAKE) $@ @cd hackersguide && $(MAKE) $@ xine-lib-1.2/doc/README.WIN320000644000175000017500000001224114647725152013112 0ustar memeIntroduction ------------ This document describes how to build xine library under Windows. Download -------- Checkout source code from CVS (under Windows can be used CygWin or another tool). You will need 'xine-lib' (the library) and 'xine-win32' (testing Windows frontend). Instead xine-win32 you can use any other frontend working under Windows (toxine, ...) Build ----- There are three different ports on Windows: 1) MinGW (the simplest and recommended) 1) CygWin 3) M$ Visual C, or maybe .NET (recommended for debugging) 1. MinGW port ------------- This is the best way. Result is 100% native Windows library with all optimizations. Also you can use cross-build from comfortable unix-like system. See README.MINGWCROSS for more information. Requirements for compilation under Windows: a) installed MinGW b) LIB.EXE, LINK.EXE and MSPDB60.DLL from M$ Visual C (necessary only for usability created xine library by M$ compilers) How to build: # # configure for building in MinGW under Windows # ./configure --with-dxheaders=DIRECTORY # # compile # make # # install and manually remove the static plugins # make install DESTDIR=/tmp/xine-lib Prepare xine library for using in M$ compilers too: # run terminal window (MinGW for example) ... # creating libxine-1.lib file cd /lib cp ../bin/libxine-1.dll . /VC98/BIN/LIB.EXE /machine:i386 /def:libxine-1.def rm libxine-1.dll For 64bit, use x86 instead of i386: /VC98/BIN/LIB.EXE /machine:x86 /def:libxine-1.def 2. CygWin port -------------- This is the second way. Created library won't be 100% windows native: it will contains some additional emulation code and I'm not sure, if it can be used with M$ compilers. It's possible to use CygWin for cross-compiling with MinGW. How to build: # # configure # ./configure --with-dxheaders=DIRECTORY # # compile # make # # install # make install DESTDIR=/tmp/xine-lib 3. M$ Visual C port ------------------- This build system is different from the one, used for all other platforms, but we partially keep it up to date - just for experimental reasons, but only if we have access to some M$ computer. Reasons, why not to use this port: - can't compile included ffmpeg (important multi-decoder in xine) - can't compile new assembler code (it means degradation of power) - never 100% up to date - somebody must own the OS and compiler Reasons, why to use this port: - obtaining cute backtrace after crash, debugging How to build xine in M$ Visual C: - Set up MSVC to look for DirectX headers. - Download Pthreads Win32 (ftp://sources.redhat.com/pub/pthreads-win32/), from prebuild directory install include/*.h, lib/pthreadVC2.lib and lib/pthreadVC2.dll, rename pthreadVC2.lib to pthread.lib set up MSVC - libraries and headers. - Download zlib (http://www.zlib.net), instal all in include and lib, set up MSVC - libraries and headers. - Copy include/xine.h.in to include/xine.h, replace @text@ by right values (eg. XINE_MAJOR 1, XINE_MINOR 1, XINE_SUB 0, XINE_VERSION "1.1.0") - Open up the xine.dsw workspace/project in MSVC. - Click on the FileView tab. - Build the following projects in this order: libxinesuppt libxine libdvdnav - Next build any desired plugins (decoders/demuxers ...). The ao_out_directx2 and vo_out_directx are required for Win32. ao_out_directx is obsoleted. There is a possibility to use the vo_out_sdl but sdl.dll must be present for that to take place. There have also been some issues observed with the directX video driver on some machines. - If you want ffmpeg decoder plugin, you must use precompiled version. If you want to compile it, you should have the files LIB.EXE, LINK.EXE and MSPDB60.DLL from the Visual C++. Under MinGW you can compile ffmpeg for xine by this way: # # run the script/patch necessary for MSVC and for xine # cd ffmpeg sh ../xine-lib/win32/scripts/ffmpeg_win32.patch # # (for cross-compiling add "--cross-prefix=i386-mingw32-" # and "--disable-mmx") # ./configure \ --enable-gpl \ --enable-pp \ --enable-shared \ --disable-zlib \ --enable-mingw32 make # # linking by running this command in libavcodec/ directory (use wine for # cross-compiling) # # it's done automatically if you have 'LIB.EXE' linked to 'lib' in your # $PATH and set wine # wine LIB.EXE /machine:i386 /def:avcodec.def # # install # PREFIX=/tmp/ffmpeg; make install prefix=$PREFIX bindir=$PREFIX libdir=$PREFIX/lib cp libavcodec/avcodec.lib $PREFIX/lib cp libavformat/avformat.lib $PREFIX/lib cp libavutil/avutil.lib $PREFIX/lib Status ------ There remains many of work yet on Windows port. Limitations: - file > 1GB doesn't work (MinGW problem?) - seeking doesn't work with testing frontend, but it should be OK in library - libcdio not ported to mingw32-w64 (frelling headers :-)) Bugs: - random crashes and random locks in stress tests - non-seekable input plugins crash - ffmpeg bug visible for some video sizes xine-lib-1.2/doc/README.macosx0000644000175000017500000001570414647725152013611 0ustar memeBuilding -------- Mac OS X builds of xine-lib are built using the same autoconf-based build scripts that are used on other Unix-based platforms (e.g., Linux, FreeBSD). There is no Xcode project, nor is there any intention to create and/or maintain one in the future. There's no good reason, and it would only add unnecessary complexity and an additional maintenance burden. Currently, xine-lib is only supported on Mac OS X 10.4 Tiger. There are no plans to support older versions of Mac OS X for a variety of reasons. As of xine-lib 1.2, specific versions of build tools are required. They are as follows: - GNU M4 1.4.7 (1.4.9 is current, 1.4.2 is installed on Tiger) - autoconf 2.59 (2.61 is current, 2.59 is installed on Tiger) - automake 1.9 (1.10 is current, 1.6.3 is installed on Tiger) - GNU libtool 1.5.20 (1.5.22 is current, 1.5 is installed on Tiger) When building on Tiger, since some of the system-installed tools are out of date, you'll need to update at least some of them. It is recommended that you bring all of them up to current releases as listed above. The order in which you install updated tools to replace the system-installed versions is important, and in some cases, specific build options are required for them to work properly. 1. Install GNU M4 >= 1.4.7 - This is optional if you use the system-installed version of autoconf; however, if you install a newer version of autoconf, you MUST install a newer version of GNU M4 first. - Run its configure script with --program-prefix=g 2. Install autoconf >= 2.59 - This is optional, but it is recommended that you use autoconf 2.61. - No special configure options are required. Simply configure, make, and make install. 3. Install automake >= 1.9 - This is required, and since it is required, it is recommended that you use automake 1.10. - No special configure options are required. Simply configure, make, and make install. 4. Install GNU libtool >= 1.5.20 - This is required, and since it is required, it is recommended that you use GNU libtool 1.5.22. - Run its configure script with --program-prefix=g ** A special note about GNU libtool: Mac OS X has its own utility called libtool that is NOT the same as GNU libtool, but the Developer tools install GNU libtool as well. The system- installed version of GNU libtool is installed with a g- prefix, and xine's build scripts expect this as well if you install your own version. If you do not install GNU libtool with a g- prefix, xine's build scripts will pick up the system-installed version instead of the newer one you install! With your tool chain brought up-to-date with xine's requirements, you can go ahead and build xine-lib by first running configure, then make, and finally, make install, just as you would on, say, Linux. If you are building from a source repository snapshot or checkout, you will need to run autogen.sh first. When running configure, it's best if you do not attempt to forcibly enable most options that are disabled by default. For example, DVB support is disabled by default on Mac OS X because it doesn't work. Enabling it may allow it to build okay, but it will not work at runtime. The one exception is --enable-macosx-universal. Universal binaries are not enabled by default, but they are fully supported. With this optional enabled, the default is to build FAT binaries for ppc and i386; however, you may also enable support for ppc64 and/or x86_64. For example: ./configure --enable-macosx-universal=i386,ppc,x86_64,ppc64 CoreAudio audio output support will be enabled by default. Mac OS X video output support will be enabled by default. Xwindows support will be enabled by default for video output (using XShm, Xv, and OpenGL). In most cases, you'll probably want to disable Xwindows support, and that is safe to do by adding --without-x to the configure command-line. Running ------- Very limited run-time testing has been done so far. The Mac OS X port of xine-lib is in its early stages, only recently becoming buildable at all, though some quick-and-dirty efforts have been made in the past to build and run on Mac OS X. At this time, native video output only works with Objective-C Cocoa windows using the XineOpenGLView class that resides in libxineMacOSXVideo.dylib. This works, but it isn't yet stable enough for every day use. Xwindows video output support builds, but it is unknown whether it works. If you plan on using the Cocoa video output support, you'll need to link with both libxine.dylib and libxineMacOSXVideo.dylib as well as libxine.dylib. Instantiate an audio output port as follows: ao_port = xine_open_audio_driver(xine_instance, "coreaudio", NULL); Instantiate a video output port as follows: vo_port = xine_open_video_driver(xine_instance, "macosx", XINE_VISUAL_TYPE_MACOSX, view); In both cases, xine_instance is the return from xine_new() that has been then been initialized with xine_init(). For video output, the view argument to xine_open_video_driver() is the XineOpenGLView instance in which to render. The Future ---------- A full, proper port of xine-lib to Mac OS X is in progress. Efforts are under way to make as many of the various plug-ins work properly on Mac OS X as makes sense, but it is unlikely that full support will be complete by the time that xine-lib 1.2 is released. The following is a list of the things that will definitely be done: * CoreVideo support for video output instead of the current NSOpenGLView- based video output plug-in. The existing video output plugin will not be retained as a plug-in, but the code will remain available based on the new CoreVideo video output plugin. * Building xine-lib as an application bundle embeddable framework, as well as a system-wide installable framework, though the utility of the latter is questionable. * Enable VCD input support. Mac OS X specific code is required in xine-lib itself to support this. Currently, only FreeBSD, Linux, and Solaris can build the VCD input plugin. * Investigate enabling Real binary and Win32 binary support for Intel Macs. * Investigate better font support without the need for FreeType2. * SPDIF pass-through for CoreAudio Known Issues ------------ * Building on Leopard does not work due to build problems with ffmpeg. * VCD support is not yet available, though internal versions of libcdio and libvcd will build. If you enable VCD at configure time, the build WILL fail. * Real binary codec support is not yet available. * On Intel, Win32 binary codec support is not yet available. * Very little run-time testing has been done. Basic file input and ffmpeg based demux/decoding is known to work. * Xwindows support builds, but it has not been tested at all. * Applications using xine-lib must link with both libxine.dylib and libxineMacOSXVideo.dylib if they will be using the Cocoa video output support. xine-lib-1.2/doc/README_xxmc.html0000644000175000017500000002325114647725152014316 0ustar meme Xine's xxmc plugin

Compiling and installing Xine's xxmc plugin.

  1. Compiling and installing Xine's xxmc plugin.
    1. Background
    2. Needed drivers and libs
    3. Configuring and installing
    4. Running the plugin
      1. General
      2. Caveats
      3. Optimizing
      4. Deinterlacing
    5. Chips supporting XvMC acceleration using the xxmc module.
      1. VIA Unichrome / Pro
      2. Nvidia
    6. FAQ

Background

The xine xxmc plugin supports playback with
  • Standard XvMC, as supported by many Nvidia chips.
  • VLD XvMC, as supported by the VIA Unichrome / Pro chips, up to 1024x1024.
  • Standard Xv. The xxmc plugin will fall back to Xv if any of the above fails.
There is no API or hardware feature called "xxmc". It is only the name of Xine's plugin, since the name "xvmc" was already taken. The name "xxmc" stands for eXtended XvMC, and it is extended in the sense that it also includes support for VLD XvMC, which is a nonstandard extension to XvMC, proposed by the Unichrome project.

Needed drivers and libs

  • You need an XvMC driver for the chip you want to run accelerated on. (This does not apply if you only want to run Xv on the accelerated driver). Drivers for Nvidia chips are on Nvidia's website. Drivers for the VIA CLE266 chip are present in Xorg CVS or downloadable as patches at The Unichrome project's site
  • You need the XvMC wrapper, present in Xorg CVS, or downloadable from The Unichrome site

Configuring and installing

Make sure you have the XvMC wrapper installed. The wrapper will try to figure out at run-time what xvmc-hardware specific driver to load. If it fails it will open the file /etc/X11/XvMCConfig or /usr/X11R6/lib/X11/XvMCConfig and try to load the hardware-specific library mentioned in that file. If you downloaded the XvMC wrapper from the unichrome site, the default XvMCConfig will make the XvMC wrapper try to load the Nvidia XvMC driver. If you want to use it with the VIA Unichrome /Pro chips, you will have to edit the XvMCConfig file to contain the single word

libviaXvMC.so.1

Now configure and compile xine-lib as usual. Make sure that the xxmc plugin got enabled by configure or autogen.sh.

Running the plugin

General

Start xine with xine -V xxmc, or kaffeine with kaffeine -x xxmc. If the XvMC wrapper fails to load a hardware specific library or fails to read the XvMCConfig file it will specifically tell you so. If you have the wrong hardware-specific library specified in the XvMCConfig file, the xxmc plugin will think that you are running against a remote X-server and fall back to software decoding. If the driver uses hardware acceleration it will specifically tell you so. At the moment, the XvMC implementation only accelerates mpeg1 and mpeg2 files, if the hardware advertises support for these file types.

Caveats

Some Nvidia chips seem to use very much CPU when subtitles are displayed, and black areas of the screen are full of small white dots. These chips only use motion compensation accelaration, and are bad at it as well. You're better off running the Xv plugin with these chips. The white dots are due to hardware- or driver bugs. Nvidia chips that supports IDCT acceleration also seem to support motion compensation acceleration correctly.

OSD might be rendered in the wrong color with Nvidia chips. To work around this use the xine config option

video.device.xvmc_nvidia_color_fix:1

This is due to a bug in the Nvidia XvMC drivers, and this bug is probably also present in the i810 drivers.

There is also a bug in xine's XvMC support for interlaced streams with IDCT and motion compensation accelerations. The xxmc plugin will fall back to plain Xv for these streams. Hopefully this will be fixed in the not too distant future.

Optimizing

If you are running VLD XvMC on the VIA Unichrome / Pros there are some options that may affect performance:

video.device.unichrome_cpu_save:1

Will save a lot of CPU-power if you are running a 2.6 series kernel. It does this by sleeping while the hardware decoder works. Otherwise it will spend a lot of CPU waiting for decoder completion.

video.device.xvmc_more_frames:1

Will allocate 15 XvMC surfaces instead of 8. This is very useful if you are using vdr-xine and want to avoid buffer-underrun stutters in xine. Don't use this with Nvidia cards since they only allow a maximum of 8 frames. If your driver does not allow 15 frames and you turn this option on, it will abruptly fall back to software rendering, causing some rendering glitches while doing so.

gui.osd_use_unscaled:0

Don't use unscaled overlays for OSD. Sometimes the X server will have severe problems painting the OSD surface when unscaled OSD:s are used. This will be visible as severe stutters when ANY overlay (OSD or subtitle) are displayed and removed. Use this option for scaled OSD which is considerably faster with CLE266, since blending is done in hardware. This option is usable also with Nvidia cards, but I've never seen problems with unscaled OSD with those.

Deinterlacing

XvMC can only do very simple one-field deinterlacing in hardware. It's also impossible to use software deinterlacing, since XvMC does not allow xine to read the content of a decoded frame. Therefore, when you run a hardware accelerated stream, Interlacing will be toggled by pressing "i". If the xxmc plugin has fallen back to Xv and software decoding, post plugins will take care of deinterlacing.

BOB deinterlacing (alternating between top and bottom field at double the frame-rate) for XvMC accelerated streams is available as an experimental feature. It is activated using the config option

video.device.xvmc_bob_deinterlacing:1

If this option is enabled, The xxmc plugin will use bob as deinterlacing method when deinterlace is toggled pressing "i". To get the best results from this method, the screen update frequency should be a multiple of double the frame rate. For example, if the frame-rate is 25Hz, Your screen update frequency should be 50Hz or 100Hz. I have been able to get reasonable results using a 75Hz update frequency, however.

Chips supporting XvMC acceleration using the xxmc module.

VIA Unichrome / Pro

  • CLE266: up to 1024x1024.
  • K8M/N800: up to 1024x1024. Use Unichrome X drivers >= r31.
  • CN400: HDTV capable. Driver support is under development.
  • PM8X0: HDTV capable. Driver support is under development.

Nvidia

  • Quadro FX 1000 (IDCT / Mocomp)
  • Please help me fill in here.

FAQ

Q: The xxmc plugin is not enabled when I configure xine-lib
A: Check that you have installed the XvMC wrapper, and that you've run "ldconfig -v" as root after that.

Q: The XvMC wrapper complains when I start xine.
A: Check that you have created an XvMCConfig file specifying the relevant driver name.

Q: I'm running on a Nvidia card and my OSD colors are wrong.
A: See "caveats" above.

Q: I'm running VDR-xine and the playback stutters.
A: See "optimizing" above.

Q: I'm running on a CLE266 and I get severe stutter when subtitles are displayed.
A: See "optimizing" above.

Q: Can I use the xxmc plugin without the XvMC wrapper?
A: Yes, you can link directly with a hardware specific library, but this is not recommended. Run "./configure --help" to check which options to use.

xine-lib-1.2/doc/README0000644000175000017500000000174314647725152012316 0ustar memexine-lib/doc/README This directory contains documentation for xine-lib (the xine engine). Parts of this documentation are targeted towards end-users, other parts toward developers. Some frontends (e.g. xine-ui) may come with additional, frontend-specific documentation. The documents in this directory try to talk about xine engine features common to all frontends. faq/ contains the xine engine FAQ hackersguide/ contains the xine hacker's guide for developers man/ contains some general manpages about xine-lib README.dvb instructions on how to get DVB (DigitalTV) working in xine README.dxr3 instructions on how to get use the DXR3 (hollywood+) in xine README.freebsd hints on running xine on FreeBSD README.irix hints on running xine on IRIX README.macosx hints on building xine on Mac OS X README.network_dvd how to play DVDs / Audio CDs over the network README.opengl how to use xine's OpenGL video output README.solaris hints on running xine on Solaris xine-lib-1.2/doc/README.network_dvd0000644000175000017500000000633514647725152014645 0ustar meme Playing DVDs / Audio CDs over the network ========================================= xine can be used to play DVDs and Audio CDs over the network. ok, but.... why? there are some reasons people want to do that: - because you may have a 200 discs DVD changer on your garage and you want to watch them on your room. - because you don't want to have a lousy cdrom driver around when listening to your favorite music. - because the computer that is hooked to the TV doesn't have a dvdrom. - because you can :) network block devices --------------------- yes, network block device (nbd) could be an option for that. however: - they don't support ioctls which are needed for cd audio playback and dvd key exchange. (obs: one may write a custom ioctl code for enbd) - a completely user space solution is more portable. - the user space solution can handle failures more gratefuly and gives better control of closing/opening the device. installation for audio cds -------------------------- - you must compile the cdda_server.c that comes with xine-lib sources: xine-lib$ cd misc xine-lib/misc$ make cdda_server gcc -W -Wall -g -o cdda_server cdda_server.c -ldl Your xine-lib source tree needs to be configured for that, so please run ./configure in the toplevel sourcedir on a fresh tree. - start cdda_server at the machine that has the cdrom drive: xine-lib/misc$ ./cdda_server /dev/cdrom 3000 note: 3000 is the port number to listen. - start xine on the client machine with: $ xine cdda://server_address:3000/1 that will play the first track of the CD. in order to use the GUI button for "CD" you have to change the setting media.audio_cd.device to point to the server. installation for dvds --------------------- - compile and run cdda_server (see above). note: you may also need to install libdvdcss or some equivalent library on your server. - patch libdvdcss on the client. note: no CSS code is needed at all, so it would be possible to use a kind of "dummy" dvd library that is API compatible with libdvdcss. a sample patch is provided for libdvdcss-1.2.6, install it as follow: libdvdcss-1.2.6$ patch -p1 < ../xine-lib/misc/libdvdcss-1.2.6-network.patch libdvdcss-1.2.6$ ./bootstrap libdvdcss-1.2.6$ make libdvdcss-1.2.6$ make install - start xine on the client machine with: $ xine dvd://server_address:3000/ (don't forget the trailing slash) protocol details ---------------- the network protocol is pretty simple. it consists of text-based commands and replies over a TCP stream. command format: ... \n reply format: ... \n followed by n bytes of binary data (like cd or dvd sectors) cdda commands: cdda_open 0 cdda_read cdda_tochdr 0 cdda_tocentry 0 dvd commands: dvd_open 0 dvd_error dvd_read dvd_seek 0 dvd_title 0 xine-lib-1.2/doc/hackersguide/0000755000175000017500000000000014647725152014067 5ustar memexine-lib-1.2/doc/hackersguide/overview.docbook0000644000175000017500000007327614647725152017316 0ustar meme xine code overview Walking the source tree The src/ directory in xine-lib contains several modules, this should give you a quick overview on where to find what sources. Directories marked with "(imported)" contain code that is copied from an external project into xine-lib. Everything below such a directory is up to this project. When modifying code there, be sure to send the patches on. If some xine specific adaptation of the code is absolutely necessary, a patch containing the changes should be stored in Mercurial to not lose the changes the next time we sync with the external project. audio_out Audio output plugins. These provide a thin abstraction layer around different types of audio output architectures or platforms. Basically an audio output plugin provides functions to query and setup the audio hardware and output audio data (e.g. PCM samples). demuxers Demuxer plugins that handle various system layer file formats like avi, asf or mpeg. The ideal demuxer know nothing about where the data comes from and who decodes it. It should basically just unpack it into chunks the rest of the engine can eat. dxr3 Code to support the DXR3 / hollywood+ hardware mpeg decoder. input Input plugins encapsulate the origin of the data. Data sources like ordinary files, DVDs, CDA or streaming media are handled here. dvb Some headers for Digital Video Broadcast. libdvdnav (imported) The libdvdnav library for DVD navigation is used by xine's DVD input plugin. libreal, librtsp Support for RealMedia streaming as used by the RTSP input plugin. vcd The enhanced VCD input plugin which also handles VCD navigation. libcdio, libvcd (imported) Libraries used by the enhanced VCD plugin. liba52 (imported) A52 (aka AC3, aka Dolby Digital) audio decoder library and xine plugin. We maintain some small integration improving differences between the original liba52 and our copy in the file diff_against_release.patch. libdts (imported) AC5 (aka DTS) audio decoder library and xine plugin, which is capable of software decoding as well as digital passthrough. libfaad (imported) The Free AAC Decoder library and xine plugin. libffmpeg A xine decoder plugin using various audio and video decoders from the ffmpeg decoder pack libavcodec. Their MPEG encoder is also for the DXR3. To optimize the integration of libavcodec and the xine engine, we maintain some differences between the original ffmpeg and our copy in the file diff_to_ffmpeg_cvs.txt. libavcodec (imported) The libavcodec decoder pack as used by xine's ffmpeg plugin. libflac A xine demuxer and decoder plugin for the Free Lossless Audio Codec library, which has to be installed separately. liblpcm Audio decoder plugin that "decodes" raw PCM data; most notably endianess-conversions are done here. libmad (imported) Mpeg audio decoder plugin (i.e. mp2 and mp3 decoding). ISO/IEC compliant decoder using fixed point math. libmpeg2 (imported) Most important MPEG video decoder plugin, provides fast and high-precision MPEG-1/2 video decoding. Although this is an imported library, we have heavily modified our internal copy to blend it as seamlessly as possible into the xine engine in order to get the maximum MPEG decoding performance. libmpeg2new James started an effort to bring a recent and unmodified version of libmpeg2 into xine to one day replace our current internal modified libmpeg2 with one closer to the original. But since the full feature catalog has not yet been achieved with the new one, it is still disabled. include, libmpeg2 (imported) The code of the imported new libmpeg2. libreal A thin wrapper around Real's binary codecs from the Linux RealPlayer to use them as a xine plugin. libspeex A xine decoder plugin for the speex library, which has to be installed separately. libspucc Closed caption subtitle decoder plugin. libspudec DVD SPU subtitle decoder plugin. libsputext Plain text subtitle decoder plugins. libtheora A xine decoder plugin for the theora library, which has to be installed separately. libvorbis A xine decoder plugin for the ogg/vorbis library, which has to be installed separately. libw32dll Video and audio decoder plugins that exploit some wine code to use win32 (media player and Quicktime) codecs in xine. Works on x86 platforms only. DirectShow, dmo, qtx, wine (imported) Stripped down version of wine to support Video for Windows DLLs and additional code to use DirectShow, DMO and QuickTime DLLs. libxineadec xine's decoder pack of additional audio decoders. gsm610 (imported) The gsm610 audio decoder library as used by the related xine plugin. nosefart (imported) The nosefart audio decoder library as used by the related xine plugin. libxinevdec xine's decoder pack of additional video decoders. post Video and audio post effect plugins live here. Post plugins modify streams of video frames or audio buffers as they leave the decoder to provide conversion or effects. audio Some audio effects as xine audio filter posts. deinterlace (imported) The tvtime deinterlacer as a xine video filter post. goom (imported) The goom audio visualizer as a xine visualizer post. mosaico Some post plugins merging multiple frames into one. For example picture in picture can be done with this. planar Some simple 2D video effects as xine video filter posts. visualizations Audio visualization post plugins. video_out Contains various video output driver plugins. Video output drivers are thin abstraction layers over various video output platforms (e.g. X11, directfb, directX, …). Video output driver plugins provide functions like frame allocation and drawing and handle stuff like hardware acceleration, scaling and colorspace conversion if necessary. They do not handle a/v sync since this is done in the xine-engine already. libdha (imported) A library for direct hardware access to the graphics card as used by the vidix video out plugin. vidix (imported) The vidix system for high performance video output as used by the vidix video out plugin. xine-engine The heart of xine – its engine. Contains code to load and handle all the plugins, the configuration repository as well as the generic decoding loops and code for synchronized output. A lot of helper functions for plugins to use live here as well. What's in the individual files should be guessable by the files' names. This document is not going to explain the source, because it simply changes too often. A look at the architectural drawing in the internals section should give you a pretty good idea, what to expect in this directory. Basically, everything in this picture that is not called "plugin" lives here. xine-utils Collection of utility functions and platform abstractions. Also contains a simple XML parser for frontend playlist handling. Object oriented programming in C xine uses a lot of design principles normally found in object oriented designs. As xine is written in C, a few basic principles shall be explained here on how xine is object oriented anyway. Classes are structs containing function pointers and public member data. Example:    typedef struct my_stack_s my_class_t;        struct my_stack_s {     /* method "push" with one parameter and no return value */     void (*push)(my_stack_t *this, int i);         /* method "add" with no parameters and no return value */     void (*add)(my_stack_t *this);         /* method "pop" with no parameters (except "this") and a return value */     int (*pop) (my_stack_t *this);    };        /* constructor */    my_class_t *new_my_stack(void); To derive from such a class, private member variables can be added:    typedef struct {     my_stack_t stack; /* public part */         /* private part follows here */     int values[MAX_STACK_SIZE];     int stack_size;    } intstack_t; Each method is implemented as a static method (static to prevent namespace pollution). The "this" pointer needs to be cast to the private pointer type to gain access to the private member variables. Implementation of the "push" method follows:    static void push (my_stack_t *this_gen, int i) {     intstack_t *this = (intstack_t *)this_gen;     this->values[MAX_STACK_SIZE - ++this->stack_size] = i;    } The part added to the derived class is private, because when defining the new structure directly in the .c file, where it will be used, outside modules have no way of seeing the definition of the derived class. A public derivation is possible by defining the above structure in a .h file for others to include. Something similar to a protected, package or friend visibility is also possible:    struct my_stack_s {     void (*push)(my_stack_t *this, int i);     void (*add)(my_stack_t *this);     int (*pop)(my_stack_t *this);        #ifdef STACK_INTERNAL     void (*flush)(my_stack_t *this);    #endif    }; All modules, who need to access the internal part have to add    #define STACK_INTERNAL before including the header with the definition. It is clear that only those friend modules can derive from this class. Finally the contructor malloc()s the data struct (private variant) and fills in function pointers and default values. Usually the constructor is the only public (i.e. non-static) function in the module:    my_stack_t *new_my_stack(void) {     intstack_t *this;         /* alloc memory */     this = malloc(sizeof(intstack_t));         /* fill in methods */     this->push = push;     this->add = add;     this->pop = pop;         /* init data fields */     this->stack_size = 0;         /* return public part */     return &this->stack;    } Why not using C++? After all these considerations about object oriented C, you might ask, why we do not use C++ after all? The easy answer would be: xine wants to be as fast as possible and C++ is simply too slow. But this is only the easy answer and it is not entirely true any more. Thoughtfully applied, you can write very fast C++ code with today's compilers, but these compilers might not be available on all platforms in the necessary quality. Even with a sophisticated compiler, C++ is much harder to optimize than plain C and thus C compiles much faster. Another big problem is that the C++ ABI is not as well-defined as the C ABI. With C, you can easily mix libraries and applications built by different compilers. With C++, this is unlikely to work. But the final argument is that xine does not really need C++. xine's inheritance hierarchy is very flat, mostly one level only and does not need things like multiple or virtual inheritance. Most of the external projects that are used by xine are plain C as well and using more than one language complicates the build system. As we saw above, we can emulate object orientation reduced to our real needs in plain C. Coding style and guidelines This section contains some guidelines for writing xine-code. These are really just guidelines, no strict rules. Contributions will not be rejected if they do not meet these rules but they will be even more appreciated if they do. Comment your interfaces directly in the header files. No doxygen comments, ordinary C comments will do. Use C-style comments (/* */), not C++-style (//). When in doubt, use lower case. BTW: This thing is called xine, never Xine. Use expressive variable and function identifiers on all public interfaces. Use underscores to seperate words in identifiers, not uppercase letters (my_function_name is ok, myFunctionName is not ok). Avoid macros unless they are really useful. Avoid gotos. use something like    printf("module: ..."[,…]); for console output. All console output goes to stdout and must be prefixed by the module name which generates the output (see example above). Refer to emac's C-mode for all questions of proper indentiation. That first of all means: indent with two spaces. The xine logging system xine offers a wide range of possibilities to display strings. This section should describe when to use which way and how to do it right. xine_log Output which is done thru this function will be displayed for the end user by the frontend. If xine->verbosity is not 0 the messages will also be displayed on the console. Ideally these strings are translated. This function is for information which the user should read always.    xine_log(xine_t *xine, int buf, const char *format, ...); buf is either XINE_LOG_MSG for general messages or XINE_LOG_PLUGIN for messages about plugins. xprintf This macro uses the xine->verbosity value to decide if the string should be printed to the console. Possible values are XINE_VERBOSITY_NONE, XINE_VERBOSITY_LOG or XINE_VERBOSITY_DEBUG. By default nothing is printed. When you use xine-ui you can enable this output with the --verbose=[1,2] options. This function should be used for information which the user should only read up on request.    xprintf(xine_t *xine, int verbosity, const char *format, ...); lprintf/llprintf These macros are for debugging purpose only. Under normal circumstances it is disabled. And can only be enabled by changing a define statement and a recompilation. It has to be enabled for these files that are of interest. It should only be used for information which is intended for developers.    lprintf(const char *format, ...);    llprintf(bool, const char *format, ...); bool is a flag which enables or disables this logging. lprintf can be enabled by defining LOG at the top of the source file. llprintf can be used for more than one categorie per file by using diffent lables:    #define LOG_LOAD 1    #define LOG_SAVE 0        llprintf(LOG_LOAD, "loading was successful\n");    llprintf(LOG_SAVE, "could not save to file %s\n", filename); In this case only the first messages is printed. To enable/disable change the defines. LOG_MODULE should be used to set the modulename for xprintf/lprintf/llprintf. Each output line will start with "modulename: ".    #define LOG_MODULE "modulename" LOG_VERBOSE can be defined to enable the logging of functionname and linenumbers. Then the output will be: "modulename: (function_name:42) message". _x_assert/_x_abort These are not purely logging functions, but despite their original C library versions, they always output debugging text, which is why usage of these functions is preferred. _x_assert() checks a condition and prints a note, when the condition is false. In addition, a debug build and only a debug build will terminate the application, when the condition is false. Release versions will only print the note, but try to continue. _x_abort() always terminates the application after printing a note. How to contribute Make sure you send your patches in unified diff format to the xine-devel mailing list. You'll have to subscribe first, otherwise you're not allowed to post. Please do not send patches to individual developers unless instructed otherwise because your patch is more likely to get lost in an overfull INBOX in that case. Please be patient, it may take 1-2 weeks before you hear any comments on your work (developers may be working on other parts of the code or are simply busy at the moment). We prefer to receive patches in a format which is immediately committable. This normally means that we want your name and email address (we're not keen on pseudonyms), a subject line which provides a convenient summary of your changes, and body text which provides a longer description (if needed). There are a few ways to submit your patches: hg diff is probably the easiest. You'll need a subject line and body text as described above. If you're copying or renaming files, or a file should be marked as executable, then use hg diff --git; this will include the necessary information (if copying or renaming, you need to have used hg copy or hg rename for this to work). If you're attaching the patch (recommended), then including the metadata in the patch file is recommended, e.g. From: Fred Patcher <patcher@example.com> Subject: Properly toggle the randomiser switch The randomiser switch was sometimes not being toggled, leading to random behaviour. diff --git a/foo/control.c b/foo/control.c ... diff -u is also acceptable, but we prefer that you do so from the top-level directory within the source code (prefix the files' path names with ./) or from the directory containing the source code directory. Basically, use hg diff if you can. hg email is preferred. You'll need to commit your changes locally for this to work, but this is the easiest way of sending a set of patches for inclusion and review; it'll send the mail directly. hg export can also be used with specific changeset identifiers. Again, you'll need to commit your changes locally for this to work. Patches should normally be included as attachments. Some mail clients and webmail services are known to mangle whitespace or wrap lines, either of which is enough to render a patch potentially useless. xine-lib-1.2/doc/hackersguide/library.svg0000644000175000017500000014571714647725152016273 0ustar meme image/svg+xml xine_stream_t xine_post_wire xine_list_post_plugins_typed xine_list_post_plugins xine_post_dispose xine_post_t xine_post_init xine_post_in_t xine_post_out_t xine_post_output xine_post_list_outputs xine_post_list_inputs xine_post_input xine_post_wire xine_post_t xine_post_wire_video_port xine_video_port_t xine_stream_master_slave xine_list_video_output_plugins xine_close_video_driver xine_open_video_driver xine_video_port_t xine_port_send_gui_data xine_post_wire_audio_port xine_post_t xine_list_audio_output_plugins xine_close_audio_driver xine_open_audio_driver xine_audio_port_t xine_post_out_t xine_post_out_t xine_get_error xine_get_status xine_get_pos_length xine_get_audio_lang xine_get_spu_lang xine_open xine_play xine_stop xine_close xine_eject xine_set_param xine_get_param xine_stream_dispose xine_stream_t xine_stream_new xine_get_current_frame xine_get_current_vpts xine_trick_mode xine_get_audio_source xine_get_video_source xine_get_stream_info xine_get_meta_info xine_init xine_engine_set_param xine_engine_get_param xine_get_browse_mrls xine_get_autoplay_input_plugin_ids xine_get_autoplay_mrls xine_get_file_extensions xine_get_mime_types xine_get_demux_for_mime_type xine_get_input_plugin_description xine_config_register_* xine_config_get_first_entry xine_config_get_next_entry xine_config_lookup_entry xine_config_update_entry xine_config_load xine_config_save xine_config_reset xine_event_t xine_event_free xine_event_get xine_event_wait xine_event_new_queue xine_event_dispose_queue xine_event_queue_t xine_event_create_listener_thread xine_event_send xine_list_input_plugins xine_list_demuxer_plugins xine_list_video_decoder_plugins xine_list_audio_decoder_plugins xine_list_spu_plugins xine_get_log_section_count xine_get_log_names xine_log xine_get_log xine_register_log_cb xine_osd_draw_* xine_osd_set_encoding xine_osd_set_font xine_osd_get_text_size xine_osd_set_position xine_osd_get_capabilities xine_osd_show xine_osd_get_palette xine_osd_set_text_palette xine_osd_clear xine_osd_hide xine_osd_show_unscaled xine_osd_set_palette xine_osd_free xine_osd_t xine_osd_new xine_t xine_exit xine_new xine_health_check xine_stream_t xine-lib-1.2/doc/hackersguide/Makefile.am0000644000175000017500000000353314647725152016127 0ustar memeinclude $(top_srcdir)/misc/Makefile.common hackersguide_docbook = hackersguide.docbook \ intro.docbook \ library.docbook \ overview.docbook \ internals.docbook \ stream.docbook \ output.docbook hackersguide_svg = architecture.svg \ library.svg \ overlays.svg \ post_frame.svg hackersguidedir = $(htmldir)/hackersguide hackersguide_DATA = hackersguide.html \ architecture.png library.png overlays.png post_frame.png EXTRA_DIST = README $(hackersguide_docbook) $(hackersguide_svg) \ $(hackersguide_DATA) DISTCLEANFILES = $(hackersguide_DATA) SUFFIXES = .png .fig docs: $(hackersguide_DATA) clean-docs: rm -f $(hackersguide_DATA) dist-hook: @if test x"$(distcheck_lax)" = x ; then \ $(MAKE) fail_if_missing=yes docs ; \ else \ $(MAKE) docs ; \ fi distclean-local: clean-docs AM_V_FAKE = $(am__v_FAKE_@AM_V@) am__v_FAKE_ = $(am__v_FAKE_@AM_DEFAULT_V@) am__v_FAKE_0 = @echo " FAKE " $@; if HAVE_XMLTO hackersguide.html: $(hackersguide_docbook) $(AM_V_GEN)xmlto xhtml-nochunks "$(srcdir)/hackersguide.docbook" else hackersguide.html: $(hackersguide_docbook) $(AM_V_FAKE)if test x"$(fail_if_missing)" = x"yes"; then \ echo "Please install xmlto."; \ exit 1; \ fi; \ if test x"$(fail_if_missing)" != x"yes"; then \ touch $@; \ sleep 1; \ touch $^; \ fi endif $(AM_V_at)$(SED) -i -e '/]*alt=/! s/ image/svg+xml demuxer plugin demuxer loop buf buf buf buf buf buf buf buffer pool input plugin metronom xine stream stream layer decoder layer stream fifos demuxer layer input layer metronom clock clock sync loop scr plugin output layer overlay manager OSD extra info datapath detailed datapath datapath xine buffer discontinuity presentation timestamp virtual presentation timestamp subpicture unit buf buf buf buf video fifo ... buf buf buf buf audio fifo ... audio decoder loop audio decoder plugin video decoder loop spu decoder plugin video decoder plugin audio out loop audio out plugin out fifo video out loop video out plugin out fifo extra info post plugins buf buf buf buf disc disc pts vpts pts pts vpts time time spu pts vpts vpts vpts pts buf disc pts vpts spu buf buf buf buf frames samples frames xine-lib-1.2/doc/hackersguide/intro.docbook0000644000175000017500000000400214647725152016560 0ustar meme Introduction Where am I? You are currently looking at a piece of documentation for xine. xine is a free video player. It lives on http://www.xine-project.org/. Specifically this document goes under the moniker of the "xine Hackers' Guide". What does this text do? This document should help xine hackers to find their way through xine's architecture and source code. It's a pretty free-form document containing a loose collection of articles describing various aspects of xine's internals. It has been written by a number of people who work on xine themselves and is intended to provide the important concepts and methods used within xine. Readers should not consider this document to be an exhausative description of the internals of xine. As with all projects which provide access, the source-code should be considered the definitive source of information. New versions of this document This document is being developed in the xine-lib cvs repository within the directory doc/hackersguide/. If you are unsure what to do with the stuff in that directory, please read the README file located there. New versions of this document can also be obtained from the xine web site: http://www.xine-project.org/. Feedback All comments, error reports, additional information and criticism concerning this document should be directed to the xine documentations mailing list xine-docs@lists.sourceforge.net. Questions about xine hacking in general should be sent to the developer mailing list xine-devel@lists.sourceforge.net. xine-lib-1.2/doc/hackersguide/overlays.svg0000644000175000017500000002004514647725152016455 0ustar meme image/svg+xml OSD renderer public libxine API libsputext (text subtitles) libspucc (closed captions) overlay manager video out libspudec (DVD subtitles) xine-lib-1.2/doc/hackersguide/output.docbook0000644000175000017500000010245014647725152016773 0ustar meme xine's output layer Post plugin layer In this section you will learn, how the powerful post plugin architecture works and how to write post plugins. General principle of post plugins The name "post plugin" comes from "postprocessing" which already describes what these plugins are supposed to do: they take video frames, audio buffers or subpicture planes as they leave the decoders and apply arbitrary processing to them. Then they pass processed elements on to the output loops. Post plugins can not only be chained to process the predecessor's output and advance the data to their successor, they can form arbitrary trees, since post plugins can have any number of inputs and outputs. Additionally, the interconnection of the plugins currently inserted in such a tree can be changed on the fly during playback. The public function xine_post_wire() is used by frontends to form such connections. Due to the variety of possible applications, the interface post plugins have to implement is just the basic foundation. The complexity comes from hooking your post plugin into the engine data paths for video frames and audio buffers, intercepting the data and performing your operation on them. This is done by taking the interface of a video or audio port, replacing some of the functions with your own ones and passing the interface to the decoder or predecessor post plugin that is going to feed you with data by accessing this interface and by doing that, calling the functions you provide. From there you can do almost anything you want. Constructing video frames from audio buffers to visualize sound is possible as well as just outputting an integer giving the average brightness of an image. It is also possible to invent post plugins with no output (not very useful, unless the plugin has some side-effect) or no input at all; for the latter you have to create your own pthread, otherwise your plugin will not do anything. An audio signal generator could be implemented like this. The various data types, post plugins can accept as input or offer as output are defined in xine.h as XINE_POST_DATA_* defines. Some terminology used in the following explanations: down direction: The direction from the decoders to the output. This is the way video or audio data (actual content and meta information) usually travels through the engine. up direction: The direction from the output to the decoders. This is the way some video or audio metadata like metronom timestamps travel through the engine. interception: Post plugins are inserted into the engine data paths by the means of the decorator design pattern. This works by taking engine structures with member funtions like video or audio ports, video frames or overlay managers and inserting your own functions into a copy of this structure. This is called interception. This modified structure is then passed up to the plugin that uses it and thus calls your replaced functions. Writing a xine post plugin The post plugin API is declared in src/xine-engine/post.h The plugin info of post plugins contains the post plugin type, which is one of the XINE_POST_TYPE_* defines and the init_class function of the plugin.    post_plugin_t *open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target); Returns an instance of the plugin. Some post plugins evaluate inputs to open a variable number of inputs. Since almost all post plugins have audio or video outputs, you can hand in a NULL-terminated array of ports to connect to these outputs. In this function you can also intercept these ports so that your plugin is actually used. There is a helper function to initialize a post_plugin_t, which you are encouraged to use: _x_post_init().    char *get_identifier(post_class_t *class_gen); This function returns a short identifier describing the plugin.    char *get_description(post_class_t *class_gen); This function returns a plaintext, one-line string describing the plugin.    void dispose(post_class_t *class_gen); This function frees the memory used by the video out plugin class object. The post_plugin_t structure contains the publicly visible part of the post plugin with the audio and video inputs and the type of the post plugin. Not publicly visible are the lists of all inputs and outputs, the dispose() function and some internal stuff which plugins do not have to worry about.    void dispose(post_plugin_t *this_gen); This function frees the memory used by the plugin instance, but not necessarily immediately. Since post plugins enter their own functions into engine structures, they might still be needed when dispose() is being called. They maintain a usage counter to detect that. To check for such a condition, you should use the _x_post_dispose() helper function like that:    if (_x_post_dispose(this))      really_free(this); _x_post_dispose() frees any ressources allocated by any of the post plugin helper functions and returns boolean true, if the plugin is not needed any more. Interception Currently, we have four engine structures which can be intercepted by post plugins: video ports, video frames, overlay managers and audio ports. You could do this interception manually, but since this is quite a complex process, there are helper functions to assist you and their usage is encouraged. Intercepting a video port    post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post,      xine_video_port_t *port, post_in_t **input, post_out_t **output); This function will intercept port and returns a structure for you to pass up. All functions in the port will be replaced with dummy pass through functions that do nothing but relaying the call down to the original port. If you want (that is, input or output are not NULL), this function will also create the input and output descriptors complete with rewiring functions and add them to the relevant lists. This is required, if you want this port to be advertised by the plugin to the outside world. post_video_port_t makes a variety of interception schemes very easy. If you want to replace any of the default functions with your own, just enter it into new_port. You can use original_port from within your function to propagate calls down to the original port. The constraint is that your functions have to ensure that every original port held open scores one usage counter point, so that opened ports are always closed before the plugin is disposed. Therefore, you should use the macro _x_post_inc_usage() before calling original_port->open() and use the macro _x_post_dec_usage() after calling original_port->close(). Note that _x_post_dec_usage() might dispose the plugin, when dispose() has been called earlier and usage count drops to zero, so do never touch plugin structures after _x_post_dec_usage(). In addition, you must never call a port function of the original port when the port is not open. Intercepting video frames or the overlay manager of the port is even easier. You do not have to reimplement get_frame() or get_overlay_manager(). Just enter a intercept_frame or intercept_ovl function which returns boolean true, if you want to intercept. The functions to insert in the intercepted frame or overlay manager are taken from new_frame and new_manager respectively. Note that the defaults are reversed: If you do not enter such a decision function for either one, all frames and no overlay manager will be intercepted. For convenience post_video_port_t also contains pointers to the current stream and to the current post plugin and a user_data pointer, where you can put in anything you need in addition. If your port is used by more than one thread, you can also enforce locking on the port, frame or overlay manager level by entering a lock into port_lock, frame_lock or manager_lock respectively. Intercepting an audio port Audio port interception is just a stripped down version of video port interception. Everything related to frames and overlay manager is not needed and audio buffers do not need to be intercepted, since they have no member functions. Everything else of the above still applies. Intercepting overlay manager    void _x_post_intercept_overlay_manager(video_overlay_manager_t *original, post_video_port_t *port); Interception of the overlay manager is done automatically when your intercept_ovl() decision function returns boolean true. Should you ever decide not to use that, interception can be done with this helper function, which simply creates an intercepted overlay manager with dummy pass through functions in port->new_manager and stores the original manager in port->original_manager. No matter how you intercepted the overlay manager, your own replacement functions will receive port->new_manager as the overlay manager argument. But you most likely want to have access to the post_video_port_t from within your functions. For that, there exists a pointer retrieval function:    post_video_port_t *_x_post_ovl_manager_to_port(video_overlay_manager_t *manager); Intercepting a video frame    vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port);    vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port); Interception of video frames is done automatically when your intercept_frame() decision function returns boolean true or when there is no such function in post_video_port_t. Should you ever decide not to use that, interception can be done with the helper function _x_post_intercept_video_frame(). Since the same video frame can be in use in the decoder and in the output and in any post plugin in between at the same time, simply modifying the frame structure does not work, because every user of the frame needs to see his version and the frame must always travel along the same path through the plugins for its entire lifetime. To ensure that, _x_post_intercept_video_frame() provides a shallow copy of the frame structure with the original frame attached to copy->next. This copy will be filled with your own frame functions from port->new_frame and with dummy pass through functions for those you did not provide. This way, every part of xine using this frame will see its own frame structure with a list of frame contexts from down the data path attached to frame->next. _x_post_restore_video_frame() reverses this and should be used when the frame is freed or disposed. Your own replacement functions will receive the copied frame as as argument. But you most likely want to have access to the post_video_port_t from within your functions. For that, there exists a pointer retrieval function:    post_video_port_t *_x_post_video_frame_to_port(vo_frame_t *frame); The constraint is that your functions have to ensure that every intercepted frame scores one usage counter point, so that these frames are always freed or disposed before the plugin is disposed. Therefore, you should use the macro _x_post_inc_usage() before calling _x_post_intercept_video_frame() and use the macro _x_post_dec_usage() after calling _x_post_restore_video_frame(). Note that _x_post_dec_usage() might dispose the plugin, when dispose() has been called earlier and usage count drops to zero, so do never touch plugin structures after _x_post_dec_usage(). From within your own frame functions, you can propagate calls to the original frame by calling a function on frame->next. Since modifications to the frame can travel both upwards and downwards (decoders and output can modify the frame), changes need to be copied between the frame structure contexts. You should use the _x_post_frame_copy_down() and _x_post_frame_copy_up() helper functions like that:    _x_post_frame_copy_down(frame, frame->next);    frame->next->draw(frame->next, stream);    _x_post_frame_copy_up(frame, frame->next); If your post plugin modifies the content of the frame, you have to modify a deep copy of the frame, because the decoder might still use the frame as a reference frame for future decoding. The usual procedure is:    modified_frame = port->original_port->get_frame(port->original_port, …);    _x_post_frame_copy_down(frame, modified_frame);    copy_and_modify(frame, modified_frame);    skip = modified_frame->draw(modified_frame, stream);    _x_post_frame_copy_up(frame, modified_frame);    modified_frame->free(modified_frame); When the output receives a frame via draw(), it usually receives the stream where the frame originates as well and modifies the state of this stream by passing the frame through the stream's metronom. Sometimes this is unwanted. For example, when you pass the same frame to the output more than once, it will confuse metronom. To solve this, you can call frame->next->draw() with NULL as the stream. You might also want to prevent frames from being passed down to the output completely, because your post plugin creates something else from these frames, but does not need them to be drawn. In both these situations, you have to call the helper function _x_post_frame_u_turn() when the frame is drawn, because this does some housekeeping which the decoder might expect to take place. The following diagram summarizes the situations of a video frame passing through a post plugin: video frame passing through a post plugin Summary of constraints Call _x_post_inc_usage() before port open() before any other port function. Call _x_post_inc_usage() before issueing an intercepted frame. Call _x_post_dec_usage() after port close() and do not call any port functions after that. Call _x_post_dec_usage() after restoring a frame. When a frame is drawn by your plugin, it must either be drawn on the original port with the correct stream as argument or U-turned (or passed through a private metronom manually). If your post plugin keeps locked frames, release them when your input port is being closed. Do not assume your plugin is alive after _x_post_dec_usage(). Rewiring and the ticket system Rewiring is the reconnection of one post plugin's outputs and another post plugin's inputs. This can happen on the fly during playback, which makes this a very delicate process. In one such input to output connection, only the output is active by either writing data directly to the connected input or by calling functions there. Therefore we have to notify only the output, when it is rewired. This is done by calling the rewire() member function of the corresponding xine_post_out_t when the frontend issues a rewiring on this output. This is done from the frontend thread for the rewire operation to return synchroneously. But since this can happen on the fly, we have to assure that no other thread is relying on the connection while we modify it. For this, threads working within post plugins have to be accounted and on demand suspended in safe positions. For this, xine offers a synchronization facility called "tickets". Ticket system principles and operations The idea of the ticket system is based on an extended read-write lock, where there can be many readers in parallel, but only one exclusive writer. A certain interface might require you to have a ticket before calling its functions. The ticket system now allows multiple threads to operate within the component behind the interface by granting as many tickets as needed. But should an outside operation require exclusive access to the component, all granted tickets can be revoked and have to be given back by the threads who hold them, which suspends the threads. After the exclusive operation, tickets will be reissued so all suspended threads can continue where they stopped. We will now look at the ticket primitives in detail: acquire() You receive a new ticket. If the ticket is currently revoked, you can be blocked until it is reissued. There is one exception to this: You can acquire a revoked ticket, if you revoked it atomic yourself. You can also acquire a ticket irrevocably. Between acquire and release of an irrevocable ticket, it is guaranteed that you will not be blocked by ticket revocation. release() You give a ticket back when you do not need it any longer. If the ticket is currently revoked, you can be blocked until it is reissued. If you acquired the ticket irrevocably, you have to release it irrevocably as well. renew() You must only call this function, when the ticket has been revoked, so be sure to check ticket_revoked before. You give the ticket back and receive a new one. In between, you can be blocked until the ticket is reissued. You have to renew irrevocably, if you cannot assure that the thread holds no irrevocable tickets. If you can assure this, renew revocably. revoke() This function can only be called by the xine engine, plugins do not have access to it. It revokes all tickets and after finite time, all threads will run into a acquire(), release() or renew() and will be suspended there. Then the revocation returns and you can modify structures or call functions with the knowledge that all ticket holders will remain in safe positions. When you additionally need exclusive access where no other revoker can interfere, you have to revoke atomic. issue() This function can only be called by the xine engine, plugins do not have access to it. It ends ticket revocation and hands out new tickets to all threads that applied with a acquire() or renew(). If you revoked the tickets atomic, you have to issue them atomic. When you use the ticket system in any way, you have to obey to the following rules: Assure to release irrevocable tickets ater a finite time. Assure to release or renew revocable tickets ater a finite time. Assure to reissue tickets you revoked atomic after a finite time. Pair calls properly. Never revoke a ticket you hold. Never acquire a ticket you revoked atomic before. Never acquire a ticket revocable more than once. Ticket handling in decoder and post plugins The contract of the video and audio port interfaces is that you need to have the port ticket, when you want to call functions of these interfaces. The decoder plugins do not have to worry about this at all, since the decoder loops inside the engine handle the ticketing. Post plugins get the ticket assigned by the engine, but usually, a post plugin does not create a new thread, it is called by the decoder thread and therefore already owns the necessary ticket. All port functions are also ticket-safe as they follow all the rules given above. You only have to remember that tickets need to be renewed as soon as possible, when the are revoked. For this, the helper function _x_post_rewire() should be used in prominent locations where it is safe to be suspended. Candidates for such locations are at the beginning of the port's open() and get_frame()/get_buffer() functions. The default pass through implementations for intercepted ports already do this. The port tickets are revoked, whenever a rewiring takes place or the engine switches into pause mode. The tickets are reissued, when the rewiring is finished or the engine switches from pause mode into playback. Some post plugins might contain critical parts, where they must not be interrupted by a rewire or pause. These sections can be enclosed in _x_post_lock() and _x_post_unlock(), which will simply acquire and release an irrevocable ticket for you. As long as you hold such a ticket, it is guaranteed that you will never be interrupted by a pause or rewire. Video output In order to allow for device-dependant acceleration features, xine calls upon the video output plugin for more than just displaying images. The tasks performed by the video plugins are: Allocation of vo_frame_t structures and their subsequent destruction. Allocation of memory for use by one frame (this is to allow for the ability of some video output plugins to map frames directly into video-card memory hence removing the need for the frame to be copied across the PCI/AGP bus at display time). Most important, the ability to render/copy a given frame to the output device. Optionally the copying of the frame from a file dependant colour-space and depth into the frame structure. This is to allow for on-the fly colour-space conversion and scaling if required (e.g. the XShm ouput plugin uses this mechanism). Although these extra responsibilities add great complexity to your plugin it should be noted that they allow plugins to take full advantage of any special hardware-acceleration without sacrificing flexibility. Writing a xine video out plugin The video out plugin API is declared in src/xine-engine/video_out.h The plugin info of video out plugins contains the visual type, priority, and the init_class function of the plugin. The visual_type field is used by xine to determine if the GUI used by the client is supported by the plugin (e.g. X11 output plugins require the GUI to be running under the X Windowing system) and also to determine the type of information passed to the open_plugin() function as its visual parameter.    char *get_description(video_driver_class_t *this_gen); This function returns a plaintext, one-line string describing the plugin.    char *get_identifier(video_driver_class_t *this_gen); This function returns a shorter identifier describing the plugin.    void dispose(video_driver_class_t *this_gen); This function frees the memory used by the video out plugin class object.    vo_driver_t *get_instance(video_driver_class_t *class_gen, const void *visual); Returns an instance of the plugin. The visual is a pointer to a visual-dependant structure/variable. For example, if you had previously claimed your plugin was of the VISUAL_TYPE_X11 type, this would be a pointer to a x11_visual_t, which amongst other things hold the Display variable associated with the X-server xine should display to. See plugin source-code for other VISUAL_TYPE_* constants and associated structures. Note that this field is provided by the client application and so if you wish to add another visual type you will either need to extend an existing client or write a new one.    uint32_t get_capabilities(vo_driver_t *this_gen); Returns a bit mask describing the output plugin's capabilities. You may logically OR the VO_CAP_* constants together to get a suitable bit-mask (via the '|' operator).    int get_property(vo_driver_t *self, int property);    int set_property(vo_driver_t *self, int property, int value);    void get_property_min_max(vo_driver_t *self, int property, int *min, int *max); Handle the getting, setting of properties and define their bounds. Valid property IDs can be found in the video_out.h header file.    int gui_data_exchange(vo_driver_t *self, int data_type, void *data); Accepts various forms of data from the UI (e.g. the mouse has moved or the window has been hidden). Look at existing plugins for examples of data exchanges from various UIs.    vo_frame_t *alloc_frame(vo_driver_t *self); Returns a pointer to a xine video frame. Typically the video plugin will add private fields to the end of the vo_frame_t structure which are used for internal purposes by the plugin. The function pointers within the frame structure provide a mechanism for the driver to retain full control of how the frames are managed and rendered to. If the VO_CAP_COPIES_IMAGE flag was set in the plugins capabilities then the copy field is required and will be called sequentially for each 16-pixel high strip in the image. The plugin may then decide, based on the frame's format, how this is copied into the frame.    void update_frame_format(vo_driver_t *self, vo_frame_t *img, uint32_t width, uint32_t height, double ratio, int format, int flags); This function will be called each time the colour-depth/space or size of a frame changes. Typically this function would allocate sufficient memory for the frame, assign the pointers to the individual planes of the frame to the base field of the frame and perform any driver-specific changes.    void display_frame(vo_driver_t *self, vo_frame_t *vo_img); Renders a given frame to the output device.    void overlay_begin(vo_driver_t *self, vo_frame_t *vo_img, int changed);    void overlay_blend(vo_driver_t *self, vo_frame_t *vo_img, vo_overlay_t *overlay);    void overlay_end(vo_driver_t *self, vo_frame_t *vo_img); These are used to blend overlays on frames. overlay_begin() is called, when the overlay appears for the first time, overlay_blend() is then called for every subsequent frame and overlay_end() is called, when the overlay should disappear again.    int redraw_needed(vo_driver_t *self); Queries the driver, if the current frame needs to be drawn again.    void dispose(vo_driver_t *self); Releases all resources and frees the plugin. xine-lib-1.2/doc/hackersguide/internals.docbook0000644000175000017500000010726514647725152017443 0ustar meme xine internals Engine architecture and data flow xine engine architecture Media streams usually consist of audio and video data multiplexed into one bitstream in the so-called system-layer (e.g. AVI, Quicktime or MPEG). A demuxer plugin is used to parse the system layer and extract audio and video packages. The demuxer uses an input plugin to read the data and stores it in pre-allocated buffers from the global buffer pool. The buffers are then added to the audio or video stream fifo. From the other end of these fifos the audio and video decoder threads consume the buffers and hand them over to the current audio or video decoder plugin for decompression. These plugins then send the decoded data to the output layer. The buffer holding the encoded data is no longer needed and thus released to the global buffer pool. In the output layer, the video frames and audio samples pass through a post plugin tree, which can apply effects or other operations to the data. When reaching the output loops, frames and samples are enqueued to be displayed, when the presentation time has arrived. A set of extra information travels with the data. Starting at the input and demuxer level, where this information is generated, the data is attached to the buffers as they wait in the fifo. The decoder loops copy the data to a storage of their own. From there, every frame and audio buffer leaving the stream layer is tagged with the data the decoder loop storage currently holds. Plugin system The plugin system enables some of xine's most valuable features: drop-in extensiability support parallel installation of multiple (incompatible) libxine versions support for multiple plugin directories ($prefix/lib/xine/plugins, $HOME/.xine/plugins, …) support for recursive plugin directories (plugins are found even in subdirectories of the plugin directories) version management (On start, xine finds all plugins in its plugin (sub)directories and chooses an appropriate version (usually the newest) for each plugin.) simplification (Plugins don't have to follow any special naming convention, and any plugin may contain an arbitrary subset of input, demuxer, decoder or output plugins.) Essentally, plugins are just shared objects, ie dynamic libraries. In contrast to normal dynamic libraries, they are stored outside of the system's library PATHs and libxine does its own bookkeeping, which enables most advanced features mentioned above. Plugin location and filesystem layout The primary goal for this new plugin mechanism was the need to support simultaneous installation of several (most likely incompatible) libxine versions without them overwriting each other's plugins. Therefore, we have this simple layout: Plugins are installed below XINE_PLUGINDIR (/usr/local/lib/xine/plugins by default). Note that plugins are never directly installed into XINE_PLUGINDIR. Instead, a separate subdirectory is created for each "plugin provider". A plugin provider is equivalent with the exact version of one source package. Typical examples include "xine-lib-0.9.11" or "xine-vcdnav-1.0". Every source package is free to install an arbitrary number of plugins in its own, private directory. If a package installs several plugins, they may optionally be organized further into subdirectories. So you will finally end up with something like this:    /usr/local/lib/xine/plugins     xine-lib-0.9.11     demux_mpeg_block.so     decode_mpeg.so     video_out_xv.so     …     xine-vcdnav-0.9.11     input_vcdnav.so     xine-lib-1.2     input     file.so     stdin_fifo.so     vcd.so     demuxers     fli.so     avi.so     …     decoders     ffmpeg.so     mpeg.so (may contain mpeg 1/2 audio and video decoders)     pcm.so     …     output     video_xv.so     audio_oss.so     …     xine-lib-3.0     avi.so (avi demuxer)     mpeg.so (contains mpeg demuxers and audio/video decoders)     video_out_xv.so (Xv video out)     … As you can see, every package is free to organize plugins at will below its own plugin provider directory. Additionally, administrators may choose to put plugins directly into XINE_PLUGINDIR, or in a "local" subdirectory. Users may wish to put additional plugins in ~/.xine/plugins/. Again, there may be subdirectories to help organize the plugins. The default value for XINE_PLUGINDIR can be obtained using the pkg-config --variable=plugindir libxine command. Plugin Content: What's inside the .so? Each plugin library (.so file) contains an arbitrary number of (virtual) plugins. Typically, it will contain exactly one plugin. However, it may be useful to put a set of related plugins in one library, so they can share common code. First of all, what is a virtual plugin? A virtual plugin is essentially a structure that is defined by the xine engine. This structure typically contains lots of function pointers to the actual API functions. For each plugin API, there are several API versions, and each API version may specify a new, incompatible structure. Therefore, it is essential that only those plugins are loaded that support current libxine's API, so the .so file needs a plugin list that provides libxine with the version information, even before it tries to load any of the plugins. This plugin list is held in an array named xine_plugin_info":    plugin_info_t xine_plugin_info[] = {     /* type, API, "name", version, special_info, init_function */     { PLUGIN_DEMUX, 20, "flac", XINE_VERSION_CODE, NULL, demux_flac_init_class },     { PLUGIN_AUDIO_DECODER, 13, "flacdec", XINE_VERSION_CODE, &dec_info_audio, init_plugin },     { PLUGIN_NONE, 0, "", 0, NULL, NULL }    }; The structure of xine_plugin_info may never be changed. If it ever needs to be changed, it must be renamed to avoid erraneous loading of incompatible plugins. xine_plugin_info can contain any number of plugins and must be terminated with a PLUGIN_NONE entry. Available plugin types are:    #define PLUGIN_NONE 0    #define PLUGIN_INPUT 1    #define PLUGIN_DEMUX 2    #define PLUGIN_AUDIO_DECODER 3    #define PLUGIN_VIDEO_DECODER 4    #define PLUGIN_SPU_DECODER 5    #define PLUGIN_AUDIO_OUT 6    #define PLUGIN_VIDEO_OUT 7    #define PLUGIN_POST 8 The plugin version number is generated from xine-lib's version number like this: MAJOR * 10000 + MINOR * 100 + SUBMINOR. This is not required, but it's an easy way to ensure that the version increases for every release. Every entry in xine_plugin_info has an initialization function for the plugin class context. This function returns a pointer to freshly allocated (typically via malloc()) structure containing mainly function pointers; these are the "methods" of the plugin class. The "plugin class" is not what we call to do the job yet (like decoding a video or something), it must be instantiated. One reason for having the class is to hold any global settings that must be accessed by every instance. Remember that xine library is multistream capable: multible videos can be decoded at the same time, thus several instances of the same plugin are possible. If you think this is pretty much an object-oriented aproach, then you're right. A fictitious file input plugin that supports input plugin API 12 and 13, found in xine-lib 2.13.7 would then define this plugin list:    #include <xine/plugin.h>    …    plugin_t *init_api12(void) {     input_plugin_t *this;         this = malloc(sizeof(input_plugin_t));     …     return (plugin_t *)this;    }    /* same thing, with different initialization for API 13 */        const plugin_info_t xine_plugin_info[] = {     { PLUGIN_INPUT, 12, "file", 21307, init_api12 },     { PLUGIN_INPUT, 13, "file", 21307, init_api13 },     { PLUGIN_NONE, 0, "", 0, NULL }    } This input plugin supports two APIs, other plugins might provide a mixture of demuxer and decoder plugins that belong together somehow (ie. share common code). You'll find exact definitions of public functions and plugin structs in the appropriate header files for each plugin type: input/input_plugin.h for input plugins, demuxers/demux.h for demuxer plugins, xine-engine/video_decoder.h for video decoder plugins, xine-engine/audio_decoder.h for audio decoder plugins, xine-engine/post.h for post plugins, xine-engine/video_out.h for video out plugins, xine-engine/audio_out.h for audio out plugins. Additional information will also be given in the dedicated sections below. Many plugins will need some additional "private" data fields. These should be simply added at the end of the plugin structure. For example a demuxer plugin called "foo" with two private fields "xine" and "count" may have a plugin structure declared in the following way:    typedef struct {     /* public fields "inherited" from demux.h */     demux_plugin_t demux_plugin;         xine_t *xine;     int count;    } demux_foo_t; The plugin would then access public members via the demux_plugin field and private fields directly. Summary: Plugins consist of two C-style classes, each representing a different context. The first is the so called "plugin class" context. This is a singleton context, which means it will exist either not at all or at most once per xine context. This plugin class context is a C-style class which is subclassing the related class from the xine plugin headers. This contains functions, which are independent of the actual instance of the plugin. Most prominently, it contains a factory method to instantiate the next context. The second context is the instance context. This is another C-style class, which is constructed and disposed withing the plugin class context. This one does the actual work and subclasses the related plugin struct from the xine plugin headers. It is instantiated for every separate running instance of the plugin What is this metronom thingy? Metronom serves two purposes: Generate vpts (virtual presentation time stamps) from pts (presentation time stamps) for a/v output and synchronization. Provide a master clock (system clock reference, scr), possibly provided by external scr plugins (this can be used if some hardware decoder or network server dictates the time). pts/vpts values are given in 1/90000 sec units. pts values in mpeg streams may wrap (that is, return to zero or any other value without further notice), can be missing on some frames or (for broken streams) may "dance" around the correct values. Metronom therefore has some heuristics built-in to generate clean vpts values which can then be used in the output layers to schedule audio/video output. The heuristics used in metronom have always been a field of research. Current metronom's implementation tries to stick to pts values as reported from demuxers, that is, vpts may be obtained by a simple operation of vpts = pts + vpts_offset, where vpts_offset takes into account any wraps. Whenever pts is zero, metronom will estimate vpts based on previous values. If a difference is found between the estimated and calculated vpts values by above formula, it will be smoothed by using a "drift correction". How does xine synchronize audio and video? Every image frame or audio buffer leaving decoder is tagged by metronom with a vpts information. This will tell video_out and audio_out threads when that data should be presented. Usually there isn't a significative delay associated with video driver, so we expect it to get on screen at the time it's delivered for drawing. Unfortunately the same isn't true for audio: all sound systems implement some amount of buffering (or fifo), any data being send to it now will only get played some time in future. audio_out thread must take this into account for making perfect A-V sync by asking the sound latency to audio driver. Some audio drivers can't tell the current delay introduced in playback. This is especially true for most sound servers like ESD or aRts and explain why in such cases the sync is far from perfect. Another problem xine must handle is the sound card clock drift. vpts are compared to the system clock (or even to a different clock provided by a scr plugin) for presentation but sound card is sampling audio by its own clocking mechanism, so a small drift may occur. As the playback goes on this error will accumulate possibly resulting in audio gaps or audio drops. To avoid that annoying effect, two countermeasures are available (switchable with xine config option audio.synchronization.av_sync_method): The small sound card errors are feedbacked to metronom. The details are given by audio_out.c comments:    /* By adding gap errors (difference between reported and expected     * sound card clock) into metronom's vpts_offset we can use its     * smoothing algorithms to correct sound card clock drifts.     * obs: previously this error was added to xine scr.     *     * audio buf ---> metronom --> audio fifo --> (buf->vpts - hw_vpts)     * (vpts_offset + error) gap     * <---------- control --------------|     *     * Unfortunately audio fifo adds a large delay to our closed loop.     *     * These are designed to avoid updating the metronom too fast.     * - it will only be updated 1 time per second (so it has a chance of     * distributing the error for several frames).     * - it will only be updated 2 times for the whole audio fifo size     * length (so the control will wait to see the feedback effect)     * - each update will be of gap/SYNC_GAP_RATE.     *     * Sound card clock correction can only provide smooth playback for     * errors < 1% nominal rate. For bigger errors (bad streams) audio     * buffers may be dropped or gaps filled with silence.     */ The audio is stretched or squeezed a slight bit by resampling, thus compensating the drift: The next comment in audio_out.c explains:    /* Alternative for metronom feedback: fix sound card clock drift     * by resampling all audio data, so that the sound card keeps in     * sync with the system clock. This may help, if one uses a DXR3/H+     * decoder board. Those have their own clock (which serves as xine's     * master clock) and can only operate at fixed frame rates (if you     * want smooth playback). Resampling then avoids A/V sync problems,     * gaps filled with 0-frames and jerky video playback due to different     * clock speeds of the sound card and DXR3/H+.     */ Overlays and OSD The roots of xine overlay capabilities are DVD subpictures and subtitles support (also known as 'spu'). The DVD subtitles are encoded in a RLE (Run Length Encoding - the most simple compressing technique) format, with a palette of colors and transparency levels. You probably thought that subtitles were just simple text saved into DVDs, right? Wrong, they are bitmaps. In order to optimize to the most common case, xine's internal format for screen overlays is a similar representation to the 'spu' data. This brings not only performance benefit (since blending functions may skip large image areas due to RLE) but also compatibility: it's possible to re-encode any xine overlay to the original spu format for displaying with mpeg hardware decoders like DXR3. Displaying subtitles requires the ability to sync them to the video stream. This is done using the same kind of pts/vpts stuff of a-v sync code. DVD subtitles, for example, may request: show this spu at pts1 and hide it at pts2. This brings the concept of the 'video overlay manager', that is a event-driven module for managing overlay's showing and hiding. The drawback of using internal RLE format is the difficulty in manipulating it as graphic. To overcome that we created the 'OSD renderer', where OSD stands for On Screen Display just like in TV sets. The osd renderer is a module providing simple graphic primitives (lines, rectagles, draw text etc) over a "virtual" bitmap area. Everytime we want to show that bitmap it will be RLE encoded and sent to the overlay manager for displaying. overlays architecture Overlay Manager The overlay manager interface is available to any xine plugin. It's a bit unlikely to be used directly, anyway here's a code snippet for enqueueing an overlay for displaying:    video_overlay_event_t event;        event.object.handle = this->video_overlay->get_handle(this->video_overlay,0);        memset(this->event.object.overlay, 0, sizeof(*this->event.object.overlay));        /* set position and size for this overlay */    event.object.overlay->x = 0;    event.object.overlay->y = 0;    event.object.overlay->width = 100;    event.object.overlay->height = 100;        /* clipping region is mostly used by dvd menus for highlighting buttons */    event.object.overlay->clip_top = 0;    event.object.overlay->clip_bottom = image_height;    event.object.overlay->clip_left = 0;    event.object.overlay->clip_right = image_width;        /* the hard part: provide a RLE image */    event.object.overlay->rle = your_rle;    event.object.overlay->data_size = your_size;    event.object.overlay->num_rle = your_rle_count;        /* palette must contain YUV values for each color index */    memcpy(event.object.overlay->clip_color, color, sizeof(color));        /* this table contains transparency levels for each color index.     0 = completely transparent, 15 - completely opaque */    memcpy(event.object.overlay->clip_trans, trans, sizeof(trans));        /* set the event type and time for displaying */    event.event_type = EVENT_SHOW_SPU;    event.vpts = 0; /* zero is a special vpts value, it means 'now' */    video_overlay->add_event(video_overlay, &event); OSD Renderer OSD is a general API for rendering stuff over playing video. It's available both to xine plugins and to frontends. The first thing you need is to allocate a OSD object for drawing from the renderer. The code below allocates a 300x200 area. This size can't be changed during the lifetime of a OSD object, but it's possible to place it anywhere over the image.    osd_object_t osd;        osd = this->osd_renderer->new_object(osd_renderer, 300, 200); Now we may want to set font and color for text rendering. Although we will refer to fonts over this document, in fact the OSD can be any kind of bitmap. Font files are searched and loaded during initialization from $prefix/share/xine/fonts/ and ~/.xine/fonts. There's a sample utility to convert truetype fonts at xine-lib/misc/xine-fontconv.c. Palette may be manipulated directly, however most of the time it's convenient to use pre-defined text palettes.    /* set sans serif 24 font */    osd_renderer->set_font(osd, "sans", 24);        /* copy pre-defined colors for white, black border, transparent background to     starting at the index used by the first text palette */    osd_renderer->set_text_palette(osd, TEXTPALETTE_WHITE_BLACK_TRANSPARENT, OSD_TEXT1);        /* copy pre-defined colors for white, no border, translucid background to     starting at the index used by the second text palette */    osd_renderer->set_text_palette(osd, TEXTPALETTE_WHITE_NONE_TRANSLUCID, OSD_TEXT2); Now render the text and show it:    osd_renderer->render_text(osd, 0, 0, "white text, black border", OSD_TEXT1);    osd_renderer->render_text(osd, 0, 30, "white text, no border", OSD_TEXT2);        osd_renderer->show(osd, 0); /* 0 stands for 'now' */ There's a 1:1 mapping between OSD objects and overlays, therefore the second time you send an OSD object for displaying it will actually substitute the first image. By using set_position() function we can move overlay over the video.    for( i=0; i < 100; i+=10 ) {     osd_renderer->set_position(osd, i, i );     osd_renderer->show(osd, 0);     sleep(1);    }    osd_renderer->hide(osd, 0); For additional functions please check osd.h or the public header. OSD palette notes The palette functions demand some additional explanation, skip this if you just want to write text fast without worring with details! :) We have a 256-entry palette, each one defining yuv and transparency levels. Although xine fonts are bitmaps and may use any index they want, we have defined a small convention:    /*     Palette entries as used by osd fonts:         0: not used by font, always transparent     1: font background, usually transparent, may be used to implement     translucid boxes where the font will be printed.     2-5: transition between background and border (usually only alpha     value changes).     6: font border. if the font is to be displayed without border this     will probably be adjusted to font background or near.     7-9: transition between border and foreground     10: font color (foreground)    */ The so called 'transitions' are used to implement font anti-aliasing. That convention requires that any font file must use only the colors from 1 to 10. When we use the set_text_palette() function we are just copying 11 palette entries to the specified base index. That base index is the same we pass to render_text() function to use the text palette. With this scheme is possible to have several diferent text colors at the same time and also draw fonts over custom background.    /* obtains size the text will occupy */    renderer->get_text_size(osd, text, &width, &height);        /* draws a box using font background color (translucid) */    renderer->filled_rect(osd, x1, y1, x1+width, y1+height, OSD_TEXT2 + 1);        /* render text */    renderer->render_text(osd, x1, y1, text, OSD_TEXT2); OSD text and palette FAQ Q: What is the format of the color palette entries? A: It's the same as used by overlay blending code (YUV). Q: What is the relation between a text palette and a palette I set with xine_osd_set_palette? A: xine_osd_set_palette will set the entire 256 color palette to be used when we blend the osd image. "text palette" is a sequence of 11 colors from palette to be used to render text. that is, by calling osd_render_text() with color_base=100 will render text using colors 100-110. Q: Can I render text with colors in my own palette? A: Sure. Just pass the color_base to osd_render_text() Q: Has a text palette change effects on already drawed text? A: osd_set_text_palette() will overwrite some colors on palette with pre-defined ones. So yes, it will change the color on already drawed text (if you do it before calling osd_show, of course). If you don't want to change the colors of drawed text just use different color_base values. Q: What about the shadows of osd-objects? Can I turn them off or are they hardcoded? A: osd objects have no shadows by itself, but fonts use 11 colors to produce an anti-aliased effect. if you set a "text palette" with entries 0-9 being transparent and 10 being foreground you will get rid of any borders or anti-aliasing. MRLs This section defines a draft for a syntactic specification of MRLs as used by xine-lib. The language of MRLs is designed to be a true subset of the language of URIs as given in RFC2396. A type 2 grammar for the language of MRLs is given in EBNF below. Semantically, MRLs consist of two distinct parts that are evaluated by different components of the xine architecture. The first part, derivable from the symbol <input_source> in the given grammar, is completely handed to the input plugins, with input plugins signaling if they can handle the MRL. The second part, derivable from <stream_setup> and delimited from the first by a crosshatch ('#') contains parameters that modify the initialization and playback behaviour of the stream to which the MRL is passed. The possible parameters are mentioned in the manpage to xine-ui. The following definition should be regarded as a guideline only. Of course any given input plugin only understands a subset of all possible MRLs. On the other hand, invalid MRLs according to this definition might be understood for convenience reasons. Some user awareness is required at this point. EBNF grammar for MRLs:    <mrl> ::= <input_source>[#<stream_setup>]    <input_source> ::= (<absolute_mrl>|<relative_mrl>)    <absolute_mrl> ::= <input>:(<hierarch_part>|<opaque_part>)    <hierarch_part> ::= (<net_path>|<abs_path>)[?<query>]    <opaque_part> ::= (<unreserved>|<escaped>|;|?|:|@|&|=|+|$|,){<mrl_char>}    <relative_mrl> ::= (<abs_path>|<rel_path>)    <net_path> ::= //<authority>[<abs_path>]    <abs_path> ::= /<path_segments>    <rel_path> ::= <rel_segment>[<abs_path>]    <rel_segment> ::= <rel_char>{<rel_char>}    <rel_char> ::= (<unreserved>|<escaped>|;|@|&|=|+|$|,)    <input> ::= <alpha>{(<alpha>|<digit>|+|-|.)}    <authority> ::= (<server>|<reg_name>)    <server> ::= [[<userinfo>@]<host>[:<port>]]    <userinfo> ::= {(<unreserved>|<escaped>|;|:|&|=|+|$|,)}    <host> ::= (<hostname>|<ipv4_address>|<ipv6_reference>)    <hostname> ::= {<domainlabel>.}<toplabel>[.]    <domainlabel> ::= (<alphanum>|<alphanum>{(<alphanum>|-)}<alphanum>)    <toplabel> ::= (<alpha>|<alpha>{(<alphanum>|-)}<alphanum>)    <ipv4_address> ::= <digit>{<digit>}.<digit>{<digit>}.<digit>{<digit>}.<digit>{<digit>}    <port> ::= {<digit>}    <reg_name> ::= <reg_char>{<reg_char>}    <reg_char> ::= (<unreserved>|<escaped>|;|:|@|&|=|+|$|,)    <path_segments> ::= <segment>{/<segment>}    <segment> ::= {<path_char>}{;<param>}    <param> ::= {<path_char>}    <path_char> ::= (<unreserved>|<escaped>|:|@|&|=|+|$|,)    <query> ::= {<mrl_char>}    <stream_setup> ::= <stream_option>;{<stream_option>}    <stream_option> ::= (<configoption>|<engine_option>|novideo|noaudio|nospu)    <configoption> ::= <configentry>:<configvalue>    <configentry> ::= <unreserved>{<unreserved>}    <configvalue> ::= <stream_char>{<stream_char>}    <engine_option> ::= <unreserved>{<unreserved>}:<stream_char>{<stream_char>}    <stream_char> ::= (<unreserved>|<escaped>|:|@|&|=|+|$|,)    <mrl_char> ::= (<reserved>|<unreserved>|<escaped>)    <reserved> ::= (;|/|?|:|@|&|=|+|$|,|[|])    <unreserved> ::= (<alphanum>|<mark>)    <mark> ::= (-|_|.|!|~|*|'|(|))    <escaped> ::= %<hex><hex>    <hex> ::= (<digit>|A|B|C|D|E|F|a|b|c|d|e|f)    <alphanum> ::= (<alpha>|<digit>)    <alpha> ::= (<lowalpha>|<upalpha>)    <lowalpha> ::= (a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t|u|v|w|x|y|z)    <upalpha> ::= (A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z)    <digit> ::= (0|1|2|3|4|5|6|7|8|9) With <ipv6_reference> being an IPv6 address enclosed in [ and ] as defined in RFC2732. xine-lib-1.2/doc/hackersguide/README0000644000175000017500000000205214647725152014746 0ustar meme ---------------------- xine ---------------------- a free video player This directory contains the xine hacker's guide. The xine hacker's guide is written in docbook/sgml 4.1. You can learn more about docbook at http://www.oasis-open.org/docbook/documentation/reference/html/docbook.html To use docbook - for example to compile the sgml files into html - you will need the DocBook DTD itself as well as the following tools: dsssl (Modular DocBook Stylesheets), jade (SGML parser toolkit and dsssl engine) and sp (toolkit for sgml parsing), or replacements for those. If you want to generate TeX output (needed for postscript or pdf generation) you will also need jadetex (backend for TeX) and an installed TeX system (for example teTeX). sgmltools-lite examples: ------------------------ to generate html $ sgmltools -b onehtml hackersguide.sgml to generate pdf $ sgmltools -b pdf hackersguide.sgml building the hackersguide.html ------------------------------ The easy way to build everything is to issue a "make docs" here. xine-lib-1.2/doc/hackersguide/.hgignore0000644000175000017500000000003014647725152015663 0ustar memehackersguide.html *.png xine-lib-1.2/doc/hackersguide/post_frame.svg0000644000175000017500000013254114647725152016755 0ustar meme image/svg+xml post plugin get_frame field lock proc_frame proc_slice proc_macroblock draw field lock proc_frame proc_slice proc_macroblock draw draw get_frame field lock proc_frame proc_slice proc_macroblock draw get_frame field lock proc_frame proc_slice proc_macroblock draw free free / dispose free / dispose modify frame content frame from original port intercepted frame downstream meta-information from decoder to output upstream meta-information from output to decoder _x_post_intercept_frame _x_post_frame_copy_down _x_post_frame_copy_up _x_post_frame_u_turn _x_post_frame_copy_down _x_post_frame_copy_up _x_post_restore_video_frame d d d u d u d d d u d u d d u interception pass through modifying a copy dead-end draw freeing d u frame frame->next d u d d up down xine-lib-1.2/doc/hackersguide/hackersguide.docbook0000644000175000017500000000354314647725152020074 0ustar meme ]> The xine hacker's guide hackersguide GünterBartsch HeikoSchäfer RichardWareham MiguelFreitas JamesCourtier-Dutton SiggiLangauf MarcoZühlke MikeMelanson MichaelRoitzsch DiegoPettenò DarrenSalt 2001-2010 the xine project team This document should help xine hackers to find their way through xine's architecture and source code. It's a pretty free-form document containing a loose collection of articles describing various aspects of xine's internals. &intro; &library; &overview; &internals; &stream; &output; xine-lib-1.2/doc/hackersguide/library.docbook0000644000175000017500000003124314647725152017100 0ustar meme Using the xine library xine architecture as visible to libxine clients The following drawing shows the components of xine as outside applications see them. For every component, the functions for creating and destroying it are given. Every other function works in the context it is enclosed in. Functions that facilitate the connection of the individual components are also given. outside view on xine components The function are named just to give you an overview of what is actually there. It is all thoroughly documented in the plublic header xine.h, which is the main and preferably the only xine header, clients should include. (xine/xineutils.h and the XML parser might make an exception.) Details on the OSD feature can be found in the OSD section. Writing a new frontend to xine The best way to explain this seems to be actual code. Below you will find a very easy and hopefully self-explaining xine frontend to give you a start. One important thing to note is that any X11 based xine-lib frontend must call XInitThreads() before calling the first Xlib function, because xine will access the display from within a different thread than the frontend. Source code of a simple X11 frontend /* ** Copyright (C) 2003 Daniel Caujolle-Bert <segfault@club-internet.fr> ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** */ /* * compile-command: "gcc -Wall -O2 `pkg-config --cflags --libs libxine x11` -lm -o xinimin xinimin.c" */ #include <stdio.h> #include <string.h> #include <math.h> #include <X11/X.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h> #include <X11/Xatom.h> #include <X11/Xutil.h> #include <X11/extensions/XShm.h> #include <xine.h> #include <xine/xineutils.h> #define MWM_HINTS_DECORATIONS (1L << 1) #define PROP_MWM_HINTS_ELEMENTS 5 typedef struct { uint32_t flags; uint32_t functions; uint32_t decorations; int32_t input_mode; uint32_t status; } MWMHints; static xine_t *xine; static xine_stream_t *stream; static xine_video_port_t *vo_port; static xine_audio_port_t *ao_port; static xine_event_queue_t *event_queue; static Display *display; static int screen; static Window window[2]; static int xpos, ypos, width, height, fullscreen; static double pixel_aspect; static int running = 1; #define INPUT_MOTION (ExposureMask | ButtonPressMask | KeyPressMask | \ ButtonMotionMask | StructureNotifyMask | \ PropertyChangeMask | PointerMotionMask) /* this will be called by xine, if it wants to know the target size of a frame */ static void dest_size_cb(void *data, int video_width, int video_height, double video_pixel_aspect, int *dest_width, int *dest_height, double *dest_pixel_aspect) { *dest_width = width; *dest_height = height; *dest_pixel_aspect = pixel_aspect; } /* this will be called by xine when it's about to draw the frame */ static void frame_output_cb(void *data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y) { *dest_x = 0; *dest_y = 0; *win_x = xpos; *win_y = ypos; *dest_width = width; *dest_height = height; *dest_pixel_aspect = pixel_aspect; } static void event_listener(void *user_data, const xine_event_t *event) { switch(event->type) { case XINE_EVENT_UI_PLAYBACK_FINISHED: running = 0; break; case XINE_EVENT_PROGRESS: { xine_progress_data_t *pevent = (xine_progress_data_t *) event->data; printf("%s [%d%%]\n", pevent->description, pevent->percent); } break; /* you can handle a lot of other interesting events here */ } } int main(int argc, char **argv) { char configfile[2048]; x11_visual_t vis; double res_h, res_v; char *vo_driver = "auto"; char *ao_driver = "auto"; char *mrl = NULL; int i; Atom XA_NO_BORDER; MWMHints mwmhints; /* parsing command line */ for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-vo") == 0) { vo_driver = argv[++i]; } else if (strcmp(argv[i], "-ao") == 0) { ao_driver = argv[++i]; } else mrl = argv[i]; } if (!mrl) { printf("specify an mrl\n"); return 1; } printf("mrl: '%s'\n", mrl); if (!XInitThreads()) { printf("XInitThreads() failed\n"); return 1; } /* load xine config file and init xine */ xine = xine_new(); snprintf(configfile, sizeof(configfile), "%s%s", xine_get_homedir(), "/.xine/config"); xine_config_load(xine, configfile); xine_init(xine); display = XOpenDisplay(NULL); screen = XDefaultScreen(display); xpos = 0; ypos = 0; width = 320; height = 200; /* some initalization for the X11 Window we will be showing video in */ XLockDisplay(display); fullscreen = 0; window[0] = XCreateSimpleWindow(display, XDefaultRootWindow(display), xpos, ypos, width, height, 1, 0, 0); window[1] = XCreateSimpleWindow(display, XDefaultRootWindow(display), 0, 0, (DisplayWidth(display, screen)), (DisplayHeight(display, screen)), 0, 0, 0); XSelectInput(display, window[0], INPUT_MOTION); XSelectInput(display, window[1], INPUT_MOTION); XA_NO_BORDER = XInternAtom(display, "_MOTIF_WM_HINTS", False); mwmhints.flags = MWM_HINTS_DECORATIONS; mwmhints.decorations = 0; XChangeProperty(display, window[1], XA_NO_BORDER, XA_NO_BORDER, 32, PropModeReplace, (unsigned char *) &mwmhints, PROP_MWM_HINTS_ELEMENTS); XMapRaised(display, window[fullscreen]); res_h = (DisplayWidth(display, screen) * 1000 / DisplayWidthMM(display, screen)); res_v = (DisplayHeight(display, screen) * 1000 / DisplayHeightMM(display, screen)); XSync(display, False); XUnlockDisplay(display); /* filling in the xine visual struct */ vis.display = display; vis.screen = screen; vis.d = window[fullscreen]; vis.dest_size_cb = dest_size_cb; vis.frame_output_cb = frame_output_cb; vis.user_data = NULL; pixel_aspect = res_v / res_h; /* opening xine output ports */ vo_port = xine_open_video_driver(xine, vo_driver, XINE_VISUAL_TYPE_X11, (void *)&vis); ao_port = xine_open_audio_driver(xine , ao_driver, NULL); /* open a xine stream connected to these ports */ stream = xine_stream_new(xine, ao_port, vo_port); /* hook our event handler into the streams events */ event_queue = xine_event_new_queue(stream); xine_event_create_listener_thread(event_queue, event_listener, NULL); /* make the video window visible to xine */ xine_port_send_gui_data(vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void *) window[fullscreen]); xine_port_send_gui_data(vo_port, XINE_GUI_SEND_VIDEOWIN_VISIBLE, (void *) 1); /* start playback */ if (!xine_open(stream, mrl) || !xine_play(stream, 0, 0)) { printf("Unable to open mrl '%s'\n", mrl); return 1; } while (running) { XEvent xevent; int got_event; XLockDisplay(display); got_event = XPending(display); if( got_event ) XNextEvent(display, &xevent); XUnlockDisplay(display); if( !got_event ) { xine_usec_sleep(20000); continue; } switch(xevent.type) { case KeyPress: { XKeyEvent kevent; KeySym ksym; char kbuf[256]; int len; kevent = xevent.xkey; XLockDisplay(display); len = XLookupString(&kevent, kbuf, sizeof(kbuf), &ksym, NULL); XUnlockDisplay(display); switch (ksym) { case XK_q: case XK_Q: /* user pressed q => quit */ running = 0; break; case XK_f: case XK_F: { /* user pressed f => toggle fullscreen */ Window tmp_win; XLockDisplay(display); XUnmapWindow(display, window[fullscreen]); fullscreen = !fullscreen; XMapRaised(display, window[fullscreen]); XSync(display, False); XTranslateCoordinates(display, window[fullscreen], DefaultRootWindow(display), 0, 0, &xpos, &ypos, &tmp_win); XUnlockDisplay(display); xine_port_send_gui_data(vo_port, XINE_GUI_SEND_DRAWABLE_CHANGED, (void*) window[fullscreen]); } break; case XK_Up: /* cursor up => increase volume */ xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, (xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME) + 1)); break; case XK_Down: /* cursor down => decrease volume */ xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, (xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME) - 1)); break; case XK_plus: /* plus => next audio channel */ xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, (xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL) + 1)); break; case XK_minus: /* minus => previous audio channel */ xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, (xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL) - 1)); break; case XK_space: /* space => toggle pause mode */ if (xine_get_param(stream, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE) xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); else xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); break; } } break; case Expose: /* this handles (partial) occlusion of our video window */ if (xevent.xexpose.count != 0) break; xine_port_send_gui_data(vo_port, XINE_GUI_SEND_EXPOSE_EVENT, &xevent); break; case ConfigureNotify: { XConfigureEvent *cev = (XConfigureEvent *) &xevent; Window tmp_win; width = cev->width; height = cev->height; if ((cev->x == 0) && (cev->y == 0)) { XLockDisplay(display); XTranslateCoordinates(display, cev->window, DefaultRootWindow(cev->display), 0, 0, &xpos, &ypos, &tmp_win); XUnlockDisplay(display); } else { xpos = cev->x; ypos = cev->y; } } break; } } /* cleanup */ xine_close(stream); xine_event_dispose_queue(event_queue); xine_dispose(stream); xine_close_audio_driver(xine, ao_port); xine_close_video_driver(xine, vo_port); xine_exit(xine); XLockDisplay(display); XUnmapWindow(display, window[fullscreen]); XDestroyWindow(display, window[0]); XDestroyWindow(display, window[1]); XUnlockDisplay(display); XCloseDisplay (display); return 0; } xine-lib-1.2/doc/hackersguide/stream.docbook0000644000175000017500000010233414647725152016727 0ustar meme xine's stream layer Input layer Many media players expect streams to be stored within files on some local medium. In actual fact, media may be streamed over a network (e.g. via HTTP or RTP), encoded onto a specialized medium (e.g. DVD), etc. To allow you to access all this media, xine supports the concept of an "input plugin". The tasks performed by an input plugin are: Validation of Media Resource Locators (MRLs). MRL specific session management (e.g. opening and closing local files). Reading blocks/specific numbers of bytes from the input device. In addition to these tasks, the input plugin may keep track of some input device-specific state information (e.g. a DVD plugin may keep track of navigational state data such as current title/chapter). There are two classes of input device which xine recognizes. Byte-oriented devices can, upon request, return an arbitary non-zero number of bytes from a stream. Examples of such devices are files or network streams. Block-oriented devices, however, have a prefered block or "frame"-size. An example of such a device is a DVD where data is stored in logical blocks of 2048 bytes. One may pass the hint to xine that the plugin is block-oriented by setting the INPUT_CAP_BLOCK capability. Note that this is only a hint and xine does not guarantee that all requests to the plugin will be purely block based. Writing a xine input plugin An input plugin provides API functions which allow the engine to access the data source the plugin encapsulates. The input plugin API is declared in input/input_plugin.h. An input plugin exports a public function of the form:    void *input_init_plugin(xine_t *xine, void *data); This function initializes an input plugin class object with the following functions:    char *get_description(input_class_t *this_gen); This function returns a plaintext, one-line string describing the plugin.    char *get_identifier(input_class_t *this_gen); This function returns a shorter identifier describing the plugin.    xine_mrl_t **get_dir(input_class_t *this_gen, const char *filename, int *nFiles); Retrieves a directory listing from the plugin. This function is optional.    char **get_autoplay_list(input_class_t *this_gen, int *num_files); Retrieves the autoplay playlist from the plugin. This function is optional.    int eject_media(input_class_t *this_gen); Ejects the medium. This function is optional.    void dispose(input_class_t *this_gen); This function frees the memory used by the input plugin class object.    input_plugin_t *get_instance(input_class_t *class_gen, xine_stream_t *stream, const char *mrl); The plugin should try, if it can handle the specified MRL and return an instance of itself if so. If not, NULL should be returned. When a new MRL is to be played, xine engine asks all the available input plugins one by one if they can handle the MRL. Note that input plugins are not guaranteed to be queried in any particular order and the first input plugin to claim an MRL gets control so try not to duplicate MRLs already found within xine.    int open(input_plugin_t *this_gen); You should do any device-specific initialisation within this function.    uint32_t get_capabilities(input_plugin_t *this_gen); Returns a bit mask describing the input device's capabilities. You may logically OR the INPUT_CAP_* constants together to get a suitable bit-mask (via the '|' operator).    off_t read(input_plugin_t *this_gen, char *buf, off_t nlen); Reads a specified number of bytes into a buffer and returns the number of bytes actually copied.    buf_element_t *read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t len); Should the input plugin set the block-oriented hint and if the demuxer supports it, this function will be called to read a block directly into a xine buffer from the buffer pool.    off_t seek(input_plugin_t *this_gen, off_t offset, int origin); This function is called by xine when it is required that subsequent reads come from another part of the stream.    off_t get_current_pos(input_plugin_t *this_gen); Returns the current position within a finite length stream.    off_t get_length(input_plugin_t *this_gen); Similarly this function returns the length of the stream.    uint32_t get_blocksize(input_plugin_t *this_gen); Returns the device's prefered block-size if applicable.    char *get_mrl(input_plugin_t *this_gen); Returns the current MRL.    int get_optional_data(input_plugin_t *this_gen, void *data, int data_type); This function allows the input to advertise extra information that is not available through other API functions. See INPUT_OPTIONAL_* defines.    void dispose(input_plugin_t *this_gen); This function closes all resources and frees the input_plugin_t object. Demuxer layer This section is designed to familiarize a programmer with general demuxer concepts and how they apply to the xine multimedia library. Introduction to demuxer theory xine's demuxer layer is responsible for taking apart multimedia files or streams so that the engine can decode them and present them to the user. "Demuxer" is short for demultiplexor, which is the opposite of multiplexing. This refers to the process of combining 2 or more things into one. Multimedia streams usually, at a minimum, multiplex an audio stream and a video stream together into one stream. Sometimes, there are multiple audio streams (e.g., for multiple language tracks). Sometimes, there is a subtitle data stream multiplexed into the multimedia stream. There are many different multimedia formats in existence and there are varying strategies for demuxing different types of multimedia files. Formats in the MPEG family, for example, are designed to allow easy playback from almost any place within the file. Many formats cannot deal with this circumstance and at least need to be demuxed from the beginning of the stream and played through to the end. Some formats, such as MPEG and AVI, have marker information before every chunk in the stream. Other formats, such as Apple Quicktime, are required to have a master index that contains all information for taking apart a file. Many game-oriented multimedia formats are designed strictly for playing from start to finish without any regard to random seeking within the file. Input considerations A xine demuxer interacts with xine's input layer in order to receive data. The underlying input plugin might be a file, a network stream, or a block-oriented disc storage device like a DVD. A file input offers the most flexibility in being able to read either blocks of data or individual bytes, and being able to seek freely. Other input plugins may not allow the demuxer to seek (such as stdin or certain network streams). Some input plugins only allow the demuxer to read blocks of data and not individual bytes (such as the CD-DA input plugin). The demuxer needs to check the capabilities of the underlying input plugin before attempting to seek around. Seeking Policy If possible, it is desirable that a demuxer can seek randomly through the stream. This is easier for some file formats and essentially impossible for other formats. xine's seeking API function allows a seek target to be specified in terms of a ratio from 0 to 65535, or time in milliseconds from 0. Time-based seeking is useful for specifying, e.g., a 1-minute jump forward or backward in a stream. With the ratio-based seeking, the demuxer can interpret the ratio value in the domain he sees most fit. This can also be some sort of time or a simple file offset. If a multimedia stream has video, there generally needs to be a way to identify keyframes in the stream in order to facilitate seeking. Many game-oriented formats fall over in this area as they carry no keyframe information aside from the implicit assumption that the first frame is a keyframe. In a stream with video, a seek operation should always jump to a keyframe. xine Policy: When the seek target is between 2 keyframes, jump to the earlier keyframe. E.g., if there are keyframes at stream offsets 10000 and 20000, and the user requests a seek to offset 18000, choose the keyframe at offset 10000. Note that there can be difficulties when the audio and video streams are not tightly interleaved. In many formats, the audio frames are several time units ahead of the video frames for the purpose of pre-buffering. This is a typical scenario in the middle of a stream:    audio frame @ time 10    video frame @ time 8    audio frame @ time 11    video frame @ time 9    audio frame @ time 12     keyframe @ time 10    audio frame @ time 13 If the demuxer seeks to the keyframe @ time 10, the next audio chunk will have a timestamp of 13, which is well ahead of where the video is. While the xine engine will eventually recover, it will make playback choppy for a few seconds after the seek. One strategy for dealing with this situation is to seek back to the nearest keyframe before the requested seek and then seek back to find the audio frame with the nearest timestamp before the keyframe. In this example, that would mean seeking back to [af@time 10]. Then, demux the chunks in order, but skip the video frames until the next keyframe is encountered. Writing a xine demuxer A demuxer plugin provides API functions which allow the engine to initialize demuxing, dispatch data chunks to the engine, seek within the stream, get the stream length, among other functions. The demuxer API is declared in demuxers/demux.h. Writing a new xine demuxer is largely a process of using other demuxers as references and understanding how they interact with the engine. This section will give a brief overview of each API function. A demuxer plugin exports a public function of the form:    void *demux_wc3movie_init_plugin(xine_t *xine, void *data); This function initializes a demuxer plugin class object with 6 demuxer-specific functions. These functions mainly provide information that a frontend can use to build user-friendly features. These functions include:    char *get_description(demux_class_t *this_gen); This function returns a plaintext, one-line string describing the plugin.    char *get_identifier(demux_class_t *this_gen); This function returns a shorter identifier describing the plugin.    char *get_extensions(demux_class_t *this_gen); This function returns a string with the file extensions that this demuxer is known to use. For example, Microsoft .WAV files use "wav". If there are multiple known extensions, separate each extension with a space. For example, Apple Quicktime has the extensions "mov qt mp4".    char *get_mimetypes(demux_class_t *this_gen) This function returns a string with the MIME types that this demuxer is known to use. Multiple MIME type specifications should be separated with a semicolon (;). For example, Apple Quicktime uses several MIME types:    return "video/quicktime: mov,qt: Quicktime animation;"     "video/x-quicktime: mov,qt: Quicktime animation;"     "application/x-quicktimeplayer: qtl: Quicktime list;";    void class_dispose(demux_class_t *this_gen); This function frees the memory used by the demuxer plugin class object.    demux_plugin_t *open_plugin(demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input_gen); This function is invoked by the xine engine to determine if the demuxer is able to handle a particular multimedia stream. The engine can specify if the demuxer is supposed to check the stream by content (validate the actual stream data and see if it is of the expected type), by extension (check the name of the MRL and see if the file extension is correct), or explicitly (the engine is passing on a user request to force this demuxer to be used). The order in which the engine queries the available demuxers is determined by the priority stated in the demuxer_info_t, which is attached to every demuxer's plugin info structure. Demuxers with higher priority values are called before those with lower priority. The order amongst demuxers of equal priority is undefined. The idea behind this is to have the demuxers for high-level container formats have high priorities, while the raw format demuxers have low priorities. This way, a stream of a high-level container format with a beginning that happens to look like a low-level raw format is still handled by the correct demuxer, because it is queried first. NOTE: In the course of checking the stream by content, care must be taken not to consume bytes out of a non-seekable stream. If the stream is non-seekable, use the input plugin's preview buffer facility to get a cache of the first few bytes. If the stream is seekable, reset the stream before operating on the data (you do not know where some other demuxer left the stream positioned). If the demuxer can handle the stream, it creates a new demux_plugin_t structure and initializes the main demuxer functions which are called by the engine to do the tough demuxing duty. These functions include:    void demux_send_headers(demux_plugin_t *this_gen); This function generally reads the headers of the stream, does whatever it has to do to figure out what audio and video codecs are used in the file, and asks the xine engine to initialize the correct decoders with the proper parameters (like width and height for video, sample rate and channels for audio).    int demux_send_chunk(demux_plugin_t *this_gen); This function reads data from the stream and sends it to the appropriate decoder. This is where the bulk of the demuxing work is performed. Despite the name, the function is actually free to send as much data as it wants to, or as much as it can. A good policy is to send an entire chunk of compressed audio or video data and then return. The chunk is likely large enough that it will have to be broken up into multiple xine buffers. If a chunk of audio is 20000 bytes large, and the engine is returning 4096-byte buffers, send 4 full buffers and 1 partial buffer to the audio decoder and then return.    int demux_seek(demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing); This function is called by the engine to request stream repositioning. This function should be implemented if possible. See the section on "Seeking Policy" for more information. A seek operation should reposition the demuxer's internal accounting variables to be ready to start dispatching chunks from the new position when the xine engine calls demux_send_chunk() again. If seeking is not feasible, the function quietly returns and the demuxer's position is unaffected.    void demux_dispose(demux_plugin_t *this_gen); This function frees the demux_plugin_t object.    int demux_get_status(demux_plugin_t *this_gen); This function returns the current internal status of the demuxer. There are 2 states: DEMUX_OK, for when the demuxer is demuxing or ready to demux, and DEMUX_FINISHED, for when the demuxer has reached the end of the stream or has encountered some sort of error.    int demux_get_stream_length(demux_plugin_t *this_gen); This function returns the length (time duration) of the stream in milliseconds. If the length of the stream cannot be determined, return 0.    uint32_t demux_get_capabilities(demux_plugin_t *this_gen); This function returns an array of bit flags indicating special features of the demuxer. See DEMUX_CAP_* defines.    int demux_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type); This function allows the demuxer to advertise extra information that is not available through other API functions. See DEMUX_OPTIONAL_* defines. Buffer types Demuxer must send data to decoders using two fifos names video_fifo and audio_fifo. Both are available at stream level. The following code fragment shows how it's done.    buf_element_t *buf;        buf = stream->video_fifo->buffer_pool_alloc(stream->video_fifo);    buf->type = BUF_CONTROL_START;    stream->video_fifo->put(stream->video_fifo, buf); Buffers must have set the type field as shown. All buffer types are defined in xine-engine/buffer.h. The control buffer types are very important and must be sent by all kinds of demuxers. They tell decoders to start/stop their operations and inform metronom about discontinuities, either relative or absolute. There is also a reset buffer type that must be sent when demuxers are seeking as a "warm restart" indication to the decoders. To help finding out buffer types for known codecs, functions from buffer_types.c may be used to convert "FOURCC" codes or audio format tags (as used in AVI files) to the xine byffer type:    buf->type = fourcc_to_buf_video((void*)this->avi->bih.biCompression); Decoder layer This section is designed to familiarize a programmer with basic audio and video decoding concepts and how they apply to the xine decoder API. Audio and video decoders Audio and video data requires an enormous amount of storage. Thus, the raw data is encoded using a variety of compression techniques which drastically reduces the amount of space required to transmit and store the data. Before playback, the compressed data needs to be decoded. The process of decoding data is rather straightforward in a computer science sense: An array of encoded data is fed into a decoder and the decoder outputs an array of decoded data which is ready to be presented to the user (either displayed on the screen or played through the speakers). Video output formats Raw video data comes in a variety of formats, most commonly in RGB and YUV. xine's output layer currently only accepts data in YV12 format (a.k.a. YUV 4:2:0 planar) or YUY2 format (a.k.a. YUV 4:2:2 packed). If the output format is a RGB space, the data must be converted to an acceptable YUV format before being dispatched to the video output unit. xine has a number of support functions to facilitate converting RGB to YUV. Audio output formats Raw audio data equates to uncompressed PCM audio. xine's audio output modules expect 8-bit PCM data to be unsigned and 16-bit PCM data to be signed and in little endian format. When there is more than one channel, the channel data is interleaved. For example, stereo data is interleaved as left sample, right sample: LRLRLRLR. If there are 4 or 6 channels, the same interleaving applies: 123456123456. Writing a xine decoder Writing a new xine decoder for an audio or video format entails accumulating a buffer of encoded data, performing the necessary operations for decoding and then passing it on the appropriate output module. The best reference for understanding the decoder API is the various decoding modules available. In particular, xine has example video and audio decoders named src/libxinevdec/foovideo.c and src/libxineadec/fooaudio.c, respectively. This section will give a brief overview of each API function. The decoder API is declared in src/xine-engine/video_decoder.h and src/xine-engine/audio_decoder.h. A decoder plugin must, like every plugin, export a public array of plugin_info_t types. The array usually has 2 entries: The first contains the plugin information regarding the decoder and the second entry is a terminating NULL entry. However, there may be more entries. Each entry contains 6 fields: plugin type: Either PLUGIN_VIDEO_DECODER or PLUGIN_AUDIO_DECODER. API: The plugin API revision that this plugin adheres to. name: A character string that identifies the plugin. version: #define'd as XINE_VERSION_CODE. supported types: A structure that defines the buffer types that this plugin can handle. init function: The function that the xine engine calls in order to initialize this decoder plugin. The supported types field is a decoder_info_t structure. This struct combines a list of buffer types that the plugin can handle, along with a relative default priority. The priority allows xine to have multiple plugins that can handle one data type and the plugin with the highest priority takes precedence. The code defines the default priority, which can be overriden by the user. The list of buffer types is an array of uint32_t types from the list of buffer types defined in src/xine-engine/buffer.h.    void *init_plugin(xine_t *xine, void *data); This function allocates a plugin class and initializes a set of functions for the xine engine to invoke. These functions include:    char *get_identifier(video_decoder_class_t *this);    char *get_identifier(audio_decoder_class_t *this); This function returns a brief character string identifying the plugin.    char *get_description(video_decoder_class_t *this);    char *get_description(audio_decoder_class_t *this); This function returns a slightly longer description of the plugin.    void dispose_class(video_decoder_class_t *this);    void dispose_class(audio_decoder_class_t *this); This function frees the resources allocated by the plugin class.    video_decoder_t *open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream);    audio_decoder_t *open_plugin(audio_decoder_class_t *class_gen, xine_stream_t *stream); This function initializes the decoder plugin's private state. It also initializes and returns either an audio_decoder_t or a video_decoder_t for the engine. The decoder_t contains a number of functions that the plugin invokes to handle data decoding. These functions include:    void decode_data(video_decoder_t *this_gen, buf_element_t *buf);    void decode_data(audio_decoder_t *this_gen, buf_element_t *buf); This function performs the bulk of the decoding work. The xine engine delivers buffers (xine_buffer_t data types) to this function and it is up to this function to assemble the parts of the buffer, decode the data, and send the decoded data to the proper output unit. The constraint is that you must never call a port function of the output port when the port has not been opened by you. (See the open() and close() functions of xine_video_port_t and xine_audio_port_t.) A buffer has a decoder_flags field which can have a number of flags set. The first buffer that a decoder receives ought to have the BUF_FLAG_HEADER flag set. This indicates that the buffer content contains the essential setup information for decoding (width, height, etc. for video; sample rate, channels, etc. for audio). If the BUF_FLAG_HEADER flag is not set, the content of the buffer should be accumulated in a private buffer until a buffer with a BUF_FLAG_FRAME_END flag is set. This indicates that the entire chunk has been transmitted to the decoder and is ready to be decoded. Fetch either an empty video frame or audio buffer from the appropriate output unit. Perform the appropriate decoding operations and set the pts for the output buffer (and the duration, a.k.a. video_step, for video). Dispatch the decoded data to the output and reset the internal buffer accumulation accounting.    void flush(video_decoder_t *this_gen);    void flush(audio_decoder_t *this_gen); This function is called when either the xine engine flushes the stream, e.g., after a seek operation or when decoding runs too slow and frames arrive in the output loops fast enough. Decoders should release everything they have already decoded, drop the rest and wait for new input.    void reset(video_decoder_t *this_gen);    void reset(audio_decoder_t *this_gen); This function is called when the xine engine resets the stream. Decoders should get ready to receive data that has nothing to do with the one it worked on up to now.    void discontinuity(video_decoder_t *this_gen);    void discontinuity(audio_decoder_t *this_gen); This function is called when the xine engine encounters a pts discontinuity. Decoders should forget all timestamping information they might have accumulated from the stream to not confuse metronom.    void dispose(video_decoder_t *this_gen);    void dispose(audio_decoder_t *this_gen); This function frees the resources used by the decoder plugin. SPU decoder A lot written above also applies for subpicture unit (SPU) decoders. The SPU decoder API is declared in src/xine-engine/spu_decoder.h. Details on the data, SPU decoders are expected to output, see the section on overlays and OSD. However, there are some differences to consider. At first, unlike audio and video, subtitles do not form a continuous stream. The decoder will therefore only be called once in a while. The metronom call for timestamping, which for audio and video is done by the engine, has to be done manually for SPU:    vpts = metronom->got_spu_packet(metronom, buf->pts); Another difference is that while both audio and video decoders are automatically blocked in their get_buffer()/get_frame() methods when the output cannot take any more data, this does not work for SPU, because it could take minutes before the next free slot becomes available and we must not block the decoder thread for that long since it might be shared with a video decoder. But when a SPU decoder does not share the thread and we let it run without any blocking, it will overflow the available overlay slots very soon. Since SPU decoders should not have to know, whether they share the thread or not, a helper function _x_spu_decoder_sleep() is provided, which, when told the timestamp of the next overlay, will wait long enough to not overflow the overlay slots, but short enough to not hinder a video decoder in the same thread. There are also two functions in the SPU decoder API, which have not been discussed above:    int get_interact_info(spu_decoder_t *this_gen, void *data); Since SPUs are sometimes (on DVDs for example) used for user interaction like menu highlights, this function can be called to get data filled with the current interaction information. The caller and the decoder have to agree on what this is exactly. With DVDs, you can get a copy of the current NAV packet here.    void set_button(spu_decoder_t *this_gen, int32_t button, int32_t mode); Also for interaction, you can ask the decoder here to change the current highlighting. xine-lib-1.2/doc/README.dvb0000644000175000017500000001433314647725152013067 0ustar meme xine Digital TV (DVB) ===================== xine can be used to watch digital television. xine supports Digital TV (Digital Video Broadcasting - DVB) cards using the Linux DVB drivers in your kernel or from http://www.linuxtv.org/. Many DVB-S (direct satellite reception), DVB-C (Cable) and DVB-T and ATSC (Terrestrial) devices are supported via these drivers. Driver download and installation -------------------------------- You may need to download and install drivers for recent hardware. See the "Getting Started" section at http://www.linuxtv.org/wiki/index.php/ . You will probably need to add yourself to group "video". With a DVB device installed and recognised: $ ls -l /deb/dvb/adapter0 total 0 crw-rw---- 1 root video 212, 4 2007-08-07 15:33 demux0 crw-rw---- 1 root video 212, 5 2007-08-07 15:33 dvr0 crw-rw---- 1 root video 212, 3 2007-08-07 15:33 frontend0 crw-rw---- 1 root video 212, 7 2007-08-07 15:33 net0 This shows that you need to be either root or in group "video" to be able to use the DVB device. You can find out if you're already in this group by using the "groups" command in a terminal. If you aren't, then trying to use the DVB plugin will cause a "no input plugin" error: this is somewhat misleading because the DVB plugin was actually found but it failed because it couldn't open the device nodes. Adding yourself to group "video" is the best way; one of # adduser fred video $ sudo adduser fred video will do the job for a user named "fred". Note that the change won't take effect until after fred has logged out if he's currently logged in. Install a channel list ---------------------- xine-lib's dvb input plugin needs a channel/transponder list that fits your dvb equipment. xine-lib uses the channels.conf format of szap, czap and tzap as appropriate for DVB-S, DVB-C and DVB-T. It will search the channel list file in ~/.config/xine/channels.conf. channel list format for DVB-S: (satellite) ------------------------------------------- NBC :11053 :h :1 :27500 :550 :551 :1 :8008 station name:freqency:h/v:sat no :symbol rate:vpid:apid:sid:???? ------------------------------------------- channel list format for DVB-T (terrestrial): ------------------------------------------- WINSA :557500000:INVERSION_AUTO:BANDWIDTH_7_MHZ:FEC_2_3:FEC_AUTO:QAM_64: \ TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE :33 :36 :1 station name:frequency:config options go on seemingly forever ... :vpid:apid:serviceid ------------------------------------------- You scan for all available channels using the scan utility which comes with the dvb-apps package (also known as dvb-utils). See http://www.linuxtv.org/wiki/index.php/Scan for more information. $ scan /usr/share/doc/dvb-utils/examples/scan/dvb-t/uk-PontopPike >~/.config/xine/channels.conf $ scan Hotbird-13.0 >~/.config/xine/channels.conf This can take a while. In a DiSEqC environment, use the -s N switch to select different satellites to scan and paste the results in one big channels.conf file. As always, please be sure to read the man page for the version of the tool you are using. HINT: you might want to manually sort the channels.conf file to have your favourite channels at the top and maybe remove any scrambled channels to which you don't have access. Using xine to watch digital television -------------------------------------- Make sure you have a recent libxine and front end installed, then simply start something like $ gxine dvb:// or, perhaps, click on the DVB button in xine-ui. You should be able to zap around using the NumPad-9 / NumPad-3 keys, the xine playlist, or using the next/previous chapter buttons in your gui. An OSD menu is available too. Press NumPad-8 / NumPad-2 to scroll through the channels, then press NumPad-Enter to switch to the channel you have selected. The channel list can be brought up and scrolled through via the mouse wheel. Use the left mouse button to switch to the channel you've selected. The side buttons (6 & 7) can be used to rapidly switch to previous/next channels, if they are available on your mouse. You can use MENU3 (F2 in xine-ui, F3 in gxine) to zoom into the centre of a videostream. This will allow you to view 4:3 content that has been embedded into a 16:9 stream in fullscreen (no more black borders). Press the key again to return to normal viewing. There is also an option in the xine preferences to zoom automatically when using xine to view DVB. MENU7 (F6 in xine-ui or F7 in gxine) will toggle viewing of the current channel's Electronic Program Guide (information on the current/next program) on the OSD, if available. HINT: if audio or video is stuttering, pause (space key) shortly to give xine-lib a chance to fill its buffers. If watching a large HDTV stream, you may need to increase the xine video & audio buffer size - increasing audio buffers to 300 and video buffers to 700 has been known to work with streams up to 1920x1088 in size. Recording digital television ---------------------------- There is a very simple VCR-like feature built into the xine engine. just press MENU2 (that is F2 in gxine, or F1 in xine-ui for example) to start/stop recording the currently displayed program to your local disc. A small OSD message in the upper left corner of your screen will tell you the file name the recorded stream is being written to. You can select the directory to save to in the xine configuration under the MISC tab, otherwise the plugin will record to your home directory. You can pause the recording at any time by pressing MENU4 (F3 in xine-ui, F4 in gxine). An OSD in the top left hand corner will notify you of the status of the recording. Pressing MENU4 again will resume recording. Using the Kaffeine DVB frontend ------------------------------- Kaffeine has a very nice DVB (digital TV) frontend. However, since Qt/KDE 4, Kaffeine no longer has a built-in configuration GUI. The defaults are not really optimal. A suggested quick solution is: * close Kaffeine * build/install xine-ui * do your configuration with that * make Kaffeine use it too: $ ln -sf ~/.xine/config ~/.kde4/share/apps/kaffeine/xine-config A similar trick applies to previewing videos in Gwenview via phonon: $ ln -sf ~/.xine/config ~/.config/kde.org/Phonon-Xine.xine.conf Have fun. xine-lib-1.2/doc/Doxyfile.in0000644000175000017500000012446414647725152013557 0ustar meme# Doxyfile 1.5.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = @PACKAGE@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = @VERSION@ # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = @abs_top_builddir@/doc/api/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = @top_srcdir@ # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for Java. # For instance, namespaces will be presented as packages, qualified scopes # will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to # include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = YES # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = YES # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from the # version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = @abs_top_srcdir@/src @abs_top_builddir@/include # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = */src/libw32dll/wine/* EXCLUDE_PATTERNS += */src/input/libdvdnav/* EXCLUDE_PATTERNS += */src/input/vcd/libcdio/* EXCLUDE_PATTERNS += */src/input/vcd/libvcd/* EXCLUDE_PATTERNS += */src/libxineadec/nosefart/* EXCLUDE_PATTERNS += */src/libxineadec/gsm610/* # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = . # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = DOXYGEN XINE_COMPILE PREDEFINED += XINE_PACKED= ATTR_ALIGN(x)= XINE_PROTECTED= PREDEFINED += XINE_MALLOC= # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO xine-lib-1.2/doc/README.freebsd0000644000175000017500000000553614647725152013733 0ustar meme ---------------------- xine ---------------------- a free video player This document contains FreeBSD related information about xine xine fails when allocating images --------------------------------- Make sure you have enough shared memory enabled. This is very limited by default. Edit your /etc/sysctl.conf: kern.ipc.shmmax=67108864 kern.ipc.shmall=32768 mtrr on freebsd --------------- setting up the caching behaviour of the memory on the graphics board. what is being done with the mtrr support on linux is to set the caching type of the memory of the graphics board to 'write-combine' mode. that way the performance of big writes into this memory should be faster. it seems that the same can be achieved on freebsd by executing: memcontrol set -b -l write-combine for example on my system i executed: memcontrol set -n 0xd8000000 -l 0x02000000 write-combine i got the base-adress by executing 'startx' and looking at the output. it seems to be dangerous to change the cache setting of the graphics memory while xfree is running - at least i managed to have my system freeze that way. so better do it on the commandline. this tip is still subject of research, so it might be incorrect - please report any further information on this topic to the xine-user list. please also report success or non-success on xine-user if you have the time. playing video cd on freebsd --------------------------- currently (because of issues with the freebsd kernel) xine can only play video cd from atapi cdrom drives. not for scsi drives! currently (Jan 2001), FreeBSD-stable (and thus the current releases also) needs a patch to the kernel sources to make video cd work (please check the freebsd documentation if you are unsure on how to build a custom kernel with this patch included). the file you have to patch is /sys/dev/ata/atapi-cd.c: *** atapi-cd.c.orig Sun Jan 21 14:42:57 2001 --- atapi-cd.c Sun Jan 21 14:47:13 2001 *************** *** 1163,1174 **** return; } } ! if (blocksize == 2048) ! ccb[0] = ATAPI_READ_BIG; ! else { ! ccb[0] = ATAPI_READ_CD; ! ccb[9] = 0x10; ! } } else ccb[0] = ATAPI_WRITE_BIG; --- 1163,1182 ---- return; } } ! switch (blocksize) { ! case 2048: ! ccb[0] = ATAPI_READ_BIG; ! break; ! ! case 2352: ! ccb[0] = ATAPI_READ_CD; ! ccb[9] = 0xf8; ! break; ! ! default: ! ccb[0] = ATAPI_READ_CD; ! ccb[9] = 0x10; ! } } else ccb[0] = ATAPI_WRITE_BIG; v4l on freebsd -------------- For building v4l plugins you will need install v4l_compat package. ------------------------------------------------------------------------ xine-lib-1.2/doc/README.opengl0000644000175000017500000000752414647725152013604 0ustar memeStartup ------- Start xine with '-V opengl'. You can choose the render technique in xine's configuration menu (video.output.opengl_renderer). The following renderer are available: * 2D_Tex_Fragprog This module downloads the images as YUV 2D textures and renders a textured slice using fragment programs for reconstructing RGB. This is the best and fastest method on modern graphics cards. Performance similar to XVideo or even better. Good for 1080p HDTV. * 2D_Tex This module downloads the images as 2D textures and renders a textured slice. * 2D_Tex_Tiled This module downloads the images as multiple 2D textures and renders a textured slice. Thus this works with smaller maximum texture sizes as well. * Image_Pipeline This module uses glDraw() to render the images. Only accelerated on few drivers. Does not interpolate on scaling. * Cylinder Shows images on a rotating cylinder. Nice effect :) * Environment_Mapped_Torus Show images reflected in a spinning torus. Way cool =) Problems you might encounter (FAQ) ---------------------------------- * Output is *extremely* slow Run 'glxinfo' and check the third output line saying 'direct rendering:' If it doesn't say 'Yes', you are not running an accelerated OpenGL setup. Check your installation. Image_Pipeline based rendering is typically slower than 2D_Textures. Note that OpenGL output is always slower than XVideo, and often faster than X shared memory. * Output is still slower than xshm, even though I do have direct rendering The Mesa hardware accelerated drivers do not seem to be optimized WRT texture transfer, at least for the older radeon chips. If it does not work well with other drivers please drop me a line. * xine crashes when switching to fullscreen ('f') and back This only happens with accelerated Mesa drivers (reproducable), not with the binary only NVIDIA and ATI drivers. So either I uncovered a seldomly triggered bug in Mesa, or (more likely) there is still an undiscovered race or bug in the output plugin. I have debugged it a lot, but I cannot find anything wrong in my code. Can someone verify this behavior? * I've chosing a more complex rendering option, but suddenly xine switched back to '2D_Tex' or '2D_Tex_Tiled' If the current video cannot be displayed with the render settings, xine falls back to a render technique that is capable of displaying the video. Unfortunately, this can happen e.g. for large video frames, while smaller video frames could be rendered differently, but xine does not switch back to complex rendering techniques for them. This also can happen for decoders using the WinAPI for loading windows codecs from /usr/lib/codecs. They often decode into interleaved YUY2 video instead of planar YUV, which is not yet implemented. You have to switch back to more complex rendering techniques like '2D_Tex_Fragprog' manually. * Low color quality / quantization artifacts xine might choose a visual with a different color depth than you would prefer. Choose an appropriate visual with 'glxinfo' and select it with '-V opengl --visual xyz' in this case. Known minor issues ------------------ * GL_BGRA (used on little endian machines, i.e. ix86) needs an extension check. This is implemented, but not used yet... * Big endian machines have not been checked yet. * VO_CAP_UNSCALED_OVERLAY reduces performance a lot during the first few frames. Thus disabled. * Cropping is not yet implemented - this is done by video_out.c * XINE_GUI_SEND_WILL_DESTROY_DRAWABLE only sent by few UIs * On startup or when switching to fullscreen, the screen may remain black on rare occasions. On the next switch, however, everything looks normal. Seems like a race, again. I've given up finding it. Feel free to look at the code. Hasn't happened for a while for me, maybe it is gone now. Matthias Hopf xine-lib-1.2/doc/README.irix0000644000175000017500000000133614647725152013266 0ustar memebuilding xine on IRIX --------------------- * Choose gcc for compilation during configure, e.g. 'env CC=gcc ./configure' * Compile xine with GNU make (gmake). Known Problems -------------- * Cannot compile with IRIX cc This is an unresolved issue with automake and dependencies. Not likely to be fixed soon. * xine only opens a 16 bit visual and looks ugly This is done intentionally (speedup on most architectures). Choose an appropriate visual (with xdpyinfo) and select it e.g. with 'xine --visual 0x33'. * Scaling is slow Choose the opengl plugin instead of the xshm plugin. However, this plugin is still highly experimental, expect some crashes, and read README.opengl Matthias Hopf xine-lib-1.2/doc/README.solaris0000644000175000017500000000763514647725152013777 0ustar meme ---------------------- xine ---------------------- a free video player building xine on solaris ------------------------ * The preferred make command to compile xine is GNU make (gmake, /opt/sfw/bin/gmake). Sun's make (/usr/ccs/bin/make, or dmake) may work, too. * On Solaris x86: When xine-lib code is build using GCC as the compiler, xine-lib tries to use MMX/SSE/3DNOW! instructions of x86 CPUs, which may not assemble using Solaris' /usr/ccs/bin/as. Make sure to use the GNU assembler as the assembler backend for the GNU C compiler and as a standalone assembler command. A quick workaround when using the GCC from Sun's "Software Companion" CD is to replace /usr/ccs/bin/as with a link to GNU as, for example like this: cd /usr/ccs/bin ln -s /opt/sfw/bin/gas gnu-as mv as sun-as ln -s gnu-as as (Use "ln -s gnu-as as" or "ln -s sun-as as" to switch between the two assemblers) * To get VIS accelerated video decoding and colour space conversion on Solaris SPARC with an UltraSPARC cpu, download and install Sun's mediaLib 2.0 before compiling xine. mediaLib is available here: http://www.sun.com/sparc/vis/mediaLib.html Known Problems -------------- * Can't use MIT shared memory for local video display The default value for the maximum allowed shared memory segment size (1MByte) and the number of allowed shared memory segments (6) is very small on solaris. You may want to increase both parameters. Add the following lines to /etc/system to increase the shmmax parameter to 8MBytes and the shmseg parameter to at least 32 [*]: set shmsys:shminfo_shmmax=8388608 set shmsys:shminfo_shmseg=32 Reboot the machine after modifying /etc/system to activate the new shared memory defaults. [*] Note: 15 shared memory segments is the minimum requirement for xine's "XShm" video output plugin; 32 gives a bit of extra room for other applications. The GUI frontend might need more shared memory segments, see below. * Warnings from xine-ui, when playlist / control / mrl browser panel is opened (and broken skin image elements in these panels): xiTK WARNING: X error received: 'BadShmSeg (invalid shared segment parameter)' xiTK WARNING: X error received: 'BadAccess (attempt to access private resource denied)' xiTK WARNING: XShmAttach() failed. xine-ui tries to use even more shared memory segments for skin images. Workaround: The problem can be avoided with one of - create a text file $HOME/.xitkrc (or /etc/xitkrc) and add the following line into it feature.shm = 0 - configure and build xine-ui with option "--disable-shm" or "--disable-shm-default" - increase shmsys:shminfo_shmseg to at least 768 * When using an 8-bit display, xine aborts with the error message: IMLIB ERROR: Cannot Find Palette. A Palette is required for this mode Unable to initialize Imlib xine expects an installed Imlib package, installed using the "prefix" / xine is looking for the global Imlib config file in /etc/imrc. If you have the solaris 8 companion CD installed, an Imlib package is already installed on your system, but it uses the "prefix" /opt/sfw. To work around the problem: - install a symbolic link /etc/imrc, pointing to /opt/sfw/etc/imrc (needs root permission) # ln -s /opt/sfw/etc/imrc /etc or - install an ".imrc" file in your home directory, with the following contents: PaletteFile /opt/sfw/etc/im_palette.pal * On Solaris x86, you cannot reliably play DVDs using a capacity >4GB: The sd(7D) driver on solaris x86 has a bug when accessing a disk block >4GB on a device using a logical blocksize != DEV_BSIZE (i.e. CDROM and DVD media). Due to a 32bit int overflow, a disk address modulo 4GB is accessed. There's no workaround available. See the following message for more details about this bug: http://groups.yahoo.com/group/solarisonintel/message/22516 xine-lib-1.2/CREDITS0000644000175000017500000000437314647725151011712 0ustar memeexternal projects used in libxine and its plugins ================================================= This list is provided to give credit to the external project maintainers that their work is used in xine. It is also useful to track the versioning and see, which copy of an external lib needs updating and who (if anyone) is usually doing these updates (the word 'maintainer' is intentionally avoided here). project version mediator ----------------------------------------------------------------------- goom 2k4-0 gsm610 1.0.10 Mike Melanson liba52 0.7.4 libca 0.0.5 libdvdnav 0.1.10 Michael Roitzsch libfaad 2.6.1 Miguel Freitas libmad 0.15.1b Miguel Freitas libmpeg2 0.2.1 [*] libmpcdec 1.2.5 libxdg-basedir 0.1.3 Diego Pettenò nosefart 2.7-mls Mike Melanson tvtime 0.9.8.4 Miguel Freitas wine vidix cvs 6/03/05 James Stembridge ----------------------------------------------------------------------- [*] common question: lastest version of libmpeg2 is 0.3.1, why don't you update? the answer is not so simple. quoting libmpeg2.sf.net: "The old API [0.2.x] was not flexible enough for most users, as a result various projects (xine, mplayer etc...) ended up rewriting their own versions of decode.c." this is indeed true: in order to support a lot of dvd features, menus with still frames, closed caption decoding and better buffer management for xine it was needed to patch our libmpeg2 copy. of course we should always try not to "fork" external projects, but in the libmpeg2/xine case it is easy to see (from CVS logs) how long did it took to reach the stability point we have now. so, while targeting a stable libxine release, there is no hurry in updating libmpeg2 and this is not the trivial task as it might sound. note that we have also backported some fixes/improvements from libmpeg2 cvs (eg. motion vector clipping for broken streams). if you need any specific change or fix feel free to send us a patch or discuss the issue at xine-devel. update plan for libmpeg2: we should leave our patched libmpeg2 for hardware accelerated decoding (xvmc) only and use "libmpeg2new" (containing updated libmpeg2) for software decoding. xine-lib-1.2/lib/0000755000175000017500000000000014647725152011432 5ustar memexine-lib-1.2/lib/Makefile.common0000644000175000017500000000016314647725152014361 0ustar memeLIBXINEPOSIX=$(top_builddir)/lib/libxineposix.la $(LIBXINEPOSIX): $(MAKE) -C $(top_builddir)/lib libxineposix.la xine-lib-1.2/lib/timedlock.c0000644000175000017500000000200314647725152013544 0ustar meme#include "config.h" #include #define _x_min(a, b) ((a) < (b) ? (a) : (b)) int xine_private_pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abs_timeout) { int pthread_rc; struct timespec remaining, slept, ts; remaining = *abs_timeout; while ((pthread_rc = pthread_mutex_trylock(mutex)) == EBUSY) { ts.tv_sec = 0; ts.tv_nsec = (remaining.tv_sec > 0 ? 10000000 : _x_min(remaining.tv_nsec, 10000000)); nanosleep(&ts, &slept); ts.tv_nsec -= slept.tv_nsec; if (ts.tv_nsec <= remaining.tv_nsec) { remaining.tv_nsec -= ts.tv_nsec; } else { remaining.tv_sec--; remaining.tv_nsec = (1000000 - (ts.tv_nsec - remaining.tv_nsec)); } if (remaining.tv_sec < 0 || (!remaining.tv_sec && remaining.tv_nsec <= 0)) { return ETIMEDOUT; } } return pthread_rc; } xine-lib-1.2/lib/basename.c0000644000175000017500000000135314647725152013353 0ustar meme/* * get base name * * (adopted from sh-utils) */ #include "config.h" #define FILESYSTEM_PREFIX_LEN(filename) 0 #define ISSLASH(C) ((C) == '/') char *xine_private_basename(char *name) { char const *base = name + FILESYSTEM_PREFIX_LEN (name); char const *p; for (p = base; *p; p++) { if (ISSLASH (*p)) { /* Treat multiple adjacent slashes like a single slash. */ do p++; while (ISSLASH (*p)); /* If the file name ends in slash, use the trailing slash as the basename if no non-slashes have been found. */ if (! *p) { if (ISSLASH (*base)) base = p - 1; break; } /* *P is a non-slash preceded by a slash. */ base = p; } } return (char *)base; } xine-lib-1.2/lib/strlcat.c0000644000175000017500000000334214647725152013254 0ustar meme/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and 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. */ #include "config.h" #include #include /* * Appends src to string dst of size siz (unlike strncat, siz is the * full size of dst, not space left). At most siz-1 characters * will be copied. Always NUL terminates (unless siz <= strlen(dst)). * Returns strlen(src) + MIN(siz, strlen(initial dst)). * If retval >= siz, truncation occurred. */ size_t xine_private_strlcat(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; size_t dlen; /* Find the end of dst and adjust bytes left but don't go past end */ while (n-- != 0 && *d != '\0') d++; dlen = d - dst; n = siz - dlen; if (n == 0) return(dlen + strlen(s)); while (*s != '\0') { if (n != 1) { *d++ = *s; n--; } s++; } *d = '\0'; return(dlen + (s - src)); /* count does not include NUL */ } xine-lib-1.2/lib/swab.c0000644000175000017500000000214514647725152012534 0ustar meme/* * Copyright (C) 2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #include "config.h" #include #include #include void xine_private_swab(const void *from, void *to, ssize_t n) { const int16_t *in = (int16_t*)from; int16_t *out = (int16_t*)to; ssize_t i; n /= 2; for (i = 0 ; i < n; i++) { out[i] = bswap_16(in[i]); } } xine-lib-1.2/lib/Makefile.am0000644000175000017500000000035614647725152013472 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) EXTRA_DIST = Makefile.common noinst_LTLIBRARIES = libxineposix.la noinst_HEADERS = os_internal.h libxineposix_la_SOURCES = libxineposix_la_LIBADD = @LTLIBOBJS@ xine-lib-1.2/lib/memmem.c0000644000175000017500000000334114647725152013054 0ustar meme/* Copyright (C) 1991,92,93,94,96,97,98,2000,2004,2007 Free Software Foundation, Inc. This file is part of the GNU C Library. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include #include /* Return the first occurrence of NEEDLE in HAYSTACK. */ void *xine_private_memmem (const void *haystack, size_t haystack_len, const void *needle, size_t needle_len) { const char *begin; const char *const last_possible = (const char *) haystack + haystack_len - needle_len; if (needle_len == 0) /* The first occurrence of the empty string is deemed to occur at the beginning of the string. */ return (void *) haystack; /* Sanity check, otherwise the loop might search through the whole memory. */ if (haystack_len < needle_len) return NULL; for (begin = (const char *) haystack; begin <= last_possible; ++begin) if (begin[0] == ((const char *) needle)[0] && !memcmp ((const void *) &begin[1], (const void *) ((const char *) needle + 1), needle_len - 1)) return (void *) begin; return NULL; } xine-lib-1.2/lib/unsetenv.c0000644000175000017500000000015314647725152013444 0ustar meme#include "config.h" #include void xine_private_unsetenv(const char *name) { putenv(name); } xine-lib-1.2/lib/strpbrk.c0000644000175000017500000000042514647725152013266 0ustar meme#include /* Shamefully copied from glibc 2.2.3 */ char *xine_private_strpbrk(const char *s, const char *accept) { while(*s != '\0') { const char *a = accept; while(*a != '\0') if(*a++ == *s) return(char *) s; ++s; } return NULL; } xine-lib-1.2/lib/strlcpy.c0000644000175000017500000000732314647725152013303 0ustar meme/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * Permission to use, copy, modify, and 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. * * x86 asm version by Torsten Jager */ #include "config.h" #include #include /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. */ size_t xine_private_strlcpy(char *dst, const char *src, size_t siz) { #if defined(ARCH_X86) && (defined(__GNUC__) || defined(__clang__)) size_t a; #if defined(ARCH_X86_32) # define DO_P(what) what"l" # define REG_P(reg) "%"reg #elif defined(ARCH_X86_X32) # define DO_P(what) what"q" # define REG_P(reg) "%q"reg #else /* ARCH_X86_64 */ # define DO_P(what) what"q" # define REG_P(reg) "%"reg #endif __asm__ __volatile__ ( "cld" "\n\ttestl\t%%ecx, %%ecx" "\n\t"DO_P("mov")"\t"REG_P("0")", "REG_P("3") "\n\tje\t3f" "\n1:" "\n\ttestb\t$255, ("REG_P("0")")" "\n\tmovsb" "\n\tje\t4f" "\n\tsubl\t$1, %%ecx" "\n\tje\t2f" "\n\ttestb\t$255, ("REG_P("0")")" "\n\tmovsb" "\n\tje\t4f" "\n\tsubl\t$1, %%ecx" "\n\tjne\t1b" "\n2:" "\n\tmovb\t$0, -1("REG_P("1")")" "\n3:" "\n\ttestb\t$255, ("REG_P("0")")" "\n\t"DO_P("lea")"\t1("REG_P("0")"), "REG_P("0") "\n\tje\t4f" "\n\ttestb\t$255, ("REG_P("0")")" "\n\t"DO_P("lea")"\t1("REG_P("0")"), "REG_P("0") "\n\tjne\t3b" "\n4:" "\n\t"DO_P("neg")"\t"REG_P("3") "\n\t"DO_P("lea")"\t-1("REG_P("0")","REG_P("3")"), "REG_P("3") : "=S" (src), "=D" (dst), "=c" (siz), "=a" (a) : "0" (src), "1" (dst), "2" (siz) : "cc", "memory" ); return a; #else char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0) { while (--n != 0) { if ((*d++ = *s++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return(s - src - 1); /* count does not include NUL */ #endif } #ifdef TEST_THIS_FILE #include int main (void) { char b[128]; unsigned int u; u = xine_private_strlcpy (b, "wrong wrung wrang", 128); printf ("xine_private_strlcpy (b, \"wrong wrung wrang\", 128) = (\"%s\", %u)\n", b, u); u = xine_private_strlcpy (b, "wrong wrung wrang", 0); printf ("xine_private_strlcpy (b, \"wrong wrung wrang\", 0) = (\"%s\", %u)\n", b, u); u = xine_private_strlcpy (b, "wrong wrung wrang", 17); printf ("xine_private_strlcpy (b, \"wrong wrung wrang\", 17) = (\"%s\", %u)\n", b, u); u = xine_private_strlcpy (b, "wrong wrung wrang", 10); printf ("xine_private_strlcpy (b, \"wrong wrung wrang\", 10) = (\"%s\", %u)\n", b, u); u = xine_private_strlcpy (b, "wrong wrung wrang", 1); printf ("xine_private_strlcpy (b, \"wrong wrung wrang\", 1) = (\"%s\", %u)\n", b, u); return 0; } #endif xine-lib-1.2/lib/hstrerror.c0000644000175000017500000000105314647725152013627 0ustar meme#include "config.h" #ifdef WIN32 #include #else #include #endif #include #include "xine/xineintl.h" /** * get error descriptions in DNS lookups */ const char *xine_private_hstrerror(int err) { switch (err) { case 0: return _("No error"); case HOST_NOT_FOUND: return _("Unknown host"); case NO_DATA: return _("No address associated with name"); case NO_RECOVERY: return _("Unknown server error"); case TRY_AGAIN: return _("Host name lookup failure"); default: return _("Unknown error"); } } xine-lib-1.2/lib/gettimeofday.c0000644000175000017500000000112014647725152014251 0ustar meme/* replacement function of gettimeofday */ #include "config.h" #ifdef HAVE_POSIX_TIMERS # include #else # include #endif #ifdef WIN32 # include #else # include #endif int xine_private_gettimeofday(struct timeval *tv) { #ifdef HAVE_POSIX_TIMERS struct timespec *ts; int r; r = clock_gettime (CLOCK_REALTIME, &ts); if (!r) { tv->tv_sec = ts.tv_sec; tv->tv_usec = ts.tv_nsec / 1000; } return r; } #else struct timeb tp; ftime(&tp); tv->tv_sec = tp.time; tv->tv_usec = tp.millitm * 1000; return 0; #endif } xine-lib-1.2/lib/strcasestr.c0000644000175000017500000000421314647725152013773 0ustar meme/*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * 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 University 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. */ #include "config.h" #include #include #include /* * Find the first occurrence of find in s, ignore case. */ char * xine_private_strcasestr(const char *s, const char *find) { char c, sc; size_t len; if ((c = *find++) != 0) { c = tolower((unsigned char)c); len = strlen(find); do { do { if ((sc = *s++) == 0) return (NULL); } while ((char)tolower((unsigned char)sc) != c); } while (strncasecmp(s, find, len) != 0); s--; } return (char *)s; } xine-lib-1.2/lib/strndup.c0000644000175000017500000000400514647725152013274 0ustar meme/* $NetBSD: strndup.c,v 1.4 2007/07/03 12:11:09 nakayama Exp $ */ /* * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * Modified for xine project. * * 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 University 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. */ #include "config.h" #include #include #include char * xine_private_strndup(const char *str, size_t n) { size_t len; char *copy; if (!str) return (NULL); for (len = 0; len < n && str[len]; len++) continue; if (!(copy = malloc(len + 1))) return (NULL); memcpy(copy, str, len); copy[len] = '\0'; return (copy); } xine-lib-1.2/lib/strtok_r.c0000644000175000017500000000140514647725152013445 0ustar meme/* * written for xine project, 2004-2006 * * public domain replacement function for strtok_r() * */ #include "config.h" #include #include char *xine_private_strtok_r(char *s, const char *delim, char **ptrptr) { char *next; size_t toklen, cutlen; /* first or next call */ if (s) *ptrptr = s; else s = *ptrptr; /* end of searching */ if (!s || !*s) return NULL; /* cut the initial garbage */ cutlen = strspn(s, delim); s = s + cutlen; /* pointer before next token */ if ((toklen = strcspn(s, delim)) == 0) { *ptrptr = NULL; return NULL; } next = s + toklen; /* prepare next call */ *ptrptr = *next ? next + 1 : NULL; /* cut current token */ *next = '\0'; /* return the token */ return s; } xine-lib-1.2/lib/os_internal.h0000644000175000017500000002422614647725152014126 0ustar meme#ifndef _XINE_OS_INTERNAL_H #define _XINE_OS_INTERNAL_H /* When using Apple's GCC, __APPLE__ will be defined. This is a whole lot of * messiness, but it's necessary in order to perform universal builds properly. * It's meant to over-ride configure time stuff that would be different at * compile time. */ #if defined(__APPLE__) && defined(XINE_MACOSX_UNIVERSAL_BINARY) /* __ppc__, __ppc64__, __i386__, __x86_64__ are interesting arch macros */ #undef HOST_ARCH #if defined(__ppc__) || defined(__ppc64__) #define ARCH_PPC #if defined(__ppc64__) #define HOST_ARCH "darwin/powerpc64" #else #define HOST_ARCH "darwin/powerpc" #endif #elif defined(__i386__) || defined(__x86_64__) #define ARCH_X86 #define BITFIELD_LSBF #define HAVE_MMX #if defined(__x86_64__) #define ARCH_X86_64 #define HOST_ARCH "darwin/x86_64" #elif defined(__i386__) #define ARCH_X86_32 #define HOST_ARCH "darwin/x86_32" #else #error unrecognized/unsupported CPU type building for Apple Darwin #endif #endif /* See /Developer/SDKs/MacOSX10.4u.sdk/usr/include/machine/limits.h */ #if SIZEOF_INT != 4 #undef SIZEOF_INT #define SIZEOF_INT 4 #endif #if defined(__LP64__) && SIZEOF_LONG != 8 #undef SIZEOF_LONG #define SIZEOF_LONG 8 #elif !defined(__LP64__) && SIZEOF_LONG != 4 #undef SIZEOF_LONG #define SIZEOF_LONG 4 #endif /* WORDS_BIGENDIAN (replaces AC_C_BIGENDIAN autoconf test at compile time) */ #include #if BYTE_ORDER == BIG_ENDIAN #define WORDS_BIGENDIAN 1 #else #undef WORDS_BIGENDIAN #endif #if defined(__LP64__) #define FPM_64BIT 1 #elif defined(__ppc__) || defined(__ppc64__) #define FPM_PPC 1 #elif defined(__i386__) || defined(__x86_64__) #define FPM_INTEL 1 #endif #endif /* __APPLE__ */ #include #include #ifdef HAVE_SYS_PARAM_H # include #endif #ifdef HOST_OS_DARWIN /* Darwin (Mac OS X) needs __STDC_LIBRARY_SUPPORTED__ for SCNx64 and * SCNxMAX macros */ # ifndef __STDC_LIBRARY_SUPPORTED__ # define __STDC_LIBRARY_SUPPORTED__ # endif /* __STDC_LIBRARY_SUPPORTED__ */ #endif #if defined (__SVR4) && defined (__sun) # include #endif #include #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK #include #endif #include /* convenience */ #define snprintf_buf(buffer, ...) snprintf(buffer, sizeof(buffer), __VA_ARGS__) #if defined(WIN32) || defined(__CYGWIN__) # define XINE_PATH_SEPARATOR_STRING ";" # define XINE_PATH_SEPARATOR_CHAR ';' # define XINE_DIRECTORY_SEPARATOR_STRING "\\" # define XINE_DIRECTORY_SEPARATOR_CHAR '\\' #else # define XINE_PATH_SEPARATOR_STRING ":" # define XINE_PATH_SEPARATOR_CHAR ':' # define XINE_DIRECTORY_SEPARATOR_STRING "/" # define XINE_DIRECTORY_SEPARATOR_CHAR '/' #endif /* replacement of min/max macros */ #ifndef HAVE_MAX_MACRO #define MAX(a,b) (((a)>(b))?(a):(b)) #endif #ifndef HAVE_MIN_MACRO #define MIN(a,b) (((a)<(b))?(a):(b)) #endif #ifndef HAVE_STRLCAT #define HAVE_STRLCAT #define strlcat(D, S, N) xine_private_strlcat((D), (S), (N)) size_t xine_private_strlcat(char *dst, const char *src, size_t size); #endif #ifndef HAVE_STRLCPY #define HAVE_STRLCPY #define strlcpy(D, S, N) xine_private_strlcpy((D), (S), (N)) size_t xine_private_strlcpy(char *dst, const char *src, size_t size); #endif /* replacement of strndup */ #ifndef HAVE_STRNDUP #define HAVE_STRNDUP #define strndup(S, N) xine_private_strndup((S), (N)) char *xine_private_strndup(const char *s, size_t n); #endif /* replacement of basename */ #ifndef HAVE_BASENAME #define HAVE_BASENAME #define basename(PATH) xine_private_basename((PATH)) char *xine_private_basename(char *path); #endif /* replacement of hstrerror */ #ifndef HAVE_HSTRERROR #define HAVE_HSTRERROR #define hstrerror(ERR) xine_private_hstrerror((ERR)) const char *xine_private_hstrerror(int err); #endif /* replacement of setenv */ #ifndef HAVE_SETENV #define HAVE_SETENV #define setenv(NAME, VALUE, OVERWRITE) xine_private_setenv((NAME), (VALUE)) int xine_private_setenv(const char *name, const char *value); #endif /* replacement of strcasestr */ #ifndef HAVE_STRCASESTR #define HAVE_STRCASESTR #define strcasestr(HAYSTACK, NEEDLE) xine_private_strcasestr((HAYSTACK), (NEEDLE)) char *xine_private_strcasestr(const char *haystack, const char *needle); #endif /* replacement of strtok_r */ #ifndef HAVE_STRTOK_R #define HAVE_STRTOK_R #define strtok_r(S, DELIM, PTRPTR) xine_private_strtok_r((S), (DELIM), (PTRPTR)) char *xine_private_strtok_r(char *s, const char *delim, char **ptrptr); #endif #ifndef HAVE_SWAB #define HAVE_SWAB #define swab(A,B,C) xine_private_swab((A),(B),(C)) #include /* ssize_t */ void xine_private_swab(const void *from, void *to, ssize_t n); #endif /* replacement of gettimeofday */ #ifndef HAVE_GETTIMEOFDAY # define HAVE_GETTIMEOFDAY # ifdef WIN32 # include struct timezone; # else # include # endif # define gettimeofday(TV, TZ) xine_private_gettimeofday((TV)) int xine_private_gettimeofday(struct timeval *tv); #endif /* replacement of strpbrk */ #ifndef HAVE_STRPBRK #define HAVE_STRPBRK #define strpbrk(S, ACCEPT) xine_private_strpbrk((S), (ACCEPT)) char *xine_private_strpbrk(const char *s, const char *accept); #endif /* replacement of strsep */ #ifndef HAVE_STRSEP #define HAVE_STRSEP #define strsep(STRINGP, DELIM) xine_private_strsep((STRINGP), (DELIM)) char *xine_private_strsep(char **stringp, const char *delim); #endif /* replacement of timegm */ #ifndef HAVE_TIMEGM #define HAVE_TIMEGM #include #define timegm(TM) xine_private_timegm((TM)) time_t xine_private_timegm(struct tm *tm); #endif /* replacement of unsetenv */ #ifndef HAVE_UNSETENV #define HAVE_UNSETENV #define unsetenv(NAME) xine_private_unsetenv((NAME)) void xine_private_unsetenv(const char *name); #endif /* replacement of asprintf & vasprintf */ #ifndef HAVE_ASPRINTF #define HAVE_ASPRINTF #ifdef __GNUC__ #define asprintf(STRINGPP, FORMAT, ARGS...) xine_private_asprintf((STRINGPP), FORMAT, ##ARGS) #elif defined (_MSC_VER) #define asprintf(STRINGPP, FORMATARGS) xine_private_asprintf((STRINGPP), FORMATARGS) #else #define asprintf(STRINGPP, FORMAT, ...) xine_private_asprintf((STRINGPP), FORMAT, __VA_ARGS__) #endif #define vasprintf(STRINGPP, FORMAT, VA_ARG) xine_private_vasprintf((STRINGPP), (FORMAT), (VA_ARG)) int xine_private_asprintf(char **string, const char *format, ...) XINE_FORMAT_PRINTF(2, 3); int xine_private_vasprintf(char **string, const char *format, va_list ap) XINE_FORMAT_PRINTF(2, 0); #endif /* replacement of strndup */ #ifndef HAVE_STRNDUP #define HAVE_STRNDUP #define strndup(S, N) xine_private_strndup((S), (N)) char *xine_private_strndup(const char *s, size_t n); #endif /* replacement of pthread_mutex_timedlock */ #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK #define HAVE_PTHREAD_MUTEX_TIMEDLOCK #define pthread_mutex_timedlock(M, T) xine_private_pthread_mutex_timedlock((M), (T)) int xine_private_pthread_mutex_timedlock(pthread_mutex_t *mutex, const struct timespec *abs_timeout); #endif /* handle non-standard function names */ #if !defined(HAVE_SNPRINTF) && defined(HAVE__SNPRINTF) # define HAVE_SNPRINTF # define snprintf _snprintf #endif #if !defined(HAVE_VSNPRINTF) && defined(HAVE__VSNPRINTF) # define HAVE_VSNPRINTF # define vsnprintf _vsnprintf #endif #if !defined(HAVE_STRCASECMP) && defined(HAVE__STRICMP) # define HAVE_STRCASECMP # define strcasecmp _stricmp #endif #if !defined(HAVE_STRNCASECMP) && defined(HAVE__STRNICMP) # define HAVE_STRNCASECMP # define strncasecmp _strnicmp #endif #include #ifndef M_PI # define M_PI 3.14159265358979323846 #endif #ifdef WIN32 /* this hack applied only on attic version of MinGW platform */ # if !defined(va_copy) && !defined(HAVE_VA_COPY) # define va_copy(DEST, SRC) ((DEST) = (SRC)) # endif # include # ifdef _MSC_VER # include # endif # ifdef HAVE_SYS_STAT_H # include # endif # ifdef __MINGW64__ # define mkdir(A, B) mkdir((A)) # else # define mkdir(A, B) _mkdir((A)) # endif # ifndef S_ISDIR # define S_ISDIR(m) ((m) & _S_IFDIR) # endif # ifndef S_ISREG # define S_ISREG(m) ((m) & _S_IFREG) # endif # ifndef S_ISBLK # define S_ISBLK(m) 0 # endif # ifndef S_ISCHR # define S_ISCHR(m) 0 # endif # ifndef S_ISLNK # define S_ISLNK(mode) 0 # endif # ifndef S_ISSOCK # define S_ISSOCK(mode) 0 # endif # ifndef S_ISFIFO # define S_ISFIFO(mode) 0 # endif # ifndef S_IXUSR # define S_IXUSR S_IEXEC # endif # ifndef S_IXGRP # define S_IXGRP S_IEXEC # endif # ifndef S_IXOTH # define S_IXOTH S_IEXEC # endif # if !S_IXUGO # define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) # endif /* * workaround compatibility code due to 'near' and 'far' keywords in windef.h * (do it only inside ffmpeg) */ # ifdef HAVE_AV_CONFIG_H # include # ifdef near # undef near # endif # ifdef far # undef far # endif # ifdef frm1 # undef frm1 # endif /* it sucks everywhere :-) */ # define near win32_sucks_near # define far win32_sucks_far # endif /* av_config */ #endif #ifndef HAVE_READLINK # define readlink(PATH, BUF, BUFSIZE) 0 #endif /* replacing lstat by stat */ #ifndef HAVE_LSTAT # define HAVE_LSTAT # define lstat(FILENAME, BUF) stat((FILENAME), (BUF)) #endif /* replace llabs */ #ifndef HAVE_LLABS # define llabs(a) (((a) < 0) ? (-a) : (a)) #endif /* replacements of dirent for MSVC platform */ #ifndef HAVE_OPENDIR #define HAVE_OPENDIR typedef struct DIR DIR; struct dirent { unsigned short d_reclen; char *d_name; }; DIR *xine_private_opendir(const char *); int xine_private_closedir(DIR *); struct dirent *xine_private_readdir(DIR *); void xine_private_rewinddir(DIR *); #define opendir(DIRENT_NAME) xine_private_opendir((DIRENT_NAME)) #define closedir(DIRENT_DIR) xine_private_closedir((DIRENT_DIR)) #define readdir(DIRENT_DIR) xine_private_readdir((DIRENT_DIR)) #define rewinddir(DIRENT_DIR) xine_private_rewinddir((DIRENT_DIR)) #endif /* replacement of memmem */ #ifndef HAVE_MEMMEM #define HAVE_MEMMEM #define memmem(H, HL, N, NL) \ xine_private_memmem((H), (HL), (N), (NL)) void *xine_private_memmem (const void *haystack, size_t haystack_len, const void *needle, size_t needle_len); #endif #endif xine-lib-1.2/lib/asprintf.c0000644000175000017500000000307114647725152013425 0ustar meme/* * Copyright (C) 2006-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any * later version. * * xine is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #include "config.h" #include #include #include #include int xine_private_vasprintf (char **buffer, const char *format, va_list ap) { char *buf = NULL; int size = 128; for (;;) { int ret; va_list cp; char *newbuf = realloc (buf, size *= 2); if (!newbuf) { free (buf); return -1; } buf = newbuf; va_copy (cp, ap); ret = vsnprintf (buf, size, format, cp); va_end (cp); if (ret >= 0 && ret < size) { *buffer = realloc (buf, ret + 1); return ret; } } } int xine_private_asprintf (char **buffer, const char *format, ...) { int ret; va_list ap; va_start (ap, format); ret = xine_private_vasprintf (buffer, format, ap); va_end (ap); return ret; } xine-lib-1.2/lib/strsep.c0000644000175000017500000000476414647725152013131 0ustar meme/* $OpenBSD: strsep.c,v 1.6 2005/08/08 08:05:37 espie Exp $ */ /*- * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * * 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 University 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 REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. */ #include "config.h" #include #include /* * Get next token from string *stringp, where tokens are possibly-empty * strings separated by characters from delim. * * Writes NULs into the string at *stringp to end tokens. * delim need not remain constant from call to call. * On return, *stringp points past the last NUL written (if there might * be further tokens), or is NULL (if there are definitely no more tokens). * * If *stringp is NULL, strsep returns NULL. */ char * xine_private_strsep(char **stringp, const char *delim) { char *s; const char *spanp; int c, sc; char *tok; if ((s = *stringp) == NULL) return (NULL); for (tok = s;;) { c = *s++; spanp = delim; do { if ((sc = *spanp++) == c) { if (c == 0) s = NULL; else s[-1] = 0; *stringp = s; return (tok); } } while (sc != 0); } /* NOTREACHED */ } xine-lib-1.2/lib/timegm.c0000644000175000017500000000053614647725152013064 0ustar meme#include "config.h" #include #include time_t xine_private_timegm(struct tm *tm) { time_t ret; #if defined(HAVE_TZSET) char *tz; tz = getenv("TZ"); setenv("TZ", "", 1); tzset(); #endif ret = mktime(tm); #if defined(HAVE_TZSET) if (tz) setenv("TZ", tz, 1); else unsetenv("TZ"); tzset(); #endif return ret; } xine-lib-1.2/lib/setenv.c0000644000175000017500000000062214647725152013102 0ustar meme#include "config.h" #include #include #include /* This function will leak a small amount of memory */ int xine_private_setenv(const char *name, const char *val) { int len; char *env; len = strlen(name) + strlen(val) + 2; env = malloc(len); if (env != NULL) { snprintf(env, len, "%s=%s", name, val); putenv(env); return 0; } else return -1; } xine-lib-1.2/lib/dirent_msvc.c0000644000175000017500000000567014647725152014123 0ustar meme/* Implementation of POSIX directory browsing functions and types for Win32. Kevlin Henney (mailto:kevlin@acm.org), March 1997. Copyright Kevlin Henney, 1997. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose is hereby granted without fee, provided that this copyright and permissions notice appear in all copies and derivatives, and that no charge may be made for the software and its documentation except to cover cost of distribution. This software is supplied "as is" without express or implied warranty. But that said, if there are any problems please get in touch. */ #include "config.h" #include #include #include #include #ifndef DIR struct DIR { long handle; /* -1 for failed rewind */ struct _finddata_t info; struct dirent result; /* d_name null iff first time */ char *name; /* NTBS */ }; #endif DIR *xine_private_opendir(const char *name) { DIR *dir = 0; if(name && name[0]) { size_t base_length = strlen(name); const char *all = /* the root directory is a special case... */ strchr("/\\", name[base_length - 1]) ? "*" : "/*"; if((dir = (DIR *) malloc(sizeof *dir)) != 0 && (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) { strcat(strcpy(dir->name, name), all); if((dir->handle = _findfirst(dir->name, &dir->info)) != -1) { dir->result.d_name = 0; } else /* rollback */ { free(dir->name); free(dir); dir = 0; } } else /* rollback */ { free(dir); dir = 0; errno = ENOMEM; } } else { errno = EINVAL; } return dir; } int xine_private_closedir(DIR *dir) { int result = -1; if(dir) { if(dir->handle != -1) { result = _findclose(dir->handle); } free(dir->name); free(dir); } if(result == -1) /* map all errors to EBADF */ { errno = EBADF; } return result; } struct dirent *xine_private_readdir(DIR *dir) { struct dirent *result = 0; if(dir && dir->handle != -1) { if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { result = &dir->result; result->d_name = dir->info.name; result->d_reclen = strlen(dir->info.name); } } else { errno = EBADF; } return result; } void xine_private_rewinddir(DIR *dir) { if(dir && dir->handle != -1) { _findclose(dir->handle); dir->handle = _findfirst(dir->name, &dir->info); dir->result.d_name = 0; } else { errno = EBADF; } } xine-lib-1.2/po/0000755000175000017500000000000014647725152011302 5ustar memexine-lib-1.2/po/pt_BR.po0000644000175000017500000047727014647725152012671 0ustar meme# Portuguese (Brazilian) xine-lib.po file. # Copyright (C) 2002 Free Software Foundation, Inc. # Marcelo Roberto Jimenez , 2002 # msgid "" msgstr "" "Project-Id-Version: xine-lib 0.9.13\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2002-01-22 18:31GMT-3\n" "Last-Translator: Marcelo Roberto Jimenez \n" "Language-Team: Portuguese (Brazilian) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "X-Generator: KBabel 0.9.5\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #: lib/hstrerror.c msgid "No error" msgstr "" #: lib/hstrerror.c msgid "Unknown host" msgstr "" #: lib/hstrerror.c msgid "No address associated with name" msgstr "" #: lib/hstrerror.c msgid "Unknown server error" msgstr "" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "" #: lib/hstrerror.c msgid "Unknown error" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c msgid "Linear PCM audio decoder plugin" msgstr "" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "incapaz de alocar buffer de direct sound." #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "" #: src/audio_out/audio_fusionsound_out.c msgid "xine FusionSound audio output plugin" msgstr "" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr "" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" #: src/audio_out/audio_sndio_out.c msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/combined/flac_decoder.c msgid "flac audio decoder plugin" msgstr "" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c msgid "Speex audio decoder plugin" msgstr "" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c msgid "AIFF file demux plugin" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: o índice do avi está quebrado\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c msgid "CD Digital Audio demux plugin" msgstr "" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "xine: usando o plugin de demuxer >%s< para este MRL.\n" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: aviso: o cabeçalho de pes inidca que este stream pode " "estar encriptado (encryption mode %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: aviso: o cabeçalho de pes inidca que este stream pode " "estar encriptado (encryption mode %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c msgid "MPEG audio demux plugin" msgstr "" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c msgid "Id RoQ file demux plugin" msgstr "" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c msgid "SMJPEG file demux plugin" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c msgid "WAV file demux plugin" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" #: src/input/input_cdda.c msgid "query CDDB" msgstr "" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "" #: src/input/input_file.c msgid "file input plugin" msgstr "" #: src/input/input_file.c msgid "file browsing start location" msgstr "" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "" #: src/input/input_helper.c msgid "list hidden files" msgstr "" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: invalid http answer\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: http status not 2xx: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: content length = % bytes\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "" #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" #: src/input/input_mms.c msgid "MMS protocol" msgstr "" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "net input plugin tal como enviado com xine" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_nfs.c msgid "Network File System (NFS) input plugin" msgstr "" #: src/input/input_pnm.c #, fuzzy msgid "pnm streaming input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "" #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) falhou (multicast kernel?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "incapaz de resolver '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "incapaz de conectar com '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: não consigo criar um novo thread (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "RTP/UDP input plugin tal como enviado com xine" #: src/input/input_rtsp.c #, fuzzy msgid "rtsp streaming input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "input_rip: erro de leitura no input plugin\n" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "" #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "" #: src/input/input_v4l.c msgid "Adjusting..." msgstr "" #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l video device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: MRL mal formada. Use vcd://\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: trilha invalida %d (faixa valida: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "incapaz de abrir %s: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_dvd: incapaz de abrir o acionador de vcd (%s): %s\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "" #: src/input/multirate_pref.c msgid "Preferred video size" msgstr "" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred bitrate" msgstr "" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "" #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" #: src/libw32dll/qt_decoder.c msgid "quicktime audio decoder plugin" msgstr "" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr "" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: não consigo criar novo thread (%s)\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" #: src/video_out/video_out_mmal.c msgid "xine video output plugin using MMAL" msgstr "" #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "xine video output plugin using VAAPI" msgstr "" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr "" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio decoder plugin achado : %s\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "" #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out : desculpe, isto não deveria acontecer, reinicie o xine por " "favor.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: erro de leitura no input plugin\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: não consigo abrir o arquivo >%s<: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: não consigo abrir o plugin %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "" #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d quadros enviados, %d quadros pulados, %d quadros descartados\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out : descartando imagem com pts % porque é muito velha " "(diff : %).\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out : desculpe, isto não deveria acontecer, reinicie o xine por " "favor.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: não consigo achar um plugin para este MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine_play: demuxer %s falhou em começar\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine_play: demuxer %s falhou em começar\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "xine: não conseguí achar o demuxer %s para >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: não conseguí achar o demuxer para >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: usando o plugin de demuxer >%s< para este MRL.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine_play: demuxer falhou em começar\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: demuxer falhou em começar\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: demuxer falhou em começar\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: demuxer falhou em começar\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "menssagens" #: src/xine-engine/xine.c msgid "plugin" msgstr "plugin" #: src/xine-engine/xine.c msgid "trace" msgstr "" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "erro de leitura:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c msgid "Recording done:" msgstr "" #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: erro de leitura (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: incapaz de resolver '%s'.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: incapaz de conectar em '%s'.\n" xine-lib-1.2/po/it.po0000644000175000017500000073510114647725152012265 0ustar meme# translation of it.po to Italian # This file is distributed under the same license as the PACKAGE package. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. # # Giovanni Venturi , 2003. # Giovanni Venturi , 2003, 2004. # Diego 'Flameeyes' Pettenò , 2006. msgid "" msgstr "" "Project-Id-Version: it\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2007-12-24 16:09+0100\n" "Last-Translator: Diego 'Flameeyes' Pettenò \n" "Language-Team: Italian\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "X-Generator: KBabel 1.11.2\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/hstrerror.c msgid "No error" msgstr "Nessun errore" #: lib/hstrerror.c msgid "Unknown host" msgstr "Host sconosciuto" #: lib/hstrerror.c msgid "No address associated with name" msgstr "Nessun indirizzo associato con il nome" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Errore del server sconosciuto" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Errore nella ricerca dell'host" #: lib/hstrerror.c msgid "Unknown error" msgstr "Errore sconosciuto" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "dvaudio: aumentando il buffer a %d per evitare overflow.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "AIUTO! un driver audio solo mono?\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "volume A/52" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" "Con l'audio A/52 si può modificare il volume a livello di decoder. Questo ha " "il vantaggio che l'audio è già decodificato al volume specificato quindi le " "successive operazioni come il mixaggio dei canali funzioneranno su uno " "stream al volume richiesto." #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "usa la compressione dinamica A/52" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" "La compressione dinamica limita l'intervallo dell'audio. Questo singifica " "che rende i suoni forti morbidi e i suoni morbidi forti, in modo che si " "possa ascoltare più facilmente l'audio in un ambiente rumoroso senza " "disturbare." #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "declassa l'audio a due canali stereo surround" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" "Quando si vuole ascoltare un suono surround multicanale ma si hanno solo due " "speaker o un decodificatore o amplificatore surround che effettua una " "decodifica della matrice surround come prologic, si dovrebbe abilitare " "questa opzione in modo che i canali aggiuntivi sono mixati nel segnale " "stereo." #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() fallita.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 fallita.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit fallita.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "plugin di uscita audio per xine su file" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "libmusepack: mpc_demux_initialise fallita\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: mpc_streaminfo_read fallita: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: dati dopo l'ultimo frame ignorati.\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: mpc_decoder_initialise fallita\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: mpc_decoder_decode fallita: %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out: già aperto...PERCHÈ!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() di %s non riuscito: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>> controlla se un altro programma sta già usando PCM <<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: configurazione errata per questo PCM: nessuna configurazione " "disponibile: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "notifica modifiche al mixer hardware" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "Quando il mixer hardware viene cambiato, la propria applicazione riceverà " "una notifica così che possa aggiornare la propria rappresentazione delle " "impostazioni del mixer al volo." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : i modi supportati sono" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4-canali non abilitato nella configurazione di xine)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-canali" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-canali non abilitati nella configurazione di xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5-canali" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5-canali non abilitati nella configurazione di xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-canali non abilitati nella configurazione di xine)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr "" " (passaggio diretto a/52 e DTS non abilitato nella configurazione di xine)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() non riuscito:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>>Controlla se un altro programma sta già usando PCM <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8-bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16-bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24-bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32-bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "la scheda audio può usare mmap" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Si abiliti questa opzione se la propria scheda audio e il driver ALSA " "supportano l'IO mappato in memoria.\n" "Si può provare ad abilitarlo e vedere se funziona, in qual caso migliorerà " "le prestazioni." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "dispositivo usato per output mono" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilizzerà questo dispositivo ALSA per riprodurre suono mono.\n" "Si veda la documentazione ALSA per informazioni sui dispositivi." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " stereo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "dispositivo usato per output stereo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilizzerà questo dispositivo ALSA per riprodurre suono stereo.\n" "Si veda la documentazione ALSA per informazioni sui dispositivi." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-canali" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "dispositivo usato per output a 4 canali" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilizzerà questo dispositivo ALSA per riprodurre suono surround a 4 " "canali (4.0.\n" "Si veda la documentazione ALSA per informazioni sui dispositivi." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-canali" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "dispositivo usato per output a canale 5.1" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilizzerà questo dispositivo ALSA per riprodurre suono surround a 5 " "canali più RFE (5.1).\n" "Si veda la documentazione ALSA per informazioni sui dispositivi." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " passaggio diretto a/52 e DTS" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " passaggio diretto a/52 e DTS" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilizzerà questo dispositivo ALSA per riprodurre suono surround " "digitale non decodificato che può essere utilizzato da decodificatori " "surround esterni.\n" "Si veda la documentazione ALSA per informazioni sui dispositivi." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() non riuscita: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "dispositivo mixer di alsa" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilizzerà questo dispositivo del mixer ALSA per moidificare il " "volume.\n" "Si veda la documentazione ALSA per informazioni sui dispositivi." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" "plugin output audio di xine che usa i dispositivi/driver audio compiacenti " "di alsa" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "plugin di uscita audio per xine per Coreaudio/Max OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Errore" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "successo" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "accesso negato" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "risorsa già in uso" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "oggetto già inizializzato" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "il formato d'onda specificato non è supportato" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "il buffer in memoria è stato perso e deve essere ripristinato" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "il controllo del buffer richiesto non è disponibile" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "errore non determinato nel sistema DirectSound" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "il dispositivo hardware DirectSound non è disponibile" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "la funzione non è valida per l'attuale stato dell'oggetto" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "parametro passato non valido" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "l'oggetto non supporta aggregazione" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "nessun driver sonoro disponibile all'uso" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "l'interfaccia COM richiesta non è disponibile" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "un'altra applicazione ha un livello di priorità maggiore" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "memoria insufficiente" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "basso livello di priorità per questa funzione" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound non inizializzato" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "la funzione non è supportata" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "errore sconosciuto" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Impossibile creare l'oggetto DirectSound." #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "Impossibile impostare il livello cooperativo DirectSound." #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "Impossibile creare il buffer DirectSound secondario." #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "Impossibile riprodurre il buffer sonoro" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "Impossibile fermare il buffer sonoro" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "Impossibile leggere la posizione del buffer" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "Impossibile impostare la posizione del buffer" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "Impossibile impostare il volume sonoro" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": buffer perso, provando a recuperare\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "Impossibile bloccare il buffer DirectSound" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "Impossibile sbloccare il buffer DirectSound" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Impossibile creare il buffer DirectSound primario." #: src/audio_out/audio_directx2_out.c #, fuzzy, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" ": il cursore di riproduzione è uscito dai limiti (data %u, min %u), " "svuotamento dei buffer.\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": impossibile creare il buffer pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": impossibile cancellare il buffer pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ": impossibile cancellare la condizione pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": impossibile cancellare il mutex pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "; comando di controllo sconosciuto %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": impossibile creare la condizione pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": impossibile creare il mutex pthread: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "secondo plugin di uscita audio per xine utilizzante directx" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "plugin output audio di xine che usa directx per win32" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: si sta connettendo al server ESD %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: si sta connettendo al server ESD...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: impossibile connettersi al %s server ESD: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "latenza di output per l'audio esd (aggiusta a/v sync)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Se si nota l'audio non in sincronia con il video si può inserire un offset " "fisso per compensarlo.\n" "L'unità di valore è un \"PTS tick\" ovvero 1/90000 secondi." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "pluging output audio di xine che usa esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "plugin di uscita audio per xine su file" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "plugin di uscita audio per xine su file" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "lunghezza massima dei salti per il plugin di uscita audio irixal" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Si può specificare la massima distranza tra audio e video che xine tollererà " "prima di provare a rimetterli in sincronia.\n" "L'unità di questo valore è un \"PTS tick\", che è 1/90000 secondi." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "plugin di uscita audio per xine utilizzante libaudio IRIX" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "nome dispositivo audio JACK" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "plugin di uscita audio per xine per JACK Audio Connection Kit" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "pluging output audio dummy di xine" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: si sta aprendo il dispositivo audio %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: attenzione: tasso di campionamento %d Hz non supportato, si " "prova a 44100 Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "audio_oss_out: tasso audio: %d richiesto, %d fornito dal dispositivo\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "nome dispositivo audio OSS" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "Specifica la parte base del nome del dispositivo audio a cui viene postfisso " "il numero di dispositivo per ricavare il nome completo del dispositivo.\n" "Selezionate \"auto\" se si vuole l'auto riconoscimento dell'impostazione " "corretta." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "numero del dispositivo audio OSS, -1 per nessun dispositivo" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Il nome completo del dispositivo audio è creato concatenando il nome del " "dispositivo OSS e il numero del dispositivo audio.\n" "Se non si ha bisogno di un numero perché si è a posto con il dispositivo " "audio predefinito del proprio sistema, lo si imposti a -1.\n" "L'intevallo di questo valore è -1 oppure 0-15. Questa impostazione è " "ignorata quando il nome del dispositivo audio OSS è settato a \"auto\"." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "audio_oss_out: audio.device.oss_device_name = auto, si provano i dev\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "" "audio_oss_out: controllo automatico per il dispositivo audio non riuscito\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: si sta utilizzando il dispositivo >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: apertura dispositivo audio %s non riuscito:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "metodo di sincronia audio/video da usare con OSS" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "xine può utilizzare diversi metodi per tenere audio e video sincronizzati. " "Quale impostazione funzioni meglio dipende dal driver OSS e dall'hardware " "sonoro che si sta utilizzando. Si provino i vari metodi se si notano " "problemi di sincronia.\n" "\n" "Il significato dei valori è il seguente:\n" "\n" "auto\n" "xine tenterà di riconoscere automaticamente l'impostazione ottimale.\n" "\n" "getodelay\n" "utilizza l'ioctl SNDCTL_DSP_GETOPTR per raggiungere la vera sincronia a/v " "anche se il driver dice di non supportare la riproduzione a tempo reale.\n" "\n" "getoptr\n" "utilizza l'ioctl SNDCTL_DSP_GETOPTR per raggiungere la vera sincronia a/v " "anche se il driver supporta il preferibile SNDCTL_DSP_GETODELAY.\n" "\n" "softsync\n" "utilizza la sincronizzazione software con l'orologio di sistema; audio e " "video possono andare fuori sincronia se la velocità dell'orologio di sistema " "non corrisponde esattamente alla velocità di riproduzione della propria " "scheda audio.\n" "\n" "probebuffer\n" "controlla la dimensione del buffer della scheda audio all'avvio per " "calcolare la latenza per la sincronia a/v; si provi questo se il proprio " "sistema non supporta nessuna delle ioctl in tempo reale e si notano problemi " "di sincronia dopo una lunga riproduzione." #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: driver audio con sincronizzazione real time disabilitata...\n" "audio_oss_out: ... invece userà un sistema real-time con orologio per " "sincronizzazione soft\n" "audio_oss_out: ... potrebbe essereci sincronizzazione audio/video\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "latenza nell'uscita audio OSS (calibra sincronia audio/video)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: driver audio real time con sincronizzazione disabilitato...\n" "audio_oss_out: ...si sta provando la dimensione del buffer di output: %d " "byte\n" "audio_oss_out: ... potrebbe essereci sincronizzazione audio/video\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: i modi supportati sono" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " passaggio diretto a/52" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (passaggio diretto a/52 non abilitato nella configurazione di xine)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "Numero del mixer audio OSS, -1 per nessuno." #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Il nome completo del dispositivo mixer è creato prendendo il nome del " "dispositivo OSS, sostituendo \"dsp\" con \"mixer\" e aggiungendo il numero " "del mixer. Se non si ha bisogno di un numero perché si è a posto con il " "proprio dispositivo di mixing predefinito, si imposti a -1.\n" "L'intervallo di questo valore è -1 o 0-15, questa impostazione è ignorata " "quando il nome del dispositivo audio OSS è settato a \"auto\".s" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: open() del mixer %s non riuscita: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" "plugin output audio di xine che usa i dispositivi/driver audio compiacenti " "di oss" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "dispositivo utilizzato per PulseAudio" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" "Si usi 'server[:sink]' per impostare il dispositivo sink di PulseAudio." #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " passaggio diretto a/52" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "plugin di output audio di xine che usa il server sonoro PulseAudio" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" "plugin output audio di xine che usa i dispositivi/driver audio compiacenti " "di sun" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: apertura dispositivo audio %s non riuscita: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "nome dispositivo audio Sun" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Specifica il nome di file per il dispositivo audio Sun da utilizzare.\n" "Questa impostazione è critica, perché quando cambiato ad un file diverso, " "xine può essere utilizzato per riempire tale file con contenuto arbitrario, " "quindi si deve essere attenti che il valore inserito sia davvero un " "dispositivo audio Sun." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "audio_sun_out: ioctl sul dispositivo %s non riuscita: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" "plugin output audio di xine che usa i dispositivi/driver audio compiacenti " "di sun" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "disposizione degli speaker" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Selezionate come sono disposti gli speaker, questo determinerà quali speaker " "xine utilizzerà per l'uscita sonora. I singoli valori sono:\n" "\n" "Mono 1.0: solo uno speaker.\n" "Stereo 2.0: due speaker per i canali destro e sinistro.\n" "Headphones 2.0: cuffie.\n" "Stereo 2.1: due speaker per i canali destro e sinistro e un subwoofer per le " "basse frequenze.\n" "Surround 3.0: tre speaker per i canali destro sinistro e retrostante.\n" "Surround 4.0: quattro speaker per i canali destro e sinistro frontali e " "retrostanti.\n" "Surround 4.1: quattro speaker per i canali destro e sinistro frontali e " "retrostanti e un subwoofer per le basse frequenze.\n" "Surround 5.0: cinque speaker per i canali destro e sinistro frontali e " "retrostanti e centrale frontale. \n" "Surround 5.1: cinque speaker per i canali destro e sinistro frontali e " "retrostanti e centrale frontale e un subwoofer per le basse frequenze. \n" "Surround 6.0: sei speaker per i canali destro, sinistro e centrale frontali " "e retrostanti. \n" "Surround 6.1: sei speaker per i canali destro, sinistro e centrale frontali " "e retrostanti e un subwoofer per le basse frequenze. \n" "Surround 7.1: sette speaker per i canali destro sinistro e centrale " "frontali, destro e sinistro, destro sinistro retrostante e un subwoofer per " "le basse frequenze.\n" "Pass Through: il proprio sistema sonoro riceverà il suono digitale non " "decodificato da xine, si deve connettere all'uscita digitale della propria " "scheda audio un decodificatore surround digitale capace di decodificare i " "formati che si vogliono riprodurre." #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "plugin di input del file" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_audio_dec: aumentando il buffer a %d per evitare overflow.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_audio_dec: impossibile trovare il decoder ffmpeg per il tipo di " "buffer 0x%X\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: provando ad aprire un codec nullo.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: impossibile aprire il decoder.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" "ffmpeg_video_dec: dimensioni del frame non supportate. DR1 disabilitato.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: formato frame non supportato, DR1 disabilitato.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: visualizzazione diretta abilitata\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "ffmpeg_video_dec: formato frame non supportato, DR1 disabilitato.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: impossibile aprire il decoder\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: impossibile aprire il decoder (2)\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_video_dec: buffer aumentato a %d per evitare overflow.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: formato frame non supportato, DR1 disabilitato.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_video_dec: impossibile trovare il decoder ffmpeg per il tipo di " "buffer 0x%X\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "qualità di post-elaborazione MPEG-4" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "Si può tarare la quantità di post elaborazione applicata ai video MPEG-4.\n" "Valori più alti risultano in qualità migliore ma richiedono più CPU. Valroi " "più bassi possono risultare in difetti dell'immagine come artefatti. Per unc " "otnenuto ad alta qualità, una post elaborazione troppo alta può in realtà " "rendere l'immagine peggiore sfocandola troppo." #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "Numero di thread di decodifica FFmpeg" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Puoi impostare il numero di thread di decodifica che FFMpeg può usare.\n" "Valori più alti dovrebbero renere più veloce la decodifica, ma il supporto " "alla decodifica parallela dipende dal codec utilizzato. Una buona regola " "pratica è di avere un thread di decodifica per ogni CPU virtuale " "(tipicamente da 1 a 4). La modifica avrà effetto alla riproduzione del " "prossimo flusso." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "abilita doppio buffering" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "plugin di ingresso radio V4L" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "plugin di uscita audio per xine su file" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: indicata traccia audio vorbis ma nessuno stream di intestazione vorbis " "trovato.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "plugin di uscita audio per xine su file" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: aumentando il buffer a %d per evitare overflow.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "plugin di input del file" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: attenzione: L'id dello stream =%d è cifrato.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Stream multimediale confuso/cifrato" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Ripristino indice..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" "demux_avi: parte di avi non valida \"%c%c%c%c\" alla posizione %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: l'indice avi è interrotto\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" "demux_avi: riposizionamento alla successiva parte fallito (pos %)\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "plugin di input per DVB (TV Digitale)" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "dimensione di parte di FILM non valida\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "parte di FILM non roconosciuta\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, fuzzy, c-format msgid "unsupported FLV version (%d).\n" msgstr "Versione FLV non supportata (%d).\n" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "Non ci sono flussi audio o video in questo file.\n" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: compressione sconosciuta: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: compressione sconosciuta: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: pezzo sconosciuto: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "plugin di input del file" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: frame troppo grande per il buffer" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: stream_id 0x%02x sconosciuto. Segnala la cosa " "agli sviluppatori di xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: errore di deallocazione. Segnala la cosa agli sviluppatori " "di xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: attenzione: l'intestazione PES ha riservato 10 bit non " "trovati\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: attenzione: l'intestazione PES indica che questo stream " "può essere cifrato (modalità di cifratura %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "plugin di input per lo stream pnm" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: stream_id 0x%02x sconosciuto. Segnala la cosa agli " "sviluppatori di.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: attenzione: lo stream PACK con id=0x%x non è riuscito nella " "decodifica.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: attenzione: l'intestazione PES ha riservato 10 bit non " "trovati\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: attenzione: l'intestazione PES indica che questo stream " "può essere cifrato (modalità di cifratura %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes: stream 1 0x%02x privato sconosciuto. Segnala la cosa agli " "sviluppatori di xine.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "plugin di ingresso radio V4L" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c #, fuzzy msgid "Playlist demux plugin" msgstr "plugin di input del BluRay" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "plugin di input del file" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "plugin di input del file" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: paramentri intestazione errati\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: tipo audio non supportato: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "demux_tta: numero di frame totali troppo alto\n" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "tipo di blocco VOC sconosciuto (0x%02X); per favore riporta l'errore ai " "sviluppatori di xine\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "tipo di compressione VOC sconosciuta (0x%02X); per favore riporta l'errore " "ai sviluppatori di xine\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "plugin di input del file" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" "demux_wc3movie: parte di SHOT di riferimento con palette non valida (%d >= %" "d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" "demux_wc3movie: Si è verificato un problema durante il caricamento di un " "grossi pezzi di palette\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: apertura dispositivo SPU %s non riuscita (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_video: scrittura sul dispositivo video non riuscita (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "pulsante richiesto non disponibile\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" "dxr3_decode_video: apertura dispositivo di controllo %s non riuscita (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "usa informazioni Pan & Scan" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Pan & Scan\" è una modalità di visualizzazione specifica che viene " "talvolta utilizzata nel materiale codificato MPEG. Si può qui specificare " "come gestire tale contenuto.\n" "\n" "only when forced\n" "Utilizza Pan & Scans olamente quando il contenuto riprodotto lo richiede.\n" "\n" "use MPEG hint\n" "Abilita Pan & Scan basandosi sulle informazioni integrate nel flusso video " "MPEG.\n" "\n" "use DVB hint\n" "Abilita Pan & Scan basandosi sulle informazioni integrate nei flussi DVB. " "Questo utilizza il Descrittore di Formato Attivo (AFD) utilizzato in alcuni " "canali DVB europei." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "prova a sincronizzare il video ogni frame" #: src/dxr3/dxr3_decode_video.c #, fuzzy msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" "Pova ad impostare un tempo di sincronizzazione per ogni frame. Solitamente " "questo non è necessario perché la sincronia è sufficiente anche solo quando " "si inserisce un tempo una volta ogni tanto.\n" "È relativo solamente ai video progressivi (la maggior parte dei film PAL)." #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "utilizza modalità di riproduzione liscia" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "" "Abilitando questa opzione si utilizzerà un modo di riproduzione più definito." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "correggi la durata dei frame su flussi rovinati" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" "Abilita una piccola logica che corregge la durata dei frame su alcuni flussi " "MPEG con codici di framerate errati. Al momento è implementata una " "correzione per i flussi NTSC erroneamente etichettati come flussi PAL. Si " "abiliti solo quando si incontrano tali flussi." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: apertura dispositivo video %s non riuscita (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" "dxr3_decode_video: scrittura al dispositivo potrebbe bloccherebbe " "svuotamento\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: scrittura sul dispositivo video non riuscita (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "dxr3_decode_video: ATTENZIONE: codice tasso frame sconosciuto %d\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: ATTENZIONE: si sta correggendo il codice tasso frame da " "PAL a NTSC\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "Numero del dispositivo DXR3" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Se si ha più di un dispositivo DXR3 nel proprio computer si può specificare " "quale utilizzare." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: inizializzazione librte non riuscita\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte gestisce solo le dimensioni video che sono multiple " "di 16\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: rilevazione contesto rte non riuscito.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: impossibile creare codec.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "bitrate dell'output MPEG rte (kbit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "Il bitrate che la libreria librte di codifica MPEG utilizzerà per la " "modalità di codifica DXR3. Valori più alti aumenteranno la qualità e " "l'utilizzo di CPU." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: impossibile inizializzare contesto: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: impossibile avviare codifica: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: impossibile avviare la libreria FAME\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "qualità della codifica MPEG di fame" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "La qualità di codifica del codificatore MPEG di libfame. Più bassa è più " "veloce ma fornisce artifatti visibili, più alta è migliore ma più lenta." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "Priorità del plugin SCR" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" "Priorita del plugin SCR DXR3. Valori inferiori a 5 significano che sarà " "utilizzato il timer di sistema Unix, valori maggiori forzeranno l'uso " "dell'orologio interno della DXR3 come sorgente di sincronia a/v." #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "bitrate MPEG di uscita per libavcodec (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" "La bitrate utilizzata dal codificatore MPEG libavcodec per la modalità di " "codifica DXR3. Valori più alti aumenteranno la qualità e l'uso di CPU.\n" "Questa impostazione è considerata solo quando è disabilitata la modalità a " "qualità costante. " #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "modalità a qualità costante" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" "Se abilitata libavcodec utilizzerà una modalità a qualità costante " "comprimendo le immagini a secodna della loro complessità. Quando " "disabilitata libavcodec utilizzerà una modalità a bitrate costante." #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "compressione minima" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" "La compressione minima da applicare ad un'immagine utilizzando una modalità " "a qualità costante." #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "quantizzatore massimo" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" "La compressione massima da applicare ad un'immagine utilizzando una modalità " "a qualità costante." #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "" "video_out_dxr3: apertura dispositivo di controllo %s non riuscita (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "scambio linee spaiate e piatte" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" "Scambia i campi pari e dispari dell'immagine.\n" "Abilitate questa opzione per materiale non-MPEG che produce sporcizia " "verticale sullo schermo." #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "Aggiungi barre nere per correggere le proporzioni" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Aggiunge delle barre nere quando l'immagine ha una proporzione che la scheda " "non può gestire nativamente. Questo è necessario per mantenere le giuste " "proporzioni dell'immagine." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "" "usa modalità di riproduzione lisca per la riproduzione tramite encoder mpeg" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Abilitando questa opzione si utilizzerà una modalità di riproduzione più " "liscia per contenuto non-MPEG." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: apertura dispositivo video %s non riuscita (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "codificatore per contenuto non-MPEG" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "Contenuto diverso da MPEG deve passare uno stadio di ricodifica aggiuntivo, " "poiché DXR3 gestisce solo MPEG.\n" "A seconda di cosa è supportato dal proprio xine, questa impostazione può " "essere \"fame\", \"rte\", \"libavcodec\" o \"none\".\n" "Il codificatore \"libavcodec\" utilizza il plugin ffmpeg che viene già " "fornito con xine, quindi non si ha bisogno di alcuna libreria addizionale " "per questo, ancora meglio, libacodec fornisce alta qualità con un basso " "utilizzo di CPU. L'utilizzo di \"libavcodec\" è dunque altamente suggerito.\n" "\"fame\" e \"rte\" sono ancora lì, ma il loro supporto in xine è obsoleto, " "quindi questi potrebbero non funzionare." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" "video_out_dxr3: inizializzazione encoder MPEG libavcodec non riuscita.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: inizializzazione encoder MPEG rte non riuscita.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: inizializzazione encoder MPEG fame non riuscita.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: codifica MPEG disabilitata.\n" "video_out_dxr3: non c'è bisogno di questo per video MPEG come DVD, ma\n" "video_out_dxr3: non sarà possibile riprodurre contenuto non-MPEG con questo " "driver\n" "video_out_dxr3: di uscita video. Si veda README.dxr3 per dettagli sulla " "configurazione di un codificatore.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: nessun codificatore MPEG compilato.\n" "video_out_dxr3: non c'è bisogno di questo per video MPEG come DVD, ma\n" "video_out_dxr3: non sarà possibile riprodurre contenuto non-MPEG con questo " "driver\n" "video_out_dxr3: di uscita video. Si veda README.dxr3 per dettagli sulla " "configurazione di un codificatore.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "modalità di visualizzazione (TV oppure overlay)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" "Il modo in cui la DXR3 visualizzerà il video finale può essere impostato " "qui. I singoli valori sono: \n" "\n" "letterboxed tv\n" "Invia il video solamente al connettore di uscita TV. Questa è la modalità " "usata per i normali televisori 4:3. Il video anamorfico (16:9) sarà " "visualizzato in una scatola, il materiale pan&scan avrà l'immagine tagliata " "ai lati. Questa è l'impostazione comune per la visione TV e agisce come un " "lettore DVD autosufficiente.\n" "\n" "widescreen tv\n" "Invia il video solamente al connettore di uscita TV. Questa modalità è " "pensata per i televisori a schermo panoramico 16:9. Il contenuto anamorfico " "e pan&scan riempirà l'intero schermo, ma si dovrà impostare la proporzione " "delle immagini a 16:9 manualmente.\n" "\n" "letterboxed overlay\n" "Sovraimprimi il video sullo schermo del computer con l'opzione di scambiare " "al volo all'uscita TV nascondendo la finestra video. L'overlay sarà " "visualizzato con bordi neri se è anamorfico (16:9).\n" "Questa impostazione è utile solamente nei rari casi in cui il canale " "sottotitoli di un DVD si visualizzi solamente utilizzando la modalità " "letterbox. Un buon esempio di questo sono le ombre animate dei commentatori " "su \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Sovraimprimi il video sullo schermo con l'opzione di scambiare al volo " "all'uscita TV nascondendo la finestra video. Questa è la variante comune " "dell'overlay DXR3." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "valore della chiave cromatica di sovraimpressione" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Valore esadecimale RGB della chiave cromatica.\n" "Si possono provare provare valori diversi se si riscontrano finestre " "trasparenti quando si utilizza la modalità overlay DXR3. " #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "tolleranza della chiave cromatica di sovraimpressione" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" "Un valore più alto aumenta la tolleranza per la chiave cromatica di " "sovraimpressione.\n" "Si possono provare valori più bassi se si riscontrano finestre trasparenti " "quando si utilizza la modalità overlay DXR3, ma alcune parti dei bordi " "dell'immagine potrebbero sparire se si utilizza un valore troppo basso." #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "taglia l'area overlay nelle parti superiore e inferiore" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Rimuove una linea di pixel dai margini superiore e inferioriore " "dell'overlay. Si abiliti questo se si vedono linee verdi sopra o sotto " "l'immagine." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: autocalibrazione necessaria, overlay disabilitato.\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "modalità TV preferita" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Seleziona la modalità TV da utilizzare con il DXR3. I valori significano:\n" "\n" "ntsc: NTSC a 60Hz\n" "pal: PAL a 50Hz\n" "pal60: PAL a 60Hz\n" "default: mantieni l'impostazione della scheda" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: impostazione della modalità video fallita.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: è necessario un codificatore MPEG per riprodurre video non-" "MPEG su DXR3.\n" "video_out_dxr3: Si legga README.dxr3 per dettagli.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: ERRORE leggendo il file di inizializzazione dell'overlay. Si " "esegua l'autocalibrazione.\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "plugin di input del BluRay" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "dispositivo utilizzato per la riproduzione BluRay" #: src/input/input_bluray.c #, fuzzy msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "Il percorso al dispositivo, solitamente un lettore BluRay, che si intende " "usare per riprodurre BluRay." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "lingua predefinita per la riproduzione BluRay" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" "xine proverà ad usare questa lingua come predefinita per la riproduzione " "BluRay. Finché il BluRay la supporta, menu e tracce audio saranno presentate " "in questa lingua.\n" "Questo valore deve essere un codice di lingua di tre caratteri ISO639-2." #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" "Questa impostazione necessita di essere cambiata solo se il proprio BluRay " "salta ad uno schermo lamentandosi di un codice regionale errato. Non ha " "nulla a che vedere con il codice regionale settato nei lettori BluRay, è " "interamente software." #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "unità per l'azione di salto" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: impossibile connettersi a %s: %d\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: connesso al server CDDB %s:%d con successo.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "input_cdda: connessione al server CDDB '%s:%d' non riuscita (%s).\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "CD Audio (CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "dispositivo utilizzato per CD audio" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "Il percorso al dispositivo, solitamente un lettore CD o DVD, che si intende " "utilizzare per riprodurre CD audio." #: src/input/input_cdda.c msgid "query CDDB" msgstr "interroga CDDB" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" "Abilita le interrogazioni CDDB, che forniranno titoli e nomi di tracce " "adatte per i propri CD audio.\n" "Si tenga in mente che a meno che non si usi un proprio CDDB privato queste " "informazioni sono ricercate su un server internet che può raccogliere un " "profilo delle proprie abitudini d'ascolto." #: src/input/input_cdda.c msgid "CDDB server name" msgstr "nome del server CDDB" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" "Il server CDDB da utilizzare per recuperare titoli e tracce.\n" "Questa impostazione è critica, perché il server riceverà informazioni sulle " "proprie abitudini d'ascolto e potrebbe rispondere alle interrogazioni con " "risposte maliziose. Assicuratevi di inserire un server di cui ci si possa " "fidare." #: src/input/input_cdda.c msgid "CDDB server port" msgstr "porta del server CDDB" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "La porta del server utilizzato per recuperare titoli e tracce." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "rallenta il lettore dischi a questa velocità" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" "Poiché alcuni lettori CD o DVD sono molto rumorosi a causa dell'alta " "velocità di rotazione del disco, xine proverà a rallentarli. Con la normale " "riproduzione CD o DVD le alte velocità di trasferimento dati che richiedono " "la rotazione veloce non sono necessarie, quindi il rallentamento non " "dovrebbe influenzare le prestazioni di riproduzione.\n" "Un valore pari a zero disabilita il rallentamento." #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "input_dvb: apertura file canali DVB non riuscita '%s': %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "input_dvb: il file canali '%s' non è un file di testo semplice\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: tuner_set_channel non riuscito\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: impossibile aprire dispositivo DVB\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" "input_dvb: canale %d fuori scala, sarà utilizzato il valore predefinito 0\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: ricerca del canale %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" "input_dvb: corrispondenza esatta per %s non trovata: saranno provate le " "corrispondenze parziali.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: trovato canale corrispondente %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" "input_dvb: canale %s non trovato in channels.conf, sarà utilizzata un " "predefinito.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" "input_dvb: specifica del canale non valida, sarà utilizzato l'ultimo canale " "visto.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" "input_dvb: specifica del canale non valida, sarà utilizzato il canale " "predefinito 0.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" "input_dvb: è stato specificato un MRL DVB-S, ma il sintonizzatore non pare " "essere QPSK (DVB-S)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: è stato specificato un MRL DVB-T ma il sintonizzatore non pare " "essere OFDM (DVB-T)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: è stato specificato un MRL DVB-C ma il sintonizzatore non pare " "essere QAM (DVB-C)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" "input_dvb: è stato specificato un MRL DVB-A ma il sintonizzatore non pare " "essere ATSC (DVB-C)\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: impossibile aprire dispositivo DVR '%s'\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "input_dvb: impossibile creare thread di aggiornamento EPG.\n" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "usa il 'taglio centrale' DVB (zoom)" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Questo permetterà la riproduzione a pieno schermo di contenuto 4:3 trasmesso " "in un frame 16:9." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "plugin di input per DVB (TV Digitale)" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Ricorda l'ultimo canale DVB visto." #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" "Durante l'auto riproduzione xine ricorderà e scambierà al canale indicato in " "media.dvb.last_channel ." #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Ultimo canale DVB visto" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "Se abilitato xine ricorderà e scambierà a questo canale." #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "Numero di secondi prima dell'interruzione della sintonizzazione." #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" "Lasciandolo a 0 proverà all'infinito. Un valore maggiore a 0 significa " "attendi quei secondi per ricevere il controllo. Il minimo è di 5 secondi." #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Indice di scheda DVB da utilizzare." #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" "Lasciare questo a zero a meno che non si abbia davvero più di una scheda nel " "proprio sistema." #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "input_dvd: values of \\beta will give rise to dom!\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Errore nella lettura del prossimo blocco dal DVD (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Errore di apertura del dispositivo DVD\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "dispositivo utilizzato per la riproduzione DVD" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "Il percorso al dispositivo, solitamente un lettore DVD, che si intende usare " "per riprodurre DVD." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "Metodo di decifratura CSS" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" "Seleziona il metodo di decifratura che libdvdcss utilizzerà per decifrare i " "DVD protetti da copia. Si provino i vari metodi se si hanno problemi nella " "riproduzione di DVD cifrati." #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "regione a cui il lettore DVD dirà di appartenere (da 1 a 8)" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "Questa impostazione necessita di essere cambiata solo se il proprio DVD " "salta ad uno schermo lamentandosi di un codice regionale errato. Non ha " "nulla a che vedere con il codice regionale settato nei lettori DVD, è " "interamente software." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "lingua predefinita per la riproduzione DVD" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine proverà ad usare questa lingua come predefinita per la riproduzione " "DVD. Finché il DVD la supporta, menu e tracce audio saranno presentate in " "questa lingua.\n" "Questo valore deve essere un codice di lingua di due caratteri ISO639." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "read-ahead caching" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" "xine può usare la cache read ahead per l'accesso al lettore DVD.\n" "Questo può portare a cattiva riproduzione su lettori lenti, ma migliora " "l'impatto con il cambio di strato nel DVD sui lettori più veloci." #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" "Si può configurare il comportamento quando si effettua un comando di salto " "(usando per esempio i pulsanti 'skip')). I singoli valori significano:\n" "\n" "skip program\n" "salterà un programma del DVD, ovvero un'unità di navigazione simile agli " "indici dei CD audio, è il normale comportamento dei player DVD.\n" "\n" "skip part\n" "salterà una parte del DVD, che è un'unità strutturale simile alle tracce su " "un CD audio; le parti solitamente coincidono con i programmi, ma possono " "essere più grandi.\n" "\n" "skip title\n" "salterà un titolo DVD, un'unità strutturale che rappresenta intere " "funzionalità sul DVD." #: src/input/input_dvd.c msgid "unit for seeking" msgstr "unità per la ricerca" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" "Si può configurare il dominio interessato dalla slitta di ricerca. I singoli " "valori indicano:\n" "\n" "seek in program chain\n" "la ricerca sarà effettuata su un'intera catena del programma DVD, che è " "un'unità di navigazione che rappresenta l'intero flusso video della corrente " "funzionalità.\n" "\n" "seek in program\n" "la ricerca sarà effettuata su un programma DVD, che è un'unità di " "navigazione che rappresenta un capitolo della corrente funzionalità." #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "modalità di riproduzione quando si fornisce un titolo/capitolo" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" "Si può configurare il comportamento quando si riproduce un DVD da un certo " "titolo o capitolo (per esempio usando il MRL 'dvd:/1.2'). I singoli valori " "significano:\n" "\n" "entire dvd\n" "riproduce l'intero DVD partendo dalla posizione indicata.\n" "\n" "one chapter\n" "riproduce soltanto lo specifico titolo/capitolo e quindi si ferma." #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Permesso negato: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: File non trovato: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: File vuoto: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "plugin di input del file" #: src/input/input_file.c msgid "file browsing start location" msgstr "Posizione di partenza del navigatore di file" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" "Il navigatore per selezionare i file da riprodurre partirà da questa " "posizione." #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "plugin di input del file" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "plugin di input del file" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "plugin di input gnome-vfs incluso con xine" #: src/input/input_helper.c msgid "list hidden files" msgstr "elenca i file nascosti" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" "Se abilitato, il navigatore per selezionare i file da riprodurre mostrerà " "anche i file nascosti." #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "plugin di input per lo stream di stdin" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s) fallito: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: errore di lettura %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Connessione in corso al server HTTP..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: risposta http non valida\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: 3xx ridirezione: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: lo stato di http non è 2xx: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_httml: lunghezza del contenuto = % byte\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: buffer esaurito dopo %d byte." #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "plugin di ingresso http" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "Server proxy HTTP" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "Nome del proxy HTTP" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "Porta proxy HTTP" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "Il numero di porta del proxy HTTP" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "Nome utente proxy HTTP" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "Il nome utente per il proxy HTTP" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "Password proxy HTTP" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "La password per il proxy HTTP" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Domini per cui si vuole ignorare il proxy HTTP" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Una lista separata da virgole di nomi di dominio per cui il proxy deve " "essere ignorato.\n" "Se un nome di dominio è prefissato da =, allora è trattato come il nome di " "un singolo host (e viene richiesta corrispondenza completa)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "plugin di ingresso per stream MMS" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "larghezza di banda" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "Specifica la larghezza di banda della propria connessione ad Internet. " "Questa sarà utilizzata quando i server di streaming offrano versioni diverse " "con diversi requisiti di banda dello stesso flusso." #: src/input/input_mms.c msgid "MMS protocol" msgstr "Protocollo MMS" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Seleziona il protocollo in cui incapsulare MMS.\n" "TCP è migliore ma potrebbe essere necessario HTTP se si è dietro a firewall." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "plugin di input per lo stream di stdin" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "plugin di input della rete trasportato così con xine" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "plugin di input del file" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "plugin di input del file" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "plugin di input per lo stream di stdin" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "plugin di input per lo stream pnm" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: errore creando il file pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: errore aprendo il file pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: errore di lettura (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: errore aprendo il dispotivo %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_G_CODEC fallito, forse l'interfaccia è cambiata?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_S_CODEC fallito, forse l'interfaccia è cambiata?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "WinTV-PVR 250/350 input plugin" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "dispositivo utilizzato per WinTV-PVR 250/350 (pvr plugin)" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "Il percorso al dispositivo della propria scheda WinTV." #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "L'indirizzo IP specificato è multicast\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Impossibile trovare l'indirizzo per l'interfaccia %s: %s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "" "setsockopt(IP_ADD_MEMBERSHIP) non riuscito (multicast del kernel?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "impossibile risolvere '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "impossibile fare il bind a '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: interruzione di lettura di thread...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: lettura thread terminata\n" #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Apertura in corso > nome del file: %s porta: %d interfaccia: %s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: impossibile creare nuova thread (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "plugin input RTP e UDP tarsportati così con xine" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "plugin di input per lo stream rtsp" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "Plugin di ingresso CIFS/SMB basato su libsmbclient" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "plugin di input del file" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "plugin di input del file" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: apertura non riuscita '%s'\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "plugin di input per lo stream di stdin" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "plugin di ingresso TV V4L" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Buffer underrun..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Buffer overrun..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Calibrando..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Nome del sintonizzatore non trovato.\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "plugin di ingresso TV V4L" #: src/input/input_v4l.c msgid "v4l video device" msgstr "dispositivo video v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Il percorso al proprio dispositivo video Video4Linux." #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "Il percorso al proprio dispositivo video Video4Linux." #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "plugin di ingresso radio V4L" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "dispositivo radio v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Il percorso al proprio dispositivo radio Video4Linux," #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: MRL malformata. Utilizzare vcdo://\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: traccia %d non valida (intervallo valido: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "impossibile aprire %s: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: impossibile aprire %s: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "plugin di input per Video CD" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "dispositivo utilizzato per la riproduzione VCD" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" "Il percorso al dispositivo, solitamente un lettore CD o DVD, che si intende " "utilizzare per riprodurre VideoCD." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: MRL errata: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: connessione a '%s' fallita.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: connessione al server fallita: %s\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: impossibile stabilire una sessione.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "rtsp_session: impossibile stabilire una sessione.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "rtsp_session: il tipo di server rtsp '%s' non è supportato.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" "input_dvd: l'apertura del dispositivo %s è fallita durante l'espulsione.\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Connessione in corso al server MMS (su TCP)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: errore di invio\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: formato di risposta non valido.\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: redirezione 3xx non implementata: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: lo stato di ritorno HTTP non è 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: redirezione Location non implementata\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Connessione al server MMS (tramite http)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "url non valido\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "protocollo non supportato\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "modalità TV preferita" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "modalità TV preferita" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: ricevuto messaggio dal server durante la lettura dello stream:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: connessione fallita '%s'\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: impostazione dello stream fallita.\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR non implementato per offset diversi da zero." #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END non implementato." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "seek non implementato." #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "tipo di oggetto non valido" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "numero di inserimento non valido" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "numero di segmento non valido" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "errore nel leggere il numero di segmento corrente" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Il precedente sarebbe dovuto esser convertito" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "impossibile trovare un dispositivo con un VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "è stato passato un parametro classe nullo." #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Tipo di inserimento attuale non valido." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "la selezione non ha un elemento RETURN" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "selezionato DEFAULT, ma PBC non è abilitato." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "la selezione non ha un elemento NEXT" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "la selezione non ha un elemento PREVIOUS" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Tipo di evento sconosciuto: " #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" "Plugin Video CD con PBC e supporto per: (X)VCD, (X)SVCD, HQVCD, CVD ..." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "Tipo predefinito di VCD da usare in riproduzione automatica." #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "L'unità di riproduzione VCD da utilizzare quando non è specificata in un " "MRL, per esempio vcd:// o vcd://dev/dvd:" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "Lettore CD-ROM utilizzato per i VCD quando non è specificato." #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Cosa usare se non è specificato nessun drive. Se l'impostazione è vuota xine " "scandirà per lettori CD. " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "intervallo della slitta di posizione VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" "intervallo che la slitta di posizione nel flusso riprodotto rappresenta " "quando si riproduce un VCD." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "VCD read-ahead caching?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "La classe può portare a riproduzione a singhiozzo su macchine lente." #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "avanza automaticamente di traccia/elemento VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Se abilitato si passerà automaticamente al successivo elemento o traccia. " "Utilizzato solo quando il controllo di riproduzione (PBC) è disabilitato." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "mostra LID \"rifiutati\" dei VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" "Alcune liste di ID da riprodurre (LID) sono segnate non mostrabili, ma si " "possono vedere nella lista MRL se questa opzione è abilitata. Gli elementi " "rifiutati sono segnati con un asterisco (*) alla fine del MRL." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "Stringa di formato VCD per il banner da visualizzare." #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" "Formato VCD utilizzato nel titolo dell'interfaccia grafica, simile al " "comando date Unix. Gli specificatore di formato cominciano con un simbolo di " "percentuale. Gli specificatori sono:\n" " %A : le informazioni dell'album\n" " %C : il totale di volumi VCD - il numero di CD nella collezione.\n" "%c : il numero di volume del VCD - il numero di questo CD nella collezione.\n" " %F : il formato del VCD, per esempio VCD 1.0, VCD 1.1, VCD 2.0 o SVCD.\n" " %I : il tipo di elemento/segmento/riproduzione attuale, per esmepio ENTRY, " "TRACK, ...\n" " %L : l'identificativo della playlist prefisso con \"LID\" se esiste.\n" " %N : l'attuale numero del precedente - un numero decimale.\n" " %P : l'ID dell'editore.\n" " %p : l'ID del preparante.\n" " %S : se si è in un segmento (menu), il tipo di segmento.\n" " %T : il numero di traccia.\n" " %V : l'ID del set di volumi.\n" " %v : l'ID del volume (un numero tra 1 e il totale di volumi).\n" " %% : un simbolo %\n" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "Stringa di formato utilizzata per il campo di commento del flusso" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "Formato VCD utilizzato nel campo di commento del flusso, simile al comando " "date Unix. Gli specificatori di formato iniziano con un simbolo di " "percentuale. Gli specificatori sono %a, %C, %c, %F, %I, %L, %N, %P, %p, %S, %" "T e %%.\n" "Si veda la descrizione di title_format per il loro significato." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "Flag di debug per VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" "Per tracciare i bug nel plugin VCD. I valori della maschera sono:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "percorso ai codecs RealPlayer" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "Se si ha RealPlayer installato, si specifichi il percorso ai sui codec qui. " "Si possono individuare facilmente i codec cercando un file chiamato \"drvc.so" "\". Se xine può trovare i codec RealPlayer li utilizzerà per decodificare " "contenuto RealPlayer. Si consultino le FAQ per maggiori informazioni su come " "installare i codec." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "" "libareal: (audio) impossibile risolvere i simboli - DLL incompatibile: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" "libareal: inizializzazione del decoder fallita, codice di errore: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "libareal: setup del tipo di decoder fallito, codice di errore: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: ops, real può usare più di 2 canali?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" "libreal: Errore nella risoluzione dei simboli (incompatibilità di " "versione?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "percorso ai codecs Win32" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "Se si hanno i pacchetti di codec Windows o Apple QuickTime installati, si " "specifichi il percorso alla directory dei codec. Se xine può trovare i codec " "Windows o Apple QuickTime li utilizzerà per decodificare vari formati che " "non sono attualmente implementati. Si consultino le FAQ per maggiori " "informazioni su come installare i codec." #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "plugin di uscita audio per xine su file" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ICOpen fallito! codec sconosciuto %08lx / parametri sbagliati?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) fallito: Errore %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery fallito: Errore %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin fallito: Errore %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder fallito! codec sconosciuto %08lx / parametri " "sbagliati?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder fallito! codec sconosciuto %08lx / parametri " "sbagliati?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: errore nella partenza del decoder. '%s' è installato?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_decoder) Formato audio non appropriato.\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen errore %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: errore inizializzando l'audio DirectShow\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: errore inizializzando l'audio DMO\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" "Questo filtro effettua una dilatazione temporale, riproducendo il flusso più " "velocemente o più lentamente da un fattore. Il tono è, su richiesta, " "preservato quindi è possibile per esempio per guardare un film in meno tempo " "di quanto fosse stato originariamente registrato.\n" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" "Funzioni di mixaggio. Per esempio prendere un ingresso stereo e produrre un " "output Surround 5.1.\n" "Parametri:\n" " cut_off_freq\n" "\n" "Nota: è possibile utilizzare la finestra di controllo del frontend per " "impostare questi parametri.\n" "\n" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" "Questo filtro mixa un flusso mono a stereo duplicando i canali. In " "alternativa si può utilizzare questo plugin per ascoltare solo un canale di " "un certo flusso.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": mixando da Mono a Stereo.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] ": mixando un singolo canale da un flusso originale a %d canale.\n" msgstr[1] ": mixando un singolo canale da un flusso originale a %d canali.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": dispositivo audio incapace di usare AO_CAP_MODE_STEREO.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr ": mixando da Mono a Stereo" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" "Normalizza l'audio massimizzando il volume senza distorcere il suono.\n" "\n" "Parametri:\n" " method: 1: utilizza un singolo campione per assottigliare le variazioni " "attraverso la media standard pesata sui campioni precedenti (default; 2: " "utilizza diversi campioni per assottigliare le variazioni attraverso la " "media standard pesata sui campioni precedenti.\n" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: Nessun metodo di deinterlacciamento disponibile. uscita.\n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "frame per secondo da generare" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Con più frame per secondo l'animazione diventerà più fluida e veloce, ma " "richiederà anche più potenza CPU." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "larghezza dell'immagine goom" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "La larghezza in pixel dell'immagine da generare." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "altezza dell'immagine goom" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "L'altezza in pixel dell'immagine da generare." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "metodo di conversione dello spazio di colore" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" "Si scelga il metodo di conversione dei colori utilizzato da goom.\n" "Le selezioni disponibili dovrebbero spiegarsi da sole." #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico effettua semplici effetti \"picture in picture\".\n" "\n" "Parametri: pip_num: il numero di immagini a cui si riferiscono le " "impostazioni successive\n" " x: la coordinata x dell'angolo superiore sinistro dell'immagine\n" " y: la coordinata y dell'angolo superiore sinistro dell'immagine\n" " w: la larghezza dell'immagine\n" " h: l'altezza dell'immagine\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Switch può essere utilizzato per scambiare velocemente attraverso input " "multipli.\n" "\n" "Parametri\n" " select: il numero di input che saranno passati all'output.\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Box blur effettua una semplice sfocatura dell'immagine\n" "\n" "Parametri:\n" " Radius: dimensione del filtro\n" " Power: quanto spesso deve essere applicato il filtro\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Questo filtro mira a ridurre il rumore dell'immagine producendo immagini più " "fluide e rendendo le immagini ferme davvero ferme (Dovrebbe migliorare la " "compressibilità). Gli si possono passare da 0 a 3 parametri. Se si omette un " "parametro, un valore ragionevole sarà predefinito.\n" "\n" "Parametri\n" " Luma: forza luminosa spaziale (default = 4)\n" " Chroma: forza cromatica spaziale (default = 3)\n" " Time: forza temporale (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" "Equalizzatore software laternativo che utilizza tabelle di ricerca (molto " "lento), permettendo la correzione della gamma oltre che la semplice taratura " "di luminosita, contrasto e saturazione.\n" "Nota che utilizza lo stesso codice ottimizzato MMX di 'eq' se tutti i valori " "gamma sono 1.0.\n" "\n" "Parametri\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma per il componente rosso)\n" " ggamma (gamma per il componente verde)\n" " bgamma (gamma per il componente blu)\n" "\n" "Gli intervalli dei valori sono 0.1-10 per le gamma, -2-2 per il contrasto " "(valori negativi risultano in immagini negative), -1-1 per la luminosità e 0-" "3 per la saturazione.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" "Equalizzatore software con controlli interattivi come l'equalizzatore " "hardware, per driver e schede che non supportano i controlli di luminosità e " "contrasto in hardware.\n" "\n" "Parametri: luminosità\n" " contrasto\n" "\n" "Nota: è possibile utilizzare la finestra di controllo del frontend per " "impostare questi parametri\n" "\n" "* mplayer's eq (C) Richard Felker\n" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" "Il plugin di espansione è pensato per prendere frame di proporzioni " "arbitrarie e convertirli ad un aspetto diverso (predefinito: 4:3) " "aggiungendo barre nere sopra e sotto il frame. Questo permette di inserire " "le sovrimpressioni dentro all'area nera in modo che non coprano l'immagine.\n" "\n" "Parametri (DA CORREGGERE: migliorare il testo informativo)\n" " Enable_automatic_shift: Abilita lo spostamento automatico delle " "sovraimpressioni\n" " Overlay_y_offset: Sposta manualmente le sovraimpressioni veticalmente\n" " aspect: La proporzione destinazione (default 4:3)\n" " Centre_cut_out_mode: estrae l'immagine 4:3 contenuta in un frame 16:9\n" "\n" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" "Aggiunge rumore casuale al video.\n" "\n" "Parametri:\n" " luma_strength: forza del rumore aggiunto al canale luminosità (0-100, " "default: 8)\n" " chroma_strength: forza del rumore aggiungo al canale cromatico (0-100, " "default: 5)\n" " quality: livello di qualità del rumore. fixed: schema costante; temporal: " "lo schema varia tra i frame; averaged temporal: schema più liscio che cambia " "tra i frame. (default: averaged_temporal)\n" " type: tipo di rumore: uniforme o gaussiano (default: gaussiano)\n" " patter: mescola il rumore casuale con uno schema semi-regolare. (default: " "falso)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "Plugin libpostprocess FFMpeg\n" "\n" "Parametri\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" "Unsharp mask / gaussian blur\n" "È possibile la larghezza e la dimensione della matrice, di dimensioni " "dispari in entrambe le direzioni (min = 3x3, max = 13x11 o 11x13, " "solitamente tra 3x3 e 7x7) e la quantità relativa di definizione/sfocatura " "da aggiungere all'immagine (un intervallo sano dovrebbe essere -1.5 - 1.5).\n" "\n" "Parametri\n" "\n" " Luma_matrix_width: Larghezza della matrice (deve essere dispari)\n" "\n" " Luma_matrix_height: Altezza della matrice (deve essere dispari)\n" "\n" " Luma_amount: Quantità relativa di definizione/sfocatura (=0 disabilita, <0 " "sfoca, >0 definisci)\n" "\n" " Chroma_matrix_width: Larghezza della matrice (deve essere dispari)\n" "\n" " Chroma_matrix_height: Altezza della matrice (deve essere dispari)\n" "\n" " Chroma_amount: Quantità relativa di definizione/sfocatura (=0 disabilita, " "<0 sfoca, >0 definisci)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "Carattere per sottotitoli esterni" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "Spostamento verticale sottotitolo" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "Codifica dei sottotitoli" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "durata predefinita dei sottotitoli in secondi" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Alcuni formati di sottotitolo non forniscono esplicitamente una durata per " "ciascun sottotitolo. In questo caso si può impostare una durata predefinita " "qui. Utilizzando zero il sottotitolo sarà visualizzato finché il successivo " "non ne prende il posto." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "dimensione del sottotitolo" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" "Potete qui impostare la dimensione del sottotitolo, l'impostazione sarà " "valutata relativamente alla dimensione della finestra." #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "Spostamento verticale sottotitolo" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" "Si può calibrare la posizione verticale del sottotitolo, l'impostazione sarà " "valutata relativamente alla dimensione della finestra." #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "Carattere per sottotitoli" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Un carattere della directory di caratteri di xine da utilizzare per il testo " "del sottotitolo." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" "Un font grafico (es. un .ttf) da utilizzare per il testo dei sottotitoli." #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "se utilizzare un font FreeType" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "Codifica dei sottotitoli" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "La codifica del testo dei sottotitoli nel flusso. Questa impostazione è " "utilizzata per visualizzare correttamente i caratteri non-ASCII. Se i " "caratteri non-ASCII non sono visualizzati correttamente, chiedere al " "creatore dei sottotitoli quale codifica è stata usata." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "utilizza OSD non ridimensionato se possibile" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" "L'OSD non ridimensionato sarà visualizzato indipendentemente dal frame video " "e sarà sempre netto, anche se il video è ingrandito. Questa opzione non " "funziona con tutto l'hardware grafico, l'alternativa è utilizzare OSD " "ridimensionato, che diventa sfocato se si ingrandisce un video a bassa " "risoluzione a pieno schermo, ma funziona con tutte le schede grafiche." #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "visualizza sottotitoli CC (closed captions) negli stream MPEG-2" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" "I sottotitoli CC sono sottotitoli perlopiù utilizzati per aiutare i non " "udenti." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "schema colori primo piano/sfondo per sottotitoli CC" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Si scelga la visualizzazione preferita per i sottotitoli CC." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "carattere standard per i sottitotoli CC" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Si scelga il carattere per il testo standard dei sottotitoli CC." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "carattere corsivo per i sottotitoli CC" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "Si scelga il carattere per il testo corsivo dei sottotitoli CC" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "dimensione del carattere per sottotitoli CC" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "Si celga la dimensione del carattere per i sottotitoli CC." #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "allinea al centro i sottititoli CC" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" "Se abilitato i sottotitoli CC saranno posizionati al centro delle rispettive " "righe." #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "%s: apertura non riuscita '%s' (%s)\n" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "%s: connessione a port %d fallita (%s).\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: impossibile creare nuova thread (%s)\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: errore durante la decompressione ByteRun1\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 non supportata al momento\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 non supportata al momento\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ non supportata al momento\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: questo tipo di Anim non è supportato al momento\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c #, fuzzy msgid "image video decoder plugin" msgstr "Numero di thread di decodifica FFmpeg" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c #, fuzzy msgid "mpeg2 based video decoder plugin" msgstr "Numero di thread di decodifica FFmpeg" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "plugin di uscita video per xine utilizzante la libreria AsCii Art" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "" "plugin di uscita video per xine utilizzante la libreria Color AsCii Art" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "modalità di buffer per lo strato video" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" "Seleziona la modalità di buffer per los trato di uscita. Buffer doppio o " "triplo fornisce una riproduzione più scorrevole ma consuma più memoria video." #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "attendi il ritracciamento verticale" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" "Abilita la sicnronizzazione dell'update dell'immagine video al ridisegno " "dello schermo intero (ritracciamento verticale)." #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "abilita la chiave cromatica video" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" "Abilita l'uso di una chiave cromatica per dire alla scheda grafica dove " "sovrapporre l'immagine video." #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "chiave cromatica video" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" "La chiave cromatica è utilizzata per dire alla scheda grafica dove " "sovrapporre l'immagine video. Si provino diversi valori se si notano le " "finestre diventare trasparenti." #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "filtro sfarfallio" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" "Abilita il filtro sfarfallio per un'uscita liscia su un display " "interlacciato." #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "parità di campo" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" "Per un display interlacciato abilita il controllo della parità di campo " "(\"none\" = disabilitato)." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" "video_out_directfb: si utilizza l'accelerazione sottotitoli hardware.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "video_out_vidix: lo strato supporta l'output video.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "video_out_syncfb: lo strato non supporta YV12!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "video_out_directfb: lo strato non supporta YUY2!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" "video_out_directfb: è necessario almeno DirectFB 0.9.25 per riprodurre su " "questo strato!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "video_out_directfb: lo strato non supporta l'impostazione buffer %d!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "video_out_directfb: lo strato non supporta le opzioni 0x%08x!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" "video_out_directfb: utilizzando il ridimensionamento accelerato hardware.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" "video_out_directfb: il ridimensionamento dell'immagine con " "deinterlacciamento è accelerato hardware.\n" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "id dello strato video (auto: -1)" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "Selezionate lo strato di uscita video tramite id." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "video_out_directfb: si utilizza lo strato di visualizzazione #%d.\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "plugin di output video per xine utilizzante DirectFB" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" "video_out_directfb: nessuno strato di visualizzazione utilizzabile trovato!\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "plugin di output video per xine utilizzante DirectFB sotto XDirectFB" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "plugin di output video per xine per win32 che usa directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: è supportato solo truecolor/directcolor impacchettato (%d).\n" " Si controlli 'fbset -i' o si provi 'fbset -depth 16'.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "nome del dispositivo framebuffer" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" "Specifica il nome del file per il dispositivo framebuffer da utilizzare.\n" "Questa impostazione è critica, poiché se questo viene cambiato ad un file " "diverso, xine può essere utilizzato per riempire questo file con contenuto " "arbitrario, si deve quindi essere attenti che il valore inserito sia " "veramente un dispositivo framebuffer valido." #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: la modalità video non è stata riconosciuta.\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: sono disponibili %d buffer in RAM video.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "ATTENZIONE: %s: i buffer a copia zero sono DISABILITATI poiché solo %d " "buffe\n" " sono disponibili, meno dei %d buffer raccomandati.\n" " Abbassare la risoluzione del frame buffer può aiutare.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "ATTENZIONE: %s: i buffer a copia zero sono DISABILITATI perché i driver\n" " del kernel non supportano lo spostamento dello schermo (utilizzati per " "l'inversione dei frame)\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "ATTENZIONE: %s: la profondità corrente è %d. Per migliori prestazioni\n" "è raccomandata una profondità di 16bpp.\n" "\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" "plugin di uscita video per xine usante il dispositivo Framebuffer di Linux" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "plugin di output video per xine utilizzante DirectFB" #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "plugin di uscita video per xine che non visualizza nulla" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "plugin di output video per xine utilizzante OpenGL 2.0" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "Visualizzatore OpenGL" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" "Il plugin OpeNGL fornsice diversi moduli visualizzatori:\n" "\n" "2D_Tex_Fragprog\n" "Questo modulo scarica l'immagine come texture YUV2D e le visualizza come una " "superficie texturizzata utilizzando programmi di frammentazione per " "ricostruire l'RGB.\n" "Questo è il metodo migliore e il più veloce sulle moderne schede grafiche.\n" "\n" "2D_Tex\n" "Questo modulo scarica le immagini come texture 2D e le visualizza come una " "superficie texturizzata.\n" "2D_Tex_Tiled\n" "Questo modulo scarica le immagine come texture 2D multiple e le visualizza " "come una superficie texturizzata. Per questo funziona anche con dimensioni " "massime delle texture più basse.\n" "Image_Pipeline\n" "Questo modulo utilizza glDraw() per visualizzare le immagini.\n" "Accelerato solo su alcuni driver.\n" "Non interpola nel ridimensionamento.\n" "\n" "Cylinder\n" "Mostra le immagini su un cilindro che ruota. Bell'effetto :)\n" "\n" "Environment_Mapped_Torus\n" "Mostra le immagini su un torroide che ruota. Beeello =)" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "framerate OpenGL minima" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" "Minima framerate per le routine di visualizzazione animata.\n" "Ignorato per le routine statiche.\n" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "abilita doppio buffering" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" "Per OpenGL il doppio buffering non elimina solo gli artefatti, ma riduce " "anche di molto lo sfarfallio.\n" "Non dovrebbe avere alcun impatto sulle prestazioni." #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "" "plugin di output video per xine utilizzante l'interfaccia grafica 3D OpenGL" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx32: errore: impossibile controllare la superficie DGA per la " "finestra video\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Errore: ioctl fallita, dispositivo non valido (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "video_out_pgx32: Errore: '%s' non`e un dispositivo framebuffer pgx32\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "plugin di output video di xine per il frame buffer Sun PGX32" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx64: errore: impossibile controllare la superficie DGA per la " "finestra video\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" "video_out_pgx64: errore: impossibile aprire il dispositivo framebuffer '%s'\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "video_out_pgx64: Errore: ioctl fallita, dispositivo non valido (%s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Errore: '%s' non`e un dispositivo framebuffer xvr100/pgx64/" "pgx24\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" "video_out_pgx64: Errore: l'overlay video su questo schermo è già in uso.\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" "video_out_pgx64: Error: impossibile impostare le priorità della finestra.\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Attenzione: poca memoria video, buffer multiplo " "disabilitato.\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Error: memoria video insufficiente.\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Attenzione: poca memoria video, doppio buffer " "disabilitato.\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Errore: ioctl fallita (FBIOGATTR)\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "chiave cromatica per l'overlay video" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" "La chiave cromatica è utilizzata per dire alla scheda grafica dove " "sovrapporre l'immagine video. Si provino diversi valori se si notano le " "finestre diventare trasparenti." #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "abilita chiave cromatica" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" "Disegna la grafica OSD sopra alla chiave cromatica anziché mescolarlo di " "volta in volta nei frame." #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "abilita buffer multiplo" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" "Il buffer multiplo migliora le prestazioni al costo di usare più memoria " "video." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" "plugin di output video di xine per il frame buffer Sun XVR100/PGX64/PGX24" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "utilizza accelerazione hardware se disponibile" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "Sarà utilizzata l'accelerazione fornita dall'hardware grafico se il sistema " "lo supporta. Nel caso in cui non funzionasse è possibile disabilitarla." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" "sdl dovrà emulare una superficie a 16 bit, questo rallenterà le cose.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: la modalità a pieno schermo NON è supportata.\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "plugin di uscita video di xine utilizzante SDL" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "plugin di output video di xine che usa Libstk Surface Set-top Toolkit" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "numero predefinito di frame video" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" "Il numero predefinito di frame video da richiedere dal driver di uscita " "video. Alcuni driver rimpiazzeranno questa impostazione con il loro valore." #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI colour conversion method" msgstr "metodo di conversione dello spazio di colore" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "plugin di output video per xine utilizzante DirectFB" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "vdpau: Non utilizzare il deinterlacciamento per frame progressivi." #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "plugin di output video per xine utilizzante VDPAU" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "intensità del colore rosso" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "L'intensità dei componenti di colore rosso." #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "intensità del colore verde" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "L'intensità dei componenti di colore verde." #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "intensità del colore blu" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "L'intensità dei componenti di colore blu." #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" "Il doppio buffering sincronizzerà l'aggiornamento dell'immagine video con il " "ridisegnod ell'intero schermo (ritracciamento verticale). Questo eliminerà " "gli sfarfallii e gli artifatti, ma utilizzerà più memoria video." #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: il dispositivo supporta il formato yuv2\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: il dispositivo supporta il formato yv12\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "video_out_vidix: la versione della libreria VIDIX è errata\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: impossibile trovare un driver VIDIX funzionante\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: utilizzando il driver %s di %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "componente rossa della chiave cromatica di sovraimpressione" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "componente verde della chiave cromatica di sovraimpressione" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "componente blu della chiave cromatica di sovraimpressione" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "plugin di output video di xine che usa libvidix per x11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" "plugin di output video di xine che usa libvidix per il frame buffer Linux" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "%s: => l'estensione MIT Shared Memory non sarà utilizzata.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" "%s: errore nella memoria condivisa (errore d'indirizzo) riservando " "l'immagine \n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "ATTENZIONE: la profondità corrente è %d. Per migliori prestazioni\n" "è raccomandata una profondità di 16bpp.\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "%s: l'estensione MIT Shared Meory non è presente sul display.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: la modalità video non è stata riconosciuta.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" "plugin di output video per xine utilizzante l'estensione MIT X Shared Memory" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: questo dispositivo supporta il formato %s.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: estensione Xv non presente.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: estensione XV presente ma non è stato possibile trovare una porta yuv12 " "utilizzabile.\n" "sembrerebbe che l'hardware grafico non supporti Xv.\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: utilizzando la porta Xv %d dal dispositivo %s per la conversione di " "colori e il ridimensionamento hardware.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" "Il doppio buffering sincronizzerà l'aggiornamento dell'immagine video con il " "ridisegnod ell'intero schermo (ritracciamento verticale). Questo eliminerà " "gli sfarfallii e gli artifatti, ma utilizzerà più memoria video." #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "plugin di output video di xine che usa l'estensione video MIT X" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: utilizzando la porta Xv %ld dal dispositivo %s per la conversione di " "colori e il ridimensionamento hardware.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: estensione XvMC non presente.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: estensione XV presente ma non è stato possibile trovare una " "porta yuv12 utilizzabile.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xxmc: utilizzando la porta Xv %ld dal dispositivo %s\n" " per la conversione di colori e il ridimensionamento hardware.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " accelerazione idct e compensazione del movimento \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " solo accelerazione della compensazione di movimento\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " nessun supporto XvMC \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " Con overlay = %d; UnsignedIntra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "plugin di output video per xine utilizzante l'estensione X video XvMC" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "Fa sì che XvMC riservi più frame per un miglior buffer." #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" "Alcune implementazioni XvMC permettono più di 8 frame.\n" "Questa opzione, quando abilitata, fa sì che il drive tenti\n" "di riservare 15 frame. Necessario per unichrom e VDR istantanei.\n" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Risparmio CPU Unichrome" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" "Risparmia tempo di CPU \"dormendo\" quando il decoder è inf unzione.\n" "Solo per kernel Linux 2.6 o 2.4 con patch multimediale.\n" "Sperimentale.\n" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "Correggi i colori dei sottotitoli difettosi su NVIDIA XvMC" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" "C'è un errore nella libreria XvMC NVIDIA che rende i colori rossi dell'OSD " "blu e viceversa. Questa opzione fornisce un workaround.\n" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Utilizza bob come metodo di deinterlacciamento accelerato." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" "Quando l'interlacciamento è abilitato per i frame accelerati hardware, " "alterna i campi superiore e inferiori al doppio del frame rate.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "Non utilizzare il deinterlacciamento bob per frame progressivi." #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" "I frame progressivi non devono essere deinterlacciati, quindi disabilitarlo\n" "a richiesta dovrebbe fornire una migliore immagine.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" "Non utilizzare il deinterlacciamento bob quando è attivo un OSD " "ridimensionato." #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" "Il deinterlacciamento bob aggiunge del rumore alle righe orizzontali, " "quindi\n" "disabilitarlo a richiesta dovrebbe fornire una migliore immagine OSD.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: estensione XShape non disponibile: overlay non ridimensionato " "disabilitato.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: errore creando la finestra, overlay non ridimensionato " "disabilitato.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: errore creando la pixmap, overlay non ridimensionato disabilitato.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: overlay non ridimensionato creato (modalità %s).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "colora automaticamente la chive cromatica" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Fa sì che Xv colori automaticamente la propria chiave cromatica." #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "modalità di ridimensionamento bilineare" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" "Seleziona la modalità di ridimensionamento bilineare per le schede Permedia. " "I singoli valori sono:\n" "\n" "Permedia 2\n" "0 - disabilita il filtro bilineare\n" "1 - abilita il filtro bilineare\n" "\n" "Permedia 3\n" "0 - disabilita il filtro bilineare\n" "1 - abilita il filtro lineare orizzontale\n" "2 - abilita il filtro bilineare completo" #: src/video_out/xv_common.h #, fuzzy msgid "Xv port number" msgstr "numero di inserimento non valido" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "pitch alignment workaround" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" "Alcuni driver video difettosi richiedono un workaround per funzionare " "correttamente." #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "filtro sfarfallio" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "disabilita la trasparenza esatta per gli overlay" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" "Se si nota un impatto sulle prestazioni quando l'OSD o altri overlay come i " "sottotitoli dei DVD sono attivi, si potrebbe voler abilitare quest'opzione.\n" "Il risultato è che la trasparenza degli overlay è meno accurata che in " "precedenza, ma questo fa anche diminuire l'utilizzo del processore." #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: nessun plugin disponibile per gestire '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: errore, tipo di buffer %08x sconosciuto\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "numero di buffer audio" #: src/xine-engine/audio_decoder.c #, fuzzy msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Il numero di buffer audio (di 8kB ognuno) utilizzati da xine nella sua coda " "interna. Valori alti significano una riproduzione più liscia per ingressi " "inaffidabili, ma aumenta la latenza e il consumo di memoria." #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: calcolo del ritardo impossibile con un dispositivo audio non " "disponibile.\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" "scrittura sulla scheda audio fallita. Si suppone il dispositivo sia stato " "scollegato.\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "8 bit non supportati dal driver, conversione a 16 bit.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "mono non supportato dal driver, conversione a stereo.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "stereo non supportato dal driver, conversione a mono.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "metodo di sincronia audio/video" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" "Quando si riproducono audio e video ci sono almeno due orologi coinvolti. Il " "orologi di sistema, su cui sono sincronizzati i frame video, e il orologi " "nel proprio hardware sonoro, che determina la velocità della riproduzione " "audio. Questi orologi non corrono mai alla stessa velocità, ad eccezione di " "alcuni rari casi in cui sono fisicamente identici. In generale, i due " "orologi inizieranno a distanziarsi dopo un certo periodo, per quesot motivo " "xine offre due modi di tenere audio e video sincronizzati: \n" "\n" "metronom feedback\n" "Questo è il metodo standard che applica una distanziazione contraria al " "video appena la distanza con l'audio si è accumulata oltre ad un valore " "soglia.\n" "\n" "resample\n" "Per alcuni hardware video, limitati ad un frame rate fisso (come DXR3 o " "altre schede di decodifica) il metodo precedente non funziona, poiché il " "video non si può distanziare. Per questo viene ricampionato il flusso audio " "per accorciarlo o allungarlo per compensare con la distanza presa " "dall'audio. Questo metodo non funziona per il passaggio diretto digitale, " "dove i dati audio sono passati ad un decodificatore esterno in forma " "digitale." #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "abilita ricampionamento" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" "Quando la frequenza di campionamento dell'audio decodificato non corrisponde " "alle capacità del proprio hardware sonoro è richiesto un adattamento " "chiamato \"ricampionamento\". Qui si può selezionare se abilitare, " "disabilitare o utilizzare automaticamente quando necessario il " "ricampionamento." #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "ricampiona sempre a questa frequenza (0 per disabilitare)" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" "Alcuni driver audio non annunciano correttamente le capacità dell'hardware " "sonoro. Impostando un valore diverso da zero qui si può forzare il " "ricampionamento del flusso audio alla frequenza data." #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "offset per il passaggio diretto digitale" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Se si utilizza un decodificatore surround esterno e l'audio è in anticipo o " "in ritardo rispetto al video, si può inserire un offset fisso per " "compensare.\n" "L'unità di misura è un \"PTS tick\" ovvero 1/90000 secondi." #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "riproduci audio anche a velocità basse/elevate" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" "Se si abilita questa opzione, l'audio sarà ascoltabile anche quando la " "velocità di riproduzione è diversa da 1X. Ovviamente sarà distorto (tono più " "basso o più alto). Se si vuole sperimentare preservando il tono, è possibile " "provare il plugin di post-elaborazione audio 'stretch'." #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "volume audio di partenza" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Il volume audio generale da impostare all'avvio di xine.partenza" #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "ripristina il volume all'avvio" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "Se disabilitato, xine non modificherà alcuna impostazione del mixer " "all'avvio." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: spiacente, non sarebbe dovuto succedere. Per favore riavvia " "xine.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "xine-lib: buffer.c: C'è stato un errore fatale: TROPPI FREE\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "L'attuale file di configurazione è stato modificato da una nuova versione di " "xine." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: ATTENZIONE: la propria configurazione non sarà salvata.\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" "configfile: ATTENZIONE: scrittura della configurazione in %s fallita.\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: ATTENZIONE: rimozione del file di configurazione %s " "possibilmente rovinato.\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: ATTENZIONE: si controlli il file di backup %s.\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: la voce '%s' non deve essere modificata da MRL\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" "info_helper: impossibile individuare il set di caratteri locale corrente.\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" "info_helper: conversione %s -> UTF-8 non supportata, nessuna conversione " "eseguita\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": la funzione open() non dovrebbe mai essere chiamata.\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": plugin di ingresso non definito!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: la lettura di dati salvati non è riuscita: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: posizionamento fallito: %s.\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: la lettura tramite plugin di ingresso è fallita.\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: errore scrivendo su file % byte: %s.\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: la funzione open() non dovrebbe essere mai chiamata\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: posizionamento fallito.\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % byte rimossi.\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: plugin di ingresso non definito!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: la directory di destinazione non è stata specificata, si imposti " "l'opzione 'media.capture.save_dir'\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "La funzione di salvataggio dello stream sarà disabilitata finché non si " "imposta media.capture.save_dir nella configurazione. " #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: l'estrazione/cache di questa sorgente non è permessa.\n" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "A xine non è possibile salvare da questa sorgente. (possibile materiale " "protetto da copyright?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: nome del file non fornito!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: errore aprendo il file %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: attesa annullata\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: attesa fallita: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "impossibile recuperare lo stato del socket" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Permesso negato\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: File non trovato\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Connessionr rifiutata\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "map_decoder_list: niente spazio per il decoder, ignorato.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: tipo del plugin sconosciuto %d in %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: tipo del plugin statico sconosciuto %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: plugin %s ignorato, versione di interfaccia %d errata " "(dovrebbe essere %d)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" "load_plugins: raggiunto il limite di plugin, non è stato possibile caricare %" "s.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" "load_plugins: raggiunto il limite di plugin, non è stato possibile caricare " "il plugin statico.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "priorità per il decoder %s" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: il plugin demuxer %s non fornisce una priorità, xine-lib " "utilizzerà la priorità predefinita.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: il plugin di ingresso %s non fornisce una priorità, xine-lib " "utilizzerà la priorità predefinita.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: trovato plugin %s:%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: directory %s illeggibile ignorata.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: impossibile individuare %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: impossibile aprire la libreria plugin %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: non ottengo informazioni del plugin da %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: impossibile aprire la libreria plugin %s (stadio 2):\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Argh! %s non contiene informazioni plugin.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" "La priorità fornisce una gerarchia nel caso in cui un certo tipo di " "contenuto possa essere gestito da più di un decoder.\n" "Una priorità pari a 0 abilita la priorità predefinita del decoder." #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: strategia di riconoscimento contenuto sconosciuta %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: utilizzo del demuxer '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: caricamento del plugin output audio fallito <%s>\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" "load_plugins: il riconoscimento automatico dell'output audio non ha trovato " "alcun driver audio utilizzabile.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: impossibile rimuovere la libreria plugin %s:\n" "%s\n" #: src/xine-engine/metronom.c #, fuzzy msgid "basic video to audio delay in pts" msgstr "Non ci sono flussi audio o video in questo file.\n" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Bufferizzando..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "versione del font '%s' errata. Richiesto %d trovato %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "il carattere '%s-%d' è già caricato, strano.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "caricamento del carattere '%s' fallito (%d < %d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "osd: errore nel trovare il caratter carattere %s con FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "osd: errore nel caricamento del carattere %s con FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "osd: errore nella ricerca del carattere %s con FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "osd: errore nel caricamento del carattere %s con XDG.\n" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: impossibile inizializzare la libreria ft2\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" "osd: errore impostando la dimensione del carattere (nessun carattere " "scalabile?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: sequenza sconosciuta cominciante con byte 0x%02X nella codifica \"%s\", " "ignorata.\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: impossibile individuare il set di caratteri locale corrente.\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "" "osd: conversione %s -> %s non supportata, nessuna conversione eseguita\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: errore nel caricamento del glifo.\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: errore nella visualizzazione del glifo.\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: carattere non definito.\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: errore nel caricamento del glifo %i.\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: errore nella visualizzazione.\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" "palette (primo piano-bordo-sfondo) da utilizzare per i sottotitoli e OSD" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" "I colori per la visualizzazione a schermo e per alcuni formati di " "sottotitolo ceh non specificano nessuna colorazione. Le palette sono " "elencate nella forma: primo piano - bordo - sfondo." #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: nessun plugin disponibile per gestire '%s'\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: errore, tipo di buffer sconosciuto: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "numero di buffer video" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Il numero di buffer video (di 8kB ognuno) utilizzati da xine nella sua coda " "interna. Valori alti significano una riproduzione più liscia per ingressi " "inaffidabili, ma aumenta la latenza e il consumo di memoria." #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d frame consegnati, %d frame saltati, %d frame scartati\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: immagine con % pts scartata perché troppo vecchia (diff : " "%).\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "percentuale di frame saltati da tollerare." #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" "Quando non è mostrata una percentuale di frame superiore a questa, perché " "non decodificati in tempo, xine invia una notifica." #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "percentuale di frame scartati da tollerare." #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" "Quando non è mostrata una percentuale di frame superiore a questa, perché " "non disposti alla visualizzazione in tempo, xine invia una notifica." #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out: spiacente, non sarebbe dovuto succedere. Per favore riavvia " "xine.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "posizione orizzontale dell'immagine nella finestra di visualizzazione" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" "Se la dimensione orizzontale della finestra video è maggiore dell'immagine " "reale da mostrare, si può aggiustare la posizione dove l'immagine sarà " "visualizzata.\n" "La posizione è fornita come percentuale, quindi un valore di 50 indica \"al " "centro\" mentre 0 significa \"tutto a sinistra\" e 100 \"tutto a destra\"." #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "posizione vergicale dell'immagine nella finestra di visualizzazione" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" "Se la dimensione verticale della finestra video è maggiore dell'immagine " "reale da mostrare, si può aggiustare la posizione dove l'immagine sarà " "visualizzata.\n" "La posizione è fornita come percentuale, quindi un valore di 50 indica \"al " "centro\" mentre 0 significa \"tutto in alto\" e 100 \"tutto in basso\"." #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "disabilita il ridimensionamento video" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" "Se si vuole che l'immagine sia sempre visualizzata nella sua risoluzione " "reale, si può disabilitare tutto il ridimensionamento qui.\n" "Questo singiifca ovviamente che l'immagine non sarà più adattata alla " "finestra di visualizzazione e che i video con una proporzione diversa da 1:1 " "(come i DVD anamorfici) saranno visualizzati distorti. Però, con alcuni " "driver di uscita video come XShm, dove il ridimensionamento non è accelerato " "in hardware, questo può ridurre drasticamente l'uso di CPU." #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: errore durante l'interpretazione del MRL\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: plugin di ingresso trovato : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: il plugin di ingresso non può aprire il MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: impossibile trovare il plugin di ingresso per il MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: l'avvio del demuxer %s specificato è fallito.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: avvio del plugin di estrazione.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: errore nell'avvio del plugin di estrazione.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: l'avvio dell'ultimo demuxer provato %s è fallito.\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "video ignorato\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "audio ignorato\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "sottotitoli ignorati\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "plugin cache d'ingresso disattivato.\n" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "aperto il MRL sottotitoli '%s'\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: errore nell'apertura del MRL dei sottotitoli.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: modificare l'opzione '%s' da MRL non è consentito.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "xine: impossibile trovare il demuxer %s per >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: impossibile trovare il demuxer per >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: trovato plugin demuxer: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine: avvio del demuxer completo. veloce!\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: avvio del demuxer fallito.\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: nessun demux disponibile\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine: avvio del demuxer fallito.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" "xine: La directory di salvataggio specificata \"%s\" potrebbe essere un " "rischio per la sicurezza.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" "La directory di salvataggio specificata potrebbe essere un rischio per la " "sicurezza." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: locale non supportarto dalla liberaria C\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "Strategia di riconoscimento del formato di contenuto" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" "xine offre diversi metodi per riconoscere il formato di contenuto " "dell'ingresso da riprodurre. I singoli valori sono: \n" "\n" "default\n" "prima prova a riconoscere tramite contenuto, quindi tramite estensione del " "file.\n" "\n" "reverse\n" "Prima prova a individuare tramite estensione del file, poi tramite " "contenuto.\n" "\n" "content\n" "Riconosce solo tramite contenut.\n" "\n" "extension\n" "Riconosce solo tramite estensione del file.\n" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "Cartella di salvataggio degli stream" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" "QUando si utilizza la funzionalità di salvataggio degli stream, i file " "saranno scritti solo in questa directory.\n" "Questa impostazione è critica, perché quando si cambia ad una diversa " "directory, xine può essere utilizzato per riempirla di file con contenuto " "arbitrario. Per questo si deve essere attenti che la directory che si " "specifica sia robusta per qualsiasi contenuto di ogni file." #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" "permetti modifiche implicite alla configurazione (per esmepio tramite MRL)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" "Se abilitato, si permette a xine di modificare la propria configurazione " "senza azione specifica. Per esempio saranno eseguite le modifiche alla " "configurazione richieste dagli MRL o integrate nella playlist.\n" "Questa impostazione è critica, perché xine può ricevere MRL o playlist da " "sorgenti remote non fidate. Se si permette loro di modificare " "arbitrariamente la propria configurazione si può finire con uno xine " "completamente caotico." #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "Timeout per la lettura dei flussi via rete (in secondi)" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" "Specifica il timeout durante la lettura dei flussi di rete, in secondi. " "Valori troppo bassi possono fermare la riproduzione quando la sorgente è " "lenta o la banda è occupata, valori troppo alti congeleranno il player se la " "connessione viene persa." #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "messaggi" #: src/xine-engine/xine.c msgid "plugin" msgstr "plugin" #: src/xine-engine/xine.c msgid "trace" msgstr "traccia" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Attenzione:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "Host sconosciuto:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Dispositivo sconosciuto:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Rete irraggiungibile" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Connessione rifiutata:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "File non trovato:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Errore leggendo da:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Errore nel caricamento della libreria:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Individuato flusso multimediale cifrato" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Messaggio di sicurezza:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Dispositivo audio non disponibile" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Errore di permessi" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "Il file è vuoto:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Ripristino indice..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Test di velocità dei metodi memcpy (più piccolo è migliore):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "metodo di copia di memoria usato da xine" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" "La copia di grandi blocchi di memoria è una delle operazioni più costose nei " "computer moderni. Per questo xine fornisce diversi metodi raffinati per fare " "tale copia. Solitamente il metodo migliore è riconosciuto automaticamente." #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "" #~ "configfile: ATTENZIONE: copia di backup del file di configurazione in %s " #~ "fallita.\n" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: MRL errata: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: errore di lettura (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: impossibile risolvere '%s'.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: impossibile connettesi a '%s'.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "stdin: impossibile tornare indietro! (% %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: errore nell'interpretazione del MRL.\n" #~ msgid "raw device set up for DVD access" #~ msgstr "dispositivo diretto impostato per l'accesso DVD" #~ msgid "" #~ "If this points to a raw device connected to your DVD device, xine will " #~ "use the raw device for playback. This has the advantage of being slightly " #~ "faster and of bypassing the block device cache, which avoids throwing " #~ "away important cache content by keeping DVD data cached. Using the block " #~ "device cache for DVDs is useless, because almost all DVD data will be " #~ "used only once.\n" #~ "See the documentation on raw device setup (man raw) for further " #~ "information." #~ msgstr "" #~ "Se questo valore punta ad un dispositivo diretto collegato al proprio " #~ "lettore DVD, xine utilizzerà quest'ultimo per la riproduzione, con il " #~ "vantaggio di essere leggemente più veloce e di saltare la cache del " #~ "dispositivo a blocchi, che evita di buttare contenuto importante della " #~ "cache tenendo memorizzati i dati del DVD. L'utilizzo della cache del " #~ "dispositivo a blocchi per i DVD è inutile, poiché quasi tutti i dati DVD " #~ "sono utilizzati solo una volta.\n" #~ "Si veda la documentazione sull'impostazione dei dispositivi diretti (man " #~ "raw) per maggiori informazioni." #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "" #~ "Il messaggio precedente ha un livello di log di vcdimager sconosciuto." #~ msgid "load_plugins: static plugin %s found\n" #~ msgstr "load_plugins: trovato plugin statico %s\n" xine-lib-1.2/po/Rules-quot0000644000175000017500000000341114647725152013304 0ustar meme# Special Makefile rules for English message catalogs with quotation marks. DISTFILES.common.extra1 = quot.sed boldquot.sed en@quot.header en@boldquot.header insert-header.sin Rules-quot .SUFFIXES: .insert-header .po-update-en en@quot.po-create: $(MAKE) en@quot.po-update en@boldquot.po-create: $(MAKE) en@boldquot.po-update en@quot.po-update: en@quot.po-update-en en@boldquot.po-update: en@boldquot.po-update-en .insert-header.po-update-en: @lang=`echo $@ | sed -e 's/\.po-update-en$$//'`; \ if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; GETTEXTLIBDIR=`cd $(top_srcdir)/src && pwd`; export GETTEXTLIBDIR; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ ll=`echo $$lang | sed -e 's/@.*//'`; \ LC_ALL=C; export LC_ALL; \ cd $(srcdir); \ if $(MSGINIT) -i $(DOMAIN).pot --no-translator -l $$lang -o - 2>/dev/null | sed -f $$tmpdir/$$lang.insert-header | $(MSGCONV) -t UTF-8 | $(MSGFILTER) $(SED) -f `echo $$lang | sed -e 's/.*@//'`.sed 2>/dev/null > $$tmpdir/$$lang.new.po; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "creation of $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "creation of $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi en@quot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@quot.header/g' $(srcdir)/insert-header.sin > en@quot.insert-header en@boldquot.insert-header: insert-header.sin sed -e '/^#/d' -e 's/HEADER/en@boldquot.header/g' $(srcdir)/insert-header.sin > en@boldquot.insert-header mostlyclean: mostlyclean-quot mostlyclean-quot: rm -f *.insert-header xine-lib-1.2/po/POTFILES.in0000644000175000017500000001542514647725152013066 0ustar meme# For updating this file, look at the result of: # head -n 3 po/POTFILES.in > /tmp/POTFILES.in && grep -l '[^A-Za-z_]_(' . -r --include '*.[chy]' --exclude xineintl.h | sed -e 's:^\./::' | sort >> /tmp/POTFILES.in && cp /tmp/POTFILES.in po/ lib/hstrerror.c src/audio_dec/ff_dvaudio_decoder.c src/audio_dec/gsm610.c src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c src/audio_dec/xine_faad_decoder.c src/audio_dec/xine_lpcm_decoder.c src/audio_dec/xine_mad_decoder.c src/audio_dec/xine_musepack_decoder.c src/audio_out/audio_alsa_out.c src/audio_out/audio_coreaudio_out.c src/audio_out/audio_directx2_out.c src/audio_out/audio_directx_out.c src/audio_out/audio_esd_out.c src/audio_out/audio_file_out.c src/audio_out/audio_fusionsound_out.c src/audio_out/audio_irixal_out.c src/audio_out/audio_jack_out.c src/audio_out/audio_none_out.c src/audio_out/audio_oss_out.c src/audio_out/audio_pulse_out.c src/audio_out/audio_sndio_out.c src/audio_out/audio_sun_out.c src/audio_out/speakers.h src/combined/ffmpeg/demux_avformat.c src/combined/ffmpeg/ff_audio_decoder.c src/combined/ffmpeg/ff_video_decoder.c src/combined/ffmpeg/input_avio.c src/combined/flac_decoder.c src/combined/flac_demuxer.c src/combined/nsf_decoder.c src/combined/nsf_demuxer.c src/combined/wavpack_decoder.c src/combined/wavpack_demuxer.c src/combined/xine_ogg_demuxer.c src/combined/xine_speex_decoder.c src/combined/xine_theora_decoder.c src/combined/xine_vorbis_decoder.c src/demuxers/demux_4xm.c src/demuxers/demux_aac.c src/demuxers/demux_ac3.c src/demuxers/demux_aiff.c src/demuxers/demux_asf.c src/demuxers/demux_aud.c src/demuxers/demux_avi.c src/demuxers/demux_cdda.c src/demuxers/demux_dts.c src/demuxers/demux_eawve.c src/demuxers/demux_elem.c src/demuxers/demux_film.c src/demuxers/demux_flac.c src/demuxers/demux_fli.c src/demuxers/demux_flv.c src/demuxers/demux_idcin.c src/demuxers/demux_iff.c src/demuxers/demux_image.c src/demuxers/demux_ipmovie.c src/demuxers/demux_ivf.c src/demuxers/demux_matroska.c src/demuxers/demux_mng.c src/demuxers/demux_mod.c src/demuxers/demux_mpc.c src/demuxers/demux_mpeg_block.c src/demuxers/demux_mpeg.c src/demuxers/demux_mpeg_pes.c src/demuxers/demux_mpgaudio.c src/demuxers/demux_nsv.c src/demuxers/demux_playlist.c src/demuxers/demux_pva.c src/demuxers/demux_qt.c src/demuxers/demux_rawdv.c src/demuxers/demux_realaudio.c src/demuxers/demux_real.c src/demuxers/demux_roq.c src/demuxers/demux_shn.c src/demuxers/demux_smjpeg.c src/demuxers/demux_snd.c src/demuxers/demux_str.c src/demuxers/demux_ts.c src/demuxers/demux_tta.c src/demuxers/demux_vc1es.c src/demuxers/demux_vmd.c src/demuxers/demux_voc.c src/demuxers/demux_vox.c src/demuxers/demux_vqa.c src/demuxers/demux_wav.c src/demuxers/demux_wc3movie.c src/demuxers/demux_yuv4mpeg2.c src/demuxers/demux_yuv_frames.c src/dxr3/dxr3_decode_spu.c src/dxr3/dxr3_decode_video.c src/dxr3/dxr3.h src/dxr3/dxr3_mpeg_encoders.c src/dxr3/dxr3_scr.c src/dxr3/ffmpeg_encoder.c src/dxr3/video_out_dxr3.c src/input/input_bluray.c src/input/input_cdda.c src/input/input_dvb.c src/input/input_dvd.c src/input/input_file.c src/input/input_ftp.c src/input/input_gnome_vfs.c src/input/input_helper.c src/input/input_hls.c src/input/input_http.c src/input/input_mms.c src/input/input_mpegdash.c src/input/input_net.c src/input/input_nfs.c src/input/input_pnm.c src/input/input_pvr.c src/input/input_rtp.c src/input/input_rtsp.c src/input/input_smb.c src/input/input_ssh.c src/input/input_stdin_fifo.c src/input/input_test.c src/input/input_v4l2.c src/input/input_v4l.c src/input/input_vcd.c src/input/librtsp/rtsp.c src/input/librtsp/rtsp_session.c src/input/media_helper.c src/input/mms.c src/input/mmsh.c src/input/multirate_pref.c src/input/pnm.c src/input/tls/tls_gnutls.c src/input/tls/tls_openssl.c src/input/tls/xine_tls_plugin.h src/input/vcd/vcdio.c src/input/vcd/vcdplayer.c src/input/vcd/xineplug_inp_vcd.c src/libreal/real_common.c src/libreal/xine_real_audio_decoder.c src/libreal/xine_real_video_decoder.c src/libw32dll/common.c src/libw32dll/qt_decoder.c src/libw32dll/w32codec.c src/post/audio/stretch.c src/post/audio/upmix.c src/post/audio/upmix_mono.c src/post/audio/volnorm.c src/post/deinterlace/xine_plugin.c src/post/goom/xine_goom.c src/post/mosaico/mosaico.c src/post/mosaico/switch.c src/post/planar/boxblur.c src/post/planar/denoise3d.c src/post/planar/eq2.c src/post/planar/eq.c src/post/planar/expand.c src/post/planar/fill.c src/post/planar/invert.c src/post/planar/noise.c src/post/planar/pp.c src/post/planar/unsharp.c src/post/visualizations/fftgraph.c src/post/visualizations/fftscope.c src/post/visualizations/oscope.c src/post/visualizations/tdaudioanalyzer.c src/spu_dec/cmml_decoder.c src/spu_dec/spu_decoder.c src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_decoder.c src/spu_dec/sputext_demuxer.c src/spu_dec/xine_cc_decoder.c src/vdr/input_vdr.c src/vdr/post_vdr_audio.c src/vdr/post_vdr_video.c src/video_dec/bitplane.c src/video_dec/gdkpixbuf.c src/video_dec/image.c src/video_dec/libaom.c src/video_dec/libjpeg.c src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c src/video_dec/libmpeg2/xine_mpeg2_decoder.c src/video_dec/libopenhevc.c src/video_dec/libvdpau/alterh264_decode.c src/video_dec/libvdpau/vdpau_h264.c src/video_dec/libvdpau/vdpau_mpeg12.c src/video_dec/libvdpau/vdpau_mpeg4.c src/video_dec/libvdpau/vdpau_vc1.c src/video_dec/libvpx.c src/video_dec/mmal.c src/video_dec/rgb.c src/video_dec/yuv.c src/video_out/color_matrix.c src/video_out/opengl/xine_glx.c src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_aa.c src/video_out/video_out_caca.c src/video_out/video_out_directfb.c src/video_out/video_out_directx.c src/video_out/video_out_fb.c src/video_out/video_out_mmal.c src/video_out/video_out_none.c src/video_out/video_out_opengl2.c src/video_out/video_out_opengl.c src/video_out/video_out_pgx32.c src/video_out/video_out_pgx64.c src/video_out/video_out_raw.c src/video_out/video_out_sdl.c src/video_out/video_out_stk.c src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c src/video_out/video_out_vidix.c src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c src/video_out/video_out_xshm.c src/video_out/video_out_xv.c src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c src/video_out/x11osd.c src/video_out/xcbosd.c src/video_out/xv_common.h src/xine-engine/alphablend.c src/xine-engine/audio_decoder.c src/xine-engine/audio_out.c src/xine-engine/buffer.c src/xine-engine/buffer_types.c src/xine-engine/configfile.c src/xine-engine/demux.c src/xine-engine/info_helper.c src/xine-engine/input_cache.c src/xine-engine/input_rip.c src/xine-engine/io_helper.c src/xine-engine/load_plugins.c src/xine-engine/metronom.c src/xine-engine/net_buf_ctrl.c src/xine-engine/osd.c src/xine-engine/spu.c src/xine-engine/video_decoder.c src/xine-engine/video_out.c src/xine-engine/vo_scale.c src/xine-engine/xine.c src/xine-engine/xine_interface.c src/xine-utils/memcpy.c xine-lib-1.2/po/de.po0000644000175000017500000076644714647725152012262 0ustar meme# German xine-lib.po file. # Copyright (C) 2002-2023 Free Software Foundation, Inc. # # Jens Gutzeit , 2002. # Torsten Jager , 2023.". # Ronald Stroethoff , 2023. msgid "" msgstr "" "Project-Id-Version: xine-lib 1.2.2\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2023-01-16 17:45+0100\n" "Last-Translator: Torsten Jager \n" "Language-Team: German \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: de\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" "X-Generator: Lokalize 2.0\n" #: lib/hstrerror.c msgid "No error" msgstr "Kein Fehler" #: lib/hstrerror.c msgid "Unknown host" msgstr "Unbekannter Rechner" #: lib/hstrerror.c msgid "No address associated with name" msgstr "Keine Adresse zu diesem Namen" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Unbekannter Serverfehler" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Namensauflösung fehlgeschlagen" #: lib/hstrerror.c msgid "Unknown error" msgstr "Unbekannter Fehler" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "dvaudio: Vergrößere Puffer auf %d um Überlauf zu vermeiden.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "Digital Video (DV) Dekoder" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "GSM 6.10 Audio Dekoder" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "HILFE! Ein nur-Mono-Audiogerät?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "liba52 A52/AC3 Audiodekoder" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "A/52 Lautstärke" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" "Mit A/52 Audio kann die Lautstärke auf Dekoderebene verändert werden. Dies " "hat den Vorteil, dass die Audiodaten bereits für die spezifische Lautstärke " "dekodiert sind und nachfolgende Operationen wie Heruntermischen direkt mit " "diesen Audiodaten arbeiten können." #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "Benutze dynamische A/52 Bereichskomprimierung" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" "Dynamische Bereichskomprimierung reduziert den dynamischen Bereich des Tons: " "Laute Geräusche klingen leiser und leise Geräusche klingen lauter. Dies " "ermöglicht ein besseres Verständnis des Tons in lauten Umgebungen, ohne " "dabei andere zu stören." #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "Heruntermischen zu Zweikanal Stereo Raumklang" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" "Wählen sie dies, falls Sie Mehrkanal-Raumklang anhören wollen, aber nur zwei " "Lautsprecher oder einen Raumklang-Dekoder haben, der Matrix-Raumklang-" "Dekodierung wie ProLogic unterstützt, damit die zusätzlichen Kanäle in das " "Stereo-Signal gemixt werden." #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "A/52 Bass zu Stereo Lautstärke" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" "Mische den Bass-Effekt mit dieser Lautstärke ein,\n" "wenn Sie große Stereolautsprecher oder\n" "einen analogen Subwoofer haben." #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "DTS Audio Weiterleitung an externen Dekoder" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() schlug fehl.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 schlug fehl.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit schlug fehl.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "Freeware Advanced Audio Dekoder" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "FAAD Tonpegel anpassen (in dB)" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" "Manche AAC Tonspuren sind zu laut aufgenommen und klingen deshalb verzerrt.\n" "Die Lautstärkeeinstellung kann das nicht korrigieren, wohl aber diese " "Einstellung." #: src/audio_dec/xine_lpcm_decoder.c msgid "Linear PCM audio decoder plugin" msgstr "Linear PCM Audio Dekoder" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "libmad MPEG 1/2/3 Audio Dekoder" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "libmusepack: mpc_demux_init schlug fehl\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: mpc_streaminfo_read schlug fehl: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: Daten nach letztem Bild ignoriert\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: mpc_decoder_initialise schlug fehl\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: mpc_decoder_decode schlug fehl: %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "MusePack Audiodekoder" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out:Bereits geöffnet...WARUM?" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() von %s fehlgeschlagen: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>> Überprüfen Sie, ob ein anderen Programm PCM bereits " "benutzt<<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: Keine Konfiguration für dieses PCM Tongerät verfügbar: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "Geräte-Tonmischpult aktualisieren" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "Wenn sich die Einstellungen des Hardwaremixers ändern wird die Anwendung " "benachrichtigt, damit sie die grafische Darstellung des Mixers direkt " "aktualisieren kann." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : Unterstützte Modi sind" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4-Kanal nicht aktiviert in xine Konfiguration)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-Kanal" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-Kanal nicht aktiviert in xine Konfiguration)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5-Kanal" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5-Kanal nicht aktiviert in xine Konfiguration)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-Kanal nicht aktiviert in xine Konfiguration)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (a/52 und DTS Weiterleitung nicht aktiviert in xine Konfiguration)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() fehlgeschlagen: %d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Überprüfen Sie, ob ein anderen Programm bereits PCM benutzt <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8Bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16Bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24Bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32Bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "Soundkarte unterstützt mmap" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Aktivieren Sie dies, falls Ihre Soundkarte und der ALSA-Treiber direkten " "Speicherzugriff unterstützen.\n" "Sie können dies aktivieren und testen, ob alles funktioniert. Falls ja, " "erhöht es die Leistung." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " Mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "Gerät für Monoausgabe" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine benutzt dieses ALSA-Gerät für die Monoausgabe.\n" "Lesen Sie die ALSA-Dokumentation für Informationen zu ALSA-Geräten." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " Stereo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "Gerät für Stereoausgabe" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine benutzt dieses ALSA-Gerät für die Stereoausgabe.\n" "Lesen Sie die ALSA-Dokumentation für Informationen zu ALSA-Geräten." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-Kanal" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "Gerät für 4-Kanalausgabe" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine benutzt dieses ALSA-Gerät für die 4-Kanalausgabe (4.0 Raumklang).\n" "Lesen Sie die ALSA-Dokumentation für Informationen zu ALSA-Geräten." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-Kanal" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "Gerät für 5.1-Kanalausgabe" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine benutzt dieses ALSA-Gerät für die 5-Kanalausgabe mit Bassbox (5.1 " "Raumklang).\n" "Lesen Sie die ALSA-Dokumentation für Informationen zu ALSA-Geräten." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " a/52 und DTS Weiterleitung" #: src/audio_out/audio_alsa_out.c msgid "device used for a/52 and DTS pass-through" msgstr "Gerät für a/52 und DTS Weiterleitung" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine benutzt dieses ALSA-Gerät zur Weiterleitung von digitalem Raumklang an " "einen externen Dekoder.\n" "Lesen Sie die ALSA-Dokumentation für Informationen zu ALSA-Geräten." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() fehlgeschlagen: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "ALSA Tonmischpult" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine benutzt dieses ALSA Tonmischpult, um die Lautstärke zu ändern.\n" "Lesen Sie die ALSA-Dokumentation für Informationen zu ALSA-Geräten." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "xine Tonausgabe über ALSA-kompatibles Gerät/Treiber" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "xine Tonausgabe über Coreaudio/Mac OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Fehler" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "Erfolg" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "Zugriff verweigert" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "Ressource bereits in Benutzung" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "Objekt bereits initialisiert" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "Angegebenes wave-Format nicht unterstützt" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "Speicherpuffer verloren und muss wiederhergestellt werden" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "Angeforderter Puffereinstellung nicht verfügbar" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "Unbestimmter Fehler in DirectSound-System" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "DirectSound-Hardware nicht verfügbar" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "Funktion ist ungültig im aktuellen Zustand des Objekts" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "Ungültiger Parameter wurde übergeben" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "Objekt unterstützt keine Aggregation" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "Kein Ton-Treiber verfügbar" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "Angeforderte serielle Schnittstelle nicht verfügbar" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "Eine andere Anwendung hat Vorrang" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "Zu wenig Speicher" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "Niedrige Priorität für diese Funktion" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound wurde nicht initialisiert" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "Funktion wird nicht unterstützt" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "Unbekannter Fehler" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Kann DirectSound-Objekt nicht erzeugen." #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "Konnte DirectSound-Kooperationslevel nicht setzen." #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "Konnte keinen zweiten DirectSound-Puffer anlegen" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "Konnte Tonpuffer nicht wiedergeben" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "Konnte Tonwiedergabe nicht anhalten" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "Konnte Pufferposition nicht ermitteln" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "Konnte Pufferposition nicht setzen" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "Konnte Lautstärke nicht ändern" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": Puffer verloren, versuche wiederherzustellen\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "Konnte DirectSound-Puffer nicht belegen" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "Konnte DirectSound-Puffer nicht freigeben" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Konnte keinen primären DirectSound-Puffer erzeugen." #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" ": Wiedergabeposition überschritten (Daten %zu, min %zu), leere Puffer\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": Kann Puffer-PThread nicht erzeugen: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": Kann Puffer-PThread nicht freigeben: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ": Kann PThread-Bedingung nicht freigeben: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": Kann PThread-Mutex nicht freigeben: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr ": Unbekanntes Steuerkommando %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": Kann PThread-Bedingung nicht erzeugen: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": Kann PThread-Mutex nicht erzeugen: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "xine Tonausgabe über directx (zweite Variante)" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "xine Tonausgabe über directx für win32" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: Verbinde mit ESD Server %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: Verbinde mit ESD Server...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: Keine Verbindung zu ESD Server %s: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "Verzögerung der esd Tonausgabe (Verändert A/V Synchronisation)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Hier können Sie den Ton um /90000 Sekunden verzögern, um ihn mit dem " "Bild zu synchronisieren." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "xine Tonausgabe über esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "xine Tonausgabe in Datei" #: src/audio_out/audio_fusionsound_out.c msgid "xine FusionSound audio output plugin" msgstr "xine Tonausgabe über FusionSound" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "Maximal erlaubte Lücke für IRIXAL Tonausgabe" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Ab einem Bild-Ton-Versatz von /90000 Sekunden versucht xine, diesen zu " "korrigieren." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "xine Tonausgabe über IRIX-kompatibles Gerät/Treiber" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "\"Jack Audio\"-Gerätename" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "Der \"Jack Audio\"-Gerätename. Leer lassen, falls nicht bekannt." #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "xine Tonausgabe für JACK Audio System" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "Keine xine Tonausgabe" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Öffne Audiogerät %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: Warnung: Abtastrate %d Hz nicht unterstützt, versuche 44100 " "Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "audio_oss_out: Abtastrate: %d gefordert, %d angeboten\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "OSS Audio-Gerätename" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "Spezifizieren Sie den Basisgerätenamen, an den die OSS-Gerätenummer " "angehängt wird, um den vollen Gerätenamen zu erhalten.\n" "Wählen Sie \"auto\", falls xine automatisch die korrekte Einstellung wählen " "soll." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "OSS Audio-Gerätename, -1 für keinen" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Der Audio-Gerätename wird durch Aneinanderhängen des OSS-Gerätenamens und " "der Audio-Gerätenummer gebildet.\n" "Wenn Sie keine Nummer benötigen (weil alles bereits funktioniert), benutzen " "Sie -1.\n" "Der gültige Bereich ist -1 oder 0-15. Diese Einstellung wird ignoriert, " "falls OSS Audio-Gerätenamen auf \"auto\" steht." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "audio_oss_out: audio.device.oss_device_name = auto, suche Geräte\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Automatische Suche nach Audiogeräten fehlgeschlagen\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: Benutze Gerät >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "audio_oss_out: Öffnen des Audiogeräts %s fehlgeschlagen: %s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "A/V Synchronisationsmethode für OSS" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "xine kann verschiedene Methoden benutzen, um Audio und Video zu " "synchronisieren. Welche Einstellung am besten ist hängt vom OSS Treiber und " "der benutzten Tonhardware ab. Versuchen Sie verschiedene Methoden, falls Sie " "Synchronisationsprobleme bemerken.\n" "\n" "Die Bedeutung der Werte ist wie folgt:\n" "\n" "auto\n" "xine versucht automatisch die besten Einstellungen zu erkennen\n" "\n" "getodelay\n" "Benutzt ioctl(SNDCTL_DSP_GETODELAY) selbst dann, wenn der Treiber keine " "Echtzeitwiedergabe anbietet\n" "\n" "getoptr\n" "Benutzt ioctl(SNDCTL_DSP_GETOPTR) selbst dann, wenn der Treiber das " "bevorzugte ioctl(SNDCTL_DSP_GETODELAY) anbietet\n" "\n" "softsync\n" "Benutzt Softwaresynchronisation mit der Systemuhr; Audio und Video können " "weit auseinanderdriften, wenn die Systemuhrgeschwindigkeit nicht exakt mit " "der Wiedergabegeschwindigkeit der Soundkarte übereinstimmt\n" "\n" "probebuffer\n" "Testet die Puffergröße der Soundkarte bei der Initialisierung, um die " "Verzögerung zur A/V Synchronisation zu berechnen. Versuchen Sie dies, falls " "Ihr System keine ioctls zu Echtzeitwiedergabe anbietet und " "Synchronisationsprobleme nach langer Wiedergabe auftreten." #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Audio-Echtzeit-Synchronisation deaktiviert...\n" "audio_oss_out: ...System-Realzeituhr wird zur soft-Synchronisation benutzt\n" "audio_oss_out: ...es können Bild/Ton-Gleichlaufprobleme auftreten\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "Verzögerung der OSS Audioausgabe (Verändert A/V Synchronisation)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Audio-Echtzeit-Synchronisation deaktiviert...\n" "audio_oss_out: ...Untersuche Größe des Ausgabepuffers: %d Bytes\n" "audio_oss_out: ...es können Bild/Ton-Gleichlaufprobleme auftreten\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: Unterstützte Modi sind" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " a/52 Weiterleitung" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (a/52 Weiterleitung nicht aktiviert in xine Konfiguration)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "OSS Mischpultnummer, -1 für keine" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Der Mischpult-Gerätename wird durch Ersetzen von \"dsp\" durch \"mixer\" im " "OSS Audio-Gerätenamen und durch Anhängen der Mixernummer gebildet.\n" "Wenn Sie keine Nummer benötigen (weil alles bereits funktioniert), benutzen " "Sie -1.\n" "Der gültige Bereich ist -1 oder 0-15. Diese Einstellung wird ignoriert, " "falls OSS Audio-Gerätenamen auf \"auto\" steht." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: open() Mischpult %s fehlgeschlagen: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "xine Tonausgabe über OSS-kompatibles Gerät/Treiber" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "Gerät für Pulse-Audio" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "Geben Sie das Pulse Audio Gerät so an: 'Server[:Senke]'." #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr "a/52 Weiterleitung verwenden" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "Audiodaten an einen externen digitalen Raumklangdekoder weiterleiten." #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "xine Tonausgabe über Pulse-Audio Soundserver" #: src/audio_out/audio_sndio_out.c msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "xine Tonausgabe über sndio" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: Öffnen des Audiogeräts %s fehlgeschlagen: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "Sun Audio-Gerätename" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Gibt den Namen für das Sun Audiogerät an.\n" "ACHTUNG: Eine falsche Angabe überschreibt eine Datei dieses Namens mit " "riesigen Datenmengen! Also besser doppelt prüfen." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "audio_sun_out: Audio ioctl auf Gerät %s schlug fehl: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "xine Tonausgabe über SUN-kompatibles Gerät/Treiber" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "Lautsprecherplatzierung" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Wählen Sie, wie Ihre Lautsprecher angeordnet sind. Darüber wird gewählt, " "welche Lautsprecher xine für die Ausgabe verwendet. Mögliche Werte sind:\n" "\n" "Mono 1.0: Sie haben nur einen Lautsprecher.\n" "Stereo 2.0: Sie haben zwei Lautsprecher (vorn links und rechts).\n" "Headphones 2.0: Sie benutzen einen Kopfhörer.\n" "Stereo 2.1: Sie haben drei Lautsprecher (vorn links und rechts, plus Bass).\n" "Surround 3.0: Sie haben drei Lautsprecher (vorn links und rechts, plus Mitte " "hinten).\n" "Surround 4.0: Sie haben vier Lautsprecher (vorn und hinten, je links und " "rechts).\n" "Surround 4.1: Wie 4.1, plus Bass.\n" "Surround 5.0: Sie haben fünf Lautsprecher (vorn links, Mitte, rechts und " "hinten links und rechts.\n" "Surround 5.1: Wie 5.1, plus Bass.\n" "Surround 6.0: Sie haben sechs Lautsprecher (vorn und hinten, je links, Mitte " "und rechts).\n" "Surround 6.1: Wie 6.1, plus Bass.\n" "Surround 7.1: Sie haben sieben Lautsprecher (vorn links, Mitte und rechts, " "Mitte links und rechts, hinten links und rechts plus Bass.\n" "Pass Through: Sie haben einen digitalen Raumklangdekoder, der mit dem " "Digitalausgang Ihrer Soundkarte verbunden ist." #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat input plugin" msgstr "libavformat-Eingabe" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "libavformat Demultiplexer" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_audio_dec: Vergrößere Puffer auf %d um Überlauf zu vermeiden.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_audio_dec: Konnte keinen ffmpeg-Dekoder für Puffertyp 0x%X finden\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: Versuche Null-Codec zu öffnen\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: Konnte Dekoder nicht öffnen\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "ffmpeg_audio_dec: Dekodereinstellungen geändert\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "ffmpeg_audio_dec: Konnte Dekodereinstellungen nicht lesen\n" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "FFMpeg Audiodekoder" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "FFmpeg Tonpegel anpassen (in dB)" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" "Manche AAC und WMA Tonspuren sind zu laut aufgenommen und klingen deshalb " "verzerrt.\n" "Die Lautstärkeeinstellung kann das nicht korrigieren, wohl aber diese " "Einstellung." #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "ffmpeg_video_dec: Nicht unterstütztes Bildformat, DR1 deaktiviert.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: Nicht unterstütztes Bildformat, DR1 deaktiviert.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: Direktausgabe aktiviert\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" "ffmpeg_video_dec: Kein geeignetes Bildformat zum Dekodieren per Hardware\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "ffmpeg_video_dec: erzwinge AVDISCARD_DEFAULT bei VAAPI\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: Konnte Dekoder nicht öffnen\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: Konnte Dekoder nicht öffnen\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_video_dec: Vergrößere Puffer auf %d um Überlauf zu vermeiden.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: %d DR1-Bilder verwendet.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_video_dec: Konnte keinen ffmpeg-Dekoder für Puffertyp 0x%X finden\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "ffmpeg_video_dec: VAAPI MPEG 1/2 Software Dekodierung %d\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "ffmpeg_video_dec: VAAPI eingeschaltet in Konfiguration\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "ffmpeg_video_dec: VAAPI vom Grafiktreiber abgeschaltet.\n" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "FFMpeg Videodekoder" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "Qualität der MPEG-4 Nachbearbeitungsstufe" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "Die Umfang der Nachbearbeitung bei MPEG-4 Videos kann angepasst werden.\n" "Höhere Werte verbessern die Qualität bei mehr CPU-Belastung. Niedrige Werte " "können zu Defekten wie Artefakte führen. Bei hochqualitativen Inhalten kann " "zu starke Nachbearbeitung das Bild durch zu starkes verwischen " "verschlechtern." #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "Anzahl parallel arbeitender FFMpeg Videodekoder" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Höhere Werte können schneller sein - abhängig vom Typ des Videos.\n" "Versuchen Sie die Anzahl Ihrer Prozessorkerne (üblicherweise 1..4).\n" "Änderungen wirken ab dem nächsten abgespielten Video." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "Nachfilter weglassen" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Gibt an, für welche Bildtypen auf eine Filterung nach dem Dekodieren " "verzichtet werden soll:\n" " none: Alle Bilder nachfiltern. Gute Bildqualität, aber langsam.\n" " nonref: Nur mehrfach genutzte Bilder nachfiltern.\n" " bidir: Nur I- und P-Bilder nachfiltern.\n" " nonkey: Nur I-Bilder nachfiltern.\n" " all: Nichts nachfiltern. Schnell, aber oft schlechtes Bild.\n" " default: Automatisch wählen.\n" "Änderungen wirken ab dem nächsten abgespielten Video." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "Arbeite schneller, wenn auch ungenauer" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Erlaube diverse Tricks welche das Dekodieren beschleunigen, aber die " "offizielle Formatbeschreibung verletzen und somit Bildfehler riskieren.\n" "Änderungen wirken ab dem nächsten abgespielten Video." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "Direktausgabe benutzen" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" "Deaktivieren Sie die Direktausgabe, falls Videos mit vielen mehrfach " "genutzten Bildern beim Abspielen hängenbleiben." #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "VAAPI MPEG 1/2 Software-Dekodierung" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "Versuchen Sie dies, wenn das Abspielen von MPEG 1/2 hängen bleibt." #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "VAAPI einschalten" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "VAAPI ein- oder ausschalten" #: src/combined/ffmpeg/input_avio.c msgid "libavio input plugin" msgstr "libavio Eingabe" #: src/combined/flac_decoder.c msgid "flac audio decoder plugin" msgstr "FLAC Audio Dekoder" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "FLAC Demultiplexer" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "NES Music Audio Dekoder" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "NES Music Demultiplexer" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "wavpack Audio Dekoder" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "wavpack Demultiplexer" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "ogg: vorbis Tonspur eingetragen aber nicht vorhanden.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "Annodex Demultiplexer" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "OGG Demultiplexer" #: src/combined/xine_speex_decoder.c msgid "Speex audio decoder plugin" msgstr "Speex Audio Dekoder" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "theora Videodekoder" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: Vergrößere Puffer auf %d um Überlauf zu vermeiden.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "vorbis Audio Dekoder" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "4X Technologies (4xm) Demultiplexer" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "ADIF/ADTS AAC Demultiplexer" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "Raw AC3 Demultiplexer" #: src/demuxers/demux_aiff.c msgid "AIFF file demux plugin" msgstr "AIFF Datei-Demultiplexer" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "demux_asf: Warnung: Ein Datenstrom fehlt?\n" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "Ein Datenstrom fehlt?" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: Warnung: Datenstrom id=%d ist verschlüsselt.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Medienstrom verschlüsselt" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "ASF Demultiplexer" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "Westwood Studios AUD Datei-Demultiplexer" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Stelle Index wieder her..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "demux_avi: Ungültiges AVI-Paket \"%c%c%c%c\" an Position %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: AVI-Index ist fehlerhaft\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" "demux_avi: Positionierung zum nächsten Paket (Position %) schlug " "fehl\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "AVI/RIFF Demultiplexer" #: src/demuxers/demux_cdda.c msgid "CD Digital Audio demux plugin" msgstr "Audio CD Demultiplexer" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "Raw DTS Demultiplexer" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "Electronics Arts WVE Demultiplexer" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "Elementary MPEG stream Demultiplexer" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "Ungültige Größe des FILM-Pakets\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "Nicht erkanntes FILM-Paket\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "FILM (CPK) Demultiplexer" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "Free Lossless Audio Codec (flac) Demultiplexer" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "Autodesk Animator FLI/FLC Demultiplexer" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "demux_flv: Ignoriere fehlerhaften Suchindex.\n" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" "demux_flv: Diese Datei ist nicht spulbar. Ein Bild-Ton-Versatz kann " "auftreten.\n" " Empfehle, die Datei mittels eines geeigneten \"flvtool\" zu " "reparieren.\n" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "Nicht unterstützte FLV-Version (%d).\n" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "Weder Bild noch Ton in dieser Datei.\n" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "FLV Demultiplexer" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "Id Quake II Cinematic Datei-Demultiplexer" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: Unbekannte Kompression: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: Unbekannte Kompression: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: Unbekanntes Paket: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "IFF Demultiplexer" #: src/demuxers/demux_image.c msgid "image demux plugin" msgstr "Standbild-Demultiplexer" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "Interplay MVE Movie Demultiplexer" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "IVF Demultiplexer" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "matroska & webm Demultiplexer" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "Multiple-image Network Graphics Demultiplexer" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "ModPlug Amiga MOD Music Datei-Demultiplexer" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: Bild zu groß für Puffer" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "Musepack Demultiplexer" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: Unbekannte Strom-Kennung 0x%02x. Bitte bei den " "xine-Entwicklern melden.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: Fehler! Abbruch. Bitte bei den xine-Entwicklern melden.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: Warnung: PES-Header reservierte 10 Bits nicht gefunden\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: Warnung: PES-Header deutet an, das dieser Datenstrom " "verschlüsselt sein könnte (Verschlüsselungsmodus %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "DVD/VOB Demultiplexer" #: src/demuxers/demux_mpeg.c msgid "MPEG program stream demux plugin" msgstr "MPEG program stream Demultiplexer" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_ps: Unbekannte Strom-Kennung 0x%02x. Bitte bei den xine-" "Entwicklern melden.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: Warnung: PACK-Datenstrom id=0x%x Dekodierung " "fehlgeschlagen.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: Warnung: PES-Header reserviert 10 Bits nicht gefunden\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: Warnung: PES-Header deutet an, das dieser Datenstrom " "verschlüsselt sein könnte (Verschlüsselungsmodus %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes:Unbekannter privater Datenstrom 1 0x%02x. Bitte bei den xine-" "Entwicklern melden.\n" "melden\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "MPEG-PES Demultiplexer" #: src/demuxers/demux_mpgaudio.c msgid "MPEG audio demux plugin" msgstr "MPEG audio Demultiplexer" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "Nullsoft Video Demultiplexer" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "Playlist Demultiplexer" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "TechnoTrend PVA Demultiplexer" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "demux_qt: %d Medienfragmente hinzugefügt\n" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "Quicktime (MOV) und MPEG-4 Demultiplexer" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "Einfacher DV Video Datenstrom" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "RealAudio Datei-Demultiplexer" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "RealMedia Demultiplexer" #: src/demuxers/demux_roq.c msgid "Id RoQ file demux plugin" msgstr "Id RoQ Datei-Demultiplexer" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "Shorten Demultiplexer" #: src/demuxers/demux_smjpeg.c msgid "SMJPEG file demux plugin" msgstr "SMJPEG Demultiplexer" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: Ungültige Dateikopf-Parameter\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: Nicht unterstützter Audiotyp: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "SND/AU Demultiplexer" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "Sony Playstation STR Demultiplexer" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "MPEG Transport Stream Demultiplexer" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "demux_tta: Gesamt-Bildanzahl zu hoch\n" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "True Audio Demultiplexer" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "VC1 elementary stream Demultiplexer" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "Sierra VMD Demultiplexer" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "Unbekannter VOC-Blocktyp (0x%02X); bitte bei den xine-Entwicklern melden\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "Unbekannter VOC-Kompressionstyp (0x%02X); bitte bei den xine-Entwicklern " "melden\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "VOC Demultiplexer" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "Dialogic VOX Demultiplexer" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "Westwood Studios VQA Demultiplexer" #: src/demuxers/demux_wav.c msgid "WAV file demux plugin" msgstr "WAV Demultiplexer" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "demux_wc3movie: SHOT Paket referenziert ungültige Palette (%d >= %d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "demux_wc3movie: Beim Laden der Palette ist ein Problem aufgetreten\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "Wing Commander III Movie (MVE) Demultiplexer" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "YUV4MPEG2 Demultiplexer" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "YUV frames Demultiplexer" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "Untertiteldekoder welcher die DXR3 Karte verwendet" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Öffnen des Untertitel-Geräts %s schlug fehl (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_spu: Schreibzugriff auf Video-Gerät schlug fehl (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "Angeforderter Knopf nicht verfügbar\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "MPEG1/2 Dekoder welcher die DXR3 Karte verwendet" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "dxr3_decode_video: Öffnen des Steuer-Geräts %s schlug fehl (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "Benutze Pan & Scan Informationen" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Pan & Scan\" ist ein spezieller Darstellungsmodus, der manchmal in MPEG " "kodiertem Material verwendet wird. Sie können hier wählen, wie solche " "Inhalte behandelt werden sollen.\n" "\n" "only when forced\n" "Pan & Scan nur benutzen, wenn ausdrücklich verlangt.\n" "\n" "use MPEG hint\n" "Pan & Scan entsprechend den Informationen im MPEG-Videostrom benutzen.\n" "\n" "use DVB hint\n" "Pan & Scan entsprechend den \"Active Format Descriptor\" (AFD) Informationen " "benutzen. Diese finden sich in manchen europäischen DVB-Datenströmen." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "Versuche Video mit jedem Bild zu synchronisieren" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" "Zeitmarken zur Synchronisationen für jedes Einzelbild erzeugen. " "Normalerweise ist dies nicht nötig, da es zur Synchronisation ausreicht, " "wenn nur ab und zu Zeitmarken erzeugt werden.\n" "Dies ist nur für progressive Videos (die meisten PAL Filme) relevant." #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "Benutze weichen Wiedergabemodus" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Das Aktivieren dieser Option sorgt für eine flüssigere Wiedergabe." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "Korrigiere Bilddauer in fehlerhaften Videos" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" "Aktiviert eine Logik zur Korrektur falscher Bilddauern in einigen MPEG " "Videos mit falschen Bildwiederholratencodes. Momentan ist eine Korrektur für " "NTSC Ströme implementiert, die fälschlicherweise als PAL markiert sind. " "Aktivieren Sie dies nur, wenn Sie einen solchen Datenstrom antreffen." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Öffnen des Video-Geräts %s schlug fehl (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "dxr3_decode_video: Schreibzugriff würde blockieren. Leeren\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: Schreibzugriff auf Video-Gerät schlug fehl (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" "dxr3_decode_video: WARNUNG: Unbekannter Code für Bildwiederholrate %d\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: WARNUNG: Korrigiere Code für Wiederholrate von PAL zu " "NTSC\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "DXR3 Gerätenummer" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Falls Sie mehr als eine DXR3 in Ihrem Computer haben, können Sie hier " "angeben, welche benutzt werden soll." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: Initialisierung von librte schlug fehl\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte unterstützt nur Bildgrößen, die Vielfache von 16 " "sind\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: rte-Kontext konnte nicht geholt werden.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: CODEC konnte nicht erzeugt werden.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "Bitrate der librte MPEG Wiedergabe (kBit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "Bitrate für die MPEG-Enkodierungsbibliothek librte zur DXR3 Enkodierung. " "Höhere Werte verbessern die Qualität, aber brauchen mehr Rechenleistung." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: Konnte Kontext nicht initialisieren: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: Kodierung kann nicht gestartet werden: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: FAME-Bibliothek konnte nicht gestartet werden\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "fame-MPEG-Enkodierungsqualität" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "Die Enkodierungsqualität für die MPEG-Enkodierungsbibliothek libfame. " "Niedrige Werte sind schneller, produzieren aber Artefakte. Höhere Werte " "verbessern die Qualität, brauchen aber mehr Rechenleistung." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "SCR-Plugin Priorität" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" "Priorität für das DXR3 SCR-Plugin. Werte kleiner 5 führen dazu, dass die " "UNIX Systemuhr zur Synchronisation benutzt wird; Werte größer 5 erzwingen " "die Verwendung der internen Uhr der DXR3 als Synchronisationsquelle." #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "libavcodec MPEG Ausgangsbitrate (kBit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" "Bitrate für die MPEG-Enkodierungsbibliothek libavcodec zur DXR3 Enkodierung. " "Höhere Werte verbessern die Qualität bei höherer CPU-Belastung.\n" "Diese Einstellung ist nur wirksam, wenn der Modus für konstante Qualität " "deaktiviert ist." #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "Modus für konstante Qualität" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" "Falls aktiviert benutzt libavcodec einen Modus für konstante Qualität, bei " "der Bilder je nach Komplexität dynamische komprimiert werden. Anderenfalls " "benutzt libavcodec eine Modus mit konstanter Bitrate." #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "Minimale Kompression" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "Minimale Kompression für ein Bild im Modus konstanter Qualität" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "Maximaler Quantisierer" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "Maximale Kompression für ein Bild im Modus konstanter Qualität" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "Bildausgabe über die DXR3 Karte" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Öffnen des Steuer-Geräts %s schlug fehl (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "Vertausche gerade und ungerade Zeilen" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" "Vertauscht die geraden und ungeraden Zeilen des Bildes.\n" "Aktivieren Sie diese Option für nicht-MPEG-Material, welches ein vertikales " "Zittern am Bildschirm zeigt." #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "Schwarze Balken zur Korrektur des Seitenverhältnisses hinzufügen" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Fügt dem Bild schwarze Balken hinzu, falls die Karte das Seitenverhältnis " "nicht direkt verarbeiten kann." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "Benutze weichen Wiedergabemodus für MPEG-kodierte Wiedergabe" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Das Aktivieren dieser Option sorgt für eine flüssigere Wiedergabe von nicht-" "MPEG-Inhalten." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Öffnen des Video-Geräts %s schlug fehl (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "Der Koder für nicht-MPEG-Inhalte" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "Andere Inhalte als MPEG müssen eine zusätzliche Rekodierungsstufe " "durchlaufen, da die DXR3 nur MPEG verarbeiten kann.\n" "Je nach dem was xine unterstützt, kann diese Einstellung \"fame\", \"rte\" " "\"libavcodec\" oder \"none\" sein.\n" "Der \"libavcoder\" benutzt das ffmpeg Plugin, das bereits mit xine " "ausgeliefert wird, so dass keine zusätzlichen Bibliotheken gebraucht werden. " "libavcoder liefert sogar eine sehr hohe Qualität bei niedriger CPU " "Belastung, weshalb libavcodec besonders empfohlen wird.\n" "\"fame\" und \"rte\" werden noch angeboten, aber die xine-Unterstützung für " "sie ist veraltet und evtl. sogar defekt." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" "video_out_dxr3: MPEG-Kodierer libavcodec konnte nicht initialisiert werden.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: MPEG-Kodierer rte konnte nicht initialisiert werden.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "" "video_out_dxr3: MPEG-Kodierer fame konnte nicht initialisiert werden.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: MPEG-Kodierung deaktiviert.\n" "video_out_dxr3: Das ist unproblematisch für MPEG-Videos wie DVDs, aber\n" "video_out_dxr3: Sie können keine nicht-MPEG-Inhalte mit diesem Video-" "Treiber\n" "video_out_dxr3: wiedergeben. Lesen Sie README.dxr3, um einen Kodierer zu " "konfigurieren.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Kein MPEG-Kodierer mitgeliefert.\n" "video_out_dxr3: Das ist unproblematisch für MPEG-Videos wie DVDs, aber\n" "video_out_dxr3: Sie können keine nicht-MPEG-Inhalte mit diesem Video-" "Treiber\n" "video_out_dxr3: wiedergeben. Lesen Sie README.dxr3, um einen Kodierer zu " "konfigurieren.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "Videoausgabemodus (TV oder Einblendung)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" "Legt fest, wie die DXR3 das endgültige Video ausgeben soll. Gültige Werte " "sind:\n" "\n" "letterboxed tv\n" "Video wird nur über den TV-Ausgang ausgegeben. Dieser Modus wird für normale " "4:3 Fernseher benutzt. Anamorphische (16:9) Videos werden gestaucht " "wiedergegeben, Pan&Scan-Material wird links und rechts beschnitten. Dies ist " "die Standardeinstellung zum Fernsehen und verhält sich wie ein " "eigenständiger DVD Player.\n" "\n" "widescreen tv\n" "Video wird nur über den TV-Ausgang ausgegeben. Dieser Modus wird für 16:9 " "Breitbildfernseher benutzt. Anamorphische und Pan&Scan-Inhalte füllen das " "ganze Bild aus, aber das Seitenverhältnis muss manuell auf 16:9 gestellt " "werden.\n" "letterboxed overlay\n" "Overlay Videoausgabe auf dem Computerbildschirm mit optionaler " "Sofortumschaltung auf TV-Ausgabe durch Verstecken des Videofensters. Das " "Overlay wird mit schwarzen Rändern angezeigt, falls es anamorph (16:9) ist.\n" "Diese Einstellung ist nur in den seltenen Fällen nützlich, wenn DVD " "Untertitel nur korrekt im \"letterboxed\"-Modus dargestellt werden. Ein " "gutes Beispiel dafür ist die animierte Kommentatorensilhouletten in " "\"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Videoausgabe auf dem Computerbildschirm mit optionaler " "Sofortumschaltung auf TV-Ausgabe durch Verstecken des Videofensters. Dies " "ist die Standardvariante bei DXR3 Einblendungen." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "Farbwert für Einblendung" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Hexadezimaler RGB-Wert für Farbschlüssel.\n" "Sie können verschiedene Werte probieren, falls bei der Benutzung des DXR3-" "Einblendmodus Fenster transparent werden." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "Farbvarianz für Einblendung" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" "Ein höherer Wert vergrößert die Toleranz für den Farbschüssel.\n" "Sie können niedrigere Werte probieren, falls bei der Benutzung des DXR3-" "Einblendmodus Fenster transparent werden; bei zu niedrigen Werten können " "Teile der Bildränder verschwinden." #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "Beschneide Einblendungen oben und unten" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Entfernt eine Pixelzeile am oberen und unteren Rand von Einblendungen. " "Aktivieren Sie dies, falls Sie grüne Linien am oberen oder unteren Rand " "sehen." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: Starten Sie autocal, Überlagerung deaktiviert\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "Bevorzugter TV-Modus" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Wählt den TV-Modus der DXR3. Die Werte bedeuten:\n" "\n" "ntsc: NTSC bei 60Hz\n" "pal: PAL bei 50Hz\n" "pal60: PAL bei 60Hz\n" "default: Einstellungen der Karte beibehalten" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: Setzen des Videomodus schlug fehl.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: Benötige einen MPEG-Kodierer zum Abspielen von nicht-MPEG-" "Videos on dxr3\n" "video_out_dxr3: Lesen Sie README.dxr3 für Details.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: Fehler beim Lesen der Überlagerungsdatei. Starten Sie " "autocal!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "BluRay-Eingabe" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "Lokales BluRay Verzeichnis" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "Pfadangabe wohin BluRay's eingebunden werden sollen." #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "Gerät für BluRay Wiedergabe" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "Pfadangabe zum Gerät, das zur Wiedergabe von BluRays benutzt werden soll." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "Standardsprache für die BluRay-Wiedergabe" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" "xine versucht diese Sprache als Standard bei der BluRay-Wiedergabe. Sofern " "die Scheibe dies unterstützt, werden Menüs und Titel in dieser Sprache " "angezeigt.\n" "Der Wert muss ein dreibuchstabiger ISO639-2-Sprachcode sein." #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "BluRay Länderkennung" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "Der Wert muss eine zweibuchstabige ISO3166-1 Länderkennung sein." #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "BluRay Länderkennung (1=A, 2=B, 4=C)" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" "Diese Einstellung muss nur geändert werden, falls die BluRay auf einem Bild " "stehenbleibt, wo sich über eine falsche Länderkennung beschwert wird. Dies " "hat nichts mit der Laufwerkseinstellung zu tun, dies ist nur für die " "Software." #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "Jugendschutz-Mindestalter (1-99)" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "Verhindert das Abspielen von Titeln mit höherer Altersfreigabe" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "Einheit für die Überspringen-Aktion" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" "Hier können Sie die Funktion der \"Weiter\"- und \"Zurück\"-Tasten " "einstellen." #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "BluRay Eingabe (mit Menüs)" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: Kann keine Verbindung zu '%s:%d' aufbauen\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: Verbindung zum CDDB-Server '%s:%d' steht.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" "input_cdda: Kann keine Verbindung zum CDDB-Server '%s:%d' (%s) herstellen.\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "CD Digital Audio (CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "Gerät für CD-Audio" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "Pfadangabe zum Gerät (normalerweise CD oder DVD Laufwerk), das zur " "Wiedergabe von Audio-CDs benutzt werden soll." #: src/input/input_cdda.c msgid "query CDDB" msgstr "CDDB abfragen" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" "Aktiviert CDDB-Abfragen zum abfragen von Titelinformationen für Audio-CDs.\n" "Vergessen Sie nicht, dass sofern Sie keine private CDDB benutzen, diese " "Informationen von einem Internetserver bezogen werden, der ein Profil Ihrer " "Hörgewohnheiten erstellen kann." #: src/input/input_cdda.c msgid "CDDB server name" msgstr "CDDB Servername" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" "Der CDDB-Server, von dem Titelinformationen bezogen werden.\n" "Diese Einstellung ist Sicherheitskritisch, da der Server Informationen zu " "Ihren Hörgewohnheiten erhält und bösartige Antworten senden kann. Geben Sie " "nur einen Server ihres Vertrauens an." #: src/input/input_cdda.c msgid "CDDB server port" msgstr "CDDB Serverport" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "Der Serverport, vom dem Titelinformationen bezogen werden sollen." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "Laufwerk auf diesen Faktor verlangsamen" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" "Da einige CD- und DVD-Laufwerke durch hohe Umdrehungsgeschwindigkeiten viel " "Lärm produzieren, versucht xine sie zu bremsen. Für die Standardwiedergabe " "von CDs und DVDs werden keine hohen Datenraten benötigt, die eine hohe " "Umdrehungsgeschwindigkeiten erfordern, weshalb das Bremsen keinen Einfluss " "auf die Wiedergabeleistung haben sollte.\n" "Ein Wert von Null deaktiviert das Bremsen." #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "input_dvb: Öffnen der DVB-Kanaldatei '%s' schlug fehl: %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "input_dvb: DVB-Kanaldatei '%s' ist keine Datei??\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: tuner_set_channel schlug fehl\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "input_dvb: DVB Benutzeroberfläche %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: Kann DVB-Gerät nicht öffnen\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "input_dvb: Kanal %d außerhalb des Bereichs, benutze 0\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: Suche nach Kanal %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" "input_dvb: Keine exakte Übereinstimmung für %s gefunden: versuche teilweise " "Übereinstimmung\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: Übereinstimmung mit Kanal %s gefunden\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" "input_dvb: Kanal %s nicht in channels.conf gefunden, verwende " "Standardkanal.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" "input_dvb: Ungültige Kanalspezifikation, benutze zuletzt gesehenen Kanal.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "input_dvb: Ungültige Kanalspezifikation, benutze Kanal 0\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" "input_dvb: DVB-S Medienadresse angegeben, aber Tuner scheint kein QPSK (DVB-" "S) zu sein\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: DVB-T Medienadresse angegeben, aber Tuner scheint kein OFDM (DVB-" "T) zu sein\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: DVB-C Medienadresse angegeben, aber Tuner scheint kein QAM (DVB-" "C) zu sein\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" "input_dvb: DVB-C Medienadresse angegeben, aber Tuner scheint kein ATSC (DVB-" "A) zu sein\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: Kann DVR-Gerät '%s' nicht öffnen\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "input_dvb: Kann EPG-Aktualisierungsthread nicht erstellen\n" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "Benutze DVB Ausschnittvergrößerung" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Dies erlaubt Vollbildwiedergabe von 4:3 Inhalten, die in 16:9 übertragen " "werden." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "DVB (Digital TV) Plugin" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Zuletzt gesehenen DVB-Kanal merken" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" "Bei automatischer Wiedergabe wechselt xine zum zuletzt gesehenen Kanal " "(media.dvb.last_channel). " #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Zuletzt gesehener DVB-Kanal" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "Falls aktiviert merkt sich xine den Kanal und wechselt zu diesem. " #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "Versuche so viele Sekunden, einen Sender einzustellen." #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "Mindestens 5, 0 = 'unbegrenzt'." #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "DVB Benutzeroberfläche einschalten" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "Aktiviere mausgesteuerte Kanalumschaltung und Aufzeichnung." #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Nummer der zu benutzenden DVB-Karte." #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" "Belassen Sie den Wert 0, außer Sie haben mehr als eine Karte in ihrem System." #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "input_dvd: Werte von \\beta werden dom erhöhen!\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Fehler beim Lesen des nächsten Blocks von DVD (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Fehler beim Öffnen des DVD-Geräts\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "DVD-Navigator" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "Gerät für DVD Wiedergabe" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "Pfadangabe zum Gerät (normalerweise ein DVD Laufwerk), das zur Wiedergabe " "von DVDs benutzt werden soll." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "CSS Entschlüsselungsmethode" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" "Wählt die Entschlüsselungsmethode, die libdvdcss zum entschlüsseln von " "kopiergeschützten DVDs verwenden soll. Versuchen Sie die verschiedenen " "Methoden, falls Probleme bei der Wiedergabe von verschlüsselten DVDs " "auftreten." #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "Region (1-8), aus der der DVD Player zu kommen scheint" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "Diese Einstellung muss nur geändert werden, falls die DVD auf ein Bild, wo " "sich über ein falscher Regionscode beschwert wird. Dies hat nichts mit dem " "Regionscode im DVD-Laufwerk zu tun, dies ist nur für die Software." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "Standardsprache für die DVD-Wiedergabe" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine versucht diese Sprache als Standard bei der DVD-Wiedergabe. Sofern die " "DVD dies unterstützt, werden Menüs und Titel in dieser Sprache angezeigt.\n" "Der Wert muss ein zweibuchstabiger ISO639-Sprachcode sein." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "Vorauslesen benutzen" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" "xine kann einen vorauseilenden Cache für DVD-Laufwerkszugriffe verwenden.\n" "Dies kann bei langsamen Laufwerken zu einer stotternden Wiedergabe führen, " "verringert aber den Einfluss von DVD-Ebenenwechseln bei schnellen Laufwerken." #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" "Das Verhalten beim Überspringen-Kommando (z.B. beim benutzen des " "Überspringen-Knopf) ist konfigurierbar. Die Werte bedeuten:\n" "\n" "skip program\n" "Überspringt eine DVD-Programm, was eine Navigationseinheit ähnlich der " "Indexmarkierung einer Audio-CD ist; dies ist das normale Verhalten von DVD " "Playern\n" "\n" "skip part\n" "Überspringt eine DVD-Abschnitt, was eine Struktureinheit ähnlich einem Track " "einer Audio-CD ist; Abschnitte entsprechen normalerweise Programmen, können " "aber größer als sie sein\n" "\n" "skip title\n" "Überspringt eine DVD-Titel, was eine Struktureinheit ist, die einem " "kompletten DVD Film entspricht" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "Einheit beim Suchen" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" "Legt den Suchbereich des Positionsschiebers fest. Die Werte bedeuten:\n" "\n" "seek in program chain\n" "Der Suchbereich umfasst die komplette DVD-Programmkette, entsprechend dem " "kompletten aktuellen Film\n" "\n" "seek in program\n" "Der Suchbereich umfasst ein DVD-Programm, entsprechend einem Kapitel des " "aktuellen Films" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "Wiedergabemodus falls Titel/Kapitel angegeben" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" "Legt das Verhalten der Wiedergabe von DVDs fest, wenn ein Titel/Kapitel (z." "B. per Medienadresse 'dvd:/1.2') angegeben wird. Die Werte bedeuten:\n" "\n" "entire dvd\n" "Wiedergabe der gesamten DVD ab der angegebenen Position.\n" "\n" "one chapter\n" "Nur Wiedergabe des angegebenen Titels/Kapitels, danach Stopp." #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Zugriff verweigert: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Datei nicht gefunden: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: Datei leer: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "Datei-Eingabe" #: src/input/input_file.c msgid "file browsing start location" msgstr "Startverzeichnis für Dateisuche" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "Die Dateiauswahl startet an dieser angegebenen Pfadposition" #: src/input/input_ftp.c msgid "FTP input plugin" msgstr "FTP-Eingabe" #: src/input/input_ftp.c msgid "FTPES input plugin" msgstr "FTPES-Eingabe" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "Xine-eigene gnome-vfs-Eingabe" #: src/input/input_helper.c msgid "list hidden files" msgstr "Versteckte Dateien zeigen" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "Falls aktiviert, zeigt die Dateiauswahl auch versteckte Dateien." #: src/input/input_helper.c msgid "Default servers" msgstr "Standardserver" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" "Ein oder mehrere durch Leerzeichen getrennte Serveradressen für die " "Medienauswahl (z.B. \"ftp://ftp3.itu.int sftp://user:pass@host.com\")" #: src/input/input_hls.c msgid "HTTP live streaming input plugin" msgstr "HTTP live streaming Eingabe" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s) schlug fehl: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: Lesefehler %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Kontaktiere HTTP Server..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: Ungültige http-Antwort\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: 3xx Weiterleitung : >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: http-Status ungleich 2xx: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: Inhaltslänge = % bytes\n" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: Puffer erschöpft nach %zu Bytes." #: src/input/input_http.c msgid "http/https input plugin" msgstr "HTTP(S)-Eingabe" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "HTTP Proxy Rechnername" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "Der Rechnername des HTTP Proxys." #: src/input/input_http.c msgid "HTTP proxy port" msgstr "HTTP Proxy Portnummer" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "Die Portnummer des HTTP Proxys." #: src/input/input_http.c msgid "HTTP proxy username" msgstr "HTTP Proxy Benutzername" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "Der Benutzername für den HTTP Proxy." #: src/input/input_http.c msgid "HTTP proxy password" msgstr "HTTP Proxy Passwort" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "Das Passwort für den HTTP Proxy." #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Domains, die den HTTP Proxy umgehen" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Eine kommagetrennte Liste von Domain-Namen, für die der Proxy ignoriert " "wird.\n" "Wenn ein Domain-Name mit einem '=' beginnt, trifft er nur auf Hostnamen zu " "(vollständige Übereinstimmung nötig)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "Verwende diese HTTP-Version" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "Versuchen Sie diese bei Kommunikationsproblemen." #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "Schreibe HTTP-Kopfzeilen in diese Datei" #: src/input/input_http.c msgid "Set this for debugging." msgstr "Zur Fehlersuche angeben." #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "MMS-Streaming-Eingabe" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "Netzwerkbandbreite" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "Geben Sie hier die Bandbreite Ihrer Internetverbindung an. Dies wird " "benutzt, falls Streaming-Server verschiedene Versionen eines Datenstroms mit " "unterschiedlichen Bandbreitenanforderungen anbieten." #: src/input/input_mms.c msgid "MMS protocol" msgstr "MMS-Protokoll" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Wählt das Protokoll über MMS.\n" "TCP ist besser, aber hinter einer Firewall kann HTTP benötigt werden." #: src/input/input_mpegdash.c msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "MPEG Dynamic Adaptive Streaming over Http Eingabe" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "Mit xine ausgeliefertes net Plugin" #: src/input/input_net.c msgid "tls input plugin" msgstr "TLS-Eingabe" #: src/input/input_net.c msgid "gopher input plugin" msgstr "Gopher-Eingabe" #: src/input/input_nfs.c msgid "Network File System (NFS) input plugin" msgstr "Network File System (NFS) Eingabe" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "PNM Streaming-Eingabe" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: Fehler beim Erstellen der PVR-Datei (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: Fehler beim Öffnen der PVR-Datei (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: Lesefehler (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: Fehler beim Öffnen der Geräts %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_G_CODEC schlug fehl, vielleicht API-Änderung?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_S_CODEC schlug fehl, vielleicht API-Änderung?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "WinTV-PVR 250/350 Eingabe" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "Gerät für WinTV-PVR 250/350 (PVR) Plugin" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "Pfadangabe zum Gerät der WinTV-Karte" #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "xine_socket_cloexec (): %s.\n" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "IP-Adresse für Multicast\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt (SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt (SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind (): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Adresse für iface %s nicht gefunden: %s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) abgebrochen (multicast Kernel?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "Kann '%s' nicht auflösen.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "Kann keine Verbindung zu '%s' herstellen.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv (): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: Stoppe Lese-Thread...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: Lese-Thread beendet\n" #: src/input/input_rtp.c #, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Öffne >Adresse:%s Port:%d Schnittstelle:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: Kann neuen Thread (%s) nicht erstellen\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "Mit xine ausgeliefertes RTP und UDP Plugin" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "RTSP Streaming-Plugin" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "CIFS/SMB Plugin basierend auf libsmbclient" #: src/input/input_ssh.c msgid "SCP input plugin" msgstr "SCP-Eingabe" #: src/input/input_ssh.c msgid "SFTP input plugin" msgstr "SFTP-Eingabe" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "Standardeingabe: Öffnen von '%s' schlug fehl\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "Standardeingabe Streaming-Plugin" #: src/input/input_test.c msgid "Colour Circle" msgstr "Farbkreis" #: src/input/input_test.c msgid "RGB Levels" msgstr "Rot-Grün-Blau Pegel" #: src/input/input_test.c msgid "Saturation Levels" msgstr "Farbsättigungspegel" #: src/input/input_test.c msgid "UV Square" msgstr "UV Quadrat" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "Graubildauflösung" #: src/input/input_test.c msgid "test card input plugin" msgstr "Testbild-Generator" #: src/input/input_v4l2.c msgid "v4l2 input plugin" msgstr "V4L2 Eingabe" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Pufferunterlauf..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Pufferüberlauf..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Anpassen..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Empfängername nicht gefunden\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "V4L TV Plugin" #: src/input/input_v4l.c msgid "v4l video device" msgstr "Pfad zum V4L Videogerät" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Pfad zum Video4Linux Videogerät" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "Pfad zum V4L Radiogerät" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "Pfad zum Video4Linux Videogerät" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "v4l TV Standard" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "Wählt den TV Standard der Quelle. AUTO, PAL, NTSC oder SECAM." #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "V4L Radio Plugin" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "Pfad zum V4L Radiogerät" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Pfad zum Video4Linux Radiogerät" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: Ungültige Medienadresse: Benutze vcdo:/\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: Fehlerhafter Track %d (Gültiger Bereich: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "Kann %s nicht öffnen: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: Kann %s nicht öffnen: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "Video-CD Plugin" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "Gerät für VCD Wiedergabe" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" "Pfadangabe zum Gerät (normalerweise CD oder DVD Laufwerk), das zur " "Wiedergabe von Video-CDs benutzt werden soll." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: Fehlerhafte mrl: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: Kann keine Verbindung zu '%s' aufbauen\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: Kann keine Verbindung zum Server %s aufbauen\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: Sitzung kann nicht eingerichtet werden.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" "rtsp_session: RTSP Server liefert zu große Antworten, Sitzung kann nicht " "eingerichtet werden.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "rtsp_session: RTSP-Servertyp '%s' wird nicht unterstützt. Ups.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "input_dvd: Gerät %s konnte zum Auswerfen nicht geöffnet werden\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Kontaktiere MMS Server (über TCP)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: Sendefehler\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: Fehlerhaftes Empfangsformat\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: 3xx Weiterleitung nicht implementiert: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: http-Status ungleich 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: Weiterleitung nicht implementiert\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Kontaktiere MMS Server (über HTTP)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "Ungültige URL\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "Nicht unterstütztes Protokoll\n" #: src/input/multirate_pref.c msgid "Preferred video size" msgstr "Bevorzugte Bildgröße" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "Wähle eine von mehreren verfügbaren Bildgrößen." #: src/input/multirate_pref.c msgid "Preferred language" msgstr "Bevorzugte Sprache" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "Wähle eine von mehreren verfügbaren Sprachen." #: src/input/multirate_pref.c msgid "Preferred bitrate" msgstr "Bevorzugte Bitrate" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "Wähle eine von mehreren verfügbaren Bitraten mit der selben Bildgröße." #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: Während dem Lesen ist eine Nachricht vom Server eingetroffen:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: Kann keine Verbindung zu '%s' herstellen.\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: Datenstrom konnte nicht eingerichtet werden\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "TLS-Anbieter (gnutls)" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "TLS-Anbieter (openssl)" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "Überprüfe Server-Identität" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" "Prüfe immer das TLS-Identitätszertifikat des Servers, und verweigere ggf. " "die Verbindung." #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR nicht implementiert für Versatz != 0" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END noch nicht implementiert." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "Suchen noch nicht implementiert für" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "Fehlerhaften Elementtyp" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "Fehlerhafte Eintragsnummer" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "Fehlerhafte Segmentnummer" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Fehler beim lesen der aktuellen Segmentnummer" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Sollte bereits konvertiert worden sein" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "Konnte kein Gerät mit einer VCD finden" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "Es wurde ein NULL-Klassenparameter übergeben" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Ungültiger Eintragstyp" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "Auswahl hat keinen RETURN-Eintrag" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "DEFAULT ausgewählt, aber PBC ist nicht an." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "Auswahl hat keinen NEXT-Eintrag" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "Auswahl hat keinen PREVIOUS-Eintrag" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Unbekannter Ereignistyp" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" "Video-CD Plugin mit PBC und Unterstützung für (X)VCD, (X)SVCD, HQVCD, " "CVD, ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "Standardlaufwerk für VCD bei automatischer Wiedergabe" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "Das zu benutzende Laufwerk, wenn keins in der Medienadresse angegeben ist (z." "B. vcd:// oder vcd:///dev/dvd:)" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "Standard CD-ROM-Laufwerk für VCD, wenn keins angegeben wird" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Welches Laufwerk benutzt werden soll, falls kein angegeben ist. Falls die " "Einstellung leer ist, wird xine nach CD-Laufwerken suchen." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "VCD Positionierungsbereich" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" "Der Bereich, den der Positionsschieber bei Wiedergabe von VCDs repräsentiert." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "Vorauslesen für VCDs benutzen?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "Kann auf langsamen Rechnern zu ruckeliger Wiedergabe führen." #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "Automatisch Spur/Eintrag weiter schalten bei VCDs" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Wechsle automatisch zum nächsten Eintrag oder Titel, wenn die " "Wiedergabesteuerung gesperrt ist." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "'Abgelehnte' VCD Wiedergabelistenkennungen zeigen" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" "Einige Kennungen in Wiedergabelisten (LIDs) sind als nicht anzeigbar " "markiert. Diese Option zeigt solche Einträge trotzdem, mit angehängtem " "Sternchen (*)." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "Formatvorlage für Fenstertitel bei VCDs" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" "VCD Formatvorlage für Fenstertitel, ähnlich dem Unix date-Befehl. " "Formatangaben beginnen mit einem Prozentzeichen. Formatangaben sind:\n" " %A : Die Album-Information\n" " %C : Die VCD Serienlänge - Die Anzahl der CDs in der Serie.\n" " %c : Die VCD Seriennummer - Die Nummer der CD in der Serie.\n" " %F : Das VCD Format, z.B. VCD 1.0, VCD 1.1, VCD 2.0, oder SVCD\n" " %I : Der momentane Typ von Eintrag/Segment/Wiedergabe, z.B. ENTRY " "(Eintrag), TRACK (Titel), ...\n" " %L : \"LID\" gefolgt von der Wiedergabelistenkennung, falls vorhanden\n" " %N : Die momentane Nummer des Eintrags/Segments als Dezimalzahl\n" " %P : Die Herausgeberkennung\n" " %p : Die Herstellerkennung\n" " %S : Falls in einem Segment (Menü), der Typ des Segments\n" " %T : Die Titelnummer\n" " %V : Die Serienkennung\n" " %v : Die CD-Kennung\n" " Eine Zahl zwischen 1 und der Serienlänge.\n" " %% : ein Prozentzeichen %\n" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "Formatvorlage für Kommentarfeld eines VCD Datenstroms." #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "Das selbe Format wie für Fenstertitel. Ähnlich dem Unix date-Befehl. " "Formatangaben starten mit einem Prozentzeichen. Formatfelder sind %A, %C, %" "c, %F, %I, %L, %N, %P, %p, %S, %T, %V, %v, und %%.\n" "Siehe Hilfe für title_format bezüglich deren Bedeutung." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "Bitfeld für VCD Fehlersuche" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" "Zusätzliche Meldungen zur Fehlersuche im VCD-Plugin einschalten. Addieren " "Sie einen oder mehrere dieser Werte:\n" " 1: Metainformationen\n" " 2: Eingabe (Tastatur/Maus)\n" " 4: Medienadressen-Auswertung\n" " 8: Aufrufe von außen\n" " 16: interne Aufrufe\n" " 32: LSN Änderungen\n" " 64: Wiedergabesteuerung\n" " 128: CD Ein/Ausgabe\n" " 256: Aufsuchen einer neuen Position\n" " 512: Wiederfinden der aktuellen Position\n" "1024: Standbilder\n" "2048: VCDINFO-Meldungen\n" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "Pfad zu den Real-Player-Codecs" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "Falls Sie den RealPlayer installiert haben, geben Sie hier den Pfad zum " "codec-Verzeichnis an. Sie können das codec-Verzeichnis einfach finden, " "indem Sie nach der Datei \"drvc.so\" in ihm suchen. xine die RealPlayer-" "Codecs findet, verwendet xine diese zum dekodieren von RealPlayer-Inhalten. " "Konsultieren Sie die xine FAQ für weitere Informationen, wie die Codecs zu " "installieren sind." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (Audio) Kann Symbole nicht auflösen - Inkompatible DLL: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "libareal: Dekoderinitialisierung schlug fehl, Fehlercode: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" "libareal: Einrichtung der Dekodervariante schlug fehl, Fehlercode: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: Ups, Real unterstützt mehr als 2 Kanäle?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "Audiodekoder mittels RealPlayer-Bibliotheken" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "libreal: Kann Symbole nicht auflösen! (Version inkompatibel?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "Videodekoder mittels RealPlayer-Bibliotheken" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "Pfad zu win32-Codecs" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "Geben Sie hier den Pfad zu den Windows oder Apple Quicktime Codec-Paketen " "an, falls sie installiert sind. Falls xine die Windows oder Apple Quicktime " "Codecs findet, verwendet xine diese zum dekodieren von verschiedenen Windows " "Media- oder Quicktime Datenströmen. Konsultieren Sie die xine FAQ für " "weitere Informationen, wie die Codecs zu installieren sind." #: src/libw32dll/qt_decoder.c msgid "quicktime audio decoder plugin" msgstr "quicktime Audio Dekoder" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "Videodekoder mittels Quicktime-Bibliotheken" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ICOpen schlug fehl! Unbekannter Codec %08lx / falsche Parameter?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) schlug fehl: Fehler %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery schlug fehl: Fehler %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin schlug fehl: Fehler %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder schlug fehl! Unbekannter Codec %08lx / falsche " "Parameter?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder schlug fehl! Unbekannter Codec %08lx / falsche " "Parameter?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: Dekoder startete nicht. Ist '%s' installiert?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Unpassendes Audioformat\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen Fehler %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Fehler beim Initialisieren von DirectShow Audio\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Fehler beim Initialisieren von DMO Audio\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "win32 DLL Videodekoder" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "win32 Audiodecoder" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" "Dieser Filter führt eine zeitliche Ausdehnung durch, was den Datenstrom um " "einen Faktor schneller oder langsamer abspielt. Die Tonhöhe kann optional " "erhalten werden, was es z.B. möglich macht, einen Film in weniger als seiner " "originalen Aufnahmedauer anzusehen.\n" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" "Beschleunige/Verlangsame den Ton, wahlweise unter Beibehaltung der Tonlage" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" "Upmix Funktion, produziere aus Stereoeingangssignal 5.1 Raumklang.\n" "Parameter\n" " cut_off_freq\n" "\n" "Hinweis: Es kann das Kontrollfenster der Bedienoberfläche benutzt werden, um " "diese Parameter zu setzen.\n" "\n" #: src/post/audio/upmix.c msgid "upmix" msgstr "Hochmischen" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" "Dieser Filter mischt durch Duplizierung der Tonspur Mono zu Stereo. " "Alternativ kann dieser Filter auch dazu benutzt werden, nur einen Kanal " "eines Tonsignals wiederzugeben.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": mische Mono zu Stereo hoch.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] ": mische einen Kanal von ursprünglich %d Kanal hoch.\n" msgstr[1] ": mische einen Kanal von ursprünglich %d Kanälen hoch.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": Audiogerät ist nicht AO_CAP_MODE_STEREO fähig.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "mische Mono zu Stereo hoch" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" "Normalisiert den Ton durch Maximieren der Lautstärke ohne Verzerren des " "Tons.\n" "\n" "Parameter:\n" " method: 1: Benutzt einen einzigen Abtastpunkt, um die Variationen mit " "Hilfe des gewichteten Mittels über vorherige Abtastpunkte zu glätten " "(Standard); 2: Benutzt mehrere Abtastpunkte, um die Variationen mit Hilfe " "des gewichteten Mittels über vorherige Abtastpunkte zu glätten.\n" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "Lautstärke anpassen" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" "Erweitertes tvtime/deinterlacer Plugin mit pulldown-Erkennung\n" "Dieses Plugin hat das Ziel, im Zeilensprungverfahren aufgenommenes " "Bildmaterial auf Rechnerbildschirmen und Projektoren hochwertig darzustellen " "(ähnlich DVD-Spieler und sogenannten Zeilenverdopplern).\n" "\n" "Einstellungen\n" "\n" " Method: Wählt die Entflechtungsmethode. Eine genaue Beschreibung jeder " "Methode folgt weiter unten.\n" "\n" " Enabled: Aktiviert/Deaktiviert das Plugin.\n" "\n" " Pulldown: Wählt die 2-3 Pulldown-Erkennung. Kinofilme mit 24 Bildern pro " "Sekunde, die nach NTSC konvertiert wurden, können erkannt und intelligent " "in ihr Originalformat zurückgewandelt werden.\n" "\n" " Framerate_mode: 'full' entflechtet jedes Quellbild in ein eigenes Bild in " "Fernsehqualität oder besser. Dieser Modus verdoppelt effektiv die " "Bildwiederholrate und verbessert die Gleichförmigkeit. Beachten Sie, dass " "volle 59.94 Bilder/Sekunde mit einem Linux-2.4-Kernel nicht möglich sind. " "Neuere Kernel (2.6 oder besser) sollten anstandslos funktionieren.\n" "\n" " Judder_correction: Falls 2-3-Pulldown aktiviert ist und entsprechendes " "Filmmaterial erkannt wurde, kann die Bildwiederholrate auf die ursprüngliche " "Rate (24 Bilder/Sekunde) reduziert werden. Dies ergibt eine flüssigere " "Wiedergabe.\n" "\n" " Use_progressive_frame_flag: MPEG2-Videos enthalten eine Markierung die " "angibt ob das Zeilensprungverfahren verwendet wird (interlaced) oder nicht " "(progressive). Hier bestimmen Sie, ob dieser Markierung vertraut werden soll " "oder nicht (Einige seltene und fehlerhafte MPEG2-Datenströme setzen es " "falsch).\n" "\n" " Chroma_filter: DVD/MPEG2 benutzen ein verschränktes Bildformat, das eine " "schlechte vertikale Farbauflösung hat. Das Hochskalieren dieser " "Farbinformation zum Entflechten kann das Auftreten von Artefakten " "hervorrufen (z.B. Farbstreifen). Benutzen Sie diese Option, um die " "Farbinformation nach dem Entflechten zu verwischen, um solche Artefakte zu " "entfernen. Achtung: CPU intensiv.\n" "\n" " Cheap_mode: Die überspringt die aufwendige YV12->YUV2 Bildkonvertierung, " "aber die tvtime/dscaler-Routinen arbeiten weiterhin so, als wäre es YUV2. " "Natürlich ist das nicht korrekt, da nicht alle Pixel von den Algorithmen " "ausgewertet werden, um die Regionen zum entflechten zu entscheiden, und " "Farbinformationen werden getrennt bearbeitet. Dieses Vorgehen erlaubt es " "Personen mit leistungsärmeren Systemen trotzdem die Entflechtungsalgorithmen " "als Kompromiss zwischen Qualität und CPU-Auslastung auszuprobieren.\n" "\n" "* Benutzt verschiedene Algorithmen von tvtime und vom dscaler Projekt.\n" "Deinterlacing methods: (Nicht alle Methoden stehen auf allen Plattformen zur " "Verfügung)\n" "\n" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "Erweitertes tvtime/deinterlacer Plugin mit pulldown-Erkennung" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: Keine Entflechtungsmethoden verfügbar, beendet.\n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "Zu erzeugende Bilder pro Sekunde" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Mit mehr Bildern pro Sekunde wird die Animation flüssiger und schneller, " "benötigt aber mehr Rechenleistung." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "Goom Bildbreite" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "Die Breite des zu generierenden Bilds in Pixeln." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "Goom Bildhöhe" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "Die Höhe des zu generierenden Bilds in Pixeln." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "Farbraumkonvertierungsmethode" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" "Sie können die Methode zum Konvertieren des Farbraums in Goom wählen.\n" "Die auswählbaren Möglichkeiten sollten selbsterklärend sein." #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico ermöglicht einfache Bild-in-Bild Effekte.\n" "\n" "Parameter\n" " pic_num: Nummer des Bildbereiches, für den die folgenden Werte gelten\n" " x: Die X-Koordinate der linken oberen Ecke des Bilds\n" " y: Die Y-Koordinate der linken oberen Ecke des Bilds\n" " w: Die Breite des Bilds\n" " h: Die Höhe des Bilds\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "Mosaico ist ein Bild-im-Bild Plugin" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Schalter kann benutzt werden, um schnell zwischen mehreren Quellen " "umzuschalten.\n" "\n" "Parameter\n" " select: Die Nummer der Quelle, die zum Ausgang geleitet werden soll\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" "Switch ist ein Plugin zum Hin- und Herschalten zwischen mehreren Videos" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Box blur verwischt ein Bild.\n" "\n" "Parameter\n" " Radius: Größe des Filters\n" " Power: Anzahl der Anwendungen dieses Filters\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "Weichzeichner-Filter von MPlayer" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Dieser Filter reduziert Bildrauschen und erzeugt sehr gleichmäßige Bilder " "und macht Standbilder sehr still (sollte Komprimierbarkeit verbessern). Es " "können 0-3 Parameter angegeben werden. Für ausgelassene Parameter werden " "passende Werte verwendet.\n" "\n" "Parameter\n" " Luma: Lokale Helligkeitsstärke (Standard = 4)\n" " Chroma: Lokale Farbstärke (Standard = 3)\n" " Time: Zeitliche Stärke (Standard = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "3D Rauschminderer (variabler Tiefpass)" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" "Alternativer Software-Equalizer, der Tabellen benutzt (sehr langsam) und " "zusätzlich zu Helligkeit, Kontrast und Sättigung Gamma-Korrekturen erlaubt.\n" "Beachten Sie, dass derselbe MMX-optimierte Code von 'eq' benutzt wird, falls " "alle Gamma-Werte 1.0 sind.\n" "\n" "Parameter\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (Gamma für Rotanteil)\n" " ggamma (Gamma für Grünanteil)\n" " bgamma (Gamma für Blauanteil)\n" "\n" "Wertebereiche sind 0.1 bis 10 für Gamma, -2 bis 2 für Kontrast (negative " "Werte resultieren in ein negatives Bild), -1 bis 1 für Helligkeit und 0 bis " "3 für Sättigung.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "Software video Equalizer" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" "Software-Equalizer mit interaktiver Steuerung ähnlich Hardware-Equalizer für " "solche Karten/Treiber, die keine Helligkeits-/Kontraststeuerung in Hardware " "besitzen.\n" "\n" "Parameters\n" " brightness: Helligkeit\n" " contrast: Kontrast\n" "\n" "Hinweis: Es kann das Kontrollfenster der Bedienoberfläche benutzt werden, um " "diese Parameter zu setzen.\n" "\n" "* mplayer's eq (C) Richard Felker\n" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "Software video Equalizer" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" "Dieses expand-Plugin konvertiert Bilder mit beliebigem Seitenverhältnis in " "Bilder mit einem Seitenverhältnis (normalerweise von 4:3) durch Hinzufügen " "von schwarzen Balken am oberen und unteren Bildrand. Dadurch können " "Überlagerungen nach unten verschoben werden, so dass sie nicht das Bild " "überdecken.\n" "\n" "Parameter\n" " Enable_automatic_shift: Automatisch Überlagerungsverschiebung\n" " Overlay_y_offset: Manuelle vertikale Überlagerungsverschiebung\n" " aspect: das Zielseitenverhältnis (normalerweise 4:3)\n" " Centre_cut_out_mode: Extrahiert 4:3 Bilder aus 16:9 Bildern\n" "\n" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" "Füge oben und unten schwarze Balken an, um ein Bildseitenverhältnis von 4:3 " "zu erhalten" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" "Schneide links und rechts etwas vom Bild ab, um ein Bildseitenverhältnis von " "4:3 zu erhalten" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "Kehrt die Bildfarben um." #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" "Fügt dem Video Bildrauschen hinzu.\n" "\n" "Parameter:\n" " luma_strength: Stärke der Störung des Helligkeitskanals (0-100, Standard: " "8)\n" " chroma_strength: Stärke der Störung des Farbkanals (0-100, Standard: 5)\n" " quality: Qualitätslevel der Störung. fixed: Konstantes Störungsmuster; " "temporal: Störungsmuster ändert sich zwischen Bildern; averaged temporal: " "weicheres Störungsmuster, das sich zwischen Bildern ändern. (Standard: " "averaged temporal)\n" " type: Typ der Störung: uniform oder gaussian. (Standard: gaussian)\n" " pattern: Vermische Störung mit einem (semi-)regelmäßigem Muster. " "(Standard: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" #: src/post/planar/noise.c msgid "Adds noise" msgstr "Fügt dem Video Bildrauschen hinzu." #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "FFmpeg libpostprocess Plugin.\n" "\n" "Parameter\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "Plugin zur Video-Nachbearbeitung mit FFmpeg" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" "Unschärfemaske / Gaußsche Unschärfe\n" "Die Breite und Höhe der Matrix kann gesetzt werden, beide Dimensionen müssen " "ungerade sein (Minimum 3x3, Maximum 13x11 oder 11x13, normalerweise zwischen " "3x3 und 7x7. Der relative Grad der Schärfe/Unschärfe, die dem Bild " "hinzugefügt wird, sollte typischerweise zwischen -1.5 und 1.5 liegen).\n" "\n" "Parameter\n" "\n" " Luma_matrix_width: Breite der Matrix (muss ungerade sein)\n" " Luma_matrix_hieght: Höhe der Matrix (muss ungerade sein)\n" " Luma_amount: Relativer Grad der Schärfe/Unschärfe (=0 deaktiviert, <0 " "Unschärfe, >0 Schärfe)\n" " Chroma_matrix_width: Breite der Matrix (muss ungerade sein)\n" " Chroma_matrix_height: Höhe der Matrix (muss ungerade sein)\n" " Chroma_amount: Relativer Grad der Schärfe/Unschärfe (=0 deaktiviert, <0 " "Unschärfe, >0 Schärfe)\n" "\n" "* mplayer's unsharp (C) 2002 Rémi Guyomarch\n" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "Gaußsche und adaptive Weichzeichner" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "fftgraph Tonanimation" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "FFT Scope Tonanimation" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "Oszilloskop Tonanimation" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "Zeitbereichs-Tonanalyse Animation" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "Schriftart für externe Untertitel" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "Vertikaler Versatz für Untertitel (Relativ zu Fenstergröße)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "CMML Untertitel Decoder" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "Zeichenkodierung für Untertitel" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "DVD/VOB Untertitel-Dekoder" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "DVB Untertitel Decoder" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "Standardzeitspanne in Sekunden bis zum Ausblenden des Untertitels" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Einige Untertitel sagen nicht genau wie lange sie sichtbar sein sollen. " "Dafür können Sie hier eine Standardzeitspanne angeben. Null bedeutet \"so " "lange zeigen bis der nächste Untertitel erscheint\"." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "Dekoder für externe Untertitel" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "Untertitelgröße" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" "Passt die Untertitelgröße an. Diese Einstellung ist relativ zur Fenstergröße." #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "Vertikaler Versatz für Untertitel" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" "Passt den vertikalen Versatz der Untertitel an. Diese Einstellung ist " "relativ zur Fenstergröße." #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "Schriftart für Untertitel" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Eine Schriftart aus xines font-Verzeichnis zur Anzeige von Untertiteln." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "Ein Schriftart (z.B. .ttf) zur Anzeige von Untertiteln." #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "ob Freetype-Zeichensätze genutzt werden" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "Zeichenkodierung für Untertitel" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "Die Kodierung der Untertitel im Datenstrom. Diese Einstellung wird bei der " "Darstellung von nicht-ASCII-Zeichen benutzt. Falls nicht-ASCII-Zeichen " "anders als erwartet dargestellt werden, fragen Sie den Ersteller der " "Untertitel nach der verwendeten Kodierung." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "Benutze unskalierte Einblendungen falls möglich" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" "Unskalierte Einblendungen werden unabhängig vom Videobild erzeugt und sind " "immer scharf, sogar falls das Video vergrößert wird. Es sieht besser aus, " "funktioniert aber nicht mit jeder Grafikkarte. Die Alternative sind " "skalierte Einblendungen, welche verwischen, wenn ein Video mit niedriger " "Auflösung bildschirmfüllend angezeigt wird." #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "Untertitel-Demultiplexer" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "Untertitel in MEPG-2-Strömen anzeigen" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "Untertitel sollen Hörgeschädigten helfen." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "Untertitelschema für Vordergrund-/Hintergrundfarbe" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Wählen Sie eine Darstellung für Untertitel." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "Schriftart für normale Untertitel" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Wählen Sie die Schriftart für normale Untertiteltexte." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "Schriftart für kursive Untertitel" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "Wählen Sie die Schriftart für kursive Untertiteltexte." #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "Schriftgröße für Untertitel" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "Wählen Sie die Schriftgröße für Untertiteltexte." #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "Zentrieren von Untertiteln" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" "Falls aktiviert werden die Zeilen des Untertitels jeweils mittig " "ausgerichtet." #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "Untertitel-Decoder" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "%s: Sende Ereignis: %s.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "%s: buffer_pool_alloc() fehlgeschlagen!\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "%s: Leere Puffer (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "%s: Beende Fernzugriff (Zeitüberschreitung: %d ms) ...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "%s: Breche Ferndienstanfrage in Funktion %d ab...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "%s: Trete Fernzugriff bei...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "%s: Fernzugriff beigetreten.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "%s: Öffnen von '%s' schlug fehl (%s)\n" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "Zeitüberschreitung beim Einrichten" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "%s: Lesen von '%s' fehlgeschlagen (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "%s: Kanaleinrichtung für Port %d fehlgeschlagen (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "%s: Keine Verbindung zu port %d (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "%s: Kanal zu Port %d erfolgreich geöffnet, fd = %d\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "%s: Verbinde mit VDR.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "%s: Unbekannter Rechner '%s' (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "%s: Alle Verbindungen (Ports %d .. %d) erfolgreich hergestellt.\n" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" "%s: Medienadresse (%s) ungültig! Muster: vdr://Pfad/zu/fifo/stream oder " "netvdr://Rechner:Port wobei ':Port' auch entfallen kann.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: Kann neuen Thread (%s) nicht erzeugen\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "Plugin für VDR Anzeigegerät" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "Verändert den Ton wie von VDR gewünscht" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "Verändert jedes Videobild wie von VDR gewünscht" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr ": Einblendung: (%d, %d)-(%d, %d)@%lg\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: Fehler beim ByteRun1-Dekomprimieren\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 wird momentan nicht unterstützt\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 wird momentan nicht unterstützt\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ wird momentan nicht unterstützt\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: Dieser anim-Type wird momentan nicht unterstützt\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "Bitebenen Videodekoder" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "gdk-pixbuf Standbild Videodekoder" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "Standbild Videodekoder" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "AVI (libaom) Videodekoder" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "JPEG Standbild Videodekoder" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "Verkleinere zu große Bilder, statt sie abzuschneiden" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" "Falls ein Bild zu groß für Ihre Grafikkarte ist, zeige es verkleinert oder " "beschnitten." #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "mpeg2 Videodekoder" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "HEVC Videodekoder" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "vdpau: Öffne Dekoder nach Zeitsprüngen neu." #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "Manche Treiber stürzen ohne dieses ab." #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "Alternativer VDPAU h264 Videodekoder.\n" "Benötigt VDPAU Video-Ausgabe." #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "VDPAU h264 Videodekoder.\n" "Benötigt VDPAU Video-Ausgabe." #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "VDPAU mpeg1/2 Videodekoder.\n" "Benötigt VDPAU Video-Ausgabe." #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "VDPAU mpeg4 part 2 Videodekoder.\n" "Benötigt VDPAU Video-Ausgabe." #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "VDPAU vc1/wmv3 Videodekoder.\n" "Benötigt VDPAU Video-Ausgabe." #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "WebM (VP8/VP9) Videodekoder" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "mmal Videodekoder" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "Raw RGB Videodekoder" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "Raw YUV Videodekoder" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "Farbmatrix" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" "Wie sollen die Ausgabefarben berechnet werden:\n" "\n" "Signal: Wie im Video angegeben.\n" " Dies ist nicht immer die beste Wahl.\n" "\n" "Signal+Size: Desgleichen, aber verwende HD Farben\n" " für unmarkiertes HD Video.\n" "\n" "SD: Erzwinge SD Videostandard ITU-R 470/601.\n" " Nützlich bei zu wenig Grün.\n" "\n" "HD: Erzwinge HD Videostandard ITU-R 709.\n" " Versuchen Sie dies bei zu viel Grün.\n" "\n" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "Kontrastumfang" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" "Welchen Kontrastumfang verwenden?\n" "\n" "Auto: Wie im Video angegeben.\n" "\n" "MPEG: Erzwinge MPEG/studio swing/Video-Modus (16..235).\n" " Nützlich bei flauem Bild (kein echtes Schwarz oder Weiß).\n" "\n" "FULL: Erzwinge FULL/full swing/PC Modus (0..255).\n" " Versuchen Sie dies bei schwarzen und weißen Flecken ohne Details.\n" "\n" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "Reserviere das X Ausgabegerät während des gesamten Bildes." #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" "Dies ergibt manchmal weniger Systemlast und eine flüssigere Wiedergabe.\n" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "GL-Anbieter (GLX)" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" "Schalte VAAPI Beschleunigung für alle Videotreiber ein. Andernfalls versucht " "dies nur der VAAPI Videotreiber. Zur Zeit klappt das jedoch nur mit dem " "OpenGL2 Treiber." #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "vaapi: vaapi_guarded_render 0 (aus) 1 (ein)" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "VAAPI Bildpuffer-Anbieter" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "xine Bildausgabe über ASCII-Art Bibliothek" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "xine Bildausgabe über Farb-ASCII-Art Bibliothek" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "Videoebenen-Puffermodus" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" "Wählt den Puffermodus für die Ebene der Ausgabe. Doppel- oder " "Dreifachpufferung führen zu einer weicheren Wiedergabe, verbrauchen aber " "mehr Videospeicher." #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "Warte auf vertikalen Strahlenrücklauf" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" "Synchronisiert die Aktualisierung des Videobilds mit der Neudarstellung des " "Bildschirms (\"Vertikaler Strahlenrücklauf\")." #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "Aktiviert Farbschlüssel für Einblendung" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" "Aktiviert die Benutzung eines Farbschlüssel, um der Grafikkarte mitzuteilen, " "wo das Videobild angezeigt werden soll." #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "Farbschlüssel für Einblendung" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" "Der Farbschlüssel wird benutzt, um der Grafikkarte mitzuteilen, wo das Video " "eingeblendet werden kann. Probieren Sie verschiedenen Werte, falls einige " "Fenster durchscheinend werden." #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "Flackerfilterung" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" "Aktiviert die Flackerfilterung für eine weichere Wiedergabe auf " "Bildschirmen, die das Halbzeilenverfahren verwenden." #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "Feldpriorität" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" "Für einen Bildschirm im Halbzeilenverfahren, erlaubt die Kontrolle der " "Feldpriorität (\"none\"=deaktiviert)." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "video_out_directfb: Benutzt Hardwarebeschleunigung für Untertitel.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "video_out_directfb: Ebene unterstützt Videoausgabe.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "video_out_directfb: Ebene unterstützt kein YV12!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "video_out_directfb: Ebene unterstützt kein YUY2!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" "video_out_directfb: Benötige mindestens DirectFB 0.9.25 zur Wiedergabe auf " "dieser Ebene!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "video_out_directfb: Ebene unterstützt keinen Puffermodus %d!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "video_out_directfb: Ebene unterstützt keine Option 0x%08x!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" "video_out_directfb: Benutzt Hardwarebeschleunigung für Bildskalierung.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" "video_out_directfb: Bildskalierung und -entflechtung sind " "gerätebeschleunigt.\n" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "Videoebenen-Kennung (automatisch: -1)" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "Wählt die Ausgabeebene für Videos nach deren Kennung." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "video_out_directfb: Benutze Anzeigenebene #%d.\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "xine Bildausgabe über DirectFB" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "video_out_directfb: Keine benutzbare Anzeigenebene gefunden!\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "xine Bildausgabe über DirectFB/XDirectFB" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "Gerätebeschleunigung" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" "Mögliche Werte (Standard: full):\n" "\n" "full: Farbberechnungen und Größenänderungen beschleunigen\n" "scale: Nur Größenänderungen beschleunigen\n" "none: Keine Beschleunigung" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "xine Bildausgabe über win32/directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: Nur packed truecolor/directcolor wird unterstützt (%d).\n" " Überprüfen Sie 'fbset -i' oder versuchen Sie 'fbset -depth 16'.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "Framebuffer Gerät" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" "Gibt den Namen für das Sun Framebuffer-Gerät an.\n" "ACHTUNG: Eine falsche Angabe überschreibt eine Datei dieses Namens mit " "riesigen Datenmengen! Also besser doppelt prüfen." #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Ihr Videomodus wurde nicht erkannt, Entschuldigung.\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: %d Grafikspeicher-Puffer sind verfügbar.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "WARNUNG: %s: Null-Kopie-Puffer sind DEAKTIVIERT, weil nur %d Puffer\n" " verfügbar sind, was weniger als die empfohlenen %d Puffer sind. " "Verringern\n" " der Framebuffer-Auflösung kann helfen.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "WARNUNG: %s: Null-Kopie-Puffer sind DEAKTIVIERT, weil der Kernel-Treiber\n" " kein screen-panning unterstützt (benutzt für Bildwechsel).\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "WARNUNG: %s: Aktuelle Farbtiefe ist %d. Für bessere Leistung wird eine " "Farbtiefe von 16 bpp empfohlen!\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "xine Bildausgabe über Linux Framebuffer" #: src/video_out/video_out_mmal.c msgid "xine video output plugin using MMAL" msgstr "xine Bildausgabe über MMAL" #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "Keine xine Bildausgabe" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "opengl2: Skaliere Video bikubisch" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" "Bikubisches Vergrößern/Verkleinern des Bildes bewirkt (fast) keinen Verlust " "an Schärfe.\n" "Es benötigt aber eine schnelle Grafikkarte.\n" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "opengl2: Video Größenänderungsverfahren" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" "0: Einfach. Sehr schnell, sehr scharf,\n" " aber auch Treppenstufen, unruhige Linien, und flackernde Bewegungen.\n" "\n" "1: Linear. Schnell, sehr weich, aber auch etwas verwaschen.\n" "\n" "2: Catmullrom. Sehr weich, scharf, braucht aber eine schnelle Grafikkarte.\n" "\n" "3: Cosinus. Weich, sehr scharf, braucht aber eine schnelle Grafikkarte..\n" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "OpenGL 2.0 Bildausgabe" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "OpenGL Renderer" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" "Das OpenGL Plugin bietet verschiedene Render-Modelle:\n" "\n" "2D_Tex_Tragprog\n" "Dieses Modul lädt die Bilder als YUV 2D-Textur und rendert einen " "texturierten Streifen mit Hilfe von Fragmentprogrammen zur Rekonstruktion " "von RGB.\n" "Dies ist die beste und schnellste Methode bei modernen Grafikkarten.\n" "\n" "2D_Tex\n" "Dieses Modell lädt die Bilder als 2D-Textur und rendert einen texturierten " "Streifen.\n" "\n" "2D_Tex_Tiles\n" "Dieses Modell lädt die Bilder als mehrere 2D-Texturen und rendert " "texturierte Streifen.\n" "Deshalb funktioniert diese Methode auch mit kleineren Texturgrößen.\n" "\n" "Image_Pipeline\n" "Dieses Modul benutzt glDraw() zum Rendern der Bilder.\n" "Nur beschleunigt bei wenigen Treibern.\n" "Interpoliert nicht bei Skalierung.\n" "\n" "Cylinder\n" "Zeigt Bilder auf einem rotierenden Zylinder. Netter Effekt :)\n" "\n" "Environment_Mapped_Torus\n" "Zeigt Bilder auf einem sich drehenden spiegelndem Torus. Sehr cool =)" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "Minimale OpenGL Bildrate" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" "Minimale Bildrate für animierte Renderroutinen.\n" "Ignoriert für statische Renderroutinen.\n" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "Doppelpufferung benutzen" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" "Doppelpufferung bei OpenGL entfernt nicht nur Fransen-Artefakte,\n" "sondern reduziert auch Flackern.\n" "Es sollte keine Leistungseinbußen haben." #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "xine Bildausgabe über OpenGL 3D Grafikschnittstelle" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx32: Fehler: Kann DGA Zeichenfläche für Videofenster nicht " "bekommen\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Fehler: ioctl schlug fehl, fehlerhaftes Gerät (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "video_out_pgx32: Fehler: '%s' ist kein pgx32 Framebuffer Gerät\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "xine Bildausgabe über Sun PGX32 Bildpuffer" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx64: Fehler: Kann DGA Zeichenfläche für Videofenster nicht " "bekommen\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "video_out_pgx64: Fehler: Kann Framebuffer Gerät '%s' nicht öffnen\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Fehler: ioctl(VIS_GETIDENTIFIER) schlug fehl, fehlerhaftes " "Gerät (%s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Fehler: '%s' ist kein xvr100/pgx64/pgx24 Framebuffer Gerät\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" "video_out_pgx64: Fehler: Video-Einblendung auf diesem Schirm ist bereits " "benutzt\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" "video_out_pgx64: Fehler: Fenstereigenschaften können nicht gesetzt werden\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Warnung: Wenig Videospeicher, Mehrfachpufferung " "deaktiviert\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Fehler: Ungenügend Videospeicher\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Warnung: Wenig Videospeicher, Doppelpufferung deaktiviert\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Fehler: ioctl(FBIOGATTR) schlug fehl\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "Farbschlüssel für Einblendung" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" "Der Farbschlüssel wird benutzt, um der Grafikkarte mitzuteilen, wo das Video " "eingeblendet werden kann. Probieren Sie verschiedenen Werte, falls das Video " "bei anderen Fenstern durchscheint." #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "Benutze Farbschlüssel" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" "OSD-Grafiken werden an den Stellen des Farbschlüssels dargestellt, anstatt " "sie in jedes Bild einzublenden." #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "Mehrfachpufferung benutzen" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" "Mehrfachpufferung erhöht die Leistung auf Kosten eines erhöhten Verbrauchs " "von Grafikspeicher." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "xine Bildausgabe über Sun XVR100/PGX64/PGX24 Bildpuffer" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "xine Bildausgabe als Rohdaten an externes Programm" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "Benutze Hardwarebeschleunigung falls verfügbar" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "Falls Ihr System es unterstützt, wird die Hardwarebeschleunigung Ihrer " "Grafikhardware benutzt. Falls es nicht funktioniert, können Sie dies " "deaktivieren." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "SDL muss eine 16 Bit Ausgabe emulieren, was alles verlangsamt.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: Vollbildmodus wird NICHT unterstützt\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "xine Bildausgabe über 'Simple Direct Media Layer'" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "xine Bildausgabe über LibStk Surface Set-top Toolkit" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" "video_out_vaapi: Treiber unterstützt keine \"%s\" Farbraumkonvertierung\n" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "Standardanzahl von Videobildern" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" "Die Standardanzahl von Videobildern, die vom xine Videoausgabetreiber " "angefordert werden. Einige Treiber überschreiben diese Einstellung mit ihren " "eigenen Werten." #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "vaapi: Ausgabe über OpenGL" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "vaapi: opengl tfp Modus" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "vaapi: Abhilfe für fehlerhafte Breite von VDR Einblendungen." #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "vaapi: Abhilfe für fehlerhafte Höhe von VDR Einblendungen." #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" "vaapi: Wähle Entflechtungsmethode: 0 (keine), 1 (verweben), 2 " "(weichzeichnen)." #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" "vaapi: Wähle Qualität beim Vergrößern/Verkleinern:\n" "default (Standard), fast (schnell), hq (gut), nla (anamorph)" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "vaapi: Vertausche U und V Farbebenen." #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" "vaapi: Korrigiere Rot/Blau-Farbfehler bei einigen Treibern (intel " "IronLake).\n" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "VAAPI Farbraumkonvertierungsmethode" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" "Farbraumumwandlung über VAAPI:\n" "\n" "user_matrix: Die beste Art - falls Ihr Treiber mitspielt.\n" "simple: Wähle SD/HD Farbraum, und rechne Video mit erweitertem " "Kontrastumfang herunter.\n" "simple+2: Wähle SD/HD Farbraum, und korrigiere erweitertem Kontrastumfang " "über die\n" " Helligkeit/Kontrast-Einstellungen.\n" "simple+3: Wie oben, aber passe auch die Farbsättigung mit an.\n" "\n" "Tipp: Spielen Sie \"test://rgb_levels.bmp\" ab, während Sie dies hier " "ausprobieren.\n" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "VAAPI Einblendungsmethode" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" "Wie Bildeinblendungen und Untertitel dargestellt werden sollen:\n" "0: Einblendungen ganz abschalten, z.B. für fehlerhafte Mesa radeonsi " "Treiber.\n" "1: Automatisch wählen.\n" "2: Erzwinge BGRA Farben.\n" #: src/video_out/video_out_vaapi.c msgid "xine video output plugin using VAAPI" msgstr "xine Bildausgabe über VAAPI" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "Maximale Anzahl von mehrfach genutzten Videobildern" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "Maximale Anzahl von mehrfach genutzten Videobildern" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "Normale Länge der Anzeige-Warteschlange" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "Reserviere so viele Bilder für die Anzeige-Warteschlange" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "vdpau: HD-Entflechtungsmethode" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "vdpau: SD-Entflechtungsmethode" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "vdpau: Qualität beim Vergrößern/Verkleinern" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "Qualitätsstufe beim Vergrößern/Verkleinern" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "vdpau: Versuche die originale Bildwiederholrate wieder her zu stellen" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" "Erkenne falsch markiertes, für TV nachbearbeitetes Material\n" "(sogenanntes 2:2 oder 3:2 Pulldown).\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "vdpau: Deaktiviere Entflechten bei Video ohne Zeilensprung" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "Vertraue den im Video enthaltenen Markierungen.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "vdpau: Deaktiviere Farbfilter beim Entflechten" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "Sinnvoll bei einigen älteren Grafikkarten.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "vdpau: Füllfarbe für ungenutzte Bildflächen" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" "Plasmabildschirme zeigen Einbrenneffekte nach langem Gebrauch mit schwarzen " "Balken wie 4:3 -> 16:9. Mit einer anderen Balkenfarbe (z.B. 8421404) lässt " "sich dieses Problem reduzieren.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "vdpau: SD-spezifische Einstellungen" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" "none\n" "Alles wie bei HD.\n" "\n" "noise\n" "Rauschminderung nur bei SD.\n" "\n" "sharpness\n" "Schärfen nur bei SD.\n" "\n" "noise+sharpness\n" "Rauschminderung und Schärfen nur bei SD.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "vdpau: Mache Schnappschüsse wie auf dem Bildschirm gezeigt" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" "Ein: vergrößert/verkleinert, beschnitten, aufgefüllt und untertitelt.\n" "Aus: nur das reine originale Videobild.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "vdpau: Umgehe defekte Bildmischer-Einblendungen" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" "Manche vdpau_radeonsi Systemtreiber von 2022 stürzen beim Versuch ab,\n" "Untertitel oder Einblendungen auf normale Weise zu zeigen.\n" "\"On\" ist etwas langsamer, aber hilft hier.\n" "\"Off\" vermeidet Flackern bei einigen anderen Treibern.\n" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "xine Bildausgabe über VDPAU-Beschleuniger" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "Rot-Intensität" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "Die Intensität roter Farbanteile" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "Grün-Intensität" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "Die Intensität grüner Farbanteile" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "Blau-Intensität" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "Die Intensität blauer Farbanteile" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" "Doppelpufferung synchronisiert das Aktualisieren des Videobildes mit der " "Darstellung des gesamten Bildschirms (\"Strahlenrücklauf\"). Dies verhindert " "Flackern und Fransenbildung, benötigt aber mehr Grafikspeicher." #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: Adapter unterstützt das YUY2 Format\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: Adapter unterstützt das YV12 Format\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "video_out_vidix: Sie haben die falsche Version der VIDIX-Bibliothek\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: Kein funktionierende VIDIX-Treiber gefunden\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: Benutzer Treiber: %s von %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "Rot-Komponente des Farbschlüssels für Einblendungen" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "Grün-Komponente des Farbschlüssels für Einblendungen" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "Blau-Komponente des Farbschlüssels für Einblendungen" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "xine Bildausgabe über libvidix für X11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "xine Bildausgabe über libvidix für Linux Framebuffer" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "%s: %s: Belege Bildpuffer\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "%s: => benutze die \"MIT Shared Memory\" Erweiterung nicht.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "%s: Shared-Memory-Fehler (Adressfehler) beim Belegen des Bildes\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" "%s: x11 Fehler beim Anlegen eines XImage in gemeinsam genutzten Speicher\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "WARNUNG: Aktuelle Farbtiefe ist %d. Für bessere Leistung wird eine Farbtiefe " "von 16 bpp empfohlen!\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "%s: \"MIT-Shared-Memory\" Erweiterung für Anzeige nicht vorhanden.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: Ihr Videomodus wurde nicht erkannt, Entschuldigung.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "xine Bildausgabe über 'MIX X Shared Memory' Erweiterung" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "%s: XvShmCreateImage lieferte Null als Größe\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "%s: Fehler bei gemeinsam genutztem Speicher in shmget: %s\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "%s: Adressfehler bei gemeinsam genutzten Speicher\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: Adapter unterstützt das %s-Format.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: Xv-Erweiterung nicht vorhanden.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "%s: Konnte Xv Port %lu nicht öffnen - treffe automatische Wahl\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "%s: Keine Ports des Typs \"%s\" verfügbar, wähle Standardtyp...\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: Xv-Erweiterung ist vorhanden, aber es wurde kein brauchbarer YUV12-Port " "gefunden.\n" " Unterstützt die Grafikhardware evtl. kein Xv?!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: Benutze Xv-Port %d von Adapter %s for Hardware-Farbraumtransformation " "und Skalierung.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "Synchronisiere Bildwechsel" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" "Doppelpufferung synchronisiert das Aktualisieren des Videobildes mit der " "Darstellung des gesamten Bildschirms (\"Strahlenrücklauf\"). Dies verhindert " "Flackern und Fransenbildung, benötigt aber mehr Grafikspeicher." #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "Erweiterten Kontrastumfang nachbilden" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" "Verarbeite erweiterten Kontrastumfang durch absichtliches Verstellen von " "Helligkeit, Kontrast und Farbsättigung.\n" "\n" "Off (Aus): Rechne das Bild vor der Ausgabe auf Standard-Kontrast herunter.\n" " Dies funktioniert mit allen Grafikkarten, braucht aber etwas\n" " mehr Rechenleistung.\n" "\n" "Normal: Schneller und bessere Bildqualität. Sollte zumindest auf neueren\n" " Grafikkarten (GeForce 7+, 210+) klappen.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "Erzwinge YUY2-Emulation" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "Fehlersuche." #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "xine Bildausgabe über \"MIT XVideo\" Erweiterung" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "%s: Fehler bei Anlegen des Bildes im gemeinsam genutzten Speicher\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "%s: XvShmCreateImage fehlgeschlagen\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: Benutze Xv-Port %ld von Adapter %s for Hardware-Farbraumtransformation " "und Skalierung.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: XvMC-Erweiterung nicht vorhanden.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: Xv-Erweiterung ist vorhanden, aber es wurde kein benutzbarer " "YUV12-Port gefunden.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xvmc: Benutze Xv-Port %ld von Adapter %s for Hardware-" "Farbraumtransformation und Skalierung\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " IDCT und Bewegungskompensationsbeschleunigung \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " nur Bewegungskompensationsbeschleunigung\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " Keine XvMC-Unterstützung \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " Mit Überlagerung = %d; UnsignedIntra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "xine Bildausgabe über XvMC XVideo-Erweiterung" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "XvMC belegt zur besseren Pufferung mehr Bildspeicher." #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" "Einige XvMC-Implementierungen erlauben mehr als 8 Bilder.\n" "Diese Option, wenn ausgewählt, veranlasst den Treiber 15\n" "Bilder zu belegen. Ein Muss für Unichrome oder live VDR.\n" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Unichrome Prozessorschoner" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" "Spart CPU-Rechenzeit durch Schlafen während der Dekoder arbeitet.\n" "Nur verfügbar mit Linux-Kernel der 2.6er Serie oder 2.4er mit Multimedia-" "Patch.\n" "Experimentell.\n" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "Behebe NVIDIA XvMV Subpicture-Farbfehler" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" "Behebt den Fehler in NVIDIAs XVmC Bibliothek, die bei Einblendungen Rot blau " "darstellt und umgekehrt. Diese Option liefert eine provisorische Lösung.\n" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Benutze Weichzeichner als beschleunigte Entflechtungsmethode." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" "Wenn Zeilensprung bei gerätebeschleunigter Ausgabe aktiviert ist,\n" "alterniere zwischen oberer und unterer Hälfte bei doppelter " "Bildwiederholrate.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "Deaktiviere \"BOB\"-Entflechten bei Video ohne Zeilensprung." #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" "Video ohne Zeilensprung benötigt kein Entflechten. Zuschalten nur bei Bedarf " "sollte die Bildqualität verbessern.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "Deaktiviere \"BOB\"-Entflechten während skalierter Einblendungen." #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "Verbessert die Bildqualität von eingeblendeten Texten.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: XShape-Erweiterung nicht verfügbar. Unskalierte Überlagerung " "deaktiviert.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: Fehler bei Fenstererstellung. Unskalierte Überlagerung deaktiviert.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: Fehler bei Bitmapstellung. Unskalierte Überlagerung deaktiviert.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: Unskalierte Einblendung erzeugt (%s Modus).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "automatischer Farbschlüssel" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Veranlasst Xv automatisch den Farbschlüssel zu zeichnen." #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "Bilinearer Skalierungsmodus" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" "Wählt den bilinearen Skalierungsmodus bei Permedia Karten. Die Werte " "bedeuten:\n" "\n" "Permedia 2\n" "0 - deaktiviert bilineares Filtern\n" "1 - aktiviert bilineares Filtern\n" "\n" "Permedia 3\n" "0 - deaktiviert bilineares Filtern\n" "1 - horizontales lineares Filtern\n" "2 - aktiviert volles bilineares Filtern" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "Xv Portnummer" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "Wählt die Xv Portnummer, oder 0 für \"automatisch\"." #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "pitch alignment Abhilfe" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "Einige fehlerhafte Videotreiber benötigen dies zur korrekten Funktion." #: src/video_out/xv_common.h msgid "video display method preference" msgstr "Bevorzugte Bildausgabemethode" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "Bevorzugte Bildausgabemethode bei automatischer XV Portauswahl." #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "Bikubische Filterung" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" "Einige Grafikkarten bieten diese Bildverbesserung an.\n" "Sie lässt sich zusätzlich zu, oder an Stelle von Entflechten nutzen." #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "Deaktiviere exakte Transparenz bei Einblendungen" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" "Spart Rechenleistung bei Einblendungen wie z.B. DVD-Untertiteln.\n" "Sieht aber auch weniger schön aus." #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: Kein Plugin verfügbar zur Behandlung von '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: Fehler, unbekannter Puffertyp: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "Anzahl der Audiopuffer" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Anzahl der Audiopuffer (jeder 2KiB groß), die xine für seine interne " "Warteschlange benutzt. Höhere Werte bedeuten eine flüssigere Wiedergabe bei " "unzuverlässigen Quellen, erhöhen aber auch die Latenzzeit und den " "Speicherverbrauch." #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: Berechnung der Verzögerung unmöglich mit einem nicht verfügbaren " "Audiogerät\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "Schreiben an Soundkarte schlug fehl. Wurde ein USB-Gerät entfernt?\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "Keine Treiberunterstützung für 8 Bit, Konvertierung zu 16 Bit.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "Keine Treiberunterstützung für Mono, Konvertierung zu Stereo.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "Keine Treiberunterstützung für Stereo, Konvertierung zu Mono.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "Methode für Audio/Videosynchronisation" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" "Bei der Audio- und Videowiedergabe sind mindestens zwei Uhren beteiligt: Die " "Systemuhr, anhand der die Videobilder synchronisiert werden, und der " "Zeitgeber der Tonhardware, der die Geschwindigkeit der Audiowiedergabe " "festlegt. Diese Uhren laufen bis auf wenige Ausnahmen nie mit exakt der " "gleichen Geschwindigkeit, außer beide Uhren sind identisch. Im Allgemeinen " "laufen die Uhren nach einiger Zeit auseinander, für was xine zwei Methoden " "anbietet, um Audio und Video zu synchronisieren:\n" "\n" "metronom feedback\n" "Dies ist die Standardmethode, welche einen gegensteuernde Videodrift " "anwendet, sobald die akkumulierte Audiodrift einen Grenzwert überschritten " "hat.\n" "\n" "resample\n" "Bei einige Videohardware, die nur feste Frameraten (wie z.B. die DXR3 oder " "andere Dekoderkarten) unterstützt, funktioniert das Obige nicht, da das " "Video nicht driften kann. Stattdessen wird der Audiodatenstrom resampled, um " "ihn zum Ausgleich des Tonversatzes kürzer oder länger zu machen. Dies " "funktioniert nicht mit Weiterleitung des Tons an einen externen Dekoder." #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "Genauigkeit des Bild-Ton-Gleichlaufs" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" "Normal: halte die Abweichung unter der Treiber-Toleranzschwelle.\n" "Fine: halte die mittlere Abweichung unter 1/8 der Schwelle." #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "Resampling benutzen" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" "Wenn die Abtastrate der dekodierten Audiodaten nicht zu den Fähigkeiten der " "Tonhardware passen, ist eine Adaption namens \"resampling\" nötig. Diese " "Adaption kann dauerhaft aktiviert, deaktiviert oder bei Bedarf automatisch " "aktiviert werden." #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "Wenn !=0, immer auf diese Rate anpassen" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" "Einige Audiotreiber melden nicht korrekt die Fähigkeiten der Tonhardware. " "Durch Eingabe eines Wertes ungleich Null wird erzwungen, dass " "Audiodatenströme immer auf die angegebene Rate resampled werden." #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "Versatz für externe Tondekoder" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Falls sie einen externen Raumklang-Dekoder benutzen und der Ton vor oder " "hinter dem Video ist, kann dies durch einen festen Versatz kompensiert " "werden.\n" "Die Einheit dieses Wertes ist ein \"PTS-Tick\", was dem 90.000stel einer " "Sekunde entspricht." #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "Audiowiedergabe während langsamer/schneller Geschwindigkeit" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" "Diese Option aktiviert die Tonwiedergabe selbst bei " "Wiedergabegeschwindigkeiten ungleich 1×. Die Wiedergabe wird sich verzerrt " "anhören (höhere/tiefere Lage). Falls sie experimentieren und die Tonlage " "erhalten wollen, versuchen sie stattdessen das 'stretch' Audio-Wiedergabe-" "Plugin." #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "Startlautstärke" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Gesamtlautstärke beim Starten von xine." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "Lautstärke beim Starten wiederherstellen" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "Wenn nicht angewählte, lässt xine die Lautstärke beim Starten unverändert." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: Ups, das sollte eigentlich nicht passieren, bitte xine neu " "starten.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "xine-lib: buffer.c: Fataler Defekt: ZU VIELE FREIGABEN\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "%s: unbekannte Bildformatkennung %#x \"%s\"\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "%s: unbekannte Tonformatkennung %#x \"%s\"\n" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "Die Konfigurationsdatei wurde von einer neueren Version von xine verändert." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "Einstellungen von Datei '%s' gelesen\n" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "Lesen der Einstellungen von Datei '%s' schlug fehl: %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: WARNUNG: Ihre Konfigurationsdatei wird nicht gesichert\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "configfile: WARNUNG: Schreiben der Konfiguration nach %s schlug fehl\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: WARNUNG: Lösche möglicherweise defekte Konfigurationsdatei %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: WARNUNG: Überprüfen Sie die Sicherheitskopie %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "" "configfile: Eintrag '%s' darf nicht per Medienadresse geändert werden\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" "Endlosschleife in demux_control_headers_done(). Versuche abzubrechen.\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "Endlosschleife in demux_loop(). Versuche abzubrechen.\n" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "info_helper: Kann locale-Zeichensatz nicht erkennen\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" "info_helper: Umwandlung %s -> UTF-8 nicht unterstützt, Text unverändert\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": open()-Funktion sollte niemals aufgerufen werden\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": Input-Plugin nicht angegeben!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: Fehlschlag beim Lesen der gespeicherten Daten: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: Positionierung fehlgeschlagen: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: Lesefehler im input_rip-Plugin\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: Schreibfehler in Datei bei % Bytes: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: open()-Funktion sollte niemals aufgerufen werden\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: Positionierung fehlgeschlagen\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % Bytes verworfen\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: Eingabe-Plugin nicht angegeben!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: Zielverzeichnis nicht angegeben, bitte die Option 'media.capture." "save_dir' angeben\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "Das Abspeichern von Datenströmen ist solange deaktiviert, bis media.capture." "save_dir in der Konfiguration gesetzt ist." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: Rippen/Zwischenspeichern dieser Quelle nicht erlaubt!\n" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine darf diese Quelle nicht speichern. (Möglicherweise kopiergeschütztes " "Material?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: Dateiname nicht angegeben!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_ipd: Fehler beim Öffnen der Datei %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: Warten aufgegeben\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: Warten fehlgeschlagen: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "Status des Sockets konnte nicht ermittelt werden" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Zugriff verweigert\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Datei nicht gefunden\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Verbindung verweigert\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "map_decoder_list: Kein Platz für Dekoder, übersprungen.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: Unbekannter Plugintyp %d in %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: Unbekannter statisch eingebundener Plugintyp %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: Ignoriere Plugin %s, falsche iface-Version %d (sollte %d " "sein)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "load_plugins: Plugingrenze erreicht, %s konnte nicht geladen werden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" "load_plugins: Plugingrenze erreicht, statisches Plugin konnte nicht geladen " "werden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "Priorität für Dekoder %s" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: Demultiplexer-Plugin %s liefert keine Priorität, xine-lib " "benutzt die Standardpriorität.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: Input-Plugin %s liefert keine Priorität, xine-lib benutzt die " "Standardpriorität.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: Plugin %s:%s gefunden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: Überspringe unlesbares Pluginverzeichnis %s.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: Kann %s nicht untersuchen\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: Kann Pluginbibliothek %s nicht öffnen:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: Kann Plugininformation von %s nicht lesen:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: (Stufe 2) Kann Pluginbibliothek %s nicht öffnen:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Dreck! %s enthält keine Plugininformation.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "Kann Verzeichnis %s nicht anlegen: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "Speichern der Pluginliste fehlgeschlagen: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "Erneuern der Pluginliste fehlgeschlagen: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "Löschen der Pluginliste fehlgeschlagen: %s\n" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" "Die Priorität legt eine Rangfolge fest, falls Medien von mehr als einem " "Dekoder behandelt werden können.\n" "Eine Priorität von 0 aktiviert den Dekoder mit seiner Standardpriorität." #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: Unbekannte Inhaltserkennungsstrategie %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: Benutze Demultiplexer '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: Audio-Plugin <%s> konnte nicht geladen werden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "load_plugins: Kein brauchbarer Audiotreiber.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: Kann Pluginbibliothek %s nicht entladen:\n" "%s\n" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "Allgemeiner Bild-Ton-Zeitversatz" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" "Es ist nicht einfach, Bild und Ton in Übereinstimmung zu bringen.\n" "Xine gleicht die bekannten Verzögerungen selbst aus.\n" "Für äußere Einflüsse wie Flachbildschirme, Verstärker oder ganz\n" "einfach den Abstand zwischen Ihnen und den Lautsprechern, können Sie\n" "hier von Hand das Bild in 1/90000 Sekunden-Schritten verzögern." #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "Synchronisiere mehrere Taktgeber in einem eigenen Thread" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" "Dies hilft bei Problemen mit mehreren (z.B. anwendungseigenen) Taktgebern." #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Zwischenspeichen..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "Falsche Schriftart-Version '%s'. Erwartet %d gefunden %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "Schriftart '%s-%d' bereits geladen, seltsam.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "Laden der Schriftart '%s' schlug fehl (%d <%d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "osd: Fehler beim Suchen der Schriftart %s mit FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "osd: Fehler beim Laden der Schriftart %s mit FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "osd: Schriftart %s nicht gefunden mit FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "osd: Fehler beim Laden der Schriftart %s von XDG\n" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: Kann ft2-Bibliothek nicht initialisieren\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "osd: Kann Schriftgröße nicht ändern (keine skalierbare Schrift?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: Unbekannte Sequenz startet mit Byte 0x%02X in Kodierung \"%s\", " "überspringe\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: Kann landesüblichen Zeichensatz nicht erkennen\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: Umwandlung %s -> %s nicht unterstützt, Text unverändert\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: Fehler beim Laden von Bildzeichen\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: Fehler beim Darstellen von Bildzeichen\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: Schriftart nicht angegeben\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: Fehler beim Laden des Bildzeichens %i\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: Fehler beim Darstellen\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" "Farbpalette (Vordergrund-Rand-Hintergrund) für Untertitel und Einblendungen" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" "Die Palette für Einblendungen und Untertitel ohne eigene Farbangabe. Muster: " "Vordergrund-Rand-Hintergrund." #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "Deckkraft für Schwarz in grafischen Untertiteln" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "Deckkraft für Farbe in grafischen Untertiteln" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: Kein Plugin gefunden zur Behandlung von '%s'\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: Fehler, unbekannter Puffertyp: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "Anzahl der Videopuffer" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Anzahl der Videopuffer (jeder 8KiB groß), die xine für seine interne " "Warteschlange benutzt. Höhere Werte bedeuten eine flüssigere Wiedergabe bei " "unzuverlässigen Quellen, erhöhen aber auch die Latenzzeit und den " "Speicherverbrauch." #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" "video_out: unbrauchbaren Bildpuffer gefunden (%dx%d, format %0x08x) - " "Speicherplatzmangel??\n" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d Bilder angezeigt, %d Bilder übersprungen, %d Bilder verworfen\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: Verwerfe Bild mit pts %, weil es zu alt ist (Unterschied: " "%).\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "Deaktiviere Dekoderleerung durch Videoausgabe" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" "Der Videodekoder wird geleert, wenn er lange keine neuen Bilder geliefert " "hat.\n" "Ausschalten behebt einige vorübergehende Bildstörungen.\n" "Es kann aber möglicherweise auch Probleme mit DVD-Standbildern verursachen.\n" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "video_out: %d von %d Bildpuffern verwendet\n" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "video_out: Kein Bild bei %d von %d Durchläufen\n" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "Begrenze Ausgabe-Bildrate" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" "Wenn nicht 0, begrenze Ausgabe-Bildrate auf diesen Wert, ohne zusätzliches " "Ruckeln.\n" "Versuchen Sie 40 um Strom zu sparen und/oder einen langsamen Treiber zu " "entlasten.\n" "Ansonsten ist die aktuelle Bildschirm-Wiederholrate plus 5 eine gute " "Idee ;-)\n" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "Erlaubter Prozentsatz für übersprungene Bilder" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" "Melde, wenn so viel Prozent der Videobilder nicht rechtzeitig dekodiert " "werden konnten." #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "Erlaubter Prozentsatz für verworfene Bilder" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" "Melde, wenn so viel Prozent der Videobilder nicht rechtzeitig dargestellt " "werden konnten." #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out : Ups, das sollte eigentlich nicht passieren, bitte xine neu " "starten.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "Horizontale Bildposition im Ausgabefenster" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" "Wenn die horizontale Größe des Videofensters größer als die des aktuell " "angezeigten Bildes ist, kann die Position, wo das Bild platziert wird, " "angepasst werden.\n" "Die Position wird als Prozentzahl angegeben: Der Wert 50 bedeutet \"in der " "Mitte\", während 0 \"ganz links\" und 100 \"ganz rechts\" bedeuten." #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "Vertikale Bildposition im Ausgabefenster" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" "Wenn die vertikale Größe des Videofensters größer als die des aktuell " "angezeigten Bildes ist, kann die Position, wo das Bild platziert wird, " "angepasst werden.\n" "Die Position wird als Prozentzahl angegeben: Der Wert 50 bedeutet \"in der " "Mitte\", während 0 \"ganz oben\" und 100 \"ganz unten\" bedeuten." #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "Alle Videoskalierungen deaktivieren" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" "Wenn das Videobild immer in der Originalauflösung angezeigt werden soll, " "können Sie hier die Skalierung des Bildes deaktivieren.\n" "Natürlich bedeutet dies, dass das Bild nicht länger an die Fenstergröße " "angepasst wird und das Videos, deren Bildpunktseitenverhältnis nicht 1:1 ist " "(z.B. amorphe DVDs), verzerrt angezeigt werden. Andererseits profitieren " "einige Videoausgabetreiber wie XShm davon, deren Bildskalierung nicht " "gerätebeschleunigt ist, wodurch die CPU-Auslastung drastisch sinkt." #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "Betrachte Monitor-Bildpunkte als genau quadratisch" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" "Viele Monitore haben \"nur\" fast quadratische Bildpunkte, wie z.B. 94x93 " "dpi.\n" "Für Druckgrafik und ähnliche Anwendungen ist diese kleine Abweichung " "wichtig.\n" "Für Video bedeutet sie hingegen oft nur unnötige schwarze Balken und weniger " "Bildschärfe.\n" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "Deaktiviere Dekoderleerung bei Zeitsprüngen" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" "Der Videodekoder wird nach Sprüngen in der Zeitleiste geleert.\n" "Ausschalten behebt gelegentliche Bildstörungen bei DVB (TV).\n" "Es kann aber möglicherweise auch Probleme mit DVD-Standbildern verursachen.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: Medienadresse unverständlich\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: Eingabe-Plugin gefunden: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: Plugin kann Medienadresse [%s] nicht öffnen\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: Kann kein Plugin für Medienadresse [%s] finden\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: Demultiplexer %s startete nicht\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: Öffne Mitschnitt-Plugin\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: Fehler beim Öffnen einer Mitschnitt-Plugin-Instanz\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: Letztes Demultiplexer-Plugin %s startete nicht\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "Ignoriere Bild\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "Ignoriere Ton\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "Ignoriere Untertitel\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "Input-Cache Plugin deaktiviert\n" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "Untertitel-Medienadresse öffnete '%s'\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: Fehler beim Öffnen der Untertitel-Medienadresse\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "xine: Ignoriere unbekannte Option \"%s\".\n" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: Das Ändern der Option '%s' per Medienadresse ist verboten\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "xine: Ignoriere \"%s\" ohne Wertangabe.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "xine: Kann Demultiplexer %s für >%s< nicht laden\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: Kann keinen Demultiplexer für >%s< finden\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: Demultiplexer gefunden: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine: Demultiplexer schon fertig - so schnell?\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: Demultiplexer startete nicht\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: Kein Demultiplexer vorhanden\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: Demultiplexer startete nicht\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "xine: Das angegebene save_dir '%s' kann ein Sicherheitsproblem sein.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "Das angegebene save_dir kann ein Sicherheitsproblem sein." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: Sprache wird nicht von C-Bibliothek unterstützt\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "Medienformaterkennungsstrategie" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" "xine bietet verschiedene Methoden, um das Medienformat der Quelle zu " "erkennen. Die Werte bedeuten:\n" "\n" "default\n" "Zuerst anhand des Inhalts erkennen, dann anhand der Dateiendung.\n" "\n" "reverse\n" "Zuerst anhand der Dateiendung erkennen, dann anhand des Inhalts.\n" "\n" "content\n" "Nur anhand des Inhalts erkennen.\n" "\n" "extension\n" "Nur anhand der Dateiendung erkennen.\n" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "Pfad zum Sichern von Datenströmen" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" "Wenn Datenströme gesichert werden sollen, werden Dateien in dieses " "Verzeichnis geschrieben.\n" "Diese Einstellung ist Sicherheitskritisch, da falle sie geändert wird, xine " "benutzt werden kann, um Dateien mit beliebigen Inhalt zu füllen. Stellen Sie " "sicher, dass das Verzeichnis robust ist für beliebige Inhalte in jeder Datei." #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" "Erlaube implizierte Änderungen an Konfiguration (z.B. durch Medienadresse)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" "Falls aktiviert, können Einstellungen auch ohne eine explizite Aktion " "Ihrerseits verändert werden. Zum Beispiel werden durch Medienadressen oder " "durch die Wiedergabeliste geforderte Konfigurationsänderungen ausgeführt.\n" "Diese Einstellung ist sicherheitskritisch, da xine Medienadressen oder " "Wiedergabelisten von nicht vertrauenswürdigen Stellen empfangen kann. Falls " "diese willkürlichen Änderungen erlaubt sind, kann dies zu einem schlecht " "konfigurierten xine führen." #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "Zeitüberschreitung für Netzwerkdatenströme (in Sekunden)" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" "Gibt die maximale Zeitspanne zum Lesen von Netzwerkdatenströmen in Sekunden " "an. Zu niedrige Werte können das Streamen behindern, wenn die Quelle zu " "langsam ist oder die Bandbreite erschöpft ist. Zu hohe Werte können xine " "einfrieren lassen, wenn die Verbindung abbricht." #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "Verwende diese Internet Protokoll-Version(en)" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" "\"auto\" nimmt einfach die Namensauskunft wörtlich.\n" "Ansonsten bietet IPv4 möglicherweise mehr Kompatibilität und Privatsphäre." #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "Setze getrennte Bild/Tondateien automatisch zusammen" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" "Beim Öffnen einer Tondatei \"foo_a.ext\", versuche das dazu gehörige Bild in " "\"foo_v.ext\" zu finden und umgekehrt.\n" "Dies ist hauptsächlich ein Test für \"side streams\"." #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "Verwende Tonpegel wie bei libxine-Versionen vor 1.2.13" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" "Ein: 0..200 bedeutet 0..200% Amplitude für Tonverstärkungspegel und " "Equalizer.\n" " Manche Anwendungen verlassen sich darauf, und verwenden ihre eigene " "Anpassung.\n" "Aus: 100 bedeutet immer noch 100% oder 0 dB. Ein Schritt von 1 bedeutet dann " "jedoch\n" " plus oder minus 1 dB für Tonverstärkung, und 0.5 dB für Equalizer.\n" #: src/xine-engine/xine.c msgid "messages" msgstr "Nachrichten" #: src/xine-engine/xine.c msgid "plugin" msgstr "Plugin" #: src/xine-engine/xine.c msgid "trace" msgstr "Programmverfolgung" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Warnung:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "Unbekannter Rechner:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Unbekanntes Gerät:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Netzwerk unerreichbar" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Verbindung verweigert:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "Datei nicht gefunden:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Lesefehler von:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Fehler beim Laden der Bibliothek:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Verschlüsselter Mediendatenstrom erkannt" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Sicherheitsmeldung:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Audiogerät nicht verfügbar" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Berechtigungsfehler" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "Datei ist leer:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "Zugangsberechtigung erforderlich" #: src/xine-engine/xine_interface.c msgid "Recording done:" msgstr "Aufzeichnung beendet:" #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Geschwindigkeitsvergleich der memcpy-Methoden (klein ist besser):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "xines Methode zum Kopieren von Speicher" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" "Das Kopieren von großen Speicherblöcken ist eine der langsamsten Operationen " "in heutigen Computern. Deshalb unterstützt xine verschiedene optimierte " "Methoden für dieses Kopieren, von denen normalerweise automatisch die beste " "gewählt wird." #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "" #~ "configfile: WARNUNG: Sichern der Konfigurationsdatei nach %s schlug fehl\n" #~ msgid "%s: joining metronom thread ...\n" #~ msgstr "%s: Trete Metronom bei ...\n" #~ msgid "%s: metronom thread joined.\n" #~ msgstr "%s: Metronom beigetreten.\n" #~ msgid "%s: audio: %s\n" #~ msgstr "%s: Ton: %s\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: Medienadresse unverständlich\n" #~ msgid "raw device set up for DVD access" #~ msgstr "Pfad zum RAW-Device des DVD-Laufwerks" #~ msgid "" #~ "If this points to a raw device connected to your DVD device, xine will " #~ "use the raw device for playback. This has the advantage of being slightly " #~ "faster and of bypassing the block device cache, which avoids throwing " #~ "away important cache content by keeping DVD data cached. Using the block " #~ "device cache for DVDs is useless, because almost all DVD data will be " #~ "used only once.\n" #~ "See the documentation on raw device setup (man raw) for further " #~ "information." #~ msgstr "" #~ "Falls dies der Pfad zu dem RAW-Device des DVD-Laufwerks ist, wird xine " #~ "dieses zur Wiedergabe benutzen. Dies bietet einen Geschwindigkeitvorteil " #~ "und vermeidet es, das wichtige Daten auf dem Cache durch DVD-Daten " #~ "verdrängt werden. Das benutzen des Zwischenspeichers für Blockgeräte für " #~ "DVD-Daten ist zwecklos, da die DVD Daten nur einmal benutzt werden.\n" #~ "Lesen Sie die Dokumentation zu RAW-Devices (man raw) für weitere " #~ "Informationen." #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "Die vorherige Nachricht hat einen unbekannten Log-Level" #~ msgid "load_plugins: static plugin %s found\n" #~ msgstr "load_plugins: eingebautes Plugin %s gefunden\n" xine-lib-1.2/po/en@boldquot.header0000644000175000017500000000247114647725152014734 0ustar meme# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # # This catalog furthermore displays the text between the quotation marks in # bold face, assuming the VT100/XTerm escape sequences. # xine-lib-1.2/po/ja.po0000644000175000017500000050132114647725152012236 0ustar meme# Japanese translation of xine-lib po file. # Copyright (C) YEAR Copyright (C) 2000-2010 the xine project # This file is distributed under the same license as the xine-lib package. # Takeshi Hamasaki , 2010. # msgid "" msgstr "" "Project-Id-Version: xine-lib 1.1.19\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2010-07-31 01:14+0700\n" "Last-Translator: Takeshi Hamasaki \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/hstrerror.c msgid "No error" msgstr "エラーなし" #: lib/hstrerror.c msgid "Unknown host" msgstr "不明なホストです" #: lib/hstrerror.c msgid "No address associated with name" msgstr "名前に対応するアドレスがありません" #: lib/hstrerror.c msgid "Unknown server error" msgstr "不明なサーバエラー" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "ホスト名の検索に失敗しました" #: lib/hstrerror.c msgid "Unknown error" msgstr "不明なエラー" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out:既に開いています...なぜ?!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: %s で snd_pcm_open() が失敗: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>> 他のプログラムが PCM を使用していないか確認してください " "<<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: このPCMのための設定が壊れています: 有効な設定がありません: %" "s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1チャネル" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5チャネル" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr "8ビット" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16ビット" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24ビット" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 24ビット" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "サウンドカードは mmap を使用可能" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "サウンドカードと ALSA ドライバがメモリマップドIO をサポートしている場合には有" "効にしてください。\n" "一度有効にしてきちんと働くか確認してみてください。大丈夫なら性能が向上しま" "す。" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr "モノラル" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr "ステレオ" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4チャネル" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1チャネル" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() が失敗: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_coreaudio_out.c #, fuzzy msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "エラー" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "成功" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "アクセスが拒否されました" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "指定された波形形式はサポートされていません" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "不明なエラー" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "" #: src/audio_out/audio_directx_out.c #, fuzzy msgid "xine audio output plugin for win32 using directx" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "" #: src/audio_out/audio_file_out.c #, fuzzy msgid "xine file audio output plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "JACK 音声デバイス名" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" #: src/audio_out/audio_none_out.c #, fuzzy msgid "xine dummy audio output plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "OSS 音声デバイス名" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr "" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "Sun mu-law オーディオ" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat input plugin" msgstr "" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c msgid "AIFF file demux plugin" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c msgid "CD Digital Audio demux plugin" msgstr "" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c msgid "image demux plugin" msgstr "" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c msgid "MPEG program stream demux plugin" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c msgid "MPEG audio demux plugin" msgstr "" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c msgid "Id RoQ file demux plugin" msgstr "" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c msgid "SMJPEG file demux plugin" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" #: src/dxr3/dxr3.h #, fuzzy msgid "DXR3 device number" msgstr "%s: デバイス名は `%s' です\n" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" #: src/input/input_cdda.c msgid "query CDDB" msgstr "" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "CDDBサーバ名" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "CDDBサーバのポート番号" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "使用するDVBカードの数" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "DVD ドライブとして使用するデバイス" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "" #: src/input/input_file.c msgid "file input plugin" msgstr "" #: src/input/input_file.c msgid "file browsing start location" msgstr "" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" #: src/input/input_ftp.c msgid "FTP input plugin" msgstr "" #: src/input/input_ftp.c msgid "FTPES input plugin" msgstr "" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "" #: src/input/input_helper.c msgid "list hidden files" msgstr "隠しファイルを表示する" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c msgid "HTTP live streaming input plugin" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "HTTP サーバへ接続中..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: content length = % bytes\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "" #: src/input/input_http.c msgid "http/https input plugin" msgstr "" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "HTTP プロキシのユーザ名" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "HTTP プロキシのホスト名が無効です。" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "HTTP プロキシのパスワード" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "HTTP プロキシのホスト名が無効です。" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "ネットワークの帯域幅" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" #: src/input/input_mms.c msgid "MMS protocol" msgstr "MMSプロトコル" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" #: src/input/input_mpegdash.c msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "" #: src/input/input_net.c msgid "tls input plugin" msgstr "" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/input/input_nfs.c msgid "Network File System (NFS) input plugin" msgstr "" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "" #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "'%s'を解決できません\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "'%s' に接続できません\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "" #: src/input/input_ssh.c msgid "SCP input plugin" msgstr "" #: src/input/input_ssh.c msgid "SFTP input plugin" msgstr "" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c msgid "v4l2 input plugin" msgstr "" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "" #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "" #: src/input/input_v4l.c msgid "Adjusting..." msgstr "調整しています..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "チューナーの名前が見つかりません\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l video device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "VCD ドライブとして使用するデバイス" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "無効なURL\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "対応していないプロトコル\n" #: src/input/multirate_pref.c msgid "Preferred video size" msgstr "" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred bitrate" msgstr "" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END はまだ実装されていません" #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr "" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "字幕のサイズ" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "字幕に使用するフォント" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c #, fuzzy msgid "xine video output plugin using the ascii-art library" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/video_out/video_out_none.c #, fuzzy msgid "xine video output plugin which displays nothing" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "xine video output plugin using VAAPI" msgstr "" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr "" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "Xv のポート番号" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "起動時の音量" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "" #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "バッファリング..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: MRLの構文解析中にエラーが発生しました\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: 入力プラグインが見つかりました : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "画像を無視\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "音声を無視\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "副映像を無視\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "メッセージ" #: src/xine-engine/xine.c msgid "plugin" msgstr "plugin" #: src/xine-engine/xine.c msgid "trace" msgstr "トレース" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Warning:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "不明なホスト:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "不明なデバイス:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Network unreachable" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "接続を拒否されました:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "ファイルがみつかりません:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "読み込みエラー:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "ライブラリの読み込みエラー:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "セキュリティメッセージ:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "音声デバイスが利用できません" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "空のファイル:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c msgid "Recording done:" msgstr "" #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: MRLの構文解析中にエラーが発生しました\n" #~ msgid "CDDB cache directory" #~ msgstr "CDDBキャッシュディレクトリ" #, fuzzy #~ msgid "DVB Channels config file" #~ msgstr "設定ファイル '%s' は空です" #, fuzzy #~ msgid "path to the title key cache" #~ msgstr "キャッシュ生成時に相対パス `%s' が使用されました" #, fuzzy #~ msgid "default number of frame repetitions" #~ msgstr "デフォルトのエントリにリビジョン番号がありません" xine-lib-1.2/po/quot.sed0000644000175000017500000000023114647725152012763 0ustar memes/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g xine-lib-1.2/po/remove-potcdate.sin0000644000175000017500000000066014647725152015115 0ustar meme# Sed script that remove the POT-Creation-Date line in the header entry # from a POT file. # # The distinction between the first and the following occurrences of the # pattern is achieved by looking at the hold space. /^"POT-Creation-Date: .*"$/{ x # Test if the hold space is empty. s/P/P/ ta # Yes it was empty. First occurrence. Remove the line. g d bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } xine-lib-1.2/po/libxine2.pot0000644000175000017500000047104514647725152013555 0ustar meme# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR Copyright (C) 2000-2022 the xine project # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: xine-lib 1.2.13\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" #: lib/hstrerror.c msgid "No error" msgstr "" #: lib/hstrerror.c msgid "Unknown host" msgstr "" #: lib/hstrerror.c msgid "No address associated with name" msgstr "" #: lib/hstrerror.c msgid "Unknown server error" msgstr "" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "" #: lib/hstrerror.c msgid "Unknown error" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c msgid "Linear PCM audio decoder plugin" msgstr "" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "" #: src/audio_out/audio_fusionsound_out.c msgid "xine FusionSound audio output plugin" msgstr "" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr "" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" #: src/audio_out/audio_sndio_out.c msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat input plugin" msgstr "" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c msgid "libavio input plugin" msgstr "" #: src/combined/flac_decoder.c msgid "flac audio decoder plugin" msgstr "" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c msgid "Speex audio decoder plugin" msgstr "" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c msgid "AIFF file demux plugin" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c msgid "CD Digital Audio demux plugin" msgstr "" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c msgid "image demux plugin" msgstr "" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c msgid "MPEG program stream demux plugin" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c msgid "MPEG audio demux plugin" msgstr "" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c msgid "Id RoQ file demux plugin" msgstr "" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c msgid "SMJPEG file demux plugin" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c msgid "WAV file demux plugin" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" #: src/input/input_cdda.c msgid "query CDDB" msgstr "" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "" #: src/input/input_file.c msgid "file input plugin" msgstr "" #: src/input/input_file.c msgid "file browsing start location" msgstr "" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" #: src/input/input_ftp.c msgid "FTP input plugin" msgstr "" #: src/input/input_ftp.c msgid "FTPES input plugin" msgstr "" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "" #: src/input/input_helper.c msgid "list hidden files" msgstr "" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c msgid "HTTP live streaming input plugin" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: content length = % bytes\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "" #: src/input/input_http.c msgid "http/https input plugin" msgstr "" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" #: src/input/input_mms.c msgid "MMS protocol" msgstr "" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" #: src/input/input_mpegdash.c msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "" #: src/input/input_net.c msgid "tls input plugin" msgstr "" #: src/input/input_net.c msgid "gopher input plugin" msgstr "" #: src/input/input_nfs.c msgid "Network File System (NFS) input plugin" msgstr "" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "" #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "" #: src/input/input_ssh.c msgid "SCP input plugin" msgstr "" #: src/input/input_ssh.c msgid "SFTP input plugin" msgstr "" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c msgid "v4l2 input plugin" msgstr "" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "" #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "" #: src/input/input_v4l.c msgid "Adjusting..." msgstr "" #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l video device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "" #: src/input/multirate_pref.c msgid "Preferred video size" msgstr "" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred bitrate" msgstr "" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "" #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" #: src/libw32dll/qt_decoder.c msgid "quicktime audio decoder plugin" msgstr "" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr "" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" #: src/video_out/video_out_mmal.c msgid "xine video output plugin using MMAL" msgstr "" #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "xine video output plugin using VAAPI" msgstr "" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr "" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "" #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "" #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "" #: src/xine-engine/xine.c msgid "plugin" msgstr "" #: src/xine-engine/xine.c msgid "trace" msgstr "" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c msgid "Recording done:" msgstr "" #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" xine-lib-1.2/po/en@quot.header0000644000175000017500000000226314647725152014072 0ustar meme# All this catalog "translates" are quotation characters. # The msgids must be ASCII and therefore cannot contain real quotation # characters, only substitutes like grave accent (0x60), apostrophe (0x27) # and double quote (0x22). These substitutes look strange; see # http://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html # # This catalog translates grave accent (0x60) and apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019). # It also translates pairs of apostrophe (0x27) to # left single quotation mark (U+2018) and right single quotation mark (U+2019) # and pairs of quotation mark (0x22) to # left double quotation mark (U+201C) and right double quotation mark (U+201D). # # When output to an UTF-8 terminal, the quotation characters appear perfectly. # When output to an ISO-8859-1 terminal, the single quotation marks are # transliterated to apostrophes (by iconv in glibc 2.2 or newer) or to # grave/acute accent (by libiconv), and the double quotation marks are # transliterated to 0x22. # When output to an ASCII terminal, the single quotation marks are # transliterated to apostrophes, and the double quotation marks are # transliterated to 0x22. # xine-lib-1.2/po/Makevars.template0000644000175000017500000000445214647725152014615 0ustar meme# Makefile variables for PO directory in any package using GNU gettext. # Usually the message domain is the same as the package name. DOMAIN = $(PACKAGE) # These two variables depend on the location of this directory. subdir = po top_builddir = .. # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = Free Software Foundation, Inc. # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: # - Strings which are not entire sentences, see the maintainer guidelines # in the GNU gettext documentation, section 'Preparing Strings'. # - Strings which use unclear terms or require additional context to be # understood. # - Strings which make invalid assumptions about notation of date, time or # money. # - Pluralisation problems. # - Incorrect English spelling. # - Incorrect formatting. # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = # This tells whether the $(DOMAIN).pot file contains messages with an 'msgctxt' # context. Possible values are "yes" and "no". Set this to yes if the # package uses functions taking also a message context, like pgettext(), or # if in $(XGETTEXT_OPTIONS) you define keywords with a context argument. USE_MSGCTXT = no # These options get passed to msgmerge. # Useful options are in particular: # --previous to keep previous msgids of translated messages, # --quiet to reduce the verbosity. MSGMERGE_OPTIONS = xine-lib-1.2/po/pl.po0000644000175000017500000053577314647725152012301 0ustar meme# translation of pl_PL.po to Polish # Polish xine-lib translation file. # Copyright (C) 2002,2003 Free Software Foundation, Inc. # Bartłomiej Muryn <_4ever_@irc.pl>, 2002,2003. # msgid "" msgstr "" "Project-Id-Version: pl_PL\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2003-05-24 12:36+0200\n" "Last-Translator: Bartłomiej Muryn <_4ever_@irc.pl>\n" "Language-Team: Polish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: pl\n" "X-Generator: KBabel 1.0\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " "|| n%100>=20) ? 1 : 2;\n" #: lib/hstrerror.c msgid "No error" msgstr "" #: lib/hstrerror.c msgid "Unknown host" msgstr "" #: lib/hstrerror.c msgid "No address associated with name" msgstr "" #: lib/hstrerror.c msgid "Unknown server error" msgstr "" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "" #: lib/hstrerror.c msgid "Unknown error" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" # src/xine-engine/audio_out.c:868 #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" # src/liba52/xine_decoder.c:577 #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "włączanie dynamicznego zakresu kompensacji a/52" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" # src/liba52/xine_decoder.c:580 #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "włącz redukcję dźwięku do 2.0 surround stereo" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" # src/xine-engine/audio_out.c:868 #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "wtyczka wyjścia dźwięku używająca file" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr "" # src/audio_out/audio_alsa_out.c:181 src/audio_out/audio_alsa_out.c:728 # src/audio_out/audio_alsa_out.c:913 src/audio_out/audio_alsa_out.c:957 #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "urządzenie użyte w trybie mono" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr "" # src/audio_out/audio_alsa_out.c:191 src/audio_out/audio_alsa_out.c:920 #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "urządzenie użyte w trybie stereo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr "" # src/audio_out/audio_alsa_out.c:201 src/audio_out/audio_alsa_out.c:927 #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "urządzenie użyte do wyjścia 4-kanałowego" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr "" # src/audio_out/audio_alsa_out.c:221 src/audio_out/audio_alsa_out.c:232 # src/audio_out/audio_alsa_out.c:941 src/audio_out/audio_alsa_out.c:948 #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "urządzenie użyte do wyjścia 5.1-kanałowego" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr "" # src/audio_out/audio_alsa_out.c:191 src/audio_out/audio_alsa_out.c:920 #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr "urządzenie użyte w trybie stereo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "" # src/audio_out/audio_alsa_out.c:862 src/audio_out/audio_alsa_out.c:1072 #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "urządzenie miksera alsa" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" # src/audio_out/audio_alsa_out.c:1105 #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" "wtyczka wyjścia dźwięku xine używająca sprzętu/sterowników kompatybilnych z " "systemem alsa" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "wtyczka wyjścia dźwięku używająca Coreaudio/Mac OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" # src/input/input_rtp.c:339 #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr "" # src/xine-engine/video_out.c:890 #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr "" # src/xine-engine/video_out.c:890 #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "" # src/xine-engine/video_out.c:890 #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr "" # src/xine-engine/video_out.c:890 #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "wtyczka wyjścia dźwięku używająca directx (2)" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "wtyczka wyjścia dźwięku używająca directx" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "" # src/audio_out/audio_esd_out.c:414 #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "opóźnienie wyjścia dźwieku esd (regulacja synchronizacji a/v)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "wtyczka wyjścia dźwięku używająca esound" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "wtyczka wyjścia dźwięku używająca file" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "wtyczka wyjścia dźwięku używająca file" # src/audio_out/audio_irixal_out.c:382 #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "maksymalna długość przerwy wyjścia dźwięku irixal w 1/90000s" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" # src/audio_out/audio_irixal_out.c:411 #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "wtyczka wyjścia dźwięku xine używająca IRIX libaudio" # src/input/input_vcd.c:1184 #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "wtyczka wyjścia dźwięku używająca JACK Audio" # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_none_out.c #, fuzzy msgid "xine dummy audio output plugin" msgstr "wtyczka wyjścia dźwięku używająca file" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" # src/audio_out/audio_oss_out.c:708 #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "" "metoda synchronizacji A/V używana przez OSS, zależy od sterownika/sprzętu" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" # src/audio_out/audio_esd_out.c:414 #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "opóźnienie wyjścia dźwieku esd (regulacja synchronizacji a/v)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr "" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "" # src/audio_out/audio_oss_out.c:923 #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" "wtyczka wyjścia dźwięku xine, używająca urządzeń/sterowników kompatybilnych " "z oss" # src/audio_out/audio_alsa_out.c:201 src/audio_out/audio_alsa_out.c:927 #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" # src/audio_out/audio_alsa_out.c:201 src/audio_out/audio_alsa_out.c:927 # src/audio_out/audio_esd_out.c:441 #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "wtyczka wyjścia dźwięku używająca pulseaudio" # src/audio_out/audio_sun_out.c:748 #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" "wtyczka wyjścia dźwięku xine kompatybilna z urządzeniami/sterownikami sun" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" # src/audio_out/audio_sun_out.c:748 #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" "wtyczka wyjścia dźwięku xine kompatybilna z urządzeniami/sterownikami sun" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "wtyczka wejścia pliku" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "jakość post-przetwarzania ffmpeg mpeg-4" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "wtyczka wejścia pliku" # src/audio_out/audio_esd_out.c:441 #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "wtyczka wyjścia dźwięku używająca file" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: ścieżka oznaczona jako vorbis ale nie znaleziono nagłówka strumienia " "vorbis.\n" # src/xine-engine/xine.c:436 #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "wtyczka wyjścia dźwięku używająca file" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "wtyczka wejścia pliku" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Odtwarzanie indeksu..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" # src/demuxers/demux_avi.c:659 #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: index pliku avi uszkodzony\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c msgid "CD Digital Audio demux plugin" msgstr "" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" # src/demuxers/demux_film.c:176 #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "nieprawidłowy rozmiar fragmentu filmu\n" # src/demuxers/demux_film.c:254 #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "nie rozpoznany fragment filmu\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" # src/input/input_http.c:640 #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "wtyczka wejścia pliku" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "nieznany typ bloku; proszę skontaktować się z programistami xine\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" # src/demuxers/demux_mpeg_block.c:456 #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: uwaga: nagłówek pes wskazuje na to ze strumień może być " "zaszyfrowany (tryb szyfrowania %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" # src/input/input_http.c:640 #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "wtyczka strumienia standardowego wejścia" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" # src/demuxers/demux_mpeg_block.c:456 #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: uwaga: nagłówek pes wskazuje na to ze strumień może być " "zaszyfrowany (tryb szyfrowania %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "nieznany typ kompresji VOC (0x%02X); proszę skontaktować się z programistami " "xine\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c msgid "MPEG audio demux plugin" msgstr "" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "wtyczka wejścia pliku" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "wtyczka wejścia pliku" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: błędne parametry nagłówka\n" # src/demuxers/demux_avi.c:1257 #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: niewspierany typ dźwięku %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" # src/xine-engine/xine.c:436 #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "nieznany typ bloku VOC (0x%02X); proszę skontaktować się z programistami " "xine\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "nieznany typ kompresji VOC (0x%02X); proszę skontaktować się z programistami " "xine\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "wtyczka wejścia pliku" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" "demux_wc3movie: fragment zrzutu odnosi się do błędnej palety (%d >= %d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "demux_wc3movie: Wystąpił problem przy ładowaniu fragmentów palety\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" # src/dxr3/dxr3_decode_video.c:176 #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "próbuj synchronizować każdą ramkę" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" # src/dxr3/dxr3_decode_video.c:180 #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "użyj alternatywnego trybu odtwarzania" # src/dxr3/dxr3_decode_video.c:181 src/dxr3/video_out_dxr3.c:161 #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "włączenie tej opcji użyje wygładzonego trybu odtwarzania" # src/dxr3/dxr3_decode_video.c:184 #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "korekta czasu trwania ramki w zepsutych strumieniach" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" # src/dxr3/dxr3.h:33 #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "dxr3: nazwa urządzenia" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "" # src/dxr3/dxr3_mpeg_encoders.c:182 #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "dxr3enc: częstotliwość wyjśćia rte mpeg (kbit/s)" # src/dxr3/dxr3_mpeg_encoders.c:183 #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "częstotliwość jaką biblioteka librte powinna użyć dla trybu kodowania dxr3" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "" # src/dxr3/dxr3_mpeg_encoders.c:389 #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "dxr3enc: jakość kodowania fame" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" # src/dxr3/dxr3_scr.c:81 #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "dxr3: priorytet wtyczki SCR" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" # src/dxr3/dxr3_mpeg_encoders.c:182 #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "dxr3enc: częstotliwość wyjśćia rte mpeg (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "" # src/dxr3/video_out_dxr3.c:153 #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "zamiana lini parzystych i nieparzystych" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" # src/dxr3/video_out_dxr3.c:156 #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "dodanie czarnch pasków w celu skorygowania proporcji" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" # src/dxr3/video_out_dxr3.c:160 #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "dxr3: użyj alternatywnego trybu odtwarzania dla kodera mpeg" # src/dxr3/dxr3_decode_video.c:181 src/dxr3/video_out_dxr3.c:161 #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "włączenie tej opcji użyje wygładzonego trybu odtwarzania" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "" # src/dxr3/video_out_dxr3.c:221 #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "koder do zawartości nie-mpeg" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" # src/dxr3/video_out_dxr3.c:260 #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "dxr3: tryb wyjścia tv (tv lub overlay)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" # src/dxr3/video_out_dxr3.c:287 #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "dxr3: wartość koloru kluczowego dla overlay" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" # src/dxr3/video_out_dxr3.c:290 #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "dxr3: zakres koloru kluczowego" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "" "Obcięcie obszaru overlay z góry i z dołu aby uniknąć wyświetlania zielonych " "linii" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "" # src/dxr3/video_out_dxr3.c:303 #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "dxr3: wybór trybu tv" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" # src/audio_out/audio_alsa_out.c:181 src/audio_out/audio_alsa_out.c:728 # src/audio_out/audio_alsa_out.c:913 src/audio_out/audio_alsa_out.c:957 #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" # src/input/input_http.c:134 #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "" # src/input/input_net.c:138 #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "" # src/audio_out/audio_alsa_out.c:201 src/audio_out/audio_alsa_out.c:927 #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" #: src/input/input_cdda.c msgid "query CDDB" msgstr "" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" # src/input/input_http.c:98 #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" # src/input/input_http.c:98 #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" # src/input/input_http.c:98 #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" # src/input/input_http.c:98 #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "" # src/input/input_rtp.c:339 #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" # src/audio_out/audio_alsa_out.c:181 src/audio_out/audio_alsa_out.c:728 # src/audio_out/audio_alsa_out.c:913 src/audio_out/audio_alsa_out.c:957 #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "" # src/input/input_file.c:353 #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "" # src/input/input_file.c:353 #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "" #: src/input/input_file.c msgid "file input plugin" msgstr "wtyczka wejścia pliku" #: src/input/input_file.c msgid "file browsing start location" msgstr "miejsce startu nawigatora plików" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "wtyczka wejścia pliku" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "wtyczka wejścia pliku" # src/input/input_net.c:302 #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "" #: src/input/input_helper.c msgid "list hidden files" msgstr "listowanie ukrytych plików" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" # src/input/input_http.c:640 #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "wtyczka strumienia standardowego wejścia" # src/input/input_rtp.c:339 #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "" # src/input/input_http.c:416 src/input/input_http.c:537 #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: błąd odczytu %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "" # src/input/input_http.c:445 #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: błędna odpowiedź http\n" # src/input/input_http.c:450 #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: przekierowanie 3xx: >%d %s<\n" # src/input/input_http.c:455 #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: status http nie jest 2xx: >%d %s<\n" # src/input/input_http.c:464 #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: długość zawartości = % bytes\n" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "" # src/input/input_http.c:640 #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "wtyczka wejścia http" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" # src/input/input_http.c:640 #: src/input/input_mms.c #, fuzzy msgid "mms streaming input plugin" msgstr "wtyczka strumienia standardowego wejścia" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" #: src/input/input_mms.c msgid "MMS protocol" msgstr "" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" # src/input/input_http.c:640 #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "wtyczka strumienia standardowego wejścia" # src/input/input_net.c:302 #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "wtyczka wejścia net dostarczana z xine" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "wtyczka wejścia pliku" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "wtyczka wejścia pliku" # src/input/input_http.c:640 #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "wtyczka strumienia standardowego wejścia" # src/input/input_http.c:640 #: src/input/input_pnm.c #, fuzzy msgid "pnm streaming input plugin" msgstr "wtyczka strumienia standardowego wejścia" # src/input/input_rtp.c:339 #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "" # src/input/input_file.c:353 #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "" # src/input/input_rtp.c:157 #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "" # src/input/input_rtp.c:157 #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" # src/input/input_rtp.c:157 #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "" # src/input/input_rtp.c:167 #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "" # src/input/input_rtp.c:185 #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) zawiodło (multicast kernel?): %s.\n" # src/input/input_rtp.c:205 #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "nie mogę znaleźć IP dla '%s'.\n" # src/input/input_rtp.c:218 #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "nie da się dowiązać do '%s'.\n" # src/input/input_rtp.c:157 #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: zatrzymuje odczyt wątku...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: odczyt wątku zakończony\n" #: src/input/input_rtp.c #, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "" # src/input/input_rtp.c:339 #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: nie mogę utworzyć nowego wątku (%s)\n" # src/input/input_net.c:302 #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "wtyczka wejścia RTP i UDP dostarczana z xine" # src/input/input_http.c:640 #: src/input/input_rtsp.c #, fuzzy msgid "rtsp streaming input plugin" msgstr "wtyczka strumienia standardowego wejścia" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "wtyczka wejścia pliku" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "wtyczka wejścia pliku" # src/input/input_http.c:98 #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "" # src/input/input_http.c:640 #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "wtyczka strumienia standardowego wejścia" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" # src/input/input_http.c:640 #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "wtyczka wejścia pliku" # src/input/net_buf_ctrl.c:67 #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "" # src/input/net_buf_ctrl.c:67 #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "" #: src/input/input_v4l.c msgid "Adjusting..." msgstr "" #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "" # src/input/input_vcd.c:1184 #: src/input/input_v4l.c msgid "v4l video device" msgstr "" # src/input/input_vcd.c:1184 #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "" # src/input/input_vcd.c:1184 #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" # src/input/input_vcd.c:1184 #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "" # src/input/input_vcd.c:1184 #: src/input/input_v4l.c msgid "v4l radio device" msgstr "" # src/input/input_vcd.c:1184 #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "" # src/input/input_rtp.c:205 #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "" # src/input/input_net.c:126 #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "" # src/input/input_http.c:640 #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "wtyczka wejścia VCD" # src/audio_out/audio_alsa_out.c:181 src/audio_out/audio_alsa_out.c:728 # src/audio_out/audio_alsa_out.c:913 src/audio_out/audio_alsa_out.c:957 #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "" # src/input/input_http.c:134 #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "" # src/input/input_http.c:134 #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "" # src/input/input_http.c:416 src/input/input_http.c:537 #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "" # src/input/input_http.c:450 #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: przekierowanie 3xx: >%d %s<\n" # src/input/input_http.c:455 #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: status http nie jest 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "" # src/dxr3/video_out_dxr3.c:303 #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "dxr3: wybór trybu tv" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" # src/dxr3/video_out_dxr3.c:303 #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "dxr3: wybór trybu tv" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" # src/input/input_net.c:138 #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "" # src/input/input_http.c:98 #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "" #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" # src/libw32dll/w32codec.c:1404 src/libw32dll/w32codec.c:1453 #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" # src/libw32dll/w32codec.c:1404 src/libw32dll/w32codec.c:1453 #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "ścieżka do kodeków dll win32" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "wtyczka wyjścia dźwięku używająca file" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" # src/audio_out/audio_esd_out.c:441 #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr "" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" # src/libdivx4/xine_decoder.c:602 #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" # src/libsputext/xine_decoder.c:1078 #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "fonty dla zewnętrznych napisów" # src/libsputext/xine_decoder.c:1084 #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "pionowe wyrównanie napisów (względny rozmiar okna)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" # src/libsputext/xine_decoder.c:1078 #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "kodowanie napisów" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" # src/libsputext/xine_decoder.c:1084 #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" # src/libsputext/xine_decoder.c:1078 #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "fonty dla zewnętrznych napisów" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" # src/libsputext/xine_decoder.c:1078 #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "kodowanie napisów" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" # src/xine-engine/xine.c:436 #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" # src/libspucc/xine_decoder.c:220 #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "włącz closed-caption w strumieniach mpeg-2" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" # src/libspucc/xine_decoder.c:227 #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "schemat (tło/napisy) dla closed-caption" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "" # src/libspucc/xine_decoder.c:233 #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "standardowa czcionka dla closed-caption" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "" # src/libspucc/xine_decoder.c:239 #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "czcionka italic dla closed-caption" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "" # src/libspucc/xine_decoder.c:245 #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "rozmiar czcionki closed-caption" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" # src/libspucc/xine_decoder.c:250 #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "centrowanie closed-caption" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" # src/libspucc/xine_decoder.c:245 #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" # src/xine-engine/video_out.c:890 #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" # src/input/input_http.c:98 #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" # src/input/input_http.c:98 #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" # src/input/input_http.c:98 #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" # src/input/input_http.c:134 #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" # src/input/input_http.c:134 #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" # src/input/input_http.c:98 #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" # src/input/input_rtp.c:339 #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: nie mogę utworzyć nowego wątku (%s)\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" # src/video_out/video_out_aa.c:307 #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "wtyczka wyjścia obrazu xine używająca biblioteki ascii-art" # src/video_out/video_out_aa.c:307 #: src/video_out/video_out_caca.c #, fuzzy msgid "xine video output plugin using the Color AsCii Art library" msgstr "wtyczka wyjścia obrazu xine używająca biblioteki color ascii-art" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" # src/dxr3/video_out_dxr3.c:287 #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "wartość koloru kluczowego dla overlay" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" # src/dxr3/video_out_dxr3.c:287 #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "koloru kluczowego dla overlay" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" # src/video_out/video_out_directfb.c:569 #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "wtyczka wyjścia obrazu xine używająca biblioteki DirectFB" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" # src/video_out/video_out_directfb.c:569 #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "wtyczka wyjścia obrazu xine używająca biblioteki XDirectFB" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" # src/video_out/video_out_vidix.c:869 #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "wtyczka wyjścia obrazu xine używająca directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" # src/video_out/video_out_fb.c:721 #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" # src/video_out/video_out_fb.c:885 #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" "xtyczka wyjścia obrazu xine używająca linuxowego urządzenia buforu ramki" # src/video_out/video_out_directfb.c:569 #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "wtyczka wyjścia obrazu xine używająca biblioteki DirectFB" # src/video_out/video_out_directfb.c:569 #: src/video_out/video_out_none.c #, fuzzy msgid "xine video output plugin which displays nothing" msgstr "wtyczka wyjścia obrazu xine używająca biblioteki DirectFB" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" # src/video_out/video_out_directfb.c:569 #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "wtyczka wyjścia obrazu xine używająca biblioteki OpenGL 2.0" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" # src/video_out/video_out_opengl.c:1124 #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "wtyczka wyjścia obrazu xine używająca OpenGL - TNG" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" # src/video_out/video_out_fb.c:885 #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "wtyczka wyjścia obrazu xine dla Sun PGX32 urządzenia buforu ramki" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "" # src/dxr3/video_out_dxr3.c:287 #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "wartość koloru kluczowego dla overlay" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" # src/video_out/video_out_fb.c:885 #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" "wtyczka wyjścia obrazu xine dla Sun XVR100/PGX64/PGX24 urządzenia buforu " "ramki" # src/video_out/video_out_aa.c:307 #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "" # src/video_out/video_out_sdl.c:696 #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "wtyczka wyjścia obrazu xine używająca Simple Direct Media Layer" # src/video_out/video_out_aa.c:307 #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" "wtyczka wyjścia obrazu xine używająca biblioteki Libstk Surface Set-top " "Toolkit" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" # src/video_out/video_out_directfb.c:569 #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "wtyczka wyjścia obrazu xine używająca biblioteki DirectFB" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" # src/video_out/video_out_directfb.c:569 #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "wtyczka wyjścia obrazu xine używająca biblioteki VDPAU" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "" # src/dxr3/video_out_dxr3.c:290 #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "" # src/dxr3/video_out_dxr3.c:290 #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "" # src/dxr3/video_out_dxr3.c:287 #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "" # src/video_out/video_out_vidix.c:869 #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "wtyczka wyjścia obrazu xine używająca libvidix dla X11" # src/video_out/video_out_fb.c:885 #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" "wtyczka wyjścia obrazu xine używająca libvidix dla linuxowego urządzenia " "buforu ramki" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" # src/video_out/video_out_xshm.c:1445 #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "" # src/video_out/video_out_xshm.c:1445 #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" "wtyczka wyjścia obrazu xine używajaca rozszerzenie dzielonej pamięci MIT X" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" # src/video_out/video_out_xv.c:1479 #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "wtyczka wyjścia obrazu xine używająca rozszerzenia obrazu MIT X" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr "" # src/video_out/video_out_xv.c:1479 #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "wtyczka wyjścia obrazu xine używająca rozszerzenia obrazu XvMC" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "Auto-tworzenie koloru-klucza przez Xv" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Auto-tworzenie koloru-klucza przez Xv" # src/video_out/video_out_xv.c:1408 #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "tryb skalowania bilinearnego" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "wybierz metodę synchronizacji dźwięku z obrazem" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" # src/xine-engine/audio_out.c:828 #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "jeśli !=0 zawsze ponowne próbkowanie do podanej częstotliwości" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" # src/xine-engine/audio_out.c:868 #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "głośność dźwięku" # src/xine-engine/audio_out.c:872 #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "przywracanie głośności przy starcie" # src/xine-engine/audio_out.c:872 #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "przywracanie głośności przy starcie" # src/xine-engine/audio_out.c:873 #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "jeśli ustawione - xine nie będzie zmieniać żadnych ustawień miksera przy " "starcie" # src/xine-engine/video_out.c:893 #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: przykro mi, to nie powinno sie zdarzyć.\n" "Proszę ponownie uruchomić xine.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" # src/input/input_http.c:98 #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" "info_helper: nie można znaleźć zestawu znaków dla aktualnej lokalizacji\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "info_helper: niewspierana konwersja %s -> UTF-8\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr "" #: src/xine-engine/input_cache.c #, fuzzy, c-format msgid ": input plugin not defined!\n" msgstr "osd: nie został zdefiniowany font\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "" # src/input/input_http.c:640 #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "" # src/input/input_rtp.c:339 #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: nieznany typ wtyczki %d w %s\n" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: wtyczka %s:%s znaleziona\n" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: pomijanie katalogu wtyczek nie do odczytu %s.\n" # src/xine-engine/load_plugins.c:520 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: nie udał się start %s\n" # src/xine-engine/load_plugins.c:138 #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nie mogę otworzyć biblioteki wtyczki %s:\n" "%s\n" # src/xine-engine/load_plugins.c:300 #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: nie mogę pobrać informacji z %s:\n" "%s\n" # src/xine-engine/load_plugins.c:138 #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nie mogę (etap 2) otworzyć biblioteki wtyczki %s:\n" "%s\n" # src/xine-engine/load_plugins.c:300 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: nie mogę pobrać informacji z %s\n" # src/input/input_rtp.c:205 #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "" # src/xine-engine/load_plugins.c:153 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "" # src/xine-engine/load_plugins.c:520 #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" # src/xine-engine/load_plugins.c:138 #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" # src/input/net_buf_ctrl.c:67 #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Buforowanie..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: nieznana sekwencja zaczynająca się od bajtu 0x%02X w kodowaniu \"%s\", " "pomijanie\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: nie można znaleźć zestawu znaków dla aktualnej lokalizacji\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: niewspierana konwersja %s -> %s\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: nie został zdefiniowany font\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "" # src/xine-engine/osd.c:863 #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "paleta użyta przy napisach (tło-napisy-kontur)" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" # src/xine-engine/video_out.c:308 #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d ramek dostarczonych, %d ramek pominiętych, %d ramek porzuconych\n" # src/xine-engine/video_out.c:351 #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: odrzucam obraz o pts % bo jest za stary (diff : %" ").\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" # src/xine-engine/video_out.c:893 #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out: przykro mi, to nie powinno sie zdarzyć.\n" "Proszę ponownie uruchomić xine.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" # src/video_out/video_out_fb.c:705 src/video_out/video_out_xshm.c:1283 #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "wyłącz skalowanie obrazu (szybsze!)" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "" # src/xine-engine/xine.c:415 #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "" # src/xine-engine/xine.c:415 #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "" # src/xine-engine/xine.c:415 #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "" # src/xine-engine/xine.c:471 #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: zawiódł start wybranego demultiplexera %s\n" # src/input/input_http.c:640 #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "" # src/input/input_http.c:640 #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "" # src/xine-engine/xine.c:471 #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: zawiódł start ostatnio próbowanego demultiplexera %s\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" # src/xine-engine/xine.c:436 #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "xine: nie mogę znaleźć demultiplexera %s dla >%s<\n" # src/xine-engine/xine.c:436 #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: nie mogę znaleźć demultiplexera dla >%s<\n" # src/xine-engine/xine.c:436 #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "" # src/xine-engine/xine.c:471 #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "" # src/xine-engine/xine.c:471 #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: zawiódł start demultiplexera\n" # src/xine-engine/xine.c:471 #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: brak dostępnego demultiplexera\n" # src/xine-engine/xine.c:471 #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: zawiódł start demultiplexera\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" # src/xine-engine/xine.c:1025 #: src/xine-engine/xine.c msgid "messages" msgstr "wiadomości" # src/xine-engine/xine.c:1026 #: src/xine-engine/xine.c msgid "plugin" msgstr "wtyczka" #: src/xine-engine/xine.c msgid "trace" msgstr "" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "" # src/input/input_file.c:353 #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Odtwarzanie indeksu..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" # src/input/input_file.c:353 #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: błąd odczytu (%s)\n" # src/input/input_net.c:102 #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" # src/input/input_net.c:111 #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" # src/input/input_net.c:126 #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: nie mogę znaleźć IP dla '%s'.\n" # src/input/input_net.c:138 #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: nie mogę podłączyć się do '%s'.\n" xine-lib-1.2/po/insert-header.sin0000644000175000017500000000124014647725152014544 0ustar meme# Sed script that inserts the file called HEADER before the header entry. # # At each occurrence of a line starting with "msgid ", we execute the following # commands. At the first occurrence, insert the file. At the following # occurrences, do nothing. The distinction between the first and the following # occurrences is achieved by looking at the hold space. /^msgid /{ x # Test if the hold space is empty. s/m/m/ ta # Yes it was empty. First occurrence. Read the file. r HEADER # Output the file's contents by reading the next line. But don't lose the # current line while doing this. g N bb :a # The hold space was nonempty. Following occurrences. Do nothing. x :b } xine-lib-1.2/po/boldquot.sed0000644000175000017500000000033114647725152013625 0ustar memes/"\([^"]*\)"/“\1”/g s/`\([^`']*\)'/‘\1’/g s/ '\([^`']*\)' / ‘\1’ /g s/ '\([^`']*\)'$/ ‘\1’/g s/^'\([^`']*\)' /‘\1’ /g s/“”/""/g s/“/“/g s/”/”/g s/‘/‘/g s/’/’/g xine-lib-1.2/po/nl.po0000644000175000017500000077300414647725152012266 0ustar meme# Copyright (C) 2000-2023 the xine project # This file is distributed under the same license as the xine-lib package. # # Ronald Stroethoff , 2023. msgid "" msgstr "" "Project-Id-Version: xine-lib 1.2.13-20230125hg15249\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2023-02-19 19:27+0100\n" "Last-Translator: Ronald Stroethoff \n" "Language-Team: Dutch \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: nl\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Lokalize 21.12.3\n" #: lib/hstrerror.c msgid "No error" msgstr "Geen fout" #: lib/hstrerror.c msgid "Unknown host" msgstr "Onbekende host" #: lib/hstrerror.c msgid "No address associated with name" msgstr "Bij deze naam hoort geen adres" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Onbekende serverfout" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Servernaam opzoeken mislukte" #: lib/hstrerror.c msgid "Unknown error" msgstr "Onekende fout" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "dvaudio: Vergroot buffer naar %d om overflow te vermeiden.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "Digital Video (DV) Decoder" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "GSM 6.10 Audio Decoder" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "HELP! Een audio driver met alleen mono?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "liba52 A52/AC3 audio decoder" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "A/52 volume" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" "Met A/52 audio kan de volume op decoder-niveau aangepast worden. Dit heeft " "het voordeel dat de code van de audio al op dat specifieke volume is " "ingesteld is zodat de volgende bewerkingen zoals downmixing direct op de " "audio-stream met dat volume werkt." #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "Gebruik dynamische A/52 dynamische range compressie" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" "Dynamische range compressie reduceert het dynamische bereik van de audio: " "luide geluiden klinken zachter en zachte geluiden klinken luider. dit maakt " "dat u makkelijker naar de audio kan luisteren in een luidruchtige omgeving " "zonder dat u andere mensen stoort." #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "Converteer audio naar tweekanaals surround stereo" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" "Als u naar een surround geluid wilt luisteren, maar u heeft maar twee " "luidsprekers of u heeft een Matrix-surround-decoder zoals de ProLogic, dan " "kunt u de extra kanalen naar het stereo-signaal laten converteren." #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "A/52 bass naar stereo volume" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" "Gebruik dit om het bass-effect te krijgen,\n" "als u grote stereo luidsprekers\n" "of een analoge subwoofer heeft." #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "DTS audio doorgave naar een externe decoder" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() faalde.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 faalde.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit faalde.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "Freeware Advanced audio decoder" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "FAAD geluidsniveau aanpassen (in dB)" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" "Enkele AAC tracks zijn te luid opgenomen en klinken daarom vervormd.\n" "De volumeregelaar kan dat niet corrigeren, maar deze instelling wel." #: src/audio_dec/xine_lpcm_decoder.c msgid "Linear PCM audio decoder plugin" msgstr "Lineaire PCM audio decoder" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "libmad MPEG 1/2/3 audio decoder" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "libmusepack: mpc_demux_init faalde\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: mpc_streaminfo_read faalde: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: data na het laatste frame genegeerd\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: mpc_decoder_initialise faalde\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: mpc_decoder_decode faalde: %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "MusePack audio decoder" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out:Al geopend...WAAROM?" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() van %s faalde: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>> Controleer of PCM al in gebruik is bij een ander " "programma<<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: defecte configuratie voor dit PCM: geen configuratie " "beschikbaar: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "Informeren over wijzigingen in de hardwaremixer" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "Als de instellingen van de hardwaremixers wijzigen dan wordt het programma " "daarover geïnformeerd, zodat die de grafische voorstelling van de mixer " "onmiddellijk kan aanpassen." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : Ondersteunde modes zijn" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4-kanaal niet ingeschakeld in de configuratie van xine)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-kanaal" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-kanaal niet ingeschakeld in de configuratie van xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5-kanaal" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5-kanaal niet ingeschakeld in de configuratie van xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-kanaal niet ingeschakeld in de configuratie van xine)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (a/52 en DTS doorgave niet ingeschakeld in de configuratie van xine)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() faalde: %d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Controleer of PCM al in gebruik is bij een ander programma <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8 bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16 bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24 bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32 bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "Geluidskaart kan met mmap overweg" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Schakel dit in als bij uw geluidskaart en de alsa-driver direct toegang tot " "het geheugen mogelijk is.\n" "U kan dit inschakelen en uittesten of alles functioneert. Als dat het geval " "is, dan verbetert dit de prestaties." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "Apparaat mono-weergave" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "XINE gebruikt dit ALSA-apparaat voor de mono-weergave.\n" "Lees de ALSA-documentatie voor informatie over ALSA-apparaten." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " stereo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "Apparaat voor stereoweergave" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "XINE gebruikt dit ALSA-apparaat voor de stereo-weergave.\n" "Lees de ALSA-documentatie voor informatie over ALSA-apparaten." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-kanaal" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "Apparaat voor 4-kanaalweergave" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "XINE gebruikt dit ALSA-apparaat voor de 4-kanaalweergave (4.0 surround " "sound).\n" "Lees de ALSA-documentatie voor informatie over ALSA-apparaten." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-kanaal" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "Apparaat voor 5.1-kanaalweergave" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "XINE gebruikt dit ALSA-apparaat voor de 5-kanaalweergave met LFE (5.1) " "surround sound).\n" "Lees de ALSA-documentatie voor informatie over ALSA-apparaten." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " a/52 en DTS doorgave" #: src/audio_out/audio_alsa_out.c msgid "device used for a/52 and DTS pass-through" msgstr "Apparaat voor a/52 en DTS doorgave" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine gebruikt dit ALSA-apparaat om een niet gecodeerd digitaalsurround " "signaal te creëren om deze naar een externe decoder te sturen.\n" "Lees de ALSA-documentatie voor informatie over ALSA-apparaten." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() faalde: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "ALSA mixer" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine gebruikt deze ALSA-mixer, om het volume te wijzigen.\n" "Lees de ALSA-documentatie voor informatie over ALSA-apparaten." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "xine audio-uitvoer gebruikt ALSA-compatibel apparaat/driver" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "xine audio-uitvoer via Coreaudio/Mac OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Fout" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "success" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "Toegang geweigerd" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "De bron is reeds in gebruik" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "Object was al geïnitialiseerd" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "Opgegeven wave-format wordt niet ondersteund" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "Buffer geheugen is verloren gegaan en moet weer gecreëerd worden" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "De gevraagde buffer controle is niet beschikbaar" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "Onbekende fout in het DirectSound-systeem" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "DirectSound-hardware is niet beschikbaar" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "Functie is ongeldig voor de huidige status van het object" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "Ongeldige parameter werd doorgeven" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "Object ondersteund geen aggregatie" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "Geen audio-driver voor gebruik beschikbaar" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "De gevraagde seriële interface is niet beschikbaar" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "Een ander programma heeft voorrang" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "Onvoldoende geheugen" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "Lage prioriteit voor deze functie" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound was niet geïnitialiseerd" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "Functie wordt niet ondersteund" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "Onbekende fout" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Kan DirectSound-object niet creëren" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "Kon DirectSound-coöperatie niveau niet instellen." #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "Kon geen secundaire DirectSound-buffer creëren" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "Kon buffer niet afspelen" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "Kon afspelen van geluid niet stoppen" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "Kan bufferpositie niet krijgen" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "Kan bufferpositie niet instellen" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "Kon volume niet wijzigen" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": Buffer is verloren, probeer weer te creëren\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "Kon DirectSound-buffer niet reserveren" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "Kon DirectSound-buffer niet vrijgeven" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Kon geen primaire DirectSound-buffer creëren." #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" ": Voorbij weergavepositie (data %zu, min %zu), flushing (legen) buffers\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": Kan buffer-pthread niet creëren: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": Kan buffer-pthread niet vrijgeven: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ": Kan pthread-voorwaarde niet vrijgeven: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": Kan pthread-mutex niet vrijgeven: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr ": Onbekend commando %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": Kan pthread-conditie niet creëren: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": Kan pthread-mutex niet creëren: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "xine audio-uitvoer via directx (tweede variant)" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "xine audio-uitvoer via directx voor win32" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: Bezig met verbinden met ESD Server %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: Bezig met verbinden met ESD Server...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: geen verbinding met ESD Server %s: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "Vertraging van de esd audio-uitvoer (verandert A/V synchronisatie)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Hier kunt u het geluid in stapjes van 1/90000 seconde vertragen, om " "het met het beeld te synchroniseren." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "xine audio-uitvoer via esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "xine audio-uitvoer naar een bestand" #: src/audio_out/audio_fusionsound_out.c msgid "xine FusionSound audio output plugin" msgstr "xine audio-uitvoer via FusionSound" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "Maximaal toegestane gat voor IRIXAL audio-uitvoer" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Vanaf een beeld-audio-vertraging van /90000 seconde probeert xine, " "deze te corrigeren." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "xine audio-uitvoer via IRIX-compatibel apparaat/driver" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "\"Jack Audio\"-apparaat-naam" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" "Het \"Jack Audio\"-apparaat-naam. Laat het leeg, als het niet bekend is." #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "xine audio-uitvoer via JACK Audio systeem" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "Geen xine audio-uitvoer" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Bezig met het openen van het audio-apparaat %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: Waarschuwing: samplesnelheid %d Hz wordt niet ondersteund, " "probeer 44100 Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "audio_oss_out: Audio rate: %d gevraagd, %d aangeboden\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "OSS-apparaat-naam" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "Specificeert het basisgedeelte van het audio-apparaat, waaraan het OSS-" "apparaatnummer gekoppeld wordt, om het complete apparaatnaam te krijgen.\n" "Selecteer \"auto\" als u wilt dat xine automatisch de correcte instelling " "kiezen moet." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "OSS audio-apparaat-nummer, -1 voor geen" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "De volledige naam van het audio-apparaat wordt gecreëerd door samenvoegen " "van het OSS-apparaat-naam en het audio apparaat-nummer.\n" "als u geen nummer nodig heeft (omdat alles goed functioneert), gebruik dan -" "1.\n" "De range die u kunt gebruiken is -1 of 0-15. Deze instelling wordt genegeerd " "als OSS audio-apparaat-naam op \"auto\" is ingesteld." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "audio_oss_out: audio.device.oss_device_name = auto, zoek apparaat\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Automatisch zoeken naar audio apparaten mislukte\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: Apparaat >%s is in gebruik<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: Openen van audio programma %s mislukte:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "A/V synchronisatie-methode voor OSS" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "XINE kan verschillende methoden gebruiken om audio en video te " "synchroniseren. Welke instelling het beste werkt hangt van de OSS-driver en " "de gebruikte geluid-hardware af. Probeer verschillende methoden uit, als u " "synchronisatie-problemen merkt.\n" "\n" "De betekenis van de waarden is als volgt:\n" "\n" "auto\n" "xine probeert automatisch de beste instellingen te vinden\n" "\n" "getodelay\n" "Gebruikt ioctl(SNDCTL_DSP_GETODELAY), zelfs dan als de driver geen realtime " "afspelen aanbiedt\n" "\n" "getoptr\n" "Gebruikt ioctl(SNDCTL_DSP_GETOPTR), zelfs dan als de driver de ioctl" "(SNDCTL_DSP_GETODELAY) als voorkeur aanbiedt\n" "\n" "softsync\n" "Gebruikt software-synchronisatie met de systeem-klok; audio en video kunnen " "erg uit synchronisatie raken als de snelheid van de systeem-klok niet exact " "overeenkomt met die van uw geluidskaart\n" "\n" "probebuffer\n" "Test de grootte van de buffer in de geluidskaart bij de initialisatie om de " "vertraging van de A/V synchronisatie uit te rekenen. Probeer dit uit als uw " "systeem geen van de ioctls voor realtime aanbiedt en als bij een lange film " "problemen met de synchronisatie optreden." #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Audio-realtime-synchronisatie uitgeschakeld...\n" "audio_oss_out: ...Systeem-realtime-klok word voor soft-synchronisatie " "gebruikt\n" "audio_oss_out: ...er kunnen audio/video-synchronisatieproblemen optreden\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "Vertraging van de OSS audio-uitvoer (verandert A/V synchronisatie)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Audio-realtime-synchronisatie uitgeschakeld...\n" "audio_oss_out: ...Bezig met vaststellen van de grootte van de " "uitgangsbuffer: %d Bytes\n" "audio_oss_out: ...er kunnen audio/video-synchronisatieproblemen optreden\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: Ondersteunde modes zijn" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " a/52 doorgave" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (a/52 doorgave niet ingeschakeld in de configuratie van xine)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "OSS audio mixer number, -1 voor geen" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "De volledige naam van de mixer wordt gecreëerd door samenvoegen van het OSS-" "apparaat-naam, waarbij u \"dsp\" door \"mixer\" vervangt en het mixer nummer " "toevoegt.\n" "als u geen nummer nodig heeft (omdat alles goed functioneert), gebruik dan -" "1.\n" "De range die u kunt gebruiken is -1 of 0-15. Deze instelling wordt genegeerd " "als OSS audio-apparaat-naam op \"auto\" is ingesteld." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: openen () mixer %s mislukte: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "xine audio-uitvoer via OSS-compatibel apparaat/driver" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "Apparaat voor pulse-audio" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" "Gebruik 'server[:sink]' voor het instellen van het pulse-audio sink apparaat." #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr "a/52 doorgave gebruiken" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Audiodata naar een externe digitale audio decoder doorgeven met de hulp van " "pulseaudio.\n" "U moet een een verbinding maken met een digitale audio-decoder die in staat " "is om de audioformaten te decoderen die u wilt afspelen." #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "xine audio-uitvoer via pulse-audio soundserver" #: src/audio_out/audio_sndio_out.c msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "xine audio-uitvoer via sndio" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: Openen van audio programma %s mislukte: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "Sun Audio-apparaat-naam" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Specificeert de naam van het Sun audio-apparaat.\n" "OPGEPAST: Een verkeerde naam zorgt dat een bestand met deze naam wordt " "gecreëerd (of overschreven) met reusachtige hoeveelheden data! Zorg er " "daarom voor dat de ingevoerde naam een echt Sun audio-apparaat is." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "audio_sun_out: Audio ioctl op apparaat %s faalde: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "xine audio-uitvoer via SUN-compatibel apparaat/driver" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "Opstelling luidsprekers" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Stel in hoe uw luidsprekers zijn opgesteld. Dit bepaald welke luidsprekers " "xine voor het geluid gebruikt. De mogelijke opstellingen zijn:\n" "\n" "Mono 1.0: U heeft maar een luidspreker.\n" "Stereo 2.0: U heeft twee luidsprekers (voor links en voor rechts).\n" "Headphones 2.0: U gebruikt een koptelefoon.\n" "Stereo 2.1: U heeft drie luidsprekers (voor links en voor rechts, plus " "bas).\n" "Surround 3.0: U heeft drie luidsprekers (voor links en voor rechts, plus " "midden achter).\n" "Surround 4.0: U heeft vier luidsprekers (voor en achter, elk links en " "rechts).\n" "Surround 4.1: Net zoals 4.o, plus bas.\n" "Surround 5.0: U heeft vijf luidsprekers (voor links, voor midden, voor " "rechts en achter links en achter rechts.\n" "Surround 5.1: Net zoals 5.0, plus bas.\n" "Surround 6.0: U heeft zes luidsprekers (voor en achter, elk links, midden en " "rechts).\n" "Surround 6.1: Net zoals 6.0, plus bas.\n" "Surround 7.1: U heeft zeven luidsprekers (voor links, voor midden en voor " "rechts, midden links en midden rechts, achter links en achter rechts plus " "bas.\n" "Pass Through: Uw digitale geluidsysteem ontvangt een niet gecodeerd digitaal " "signaal van xine via de digitale uitgang van uw geluidskaart." #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat input plugin" msgstr "libavformat-invoer" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "libavformat demultiplexer" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_audio_dec: Vergroot de buffer naar %d om overflow te vermeiden.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_audio_dec: Kan geen ffmpeg-decoder voor buffer type 0x%X vinden\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: Probeer om null-codec te openen\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: Kon decoder niet openen\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "ffmpeg_audio_dec: Decoder-instellingen zijn gewijzigd\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "ffmpeg_audio_dec: Kan decoder-instellingen niet lezen\n" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "FFMpeg audio decoder" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "FFmpeg geluidsniveau aanpassen (in dB)" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" "Sommige AAC en WMA tracks zijn te luid opgenomen en klinken daarom " "vervormd.\n" "De volumeregelaar kan dat niet corrigeren, maar deze instelling wel." #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "ffmpeg_video_dec: Niet-ondersteund beeldformaat, DR1 uitgeschakeld.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: Niet-ondersteund beeldformaat, DR1 uitgeschakeld.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: Directe weergave ingeschakeld\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" "ffmpeg_video_dec: Geen geschikt beeldformaat voor decoderen door hardware\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "ffmpeg_video_dec: forceer AVDISCARD_DEFAULT door VAAPI\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: Kon decoder niet openen\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: Kon decoder niet openen\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_video_dec: Vergroot de buffer naar %d om overflow te vermeiden.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: %d DR1-beelden gebruikt.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_video_dec: Kan geen ffmpeg-decoder voor buffer type 0x%X vinden\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "ffmpeg_video_dec: VAAPI MPEG 1/2 software decodering %d\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "ffmpeg_video_dec: VAAPI ingeschakeld in configuratie\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "ffmpeg_video_dec: VAAPI uitgeschakeld door grafische kaart.\n" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "FFMpeg video-decoder" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "Kwaliteit van de MPEG-4 nabewerking" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "Hoeveel MPEG-4 Video's worden nabewerkt kunt u instellen.\n" "Grotere waarden verbeteren de kwaliteit, maar hebben ook meer rekenkracht " "nodig. Lagere waarden kunnen in defecten zoals blokkerige artefacten " "resulteren. Bij een inhoud met een goede kwaliteit kan te sterke nabewerking " "het beeld slechter maken door het te veel te vervagen." #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "Aantal parallel werkende FFMpeg video-decoder" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" "U kunt het aantal video decodeer threads instellen dat FFmpeg kan " "gebruiken.\n" "Grotere waarden kunnen het decoderen versnellen - afhankelijk van het type " "codec in de video en of parallel decoderen mogelijk is.\n" "Een vuistregel is een decodeer-thread per CPU (meestal 1 tot 4).\n" "Een gewijzigde instelling heeft pas bij de volgende af te spelen video " "effect." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "Nabewerking weglaten" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Hier kunt u instellen voor welke beeldtypen een filtering na het decoderen " "overgeslagen kan worden:\n" " none: Alle beelden worden nagefilterd. Goede beeldkwaliteit, maar " "langzaam.\n" " nonref: Alleen meervoudig gebruikte beelden nafilteren.\n" " bidir: Alleen I- en P-beelden nafilteren.\n" " nonkey: Alleen I-beelden nafilteren.\n" " all: Niets nafilteren. Snel, maar vaak slecht beeld.\n" " default: Automatisch selectie.\n" "Een gewijzigde instelling heeft pas bij de volgende af te spelen video " "effect." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "Werkt sneller, maar ook minder nauwkeurig" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Staat diverse trucks toe die het decoderen versnellen, maar die tegen de " "officiële codec-specificatie ingaan en soms tot artefacten leiden.\n" "Een gewijzigde instelling heeft pas bij de volgende af te spelen video " "effect." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "Directe weergave gebruiken" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" "Schakel de directe weergave uit als video's met veel gebruikte beelden " "blijven hangen." #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "VAAPI MPEG 1/2 software-decodering" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" "Als de machine bij MPEG 1/2 blijft hangen, probeer dan MPEG2 software " "decodering." #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "VAAPI inschakelen" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "VAAPI in- of uitschakelen" #: src/combined/ffmpeg/input_avio.c msgid "libavio input plugin" msgstr "libavio Invoer" #: src/combined/flac_decoder.c msgid "flac audio decoder plugin" msgstr "FLAC audio decoder" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "FLAC demultiplexer" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "NES Music audio decoder" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "NES Music demultiplexer" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "wavpack audio decoder" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "wavpack demultiplexer" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: vorbis audio track aangegeven maar geen vorbis stream header gevonden.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "Annodex demultiplexer" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "OGG demultiplexer" #: src/combined/xine_speex_decoder.c msgid "Speex audio decoder plugin" msgstr "Speex audio decoder" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "theora video-decoder" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: Vergroot de buffer naar %d om overflow te vermeiden.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "vorbis audio decoder" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "4X Technologies (4xm) demultiplexer" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "ADIF/ADTS AAC demultiplexer" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "Raw AC3 demultiplexer" #: src/demuxers/demux_aiff.c msgid "AIFF file demux plugin" msgstr "AIFF bestand-demultiplexer" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "demux_asf: Waarschuwing: Een datastroom ontbreekt?\n" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "Een datastroom ontbreekt?" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: Waarschuwing: Datastroom id=%d is versleuteld.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Mediastroom is versleutelt" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "ASF demultiplexer" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "Westwood Studios AUD bestand-demultiplexer" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Bezig met herstellen van index..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "demux_avi: ongeldig AVI-pakket \"%c%c%c%c\" op positie %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: avi-index is beschadigt\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" "demux_avi: Opzoeken van volgende pakket (positie %) mislukte\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "AVI/RIFF demultiplexer" #: src/demuxers/demux_cdda.c msgid "CD Digital Audio demux plugin" msgstr "Audio CD demultiplexer" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "Raw DTS demultiplexer" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "Electronics Arts WVE demultiplexer" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "Elementary MPEG stream demultiplexer" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "Ongeldige grootte van FILM-pakket\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "Niet herkent FILM-pakket\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "FILM (CPK) demultiplexer" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "Free Lossless Audio Codec (flac) demultiplexer" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "Autodesk Animator FLI/FLC demultiplexer" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "demux_flv: Beschadigde zoekindex wordt niet gebruikt.\n" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" "demux_flv: Dit bestand is niet doorzoekbaar. Een beeld-toon-naijlen kan " "optreden.\n" " We raden aan om het bestand met een geschikt \"flvtool\" te " "repareren.\n" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "Niet-ondersteunde FLV-versie (%d).\n" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "Zowel geen beeld als geen audio in dit bestand.\n" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "FLV demultiplexer" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "Id Quake II Cinematic bestand-demultiplexer" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: Onbekende compressie: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: Onbekende compressie: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: Onbekend pakket: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "IFF demultiplexer" #: src/demuxers/demux_image.c msgid "image demux plugin" msgstr "Afbeelding-demultiplexer" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "Interplay MVE Movie demultiplexer" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "IVF demultiplexer" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "matroska & webm demultiplexer" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "Multiple-image Network Graphics demultiplexer" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "ModPlug Amiga MOD Music bestand-demultiplexer" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: Beeld is te groot voor buffer" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "Musepack demultiplexer" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: Onbekende datastroom-id 0x%02x. Wilt u dit bij de " "xine-ontwikkelaars melden.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: Fout! Voortijdige beëindiging. Wilt u dit bij de xine-" "ontwikkelaars melden.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: Waarschuwing: de voor de PES-header gereserveerde 10 Bits " "zijn niet gevonden\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: Waarschuwing: PES-header geeft aan, dat deze datastroom " "versleuteld kan zijn (versleuteling-methode %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "DVD/VOB demultiplexer" #: src/demuxers/demux_mpeg.c msgid "MPEG program stream demux plugin" msgstr "MPEG program datastroom demultiplexer" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_ps: Onbekende datastroom-id 0x%02x. Wilt u dit bij de " "xine-ontwikkelaars melden.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: Waarschuwing: PACK-datastroom id=0x%x decodering mislukte.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: Waarschuwing: de voor de PES-header gereserveerde 10 Bits " "zijn niet gevonden\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: Waarschuwing: PES-header geeft aan, dat deze datastroom " "versleuteld kan zijn (Versleuteling-methode %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes:Onbekende privé datastroom 1 0x%02x. Wilt u dit bij de xine-" "ontwikkelaars melden.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "MPEG-PES demultiplexer" #: src/demuxers/demux_mpgaudio.c msgid "MPEG audio demux plugin" msgstr "MPEG audio demultiplexer" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "Nullsoft Video demultiplexer" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "Playlist demultiplexer" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "TechnoTrend PVA demultiplexer" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "demux_qt: %d mediafragment toegevoegd\n" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "Apple Quicktime (MOV) en MPEG-4 demuxer" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "Raw DV Video datastroom" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "RealAudio bestand-demultiplexer" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "RealMedia demultiplexer" #: src/demuxers/demux_roq.c msgid "Id RoQ file demux plugin" msgstr "Id RoQ bestand-demultiplexer" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "Shorten demultiplexer" #: src/demuxers/demux_smjpeg.c msgid "SMJPEG file demux plugin" msgstr "SMJPEG demultiplexer" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: Ongeldige header-parameter\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: Niet-ondersteunde audiotype: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "SND/AU demultiplexer" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "Sony Playstation STR demultiplexer" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "MPEG Transport datastroom demultiplexer" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "demux_tta: Totaal aantal getelde frames is teveel\n" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "True Audio demultiplexer" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "VC1 elementary datastroom demultiplexer" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "Sierra VMD demultiplexer" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "Onbekende VOC-bloktype (0x%02X); Wilt u dit bij de xine-ontwikkelaars " "melden\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "Onbekende VOC-compressietype (0x%02X); Wilt u dit bij de xine-ontwikkelaars " "melden\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "VOC demultiplexer" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "Dialogic VOX demultiplexer" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "Westwood Studios VQA demultiplexer" #: src/demuxers/demux_wav.c msgid "WAV file demux plugin" msgstr "WAV bestand-demultiplexer" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" "demux_wc3movie: SHOT pakket verwijst naar naar een ongeldig palet (%d >= %" "d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" "demux_wc3movie: Bij het laden van het palet is een probleem opgetreden\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "Wing Commander III Movie (MVE) demultiplexer" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "YUV4MPEG2 demultiplexer" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "YUV frames dummy demultiplexer" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" "Ondertitel-decoder die de decodeer-capaciteit van een DXR3 kaart gebruikt" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Openen van ondertitel-programma %s mislukte (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_spu: Schrijven naar video-programma mislukte (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "De gevraagde knop is niet beschikbaar\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "MPEG1/2 decoder die de mogelijkheden van een DXR3 kaart gebruikt" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "dxr3_decode_video: Openen van stuurprogramma %s mislukte (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "Gebruik Pan & Scan Informatie" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Pan & Scan\" is een speciale display-mode, die soms in MPEG gecodeerde " "materiaal gebruikt wordt. U kan hier specificeren hoe met dergelijke inhoud " "omgegaan moet worden.\n" "\n" "only when forced\n" "Pan & Scan alleen dan gebruiken als de inhoud die u afspeelt het " "voorschrijft.\n" "\n" "use MPEG hint\n" "Pan & Scan dan gebruiken als de betreffende informatie in de MPEG " "videostroom ingebed is.\n" "use DVB hint\n" "Pan & Scan dan gebruiken als de betreffende informatie in de DVB Datastroom " "ingebed is. Dit benut de Active Format Descriptor (AFD), die in sommige " "Europese DVB Datastromen gebruikt wordt." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "Probeer om elk beeld van de video te synchroniseren" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" "Dit probeert om bij elk beeld een synchronisatie-tijdstip te plaatsen. " "Normaal gesproken is dit niet nodig, omdat het voor de synchronisatie genoeg " "is om af en toe een synchronisatie-tijdstip te plaatsen.\n" "Dit is alleen voor progressieve video´s (de meeste PAL films) relevant." #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "Gebruik vloeiend afspelen" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Het inschakelen van deze optie zorgt voor een vloeiender weergave." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "Corrigeer de tijdsduur van beelden in video's met fouten" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" "Activeert een logica waarmee een foute tijdsduur van frames in sommige MPEG " "video´met foute beeldherhaalcodes wordt gecorrigeerd. Momenteel is een " "correctie voor NTSC stromen geïmplementeerd, die foutief als PAL gemarkeerd " "zijn. Activeer dit alleen, als u een dergelijk datastroom aantreft." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Openen van video-apparaat %s mislukte (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" "dxr3_decode_video: Schrijven naar het apparaat zal blokkeren. flushing " "(legen)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: Schrijven naar video-apparaat mislukte (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" "dxr3_decode_video: Waarschuwing: Onbekende code %d voor de beeldfrequentie\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: Waarschuwing: bezig met corrigeren van de code voor de " "beeldfrequentie van PAL naar NTSC\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "DXR3 apparaat-nummer" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Als u meer dan een DXR3 in uw computer heeft, dan kunt u hier aangegeven " "welke gebruikt moet worden." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: initialiseren van librte faalde\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte kan alleen met beeldgroottes omgaan die een veelvoud " "van 16 zijn\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: rte-context kon niet verkregen worden.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: CODEC kon niet gecreëerd worden.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "Bitrate van de librte MPEG weergave (kBit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "Bitrate voor de MPEG-decoderingsbibliotheek librte voor DXR3 codering. " "Grotere waarden verbeteren de kwaliteit, maar hebben ook meer rekenkracht " "nodig." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: initialiseren van context faalde: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: decodering kan niet gestart worden: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: FAME-bibliotheek kon niet gestart worden\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "fame-MPEG-decodeer kwaliteit" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "De decodeer-kwaliteit van de MPEG-decodeerbibliotheek libfame. Een lagere " "waarde is sneller, maar produceert artefacten. Hogere waarden verbeteren de " "kwaliteit, maar hebben wel meer rekenkracht nodig." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "SCR-plugin prioriteit" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" "Prioriteit van de DXR3 SCR-plugin. Waarden kleiner dan 5 resulteren erin dat " "de UNIX systeemklok voor de synchronisatie wordt gebruikt; Waarden groter " "dan 5 dwingen tot het gebruik van de interne klok van DXR3 als " "synchronisatiebron." #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "libavcodec MPEG uitvoer-bitrate (kBit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" "De bitrate dat de MPEG-decoderingsbibliotheek libavcodec voor de DXR3 " "decodering zou moeten gebruiken. Grotere waarden vergroten de kwaliteit maar " "ook de nodige rekenkracht.\n" "Deze instelling is alleen werkzaam als constante kwaliteit-modus is " "uitgeschakeld." #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "Constante kwaliteit-modus" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" "Indien ingeschakeld, zal libavcodec een mode voor constante kwaliteit " "gebruiken, waarbij de afbeeldingen gebaseerd op hun complexiteit dynamisch " "gecomprimeerd worden. In het geval dat het uitgeschakeld is, zal libavcodec " "een mode met constante bitrate gebruiken." #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "Minimale compressie" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "Minimale compressie voor een beeld in de constante kwaliteit mode" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "Maximale kwantiseerder" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "Maximale compressie van een beeld in de maximale kwaliteit mode." #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "Videoweergave via uw DXR3 kaart" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Openen van het stuurprogramma %s mislukte (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "Wissel even en oneven lijnen om" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" "Wisselt de even en de oneven lijnen om van een beeld .\n" "Schakel deze optie in bij niet-MPEG-materiaal, die een verticaal trillen in " "het beeld laat zien." #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "" "Zwarte balken voor de correctie van de hoogte/breedte-verhouding toevoegen." #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Voegt aan het beeld zwarte balken toe, in het geval dat de kaart de hoogte/" "breedte-verhouding niet zelf verwerken kan." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "Gebruik vloeiend afspelen voor MPEG-gecodeerde films." #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Het inschakelen van deze optie zorgt voor een vloeiender weergave van niet-" "MPEG-inhoud." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Openen van video-apparaat %s mislukte (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "Decoderen voor niet-MPEG-inhoud" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "Andere content dan MPEG-inhoud moet een extra hercodeer-fase doorlopen, " "omdat DXR3 alleen met MPEG overweg kan.\n" "Afhankelijk van waarmee uw xine overweg kan, kan deze instelling \"fame\", " "\"rte\" \"libavcodec\" of \"none\" zijn.\n" "De \"libavcoder\" gebruikt de ffmpeg plugin, dat al met xine meegeleverd " "werd, zodat u daarvoor geen extra bibliotheek nodig heeft. libavcoder levert " "zelfs een zeer hoge kwaliteit terwijl het weinig rekenkracht nodig heeft, " "zodat daarom libavcodec speciaal name aanbevolen word.\n" "\"fame\" en \"rte\" worden nog aangeboden, maar de xine-ondersteuning voor " "hun is verouderd en kan zelfs in de toekomst defect raken." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" "video_out_dxr3: initialiseren van libavcodec voor Mpeg-decodering faalde.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: initialiseren van rte voor Mpeg-decodering faalde.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: initialiseren van fame voor Mpeg-decodering faalde.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: MPEG-decodering uitgeschakeld.\n" "video_out_dxr3: Dat is geen probleem bij MPEG-video´s zoals DVDs, maar\n" "video_out_dxr3: u kan geen niet-MPEG-inhoud met deze video-driver\n" "video_out_dxr3: weergeven. Lees de README.dxr3, voor de details wat betreft " "de configuratie van de codeerder.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Geen MPEG-decodering meegecompileerd.\n" "video_out_dxr3: Dat is geen probleem bij MPEG-video´s zoals DVDs, maar\n" "video_out_dxr3: u kan geen niet-MPEG-inhoud met deze video-driver\n" "video_out_dxr3: weergeven. Lees de README.dxr3, voor de details wat betreft " "de configuratie van de codeerder.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "Videoweergave mode (TV of Overlay)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" "U kunt hier instellen hoe DXR3 de uiteindelijke video weergeven moet. " "Geldige waarden zijn:\n" "\n" "letterboxed tv\n" "Video word alleen via de TV-uitgang verstuurt. Dezer modus word voor normale " "4:3 televisie gebruikt. Anamorphische (16:9) video's worden als in een " "brievenbus samengeperst weergegeven, Pan&Scan-materiaal word links en rechts " "bijgesneden. Dit is de standaardinstelling voor televisies en gedraagt zich " "net als een zelfstandige DVD-speler.\n" "\n" "widescreen tv\n" "Video word alleen via de TV-uitgang verstuurt. Dezer modus word voor 16:9 " "breedbeeld-televisies gebruikt. Anamorphische en Pan&Scan-inhoud vullen het " "complete scherm, maar de beeldverhouding moet handmatig op 16:9 ingesteld " "worden.\n" "letterboxed overlay\n" "Overlay Video-uitgang op het computerbeeldscherm met optioneel onmiddellijk " "omschakelen naar de TV-uitgang door het verbergen van het videovenster. De " "overlay word met zwarte randen aangegeven, als het anamorph (16:9) is.\n" "Deze instelling is alleen in de zeldzame gevallen zinvol als de DVD-" "ondertitel alleen in de \"letterboxed\"-mode weergegeven kan worden. Een " "goed voorbeeld daarvan is de geanimeerde commentaar-silhouetten in " "\"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Videoweergave op het computerbeeldscherm met optioneel onmiddellijk " "omschakelen naar de TV-uitgang door het verbergen van het videovenster. Dit " "is de standaardvariant bij DXR3 Overlays." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "Kleur voor overlay colour key" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Hexadecimale RGB-waarde voor de hoofdkleur.\n" "U kan verschillende waarden uitproberen, als bij het gebruik van de DXR3-" "overlay-modus de vensters transparant worden." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "Variatie voor overlay colour key" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" "Een grote waarde vergroot de tolerantie voor de overlay key colour.\n" "U kan kleinere waarden uitproberen, als u merkt dat bij het gebruik van de " "DXR3-Overlay-modus de vensters transparant worden; bij te kleine waarden " "kunnen gedeeltes van de beeldranden verdwijnen." #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "Snijd de overlay aan de bovenkant en onderkant bij" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Verwijdert een rij pixels aan de bovenkant en aan de onderkant van de " "overlay. Schakel dit in als u een groene lijn aan de bovenkant of aan de " "onderkant ziet." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: Voer autocal uit, overlay uitgeschakeld\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "Voorkeur TV-mode" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Selecteert de door de DXR3 gebruikte TV-Mode. De waarden betekenen:\n" "\n" "ntsc: NTSC met 60Hz\n" "pal: PAL met 50Hz\n" "pal60: PAL met 60Hz\n" "default: de instellingen van de kaart houden" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: Instellen van de video-mode mislukte.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: Voor het afspelen van niet-MPEG-Video's op dxr3 is een MPEG-" "decodeerder nodig.\n" "video_out_dxr3: Lees de README.dxr3 voor meer details.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: Fout bij het lezen van overlay init file. Start autocal!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "BluRay-invoer" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "BluRay aankoppelpunt" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "Standaard aankoppelpunt voor BluRay's." #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "Apparaat voor BluRay afspelen" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "Het pad naar het apparaat, dat u wilt gebruiken voor het afspelen van BluRay" "´s." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "Standaard taal voor BluRay-afspelen" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" "xine probeert deze taal te gebruiken als standaard bij het afspelen van " "BluRay. Als de schijf het ondersteund, dan worden menus en titel in deze " "taal getoond.\n" "De waarde moet een drieletterige ISO639-2-taalcode zijn." #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "BluRay landherkenning" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "De waarde moet een tweeletterige ISO3166-1 landcode zijn." #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "BluRay regiocode (1=A, 2=B, 4=C)" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" "Dit hoeft alleen gewijzigd te worden, als uw BluRay een venster laat zien, " "waar het klaagt over een foute regiocode. Dit heeft niets met de regiocode " "in de BluRay drive te doen, dit is alleen voor de software." #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "Leeftijdvrijgave ouderlijk toezicht (1-99)" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "Verhindert het afspelen van titels met een hogere leeftijdvrijgave" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "Eenheid voor overslaan" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" "Hier kunt u het gedrag van de knoppen voor \"vooruit\"- en \"terug\" " "instellen." #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "BluRay invoer (met menus)" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: Kan geen verbinding met '%s:%d' maken\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: Succesvolle verbinding met CDDB-Server '%s:%d'.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" "input_cdda: Kan geen verbinding naar CDDB-Server '%s:%d' (%s) tot stand " "brengen.\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "CD Digital Audio (CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "Apparaat voor CD-Audio" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "Het pad naar het apparaat (meestal een CD of DVD loopwerk), dat u wilt " "gebruiken voor het afspelen van audio-CDs." #: src/input/input_cdda.c msgid "query CDDB" msgstr "CDDB doorzoeken" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" "Schakelt CDDB-doorzoeken in voor het zoeken naar titelinformatie en track-" "naam voor uw audio-CDs.\n" "Vergeet niet dat tenzij u een privé CDDB gebruikt, deze informatie van een " "internetserver afkomstig is die een profiel van uw luistergewoontes kan " "opstellen." #: src/input/input_cdda.c msgid "CDDB server name" msgstr "CDDB servernaam" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" "De CDDB-server, waarvan de titelinformatie gehaald moet worden.\n" "Deze instelling ist veiligheid-kritisch, omdat de server informatie over uw " "luister-gewoontes ontvangt en boosaardige antwoorden versturen kan. Zorg " "ervoor dat u een server opgeeft die uw vertrouwen heeft." #: src/input/input_cdda.c msgid "CDDB server port" msgstr "CDDB serverpoort" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "De server-poort, waarvan de titelinformatie gehaald moet worden." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "Snelheid van disc drive naar deze factor vertragen" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" "Daar sommige CD- en DVD-loopwerken door de snelheden waarmee ze draaien veel " "geluid produceren, zal xine proberen om ze af te remmen. Voor het standaard " "afspelen van CDs en DVDs zijn de datasnelheden die een grote rotatiesnelheid " "niet nodig, zodat het afremmen geen invloed op het afspelen zou moeten " "hebben.\n" "Een waarde van nul schakelt het afremmen uit." #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "input_dvb: Openen van het DVB-kanaalbestand '%s' mislukte: %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "input_dvb: DVB-kanaalbestand '%s' is geen gewoon bestand\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: tuner_set_channel faalde\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "input_dvb: DVB Bedienpaneel %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: Kon DVB-apparaat niet openen\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "input_dvb: Kanaal %d is niet bereikbaar, gebruikt daarom 0\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: Bezig met zoeken naar kanaal %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" "input_dvb: Exacte overeenkomst met %s niet gevonden: daarom bezig met " "gedeeltelijke overeenkomst te vinden\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: Overeenkomst met kanaal %s gevonden\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" "input_dvb: Kanaal %s niet in channels.conf gevonden, opent daarom het " "standaardkanaal.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" "input_dvb: Ongeldige kanaalspecificatie, open het laatst bekeken kanaal.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "input_dvb: Ongeldige kanaalspecificatie, open kanaal 0\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" "input_dvb: DVB-T media-adres opgegeven, maar de tuner lijkt geen QPSK (DVB-" "S) te zijn\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: DVB-T media-adres opgegeven, maar de tuner lijkt geen OFDM (DVB-" "T) te zijn\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: DVB-C media-adres opgegeven, maar de tuner lijkt geen QAM (DVB-C) " "te zijn\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" "input_dvb: DVB-C media-adres opgegeven, maar de tuner lijkt geen ATSC (DVB-" "A) te zijn\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: Kan DVR-apparaat '%s' niet openen\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "input_dvb: Kan EPG-actualisatie-thread niet creëren\n" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "Gebruik DVB 'center cutout' (zoom)" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Dit maakt het volledig scherm afspelen mogelijk van 4:3 inhoud dat in 16:9 " "over gezonden werd." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "DVB (Digital TV) Plugin" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Laatst bekeken DVB-kanaal onthouden" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" "Bij automatisch afspelen, zal XINE onthouden en omschakelen naar het kanaal " "opgegeven in media.dvb.last_channel. " #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Laatst bekeken DVB-kanaal" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" "Indien ingeschakeld zal xine onthouden en naar dit kanaal omschakelen. " #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "Hoeveel seconde u heeft om een zender in te stellen" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "Minimum 5, 0 = 'voor altijd'." #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "DVB Bedienpaneel inschakelen" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "Schakelt muisgestuurde omschakeling van het kanaal en opnames in." #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Aantal te gebruiken DVB-kaarten." #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" "Laat dit op nul staan, tenzij u daadwerkelijk meer dan 1 kaart in uw systeem " "heeft." #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "input_dvd: Waarden van \\beta zullen dom verhogen!\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Fout bij het lezen van het volgende blok op de DVD (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Fout bij het openen van het DVD-apparaat\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "DVD-navigatie" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "Apparaat voor DVD afspelen" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "Het pad naar het apparaat (meestal een DVD loopwerk), dat u wilt gebruiken " "voor het afspelen van DVDs." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "CSS ontcijfering-methode" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" "Selecteert de ontcijfering-methode die libdvdcss zal gebruiken voor het " "ontcijferen van DVDs met kopieer-bescherming. Probeer de verschillende " "methoden uit, als u problemen heeft bij het afspelen van versleutelde DVDs." #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "Regio (1-8), waarin de DVD speler denkt te staan" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "Dit hoeft alleen gewijzigd te worden, als uw DVD een venster laat zien, waar " "het klaagt over een foute regiocode. Dit heeft niets met de regiocode in de " "DVD-speler te doen, dit is alleen voor de software." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "Standaard taal voor DVD-afspelen" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine probeert deze taal te gebruiken als standaard bij het afspelen van de " "DVD. Als de DVD het ondersteund, dan worden menus en titel in deze taal " "getoond.\n" "De waarde moet een tweeletterige ISO639-taalcode zijn." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "Voorijlende cache gebruiken" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" "xine kan een voorijlende cache voor DVD-loopwerk toepassen.\n" "Dit kan bij langzame loopwerken een stotterende weergave geven, maar " "verbetert de invloed van DVD-layer wisselingen bij snelle loopwerken." #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" "Stelt het gedrag in bij het overspring-commando (b.v. bij het gebruik van de " "oversla-knop) wat configureerbaar is. De waarden kunnen zijn:\n" "\n" "skip program\n" "Slaat een DVD-programma over, wat een navigatie-eenheid vergelijkbaar met de " "indexmarkering op een Audio-CD is; dit is het normale gedrag van een DVD-" "speler\n" "\n" "skip part\n" "Slaat een DVD-gedeelte over, wat een structurele eenheid vergelijkbaar met " "een track op een Audio-CD is; Eenheden komen normaal gesproken overeen met " "programma's, maar kunnen ook groter zijn\n" "\n" "skip title\n" "Slaat een DVD-titel over, wat een structurele eenheid vergelijkbaar met een " "complete DVD film." #: src/input/input_dvd.c msgid "unit for seeking" msgstr "Eenheid bij zoeken" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" "Stelt het zoekbereik van de schuifknop vast. De parameters kunnen zijn:\n" "\n" "seek in program chain\n" "Het zoekbereik omvat de complete DVD-programmaketen, wat een navigatie-" "eenheid is die de complete videodatastroom van de geselecteerdefilm " "voorstelt\n" "\n" "seek in program\n" "Het zoekbereik omvat een DVD-programma, wat een navigatie-eenheid is die een " "hoofdstuk van de geselecteerde film voorstelt." #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "Weergave-mode als titel/hoofdstuk is opgegeven" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" "Stelt het gedrag in voor de weergave van DVD's in, als een titel/hoofdstuk " "(b.v. via een media-adres 'dvd:/1.2') opgegeven word. De parameters kunnen " "zijn:\n" "\n" "entire dvd\n" "Weergave van de gehele DVD vanaf de opgegeven positie.\n" "\n" "one chapter\n" "Alleen de opgegeven titels/hoofdstukken weergeven, en daarna stoppen." #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Toegang geweigerd: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Bestand niet gevonden: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: Bestand leeg: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "Invoer uit bestand" #: src/input/input_file.c msgid "file browsing start location" msgstr "Startlocatie voor bestandsbeheer" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "De bestandsbeheerder start op deze locatie." #: src/input/input_ftp.c msgid "FTP input plugin" msgstr "Invoer uit FTP" #: src/input/input_ftp.c msgid "FTPES input plugin" msgstr "Invoer uit FTPES" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "Met xine meegeleverde gnome-vfs plugin" #: src/input/input_helper.c msgid "list hidden files" msgstr "Verborgen bestanden tonen" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "Indien ingeschakeld, toont de browser ook de verborgen bestanden." #: src/input/input_helper.c msgid "Default servers" msgstr "Standaardserver" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" "Een of meer door spaties gescheiden serveradressen voor de Media-selectie (V." "B. \"ftp://ftp3.itu.int sftp://user:pass@host.com\")" #: src/input/input_hls.c msgid "HTTP live streaming input plugin" msgstr "HTTP live streaming plugin" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s) faalde: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: Leesfout %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Bezig met verbinden met HTTP Server..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: Ongeldig http-antwoord\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: 3xx doorverwijzing : >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: http-status komt niet overeen met 2xx: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: Inhoudsgrootte = % bytes\n" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: Buffer opgebruikt na %zu bytes." #: src/input/input_http.c msgid "http/https input plugin" msgstr "Invoer uit HTTP(S)" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "HTTP proxy-host" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "De computernaam van de HTTP Proxy." #: src/input/input_http.c msgid "HTTP proxy port" msgstr "HTTP proxy poortnummer" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "Het poortnummer van de HTTP proxy." #: src/input/input_http.c msgid "HTTP proxy username" msgstr "HTTP proxy gebruikersnaam" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "De gebruikersnaam voor de HTTP proxy." #: src/input/input_http.c msgid "HTTP proxy password" msgstr "HTTP proxy wachtwoord" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "Het wachtwoord voor de HTTP proxy." #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Domeinen, waarvoor de HTTP proxy wordt genegeerd" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Een door ´komma's gescheiden lijst met domein-namen, waarvoor de proxy " "genegeerd wordt.\n" "Als een domein-naam met een '=' begint, dan wordt het alleen als een host-" "naam behandelt (volledige overeenkomst nodig)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "Gebruik deze HTTP-versie" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "Probeer deze bij communicatieproblemen." #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "Dump HTTP-request en response heads in dit bestand" #: src/input/input_http.c msgid "Set this for debugging." msgstr "Voor debugging." #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "MMS-streaming-plugin" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "Netwerkbandbreedte" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "Geef hier de bandbreedte van uw internetverbinding op. Deze word gebruikt in " "het geval dat de streaming-server verschillende versies van een datastroom " "met verschillende bandbreedte-vereisten aanbied." #: src/input/input_mms.c msgid "MMS protocol" msgstr "MMS-protocol" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Selecteer een protocol om MMS in te pakken.\n" "TCP is beter, maar achter een Firewall heeft u wellicht een HTTP nodig." #: src/input/input_mpegdash.c msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "MPEG Dynamic Adaptive Streaming over Http plugin" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "Met xine meegeleverde net plugin" #: src/input/input_net.c msgid "tls input plugin" msgstr "TLS-invoer" #: src/input/input_net.c msgid "gopher input plugin" msgstr "Gopher-invoer" #: src/input/input_nfs.c msgid "Network File System (NFS) input plugin" msgstr "Netwerk bestandssysteem (network file System (NFS)) plugin" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "PNM streaming-plugin" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: Fout bij het aanmaken van PVR-bestand (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: Fout bij openen van PVR-bestand (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: Leesfout (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: Fout bij het openen van het apparaat %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_G_CODEC faalde, wellicht is de API gewijzigd?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_S_CODEC faalde, wellicht is de API gewijzigd?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "WinTV-PVR 250/350 invoer" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "Apparaat gebruikt voor de invoer voer WinTV-PVR 250/350 (PVR)" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "Pad naar het apparaat van uw WinTV-kaart" #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "xine_socket_cloexec(): %s.\n" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "IP-adres voor multicast\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Adres voor iface %s niet gevonden: %s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) faalde (multicast Kernel?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "Kan '%s' niet oplossen.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "Kan geen verbinding met '%s' maken.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: bezig met stoppen van lees-thread...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: lees-thread beëindigt\n" #: src/input/input_rtp.c #, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Openen >Adres:%s poort:%d interface:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: Kan geen nieuwe thread (%s) creëren\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "Met xine meegeleverde RTP en UDP plugin" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "RTSP streaming-plugin" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "CIFS/SMB plugin gebaseerd op libsmbclient" #: src/input/input_ssh.c msgid "SCP input plugin" msgstr "SCP-invoer" #: src/input/input_ssh.c msgid "SFTP input plugin" msgstr "SFTP-invoer" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "Standaardinvoer (stdin): openen van '%s' mislukte\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "Standaardinvoer (stdin) streaming-plugin" #: src/input/input_test.c msgid "Colour Circle" msgstr "Kleuren cirkel" #: src/input/input_test.c msgid "RGB Levels" msgstr "Rood-Groen-Blauw niveaus" #: src/input/input_test.c msgid "Saturation Levels" msgstr "Verzadiging niveau" #: src/input/input_test.c msgid "UV Square" msgstr "UV kwadraat" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "Luminance resolutie" #: src/input/input_test.c msgid "test card input plugin" msgstr "Testbeeld-generator" #: src/input/input_v4l2.c msgid "v4l2 input plugin" msgstr "V4L2 invoer" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Buffer underrun..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Buffer overrun..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Aanpassen..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Tuner naam niet gevonden\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "V4L TV plugin" #: src/input/input_v4l.c msgid "v4l video device" msgstr "Pad naar V4L video-apparaat" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Pad naar Video4Linux video-apparaat" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "Pad naar V4L radioapparaat" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "Pad naar Video4Linux video-apparaat" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "v4l TV standaard" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "Stelt de TV standaard voor de bron in. AUTO, PAL, NTSC of SECAM." #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "V4L radio plugin" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "Pad naar V4L radioapparaat" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Pad naar Video4Linux radio-apparaat" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: Ongeldig media-adres: Gebruik vcdo:/\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: Track met fouten %d (geldig range: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "Kan %s niet openen: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: Kan %s niet openen: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "Video-CD plugin" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "Apparaat voor VCD afspelen" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" "Het pad naar het apparaat (meestal een CD of DVD loopwerk), dat u wilt " "gebruiken voor het afspelen van video-CDs." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: Ongeldige mrl: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: Kan geen verbinding naar '%s' tot stand brengen\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: Kan geen verbinding naar server %s tot stand brengen\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: Kan geen sessie creëren.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" "rtsp_session: RTSP Server geeft te grote antwoorden, kan geen sessie " "creëren.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "rtsp_session: RTSP-servertype '%s' wordt nog niet ondersteund. Oeps.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "input_dvd: Apparaat %s kon voor het uitwerpen niet geopend worden\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Bezig met verbinden met MMS Server (via TCP)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: zendfout\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: Foutief response opbouw\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: 3xx doorverwijzing nog niet geïmplementeerd: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: http-Status is niet 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: doorverwijzing nog niet geïmplementeerd\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Bezig met verbinden met MMS Server (via HTTP)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "Ongeldige URL\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "Niet-ondersteunde protocol\n" #: src/input/multirate_pref.c msgid "Preferred video size" msgstr "Voorkeur beeldgrootte" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" "Welk formaat van de video moet afgespeeld worden als er meerdere versies met " "een verschillende beeldgrootte beschikbaar zijn." #: src/input/multirate_pref.c msgid "Preferred language" msgstr "Voorkeur taal" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" "Welke taal moet afgespeeld worden als er meerdere versies met elk een andere " "taal beschikbaar zijn." #: src/input/multirate_pref.c msgid "Preferred bitrate" msgstr "Voorkeur bitrate" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" "Welke van de meerdere beschikbare bitrates te gebruiken voor dezelfde " "beeldgrootte." #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: Ontving tijdens het ontvangen van de datastroom een bericht van " "de server:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: Kan geen verbinding naar '%s' tot stand brengen.\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: de initialisatie van datastroom mislukte\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "TLS-leverancier (gnutls)" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "TLS-leverancier (openssl)" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "Verifieer server-certificaat" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" "Verifieer altijd het TLS-certificaat van de server, en weiger bij negatief " "resultaat de verbinding." #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR nog niet geïmplementeerd voor offset die niet nul is." #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END nog niet geïmplementeerd." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "Zoeken nog niet geïmplementeerd." #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "Foute item type" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "Ongeldig nummer" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "Ongeldig segmentnummer" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Fout bij het lezen van het huidige segmentnummer" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Zou al geconverteerd moeten zijn" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "Kon geen apparaat met een VCD vinden" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "Er werd een NULL-classeparameter doorgeven" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Ongeldig item-type" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "Selectie heeft geen RETURN" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "DEFAULT geselecteerd, maar PBC is niet aan." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "Selectie heeft geen NEXT" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "Selectie heeft geen PREVIOUS" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Onbekende event type:" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" "Video-CD plugin met PBC (playback control) en support voor (X)VCD, (X)SVCD, " "HQVCD, CVD, ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "Standaard loopwerk voor gebruik bij VCD bij automatische weergave" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "Het te gebruiken loopwerk als er geen in een media-adres is opgegeven (b.v. " "vcd:// of vcd:///dev/dvd:)" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "Standaard CD-ROM-drive voor VCD, als er geen word opgegeven" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Welk loopwerk moet worden gebruikt als geen loopwerk is opgegeven. Als deze " "instelling leeg is, dan zal xine naar CD-loopwerken gaan zoeken." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "VCD weergave bereik" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "Het bereik dat de positie-schuif bij de weergave van VCD's voorstelt." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "Voorijlende cache voor VCD's gebruiken?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "Dit kan bij langzamere computers een stotterende weergave geven." #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "Automatisch naar volgend item/track gaan bij VCD's" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Indien ingeschakeld, zal automatisch naar de volgende item of track worden " "gegaan. Wordt alleen gebruikt als \"playback control\" (PBC) is " "uitgeschakeld." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "'Afgewezen' VCD LIDs tonen" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" "Enkele IDs in de afspeellijst (LIDs) zijn als niet zichtbaar gemarkeerd. Na " "het inschakelen van deze optie worden ze desondanks toch getoond en met een " "ster (*) aan het einde van de media-adres gemarkeerd." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "Opbouw venstertitel bij VCD´s" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" "VCD parameters voor de venstertitel. Vergelijkbaar met een Unix date-" "commando. De parameters starten met een procentteken (%). Parameters zijn:\n" " %A : De album informatie\n" " %C : De VCD serielengte - Het aantal CD's in de serie.\n" " %c : De VCD serienummer - Het nummer van de CD in de serie.\n" " %F : Het VCD type, b.v. VCD 1.0, VCD 1.1, VCD 2.0, of SVCD\n" " %I : Het huidige type item/segment/weergavetype, b.v. ENTRY, TRACK, ...\n" " %L : De playlist-ID met \" LID\" als het voorkomt\n" " %N : Het huidige nummer van het item/segment - een decimaal getal\n" " %P : De uitgever-ID\n" " %p : De fabrikant-ID\n" " %S : Als we in een segment (Menu) zijn, het type segment\n" " %T : De tracknummer\n" " %V : De volume set ID\n" " %v : De volume ID\n" " Een nummer tussen 1 en de serielengte.\n" " %% : een %\n" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "De opbouw van het commentaarveld van een VCD." #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "Dezelfde opbouw als bij een venstertitel. Vergelijkbaar met een Unix date-" "commando. De parameters starten met een procentteken (%). Parameters zijn %" "A, %C, %c, %F, %I, %L, %N, %P, %p, %S, %T, %V, %v, en %%.\n" "Lees de help voor de titelopbouw voor de betekenis van deze." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "Bitveld voor VCD foutzoeken" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" "Extra meldingen inschakelen voor het foutzoeken in de VCD-plugin. Voeg een " "of meerdere van deze waarden toe:\n" " 1: Meta-informatie\n" " 2: I(toetsenbord/muis) events\n" " 4: Media-adres \n" " 8: Aanroep door externe routines\n" " 16: Aanroep van routines\n" " 32: LSN wijzigingen\n" " 64: Weergave besturing\n" " 128: Debuggen van CDIO\n" " 256: Zoeken naar een bepaalde positie\n" " 512: Zoeken naar de actuele positie\n" "1024: Still-frame\n" "2048: Debuggen van VCDINFO\n" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "Pad naar RealPlayer-codecs" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "In het geval dat u RealPlayer geïnstalleerd heeft, geeft u hier het pad naar " "de map met de codecs op. U kan makkelijk de map met de codecs vinden, door " "te zoeken naar een map waarin het bestand genaamd \"drvc.so\" te vinden is. " "Als xine de RealPlayer-codecs kan vinden, dan gebruikt xine deze voor het " "decoderen van RealPlayer-inhoud. Lees de xine FAQ voor meer informatie over " "hoe u de codecs moet installeren." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (Audio) Kan symbolen niet oplossen - incompatibel DLL: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "libareal: initialiseren van decoder faalde, foutcode: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" "libareal: initialiseren van de decoder-variant faalde, foutcode: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: Oeps, kan Real met meer dan 2 kanalen overweg?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "Audio decoder met RealPlayer-bibliotheken" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "libreal: Kan symbolen niet oplossen! (versie incompatibel?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "Video decoder met RealPlayer-bibliotheken" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "Pad naar win32-codecs" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "Geef hier het pad op naar de Windows of Apple Quicktime Codec-pakketten, als " "deze geïnstalleerd zijn. Als xine de Windows of Apple Quicktime Codecs kan " "vinden, dan zal xine deze gebruiken voor het decoderen van verschillende " "Windows media- of Quicktime datastromen. Lees de xine FAQ voor meer " "informatie over hoe u de codecs moet installeren." #: src/libw32dll/qt_decoder.c msgid "quicktime audio decoder plugin" msgstr "quicktime audio decoder" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "Video decoder met gebruik van Quicktime-bibliotheken" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ICOpen faalde! Onbekende Codec %08lx / verkeerde parameter?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) faalde: fout %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery faalde: fout %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin faalde: fout %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder faalde! Onbekende codec %08lx / foute parameter?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder faalde! Onbekende codec %08lx / foute parameter?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: Decoder startte niet. Is '%s' geïnstalleerd?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Ongeschikt audioformaat\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen fout %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Fout bij het initialiseren van DirectShow Audio\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Fout bij het initialiseren van DMO Audio\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "win32 DLL video-decoder" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "win32 audio-decoder" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" "Dit filter rekt de tijd uit, zodat de datastroom sneller of langzamer af " "wordt gespeeld. Indien gewenst kan de toonhoogte behouden blijven, wat het b." "v. mogelijk maakt om een film in minder dan zijn originele speeltijd af te " "spelen.\n" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" "Versnelt/Vertraagt audio, met naar keuze het behoudt van de toonhoogtes" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" "Conversie functie, produceert een surround 5.1 uit een stereo-" "ingangssignaal.\n" "Parameter\n" " cut_off_freq\n" "\n" "Opmerking: het is mogelijk om het controlevenster te gebruiken om deze " "parameters in te stellen.\n" "\n" #: src/post/audio/upmix.c msgid "upmix" msgstr "Conversie" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" "Dit filter converteert een mono kanaal naar stereo, door de kanalen te " "dupliceren. Dit filter kan als alternatief gebruikt worden om maar een " "kanaal weer te geven.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": Mono naar stereo converteren.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] ": Converteert een enkel kanaal van oorspronkelijk %d kanaal.\n" msgstr[1] ": Converteert een enkel kanaal van oorspronkelijk %d kanalen.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": Audio-apparaat is niet in staat tot AO_CAP_MODE_STEREO.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "Converteer mono naar stereo" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" "Standaardiseert de audio door de volume te maximaliseren zonder het geluid " "te vervormen.\n" "\n" "Parameter:\n" " methode: 1: gebruik een enkel meetmoment, om de variaties met de hulp van " "het gemiddelde over eerdere meetmomenten weg te werken (standaard); " "methode: 2: gebruik meerdere meetmomenten, om de variaties met de hulp van " "het gemiddelde van eerdere meetmomenten weg te werken.\n" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "Volume aanpassen" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" "Geavanceerde plugin voor tvtime/deinterlace met pulldown-herkenning\n" "Deze plugin heeft deinterlacing-mechanismes vergelijkbaar met dure " "progressieve DVD-spelers en zogeheten line-doublers, om te gebruiken bij " "computer monitors, projectors en andere progressive beeld-apparaten\n" "\n" "Parameters\n" "\n" "\n" " Method: Selecteert welke deinterlacing methode/algoritme moet worden " "gebruikt. zie hieronder voor een beschrijving van elke methode.\n" "\n" " Enabled: Schakelt de plugin IN en UIT\n" "\n" " Pulldown: Selecteert de 2-3 pulldown-detectie algoritme. Bioscoopfilms met " "24 beelden per seconde, die naar NTSC geconverteerd werden, kunnen herkent " "worden en intelligent weer naar hun originele (non-interlaced) " "beeldfrequentie terug geconverteerd worden.\n" "\n" " Framerate_mode: Als u 'full' selecteert dan wordt elk beeld gedeinterlaced " "naar een apart beeld in televisiekwaliteit of beter. Deze mode verdubbelt " "effectief de beeldfrequentie en verbetert de gelijkvormigheid. Let er op dat " "een volledige 59.94 beelden per seconde bij een Linux-2.4-kernel niet " "mogelijk is (dat een timer interrupt frequentie van 100Hz gebruikt). " "Nieuwere kernels (2.6 of nieuwer) gebruiken hogere HZ waarden (512 en 1000, " "respectievelijk) en zouden probleemloos moeten werken.\n" "\n" " Judder_correction: Nadat 2-3-Pulldown is ingeschakeld en de betreffende " "filmmateriaal is herkent, kan de beeldfrequentie naar de oorspronkelijkerate " "(24 beelden/seconde) gereduceerd worden. Dit verdeelt de beelden in de tijd " "overeenkomstig de snelheid waarmee het is opgenomen en geeft daarmee een " "vloeiender weergave.\n" "\n" " Use_progressive_frame_flag: Goede MPEG2-Video's hebben intern een " "markeerbit die aangeeft dat interlaced of progressief materiaal wordt " "gebruikt. Hier geeft u aan of deze markering vertrouwt moet worden (bij " "enkele zeldzame MPEG2 wordt dit foutief ingesteld).\n" "\n" " Chroma_filter: DVD/MPEG2 gebruiken een beperkt beeldformaat dat een " "slechte verticale chroma heeft. Het groter maken van deze kleurinformatie " "voor het deinterlacing kan artefacten veroorzaken (b.v. kleurstrepen). " "Gebruik deze instelling om de kleurinformatie verticaal te vervagen om deze " "artefacten te verwijderen. Opgepast: CPU intensief.\n" "\n" " Cheap_mode: Dit slaat de complexe YV12->YUV2 beeld-convertering over, " "waarbij de tvtime/dscaler-routines verder werken alsof het YUV2-afbeeldingen " "zijn. Natuurlijk is dat niet correct, omdat niet alle pixel door het " "algoritme uitgerekend kan worden om het vlak te deinterlacen, en de " "kleurinformatie wordt apart bewerkt. Deze methode staat het personen met " "niet zo snelle computers toe om toch in een compromis tussen de kwaliteit en " "CPU-belasting deinterlace algoritmes uit te proberen .\n" "\n" "* Gebruikt meerdere algoritmes van de tvtime en van dscaler projecten.\n" "Deinterlacing methods: (Niet alle methoden zijn voor alle platformen " "beschikbaar)\n" "\n" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "Geavanceerde plugin voor deinterlacing met pulldown-herkenning" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: Geen deinterlacing beschikbaar, dit onderdeel is geëindigd.\n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "Wat een GOOM" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "Het aantal te creëren frames per seconde" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Met meer beelden per seconde word de animatie vloeiender en sneller, maar " "heeft ook meer rekenkracht nodig." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "Goom beeldbreedte" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "De breedte van de te genereren afbeelding in pixels." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "Goom beeldhoogte" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "De hoogte van de te genereren afbeelding in pixels." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "Kleurruimte conversie-methode" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" "U kan de kleurruimte conversie-methode die in GOOM wordt gebruikt kiezen.\n" "De beschikbare keuzes zouden zelf uitleggend verklarend moeten zijn." #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico maakt eenvoudige beeld in beeld effecten mogelijk.\n" "\n" "Parameter\n" " pic_num: het aantal beeldposities waarvoor de volgende waarden gelden\n" " x: de X-coördinaten van de hoek linksboven van het beeld\n" " y: de Y-coördinaten van de linksboven van het beeld\n" " w: de breedte van het beeld\n" " h: de hoogte van het beeld\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "Mosaico is een beeld in beeld plugin" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Switch kan gebruikt worden om makkelijk tussen meerdere bronnen om te " "schakelen.\n" "\n" "Parameter\n" " select: het aantal bronnen die naar de uitvoer geleid zal worden\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "Switch is een plugin om tussen meerdere video's om te schakelen." #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Box blur vervaagt (blur) een beeld.\n" "\n" "Parameter\n" " Radius: grootte van het filter\n" " Power: hoe vaak het filter moet worden toegepast\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "box blur filter van MPlayer" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Dit filter gereduceerd beeldruis wat resulteert in gelijkmatiger beelden en " "zorgt dat afbeeldingen zeer stil zijn (dit zou de compressie moeten " "verbeteren). U kunt 0-3 parameter opgeven. Als u een parameter weg laat dan " "wordt een geschikte waarde toegepast.\n" "\n" "Parameter\n" " Luma: Lokale helderheid (standaard = 4)\n" " Chroma: Lokale kleursterkte (standaard = 3)\n" " Time: tijdelijke sterkte (standaard = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "3D Denoiser (variabel laagdoorlaat filter)" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" "Alternatieve software-equalizer, welke tabellen gebruikt (zeer langzaam) " "waarbij correcties op de helderheid, contrast, verzadiging en gamma mogelijk " "zijn.\n" "Let er op dat het dezelfde MMX-optimaliseerde code van 'eq' gebruikt wordt, " "als alle gamma-waarden 1.0 zijn.\n" "\n" "Parameter\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma voor het rood-aandeel)\n" " ggamma (gamma voor het groen-aandeel)\n" " bgamma (gamma voor blauw-aandeel)\n" "\n" "De waarden moeten tussen 0.1 en 10 voor de gamma liggen, -2 en 2 voor de " "contrast (negatieve waarden resulteren in een negatief beeld), -1 en 1 voor " "de helderheid en 0 tot 3 voor de verzadiging.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "Software video equalizer" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" "Software-Equalizer met interactieve bediening zoals bij een hardware-" "Equalizer voor zulke kaarten/drivers, die geen helderheid-/contraststuring " "in hardware bezitten.\n" "\n" "Parameters\n" " brightness: helderheid\n" " contrast: contrast\n" "\n" "Opmerking: het is mogelijk om het controlevenster te gebruiken om deze " "parameters in te stellen.\n" "\n" "* mplayer's eq (C) Richard Felker\n" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "soft video equalizer" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" "Deze expand-plugin converteert beelden met elke beeldverhoudingen naar " "beelden met een andere beeldverhouding (standaard 4:3) door het toevoegen " "van zwarte balken aan de bovenkant en de onderkant van het beeld. Hierdoor " "kunnen overlays naar onderen verschoven worden, zodat ze het beeld niet " "bedekken.\n" "\n" "Parameter\n" " Enable_automatic_shift: Automatisch overlay verschuiven\n" " Overlay_y_offset: handmatig de overlay verticaal verschuiven\n" " aspect: het doel-beeldverhouding (standaard 4:3)\n" " Centre_cut_out_mode: Extraheert 4:3 beelden uit 16:9 beelden\n" "\n" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" "Voegt boven en onder zwarten balken toe, om een beeldverhouding van 4:3 te " "krijgen." #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" "Snijdt links en rechts iets van het beeld af, om een beeldverhouding van 4:3 " "te krijgen." #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "Keert de beeldkleuren om." #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" "Voegt aan de video beeldruis toe.\n" "\n" "Parameter:\n" " luma_strength: hoeveelheid ruis dat aan de helderheid (luma)-kanaal (0-" "100, standaard: 8) wordt toegevoegd\n" " chroma_strength: hoeveelheid ruis dat aan de kleur-kanaal (0-100, " "standaard: 5) wordt toegevoegd\n" " quality: kwaliteit van de ruis. fixed: constant ruispatroon; temporal: " "ruispatroon wijzigt tussen de beelden; averaged temporal: zachtere " "ruispatroon, dat wijzigt tussen de beelden. (standaard: averaged temporal)\n" " type: type ruis: uniform of gaussian. (standaard: gaussian)\n" " pattern: mengt ruis met een (semi-)regelmatige patroon. (standaard: " "False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" #: src/post/planar/noise.c msgid "Adds noise" msgstr "Voegt aan de video beeldruis toe." #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameter\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "Plugin voor video-nabewerking met ffmpeg" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" "Unsharp masker / Gaussiaans vervagen \n" "De breedte en de hoogte van de matrix kan ingesteld worden, beide dimensies " "moeten oneven zijn (minimum 3x3, maximum 13x11 of 11x13, normaal gesproken " "tussen 3x3 en 7x7. De relatieve hoeveelheid scherpte/onscherpte, die aan het " "beeld toegevoegd wordt, moet normaal gesproken tussen -1.5 en 1.5 liggen).\n" "\n" "Parameter\n" "\n" " Luma_matrix_width: breedte van de matrix (moet oneven zijn)\n" " Luma_matrix_height: hoogte van de matrix (moet oneven zijn)\n" " Luma_amount: Relatieve hoeveelheid scherpte/onscherpte (=0 uitgeschakeld, " "<0 wazig, >0 scherpte)\n" " Chroma_matrix_width: breedte van de matrix (moet oneven zijn)\n" " Chroma_matrix_height: hoogte van de matrix (moet oneven zijn)\n" " Chroma_amount: Relatieve hoeveelheid scherpte/onscherpte (=0 " "uitgeschakeld, <0 wazig, >0 scherpte)\n" "\n" "* mplayer's unsharp (C) 2002 Rémi Guyomarch\n" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "Unsharp masker & Gaussiaans vervagen " #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "fftgraph geluidanimatie" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "FFT scoop geluidanimatie" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "Oscilloscoop" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "Animatie van de geluidsanalyse." #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "Lettertype voor externe ondertitels" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "" "Verticale offset voor ondertitels (relatief ten opzichte van de " "venstergrootte)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "CMML Ondertitel decoder" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "Tekstcodering van de ondertitels" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "DVD/VOB Ondertitel decoder" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "DVB Ondertitel decoder" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "Standaard tijdsduur in seconden voor het tonen van een ondertitel" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Enkele ondertitel bestandsformaten geven geen expliciete tijdsduur voor de " "ondertitel aan. Voor deze kunt u een standaard tijdsduur aangeven. Als u nul " "instelt, dan wordt de ondertitel getoond totdat door de volgende vervangt " "wordt." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "Decoder voor externe ondertitels" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "Ondertitel-grootte" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" "Past de ondertitel-grootte aan. Deze instelling is relatief ten opzichte van " "de venstergrootte." #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "Verticale offset voor ondertitels" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" "Past de verticale offset van de ondertitel aan. Deze instelling is relatief " "ten opzichte van de venstergrootte." #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "Lettertype voor ondertitels" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Een lettertype uit de font-map van xine voor het gebruik in de ondertitels." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "Een contour-lettertype (B.V. .ttf) voor het gebruik in de ondertitels." #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "Of een Freetype-lettertype gebruikt kan worden" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "Tekstcodering van de ondertitels" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "De tekstcodering van de ondertitels in de datastroom. Deze instelling wordt " "bij het tonen van niet-ASCII-tekens gebruikt. In het geval dat niet-ASCII-" "tekens anders getoond worden dan verwacht, kunt u het beste aan de maker van " "de ondertitels vragen welke tekstcodering is gebruikt." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "Gebruik niet verschaald OSD \"on screen display\" indien mogelijk." #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" "Niet verschaalde OSD worden onafhankelijk van het videobeeld gecreëerd en " "zullen altijd scherp zijn, zelfs als de video vergroot word. Het ziet er " "beter uit, maar werkt niet met alle grafische kaarten. De alternatieve zijn " "verschaalde OSD, die wazig worden als u een video met lage resolutie " "beeldvullend vergroot, maar werkt met alle videokaarten." #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "Ondertitel-demultiplexer" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "Ondertitel in MEPG-2-datastromen tonen" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "Ondertitels zijn meestal bedoelt voor hulp aan slechthorende." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "Voorgrond/achtergrond-schema voor ondertitels" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Selecteer uw favoriete weergave-schema voor ondertitels." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "Lettertype voor standaard ondertitel" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Selecteer het lettertype voor standaard ondertitels." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "Lettertype voor cursieve ondertitel" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "Selecteer het lettertype voor cursieve ondertitels." #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "Lettergrootte van ondertitel" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "Selecteer de lettergrootte voor ondertitels." #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "Centreren van ondertitels" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" "Indien ingeschakeld, zullen de ondertitels gecentreerd worden geplaatst." #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "Ondertitel-decoder" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "%s: input event resultaat: %s.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "%s: buffer_pool_alloc() faalde!\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "%s: flush (leegt) buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "%s: Beëindigd toegang op afstand (tijdoverschrijding: %d ms) ...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "%s: Breek toegang op afstand in de functie %d af...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "%s: Neem deel aan de toegang op afstand bij...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "%s: Aangesloten bij de toegang op afstand.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "%s: Openen van '%s' mislukte (%s)\n" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "Initialiseren duurde te lang" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "%s: Lezen van '%s' mislukte (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "%s: de creatie van een socket (kanaal) naar poort %d is mislukt (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "%s: Kan geen verbinding naar port %d (%s) tot stand brengen\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "%s: socket (kanaal) naar %d succesvol geopend, fd = %d\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "%s: Bezig met verbinden met VDR.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "%s: Onbekende computer '%s' (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" "%s: De verbinding maken naar alle sockets (kanalen) (poorten %d .. %d) was " "succesvol.\n" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" "%s: Media-adres (%s) is ongeldig! de opbouw moet zijn: vdr://Pfad/zu/fifo/" "stream of netvdr://computer:port waar ':port' ook weggelaten kan worden.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: Kan geen nieuwe thread (%s) creëren\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "Plugin voor VDR weergave-apparaat" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "Wijzigt alle audio zoals verlangt door VDR" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "Wijzigt alle video zoals verlangt door VDR" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr ": OSD \"on screen display\": (%d, %d)-(%d, %d)@%lg\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: Fouten bij ByteRun1-decomprimeren\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 wordt op dit moment niet ondersteund\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 wordt op dit moment niet ondersteund\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ wordt op dit moment niet ondersteund\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: Dit anim-type wordt op dit moment niet ondersteund\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "Raw bitplane video-decoder" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "gdk-pixbuf stilbeeld video-decoder" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "Stilbeeld video-decoder" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "AVI (libaom) video-decoder" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "JPEG stilbeeld video-decoder" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "Verkleint te grote JPEG-afbeeldingen, in plaats ze af te snijden" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" "Indien ingeschakeld, zal xine de JPEG-afbeeldingen verkleinen zodat deze met " "de mogelijkheden van uw grafische kaart kunnen worden bekeken. Als " "verschalen is uitgeschakeld, dan zullen de afbeeldingen worden bijgesneden." #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "mpeg2 video-decoder" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "HEVC video-decoder" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "vdpau: bij zoeken decoder opnieuw openen" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "Sommige drivers crashen zonder dit." #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "Alternative H264 decoder plugin gebruikt VDPAU hardware decoderen.\n" "Moet bij samen met video_out_vdpau worden gebruikt." #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "H264 decoder plugin gebruikt VDPAU hardware decoderen.\n" "Moet samen met video_out_vdpau gebruikt worden." #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "MPEG1/2 decoder plugin gebruikt VDPAU hardware decoderen.\n" "Moet samen met video_out_vdpau gebruikt worden." #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "MPEG4 part 2 decoder plugin gebruikt VDPAU hardware decoderen.\n" "Moet samen met video_out_vdpau gebruikt worden." #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" "VC-1/WMV3 decoder plugin gebruikt VDPAU hardware decoderen.\n" "Moet samen met video_out_vdpau gebruikt worden." #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "WebM (VP8/VP9) video-decoder" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "mmal video-decoder" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "Raw RGB video-decoder" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "Raw YUV video-decoder" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "Kleurmatrix" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" "Vertelt hoe weergave-kleuren uitgerekend moeten worden:\n" "\n" "Signal: hoe de video het aangeeft.\n" " Dit is niet altijd de beste keuze.\n" "\n" "Signal+Size: Hetzelfde als boven, maar gebruikt HD kleuren\n" " voor niet gemarkeerde HD Video.\n" "\n" "SD: Forceert de SD videostandaard ITU-R 470/601.\n" " probeer deze bij te weinig groen.\n" "\n" "HD: Forceert de HD videostandaard ITU-R 709.\n" " probeer deze bij te veel groen.\n" "\n" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "Contrastbereik" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" "Welk contrastbereik moet worden gebruikt?\n" "\n" "Auto: Zoals in de video wordt aangegeven.\n" " Dit kan soms fout zijn\n" "\n" "MPEG: Forceer MPEG/studio swing/Video-mode (16..235).\n" " Bruikbaar bij vale beelden (geen echte zwart of wit).\n" "\n" "FULL: Forceer FULL/full swing/PC Mode (0..255).\n" " Probeer deze als er zwarte en witte vlekken zonder details " "verschijnen.\n" "\n" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "Reserveert het X weergave-apparaat gedurende de complete video." #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" "Dit reduceert soms de systeembelasting en geeft minder beeldtrilling.\n" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "GL-leverancier (GLX)" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" "VAAPI video decodering mogelijk maken met elke video driver. als dit " "uitgeschakeld is, dan gebruikt alleen de vaapi video-driver de VAAPI " "accelerated decodering. Op dit moment kan alleen de opengl2 videodriver " "hiermee overweg." #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "vaapi: vaapi_guarded_render 0 (uit) 1 (in)" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "VAAPI beeld leverancier" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "xine videoweergave via ASCII-Art bibliotheek" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "xine videoweergave via kleuren-ASCII-Art bibliotheek" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "Video-laag buffer mode" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" "Selecteert de buffer mode voor de afspeellaag. Dubbel- of trippel-buffering " "geeft een vloeiender weergave, maar heeft ook meer videogeheugen nodig." #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "Wachten op straal-terugloop" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" "Synchroniseert het bijwerken van het videobeeld met het weergave van het " "complete beeldscherm (\"vertical retrace\")(\"Strahlenrücklauf\")." #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "colour key voor overlay inschakelen" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" "Schakelt het gebruik van een colour key in om aan de grafische kaart de " "locatie mede te delen waar het videobeeld geplaatst moet worden." #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "Video-colour key" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" "De colour key wordt gebruikt om aan de grafische kaart de locatie mede te " "delen waar het videobeeld geplaatst moet worden. Probeer verschillende " "kleuren uit als u merkt dat vensters transparant worden." #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "flikker filtering" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" "Schakelt flikker filtering in voor een vloeiende weergave op beeldschermen " "die een interlaced weergave gebruiken." #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "Veld prioriteit" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" "Voor een interlaced beeldscherm, de controle van de veld prioriteit toestaan " "(\"none\"=uitgeschakeld)." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" "video_out_directfb: Gebruikt hardwareversnelling voor de ondertitels.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "video_out_directfb: Videoweergave is op deze laag mogelijk.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "video_out_directfb: YV12 is op deze laag niet mogelijk!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "video_out_directfb: YUY2 is op deze laag niet mogelijk!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" "video_out_directfb: Minimaal is DirectFB 0.9.25 nodig voor het afspelen van " "deze laag!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "video_out_directfb: Buffer mode %d is op deze laag niet mogelijk!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "video_out_directfb: Optie 0x%08x is op deze laag niet mogelijk!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" "video_out_directfb: Gebruik hardwareversnelling voor het beeld-verschaling.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" "video_out_directfb: Beeld-verschaling en deinterlacing wordt met " "hardwareversnelling uitgevoerd.\n" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "Video-layer id (automatisch: -1)" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "Selecteert voor video's de video-laag aan de hand van zijn id." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "video_out_directfb: gebruikt weergave-laag #%d.\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "xine videoweergave via DirectFB" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "video_out_directfb: Geen bruikbare weergave-laag gevonden!\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "xine videoweergave via DirectFB/XDirectFB" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "Hardwareversnelling" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" "Mogelijke waarden (standaard: full):\n" "\n" "full: kleurberekeningen en grote veranderingen versnellen\n" "scale: geen kleurruimte conversie (alleen HW verschalen\n" "none: geen versnelling" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "xine videoweergave via win32/directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: Alleen packed truecolor/directcolor kan worden gebruikt (%d).\n" " Controleer 'fbset -i' of probeer 'fbset -depth 16' uit.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "Framebuffer apparaat" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" "Specificeert de naam van het Sun framebuffer-apparaat.\n" "OPGEPAST: Een verkeerde naam zorgt dat een bestand met deze naam wordt " "gecreëerd (of overschreven) met reusachtige hoeveelheden data! Zorg er " "daarom voor dat de ingevoerde naam een echt framebuffer-apparaat is." #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Uw video mode werd niet herkend, sorry.\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: %d video RAM buffers zijn beschikbaar.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "WAARSCHUWING: %s: Nul-kopie-buffers zijn UITGESCHAKELD, omdat alleen %d " "buffers\n" " beschikbaar zijn, wat minder dan de aanbevolen %d buffer zijn. " "Verkleinen\n" " van de framebuffer-resolutie kan helpen.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "WAARSCHUWING: %s: Nul-kopie-buffers zijn UITGESCHAKELD, omdat de kernel " "driver\n" " geen screen-panning ondersteund (gebruikt voor beeldwisseling).\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "WAARSCHUWING: %s: Actuele kleurdiepte is %d. Voor betere prestaties wordt " "een een diepte van 16 bpp aangeraden!\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "xine videoweergave via Linux framebuffer" #: src/video_out/video_out_mmal.c msgid "xine video output plugin using MMAL" msgstr "xine videoweergave via MMAL" #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "Geen xine videoweergave" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "opengl2: Vergroot bi-kubisch de video" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" "Bi-kubisch vergroten of verkleinen van het beeld geeft (bijna) geen verlies " "van scherpte.\n" "Maar het heeft wel een snelle grafische kaart nodig.\n" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "opengl2: video verschalingsmodus" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" "0: Simple. Zeer snel, zeer scherp,\n" " maar geeft ook trappetjes, oneven lijnen, en flikkerende bewegingen.\n" "\n" "1: Linear blending. Snel, erg vloeiend, maar ook een beetje wazig.\n" "\n" "2: Catmullrom blending. erg vloeiend, scherp, maar heeft snelle hardware " "nodig.\n" "\n" "3: Cosinus blending. vloeiend, zeer scherp, maar heeft snelle hardware " "nodig.\n" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "Opengl 2.0 videoweergave" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "OpenGL renderer" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" "De OpenGL plugin heeft verschillende render-modellen:\n" "\n" "2D_Tex_Tragprog\n" "Dit modul laad de beelden als YUV 2D-texturen en rendert als een vlak met " "textuur met de hulp van fragment-programma's voor de reconstructie van RGB.\n" "Dit is de beste en snelste methode bij moderne grafische kaarten.\n" "\n" "2D_Tex\n" "Dit module laadt de beelden als 2D-texturen en rendert een vlak met met " "textuur.\n" "\n" "2D_Tex_Tiles\n" "Dit module laadt de beelden als meerdere 2D-texturen en rendert een vlak met " "textuur.\n" "Daarom werkt deze methode ook met kleinere textuur-groottes.\n" "\n" "Image_Pipeline\n" "Deze module gebruikt glDraw() voor het renderen van de beelden.\n" "Werkt alleen sneller bij maar een paar drivers.\n" "Interpoleert niet bij verschaling.\n" "\n" "Cylinder\n" "Toont afbeeldingen op een roterende cylinder. Leuk effect :)\n" "\n" "Environment_Mapped_Torus\n" "Toont afbeeldingen op een roterende torus. Heel cool =)" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "Minimale OpenGL framesnelheid" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" "Minimum framesnelheid voor geanimeerde render-routines.\n" "Wordt genegeerd voor statische render-routines.\n" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "Dubbel bufferen gebruiken" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" "Bij OpenGL voorkomt dubbel buffering niet alleen scheeftrekken,\n" "maar reduceert ook flikkeren.\n" "Het zou geen invloed op de prestaties moeten hebben." #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "xine videoweergave via OpenGL 3D Grafische API" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx32: Fout: kan DGA tekenvlak voor videovenster niet krijgen\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Fout: ioctl faalde, foutgevoelig apparaat (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "video_out_pgx32: Fout: '%s' is geen apparaat met pgx32 framebuffer\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "xine videoweergave via Sun PGX32 framebuffer" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx64: Fout: kan DGA tekenvlak voor videovenster niet krijgen\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "video_out_pgx64: Fout: kan framebuffer apparaat '%s' niet openen\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Fout: ioctl (VIS_GETIDENTIFIER) faalde, foutgevoelig " "apparaat (%s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Fout: '%s' is geen apparaat met xvr100/pgx64/pgx24 " "framebuffer\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" "video_out_pgx64: Fout: Video-overlay wordt als op dit scherm gebruikt\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" "video_out_pgx64: Fout: venstereigenschappen kunnen niet ingesteld worden\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Waarschuwing: te weinig videogeheugen, multi-buffering " "uitgeschakeld\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Fout: niet genoeg videogeheugen\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Waarschuwing: te weinig videogeheugen, dubbel-buffering " "uitgeschakeld\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Fout: ioctl(FBIOGATTR) faalde\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "colour key voor video-overlay" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" "De colour key wordt gebruikt om aan de grafische kaart de locatie mede te " "delen waar het videobeeld geplaatst moet worden. Probeer verschillende " "kleuren uit als u merkt dat video's door andere vensters heen schijnen." #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "Bluescreen gebruiken" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" "OSD-afbeeldingen worden op de locatie geplaatst van de overlay-colour key, " "in plaats van dat ze op elk beeld worden geprojecteerd." #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "Multi-buffer gebruiken" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" "Een multi-buffer verhoogt de prestaties ten koste van groter gebruik van het " "grafische geheugen." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "xine videoweergave via Sun XVR100/PGX64/PGX24 framebuffer" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "xine Beelduitgave als ruwe data naar een extern programma" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "Gebruik hardwareversnelling indien beschikbaar" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "Als het bij uw systeem mogelijk is, word de hardwareversnelling van uw " "videokaart gebruikt. Als dit niet functioneert, dan kunt u het uitschakelen." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "SDL moet een 16 bit uitvoer nabootsen, wat alles langzamer maakt.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: Volledig scherm is NIET mogelijk\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "xine videoweergave via 'Simple Direct Media Layer'" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "xine video beeldweergave via LibStk Surface Set-top Toolkit" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" "video_out_vaapi: Driver kan geen \"%s\" kleurruimteconversie uitvoeren\n" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "Standaard aantal videobeelden" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" "Het standaard aantal videobeelden die van xine videodrivers worden gevraagd. " "Sommige drivers overschrijven dit met hun eigen waarden." #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "vaapi: Weergave via OpenGL" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "vaapi: opengl rendering tfp" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" "vaapi: Provisorische oplossing voor VDR OSD \"on screen display\" met een " "foutieve breedte." #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "vaapi: Provisorische oplossing voor foutieve VDR OSD-hoogte." #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" "vaapi: Stelt deinterlace-mode: 0 (geen), 1 (top veld), 2 (weichzeichnen)." #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" "vaapi: Stelt de kwaliteit in voor het vergroten/verkleinen:\n" "default (standaard), fast (snel), hq (goed), nla (anamorph)" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "vaapi: Verwisselt U en V vlakken." #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" "vaapi: Corrigeert rood/blauw-fouten bij enige buggy drivers (intel " "IronLake).\n" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "VAAPI Kleurruimte conversie-methode" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" "Kleurenconversie via VAAPI:\n" "\n" "user_matrix: De beste manier - als uw driver ermee om kan gaan.\n" "simple: Verwissel SD/HD kleurruimtes, en laat decoders de de complete " "video converteren.\n" "simple+2: Verwissel SD/HD kleurruimtes, en corrigeer de full-range kleur " "door de\n" " helderheid/contrast-instellingen aan te passen.\n" "simple+3: Zoals boven, maar pas ook de verzadiging aan.\n" "\n" "Tip: Speel \"test://rgb_levels.bmp\" af, terwijl u dit uit probeert.\n" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI overlay mode" msgstr "VAAPI beeld leverancier" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "xine video output plugin using VAAPI" msgstr "xine videoweergave via VAAPI" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "Maximaal voor hergebruik opgeslagen aantal videobeelden" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "Maximaal voor hergebruik opgeslagen aantal videobeelden" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "Standaard lengte van weergave-wachtrij" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" "Het standaard aantal videobeelden dat gecreëerd wordt voor de weergave-" "wachtrij." #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "vdpau: HD-deinterlace methode" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "vdpau: SD-deinterlace methode" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "vdpau: Kwaliteit bij het vergroten/verkleinen" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "Kwaliteitsniveau bij het vergroten/verkleinen." #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "vdpau: Probeer de originele beeldherhaalfrequentie te herstellen" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" "Schakel dit in om verkeerd gemarkeerde progressieve inhoud te detecteren\n" " wat voor de TV nabewerkt is (zogeheten 2:2 of 3:2 Pulldown).\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "vdpau: deinterlacing niet gebruiken bij progressieve video" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" "Markeer deze instelling als u vertrouwen heeft in de progressive_frame " "stream's flag.\n" "Dit bitveld is niet altijd betrouwbaar.\n" "\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "vdpau: Kleurenfilter uitschakelen bij deinterlace" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" "Dit inschakelen kan helpen als uw videokaart niet in staat is om met " "geavanceerde deinterlacers te werken.\n" "\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "vdpau: Gekleurde vlakken voor ongebruikt beeldvlak" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" "Door het tonen van 4:3 afbeeldingen op een 16:9 plasma TV set laat de " "inactieve pixels buiten de video langzamer verouderen dan de pixels in het " "actieve vlak. Door het instellen van een andere achtergrond kleur (b.v. " "8421504) verouderen alle pixels met dezelfde snelheid. Het getal dat " "ingevoerd moet worden voor een bepaalde kunt u verkrijgen uit zijn 6 " "cijferige hexadecimale RGB waarde.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "vdpau: SD-specifieke instellingen" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" "none\n" "Alles zoals bij HD, geen restricties.\n" "\n" "noise\n" "Ruis vermindering alleen bij SD.\n" "\n" "sharpness\n" "Verscherpen alleen bij SD.\n" "\n" "noise+sharpness\n" "Ruis vermindering en verscherpen alleen bij SD.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "vdpau: Maakt snapshots zoals op het beeldscherm is getoond." #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" "IN: vergroot/verkleint, bijgesneden, opgevuld en ondertitelt.\n" "UIT: puur alleen het originele videobeeld.\n" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" "vdpau: Provisorische oplossing voor problematische video mixer overlays" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" "Sommige 2022 vdpau_radeonsi drivers crashen bij het tonen\n" "van ondertitels of berichten op het scherm op de normale manier.\n" "De instelling \"Aan\" is iets langzamer maar helpt hier.\n" "De instelling \"Uit\" voorkomt het flikkeren bij sommige drivers.\n" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "xine videoweergave met gebruik van VDPAU-hardwareversnelling" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "Rood-intensiteit" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "De intensiteit van het rode kleuraandeel" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "Groen-intensiteit" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "De intensiteit van het groene kleuraandeel" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "Blauw-intensiteit" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "De intensiteit van het blauwe kleuraandeel" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" "Dubbel buffering synchroniseert het updaten van de videobeelden met de " "weergave van het complete beeldscherm (\"vertical retrace\")" "(\"Strahlenrücklauf\"). Dit verhindert flikkeren en scheeftrekken, maar het " "heeft wel meer grafisch geheugen nodig." #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: adapter kan met het YUY2 formaat overweg\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: adapter kan met het YV12 formaat overweg\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" "video_out_vidix: U heeft een verkeerde versie van de VIDIX-bibliotheek\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: Kan geen functionerende VIDIX-driver vinden\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: Gebruikt driver: %s van %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "Rood-component van de colour key" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "Groen-component van de colour key" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "Blauw-component van de colour key" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "xine videoweergave via libvidix voor X11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "xine videoweergave via libvidix voor Linux framebuffer" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "%s: %s: opslaan afbeelding\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "%s: => gebruikt de \"MIT Shared Memory\" extensie niet.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "%s: shared memory fout (fout in adres) bij opslaan van afbeelding\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "%s: x11 fout bij het opslaan van een XImage in shared memory\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "WAARSCHUWING: Actuele kleurdiepte is %d. Voor betere prestaties wordt een " "een diepte van 16 bpp aangeraden!\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" "%s: \"MIT-Shared-Memory\" extensie is niet aanwezig op het beeldscherm.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: Uw video mode werd niet herkend, sorry.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "xine videoweergave door gebruik van de 'MIX X Shared Memory' extensie" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "%s: XvShmCreateImage antwoordde met Nul als grootte\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "%s: fout in shared memory in shmget: %s\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "%s: shared memory fout (fout in adres)\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: adapter kan met het %s-formaat overweg.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: Xv-extensie is niet aanwezig.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" "%s: Kon Xv poort %lu niet openen - gaat automatische detectie gebruiken\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" "%s: Geen poort van het type \"%s\" beschikbaar, selecteert " "standaardkeuze...\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: Xv-extensie is aanwezig, maar er is geen bruikbare YUV12-conversie " "gevonden.\n" " het lijkt dat uw grafische kaart niet met Xv overweg kan!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: Xv-poort %d van adapter %s wordt gebruikt voor hardware-kleurruimte-" "conversie en verschaling\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "Synchroniseer beeldwissel" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" "Dubbel buffering synchroniseert het updaten van de videobeelden met de " "weergave van het complete beeldscherm (\"vertical retrace\")" "(\"Strahlenrücklauf\"). Dit verhindert flikkeren en scheeftrekken, maar het " "heeft wel meer grafisch geheugen nodig. Bij nvidia kaarten moet u wellicht " "ook \"nvidia-settings\" opstarten en in de XVideo Settings tab instellen " "welk beeldscherm wordt gebruikt voor de synchronisatie." #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "Full-range kleur emulatie" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" "Emuleer full-range kleur door de instellingen voor helderheid/contrast/" "verzadiging te wijzigen.\n" "\n" "Off: Laat decoders een dergelijke video converteren.\n" " Werkt met alle grafische kaarten, maar heeft een stuk meer " "rekenkracht nodig.\n" "\n" "Normal: Snellere en betere beeldkwaliteit. Zou in elk geval met nieuwere\n" " grafische kaarten (GeForce 7+, 210+) moeten werken.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "Forceer YUY2-Emulatie" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "Foutzoeken" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "xine videoweergave door gebruik van de \"MIT XVideo\" extensie" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "%s: Fout bij het opslaan van afbeelding in shared memory\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "%s: XvShmCreateImage faalde\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: Xv-poort %ld van adapter %s wordt gebruikt voor hardware-kleurruimte-" "conversie en verschaling\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: XvMC-extensie is niet aanwezig.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: Xv-extensie is aanwezig, maar er is geen bruikbare YUV12-" "conversie gevonden.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xvmc: Xv-poort %ld van adapter %s wordt gebruikt voor hardware-" "kleurruimte-conversie en verschaling\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " IDCT en beweging-compensatie versnelling \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " alleen beweging-compensatie versnelling\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " Geen XvMC-ondersteuning \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " Met overlay = %d; UnsignedIntra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "xine videoweergave door gebruik van de \"XvMC XVideo\" extensie" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "XvMC claimt meer videogeheugen voor betere buffering." #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" "Sommige XvMC-implementaties staan meer dan 8 beelden toe.\n" "Deze optie laat het de drive proberen (als het ingeschakeld is) om 15\n" "beelden te gebruiken. Een noodzaak voor Unichrome en live VDR.\n" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Unichrome Rekenkracht besparing" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" "Bespaart op de CPU-rekentijd door te gaan slapen terwijl de decoder aan het " "werk is.\n" "Alleen beschikbaar bij Linux-kernel uit de 2.6er serie of 2.4er met " "multimedia-patch.\n" "Experimenteel.\n" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "Herstelt fouten in NVIDIA XvMV ondertitel-kleuren" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" "Er is een bug in NVIDIAs XVmC bibliotheek, dat er voor zorgt dat rode OSD " "\"On Screen Display\" er blauw uitziet en omgekeerd. Deze instelling levert " "een provisorische oplossing.\n" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Gebruik BOB als snellere deinterlacing-methode." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" "Als interlacing is ingeschakeld bij hardware-versnelde weergave,\n" "wissel dan af tussen de bovenste helft en de onderste helft met een dubbele " "beeldfrequentie.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "\"BOB\"-deinterlacing niet gebruiken bij progressieve beelden." #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" "Progressieve beelden hebben deinterlacing niet nodig, daarom zou het op \n" "verzoek uitschakelen een beter beeld moeten geven.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" "Deaktiveer \"BOB\"-deinterlacing als een verschaalde OSD \"on screen display" "\" actief is." #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" "Verbetert de beeldkwaliteit van als OSD \"on screen display\" weergegeven " "teksten.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: XShape-extensie niet beschikbaar. niet verschaalde OSD " "uitgeschakeld.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: Fout bij het creatie van het venster. niet verschaalde OSD " "uitgeschakeld.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: Fout bij het creatie van het pixmap. niet verschaalde OSD " "uitgeschakeld.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: Niet verschaalde overlay gecreëerd (%s Modus).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "automatische colour key" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Zorgt dat Xv automatisch de colour key selecteert." #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "Bilineaire verschalingsmodus" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" "Hier stelt u de bilineaire verschalingsmodus in voor Permedia kaarten. De " "waarden kunnen zijn:\n" "\n" "Permedia 2\n" "0 - schakelt het bilineaire filter uit\n" "1 - schakelt het bilineaire filter in\n" "\n" "Permedia 3\n" "0 - schakelt het bilineaire filter uit\n" "1 - horizontale lineaire filter\n" "2 - schakelt het complete bilineaire filter in" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "Xv Poortnummer" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "Selecteer het Xv poortnummer, of 0 voor \"automatisch\"." #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "provisorische oplossing voor toonhoogte correctie" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" "Enkele foutieve videodrivers hebben dit nodig voor een correcte functie." #: src/video_out/xv_common.h msgid "video display method preference" msgstr "Voorkeur videoweergave" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" "Hier stelt u in welke videoweergave de voorkeur heeft. De detectie gaat via " "de gemelde Xv adapter namen.\n" "(Is alleen van toepassing als wordt gedetecteerd welke Xv poort wordt " "gebruikt.)" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "Bi-kubisch filter" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" "Enkele grafische kaarten bieden deze beeldverbetering aan.\n" "Het kan in plaats van of samen met xine's deinterlacers worden gebruikt." #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "Schakel exacte transparantie bij overlays uit" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" "Als u problemen merkt met de rekenkracht als u een OSD (On Screen Display) " "of andere overlays zoals DVD ondertitels ingeschakeld zijn, dan wilt u dit " "wellicht inschakelen.\n" "Het resultaat zal zijn dat de projecties van overlays minder mooi en " "nauwkeurig zal zijn, maar het gebruik van de CPU ook minder zal zijn." #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: Geen plugin beschikbaar dat met '%s' overweg kan\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: Fout, onbekend type buffer: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "Aantal audio-buffers" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Het aantal audio-buffer (elk 2KiB groot), die xine voor zijn interne " "wachtrij gebruikt. Grotere waarden geven een vloeiender afspelen bij " "onbetrouwbare bronnen, maar verhogen ook de vertraging (latency) en het " "geheugen verbruik." #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: Berekening van de vertraging is niet mogelijk voor een niet " "beschikbaar audio-apparaat\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" "Naar de geluidskaart sturen mislukte. Werd een USB-apparaat verwijderd?\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "" "8 bits is niet mogelijk met deze driver, bezig met converteren naar 16 bit.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "" "Mono is niet mogelijk met deze driver, bezig met converteren naar stereo.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "" "Stereo is niet mogelijk met deze driver, bezig met converteren naar mono.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "Methode voor audio/video-synchronisatie" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" "Bij het afspelen van audio en video zijn minstens twee klokken betrokken: De " "systeemklok, waarmee de videobeelden worden gesynchroniseerd, en de klok in " "uw geluidskaart, die de snelheid van de audio bepaalt. Deze klokken klokken " "lopen nooit exact met dezelfde snelheid uitgezonderd enkele zeldzame " "gevallen waar ze fysiek identiek zijn. In het algemeen lopen de klokken na " "enige tijd uit elkaar, waarvoor xine twee methoden aanbied, om de audio en " "de video weer te synchroniseren:\n" "\n" "metronom feedback\n" "Dit is de standaardmethode, waarbij een tegengestuurde videodrift wordt " "toegepast, zodra de opgestapelde audiodrift een grenswaarde overschreden " "heeft.\n" "\n" "resample\n" "Bij enkele videokaarten, die beperkt zijn tot alleen een vaste " "beeldfrequentie (zoals b.v. de DXR3 of andere decoder-kaarten), functioneert " "bovengenoemde niet, omdat de video niet driften kan. In plaats daarvan wordt " "de audiostroom geresampled, om deze als compensatie voor de audiodrift " "korter of langer te maken. Dit werkt niet bij het doorgeven van de audio " "naar een externe decoder." #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "Nauwkeurigheid voor audio/video synchronisatie" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" "Normal: houd de afwijking onder de driver-tolerantie.\n" "Fine: houd de afwijking onder 1/8 van de tolerantie." #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "Resampling gebruiken" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" "Als de samplesnelheid van de gecodeerde audio niet overeenkomt met de " "mogelijkheden van de audio-hardware, dan is een aanpassing genaamd " "\"resampling\" nodig. U kan hier instellen of deze aanpassing permanent " "ingeschakeld is, permanent uitgeschakeld of indien nodig automatisch " "ingeschakeld kan worden." #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "Altijd resample met deze frequentie (0 om uit te schakelen)" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" "Enkele audio-drivers melden niet correct de mogelijkheden van de audio " "hardware. Door een waarde anders dan nul op te geven, kunt u forceren dat de " "audiostroom met deze snelheid wordt geresampled." #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "Offset voor externe geluid-decoder" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Als u een extern surround-decoder gebruikt en de audio loopt altijd niet " "synchroon met de video, dan kan dit door een vaste offset gecompenseerd " "worden.\n" "De eenheid van deze waarde is een \"PTS-tick\", wat overeenkomt een " "90.000ste van een seconde." #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "Audio afspelen bij langzamere/snellere snelheid" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" "Als u dit inschakelt, dan wordt de audio zelfs afgespeeld als de " "weergavesnelheid anders is dan 1×. De weergave zal uiteraard vervormd " "klinken (hogere/lagere tonen). Als u wilt experimenteren en de toonhoogte " "wilt bewaren, probeer dan in plaats daarvan de 'stretch' weergave plugin." #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "Audio start volume" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Gezamenlijke volume bij start van XINE." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "Volume bij starten herstellen" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "Indien uitgeschakeld, zal xine bij het starten de geluidsvolume niet " "wijzigen." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: Oeps, dat zou eigenlijk niet mogen gebeuren, start xine opnieuw " "op.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "xine-lib: buffer.c: Fatale fout: TEVEEL VRIJGAVEN\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "%s: Onbekend beeldformaat %#x \"%s\"\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "%s: Onbekend geluidformaat %#x \"%s\"\n" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "Het configuratiebestand is door een nieuwere versie van XINE gewijzigd." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "Instellingen uit bestand '%s' zijn geladen\n" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "Laden van de instellingen uit bestand '%s' mislukte: %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "" "configfile: WAARSCHUWING: uw configuratie zal niet worden worden opgeslagen\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" "configfile: WAARSCHUWING: Schrijven van configuratie naar %s mislukte\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: WAARSCHUWING: bezig met verwijderen van mogelijk defect " "configuratiebestand %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: WAARSCHUWING: Controleer de reservekopie %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: Item '%s' mag niet door media-adres gewijzigd worden\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" "Het programma is blijven steken in demux_control_headers_done(). Probeer af " "te breken.\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" "Het programma is blijven steken in demux_loop(). Probeer af te breken.\n" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "info_helper: Kan de gekozen lokale karakterset niet vinden\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" "info_helper: Conversie %s -> UTF-8 is niet beschikbaar, tekst onveranderd\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": open()-functie zou nooit opgeroepen moeten worden\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": Input-plugin niet gedefinieerd!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: Lezen van opgeslagen data mislukte: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: Opzoeken van positie is mislukt: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: Lezen door input_rip-plugin mislukte\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "" "input_rip: fouten bij schrijven naar bestand % bij bytes: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: open()-function zou nooit opgeroepen moeten worden\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: Opzoeken van positie is mislukt\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % bytes genegeerd\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: Input-plugin niet gedefinieerd!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: Doelmap is niet opgegeven, stel de optie 'media.capture.save_dir' " "in\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "Het opslaan van datastromen is uitgeschakeld totdat de media.capture." "save_dir in de configuratie is ingesteld." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: Rippen/tussenopslag van deze bron is niet toegestaan!\n" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine mag deze bron niet opslaan. (Misschien materiaal met beschermde " "auteursrechten?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: Bestandsnaam niet opgegeven!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_ipd: Fout bij openen bestand %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: Wachten opgegeven\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: Wachten faalde: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "De status van de socket (kanaal) kon niet verkregen worden" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Toegang geweigerd\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Bestand niet gevonden\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Verbinding geweigerd\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "map_decoder_list: geen plaats voor decoder, overgeslagen.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: Onbekend plugin-type %d in %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: Onbekend statisch gelinkte plugin-type %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: Plugin %s wordt genegeerd, verkeerde iface-versie %d (zou %d " "moeten zijn)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" "load_plugins: Maximum aantal plugins bereikt, %s kon niet geladen worden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" "load_plugins: Maximum aantal plugins bereikt, statisch plugin kon niet " "geladen worden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "Prioriteit voor decoder %s" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: Demultiplexer-plugin %s geeft geen prioriteit op, xine-lib " "gebruikt de standaard prioriteit.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: Input-plugin %s geeft geen prioriteit, xine-lib gebruikt de " "standaard prioriteit.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: Plugin %s:%s gevonden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: Onleesbare plugin-map %s overgeslagen.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: Kan %s niet onderzoeken\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: Kan plugin-bibliotheek %s niet openen:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: Kan plugin-informatie van %s niet lezen:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: (Fase 2) Kan plugin-bibliotheek %s niet openen:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Yakes! in %s is geen plugin-informatie aanwezig.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "Kon map %s niet creëren: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "Opslaan van plugin-lijst is mislukt: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "Vernieuwen van plugin-lijst is mislukt: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "Verwijderen van plugin-lijst is mislukt: %s\n" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" "De prioriteit legt een rangorde vast, in het geval dat een media door meer " "dan een decoder behandelt kan worden.\n" "Een prioriteit van 0 activeert de decoder met zijn standaardprioriteit ." #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: Onbekende strategie voor inhoud-detectie %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: Demultiplexer '%s' is in gebruik\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: Audio-plugin <%s> kon niet geladen worden\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "load_plugins: Geen bruikbare audio-driver gevonden.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: Kan plugin-bibliotheek %s niet uit geheugen verwijderen:\n" "%s\n" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "Algemene beeld naar audio tijdvertraging" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" "Het is niet eenvoudig om beeld en geluid gelijk te laten lopen.\n" "Xine compenseert zelf de vertragingen die bij hem bekend zijn.\n" "Maar externe zaken zoals flatscreens, versterker of heel eenvoudig\n" "de afstand tussen u en de luidsprekers, kunt u \n" "hier handmatig het beeld in stapjes van 1/90000 seconde vertragen." #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "Synchroniseer meerdere klokken in een separate thread" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "Dit helpt bij problemen met meerdere (b.v. programma-eigen ) klokken." #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Bezig met bufferen..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "Verkeerde versie van lettertype '%s'. Verwachtte %d gevonden %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "Lettertype '%s-%d' is al geladen, vreemd.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "Laden van lettertype '%s' mislukte (%d <%d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" "osd: Er is een fout opgetreden bij het zoeken naar het lettertype %s met " "FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" "osd: Er is een fout opgetreden bij het laden van het lettertype %s met " "FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "osd: Lettertype %s niet gevonden met FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "osd: Fout bij het laden van lettertype %s uit de XDG datamap\n" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: initialiseren van ft2-bibliotheek mislukte\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" "osd: Kan lettergrootte niet veranderen (geen verschaalbare lettertype?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: Onbekende sequens startte met byte 0x%02X in codering \"%s\", " "overgeslagen\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: Kan de gekozen lokale karakterset niet vinden\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: Conversie %s -> %s niet beschikbaar, tekst onveranderd\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: Fout bij het laden van glyph\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: Fout bij de weergave van glyph\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: Lettertype is niet gedefinieerd\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: Fout bij het laden van glyph %i\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: Fout bij de weergave\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" "Kleurpalet (voorgrond-rand-achtergrond) voor ondertitels en OSD \"on screen " "display\"" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" "Het kleurpalet voor OSD \"On Screen Display\" en ondertitels die niet zelf " "de kleur voorschrijven. De opbouw van het kleurpalet is: voorgrond-rand-" "achtergrond." #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "Transparantie van de zwarte gedeelten in grafische ondertitels." #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "Transparantie van de gekleurde gedeelten in grafische ondertitels." #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: Geen plugin beschikbaar dat met '%s' overweg kan\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: Fout, onbekend type buffer: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "Aantal video-buffers" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Het aantal video-buffer (elk 8KiB groot), die xine voor zijn interne " "wachtrij gebruikt. Grotere waarden geven een vloeiender afspelen bij " "onbetrouwbare bronnen, maar verhogen ook de vertraging (latency) en het " "geheugen verbruik." #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" "video_out: onbruikbaar beeld-buffer gevonden (%dx%d, format %0x08x) - " "geheugen gebrek??\n" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d beelden getoond, %d beelden overgeslagen, %d beelden genegeerd\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: Negeer beeld met pts %, omdat het te oud is (verschil: %" ").\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "decoder flush (legen) door video-uitvoer uitschakelen" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" "Video decoder is flushed (geleegd) als het een tijdje geen nieuwe beelden " "heeft geleverd.\n" "Als u dit uitschakelt dan verdwijnen enkele tijdelijke beeld-vervormingen.\n" "Maar het kan problemen opleveren bij stilbeelden op een DVD.\n" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "video_out: %d van %d beeldbuffer gebruikt\n" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "video_out: Geen beeld bij %d van %d gebruikt\n" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "Beeldfrequentie beperken" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" "Indien geen 0, wordt de uitgevoerde beeldfrequentie beperkt tot deze waarde, " "zonder extra beeldtrilling.\n" "Probeer 40 om energiegebruik te beperken, en/of om een langzame driver te " "gebruiken.\n" "Anders is de huidige beeld-verversingsfrequentie plus 5 een goed idee ;-)\n" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "Toegestane percentage overgeslagen beelden" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" "Wanneer meer dan dit percentage videobeelden niet worden getoond omdat ze " "niet op tijd gedecodeerd werden, zal XINE een melding geven." #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "Toegestane percentage genegeerde beelden" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" "Wanneer meer dan dit percentage videobeelden niet worden getoond omdat ze " "niet op tijd gepland werden, zal XINE een melding geven." #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out : Oeps, dat zou eigenlijk niet mogen gebeuren, start xine opnieuw " "op.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "Horizontale beeldpositie in venster" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" "Als de horizontale grootte van het videovenster groter is dan de actuele " "afbeelding die u wilt tonen, dan kunt u de positie aanpassen waar de " "afbeelding geplaatst wordt.\n" "De positie wordt als een percentage aangegeven: de waarde van 50 betekent " "\"in het midden\", terwijl 0 \"helemaal links\" en 100 \"helemaal rechts\" " "betekent." #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "Verticale beeldpositie in venster" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" "Als de verticale grootte van het videovenster groter is dan de actuele " "afbeelding die u wilt tonen, dan kunt u de positie aanpassen waar de " "afbeelding geplaatst wordt.\n" "De positie wordt als een percentage aangegeven: de waarde van 50 betekent " "\"in het midden\", terwijl 0 \"helemaal bovenaan\" en 100 \"helemaal onderaan" "\" betekent." #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "Alle video-verschaling uitschakelen" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" "Als het videobeeld altijd in de originele resolutie getoond moet worden, dan " "kunt u hier de verschaling van het beeld uitschakelen.\n" "Dit betekent natuurlijk dat het beeld niet langer aan het venstergrootte " "aangepast wordt en dat videos, waarvan de hoogte/breedte-verhouding van de " "pixels niet 1:1 is (b.v. DVDs met vertekende (anamorf) beelden), vervormd " "getoond worden. Maar aan de andere kant profiteren enkele video-drivers " "waarvan XShm er eentje is, waarvan de beeldverschaling zonder " "hardwareversnelling is, zodat de CPU-belasting drastisch minder is." #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "Beschouwt monitor-pixels als exact vierkant" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" "Vele monitoren hebben \"alleen\" bijna vierkante pixels, zoals b.v. 94x93 " "dpi.\n" "Voor grafische programma´s en dergelijke is deze kleine afwijking " "belangrijk.\n" "Voor video betekent dit echter alleen maar onnodige zwarte balken en minder " "beeldscherpte.\n" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "Bij tijdsprongen decoder flush (legen) uitschakelen" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" "Video decoder is flushed (geleegd) bij tijdsprongen.\n" "Als u dit uitschakelt dan verdwijnen enkele tijdelijke beeld-vervormingen " "bij DVB (TV).\n" "Maar het kan problemen opleveren bij stilbeelden op een DVD.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: onbegrijpelijk media-adres\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: Invoer-plugin gevonden: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: plugin kan media-adres [%s] niet openen\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: Kan geen plugin voor het media-adres [%s] vinden\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: Demultiplexer %s startte niet\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: Rip input plugin openen\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: Fout bij het openen van rip input plugin-instance\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: Laatste demultiplexer %s startte niet\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "Video wordt genegeerd\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "Audio wordt genegeerd\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "Ondertitels worden genegeerd\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "Input-cache plugin uitgeschakeld\n" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "Ondertitel-Media-adres geopend '%s'\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: Fout bij het openen van het ondertitel-media-adres\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "xine: Negeer onbekende configuratie-optie \"%s\".\n" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: Het veranderen van de optie '%s' per media-adres is verboden\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "xine: \"%s\" zonder inhoud wordt genegeerd.\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "xine: Kan demultiplexer %s voor >%s< niet laden\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: Kan geen demultiplexer voor >%s< vinden\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: Demultiplexer gevonden: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine: Demultiplexer is al klaar - dat was snel!\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: Demultiplexer startte niet\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: Geen demultiplexer beschikbaar\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: Demultiplexer startte niet\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "xine: De opgegeven save_dir '%s' kan een veiligheidsprobleem zijn.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "De opgegeven save_dir '%s' kan een veiligheidsprobleem zijn." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: Taal wordt niet door een C-bibliotheek ondersteund\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "Media format herkenningsstrategie" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" "xine bied verschillende methodes, om het media-format van de bron te " "herkennen. De waardes kunnen zijn:\n" "\n" "default\n" "Probeer eerst aan de hand van de inhoud te herkennen, en vervolgens via de " "bestand-extensie.\n" "\n" "reverse\n" "Probeer eerst aan de hand van de bestand-extensie, en vervolgens aan de hand " "van de inhoud.\n" "\n" "content\n" "Alleen aan de hand van de inhoud te herkennen.\n" "\n" "extension\n" "Alleen aan de hand van de bestand-extensie.\n" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "Pad voor het opslaan van datastromen" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" "Als datastromen opgeslagen moet worden, dan wordt de data alleen in deze map " "opgeslagen.\n" "OPGEPAST: deze instelling is veiligheid-kritisch, een verkeerde naam zorgt " "dat een bestand met deze naam wordt gecreëerd (of overschreven) met " "reusachtige hoeveelheden willekeurige data! Test dus goed uit dat dat het " "adres robuust is voor iedere soort inhoud in elk bestand." #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" "Impliciete wijzigingen aan de configuratie toestaan (b.v. door media-" "adressen)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" "Indien ingeschakeld, kunnen instellingen ook zonder expliciete actie van u " "verandert worden. Bijvoorbeeld door media-adressen of door opdrachten " "ingebed in de afspeellijst kunnen wijzigingen aan de configuratie " "uitvoeren.\n" "Deze instelling is veiligheid-kritisch, omdat xine media-adressen of " "afspeellijsten van niet vertrouwde bronnen kan ontvangen. Als u toestaat dat " "deze veranderingen aan uw configuratie uitvoert, dan kunt u eindigen met " "complete puinhoop van een xine." #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "Tijdlimiet voor datastromen via netwerk (in secondes)" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" "Geeft de maximale tijdsduur voor het lezen van datastromen via het netwerk " "in secondes aan. Te kleine waarden kunnen de datastroom stoppen als de bron " "te langzaam is of de bandbreedte opgebruikt is. Te grote waarden kunnen xine " "laten bevriezen als de verbinding verbroken wordt." #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "Gebruik deze internet protocol-versie(s)" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" "\"auto\" gebruikt eenvoudig de opgevraagde naam.\n" "Anders biedt IPv4 wellicht meer compatibiliteit en privacy." #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "Automatisch separate audio/video-bestanden samenvoegen" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" "Bij het openen van een audiobestand \"foo_a.ext\", wordt geprobeerd het " "bijbehorende videobestand \"foo_v.ext\" te vinden of omgekeerd.\n" "Dit is voornamelijk een test voor \"side streams\"." #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "Meldingen" #: src/xine-engine/xine.c msgid "plugin" msgstr "plugin" #: src/xine-engine/xine.c msgid "trace" msgstr "trace" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Waarschuwing:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "Onbekende host:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Onbekend apparaat:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Netwerk onbereikbaar" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Verbinding geweigerd:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "Bestand niet gevonden:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Leesfout van:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Fout bij het laden van de bibliotheek:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Versleutelde mediastroom herkent" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Veiligheidsmelding:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Audio apparaat niet beschikbaar" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Fout in de toegangsrechten" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "Bestand is leeg:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "Authenticatie is noodzakelijk" #: src/xine-engine/xine_interface.c msgid "Recording done:" msgstr "Opname is voltooid:" #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Snelheidsvergelijking van de memcpy-methoden (kleiner is better):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "Xines methode voor het kopiëren van geheugen" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" "Het kopiëren van grote stukken geheugen is een van de langzaamste " "bewerkingen in de huidige computers. Daarom heeft xine diverse " "geoptimaliseerde methoden voor dit kopiëren, waarvan normaal gesproken " "automatisch de beste methode gekozen wordt." xine-lib-1.2/po/fr.po0000644000175000017500000064503114647725152012262 0ustar meme# translation of fr.po to français # Daniel Caujolle-Bert , 2001. # Christophe Giraud , 2007, 2008. # Xavier Bachelot , 2013. # French xine-lib.po file. # Copyright (C) 2002, 2007, 2008 Free Software Foundation, Inc. msgid "" msgstr "" "Project-Id-Version: xine-lib 1.1.9\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2014-03-11 23:17+0100\n" "Last-Translator: Xavier Bachelot \n" "Language-Team: french \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" "X-Generator: Poedit 1.5.4\n" #: lib/hstrerror.c msgid "No error" msgstr "Aucune erreur" #: lib/hstrerror.c msgid "Unknown host" msgstr "Hôte inconnu" #: lib/hstrerror.c msgid "No address associated with name" msgstr "Aucune adresse associée à ce nom" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Erreur du serveur inconnue" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "La recherche du nom d'hôte a échouée" #: lib/hstrerror.c msgid "Unknown error" msgstr "Erreur inconnue" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "dvaudio: augmentation du buffer à %d pour éviter sa saturation.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/audio_dec/gsm610.c #, fuzzy msgid "GSM 6.10 audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "A L'AIDE ! un pilote audio seulement mono ?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "plugin de décodage audio a52 basé sur liba52" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "Volume A/52" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() a échoué.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 a échoué.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit a échoué.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "Décodeur Freeware Advanced Audio" #: src/audio_dec/xine_faad_decoder.c #, fuzzy msgid "FAAD audio gain (dB)" msgstr "Gain audio FFmpeg (dB)" #: src/audio_dec/xine_faad_decoder.c #, fuzzy msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" "Certaines pistes AAC et WMA sont encodées trop fort et sont donc jouées " "distordues.\n" "Cela ne peut être réparé par le contrôle du volume, mais par ce réglage." #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/audio_dec/xine_mad_decoder.c #, fuzzy msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "plugin de décodage audio a52 basé sur liba52" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "libmusepack: mpc_demux_init a échoué.\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: mpc_streaminfo_read a échoué: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: données après la dernière trame ignorées\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: mpc_decoder_initialise a échoué\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: mpc_decoder_decode a échoué : %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "mpc: plugin de décodage audio musepack" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out: Déjà ouvert...POURQUOI!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() de %s a echoué: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>> Vérifiez si un autre programme utilise déjà PCM <<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: Mauvaise configuration pour ce PCM: aucune configuration " "disponible: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "Notifie les changements au mixeur matériel" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "A chaque modification du mixeur matériel, votre application recevra une " "notification afin qu'elle puisse automatiquement mettre à jour sa " "représentation graphique du mixeur." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : les modes supportés sont" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (sortie 4 canaux non activée dans la configuration de xine)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " sortie 4.1 canaux" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (sortie 4.1 canaux non activée dans la configuration de xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " Sortie 5 canaux" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (Sortie 5 canaux non activée dans la configuration de xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (Sortie 5.1 canaux non activée dans la configuration de xine)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (a/52 et DTS pass-through non activés dans la configuration de xine)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() a échoué:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Vérifiez si un autre programme utilise déjà PCM <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "La carte son peut utiliser mmap" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Activez ceci si votre carte son et votre pilote alsa supportent memory " "mapped IO.\n" "Essayez de l'activer et contrôlez que tout fonctionne correctement.Si c'est " "le cas,cela augmentera les performances ." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "périphérique utilisé pour la sortie mono" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilisera ce périphérique alsa pour la sortie son mono.\n" "Voir la documentation alsa pour toutes informations complémentaires sur les " "périphériques alsa." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " stéréo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "périphérique utilisé pour la sortie stéréo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilisera ce périphérique alsa pour la sortie son stéréo.\n" "Voir la documentation alsa pour toutes informations complémentaires sur les " "périphériques alsa" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-canaux" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "périphérique utilisé pour la sortie 4 canaux" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilisera ce périphérique alsa pour la sortie son 4 canaux ( 4.0 ) " "surround.\n" "Voir la documentation alsa pour toutes informations complémentaires sur les " "périphériques alsa." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " Sortie 5.1 canaux" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "périphérique utilisé pour la sortie 5.1 canaux" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilisera ce périphérique alsa pour la sortie son 5 canaux plus LFE " "(5.1) surround.\n" "Voir la documentation alsa pour toutes informations complémentaires sur les " "périphériques alsa." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " a/52 et DTS pass-through" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " a/52 et DTS pass-through" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilisera ce périphérique alsa pour une sortie son numérique surround " "non décodée. Celle-ci peut être utilisée par un décodeur surround externe.\n" "Voir la documentation alsa pour toutes informations complémentaires sur les " "périphériques alsa." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() a échoué: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "périphérique du mixeur alsa" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine utilisera ce périphérique du mixeur alsa pour changer le volume.\n" "Voir la documentation alsa pour toutes informations complémentaires sur les " "périphériques alsa." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" "plugin de sortie audio xine utilisant les pilotes/périphériques compatible " "alsa " #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "plugin de sortie audio xine pour Coreaudio/Mac OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Erreur" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "succès" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "accès interdit" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "la ressource est déjà en cours d'utilisation" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "L'objet était déjà initialisé" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "Le format wave spécifié n'est pas supporté" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "le tampon mémoire a été perdu et doit être restauré" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "Le contrôle du buffer requis n'est pas disponible" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "Erreur interne indéterminée du sous-système DirectSound" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "Le périphérique matériel DirectSound est indisponible" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "La fonction n'est pas valide pour l'état actuel de l'objet" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "Un paramètre invalide a été passé" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "L'objet ne supporte pas l'agrégation" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "pas de pilote son disponible" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "L'interface COM requise n'est pas disponible" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "une autre application a un niveau de priorité plus élevé" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "mémoire insuffisante" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "Niveau de priorité bas pour cette fonction" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound n'était pas initialisé" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "cette fonction n'est pas supportée" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "erreur inconnue" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Impossible de créer l'objet direct sound." #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "Impossible de régler le niveau coopératif direct sound." #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "Impossible de créer un second tampon pour direct sound" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "Impossible de jouer le tampon audio" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "Impossible de stopper le tampon audio" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "Impossible d'obtenir la position du tampon" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "Impossible d'ajuster la position du tampon" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "Impossible de régler le volume sonore" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": tampon perdu, tentative de restauration\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "Impossible de verrouiller le buffer de direct sound" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "Impossible de déverrouiller le buffer de direct sound" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Impossible de créer le tampon direct sound primaire." #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": ne peut pas créer le pthread du buffer: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": ne peut pas détruire le pthread du buffer: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ":ne peut pas détruire la condition pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": ne peut pas détruire pthread mutex: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr ": commande inconnu %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": ne peux pas créer la condition pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": ne peut pas créer pthread mutex: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "second plugin de sortie audio xine utilisant directx" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "plugin de sortie audio xine pour win32 utilisant directx" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: connexion au serveur ESD en cours %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: connexion au serveur esd en cours...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: ne peut pas se connecter au %s serveur ESD: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "Temps de latence de la sortie audio esd (ajustement de a/v sync) " #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Si vous rencontrez des problèmes de synchronisation du son par rapport à la " "vidéo, vous pouvez entrer une valeur de décalage fixe pour compenser.\n" "L'unité de valeur est un PTS tick, ce qui représente 1/90000 de seconde." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "plugin de sortie audio xine utilisant esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "plugin de sortie audio xine utilisant un fichier " #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "plugin de sortie audio xine utilisant un fichier " #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "longueur maximale de l'écart pour la sortie audio irixal" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Vous pouvez spécifié l'écart maximum entre le son et l'image que xine " "tolérera avant d'essayer de les re-synchroniser.\n" "L'unité de cette valeur est un PTS tick, qui correspond a 1/90000 éme d'une " "seconde." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "plugin de sortie audio xine utilisant IRIX libaudio" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "Nom du périphérique audio JACK" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" "Spécifie le nom du péripherique audio jack, laissez vide pour le port de " "sortie physique par défaut." #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "plugin de sortie audio xine pour JACK Audio Connection Kit" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "plugin de sortie audio xine utilisant dummy" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Ouverture du périphérique audio %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: Attention: un taux d'échantillonage de %d Hz n'est pas " "supporté , essayez 44100 Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" "audio_oss_out: échantillonage audio demandé %d, %d fourni par le " "périphérique\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "Nom du périphérique audio OSS" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Choisissez \"auto\" si vous voulez que xine détecte automatiquement le " "réglage adéquat." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "Numéro de périphérique audio OSS, -1 pour aucun" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Le nom complet du périphérique audio est obtenu en concaténant le nom du du " "périphérique audio OSS et le numéro du périphérique audio.\n" "Si vous n'avez pas besoin d'un numéro parce que le défaut du système vous " "convient, réglez ce paramétre à -1.\n" "Cette valeur peut être -1, ou de 1 à 15. Ce réglage est ignoré quand le nom " "du périphérique OSS est réglé à \"auto\"." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" "audio_oss_out: audio.device.oss_device_name = auto, test des périphériques\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Echec du test automatique des périphériques audio\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: utilise le périphérique >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: l'ouverture du périphérique audio %s a échouée:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "méthode A/V sync à utiliser par OSS" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "xine peut utiliser différentes méthodes pour garder le son et l'image en " "synchronisation. Le réglage qui fonctionnera le mieux dépend du pilote OSS " "et de la carte audio que vous utilisez. Si vous expérimentez des problèmes " "de synchronisation, essayez les différentes méthodes.\n" "\n" "La signification des valeurs est la suivante :\n" "\n" "auto\n" "xine essaie de détecter automatiquement le meilleur réglage\n" "\n" "getodelay\n" "utilise l'ioctl SNDCTL_DSP_GETODELAY pour obtenir une vraie synchronisation " "son/image si le pilote prétend ne pas supporter la lecture temps réel\n" "\n" "getoptr\n" "utilises l'ioctl SNDCTL_DSP_GETOPTR pour obtenir une vraie synchronisation " "son/image même si le pilote supporte l'ioctl SNDCTL_DSP_GETODELAYl\n" "\n" "softsync\n" "utilise la synchronisation avec l'horloge système; le son et l'image peuvent " "être fortement désynchronisés si l'horloge système ne correspond pas " "précisément a la vitesse de lecture de votre carte son\n" "\n" "probebuffer\n" "teste la taille de tampon de la carte son a l'initialisation pour calculer " "la latence pour la synchronisation a/v; essayer ce réglage si votre système " "ne supporte aucun des ioctls temps réel et que vous expérimentez des erreurs " "de synchronisation après une longue lecture" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Synchronisation en temps réel du pilote audio désactivée...\n" "audio_oss_out: ...utilisation de l'horloge temps réel du système pour la " "synchronisation\n" "audio_oss_out: ...il pourrait y avoir des problèmes de synchronisation audio/" "vidéo\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "Temps de latence de la sortie audio OSS (ajustement de a/v sync) " #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Synchronisation temps réel du pilote audio désactivée...\n" "audio_oss_out: ...teste de la taille du tampon de sortie : %d octets\n" "audio_oss_out: ...il pourrait y avoir des problèmes de synchronisation audio/" "vidéo\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out : les modes supportés sont" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " a/52 pass-through" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (a/52 pass-through non activé dans la configuration de xine)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "" "Le nom complet du périphérique de mixage est créé en prenant le nom du " "périphérique OSS, en substituant \"dsp\" par \"mixer\" et en ajoutant le " "numéro du mixer.\n" "Si vous n'avez pas besoin d'un nombre parce que le périphérique de mixage " "par défaut du système vous convient, mettez ce réglage à -1.\n" "Cette valeur doit être soit -1, soit comprise entre 0 et 15. Ce réglage est " "ignoré quand le nom du périphérique audio OSS est réglé à \"auto\"." #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Le nom complet du périphérique de mixage est créé en prenant le nom du " "périphérique OSS, en substituant \"dsp\" par \"mixer\" et en ajoutant le " "numéro du mixer.\n" "Si vous n'avez pas besoin d'un nombre parce que le périphérique de mixage " "par défaut du système vous convient, mettez ce réglage à -1.\n" "Cette valeur doit être soit -1, soit comprise entre 0 et 15. Ce réglage est " "ignoré quand le nom du périphérique audio OSS est réglé à \"auto\"." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: l'ouverture() du mixeur %s a échouée: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" "plugin de sortie audio xine utilisant les pilotes/périphériques audio " "compatible oss" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "périphérique utilisé pour pulseaudio" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " a/52 pass-through" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "plugin de sortie audio xine utilisant le serveur de son pulseaudio" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" "plugin de sortie audio xine utilisant les pilotes/périphériques compatible " "sun" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: l'ouverture du périphérique audio %s a échouée : %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "Nom du périphérique audio Sun" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Spécifie le nom de fichier pour le périphérique audio Sun à utiliser.\n" "Ce réglage est critique pour la sécurité, car si changé pour un autre " "fichier, xine pourrait être utilisé pour remplir ce fichier avec un contenu " "arbitraire. Vous devez faire attention à ce que la valeur que vous entrez " "est bien un périphérique audio Sun." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "audio_sun_out: audio ioctl sur le périphérique %s a échoué: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" "plugin de sortie audio xine utilisant les pilotes/périphériques compatible " "sun" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "Arrangement des haut-parleurs" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Choisissez parmi les choix suivants selon les haut-parleurs à votre " "disposition , Cela déterminera quels haut-parleurs xine utilisera pour la " "sortie son. Les valeurs individuelles sont:\n" "\n" "Mono 1.0: Vous avez seulement un haut-parleur.\n" "Stereo 2.0: Vous avez deux haut-parleurs , un pour le canal gauche et un " "pour le canal droit\n" "Headphones 2.0: Vous utilisez un casque audio.\n" "Stereo 2.1: Vous avez deux haut-parleurs: 1 gauche et 1 droit, plus un " "subwoofer pour les basses fréquences.\n" "Surround 3.0: Vous avez trois haut-parleurs : 1 avant gauche et 1 avant " "droit, plus un arrière.\n" "Surround 4.0: Vous avez quatre haut-parleurs : 1 avant gauche , 1 avant " "droit, 1 arrière gauche et 1 arrière droit.\n" "Surround 4.1: Vous avez quatre haut-parleurs : 1 avant gauche, 1 avant " "droit, 1 arrière gauche et 1 arrière droit, plus un subwoofer pour les " "basses fréquences.\n" "Surround 5.0: Vous avez cinq haut-parleurs : 1 avant gauche, 1 avant droit, " "1 voie centrale, 1 arrière gauche et 1 arrière droit.\n" "Surround 5.1: Vous avez cinq haut-parleurs : 1 avant gauche, 1 avant droit, " "1 voie centrale, 1 arrière gauche et 1 arrière droit, plus un subwoofer pour " "les basses fréquences .\n" "Surround 6.0: Vous avez six haut-parleurs : 1 avant gauche, 1 avant droit, 1 " "voie centrale avant, 1 arrière gauche, 1 arrière droit et 1 voie centrale " "arrière.\n" "Surround 6.1: Vous avez six haut-parleurs : 1 avant gauche, 1 avant droit, 1 " "voie centrale avant, 1 arrière gauche, 1 arrière droit et 1 voie centrale " "arrière, plus un subwoofer pour les basses fréquences.\n" "Surround 7.1: Vous avez sept haut-parleurs : 1 avant gauche, 1 avant droit, " "1 voie centrale avant droite et 1 avant gauche, 1 arrière gauche et 1 " "arrière droit, plus un subwoofer pour les basses fréquences.\n" "Pass Through: Votre système de son recevra un signal numérique non décodé " "provenant de xine .Vous aurez besoin de connecter un décodeur numérique " "surround capable de traiter le signal envoyé par votre carte son. " #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "plugin d'entrée fichier" #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat demux plugin" msgstr "plugin de démultiplexage OGG" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_audio_dec: augmentation du buffer à %d pour éviter sa saturation.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_audio_dec: impossible de trouver un decoder ffmpeg pour un tampon de " "type 0x%X\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: essai d'ouverture du codec null\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: impossible d'ouvrir le décodeur\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "ffmpeg_audio_dec: les parmétres du codec ont changés\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" "ffmpeg_audio_dec: impossible de lire les paramétres du codecs depuis le " "paquet\n" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "plugin de décodage audio basé sur ffmpeg" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "Gain audio FFmpeg (dB)" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" "Certaines pistes AAC et WMA sont encodées trop fort et sont donc jouées " "distordues.\n" "Cela ne peut être réparé par le contrôle du volume, mais par ce réglage." #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" "ffmpeg_video_dec: dimensions de trame non-supportées, DRI1 désactivé.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: format de trame non-supporté, DRI1 désactivé.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: rendu direct activé\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "ffmpeg_video_dec: format de trame non-supporté, DRI1 désactivé.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "ffmpeg_video_dec: force AVDISCARD_DEFAULT pour VAAPI\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: impossible d'ouvrir le décodeur\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: impossible d'ouvrir le décodeur (2éme passe)\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_video_dec: augmentation du buffer à %d pour éviter sa saturation.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: format de trame non-supporté, DRI1 désactivé.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_video_dec: impossible de trouver un decoder ffmpeg pour un tampon de " "type 0x%X\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "ffmpeg_video_dec: VAAPI activé dans la configuration.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "ffmpeg_video_dec: VAAPI activé mais désactivé par le pilote.\n" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "plugin de décodage vidéo basé sur ffmpeg" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "Qualité du post-traitement MPEG-4" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "Vous pouvez ajuster le niveau de post-traitement a appliqué au vidéo MPEG-" "4.\n" "De hautes valeurs donnent une meilleure qualité d'image mais sollicite " "davantage le processeur.De faibles valeurs peuvent provoquer une dégradation " "de l'image comme par exemple l'apparition d'artefacts. Dans le cas d'une " "vidéo de haute qualité, un post-traitement trop important peut actuellement " "dégrader l'image en la rendant plus floue . " #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "Nombre de processus de décodage vidéo FFmpeg" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Vous pouvez ajuster le nombre de processus de décodage vidéo que FFmpeg peut " "utiliser.\n" "De grandes valeurs devraient accélerer le décodage si le codec supporte le " "décodage en paralléle. La régle est d'avoir un processus de décodage par CPU " "logique (typiquement de 1 à 4).\n" "Un changement de ce réglage sera pris en compte lors de la lecture du " "prochain flux." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "Préférer la vitesse au respect des spécifications" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Vous pouvez souhaiter autoriser des astuces pour améliorer la vitesse qui " "violent la spécification du codec.\n" "Tricher peut permettre d'accélérer le décodage mais peut engendrer des " "artefacts de décodage.\n" "Un changement de ce réglage sera pris un compte lors de la lecture du flux " "suivant." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "Activation du rendu direct" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" "Désactivez le rendu direct si vous expérimentez des blocages avec\n" "des flux qui contiennent beaucoup de trames de références." #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "Décodage VAAPI Mpeg2 logiciel" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" "Si la machine bloque sur le décodage mpeg2, utiliser le décodage mpeg2 " "logiciel." #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "Active VAAPI" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "Active ou désactive l'utilisation de vaapi" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "plugin d'entré radio v4l" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/combined/flac_demuxer.c #, fuzzy msgid "FLAC demux plugin" msgstr "plugin de démultiplexage ASF" #: src/combined/nsf_decoder.c #, fuzzy msgid "NES Music audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/combined/nsf_demuxer.c #, fuzzy msgid "NES Music file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/combined/wavpack_decoder.c #, fuzzy msgid "wavpack audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/combined/wavpack_demuxer.c #, fuzzy msgid "Wavpack demux plugin" msgstr "Plugin de démultiplexage Musepack" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: piste audio vorbis indiquée mais aucune entête de flux vorbis n'a été " "trouvée.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "plugin de démultiplexage annodex" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "plugin de démultiplexage OGG" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/combined/xine_theora_decoder.c #, fuzzy msgid "theora video decoder plugin" msgstr "plugin de décodage vidéo basé sur ffmpeg" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: augmentation du buffer à %d pour éviter sa saturation.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "plugin de décodage audio vorbis" #: src/demuxers/demux_4xm.c #, fuzzy msgid "4X Technologies (4xm) demux plugin" msgstr "plugin de démultiplexage annodex" #: src/demuxers/demux_aac.c #, fuzzy msgid "ADIF/ADTS AAC demux plugin" msgstr "plugin de démultiplexage ASF" #: src/demuxers/demux_ac3.c #, fuzzy msgid "Raw AC3 demux plugin" msgstr "plugin de démultiplexage ASF" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "Plugin de démultiplexage IFF" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "demux_asf: attention : Un flux semble manquant.\n" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "Flux média manquant ?" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: attention: Le flux id=%d est crypté.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Flux média brouillé/crypté" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "plugin de démultiplexage ASF" #: src/demuxers/demux_aud.c #, fuzzy msgid "Westwood Studios AUD file demux plugin" msgstr "plugin de démultiplexage de fichier SND/AU" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Restauration de l'index..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" "demux_avi: segment avi invalide \"%c%c%c%c\" a la position %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: l'index avi est corrompu\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "plugin de démultiplexage AVI/RIFF" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "Plugin de démultiplexage True Audio" #: src/demuxers/demux_dts.c #, fuzzy msgid "Raw DTS demux plugin" msgstr "plugin de démultiplexage ASF" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c #, fuzzy msgid "Elementary MPEG stream demux plugin" msgstr "Plugin de démultiplexage Musepack" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "taille de segment FILM invalide\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "segment FILM inconnu\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "Plugin de démultiplexage FILM (CPK)" #: src/demuxers/demux_flac.c #, fuzzy msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_fli.c #, fuzzy msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "Plugin de démultiplexage True Audio" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, fuzzy, c-format msgid "unsupported FLV version (%d).\n" msgstr "version FLV non supportée (%d).\n" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "aucun flux audio ou vidéo n'est présent dans ce fichier.\n" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_idcin.c #, fuzzy msgid "Id Quake II Cinematic file demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: compression inconnue: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: compression inconnue: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: segment inconnu : %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "Plugin de démultiplexage IFF" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "plugin de démultiplexage mpeg pes" #: src/demuxers/demux_ipmovie.c #, fuzzy msgid "Interplay MVE Movie demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c #, fuzzy msgid "matroska & webm demux plugin" msgstr "plugin de démultiplexage mpeg pes" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c #, fuzzy msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: image trop grosse pour le tampon" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "Plugin de démultiplexage Musepack" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: stream_id 0x%02x non-reconnu. Merci de prévenir " "les développeurs de xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: erreur! Libération. Merci de reporter ce problème aux " "développeurs de xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: attention : les 10 bits réservés de l'entêtes PES n'ont " "pas été trouvés\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: attention: l'entête PES indique que ce flux peut être " "crypté (mode de cryptage %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "Plugin de démultiplexage DVD/VOB" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "Plugin de démultiplexage Musepack" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: stream_id 0x%02x non reconnu. Veuillez reporter " "ceci aux développeurs xine.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: attention: le décodage du flux PACK id=0x%x a échoué.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: attention : les 10 bits réservés de l'entêtes PES n'ont pas " "été trouvés\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: attention: l'entête PES indique que ce flux peut être " "crypté (mode de cryptage %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes:Flux privé non reconnu 1 0x%02x. Veuillez reporter ceci aux " "développeurs xine.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "plugin de démultiplexage mpeg pes" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "Plugin de démultiplexage True Audio" #: src/demuxers/demux_nsv.c #, fuzzy msgid "Nullsoft Video demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_playlist.c #, fuzzy msgid "Playlist demux plugin" msgstr "plugin de démultiplexage OGG" #: src/demuxers/demux_pva.c #, fuzzy msgid "TechnoTrend PVA demux plugin" msgstr "Plugin de démultiplexage True Audio" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "demux_qt: ajout de %d fragments\n" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "plugin de démultiplexage Apple Quicktime (MOV) et MPEG-4" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c #, fuzzy msgid "RealAudio file demux plugin" msgstr "Plugin de démultiplexage True Audio" #: src/demuxers/demux_real.c #, fuzzy msgid "RealMedia file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_shn.c #, fuzzy msgid "Shorten demux plugin" msgstr "plugin de démultiplexage ASF" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: mauvais paramètres d'entête\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: type audio non supporté: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "plugin de démultiplexage de fichier SND/AU" #: src/demuxers/demux_str.c #, fuzzy msgid "Sony Playstation STR file demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "demux_tta: nombre total de trames top grand\n" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "Plugin de démultiplexage True Audio" #: src/demuxers/demux_vc1es.c #, fuzzy msgid "VC1 elementary stream demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_vmd.c #, fuzzy msgid "Sierra VMD file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "bloc VOC de type inconnu (0x%02X); merci de reporter ce problème aux " "développeurs de xine\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "compression VOC de type inconnu (0x%02X); merci de reporter ce problème aux " "développeurs de xine\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_vox.c #, fuzzy msgid "Dialogic VOX file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_vqa.c #, fuzzy msgid "Westwood Studios VQA file demux plugin" msgstr "plugin de démultiplexage de fichier Flash Vidéo" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "Plugin de démultiplexage pour Wing Commander III Movie (MVE)" #: src/demuxers/demux_yuv4mpeg2.c #, fuzzy msgid "YUV4MPEG2 file demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/demuxers/demux_yuv_frames.c #, fuzzy msgid "YUV frames dummy demux plugin" msgstr "plugin de démultiplexage de fichier VOC" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" "plugin de décodage des sous-titres utilisant le décodage matériel des cartes " "dxr3" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Echec de l'ouverture du périphérique spu %s (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_spu: Echec de l'ouverture du périphérique spu %s (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "bouton demandé non disponible\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" "Plugin de décodage MPEGI/II utilisant les capacités de décodage matériel de " "la carte DXR3." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" "dxr3_decode_video: Echec de l'ouverture du périphérique de contrôle %s (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "utiliser les informations Pan & Scan" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Pan & Scan\" est un mode d'affichage spécial qui est parfois utilisé dans " "les contenus encodé en MPEG. Vous pouvez spécifié ici comment gérer ce type " "de contenu.\n" "\n" "only when forced\n" "Utiliser seulement Pan & Scan, quand le contenu que vous jouez le demande.\n" "\n" "use MPEG hint\n" "Activer Pan & Scan d'après les informations contenues dans le flux vidèo " "MPEG.\n" "\n" "use DVB hint\n" "Activé Pan & Scan en se basant sur les informations contenues dans les flux " "DVB. Ceci utilise l'Active Format Descriptor (AFD) utilisé par certains " "canaux DVB europééens.." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "Essayer de synchroniser la vidéo à chaque trame" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "utiliser un mode de lecture fluide" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Activé cette option utilisera un mode de lecture plus fluide." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "corriger la durée des trames dans les flux défectueux" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" "Active une heuristique de correction de la durée des trames de certains flux " "mpeg avec des mauvais codes de taux de rafraichissement. Actuellement une " "correction des flux NTSC marqués de manière erroné comme des flux PAL est " "implémentée. Activez seulement lorsque vous rencontrez de tels flux." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "" "dxr3_decode_video: L'ouverture du périphérique vidéo a echouée %s (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "Numéro de périphérique DXR3" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Si vous avez plus d'une carte DXR3 dans votre ordinateur, vous pouvez " "spécifier celle à utiliser ici." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: échec de l'initialisation de librte\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte supporte seulement des dimensions de vidéo qui sont " "des multiples de 16\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: échec de récupération du contexte rte.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: impossible de créer le codec.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: impossible d'initialiser le contexte : %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: ne peut pas démarrer l'encodage: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: Impossible de démarrer la bibliothèque FAME\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "qualité d'encodage mpeg de fame" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "La qualité d'encodage de la bibliothèque libfame. Un petit nombre est plus " "rapide mais donne des artefacts notables. Un grand nombre est meilleur mais " "plus lent." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "Priorité du plugin SCR" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "mode qualité constante" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "compression minimum" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "plugin de sortie vidéo qui affiche les images avec votre carte DXR3." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "" "video_out_dxr3: L'ouverture du périphérique de contrôle a échouée %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "Inverser les lignes paires et impaires" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "Ajouter des bandes noires pour corriger le ratio de l'aspect" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Ajoute des bandes noires quand l'image a un format que la carte ne peut pas " "gérer nativement. Ceci est nécessaire pour maintenir les proportions de " "l'image." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "" "utilisez un mode de lecture fluide pour la lecture à travers l'encodeur mpeg" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Activer cette option utilisera un mode de lecture plus fluide pour les " "contenus non-MPEG." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: L'ouverture du périphérique vidéo a échouée %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "Encodeur pour le contenu non mpeg" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "Les contenus autres que MPEG doivent passer une étape additionnelle de ré-" "encodage car la dxr3 gére uniquement le MPEG.\n" "En fonction de ce qui est supporté par votre xine, ce réglage peut être " "\"fame\", \"rte\", \"libavcodec\" ou \"none\".\n" "L'encodeur \"libavcodec\" utilise le plugin ffmpeg qui est déjà inclus dans " "xine, donc vous n'avez besoin d'installer de bibliothèque additionnelle. " "libavcodec apporte une grande qualité avec une utilsation CPU basse. " "L'utilisation de \"libavcodec\" est donc fortement recommendée.\n" "\"fame\" et \"rte\" sont toujours présents, mais leur support est obsoléte, " "et ils peuvent ne pas fonctionner." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" "video_out_dxr3: L'initialisation de l'encodeur mpeg libavcodec a échoué.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: L'initialisation de l'encodeur mpeg rte a échoué.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: L'initialisation de l'encodeur mpeg fame a échoué.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Encodage mpeg désactivé.\n" "video_out_dxr3: Vous n'en avez pas besoin pour les vidéos mpeg comme les " "DVDs, mais\n" "video_out_dxr3: vous ne pourrez pas lire de contenu non-mpeg avec ce pilote " "de sortie vidéo.\n" "video_out_dxr3: Voir le fichier README.dxr3 pour la configuration d'un " "encodeur.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Pas d'encodeur mpeg compilé.\n" "video_out_dxr3: Vous n'en avez pas besoin pour les vidéos mpeg comme les " "DVDs, mais\n" "video_out_dxr3: vous ne pourrez pas lire de contenu non-mpeg avec ce pilote " "de sortie vidéo.\n" "video_out_dxr3: Voir le fichier README.dxr3 pour la configuration d'un " "encodeur.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Valeur RGB héxadécimale de la clé de couleur.\n" "Vous pouvez essayer différentes valeurs si vous expérimentez des fenêtres " "qui deviennent transparente lors de l'utilisation du mode overlay du DXR3." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "mode tv préféré" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Sélectionne le mode TV a utilisé par le DXR3. Les valeurs signifient :\n" "\n" "ntsc: NTSC à 60Hz\n" "pal: PAL à 50Hz\n" "pal60: PAL à 60Hz\n" "default: garder le réglage de la carte" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: le réglage du mode vidéo a échoué.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: Nécessite un encodeur mpeg pour jouer des vidéos non-mpeg " "sur la carte dxr3\n" "video_out_dxr3: Lisez le fichier README.dxr3 pour plus de détails.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "plugin d'entré BluRay" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "point de montage des BluRay" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "Point de montage par défaut des disques BluRay." #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "périphérique utilisé pour la lecture des BluRay" #: src/input/input_bluray.c #, fuzzy msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "Le chemin d'accès vers le périphérique, choisissez celui que vous souhaitez " "utiliser pour lire vos BluRay ." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "langue par défaut pour la lecture des BluRay" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" "xine essaye d'utiliser ce langage par défaut pour la lecture des BluRay. Si " "le BluRay le supporte, les menus et les pistes audio seront dans ce " "langage.\n" "La valeur doit être un code de langage ISO639-2 à 3 caractères." #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "code région du lecteur BluRay" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "La valeur doit être un code pays ISO3166-1 à 2 caractères." #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "code pays du lecteur BluRay (1=A, 2=B, 4=C)" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" "Ce régalage doit seulement être changé si votre BluRay saute vers un écran " "se plaignant d'un mauvais code de région. Cela n'a rien à voir avec le code " "de région du lecteur BluRay, c'est uniquement logiciel." #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "limite d'age pour le contrôle parental (1-99)" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" "Empêche la lecture des BluRay dont l'age de contrôle parental est supérieur " "à cette limite." #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "plugin d'entré BluRay (avec menus)" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: ne peut pas se connecter à %s:%d\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: serveur cddb '%s:%d' connecté avec succés.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "input_cdda: impossible de se connecter au serveur cddb '%s:%d' (%s).\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "CD Digital Audio (aka. CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "périphérique utilisé pour les cd audio" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "Le chemin d'accès vers le périphérique, généralement un lecteur CD ou DVD, " "choisissez celui que vous souhaitez utiliser pour lire vos CD audio." #: src/input/input_cdda.c msgid "query CDDB" msgstr "Interroger CDDB" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "Nom du serveur CDDB" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "Port du serveur CDDB " #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" "Le port du serveur utilisé pour récupérer les informations de titres et de " "pistes." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "ralentir le lecteur de disque à ce facteur de vitesse" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: tuner_set_channel a échoué\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "input_dvb: DVB GUI %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: ne peux pas ouvrir le périphérique dvb\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: recherche du canal %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: ne peut pas ouvrir le périhérique dvr '%s'\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "plugin d'entrée DVB (TV numérique)" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Se rappeller du dernier canal DVB regardé" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" "En lecture automatique, xine changera vers le canal indiqué dans media.dvb." "last_channel. " #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Dernier canal DVB regardé" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "Si activé, xine se souviendra de ce canal et changera vers lui." #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "Activation de l'interface graphique DVB" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Nombre de cartes dvb a utiliser." #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" "Laissez cette valeur à zéro sauf si vous avez vraiment plus de 1 carte dans " "votre système." #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "" "input_dvd: Erreur lors de la récupération du prochain bloc depuis le DVD (%" "s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Erreur à l'ouverture du périphérique DVD\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "Navigateur DVD" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "périphérique utilisé pour la lecture des DVD" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "Le chemin d'accès vers le périphérique, généralement un lecteur CD ou DVD, " "choisissez celui que vous souhaitez utiliser pour lire vos DVD ." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "méthode de décryptage CSS" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" "Sélectionne la méthode de décryptage que libdvdcss utilisera pour décoder " "les DVDs protégé contre la copie. Essayez les différentes méthodes si vous " "avez des problèmes à lire des DVDs cryptés." #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "la région que votre lecteur DVD prêtant être (de 1 à 8)" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "Ceci a besoin d'être changé uniquement si votre DVD affiche une page à " "propos d'un mauvais code de région. Cela n'a rien a voir avec le code de " "région inscrit dans les lecteurs DVD, ceci est purement logiciel." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "langue par défaut pour la lecture des DVD" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine essaye d'utiliser ce langage par défaut pour la lecture des DVDs. Si le " "DVD le supporte, les menus et les pistes audio seront dans ce langage.\n" "La valeur doit être un code de langage ISO639 à 2 caractères." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "Mode de lecture quand le titre/chapitre est spécifié" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Permission refusée: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Fichier non trouvé: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: Fichier vide: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "plugin d'entrée fichier" #: src/input/input_file.c msgid "file browsing start location" msgstr "emplacement de départ du navigateur de fichiers" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" "Le navigateur pour sélectionner le fichier à jouer démarrera à cet " "emplacement." #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "plugin d'entrée fichier" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "plugin d'entrée fichier" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "plugin d'entré gnome-vfs fourni avec xine" #: src/input/input_helper.c msgid "list hidden files" msgstr "lister les fichiers cachés" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" "Si activé, le navigateur qui vous permet de sélectionner les fichiers à " "jouer vous montrera également ceux qui sont cachés." #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "plugin d'entré de flux stdin" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s) a echoué: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: erreur de lecture %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Connexion au serveur HTTP..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: réponse http invalide\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: 3xx redirection: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: le status http n'est pas 2xx: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: longueur de contenu = % bytes\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: buffer épuisé après %d bytes." #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "plugin d'entré http" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "hôte du proxy HTTP" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "Le nom d'hôte pour le proxy HTTP." #: src/input/input_http.c msgid "HTTP proxy port" msgstr "port du proxy HTTP" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "Le numéro de port du proxy HTTP." #: src/input/input_http.c msgid "HTTP proxy username" msgstr "nom d'utilisateur du proxy HTTP" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "Le nom d'utilisateur du proxy HTTP." #: src/input/input_http.c msgid "HTTP proxy password" msgstr "mot de passe du proxy HTTP" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "Le mot de passe pour le proxy HTTP." #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Domaines pour lesquels le proxy HTTP est ignoré" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Une liste de noms de domaine séparés par des virgules pour lesquels le proxy " "est ignoré.\n" "Si un nom de domaine est préfixé par '=', alors il est traité comme un nom " "d'hôte seulement (concordance complète requise)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "plugin d'entré de flux mms" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "bande passante réseau" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "Spécifiez la bande passante de votre connexion internet ici. Cela sera " "utilisé lorsque les serveurs de flux offrent différentes versions avec des " "besoins en bande passante différents pour un même flux." #: src/input/input_mms.c msgid "MMS protocol" msgstr "Protocole MMS" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Sélectionne le protocole d'encapsulation de MMS.\n" "TCP est meilleur mais vous pouvez avoir besoin de HTTP derrière un pare-feu." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "plugin d'entré de flux stdin" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "plugin d'entré réseau fournis avec xine" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "plugin d'entrée fichier" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "plugin d'entrée fichier" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "plugin d'entré de flux stdin" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "plugin d'entré pour les flux pnm" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: erreur à la création du fichier pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: erreur à l'ouverture du fichier pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: erreur de lecture (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: erreur à l'ouverture du périphérique %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" "input_pvr: IVTV_IOC_G_CODEC a échoué, peut-être que l' API a changé ?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" "input_pvr: IVTV_IOC_S_CODEC a échoué, peut-être que l' API a changé ?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "plugin d'entré WinTV-PVR 250/350" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "périphérique utilisé pour WinTV-PVR 250/350 (pvr plugin)" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "Le chemin d'accès vers le périphérique de votre carte WinTV." #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "xine_socket_cloexec(): %s.\n" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "L'adresse IP spécifiée est multicast\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Impossible de trouvé l'adresse pour l'interface %s:%s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) a échoué (noyau multicast ?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "incapable de resoudre '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "incapable de se connecter à '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: arrêt du processus de lecture...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: processus de lecture arrété\n" #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Ouverture de >nom de ficier:%s port:%d interface:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: ne peux pas créer le nouveau thread (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "plugin d'entré RTP et UDP fournis avec xine" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "plugin d'entré de flux rtsp" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "plugin d'entrée CIFS/SMB basé sur libsmbclient" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "plugin d'entrée fichier" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "plugin d'entrée fichier" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: impossible d'ouvrir '%s'\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "plugin d'entré de flux stdin" #: src/input/input_test.c msgid "Colour Circle" msgstr "Circle des couleurs" #: src/input/input_test.c msgid "RGB Levels" msgstr "Niveaux RGB" #: src/input/input_test.c msgid "Saturation Levels" msgstr "Niveaux de saturation" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "Résolution de la luminance" #: src/input/input_test.c msgid "test card input plugin" msgstr "plugin d'entré pour test de carte" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "plugin d'entré tv V4l" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Tampon sous-rempli..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Dépassement de tampon..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Ajustement..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Tuner non trouvé\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "plugin d'entré tv V4l" #: src/input/input_v4l.c msgid "v4l video device" msgstr "périphérique vidéo v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Le chemin d'accès vers votre périphérique vidéo Video4Linux" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "périphérique d'entrée audio v4l ALSA" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "Le chemin d'accès vers votre périphérique vidéo Video4Linux" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "standard TV pour v4l" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" "Selectionne le standard TV pour les signaux d'entré. Soit : AUTO, PAL, NTSC " "ou SECAM. " #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "plugin d'entré radio v4l" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "périphérique radio v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Le chemin d'accès vers votre périphérique radio Video4Linux" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: MRL mal formée. Utilisez vcdo:/\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: piste %d invalide (limites correctes: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "incapable d'ouvrir %s: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: incapable d'ouvrir %s: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "plugin d'entré Video CD" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "périphérique utilisé pour la lecture des VCD" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" "Le chemin d'accès vers le périphérique, généralement un lecteur CD ou DVD, " "choisissez celui que vous souhaitez utiliser pour lire vos VideoCD ." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: mauvaise mrl: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: impossible de se connecter à '%s'\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: impossible de se connecter au serveur %s\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: la session ne peut pas être établie.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "rtsp_session: la session ne peut pas être établie.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" "rtsp_session: ce type de serveur rtsp '%s' n'est pas encore supporté. " "Désolé.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" "input_dvd: Le périphérique %s a échoué à l'ouverture lors de l’éjection\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Connexion au serveur MMS (over tcp)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: erreur d'envoi\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: mauvais format de réponse\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: 3xx redirection non effectuée: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: le status http n'est pas 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: La redirection d'emplacement n'est pas implémentée\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Connection au serveur MMS (au dessus de http)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "url invalide\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "protocol non supporté\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "mode tv préféré" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "mode tv préféré" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: message reçu du serveur pendant la lecture du flux :\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: impossible de se connecter '%s'\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: échec de la mise en place du flux\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR non implémenté pour un écart différent de zéro" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END n'est pas encore implémenté." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "mauvais type d'objet" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "mauvais numéro d'entrée" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "mauvais numéro de segment" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Erreur de récupération du numéro de segment courant" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "impossible de trouvé un périphérique avec un VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "passage d'un paramètre de classe null" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Type d'entrée courante invalide" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "la sélection n'a aucune entrée RETURN" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "DEFAULT selectionné, mais PBC n'est pas activé." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "la sélection n'a aucune entrée NEXT" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "la sélection n'a aucune entrée PREVIOUS" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "type d'évènement inconnu:" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "Type VCD par défaut pour la lecture automatique" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "Lecteur de CD utilisé pour les VCD lorsque aucun n'est spécifié" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Quoi utilisé si aucun lecteur n'est spécifié. Si le réglage est vide, xine " "cherchera les lecteurs de CD." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "montre les VCD LIDs 'rejetés'" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "chemin d'accès vers les codecs RealPlayer" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "Si RealPlayer est installé, spécifiez le chemin vers le répertoire des " "codecs ici. Vous pouvez facilement trouver le répertoire des codes en " "cherchant un fichier nommé \"drvc.so\" à l'intérieur. Si xine peut trouver " "les codecs RealPlayer, il les utilisera pour décoder les contenus. Consultez " "la FAQ de xine pour plus d'informations sur comment installer les codecs." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "" "libareal: (audio) Impossible de résoudre les symboles - dll incompatible : %" "s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" "libareal: échec de l'initialisation du décodeur, code d'erreur : 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: oups, real peut utiliser plus de 2 canaux ?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "plugin de décodage audio basé sur les codecs binaires real" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" "libreal: Erreur lors de la résolution des symboles ! (version " "incompatible ?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "plugin de décodage vidéo basé sur les codecs binaires real" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "chemin vers les codecs Win32" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "La compression maximum à appliquer à une image en mode de qualité constante." #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "plugin de décodage audio dv" #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime binary-only codec based video decoder plugin" msgstr "plugin de décodage vidéo basé sur les codecs binaires real" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ICOpen a échoué ! codec inconnu %08lx / mauvais paramètres ?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) a échoué : Erreur %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery a échoué : Erreur %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin a échoué : Erreur %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder a échoué ! codec inconnu %08lx / mauvais " "paramètres ?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder a échoué ! codec inconnu %08lx / mauvais " "paramètres ?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "" "w32codec: le décodeur n'a pas réussi à démarrer. Est-ce que '%s' est " "installé ?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Format audio inapproprié\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen erreur %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Erreur d'initialisation de DirectShow Audio\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Erreur d'initialisation de DMO Audio\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "plugin de codec vidéo win32 binaire" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "plugin de codec audio win32 binaire" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" "Vous pouvez ajuster le nombre de processus de décodage que FFmpeg peut " "utiliser.\n" "Une plus grande valeur devrait accélérer le décodage, mais cela du codec et " "de s'il supporte le décodage en parallèle. Une règle de base est d'avoir un " "processus de décodage par CPU logique (typiquement de 1 à 4).\n" "Un changement de ce réglage sera pris en compte lors de la lecture du " "prochain flux." #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": conversion de Mono à Stéréo.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": le périphérique audio n'a pas la capacité AO_CAP_MODE_STEREO.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "Convertie le Mono en Stéréo" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "Normaliser le volume" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "What a GOOM" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "images par seconde à générer" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Avec plus de trames par seconde, l'animation sera plus fluide et plus " "rapide, mais requiérera alors plus de puissance CPU." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "largeur d'image goom" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "La largeur en pixel de l'image a générer." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "hauteur d'image goom" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "La hauteur en pixel de l'image a générer." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "méthode de conversion des couleurs" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "Egaliseur vidéo logiciel" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "égaliseur vidéo logiciel" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" "Ajouter des bordures noires en haut et en bas de la vidéo pour étendre le " "ratio d'image à 4:3" #: src/post/planar/fill.c #, fuzzy msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" "Ajouter des bordures noires en haut et en bas de la vidéo pour étendre le " "ratio d'image à 4:3" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "Ajoute du bruit" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "fonte pour les sous-titres externes" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "Ecart vertical des sous-titres (relatif à la taille de l'image)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "plugin de décodage des sous-titres CMML" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "encodage des sous-titres" #: src/spu_dec/spu_decoder.c #, fuzzy msgid "DVD/VOB SPU decoder plugin" msgstr "Plugin de démultiplexage DVD/VOB" #: src/spu_dec/spudvb_decoder.c #, fuzzy msgid "DVB subtitle decoder plugin" msgstr "plugin de décodage des sous-titres CMML" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "durée d'affichage par défaut des sous-titres en secondes" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "plugin de décodage pour sous-titres externes" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "taille des sous-titres" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "Ecart vertical des sous-titres" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "police pour les sous-titres" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Une police du répertoire de polices de xine à utiliser pour le texte des " "sous-titres." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "encodage des sous-titres" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "plugin de démultiplexage sputext" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "%s: buffer_pool_alloc()a échoué !\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "%s: incapable de ouvrir '%s' (%s).\n" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "%s: incapable de lire '%s' (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "%s: échec de création de socket pour le port %d (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "%s: impossible de se connecter à port %d (%s).\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "%s: connection à vdr.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "%s: échec de la résolution du nom d'hôte '%s' (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: ne peux pas créer le nouveau thread (%s)\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "plugin d'affichage de périphérique VDR" #: src/vdr/post_vdr_audio.c #, fuzzy msgid "modifies every audio frame as requested by VDR" msgstr "modifie chaque trame tel que demandé par VDR" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "modifie chaque trame tel que demandé par VDR" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr ": osd: (%d, %d)-(%d, %d)@%lg\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c #, fuzzy msgid "gdk-pixbuf image video decoder plugin" msgstr "plugin de décodage vidéo des images JPEG" #: src/video_dec/image.c #, fuzzy msgid "image video decoder plugin" msgstr "plugin de décodage vidéo des images JPEG" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "plugin de décodage vidéo des images JPEG" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c #, fuzzy msgid "mpeg2 based video decoder plugin" msgstr "plugin de décodage vidéo basé sur ffmpeg" #: src/video_dec/libopenhevc.c #, fuzzy msgid "HEVC video decoder plugin" msgstr "plugin de décodage vidéo des images JPEG" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c #, fuzzy msgid "WebM (VP8/VP9) video decoder plugin" msgstr "plugin de décodage vidéo basé sur ffmpeg" #: src/video_dec/mmal.c #, fuzzy msgid "mmal-based HW video decoder plugin" msgstr "plugin de décodage vidéo basé sur ffmpeg" #: src/video_dec/rgb.c #, fuzzy msgid "Raw RGB video decoder plugin" msgstr "plugin de décodage vidéo des images JPEG" #: src/video_dec/yuv.c #, fuzzy msgid "Raw YUV video decoder plugin" msgstr "plugin de décodage vidéo des images JPEG" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "plugin de sortie video xine utilisant la bibliothèque AsCii Art" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "plugin de sortie video xine utilisant la bibliothèque Color AsCii Art" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "active la clé de couleur vidéo" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "plugin de sortie vidéo xine utilisant DirectFB." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "plugin de sortie vidéo xine utilisant DirectFB sous XDirectFB." #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "niveau d'accélération matériel" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "plugin de sortie vidéo xine pour win32 utilisant directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "Nom du périphérique framebuffer" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Votre mode vidéo n'a pas été reconnu, désolé :-(\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" "plugin de sortie video xine utilisant le périphérique framebuffer de linux" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "plugin de sortie vidéo xine utilisant DirectFB." #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "plugin de sortie video xine qui n'affiche rien" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "plugin de sortie vidéo xine utilisant OpenGL 2.0" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "active le double tampon" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "plugin de sortie vidéo xine utilisant l'API graphique 3D OpenGL" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Erreur: ioctl a échoué, mauvais périphérique (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" "plugin de sortie video de xine utilisant le périphérique framebuffer de Sun " "PGX32" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" "video_out_pgx64: Erreur: ne peut pas ouvrir le périphérique framebuffer '%" "s'\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Erreur: ioctl a échoué (VIS_GETIDENTIFIER), mauvais " "périphérique (%s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Erreur: '%s' n'est pas un périphérique framebuffer xvr100/" "pgx64/pgx24\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" "video_out_pgx64: Erreur: impossible de régler les propriétés de la fenêtre\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Attention : mémoire vidéo basse, tampons multiples " "désactivés\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Erreur: mémoire vidéo insuffisante\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Attention : mémoire vidéo basse, double tampon désactivé\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Erreur: ioctl a échoué (FBIOGATTR)\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "Activation des tampons multiples" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" "Les tampons multiples augmentent les performances au détriment de " "l'utilisation de la mémoire graphique." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" "plugin de sortie video de xine utilisant le périphérique framebuffer de Sun " "XVR100/PGX64/PGX24" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "utilise l'accélération matérielle si disponible" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "quand votre système le supporte, l'accélération matérielle fournie par votre " "carte graphique sera utilisée. Cela pourrait ne pas fonctionner, vous pouvez " "donc la désactiver si les choses ne se passaient pas bien." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" "sdl doit émuler les surfaces 16 bits, cela va entrainer un ralentissement.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: le mode plein écran n'est PAS supporté\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "plugin de sortie video xine utilisant Simple Direct Media Layer" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" "plugin de sortie video xine utilisant le toolkit Libstk Surface Set-top" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "nombre par défaut de trames vidéo" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI colour conversion method" msgstr "méthode de conversion des couleurs" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "plugin de sortie vidéo xine utilisant DirectFB." #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "longueur par défaut de la file d'affichage" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "plugin de sortie vidéo xine utilisant VDPAU." #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "intensité de rouge" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "L'intensité du composant de couleur rouge." #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "intensité de vert" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "L'intensité du composant de couleur verte." #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "intensité de bleu" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "L'intensité du composant de couleur bleue." #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: l'adaptateur supporte le format yuy2\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: l'adaptateur supporte le format yv12\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" "video_out_vidix: Vous avez une mauvaise version de la bibliothèque VIDIX\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "" "video_out_vidix: Impossible de trouver un pilote VIDIX qui fonctionne\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: utilisation du pilote : %s par %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "plugin de sortie vidéo xine utilisant libvidix pour x11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" "plugin de sortie vidéo xine utilisant libvidix pour le framebuffer linux" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "%s: %s: allocation de l'image\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" "%s: erreur de mémoire partagée (erreur d'adresse) lors de l'allocation de " "l'image\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "ATTENTION : la profondeur d'affichage courante est %d. Pour de meilleures " "performances\n" "une profondeur de 16 bpp est recommandée !\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: votre mode vidéo n'a pas été reconnu, désolé :-(\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" "plugin de sortie vidéo xine utilisant l'extension vidéo MIT X mémoire " "partagée" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "%s: XvShmCreateImage a retouné une taille de zéro\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "%s: erreur de mémoire partagée dans shmget: %s\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "%s: erreur de mémoire partagée (erreur d'adresse)\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: cet adaptateur supporte le format %s.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: extension Xv non disponible.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "%s: impossible d'ouvrir le port Xv %lu - autodétection\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: extension Xv disponible mais pas de port yuv12 utilisable.\n" "\tIl semblerait que le pilote de votre carte graphique ne supporte pas " "Xv ?!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "plugin de sortie video xine utilisant l'extension video MIT X" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "%s: erreur de mémoire partagée lors de l'allocation de l'image\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "%s: XvShmCreateImage a échoué\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: extension XvMC absente.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: l’extension Xv est présente mais aucun port yuv12 n'est " "utilisable.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " pas de support XvMC\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr "" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "plugin de sortie vidéo xine utilisant l'extension vidéo XvMC " #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Economie de CPU unichrome" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Utiliser bob comme méthode de désentrelacement accélérée.." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "Ne pas utiliser le désentrelacement bob pour les trames progressives." #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "" #: src/video_out/xv_common.h #, fuzzy msgid "autopaint colour key" msgstr "active la clé de couleur vidéo" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "Numéro du port Xv" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "sélectionne le numéro de port Xv à utiliser (0 pour autodétection)." #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" "Certains pilotes vidéo buggés ont besoin d'un workaround ( une solution de " "rechange/contournement ) pour fonctionner correctement." #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "filtrage bicubique" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: aucun plugin disponible pour gérer '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: erreur, tampon de type inconnu : %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "nombre de tampons audio" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: calcul du délai impossible avec un périphérique audio non-" "disponible\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "8 bits non supporté par le pilote, conversion vers 16 bits.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "stéréo non supporté par le pilote, conversion vers mono.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "méthode pour synchroniser le son et l'image" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "Activation du ré-échantillonage" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "toujours ré-échantillonner à ce taux (0 pour désactiver)" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "volume audio au démarrage" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Le volume audio général au démarrage de xine." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "restaurer le volume au démarrage" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "Si désactivé, xine ne modifiera aucun réglages du mixer au démarrage." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: désolé, cela ne devrait pas arriver. veuillez redémarrer xine.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "xine-lib: buffer.c: Il y a eu une erreur fatale : trop de FREE\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "%s: code vidéo FourCC inconnu %#x \"%s\"\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "%s: marque de format audio inconnue %#x \"%s\"\n" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "Le fichier de configuration courant a été modifié par une version de xine " "plus récente." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "Chargement de la configuration depuis le fichier '%s'\n" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "Echec du chargement de la configuration depuis le fichier '%s': %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: ATTENTION : votre configuration ne sera pas sauvegardée\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" "configfile: ATTENTION : l'écriture de la configuration dans %s a échouée\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: ATTENTION : suppresion du fichier de configuration " "potentiellement corrompu %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "" "configfile: ATTENTION : vous devriez vérifier le fichier de sauvegarde %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: l'entrée '%s' ne doit pas être modifiée depuis un MRL\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": la fonction open() ne devrait jamais être appelée\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": plugin d'entré non défini!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: la lecture des données sauvegardées a échouée: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: la recherche a échouée: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: la lecture par le plugin d'entré a echoué\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: la fonction open() ne devrait jamais être appelée\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: la recherche a échouée\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: le plugin d'entré n'est pas défini !\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: le répertoire cible n'était pas défini, merci de remplir l'option " "'media.capture.save_dir'\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "La capacité à sauvegarder un flux est désactivée tant que vous n'avez pas " "renseigné media.capture.save_dir dans la configuration." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine n'est pas autorisé à sauvegarder depuis cette source. (peut-être un " "contenu protéger pas des droits d'auteurs ?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: nom de fichier non donné !\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: erreur à l'ouverture du fichier %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: l'attente a été abandonée\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: l'attente a échouée : %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Permission refusée\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Fichier non trouvé\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Connexion refusée\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: type de plugin %d inconnu dans %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: unknown statically linked plugin type %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: le plugin %s est ignoré, mauvaise version d'interface %d (elle " "devrait être %d)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "load_plugins: limite de plugin atteinte, %s ne peut pas être chargé\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" "load_plugins: limite de plugin atteinte, le plugin statique ne peut pas être " "chargé\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "priorité du décodeur %s" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: le plugin de démultiplexage %s ne fournit pas de priorité, " "xine-lib utilisera la priorité par défaut.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: le plugin d'entré %s ne fournit pas de priorité, xine-lib " "utilisera la priorité par défaut.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: le plugin %s:%s a été trouvé\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: impossible d'ouvrir plugin lib %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Yikes! %s ne contient pas d'information de plugin.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "Impossible de créer l'repertoire %s: %s.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" "La priorité apporte un classement dans le cas où certains médias peuvent " "être gérés par plus d'un décodeur.\n" "Une priorité de 0 active la priorité par défaut du décodeur." #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: stratégie de détéction de contenu %d inconnue\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: utilise le demuxer '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: impossible de charger le plugin de sortie audio <%s>\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: ne peut pas décharger plugin lib %s:\n" "%s\n" #: src/xine-engine/metronom.c #, fuzzy msgid "basic video to audio delay in pts" msgstr "aucun flux audio ou vidéo n'est présent dans ce fichier.\n" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Remplissage du tampon..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: impossible d'initialiser la bibliothèque ft2\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: conversion non supportée %s -> %s, pas de conversion effectuée\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd; erreur de chargement du glyphe\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: erreur de rendu du glyphe\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: la fonte n'est pas définie\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: erreur de chargement du glyphe %i\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: erreur de rendu\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: pas de plugin disponible pour gérer '%s'\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: erreur, tampon de type inconnu : %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "nombre de tampons vidéo" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d trames livrées, %d trames passées, %d trames écartées\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "pourcentage de trames passées à tolérer" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "Pourcentage de trames écartées toléré" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out: désolé, ceci ne devrait pas arriver. Merci de redémarrer xine.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "position horizontale de l'image dans la fenêtre de sortie" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "position verticale de l'image dans la fenêtre de sortie" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: erreur de parcours du mrl\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: plugin d'entré trouvé : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: le plugin d'entré ne peut pas ouvrir la MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: impossible de trouver un plugin d'entrée pour le MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: le démultiplexeur spécifié %s n'a pas réussi a démarré\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: erreur à l'ouverture de l'instance du plugin d'entré rip\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: le dernier démultiplexeur testé %s a échoué à démarrer\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "vidéo ignoré\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "audio ignoré\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "mrl de sous-titres '%s' ouvert\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: erreur à l'ouverture des sous-titres de la mrl\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: changer l'option '%s' depuis le MRL n'est pas permis\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" "xine: impossible de charger le démultiplexeur spécifié par le plugin %s pour " ">%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: impossible de trouver un démultiplexeur pour >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine : trouvé plugin de démultiplexage %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine: le démultiplexeur a déjà fini. C'était rapide !\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: le démultiplexeur n'a pas réussi à démarrer\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: pas de démultiplexeur disponible\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: le démultiplexeur n'a pas réussi à démarrer\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" "xine: Le répertoire de sauvegarde spécifié \"%s\" pourrait constituer un " "risque de sécurité.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" "Le répertoire de sauvegarde spécifié pourrait constituer un risque de " "sécurité." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: locale non supportée par la bibliothèque C\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "stratégie de détection du format de média" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "répertoire pour sauvegarder les flux" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "messages" #: src/xine-engine/xine.c msgid "plugin" msgstr "plugin" #: src/xine-engine/xine.c msgid "trace" msgstr "trace" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Attention:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "Hôte inconnu:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Périphérique inconnu:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Réseau inaccessible" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Connexion refusée:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "Fichier non trouvé:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Erreur de lecture provenant de:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Erreur de chargement de la bibliothéque : " #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Flux média crypté détecté" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Message de sécurité:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Périphérique audio non disponible" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Erreur de permission" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "Le fichier est vide:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Restauration de l'index..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Test des méthodes de copie mémoire (un petit nombre est meilleur):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "méthode de copie mémoire utilisée par xine" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" "La copie de grands blocs de mémoire est une des opérations les plus " "couteuses sur un ordinateur moderne. En conséquence, xine fournit " "différentes méthodes optimisées pour faire cette copie. Habituellement, la " "meilleure méthode est détectée automatiquement." #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "" #~ "configfile: ATTENTION : la sauvegarde du fichier de configuration dans %s " #~ "a échouée\n" #, fuzzy #~ msgid "fooaudio: reference xine audio decoder plugin" #~ msgstr "plugin de décodage audio basé sur ffmpeg" #, fuzzy #~ msgid "foovideo: reference xine video decoder plugin" #~ msgstr "plugin de décodage vidéo basé sur ffmpeg" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: mauvaise mrl: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: erreur de lecture (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: impossible de résoudre '%s'.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: impossible de se connecter à '%s'.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "" #~ "stdin: impossible de revenir en arrière ! (% > %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: erreur lors du parcours du MRL\n" #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "Le message ci-dessus a un niveau de llog vcdimager inconnu" #~ msgid "load_plugins: static plugin %s found\n" #~ msgstr "load_plugins: plugin statique %s trouvé\n" xine-lib-1.2/po/Makevars.extra.in0000644000175000017500000000021114647725152014517 0ustar meme# Extra file just to get LIBNAME correctly. # Unfortunate but it's the only way to avoid changing po/Makefile.in.in LIBNAME = @LIBNAME@ xine-lib-1.2/po/Makefile.in.in0000644000175000017500000004042314647725152013757 0ustar meme# Makefile for PO directory in any package using GNU gettext. # Copyright (C) 1995-1997, 2000-2007, 2009-2010 by Ulrich Drepper # # This file can be copied and used freely without restrictions. It can # be used in projects which are not available under the GNU General Public # License but which still want to provide support for the GNU gettext # functionality. # Please note that the actual code of GNU gettext is covered by the GNU # General Public License and is *not* in the public domain. # # Origin: gettext-0.18.3 GETTEXT_MACRO_VERSION = 0.18 PACKAGE = @PACKAGE@ VERSION = @VERSION@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ SED = @SED@ SHELL = /bin/sh @SET_MAKE@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ datarootdir = @datarootdir@ datadir = @datadir@ localedir = @localedir@ gettextsrcdir = $(datadir)/gettext/po INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ # We use $(mkdir_p). # In automake <= 1.9.x, $(mkdir_p) is defined either as "mkdir -p --" or as # "$(mkinstalldirs)" or as "$(install_sh) -d". For these automake versions, # @install_sh@ does not start with $(SHELL), so we add it. # In automake >= 1.10, @mkdir_p@ is derived from ${MKDIR_P}, which is defined # either as "/path/to/mkdir -p" or ".../install-sh -c -d". For these automake # versions, $(mkinstalldirs) and $(install_sh) are unused. mkinstalldirs = $(SHELL) @install_sh@ -d install_sh = $(SHELL) @install_sh@ MKDIR_P = @MKDIR_P@ mkdir_p = @mkdir_p@ GMSGFMT_ = @GMSGFMT@ GMSGFMT_no = @GMSGFMT@ GMSGFMT_yes = @GMSGFMT_015@ GMSGFMT = $(GMSGFMT_$(USE_MSGCTXT)) MSGFMT_ = @MSGFMT@ MSGFMT_no = @MSGFMT@ MSGFMT_yes = @MSGFMT_015@ MSGFMT = $(MSGFMT_$(USE_MSGCTXT)) XGETTEXT_ = @XGETTEXT@ XGETTEXT_no = @XGETTEXT@ XGETTEXT_yes = @XGETTEXT_015@ XGETTEXT = $(XGETTEXT_$(USE_MSGCTXT)) MSGMERGE = msgmerge MSGMERGE_UPDATE = @MSGMERGE@ --update MSGINIT = msginit MSGCONV = msgconv MSGFILTER = msgfilter POFILES = @POFILES@ GMOFILES = @GMOFILES@ UPDATEPOFILES = @UPDATEPOFILES@ DUMMYPOFILES = @DUMMYPOFILES@ DISTFILES.common = Makefile.in.in remove-potcdate.sin \ $(DISTFILES.common.extra1) $(DISTFILES.common.extra2) $(DISTFILES.common.extra3) DISTFILES = $(DISTFILES.common) Makevars POTFILES.in \ $(POFILES) $(GMOFILES) \ $(DISTFILES.extra1) $(DISTFILES.extra2) $(DISTFILES.extra3) POTFILES = \ CATALOGS = @CATALOGS@ # Makevars gets inserted here. (Don't remove this line!) .SUFFIXES: .SUFFIXES: .po .gmo .mo .sed .sin .nop .po-create .po-update .po.mo: @echo "$(MSGFMT) -c -o $@ $<"; \ $(MSGFMT) -c -o t-$@ $< && mv t-$@ $@ .po.gmo: @lang=`echo $* | sed -e 's,.*/,,'`; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o $${lang}.gmo $${lang}.po"; \ cd $(srcdir) && rm -f $${lang}.gmo && $(GMSGFMT) -c --statistics --verbose -o t-$${lang}.gmo $${lang}.po && mv t-$${lang}.gmo $${lang}.gmo .sin.sed: sed -e '/^#/d' $< > t-$@ mv t-$@ $@ all: all-@USE_NLS@ all-yes: stamp-po all-no: # Ensure that the gettext macros and this Makefile.in.in are in sync. CHECK_MACRO_VERSION = \ test "$(GETTEXT_MACRO_VERSION)" = "@GETTEXT_MACRO_VERSION@" \ || { echo "*** error: gettext infrastructure mismatch: using a Makefile.in.in from gettext version $(GETTEXT_MACRO_VERSION) but the autoconf macros are from gettext version @GETTEXT_MACRO_VERSION@" 1>&2; \ exit 1; \ } # $(srcdir)/$(DOMAIN).pot is only created when needed. When xgettext finds no # internationalized messages, no $(srcdir)/$(DOMAIN).pot is created (because # we don't want to bother translators with empty POT files). We assume that # LINGUAS is empty in this case, i.e. $(POFILES) and $(GMOFILES) are empty. # In this case, stamp-po is a nop (i.e. a phony target). # stamp-po is a timestamp denoting the last time at which the CATALOGS have # been loosely updated. Its purpose is that when a developer or translator # checks out the package via CVS, and the $(DOMAIN).pot file is not in CVS, # "make" will update the $(DOMAIN).pot and the $(CATALOGS), but subsequent # invocations of "make" will do nothing. This timestamp would not be necessary # if updating the $(CATALOGS) would always touch them; however, the rule for # $(POFILES) has been designed to not touch files that don't need to be # changed. stamp-po: $(srcdir)/$(DOMAIN).pot @$(CHECK_MACRO_VERSION) test ! -f $(srcdir)/$(DOMAIN).pot || \ test -z "$(GMOFILES)" || $(MAKE) $(GMOFILES) @test ! -f $(srcdir)/$(DOMAIN).pot || { \ echo "touch stamp-po" && \ echo timestamp > stamp-poT && \ mv stamp-poT stamp-po; \ } # Note: Target 'all' must not depend on target '$(DOMAIN).pot-update', # otherwise packages like GCC can not be built if only parts of the source # have been downloaded. # This target rebuilds $(DOMAIN).pot; it is an expensive operation. # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. # The determination of whether the package xyz is a GNU one is based on the # heuristic whether some file in the top level directory mentions "GNU xyz". # If GNU 'find' is available, we avoid grepping through monster files. $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed if { if (LC_ALL=C find --version) 2>/dev/null | grep GNU >/dev/null; then \ LC_ALL=C find -L $(top_srcdir) -maxdepth 1 -type f -size -10000000c -exec grep 'GNU @PACKAGE@' /dev/null '{}' ';' 2>/dev/null; \ else \ LC_ALL=C grep 'GNU @PACKAGE@' $(top_srcdir)/* 2>/dev/null; \ fi; \ } | grep -v 'libtool:' >/dev/null; then \ package_gnu='GNU '; \ else \ package_gnu=''; \ fi; \ if test -n '$(MSGID_BUGS_ADDRESS)' || test '$(PACKAGE_BUGREPORT)' = '@'PACKAGE_BUGREPORT'@'; then \ msgid_bugs_address='$(MSGID_BUGS_ADDRESS)'; \ else \ msgid_bugs_address='$(PACKAGE_BUGREPORT)'; \ fi; \ case `$(XGETTEXT) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-5] | 0.1[0-5].* | 0.16 | 0.16.[0-1]*) \ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ --files-from=$(srcdir)/POTFILES.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --msgid-bugs-address="$$msgid_bugs_address" \ ;; \ *) \ $(XGETTEXT) --default-domain=$(DOMAIN) --directory=$(top_srcdir) \ --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) @XGETTEXT_EXTRA_OPTIONS@ \ --files-from=$(srcdir)/POTFILES.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ --package-name="$${package_gnu}@PACKAGE@" \ --package-version='@VERSION@' \ --msgid-bugs-address="$$msgid_bugs_address" \ ;; \ esac test ! -f $(DOMAIN).po || { \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ sed -f remove-potcdate.sed < $(DOMAIN).po > $(DOMAIN).2po && \ if cmp $(DOMAIN).1po $(DOMAIN).2po >/dev/null 2>&1; then \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(DOMAIN).po; \ else \ rm -f $(DOMAIN).1po $(DOMAIN).2po $(srcdir)/$(DOMAIN).pot && \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ else \ mv $(DOMAIN).po $(srcdir)/$(DOMAIN).pot; \ fi; \ } # This rule has no dependencies: we don't need to update $(DOMAIN).pot at # every "make" invocation, only create it when it is missing. # Only "make $(DOMAIN).pot-update" or "make dist" will force an update. $(srcdir)/$(DOMAIN).pot: $(MAKE) $(DOMAIN).pot-update # This target rebuilds a PO file if $(DOMAIN).pot has changed. # Note that a PO file is not touched if it doesn't need to be changed. $(POFILES): $(srcdir)/$(DOMAIN).pot @lang=`echo $@ | sed -e 's,.*/,,' -e 's/\.po$$//'`; \ if test -f "$(srcdir)/$${lang}.po"; then \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot"; \ cd $(srcdir) \ && { case `$(MSGMERGE_UPDATE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) $${lang}.po $(DOMAIN).pot;; \ *) \ $(MSGMERGE_UPDATE) $(MSGMERGE_OPTIONS) --lang=$${lang} $${lang}.po $(DOMAIN).pot;; \ esac; \ }; \ else \ $(MAKE) $${lang}.po-create; \ fi install: install-exec install-data install-exec: install-data: install-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ for file in $(DISTFILES.common) Makevars.template; do \ $(INSTALL_DATA) $(srcdir)/$$file \ $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ for file in Makevars; do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi install-data-no: all install-data-yes: all @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $(DESTDIR)$$dir; \ if test -r $$cat; then realcat=$$cat; else realcat=$(srcdir)/$$cat; fi; \ $(INSTALL_DATA) $$realcat $(DESTDIR)$$dir/$(DOMAIN).mo; \ echo "installing $$realcat as $(DESTDIR)$$dir/$(DOMAIN).mo"; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ ln -s ../LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ ln $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo 2>/dev/null || \ cp -p $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(DOMAIN).mo $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ echo "installing $$realcat link as $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo"; \ fi; \ done; \ done install-strip: install installdirs: installdirs-exec installdirs-data installdirs-exec: installdirs-data: installdirs-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ $(mkdir_p) $(DESTDIR)$(gettextsrcdir); \ else \ : ; \ fi installdirs-data-no: installdirs-data-yes: @catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ dir=$(localedir)/$$lang/LC_MESSAGES; \ $(mkdir_p) $(DESTDIR)$$dir; \ for lc in '' $(EXTRA_LOCALE_CATEGORIES); do \ if test -n "$$lc"; then \ if (cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc 2>/dev/null) | grep ' -> ' >/dev/null; then \ link=`cd $(DESTDIR)$(localedir)/$$lang && LC_ALL=C ls -l -d $$lc | sed -e 's/^.* -> //'`; \ mv $(DESTDIR)$(localedir)/$$lang/$$lc $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ (cd $(DESTDIR)$(localedir)/$$lang/$$lc.old && \ for file in *; do \ if test -f $$file; then \ ln -s ../$$link/$$file $(DESTDIR)$(localedir)/$$lang/$$lc/$$file; \ fi; \ done); \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc.old; \ else \ if test -d $(DESTDIR)$(localedir)/$$lang/$$lc; then \ :; \ else \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc; \ mkdir $(DESTDIR)$(localedir)/$$lang/$$lc; \ fi; \ fi; \ fi; \ done; \ done # Define this as empty until I found a useful application. installcheck: uninstall: uninstall-exec uninstall-data uninstall-exec: uninstall-data: uninstall-data-@USE_NLS@ if test "$(PACKAGE)" = "gettext-tools"; then \ for file in $(DISTFILES.common) Makevars.template; do \ rm -f $(DESTDIR)$(gettextsrcdir)/$$file; \ done; \ else \ : ; \ fi uninstall-data-no: uninstall-data-yes: catalogs='$(CATALOGS)'; \ for cat in $$catalogs; do \ cat=`basename $$cat`; \ lang=`echo $$cat | sed -e 's/\.gmo$$//'`; \ for lc in LC_MESSAGES $(EXTRA_LOCALE_CATEGORIES); do \ rm -f $(DESTDIR)$(localedir)/$$lang/$$lc/$(DOMAIN).mo; \ done; \ done check: all info dvi ps pdf html tags TAGS ctags CTAGS ID: mostlyclean: rm -f remove-potcdate.sed rm -f stamp-poT rm -f core core.* $(DOMAIN).po $(DOMAIN).1po $(DOMAIN).2po *.new.po rm -fr *.o clean: mostlyclean distclean: clean rm -f Makefile Makefile.in POTFILES *.mo maintainer-clean: distclean @echo "This command is intended for maintainers to use;" @echo "it deletes files that may require special tools to rebuild." rm -f stamp-po $(GMOFILES) distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) dist distdir: $(MAKE) update-po @$(MAKE) dist2 # This is a separate target because 'update-po' must be executed before. dist2: stamp-po $(DISTFILES) dists="$(DISTFILES)"; \ if test "$(PACKAGE)" = "gettext-tools"; then \ dists="$$dists Makevars.template"; \ fi; \ if test -f $(srcdir)/$(DOMAIN).pot; then \ dists="$$dists $(DOMAIN).pot stamp-po"; \ fi; \ if test -f $(srcdir)/ChangeLog; then \ dists="$$dists ChangeLog"; \ fi; \ for i in 0 1 2 3 4 5 6 7 8 9; do \ if test -f $(srcdir)/ChangeLog.$$i; then \ dists="$$dists ChangeLog.$$i"; \ fi; \ done; \ if test -f $(srcdir)/LINGUAS; then dists="$$dists LINGUAS"; fi; \ for file in $$dists; do \ if test -f $$file; then \ cp -p $$file $(distdir) || exit 1; \ else \ cp -p $(srcdir)/$$file $(distdir) || exit 1; \ fi; \ done update-po: Makefile $(MAKE) $(DOMAIN).pot-update test -z "$(UPDATEPOFILES)" || $(MAKE) $(UPDATEPOFILES) $(MAKE) update-gmo # General rule for creating PO files. .nop.po-create: @lang=`echo $@ | sed -e 's/\.po-create$$//'`; \ echo "File $$lang.po does not exist. If you are a translator, you can create it through 'msginit'." 1>&2; \ exit 1 # General rule for updating PO files. .nop.po-update: @lang=`echo $@ | sed -e 's/\.po-update$$//'`; \ if test "$(PACKAGE)" = "gettext-tools"; then PATH=`pwd`/../src:$$PATH; fi; \ tmpdir=`pwd`; \ echo "$$lang:"; \ test "$(srcdir)" = . && cdcmd="" || cdcmd="cd $(srcdir) && "; \ echo "$${cdcmd}$(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang $$lang.po $(DOMAIN).pot -o $$lang.new.po"; \ cd $(srcdir); \ if { case `$(MSGMERGE) --version | sed 1q | sed -e 's,^[^0-9]*,,'` in \ '' | 0.[0-9] | 0.[0-9].* | 0.1[0-7] | 0.1[0-7].*) \ $(MSGMERGE) $(MSGMERGE_OPTIONS) -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ *) \ $(MSGMERGE) $(MSGMERGE_OPTIONS) --lang=$$lang -o $$tmpdir/$$lang.new.po $$lang.po $(DOMAIN).pot;; \ esac; \ }; then \ if cmp $$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \ rm -f $$tmpdir/$$lang.new.po; \ else \ if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \ :; \ else \ echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \ exit 1; \ fi; \ fi; \ else \ echo "msgmerge for $$lang.po failed!" 1>&2; \ rm -f $$tmpdir/$$lang.new.po; \ fi $(DUMMYPOFILES): update-gmo: Makefile $(GMOFILES) @: # Recreate Makefile by invoking config.status. Explicitly invoke the shell, # because execution permission bits may not work on the current file system. # Use @SHELL@, which is the shell determined by autoconf for the use by its # scripts, not $(SHELL) which is hardwired to /bin/sh and may be deficient. Makefile: Makefile.in.in Makevars $(top_builddir)/config.status @POMAKEFILEDEPS@ cd $(top_builddir) \ && @SHELL@ ./config.status $(subdir)/$@.in po-directories force: # Tell versions [3.59,3.63) of GNU make not to export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: xine-lib-1.2/po/tr.po0000644000175000017500000073736014647725152012307 0ustar meme# translation of libxine1.po to Türkçe # translation of libxine1.po to # Copyright (C) YEAR Copyright (C) 2000-2006 the xine project # This file is distributed under the same license as the PACKAGE package. # # Serdar Soytetir , 2007. # Server Acim , 2007, 2008. # Serdar Soytetir , 2008. msgid "" msgstr "" "Project-Id-Version: libxine1\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2008-01-05 18:22+0200\n" "Last-Translator: Server Acim \n" "Language-Team: Türkçe \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Generator: KBabel 1.11.4\n" #: lib/hstrerror.c msgid "No error" msgstr "Hata yok" #: lib/hstrerror.c msgid "Unknown host" msgstr "Bilinmeyen makine" #: lib/hstrerror.c msgid "No address associated with name" msgstr "Bu isim ile ile ilişkilendirilmiş bir adres yok" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Bilinmeyen sunucu hatası" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Makine adını bakma hatası" #: lib/hstrerror.c msgid "Unknown error" msgstr "Bilinmeyen hata" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" "dvaudio: taşmayı önlemek için tampon belleği %d seviyesine çıkartıyor.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c #, fuzzy msgid "GSM 6.10 audio decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "YARDIM! sadece mono olan bir ses sürücüsü mü?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "A/52 sesi" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" "A/52 ses ile, sesi kodlama seviyesinde değiştirebilirsiniz. Bu özel bir ses " "şiddeti için ayarlanmış olan ses kaynakları açısından bir avantajdır, " "böylece daha sonra yapacağınız kanalın ses yayın akışlarının ses " "dengelerinin ayarlanması sırasında bu işinize yarayacaktır." #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "dinamik alan sıkıştırılması için A/52 kullan" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" "Dinamik alan sıkıştırma sesin dinamik boyunu sınırlar. Bu yüksek seslerin " "yumuşak ve yumuşak seslerin yüksek olması demektir ki, bu sayede müziği " "kimseyi rahatsız etmeden gürültülü bir ortamda rahatlıkla dinleyebilirsiniz." #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "sesi 2 kanal surround stereo'ya indirge" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" "Çokkanallı surround bir ses dinlemek isteyip de, sadece iki hoparlörünüz " "veya surround kod çözücünüz veya prologic gibi bir matrix surround kod " "çözümleme imkanınız varsa, bu ek kanalların stereo sinyale çevrilebilmesi " "için bu seçeneği etkin hale getirmelisiniz" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() başarılamadı.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 başarılamadı.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit başarılamadı.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: mpc_streaminfo_read başarılamadı: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: son çerçeveden sonraki veri görmezden gelindi\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: mpc_decoder_initialise başarılamadı\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: mpc_decoder_decode başarılamadı: %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out:Zaten açık...NEDEN!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() of %s başarısız oldu: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>>başka bir uygulamanın PCM'yi kullanıp kullanmadığını " "kontrol edin<<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: bu PCM: için bozuk yapılandırma: hiç bir yapılandırma uygun " "değil: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "donanım karıştırıcısına değişiklikleri bildir" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "Donanım karıştırıcısı değiştiğinde, uygulamanız karıştırıcı ayarlarının " "görsel yeniden sunumunun güncelleneceği uyarısını alacaktır." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : desteklenen kipler" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4-kanal xine yapılandırmasında etkinleştirilmemiş)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-kanal" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-kanal xine yapılandırmasında etkinleştirilmemiş)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5-kanal" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5-kanal xine yapılandırmasında etkinleştirilmemiş)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-kanal xine yapılandırmasında etkinleştirilmemiş)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (a/52 and DTS pass-through xine yapılandırmasında etkinleştirilmemiş)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() başarısız oldu:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr "" ">>>Başka bir uygulamanın PCM'yi kullanıp kullanmadığını kontrol edin<<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "ses kartı mmap işlerimi yapamıyor" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Eğer ses kartınız ve alsa sürücünüz hafızayla eşlenmiş IO'ya destek " "veriyorsa bunu etkinleştirin./n Eğer her şey çalışıyorsa, onu " "etkinleştirmeyi ve kontrol etmeyi deneyebilirsiniz. Eğer çalışırsa, bu " "başarını arttıracaktır." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "mono çıktı için kullanılan aygıt" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine mono ses çıkışı için bu alsa aygıtını kullanacaktır.\n" "Alsa aygıtları hakkında daha fazla bilgi için alsa belgesine bakınız." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " stereo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "stereo çıktı için kullanılan aygıt" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine stereo ses çıkışı için bu alsa aygıtını kullanacaktır.\n" "Alsa aygıtları hakkında daha fazla bilgi için alsa belgesine bakınız." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-kanal" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "4-kanal çıktı için kullanılan aygıt" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine mono 4 kanal (4.0) surround ses çıkışı için bu alsa aygıtını " "kullanacaktır.\n" "Alsa aygıtları hakkında daha fazla bilgi için alsa belgesine bakınız." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-kanal" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "5.1-kanal çıktı için kullanılan aygıt" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine 5 kanal artı LFE (5.1) surround ses çıkışı için bu alsa aygıtını " "kullanacaktır.\n" "Alsa aygıtları hakkında daha fazla bilgi için alsa belgesine bakınız." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " a/52 and DTS pass-through" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " a/52 and DTS pass-through" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine kodlanmamış sayısal surround ses çıkışı için bu alsa aygıtını " "kullanacaktır.\n" "Alsa aygıtları hakkında daha fazla bilgi için alsa belgesine bakınız." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() başarısız oldu: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "alsa karıştırıcı aygıtı" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine ses gürlüğünü değiştirmek bu alsa karıştırıcısını kullanacaktır.\n" "Alsa aygıtları hakkında daha fazla bilgi için alsa belgesine bakınız." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "xine ses çıkışı eklentisi alsa uyumlu aygıtları/sürücüleri kullanıyor" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "Coreaudio/Mac OS X için xine ses çıktısı eklentisi" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Hata" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "başarılı" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "erişim engellendi" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "kaynak zaten kullanımda" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "nesne zaten algılanmıştı" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "belirtilen dalga biçimi desteklenmiyor" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "hafıza arabelleği kayıp ve onarılması gerekiyor" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "istenen ara bellek kontrolü uygun değil" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "DirectSound alt sistemi içinde belirlenemeyen hata" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "DirectSound donanım aygıtı geçerli değil" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "uygulamanın geçerli durumu için işlev uygun değil" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "geçersiz parametre geçirildi" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "nesne kümeyi desteklemiyor" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "kullanılabilecek bir ses sürücüsü yok" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "istenilen COM arayüzü kullanılabilir değil" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "başka bir uygulamanın daha yüksek öncelik düzeyi var" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "yetersiz bellek" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "bu fonksiyon için düşük öncelik düzeyi" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound başlatılamadı" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "fonksiyon desteklenmiyor" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "bilinmeyen hata" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Doğrudan ses nesnesi oluşturulamadı." #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "Doğrudan ses işbirliği düzeyi ayarlanamadı." #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "İkincil doğrudan ses önbelleği oluşturulamadı" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "Ses önbelleği çalınamadı" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "Ses önbelleği durdurulamadı" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "Önbellek konumu alınamadı" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "Önbellek konumu ayarlanamadı" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "Ses düzeyi ayarlanamadı" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": önbellek kayıp, geri yüklenmeye çalışılıyor\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "Doğrudan ses önbelleğinin kilitlenemedi" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "Doğrudan ses önbelleğinin kilidi açılamadı" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Birincil doğrudan ses önbelleği oluşturulamadı." #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": tampon bellek iş parçacığı oluşturamaz: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": tampon bellek iş parçacığını yok edemez: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ": iş parçacığı şartını yok edemez : %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": mutex iş parçacığını yok edemez : %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr ": bilinmeyen denetim komutu %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": iş parçacığı durumu yaratamaz: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": mutex iş parçacığı oluşturamaz: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "directx kullanan ikinci xine ses çıktısı eklentisi" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "win32 için directx kullanan xine ses çıktısı eklentisi" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: ESD sunucusuna bağlanılıyor %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: esd sunucusuna bağlanılıyor...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: %s ESD sunucusuna bağlanılamadı: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "esd ses çıkışı gecikme süresi (a/v senkronunu ayarla)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Eğer, sesin görüntü ile senkronize olmadığını fark ederseniz, eşitlemek için " "buraya sabitlenmiş göreli konum girebilirsiniz.\n" "Değerin birimi saniyenin 90000de bir olan bir PTS tıklamasıdır." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "esound kullanan xine ses çıktısı eklentisi" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "xine dosyası ses çıkışı eklentisi" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "xine dosyası ses çıkışı eklentisi" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "iriksiyal ses çıkışı en fazla boşluk uzunluğu" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Ses ve görüntü arasındaki en fazla konumu belirlerseniz, xine ikisi " "arasındaki senkronu yeniden denemeden önce bunu tolere edecektir.\n" "Bu ünitenin değeri, saniyenin 90000'de biri değerindeki bir PTS tıklamasıdır." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "IRIX libaudio kullanan xine ses çıktısı eklentisi" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "JACK Audio Connection Kit kullanan xine ses çıktısı eklentisi" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "xine sahte ses çıktısı eklentisi" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Ses aygıtı açılıyor %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: uyarı: örnekleme oranı %d Hz desteklenmiyor, 44100 Hz " "deneniyor\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "audio_oss_out: ses oranı : %d istendi, %d aygıt tarafından sağlandı\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "OSS ses aygıtı adı" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "hangi OSS aygıtı numarasının tam aygıt ismini almayı üstlendiğini belirlemek " "için ses aygıtı adının temel kısmını belirler .\n" "Eğer xine'nin doğru ayarı otomatik olarak algılamasını isterseniz \"auto\"yu " "seçiniz." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "OSS ses aygıtı numarası, hiçbiri için -1" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Ses aygıtının tam ismi OSS aygıt adına ve ses aygıtı numarasından " "oluşturulmuştur.\n" "Eğer numaraya ihtiyacınız yoksa ve varsayılan sistem ses aygıtından " "memnunsanız bunu -1'e ayarlayın.\n" "Bu değerin genişliği -1 veya 0-15 arasındadır. Bu ayar, OSS ses aygıt adı " "\"otomatik\" olarak saptanmış ise göz ardı edilir." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Ses aygıtı için otomatik hazırlama başarısız oldu\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: kullanılan aygıt >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: %s ses aygıtının açılamadı:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "OSS tarafından kullanılması için a/v senkron yöntemi" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "xine ses ve görüntünün senkronize olması için farklı yöntemler kullanabilir. " "Kullandığınız ses donanımından hangi ayarın en iyi çalışacağı OSS sürücünüze " "ve kullandığınız ses donanımına bağlıdır. Eğer senkron sorunları yaşarsanız " "değişik yöntemler deneyin. \n" "\n" "Değerlerin anlamları aşağıdadır:\n" "\n" "otomatik\n" "xine en ayarı bulmak için otomatik seçeneğini atar\n" "\n" "getodelay\n" "Sürücü gerçek zamanlı çalmayı desteklemese bile, SNDCTL_DSP_GETODELAY ioctl " "parametresini gerçek a/v senkronunu başarmak için kullanır.\n" "\n" "getoptr\n" "Sürücü tercih edilen SNDCTL_DSP_GETODELAY ioctl parametresini kullansa bile, " "SNDCTL_DSP_GETOPTR ioctl parametresini gerçek a/v senkronunu başarmak için " "kullanır.\n" "\n" "softsync\n" "sistem saati ile birlikte yazılım senkronizasyonunu kullanır;eğer sistem " "saati kızı ses kartınızın çalma hızı ile uyuşmaz ise ses ve görüntü, " "senkronize çalışmaz\n" "\n" "probebuffer\n" "ses kartı tampon boyutunu sıfırlamak için tüm a/v senkronizasyonundaki " "gecikme süresini hesaplamayı araştırır; sisteminizin gerçek zamanlı ioctl " "(Giriş/Çıkış Kontrolu) uygulamalarından birini destekleyip desteklemediğini " "denetlemek için veya uzun süreli çalmalardan sonra senkron hatası alırsanız " "bunu deneyin" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Ses sürücüsü gerçek zamanlı senkron etkisizleştirildi...\n" "audio_oss_out: ...soft-sync yerine sistem gerçek zamanlı saatini kullanacak\n" "audio_oss_out: ...burada ses/görüntü senkronizasyon sorunları olabilir\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "OSS ses çıkışı gecikme süresi (a/v/ senkronunu ayarlayın)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Ses sürücüsü gerçek zamanlı senkron etkisizleştirildi...\n" "audio_oss_out: ...çıkış tampon boyutunu araştırıyor: %d bytes\n" "audio_oss_out: ...burada ses/görüntü senkronizasyon sorunları olabilir\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: desteklenen kipler" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " a/52 pass-through" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (a/52 pass-through xine yapılandırmasında etkinleştirilmemiş)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "OSS ses karıştırıcısı numarası, hiçbiri için -1" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Tam karıştırıcı aygıt adı OSS aygıtı adından alınarak oluşturuldu, \"dsp\" " "ile \"karıştırıcı\" yer değiştiriyor ve karıştırıcı numarası ekliyor.\n" "Eğer sisteminizin varsayılan karıştırıcı aygıtınızdan memnun olduğunuz için " "bir numaraya ihtiyacınız yoksa, bunu -1'e ayarlayın.\n" "Bu değerin oranı -1 veya 0-15 arasındadır. Bu ayar OSS ses aygıt numarası " "\"auto\" olarak ayarlandığında göz ardı edilir." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: karıştırıcı() açılması %s başarılamadı: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "xine ses çıkışı eklentisi oss uyumlu aygıtları/sürücüleri kullanıyor" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "pulseaudio için kullanılan aygıt" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "sesatımı kısma aygıtını ayarlamak için sunucuyu [:kısma] kullanın." #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " a/52 pass-through" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" "xine ses çıkışı eklentisi sesatımı uyumlu aygıtları/sürücüleri kullanıyor" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "xine ses çıkışı eklentisi sun uyumlu aygıtları/sürücüleri kullanıyor" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: ses aygıtı açılması başarılamadı %s failed: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "Sun ses aygıtı adı" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Sun ses aygıtı kullanımı için dosya adını belirler.\n" "Bu ayar güvenlik açısından tehlikelidir, çünkü farklı bir dosya olarak " "değiştirilirse, xine bu dosyayı keyfi bir içerikle doldurabilir. Bu nedenle, " "girdiğiniz değerin Sun ses aygıtına uyması konusunda dikkatli olmalısınız." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" "audio_sun_out: %s aygıtının ses ioctl (Giriş/Çıkış Denetimi) başarılamadı: %" "s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "xine ses çıkışı eklentisi sun uyumlu aygıtları/sürücüleri kullanıyor" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "hoparlör ayarları" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Hoparlörlerin nasıl düzenlendiğine bakınız, bu xine'nin ses çıkışı için " "hangi hoparlörlerin kullanıldığını belirler. Bireysel değerler şöyledir:\n" "\n" "Mono 1.0: Sadece tek hoparlörünüz var demektir. Stereo 2.0: Sol ve sağ kanal " "için iki hoparlörünüz var demektir." #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "dosya girdi eklentisi" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_audio_dec: tampon belleği %d seviyesine taşmayı önlemek için " "arttırıyor.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "ffmpeg_audio_dec: 0x%X türü dışında ffmpeg kod çözücü bulamıyor\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: boş kodu açmaya çalışıyor\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: kod çözücüyü açamıyor\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "ffmpeg_audio_dec: kod çözücüyü açamıyor\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "ffmpeg_video_dec: desteklenmeyen çerçeve boyutları, DR1 devre dışı.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: desteklenmeyen çerçeve kipi, DR1 devre dışı.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: doğrudan işleme etkin\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "ffmpeg_video_dec: desteklenmeyen çerçeve kipi, DR1 devre dışı.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: kod çözücüyü açamıyor\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_video_dec: taşmayı önlemek için tampon belleği %d seviyesine " "yükseltiyor.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: desteklenmeyen çerçeve kipi, DR1 devre dışı.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "ffmpeg_video_dec: 0x%Xtürü için ffmpeg kod çözücüyü bulamıyor\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "MPEG 4 işleme kalitesi" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "MPEG 4 görüntüye uygulanan işlemenin oranını ayarlayabilirsiniz.\n" "Yüksek değerler daha iyi sonuç verir, fakat daha çok işlemci gücü " "gerektirir. Düşük değerler görüntü bozulmalarınına sebebiyet verir. Yüksek " "kalite içeriği için, ağır işleme işlemleri doğal olarak onun netliğinin " "bozulmasına neden olabilir ve görüntünün kötüleşmesi sonucunu doğurabilir." #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "FFmpeg görüntü kodlaması iş sayısı" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" "FFmpeg'nin kullanabileceği görüntü kodlama işlerinin sayılarını " "ayarlayabilirsiniz.\n" "Yüksek değerler kodlama işleminin hızını yükseltir fakat bu kodlamada " "paralel kodlamanın yapılıp yapılmadığıyla da bağlantılıdır. Mimari kuralına " "göre mantıksal işlemci başına bir adet kodlama işlemi yapılmalıdır (tipik " "olarak 1den14'e kadar). Bu değişim sonraki yayın akışında etkili olacaktır." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "v4l radyo girdi eklentisi" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c #, fuzzy msgid "NES Music audio decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c #, fuzzy msgid "wavpack audio decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "ogg: vorbis ses izi bulundu ama hiç vorbis akış başlığı bulunamadı.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/combined/xine_theora_decoder.c #, fuzzy msgid "theora video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "dosya girdi eklentisi" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: uyarı: Akış kimliği=%d şifrelidir.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Ortam akışı şifrelidir" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "İndeks Yeniden Yükleniyor..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "demux_avi: geçersiz avi yığını \"%c%c%c%c\" at pos %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: avi indeksi bozuk\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "demux_avi: sonraki yığın bulunamadı (konum %)\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "DVB (Dijital TV) girdi eklentisi" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "geçersiz FILM yığını\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "tanınmayan FILM yığını\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, fuzzy, c-format msgid "unsupported FLV version (%d).\n" msgstr "desteklenmeyen FLV sürümü (%d).\n" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "bu dosya içerisinde ses ya da görüntü akışı yok.\n" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: bilinmeyen sıkıştırma: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: bilinmeyen sıkıştırma: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: bilinmeyen Yığın: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "dosya girdi eklentisi" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: çerçeve önbellek için çok büyük" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: Tanınmayan akış_kimliği 0x%02x. Lütfen bunu xine " "geliştiricilerine bildirin.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: hata! boşaltılıyor.Lütfen bunu xine geliştiricilerine " "bildirin.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: uyarı: 10 bit olarak saklanan PES başlığı bulunamadı\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: uyarı: PES başlığı bu akışın şifrelenmiş olabileceğini " "bildiriyor (şifrelenmiş kip %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "pnm yayın girdi eklentisi" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: Tanınmayan akış_kimliği 0x%02x. Lütfen bunu xine " "geliştiricilerine bildirin.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: uyarı: PACK akış kimliği=0x%x kodlamasının açılması işlemi " "başarısız oldu.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "demux_mpeg_pes: uyarı: 10 bit olarak saklanan PES başlığı bulunamadı\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: uyarı: PES başlığı bu akışın şifrelenmiş olabileceğini " "bildiriyor (şifrelenmiş kip %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes:Tanınmayan gizli akış 1 0x%02x. Lütfen bunu xine " "geliştiricilerine bildirin.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "v4l radyo girdi eklentisi" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "dosya girdi eklentisi" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "dosya girdi eklentisi" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: kötü başlık parametreleri\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: desteklenmeyen ses tipi: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "demux_tta: toplam çerçeve sayısı çok yüksek\n" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "bilinmeyen VOC blok tipi (0x%02X); lütfen bunu xine geliştiricilerine " "bildirin.\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "bilinmeyen VOC sıkıştırma tipi (0x%02X); lütfen bunu xine geliştiricilerine " "bildirin.\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "dosya girdi eklentisi" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "demux_wc3movie: SHOT yığını geçersiz paleti gösterdi (%d >= %d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "demux_wc3movie: Palet yığınlarını yüklerken bir sorunla karşılaştı\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: spu device %s (%s) yüklenemedi\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_video: görüntü aygıtına yazılamadı (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "istenilen düğme kullanılabilir değil\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "dxr3_decode_video: Denetim aygıtı %s (%s) açılamadı\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "Panla & Tara bilgisini kullanın" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Panla & Tara\" bazen MPEG kodlama malzemesinde kullanılan özel bir " "görüntüleme kipidir. Böyle bir içeriğin nasıl kullanılacağını burada " "belirleyebilirsiniz.\n" "\n" "sadece zorunluluk halinde\n" "Yalnızca çalmakta olduğunuz içerik sizi mecbur bıraktığında Panla & Tara " "özelliğini kullanınız.\n" "\n" "MPEG işareti\n" "MPEG görüntü akışına gömülü bilgiyi temel alan Panla & Tara seçeneğini " "etkinleştiriniz.\n" "\n" "DVB işaretini kullan\n" "DVB görüntü akışına gömülü bilgiyi temel alan Panla & Tara seçeneğini " "etkinleştiriniz. Bu bazı Avrupa DVB kanallarında kullanılan Etkin Kip " "Tanımlayıcısı'nın (AFD) kullanımını sağlar." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "her çerçevede görüntüyü eşzamanlamayı dene" #: src/dxr3/dxr3_decode_video.c #, fuzzy msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" "Eğer kare için zaman çizelgesinin senkronize edilmesini dener. Normalde bu " "gerekli değildir, çünkü zaman çizelgesi ayarlanmış olsun veya olması senkron " "uygundur.\n" "Bu sadece yürüyen görüntü için geçerlidir (çoğu PAL görüntüde oluğu gibi)." #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "düz oynatma kipini kullan" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "" "Bu seçeneği etkinleştirmek daha yumuşak bir çalma kipine geçişi " "sağlayacaktır." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "kırık akışlarda çerçeve sürelerini düzelt" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" "Bazı hatalı kare sürelerine sahip mpeg akışlarındaki yanlış kare hatası " "kodlarını düzelten bir küçük mantığı etkinleştirir. Bu hata karşımıza daha " "çok yanlışlıkla PAL akışı olarak etiketlenmiş NTSC akışlarında karşımıza " "çıkar. Bu özelliği böylesi akışlarla karşılaştığınızda etkinleştirin." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Aygıt açılamadı %s (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "dxr3_decode_video: kızarmayı önlemesi için aygıta yazar\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: görüntü aygıtına yazılamadı (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "dxr3_decode_video: UYARI: bilinmeyen çerçevesi oranı kodu %d\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: UYARI: çerçeve oranı kodu PAL'den NTSC'ye çevriliyor\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "DXR3 aygıt numarası" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Eğer bilgisayarınızda birden fazla DXR3 varsa, burada hangisini " "kullanacağınızı belirlemelisiniz." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: librte başlatılamadı\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: 16 çoklamasına sahip görüntü boyutlarında sadece rte \n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: rte bağlamı alınamadı.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: kodlayıcı oluşturulamadı.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "rte mpeg çıktısı bit oranı (kbit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "Mpeg kodlama kütüphanesi bit boyu olan librte, DXR3 kodlama kipini " "kullanmalı. Daha yüksek değerle kaliteyi ve işlemci kullanımını " "arttıracaktır." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: bağlam başlatılamadı: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: kodlamaya başlanamadı: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: FAME kütüphanesi başlatılamadı\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "fame mpeg kodlama kalitesi" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "Libfame mpeg kodlama kütüphanesinin kodlama kalitesi. Yavaş, daha hızlıdır " "ama dikkat çekici bir özellik katar. Daha hızlı, daha iyidir, fakat daha " "yavaştır." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "SCR eklenti önceliği" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" "DXR3 SCR eklentisinin önceliği. 5'den daha az olan değerler unix sistem " "zamanlayıcısının kullanılacağı anlamına gelir. 5'den daha büyük değerler " "DXR3'ü senkron kaynağı olarak dahili saati kullanması için zorlarlar." #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "libavcodec mpeg çıkış bit oranı (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" "libavcodec mpeg çıkış bit oranı, DXR3 kodlama kipini kullanmalıdır. Yüksek " "değerler kaliteyi ve işlemci kullanımını yükseltir.\n" "Bu ayar sadece sabit kalite kipi devre dışı ise etkilidir." #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "sabit kalite kipi" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" "Etkinleştirildiğinde libavcodec, görüntünün karmaşık yapısına göre dinamik " "olarak sıkıştırılmış sabit kalite kipini kullanacaktır " #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "en düşük sıkıştırma" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "Sabit kalite kipindeki bir resme uygulanacak ola en düşük sıkıştırma." #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "en yüksek nicelikler" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "Sabit kalite kipindeki bir resme uygulanacak ola en yüksek sıkıştırma." #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Denetim aygıtı %s (%s) açılamadı\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "tek ve çift satırları değiştir" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" "Resmin tek ve çift alanlarını değiştirir.\n" "Bu seçeneği MPEG malzemesi dışında ekranda dikey oynamalar üretmek için " "etkinleştirin." #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "görünüm oranını düzeltmek için siyah çubuklar ekle" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Resim görüntü oranı kartı ile başa çıkamadığında siyah çizgiler ekler. Bu " "uygun görüntü kesitleri oluşturulmak isteniğinde gereklidir." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "mpeg kodlayıcı oynatması için pürüzsüz oynatmayı kullan" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Bu seçeneği etkinleştirmek MPEG içeriği dışındaki kaynaklar için daha " "yumuşak oynatma kipine geçişi sağlayacaktır." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Görüntü aygıtı %s (%s) açılamadı\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "mpeg olmayan içerik için kodlayıcı" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "MPEG dışındaki içeriğin, ek bir yeniden kodlanma aşamasından geçmesi " "gereklidir, çünkü dxr3 sadece MPEG ile başa çıkabilir.\n" "xine'nin neyi desteklediğine bağlı olarak, bu ayar \"fame\", \"rte\", " "\"libavcodec\" veya \"hiçbiri\". olarak ayarlanabilir.\n" "\"libavcodec\" kodlayıcısı xine ile çalışan ffmpeg eklentisinin çalışmasına " "sebep olur, böylece bunun için ek bir kütüphane dosyası yüklemek zorunda " "kalmazsınız. Hatta daha iyi bir olanak olarak, libavcodec'in aynı zamanda " "düşük işlemci hızıyla yüksek kalitede performans gösterdiğidir. \"libavcodec" "\" kullanılması bu yüzden şiddetle tavsiye edilir.\n" "\"fame\" ve \"rtre\" hala oradadırlar, fakat xine onları güncel olarak " "desteklemezler, bu yüzden çalışmazlar." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "video_out_dxr3: Mpeg kodlayıcı libavcodec başlatılamadı.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: Mpeg kodlayıcı rte başlatılamadı.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: Mpeg kodlayıcı fame başlatılamadı.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Mpeg kodlaması edilgenleştirilmiş.\n" "video_out_dxr3: burası tamamdır, ona DVDler gibi mpeg video amacıyla " "ihtiyacınız yoktur, fakat\n" "video_out_dxr3: bu görüntü çıkışını kullanarak mpeg-dışı içeriği " "oynatamazsınız\n" "video_out_dxr3: sürücü. kodlayıcıyı yapılandırmak hakkında daha detaylı " "bilgiler için README.dxr3 dosyasını okuyunuz.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Hiç bir mpeg kodlayıcısı derlenmemiştir.\n" "video_out_dxr3: burası tamamdır, ona DVDler gibi mpeg görüntü amacıyla " "ihtiyacınız yoktur, fakat\n" "video_out_dxr3: bu görüntü çıkışını kullanarak mpeg-dışı içeriği " "oynatamazsınız\n" "video_out_dxr3: sürücü. kodlayıcıyı yapılandırmak hakkında daha detaylı " "bilgiler için README.dxr3 dosyasını okuyunuz.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "görüntü çıktı kipi (TV ya da üstyazım)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" "Bitmiş görüntü için DXR3 çıkışlarının yolları buradan ayarlanabilir. Kişisel " "değerler:\n" "\n" "harfkutucuklu tv\n" "görüntüyü sadece TV çıkış bağlantılarına gönderme. Bu standart 4:3 " "televizyonlar için kullanılan bir kiptir. Anamorfik (16:9) görüntü " "harfkutucuklu görüntülenecektir, panla&tara malzemesi görüntünün sağ ve sol " "tarafta kesilmiş gibi görüntülenmesine yol açacaktır. Bu televizyonun " "bağımsız DVD çalıcı gibi kullanıldığı ortak bir ayardır.\n" "\n" "geniş ekran tv\n" "Görüntüyü sadece TV çıkış bağlantılarına gönderme. Bu kip 16:9 geniş ekran " "TV setleri için oluşturulmuştur. Anamorfik ve panla&tara içeriği tüm ekranı " "kaplayacaktır, fakat televizyonun görüntü ayarlarını elle 16:9 ekran " "boyutunda kullanacak şekilde ayarlamalısınız.\n" "\n" "harfkutucuklu kaplama\n" "Bilgisayar ekranındaki üstyazım görüntü çıkışının, görüntü ekranının " "gizlenmesi suretiyle TV çıkışına geçirilmesidir. Eğer kaynak anamorfik " "(16:9) ise, üstyazım siyah çerçeveyle görüntülenecektir.\n" "Bu ayar, DVD altyazı kanalının sadece harfkutucuklu kipte düzgün " "görüntülenebildiği ender durumlarda faydalı olabilecektir. Bunun için en iyi " "örnek \"Ghostbusters\" filmindeki hareketli yorumcu silüetleridir.\n" "\n" "geniş ekran kaplama\n" "Bilgisayar ekranındaki üstyazım görüntü çıkışının, görüntü ekranının " "gizlenmesi suretiyle TV çıkışına geçirilmesidir. Bu DXR3 kaplamasının ortak " "değişkenidir." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "katman renk değeri" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Anahtar rengin onaltılık RGB değeri.\n" "Eğer DXR3 katman kipini kullandığınızda pencereler şeffaflaşırsa değişik " "değerler deneyebilirsiniz." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "katman renk toleransı" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" "Daha büyük bir değer katmak renginin toleransını genişletebilir.\n" "Eğer DXR3 katman kipini kullandığınızda pencereler şeffaflaşırsa daha düşük " "değerler deneyebilirsiniz, fakat çok daha düşük bir değer denediğinizde " "görüntü sınırlarının bazı kısımları kaybolabilir." #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "Üst ve altın katman bölgesini kesin" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Katmanın üst ve altından bir piksel satırını çıkarır. Katmanın üst ve " "altındaki yeşil satırı görmek isterseniz bunu etkinleştirin." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: lütfen otomatik ayarı çalıştırın, katman kayboldu\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "tercih edilen tv kipi" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "DXR3 kullanarak TV kipini seçer. Değerlerin anlamları şöyledir:\n" "\n" "ntsc: saniyede 60Hz hızındaki NTSC\n" "pal: saniyede 50Hz hızındaki PAL\n" "pal60: saniyede 60Hz hızındaki PAL\n" "varsayılan: ekran kartının ayarlarını korur" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: görüntü kipi ayarlanamadı.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: mpeg-dışı görüntüleri oynatmak için dxr3 üzerinde bir mpeg " "kodlayıcısına ihtiyaç duyar\n" "video_out_dxr3: Detaylar için README.dxr3 dosyasını okuyun.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: HATA Katman init dosyasını okuyor. Otomatik kullanımı " "çalıştırın!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c #, fuzzy msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "Aygıta giden yol, genellikle DVDleri oynatmak amacıyla kullanılan DVD " "sürücüsü." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "atlama eylemi için birim" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: %s konumuna bağlanılamadı:%d\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: cddb sunucusuna başarılı bir şekilde bağlandı '%s:%d'.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" "input_cdda: cddb sunucusuna '%s:%d' (%s) bağlanma işlemi başarısız oldu.\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "CD Dijital Ses (CDDA olarak da bilinir)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "CD sesi için kullanılan aygıt" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "Aygıta giden yol, ses CDlerini çalmak amacıyla kullandığınız CD yada DVD " "sürücüsü." #: src/input/input_cdda.c msgid "query CDDB" msgstr "CDDB sorgusu" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" "Ses CD'niz için uygun başlıklar ve iz isimleri sunan CDDB sorgularını " "etkinleştirir.\n" "Size özel, kişisel CDDB'yi kullanmadığınız taktirde sizin dinlediğiniz " "müziklerinizin toplanmasından yola çıkarak oluşturulan profiliniz " "paralelinde bir ağ sunucusundan ilgili bilgilerin toplandığını aklınızdan " "çıkarmayınız." #: src/input/input_cdda.c msgid "CDDB server name" msgstr "CDDB sunucu adı" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" "CDDB sunucusu başlık ve iz bilgilerinin toplanması için kullanılır.\n" "Bu ayar güvenlik açısından kritiktir, çünkü sunucu sizin dinleme " "alışkanlıklarınız hakkında bilgiler toplayacak ve kötü niyetli sorguları " "cevaplandıracaktır. Güvenilir sunucuları kullanmayı deneyin." #: src/input/input_cdda.c msgid "CDDB server port" msgstr "CDDB sunucu portu" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "Sunucu portu başlık ve iz bilgisini almak için kullanıldı." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "disk sürücüsünün hızını seviyesine düşür" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" "Bazı CD ve DVD sürücüler hızlı disk dönüşü nedeniyle çok ses çıkaracağı " "için, xine onları yavaşlatmayı deneyecektir. Standart CD veya DVD " "çalınırken, hızlı dönüşü gerektiren yüksek verilere ihtiyaç duyulmaz, " "böylece yavaşlama, çalma performansını etkilemez.\n" "Buradaki sıfır değeri yavaşlamayı devre dışı bırakacaktır." #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "input_dvb: dvb kanal dosyası açılamadı '%s': %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "input_dvb: dvb kanal dosyası '%s' düz bir dosya değil\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: tuner_set_channel başarısız oldu\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: dvb aygıtı açılamadı\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "input_dvb: kanal %d sınırların dışında, Sıfırlanıyor\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: %s kanalını arıyor\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" "input_dvb: %s için tam eşleşme bulunamadı: kısmi eşleşmeler deneniyor\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: %s eşleşen kanal bulundu\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" "input_dvb: %s kanalı channels.conf dosyasında bulunamadı, öntanımlı " "değerlere dönülüyor.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" "input_dvb: geçersiz kanal belirtimi, son görüntülenen kanala dönülüyor.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "input_dvb: geçersiz kanal belirtimi, kanal 0(sıfır)'a dönülüyor.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" "input_dvb: dvb'nin mrl değeri belirtilmiş fakat alıcı QPSK (DVB-S) gibi " "gözükmemekte.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: dvbt'nin mrl değeri belirtilmiş fakat alıcı OFDM (DVB-T) gibi " "gözükmemekte.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: dvbc'nin mrl değeri belirtilmiş fakat alıcı QAM (DVB-C) gibi " "gözükmemekte.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" "input_dvb: dvba'nın mrl değeri belirtilmiş fakat alıcı ATSC (DVB-A) gibi " "gözükmemekte.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: dvr aygıtını açamıyor '%s'\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "input_dvb: EPG güncelleyici bağı yaratamıyor\n" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "DVB merkez kesmesini kullan (yakınlaştır)" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Bu, 4:3 tam ekran oynatımı içeriğinin 16:9 çerçevesinde gösterilmesine izin " "verecektır." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "DVB (Dijital TV) girdi eklentisi" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Son izlenen DVB kanalını hatırla" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" "Otomatik çalmada, xine hatırlayacak ve ortamdaki ilgili kanala geçecektir. " "dvb.son_kanal." #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Görüntülenen son DVB kanalı" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "Eğer etkinleştirilmişse, xine hatırlayacak ve bu kanala geçecektir." #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "Ayarın süresinin dolmasına kalan saniyelerin sayısı" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" "0'da bırakmak, sürekli dene anlamına gelir. 0'dan büyükler kilitlenmeye " "kadar bekleyin anlamına gelir. En az olanı 5 saniyedir." #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Kullanılacak dvb kartların sayısı." #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "Eğer sisteminizde birden fazla kart yoksa bunu sıfırda bırakın." #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "input_dvd: values of \\beta will give rise to dom!\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: DVD (%s) ortamından sonraki blok alınamadı\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: DVD aygıtı açılırken hata oluştu\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "DVD oynatmak için kullanılacak aygıt" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "Aygıta giden yol, genellikle DVDleri oynatmak amacıyla kullanılan DVD " "sürücüsü." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "CSS şifre çözme yöntemi" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" "Şifreyi kırma yöntemini seçer, libdvdcss kopya korumalı DVDlerin şifrelerini " "çözmekte kullanılacaktır. Eğer şifreli DVD'leri çalmakta problemler " "yaşarsanzı değişik yöntemler deneyin." #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "DVD çaların kapsadığı bölge (1 ile 8 arası)" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "Eğer DVDniz hatalı bölge kodunu ekranda gösterirse, sadece bu durumda " "gereklidir. Yazılımın özelliğinden dolayı, DVD sürücülerine ayarlanan bölge " "kodları ile ilgili bir değişikli yapılamaz." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "DVD oynatmak için öntanımlı dil" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine, ön tanımlı DVD çalma dili olarak bunu kullanmayı dener. DVD'nin " "desteklediği ölçüde, menüler ve ses izleri bu dilde sunulacaktır.\n" "Dil kodu değerinin iki karakterli ISO639 dil kodu olması gereklidir." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "tamponlama boyunca oku" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" "xine, DVD sürücü yolu için tamponlama boyunca oku özelliğini kullanabilir.\n" "Bu özellik, yavaş çalışan sürücülerde kötü çalmalara sebebiyet verebilir, " "fakat o daha hızlı sürücülerde DVD katman değişiminin etkisini güçlendirir." #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" "Bir atlama komutunu kullanırken davranışı yapılandırlabilirsiniz (örneğin " "atlama tuşlarını kullanarak). Bireysel değerler şu anlama gelir:\n" "\n" "program atla\n" "Ses CD'sindeki içindekileri gösteren yapıya benzer şekilde görüntülenebilir " "bir ünite olan DVD programına atlayacaktır\n" "\n" " kısım atla\n" "bir ses CD'sindeki iz işaretlerine benzeyen yapısal bir ünite olan DVD " "kısmına atlayacaktır, kısımlar programlarla uyumludur, fakat kısımlar " "programlardan daha büyük olabilirler.\n" "\n" "başlığı atla\n" "DVD'deki tüm özellikleri gösteren yapısal bir birim olan DVD başılığını " "atlayacaktır" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "arama birimi" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" "Arama kaydıracı ile kullanılan alanı yapılandırabilirsiniz. Kişisel " "değerlerin anlamları:\n" "\n" "program zincirinde ara\n" "arama tüm DVD program zincirini bağlayacaktır, geçerli özelliğin tüm görüntü " "akışını gösteren gözlemsel bir birimdir bu\n" "n programda arama\n" "arama tüm DVD program zincirini bağlayacaktır, geçerli özelliğin bölümlerini " "gösteren gözlemsel bir birimdir bu" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "başlık/bölüm verildiğindeki çalma kipi" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" "Verilmiş bir başlık/bölüm'den bir dvd çalarken davranış modelini " "yapılandırabilirsiniz (örneğin MRL kullanıyor dvd:/1.2). Bireysel değerlerin " "anlamları:\n" "\n" "tüm dvd\n" "tüm dvd'yi belirlenen konumdan başlayarak çal.\n" "bir bölüm\n" "sadece belirlenen başlık/bölüm'ü çal ve dur" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: İzin verilmedi: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Dosya bulunamadı: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: Dosya boş: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "dosya girdi eklentisi" #: src/input/input_file.c msgid "file browsing start location" msgstr "dosya açma başlangıç konumu" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "Çalınması istenen dosyanın bu konumdan bağlayacağını seçen tarayıcı." #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "dosya girdi eklentisi" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "dosya girdi eklentisi" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "xine ile birlikte gelen gnome vfs girişi" #: src/input/input_helper.c msgid "list hidden files" msgstr "gizli dosyaları listele" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" "Eğer etkinleştirilmişse, çalınacak dosyayı seçen tarayıcı aynı zamanda gizli " "dosyaları da gösterebilir." #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "stdin yayın girdi eklentisi" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s) başarısız oldu: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: okuma hatası %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "HTTP sunucusuna bağlanılıyor..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: geçersiz http yanıtı\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: 3xx yeniden yönlendirme: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: http durumu 2xx değil: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: içerik büyüklüğü = % byte\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: %d byte ardından önbellek boşaltıldı." #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "http girdi eklentisi" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "HTTP vekil sunucu makinesi" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "HTTP vekil sunucusu için makine adı." #: src/input/input_http.c msgid "HTTP proxy port" msgstr "HTTP vekil sunucu portu" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "HTTP vekil sunucusu için port numarası." #: src/input/input_http.c msgid "HTTP proxy username" msgstr "HTTP vekil sunucu kullanıcı adı" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "HTTP vekil sunucusu için kullanıcı adı." #: src/input/input_http.c msgid "HTTP proxy password" msgstr "HTTP vekil sunucu parolası" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "HTTP vekil sunucusu için parola." #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "HTTP vekilini göz ardı etmek için alanlar" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Vekilin göz ardı edilmesi için birbirinden virgülle ayrılan alan adları " "listesi.\n" "Eğer bir alan adı '=' ile ön ek almışsa, o zaman ona sadece ana makina adı " "olarak bakmak gerekir (tam uyuşum gereklidir)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "mms yayın girdi eklentisi" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "ağ bant genişliği" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "İnternet bağlantınızın bant genişliğini burada belirtiniz. Bu, yayın akışı " "sunucularının aynı yayın akışını farklı bant genişliği gereksinimleriyle " "önerdiklerinde kullanılacaktır." #: src/input/input_mms.c msgid "MMS protocol" msgstr "MMS protokolü" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "MMS için kullanılacak protokolü seçin.\n" "TCP daha iyidir ancak bir güvenlik duvarı kullanıyorsanız HTTP seçmeniz " "gerekir." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "stdin yayın girdi eklentisi" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "xine ile birlikte gelen ağ girişi eklentisi" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "dosya girdi eklentisi" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "dosya girdi eklentisi" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "stdin yayın girdi eklentisi" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "pnm yayın girdi eklentisi" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: pvr dosyası oluşturma hatası (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: pvr dosyası açma hatası (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: okuma hatası (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: %s aygıtı açılamadı\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" "input_pvr: IVTV_IOC_G_CODEC başarısız oldu, API değişmiş olabilir mi?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" "input_pvr: IVTV_IOC_S_CODEC başarısız oldu, API değişmiş olabilir mi?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "WinTV-PVR 250/350 girdi eklentisi" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "WinTV-PVR 250/350 (pvr eklentisi) için kullanılan aygıt" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "WinTV kartınızın aygıt yolu." #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "IP adresi çoklu yayın olarak belirlendi\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "%s iface için adres bulunamadı:%s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "" "setsockopt(IP_ADD_MEMBERSHIP) başarısız oldu (multicast kernel?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "'%s' çözümlenemedi.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "Buraya bağlanamadı %s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: okuma işini durduruyor...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: okuma işi kapatıldı\n" #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Dosya adını >açıyor:%s bağlantı noktası:%d arabirim:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: yeni iş üretemez (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "xine ile birlikte gelen RTP ve UDP giriş eklentisi" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "rtsp yayın girdi eklentisi" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "libsmbclient temelli CIFS/SMB girdi eklentisi" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "dosya girdi eklentisi" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "dosya girdi eklentisi" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: '%s' açılamadı\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "stdin yayın girdi eklentisi" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "v4l tv girdi eklentisi" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Tampon bellek zayıfladı..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Tampon bellek aşımı..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Ayarlanıyor..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Tuner adı bulunamadı\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "v4l tv girdi eklentisi" #: src/input/input_v4l.c msgid "v4l video device" msgstr "v4l görüntü aygıtı" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Video4Linux görüntü aygıtının yolu." #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "v4l radyo girdi eklentisi" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "v4l radyo aygıtı" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Video4Linux radyo aygıtının yolu." #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: bozuk MRL. vcdo:/ kullanın\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: geçersiz iz %d (geçerli oran: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "%s açılamadı: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: %s açılamadı: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "Video CD girdi eklentisi" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "VCD oynatmak için kullanılan aygıt" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" "Video CD'lerinizi çalmak istediğiniz ve genellikle CD veya DVD sürücü " "olarak bilinen aygıta giden yol." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: bozuk mrl: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: '%s' konumuna bağlanılamadı\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: %s sunucusuna bağlanılamadı\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: oturuma erişilemedi.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "rtsp_session: oturuma erişilemedi.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "rtsp_session: rtsp sunucu tipi '%s' henüz desteklenmiyor. üzgünüm.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "input_dvd: eject çağrıları sırasında %s aygıtı açılamadı\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "MMS sunucusuna bağlanılıyor (tcp üzerinden)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: gönderme hatası\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: kötü yanıt biçimi\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: 3xx yeniden yönlendirme uygulamaya eklenmedi: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: http durumu 2xx değil: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: Konum yeniden yönlendirmesi uygulamaya eklenmedi\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "MMS sunucuya bağlanılıyor (http üzerinden)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "geçersiz adres\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "desteklenmeyen protokol\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "tercih edilen tv kipi" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "tercih edilen tv kipi" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: yayın akışıniı okurken sunucdan mesaj geldi:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: '%s' konumuna bağlanılamadı\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: akış ayarlaması başarısız oldu\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR sıfır-dışı kolu için yerine getirilemedi" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END henüz tamamlanmadı." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "için arama henüz tamamlanmadı" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "hatalı öge tipi" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "hatalı girdi numarası" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "hatalı parça numarası" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Geçerli bölüm numarası alma hatası" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Bunun yukarıdakine dönüştürülmesi gerekirdi" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "VCD içeren aygıt bulunamadı" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "geçersiz sınıf parametresi atlandı" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Geçersiz güncel girdi tipi" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "seçim hiç RETURN girişe sahip değil" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "DEFAULT seçili, fakat PBC açık değil." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "seçim hiç NEXT girişe sahip değil" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "seçim hiç PREVIOUS girişe sahip değil" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Bilinmeyen olay tipi: " #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" "Şunlar için PBC ile Video CD eklentisi ve desteği: (X)VCD, (X)SVCD, HQVCD, " "CVD ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "Otomatik çalmayı kullanmak için VCD öntanımlı türü" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "Bir MRL'de hiçbirinin belirtilmediği konumu kullanan VCD çalma birimi, örn. " "vcd:// veya vcd:///dev/dvd:" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "Aksi belirtilmedikçe CD-ROM sürücüsü VCD için kullanılanacak" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Eğer hiç sürücü belirtilmemişse ne kullanmalı. Eğer ayarlar boş ise, xine CD " "sürücülerini bulmak üzere taramaya başlayacak." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "VCD konumu kaydırma alanı" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" "akış çalma konumu kaydırma alanının bir VCD çalmakta olduğunu belirten bölge." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "Bellekleme yerine doğrudan VCD'yi okusun mu?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "Son-kullanıcı cihazlarında sınıf, kötü çalma sonuçlarına sebep olur." #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "VCD iz/giriş yapılarında otomatik ilerleme" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Eğer etkinleştirilmişse, otomatik olarak sonraki giriş veya ize geçebiliriz. " "Bu özellik, sadece eğer çalma denetimi (PBC) devre dışı ise kullanılır." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "reddedilen VCD'leri göster" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" "Bazı çalma listeleri gösterilemez olarak işaretlenmiştir, fakat onları eğer " "ayarlanmışsa MRL listesinde görebilirsiniz. Reddedilen girdiler yıldız (*) " "ile işaretlenmiş olup MRL'ye eklenmiştir." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "Başlığı görüntülemen için VCD kipi dizgesi" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" "GUI Başlığı'nda kullanılan VCD kipi. Unix tarih komutuna benzer. Kip " "belirteci yüzde işaretiyle başlar. Belirteçler şöyledir: \n" " %A : Albüm bilgisi\n" " %C : VCD ses seviyesi sayacı - seçimdeki CD'lerin numarası.\n" " %c : VCD ses seviyesi numarası - seçimdeki CD'nin sayısı.\n" " %F : Şu anki girdi/kesit/çalma türü, v.b. GİRDİ, İZ, ...\n" " %L : Eğer varsa \" LID\" önekli liste bilgisi\n" " %N : Yukardakinin numarası - bir ondalık sayı\n" " %P : Yayımcı kimliği\n" " %p : Hazırlayıcı kimliği\n" " %S : eğer bir kesitte isek (menüdeysek), kesitin türü\n" " %T : İz numarası\n" " %V : Ses ayarı kimliği\\ %v : Ses kimliği\n" ".......Ses ayarı sayısı ile 1 arası bir sayı.\n" " %% : a %\n" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "Yayın akışı yorum alanı için VCD kipi dizgesi" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "GUI Başlığı'nda kullanılan VCD kipi. Unix tarih komutuna benzer. Kip " "belirteci yüzde işaretiyle başlar. Belirteçler şöyledir: %A, %C, %c, %F, %I, " "%L, %N, %P, %p, %S, %T, %V, %v, and %%.\n" "Bunların anlamları için başlık_kipi yardım dosyasına bakınız." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "VCD hata ayıklaması bayrak maskesi" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" "VCD eklentilerindeki hataların izlerini sürmek için, Maske değerleri " "şunlardır:\n" "...1: Meta bilgisi\n" "...2: giriş (klavye/fare) olayları\n" "...4: MRL incelemesi\n" "...8: Dış yordamlar gelen çağrılar\n" "..16: yordam çağrıları\n" "..32: LSN değişiklikleri\n" " 64: Çalma denetimi\n" ".128: CDIO'dan hata ayıklama\n" ".256: Bölgeyi ayarlama için yapılan arama\n" " 512: Şu anki bölgesi bulmak için yapılan arama\n" "1024: Donmuş kare\n" "2048: VCDINFO'dan hata ayıklama\n" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "RealPlayer kodları yolu" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "Eğer RealPlayer yüklüyse, buraya onun kod dizinini belirtiniz. Kod dizinini " "\"drvc.so\" dosyasını arayarak kolayca bulabilirisiniz. Eğer xine, " "RealPlayer kodlarını bulursa, onu RealPlayer kodlarını sizin için çözmek " "üzere kullanacaktır. Kodların yüklenmesi hakkında daha fazla bilgi için SSS " "başvrunuz." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (ses) Simgeleri çözümleyemiyor - uyumsuz dll: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "libareal: kod çözücü init başarılamadı, hata kodu: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "libareal: kod çözücü yapısal ayarı başarılamadı, hata kodu: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: ops, real 2 kanaldan daha fazlasıyla baş edebilir ?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "libreal: Simgeleri çözmede hata! (sürüm uyumu?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "lWin32 kodlayıcılarının yolu" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "Eğer Windows veya Apple Quicktime kod paketleri kuruluysa, burada kod dizini " "yolunu belirtiniz. Eğer xine Windows veya Apple Quicktime kodlarını bulursa, " "bunu sizin için farklı Windows veya Apple Quicktime yayın akışlarının " "kodlarını çözümlemede kullanacaktır. Kodların kurulması konusundaki daha " "fazla bilgiye ulaşmak için xine SSS'ye başvurun." #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ICOpen başarılamadı! bilinmeyen kod %08lx / parametreler yanlış?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) başarılamadı: Hata %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery başarılamadı: Hata %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin başarılamadı: Error %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder başarılamadı! bilinmeyen kod %08lx / parametreler " "yanlış?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder başarılamadı! bilinmeyen kod %08lx / parametreler " "yanlış?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: kod çözümleyici başlayamadı. Yoksa '%s' kurulmadı mı?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Uyumusuz ses kipi\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen hatası %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: DirectShow Audio sıfırlamada hata\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: DMO Audio sıfırlamada hata\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" "Bu süzgeç bir etmenden dolayı yayın akışını daha hızlı veya daha yavaş " "oynatılmasına yol açan zaman uzamasına etki edecektir. Oran büyük olasılıkla " "korunacaktır, böylece bir filmi gerçek süresine göre daha az zamanda izlemek " "için kullanılabilir.\n" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" "Çoğaltma fonksiyonları. örn. Stereo giriş alın ve Surround 5.1 çıkışa " "dönüştürün.\n" "Parametreler\n" " cut_off_freq\n" "\n" "Dikkat: Bu parametreleri öndeki denetim penceresinden ayarlamak mümkündür.\n" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" "Bu süzgeç, mono akışı kanalları çiftleyerek stereo'ya dönüştürecektir. " "Alternatif olarak, bu eklenti sadece bir kanalın ya da verilen yayın " "akışının dinlenmesi için de kullanılabilir.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": Mono'dan Stereo'ya dönüştürme.\n" #: src/post/audio/upmix_mono.c #, fuzzy, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] ": tek kanalı özgün %d kanal yayın akışlarına dönüştürme.\n" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": ses aygıtının AO_CAP_MODE_STEREO özelliği yok.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr ": Mono'dan Stereo'ya dönüştürme" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" "Sesin bozmadan sesi yükselterek ses kaynağını normalleştiriyor.\n" "\n" "Parametreler:\n" " yöntem: 1: çeşitlemeleri yumuşatmak ya da eski ses örneklerini temel " "alarak tek bir örnek kullanınız (varsayılan); 2: çeşitlemeleri yumuşatmak " "ya da eski ses örneklerini temel alarak farklı örnekler kullanınız.\n" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" "Gelişmiş seçenek tanımalı tvtime/dönüştürücü eklentisi \n" "Bu eklentinin amacı dönüştürme mekanizmasına yüksek kaliteli DVD çalarlarla " "yarışacak bir ortam sağlamaktır ve buna bilgisayar ekranları, yansıtıcılar " "ve diğer ileri seviyede görüntü cihazlarıyla kullanılması için çizgi " "çiftleyici denir.\n" "\n" "Parametreler\n" "\n" "Method: Kullanılacak dönüştürme yöntemini/algoritmasını seçer, her yöntemin " "açıklaması için aşağıda bakınız.\n" "\n" "Etkin: Eklenti etkin/etkisiz\n" "\n" " Pulldown: 2-3 indirme tanıma algoritmasını seçin, 24 fps NTSC kipine " "dönüştürülmüşlerdir ve rahatlıkla algılanabilir ve eski hallerine " "döndürülebilirler (dönüştürülmemiş).\n" "\n" " Framerate_mode: Tam'ı seçmek her alanı televizyon ve ötesi kalitede bir " "noktaya dönüştürecektir. Bu özellik yumuşaklığı arttırarak çerçeve oranını " "ikiye katlayacaktır. Yalnız, düz 2.4 Linux çekirdeği ile tam 59.94 FPS " "olanaklı değildir (zaman kesme oranı olarak 100Hz'i kullanan. Daha yeni Red " "Hat veya 2.6 çekirdekleri daha yüksek HZ ayarları kullanırlar (büyük " "olasılıkla 512 veya 1000) ve daha güzel çalışır.\n" "\n" " Judder_correction: Bir kez 2-3 indirme etkinleştirilirse ve film malzemesi " "tanınırsa çerçeve oranını kullanılan özgün orana (24 FPS) indirmek mümkün " "olabilir. Bu çerçevelerin düzgün görüntülenmesine ve titreme etkisini " "eleyerek hızının normalleşmesine imkan tanıyacaktır.\n" "\n" " Use_progressive_frame_flag: İyi master edilmiş MPEG2 yayın akışları " "ilerleyen malzemeyi belirten bir bayrak kullanırlar. Bu ayar, bu bayrağa " "güvenip güvenemeyeceğimizi denetler (bazı ender ve böcekli! mpeg yayın " "akışlarında bu yanlış ayarlanmıştır).\n" " Chroma-filter: DVD/MPEG2, çok zayıf bir kroma çözünürlüğe sahip " "dönüştürülmüş resim kipi kullanır. Dönüşüm amacıyla kromayı değiştirmek bazı " "hatalara sebep olabilir (renk karışımı gibi...). Bu seçeneği yapılanları " "silip dönüştürdükten sonra renk parlaklığını dikey olarak bulanıklaştırmak " "için kullanın. Uyarı: işlemci yoğunluğu\n" "\n" " Cheap-mode. Bu geniş YV12->YUY2 görüntü çevrimini tvtime/dscaler " "yordamlarını sanki onlar hala YUY2 görüntüleriyle uğraşıyormuş gibi " "kandırarak atlayacaktır, Tabii ki, bu doğru değildir, saptanan algoritmalar " "tarafından dönüştürme ve renk parlaklığının ayrı ayrı işlem görüp " "görmeyeceğine bağlı olarak tüm pikseller değerlendirilmeyecektir. Ne yazık " "ki, sistemi yavaş olan makinalarda kalite ve işlemci rekabetine a göre " "algoritmaları dönüştürme işlemleri yapılmaya çalışılacaktır.\n" "\n" "* tvtime ve dscaler projeleri için farklı algoritmalar kullanır.\n" "Dönüştürme yöntemleri: (Tüm yöntemler tüm platformlar için geçerli " "olmayabilir)\n" "\n" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: Hiç bir dönüştürme yöntemi uygun değil. Kapatılıyor. \n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "oluşturulmak üzere saniye başına kareler" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Saniye başına daha çok kareler için, hareket daha yumuşayacak ve hızlanacak, " "fakat aynı zamanda daha çok işlemci gücü gerektirecek." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "goom resim genişliği" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "İşlenecek olan resmin piksel olarak genişliği." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "goom resim yüksekliği" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "İşlenecek olan resmin piksel olarak yüksekliği." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "renk dizgesi dönüştürme yöntemi" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" "Goom tarafından kullanılan renk dizgesi dönüştürme yöntemini " "seçebilirsiniz.\n" "Uygun seçimler açıklamalılar olabilir." #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico resim içinde resim efektidir.\n" "\n" "Parametreler\n" " pip_num: gelen ayarların uygulanacağı resimlerin aralığı\n" " x: x, resmin sol üst köşesine giden bağlantıdır\n" " y: y resmin sol üst köşesine giden bağlantıdır\n" " w: w resmin genişliğidir\n" " h: h resmin yüksekliğidir\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Düğme, çoklu girişler arasında hızlı geçiş yapmak için kullanılabilir.\n" "\n" "Parametreler\n" " seç: çıkışa gönderilecek olan girişin sayısı\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Kutu lekesi resmi basit olarak bulanıklaştırır.\n" "\n" "Parametreler\n" " Radius: süzgeçlerin sayısı\n" " Power: süzgeçin ne kadar sıklıkla uygulanacağı ile ilgilidir\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Bu süzgeç, düz ve donmuş resimler üreten resim gürültüsünü azaltmayı amaçlar " "(Bu sıkıştırmayı azaltır). 0 ile 3 parametleri verilmiş olabilir. Eğer bir " "parametreyi atlarsanız, önemli bir değer kaybolmuş olur.\n" "\n" "Parametreler\n" " Luma: Uzamsal luma kuvveti (öntanımlı = 4)\n" " Chroma: Uzamsal renk berraklığı kuvveti (öntanımlı = 3)\n" " Time: Maddesel kuvvet (öntanımlı = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" "Tabloları kullanan (çok yavaş) alternatif yazılım eşitleyicisi, gamma " "düzeltmesine ve ek olarak basit parlaklık, zıtlık ve doyum ayarlarına izin " "veriyor.\n" "Eğer gamma değerleri 1.0 ise Eq olarak aynı MMX iyileştirilmiş kodun " "kullanıldığına dikkat ediniz.\n" "\n" "Parametreler\n" " gamma\n" " parlaklık\n" " zıtlık\n" " doyum\n" " rgamma (kırmızı bileşen için gamma)\n" " ggamma (yeşil bileşen için gamma)\n" " bgamma (mavi bileşen için gamma)\n" "\n" "Gammalar için değerler 0.1 - 10 arasındadır, -2 - 2 zıtlık için (negative " "değerler negatif resim sonucu doğururlar), -1 - 1 parlaklık için ve 0 - 3 " "doyum için.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" "Aynen donanım eşitleyicisi gibi olan etkileşimli denetimlere sahip yazılım " "eşitleyicisi, bu, kartlar/sürücüler için donanımdaki parlaklık ve zıtlığı " "desteklemez.\n" "\n" "Parametreler\n" " parlaklık\n" " zıtlık\n" "\n" "Dikkat: Bu parametreleri kullanmak için ön pencere denetimleri " "kullanabilir.\n" "\n" "* mplayer's eq (C) Richard Felker\n" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" "Eklenti büyümesi, keyfi durum oranının karelerini almak ve onları çerçevenin " "üst ve altlarına siyah çizgiler ekleyerek farklı görünüme çevirmek (4:3 " "öntanımlı'dır) anlamına gelmektedir. Bu bize katmanları siyaha alana " "döndürme olanağı tanır böylece onlar resmi kaplamazlar.\n" "\n" "Parametreler (FIXME: daha çok yardım)\n" " Enable_automatic_shift: Katman değişimini otomatik olarak etkinleştirir\n" " Overlay_y_offset: Elle tabakayı dikey olarak değiştirir\n" " aspect: The hedef görünüm oranı (öntanımlı 4:3)\n" " Centre_cut_out_mode: 16:9 çerçevesindekileri 4:3 oranına çıkarır\n" "\n" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" "Görüntüye rastgele gürültü ekler.\n" "\n" "Parametreler:\n" " luma_strength: luma kanalına eklenen gürültünün gücü (0-100, öntanımlı: " "8)\n" " chroma_strength: chroma kanalına eklenen gürültünün gücü (0-100, " "öntanımlı: 5)\n" " quality: gürültünün kalite seviyesi. düzeltilmiş: sürekli gürültü modeli; " "temporal: gürültü modeli kareler arasında değişir; ortalama zaman: kareler " "arasında değişen daha düz gürültü modeli. (öntanımlı: ortalama zaman)\n" " type: Gürltü türü: birörnek veya veya gaussian. (öntanımlı: gaussian)\n" " pattern: Rastgele gürültünün bir (yarı) düzenli model ile karışımı. " "(öntanımlı: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "FFmpeg libpostprocess eklentisi.\n" "\n" "Parametreler\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" "Yumuşak maske / gaussian blur\n" "Dizey'in genişlik ve yüksekliğini ayarlamak mümkündür, tek sayılı ayarlar " "her iki yönde de ayarlanmıştır (min = 3x3, max = 13x11 or 11x13, genellikle " "3x3 ve 7x7 arasında bir şey olabilir.) ve keskinlik/bulanıklığın resme " "eklenecek olan ilgili büyüklüğü de ayarlanmıştır (makul bir oran -1.5 - 1.5 " "olabilir).\n" "\n" "Parametreler\n" "\n" " Luma_matrix_width: Dizey'in genişliği (tek sayı olmalı)\n" "\n" " Luma_matrix_height: Dizey'in yüksekliği (tek sayı olmalı)\n" "\n" " Luma_amount: Keskinlik/bulanıklığın ilişkili oranı (=0 devre dışı bırak, " "<0 bulanıklaştır, >0 keskinleştir)\n" "\n" " Chroma_matrix_width: Dizey'in genişliği (tek sayı olmalı)\n" "\n" " Chroma_matrix_height: Dizey'in yüksekliği (tek sayı olmalı)\n" "\n" " Chroma_amount: Keskinlik/bulanıklığın ilişkili oranı (=0 devre dışı bırak, " "<0 bulanıklaştır, >0 keskinleştir)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "dış altyazılar için yazı tipi" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "altyazı dikey konumu (pencere boyutuna göre değişir)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "altyazıların kodlanması" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c #, fuzzy msgid "DVB subtitle decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "altyazı görünümünün saniye bazında ön tanımlı süresi" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Bazı altyazı kipleri her altyazı için kesin süre vermez. Bunun için, buradan " "kesin bir süre ayarlayabilirsiniz. Ayarı sıfır yapmak bir sonraki altyazı " "gelene kadar altyazının gösterilmesi sonucunu doğurur." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "altyazı büyüklüğü" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" "Altyazı büyüklüğünü buradan ayarlayabilirsiniz. Bu ayar pencere boyutunuza " "göre yeniden değerlendirilecektir." #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "altyazı dikey konumu" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" "Altyazı dikey konumunu buradan ayarlayabilirsiniz. Bu ayar pencere " "boyutunuza göre yeniden değerlendirilecektir." #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "altyazılar için yazı tipi" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Altyazı metni olarak xine yazı tipi dizininden bir yazı tipi kullanılacaktır." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" "Altyazı metni olarak kullanılacak olan bir çerçeve yazı tipi dosyası (örn. " "bir .ttf)" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "bir freetype yazı tipinin kullanılıp kullanılmayacağı" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "alt yazılar kodlanıyor" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "Yayın akışındaki altyazı metninin kod çözümü. Bu ayar, ASCII-dışı " "karakterlerin doğru görüntülenmesi için kullanılır. Eğer ASCII-dışı " "karakterler beklediğiniz gibi görüntülenmezse, bunu oluşturan kişiye " "altyazılarda kullanılan kodlamanın ne olduğunu sormalısınız." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "eğer mümkünse hesaplanmamış OSD kullanın" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" "Hesaplanmamış OSD görüntü çerçevesinden bağımsız olarak işlenecek ve görüntü " "büyütülmüş olsa bile daima keskin olacaktır. Bu daha iyi görünecek, fakat " "tüm grafik donanımla çalışamayabilecektir. Bunun çözümü ise hesaplanmış " "OSD'dir, fakat eğer düşük çözünürlüğe sahip bir görüntüyü tam ekran " "yaparsanız bulanık gözükecektir, buna rağmen tüm grafik kartlarla çalışır." #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "MPEG yayın akışlarında kapalı başlıkları görüntüle" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" "Kapalı Başlıklar daha çok duyma özürlülere yardımcı olmayı amaçlayan " "altyazılardır." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "kapalı başlık ön/arka şeması" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Sık kullandığınız kapalı başlık işlemini seçin." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "standart kapalı başlık yazı tipi" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Standart kapalı başlık metni için yazı tipini seçin." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "italik kapalı başlık yazı tipi" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "İtalik kapalı başlık metni için yazı tipini seçin." #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "Kapalı başlık yazı tipi boyutu" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "Kapalı başlık metni için yazı tipini boyutunu seçin." #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "Ortalanmış kapalı başlıklar" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "Etkinleştirildiğinde, bireysel satırlar ortalanacaktır." #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: ByteRun1 sıkıştırmasında hata\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 şu anda desteklenmiyor\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 şu anda desteklenmiyor\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ şu anda desteklenmiyor\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: Bu hareket türü şu anda desteklenmiyor\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c #, fuzzy msgid "gdk-pixbuf image video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/video_dec/image.c #, fuzzy msgid "image video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c #, fuzzy msgid "mpeg2 based video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/video_dec/libopenhevc.c #, fuzzy msgid "HEVC video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c #, fuzzy msgid "mmal-based HW video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/video_dec/rgb.c #, fuzzy msgid "Raw RGB video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/video_dec/yuv.c #, fuzzy msgid "Raw YUV video decoder plugin" msgstr "Kapalı başlık yazı tipi boyutu" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "AsCii Art kütüphanesinin kullanan xine görüntü çıkış eklentisi" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "Color AsCii Art kütüphanesinin kullanan xine görüntü çıkış eklentisi" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "görüntü katmanı tamponlama kipi" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" "Çıkış katmanının tamponlama kipini seçin. İkili veya üçlü tamponlama, daha " "yumuşak bir çalma sonucu doğurur, fakat daha çok görüntü belleği tüketir." #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "dikey takip için bekleyiniz" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" "Tüm ekranın yeniden oluşturulması amacıyla video görüntüsünün güncellenmesi " "için senkronizasyonu etkinleştiriniz. (\"dikey takip\")." #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "görüntü renk anahtarını etkinleştirin" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" "Görüntü renk anahtarını etkinleştirme kullanımı, video görüntüsünün nerede " "ekranı kaplayacağını ekran kartına bildirir." #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "görüntü renk anahtarı" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" "Renk anahtarı, video görüntüsünün nerede ekranı kaplayacağını ekran kartına " "bildirmek için kullanılır. Eğer pencereleriniz şeffaf hale geliyorsa değişik " "değerler deneyin." #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "titreme filtreleme" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" "Titreme Filtreleme, karmaşık görünümün daha düz bir çıkış haline dönüşmesine " "olanak tanır." #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "alan eşliği" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" "Görüntü karmaşası için, alan eşliği denetimini etkinleştirin (\"hiçbiri" "\"=devre dışı)." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "video_out_directfb: donanım altresim hızlandırmasını kullanıyor.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "video_out_directfb: katman görüntü çıktısını destekler.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "video_out_directfb: katman YV12 desteği vermez!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "video_out_directfb: katman YUY2 desteği vermez!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" "video_out_directfb:bu katmanda çalmak için en az DirectFB 0.9.25 desteği " "gereklidir!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "video_out_directfb: katman tampon bellek kipini %d desteklemez !\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "video_out_directfb: katmanın desteklemediği seçenekler 0x%08x!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" "video_out_directfb: donanım tarafından hızlandırılan resim ölçeklemesini " "kullanıyor.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" "video_out_directfb: dönüştürme destekli resim ölçekleme donanım " "hızlandırmalıdır.\n" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "görüntü katman kimliği (otomatik: -1)" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "Görüntü çıkış katmanını kendi kimliğiyle birlikte seçiniz." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "video_out_directfb: kullanılan görüntü katmanı #%d.\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "xine görüntü çıkış eklentisi DirectFB kullanıyor." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "video_out_directfb: kullanılabilecek görüntü katmanı bulunamadı!\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "" "xine video çıkış eklentisi XDirectFB altında yer alan DirectFB kullanıyor." #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "directx kullanan win32 için xine video çıkış eklentisi" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: sadece paketlenmiş truecolor/directcolor desteklenmektedir (%" "d).\n" " Şu komutu 'fbset -i' veya 'fbset -depth 16' seçeneğini deneyin.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "çerçevearabellek aygıtı ismi" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" "Kullanılacak olan çerçevearabellek aygıtı ismi için dosya adını belirler.\n" "Bu ayarlar güvenlik açısından kritiktir, çünkü dosya değiştirildiğinde, xine " "bu dosyayı ilgisiz içerikle doldurmak için kullanılabilir. Bu yüzden, bu " "yüzden girdiğiniz değerin çerçevearabellek aygıtı için uygun olmasına özen " "göstermelisiniz." #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Video kipiniz tanınamadı, üzgünüm.\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: %d video RAM ara belleği kullanılabilir.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "UYARI: %s: Tampon belleğin sıfır kopyası DEVRE DIŞI çünkü sadece %d ara " "belleğe alır\n" " önerilen %d tampon belleğe göre daha düşük seviyededir. Düşürüyor\n" " çerçeve tampon bellek çözünürlüğü yardımcı olabilir.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "UYARI: %s: Tampon belleğin sıfır kopyası DEVRE DIŞI sorun çekirdek " "sürücüsündedir\n" " ekran panlamasını desteklemez (çerçeve hareketleri için kullanılır.).\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "UYARI: %s: şu anki görüntü derinliği %d. Ama, daha iyi performanstır\n" "16 bpp derinliği önerilir!\n" "\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "Linux çerçeve ara bellek aygıtı için Xine video çıkış eklentisi" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "xine görüntü çıkış eklentisi DirectFB kullanıyor." #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "hiçbir şey göstermeyen xine video çıkış eklentisi" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "OpenGL uygulayıcısı" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" "OpenGL eklentisi pek çok işleme modülü sağlar:\n" "\n" "2D_Tex_Fragprog\n" "Bu modül resimleri YUV 2D dokuları olarak indirir ve dokulanmış dilim olarak " "işler\n" "ve RGB'yi yeniden oluşturmak için dilimlere programları kullanır.\n" "Bu, modern grafik kartları için en iyi ve en hızlı yöntemdir.\n" "\n" "2D_Tex\n" "Bu modül resimleri 2D dokular olarak indirir ve dokulanmış dilim olarak " "işler.\n" "2D_Tex_Tiled\n" "Bu modül resimleri çoklu 2D dokular olarak indirir ve dokulanmış\n" "dilim olarak işler. Böylece, daha küçük oranda ama en büyük doku " "boyutlarıyla çalışılmış olur.\n" "Image_Pipeline\n" "Bu modül resimleri işlemek için glDraw() kullanır.\n" "Ancak, birkaç hızlandırılmış sürücülerle bu mümkündür.\n" "Ölçeklemeyi etkilemez.\n" "\n" "Cylinder\n" "Resimlerin dönen silindirde gösterir. Güzel efekt :)\n" "\n" "Environment_Mapped_Torus\n" "Resimleri eğilip bükülen halkada yansıtarak gösterir. Harika =)" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "OpenGL en az çerçeve oranı" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" "Hareketli işleme yolları için en az çerçeve oranı\n" "Durağan işleme yolları göz ardı edilmiştir.\n" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "çift ara belleğe almayı etkinleştir" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" "OpenGL çift ara belleğe alma işlemi için sadece parçalanan görüntüleri " "kaldırmakla kalmaz,\n" "aynı zamanda titremeyi de oldukça azaltır.\n" "Bunun performansa herhangi bir etkisi olmaz." #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "OpenGL 3D grafikleri API'sini kullanan xine video çıkış eklentisi" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "video_out_pgx32: Hata: video penceresi için DGA yakalanamıyor\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Hata: ioctl başarılamadı, kötü aygıt (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" "video_out_pgx32: Hata: '%s' bir pgx32 çerçeve ara belleği aygıtı değildir\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "video_out_pgx64: Hata: video penceresi için DGA yakalanamıyor\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "video_out_pgx64: Hata: çerçeve ara belleği aygıtını açamıyor '%s'\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Hata: Hata: ioctl başarılamadı (VIS_GETIDENTIFIER), kötü " "aygıt (%s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Hata: '%s' bir xvr100/pgx64/pgx24 çerçeve ara belleği " "aygıtı değildir\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" "video_out_pgx64: Hata: bu ekrandaki video üstyazım halen kullanımdadır\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "video_out_pgx64: Hata: pencere özellikleri ayarlanamıyor\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Uyarı: düşük görüntü hafızası, çift-ara bellekleme devre " "dışı\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Hata: yetersiz video hafızası\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Uyarı: düşük video hafızası, çift-ara bellekleme devre " "dışı\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Hata: ioctl başarılamadı (FBIOGATTR)\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "görüntü üstyazım renk anahtarı" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" "Renk anahtarı, video görüntüsünün nerede ekranı kaplayacağını ekran kartına " "bildirmek için kullanılır. Eğer videonun farklı pencerelerde gösterdiğini " "saptarsanız değişik değerler deneyin." #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "renk berraklığı anahtarlamayı etkinleştir" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" "OSD grafiklerini her çerçevede harmanlamak yerine üstyazım renk anahtarının " "üzerine çizin." #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "çoklu-tamponlamayı etkinleştir" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "Çoklu Tamponlama, daha fazla görüntü hafızası kullanılmasına yol açar." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "olanaklı ise donanım hızlandırması kullan" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "Sisteminiz desteklediğinde, grafik donanımız tarafından sağlanan donanım " "hızlandırması kullanılacaktır. Eğer bir şeyler yanlış giderse, bu " "çalışmayabilir, o zaman devre dışı bırakabilirsiniz." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" "sdl 16 bit yüzeylerine öykünmek zorundadır, ki bu da işleri yavaşlatır.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: tam ekran kipi desteklenmiyor\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "" "Simple Direct Media Layer özelliğini kullanan xine görüntü çıkışı eklentisi" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" "Libstk Surface Set-top Toolkit özelliğini kullanan xine görüntü çıkışı " "eklentisi" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "video çerçevelerinin öntanımlı sayısı" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" "Xine video çıkış sürücüsünden istenecek olan video çerçevelerinin öntanımlı " "sayısı. Bazı sürücüler kendi değerlerini koruyarak bu ayara önem " "vermeyecektir." #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI colour conversion method" msgstr "renk dizgesi dönüştürme yöntemi" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "xine görüntü çıkış eklentisi DirectFB kullanıyor." #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "kırmızı yoğunluğu" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "Kırmızı renk bileşenlerinin yoğunluğu." #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "yeşil yoğunluğu" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "Yeşil renk bileşenlerinin yoğunluğu." #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "mavi yoğunluğu" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "Mavi renk bileşenlerinin yoğunluğu." #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" "Çift ara bellekleme tüm ekranı yeniden oluşturan görüntünün güncellenmesi " "için senkron çalışacaktır (\"dikey takip\"). Bu, görüntüde titreme ve " "parçalanmayı önler, fakat bu işlem daha çok ekran kartı hafızası kullanımına " "sebebiyet verecektr." #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: çevirici yuy2 kipini destekler\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: paralel bilgisayar yv12 kipini destekler\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "video_out_vidix: VIDIX kütüphanesinin hatalı sürümüne sahipsiniz\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: Çalışan VIDIX sürücünü bulamıyor\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: kullanılan sürücü: %s by %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "görüntü üstyazım renk anahtarı kırmızı bileşeni" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "görüntü üstyazım renk anahtarı yeşil bileşeni" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "görüntü üstyazım renk anahtarı mavi bileşeni" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "x11 için libvidix kullanan xine görüntü çıkışı eklentisi" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" "linux çerçeve ara belleği için libvidix kullanan xine görüntü çıkışı " "eklentisi" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "UYARI: şu anki görüntü derinliği %d. Ama, daha iyi performanstır\n" "16 bpp derinliği önerilir!\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "%s: MIT Paylaşılan Bellek uzantısı şu and ekranda değildir.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: görüntü kipiniz algılanamadı, üzgünüm :-(\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "MIT X paylaşılan bellek uzantısını kullanan xine görüntü eklentisi" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: Xv uzantısı hazır değil.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: Xv extension şu anda hazır fakat kullanılabilir yuv12 portunu " "bulamıyorum.\n" " Ekran donanım sürücünüz Xv desteği vermiyor gibi gözüküyor?!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: Xv portunu %d çeviriciden %s donanım renk modeli çevrimi ve yükseltmesi " "için kullanıyor.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" "Çift ara bellekleme tüm ekranı yeniden oluşturan görüntünün güncellenmesi " "için senkron çalışacaktır (\"dikey takip\"). Bu, görüntüde titreme ve " "parçalanmayı önler, fakat bu işlem daha çok ekran kartı hafızası kullanımına " "sebebiyet verecektr." #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "MIT X görüntü genişlemesini kullanmak için xine görüntü eklentisi" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: Xv portunu %ld çeviriciden %s donanım renk modeli çevrimi ve " "yükseltmesi için kullanıyor.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: XvMC uzantısı şu an hazır değil.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: Xv uzantısı hazır fakat kullanılabilir durumda bir yuv12 " "portu bulamıyorum.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xvmc: Xv portunu %ld çeviriciden %s kullanıyor\n" " donanım renk modeli çevrimi ve yükselmesi için\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " idct ve hareket bedeli hızlandırılması \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " sadece hareket bedeli hızlandırılması\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " hiçbir XvMC desteği yok \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " Üstyazımlı = %d; İmzalanmamış Intra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "XvMC X görüntü uzantısını kullanması için xine görüntü eklentisi" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" "Daha iyi tamponlama için XvMC belirlemesini daha fazla çerçeveye atayın." #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" "Bazı XvMC yürütmeleri 8 kareden daha fazlasına izin verir..\n" "Bu seçenek, açıldığında, sürücülerin\n" "15 kareyi denemesine izin verir. Birleşik renk berraklığı ve canlı VDR için " "bu yapılmalıdır.\n" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Birleşik Renk Berraklığı işlemci koruması" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" "Kod çözücü çalışırken işlemci zamanını uyuyarak korur.\n" "Sadece 2.6 veya 2.4 serisi Linux çekirdeği için ve çokluortam yamasıyla " "birlikte.\n" "Deneysel.\n" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "Sorunlu NVIDIA XvMC altresim renklerini düzeltin." #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" "NVIDIA'nın XvMC kütüphanesinde kırmızı OSD renklerinin mavi veya başka\n" "gözükmelerine sebep olanen bir hata vardır.Bu seçenek temizleme gerektir.\n" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Hızlandırılmış dönüştürme yöntemi olarak bob'u kullanın." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" "Donanımca hızlandırılmış kareler için dönüştürme devrede olduğunda,\n" "çerçeve oranındaki üst ve alt alanlara göz atmalı.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "İlerleyen kareler için bob dönüştürmeyi kullanmayın." #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" "İlerleyen karelerin dönüştürmeye ihtiyaçları yoktur, bu yüzden onu devre " "dışı bırakmak\n" "daha iyi bir görüntü elde etmenizi sağlayabilir.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "Ayarlanmış OSD etkin olduğunda bob dönüştürmesini kullanmayın." #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" "Bob geri dönüştürme yatay çizgilere bazı gürültüler ekler, bu durumda\n" "onu devre dışı bırakırsanız daha iyi bir OSD resmi elde edebilirsiniz.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: XShape uzantısı uygun değildir. ayarlanmamış üstyazım devre dışı " "bırakıldı.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: pencere oluşturmakta hata, ayarlanmamış üstyazım devre dışı " "bırakıldı.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: piksel harıtası oluşturmada hata. ayarlanmamış üstyazım devre dışı " "bırakıldı.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: ayarlanmamış üstyazım oluşturuldu (%s kipi).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "otomatik boyama renk anahtarı" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "XV'yi onun otomatik boyama renk anahtarı yap." #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "çift çizgili arıtma kipi" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" "Çift çizgili arıtma kipini, Permedia kartlar için seçer. Bireysel değerler " "şunlardır:\n" "\n" "Permedia 2\n" "0 - çift çizgili filtrelemeyi devre dışı bırak\n" "1 - çift çizgili filtrelemeyi etkinleştir\n" "\n" "Permedia 3\n" "0 - çift çizgili filtrelemeyi devre dışı bırak\n" "1 - yatay doğrusal filtreleme\n" "2 - tam çift çizgili filtrelemeyi etkinleştir" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "hatalı girdi numarası" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "karakter hizalama düzeltmesi" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" "Bazı sorunlu video sürücüleri doğru çalışmaları için bazı düzeltmelere " "ihtiyaç duyarlar." #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "titreme filtreleme" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "üstyazımların tam alfa karışımını devre dışı bırak" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" "Eğer Ekran Ayarları veya DVD altyazıları gibi üstyazımlar etkin olup da bir " "performans kaybı yaşarsanız, bu seçeneği etkinleştirmek isteyebilirsiniz.\n" "Sonuç olarak, üstyazımların alfa karışımı eskisine oranla daha iyidir fakat " "işlemci kullanımı da buna bağlı olarak azalmıştır." #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: kullanılacak bir eklenti yok '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: hata, bilinmeyen ön bellek türü: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "ses ön belleklerinin sayısı" #: src/xine-engine/audio_decoder.c #, fuzzy msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Ses ön belleklerinin sayısı (her biri 8k büyüklüğünde) kendi iç kuyruğunu " "kullanır. Daha yüksek değerler uyumsuz girişler için daha düz bir çalma " "sonucu doğuracağı anlamına gelir, fakat aynı zamanda da gecikme ve bellek " "tüketiminin artması anlamına da gelir." #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: uyumsuz ses aygıtıyla gecikme hesaplaması yapmak olanaksızdır.\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "ses kartına yazma başarılamadı. Aygıtın bağlı olmadığı varsayılıyor.\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "8 bit sürücü tarafından desteklenmiyor, onu 16 bit'e çeviriyor.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "mono sürücü tarafından desteklenmiyor, stereo'ya dönüştürülüyor.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "stereo sürücü tarafından desteklenmiyor, mono'ya dönüştürülüyor.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "ses ve görüntü arasındaki senkronu sağlama yöntemi" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" "Ses ve video çalarken, en az iki saat çalışmaktadır: Sistem saati, görüntü " "karelerinin senkronize olduğu ve ses çalımının hızını belirleyen ses " "donanımındaki saat. Bu saatler, hiç bir zaman aynı hızda çalışmazlar, bazı " "fiziksel koşullar haricinde. Genel olarak, bir süre sonra iki saat kendi " "başlarına çalışmaya başlayacaktır, xine bu durumda ses ve görüntü arasındaki " "senkronizasyonu sağlamak için iki yol önerecektir:\n" "\n" "metronom geri bildirimi\n" "bu görüntü sürüklenmesinin etkisini azaltırken, bir yandan da ses " "sürklenmesini bir sınıra dayayan standart bir yoldur,\n" "\n" "yeniden örnekleme\\ Sabitlenmiş kare oranlarında sahip (DXR3 veya diğer kod " "çözücü kartlar gibi) bazı görüntü donanımları için yukarıdaki çözüm bir işe " "yaramaz, çünkü görüntü hareket edemez. Bu yüzden, ses hareket hatasını " "dengelemek için onu kısaltıp uzatarak ses akışını yeniden örnekleriz. Bu, " "ses verisinin harici kod çözücü aracılığıyla sayısal biçimlere dönüştürülen " "sayısal ürünlerde işe yaramaz." #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "yeniden örneklemeyi etkinleştir " #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" "Kodlanmış sesin örnekleme oranı ses donanımınızın olanaklarına uymuyorsa, bu " "noktada \"yeniden örnekleme\" yapmak gereklidir. Burada, yeniden " "örneklemenin devrede olması veya olmamasını ya da gerektiğinde otomatik " "olarak devreye girip girmeyeceğini siz seçebilirsiniz." #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "daima bu orada yeniden örnekle (devre dışı için 0)" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" "Bazı ses sürücüleri, o ses donanımının olanaklarını tam olarak " "bildiremezler. Değeri burada sıfırdan başka bir yere ayarlayarak, ses " "akışının verilmiş orana yeniden örneklenmesini sağlayabilirsiniz." #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "sayısal dönüşüm için eşitleme" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Eğer harici bir surround kod çözücü kullanırsanız ve ses görüntünün önünde " "veya gerisinde ise, dengelemek için buraya sabit bir değer girebilirsiniz.\n" "Değerin birimi bir PTS tıklamasıdır, ki bu da saniyenin 90000de biridir." #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "sesi eşit olarak yavaş/hızlı hızlarında çal" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" "Bu seçeneği devreye sokarsanız, çalma hızı bir mislinden hızlı olsa bile ses " "eşit duyulacaktır. Doğal olarak, ses bozulmuş gelecektir (düşük/yüksek ses " "hızında). Ses bölgesini korumak isterseniz, ses .. eklentisini uzatmayı " "denemek için deneyebilirsiniz." #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "başlangıç ses düzeyi" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Xine başladığında duyulacak olan ayrıntılı ses gürlüğü ayarı." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "başlangıçtaki ses seviyesini yeniden yapılandır" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "eğer etkin değilse, xine başlangıçta herhangi bir karşıtırıcı ayarı " "yapmayacaktır." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: üzgünüm, bu olay yaşanmamalıydı, lütfen xine uygulamasını baştan " "başlatın.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "xine-lib: buffer.c: Sonlandırıcı bir hata var: TOO MANY FREE's\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "Şu anki yapılandırma dosyası xine'nin daha yeni bir uygulaması tarafından " "değiştirilmiş durumdadır." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: UYARI: yapılandırmanız kaydedilmeyecektir\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "configfile: UYARI: yapılandırmanın şuraya %s yazılması başarılamadı\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: UYARI: büyük ihtimaller bozulmuş olan yapılandırma dosyasını " "kaldırıyor %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: UYARI: yedekleme dosyasını denetlemelisiniz %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: girdi '%s' MRL tarafından değiştirilmiş olmamalı\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "info_helper: şu anki yerel karakter ayarını çözümleyemez\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" "info_helper: desteklenmeyen dönüşüm %s -> UTF-8, hiç bir dönüşüm " "gerçekleşmedi\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": open() fonksiyonu asla çağrılamaz\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": girdi eklentisi tanımlanmadı!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: kaydedilen veriyi okuma hatası: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: aramada hata: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: giriş eklentisini okuma hatası\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: dosyaya yazmada hata % byte: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: open() fonksiyonu asla çağrılamaz\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: aramada hata\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % byte iptal edildi\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: giriş eklentisi belirtilmedi!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: hedef dizin belirtilmedi, lütfen 'media.capture.save_dir' " "seçeneğini yayınız\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "Yapılandırmada siz media.capture.save_dir ayarını yapana kadar, yayın " "akışını kaydet seçeneği devre dışı bırakıldı." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: bu kaynağın açılması/belleğe alınmasına izin verilmedi!\n" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine bu kaynaktan kaydedilmesine izin vermedi. (bir ihtimal telif hakları " "ile korunmuş malzeme?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: dosya adı verilmemiş!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: %s dosyası açılırken hata oluştu: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: bekleme bırakıldı\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: bekleme başarısız oldu: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "soket durumu alınamadı" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: İzin verilmedi\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Dosya bulunamadı\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Bağlantı Reddedildi\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "map_decoder_list: kod çözücü için yer yok, atlandı.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: bilinmeyen eklenti türü %d in %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: bilinmeyen statik bağlantılı eklenti türü %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: eklentileri göz ardı ediyor %s, yanlış iface sürümü %d " "(olması gereken %d)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "load_plugins: eklenti sınırına ulaşıldı, %s yüklenemez\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "load_plugins: eklenti sınırına ulaşıldı, statik eklenti yüklenemez\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "%s kod çözücü için öncelik" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: demuxer eklentisi %s öncelik sağlamaz, xine-lib öntanımlı " "önceliği kullanacak.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: giriş eklentisi %s öncelik sağlamaz, xine-lib öntanımlı " "önceliği kullanacak.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: %s:%s eklentisi bulundu\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: okunamayan eklenti dizinini atlıyor %s.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: stat yapamaz %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: eklenti kütüphanesini açamıyor %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: ekleni bilgisini şuradan alabilir %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: eklenti (aşama 2) eklenti kütüphanesini açamıyor %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Aman! %s eklenti bilgisi yok.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" "Öncelik bazı ortamların diğerlerine göre birden fazla kod çözücü ile " "uğraşacağı göz önüne alınarak sınıflandırılır.\n" "0 önceliği kod çözücünün öntanımlı önceliğini ektinleştirir." #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: bilinmeyen içerik bulma yöntemi %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: demuxer eklentisini kullanıyor '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: ses çıkış eklentisini yüklemede hata <%s>\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" "load_plugins: ses çıktısı otomatik bulma işlemi kullanılabilir bir sürücü " "bulamadı.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: eklenti kütüphanesi %s kaldırılamadı:\n" "%s\n" #: src/xine-engine/metronom.c #, fuzzy msgid "basic video to audio delay in pts" msgstr "bu dosya içerisinde ses ya da görüntü akışı yok.\n" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Önbelleğe alınıyor..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "'%s' yazı tipi için yanlış sürüm. beklenen %d bulunan %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "'%s-%d' yazı tipi zaten yüklü.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "'%s' yazı tipi yüklenemedi (%d < %d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "osd: %s yazı tipi FontConfig ile eşlenirken hata oluştu" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "osd: %s yazı tipi FontConfig ile yüklenirken hata oluştu" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "osd: %s yazı tipine FontConfig ile bakılırken hata oluştu" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: ft2 kütüphanesi başlatılamadı\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" "osd: yazı tipi boyutu ayarlama hatası (boyutlandırılabilir yazı tipi yok " "mudur?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: 0x%02X ile başlayan ve \"%s\" kodlamasında bulunan bilinmeyen sıralama, " "atlanıyor\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: yerel karakter seti anlaşılamadı\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: desteklenmeyen dönüşüm %s -> %s, dönüşüm yapılmadı\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: glyph yüklenirken hata oluştu\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: glyph hazırlanırken hata oluştu\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: yazı tipi belirtilmedi\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: glyph %i yüklenirken hata oluştu\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: hazırlama hatası\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "Altyazılar ve OSD için kullanılacak palet (ön yüz-sınır-arka plan)" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" "Ekranda görüntülemek için palet ve bazı altyazı kipleri kendi " "renklendirmelerini belirlemezler. Paletler formda listelenmiştir: ün yüz-" "sınır-arka plan." #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: '%s' dosyasını işleyebilmek için uygun eklenti yok\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: hata, bilinmeyen tampon bellek türü: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "video tamponlarının sayısı" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Video tamponlarının sayısı (her biri 8k büyüklüğünde) kendi iç kuyruğunu " "kullanır. Daha yüksek değerler uyumsuz girişler için daha düz bir çalma " "sonucu doğuracağı anlamına gelir, fakat aynı zamanda da gecikme ve bellek " "tüketiminin artması anlamına da gelir." #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d kare alındı, %d kare atlandı, %d kare atıldı\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: resmi pts ile atıyor % çünkü çok eski (diff : %" ").\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "görmezden gelinecek atlanan çerçeve sayısı" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" "Bu çerçeve oranlarından daha fazlası gösterilmezse, zamanında " "kodlanmadıklarındandır, xine bir uyarı gönderir." #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "görmezden gelinecek yoksayılan çerçeve sayısı" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" "Bu çerçeve oranlarından daha fazlası gösterilmezse, zamanında " "görüntülenmeleri için programlanmadıklarındandır, xine bir uyarı gönderir." #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out: üzgünüm, bu olmamalıydı. lütfen xine uygulamasını yeniden " "başlatın.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "çıktı penceresindeki yatay resim konumu" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" "Eğer video penceresinin yatay boyutu olması gerekenden büyükse, görüntünün " "yerleşeceği konumu ayarlayabilirsiniz.\n" "Konum yüzdesel olarak verilmiştir, böylece 50 değeri \"ortada\", 0 değeri " "\"çok solda\" ve 100 değeri \"çok sağda\" anlamına gelecektir." #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "çıktı penceresindeki dikey resim konumu" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" "Eğer video penceresinin yatay boyutu olması gerekenden büyükse, görüntünün " "yerleşeceği konumu ayarlayabilirsiniz.\n" "Konum yüzdesel olarak verilmiştir, böylece 50 değeri \"ortada\", 0 değeri " "\"yukarıda\" ve 100 değeri \"aşağıda\" anlamına gelecektir." #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "tüm video ölçeklemelerini pasifleştir" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" "Eğer video görüntüsünün daima kendi orijinal çözünürlüğünde gösterilmesini " "istiyorsanız, buradaki tüm resim ölçeklemelerini devre dışı " "bırakabilirsiniz.\n" "Bu doğal olarak anamorfik DVD'ler gibi 1:1 ölçeğinden farklı özelliklerde " "olduğu gibi görüntü video penceresinin boyutuyla uyumlu olamayabilecek ve " "görüntüde bozukluklar meydana gelebilecektir. Fakat diğer taraftan, XShm " "gibi bazı video sürücülerinin resim ölçeklemesi donanım hızlandırmalı " "olmadığı için, bu işlemci kullanımını dramatik olarak azaltacaktır." #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: mrl ayrıştırma hatası\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: bulunan girdi eklentisi : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: girdi eklentisi MRL [%s] dosyasını açamadı\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: MRL [%s] için girdi eklentisi bulunamadı\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: belirlenmiş demuxer %s başlatılamadı\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: hızlı giriş eklentisini ekle\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: hızlı giriş eklentisini açmada hata\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: en son_kullanılan demuxer %s başlatılamadı\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "video yoksayılıyor\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "ses yoksayılıyor\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "altresmi göz ardı ediyor\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "girdi önbellek eklentisi pasifleştirildi\n" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "alt yazı mrl dosyası '%s' açıldı\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: alt yazı mrl dosyası açılırken hata oluştu\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "" "xine: MRL dosyasındaki '%s' seçeneğinin değiştirilmesine izin verilmiyor\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: demux bunun için bulunamıyor >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: demuxer eklentisi bulundu: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine: demuxer hazır durumda. bu hızlıydı!\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: demuxer başlatılamadı\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: hiç bir demux uygun değil\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: demux başlatılamadı\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "xine: Belirtilen save_dir \"%s\" bir güvenlik riski oluşturabilir.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "Belirtilen save_dir bir güvenlik riski oluşturabilir." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: sistem yereliniz C kütüphanesi tarafından desteklenmiyor\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "ortam biçimi belirleme yöntemi" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" "xine çalınacak ortam kipini tanımak için farklı yönetmler önerir. Bireysel " "değerler şöyledir:\n" "\n" "default\n" "Önce, içerikten tanımaya, sonra da dosya uzantısıyla tanımaya çalışır.\n" "\n" "reverse\n" "Önce, dosya uzantısından tanımaya, sonra da içerikten tanımaya çalışır.\n" "\n" "content\n" "Sadece içerikten tanır.\n" "\n" "extension\n" "Sadece dosya adı uzantısından tanır.\n" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "yayınların kaydedileceği dizin" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" "Yayın akışının kaydedilmesi özelliği kullanıldığında, dosyalar sadece bu " "dizine yazılacaktır.\n" "Bu ayar güvenlik açısından kritiktir, çünkü dizinin değiştirilmesi " "denendiğinde, xine dosyaları alakasız içerikle doldurmak için kullanabilir. " "Bu yüzden, belirttiğiniz dizinin her türlü içeriğe karşı dirençli olmasına " "özen göstermelisiniz." #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" "yapılandırmada kesin değişikliklere izin ver (örn. MRL tarafından yapılan " "değişikliklere)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" "Eğer devrede ise, xine'nin sizin net bir katkınız olmayan değişiklikler " "yapmasına izin veriyorsunuz demektir. Örneğin, MRL tarafından talep edilen " "değişiklikler veya çalma listesine gömülü olan istekler yerine " "getirilecektir.\n" "Bu ayar, güvenlik açısından kritiktir, çünkü xine güvenilmeyen uzak " "kaynaklardan MRL veya çalma listelerini alabilir. Eğer onların " "yapılandırmanızı kendi istedikleri gibi değiştirmelerine izin verirseniz, " "xine'nin tamamen işleri berbat etmesiyle her şey sona erebilir." #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "Ağ yayını okumada zaman aşımı (saniye olarak)" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" "Ağ'dan gelen yayın akışını okurken zaman aşımını saniye bazında belirtir. " "Eğer kaynak yavaş veya bant genişliği yoğun ise çok küçük değerler yayın " "akışını durdurabilir, çok yüksek değerler ise bağlantı kesilirse çalıcının " "donmasına neden olabilir." #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "iletiler" #: src/xine-engine/xine.c msgid "plugin" msgstr "eklenti" #: src/xine-engine/xine.c msgid "trace" msgstr "iz" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Uyarı:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "Bilinmeyen makine:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Bilinmeyen aygıt:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Ağ erişilebilir değil" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Bağlantı reddedildi:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "Dosya bulunamadı:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Okuma hatası alınan konum:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Kütüphane yükleme hatası:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Şifrelenmiş ortam yayını bulundu" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Güvenlik iletisi:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Ses aygıtı kullanılamaz" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Yetki hatası" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "Dosya boş:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "İndeks Yeniden Yükleniyor..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Memcpy karşılaştırma yöntemleri (daha küçük olan daha iyidir):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "xine tarafından kullanılan memcopy metodu" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" "Günümüz bilgisayarlarında, büyük bellek kütlelerinin kopyalanması en pahalı " "işlemlerden biridir. Bu yüzden, xine bu kopyalamayı gerçekleştirmek için " "farklı ayarlanmış yöntemler sunar. Genellikle, en iyi yöntem otomatik olarak " "algılanacaktır." #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "" #~ "configfile: UYARI: configfile dosyasının şuraya %s yedeklenmesi " #~ "başarılamadı\n" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: bozuk mrl: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: okuma hatası (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: '%s' çözümlenemedi.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: '%s' konumuna bağlanılamadı.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "stdin: geri arama yapamaz! (% > %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: MRL ayrıştırılırken hata oluştu\n" #~ msgid "raw device set up for DVD access" #~ msgstr "DVD girişi için yeni aygıt ayarı" #~ msgid "" #~ "If this points to a raw device connected to your DVD device, xine will " #~ "use the raw device for playback. This has the advantage of being slightly " #~ "faster and of bypassing the block device cache, which avoids throwing " #~ "away important cache content by keeping DVD data cached. Using the block " #~ "device cache for DVDs is useless, because almost all DVD data will be " #~ "used only once.\n" #~ "See the documentation on raw device setup (man raw) for further " #~ "information." #~ msgstr "" #~ "Eğer bu, yeni aygıtın DVD aygıtına bağlı olduğunu gösterirse, xine çalmak " #~ "için yeni aygıtı kullanacaktır. Bu daha hızlı olma konusunda bir " #~ "avantajdır ve DVD verilerinin tutulduğu önemli bellek içeriklerinin " #~ "kaybolmasını önleyen blok belleğin atlanmasını sağlar. Aygıt belleğinin " #~ "DVD için bloke edilmesi kullanışsızdır, çünkü tüm DVD verisi sadece bir " #~ "kez kullanılacaktır.\n" #~ "Daha fazla bilgi için yeni aygıt ayarı (man raw) belgesine bakınız." #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "Yukarıdaki ileti bilinmeyen vcdimager günlük seviyesine sahip" #~ msgid "load_plugins: static plugin %s found\n" #~ msgstr "load_plugins: %s sabit eklenti bulundu\n" xine-lib-1.2/po/es.po0000644000175000017500000077446614647725152012301 0ustar meme# translation of xine-lib.hg.po to Spanish # Spanish es.po file for xine-lib. # Copyright (C) YEAR Copyright (C) 2000-2006 the xine project # Copyright (C) 2002, 2006, 2007, 2008 Free Software Foundation, Inc. # # Juan Manuel García Molina , 2002. # Carlos E. R. M. , 2006, 2007, 2008. # Cer: <<== marcas de revision. msgid "" msgstr "" "Project-Id-Version: xine-lib.hg\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2008-04-02 01:05+0200\n" "Last-Translator: Carlos E. R. M. \n" "Language-Team: Spanish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: es\n" "X-Generator: KBabel 1.11.4\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Poedit-Language: Spanish\n" "X-Poedit-Country: SPAIN\n" "X-Poedit-SourceCharset: utf-8\n" "X-Poedit-Basepath: /home/cer/Documents/babel/xine-lib/po/\n" #: lib/hstrerror.c msgid "No error" msgstr "Sin error" #: lib/hstrerror.c msgid "Unknown host" msgstr "Host desconocido" #: lib/hstrerror.c msgid "No address associated with name" msgstr "No hay dirección asociada con el nombre" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Error de servidor desconocido" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Fallo de búsqueda de nombre del host" #: lib/hstrerror.c msgid "Unknown error" msgstr "Error desconocido" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" "dvaudio: incrementando el tamaño de la memoria tampón a %d para evitar el " "desbordamiento.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/audio_dec/gsm610.c #, fuzzy msgid "GSM 6.10 audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "¡AYUDA! ¿¡Un manejador de audio exclusivamente mono-aural?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "complemento decodificador de audio a52 basado en liba52" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "Volúmen A/52" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" "Con audio A/52, puede modificar el volúmen en el decodificador. Esto tiene " "la ventaja que el sonido se ya se decodifica para el volúmen especificado, " "de modo que las operaciones posteriores como mezclado hacia abajo de canales " "trabajaran en un flujo de bits de audio del volúmen dado." #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "use A/52 compresión de rango dinámico" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" "La compresión de rango dinámico limita el rango dinámico del sonido. Esto " "significa hacer más suaves los sonidos fuertes, y más fuertes los sonidos " "flojos, de modo que puede escuchar el audio en un entorno ruidoso sin " "molestar a nadie." #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "mezcla reducida de audio a 2 canales estereo envolvente" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" "Cuando desee escuchar sonido envolvente multicanal, pero sólo tiene dos " "altavoces o un decodificador o amplificador envolvente que hace algún tipo " "de decodificación envolvente matricial como prologic, debería activar esta " "opción de modo que los canales adicionales se mezclen en la señal estéreo." #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "complemento decodificador de formato audio paso a través DTS" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() falló.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 falló.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit falló.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" "Decodificador de audio Freeware avanzado (“Freeware Advanced Audio Decoder”, " "faad)" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/audio_dec/xine_mad_decoder.c #, fuzzy msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "complemento decodificador de audio a52 basado en liba52" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "libmusepack: falló mpc_decoder_initialise\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: falló lectura mpc_streaminfo_read: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: datos después de la última trama ignorados\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: falló mpc_decoder_initialise\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: falló mpc_decoder_decode: %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "mpc: complemento decodificador de audio musepack" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out:Ya está abierto...¡PORQUÉ!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() de %s falló: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "audio_alsa_out: >>> comprobar si otro programa ya usa PCM <<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: configuración rota para éste PCM: no hay configuraciones " "disponibles: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "notificar cambios al mezclador en hardware" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "Cuando el mezclador en hardware cambia, su aplicación recibirá una " "notificiación de modo que pueda actualizar su representación gráfica de los " "ajustes del mezclador al vuelo." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : los modos soportados son" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4-canales no activado en la configuración de xine)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-canales" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-canales no activado en la configuración de xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5-canales" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5-canales no activado en la configuración de xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-canales no activado en la configuración de xine)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (travesía a/52 and DTS no activada en la configuración de xine)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() falló:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Comprobar si otro programa está ya usando PCM <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "la tarjeta de sonido puede hacer mmap" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Active esto, si su tarjeta de sonido y el driver soporta ES mapeada en " "memoria.\n" "Puede probar a activarlo y verficar, si todo funciona. Si lo hace, esto " "aumentará el rendimiento." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "dispositivo usado para salida mono" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine usará éste dispositivo para generar sonido monofónico.\n" "Vea la documentación de alsa para información de dispositivos alsa." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " estéreo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "dispositivo usado para salida estéreo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine usará este dispositivo alsa para la salida de sonido estereo.\n" "Vea la documentación de alsa para información de dispositivos alsa." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-canales" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "dispositivo usado para salida de cuatro canales" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine usará este dispositivo alsa para la salida de sonido envolvente de 4 " "canales (4.0).\n" "Vea la documentación de alsa para información de dispositivos alsa." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-canales" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "dispositivo usado para salida de 5.1 canales" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine usará este dispositivo alsa para la salida de sonido envolvente de 5 " "canales más LFE (5.1).\n" "Vea la documentación de alsa para información de dispositivos alsa." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " travesía a/52 y DTS" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " travesía a/52 y DTS" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine usará este dispositivo alsa para la salida de sonido digital envolvente " "sin decodificar. Esto puede usarse en decodificadores envolventes externos.\n" "Vea la documentación de alsa para información de dispositivos alsa." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() falló: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "dispositivo mezclador alsa" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine usará este dispositivo mezclador alsa para cambiar el volumen.\n" "Vea la documentación de alsa para información de dispositivos alsa." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" "complemento de xine de salida de audio usando dispositvos/drivers " "compatibles alsa" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "complemento de xine de salida de audio para Coreaudio/Mac OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Error" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "éxito" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "acceso denegado" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "el recurso ya está siendo utilizado" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "el objecto ya fué inicializado" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "el formato de onda especificado no está soportado" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "el búfer en memoria se ha perdido y debe ser restaurado" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "el control del búfer pedido no está disponible" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "error indeterminado dentro del subsistema DirectSound" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "dispositivo físico DirectSound no disponible" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "función no válida para el estado actual del object" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "se ha pasado un parámetro inválido" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "el objeto no soporta agregación" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "no hay driver de sonido disponible para su uso" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "interfase COM solicitada no disponible" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "otra aplicación tiene un nivel de prioridad más alto" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "memoria insuficiente" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "nivel de prioridad bajo para ésta función" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound no fué inicializado" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "función no soportada" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "error desconocido" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Incapaz de crear el objeto de sonido directo." #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "No pude poner el nivel cooperativo del sonido directo." #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "Incapaz de crear búfer secundario de sonido directo" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "No pude tocar el búfer de sonido" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "No pude parar el búfer de sonido" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "No puedo conseguir la posición del búfer" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "No puedo poner la posición del búfer" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "No puedo poner el volumen de sonido" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": búfer perdido, intentando restaurar\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "No pude bloquear el búfer de sonido directo" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "No pude desbloquear el búfer de sonido directo" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Incapaz de crear el búfer primario de sonido directo." #: src/audio_out/audio_directx2_out.c #, fuzzy, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr ": cursor de ejecución desbordado (data %u, min %u), vaciando búffers\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": no puedo crear búfer pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": no puedo destruir búfer: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ": no puedo crear condición pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": no puedo destruir mutex pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr ": comando de control desconocido %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": no puedo crear condición pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": no puedo crear mutex pthread: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "segundo complemento de xine de salida de audio usando directx" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "" "segundo complemento de xine de salida de audio para win32 usando directx" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: conectando al servidor ESD %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: conectando al servidor esd...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: no puedo conectar al servidor ESD %s: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "latencia de salida de audio esd (ajustar sincronismo a/v)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Si observa que el sonido no está sincronizado con la imagen, puede " "introducir aquí un desfase fijo para compensar.\n" "La unidad del valor es una marca PTS, que es 1/90000 segundo." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "complemento de xine de salida de audio usando esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "complemento de xine de salida de audio a fichero" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "complemento de xine de salida de audio a fichero" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "máxima longitud de intervalo en salida de sonido irixal" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Puede especificar la máxima distancia entre el audio y el video que xine " "tolerará antes de que trate de resincronizarlos.\n" "La unidad del valor es una marca PTS, que es 1/90000 segundo." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "complemento de xine de salida de audio usando libaudio IRIX" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" "complemento de xine de salida de audio para \"JACK Audio Connection Kit\"" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "complemento ficticio de xine de salida de audio " #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Abriendo dispositivo de audio %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: aviso: tasa de muestreo de %d Hz no suportada, probando 44100 " "Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" "audio_oss_out: tasa de audio: %d solicitada, %d proporcionada por el " "dispositivo\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "nombre del dispositivo de audio OSS" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "Especifica la parte raiz del nombre de dispositivo de audio, al cual el " "número del dispositivo OSS se adjunta para obtener el nombre completo del " "dispositivo.\n" "Seleccione \"auto\" si desea que xine auto detecte el parámetro correcto." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "número de dispositivo audio OSS, -1 para ninguno" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "El nombre completo del dispositivo audio se crea concatenando el nombre de " "dispositivo OSS y el número de dispositivo audio.\n" "Si no necesita un número porque está contento con el dispositivo audio por " "defecto de su sistema, póngalo a -1\n" "El rango de este valor es -1 o 0-15. Éste parámetro se ignora cuando el " "nombre del dispositivo audio OSS está puesto a \"auto\"." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "audio_oss_out: audio.device.oss_device_name = auto, sondeando devs\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Sondeo automático de dispositivo audio falló\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: usando dispositivo >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: falló al abrir el dispositivo de audio %s:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "método de sincronismo a/v a usar por OSS" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "xine puede usar diferentes métodos para mantener audio y vídeo " "sincronizados. Que ajuste funciona mejor depende en el driver OSS y el " "equipo de sonido que esté usando. Pruebe los varios métodos, si observa " "problemas de sincronismo.\n" "\n" "El significado de las opciones es como sigue:\n" "\n" "auto\n" "xine intenta detectar automáticamente detectar el ajuste óptimo\n" "\n" "getodelay\n" "usa el ioctl SNDCTL_DSP_GETODELAY para conseguir verdadero sincronismo a/v " "incluso si el driver asegura no soportar reprodución en tiempo real\n" "\n" "getoptr\n" "usa el ioctl SNDCTL_DSP_GETOPTR para conseguir verdadero sincronismo a/v " "incluso si el driver asegura no soportar el preferido ioctl " "SNDCTL_DSP_GETODELAY\n" "\n" "softsync\n" "usa sincronización software con el reloj del sistema; audio y vídeo pueden " "quedar severamente fuera de sincronismo si la velocidad del reloj del " "sistema no se ajusta exactamente a la velocidad de reproducción de su " "tarjeta de sonido\n" "\n" "probebuffer\n" "sondea el búfer de la tarjeta de sonido durante la inicialización para " "calcular la latencia para sincronismo a/v; pruebe esto si su sistema no " "soporta ninguno de los ioctls de tiempo real y observa errores de " "sincronismo después de una reproducción larga" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Sincronismo en tiempo real del driver de sonido " "desactivado...\n" "audio_oss_out: ...usaremos el reloj de tiempo real del sistema para soft-" "sync, en su lugar\n" "audio_oss_out: ...puede haber problemas de sincronización audio/vídeo\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "Latencia de salida de audio OSS audio (ajuste sincronismo a/v)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Sincronismo tiempo real driver de audio desactivado...\n" "audio_oss_out: ...ensayando tamaño del búfer de salida: %d bytes\n" "audio_oss_out: ...puede haber problemas de sincronización audio/vídeo\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: los modos soportados son" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " travesía a/52" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (travesía a/52 no activada en la configuración de xine)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "número de mezclador audio OSS, -1 para ninguno" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "El nombre completo del dispositivo mezclador se crea tomando el nombre del " "dispositivo OSS, reemplazando \"dsp\" por \"mixer\" y añadiendo el número de " "mezclador.\n" "Si no necesita un número porque está contento con el dispositivo mezclador " "por omisión de su sistema, ponga esto a -1.\n" "El rango de este valor es -1 o 0-15. Este parámetro se ignora cuando el " "nombre del dispositivo audio OSS está puesto a \"auto\"." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: función open() mezclador %s falló: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" "complemento de xine de salida de audio usando dispositivos/drivers " "compatibles OSS" # Cer: ¿pulseaudio? #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "dispositivo usado para audio a pulsos" # Cer: ¿pulseaudio? Estaba como "polypaudio" pero fuzzy. #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" "use 'server[:sink]' para definir el sumidero del dispositivo audio a pulsos." #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " travesía a/52" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" # Cer: ¿pulseaudio? #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" "complemento de xine de salida de audio usando servidor de sonido audio a " "pulsos" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" "complemento de xine de salida de audio usando dispositivos/drivers " "compatibles sun" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: fallo al abrir el dispositivo audio %s: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "Nombre del dispositivo audio de Sun" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Especifica el nombre de fichero del dispositivo audio de Sun que debe " "usarse.\n" "Este parámetro es crítico, porque cuando se cambia a un fichero diferente, " "xine puede usarse para llenar este fichero con contenido arbitrario. Por " "ello deberá ser usted cuidadoso de que el parámetro que introduzca sea " "realmente un dispositivo audio de Sun." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" "audio_sun_out: fallo al abrir el controlador del dispositivo audio %s: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" "complemento de xine de salida de audio usando dispositivos/drivers " "compatibles sun" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "disposición de altavoces" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Seleccione como están dispuestos sus altavoces, esto determina que altavoces " "usará xine para la salida de sonido. Los valores individuales son:\n" "\n" "Mono 1.0: Tiene únicamente un altavoz.\n" "Estéreo 2.0: Tiene dos altavoces, para el canal izquierdo y derecho.\n" "Auriculares 2.0: Usa auriculares.\n" "Estéreo 2.1: Tiene dos altavoces, para el canal izquierdo y derecho, y un " "superbajos para las frecuencias bajas.\n" "Envolvente 3.0: Tiene tres altavoces, para los canales izquierdo, derecho y " "trasero.\n" "Envolvente 4.0: Tiene cuatro altavoces para los canales izquierdo y derecho " "delanteros, e izquierdo y derecho traseros.\n" "Envolvente 4.1: Tiene cuatro altavoces para los canales izquierdo y derecho " "delanteros, e izquierdo y derecho traseros, y un superbajos para las " "frecuencias bajas.\n" "Envolvente 5.0: Tiene cinco altavoces para los canales izquierdo centro y " "derecho delanteros, e izquierdo y derecho traseros.\n" "Envolvente 5.1: Tiene cinco altavoces para los canales izquierdo centro y " "derecho delanteros, e izquierdo y derecho traseros, y un superbajos para las " "frecuencias bajas.\n" "Envolvente 6.0: Tiene cinco altavoces para los canales izquierdo centro y " "derecho delanteros, e izquierdo centro y derecho traseros.\n" "Envolvente 6.1: Tiene seis altavoces para los canales izquierdo centro y " "derecho delanteros, e izquierdo centro y derecho traseros, y un superbajos " "para las frecuencias bajas.\n" "Envolvente 7.1: Tiene siete altavoces para los canales izquierdo centro y " "derecho delanteros, izquierdo y derecho, e izquierdo y derecho traseros, y " "un superbajos para las frecuencias bajas.\n" "Paso libre: Su sistema de sonido recibirá sonido digital sin decodificar de " "xine. Necesita conectar un decodificador digital envolvente capaz de " "decodificar los formatos que quiera reproducir mediante la salida digital de " "su tarjeta de sonido." #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "complemento de fichero entrada" #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat demux plugin" msgstr "Complemento demultiplexor OGG" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_audio_dec: incrementando el tamaño de la memoria tampón a %d para " "evitar el desbordamiento.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_audio_dec: no pude encontrar el decodificador ffmpeg para el tipo de " "tampón 0x%X\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: intentando abrir códec nulo\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: no pude abrir el decodificador\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "complemento decodificador de audio basado en ffmpeg" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" "ffmpeg_video_dec: dimensiones de cuadro no soportadas, DR1 desactivado.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: formato de cuadro no soportado, DR1 desactivado.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: renderizado directo activado\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "ffmpeg_video_dec: formato de cuadro no soportado, DR1 desactivado.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: no pude abrir el decodificador\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: no pude abrir el decodificador (2)\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" "ffmpeg_video_dec: incrementando el tamaño de la memoria tampón a %d para " "evitar el desbordamiento.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: formato de cuadro no soportado, DR1 desactivado.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_video_dec: no pude encontrar el decodificador ffmpeg para el tipo de " "tampón 0x%X\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "complemento decodificador de vídeo basado en ffmpeg" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "calidad de postprocesado MPEG-4" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "Puede ajustar la cantidad de postprocesado aplicado a video MPEG-4.\n" "Valores más altos pueden resultar en mejor calidad, pero necesitarán más " "CPU. Valores más bajos resultarán en defectos de imagen como artefactos de " "bloque. Para contenido de alta calidad, demasiado postprocesado puede de " "hecho hacer la imagen peor emborronándola demasiado." #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "Conteo de hilos decodificando vídeo FFmpeg" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Puede ajustar el número de hilos decodificadores que pueda usar FFmpeg.\n" "Valores más altos deben acelerar la decodificación, pero depende del códec " "si se soporta procesado en paralelo. Una regla general es tener un hilo " "decodificador por cada CPU lógica (típicamente de 1 a 4). Un cambio hará " "efecto cuando se reproduzca el siguiente flujo." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "Saltarse filtro de bucle" # Cer "saltar" por"skip" suena raro. #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Puede controlar para que cuadros el filtro de bucle será saltado después de " "decodificar.\n" "Omitir el filtro de bucle acelerará la decodificación, pero puede llevarnos " "a tener artefactos. El número de cuadros para los que se salta aumenta de " "'none' a 'all' (“nada” a “todos”). El valor por omisión deja la decisión en " "manos de la implementación.\n" "Un cambio de este ajuste tendrá efecto a la reproducción de siguiente flujo." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "Elegir velocidad en vez de conformidad con la especificación" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Usted puede querer permitir trampas de velocidad que violan las " "especificaciones del códec.\n" "Hacer trampas puede acelerar la decodificación pero también provocar " "artefactos de decodificación.\n" "Un cambio de este ajuste tendrá efecto a la reproducción de siguiente flujo." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "activar renderizado directo" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "Complemento de entrada v4l radio" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/combined/flac_demuxer.c #, fuzzy msgid "FLAC demux plugin" msgstr "Complemento demultiplexor ASF" #: src/combined/nsf_decoder.c #, fuzzy msgid "NES Music audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/combined/nsf_demuxer.c #, fuzzy msgid "NES Music file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/combined/wavpack_decoder.c #, fuzzy msgid "wavpack audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/combined/wavpack_demuxer.c #, fuzzy msgid "Wavpack demux plugin" msgstr "Complemento demultiplexor Musepack" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: pista de audio vorbis indicada pero cabecera de flujo de bits vorbis no " "encontrada.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "Complemento demultiplexor annodex" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "Complemento demultiplexor OGG" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/combined/xine_theora_decoder.c #, fuzzy msgid "theora video decoder plugin" msgstr "complemento decodificador de vídeo basado en ffmpeg" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "" "vorbis: incrementando el tamaño de la memoria tampón a %d para evitar el " "desbordamiento.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "complemento decodificador de audio vorbis" #: src/demuxers/demux_4xm.c #, fuzzy msgid "4X Technologies (4xm) demux plugin" msgstr "Complemento demultiplexor annodex" #: src/demuxers/demux_aac.c #, fuzzy msgid "ADIF/ADTS AAC demux plugin" msgstr "Complemento demultiplexor ASF" #: src/demuxers/demux_ac3.c #, fuzzy msgid "Raw AC3 demux plugin" msgstr "Complemento demultiplexor ASF" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "Complemento demultiplexor IFF" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: aviso: El flujo de bits (stream) id=%d está encriptado.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Flujo de bits del medio revuelto/encriptado" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "Complemento demultiplexor ASF" #: src/demuxers/demux_aud.c #, fuzzy msgid "Westwood Studios AUD file demux plugin" msgstr "Complemento demultiplexor para fichero SND/AU" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Restaurando índice..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "demux_avi: bloque avi inválido \"%c%c%c%c\" en posición %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: el índice del avi está roto\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" "demux_avi: falló el posicionamiento al siguiente bloque (pos %)\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "Complemento demultiplexor AVI/RIFF" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "Complemento demultiplexor True Audio (audio verdadero)" #: src/demuxers/demux_dts.c #, fuzzy msgid "Raw DTS demux plugin" msgstr "Complemento demultiplexor ASF" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c #, fuzzy msgid "Elementary MPEG stream demux plugin" msgstr "Complemento demultiplexor Musepack" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "tamaño de bloque FILM inválido\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "bloque FILM no reconocido\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "Complemento demultiplexor FILM (CPK)" #: src/demuxers/demux_flac.c #, fuzzy msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_fli.c #, fuzzy msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "Complemento demultiplexor True Audio (audio verdadero)" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, fuzzy, c-format msgid "unsupported FLV version (%d).\n" msgstr "Versión FLV no soportada (%d).\n" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "no hay flujo de vídeo ni audio en este fichero.\n" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_idcin.c #, fuzzy msgid "Id Quake II Cinematic file demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: compresión desconocida: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: compresión desconocida: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: Bloque no reconocido: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "Complemento demultiplexor IFF" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "Complemento demultiplexor pes mpeg" #: src/demuxers/demux_ipmovie.c #, fuzzy msgid "Interplay MVE Movie demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c #, fuzzy msgid "matroska & webm demux plugin" msgstr "Complemento demultiplexor pes mpeg" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c #, fuzzy msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: marco demasiado grande para el búfer" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "Complemento demultiplexor Musepack" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: Identificador de flujo de bits no reconocido, " "stream_id 0x%02x. Por favor, repórtelo a los desarrolladores de xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: ¡error! liberando. Por favor, repórtelo a los " "desarrolladores de xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: aviso: 10 bits reservados de la cabecera PES no " "encontrados\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: aviso: la cabecera PES indica que este flujo de bits puede " "estar encriptado (modo de encriptación %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "Complemento demultiplexor DVD/VOB" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "Complemento demultiplexor Musepack" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: Identificador de flujo de bits no reconocido 0x%" "02x. Por favor, repórtelo a los desarrolladores de xine.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: aviso: decodificado del flujo de bits PACK id=0x%x falló.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: aviso: 10 bits reservados de la cabecera PES no encontrados\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: aviso: la cabecera PES indica que este flujo de bits puede " "estar encriptado (modo de encriptación %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes:flujo de bits privado 1 0x%02x. Por favor, repórtelo a los " "desarrolladores de xine.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "Complemento demultiplexor pes mpeg" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "Complemento demultiplexor True Audio (audio verdadero)" #: src/demuxers/demux_nsv.c #, fuzzy msgid "Nullsoft Video demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_playlist.c #, fuzzy msgid "Playlist demux plugin" msgstr "Complemento demultiplexor OGG" #: src/demuxers/demux_pva.c #, fuzzy msgid "TechnoTrend PVA demux plugin" msgstr "Complemento demultiplexor True Audio (audio verdadero)" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c #, fuzzy msgid "RealAudio file demux plugin" msgstr "Complemento demultiplexor True Audio (audio verdadero)" #: src/demuxers/demux_real.c #, fuzzy msgid "RealMedia file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_shn.c #, fuzzy msgid "Shorten demux plugin" msgstr "Complemento demultiplexor ASF" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: parámetros de cabecera malos\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: tipo de audio no soportado: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "Complemento demultiplexor para fichero SND/AU" #: src/demuxers/demux_str.c #, fuzzy msgid "Sony Playstation STR file demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "demux_tta: la cuenta total de cuadros es demasiado alta\n" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "Complemento demultiplexor True Audio (audio verdadero)" #: src/demuxers/demux_vc1es.c #, fuzzy msgid "VC1 elementary stream demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_vmd.c #, fuzzy msgid "Sierra VMD file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "tipo de bloque VOC desconocido (0x%02X); Por favor, repórtelo a los " "desarrolladores de xine\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "tipo de compresión VOC desconocida (0x%02X); Por favor, repórtelo a los " "desarrolladores de xine\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_vox.c #, fuzzy msgid "Dialogic VOX file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_vqa.c #, fuzzy msgid "Westwood Studios VQA file demux plugin" msgstr "Complemento demultiplexor para fichero Flash Video" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" "demux_wc3movie: bloque SHOT referenció una paleta inválida (%d >= %d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" "demux_wc3movie: Hubo un problema mientras se cargaban bloques de paleta\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "Complemento demultiplexor Wing Commander III Movie (MVE)" #: src/demuxers/demux_yuv4mpeg2.c #, fuzzy msgid "YUV4MPEG2 file demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/demuxers/demux_yuv_frames.c #, fuzzy msgid "YUV frames dummy demux plugin" msgstr "Complemento demultiplexor fichero VOC" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" "complemento decodificador de subtítulos usando las capacidades " "decodificadoras en hardware de una tarjeta decodificadora DXR3" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Falló la apertura de dispositivo spu %s (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_video: escritura al dispositivo de vídeo falló (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "botón pedido no disponible\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" "Complemento decodificador de MPEGI/II usando las capacidades decodificadoras " "en hardware de una tarjeta decodificadora DXR3." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" "dxr3_decode_video: Fallí la apertura del dispositivo de control %s (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "use información Pan & Scan" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Pan & Scan\" (panorámica y escaneado) es un modo especial de visualización " "que se usa algunas veces en material codificado en MPEG. Usted puede " "especificar aquí como desea manejar ese contenido.\n" "\n" "only when forced (sólo cuando se fuerza)\n" "Use Pan & Scan sólo, cuando el contenido que esté visualizando lo fuerce.\n" "\n" "use MPEG hint (sugerencia use MPEG )\n" "Active Pan & Scan basado en la información incluida en el flujo de bits de " "video MPEG.\n" "\n" "use DVB hint (sugerencia use DVB)\n" "Active Pan & Scan basado en la información incluida en el flujo de bits DVB. " "Esto hace uso del Descriptor de Formato Activo (AFD) usado en algunos " "canales DVB europeos." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "probar de sincronizar video en cada cuadro" #: src/dxr3/dxr3_decode_video.c #, fuzzy msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" "Intenta poner una marca de tiempo de sincronización para cada cuadro. " "Normalmente esto no es necesario, porque sync es suficiente incluso cuando " "la marca de tiempo se pone sólo de vez en cuando.\n" "Esto es relevante sólo para video progresivo (la mayoría de las películas " "PAL)." #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "use modo visualización suave (smooth play)" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Activando esta opción se utilizará unmodo de visualización más suave." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "corregir las duraciones de los cuadros en flujos de bits rotos" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" "Activa una pequeña lógica que corrige la duración de los cuadros de algunos " "flujos de bits mpeg con códigos de frecuencia de cuadro equivocados. " "Actualmente se implementa una corrección de flujos de bits NTSC erróneamente " "etiquetada como PAL. Actívelo únicamente cuando se encuentre un flujo de " "bits de esa clase." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Falló al abrir el dispositivo de vídeo %s (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "dxr3_decode_video: escribir al dispositivo se bloquearía. Vaciando\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: escritura al dispositivo de vídeo falló (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" "dxr3_decode_video: AVISO: código de frecuencia de cuadro desconocido %d\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: AVISO: corrigiendo código de frecuencia de cuadro de de " "PAL a NTSC\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "número de dispositivo DXR3" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Si tiene más de un DXR3 en su computadora, puede especificar cual debe " "usarse aquí." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: falló al inicializar librte\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte sólo maneja dimensiones de vídeo que son múltiplos de " "16\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: falló en conseguir el contexto de rte.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: no pudo crear el códec.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "frecuencia de bits rte de salida mpeg (kbit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "La frecuencia de bits del codificador mpeg que que la librería librte " "debiera usar para el modo codificación DXR3's. Los valores más altos " "aumentarán la calidad y el uso de CPU." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: no puedo inicializar el contexto: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: no puedo empezar a codificar: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: No pude arrancar la librería FAME\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "calidad del codificador fame mpeg" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "La calidad del codificador mpeg de la librería fame. Más baja es más rápido " "pero da \"artefactos\" visibles. Más alta es mejor pero más lento." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "Prioridad del complemento SCR" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" "Prioridad del complemento DXR3 SCR. Valores menores de 5 significan que se " "usará el temporizador del sistema unix. Valores mayores de 5 fuerzan a usar " "el reloj interno del DXR3's como fuente de sincronismo." #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "tasa de bits salida mpeg de libavcodec (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" "La velocidad de salida (tasa de bits) que el codificador mpeg de libavcodec " "debería usar para el modo de codificado de DXR3. Valores más altos " "aumentarán la calidad y el uso de CPU.\n" "Este ajuste sólo se considera cuando el modo de calidad constante está " "desactivado." #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "modo de calidad constante" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" "Cuando se activa, libavcodec usará un modo de calidad constante " "dinámicamente comprimiendo las imágenes basado en su complejidad. Cuando se " "desactiva, libavcodec usará el modo de tasa de bits constante." #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "compresión mínima" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" "La mínima compresión a aplicar a una imagen en el modo de calidad constante." #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "cuantificador máximo" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" "La máxima compresión a aplicar a una imagen en modo de calidad constante." #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" "complemento de salida de vídeo mostrando imágenes a través de su tarjeta " "decodificadora DXR3" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Falló la apertura del dispositivo de control %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "intercambiar lineas impares y pares" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" "Intercambia los campos pares e impares de la imagen.\n" "Active esta opción para material no MPEG que produce una inestabilidad " "vertical en la pantalla." #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "añade barras negras para corregir la razón de aspecto" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Añade barras negras cuando la imagen tiene una razón de aspecto que la " "tarjeta no puede manejar por si misma Esto es necesario para mantener las " "proporciones de imagen adecuadas." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "use modo de ejecución suave para reproducción con codificador mpeg" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Activando esta opción utilizará un modo de ejecución más suave para " "contenido no MPEG." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Falló la apertura del dispositivo de vídeo %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "codificador para contenido no mpeg" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "El contenido distinto que MPEG tiene que pasar otra etapa adicional de " "codificación, porque el dxr3 sólo maneja MPEG.\n" "Dependiendo de que sea soportado por su xine, este ajuste puede ser \"fame" "\", \"rte\", \"libavcodec\" or \"none\".\n" "El codificador \"libavcodec\" hace uso del complemento ffmpeg que viene ya " "con xine, de modo que no necesita instalar una librería adicional para ello. " "Incluso mejor es que libavcodec también proporciona alta calidad con poco " "uso de la CPU. El uso de \"libavcodec\" es por tanto muy recomendado.\n" "\"fame\" y \"rte\" siguen estando, pero su soporte por xine es anticuado, " "así que pueden fallar." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" "video_out_dxr3: el codificador de MPEG libavcodec falló al iniciarse.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: el codificador de MPEG rte falló al iniciarse.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: el codificador de MPEG fame falló al iniciarse.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: codificación MPEG deshabilitada.\n" "video_out_dxr3: no pasa nada, no lo necesita para video MPEG como los DVDs, " "pero\n" "video_out_dxr3: no podrá reproducir contenido no MPEG usando éste driver de " "salida\n" "video_out_dxr3: de vídeo. Vea README.dxr3 para detalles de como configurar " "un codificador.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: No se ha compilado ningún codificador MPEG.\n" "video_out_dxr3: no pasa nada, no lo necesita para video MPEG como los DVDs, " "pero\n" "video_out_dxr3: no podrá reproducir contenido no MPEG usando éste driver de " "salida\n" "video_out_dxr3: de vídeo. Vea README.dxr3 para detalles de como configurar " "un codificador.\n" # Overlay? #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "modo de salida de vídeo (TV u overlay)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" "La manera en la que el DXR3 saca el vídeo final puede configurarse aquí. Los " "valores individuales son:\n" "\n" "letterboxed tv (TV en forma de buzón)\n" "Envía el vídeo solamente al conector de salida de TV. Éste es el modo usado " "para el televisor normal formato 4:3. El vídeo anamórfico (16:9) se verá " "mostrado como en forma de buzón , material pan&scan recortará la imagen a " "izquierda y derecha. Ésta es la configuración normal para ver la TV y actúa " "como un reproductor DVD de salón.\n" "\n" "widescreen tv (TV en pantalla ancha)\n" "Envía el vídeo solamente al conector de salida de TV. Éste modo está " "previsto para televisores de pantalla ancha formato 16:9. Contenido " "anamórfico y pan&scan llenará toda la pantalla, pero tendrá que ajustar la " "razón de aspecto del televisor manualmente a 16:9.\n" "\n" "letterboxed overlay (TV superpuesta en forma de buzón)\n" "Superponer la salida de vídeo en la pantalla del ordenador con la opción de " "conmutar al vuelo a salida de TV escondiendo la ventana de vídeo. La " "superposición se mostrará con bordes negros si es anamórfica (16:9).\n" "Este ajuste sólo es útil en el caso raro de un canal de subtítulos de un DVD " "que sólo visualicen adecuadamente en modo buzón. Un buen ejemplo son las " "siluetas animadas del comentador en \"Ghostbusters\".\n" "\n" "widescreen overlay (TV superpuesta en pantalla ancha)\n" "Superponer la salida de vídeo en la pantalla del ordenador con la opción de " "conmutar al vuelo a salida de TV escondiendo la ventana de vídeo. Esta es la " "variante común de superposición DXR3." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "superponer valor del código de color" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Valor hexadecimal del código de color RGB.\n" "Puede probar diferentes valores, si observa que las ventanas se vuelven " "transparentes cuando usa modo superpuesto DXR3." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "tolerancia de código de color de superposición" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" "Un valor mayor amplía la toleracia del código de color superpuesto.\n" "Puede probar valores más bajos, si observa que las ventanas se vuelven " "transparentes cuando usa modo superpuesto DXR3, pero partes de los bordes de " "la imagen pueden desaparecer cuando use un ajuste demasiado bajo." #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "cortar el area de superposición arriba y abajo" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Quita una linea de pixels encima y debajo de la superposición. Active esto " "si observa lineas verdes encima y debajo de la superposición." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "" "video_out_dxr3: por favor, ejecute autocal, superposición desactivada\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "modo preferido de TV" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Selecciona el modo de TV que será usado por el DXR3. Los valores " "significan:\n" "\n" "ntsc: NTSC a 60Hz\n" "pal: PAL a 50Hz\n" "pal60: PAL a 60Hz\n" "default: mantener la configuración de la tarjeta" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: falló el establecimiento del modo de video..\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: Se necesita un codificador mpeg para reproducir vídeos no " "mpeg en DXR3\n" "video_out_dxr3: Lea el README.dxr3 para más detalles.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: ERROR leyendo en fichero de inicialización de la " "superposición. ¡Ejecute autocal!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c #, fuzzy msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "El camino al dispositivo, usualmente una unidad de DVD, que desea usar para " "reproducir DVDs." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "idioma por defecto para reproducción de BluRay" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" "xine intenta usar este idioma por defecto para reproducción de BluRay. " "Mientras el BluRay lo soporte, los menús y pistas de audio se presentarán en " "este idioma.\n" "El valor debe ser un código de idioma de dos caracteres según ISO639." #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" "Esto solo necesita cambiarse si su BluRay salta a una pantalla quejándose de " "un código regional equivocado. No tiene nada ue ver con el código regional " "puesto en los reproductores de DVD, esto es puramente software." #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "unidad para la acción de salto (skip)" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: no se puede conectar a %s:%d\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: conectado con éxito al servidor cddb '%s:%d'.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "input_cdda: falló al conectar al servidor cddb '%s:%d' (%s).\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "audio CD digital (alias CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "dispositivo usado para audio CD" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "El camino al dispositivo, normalmente un lector de de CD o DVD, que desea " "usar para reproducir CDs de audio." #: src/input/input_cdda.c msgid "query CDDB" msgstr "consultar la CDDB" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" "Activa conslutas a la base de datos CDDB, que le dará titulos y nombres de " "pista adecuados para sus CDs de audio\n" "Recuerde que, a menos que use su base de datos CDDB privada, esta " "información se obtiene de un servidor en Internet que podría sacar un perfil " "de sus hábitos de escucha." #: src/input/input_cdda.c msgid "CDDB server name" msgstr "nombre del servidor CDDB" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" "El servidor CDDB usado para obtener la información de título y pista.\n" "Esta configuración es crítica para su seguridad, porque el servidor recibirá " "información acerca de sus hábitos de escucha y podría responder sus " "consultas con respuestas maliciosas. Asegúrese de poner un servidor del que " "se pueda fiar." #: src/input/input_cdda.c msgid "CDDB server port" msgstr "puerto del servidor CDDB" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" "El puerto del servidor usado para obtener la información de título y pista." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "enlentecer la unidad de disco a este factor de velocidad" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" "Puesto que algunas unidades lectoras de CD o DVD hacen un ruido considerable " "a causa de la alta velocidad de rotación del disco, xine intentará " "enlentecerlas. Con la reproducción estándar de CD o DVD, los grandes flujos " "de datos que requieren la alta velocidad de rotación no son necesarios, así " "que el enlentecimiento no afectaría el rendimiento de la reproducción.\n" "Un valor de cero desactivará el enlentecimiento." #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "input_dvb: falló al abrir el fichero de canales'%s': %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" "input_dvb: el fichero de canales dvb '%s' no es un fichero texto plano\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: falló tuner_set_channel\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "input_dvb: IGU de DVB %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: no puedo abrir dispositivo DVB\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "input_dvb: canal %d fuera de rango, poniendo a 0\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: buscando el canal %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" "input_dvb: no encontrada una coincidencia exacta para %s: probando " "coincidencias parciales\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: encontrado el canal correspondiente %s\n" # Cer: (temporal) "valores por defecto" no es la traducción exacta #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" "input_dvb: canal %s no encontrado en channels.conf, yendo a valores por " "defecto.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" "input_dvb: especificación de canal inválida, usaremos el ultimo canal " "visualizado.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "input_dvb: especificación de canal inválida, usaremos el canal 0.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" "input_dvb: se especificó mrl dvbs pero el sintonizador no aparenta ser QPSK " "(DVB-S)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: se especificó mrl dvbt pero el sintonizador no aparenta ser OFDM " "(DVB-T)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: se especificó mrl dvbc pero el sintonizador no aparenta ser QAM " "(DVB-C)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" "input_dvb: se especificó mrl dvba pero el sintonizador no aparenta ser ATSC " "(DVB-A)\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: no se puede abrir el dispositivo DVR '%s'\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "input_dvb: no se puede crear el hilo actualizador de EPG\n" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "usar corte de la zona central del DVB (zoom)" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Esto permitirá reproducción a pantalla completa de contenido en formato 4:3 " "transmitido en un cuadro 16:9." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "complemento de entrada DVB (TV Digital)" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Recordar el último canal DVB visto" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" "En autoejecución, xine recordará y cambiará al canal indicado en media.dvb." "last_channel. " #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Último canal DVB visto" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "Si se activa xine recordará y cambiará a este canal. " #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "Número de segundos hasta que la sintonización temporice." #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" "Dejar como 0 significa probar indefinidamente. Mayor que cero significa " "esperar esos segundos hasta conseguir un ajuste. El mínimo son 5 segundos." #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "Activar el IGU de DVB" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" "Activar el IGU de DVB, grabación y cambio de canal controlados por ratón." #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Número de tarjeta DVB a usar." #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" "Dejar esto a cero a menos que realmemte tenga más de 1 tarjeta en sus " "sistema." #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "input_dvd: ¡valores de \\beta darán lugar a 'dom'!\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Error al conseguir el siguiente bloque desde el DVD (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Error abriendo dispositivo DVD\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "Navegador de DVD" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "dispositivo usado para reproducción de DVD" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "El camino al dispositivo, usualmente una unidad de DVD, que desea usar para " "reproducir DVDs." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "método de desencriptación CSS" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" "Selecciona el método de desencriptado que libdvdcss usará para descifrar " "DVDs protegidos de copia. Pruebe los varios métodos, si tiene problemas " "reproduciendo DVDs cifrados." #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "Región a la cual el reproductor de DVDs dice pertenecer (1 a 8)" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "Esto solo necesita cambiarse si su DVD salta a una pantalla quejándose de un " "código regional equivocado. No tiene nada ue ver con el código regional " "puesto en los reproductores de DVD, esto es puramente software." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "idioma por defecto para reproducción de DVD" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine intenta usar este idioma por defecto para reproducción de DVD. Mientras " "el DVD lo soporte, los menús y pistas de audio se presentarán en este " "idioma.\n" "El valor debe ser un código de idioma de dos caracteres según ISO639." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "caché de lectura adelantada" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" "xine puede usar un caché de lectura adelantada para acceso al DVD.\n" "Esto puede dar lugar a reproducción a golpes en unidades lentas, pero mejora " "el impacto del cambio de capa del DVD en unidades más rápidas." #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" "Puede configurar el comportamiento cuando use el comando \"skip\" (por " "ejemplo, usando los botones de skip). Los valores individuales significan:\n" "\n" "skip program (saltar programa)\n" "se saltará un programa del DVD, que es una unidad navegacional similar a las " "marcas de índice en un CD de audio CD; éste es el comportamiento normal de " "los reproductores de DVD\n" "\n" "skip part (saltar parte)\n" "saltará una parte del DVD, que es una unidad estructural similar a las " "marcas de pista (¿canción?) en un CD de audio; las partes usualmente " "coinciden con los programas, pero las partes pueden ser mayores que los " "programas\n" "\n" "skip title (saltar título)\n" "saltará un título del DVD, que es una unidad estructural representando " "piezas completas en el DVD" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "unidad para búsqueda" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" "Puede configurar el dominio abarcado por el deslizador de búsqueda. Los " "valores individuales significan:\n" "\n" "seek in program chain (búsqueda en la cadena de programas)\n" "la búsqueda abarcará la cadena entera de programas del DVD, que es una " "unidad navigacional representando el flujo de video entero de la feature " "actual\n" "\n" "seek in program (búsqueda en programa)\n" "la busqueda abarcará un programa del DVD, que es una unidad navigacional " "representando un capítulo de la feature actual" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "modo de ejecución cuando se da el título/capítulo" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" "Puede configurar el comportamiento cuando se reproduce un DVD de un título/" "capítulo dado (p.e.: usando MRL 'dvd:/1.2'). Los valores individuales " "significan:\n" "\n" "dvd entero\n" "reproducir el dvd completo empezando en la posición especificada.\n" "\n" "un capítulo\n" "reproducir únicamente el título capítulo especificado y entonces parar" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Permiso denegado: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Fichero no encontrado: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: Fichero vacío: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "complemento de fichero entrada" #: src/input/input_file.c msgid "file browsing start location" msgstr "localización de comienzo de ojeado de ficheros" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" "El ojeador para seleccionar el fichero a reproducir comenzará en esta " "localización." #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "complemento de fichero entrada" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "complemento de fichero entrada" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "complemento de entrada gnome-vfs tal como vino con xine" #: src/input/input_helper.c msgid "list hidden files" msgstr "listar ficheros ocultos" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" "si se activa. el ojeador para seleccionar el fichero a reproducir también " "mostrará los ficheros ocultos." #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "complemento de entrada de flujo de bits" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s) falló: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: error de lectura %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Conectando servidor HTTP..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: respuesta http no válida\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: redirección 3xx: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: el estado de http no es 2xx: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: longitud del contenido = % bytes\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: tampón agotado después de %d bytes." #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "complemento de entrada http" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "Servidor delegado de HTTP" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "El nombre del servidor delegado (\"proxy\") de HTTP." #: src/input/input_http.c msgid "HTTP proxy port" msgstr "Puerto del servidor delegado de HTTP" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "El número de puerto en el servidor delegado (\"proxy\") de HTTP." #: src/input/input_http.c msgid "HTTP proxy username" msgstr "Usuario en el servidor delegado de HTTP" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "El nombre de usuario en el servidor delegado de HTTP." #: src/input/input_http.c msgid "HTTP proxy password" msgstr "Contraseña en el servidor delegado de HTTP" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "La contraseña en el servidor delegado de HTTP." #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Dominios para los cuales se ignorará el servidor HTTP delegado" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Una lista separada por comas de nombres de dominio para los cuales el " "servidor delegado de HTTP sea ignorado.\n" "Si un nombre de dominio se antecede con '=' entonces se trata como un " "nombre de servidor sólamente (se requiere coincidencia completa)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "complemento de flujo de bits mms" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "ancho de banda de red" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "Especifique aquí el ancho de banda de su conexión a Internet aquí. Esto se " "usará cuando servidores de flujos de bits ofrezcan diferentes versiones con " "diferentes requisitos de ancho de banda del mismo flujo." #: src/input/input_mms.c msgid "MMS protocol" msgstr "protocolo MMS" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Seleccione el protocolo para encapsular MMS.\n" "TCP es mejor pero puede que necesite HTTP detrás de un cortafuegos." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "complemento de entrada de flujo de bits" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "complemento de entrada de red incluido en xine" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "complemento de fichero entrada" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "complemento de fichero entrada" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "complemento de entrada de flujo de bits" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "complemento de flujo de bits pnm de entrada" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: error al crear el archivo pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: error al abrir el archivo pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: error de lectura (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: error al abrir el dispositivo %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" "input_pvr: IVTV_IOC_G_CODEC falló, ¿quizás cambió la API? (interfase para " "programación de aplicaciones)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" "input_pvr: IVTV_IOC_S_CODEC falló, ¿quizás cambió la API? (interfase para " "programación de aplicaciones)\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "complemento de entrada para WinTV-PVR 250/350" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "dispositivo usado para WinTV-PVR 250/350 (complemento pvr)" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "El camino al dispositivo de su tarjeta WinTV." #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "La dirección IP especificada es multidifusión\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "No se puede encontrar la dirección para la interfase %s:%s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) falló (¿kernel multidifusión?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "no se puede resolver '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "incapaz de conectar a '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: parando el hilo de lectura...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: hilo de lectura terminado\n" # Cer: no esoy seguro del formato. #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Abriendo >fichero:%s puerto:%d interfase:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: no se puede crear un hilo nuevo (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "complemento de entrada RTP y UDP original de xine" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "complemento de flujo de bits de entrada rtsp" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "Complemento de entrada CIFS/SMB basado en libsmbclient" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "complemento de fichero entrada" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "complemento de fichero entrada" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: falló al abrir '%s'\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "complemento de entrada de flujo de bits" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "Complemento de entrada v4l tv" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Memoria intermedia vacía..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Memoria intermedia rebosando..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Ajustando..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Nombre del sintonizador no encontrado\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "Complemento de entrada v4l tv" #: src/input/input_v4l.c msgid "v4l video device" msgstr "dispositivo vídeo v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "El camino a su dispositivo de vídeo Video4Linux." #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "dispositivo audio de entrada ALSA v4l" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" "El nombre del dispositivo de audio que corresponde a su dispositivo de vídeo " "Video4Linux." #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "Estandar v4l de TV" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" "Selecciona el estandar de TV de las señales de entrada. Ha de ser una de: " "PAL, NTSC o SECAM. " #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "Complemento de entrada v4l radio" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "dispositivo audio v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "El camino a su dispositivo de radio Video4Linux." #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: MRL mal formada. Use vcdo:/\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: pista %d no válida (rango válido: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "incapaz de abrir %s: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: incapaz de abrir %s: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "Complemento de entrada de vídeo CD" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "dispositivo usado para reproducción de VCD" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" "El camino al dispositivo, usualmente una unidad de CD o DVD, que quiere usar " "para reproducir sus VideoCDes." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: mal mrl: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: falló en conectar a '%s'\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: falló en conectar al servidor %s\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: la sesión no pudo establecerse.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" "rtsp_session: el servidor rtsp devolvió cabeceras demasiado grandes, la " "sesión no puede ser establecida.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" "rtsp_session: servidor rtsp tipo '%s' no se porta todavía. Lo sentimos.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" "input_dvd: Dispositivo %s falló al abrir durante las llamadas para ejectar\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Conectando a servidor MMS (sobre tcp)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: error de envío\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: mal formato de respuesta\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: redirección 3xx no implementada: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: estado http no 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: redirección de localización no implementada\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Conectando a servidor MMS (sobre http)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "URL inválida\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "protocolo no soportado\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "modo preferido de TV" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "modo preferido de TV" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: se recibió un mensaje del servidor mientras se leía el flujo de " "bits:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: falló en conectar '%s'\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: falló en poner el flujo de bits\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR no ha sido implementado para desplazamiento no nulo" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END no ha sido implementado todavía." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "seek no ha sido implementado todavía para" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "mal tipo de artículo" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "mal número de entrada" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "mal número de segmento" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Error en conseguir número de segmento actual" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Debería haber convertido esto arriba" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "falló en encontrar un dispositivo con un VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "se pasó un parámetro de clase nula" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Tipo de entrada actual incorrecta" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "la selección no tiene entrada RETURN" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "se seleccionó DEFAULT, pero PBC no está activado." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "la selección no tiene entrada NEXT" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "la selección no tiene entrada PREVIOUS" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Tipo de evento desconocido: " #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" "Complemento de entrada Video CD con PBC y soporte para: (X)VCD, (X)SVCD, " "HQVCD, CVD ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "tipo por defecto VCD a usar en autoreproducción" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "La unidad de reproducción VCD a usar cuando ninguna se especifica en un MRL, " "p.e. vcd:// o vcd:///dev/dvd:" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "Unidad de CD-ROM usada para VCD cuando no se da ninguno" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Que usar si no se especifica unidad. Si la configuración está vacía, xine " "buscará unidades CD." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "rango de la barra deslizadora de posiciones del VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" "rango que la barra deslizadora de posiciones del flujo de bits representa al " "reproducir un VCD." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "¿Memoria intermedia de lectura adelantada del VCD?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" "La clase puede llevar a reproducción temblorosa en máquinas de gama inferior." #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "automáticamente avanzar pista/entrada en el VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Si se activa, deberíamos avanzar automáticamente a la siguiente entrada o " "pista. Se usa sólo cuando el control de reproducción (PBC) está desactivado." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "mostrar LIDs de VCD 'rechazados' " #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" "Algunas listas de IDs de reproducción (LIDs) se marcan como no mostrables, " "pero puede verlas en la lista de MRL si se activa esto. Las entradas " "rechazadas se marcan con un asterisco (*) anexado al MRL." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "Cadena de formato VCD para pantalla banderola" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" "formato VCD usado en el título del GUI. Similar al comando Unix date. Los " "especificadores de formato empiezan con un símbolo de porcentaje. Los " "especificadores son:\n" " %A : Información del álbum \n" " %C : Contador del volúmenes VCD - el número de CDs en la colección.\n" " %c : Número del volúmen VCD - el número del CD en la colección.\n" " %F : El formato VCD, p.e.: VCD 1.0, VCD 1.1, VCD 2.0, o SVCD\n" " %I : El tipo de la entrada/segmento/reproducción actual, p.e:. ENTRY, " "TRACK, ...\n" " %L : El ID de la lista de ejecución con el prifijo \" LID\" si existe\n" " %N : El número actual de lo de arriba - un número decimal\n" " %P : El ID del editor\n" " %p : El ID del preparador\n" " %S : Si estamos en segmento (menú), el tipo de segmento\n" " %T : El número de pista\n" " %V : El ID del juego de volúmenes\n" " %v : El ID del volúmen\n" " Un número entre 1 y el contador de volúmenes.\n" " %% : a %\n" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "Cadena de formato VCD para campo de comentario" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "Formato VCD usado en el el título del GUI. Similar al comando Unix date. Los " "especificadores de formato empiezan con un símbolo de porcentaje. Los " "especificadores son %A, %C, %c, %F, %I, %L, %N, %P, %p, %S, %T, %V, %v, y %" "%.\n" "Vea la ayuda para title_format para ver su significado." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "Máscara de banderas de depuración VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" "Para depurar errores en el complemento VCD. Los valores de la máscara son:\n" " 1: Meta información\n" " 2: Eventos de entrada (teclado/ratón) \n" " 4: Análisis sintáctico de MRL\n" " 8: Llamadas a rutinas externas\n" " 16: Llamadas a rutinas\n" " 32: Cambios en LSN\n" " 64: Control de reproducción\n" " 128: Depurando desde CDIO\n" " 256: Búsquedas a localización determinada\n" " 512: Búsquedas para encontrar la localización actual\n" "1024: Cuadro congelado\n" "2048: Depurando desde VCDINFO\n" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "camino a los codificadores RealPlayer" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "Si tiene instalado RealPlayer, indique aquí el camino a su directorio de " "codificadores (codecs). Puede encontrar fácilmente el directorio de " "codificadores buscando un fichero llamado \"drvc.so\" en él. Si xine puede " "encontrar los códecs de RealPlayer, los usará para decodificar el contenido " "RealPlayer para usted. Consulte el FAQ de xine FAQ para más información " "sobre cómo instalar los codificadores." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (audio) No puedo resolver símbolos - dll incompatible: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" "libareal: falló la inicialización del decodificador, código de error: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" "libareal: falló la configuración de tipo de decodificador, código de error: " "0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: Ostras, ¿puede real hacer más de dos canales?\n" # Cer: dudoso #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" "complemento decodificador de audio basado en exclusivamente binario “real”" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" "libreal: ¡Error resolviendo símbolos! (¿incompatibilidad de versión?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" "complemento decodificador de vídeo basado en exclusivamente binario “real”" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "camino a los codificadores Win32" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "Si tiene instalado los paquetes de codificador (codec) Quicktime de Windows " "o Apple , indique aquí el camino a su directorio de codificadores. Si xine " "puede encontrar los codificadores Quicktime de Windows o Apple, los usará " "para decodificar flujos diversos de Windows Media y Quicktime para usted. " "Consulte el FAQ de xine FAQ para más información sobre cómo instalar los " "codificadores." #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "complemento decodificador de audio dv" #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime binary-only codec based video decoder plugin" msgstr "" "complemento decodificador de vídeo basado en exclusivamente binario “real”" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ¡Falló ICOpen! ¿codec %08lx desconocido / parámetros equivocados?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "w32codec: Falló ICDecompressGetFormat (%.4s %08lx/%d): Error %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: Falló ICDecompressQuery: Error %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: Falló ICDecompressBegin: Error %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ¡Falló DS_VideoDecoder! ¿codec %08lx desconocido / parámetros " "equivocados?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ¡Falló DMO_VideoDecoder! ¿codec %08lx / desconocido / parámetros " "equivocados??\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: Falló el arranque del decodificador. ¿está '%s' instalado?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Formato de audio no apropiado\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) error en acmStreamOpen %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Error inicializando audio DirectShow\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Error inicializando audio DMO\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "complemento binario win32 codec de vídeo" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "complemento binario win32 codec de audio" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" "Este filtro estirará el tiempo, reproduciendo el flujo de datos mas rápido o " "más lento por un factor.Es paso se puede preservar opcionalmente, de modo " "que es posible, por ejemplo, usarlo para visualizar una película en menos " "tiempo del que fué originalmente rodada.\n" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "Estirar el tiempo en un factor dado, opcionalmente manteniendo el tono" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" "Funciones upmix (mezclador mejorador). p.e:. Tomar la entrada estereo y " "generar salida Surround 5.1.\n" "Parámetros\n" " cut_off_freq\n" "\n" "Nota: es posible usar la ventana de control de la interfaz para ajustar " "estos parámetros.\n" "\n" #: src/post/audio/upmix.c msgid "upmix" msgstr "mezcla mejorada (“upmix”)" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" "Este filtro mezclador mejorará {upmix} un flujo de datos mono a estéreo, " "duplicando los canales. Alternativamente, uno puede usar este complemento " "para escuchar sólo un canal de un flujo de datos dado.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": mejorando Mono a Stereo.\n" # Cer: ¿upmixing? #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" ": mejorando un canal simple desde el %d canal del flujo original.\n" msgstr[1] "" ": mejorando un canal simple desde los %d canales del flujo original.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": dispositivo audio incapaz de AO_CAP_MODE_STEREO.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "convierte mono a estéreo" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" "Normaliza el audio maximizando el volumen sin distorsionar el sonido.\n" "\n" "Parámetros: Método: 1: usa una muestra única para nivelar las variaciones " "vía la media ponderada standard de las muestras pasadas (por defecto); 2 usa " "varias muestras para nivelar las variaciones vía la media ponderada standard " "de las muestras pasadas.\n" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "Normalizar el volumen" # Cer: pulldown: se refiere a curiosos mecanismos de adaptación # de las diferentes frecuencias de cuadro entre pelicula y vídeo # (ver http://en.wikipedia.org/wiki/Telecine#2:3_pulldown). # Ignoro que nombre puede tener en español. Lo de “pulldown” # viene del arrastre de la pelicula, de la que se tira con una uña # en la cámara #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" "Complemento avanzado tvtime/desentrelazador con detección de conversión de " "frecuencia de cuadro en el telecine (“pulldown”)\n" "Este complemento trata de suministrar mecanismos de desentrelazado " "comparables a reproductores de alta calidad progresivos de DVD y los así " "llamados dobladores de linea, para usar con monitores de ordenador, " "proyectores y otros dispositivos de visualización progresiva.\n" " \n" "Parámetros\n" "\n" " Method (método): Seleccione el método/algoritmo de desentrelazado a usar; " "ver abajo para explicación de cada método.\n" "\n" " Enabled (activado): Activar/desactivar el complemento.\n" "\n" " Pulldown (ajuste de telecine): Escoger el algoritmo de detección de ajuste " "de telecine 2-3. Las películas de 24 CPS (cuadros por segundo) que han sido " "convertidas a NTSC con ese ajuste, pueden ser detectadas e inteligentemente " "reconstruidas a sus cuadros originales (no entrelazados).\n" "\n" " Framerate_mode (modo de cadencia de cuadro): Seleccionar 'full' (completo) " "desentrelazará cada campo a un único cuadro en calidad de televisión y más " "allá. Esta característica efectivamente dobla la cadencia de cuadro, " "mejorando la suavidad. Note, sin embargo, que los 59.94 CPS no son posibles " "con un kernel Linux 2.4 (que usa una frecuencia de interrupción de 100Hz). " "Un RedHat más moderno y los kernels 2.6 usan una frecuencia mayor (512 y " "1000, respectivamente) y deberían funcionar bien.\n" "\n" " Judder_correction (corrección de vibración): Una vez que ajuste de " "telecine 2-3 está activado y se detecta que tenemos una película, es posible " "reducir la cadencia de cuadro a la original (24 CPS). Esto distribuirá los " "cuadros uniformemente en el tiempo, coincidiendo con la velocidad con que " "fueron rodados y eliminando el efecto de vibración.\n" "\n" " Use_progressive_frame_flag (use bandera de cuadro progresivo): Flujos de " "datos MPEG2 bien creados usan una bandera para indicar material progresivo. " "Este ajuste controla si nos fiamos de esta bandera o no (algunos flujos de " "datos mpeg2 raros y erróneos la ponen mal).\n" "\n" " Chroma_filter: DVD/MPEG2 usa un formato de imagen entrelazado que tiene " "una resolución cromática vertical muy pobre. Sobremuestreando el croma con " "propósitos de desentrelazar puede causar la ocurrencia de algunos artefactos " "(pe, bandas de color). Use esta opción para emborronar el croma " "verticalmente después de desentrelazar para quitar los artefactos. Aviso: " "usa intensivamente la cpu\n" "\n" " Cheap_mode (modo barato): Esto saltará la compleja conversión de imagen " "YV12->YUY2, engañando a las rutinas tvtime/dscaler como si estuvieran " "todavía manejando imágenes YUY2. Por supuesto, esto no es correto, no todos " "los píxeles serán evaluados por los algoritmos para decidir las regiones a " "desentrelazar y el croma se procesará por separado. No obstante, permite a " "la gente con sistemas no tan rápidos probar algoritmos desentrelazantes, en " "un toma y daca entre calidad y uso de cpu.\n" "\n" "* Usa varios algoritmos de los proyectos tvtime y dscaler.\n" "Deinterlacing methods (métodos de desentrelazado): (No todos los métodos " "está disponibles para todas las plataformas)\n" "\n" # Pull down es demoler, pero... no pega. #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" "complemento desentrelazador avanzado con detección de ajuste de frecuencia " "de cuadro en el telecine" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: No hay métodos de desentrelazado disponibles, saliendo.\n" # Cer: no se que quieren decir. #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "Vaya un GOOM" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "cuadros por segundo a generar" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Con más cuadros por segundo, la animación será más suave y rápida, pero " "también requiere más potencia de CPU." # Cer: ¿goom? #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "anchura de imagen goom" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "La anchura en píxeles de la imagen a ser generada." # Cer: ¿goom? #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "altura de imagen goom" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "La altura en píxeles de la imagen a ser generada." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "método de conversión del espacio de color" # Cer: ¿goom? #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" "Puede escoger el método de conversión del espacio de color usado por goom.\n" "Las selecciones disponibles deberían ser autoexplicativas." #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico hace efectos simples de imagen en imagen.\n" "\n" "Parámetros\n" " pip_num: el número de la ranura {slot} de la imagen a la que aplica los " "siguientes ajustes\n" " x: la coordenada x de la esquina superior izquierda de la imagen\n" " y: la coordenada y de la esquina superior izquierda de la imagen\n" " w: anchura de la imagen\n" " h: altura de la imagen\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "Mosaico es un post-complemento de imagen en imagen (“pip”) " #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Switch (conmutador) puede ser usado para conmutar rápidamente entre " "múltiples entradas.\n" "\n" "Parámetros\n" " select (seleccionar): el número de la entrada que se pasará a la salida\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" "Switch es un post-complemento capaz de conmutar en cualquier momento entre " "dos flujos diferentes" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Box blur (caja borrosa) hace un emborronamiento simple de la imagen.\n" "\n" "Parámetros\n" " Radius (radio): tamaño del filtro\n" " Power (potencia): cuan a menudo debería ser aplicado el filtro\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "filtro caja borrosa de mplayer" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Este filtro trata de reducir el ruido de imagen produciendo imágenes suaves " "y haciendo la foto fija realmente fija (esto debería mejorar la " "compresibilidad). Puede dársele de 0 a 3 parámetros. Si omite un parámetro, " "se inferirá un valor razonable\n" "\n" "Parámetros\n" " Luma (¿luminancia)?: Fuerza espacial de luma (por defecto = 4)\n" " Chroma (crominancia): Fuerza espacial de chroma (por defecto = 3)\n" " Time (tiempo): Fuerza temporal (por defecto = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "“3D Denoiser” (filtro variable pasobajo antiruido)" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" "Ecualizador en software alternativo que usa tablas de búsqueda (muy lento), " "permitiendo corrección gamma además de ajustes simples de brillo, contraste " "y saturación.\n" "Observe que usa el mísmo código optimizado para MMX que 'eq' si todos los " "valores gamma son 1.0\n" "\n" "Parámetros\n" " gamma\n" " brightness (brillo)\n" " contrast (contraste)\n" " saturation (saturación)\n" " rgamma (gamma para el componente rojo)\n" " ggamma (gamma para el componente verde)\n" " bgamma (gamma para el componente azul)\n" "\n" "Los rangos de valores son 0.1 - 10 para los gammas, -2 - 2 para contraste " "(valores negativos producen una imagen negativa), -1 - 1 para brillo y 0 - 3 " "para saturación.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "Ecualizador de vídeo en software" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" "Ecualizador en software con controles interactivos justo como el ecualizador " "en hardware, para tarjetas/drivers que no soportan controles de brillo y " "contraste en hardware.\n" "\n" "Parámetros\n" " brightness (brillo)\n" " contrast (contraste)\n" "\n" "Note: es posible usar los la ventana de control de la interfaz para ajustar " "estos parámetros.\n" "\n" "* mplayer's eq (C) Richard Felker\n" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "ecualizador blando de vídeo" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" "El complemento expand (expansor) está pensado para tomar cuadros de razón de " "aspecto arbitrario y convertirlos a una razón de aspecto diferente (4:3 por " "omisión) añadiendo barras negras arriba y abajo del cuadro. Esto nos permite " "desplazar superposiciones abajo en la zona negra de modo que no cubran la " "imagen\n" "\n" "Parámetros (ARREGLADME: mejor ayuda)\n" " Enable_automatic_shift: Activar desplazamiento automático de la " "superposición\n" " Overlay_y_offset: Manualmente desplazar la superposición verticalmente\n" " aspect: La razón de aspecto resultante deseada (4:3 por defecto)\n" " Centre_cut_out_mode: extrae la imagen 4:3 contenida en un cuadro 16:9\n" "\n" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" "añade bordes negros al tope superior e inferior del vídeo para expandirlo a " "la razón de aspecto 4:3" #: src/post/planar/fill.c #, fuzzy msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" "añade bordes negros al tope superior e inferior del vídeo para expandirlo a " "la razón de aspecto 4:3" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" "Añade ruido aleatorio al vídeo.\n" "\n" "Parámetros:\n" " luma_strength: fuerza del ruido añadido al canal luma (0-100, omisión: 8)\n" " chroma_strength: fuerza del ruido añadido al canal chroma (0-100, omisión: " "5)\n" " quality: nivel de calidad del ruido. fixed: patrón de ruido constante; " "temporal: el patrón de ruido cambia entre cuadros; averaged temporal: " "smoother patrón de ruido más suave que cambia entre cuadros. (omisión: " "averaged temporal)\n" " type: Tipo de ruido: uniforme or gaussiano. (omisión: gaussiano)\n" " pattern: Mezcla ruido aleatorio con un patrón (semi)regular. (omisión: " "False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" #: src/post/planar/noise.c msgid "Adds noise" msgstr "añade ruido" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "Complemento FFmpeg libpostprocess.\n" "\n" "Parámetros\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "complemento para libpostprocess ffmpeg " #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" "Unsharp mask / gaussian blur (máscara de des-nitidez / borrosidad " "gaussiana)\n" "Es posible ajustar el ancho y altura de la matriz, tamaño impar en ambas " "direcciones (min = 3x3, máx = 13x11 o 11x13, usualmente algo entre 3x3 y " "7x7) y la cantidad relativa de nitidez/borrosidad a añadir a la imagen (un " "rango adecuado sería -1.5 - 1.5).\n" "\n" "Parámetros\n" "\n" " Luma_matrix_width: Anchura de la matriz (debe ser impar)\n" "\n" " Luma_matrix_height: Altura de la matriz (debe ser impar)\n" "\n" " Luma_amount: Cantidad relativa de nitidez/borrosidad (=0 disable, <0 blur, " ">0 sharpen)\n" "\n" " Chroma_matrix_width: Anchura de la matriz (debe ser impar)\n" "\n" " Chroma_matrix_height: Altura de la matriz (debe ser impar)\n" "\n" " Chroma_amount: Cantidad relativa de nitidez/borrosidad (=0 disable, <0 " "blur, >0 sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" "Unsharp mask & gaussian blur (máscara de des-nitidez y borrosidad gaussiana)" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "tipografía para subtítulos externos" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "" "desplazamiento vertical de los subtítulos (relativo al tamaño de ventana)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "complemento decodificador de subtítulos CMML" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "codificado de los subtítulos" #: src/spu_dec/spu_decoder.c #, fuzzy msgid "DVD/VOB SPU decoder plugin" msgstr "Complemento demultiplexor DVD/VOB" #: src/spu_dec/spudvb_decoder.c #, fuzzy msgid "DVB subtitle decoder plugin" msgstr "complemento decodificador de subtítulos CMML" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "duración por defecto de la exhibición de los subtítulos en segundos" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Algunos formatos de subtítulos no dan explícitamente una duración para cada " "subtítulo. Para estos, puede definir aquí una duración por defecto. Ponerla " "a cero hará que el subtítulo se siga mostrando hasta que aparezca el " "siguiente." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "complemento decodificador de subtítulos externo" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "tamaño de subtítulo " #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" "Puede ajustar el tamaño de los subtítulos aquí. El ajuste será evaluado " "relativo al tamaño de la ventana." #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "desplazamiento vertical de los subtítulos" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" "Puede ajustar la posición vertical de los subtítulos aquí. El ajuste será " "evaluado relativo al tamaño de la ventana." #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "tipografía para los subtítulos" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Tipografía del directorio de xine que será usada para el texto de los " "subtítulos." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" "Un fichero de tipografía tipo linea (pe: a.ttf) que será usada para el texto " "de los subtítulos." #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "si debemos usar una tipografía freetype" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "codificación de los subtítulos" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "La codificación del texto de los subtítulos en el flujo de datos. Este " "ajuste se usa para generar caracteres no ASCII correctamente. Si los " "caracteres no ASCII no se muestran de la forma que usted espera, pregúntele " "al creador de los subtítulos que codificación se usó." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "use OSD sin escalar si es posible" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" "La visualización en pantalla (OSD) se generará independientemente del cuadro " "de video y siempre será nítida, incluso aunque el vídeo esté magnificado. " "Esto tendrá mejor apariencia, pero no funciona con todos los equipos " "gráficos. La alternativa es OSD escalado, que será borroso si aumenta una " "vista a baja resolución a pantalla completa, pero trabaja con todas las " "tarjetas." #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "complemento demultiplexor sputext" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "mostrar los subtítulos en flujos MPEG-2" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" "Son subtítulos (Closed Captions) pensados mayormente para ayudar a las " "personas con deficiencias auditivas." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "esquema de subtitulado en primer o segundo plano" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Escoja su renderizado favorito de los subtítulos." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "tipografía estándard de subtitulado" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Escoja la fuente tipográfica estándard para el texto del subtitulado." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "tipografía cursiva de subtitulado" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "Escoja la fuente tipográfica cursiva para el texto del subtitulado." #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "tamaño de la tipografía del subtitulado" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" "Escoja el tamaño de la fuente tipográfica para el texto del subtitulado." #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "subtitulado ajustado al centro " #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" "Cuando se activa, el subtitulado se posicionará en el centro de las lineas " "individuales." #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "complemento decodificador de subtitulado para sordos" # Cer: no lo tengo claro #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "%s: evento de entrada escribe: %s.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "%s: ¡buffer_pool_alloc() falló!\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "%s: vaciar tampones (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "%s: cerrando el hilo rpc (temporizado: %d ms) ...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "%s: cancelando el hilo rpc en la función %d...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "%s: uniendo el hilo rpc ...\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "%s: hilo rpc unido.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "%s: falló en abrir '%s' (%s)\n" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "expiró el límite de tiempo durante la fase de configuración" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "%s: fallo al crear el socket para el puerto %d (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "%s: falló en conectar al puerto %d (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "%s: abriendo socket (puerto %d) con éxito, fd = %d\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "%s: conectando a vdr.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "%s: falló al resolver el nombre de equipo '%s' (%s)\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "%s: la conexión a todos los sockets (puerto %d .. %d) tuvo éxito.\n" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" "%s: ¡MRL (%s) inválido! El MRL debiera empezar con vdr://camino/a/flujo/fifo " "o netvdr://equipo:puerto donde ':puerto' es opcional.\n" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: no puedo crear nuevo hilo (%s)\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "complemento de dispositivo de visualización VDR" #: src/vdr/post_vdr_audio.c #, fuzzy msgid "modifies every audio frame as requested by VDR" msgstr "modifica todos los cuadros de vídeo como lo pida el VDR" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "modifica todos los cuadros de vídeo como lo pida el VDR" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr ": vep: (%d, %d)-(%d, %d)@%lg\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: error haciendo descompresión ByteRun1\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 no está soportado de momento\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 no está soportado de momento\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ no está soportado de momento\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: Este tipo anim no está soportado de momento\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "complemento decodificador de vídeo plano de bits en bruto" #: src/video_dec/gdkpixbuf.c #, fuzzy msgid "gdk-pixbuf image video decoder plugin" msgstr "complemento decodificador de vídeo basado en ffmpeg" #: src/video_dec/image.c #, fuzzy msgid "image video decoder plugin" msgstr "complemento decodificador de vídeo basado en ffmpeg" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c #, fuzzy msgid "mpeg2 based video decoder plugin" msgstr "complemento decodificador de vídeo basado en ffmpeg" #: src/video_dec/libopenhevc.c #, fuzzy msgid "HEVC video decoder plugin" msgstr "complemento decodificador de audio dv" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c #, fuzzy msgid "WebM (VP8/VP9) video decoder plugin" msgstr "complemento decodificador de vídeo basado en ffmpeg" #: src/video_dec/mmal.c #, fuzzy msgid "mmal-based HW video decoder plugin" msgstr "complemento decodificador de vídeo basado en ffmpeg" #: src/video_dec/rgb.c #, fuzzy msgid "Raw RGB video decoder plugin" msgstr "complemento decodificador de vídeo plano de bits en bruto" #: src/video_dec/yuv.c #, fuzzy msgid "Raw YUV video decoder plugin" msgstr "complemento decodificador de vídeo plano de bits en bruto" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "" "Complemento de xine de salida de vídeo usando la librería de arte ascii" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "" "Complemento de xine de salida de vídeo usando la librería de arte ascii a " "color" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "modo de capa de vídeo tamponeado" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" "Seleccione el modo tamponeado de la capa de salida. Doble o triple " "tamponeado (buffering) da una reproducción más suave, pero consume más " "memoria de vídeo." #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "esperar al retrazado vertical" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" "Activa la sincronización de la actualización de la imagen de vídeo con el " "repintado de la pantalla entera (\"retrazado vertical\")." #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "activar llave de color de vídeo" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" "Activar el uso de una llave de color para decirle a la tarjeta gráfica dónde " "superponer la imagen de vídeo." #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "llave de color de vídeo" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" "La llave de color se usa para decirle a la tarjeta gráfica donde superponer " "la imagen de vídeo. Pruebe diferentes valores si observa que las ventanas se " "vuelven transparentes." #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "filtro de parpadeo" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" "Active Filtro de Parpadeo para una salida suave en una pantalla entrelazada." #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "paridad de campo" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" "para una pantalla entrelazada, activa el control de paridad de campo(\"none" "\"=desactivado)." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "video_out_directfb: usando aceleración hardware de subimagen\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "video_out_directfb: la capa soporta salida de vídeo\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "video_out_directfb: ¡la capa no soporta YV12!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "video_out_directfb: ¡la capa no soporta YUV2!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" "video_out_directfb:¡se necesita al menos DirectFB 0.9.25 para reproducir en " "esta capa!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "video_out_directfb: ¡la capa no soporta modo tamponeado %d!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "video_out_directfb: ¡la capa no soporta las opciones 0x%08x!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "video_out_directfb: usando escalado de imagen en hardware acelerado.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" "video_out_directfb: escalado de imagen con desentrelazado es acelerado en " "hardware.\n" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "id. de la capa de vídeo (auto: -1)" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "Seleccione la capa de salida de vídeo por su id." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "video_out_directfb: usando capa de visualización nº %d.\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "complemento de xine de salida de vídeo usando DirectFB." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" "video_out_directfb: ¡no se encontró una capa de visualización usable!\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "complemento de xine de salida de vídeo usando DirectFB bajo XDirectFB." #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "complemento de xine de salida de vídeo para win32 usando directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: sólo se soporta truecolor/directcolor (color verdadero / color " "directo) empaquetado (%d).\n" " Compruebe 'fbset -i' o pruebe 'fbset -depth 16'.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "nombre del dispositivo framebuffer" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" "Especifica el nombre de fichero del dispositivo framebuffer (tampón de " "cuadro) a usarse.\n" "Este ajuste es crítico para la seguridad, porque cuando se cambia a un " "fichero diferente, xine puede usarse para llenar este fichero con contenido " "arbitrario. De modo que debería ser cuidadoso de que el valor que introduzca " "es realmente un verdadero dispositivo framebuffer." #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Lo sentimos, su modo de vídeo no fue reconocido.\n" # CER: hacer update-po, no coincide con el fuente. #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: están disponibles %d tampones de vídeo en RAM.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "AVISO: %s: Tampones “zero copy” (copia Cero) están DESACTIVADOS porque sólo " "hay\n" " disponibles %d tampones lo cual es menos que los recomendados %d " "tampones.\n" " Disminuir la resolución del tampón de cuadro podría ayudar.\n" # Cer: panning --> panoramizado # frame flips --> volteos de cuadro # Zero copy buffers --> tampones copia cero #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "AVISO: %s: Los tampones copia cero están DESACTIVADOS porque el driver del " "kernel\n" " no soporta panoramizado de pantalla (usado para volteos de cuadro ).\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "AVISO: %s: la profundidad actual de pantalla es %d. ¡Para tener mejor " "rendimiento \n" " se recomienda una profundidad de 16 bpp!\n" "\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" "Complemento de xine de salida de vídeo usando el dispositivo Linux tampón de " "cuadro (frame buffer device)" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "complemento de xine de salida de vídeo usando DirectFB." #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "Complemento de xine de salida de vídeo que no muestra nada" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "complemento de xine de salida de vídeo usando OpenGL." #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "renderizador OpenGL" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" "El complemento OpenGL provee varios módulos de renderizado (convertir datos " "en imagen):\n" "\n" "2D_Tex_Fragprog\n" "Este módulo descarga las imágenes como texturas YUV 2D y las renderiza como " "rodajas\n" "texturizadas usando fragmentos de programas para reconstruir RGB.\n" "Este es el método mejor y más rápido en las tarjetas gráficas modernas\n" "\n" "2D_Tex\n" "Este módulo descarga las imágenes como texturas 2D y las renderiza como " "rodajas texturizadas.\n" "2D_Tex_Tiled\n" "Este módulo descarga las imágenes como multiple 2D textures y las renderiza " "como rodajas \n" "texturizadas. Así esto funciona también con tamaños máximos de textura más " "pequeños.\n" "Image_Pipeline\n" "Este módulo usa glDraw() para renderizar las imágenes.\n" "Sólo está acelerado en unos pocos drivers.\n" "No interpola al escalar.\n" "\n" "Cylinder\n" "Muestra imágenes en un cilindro rotando.Bonito efecto :)\n" "\n" "Environment_Mapped_Torus\n" "Muestra las imágenes en un toro dando vueltas. Muy guais =)" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "frecuencia de cuadro mínima OpenGL" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" "Frecuencia mínima de cuadro para rutinas animadas de renderizado.\n" "Ignorado para rutinas estáticas de renderizado.\n" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "activar doble tamponeado" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" "Para OpenGL el doble tamponeado no solo quita artefactos de rajado,\n" "también reduce un montón el parpadeo.\n" "No debería impactar nada el rendimiento." #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "Complemento de xine de salida de vídeo usando la API gráfica 3D OpenGL" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx32: Error: no puedo coger el DGA pintable para la ventana de " "vídeo\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Error: falló ioctl, mal dispositivo (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" "video_out_pgx32: Error: '%s' no es un dispositivo tampón de cuadro " "(framebuffer) pgx32\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "complemento de salida de vídeo para tampón de cuadro Sun PGX32 " # Cer: Mmm, coger :-? #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx64: Error: no puedo coger el DGA pintable para la ventana de " "vídeo\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" "video_out_pgx64: Error: no puedo abrir el dispositivo tampón de cuadro " "(framebuffer) '%s'\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Error: falló ioctl (VIS_GETIDENTIFIER), mal dispositivo (%" "s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Error: '%s' no es un dispositivo framebuffer (tampón de " "cuadro) xvr100/pgx64/pgx24 \n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" "video_out_pgx64: Error: la superposición de vídeo (overlay) en esta pantalla " "ya está en uso\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "video_out_pgx64: Error: incapaz de poner las propiedades de ventana\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Aviso: memoria de vídeo baja, multi-tamponeado desactivado\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Error: memoria de vídeo insuficiente\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Aviso: memoria de vídeo baja, tamponeado-doble desactivado\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Error: falló ioctl (FBIOGATTR)\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "llave de color de superposición de vídeo" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" "La llave de color se usa para decirle a la tarjeta gráfica donde puede " "superponer la imagen de vídeo. Pruebe usando diferentes valores si ve que el " "vídeo asoma a través de otras ventanas." #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "activa llave croma (chroma keying)" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" "Dibuja gráficos VEP (OSD) encima de la llave de color de la superposición de " "vídeo en vez de mezclarlos en cada cuadro." #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "activa multi-tamponeado" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" "Multi-tamponeado incrementa el rendimiento a costa de usar más memoria " "gráfica." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" "complemento de xine de salida de vídeo para tampones-de-cuadro Sun XVR100/" "PGX64/PGX24" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "use aceleración gráfica si está disponible" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "Cuando su sistema lo soporta, se usará aceleración en hardware suministrada " "por su hardware gráfico. Esto podría no funcionar, así que lo puede " "desactivar, si las cosas van mal." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" "sdl tiene que emular superficies de16 bit, que enlentecerán las cosas.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: el modo de pantalla completa NO está soportado\n" # Cer: traducción incierta #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "" "complemento de xine de salida de vídeo usando la Capa Simple de Medios " "Directo" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" "complemento de vídeo de xine usando el \"Libstk Surface Set-top Toolkit\"" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "número por defecto de marcos de vídeo" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" "El número por omisión de cuadros de vídeo a pedir del manejador de vídeo de " "salida. Algunos manejadores invalidará este ajuste con sus propios valores." #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI colour conversion method" msgstr "método de conversión del espacio de color" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "complemento de xine de salida de vídeo usando DirectFB." #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "vdpau: No usar desentrelazado para cuadros progresivos." #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "complemento de xine de salida de vídeo usando VDPAU." #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "intensidad de rojo " #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "La intensidad de los componentes de color rojo." #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "intensidad de verde" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "La intensidad de los componentes de color verde." #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "intensidad de azul" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "La intensidad de los componentes de color azul." #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" "El doble tamponeado sincronizará la actualización de la imagen de vídeo al " "redibujado de la pantalla de video entera (\"vertical retrace\", retrazado " "vertical). Esto elimina el parpadeo y artifactos de rajado, pero usa más " "memoria gráfica." #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: el adaptador soporta el formato yuy2\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: el adaptador soporta el formato yv12\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" "video_out_vidix: Tiene usted la versión incorrecta de la librería VIDIX\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: No pude localizar el driver VIDIX que funcione\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: usando driver: %s por %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "clave de componente rojo en superposición de vídeo" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "clave de componente verde en superposición de vídeo" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "clave de componente azul en superposición de vídeo" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "complemento de salida de vídeo usando libvidix para x11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" "complemento de salida de vídeo usando libvidix para frame buffer de linux" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "%s: %s: ubicando imagen\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" "%s: => no usando la extensión de memoria compartida MIT (MIT Shared " "Memory).\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" "%s: error de memoria compartida (error de dirección) ) al ubicar imagen\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "%s: x11 error durante creación de XImage en memoria compartida\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "AVISO: la profundidad actual de la pantalla es %d. ¡Para el mejor\n" "rendimiento se recomienda una profundidad de 16 bpp!\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" "%s: la extensión de memoria compartida del MIT (MIT Shared Memory) no está " "presente en la pantalla.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: lo sentimos, su modo de vídeo no fue reconocido :-(\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" "complemento de salida de vídeo de xine usando la extensión de memoria " "compartida del MIT (MIT Shared Memory) " #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "%s: XvShmCreateImage retornó un tamaño cero\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "%s: error de memoria compartida en shmget: %s\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "%s: error de memoria compartida (error de dirección)\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: éste adaptador soporta el formato %s.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: la extensión Xv no está presente.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "%s: no se pudo abrir el puerto Xv %lu - autodetectando\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: la extensión Xv está presente pero no pude encontrar un puerto yuv12 " "usable.\n" " ¡¿Parece que su driver de hardware gráfico no soporta Xv?!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: usando puerto Xv %d del adaptador %s para conversión y escalado de " "espacio de color en hardware .\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "activar sincronismo de blanqueo vertical (vblank sync)" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" "Esta opción sincronizará la actualización de la imagen de vídeo al " "redibujado de la pantalla de video entera (\"vertical retrace\", retrazado " "vertical). Esto elimina el parpadeo y artefactos de rajado. En las tarjetas " "nvidia puede también necesitar que ejecute \"nvidia-settings" "\" (configuración de nvidia) y escoger que dispositivo de pantalla debe " "sincronizar bajo la pestaña de configuración de XVideo" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "complemento de salida de vídeo usando la extensión MIT X vídeo" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "%s: error de memoria compartida al ubicar imagen\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" "video_out_xv: error de memoria compartida en shmget: %s\n" "video_out_xv: => no usando la extensión de memoria compartida MIT (MIT " "Shared Memory).\n" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: usando puerto Xv %ld del adaptador %s para conversión y escalado de " "espacio de color en hardware .\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: extensión XvMC no presente.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: la extensión Xv está presente pero no pude encontrar un " "puerto yuv12 usable.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xvmc: usando puerto %ld de Xv del adaptador %s\n" " para conversión del espacio de color y escalado en hardware\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " compensación de movimiento y aceleración idct \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " sólo compensación de aceleración \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " sin soporte XvMC \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " Con Overlay = %d; UnsignedIntra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "complemento de vídeo de xine usando extensión de vídeo X XvMC" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "Hacer que XvMC ubique más cuadros more cuadros para mejor tamponeado." #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" "Algunas implementaciones XvMC permiten más de 8 cuadros.\n" "Esta opción, cuando se activa, hace que el manejador trate de\n" "ubicar 15 cuadros. hay que tenerlo para VDR uni cromático y en vivo.\n" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Ahorro de cpu unichrome" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" "Ahorra tiempo de CPU durmiendo mientras trabaja el decodificador.\n" "Sólo para Linux con kernel serie 2.6 series o 2.4 con parche multimedia.\n" "Experimental.\n" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "Arreglar colores de subimagen en NVIDIA XvMC con errores" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" "Hay un bug en la librería XvMC de NVIDIA que hace que el color \n" "rojo en el DEP aparezca como azul y viceversa.\n" "Esta opción proporciona un arreglo.\n" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Use «bob» como método acelerado de desentrelazado." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" "Cuando el entrelazado está activado para cuadros acelerados\n" "en hardware, alterna entre el campo superior e inferior\n" "al doble de la frecuencia de cuadro.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "No usar desentrelazado «bob» para cuadros progresivos." #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" "Los cuadros progresivos no necesitan desentrelazado, de manera\n" "que desentrelazarlos bajo demanda no resultará en una mejor imagen.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" "No usar desentrelazado «bob» mientras una escalado de VEP (OSD) está activo." #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" "El desentrelazado «bob» añade algún ruido a las lineas horizontales,\n" "de manera que desactivarlo bajo demanda debería resultar en una\n" "mejor imagen VEP (visualización en pantalla, OSD)\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: extensión XShape no disponible. Superposición no escalada " "desactivada.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: error al crear ventana . Superposición no escalada desactivada.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: error al crear pixmap (mapa de píxeles). Superposición no escalada " "desactivada.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: superposición no escalada creada (modo %s).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "llave de color autopintado" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Hacer Xv autopintar su llave de color." #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "modo de escalado bilineal" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" "Selecciona el modo de escalado bilineal para las tarjetas Permedia. Los " "valores individuales son:\n" "\n" "Permedia 2\n" "0 - desactivar filtrado bilineal\n" "1 - activar filtrado bilineal\n" "\n" "Permedia 3\n" "0 - desactivar filtrado bilineal\n" "1 - filtrado horizontal lineal\n" "2 - sactivar filtrado bilineal completo" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "puerto Xv número" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "Selecciona el número de puerto Xv a usar (0 para autodetectar)." #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "rodeo para alineamiento de paso" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" "Algunos drivers de vídeo con errores necesitan un rodeo para que funcionen " "adecuadamente." #: src/video_out/xv_common.h msgid "video display method preference" msgstr "preferencia de método de visualización de vídeo (display)" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" "Selecciona que método de salida de vídeo se prefiere. La detección se hace " "usando los nombres reportados del adaptador Xv.\n" "(Sólo aplica al detectar qué puerto Xv a usar.)" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "filtro de parpadeo" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "desactivar la mezcla alfa exacta de superposiciones" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" "Si experimenta un impacto en el rendimiento cuando la Visualización En " "Pantalla u otras superposiciones como los subtítulos de DVD están activos, " "entonces quizás quiera activar esta opción\n" "El resultado es que la mezcla alfa de superposiciones son menos precisos que " "antes, pero el uso de la CPU también disminuirá." #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: no hay disponible complemento para manejar '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: error, tipo de tampón desconocido: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "número de tampones de audio" #: src/xine-engine/audio_decoder.c #, fuzzy msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "El número de tampones de memoria de audio (cada uno tiene 8k) que xine usa " "en su propia cola. Valores más altos implican reproducción más suave de " "entradas poco fiables, pero también aumentan la latencia y el consumo de " "memoria." #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: cálculo de retardo imposible con un dispositivo de sonido no " "disponible\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" "la escritura a la tarjeta de sonido falló. Supondremos que el dispositivo se " "desconectó.\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "8 bits no soportados por el driver, convirtiendo a 16 bits.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "mono no soportado por el driver, convirtiendo a estéreo.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "estéreo no soportado por el driver, convirtiendo a mono.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "método para sincronizar audio y vídeo" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" "Cuando se reproduce audio y vídeo, hay al menos dos lrelojes concernidos: el " "reloj del sistema, con el cual se sincronizan los cuadros de vídeo, y el " "reloj en el hardware de sonido, que determina la velocidad de reproducción " "del sonido. Estos relojes nunca van a la misma velocidad, excepto en los " "raros casos en los que son físicamente idénticos. En general, los dos " "relojes derivarán después de algún tiempo, por lo que xine ofrece dos " "maneras de mantener sincronizados el audio y el vídeo:\n" "\n" "metronom feedback (realimentación metronómica)\n" "Este es el método estándar, que se aplica a contrarestar la deriva de vídeo " "tan pronto como la deriva de audio se ha acumulado por encima de un límite.\n" "\n" "resample (remuestreo)\n" "Para algún hardware de vídeo, que está limitado a una cadencia de cuadro " "fija (como DXR3 o las otras tarjetas decodificadoras) lo de arriba no " "funciona, porque el vídeo no puede derivar. Por tanto remuestreamos el flujo " "de audio para hacerlo más largo o corto y compensar el error de deriva de " "audio. Esto no funciona para para paso a través digital, donde los datos de " "audio se pasan a un decodificador externo en forma digital." #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "activar remuestreo (resampling)" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" "Cuando la cadencia de muestreo del audio decodificado no se ajusta a las " "capacidades de su hardware de sonido, se requiere una adaptación denominada " "\"remuestreo\". Aquí puede seleccionar si se activa el remuestreo, se " "desactiva, o se usa automáticamente cuando sea necesario." #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "siempre remuestrear a ésta cadencia (0 para desactivar)" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" "Algunos manejadores de audio no anuncian correctamente las capacidades del " "hardware de audio. Poniendo este valor a algo distinto de cero aquí, puede " "forzar el flujo de datos de audio a ser remuestreado a la cadencia dada." #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "compensación para paso a través digital" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Si usa un decodificador externo envolvente y el audio está adelantado o " "retrasado respecto al vídeo, puede introducir aquí un desplazamiento fijo " "para compensar.\n" "Las unidades del valor es una marca PTS, que es 1/90000 segundo." #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "reproduzca vídeo incluso a velocidades lentas/rápidas" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" "Si activa esta opción, el audio se escuchará incluso cuando la velocidad de " "reproducción no sea 1X. Por supuesto, sonará distorsionado (tono más agudo o " "grave). Si desea experimentar preservando el tono, puede probar el post-" "complemento de sonido 'stretch' en su lugar." #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "volumen de audio inicial" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "El volumen de sonido al arrancar xine." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "restaurar el nivel del volumen al arrancar" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "Si se desactiva, xine no modificará ningún ajuste del mezclador al arrancar." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: lo siento, ésto no debiera ocurrir. Por favor reinicie xine.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" "xine-lib: buffer.c: Ha ocurrido un error fatal: DEMASIADAS LIBERACIONES DE " "MEMORIA (FREE'S)\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "El fichero actual de configuración ha sido modificado por una versión de " "xine más nueva." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: AVISO: su configuración no será guardada\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "configfile: AVISO: la escritura de la configuración a %s falló\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: AVISO: eliminando fichero de configuración %s posiblemente roto\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: AVISO: debería comprobar el fichero de respaldo %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: la entrada '%s' no debería ser modificada desde MRL\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" "info_helper: no puedo encontrar el \"locale\" actual del juego de " "caracteres\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" "info_helper: conversión no soportada %s -> UTF-8, conversión no realizada\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": la función open() no debiera ser nunca llamada\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": ¡complemento de entrada no definido!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: falló la lectura de los datos guardados: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: la búsqueda falló: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: falló la lectura por complemento de entrada\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: error escribiendo al fichero % bytes: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: la función open() no debiera ser nunca llamada\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: la búsqueda falló\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % bytes desechados\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: ¡complemento de entrada no definido!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: el directorio de destino no fué especificado, por favor rellene " "la opción 'media.capture.save_dir'\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "La característica de guardar flujo de datos está desactivada hasta que " "defina media.capture.save_dir en la configuración." # CER: ¿ripeado? #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: ¡ripeado/cacheado de esta fuente no está permitido!\n" # CER: el "." está mal colocado, pero al final daría eror. #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "a xine no se le permite grabar desde esta fuente. (¿puede ser material con " "copyright?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: file ¡el nombre no está dado!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: error abriendo fichero %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: espera abandonada\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: falló la espera: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "falló la consecución de un socket" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Permiso denegado\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Fichero no encontrado\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Conexión Rechazada\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "map_decoder_list: no hay espacio para el decodificador, omitido.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: tipo de complemento desconocido %d en %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "" "load_plugins: tipo de complemento estáticamente ligado desconocido %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: ignorando complemento%s, versión \"iface\" equivocada%d " "(debería ser %d)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" "load_plugins: alcanzado límite de complementos, %s no pudo ser cargado\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" "load_plugins: alcanzado límite de complementos, complemento estático no " "pudo ser cargado\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "prioridad para decodificador %s" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: el complemento desmultiplexor %s no proporciona una prioridad, " "xine-lib usará la prioridad por defecto.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: el complemento de entrada %s no proporciona una prioridad, " "xine-lib usará la prioridad por defecto.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: encontrado complemento %s:%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: omitiendo directorio de complementos ilegible %s.\n" # CER: ¿stat? #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: incapaz de obtener estado %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: no puedo abrir librería de complemento %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: no puedo conseguir información del complemento de %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: no puedo (etapa 2) abrir librería de complementos %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: ¡Ondiá! %s no contiene información del complemento.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "Incapaz de crear el directorio %s: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" # CER: ¿rank? #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" "La prioridad proporciona un rango o grado en caso que algún medio pueda ser " "manejado por más de un decodificador.\n" "Una prioridad de 0 activa la prioridad por omisión del decodificador." #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: estrategia %d de detección de contenido desconocida\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: usando desmultiplexor '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: fallé al cargar complemento de salida de audio <%s>\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" "load_plugins: el auto-probado de salida de audio no encontró ningún driver " "de audio usable audio.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: no puedo descargar librería de complementos %s:\n" "%s\n" #: src/xine-engine/metronom.c #, fuzzy msgid "basic video to audio delay in pts" msgstr "no hay flujo de vídeo ni audio en este fichero.\n" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" # msgstr "Tamponeando..." # Llenando mem. tampón... # Tamponeando... #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Precargando..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" "versión incorrecta para la tipografía '%s'. Se esperaba %d se encontró %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "la tipografía '%s-%d' ya estaba cargada, raro.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "la carga de la tipografía '%s' falló (%d < %d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "osd: error encajando tipografía %s con FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "osd: error cargando tipografía %s con FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "osd: error buscando tipografía %s con FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "osd: error cargando tipografía %s con directorios de datos XDG\n" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: no puedo inicializar librería ft2\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "osd: error poniendo tamaño de (¿tipografía no escalable?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: secuencia desconocida comenzando con byte 0x%02X en codificación \"%s" "\", saltando\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: no puedo encontrar juego de caracteres actual del \"locale\"\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: conversión no soportada %s -> %s, conversión no realizada\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: error cargando glifo\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: error en renderizado de glifo\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: la tipografía no está definida\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: error cargando glifo %i\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: error en renderizado\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "paleta (frente-borde-fondo) a usar para subtítulos y VEP (OSD)" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" "La paleta para la visualización en pantalla y algunos formatos de subtítulos " "que no especifican ningún coloreado ellos mismos. Las paletas se listan en " "la forma:frente-borde-fondo." #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "opacidad para las partes negras de los subtítulos mapeados por bits" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" "opacidad para las partes coloreadas de los subtítulos mapeados por bits" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: no hay complemento disponible para manejar '%s'\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: error, tipo de tampón desconocido: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "número de tampones de vídeo" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "El número de tampones de memoria de vídeo (cada uno tiene 8k) que xine usa " "en su propia cola. Valores más altos implican reproducción más suave de " "entradas poco fiables, pero también aumentan la latencia y el consumo de " "memoria." #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d marcos entregados, %d cuadros omitidos, %d cuadros descartados\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: tirando la imagen con pts % porque es demasiado vieja " "(diff : %).\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "porcentaje de cuadros omitidos a tolerar" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" "Cuando más de este porcentaje de cuadros no sean mostrados, porque no fueron " "decodificados a tiempo, xine envía una notificación." #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "porcentaje de cuadros descartados a tolerar" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" "Cuando más de este porcentaje de cuadros no sean mostrados, porque no fueron " "programados para su visualización a tiempo, xine envía una notificación." #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out: Lo siento, esto no debería ocurrir. Por favor, reinicie xine.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "posición horizontal de la imagen en la ventana de salida" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" "Si el tamaño horizontal de ventana de vídeo es mayor que el tamaño real de " "la imagen a mostrar, puede ajustar la posición donde se sitúe la imagen.\n" "La posición se da como un porcentaje, de modo que un valor de 50 significa " "\"en el centro\", mientras que 0 significa \"a la izquierda del todo\" y 100 " "\"a la deracha del todo\"." #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "posición vertical de la imagen en la ventana de salida" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" "Si el tamaño vertical de la ventana es mayor que la imagen real a mostrar, " "puede ajustar la posición vertical en la que se situará la imagen.\n" "La posición se da como un porcentaje, de modo que un valor de 50 significa " "\"en el centro\", mientras que 0 significa\"arriba a tope\" y 100 \"abajo al " "fondo\"." #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "desactive todo escalado de vídeo" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" "Si desea que la imagen se muestre siempre en su resolución original, puede " "desactivar todo escalado de la imagen aquí.\n" "Esto por supuesto significa que la imagen ya no se adaptará al tamaño de la " "ventana de vídeo y que vídeos con una razón de aspecto de píxel distinta de " "1:1, como DVDs anamórficos, se mostrarán distorsionados. Pero por otro lado, " "con algunos drivers de salida de vídeo como XShm, donde el escalado de la " "imagen no está acelerado en hardware, esto puede reducir drásticamente el " "uso de cpu." #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: error mientras se interpretaba mrl\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: encontrado complemento de entrada : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: el complemento de entrada no puede abrir el MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: no se puede encontrar el complemento de entrada para MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: fallo al iniciar el demultiplexor %s especificado\n" # cer: ¿join rip? #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: complemento de entrada join rip \n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: error al abrir instancia de complemento de entrada rip\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "" "xine: el último demultiplexor probado (last_probed) %s no consiguió " "iniciarse \n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "ignorando vídeo\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "ignorando audio\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "ignorando subimagen\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "caché del complemento de entrada desactivado\n" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "abierto mrl de subtítulos '%s'\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: error abriendo mrl de subtítulos\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: cambiar la ocpión '%s' del MRL no está permitido\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "xine: no se pudo encontrar un demultiplexor %s para >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: no se pudo encontrar un demultiplexor para >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: encontrado complemento demultiplexor: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine: el demultiplexor ya ha terminado, ¡eso fué rápido\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: fallo al iniciar el demultiplexor\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: no hay disponible un demultiplexor\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: fallo al iniciar el demultiplexor\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" "xine: El directorio (save_dir) especificado \"%s\" pudiera ser un riesgo " "para la seguridad.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" "El directorio (save_dir) especificado pudiera ser un riesgo para la " "seguridad." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: \"locale\" no soportada por la librería de C\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "estrategia de detecciónde formato" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" "xine ofrece varios métodos para detectar el formato de medios introducidos " "para reproducirlos. Los valores individuales son:\n" "\n" "default\n" "Primero prueba a detectar por el contenido, y después por la extensión del " "nombre del fichero.\n" "\n" "reverse\n" "Primero prueba a detectar por la extensión del nombre del fichero, y después " "por el contenido.\n" "\n" "content\n" "Detectar sólo por el contenido.\n" "\n" "extension\n" "Detectar sólo por la extensión del nombre del fichero.\n" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "directorio para guardar flujos de bits" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" "Cuando se usa la función de grabar flujo, los ficheros se escribirán sólo a " "éste directorio.\n" "Este ajuste es crítico para la seguridad, porque cuando se cambia a un " "directorio diferente, xine puede usarse para llenar ficheros con contenido " "arbitrario. Así que debiera ser cuidadoso que el directorio especificado sea " "robusto contra cualquier contenido en cualquier fichero." #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "permitir cambios implícitos a la configuración (p.e. por MRL)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" "Si se activa, usted permite a xine cabiar su configuración sin acciones " "explícitas por su parte. Por ejemplo cambios de configuración demandados por " "MRLs o embebidos en la lista de reproducción serán realizados.\n" "Este ajuste es crítico para la seguridad, porque xine puede recibir MRLs o " "listas de reproducción de sitios remotos no confiables. Si les permite " "arbitrariamente cambiar su configuración, usted podría acabar con un xine " "totalmente enredado." #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "Temporización para lectura de flujos de bits desde red (en segundos)" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" "Especifica la temporización cuando se leen flujos de datos desde la red, en " "segundos. Valore demasiado bajos pueden detener la transmisión cuando la " "fuente es lenta o el ancho de banda está ocupado; valores demasiado altos " "congelarán el reproductor si se pierde la conexión." #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "mensajes" #: src/xine-engine/xine.c msgid "plugin" msgstr "complemento" #: src/xine-engine/xine.c msgid "trace" msgstr "traza" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Aviso:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "host desconocido:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Dispositivo desconocido:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Red no alcanzable" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Conexión rechazada:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "Fichero no encontrado:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Error de lectura desde:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Error de carga de librería:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Detectado flujo de bits de medios encriptado" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Mensaje de seguridad:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Dispositivo de audio no disponible" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Error de permisos" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "El fichero está vacío:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Restaurando índice..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Evaluando métodos \"memcpy\" (menor es mejor):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "método \"memcopy\" usado por xine" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" "El copiado de grandes bloques de memoria es una de las operaciones más " "costosas en las computadoras actuales. Por tanto xine provee varios metodos " "ajustados para hacer este copiado. Usualmente, el método mejor se detecta " "automáticamente." #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "" #~ "configfile: AVISO: la copia de seguridad del fichero de configuración a %" #~ "s falló\n" #, fuzzy #~ msgid "fooaudio: reference xine audio decoder plugin" #~ msgstr "complemento decodificador de audio basado en ffmpeg" #, fuzzy #~ msgid "foovideo: reference xine video decoder plugin" #~ msgstr "complemento decodificador de vídeo basado en ffmpeg" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: mal mrl: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: error de lectura (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: no se puede resolver '%s'.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: no se puede conectar a '%s'.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "stdin: ¡no puedo ir hacia atrás! (% > %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: error al interpretar MRL\n" #~ msgid "raw device set up for DVD access" #~ msgstr "dispositivo bruto usado para acceso al DVD" #~ msgid "" #~ "If this points to a raw device connected to your DVD device, xine will " #~ "use the raw device for playback. This has the advantage of being slightly " #~ "faster and of bypassing the block device cache, which avoids throwing " #~ "away important cache content by keeping DVD data cached. Using the block " #~ "device cache for DVDs is useless, because almost all DVD data will be " #~ "used only once.\n" #~ "See the documentation on raw device setup (man raw) for further " #~ "information." #~ msgstr "" #~ "Si esto apunta a un dispositvo en bruto conectado a su dispositivo DVD, " #~ "sine usará el dispositivo en bruto para reproducción. Esto tiene la " #~ "ventaja de ser ligeramente más rapido y de saltarse el caché del " #~ "dispositivo de bloques, lo que evita tirar contenido importante del caché " #~ "al mantener los datos del DVD cacheados. Usar el caché del dispositivo de " #~ "bloques para DVDs es inútil, porque casi todos los datos del DVD serán " #~ "usados una única vez.\n" #~ "Vea la documentación de configuración de dispositivos en bruto (man raw) " #~ "para más información." #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "El mensaje de arriba tenía nivel de registro vcdimager desconocido" #~ msgid "load_plugins: static plugin %s found\n" #~ msgstr "load_plugins: encontrado complemento estático %s\n" xine-lib-1.2/po/cs.po0000644000175000017500000074153114647725152012262 0ustar meme# Czech translate, xine-lib.po. # Copyright (C) 2002-2008 Free Software Foundation, Inc. # Frantisek Dvorak , 2002-2008. # msgid "" msgstr "" "Project-Id-Version: xine-lib 1.0.1\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2008-11-10 16:33+0200\n" "Last-Translator: František Dvořák \n" "Language-Team: Czech \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: cs\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" #: lib/hstrerror.c msgid "No error" msgstr "Žádná chyba" # standarní hláška hstrerror #: lib/hstrerror.c msgid "Unknown host" msgstr "Neznámý počítač" # standarní hláška hstrerror #: lib/hstrerror.c msgid "No address associated with name" msgstr "Adresa není asociována se jménem" # standarní hláška hstrerror #: lib/hstrerror.c msgid "Unknown server error" msgstr "Neznámá chyba na serveru" # standarní hláška hstrerror #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Zjišťování jména selhalo" #: lib/hstrerror.c msgid "Unknown error" msgstr "Neznámá chyba" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "dvaudio: zvětšení bufferu na %d, aby se předešlo přetečení.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "POMÓC! Zvukový ovladač pouze mono?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "hlasitost A/52" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" "U zvuku A/52 můžete změnit hlasitost na úrovni dekódování. To má výhodu, že " "zvuk je již dekódován na specifikovanou hlasitost, takže pozdější operace " "jako smixovávání kanálů budou pracovat na zvukových datech dané hlasitosti." #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "povolit zhuštění dynamického rozsahu A/52" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" "Zhuštění dynamického rozsahu omezí dynamický rozsah zvuku. To znamená, že " "hlasité zvuky se stanou tiššími a tiché zvuky hlasitějšími, a tak můžete " "lépe slyšet zvuk v hlasitém prostředí bez toho, abyste kohokoliv rušili." #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "redukce zvuku do 2.0 surround stereo" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" "Jestli chcete poslouchat vícekanálový surround zvuk, ale máte pouze dva " "reproduktory, surround dekodér nebo zesilovač, který provádí nějaké maticové " "surround dekódování jako např. prologic, měli byste tuto volbu povolit. Pak " "budou dodatečné kanály přimixovávány do stereo signálu." #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: selhala funkce NeAACDecOpen().\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: selhala funkce NeAACDecInit2.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: selhala funkce NeAACDecInit.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "modul zvukového výstupu xine do souboru" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "libmusepack: selhalo mpc_demux_initialise\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: mpc_streaminfo_read selhalo: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: data po posledním snímku ignorována\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: selhalo mpc_decoder_initialise\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: selhalo mpc_decoder_decode: %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out: Již otevřeno...PROČ!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() na %s selhalo: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>> zkontrolujte, jestli už jiný program nepoužívá PCM <<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: přerušena konfigurace tohoto PCM: žádná konfigurace není k " "dispozici: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "uvědomit o změnách hardwarový mixer" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "Když se změní hardwarový mixer, vaše aplikace obdrží upozornění, a tak může " "za běhu aktualizovat svoji grafickou reprezentaci nastavení mixeru." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : podporované režimy jsou" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4kanálový není povolen v konfiguraci xine)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1kanálový" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1kanálový není povolen v konfiguraci xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5kanálový" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5kanálový není povolen v konfifuraci xine)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1kanálový není povolen v konfiguraci xine)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (a/52 a DTS pass-through nejsou povoleny v konfiguraci xine)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_cm_open() selhalo:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Zkontrolujte, jestli už jiný program nepoužívá PCM <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8bitový" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16bitový" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24bitový" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32bitový" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "zvuková karta umožňuje provádět mmap" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Toto povolte, pokud vaše zvuková karta a ovladač ALSA podporují I/O mapované " "do paměti.\n" "Můžete to zkusit povolit a zkontrolovat, zda vše funguje. Pokud ano, zlepší " "toto nastavení výkon." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "zařízení použité pro mono výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine použije toto zařízení ALSA pro výstup zvuku mono.\n" "Informace o zařízeních ALSA naleznete v dokumentaci k ALSA." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " stereo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "zařízení použité pro stereo výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine použije toto zařízení ALSA pro výstup zvuku stereo.\n" "Informace o zařízeních ALSA naleznete v dokumentaci k ALSA." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4kanálový" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "zařízení použité pro čtyřkanálový výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine použije toto zařízení ALSA pro výstup surround zvuku 4kanálově (4.0).\n" "Informace o zařízeních ALSA naleznete v dokumentaci k ALSA." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1kanálový" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "zařízení použité pro 5.1-kanálový výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine použije toto zařízení ALSA pro výstup surround zvuku 5kanálově s LFE " "(5.1).\n" "Informace o zařízeních ALSA naleznete v dokumentaci k ALSA." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " a/52 a DTS pass-through" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " a/52 a DTS pass-through" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine použije toto zařízení ALSA pro výstup nedekódovaného surround zvuku. " "Může to být použito vnějšími surround dekodéry.\n" "Informace o zařízeních ALSA naleznete v dokumentaci k ALSA." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() selhalo: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "mixovací zařízení alsa" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "ke změně hlasitosti použije xine toto zařízení mixeru ALSA.\n" "Informace o zařízeních ALSA naleznete v dokumentaci k ALSA." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "výstupní zvukový modul xine použije zvuková zařízení/ovladače alsa" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "modul zvukového výstupu xine pro Coreaudio/Mac OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Chyba" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "úspěch" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "přístup odepřen" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "zdroj je již používán" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "objekt již byl inicializován" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "uvedený wave formát není podporován" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "paměťový buffer byl ztracen a musí být obnoven" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "požadované řízení bufferu není k dispozici" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "neurčená chyba uvnitř subsystému DirectSound" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "hardwarové zařízení DirectSound není k dispozici" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "pro stávající stav objektu není funkce platná" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "byl předán neplatný parametr" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "objekt nepodporuje agregaci" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "není k dispozici žádný zvukový ovladač k použití" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "požadované COM rozhraní není k dispozici" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "jiná aplikace má vyšší úroveň priority" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "nedostatek paměti" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "pro tuto funkci nízká úroveň priority" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound nebyl inicializován" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "funkce není podporována" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "neznámá chyba" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Nepodařilo se vytvořit objekt direct sound." #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "Nelze nastavit kooperativní úroveň direct sound." #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "Nepodařilo se vytvořit sekundární buffer direct sound" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "Nelze přehrát zvukový buffer" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "Nelze zastavit zvukový buffer" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "Nelze získat pozici bufferu" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "Nelze nastavit pozici bufferu" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "Nelze nastavit hlasitost zvuku" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": buffer ztracen, zkusí se obnovit\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "Nešlo zamknou buffer direct sound" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "Nešlo odemknout buffer direct sound" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Nepodařilo se vytvořit primární buffer direct sound." #: src/audio_out/audio_directx2_out.c #, fuzzy, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" ": kurzor přehrávání se předběhl (data %u, min %u), resetování bufferů\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": nelze vytvořit vlákno bufferu: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": nelze zlikvidovat vlákno bufferu: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ": nelze zlikvidovat pthread condition: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": nelze zlikvidovat pthread mutex: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr ": neznámý řídicí příkaz: %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": nelze vytvořit pthread condition: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": nelze vytvořit pthread mutex: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "druhý modul zvukového výstupu xine používající DirectX" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "modul zvukového výstupu xine pro win32 používající directx" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: připojuje se k serveru ESD %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: připojuje se k serveru ESD...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: nelze se připojit k ESD serveru %s: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "zpoždění zvukového výstupu esd (upraví synchronizaci zvuku a videa)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Pokud zjistíte, že zvuk není synchronizovaný s videem, můžete to kompenzovat " "zadáním pevného posunu.\n" "Jednotka hodnoty je jeden tik PTS, což je 1/90000 sekundy." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "modul zvukového výstupu xine použije esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "modul zvukového výstupu xine do souboru" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "modul zvukového výstupu xine do souboru" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "maximální mezera zvukového výstupu irix" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Můžete uvézt maximální posuv mezi zvukem a videem, který bude xine tolerovat " "před tím, než se je pokusí znovu synchronizovat.\n" "Jednotka této hodnoty je jeden tik PTS, což je 1/90000 sekundy." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "zvukový výstupní modul xine použije IRIX libaudio" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "jméno zvukového zařízení JACK" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" "Specifikuje jméno zvukového zařízení jack, na výchozí fyzické ponechte " "prázdné" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "modul zvukového výstupu xine pro JACK Audio Connection Kit" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "fiktivní modul zvukového výstupu xine" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Otevírá se zvukové zařízení %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: varování: vzorkovací frekvence %d Hz není podporována, zkusí " "se 44100 Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" "audio_oss_out: rychlost zvuku : %d požadováno, %d poskytnuto zařízením\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "jméno zvukového zařízení OSS" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "Specifikuje základní část jména zvukového zařízení, ke kterému se přidá " "číslo OSS zařízení, aby se získalo celé jméno zařízení.\n" "Vyberte \"auto\", jestliže chcete, aby xine automaticky zjistilo správné " "nastavení." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "číslo zvukového zařízení OSS, -1 pro žádné číslo" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Plné jméno zvukového zařízení je vytvořeno zřetězením jména zařízení OSS a " "čísla zvukového zařízení.\n" "Jestliže nepotřebujete číslo, protože jste spokojeni s výchozím zařízením " "systému, nastavte ho na -1.\n" "Rozsah této hodnoty je -1 nebo 0-15. Toto nastavení je ignorováno, pokud je " "jméno zvukového zařízení nastaveno na \"auto\"." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" "audio_oss_out: audio.device.oss_device_name = auto, zkouší se zařízení\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: automatická zkouška zvukového zařízení selhala\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: použije se zařízení >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: otevírání zvukového zařízení %s selhalo:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "metoda synchronizace zvuku a videa použitá OSS" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "xine může k zachování synchronizace zvuku a videa používat různé metody. " "Které nastavení funguje nejlépe záleží na ovladači OSS a zvukovém hardware, " "který používáte. Pokud narazíte na problémy se synchronizací, vyzkoušejte " "různé metody.\n" "\n" "Význam hodnot je následující:\n" "\n" "auto\n" "xine zkusí automaticky zjistit optimální nastavení\n" "\n" "getodelay\n" "k dosažení věrné synchronizace zvuku a videa používá ioctl " "SNDCTL_DSP_GETODELAY dokonce, když ovladač tvrdí, že nepodporuje přehrávání " "v reálném čase\n" "\n" "getoptr\n" "k dosažení věrné synchronizace zvuku a videa používá ioctl " "SNDCTL_DSP_GETOPTR dokonce, když ovladač podporuje preferované ioctl " "SNDCTL_DSP_GETODELAY\n" "\n" "softsync\n" "používá softwarovou synchronizaci se systémovými hodinami; zvuk a video se " "mohou vzájemně dostat mimo synchronizaci, jestliže rychlost hodin v systému " "přesně nesouhlasí s rychlostí přehrávání zvukové karty\n" "\n" "probebuffer\n" "při inicializaci se zkouší velikost vyrovnávací paměti zvukové karty, aby se " "vypočetlo zpoždění synchronizace zvuku a videa; toto vyzkoušejte, jestliže " "váš systém nepodporuje žádné ioctl reálného času a zjistíte, že je po " "dlouhém přehrávání špatná synchronizace" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: synchronizace reálného času zvukového zařízení zakázána...\n" " audio_oss_out: ...místo toho se použijí pro soft-sync systémové hodiny " "reálného času\n" " audio_oss_out: ...mohou zde být problémy se synchronizací zvuku a videa\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "zpoždění zvukového výstupu OSS (upraví synchronizaci zvuku a videa)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: synchronizace reálného času zvukového zařízení zakázána...\n" "audio_oss_out: ...zkouší se velikost výstupní vyrovnávací paměti: %d bytů\n" "audio_oss_out: ...mohou zde být problémy se synchronizací zvuku a videa\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: podporované režimy jsou" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " a/52 pass-through" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (a/52 pass-through není povoleno v konfiguraci xine)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "číslo zvukového mixeru OSS, -1 pro žádné" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Plné jméno zařízení mixeru se vytvoří tak, že se vezme jméno zařízení OSS, " "\"dsp\" se nahradí \"mixer\" a přidá se číslo mixeru.\n" "Pokud nepotřebujete číslo, protože jste spokojeni s výchozím nastavením " "mixovacího zařízení v systému, nastavte tuto volbu na -1.\n" "Rozsah této hodnoty je -1 nebo 0-15. Toto nastavení je ignorováno, pokud je " "jméno zvukového zařízení OSS nastaveno na \"auto\"." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: open() mixer %s selhalo: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "výstupní zvukový modul xine použije zvuková zařízení/ovladače OSS" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "zařízení použité pro pulseaudio" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "pro nastavení jímacího zařízení pulseaudia použijte '[server[:sink]]'" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " a/52 pass-through" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "modul zvukového výstupu xine použije server pulseaudio" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "výstupní zvukový modul použije zvuková zařízení/ovladače sun" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: otevírání zvukového zařízení %s selhalo: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "jméno zvukového zařízení Sun" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Specifikuje jméno souboru zvukového zařízení Sun, které se má použít.\n" "Toto nastavení je kritické s ohledem na bezpečnost, protože při změně na " "jiný soubor může být xine použito k vyplnění tohoto souboru libovolným " "obsahem. A tak by jste si měli být jisti, že hodnota, kterou zadáváte, je " "skutečně náležité zvukové zařízení Sun." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "audio_sun_out: zvukové ioctl na zařízení %s selhalo: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "výstupní zvukový modul použije zvuková zařízení/ovladače sun" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "uspořádání reproduktorů" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Vyberte, jak jsou uspořádány vaše reproduktory. To určuje, které " "reproduktory xine použije pro výstup zvuku. Jednotlivé hodnoty jsou:\n" "\n" "Mono 1.0: Máte pouze jeden reproduktor.\n" "Stereo 2.0: Máte dva reproduktory na levý a pravý kanál.\n" "Headphones 2.0: Používáte sluchátka.\n" "Stereo 2.1: Máte dva reproduktory na levý a pravý kanál a jeden subwoofer na " "nízké frekvence.\n" "Surround 3.0: Máte tři reproduktory na levý, pravý a zadní kanál.\n" "Surround 4.0: Máte čtyři reproduktory na přední levý a pravý kanál a na " "zadní levý a pravý kanál.\n" "Surround 4.1: Máte čtyři reproduktory na přední levý a pravý kanál a na " "zadní levý a pravý kanál a jeden subwoofer na nízké frekvence.\n" "Surround 5.0: Máte pět reproduktorů na přední levý, střední a pravý kanál a " "zadní levý a pravý kanál.\n" "Surround 5.1: Máte pět reproduktorů na přední levý, střední a pravý kanál a " "zadní levý a pravý kanál a jeden subwoofer na nízké frekvence.\n" "Surround 6.0: Máte šest reproduktorů na přední levý, střední a pravý kanál a " "zadní levý, střední a pravý kanál.\n" "Surround 6.1: Máte šest reproduktorů na přední levý, střední a pravý kanál a " "zadní levý, střední a pravý kanál a jeden subwoofer na nízké frekvence.\n" "Surround 7.1: Máte sedm reproduktorů na přední levý, střední a pravý kanál, " "levý a pravý kanál a zadní levý, střední a pravý kanál a jeden subwoofer na " "nízké frekvence.\n" "Pass Through: Váš zvukový systém obdrží ze xine nedekódovaný digitální zvuk. " "Na digitální výstup vaší zvukové karty potřebujete připojit digitální " "surround dekodér schopný dekódovat formáty, které chcete přehrát." #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "modul pro vstup ze souboru" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_audio_dec: zvětšení bufferu na %d, aby se předešlo přetečení.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "ffmpeg_audio_dec: nelze nalézt dekodér ffmpeg pro buffer typu 0x%X\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: pokus o otevření kodeku null\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: nelze otevřít dekodér\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "ffmpeg_video_dec: nepodporované rozměry snímku, DR1 zakázáno.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: nepodporovaný formát, DR1 zakázáno.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: přímé renderování povoleno\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "ffmpeg_video_dec: nepodporovaný formát, DR1 zakázáno.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: nelze otevřít dekodér\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: nelze otevřít dekodér (2)\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_video_dec: zvětšení bufferu na %d, aby se předešlo přetečení.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: nepodporovaný formát, DR1 zakázáno.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "ffmpeg_video_dec: nelze nalézt dekodér ffmpeg pro buffer typu 0x%X\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "kvalita dodatečného zpracování MPEG-4" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "Můžete přizpůsobit množství dodatečného zpracování použitého na video MPEG-" "4.\n" "Vyšší hodnoty mají za následek lepší kvalitu, ale více zatíží CPU. Menší " "hodnoty mohou mít za následek defekty v obrázku, např. blokové artefakty. " "Pro vysokou kvalitu videa může příliš silné dodatečné zpracování způsobit " "horší obraz tím, že ho více rozmaže." #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "Počet vláken na dekódování videa FFmpegem" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Můžete upravit počet vláken dekódující video, které má FFmpeg používat.\n" "Vyšší hodnoty by měly urychlit dekódování, ale záleží také na tom, jestli " "daný kodek podporuje paralelní dekódování. Zpravidla je dobré mít jedno " "dekódovací vlákno na jeden logický procesor (typicky od 1 do 4).\n" "Změna tohoto nastavení se projeví při přehrávání následujícího videa." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "Přeskakování filtru ve smyčce" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Můžete řídit, pro které snímky by měl být po dekódování přeskočen filtr ve " "smyčce.\n" "Přeskakování filtru ve smyčce urychlí dekódování, ale může vést k " "artefaktům. Počet přeskočených snímků je od 'none' (žádné) po " "'all' (všechny).Výchozí hodnota ponechává rozhodnutí na implementaci.\n" "Změna tohoto nastavení se projeví při přehrávání následujícího videa." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "Upřednostnit rychlost před vyhověním specifikacím" # "zneuctívají specifikace kodeku" ;-) #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" "Můžete chtít umožnit rychlostní cheaty, které porušují specifikace kodeku.\n" "Cheaty mohou urychlit dekódování, ale také vedou k dekódovacím artefaktům.\n" "Změna tohoto nastavení se projeví při přehrávání následujícího videa." #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "vstupní modul v4l rádio" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "modul zvukového výstupu xine do souboru" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: zjištěna zvuková stopa vorbis, ale nenalezena žádná hlavička dat " "vorbis.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "modul zvukového výstupu xine do souboru" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: zvětšení bufferu na %d, aby se předešlo přetečení.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "modul pro vstup ze souboru" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "demux_asf: varování: Vypadá to, že tok dat chybí.\n" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "Chybějící data z média?" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: varování: Proud dat číslo %d je zašifrovaný.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Proud dat je zamíchán/zašifrován" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Obnovuje se index..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" "demux:avi: neplatný datový blok avi \"%c%c%c%c\" na pozici %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: index avi je porušen\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" "demux_avi: selhalo nastavení pozice na další data (pozice %)\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "vstupní modul DVB (digitální TV)" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "neplatná velikost datového bloku FILM\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "nerozpoznaný datový blok FILM\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, fuzzy, c-format msgid "unsupported FLV version (%d).\n" msgstr "nepodporovaná verze FLV (%d).\n" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "v tomto souboru žádné video ani zvuk\n" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: neznámá komprese: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: neznámá komprese: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: neznámý datový blok: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "modul pro vstup ze souboru" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: snímek příliš velký do bufferu" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: Nerozpoznané stream_id 0x%02x. Prosím oznamte to " "vývojářům xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: Chyba! Uvolní se. Prosím oznamte to vývojářům xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: varování: 10 rezervovaných bitů hlavičky PES nenalezeno\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: varování: hlavička PES indikuje, že tyto data mohou být " "zašifrována (šifrovací mód: %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "vstupní modul pnm pro streamovaná data" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: Nerozpoznané stream_id 0x%02x. Prosím oznamte to " "vývojářům xine.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "demux_mpeg_pes: varování: selhalo dekódování sekvence PACK id=0x%x.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: varování: 10 rezervovaných bitů hlavičky PES nenalezeno\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: varování: hlavička PES indikuje, že tyto data mohou být " "zašifrována (šifrovací mód: %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes: Nerozpoznaný soukromý proud dat 1 0x%02x. Prosím oznamte to " "vývojářům xine.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "vstupní modul v4l rádio" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "modul pro vstup ze souboru" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "modul pro vstup ze souboru" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: špatné parametry hlavičky\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: nepodporovaný typ zvuku: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "demux_tta: celkový počet snímků příliš velký\n" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "neznámý typ bloku VOC (0x%02X); prosím oznamte vývojářům xine\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "neznámý typ komprese VOC (0x%02X); prosím oznamte vývojářům xine\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "modul pro vstup ze souboru" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" "demux_wc3movie: datový blok SHOT odkazoval na neplatnou paletu (%d >= %d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "demux_wc3movie: Byl zde problém během načítání datových bloků palety\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Selhalo otevření zařízení titulků %s (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_video: zápis do video zařízení selhal (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "požadované tlačítko není k dispozici\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "dxr3_decode_video: Selhalo otevření řídícího zařízení %s (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "použít informaci Pan & Scan" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Pan & Scan\" je speciální režim zobrazení, který je občas používán v " "médiích kódovaných v MPEG. Můžete zde uvézt, jak pracovat s takovým " "obsahem.\n" "\n" "pouze, pokud je vynuceno\n" "Použít Pan & Scan pouze, když si to obsah, který přehráváte, vynucuje.\n" "\n" "použít informaci v MPEG\n" "Povolit Pan & Scan na základě informací vložených v datech MPEG videa.\n" "\n" "použít informaci z DVB\n" "Povolit Pan & Scan na základě informací vložených v datech DVB. Toto " "způsobí, že se použije Active Format Descriptor (AFD) používaný některými " "Evropskými kanály." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "Zkusit synchronizovat video každý snímek" #: src/dxr3/dxr3_decode_video.c #, fuzzy msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" "Zkouší nastavit pro každý snímek synchronizační časovou značku. Běžně toto " "není nutné, protože synchronizace je dostatečná, i když je časová značka " "nastavena pouze občas.\n" "Toto je odůvodněné pouze pro postupné video (většina filmů PAL)." #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "použít hladký režim přehrávání" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Povolením této volby se využije hladší režim přehrávání." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "opravovat dobu trvání snímků v porušených datových proudech" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" "Povolí logiku, která upravuje doby trvání snímku některých mpeg streamů se " "špatnými kódy rychlosti snímku. V současnosti je implementována korekce pro " "NTSC streamy mylně označené jako PAL streamy. Povolte to pouze tehdy, když " "se s takovými streamy setkáte." #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Selhalo otevření video zařízení %s (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "dxr3_decode_video: zápis do zařízení by blokoval. okamžité zapsání\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: zápis do video zařízení selhal (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "dxr3_decode_video: VAROVÁNÍ: neznámý kód rychlosti snímků %d\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: VAROVÁNÍ: oprava kódu rychlosti snímků z PAL na NTSC\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "Číslo zařízení DXR3" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Jestliže máte ve vašem počítači více než jednu DXR3, můžete uvézt, kterou z " "nich zde použít." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: selhala inicializace librte\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte pracuje pouze s rozměry videa, které jsou násobky 16\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: selhalo získání kontextu rte.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: nešlo vytvořit kodek.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "výstupní rychlost rte mpeg (kbit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "Bitová rychlost knihovny librte kódující mpeg, jaká by se měla používat v " "režimu kódování DXR3. Vyšší hodnoty zvýší využití procesoru a kvalitu." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: nelze inicializovat kontext: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: nelze začít s kódováním: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: Nešlo spustit knihovnu FAME\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "kvalita kódování MPEG knihovny fame" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "Kvalita kódování knihovny libfame vytvářející mpeg. Menší je rychlejší, ale " "dává viditelné artefakty. Vyšší je lepší, ale pomalejší." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "priorita modulu SCR" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" "Priorita modulu DXR3 SCR. Hodnoty menší než 5 znamenají, že bude použit " "časovač unixového systému. Hodnoty větší než 5 vynutí použití jako zdroj " "synchronizace vnitřních hodin DXR3." #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "výstupní rychlost mpegu libavcodec (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" "Bitová rychlost knihovny libavcodec kódující mpeg, jaká by se měla používat " "v režimu kódování DXR3. Vyšší hodnoty zvýší využití procesoru a kvalitu.\n" "Toto nastavení je uvažováno pouze, když je zakázán režim konstantní kvality." #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "režim konstantní kvality" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" "Když bude povoleno, libavcodec použije režim konstantní kvality dynamickou " "kompresí obrázků na základě jejich složitosti. Když bude zakázáno, " "libavcodec použije režim konstantní bitové rychlosti." #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "minimální komprese" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" "Minimální komprese, která se použije na obraz v režimu konstantní kvality." #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "Maximální kvantizér" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" "Maximální komprese, která se použije na obraz v režimu konstantní kvality." #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Selhalo otevření řídícího zařízení %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "prohodit liché a sudé řádky" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" "Prohodí sudé a liché pole obrázku.\n" "Povolte tuto volbu pro média v jiném formátu než MPEG, které vytváří na " "obrazovce vodorovné chvění." #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "upravit poměr stran přidáním černých pruhů" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Přidá černé pruhy, jestliže má obraz poměr stran, se kterým karta nemůže " "pracovat přímo. Je to nutné k udržení patřičných proporcí obrázku." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "pro kodér MPEG použít hladký režim přehrávání" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Povolením této volby se využije pro ne-MPEG obsah hladší režim přehrávání." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Selhalo otevření video zařízení %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "kodér pro ne-MPEG obsah" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "Obsah jiný než MPEG musí projít dodatečnou překódovávací fází, protože DXR3 " "pracuje pouze s MPEG.\n" "V závislosti na tom, co je podporováno vaším xine, může být toto nastavení " "\"fame\", \"rte\", \"libavcodec\" nebo \"none\".\n" "Kodér \"libavcodec\" použije modul ffmpeg, který je již se xine dodán, takže " "pro to nepotřebujete instalovat žádné další knihovny. libavcodec je dokonce " "lepší, poskytuje vyšší kvalitu s nižším využitím CPU. Použití \"libavcodec\" " "je proto silně doporučováno.\n" "\"fame\" a \"rte\" zde stále jsou, ale jejich podpora ve xine je zastaralá, " "takže tyto by nemusely fungovat." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "video_out_dxr3: Selhala inicializace Mpeg kodéru.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: Selhala inicializace Mpeg kodéru rte.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: Selhala inicializace Mpeg kodéru fame.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: kódování MPEG zakázáno.\n" "video_out_dxr3: to je v pořádku, nepotřebujete to pro MPEG video jako je " "DVD,\n" "video_out_dxr3: ale při použití tohoto ovladače výstupu videa nebudete\n" "video_out_dxr3: moci přehrávat ne-MPEG obsah. Detaily o konfiguraci kodéru\n" "video_out_dxr3: viz README.dxr3.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: kódování MPEG není zakompilováno.\n" "video_out_dxr3: to je v pořádku, nepotřebujete to pro MPEG video jako je " "DVD,\n" "video_out_dxr3: ale při použití tohoto ovladače výstupu videa nebudete\n" "video_out_dxr3: moci přehrávat ne-MPEG obsah. Detaily o konfiguraci kodéru\n" "video_out_dxr3: viz README.dxr3.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "režim výstupu videa (TV nebo překrývaní)" # TODO: dopřeložit #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" "Zde může být nastaven způsob výstupu výsledného videa z DXR3. Jednotlivé " "hodnoty jsou:\n" "\n" "letterboxed tv\n" "Posílat video pouze do výstupního TV konektoru. Toto je režim použitý pro " "standardní nastavení televize 4:3. Anamorfotické video (16:9) bude zobrazeno " "4:3, média pan&scan budou mít oříznutý obraz na levé a pravé straně. Toto je " "běžné nastavení pro sledování TV, která se chová stejně jako samotný DVD " "přehrávač.\n" "\n" "widescreen tv\n" "Posílat video pouze do výstupního TV konektoru. This mode is intended for " "16:9 widescreen TV sets. Anamorphic and pan&scan content will fill the " "entire screen, but you have to set the TV's aspect ratio manually to 16:9 " "using your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "hodnota klíčové barvy překrývání" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Šestnáctková hodnota RGB klíčové barvy.\n" "Pokud při použití překryvného režimu DXR3 zjistíte, že se okna stávají " "transparentní, můžete vyzkoušet jiné hodnoty." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "rozsah klíčové barvy překrývání" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" "Větší hodnota rozšíří toleranci překryvné klíčové barvy.\n" "Pokud při použití překryvného režimu DXR3 zjistíte, že se okna stávají " "transparentní, můžete vyzkoušet nižší hodnoty. Ale při použití příliš " "nízkého nastavení mohou mizet části okrajů obrazu." #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "oříznout překrývanou oblast nahoře a dole" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Odstraní jeden bodový řádek z hořejšku a dolejšku překrývaného obrazu. Toto " "povolte, pokud vidíte nahoře a dole zelené řádky." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: spusťte prosím autocal, překrývání zakázáno\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "přednost režimu TV" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Vybere TV režim, který má použít DXR3. Hodnoty znamenají:\n" "\n" "ntsc: NTSC na 60Hz\n" "pal: PAL na 50Hz\n" "pal60: PAL na 60Hz\n" "default: zachovat nastavení karty" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: selhalo nastavení režimu videa.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: K přehrávání ne-MPEG videa na dxr3 potřebujete MPEG kodér\n" "video_out_dxr3: Detaily viz README.dxr3.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: CHYBA čtení souboru inicializace překrývání. Spusťte " "autocal!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "zařízení použité pro přehrávání BluRay" #: src/input/input_bluray.c #, fuzzy msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "Cesta k zařízení, obvykle BluRay mechanice, které chcete používat pro " "přehrávání BluRay." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "výchozí jazyk pro přehrávání BluRay" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" "xine zkusí tento jazyk použít jako výchozí pro přehrávání BluRay. Pokud to " "BluRay bude podporovat, volby a zvukové stopy budou prezentovány v tomto " "jazyce.\n" "Hodnotou musí být 3 znaky jazykového kódu ISO639-2." #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" "Toto je nutné změnit pouze, pokud vaše BluRay skočí na obrazovku stěžující " "si na špatný kód oblasti. Nemá to nic dělat s kódem oblasti nastaveným v " "BluRay mechanikách, je to čistě softwarové." #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "jednotka pro akci skoku" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: http: nelze se připojit k %s:%d\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: úspěšně připojeno k CDDB serveru '%s:%d'.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "input_cdda: nelze se připojit k CDDB serveru '%s:%d' (%s).\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "digitální zvukové CD (CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "zařízení použité pro zvukové CD" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "Cesta k zeřízení, obvykle CD nebo DVD mechanika, které máte v úmyslu " "používat k přehrávání zvukových CD." #: src/input/input_cdda.c msgid "query CDDB" msgstr "dotazovat se CDDB" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" "Povolí dotazy CDDB, které vám budou vracet pro vaše zvuková CD příslušné " "nadpisy a názvy stop.\n" "Vězte, že pokud nepoužíváte vlastní CDDB, je tato informace získávána z " "internetového serveru, který by pak mohl znát profil vašich poslechových " "zvyků." #: src/input/input_cdda.c msgid "CDDB server name" msgstr "jméno serveru CDDB" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" "Server CDDB, který se použije, aby se z něj získávaly nadpisy a informace o " "stopě.\n" "Toto nastavení je kritické s ohledem na bezpečnost, protože serveru budou " "posílány informace o vašich poslechovích zvycích a také mohl by odpovídat na " "dotazy zákeřnými odpověďmi. Ujistěte se, že serveru můžete důvěřovat." #: src/input/input_cdda.c msgid "CDDB server port" msgstr "port serveru CDDB" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" "Port serveru, který se použije, aby se z něj získávaly nadpisy a informace o " "stopě." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "zpomalit diskovou jednotku na tento rychlostní faktor" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" "Protože některé CD nebo DVD jednotky vydávají opravdu silný hluk kvůli " "rychlé rotaci disku, xine je zkusí zpomalit. Pro běžné přehrávání CD nebo " "DVD nejsou vysoké rychlosti dat, které vyžadují rychlou rotaci disku, " "potřebné, a tak by nemělo zpomalení ovlivnit výkon přehrávání.\n" "Hodnota nula zde zakáže zpomalování." #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "input_dvb: selhalo otevření souboru kanálu dvb '%s': %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "input_dvb: soubor kanálu dvb '%s' není běžný soubor\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: selhalo nastavení kanálu\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "input_dvb: DVB rozhraní %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: nelze otevřít zařízení dvb\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "input_dvb: kanál %d mimo rozsah, použije se výchozí 0\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: hledání kanálu %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "input_dvb: přesná shoda pro %s nenalezena: zkusí se částečné shody\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: nalezen odpovídající kanál %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "input_dvb: kanál %s nenalezen v channels.conf, použije se výchozí.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" "input_dvb: neplatná specifikace kanálu, použije se naposledy sledovaný\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "input_dvb: neplatná specifikace kanálu, použije se výchozí kanál 0\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" "input_dvb: bylo uvedeno MRL DVBS, ale nezdá se, že by tuner byl QPSK (DVB-" "S)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: bylo uvedeno MRL DVBT, ale nezdá se, že by byl tuner OFDM (DVB-" "T)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: bylo uvedeno MRL DVBC, ale nezdá se, že by byl tuner QAM (DVB-C)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" "input_dvb: bylo uvedeno MRL DVBA, ale nezdá se, že by byl tuner ATSC (DVB-" "A)\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: nelze otevřít zařízení dvr '%s'\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "input_dvb: nelze vytvořit vlákno na aktualizace EPG\n" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "použít 'středový výsek' DVB (zvětšení)" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Toto dovolí přehrát obsah 4:3 na celé obrazovce, který byl přenášen ve " "formátu 16:9." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "vstupní modul DVB (digitální TV)" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Pamatovat si naposledy sledovaný kanál DVB" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" "Při automatickém přehrávání xine přepne na poslední kanál uvedený v media." "dvb.last_channel." #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Naposledy sledovaný kanál DVB" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" "Pokud je povoleno, xine si bude pamatovat tento kanál a bude se na něj " "automaticky přepínat." #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "Počet sekund, než nechat ukončit ladění." #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" "Ponechání na 0 znamená zkoušet bez přestání. Více než 0 znamená čekat na " "získání zámku uvedený počet sekund. Minimum je 5 sekund." #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "Povolit rozhraní DVB" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "Povolí rozhraní DVB - nahrávání a přepínání kanálů řízené myší." #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Počet karet DVB, které se mají použít." #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" "Nechte to na nule, pokud opravdu nechcete ve vašem systému více než jednu " "kartu." #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" "input_dvd: values of \\beta will give rise to dom! (pět korun za překlad)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Chyba získání bloku z DVD (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: chyba otevírání zařízení DVD\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "zařízení použité pro přehrávání DVD" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "Cesta k zařízení, obvykle DVD mechanice, které chcete používat pro " "přehrávání DVD." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "metoda dešifrování CSS" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" "Vybere metodu dešifrování, kterou libdvdcss použije k rozkódování DVD " "chráněních proti kopírování. Pokud máte problémy s přehráváním zakódovaných " "DVD, vyzkoušejte různé metody." #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "DVD přehrávač tvrdí, že je v oblasti (1 až 8)" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "Toto je nutné změnit pouze, pokud vaše DVD skočí na obrazovku stěžující si " "na špatný kód oblasti. Nemá to nic dělat s kódem oblasti nastaveným v DVD " "mechanikách, je to čistě softwarové." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "výchozí jazyk pro přehrávání DVD" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine zkusí tento jazyk použít jako výchozí pro přehrávání DVD. Pokud to DVD " "bude podporovat, volby a zvukové stopy budou prezentovány v tomto jazyce.\n" "Hodnotou musí být dva znaky jazykového kódu ISO639." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "read-ahead cachování" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" "xine může používat pro přístup k jednotce DVD cachování s dopředným čtením.\n" "To může vést na pomalých mechanikách ke škubavému přehrávání, ale na " "rychlejších mechanikách to zlepší výsledek změny vrstvy DVD." #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" "Můžete nakonfigurovat chování při vyvolání akce skoku (např. použitím " "tlačítek pro skákání). Jednotlivé hodnoty znamenají:\n" "\n" "skip program\n" "přeskočí DVD program, což je navigační jednotka podobná indexovým značkám na " "zvukových CD; toto je normální chování pro DVD přehrávače\n" "\n" "skip part\n" "přeskočí DVD část, což je stavební jednotka podobná značkám stop na zvukovém " "CD; části se obvykle shodují s programy, ale mohou být delší než programy\n" " \n" "skip title\n" "přeskočí DVD titul, což je stavební jednotka reprezentující celé DVD" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "jednotka pro nastavení pozice" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" "Můžete konfigurovat rozsah vyměřený ukazatelem pozice. Jednotlivé hodnoty " "znamenají:\n" "\n" "seek in program chain\n" "nastavování pozice se týká celé sady programů DVD, což je navigační jednotka " "reprezentující veškeré video současného dějství\n" "\n" "seek in program\n" "nastavování pozice se týká programu DVD, což je navigační jednotka " "reprezentující kapitolu současného dějství" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "režim přehrávání, když je zadán titul nebo kapitola" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" "Můžete přizpůsobit chování při přehrávání daného titulu nebo kapitoly z DVD " "(např. použitím MRL 'dvd:/1.2'). Jednotlivé hodnoty znamenají:\n" "\n" "entire dvd\n" "přehrát celé DVD od uvedené pozice.\n" "\n" "one chapter\n" "přehrát pouze uvedený titul nebo kapitolu a zastavit" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Přístup odepřen: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Soubor nenalezen >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: Soubor prázdný: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "modul pro vstup ze souboru" #: src/input/input_file.c msgid "file browsing start location" msgstr "počáteční umístění při procházení souborů" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "Prohlížeč vybírající soubor k přehrání začne na tomto umístění." #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "modul pro vstup ze souboru" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "modul pro vstup ze souboru" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "vstupní modul gnome-vfs dodaný se xine" #: src/input/input_helper.c msgid "list hidden files" msgstr "ukazovat skryté soubory" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" "Pokud je povoleno, bude prohlížeč vybírající soubor k přehrání ukazovat také " "skryté soubory." #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "vstupní modul pro data ze standardního vstupu" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: selhalo gethostbyname(%s): %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: chyba čtení %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Připojuje se k HTTP serveru..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: neplatná odpověď http\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: přesměrování 3xx: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: stav http není 2xx: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: délka obsahu = % bytů\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: buffer vyčerpán po %d bytech" #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "vstupní modul http" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "HTTP proxy host" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "Hostitelské jméno HTTP proxy." #: src/input/input_http.c msgid "HTTP proxy port" msgstr "HTTP proxy port" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "Číslo portu HTTP proxy." #: src/input/input_http.c msgid "HTTP proxy username" msgstr "Uživatelské jméno HTTP proxy" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "Uživatelské jméno pro HTTP proxy." #: src/input/input_http.c msgid "HTTP proxy password" msgstr "Heslo HTTP proxy" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "Heslo pro HTTP proxy." #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Domény, pro které ignorovat HTTP proxy" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Seznam doménových jmen oddělených čárkami, pro které bude ignorováno proxy.\n" "Pokud bude doménové jméno začínat na '=', pak bude zpracováno pouze jako " "hostitelské jméno (bude vyžadována rovnost celého jména)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "vstupní modul mms pro streamovaná data" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "šířka pásma sítě" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "Uveďte zde šířku pásma vašeho internetového připojení. To bude použito v " "případě, že streamovací servery poskytnou různé verze stejných dat s " "rozdílnými požadavky na šířku pásma." #: src/input/input_mms.c msgid "MMS protocol" msgstr "protokol MMS" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Vyberte protokol zapouzdřující MMS. TCP je lepší, ale za firewallem můžete " "potřebovat HTTP." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "vstupní modul pro data ze standardního vstupu" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "vstupní modul pro síť dodaný se xine" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "modul pro vstup ze souboru" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "modul pro vstup ze souboru" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "vstupní modul pro data ze standardního vstupu" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "vstupní modul pnm pro streamovaná data" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: chyba vytváření souboru pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: chyba otevírání souboru pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: chyba čtení (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: chyba otevírání zařízení %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "input_pvr: selhalo IVTV_IOC_G_CODEC, možná se změnilo API?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "input_pvr: selhalo IVTV_IOC_S_CODEC, možná se změnilo API?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "Vstupní modul WinTV-PVR 250/350" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "zařízení použité pro WinTV-PVR 250/350 (modul pvr)" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "Cesta k zařízení vaší karty WinTV." #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "Uvedená IP adresa je multicast\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Nelze nalézt adresu rozhraní %s:%s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) selhalo (jádro s multicastem?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "nelze zjistit adresu '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "nelze se připojit k '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: ukončuje se čtecí vlákno...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: čtecí vlákno ukončeno\n" #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Otevírání >soubor:%s port:%d rozhraní:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: nelze vytvořit nové vlákno (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "vstupní modul pro RTP a UDP dodaný se xine" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "vstupní modul rtsp pro streamovaná data" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "Vstupní modul CIFS/SMB založený na libsmbclient" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "modul pro vstup ze souboru" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "modul pro vstup ze souboru" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: selhalo otevření '%s'\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "vstupní modul pro data ze standardního vstupu" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "vstupní modul v4l tv" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Buffer podtekl..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Buffer přetekl..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Přizpůsobuje se..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Jméno tuneru nenalezeno\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "vstupní modul v4l tv" #: src/input/input_v4l.c msgid "v4l video device" msgstr "zařízení videa v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Cesta k vašemu zařízení videa Video4Linux." #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "vstupní zvukové zařízení v4l ALSA" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "Název zvukového zařízení, které koresponduje s vaším Video4Linux." #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "TV standard v4l" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" "Vybírá televizní standard vstupního signálu. Buď AUTO, PAL, NTSC nebo SECAM." #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "vstupní modul v4l rádio" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "zařízení rádia v4l" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Cesta k vašemu zařízení rádia Video4Linux." #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: Neplatné MRL. Použijte vcdo:/\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: neplatná stopa %d (platný rozsah: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "nelze otevřít %s: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: nelze otevřít %s: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "Vstupní modul pro video CD" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "zařízení použité pro přehrávání VCD" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" "Cesta k zařízení, obvykle CD nebo DVD mechanika, se kterým zamýšlíte " "přehrávat VideoCD." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: špatné MRL: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: nelze se připojit k '%s'\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: nelze se připojit k serveru %s\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: nelze zavést relaci.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" "rtsp_session: rtsp server vrátil příliš velké hlavičky, nemůže být zřízeno " "sezení.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "rtsp_session: typ rtsp serveru '%s' ještě není podporován. bohužel.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "input_dvd: Selhalo otevření zařízení %s během volání vysunutí\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Připojuje se k MMS serveru (přes TCP)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: chyba při posílání\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: špatný formát odpovědi\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: přesměrování 3xx není implementováno: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: stav http není 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: Přesměrování umístění není implementováno\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Připojuje se k MMS serveru (přes HTTP)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "neplatné URL\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "nepodporovaný protokol\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "přednost režimu TV" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "přednost režimu TV" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: během čtení proudu dat přišla zpráva ze serveru:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: nelze se připojit k '%s'\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: selhalo nastavení proudu dat\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR není implementováno pro nenulovou hodnotu posuvu" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END ještě není implementováno." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "posuv ještě není implementován" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "špatný typ položky" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "špatné číslo položky" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "špatné číslo segmentu" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Chyba při získávání čísla aktuálního segmentu" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Výše uvedené by mělo být převedeno" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "selhalo hledání zařízení s VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "byl předán parametr třídy null" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Neplatný typ aktuální položky" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "výběr nemá položku NÁVRAT" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "VÝCHOZÍ vybráno, ale PBC není zapnuto." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "výběr nemá položku DALŠÍ" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "výběr nemá položku PŘEDCHOZÍ" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Neznámý typ události: " #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "modul video CD s PBC a podporou: (X)VCD, (X)SVCD, HQVCD, CVD ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "výchozí typ VCD, který se použije na automatické přehrání" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "Jednotka přehrávání VCD, kterou použít, jestliže není žádná uvedena v MRL. " "Např. vcd:// nebo vcd:///dev/dvd:" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "výchozí zařízení CD-ROM použité pro VCD, jestliže není žádné zadáno" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Co použít, jestliže není uvedeno zařízení. Jestliže je nastavení prázdné, " "xine prozkoumá jednotky CD." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "rozsah ukazatele pozice VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "Rozsah ukazatele pozice přehrávání přítomného při přehrávání." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "read-ahead cachování VCD?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "Na slabších strojích může toto vést k trhanému přehrávání" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "automaticky postupovat po stopách nebo položkách VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Jestliže je povoleno, měli bychom automaticky postoupit na další položku " "nebo stopu. Použito pouze, když není zapnuta kontrola přehrávání (PBC)." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "zobrazit 'odmítané' VCD LID?" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" "Některé identifikátory seznamů přehrávání (LID) bývají označeny, aby se " "nezobrazovaly. Ale pokud je nastavena tato volba, můžete je vidět v seznamu " "MRL. Odmítané položky jsou označeny hvězdičkou (*) přidanou na konec MRL." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "VCD formát řetězce pro nápis na obrazovce" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" "Formát VCD použitý v nadpisu GUI. Podobá se unixovému příkazu date. " "Specifikátory formátu začínají znakem procento. Specifikátory jsou:\n" " %A : informace o albu\n" " %C : čítač svazků VCD - počet CD v kolekci.\n" " %c : číslo svazku VCD - číslo CD v kolekci.\n" " %F : formát VCD, např. VCD 1.0, VCD 1.1, VCD 2.0 nebo SVCD\n" " %I : aktuální typ položky/segmenty/přehrávání, např. ENTRY, TRACK, ...\n" " %L : ID playlistu začínající \" LID\", pokud existuje\n" " %N : aktuální číslo ID playlistu - desítkové číslo\n" " %P : ID nakladatele\n" " %p : ID připravovatele\n" " %S : pokud jsme v segmentu (menu), druh segmentu\n" " %T : číslo stopy\n" " %V : ID sady svazků\n" " %v : ID svazku\n" " číslo 1 až počet svazků\n" " %% : %\n" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "formátovací řetězec VCD pro pole komentáře proudu dat" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "Formát VCD použitý v titulku GUI. Podobá se unixovému příkazu date. " "Specifikátory formátu začínají znakem procento. Specifikátory jsou %A, %C, %" "c, %F, %I, %L, %N, %P, %p, %S, %T, %V, %v a %%.\n" "Jejich význam viz nápověda k title_format." # odvšivovací #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "debugovací maska příznaků VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" "Pro stopování chyb v modulu VCD. Hodnoty masek jsou:\n" " 1: meta informace\n" " 2: události vstupu (klávesnice, myš)\n" " 4: parsování MRL\n" " 8: volání z vnějších podprogramů\n" " 16: volání podprogramů\n" " 32: změny LSN\n" " 64: řízení přehrávání\n" " 128: debugování z CDIO\n" " 256: změna pozice k nastavení pozice\n" " 512: změna pozice k nalezení aktuální pozice\n" "1024: nehybný snímek\n" "2048: debugování z VCDINFO\n" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "cesta ke kodekům Real Playeru" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "Pokud máte nainstalovaný RealPLayer, uveďte zde cestu k adresáři s jeho " "kodeky. Adresář s kodeky můžete jednoduše nalézt hledáním souboru \"drv3." "so.6.0\", který je v něm. Pokud bude moci xine nalézt kodeky RealPlayeru, " "použije je pro vás k dekódování RealPlayer obsahu. Více informací, jak " "nainstalovat kodeky, získáte z xine FAQ." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (audio) Nelze zjistit symboly - nekompatibilní dll: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "libareal: selhala inicializace dekodéru, chybový kód: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "libareal: nastavení esence dekodéru selhalo, chybový kód: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: jejda, real může mít více než 2 kanály?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "libreal: Chyba hledání symbolů! (nekompatibilita verzí?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "cesta ke kodekům WIN32" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "Pokud máte nainstalované kodeky Windows nebo Apple Quicktime, uveďte zde " "cestu k tomuto adresáři s kodeky. Pokud bude moci xine nalézt kodeky Windows " "nebo Apple Quicktime, použije je pro vás k dekódování různých dat Windows " "Media a Quickime. Více informací, jak nainstalovat kodeky, získáte ve xine " "FAQ." #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "modul zvukového výstupu xine do souboru" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "w32codec: Selhalo ICOpen! neznámý kodek %08lx nebo špatné parametry?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "w32codec: Selhalo ICDecompressGetFormat (%.4s %08lx/%d): Chyba %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: Selhalo ICDecompressQuery: Chyba %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: Selhalo ICDecompressBegin: Chyba %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: Selhal DS_VideoDecoder! neznámý kodek %08lx nebo špatné " "parametry?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: Selhal DMO_VideoDecoder! neznámý kodek %08lx nebo špatné " "parametry?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: selhalo spuštění dekodéru. Je nainstalován '%s?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Neadekvátní zvukový formát\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) chyba acmStreamOpen%d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Chyba inicializace DirectShow zvuku\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Chyba inicializace DMO zvuku\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" "Tento filtr bude provádět časové natahování - sekvence se přehraje rychleji " "nebo pomaleji podle násobku. Rozteč je volitelně zachovávána, takže je možné " "např. použít tento filtr ke shlédnutí filmu v kratším čase, než byl původně " "natočen.\n" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" "Funkce upmixu, např. vzít vstup stereo a vydat výstup Surround 5.1.\n" "Parametry\n" " cut_off_freq\n" "\n" "Poznámka: K nastavení těchto parametrů je možné použít řídící okno " "frontendu.\n" "\n" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" "Tento filtr namixuje mono data na stereo opakováním kanálů. Také můžete " "použít tento modul, aby poslouchal v daných datech pouze jeden kanál.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": namixování Mono na Stereo.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] ": namixování jednoho kanálu z %d kanálu v původních datech.\n" msgstr[1] ": namixování jednoho kanálu z %d kanálů v původních datech.\n" msgstr[2] ": namixování jednoho kanálu z %d kanálů v původních datech.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": zvukové zařízení nemá schopnost AO_CAP_MODE_STEREO.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr ": namixování Mono na Stereo." #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" "Normalizuje audio na maximální úroveň bez zkreslení zvuku.\n" "\n" "Parametry:\n" " metoda 1: použít jeden vzorek na vyhlazení variací využitím standardního " "váženého průměru přes předchozí vzorky (výchozí); 2: použít několik vzorků " "na vyhlazení variací využitím standardního váženého průměru přes předchozí " "vzorky.\n" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" "Zdokonalený modul tvtime/deinterlacer s pulldown detekcí\n" "Tento modul má za cíl poskytnout mechanizmy korekce prokládání srovnatelné s " "vysoce kvalitními postupnými přehrávači DVD a takzvanými \"zdvojovači řádek" "\" (line-doublers) pro použití s počítačovými monitory, projektory a jinými " "postupnými zobrazovacími zařízeními.\n" "\n" "Parametry\n" "\n" " Method: Vybrat metodu (algoritmus), kterou použít. Vysvětlení všech metod " "je dále.\n" "\n" " Enabled: Povolit nebo zakázat modul.\n" "\n" " Pulldown: Vybrat detekční algoritmus 2-3 pulldown. Filmy s rychlostí 24 " "snímků/s, které byly konvertovány do NTSC mohou být detekovány a " "inteligentně rekonstruovány do původních (neprokládaných) snímků.\n" "\n" " Framerate_mode: Vybráním 'full' se bude korigovat prokládání každého " "půlsnímku do unikátního snímku. Získá se tím televizní nebo i vyšší kvalita. " "Tato funkce účinně zdvojnásobí rychlost snímků, což zlepší hladkost. " "Poznamenejme však, že plných 59.94 snímků/s nelze dosáhnout s neupraveným " "jádrem Linuxu 2.4 (to používá frekvenci přerušení časovače 100 Hz). Novější " "jádra RedHatu a jádra 2.6 používají vyšší nastavení HZ (512 a 1000, v " "pořadí) a měly by v pohodě fungovat.\n" "\n" " Judder_correction: Je-li povoleno 2-3 pulldown a je detekován filmový " "materiál, je možné omezit rychlost snímků na původní použitou rychlost (24 " "snímků/s). To způsobí, že snímky budou rovnoměrně rozložené v čase. Jejich " "čas bude souhlasit a eliminuje se chvění.\n" "\n" " Use_progressive_frame_flag: Dobře nahrané streamy MPEG2 používají příznak " "k indikaci postupného materiálu. Toto nastavení řídí, zda věříme či nevěříme " "tomuto příznaku (některé ojedinělé chybné streamy mpeg2 ho mají nastavený " "špatně).\n" "\n" " Chroma_filter: DVD/MPEG2 používá prokládaný obrazový formát, který má " "velmi špatné svislé barevné rozlišení. Převzorkování barvy na vyšší " "rozlišení pro účely korekce prokládání může způsobit vytvoření artefaktů " "(např. barevné pruhy). Tuto volbu použijte k svislému rozmazání barvy po " "korekci prokládání, což odstraní tyto artefakty. Varování: náročné na CPU.\n" "\n" " Cheap_mode: Toto přeskočí nákladnou konverzi obrazu YV12->YUY2 a rutiny " "tvtime/dscaleru budou používány, jako by stále zpracovávaly obrazy YUY2." "Samozřejmě to není správně, ne všechny body budou vyhodnoceny algoritmem pro " "rozhodování o oblastech ke korekci a barva bude zpracována odděleně. Nicméně " "toto dovolí lidem s ne tak rychlými systémy vyzkoušet si algoritmus korekce " "prokládání, v kompromisu mezi kvalitou využitím CPU.\n" "\n" "* Používá několik algoritmů z projektů tvtime a dscaler.\n" "Metody korekce prokládání: (ne všechny metody jsou k dispozici pro všechny " "platformy)\n" "\n" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: Nejsou k dispozici žádné metody korekce prokládání, konec.\n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "snímků generovaných za sekundu" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "S více snímky za sekundu bude animace hladší a rychlejší, ale také to bude " "vyžadovat více výkonu CPU." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "šířka obrazu Goomu" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "Šířka generovaného obrazu v pixelech." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "výška obrazu Goomu" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "Výška generovaného obrazu v pixelech." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "metoda konverze barev" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" "Můžete vybrat metodu konverze barevného prostoru použitou goomem.\n" "Výběry k dispozici by měly být samovysvětlující." #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico dělá jednoduché efekty obraz v obrazu.\n" "\n" "Parametry\n" " pip_num: počet obrazových slotů, na které použít následující nastavení\n" " x: x-ová souřadnice levého horního rohu obrazu\n" " y: y-ová souřadnice levého horního rohu obrazu\n" " w: šířka obrazu\n" " h: výška obrazu\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Přepínač může být použit pro rychlé přepínání mezi vícero vstupy.\n" "\n" "Parametry\n" " select: počet vstupů, které projdou na výstup\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Box blur provádí jednoduché rozmazání obrazu.\n" "\n" "Parametry:\n" " Radius: rozměr filtru\n" " Power: jak často by měl být filtr použit\n" "\n" "* boxblur mplayeru (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Tento filtr má za cíl snížit šum obrazu produkováním vyhlazených snímků a " "děláním nehybného obrazu skutečně nehybným (to by mělo zvýšit " "komprimovatelnost). Může být zadáno od 0 do 3 parametrů. Jestliže vynecháte " "parametr, bude odhadnuta přiměřená hodnota.\n" "\n" "Parametry\n" " Luma: prostorová intenzita světlosti (implicitní = 4)\n" " Chroma: prostorová intenzita sytosti (implicitní = 3)\n" " Time: dočasná intenzita (implicitní = 6)\n" "\n" "* denoise3d mplayeru (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" "Alternativní softwarový ekvalizér, který pro jednoduchou úpravu světlosti, " "kontrastu a sytosti používá vyhledávací tabulky. Je to velmi pomalé, ale " "umožňuje to navíc gama korekci.\n" "Poznamenejme ještě, že se používá stejný kód optimalizovaný pro MMX jako u " "'eq', pokud jsou všechny hodnoty gama 1.0.\n" "\n" "Parametry\n" " gama\n" " jas\n" " kontrast\n" " sytost\n" " rgama (gama pro červenou složku)\n" " ggama (gama pro zelenou složku)\n" " bgama (gama pro modrou složku)\n" "\n" "Rozsahy hodnot jsou 0.1 - 10 pro gamy, -2 - 2 pro kontrast (negativní " "hodnoty mají za následek negativní obraz), -1 - 1 pro jas a 0 - 3 pro " "sytost.\n" "\n" "* eq2 mplayeru (C) Hampa Hug, Daniel Moreno, Richard Felker\n" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" "Softwarový ekvalizér s interaktivním ovládáním tak jako u hardwarového " "ekvalizéru pro karty, které nepodporují řízení jasu a kontrastu hardwarově.\n" "Parametry\n" " světlost\n" " kontrast\n" "\n" "Poznámka: K nastavení těchto parametrů je možné použít okno ovládání " "frontendů.\n" "\n" "* eq mplayeru (C) Richard Felker\n" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" "Modul expand je určen k tomu, aby bral snímky s libovolnými poměry stran a " "konvertoval je na jiný poměr (výchozí je 4:3) přidáním černých pruhů nahoru " "a dolů. To dovolí posunovat OSD nebo titulky tak, že nezasahují do obrazu.\n" "\n" "Parametry (FIXME: lepší nápověda)\n" " Enable_automatic_shift: Povolí automatické posunutí\n" " Overlay_y_offset: Ruční posun svisle\n" " aspect: Vybraný poměr stran (výchozí je 4:3)\n" " Centre_cut_out_mode: vytáhne obraz 4:3 obsažený v 16:9\n" "\n" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" "Přidává do videa náhodný šum.\n" "\n" "Parametry:\n" " luma_strength: intenzita šumu přidaného ke kanálu luma (0-100, výchozí: " "8)\n" " chroma_strength: intenzita šumu přidaného ke kanálu chroma (0-100, výchozí " "5)\n" " quality: úroveň kvality šumu. fixed: konstantní vzorek šumu; temporal: " "vzorek šumu se mezi snímky mění; averaged temporal: vzorek šumu, který se " "mění mezi snímky plynule. (výchozí: averaged temporal)\n" " type: typ šumu: uniform nebo gaussian. (výchozí: gaussian)\n" " pattern: míchat náhodný šum s polopravidelným vzorkem. (výchozí: False)\n" "\n" "* noise mplayeru (C) Michael Niedermayer\n" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "libpostprocess modul FFmpeg.\n" "\n" "Parametry\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" "Rozostřovací maska / gaussovské rozmazání\n" "Je možné nastavit šířku a výšku matice s lichými velikostmi v obou směrech " "(min = 3x3, max = 13x11 nebo 11x13, obvykle něco mezi 3x3 až 7x7) a poměrné " "množství ostrosti/rozmazání, které se má přidat k obrazu (rozumný rozsah by " "měl být -1.5 - 1.5).\n" "\n" "Parametry\n" "\n" " Luma_matrix_width: Šířka matice (musí být lichá)\n" "\n" " Luma_matrix_height: Výška matice (musí být lichá)\n" "\n" " Luma_amount: Poměrné množství ostrosti nebo rozmazání (=0 zakázat, <0 " "rozmazat, >0 zostřit)\n" "\n" " Chroma_matrix_width: Šířka matice (musí být lichá)\n" "\n" " Chroma_matrix_height: Výška matice (musí být lichá)\n" "\n" " Chroma_amount: Poměrné množství ostrosti nebo rozmazání (=0 zakázat, <0 " "rozmazat, >0 zostřit)\n" "\n" "\n" "* unsharp mplayeru (C) 2002 Rémi Guyomarch\n" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "font externích titulků" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "vertikální posun titulků (vzhledem k velikosti okna)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "kódování titulků" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "výchozí doba zobrazení titulků v sekundách" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Některé formáty titulků neobsahují explicitně trvání každého titulku.Pro " "takové formáty zde můžete nastavit výchozí dobu trvání. Nastavení na nulu " "bude mít za následek, že titulek bude vždy zobrazen tak dlouho, než se " "objeví další." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "velikost titulků" # FIXME: correct original? #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" "Zde můžete upravit velikost titulků. Nastavení bude bráno relativně k " "velikosti okna." #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "vertikální posun titulků" # FIXME: correct original? #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" "Můžete upravit svislou polohu titulků. Nastavení bude bráni relativně k " "velikosti okna." #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "font titulků" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "Font z adresáře fontů xine, který se použije na text s titulky." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" "Vnější font jako soubor (např. .ttf), který se použije na text s titulky." #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "jestli použít vnější font freetype" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "kódování titulků" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "Kódování textu titulků ve streamu dat. Toto nastavení se používá ke " "správnému renderování znaků, které nejsou v ASCII. Jestliže nejsou takové " "znaky zobrazeny tak, jak očekáváte, zeptejte se toho, kdo titulky vytvářel, " "jaké bylo použito kódování." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "používat OSD bez změn měřítka, je-li to možné" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" "OSD bez změn měřítka bude renderováno nezávisle na snímku videa a bude vždy " "ostré, dokonce když se zvětší video. Vypadá to lépe, ale nefunguje to na " "každém grafickém hardwaru. Druhá možnost je škálované OSD, které se stane " "rozmazané, jestliže rozšíříte video s nízkým rozlišením na celou obrazovku, " "ale funguje na všech grafických kartách." #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "zobrazovat skryté titulky v sekvencích MPEG-2" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" "Skryté titulky jsou titulky určené hlavně na pomoc sluchově postiženým." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "podoba skrytých titulků (popředí/pozadí)" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Vyberte váš oblíbený způsob vykreslování skrytých titulků." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "standardní font skrytých titulků" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Vyberte font pro normální text u skrytých titulků." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "font kurzívy skrytých titulků" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "Vyberte font pro text kurzívy u skrytých titulků." #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "velikost fontu skrytých titulků" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "Vyberte velikost fontu pro text skrytých titulků." #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "přizpůsobení centrování skrytých titulků" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" "Pokud je povoleno, skryté titulky budou umisťovány doprostřed jednotlivých " "řádků." #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "%s: nelze vytvořit nové vlákno (%s)\n" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: chyba při provádění dekomprese ByteRun1\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: V tomto okamžiku není Anim Opt 1 podporován\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: V tomto okamžiku není Anim Opt 2 podporován\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: V tomto okamžiku není Anim ASCIIJ podporován\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: V tomto okamžiku není tento typ anim podporován\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c #, fuzzy msgid "image video decoder plugin" msgstr "Počet vláken na dekódování videa FFmpegem" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c #, fuzzy msgid "mpeg2 based video decoder plugin" msgstr "Počet vláken na dekódování videa FFmpegem" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "výstupní modul videa xine použije knihovnu AsCii Art" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "výstupní modul videa xine použije knihovnu Color AsCii Art" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "režim bufferování vrstvy videa" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" "Vyberte režim bufferování výstupní vrstvy. Dvojité nebo trojité bufferování " "dává hladší přehrávání, ale spotřebuje více videopaměti." #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "čekat na zpětný běh" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" "Povolí synchronizaci změn obrazu videa s překreslováním celé obrazovky " "(\"vertikální zpětný běh paprsku\")." #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "povolit klíčovou barvu videa" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" "Povolí použití klíčové barvy, která říká grafické kartě, kde vykreslovat " "obraz videa." #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "klíčová barva videa" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" "Klíčová barva je používána k informování grafické karty, kam vykreslit obraz " "videa. Jestliže zjistíte, že se okna stávají transparentní, vyzkoušejte jiné " "hodnoty." #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "filtr mihotání" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" "Povolí filtr mihotání k docílení hladkého výstupu na prokládaném zobrazovači." #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "parita pole" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" "U prokládaného zobrazovače, povolí řízení parity pole (\"none\" znamená " "zakázáno)." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" "video_out_directfb: použije se hardwarově urychlované renderování titulků.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "video_out_directfb: vrstva podporuje výstup videa.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "video_out_directfb: vrstva nepodporuje YV12!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "video_out_directfb: vrstva nepodporuje YUY2!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" "video_out_directfb: k přehrávání na této vrstvě potřeba minimálně DirectFB " "0.9.25!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "video_out_directfb: vrstva nepodporuje režim bufferování %d!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "video_out_directfb: vrstva nepodporuje volby 0x%08x!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" "video_out_directfb: použije se hardwarově urychlované škálování obrazu.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" "video_out_directfb: škálování obrazu s korekcí prokládání je hardwarově " "urychlované.\n" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "ID vrstvy videa (auto: -1)" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "Vybere vrstvu výstupu videa podle jeho ID." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "video_out_directfb: použije se obrazová vrstva #%d.\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "výstupní modul videa xine použije DirectFB." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" "video_out_directfb: žádná použitelná obrazová vrstva nebyla nalezena!\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "výstupní modul videa xine použije DirectFB pod XDirectFB." #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "výstupní modul videa xine pro win32 používající directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: jsou podporovány pouze pravé barvy (truecolor/directcolor) (%" "d).\n" " Zkontrolujte 'fbset -i' nebo zkuste 'fbset -depth 16'.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "jméno zařízení framebufferu" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" "Specifikuje jméno souboru pro framebuffer, které se má použít.\n" "Toto nastavení je kritické s ohledem na bezpečnost, protože při změně na " "jiný soubor může být xine použito k vyplnění tohoto souboru libovolným " "obsahem. A tak by jste si měli být jistí, že hodnota, kterou zadáváte, " "skutečně je náležité zařízení framebufferu." #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Váš videorežim nebyl rozpoznán, bohužel.\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: je k dispozici %d video RAM bufferů.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "VAROVÁNÍ: %s: Buffery s nulami jsou ZAKÁZÁNY, protože je k dispozici\n" " pouze %d bufferů, což je méně než doporučovaných %d bufferů.\n" " Mohlo by pomoci snížení rozlišení bufferu.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "VAROVÁNÍ: %s: Buffery s nulami jsou ZAKÁZÁNY, protože ovladač jádra\n" " nepodporuje \"screen panning\" (použito pro přepínání snímků).\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "VAROVÁNÍ: %s hloubka současného displeje je %d. Pro lepší výkon\n" "je doporučována hloubka 16 bitů/bod!\n" "\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "výstupní modul videa xine použije zařízení framebuffer" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "výstupní modul videa xine použije DirectFB." #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "výstupní modul videa xine, které nezobrazuje nic" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "výstupní modul videa xine použije OpenGL 2.0." #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "renderer OpenGL" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" "Modul OpenGL poskytuje několik renderovacích modulů:\n" "\n" "2D_Tex_Fragprog\n" "Tento modul zavádí obraz jako 2D YUV textury a rendruje texturovaný plát\n" "za použití programových fragmentů na rekonstruování RGB.\n" "Na moderních grafických kartách je toto nejlepší a nejrychlejší metoda.\n" "\n" "2D_Tex\n" "Tento modul zavádí obraz jako 2D textury a renderuje texturovaný plát.\n" "\n" "2D_Tex_Tiled\n" "Tento modul zavádí obraz jako vícero 2D textur a rendruje texturovaný\n" "plát. A tak to pracuje s menšími maximálními velikostmi textur.\n" "Image_Pipeline\n" "Tento modul používá k renderování obrázků glDraw().\n" "Urychlované pouze v několika ovladačích.\n" "Neinterpoluje škálování.\n" "\n" "Cylinder\n" "Zobrazuje obrázky na rotačním válci. Hezký efekt :)\n" "\n" "Environment_Mapped_Torus\n" "Zobrazuje obrázky odražené v otáčejícím se anuloidu. Hezký způsob =)" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "minimální rychlost snímků OpenGL" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" "Minimální rychlost snímků animačních renderovacích podprogramů.\n" "Ignorováno u statických renderovacích podprogramů.\n" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "povolit dvojité bufferování" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" "V případě dvojitého bufferování u OpenGL to odstraňuje nejen trhavé " "artefakty,\n" "ale také to velmi redukuje třepotání.\n" "Nemělo by to mít žádný dopad na výkon." #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "výstupní modul videa xine používající OpenGL 3D grafické API" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "video_out_pgx32: Chyba: nelze použít DGA drawable okno videa\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_dxr3: Chyba: selhalo ioctl, špatné zařízení (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "video_out_pgx32: Chyba: '%s' není zařízení framebufferu pgx32\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "výstupní modul videa xine pro Sun PGX32 frame buffer" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx64: Chyba: nelze použít DGA drawable pro okno videa\n" "\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "video_out_pgx64: Chyba: nelze otevřít zařízení framebufferu '%s'\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Chyba: ioctl selhalo (VIS_GETIDENTIFIER), špatné zařízení (%" "s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Chyba: '%s' není zařízení framebufferu xvr100/pgx64/pgx24\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" "video_out_pgx64: Chyba: překrývání videa je na této obrazovce již používáno\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "video_out_pgx64: Chyba: nelze nastavit vlastnosti okna\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "video_out_pgx64: Varování: málo videopaměti, multi-buffering zakázán\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Chyba: nedostatek videopaměti\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Varování: málo videopaměti, double-buffering zakázán\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Chyba: selhalo ioctl (FBIOGATTR)\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "hodnota klíčové barvy překrývání" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" "Barevný klíč je použit k tomu, aby se řeklo grafické kartě, kam může " "zobrazit obraz videa. Pokud vidíte video zobrazované skrz jiná okna, " "vyzkoušejte jiné hodnoty." #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "povolit klíčování barvou" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" "Raději kreslit grafiku OSD nahoře na klíčové barvě overlay než ji míchat do " "každého snímku." #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "povolit multi-buffering" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "Multi buffering zvýší výkon na úkor využití více grafické paměti." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "výstupní modul videa xine pro Sun XVR100/PGX64/PGX24 frame buffer" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "použít hardwarovou akceleraci videa, je-li k dispozici" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "Pokud to systém podporuje, bude použita hardwarová akcelerace vašeho " "grafického hardwaru. Nemuselo by to správně fungovat, proto to můžete " "zakázat, pokud by to fungovalo chybně." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "SDL musí emulovat 16bitové povrchy, to vše zpomalí.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: celoobrazovkový režim NENÍ podporován\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "výstupní modul videa xine použije Simple Direct Media Layer" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" "výstupní modul videa xine použije knihovnu Libstk Surface Set-top Toolkit" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "výchozí počet videosnímků" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" "Výchozí počet videosnímků, který se bude žádat z videovýstupního ovladače " "xine. Některé ovladače použijí své vlastní hodnoty místo této." #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI colour conversion method" msgstr "metoda konverze barev" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "výstupní modul videa xine použije DirectFB." #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" # TODO #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "vdpau: Nepoužívat korekci prokládání pro postupné snímky." #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "výstupní modul videa xine použije VDPAU." #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "intenzita červené" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "Intenzita červené barevné složky." #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "intenzita zelené" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "Intenzita zelené barevné složky." #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "intenzita modré" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "Intenzita modré barevné složky." #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" "Dvojité bufferování synchronizuje aktualizaci obrazu videa s překreslováním " "úplné obrazovky (\"vertikální zpětný běh paprsku\"). Toto eliminuje blikání " "a trhané artefakty, ale bude použito více grafické paměti." #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: adaptér podporuje formát yuy2\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: adaptér podporuje formát yv12\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "video_out_vidix: Máte špatnou verzi knihovny VIDIX\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: Nelze nalézt fungující ovladač VIDIX\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: použije se ovladač: %s od %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "klíčová barva překrývání videa červené složky" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "klíčová barva překrývání videa zelené složky" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "klíčová barva překrývání videa modré složky" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "výstupní modul videa xine použije libvidix pro X11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "výstupní modul videa xine použije libvidix pro linux frame buffer" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "%s: => rozšíření MIT Shared Memory se nepoužije.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "%s: chyba sdílené paměti (chyba adresy) během alokování obrázku\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "VAROVÁNÍ: hloubka současného displeje je %d. Pro lepší výkon\n" "je doporučována hloubka 16 bitů/bod!\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "%s: Rozšíření MIT shared memory není na displeji přítomno.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: Váš videorežim nebyl rozpoznán, bohužel.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "výstupní modul videa xine použije rozšíření MIT X shared memory" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: tento adaptér podporuje formát %s.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: Rozšíření Xv není přítomno.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "%s: nepodařilo se otevřít Xv port %lu - najde se automaticky\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: Rozšíření Xv je přítomno, ale nepodařilo se nalézt použitelný port " "yuv12.\n" " Vypadá to, jako by váš grafický hardwarový ovladač " "nepodporoval Xv?!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: pro hardwarovou konverzi barevného prostoru a škálování se použije Xv " "port %d z adaptéru %s.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "povolit synchronizaci s vblank" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" "Tato volba synchronizuje aktualizaci obrazu videa s překreslováním úplné " "obrazovky (\"vertikální zpětný běh paprsku\"). To eliminuje blikání a trhané " "artefakty. Na kartách nVidia může být ještě třeba spustit \"nvidia-settings" "\" a v kartě XVideo Settings vybrat, se kterým zařízením obrazovky " "synchronizovat." #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "výstupní modul videa xine použije rozšíření MIT X video" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: pro hardwarovou konverzi barevného prostoru a škálování se použije Xv " "port %ld z adaptéru %s.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: rozšíření XvMC není přítomno.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: rozšíření Xv je přítomno, ale nebyl nalezen použitelný port " "yuv12\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xvmc: pro hardwarovou konverzi barevného prostoru a škálování\n" " se použije Xv port %ld z adaptéru %s\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " idct a akcelerace kompenzace pohybu\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " pouze akcelerace kompenzace pohybu\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " žádná podpora XvMC\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " S Overlay = %d; UnsignedIntra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "výstupní modul videa xine použije X video rozšíření XvMC" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "Přimět XvMC alokovat více snímků za účelem lepšího bufferování." #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" "Některé implementace XvMC dovolují více než 8 snímků.\n" "Tato volba, pokud je zapnuta, přiměje ovladač zkusit alokovat 15 snímků. " "Nutnost pro unichrome a live VDR.\n" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Šetření procesoru unichrome" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" "Šetří procesorový čas uspáváním, zatímco dekodér pracuje.\n" "Pouze pro jádra Linuxu řady 2.6 nebo 2.4 s multimediálním patchem.\n" "Experimentální.\n" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "Opravovat chybné barvy elementů XvMC" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" "V knihovně XvMC od NVidie je chyba, která způsobuje, že červené barvy OSD " "vypadají modře a naopak. Tato volba umožňuje chybu obejít.\n" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Použít 'bob' jako akcelerovanou metodu korekce prokládání." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" "Pokud je povoleno prokládání pro hardwarově akcelerované snímky,\n" "přepíná mezi vrchním a spodním polem k dosažení dvojnásobné rychlosti " "snímků.\n" # TODO #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "Nepoužívat korekci prokládání bob pro postupné snímky." #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" "Postupné snímky nepotřebují korekci prokládání, takže zakázat ji podle " "potřeby by mělo vést k lepšímu zobrazení.\n" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "Nepoužívat korekci prokládání bob, pokud je aktivní škálované OSD" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" "Korekce prokládání bob přidává k vodorovným linkám šum, takže zakázat ji " "podle potřeby by mělo vést k lepšímu zobrazení OSD.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: rozšíření XShape není k dispozici. Overlay bez změn měřítka " "zakázán.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "x11osd: chyba vytvoření okna. Overlay bez změn měřítka zakázán.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "x11osd: chyba vytváření mapy bodů. Overlay bez změn měřítka zakázán.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: overlay bez změn měřítka vytvořen (režim %s).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "klíčová barva pro automatické vykreslování" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Přimět Xv automaticky kreslit svou klíčovou barvu." #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "bilineární režim škálování" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" "Vybere bilineární režim škálování pro karty Permedia. Jednotlivé hodnoty " "jsou:\n" "\n" "Permedia 2\n" "0 - zakázat bilineární filtrování\n" "1 - povolit bilineární filtrování\n" "\n" "Permedia 3\n" "0 - zakázat bilineární filtrování\n" "1 - horizontální lineární filtrování\n" "2 - povolit plné bilineární filtrování" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "číslo Xv portu" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "Vybere, který port Xv použít (0 na autodetekci)." #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "obcházet chybu zarovnávání rozteče" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" "Některé chybové ovladače videa potřebují ke správně funkci tento workaround." #: src/video_out/xv_common.h msgid "video display method preference" msgstr "Upřednostněná metoda zobrazení videa" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" "Vybírá, která metoda zobrazení videa je upřednostňována. Detekce se provádí " "použitím oznámených jmen adaptérů Xv.\n" "(Platí jen při použití autodetekce portů Xv.)" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "filtr mihotání" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "zakázat přesné alfa míchání overlayů" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" "Jestliže zjistíte, že OSD nebo jiné overlaye jako DVD titulky mají v " "činnosti dopad na výkon, pak byste mohli povolit tuto volbu.\n" "Výsledkem bude, že alfa míchání overlayů bude méně přesné než předtím, ale " "také se sníží využití procesoru." #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: není k dispozici žádný modul ke zpracování '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: chyba, neznámý typ bufferu: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "počet bufferů zvuku" #: src/xine-engine/audio_decoder.c #, fuzzy msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Počet bufferů zvuku (každý o velikosti 8k), které xine použije ve své " "vnitřní frontě. Vyšší hodnoty znamenají hladší přehrávání u nespolehlivých " "vstupů, ale také zvýšené zpoždění a spotřebu paměti." #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: výpočet čekání není možný, pokud není k dispozici zvukové " "zařízení\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "Zápis do zvukové karty selhal. Zařízení považováno za odpojené.\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "8 bitů není ovladačem podporováno, konvertuje se na 16 bitů.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "mono není ovladačem podporováno, konvertuje se na stereo.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "stereo není ovladačem podporováno, konvertuje se na mono.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "metoda synchronizace zvuku a videa" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" "Do přehrávání zvuku a videa jsou zapojeny minimálně dvoje hodiny: systémové " "hodiny, ke kterým se synchronizují videosnímky, a hodiny ve vašem zvukovém " "hardwaru, které určují rychlost přehrávání zvuku. Tyto hodiny nikdy netikají " "stejnou rychlostí vyjma některých velmi vzácných případů, kdy jsou fyzicky " "identické. Obvykle bude dvojice hodin běžet po nějakém čase odlišně a xine " "nabízí dva způsoby, jak zachovat zvuk a video synchronizované:\n" "\n" "metronom feedback\n" "Toto je standardní metoda, která aplikuje napočítanou odchylku na video, " "jakmile přesáhne odchylka zvuku práh.\n" "\n" "resample\n" "U některého videohardware, který je limitován na pevnou rychlost snímků " "(jako jsou DXR3 nebo jiné dekódovací karty), výše uvedené nefunguje, protože " "video se nemůže odchýlit. Proto převzorkujeme zvuková data, aby byla delší " "nebo kratší a kompenzovalo to chybu zvukové odchylky. Toto nefunguje s " "digital passthrough, kde jsou zvuková data posílána do vnějšího dekodéru v " "digitální formě." #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "povolit převzorkovávání" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" "Pokud rychlost vzorků dekódovaného zvuku neodpovídá schopnostem vašeho " "zvukového hardware, je vyžadováno přizpůsobení - \"převzorkování" "\" (\"resampling\"). Zde můžete vybrat, zda je převzorkovávání povoleno, " "zakázáno nebo použito automaticky v případě potřeby." #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "vždy převzorkovat na danou frekvenci (0 zakáže)" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" "Některé ovladače zvuku nehlásí správně schopnosti zvukového hardwaru. " "Nastavením hodnoty jiné, než je nula, můžete vnutit převzorkovávání " "zvukových dat na danou rychlost." #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "posun pro digital passthrough" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Jestliže používáte vnější surround dekodér a zvuk je před nebo za videem, " "můžete zde zadat pevný posuv, který to bude kompenzovat.\n" "Jednotka hodnoty je jeden tik PTS, což je 1/90000 sekundy." #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "přehrávat zvuk i při pomalých a rychlých rychlostech" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" "Pokud povolíte tuto volbu, zvuk bude slyšet, i když rychlost přehrávání bude " "jiná než 1X. Samozřejmě bude slyšet zkresleně (nižší nebo vyšší výška). " "Pokud chcete experimentovat se zachováním výšky, můžete vyzkoušet místo " "tohoto modulu zvukový post modul 'stretch'." #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "hlasitost zvuku při startu" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Celková úroveň hlasitosti při startu." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "obnovit úroveň hlasitosti při startu" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "Pokud je zakázáno, xine nebude při spuštění měnit žádná nastavení mixeru." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: Litujeme, toto by se nemělo přihodit. Prosím restartujte xine.\n" # příliš mnoho svobody ;-) #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "xine-lib: buffer.c: Došlo k fatální chybě: PŘÍLIŠ MNOHO FREE\n" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "Stávající konfigurační soubor byl upraven novější verzí xine." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: VAROVÁNÍ: vaše konfigurace nebude uložena\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "configfile: VAROVÁNÍ: zápis konfigurace do %s selhal\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: VAROVÁNÍ: odstraní se pravděpodobně poškozený konfigurační " "soubor %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: VAROVÁNÍ: měli byste zkontrolovat záložní soubor %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: údaj '%s' nesmí být modifikován z MRL\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "info_helper: nelze zjistit aktuální kódovou stránku\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "info_helper: nepodporovaná konverze %s -> UTF-8, nebude prováděna\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": funkce open() by nikdy neměla být volána\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": vstupní modul není definován!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: čtení uložených dat selhalo: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: selhalo nastavení pozice: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: čtení vstupním modulem selhalo\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: chyba zápisu % bytů do souboru: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: funkce open() by nikdy neměla být volána\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: selhalo nastavení pozice\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: zahozeno % bytů\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: vstupní modul není definován!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: cílový adresář nebyl specifikován, prosím vyplňte volbu 'misc." "save_dir'\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "Vlastnost ukládání dat je zakázána, dokud nenastavíte v konfiguraci 'misc." "save_dir'." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: ukládání z tohoto zdroje není povoleno!\n" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine nemá dovoleno ukládat z tohoto zdroje (možná materiál chráněný " "autorskými právy?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: nebyl dán název souboru!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: chyba otevírání souboru %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: čekání ukončeno\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: čekání selhalo: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "selhalo získání stavu soketu" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Přístup odepřen\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Soubor nenalezen\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Spojení odmítnuto\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "map_decoder_list: není prostor pro dekodér, přeskočen.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: neznámý typ modulu %d v %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: neznámý typ %d staticky linkovaného modulu\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: ignoruje se zásuvný modul %s, nesprávná verze rozhraní %d " "(měla by být %d)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "load_plugins: dosažen limit počtu modulů, %s nemohl být nahrán\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" "load_plugins: dosažen limit počtu modulů, statický modul nemohl být nahrán\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "priorita dekodéru %s" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: demultiplexní modul %s neposkytuje prioritu, xine-lib použije " "výchozí hodnotu.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: vstupní modul %s neposkytuje prioritu, xine-lib použije " "výchozí hodnotu.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: nalezen modul %s:%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: přeskočí se adresář s moduly %s.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: nelze provést stat na %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nelze otevřít knihovnu modulu %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: nelze získat informace modulu z %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nelze (fáze 2) otevřít knihovnu modulu %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Co?! %s neobsahuje informace modulu.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" "Priorita poskytuje pořadí v případě, že by mohla být některá média " "zpracovávána více než jedním dekodérem.\n" "Priorita 0 povoluje výchozí prioritu dekodéru." #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: neznámá strategie %d zjišťování obsahu\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: použije se demultiplexor '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: nelze načíst zvukový modul <%s>\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" "load_plugins: automatické testování zvukového výstupu nenašlo žádný " "použitelný zvukový ovladač.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nelze uvolnit knihovnu modulu %s:\n" "%s\n" #: src/xine-engine/metronom.c #, fuzzy msgid "basic video to audio delay in pts" msgstr "v tomto souboru žádné video ani zvuk\n" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Nahrává se..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "nesprávná verze u fontu '%s'. očekávána %d, nalezena %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "font '%s-%d' je již nahrán, divné.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "načítání fontu '%s' selhalo (%d < %d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "osd: chyba přiřazení fontu %s pomocí FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "osd: chyba načítání fontu %s pomocí FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "osd: chyba hledání fontu %s pomocí FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "osd: chyba načítání fontu %s pomocí XDG\n" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: nelze inicializovat knihovnu ft2\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "osd: chyba při nastavování velikosti fontu (font není škálovatelný?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: neznámá sekvence začínající bytem 0x%02X v kódování \"%s\", přeskočí " "se\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: nelze zjistit aktuální kódovou stránku\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: nepodporovaná konverze %s -> %s, nebude prováděna\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: chyba načítaní glyfu\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: chyba v renderování glyfu\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: font není definován\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: chyba načítání glyfu %i\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: chyba při renderování\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "paleta (popředí-okraj-pozadí) použitá na titulky a OSD" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" "Paleta on-screen-display a některých formátů titulků, které samy o sobě " "nespecifikují žádnou barvu. Paleta je uvedena ve formě: popředí-okraj-pozadí." #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: není k dispozici žádný modul ke zpracování '%s'\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: chyba, neznámý typ bufferu: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "počet bufferů videa" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" "Počet bufferů videa (každý o velikosti 8k), které xine použije ve své " "vnitřní frontě. Vyšší hodnoty znamenají hladší přehrávání u nespolehlivých " "vstupů, ale také zvýšené zpoždění a spotřebu paměti." #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" # This message should match with FAQ_cs. #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "%d snímků předaných, %d snímků přeskočených, %d snímků zahozených\n" # This message should match with FAQ_cs. #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: zahození obrazu s pts %, protože je příliš starý " "(rozdíl : %).\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "procentní tolerance přeskočených snímků" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" "Pokud se nezobrazí více než toto procento snímků, protože nebyly včas " "dekódovány, pošle xine hlášení." #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "procentní tolerance zahozených snímků" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" "Pokud se nezobrazí více než toto procento snímků, protože nebyly včas " "naplánovány k zobrazení, pošle xine hlášení." #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out: Litujeme, toto by se nemělo přihodit. Prosím restartujte xine.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "horizontální pozice obrazu ve výstupním okně videa" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" "Pokud je vodorovná velikost okna videa větší než aktuální obraz k zobrazení, " "můžete přizpůsobit pozici, kam se obraz umístí.\n" "Pozice se zde udává jako procento, takže hodnota 50 znamená \"uprostřed\", " "zatímco 0 znamená \"co nejvíce vlevo\" a 100 \"co nejvíce vpravo\"." #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "vertikální pozice obrazu ve výstupním okně videa" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" "Pokud je svislá velikost okna větší než aktuální obraz k zobrazení, můžete " "přizpůsobit pozici, kam se obraz umístí.\"Pozice se zde udává jako procento, " "takže hodnota 50 znamená \"uprostřed\", zatímco hodnota 0 znamená \"nahoře\" " "a 100 \"dole\"." #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "zakázat veškeré změny měřítka" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" "Pokud chcete, aby se zobrazoval obraz videa vždy v jeho původním rozlišení, " "můžete zakázat veškeré změny měřítka.\n" "Toto samozřejmě znamená, že se obraz nebude dále přizpůsobovat velikosti " "okna videa a videa s poměrem stran bodu jiným než je 1:1 (např. " "anamorfotické DVD) se budou zobrazovat deformovaně. Ale na druhou stranu, s " "některými videovýstupy jako je XShm, kde není škálování obrazu hardwarově " "urychlováno, může toto dramaticky snížit využití CPU." #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: chyba během zpracování MRL\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: nelze nalézt vstupní modul: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: vstupní modul nemůže otevřít MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: nelze nalézt vstupní modul pro MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: selhalo spuštění demultiplexoru %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: připojen ripovací vstupní modul\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: chyba otevírání instance ripovacího vstupního modulu\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: selhalo spuštění posledního vyzkoušeného demultiplexoru %s\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "ignoruje se video\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "ignoruje se zvuk\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "ignorují se titulky\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "vstupní modul cache zakázán\n" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "otevřeno MRL titulků '%s'\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: chyba otevírání MRL titulků\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: změna volby '%s' z MRL není povolena\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" "xine: nepodařilo se načíst demultiplexor %s požadovaný vstupním modulem pro >" "%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: nelze nalézt demultiplexor pro >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: nalezen demultiplexní modul: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "xine: demultiplexor již skončil. to bylo rychlé!\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: selhalo spuštění demultiplexoru\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: žádný dostupný demultiplexor\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: selhalo spuštění demultiplexoru\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" "xine: Uvedený adresář pro ukládání \"%s\" by mohl znamenat bezpečnostní " "riziko.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "Uvedený adresář pro ukládání by mohl znamenat bezpečnostní riziko." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: locale není podporováno knihovnou C\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "strategie zjišťování formátu dat" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" "xine poskytuje různé metody k detekci formátu multimédia, které se má " "přehrát. Jednotlivé hodnoty jsou:\n" "default\n" "Nejprve zkusit detekovat podle obsahu, pak podle přípony jména souboru.\n" "\n" "reverse\n" "Nejprve zkusit detekovat podle přípony jména souboru, pak podle obsahu.\n" "\n" "content\n" "Detekovat pouze podle obsahu.\n" "\n" "extension\n" "Detekovat pouze podle přípony jména souboru.\n" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "adresář pro ukládání dat" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" "Při použití funkce ukládání toku dat budou soubory zapisovány pouze do " "tohoto adresáře.\n" "Toto nastavení je kritické z hlediska bezpečnosti, protože při změně na jiný " "adresář může xine vyplňovat soubory v tomto adresáři libovolným obsahem. " "Proto byste si měli být jisti, že je v uvedeném adresáři bezproblémový " "jakýkoliv obsah v jakémkoliv souboru." #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "povolit implicitní změny v konfiguraci (např. pomocí MRL)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" "Pokud je povoleno, dovolíte xine měnit vaši konfiguraci bez výslovných akcí " "z vaší strany. Budou vykonány např. změny konfigurace žádané z MRL nebo " "vložené do playlistu.\n" "Toto nastavení je kritické z hlediska bezpečnosti, protože xine může " "přijímat MRL nebo playlist z nedůvěryhodných vzdálených zdrojů. Pokud jim " "dovolíte libovolně měnit vaši konfiguraci, můžete skončit s úplně rozhozeným " "xine." #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "Timeout čtení dat ze sítě (v sekundách)" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" "Specifikuje timeout při čtení dat ze sítě v sekundách. Příliš nízké hodnoty " "by mohly přerušovat přehrávání, pokud je zdroj pomalý nebo je zabrané pásmo, " "příliš vysoké hodnoty zablokují přehrávač, pokud se ztratí spojení." #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "zprávy" #: src/xine-engine/xine.c msgid "plugin" msgstr "modul" #: src/xine-engine/xine.c msgid "trace" msgstr "trasování" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Varování:" # standarní hláška hstrerror #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "Neznámý host:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Neznámé zařízení: " #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Síť není dosažitelná" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Spojení odmítnuto:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "Soubor nenalezen:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Chyba čtení z:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Chyba načítání knihovny:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Detekována šifrovaná multimediální data" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Bezpečnostní zpráva:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Zvukové zařízení není k dispozici" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Chyba povolení přístupu" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "Soubor je prázdný:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Obnovuje se index..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Výkonnostní testování metod memcpy (menší je lepší):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "metoda memcpy použitá xine" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" "Kopírování objemných paměťových bloků je jednou z nejnáročnějších operací na " "dnešních počítačích. Proto xine poskytuje různé vyladěné metody, které " "provádějí toto kopírování. Obvykle je nejlepší metoda zjišťována automaticky." #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "" #~ "configfile: VAROVÁNÍ: zálohování konfiguračního souboru do %s selhalo\n" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: špatné MRL: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: chyba čtení (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: nelze zjistit adresu '%s'.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: nelze se připojit k '%s'.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "stdin: nelze se posunout zpět! (% < %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: chyba během zpracování MRL\n" #~ msgid "raw device set up for DVD access" #~ msgstr "cesta k raw zařízení nastavenému pro přístup k DVD" #~ msgid "" #~ "If this points to a raw device connected to your DVD device, xine will " #~ "use the raw device for playback. This has the advantage of being slightly " #~ "faster and of bypassing the block device cache, which avoids throwing " #~ "away important cache content by keeping DVD data cached. Using the block " #~ "device cache for DVDs is useless, because almost all DVD data will be " #~ "used only once.\n" #~ "See the documentation on raw device setup (man raw) for further " #~ "information." #~ msgstr "" #~ "Pokud toto ukazuje na raw zařízení připojené k vašemu zařízení DVD, xine " #~ "použije raw zařízení k přehrávání.To má výhodu, že je to nepatrně " #~ "rychlejší a že se obchází cache blokového zařízení. Předchází to " #~ "zahazování důležitého obsahu cache tím, že by se zachovávala data DVD v " #~ "cache. Použití cache blokového zařízení je pro DVD zbytečné, protože " #~ "většina všech dat DVD bude použita pouze jednou.\n" #~ "Další informace viz dokumentace o raw zařízeních (man raw)." #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "Výše uvedená zpráva má neznámou logovací úroveň vcdimageru" #~ msgid "load_plugins: static plugin %s found\n" #~ msgstr "load_plugins: nalezen statický modul %s\n" #~ msgid "sequence header too big (%u bytes)!\n" #~ msgstr "hlavička posloupnosti příliš veliká (%u bytů)!\n" xine-lib-1.2/po/en_US.po0000644000175000017500000047076514647725152012676 0ustar meme# Translation of xine-lib.po into American English. # Copyright (C) 2008 the xine project # Copyright (C) 2002, 2006, 2007, 2008 Free Software Foundation, Inc. # msgid "" msgstr "" "Project-Id-Version: xine-lib.hg\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2009-01-15 19:04+0000\n" "Last-Translator: Not translated \n" "Language-Team: en_US \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/hstrerror.c msgid "No error" msgstr "" #: lib/hstrerror.c msgid "Unknown host" msgstr "" #: lib/hstrerror.c msgid "No address associated with name" msgstr "" #: lib/hstrerror.c msgid "Unknown server error" msgstr "" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "" #: lib/hstrerror.c msgid "Unknown error" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c msgid "Linear PCM audio decoder plugin" msgstr "" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "device used for a/52 and DTS pass-through" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "" #: src/audio_out/audio_fusionsound_out.c msgid "xine FusionSound audio output plugin" msgstr "" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr "" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" #: src/audio_out/audio_sndio_out.c msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat input plugin" msgstr "" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c msgid "libavio input plugin" msgstr "" #: src/combined/flac_decoder.c msgid "flac audio decoder plugin" msgstr "" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c msgid "Speex audio decoder plugin" msgstr "" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c msgid "AIFF file demux plugin" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c msgid "CD Digital Audio demux plugin" msgstr "" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c msgid "image demux plugin" msgstr "" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c msgid "MPEG program stream demux plugin" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c msgid "MPEG audio demux plugin" msgstr "" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c msgid "Id RoQ file demux plugin" msgstr "" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c msgid "SMJPEG file demux plugin" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c msgid "WAV file demux plugin" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" #: src/input/input_cdda.c msgid "query CDDB" msgstr "" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "" #: src/input/input_file.c msgid "file input plugin" msgstr "" #: src/input/input_file.c msgid "file browsing start location" msgstr "" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" #: src/input/input_ftp.c msgid "FTP input plugin" msgstr "" #: src/input/input_ftp.c msgid "FTPES input plugin" msgstr "" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "" #: src/input/input_helper.c msgid "list hidden files" msgstr "" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c msgid "HTTP live streaming input plugin" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: content length = % bytes\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "" #: src/input/input_http.c msgid "http/https input plugin" msgstr "" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" #: src/input/input_mms.c msgid "MMS protocol" msgstr "" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" #: src/input/input_mpegdash.c msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "" #: src/input/input_net.c msgid "tls input plugin" msgstr "" #: src/input/input_net.c msgid "gopher input plugin" msgstr "" #: src/input/input_nfs.c msgid "Network File System (NFS) input plugin" msgstr "" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "" #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "" #: src/input/input_ssh.c msgid "SCP input plugin" msgstr "" #: src/input/input_ssh.c msgid "SFTP input plugin" msgstr "" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c msgid "v4l2 input plugin" msgstr "" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "" #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "" #: src/input/input_v4l.c msgid "Adjusting..." msgstr "" #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l video device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "" #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "" #: src/input/multirate_pref.c msgid "Preferred video size" msgstr "" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred bitrate" msgstr "" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "" #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" #: src/libw32dll/qt_decoder.c msgid "quicktime audio decoder plugin" msgstr "" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr "" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" #: src/video_out/video_out_mmal.c msgid "xine video output plugin using MMAL" msgstr "" #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "xine video output plugin using VAAPI" msgstr "" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr "" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "" #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr "" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "" #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "" #: src/xine-engine/xine.c msgid "plugin" msgstr "" #: src/xine-engine/xine.c msgid "trace" msgstr "" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c msgid "Recording done:" msgstr "" #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" xine-lib-1.2/po/eu.po0000644000175000017500000061622114647725152012263 0ustar meme# translation of xine-lib-1.po to lubrezale # translation of xine-lib.po to Librezale.org # This file is distributed under the same license as the PACKAGE package. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. # Piarres Beobide , 2005. # msgid "" msgstr "" "Project-Id-Version: xine-lib-1\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2005-02-17 14:29+0100\n" "Last-Translator: Piarres Beobide \n" "Language-Team: lubrezale \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "X-Generator: KBabel 1.9.1\n" #: lib/hstrerror.c msgid "No error" msgstr "" #: lib/hstrerror.c msgid "Unknown host" msgstr "ostalari ezezaguna" #: lib/hstrerror.c msgid "No address associated with name" msgstr "ez dago helbiderik izen horri loturik" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Zerbitzari errore ezezaguna" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Ostalari izen ebazketak huts egin du" #: lib/hstrerror.c msgid "Unknown error" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "dvaudio: bufeera %d -ra handitzen askieza sahiesteko.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "LAGUNTZA! mono bakarrik audio kontrolatzailea?\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "A/52 bolumena" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "A/52 bitarte dinamiko konpresioa" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen()-ek huts egin du.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2-ek huts egin du.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit-ek huts egin du.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "xine fitxategi audio irteera plugina" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out:Dagoeneko irekirik...ZERGATIK!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "%s audio_alsa_out: snd_pcm_open()-ek huts egin du: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "" "audio_alsa_out: >>> Egiaztatu beste programa batek PCM darabilkien<<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: PCM onentzat apurturiko konfigurazioa: Ez dago konfigurazio " "erabilgarririk: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "hardware nahasleari aldaketen berri eman" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" "Hardware nahaslea aldatzerakoan, zure aplikazioak honen berri jasoko du eta " "nahaslearen irudi grafikoa denbora errealean eraldatuko du." #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : Onartutako moduak:" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4-kanal ez dago gaiturik xine konfigruaketan)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-kanal" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-kanal ez dago gaiturik xine konfigruaketan)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5-kanal" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5-kanal ez dago gaiturik xine konfigruaketan)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-kanal ez dago gaiturik xine konfigruaketan)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (a/52 eta DTS pass-through ez daude gaiturik xine konfiguraketan)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open()-ek huts egin du:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Egiaztatu beste programa batek PCM darabilkien<<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "soinu txartelak mmap egin dezake" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" "Zure soinu txartelak eta alsa kontrolatzaileak mapaturiko IO obartzen badute " "gaitu\n" "Gaitu eta frogaru dezakezu beldurrik gabe, denak behar bezala funtzionatu " "ezkero portamoldea obetuko du." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "mono irteerarako erabiliko den gailua" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "Xinek alsa gailua erabiliko du mono soinuarentzat.\n" "Irakurri alsa dokumentazioa alsa gailuei buruzko informazio gehiago behar " "izan ezkero." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " estereo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "Estereo irteerak erabiltzen duen gailua" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "Xinek alsa gailua erabiliko du estereo soinuarentzat.\n" "Irakurri alsa dokumentazioa alsa gailuei buruzko informazio gehiago behar " "izan ezkero." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-kanal" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "4 kanaletako irteerak erabiltzen duen gailua" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "Xinek alsa gailua erabiliko du 4 kanaleko (4.0) soinuarentzat.\n" "Irakurri alsa dokumentazioa alsa gailei buruzko informazio gehiago behar " "izan ezkero." #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-kanal" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "5.1 kanaletako irteerak erabiltzen duen gailua" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" "Xinek alsa gailua erabiliko du 5 kanaleko (5.1) soinuarentzat.\n" "Irakurri alsa dokumentazioa alsa gailei buruzko informazio gehiago behar " "izan ezkero." #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " a/52 eta DTS pass-through" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " a/52 eta DTS pass-through" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xinel alda gailu hau erabiliko du kodifikatu gabeko ingurugiro soinuentzako. " "hau kanpo ingurugiro dekodifikatzaileez erabil daiteke.\n" "Begiratu alsa dokumentazioa argibide gehiagorako." #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() hutsa: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "alsa nahasle gailua" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xinek alsa nahaslea erabiliko du bolumena aldatzeko.\n" "Begiratu alsa dokumentazioa alsa gailueri buruzko argibideentzat." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" "xine audio irteera plugina alsa-konpilaturiko audio gailu/kontrolatzailea " "erabiliaz" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "xine irteera plugina Coreaudio/Mac OS X-entzat" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Errorerik ez" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "" #: src/audio_out/audio_directx2_out.c #, fuzzy msgid "requested buffer control is not available" msgstr "eskatutako botoia ez da erabilgarri\n" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "xine audio irteera plugina win32-arentzat directx erabiliaz (2)" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "xine audio irteera plugina win32-arentzat directx erabiliaz" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: %s ESD zerbitzarira konektatzen: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: esd zerbitzarira konektatzen...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: ezin da %s ESD zerbitzarira konektatu: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "esd audio irteera atzerapena (a/b sinkronia ezarri)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" "Audio eta bideoa ez badago sinkronizaturik, hemen konpentsatzeko mugimendua " "konpondu dezakezu.\n" "Unitatearean balioa PTS marka, segundu baten 90000-garren zatia da." #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "xine audio irteera plugina esound erabiliz" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "xine fitxategi audio irteera plugina" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "xine fitxategi audio irteera plugina" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "irixal audio irteera gehinezko hutsune luzera" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" "Sinkronizatzen saiatu aurretik Bideo eta audioaren arteko ezberdintasun muga " "ezarri dezakezu.\n" "Unitatea PTS marka bat da, zein segundu baten 90000-garren zatia den." #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "xine audio irteera plugina IRIX libaudio erabiliaz" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "JACK audio gailu izena" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "xine gezurrezko audio irteera plugina" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: %s audio gailua irekitzen: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: abisua: %d Hz laginketa abiadura ez da onartzen, 44100 Hz-" "rekin saiatzen\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "audio_oss_out: audio abiadura : %d eskaturik, %d gailuak hornitua\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "OSS audio gailu izena" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "OSS audio gailu zenbakia, -1 batez" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Audio gailuaren izen osoa OOS gailu izena eta audio gailuaren zenbakiaz " "osatzen da.\n" "Zure sistemako lehenetsitako audioarekin gustoara bazaude ezarri '-1'.\n" "balio honen muga -1 eta 0-15 artean dago. Ezarpena hau alde batetar utziko " "da OSS audio gailu izena\"auto\" bezala ezarririk badago." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "" "audio_oss_out: audio.device.oss_device_name = auto, gailuak frogatzen\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Audio gailu auto-frogak huts egin du\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: Erabilitako gailua >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: huts %s audio gailua irekitzerakoan:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "OSS-k erabilitako a/b sinkronimo metodoa" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" "xinek metodo ezberdinak erabili ditzake audioa eta bideoa sinkronizaturik " "mantentzeko. Zein ezarpen den erabili behar duzuna zure hardware eta OSS " "kontrolatzailearen araberakoa da. Saiatu metodo guztiak arazorik izan " "ezkero.\n" "\n" "baloreen esanhaiak hauek dira\n" "\n" "auto\n" "xine automatiko ezarpen hobernak atzematen saiatuko da\n" "\n" "getodelay\n" "SNDCTL_DSP_GETODELAY ioctl erbiltzen du benetazko a/b sinkronia gordetzeko " "nahiz kontrolatzaileak ez badu denbora errealeko erreprodukzioa onartzen\n" "\n" "getoptr\n" "SNDCTL_DSP_GETODELAY ioctl erbiltzen du benetazko a/b sinkronia gordetzeko " "nahiz kontrolatzaileak SNDCTL_DSP_GETODELAY ioctl nahiago izan\n" "\n" "softsync\n" "Sistema erlojuarekiko software sinkronizazia erabiltzen du; audio eta bideo " "sinkronismoak sistema erlojuak ez bada zehazki zure soinu txartelaren " "abiadura berdina\n" "probebuffer\n" "frogatu soinu txartelaren buffer tamaina abiaraztean a/b atzerapena " "kalkulatzeko; saiatu honekin zure sistemak ez badu denbora errealeko " "kontrolatzailerik onartzen eta erreprodukzio luzeetan sinkronismo arazoak " "badituzu" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Audio kontrolatzailearen denbora errealeko sinkronia " "ezgaitu...\n" "audio_oss_out: ...erabili sistema denbora erreal erlojua soft " "sinkronismoaren ordez\n" "audio_oss_out: ...audio/bideo sinkronismo arazoak egon daitezke\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "OSS audio irteera atzerapena(a/b synk ezarri)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Audio kontrolatzailearen denbora errealeko sinkronia " "ezgaitu...\n" "audio_oss_out: ...irteera bufffer tamaina frogatzen: %d bite\n" "audio_oss_out: ...audio/bideo sinkronismo arazoak egon daitezke\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: Onartutako moduak:" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " a/52 pass-through" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (a/52 pass-through ez daude gaiturik xine konfiguraketan)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "OSS audio nahasle zenbakia, -1 ez erabiltzeko" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Nahasle izen osoa OOS gailu izena artu, \"dsp\"-ren ordez \"mixer\" ipini " "eta nahasle zenbakia gehiturik lortzen da.\n" "Sistemako nahasle gailuarekin gustora bazaude ez duzu nahasle zenbakirik " "behar; ezarri eremu hau -1 bezala.\n" "Balio honen eremua -1 eta 1-15 artekoa da. OSS gailu izena \"auto\" bezala " "ezarririk dagoenean ezarpen hau alde batetara utziko da." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: huts %s nahaslea abiaraztean: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" "xine audio irteera plugina oss-kompilaturiko audio gailu/kontrolatzailea" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " a/52 pass-through" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" "xine audio irteera plugina sun-kompilaturiko audio gailu/kontrolatzailea" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: huts %s audio gailua irekitzerakoan: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "Sun audio gailu izena" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" "Erabiliko den SUn audio gailuaren fitxategi izena.\n" "Ezarpenez segurtasun aldetik kritikoa da, fitxategi ezberdin batetara " "aldatzean, xine erbili daiteke fitxategi hau eduki arbitrarioez bete dezake. " "Beraz kontu izan behar duzu Sun audio gailu egoki bat ezartzea." #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" "xine audio irteera plugina sun-kompilaturiko audio gailu/kontrolatzailea" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "bozgorailu ordenamendua" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" "Aukeratu zenbat bozgorailu dauden instalaturik, honek xine-k erabiliko duen " "bozgorailu kopurua ezarriko di. Balioak hauek dira:\n" "\n" "Mono 1.0: Bozgorailu bat bakarrik duzunean.\n" "Stereo 2.0: Bi bozgorailu dituzu ezker eta eskuin kanalentzat.\n" "Headphones 2.0: Aurikularrak erabiltzen dituzu.\n" "Stereo 2.1: Ezker eta eskuin kanalentzat bi bozgorailu eta frekuentzi " "baxuetarako subwoofer bat duzu.\n" "Surround 3.0: Ezker, eskuin eta atzeko kanalentzat hiru bozgorailu.\n" "Surround 4.0: Ezker, eskuin, atze-ezker eta atze-eskuin kanalentzat lau " "bozgorailu.\n" "Surround 4.1: Ezker, eskuin, atze-ezker eta atze-eskuin kanalentzat lau " "bozgorailu eta frekuentzi baxuetarako subwoofer bat.\n" "Surround 5.0: Ezker, eskuin, atze-ezker, atze-eskuin eta aurreko kanalentzat " "bost bozgorailu.\n" "Surround 5.1: Ezker, eskuin, atze-ezker, atze-eskuin eta aurreko kanalentzat " "bost bozgorailu eta frekuentzi baxuetarako subwoofer bat.\n" "Surround 6.0: Aurreko eta atzeko ezkerreko, erdiko eta eskuineko kanalentzat " "sei bozgorailu .\n" "Surround 6.1: Aurreko eta atzeko ezkerreko, erdiko eta eskuineko kanalentzat " "sei bozgorailu eta frekuentzi baxuetarako subwoofer bat.\n" "Surround 7.1: Aurreko ezkerreko, erdiko eta eskuineko, ezker eta eskuin eta " "atzeko ezker eta eskuineko kanalentzat zazpi bozgorailu eta frekuentzi " "baxuetarako subwoofer bat.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "fitxategi sarrera plugina" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_audio_dec: bufferra%d-ra handitzen askieza sahiesteko.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: ezin da deskodetzailea ireki\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "ffmpeg_video_dec: marko formatu onartezina, DR1 ezgaiturik.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: marko formatu onartezina, DR1 ezgaiturik.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: direct reenderizazioa gaiturik\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "ffmpeg_video_dec: marko formatu onartezina, DR1 ezgaiturik.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: ezin da deskodetzailea ireki\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: ezin da deskodetzailea ireki (2)\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_video_dec: bufferra %d -ra handitzen askieza saiesteko.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: marko formatu onartezina, DR1 ezgaiturik.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "MPEG-4 postprozesatze kalitatea" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "v4l irrati sarrera plugina" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "xine fitxategi audio irteera plugina" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: vorbis audio pista esan da baina ez da vorbis korronte bururik " "aurkitu.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "xine fitxategi audio irteera plugina" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: bufeera %d -ra handitzen askieza sahiesteko.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "fitxategi sarrera plugina" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: abisua: id=%d korrontea enkriptaturik dago.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Medioa korrontea nahasi/enkriptaturik" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Indizea bersortzen..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "demux_avi: \"%c%c%c%c\" baliogabeko avi zatia % kokalekuan\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: avi indizea hautsirik dago\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "demux_avi: huts hurrengo zatira pasatzekoan (% kokalekua)\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "DVB (Telebista Digitala) sarrera plugina" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "baliogabeko FILMA zati tamaina\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "FILMA zati ezezaguna\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: konpresio ezezaguna: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: konpresio ezezaguna: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: Zati ezezaguna: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "fitxategi sarrera plugina" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: 0x%02x korronte_id-a. Mesedez berri eman xine " "garatzaileei.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: errorea! askatzen. Mesedez abisua eman xine garatzaileei.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: abisua: PES buarentzat gorderiko 10 bit ez dira aurkitu\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: kontuz: PES goiburuak korrontea enkriptaturik dagoela " "ezartzen du (enkriptazioa %d modua)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "pnm korronte sarrera plugina" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: 0x%02x korronte_id ezezaguna. MEsedez honen berri " "eman xine garatzaileei.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: kontuz: PACK korronte -aid=0x%x dekodifikatzerakoan huts.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: abisua: PES buruarentzat gorderiko 10 bit ez dira aurkitu\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: abisua: PES buruak korronte hau enkriptaturik dagoela " "adierazten du (enkriptazio mota: %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes:1 0x%02x korronte pribatu ezezaguna. Mesedez berri eman xine " "garatzaileei.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "v4l irrati sarrera plugina" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "fitxategi sarrera plugina" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "fitxategi sarrera plugina" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: okerreko goiburu parametroa\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: onartzen ez den audio mota: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "VOC bloke mota (0x%02X) ezezaguna; mesedez erreportea eman xine " "garatzaileei\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "VOC konpresio mota (0x%02X) ezezaguna; mesedez erreportea eman xine " "garatzaileei\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "fitxategi sarrera plugina" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "demux_wc3movie: Arazo bat dago paleta zatiak kargatzerakoan\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Huts %s (%s) spu gailua irekitzerakoan\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_video: huts (%s) bideo gailua idazterakoan\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "eskatutako botoia ez da erabilgarri\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "dxr3_decode_video: Huts %s (%s) kontrol gailua irekitzerakoan\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "\"Pan eta Scan\" informazioa erabili" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" "\"Pan eta Scan\" zenbait MPEG kodifikaturiko materialen erabiltzen den " "bistaratze modu bereizi bat da, hauek nola kudeatu ezarri dezakezu hemen.\n" "\n" "bakarrik indartzerakoan\n" "\"Pan eta Scan\" erreproduzitzen ari zarenak behartzean bakarrik erabili.\n" "\n" "Erabili MPEG gomendioa\n" "Gaitu \"Pan eta Scan\" MPEG korronte argibideetan oinarriturik.\n" "\n" "Erabili DVB gomendioa\n" "Gaitu \"Pan eta Scan\" SVB korronte argibideetan oinarriturik.Honek Europear " "DVB kateek erabiltzen duten \"Active Format Descriptor\" erabiltzen du." #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "saiatu bideoa marko bakoitzean sinkronizatzen" #: src/dxr3/dxr3_decode_video.c #, fuzzy msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" "Sinkronizazio denbora-marka bat marko bakoitzean ezartzen saiatu. Arruntean " "hau ez da beharrezkoa sinkronia nahikoa da \"now\" eta \"then\" bakoitzean " "denbora-marka ipiniaz.\n" "Hau bideo prograsiboetan (PAT filma gehienak) bakarrik behar da." #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "Erreprodukzio modu leuna erabili" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Aukera hau gaituaz erreprodukzio modu leunago bat erabiliko da." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "konpondu marko iraupena apurturiko korronteetan" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Huts %s (%s) bideo gailua irekitzerakoan\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "dxr3_decode_video: gailuan idaztea blokeatuta egon liteke. garbitzen\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: huts (%s) bideo gailua idazterakoan\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "dxr3_decode_video: KONTUZ: %d marko abiadura kode ezezaguna\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: ABISUA: marko abiaradura PAT-etik NTSC-ra biurtzen\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "DXR3 gailu zenbakia" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" "Zure ordenagailuan DXR3 gailu bat baino gehiago izan ezkero zein erabili " "nahi duzun ezarri dezakezu." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: huts librte abiaraztean\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte-ek 16-en multiploak diren bideo dimentsioak kudea " "ditzake\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: huts rte contestua eskuratzerakoan.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: Ezin da kodeka sortu.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "rte mpeg irteera bit tasa (kbit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "DXR3 kodeketa motarako mpeg kodeketa liburutegiak erabili behar dun bit " "abiadura. Balio handiek CPU erabilera handiagoa egiten dute." #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: ezin da kontestua abiarazi: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: ezin kodifikazioa abiarazi: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: Ezin da FAME liburutegia abiarazi\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "mpeg kodifikazio kalitate famatua" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" "libfame kodifikazio liburutegiaren kodifikazio kalitatea. Txikiagoa " "azkarragoa da baina arazoak izan ditzake. Handiago obea da baina astiroagoa." #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "SCR plugin lehentasuna" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" "DXR3 SCR plugin lehentasuna. 5 baino balio txikiagoek unyx sistema denbora " "erabiliko dute. 5 baino balio handiagoek DXR3-arne barne erlojua erabiliko " "dute sinkronia jatorri bezala." #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "libavcodec mpeg irteera bit tasa (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "kalitate modu iraunkorra" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "konpresio txikiena" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" "Kalitate iraunkorreko kalitate moduko ezarriko den gutxienezko konpresioa." #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" "Kalitate iraunkorreko kalitate moduko ezarriko den gehinezko konpresioa." #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Huts %s (%s) kontrol gailua irekitzerakoan\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "aldatu lerro bakoiti eta bikoitiarrak" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" "Irudiaren lerro bakoiti eta bikoitiarrak aldatu.\n" "Aukera hau ez-MPEG diren eta materialak pantailan \"jitter\" bertikal bat " "sortzean." #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "Barra beltzak gehitu itxura proportzioa konpontzeko" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" "Gehitu barra beltzak irudiari itxura biadura ezin denean behar bezala " "kudeatu, Hau beharrezkoa da irudien proportzio zuzenak mantentzeko." #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "erabili erreprodukzio modu leuna mpeg kodeketa erreproduzitzerakoan" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Aukera hau gaituaz erreprodukzio modu leuna erabiliko da ez-MPEG edukia " "erreprduzitzeko" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Huts %s (%s) bideo gailua irekitzerakoan\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "kodetzailea mpeg ez den edukientzat" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" "MPEG ez diren edukiek beste berrenkodeketa egoera bat pasa behar dute, dxr3-" "k MPEG bakarrik kudeatzen duelako.\n" "Xine-k onartzen duen arabera ezarpen hau \"fame\", \"rte\", \"libavcodec\" " "edo \"none\"izan daitezke.\n" "\"libavcodec\" kodeatzaileak xine-k dakarren ffmpeg plugina erabiltzen du, " "beraz ez duzu liburutegi gehigarririk instalatu beharrik honetarako. " "Libdavcodec-ek kalitate handia CPu erabilera txikiaz eskeintzen du. Beraz " "\"libdavcodec\" erabiltzea gomendatzen da.\n" "\"fame\" eta \"rte\" aukerak daude baina xineren hauetariko onespena " "zaharkiturik dago beraz exkeutatzean huts egin dezalekete." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "video_out_dxr3: Mpeg kodetzaile libavcodec huts abiaraztean.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: Mpeg kodetzaile rte huts abiaraztean.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: Mpeg kodetzaile fame huts abiaraztean.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Mpeg kodetzea ezgaiturik.\n" "video_out_dxr3: hau ondo dago, ez duzu DVD antzerako mpeg bideoetan,\n" "video_out_dxr3: baina ez zara ez-mpeg edukaik erreproduzitzeko gai izango " "bideo-irteera\n" "video_out_dxr3: kontrolatzaile honekin.begiratu README.dxr3 kodeatzaile " "konfigurazioa.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Ez dago mpeg kodedeatzailerik konpilaturik.\n" "video_out_dxr3: hau ondo dago; ez duzu behar DVD antzerako bideoak " "ikusteko,\n" "video_out_dxr3: baina ez zara ez-mpeg edukiak bideo irteera driberra " "erabiliaz\n" "video_out_dxr3: ikusteko gai izango. README.dxr3 begiratu xehetasunentzat.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "bideo irteera modua (Telebista edo Gainjarri)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" "Hemen DXR3 irteerak bideo irteerak erabilitako modua ezarri daiteke. " "Balioak:\n" "\n" "letterboxed tv\n" "Bideoa telebista irteerara bakarrik bideali. Modu hau 4:3 estandar telebista " "eza" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "Gainjarri koloretekla balioa" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "Gainjarri koloretekla tolerantzia" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "Txikitu gainjarpena area goi eta behetik" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Gainjarpenaren goi eta beheko aldetik pixel lerro bat ezabatzen du. Hau " "gaitu gainjarpen goi eta beheko aldean lerro orlegiak ikusi ezkero." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: mesedez autocal abiarazi, gainjarpena ezgaiturik\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "gogoko telebista modua" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Aukeratu DXR3 telebista modua. Balioen esanahia:\n" "\n" "ntsc: NTSC - 60Hz\n" "pal: PAL - 50Hz\n" "pal60: PAL - 60Hz\n" "default: mantendu txartel ezarpenak" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: bideo modu ezarpenak huts egin du.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: Mpeg kodeatzailea behar da dxr3-an ez-mpeg bideoak " "bistaratzeko\n" "video_out_dxr3: README.dxr3 begiratu xehetasunentzat.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: ERROREA gainjarri abiarazte fitxategia irakurtzeab. Run " "abiarazi!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "BluRay-a erreproduzitzeko erabiliko den gailua" #: src/input/input_bluray.c #, fuzzy msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" "BluRay-ak erreproduzitzeko erabli nahi duzun, arruntean BluRay gailu bat, " "gaiuaren bidea." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "BluRay erreprodukzioaren lehenetsirako hizkuntza" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" "xine hizkuntza hau lehenetsi bezala erabiltzen saiatuko da BluRay-ak " "erreproduzitzean. BluRay-ak onartzen duen arabera menua eta audio pistak " "hizkuntza honetan emango dira.\n" "Balioak 3 karaktereko ISO639-2 kode bat izan behar da." #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" "BluRay erreproduktoreak okerreko erregioan dagoela leiho bat erakusten badu " "bakarrik behar da hau. Honek ez du zerikusirik BluRay gailuetan ezarritako " "erregio kodearekin, hau software hutsa da." #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "Ekintza egingo ez den unitatea" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: Ezin da %s-ra konektatu: %d\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: arrakastatsuki konektaturik cddb zerbitzarira'%s:%d'.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "input_cdda: huts cddb zerbitzarira konektatzerakoan '%s:%d' (%s).\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "CD Audio Digitala (hemen. CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "CD audio-k erabiliko duen gailua" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" "Gailuaren bidea, arruntean audio CD erreproduzitzeko erabili nahi duzun CD " "edo DVD gailua." #: src/input/input_cdda.c msgid "query CDDB" msgstr "CDDB galderak" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" "CDDB galdeketa gaitu, audio CD-entzat behr den titulu eta pista izenak " "eskuratzeko.\n" "Izan kontutan zuk ez baduzu CDDB zerbitzari pribatu bat, informazio hau zure " "ohiturak grabatuko dituen internet ostalari batetatik jasoko da." #: src/input/input_cdda.c msgid "CDDB server name" msgstr "CDDB zerbitzari izena" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" "IZenburu eta pista informazioa jasotzeko erabiliko den CDDB zerbitzaria.\n" "Ezarpen hau segurtasun aldetik kritikoa da, zerbitzariak zure musika " "entzuteko ohituraz informazioa jaso eta erantzun zitalekin erantzun bait " "dezake. Ziurtatu konfidantza duzun zerbitzari bat izatea." #: src/input/input_cdda.c msgid "CDDB server port" msgstr "CDDB zerbitzari ataka" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" "Izenburu eta pista informazioa jasotzeko erabiliko den zerbitzari ataka." #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "gutxitu diska gailua abiadura faktore honetara" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" "Zenbait CD edo DVD gailuk diskaren abiadura handiagatik soinu handia egiten " "dutenez, xine berauek polikiagotzen saiatu daiteke. CD edo DVD " "estandarrekin, ez de behar irakurle abiadura handirik, beraz irakurlea " "geldoarazteak ez du ezertan txikiagotzen erreprodukzio kalitatea.\n" "Zero balioa poliagotzea ezgaitzen da." #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: irrati_ezarpen_kanalak huts egin du\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: ezin da dvb gailua ireki\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "input_dvb: %d kanala eremutik kanpo, 0-ra lehenesten\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: %s kanala bilatzen\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" "input_dvb: ez da %s-ren parekatze zehatzik aurkitu: parekatze hurbilduak " "saiatzen\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: %s kanal parekatzea aurkiturik\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "input_dvb: baliogabeko kanal ezarpena, 0 kanalera lehenesten\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" "input_dvb: dvbs mrl ezarririk baina sintonizatzailea ez dirudu QPSK (DVB-S) " "dagoenik\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: dvbt mrl ezarririk baina sintonizatzailea ez dirudu OFDM (DVB-T) " "dagoenik\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: dvbc mrl ezarririk baina sintonizatzailea ez dirudu QAM (DVB-C) " "dagoenik\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: ezin da '%s' dvr gailua ireki\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Honek pantaila osoko erreprdukzioa 4:3 formatu edukiak 16:9 markotan " "transmititzea gaitzen du." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "DVB (Telebista Digitala) sarrera plugina" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Errorea DVD-tik hurrengo blokea eskuratzerakoan (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Errorea DVD gailua irekitzerakoan\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "DVD-a erreproduzitzeko erabiliko den gailua" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" "DVD-ak erreproduzitzeko erabli nahi duzun, arruntean DVD gailu bat, gaiuaren " "bidea." #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "CSS desenkriptazio metodoa" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "DVD erreproduktorean eskatzen duen erregioa (1 - 8)" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" "DVD erreproduktoreak okerreko erregioan dagoela leiho bat erakusten badu " "bakarrik behar da hau. Honek ez du zerikusirik DVD gailuetan ezarritako " "erregio kodearekin, hau software hutsa da." #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "DVD erreprodukzioaren lehenetsirako hizkuntza" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" "xine hizkuntza hau lehenetsi bezala erabiltzen saiatuko da DVD-ak " "erreproduzitzean. DVD-ak onartzen duen arabera menua eta audio pistak " "hizkuntza honetan emango dira.\n" "Balioak bi karaktereko ISO639 kode bat izan behar da." #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "irakuketa-goiburu gordetzea" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "Bilatuko den untitatea" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Baimena ukaturik: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Fitxategia ez da aurkitu: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "" #: src/input/input_file.c msgid "file input plugin" msgstr "fitxategi sarrera plugina" #: src/input/input_file.c msgid "file browsing start location" msgstr "fitxategi kudeatzailearen abiarazte kokalekua" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" "Erreproduzitzeko fitxategi kudeatzailea kokaleu horretan abiaraziko da." #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "fitxategi sarrera plugina" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "fitxategi sarrera plugina" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "gnome-vfs sarrera plugina, xinerekin banatzen dena" #: src/input/input_helper.c msgid "list hidden files" msgstr "bistaratu ezkutatuako fitxategiak" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" "gaiturik dagoenean, fitxategi kudeatzaileak ezkutatutako fitxategia " "bistaraziko ditu." #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "stdin korronte sarrera plugina" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s)-ek huts egin du: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: irekurketa errorea %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "HTTP zerbitzarira konektatzen..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: http erantzun baliogabea\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: 3xx birbideratzea: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: http egoera ez da 2xx: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: eduki luzera = % bite\n" #: src/input/input_http.c #, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "" #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "http sarrera plugina" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "HTTP proxy ostalaria" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "HTTP proxy-aren ostalari izena." #: src/input/input_http.c msgid "HTTP proxy port" msgstr "HTTP proxy ataka" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "HTTP proxy-aren ataka zenbakia." #: src/input/input_http.c msgid "HTTP proxy username" msgstr "HTTP proxy erabiltzailea" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "HTTP proxy-aren erabiltzaile izena" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "HTTP proxy pasahitza" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "HRRP proxy-aren pasahitza." #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Domeinuak, non ez den HTTP proxy-a erabiliko" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "mms korronte sarrera plugina" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "sare zabalera" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" "Ezarri zure internet konexioaren zabalera hemen. Hau korronte zerbitzariek " "korronte berdinaren konexio zabalera behar duten korronte bertsio ezberdinak " "eskeintzean erabiliko da." #: src/input/input_mms.c msgid "MMS protocol" msgstr "MMS protokoloa" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "aukeratu MMS enkapsulatzeko metodoa.\n" "TCP obea da baina suebaki baten atzean HTTP beharko duzu." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "stdin korronte sarrera plugina" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "sare sarrera plugina, xinerekin anatzen dena" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "fitxategi sarrera plugina" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "fitxategi sarrera plugina" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "stdin korronte sarrera plugina" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "pnm korronte sarrera plugina" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: errorea¡pvr fitxategia (%s) sortzerakoan\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: errorea¡pvr fitxategia (%s) irekitzerakoan\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: irakurketa errorea (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: errorea %s gailua irekitzerakoan\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_G_CODEC-ak huts egin du, agian API-a aldatu da?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_S_CODEC-ak huts egin du, agian API-a aldatu da?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "WinTV-PVR 250/350 sarrera plugina" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "WinTV-PVR 250/350 (pvr plugin)-ek erabiliko duen gailua" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "WinTV txartelaren gailuaren bidea." #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "ezarritako IP helbidea multidifusioa (multicast) da\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Ezin da %s interfazearen helbidea aurkitu:%s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "ezin da '%s' ebatzi.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "Ezin da '%s' lotu.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: geratu irakurketa haria...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: hari irakurketa amaiturik\n" #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Opening >fitxategia:%s ataka:%d interfazea:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: Ezin da hari berria sortu (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "RTP eta UDP sarrera plugina, xinerekin banatzen dena" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "rtsp korronte sarrera plugina" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "fitxategi sarrera plugina" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "fitxategi sarrera plugina" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: ezin da '%s' ireki\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "stdin korronte sarrera plugina" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "v4l tv sarrera plugina" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Buffer gainditzea..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Buffer askieza..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Egokitzen..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "sintonizatzaile izena ez da aurkitu\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "v4l tv sarrera plugina" #: src/input/input_v4l.c msgid "v4l video device" msgstr "v4l bideo gailua" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Video4Linux bideo gailuaren bidea." #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "Video4Linux bideo gailuaren bidea." #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "v4l irrati sarrera plugina" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "v4l irrati gailua" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Video4Linux irrati gailuaren bidea." #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: gaikieraturiko MRL-a. vcdo:/ erbili\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: %d pista baliogabea (baliozko eremua: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "Ezin da %s ireki: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: Ezin da %s ireki: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "Bideoa CD sarrera plugina" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "VCD erreproduzitzeko erabiliko den gailua" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "BideoCD-ak erreproduzitzeko erabili nahi duzun gailuaren bidea." #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: okerreko mrl-a: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: huts '%s'-ra konektatzerakoan\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: huts %s zerbitzarira konektatzerakoan\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: ezin da saioa sortu.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" "rtsp_session: '%s' rtsp server mota ez da oraindik onartzen. barkatu.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "" "input_dvd: %s gailuak huts egin du ateratzen ari den bitartean " "irekitzerakoan\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "MMS zerbitzarira konektatzen (tcp bidez),,," #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: bidalketa errorea\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: okerreko erantzun formatua\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: 3xx berbideraketa ez da onartzen: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: http egoera ez da 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: Kokaleku nbirbideratzea ez da onartzen\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "MMS zerbitzarira konektatzen (http bidez)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "url baliogabea\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "onartzen ez den protokoloa\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "gogoko telebista modua" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "gogoko telebista modua" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: zerbitzariritik mezua bat jaso da korrontea irakurtzerakoan:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: ezin da '%s' konektatu\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: huts korrotea ezartzerakoan\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END ez dago oraindik inplementaturik." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "saltoa ez dago oraindik inplementaturik honentzat: " #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "elementu mota okerra" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "sarrera zenbaki okerra" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "okerreko segmentu zenbakia" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Erroreauneko segmentu zenbakia eskuratzerakoan" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "huts VCD bat duen gailu bat bilatzerakoan" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "baliogabeko klase parametroa pasa zen" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "baliogabeko sarrera mota" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "Aukerak ez du RETURN sarrerarik" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "LEHENETSIRIKOA aukeraturik baina PBC ez dago gaiturik." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "Aukerak ez du HURRENGO sarrerarik" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "Aukerak ez du AURREKO sarrerarik" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "gertaera mota ezezaguna: " #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" "Bideo CD plugina PBC.rekin eta onarpen hauekin: (X)VCD, (X)SVCD, HQVCD, " "CVD ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "VCD auto-erreproduzitzea erabiltzeko lehenetsiriko mota" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "MRL-an ez ezarri ezkero erabiliko den erreprodukzio unitatea, adib. vcd:// " "edo vcd:///dev/dvd:" #: src/input/vcd/xineplug_inp_vcd.c #, fuzzy msgid "CD-ROM drive used for VCD when none given" msgstr "Lehenetsiriko CD gailya VCD-entzat ematen ez denean" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Zein erabili gailurik ez ezartzean. Ezarpen hau hutsik utzi ezkero xinek " "gailu guztietan bilatuko du." #: src/input/vcd/xineplug_inp_vcd.c #, fuzzy msgid "VCD position slider range" msgstr "posizio graduatzaile bitartea" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c #, fuzzy msgid "VCD read-ahead caching?" msgstr "irakuketa-goiburu gordetzea" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "automatikoki aurrera pista/sarrera" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Gaiturik dagoenean, hurrengo sarrera edo pista automatikoki erreproduzituko " "du. Erreprodukzio kontrola (PBC) ezgaiturik dagoenean bakarrik erabiliko da." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "bistaratu ukaturiko LID-ak" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "Bistaratze banerraren kate formatua" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "Korronte iruzkin eremuaren kate formatua" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "GUI Izenburuan erabilitako formatua. Unix date komandoaren antzerakoa. " "Formatu espezifikazioakehuneko ikur bates hasten dira. Ezpezifikazioak: %A, %" "C, %c, %F, %I, %L, %N, %P, %p, %S, %T, %V, %v, eta %%." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "arazpen bandera maskara" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "RealPlayer kodeken bidea" #: src/libreal/real_common.c #, fuzzy msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" "Zuk Windows edo Apple Quicktime kodek paketeak instalaturik izan ezkero " "ezarri kokalekua hemen. Xine-k Windows edo Apple Quicktime kodekak aurkitu " "ezkero horiek erabiliko dira Windows Media eta Quicktime korronteak " "dekodifikatzeko. Begiratu XINE FAQ dokumentua kodek horiek nola instalaturi " "buruzko argibide gehiagorako." #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (audio) Ezin dira sinboloak ebatzi - dll bateraezina: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "libareal: huts deskodetzailea abiaraztekoan, errore kodea: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "" "libareal: deskodetzaile zapore konfigurazio hutsa, errore kodea: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" "libreal: Errorea sinboloak ebazterakoan! (bertsio bateragarritasun eza?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "Win32 kodek-en kokalekua" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" "Zuk Windows edo Apple Quicktime kodek paketeak instalaturik izan ezkero " "ezarri kokalekua hemen. Xine-k Windows edo Apple Quicktime kodekak aurkitu " "ezkero horiek erabiliko dira Windows Media eta Quicktime korronteak " "dekodifikatzeko. Begiratu XINE FAQ dokumentua kodek horiek nola instalaturi " "buruzko argibide gehiagorako." #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "xine fitxategi audio irteera plugina" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ICOpen huts egin du! %08lx kodek ezezaguna/ okerreko parametroa?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) huts egin du: Errorea %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery hutsa: %ld errorea\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin hutsa:Erro errorear %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder-ak huts egin du! %08lx kodek ezezaguna / okerreko " "parametroak?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder-ak huts egin du! %08lx kodek ezezaguna / okerreko " "parametroak?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "" "w32codec: huts deskodetzailea abiaraztean. '%s' instalaturik al dago?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Okerreko audio formatua\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen errorea %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Errorea DirectShow Audio abiarazterakoan\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Errorea DMO Audioa abiarazterakoan\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" "Upmix funtzioak. adib Estereo sarrera artu eta 5.1 irteera sortu.\n" "Parametroak\n" "cut_off_freq\n" "\n" "Oharra: posible da interfazearen kontrol leihoa erabiltzea parametro hauek " "ezartzeko.\n" "\n" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr "" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: Ez dago elkargurutzatur modurik eskuragarri, irteten.\n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "sortuko diren segunduko marko kopurua" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Segunduko marko gehiagorekin, animazioa leun eta azkarragoa izango da, baina " "CPU azkarragoa behar du." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "sortuko den irudian zabalera pixeletan." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "sortuko den irudian altuera pixeletan." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico-k irudi efektuen irudi sinpleak egiten ditu.\n" "\n" "Parametroak:\n" " pip_num: hobespen hauek ezarri behar diren irudi zenbakia\n" " x: x-ak irudiaren goiko ezkerreko ertza ezartzen du\n" " y: y -ak irudiaren beheko eskuineko ertza ezartzen du\n" " w: irudiaren zabalera\n" " h: irudairen altuera\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Switch sarrera anitz artean azkar aldatzeko erabili daiteke.\n" "\n" "Parametroak\n" " select: irteerara pasako den sarreraren zenbakia\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Iragazki honek irduairen soinua gutxiagotzeko, irudiak leuntzeko eta " "geratutako irudiak benetan geratzeko (honek ulegarritasuna onetu beharko " "luke). 0 eta 3 arteko parametro eman behar zaizkio. parametroa ez eman " "ezkero balio erabilgarri bat emango zaio.\n" "\n" "Parametroak\n" " Luma: Spatial luma erresistentzia (lehenetsia = 4)\n" " Chroma: Spatial chroma erresistentzia (lehenetsia = 3)\n" " Time: Aldiroko erresistentzia (lehenetsia = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "FFmpeg libpostprocess plugin-a.\n" "\n" "Parametroak\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "Kanpo azpitituluen letra-tipoa" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "azpititulu kokapen bertikala (panataila tamainaren arabera)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "Apititulu kodifikatzea" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "azpititulu bistaratze denbora segundutan" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Zenbait azpititulu formatuk ez du ezartzen azpititulu bakoitzarne iraupena. " "Hauentzat lehenetsitako iraupena ezarri dezakezu hemen. Zero bezala " "ezartzean azpititulu bakoizta hurrengo azpititulu arte bistaraziko da." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "azpititulu tamaina" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" "Azpititulu tamaina ezarri dezakezi hemen. Ezarpenak panatailaren tamainaren " "arabera ulertuko dira." #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "azpititulu mugimetu bertikala" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" "Azpitituluen kokapen bertikala ezarri dezakezu hemen.Ezarpenak panatailaren " "tamainaren arabera ulertuko dira." #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "Azpitituluen letra-tipoa" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Xine letra-tipo karpetako letra-tipo bat erabili daiteke azpititulu " "testuetarako." #: src/spu_dec/sputext_decoder.c #, fuzzy msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" "Xine letra-tipo karpetako letra-tipo bat erabili daiteke azpititulu " "testuetarako." #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "azpitituluen kodifikazioa" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "Korronteko azpititulu testu kodeketa. Ezarpen hau ASCII ez diren karaktereak " "behar bezala errenderizatzteko erabiltzen da. ASCII ez diren karaktereak ez " "badira zuk espero bezala bistaratzen, galdetu azpititulu sortzaileari zein " "kodeketa erabiltzen duen." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "erabili eskalagabeko OSD posible bada" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "bistaratu itxitako izenburuak MPEG-2 korronteetan" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" "Itxitako Tituluak (closed caption) normalean entzumen arazoak dituztenei " "laguntzeko azpitituluak dira." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "Itxitako-tituluen atzealdeko eskema" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Aukeratu itxitako tituluentzat gustoko duzun errendarizatzailea." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "Lehenetsitako itxitako titulu letra-tipoa" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Aukeratu ixtitako titulu testuarentzat lehenetsitako letra-tipoa." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "etzandako itxitako izenburu letra-tipoa" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "Aukeratu etzandako itxitako tituluen letra-tipoa." #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "Itxitako izenburuen letra-tamaina" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "Aukeratuko itxitako tituluen letra tamaina" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "erdira-doitu itxitako tituluak" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" "Gaiturik daudenean, itxitako titulu testua lerro bakoitzean erdiratu egingo " "da." #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: errorea ByteRun1 dekonpresioa egiterakoan\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 ez da onartzen momentuz\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 ez da onartzen momentuz\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ ez da onartzen momentuz\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: Animazio-mota ahu ez da onartzen momentu honetan\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "xine bideo irteera plugina AsCii Arte liburutegia erabiliaz" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "xine bideo irteera plugina Kolore AsCii Arte liburutegia erabiliaz" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "xine bideo irteera plugina DirectFB liburutegia erabiliaz" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "xine bideo irteera plugina XDirectFB liburutegia erabiliaz" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "xine bideo irteera plugina win32-rentzat directx erabiliaz" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "framebuffer gailu izena" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" "Ezarri erabiliko den framebuffer gailuaren fitxategi izena\n" "Ezarpen hau seguratsun kritikokoa da, fitxategi ezberdin batetara aldatzean, " "xinek fitxategia eduki arbitrario bat erabiliaz bete bait dezake. Beraz " "balioaegiazko framebuffer gailu bat dela ziurtatu behar duzu." #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Bideo modua ez da ezagutzen, barkatu.\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: %d bideo RAM buffer eskuragarri dira.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "Xine bideo irteera plugina Linux framebuffer gailua erabiliaz" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "xine bideo irteera plugina DirectFB liburutegia erabiliaz" #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "xine bideo irteera plugina ezer bistaratzeko" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "xine bideo irteera plugina OpenGL 2.0 liburutegia erabiliaz" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "gaitu buffer bikoitza" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "xine bideo irteera OpenGL - TNG erabiliaz" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Error: ioctl hutsa, okerreko gailua (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "video_out_pgx32: Errorea: '%s' ez da pgx32 framebuffer gailua\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "xine bideo irteera plugina Sun PGX32 Frame buffer-arentzat erabiliaz" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "video_out_pgx64: Errorea: ezinda '%s' framebuffer ireki\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Error: ioctl hutsa (VIS_GETIDENTIFIER), okerreko gailua (%" "s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Errorea: '%s' ez da xvr100/pgx64/pgx24 framebuffer gailua\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" "video_out_pgx64: Errorea: pantaila honetako bideo ingurunea erabilia dago\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "video_out_pgx64: Errorea: ezin dira leiho propietateak ezarri\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Abisua: bideo memoria baxua, buffer-anitza ezgaiturik\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Errorea: Bideo memoria askieza\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Abisua: bideo memoria baxua, buffer-bikoitza ezgaiturik\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Errorea: ioctl hutsa (FBIOGATTR)\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "gaitu buffer-anitzak" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" "Buffer anitzek performantzia betzen dute baina memoria grafiko gehiago " "erabiliaz." #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" "xine bideo irteera plugina Sun XVR100/PGX64/PGX24 Frame buffer-arentzat " "erabiliaz" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "Erabili hardware azelerazioa eskuragarri badago" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" "Zure sistemak onartzen duenean, zure hardware grafikoaren hardware " "azelerazioa erbailikiko da. Honek agian ez du funtzionatzen, beraz zerbait " "oker joan ezkero ezgaitu ezazu." #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "" "sdl-ek ez ditu 16 bit gainazalak emulatu, honek gauzak geldot ditzake.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: pantaila osoko modua EZ da onartzen\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "xine video irteera plugina \"Simple Direct Media Layer\" erabiliaz" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "xine video output plugina \"Libstk Surface Set-top Toolkit\" erabiliaz" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c #, fuzzy msgid "default number of video frames" msgstr "marko errepikatze lehenetsiriko kopurua" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI colour conversion method" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "xine bideo irteera plugina DirectFB liburutegia erabiliaz" #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "xine bideo irteera plugina VDPAU liburutegia erabiliaz" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "intentsitate gorria" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "Gorri koloreko osagaien intentsitatea." #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "intentsitate berdea" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "Berde koloreko osagaien intentsitatea." #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "Intentsitate urdina" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "Urdin koloreko osagaien intentsitatea." #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: egokigailuak yuy2 formatua onartzen du\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: egokigailuak yv12 formatua onartzen du\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "video_out_vidix: VIDIX liburutegiaren okerreko bertsio bat duzu\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: Ezin da dabilen VIDIX kontrolatzailerik\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: erabilitako kontrolatzailea: %s, %s-rena\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "bideo ingurune kolore teklaren gorri osagaia" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "bideo ingurune kolore teklaren berde osagaia" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "bideo ingurune kolore teklaren urdin osagaia" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "xine bideo irteera plugina libvidix X11-rentzat erabiliaz" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "" "xine bideo irteera plugina libvidix Linux Frame buffer-arentzat erabiliaz" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "%s: MIT partekatutako memoria luzapena ez dago pantailan.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: Bideo modua ez da ezagutzen, barkatu.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: adaptadoreak %s formatua onartzen du.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: Xv luzapena ez dago.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: Xv luzapena dago baina ez da yuv12 ataka erabilgarririkaurkitu.\n" " Dirudienez zure txartela grafikoak ez du Xv onartzen?!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "xine bideo irteera plugina MIT X bideo luzapena erabiltzen" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: XvMC luzapena ez dago.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr "" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " ez da XvMC onartzen \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr "" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "xineo bideo irteera plugina XvMC X bideo luzapena erabiltzen" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: errorea leihoa sorzterakoan, eskala gabeko gainjarria ezgaiturik.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: errorea pixel mapa sorzterakoan, eskala gabeko gainjarria " "ezgaiturik.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: eskala gabeko gainjarria sorturik (%s modua).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "eskalatze modu bilinearra" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h #, fuzzy msgid "Xv port number" msgstr "sarrera zenbaki okerra" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: ez dago plugin erabilgarririk '%s' kudeatzeko\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: errorea, buffer mota ezezaguna: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "audio buffer kopurua" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: atzerapena kalkulatzea ezinezko audio gailu eskuraezin batekin\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "" "Hus soinu txartelan idazterakoan. Konektatu gabeko USB gailu bat ote?\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "kontrolatzaileak ez du 8bit onartzen, 16bit-era bihurtzen.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "kontrolatzaileak ez du mono onartzen, estereo-ra bihurtzen.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "kontrolatzaileak ez du estereo onartzen, mono-ra bihurtzen.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "audioa eta bideoa sinkronizatzeko metodoa" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "abiarazterakoan audio bolumena" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Xine abiaraztean ezarriko den audio bolumena." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "berezarri tamaina maila abiaraztean" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "ezgaiturik badago, xine-k ez ditu nahasle ezarpenak aldatuko abiaraztean." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "" "audio_out: barkatu, hau ez zen gertatu beharko. mesedez xine berrabiarazi.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "Konfigurazio fitxategia xine-ren bertsio berriagobategatik aldatua izan da." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: ABISUA: zure konfigurazioa ezin da gorde\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "configfile: ABISUA: huts %s konfigurazioa gordetzerakoan\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: ABISUA: agian apurturiko %s konfigurazio fitxategia ezabatzen\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "" "configfile: ABISUA: zuk segurtasun kopia %s fitxategia egiaztatu beharko " "zenuke\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: ¡'%s' sarrera ezin MRL-tik aldatu\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "info_helper: ezin da irteera karaktere jokoa aurkitu\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "info_helper: ez da moldatzea onartzen: %s -> UTF-8, ez da moldatuko\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": open() funtzioa ez zen inoiz deitu beharko\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": sarrera pluginia ez ezarririk!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: huts grabatutako datuak irakurtzerkaoan: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: bilaketak huts egin du: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: huts sarrera pluginetik irakirtzerakoan\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: errorea % fitxategian idazterakoan, byte-ak: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: open() funtzioa ez zen inoiz deitu beharko\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: bilaketak huts egin du\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % byte alde batetara utzirik\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: sarrera pluginia ez ezarririk!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "korreonte grabaketa aukera ezgaiturik dago konfigruaketan media.capture." "save_dir ezarri arte." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine ez dago jatorri horretatik grabatzeko gaiturik (kopia eskubidedun " "materiala agian?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: ez da fitxategi izena eman!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: errorea %s fitxategia irekitzerakoan: %s\n" #: src/xine-engine/io_helper.c #, fuzzy, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: Baimena ukaturik\n" #: src/xine-engine/io_helper.c #, fuzzy, c-format msgid "io_helper: waiting failed: %s\n" msgstr "input_rip: bilaketak huts egin du: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "huts soket egoera eskuratzerakoan" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Baimena ukaturik\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Fitxategia ez da aurkitu\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Konexioa Ukaturik\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: %d plugin mota ezezaguna %s-n\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: %s plugina alde batetara utzi, okerreko iface bertsioa %d (%d " "espero zen)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "load_plugins: plugin muga gainditu da, %s ezin da kargatu\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "%s deskodetzailearen lehentasuna" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: %s:%s plugin aurkitu dira\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: alde batetara uzten %s plugin karpeta irakurtezina.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: ezin da %s identifikatu\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: ezin da %s plugin liburutegia ireki:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: ezin da %s-eko plugin informazio eskuratu:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "" #: src/xine-engine/load_plugins.c #, fuzzy, c-format msgid "Unable to create %s directory: %s\n" msgstr "Ezin da %s ireki: %s.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: %d eduki atzemate estrategia ezezaguna\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: huts <%s> audio irteera plugina kargatzerakoan\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" "load_plugins: audio irteera auto-frogak ez du adio kontrolatzailerik " "aurkitu.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: ezin da %s plugin liburutegia ireki:\n" "%s\n" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Bufferra betetzen..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "" "'%s' letra tipoaren okerreko bertsioa. %d espero zen baina %d aurkitu da.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "'%s-%d' letra-tipoa dagoeneko kargaturik, bitxia.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "huts '%s' letra tipoa kargatzerakoan (%d < %d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: ezin da ft2 liburutegia abiarazi\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" "osd: errorea letra-tipo tamaina ezarpenean (letra-tipo ez eskalagarria?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: ezin da irteera karaktere jokoa aurkitu\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: ez da moldatzea onartzen: %s -> %s, ez da moldatuko\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: errorea glyph kargatzerkaoan\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: errorea glyph reenderizatzerakoan\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: letra-tipoa ez dago ezarririk\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: errorea glyph %i kargatzerakoan\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: errorea reenderizatzerakoan\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "" "OSD eta azpitituluetan erabiliko den paleta (aurreko-ertza-atzeko koloreak)" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: ez dago pluginik '%s' kudeatzeko\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: errorea, buffer mota ezezaguna: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "bideo buffer kopurua" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "onartzen den alde batetara utziko marko kopuru ehunekoa" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "onartzen den alde batetara utziko marko kopuru ehunekoa" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "" "video_out: barkatu, hau ez zen gertatu beharko. mesedez xine berrabiarazi.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "irudi horizontal kokalekua irteera lehoan" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "irudi bertikal kokalekua irteera lehoan" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "bideo eskalatze guztiak ezgaitu" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: errorea mrl analizatzerakoan\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: input plugin-a aurkiturik : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: sarrera pluginak ezin du MRL-a [%s] ireki\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: ezin da [%s] MRL-aren plugina aurkitu\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "bidoa alde batetara uzten\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "audioa alde batetara uzten\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "azpi-irudia alde batetara uzten\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "'%s' azpititulu mrl-a irekirik\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: errorea azpititulu mrl-a irekitzerakoan\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: MRL-ko '%s' aukera aldaketa ez da onartzen\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" "xine: Ezarritako \"%s\" gordetze karpeta (save_dir) segurtasun arrisku bat " "izan daiteke.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "" "Ezarritako gordetze karpeta (save_dir) segurtasun arrisku bat izan daiteke." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: lokala ez du C liburutegiak onartzen\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "medio formatu atzemate modua" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" "xinek erreproduzitzeko sarrera ofrmatua atzemateko zenbai metodo erabiltzen " "ditu. Balioak:\n" "default\n" "Lehenik eduki bidez atzematen saiatu gero izen luzapenaz.\n" "reverse\n" "Lehenik izen luzapenaz atzematen saiatu gero eduki bidez.\n" "content\n" "Eduki bidez bakarrik atzeman.\n" "\n" "extension\n" "Izen luzapen bidez bakarrik atzemna.\n" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "korronteak gordetzeko karpeta" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "Onartu aldaketa inplizitoak konfiguraketan (adib. MRL bidez)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "mezuak" #: src/xine-engine/xine.c msgid "plugin" msgstr "plugina" #: src/xine-engine/xine.c msgid "trace" msgstr "aztarna" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Unknown host:" msgstr "ostalari ezezaguna" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Connection refused:" msgstr "io_helper: Konexioa Ukaturik\n" #: src/xine-engine/xine_interface.c #, fuzzy msgid "File not found:" msgstr "io_helper: Fitxategia ez da aurkitu\n" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Indizea bersortzen..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "memcpy metodoak frogatzen (txeikiena obea da)\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "xinek erabiltzen duen memoria kopia metodoa" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "" #~ "configfile: ABISUA: %s-en konfigurazio fitxategia segurtasun kopia " #~ "egiten\n" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: okerreko mrl-a: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: irakurketa errorea (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: ezin da '%s' ebatzi.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: ezin da '%s'-ra konektatzen.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "stdin: ezin da atzera salto egin! (% > %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: errorea MRL-analizatzerakoan\n" #~ msgid "raw device set up for DVD access" #~ msgstr "DVD irakurleantzat gailu gordin (raw) ezarpenak" #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "Goiko mezuak vcdimager arazpen maila ezezagun bat du" xine-lib-1.2/po/sk.po0000644000175000017500000057632214647725152012276 0ustar meme# Slovak xine-lib.po file. # Copyright (C) 2002 Free Software Foundation, Inc. # Tomáš Kovár , 2002. # msgid "" msgstr "" "Project-Id-Version: xine-lib 1.0\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2004-09-15 13:53+0100\n" "Last-Translator: \n" "Language-Team: Slovak \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: sk\n" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: KBabel 1.9\n" #: lib/hstrerror.c msgid "No error" msgstr "" #: lib/hstrerror.c msgid "Unknown host" msgstr "" #: lib/hstrerror.c msgid "No address associated with name" msgstr "" #: lib/hstrerror.c msgid "Unknown server error" msgstr "" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "" #: lib/hstrerror.c msgid "Unknown error" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c msgid "GSM 6.10 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "POMOC! iba mono audio ovládač?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "povoliť a/52 dynamickú úpravu rozsahu" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "povoliť audio zmiešanie na 2.0 priestorové stereo" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() zlyhal.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 zlyhal.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit zlyhal.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "xine file audio output plugin" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out:Už otvorené...PREČO!" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() z %s zlyhal: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "audio_alsa_out: >>> skontrolujte či už iný program používa PCM <<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: poškodená konfigurácia pre toto PCM: konfigurácia " "nedostupná: %s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : podporované módy sú" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (4-kanály nepovolené v xine konfigu)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-kanálov" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-kanálov nepovolené v xine konfigu)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " 5-kanálov" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (5-kanálov nepovolené v xine konfigu)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-kanálov nepovolené v xine konfigu)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (a/52 a DTS pass-through not enabled in xine config)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() zlyhal:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Skontrolujte či už iný program používa PCM <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8bit" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16bit" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24bit" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32bit" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " mono" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "zariadenie pre mono výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " stereo" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "zariadenie pre stereo výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " 4-kanály" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "zariadenie pre 4-kanálový výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-kanálov" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "zariadenie pre 5.1-kanálový výstup" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " a/52 a DTS pass-through" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " a/52 a DTS pass-through" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() zlyhal: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "alsa mixovacie zaridenie" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "" "výstupný xine audio plugin používa alsa-compliant audio zariadenia/ovládače" #: src/audio_out/audio_coreaudio_out.c #, fuzzy msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "výstupný video modul pre win32 použitím directx" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr "" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "výstupný xine audio plugin pre win32 používa directx" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "výstupný xine audio plugin pre win32 používa directx" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: pripájanie na ESD server %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: pripájanie na esd server ...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: nemôžem sa pripojiť na %s ESD server: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "výstupné oneskorenie esd audia (nastavte odstup a/v)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "výstupný xine audio plugin používa esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "xine file audio output plugin" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "xine file audio output plugin" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "maximálna dľžka medzery irixal audio výstupu v 1/90000s" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "výstupný xine audio plugin používa IRIX libaudio" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "mĺkvy výstupný xine audio plugin" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Otváram audio zariadenie %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: varovanie: vzork. frekvencia %d Hz nepodporovaná, skúšam " "44100 Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" "audio_oss_out: audio frekv. : %d požadovaná, %d poskytnutá zariadením\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "názov OSS audio zariadenia" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" "Špecifikujte zákl. čast mena audio zariadenia, potom použite " "oss_device_number na nastavenie čísla zariadenia. Vyberte auto ak autom. " "hľadať zariadenie." #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "názov OSS audio zariadenia" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" "Názov audio zariadenia je tvorený z oss_device_name a čísla zariadenia " "(napr. /dev/sound/dsp2). Ak nepotrebujete číslo, nastavte na -1 (eg /dev/" "sound/dsp). Rozsah čísla je -1 alebo 0-15." #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "audio_oss_out: audio.device.oss_device_name = auto, skúšam devs\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Automatické hľadanie audio zar. zlyhalo\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: používam zariadenie >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: zlyhalo otvorenie audio zariadenia %s:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "synchronizačná A/V metóda použitá OSS, závisí od ovládača/hardvéru" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: RT synchronizácia audio ovládača zakázaná ...\n" "audio_oss_out: ...budú použité systémové hodiny skut.času pre softvérovú\n" "audio_oss_out: ...preto môžu byť problémy s audio/video synchronizáciou\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "výstupné oneskorenie esd audia (nastavte odstup a/v)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: RT synchronizácia audio ovládača zakázaná ...\n" "audio_oss_out: ...zisťujem veľkosť výst. vyrovn. pamäte: %d bytov\n" "audio_oss_out: ...môžu byť problémy s audio/video synchronizáciou\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: podporované módy sú" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " a/52 pass-through" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: open() mixer %s zlyhal: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" "výstupný xine audio plugin používa oss-compliant audio zariadenia/ovládače" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " a/52 pass-through" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" "výstupný xine audio plugin používa sun-compliant audio zariadenia/ovládače" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: otvorenie audio zariadenia %s zlyhalo: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "audio_sun_out: otvorenie audio zariadenia %s zlyhalo: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" "výstupný xine audio plugin používa sun-compliant audio zariadenia/ovládače" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "modul vstupu zo súboru" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_audio_dec: zväčšujem buffer na %d aby sa predišlo pretečeniu.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "ffmpeg_audio_dec: nenašiel ffmpeg dekóder pre buf typu 0x%X\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: nemôžem otvoriť dekóder\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "ffmpeg_video_dec: nepodporovaný formát snímku, DR1 nepovolený.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "ffmpeg_video_dec: nepodporovaný formát snímku, DR1 nepovolený.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: priame vykreslovanie zapnuté\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "ffmpeg_video_dec: nepodporovaný formát snímku, DR1 nepovolený.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: nedá sa otvoriť dekóder\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "ffmpeg_video_dec: nedá sa otvoriť dekóder\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_video_dec: zväčšujem buffer na %d aby sa predišlo pretečeniu.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "ffmpeg_video_dec: nepodporovaný formát snímku, DR1 nepovolený.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "ffmpeg_video_dec: nenájdený ffmpeg dekóder pre buf typu 0x%X\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "kvalita ffmpeg mpeg-4 postspracovania" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "modul vstupu z rádia v4l" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "xine file audio output plugin" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c msgid "NES Music audio decoder plugin" msgstr "" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c msgid "wavpack audio decoder plugin" msgstr "" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "stopa ogg: vorbis audio indikovaná, ale hlavička vorbis prúdu nenájdená.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "xine file audio output plugin" #: src/combined/xine_theora_decoder.c msgid "theora video decoder plugin" msgstr "" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: zväčšujem buffer na %d aby sa predišlo pretečeniu.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "modul vstupu zo súboru" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: varovanie: Prúd id=%d je kryptovaný.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Media stream scrambled/encrypted" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Obnovujem index..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "demux_avi: neplatný avi blok \"%c%c%c%c\" na poz. %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: index avi súboru je poškodený\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "demux_avi: zlyhalo preskočenie videa na nasl. blok (poz. %)\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "DVB (Digital TV) vstupný modul" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "neplatná veľkosť FILM bloku\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "nerozoznaný FILM blok\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: neznáma kompresia: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: neznáma kompresia: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: neznámy blok: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "modul vstupu zo súboru" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: Nerozoznaný stream_id 0x%02x. Prosím nahláste to " "tvorcom xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "demux_mpeg_block: chyba! uvoľňujem. Prosím nahláste to tvorcom xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_block: varovanie: rezervovaných 10 bit hlavičky PES nenajdené\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: varovanie: hlavička PES indikuje, že tento prúd môže byť " "zašifrovaný (režim šifrovania %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "modul vstupu z prúdu pnm" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: Nerozoznaný stream_id 0x%02x. Prosím nahláste to " "tvorcom xine.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "demux_mpeg_pes: varovanie: dekódovanie PACK prúdu id=0x%x zlyhalo.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "" "demux_mpeg_pes: varovanie: rezervovaných 10 bit hlavičky PES nenajdené\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: varovanie: hlavička PES indikuje, že tento prúd môže byť " "zašifrovaný (režim šifrovania %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes:Nerozoznaný súkr. prúd 1 0x%02x. Prosím nahláste to tvorcom " "xine.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "modul vstupu z rádia v4l" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "modul vstupu zo súboru" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "modul vstupu zo súboru" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: zlé parametre hlavičky\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: nepodporovaný typ zvuku: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "neznámy VOC blok typu (0x%02X); prosím nahlásiť tvorcom xine\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "neznáma VOC kompresia typu (0x%02X); prosím nahlásiť tvorcom xine\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "modul vstupu zo súboru" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "demux_wc3movie: SHOT blok refercoval neznámu paletu (%d >= %d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "demux_wc3movie: Bol problém pri nahrávaní blokov palety\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Zlyhalo otvorenie zariadenia titulkov %s (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_video: zápis na video zariadenie zlyhal (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "požadované tlačidlo nedostupné\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "dxr3_decode_video: Zlyhalo otvorenie riadiaceho zariadenia %s (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "Skúsiť zosynchronizovať každý snímok" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "Použiť alternatívny Play mód" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Povolením tejto voľby sa použije hladšie prehrávanie." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "Opraviť trvanie snímku v poškodených prúdoch" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Zlyhalo otvorenie video zariadenia %s (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "dxr3_decode_video: zápis na zariadenie by blokoval. vyprázdňujem\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: zápis na video zariadenie zlyhal (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "dxr3_decode_video: WARNING: neznámy kód rýchlosti snímkov %d\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: VAROVANIE: korigujem snímk. rýchlosť z PAL na NTSC\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: init librte zlyhal\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte pracuje iba s rozmermi videa, ktoré sú násobkami 16\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: zlyhalo získanie rte kontextu.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: nemohol vytvoriť kodec.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "Dxr3enc: rte mpeg výstupná rýchlosť (kbit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" "Bitová rýchlosť, ktorú má mpeg kód. knižnica librte použiť pre dxr3 kódovací " "mód" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: nedá sa inicializovat kontext: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: nemožno začať kódovanie: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: Nešlo naštartovať FAME knižnicu\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "Dxr3enc: kvalita mpeg kódovania snímku" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "Dxr3: priorita SCR modulu" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "Dxr3enc: výstupná rýchlosť libavcodec mpeg (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "Dxr3enc: Maximálny kvantizér" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Zlyhalo otvorenie ovládacieho zariadenia %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "prehodiť párne a nepárne riadky" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "Pridať čierne pruhy na korekciu pomeru obrazu" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "dxr3: použije alternatívny mód pre prehratie mpeg kódovania" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "Povolením tejto voľby sa použije hladšie prehrávanie." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Zlyhalo otvorenie video zariadenia %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "kóder pre nie mpeg obsah" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "video_out_dxr3: Mpeg kóder libavcodec nešiel spustiť.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: Mpeg kóder rte nešiel spustiť.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: Mpeg kóder fame nešiel spustiť.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Mpeg kódovanie zakázané.\n" "video_out_dxr3: to je v poriadku, nepotrebujetie to na mpeg video ako DVD, " "ale\n" "video_out_dxr3:nebudete schopní prehrať nie-mpeg obsah použitím tohto video " "výstupného\n" "video_out_dxr3: ovládača. Pozrite README.dxr3 pre detaily konfigurácie " "kódera.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" "video_out_dxr3: Neskompilovaný mpeg kóder.\n" "video_out_dxr3: to je v poriadku, nepotrebujetie to na mpeg video ako DVD, " "ale\n" "video_out_dxr3:nebudete schopní prehrať nie-mpeg obsah použitím tohto video " "výstupného\n" "video_out_dxr3: ovládača. Pozrite README.dxr3 pre detaily konfigurácie " "kódera.\n" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "Dxr3: video výst. mód (tv alebo overlay)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "Dx3: hodnota kľúčovej farby prekrývánia" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "rozsah kľúčovej farby prekrývánia" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "Orezať prekrývanú oblasť zhora a zdola na zamedzenie zelených riadkov" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: prosím spustite autocal, prekrývanie zakázané\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "dxr3 preferovaný tv mód" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: nastavenie video módu zlyhalo.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: Potrebujete mpeg kóder na prehratie nie-mpeg videa na dxr3\n" "video_out_dxr3: Čítajte README.dxr3 kôli detailom.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: CHYBA Čítania init súboru prekrývania. Spustite autocal!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: úspešne pripojenie na cddb server '%s:%d'.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "input_cdda: nemožno sa pripojiť na cddb server '%s:%d' (%s).\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "CD Digital Audio (aka. CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "zariadenie pre cdda mechaniku" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" #: src/input/input_cdda.c msgid "query CDDB" msgstr "" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "cddbp meno servera" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "cddb port servra" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "input_dvb: zlyhalo otvorenie súboru dvb kanála '%s': %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: tuner_set_channel zlyhal\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: nemožno otvoriť dvb zariadenie\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: nemožno otvoriť dvr zariadenie '%s'\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "DVB (Digital TV) vstupný modul" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Chyba pri získavaní ďaľšieho bloku z DVD (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Nemožno otvoriť DVD zariadenie\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "Použijeme kešovanie predčítaním?" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "" #: src/input/input_file.c #, fuzzy, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: chyba pri čítaní (%s)\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, fuzzy, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: chyba pri čítaní (%s)\n" #: src/input/input_file.c msgid "file input plugin" msgstr "modul vstupu zo súboru" #: src/input/input_file.c msgid "file browsing start location" msgstr "začiatočné miesto prehliadania súborov" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "modul vstupu zo súboru" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "modul vstupu zo súboru" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "modul vstupu gnome-vfs dodávaný so xine" #: src/input/input_helper.c msgid "list hidden files" msgstr "zobraziť skryté súbory" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "modul vstupu zo štandard. vstupu" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: chyba pri čítaní %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Pripájam sa na HTTP server..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: neplatná odpoveď http\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: presmerovanie 3xx: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: stav http nie je 2xx: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: dĺžka obsahu = % bajtov\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: chyba pri čítaní %d." #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "modul vstupu zo siete protokolom http" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "adresa http proxy" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "port http proxy" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "meno používateľa pre http proxy" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "heslo pre http proxy" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "modul vstupu zo siete protokolom mms" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c #, fuzzy msgid "network bandwidth" msgstr "Sieťové prenosové pásmo" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" #: src/input/input_mms.c msgid "MMS protocol" msgstr "MMS protokol" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Vyberte protokol nad MMS. TCP je lepšie, ale možno budete potrebovať HTTP za " "firewall-om." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "modul vstupu zo štandard. vstupu" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "modul vstupu zo siete dodávaný so xine" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "modul vstupu zo súboru" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "modul vstupu zo súboru" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "modul vstupu zo štandard. vstupu" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "modul vstupu z prúdu pnm" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: nedá sa vytvoriť pvr súbor (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: nedá sa otvoriť pvr súbor (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: chyba pri čítaní (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: nemožno otvoriť zariadenie %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_G_CODEC zlyhal, možno sa API zmenilo?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_S_CODEC zlyhal, možno sa API zmenilo?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "modul vstupu z WinTV-PVR 250/350" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "zariadenie použité pre WinTV-PVR 250/350 (pvr modul)" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "" #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "Špecifikovaná IP adresa je multicast\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Nemôžem nájsť adresu rozhrania %s:%s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "" "zlyhala funkcia setsockopt(IP_ADD_MEMBERSHIG) (kernel s podporou " "multicastingu?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "nemožno zistiť adresu '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "nemožno sa naviazať k '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: zastavujem čítacie vlákno...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: čítacie vlákno ukončené\n" #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Otváranie >súbor:%s port:%d rozhranie:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: nemožno vytvoriť nové vlákno (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "modul vstupu zo siete protokolom RTP a UDP dodávaný s xine" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "modul vstupu zo siete protokolom rtsp" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "modul vstupu zo súboru" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "modul vstupu zo súboru" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: nemožno otvoriť '%s'\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "modul vstupu zo štandard. vstupu" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "modul vstupu z tv v4l" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Buffer dáta odtiekli..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Buffer pretiekol..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Prispôsobovanie sa..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Meno tuneru nenájdené\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "modul vstupu z tv v4l" #: src/input/input_v4l.c msgid "v4l video device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "cesta k video zariadeniu v4l" #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "" #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "modul vstupu z rádia v4l" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "cesta k rádio zariadeniu v4l" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: neplatné MRL. Použite vcdo:/<číslo stopy>\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: neplatná stopa %d (platný rozsah: 0..%d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "nemožno otvoriť %s: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: nemožno otvoriť %s: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "modul vstupu z Video CD" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: zlé mrl: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: nemožno sa pripojiť k '%s'\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: nemožno sa pripojiť k servru %s\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: nemožno zaviesť reláciu\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" "rtsp_session: rtsp server typu '%s' nie je zatiaľ podporovaný. prepáčte.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "input_dvd: Zariadenie %s zlyhalo pri otvorení počas volania eject\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Pripájanie k MMS serveru (cez tcp)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: chyba posielania\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: zlý formát odpovede\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: presmerovanie 3xx nie je implementované: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: stav http nie je 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: Presmerovanie umiestnenia nie je implementované\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Pripájanie na MMS server (cez http)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "neplatné url\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "nepodporovaný protokol\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "dxr3 preferovaný tv mód" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "dxr3 preferovaný tv mód" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: získaná spáva od servra počas čítania prúdu:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "input_pnm: nemožno sa pripojiť k '%s'\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: zlyhalo nastavenie prúdu dát\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR neimplementované pre nenulové offsety" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END neimplementované zatiaľ." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "skok neimplementovaný zatiaľ pre" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "zlý typ položky" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "zlé číslo záznamu" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "zlé číslo segmentu" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Chyba pri získavaní aktuálneho čísla segmentu" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Vyššie uvedené by malo byť prevedené" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "zlyhalo hľadanie zariadenia s VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "bol poslaný parameter neznámej triedy" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Neplatný typ aktuálnej položky" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Udalosť neznámeho typu: " #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "Video CD modul s PBC a podporou pre: (X)VCD, (X)SVCD, HQVCD, CVD ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "predvolený typ, ktorý sa použije na automat. prehratie VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" "Jednotka prehrávania, ktorú použiť, keď nie je uvedená v MRL, napr. vcd:// " "alebo vcd:///dev/dvd:" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "predvolené CD zariadenie použité pre VCD, pokiaľ nie je žiadne zadané" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" "Čo použiť ak nie je mechanika zadaná. Ak je zadané nič, xine preskenuje CD " "mechaniky." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "Rozsah ukazovateľa pozície prehrávania použitého pri prehrávaní." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "Použijeme kešovanie predčítaním?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "Na slabších strojoch by mohlo viesť k trhanému prehrávaniu" #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "Automaticky postupovať po stopách/položkách?" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" "Ak je povolené, mali by sme automaticky postúpiť na ďaľšiu položku alebo " "stopu. Použité iba ak nie je zapnutá kontola prehrávania (PBC)." #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "Zobraziť 'odmietnuté' LID?" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "formát reťazca pre nápis na obrazovke" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "formátovací reťazec pre pole komentáru prúdu dát" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" "Formát použitý v titulku GUI. Podobá sa zadaniu unixového dátumu. " "Špecifikátory formátu začínaju znakom percento. Špecifikátory sú %A, %C, %c, " "%F, %I, %L, %N, %P, %p, %S, %T, %V, %v, and %%." #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "debugovacia maska príznakov" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "cesta k real player kódekom, ak sú nainštalované" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (audio) Nedajú sa zistiť symboly - nekompatibilná dll: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "libareal: decoder init zlyhal, kód chyby: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "libareal: chutné nastavenie dekódera zlyhalo, kód chyby: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: ach, real môže mať viac ako 2 kanály ?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "libreal: Chyba hľadania symbolov! (nekompatibilita verzii?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "cesta k win32 dll kódekom" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "xine file audio output plugin" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "w32codec: ICOpen zlyhal! neznámy kódek %08lx / zlé parametre?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) zlyhal: Chyba %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery zlyhal: Chyba %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin zlyhal: Chyba %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder zlyhal! neznámy kódek %08lx / zlé parametre?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder zlyhal! neznámy kódek %08lx / zlé parametre?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: dekóder zlyhal pri štarte. Je '%s' nainštalovaný?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) Neadekvátny audio formát\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen chyba %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Chyba inicializácie DirectShow zvuku\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Chyba inicializácie DMO zvuku\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr "" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] "" msgstr[1] "" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr "" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" "Pokročilý tvtime/odprekladací modul s detekcoiu pulldown\n" "Tento modul má za cieľ poskytnúť mechanizmy korekcie prekladania " "porovnateľné s vysoko kvalitnými progresívnymi DVD prehrávačmi a takzvanými " "zdvojovačmi riadkov, pre použitie s po monitormi, projektormi a inými " "progresívnymi zobrazovacími zariadeniami.\n" "\n" "Parametre\n" "\n" " Method: Vybrať metódu/algoritmus na použitie, pozrite nižšie na " "vysvetlenie metód.\n" "\n" " Enabled: Zapnutý/vypnutý modul.\n" "\n" " Pulldown: Vybrať detekčný 2-3 pulldown algoritmus. 24 snimk./s filmy ktoré " "boli konvertované na NTSC môžu byť konvertované a rekonštruované do " "originálnych (neprekladaných) snímkov.\n" "\n" " Framerate_mode: Vybraním 'full' bude odprekladané každého polsnímku do " "unikátneho snímku pre televíznu a vyššiu kvalitu. Táto možnosť efektívne " "zdvojnásobi rýchl.snímkov a vylepší plynulosť. Dodajme, že, hoci plných " "59.94 snímk./s nie je m,ožné dosiahnuť s neupraveným Linuxovým jadrom 2.4l " "(ktoré používa frekvenciu prerušenia 100Hz). Novér RedHat a 2.6 jadrá " "používajú vyššie nastavenie HZ (512 a 1000, v poradí) a mali by dobre " "fungovať.\n" "\n" " Judder_correction: Ak je povolené 2-3 pulldown a je deketovaný filmový " "materiál, je možné obmedziť rýchlosť snímkov na pôvodne použitú rýchlosť (24 " "snímkov/s). To spôsobí, že snímky budú rovnomerne rozložené v čase. Ich čas " "bude súhlasiť a eliminuje sa trasenie..\n" "\n" " Use_progressive_frame_flag: Dobre zvládnuté prúdy MPEG2 používajú príznak " "k indikáci progresívneho materiálu. Toto nastavenie riadi, či veríme či " "neveríme tomuto príznaku (niektoré ojedinelé chybné prúdy mpeg2 ho nastavujú " "zle)..\n" "\n" " Chroma_filter: DVD/MPEG2 používa prekladaný formát obrazu, ktorý má veľmi " "zlé zvislé farebné rozlíšenie. Prevzorkovánie farby na vyššie rozlišení prr " "účely korekcie prekladania môže spôsobit vytvořenie artefaktov (napr. " "farebné pruhy). Túto voľbu použite k zvislému rozmazaniu farby po korekcii " "prekladania, čo odstráni tieto artefakty. Varovanie: náročné na CPU.\n" "\n" " Cheap_mode: Toto preskočí nákladnú konverziu obrazu YV12->YUY2 a rutiny " "tvtime/dscaleru budú používané, ako by stále spracovávaly obrazy YUY2. " "Samozrejme to nie je správne, nie všetky body budú vyhodnotené algoritmom " "pre rozhodovanie o oblastiach ku korekcii a farba bude zpracována oddelene. " "Toto dovolí luďom s nie tak rychlými strojmi, vyzkúšať si algoritmus " "korekcie prekladania, v kompromise mezi kvalitou a využitím CPU.\n" "\n" "Metódy odprekladania: (Nie všetky metódy sú dostupné pre všetky plataformy)\n" "\n" "(OPRAV: vysvetlenie všetkých metód, skontr. tvtime/dscaler dokum... už som " "lenivý)\n" "\n" "* Používa niektoré algoritmy z tvtime a dscaler projektu.\n" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "tvtime: Žiadna metóda odprekladania nie je dostupná, končím.\n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "Snímkov za sekundu generovaných Goom-om" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "Šírka obrazu Goom v pixeloch" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "Výška obrazu Goom v pixeloch" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "" #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "Metóda konverzie priestoru farieb použitá Goom-om" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "Mosaico robí jednoduché obraz v obraze efekty.\n" "\n" "Parametre\n" " pip_num: počet obrazových slotov, na ktoré sa použije nastavenie\n" " x: x-ová súradnica ľavého horného rohu obrazu\n" " y: y-nová súradnica ľavého horného rohu obrazu\n" " w: šírka obrazu\n" " h: výška obrazu\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" "Prepínač môže byť použitý pre rýchle prepínanie medzi viacerými vstupmi.\n" "\n" "Parametre\n" " select: počet vstupov, ktoré prejdú na výstup\n" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Box blur robí jednoduché rozmazanie obrazu.\n" "\n" "Parametre\n" " Radius: veľkosť filtru\n" " Power: ako často má byť filter použitý\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" "Tento filter má za cieľ znížiť šum obrazu produkovaním vyhladených snímkov a " "robením nehybného obrazu skutočne nehybným (to by malo zvýšiť " "komprimovateľnosť). Môže byť zadané od 0 do 3 parametrov. Ak vynecháte " "parameter, bude odhadnutá primeraná hodnota.\n" "\n" "Parametre\n" " Luma: priestorová intenzita svetlosti (predvolené = 4)\n" " Chroma: priestorová intenzita sýtosti (predvolené = 3)\n" " Time: dočasná sila (predvolené = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" "Alternatívny softvérový ekvalizér, ktorý pre jednoduchú úpravu svetlosti, " "kontrastu a sýtosti používa vyhladávacie tabuľky (veľmi pomalé), dovoluje to " "naviac gamma korekciu k nastaveniu jednoduchého jasu, kontrastu a " "nasýtenia.\n" "Používa ten istý optimalizovaný MMX kód ako 'eq' ak sú všetky gamma hodnoty " "1.0.\n" "\n" "Parametre\n" " gamma\n" " jas\n" " kontrast\n" " sýtosť\n" " rgamma (gamma pre červenú zložku)\n" " ggamma (gamma pre zelenú zložku)\n" " bgamma (gamma pre modrú zložku)\n" "\n" "Rozsahy hodnôt sú 0.1 - 10 pre gammy, -2 - 2 pre kontrast (negatívne hodnoty " "spôsobia negatívny obraz), -1 - 1 pre jas a 0 - 3 pre sýtosť.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" "Softvétový ekvalizér s interaktívným ovládaním tak ako pri hardvérovom " "ekvalizéri pre karty, ktoré nepodporujú riadenie jasu a kontrastu " "harvérovo.\n" "\n" "Parametre\n" " jas\n" " kontrast\n" "\n" "Poznámka: K ich nastaveniu je možne použiť ovládacie okno frontendu.\n" "\n" "* mplayer's eq (C) Richard Felker\n" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" "Expand modul je navrhnutý tak, aby prijímal snímky s lubovolnými pomermi " "strán a konvertoval ich na 4:3 pomer pridaním čiernych pruhov navrch a " "naspodok obrazu. To nám dovolí posunúť OSD a titulky tak, aby neprekrývali " "obraz.\n" "\n" "Parametre (FIXME: lepšia nápoveda)\n" " Enable_automatic_shift: Povoliť automatické posunutie\n" " Overlay_y_offset: Manuálne zvislé posunutie\n" "\n" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "FFmpeg libpostprocess modul.\n" "\n" "Parametre\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" "\n" "* libpostprocess (C) Michael Niedermayer\n" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" "Rozostrovacia maska /gausovské rozmazanie\n" "Jemožné nastaviť šírku a výšku matice nepárnymi veľkosťami v oboch smeroch " "(min = 3x3, max = 13x11 alebo 11x13, obyčajne niečo medzi 3x3 a 7x7) a " "pomerné množstvo ostrosti/rozmazania pridaného k obrazu (rozumný rozsah by " "mal byť -1.5 - 1.5).\n" "\n" "Parametre\n" "\n" " Luma_matrix_width: Šírka matice (mus'byť nepárne)\n" "\n" " Luma_matrix_height: Výška matice (musí byť nepárne)\n" "\n" " Luma_amount: Pomerné množstvo ostrosti/rozmazania " "(=0 vypnuté, <0 rozmazanie, >0 ostrenie)\n" "\n" " Chroma_matrix_width: Šírka matice (mus'byť nepárne)\n" "\n" " Chroma_matrix_height: Výška matice (mus'byť nepárne)\n" "\n" " Chroma_amount: Pomerné množstvo ostrosti/rozmazania " "(=0 vypnuté, <0 rozmazanie, >0 ostrenie)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Rémi Guyomarch\n" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "Font pre externé titulky" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "Vertikálny posun titulkov (vzhľadom k velkosti okna)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "Kódovanie titulkov" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c msgid "DVB subtitle decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "Predvolený čas na skrytie titulkov v sekundách" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "Font pre externé titulky" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "Kódovanie titulkov" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "Použiť OSD bez zmeny mierky, ak je možné" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "Povoliť skyté titulky v MPEG-2 prúdoch" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "Schéma skrytých titulkov popredie/pozadie" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "Štandardný font skrytých titulkov" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "Font kurzívy skrytých titulkov" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "Veľkosť fontu skrytých titulkov" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "Prispôsobenie centrovania skrytých titulkov" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: chyba pri ByteRun1 dekomprimácii\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 nie je podporovaný momentálne\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 nie je podporovaný momentálne\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ nie je podporovaný momentálne\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: Tento anim-typ nie je podporovaný momentálne\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c msgid "gdk-pixbuf image video decoder plugin" msgstr "" #: src/video_dec/image.c msgid "image video decoder plugin" msgstr "" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c msgid "mpeg2 based video decoder plugin" msgstr "" #: src/video_dec/libopenhevc.c msgid "HEVC video decoder plugin" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c msgid "mmal-based HW video decoder plugin" msgstr "" #: src/video_dec/rgb.c msgid "Raw RGB video decoder plugin" msgstr "" #: src/video_dec/yuv.c msgid "Raw YUV video decoder plugin" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "výstupný video modul použitím AsCii Art knižnice" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "výstupný video modul použitím Color AsCii Art knižnice" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "Dx3: hodnota kľúčovej farby prekrývánia" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "Dx3: hodnota kľúčovej farby prekrývánia" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "výstupný modul xine s použitím DirectFB knižnice." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "" #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "výstupný video modul pre win32 použitím directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: sú podporované iba pravé farby truecolor/directcolor (%d).\n" " Zkontrolujte 'fbset -i' alebo skúste 'fbset -depth 16'.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "zariadenie framebufferu" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Váš video mód nebol rozpoznaný, prepáčte.\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: %d video RAM buffere dostupné.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "WARNING: %s: Buffere s nulami sú ZAKÁZANÉ lebo je iba %d buffrov\n" " k dispozícii, čo je menej neždoporučených %d buffrov. Zníženie\n" " rozlíšenia bufferu snímkov môže pomôcť.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "WARNING: %s: Buffere s nulami sú ZAKÁZANÉ lebo lebo kernel ovládač\n" " nepodporuje screen panning (používaný pre prepínanie snímkov).\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "VAROVANIE: %s: aktuálna hĺbka zobrazenia je %d. Pre lepší výkon\n" "je doporučená hĺbka 16 bit/bod!\n" "\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "" "výstupný xine video modul s použitím Linux kernelového frame buffer " "zariadenia" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "výstupný modul xine s použitím DirectFB knižnice." #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "výstupný xine video modul, ktorý nič nezobrazuje" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "výstupný xine video modul, ktorý používa OpenGL - TNG" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "" #: src/video_out/video_out_pgx64.c #, fuzzy, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "video_out_pgx64: Chyba: nedostatočná veľkosť video pamäte\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Varovanie: málo video pamäte, multi-buffering zakázaný\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Chyba: nedostatočná veľkosť video pamäte\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Varovanie: málo video pamäte, dvoj-buffering zakázaný\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "sdl musí emulovať 16 bitové povrchy, to všetko spomalí.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: plnoobrazovkový mód NIE JE podporovaný\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "výstupný xine video modul používajúci Simple Direct Media Layer" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "výstupný video modul použitím Libstk Surface Set-top Toolkit" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI colour conversion method" msgstr "Metóda konverzie priestoru farieb použitá Goom-om" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "výstupný modul xine s použitím DirectFB knižnice." #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "" #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: karta podporuje yuy2 formát\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: karta podporuje yv12 formát\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "video_out_vidix: Máte zlú verziu knižnice VIDIX\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "video_out_vidix: Nemôžem nájsť funkčný VIDIX ovládač\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: používam ovládač: %s od %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "výstupný video modul xine použitím libvidix pre x11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "výstupný video modul xine použitím libvidix pre linux frame buffer" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "VAROVANIE: aktuálna hĺbka zobrazenia je %d. Pre lepší výkon\n" "je doporučená hĺbka 16 bit/bod!\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "%s: rozšírenie zdielanej pamäte MIT neprítomné na obrazovke.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: Váš video mód nebol rozpoznaný, prepáčte.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "výstupný video xine modul použitím rozšírenia zdielanej pamäte MIT X" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: tento adaptér podporuje %s formát.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: Xv rozšírenie neprítomné.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: rozšírenie Xv je prítomné, ale nenašiel som použiteľný yuv12 port.\n" " Vyzerá to tak, že vaša grafická karta nepodoruje Xv?!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: používam Xv port %d z adaptéru %s pre hardvérovú konverziu farebného " "priestoru a škálovania.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "výstupný video xine modul použitím MIT X video rozšírenia" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: používam Xv port %ld z adaptéru %s pre hardvérovú konverziu farebného " "priestoru a škálovania.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: XvMC rozšírenie neprítomné.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: Xv rozšírenie je prítomné, ale nenašiel som použiteľný yuv12 " "port.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xvmc: používam Xv port %ld z adaptéru %s\n" " pre hardvérovú konverziu farebného priestoru a škálovania\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " idct a akcelerácia kompenzácie pohybu \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " iba akcelerácia kompenzácie pohybu\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " žiadna XvMC podpora \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " S Prekrývaním = %d; UnsignedIntra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "výstupný video xine modul použitím XvMC X video rozšírenia" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: XShape rozšírenie nedostupné. Prekrývanie bez zmien merítka " "zakázané.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: chyba vytvorenia okna. Prekrývanie bez zmien merítka zakázané.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: chyba vytvorenia mapy bodov. Prekrývanie bez zmien merítka " "zakázané.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "" #: src/video_out/xv_common.h #, fuzzy msgid "autopaint colour key" msgstr "Donútiť Xv automaticky kresliť svojou kľúčovou farbou" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Donútiť Xv automaticky kresliť svojou kľúčovou farbou" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "bilinearny škálovací mód (permedia 2/3)" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h msgid "Xv port number" msgstr "zlé číslo záznamu" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: žiaden modul nedostupný na spracovanie '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: chyba, neznámy typ bufferu: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "zápis na zvukovú kartu zlyhal. Bolo odpojené USB zariadenie ?\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "8 bitov nepodporované ovládačom, konvertujem na 16bitov.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "mono nepodporované ovládačom, konvertujem na stereo.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "stereo nepodporované ovládačom, konvertujem na mono.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "zvolte metódu synchronizácie audia a videa" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "ak !=0 vždy prevzorkovať na zvolenú frekv." #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "Hlasitosť" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "" #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "obnoviť úroveň hlasitosti pri štarte" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "ak toto nie je nastavené, xine sa nedotkne pri štarte nastavenia mixéru" #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "audio_out: prepáč, toto sa nemalo stať, prosím reštartuj xine.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "Aktuálny konfiguračný súbor bol modifikovaný novou verziou xine." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: VAROVANIE: vaša konfigurácia nebude uložená\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "configfile: VAROVANIE: zápis konfigurácie %s zlyhal\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "configfile: VAROVANIE: odstraňujem možno poškodený konf. súbor %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: VAROVANIE: mali by ste skontrolovať záložný súbor %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: položka '%s' nesmie byť modifikovaná z MRL\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "osd: nemôžem zistiť aktuálnu kódovú stánku\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" "info_helper: nepodporovaná konverzia %s -> UTF-8, nebude vykonaná žiadna\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": funkcia open() by nikdy nemala byť volaná\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": vstupný modul nedefinovaný!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: zlyhalo čítanie zapísaných dát: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: skok zlyhal: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: zlyhalo čítanie vo vstupnom module\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: chyba pri zápise do súboru % bytov: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: funkcia open() by nikdy nemala byť volaná\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: skok zlyhal\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % bytov zahodených\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: vstupný modul nedefinovaný!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: cieľový adresár nebol špecifikovaný, prosím vyplnte voľbu 'media." "capture.save_dir'\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "Schopnosť ukladania je zakázaná dovtedy kým nenastavíte media.capture." "save_dir v konfigurácii." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: ukladanie/kešovanie z tohto zdroja nedovolené!\n" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine nemá povolené ukladať z tohto zdroja. (možno autorsky chránenýmateriál?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: nezadané meno súboru!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: nemožno otvoriť súbor %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: neznámy typ modulu %d v %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: neznámy typ modulu %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: ignorujem modul %s, zlá verzia rozhrania %d (má byť %d)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: nájdený modul: %s:%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: preskakujem nečitateľný adresár modulov: %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: nemôžem naštartovať %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nemožno otvoriť knižnicu modulov %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: nemožno získať info modulu z %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nemožno (fáza 2) otvoriť knižnicu modulov %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Čo! %s neobsahuje informácie modulu.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: neznáma stratégia %d zisťovánia obsahu\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: nájdený demultiplexor '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: zlyhalo načítanie výstupného audio modulu <%s>\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" "load_plugins: auto-detekcia audio výstupu nenašla žiadne použiteľné audio " "ovládače.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: nemožno otvoriť knižnicu modulov %s:\n" "%s\n" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Buffering..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "zlá verzia fontu '%s'. očakávaná %d nájdená %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "font '%s-%d' už načítaný, divné.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "načítanie fontu '%s' zlyhalo (%d < %d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "osd: chyba načítania fontu %s s FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "osd: chyba načítania fontu %s s XDG\n" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: nemôžem inicializovať ft2 knižnicu\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "osd: chyba pri nastavení veľkosti fontu (neškálovateľný font?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: neznáma sekvencia začínajúca s bytom 0x%02X v kódovaní \"%s\", " "preskakujem\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: nemôžem zistiť aktuálnu kódovú stánku\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: nepodporovaná konverzia %s -> %s, nebude vykonaná žiadna\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: chyba zavedenia glyph\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: chyba pri vykreslovaní glyph\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: font nie je definovaný\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: chyba zavedenia glyph %i\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: chyba pri vykreslovaní\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "Paleta (popredie-okraj-pozadie) použitá na titulky" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: nedostupný modul na spracovanie '%s'\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: chyba, neznámy typ bufferu: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "doručených %d rámcov, preskočených %d rámcov, zahodených %d rámcov\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: zahadzuje sa obraz s pts %, pretože už je príliš starý " "(rozdiel: %).\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "video_out: prepáč, toto sa nemalo stať, reštartuj xine.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "horizontálna pozícia obrazu vo výstupnom okne" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "vertikálna pozícia obrazu vo výstupnom okne" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c #, fuzzy msgid "disable all video scaling" msgstr "vypnúť všetky zmeny merítka (rýchle!)" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: chyba pri spracovaní mrl\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: nájdený vstupný modul : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: vstupný modul nemôže otvoriť MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: nemožno nájsť vstupný modul pre MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: špecifikovaný demultiplexor %s nenaštartoval\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: pripojený rip vstupný modul\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: chyba otvorenia modulu vstupu rip\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: last_probed demultiplexor %s nenaštartoval\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "ignorujem video\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "ignorujem audio\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "ignorujem titulky\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "mrl titulkov otvorené '%s'\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: nemožno otvoriť mrl titulkov\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: zmeniť voľbu '%s' z MRL nie je dovolené\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "xine: nemožno nájsť demultiplexor %s pre >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: nemožno nájsť demultiplexor pre >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: nájdený modul demultiplexora %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: demultiplexor nenaštartoval\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: demultiplexor nedostupný\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: demultiplexor nenaštartoval\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "xine: Špecifikovaný save_dir \"%s\" môže byť bezpečnostným rizikom.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "Špecifikovaný save_dir môže byť bezpečnostným rizikom." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: locale nepodporované vašou C knižnicou\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "Stratégia detekcie formátu médii" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "Cesta pre ukladanie prúdov" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "dovoliť implicitné zmeny v konfigurácii (napr. cez MRL)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" "Ak je povolené, dovolíte xine zmentiť konfiguráciu bez explicitných akcii z " "vašej strany. Napríklad konfiguračné zmeny požadované z MRL alebo vložené do " "playlistu budú vykonané.\n" "Toto nastavenie je kritické z hľadiska bezpečnosti, lebo xine môže dostať " "MRL alebo playlisty z nedôverihodných vzdialených zdrojov. Ak im dovolíte " "ľubovoľne meniť vašu konfiguráciu, môžete skončiť s úplne rozhodeným xine." #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "správy" #: src/xine-engine/xine.c msgid "plugin" msgstr "modul" #: src/xine-engine/xine.c msgid "trace" msgstr "trace" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Obnovujem index..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Testovanie výkonnosti memcpy metód (menej je lepšie):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "configfile: VAROVANIE: záloha konf.súboru do %s zlyhala\n" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: zlé mrl: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: chyba pri čítaní (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: nemožno zistiť adresu '%s'.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: nemožno sa pripojiť k '%s'.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "stdin: nemôžem skočiť späť! (% > %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: chyba pri spracovaní MRL\n" #~ msgid "The above message had unknown vcdimager log level" #~ msgstr "Vyššie uvedená správa má neznámu log. úroveň vcdimageru" xine-lib-1.2/po/LINGUAS0000644000175000017500000000010314647725152012321 0ustar memecs de # en_GB not needed en_US eo es eu fr it ja nl pl pt_BR sk tr xine-lib-1.2/po/Makevars0000644000175000017500000000517114647725152013002 0ustar meme# Makefile variables for PO directory in any package using GNU gettext. include Makevars.extra DISTFILES += Makevars.extra.in # Usually the message domain is the same as the package name. DOMAIN = $(LIBNAME) # These two variables depend on the location of this directory. subdir = po top_builddir = .. # Internal usage XGETTEXT_FORMAT_FLAGS_PRIVATE = \ --flag=xine_log_msg:1:c-format \ --flag=xine_log_err:1:c-format \ --flag=xprintf:3:c-format \ --flag=xine_printf:3:c-format \ --flag=set_hc_result:3:c-format \ --flag=log_printf:1:c-format \ --flag=error_message:1:c-format \ --flag=error_callback:5:c-format \ --flag=dbgprintf:1:c-format \ --flag=dbg_printf:1:c-format \ --flag=sock_string_write:3:c-format \ --flag=broadcaster_string_write:3:c-format \ --flag=scratch_printf:3:c-format # External usage (installed include files) XGETTEXT_FORMAT_FLAGS = \ --flag=xine_log:3:c-format \ --flag=xine_vlog:3:c-format # These options get passed to xgettext. XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ --from-code=UTF-8 \ --add-location=file \ $(XGETTEXT_FORMAT_FLAGS_PRIVATE) \ $(XGETTEXT_FORMAT_FLAGS) # This is the copyright holder that gets inserted into the header of the # $(DOMAIN).pot file. Set this to the copyright holder of the surrounding # package. (Note that the msgstr strings, extracted from the package's # sources, belong to the copyright holder of the package.) Translators are # expected to transfer the copyright for their translations to this person # or entity, or to disclaim their copyright. The empty string stands for # the public domain; in this case the translators are expected to disclaim # their copyright. COPYRIGHT_HOLDER = Copyright (C) 2000-2022 the xine project # This is the email address or URL to which the translators shall report # bugs in the untranslated strings: # - Strings which are not entire sentences, see the maintainer guidelines # in the GNU gettext documentation, section 'Preparing Strings'. # - Strings which use unclear terms or require additional context to be # understood. # - Strings which make invalid assumptions about notation of date, time or # money. # - Pluralisation problems. # - Incorrect English spelling. # - Incorrect formatting. # It can be your email address, or a mailing list address where translators # can write to without being subscribed, or the URL of a web page through # which the translators can contact you. MSGID_BUGS_ADDRESS = xine-devel@lists.sourceforge.net # This is the list of locale categories, beyond LC_MESSAGES, for which the # message catalogs shall be used. It is usually empty. EXTRA_LOCALE_CATEGORIES = debug: install-debug: xine-lib-1.2/po/eo.po0000644000175000017500000061016614647725152012257 0ustar meme# translation of eo.po to ESPERANTO # # Libxine - ESPERANTO LANGUAGE SUPPORT. # Copyright (C) 2000-2007 the xine project # This file is distributed under the same license as the xine-lib package. # # Esperanto special letters: ĉŝĝĥĵŭ # Antonio C. Codazzi "La Filozofo" , 2007. # # msgid "" msgstr "" "Project-Id-Version: eo\n" "Report-Msgid-Bugs-To: xine-devel@lists.sourceforge.net\n" "POT-Creation-Date: 2023-07-06 13:04+0200\n" "PO-Revision-Date: 2007-05-24 17:57+0200\n" "Last-Translator: Antonio C. Codazzi \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "X-Generator: KBabel 1.0.2\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: lib/hstrerror.c msgid "No error" msgstr "Neniu eraro" #: lib/hstrerror.c msgid "Unknown host" msgstr "Nekonata gastiga komputilo" #: lib/hstrerror.c msgid "No address associated with name" msgstr "Neniu adreso estas kuna al nomo" #: lib/hstrerror.c msgid "Unknown server error" msgstr "Nekonata eraro de servilo" #: lib/hstrerror.c msgid "Host name lookup failure" msgstr "Eraro dun serĉado de gastiga komputilo" #: lib/hstrerror.c msgid "Unknown error" msgstr "Nekonata eraro" #: src/audio_dec/ff_dvaudio_decoder.c #, c-format msgid "dvaudio: increasing buffer to %d to avoid overflow.\n" msgstr "dvaudio: agordo de bufro je %d por eviti troon.\n" #: src/audio_dec/ff_dvaudio_decoder.c msgid "dv audio decoder plugin" msgstr "" #: src/audio_dec/gsm610.c #, fuzzy msgid "GSM 6.10 audio decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/audio_dec/xine_a52_decoder.c src/audio_dec/xine_dts_decoder.c #, c-format msgid "HELP! a mono-only audio driver?!\n" msgstr "HELPO! Ĉu nur unufonia aŭdozorgilo?!\n" #: src/audio_dec/xine_a52_decoder.c msgid "liba52 based a52 audio decoder plugin" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 volume" msgstr "A/52 laŭteco" #: src/audio_dec/xine_a52_decoder.c msgid "" "With A/52 audio, you can modify the volume at the decoder level. This has " "the advantage of the audio being already decoded for the specified volume, " "so later operations like channel downmixing will work on an audio stream of " "the given volume." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "use A/52 dynamic range compression" msgstr "uzu A/52 dinamikan kunpremon" #: src/audio_dec/xine_a52_decoder.c msgid "" "Dynamic range compression limits the dynamic range of the audio. This means " "making the loud sounds softer, and the soft sounds louder, so you can more " "easily listen to the audio in a noisy environment without disturbing anyone." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "downmix audio to 2 channel surround stereo" msgstr "downmix aŭdo kun 2 (surround) stereaj kanaloj" #: src/audio_dec/xine_a52_decoder.c msgid "" "When you want to listen to multichannel surround sound, but you have only " "two speakers or a surround decoder or amplifier which does some sort of " "matrix surround decoding like prologic, you should enable this option so " "that the additional channels are mixed into the stereo signal." msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "A/52 bass downmix volume" msgstr "" #: src/audio_dec/xine_a52_decoder.c msgid "" "Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer." msgstr "" #: src/audio_dec/xine_dts_decoder.c msgid "DTS passthru audio format decoder plugin" msgstr "" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecOpen() failed.\n" msgstr "libfaad: libfaad NeAACDecOpen() malsukcesis.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit2 failed.\n" msgstr "libfaad: libfaad NeAACDecInit2 malsukcesis.\n" #: src/audio_dec/xine_faad_decoder.c #, c-format msgid "libfaad: libfaad NeAACDecInit failed.\n" msgstr "libfaad: libfaad NeAACDecInit malsukcesis.\n" #: src/audio_dec/xine_faad_decoder.c msgid "Freeware Advanced Audio Decoder" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "FAAD audio gain (dB)" msgstr "" #: src/audio_dec/xine_faad_decoder.c msgid "" "Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/audio_dec/xine_lpcm_decoder.c #, fuzzy msgid "Linear PCM audio decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/audio_dec/xine_mad_decoder.c msgid "libmad based mpeg audio layer 1/2/3 decoder plugin" msgstr "" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_demux_init failed.\n" msgstr "libmusepack: mpc_demux_initialise malsukcesis\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_streaminfo_read failed: %d\n" msgstr "libmusepack: mpc_streaminfo_read malsukcesis: %d\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: data after last frame ignored\n" msgstr "libmusepack: datumoj post lasta filmero estis ignorataj\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_initialise failed\n" msgstr "libmusepack: mpc_decoder_initialise malsukcesis\n" #: src/audio_dec/xine_musepack_decoder.c #, c-format msgid "libmusepack: mpc_decoder_decode failed: %d\n" msgstr "libmusepack: mpc_decoder_decode malsukcesis: %d\n" #: src/audio_dec/xine_musepack_decoder.c msgid "mpc: musepack audio decoder plugin" msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out:Already open...WHY!" msgstr "audio_alsa_out: jam malfermita... KIAL?" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: snd_pcm_open() of %s failed: %s\n" msgstr "audio_alsa_out: snd_pcm_open() de %s malsukcesis: %s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "audio_alsa_out: >>> check if another program already uses PCM <<<\n" msgstr "audio_alsa_out: >>> kontrolu se alia programo estas uzanta PCM <<<\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid "" "audio_alsa_out: broken configuration for this PCM: no configurations " "available: %s\n" msgstr "" "audio_alsa_out: difektita agordaĵo de tiu ĉi PCM: neniu disponebla agordaĵo: " "%s\n" #: src/audio_out/audio_alsa_out.c msgid "notify changes to the hardware mixer" msgstr "rimarku ŝanĝojn de hardwara miksilo" #: src/audio_out/audio_alsa_out.c msgid "" "When the hardware mixer changes, your application will receive a " "notification so that it can update its graphical representation of the mixer " "settings on the fly." msgstr "" #: src/audio_out/audio_alsa_out.c msgid "audio_alsa_out : supported modes are" msgstr "audio_alsa_out : subtenitaj modusoj estas" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (4-channel not enabled in xine config)" msgstr " (kvarfonio ne estas ebligita en xine-agordoj)" #: src/audio_out/audio_alsa_out.c msgid " 4.1-channel" msgstr " 4.1-kanalo" #: src/audio_out/audio_alsa_out.c msgid " (4.1-channel not enabled in xine config)" msgstr " (4.1-kanaloj ne estas ebligita en xine-agordoj)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5-channel" msgstr " kvinfonio" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5-channel not enabled in xine config)" msgstr " (kvinfonio ne estas ebligita en xine-agordoj)" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " (5.1-channel not enabled in xine config)" msgstr " (5.1-kanaloj ne estas ebligita en xine-agordoj)" #: src/audio_out/audio_alsa_out.c msgid " (a/52 and DTS pass-through not enabled in xine config)" msgstr " (rektotrajro de a/52 kaj DTS ne estas ebligita en xine-agordoj)" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_pcm_open() failed:%d:%s\n" msgstr "snd_pcm_open() malsukcesis:%d:%s\n" #: src/audio_out/audio_alsa_out.c #, c-format msgid ">>> Check if another program already uses PCM <<<\n" msgstr ">>> Kontrolu se alia programo estas uzanta PCM <<<\n" #: src/audio_out/audio_alsa_out.c msgid " 8bit" msgstr " 8bitoj" #: src/audio_out/audio_alsa_out.c msgid " 16bit" msgstr " 16bitoj" #: src/audio_out/audio_alsa_out.c msgid " 24bit" msgstr " 24bitoj" #: src/audio_out/audio_alsa_out.c msgid " 32bit" msgstr " 32bitoj" #: src/audio_out/audio_alsa_out.c msgid "sound card can do mmap" msgstr "sonkarto ne povas uzi mmap" #: src/audio_out/audio_alsa_out.c msgid "" "Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " mono" msgstr " unufonio" #: src/audio_out/audio_alsa_out.c msgid "device used for mono output" msgstr "aparato uzita por unufonia eligo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " stereo" msgstr " stereofonio" #: src/audio_out/audio_alsa_out.c msgid "device used for stereo output" msgstr "aparato uzita por stereofonia eligo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 4-channel" msgstr " kvarfonio" #: src/audio_out/audio_alsa_out.c msgid "device used for 4-channel output" msgstr "aparato uzita por kvarfonia eligo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c src/audio_out/audio_oss_out.c msgid " 5.1-channel" msgstr " 5.1-kanalo" #: src/audio_out/audio_alsa_out.c msgid "device used for 5.1-channel output" msgstr "aparato uzita por 5.1-kanala eligo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output 5 channel plus LFE (5.1) surround " "sound.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c msgid " a/52 and DTS pass-through" msgstr " rektotrajro de a/52 kaj DTS" #: src/audio_out/audio_alsa_out.c #, fuzzy msgid "device used for a/52 and DTS pass-through" msgstr " rektotrajro de a/52 kaj DTS" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices." msgstr "" #: src/audio_out/audio_alsa_out.c #, c-format msgid "snd_lib_error_set_handler() failed: %d" msgstr "snd_lib_error_set_handler() malsukcesis: %d" #: src/audio_out/audio_alsa_out.c msgid "alsa mixer device" msgstr "alsa-miksilo" #: src/audio_out/audio_alsa_out.c msgid "" "xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices." msgstr "" "xine uzos tiun ĉi alsa-miksilon por ŝanĝi laŭtecon.\n" "Legu dokumentaron de alsa por havi informojn pri aparatoj de alsa." #: src/audio_out/audio_alsa_out.c msgid "xine audio output plugin using alsa-compliant audio devices/drivers" msgstr "aŭdeliga xine-kromaĵo uzanta alsa-favorajn aŭdajn aparatojn/zorgilojn" #: src/audio_out/audio_coreaudio_out.c msgid "xine output plugin for Coreaudio/Mac OS X" msgstr "kromaĵo de aŭdeligo por Coreaudio/Mac OS X" #: src/audio_out/audio_directx2_out.c msgid "Error" msgstr "Eraro" #: src/audio_out/audio_directx2_out.c msgid "success" msgstr "sukceso" #: src/audio_out/audio_directx2_out.c msgid "access denied" msgstr "aliro rifuzita" #: src/audio_out/audio_directx2_out.c msgid "resource is already in use" msgstr "risurco estas nune uzata" #: src/audio_out/audio_directx2_out.c msgid "object was already initialized" msgstr "objekto estis jam pravalorizita" #: src/audio_out/audio_directx2_out.c msgid "specified wave format is not supported" msgstr "la specifita ondoformato ne estas subtenita" #: src/audio_out/audio_directx2_out.c msgid "memory buffer has been lost and must be restored" msgstr "memorbufro estis perdita kaj ĝi estas restarigenda" #: src/audio_out/audio_directx2_out.c msgid "requested buffer control is not available" msgstr "mendita bufradministrilo ne estas disponebla" #: src/audio_out/audio_directx2_out.c msgid "undetermined error inside DirectSound subsystem" msgstr "nedifinita eraro en subsistemo de DirectSound" #: src/audio_out/audio_directx2_out.c msgid "DirectSound hardware device is unavailable" msgstr "DirectSound hardvaparato estas nedisponebla" #: src/audio_out/audio_directx2_out.c msgid "function is not valid for the current state of the object" msgstr "funkcio estas nevalida laŭ nuna stato de objekto" #: src/audio_out/audio_directx2_out.c msgid "invalid parameter was passed" msgstr "havigitaj parametroj estas nevalidaj" #: src/audio_out/audio_directx2_out.c msgid "object doesn't support aggregation" msgstr "la objekto ne subtenas agragadon" #: src/audio_out/audio_directx2_out.c msgid "no sound driver available for use" msgstr "neniu sonzorgilo estas disponebla por uzo" #: src/audio_out/audio_directx2_out.c msgid "requested COM interface not available" msgstr "mendita COM interfaco ne estas disponebla" #: src/audio_out/audio_directx2_out.c msgid "another application has a higher priority level" msgstr "alia programo havas pli altan gradon de prioritato" #: src/audio_out/audio_directx2_out.c msgid "insufficient memory" msgstr "nesufiĉa memoro" #: src/audio_out/audio_directx2_out.c msgid "low priority level for this function" msgstr "malalta grado de prioritato por tiu ĉi funkcio" #: src/audio_out/audio_directx2_out.c msgid "DirectSound wasn't initialized" msgstr "DirectSound ne estis pravalorizita" #: src/audio_out/audio_directx2_out.c msgid "function is not supported" msgstr "funkcio ne estas subtenita" #: src/audio_out/audio_directx2_out.c msgid "unknown error" msgstr "nekonata eraro" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create direct sound object." msgstr "Mi estas nekapabla krei objekton de directsound" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Could not set direct sound cooperative level." msgstr "Estas neeble agordi gradon de kunagado por directsound" #: src/audio_out/audio_directx2_out.c msgid "Unable to create secondary direct sound buffer" msgstr "Mi estas nekapabla krei duan bufron de directsound" #: src/audio_out/audio_directx2_out.c msgid "Couldn't play sound buffer" msgstr "Estas neeble ludi aŭdobufron" #: src/audio_out/audio_directx2_out.c msgid "Couldn't stop sound buffer" msgstr "Estas neeble fermi aŭdobufron" #: src/audio_out/audio_directx2_out.c msgid "Can't get buffer position" msgstr "Estas neeble determini lokon de bufro" #: src/audio_out/audio_directx2_out.c msgid "Can't set buffer position" msgstr "Estas neeble agordi lokadon de bufro" #: src/audio_out/audio_directx2_out.c msgid "Can't set sound volume" msgstr "Estas neeble agordi laŭtecon" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": buffer lost, trying to restore\n" msgstr ": perdita bufro, mi provas restarigi ĝin\n" #: src/audio_out/audio_directx2_out.c msgid "Couldn't lock direct sound buffer" msgstr "Estas neeble bloki bufron de directsound" #: src/audio_out/audio_directx2_out.c msgid "Couldn't unlock direct sound buffer" msgstr "Estas neeble malbloki bufron de directsound" #: src/audio_out/audio_directx2_out.c #, c-format msgid "Unable to create primary direct sound buffer." msgstr "Mi estas nekapabla krei ĉefan bufro de directsound" #: src/audio_out/audio_directx2_out.c #, fuzzy, c-format msgid ": play cursor overran (data %zu, min %zu), flushing buffers\n" msgstr "" ": indikilo de legado translimiĝis (data %u, min %u), do mi elbufriĝas\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create buffer pthread: %s\n" msgstr ": estas neeble krei bufron de pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy buffer pthread: %s\n" msgstr ": estas neeble detrui bufron de pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread condition: %s\n" msgstr ": estas neeble detrui kondiĉon de pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't destroy pthread mutex: %s\n" msgstr ": estas neeble detrui pthread mutex: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": unknown control command %d\n" msgstr ": nekonata komando de regado %d\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread condition: %s\n" msgstr ": estas neeble krei kondiĉon de pthread: %s\n" #: src/audio_out/audio_directx2_out.c #, c-format msgid ": can't create pthread mutex: %s\n" msgstr ": estas neeble krei pthread mutex: %s\n" #: src/audio_out/audio_directx2_out.c msgid "second xine audio output plugin using directx" msgstr "dua direcx-uzanta kromaĵo de aŭdeligo de xine" #: src/audio_out/audio_directx_out.c msgid "xine audio output plugin for win32 using directx" msgstr "direcx-uzanta kromaĵo de aŭdeligo de xine por win32" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to ESD server %s: %s\n" msgstr "audio_esd_out: konektante ESD servilon %s: %s\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: connecting to esd server...\n" msgstr "audio_esd_out: konektante ESD servilon...\n" #: src/audio_out/audio_esd_out.c #, c-format msgid "audio_esd_out: can't connect to %s ESD server: %s\n" msgstr "audio_esd_out: estas neeble konekti %s ESD servilon: %s\n" #: src/audio_out/audio_esd_out.c msgid "esd audio output latency (adjust a/v sync)" msgstr "latento de eligo por esd-aŭdo (aranĝo a/v sink)" #: src/audio_out/audio_esd_out.c src/audio_out/audio_oss_out.c msgid "" "If you experience audio being not in sync with the video, you can enter a " "fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/audio_out/audio_esd_out.c msgid "xine audio output plugin using esound" msgstr "aŭdeliga xine-kromaĵo uzanta esound" #: src/audio_out/audio_file_out.c msgid "xine file audio output plugin" msgstr "kromaĵo de aŭdeligo por xine dosiero" #: src/audio_out/audio_fusionsound_out.c #, fuzzy msgid "xine FusionSound audio output plugin" msgstr "kromaĵo de aŭdeligo por xine dosiero" #: src/audio_out/audio_irixal_out.c msgid "irixal audio output maximum gap length" msgstr "maksimuma longo de ekarto por aŭdeliga kromaĵo irixal" #: src/audio_out/audio_irixal_out.c msgid "" "You can specify the maximum offset between audio and video xine will " "tolerate before trying to resync them.\n" "The unit of this value is one PTS tick, which is the 90000th part of a " "second." msgstr "" #: src/audio_out/audio_irixal_out.c msgid "xine audio output plugin using IRIX libaudio" msgstr "aŭdeliga xine-kromaĵo uzanta libaudio-n IRIX" #: src/audio_out/audio_jack_out.c msgid "JACK audio device name" msgstr "" #: src/audio_out/audio_jack_out.c msgid "" "Specifies the jack audio device name, leave blank for the default physical " "output port." msgstr "" #: src/audio_out/audio_jack_out.c msgid "xine output plugin for JACK Audio Connection Kit" msgstr "" #: src/audio_out/audio_none_out.c msgid "xine dummy audio output plugin" msgstr "testanta kromaĵo de aŭdeligo de xine" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Opening audio device %s: %s\n" msgstr "audio_oss_out: Malfermante aŭdaparaton %s: %s\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n" msgstr "" "audio_oss_out: averto: samplado de %d Hz ne estas subtenita, provu 44100 Hz\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio rate : %d requested, %d provided by device\n" msgstr "" "audio_oss_out: aŭdokvanto : %d estas mendita, %d estas havigita far aparato\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio device name" msgstr "Nomo de OSS aŭdaparato" #: src/audio_out/audio_oss_out.c msgid "" "Specifies the base part of the audio device name, to which the OSS device " "number is appended to get the full device name.\n" "Select \"auto\" if you want xine to auto detect the correct setting." msgstr "" #: src/audio_out/audio_oss_out.c msgid "OSS audio device number, -1 for none" msgstr "Numero de OSS aŭdaparato, -1 por nenio" #: src/audio_out/audio_oss_out.c msgid "" "The full audio device name is created by concatenating the OSS device name " "and the audio device number.\n" "If you do not need a number because you are happy with your system's default " "audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" msgstr "audio_oss_out: audio.device.oss_device_name = auto, probing devs\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: Auto probe for audio device failed\n" msgstr "audio_oss_out: Memrekono de aŭdaparato malsukcesis\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: using device >%s<\n" msgstr "audio_oss_out: uzante aparaton >%s<\n" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: opening audio device %s failed:\n" "%s\n" msgstr "" "audio_oss_out: malfermo de aŭdaparato %s malsukcesis:\n" "%s\n" #: src/audio_out/audio_oss_out.c msgid "a/v sync method to use by OSS" msgstr "a/v sinkronmetodo uzenda de OSS" #: src/audio_out/audio_oss_out.c msgid "" "xine can use different methods to keep audio and video synchronized. Which " "setting works best depends on the OSS driver and sound hardware you are " "using. Try the various methods, if you experience sync problems.\n" "\n" "The meaning of the values is as follows:\n" "\n" "auto\n" "xine attempts to automatically detect the optimal setting\n" "\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v sync even if the " "driver claims not to support realtime playback\n" "\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v sync even if the " "driver supports the preferred SNDCTL_DSP_GETODELAY ioctl\n" "\n" "softsync\n" "uses software synchronization with the system clock; audio and video can get " "severely out of sync if the system clock speed does not precisely match your " "sound card's playback speed\n" "\n" "probebuffer\n" "probes the sound card buffer size on initialization to calculate the latency " "for a/v sync; try this if your system does not support any of the realtime " "ioctls and you experience sync errors after long playback" msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Aŭdozorgilo por realtempa sinkronigo estas malebligita...\n" "audio_oss_out: ...do oni uzos realtempan sistemon kun horloĝo por milda-" "sink\n" "audio_oss_out: ...ĝi povus esti temo de aŭda/videa sinkronigo\n" #: src/audio_out/audio_oss_out.c msgid "OSS audio output latency (adjust a/v sync)" msgstr "latenco de OSS aŭdeligo (aranĝo de a/v sinkro)" #: src/audio_out/audio_oss_out.c #, c-format msgid "" "audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\n" "audio_oss_out: ...there may be audio/video synchronization issues\n" msgstr "" "audio_oss_out: Aŭdozorgilo por realtempa sinkronigo estas malebligita...\n" "audio_oss_out: ...sondante grandon de eliga bufro: %d bajtoj\n" "audio_oss_out: ...eble ĝi estas problemo de aŭdo/video sinkronigo\n" #: src/audio_out/audio_oss_out.c msgid "audio_oss_out: supported modes are" msgstr "audio_oss_out: subtenitaj modusoj estas" #: src/audio_out/audio_oss_out.c msgid " a/52 pass-through" msgstr " rektotrajro de a/52" #: src/audio_out/audio_oss_out.c msgid " (a/52 pass-through not enabled in xine config)" msgstr " (rektotrajro de a/52 ne estas ebligita en xine-agordoj)" #: src/audio_out/audio_oss_out.c msgid "OSS audio mixer number, -1 for none" msgstr "numero de OSS aŭdomiksilo, -1 por nenio" #: src/audio_out/audio_oss_out.c msgid "" "The full mixer device name is created by taking the OSS device name, " "replacing \"dsp\" with \"mixer\" and adding the mixer number.\n" "If you do not need a number because you are happy with your system's default " "mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is ignored, when the OSS " "audio device name is set to \"auto\"." msgstr "" #: src/audio_out/audio_oss_out.c #, c-format msgid "audio_oss_out: open() mixer %s failed: %s\n" msgstr "audio_oss_out: open() de miksilo %s malsukcesis: %s\n" #: src/audio_out/audio_oss_out.c msgid "xine audio output plugin using oss-compliant audio devices/drivers" msgstr "" "kromaĵo de xine-aŭdligo kiu uzas aŭdajn aparatojn/zorgiloj oss-favorajn" #: src/audio_out/audio_pulse_out.c msgid "device used for pulseaudio" msgstr "aparato uzata por pulsa aŭdo" #: src/audio_out/audio_pulse_out.c msgid "use 'server[:sink]' for setting the pulseaudio sink device." msgstr "uzu 'server[:sink]' por agordi aparato de pulsa aŭdo." #: src/audio_out/audio_pulse_out.c msgid "use A/52 pass through" msgstr " rektotrajro de a/52" #: src/audio_out/audio_pulse_out.c msgid "" "Enable this, if your want to use digital audio pass through with " "pulseaudio.\n" "You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/audio_out/audio_pulse_out.c msgid "xine audio output plugin using pulseaudio sound server" msgstr "aŭdeliga xine-kromaĵo uzanta sonservilon de pulseaudio" #: src/audio_out/audio_sndio_out.c #, fuzzy msgid "xine audio output plugin using sndio audio devices/drivers " msgstr "" "kromaĵo de xine-aŭdligo kiu uzas aŭdajn aparatojn/zorgiloj SUN-favorajn" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: opening audio device %s failed: %s\n" msgstr "audio_sun_out: malfermo de aŭdaparato %s malsukcesis: %s\n" #: src/audio_out/audio_sun_out.c msgid "Sun audio device name" msgstr "nomo de Sun aŭdaparato" #: src/audio_out/audio_sun_out.c msgid "" "Specifies the file name for the Sun audio device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper Sun audio device." msgstr "" #: src/audio_out/audio_sun_out.c #, c-format msgid "audio_sun_out: audio ioctl on device %s failed: %s\n" msgstr "audio_sun_out: aŭda ioctl super aparato %s malsukcesis: %s\n" #: src/audio_out/audio_sun_out.c msgid "xine audio output plugin using sun-compliant audio devices/drivers" msgstr "" "kromaĵo de xine-aŭdligo kiu uzas aŭdajn aparatojn/zorgiloj SUN-favorajn" #: src/audio_out/speakers.h msgid "speaker arrangement" msgstr "aranĝo de laŭtigilo" #: src/audio_out/speakers.h msgid "" "Select how your speakers are arranged, this determines which speakers xine " "uses for sound output. The individual values are:\n" "\n" "Mono 1.0: You have only one speaker.\n" "Stereo 2.0: You have two speakers for left and right channel.\n" "Headphones 2.0: You use headphones.\n" "Stereo 2.1: You have two speakers for left and right channel, and one " "subwoofer for the low frequencies.\n" "Surround 3.0: You have three speakers for left, right and rear channel.\n" "Surround 4.0: You have four speakers for front left and right and rear left " "and right channels.\n" "Surround 4.1: You have four speakers for front left and right and rear left " "and right channels, and one subwoofer for the low frequencies.\n" "Surround 5.0: You have five speakers for front left, center and right and " "rear left and right channels.\n" "Surround 5.1: You have five speakers for front left, center and right and " "rear left and right channels, and one subwoofer for the low frequencies.\n" "Surround 6.0: You have six speakers for front left, center and right and " "rear left, center and right channels.\n" "Surround 6.1: You have six speakers for front left, center and right and " "rear left, center and right channels, and one subwoofer for the low " "frequencies.\n" "Surround 7.1: You have seven speakers for front left, center and right, left " "and right and rear left and right channels, and one subwoofer for the low " "frequencies.\n" "Pass Through: Your sound system will receive undecoded digital sound from " "xine. You need to connect a digital surround decoder capable of decoding the " "formats you want to play to your sound card's digital output." msgstr "" #: src/combined/ffmpeg/demux_avformat.c #, fuzzy msgid "libavformat input plugin" msgstr "eniga kromaĵo de dosiero" #: src/combined/ffmpeg/demux_avformat.c msgid "libavformat demux plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_audio_dec: agordo de bufro je %d por eviti troon.\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_audio_dec: estas neeble trovi malkodilo de ffmpeg por bufrospeco 0x%" "X\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: trying to open null codec\n" msgstr "ffmpeg_audio_dec: mi provas malfermi nulan kodaĵon\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: couldn't open decoder\n" msgstr "ffmpeg_audio_dec: estas neeble malfermi malkodilon\n" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: codec parameters changed\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c #, c-format msgid "ffmpeg_audio_dec: cannot read codec parameters from packet\n" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "ffmpeg based audio decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "FFmpeg audio gain (dB)" msgstr "" #: src/combined/ffmpeg/ff_audio_decoder.c msgid "" "Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n" msgstr "" "ffmpeg_video_dec: nesubtenitaj dimensioj de bildero, DR1 estas malebligita.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n" msgstr "" "ffmpeg_video_dec: nesubtenita formato de bildero, DR1 estas malebligita.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: direct rendering enabled\n" msgstr "ffmpeg_video_dec: ebligita rekta bildigo\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: no suitable format for HW decoding\n" msgstr "" "ffmpeg_video_dec: nesubtenita formato de bildero, DR1 estas malebligita.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder\n" msgstr "ffmpeg_video_dec: estas neeble malfermi malkodilon\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't open decoder (pass 2)\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n" msgstr "ffmpeg_video_dec: agordo de bufro je %d por eviti troon.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, fuzzy, c-format msgid "ffmpeg_video_dec: used %d DR1 frames.\n" msgstr "" "ffmpeg_video_dec: nesubtenita formato de bildero, DR1 estas malebligita.\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n" msgstr "" "ffmpeg_video_dec: estas neeble trovi malkodilo de ffmpeg por bufrospeco 0x%" "X\n" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: vaapi_mpeg_softdec %d\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled in config.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #, c-format msgid "ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "ffmpeg based video decoder plugin" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "MPEG-4 postprocessing quality" msgstr "kvalito de MPEG-4 postprocesado" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, too " "heavy post processing can actually make the image worse by blurring it too " "much." msgstr "" "Vi povas aranĝi kvanton de postprocezado aplikita al MPEG-4 video.\n" "Pli alta valoro atingas pli bonan kvaliton, sed ĝi nacesas pli CPU. Malaltaj " "valoroj povas krei difektojn kiel blokartefaktojn. Ankaŭ se la enhavo estas " "altkvalita, grava postprocezado povas igi bildon pli aĉa ĉar ĝi estas tro " "malfokusita." #: src/combined/ffmpeg/ff_video_decoder.c msgid "FFmpeg video decoding thread count" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Skip loop filter" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Choose speed over specification compliance" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable direct rendering" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "" "Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "VAAPI Mpeg2 softdecoding" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "If the machine freezes on mpeg2 decoding use mpeg2 software decoding." msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "Enable VAAPI" msgstr "" #: src/combined/ffmpeg/ff_video_decoder.c msgid "Enable or disable usage of vaapi" msgstr "" #: src/combined/ffmpeg/input_avio.c #, fuzzy msgid "libavio input plugin" msgstr "v4l eniga kromaĵo por radio" #: src/combined/flac_decoder.c #, fuzzy msgid "flac audio decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/combined/flac_demuxer.c msgid "FLAC demux plugin" msgstr "" #: src/combined/nsf_decoder.c #, fuzzy msgid "NES Music audio decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/combined/nsf_demuxer.c msgid "NES Music file demux plugin" msgstr "" #: src/combined/wavpack_decoder.c #, fuzzy msgid "wavpack audio decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/combined/wavpack_demuxer.c msgid "Wavpack demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c #, c-format msgid "ogg: vorbis audio track indicated but no vorbis stream header found.\n" msgstr "" "ogg: vorbis-aŭdotrako estas indikita sed nenio ĉapo de vorbis-datumstrio " "estis trovita.\n" #: src/combined/xine_ogg_demuxer.c msgid "Annodex demux plugin" msgstr "" #: src/combined/xine_ogg_demuxer.c msgid "OGG demux plugin" msgstr "" #: src/combined/xine_speex_decoder.c #, fuzzy msgid "Speex audio decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/combined/xine_theora_decoder.c #, fuzzy msgid "theora video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/combined/xine_vorbis_decoder.c #, c-format msgid "vorbis: increasing buffer to %d to avoid overflow.\n" msgstr "vorbis: agordo de bufro je %d por eviti troon.\n" #: src/combined/xine_vorbis_decoder.c msgid "vorbis audio decoder plugin" msgstr "" #: src/demuxers/demux_4xm.c msgid "4X Technologies (4xm) demux plugin" msgstr "" #: src/demuxers/demux_aac.c msgid "ADIF/ADTS AAC demux plugin" msgstr "" #: src/demuxers/demux_ac3.c msgid "Raw AC3 demux plugin" msgstr "" #: src/demuxers/demux_aiff.c #, fuzzy msgid "AIFF file demux plugin" msgstr "eniga kromaĵo de dosiero" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: A stream appears to be missing.\n" msgstr "" #: src/demuxers/demux_asf.c msgid "Media stream missing?" msgstr "" #: src/demuxers/demux_asf.c #, c-format msgid "demux_asf: warning: The stream id=%d is encrypted.\n" msgstr "demux_asf: averto: datumstrio id=%d estas cifrata.\n" #: src/demuxers/demux_asf.c msgid "Media stream scrambled/encrypted" msgstr "Plurmedia datumstrio estas cifrata" #: src/demuxers/demux_asf.c msgid "ASF demux plugin" msgstr "" #: src/demuxers/demux_aud.c msgid "Westwood Studios AUD file demux plugin" msgstr "" #: src/demuxers/demux_avi.c msgid "Restoring index..." msgstr "Restarigo de indekso..." #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %\n" msgstr "demux_avi: nevalida avi-parto \"%c%c%c%c\" en loko %\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: avi index is broken\n" msgstr "demux_avi: avi-indekso estas difektita\n" #: src/demuxers/demux_avi.c #, c-format msgid "demux_avi: failed to seek to the next chunk (pos %)\n" msgstr "demux_avi: relokado al sekva parto malsukcesis (pos %)\n" #: src/demuxers/demux_avi.c msgid "AVI/RIFF demux plugin" msgstr "" #: src/demuxers/demux_cdda.c #, fuzzy msgid "CD Digital Audio demux plugin" msgstr "eniga kromaĵo por DVB (Diĝita TV)" #: src/demuxers/demux_dts.c msgid "Raw DTS demux plugin" msgstr "" #: src/demuxers/demux_eawve.c msgid "Electronics Arts WVE format demux plugin" msgstr "" #: src/demuxers/demux_elem.c msgid "Elementary MPEG stream demux plugin" msgstr "" #: src/demuxers/demux_film.c #, c-format msgid "invalid FILM chunk size\n" msgstr "nevalida grando por peco de FILMo\n" #: src/demuxers/demux_film.c #, c-format msgid "unrecognized FILM chunk\n" msgstr "nerekonata peco de FILMo\n" #: src/demuxers/demux_film.c msgid "FILM (CPK) demux plugin" msgstr "" #: src/demuxers/demux_flac.c msgid "Free Lossless Audio Codec (flac) demux plugin" msgstr "" #: src/demuxers/demux_fli.c msgid "Autodesk Animator FLI/FLC demux plugin" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "demux_flv: Not using broken seek index.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "" "demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "unsupported FLV version (%d).\n" msgstr "" #: src/demuxers/demux_flv.c #, c-format msgid "neither video nor audio stream in this file.\n" msgstr "" #: src/demuxers/demux_flv.c msgid "Flash Video file demux plugin" msgstr "" #: src/demuxers/demux_idcin.c msgid "Id Quake II Cinematic file demux plugin" msgstr "" #: src/demuxers/demux_iff.c #, c-format msgid "iff-8svx/16sv: unknown compression: %d\n" msgstr "iff-8svx/16sv: kunpremo nekonata: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff-ilbm: unknown compression: %d\n" msgstr "iff-ilbm: kunpremo nekonata: %d\n" #: src/demuxers/demux_iff.c #, c-format msgid "iff: unknown Chunk: %s\n" msgstr "iff: peco nekonata: %s\n" #: src/demuxers/demux_iff.c msgid "IFF demux plugin" msgstr "" #: src/demuxers/demux_image.c #, fuzzy msgid "image demux plugin" msgstr "eniga kromaĵo de dosiero" #: src/demuxers/demux_ipmovie.c msgid "Interplay MVE Movie demux plugin" msgstr "" #: src/demuxers/demux_ivf.c msgid "IVF demuxer" msgstr "" #: src/demuxers/demux_matroska.c msgid "matroska & webm demux plugin" msgstr "" #: src/demuxers/demux_mng.c msgid "Multiple-image Network Graphics demux plugin" msgstr "" #: src/demuxers/demux_mod.c msgid "ModPlug Amiga MOD Music file demux plugin" msgstr "" #: src/demuxers/demux_mpc.c #, c-format msgid "demux_mpc: frame too big for buffer" msgstr "demux_mpc: filmero estas tro granda por bufro" #: src/demuxers/demux_mpc.c msgid "Musepack demux plugin" msgstr "" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "xine-lib:demux_mpeg_block: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_block: Nerokonita datumstrio_id 0x%02x. Bonvolu komuniki " "tion al disvolvantoj de xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: error! freeing. Please report this to xine developers.\n" msgstr "" "demux_mpeg_block: eraro de malokupo! Bonvolu komuniki tion al disvolvantoj " "de xine.\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "demux_mpeg_block: warning: PES header reserved 10 bits not found\n" msgstr "demux_mpeg_block: averto: PES-ĉapo rezervis 10 netrovitajn bitojn\n" #: src/demuxers/demux_mpeg_block.c #, c-format msgid "" "demux_mpeg_block: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_block: averto: PES-ĉapo indikas ke tiu ĉi datumstrio eble estas " "cifrata (moduso de cifrado %d)\n" #: src/demuxers/demux_mpeg_block.c msgid "DVD/VOB demux plugin" msgstr "" #: src/demuxers/demux_mpeg.c #, fuzzy msgid "MPEG program stream demux plugin" msgstr "eniga kromaĵo por pmn-datumstio" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. Please report this " "to xine developers.\n" msgstr "" "xine-lib:demux_mpeg_pes: Nerekonita datumstrio_id 0x%02x. Bonvolu komuniki " "tion al disvolvantoj de xine.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n" msgstr "" "demux_mpeg_pes: averto: malcodado de PACK-datumstrio id=0x%x malsukcesis.\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "demux_mpeg_pes: warning: PES header reserved 10 bits not found\n" msgstr "demux_mpeg_pes: averto: PES-ĉapo rezervis 10 netrovitajn bitojn\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes: warning: PES header indicates that this stream may be " "encrypted (encryption mode %d)\n" msgstr "" "demux_mpeg_pes: averto: PES-ĉapo indikas ke tiu ĉi datumstrio eble estas " "cifrata (moduso de cifrado %d)\n" #: src/demuxers/demux_mpeg_pes.c #, c-format msgid "" "demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to " "xine developers.\n" msgstr "" "demux_mpeg_pes: Nerekonita privata datumstrio 1 0x%02x. Bonvolu komuniki " "tion al disvolvantoj de xine.\n" #: src/demuxers/demux_mpeg_pes.c msgid "mpeg pes demux plugin" msgstr "" #: src/demuxers/demux_mpgaudio.c #, fuzzy msgid "MPEG audio demux plugin" msgstr "v4l eniga kromaĵo por radio" #: src/demuxers/demux_nsv.c msgid "Nullsoft Video demux plugin" msgstr "" #: src/demuxers/demux_playlist.c msgid "Playlist demux plugin" msgstr "" #: src/demuxers/demux_pva.c msgid "TechnoTrend PVA demux plugin" msgstr "" #: src/demuxers/demux_qt.c #, c-format msgid "demux_qt: added %d fragments\n" msgstr "" #: src/demuxers/demux_qt.c msgid "Apple Quicktime (MOV) and MPEG-4 demux plugin" msgstr "" #: src/demuxers/demux_rawdv.c msgid "Raw DV Video stream" msgstr "" #: src/demuxers/demux_realaudio.c msgid "RealAudio file demux plugin" msgstr "" #: src/demuxers/demux_real.c msgid "RealMedia file demux plugin" msgstr "" #: src/demuxers/demux_roq.c #, fuzzy msgid "Id RoQ file demux plugin" msgstr "eniga kromaĵo de dosiero" #: src/demuxers/demux_shn.c msgid "Shorten demux plugin" msgstr "" #: src/demuxers/demux_smjpeg.c #, fuzzy msgid "SMJPEG file demux plugin" msgstr "eniga kromaĵo de dosiero" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: bad header parameters\n" msgstr "demux_snd: nevalidaj parametroj de ĉapo\n" #: src/demuxers/demux_snd.c #, c-format msgid "demux_snd: unsupported audio type: %d\n" msgstr "demux_snd: nesubtenita aŭdospeco: %d\n" #: src/demuxers/demux_snd.c msgid "SND/AU file demux plugin" msgstr "" #: src/demuxers/demux_str.c msgid "Sony Playstation STR file demux plugin" msgstr "" #: src/demuxers/demux_ts.c msgid "MPEG Transport Stream demuxer" msgstr "" #: src/demuxers/demux_tta.c #, c-format msgid "demux_tta: total frames count too high\n" msgstr "" #: src/demuxers/demux_tta.c msgid "True Audio demux plugin" msgstr "" #: src/demuxers/demux_vc1es.c msgid "VC1 elementary stream demux plugin" msgstr "" #: src/demuxers/demux_vmd.c msgid "Sierra VMD file demux plugin" msgstr "" #: src/demuxers/demux_voc.c #, c-format msgid "unknown VOC block type (0x%02X); please report to xine developers\n" msgstr "" "nekonata VOC-blokspeco (0x%02X); bonvolu komuniki tion al disvolvantoj de " "xine\n" #: src/demuxers/demux_voc.c #, c-format msgid "" "unknown VOC compression type (0x%02X); please report to xine developers\n" msgstr "" "nekonata VOC-kunpremspeco (0x%02X); bonvolu komuniki tion al disvolvantoj de " "xine\n" #: src/demuxers/demux_voc.c msgid "VOC file demux plugin" msgstr "" #: src/demuxers/demux_vox.c msgid "Dialogic VOX file demux plugin" msgstr "" #: src/demuxers/demux_vqa.c msgid "Westwood Studios VQA file demux plugin" msgstr "" #: src/demuxers/demux_wav.c #, fuzzy msgid "WAV file demux plugin" msgstr "eniga kromaĵo de dosiero" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n" msgstr "demux_wc3movie: parto de SHOT rilata al nevalida paletro (%d >= %d)\n" #: src/demuxers/demux_wc3movie.c #, c-format msgid "demux_wc3movie: There was a problem while loading palette chunks\n" msgstr "" "demux_wc3movie: okazis problemo dum ŝargo de grandaj pecoj de paletro\n" #: src/demuxers/demux_wc3movie.c msgid "Wing Commander III Movie (MVE) demux plugin" msgstr "" #: src/demuxers/demux_yuv4mpeg2.c msgid "YUV4MPEG2 file demux plugin" msgstr "" #: src/demuxers/demux_yuv_frames.c msgid "YUV frames dummy demux plugin" msgstr "" #: src/dxr3/dxr3_decode_spu.c msgid "" "subtitle decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card" msgstr "" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "dxr3_decode_spu: Failed to open spu device %s (%s)\n" msgstr "dxr3_decode_spu: Malsukcesis malfermado de SPU-aparato %s (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, fuzzy, c-format msgid "dxr3_decode_spu: spu device write failed (%s)\n" msgstr "dxr3_decode_video: skribo en videoaparato malsukcesis (%s)\n" #: src/dxr3/dxr3_decode_spu.c #, c-format msgid "requested button not available\n" msgstr "mendita butono ne estas disponebla\n" #: src/dxr3/dxr3_decode_video.c msgid "" "MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 " "decoder card." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open control device %s (%s)\n" msgstr "dxr3_decode_video: Malsukcesis malfermo de stiraparato %s (%s)\n" #: src/dxr3/dxr3_decode_video.c msgid "use Pan & Scan info" msgstr "Uzu informojn pri Pan & Skan" #: src/dxr3/dxr3_decode_video.c msgid "" "\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n" "\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n" "\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n" "\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "try to sync video every frame" msgstr "provu sinkronigi videon por ĉiu filero" #: src/dxr3/dxr3_decode_video.c msgid "" "Tries to set a synchronization timestamp for every frame. Normally this is " "not necessary, because sync is sufficient even when the timestamp is set " "only every now and then.\n" "This is relevant for progressive video only (most PAL films)." msgstr "" #: src/dxr3/dxr3_decode_video.c msgid "use smooth play mode" msgstr "uzu glatiga moduso de lego" #: src/dxr3/dxr3_decode_video.c msgid "Enabling this option will utilise a smoother play mode." msgstr "Ebligante tiun ĉi opcion, glatiga moduso de lego estos utiligebla." #: src/dxr3/dxr3_decode_video.c msgid "correct frame durations in broken streams" msgstr "korektu daŭron de filmeroj en difektitaj datumstrioj" #: src/dxr3/dxr3_decode_video.c msgid "" "Enables a small logic that corrects the frame durations of some mpeg streams " "with wrong framerate codes. Currently a correction for NTSC streams " "erroneously labeled as PAL streams is implemented. Enable only, when you " "encounter such streams." msgstr "" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: Failed to open video device %s (%s)\n" msgstr "dxr3_decode_video: Malfermo de videoaparato %s (%s) malsukcesis\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: write to device would block. flushing\n" msgstr "dxr3_decode_video: skribo en aparato povus blokigi elbufrigon\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: video device write failed (%s)\n" msgstr "dxr3_decode_video: skribo en videoaparato malsukcesis (%s)\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "dxr3_decode_video: WARNING: unknown frame rate code %d\n" msgstr "dxr3_decode_video: ATENTU: kodo de filmerkvanto estas nekonata %d\n" #: src/dxr3/dxr3_decode_video.c #, c-format msgid "" "dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n" msgstr "" "dxr3_decode_video: ATENTU: korektante kodon de filmerkvanto, de PAL en NTSC\n" #: src/dxr3/dxr3.h msgid "DXR3 device number" msgstr "Numero de DXR3 aparato" #: src/dxr3/dxr3.h msgid "" "If you have more than one DXR3 in your computer, you can specify which one " "to use here." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to init librte\n" msgstr "dxr3_mpeg_encoder: malsukcesis preparado de librte\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "" "dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of " "16\n" msgstr "" "dxr3_mpeg_encoder: rte administras nur videograndojn kiuj estas multobloj de " "16\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: failed to get rte context.\n" msgstr "dxr3_mpeg_encoder: malsukcesis akiro de kunteksto rte.\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: could not create codec.\n" msgstr "dxr3_mpeg_encoder: estas neeble krei kodaĵon.\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "rte mpeg output bitrate (kbit/s)" msgstr "bitkvanto de eligo de MPEG rte (kbit/s)" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The bitrate the mpeg encoder library librte should use for DXR3's encoding " "mode. Higher values will increase quality and CPU usage." msgstr "" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot init the context: %s\n" msgstr "dxr3_mpeg_encoder: estas neeble prepari la kunteston: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: cannot start encoding: %s\n" msgstr "dxr3_mpeg_encoder: estas neeble lanĉi kodon: %s\n" #: src/dxr3/dxr3_mpeg_encoders.c #, c-format msgid "dxr3_mpeg_encoder: Couldn't start the FAME library\n" msgstr "dxr3_mpeg_encoder: Estas neeble lanĉi bibliotekon FAME\n" #: src/dxr3/dxr3_mpeg_encoders.c msgid "fame mpeg encoding quality" msgstr "Kvalito de MPEG-kodigo por filmero" #: src/dxr3/dxr3_mpeg_encoders.c msgid "" "The encoding quality of the libfame mpeg encoder library. Lower is faster " "but gives noticeable artifacts. Higher is better but slower." msgstr "" #: src/dxr3/dxr3_scr.c msgid "SCR plugin priority" msgstr "Antaŭeco de SCR kromaĵo" #: src/dxr3/dxr3_scr.c msgid "" "Priority of the DXR3 SCR plugin. Values less than 5 mean that the unix " "system timer will be used. Values greater 5 force to use DXR3's internal " "clock as sync source." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "libavcodec mpeg output bitrate (kbit/s)" msgstr "bitkvanto de mpeg eligo por libavcodec (kbit/s)" #: src/dxr3/ffmpeg_encoder.c msgid "" "The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled." msgstr "" #: src/dxr3/ffmpeg_encoder.c msgid "constant quality mode" msgstr "moduso de konstanta kvalito" #: src/dxr3/ffmpeg_encoder.c msgid "" "When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode." msgstr "" "Se ĝi estas ebligita, libavcodec uzos moduson de konstanta kvalito per " "dinamika kompleksecbazita kunpremado de la bildoj. Se ĝi estas malebligita, " "libavcodec uzos moduson de konstanta bitkvanto." #: src/dxr3/ffmpeg_encoder.c msgid "minimum compression" msgstr "minimuma kunpremo" #: src/dxr3/ffmpeg_encoder.c msgid "The minimum compression to apply to an image in constant quality mode." msgstr "Minimuma kunpremo aplikenda al bildo kun moduso de konstanta kvalito." #: src/dxr3/ffmpeg_encoder.c msgid "maximum quantizer" msgstr "maksimuma ciferecigilo" #: src/dxr3/ffmpeg_encoder.c msgid "The maximum compression to apply to an image in constant quality mode." msgstr "Maksimuma kunpremo aplikenda al bildo kun moduso de konstanta kvalito." #: src/dxr3/video_out_dxr3.c msgid "video output plugin displaying images through your DXR3 decoder card" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open control device %s (%s)\n" msgstr "video_out_dxr3: Malsukcesis malfermado de stiraparato %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "swap odd and even lines" msgstr "inerŝangado de plataj kaj senkunaj liniojn" #: src/dxr3/video_out_dxr3.c msgid "" "Swaps the even and odd field of the image.\n" "Enable this option for non-MPEG material which produces a vertical jitter on " "screen." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "add black bars to correct aspect ratio" msgstr "aldonu nigrajn bendojn por aranĝi proporciojn" #: src/dxr3/video_out_dxr3.c msgid "" "Adds black bars when the image has an aspect ratio the card cannot handle " "natively." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "use smooth play mode for mpeg encoder playback" msgstr "uzu glatigan moduson de lego por re-legado per mpeg-enkodilo" #: src/dxr3/video_out_dxr3.c msgid "" "Enabling this option will utilise a smoother play mode for non-MPEG content." msgstr "" "Ebligante tiun ĉi opcion, glatiga moduso de lego estos uzebla por ne-MPEG-" "aĵoj." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Failed to open video device %s (%s)\n" msgstr "video_out_dxr3: Malsukcesis malfermado de videoaparato %s (%s)\n" #: src/dxr3/video_out_dxr3.c msgid "encoder for non mpeg content" msgstr "enkodilo por ne-mpeg-aĵoj" #: src/dxr3/video_out_dxr3.c msgid "" "Content other than MPEG has to pass an additional reencoding stage, because " "the dxr3 handles only MPEG.\n" "Depending on what is supported by your xine, this setting can be \"fame\", " "\"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships " "with xine, so you do not need to install any additional library for that. " "Even better is that libavcodec also provides high quality with low CPU " "usage. Using \"libavcodec\" is therefore strongly suggested.\n" "\"fame\" and \"rte\" are still there, but xine support for them is outdated, " "so these might fail to work." msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder libavcodec failed to init.\n" msgstr "" "video_out_dxr3: malsukcesis preparado de Mpeg-enkodilo nomita libavicodec.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder rte failed to init.\n" msgstr "video_out_dxr3: malsukcesis preparado de Mpeg-enkodilo nomita rte.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: Mpeg encoder fame failed to init.\n" msgstr "video_out_dxr3: malsukcesis preparado de Mpeg-enkodilo nomita fame.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this " "video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an " "encoder.\n" msgstr "" #: src/dxr3/video_out_dxr3.c msgid "video output mode (TV or overlay)" msgstr "moduso de videoeligo (TV aŭ surmeto)" #: src/dxr3/video_out_dxr3.c msgid "" "The way the DXR3 outputs the final video can be set here. The individual " "values are:\n" "\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the " "standard 4:3 television set. Anamorphic (16:9) video will be displayed " "letterboxed, pan&scan material will have the image cropped at the left and " "right side. This is the common setting for TV viewing and acts like a " "standalone DVD player.\n" "\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 " "widescreen TV sets. Anamorphic and pan&scan content will fill the entire " "screen, but you have to set the TV's aspect ratio manually to 16:9 using " "your.\n" "\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. The overlay will be " "displayed with black borders if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that " "would only display properly in letterbox mode. A good example for that are " "the animated commentator's silhouettes on \"Ghostbusters\".\n" "\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly " "switching to TV out by hiding the video window. This is the common variant " "of DXR3 overlay." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "overlay colour key value" msgstr "valoro de kromata ŝlosilo de surmeto" #: src/dxr3/video_out_dxr3.c msgid "" "Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode." msgstr "" "Deksesuma RGB-valoro de kolorŝlosilo.\n" "Vi povas provi malsamajn valorojn, se vi vidas diafanajn fenestrojn kiam vi " "uzas DXR3-moduson de surmeto." #: src/dxr3/video_out_dxr3.c msgid "overlay colour key tolerance" msgstr "tolero de kromata ŝlosilo de surmeto" #: src/dxr3/video_out_dxr3.c msgid "" "A greater value widens the tolerance for the overlay key colour.\n" "You can try lower values, if you experience windows becoming transparent " "when using DXR3 overlay mode, but parts of the image borders may disappear " "when using a too low setting." msgstr "" #: src/dxr3/video_out_dxr3.c msgid "crop the overlay area at top and bottom" msgstr "tranĉu area de surmeto en supraj kaj subaj partoj" #: src/dxr3/video_out_dxr3.c msgid "" "Removes one pixel line from the top and bottom of the overlay. Enable this, " "if you see green lines at the top or bottom of the overlay." msgstr "" "Ĝi formovas unu bilderolinion el supraj kaj subaj partoj de la surmeto. " "Ebligu ĝin, se estas verdaj linioj en supraj kaj subaj partoj de la surmeto." #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: please run autocal, overlay disabled\n" msgstr "video_out_dxr3: bonvolu lanĉi autocal, surmeto estas malebligita\n" #: src/dxr3/video_out_dxr3.c msgid "preferred tv mode" msgstr "favorata tv-moduso" #: src/dxr3/video_out_dxr3.c msgid "" "Selects the TV mode to be used by the DXR3. The values mean:\n" "\n" "ntsc: NTSC at 60Hz\n" "pal: PAL at 50Hz\n" "pal60: PAL at 60Hz\n" "default: keep the card's setting" msgstr "" "Elektado de TV-moduso kiu estas uzenda de DXR3. La valoroj signifas:\n" "\n" "ntsc: NTSC - 60Hz\n" "pal: PAL - 50Hz\n" "pal60: PAL - 60Hz\n" "default: tenu agordojn de la sonkarto" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: setting video mode failed.\n" msgstr "video_out_dxr3: agordado de videomoduso malsukcesis.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "" "video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n" msgstr "" "video_out_dxr3: Estas necese mpeg enkodilo por legi ne-mpeg videoj en dxr3\n" "video_out_dxr3: Legu README.dxr3 por pluaj detaloj.\n" #: src/dxr3/video_out_dxr3.c #, c-format msgid "video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n" msgstr "" "video_out_dxr3: ERARO dum lego de preparaddosiero de surmeto. Lanĉu " "autocal!\n" #: src/input/input_bluray.c msgid "BluRay input plugin" msgstr "" #: src/input/input_bluray.c msgid "BluRay mount point" msgstr "" #: src/input/input_bluray.c msgid "Default mount location for BluRay discs." msgstr "" #: src/input/input_bluray.c msgid "device used for BluRay playback" msgstr "" #: src/input/input_bluray.c #, fuzzy msgid "" "The path to the device which you intend to use for playing BluRay discs." msgstr "Raŭto por la aparato de WinTV-karto." #: src/input/input_bluray.c msgid "default language for BluRay playback" msgstr "" #: src/input/input_bluray.c msgid "" "xine tries to use this language as a default for BluRay playback. As far as " "the BluRay supports it, menus and audio tracks will be presented in this " "language.\n" "The value must be a three characterISO639-2 language code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player country code" msgstr "" #: src/input/input_bluray.c msgid "The value must be a two character ISO3166-1 country code." msgstr "" #: src/input/input_bluray.c msgid "BluRay player region code (1=A, 2=B, 4=C)" msgstr "" #: src/input/input_bluray.c msgid "" "This only needs to be changed if your BluRay jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "BluRay drives, this is purely software." msgstr "" #: src/input/input_bluray.c msgid "parental control age limit (1-99)" msgstr "" #: src/input/input_bluray.c msgid "" "Prevents playback of BluRay titles where parental control age limit is " "higher than this limit" msgstr "" #: src/input/input_bluray.c src/input/input_dvd.c msgid "unit for the skip action" msgstr "unito de preterlaso" #: src/input/input_bluray.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)." msgstr "" #: src/input/input_bluray.c msgid "BluRay input plugin (using menus)" msgstr "" #: src/input/input_cdda.c #, c-format msgid "%s: can't connect to %s:%d\n" msgstr "%s: estas neeble konektigi %s:%d\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: successfully connected to cddb server '%s:%d'.\n" msgstr "input_cdda: sukcesa konekto kun cddb servilo '%s:%d'.\n" #: src/input/input_cdda.c #, c-format msgid "input_cdda: failed to connect to cddb server '%s:%d' (%s).\n" msgstr "input_cdda: malsukcesa konekto kun cddb servilo '%s:%d' (%s).\n" #: src/input/input_cdda.c msgid "CD Digital Audio (aka. CDDA)" msgstr "KD Diĝita Aŭdo (alie CDDA)" #: src/input/input_cdda.c msgid "device used for CD audio" msgstr "" #: src/input/input_cdda.c msgid "" "The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs." msgstr "" #: src/input/input_cdda.c msgid "query CDDB" msgstr "informmendo de CDDB" #: src/input/input_cdda.c msgid "" "Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is " "retrieved from an internet server which might collect a profile of your " "listening habits." msgstr "" #: src/input/input_cdda.c msgid "CDDB server name" msgstr "Nomo de servilo de CDDB" #: src/input/input_cdda.c msgid "" "The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive " "information about your listening habits and could answer the queries with " "malicious replies. Be sure to enter a server you can trust." msgstr "" #: src/input/input_cdda.c msgid "CDDB server port" msgstr "Servilpordo de CDDB" #: src/input/input_cdda.c msgid "The server port used to retrieve the title and track information from." msgstr "" #: src/input/input_cdda.c msgid "slow down disc drive to this speed factor" msgstr "Malrapidigu disk-turnilon per faktoro je tiu ĉi rapideco" #: src/input/input_cdda.c msgid "" "Since some CD or DVD drives make some really loud noises because of the fast " "disc rotation, xine will try to slow them down. With standard CD or DVD " "playback, the high datarates that require the fast rotation are not needed, " "so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown." msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: failed to open dvb channel file '%s': %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: dvb channel file '%s' is not a plain file\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: tuner_set_channel failed\n" msgstr "input_dvb: tuner_set_channel malsukcesis\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: DVB GUI %s\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvb device\n" msgstr "input_dvb: estas neeble malfermi dvb-aparaton\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %d out of range, defaulting to 0\n" msgstr "input_dvb: kanalo %d estas ekstera de intervalo, agordante je 0\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: searching for channel %s\n" msgstr "input_dvb: serĉante kanalon %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: exact match for %s not found: trying partial matches\n" msgstr "" "input_dvb: preciza kongruo ne estis trovita por %s: provante partan " "kongruon\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: found matching channel %s\n" msgstr "input_dvb: estas trovita kongrua kanalo %s\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: channel %s not found in channels.conf, defaulting.\n" msgstr "" "input_dvb: kanalo %s ne trovita en channels.conf, agordante per defaŭlto.\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: invalid channel specification, defaulting to last viewed " "channel.\n" msgstr "" "input_dvb: nevalida specifo de kanalo, defaŭlte agordante per valoroj de " "lasta vidita kanalo.\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: invalid channel specification, defaulting to channel 0\n" msgstr "" "input_dvb: nevalida specifo de kanalo, defaŭlte agordante al kanalo 0\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-" "S)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-" "T)\n" msgstr "" "input_dvb: dvbt mrl estis specifita sed sintonizilo ŝajnas ne esti OFDM (DVB-" "T)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-" "C)\n" msgstr "" "input_dvb: dvbt mrl estis specifita sed sintonizilo ŝajnas ne esti QAM (DVB-" "C)\n" #: src/input/input_dvb.c #, c-format msgid "" "input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-" "A)\n" msgstr "" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot open dvr device '%s'\n" msgstr "input_dvb: estas neeble malfermi dvr-aparaton '%s'\n" #: src/input/input_dvb.c #, c-format msgid "input_dvb: cannot create EPG updater thread\n" msgstr "input_dvb: estas neeble krei fadenon de ĝisdatigo EPG\n" #: src/input/input_dvb.c msgid "use DVB 'center cutout' (zoom)" msgstr "uzu 'centran tranĉon' DVB (zomo)" #: src/input/input_dvb.c msgid "" "This will allow fullscreen playback of 4:3 content transmitted in a 16:9 " "frame." msgstr "" "Ĝi ebligas tutekrame vidigon laŭ entenoj kiu havas formato de 4:3 sed " "elsenditaj per filmeroj en 16:9-formato." #: src/input/input_dvb.c msgid "DVB (Digital TV) input plugin" msgstr "eniga kromaĵo por DVB (Diĝita TV)" #: src/input/input_dvb.c msgid "Remember last DVB channel watched" msgstr "Memorigu lastan viditan DVB-kanalon" #: src/input/input_dvb.c msgid "" "On autoplay, xine will remember and switch to the channel indicated in media." "dvb.last_channel. " msgstr "" #: src/input/input_dvb.c msgid "Last DVB channel viewed" msgstr "Lasta vidita DVB-kanalo" #: src/input/input_dvb.c msgid "If enabled xine will remember and switch to this channel. " msgstr "" #: src/input/input_dvb.c msgid "Number of seconds until tuning times out." msgstr "" #: src/input/input_dvb.c msgid "" "Leave at 0 means try forever. Greater than 0 means wait that many seconds to " "get a lock. Minimum is 5 seconds." msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI" msgstr "" #: src/input/input_dvb.c msgid "Enable the DVB GUI, mouse controlled recording and channel switching." msgstr "" #: src/input/input_dvb.c msgid "Number of dvb card to use." msgstr "Numero de uzenda DVB-karto" #: src/input/input_dvb.c msgid "" "Leave this at zero unless you really have more than 1 card in your system." msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: values of \\beta will give rise to dom!\n" msgstr "" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error getting next block from DVD (%s)\n" msgstr "input_dvd: Eraro dum la akirado de sekva bloko el DVD (%s)\n" #: src/input/input_dvd.c #, c-format msgid "input_dvd: Error opening DVD device\n" msgstr "input_dvd: Eraro dum malfermado de DVD-apararo\n" #: src/input/input_dvd.c msgid "DVD Navigator" msgstr "" #: src/input/input_dvd.c msgid "device used for DVD playback" msgstr "aparato uzata por legi/ludi DVD" #: src/input/input_dvd.c msgid "" "The path to the device, usually a DVD drive, which you intend to use for " "playing DVDs." msgstr "" #: src/input/input_dvd.c msgid "CSS decryption method" msgstr "Metodo de deĉifrado CSS" #: src/input/input_dvd.c msgid "" "Selects the decryption method libdvdcss will use to descramble copy " "protected DVDs. Try the various methods, if you have problems playing " "scrambled DVDs." msgstr "" #: src/input/input_dvd.c msgid "region the DVD player claims to be in (1 to 8)" msgstr "zono kie DVD-legilo deklari sian lokiĝon (de 1 ĝis 8)" #: src/input/input_dvd.c msgid "" "This only needs to be changed if your DVD jumps to a screen complaining " "about a wrong region code. It has nothing to do with the region code set in " "DVD drives, this is purely software." msgstr "" #: src/input/input_dvd.c msgid "default language for DVD playback" msgstr "defaŭlta lingvo por legi/ludi DVD" #: src/input/input_dvd.c msgid "" "xine tries to use this language as a default for DVD playback. As far as the " "DVD supports it, menus and audio tracks will be presented in this language.\n" "The value must be a two character ISO639 language code." msgstr "" #: src/input/input_dvd.c msgid "read-ahead caching" msgstr "lega-senkapa kaŝmemorigado" #: src/input/input_dvd.c msgid "" "xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives." msgstr "" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n" "\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the index " "marks on an audio CD; this is the normal behaviour for DVD players\n" "\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the track marks " "on an audio CD; parts usually coincide with programs, but parts can be " "larger than programs\n" "\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD" msgstr "" #: src/input/input_dvd.c msgid "unit for seeking" msgstr "unito de enpoziciigo" #: src/input/input_dvd.c msgid "" "You can configure the domain spanned by the seek slider. The individual " "values mean:\n" "\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational unit " "representing the entire video stream of the current feature\n" "\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing a " "chapter of the current feature" msgstr "" #: src/input/input_dvd.c msgid "play mode when title/chapter is given" msgstr "moduso de lego kiam oni havigas titolon/ĉapitron" #: src/input/input_dvd.c msgid "" "You can configure the behaviour when playing a dvd from a given title/" "chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n" "\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n" "\n" "one chapter\n" "play just the specified title/chapter and then stop" msgstr "" #: src/input/input_file.c #, c-format msgid "input_file: Permission denied: >%s<\n" msgstr "input_file: Rifuzita permeso: >%s<\n" #: src/input/input_file.c #, c-format msgid "input_file: File not found: >%s<\n" msgstr "input_file: Netrovita dosierod: >%s<\n" #: src/input/input_file.c src/input/input_gnome_vfs.c #, c-format msgid "input_file: File empty: >%s<\n" msgstr "input_file: Vakua dosiero: >%s<\n" #: src/input/input_file.c msgid "file input plugin" msgstr "eniga kromaĵo de dosiero" #: src/input/input_file.c msgid "file browsing start location" msgstr "startpunkto de foliumo" #: src/input/input_file.c msgid "The browser to select the file to play will start at this location." msgstr "" #: src/input/input_ftp.c #, fuzzy msgid "FTP input plugin" msgstr "eniga kromaĵo de dosiero" #: src/input/input_ftp.c #, fuzzy msgid "FTPES input plugin" msgstr "eniga kromaĵo de dosiero" #: src/input/input_gnome_vfs.c msgid "gnome-vfs input plugin as shipped with xine" msgstr "gnome-vfs-eniga kromaĵo kiu estas entenata en xine" #: src/input/input_helper.c msgid "list hidden files" msgstr "listo de kaŝitaj dosieroj" #: src/input/input_helper.c msgid "" "If enabled, the browser to select the file to play will also show hidden " "files." msgstr "" #: src/input/input_helper.c msgid "Default servers" msgstr "" #: src/input/input_helper.c msgid "" "List of space-separated server urls for media browser. (ex. \"ftp://ftp3.itu." "int sftp://user:pass@host.com\")" msgstr "" #: src/input/input_hls.c #, fuzzy msgid "HTTP live streaming input plugin" msgstr "eniga kromaĵo por datumstrio de stdin" #: src/input/input_http.c #, c-format msgid "input_http: gethostbyname(%s) failed: %s\n" msgstr "input_http: gethostbyname(%s) malsukcesis: %s\n" #: src/input/input_http.c #, c-format msgid "input_http: read error %d\n" msgstr "input_http: eraro de lego %d\n" #: src/input/input_http.c msgid "Connecting HTTP server..." msgstr "Konektigante servilon de HTTP..." #: src/input/input_http.c #, c-format msgid "input_http: invalid http answer\n" msgstr "input_http: nevalida demando de http\n" #: src/input/input_http.c #, c-format msgid "input_http: 3xx redirection: >%d %s<\n" msgstr "input_http: 3xx-alidirektado: >%d %s<\n" #: src/input/input_http.c #, c-format msgid "input_http: http status not 2xx: >%d %s<\n" msgstr "input_http: stato de http ne estas 2xx: >%d %s<\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: content length = % bytes\n" msgstr "input_http: entenlongo = % bytes\n" #: src/input/input_http.c #, fuzzy, c-format msgid "input_http: buffer exhausted after %zu bytes." msgstr "input_http: bufro estis plenigita post %d bajtoj." #: src/input/input_http.c #, fuzzy msgid "http/https input plugin" msgstr "eniga kromaĵo por HTTP" #: src/input/input_http.c msgid "HTTP proxy host" msgstr "HTTP-prokura ĉefkomputilo" #: src/input/input_http.c msgid "The hostname of the HTTP proxy." msgstr "Nomo de ĉefkomputilo por prokura servo de HTTP" #: src/input/input_http.c msgid "HTTP proxy port" msgstr "HTTP-prokura pordo" #: src/input/input_http.c msgid "The port number of the HTTP proxy." msgstr "Numero de pordo por prokura servo de HTTP" #: src/input/input_http.c msgid "HTTP proxy username" msgstr "HTTP-prokura uzantnomo" #: src/input/input_http.c msgid "The user name for the HTTP proxy." msgstr "Nomo de uzanto por prokura servo de HTTP" #: src/input/input_http.c msgid "HTTP proxy password" msgstr "HTTP-prokura pasvorto" #: src/input/input_http.c msgid "The password for the HTTP proxy." msgstr "Pasvorto por prokura servo de HTTP" #: src/input/input_http.c msgid "Domains for which to ignore the HTTP proxy" msgstr "Domajnoj kiuj devas ignori prokuran servon de HTTP" #: src/input/input_http.c msgid "" "A comma-separated list of domain names for which the proxy is to be " "ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)." msgstr "" "Kom-dividita listo pri nomoj de domajnoj kiuj devas ignori prokuran servon.\n" "Se la nomo de domajno havas antaŭmetan '=' do ĝi estas konsiderita kiel " "unuopa nomo de gastiga komputilo (plena kongruo estas necesa)." #: src/input/input_http.c msgid "HTTP protocol version to use" msgstr "" #: src/input/input_http.c msgid "Try these when there are communication problems." msgstr "" #: src/input/input_http.c msgid "Dump HTTP request and response heads to this file" msgstr "" #: src/input/input_http.c msgid "Set this for debugging." msgstr "" #: src/input/input_mms.c msgid "mms streaming input plugin" msgstr "eniga kromaĵo por MMS" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "network bandwidth" msgstr "bendolarĝo de reto" #: src/input/input_mms.c src/input/librtsp/rtsp_session.c msgid "" "Specify the bandwidth of your internet connection here. This will be used " "when streaming servers offer different versions with different bandwidth " "requirements of the same stream." msgstr "" #: src/input/input_mms.c msgid "MMS protocol" msgstr "MMS-protokolo" #: src/input/input_mms.c msgid "" "Select the protocol to encapsulate MMS.\n" "TCP is better but you may need HTTP behind a firewall." msgstr "" "Elektu protokolon por enpakigita MMS.\n" "TCP estas la plej bona sed povus necesi HTTP trans fajroŝirmo." #: src/input/input_mpegdash.c #, fuzzy msgid "MPEG Dynamic Adaptive Streaming over Http input plugin" msgstr "eniga kromaĵo por datumstrio de stdin" #: src/input/input_net.c msgid "net input plugin as shipped with xine" msgstr "eniga xine-entenita kromaĵo de reto" #: src/input/input_net.c #, fuzzy msgid "tls input plugin" msgstr "eniga kromaĵo de dosiero" #: src/input/input_net.c #, fuzzy msgid "gopher input plugin" msgstr "eniga kromaĵo de dosiero" #: src/input/input_nfs.c #, fuzzy msgid "Network File System (NFS) input plugin" msgstr "eniga kromaĵo por datumstrio de stdin" #: src/input/input_pnm.c msgid "pnm streaming input plugin" msgstr "eniga kromaĵo por pmn-datumstio" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error creating pvr file (%s)\n" msgstr "input_pvr: eraro dum kreado de dosiero pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening pvr file (%s)\n" msgstr "input_pvr: eraro dum malfermado de dosiero pvr (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: read error (%s)\n" msgstr "input_pvr: eraro de lego (%s)\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: error opening device %s\n" msgstr "input_pvr: eraro dum malfermado de aparato %s\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_G_CODEC malsukcesis, ĉu API estas ŝanĝita?\n" #: src/input/input_pvr.c #, c-format msgid "input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n" msgstr "input_pvr: IVTV_IOC_S_CODEC malsukcesis, ĉu API estas ŝanĝita?\n" #: src/input/input_pvr.c msgid "WinTV-PVR 250/350 input plugin" msgstr "eniga kromaĵo WinTV-PVR 250/350" #: src/input/input_pvr.c msgid "device used for WinTV-PVR 250/350 (pvr plugin)" msgstr "aparato uzata por WinTV-PVR 250/350 (pvr-kromaĵo)" #: src/input/input_pvr.c msgid "The path to the device of your WinTV card." msgstr "Raŭto por la aparato de WinTV-karto." #: src/input/input_rtp.c #, c-format msgid "xine_socket_cloexec(): %s.\n" msgstr "" #: src/input/input_rtp.c msgid "IP address specified is multicast\n" msgstr "La specifita IP-adreso estas plursenda\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_RCVBUF): %s.\n" msgstr "setsockopt(SO_RCVBUF): %s.\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(SO_REUSEADDR): %s.\n" msgstr "setsockopt(SO_REUSEADDR): %s.\n" #: src/input/input_rtp.c #, c-format msgid "bind(): %s.\n" msgstr "bind(): %s.\n" #: src/input/input_rtp.c #, c-format msgid "Can't find address for iface %s:%s\n" msgstr "Estas neeble trovi adreson por iface %s:%s\n" #: src/input/input_rtp.c #, c-format msgid "setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n" msgstr "setsockopt(IP_ADD_MEMBERSHIP) malsukcesis (ĉu plursenda kerno?): %s.\n" #: src/input/input_rtp.c #, c-format msgid "unable to resolve '%s'.\n" msgstr "mi estas nekapabla solvi '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "unable to bind to '%s'.\n" msgstr "mi estas nekapabla bindi al '%s'.\n" #: src/input/input_rtp.c #, c-format msgid "recv(): %s.\n" msgstr "recv(): %s.\n" #: src/input/input_rtp.c msgid "RTP: stopping reading thread...\n" msgstr "RTP: lego de fadeno estas haltanta...\n" #: src/input/input_rtp.c msgid "RTP: reading thread terminated\n" msgstr "RTP: lego de fadeno finiĝis\n" #: src/input/input_rtp.c #, fuzzy, c-format msgid "Opening >address:%s port:%d interface:%s<\n" msgstr "Malfermante >dosiernomon:%s pordon:%d interfacon:%s<\n" #: src/input/input_rtp.c #, c-format msgid "input_rtp: can't create new thread (%s)\n" msgstr "input_rtp: estas neeble krei novan fadenon (%s)\n" #: src/input/input_rtp.c msgid "RTP and UDP input plugin as shipped with xine" msgstr "eniga kromaĵo entenata en xine por RTP kaj UDP" #: src/input/input_rtsp.c msgid "rtsp streaming input plugin" msgstr "eniga kromaĵo por datumstrio de RTSP" #: src/input/input_smb.c msgid "CIFS/SMB input plugin based on libsmbclient" msgstr "CIFS/SMB-eniga kromaĵo bazita sur libsmbclient" #: src/input/input_ssh.c #, fuzzy msgid "SCP input plugin" msgstr "eniga kromaĵo de dosiero" #: src/input/input_ssh.c #, fuzzy msgid "SFTP input plugin" msgstr "eniga kromaĵo de dosiero" #: src/input/input_stdin_fifo.c #, c-format msgid "stdin: failed to open '%s'\n" msgstr "stdin: malsukcesis malfermo de '%s'\n" #: src/input/input_stdin_fifo.c msgid "stdin streaming input plugin" msgstr "eniga kromaĵo por datumstrio de stdin" #: src/input/input_test.c msgid "Colour Circle" msgstr "" #: src/input/input_test.c msgid "RGB Levels" msgstr "" #: src/input/input_test.c msgid "Saturation Levels" msgstr "" #: src/input/input_test.c msgid "UV Square" msgstr "" #: src/input/input_test.c msgid "Luminance Resolution" msgstr "" #: src/input/input_test.c msgid "test card input plugin" msgstr "" #: src/input/input_v4l2.c #, fuzzy msgid "v4l2 input plugin" msgstr "v4l eniga kromaĵo por tv" #: src/input/input_v4l.c msgid "Buffer underrun..." msgstr "Troo de bufro..." #: src/input/input_v4l.c msgid "Buffer overrun..." msgstr "Maltroo de bufro..." #: src/input/input_v4l.c msgid "Adjusting..." msgstr "Aranĝante..." #: src/input/input_v4l.c #, c-format msgid "Tuner name not found\n" msgstr "Nomo de sintonizilo ne estis trovita\n" #: src/input/input_v4l.c msgid "v4l tv input plugin" msgstr "v4l eniga kromaĵo por tv" #: src/input/input_v4l.c msgid "v4l video device" msgstr "v4l videoaparato" #: src/input/input_v4l.c msgid "The path to your Video4Linux video device." msgstr "Raŭto por videoaparato de Video4Linux." #: src/input/input_v4l.c msgid "v4l ALSA audio input device" msgstr "" #: src/input/input_v4l.c msgid "" "The name of the audio device which corresponds to your Video4Linux video " "device." msgstr "Raŭto por videoaparato de Video4Linux." #: src/input/input_v4l.c msgid "v4l TV standard" msgstr "" #: src/input/input_v4l.c msgid "" "Selects the TV standard of the input signals. Either: AUTO, PAL, NTSC or " "SECAM. " msgstr "" #: src/input/input_v4l.c msgid "v4l radio input plugin" msgstr "v4l eniga kromaĵo por radio" #: src/input/input_v4l.c msgid "v4l radio device" msgstr "v4l radiooaparato" #: src/input/input_v4l.c msgid "The path to your Video4Linux radio device." msgstr "Raŭto por radioaparato de Video4Linux" #: src/input/input_vcd.c #, c-format msgid "input_vcd: malformed MRL. Use vcdo:/\n" msgstr "input_vcd: difektita MRL. Uzu vcdo:/\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: invalid track %d (valid range: 0 .. %d)\n" msgstr "input_vcd: nevalida trako %d (valida intervalo: 0 .. %d)\n" #: src/input/input_vcd.c #, c-format msgid "unable to open %s: %s.\n" msgstr "Mi estas nekapabla malfermi %s: %s.\n" #: src/input/input_vcd.c #, c-format msgid "input_vcd: unable to open %s: %s.\n" msgstr "input_vcd: mi estas nekapabla malfermi %s: %s.\n" #: src/input/input_vcd.c msgid "Video CD input plugin" msgstr "Eniga kromaĵo por Videa KD (VCD)" #: src/input/input_vcd.c msgid "device used for VCD playback" msgstr "aparato uzata por legi/ludi VCD" #: src/input/input_vcd.c msgid "" "The path to the device, usually a CD or DVD drive, you intend to play your " "VideoCDs with." msgstr "" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: bad mrl: %s\n" msgstr "rtsp: nevalida mrl: %s\n" #: src/input/librtsp/rtsp.c #, c-format msgid "rtsp: failed to connect to '%s'\n" msgstr "rtsp: malsukcesis konekto kun '%s'\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: failed to connect to server %s\n" msgstr "rtsp_session: malsukcesis konekto kun servilo %s\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: session can not be established.\n" msgstr "rtsp_session: sesio ne kapablas stariĝi.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "" "rtsp_session: rtsp server returned overly-large headers, session can not be " "established.\n" msgstr "rtsp_session: sesio ne kapablas stariĝi.\n" #: src/input/librtsp/rtsp_session.c #, c-format msgid "rtsp_session: rtsp server type '%s' not supported yet. sorry.\n" msgstr "" "rtsp_session: rtsp-servilspeco '%s' ne estas ankoraŭ subtenita. mi " "bedaŭras.\n" #: src/input/media_helper.c #, c-format msgid "input_dvd: Device %s failed to open during eject calls\n" msgstr "input_dvd: Aparato %s malsukcesis malfermiĝi dum voko de elĵeto\n" #: src/input/mms.c msgid "Connecting MMS server (over tcp)..." msgstr "Konektigante MSS-servilon (per tcp)..." #: src/input/mmsh.c #, c-format msgid "libmmsh: send error\n" msgstr "libmmsh: eraro de sendo\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: bad response format\n" msgstr "libmmsh: nevalida formato de respondo\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: 3xx redirection not implemented: >%d %s<\n" msgstr "libmmsh: 3xx-alidirektado ne estas ankoraŭ realigita: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: http status not 2xx: >%d %s<\n" msgstr "libmmsh: stato de http ne estas 2xx: >%d %s<\n" #: src/input/mmsh.c #, c-format msgid "libmmsh: Location redirection not implemented\n" msgstr "libmmsh: alidirektado de LOCATION ne estas ankoraŭ realigita\n" #: src/input/mmsh.c msgid "Connecting MMS server (over http)..." msgstr "Konektigante MSS-servilon (per http)..." #: src/input/mmsh.c #, c-format msgid "invalid url\n" msgstr "nevalida url\n" #: src/input/mmsh.c #, c-format msgid "unsupported protocol\n" msgstr "nesubtenita protokolo\n" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred video size" msgstr "favorata tv-moduso" #: src/input/multirate_pref.c msgid "What size of video to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c msgid "Preferred language" msgstr "" #: src/input/multirate_pref.c msgid "What language to play when there are multiple versions." msgstr "" #: src/input/multirate_pref.c #, fuzzy msgid "Preferred bitrate" msgstr "favorata tv-moduso" #: src/input/multirate_pref.c msgid "What bitrate to play when there are multiple versions of same size." msgstr "" #: src/input/pnm.c #, c-format msgid "" "input_pnm: got message from server while reading stream:\n" "%s\n" msgstr "" "input_pnm: mesaĝo el servilo dum lego de datumstrio:\n" "%s\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to connect '%s'\n" msgstr "nput_pnm: malsukcesis konekto '%s'\n" #: src/input/pnm.c #, c-format msgid "input_pnm: failed to set up stream\n" msgstr "input_pnm: agordado de datumstrio malsukcesis\n" #: src/input/tls/tls_gnutls.c msgid "TLS provider (gnutls)" msgstr "" #: src/input/tls/tls_openssl.c msgid "TLS provider (openssl)" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "Verify server TLS certificate" msgstr "" #: src/input/tls/xine_tls_plugin.h msgid "" "If enabled, server TLS certificate is always checked. If check fails, " "connections to server are not allowed." msgstr "" #: src/input/vcd/vcdio.c msgid "SEEK_CUR not implemented for non-zero offset" msgstr "SEEK_CUR ne estas ankoraŭ realigita por ne-nula deŝovo" #: src/input/vcd/vcdio.c msgid "SEEK_END not implemented yet." msgstr "SEEK_END ne estas ankoraŭ realigita." #: src/input/vcd/vcdio.c msgid "seek not implemented yet for" msgstr "SEEK ne estas ankoraŭ realigita por" #: src/input/vcd/vcdplayer.c msgid "bad item type" msgstr "nevalida speco de ero" #: src/input/vcd/vcdplayer.c msgid "bad entry number" msgstr "nevalida numero de ero" #: src/input/vcd/vcdplayer.c msgid "bad segment number" msgstr "nevalida numero de segmento" #: src/input/vcd/vcdplayer.c msgid "Error in getting current segment number" msgstr "Eraro dum akirado de numeron de nuna segmento" #: src/input/vcd/vcdplayer.c msgid "Should have converted this above" msgstr "Antaŭaĵo devus esti konvertita" #: src/input/vcd/xineplug_inp_vcd.c msgid "failed to find a device with a VCD" msgstr "estas neeble trovi aparaton kun VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "was passed a null class parameter" msgstr "nula parametro de klaso estis havigita" #: src/input/vcd/xineplug_inp_vcd.c msgid "Invalid current entry type" msgstr "Nevalida speco de nuna enigo" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no RETURN entry" msgstr "elekto ne havas eron de speco RETURN" #: src/input/vcd/xineplug_inp_vcd.c msgid "DEFAULT selected, but PBC is not on." msgstr "elektita DEFAULT, sed PBC ne estas ebligita." #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no NEXT entry" msgstr "elekto ne havas eron de speco NEXT" #: src/input/vcd/xineplug_inp_vcd.c msgid "selection has no PREVIOUS entry" msgstr "elekto ne havas eron de speco PREVIOUS" #: src/input/vcd/xineplug_inp_vcd.c msgid "Unknown event type: " msgstr "Nekonata speco de evento:" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... " msgstr "" "Kromaĵo por Videa KD kun PBC kaj subteno por: (X)VCD, (X)SVCD, HQVCD, " "CVD ... " #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD default type to use on autoplay" msgstr "Defaŭlta speco de VCD uzenda por aŭtomata lego" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "The VCD play unit to use when none is specified in an MRL, e.g. vcd:// or " "vcd:///dev/dvd:" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "CD-ROM drive used for VCD when none given" msgstr "Lumdiskingo uzenda por VCD kiam ĝi estas ne specifita" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "What to use if no drive specified. If the setting is empty, xine will scan " "for CD drives." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD position slider range" msgstr "intervalo de ŝovindikilo por VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "range that the stream playback position slider represents playing a VCD." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD read-ahead caching?" msgstr "Ĉu lega-senkapa kaŝmemorigo de VCD?" #: src/input/vcd/xineplug_inp_vcd.c msgid "May lead to jerky playback on low-end machines." msgstr "Tiu ĉi klaso povas kaŭzi singultan legadon laŭ malrapidaj komputiloj." #: src/input/vcd/xineplug_inp_vcd.c msgid "automatically advance VCD track/entry" msgstr "mem-pluiro laŭ trako/ero de VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "If enabled, we should automatically advance to the next entry or track. Used " "only when playback control (PBC) is disabled." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "show 'rejected' VCD LIDs" msgstr "montru LID de \"rifuzitaj\" VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "Some playback list IDs (LIDs) are marked not showable, but you can see them " "in the MRL list if this is set. Rejected entries are marked with an asterisk " "(*) appended to the MRL." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for display banner" msgstr "VDC-formata Ĉeno por vidigi rulbandon" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n" msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD format string for stream comment field" msgstr "VDC-formata Ĉeno por fako de komento pri datumstrio" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "VCD format used in the GUI Title. Similar to the Unix date command. Format " "specifiers start with a percent sign. Specifiers are %A, %C, %c, %F, %I, %L, " "%N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these." msgstr "" #: src/input/vcd/xineplug_inp_vcd.c msgid "VCD debug flag mask" msgstr "Masko de flago por sencimigi VCD" #: src/input/vcd/xineplug_inp_vcd.c msgid "" "For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" msgstr "" #: src/libreal/real_common.c msgid "path to RealPlayer codecs" msgstr "raŭto por kodaĵoj de RealPlayer" #: src/libreal/real_common.c msgid "" "If you have RealPlayer installed, specify the path to its codec directory " "here. You can easily find the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer codecs, it will use them " "to decode RealPlayer content for you. Consult the xine FAQ for more " "information on how to install the codecs." msgstr "" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n" msgstr "libareal: (aŭdo) Estas neeble solvi simbolojn - malkongrua dll: %s\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder init failed, error code: 0x%x\n" msgstr "libareal: preparado de malkodilo malsukcesis, erarkodo: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: decoder flavor setup failed, error code: 0x%x\n" msgstr "libareal: agordado de malkodilspeco malsukcesis, erarkodo: 0x%x\n" #: src/libreal/xine_real_audio_decoder.c #, c-format msgid "libareal: oups, real can do more than 2 channels ?\n" msgstr "libareal: huj, ĉu REAL povas uzi pli ol 2 kanalojn ?\n" #: src/libreal/xine_real_audio_decoder.c msgid "real binary-only codec based audio decoder plugin" msgstr "" #: src/libreal/xine_real_video_decoder.c #, c-format msgid "libreal: Error resolving symbols! (version incompatibility?)\n" msgstr "" "libreal: Eraro dum solvado de simboloj! (ĉu nekompatibileco de versioj?)\n" #: src/libreal/xine_real_video_decoder.c msgid "real binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/common.c msgid "path to Win32 codecs" msgstr "raŭto por kodaĵoj de Win32" #: src/libw32dll/common.c msgid "" "If you have the Windows or Apple Quicktime codec packs installed, specify " "the path the codec directory here. If xine can find the Windows or Apple " "Quicktime codecs, it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for more information on how " "to install the codecs." msgstr "" #: src/libw32dll/qt_decoder.c #, fuzzy msgid "quicktime audio decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/libw32dll/qt_decoder.c msgid "quicktime binary-only codec based video decoder plugin" msgstr "" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: ICOpen malsukcesis! Ĉu nekonata kodaĵo %08lx aŭ eraraj " "parametroj?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n" msgstr "" "w32codec: ICDecompressGetFormat (%.4s %08lx/%d) malsukcesis: eraro %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressQuery failed: Error %ld\n" msgstr "w32codec: ICDecompressQuery malsukcesis: eraro %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: ICDecompressBegin failed: Error %ld\n" msgstr "w32codec: ICDecompressBegin malsukcesis: eraro %ld\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DS_VideoDecoder malsukcesis! Ĉu nekonata kodaĵo %08lx aŭ eraraj " "parametroj?\n" #: src/libw32dll/w32codec.c #, c-format msgid "" "w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n" msgstr "" "w32codec: DMO_VideoDecoder malsukcesis! Ĉu nekonata kodaĵo %08lx aŭ eraraj " "parametroj?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: decoder failed to start. Is '%s' installed?\n" msgstr "w32codec: starto de malkodilo malsukcesis. Ĉu '%s' estas instalita?\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) Unappropriate audio format\n" msgstr "w32codec: (ACM_Decoder) netaŭga aŭdoformato\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: (ACM_Decoder) acmStreamOpen error %d\n" msgstr "w32codec: (ACM_Decoder) acmStreamOpen eraro %d\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DirectShow Audio\n" msgstr "w32codec: Eraro dum preparado de DirectShow Aŭdo\n" #: src/libw32dll/w32codec.c #, c-format msgid "w32codec: Error initializing DMO Audio\n" msgstr "w32codec: Eraro dum preparado de DMO Aŭdo\n" #: src/libw32dll/w32codec.c msgid "win32 binary video codec plugin" msgstr "" #: src/libw32dll/w32codec.c msgid "win32 binary audio codec plugin" msgstr "" #: src/post/audio/stretch.c msgid "" "This filter will perform a time stretch, playing the stream faster or slower " "by a factor. Pitch is optionally preserved, so it is possible, for example, " "to use it to watch a movie in less time than it was originally shot.\n" msgstr "" "Tiu ĉi filtrilo plenumos tempodilatadon, legante datumstrion pli aŭ malpli " "rapide per iu faktoro. La tembro estas, laŭpete, konservita, do vi povas uzi " "tion, ekzemple, por vidi filmon dum pli mallonga tempo.\n" #: src/post/audio/stretch.c msgid "Time stretch by a given factor, optionally preserving pitch" msgstr "" #: src/post/audio/upmix.c msgid "" "Upmix functions. e.g. Take stereo input and produce Surround 5.1 output.\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" msgstr "" #: src/post/audio/upmix.c msgid "upmix" msgstr "" #: src/post/audio/upmix_mono.c msgid "" "This filter will upmix a mono stream to stereo, by duplicating channels. " "Alternatively, one may use this plugin to listen just one channel of a given " "stream.\n" msgstr "" "Tiu ĉi filtrilo miksos unuofonian datumstrion en stereofonio, pere de " "duplikatado de la kanaloj. Alie, oni poas uzi tiun ĉi kromaĵon por aŭskulti " "nur unu kanalon de iu ajn havigita datumstrio.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing Mono to Stereo.\n" msgstr ": miksante de Unuofonio al Sterefonio.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": upmixing a single channel from original %d channel stream.\n" msgid_plural ": upmixing a single channel from original %d channels stream.\n" msgstr[0] ": miksante unuopan kanalon el originala datumstrio je %d kanalo.\n" msgstr[1] ": miksante unuopan kanalon el originala datumstrio je %d kanaloj.\n" #: src/post/audio/upmix_mono.c #, c-format msgid ": audio device not capable of AO_CAP_MODE_STEREO.\n" msgstr ": aŭdaparato ne kapablas uzi AO_CAP_MODE_STEREO.\n" #: src/post/audio/upmix_mono.c msgid "converts Mono into Stereo" msgstr "miksante de Unuofonio al Sterefonio" #: src/post/audio/volnorm.c msgid "" "Normalizes audio by maximizing the volume without distorting the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via the standard " "weighted mean over past samples (default); 2: use several samples to smooth " "the variations via the standard weighted mean over past samples.\n" msgstr "" #: src/post/audio/volnorm.c msgid "Normalize volume" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "" "Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable to high " "quality progressive DVD players and so called line-doublers, for use with " "computer monitors, projectors and other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been locked for " "this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films that " "have being converted to NTSC can be detected and intelligently reconstructed " "to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field to an unique " "frame for television quality and beyond. This feature will effetively double " "the frame rate, improving smoothness. Note, however, that full 59.94 FPS is " "not possible with plain 2.4 Linux kernel (that use a timer interrupt " "frequency of 100Hz). Newer RedHat and 2.6 kernels use higher HZ settings " "(512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material is " "detected, it is possible to reduce the frame rate to original rate used (24 " "FPS). This will make the frames evenly spaced in time, matching the speed " "they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag to " "indicate progressive material. This setting control whether we trust this " "flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has a very " "poor vertical chroma resolution. Upsampling the chroma for purposes of " "deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove the " "artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated by " "the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality and cpu " "usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" msgstr "" #: src/post/deinterlace/xine_plugin.c msgid "advanced deinterlacer plugin with pulldown detection" msgstr "" #: src/post/deinterlace/xine_plugin.c #, c-format msgid "tvtime: No deinterlacing methods available, exiting.\n" msgstr "" "tvtime: Neniu disponebla metodo de malplektado; do estas devige eliri.\n" #: src/post/goom/xine_goom.c msgid "What a GOOM" msgstr "" #: src/post/goom/xine_goom.c msgid "frames per second to generate" msgstr "kreotaj filmeroj por sekundo" #: src/post/goom/xine_goom.c msgid "" "With more frames per second, the animation will get smoother and faster, but " "will also require more CPU power." msgstr "" "Ju pli filmeroj por sekundo, des pli rapida kaj pli flua estos la animacio, " "sed ĝi necesos pli povumon de CPU." #: src/post/goom/xine_goom.c msgid "goom image width" msgstr "larĝo de goom-bildo" #: src/post/goom/xine_goom.c msgid "The width in pixels of the image to be generated." msgstr "Larĝo en bilderoj de la bildo kiu estos kreita." #: src/post/goom/xine_goom.c msgid "goom image height" msgstr "alto de goom-bildo" #: src/post/goom/xine_goom.c msgid "The height in pixels of the image to be generated." msgstr "Alto en bilderoj de la bildo kiu estos kreita." #: src/post/goom/xine_goom.c msgid "colour space conversion method" msgstr "metodo de kolor-konvertado" #: src/post/goom/xine_goom.c msgid "" "You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining." msgstr "" "Vi povas elekti metodon de kolor-konvertado kiu estas uzata far goom.\n" "La disponeblaj elektadoj devus estis mem-esplikantaj." #: src/post/mosaico/mosaico.c msgid "" "Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n" msgstr "" "MOSAICO kreas simplajn bildojn en bildefektoj.\n" "\n" "Parametoj\n" " pip_num: nombro da bildoj kies sekvantaj agordoj estas aplikendaj\n" " x: x-koordinato de maldekstr-supera angulo de bildo\n" " y: y-koordinato de maldekstr-supera angulo de bildo\n" " w: larĝo de la bildo\n" " h: alto de la bildo\n" #: src/post/mosaico/mosaico.c msgid "Mosaico is a picture in picture (pip) post plugin" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n" msgstr "" #: src/post/mosaico/switch.c msgid "" "Switch is a post plugin able to switch at any time between different streams" msgstr "" #: src/post/planar/boxblur.c msgid "" "Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" msgstr "" "Box blur malfokusas simple la bildon.\n" "\n" "Parametoj\n" " Radius: grado de filtrilo\n" " Power: ofteco de la aplikado de la filtrilo\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" #: src/post/planar/boxblur.c msgid "box blur filter from mplayer" msgstr "" #: src/post/planar/denoise3d.c msgid "" "This filter aims to reduce image noise producing smooth images and making " "still images really still (This should enhance compressibility.). It can be " "given from 0 to 3 parameters. If you omit a parameter, a reasonable value " "will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" msgstr "" #: src/post/planar/denoise3d.c msgid "3D Denoiser (variable lowpass filter)" msgstr "" #: src/post/planar/eq2.c msgid "" "Alternative software equalizer that uses lookup tables (very slow), allowing " "gamma correction in addition to simple brightness, contrast and saturation " "adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all gamma values " "are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast (negative values " "result in a negative image), -1 - 1 for brightness and 0 - 3 for " "saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" msgstr "" #: src/post/planar/eq2.c msgid "Software video equalizer" msgstr "" #: src/post/planar/eq.c msgid "" "Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and contrast " "controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set these " "parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" msgstr "" #: src/post/planar/eq.c msgid "soft video equalizer" msgstr "" #: src/post/planar/expand.c msgid "" "The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars on " "the top and bottom of the frame. This allows us to shift overlays down into " "the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" msgstr "" #: src/post/planar/expand.c msgid "" "add black borders to top and bottom of video to expand it to 4:3 aspect ratio" msgstr "" #: src/post/planar/fill.c msgid "crops left and right of video to fill 4:3 aspect ratio" msgstr "" #: src/post/planar/invert.c msgid "inverts the colours of every video frame" msgstr "" #: src/post/planar/noise.c msgid "" "Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel (0-100, default: " "8)\n" " chroma_strength: strength of noise added to chroma channel (0-100, " "default: 5)\n" " quality: quality level of the noise. fixed: constant noise pattern; " "temporal: noise pattern changes between frames; averaged temporal: smoother " "noise pattern that changes between frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. (default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/noise.c msgid "Adds noise" msgstr "" #: src/post/planar/pp.c msgid "" "FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n" msgstr "" "Kromaĵo de FFmpeg libpostprocess.\n" "\n" "Parametoj\n" "\n" #: src/post/planar/pp.c msgid "" "\n" "* libpostprocess (C) Michael Niedermayer\n" msgstr "" #: src/post/planar/pp.c msgid "plugin for ffmpeg libpostprocess" msgstr "" #: src/post/planar/unsharp.c msgid "" "Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, odd sized in both " "directions (min = 3x3, max = 13x11 or 11x13, usually something between 3x3 " "and 7x7) and the relative amount of sharpness/blur to add to the image (a " "sane range should be -1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 " "sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" msgstr "" #: src/post/planar/unsharp.c msgid "unsharp mask & gaussian blur" msgstr "" #: src/post/visualizations/fftgraph.c msgid "fftgraph Visualization Post Plugin" msgstr "" #: src/post/visualizations/fftscope.c msgid "FFT Scope" msgstr "" #: src/post/visualizations/oscope.c msgid "Oscilloscope" msgstr "" #: src/post/visualizations/tdaudioanalyzer.c msgid "Time Domain Audio Analyzer Visualisation" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "font for external subtitles" msgstr "tiparo por eksteraj surskribaĵoj" #: src/spu_dec/cmml_decoder.c msgid "subtitle vertical offset (relative window size)" msgstr "vertikala deŝovo de surskribaĵoj (rilata al fenestrogrando)" #: src/spu_dec/cmml_decoder.c msgid "CMML subtitle decoder plugin" msgstr "" #: src/spu_dec/cmml_decoder.c msgid "encoding of subtitles" msgstr "kodo de surskribaĵoj" #: src/spu_dec/spu_decoder.c msgid "DVD/VOB SPU decoder plugin" msgstr "" #: src/spu_dec/spudvb_decoder.c #, fuzzy msgid "DVB subtitle decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "default duration of subtitle display in seconds" msgstr "defaŭlta pludaŭro de surskribaĵoj en sekundoj" #: src/spu_dec/spudvb_decoder.c src/spu_dec/sputext_demuxer.c msgid "" "Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over." msgstr "" "Kelkaj formatoj de surskribaĵoj ne havas pludaŭro por ĉiu surskribaĵo. Do, " "vi povas ĉi tie agordi defaŭltan pludaŭro. Agordante je nulo, la surskribaĵo " "pludaŭras ĝis anstataŭigo de ĝi per la sekvanta." #: src/spu_dec/sputext_decoder.c msgid "external subtitle decoder plugin" msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle size" msgstr "grando de surskribaĵoj" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the subtitle size here. The setting will be evaluated " "relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "subtitle vertical offset" msgstr "vertikala deŝovo de surskribaĵoj" #: src/spu_dec/sputext_decoder.c msgid "" "You can adjust the vertical position of the subtitle. The setting will be " "evaluated relative to the window size." msgstr "" #: src/spu_dec/sputext_decoder.c msgid "font for subtitles" msgstr "tiparo por surskribaĵoj" #: src/spu_dec/sputext_decoder.c msgid "A font from the xine font directory to be used for the subtitle text." msgstr "" "Tipardosiero (el dosierujo de tiparoj de xine) uzenda por surskribaĵoj." #: src/spu_dec/sputext_decoder.c msgid "An outline font file (e.g. a .ttf) to be used for the subtitle text." msgstr "Ekstera tipardosiero (ekz. .ttf) uzenda por surskribaĵoj." #: src/spu_dec/sputext_decoder.c msgid "whether to use a freetype font" msgstr "uzu libertiparan tiparon, se ĝi estas farebla" #: src/spu_dec/sputext_decoder.c msgid "encoding of the subtitles" msgstr "kodo de surskribaĵoj" #: src/spu_dec/sputext_decoder.c msgid "" "The encoding of the subtitle text in the stream. This setting is used to " "render non-ASCII characters correctly. If non-ASCII characters are not " "displayed as you expect, ask the creator of the subtitles what encoding was " "used." msgstr "" "Kodo de tekston de surskribaĵoj en datumstrio. Tio estas uzata por taŭge " "bildigi ne-ASCII-ajn tipojn. Se ne-ASCII-ajn tipojn ne estas vidigitaj kiel " "vi supozas, demandu al kreanto de surskribaĵoj pri uzata kodo." #: src/spu_dec/sputext_decoder.c msgid "use unscaled OSD if possible" msgstr "uzu neskalitan OSD, se ĝi estas farebla" #: src/spu_dec/sputext_decoder.c msgid "" "The unscaled OSD will be rendered independently of the video frame and will " "always be sharp, even if the video is magnified. This will look better, but " "does not work with all graphics hardware. The alternative is the scaled OSD, " "which will become blurry, if you enlarge a low resolution video to " "fullscreen, but it works with all graphics cards." msgstr "" "La neskalita OSD estos vidigita sendepende de filmero kaj ĝi estas ĉiam " "neta, ankaŭ se la video estas grandigita. Tio ŝajnas bona, sed ĝi ne laboras " "kun ĉiu grafika hardvaro. Alternativo estas skalita OSD, kiu iĝas " "malfokusigita, se vi igas tutekrana malaltkvalitan videon, sed ĝi laboras " "kun ĉiu grafika karto." #: src/spu_dec/sputext_demuxer.c msgid "sputext demuxer plugin" msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "display closed captions in MPEG-2 streams" msgstr "vidigu fermitajn ĉapitrojn en MPEG-2 datumstrioj" #: src/spu_dec/xine_cc_decoder.c msgid "" "Closed Captions are subtitles mostly meant to help the hearing impaired." msgstr "" "Fermitaj Ĉapitroj estas surskribaĵojn kutime uzatajn por helpi surdulojn." #: src/spu_dec/xine_cc_decoder.c msgid "closed-captioning foreground/background scheme" msgstr "skemo de fonaj/malfonaj koloroj por fermitaj ĉapitroj" #: src/spu_dec/xine_cc_decoder.c msgid "Choose your favourite rendering of the closed captions." msgstr "Elektu vian favoratan bildigon por fermitaj ĉapitroj." #: src/spu_dec/xine_cc_decoder.c msgid "standard closed captioning font" msgstr "defaŭlta tiparo de fermitaj ĉapitroj" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for standard closed captions text." msgstr "Elektu tiparon por defaŭlta teksto de fermitaj ĉapitroj." #: src/spu_dec/xine_cc_decoder.c msgid "italic closed captioning font" msgstr "kursivo por fermitaj ĉapitroj" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font for italic closed captions text." msgstr "Elektu tiparon por kursiva teksto de fermitaj ĉapitroj" #: src/spu_dec/xine_cc_decoder.c msgid "closed captioning font size" msgstr "tipargrando por fermitaj ĉapitroj" #: src/spu_dec/xine_cc_decoder.c msgid "Choose the font size for closed captions text." msgstr "Elektu tipargrandon por teksto de fermitaj ĉapitroj" #: src/spu_dec/xine_cc_decoder.c msgid "center-adjust closed captions" msgstr "centrigo de fermitaj ĉapitroj" #: src/spu_dec/xine_cc_decoder.c msgid "" "When enabled, closed captions will be positioned by the center of the " "individual lines." msgstr "" #: src/spu_dec/xine_cc_decoder.c msgid "closed caption decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/vdr/input_vdr.c #, c-format msgid "%s: input event write: %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: buffer_pool_alloc() failed!\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: shutting down rpc thread (timeout: %d ms) ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: cancelling rpc thread in function %d...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: joining rpc thread ...\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: rpc thread joined.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to open '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "timeout expired during setup phase" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to read '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to create socket for port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to connect to port %d (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: socket opening (port %d) successful, fd = %d\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to vdr.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: failed to resolve hostname '%s' (%s)\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: connecting to all sockets (port %d .. %d) was successful.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "" "%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or " "netvdr://host:port where ':port' is optional.\n" msgstr "" #: src/vdr/input_vdr.c #, c-format msgid "%s: can't create new thread (%s)\n" msgstr "" #: src/vdr/input_vdr.c msgid "VDR display device plugin" msgstr "" #: src/vdr/post_vdr_audio.c msgid "modifies every audio frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c msgid "modifies every video frame as requested by VDR" msgstr "" #: src/vdr/post_vdr_video.c #, c-format msgid ": osd: (%d, %d)-(%d, %d)@%lg\n" msgstr "" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: error doing ByteRun1 decompression\n" msgstr "bitplane: eraro dum malkumpremado de ByteRun1\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 1 is not supported at the moment\n" msgstr "bitplane: Anim Opt 1 nun ne estas ankoraŭ subtenita\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim Opt 2 is not supported at the moment\n" msgstr "bitplane: Anim Opt 2 nun ne estas ankoraŭ subtenita\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: Anim ASCIIJ is not supported at the moment\n" msgstr "bitplane: Anim ASCIIJ nun ne estas ankoraŭ subtenita\n" #: src/video_dec/bitplane.c #, c-format msgid "bitplane: This anim-type is not supported at the moment\n" msgstr "bitplane: Tiu ĉi anim-speco nun ne estas ankoraŭ subtenita\n" #: src/video_dec/bitplane.c msgid "Raw bitplane video decoder plugin" msgstr "" #: src/video_dec/gdkpixbuf.c #, fuzzy msgid "gdk-pixbuf image video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/video_dec/image.c #, fuzzy msgid "image video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/video_dec/libaom.c msgid "AV1 (libaom) video decoder" msgstr "" #: src/video_dec/libjpeg.c msgid "JPEG image video decoder plugin" msgstr "" #: src/video_dec/libjpeg.c msgid "allow downscaling of JPEG images (an alternative is to crop)" msgstr "" #: src/video_dec/libjpeg.c msgid "" "If enabled, you allow xine to downscale JPEG images so that those can be " "viewed with your graphics hardware. If scaling is disabled, images will be " "cropped." msgstr "" #: src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c #: src/video_dec/libmpeg2/xine_mpeg2_decoder.c #, fuzzy msgid "mpeg2 based video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/video_dec/libopenhevc.c #, fuzzy msgid "HEVC video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/video_dec/libvdpau/alterh264_decode.c msgid "vdpau: reopen decoder on seek" msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "Some drivers crash without this." msgstr "" #: src/video_dec/libvdpau/alterh264_decode.c msgid "" "Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_h264.c msgid "" "H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg12.c msgid "" "MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_mpeg4.c msgid "" "MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvdpau/vdpau_vc1.c msgid "" "VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau." msgstr "" #: src/video_dec/libvpx.c msgid "WebM (VP8/VP9) video decoder plugin" msgstr "" #: src/video_dec/mmal.c #, fuzzy msgid "mmal-based HW video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/video_dec/rgb.c #, fuzzy msgid "Raw RGB video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/video_dec/yuv.c #, fuzzy msgid "Raw YUV video decoder plugin" msgstr "tipargrando por fermitaj ĉapitroj" #: src/video_out/color_matrix.c msgid "Output colour matrix" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be calculated.\n" "\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n" "\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n" "\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n" "\n" msgstr "" #: src/video_out/color_matrix.c msgid "Output colour range" msgstr "" #: src/video_out/color_matrix.c msgid "" "Tell how output colours should be ranged.\n" "\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n" "\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n" "\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n" "\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "Lock X display during whole frame output." msgstr "" #: src/video_out/opengl/xine_glx.c msgid "This sometimes reduces system load and jitter.\n" msgstr "" #: src/video_out/opengl/xine_glx.c msgid "GL provider (GLX)" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "" "Enable VAAPI video decoding with any video output driver. When disabled, " "only vaapi video output driver uses VAAPI accelerated decoding. Currently " "only opengl2 video output driver supports this." msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c src/video_out/video_out_vaapi.c msgid "vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )" msgstr "" #: src/video_out/vaapi/xine_hw_frame_vaapi.c msgid "VAAPI frame provider" msgstr "" #: src/video_out/video_out_aa.c msgid "xine video output plugin using the ascii-art library" msgstr "videoeliga kromaĵo de xine uzas bibliotekon de AsCii Art" #: src/video_out/video_out_caca.c msgid "xine video output plugin using the Color AsCii Art library" msgstr "videoeliga kromaĵo de xine uzas bibliotekon de Color AsCii Art" #: src/video_out/video_out_directfb.c msgid "video layer buffering mode" msgstr "moduso de bufrado por videa tavolo" #: src/video_out/video_out_directfb.c msgid "" "Select the buffering mode of the output layer. Double or triple buffering " "give a smoother playback, but consume more video memory." msgstr "" #: src/video_out/video_out_directfb.c msgid "wait for vertical retrace" msgstr "atendu vertikalan redesegnadon" #: src/video_out/video_out_directfb.c msgid "" "Enable synchronizing the update of the video image to the repainting of the " "entire screen (\"vertical retrace\")." msgstr "" #: src/video_out/video_out_directfb.c msgid "enable video colour key" msgstr "ebligu videan kolorŝlosilon" #: src/video_out/video_out_directfb.c msgid "" "Enable using a colour key to tell the graphics card where to overlay the " "video image." msgstr "" #: src/video_out/video_out_directfb.c msgid "video colour key" msgstr "videa kolorŝlosilo" #: src/video_out/video_out_directfb.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "" "The colour key is used to tell the graphics card where to overlay the video " "image. Try different values, if you experience windows becoming transparent." msgstr "" #: src/video_out/video_out_directfb.c msgid "flicker filtering" msgstr "filtrilo kontraŭ tremo" #: src/video_out/video_out_directfb.c msgid "Enable Flicker Filetring for a smooth output on an interlaced display." msgstr "" #: src/video_out/video_out_directfb.c msgid "field parity" msgstr "egaleco de kampo" #: src/video_out/video_out_directfb.c msgid "" "For an interlaced display, enable controlling the field parity (\"none" "\"=disabled)." msgstr "" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware subpicture acceleration.\n" msgstr "video_out_directfb: uzante hardvaran akceladon de sub-bildoj.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer supports video output.\n" msgstr "video_out_directfb: tavolo subtenas videan eligon.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YV12!\n" msgstr "video_out_directfb: la tavolo ne subtenas YV12!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support YUY2!\n" msgstr "video_out_directfb: la tavolo ne subtenas YUY2!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb:need at least DirectFB 0.9.25 to play on this layer!\n" msgstr "" "video_out_directfb: almenaŭ DirectFB 0.9.25 estas necesa por legi tiun ĉi " "tavolon!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support buffermode %d!\n" msgstr "video_out_directfb: tavolo ne subtenas la moduson de bufro %d!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: layer doesn't support options 0x%08x!\n" msgstr "video_out_directfb: tavolo ne subtenas opcion 0x%08x!\n" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using hardware accelerated image scaling.\n" msgstr "video_out_directfb: uzante skaladon hardvare akcelitan.\n" #: src/video_out/video_out_directfb.c #, c-format msgid "" "video_out_directfb: image scaling with deinterlacing is hardware " "accelerated.\n" msgstr "" #: src/video_out/video_out_directfb.c msgid "video layer id (auto: -1)" msgstr "ID de videotavolo (auto: -1)" #: src/video_out/video_out_directfb.c msgid "Select the video output layer by its id." msgstr "Elektu videoeligan tavolon per sia ID" #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: using display layer #%d.\n" msgstr "video_out_directfb: uzante vidigantan tavolon #%d.\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB." msgstr "videoeliga xine-kromaĵo uzas DirectFB." #: src/video_out/video_out_directfb.c #, c-format msgid "video_out_directfb: no usable display layer was found!\n" msgstr "video_out_directfb: neniu vidigantan tavolon estis trovita!\n" #: src/video_out/video_out_directfb.c msgid "xine video output plugin using DirectFB under XDirectFB." msgstr "videoeliga xine-kromaĵo uzas DirectFB sub XDirectFB." #: src/video_out/video_out_directx.c msgid "HW acceleration level" msgstr "" #: src/video_out/video_out_directx.c msgid "" "Possible values (default full):\n" "\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration" msgstr "" #: src/video_out/video_out_directx.c msgid "xine video output plugin for win32 using directx" msgstr "videoeliga kromaĵo de xine por win32 uzas directx" #: src/video_out/video_out_fb.c #, c-format msgid "" "video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n" msgstr "" "video_out_fb: estas subtenita nur enpakigita verkoloro/rektkoloro (%d).\n" " Kontrolu per 'fbset -i' aŭ provu 'fbset -depth 16'.\n" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "framebuffer device name" msgstr "nomo de kvadrobrufrilo" #: src/video_out/video_out_fb.c src/video_out/video_out_vidix.c msgid "" "Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, " "xine can be used to fill this file with arbitrary content. So you should be " "careful that the value you enter really is a proper framebuffer device." msgstr "" #: src/video_out/video_out_fb.c #, c-format msgid "%s: Your video mode was not recognized, sorry.\n" msgstr "%s: Videomoduso ne estis rekonita, mi bedaŭras :-(\n" #: src/video_out/video_out_fb.c #, c-format msgid "%s: %d video RAM buffers are available.\n" msgstr "%s: %d videaj RAM-bufroj estas disponeblaj.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n" msgstr "" "ATENTU: %s: la nulkopiaj bufroj estas MALEBLIGITAJ ĉar estas nur %d bufroj\n" " do ili estas malpli ol rekomenditaj %d bufroj. Malpliigo de " "kadrobufra \n" " difino povus helpi.\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n" msgstr "" "ATENTU: %s: la nulkopiaj bufroj estas MALEBLIGITAJ ĉar zorgilo de kerno\n" " ne subtenas delokadon de ekrano (uzata por inversigoj de filmeroj).\n" #: src/video_out/video_out_fb.c #, c-format msgid "" "WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n" "\n" msgstr "" "ATENTU: %s: nuna profundeco por ekranbloko estas %d. Por havi pli bonan " "performancon, \n" "oni rekomendas profundecon je 16 bpp!\n" "\n" #: src/video_out/video_out_fb.c msgid "Xine video output plugin using the Linux frame buffer device" msgstr "videoeliga kromaĵo de xine uzas kadrobufrilon de Linukso" #: src/video_out/video_out_mmal.c #, fuzzy msgid "xine video output plugin using MMAL" msgstr "videoeliga xine-kromaĵo uzas DirectFB." #: src/video_out/video_out_none.c msgid "xine video output plugin which displays nothing" msgstr "videoeliga xine-kromaĵo kiu vidigas nenion" #: src/video_out/video_out_opengl2.c msgid "opengl2: use a bicubic algo to scale the video" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "Set to true if you want bicubic scaling.\n" "\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "opengl2: video scale mode" msgstr "" #: src/video_out/video_out_opengl2.c msgid "" "0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n" "\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n" "\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n" "\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n" msgstr "" #: src/video_out/video_out_opengl2.c msgid "xine video output plugin using opengl 2.0" msgstr "videoeliga xine-kromaĵo uzas OpenGL 2.0." #: src/video_out/video_out_opengl.c msgid "OpenGL renderer" msgstr "Bildigo de OpenGL" #: src/video_out/video_out_opengl.c msgid "" "The OpenGL plugin provides several render modules:\n" "\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured " "slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n" "\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured " "slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a " "textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n" "\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n" "\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)" msgstr "" #: src/video_out/video_out_opengl.c msgid "OpenGL minimum framerate" msgstr "Minimuma filmerkvanto por OpenGL" #: src/video_out/video_out_opengl.c msgid "" "Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n" msgstr "" "Minimuma filmerkvanto por animacioj.\n" "Ĝi estas ignorita por statikaĵoj.\n" #: src/video_out/video_out_opengl.c src/video_out/video_out_vidix.c #: src/video_out/xv_common.h msgid "enable double buffering" msgstr "ebligu duoblan bufradon" #: src/video_out/video_out_opengl.c msgid "" "For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact." msgstr "" #: src/video_out/video_out_opengl.c msgid "xine video output plugin using the OpenGL 3D graphics API" msgstr "videoeliga kromaĵo de xine uzas 3D-grafikan API de OpenGL" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx32: Error: estas neeble preni desegnabla DGA por videofenestro\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: ioctl failed, bad device (%s)\n" msgstr "video_out_pgx32: Eraro: ioctl malsukcesis, nevalida aparato (%s)\n" #: src/video_out/video_out_pgx32.c #, c-format msgid "video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n" msgstr "video_out_pgx32: Eraro: '%s' ne estas pgx32-kadrobufrilo\n" #: src/video_out/video_out_pgx32.c msgid "xine video output plugin for Sun PGX32 framebuffers" msgstr "" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't grab DGA drawable for video window\n" msgstr "" "video_out_pgx64: Eraro: estas neeble preni DGA desegneblan por " "videofenestro\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: can't open framebuffer device '%s'\n" msgstr "video_out_pgx64: Eraro: estas neeble malfermi kadrobufrilon '%s'\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n" msgstr "" "video_out_pgx64: Eraro: ioctl malsukcesis (VIS_GETIDENTIFIER), nevalida " "aparato (%s)\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n" msgstr "" "video_out_pgx64: Eraro: '%s' ne estas xvr100/pgx64/pgx24 kadrobufrilo\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "" "video_out_pgx64: Error: video overlay on this screen is already in use\n" msgstr "video_out_pgx64: Eraro: videa surmeto sur ĉi ekrano estas jam uzata\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: unable to set window properties\n" msgstr "video_out_pgx64: Eraro: mi estas nekapabla agordi fenestron\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, multi-buffering disabled\n" msgstr "" "video_out_pgx64: Atentu: eta videomemoro, plur-bufrado estas malebligita\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: insuffucient video memory\n" msgstr "video_out_pgx64: Eraro: nesufiĉa videomemoro\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Warning: low video memory, double-buffering disabled\n" msgstr "" "video_out_pgx64: Atentu: eta videomemoro, duobla-bufrado estas malebligita\n" #: src/video_out/video_out_pgx64.c #, c-format msgid "video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n" msgstr "video_out_pgx64: Error: ioctl malsukcesis (FBIOGATTR)\n" #: src/video_out/video_out_pgx64.c src/video_out/xv_common.h msgid "video overlay colour key" msgstr "kolorŝlosilo de videa surmeto" #: src/video_out/video_out_pgx64.c msgid "" "The colour key is used to tell the graphics card where it can overlay the " "video image. Try using different values if you see the video showing through " "other windows." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable chroma keying" msgstr "ebligu ŝlosiligon de kromata gamo" #: src/video_out/video_out_pgx64.c msgid "" "Draw OSD graphics on top of the overlay colour key rather than blend them " "into each frame." msgstr "" #: src/video_out/video_out_pgx64.c msgid "enable multi-buffering" msgstr "ebligu plur-bufradon" #: src/video_out/video_out_pgx64.c msgid "" "Multi buffering increases performance at the expense of using more graphics " "memory." msgstr "" #: src/video_out/video_out_pgx64.c msgid "xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers" msgstr "" #: src/video_out/video_out_raw.c msgid "xine video output plugin passing raw data to supplied callback" msgstr "" #: src/video_out/video_out_sdl.c msgid "use hardware acceleration if available" msgstr "uzu hardvaran akcelado se ĝi estas disponebla" #: src/video_out/video_out_sdl.c msgid "" "When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong." msgstr "" #: src/video_out/video_out_sdl.c #, c-format msgid "sdl has to emulate a 16 bit surfaces, that will slow things down.\n" msgstr "sdl devas imiti 16-bitan surfacon, do tio malrapidigos ĉion.\n" #: src/video_out/video_out_sdl.c #, c-format msgid "video_out_sdl: fullscreen mode is NOT supported\n" msgstr "video_out_sdl: tutekrana moduso NE estas subtenita\n" #: src/video_out/video_out_sdl.c msgid "xine video output plugin using the Simple Direct Media Layer" msgstr "videoeliga kromaĵo de xine uzas Simple Direct Media Layer" #: src/video_out/video_out_stk.c msgid "xine video output plugin using the Libstk Surface Set-top Toolkit" msgstr "videoeliga kromaĵo de xine uzas Libstk Surface Set-top Toolkit" #: src/video_out/video_out_vaapi.c #, c-format msgid "" "video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n" msgstr "" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "default number of video frames" msgstr "defaŭlta nombro da filmeroj" #: src/video_out/video_out_vaapi.c src/video_out/video_out_vdpau.c #: src/xine-engine/video_out.c msgid "" "The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl output rendering" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: opengl rendering tfp" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd width workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: VDR osd height workaround." msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla " "(anamorphic)" msgstr "" #: src/video_out/video_out_vaapi.c msgid "vaapi: swap UV planes." msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "VAAPI colour conversion method" msgstr "metodo de kolor-konvertado" #: src/video_out/video_out_vaapi.c msgid "" "How to handle colour conversion in VAAPI:\n" "\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange " "video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by " "modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n" "\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n" msgstr "" #: src/video_out/video_out_vaapi.c msgid "VAAPI overlay mode" msgstr "" #: src/video_out/video_out_vaapi.c msgid "" "How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n" msgstr "" #: src/video_out/video_out_vaapi.c #, fuzzy msgid "xine video output plugin using VAAPI" msgstr "videoeliga xine-kromaĵo uzas DirectFB." #: src/video_out/video_out_vdpau.c msgid "maximum number of output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "The maximum number of video output surfaces buffered for reuse" msgstr "" #: src/video_out/video_out_vdpau.c msgid "default length of display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "The default number of video output surfaces to create for the display queue" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: HD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: SD deinterlace method" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Scaling Quality" msgstr "" #: src/video_out/video_out_vdpau.c msgid "Scaling Quality Level" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: Try to recreate progressive frames from pulldown material" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable deinterlacing when progressive_frame flag is set" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: disable advanced deinterlacers chroma filter" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Setting to true may help if your video card isn't able to run advanced " "deinterlacers.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: colour of none video area in output window" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels " "outside the video age slower than the pixels in the active area. Setting a " "different background colour (e. g. 8421504) makes all pixels age similarly. " "The number to enter for a certain colour can be derived from its 6 digit " "hexadecimal RGB value.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: restrict enabling video properties for SD video only" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "none\n" "No restrictions\n" "\n" "noise\n" "Restrict noise reduction property.\n" "\n" "sharpness\n" "Restrict sharpness property.\n" "\n" "noise+sharpnessRestrict noise and sharpness properties.\n" "\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: take snapshots as shown on the screen" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "vdpau: work around broken video mixer overlays" msgstr "" #: src/video_out/video_out_vdpau.c msgid "" "Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n" msgstr "" #: src/video_out/video_out_vdpau.c msgid "xine video output plugin using VDPAU hardware acceleration" msgstr "videoeliga xine-kromaĵo uzas VDPAU." #: src/video_out/video_out_vidix.c msgid "red intensity" msgstr "ruĝintenso" #: src/video_out/video_out_vidix.c msgid "The intensity of the red colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "green intensity" msgstr "verdintenso" #: src/video_out/video_out_vidix.c msgid "The intensity of the green colour components." msgstr "" #: src/video_out/video_out_vidix.c msgid "blue intensity" msgstr "bluintenso" #: src/video_out/video_out_vidix.c msgid "The intensity of the blue colour components." msgstr "" #: src/video_out/video_out_vidix.c src/video_out/xv_common.h msgid "" "Double buffering will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts, but will use more graphics memory." msgstr "" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yuy2 format\n" msgstr "video_out_vidix: adaptilo subtenas formaton yuy2\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: adaptor supports the yv12 format\n" msgstr "video_out_vidix: adaptilo subtenas formaton yv12\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: You have wrong version of VIDIX library\n" msgstr "video_out_vidix: Erara versio de VIDIX-biblioteko\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: Couldn't find working VIDIX driver\n" msgstr "" "video_out_vidix: estas neeble trovi funkcikapablan zorgilon por VIDIX\n" #: src/video_out/video_out_vidix.c #, c-format msgid "video_out_vidix: using driver: %s by %s\n" msgstr "video_out_vidix: uzante zorgilon: %s far de %s\n" #: src/video_out/video_out_vidix.c msgid "video overlay colour key red component" msgstr "ruĝa komponanto de kolorŝlosilo por videa surmeto" #: src/video_out/video_out_vidix.c msgid "video overlay colour key green component" msgstr "verda komponanto de kolorŝlosilo por videa surmeto" #: src/video_out/video_out_vidix.c msgid "video overlay colour key blue component" msgstr "blua komponanto de kolorŝlosilo por videa surmeto" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for x11" msgstr "videoeliga kromaĵo de xine uzas libvidix por x11" #: src/video_out/video_out_vidix.c msgid "xine video output plugin using libvidix for linux frame buffer" msgstr "videoeliga kromaĵo de xine uzas libvidix por linuksa kvadrobrufrilo" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: %s: allocating image\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: => not using MIT Shared Memory extension.\n" msgstr "%s: => ne uzante etendilon de MIT Shared Memory.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error (address error) when allocating image \n" msgstr "%s: eraro de opuza memoro (eraro de adreso) kiam oni nomumas bildon \n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xcbxv.c #: src/video_out/video_out_xshm.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: x11 error during shared memory XImage creation\n" msgstr "" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "" "\n" "\n" "WARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n" "\n" msgstr "" "\n" "\n" "ATENTU: nuna profundeco por ekranbloko estas %d. Por havi pli bonan " "performancon, \n" "oni rekomendas profundecon je 16 bpp!\n" "\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: MIT shared memory extension not present on display.\n" msgstr "%s: MIT-etendilo por opuza memoro neĉeestas en ekranbloko.\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c #, c-format msgid "%s: your video mode was not recognized, sorry :-(\n" msgstr "%s: videomoduso ne estis rekonita, mi bedaŭras :-(\n" #: src/video_out/video_out_xcbshm.c src/video_out/video_out_xshm.c msgid "xine video output plugin using the MIT X shared memory extension" msgstr "videoeliga kromaĵo de xine uzas MIT-etendilon por opuza memoro" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage returned a zero size\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: shared memory error in shmget: %s\n" msgstr "" #: src/video_out/video_out_xcbxv.c #, c-format msgid "%s: shared memory error (address error)\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xvmc.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: this adaptor supports the %s format.\n" msgstr "%s: tiu ĉi adaptilo subtenas formaton %s.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: Xv extension not present.\n" msgstr "%s: Xv-etendilo neĉeestas.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: could not open Xv port %lu - autodetecting\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "%s: no available ports of type \"%s\", defaulting...\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n" msgstr "" "%s: Xv-etendilo ĉeestas sed estas neeble trovi uzeblan yuv12 pordon.\n" " Ŝajnas ke la zorgilo de la grafika hardvaro ne subtenas Xv!\n" #: src/video_out/video_out_xcbxv.c #, c-format msgid "" "%s: using Xv port %d from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: uzante Xv-pordon %d el adaptilo %s por konverto de hardvara kolorspaco " "kaj skalado.\n" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "enable vblank sync" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "This option will synchronize the update of the video image to the repainting " "of the entire screen (\"vertical retrace\"). This eliminates flickering and " "tearing artifacts. On nvidia cards one may also need to run \"nvidia-settings" "\" and choose which display device to sync to under the XVideo Settings tab" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Fullrange colour emulation" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "" "Emulate fullrange colour by modifying brightness/contrast/saturation " "settings.\n" "\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n" "\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n" "\n" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Force emulating yuy2" msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c msgid "Debug." msgstr "" #: src/video_out/video_out_xcbxv.c src/video_out/video_out_xv.c #: src/video_out/video_out_xxmc.c msgid "xine video output plugin using the MIT X video extension" msgstr "videoeliga kromaĵo de xine uzas videan etendilon MIT X" #: src/video_out/video_out_xshm.c #, c-format msgid "%s: shared memory error when allocating image\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "%s: XvShmCreateImage failed\n" msgstr "" #: src/video_out/video_out_xv.c src/video_out/video_out_xxmc.c #, c-format msgid "" "%s: using Xv port %ld from adaptor %s for hardware colour space conversion " "and scaling.\n" msgstr "" "%s: uzante Xv-pordon %ld el adaptilo %s por konverto de hardvara kolorspaco " "kaj skalado.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "video_out_xvmc: XvMC extension not present.\n" msgstr "video_out_xvmc: etendilo de XvMC neĉeestas.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 " "port.\n" msgstr "" "video_out_xvmc: la Xv-etendilo ĉeestas sed estas neeble trovi uzeblan yuv12 " "pordon.\n" #: src/video_out/video_out_xvmc.c #, c-format msgid "" "video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n" msgstr "" "video_out_xvmc: uzante Xv-pordon %ld el adaptilo %s\n" " por hardvara konverto de kolorspaco kaj skalado\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " idct and motion compensation acceleration \n" msgstr " idct kaj kompensado por akcelo de movo \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " motion compensation acceleration only\n" msgstr " nur kompensado por akcelo de movo\n" #: src/video_out/video_out_xvmc.c #, c-format msgid " no XvMC support \n" msgstr " neniu XvMC-subteno \n" #: src/video_out/video_out_xvmc.c #, c-format msgid " With Overlay = %d; UnsignedIntra = %d.\n" msgstr " Kun Surmeto = %d; NesignitaIntra = %d.\n" #: src/video_out/video_out_xvmc.c msgid "xine video output plugin using the XvMC X video extension" msgstr "videoeliga kromaĵo uzas videan etendilon de XvMC X" #: src/video_out/video_out_xxmc.c msgid "Make XvMC allocate more frames for better buffering." msgstr "Igu XvMc disponiganta de pluraj filemroj por la plej bona brufrado" #: src/video_out/video_out_xxmc.c msgid "" "Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Unichrome cpu save" msgstr "Konservo de Unichrome CPU" #: src/video_out/video_out_xxmc.c msgid "" "Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Fix buggy NVIDIA XvMC subpicture colours" msgstr "Koretku cimajn colorojn de sub-bildoj por NVIDIA-XvMC" #: src/video_out/video_out_xxmc.c msgid "" "There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n" msgstr "" "Estas cimo en XvMC-biblioteko de NVIDIA kiu en OSD igu ruĝa la bluan " "koloron\n" "kaj inverse. Tiu ĉi opcio havigas laboradon.\n" #: src/video_out/video_out_xxmc.c msgid "Use bob as accelerated deinterlace method." msgstr "Uzu metodon nomitan bob kiel metodo de akcelita malplektado." #: src/video_out/video_out_xxmc.c msgid "" "When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing for progressive frames." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n" msgstr "" #: src/video_out/video_out_xxmc.c msgid "Don't use bob deinterlacing while a scaled OSD is active." msgstr "" #: src/video_out/video_out_xxmc.c msgid "" "Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n" msgstr "" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: XShape extension not available. unscaled overlay disabled.\n" msgstr "" "x11osd: XShape-etendilo ne estas disponebla. do neskalita surmeto estas " "malebligita.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating window. unscaled overlay disabled.\n" msgstr "" "x11osd: eraro dum kreado de fenestro, do neskalita surmeto estas " "malebligita.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: error creating pixmap. unscaled overlay disabled.\n" msgstr "" "x11osd: eraro dum kreado de bildermapo, do neskalita surmeto estas " "malebligita.\n" #: src/video_out/x11osd.c src/video_out/xcbosd.c #, c-format msgid "x11osd: unscaled overlay created (%s mode).\n" msgstr "x11osd: neskalita surmeto estas kreita (%s moduso).\n" #: src/video_out/xv_common.h msgid "autopaint colour key" msgstr "memkoloriĝanta kolorŝlosilo" #: src/video_out/xv_common.h msgid "Make Xv autopaint its colour key." msgstr "Igu XV-on memkoloriĝanta laŭ kolorŝlosilo" #: src/video_out/xv_common.h msgid "bilinear scaling mode" msgstr "bilineara moduso de skalo" #: src/video_out/xv_common.h msgid "" "Selects the bilinear scaling mode for Permedia cards. The individual values " "are:\n" "\n" "Permedia 2\n" "0 - disable bilinear filtering\n" "1 - enable bilinear filtering\n" "\n" "Permedia 3\n" "0 - disable bilinear filtering\n" "1 - horizontal linear filtering\n" "2 - enable full bilinear filtering" msgstr "" #: src/video_out/xv_common.h #, fuzzy msgid "Xv port number" msgstr "nevalida numero de ero" #: src/video_out/xv_common.h msgid "Selects the Xv port number to use (0 to autodetect)." msgstr "" #: src/video_out/xv_common.h msgid "pitch alignment workaround" msgstr "lanĉu lavoradon por enliinigo" #: src/video_out/xv_common.h msgid "Some buggy video drivers need a workaround to function properly." msgstr "" #: src/video_out/xv_common.h msgid "video display method preference" msgstr "" #: src/video_out/xv_common.h msgid "" "Selects which video output method is preferred. Detection is done using the " "reported Xv adaptor names.\n" "(Only applies when auto-detecting which Xv port to use.)" msgstr "" #: src/video_out/xv_common.h msgid "bicubic filtering" msgstr "filtrilo kontraŭ tremo" #: src/video_out/xv_common.h msgid "" "This option controls bicubic filtering of the video image. It may be used " "instead of, or as well as, xine's deinterlacers." msgstr "" #: src/xine-engine/alphablend.c msgid "disable exact alpha blending of overlays" msgstr "malebligu precizan alfa-miksadon de surmetoj" #: src/xine-engine/alphablend.c msgid "" "If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this " "option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well." msgstr "" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: no plugin available to handle '%s'\n" msgstr "audio_decoder: neniu disponebla kromaĵo por administi '%s'\n" #: src/xine-engine/audio_decoder.c #, c-format msgid "audio_decoder: error, unknown buffer type: %08x\n" msgstr "audio_decoder: eraro, nekonata speco de bufro: %08x\n" #: src/xine-engine/audio_decoder.c msgid "number of audio buffers" msgstr "nombro da bufroj de aŭdo" #: src/xine-engine/audio_decoder.c msgid "" "The number of audio buffers (each is 2k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/audio_out.c #, c-format msgid "" "audio_out: delay calculation impossible with an unavailable audio device\n" msgstr "" "audio_out: kalkulo de malfruo estas malebla kun nedisponebla aŭdaparato\n" #: src/xine-engine/audio_out.c #, c-format msgid "write to sound card failed. Assuming the device was unplugged.\n" msgstr "skribo en sonkarto malsukcesis. Ĉu estas la USB-aparato nekonektita?\n" #: src/xine-engine/audio_out.c #, c-format msgid "8 bits not supported by driver, converting to 16 bits.\n" msgstr "" "moduso de 8 bitoj ne estas subtenita de zorgiloj, konvertante en moduso de " "16 bitoj.\n" #: src/xine-engine/audio_out.c #, c-format msgid "mono not supported by driver, converting to stereo.\n" msgstr "unufonio ne estas subtenita de zorgiloj, konvertante en stereofonio.\n" #: src/xine-engine/audio_out.c #, c-format msgid "stereo not supported by driver, converting to mono.\n" msgstr "stereofonio ne estas subtenita de zorgiloj, konvertante en unufonio.\n" #: src/xine-engine/audio_out.c msgid "method to sync audio and video" msgstr "metodo de sinkronigo por aŭdo kaj video" #: src/xine-engine/audio_out.c msgid "" "When playing audio and video, there are at least two clocks involved: The " "system clock, to which video frames are synchronized and the clock in your " "sound hardware, which determines the speed of the audio playback. These " "clocks are never ticking at the same speed except for some rare cases where " "they are physically identical. In general, the two clocks will run drift " "after some time, for which xine offers two ways to keep audio and video " "synchronized:\n" "\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n" "\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer or " "shorter to compensate the audio drift error. This does not work for digital " "passthrough, where audio data is passed to an external decoder in digital " "form." msgstr "" #: src/xine-engine/audio_out.c msgid "a/v sync precision" msgstr "" #: src/xine-engine/audio_out.c msgid "" "Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance." msgstr "" #: src/xine-engine/audio_out.c msgid "enable resampling" msgstr "ebligu re-sampladon" #: src/xine-engine/audio_out.c msgid "" "When the sample rate of the decoded audio does not match the capabilities of " "your sound hardware, an adaptation called \"resampling\" is required. Here " "you can select, whether resampling is enabled, disabled or used " "automatically when necessary." msgstr "" #: src/xine-engine/audio_out.c msgid "always resample to this rate (0 to disable)" msgstr "re-sampligu ĉiam per tiu ĉi kvanto (0 por malebligi)" #: src/xine-engine/audio_out.c msgid "" "Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate." msgstr "" #: src/xine-engine/audio_out.c msgid "offset for digital passthrough" msgstr "deŝovo por diĝita rekta transiro" #: src/xine-engine/audio_out.c msgid "" "If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second." msgstr "" #: src/xine-engine/audio_out.c msgid "play audio even on slow/fast speeds" msgstr "ludu aŭdon ankaŭ se ĝi estas rapida aŭ malrapida" #: src/xine-engine/audio_out.c msgid "" "If you enable this option, the audio will be heard even when playback speed " "is different than 1X. Of course, it will sound distorted (lower/higher " "pitch). If want to experiment preserving the pitch you may try the 'stretch' " "audio post plugin instead." msgstr "" #: src/xine-engine/audio_out.c msgid "startup audio volume" msgstr "starta laŭteco" #: src/xine-engine/audio_out.c msgid "The overall audio volume set at xine startup." msgstr "Ĝenerala laŭteco kiu estos uzata dum preparado de xine." #: src/xine-engine/audio_out.c msgid "restore volume level at startup" msgstr "restarigu nivelon de laŭteco dum preparado" #: src/xine-engine/audio_out.c msgid "If disabled, xine will not modify any mixer settings at startup." msgstr "" "Se ĝi estas malebligita, xine ne povas ŝanĝi agordojn de miksilo dum " "preparado." #: src/xine-engine/audio_out.c #, c-format msgid "audio_out: sorry, this should not happen. please restart xine.\n" msgstr "audio_out: pardonu, tio ne devus okazi. bonvolu restartigi xine.\n" #: src/xine-engine/buffer.c #, c-format msgid "xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown video FourCC code %#x \"%s\"\n" msgstr "" #: src/xine-engine/buffer_types.c #, c-format msgid "%s: unknown audio format tag code %#x \"%s\"\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "The current config file has been modified by a newer version of xine." msgstr "" "La nuna dosiero de agordoj estas modifita far de pli nova versio de xine." #: src/xine-engine/configfile.c #, c-format msgid "Loaded configuration from file '%s'\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "Failed to load configuration from file '%s': %s\n" msgstr "" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: your configuration will not be saved\n" msgstr "configfile: ATENTU: via agordaĵo ne estos konservita\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: writing configuration to %s failed\n" msgstr "configfile: ATENTU: skribo de agordaĵo en %s malsukcesis\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: removing possibly broken config file %s\n" msgstr "" "configfile: ATENTU: formovovo de probable difektita dosiero de agordoj %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: WARNING: you should check the backup file %s\n" msgstr "configfile: ATENTU: kontrolu restaŭrdosieron %s\n" #: src/xine-engine/configfile.c #, c-format msgid "configfile: entry '%s' mustn't be modified from MRL\n" msgstr "configfile: ero '%s' ne devas esti modifita el MRL\n" #: src/xine-engine/demux.c #, c-format msgid "Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/demux.c #, c-format msgid "Stuck in demux_loop(). Taking the emergency exit\n" msgstr "" #: src/xine-engine/info_helper.c #, c-format msgid "info_helper: can't find out current locale character set\n" msgstr "info_helper: estas neeble trovi nuna loka tiparo\n" #: src/xine-engine/info_helper.c #, c-format msgid "" "info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n" msgstr "" "info_helper: nesubtenita konvertado %s -> UTF-8, neniu transigo plenumiĝis\n" #: src/xine-engine/input_cache.c #, c-format msgid ": open() function should never be called\n" msgstr ": la funkcio pen() neniam estas alvokenda\n" #: src/xine-engine/input_cache.c #, c-format msgid ": input plugin not defined!\n" msgstr ": eniga kromaĵo ne estas difinita!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading of saved data failed: %s\n" msgstr "input_rip: lego de konservitaj datumoj malsukcesis: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed: %s\n" msgstr "input_rip: enpoziciigado malsukcesis: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: reading by input plugin failed\n" msgstr "input_rip: lego far de eniga kromaĵo malsukcesis\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error writing to file % bytes: %s\n" msgstr "input_rip: eraro dum skribo en dosiero laŭ % bajtoj: %s\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: open() function should never be called\n" msgstr "input_rip: la funkcio open() estas nepre alvokenda\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: seeking failed\n" msgstr "input_rip: enpoziciigado malsukcesis\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: % bytes dropped\n" msgstr "input_rip: % falitaj bajtoj\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: input plugin not defined!\n" msgstr "input_rip: eniga kromaĵo ne estas difinita!\n" #: src/xine-engine/input_rip.c #, c-format msgid "" "input_rip: target directory wasn't specified, please fill out the option " "'media.capture.save_dir'\n" msgstr "" "input_rip: celdosierujo ne estas difinita, bonvolu kompletigi la opcion " "'media.capture.save_dir'\n" #: src/xine-engine/input_rip.c msgid "" "The stream save feature is disabled until you set media.capture.save_dir in " "the configuration." msgstr "" "La funkcio por konservi datumstrion estas malebligita ĝis ne estos " "kompletigita media.capture.save_dir fakon en la agordoj." #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: ripping/caching of this source is not permitted!\n" msgstr "input_rip: eltirado/kaŝmemorigado de ĉi fonto ne estas permesita!\n" #: src/xine-engine/input_rip.c msgid "" "xine is not allowed to save from this source. (possibly copyrighted " "material?)" msgstr "" "xine ne estas ebligita konservi de tiu ĉi fonto. (ĉu ĝi estas kopirajtigita?)" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: file name not given!\n" msgstr "input_rip: dosiernomo ne estas havigita!\n" #: src/xine-engine/input_rip.c #, c-format msgid "input_rip: error opening file %s: %s\n" msgstr "input_rip: eraro dum malfermado de dosiero %s: %s\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting abandoned\n" msgstr "io_helper: nuligita atendado\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: waiting failed: %s\n" msgstr "io_helper: atendado malsukcesis: %s\n" #: src/xine-engine/io_helper.c msgid "failed to get status of socket" msgstr "malsukcesis akiro de informoj pri stato de la kontaktoscatolo" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Permission denied\n" msgstr "io_helper: Rifuzita permeso\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: File not found\n" msgstr "io_helper: Netrovita dosiero\n" #: src/xine-engine/io_helper.c #, c-format msgid "io_helper: Connection Refused\n" msgstr "io_helper: Rifuzita konektado\n" #: src/xine-engine/load_plugins.c #, c-format msgid "map_decoder_list: no space for decoder, skipped.\n" msgstr "map_decoder_list: neniu spaco por malkodilo, do ĝi estis forlasita.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown plugin type %d in %s\n" msgstr "load_plugins: nekonata kromaĵospeco %d en %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown statically linked plugin type %d\n" msgstr "load_plugins: nekonata statika kromaĵospeco %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n" msgstr "" "load_plugins: kromaĵo %s estis ignorita, erara versio de interfaco %d (ĝi " "devas esti %d)\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, %s could not be loaded\n" msgstr "load_plugins: oni atingas limon de kromaĵo, estas neeble ŝargi %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin limit reached, static plugin could not be loaded\n" msgstr "" "load_plugins: oni atingas limon de kromaĵo, estas neeble ŝargi statikan " "kromaĵon\n" #: src/xine-engine/load_plugins.c #, c-format msgid "priority for %s decoder" msgstr "antaŭeco por %s malkodilo" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: demuxer plugin %s does not provide a priority, xine-lib will " "use the default priority.\n" msgstr "" "load_plugins: malmuksor-kromaĵo %s ne havigi antaŭecon, xine-lib uzos " "defaŭltan antaŭeco.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: input plugin %s does not provide a priority, xine-lib will use " "the default priority.\n" msgstr "" "load_plugins: eniga kromaĵo %s ne havigi antaŭecon, xine-lib uzos defaŭltan " "antaŭeco.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: plugin %s:%s found\n" msgstr "load_plugins: kromaĵo %s:%s estis trovita\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: skipping unreadable plugin directory %s.\n" msgstr "load_plugins: preterlasante nelegeblan kromaĵodosierujon %s.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unable to stat %s\n" msgstr "load_plugins: mi estas nekapabla trovi %s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: estas neeble malfermi bibliotekon de kromaĵo %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: can't get plugin info from %s:\n" "%s\n" msgstr "" "load_plugins: estas neeble akiri informojn pri kromaĵo el %s:\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot (stage 2) open plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: estas neeble malfermi bibliotekon de kromaĵo %s (dua fazo):\n" "%s\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: Yikes! %s doesn't contain plugin info.\n" msgstr "load_plugins: Ve! %s ne entenas informojn pri kromaĵo.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "Unable to create %s directory: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to save catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to replace catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "failed to remove new catalogue cache: %s\n" msgstr "" #: src/xine-engine/load_plugins.c msgid "" "The priority provides a ranking in case some media can be handled by more " "than one decoder.\n" "A priority of 0 enables the decoder's default priority." msgstr "" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: unknown content detection strategy %d\n" msgstr "load_plugins: nekonata strategio de rekono de enhavo %d\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: using demuxer '%s'\n" msgstr "load_plugins: uzante malmuksoron '%s'\n" #: src/xine-engine/load_plugins.c #, c-format msgid "load_plugins: failed to load audio output plugin <%s>\n" msgstr "load_plugins: ŝargo de aŭdeliga kromaĵo malsukcesis <%s>\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: audio output auto-probing didn't find any usable audio " "driver.\n" msgstr "" "load_plugins: mem-rekonado de aŭdeligo ne trovis uzelban aŭdozorgilon.\n" #: src/xine-engine/load_plugins.c #, c-format msgid "" "load_plugins: cannot unload plugin lib %s:\n" "%s\n" msgstr "" "load_plugins: estas neeble malŝargi bibliotekon de kromaĵo %s:\n" "%s\n" #: src/xine-engine/metronom.c msgid "basic video to audio delay in pts" msgstr "" #: src/xine-engine/metronom.c msgid "" "Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually." msgstr "" #: src/xine-engine/metronom.c msgid "Sync multiple clocks in a separate thread" msgstr "" #: src/xine-engine/metronom.c msgid "" "Enable this when there are problems with multiple (eg application supplied) " "clocks." msgstr "" #: src/xine-engine/net_buf_ctrl.c msgid "Buffering..." msgstr "Bufrado..." #: src/xine-engine/osd.c #, c-format msgid "wrong version for font '%s'. expected %d found %d.\n" msgstr "erara versio de tiparo '%s'. atendita %d trovita %d.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s-%d' already loaded, weird.\n" msgstr "tiparo '%s-%d' jam estas ŝargita, strange.\n" #: src/xine-engine/osd.c #, c-format msgid "font '%s' loading failed (%d < %d)\n" msgstr "ŝargo de tiparo '%s' malsukcesis (%d < %d)\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error matching font %s with FontConfig" msgstr "osd: eraro dum kongruado de tiparo %s kun FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with FontConfig" msgstr "osd: eraro dum ŝargado de tiparo %s kun FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error looking up font %s with FontConfig" msgstr "osd: eraro dum serĉado de tiparo %s kun FontConfig" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading font %s with in XDG data directories.\n" msgstr "osd: eraro dum ŝargado de tiparo %s kun XDG\n" #: src/xine-engine/osd.c #, c-format msgid "osd: cannot initialize ft2 library\n" msgstr "osd: estas neeble prepari ft2 bibliotekon\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error setting font size (no scalable font?)\n" msgstr "" "osd: eraro dum la argordado de tipargrando (ĉu ĝi estas nereadaptebla " "tiparo?)\n" #: src/xine-engine/osd.c #, c-format msgid "" "osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", " "skipping\n" msgstr "" "osd: nekonata sinsekvo startas je bajto 0x%02X en kodo\"%s\", do miforlasas\n" #: src/xine-engine/osd.c #, c-format msgid "osd: can't find out current locale character set\n" msgstr "osd: estas neeble trovi nunan lokan tiparon\n" #: src/xine-engine/osd.c #, c-format msgid "osd: unsupported conversion %s -> %s, no conversion performed\n" msgstr "osd: nesubtenita konvertado %s -> %s, neniu konverto plenumiĝis\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph\n" msgstr "osd: eraro dum ŝargado de glyph\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering glyph\n" msgstr "osd: eraro de bildigo de glyph\n" #: src/xine-engine/osd.c #, c-format msgid "osd: font isn't defined\n" msgstr "osd: tiparo ne estas difinita\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error loading glyph %i\n" msgstr "osd: eraro dum ŝargado de glyph %i\n" #: src/xine-engine/osd.c #, c-format msgid "osd: error in rendering\n" msgstr "osd: eraro de bildigo\n" #: src/xine-engine/osd.c msgid "palette (foreground-border-background) to use for subtitles and OSD" msgstr "uzenda paletro (malfono-randoj-fono) por surskribaĵoj kaj OSD" #: src/xine-engine/osd.c msgid "" "The palette for on-screen-display and some subtitle formats that do not " "specify any colouring themselves. The palettes are listed in the form: " "foreground-border-background." msgstr "" #: src/xine-engine/spu.c msgid "opacity for the black parts of bitmapped subtitles" msgstr "" #: src/xine-engine/spu.c msgid "opacity for the colour parts of bitmapped subtitles" msgstr "" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: no plugin available to handle '%s'\n" msgstr "video_decoder: neniu disponebla kromaĵo por administi '%s'\n" #: src/xine-engine/video_decoder.c #, c-format msgid "video_decoder: error, unknown buffer type: %08x\n" msgstr "video_decoder: eraro, nekonata speco de bufro: %08x\n" #: src/xine-engine/video_decoder.c msgid "number of video buffers" msgstr "nombro da videobufroj" #: src/xine-engine/video_decoder.c msgid "" "The number of video buffers (each is 8k in size) xine uses in its internal " "queue. Higher values mean smoother playback for unreliable inputs, but also " "increased latency and memory consumption." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "%d frames delivered, %d frames skipped, %d frames discarded\n" msgstr "" "%d filmeroj liveritaj, %d filmeroj forlasitaj, %d filmeroj formetitaj\n" #: src/xine-engine/video_out.c #, c-format msgid "" "video_out: throwing away image with pts % because it's too old " "(diff : %).\n" msgstr "" "video_out: bildo kun pts % estas rifuzita ĉar ĝi estas tro malnova " "(diff : %).\n" #: src/xine-engine/video_out.c msgid "disable decoder flush from video out" msgstr "" #: src/xine-engine/video_out.c msgid "" "Video decoder is flushed when it hasn't delivered new frames for quite a " "while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: max frames used: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: early wakeups: %d of %d\n" msgstr "" #: src/xine-engine/video_out.c msgid "Limit output frame rate" msgstr "" #: src/xine-engine/video_out.c msgid "" "If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n" msgstr "" #: src/xine-engine/video_out.c msgid "percentage of skipped frames to tolerate" msgstr "tolerenda procento je forlasitaj filmeroj" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not decoded in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c msgid "percentage of discarded frames to tolerate" msgstr "tolerenda procento je formetitaj filmeroj" #: src/xine-engine/video_out.c msgid "" "When more than this percentage of frames are not shown, because they were " "not scheduled for display in time, xine sends a notification." msgstr "" #: src/xine-engine/video_out.c #, c-format msgid "video_out: sorry, this should not happen. please restart xine.\n" msgstr "video_out: pardonu, tio ne devus okazi. bonvolu restartigi xine.\n" #: src/xine-engine/vo_scale.c msgid "horizontal image position in the output window" msgstr "horizontala lokiĝo de bildo en eligfenestro" #: src/xine-engine/vo_scale.c msgid "" "If the video window's horizontal size is bigger than the actual image to " "show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the very left\" and 100 \"at the very right\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "vertical image position in the output window" msgstr "vertikala lokiĝo de bildo en eligfenestro" #: src/xine-engine/vo_scale.c msgid "" "If the video window's vertical size is bigger than the actual image to show, " "you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the middle" "\", while 0 means \"at the top\" and 100 \"at the bottom\"." msgstr "" #: src/xine-engine/vo_scale.c msgid "disable all video scaling" msgstr "malebligu readapton de video" #: src/xine-engine/vo_scale.c msgid "" "If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage." msgstr "" #: src/xine-engine/vo_scale.c msgid "treat screen pixels as exactly square" msgstr "" #: src/xine-engine/vo_scale.c msgid "" "Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n" msgstr "" #: src/xine-engine/xine.c msgid "disable decoder flush at discontinuity" msgstr "" #: src/xine-engine/xine.c msgid "" "Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: error while parsing mrl\n" msgstr "xine: eraro dum sintaksa analizo de mrl\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found input plugin : %s\n" msgstr "xine: trovita enigkromaĵo : %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: input plugin cannot open MRL [%s]\n" msgstr "xine: eniga kromaĵo ne povas malfermi MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: cannot find input plugin for MRL [%s]\n" msgstr "xine: estas neeble trovi enigan kromaĵon por MRL [%s]\n" #: src/xine-engine/xine.c #, c-format msgid "xine: specified demuxer %s failed to start\n" msgstr "xine: specifita malmuksoro %s malsukcesis starti\n" #: src/xine-engine/xine.c #, c-format msgid "xine: join rip input plugin\n" msgstr "xine: startigo de eniga kromaĵo por eltiri\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening rip input plugin instance\n" msgstr "xine: eraro dum malfermado de eniga kromaĵo por eltiri\n" #: src/xine-engine/xine.c #, c-format msgid "xine: last_probed demuxer %s failed to start\n" msgstr "xine: lasta testita malmuksoro %s malsukcesis starti\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring video\n" msgstr "ignorante videon\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring audio\n" msgstr "ignorante aŭdon\n" #: src/xine-engine/xine.c #, c-format msgid "ignoring subpicture\n" msgstr "ignorante sub-bildojn\n" #: src/xine-engine/xine.c #, c-format msgid "input cache plugin disabled\n" msgstr "eniga kromaĵo por kaŝmemoro estas malebligita\n" #: src/xine-engine/xine.c #, c-format msgid "subtitle mrl opened '%s'\n" msgstr "mrl-surskribaĵo malfermita '%s'\n" #: src/xine-engine/xine.c #, c-format msgid "xine: error opening subtitle mrl\n" msgstr "xine: eraro dum malfermado de mrl-surskribaĵo\n" #: src/xine-engine/xine.c #, c-format msgid "xine: unknown config option \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: changing option '%s' from MRL isn't permitted\n" msgstr "xine: ŝanĝo de opcio '%s' el MRL ne estas permesita\n" #: src/xine-engine/xine.c #, c-format msgid "xine: no value for \"%s\", ignoring.\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't load plugin-specified demux %s for >%s<\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: couldn't find demux for >%s<\n" msgstr "xine: estas neeble trovi malmuksilo por >%s<\n" #: src/xine-engine/xine.c #, c-format msgid "xine: found demuxer plugin: %s\n" msgstr "xine: malmuksora kromaĵo estis trovita: %s\n" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer is already done. that was fast!\n" msgstr "" #: src/xine-engine/xine.c #, c-format msgid "xine: demuxer failed to start\n" msgstr "xine: malmuksoro malsukcesis starti\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: no demux available\n" msgstr "xine_play: neinu disponebla malmuksado\n" #: src/xine-engine/xine.c #, c-format msgid "xine_play: demux failed to start\n" msgstr "xine_play: malmuksilo malsukcesis starti\n" #: src/xine-engine/xine.c #, c-format msgid "xine: The specified save_dir \"%s\" might be a security risk.\n" msgstr "" "xine: La specifita savdosierujo \"%s\" povus esti danĝero por secureco.\n" #: src/xine-engine/xine.c msgid "The specified save_dir might be a security risk." msgstr "La specifita savdosierujo povus esti danĝero por secureco." #: src/xine-engine/xine.c #, c-format msgid "xine: locale not supported by C library\n" msgstr "xine: \"locale\" ne estas subtenita de C-biblioteko\n" #: src/xine-engine/xine.c msgid "media format detection strategy" msgstr "strategio por rekoni plurmedian formaton" #: src/xine-engine/xine.c msgid "" "xine offers various methods to detect the media format of input to play. The " "individual values are:\n" "\n" "default\n" "First try to detect by content, then by file name extension.\n" "\n" "reverse\n" "First try to detect by file name extension, then by content.\n" "\n" "content\n" "Detect by content only.\n" "\n" "extension\n" "Detect by file name extension only.\n" msgstr "" #: src/xine-engine/xine.c msgid "directory for saving streams" msgstr "dosierujo por konservi datumstriojn" #: src/xine-engine/xine.c msgid "" "When using the stream save feature, files will be written only into this " "directory.\n" "This setting is security critical, because when changed to a different " "directory, xine can be used to fill files in it with arbitrary content. So " "you should be careful that the directory you specify is robust against any " "content in any file." msgstr "" #: src/xine-engine/xine.c msgid "allow implicit changes to the configuration (e.g. by MRL)" msgstr "ebligu implicitajn ŝanĝojn en la agordaĵo (ekz. far de MRL)" #: src/xine-engine/xine.c msgid "" "If enabled, you allow xine to change your configuration without explicit " "actions from your side. For example configuration changes demanded by MRLs " "or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or playlists " "from untrusted remote sources. If you allow them to arbitrarily change your " "configuration, you might end with a totally messed up xine." msgstr "" #: src/xine-engine/xine.c msgid "Timeout for network stream reading (in seconds)" msgstr "Tempofino por legado de ret-datumstrioj (en sekundoj)" #: src/xine-engine/xine.c msgid "" "Specifies the timeout when reading from network streams, in seconds. Too low " "values might stop streaming when the source is slow or the bandwidth is " "occupied, too high values will freeze the player if the connection is lost." msgstr "" #: src/xine-engine/xine.c msgid "Internet Protocol version(s) to use" msgstr "" #: src/xine-engine/xine.c msgid "" "\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy." msgstr "" #: src/xine-engine/xine.c msgid "Auto join separate audio/video files" msgstr "" #: src/xine-engine/xine.c msgid "" "When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams." msgstr "" #: src/xine-engine/xine.c msgid "Use pre-1.2.13 libxine audio level settings" msgstr "" #: src/xine-engine/xine.c #, no-c-format msgid "" "On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n" msgstr "" #: src/xine-engine/xine.c msgid "messages" msgstr "mesaĝoj" #: src/xine-engine/xine.c msgid "plugin" msgstr "kromaĵo" #: src/xine-engine/xine.c msgid "trace" msgstr "bildigo" #: src/xine-engine/xine_interface.c msgid "Warning:" msgstr "Atentu:" #: src/xine-engine/xine_interface.c msgid "Unknown host:" msgstr "Nekonata gastiga komputilo:" #: src/xine-engine/xine_interface.c msgid "Unknown device:" msgstr "Nekonata aparato:" #: src/xine-engine/xine_interface.c msgid "Network unreachable" msgstr "Neatingebla reto" #: src/xine-engine/xine_interface.c msgid "Connection refused:" msgstr "Rifuzita konekto:" #: src/xine-engine/xine_interface.c msgid "File not found:" msgstr "Netrovita dosiero:" #: src/xine-engine/xine_interface.c msgid "Read error from:" msgstr "Eraro de lego el:" #: src/xine-engine/xine_interface.c msgid "Error loading library:" msgstr "Eraro dum ŝargo de biblioteko:" #: src/xine-engine/xine_interface.c msgid "Encrypted media stream detected" msgstr "Ĉifrita datumstio estis rekonita" #: src/xine-engine/xine_interface.c msgid "Security message:" msgstr "Mesaĝo de sekureco:" #: src/xine-engine/xine_interface.c msgid "Audio device unavailable" msgstr "Aŭdaparato estas nedisponebla" #: src/xine-engine/xine_interface.c msgid "Permission error" msgstr "Eraro de permeso" #: src/xine-engine/xine_interface.c msgid "File is empty:" msgstr "Dosiero estas vakua:" #: src/xine-engine/xine_interface.c msgid "Authentication needed" msgstr "" #: src/xine-engine/xine_interface.c #, fuzzy msgid "Recording done:" msgstr "Restarigo de indekso..." #: src/xine-utils/memcpy.c #, c-format msgid "Benchmarking memcpy methods (smaller is better):\n" msgstr "Testo de rapideco por medoto de memorkopio (pli eta estas pli bona):\n" #: src/xine-utils/memcpy.c msgid "memcopy method used by xine" msgstr "metodo de memorkopio uzata de xine" #: src/xine-utils/memcpy.c msgid "" "The copying of large memory blocks is one of the most expensive operations " "on todays computers. Therefore xine provides various tuned methods to do " "this copying. Usually, the best method is detected automatically." msgstr "" #~ msgid "configfile: WARNING: backing up configfile to %s failed\n" #~ msgstr "configfile: ATENTU: reservado de configfile en %s malsukcesis\n" #, fuzzy #~ msgid "%s: audio: %s\n" #~ msgstr "rtsp: nevalida mrl: %s\n" #~ msgid "input_file: read error (%s)\n" #~ msgstr "input_file: eraro de lego (%s)\n" #~ msgid "input_net: socket(): %s\n" #~ msgstr "input_net: socket(): %s\n" #~ msgid "input_net: connect(): %s\n" #~ msgstr "input_net: connect(): %s\n" #~ msgid "input_net: unable to resolve '%s'.\n" #~ msgstr "input_net: mi estas nekapabla solvi '%s'.\n" #~ msgid "input_net: unable to connect to '%s'.\n" #~ msgstr "input_net: mi estas nekapabla konektigi '%s'.\n" #~ msgid "stdin: cannot seek back! (% > %)\n" #~ msgstr "stdin: estas neeble retro-enpoziciigi! (% > %)\n" #~ msgid "xine: error while parsing MRL\n" #~ msgstr "xine: eraro dum sintaksa analizo de MRL\n" #~ msgid "raw device set up for DVD access" #~ msgstr "kruda aparato agordita por eniro al DVD" #~ msgid "load_plugins: static plugin %s found\n" #~ msgstr "load_plugins: statika kromaĵo %s estis trovita\n" xine-lib-1.2/TODO0000644000175000017500000001131714647725151011356 0ustar memeFor 1.3 series ============== - analyse impact of breaking xine.h down in multiple public headers, and rename the xine/ directory for include files in xinecore/ (for plugins only), while leaving xine/ for public include files; For 1.2 series ============== - Security-Related: start using xine_xcalloc rather than xine_xmalloc when the number of elements is not a build-time constant. - mimetype-based demuxer selection, solves the effects of shoutcast's bug; - Doxygen API documentation for both internal and public functions; - removal of (deprecated) software deinterlacers from video output plugins; - reduction of exported symbols by hiding (-fvisibility=hidden or attribute) the internal libxine-only functions; - move the contributed code (not developed by xine project) in the contrib/ directory of the source tree; - reduce memory footprint (e.g. variable fifo buffer sizes...); - handle gracefully the runtime removal of the audio output device (being it a physical removal for USB devices or a missing output on a client-server design like PulseAudio, ESounD or Jack); - review media_eject_media, possibly rewrite to use libcdio; - improve error reporting (for when demuxer/decoder plugins aren't found); - HTTPS. - review translable strings, try to follow a defined schema for naming and error reporting; known bugs ========== - frame allocation problem with h264 streams using > 15 reference frames - dvdnav time search function does not use the time table, but interpolates only cell times - apparently, dvb:// (but not dvb://CHANNEL) is broken for ATSC requested/planned features ========================== - advanced audio processors - audio normalization - crossfading - high quality overlay blending / OSD (eg. Jason Tackaberry's advanced BGRA blend plugin) - synchronized playback between multiple machines - high quality sound resampling (use libsamplerate / secret rabbit code) - "synchroneous post plugins" (post plugins behind the output fifo) - move pvr and v4l_adjust_realtime_speed routines to xine engine so it can be used by any input plugin. the following text is kept from pre-1.0 times - we must check what is still relevant ==================================================================================== optional -------- - properly localize all user-visible strings - sort out which messages should go to console and which to xine_log - look over global structures and do some cleanup - id3v2.3,v2.4 support - "metainfo change" event - double-check rate estimation in demux_mpeg/mpeg_block - fix cook audio streaming - better dvd error messages - fix streaming of small files (e.g. http) - rtp / rtsp support: - input_rtp - rtsp support (currently only real's rtsp derivate is implemented) - isma/apple streaming server support (mpeg4ip.sf.net) - find out what all those people requesting rtp/multicast/... support really want and how to implement it :) - videolan streaming server support - helix streaming server support - detect broken savage drivers in health check, disable Xv in that case beyond 1.0 ---------- - use the safe string functions from xine_buffer.h in xine's own code - rework the clock system, introducing clock and metronom speed settings - allow more frame formats, automatic post plugin insertion for conversion - frame-level seeking - experiment with splint for code verification Open Tasks ========== - port to other OS (Net/OpenBSD, hurd ...?) - MicroDVD input plugin - video output synced to vertical blank preferably without requiring root privileges (XSync extension? MAS?) - resolve issues with ffmpeg's live http streaming server - videolan streaming support - MAS support (http://www.mediaapplicationserver.net) - nonlinear video editing and compositing frontend (michael) => enix - stream format conversion frontend => enix - Multiple DVD Subtitles displayed at the same time - Move read cache code from libdvdnav into input_dvd.c - Support DVD "Trick" modes. Super Fast forward/reverse - detect raw ac3/a52 in MPEG Program streams. - detect raw ac3/a52 in MPEG Transport streams that lack PAT/PMT tables. - handle MPEG PES/PS streams with PES_packet_length = 0 xine's future ============= - implement lots of audio and video processing filters as post plugins, e.g. - scaling - colorspace conversion - deinterlacing (already done) - audio resampling - compressor ... extend public api so post plugins are instantiated automatically when needed, but keep explicit post plugin rewiring functions for advanced video processing frontends - see what kind of cooperation can be set up with other media player projects - mike will look into moving xine's decoder api closer to the one ffmpeg uses - check out other media players - output, demuxer plugins xine-lib-1.2/contrib/0000755000175000017500000000000014647725152012324 5ustar memexine-lib-1.2/contrib/libdha/0000755000175000017500000000000014647725152013547 5ustar memexine-lib-1.2/contrib/libdha/cpu_flush.c0000644000175000017500000000076214647725151015707 0ustar meme/* CPU flush support */ #include #include #include #include #include #include "libdha.h" #include "kernelhelper/dhahelper.h" void cpu_flush(void *va,unsigned long length) { int retval; int libdha_fd=-1; if( libdha_fd == -1) libdha_fd = open("/dev/dhahelper",O_RDWR); if (libdha_fd > 0) { dhahelper_cpu_flush_t _l2; _l2.va = va; _l2.length = length; retval = ioctl(libdha_fd, DHAHELPER_CPU_FLUSH, &_l2); close(libdha_fd); } } xine-lib-1.2/contrib/libdha/pci_db2c.awk0000644000175000017500000002145314647725151015724 0ustar meme# This file converts given pci.db to "C" source and header files # For latest version of pci ids see: http://pciids.sf.net # Copyright 2002 Nick Kurshev # # Usage: awk -f pci_db2c.awk pci.db # # Tested with Gawk v 3.0.x and Mawk 1.3.3 # But it should work with standard Awk implementations (hopefully). # (Nobody tested it with Nawk, but it should work, too). # BEGIN { if(ARGC != 2) { # check for arguments: print "Usage awk -f pci_db2c.awk pci.db (and make sure pci.db file exists first)"; exit(1); } in_file = ARGV[1]; vendor_file = "pci_vendors.h"; ids_file = "pci_ids.h" name_file = "pci_names.c" name_h_file = "pci_names.h" dev_ids_file = "pci_dev_ids.c" line=0; # print out head lines print_head(vendor_file); print_head(ids_file); print_head(name_file); print_head(name_h_file); print_head(dev_ids_file); print "#ifndef PCI_VENDORS_INCLUDED" >vendor_file print "#define PCI_VENDORS_INCLUDED 1">vendor_file print "" >vendor_file print "#ifndef PCI_IDS_INCLUDED" >ids_file print "#define PCI_IDS_INCLUDED 1">ids_file print "" >ids_file print "#include \"pci_vendors.h\"">ids_file print "" >ids_file print "#ifndef PCI_NAMES_INCLUDED" >name_h_file print "#define PCI_NAMES_INCLUDED 1">name_h_file print "" >name_h_file print_name_struct(name_h_file); print "#include ">name_file print "#include \"pci_names.h\"">name_file print "#include \"pci_dev_ids.c\"">name_file print "">name_file print "static struct vendor_id_s vendor_ids[] = {">name_file first_pass=1; init_name_db(); while(getline 0 && field[4] == "0") { init_device_db() svend_name = get_short_vendor_name(field[3]) printf("#define VENDOR_%s\t", svend_name) >vendor_file; if(length(svend_name) < 9) printf("\t") >vendor_file; printf("0x%s /*%s*/\n",field[2], name_field) >vendor_file; printf("{ 0x%s, \"%s\", dev_lst_%s },\n",field[2], name_field, field[2]) >name_file; printf("/* Vendor: %s: %s */\n", field[2], name_field) > ids_file if(first_pass == 1) { first_pass=0; } else { print "{ 0xFFFF, NULL }\n};" >dev_ids_file; } printf("static const struct device_id_s dev_lst_%s[]={\n", field[2])>dev_ids_file } if(field[1] == "d" && length(field[3])>0 && field[4] == "0") { sdev_name = get_short_device_name(field[3]) full_name = sprintf("#define DEVICE_%s_%s", svend_name, sdev_name); printf("%s\t", full_name) >ids_file if(length(full_name) < 9) printf("\t") >ids_file; if(length(full_name) < 17) printf("\t") >ids_file; if(length(full_name) < 25) printf("\t") >ids_file; if(length(full_name) < 32) printf("\t") >ids_file; if(length(full_name) < 40) printf("\t") >ids_file; if(length(full_name) < 48) printf("\t") >ids_file; printf("0x%s /*%s*/\n", substr(field[2], 5), name_field) >ids_file printf("{ 0x%s, \"%s\" },\n", substr(field[2], 5), name_field) >dev_ids_file } if(field[1] == "s" && length(field[3])>0 && field[4] == "0") { subdev_name = get_short_subdevice_name(field[3]) full_name = sprintf("#define SUBDEVICE_%s_%s", svend_name, subdev_name) printf("\t%s\t", full_name) >ids_file if(length(full_name) < 9) printf("\t") >ids_file; if(length(full_name) < 17) printf("\t") >ids_file; if(length(full_name) < 25) printf("\t") >ids_file; if(length(full_name) < 32) printf("\t") >ids_file; if(length(full_name) < 40) printf("\t") >ids_file; printf("0x%s /*%s*/\n", substr(field[2], 9), name_field) >ids_file } } print "Total lines parsed:", line; print "">vendor_file print "#endif/*PCI_VENDORS_INCLUDED*/">vendor_file print "">ids_file print "#endif/*PCI_IDS_INCLUDED*/">ids_file print "">name_h_file print "#endif/*PCI_NAMES_INCLUDED*/">name_h_file print "};">name_file print "{ 0xFFFF, NULL }" >dev_ids_file; print "};">dev_ids_file print_func_bodies(name_file); } function print_head( out_file) { print "/*" >out_file; printf(" * File: %s\n", out_file) >out_file; printf(" * This file was generated automatically. Don't modify it.\n") >out_file; print "*/" >out_file; return; } function print_name_struct(out_file) { print "#ifdef __cplusplus" >out_file print "extern \"C\" {" >out_file print "#endif" >out_file print "">out_file print "struct device_id_s" >out_file print "{" >out_file print "\tunsigned short\tid;" >out_file print "\tconst char *\tname;" >out_file print "};" >out_file print "">out_file print "struct vendor_id_s" >out_file print "{" >out_file print "\tunsigned short\tid;" >out_file print "\tconst char *\tname;" >out_file print "\tconst struct device_id_s *\tdev_list;" >out_file print "};" >out_file print "extern const char *pci_vendor_name(unsigned short id);">out_file print "extern const char *pci_device_name(unsigned short vendor_id, unsigned short device_id);">out_file print "">out_file print "#ifdef __cplusplus" >out_file print "}" >out_file print "#endif" >out_file return } function print_func_bodies(out_file) { print "">out_file print "const char *pci_vendor_name(unsigned short id)" >out_file print "{" >out_file print " unsigned i;" >out_file print " for(i=0;iout_file print " {" >out_file print "\tif(vendor_ids[i].id == id) return vendor_ids[i].name;" >out_file print " }" >out_file print " return NULL;" >out_file print "}">out_file print "" >out_file print "const char *pci_device_name(unsigned short vendor_id, unsigned short device_id)" >out_file print "{" >out_file print " unsigned i, j;" >out_file print " for(i=0;iout_file print " {" >out_file print "\tif(vendor_ids[i].id == vendor_id)" >out_file print "\t{" >out_file print "\t j=0;" >out_file print "\t while(vendor_ids[i].dev_list[j].id != 0xFFFF)" >out_file print "\t {">out_file print "\t\tif(vendor_ids[i].dev_list[j].id == device_id) return vendor_ids[i].dev_list[j].name;">out_file print "\t\tj++;">out_file print "\t };">out_file print "\t break;" >out_file print "\t}" >out_file print " }" >out_file print " return NULL;">out_file print "}">out_file return } function kill_double_quoting(fld) { n=split(fld,phrases, "[\"]"); new_fld = phrases[1] for(i=2;i<=n;i++) new_fld = sprintf("%s\\\"%s", new_fld, phrases[i]) return new_fld } function init_name_db() { vendor_names[1]="" } function init_device_db() { # delete device_names for( i in device_names ) delete device_names[i]; device_names[1]="" # delete subdevice_names for( i in subdevice_names ) delete subdevice_names[i]; subdevice_names[1] = "" } function get_short_vendor_name(from) { n=split(from, name, "[ ]"); new_name = toupper(name[1]); if(length(new_name)<3) new_name = sprintf("%s_%s", new_name, toupper(name[2])); n=split(new_name, name, "[^0-9A-Za-z]"); svendor = name[1]; for(i=2;i<=n;i++) svendor=sprintf("%s%s%s", svendor, length(name[i])?"_":"", name[i]); new_name = svendor; vend_suffix = 2; # check for unique while(new_name in vendor_names) { new_name = sprintf("%s%u", svendor, vend_suffix) vend_suffix = vend_suffix + 1; } # Add new name in array of vendor's names vendor_names[new_name] = new_name return new_name; } function get_short_device_name(from_name) { n=split(from_name, name, "[ ]"); new_name = toupper(name[1]); if(length(name[2])) new_name = sprintf("%s_%s", new_name, toupper(name[2])); if(length(name[3])) new_name = sprintf("%s_%s", new_name, toupper(name[3])); n=split(new_name, name, "[^0-9A-Za-z]"); sdevice = name[1]; for(i=2;i<=n;i++) sdevice=sprintf("%s%s%s", sdevice, length(name[i])?"_":"", name[i]); new_name = sdevice; dev_suffix = 2; # check for unique while(new_name in device_names) { new_name = sprintf("%s%u", sdevice, dev_suffix) dev_suffix = dev_suffix + 1; } # Add new name in array of device names device_names[new_name] = new_name return new_name; } function get_short_subdevice_name(from_name) { n=split(from_name, name, "[ ]"); new_name = toupper(name[1]); if(length(name[2])) new_name = sprintf("%s_%s", new_name, toupper(name[2])); if(length(name[3])) new_name = sprintf("%s_%s", new_name, toupper(name[3])); n=split(new_name, name, "[^0-9A-Za-z]"); ssdevice = name[1]; for(i=2;i<=n;i++) ssdevice=sprintf("%s%s%s", ssdevice, length(name[i])?"_":"", name[i]); new_name = ssdevice; sdev_suffix = 2; # check for unique while(new_name in subdevice_names) { new_name = sprintf("%s%u", ssdevice, sdev_suffix) sdev_suffix = sdev_suffix + 1; } # Add new name in array of subdevice names subdevice_names[new_name] = new_name return new_name; } xine-lib-1.2/contrib/libdha/libdha.h0000644000175000017500000001255614647725151015153 0ustar meme/* libgha.h - Library for direct hardware access Copyrights: 1996/10/27 - Robin Cutshaw (robin@xfree86.org) XFree86 3.3.3 implementation 1999 - Øyvind Aabling. Modified for GATOS/win/gfxdump. 2002 - library implementation by Nick Kurshev supported O/S's: SVR4, UnixWare, SCO, Solaris, FreeBSD, NetBSD, 386BSD, BSDI BSD/386, Linux, Mach/386, ISC DOS (WATCOM 9.5 compiler), Win9x (with mapdev.vxd) Licence: GPL */ #ifndef LIBDHA_H #define LIBDHA_H #if defined (__FreeBSD__) # include #else # include #endif #ifdef __cplusplus extern "C" { #endif #define MAX_DEV_PER_VENDOR_CFG1 64 #define MAX_PCI_DEVICES_PER_BUS 32 #define MAX_PCI_DEVICES 64 #define PCI_MULTIFUNC_DEV 0x80 typedef struct pciinfo_s { int bus,card,func; /* PCI/AGP bus:card:func */ unsigned short vendor,device; /* Card vendor+device ID */ unsigned long base0,base1,base2,baserom; /* Memory and I/O base addresses */ unsigned long base3,base4,base5; /* Memory and I/O base addresses */ unsigned char irq,ipin,gnt,lat; /* assigned IRQ parameters for this card */ // unsigned base0_limit, base1_limit, base2_limit, baserom_limit; }pciinfo_t; extern int pci_config_read(unsigned char bus, unsigned char dev, unsigned char func, unsigned char cmd, int len, unsigned long *val); extern int pci_config_write(unsigned char bus, unsigned char dev, unsigned char func, unsigned char cmd, int len, unsigned long val); /* Fill array pci_list which must have size MAX_PCI_DEVICES and return 0 if sucessful */ extern int pci_scan(pciinfo_t *pci_list,unsigned *num_card); /* Enables/disables accessing to IO space from application side. Should return 0 if o'k or errno on error. */ extern int enable_app_io( void ); extern int disable_app_io( void ); extern unsigned char INPORT8(unsigned idx); extern unsigned short INPORT16(unsigned idx); extern unsigned INPORT32(unsigned idx); #define INPORT(idx) INPORT32(idx) extern void OUTPORT8(unsigned idx,unsigned char val); extern void OUTPORT16(unsigned idx,unsigned short val); extern void OUTPORT32(unsigned idx,unsigned val); #define OUTPORT(idx,val) OUTPORT32(idx,val) extern void * map_phys_mem(unsigned long base, unsigned long size); extern void unmap_phys_mem(void *ptr, unsigned long size); /* These are the region types */ #define MTRR_TYPE_UNCACHABLE 0 #define MTRR_TYPE_WRCOMB 1 #define MTRR_TYPE_WRTHROUGH 4 #define MTRR_TYPE_WRPROT 5 #define MTRR_TYPE_WRBACK 6 extern int mtrr_set_type(unsigned base,unsigned size,int type); /* Busmastering support */ /* returns 0 if support exists else errno */ extern int bm_open( void ); extern void bm_close( void ); /* Converts virtual memory addresses into physical returns 0 if OK else - errno parray should have enough length to accept length/page_size elements. virt_addr can be located in non-continious memory block and can be allocated by malloc(). (kmalloc() is not needed). Note: if you have some very old card which requires continous memory block then you need to implement bm_kmalloc bm_kfree functions here. NOTE2: to be sure that every page of region is present in physical memory (is not swapped out) use m(un)lock functions. Note3: Probably your card will want to have page-aligned block for DMA transfer so use memalign(PAGE_SIZE,mem_size) function to alloc such memory. */ extern int bm_virt_to_phys( void * virt_addr, unsigned long length, unsigned long * parray ); /* Converts virtual memory addresses into bus address Works in the same way as bm_virt_to_phys. WARNING: This function will be die after implementing bm_alloc_pci_shmem() because we really can't pass any memory address to card. Example: 64-bit linear address can't be passed into 32-bit card. Even more - some old cards can access 24-bit address space only */ extern int bm_virt_to_bus( void * virt_addr, unsigned long length, unsigned long * barray ); /* NOTE: bm_alloc_pci_shmem() and bm_free_pci_shmem() are still not implemented! arguments: pciinfo_t - specifies pci card for which memory should be shared bitness - can be 16,24,32,64 specifies addressing possibilities of the card length - specifies size of memory which should allocated op - specifies direction as combination flags TO_CARD,FROM_CARD Return value - should be tuned we need to have something like this: struct pci_shmem { void * handler; void * virt_addr void * array_of_bus_addr[]; unsigned long length; } NOTE2: After finalizing of these functions bm_virt_to_bus() will be die */ extern void * bm_alloc_pci_shmem(pciinfo_t *, unsigned mem_bitness, unsigned long length,int op ); extern void bm_free_pci_shmem(void * pci_shmem); extern int bm_lock_mem( const void * addr, unsigned long length ); extern int bm_unlock_mem( const void * addr, unsigned long length ); /* HWIRQ support */ extern int hwirq_install(int bus, int dev, int func, int areg, unsigned long aoff, uint32_t adata); extern int hwirq_wait(unsigned irqnum); extern int hwirq_uninstall(int bus, int dev, int func); /* CPU flushing support */ extern void cpu_flush(void *va,unsigned long length); extern void libdha_exit(const char *message, int level); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libdha/Makefile.am0000644000175000017500000000212714647725151015604 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_LDFLAGS = $(xineplug_ldflags) SUBDIRS = bin oth sysdep if BUILD_DHA_KMOD SUBDIRS += kernelhelper endif AM_CFLAGS = $(DEFAULT_OCFLAGS) EXTRA_DIST = README pci_db2c.awk awk_generated = pci_dev_ids.c pci_ids.h pci_names.c pci_names.h pci_vendors.h CLEANFILES = $(awk_generated) noinst_HEADERS = AsmMacros.h libdha.h pci_ids.h pci_names.h pci_vendors.h if ENABLE_VIDIX noinst_LTLIBRARIES = libdha.la endif libdha_la_SOURCES = libdha.c mtrr.c pci.c mmi.c ports.c irq.c cpu_flush.c nodist_libdha_la_SOURCES = pci_names.c EXTRA_PROGRAMS = test test_SOURCES = test.c test_LDADD = libdha.la ## for OpenBSD LIBS += -li386 ## We have to create some files, on the fly, this is why this rule is needed. pci_db2c.awk: oth/pci.db: $(awk_generated): pci_db2c.awk oth/pci.db LC_ALL=C $(AWK) -f $(srcdir)/pci_db2c.awk \ $(srcdir)/oth/pci.db pci_names.lo: $(awk_generated) source='$*.c' object='$@' libtool=yes \ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' \ $(CCDEPMODE) $(depcomp) \ $(LTCOMPILE) -c -o $@ `test -f $*.c || echo '$(srcdir)/'`$*.c xine-lib-1.2/contrib/libdha/irq.c0000644000175000017500000000232714647725151014511 0ustar meme/* HW IRQ support */ #include #include #include #include /* mlock */ #include #include #include #include #include "libdha.h" #include "kernelhelper/dhahelper.h" static int libdha_fd=-1; static int hwirq_locks=0; int hwirq_install(int bus, int dev, int func, int ar, u_long ao, uint32_t ad) { int retval; if( libdha_fd == -1) libdha_fd = open("/dev/dhahelper",O_RDWR); hwirq_locks++; if (libdha_fd > 0) { dhahelper_irq_t _irq; _irq.bus = bus; _irq.dev = dev; _irq.func = func; _irq.ack_region = ar; _irq.ack_offset = ao; _irq.ack_data = ad; retval = ioctl(libdha_fd, DHAHELPER_INSTALL_IRQ, &_irq); return retval; } return errno; } int hwirq_wait(unsigned irqnum) { int retval; if (libdha_fd > 0) { dhahelper_irq_t _irq; _irq.num = irqnum; retval = ioctl(libdha_fd, DHAHELPER_ACK_IRQ, &_irq); return retval; } return EINVAL; } int hwirq_uninstall(int bus, int dev, int func) { if (libdha_fd > 0) { dhahelper_irq_t _irq; _irq.bus = bus; _irq.dev = dev; _irq.func = func; ioctl(libdha_fd, DHAHELPER_FREE_IRQ, &_irq); } if(!hwirq_locks) { close(libdha_fd); libdha_fd=-1; } return 0; } xine-lib-1.2/contrib/libdha/sysdep/0000755000175000017500000000000014647725152015056 5ustar memexine-lib-1.2/contrib/libdha/sysdep/AsmMacros_ia64.h0000644000175000017500000000052714647725152017743 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ Modified for readability by Nick Kurshev */ #ifndef __ASM_MACROS_IA64_H #define __ASM_MACROS_IA64_H #if defined(linux) #include #else #include "sysdep/AsmMacros_generic.h" #endif #endif xine-lib-1.2/contrib/libdha/sysdep/pci_x86.c0000644000175000017500000000645014647725151016506 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ static int pci_config_type( void ) { unsigned long tmplong1, tmplong2; unsigned char tmp1, tmp2; int retval; retval = 0; OUTPORT8(PCI_MODE2_ENABLE_REG, 0x00); OUTPORT8(PCI_MODE2_FORWARD_REG, 0x00); tmp1 = INPORT8(PCI_MODE2_ENABLE_REG); tmp2 = INPORT8(PCI_MODE2_FORWARD_REG); if ((tmp1 == 0x00) && (tmp2 == 0x00)) { retval = 2; /*printf("PCI says configuration type 2\n");*/ } else { tmplong1 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, PCI_EN); tmplong2 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, tmplong1); if (tmplong2 == PCI_EN) { retval = 1; /*printf("PCI says configuration type 1\n");*/ } else { /*printf("No PCI !\n");*/ disable_app_io(); /*exit(1);*/ retval = 0xFFFF; } } return retval; } static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT16(PCI_MODE1_DATA_REG); } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT8(PCI_MODE1_DATA_REG); } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT32(PCI_MODE1_DATA_REG,val); } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT16(PCI_MODE1_DATA_REG,val); } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT8(PCI_MODE1_DATA_REG,val); } xine-lib-1.2/contrib/libdha/sysdep/pci_lynx.c0000644000175000017500000000403714647725152017053 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #if defined(Lynx_22) #ifndef GCCUSESGAS #define GCCUSESGAS #endif /* let's mimick the Linux Alpha stuff for LynxOS so we don't have * to change too much code */ #include static unsigned char *pciConfBase; static __inline__ void enable_os_io(void) { pciConfBase = (unsigned char *) smem_create("PCI-CONF", (char *)0x80800000, 64*1024, SM_READ|SM_WRITE); if (pciConfBase == (void *) -1) exit(1); } static __inline__ void disable_os_io(void) { smem_create(NULL, (char *) pciConfBase, 0, SM_DETACH); smem_remove("PCI-CONF"); pciConfBase = NULL; } #include static unsigned char *pciConfBase; static __inline__ unsigned long static swapl(unsigned long val) { unsigned char *p = (unsigned char *)&val; return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0)); } #define BUS(tag) (((tag)>>16)&0xff) #define DFN(tag) (((tag)>>8)&0xff) #define PCIBIOS_DEVICE_NOT_FOUND 0x86 #define PCIBIOS_SUCCESSFUL 0x00 static int pciconfig_read( unsigned char bus, unsigned char dev, unsigned char offset, int len, /* unused, alway 4 */ unsigned long *val) { unsigned long _val; unsigned long *ptr; dev >>= 3; if (bus || dev >= 16) { *val = 0xFFFFFFFF; return PCIBIOS_DEVICE_NOT_FOUND; } else { ptr = (unsigned long *)(pciConfBase + ((1<>= 3; _val = swapl(val); if (bus || dev >= 16) { return PCIBIOS_DEVICE_NOT_FOUND; } else { ptr = (unsigned long *)(pciConfBase + ((1< #include /* machine/console.h seems to be outdated by recent FreeBSD * * however pcvt_ioctl.h seems to exist for very long time */ /* #include */ /* #include * - deprecated, replaced with sys/kbio.h (xine bug #534) */ #include #ifndef GCCUSESGAS #define GCCUSESGAS #endif static int io_fd; static __inline__ int enable_os_io(void) { io_fd = -1 ; if ((io_fd = open("/dev/console", O_RDWR, 0)) < 0) { perror("/dev/console"); return(errno); } if (ioctl(io_fd, KDENABIO, 0) < 0) { perror("ioctl(KDENABIO)"); return(errno); } return(0); } static __inline__ int disable_os_io(void) { if (ioctl(io_fd, KDDISABIO, 0) < 0) { perror("ioctl(KDDISABIO)"); close(io_fd); return(errno); } close(io_fd); return(0); } xine-lib-1.2/contrib/libdha/sysdep/AsmMacros_generic.h0000644000175000017500000000203514647725151020607 0ustar meme/* Generic stuff to compile VIDIX only on any system (SCRATCH) */ #ifndef __ASM_MACROS_GENERIC_H #define __ASM_MACROS_GENERIC_H #warning This stuff is not ported on your system static __inline__ void outb(short port,char val) { printf("outb: generic function call\n"); return; } static __inline__ void outw(short port,short val) { printf("outw: generic function call\n"); return; } static __inline__ void outl(short port,unsigned int val) { printf("outl: generic function call\n"); return; } static __inline__ unsigned int inb(short port) { printf("inb: generic function call\n"); return 0; } static __inline__ unsigned int inw(short port) { printf("inw: generic function call\n"); return 0; } static __inline__ unsigned int inl(short port) { printf("inl: generic function call\n"); return 0; } static __inline__ void intr_disable() { printf("intr_disable: generic function call\n"); } static __inline__ void intr_enable() { printf("intr_enable: generic function call\n"); } #endif xine-lib-1.2/contrib/libdha/sysdep/pci_sparc.c0000644000175000017500000000645014647725152017172 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ static int pci_config_type( void ) { unsigned long tmplong1, tmplong2; unsigned char tmp1, tmp2; int retval; retval = 0; OUTPORT8(PCI_MODE2_ENABLE_REG, 0x00); OUTPORT8(PCI_MODE2_FORWARD_REG, 0x00); tmp1 = INPORT8(PCI_MODE2_ENABLE_REG); tmp2 = INPORT8(PCI_MODE2_FORWARD_REG); if ((tmp1 == 0x00) && (tmp2 == 0x00)) { retval = 2; /*printf("PCI says configuration type 2\n");*/ } else { tmplong1 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, PCI_EN); tmplong2 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, tmplong1); if (tmplong2 == PCI_EN) { retval = 1; /*printf("PCI says configuration type 1\n");*/ } else { /*printf("No PCI !\n");*/ disable_app_io(); /*exit(1);*/ retval = 0xFFFF; } } return retval; } static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT16(PCI_MODE1_DATA_REG); } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT8(PCI_MODE1_DATA_REG); } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT32(PCI_MODE1_DATA_REG,val); } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT16(PCI_MODE1_DATA_REG,val); } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT8(PCI_MODE1_DATA_REG,val); } xine-lib-1.2/contrib/libdha/sysdep/Makefile.am0000644000175000017500000000110514647725152017107 0ustar memeinclude $(top_srcdir)/misc/Makefile.common EXTRA_DIST = \ libdha_os2.c \ libdha_win32.c \ pci_386bsd.c \ pci_alpha.c \ pci_arm32.c \ pci_bsdi.c \ pci_freebsd.c \ pci_generic_cpu.c \ pci_generic_os.c \ pci_ia64.c \ pci_isc.c \ pci_linux.c \ pci_lynx.c \ pci_mach386.c \ pci_netbsd.c \ pci_openbsd.c \ pci_os2.c \ pci_powerpc.c \ pci_sco.c \ pci_sparc.c \ pci_svr4.c \ pci_win32.c \ pci_x86.c noinst_HEADERS = \ AsmMacros_alpha.h \ AsmMacros_arm32.h \ AsmMacros_generic.h \ AsmMacros_ia64.h \ AsmMacros_powerpc.h \ AsmMacros_sparc.h \ AsmMacros_x86.h xine-lib-1.2/contrib/libdha/sysdep/pci_powerpc.c0000644000175000017500000001174114647725151017537 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ static int pci_config_type( void ) { return 1; } #ifdef linux #include #include #include #include "../../bswap.h" #endif #ifdef linux static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { int retval; char path[100]; int fd; short vendor, device; sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd == -1) { retval=0xFFFF; } else if (pread(fd, &vendor, 2, PCI_VENDOR_ID) == 2 && pread(fd, &device, 2, PCI_DEVICE_ID) == 2) { vendor = bswap_16(vendor); device = bswap_16(device); retval = vendor + (device<<16); /*no worries about byte order, all ppc are bigendian*/ } else { retval = 0xFFFF; } if (fd > 0) { close(fd); } return retval; } #else static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { int retval; pciconfig_read(bus, dev<<3, PCI_ID_REG, 4, &retval); return retval; } #endif #ifdef linux static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { long retval; char path[100]; int fd; sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd == -1) { retval=0; } else if (pread(fd, &retval, 4, cmd) == 4) { retval = bswap_32(retval); } else { retval = 0; } if (fd > 0) { close(fd); } return retval; } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { long retval; char path[100]; int fd; sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd == -1) { retval=0; } else if (pread(fd, &retval, 2, cmd) == 2) { retval = bswap_16(retval); } else { retval = 0; } if (fd > 0) { close(fd); } return retval; } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { long retval; char path[100]; int fd; sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd == -1) { retval=0; } else if (pread(fd, &retval, 1, cmd) != 1) { retval = 0; } if (fd > 0) { close(fd); } return retval; } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { char path[100]; int fd; val = bswap_32(val); sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd > 0) { pwrite(fd, &val, 4, cmd); close(fd); } } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { char path[100]; int fd; val = bswap_16(val); sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd > 0) { pwrite(fd, &val, 2, cmd); close(fd); } } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { char path[100]; int fd; sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev); fd = open(path,O_RDONLY|O_SYNC); if (fd > 0) { pwrite(fd, &val, 1, cmd); close(fd); } } #else static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { long retval; pciconfig_read(bus, dev<<3, cmd, 4, &retval); return retval; } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { long retval; pciconfig_read(bus, dev<<3, cmd, 2, &retval); return retval; } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { long retval; pciconfig_read(bus, dev<<3, cmd, 1, &retval); return retval; } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { long retval; pciconfig_write(bus, dev<<3, cmd, 4, val); return retval; } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { long retval; pciconfig_write(bus, dev<<3, cmd, 2, val); return retval; } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { long retval; pciconfig_write(bus, dev<<3, cmd, 1, val); return retval; } #endif xine-lib-1.2/contrib/libdha/sysdep/pci_sco.c0000644000175000017500000000125114647725151016637 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include #include #include #include #include #include #include #include static __inline__ int enable_os_io(void) { #if defined(SI86IOPL) sysi86(SI86IOPL, 3); #else sysi86(SI86V86, V86SC_IOPL, PS_IOPL); #endif return(0); } static __inline__ int disable_os_io(void) { #if defined(SI86IOPL) sysi86(SI86IOPL, 0); #else sysi86(SI86V86, V86SC_IOPL, 0); #endif return(0); } xine-lib-1.2/contrib/libdha/sysdep/pci_386bsd.c0000644000175000017500000000143214647725151017065 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include #include #include #ifndef GCCUSESGAS #define GCCUSESGAS #endif static int io_fd; static __inline__ int enable_os_io(void) { io_fd = -1 ; if ((io_fd = open("/dev/console", O_RDWR, 0)) < 0) { perror("/dev/console"); return(errno); } if (ioctl(io_fd, KDENABIO, 0) < 0) { perror("ioctl(KDENABIO)"); return(errno); } return(0); } static __inline__ int disable_os_io(void) { if (ioctl(io_fd, KDDISABIO, 0) < 0) { perror("ioctl(KDDISABIO)"); close(io_fd); return(errno); } close(io_fd); return(0); } xine-lib-1.2/contrib/libdha/sysdep/pci_generic_os.c0000644000175000017500000000052614647725152020175 0ustar meme/* Generic stuff to compile VIDIX only on any system (SCRATCH) */ #warn This stuff is not ported on yur system static __inline__ int enable_os_io(void) { printf("enable_os_io: generic function call\n"); return 0; } static __inline__ int disable_os_io(void) { printf("disable_os_io: generic function call\n"); return 0; } xine-lib-1.2/contrib/libdha/sysdep/pci_linux.c0000644000175000017500000000172714647725152017223 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include #ifdef __i386__ #include #else #ifndef __sparc__ #include #endif #endif #include "config.h" #ifdef CONFIG_DHAHELPER #include int dhahelper_initialized = 0; int dhahelper_fd = 0; #endif #if defined(__sparc__) || defined(__powerpc__) #define iopl(x) (0) #endif static __inline__ int enable_os_io(void) { #ifdef CONFIG_DHAHELPER dhahelper_fd = open("/dev/dhahelper", O_RDWR); if (dhahelper_fd > 0) { dhahelper_initialized = 1; return(0); } dhahelper_initialized = -1; #endif if (iopl(3) != 0) return(errno); return(0); } static __inline__ int disable_os_io(void) { #ifdef CONFIG_DHAHELPER if (dhahelper_initialized == 1) close(dhahelper_fd); else #endif if (iopl(0) != 0) return(errno); return(0); } xine-lib-1.2/contrib/libdha/sysdep/pci_os2.c0000644000175000017500000000260314647725152016561 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #define INCL_DOSFILEMGR #include static USHORT callgate[3] = {0,0,0}; static __inline__ int enable_os_io(void) { HFILE hfd; ULONG dlen,action; APIRET rc; static char *ioDrvPath = "/dev/fastio$"; if (DosOpen((PSZ)ioDrvPath, (PHFILE)&hfd, (PULONG)&action, (ULONG)0, FILE_SYSTEM, FILE_OPEN, OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY, (ULONG)0) != 0) { fprintf(stderr,"Error opening fastio$ driver...\n"); fprintf(stderr,"Please install xf86sup.sys in config.sys!\n"); return(42); } callgate[0] = callgate[1] = 0; /* Get callgate from driver for fast io to ports and other stuff */ rc = DosDevIOCtl(hfd, (ULONG)0x76, (ULONG)0x64, NULL, 0, NULL, (ULONG*)&callgate[2], sizeof(USHORT), &dlen); if (rc) { fprintf(stderr,"xf86-OS/2: EnableIOPorts failed, rc=%d, dlen=%d; emergency exit\n", rc,dlen); DosClose(hfd); return(42); } /* Calling callgate with function 13 sets IOPL for the program */ asm volatile ("movl $13,%%ebx;.byte 0xff,0x1d;.long _callgate" : /*no outputs */ : /*no inputs */ : "eax","ebx","ecx","edx","cc"); DosClose(hfd); return(0); } static __inline__ int disable_os_io(void) { /* Nothing to do */ return(0); } xine-lib-1.2/contrib/libdha/sysdep/pci_alpha.c0000644000175000017500000000334014647725152017142 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ static int pci_config_type( void ) { return 1; } static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { unsigned long retval; pciconfig_read(bus, dev<<3, PCI_ID_REG, 4, &retval); return retval; } static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long retval; pciconfig_read(bus, dev<<3, cmd, 4, &retval); return retval; } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long retval; pciconfig_read(bus, dev<<3, cmd, 2, &retval); return retval; } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long retval; pciconfig_read(bus, dev<<3, cmd, 1, &retval); return retval; } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { pciconfig_write(bus, dev<<3, cmd, 4, val); } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { pciconfig_write(bus, dev<<3, cmd, 2, val); } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { pciconfig_write(bus, dev<<3, cmd, 1, val); } xine-lib-1.2/contrib/libdha/sysdep/pci_openbsd.c0000644000175000017500000000075214647725152017513 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #ifdef __i386__ #include #include #include static __inline__ int enable_os_io(void) { if (i386_iopl(1) < 0) { perror("i386_iopl"); return(errno); } return(0); } static __inline__ int disable_os_io(void) { /* Nothing to do */ return(0); } #endif xine-lib-1.2/contrib/libdha/sysdep/pci_ia64.c0000644000175000017500000000645014647725151016624 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ static int pci_config_type( void ) { unsigned long tmplong1, tmplong2; unsigned char tmp1, tmp2; int retval; retval = 0; OUTPORT8(PCI_MODE2_ENABLE_REG, 0x00); OUTPORT8(PCI_MODE2_FORWARD_REG, 0x00); tmp1 = INPORT8(PCI_MODE2_ENABLE_REG); tmp2 = INPORT8(PCI_MODE2_FORWARD_REG); if ((tmp1 == 0x00) && (tmp2 == 0x00)) { retval = 2; /*printf("PCI says configuration type 2\n");*/ } else { tmplong1 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, PCI_EN); tmplong2 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, tmplong1); if (tmplong2 == PCI_EN) { retval = 1; /*printf("PCI says configuration type 1\n");*/ } else { /*printf("No PCI !\n");*/ disable_app_io(); /*exit(1);*/ retval = 0xFFFF; } } return retval; } static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT16(PCI_MODE1_DATA_REG); } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT8(PCI_MODE1_DATA_REG); } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT32(PCI_MODE1_DATA_REG,val); } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT16(PCI_MODE1_DATA_REG,val); } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT8(PCI_MODE1_DATA_REG,val); } xine-lib-1.2/contrib/libdha/sysdep/pci_win32.c0000644000175000017500000000057714647725151017027 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include /* Nothing to do for Win9x. For WinNT I have no solution */ static __inline__ int enable_os_io(void) { return(0); } static __inline__ int disable_os_io(void) { return(0); } xine-lib-1.2/contrib/libdha/sysdep/AsmMacros_powerpc.h0000644000175000017500000000247014647725152020656 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ Modified for readability by Nick Kurshev */ #ifndef __ASM_MACROS_POWERPC_H #define __ASM_MACROS_POWERPC_H #if defined(Lynx) || defined(__OpenBSD__) extern unsigned char *ioBase; static __inline__ volatile void eieio() { __asm__ __volatile__ ("eieio"); } static __inline__ void outb(short port, unsigned char value) { *(unsigned char *)(ioBase + port) = value; eieio(); } static __inline__ void outw(short port, unsigned short value) { *(unsigned short *)(ioBase + port) = value; eieio(); } static __inline__ void outl(short port, unsigned short value) { *(unsigned long *)(ioBase + port) = value; eieio(); } static __inline__ unsigned char inb(short port) { unsigned char val; val = *((unsigned char *)(ioBase + port)); eieio(); return(val); } static __inline__ unsigned short inw(short port) { unsigned short val; val = *((unsigned short *)(ioBase + port)); eieio(); return(val); } static __inline__ unsigned long inl(short port) { unsigned long val; val = *((unsigned long *)(ioBase + port)); eieio(); return(val); } #define intr_disable() #define intr_enable() #else #ifdef linux /*nothing*/ #else #include "sysdep/AsmMacros_generic.h" #endif #endif #endif xine-lib-1.2/contrib/libdha/sysdep/libdha_os2.c0000644000175000017500000001202614647725152017231 0ustar meme/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/os2/os2_video.c,v 3.14 2000/10/28 01:42:28 mvojkovi Exp $ */ /* Modified for libdha by Nick Kurshev. */ /* * (c) Copyright 1994,1999 by Holger Veit * * Modified 1996 by Sebastien Marineau * * 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 * HOLGER VEIT 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. * * Except as contained in this notice, the name of Holger Veit shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from Holger Veit. * */ /* $XConsortium: os2_video.c /main/8 1996/10/27 11:49:02 kaleb $ */ #define INCL_DOSFILEMGR #include "os2.h" /***************************************************************************/ /* Video Memory Mapping helper functions */ /***************************************************************************/ /* This section uses the xf86sup.sys driver developed for xfree86. * The driver allows mapping of physical memory * You must install it with a line DEVICE=path\xf86sup.sys in config.sys. */ static HFILE mapdev = -1; static ULONG stored_virt_addr; static char* mappath = "\\DEV\\PMAP$"; static HFILE open_mmap() { APIRET rc; ULONG action; if (mapdev != -1) return mapdev; rc = DosOpen((PSZ)mappath, (PHFILE)&mapdev, (PULONG)&action, (ULONG)0, FILE_SYSTEM, FILE_OPEN, OPEN_SHARE_DENYNONE|OPEN_FLAGS_NOINHERIT|OPEN_ACCESS_READONLY, (ULONG)0); if (rc!=0) mapdev = -1; return mapdev; } static void close_mmap() { if (mapdev != -1) DosClose(mapdev); mapdev = -1; } /* this structure is used as a parameter packet for the direct access * ioctl of pmap$ */ /* Changed here for structure of driver PMAP$ */ typedef struct{ ULONG addr; ULONG size; } DIOParPkt; /* This is the data packet for the mapping function */ typedef struct { ULONG addr; USHORT sel; } DIODtaPkt; /***************************************************************************/ /* Video Memory Mapping section */ /***************************************************************************/ static long callcount = 0L; /* ARGSUSED */ void * map_phys_mem(unsigned long base, unsigned long size) { DIOParPkt par; ULONG plen; DIODtaPkt dta; ULONG dlen; static BOOL ErrRedir = FALSE; APIRET rc; par.addr = (ULONG)base; par.size = (ULONG)size; plen = sizeof(par); dlen = sizeof(dta); open_mmap(); if (mapdev == -1) { perror("libdha: device xf86sup.sys is not installed"); exit(1); } if ((rc=DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x44, (PVOID)&par, (ULONG)plen, (PULONG)&plen, (PVOID)&dta, (ULONG)dlen, (PULONG)&dlen)) == 0) { if (dlen==sizeof(dta)) { callcount++; return (void *)dta.addr; } /*else fail*/ } return (void *)-1; } /* ARGSUSED */ void unmap_phys_mem(void * base, unsigned long size) { DIOParPkt par; ULONG plen,vmaddr; /* We need here the VIRTADDR for unmapping, not the physical address */ /* This should be taken care of either here by keeping track of allocated */ /* pointers, but this is also already done in the driver... Thus it would */ /* be a waste to do this tracking twice. Can this be changed when the fn. */ /* is called? This would require tracking this function in all servers, */ /* and changing it appropriately to call this with the virtual adress */ /* If the above mapping function is only called once, then we can store */ /* the virtual adress and use it here.... */ par.addr = (ULONG)base; par.size = 0xffffffff; /* This is the virtual address parameter. Set this to ignore */ plen = sizeof(par); if (mapdev != -1) { DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x46, (PVOID)&par, (ULONG)plen, (PULONG)&plen, &vmaddr, sizeof(ULONG), &plen); callcount--; } /* Now if more than one region has been allocated and we close the driver, * the other pointers will immediately become invalid. We avoid closing * driver for now, but this should be fixed for server exit */ if(!callcount) close_mmap(); } xine-lib-1.2/contrib/libdha/sysdep/pci_bsdi.c0000644000175000017500000000153014647725151016774 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include #include #include #include #ifndef GCCUSESGAS #define GCCUSESGAS #endif static int io_fd; static __inline__ int enable_os_io(void) { io_fd = -1 ; if ((io_fd = open("/dev/console", O_RDWR, 0)) < 0) { perror("/dev/console"); return(errno); } if (ioctl(io_fd, PCCONENABIOPL, 0) < 0) { perror("ioctl(PCCONENABIOPL)"); return(errno); } return(0); } static __inline__ int disable_os_io(void) { if (ioctl(io_fd, PCCONDISABIOPL, 0) < 0) { perror("ioctl(PCCONDISABIOPL)"); close(io_fd); return(errno); } close(io_fd); return(0); } xine-lib-1.2/contrib/libdha/sysdep/AsmMacros_sparc.h0000644000175000017500000000246214647725151020307 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ Modified for readability by Nick Kurshev */ #ifndef __ASM_MACROS_SPARC_H #define __ASM_MACROS_SPARC_H #ifndef ASI_PL #define ASI_PL 0x88 #endif static __inline__ void outb(unsigned long port, char val) { __asm__ __volatile__("stba %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL)); } static __inline__ void outw(unsigned long port, char val) { __asm__ __volatile__("stha %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL)); } static __inline__ void outl(unsigned long port, char val) { __asm__ __volatile__("sta %0, [%1] %2" : : "r" (val), "r" (port), "i" (ASI_PL)); } static __inline__ unsigned int inb(unsigned long port) { unsigned char ret; __asm__ __volatile__("lduba [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL)); return ret; } static __inline__ unsigned int inw(unsigned long port) { unsigned char ret; __asm__ __volatile__("lduha [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL)); return ret; } static __inline__ unsigned int inl(unsigned long port) { unsigned char ret; __asm__ __volatile__("lda [%1] %2, %0" : "=r" (ret) : "r" (port), "i" (ASI_PL)); return ret; } #define intr_disable() #define intr_enable() #endif xine-lib-1.2/contrib/libdha/sysdep/pci_generic_cpu.c0000644000175000017500000000326614647725152020347 0ustar meme/* Generic stuff to compile VIDIX only on any system (SCRATCH) */ #warning This stuff is not ported on your system static int pci_config_type( void ) { printf("pci_config_type: generic function call\n"); return 0xFFFF; } static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { printf("pci_get_vendor: generic function call\n"); return 0; } static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { printf("pci_config_read_long: generic function call\n"); return 0; } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { printf("pci_config_read_word: generic function call\n"); return 0; } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { printf("pci_config_read_byte: generic function call\n"); return 0; } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { printf("pci_config_write_long: generic function call\n"); } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { printf("pci_config_write_word: generic function call\n"); } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { printf("pci_config_write_byte: generic function call\n"); } xine-lib-1.2/contrib/libdha/sysdep/pci_isc.c0000644000175000017500000000122014647725151016625 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include #include #include #include #include #include #include static __inline__ int enable_os_io(void) { #if defined(SI86IOPL) sysi86(SI86IOPL, 3); #else sysi86(SI86V86, V86SC_IOPL, PS_IOPL); #endif return(0); } static __inline__ int disable_os_io(void) { #if defined(SI86IOPL) sysi86(SI86IOPL, 0); #else sysi86(SI86V86, V86SC_IOPL, 0); #endif return(0); } xine-lib-1.2/contrib/libdha/sysdep/pci_arm32.c0000644000175000017500000000645414647725152017012 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ static int pci_config_type( void ) { unsigned long tmplong1, tmplong2; unsigned char tmp1, tmp2; int retval; retval = 0; OUTPORT8(PCI_MODE2_ENABLE_REG, 0x00); OUTPORT8(PCI_MODE2_FORWARD_REG, 0x00); tmp1 = INPORT8(PCI_MODE2_ENABLE_REG); tmp2 = INPORT8(PCI_MODE2_FORWARD_REG); if ((tmp1 == 0x00) && (tmp2 == 0x00)) { retval = 2; /*printf("PCI says configuration type 2\n");*/ } else { tmplong1 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, PCI_EN); tmplong2 = INPORT32(PCI_MODE1_ADDRESS_REG); OUTPORT32(PCI_MODE1_ADDRESS_REG, tmplong1); if (tmplong2 == PCI_EN) { retval = 1; /*printf("PCI says configuration type 1\n");*/ } else { /*printf("No PCI !\n");*/ disable_app_io(); /*exit(1);*/ retval = 0xFFFF; } } return retval; } static int pci_get_vendor( unsigned char bus, unsigned char dev, int func) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_long( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT32(PCI_MODE1_DATA_REG); } static long pci_config_read_word( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT16(PCI_MODE1_DATA_REG); } static long pci_config_read_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); return INPORT8(PCI_MODE1_DATA_REG); } static void pci_config_write_long( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT32(PCI_MODE1_DATA_REG,val); } static void pci_config_write_word( unsigned char bus, unsigned char dev, int func, unsigned cmd, unsigned val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT16(PCI_MODE1_DATA_REG,val); } static void pci_config_write_byte( unsigned char bus, unsigned char dev, int func, unsigned cmd, long val) { unsigned long config_cmd; config_cmd = PCI_EN | (bus<<16) | (dev<<11) | (func<<8); OUTPORT32(PCI_MODE1_ADDRESS_REG, config_cmd | cmd); OUTPORT8(PCI_MODE1_DATA_REG,val); } xine-lib-1.2/contrib/libdha/sysdep/libdha_win32.c0000644000175000017500000000465314647725151017476 0ustar meme/* MAPDEV.h - include file for VxD MAPDEV Copyright (c) 1996 Vireo Software, Inc. Modified for libdha by Nick Kurshev. */ #include /* This is the request structure that applications use to request services from the MAPDEV VxD. */ typedef struct _MapDevRequest { DWORD mdr_ServiceID; /* supplied by caller */ LPVOID mdr_PhysicalAddress; /* supplied by caller */ DWORD mdr_SizeInBytes; /* supplied by caller */ LPVOID mdr_LinearAddress; /* returned by VxD */ WORD mdr_Selector; /* returned if 16-bit caller */ WORD mdr_Status; /* MDR_xxxx code below */ } MAPDEVREQUEST, *PMAPDEVREQUEST; #define MDR_SERVICE_MAP CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_NEITHER, FILE_ANY_ACCESS) #define MDR_SERVICE_UNMAP CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_NEITHER, FILE_ANY_ACCESS) #define MDR_STATUS_SUCCESS 1 #define MDR_STATUS_ERROR 0 /*#include "winioctl.h"*/ #define FILE_DEVICE_UNKNOWN 0x00000022 #define METHOD_NEITHER 3 #define FILE_ANY_ACCESS 0 #define CTL_CODE( DeviceType, Function, Method, Access ) ( \ ((DeviceType)<<16) | ((Access)<<14) | ((Function)<<2) | (Method) ) /* Memory Map a piece of Real Memory */ void *map_phys_mem(unsigned base, unsigned size) { HANDLE hDevice ; PVOID inBuf[1] ; /* buffer for struct pointer to VxD */ DWORD RetInfo[2] ; /* buffer to receive data from VxD */ DWORD cbBytesReturned ; /* count of bytes returned from VxD */ MAPDEVREQUEST req ; /* map device request structure */ DWORD *pNicstar, Status, Time ; int i ; char *endptr ; const PCHAR VxDName = "\\\\.\\MAPDEV.VXD" ; const PCHAR VxDNameAlreadyLoaded = "\\\\.\\MAPDEV" ; hDevice = CreateFile(VxDName, 0,0,0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0) ; if (hDevice == INVALID_HANDLE_VALUE) hDevice = CreateFile(VxDNameAlreadyLoaded, 0,0,0, CREATE_NEW, FILE_FLAG_DELETE_ON_CLOSE, 0) ; if (hDevice == INVALID_HANDLE_VALUE) { fprintf(stderr, "Cannot open driver, error=%08lx\n", GetLastError()) ; exit(1) ; } req.mdr_ServiceID = MDR_SERVICE_MAP ; req.mdr_PhysicalAddress = (PVOID)base ; req.mdr_SizeInBytes = size ; inBuf[0] = &req ; if ( ! DeviceIoControl(hDevice, MDR_SERVICE_MAP, inBuf, sizeof(PVOID), NULL, 0, &cbBytesReturned, NULL) ) { fprintf(stderr, "Failed to map device\n") ; exit(1) ; } return (void*)req.mdr_LinearAddress ; } void unmap_phys_mem(void *ptr, unsigned size) { } xine-lib-1.2/contrib/libdha/sysdep/pci_mach386.c0000644000175000017500000000074714647725151017235 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include static int io_fd; static __inline__ int enable_os_io(void) { io_fd = -1 ; if ((io_fd = open("/dev/iopl", O_RDWR, 0)) < 0) { perror("/dev/iopl"); return(errno); } return(0); } static __inline__ int disable_os_io(void) { close(io_fd); return(0); } xine-lib-1.2/contrib/libdha/sysdep/pci_netbsd.c0000644000175000017500000000152114647725151017332 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include #include #include #include #ifndef GCCUSESGAS #define GCCUSESGAS #endif static int io_fd; static __inline__ int enable_os_io(void) { io_fd = -1 ; #if !defined(USE_I386_IOPL) if ((io_fd = open("/dev/io", O_RDWR, 0)) < 0) { perror("/dev/io"); return(errno); } #else if (i386_iopl(1) < 0) { perror("i386_iopl"); return(errno); } #endif /* USE_I386_IOPL */ return(0); } static __inline__ int disable_os_io(void) { #if !defined(USE_I386_IOPL) close(io_fd); #else if (i386_iopl(0) < 0) { perror("i386_iopl"); return(errno); } #endif /* NetBSD1_1 */ return(0); } xine-lib-1.2/contrib/libdha/sysdep/AsmMacros_arm32.h0000644000175000017500000000264214647725151020123 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ Modified for readability by Nick Kurshev */ #ifndef __ASM_MACROS_ARM32_H #define __ASM_MACROS_ARM32_H unsigned int IOPortBase; /* Memory mapped I/O port area */ static __inline__ void outb(short port,char val) { if ((unsigned short)port >= 0x400) return; *(volatile unsigned char*)(((unsigned short)(port))+IOPortBase) = val; } static __inline__ void outw(short port,short val) { if ((unsigned short)port >= 0x400) return; *(volatile unsigned short*)(((unsigned short)(port))+IOPortBase) = val; } static __inline__ void outl(short port,int val) { if ((unsigned short)port >= 0x400) return; *(volatile unsigned long*)(((unsigned short)(port))+IOPortBase) = val; } static __inline__ unsigned int inb(short port) { if ((unsigned short)port >= 0x400) return((unsigned int)-1); return(*(volatile unsigned char*)(((unsigned short)(port))+IOPortBase)); } static __inline__ unsigned int inw(short port) { if ((unsigned short)port >= 0x400) return((unsigned int)-1); return(*(volatile unsigned short*)(((unsigned short)(port))+IOPortBase)); } static __inline__ unsigned int inl(short port) { if ((unsigned short)port >= 0x400) return((unsigned int)-1); return(*(volatile unsigned long*)(((unsigned short)(port))+IOPortBase)); } #define intr_disable() #define intr_enable() #endif xine-lib-1.2/contrib/libdha/sysdep/pci_svr4.c0000644000175000017500000000140714647725152016755 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ Modified for readability by Nick Kurshev */ #include #include #include #if defined(NCR) #define __STDC #include #undef __STDC #else #include #endif #if defined(sun) # ifndef __EXTENSIONS__ # define __EXTENSIONS__ # endif # include #endif static __inline__ int enable_os_io(void) { #if defined(SI86IOPL) sysi86(SI86IOPL, 3); #else sysi86(SI86V86, V86SC_IOPL, PS_IOPL); #endif return(0); } static __inline__ int disable_os_io(void) { #if defined(SI86IOPL) sysi86(SI86IOPL, 0); #else sysi86(SI86V86, V86SC_IOPL, 0); #endif return(0); } xine-lib-1.2/contrib/libdha/sysdep/AsmMacros_alpha.h0000644000175000017500000000127514647725152020266 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ Modified for readability by Nick Kurshev */ #ifndef __ASM_MACROS_ALPHA_H #define __ASM_MACROS_ALPHA_H #if defined (linux) #include #elif defined (__FreeBSD__) #include extern void outb(u_int32_t port, u_int8_t val); extern void outw(u_int32_t port, u_int16_t val); extern void outl(u_int32_t port, u_int32_t val); extern u_int8_t inb(u_int32_t port); extern u_int16_t inw(u_int32_t port); extern u_int32_t inl(u_int32_t port); #else #include "sysdep/AsmMacros_generic.h" #endif #define intr_disable() #define intr_enable() #endif xine-lib-1.2/contrib/libdha/sysdep/AsmMacros_x86.h0000644000175000017500000000255614647725151017630 0ustar meme/* This file is based on: $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ Modified for readability by Nick Kurshev */ #ifndef __ASM_MACROS_X86_H #define __ASM_MACROS_X86_H #if defined (WINNT) #include "sysdep/AsmMacros_generic.h" #else #include "config.h" static __inline__ void outb(short port,char val) { __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port)); return; } static __inline__ void outw(short port,short val) { __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port)); return; } static __inline__ void outl(short port,unsigned int val) { __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port)); return; } static __inline__ unsigned int inb(short port) { unsigned char ret; __asm__ __volatile__("inb %1,%0" : "=a" (ret) : "d" (port)); return ret; } static __inline__ unsigned int inw(short port) { unsigned short ret; __asm__ __volatile__("inw %1,%0" : "=a" (ret) : "d" (port)); return ret; } static __inline__ unsigned int inl(short port) { unsigned int ret; __asm__ __volatile__("inl %1,%0" : "=a" (ret) : "d" (port)); return ret; } static __inline__ void intr_disable() { __asm__ __volatile__("cli"); } static __inline__ void intr_enable() { __asm__ __volatile__("sti"); } #endif #endif xine-lib-1.2/contrib/libdha/pci.c0000644000175000017500000006276214647725151014502 0ustar meme/* (C) 2002 - library implementation by Nick Kyrshev XFree86 3.3.3 scanpci.c, modified for GATOS/win/gfxdump by Øyvind Aabling. */ /* $XConsortium: scanpci.c /main/25 1996/10/27 11:48:40 kaleb $ */ /* * name: scanpci.c * * purpose: This program will scan for and print details of * devices on the PCI bus. * author: Robin Cutshaw (robin@xfree86.org) * * supported O/S's: SVR4, UnixWare, SCO, Solaris, * FreeBSD, NetBSD, 386BSD, BSDI BSD/386, * Linux, Mach/386, ISC * DOS (WATCOM 9.5 compiler) * * compiling: [g]cc scanpci.c -o scanpci * for SVR4 (not Solaris), UnixWare use: * [g]cc -DSVR4 scanpci.c -o scanpci * for DOS, watcom 9.5: * wcc386p -zq -omaxet -7 -4s -s -w3 -d2 name.c * and link with PharLap or other dos extender for exe * */ /* $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ */ /* * Copyright 1995 by Robin Cutshaw * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the names of the above listed copyright holder(s) * not be used in advertising or publicity pertaining to distribution of * the software without specific, written prior permission. The above listed * copyright holder(s) make(s) no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE * LIABLE FOR ANY SPECIAL, 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. * */ #include "libdha.h" #include #include #include #include #include #include #include "kernelhelper/dhahelper.h" #ifdef __unix__ #include #endif #if 0 #if defined(__SUNPRO_C) || defined(sun) || defined(__sun) #include #else #include #endif #include #endif #if defined(Lynx) && defined(__powerpc__) /* let's mimick the Linux Alpha stuff for LynxOS so we don't have * to change too much code */ #include static unsigned char *pciConfBase; static __inline__ unsigned long static swapl(unsigned long val) { unsigned char *p = (unsigned char *)&val; return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0)); } #define BUS(tag) (((tag)>>16)&0xff) #define DFN(tag) (((tag)>>8)&0xff) #define PCIBIOS_DEVICE_NOT_FOUND 0x86 #define PCIBIOS_SUCCESSFUL 0x00 int pciconfig_read( unsigned char bus, unsigned char dev, unsigned char offset, int len, /* unused, alway 4 */ unsigned long *val) { unsigned long _val; unsigned long *ptr; dev >>= 3; if (bus || dev >= 16) { *val = 0xFFFFFFFF; return PCIBIOS_DEVICE_NOT_FOUND; } else { ptr = (unsigned long *)(pciConfBase + ((1<>= 3; _val = swapl(val); if (bus || dev >= 16) { return PCIBIOS_DEVICE_NOT_FOUND; } else { ptr = (unsigned long *)(pciConfBase + ((1<=MAX_PCI_DEVICES) return ; pci_lst[pcicards].bus = pcibus ; pci_lst[pcicards].card = pcicard ; pci_lst[pcicards].func = pcifunc ; pci_lst[pcicards].vendor = pcr->_vendor ; pci_lst[pcicards].device = pcr->_device ; pci_lst[pcicards].base0 = 0xFFFFFFFF ; pci_lst[pcicards].base1 = 0xFFFFFFFF ; pci_lst[pcicards].base2 = 0xFFFFFFFF ; pci_lst[pcicards].base3 = 0xFFFFFFFF ; pci_lst[pcicards].base4 = 0xFFFFFFFF ; pci_lst[pcicards].base5 = 0xFFFFFFFF ; pci_lst[pcicards].baserom = 0x000C0000 ; if (pcr->_base0) pci_lst[pcicards].base0 = pcr->_base0 & ((pcr->_base0&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; if (pcr->_base1) pci_lst[pcicards].base1 = pcr->_base1 & ((pcr->_base1&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; if (pcr->_base2) pci_lst[pcicards].base2 = pcr->_base2 & ((pcr->_base2&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; if (pcr->_base3) pci_lst[pcicards].base3 = pcr->_base3 & ((pcr->_base0&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; if (pcr->_base4) pci_lst[pcicards].base4 = pcr->_base4 & ((pcr->_base1&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; if (pcr->_base5) pci_lst[pcicards].base5 = pcr->_base5 & ((pcr->_base2&0x1) ? 0xFFFFFFFC : 0xFFFFFFF0) ; if (pcr->_baserom) pci_lst[pcicards].baserom = pcr->_baserom ; pci_lst[pcicards].irq = pcr->_int_line; pci_lst[pcicards].ipin= pcr->_int_pin; pci_lst[pcicards].gnt = pcr->_min_gnt; pci_lst[pcicards].lat = pcr->_max_lat; pcicards++; } /*main(int argc, char *argv[])*/ static int __pci_scan(pciinfo_t *pci_list,unsigned *num_pci) { unsigned int idx; struct pci_config_reg pcr; int do_mode1_scan = 0, do_mode2_scan = 0; int func, hostbridges=0; int ret = -1; pci_lst = pci_list; pcicards = 0; ret = enable_app_io(); if (ret != 0) return(ret); if((pcr._configtype = pci_config_type()) == 0xFFFF) return ENODEV; /* Try pci config 1 probe first */ if ((pcr._configtype == 1) || do_mode1_scan) { /*printf("\nPCI probing configuration type 1\n");*/ pcr._ioaddr = 0xFFFF; pcr._pcibuses[0] = 0; pcr._pcinumbus = 1; pcr._pcibusidx = 0; idx = 0; do { /*printf("Probing for devices on PCI bus %d:\n\n", pcr._pcibusidx);*/ for (pcr._cardnum = 0x0; pcr._cardnum < MAX_PCI_DEVICES_PER_BUS; pcr._cardnum += 0x1) { func = 0; do { /* loop over the different functions, if present */ pcr._device_vendor = pci_get_vendor(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, func); if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) break; /* nothing there */ /*printf("\npci bus 0x%x cardnum 0x%02x function 0x%04x: vendor 0x%04x device 0x%04x\n", pcr._pcibuses[pcr._pcibusidx], pcr._cardnum, func, pcr._vendor, pcr._device);*/ pcibus = pcr._pcibuses[pcr._pcibusidx]; pcicard = pcr._cardnum; pcifunc = func; pcr._status_command = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_CMD_STAT_REG); pcr._class_revision = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_CLASS_REG); pcr._bist_header_latency_cache = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_HEADER_MISC); pcr._base0 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAP_REG_START); pcr._base1 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAP_REG_START+4); pcr._base2 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAP_REG_START+8); pcr._base3 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAP_REG_START+0x0C); pcr._base4 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAP_REG_START+0x10); pcr._base5 = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAP_REG_START+0x14); pcr._baserom = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAP_ROM_REG); #if 0 pcr._int_pin = pci_config_read_byte(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_INTERRUPT_PIN); pcr._int_line = pci_config_read_byte(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_INTERRUPT_REG); pcr._min_gnt = pci_config_read_byte(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MIN_GNT); pcr._max_lat = pci_config_read_byte(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_MAX_LAT); #else pcr._max_min_ipin_iline = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_INTERRUPT_REG); #endif pcr._user_config = pci_config_read_long(pcr._pcibuses[pcr._pcibusidx], pcr._cardnum,func,PCI_REG_USERCONFIG); /* check for pci-pci bridges */ #define PCI_CLASS_MASK 0xff000000 #define PCI_SUBCLASS_MASK 0x00ff0000 #define PCI_CLASS_BRIDGE 0x06000000 #define PCI_SUBCLASS_BRIDGE_PCI 0x00040000 switch(pcr._class_revision & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) { case PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI: if (pcr._secondary_bus_number > 0) { pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; } break; case PCI_CLASS_BRIDGE: if ( ++hostbridges > 1) { pcr._pcibuses[pcr._pcinumbus] = pcr._pcinumbus; pcr._pcinumbus++; } break; default: break; } if((func==0) && ((pcr._header_type & PCI_MULTIFUNC_DEV) == 0)) { /* not a multi function device */ func = 8; } else { func++; } if (idx++ >= MAX_PCI_DEVICES) continue; identify_card(&pcr); } while( func < 8 ); } } while (++pcr._pcibusidx < pcr._pcinumbus); } #if !defined(__alpha__) && !defined(__powerpc__) /* Now try pci config 2 probe (deprecated) */ if ((pcr._configtype == 2) || do_mode2_scan) { OUTPORT8(PCI_MODE2_ENABLE_REG, 0xF1); OUTPORT8(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ /*printf("\nPCI probing configuration type 2\n");*/ pcr._pcibuses[0] = 0; pcr._pcinumbus = 1; pcr._pcibusidx = 0; idx = 0; do { for (pcr._ioaddr = 0xC000; pcr._ioaddr < 0xD000; pcr._ioaddr += 0x0100){ OUTPORT8(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ pcr._device_vendor = INPORT32(pcr._ioaddr); OUTPORT8(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ if ((pcr._vendor == 0xFFFF) || (pcr._device == 0xFFFF)) continue; if ((pcr._vendor == 0xF0F0) || (pcr._device == 0xF0F0)) continue; /* catch ASUS P55TP4XE motherboards */ /*printf("\npci bus 0x%x slot at 0x%04x, vendor 0x%04x device 0x%04x\n", pcr._pcibuses[pcr._pcibusidx], pcr._ioaddr, pcr._vendor, pcr._device);*/ pcibus = pcr._pcibuses[pcr._pcibusidx] ; pcicard = pcr._ioaddr ; pcifunc = 0 ; OUTPORT8(PCI_MODE2_FORWARD_REG, pcr._pcibuses[pcr._pcibusidx]); /* bus 0 for now */ pcr._status_command = INPORT32(pcr._ioaddr + 0x04); pcr._class_revision = INPORT32(pcr._ioaddr + 0x08); pcr._bist_header_latency_cache = INPORT32(pcr._ioaddr + 0x0C); pcr._base0 = INPORT32(pcr._ioaddr + 0x10); pcr._base1 = INPORT32(pcr._ioaddr + 0x14); pcr._base2 = INPORT32(pcr._ioaddr + 0x18); pcr._base3 = INPORT32(pcr._ioaddr + 0x1C); pcr._base4 = INPORT32(pcr._ioaddr + 0x20); pcr._base5 = INPORT32(pcr._ioaddr + 0x24); pcr._baserom = INPORT32(pcr._ioaddr + 0x30); pcr._max_min_ipin_iline = INPORT8(pcr._ioaddr + 0x3C); pcr._user_config = INPORT32(pcr._ioaddr + 0x40); OUTPORT8(PCI_MODE2_FORWARD_REG, 0x00); /* bus 0 for now */ /* check for pci-pci bridges (currently we only know Digital) */ if ((pcr._vendor == 0x1011) && (pcr._device == 0x0001)) if (pcr._secondary_bus_number > 0) pcr._pcibuses[pcr._pcinumbus++] = pcr._secondary_bus_number; if (idx++ >= MAX_PCI_DEVICES) continue; identify_card(&pcr); } } while (++pcr._pcibusidx < pcr._pcinumbus); OUTPORT8(PCI_MODE2_ENABLE_REG, 0x00); } #endif /* __alpha__ */ disable_app_io(); *num_pci = pcicards; return 0 ; } #if !defined(ENOTSUP) #if defined(EOPNOTSUPP) #define ENOTSUP EOPNOTSUPP #else #warning "ENOTSUP nor EOPNOTSUPP defined!" #endif #endif int pci_scan(pciinfo_t *pci_list,unsigned *num_pci) { int libdha_fd; if ( (libdha_fd = open("/dev/dhahelper",O_RDWR)) < 0) { return __pci_scan(pci_list,num_pci); } else { dhahelper_pci_device_t pci_dev; unsigned idx; idx = 0; while(ioctl(libdha_fd, DHAHELPER_PCI_FIND, &pci_dev)==0) { pci_list[idx].bus = pci_dev.bus; pci_list[idx].card = pci_dev.card; pci_list[idx].func = pci_dev.func; pci_list[idx].vendor = pci_dev.vendor; pci_list[idx].device = pci_dev.device; pci_list[idx].base0 = pci_dev.base0?pci_dev.base0:0xFFFFFFFF; pci_list[idx].base1 = pci_dev.base1?pci_dev.base1:0xFFFFFFFF; pci_list[idx].base2 = pci_dev.base2?pci_dev.base2:0xFFFFFFFF; pci_list[idx].baserom = pci_dev.baserom?pci_dev.baserom:0x000C0000; pci_list[idx].base3 = pci_dev.base3?pci_dev.base3:0xFFFFFFFF; pci_list[idx].base4 = pci_dev.base4?pci_dev.base4:0xFFFFFFFF; pci_list[idx].base5 = pci_dev.base5?pci_dev.base5:0xFFFFFFFF; pci_list[idx].irq = pci_dev.irq; pci_list[idx].ipin = pci_dev.ipin; pci_list[idx].gnt = pci_dev.gnt; pci_list[idx].lat = pci_dev.lat; idx++; } *num_pci=idx; close(libdha_fd); } return 0; } int pci_config_read(unsigned char bus, unsigned char dev, unsigned char func, unsigned char cmd, int len, unsigned long *val) { int ret; int dhahelper_fd; if ( (dhahelper_fd = open("/dev/dhahelper",O_RDWR)) > 0) { int retval; dhahelper_pci_config_t pcic; pcic.operation = PCI_OP_READ; pcic.bus = bus; pcic.dev = dev; pcic.func = func; pcic.cmd = cmd; pcic.size = len; retval = ioctl(dhahelper_fd, DHAHELPER_PCI_CONFIG, &pcic); close(dhahelper_fd); *val = pcic.ret; return retval; } ret = enable_app_io(); if (ret != 0) return(ret); switch(len) { case 4: ret = pci_config_read_long(bus, dev, func, cmd); break; case 2: ret = pci_config_read_word(bus, dev, func, cmd); break; case 1: ret = pci_config_read_byte(bus, dev, func, cmd); break; default: printf("libdha_pci: wrong length to read: %u\n",len); } disable_app_io(); *val = ret; return(0); } int pci_config_write(unsigned char bus, unsigned char dev, unsigned char func, unsigned char cmd, int len, unsigned long val) { int ret; int dhahelper_fd; if ( (dhahelper_fd = open("/dev/dhahelper",O_RDWR)) > 0) { int retval; dhahelper_pci_config_t pcic; pcic.operation = PCI_OP_WRITE; pcic.bus = bus; pcic.dev = dev; pcic.func = func; pcic.cmd = cmd; pcic.size = len; pcic.ret = val; retval = ioctl(dhahelper_fd, DHAHELPER_PCI_CONFIG, &pcic); close(dhahelper_fd); return retval; } ret = enable_app_io(); if (ret != 0) return ret; switch(len) { case 4: pci_config_write_long(bus, dev, func, cmd, val); break; case 2: pci_config_write_word(bus, dev, func, cmd, val); break; case 1: pci_config_write_byte(bus, dev, func, cmd, val); break; default: printf("libdha_pci: wrong length to read: %u\n",len); } disable_app_io(); return 0; } xine-lib-1.2/contrib/libdha/test.c0000644000175000017500000000254614647725152014701 0ustar meme#include "libdha.h" #include "pci_names.h" #include #include #include #include /* for __WORDSIZE */ int main( void ) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; err = pci_scan(lst,&num_pci); if(err) { printf("Error occured during pci scan: %s\n",strerror(err)); return EXIT_FAILURE; } else { printf(" Bus:card:func vend:dev base0 :base1 :base2 :baserom :irq:pin:gnt:lat\n"); for(i=0;i 32 printf("%04X:%04X:%04X %04X:%04X %16X:%16X:%16X:%16X:%02X :%02X :%02X :%02X\n" #else printf("%04X:%04X:%04X %04X:%04X %08X:%08X:%08X:%08X:%02X :%02X :%02X :%02X\n" #endif ,lst[i].bus,lst[i].card,lst[i].func ,lst[i].vendor,lst[i].device ,lst[i].base0,lst[i].base1,lst[i].base2,lst[i].baserom ,lst[i].irq,lst[i].ipin,lst[i].gnt,lst[i].lat); printf("Additional info:\n"); printf("================\n"); printf("base3 :base4 :base5 :name (vendor)\n"); for(i=0;i #include #include #include /* mlock */ #include #include #include #include "libdha.h" #include "kernelhelper/dhahelper.h" static int libdha_fd=-1; #define ALLOWED_VER 0x10 int bm_open( void ) { int retv; libdha_fd = open("/dev/dhahelper",O_RDWR); retv = libdha_fd > 0 ? 0 : ENXIO; if(!retv) { int ver; ioctl(libdha_fd,DHAHELPER_GET_VERSION,&ver); if(ver < ALLOWED_VER) { printf("libdha: You have wrong version (%i) of /dev/dhahelper\n" "libdha: Please upgrade your driver up to ver=%i\n",ver,ALLOWED_VER); retv = EINVAL; close(libdha_fd); } } else printf("libdha: Can't open /dev/dhahelper\n"); return retv; } void bm_close( void ) { close(libdha_fd); } int bm_virt_to_phys( void * virt_addr, unsigned long length, unsigned long * parray ) { dhahelper_vmi_t vmi; vmi.virtaddr = virt_addr; vmi.length = length; vmi.realaddr = parray; if(libdha_fd > 0) return ioctl(libdha_fd,DHAHELPER_VIRT_TO_PHYS,&vmi); return ENXIO; } int bm_virt_to_bus( void * virt_addr, unsigned long length, unsigned long * barray ) { dhahelper_vmi_t vmi; vmi.virtaddr = virt_addr; vmi.length = length; vmi.realaddr = barray; if(libdha_fd > 0) return ioctl(libdha_fd,DHAHELPER_VIRT_TO_BUS,&vmi); return ENXIO; } void * bm_alloc_pci_shmem(pciinfo_t *pi, unsigned mem_bitness, unsigned long length,int op ) { printf("libdha: Pure virtual function call - bm_alloc_pci_shmem()\n"); #if 0 dhahelper_mem_t vmi; vmi.length = length; if(libdha_fd > 0) { if(ioctl(libdha_fd,DHAHELPER_ALLOC_PA,&vmi) == 0) return vmi.addr; } #else (void)pi; (void)mem_bitness; (void)length; (void)op; #endif return NULL; } void bm_free_pci_shmem(void * pci_shmem) { printf("libdha: Pure virtual function call - bm_free_pci_shmem()\n"); #if 0 dhahelper_mem_t vmi; vmi.addr = virt_addr; vmi.length = length; if(libdha_fd > 0) { ioctl(libdha_fd,DHAHELPER_FREE_PA,&vmi); } #else (void)pci_shmem; #endif } int bm_lock_mem( const void *addr, unsigned long length ) { dhahelper_mem_t vmi; vmi.addr = (void *) addr; vmi.length = length; if(libdha_fd > 0) { return ioctl(libdha_fd,DHAHELPER_LOCK_MEM,&vmi); } return mlock(addr,length); } int bm_unlock_mem( const void * addr, unsigned long length ) { dhahelper_mem_t vmi; vmi.addr = (void *) addr; vmi.length = length; if(libdha_fd > 0) { return ioctl(libdha_fd,DHAHELPER_UNLOCK_MEM,&vmi); } return munlock(addr,length); } xine-lib-1.2/contrib/libdha/bin/0000755000175000017500000000000014647725152014317 5ustar memexine-lib-1.2/contrib/libdha/bin/mapdev.copyright0000644000175000017500000000631714647725151017533 0ustar memeFrom khazzah@melita.com Mon Jun 23 21:48:19 1997 Return-Path: Received: from melita.melita.com by max4.rrze.uni-erlangen.de; Mon, 23 Jun 1997 21:48:16 +0200 Received: from mailgate.melita.com ([192.68.22.8]) by melita.melita.com (8.6.12/8.6.9) with SMTP id QAA29292 for ; Mon, 23 Jun 1997 16:17:55 -0400 Received: by mailgate.melita.com with Microsoft Mail id <33AEFD34@mailgate.melita.com>; Mon, 23 Jun 97 15:48:20 PDT From: Karen Hazzah To: "'Stefan.Dirsch@stud.uni-erlangen.de'" Subject: Your post to vxd newsgroup Date: Sun, 22 Jun 97 20:51:00 PDT Message-ID: <33AEFD34@mailgate.melita.com> Encoding: 22 TEXT X-Mailer: Microsoft Mail V3.0 I posted an answer to your question in the newsgroup. I also have additional information for you. I can email you the binary for VxD which does exactly what you need: given a physical address, returns a pointer that can be used by a Win32 application. I'll also give you source for a Win32 app which uses the VxD to read an area of physical memory. I don't offer this solution to everyone, since in most cases the proper solution is for them to write a VxD which interacts with their hardware, rather than simply getting a pointer to the hardware and interacting with it from an application. However, in your case, you're just using a VxD as a tool to get your Linux driver working...you shouldn't have to write a VxD for this :-) Let me know if you're interested. =============================================================================== Hello Karen A long time ago, you sent me your VXD for reading an area of physical memory under Win32, so I could make register dumps of the graphic chip. Did I ever mention, that it works perfectly for me? Why I contact you is, that I really would like to offer this solution to all XFree86 members, so that it will be much easier in the future for XFree86 to develop drivers for graphic boards. Can I count with your agreement? Would you like to add a special copyright to your software? Stefan =============================================================================== From KHazzah@melita.com Wed Mar 4 00:00:28 1998 Return-Path: Received: from melita.melita.com (melita.com [192.68.22.2]) by Galois.suse.de (8.8.8/8.8.8) with SMTP id AAA03709 for ; Wed, 4 Mar 1998 00:00:26 +0100 Received: from norcross.melita.com (norcross.melita.com [192.68.22.10]) by melita.melita.com (8.6.12/8.6.9) with ESMTP id TAA31217 for ; Tue, 3 Mar 1998 19:48:10 -0500 Received: by zippy.melita.com with Internet Mail Service (5.5.1960.3) id ; Tue, 3 Mar 1998 18:00:26 -0500 Message-ID: From: "Hazzah, Karen" To: Stefan Dirsch Subject: RE: VXD binary for Win32 for reading an area of physical memory Date: Tue, 3 Mar 1998 18:00:25 -0500 MIME-Version: 1.0 X-Mailer: Internet Mail Service (5.5.1960.3) Content-Type: text/plain Status: ROr OK, you have my permission to make it publicly available, as is. If you make it available on the web (ftp, etc.), please give me the URL so I can refer others to it. xine-lib-1.2/contrib/libdha/bin/Makefile.am0000644000175000017500000000013614647725151016352 0ustar memeinclude $(top_srcdir)/misc/Makefile.common EXTRA_DIST = README mapdev.copyright mapdev.vxd xine-lib-1.2/contrib/libdha/bin/mapdev.vxd0000644000175000017500000001322414647725152016320 0ustar memeMZ@ !L!This program cannot be run in DOS mode. $LE\GP $[[\#|E LCOD\ ICODMAPDEV--7T'P0 'HQMAPDEV verPU|$#uu]UD$VWH tP"t "t7t;6@3W0vvV F ;uf~fF @f@3_^]UVW3Wj80tn="t = "t #include #include #include #include #include #ifdef ARCH_ALPHA #include #endif #include /* instead exit() use libdha_exit, and do the 'mother-application' deinit only in this code */ void libdha_exit(const char *message, int level) { printf("libdha: FATAL: %s\n", message); exit(level); /* FIXME */ } #if defined(_WIN32) #include "sysdep/libdha_win32.c" #elif defined (__EMX__) #include "sysdep/libdha_os2.c" #else #if defined(SVR4) || defined(SCO325) # if !(defined(sun) && defined (i386) && defined (SVR4)) # define DEV_MEM "/dev/pmem" # elif defined(PowerMAX_OS) # define DEV_MEM "/dev/iomem" # endif # ifdef SCO325 # undef DEV_MEM # define DEV_MEM "/dev/mem" # endif # endif /* SVR4 */ /* Generic version */ #include #include #ifndef DEV_MEM #define DEV_MEM "/dev/mem" #endif #include "kernelhelper/dhahelper.h" static int devmem_fd=-1; static unsigned devmem_locks=0; void *map_phys_mem(unsigned long base, unsigned long size) { #ifdef ARCH_ALPHA /* TODO: move it into sysdep */ base += bus_base(); #endif if( devmem_fd == -1) { if ( (devmem_fd = open("/dev/dhahelper",O_RDWR)) < 0) { if ( (devmem_fd = open(DEV_MEM,O_RDWR)) == -1) { perror("libdha: open(/dev/mem) failed"); exit(1); } } } devmem_locks++; return mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED,devmem_fd,base) ; } void unmap_phys_mem(void *ptr, unsigned long size) { int res=munmap(ptr,size) ; if (res == -1) { perror("libdha: munmap() failed") ; exit(1) ; } devmem_locks--; if(!devmem_locks) { close(devmem_fd); devmem_fd=-1; } } #endif xine-lib-1.2/contrib/libdha/README0000644000175000017500000000100214647725151014417 0ustar memelibdha - Library of Direct Hardware Access. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This library was designed for direct hardware access under different OS and architectures. It's not linux specific only (like harddrake and other). This library is based on gfxdump utility from GATOS project. Full list of supported OS'es see in libdha.h Note: This library requires ROOT privileges or SUID'ed executable file (same as XServer). (Or use newly developed libdha kernel helper. Look at kernelhelper/dhahelper.c) xine-lib-1.2/contrib/libdha/oth/0000755000175000017500000000000014647725152014341 5ustar memexine-lib-1.2/contrib/libdha/oth/Makefile.am0000644000175000017500000000010014647725152016364 0ustar memeinclude $(top_srcdir)/misc/Makefile.common EXTRA_DIST = pci.db xine-lib-1.2/contrib/libdha/oth/pci.db0000644000175000017500000136564714647725152015451 0ustar memev 0000 Gammagraphx, Inc. 0 v 001a Ascend Communications, Inc. 0 v 0033 Paradyne corp. 0 v 003d Lockheed Martin-Marietta Corp 0 v 0059 Tiger Jet Network Inc. (Wrong ID) 0 Real TJN ID is e159, but they got it wrong several times --mj v 0070 Hauppauge computer works Inc. 0 d 00704000 WinTV PVR-350 0 d 00704001 WinTV PVR-250 (v1) 0 d 00704009 WinTV PVR-250 0 d 00704801 WinTV PVR-250 MCE 0 v 0071 Nebula Electronics Ltd. 0 v 0095 Silicon Image, Inc. (Wrong ID) 0 d 00950680 Ultra ATA/133 IDE RAID CONTROLLER CARD 0 v 0100 Ncipher Corp Ltd 0 v 018a LevelOne 0 018a is not LevelOne but there is a board misprogrammed d 018a0106 FPC-0106TX misprogrammed [RTL81xx] 0 v 021b Compaq Computer Corporation 0 021b is not Compaq but there is a board misprogrammed d 021b8139 HNE-300 (RealTek RTL8139c) [iPaq Networking] 0 v 0291 Davicom Semiconductor, Inc. 0 http://www.davicom.com.tw/ d 02918212 DM9102A(DM9102AE, SM9102AF) Ethernet 100/10 MBit(Rev 40) 0 v 02ac SpeedStream 0 SpeedStream is Efficient Networks, Inc, a Siemens Company d 02ac1012 1012 PCMCIA 10/100 Ethernet Card [RTL81xx] 0 v 0357 TTTech AG 0 d 0357000a TTP-Monitoring Card V2.0 0 v 05e3 CyberDoor 0 d 05e30701 CBD516 0 v 0675 Dynalink 0 d 06751700 IS64PH ISDN Adapter 0 d 06751702 IS64PH ISDN Adapter 0 v 0925 VIA Technologies, Inc. (Wrong ID) 0 Wrong ID used in subsystem ID of VIA USB controllers. v 09c1 Arris 0 d 09c10704 CM 200E Cable Modem 0 v 0a89 BREA Technologies Inc 0 v 0b49 ASCII Corporation 0 d 0b49064f Trance Vibrator 0 see http://homepage1.nifty.com/mcn/lab/machines/trance_vibrator/usbview.vib.txt v 0e11 Compaq Computer Corporation 0 d 0e110001 PCI to EISA Bridge 0 d 0e110002 PCI to ISA Bridge 0 d 0e110046 Smart Array 64xx 0 s 0e1100460e11409a Smart Array 641 0 s 0e1100460e11409b Smart Array 642 0 s 0e1100460e11409c Smart Array 6400 0 s 0e1100460e11409d Smart Array 6400 EM 0 d 0e110049 NC7132 Gigabit Upgrade Module 0 d 0e11004a NC6136 Gigabit Server Adapter 0 d 0e11007c NC7770 1000BaseTX 0 d 0e11007d NC6770 1000BaseTX 0 d 0e110085 NC7780 1000BaseTX 0 d 0e1100bb NC7760 0 d 0e1100ca NC7771 0 d 0e1100cb NC7781 0 d 0e1100cf NC7772 0 d 0e1100d0 NC7782 0 d 0e1100d1 NC7783 0 d 0e1100e3 NC7761 0 d 0e110508 Netelligent 4/16 Token Ring 0 d 0e111000 Triflex/Pentium Bridge, Model 1000 0 d 0e112000 Triflex/Pentium Bridge, Model 2000 0 d 0e113032 QVision 1280/p 0 d 0e113033 QVision 1280/p 0 d 0e113034 QVision 1280/p 0 d 0e114000 4000 [Triflex] 0 d 0e114030 SMART-2/P 0 d 0e114031 SMART-2SL 0 d 0e114032 Smart Array 3200 0 d 0e114033 Smart Array 3100ES 0 d 0e114034 Smart Array 221 0 d 0e114040 Integrated Array 0 d 0e114048 Compaq Raid LC2 0 d 0e114050 Smart Array 4200 0 d 0e114051 Smart Array 4250ES 0 d 0e114058 Smart Array 431 0 d 0e114070 Smart Array 5300 0 d 0e114080 Smart Array 5i 0 d 0e114082 Smart Array 532 0 d 0e114083 Smart Array 5312 0 d 0e114091 Smart Array 6i 0 d 0e11409a Smart Array 641 0 d 0e11409b Smart Array 642 0 d 0e11409c Smart Array 6400 0 d 0e11409d Smart Array 6400 EM 0 d 0e116010 HotPlug PCI Bridge 6010 0 d 0e117020 USB Controller 0 d 0e11a0ec Fibre Channel Host Controller 0 d 0e11a0f0 Advanced System Management Controller 0 d 0e11a0f3 Triflex PCI to ISA Bridge 0 d 0e11a0f7 PCI Hotplug Controller 0 s 0e11a0f78086002a PCI Hotplug Controller A 0 s 0e11a0f78086002b PCI Hotplug Controller B 0 d 0e11a0f8 ZFMicro Chipset USB 0 d 0e11a0fc FibreChannel HBA Tachyon 0 d 0e11ae10 Smart-2/P RAID Controller 0 s 0e11ae100e114030 Smart-2/P Array Controller 0 s 0e11ae100e114031 Smart-2SL Array Controller 0 s 0e11ae100e114032 Smart Array Controller 0 s 0e11ae100e114033 Smart 3100ES Array Controller 0 d 0e11ae29 MIS-L 0 d 0e11ae2a MPC 0 d 0e11ae2b MIS-E 0 d 0e11ae31 System Management Controller 0 d 0e11ae32 Netelligent 10/100 TX PCI UTP 0 d 0e11ae33 Triflex Dual EIDE Controller 0 d 0e11ae34 Netelligent 10 T PCI UTP 0 d 0e11ae35 Integrated NetFlex-3/P 0 d 0e11ae40 Netelligent Dual 10/100 TX PCI UTP 0 d 0e11ae43 Netelligent Integrated 10/100 TX UTP 0 d 0e11ae69 CETUS-L 0 d 0e11ae6c Northstar 0 d 0e11ae6d NorthStar CPU to PCI Bridge 0 d 0e11b011 Netelligent 10/100 TX Embedded UTP 0 d 0e11b012 Netelligent 10 T/2 PCI UTP/Coax 0 d 0e11b01e NC3120 Fast Ethernet NIC 0 d 0e11b01f NC3122 Fast Ethernet NIC 0 d 0e11b02f NC1120 Ethernet NIC 0 d 0e11b030 Netelligent 10/100 TX UTP 0 d 0e11b04a 10/100 TX PCI Intel WOL UTP Controller 0 d 0e11b060 Smart Array 5300 Controller 0 d 0e11b0c6 NC3161 Fast Ethernet NIC 0 d 0e11b0c7 NC3160 Fast Ethernet NIC 0 d 0e11b0d7 NC3121 Fast Ethernet NIC 0 d 0e11b0dd NC3131 Fast Ethernet NIC 0 d 0e11b0de NC3132 Fast Ethernet Module 0 d 0e11b0df NC6132 Gigabit Module 0 d 0e11b0e0 NC6133 Gigabit Module 0 d 0e11b0e1 NC3133 Fast Ethernet Module 0 d 0e11b123 NC6134 Gigabit NIC 0 d 0e11b134 NC3163 Fast Ethernet NIC 0 d 0e11b13c NC3162 Fast Ethernet NIC 0 d 0e11b144 NC3123 Fast Ethernet NIC 0 d 0e11b163 NC3134 Fast Ethernet NIC 0 d 0e11b164 NC3165 Fast Ethernet Upgrade Module 0 d 0e11b178 Smart Array 5i/532 0 s 0e11b1780e114080 Smart Array 5i 0 s 0e11b1780e114082 Smart Array 532 0 s 0e11b1780e114083 Smart Array 5312 0 d 0e11b1a4 NC7131 Gigabit Server Adapter 0 d 0e11b200 Memory Hot-Plug Controller 0 HP Memory Hot-Plug Controller d 0e11b203 Integrated Lights Out Controller 0 d 0e11b204 Integrated Lights Out Processor 0 d 0e11f130 NetFlex-3/P ThunderLAN 1.0 0 d 0e11f150 NetFlex-3/P ThunderLAN 2.3 0 v 0e55 HaSoTec GmbH 0 v 1000 LSI Logic / Symbios Logic 0 Formerly NCR d 10000001 53c810 0 s 1000000110001000 LSI53C810AE PCI to SCSI I/O Processor 0 d 10000002 53c820 0 d 10000003 53c825 0 s 1000000310001000 LSI53C825AE PCI to SCSI I/O Processor (Ultra Wide) 0 d 10000004 53c815 0 d 10000005 53c810AP 0 d 10000006 53c860 0 s 1000000610001000 LSI53C860E PCI to Ultra SCSI I/O Processor 0 d 1000000a 53c1510 0 s 1000000a10001000 LSI53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Nonintelligent mode) 0 d 1000000b 53C896/897 0 s 1000000b0e116004 EOB003 Series SCSI host adapter 0 s 1000000b10001000 LSI53C896/7 PCI to Dual Channel Ultra2 SCSI Multifunction Controller 0 s 1000000b10001010 LSI22910 PCI to Dual Channel Ultra2 SCSI host adapter 0 s 1000000b10001020 LSI21002 PCI to Dual Channel Ultra2 SCSI host adapter 0 s 1000000b13e91000 6221L-4U 0 multifunction PCI card: Dual U2W SCSI, dual 10/100TX, graphics d 1000000c 53c895 0 s 1000000c10001010 LSI8951U PCI to Ultra2 SCSI host adapter 0 s 1000000c10001020 LSI8952U PCI to Ultra2 SCSI host adapter 0 s 1000000c1de13906 DC-390U2B SCSI adapter 0 s 1000000c1de13907 DC-390U2W 0 d 1000000d 53c885 0 d 1000000f 53c875 0 s 1000000f0e117004 Embedded Ultra Wide SCSI Controller 0 s 1000000f10001000 LSI53C876/E PCI to Dual Channel SCSI Controller 0 s 1000000f10001010 LSI22801 PCI to Dual Channel Ultra SCSI host adapter 0 s 1000000f10001020 LSI22802 PCI to Dual Channel Ultra SCSI host adapter 0 s 1000000f10928760 FirePort 40 Dual SCSI Controller 0 s 1000000f1de13904 DC390F/U Ultra Wide SCSI Adapter 0 s 1000000f4c531000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard 0 s 1000000f4c531050 CT7 mainboard 0 d 10000010 53C1510 0 s 100000100e114040 Integrated Array Controller 0 s 100000100e114048 RAID LC2 Controller 0 s 1000001010001000 53C1510 PCI to Dual Channel Wide Ultra2 SCSI Controller (Intelligent mode) 0 d 10000012 53c895a 0 s 1000001210001000 LSI53C895A PCI to Ultra2 SCSI Controller 0 d 10000013 53c875a 0 s 1000001310001000 LSI53C875A PCI to Ultra SCSI Controller 0 d 10000020 53c1010 Ultra3 SCSI Adapter 0 s 1000002010001000 LSI53C1010-33 PCI to Dual Channel Ultra160 SCSI Controller 0 s 100000201de11020 DC-390U3W 0 d 10000021 53c1010 66MHz Ultra3 SCSI Adapter 0 s 1000002110001000 LSI53C1000/1000R/1010R/1010-66 PCI to Ultra160 SCSI Controller 0 s 1000002110001010 Asus TR-DLS onboard 53C1010-66 0 s 10000021124b1070 PMC-USCSI3 0 s 100000214c531080 CT8 mainboard 0 s 100000214c531300 P017 mezzanine (32-bit PMC) 0 s 100000214c531310 P017 mezzanine (64-bit PMC) 0 d 10000030 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI 0 s 1000003010280123 PowerEdge 2600 0 s 100000301028014a PowerEdge 1750 0 s 100000301028016c PowerEdge 1850 MPT Fusion SCSI/RAID (Perc 4) 0 s 1000003010281010 LSI U320 SCSI Controller 0 d 10000031 53c1030ZC PCI-X Fusion-MPT Dual Ultra320 SCSI 0 d 10000032 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI 0 s 1000003210001000 LSI53C1020/1030 PCI-X to Ultra320 SCSI Controller 0 d 10000033 1030ZC_53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI 0 d 10000040 53c1035 PCI-X Fusion-MPT Dual Ultra320 SCSI 0 s 1000004010000033 MegaRAID SCSI 320-2XR 0 s 1000004010000066 MegaRAID SCSI 320-2XRWS 0 d 10000041 53C1035ZC PCI-X Fusion-MPT Dual Ultra320 SCSI 0 d 1000008f 53c875J 0 s 1000008f10928000 FirePort 40 SCSI Controller 0 s 1000008f10928760 FirePort 40 Dual SCSI Host Adapter 0 d 10000407 MegaRAID 0 s 1000040710000530 MegaRAID 530 SCSI 320-0X RAID Controller 0 s 1000040710000531 MegaRAID 531 SCSI 320-4X RAID Controller 0 s 1000040710000532 MegaRAID 532 SCSI 320-2X RAID Controller 0 s 1000040710280531 PowerEdge Expandable RAID Controller 4/QC 0 s 1000040710280533 PowerEdge Expandable RAID Controller 4/QC 0 s 1000040780860530 MegaRAID Intel RAID Controller SRCZCRX 0 s 1000040780860532 MegaRAID Intel RAID Controller SRCU42X 0 d 10000408 MegaRAID 0 s 1000040810000001 MegaRAID SCSI 320-1E RAID Controller 0 s 1000040810000002 MegaRAID SCSI 320-2E RAID Controller 0 s 100004081025004d MegaRAID ACER ROMB-2E RAID Controller 0 s 1000040810280001 PowerEdge RAID Controller PERC4e/SC 0 s 1000040810280002 PowerEdge RAID Controller PERC4e/DC 0 s 1000040817341065 FSC MegaRAID PCI Express ROMB 0 s 1000040880860002 MegaRAID Intel RAID Controller SRCU42E 0 d 10000409 MegaRAID 0 s 1000040910003004 MegaRAID SATA 300-4X RAID Controller 0 s 1000040910003008 MegaRAID SATA 300-8X RAID Controller 0 s 1000040980863008 MegaRAID RAID Controller SRCS28X 0 s 1000040980863431 MegaRAID RAID Controller Alief SROMBU42E 0 s 1000040980863499 MegaRAID RAID Controller Harwich SROMBU42E 0 d 10000621 FC909 Fibre Channel Adapter 0 d 10000622 FC929 Fibre Channel Adapter 0 s 1000062210001020 44929 O Dual Fibre Channel card 0 d 10000623 FC929 LAN 0 d 10000624 FC919 Fibre Channel Adapter 0 d 10000625 FC919 LAN 0 d 10000626 FC929X Fibre Channel Adapter 0 s 1000062610001010 7202-XP-LC Dual Fibre Channel card 0 d 10000627 FC929X LAN 0 d 10000628 FC919X Fibre Channel Adapter 0 d 10000629 FC919X LAN 0 d 10000701 83C885 NT50 DigitalScape Fast Ethernet 0 d 10000702 Yellowfin G-NIC gigabit ethernet 0 s 1000070213180000 PEI100X 0 d 10000804 SA2010 0 d 10000805 SA2010ZC 0 d 10000806 SA2020 0 d 10000807 SA2020ZC 0 d 10000901 61C102 0 d 10001000 63C815 0 d 10001960 MegaRAID 0 s 1000196010000518 MegaRAID 518 SCSI 320-2 Controller 0 s 1000196010000520 MegaRAID 520 SCSI 320-1 Controller 0 s 1000196010000522 MegaRAID 522 i4 133 RAID Controller 0 s 1000196010000523 MegaRAID SATA 150-6 RAID Controller 0 s 1000196010004523 MegaRAID SATA 150-4 RAID Controller 0 s 100019601000a520 MegaRAID ZCR SCSI 320-0 Controller 0 s 1000196010280518 MegaRAID 518 DELL PERC 4/DC RAID Controller 0 s 1000196010280520 MegaRAID 520 DELL PERC 4/SC RAID Controller 0 s 1000196010280531 PowerEdge Expandable RAID Controller 4/QC 0 s 1000196010280533 PowerEdge Expandable RAID Controller 4/QC 0 s 1000196080860520 MegaRAIDRAID Controller SRCU41L 0 s 1000196080860523 MegaRAID RAID Controller SRCS16 0 v 1001 Kolter Electronic 0 d 10010010 PCI 1616 Measurement card with 32 digital I/O lines 0 d 10010011 OPTO-PCI Opto-Isolated digital I/O board 0 d 10010012 PCI-AD/DA Analogue I/O board 0 d 10010013 PCI-OPTO-RELAIS Digital I/O board with relay outputs 0 d 10010014 PCI-Counter/Timer Counter Timer board 0 d 10010015 PCI-DAC416 Analogue output board 0 d 10010016 PCI-MFB Analogue I/O board 0 d 10010017 PROTO-3 PCI Prototyping board 0 d 10019100 INI-9100/9100W SCSI Host 0 v 1002 ATI Technologies Inc 0 d 10023150 M24 1P [Radeon Mobility X600] 0 d 10023154 M24 1T [FireGL M24 GL] 0 d 10023e50 RV380 0x3e50 [Radeon X600] 0 d 10023e54 RV380 0x3e54 [FireGL V3200] 0 d 10023e70 RV380 [Radeon X600] Secondary 0 d 10024136 Radeon IGP 320 M 0 d 10024137 Radeon IGP330/340/350 0 d 10024144 R300 AD [Radeon 9500 Pro] 0 d 10024145 R300 AE [Radeon 9700 Pro] 0 New PCI ID provided by ATI developer relations (correction to above) d 10024146 R300 AF [Radeon 9700 Pro] 0 New PCI ID provided by ATI developer relations (oops, correction to above) d 10024147 R300 AG [FireGL Z1/X1] 0 d 10024148 R350 AH [Radeon 9800] 0 d 10024149 R350 AI [Radeon 9800] 0 d 1002414a R350 AJ [Radeon 9800] 0 d 1002414b R350 AK [Fire GL X2] 0 d 10024150 RV350 AP [Radeon 9600] 0 New PCI ID provided by ATI developer relations s 1002415010020002 R9600 Pro primary (Asus OEM for HP) 0 s 1002415010020003 R9600 Pro secondary (Asus OEM for HP) 0 s 1002415014584024 Giga-Byte GV-R96128D Primary 0 s 10024150148c2064 PowerColor R96A-C3N 0 s 10024150148c2066 PowerColor R96A-C3N 0 s 10024150174b7c19 Sapphire Atlantis Radeon 9600 Pro 0 s 10024150174b7c29 GC-R9600PRO Primary [Sapphire] 0 s 1002415017ee2002 Radeon 9600 256Mb Primary 0 s 1002415018bc0101 GC-R9600PRO Primary 0 d 10024151 RV350 AQ [Radeon 9600] 0 New PCI ID provided by ATI developer relations s 100241511043c004 A9600SE 0 d 10024152 RV350 AR [Radeon 9600] 0 New PCI ID provided by ATI developer relations s 1002415210020002 Radeon 9600XT 0 s 100241521043c002 Radeon 9600 XT TVD 0 d 10024153 RV350 AS [Radeon 9600 AS] 0 d 10024154 RV350 AT [Fire GL T2] 0 d 10024155 RV350 AU [Fire GL T2] 0 d 10024156 RV350 AV [Fire GL T2] 0 d 10024157 RV350 AW [Fire GL T2] 0 d 10024158 68800AX [Mach32] 0 d 10024164 R300 AD [Radeon 9500 Pro] (Secondary) 0 The PCI ID is unrelated to any DVI output. d 10024165 R300 AE [Radeon 9700 Pro] (Secondary) 0 New PCI ID info provided by ATI developer relations d 10024166 R300 AF [Radeon 9700 Pro] (Secondary) 0 New PCI ID info provided by ATI developer relations d 10024168 Radeon R350 [Radeon 9800] (Secondary) 0 New PCI ID provided by ATI developer relations d 10024170 RV350 AP [Radeon 9600] (Secondary) 0 New PCI ID provided by ATI developer relations (correction to above) s 1002417014584025 Giga-Byte GV-R96128D Secondary 0 s 10024170148c2067 PowerColor R96A-C3N (Secondary) 0 s 10024170174b7c28 GC-R9600PRO Secondary [Sapphire] 0 s 1002417017ee2003 Radeon 9600 256Mb Secondary 0 s 1002417018bc0100 GC-R9600PRO Secondary 0 d 10024171 RV350 AQ [Radeon 9600] (Secondary) 0 New PCI ID provided by ATI developer relations (correction to above) s 100241711043c005 A9600SE (Secondary) 0 d 10024172 RV350 AR [Radeon 9600] (Secondary) 0 New PCI ID provided by ATI developer relations (correction to above) s 1002417210020003 Radeon 9600XT (Secondary) 0 s 100241721043c003 A9600XT (Secondary) 0 d 10024173 RV350 ?? [Radeon 9550] (Secondary) 0 d 10024237 Radeon 7000 IGP 0 d 10024242 R200 BB [Radeon All in Wonder 8500DV] 0 s 10024242100202aa Radeon 8500 AIW DV Edition 0 d 10024243 R200 BC [Radeon All in Wonder 8500] 0 d 10024336 Radeon Mobility U1 0 s 10024336103c0024 Pavilion ze4400 builtin Video 0 d 10024337 Radeon IGP 330M/340M/350M 0 s 100243371014053a ThinkPad R40e (2684-HVG) builtin VGA controller 0 s 10024337103c0850 Radeon IGP 345M 0 d 10024341 IXP150 AC'97 Audio Controller 0 d 10024345 EHCI USB Controller 0 d 10024347 OHCI USB Controller #1 0 d 10024348 OHCI USB Controller #2 0 d 1002434d IXP AC'97 Modem 0 d 10024353 ATI SMBus 0 Radeon 9100 IGP integrated d 10024354 215CT [Mach64 CT] 0 d 10024358 210888CX [Mach64 CX] 0 d 10024437 Radeon Mobility 7000 IGP 0 d 10024554 210888ET [Mach64 ET] 0 d 10024654 Mach64 VT 0 d 10024742 3D Rage Pro AGP 1X/2X 0 s 1002474210020040 Rage Pro Turbo AGP 2X 0 s 1002474210020044 Rage Pro Turbo AGP 2X 0 s 1002474210020061 Rage Pro AIW AGP 2X 0 s 1002474210020062 Rage Pro AIW AGP 2X 0 s 1002474210020063 Rage Pro AIW AGP 2X 0 s 1002474210020080 Rage Pro Turbo AGP 2X 0 s 1002474210020084 Rage Pro Turbo AGP 2X 0 s 1002474210024742 Rage Pro Turbo AGP 2X 0 s 1002474210028001 Rage Pro Turbo AGP 2X 0 s 1002474210280082 Rage Pro Turbo AGP 2X 0 s 1002474210284082 Optiplex GX1 Onboard Display Adapter 0 s 1002474210288082 Rage Pro Turbo AGP 2X 0 s 100247421028c082 Rage Pro Turbo AGP 2X 0 s 1002474280864152 Xpert 98D AGP 2X 0 s 100247428086464a Rage Pro Turbo AGP 2X 0 d 10024744 3D Rage Pro AGP 1X 0 s 1002474410024744 Rage Pro Turbo AGP 0 d 10024747 3D Rage Pro 0 d 10024749 3D Rage Pro 0 s 1002474910020061 Rage Pro AIW 0 s 1002474910020062 Rage Pro AIW 0 d 1002474c Rage XC 0 d 1002474d Rage XL AGP 2X 0 s 1002474d10020004 Xpert 98 RXL AGP 2X 0 s 1002474d10020008 Xpert 98 RXL AGP 2X 0 s 1002474d10020080 Rage XL AGP 2X 0 s 1002474d10020084 Xpert 98 AGP 2X 0 s 1002474d1002474d Rage XL AGP 0 s 1002474d1033806a Rage XL AGP 0 d 1002474e Rage XC AGP 0 s 1002474e1002474e Rage XC AGP 0 d 1002474f Rage XL 0 s 1002474f10020008 Rage XL 0 s 1002474f1002474f Rage XL 0 d 10024750 3D Rage Pro 215GP 0 s 1002475010020040 Rage Pro Turbo 0 s 1002475010020044 Rage Pro Turbo 0 s 1002475010020080 Rage Pro Turbo 0 s 1002475010020084 Rage Pro Turbo 0 s 1002475010024750 Rage Pro Turbo 0 d 10024751 3D Rage Pro 215GQ 0 d 10024752 Rage XL 0 s 1002475210020008 Rage XL 0 s 1002475210024752 Rage XL 0 s 1002475210028008 Rage XL 0 s 10024752102800ce PowerEdge 1400 0 s 10024752102800d1 PowerEdge 2550 0 s 10024752102800d9 PowerEdge 2500 0 s 1002475280863411 SDS2 Mainboard 0 s 1002475280863427 S875WP1-E mainboard 0 d 10024753 Rage XC 0 s 1002475310024753 Rage XC 0 d 10024754 3D Rage I/II 215GT [Mach64 GT] 0 d 10024755 3D Rage II+ 215GTB [Mach64 GTB] 0 d 10024756 3D Rage IIC 215IIC [Mach64 GT IIC] 0 s 1002475610024756 Rage IIC 0 d 10024757 3D Rage IIC AGP 0 s 1002475710024757 Rage IIC AGP 0 s 1002475710280089 Rage 3D IIC 0 s 1002475710284082 Rage 3D IIC 0 s 1002475710288082 Rage 3D IIC 0 s 100247571028c082 Rage 3D IIC 0 d 10024758 210888GX [Mach64 GX] 0 d 10024759 3D Rage IIC 0 d 1002475a 3D Rage IIC AGP 0 s 1002475a10020084 Rage 3D Pro AGP 2x XPERT 98 0 s 1002475a10020087 Rage 3D IIC 0 s 1002475a1002475a Rage IIC AGP 0 d 10024964 Radeon RV250 Id [Radeon 9000] 0 d 10024965 Radeon RV250 Ie [Radeon 9000] 0 d 10024966 Radeon RV250 If [Radeon 9000] 0 s 1002496610f10002 RV250 If [Tachyon G9000 PRO] 0 s 10024966148c2039 RV250 If [Radeon 9000 Pro "Evil Commando"] 0 s 1002496615099a00 RV250 If [Radeon 9000 "AT009"] 0 s 1002496616810040 RV250 If [3D prophet 9000] 0 New subdevice - 3D Prophet 9000 PCI by Hercules. AGP version probably would have same ID, so not specified. s 10024966174b7176 RV250 If [Sapphire Radeon 9000 Pro] 0 s 10024966174b7192 RV250 If [Radeon 9000 "Atlantis"] 0 s 1002496617af2005 RV250 If [Excalibur Radeon 9000 Pro] 0 s 1002496617af2006 RV250 If [Excalibur Radeon 9000] 0 d 10024967 Radeon RV250 Ig [Radeon 9000] 0 d 1002496e Radeon RV250 [Radeon 9000] (Secondary) 0 d 10024a48 R420 JH [Radeon X800] 0 d 10024a49 R420 JI [Radeon X800PRO] 0 d 10024a4a R420 JJ [Radeon X800SE] 0 d 10024a4b R420 JK [Radeon X800] 0 d 10024a4c R420 JL [Radeon X800] 0 d 10024a4d R420 JM [FireGL X3] 0 d 10024a4e M18 JN [Radeon Mobility 9800] 0 d 10024a50 R420 JP [Radeon X800XT] 0 d 10024a70 R420 [X800XT-PE] (Secondary) 0 d 10024c42 3D Rage LT Pro AGP-133 0 s 10024c420e11b0e7 Rage LT Pro (Compaq Presario 5240) 0 s 10024c420e11b0e8 Rage 3D LT Pro 0 s 10024c420e11b10e 3D Rage LT Pro (Compaq Armada 1750) 0 s 10024c4210020040 Rage LT Pro AGP 2X 0 s 10024c4210020044 Rage LT Pro AGP 2X 0 s 10024c4210024c42 Rage LT Pro AGP 2X 0 s 10024c4210028001 Rage LT Pro AGP 2X 0 s 10024c4210280085 Rage 3D LT Pro 0 d 10024c44 3D Rage LT Pro AGP-66 0 d 10024c45 Rage Mobility M3 AGP 0 d 10024c46 Rage Mobility M3 AGP 2x 0 s 10024c46102800b1 Latitude C600 0 d 10024c47 3D Rage LT-G 215LG 0 d 10024c49 3D Rage LT Pro 0 s 10024c4910020004 Rage LT Pro 0 s 10024c4910020040 Rage LT Pro 0 s 10024c4910020044 Rage LT Pro 0 s 10024c4910024c49 Rage LT Pro 0 d 10024c4d Rage Mobility P/M AGP 2x 0 s 10024c4d0e11b111 Armada M700 0 s 10024c4d0e11b160 Armada E500 0 s 10024c4d10020084 Xpert 98 AGP 2X (Mobility) 0 s 10024c4d10140154 ThinkPad A20m 0 s 10024c4d102800aa Latitude CPt 0 d 10024c4e Rage Mobility L AGP 2x 0 d 10024c50 3D Rage LT Pro 0 s 10024c5010024c50 Rage LT Pro 0 d 10024c51 3D Rage LT Pro 0 d 10024c52 Rage Mobility P/M 0 s 10024c5210338112 Versa Note VXi 0 d 10024c53 Rage Mobility L 0 d 10024c54 264LT [Mach64 LT] 0 d 10024c57 Radeon Mobility M7 LW [Radeon Mobility 7500] 0 s 10024c5710140517 ThinkPad T30 0 s 10024c57102800e6 Radeon Mobility M7 LW (Dell Inspiron 8100) 0 s 10024c571028012a Latitude C640 0 s 10024c57144dc006 Radeon Mobility M7 LW in vpr Matrix 170B4 0 d 10024c58 Radeon RV200 LX [Mobility FireGL 7800 M7] 0 d 10024c59 Radeon Mobility M6 LY 0 s 10024c5910140235 ThinkPad A30/A30p (2652/2653) 0 s 10024c5910140239 ThinkPad X22/X23/X24 0 s 10024c59104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 d 10024c5a Radeon Mobility M6 LZ 0 d 10024c64 Radeon R250 Ld [Radeon Mobility 9000 M9] 0 d 10024c65 Radeon R250 Le [Radeon Mobility 9000 M9] 0 d 10024c66 Radeon R250 Lf [FireGL 9000] 0 d 10024c67 Radeon R250 Lg [Radeon Mobility 9000 M9] 0 d 10024c6e Radeon R250 Ln [Radeon Mobility 9000 M9] [Secondary] 0 Secondary chip to the Lf d 10024d46 Rage Mobility M4 AGP 0 d 10024d4c Rage Mobility M4 AGP 0 d 10024e44 Radeon R300 ND [Radeon 9700 Pro] 0 d 10024e45 Radeon R300 NE [Radeon 9500 Pro] 0 s 10024e4510020002 Radeon R300 NE [Radeon 9500 Pro] 0 s 10024e4516810002 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] 0 d 10024e46 RV350 NF [Radeon 9600] 0 New PCI ID provided by ATI developer relations (correction to above) d 10024e47 Radeon R300 NG [FireGL X1] 0 d 10024e48 Radeon R350 [Radeon 9800 Pro] 0 (added pro) d 10024e49 Radeon R350 [Radeon 9800] 0 New PCI ID provided by ATI developer relations d 10024e4a RV350 NJ [Radeon 9800 XT] 0 d 10024e4b R350 NK [Fire GL X2] 0 d 10024e50 RV350 [Mobility Radeon 9600 M10] 0 New PCI ID provided by ATI developer relations s 10024e501025005a TravelMate 290 0 s 10024e50103c0890 NC6000 laptop 0 s 10024e5017341055 Amilo M1420W 0 d 10024e51 M10 NQ [Radeon Mobility 9600] 0 d 10024e52 RV350 [Mobility Radeon 9600 M10] 0 d 10024e53 M10 NS [Radeon Mobility 9600] 0 d 10024e54 M10 NT [FireGL Mobility T2] 0 d 10024e56 M11 NV [FireGL Mobility T2e] 0 d 10024e64 Radeon R300 [Radeon 9700 Pro] (Secondary) 0 d 10024e65 Radeon R300 [Radeon 9500 Pro] (Secondary) 0 s 10024e6510020003 Radeon R300 NE [Radeon 9500 Pro] 0 s 10024e6516810003 Hercules 3D Prophet 9500 PRO [Radeon 9500 Pro] (Secondary) 0 d 10024e66 RV350 NF [Radeon 9600] (Secondary) 0 New PCI ID provided by ATI developer relations (correction to above) d 10024e67 Radeon R300 [FireGL X1] (Secondary) 0 d 10024e68 Radeon R350 [Radeon 9800 Pro] (Secondary) 0 (added pro) d 10024e69 Radeon R350 [Radeon 9800] (Secondary) 0 New PCI ID provided by ATI developer relations d 10024e6a RV350 NJ [Radeon 9800 XT] (Secondary) 0 d 10025041 Rage 128 PA/PRO 0 d 10025042 Rage 128 PB/PRO AGP 2x 0 d 10025043 Rage 128 PC/PRO AGP 4x 0 d 10025044 Rage 128 PD/PRO TMDS 0 s 1002504410020028 Rage 128 AIW 0 s 1002504410020029 Rage 128 AIW 0 d 10025045 Rage 128 PE/PRO AGP 2x TMDS 0 d 10025046 Rage 128 PF/PRO AGP 4x TMDS 0 s 1002504610020004 Rage Fury Pro 0 s 1002504610020008 Rage Fury Pro/Xpert 2000 Pro 0 s 1002504610020014 Rage Fury Pro 0 s 1002504610020018 Rage Fury Pro/Xpert 2000 Pro 0 s 1002504610020028 Rage 128 Pro AIW AGP 0 s 100250461002002a Rage 128 Pro AIW AGP 0 s 1002504610020048 Rage Fury Pro 0 s 1002504610022000 Rage Fury MAXX AGP 4x (TMDS) (VGA device) 0 s 1002504610022001 Rage Fury MAXX AGP 4x (TMDS) (Extra device?!) 0 d 10025047 Rage 128 PG/PRO 0 d 10025048 Rage 128 PH/PRO AGP 2x 0 d 10025049 Rage 128 PI/PRO AGP 4x 0 d 1002504a Rage 128 PJ/PRO TMDS 0 d 1002504b Rage 128 PK/PRO AGP 2x TMDS 0 d 1002504c Rage 128 PL/PRO AGP 4x TMDS 0 d 1002504d Rage 128 PM/PRO 0 d 1002504e Rage 128 PN/PRO AGP 2x 0 d 1002504f Rage 128 PO/PRO AGP 4x 0 d 10025050 Rage 128 PP/PRO TMDS [Xpert 128] 0 s 1002505010020008 Xpert 128 0 d 10025051 Rage 128 PQ/PRO AGP 2x TMDS 0 d 10025052 Rage 128 PR/PRO AGP 4x TMDS 0 d 10025053 Rage 128 PS/PRO 0 d 10025054 Rage 128 PT/PRO AGP 2x 0 d 10025055 Rage 128 PU/PRO AGP 4x 0 d 10025056 Rage 128 PV/PRO TMDS 0 d 10025057 Rage 128 PW/PRO AGP 2x TMDS 0 d 10025058 Rage 128 PX/PRO AGP 4x TMDS 0 d 10025144 Radeon R100 QD [Radeon 7200] 0 s 1002514410020008 Radeon 7000/Radeon VE 0 s 1002514410020009 Radeon 7000/Radeon 0 s 100251441002000a Radeon 7000/Radeon 0 s 100251441002001a Radeon 7000/Radeon 0 s 1002514410020029 Radeon AIW 0 s 1002514410020038 Radeon 7000/Radeon 0 s 1002514410020039 Radeon 7000/Radeon 0 s 100251441002008a Radeon 7000/Radeon 0 s 10025144100200ba Radeon 7000/Radeon 0 s 1002514410020139 Radeon 7000/Radeon 0 s 100251441002028a Radeon 7000/Radeon 0 s 10025144100202aa Radeon AIW 0 s 100251441002053a Radeon 7000/Radeon 0 d 10025145 Radeon R100 QE 0 d 10025146 Radeon R100 QF 0 d 10025147 Radeon R100 QG 0 d 10025148 Radeon R200 QH [Radeon 8500] 0 s 100251481002010a FireGL 8800 64Mb 0 s 1002514810020152 FireGL 8800 128Mb 0 s 1002514810020162 FireGL 8700 32Mb 0 s 1002514810020172 FireGL 8700 64Mb 0 d 10025149 Radeon R200 QI 0 d 1002514a Radeon R200 QJ 0 d 1002514b Radeon R200 QK 0 d 1002514c Radeon R200 QL [Radeon 8500 LE] 0 s 1002514c1002003a Radeon R200 QL [Radeon 8500 LE] 0 s 1002514c1002013a Radeon 8500 0 s 1002514c148c2026 R200 QL [Radeon 8500 Evil Master II Multi Display Edition] 0 s 1002514c16810010 Radeon 8500 [3D Prophet 8500 128Mb] 0 s 1002514c174b7149 Radeon R200 QL [Sapphire Radeon 8500 LE] 0 d 1002514d Radeon R200 QM [Radeon 9100] 0 d 1002514e Radeon R200 QN [Radeon 8500LE] 0 d 1002514f Radeon R200 QO [Radeon 8500LE] 0 d 10025154 R200 QT [Radeon 8500] 0 d 10025155 R200 QU [Radeon 9100] 0 d 10025157 Radeon RV200 QW [Radeon 7500] 0 s 100251571002013a Radeon 7500 0 s 100251571002103a Dell Optiplex GX260 0 s 1002515714584000 RV200 QW [RADEON 7500 PRO MAYA AR] 0 s 10025157148c2024 RV200 QW [Radeon 7500LE Dual Display] 0 s 10025157148c2025 RV200 QW [Radeon 7500 Evil Master Multi Display Edition] 0 s 10025157148c2036 RV200 QW [Radeon 7500 PCI Dual Display] 0 s 10025157174b7146 RV200 QW [Radeon 7500 LE] 0 s 10025157174b7147 RV200 QW [Sapphire Radeon 7500LE] 0 s 10025157174b7161 Radeon RV200 QW [Radeon 7500 LE] 0 s 1002515717af0202 RV200 QW [Excalibur Radeon 7500LE] 0 d 10025158 Radeon RV200 QX [Radeon 7500] 0 d 10025159 Radeon RV100 QY [Radeon 7000/VE] 0 s 100251591002000a Radeon 7000/Radeon VE 0 s 100251591002000b Radeon 7000 0 s 1002515910020038 Radeon 7000/Radeon VE 0 s 100251591002003a Radeon 7000/Radeon VE 0 s 10025159100200ba Radeon 7000/Radeon VE 0 s 100251591002013a Radeon 7000/Radeon VE 0 s 1002515914584002 RV100 QY [RADEON 7000 PRO MAYA AV Series] 0 s 10025159148c2003 RV100 QY [Radeon 7000 Multi-Display Edition] 0 s 10025159148c2023 RV100 QY [Radeon 7000 Evil Master Multi-Display] 0 s 10025159174b7112 RV100 QY [Sapphire Radeon VE 7000] 0 s 10025159174b7c28 Sapphire Radeon VE 7000 DDR 0 s 1002515917870202 RV100 QY [Excalibur Radeon 7000] 0 d 1002515a Radeon RV100 QZ [Radeon 7000/VE] 0 d 10025168 Radeon R200 Qh 0 d 10025169 Radeon R200 Qi 0 d 1002516a Radeon R200 Qj 0 d 1002516b Radeon R200 Qk 0 d 1002516c Radeon R200 Ql 0 This one is not in ATI documentation, but is in XFree86 source code d 10025245 Rage 128 RE/SG 0 s 1002524510020008 Xpert 128 0 s 1002524510020028 Rage 128 AIW 0 s 1002524510020029 Rage 128 AIW 0 s 1002524510020068 Rage 128 AIW 0 d 10025246 Rage 128 RF/SG AGP 0 s 1002524610020004 Magnum/Xpert 128/Xpert 99 0 s 1002524610020008 Magnum/Xpert128/X99/Xpert2000 0 s 1002524610020028 Rage 128 AIW AGP 0 s 1002524610020044 Rage Fury/Xpert 128/Xpert 2000 0 s 1002524610020068 Rage 128 AIW AGP 0 s 1002524610020448 Rage Fury 0 d 10025247 Rage 128 RG 0 d 1002524b Rage 128 RK/VR 0 d 1002524c Rage 128 RL/VR AGP 0 s 1002524c10020008 Xpert 99/Xpert 2000 0 s 1002524c10020088 Xpert 99 0 d 10025345 Rage 128 SE/4x 0 d 10025346 Rage 128 SF/4x AGP 2x 0 s 1002534610020048 RAGE 128 16MB VGA TVOUT AMC PAL 0 d 10025347 Rage 128 SG/4x AGP 4x 0 d 10025348 Rage 128 SH 0 d 1002534b Rage 128 SK/4x 0 d 1002534c Rage 128 SL/4x AGP 2x 0 d 1002534d Rage 128 SM/4x AGP 4x 0 s 1002534d10020008 Xpert 99/Xpert 2000 0 s 1002534d10020018 Xpert 2000 0 d 1002534e Rage 128 4x 0 d 10025354 Mach 64 VT 0 s 1002535410025654 Mach 64 reference 0 d 10025446 Rage 128 Pro Ultra TF 0 s 1002544610020004 Rage Fury Pro 0 s 1002544610020008 Rage Fury Pro/Xpert 2000 Pro 0 s 1002544610020018 Rage Fury Pro/Xpert 2000 Pro 0 s 1002544610020028 Rage 128 AIW Pro AGP 0 s 1002544610020029 Rage 128 AIW 0 s 100254461002002a Rage 128 AIW Pro AGP 0 s 100254461002002b Rage 128 AIW 0 s 1002544610020048 Xpert 2000 Pro 0 d 1002544c Rage 128 Pro Ultra TL 0 d 10025452 Rage 128 Pro Ultra TR 0 s 100254521002001c Rage 128 Pro 4XL 0 s 10025452103c1279 Rage 128 Pro 4XL 0 d 10025453 Rage 128 Pro Ultra TS 0 d 10025454 Rage 128 Pro Ultra TT 0 d 10025455 Rage 128 Pro Ultra TU 0 d 10025460 M22 [Radeon Mobility M300] 0 d 10025464 M22 [FireGL GL] 0 d 10025548 R423 UH [Radeon X800 (PCIE)] 0 d 10025549 R423 UI [Radeon X800PRO (PCIE)] 0 d 1002554a R423 UJ [Radeon X800LE (PCIE)] 0 d 1002554b R423 UK [Radeon X800SE (PCIE)] 0 d 10025551 R423 UQ [FireGL V7200 (PCIE)] 0 d 10025552 R423 UR [FireGL V5100 (PCIE)] 0 d 10025554 R423 UT [FireGL V7100 (PCIE)] 0 d 1002556b Radeon R423 UK (PCIE) [X800 SE] (Secondary) 0 d 10025654 264VT [Mach64 VT] 0 s 1002565410025654 Mach64VT Reference 0 d 10025655 264VT3 [Mach64 VT3] 0 d 10025656 264VT4 [Mach64 VT4] 0 d 10025830 RS300 Host Bridge 0 d 10025831 RS300 Host Bridge 0 d 10025832 RS300 Host Bridge 0 d 10025833 Radeon 9100 IGP Host Bridge 0 d 10025834 Radeon 9100 IGP 0 d 10025835 RS300M AGP [Radeon Mobility 9100IGP] 0 d 10025838 Radeon 9100 IGP AGP Bridge 0 d 10025941 RV280 [Radeon 9200] (Secondary) 0 s 10025941174b7c12 Sapphire Radeon 9200 0 s 1002594117af200d Excalibur Radeon 9200 0 http://www.hightech.com.hk/html/9200.htm s 1002594118bc0050 GeXcube GC-R9200-C3 (Secondary) 0 d 10025944 RV280 [Radeon 9200 SE (PCI)] 0 d 10025960 RV280 [Radeon 9200 PRO] 0 d 10025961 RV280 [Radeon 9200] 0 s 1002596110022f72 All-in-Wonder 9200 Series 0 s 1002596112ab5961 YUAN SMARTVGA Radeon 9200 0 s 1002596114584018 Gigabyte Radeon 9200 0 s 10025961174b7c13 Sapphire Radeon 9200 0 s 1002596117af200c Excalibur Radeon 9200 0 http://www.hightech.com.hk/html/9200.htm s 1002596118bc0050 Radeon 9200 Game Buster 0 s 1002596118bc0051 GeXcube GC-R9200-C3 0 s 1002596118bc0053 Radeon 9200 Game Buster VIVO 0 d 10025962 RV280 [Radeon 9200] 0 d 10025964 RV280 [Radeon 9200 SE] 0 s 100259641043c006 ASUS Radeon 9200 SE / TD / 128M 0 s 1002596414584018 Radeon 9200 SE 0 s 10025964148c2073 CN-AG92E 0 s 10025964174b7c13 Sapphire Radeon 9200 SE 0 s 1002596417875964 Excalibur 9200SE VIVO 128M 0 s 1002596417af2012 Radeon 9200 SE Excalibur 0 s 1002596418bc0170 Sapphire Radeon 9200 SE 128MB Game Buster 0 s 1002596418bc0173 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster] 0 128MB DDR, DVI/VGA/TV out d 10025b60 RV370 5B60 [Radeon X300 (PCIE)] 0 s 10025b601043002a EAX300SE 0 d 10025b62 RV370 5B62 [Radeon X600 (PCIE)] 0 d 10025b64 RV370 5B64 [FireGL V3100 (PCIE)] 0 d 10025b65 RV370 5B65 [FireGL D1100 (PCIE)] 0 d 10025c61 M9+ 5C61 [Radeon Mobility 9200 (AGP)] 0 d 10025c63 M9+ 5C63 [Radeon Mobility 9200 (AGP)] 0 d 10025d44 RV280 [Radeon 9200 SE] (Secondary) 0 s 10025d4414584019 Radeon 9200 SE (Secondary) 0 s 10025d44174b7c12 Sapphire Radeon 9200 SE (Secondary) 0 s 10025d4417875965 Excalibur 9200SE VIVO 128M (Secondary) 0 s 10025d4417af2013 Radeon 9200 SE Excalibur (Secondary) 0 s 10025d4418bc0171 Radeon 9200 SE 128MB Game Buster (Secondary) 0 s 10025d4418bc0172 GC-R9200L(SE)-C3H [Radeon 9200 Game Buster] 0 d 10025d57 R423 5F57 [Radeon X800XT (PCIE)] 0 d 1002700f PCI Bridge [IGP 320M] 0 d 10027010 PCI Bridge [IGP 340M] 0 d 10027834 Radeon 9100 PRO IGP 0 d 10027835 Radeon Mobility 9200 IGP 0 d 10027c37 RV350 AQ [Radeon 9600 SE] 0 d 1002cab0 AGP Bridge [IGP 320M] 0 d 1002cab2 RS200/RS200M AGP Bridge [IGP 340M] 0 d 1002cbb2 RS200/RS200M AGP Bridge [IGP 340M] 0 v 1003 ULSI Systems 0 d 10030201 US201 0 v 1004 VLSI Technology Inc 0 d 10040005 82C592-FC1 0 d 10040006 82C593-FC1 0 d 10040007 82C594-AFC2 0 d 10040008 82C596/7 [Wildcat] 0 d 10040009 82C597-AFC2 0 d 1004000c 82C541 [Lynx] 0 d 1004000d 82C543 [Lynx] 0 d 10040101 82C532 0 d 10040102 82C534 [Eagle] 0 d 10040103 82C538 0 d 10040104 82C535 0 d 10040105 82C147 0 d 10040200 82C975 0 d 10040280 82C925 0 d 10040304 QSound ThunderBird PCI Audio 0 s 1004030410040304 QSound ThunderBird PCI Audio 0 s 10040304122d1206 DSP368 Audio 0 s 1004030414835020 XWave Thunder 3D Audio 0 d 10040305 QSound ThunderBird PCI Audio Gameport 0 s 1004030510040305 QSound ThunderBird PCI Audio Gameport 0 s 10040305122d1207 DSP368 Audio Gameport 0 s 1004030514835021 XWave Thunder 3D Audio Gameport 0 d 10040306 QSound ThunderBird PCI Audio Support Registers 0 s 1004030610040306 QSound ThunderBird PCI Audio Support Registers 0 s 10040306122d1208 DSP368 Audio Support Registers 0 s 1004030614835022 XWave Thunder 3D Audio Support Registers 0 d 10040307 Thunderbird 0 d 10040308 Thunderbird 0 d 10040702 VAS96011 [Golden Gate II] 0 d 10040703 Tollgate 0 v 1005 Avance Logic Inc. [ALI] 0 d 10052064 ALG2032/2064 0 d 10052128 ALG2364A 0 d 10052301 ALG2301 0 d 10052302 ALG2302 0 d 10052364 ALG2364 0 d 10052464 ALG2364A 0 d 10052501 ALG2564A/25128A 0 v 1006 Reply Group 0 v 1007 NetFrame Systems Inc 0 v 1008 Epson 0 v 100a Phoenix Technologies 0 v 100b National Semiconductor Corporation 0 d 100b0001 DP83810 0 d 100b0002 87415/87560 IDE 0 d 100b000e 87560 Legacy I/O 0 d 100b000f FireWire Controller 0 d 100b0011 NS87560 National PCI System I/O 0 d 100b0012 USB Controller 0 d 100b0020 DP83815 (MacPhyter) Ethernet Controller 0 s 100b0020103c0024 Pavilion ze4400 builtin Network 0 s 100b00201385f311 FA311 / FA312 (FA311 with WoL HW) 0 d 100b0022 DP83820 10/100/1000 Ethernet Controller 0 d 100b0028 CS5535 Host bridge 0 d 100b002b CS5535 ISA bridge 0 d 100b002d CS5535 IDE 0 d 100b002e CS5535 Audio 0 d 100b002f CS5535 USB 0 d 100b0030 CS5535 Video 0 d 100b0035 DP83065 [Saturn] 10/100/1000 Ethernet Controller 0 d 100b0500 SCx200 Bridge 0 d 100b0501 SCx200 SMI 0 d 100b0502 SCx200 IDE 0 d 100b0503 SCx200 Audio 0 d 100b0504 SCx200 Video 0 d 100b0505 SCx200 XBus 0 d 100b0510 SC1100 Bridge 0 d 100b0511 SC1100 SMI 0 d 100b0515 SC1100 XBus 0 d 100bd001 87410 IDE 0 v 100c Tseng Labs Inc 0 d 100c3202 ET4000/W32p rev A 0 d 100c3205 ET4000/W32p rev B 0 d 100c3206 ET4000/W32p rev C 0 d 100c3207 ET4000/W32p rev D 0 d 100c3208 ET6000 0 d 100c4702 ET6300 0 v 100d AST Research Inc 0 v 100e Weitek 0 d 100e9000 P9000 Viper 0 d 100e9001 P9000 Viper 0 d 100e9002 P9000 Viper 0 d 100e9100 P9100 Viper Pro/SE 0 v 1010 Video Logic, Ltd. 0 v 1011 Digital Equipment Corporation 0 d 10110001 DECchip 21050 0 d 10110002 DECchip 21040 [Tulip] 0 d 10110004 DECchip 21030 [TGA] 0 d 10110007 NVRAM [Zephyr NVRAM] 0 d 10110008 KZPSA [KZPSA] 0 d 10110009 DECchip 21140 [FasterNet] 0 s 1011000910250310 21140 Fast Ethernet 0 s 1011000910b82001 SMC9332BDT EtherPower 10/100 0 s 1011000910b82002 SMC9332BVT EtherPower T4 10/100 0 s 1011000910b82003 SMC9334BDT EtherPower 10/100 (1-port) 0 s 1011000911092400 ANA-6944A/TX Fast Ethernet 0 s 1011000911122300 RNS2300 Fast Ethernet 0 s 1011000911122320 RNS2320 Fast Ethernet 0 s 1011000911122340 RNS2340 Fast Ethernet 0 s 1011000911131207 EN-1207-TX Fast Ethernet 0 s 1011000911861100 DFE-500TX Fast Ethernet 0 s 1011000911861112 DFE-570TX Fast Ethernet 0 s 1011000911861140 DFE-660 Cardbus Ethernet 10/100 0 s 1011000911861142 DFE-660 Cardbus Ethernet 10/100 0 s 1011000911f60503 Freedomline Fast Ethernet 0 s 1011000912829100 AEF-380TXD Fast Ethernet 0 s 1011000913851100 FA310TX Fast Ethernet 0 s 1011000926460001 KNE100TX Fast Ethernet 0 d 1011000a 21230 Video Codec 0 d 1011000d PBXGB [TGA2] 0 d 1011000f DEFPA 0 d 10110014 DECchip 21041 [Tulip Pass 3] 0 s 1011001411860100 DE-530+ 0 d 10110016 DGLPB [OPPO] 0 d 10110017 PV-PCI Graphics Controller (ZLXp-L) 0 d 10110019 DECchip 21142/43 0 s 101100191011500a DE500A Fast Ethernet 0 s 101100191011500b DE500B Fast Ethernet 0 s 1011001910140001 10/100 EtherJet Cardbus 0 s 1011001910250315 ALN315 Fast Ethernet 0 s 101100191033800c PC-9821-CS01 100BASE-TX Interface Card 0 s 101100191033800d PC-9821NR-B06 100BASE-TX Interface Card 0 s 10110019108d0016 Rapidfire 2327 10/100 Ethernet 0 s 10110019108d0017 GoCard 2250 Ethernet 10/100 Cardbus 0 s 1011001910b82005 SMC8032DT Extreme Ethernet 10/100 0 s 1011001910b88034 SMC8034 Extreme Ethernet 10/100 0 s 1011001910ef8169 Cardbus Fast Ethernet 0 s 1011001911092a00 ANA-6911A/TX Fast Ethernet 0 s 1011001911092b00 ANA-6911A/TXC Fast Ethernet 0 s 1011001911093000 ANA-6922/TX Fast Ethernet 0 s 1011001911131207 Cheetah Fast Ethernet 0 s 1011001911132220 Cardbus Fast Ethernet 0 s 10110019115d0002 Cardbus Ethernet 10/100 0 s 1011001911790203 Fast Ethernet 0 s 1011001911790204 Cardbus Fast Ethernet 0 s 1011001911861100 DFE-500TX Fast Ethernet 0 s 1011001911861101 DFE-500TX Fast Ethernet 0 s 1011001911861102 DFE-500TX Fast Ethernet 0 s 1011001911861112 DFE-570TX Quad Fast Ethernet 0 s 1011001912592800 AT-2800Tx Fast Ethernet 0 s 1011001912660004 Eagle Fast EtherMAX 0 s 1011001912af0019 NetFlyer Cardbus Fast Ethernet 0 s 1011001913740001 Cardbus Ethernet Card 10/100 0 s 1011001913740002 Cardbus Ethernet Card 10/100 0 s 1011001913740007 Cardbus Ethernet Card 10/100 0 s 1011001913740008 Cardbus Ethernet Card 10/100 0 s 1011001913852100 FA510 0 s 1011001913950001 10/100 Ethernet CardBus PC Card 0 s 1011001913d1ab01 EtherFast 10/100 Cardbus (PCMPC200) 0 s 1011001914cb0100 LNDL-100N 100Base-TX Ethernet PC Card 0 s 1011001980860001 EtherExpress PRO/100 Mobile CardBus 32 0 d 1011001a Farallon PN9000SX Gigabit Ethernet 0 d 10110021 DECchip 21052 0 d 10110022 DECchip 21150 0 d 10110023 DECchip 21150 0 d 10110024 DECchip 21152 0 d 10110025 DECchip 21153 0 d 10110026 DECchip 21154 0 d 10110034 56k Modem Cardbus 0 s 1011003413740003 56k Modem Cardbus 0 d 10110045 DECchip 21553 0 d 10110046 DECchip 21554 0 s 101100460e114050 Integrated Smart Array 0 s 101100460e114051 Integrated Smart Array 0 s 101100460e114058 Integrated Smart Array 0 s 10110046103c10c2 Hewlett-Packard NetRAID-4M 0 s 1011004612d9000a IP Telephony card 0 s 101100464c531050 CT7 mainboard 0 s 101100464c531051 CE7 mainboard 0 s 1011004690050364 5400S (Mustang) 0 s 1011004690050365 5400S (Mustang) 0 s 1011004690051364 Dell PowerEdge RAID Controller 2 0 s 1011004690051365 Dell PowerEdge RAID Controller 2 0 s 10110046e4bf1000 CC8-1-BLUES 0 d 10111065 StrongARM DC21285 0 s 1011106510690020 DAC960P / DAC1164P 0 v 1012 Micronics Computers Inc 0 v 1013 Cirrus Logic 0 d 10130038 GD 7548 0 d 10130040 GD 7555 Flat Panel GUI Accelerator 0 d 1013004c GD 7556 Video/Graphics LCD/CRT Ctrlr 0 d 101300a0 GD 5430/40 [Alpine] 0 d 101300a2 GD 5432 [Alpine] 0 d 101300a4 GD 5434-4 [Alpine] 0 d 101300a8 GD 5434-8 [Alpine] 0 d 101300ac GD 5436 [Alpine] 0 d 101300b0 GD 5440 0 d 101300b8 GD 5446 0 d 101300bc GD 5480 0 s 101300bc101300bc CL-GD5480 0 d 101300d0 GD 5462 0 d 101300d2 GD 5462 [Laguna I] 0 d 101300d4 GD 5464 [Laguna] 0 d 101300d5 GD 5464 BD [Laguna] 0 d 101300d6 GD 5465 [Laguna] 0 s 101300d613ce8031 Barco Metheus 2 Megapixel, Dual Head 0 s 101300d613cf8031 Barco Metheus 2 Megapixel, Dual Head 0 d 101300e8 GD 5436U 0 d 10131100 CL 6729 0 d 10131110 PD 6832 PCMCIA/CardBus Ctrlr 0 d 10131112 PD 6834 PCMCIA/CardBus Ctrlr 0 d 10131113 PD 6833 PCMCIA/CardBus Ctrlr 0 d 10131200 GD 7542 [Nordic] 0 d 10131202 GD 7543 [Viking] 0 d 10131204 GD 7541 [Nordic Light] 0 d 10134400 CD 4400 0 d 10136001 CS 4610/11 [CrystalClear SoundFusion Audio Accelerator] 0 s 1013600110141010 CS4610 SoundFusion Audio Accelerator 0 d 10136003 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator] 0 s 1013600310134280 Crystal SoundFusion PCI Audio Accelerator 0 s 1013600316810050 Game Theater XP 0 s 101360031681a011 Fortissimo III 7.1 0 d 10136004 CS 4614/22/24 [CrystalClear SoundFusion Audio Accelerator] 0 d 10136005 Crystal CS4281 PCI Audio 0 s 1013600510134281 Crystal CS4281 PCI Audio 0 s 1013600510cf10a8 Crystal CS4281 PCI Audio 0 s 1013600510cf10a9 Crystal CS4281 PCI Audio 0 s 1013600510cf10aa Crystal CS4281 PCI Audio 0 s 1013600510cf10ab Crystal CS4281 PCI Audio 0 s 1013600510cf10ac Crystal CS4281 PCI Audio 0 s 1013600510cf10ad Crystal CS4281 PCI Audio 0 s 1013600510cf10b4 Crystal CS4281 PCI Audio 0 s 1013600511790001 Crystal CS4281 PCI Audio 0 s 1013600514c0000c Crystal CS4281 PCI Audio 0 v 1014 IBM 0 d 10140002 PCI to MCA Bridge 0 d 10140005 Alta Lite 0 d 10140007 Alta MP 0 d 1014000a Fire Coral 0 d 10140017 CPU to PCI Bridge 0 d 10140018 TR Auto LANstreamer 0 d 1014001b GXT-150P 0 d 1014001c Carrera 0 d 1014001d 82G2675 0 d 10140020 GXT1000 Graphics Adapter 0 d 10140022 IBM27-82351 0 d 1014002d Python 0 d 1014002e SCSI RAID Adapter [ServeRAID] 0 [official name in AIX 5] s 1014002e1014002e ServeRAID-3x 0 s 1014002e1014022e ServeRAID-4H 0 d 10140031 2 Port Serial Adapter 0 s 1014003110140031 2721 WAN IOA - 2 Port Sync Serial Adapter 0 AS400 iSeries PCI sync serial card d 10140036 Miami 0 d 10140037 82660 CPU to PCI Bridge 0 d 1014003a CPU to PCI Bridge 0 d 1014003c GXT250P/GXT255P Graphics Adapter 0 d 1014003e 16/4 Token ring UTP/STP controller 0 s 1014003e1014003e Token-Ring Adapter 0 s 1014003e101400cd Token-Ring Adapter + Wake-On-LAN 0 s 1014003e101400ce 16/4 Token-Ring Adapter 2 0 s 1014003e101400cf 16/4 Token-Ring Adapter Special 0 s 1014003e101400e4 High-Speed 100/16/4 Token-Ring Adapter 0 s 1014003e101400e5 16/4 Token-Ring Adapter 2 + Wake-On-LAN 0 s 1014003e1014016d iSeries 2744 Card 0 d 10140045 SSA Adapter 0 d 10140046 MPIC interrupt controller 0 d 10140047 PCI to PCI Bridge 0 d 10140048 PCI to PCI Bridge 0 d 10140049 Warhead SCSI Controller 0 d 1014004e ATM Controller (14104e00) 0 d 1014004f ATM Controller (14104f00) 0 d 10140050 ATM Controller (14105000) 0 d 10140053 25 MBit ATM Controller 0 d 10140054 GXT500P/GXT550P Graphics Adapter 0 d 10140057 MPEG PCI Bridge 0 d 1014005c i82557B 10/100 0 d 1014005e GXT800P Graphics Adapter 0 d 1014007c ATM Controller (14107c00) 0 d 1014007d 3780IDSP [MWave] 0 d 1014008b EADS PCI to PCI Bridge 0 d 1014008e GXT3000P Graphics Adapter 0 d 10140090 GXT 3000P 0 s 101400901014008e GXT-3000P 0 d 10140091 SSA Adapter 0 d 10140095 20H2999 PCI Docking Bridge 0 d 10140096 Chukar chipset SCSI controller 0 s 1014009610140097 iSeries 2778 DASD IOA 0 s 1014009610140098 iSeries 2763 DASD IOA 0 s 1014009610140099 iSeries 2748 DASD IOA 0 d 1014009f PCI 4758 Cryptographic Accelerator 0 d 101400a5 ATM Controller (1410a500) 0 d 101400a6 ATM 155MBPS MM Controller (1410a600) 0 d 101400b7 256-bit Graphics Rasterizer [Fire GL1] 0 s 101400b7109200b8 FireGL1 AGP 32Mb 0 d 101400b8 GXT2000P Graphics Adapter 0 d 101400be ATM 622MBPS Controller (1410be00) 0 d 101400dc Advanced Systems Management Adapter (ASMA) 0 d 101400fc CPC710 Dual Bridge and Memory Controller (PCI-64) 0 d 10140104 Gigabit Ethernet-SX Adapter 0 d 10140105 CPC710 Dual Bridge and Memory Controller (PCI-32) 0 d 1014010f Remote Supervisor Adapter (RSA) 0 d 10140142 Yotta Video Compositor Input 0 s 1014014210140143 Yotta Input Controller (ytin) 0 d 10140144 Yotta Video Compositor Output 0 s 1014014410140145 Yotta Output Controller (ytout) 0 d 10140156 405GP PLB to PCI Bridge 0 d 1014015e 622Mbps ATM PCI Adapter 0 d 10140160 64bit/66MHz PCI ATM 155 MMF 0 d 1014016e GXT4000P Graphics Adapter 0 d 10140170 GXT6000P Graphics Adapter 0 d 1014017d GXT300P Graphics Adapter 0 d 10140180 Snipe chipset SCSI controller 0 s 1014018010140241 iSeries 2757 DASD IOA 0 s 1014018010140264 Quad Channel PCI-X U320 SCSI RAID Adapter (2780) 0 d 10140188 EADS-X PCI-X to PCI-X Bridge 0 d 101401a7 PCI-X to PCI-X Bridge 0 d 101401bd ServeRAID Controller 0 s 101401bd101401be ServeRAID-4M 0 s 101401bd101401bf ServeRAID-4L 0 s 101401bd10140208 ServeRAID-4Mx 0 s 101401bd1014020e ServeRAID-4Lx 0 s 101401bd1014022e ServeRAID-4H 0 s 101401bd10140258 ServeRAID-5i 0 s 101401bd10140259 ServeRAID-5i 0 d 101401c1 64bit/66MHz PCI ATM 155 UTP 0 d 101401e6 Cryptographic Accelerator 0 d 101401ff 10/100 Mbps Ethernet 0 d 10140219 Multiport Serial Adapter 0 s 101402191014021a Dual RVX 0 s 1014021910140251 Internal Modem/RVX 0 s 1014021910140252 Quad Internal Modem 0 d 1014021b GXT6500P Graphics Adapter 0 d 1014021c GXT4500P Graphics Adapter 0 d 10140233 GXT135P Graphics Adapter 0 d 10140266 PCI-X Dual Channel SCSI 0 d 10140268 Gigabit Ethernet-SX Adapter (PCI-X) 0 d 10140269 10/100/1000 Base-TX Ethernet Adapter (PCI-X) 0 d 10140302 Winnipeg PCI-X Host Bridge 0 d 10140314 ZISC 036 Neural accelerator card 0 d 1014ffff MPIC-2 interrupt controller 0 v 1015 LSI Logic Corp of Canada 0 v 1016 ICL Personal Systems 0 v 1017 SPEA Software AG 0 d 10175343 SPEA 3D Accelerator 0 v 1018 Unisys Systems 0 v 1019 Elitegroup Computer Systems 0 v 101a AT&T GIS (NCR) 0 d 101a0005 100VG ethernet 0 v 101b Vitesse Semiconductor 0 v 101c Western Digital 0 d 101c0193 33C193A 0 d 101c0196 33C196A 0 d 101c0197 33C197A 0 d 101c0296 33C296A 0 d 101c3193 7193 0 d 101c3197 7197 0 d 101c3296 33C296A 0 d 101c4296 34C296 0 d 101c9710 Pipeline 9710 0 d 101c9712 Pipeline 9712 0 d 101cc24a 90C 0 v 101e American Megatrends Inc. 0 d 101e1960 MegaRAID 0 s 101e1960101e0471 MegaRAID 471 Enterprise 1600 RAID Controller 0 s 101e1960101e0475 MegaRAID 475 Express 500/500LC RAID Controller 0 s 101e1960101e0477 MegaRAID 477 Elite 3100 RAID Controller 0 s 101e1960101e0493 MegaRAID 493 Elite 1600 RAID Controller 0 s 101e1960101e0494 MegaRAID 494 Elite 1650 RAID Controller 0 s 101e1960101e0503 MegaRAID 503 Enterprise 1650 RAID Controller 0 s 101e1960101e0511 MegaRAID 511 i4 IDE RAID Controller 0 s 101e1960101e0522 MegaRAID 522 i4133 RAID Controller 0 s 101e196010280471 PowerEdge RAID Controller 3/QC 0 s 101e196010280475 PowerEdge RAID Controller 3/SC 0 s 101e196010280493 PowerEdge RAID Controller 3/DC 0 s 101e196010280511 PowerEdge Cost Effective RAID Controller ATA100/4Ch 0 d 101e9010 MegaRAID 428 Ultra RAID Controller 0 d 101e9030 EIDE Controller 0 d 101e9031 EIDE Controller 0 d 101e9032 EIDE & SCSI Controller 0 d 101e9033 SCSI Controller 0 d 101e9040 Multimedia card 0 d 101e9060 MegaRAID 434 Ultra GT RAID Controller 0 d 101e9063 MegaRAC 0 s 101e9063101e0767 Dell Remote Assistant Card 2 0 v 101f PictureTel 0 v 1020 Hitachi Computer Products 0 v 1021 OKI Electric Industry Co. Ltd. 0 v 1022 Advanced Micro Devices [AMD] 0 d 10221100 K8 [Athlon64/Opteron] HyperTransport Technology Configuration 0 d 10221101 K8 [Athlon64/Opteron] Address Map 0 d 10221102 K8 [Athlon64/Opteron] DRAM Controller 0 d 10221103 K8 [Athlon64/Opteron] Miscellaneous Control 0 d 10222000 79c970 [PCnet32 LANCE] 0 s 1022200010142000 NetFinity 10/100 Fast Ethernet 0 s 1022200010222000 PCnet - Fast 79C971 0 s 10222000103c104c Ethernet with LAN remote power Adapter 0 s 10222000103c1064 Ethernet with LAN remote power Adapter 0 s 10222000103c1065 Ethernet with LAN remote power Adapter 0 s 10222000103c106c Ethernet with LAN remote power Adapter 0 s 10222000103c106e Ethernet with LAN remote power Adapter 0 s 10222000103c10ea Ethernet with LAN remote power Adapter 0 s 1022200011131220 EN1220 10/100 Fast Ethernet 0 s 1022200012592450 AT-2450 10/100 Fast Ethernet 0 s 1022200012592454 AT-2450v4 10Mb Ethernet Adapter 0 s 1022200012592700 AT-2700TX 10/100 Fast Ethernet 0 s 1022200012592701 AT-2700FX 100Mb Ethernet 0 s 102220004c531000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard 0 s 102220004c531010 CP5/CR6 mainboard 0 s 102220004c531020 VR6 mainboard 0 s 102220004c531030 PC5 mainboard 0 s 102220004c531040 CL7 mainboard 0 s 102220004c531060 PC7 mainboard 0 d 10222001 79c978 [HomePNA] 0 s 1022200110920a78 Multimedia Home Network Adapter 0 s 1022200116680299 ActionLink Home Network Adapter 0 d 10222003 Am 1771 MBW [Alchemy] 0 d 10222020 53c974 [PCscsi] 0 d 10222040 79c974 0 d 10223000 ELanSC520 Microcontroller 0 d 10227006 AMD-751 [Irongate] System Controller 0 d 10227007 AMD-751 [Irongate] AGP Bridge 0 d 1022700a AMD-IGR4 AGP Host to PCI Bridge 0 d 1022700b AMD-IGR4 PCI to PCI Bridge 0 d 1022700c AMD-760 MP [IGD4-2P] System Controller 0 d 1022700d AMD-760 MP [IGD4-2P] AGP Bridge 0 d 1022700e AMD-760 [IGD4-1P] System Controller 0 d 1022700f AMD-760 [IGD4-1P] AGP Bridge 0 d 10227400 AMD-755 [Cobra] ISA 0 d 10227401 AMD-755 [Cobra] IDE 0 d 10227403 AMD-755 [Cobra] ACPI 0 d 10227404 AMD-755 [Cobra] USB 0 d 10227408 AMD-756 [Viper] ISA 0 d 10227409 AMD-756 [Viper] IDE 0 d 1022740b AMD-756 [Viper] ACPI 0 d 1022740c AMD-756 [Viper] USB 0 d 10227410 AMD-766 [ViperPlus] ISA 0 d 10227411 AMD-766 [ViperPlus] IDE 0 d 10227413 AMD-766 [ViperPlus] ACPI 0 d 10227414 AMD-766 [ViperPlus] USB 0 d 10227440 AMD-768 [Opus] ISA 0 s 1022744010438044 A7M-D Mainboard 0 d 10227441 AMD-768 [Opus] IDE 0 d 10227443 AMD-768 [Opus] ACPI 0 s 1022744310438044 A7M-D Mainboard 0 d 10227445 AMD-768 [Opus] Audio 0 d 10227446 AMD-768 [Opus] MC97 Modem (Smart Link HAMR5600 compatible) 0 d 10227448 AMD-768 [Opus] PCI 0 d 10227449 AMD-768 [Opus] USB 0 d 10227450 AMD-8131 PCI-X Bridge 0 d 10227451 AMD-8131 PCI-X APIC 0 d 10227454 AMD-8151 System Controller 0 d 10227455 AMD-8151 AGP Bridge 0 d 10227460 AMD-8111 PCI 0 s 10227460161f3017 HDAMB 0 d 10227461 AMD-8111 USB 0 d 10227462 AMD-8111 Ethernet 0 d 10227464 AMD-8111 USB 0 s 10227464161f3017 HDAMB 0 d 10227468 AMD-8111 LPC 0 s 10227468161f3017 HDAMB 0 d 10227469 AMD-8111 IDE 0 s 10227469161f3017 HDAMB 0 d 1022746a AMD-8111 SMBus 2.0 0 d 1022746b AMD-8111 ACPI 0 s 1022746b161f3017 HDAMB 0 d 1022746d AMD-8111 AC97 Audio 0 s 1022746d161f3017 HDAMB 0 d 1022746e AMD-8111 MC97 Modem 0 d 1022756b AMD-8111 ACPI 0 v 1023 Trident Microsystems 0 d 10230194 82C194 0 d 10232000 4DWave DX 0 d 10232001 4DWave NX 0 s 10232001122d1400 Trident PCI288-Q3DII (NX) 0 d 10232100 CyberBlade XP4m32 0 d 10238400 CyberBlade/i7 0 s 1023840010238400 CyberBlade i7 AGP 0 d 10238420 CyberBlade/i7d 0 s 102384200e11b15a CyberBlade i7 AGP 0 d 10238500 CyberBlade/i1 0 d 10238520 CyberBlade i1 0 s 102385200e11b16e CyberBlade i1 AGP 0 s 1023852010238520 CyberBlade i1 AGP 0 d 10238620 CyberBlade/i1 0 s 1023862010140502 ThinkPad R30/T30 0 d 10238820 CyberBlade XPAi1 0 d 10239320 TGUI 9320 0 d 10239350 GUI Accelerator 0 d 10239360 Flat panel GUI Accelerator 0 d 10239382 Cyber 9382 [Reference design] 0 d 10239383 Cyber 9383 [Reference design] 0 d 10239385 Cyber 9385 [Reference design] 0 d 10239386 Cyber 9386 0 d 10239388 Cyber 9388 0 d 10239397 Cyber 9397 0 d 1023939a Cyber 9397DVD 0 d 10239420 TGUI 9420 0 d 10239430 TGUI 9430 0 d 10239440 TGUI 9440 0 d 10239460 TGUI 9460 0 d 10239470 TGUI 9470 0 d 10239520 Cyber 9520 0 d 10239525 Cyber 9525 0 s 1023952510cf1094 Lifebook C6155 0 d 10239540 Cyber 9540 0 d 10239660 TGUI 9660/938x/968x 0 d 10239680 TGUI 9680 0 d 10239682 TGUI 9682 0 d 10239683 TGUI 9683 0 d 10239685 ProVIDIA 9685 0 d 10239750 3DImage 9750 0 s 1023975010149750 3DImage 9750 0 s 1023975010239750 3DImage 9750 0 d 10239753 TGUI 9753 0 d 10239754 TGUI 9754 0 d 10239759 TGUI 975 0 d 10239783 TGUI 9783 0 d 10239785 TGUI 9785 0 d 10239850 3DImage 9850 0 d 10239880 Blade 3D PCI/AGP 0 s 1023988010239880 Blade 3D 0 d 10239910 CyberBlade/XP 0 d 10239930 CyberBlade/XPm 0 v 1024 Zenith Data Systems 0 v 1025 Acer Incorporated [ALI] 0 d 10251435 M1435 0 d 10251445 M1445 0 d 10251449 M1449 0 d 10251451 M1451 0 d 10251461 M1461 0 d 10251489 M1489 0 d 10251511 M1511 0 d 10251512 ALI M1512 Aladdin 0 d 10251513 M1513 0 d 10251521 ALI M1521 Aladdin III CPU Bridge 0 s 1025152110b91521 ALI M1521 Aladdin III CPU Bridge 0 d 10251523 ALI M1523 ISA Bridge 0 s 1025152310b91523 ALI M1523 ISA Bridge 0 d 10251531 M1531 Northbridge [Aladdin IV/IV+] 0 d 10251533 M1533 PCI-to-ISA Bridge 0 s 1025153310b91533 ALI M1533 Aladdin IV/V ISA South Bridge 0 d 10251535 M1535 PCI Bridge + Super I/O + FIR 0 d 10251541 M1541 Northbridge [Aladdin V] 0 s 1025154110b91541 ALI M1541 Aladdin V/V+ AGP+PCI North Bridge 0 d 10251542 M1542 Northbridge [Aladdin V] 0 d 10251543 M1543 PCI-to-ISA Bridge + Super I/O + FIR 0 d 10251561 M1561 Northbridge [Aladdin 7] 0 d 10251621 M1621 Northbridge [Aladdin-Pro II] 0 d 10251631 M1631 Northbridge+3D Graphics [Aladdin TNT2] 0 d 10251641 M1641 Northbridge [Aladdin-Pro IV] 0 d 10251647 M1647 [MaGiK1] PCI North Bridge 0 d 10251671 M1671 Northbridge [ALADDiN-P4] 0 d 10251672 Northbridge [CyberALADDiN-P4] 0 d 10253141 M3141 0 d 10253143 M3143 0 d 10253145 M3145 0 d 10253147 M3147 0 d 10253149 M3149 0 d 10253151 M3151 0 d 10253307 M3307 MPEG-I Video Controller 0 d 10253309 M3309 MPEG-II Video w/ Software Audio Decoder 0 d 10253321 M3321 MPEG-II Audio/Video Decoder 0 d 10255212 M4803 0 d 10255215 ALI PCI EIDE Controller 0 d 10255217 M5217H 0 d 10255219 M5219 0 d 10255225 M5225 0 d 10255229 M5229 0 d 10255235 M5235 0 d 10255237 M5237 PCI USB Host Controller 0 d 10255240 EIDE Controller 0 d 10255241 PCMCIA Bridge 0 d 10255242 General Purpose Controller 0 d 10255243 PCI to PCI Bridge Controller 0 d 10255244 Floppy Disk Controller 0 d 10255247 M1541 PCI to PCI Bridge 0 d 10255251 M5251 P1394 Controller 0 d 10255427 PCI to AGP Bridge 0 d 10255451 M5451 PCI AC-Link Controller Audio Device 0 d 10255453 M5453 PCI AC-Link Controller Modem Device 0 d 10257101 M7101 PCI PMU Power Management Controller 0 s 1025710110b97101 M7101 PCI PMU Power Management Controller 0 v 1028 Dell 0 d 10280001 PowerEdge Expandable RAID Controller 2/Si 0 s 1028000110280001 PowerEdge 2400 0 d 10280002 PowerEdge Expandable RAID Controller 3/Di 0 s 1028000210280002 PowerEdge 4400 0 d 10280003 PowerEdge Expandable RAID Controller 3/Si 0 s 1028000310280003 PowerEdge 2450 0 d 10280006 PowerEdge Expandable RAID Controller 3/Di 0 d 10280007 Remote Access Card III 0 d 10280008 Remote Access Card III 0 d 10280009 Remote Access Card III: BMC/SMIC device not present 0 d 1028000a PowerEdge Expandable RAID Controller 3/Di 0 d 1028000c Embedded Remote Access or ERA/O 0 d 1028000d Embedded Remote Access: BMC/SMIC device 0 d 1028000e PowerEdge Expandable RAID controller 4/Di 0 d 1028000f PowerEdge Expandable RAID controller 4/Di 0 d 10280010 Remote Access Card 4 0 d 10280011 Remote Access Card 4 Daughter Card 0 d 10280012 Remote Access Card 4 Daughter Card Virtual UART 0 d 10280013 PowerEdge Expandable RAID controller 4 0 s 102800131028016c PowerEdge Expandable RAID Controller 4e/Si 0 s 102800131028016d PowerEdge Expandable RAID Controller 4e/Di 0 s 102800131028016e PowerEdge Expandable RAID Controller 4e/Di 0 s 102800131028016f PowerEdge Expandable RAID Controller 4e/Di 0 s 1028001310280170 PowerEdge Expandable RAID Controller 4e/Di 0 d 10280014 Remote Access Card 4 Daughter Card SMIC interface 0 v 1029 Siemens Nixdorf IS 0 v 102a LSI Logic 0 d 102a0000 HYDRA 0 d 102a0010 ASPEN 0 d 102a001f AHA-2940U2/U2W /7890/7891 SCSI Controllers 0 s 102a001f9005000f 2940U2W SCSI Controller 0 s 102a001f90050106 2940U2W SCSI Controller 0 s 102a001f9005a180 2940U2W SCSI Controller 0 d 102a00c5 AIC-7899 U160/m SCSI Controller 0 s 102a00c5102800c5 PowerEdge 2550/2650/4600 0 d 102a00cf AIC-7899P U160/m 0 s 102a00cf10280106 PowerEdge 4600 0 s 102a00cf10280121 PowerEdge 2650 0 v 102b Matrox Graphics, Inc. 0 d 102b0010 MGA-I [Impression?] 0 DJ: I've a suspicion that 0010 is a duplicate of 0d10. d 102b0100 MGA 1064SG [Mystique] 0 d 102b0518 MGA-II [Athena] 0 d 102b0519 MGA 2064W [Millennium] 0 d 102b051a MGA 1064SG [Mystique] 0 s 102b051a102b0100 MGA-1064SG Mystique 0 s 102b051a102b1100 MGA-1084SG Mystique 0 s 102b051a102b1200 MGA-1084SG Mystique 0 s 102b051a1100102b MGA-1084SG Mystique 0 s 102b051a110a0018 Scenic Pro C5 (D1025) 0 d 102b051b MGA 2164W [Millennium II] 0 s 102b051b102b051b MGA-2164W Millennium II 0 s 102b051b102b1100 MGA-2164W Millennium II 0 s 102b051b102b1200 MGA-2164W Millennium II 0 d 102b051e MGA 1064SG [Mystique] AGP 0 d 102b051f MGA 2164W [Millennium II] AGP 0 d 102b0520 MGA G200 0 s 102b0520102bdbc2 G200 Multi-Monitor 0 s 102b0520102bdbc8 G200 Multi-Monitor 0 s 102b0520102bdbe2 G200 Multi-Monitor 0 s 102b0520102bdbe8 G200 Multi-Monitor 0 s 102b0520102bff03 Millennium G200 SD 0 s 102b0520102bff04 Marvel G200 0 d 102b0521 MGA G200 AGP 0 s 102b05211014ff03 Millennium G200 AGP 0 s 102b0521102b48e9 Mystique G200 AGP 0 s 102b0521102b48f8 Millennium G200 SD AGP 0 s 102b0521102b4a60 Millennium G200 LE AGP 0 s 102b0521102b4a64 Millennium G200 AGP 0 s 102b0521102bc93c Millennium G200 AGP 0 s 102b0521102bc9b0 Millennium G200 AGP 0 s 102b0521102bc9bc Millennium G200 AGP 0 s 102b0521102bca60 Millennium G250 LE AGP 0 s 102b0521102bca6c Millennium G250 AGP 0 s 102b0521102bdbbc Millennium G200 AGP 0 s 102b0521102bdbc2 Millennium G200 MMS (Dual G200) 0 s 102b0521102bdbc3 G200 Multi-Monitor 0 s 102b0521102bdbc8 Millennium G200 MMS (Dual G200) 0 s 102b0521102bdbd2 G200 Multi-Monitor 0 s 102b0521102bdbd3 G200 Multi-Monitor 0 s 102b0521102bdbd4 G200 Multi-Monitor 0 s 102b0521102bdbd5 G200 Multi-Monitor 0 s 102b0521102bdbd8 G200 Multi-Monitor 0 s 102b0521102bdbd9 G200 Multi-Monitor 0 s 102b0521102bdbe2 Millennium G200 MMS (Quad G200) 0 s 102b0521102bdbe3 G200 Multi-Monitor 0 s 102b0521102bdbe8 Millennium G200 MMS (Quad G200) 0 s 102b0521102bdbf2 G200 Multi-Monitor 0 s 102b0521102bdbf3 G200 Multi-Monitor 0 s 102b0521102bdbf4 G200 Multi-Monitor 0 s 102b0521102bdbf5 G200 Multi-Monitor 0 s 102b0521102bdbf8 G200 Multi-Monitor 0 s 102b0521102bdbf9 G200 Multi-Monitor 0 s 102b0521102bf806 Mystique G200 Video AGP 0 s 102b0521102bff00 MGA-G200 AGP 0 s 102b0521102bff02 Mystique G200 AGP 0 s 102b0521102bff03 Millennium G200 AGP 0 s 102b0521102bff04 Marvel G200 AGP 0 s 102b0521110a0032 MGA-G200 AGP 0 d 102b0525 MGA G400 AGP 0 s 102b05250e11b16f MGA-G400 AGP 0 s 102b0525102b0328 Millennium G400 16Mb SDRAM 0 s 102b0525102b0338 Millennium G400 16Mb SDRAM 0 s 102b0525102b0378 Millennium G400 32Mb SDRAM 0 s 102b0525102b0541 Millennium G450 Dual Head 0 s 102b0525102b0542 Millennium G450 Dual Head LX 0 s 102b0525102b0543 Millennium G450 Single Head LX 0 s 102b0525102b0641 Millennium G450 32Mb SDRAM Dual Head 0 s 102b0525102b0642 Millennium G450 32Mb SDRAM Dual Head LX 0 s 102b0525102b0643 Millennium G450 32Mb SDRAM Single Head LX 0 s 102b0525102b07c0 Millennium G450 Dual Head LE 0 s 102b0525102b07c1 Millennium G450 SDR Dual Head LE 0 s 102b0525102b0d41 Millennium G450 Dual Head PCI 0 s 102b0525102b0d42 Millennium G450 Dual Head LX PCI 0 s 102b0525102b0d43 Millennium G450 32Mb Dual Head PCI 0 s 102b0525102b0e00 Marvel G450 eTV 0 s 102b0525102b0e01 Marvel G450 eTV 0 s 102b0525102b0e02 Marvel G450 eTV 0 s 102b0525102b0e03 Marvel G450 eTV 0 s 102b0525102b0f80 Millennium G450 Low Profile 0 s 102b0525102b0f81 Millennium G450 Low Profile 0 s 102b0525102b0f82 Millennium G450 Low Profile DVI 0 s 102b0525102b0f83 Millennium G450 Low Profile DVI 0 s 102b0525102b19d8 Millennium G400 16Mb SGRAM 0 s 102b0525102b19f8 Millennium G400 32Mb SGRAM 0 s 102b0525102b2159 Millennium G400 Dual Head 16Mb 0 s 102b0525102b2179 Millennium G400 MAX/Dual Head 32Mb 0 s 102b0525102b217d Millennium G400 Dual Head Max 0 s 102b0525102b23c0 Millennium G450 0 s 102b0525102b23c1 Millennium G450 0 s 102b0525102b23c2 Millennium G450 DVI 0 s 102b0525102b23c3 Millennium G450 DVI 0 s 102b0525102b2f58 Millennium G400 0 s 102b0525102b2f78 Millennium G400 0 s 102b0525102b3693 Marvel G400 AGP 0 s 102b0525102b5dd0 4Sight II 0 s 102b0525102b5f50 4Sight II 0 s 102b0525102b5f51 4Sight II 0 s 102b0525102b5f52 4Sight II 0 s 102b0525102b9010 Millennium G400 Dual Head 0 s 102b052514580400 GA-G400 0 s 102b052517050001 Millennium G450 32MB SGRAM 0 s 102b052517050002 Millennium G450 16MB SGRAM 0 s 102b052517050003 Millennium G450 32MB 0 s 102b052517050004 Millennium G450 16MB 0 d 102b0527 MGA Parhelia AGP 0 s 102b0527102b0840 Parhelia 128Mb 0 d 102b0d10 MGA Ultima/Impression 0 d 102b1000 MGA G100 [Productiva] 0 s 102b1000102bff01 Productiva G100 0 s 102b1000102bff05 Productiva G100 Multi-Monitor 0 d 102b1001 MGA G100 [Productiva] AGP 0 s 102b1001102b1001 MGA-G100 AGP 0 s 102b1001102bff00 MGA-G100 AGP 0 s 102b1001102bff01 MGA-G100 Productiva AGP 0 s 102b1001102bff03 Millennium G100 AGP 0 s 102b1001102bff04 MGA-G100 AGP 0 s 102b1001102bff05 MGA-G100 Productiva AGP Multi-Monitor 0 s 102b1001110a001e MGA-G100 AGP 0 d 102b2007 MGA Mistral 0 d 102b2527 MGA G550 AGP 0 s 102b2527102b0f83 Millennium G550 0 s 102b2527102b0f84 Millennium G550 Dual Head DDR 32Mb 0 s 102b2527102b1e41 Millennium G550 0 d 102b2537 MGA G650 AGP 0 d 102b4536 VIA Framegrabber 0 d 102b6573 Shark 10/100 Multiport SwitchNIC 0 v 102c Chips and Technologies 0 d 102c00b8 F64310 0 d 102c00c0 F69000 HiQVideo 0 s 102c00c0102c00c0 F69000 HiQVideo 0 s 102c00c04c531000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard 0 s 102c00c04c531010 CP5/CR6 mainboard 0 s 102c00c04c531020 VR6 mainboard 0 s 102c00c04c531030 PC5 mainboard 0 s 102c00c04c531050 CT7 mainboard 0 s 102c00c04c531051 CE7 mainboard 0 d 102c00d0 F65545 0 d 102c00d8 F65545 0 d 102c00dc F65548 0 d 102c00e0 F65550 0 d 102c00e4 F65554 0 d 102c00e5 F65555 HiQVPro 0 s 102c00e50e11b049 Armada 1700 Laptop Display Controller 0 d 102c00f0 F68554 0 d 102c00f4 F68554 HiQVision 0 d 102c00f5 F68555 0 d 102c0c30 F69030 0 s 102c0c304c531000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard 0 s 102c0c304c531050 CT7 mainboard 0 s 102c0c304c531051 CE7 mainboard 0 s 102c0c304c531080 CT8 mainboard 0 C5C project cancelled v 102d Wyse Technology Inc. 0 d 102d50dc 3328 Audio 0 v 102e Olivetti Advanced Technology 0 v 102f Toshiba America 0 d 102f0009 r4x00 0 d 102f000a TX3927 MIPS RISC PCI Controller 0 d 102f0020 ATM Meteor 155 0 s 102f0020102f00f8 ATM Meteor 155 0 d 102f0030 TC35815CF PCI 10/100 Mbit Ethernet Controller 0 d 102f0031 TC35815CF PCI 10/100 Mbit Ethernet Controller with WOL 0 d 102f0105 TC86C001 [goku-s] IDE 0 d 102f0106 TC86C001 [goku-s] USB 1.1 Host 0 d 102f0107 TC86C001 [goku-s] USB Device Controller 0 d 102f0108 TC86C001 [goku-s] I2C/SIO/GPIO Controller 0 d 102f0180 TX4927/38 MIPS RISC PCI Controller 0 d 102f0181 TX4925 MIPS RISC PCI Controller 0 d 102f0182 TX4937 MIPS RISC PCI Controller 0 v 1030 TMC Research 0 v 1031 Miro Computer Products AG 0 d 10315601 DC20 ASIC 0 d 10315607 Video I/O & motion JPEG compressor 0 d 10315631 Media 3D 0 d 10316057 MiroVideo DC10/DC30+ 0 v 1032 Compaq 0 v 1033 NEC Corporation 0 d 10330000 Vr4181A USB Host or Function Control Unit 0 d 10330001 PCI to 486-like bus Bridge 0 d 10330002 PCI to VL98 Bridge 0 d 10330003 ATM Controller 0 d 10330004 R4000 PCI Bridge 0 d 10330005 PCI to 486-like bus Bridge 0 d 10330006 PC-9800 Graphic Accelerator 0 d 10330007 PCI to UX-Bus Bridge 0 d 10330008 PC-9800 Graphic Accelerator 0 d 10330009 PCI to PC9800 Core-Graph Bridge 0 d 10330016 PCI to VL Bridge 0 d 1033001a [Nile II] 0 d 10330021 Vrc4373 [Nile I] 0 d 10330029 PowerVR PCX1 0 d 1033002a PowerVR 3D 0 d 1033002c Star Alpha 2 0 d 1033002d PCI to C-bus Bridge 0 d 10330035 USB 0 s 1033003511790001 USB 0 s 1033003512ee7000 Root Hub 0 s 1033003517990001 Root Hub 0 s 10330035807d0035 PCI-USB2 (OHCI subsystem) 0 d 1033003b PCI to C-bus Bridge 0 d 1033003e NAPCCARD Cardbus Controller 0 d 10330046 PowerVR PCX2 [midas] 0 d 1033005a Vrc5074 [Nile 4] 0 d 10330063 Firewarden 0 d 10330067 PowerVR Neon 250 Chipset 0 s 1033006710100020 PowerVR Neon 250 AGP 32Mb 0 s 1033006710100080 PowerVR Neon 250 AGP 16Mb 0 s 1033006710100088 PowerVR Neon 250 16Mb 0 s 1033006710100090 PowerVR Neon 250 AGP 16Mb 0 s 1033006710100098 PowerVR Neon 250 16Mb 0 s 10330067101000a0 PowerVR Neon 250 AGP 32Mb 0 s 10330067101000a8 PowerVR Neon 250 32Mb 0 s 1033006710100120 PowerVR Neon 250 AGP 32Mb 0 d 10330074 56k Voice Modem 0 s 1033007410338014 RCV56ACF 56k Voice Modem 0 d 1033009b Vrc5476 0 d 103300a5 VRC4173 0 d 103300a6 VRC5477 AC97 0 d 103300cd IEEE 1394 [OrangeLink] Host Controller 0 s 103300cd12ee8011 Root hub 0 d 103300ce IEEE 1394 Host Controller 0 d 103300df Vr4131 0 d 103300e0 USB 2.0 0 s 103300e00ee43383 Sitecom IEEE 1394 / USB2.0 Combo Card 0 s 103300e012ee7001 Root hub 0 s 103300e017990002 Root Hub 0 s 103300e0807d1043 PCI-USB2 (EHCI subsystem) 0 d 103300e7 IEEE 1394 Host Controller 0 d 103300f2 uPD72874 IEEE1394 OHCI 1.1 3-port PHY-Link Ctrlr 0 d 103300f3 uPD6113x Multimedia Decoder/Processor [EMMA2] 0 d 1033010c VR7701 0 v 1034 Framatome Connectors USA Inc. 0 v 1035 Comp. & Comm. Research Lab 0 v 1036 Future Domain Corp. 0 d 10360000 TMC-18C30 [36C70] 0 v 1037 Hitachi Micro Systems 0 v 1038 AMP, Inc 0 v 1039 Silicon Integrated Systems [SiS] 0 d 10390001 Virtual PCI-to-PCI bridge (AGP) 0 d 10390002 SG86C202 0 d 10390006 85C501/2/3 0 d 10390008 SiS85C503/5513 (LPC Bridge) 0 d 10390009 ACPI 0 d 10390016 SiS961/2 SMBus Controller 0 source: http://members.datafast.net.au/dft0802/downloads/pcidevs.txt d 10390018 SiS85C503/5513 (LPC Bridge) 0 d 10390180 RAID bus controller 180 SATA/PATA [SiS] 0 Controller for 2 PATA and 2 SATA channels d 10390181 SiS SATA 0 d 10390200 5597/5598/6326 VGA 0 s 1039020010390000 SiS5597 SVGA (Shared RAM) 0 d 10390204 82C204 0 d 10390205 SG86C205 0 d 10390300 300/305 PCI/AGP VGA Display Adapter 0 s 10390300107d2720 Leadtek WinFast VR300 0 d 10390310 315H PCI/AGP VGA Display Adapter 0 d 10390315 315 PCI/AGP VGA Display Adapter 0 d 10390325 315PRO PCI/AGP VGA Display Adapter 0 d 10390330 330 [Xabre] PCI/AGP VGA Display Adapter 0 d 10390406 85C501/2 0 d 10390496 85C496 0 d 10390530 530 Host 0 d 10390540 540 Host 0 d 10390550 550 Host 0 d 10390597 5513C 0 d 10390601 85C601 0 d 10390620 620 Host 0 d 10390630 630 Host 0 d 10390633 633 Host 0 d 10390635 635 Host 0 d 10390645 SiS645 Host & Memory & AGP Controller 0 d 10390646 SiS645DX Host & Memory & AGP Controller 0 d 10390648 SiS 645xx 0 d 10390650 650/M650 Host 0 d 10390651 651 Host 0 d 10390655 655 Host 0 d 10390660 660 Host 0 d 10390661 661FX/M661FX/M661MX Host 0 d 10390730 730 Host 0 d 10390733 733 Host 0 d 10390735 735 Host 0 d 10390740 740 Host 0 d 10390741 741/741GX/M741 Host 0 d 10390745 745 Host 0 d 10390746 746 Host 0 d 10390755 755 Host 0 d 10390760 760/M760 Host 0 d 10390900 SiS900 PCI Fast Ethernet 0 s 1039090010190a14 K7S5A motherboard 0 s 1039090010390900 SiS900 10/100 Ethernet Adapter 0 s 1039090010438035 CUSI-FX motherboard 0 d 10390961 SiS961 [MuTIOL Media IO] 0 d 10390962 SiS962 [MuTIOL Media IO] 0 d 10390963 SiS963 [MuTIOL Media IO] 0 d 10390964 SiS964 [MuTIOL Media IO] 0 d 10390965 SiS965 [MuTIOL Media IO] 0 d 10393602 83C602 0 d 10395107 5107 0 d 10395300 SiS540 PCI Display Adapter 0 d 10395315 550 PCI/AGP VGA Display Adapter 0 d 10395401 486 PCI Chipset 0 d 10395511 5511/5512 0 d 10395513 5513 [IDE] 0 s 1039551310190970 P6STP-FL motherboard 0 s 1039551310395513 SiS5513 EIDE Controller (A,B step) 0 s 1039551310438035 CUSI-FX motherboard 0 d 10395517 5517 0 d 10395571 5571 0 d 10395581 5581 Pentium Chipset 0 d 10395582 5582 0 d 10395591 5591/5592 Host 0 d 10395596 5596 Pentium Chipset 0 d 10395597 5597 [SiS5582] 0 d 10395600 5600 Host 0 d 10396204 Video decoder & MPEG interface 0 d 10396205 VGA Controller 0 d 10396236 6236 3D-AGP 0 d 10396300 630/730 PCI/AGP VGA Display Adapter 0 s 1039630010190970 P6STP-FL motherboard 0 s 1039630010438035 CUSI-FX motherboard 0 d 10396306 530/620 PCI/AGP VGA Display Adapter 0 s 1039630610396306 SiS530,620 GUI Accelerator+3D 0 d 10396325 65x/M650/740 PCI/AGP VGA Display Adapter 0 d 10396326 86C326 5598/6326 0 s 1039632610396326 SiS6326 GUI Accelerator 0 s 1039632610920a50 SpeedStar A50 0 s 1039632610920a70 SpeedStar A70 0 s 1039632610924910 SpeedStar A70 0 s 1039632610924920 SpeedStar A70 0 s 1039632615696326 SiS6326 GUI Accelerator 0 d 10396330 661/741/760 PCI/AGP VGA Display Adapter 0 s 1039633010396330 [M]661xX/[M]741[GX]/[M]760 PCI/AGP VGA Adapter 0 d 10397001 USB 1.0 Controller 0 s 1039700110190a14 K7S5A motherboard 0 s 1039700110397000 Onboard USB Controller 0 d 10397002 USB 2.0 Controller 0 s 1039700215097002 Onboard USB Controller 0 d 10397007 FireWire Controller 0 d 10397012 Sound Controller 0 d 10397013 AC'97 Modem Controller 0 There are may be different modem codecs here (Intel537 compatible and incompatible) d 10397016 SiS7016 PCI Fast Ethernet Adapter 0 s 1039701610397016 SiS7016 10/100 Ethernet Adapter 0 d 10397018 SiS PCI Audio Accelerator 0 s 10397018101401b6 SiS PCI Audio Accelerator 0 s 10397018101401b7 SiS PCI Audio Accelerator 0 s 1039701810197018 SiS PCI Audio Accelerator 0 s 103970181025000e SiS PCI Audio Accelerator 0 s 1039701810250018 SiS PCI Audio Accelerator 0 s 1039701810397018 SiS PCI Audio Accelerator 0 s 103970181043800b SiS PCI Audio Accelerator 0 s 1039701810547018 SiS PCI Audio Accelerator 0 s 10397018107d5330 SiS PCI Audio Accelerator 0 s 10397018107d5350 SiS PCI Audio Accelerator 0 s 1039701811703209 SiS PCI Audio Accelerator 0 s 103970181462400a SiS PCI Audio Accelerator 0 s 1039701814a42089 SiS PCI Audio Accelerator 0 s 1039701814cd2194 SiS PCI Audio Accelerator 0 s 1039701814ff1100 SiS PCI Audio Accelerator 0 s 10397018152d8808 SiS PCI Audio Accelerator 0 s 1039701815581103 SiS PCI Audio Accelerator 0 s 1039701815582200 SiS PCI Audio Accelerator 0 s 1039701815637018 SiS PCI Audio Accelerator 0 s 1039701815c50111 SiS PCI Audio Accelerator 0 s 10397018270fa171 SiS PCI Audio Accelerator 0 s 10397018a0a00022 SiS PCI Audio Accelerator 0 d 10397019 SiS7019 Audio Accelerator 0 v 103a Seiko Epson Corporation 0 v 103b Tatung Co. of America 0 v 103c Hewlett-Packard Company 0 d 103c1005 A4977A Visualize EG 0 d 103c1006 Visualize FX6 0 d 103c1008 Visualize FX4 0 d 103c100a Visualize FX2 0 d 103c1028 Tach TL Fibre Channel Host Adapter 0 d 103c1029 Tach XL2 Fibre Channel Host Adapter 0 s 103c1029107e000f Interphase 5560 Fibre Channel Adapter 0 s 103c102990049210 1Gb/2Gb Family Fibre Channel Controller 0 s 103c102990049211 1Gb/2Gb Family Fibre Channel Controller 0 d 103c102a Tach TS Fibre Channel Host Adapter 0 s 103c102a107e000e Interphase 5540/5541 Fibre Channel Adapter 0 s 103c102a90049110 1Gb/2Gb Family Fibre Channel Controller 0 s 103c102a90049111 1Gb/2Gb Family Fibre Channel Controller 0 d 103c1030 J2585A DeskDirect 10/100VG NIC 0 d 103c1031 J2585B HP 10/100VG PCI LAN Adapter 0 s 103c1031103c1040 J2973A DeskDirect 10BaseT NIC 0 s 103c1031103c1041 J2585B DeskDirect 10/100VG NIC 0 s 103c1031103c1042 J2970A DeskDirect 10BaseT/2 NIC 0 d 103c1040 J2973A DeskDirect 10BaseT NIC 0 d 103c1041 J2585B DeskDirect 10/100 NIC 0 d 103c1042 J2970A DeskDirect 10BaseT/2 NIC 0 d 103c1048 Diva Serial [GSP] Multiport UART 0 s 103c1048103c1049 Tosca Console 0 s 103c1048103c104a Tosca Secondary 0 s 103c1048103c104b Maestro SP2 0 s 103c1048103c1223 Superdome Console 0 s 103c1048103c1226 Keystone SP2 0 s 103c1048103c1227 Powerbar SP2 0 s 103c1048103c1282 Everest SP2 0 d 103c1054 PCI Local Bus Adapter 0 d 103c1064 79C970 PCnet Ethernet Controller 0 d 103c108b Visualize FXe 0 d 103c10c1 NetServer Smart IRQ Router 0 d 103c10ed TopTools Remote Control 0 d 103c1200 82557B 10/100 NIC 0 d 103c1219 NetServer PCI Hot-Plug Controller 0 d 103c121a NetServer SMIC Controller 0 d 103c121b NetServer Legacy COM Port Decoder 0 d 103c121c NetServer PCI COM Port Decoder 0 d 103c1229 zx1 System Bus Adapter 0 d 103c122a zx1 I/O Controller 0 d 103c122e zx1 Local Bus Adapter 0 d 103c127c sx1000 I/O Controller 0 d 103c1290 Auxiliary Diva Serial Port 0 d 103c2910 E2910A PCIBus Exerciser 0 d 103c2925 E2925A 32 Bit, 33 MHzPCI Exerciser & Analyzer 0 v 103e Solliday Engineering 0 v 103f Synopsys/Logic Modeling Group 0 v 1040 Accelgraphics Inc. 0 v 1041 Computrend 0 v 1042 Micron 0 d 10421000 PC Tech RZ1000 0 d 10421001 PC Tech RZ1001 0 d 10423000 Samurai_0 0 d 10423010 Samurai_1 0 d 10423020 Samurai_IDE 0 v 1043 ASUSTeK Computer Inc. 0 d 10430675 ISDNLink P-IN100-ST-D 0 d 10434015 v7100 SDRAM [GeForce2 MX] 0 d 10434021 v7100 Combo Deluxe [GeForce2 MX + TV tuner] 0 d 10434057 v8200 GeForce 3 0 d 10438043 v8240 PAL 128M [P4T] Motherboard 0 d 1043807b v9280/TD [Geforce4 TI4200 8X With TV-Out and DVI] 0 d 104380bb v9180 Magic/T [GeForce4 MX440 AGP 8x 64MB TV-out] 0 v 1044 Adaptec (formerly DPT) 0 d 10441012 Domino RAID Engine 0 d 1044a400 SmartCache/Raid I-IV Controller 0 d 1044a500 PCI Bridge 0 d 1044a501 SmartRAID V Controller 0 s 1044a5011044c001 PM1554U2 Ultra2 Single Channel 0 s 1044a5011044c002 PM1654U2 Ultra2 Single Channel 0 s 1044a5011044c003 PM1564U3 Ultra3 Single Channel 0 s 1044a5011044c004 PM1564U3 Ultra3 Dual Channel 0 s 1044a5011044c005 PM1554U2 Ultra2 Single Channel (NON ACPI) 0 s 1044a5011044c00a PM2554U2 Ultra2 Single Channel 0 s 1044a5011044c00b PM2654U2 Ultra2 Single Channel 0 s 1044a5011044c00c PM2664U3 Ultra3 Single Channel 0 s 1044a5011044c00d PM2664U3 Ultra3 Dual Channel 0 s 1044a5011044c00e PM2554U2 Ultra2 Single Channel (NON ACPI) 0 s 1044a5011044c00f PM2654U2 Ultra2 Single Channel (NON ACPI) 0 s 1044a5011044c014 PM3754U2 Ultra2 Single Channel (NON ACPI) 0 s 1044a5011044c015 PM3755U2B Ultra2 Single Channel (NON ACPI) 0 s 1044a5011044c016 PM3755F Fibre Channel (NON ACPI) 0 s 1044a5011044c01e PM3757U2 Ultra2 Single Channel 0 s 1044a5011044c01f PM3757U2 Ultra2 Dual Channel 0 s 1044a5011044c020 PM3767U3 Ultra3 Dual Channel 0 s 1044a5011044c021 PM3767U3 Ultra3 Quad Channel 0 s 1044a5011044c028 PM2865U3 Ultra3 Single Channel 0 s 1044a5011044c029 PM2865U3 Ultra3 Dual Channel 0 s 1044a5011044c02a PM2865F Fibre Channel 0 s 1044a5011044c03c 2000S Ultra3 Single Channel 0 s 1044a5011044c03d 2000S Ultra3 Dual Channel 0 s 1044a5011044c03e 2000F Fibre Channel 0 s 1044a5011044c046 3000S Ultra3 Single Channel 0 s 1044a5011044c047 3000S Ultra3 Dual Channel 0 s 1044a5011044c048 3000F Fibre Channel 0 s 1044a5011044c050 5000S Ultra3 Single Channel 0 s 1044a5011044c051 5000S Ultra3 Dual Channel 0 s 1044a5011044c052 5000F Fibre Channel 0 s 1044a5011044c05a 2400A UDMA Four Channel 0 s 1044a5011044c05b 2400A UDMA Four Channel DAC 0 s 1044a5011044c064 3010S Ultra3 Dual Channel 0 s 1044a5011044c065 3010S Ultra3 Four Channel 0 s 1044a5011044c066 3010S Fibre Channel 0 d 1044a511 SmartRAID V Controller 0 s 1044a5111044c032 ASR-2005S I2O Zero Channel 0 v 1045 OPTi Inc. 0 d 1045a0f8 82C750 [Vendetta] USB Controller 0 d 1045c101 92C264 0 d 1045c178 92C178 0 d 1045c556 82X556 [Viper] 0 d 1045c557 82C557 [Viper-M] 0 d 1045c558 82C558 [Viper-M ISA+IDE] 0 d 1045c567 82C750 [Vendetta], device 0 0 d 1045c568 82C750 [Vendetta], device 1 0 d 1045c569 82C579 [Viper XPress+ Chipset] 0 d 1045c621 82C621 [Viper-M/N+] 0 d 1045c700 82C700 [FireStar] 0 d 1045c701 82C701 [FireStar Plus] 0 d 1045c814 82C814 [Firebridge 1] 0 d 1045c822 82C822 0 d 1045c824 82C824 0 d 1045c825 82C825 [Firebridge 2] 0 d 1045c832 82C832 0 d 1045c861 82C861 0 d 1045c895 82C895 0 d 1045c935 EV1935 ECTIVA MachOne PCIAudio 0 d 1045d568 82C825 [Firebridge 2] 0 d 1045d721 IDE [FireStar] 0 v 1046 IPC Corporation, Ltd. 0 v 1047 Genoa Systems Corp 0 v 1048 Elsa AG 0 d 10480c60 Gladiac MX 0 d 10480d22 Quadro4 900XGL [ELSA GLoria4 900XGL] 0 d 10481000 QuickStep 1000 0 d 10483000 QuickStep 3000 0 d 10488901 Gloria XL 0 v 1049 Fountain Technologies, Inc. 0 v 104a STMicroelectronics 0 # nee SGS Thomson Microelectronics d 104a0008 STG 2000X 0 d 104a0009 STG 1764X 0 d 104a0010 STG4000 [3D Prophet Kyro Series] 0 d 104a0209 STPC Consumer/Industrial North- and Southbridge 0 d 104a020a STPC Atlas/ConsumerS/Consumer IIA Northbridge 0 d 104a0210 STPC Atlas ISA Bridge 0 From d 104a021a STPC Consumer S Southbridge 0 d 104a021b STPC Consumer IIA Southbridge 0 d 104a0500 ST70137 [Unicorn] ADSL DMT Transceiver 0 d 104a0564 STPC Client Northbridge 0 d 104a0981 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 104a1746 STG 1764X 0 d 104a2774 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 104a3520 MPEG-II decoder card 0 d 104a55cc STPC Client Southbridge 0 v 104b BusLogic 0 d 104b0140 BT-946C (old) [multimaster 01] 0 d 104b1040 BT-946C (BA80C30) [MultiMaster 10] 0 d 104b8130 Flashpoint LT 0 v 104c Texas Instruments 0 d 104c0500 100 MBit LAN Controller 0 d 104c0508 TMS380C2X Compressor Interface 0 d 104c1000 Eagle i/f AS 0 d 104c104c PCI1510 PC card Cardbus Controller 0 d 104c3d04 TVP4010 [Permedia] 0 d 104c3d07 TVP4020 [Permedia 2] 0 s 104c3d0710114d10 Comet 0 s 104c3d071040000f AccelStar II 0 s 104c3d0710400011 AccelStar II 0 s 104c3d0710480a31 WINNER 2000 0 s 104c3d0710480a32 GLoria Synergy 0 s 104c3d0710480a35 GLoria Synergy 0 s 104c3d07107d2633 WinFast 3D L2300 0 s 104c3d0710920127 FIRE GL 1000 PRO 0 s 104c3d0710920136 FIRE GL 1000 PRO 0 s 104c3d0710920141 FIRE GL 1000 PRO 0 s 104c3d0710920146 FIRE GL 1000 PRO 0 s 104c3d0710920148 FIRE GL 1000 PRO 0 s 104c3d0710920149 FIRE GL 1000 PRO 0 s 104c3d0710920152 FIRE GL 1000 PRO 0 s 104c3d0710920154 FIRE GL 1000 PRO 0 s 104c3d0710920155 FIRE GL 1000 PRO 0 s 104c3d0710920156 FIRE GL 1000 PRO 0 s 104c3d0710920157 FIRE GL 1000 PRO 0 s 104c3d0710973d01 Jeronimo Pro 0 s 104c3d071102100f Graphics Blaster Extreme 0 s 104c3d073d3d0100 Reference Permedia 2 3D 0 d 104c8000 PCILynx/PCILynx2 IEEE 1394 Link Layer Controller 0 s 104c8000e4bf1010 CF1-1-SNARE 0 s 104c8000e4bf1020 CF1-2-SNARE 0 d 104c8009 FireWire Controller 0 s 104c8009104d8032 8032 OHCI i.LINK (IEEE 1394) Controller 0 d 104c8017 PCI4410 FireWire Controller 0 d 104c8019 TSB12LV23 IEEE-1394 Controller 0 s 104c801911bd000a Studio DV500-1394 0 s 104c801911bd000e Studio DV 0 s 104c8019e4bf1010 CF2-1-CYMBAL 0 d 104c8020 TSB12LV26 IEEE-1394 Controller (Link) 0 d 104c8021 TSB43AA22 IEEE-1394 Controller (PHY/Link Integrated) 0 s 104c8021104d80df Vaio PCG-FX403 0 s 104c8021104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 d 104c8022 TSB43AB22 IEEE-1394a-2000 Controller (PHY/Link) 0 d 104c8023 TSB43AB22/A IEEE-1394a-2000 Controller (PHY/Link) 0 d 104c8024 TSB43AB23 IEEE-1394a-2000 Controller (PHY/Link) 0 d 104c8025 TSB82AA2 IEEE-1394b Link Layer Controller 0 s 104c802555aa55aa FireWire 800 PCI Card 0 d 104c8026 TSB43AB21 IEEE-1394a-2000 Controller (PHY/Link) 0 d 104c8027 PCI4451 IEEE-1394 Controller 0 s 104c8027102800e6 PCI4451 IEEE-1394 Controller (Dell Inspiron 8100) 0 d 104c8029 PCI4510 IEEE-1394 Controller 0 s 104c802910280163 Latitude D505 0 s 104c802910718160 MIM2900 0 d 104c802e PCI7x20 1394a-2000 OHCI Two-Port PHY/Link-Layer Controller 0 d 104c8201 PCI1620 Firmware Loading Function 0 d 104c8400 ACX 100 22Mbps Wireless Interface 0 s 104c840000fc16ec U.S. Robotics 22 Mbps Wireless PC Card (model 2210) 0 s 104c840000fd16ec U.S. Robotics 22Mbps Wireless PCI Adapter (model 2216) 0 s 104c840011863b00 DWL-650+ PC Card cardbus 22Mbs Wireless Adapter [AirPlus] 0 s 104c840011863b01 DWL-520+ 22Mbps PCI Wireless Adapter 0 d 104c8401 ACX 100 22Mbps Wireless Interface 0 d 104c9000 Wireless Interface (of unknown type) 0 OK, this info is almost useless as is, but at least it's known that it's a wireless card. More info requested from reporter (whi d 104c9066 ACX 111 54Mbps Wireless Interface 0 d 104ca001 TDC1570 0 d 104ca100 TDC1561 0 d 104ca102 TNETA1575 HyperSAR Plus w/PCI Host i/f & UTOPIA i/f 0 d 104ca106 TMS320C6205 Fixed Point DSP 0 s 104ca106175c5000 ASI50xx Audio Adapter 0 s 104ca106175c8700 ASI87xx Radio Tuner card 0 d 104cac10 PCI1050 0 d 104cac11 PCI1053 0 d 104cac12 PCI1130 0 d 104cac13 PCI1031 0 d 104cac15 PCI1131 0 d 104cac16 PCI1250 0 s 104cac1610140092 ThinkPad 600 0 d 104cac17 PCI1220 0 d 104cac18 PCI1260 0 d 104cac19 PCI1221 0 d 104cac1a PCI1210 0 d 104cac1b PCI1450 0 s 104cac1b0e11b113 Armada M700 0 d 104cac1c PCI1225 0 s 104cac1c0e11b121 Armada E500 0 s 104cac1c10280088 Dell Computer Corporation Latitude CPi A400XT 0 d 104cac1d PCI1251A 0 d 104cac1e PCI1211 0 d 104cac1f PCI1251B 0 d 104cac20 TI 2030 0 d 104cac21 PCI2031 0 d 104cac22 PCI2032 PCI Docking Bridge 0 d 104cac23 PCI2250 PCI-to-PCI Bridge 0 d 104cac28 PCI2050 PCI-to-PCI Bridge 0 d 104cac30 PCI1260 PC card Cardbus Controller 0 d 104cac40 PCI4450 PC card Cardbus Controller 0 d 104cac41 PCI4410 PC card Cardbus Controller 0 d 104cac42 PCI4451 PC card Cardbus Controller 0 s 104cac42102800e6 PCI4451 PC card CardBus Controller (Dell Inspiron 8100) 0 d 104cac44 PCI4510 PC card Cardbus Controller 0 s 104cac4410280163 Latitude D505 0 s 104cac4410718160 MIM2000 0 d 104cac46 PCI4520 PC card Cardbus Controller 0 d 104cac50 PCI1410 PC card Cardbus Controller 0 d 104cac51 PCI1420 0 s 104cac511014023b ThinkPad T23 (2647-4MG) 0 s 104cac51102800b1 Latitude C600 0 s 104cac511028012a Latitude C640 0 s 104cac51103380cd Versa Note VXi 0 s 104cac5110cf1095 Lifebook C6155 0 s 104cac51e4bf1000 CP2-2-HIPHOP 0 d 104cac52 PCI1451 PC card Cardbus Controller 0 d 104cac53 PCI1421 PC card Cardbus Controller 0 d 104cac54 PCI1620 PC Card Controller 0 d 104cac55 PCI1520 PC card Cardbus Controller 0 s 104cac5510140512 ThinkPad T30/T40 0 d 104cac56 PCI1510 PC card Cardbus Controller 0 s 104cac5610140528 ThinkPad R40e (2684-HVG) Cardbus Controller 0 d 104cac60 PCI2040 PCI to DSP Bridge Controller 0 s 104cac60175c5100 ASI51xx Audio Adapter 0 s 104cac60175c6100 ASI61xx Audio Adapter 0 s 104cac60175c6200 ASI62xx Audio Adapter 0 d 104cac8d PCI 7620 0 d 104cac8e PCI7420 CardBus Controller 0 d 104cac8f PCI7420/PCI7620 Dual Socket CardBus and Smart Card Cont. w/ 1394a-2000 OHCI Two-Port PHY/Link-Layer Cont. and SD/MS-Pro Sockets 0 d 104cfe00 FireWire Host Controller 0 d 104cfe03 12C01A FireWire Host Controller 0 v 104d Sony Corporation 0 d 104d8009 CXD1947Q i.LINK Controller 0 d 104d8039 CXD3222 i.LINK Controller 0 d 104d8056 Rockwell HCF 56K modem 0 d 104d808a Memory Stick Controller 0 v 104e Oak Technology, Inc 0 d 104e0017 OTI-64017 0 d 104e0107 OTI-107 [Spitfire] 0 d 104e0109 Video Adapter 0 d 104e0111 OTI-64111 [Spitfire] 0 d 104e0217 OTI-64217 0 d 104e0317 OTI-64317 0 v 104f Co-time Computer Ltd 0 v 1050 Winbond Electronics Corp 0 d 10500000 NE2000 0 d 10500001 W83769F 0 d 10500105 W82C105 0 d 10500840 W89C840 0 s 1050084010500001 W89C840 Ethernet Adapter 0 s 1050084010500840 W89C840 Ethernet Adapter 0 d 10500940 W89C940 0 d 10505a5a W89C940F 0 d 10506692 W6692 0 d 10509921 W99200F MPEG-1 Video Encoder 0 d 10509922 W99200F/W9922PF MPEG-1/2 Video Encoder 0 d 10509970 W9970CF 0 v 1051 Anigma, Inc. 0 v 1052 ?Young Micro Systems 0 v 1053 Young Micro Systems 0 v 1054 Hitachi, Ltd 0 v 1055 Efar Microsystems 0 d 10559130 SLC90E66 [Victory66] IDE 0 d 10559460 SLC90E66 [Victory66] ISA 0 d 10559462 SLC90E66 [Victory66] USB 0 d 10559463 SLC90E66 [Victory66] ACPI 0 v 1056 ICL 0 v 1057 Motorola 0 Motorola made a mistake and used 1507 instead of 1057 in some chips. Please look at the 1507 entry as well when updating this. d 10570001 MPC105 [Eagle] 0 d 10570002 MPC106 [Grackle] 0 d 10570003 MPC8240 [Kahlua] 0 d 10570004 MPC107 0 d 10570006 MPC8245 [Unity] 0 d 10570008 MPC8540 0 d 10570009 MPC8560 0 d 10570100 MC145575 [HFC-PCI] 0 d 10570431 KTI829c 100VG 0 d 10571801 DSP56301 Digital Signal Processor 0 s 1057180114fb0101 Transas Radar Imitator Board [RIM] 0 s 1057180114fb0102 Transas Radar Imitator Board [RIM-2] 0 s 1057180114fb0202 Transas Radar Integrator Board [RIB-2] 0 s 1057180114fb0611 1 channel CAN bus Controller [CanPci-1] 0 s 1057180114fb0612 2 channels CAN bus Controller [CanPci-2] 0 s 1057180114fb0613 3 channels CAN bus Controller [CanPci-3] 0 s 1057180114fb0614 4 channels CAN bus Controller [CanPci-4] 0 s 1057180114fb0621 1 channel CAN bus Controller [CanPci2-1] 0 s 1057180114fb0622 2 channels CAN bus Controller [CanPci2-2] 0 s 1057180114fb0810 Transas VTS Radar Integrator Board [RIB-4] 0 s 10571801175c4200 ASI4215 Audio Adapter 0 s 10571801175c4300 ASI43xx Audio Adapter 0 s 10571801175c4400 ASI4401 Audio Adapter 0 s 10571801ecc00030 Layla 0 d 105718c0 MPC8265A/MPC8266 0 d 105718c1 MPC8271/MPC8272 0 d 10574801 Raven 0 d 10574802 Falcon 0 d 10574803 Hawk 0 d 10574806 CPX8216 0 d 10574d68 20268 0 d 10575600 SM56 PCI Modem 0 s 1057560010570300 SM56 PCI Speakerphone Modem 0 s 1057560010570301 SM56 PCI Voice Modem 0 s 1057560010570302 SM56 PCI Fax Modem 0 s 1057560010575600 SM56 PCI Voice modem 0 s 1057560013d20300 SM56 PCI Speakerphone Modem 0 s 1057560013d20301 SM56 PCI Voice modem 0 s 1057560013d20302 SM56 PCI Fax Modem 0 s 1057560014360300 SM56 PCI Speakerphone Modem 0 s 1057560014360301 SM56 PCI Voice modem 0 s 1057560014360302 SM56 PCI Fax Modem 0 s 10575600144f100c SM56 PCI Fax Modem 0 s 1057560014940300 SM56 PCI Speakerphone Modem 0 s 1057560014940301 SM56 PCI Voice modem 0 s 1057560014c80300 SM56 PCI Speakerphone Modem 0 s 1057560014c80302 SM56 PCI Fax Modem 0 s 1057560016680300 SM56 PCI Speakerphone Modem 0 s 1057560016680302 SM56 PCI Fax Modem 0 d 10575803 MPC5200 0 d 10576400 MPC190 Security Processor (S1 family, encryption) 0 d 10576405 MPC184 Security Processor (S1 family) 0 v 1058 Electronics & Telecommunications RSH 0 v 1059 Teknor Industrial Computers Inc 0 v 105a Promise Technology, Inc. 0 d 105a0d30 PDC20265 (FastTrak100 Lite/Ultra100) 0 more correct description from promise linux sources s 105a0d30105a4d33 Ultra100 0 d 105a0d38 20263 0 s 105a0d38105a4d39 Fasttrak66 0 d 105a1275 20275 0 d 105a3318 PDC20318 (SATA150 TX4) 0 d 105a3319 PDC20319 (FastTrak S150 TX4) 0 s 105a331980863427 S875WP1-E mainboard 0 d 105a3371 PDC20371 (FastTrak S150 TX2plus) 0 d 105a3373 PDC20378 (FastTrak 378/SATA 378) 0 s 105a3373104380f5 PC-DL Deluxe motherboard 0 s 105a33731462702e K8T NEO FIS2R motherboard 0 d 105a3375 PDC20375 (SATA150 TX2plus) 0 d 105a3376 PDC20376 (FastTrak 376) 0 s 105a33761043809e A7V8X motherboard 0 d 105a3574 PDC20579 SATAII 150 IDE Controller 0 d 105a3d18 PDC20518 SATAII 150 IDE Controller 0 d 105a4d30 PDC20267 (FastTrak100/Ultra100) 0 s 105a4d30105a4d33 Ultra100 0 s 105a4d30105a4d39 FastTrak100 0 d 105a4d33 20246 0 s 105a4d33105a4d33 20246 IDE Controller 0 d 105a4d38 PDC20262 (FastTrak66/Ultra66) 0 s 105a4d38105a4d30 Ultra Device on SuperTrak 0 s 105a4d38105a4d33 Ultra66 0 s 105a4d38105a4d39 FastTrak66 0 d 105a4d68 PDC20268 (Ultra100 TX2) 0 s 105a4d68105a4d68 Ultra100TX2 0 d 105a4d69 20269 0 s 105a4d69105a4d68 Ultra133TX2 0 d 105a5275 PDC20276 (MBFastTrak133 Lite) 0 s 105a5275105a0275 SuperTrak SX6000 IDE 0 s 105a5275105a1275 MBFastTrak133 Lite (tm) Controller (RAID mode) 0 s 105a52751458b001 MBUltra 133 0 d 105a5300 DC5300 0 d 105a6268 PDC20270 (FastTrak100 LP/TX2/TX4) 0 s 105a6268105a4d68 FastTrak100 TX2 0 d 105a6269 PDC20271 (FastTrak TX2000) 0 s 105a6269105a6269 FastTrak TX2/TX2000 0 d 105a6621 PDC20621 (FastTrak S150 SX4/FastTrak SX4000 lite) 0 d 105a6622 PDC20621 [SATA150 SX4] 4 Channel IDE RAID Controller 0 d 105a6626 PDC20618 (Ultra 618) 0 d 105a6629 PDC20619 (FastTrak TX4000) 0 d 105a7275 PDC20277 (SBFastTrak133 Lite) 0 v 105b Foxconn International, Inc. 0 v 105c Wipro Infotech Limited 0 v 105d Number 9 Computer Company 0 d 105d2309 Imagine 128 0 d 105d2339 Imagine 128-II 0 s 105d2339105d0000 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0001 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0002 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0003 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0004 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0005 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0006 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0007 Imagine 128 series 2 4Mb VRAM 0 s 105d2339105d0008 Imagine 128 series 2e 4Mb DRAM 0 s 105d2339105d0009 Imagine 128 series 2e 4Mb DRAM 0 s 105d2339105d000a Imagine 128 series 2 8Mb VRAM 0 s 105d2339105d000b Imagine 128 series 2 8Mb H-VRAM 0 s 105d233911a4000a Barco Metheus 5 Megapixel 0 s 105d233913cc0000 Barco Metheus 5 Megapixel 0 s 105d233913cc0004 Barco Metheus 5 Megapixel 0 s 105d233913cc0005 Barco Metheus 5 Megapixel 0 s 105d233913cc0006 Barco Metheus 5 Megapixel 0 s 105d233913cc0008 Barco Metheus 5 Megapixel 0 s 105d233913cc0009 Barco Metheus 5 Megapixel 0 s 105d233913cc000a Barco Metheus 5 Megapixel 0 s 105d233913cc000c Barco Metheus 5 Megapixel 0 d 105d493d Imagine 128 T2R [Ticket to Ride] 0 s 105d493d11a4000a Barco Metheus 5 Megapixel, Dual Head 0 s 105d493d11a4000b Barco Metheus 5 Megapixel, Dual Head 0 s 105d493d13cc0002 Barco Metheus 4 Megapixel, Dual Head 0 s 105d493d13cc0003 Barco Metheus 5 Megapixel, Dual Head 0 s 105d493d13cc0007 Barco Metheus 5 Megapixel, Dual Head 0 s 105d493d13cc0008 Barco Metheus 5 Megapixel, Dual Head 0 s 105d493d13cc0009 Barco Metheus 5 Megapixel, Dual Head 0 s 105d493d13cc000a Barco Metheus 5 Megapixel, Dual Head 0 d 105d5348 Revolution 4 0 s 105d5348105d0037 Revolution IV-FP AGP (For SGI 1600SW) 0 v 105e Vtech Computers Ltd 0 v 105f Infotronic America Inc 0 v 1060 United Microelectronics [UMC] 0 d 10600001 UM82C881 0 d 10600002 UM82C886 0 d 10600101 UM8673F 0 d 10600881 UM8881 0 d 10600886 UM8886F 0 d 10600891 UM8891A 0 d 10601001 UM886A 0 d 1060673a UM8886BF 0 d 1060673b EIDE Master/DMA 0 d 10608710 UM8710 0 d 1060886a UM8886A 0 d 10608881 UM8881F 0 d 10608886 UM8886F 0 d 1060888a UM8886A 0 d 10608891 UM8891A 0 d 10609017 UM9017F 0 d 10609018 UM9018 0 d 10609026 UM9026 0 d 1060e881 UM8881N 0 d 1060e886 UM8886N 0 d 1060e88a UM8886N 0 d 1060e891 UM8891N 0 v 1061 I.I.T. 0 d 10610001 AGX016 0 d 10610002 IIT3204/3501 0 v 1062 Maspar Computer Corp 0 v 1063 Ocean Office Automation 0 v 1064 Alcatel 0 v 1065 Texas Microsystems 0 v 1066 PicoPower Technology 0 d 10660000 PT80C826 0 d 10660001 PT86C521 [Vesuvius v1] Host Bridge 0 d 10660002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Master 0 d 10660003 PT86C524 [Nile] PCI-to-PCI Bridge 0 d 10660004 PT86C525 [Nile-II] PCI-to-PCI Bridge 0 d 10660005 National PC87550 System Controller 0 d 10668002 PT86C523 [Vesuvius v3] PCI-ISA Bridge Slave 0 v 1067 Mitsubishi Electric 0 d 10670301 AccelGraphics AccelECLIPSE 0 d 10670304 AccelGALAXY A2100 [OEM Evans & Sutherland] 0 d 10670308 Tornado 3000 [OEM Evans & Sutherland] 0 d 10671002 VG500 [VolumePro Volume Rendering Accelerator] 0 v 1068 Diversified Technology 0 v 1069 Mylex Corporation 0 d 10690001 DAC960P 0 d 10690002 DAC960PD 0 d 10690010 DAC960PG 0 d 10690020 DAC960LA 0 d 10690050 AcceleRAID 352/170/160 support Device 0 d 1069b166 Gemstone chipset SCSI controller 0 s 1069b16610140242 iSeries 2872 DASD IOA 0 s 1069b16610140266 Dual Channel PCI-X U320 SCSI Adapter 0 s 1069b16610140278 Dual Channel PCI-X U320 SCSI RAID Adapter 0 d 1069ba55 eXtremeRAID 1100 support Device 0 d 1069ba56 eXtremeRAID 2000/3000 support Device 0 v 106a Aten Research Inc 0 v 106b Apple Computer Inc. 0 d 106b0001 Bandit PowerPC host bridge 0 d 106b0002 Grand Central I/O 0 d 106b0003 Control Video 0 d 106b0004 PlanB Video-In 0 d 106b0007 O'Hare I/O 0 d 106b000e Hydra Mac I/O 0 d 106b0010 Heathrow Mac I/O 0 d 106b0017 Paddington Mac I/O 0 d 106b0018 UniNorth FireWire 0 d 106b0019 KeyLargo USB 0 d 106b001e UniNorth Internal PCI 0 d 106b001f UniNorth PCI 0 d 106b0020 UniNorth AGP 0 d 106b0021 UniNorth GMAC (Sun GEM) 0 d 106b0022 KeyLargo Mac I/O 0 d 106b0024 UniNorth/Pangea GMAC (Sun GEM) 0 d 106b0025 KeyLargo/Pangea Mac I/O 0 d 106b0026 KeyLargo/Pangea USB 0 d 106b0027 UniNorth/Pangea AGP 0 d 106b0028 UniNorth/Pangea PCI 0 d 106b0029 UniNorth/Pangea Internal PCI 0 d 106b002d UniNorth 1.5 AGP 0 d 106b002e UniNorth 1.5 PCI 0 d 106b002f UniNorth 1.5 Internal PCI 0 d 106b0030 UniNorth/Pangea FireWire 0 d 106b0031 UniNorth 2 FireWire 0 d 106b0032 UniNorth 2 GMAC (Sun GEM) 0 d 106b0033 UniNorth 2 ATA/100 0 d 106b0034 UniNorth 2 AGP 0 d 106b0035 UniNorth 2 PCI 0 d 106b0036 UniNorth 2 Internal PCI 0 d 106b003b UniNorth/Intrepid ATA/100 0 d 106b003e KeyLargo/Intrepid Mac I/O 0 d 106b003f KeyLargo/Intrepid USB 0 d 106b0040 K2 KeyLargo USB 0 d 106b0041 K2 KeyLargo Mac/IO 0 d 106b0042 K2 FireWire 0 d 106b0043 K2 ATA/100 0 d 106b0045 K2 HT-PCI Bridge 0 d 106b0046 K2 HT-PCI Bridge 0 d 106b0047 K2 HT-PCI Bridge 0 d 106b0048 K2 HT-PCI Bridge 0 d 106b0049 K2 HT-PCI Bridge 0 d 106b004b U3 AGP 0 d 106b004c K2 GMAC (Sun GEM) 0 d 106b004f Shasta Mac I/O 0 d 106b0050 Shasta IDE 0 d 106b0051 Shasta (Sun GEM) 0 d 106b0052 Shasta Firewire 0 d 106b0053 Shasta PCI Bridge 0 d 106b0054 Shasta PCI Bridge 0 d 106b0055 Shasta PCI Bridge 0 d 106b0058 U3L AGP Bridge 0 d 106b1645 Tigon3 Gigabit Ethernet NIC (BCM5701) 0 v 106c Hynix Semiconductor 0 d 106c8801 Dual Pentium ISA/PCI Motherboard 0 d 106c8802 PowerPC ISA/PCI Motherboard 0 d 106c8803 Dual Window Graphics Accelerator 0 d 106c8804 LAN Controller 0 d 106c8805 100-BaseT LAN 0 v 106d Sequent Computer Systems 0 v 106e DFI, Inc 0 v 106f City Gate Development Ltd 0 v 1070 Daewoo Telecom Ltd 0 v 1071 Mitac 0 d 10718160 Mitac 8060B Mobile Platform 0 v 1072 GIT Co Ltd 0 v 1073 Yamaha Corporation 0 d 10730001 3D GUI Accelerator 0 d 10730002 YGV615 [RPA3 3D-Graphics Controller] 0 d 10730003 YMF-740 0 d 10730004 YMF-724 0 s 1073000410730004 YMF724-Based PCI Audio Adapter 0 d 10730005 DS1 Audio 0 s 1073000510730005 DS-XG PCI Audio CODEC 0 d 10730006 DS1 Audio 0 d 10730008 DS1 Audio 0 s 1073000810730008 DS-XG PCI Audio CODEC 0 d 1073000a DS1L Audio 0 s 1073000a10730004 DS-XG PCI Audio CODEC 0 s 1073000a1073000a DS-XG PCI Audio CODEC 0 d 1073000c YMF-740C [DS-1L Audio Controller] 0 s 1073000c107a000c DS-XG PCI Audio CODEC 0 d 1073000d YMF-724F [DS-1 Audio Controller] 0 s 1073000d1073000d DS-XG PCI Audio CODEC 0 d 10730010 YMF-744B [DS-1S Audio Controller] 0 s 1073001010730006 DS-XG PCI Audio CODEC 0 s 1073001010730010 DS-XG PCI Audio CODEC 0 d 10730012 YMF-754 [DS-1E Audio Controller] 0 s 1073001210730012 DS-XG PCI Audio Codec 0 d 10730020 DS-1 Audio 0 d 10732000 DS2416 Digital Mixing Card 0 s 1073200010732000 DS2416 Digital Mixing Card 0 v 1074 NexGen Microsystems 0 d 10744e78 82c500/1 0 v 1075 Advanced Integrations Research 0 v 1076 Chaintech Computer Co. Ltd 0 v 1077 QLogic Corp. 0 d 10771016 ISP10160 Single Channel Ultra3 SCSI Processor 0 d 10771020 ISP1020 Fast-wide SCSI 0 d 10771022 ISP1022 Fast-wide SCSI 0 d 10771080 ISP1080 SCSI Host Adapter 0 d 10771216 ISP12160 Dual Channel Ultra3 SCSI Processor 0 s 10771216101e8471 QLA12160 on AMI MegaRAID 0 s 10771216101e8493 QLA12160 on AMI MegaRAID 0 d 10771240 ISP1240 SCSI Host Adapter 0 d 10771280 ISP1280 SCSI Host Adapter 0 d 10772020 ISP2020A Fast!SCSI Basic Adapter 0 d 10772100 QLA2100 64-bit Fibre Channel Adapter 0 s 1077210010770001 QLA2100 64-bit Fibre Channel Adapter 0 d 10772200 QLA2200 64-bit Fibre Channel Adapter 0 s 1077220010770002 QLA2200 0 d 10772300 QLA2300 64-bit Fibre Channel Adapter 0 d 10772312 QLA2312 Fibre Channel Adapter 0 v 1078 Cyrix Corporation 0 d 10780000 5510 [Grappa] 0 d 10780001 PCI Master 0 d 10780002 5520 [Cognac] 0 d 10780100 5530 Legacy [Kahlua] 0 d 10780101 5530 SMI [Kahlua] 0 d 10780102 5530 IDE [Kahlua] 0 d 10780103 5530 Audio [Kahlua] 0 d 10780104 5530 Video [Kahlua] 0 d 10780400 ZFMicro PCI Bridge 0 d 10780401 ZFMicro Chipset SMI 0 d 10780402 ZFMicro Chipset IDE 0 d 10780403 ZFMicro Expansion Bus 0 v 1079 I-Bus 0 v 107a NetWorth 0 v 107b Gateway 2000 0 v 107c LG Electronics [Lucky Goldstar Co. Ltd] 0 v 107d LeadTek Research Inc. 0 d 107d0000 P86C850 0 d 107d2134 WinFast 3D S320 II 0 d 107d2971 [GeForce FX 5900] WinFast A350 TDH MyViVo 0 v 107e Interphase Corporation 0 d 107e0001 5515 ATM Adapter [Flipper] 0 d 107e0002 100 VG AnyLan Controller 0 d 107e0004 5526 Fibre Channel Host Adapter 0 d 107e0005 x526 Fibre Channel Host Adapter 0 d 107e0008 5525/5575 ATM Adapter (155 Mbit) [Atlantic] 0 d 107e9003 5535-4P-BRI-ST 0 d 107e9007 5535-4P-BRI-U 0 d 107e9008 5535-1P-SR 0 d 107e900c 5535-1P-SR-ST 0 d 107e900e 5535-1P-SR-U 0 d 107e9011 5535-1P-PRI 0 d 107e9013 5535-2P-PRI 0 d 107e9023 5536-4P-BRI-ST 0 d 107e9027 5536-4P-BRI-U 0 d 107e9031 5536-1P-PRI 0 d 107e9033 5536-2P-PRI 0 v 107f Data Technology Corporation 0 d 107f0802 SL82C105 0 v 1080 Contaq Microsystems 0 d 10800600 82C599 0 d 1080c691 Cypress CY82C691 0 d 1080c693 82c693 0 v 1081 Supermac Technology 0 d 10810d47 Radius PCI to NuBUS Bridge 0 v 1082 EFA Corporation of America 0 v 1083 Forex Computer Corporation 0 d 10830001 FR710 0 v 1084 Parador 0 v 1085 Tulip Computers Int.B.V. 0 v 1086 J. Bond Computer Systems 0 v 1087 Cache Computer 0 v 1088 Microcomputer Systems (M) Son 0 v 1089 Data General Corporation 0 v 108a SBS Technologies 0 Formerly Bit3 Computer Corp. d 108a0001 VME Bridge Model 617 0 d 108a0010 VME Bridge Model 618 0 d 108a0040 dataBLIZZARD 0 d 108a3000 VME Bridge Model 2706 0 v 108c Oakleigh Systems Inc. 0 v 108d Olicom 0 d 108d0001 Token-Ring 16/4 PCI Adapter (3136/3137) 0 d 108d0002 16/4 Token Ring 0 d 108d0004 RapidFire 3139 Token-Ring 16/4 PCI Adapter 0 s 108d0004108d0004 OC-3139/3140 RapidFire Token-Ring 16/4 Adapter 0 d 108d0005 GoCard 3250 Token-Ring 16/4 CardBus PC Card 0 d 108d0006 OC-3530 RapidFire Token-Ring 100 0 d 108d0007 RapidFire 3141 Token-Ring 16/4 PCI Fiber Adapter 0 s 108d0007108d0007 OC-3141 RapidFire Token-Ring 16/4 Adapter 0 d 108d0008 RapidFire 3540 HSTR 100/16/4 PCI Adapter 0 s 108d0008108d0008 OC-3540 RapidFire HSTR 100/16/4 Adapter 0 d 108d0011 OC-2315 0 d 108d0012 OC-2325 0 d 108d0013 OC-2183/2185 0 d 108d0014 OC-2326 0 d 108d0019 OC-2327/2250 10/100 Ethernet Adapter 0 s 108d0019108d0016 OC-2327 Rapidfire 10/100 Ethernet Adapter 0 s 108d0019108d0017 OC-2250 GoCard 10/100 Ethernet Adapter 0 d 108d0021 OC-6151/6152 [RapidFire ATM 155] 0 d 108d0022 ATM Adapter 0 v 108e Sun Microsystems Computer Corp. 0 d 108e0001 EBUS 0 d 108e1000 EBUS 0 d 108e1001 Happy Meal 0 d 108e1100 RIO EBUS 0 d 108e1101 RIO GEM 0 d 108e1102 RIO 1394 0 d 108e1103 RIO USB 0 d 108e2bad GEM 0 d 108e5000 Simba Advanced PCI Bridge 0 d 108e5043 SunPCI Co-processor 0 d 108e8000 Psycho PCI Bus Module 0 d 108e8001 Schizo PCI Bus Module 0 d 108ea000 Ultra IIi 0 d 108ea001 Ultra IIe 0 d 108ea801 Tomatillo PCI Bus Module 0 d 108eabba Cassini 10/100/1000 0 v 108f Systemsoft 0 v 1090 Encore Computer Corporation 0 v 1091 Intergraph Corporation 0 d 10910020 3D graphics processor 0 d 10910021 3D graphics processor w/Texturing 0 d 10910040 3D graphics frame buffer 0 d 10910041 3D graphics frame buffer 0 d 10910060 Proprietary bus bridge 0 d 109100e4 Powerstorm 4D50T 0 d 10910720 Motion JPEG codec 0 d 109107a0 Sun Expert3D-Lite Graphics Accelerator 0 d 10911091 Sun Expert3D Graphics Accelerator 0 v 1092 Diamond Multimedia Systems 0 d 109200a0 Speedstar Pro SE 0 d 109200a8 Speedstar 64 0 d 10920550 Viper V550 0 d 109208d4 Supra 2260 Modem 0 d 1092094c SupraExpress 56i Pro 0 d 10921092 Viper V330 0 d 10926120 Maximum DVD 0 d 10928810 Stealth SE 0 d 10928811 Stealth 64/SE 0 d 10928880 Stealth 0 d 10928881 Stealth 0 d 109288b0 Stealth 64 0 d 109288b1 Stealth 64 0 d 109288c0 Stealth 64 0 d 109288c1 Stealth 64 0 d 109288d0 Stealth 64 0 d 109288d1 Stealth 64 0 d 109288f0 Stealth 64 0 d 109288f1 Stealth 64 0 d 10929999 DMD-I0928-1 "Monster sound" sound chip 0 v 1093 National Instruments 0 d 10930160 PCI-DIO-96 0 d 10930162 PCI-MIO-16XE-50 0 d 10931170 PCI-MIO-16XE-10 0 d 10931180 PCI-MIO-16E-1 0 d 10931190 PCI-MIO-16E-4 0 d 10931330 PCI-6031E 0 d 10931350 PCI-6071E 0 d 109314e0 PCI-6110 0 d 109314f0 PCI-6111 0 d 109317d0 PCI-6503 0 d 10931870 PCI-6713 0 d 10931880 PCI-6711 0 d 109318b0 PCI-6052E 0 d 10932410 PCI-6733 0 d 10932890 PCI-6036E 0 d 10932a60 PCI-6023E 0 d 10932a70 PCI-6024E 0 d 10932a80 PCI-6025E 0 d 10932c80 PCI-6035E 0 d 10932ca0 PCI-6034E 0 d 1093b001 IMAQ-PCI-1408 0 d 1093b011 IMAQ-PXI-1408 0 d 1093b021 IMAQ-PCI-1424 0 d 1093b031 IMAQ-PCI-1413 0 d 1093b041 IMAQ-PCI-1407 0 d 1093b051 IMAQ-PXI-1407 0 d 1093b061 IMAQ-PCI-1411 0 d 1093b071 IMAQ-PCI-1422 0 d 1093b081 IMAQ-PXI-1422 0 d 1093b091 IMAQ-PXI-1411 0 d 1093c801 PCI-GPIB 0 d 1093c831 PCI-GPIB bridge 0 v 1094 First International Computers [FIC] 0 v 1095 Silicon Image, Inc. (formerly CMD Technology Inc) 0 d 10950240 Adaptec AAR-1210SA SATA HostRAID Controller 0 d 10950640 PCI0640 0 d 10950643 PCI0643 0 d 10950646 PCI0646 0 d 10950647 PCI0647 0 d 10950648 PCI0648 0 d 10950649 SiI 0649 Ultra ATA/100 PCI to ATA Host Controller 0 s 109506490e11005d Integrated Ultra ATA-100 Dual Channel Controller 0 s 109506490e11007e Integrated Ultra ATA-100 IDE RAID Controller 0 s 10950649101e0649 AMI MegaRAID IDE 100 Controller 0 d 10950650 PBC0650A 0 d 10950670 USB0670 0 s 1095067010950670 USB0670 0 d 10950673 USB0673 0 d 10950680 PCI0680 Ultra ATA-133 Host Controller 0 s 1095068010953680 Winic W-680 (Silicon Image 680 based) 0 d 10953112 SiI 3112 [SATALink/SATARaid] Serial ATA Controller 0 s 1095311210953112 SiI 3112 SATALink Controller 0 s 1095311210956112 SiI 3112 SATARaid Controller 0 d 10953114 SiI 3114 [SATALink/SATARaid] Serial ATA Controller 0 s 1095311410953114 SiI 3114 SATALink Controller 0 s 1095311410956114 SiI 3114 SATARaid Controller 0 d 10953124 SiI 3124 PCI-X Serial ATA Controller 0 s 1095312410953124 SiI 3124 PCI-X Serial ATA Controller 0 d 10953512 SiI 3512 [SATALink/SATARaid] Serial ATA Controller 0 s 1095351210953512 SiI 3512 SATALink Controller 0 s 1095351210956512 SiI 3512 SATARaid Controller 0 v 1096 Alacron 0 v 1097 Appian Technology 0 v 1098 Quantum Designs (H.K.) Ltd 0 d 10980001 QD-8500 0 d 10980002 QD-8580 0 v 1099 Samsung Electronics Co., Ltd 0 v 109a Packard Bell 0 v 109b Gemlight Computer Ltd. 0 v 109c Megachips Corporation 0 v 109d Zida Technologies Ltd. 0 v 109e Brooktree Corporation 0 d 109e0350 Bt848 Video Capture 0 d 109e0351 Bt849A Video capture 0 d 109e0369 Bt878 Video Capture 0 s 109e036910020001 TV-Wonder 0 s 109e036910020003 TV-Wonder/VE 0 d 109e036c Bt879(?) Video Capture 0 s 109e036c13e90070 Win/TV (Video Section) 0 d 109e036e Bt878 Video Capture 0 s 109e036e007013eb WinTV Series 0 s 109e036e0070ff01 Viewcast Osprey 200 0 s 109e036e00710101 DigiTV PCI 0 s 109e036e107d6606 WinFast TV 2000 0 s 109e036e11bd0012 PCTV pro (TV + FM stereo receiver) 0 s 109e036e11bd001c PCTV Sat (DBC receiver) 0 s 109e036e127a0001 Bt878 Mediastream Controller NTSC 0 s 109e036e127a0002 Bt878 Mediastream Controller PAL BG 0 s 109e036e127a0003 Bt878a Mediastream Controller PAL BG 0 s 109e036e127a0048 Bt878/832 Mediastream Controller 0 s 109e036e144f3000 MagicTView CPH060 - Video 0 s 109e036e14610002 TV98 Series (TV/No FM/Remote) 0 s 109e036e14610004 AVerTV WDM Video Capture 0 s 109e036e14610761 AverTV DVB-T 0 s 109e036e14f10001 Bt878 Mediastream Controller NTSC 0 s 109e036e14f10002 Bt878 Mediastream Controller PAL BG 0 s 109e036e14f10003 Bt878a Mediastream Controller PAL BG 0 s 109e036e14f10048 Bt878/832 Mediastream Controller 0 s 109e036e18220001 VisionPlus DVB card 0 s 109e036e18511850 FlyVideo'98 - Video 0 s 109e036e18511851 FlyVideo II 0 s 109e036e18521852 FlyVideo'98 - Video (with FM Tuner) 0 s 109e036e270ffc00 Digitop DTT-1000 0 s 109e036ebd111200 PCTV pro (TV + FM stereo receiver) 0 d 109e036f Bt879 Video Capture 0 s 109e036f127a0044 Bt879 Video Capture NTSC 0 s 109e036f127a0122 Bt879 Video Capture PAL I 0 s 109e036f127a0144 Bt879 Video Capture NTSC 0 s 109e036f127a0222 Bt879 Video Capture PAL BG 0 s 109e036f127a0244 Bt879a Video Capture NTSC 0 s 109e036f127a0322 Bt879 Video Capture NTSC 0 s 109e036f127a0422 Bt879 Video Capture NTSC 0 s 109e036f127a1122 Bt879 Video Capture PAL I 0 s 109e036f127a1222 Bt879 Video Capture PAL BG 0 s 109e036f127a1322 Bt879 Video Capture NTSC 0 s 109e036f127a1522 Bt879a Video Capture PAL I 0 s 109e036f127a1622 Bt879a Video Capture PAL BG 0 s 109e036f127a1722 Bt879a Video Capture NTSC 0 s 109e036f14f10044 Bt879 Video Capture NTSC 0 s 109e036f14f10122 Bt879 Video Capture PAL I 0 s 109e036f14f10144 Bt879 Video Capture NTSC 0 s 109e036f14f10222 Bt879 Video Capture PAL BG 0 s 109e036f14f10244 Bt879a Video Capture NTSC 0 s 109e036f14f10322 Bt879 Video Capture NTSC 0 s 109e036f14f10422 Bt879 Video Capture NTSC 0 s 109e036f14f11122 Bt879 Video Capture PAL I 0 s 109e036f14f11222 Bt879 Video Capture PAL BG 0 s 109e036f14f11322 Bt879 Video Capture NTSC 0 s 109e036f14f11522 Bt879a Video Capture PAL I 0 s 109e036f14f11622 Bt879a Video Capture PAL BG 0 s 109e036f14f11722 Bt879a Video Capture NTSC 0 s 109e036f18511850 FlyVideo'98 - Video 0 s 109e036f18511851 FlyVideo II 0 s 109e036f18521852 FlyVideo'98 - Video (with FM Tuner) 0 d 109e0370 Bt880 Video Capture 0 s 109e037018511850 FlyVideo'98 0 s 109e037018511851 FlyVideo'98 EZ - video 0 s 109e037018521852 FlyVideo'98 (with FM Tuner) 0 d 109e0878 Bt878 Audio Capture 0 s 109e0878007013eb WinTV Series 0 s 109e08780070ff01 Viewcast Osprey 200 0 s 109e087800710101 DigiTV PCI 0 s 109e087810020001 TV-Wonder 0 s 109e087810020003 TV-Wonder/VE 0 s 109e087811bd0012 PCTV pro (TV + FM stereo receiver, audio section) 0 s 109e087811bd001c PCTV Sat (DBC receiver) 0 s 109e0878127a0001 Bt878 Video Capture (Audio Section) 0 s 109e0878127a0002 Bt878 Video Capture (Audio Section) 0 s 109e0878127a0003 Bt878 Video Capture (Audio Section) 0 s 109e0878127a0048 Bt878 Video Capture (Audio Section) 0 s 109e087813e90070 Win/TV (Audio Section) 0 s 109e0878144f3000 MagicTView CPH060 - Audio 0 s 109e087814610004 AVerTV WDM Audio Capture 0 s 109e087814610761 AVerTV DVB-T 0 s 109e087814f10001 Bt878 Video Capture (Audio Section) 0 s 109e087814f10002 Bt878 Video Capture (Audio Section) 0 s 109e087814f10003 Bt878 Video Capture (Audio Section) 0 s 109e087814f10048 Bt878 Video Capture (Audio Section) 0 s 109e087818220001 VisionPlus DVB Card 0 s 109e0878270ffc00 Digitop DTT-1000 0 s 109e0878bd111200 PCTV pro (TV + FM stereo receiver, audio section) 0 d 109e0879 Bt879 Audio Capture 0 s 109e0879127a0044 Bt879 Video Capture (Audio Section) 0 s 109e0879127a0122 Bt879 Video Capture (Audio Section) 0 s 109e0879127a0144 Bt879 Video Capture (Audio Section) 0 s 109e0879127a0222 Bt879 Video Capture (Audio Section) 0 s 109e0879127a0244 Bt879 Video Capture (Audio Section) 0 s 109e0879127a0322 Bt879 Video Capture (Audio Section) 0 s 109e0879127a0422 Bt879 Video Capture (Audio Section) 0 s 109e0879127a1122 Bt879 Video Capture (Audio Section) 0 s 109e0879127a1222 Bt879 Video Capture (Audio Section) 0 s 109e0879127a1322 Bt879 Video Capture (Audio Section) 0 s 109e0879127a1522 Bt879 Video Capture (Audio Section) 0 s 109e0879127a1622 Bt879 Video Capture (Audio Section) 0 s 109e0879127a1722 Bt879 Video Capture (Audio Section) 0 s 109e087914f10044 Bt879 Video Capture (Audio Section) 0 s 109e087914f10122 Bt879 Video Capture (Audio Section) 0 s 109e087914f10144 Bt879 Video Capture (Audio Section) 0 s 109e087914f10222 Bt879 Video Capture (Audio Section) 0 s 109e087914f10244 Bt879 Video Capture (Audio Section) 0 s 109e087914f10322 Bt879 Video Capture (Audio Section) 0 s 109e087914f10422 Bt879 Video Capture (Audio Section) 0 s 109e087914f11122 Bt879 Video Capture (Audio Section) 0 s 109e087914f11222 Bt879 Video Capture (Audio Section) 0 s 109e087914f11322 Bt879 Video Capture (Audio Section) 0 s 109e087914f11522 Bt879 Video Capture (Audio Section) 0 s 109e087914f11622 Bt879 Video Capture (Audio Section) 0 s 109e087914f11722 Bt879 Video Capture (Audio Section) 0 d 109e0880 Bt880 Audio Capture 0 d 109e2115 BtV 2115 Mediastream controller 0 d 109e2125 BtV 2125 Mediastream controller 0 d 109e2164 BtV 2164 0 d 109e2165 BtV 2165 0 d 109e8230 Bt8230 ATM Segment/Reassembly Ctrlr (SRC) 0 d 109e8472 Bt8472 0 d 109e8474 Bt8474 0 v 109f Trigem Computer Inc. 0 v 10a0 Meidensha Corporation 0 v 10a1 Juko Electronics Ind. Co. Ltd 0 v 10a2 Quantum Corporation 0 v 10a3 Everex Systems Inc 0 v 10a4 Globe Manufacturing Sales 0 v 10a5 Smart Link Ltd. 0 d 10a53052 SmartPCI562 56K Modem 0 d 10a55449 SmartPCI561 modem 0 v 10a6 Informtech Industrial Ltd. 0 v 10a7 Benchmarq Microelectronics 0 v 10a8 Sierra Semiconductor 0 d 10a80000 STB Horizon 64 0 v 10a9 Silicon Graphics, Inc. 0 d 10a90001 Crosstalk to PCI Bridge 0 d 10a90002 Linc I/O controller 0 d 10a90003 IOC3 I/O controller 0 d 10a90004 O2 MACE 0 d 10a90005 RAD Audio 0 d 10a90006 HPCEX 0 d 10a90007 RPCEX 0 d 10a90008 DiVO VIP 0 d 10a90009 AceNIC Gigabit Ethernet 0 s 10a9000910a98002 AceNIC Gigabit Ethernet 0 d 10a90010 AMP Video I/O 0 d 10a90011 GRIP 0 d 10a90012 SGH PSHAC GSN 0 d 10a91001 Magic Carpet 0 d 10a91002 Lithium 0 d 10a91003 Dual JPEG 1 0 d 10a91004 Dual JPEG 2 0 d 10a91005 Dual JPEG 3 0 d 10a91006 Dual JPEG 4 0 d 10a91007 Dual JPEG 5 0 d 10a91008 Cesium 0 d 10a9100a IOC4 I/O controller 0 d 10a92001 Fibre Channel 0 d 10a92002 ASDE 0 d 10a98001 O2 1394 0 d 10a98002 G-net NT 0 v 10aa ACC Microelectronics 0 d 10aa0000 ACCM 2188 0 v 10ab Digicom 0 v 10ac Honeywell IAC 0 v 10ad Symphony Labs 0 d 10ad0001 W83769F 0 d 10ad0003 SL82C103 0 d 10ad0005 SL82C105 0 d 10ad0103 SL82c103 0 d 10ad0105 SL82c105 0 d 10ad0565 W83C553 0 v 10ae Cornerstone Technology 0 v 10af Micro Computer Systems Inc 0 v 10b0 CardExpert Technology 0 v 10b1 Cabletron Systems Inc 0 v 10b2 Raytheon Company 0 v 10b3 Databook Inc 0 d 10b33106 DB87144 0 d 10b3b106 DB87144 0 v 10b4 STB Systems Inc 0 d 10b41b1d Velocity 128 3D 0 s 10b41b1d10b4237e Velocity 4400 0 v 10b5 PLX Technology, Inc. 0 d 10b50001 i960 PCI bus interface 0 d 10b51076 VScom 800 8 port serial adaptor 0 d 10b51077 VScom 400 4 port serial adaptor 0 d 10b51078 VScom 210 2 port serial and 1 port parallel adaptor 0 d 10b51103 VScom 200 2 port serial adaptor 0 d 10b51146 VScom 010 1 port parallel adaptor 0 d 10b51147 VScom 020 2 port parallel adaptor 0 d 10b52724 Thales PCSM Security Card 0 d 10b59030 PCI <-> IOBus Bridge Hot Swap 0 s 10b5903010b52862 Alpermann+Velte PCL PCI LV (3V/5V): Timecode Reader Board 0 s 10b5903010b52906 Alpermann+Velte PCI TS (3V/5V): Time Synchronisation Board 0 s 10b5903010b52940 Alpermann+Velte PCL PCI D (3V/5V): Timecode Reader Board 0 s 10b5903015ed1002 MCCS 8-port Serial Hot Swap 0 s 10b5903015ed1003 MCCS 16-port Serial Hot Swap 0 d 10b59036 9036 0 d 10b59050 PCI <-> IOBus Bridge 0 s 10b5905010b51067 IXXAT CAN i165 0 s 10b5905010b51172 IK220 (Heidenhain) 0 s 10b5905010b52036 SatPak GPS 0 s 10b5905010b52221 Alpermann+Velte PCL PCI LV: Timecode Reader Board 0 s 10b5905010b52273 SH-ARC SoHard ARCnet card 0 s 10b5905010b52431 Alpermann+Velte PCL PCI D: Timecode Reader Board 0 s 10b5905010b52905 Alpermann+Velte PCI TS: Time Synchronisation Board 0 s 10b5905010b59050 MP9050 0 s 10b5905014980362 TPMC866 8 Channel Serial Card 0 s 10b5905015220001 RockForce 4 Port V.90 Data/Fax/Voice Modem 0 s 10b5905015220002 RockForce 2 Port V.90 Data/Fax/Voice Modem 0 s 10b5905015220003 RockForce 6 Port V.90 Data/Fax/Voice Modem 0 s 10b5905015220004 RockForce 8 Port V.90 Data/Fax/Voice Modem 0 s 10b5905015220010 RockForce2000 4 Port V.90 Data/Fax/Voice Modem 0 s 10b5905015220020 RockForce2000 2 Port V.90 Data/Fax/Voice Modem 0 s 10b5905015ed1000 Macrolink MCCS 8-port Serial 0 s 10b5905015ed1001 Macrolink MCCS 16-port Serial 0 s 10b5905015ed1002 Macrolink MCCS 8-port Serial Hot Swap 0 s 10b5905015ed1003 Macrolink MCCS 16-port Serial Hot Swap 0 s 10b5905056542036 OpenSwitch 6 Telephony card 0 Sorry, there was a typo s 10b5905056543132 OpenSwitch 12 Telephony card 0 Sorry, there was a typo s 10b5905056545634 OpenLine4 Telephony Card 0 s 10b59050d531c002 PCIntelliCAN 2xSJA1000 CAN bus 0 s 10b59050d84d4006 EX-4006 1P 0 s 10b59050d84d4008 EX-4008 1P EPP/ECP 0 s 10b59050d84d4014 EX-4014 2P 0 s 10b59050d84d4018 EX-4018 3P EPP/ECP 0 s 10b59050d84d4025 EX-4025 1S(16C550) RS-232 0 s 10b59050d84d4027 EX-4027 1S(16C650) RS-232 0 s 10b59050d84d4028 EX-4028 1S(16C850) RS-232 0 s 10b59050d84d4036 EX-4036 2S(16C650) RS-232 0 s 10b59050d84d4037 EX-4037 2S(16C650) RS-232 0 s 10b59050d84d4038 EX-4038 2S(16C850) RS-232 0 s 10b59050d84d4052 EX-4052 1S(16C550) RS-422/485 0 s 10b59050d84d4053 EX-4053 2S(16C550) RS-422/485 0 s 10b59050d84d4055 EX-4055 4S(16C550) RS-232 0 s 10b59050d84d4058 EX-4055 4S(16C650) RS-232 0 s 10b59050d84d4065 EX-4065 8S(16C550) RS-232 0 s 10b59050d84d4068 EX-4068 8S(16C650) RS-232 0 s 10b59050d84d4078 EX-4078 2S(16C552) RS-232+1P 0 d 10b59054 PCI <-> IOBus Bridge 0 s 10b5905410b52455 Wessex Techology PHIL-PCI 0 s 10b5905410b52696 Innes Corp AM Radcap card 0 s 10b5905410b52717 Innes Corp Auricon card 0 s 10b5905410b52844 Innes Corp TVS Encoder card 0 s 10b5905412d90002 PCI Prosody Card rev 1.5 0 s 10b5905416df0011 PIKA PrimeNet MM PCI 0 s 10b5905416df0012 PIKA PrimeNet MM cPCI 8 0 s 10b5905416df0013 PIKA PrimeNet MM cPCI 8 (without CAS Signaling Option) 0 s 10b5905416df0014 PIKA PrimeNet MM cPCI 4 0 s 10b5905416df0015 PIKA Daytona MM 0 s 10b5905416df0016 PIKA InLine MM 0 d 10b59056 Francois 0 s 10b5905610b52979 CellinkBlade 11 - CPCI board VoATM AAL1 0 d 10b59060 9060 0 d 10b5906d 9060SD 0 s 10b5906d125c0640 Aries 16000P 0 d 10b5906e 9060ES 0 d 10b59080 9080 0 s 10b59080103c10eb (Agilent) E2777B 83K Series PCI based Optical Communication Interface 0 s 10b59080103c10ec (Agilent) E6978-66442 PCI CIC 0 s 10b5908010b59080 9080 [real subsystem ID not set] 0 s 10b59080129d0002 Aculab PCI Prosidy card 0 s 10b5908012d90002 PCI Prosody Card 0 s 10b5908012df4422 4422PCI ["Do-All" Telemetry Data Aquisition System] 0 d 10b5bb04 B&B 3PCIOSD1A Isolated PCI Serial 0 v 10b6 Madge Networks 0 d 10b60001 Smart 16/4 PCI Ringnode 0 d 10b60002 Smart 16/4 PCI Ringnode Mk2 0 s 10b6000210b60002 Smart 16/4 PCI Ringnode Mk2 0 s 10b6000210b60006 16/4 CardBus Adapter 0 d 10b60003 Smart 16/4 PCI Ringnode Mk3 0 s 10b600030e11b0fd Compaq NC4621 PCI, 4/16, WOL 0 s 10b6000310b60003 Smart 16/4 PCI Ringnode Mk3 0 s 10b6000310b60007 Presto PCI Plus Adapter 0 d 10b60004 Smart 16/4 PCI Ringnode Mk1 0 d 10b60006 16/4 Cardbus Adapter 0 s 10b6000610b60006 16/4 CardBus Adapter 0 d 10b60007 Presto PCI Adapter 0 s 10b6000710b60007 Presto PCI 0 d 10b60009 Smart 100/16/4 PCI-HS Ringnode 0 s 10b6000910b60009 Smart 100/16/4 PCI-HS Ringnode 0 d 10b6000a Smart 100/16/4 PCI Ringnode 0 s 10b6000a10b6000a Smart 100/16/4 PCI Ringnode 0 d 10b6000b 16/4 CardBus Adapter Mk2 0 s 10b6000b10b60008 16/4 CardBus Adapter Mk2 0 s 10b6000b10b6000b 16/4 Cardbus Adapter Mk2 0 d 10b6000c RapidFire 3140V2 16/4 TR Adapter 0 s 10b6000c10b6000c RapidFire 3140V2 16/4 TR Adapter 0 d 10b61000 Collage 25/155 ATM Client Adapter 0 d 10b61001 Collage 155 ATM Server Adapter 0 v 10b7 3Com Corporation 0 d 10b70001 3c985 1000BaseSX (SX/TX) 0 d 10b70013 AR5212 802.11abg NIC (3CRDAG675) 0 s 10b7001310b72031 3CRDAG675 11a/b/g Wireless PCI Adapter 0 d 10b70910 3C910-A01 0 d 10b71006 MINI PCI type 3B Data Fax Modem 0 d 10b71007 Mini PCI 56k Winmodem 0 s 10b7100710b7615c Mini PCI 56K Modem 0 d 10b71201 3c982-TXM 10/100baseTX Dual Port A [Hydra] 0 d 10b71202 3c982-TXM 10/100baseTX Dual Port B [Hydra] 0 d 10b71700 3c940 10/100/1000Base-T [Marvell] 0 s 10b71700104380eb P4P800 Mainboard 0 s 10b7170010b70010 3C940 Gigabit LOM Ethernet Adapter 0 s 10b7170010b70020 3C941 Gigabit LOM Ethernet Adapter 0 s 10b71700147b1407 KV8-MAX3 motherboard 0 d 10b73390 3c339 TokenLink Velocity 0 d 10b73590 3c359 TokenLink Velocity XL 0 s 10b7359010b73590 TokenLink Velocity XL Adapter (3C359/359B) 0 d 10b74500 3c450 HomePNA [Tornado] 0 d 10b75055 3c555 Laptop Hurricane 0 d 10b75057 3c575 Megahertz 10/100 LAN CardBus [Boomerang] 0 s 10b7505710b75a57 3C575 Megahertz 10/100 LAN Cardbus PC Card 0 d 10b75157 3cCFE575BT Megahertz 10/100 LAN CardBus [Cyclone] 0 s 10b7515710b75b57 3C575 Megahertz 10/100 LAN Cardbus PC Card 0 d 10b75257 3cCFE575CT CardBus [Cyclone] 0 s 10b7525710b75c57 FE575C-3Com 10/100 LAN CardBus-Fast Ethernet 0 d 10b75900 3c590 10BaseT [Vortex] 0 d 10b75920 3c592 EISA 10mbps Demon/Vortex 0 d 10b75950 3c595 100BaseTX [Vortex] 0 d 10b75951 3c595 100BaseT4 [Vortex] 0 d 10b75952 3c595 100Base-MII [Vortex] 0 d 10b75970 3c597 EISA Fast Demon/Vortex 0 d 10b75b57 3c595 Megahertz 10/100 LAN CardBus [Boomerang] 0 s 10b75b5710b75b57 3C575 Megahertz 10/100 LAN Cardbus PC Card 0 d 10b76000 3CRSHPW796 [OfficeConnect Wireless CardBus] 0 d 10b76001 3com 3CRWE154G72 [Office Connect Wireless LAN Adapter] 0 d 10b76055 3c556 Hurricane CardBus [Cyclone] 0 d 10b76056 3c556B CardBus [Tornado] 0 s 10b7605610b76556 10/100 Mini PCI Ethernet Adapter 0 d 10b76560 3cCFE656 CardBus [Cyclone] 0 s 10b7656010b7656a 3CCFEM656 10/100 LAN+56K Modem CardBus 0 d 10b76561 3cCFEM656 10/100 LAN+56K Modem CardBus 0 s 10b7656110b7656b 3CCFEM656 10/100 LAN+56K Modem CardBus 0 d 10b76562 3cCFEM656B 10/100 LAN+Winmodem CardBus [Cyclone] 0 s 10b7656210b7656b 3CCFEM656B 10/100 LAN+56K Modem CardBus 0 d 10b76563 3cCFEM656B 10/100 LAN+56K Modem CardBus 0 s 10b7656310b7656b 3CCFEM656 10/100 LAN+56K Modem CardBus 0 d 10b76564 3cXFEM656C 10/100 LAN+Winmodem CardBus [Tornado] 0 d 10b77646 3cSOHO100-TX Hurricane 0 d 10b77770 3CRWE777 PCI(PLX) Wireless Adaptor [Airconnect] 0 d 10b77940 3c803 FDDILink UTP Controller 0 d 10b77980 3c804 FDDILink SAS Controller 0 d 10b77990 3c805 FDDILink DAS Controller 0 d 10b780eb 3c940B 10/100/1000Base-T 0 d 10b78811 Token ring 0 d 10b79000 3c900 10BaseT [Boomerang] 0 d 10b79001 3c900 10Mbps Combo [Boomerang] 0 d 10b79004 3c900B-TPO Etherlink XL [Cyclone] 0 s 10b7900410b79004 3C900B-TPO Etherlink XL TPO 10Mb 0 d 10b79005 3c900B-Combo Etherlink XL [Cyclone] 0 s 10b7900510b79005 3C900B-Combo Etherlink XL Combo 0 d 10b79006 3c900B-TPC Etherlink XL [Cyclone] 0 d 10b7900a 3c900B-FL 10base-FL [Cyclone] 0 d 10b79050 3c905 100BaseTX [Boomerang] 0 d 10b79051 3c905 100BaseT4 [Boomerang] 0 d 10b79055 3c905B 100BaseTX [Cyclone] 0 s 10b7905510280080 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280081 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280082 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280083 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280084 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280085 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280086 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280087 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280088 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280089 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280090 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280091 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280092 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280093 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280094 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280095 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280096 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280097 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280098 3C905B Fast Etherlink XL 10/100 0 s 10b7905510280099 3C905B Fast Etherlink XL 10/100 0 s 10b7905510b79055 3C905B Fast Etherlink XL 10/100 0 d 10b79056 3c905B-T4 Fast EtherLink XL [Cyclone] 0 d 10b79058 3c905B Deluxe Etherlink 10/100/BNC [Cyclone] 0 d 10b7905a 3c905B-FX Fast Etherlink XL FX 100baseFx [Cyclone] 0 d 10b79200 3c905C-TX/TX-M [Tornado] 0 s 10b7920010280095 3C920 Integrated Fast Ethernet Controller 0 s 10b7920010280097 3C920 Integrated Fast Ethernet Controller 0 s 10b79200102800fe Optiplex GX240 0 s 10b792001028012a 3C920 Integrated Fast Ethernet Controller [Latitude C640] 0 s 10b7920010b71000 3C905C-TX Fast Etherlink for PC Management NIC 0 s 10b7920010b77000 10/100 Mini PCI Ethernet Adapter 0 s 10b7920010f12466 Tiger MPX S2466 (3C920 Integrated Fast Ethernet Controller) 0 d 10b79201 3C920B-EMB Integrated Fast Ethernet Controller [Tornado] 0 s 10b79201104380ab A7N8X Deluxe onboard 3C920B-EMB Integrated Fast Ethernet Controller 0 d 10b79202 3Com 3C920B-EMB-WNM Integrated Fast Ethernet Controller 0 d 10b79210 3C920B-EMB-WNM Integrated Fast Ethernet Controller 0 d 10b79300 3CSOHO100B-TX 910-A01 [tulip] 0 d 10b79800 3c980-TX Fast Etherlink XL Server Adapter [Cyclone] 0 s 10b7980010b79800 3c980-TX Fast Etherlink XL Server Adapter 0 d 10b79805 3c980-C 10/100baseTX NIC [Python-T] 0 s 10b7980510b71201 EtherLink Server 10/100 Dual Port A 0 s 10b7980510b71202 EtherLink Server 10/100 Dual Port B 0 s 10b7980510b79805 3c980 10/100baseTX NIC [Python-T] 0 s 10b7980510f12462 Thunder K7 S2462 0 d 10b79900 3C990-TX [Typhoon] 0 d 10b79902 3CR990-TX-95 [Typhoon 56-bit] 0 d 10b79903 3CR990-TX-97 [Typhoon 168-bit] 0 d 10b79904 3C990B-TX-M/3C990BSVR [Typhoon2] 0 s 10b7990410b71000 3CR990B-TX-M [Typhoon2] 0 s 10b7990410b72000 3CR990BSVR [Typhoon2 Server] 0 d 10b79905 3CR990-FX-95/97/95 [Typhon Fiber] 0 s 10b7990510b71101 3CR990-FX-95 [Typhoon Fiber 56-bit] 0 s 10b7990510b71102 3CR990-FX-97 [Typhoon Fiber 168-bit] 0 s 10b7990510b72101 3CR990-FX-95 Server [Typhoon Fiber 56-bit] 0 s 10b7990510b72102 3CR990-FX-97 Server [Typhoon Fiber 168-bit] 0 d 10b79908 3CR990SVR95 [Typhoon Server 56-bit] 0 d 10b79909 3CR990SVR97 [Typhoon Server 168-bit] 0 d 10b7990a 3C990SVR [Typhoon Server] 0 d 10b7990b 3C990SVR [Typhoon Server] 0 v 10b8 Standard Microsystems Corp [SMC] 0 d 10b80005 83c170 EPIC/100 Fast Ethernet Adapter 0 s 10b800051055e000 LANEPIC 10/100 [EVB171Q-PCI] 0 s 10b800051055e002 LANEPIC 10/100 [EVB171G-PCI] 0 s 10b8000510b8a011 EtherPower II 10/100 0 s 10b8000510b8a014 EtherPower II 10/100 0 s 10b8000510b8a015 EtherPower II 10/100 0 s 10b8000510b8a016 EtherPower II 10/100 0 s 10b8000510b8a017 EtherPower II 10/100 0 d 10b80006 83c175 EPIC/100 Fast Ethernet Adapter 0 s 10b800061055e100 LANEPIC Cardbus Fast Ethernet Adapter 0 s 10b800061055e102 LANEPIC Cardbus Fast Ethernet Adapter 0 s 10b800061055e300 LANEPIC Cardbus Fast Ethernet Adapter 0 s 10b800061055e302 LANEPIC Cardbus Fast Ethernet Adapter 0 s 10b8000610b8a012 LANEPIC Cardbus Fast Ethernet Adapter 0 s 10b8000613a28002 LANEPIC Cardbus Fast Ethernet Adapter 0 s 10b8000613a28006 LANEPIC Cardbus Fast Ethernet Adapter 0 d 10b81000 FDC 37c665 0 d 10b81001 FDC 37C922 0 d 10b82802 SMC2802W [EZ Connect g] 0 802.11g card d 10b8a011 83C170QF 0 d 10b8b106 SMC34C90 0 v 10b9 ALi Corporation 0 d 10b90101 CMI8338/C3DX PCI Audio Device 0 d 10b90111 C-Media CMI8738/C3DX Audio Device (OEM) 0 s 10b9011110b90111 C-Media CMI8738/C3DX Audio Device (OEM) 0 d 10b90780 Multi-IO Card 0 d 10b90782 Multi-IO Card 0 d 10b91435 M1435 0 d 10b91445 M1445 0 d 10b91449 M1449 0 d 10b91451 M1451 0 d 10b91461 M1461 0 d 10b91489 M1489 0 d 10b91511 M1511 [Aladdin] 0 d 10b91512 M1512 [Aladdin] 0 d 10b91513 M1513 [Aladdin] 0 d 10b91521 M1521 [Aladdin III] 0 s 10b9152110b91521 ALI M1521 Aladdin III CPU Bridge 0 d 10b91523 M1523 0 s 10b9152310b91523 ALI M1523 ISA Bridge 0 d 10b91531 M1531 [Aladdin IV] 0 d 10b91533 M1533 PCI to ISA Bridge [Aladdin IV] 0 s 10b915331014053b ThinkPad R40e (2684-HVG) PCI to ISA Bridge 0 s 10b9153310b91533 ALI M1533 Aladdin IV ISA Bridge 0 d 10b91541 M1541 0 s 10b9154110b91541 ALI M1541 Aladdin V/V+ AGP System Controller 0 d 10b91543 M1543 0 d 10b91563 M1563 HyperTransport South Bridge 0 d 10b91621 M1621 0 d 10b91631 ALI M1631 PCI North Bridge Aladdin Pro III 0 d 10b91632 M1632M Northbridge+Trident 0 d 10b91641 ALI M1641 PCI North Bridge Aladdin Pro IV 0 d 10b91644 M1644/M1644T Northbridge+Trident 0 d 10b91646 M1646 Northbridge+Trident 0 d 10b91647 M1647 Northbridge [MAGiK 1 / MobileMAGiK 1] 0 d 10b91651 M1651/M1651T Northbridge [Aladdin-Pro 5/5M,Aladdin-Pro 5T/5TM] 0 d 10b91671 M1671 Super P4 Northbridge [AGP4X,PCI and SDR/DDR] 0 d 10b91672 M1672 Northbridge [CyberALADDiN-P4] 0 d 10b91681 M1681 P4 Northbridge [AGP8X,HyperTransport and SDR/DDR] 0 d 10b91687 M1687 K8 Northbridge [AGP8X and HyperTransport] 0 d 10b91689 M1689 K8 Northbridge [Super K8 Single Chip] 0 d 10b93141 M3141 0 d 10b93143 M3143 0 d 10b93145 M3145 0 d 10b93147 M3147 0 d 10b93149 M3149 0 d 10b93151 M3151 0 d 10b93307 M3307 0 d 10b93309 M3309 0 d 10b93323 M3325 Video/Audio Decoder 0 d 10b95212 M4803 0 d 10b95215 MS4803 0 d 10b95217 M5217H 0 d 10b95219 M5219 0 d 10b95225 M5225 0 d 10b95229 M5229 IDE 0 s 10b952291014050f ThinkPad R30 0 s 10b952291014053d ThinkPad R40e (2684-HVG) builtin IDE 0 s 10b95229103c0024 Pavilion ze4400 builtin IDE 0 s 10b9522910438053 A7A266 Motherboard IDE 0 d 10b95235 M5225 0 d 10b95237 USB 1.1 Controller 0 s 10b9523710140540 ThinkPad R40e (2684-HVG) builtin USB 0 s 10b95237103c0024 Pavilion ze4400 builtin USB 0 d 10b95239 USB 2.0 Controller 0 d 10b95243 M1541 PCI to AGP Controller 0 d 10b95246 AGP8X Controller 0 d 10b95247 PCI to AGP Controller 0 d 10b95249 M5249 HTT to PCI Bridge 0 d 10b95251 M5251 P1394 OHCI 1.0 Controller 0 d 10b95253 M5253 P1394 OHCI 1.1 Controller 0 d 10b95261 M5261 Ethernet Controller 0 d 10b95263 M5263 Ethernet Controller 0 d 10b95281 ALi M5281 Serial ATA / RAID Host Controller 0 d 10b95450 Lucent Technologies Soft Modem AMR 0 d 10b95451 M5451 PCI AC-Link Controller Audio Device 0 s 10b9545110140506 ThinkPad R30 0 s 10b954511014053e ThinkPad R40e (2684-HVG) builtin Audio 0 s 10b95451103c0024 Pavilion ze4400 builtin Audio 0 s 10b9545110b95451 HP Compaq nc4010 (DY885AA#ABN) 0 d 10b95453 M5453 PCI AC-Link Controller Modem Device 0 d 10b95455 M5455 PCI AC-Link Controller Audio Device 0 d 10b95457 M5457 AC'97 Modem Controller 0 s 10b9545710140535 ThinkPad R40e (2684-HVG) builtin modem 0 s 10b95457103c0024 Pavilion ze4400 builtin Modem Device 0 d 10b95459 SmartLink SmartPCI561 56K Modem 0 Same but more usefull for driver's lookup d 10b9545a SmartLink SmartPCI563 56K Modem 0 SmartLink PCI SoftModem d 10b95471 M5471 Memory Stick Controller 0 d 10b95473 M5473 SD-MMC Controller 0 d 10b97101 M7101 Power Management Controller [PMU] 0 s 10b9710110140510 ThinkPad R30 0 s 10b971011014053c ThinkPad R40e (2684-HVG) Power Management Controller 0 s 10b97101103c0024 Pavilion ze4400 0 v 10ba Mitsubishi Electric Corp. 0 d 10ba0301 AccelGraphics AccelECLIPSE 0 d 10ba0304 AccelGALAXY A2100 [OEM Evans & Sutherland] 0 d 10ba0308 Tornado 3000 [OEM Evans & Sutherland] 0 d 10ba1002 VG500 [VolumePro Volume Rendering Accelerator] 0 v 10bb Dapha Electronics Corporation 0 v 10bc Advanced Logic Research 0 v 10bd Surecom Technology 0 d 10bd0e34 NE-34 0 v 10be Tseng Labs International Co. 0 v 10bf Most Inc 0 v 10c0 Boca Research Inc. 0 v 10c1 ICM Co., Ltd. 0 v 10c2 Auspex Systems Inc. 0 v 10c3 Samsung Semiconductors, Inc. 0 d 10c31100 Smartether100 SC1100 LAN Adapter (i82557B) 0 v 10c4 Award Software International Inc. 0 v 10c5 Xerox Corporation 0 v 10c6 Rambus Inc. 0 v 10c7 Media Vision 0 v 10c8 Neomagic Corporation 0 d 10c80001 NM2070 [MagicGraph 128] 0 d 10c80002 NM2090 [MagicGraph 128V] 0 d 10c80003 NM2093 [MagicGraph 128ZV] 0 d 10c80004 NM2160 [MagicGraph 128XD] 0 s 10c80004101400ba MagicGraph 128XD 0 s 10c8000410251007 MagicGraph 128XD 0 s 10c8000410280074 MagicGraph 128XD 0 s 10c8000410280075 MagicGraph 128XD 0 s 10c800041028007d MagicGraph 128XD 0 s 10c800041028007e MagicGraph 128XD 0 s 10c800041033802f MagicGraph 128XD 0 s 10c80004104d801b MagicGraph 128XD 0 s 10c80004104d802f MagicGraph 128XD 0 s 10c80004104d830b MagicGraph 128XD 0 s 10c8000410ba0e00 MagicGraph 128XD 0 s 10c8000410c80004 MagicGraph 128XD 0 s 10c8000410cf1029 MagicGraph 128XD 0 s 10c8000410f78308 MagicGraph 128XD 0 s 10c8000410f78309 MagicGraph 128XD 0 s 10c8000410f7830b MagicGraph 128XD 0 s 10c8000410f7830d MagicGraph 128XD 0 s 10c8000410f78312 MagicGraph 128XD 0 d 10c80005 NM2200 [MagicGraph 256AV] 0 s 10c80005101400dd ThinkPad 570 0 s 10c8000510280088 Latitude CPi A 0 d 10c80006 NM2360 [MagicMedia 256ZX] 0 d 10c80016 NM2380 [MagicMedia 256XL+] 0 s 10c8001610c80016 MagicMedia 256XL+ 0 d 10c80025 NM2230 [MagicGraph 256AV+] 0 d 10c80083 NM2093 [MagicGraph 128ZV+] 0 d 10c88005 NM2200 [MagicMedia 256AV Audio] 0 s 10c880050e11b0d1 MagicMedia 256AV Audio Device on Discovery 0 s 10c880050e11b126 MagicMedia 256AV Audio Device on Durango 0 s 10c88005101400dd MagicMedia 256AV Audio Device on BlackTip Thinkpad 0 s 10c8800510251003 MagicMedia 256AV Audio Device on TravelMate 720 0 s 10c8800510280088 Latitude CPi A 0 s 10c880051028008f MagicMedia 256AV Audio Device on Colorado Inspiron 0 s 10c88005103c0007 MagicMedia 256AV Audio Device on Voyager II 0 s 10c88005103c0008 MagicMedia 256AV Audio Device on Voyager III 0 s 10c88005103c000d MagicMedia 256AV Audio Device on Omnibook 900 0 s 10c8800510c88005 MagicMedia 256AV Audio Device on FireAnt 0 s 10c88005110a8005 MagicMedia 256AV Audio Device 0 s 10c8800514c00004 MagicMedia 256AV Audio Device 0 d 10c88006 NM2360 [MagicMedia 256ZX Audio] 0 d 10c88016 NM2380 [MagicMedia 256XL+ Audio] 0 v 10c9 Dataexpert Corporation 0 v 10ca Fujitsu Microelectr., Inc. 0 v 10cb Omron Corporation 0 v 10cc Mai Logic Incorporated 0 nee Mentor ARC Inc d 10cc0660 Articia S Host Bridge 0 d 10cc0661 Articia S PCI Bridge 0 v 10cd Advanced System Products, Inc 0 d 10cd1100 ASC1100 0 d 10cd1200 ASC1200 [(abp940) Fast SCSI-II] 0 d 10cd1300 ABP940-U / ABP960-U 0 s 10cd130010cd1310 ASC1300 SCSI Adapter 0 d 10cd2300 ABP940-UW 0 d 10cd2500 ABP940-U2W 0 v 10ce Radius 0 v 10cf Fujitsu Limited. 0 nee Citicorp TTI d 10cf2001 mb86605 0 v 10d1 FuturePlus Systems Corp. 0 v 10d2 Molex Incorporated 0 v 10d3 Jabil Circuit Inc 0 v 10d4 Hualon Microelectronics 0 v 10d5 Autologic Inc. 0 v 10d6 Cetia 0 v 10d7 BCM Advanced Research 0 v 10d8 Advanced Peripherals Labs 0 v 10d9 Macronix, Inc. [MXIC] 0 d 10d90512 MX98713 0 d 10d90531 MX987x5 0 s 10d9053111861200 DFE-540TX ProFAST 10/100 Adapter 0 d 10d98625 MX86250 0 d 10d98888 MX86200 0 v 10da Compaq IPG-Austin 0 d 10da0508 TC4048 Token Ring 4/16 0 d 10da3390 Tl3c3x9 0 v 10db Rohm LSI Systems, Inc. 0 v 10dc CERN/ECP/EDU 0 d 10dc0001 STAR/RD24 SCI-PCI (PMC) 0 d 10dc0002 TAR/RD24 SCI-PCI (PMC) 0 d 10dc0021 HIPPI destination 0 d 10dc0022 HIPPI source 0 d 10dc10dc ATT2C15-3 FPGA 0 v 10dd Evans & Sutherland 0 v 10de nVidia Corporation 0 d 10de0008 NV1 [EDGE 3D] 0 d 10de0009 NV1 [EDGE 3D] 0 d 10de0010 NV2 [Mutara V08] 0 d 10de0020 NV4 [RIVA TNT] 0 s 10de002010430200 V3400 TNT 0 s 10de002010480c18 Erazor II SGRAM 0 s 10de002010480c1b Erazor II 0 s 10de002010920550 Viper V550 0 s 10de002010920552 Viper V550 0 s 10de002010924804 Viper V550 0 s 10de002010924808 Viper V550 0 s 10de002010924810 Viper V550 0 s 10de002010924812 Viper V550 0 s 10de002010924815 Viper V550 0 s 10de002010924820 Viper V550 with TV out 0 s 10de002010924822 Viper V550 0 s 10de002010924904 Viper V550 0 s 10de002010924914 Viper V550 0 s 10de002010928225 Viper V550 0 s 10de002010b4273d Velocity 4400 0 s 10de002010b4273e Velocity 4400 0 s 10de002010b42740 Velocity 4400 0 s 10de002010de0020 Riva TNT 0 s 10de002011021015 Graphics Blaster CT6710 0 s 10de002011021016 Graphics Blaster RIVA TNT 0 d 10de0028 NV5 [RIVA TNT2/TNT2 Pro] 0 s 10de002810430200 AGP-V3800 SGRAM 0 s 10de002810430201 AGP-V3800 SDRAM 0 s 10de002810430205 PCI-V3800 0 s 10de002810434000 AGP-V3800PRO 0 s 10de002810480c21 Synergy II 0 s 10de002810480c31 Erazor III 0 s 10de0028107d2134 WinFast 3D S320 II + TV-Out 0 s 10de002810924804 Viper V770 0 s 10de002810924a00 Viper V770 0 s 10de002810924a02 Viper V770 Ultra 0 s 10de002810925a00 RIVA TNT2/TNT2 Pro 0 s 10de002810926a02 Viper V770 Ultra 0 s 10de002810927a02 Viper V770 Ultra 0 s 10de002810de0005 RIVA TNT2 Pro 0 s 10de002810de000f Compaq NVIDIA TNT2 Pro 0 s 10de002811021020 3D Blaster RIVA TNT2 0 s 10de002811021026 3D Blaster RIVA TNT2 Digital 0 s 10de002814af5810 Maxi Gamer Xentor 0 d 10de0029 NV5 [RIVA TNT2 Ultra] 0 s 10de002910430200 AGP-V3800 Deluxe 0 s 10de002910430201 AGP-V3800 Ultra SDRAM 0 s 10de002910430205 PCI-V3800 Ultra 0 s 10de002911021021 3D Blaster RIVA TNT2 Ultra 0 s 10de002911021029 3D Blaster RIVA TNT2 Ultra 0 s 10de00291102102f 3D Blaster RIVA TNT2 Ultra 0 s 10de002914af5820 Maxi Gamer Xentor 32 0 d 10de002a NV5 [Riva TnT2] 0 d 10de002b NV5 [Riva TnT2] 0 d 10de002c NV6 [Vanta/Vanta LT] 0 s 10de002c10430200 AGP-V3800 Combat SDRAM 0 s 10de002c10430201 AGP-V3800 Combat 0 s 10de002c10926820 Viper V730 0 s 10de002c11021031 CT6938 VANTA 8MB 0 s 10de002c11021034 CT6894 VANTA 16MB 0 s 10de002c14af5008 Maxi Gamer Phoenix 2 0 d 10de002d NV5M64 [RIVA TNT2 Model 64/Model 64 Pro] 0 s 10de002d10430200 AGP-V3800M 0 s 10de002d10430201 AGP-V3800M 0 s 10de002d10480c3a Erazor III LT 0 s 10de002d10de001e M64 AGP4x 0 s 10de002d11021023 CT6892 RIVA TNT2 Value 0 s 10de002d11021024 CT6932 RIVA TNT2 Value 32Mb 0 s 10de002d1102102c CT6931 RIVA TNT2 Value [Jumper] 0 s 10de002d14628808 MSI-8808 0 s 10de002d15541041 Pixelview RIVA TNT2 M64 0 d 10de002e NV6 [Vanta] 0 d 10de002f NV6 [Vanta] 0 d 10de0034 MCP04 SMBus 0 d 10de0035 MCP04 IDE 0 d 10de0036 MCP04 Serial ATA Controller 0 d 10de0037 MCP04 Ethernet Controller 0 d 10de0038 MCP04 Ethernet Controller 0 d 10de003a MCP04 AC'97 Audio Controller 0 d 10de003b MCP04 USB Controller 0 d 10de003c MCP04 USB Controller 0 d 10de003d MCP04 PCI Bridge 0 d 10de003e MCP04 Serial ATA Controller 0 d 10de0040 nv40 [GeForce 6800 Ultra] 0 d 10de0041 NV40 [GeForce 6800] 0 d 10de0042 NV40.2 0 d 10de0043 NV40.3 0 d 10de0045 NV40 [GeForce 6800 GT] 0 d 10de0049 NV40GL 0 d 10de004e NV40GL [Quadro FX 4000] 0 d 10de0052 CK804 SMBus 0 d 10de0053 CK804 IDE 0 d 10de0054 CK804 Serial ATA Controller 0 d 10de0055 CK804 Serial ATA Controller 0 d 10de0056 CK804 Ethernet Controller 0 d 10de0057 CK804 Ethernet Controller 0 d 10de0059 CK804 AC'97 Audio Controller 0 d 10de005a CK804 USB Controller 0 d 10de005b CK804 USB Controller 0 d 10de005c CK804 PCI Bridge 0 d 10de005d CK804 PCIE Bridge 0 d 10de005e CK804 Memory Controller 0 d 10de0060 nForce2 ISA Bridge 0 s 10de0060104380ad A7N8X Mainboard 0 d 10de0064 nForce2 SMBus (MCP) 0 d 10de0065 nForce2 IDE 0 d 10de0066 nForce2 Ethernet Controller 0 s 10de0066104380a7 A7N8X Mainboard onboard nForce2 Ethernet 0 d 10de0067 nForce2 USB Controller 0 s 10de006710430c11 A7N8X Mainboard 0 d 10de0068 nForce2 USB Controller 0 s 10de006810430c11 A7N8X Mainboard 0 d 10de006a nForce2 AC97 Audio Controler (MCP) 0 d 10de006b nForce MultiMedia audio [Via VT82C686B] 0 s 10de006b10de006b nForce2 MCP Audio Processing Unit 0 d 10de006c nForce2 External PCI Bridge 0 d 10de006d nForce2 PCI Bridge 0 d 10de006e nForce2 FireWire (IEEE 1394) Controller 0 d 10de0084 MCP2A SMBus 0 d 10de0085 MCP2A IDE 0 d 10de0086 MCP2A Ethernet Controller 0 d 10de0087 MCP2A USB Controller 0 d 10de0088 MCP2A USB Controller 0 d 10de008a MCP2S AC'97 Audio Controller 0 d 10de008b MCP2A PCI Bridge 0 d 10de008c MCP2A Ethernet Controller 0 d 10de008e nForce2 Serial ATA Controller 0 d 10de00a0 NV5 [Aladdin TNT2] 0 s 10de00a014af5810 Maxi Gamer Xentor 0 d 10de00c0 NV41.0 0 d 10de00c1 NV41.1 0 d 10de00c2 NV41.2 0 d 10de00c8 NV41.8 0 d 10de00ce NV41GL 0 d 10de00d0 nForce3 LPC Bridge 0 d 10de00d1 nForce3 Host Bridge 0 d 10de00d2 nForce3 AGP Bridge 0 d 10de00d3 CK804 Memory Controller 0 d 10de00d4 nForce3 SMBus 0 d 10de00d5 nForce3 IDE 0 d 10de00d6 nForce3 Ethernet 0 d 10de00d7 nForce3 USB 1.1 0 d 10de00d8 nForce3 USB 2.0 0 d 10de00da nForce3 Audio 0 d 10de00dd nForce3 PCI Bridge 0 d 10de00df CK8S Ethernet Controller 0 d 10de00e1 nForce3 250Gb Host Bridge 0 d 10de00e2 nForce3 250Gb AGP Host to PCI Bridge 0 d 10de00e3 CK8S Serial ATA Controller (v2.5) 0 d 10de00e4 nForce 250Gb PCI System Management 0 d 10de00e5 CK8S Parallel ATA Controller (v2.5) 0 d 10de00e6 CK8S Ethernet Controller 0 d 10de00e7 CK8S USB Controller 0 d 10de00e8 CK8S USB Controller 0 d 10de00ea nForce3 250Gb AC'97 Audio Controller 0 d 10de00ed nForce3 250Gb PCI-to-PCI Bridge 0 d 10de00ee CK8S Serial ATA Controller (v2.5) 0 d 10de00f0 NV40 [GeForce 6800/GeForce 6800 Ultra] 0 d 10de00f1 NV43 [GeForce 6600/GeForce 6600 GT] 0 d 10de00f2 NV43 [GeForce 6600 GT] 0 d 10de00f8 NV45GL [Quadro FX 3400] 0 d 10de00f9 NV40 [GeForce 6800 Ultra] 0 d 10de00fa NV36 [GeForce PCX 5750] 0 d 10de00fb NV35 [GeForce PCX 5900] 0 d 10de00fc NV37GL [Quadro FX 330/GeForce PCX 5300] 0 d 10de00fd NV37GL [Quadro FX 330] 0 d 10de00fe NV38GL [Quadro FX 1300] 0 d 10de00ff NV18 [GeForce PCX 4300] 0 d 10de0100 NV10 [GeForce 256 SDR] 0 s 10de010010430200 AGP-V6600 SGRAM 0 s 10de010010430201 AGP-V6600 SDRAM 0 s 10de010010434008 AGP-V6600 SGRAM 0 s 10de010010434009 AGP-V6600 SDRAM 0 s 10de01001102102d CT6941 GeForce 256 0 s 10de010014af5022 3D Prophet SE 0 d 10de0101 NV10DDR [GeForce 256 DDR] 0 s 10de010110430202 AGP-V6800 DDR 0 s 10de01011043400a AGP-V6800 DDR SGRAM 0 s 10de01011043400b AGP-V6800 DDR SDRAM 0 s 10de0101107d2822 WinFast GeForce 256 0 s 10de01011102102e CT6971 GeForce 256 DDR 0 s 10de010114af5021 3D Prophet DDR-DVI 0 d 10de0103 NV10GL [Quadro] 0 d 10de0110 NV11 [GeForce2 MX/MX 400] 0 s 10de011010434015 AGP-V7100 Pro 0 s 10de011010434031 V7100 Pro with TV output 0 s 10de011010de0091 Dell OEM GeForce 2 MX 400 0 s 10de011014628817 MSI GeForce2 MX400 Pro32S [MS-8817] 0 s 10de011014af7102 3D Prophet II MX 0 s 10de011014af7103 3D Prophet II MX Dual-Display 0 d 10de0111 NV11DDR [GeForce2 MX 100 DDR/200 DDR] 0 d 10de0112 NV11 [GeForce2 Go] 0 d 10de0113 NV11GL [Quadro2 MXR/EX] 0 d 10de0150 NV15 [GeForce2 GTS/Pro] 0 s 10de015010434016 V7700 AGP Video Card 0 s 10de0150107d2840 WinFast GeForce2 GTS with TV output 0 s 10de0150107d2842 WinFast GeForce 2 Pro 0 s 10de015014628831 Creative GeForce2 Pro 0 d 10de0151 NV15DDR [GeForce2 Ti] 0 s 10de01511043405f V7700Ti 0 s 10de015114625506 Creative 3D Blaster Geforce2 Titanium 0 d 10de0152 NV15BR [GeForce2 Ultra, Bladerunner] 0 s 10de015210480c56 GLADIAC Ultra 0 d 10de0153 NV15GL [Quadro2 Pro] 0 d 10de0170 NV17 [GeForce4 MX 460] 0 d 10de0171 NV17 [GeForce4 MX 440] 0 s 10de017110b00002 Gainward Pro/600 TV 0 s 10de017114628661 G4MX440-VTP 0 s 10de017114628730 MX440SES-T (MS-8873) 0 s 10de0171147b8f00 Abit Siluro GeForce4MX440 0 d 10de0172 NV17 [GeForce4 MX 420] 0 d 10de0173 NV17 [GeForce4 MX 440-SE] 0 d 10de0174 NV17 [GeForce4 440 Go] 0 d 10de0175 NV17 [GeForce4 420 Go] 0 d 10de0176 NV17 [GeForce4 420 Go 32M] 0 s 10de01764c531090 Cx9 / Vx9 mainboard 0 d 10de0177 NV17 [GeForce4 460 Go] 0 d 10de0178 NV17GL [Quadro4 550 XGL] 0 d 10de0179 NV17 [GeForce4 440 Go 64M] 0 s 10de017910de0179 GeForce4 MX (Mac) 0 d 10de017a NV17GL [Quadro4 200/400 NVS] 0 d 10de017b NV17GL [Quadro4 550 XGL] 0 d 10de017c NV17GL [Quadro4 550 GoGL] 0 d 10de017d NV17 [GeForce4 410 Go 16M] 0 d 10de0181 NV18 [GeForce4 MX 440 AGP 8x] 0 s 10de01811043806f V9180 Magic 0 s 10de018114628880 MS-StarForce GeForce4 MX 440 with AGP8X 0 s 10de018114628900 MS-8890 GeForce 4 MX440 AGP8X 0 s 10de018114629350 MSI Geforce4 MX T8X with AGP8X 0 s 10de0181147b8f0d Siluro GF4 MX-8X 0 d 10de0182 NV18 [GeForce4 MX 440SE AGP 8x] 0 d 10de0183 NV18 [GeForce4 MX 420 AGP 8x] 0 d 10de0185 NV18 [GeForce4 MX 4000 AGP 8x] 0 d 10de0186 NV18M [GeForce4 448 Go] 0 d 10de0187 NV18M [GeForce4 488 Go] 0 d 10de0188 NV18GL [Quadro4 580 XGL] 0 d 10de018a NV18GL [Quadro4 NVS AGP 8x] 0 d 10de018b NV18GL [Quadro4 380 XGL] 0 d 10de018d NV18M [GeForce4 448 Go] 0 d 10de01a0 NVCrush11 [GeForce2 MX Integrated Graphics] 0 d 10de01a4 nForce CPU bridge 0 d 10de01ab nForce 420 Memory Controller (DDR) 0 d 10de01ac nForce 220/420 Memory Controller 0 d 10de01ad nForce 220/420 Memory Controller 0 d 10de01b0 nForce Audio 0 d 10de01b1 nForce Audio 0 d 10de01b2 nForce ISA Bridge 0 d 10de01b4 nForce PCI System Management 0 d 10de01b7 nForce AGP to PCI Bridge 0 d 10de01b8 nForce PCI-to-PCI bridge 0 d 10de01bc nForce IDE 0 d 10de01c1 nForce AC'97 Modem Controller 0 d 10de01c2 nForce USB Controller 0 d 10de01c3 nForce Ethernet Controller 0 d 10de01e0 nForce2 AGP (different version?) 0 d 10de01e8 nForce2 AGP 0 d 10de01ea nForce2 Memory Controller 0 0 d 10de01eb nForce2 Memory Controller 1 0 d 10de01ec nForce2 Memory Controller 2 0 d 10de01ed nForce2 Memory Controller 3 0 d 10de01ee nForce2 Memory Controller 4 0 d 10de01ef nForce2 Memory Controller 5 0 d 10de01f0 NV18 [GeForce4 MX - nForce GPU] 0 d 10de0200 NV20 [GeForce3] 0 s 10de02001043402f AGP-V8200 DDR 0 d 10de0201 NV20 [GeForce3 Ti 200] 0 d 10de0202 NV20 [GeForce3 Ti 500] 0 s 10de02021043405b V8200 T5 0 s 10de02021545002f Xtasy 6964 0 d 10de0203 NV20DCC [Quadro DCC] 0 d 10de0250 NV25 [GeForce4 Ti 4600] 0 d 10de0251 NV25 [GeForce4 Ti 4400] 0 s 10de025110438023 v8440 GeForce 4 Ti4400 0 d 10de0252 NV25 [GeForce4 Ti] 0 d 10de0253 NV25 [GeForce4 Ti 4200] 0 s 10de0253107d2896 WinFast A250 LE TD (Dual VGA/TV-out/DVI) 0 s 10de0253147b8f09 Siluro (Dual VGA/TV-out/DVI) 0 d 10de0258 NV25GL [Quadro4 900 XGL] 0 d 10de0259 NV25GL [Quadro4 750 XGL] 0 d 10de025b NV25GL [Quadro4 700 XGL] 0 d 10de0280 NV28 [GeForce4 Ti 4800] 0 d 10de0281 NV28 [GeForce4 Ti 4200 AGP 8x] 0 d 10de0282 NV28 [GeForce4 Ti 4800 SE] 0 d 10de0286 NV28 [GeForce4 Ti 4200 Go AGP 8x] 0 d 10de0288 NV28GL [Quadro4 980 XGL] 0 d 10de0289 NV28GL [Quadro4 780 XGL] 0 d 10de028c NV28GLM [Quadro4 700 GoGL] 0 d 10de0300 NV30 [GeForce FX] 0 d 10de0301 NV30 [GeForce FX 5800 Ultra] 0 d 10de0302 NV30 [GeForce FX 5800] 0 d 10de0308 NV30GL [Quadro FX 2000] 0 d 10de0309 NV30GL [Quadro FX 1000] 0 d 10de0311 NV31 [GeForce FX 5600 Ultra] 0 d 10de0312 NV31 [GeForce FX 5600] 0 d 10de0313 NV31 0 d 10de0314 NV31 [GeForce FX 5600XT] 0 s 10de03141043814a V9560XT/TD 0 d 10de0316 NV31 0 d 10de0317 NV31 0 d 10de031a NV31M [GeForce FX Go 5600] 0 d 10de031b NV31M [GeForce FX Go5650] 0 d 10de031c NVIDIA Quadro FX 700 Go 0 d 10de031d NV31 0 d 10de031e NV31 0 d 10de031f NV31 0 d 10de0320 NV34 [GeForce FX 5200] 0 d 10de0321 NV34 [GeForce FX 5200 Ultra] 0 d 10de0322 NV34 [GeForce FX 5200] 0 s 10de032214629171 MS-8917 (FX5200-T128) 0 d 10de0323 NV34 [GeForce FX 5200LE] 0 d 10de0324 NV34M [GeForce FX Go 5200] 0 s 10de032410718160 MIM2000 0 d 10de0325 NV34M [GeForce FX Go5250] 0 d 10de0326 NV34 [GeForce FX 5500] 0 d 10de0327 NV34 [GeForce FX 5100] 0 d 10de0328 NV34M [GeForce FX Go 5200] 0 d 10de0329 NV34M [GeForce FX Go5200] 0 d 10de032a NV34GL [Quadro NVS 280 PCI] 0 d 10de032b NV34GL [Quadro FX 500/600 PCI] 0 d 10de032c NV34GLM [GeForce FX Go 5300] 0 d 10de032d NV34 [GeForce FX Go5100] 0 d 10de032f NV34 0 d 10de0330 NV35 [GeForce FX 5900 Ultra] 0 d 10de0331 NV35 [GeForce FX 5900] 0 s 10de033110438145 V9950GE 0 d 10de0332 NV35 [GeForce FX 5900XT] 0 d 10de0333 NV38 [GeForce FX 5950 Ultra] 0 d 10de0334 NV35 [GeForce FX 5900ZT] 0 d 10de0338 NV35GL [Quadro FX 3000] 0 d 10de033f NV35GL [Quadro FX 700] 0 d 10de0341 NV36.1 [GeForce FX 5700 Ultra] 0 d 10de0342 NV36.2 [GeForce FX 5700] 0 d 10de0343 NV36 [GeForce FX 5700LE] 0 d 10de0344 NV36.4 [GeForce FX 5700VE] 0 d 10de0345 NV36.5 0 d 10de0347 NV36 [GeForce FX Go5700] 0 d 10de0348 NV36 [GeForce FX Go5700] 0 d 10de0349 NV36 0 d 10de034b NV36 0 d 10de034c NV36 [Quadro FX Go1000] 0 d 10de034e NV36GL [Quadro FX 1100] 0 d 10de034f NV36GL 0 v 10df Emulex Corporation 0 d 10df1ae5 LP6000 Fibre Channel Host Adapter 0 d 10df1ae6 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2) 0 d 10df1ae7 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:2-3) 0 d 10dff015 LP1150e 0 d 10dff085 LP850 Fibre Channel Adapter 0 d 10dff095 LP952 Fibre Channel Adapter 0 d 10dff098 LP982 Fibre Channel Adapter 0 d 10dff0a1 LightPulse Fibre Channel Adapter 0 d 10dff0a5 LP1050 0 d 10dff0d5 LP1150 0 d 10dff100 LP11000e 0 d 10dff700 LP7000 Fibre Channel Host Adapter 0 d 10dff701 LP 7000EFibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2) 0 d 10dff800 LP8000 Fibre Channel Host Adapter 0 d 10dff801 LP 8000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2) 0 d 10dff900 LP9000 Fibre Channel Host Adapter 0 d 10dff901 LP 9000 Fibre Channel Host Adapter Alternate ID (JX1:2-3, JX2:1-2) 0 d 10dff980 LP9802 Fibre Channel Adapter 0 d 10dff981 LP 9802 Fibre Channel Host Adapter Alternate ID 0 d 10dff982 LP 9802 Fibre Channel Host Adapter Alternate ID 0 d 10dffa00 LP10000 Fibre Channel Host Adapter 0 d 10dffa01 LP101 0 d 10dffb00 LightPulse Fibre Channel Adapter 0 d 10dffd00 LP11000 0 v 10e0 Integrated Micro Solutions Inc. 0 d 10e05026 IMS5026/27/28 0 d 10e05027 IMS5027 0 d 10e05028 IMS5028 0 d 10e08849 IMS8849 0 d 10e08853 IMS8853 0 d 10e09128 IMS9128 [Twin turbo 128] 0 v 10e1 Tekram Technology Co.,Ltd. 0 d 10e10391 TRM-S1040 0 s 10e1039110e10391 DC-315U SCSI-3 Host Adapter 0 d 10e1690c DC-690c 0 d 10e1dc29 DC-290 0 v 10e2 Aptix Corporation 0 v 10e3 Tundra Semiconductor Corp. 0 d 10e30000 CA91C042 [Universe] 0 d 10e30860 CA91C860 [QSpan] 0 d 10e30862 CA91C862A [QSpan-II] 0 d 10e38260 CA91L8200B [Dual PCI PowerSpan II] 0 d 10e38261 CA91L8260B [Single PCI PowerSpan II] 0 v 10e4 Tandem Computers 0 v 10e5 Micro Industries Corporation 0 v 10e6 Gainbery Computer Products Inc. 0 v 10e7 Vadem 0 v 10e8 Applied Micro Circuits Corp. 0 d 10e81072 INES GPIB-PCI (AMCC5920 based) 0 d 10e82011 Q-Motion Video Capture/Edit board 0 d 10e84750 S5930 [Matchmaker] 0 d 10e85920 S5920 0 d 10e88043 LANai4.x [Myrinet LANai interface chip] 0 d 10e88062 S5933_PARASTATION 0 d 10e8807d S5933 [Matchmaker] 0 d 10e88088 Kongsberg Spacetec Format Synchronizer 0 d 10e88089 Kongsberg Spacetec Serial Output Board 0 d 10e8809c S5933_HEPC3 0 d 10e880d7 PCI-9112 0 d 10e880d9 PCI-9118 0 d 10e880da PCI-9812 0 d 10e8811a PCI-IEEE1355-DS-DE Interface 0 d 10e8814c Fastcom ESCC-PCI (Commtech, Inc.) 0 d 10e88170 S5933 [Matchmaker] (Chipset Development Tool) 0 d 10e881e6 Multimedia video controller 0 sold with Roper Scientifc(Photometrics) CoolSnap HQ camera d 10e88291 Fastcom 232/8-PCI (Commtech, Inc.) 0 d 10e882c4 Fastcom 422/4-PCI (Commtech, Inc.) 0 d 10e882c5 Fastcom 422/2-PCI (Commtech, Inc.) 0 d 10e882c6 Fastcom IG422/1-PCI (Commtech, Inc.) 0 d 10e882c7 Fastcom IG232/2-PCI (Commtech, Inc.) 0 d 10e882ca Fastcom 232/4-PCI (Commtech, Inc.) 0 d 10e882db AJA HDNTV HD SDI Framestore 0 d 10e882e2 Fastcom DIO24H-PCI (Commtech, Inc.) 0 d 10e88851 S5933 on Innes Corp FM Radio Capture card 0 v 10e9 Alps Electric Co., Ltd. 0 v 10ea Intergraphics Systems 0 d 10ea1680 IGA-1680 0 d 10ea1682 IGA-1682 0 d 10ea1683 IGA-1683 0 d 10ea2000 CyberPro 2000 0 d 10ea2010 CyberPro 2000A 0 d 10ea5000 CyberPro 5000 0 d 10ea5050 CyberPro 5050 0 d 10ea5202 CyberPro 5202 0 d 10ea5252 CyberPro5252 0 CyberPro5202 Audio Function v 10eb Artists Graphics 0 d 10eb0101 3GA 0 d 10eb8111 Twist3 Frame Grabber 0 v 10ec Realtek Semiconductor Co., Ltd. 0 d 10ec8029 RTL-8029(AS) 0 s 10ec802910b82011 EZ-Card (SMC1208) 0 s 10ec802910ec8029 RTL-8029(AS) 0 s 10ec802911131208 EN1208 0 s 10ec802911860300 DE-528 0 s 10ec802912592400 AT-2400 0 d 10ec8129 RTL-8129 0 s 10ec812910ec8129 RT8129 Fast Ethernet Adapter 0 d 10ec8138 RT8139 (B/C) Cardbus Fast Ethernet Adapter 0 s 10ec813810ec8138 RT8139 (B/C) Fast Ethernet Adapter 0 d 10ec8139 RTL-8139/8139C/8139C+ 0 s 10ec81390357000a TTP-Monitoring Card V2.0 0 s 10ec81391025005a TravelMate 290 0 s 10ec813910258920 ALN-325 0 s 10ec813910258921 ALN-325 0 s 10ec813910718160 MIM2000 0 s 10ec813910bd0320 EP-320X-R 0 s 10ec813910ec8139 RT8139 0 s 10ec81391113ec01 FNC-0107TX 0 s 10ec813911861300 DFE-538TX 0 s 10ec813911861320 SN5200 0 s 10ec813911868139 DRN-32TX 0 s 10ec813911f68139 FN22-3(A) LinxPRO Ethernet Adapter 0 s 10ec813912592500 AT-2500TX 0 s 10ec813912592503 AT-2500TX/ACPI 0 s 10ec81391429d010 ND010 0 s 10ec813914329130 EN-9130TX 0 s 10ec813914368139 RT8139 0 s 10ec81391458e000 GA-7VM400M/7VT600 Motherboard 0 s 10ec8139146c1439 FE-1439TX 0 s 10ec813914896001 GF100TXRII 0 s 10ec813914896002 GF100TXRA 0 s 10ec8139149c139a LFE-8139ATX 0 s 10ec8139149c8139 LFE-8139TX 0 s 10ec813914cb0200 LNR-100 Family 10/100 Base-TX Ethernet 0 s 10ec813917995000 F5D5000 PCI Card/Desktop Network PCI Card 0 s 10ec813926460001 EtheRx 0 s 10ec81398e2e7000 KF-230TX 0 s 10ec81398e2e7100 KF-230TX/2 0 s 10ec8139a0a00007 ALN-325C 0 d 10ec8169 RTL-8169 Gigabit Ethernet 0 s 10ec81691259c107 CG-LAPCIGT 0 s 10ec81691371434e ProG-2000L 0 s 10ec81691458e000 GA-K8VT800 Pro Motherboard 0 s 10ec81691462702c K8T NEO 2 motherboard 0 d 10ec8180 RTL8180L 802.11b MAC 0 d 10ec8197 SmartLAN56 56K Modem 0 v 10ed Ascii Corporation 0 d 10ed7310 V7310 0 v 10ee Xilinx Corporation 0 d 10ee3fc0 RME Digi96 0 d 10ee3fc1 RME Digi96/8 0 d 10ee3fc2 RME Digi96/8 Pro 0 d 10ee3fc3 RME Digi96/8 Pad 0 d 10ee3fc4 RME Digi9652 (Hammerfall) 0 d 10ee3fc5 RME Hammerfall DSP 0 d 10ee3fc6 RME Hammerfall DSP MADI 0 d 10ee8381 Ellips Santos Frame Grabber 0 v 10ef Racore Computer Products, Inc. 0 d 10ef8154 M815x Token Ring Adapter 0 v 10f0 Peritek Corporation 0 v 10f1 Tyan Computer 0 v 10f2 Achme Computer, Inc. 0 v 10f3 Alaris, Inc. 0 v 10f4 S-MOS Systems, Inc. 0 v 10f5 NKK Corporation 0 d 10f5a001 NDR4000 [NR4600 Bridge] 0 v 10f6 Creative Electronic Systems SA 0 v 10f7 Matsushita Electric Industrial Co., Ltd. 0 v 10f8 Altos India Ltd 0 v 10f9 PC Direct 0 v 10fa Truevision 0 d 10fa000c TARGA 1000 0 v 10fb Thesys Gesellschaft fr Mikroelektronik mbH 0 d 10fb186f TH 6255 0 v 10fc I-O Data Device, Inc. 0 d 10fc0003 Cardbus IDE Controller 0 What's in the cardbus end of a Sony ACR-A01 card, comes with newer Vaio CD-RW drives d 10fc0005 Cardbus SCSI CBSC II 0 v 10fd Soyo Computer, Inc 0 v 10fe Fast Multimedia AG 0 v 10ff NCube 0 v 1100 Jazz Multimedia 0 v 1101 Initio Corporation 0 d 11011060 INI-A100U2W 0 d 11019100 INI-9100/9100W 0 d 11019400 INI-940 0 d 11019401 INI-950 0 d 11019500 360P 0 d 11019502 Initio INI-9100UW Ultra Wide SCSI Controller INIC-950P chip 0 v 1102 Creative Labs 0 d 11020002 SB Live! EMU10k1 0 s 1102000211020020 CT4850 SBLive! Value 0 s 1102000211020021 CT4620 SBLive! 0 s 110200021102002f SBLive! mainboard implementation 0 s 1102000211024001 E-mu APS 0 s 1102000211028022 CT4780 SBLive! Value 0 s 1102000211028023 CT4790 SoundBlaster PCI512 0 s 1102000211028024 CT4760 SBLive! 0 s 1102000211028025 SBLive! Mainboard Implementation 0 s 1102000211028026 CT4830 SBLive! Value 0 s 1102000211028027 CT4832 SBLive! Value 0 s 1102000211028028 CT4760 SBLive! OEM version 0 s 1102000211028031 CT4831 SBLive! Value 0 s 1102000211028040 CT4760 SBLive! 0 s 1102000211028051 CT4850 SBLive! Value 0 s 1102000211028061 SBLive! Player 5.1 0 s 1102000211028064 SB Live! 5.1 Model SB0100 0 s 1102000211028065 SBLive! 5.1 Digital Model SB0220 0 s 1102000211028067 SBLive! 5.1 eMicro 28028 0 d 11020004 SB Audigy 0 s 1102000411020051 SB0090 Audigy Player 0 s 1102000411020053 SB0090 Audigy Player/OEM 0 s 1102000411020058 SB0090 Audigy Player/OEM 0 s 1102000411022002 SB Audigy 2 ZS (SB0350) 0 d 11020006 [SB Live! Value] EMU10k1X 0 d 11020007 SB Audigy LS 0 s 1102000711021001 SB0310 Audigy LS 0 s 1102000711021002 SB0312 Audigy LS 0 d 11020008 SB0400 Audigy2 Value 0 d 11024001 SB Audigy FireWire Port 0 s 1102400111020010 SB Audigy FireWire Port 0 d 11027002 SB Live! MIDI/Game Port 0 s 1102700211020020 Gameport Joystick 0 d 11027003 SB Audigy MIDI/Game port 0 s 1102700311020040 SB Audigy MIDI/Game Port 0 d 11027004 [SB Live! Value] Input device controller 0 d 11027005 SB Audigy LS MIDI/Game port 0 s 1102700511021001 SB0310 Audigy LS MIDI/Game port 0 s 1102700511021002 SB0312 Audigy LS MIDI/Game port 0 d 11028064 SB0100 [SBLive! 5.1 OEM] 0 d 11028938 Ectiva EV1938 0 v 1103 Triones Technologies, Inc. 0 d 11030003 HPT343 0 d 11030004 HPT366/368/370/370A/372 0 Revisions: 01=HPT366, 03=HPT370, 04=HPT370A, 05=HPT372 s 1103000411030001 HPT370A 0 s 1103000411030003 HPT343 / HPT345 / HPT363 UDMA33 0 s 1103000411030004 HPT366 UDMA66 (r1) / HPT368 UDMA66 (r2) / HPT370 UDMA100 (r3) / HPT370 UDMA100 RAID (r4) 0 s 1103000411030005 HPT370 UDMA100 0 s 1103000411030006 HPT302 0 s 1103000411030007 HPT371 UDMA133 0 s 1103000411030008 HPT374 UDMA/ATA133 RAID Controller 0 d 11030005 HPT372A 0 d 11030006 HPT302 0 d 11030007 HPT371 0 d 11030008 HPT374 0 d 11030009 HPT372N 0 v 1104 RasterOps Corp. 0 v 1105 Sigma Designs, Inc. 0 d 11051105 REALmagic Xcard MPEG 1/2/3/4 DVD Decoder 0 d 11058300 REALmagic Hollywood Plus DVD Decoder 0 d 11058400 EM840x REALmagic DVD/MPEG-2 Audio/Video Decoder 0 d 11058401 EM8401 REALmagic DVD/MPEG-2 A/V Decoder 0 d 11058470 EM8470 REALmagic DVD/MPEG-4 A/V Decoder 0 d 11058471 EM8471 REALmagic DVD/MPEG-4 A/V Decoder 0 d 11058475 EM8475 REALmagic DVD/MPEG-4 A/V Decoder 0 d 11058476 EM8476 REALmagic DVD/MPEG-4 A/V Decoder 0 d 11058485 EM8485 REALmagic DVD/MPEG-4 A/V Decoder 0 d 11058486 EM8486 REALmagic DVD/MPEG-4 A/V Decoder 0 v 1106 VIA Technologies, Inc. 0 d 11060102 Embedded VIA Ethernet Controller 0 d 11060130 VT6305 1394.A Controller 0 d 11060305 VT8363/8365 [KT133/KM133] 0 s 1106030510438033 A7V Mainboard 0 s 110603051043803e A7V-E Mainboard 0 s 1106030510438042 A7V133/A7V133-C Mainboard 0 s 11060305147ba401 KT7/KT7-RAID/KT7A/KT7A-RAID Mainboard 0 d 11060391 VT8371 [KX133] 0 d 11060501 VT8501 [Apollo MVP4] 0 d 11060505 VT82C505 0 d 11060561 VT82C576MV 0 Shares chip with :0576. The VT82C576M has :1571 instead of :0561. d 11060571 VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE 0 s 1106057110190985 P6VXA Motherboard 0 s 1106057110190a81 L7VTA v1.0 Motherboard (KT400-8235) 0 s 1106057110438052 VT8233A Bus Master ATA100/66/33 IDE 0 s 110605711043808c A7V8X motherboard 0 s 11060571104380a1 A7V8X-X motherboard rev. 1.01 0 s 11060571104380ed A7V600 motherboard 0 s 1106057111060571 VT82C586/B/VT82C686/A/B/VT8233/A/C/VT8235 PIPC Bus Master IDE 0 s 1106057111790001 Magnia Z310 0 s 110605711297f641 FX41 motherboard 0 s 1106057114585002 GA-7VAX Mainboard 0 s 1106057114627020 K8T NEO 2 motherboard 0 s 11060571147b1407 KV8-MAX3 motherboard 0 s 1106057118490571 K7VT2 motherboard 0 d 11060576 VT82C576 3V [Apollo Master] 0 d 11060585 VT82C585VP [Apollo VP1/VPX] 0 d 11060586 VT82C586/A/B PCI-to-ISA [Apollo VP] 0 s 1106058611060000 MVP3 ISA Bridge 0 d 11060595 VT82C595 [Apollo VP2] 0 d 11060596 VT82C596 ISA [Mobile South] 0 s 1106059611060000 VT82C596/A/B PCI to ISA Bridge 0 s 1106059614580596 VT82C596/A/B PCI to ISA Bridge 0 d 11060597 VT82C597 [Apollo VP3] 0 d 11060598 VT82C598 [Apollo MVP3] 0 d 11060601 VT8601 [Apollo ProMedia] 0 d 11060605 VT8605 [ProSavage PM133] 0 s 110606051043802c CUV4X mainboard 0 d 11060680 VT82C680 [Apollo P6] 0 d 11060686 VT82C686 [Apollo Super South] 0 s 1106068610190985 P6VXA Motherboard 0 s 110606861043802c CUV4X mainboard 0 s 1106068610438033 A7V Mainboard 0 s 110606861043803e A7V-E Mainboard 0 s 1106068610438040 A7M266 Mainboard 0 s 1106068610438042 A7V133/A7V133-C Mainboard 0 s 1106068611060000 VT82C686/A PCI to ISA Bridge 0 s 1106068611060686 VT82C686/A PCI to ISA Bridge 0 s 1106068611790001 Magnia Z310 0 s 11060686147ba702 KG7-Lite Mainboard 0 d 11060691 VT82C693A/694x [Apollo PRO133x] 0 s 1106069110190985 P6VXA Motherboard 0 s 1106069111790001 Magnia Z310 0 s 1106069114580691 VT82C691 Apollo Pro System Controller 0 d 11060693 VT82C693 [Apollo Pro Plus] 0 d 11060698 VT82C693A [Apollo Pro133 AGP] 0 d 11060926 VT82C926 [Amazon] 0 d 11061000 VT82C570MV 0 d 11061106 VT82C570MV 0 d 11061571 VT82C576M/VT82C586 0 d 11061595 VT82C595/97 [Apollo VP2/97] 0 d 11063022 CLE266 0 d 11063038 VT82xxxxx UHCI USB 1.1 Controller 0 This is *not* USB 2.0 as the existing entry suggests s 1106303809251234 USB Controller 0 s 1106303810190985 P6VXA Motherboard 0 s 1106303810190a81 L7VTA v1.0 Motherboard (KT400-8235) 0 s 110630381043808c VT6202 USB2.0 4 port controller 0 s 11063038104380a1 A7V8X-X motherboard 0 s 11063038104380ed A7V600 motherboard 0 s 1106303811790001 Magnia Z310 0 s 1106303814585004 GA-7VAX Mainboard 0 s 1106303814627020 K8T NEO 2 motherboard 0 s 11063038147b1407 KV8-MAX3 motherboard 0 d 11063040 VT82C586B ACPI 0 d 11063043 VT86C100A [Rhine] 0 s 1106304310bd0000 VT86C100A Fast Ethernet Adapter 0 s 1106304311060100 VT86C100A Fast Ethernet Adapter 0 s 1106304311861400 DFE-530TX rev A 0 d 11063044 IEEE 1394 Host Controller 0 s 110630441025005a TravelMate 290 0 s 1106304414581000 GA-7VT600-1394 Motherboard 0 s 110630441462702d K8T NEO 2 motherboard 0 d 11063050 VT82C596 Power Management 0 d 11063051 VT82C596 Power Management 0 d 11063053 VT6105M [Rhine-III] 0 d 11063057 VT82C686 [Apollo Super ACPI] 0 s 1106305710190985 P6VXA Motherboard 0 s 1106305710438033 A7V Mainboard 0 s 110630571043803e A7V-E Mainboard 0 s 1106305710438040 A7M266 Mainboard 0 s 1106305710438042 A7V133/A7V133-C Mainboard 0 s 1106305711790001 Magnia Z310 0 d 11063058 VT82C686 AC97 Audio Controller 0 s 110630580e110097 SoundMax Digital Integrated Audio 0 s 110630580e11b194 Soundmax integrated digital audio 0 s 1106305810190985 P6VXA Motherboard 0 s 1106305810431106 A7V133/A7V133-C Mainboard 0 s 1106305811064511 Onboard Audio on EP7KXA 0 s 1106305814587600 Onboard Audio 0 s 1106305814623091 MS-6309 Onboard Audio 0 s 1106305814623300 MS-6330 Onboard Audio 0 s 1106305815dd7609 Onboard Audio 0 d 11063059 VT8233/A/8235/8237 AC97 Audio Controller 0 s 1106305910190a81 L7VTA v1.0 Motherboard (KT400-8235) 0 s 1106305910438095 A7V8X Motherboard (Realtek ALC650 codec) 0 s 11063059104380a1 A7V8X-X Motherboard 0 s 11063059104380b0 A7V600 motherboard (ADI AD1980 codec [SoundMAX]) 0 s 1106305911063059 L7VMM2 Motherboard 0 s 1106305911064161 K7VT2 motherboard 0 s 110630591297c160 FX41 motherboard (Realtek ALC650 codec) 0 s 110630591458a002 GA-7VAX Onboard Audio (Realtek ALC650) 0 s 1106305914620080 K8T NEO 2 motherboard 0 s 1106305914623800 KT266 onboard audio 0 s 11063059147b1407 KV8-MAX3 motherboard 0 d 11063065 VT6102 [Rhine-II] 0 s 11063065104380a1 A7V8X-X Motherboard 0 s 1106306511060102 VT6102 [Rhine II] Embeded Ethernet Controller on VT8235 0 s 1106306511861400 DFE-530TX rev A 0 s 1106306511861401 DFE-530TX rev B 0 s 1106306513b91421 LD-10/100AL PCI Fast Ethernet Adapter (rev.B) 0 d 11063068 AC'97 Modem Controller 0 This hosts more than just the Intel 537 codec, it also hosts PCtel (SIL33) and SmartLink (SIL34) codecs s 110630681462309e MS-6309 Saturn Motherboard 0 d 11063074 VT8233 PCI to ISA Bridge 0 s 1106307410438052 VT8233A 0 d 11063091 VT8633 [Apollo Pro266] 0 d 11063099 VT8366/A/7 [Apollo KT266/A/333] 0 s 1106309910438064 A7V266-E Mainboard 0 s 110630991043807f A7V333 Mainboard 0 s 1106309918493099 K7VT2 motherboard 0 d 11063101 VT8653 Host Bridge 0 d 11063102 VT8662 Host Bridge 0 d 11063103 VT8615 Host Bridge 0 d 11063104 USB 2.0 0 s 1106310410190a81 L7VTA v1.0 Motherboard (KT400-8235) 0 s 110631041043808c A7V8X motherboard 0 s 11063104104380a1 A7V8X-X motherboard rev 1.01 0 s 11063104104380ed A7V600 motherboard 0 s 110631041297f641 FX41 motherboard 0 s 1106310414585004 GA-7VAX Mainboard 0 s 1106310414627020 K8T NEO 2 motherboard 0 s 11063104147b1407 KV8-MAX3 motherboard 0 d 11063106 VT6105 [Rhine-III] 0 s 1106310611861403 DFE-530TX rev C 0 d 11063108 S3 Unichrome Pro VGA Adapter 0 d 11063109 VT8233C PCI to ISA Bridge 0 d 11063112 VT8361 [KLE133] Host Bridge 0 d 11063116 VT8375 [KM266/KL266] Host Bridge 0 s 110631161297f641 FX41 motherboard 0 d 11063118 S3 Unichrome Pro VGA Adapter 0 d 11063119 VT6120/VT6121/VT6122 Gigabit Ethernet Adapter 0 d 11063122 VT8623 [Apollo CLE266] integrated CastleRock graphics 0 found on EPIA M6000/9000 mainboard d 11063123 VT8623 [Apollo CLE266] 0 found on EPIA M6000/9000 mainboard d 11063128 VT8753 [P4X266 AGP] 0 d 11063133 VT3133 Host Bridge 0 d 11063147 VT8233A ISA Bridge 0 d 11063148 P4M266 Host Bridge 0 d 11063149 VIA VT6420 SATA RAID Controller 0 s 11063149104380ed A7V600 motherboard 0 s 110631491458b003 GA-7VM400AM(F) Motherboard 0 s 1106314914627020 K8T Neo 2 Motherboard 0 d 11063156 P/KN266 Host Bridge 0 d 11063164 VT6410 ATA133 RAID controller 0 on ASUS P4P800 d 11063168 VT8374 P4X400 Host Controller/AGP Bridge 0 d 11063177 VT8235 ISA Bridge 0 s 1106317710190a81 L7VTA v1.0 Motherboard (KT400-8235) 0 s 110631771043808c A7V8X motherboard 0 s 11063177104380a1 A7V8X-X motherboard 0 s 110631771297f641 FX41 motherboard 0 s 1106317714585001 GA-7VAX Mainboard 0 s 1106317718493177 K7VT2 motherboard 0 d 11063188 VT8385 [K8T800 AGP] Host Bridge 0 s 11063188147b1407 KV8-MAX3 motherboard 0 d 11063189 VT8377 [KT400/KT600 AGP] Host Bridge 0 s 110631891043807f A7V8X motherboard 0 s 1106318914585000 GA-7VAX Mainboard 0 d 11063204 K8M800 0 d 11063205 VT8378 [KM400/A] Chipset Host Bridge 0 s 1106320514585000 GA-7VM400M Motherboard 0 d 11063227 VT8237 ISA bridge [KT600/K8T800 South] 0 s 11063227104380ed A7V600 motherboard 0 s 1106322711063227 DFI KT600-AL Motherboard 0 s 1106322714585001 GA-7VT600 Motherboard 0 s 11063227147b1407 KV8-MAX3 motherboard 0 d 11064149 VIA VT6420 (ATA133) Controller 0 d 11065030 VT82C596 ACPI [Apollo PRO] 0 d 11066100 VT85C100A [Rhine II] 0 d 11067204 K8M800 0 d 11067205 VT8378 [S3 UniChrome] Integrated Video 0 S3 Graphics UniChrome™ 2D/3D Graphics with motion compensation s 110672051458d000 Gigabyte GA-7VM400(A)M(F) Motherboard 0 d 11068231 VT8231 [PCI-to-ISA Bridge] 0 d 11068235 VT8235 ACPI 0 d 11068305 VT8363/8365 [KT133/KM133 AGP] 0 d 11068391 VT8371 [KX133 AGP] 0 d 11068501 VT8501 [Apollo MVP4 AGP] 0 d 11068596 VT82C596 [Apollo PRO AGP] 0 d 11068597 VT82C597 [Apollo VP3 AGP] 0 d 11068598 VT82C598/694x [Apollo MVP3/Pro133x AGP] 0 s 1106859810190985 P6VXA Motherboard 0 d 11068601 VT8601 [Apollo ProMedia AGP] 0 d 11068605 VT8605 [PM133 AGP] 0 d 11068691 VT82C691 [Apollo Pro] 0 d 11068693 VT82C693 [Apollo Pro Plus] PCI Bridge 0 d 1106b091 VT8633 [Apollo Pro266 AGP] 0 d 1106b099 VT8366/A/7 [Apollo KT266/A/333 AGP] 0 d 1106b101 VT8653 AGP Bridge 0 d 1106b102 VT8362 AGP Bridge 0 d 1106b103 VT8615 AGP Bridge 0 d 1106b112 VT8361 [KLE133] AGP Bridge 0 d 1106b168 VT8235 PCI Bridge 0 d 1106b188 VT8237 PCI bridge [K8T800 South] 0 s 1106b188147b1407 KV8-MAX3 motherboard 0 d 1106b198 VT8237 PCI Bridge 0 d 1106d104 VT8237 Integrated Fast Ethernet Controller 0 32-Bit PCI bus master Ethernet MAC with standard MII interface v 1107 Stratus Computers 0 d 11070576 VIA VT82C570MV [Apollo] (Wrong vendor ID!) 0 v 1108 Proteon, Inc. 0 d 11080100 p1690plus_AA 0 d 11080101 p1690plus_AB 0 d 11080105 P1690Plus 0 d 11080108 P1690Plus 0 d 11080138 P1690Plus 0 d 11080139 P1690Plus 0 d 1108013c P1690Plus 0 d 1108013d P1690Plus 0 v 1109 Cogent Data Technologies, Inc. 0 d 11091400 EM110TX [EX110TX] 0 v 110a Siemens Nixdorf AG 0 d 110a0002 Pirahna 2-port 0 d 110a0005 Tulip controller, power management, switch extender 0 d 110a0006 FSC PINC (I/O-APIC) 0 d 110a0015 FSC Multiprocessor Interrupt Controller 0 d 110a001d FSC Copernicus Management Controller 0 d 110a007b FSC Remote Service Controller, mailbox device 0 d 110a007c FSC Remote Service Controller, shared memory device 0 d 110a007d FSC Remote Service Controller, SMIC device 0 d 110a2102 DSCC4 WAN adapter 0 d 110a2104 Eicon Diva 2.02 compatible passive ISDN card 0 d 110a3142 SIMATIC NET CP 5613A1 (Profibus Adapter) 0 d 110a4021 SIMATIC NET CP 5512 (Profibus and MPI Cardbus Adapter) 0 d 110a4029 SIMATIC NET CP 5613A2 (Profibus Adapter) 0 d 110a4942 FPGA I-Bus Tracer for MBD 0 d 110a6120 SZB6120 0 v 110b Chromatic Research Inc. 0 d 110b0001 Mpact Media Processor 0 d 110b0004 Mpact 2 0 v 110c Mini-Max Technology, Inc. 0 v 110d Znyx Advanced Systems 0 v 110e CPU Technology 0 v 110f Ross Technology 0 v 1110 Powerhouse Systems 0 d 11106037 Firepower Powerized SMP I/O ASIC 0 d 11106073 Firepower Powerized SMP I/O ASIC 0 v 1111 Santa Cruz Operation 0 v 1112 Osicom Technologies Inc 0 Also claimed to be RNS or Rockwell International, current PCISIG records list Osicom d 11122200 FDDI Adapter 0 d 11122300 Fast Ethernet Adapter 0 d 11122340 4 Port Fast Ethernet Adapter 0 d 11122400 ATM Adapter 0 v 1113 Accton Technology Corporation 0 d 11131211 SMC2-1211TX 0 s 11131211103c1207 EN-1207D Fast Ethernet Adapter 0 s 1113121111131211 EN-1207D Fast Ethernet Adapter 0 d 11131216 EN-1216 Ethernet Adapter 0 s 1113121611132242 EN2242 10/100 Ethernet Mini-PCI Card 0 s 11131216111a1020 SpeedStream 1020 PCI 10/100 Ethernet Adaptor [EN-1207F-TX ?] 0 d 11131217 EN-1217 Ethernet Adapter 0 d 11135105 10Mbps Network card 0 d 11139211 EN-1207D Fast Ethernet Adapter 0 s 1113921111139211 EN-1207D Fast Ethernet Adapter 0 d 11139511 21x4x DEC-Tulip compatible Fast Ethernet 0 d 1113d301 CPWNA100 (Philips wireless PCMCIA) 0 d 1113ec02 SMC 1244TX v3 0 v 1114 Atmel Corporation 0 d 11140506 802.11b Wireless Network Adaptor (at76c506) 0 v 1115 3D Labs 0 v 1116 Data Translation 0 d 11160022 DT3001 0 d 11160023 DT3002 0 d 11160024 DT3003 0 d 11160025 DT3004 0 d 11160026 DT3005 0 d 11160027 DT3001-PGL 0 d 11160028 DT3003-PGL 0 v 1117 Datacube, Inc 0 d 11179500 Max-1C SVGA card 0 d 11179501 Max-1C image processing 0 v 1118 Berg Electronics 0 v 1119 ICP Vortex Computersysteme GmbH 0 d 11190000 GDT 6000/6020/6050 0 d 11190001 GDT 6000B/6010 0 d 11190002 GDT 6110/6510 0 d 11190003 GDT 6120/6520 0 d 11190004 GDT 6530 0 d 11190005 GDT 6550 0 d 11190006 GDT 6117/6517 0 d 11190007 GDT 6127/6527 0 d 11190008 GDT 6537 0 d 11190009 GDT 6557/6557-ECC 0 d 1119000a GDT 6115/6515 0 d 1119000b GDT 6125/6525 0 d 1119000c GDT 6535 0 d 1119000d GDT 6555 0 d 11190010 GDT 6115/6515 0 d 11190011 GDT 6125/6525 0 d 11190012 GDT 6535 0 d 11190013 GDT 6555/6555-ECC 0 d 11190100 GDT 6117RP/6517RP 0 d 11190101 GDT 6127RP/6527RP 0 d 11190102 GDT 6537RP 0 d 11190103 GDT 6557RP 0 d 11190104 GDT 6111RP/6511RP 0 d 11190105 GDT 6121RP/6521RP 0 d 11190110 GDT 6117RD/6517RD 0 d 11190111 GDT 6127RD/6527RD 0 d 11190112 GDT 6537RD 0 d 11190113 GDT 6557RD 0 d 11190114 GDT 6111RD/6511RD 0 d 11190115 GDT 6121RD/6521RD 0 d 11190118 GDT 6118RD/6518RD/6618RD 0 d 11190119 GDT 6128RD/6528RD/6628RD 0 d 1119011a GDT 6538RD/6638RD 0 d 1119011b GDT 6558RD/6658RD 0 d 11190120 GDT 6117RP2/6517RP2 0 d 11190121 GDT 6127RP2/6527RP2 0 d 11190122 GDT 6537RP2 0 d 11190123 GDT 6557RP2 0 d 11190124 GDT 6111RP2/6511RP2 0 d 11190125 GDT 6121RP2/6521RP2 0 d 11190136 GDT 6113RS/6513RS 0 d 11190137 GDT 6123RS/6523RS 0 d 11190138 GDT 6118RS/6518RS/6618RS 0 d 11190139 GDT 6128RS/6528RS/6628RS 0 d 1119013a GDT 6538RS/6638RS 0 d 1119013b GDT 6558RS/6658RS 0 d 1119013c GDT 6533RS/6633RS 0 d 1119013d GDT 6543RS/6643RS 0 d 1119013e GDT 6553RS/6653RS 0 d 1119013f GDT 6563RS/6663RS 0 d 11190166 GDT 7113RN/7513RN/7613RN 0 d 11190167 GDT 7123RN/7523RN/7623RN 0 d 11190168 GDT 7118RN/7518RN/7518RN 0 d 11190169 GDT 7128RN/7528RN/7628RN 0 d 1119016a GDT 7538RN/7638RN 0 d 1119016b GDT 7558RN/7658RN 0 d 1119016c GDT 7533RN/7633RN 0 d 1119016d GDT 7543RN/7643RN 0 d 1119016e GDT 7553RN/7653RN 0 d 1119016f GDT 7563RN/7663RN 0 d 111901d6 GDT 4x13RZ 0 d 111901d7 GDT 4x23RZ 0 d 111901f6 GDT 8x13RZ 0 d 111901f7 GDT 8x23RZ 0 d 111901fc GDT 8x33RZ 0 d 111901fd GDT 8x43RZ 0 d 111901fe GDT 8x53RZ 0 d 111901ff GDT 8x63RZ 0 d 11190210 GDT 6519RD/6619RD 0 d 11190211 GDT 6529RD/6629RD 0 d 11190260 GDT 7519RN/7619RN 0 d 11190261 GDT 7529RN/7629RN 0 d 111902ff GDT MAXRP 0 d 11190300 GDT NEWRX 0 v 111a Efficient Networks, Inc 0 d 111a0000 155P-MF1 (FPGA) 0 d 111a0002 155P-MF1 (ASIC) 0 d 111a0003 ENI-25P ATM 0 s 111a0003111a0000 ENI-25p Miniport ATM Adapter 0 d 111a0005 SpeedStream (LANAI) 0 s 111a0005111a0001 ENI-3010 ATM 0 s 111a0005111a0009 ENI-3060 ADSL (VPI=0) 0 s 111a0005111a0101 ENI-3010 ATM 0 s 111a0005111a0109 ENI-3060CO ADSL (VPI=0) 0 s 111a0005111a0809 ENI-3060 ADSL (VPI=0 or 8) 0 s 111a0005111a0909 ENI-3060CO ADSL (VPI=0 or 8) 0 s 111a0005111a0a09 ENI-3060 ADSL (VPI=<0..15>) 0 d 111a0007 SpeedStream ADSL 0 s 111a0007111a1001 ENI-3061 ADSL [ASIC] 0 d 111a1203 SpeedStream 1023 Wireless PCI Adapter 0 v 111b Teledyne Electronic Systems 0 v 111c Tricord Systems Inc. 0 d 111c0001 Powerbis Bridge 0 v 111d Integrated Device Technology, Inc. 0 d 111d0001 IDT77201/77211 155Mbps ATM SAR Controller [NICStAR] 0 d 111d0003 IDT77222/77252 155Mbps ATM MICRO ABR SAR Controller 0 d 111d0004 IDT77V252 155Mbps ATM MICRO ABR SAR Controller 0 d 111d0005 IDT77V222 155Mbps ATM MICRO ABR SAR Controller 0 v 111e Eldec 0 v 111f Precision Digital Images 0 d 111f4a47 Precision MX Video engine interface 0 d 111f5243 Frame capture bus interface 0 v 1120 EMC Corporation 0 v 1121 Zilog 0 v 1122 Multi-tech Systems, Inc. 0 v 1123 Excellent Design, Inc. 0 v 1124 Leutron Vision AG 0 v 1125 Eurocore 0 v 1126 Vigra 0 v 1127 FORE Systems Inc 0 d 11270200 ForeRunner PCA-200 ATM 0 d 11270210 PCA-200PC 0 d 11270250 ATM 0 d 11270300 ForeRunner PCA-200EPC ATM 0 d 11270310 ATM 0 d 11270400 ForeRunnerHE ATM Adapter 0 s 1127040011270400 ForeRunnerHE ATM 0 v 1129 Firmworks 0 v 112a Hermes Electronics Company, Ltd. 0 v 112b Linotype - Hell AG 0 v 112c Zenith Data Systems 0 v 112d Ravicad 0 v 112e Infomedia Microelectronics Inc. 0 v 112f Imaging Technology Inc 0 d 112f0000 MVC IC-PCI 0 d 112f0001 MVC IM-PCI Video frame grabber/processor 0 v 1130 Computervision 0 v 1131 Philips Semiconductors 0 d 11311561 USB 1.1 Host Controller 0 d 11311562 USB 2.0 Host Controller 0 d 11313400 SmartPCI56(UCB1500) 56K Modem 0 d 11315400 TriMedia TM1000/1100 0 d 11315402 TriMedia TM-1300 0 d 11317130 SAA7130 Video Broadcast Decoder 0 s 1131713051680138 LiveView FlyVideo 2000 0 d 11317133 SAA713X Audio+video broadcast decoder 0 s 1131713351680138 LifeView FlyVideo 3000 0 s 1131713351680212 LifeView FlyTV Platinum mini 0 d 11317134 SAA7134 0 PCI audio and video broadcast decoder (http://www.semiconductors.philips.com/pip/saa7134hl) d 11317135 SAA7135 Audio+video broadcast decoder 0 d 11317145 SAA7145 0 d 11317146 SAA7146 0 s 11317146110a0000 Fujitsu/Siemens DVB-C card rev1.5 0 s 11317146110affff Fujitsu/Siemens DVB-C card rev1.5 0 s 1131714611314f56 KNC1 DVB-S Budget 0 s 1131714611314f61 Fujitsu-Siemens Activy DVB-S Budget 0 s 11317146114b2003 DVRaptor Video Edit/Capture Card 0 s 1131714611bd0006 DV500 Overlay 0 s 1131714611bd000a DV500 Overlay 0 s 1131714613c20000 Siemens/Technotrend/Hauppauge DVB card rev1.3 or rev1.5 0 s 1131714613c20001 Technotrend/Hauppauge DVB card rev1.3 or rev1.6 0 s 1131714613c20002 Technotrend/Hauppauge DVB card rev2.1 0 s 1131714613c20003 Technotrend/Hauppauge DVB card rev2.1 0 s 1131714613c20004 Technotrend/Hauppauge DVB card rev2.1 0 s 1131714613c20006 Technotrend/Hauppauge DVB card rev1.3 or rev1.6 0 s 1131714613c20008 Technotrend/Hauppauge DVB-T 0 s 1131714613c2000a Octal/Technotrend DVB-C for iTV 0 s 1131714613c21003 Technotrend-Budget / Hauppauge WinTV-NOVA-S DVB card 0 s 1131714613c21004 Technotrend-Budget / Hauppauge WinTV-NOVA-C DVB card 0 s 1131714613c21005 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card 0 s 1131714613c2100c Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card 0 s 1131714613c2100f Technotrend-Budget / Hauppauge WinTV-NOVA-CI DVB card 0 s 1131714613c21011 Technotrend-Budget / Hauppauge WinTV-NOVA-T DVB card 0 s 1131714613c21013 SATELCO Multimedia DVB 0 s 1131714613c21102 Technotrend/Hauppauge DVB card rev2.1 0 v 1132 Mitel Corp. 0 v 1133 Eicon Networks Corporation 0 This is the new official company name. See disclaimer on www.eicon.com for details! d 11337901 EiconCard S90 0 d 11337902 EiconCard S90 0 d 11337911 EiconCard S91 0 d 11337912 EiconCard S91 0 d 11337941 EiconCard S94 0 d 11337942 EiconCard S94 0 d 11337943 EiconCard S94 0 d 11337944 EiconCard S94 0 d 1133b921 EiconCard P92 0 d 1133b922 EiconCard P92 0 d 1133b923 EiconCard P92 0 d 1133e001 Diva Pro 2.0 S/T 0 d 1133e002 Diva 2.0 S/T PCI 0 d 1133e003 Diva Pro 2.0 U 0 d 1133e004 Diva 2.0 U PCI 0 d 1133e005 Diva 2.01 S/T PCI 0 d 1133e006 Diva CT S/T PCI 0 d 1133e007 Diva CT U PCI 0 d 1133e008 Diva CT Lite S/T PCI 0 d 1133e009 Diva CT Lite U PCI 0 d 1133e00a Diva ISDN+V.90 PCI 0 d 1133e00b Diva 2.02 PCI S/T 0 d 1133e00c Diva 2.02 PCI U 0 d 1133e00d Diva ISDN Pro 3.0 PCI 0 d 1133e00e Diva ISDN+CT S/T PCI Rev 2 0 d 1133e010 Diva Server BRI-2M PCI 0 s 1133e010110a0021 Fujitsu Siemens ISDN S0 0 s 1133e01080010014 Diva Server BRI-2M PCI Cornet NQ 0 d 1133e011 Diva Server BRI S/T Rev 2 0 d 1133e012 Diva Server 4BRI-8M PCI 0 s 1133e01280010014 Diva Server 4BRI-8M PCI Cornet NQ 0 d 1133e013 Diva Server 4BRI Rev 2 0 s 1133e01311331300 Diva Server V-4BRI-8 0 s 1133e0131133e013 Diva Server 4BRI-8M 2.0 PCI 0 s 1133e01380010014 Diva Server 4BRI-8M 2.0 PCI Cornet NQ 0 d 1133e014 Diva Server PRI-30M PCI 0 s 1133e01400080100 Diva Server PRI-30M PCI 0 s 1133e01480010014 Diva Server PRI-30M PCI Cornet NQ 0 d 1133e015 DIVA Server PRI Rev 2 0 s 1133e0151133e015 Diva Server PRI 2.0 PCI 0 s 1133e01580010014 Diva Server PRI 2.0 PCI Cornet NQ 0 d 1133e016 Diva Server Voice 4BRI PCI 0 s 1133e01680010014 Diva Server PRI Cornet NQ 0 d 1133e017 Diva Server Voice 4BRI Rev 2 0 s 1133e0171133e017 Diva Server Voice 4BRI-8M 2.0 PCI 0 s 1133e01780010014 Diva Server Voice 4BRI-8M 2.0 PCI Cornet NQ 0 d 1133e018 Diva Server BRI-2M 2.0 PCI 0 s 1133e01811331800 Diva Server V-BRI-2 0 s 1133e0181133e018 Diva Server BRI-2M 2.0 PCI 0 s 1133e01880010014 Diva Server BRI-2M 2.0 PCI Cornet NQ 0 d 1133e019 Diva Server Voice PRI Rev 2 0 s 1133e0191133e019 Diva Server Voice PRI 2.0 PCI 0 s 1133e01980010014 Diva Server Voice PRI 2.0 PCI Cornet NQ 0 d 1133e01a Diva Server 2FX 0 d 1133e01b Diva Server Voice BRI-2M 2.0 PCI 0 s 1133e01b1133e01b Diva Server Voice BRI-2M 2.0 PCI 0 s 1133e01b80010014 Diva Server Voice BRI-2M 2.0 PCI Cornet NQ 0 d 1133e01c Diva Server PRI Rev 3 0 s 1133e01c11331c01 Diva Server PRI/E1/T1-8 0 s 1133e01c11331c02 Diva Server PRI/T1-24 0 s 1133e01c11331c03 Diva Server PRI/E1-30 0 s 1133e01c11331c04 Diva Server PRI/E1/T1 0 s 1133e01c11331c05 Diva Server V-PRI/T1-24 0 s 1133e01c11331c06 Diva Server V-PRI/E1-30 0 s 1133e01c11331c07 Diva Server PRI/E1/T1-8 Cornet NQ 0 s 1133e01c11331c08 Diva Server PRI/T1-24 Cornet NQ 0 s 1133e01c11331c09 Diva Server PRI/E1-30 Cornet NQ 0 s 1133e01c11331c0a Diva Server PRI/E1/T1 Cornet NQ 0 s 1133e01c11331c0b Diva Server V-PRI/T1-24 Cornet NQ 0 s 1133e01c11331c0c Diva Server V-PRI/E1-30 Cornet NQ 0 d 1133e01e Diva Server 2PRI 0 s 1133e01e11331e00 Diva Server V-2PRI/E1-60 0 s 1133e01e11331e01 Diva Server V-2PRI/T1-48 0 s 1133e01e11331e02 Diva Server 2PRI/E1-60 0 s 1133e01e11331e03 Diva Server 2PRI/T1-48 0 d 1133e020 Diva Server 4PRI 0 s 1133e02011332000 Diva Server V-4PRI/E1-120 0 s 1133e02011332001 Diva Server V-4PRI/T1-96 0 s 1133e02011332002 Diva Server 4PRI/E1-120 0 s 1133e02011332003 Diva Server 4PRI/T1-96 0 d 1133e024 Diva Server Analog-4P 0 s 1133e02411332400 Diva Server V-Analog-4P 0 s 1133e0241133e024 Diva Server Analog-4P 0 d 1133e028 Diva Server Analog-8P 0 s 1133e02811332800 Diva Server V-Analog-8P 0 s 1133e0281133e028 Diva Server Analog-8P 0 v 1134 Mercury Computer Systems 0 d 11340001 Raceway Bridge 0 d 11340002 Dual PCI to RapidIO Bridge 0 v 1135 Fuji Xerox Co Ltd 0 d 11350001 Printer controller 0 v 1136 Momentum Data Systems 0 v 1137 Cisco Systems Inc 0 v 1138 Ziatech Corporation 0 d 11388905 8905 [STD 32 Bridge] 0 v 1139 Dynamic Pictures, Inc 0 d 11390001 VGA Compatable 3D Graphics 0 v 113a FWB Inc 0 v 113b Network Computing Devices 0 v 113c Cyclone Microsystems, Inc. 0 d 113c0000 PCI-9060 i960 Bridge 0 d 113c0001 PCI-SDK [PCI i960 Evaluation Platform] 0 d 113c0911 PCI-911 [i960Jx-based Intelligent I/O Controller] 0 d 113c0912 PCI-912 [i960CF-based Intelligent I/O Controller] 0 d 113c0913 PCI-913 0 d 113c0914 PCI-914 [I/O Controller w/ secondary PCI bus] 0 v 113d Leading Edge Products Inc 0 v 113e Sanyo Electric Co - Computer Engineering Dept 0 v 113f Equinox Systems, Inc. 0 d 113f0808 SST-64P Adapter 0 d 113f1010 SST-128P Adapter 0 d 113f80c0 SST-16P DB Adapter 0 d 113f80c4 SST-16P RJ Adapter 0 d 113f80c8 SST-16P Adapter 0 d 113f8888 SST-4P Adapter 0 d 113f9090 SST-8P Adapter 0 v 1140 Intervoice Inc 0 v 1141 Crest Microsystem Inc 0 v 1142 Alliance Semiconductor Corporation 0 d 11423210 AP6410 0 d 11426422 ProVideo 6422 0 d 11426424 ProVideo 6424 0 d 11426425 ProMotion AT25 0 d 1142643d ProMotion AT3D 0 v 1143 NetPower, Inc 0 v 1144 Cincinnati Milacron 0 d 11440001 Noservo controller 0 v 1145 Workbit Corporation 0 d 11458007 NinjaSCSI-32 Workbit 0 d 1145f007 NinjaSCSI-32 KME 0 d 1145f010 NinjaSCSI-32 Workbit 0 d 1145f012 NinjaSCSI-32 Logitec 0 d 1145f013 NinjaSCSI-32 Logitec 0 d 1145f015 NinjaSCSI-32 Melco 0 v 1146 Force Computers 0 v 1147 Interface Corp 0 v 1148 SysKonnect 0 Formerly (Schneider & Koch) d 11484000 FDDI Adapter 0 s 114840000e11b03b Netelligent 100 FDDI DAS Fibre SC 0 s 114840000e11b03c Netelligent 100 FDDI SAS Fibre SC 0 s 114840000e11b03d Netelligent 100 FDDI DAS UTP 0 s 114840000e11b03e Netelligent 100 FDDI SAS UTP 0 s 114840000e11b03f Netelligent 100 FDDI SAS Fibre MIC 0 s 1148400011485521 FDDI SK-5521 (SK-NET FDDI-UP) 0 s 1148400011485522 FDDI SK-5522 (SK-NET FDDI-UP DAS) 0 s 1148400011485541 FDDI SK-5541 (SK-NET FDDI-FP) 0 s 1148400011485543 FDDI SK-5543 (SK-NET FDDI-LP) 0 s 1148400011485544 FDDI SK-5544 (SK-NET FDDI-LP DAS) 0 s 1148400011485821 FDDI SK-5821 (SK-NET FDDI-UP64) 0 s 1148400011485822 FDDI SK-5822 (SK-NET FDDI-UP64 DAS) 0 s 1148400011485841 FDDI SK-5841 (SK-NET FDDI-FP64) 0 s 1148400011485843 FDDI SK-5843 (SK-NET FDDI-LP64) 0 s 1148400011485844 FDDI SK-5844 (SK-NET FDDI-LP64 DAS) 0 d 11484200 Token Ring adapter 0 d 11484300 SK-98xx Gigabit Ethernet Server Adapter 0 s 1148430011489821 SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T) 0 s 1148430011489822 SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link) 0 s 1148430011489841 SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX) 0 s 1148430011489842 SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link) 0 s 1148430011489843 SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX) 0 s 1148430011489844 SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link) 0 s 1148430011489861 SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition) 0 s 1148430011489862 SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link) 0 s 1148430011489871 SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX) 0 s 1148430011489872 SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) 0 s 1148430012592970 AT-2970SX Gigabit Ethernet Adapter 0 s 1148430012592971 AT-2970LX Gigabit Ethernet Adapter 0 s 1148430012592972 AT-2970TX Gigabit Ethernet Adapter 0 s 1148430012592973 AT-2971SX Gigabit Ethernet Adapter 0 s 1148430012592974 AT-2971T Gigabit Ethernet Adapter 0 s 1148430012592975 AT-2970SX/2SC Gigabit Ethernet Adapter 0 s 1148430012592976 AT-2970LX/2SC Gigabit Ethernet Adapter 0 s 1148430012592977 AT-2970TX/2TX Gigabit Ethernet Adapter 0 d 11484320 SK-98xx V2.0 Gigabit Ethernet Adapter 0 s 1148432011480121 Marvell RDK-8001 Adapter 0 s 1148432011480221 Marvell RDK-8002 Adapter 0 s 1148432011480321 Marvell RDK-8003 Adapter 0 s 1148432011480421 Marvell RDK-8004 Adapter 0 s 1148432011480621 Marvell RDK-8006 Adapter 0 s 1148432011480721 Marvell RDK-8007 Adapter 0 s 1148432011480821 Marvell RDK-8008 Adapter 0 s 1148432011480921 Marvell RDK-8009 Adapter 0 s 1148432011481121 Marvell RDK-8011 Adapter 0 s 1148432011481221 Marvell RDK-8012 Adapter 0 s 1148432011483221 SK-9521 V2.0 10/100/1000Base-T Adapter 0 s 1148432011485021 SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter 0 s 1148432011485041 SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter 0 s 1148432011485043 SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter 0 s 1148432011485051 SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter 0 s 1148432011485061 SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter 0 s 1148432011485071 SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter 0 s 1148432011489521 SK-9521 10/100/1000Base-T Adapter 0 d 11484400 SK-9Dxx Gigabit Ethernet Adapter 0 d 11484500 SK-9Mxx Gigabit Ethernet Adapter 0 d 11489e00 SK-9Exx 10/100/1000Base-T Adapter 0 s 11489e0011482100 SK-9E21 Server Adapter 0 s 11489e00114821d0 SK-9E21D 10/100/1000Base-T Adapter 0 s 11489e0011482200 SK-9E22 Server Adapter 0 s 11489e0011488100 SK-9E81 Server Adapter 0 s 11489e0011488200 SK-9E82 Server Adapter 0 s 11489e0011489100 SK-9E91 Server Adapter 0 s 11489e0011489200 SK-9E92 Server Adapter 0 v 1149 Win System Corporation 0 v 114a VMIC 0 d 114a5579 VMIPCI-5579 (Reflective Memory Card) 0 d 114a5587 VMIPCI-5587 (Reflective Memory Card) 0 d 114a6504 VMIC PCI 7755 FPGA 0 d 114a7587 VMIVME-7587 0 v 114b Canopus Co., Ltd 0 v 114c Annabooks 0 v 114d IC Corporation 0 v 114e Nikon Systems Inc 0 v 114f Digi International 0 d 114f0002 AccelePort EPC 0 d 114f0003 RightSwitch SE-6 0 d 114f0004 AccelePort Xem 0 d 114f0005 AccelePort Xr 0 d 114f0006 AccelePort Xr,C/X 0 d 114f0009 AccelePort Xr/J 0 d 114f000a AccelePort EPC/J 0 d 114f000c DataFirePRIme T1 (1-port) 0 d 114f000d SyncPort 2-Port (x.25/FR) 0 d 114f0011 AccelePort 8r EIA-232 (IBM) 0 d 114f0012 AccelePort 8r EIA-422 0 d 114f0013 AccelePort Xr 0 d 114f0014 AccelePort 8r EIA-422 0 d 114f0015 AccelePort Xem 0 d 114f0016 AccelePort EPC/X 0 d 114f0017 AccelePort C/X 0 d 114f001a DataFirePRIme E1 (1-port) 0 d 114f001b AccelePort C/X (IBM) 0 d 114f001d DataFire RAS T1/E1/PRI 0 s 114f001d114f0050 DataFire RAS E1 Adapter 0 s 114f001d114f0051 DataFire RAS Dual E1 Adapter 0 s 114f001d114f0052 DataFire RAS T1 Adapter 0 s 114f001d114f0053 DataFire RAS Dual T1 Adapter 0 d 114f0023 AccelePort RAS 0 d 114f0024 DataFire RAS B4 ST/U 0 s 114f0024114f0030 DataFire RAS BRI U Adapter 0 s 114f0024114f0031 DataFire RAS BRI S/T Adapter 0 d 114f0026 AccelePort 4r 920 0 d 114f0027 AccelePort Xr 920 0 d 114f0028 ClassicBoard 4 0 d 114f0029 ClassicBoard 8 0 d 114f0034 AccelePort 2r 920 0 d 114f0035 DataFire DSP T1/E1/PRI cPCI 0 d 114f0040 AccelePort Xp 0 d 114f0042 AccelePort 2p 0 d 114f0043 AccelePort 4p 0 d 114f0044 AccelePort 8p 0 d 114f0045 AccelePort 16p 0 d 114f004e AccelePort 32p 0 d 114f0070 Datafire Micro V IOM2 (Europe) 0 d 114f0071 Datafire Micro V (Europe) 0 d 114f0072 Datafire Micro V IOM2 (North America) 0 d 114f0073 Datafire Micro V (North America) 0 d 114f00b0 Digi Neo 4 0 d 114f00b1 Digi Neo 8 0 d 114f00c8 Digi Neo 2 DB9 0 d 114f00c9 Digi Neo 2 DB9 PRI 0 d 114f00ca Digi Neo 2 RJ45 0 d 114f00cb Digi Neo 2 RJ45 PRI 0 d 114f00d0 ClassicBoard 4 422 0 d 114f00d1 ClassicBoard 8 422 0 d 114f6001 Avanstar 0 v 1150 Thinking Machines Corp 0 v 1151 JAE Electronics Inc. 0 v 1152 Megatek 0 v 1153 Land Win Electronic Corp 0 v 1154 Melco Inc 0 v 1155 Pine Technology Ltd 0 v 1156 Periscope Engineering 0 v 1157 Avsys Corporation 0 v 1158 Voarx R & D Inc 0 d 11583011 Tokenet/vg 1001/10m anylan 0 d 11589050 Lanfleet/Truevalue 0 d 11589051 Lanfleet/Truevalue 0 v 1159 Mutech Corp 0 d 11590001 MV-1000 0 v 115a Harlequin Ltd 0 v 115b Parallax Graphics 0 v 115c Photron Ltd. 0 v 115d Xircom 0 d 115d0003 Cardbus Ethernet 10/100 0 s 115d000310140181 10/100 EtherJet Cardbus Adapter 0 s 115d000310141181 10/100 EtherJet Cardbus Adapter 0 s 115d000310148181 10/100 EtherJet Cardbus Adapter 0 s 115d000310149181 10/100 EtherJet Cardbus Adapter 0 s 115d0003115d0181 Cardbus Ethernet 10/100 0 s 115d0003115d1181 Cardbus Ethernet 10/100 0 s 115d000311790181 Cardbus Ethernet 10/100 0 s 115d000380868181 EtherExpress PRO/100 Mobile CardBus 32 Adapter 0 s 115d000380869181 EtherExpress PRO/100 Mobile CardBus 32 Adapter 0 d 115d0005 Cardbus Ethernet 10/100 0 s 115d000510140182 10/100 EtherJet Cardbus Adapter 0 s 115d000510141182 10/100 EtherJet Cardbus Adapter 0 s 115d0005115d0182 Cardbus Ethernet 10/100 0 s 115d0005115d1182 Cardbus Ethernet 10/100 0 d 115d0007 Cardbus Ethernet 10/100 0 s 115d000710140182 10/100 EtherJet Cardbus Adapter 0 s 115d000710141182 10/100 EtherJet Cardbus Adapter 0 s 115d0007115d0182 Cardbus Ethernet 10/100 0 s 115d0007115d1182 Cardbus Ethernet 10/100 0 d 115d000b Cardbus Ethernet 10/100 0 s 115d000b10140183 10/100 EtherJet Cardbus Adapter 0 s 115d000b115d0183 Cardbus Ethernet 10/100 0 d 115d000c Mini-PCI V.90 56k Modem 0 d 115d000f Cardbus Ethernet 10/100 0 s 115d000f10140183 10/100 EtherJet Cardbus Adapter 0 s 115d000f115d0183 Cardbus Ethernet 10/100 0 d 115d00d4 Mini-PCI K56Flex Modem 0 d 115d0101 Cardbus 56k modem 0 s 115d0101115d1081 Cardbus 56k Modem 0 d 115d0103 Cardbus Ethernet + 56k Modem 0 s 115d010310149181 Cardbus 56k Modem 0 s 115d010311151181 Cardbus Ethernet 100 + 56k Modem 0 s 115d0103115d1181 CBEM56G-100 Ethernet + 56k Modem 0 s 115d010380869181 PRO/100 LAN + Modem56 CardBus 0 v 115e Peer Protocols Inc 0 v 115f Maxtor Corporation 0 v 1160 Megasoft Inc 0 v 1161 PFU Limited 0 v 1162 OA Laboratory Co Ltd 0 v 1163 Rendition 0 d 11630001 Verite 1000 0 d 11632000 Verite V2000/V2100/V2200 0 s 1163200010922000 Stealth II S220 0 v 1164 Advanced Peripherals Technologies 0 v 1165 Imagraph Corporation 0 d 11650001 Motion TPEG Recorder/Player with audio 0 v 1166 ServerWorks 0 d 11660000 CMIC-LE 0 d 11660005 CNB20-LE Host Bridge 0 d 11660006 CNB20HE Host Bridge 0 d 11660007 CNB20-LE Host Bridge 0 d 11660008 CNB20HE Host Bridge 0 d 11660009 CNB20LE Host Bridge 0 d 11660010 CIOB30 0 d 11660011 CMIC-HE 0 d 11660012 CMIC-WS Host Bridge (GC-LE chipset) 0 d 11660013 CNB20-HE Host Bridge 0 d 11660014 CMIC-LE Host Bridge (GC-LE chipset) 0 d 11660015 CMIC-GC Host Bridge 0 d 11660016 CMIC-GC Host Bridge 0 d 11660017 GCNB-LE Host Bridge 0 d 11660101 CIOB-X2 PCI-X I/O Bridge 0 d 11660110 CIOB-E I/O Bridge with Gigabit Ethernet 0 d 11660200 OSB4 South Bridge 0 d 11660201 CSB5 South Bridge 0 s 116602014c531080 CT8 mainboard 0 d 11660203 CSB6 South Bridge 0 d 11660211 OSB4 IDE Controller 0 d 11660212 CSB5 IDE Controller 0 s 116602124c531080 CT8 mainboard 0 d 11660213 CSB6 RAID/IDE Controller 0 d 11660217 CSB6 IDE Controller 0 d 11660220 OSB4/CSB5 OHCI USB Controller 0 s 116602204c531080 CT8 mainboard 0 d 11660221 CSB6 OHCI USB Controller 0 d 11660225 CSB5 LPC bridge 0 s 116602254c531080 CT8 mainboard 0 cancelled d 11660227 GCLE-2 Host Bridge 0 d 11660230 CSB5 LPC bridge 0 s 116602304c531080 CT8 mainboard 0 d 11660240 K2 SATA 0 v 1167 Mutoh Industries Inc 0 v 1168 Thine Electronics Inc 0 v 1169 Centre for Development of Advanced Computing 0 v 116a Polaris Communications 0 d 116a6100 Bus/Tag Channel 0 d 116a6800 Escon Channel 0 d 116a7100 Bus/Tag Channel 0 d 116a7800 Escon Channel 0 v 116b Connectware Inc 0 v 116c Intelligent Resources Integrated Systems 0 v 116d Martin-Marietta 0 v 116e Electronics for Imaging 0 v 116f Workstation Technology 0 v 1170 Inventec Corporation 0 v 1171 Loughborough Sound Images Plc 0 v 1172 Altera Corporation 0 v 1173 Adobe Systems, Inc 0 v 1174 Bridgeport Machines 0 v 1175 Mitron Computer Inc. 0 v 1176 SBE Incorporated 0 v 1177 Silicon Engineering 0 v 1178 Alfa, Inc. 0 d 1178afa1 Fast Ethernet Adapter 0 v 1179 Toshiba America Info Systems 0 d 11790103 EX-IDE Type-B 0 d 11790404 DVD Decoder card 0 d 11790406 Tecra Video Capture device 0 d 11790407 DVD Decoder card (Version 2) 0 d 11790601 601 0 d 11790603 ToPIC95 PCI to CardBus Bridge for Notebooks 0 d 1179060a ToPIC95 0 d 1179060f ToPIC97 0 d 11790617 ToPIC100 PCI to Cardbus Bridge with ZV Support 0 d 11790618 CPU to PCI and PCI to ISA bridge 0 d 11790701 FIR Port 0 Claimed to be Lucent DSP1645 [Mars], but that's apparently incorrect. Does anyone know the correct ID? d 11790804 TC6371AF SmartMedia Controller 0 d 11790805 SD TypA Controller 0 d 11790d01 FIR Port Type-DO 0 s 11790d0111790001 FIR Port Type-DO 0 v 117a A-Trend Technology 0 v 117b L G Electronics, Inc. 0 v 117c Atto Technology 0 v 117d Becton & Dickinson 0 v 117e T/R Systems 0 v 117f Integrated Circuit Systems 0 v 1180 Ricoh Co Ltd 0 d 11800465 RL5c465 0 d 11800466 RL5c466 0 d 11800475 RL5c475 0 s 11800475144dc006 vpr Matrix 170B4 CardBus bridge 0 d 11800476 RL5c476 II 0 s 1180047610140185 ThinkPad A/T/X Series 0 s 11800476104d80df Vaio PCG-FX403 0 s 11800476104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 1180047614ef0220 PCD-RP-220S 0 d 11800477 RL5c477 0 d 11800478 RL5c478 0 s 1180047810140184 ThinkPad A30p (2653-64G) 0 d 11800522 R5C522 IEEE 1394 Controller 0 s 11800522101401cf ThinkPad A30p (2653-64G) 0 d 11800551 R5C551 IEEE 1394 Controller 0 s 11800551144dc006 vpr Matrix 170B4 0 d 11800552 R5C552 IEEE 1394 Controller 0 s 1180055210140511 ThinkPad A/T/X Series 0 v 1181 Telmatics International 0 v 1183 Fujikura Ltd 0 v 1184 Forks Inc 0 v 1185 Dataworld International Ltd 0 v 1186 D-Link System Inc 0 d 11860100 DC21041 0 d 11861002 DL10050 Sundance Ethernet 0 s 1186100211861002 DFE-550TX 0 s 1186100211861012 DFE-580TX 0 d 11861025 AirPlus Xtreme G DWL-G650 Adapter 0 d 11861026 AirXpert DWL-AG650 Wireless Cardbus Adapter 0 d 11861043 AirXpert DWL-AG650 Wireless Cardbus Adapter 0 d 11861300 RTL8139 Ethernet 0 s 1186130011861300 DFE-538TX 10/100 Ethernet Adapter 0 s 1186130011861301 DFE-530TX+ 10/100 Ethernet Adapter 0 d 11861340 DFE-690TXD CardBus PC Card 0 d 11861541 DFE-680TXD CardBus PC Card 0 d 11861561 DRP-32TXD Cardbus PC Card 0 d 11862027 AirPlus Xtreme G DWL-G520 Adapter 0 d 11863203 AirPlus Xtreme G DWL-G520 Adapter 0 d 11863300 DWL-510 2.4GHz Wireless PCI Adapter 0 d 11863a03 AirPro DWL-A650 Wireless Cardbus Adapter(rev.B) 0 d 11863a04 AirPro DWL-AB650 Multimode Wireless Cardbus Adapter 0 d 11863a05 AirPro DWL-AB520 Multimode Wireless PCI Adapter 0 d 11863a07 AirXpert DWL-AG650 Wireless Cardbus Adapter 0 d 11863a08 AirXpert DWL-AG520 Wireless PCI Adapter 0 d 11863a10 AirXpert DWL-AG650 Wireless Cardbus Adapter(rev.B) 0 d 11863a11 AirXpert DWL-AG520 Wireless PCI Adapter(rev.B) 0 d 11863a12 AirPlus DWL-G650 Wireless Cardbus Adapter(rev.C) 0 d 11863a13 AirPlus DWL-G520 Wireless PCI Adapter(rev.B) 0 d 11863a14 AirPremier DWL-AG530 Wireless PCI Adapter 0 d 11863a63 AirXpert DWL-AG660 Wireless Cardbus Adapter 0 d 11863b05 DWL-G650+ CardBus PC Card 0 d 11864000 DL2000-based Gigabit Ethernet 0 d 11864c00 Gigabit Ethernet Adapter 0 s 11864c0011864c00 DGE-530T Gigabit Ethernet Adapter 0 d 11868400 D-Link DWL-650+ CardBus PC Card 0 v 1187 Advanced Technology Laboratories, Inc. 0 v 1188 Shima Seiki Manufacturing Ltd. 0 v 1189 Matsushita Electronics Co Ltd 0 v 118a Hilevel Technology 0 v 118b Hypertec Pty Limited 0 v 118c Corollary, Inc 0 d 118c0014 PCIB [C-bus II to PCI bus host bridge chip] 0 d 118c1117 Intel 8-way XEON Profusion Chipset [Cache Coherency Filter] 0 v 118d BitFlow Inc 0 d 118d0001 Raptor-PCI framegrabber 0 d 118d0012 Model 12 Road Runner Frame Grabber 0 d 118d0014 Model 14 Road Runner Frame Grabber 0 d 118d0024 Model 24 Road Runner Frame Grabber 0 d 118d0044 Model 44 Road Runner Frame Grabber 0 d 118d0112 Model 12 Road Runner Frame Grabber 0 d 118d0114 Model 14 Road Runner Frame Grabber 0 d 118d0124 Model 24 Road Runner Frame Grabber 0 d 118d0144 Model 44 Road Runner Frame Grabber 0 d 118d0212 Model 12 Road Runner Frame Grabber 0 d 118d0214 Model 14 Road Runner Frame Grabber 0 d 118d0224 Model 24 Road Runner Frame Grabber 0 d 118d0244 Model 44 Road Runner Frame Grabber 0 d 118d0312 Model 12 Road Runner Frame Grabber 0 d 118d0314 Model 14 Road Runner Frame Grabber 0 d 118d0324 Model 24 Road Runner Frame Grabber 0 d 118d0344 Model 44 Road Runner Frame Grabber 0 v 118e Hermstedt GmbH 0 v 118f Green Logic 0 v 1190 Tripace 0 d 1190c731 TP-910/920/940 PCI Ultra(Wide) SCSI Adapter 0 v 1191 Artop Electronic Corp 0 d 11910003 SCSI Cache Host Adapter 0 d 11910004 ATP8400 0 d 11910005 ATP850UF 0 d 11910006 ATP860 NO-BIOS 0 d 11910007 ATP860 0 d 11910008 ATP865 NO-ROM 0 d 11910009 ATP865 0 d 11918002 AEC6710 SCSI-2 Host Adapter 0 d 11918010 AEC6712UW SCSI 0 d 11918020 AEC6712U SCSI 0 d 11918030 AEC6712S SCSI 0 d 11918040 AEC6712D SCSI 0 d 11918050 AEC6712SUW SCSI 0 v 1192 Densan Company Ltd 0 v 1193 Zeitnet Inc. 0 d 11930001 1221 0 d 11930002 1225 0 v 1194 Toucan Technology 0 v 1195 Ratoc System Inc 0 v 1196 Hytec Electronics Ltd 0 v 1197 Gage Applied Sciences, Inc. 0 d 1197010c CompuScope 82G 8bit 2GS/s Analog Input Card 0 v 1198 Lambda Systems Inc 0 v 1199 Attachmate Corporation 0 v 119a Mind Share, Inc. 0 v 119b Omega Micro Inc. 0 d 119b1221 82C092G 0 v 119c Information Technology Inst. 0 v 119d Bug, Inc. Sapporo Japan 0 v 119e Fujitsu Microelectronics Ltd. 0 d 119e0001 FireStream 155 0 d 119e0003 FireStream 50 0 v 119f Bull HN Information Systems 0 v 11a0 Convex Computer Corporation 0 v 11a1 Hamamatsu Photonics K.K. 0 v 11a2 Sierra Research and Technology 0 v 11a3 Deuretzbacher GmbH & Co. Eng. KG 0 v 11a4 Barco Graphics NV 0 v 11a5 Microunity Systems Eng. Inc 0 v 11a6 Pure Data Ltd. 0 v 11a7 Power Computing Corp. 0 v 11a8 Systech Corp. 0 v 11a9 InnoSys Inc. 0 d 11a94240 AMCC S933Q Intelligent Serial Card 0 v 11aa Actel 0 v 11ab Marvell Technology Group Ltd. 0 Formerly Galileo Technology, Inc. d 11ab0146 GT-64010/64010A System Controller 0 d 11ab138f W8300 802.11 Adapter (rev 07) 0 d 11ab1fa6 Marvell W8300 802.11 Adapter 0 d 11ab4320 Gigabit Ethernet Controller 0 s 11ab432010190f38 Marvell 88E8001 Gigabit Ethernet Controller (ECS) 0 s 11ab432010198001 Marvell 88E8001 Gigabit Ethernet Controller (ECS) 0 s 11ab43201043173c Marvell 88E8001 Gigabit Ethernet Controller (Asus) 0 s 11ab43201043811a Marvell 88E8001 Gigabit Ethernet Controller (Asus) 0 s 11ab4320105b0c19 Marvell 88E8001 Gigabit Ethernet Controller (Foxconn) 0 s 11ab432010b8b452 SMC EZ Card 1000 (SMC9452TXV.2) 0 s 11ab432011ab0121 Marvell RDK-8001 0 s 11ab432011ab0321 Marvell RDK-8003 0 s 11ab432011ab1021 Marvell RDK-8010 0 s 11ab432011ab5021 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (64 bit) 0 s 11ab432011ab9521 Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Controller (32 bit) 0 s 11ab43201458e000 Marvell 88E8001 Gigabit Ethernet Controller (Gigabyte) 0 s 11ab4320147b1406 Marvell 88E8001 Gigabit Ethernet Controller (Abit) 0 s 11ab432015d40047 Marvell 88E8001 Gigabit Ethernet Controller (Iwill) 0 s 11ab432016959025 Marvell 88E8001 Gigabit Ethernet Controller (Epox) 0 s 11ab432017f21c03 Marvell 88E8001 Gigabit Ethernet Controller (Albatron) 0 s 11ab4320270f2803 Marvell 88E8001 Gigabit Ethernet Controller (Chaintech) 0 d 11ab4350 Fast Ethernet Controller 0 s 11ab435011790001 Marvell 88E8035 Fast Ethernet Controller (Toshiba) 0 s 11ab435011ab3521 Marvell RDK-8035 0 s 11ab43501854000d Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab43501854000e Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab43501854000f Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab435018540011 Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab435018540012 Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab435018540016 Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab435018540017 Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab435018540018 Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab435018540019 Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab43501854001c Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab43501854001e Marvell 88E8035 Fast Ethernet Controller (LGE) 0 s 11ab435018540020 Marvell 88E8035 Fast Ethernet Controller (LGE) 0 d 11ab4351 Fast Ethernet Controller 0 s 11ab4351107b4009 Marvell 88E8036 Fast Ethernet Controller (Wistron) 0 s 11ab435110f78338 Marvell 88E8036 Fast Ethernet Controller (Panasonic) 0 s 11ab435111790001 Marvell 88E8036 Fast Ethernet Controller (Toshiba) 0 s 11ab43511179ff00 Marvell 88E8036 Fast Ethernet Controller (Compal) 0 s 11ab43511179ff10 Marvell 88E8036 Fast Ethernet Controller (Inventec) 0 s 11ab435111ab3621 Marvell RDK-8036 0 s 11ab435113d1ac12 Abocom EFE3K - 10/100 Ethernet Expresscard 0 s 11ab4351161f203d Marvell 88E8036 Fast Ethernet Controller (Arima) 0 s 11ab43511854000d Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab43511854000e Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab43511854000f Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab435118540011 Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab435118540012 Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab435118540016 Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab435118540017 Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab435118540018 Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab435118540019 Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab43511854001c Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab43511854001e Marvell 88E8036 Fast Ethernet Controller (LGE) 0 s 11ab435118540020 Marvell 88E8036 Fast Ethernet Controller (LGE) 0 d 11ab4360 Gigabit Ethernet Controller 0 s 11ab436010438134 Marvell 88E8052 Gigabit Ethernet Controller (Asus) 0 s 11ab4360107b4009 Marvell 88E8052 Gigabit Ethernet Controller (Wistron) 0 s 11ab436011ab5221 Marvell RDK-8052 0 s 11ab43601458e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte) 0 s 11ab43601462052c Marvell 88E8052 Gigabit Ethernet Controller (MSI) 0 s 11ab436018498052 Marvell 88E8052 Gigabit Ethernet Controller (ASRock) 0 s 11ab43601940e000 Marvell 88E8052 Gigabit Ethernet Controller (Gigabyte) 0 s 11ab4360a0a00509 Marvell 88E8052 Gigabit Ethernet Controller (Aopen) 0 d 11ab4361 Gigabit Ethernet Controller 0 s 11ab4361107b3015 Marvell 88E8050 Gigabit Ethernet Controller (Gateway) 0 s 11ab436111ab5021 Marvell 88E8050 Gigabit Ethernet Controller (Intel) 0 s 11ab436180863063 D925XCVLK mainboard 0 d 11ab4362 Gigabit Ethernet Controller 0 s 11ab4362103c2a0d Marvell 88E8053 Gigabit Ethernet Controller (Asus) 0 s 11ab436210438142 Marvell 88E8053 Gigabit Ethernet Controller (Asus) 0 s 11ab4362109f3197 Marvell 88E8053 Gigabit Ethernet Controller (Trigem) 0 s 11ab436210f78338 Marvell 88E8053 Gigabit Ethernet Controller (Panasonic) 0 s 11ab436210fda430 Marvell 88E8053 Gigabit Ethernet Controller (SOYO) 0 s 11ab436211790001 Marvell 88E8053 Gigabit Ethernet Controller (Toshiba) 0 s 11ab43621179ff00 Marvell 88E8053 Gigabit Ethernet Controller (Compal) 0 s 11ab43621179ff10 Marvell 88E8053 Gigabit Ethernet Controller (Inventec) 0 s 11ab436211ab5321 Marvell RDK-8053 0 s 11ab43621297c240 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) 0 s 11ab43621297c241 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) 0 s 11ab43621297c242 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) 0 s 11ab43621297c243 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) 0 s 11ab43621297c244 Marvell 88E8053 Gigabit Ethernet Controller (Shuttle) 0 s 11ab436213d1ac11 Abocom EGE5K - Giga Ethernet Expresscard 0 s 11ab43621458e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte) 0 s 11ab43621462058c Marvell 88E8053 Gigabit Ethernet Controller (MSI) 0 s 11ab436214c00012 Marvell 88E8053 Gigabit Ethernet Controller (Compal) 0 s 11ab4362155804a0 Marvell 88E8053 Gigabit Ethernet Controller (Clevo) 0 s 11ab436215bd1003 Marvell 88E8053 Gigabit Ethernet Controller (DFI) 0 s 11ab4362161f203c Marvell 88E8053 Gigabit Ethernet Controller (Arima) 0 s 11ab4362161f203d Marvell 88E8053 Gigabit Ethernet Controller (Arima) 0 s 11ab436216959029 Marvell 88E8053 Gigabit Ethernet Controller (Epox) 0 s 11ab436217f22c08 Marvell 88E8053 Gigabit Ethernet Controller (Albatron) 0 s 11ab436217ff0585 Marvell 88E8053 Gigabit Ethernet Controller (Quanta) 0 s 11ab436218498053 Marvell 88E8053 Gigabit Ethernet Controller (ASRock) 0 s 11ab43621854000b Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab43621854000c Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab436218540010 Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab436218540013 Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab436218540014 Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab436218540015 Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab43621854001a Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab43621854001b Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab43621854001d Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab43621854001f Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab436218540021 Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab436218540022 Marvell 88E8053 Gigabit Ethernet Controller (LGE) 0 s 11ab43621940e000 Marvell 88E8053 Gigabit Ethernet Controller (Gigabyte) 0 s 11ab4362270f2801 Marvell 88E8053 Gigabit Ethernet Controller (Chaintech) 0 s 11ab4362a0a00506 Marvell 88E8053 Gigabit Ethernet Controller (Aopen) 0 d 11ab4611 GT-64115 System Controller 0 d 11ab4620 GT-64120/64120A/64121A System Controller 0 d 11ab4801 GT-48001 0 d 11ab5040 MV88SX5040 4-port SATA I PCI-X Controller 0 d 11ab5041 MV88SX5041 4-port SATA I PCI-X Controller 0 d 11ab5080 MV88SX5080 8-port SATA I PCI-X Controller 0 d 11ab5081 MV88SX5081 8-port SATA I PCI-X Controller 0 d 11ab6041 MV88SX6041 4-port SATA II PCI-X Controller 0 d 11ab6081 MV88SX6081 8-port SATA II PCI-X Controller 0 d 11ab6460 MV64360/64361/64362 System Controller 0 d 11abf003 GT-64010 Primary Image Piranha Image Generator 0 v 11ac Canon Information Systems Research Aust. 0 v 11ad Lite-On Communications Inc 0 d 11ad0002 LNE100TX 0 s 11ad000211ad0002 LNE100TX 0 s 11ad000211ad0003 LNE100TX 0 s 11ad000211adf003 LNE100TX 0 s 11ad000211adffff LNE100TX 0 s 11ad00021385f004 FA310TX 0 d 11adc115 LNE100TX [Linksys EtherFast 10/100] 0 s 11adc11511adc001 LNE100TX [ver 2.0] 0 v 11ae Aztech System Ltd 0 v 11af Avid Technology Inc. 0 d 11af0001 [Cinema] 0 v 11b0 V3 Semiconductor Inc. 0 d 11b00002 V300PSC 0 d 11b00292 V292PBC [Am29030/40 Bridge] 0 d 11b00960 V96xPBC 0 d 11b0c960 V96DPC 0 v 11b1 Apricot Computers 0 v 11b2 Eastman Kodak 0 v 11b3 Barr Systems Inc. 0 v 11b4 Leitch Technology International 0 v 11b5 Radstone Technology Plc 0 v 11b6 United Video Corp 0 v 11b7 Motorola 0 v 11b8 XPoint Technologies, Inc 0 d 11b80001 Quad PeerMaster 0 v 11b9 Pathlight Technology Inc. 0 d 11b9c0ed SSA Controller 0 v 11ba Videotron Corp 0 v 11bb Pyramid Technology 0 v 11bc Network Peripherals Inc 0 d 11bc0001 NP-PCI 0 v 11bd Pinnacle Systems Inc. 0 v 11be International Microcircuits Inc 0 v 11bf Astrodesign, Inc. 0 v 11c0 Hewlett Packard 0 v 11c1 Agere Systems (former Lucent Microelectronics) 0 d 11c10440 56k WinModem 0 s 11c1044010338015 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044010338047 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c104401033804f LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044010cf102c LB LT Modem V.90 56k 0 s 11c1044010cf104a BIBLO LT Modem 56k 0 s 11c1044010cf105f LB2 LT Modem V.90 56k 0 s 11c1044011790001 Internal V.90 Modem 0 s 11c1044011c10440 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c10440122d4101 MDP7800-U Modem 0 s 11c10440122d4102 MDP7800SP-U Modem 0 s 11c1044013e00040 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044013e00440 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044013e00441 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044013e00450 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044013e0f100 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044013e0f101 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c10440144d2101 LT56PV Modem 0 s 11c10440149f0440 LT WinModem 56k Data+Fax+Voice+Dsvd 0 d 11c10441 56k WinModem 0 s 11c104411033804d LT WinModem 56k Data+Fax 0 s 11c1044110338065 LT WinModem 56k Data+Fax 0 s 11c1044110920440 Supra 56i 0 s 11c1044111790001 Internal V.90 Modem 0 s 11c1044111c10440 LT WinModem 56k Data+Fax 0 s 11c1044111c10441 LT WinModem 56k Data+Fax 0 s 11c10441122d4100 MDP7800-U Modem 0 s 11c1044113e00040 LT WinModem 56k Data+Fax 0 s 11c1044113e00100 LT WinModem 56k Data+Fax 0 s 11c1044113e00410 LT WinModem 56k Data+Fax 0 s 11c1044113e00420 TelePath Internet 56k WinModem 0 s 11c1044113e00440 LT WinModem 56k Data+Fax 0 s 11c1044113e00443 LT WinModem 56k Data+Fax 0 s 11c1044113e0f102 LT WinModem 56k Data+Fax 0 s 11c1044114169804 CommWave 56k Modem 0 s 11c10441141d0440 LT WinModem 56k Data+Fax 0 s 11c10441144f0441 Lucent 56k V.90 DF Modem 0 s 11c10441144f0449 Lucent 56k V.90 DF Modem 0 s 11c10441144f110d Lucent Win Modem 0 s 11c1044114680441 Presario 56k V.90 DF Modem 0 s 11c1044116680440 Lucent Win Modem 0 d 11c10442 56k WinModem 0 s 11c1044211c10440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c1044211c10442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c1044213e00412 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c1044213e00442 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c1044213fc2471 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c10442144d2104 LT56PT Modem 0 s 11c10442144f1104 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c10442149f0440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c1044216680440 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 d 11c10443 LT WinModem 0 d 11c10444 LT WinModem 0 d 11c10445 LT WinModem 0 s 11c1044580862203 PRO/100+ MiniPCI (probably an Ambit U98.003.C.00 combo card) 0 s 11c1044580862204 PRO/100+ MiniPCI on Armada E500 0 d 11c10446 LT WinModem 0 d 11c10447 LT WinModem 0 d 11c10448 WinModem 56k 0 s 11c1044810140131 Lucent Win Modem 0 s 11c1044810338066 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044813e00030 56k Voice Modem 0 s 11c1044813e00040 LT WinModem 56k Data+Fax+Voice+Dsvd 0 s 11c1044816682400 LT WinModem 56k (MiniPCI Ethernet+Modem) 0 Actiontech eth+modem card as used by Dell &c. d 11c10449 WinModem 56k 0 s 11c104490e11b14d 56k V.90 Modem 0 s 11c1044913e00020 LT WinModem 56k Data+Fax 0 s 11c1044913e00041 TelePath Internet 56k WinModem 0 s 11c1044914360440 Lucent Win Modem 0 s 11c10449144f0449 Lucent 56k V.90 DFi Modem 0 s 11c1044914680410 IBM ThinkPad T23 (2647-4MG) 0 s 11c1044914680440 Lucent Win Modem 0 s 11c1044914680449 Presario 56k V.90 DFi Modem 0 d 11c1044a F-1156IV WinModem (V90, 56KFlex) 0 s 11c1044a10cf1072 LB Global LT Modem 0 s 11c1044a13e00012 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c1044a13e00042 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 s 11c1044a144f1005 LT WinModem 56k Data+Fax+Voice+VoiceView+Dsvd 0 d 11c1044b LT WinModem 0 d 11c1044c LT WinModem 0 d 11c1044d LT WinModem 0 d 11c1044e LT WinModem 0 d 11c1044f V90 WildWire Modem 0 d 11c10450 LT WinModem 0 s 11c10450103380a8 Versa Note Vxi 0 s 11c10450144f4005 Magnia SG20 0 d 11c10451 LT WinModem 0 d 11c10452 LT WinModem 0 d 11c10453 LT WinModem 0 d 11c10454 LT WinModem 0 d 11c10455 LT WinModem 0 d 11c10456 LT WinModem 0 d 11c10457 LT WinModem 0 d 11c10458 LT WinModem 0 d 11c10459 LT WinModem 0 d 11c1045a LT WinModem 0 d 11c1045c LT WinModem 0 d 11c10461 V90 WildWire Modem 0 d 11c10462 V90 WildWire Modem 0 d 11c10480 Venus Modem (V90, 56KFlex) 0 d 11c1048c V.92 56K WinModem 0 d 11c1048f V.92 56k WinModem 0 InPorte Home Internal 56k Modem/fax/answering machine/SMS Features d 11c15801 USB 0 d 11c15802 USS-312 USB Controller 0 d 11c15803 USS-344S USB Controller 0 4 port PCI USB Controller made by Agere (formely Lucent) d 11c15811 FW323 0 s 11c158118086524c D865PERL mainboard 0 s 11c15811dead0800 FireWire Host Bus Adapter 0 d 11c1ab10 WL60010 Wireless LAN MAC 0 d 11c1ab11 WL60040 Multimode Wireles LAN MAC 0 s 11c1ab1111c1ab12 WaveLAN 11abg Cardbus card (Model 1102) 0 s 11c1ab1111c1ab13 WaveLAN 11abg MiniPCI card (Model 0512) 0 s 11c1ab1111c1ab15 WaveLAN 11abg Cardbus card (Model 1106) 0 s 11c1ab1111c1ab16 WaveLAN 11abg MiniPCI card (Model 0516) 0 d 11c1ab20 ORiNOCO PCI Adapter 0 d 11c1ab21 Agere Wireless PCI Adapter 0 d 11c1ab30 Hermes2 Mini-PCI WaveLAN a/b/g 0 s 11c1ab3014cd2012 Hermes2 Mini-PCI WaveLAN a/b/g 0 v 11c2 Sand Microelectronics 0 v 11c3 NEC Corporation 0 v 11c4 Document Technologies, Inc 0 v 11c5 Shiva Corporation 0 v 11c6 Dainippon Screen Mfg. Co. Ltd 0 v 11c7 D.C.M. Data Systems 0 v 11c8 Dolphin Interconnect Solutions AS 0 d 11c80658 PSB32 SCI-Adapter D31x 0 d 11c8d665 PSB64 SCI-Adapter D32x 0 d 11c8d667 PSB66 SCI-Adapter D33x 0 v 11c9 Magma 0 d 11c90010 16-line serial port w/- DMA 0 d 11c90011 4-line serial port w/- DMA 0 v 11ca LSI Systems, Inc 0 v 11cb Specialix Research Ltd. 0 d 11cb2000 PCI_9050 0 s 11cb200011cb0200 SX 0 s 11cb200011cbb008 I/O8+ 0 d 11cb4000 SUPI_1 0 d 11cb8000 T225 0 v 11cc Michels & Kleberhoff Computer GmbH 0 v 11cd HAL Computer Systems, Inc. 0 v 11ce Netaccess 0 v 11cf Pioneer Electronic Corporation 0 v 11d0 Lockheed Martin Federal Systems-Manassas 0 v 11d1 Auravision 0 d 11d101f7 VxP524 0 v 11d2 Intercom Inc. 0 v 11d3 Trancell Systems Inc 0 v 11d4 Analog Devices 0 d 11d41535 Blackfin BF535 processor 0 d 11d41805 SM56 PCI modem 0 d 11d41889 AD1889 sound chip 0 v 11d5 Ikon Corporation 0 d 11d50115 10115 0 d 11d50117 10117 0 v 11d6 Tekelec Telecom 0 v 11d7 Trenton Technology, Inc. 0 v 11d8 Image Technologies Development 0 v 11d9 TEC Corporation 0 v 11da Novell 0 v 11db Sega Enterprises Ltd 0 v 11dc Questra Corporation 0 v 11dd Crosfield Electronics Limited 0 v 11de Zoran Corporation 0 d 11de6057 ZR36057PQC Video cutting chipset 0 s 11de605710317efe DC10 Plus 0 s 11de60571031fc00 MiroVIDEO DC50, Motion JPEG Capture/CODEC Board 0 s 11de605713ca4231 JPEG/TV Card 0 d 11de6120 ZR36120 0 s 11de61201328f001 Cinemaster C DVD Decoder 0 v 11df New Wave PDG 0 v 11e0 Cray Communications A/S 0 v 11e1 GEC Plessey Semi Inc. 0 v 11e2 Samsung Information Systems America 0 v 11e3 Quicklogic Corporation 0 d 11e35030 PC Watchdog 0 v 11e4 Second Wave Inc 0 v 11e5 IIX Consulting 0 v 11e6 Mitsui-Zosen System Research 0 v 11e7 Toshiba America, Elec. Company 0 v 11e8 Digital Processing Systems Inc. 0 v 11e9 Highwater Designs Ltd. 0 v 11ea Elsag Bailey 0 v 11eb Formation Inc. 0 v 11ec Coreco Inc 0 v 11ed Mediamatics 0 v 11ee Dome Imaging Systems Inc 0 v 11ef Nicolet Technologies B.V. 0 v 11f0 Compu-Shack 0 d 11f04231 FDDI 0 d 11f04232 FASTline UTP Quattro 0 d 11f04233 FASTline FO 0 d 11f04234 FASTline UTP 0 d 11f04235 FASTline-II UTP 0 d 11f04236 FASTline-II FO 0 d 11f04731 GIGAline 0 v 11f1 Symbios Logic Inc 0 v 11f2 Picture Tel Japan K.K. 0 v 11f3 Keithley Metrabyte 0 v 11f4 Kinetic Systems Corporation 0 d 11f42915 CAMAC controller 0 v 11f5 Computing Devices International 0 v 11f6 Compex 0 d 11f60112 ENet100VG4 0 d 11f60113 FreedomLine 100 0 d 11f61401 ReadyLink 2000 0 d 11f62011 RL100-ATX 10/100 0 s 11f6201111f62011 RL100-ATX 0 d 11f62201 ReadyLink 100TX (Winbond W89C840) 0 s 11f6220111f62011 ReadyLink 100TX 0 d 11f69881 RL100TX Fast Ethernet 0 v 11f7 Scientific Atlanta 0 v 11f8 PMC-Sierra Inc. 0 d 11f87375 PM7375 [LASAR-155 ATM SAR] 0 v 11f9 I-Cube Inc 0 v 11fa Kasan Electronics Company, Ltd. 0 v 11fb Datel Inc 0 v 11fc Silicon Magic 0 v 11fd High Street Consultants 0 v 11fe Comtrol Corporation 0 d 11fe0001 RocketPort 32 port w/external I/F 0 d 11fe0002 RocketPort 8 port w/external I/F 0 d 11fe0003 RocketPort 16 port w/external I/F 0 d 11fe0004 RocketPort 4 port w/quad cable 0 d 11fe0005 RocketPort 8 port w/octa cable 0 d 11fe0006 RocketPort 8 port w/RJ11 connectors 0 d 11fe0007 RocketPort 4 port w/RJ11 connectors 0 d 11fe0008 RocketPort 8 port w/ DB78 SNI (Siemens) connector 0 d 11fe0009 RocketPort 16 port w/ DB78 SNI (Siemens) connector 0 d 11fe000a RocketPort Plus 4 port 0 d 11fe000b RocketPort Plus 8 port 0 d 11fe000c RocketModem 6 port 0 d 11fe000d RocketModem 4-port 0 d 11fe000e RocketPort Plus 2 port RS232 0 d 11fe000f RocketPort Plus 2 port RS422 0 d 11fe0801 RocketPort UPCI 32 port w/external I/F 0 d 11fe0802 RocketPort UPCI 8 port w/external I/F 0 d 11fe0803 RocketPort UPCI 16 port w/external I/F 0 d 11fe0805 RocketPort UPCI 8 port w/octa cable 0 d 11fe080c RocketModem III 8 port 0 d 11fe080d RocketModem III 4 port 0 d 11fe0903 RocketPort Compact PCI 16 port w/external I/F 0 d 11fe8015 RocketPort 4-port UART 16954 0 v 11ff Scion Corporation 0 d 11ff0003 AG-5 0 v 1200 CSS Corporation 0 v 1201 Vista Controls Corp 0 v 1202 Network General Corp. 0 d 12024300 Gigabit Ethernet Adapter 0 s 1202430012029841 SK-9841 LX 0 s 1202430012029842 SK-9841 LX dual link 0 s 1202430012029843 SK-9843 SX 0 s 1202430012029844 SK-9843 SX dual link 0 v 1203 Bayer Corporation, Agfa Division 0 v 1204 Lattice Semiconductor Corporation 0 v 1205 Array Corporation 0 v 1206 Amdahl Corporation 0 v 1208 Parsytec GmbH 0 d 12084853 HS-Link Device 0 v 1209 SCI Systems Inc 0 v 120a Synaptel 0 v 120b Adaptive Solutions 0 v 120c Technical Corp. 0 v 120d Compression Labs, Inc. 0 v 120e Cyclades Corporation 0 d 120e0100 Cyclom-Y below first megabyte 0 d 120e0101 Cyclom-Y above first megabyte 0 d 120e0102 Cyclom-4Y below first megabyte 0 d 120e0103 Cyclom-4Y above first megabyte 0 d 120e0104 Cyclom-8Y below first megabyte 0 d 120e0105 Cyclom-8Y above first megabyte 0 d 120e0200 Cyclades-Z below first megabyte 0 d 120e0201 Cyclades-Z above first megabyte 0 d 120e0300 PC300/RSV or /X21 (2 ports) 0 d 120e0301 PC300/RSV or /X21 (1 port) 0 d 120e0310 PC300/TE (2 ports) 0 d 120e0311 PC300/TE (1 port) 0 d 120e0320 PC300/TE-M (2 ports) 0 d 120e0321 PC300/TE-M (1 port) 0 d 120e0400 PC400 0 v 120f Essential Communications 0 d 120f0001 Roadrunner serial HIPPI 0 v 1210 Hyperparallel Technologies 0 v 1211 Braintech Inc 0 v 1212 Kingston Technology Corp. 0 v 1213 Applied Intelligent Systems, Inc. 0 v 1214 Performance Technologies, Inc. 0 v 1215 Interware Co., Ltd 0 v 1216 Purup Prepress A/S 0 v 1217 O2 Micro, Inc. 0 d 12176729 OZ6729 0 d 1217673a OZ6730 0 d 12176832 OZ6832/6833 Cardbus Controller 0 d 12176836 OZ6836/6860 Cardbus Controller 0 d 12176872 OZ6812 Cardbus Controller 0 d 12176925 OZ6922 Cardbus Controller 0 d 12176933 OZ6933 Cardbus Controller 0 s 1217693310251016 Travelmate 612 TX 0 d 12176972 OZ6912 Cardbus Controller 0 s 121769721014020c ThinkPad R30 0 s 1217697211790001 Magnia Z310 0 d 12177110 OZ711Mx MultiMediaBay Accelerator 0 s 12177110103c0890 NC6000 laptop 0 d 12177112 OZ711EC1/M1 SmartCardBus MultiMediaBay Controller 0 d 12177113 OZ711EC1 SmartCardBus Controller 0 d 12177114 OZ711M1 SmartCardBus MultiMediaBay Controller 0 d 121771e2 OZ711E2 SmartCardBus Controller 0 d 12177212 OZ711M2 SmartCardBus MultiMediaBay Controller 0 d 12177213 OZ6933E CardBus Controller 0 d 12177223 OZ711M3 SmartCardBus MultiMediaBay Controller 0 s 12177223103c0890 NC6000 laptop 0 v 1218 Hybricon Corp. 0 v 1219 First Virtual Corporation 0 v 121a 3Dfx Interactive, Inc. 0 d 121a0001 Voodoo 0 d 121a0002 Voodoo 2 0 d 121a0003 Voodoo Banshee 0 s 121a000310920003 Monster Fusion 0 s 121a000310924000 Monster Fusion 0 s 121a000310924002 Monster Fusion 0 s 121a000310924801 Monster Fusion AGP 0 s 121a000310924803 Monster Fusion AGP 0 s 121a000310928030 Monster Fusion 0 s 121a000310928035 Monster Fusion AGP 0 s 121a000310b00001 Dragon 4000 0 s 121a000311021018 3D Blaster Banshee VE 0 s 121a0003121a0001 Voodoo Banshee AGP 0 s 121a0003121a0003 Voodoo Banshee AGP SGRAM 0 s 121a0003121a0004 Voodoo Banshee 0 s 121a0003139c0016 Raven 0 s 121a0003139c0017 Raven 0 s 121a000314af0002 Maxi Gamer Phoenix 0 d 121a0004 Voodoo Banshee [Velocity 100] 0 d 121a0005 Voodoo 3 0 s 121a0005121a0004 Voodoo3 AGP 0 s 121a0005121a0030 Voodoo3 AGP 0 s 121a0005121a0031 Voodoo3 AGP 0 s 121a0005121a0034 Voodoo3 AGP 0 s 121a0005121a0036 Voodoo3 2000 PCI 0 s 121a0005121a0037 Voodoo3 AGP 0 s 121a0005121a0038 Voodoo3 AGP 0 s 121a0005121a003a Voodoo3 AGP 0 s 121a0005121a0044 Voodoo3 0 s 121a0005121a004b Velocity 100 0 s 121a0005121a004c Velocity 200 0 s 121a0005121a004d Voodoo3 AGP 0 s 121a0005121a004e Voodoo3 AGP 0 s 121a0005121a0051 Voodoo3 AGP 0 s 121a0005121a0052 Voodoo3 AGP 0 s 121a0005121a0060 Voodoo3 3500 TV (NTSC) 0 s 121a0005121a0061 Voodoo3 3500 TV (PAL) 0 s 121a0005121a0062 Voodoo3 3500 TV (SECAM) 0 d 121a0009 Voodoo 4 / Voodoo 5 0 s 121a0009121a0003 Voodoo5 PCI 5500 0 s 121a0009121a0009 Voodoo5 AGP 5500/6000 0 d 121a0057 Voodoo 3/3000 [Avenger] 0 v 121b Advanced Telecommunications Modules 0 v 121c Nippon Texaco., Ltd 0 v 121d Lippert Automationstechnik GmbH 0 v 121e CSPI 0 v 121f Arcus Technology, Inc. 0 v 1220 Ariel Corporation 0 d 12201220 AMCC 5933 TMS320C80 DSP/Imaging board 0 v 1221 Contec Co., Ltd 0 v 1222 Ancor Communications, Inc. 0 v 1223 Artesyn Communication Products 0 d 12230003 PM/Link 0 d 12230004 PM/T1 0 d 12230005 PM/E1 0 d 12230008 PM/SLS 0 d 12230009 BajaSpan Resource Target 0 d 1223000a BajaSpan Section 0 0 d 1223000b BajaSpan Section 1 0 d 1223000c BajaSpan Section 2 0 d 1223000d BajaSpan Section 3 0 d 1223000e PM/PPC 0 v 1224 Interactive Images 0 v 1225 Power I/O, Inc. 0 v 1227 Tech-Source 0 d 12270006 Raptor GFX 8P 0 v 1228 Norsk Elektro Optikk A/S 0 v 1229 Data Kinesis Inc. 0 v 122a Integrated Telecom 0 v 122b LG Industrial Systems Co., Ltd 0 v 122c Sican GmbH 0 v 122d Aztech System Ltd 0 d 122d1206 368DSP 0 d 122d1400 Trident PCI288-Q3DII (NX) 0 d 122d50dc 3328 Audio 0 s 122d50dc122d0001 3328 Audio 0 d 122d80da 3328 Audio 0 s 122d80da122d0001 3328 Audio 0 v 122e Xyratex 0 v 122f Andrew Corporation 0 v 1230 Fishcamp Engineering 0 v 1231 Woodward McCoach, Inc. 0 v 1232 GPT Limited 0 v 1233 Bus-Tech, Inc. 0 v 1234 Technical Corp. 0 v 1235 Risq Modular Systems, Inc. 0 v 1236 Sigma Designs Corporation 0 d 12360000 RealMagic64/GX 0 d 12366401 REALmagic 64/GX (SD 6425) 0 v 1237 Alta Technology Corporation 0 v 1238 Adtran 0 v 1239 3DO Company 0 v 123a Visicom Laboratories, Inc. 0 v 123b Seeq Technology, Inc. 0 v 123c Century Systems, Inc. 0 v 123d Engineering Design Team, Inc. 0 d 123d0000 EasyConnect 8/32 0 d 123d0002 EasyConnect 8/64 0 d 123d0003 EasyIO 0 v 123e Simutech, Inc. 0 v 123f C-Cube Microsystems 0 d 123f00e4 MPEG 0 d 123f8120 E4? 0 s 123f812011bd0006 DV500 E4 0 s 123f812011bd000a DV500 E4 0 d 123f8888 Cinemaster C 3.0 DVD Decoder 0 s 123f888810020001 Cinemaster C 3.0 DVD Decoder 0 s 123f888810020002 Cinemaster C 3.0 DVD Decoder 0 s 123f888813280001 Cinemaster C 3.0 DVD Decoder 0 v 1240 Marathon Technologies Corp. 0 v 1241 DSC Communications 0 v 1242 JNI Corporation 0 Formerly Jaycor Networks, Inc. d 12421560 JNIC-1560 PCI-X Fibre Channel Controller 0 s 1242156012426562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter 0 s 124215601242656a FCX-6562 PCI-X Fibre Channel Adapter 0 d 12424643 FCI-1063 Fibre Channel Adapter 0 d 12426562 FCX2-6562 Dual Channel PCI-X Fibre Channel Adapter 0 d 1242656a FCX-6562 PCI-X Fibre Channel Adapter 0 v 1243 Delphax 0 v 1244 AVM Audiovisuelles MKTG & Computer System GmbH 0 d 12440700 B1 ISDN 0 d 12440800 C4 ISDN 0 d 12440a00 A1 ISDN [Fritz] 0 s 12440a0012440a00 FRITZ!Card ISDN Controller 0 d 12440e00 Fritz!PCI v2.0 ISDN 0 d 12441100 C2 ISDN 0 d 12441200 T1 ISDN 0 d 12442700 Fritz!Card DSL SL 0 d 12442900 Fritz!Card DSL v2.0 0 v 1245 A.P.D., S.A. 0 v 1246 Dipix Technologies, Inc. 0 v 1247 Xylon Research, Inc. 0 v 1248 Central Data Corporation 0 v 1249 Samsung Electronics Co., Ltd. 0 v 124a AEG Electrocom GmbH 0 v 124b SBS/Greenspring Modular I/O 0 d 124b0040 PCI-40A or cPCI-200 Quad IndustryPack carrier 0 s 124b0040124b9080 PCI9080 Bridge 0 v 124c Solitron Technologies, Inc. 0 v 124d Stallion Technologies, Inc. 0 d 124d0000 EasyConnection 8/32 0 d 124d0002 EasyConnection 8/64 0 d 124d0003 EasyIO 0 d 124d0004 EasyConnection/RA 0 v 124e Cylink 0 v 124f Infotrend Technology, Inc. 0 d 124f0041 IFT-2000 Series RAID Controller 0 v 1250 Hitachi Microcomputer System Ltd 0 v 1251 VLSI Solutions Oy 0 v 1253 Guzik Technical Enterprises 0 v 1254 Linear Systems Ltd. 0 v 1255 Optibase Ltd 0 d 12551110 MPEG Forge 0 d 12551210 MPEG Fusion 0 d 12552110 VideoPlex 0 d 12552120 VideoPlex CC 0 d 12552130 VideoQuest 0 v 1256 Perceptive Solutions, Inc. 0 d 12564201 PCI-2220I 0 d 12564401 PCI-2240I 0 d 12565201 PCI-2000 0 v 1257 Vertex Networks, Inc. 0 v 1258 Gilbarco, Inc. 0 v 1259 Allied Telesyn International 0 d 12592560 AT-2560 Fast Ethernet Adapter (i82557B) 0 d 1259a117 RTL81xx Fast Ethernet 0 d 1259a120 21x4x DEC-Tulip compatible 10/100 Ethernet 0 v 125a ABB Power Systems 0 v 125b Asix Electronics Corporation 0 d 125b1400 ALFA GFC2204 Fast Ethernet 0 v 125c Aurora Technologies, Inc. 0 d 125c0101 Saturn 4520P 0 d 125c0640 Aries 16000P 0 v 125d ESS Technology 0 d 125d0000 ES336H Fax Modem (Early Model) 0 d 125d1948 Solo? 0 d 125d1968 ES1968 Maestro 2 0 s 125d196810280085 ES1968 Maestro-2 PCI 0 s 125d196810338051 ES1968 Maestro-2 Audiodrive 0 d 125d1969 ES1969 Solo-1 Audiodrive 0 s 125d196910140166 ES1969 SOLO-1 AudioDrive on IBM Aptiva Mainboard 0 s 125d1969125d8888 Solo-1 Audio Adapter 0 d 125d1978 ES1978 Maestro 2E 0 s 125d19780e11b112 Armada M700/E500 0 s 125d19781033803c ES1978 Maestro-2E Audiodrive 0 s 125d197810338058 ES1978 Maestro-2E Audiodrive 0 s 125d197810924000 Monster Sound MX400 0 s 125d197811790001 ES1978 Maestro-2E Audiodrive 0 d 125d1988 ES1988 Allegro-1 0 s 125d198810924100 Sonic Impact S100 0 s 125d1988125d1988 ESS Allegro-1 Audiodrive 0 d 125d1989 ESS Modem 0 s 125d1989125d1989 ESS Modem 0 d 125d1998 ES1983S Maestro-3i PCI Audio Accelerator 0 s 125d1998102800b1 Latitude C600 0 s 125d1998102800e6 ES1983S Maestro-3i (Dell Inspiron 8100) 0 d 125d1999 ES1983S Maestro-3i PCI Modem Accelerator 0 d 125d199a ES1983S Maestro-3i PCI Audio Accelerator 0 d 125d199b ES1983S Maestro-3i PCI Modem Accelerator 0 d 125d2808 ES336H Fax Modem (Later Model) 0 d 125d2838 ES2838/2839 SuperLink Modem 0 d 125d2898 ES2898 Modem 0 s 125d2898125d0424 ES56-PI Data Fax Modem 0 s 125d2898125d0425 ES56T-PI Data Fax Modem 0 s 125d2898125d0426 ES56V-PI Data Fax Modem 0 s 125d2898125d0427 VW-PI Data Fax Modem 0 s 125d2898125d0428 ES56ST-PI Data Fax Modem 0 s 125d2898125d0429 ES56SV-PI Data Fax Modem 0 s 125d2898147ac001 ES56-PI Data Fax Modem 0 s 125d289814fe0428 ES56-PI Data Fax Modem 0 s 125d289814fe0429 ES56-PI Data Fax Modem 0 v 125e Specialvideo Engineering SRL 0 v 125f Concurrent Technologies, Inc. 0 v 1260 Intersil Corporation 0 d 12603872 Prism 2.5 Wavelan chipset 0 s 1260387214680202 LAN-Express IEEE 802.11b Wireless LAN 0 d 12603873 Prism 2.5 Wavelan chipset 0 s 1260387311863501 DWL-520 Wireless PCI Adapter 0 s 1260387311863700 DWL-520 Wireless PCI Adapter, Rev E1 0 s 1260387313854105 MA311 802.11b wireless adapter 0 s 1260387316680414 HWP01170-01 802.11b PCI Wireless Adapter 0 s 1260387316a51601 AIR.mate PC-400 PCI Wireless LAN Adapter 0 s 1260387317373874 WMP11 Wireless 802.11b PCI Adapter 0 s 1260387380862513 Wireless 802.11b MiniPCI Adapter 0 d 12603886 ISL3886 [Prism Javelin/Prism Xbow] 0 s 1260388617cf0037 Z-Com XG-901 and clones Wireless Adapter 0 d 12603890 Intersil ISL3890 [Prism GT/Prism Duette] 0 s 1260389010b82802 SMC2802W Wireless PCI Adapter 0 s 1260389010b82835 SMC2835W Wireless Cardbus Adapter 0 s 1260389010b8a835 SMC2835W V2 Wireless Cardbus Adapter 0 s 126038901113ee03 SMC2802W V2 Wireless PCI Adapter 0 s 1260389011863202 DWL-G650 A1 Wireless Adapter 0 s 126038901259c104 CG-WLCB54GT Wireless Adapter 0 s 1260389013854800 WG511 Wireless Adapter 0 s 1260389016a51605 ALLNET ALL0271 Wireless PCI Adapter 0 s 1260389017cf0014 Z-Com XG-600 and clones Wireless Adapter 0 s 1260389017cf0020 Z-Com XG-900 and clones Wireless Adapter 0 d 12608130 HMP8130 NTSC/PAL Video Decoder 0 d 12608131 HMP8131 NTSC/PAL Video Decoder 0 v 1261 Matsushita-Kotobuki Electronics Industries, Ltd. 0 v 1262 ES Computer Company, Ltd. 0 v 1263 Sonic Solutions 0 v 1264 Aval Nagasaki Corporation 0 v 1265 Casio Computer Co., Ltd. 0 v 1266 Microdyne Corporation 0 d 12660001 NE10/100 Adapter (i82557B) 0 d 12661910 NE2000Plus (RT8029) Ethernet Adapter 0 s 1266191012661910 NE2000Plus Ethernet Adapter 0 v 1267 S. A. Telecommunications 0 d 12675352 PCR2101 0 d 12675a4b Telsat Turbo 0 v 1268 Tektronix 0 v 1269 Thomson-CSF/TTM 0 v 126a Lexmark International, Inc. 0 v 126b Adax, Inc. 0 v 126c Northern Telecom 0 d 126c1211 10/100BaseTX [RTL81xx] 0 d 126c126c 802.11b Wireless Ethernet Adapter 0 v 126d Splash Technology, Inc. 0 v 126e Sumitomo Metal Industries, Ltd. 0 v 126f Silicon Motion, Inc. 0 d 126f0501 SM501 VoyagerGX 0 d 126f0710 SM710 LynxEM 0 d 126f0712 SM712 LynxEM+ 0 d 126f0720 SM720 Lynx3DM 0 d 126f0730 SM731 Cougar3DR 0 d 126f0810 SM810 LynxE 0 d 126f0811 SM811 LynxE 0 d 126f0820 SM820 Lynx3D 0 d 126f0910 SM910 0 v 1270 Olympus Optical Co., Ltd. 0 v 1271 GW Instruments 0 v 1272 Telematics International 0 v 1273 Hughes Network Systems 0 d 12730002 DirecPC 0 v 1274 Ensoniq 0 d 12741171 ES1373 [AudioPCI] (also Creative Labs CT5803) 0 d 12741371 ES1371 [AudioPCI-97] 0 s 127413710e110024 AudioPCI on Motherboard Compaq Deskpro 0 s 127413710e11b1a7 ES1371, ES1373 AudioPCI 0 s 12741371103380ac ES1371, ES1373 AudioPCI 0 s 1274137110421854 Tazer 0 s 12741371107b8054 Tabor2 0 s 1274137112741371 Creative Sound Blaster AudioPCI64V, AudioPCI128 0 s 1274137114626470 ES1371, ES1373 AudioPCI On Motherboard MS-6147 1.1A 0 s 1274137114626560 ES1371, ES1373 AudioPCI On Motherboard MS-6156 1.10 0 s 1274137114626630 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 1.0A 0 s 1274137114626631 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 1.0A 0 s 1274137114626632 ES1371, ES1373 AudioPCI On Motherboard MS-6163BX 2.0A 0 s 1274137114626633 ES1371, ES1373 AudioPCI On Motherboard MS-6163VIA 2.0A 0 s 1274137114626820 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00 0 s 1274137114626822 ES1371, ES1373 AudioPCI On Motherboard MS-6182 1.00A 0 s 1274137114626830 ES1371, ES1373 AudioPCI On Motherboard MS-6183 1.00 0 s 1274137114626880 ES1371, ES1373 AudioPCI On Motherboard MS-6188 1.00 0 s 1274137114626900 ES1371, ES1373 AudioPCI On Motherboard MS-6190 1.00 0 s 1274137114626910 ES1371, ES1373 AudioPCI On Motherboard MS-6191 0 s 1274137114626930 ES1371, ES1373 AudioPCI On Motherboard MS-6193 0 s 1274137114626990 ES1371, ES1373 AudioPCI On Motherboard MS-6199BX 2.0A 0 s 1274137114626991 ES1371, ES1373 AudioPCI On Motherboard MS-6199VIA 2.0A 0 s 1274137114a42077 ES1371, ES1373 AudioPCI On Motherboard KR639 0 s 1274137114a42105 ES1371, ES1373 AudioPCI On Motherboard MR800 0 s 1274137114a42107 ES1371, ES1373 AudioPCI On Motherboard MR801 0 s 1274137114a42172 ES1371, ES1373 AudioPCI On Motherboard DR739 0 s 1274137115099902 ES1371, ES1373 AudioPCI On Motherboard KW11 0 s 1274137115099903 ES1371, ES1373 AudioPCI On Motherboard KW31 0 s 1274137115099904 ES1371, ES1373 AudioPCI On Motherboard KA11 0 s 1274137115099905 ES1371, ES1373 AudioPCI On Motherboard KC13 0 s 12741371152d8801 ES1371, ES1373 AudioPCI On Motherboard CP810E 0 s 12741371152d8802 ES1371, ES1373 AudioPCI On Motherboard CP810 0 s 12741371152d8803 ES1371, ES1373 AudioPCI On Motherboard P3810E 0 s 12741371152d8804 ES1371, ES1373 AudioPCI On Motherboard P3810-S 0 s 12741371152d8805 ES1371, ES1373 AudioPCI On Motherboard P3820-S 0 s 12741371270f2001 ES1371, ES1373 AudioPCI On Motherboard 6CTR 0 s 12741371270f2200 ES1371, ES1373 AudioPCI On Motherboard 6WTX 0 s 12741371270f3000 ES1371, ES1373 AudioPCI On Motherboard 6WSV 0 s 12741371270f3100 ES1371, ES1373 AudioPCI On Motherboard 6WIV2 0 s 12741371270f3102 ES1371, ES1373 AudioPCI On Motherboard 6WIV 0 s 12741371270f7060 ES1371, ES1373 AudioPCI On Motherboard 6ASA2 0 s 1274137180864249 ES1371, ES1373 AudioPCI On Motherboard BI440ZX 0 s 127413718086424c ES1371, ES1373 AudioPCI On Motherboard BL440ZX 0 s 127413718086425a ES1371, ES1373 AudioPCI On Motherboard BZ440ZX 0 s 1274137180864341 ES1371, ES1373 AudioPCI On Motherboard Cayman 0 s 1274137180864343 ES1371, ES1373 AudioPCI On Motherboard Cape Cod 0 s 1274137180864649 ES1371, ES1373 AudioPCI On Motherboard Fire Island 0 s 127413718086464a ES1371, ES1373 AudioPCI On Motherboard FJ440ZX 0 s 1274137180864d4f ES1371, ES1373 AudioPCI On Motherboard Montreal 0 s 1274137180864f43 ES1371, ES1373 AudioPCI On Motherboard OC440LX 0 s 1274137180865243 ES1371, ES1373 AudioPCI On Motherboard RC440BX 0 s 1274137180865352 ES1371, ES1373 AudioPCI On Motherboard SunRiver 0 s 1274137180865643 ES1371, ES1373 AudioPCI On Motherboard Vancouver 0 s 1274137180865753 ES1371, ES1373 AudioPCI On Motherboard WS440BX 0 d 12745000 ES1370 [AudioPCI] 0 d 12745880 5880 AudioPCI 0 s 1274588012742000 Creative Sound Blaster AudioPCI128 0 s 1274588012742003 Creative SoundBlaster AudioPCI 128 0 s 1274588012745880 Creative Sound Blaster AudioPCI128 0 s 1274588012748001 Sound Blaster 16PCI 4.1ch 0 s 127458801458a000 5880 AudioPCI On Motherboard 6OXET 0 s 1274588014626880 5880 AudioPCI On Motherboard MS-6188 1.00 0 s 12745880270f2001 5880 AudioPCI On Motherboard 6CTR 0 s 12745880270f2200 5880 AudioPCI On Motherboard 6WTX 0 s 12745880270f7040 5880 AudioPCI On Motherboard 6ATA4 0 v 1275 Network Appliance Corporation 0 v 1276 Switched Network Technologies, Inc. 0 v 1277 Comstream 0 v 1278 Transtech Parallel Systems Ltd. 0 d 12780701 TPE3/TM3 PowerPC Node 0 d 12780710 TPE5 PowerPC PCI board 0 v 1279 Transmeta Corporation 0 d 12790295 Northbridge 0 d 12790395 LongRun Northbridge 0 d 12790396 SDRAM controller 0 d 12790397 BIOS scratchpad 0 v 127a Rockwell International 0 d 127a1002 HCF 56k Data/Fax Modem 0 s 127a10021092094c SupraExpress 56i PRO [Diamond SUP2380] 0 s 127a1002122d4002 HPG / MDP3858-U 0 s 127a1002122d4005 MDP3858-E 0 s 127a1002122d4007 MDP3858-A/-NZ 0 s 127a1002122d4012 MDP3858-SA 0 s 127a1002122d4017 MDP3858-W 0 s 127a1002122d4018 MDP3858-W 0 s 127a1002127a1002 Rockwell 56K D/F HCF Modem 0 d 127a1003 HCF 56k Data/Fax Modem 0 s 127a10030e11b0bc 229-DF Zephyr 0 s 127a10030e11b114 229-DF Cheetah 0 s 127a10031033802b 229-DF 0 s 127a100313df1003 PCI56RX Modem 0 s 127a100313e00117 IBM 0 s 127a100313e00147 IBM F-1156IV+/R3 Spain V.90 Modem 0 s 127a100313e00197 IBM 0 s 127a100313e001c7 IBM F-1156IV+/R3 WW V.90 Modem 0 s 127a100313e001f7 IBM 0 s 127a100314361003 IBM 0 s 127a100314361103 IBM 5614PM3G V.90 Modem 0 s 127a100314361602 Compaq 229-DF Ducati 0 d 127a1004 HCF 56k Data/Fax/Voice Modem 0 s 127a100410481500 MicroLink 56k Modem 0 s 127a100410cf1059 Fujitsu 229-DFRT 0 d 127a1005 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 s 127a100510338029 229-DFSV 0 s 127a100510338054 Modem 0 s 127a100510cf103c Fujitsu 0 s 127a100510cf1055 Fujitsu 229-DFSV 0 s 127a100510cf1056 Fujitsu 229-DFSV 0 s 127a1005122d4003 MDP3858SP-U 0 s 127a1005122d4006 Packard Bell MDP3858V-E 0 s 127a1005122d4008 MDP3858SP-A/SP-NZ 0 s 127a1005122d4009 MDP3858SP-E 0 s 127a1005122d4010 MDP3858V-U 0 s 127a1005122d4011 MDP3858SP-SA 0 s 127a1005122d4013 MDP3858V-A/V-NZ 0 s 127a1005122d4015 MDP3858SP-W 0 s 127a1005122d4016 MDP3858V-W 0 s 127a1005122d4019 MDP3858V-SA 0 s 127a100513df1005 PCI56RVP Modem 0 s 127a100513e00187 IBM 0 s 127a100513e001a7 IBM 0 s 127a100513e001b7 IBM DF-1156IV+/R3 Spain V.90 Modem 0 s 127a100513e001d7 IBM DF-1156IV+/R3 WW V.90 Modem 0 s 127a100514361005 IBM 0 s 127a100514361105 IBM 0 s 127a100514371105 IBM 5614PS3G V.90 Modem 0 d 127a1022 HCF 56k Modem 0 s 127a102214361303 M3-5614PM3G V.90 Modem 0 d 127a1023 HCF 56k Data/Fax Modem 0 s 127a1023122d4020 Packard Bell MDP3858-WE 0 s 127a1023122d4023 MDP3858-UE 0 s 127a102313e00247 IBM F-1156IV+/R6 Spain V.90 Modem 0 s 127a102313e00297 IBM 0 s 127a102313e002c7 IBM F-1156IV+/R6 WW V.90 Modem 0 s 127a102314361203 IBM 0 s 127a102314361303 IBM 0 d 127a1024 HCF 56k Data/Fax/Voice Modem 0 d 127a1025 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 s 127a102510cf106a Fujitsu 235-DFSV 0 s 127a1025122d4021 Packard Bell MDP3858V-WE 0 s 127a1025122d4022 MDP3858SP-WE 0 s 127a1025122d4024 MDP3858V-UE 0 s 127a1025122d4025 MDP3858SP-UE 0 d 127a1026 HCF 56k PCI Speakerphone Modem 0 d 127a1032 HCF 56k Modem 0 d 127a1033 HCF 56k Modem 0 d 127a1034 HCF 56k Modem 0 d 127a1035 HCF 56k PCI Speakerphone Modem 0 d 127a1036 HCF 56k Modem 0 d 127a1085 HCF 56k Volcano PCI Modem 0 d 127a2005 HCF 56k Data/Fax Modem 0 s 127a2005104d8044 229-DFSV 0 s 127a2005104d8045 229-DFSV 0 s 127a2005104d8055 PBE/Aztech 235W-DFSV 0 s 127a2005104d8056 235-DFSV 0 s 127a2005104d805a Modem 0 s 127a2005104d805f Modem 0 s 127a2005104d8074 Modem 0 d 127a2013 HSF 56k Data/Fax Modem 0 s 127a201311790001 Modem 0 s 127a20131179ff00 Modem 0 d 127a2014 HSF 56k Data/Fax/Voice Modem 0 s 127a201410cf1057 Fujitsu Citicorp III 0 s 127a2014122d4050 MSP3880-U 0 s 127a2014122d4055 MSP3880-W 0 d 127a2015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 s 127a201510cf1063 Fujitsu 0 s 127a201510cf1064 Fujitsu 0 s 127a201514682015 Fujitsu 0 d 127a2016 HSF 56k Data/Fax/Voice/Spkp Modem 0 s 127a2016122d4051 MSP3880V-W 0 s 127a2016122d4052 MSP3880SP-W 0 s 127a2016122d4054 MSP3880V-U 0 s 127a2016122d4056 MSP3880SP-U 0 s 127a2016122d4057 MSP3880SP-A 0 d 127a4311 Riptide HSF 56k PCI Modem 0 s 127a4311127a4311 Ring Modular? Riptide HSF RT HP Dom 0 s 127a431113e00210 HP-GVC 0 d 127a4320 Riptide PCI Audio Controller 0 s 127a432012354320 Riptide PCI Audio Controller 0 d 127a4321 Riptide HCF 56k PCI Modem 0 s 127a432112354321 Hewlett Packard DF 0 s 127a432112354324 Hewlett Packard DF 0 s 127a432113e00210 Hewlett Packard DF 0 s 127a4321144d2321 Riptide 0 d 127a4322 Riptide PCI Game Controller 0 s 127a432212354322 Riptide PCI Game Controller 0 d 127a8234 RapidFire 616X ATM155 Adapter 0 s 127a8234108d0022 RapidFire 616X ATM155 Adapter 0 s 127a8234108d0027 RapidFire 616X ATM155 Adapter 0 v 127b Pixera Corporation 0 v 127c Crosspoint Solutions, Inc. 0 v 127d Vela Research 0 v 127e Winnov, L.P. 0 v 127f Fujifilm 0 v 1280 Photoscript Group Ltd. 0 v 1281 Yokogawa Electric Corporation 0 v 1282 Davicom Semiconductor, Inc. 0 d 12829009 Ethernet 100/10 MBit 0 d 12829100 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 12829102 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 12829132 Ethernet 100/10 MBit 0 v 1283 Integrated Technology Express, Inc. 0 d 1283673a IT8330G 0 d 12838212 IT/ITE8212 Dual channel ATA RAID controller (PCI version seems to be IT8212, embedded seems to be ITE8212) 0 s 1283821212830001 IT/ITE8212 Dual channel ATA RAID controller 0 d 12838330 IT8330G 0 d 12838872 IT8874F PCI Dual Serial Port Controller 0 d 12838888 IT8888F PCI to ISA Bridge with SMB 0 d 12838889 IT8889F PCI to ISA Bridge 0 d 1283e886 IT8330G 0 v 1284 Sahara Networks, Inc. 0 v 1285 Platform Technologies, Inc. 0 d 12850100 AGOGO sound chip (aka ESS Maestro 1) 0 v 1286 Mazet GmbH 0 v 1287 M-Pact, Inc. 0 d 1287001e LS220D DVD Decoder 0 d 1287001f LS220C DVD Decoder 0 v 1288 Timestep Corporation 0 v 1289 AVC Technology, Inc. 0 v 128a Asante Technologies, Inc. 0 v 128b Transwitch Corporation 0 v 128c Retix Corporation 0 v 128d G2 Networks, Inc. 0 d 128d0021 ATM155 Adapter 0 v 128e Hoontech Corporation/Samho Multi Tech Ltd. 0 d 128e0008 ST128 WSS/SB 0 d 128e0009 ST128 SAM9407 0 d 128e000a ST128 Game Port 0 d 128e000b ST128 MPU Port 0 d 128e000c ST128 Ctrl Port 0 v 128f Tateno Dennou, Inc. 0 v 1290 Sord Computer Corporation 0 v 1291 NCS Computer Italia 0 v 1292 Tritech Microelectronics Inc 0 v 1293 Media Reality Technology 0 v 1294 Rhetorex, Inc. 0 v 1295 Imagenation Corporation 0 v 1296 Kofax Image Products 0 v 1297 Holco Enterprise Co, Ltd/Shuttle Computer 0 v 1298 Spellcaster Telecommunications Inc. 0 v 1299 Knowledge Technology Lab. 0 v 129a VMetro, inc. 0 d 129a0615 PBT-615 PCI-X Bus Analyzer 0 v 129b Image Access 0 v 129c Jaycor 0 v 129d Compcore Multimedia, Inc. 0 v 129e Victor Company of Japan, Ltd. 0 v 129f OEC Medical Systems, Inc. 0 v 12a0 Allen-Bradley Company 0 v 12a1 Simpact Associates, Inc. 0 v 12a2 Newgen Systems Corporation 0 v 12a3 Lucent Technologies 0 d 12a38105 T8105 H100 Digital Switch 0 v 12a4 NTT Electronics Technology Company 0 v 12a5 Vision Dynamics Ltd. 0 v 12a6 Scalable Networks, Inc. 0 v 12a7 AMO GmbH 0 v 12a8 News Datacom 0 v 12a9 Xiotech Corporation 0 v 12aa SDL Communications, Inc. 0 v 12ab Yuan Yuan Enterprise Co., Ltd. 0 d 12ab0002 AU8830 [Vortex2] Based Sound Card With A3D Support 0 d 12ab3000 MPG-200C PCI DVD Decoder Card 0 v 12ac Measurex Corporation 0 v 12ad Multidata GmbH 0 v 12ae Alteon Networks Inc. 0 d 12ae0001 AceNIC Gigabit Ethernet 0 s 12ae000110140104 Gigabit Ethernet-SX PCI Adapter 0 s 12ae000112ae0001 Gigabit Ethernet-SX (Universal) 0 s 12ae000114100104 Gigabit Ethernet-SX PCI Adapter 0 d 12ae0002 AceNIC Gigabit Ethernet (Copper) 0 s 12ae000210a98002 Acenic Gigabit Ethernet 0 s 12ae000212ae0002 Gigabit Ethernet-T (3C986-T) 0 d 12ae00fa Farallon PN9100-T Gigabit Ethernet 0 v 12af TDK USA Corp 0 v 12b0 Jorge Scientific Corp 0 v 12b1 GammaLink 0 v 12b2 General Signal Networks 0 v 12b3 Inter-Face Co Ltd 0 v 12b4 FutureTel Inc 0 v 12b5 Granite Systems Inc. 0 v 12b6 Natural Microsystems 0 v 12b7 Cognex Modular Vision Systems Div. - Acumen Inc. 0 v 12b8 Korg 0 v 12b9 3Com Corp, Modem Division (formerly US Robotics) 0 d 12b91006 WinModem 0 s 12b9100612b9005c USR 56k Internal Voice WinModem (Model 3472) 0 s 12b9100612b9005e USR 56k Internal WinModem (Models 662975) 0 s 12b9100612b90062 USR 56k Internal Voice WinModem (Model 662978) 0 s 12b9100612b90068 USR 56k Internal Voice WinModem (Model 5690) 0 s 12b9100612b9007a USR 56k Internal Voice WinModem (Model 662974) 0 s 12b9100612b9007f USR 56k Internal WinModem (Models 5698, 5699) 0 s 12b9100612b90080 USR 56k Internal WinModem (Models 2975, 3528) 0 s 12b9100612b90081 USR 56k Internal Voice WinModem (Models 2974, 3529) 0 s 12b9100612b90091 USR 56k Internal Voice WinModem (Model 2978) 0 d 12b91007 USR 56k Internal WinModem 0 s 12b9100712b900a3 USR 56k Internal WinModem (Model 3595) 0 d 12b91008 56K FaxModem Model 5610 0 s 12b9100812b900a2 USR 56k Internal FAX Modem (Model 2977) 0 s 12b9100812b900aa USR 56k Internal Voice Modem (Model 2976) 0 s 12b9100812b900ab USR 56k Internal Voice Modem (Model 5609) 0 s 12b9100812b900ac USR 56k Internal Voice Modem (Model 3298) 0 s 12b9100812b900ad USR 56k Internal FAX Modem (Model 5610) 0 v 12ba BittWare, Inc. 0 v 12bb Nippon Unisoft Corporation 0 v 12bc Array Microsystems 0 v 12bd Computerm Corp. 0 v 12be Anchor Chips Inc. 0 d 12be3041 AN3041Q CO-MEM 0 d 12be3042 AN3042Q CO-MEM Lite 0 s 12be304212be3042 Anchor Chips Lite Evaluation Board 0 v 12bf Fujifilm Microdevices 0 v 12c0 Infimed 0 v 12c1 GMM Research Corp 0 v 12c2 Mentec Limited 0 v 12c3 Holtek Microelectronics Inc 0 d 12c30058 PCI NE2K Ethernet 0 d 12c35598 PCI NE2K Ethernet 0 v 12c4 Connect Tech Inc 0 v 12c5 Picture Elements Incorporated 0 d 12c5007e Imaging/Scanning Subsystem Engine 0 d 12c5007f Imaging/Scanning Subsystem Engine 0 d 12c50081 PCIVST [Grayscale Thresholding Engine] 0 d 12c50085 Video Simulator/Sender 0 d 12c50086 THR2 Multi-scale Thresholder 0 v 12c6 Mitani Corporation 0 v 12c7 Dialogic Corp 0 v 12c8 G Force Co, Ltd 0 v 12c9 Gigi Operations 0 v 12ca Integrated Computing Engines 0 v 12cb Antex Electronics Corporation 0 v 12cc Pluto Technologies International 0 v 12cd Aims Lab 0 v 12ce Netspeed Inc. 0 v 12cf Prophet Systems, Inc. 0 v 12d0 GDE Systems, Inc. 0 v 12d1 PSITech 0 v 12d2 NVidia / SGS Thomson (Joint Venture) 0 d 12d20008 NV1 0 d 12d20009 DAC64 0 d 12d20018 Riva128 0 s 12d2001810480c10 VICTORY Erazor 0 s 12d20018107b8030 STB Velocity 128 0 s 12d2001810920350 Viper V330 0 s 12d2001810921092 Viper V330 0 s 12d2001810b41b1b STB Velocity 128 0 s 12d2001810b41b1d STB Velocity 128 0 s 12d2001810b41b1e STB Velocity 128, PAL TV-Out 0 s 12d2001810b41b20 STB Velocity 128 Sapphire 0 s 12d2001810b41b21 STB Velocity 128 0 s 12d2001810b41b22 STB Velocity 128 AGP, NTSC TV-Out 0 s 12d2001810b41b23 STB Velocity 128 AGP, PAL TV-Out 0 s 12d2001810b41b27 STB Velocity 128 DVD 0 s 12d2001810b41b88 MVP Pro 128 0 s 12d2001810b4222a STB Velocity 128 AGP 0 s 12d2001810b42230 STB Velocity 128 0 s 12d2001810b42232 STB Velocity 128 0 s 12d2001810b42235 STB Velocity 128 AGP 0 s 12d200182a1554a3 3DVision-SAGP / 3DexPlorer 3000 0 d 12d20019 Riva128ZX 0 d 12d20020 TNT 0 d 12d20028 TNT2 0 d 12d20029 UTNT2 0 d 12d2002c VTNT2 0 d 12d200a0 ITNT2 0 v 12d3 Vingmed Sound A/S 0 v 12d4 Ulticom (Formerly DGM&S) 0 d 12d40200 T1 Card 0 v 12d5 Equator Technologies Inc 0 v 12d6 Analogic Corp 0 v 12d7 Biotronic SRL 0 v 12d8 Pericom Semiconductor 0 v 12d9 Aculab PLC 0 d 12d90002 PCI Prosody 0 d 12d90004 cPCI Prosody 0 d 12d90005 Aculab E1/T1 PCI card 0 v 12da True Time Inc. 0 v 12db Annapolis Micro Systems, Inc 0 v 12dc Symicron Computer Communication Ltd. 0 v 12dd Management Graphics 0 v 12de Rainbow Technologies 0 d 12de0200 CryptoSwift CS200 0 v 12df SBS Technologies Inc 0 v 12e0 Chase Research 0 d 12e00010 ST16C654 Quad UART 0 d 12e00020 ST16C654 Quad UART 0 d 12e00030 ST16C654 Quad UART 0 v 12e1 Nintendo Co, Ltd 0 v 12e2 Datum Inc. Bancomm-Timing Division 0 v 12e3 Imation Corp - Medical Imaging Systems 0 v 12e4 Brooktrout Technology Inc 0 v 12e5 Apex Semiconductor Inc 0 v 12e6 Cirel Systems 0 v 12e7 Sunsgroup Corporation 0 v 12e8 Crisc Corp 0 v 12e9 GE Spacenet 0 v 12ea Zuken 0 v 12eb Aureal Semiconductor 0 d 12eb0001 Vortex 1 0 s 12eb0001104d8036 AU8820 Vortex Digital Audio Processor 0 s 12eb000110922000 Sonic Impact A3D 0 s 12eb000110922100 Sonic Impact A3D 0 s 12eb000110922110 Sonic Impact A3D 0 s 12eb000110922200 Sonic Impact A3D 0 s 12eb0001122d1002 AU8820 Vortex Digital Audio Processor 0 s 12eb000112eb0001 AU8820 Vortex Digital Audio Processor 0 s 12eb000150533355 Montego 0 d 12eb0002 Vortex 2 0 s 12eb0002104d8049 AU8830 Vortex 3D Digital Audio Processor 0 s 12eb0002104d807b AU8830 Vortex 3D Digital Audio Processor 0 s 12eb000210923000 Monster Sound II 0 s 12eb000210923001 Monster Sound II 0 s 12eb000210923002 Monster Sound II 0 s 12eb000210923003 Monster Sound II 0 s 12eb000210923004 Monster Sound II 0 s 12eb000212eb0001 AU8830 Vortex 3D Digital Audio Processor 0 s 12eb000212eb0002 AU8830 Vortex 3D Digital Audio Processor 0 s 12eb000212eb0088 AU8830 Vortex 3D Digital Audio Processor 0 s 12eb0002144d3510 AU8830 Vortex 3D Digital Audio Processor 0 s 12eb000250533356 Montego II 0 d 12eb0003 AU8810 Vortex Digital Audio Processor 0 s 12eb0003104d8049 AU8810 Vortex Digital Audio Processor 0 s 12eb0003104d8077 AU8810 Vortex Digital Audio Processor 0 s 12eb0003109f1000 AU8810 Vortex Digital Audio Processor 0 s 12eb000312eb0003 AU8810 Vortex Digital Audio Processor 0 s 12eb000314626780 AU8810 Vortex Digital Audio Processor 0 s 12eb000314a42073 AU8810 Vortex Digital Audio Processor 0 s 12eb000314a42091 AU8810 Vortex Digital Audio Processor 0 s 12eb000314a42104 AU8810 Vortex Digital Audio Processor 0 s 12eb000314a42106 AU8810 Vortex Digital Audio Processor 0 d 12eb8803 Vortex 56k Software Modem 0 s 12eb880312eb8803 Vortex 56k Software Modem 0 v 12ec 3A International, Inc. 0 v 12ed Optivision Inc. 0 v 12ee Orange Micro 0 v 12ef Vienna Systems 0 v 12f0 Pentek 0 v 12f1 Sorenson Vision Inc 0 v 12f2 Gammagraphx, Inc. 0 v 12f3 Radstone Technology 0 v 12f4 Megatel 0 v 12f5 Forks 0 v 12f6 Dawson France 0 v 12f7 Cognex 0 v 12f8 Electronic Design GmbH 0 d 12f80002 VideoMaker 0 v 12f9 Four Fold Ltd 0 v 12fb Spectrum Signal Processing 0 v 12fc Capital Equipment Corp 0 v 12fd I2S 0 v 12fe ESD Electronic System Design GmbH 0 v 12ff Lexicon 0 v 1300 Harman International Industries Inc 0 v 1302 Computer Sciences Corp 0 v 1303 Innovative Integration 0 v 1304 Juniper Networks 0 v 1305 Netphone, Inc 0 v 1306 Duet Technologies 0 v 1307 Measurement Computing 0 Formerly ComputerBoards d 13070001 PCI-DAS1602/16 0 d 1307000b PCI-DIO48H 0 d 1307000c PCI-PDISO8 0 d 1307000d PCI-PDISO16 0 d 1307000f PCI-DAS1200 0 d 13070010 PCI-DAS1602/12 0 d 13070014 PCI-DIO24H 0 d 13070015 PCI-DIO24H/CTR3 0 d 13070016 PCI-DIO48H/CTR15 0 d 13070017 PCI-DIO96H 0 d 13070018 PCI-CTR05 0 d 13070019 PCI-DAS1200/JR 0 d 1307001a PCI-DAS1001 0 d 1307001b PCI-DAS1002 0 d 1307001c PCI-DAS1602JR/16 0 d 1307001d PCI-DAS6402/16 0 d 1307001e PCI-DAS6402/12 0 d 1307001f PCI-DAS16/M1 0 d 13070020 PCI-DDA02/12 0 d 13070021 PCI-DDA04/12 0 d 13070022 PCI-DDA08/12 0 d 13070023 PCI-DDA02/16 0 d 13070024 PCI-DDA04/16 0 d 13070025 PCI-DDA08/16 0 d 13070026 PCI-DAC04/12-HS 0 d 13070027 PCI-DAC04/16-HS 0 d 13070028 PCI-DIO24 0 d 13070029 PCI-DAS08 0 d 1307002c PCI-INT32 0 d 13070033 PCI-DUAL-AC5 0 d 13070034 PCI-DAS-TC 0 d 13070035 PCI-DAS64/M1/16 0 d 13070036 PCI-DAS64/M2/16 0 d 13070037 PCI-DAS64/M3/16 0 d 1307004c PCI-DAS1000 0 d 1307004d PCI-QUAD04 0 d 13070052 PCI-DAS4020/12 0 d 1307005e PCI-DAS6025 0 v 1308 Jato Technologies Inc. 0 d 13080001 NetCelerator Adapter 0 s 1308000113080001 NetCelerator Adapter 0 v 1309 AB Semiconductor Ltd 0 v 130a Mitsubishi Electric Microcomputer 0 v 130b Colorgraphic Communications Corp 0 v 130c Ambex Technologies, Inc 0 v 130d Accelerix Inc 0 v 130e Yamatake-Honeywell Co. Ltd 0 v 130f Advanet Inc 0 v 1310 Gespac 0 v 1311 Videoserver, Inc 0 v 1312 Acuity Imaging, Inc 0 v 1313 Yaskawa Electric Co. 0 v 1316 Teradyne Inc 0 v 1317 Linksys 0 d 13170981 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 13170985 NC100 Network Everywhere Fast Ethernet 10/100 0 d 13171985 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 13172850 HSP MicroModem 56 0 d 13178201 ADMtek ADM8211 802.11b Wireless Interface 0 s 1317820110b82635 SMC2635W 802.11b (11Mbps) wireless lan pcmcia (cardbus) card 0 s 1317820113178201 SMC2635W 802.11b (11mbps) wireless lan pcmcia (cardbus) card 0 d 13178211 ADMtek ADM8211 802.11b Wireless Interface 0 d 13179511 21x4x DEC-Tulip compatible 10/100 Ethernet 0 v 1318 Packet Engines Inc. 0 d 13180911 GNIC-II PCI Gigabit Ethernet [Hamachi] 0 v 1319 Fortemedia, Inc 0 d 13190801 Xwave QS3000A [FM801] 0 d 13190802 Xwave QS3000A [FM801 game port] 0 d 13191000 FM801 PCI Audio 0 d 13191001 FM801 PCI Joystick 0 v 131a Finisar Corp. 0 v 131c Nippon Electro-Sensory Devices Corp 0 v 131d Sysmic, Inc. 0 v 131e Xinex Networks Inc 0 v 131f Siig Inc 0 d 131f1000 CyberSerial (1-port) 16550 0 d 131f1001 CyberSerial (1-port) 16650 0 d 131f1002 CyberSerial (1-port) 16850 0 d 131f1010 Duet 1S(16550)+1P 0 d 131f1011 Duet 1S(16650)+1P 0 d 131f1012 Duet 1S(16850)+1P 0 d 131f1020 CyberParallel (1-port) 0 d 131f1021 CyberParallel (2-port) 0 d 131f1030 CyberSerial (2-port) 16550 0 d 131f1031 CyberSerial (2-port) 16650 0 d 131f1032 CyberSerial (2-port) 16850 0 d 131f1034 Trio 2S(16550)+1P 0 d 131f1035 Trio 2S(16650)+1P 0 d 131f1036 Trio 2S(16850)+1P 0 d 131f1050 CyberSerial (4-port) 16550 0 d 131f1051 CyberSerial (4-port) 16650 0 d 131f1052 CyberSerial (4-port) 16850 0 d 131f2000 CyberSerial (1-port) 16550 0 d 131f2001 CyberSerial (1-port) 16650 0 d 131f2002 CyberSerial (1-port) 16850 0 d 131f2010 Duet 1S(16550)+1P 0 d 131f2011 Duet 1S(16650)+1P 0 d 131f2012 Duet 1S(16850)+1P 0 d 131f2020 CyberParallel (1-port) 0 d 131f2021 CyberParallel (2-port) 0 d 131f2030 CyberSerial (2-port) 16550 0 s 131f2030131f2030 PCI Serial Card 0 d 131f2031 CyberSerial (2-port) 16650 0 d 131f2032 CyberSerial (2-port) 16850 0 d 131f2040 Trio 1S(16550)+2P 0 d 131f2041 Trio 1S(16650)+2P 0 d 131f2042 Trio 1S(16850)+2P 0 d 131f2050 CyberSerial (4-port) 16550 0 d 131f2051 CyberSerial (4-port) 16650 0 d 131f2052 CyberSerial (4-port) 16850 0 d 131f2060 Trio 2S(16550)+1P 0 d 131f2061 Trio 2S(16650)+1P 0 d 131f2062 Trio 2S(16850)+1P 0 d 131f2081 CyberSerial (8-port) ST16654 0 v 1320 Crypto AG 0 v 1321 Arcobel Graphics BV 0 v 1322 MTT Co., Ltd 0 v 1323 Dome Inc 0 v 1324 Sphere Communications 0 v 1325 Salix Technologies, Inc 0 v 1326 Seachange international 0 v 1327 Voss scientific 0 v 1328 quadrant international 0 v 1329 Productivity Enhancement 0 v 132a Microcom Inc. 0 v 132b Broadband Technologies 0 v 132c Micrel Inc 0 v 132d Integrated Silicon Solution, Inc. 0 v 1330 MMC Networks 0 v 1331 Radisys Corp. 0 d 13310030 ENP-2611 0 d 13318200 82600 Host Bridge 0 d 13318201 82600 IDE 0 d 13318202 82600 USB 0 d 13318210 82600 PCI Bridge 0 v 1332 Micro Memory 0 d 13325415 MM-5415CN PCI Memory Module with Battery Backup 0 d 13325425 MM-5425CN PCI 64/66 Memory Module with Battery Backup 0 v 1334 Redcreek Communications, Inc 0 v 1335 Videomail, Inc 0 v 1337 Third Planet Publishing 0 v 1338 BT Electronics 0 v 133a Vtel Corp 0 v 133b Softcom Microsystems 0 v 133c Holontech Corp 0 v 133d SS Technologies 0 v 133e Virtual Computer Corp 0 v 133f SCM Microsystems 0 v 1340 Atalla Corp 0 v 1341 Kyoto Microcomputer Co 0 v 1342 Promax Systems Inc 0 v 1343 Phylon Communications Inc 0 v 1344 Crucial Technology 0 v 1345 Arescom Inc 0 v 1347 Odetics 0 v 1349 Sumitomo Electric Industries, Ltd. 0 v 134a DTC Technology Corp. 0 d 134a0001 Domex 536 0 d 134a0002 Domex DMX3194UP SCSI Adapter 0 v 134b ARK Research Corp. 0 v 134c Chori Joho System Co. Ltd 0 v 134d PCTel Inc 0 d 134d2189 HSP56 MicroModem 0 d 134d2486 2304WT V.92 MDC Modem 0 d 134d7890 HSP MicroModem 56 0 s 134d7890134d0001 PCT789 adapter 0 d 134d7891 HSP MicroModem 56 0 s 134d7891134d0001 HSP MicroModem 56 0 d 134d7892 HSP MicroModem 56 0 d 134d7893 HSP MicroModem 56 0 d 134d7894 HSP MicroModem 56 0 d 134d7895 HSP MicroModem 56 0 d 134d7896 HSP MicroModem 56 0 d 134d7897 HSP MicroModem 56 0 v 134e CSTI 0 v 134f Algo System Co Ltd 0 v 1350 Systec Co. Ltd 0 v 1351 Sonix Inc 0 v 1353 Thales Idatys 0 d 13530002 Proserver 0 d 13530003 PCI-FUT 0 d 13530004 PCI-S0 0 d 13530005 PCI-FUT-S0 0 v 1354 Dwave System Inc 0 v 1355 Kratos Analytical Ltd 0 v 1356 The Logical Co 0 v 1359 Prisa Networks 0 v 135a Brain Boxes 0 v 135b Giganet Inc 0 v 135c Quatech Inc 0 d 135c0010 QSC-100 0 d 135c0020 DSC-100 0 d 135c0030 DSC-200/300 0 d 135c0040 QSC-200/300 0 d 135c0050 ESC-100D 0 d 135c0060 ESC-100M 0 d 135c00f0 MPAC-100 Syncronous Serial Card (Zilog 85230) 0 d 135c0170 QSCLP-100 0 d 135c0180 DSCLP-100 0 d 135c0190 SSCLP-100 0 d 135c01a0 QSCLP-200/300 0 d 135c01b0 DSCLP-200/300 0 d 135c01c0 SSCLP-200/300 0 v 135d ABB Network Partner AB 0 v 135e Sealevel Systems Inc 0 d 135e5101 Route 56.PCI - Multi-Protocol Serial Interface (Zilog Z16C32) 0 d 135e7101 Single Port RS-232/422/485/530 0 d 135e7201 Dual Port RS-232/422/485 Interface 0 d 135e7202 Dual Port RS-232 Interface 0 d 135e7401 Four Port RS-232 Interface 0 d 135e7402 Four Port RS-422/485 Interface 0 d 135e7801 Eight Port RS-232 Interface 0 d 135e8001 8001 Digital I/O Adapter 0 v 135f I-Data International A-S 0 v 1360 Meinberg Funkuhren 0 d 13600101 PCI32 DCF77 Radio Clock 0 d 13600102 PCI509 DCF77 Radio Clock 0 d 13600103 PCI510 DCF77 Radio Clock 0 d 13600201 GPS167PCI GPS Receiver 0 d 13600202 GPS168PCI GPS Receiver 0 d 13600203 GPS169PCI GPS Receiver 0 d 13600301 TCR510PCI IRIG Receiver 0 v 1361 Soliton Systems K.K. 0 v 1362 Fujifacom Corporation 0 v 1363 Phoenix Technology Ltd 0 v 1364 ATM Communications Inc 0 v 1365 Hypercope GmbH 0 v 1366 Teijin Seiki Co. Ltd 0 v 1367 Hitachi Zosen Corporation 0 v 1368 Skyware Corporation 0 v 1369 Digigram 0 v 136a High Soft Tech 0 v 136b Kawasaki Steel Corporation 0 d 136bff01 KL5A72002 Motion JPEG 0 v 136c Adtek System Science Co Ltd 0 v 136d Gigalabs Inc 0 v 136f Applied Magic Inc 0 v 1370 ATL Products 0 v 1371 CNet Technology Inc 0 d 1371434e GigaCard Network Adapter 0 s 1371434e1371434e N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L) 0 v 1373 Silicon Vision Inc 0 v 1374 Silicom Ltd 0 v 1375 Argosystems Inc 0 v 1376 LMC 0 v 1377 Electronic Equipment Production & Distribution GmbH 0 v 1378 Telemann Co. Ltd 0 v 1379 Asahi Kasei Microsystems Co Ltd 0 v 137a Mark of the Unicorn Inc 0 d 137a0001 PCI-324 Audiowire Interface 0 v 137b PPT Vision 0 v 137c Iwatsu Electric Co Ltd 0 v 137d Dynachip Corporation 0 v 137e Patriot Scientific Corporation 0 v 137f Japan Satellite Systems Inc 0 v 1380 Sanritz Automation Co Ltd 0 v 1381 Brains Co. Ltd 0 v 1382 Marian - Electronic & Software 0 d 13820001 ARC88 audio recording card 0 d 13822088 Marc-8 MIDI 8 channel audio card 0 v 1383 Controlnet Inc 0 v 1384 Reality Simulation Systems Inc 0 v 1385 Netgear 0 d 13850013 WG311T 0 Note: This lists as Atheros Communications, Inc. AR5212 802.11abg NIC because of Madwifi d 13854100 802.11b Wireless Adapter (MA301) 0 d 13854105 MA311 802.11b wireless adapter 0 d 13854400 WAG511 802.11a/b/g Dual Band Wireless PC Card 0 d 13854600 WAG511 802.11a/b/g Dual Band Wireless PC Card 0 d 13854601 WAG511 802.11a/b/g Dual Band Wireless PC Card 0 d 13854610 WAG511 802.11a/b/g Dual Band Wireless PC Card 0 d 13854a00 WAG311 802.11a/g Wireless PCI Adapter 0 d 13854c00 WG311v2 54 Mbps Wireless PCI Adapter 0 d 1385620a GA620 Gigabit Ethernet 0 d 1385622a GA622 0 d 1385630a GA630 Gigabit Ethernet 0 d 1385f004 FA310TX 0 v 1386 Video Domain Technologies 0 v 1387 Systran Corp 0 v 1388 Hitachi Information Technology Co Ltd 0 v 1389 Applicom International 0 d 13890001 PCI1500PFB [Intelligent fieldbus adaptor] 0 v 138a Fusion Micromedia Corp 0 v 138b Tokimec Inc 0 v 138c Silicon Reality 0 v 138d Future Techno Designs pte Ltd 0 v 138e Basler GmbH 0 v 138f Patapsco Designs Inc 0 v 1390 Concept Development Inc 0 v 1391 Development Concepts Inc 0 v 1392 Medialight Inc 0 v 1393 Moxa Technologies Co Ltd 0 d 13931040 Smartio C104H/PCI 0 d 13931141 Industrio CP-114 0 d 13931680 Smartio C168H/PCI 0 d 13932040 Intellio CP-204J 0 d 13932180 Intellio C218 Turbo PCI 0 d 13933200 Intellio C320 Turbo PCI 0 v 1394 Level One Communications 0 d 13940001 LXT1001 Gigabit Ethernet 0 s 1394000113940001 NetCelerator Adapter 0 v 1395 Ambicom Inc 0 v 1396 Cipher Systems Inc 0 v 1397 Cologne Chip Designs GmbH 0 d 13972bd0 ISDN network controller [HFC-PCI] 0 s 13972bd013972bd0 ISDN Board 0 s 13972bd0e4bf1000 CI1-1-Harp 0 v 1398 Clarion co. Ltd 0 v 1399 Rios systems Co Ltd 0 v 139a Alacritech Inc 0 d 139a0001 Quad Port 10/100 Server Accelerator 0 d 139a0003 Single Port 10/100 Server Accelerator 0 d 139a0005 Single Port Gigabit Server Accelerator 0 v 139b Mediasonic Multimedia Systems Ltd 0 v 139c Quantum 3d Inc 0 v 139d EPL limited 0 v 139e Media4 0 v 139f Aethra s.r.l. 0 v 13a0 Crystal Group Inc 0 v 13a1 Kawasaki Heavy Industries Ltd 0 v 13a2 Ositech Communications Inc 0 v 13a3 Hifn Inc. 0 d 13a30005 7751 Security Processor 0 d 13a30006 6500 Public Key Processor 0 d 13a30007 7811 Security Processor 0 d 13a30012 7951 Security Processor 0 d 13a30014 78XX Security Processor 0 d 13a30016 8065 Security Processor 0 d 13a30017 8165 Security Processor 0 d 13a30018 8154 Security Processor 0 v 13a4 Rascom Inc 0 v 13a5 Audio Digital Imaging Inc 0 v 13a6 Videonics Inc 0 v 13a7 Teles AG 0 v 13a8 Exar Corp. 0 d 13a80154 XR17C154 Quad UART 0 d 13a80158 XR17C158 Octal UART 0 v 13a9 Siemens Medical Systems, Ultrasound Group 0 v 13aa Broadband Networks Inc 0 v 13ab Arcom Control Systems Ltd 0 v 13ac Motion Media Technology Ltd 0 v 13ad Nexus Inc 0 v 13ae ALD Technology Ltd 0 v 13af T.Sqware 0 v 13b0 Maxspeed Corp 0 v 13b1 Tamura corporation 0 v 13b2 Techno Chips Co. Ltd 0 v 13b3 Lanart Corporation 0 v 13b4 Wellbean Co Inc 0 v 13b5 ARM 0 v 13b6 Dlog GmbH 0 v 13b7 Logic Devices Inc 0 v 13b8 Nokia Telecommunications oy 0 v 13b9 Elecom Co Ltd 0 v 13ba Oxford Instruments 0 v 13bb Sanyo Technosound Co Ltd 0 v 13bc Bitran Corporation 0 v 13bd Sharp corporation 0 v 13be Miroku Jyoho Service Co. Ltd 0 v 13bf Sharewave Inc 0 v 13c0 Microgate Corporation 0 d 13c00010 SyncLink Adapter v1 0 d 13c00020 SyncLink SCC Adapter 0 d 13c00030 SyncLink Multiport Adapter 0 d 13c00210 SyncLink Adapter v2 0 v 13c1 3ware Inc 0 d 13c11000 3ware Inc 3ware 5xxx/6xxx-series PATA-RAID 0 d 13c11001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID 0 s 13c1100113c11001 3ware Inc 3ware 7xxx/8xxx-series PATA/SATA-RAID 0 d 13c11002 3ware Inc 3ware 9xxx-series SATA-RAID 0 v 13c2 Technotrend Systemtechnik GmbH 0 v 13c3 Janz Computer AG 0 v 13c4 Phase Metrics 0 v 13c5 Alphi Technology Corp 0 v 13c6 Condor Engineering Inc 0 d 13c60520 CEI-520 A429 Card 0 d 13c60620 CEI-620 A429 Card 0 d 13c60820 CEI-820 A429 Card 0 v 13c7 Blue Chip Technology Ltd 0 v 13c8 Apptech Inc 0 v 13c9 Eaton Corporation 0 v 13ca Iomega Corporation 0 v 13cb Yano Electric Co Ltd 0 v 13cc Metheus Corporation 0 v 13cd Compatible Systems Corporation 0 v 13ce Cocom A/S 0 v 13cf Studio Audio & Video Ltd 0 v 13d0 Techsan Electronics Co Ltd 0 d 13d02103 B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card 0 d 13d02200 B2C2 FlexCopIII DVB chip / Technisat SkyStar2 DVB card 0 v 13d1 Abocom Systems Inc 0 d 13d1ab02 ADMtek Centaur-C rev 17 [D-Link DFE-680TX] CardBus Fast Ethernet Adapter 0 d 13d1ab03 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 13d1ab06 RTL8139 [FE2000VX] CardBus Fast Ethernet Attached Port Adapter 0 d 13d1ab08 21x4x DEC-Tulip compatible 10/100 Ethernet 0 v 13d2 Shark Multimedia Inc 0 v 13d3 IMC Networks 0 v 13d4 Graphics Microsystems Inc 0 v 13d5 Media 100 Inc 0 v 13d6 K.I. Technology Co Ltd 0 v 13d7 Toshiba Engineering Corporation 0 v 13d8 Phobos corporation 0 v 13d9 Apex PC Solutions Inc 0 v 13da Intresource Systems pte Ltd 0 v 13db Janich & Klass Computertechnik GmbH 0 v 13dc Netboost Corporation 0 v 13dd Multimedia Bundle Inc 0 v 13de ABB Robotics Products AB 0 v 13df E-Tech Inc 0 d 13df0001 PCI56RVP Modem 0 s 13df000113df0001 PCI56RVP Modem 0 v 13e0 GVC Corporation 0 v 13e1 Silicom Multimedia Systems Inc 0 v 13e2 Dynamics Research Corporation 0 v 13e3 Nest Inc 0 v 13e4 Calculex Inc 0 v 13e5 Telesoft Design Ltd 0 v 13e6 Argosy research Inc 0 v 13e7 NAC Incorporated 0 v 13e8 Chip Express Corporation 0 v 13e9 Intraserver Technology Inc 0 v 13ea Dallas Semiconductor 0 v 13eb Hauppauge Computer Works Inc 0 v 13ec Zydacron Inc 0 v 13ed Raytheion E-Systems 0 v 13ee Hayes Microcomputer Products Inc 0 v 13ef Coppercom Inc 0 v 13f0 Sundance Technology Inc 0 d 13f00201 ST201 Sundance Ethernet 0 v 13f1 Oce' - Technologies B.V. 0 v 13f2 Ford Microelectronics Inc 0 v 13f3 Mcdata Corporation 0 v 13f4 Troika Networks, Inc. 0 d 13f41401 Zentai Fibre Channel Adapter 0 v 13f5 Kansai Electric Co. Ltd 0 v 13f6 C-Media Electronics Inc 0 d 13f60011 CMI8738 0 d 13f60100 CM8338A 0 s 13f6010013f6ffff CMI8338/C3DX PCI Audio Device 0 d 13f60101 CM8338B 0 s 13f6010113f60101 CMI8338-031 PCI Audio Device 0 d 13f60111 CM8738 0 s 13f6011110190970 P6STP-FL motherboard 0 s 13f6011110438035 CUSI-FX motherboard 0 s 13f6011110438077 CMI8738 6-channel audio controller 0 s 13f60111104380e2 CMI8738 6ch-MX 0 s 13f6011113f60111 CMI8738/C3DX PCI Audio Device 0 s 13f601111681a000 Gamesurround MUSE XL 0 d 13f60211 CM8738 0 v 13f7 Wildfire Communications 0 v 13f8 Ad Lib Multimedia Inc 0 v 13f9 NTT Advanced Technology Corp. 0 v 13fa Pentland Systems Ltd 0 v 13fb Aydin Corp 0 v 13fc Computer Peripherals International 0 v 13fd Micro Science Inc 0 v 13fe Advantech Co. Ltd 0 d 13fe1240 PCI-1240 4-channel stepper motor controller card w. Nova Electronics MCX314 0 d 13fe1600 PCI-1612 4-port RS-232/422/485 PCI Communication Card 0 d 13fe1752 PCI-1752 0 d 13fe1754 PCI-1754 0 d 13fe1756 PCI-1756 0 v 13ff Silicon Spice Inc 0 v 1400 Artx Inc 0 d 14001401 9432 TX 0 v 1401 CR-Systems A/S 0 v 1402 Meilhaus Electronic GmbH 0 v 1403 Ascor Inc 0 v 1404 Fundamental Software Inc 0 v 1405 Excalibur Systems Inc 0 v 1406 Oce' Printing Systems GmbH 0 v 1407 Lava Computer mfg Inc 0 d 14070100 Lava Dual Serial 0 d 14070101 Lava Quatro A 0 d 14070102 Lava Quatro B 0 d 14070120 Quattro-PCI A 0 d 14070121 Quattro-PCI B 0 d 14070180 Lava Octo A 0 d 14070181 Lava Octo B 0 d 14070200 Lava Port Plus 0 d 14070201 Lava Quad A 0 d 14070202 Lava Quad B 0 d 14070220 Lava Quattro PCI Ports A/B 0 d 14070221 Lava Quattro PCI Ports C/D 0 d 14070500 Lava Single Serial 0 d 14070600 Lava Port 650 0 d 14078000 Lava Parallel 0 d 14078001 Dual parallel port controller A 0 d 14078002 Lava Dual Parallel port A 0 d 14078003 Lava Dual Parallel port B 0 d 14078800 BOCA Research IOPPAR 0 v 1408 Aloka Co. Ltd 0 v 1409 Timedia Technology Co Ltd 0 d 14097168 PCI2S550 (Dual 16550 UART) 0 v 140a DSP Research Inc 0 v 140b Ramix Inc 0 v 140c Elmic Systems Inc 0 v 140d Matsushita Electric Works Ltd 0 v 140e Goepel Electronic GmbH 0 v 140f Salient Systems Corp 0 v 1410 Midas lab Inc 0 v 1411 Ikos Systems Inc 0 v 1412 VIA Technologies Inc. 0 formerly IC Ensemble Inc. d 14121712 ICE1712 [Envy24] PCI Multi-Channel I/O Controller 0 s 141217121412d638 M-Audio Delta 410 0 d 14121724 VT1720/24 [Envy24PT/HT] PCI Multi-Channel Audio Controller 0 v 1413 Addonics 0 v 1414 Microsoft Corporation 0 v 1415 Oxford Semiconductor Ltd 0 d 14158403 VScom 011H-EP1 1 port parallel adaptor 0 d 14159501 OX16PCI954 (Quad 16950 UART) function 0 0 s 14159501131f2050 CyberPro (4-port) 0 s 1415950115ed2000 MCCR Serial p0-3 of 8 0 s 1415950115ed2001 MCCR Serial p0-3 of 16 0 d 1415950a EXSYS EX-41092 Dual 16950 Serial adapter 0 d 1415950b OXCB950 Cardbus 16950 UART 0 d 14159511 OX16PCI954 (Quad 16950 UART) function 1 0 s 1415951115ed2000 MCCR Serial p4-7 of 8 0 s 1415951115ed2001 MCCR Serial p4-15 of 16 0 d 14159521 OX16PCI952 (Dual 16950 UART) 0 v 1416 Multiwave Innovation pte Ltd 0 v 1417 Convergenet Technologies Inc 0 v 1418 Kyushu electronics systems Inc 0 v 1419 Excel Switching Corp 0 v 141a Apache Micro Peripherals Inc 0 v 141b Zoom Telephonics Inc 0 v 141d Digitan Systems Inc 0 v 141e Fanuc Ltd 0 v 141f Visiontech Ltd 0 v 1420 Psion Dacom plc 0 d 14208002 Gold Card NetGlobal 56k+10/100Mb CardBus (Ethernet part) 0 d 14208003 Gold Card NetGlobal 56k+10/100Mb CardBus (Modem part) 0 v 1421 Ads Technologies Inc 0 v 1422 Ygrec Systems Co Ltd 0 v 1423 Custom Technology Corp. 0 v 1424 Videoserver Connections 0 v 1425 Chelsio Communications Inc 0 v 1426 Storage Technology Corp. 0 v 1427 Better On-Line Solutions 0 v 1428 Edec Co Ltd 0 v 1429 Unex Technology Corp. 0 v 142a Kingmax Technology Inc 0 v 142b Radiolan 0 v 142c Minton Optic Industry Co Ltd 0 v 142d Pix stream Inc 0 v 142e Vitec Multimedia 0 d 142e4020 VM2-2 [Video Maker 2] MPEG1/2 Encoder 0 v 142f Radicom Research Inc 0 v 1430 ITT Aerospace/Communications Division 0 v 1431 Gilat Satellite Networks 0 v 1432 Edimax Computer Co. 0 d 14329130 RTL81xx Fast Ethernet 0 v 1433 Eltec Elektronik GmbH 0 v 1435 Real Time Devices US Inc. 0 v 1436 CIS Technology Inc 0 v 1437 Nissin Inc Co 0 v 1438 Atmel-dream 0 v 1439 Outsource Engineering & Mfg. Inc 0 v 143a Stargate Solutions Inc 0 v 143b Canon Research Center, America 0 v 143c Amlogic Inc 0 v 143d Tamarack Microelectronics Inc 0 v 143e Jones Futurex Inc 0 v 143f Lightwell Co Ltd - Zax Division 0 v 1440 ALGOL Corp. 0 v 1441 AGIE Ltd 0 v 1442 Phoenix Contact GmbH & Co. 0 v 1443 Unibrain S.A. 0 v 1444 TRW 0 v 1445 Logical DO Ltd 0 v 1446 Graphin Co Ltd 0 v 1447 AIM GmBH 0 v 1448 Alesis Studio Electronics 0 v 1449 TUT Systems Inc 0 v 144a Adlink Technology 0 d 144a7296 PCI-7296 0 d 144a7432 PCI-7432 0 d 144a7433 PCI-7433 0 d 144a7434 PCI-7434 0 d 144a7841 PCI-7841 0 d 144a8133 PCI-8133 0 d 144a8164 PCI-8164 0 d 144a8554 PCI-8554 0 d 144a9111 PCI-9111 0 d 144a9113 PCI-9113 0 d 144a9114 PCI-9114 0 v 144b Loronix Information Systems Inc 0 v 144c Catalina Research Inc 0 v 144d Samsung Electronics Co Ltd 0 v 144e OLITEC 0 v 144f Askey Computer Corp. 0 v 1450 Octave Communications Ind. 0 v 1451 SP3D Chip Design GmBH 0 v 1453 MYCOM Inc 0 v 1454 Altiga Networks 0 v 1455 Logic Plus Plus Inc 0 v 1456 Advanced Hardware Architectures 0 v 1457 Nuera Communications Inc 0 v 1458 Giga-byte Technology 0 v 1459 DOOIN Electronics 0 v 145a Escalate Networks Inc 0 v 145b PRAIM SRL 0 v 145c Cryptek 0 v 145d Gallant Computer Inc 0 v 145e Aashima Technology B.V. 0 v 145f Baldor Electric Company 0 d 145f0001 NextMove PCI 0 v 1460 DYNARC INC 0 v 1461 Avermedia Technologies Inc 0 v 1462 Micro-Star International Co., Ltd. 0 d 14626825 PCI Card wireless 11g [PC54G] 0 d 14628725 NVIDIA NV25 [GeForce4 Ti 4600] VGA Adapter 0 d 14629000 NVIDIA NV28 [GeForce4 Ti 4800] VGA Adapter 0 MSI G4Ti4800, 128MB DDR SDRAM, TV-Out, DVI-I d 14629119 NVIDIA NV31 [GeForce FX 5600XT] VGA Adapter 0 v 1463 Fast Corporation 0 v 1464 Interactive Circuits & Systems Ltd 0 v 1465 GN NETTEST Telecom DIV. 0 v 1466 Designpro Inc. 0 v 1467 DIGICOM SPA 0 v 1468 AMBIT Microsystem Corp. 0 v 1469 Cleveland Motion Controls 0 v 146a IFR 0 v 146b Parascan Technologies Ltd 0 v 146c Ruby Tech Corp. 0 d 146c1430 FE-1430TX Fast Ethernet PCI Adapter 0 v 146d Tachyon, INC. 0 v 146e Williams Electronics Games, Inc. 0 v 146f Multi Dimensional Consulting Inc 0 v 1470 Bay Networks 0 v 1471 Integrated Telecom Express Inc 0 v 1472 DAIKIN Industries, Ltd 0 v 1473 ZAPEX Technologies Inc 0 v 1474 Doug Carson & Associates 0 v 1475 PICAZO Communications 0 v 1476 MORTARA Instrument Inc 0 v 1477 Net Insight 0 v 1478 DIATREND Corporation 0 v 1479 TORAY Industries Inc 0 v 147a FORMOSA Industrial Computing 0 v 147b ABIT Computer Corp. 0 v 147c AWARE, Inc. 0 v 147d Interworks Computer Products 0 v 147e Matsushita Graphic Communication Systems, Inc. 0 v 147f NIHON UNISYS, Ltd. 0 v 1480 SCII Telecom 0 v 1481 BIOPAC Systems Inc 0 v 1482 ISYTEC - Integrierte Systemtechnik GmBH 0 v 1483 LABWAY Corporation 0 v 1484 Logic Corporation 0 v 1485 ERMA - Electronic GmBH 0 v 1486 L3 Communications Telemetry & Instrumentation 0 v 1487 MARQUETTE Medical Systems 0 v 1488 KONTRON Electronik GmBH 0 v 1489 KYE Systems Corporation 0 v 148a OPTO 0 v 148b INNOMEDIALOGIC Inc. 0 v 148c C.P. Technology Co. Ltd 0 v 148d DIGICOM Systems, Inc. 0 d 148d1003 HCF 56k Data/Fax Modem 0 v 148e OSI Plus Corporation 0 v 148f Plant Equipment, Inc. 0 v 1490 Stone Microsystems PTY Ltd. 0 v 1491 ZEAL Corporation 0 v 1492 Time Logic Corporation 0 v 1493 MAKER Communications 0 v 1494 WINTOP Technology, Inc. 0 v 1495 TOKAI Communications Industry Co. Ltd 0 v 1496 JOYTECH Computer Co., Ltd. 0 v 1497 SMA Regelsysteme GmBH 0 v 1498 TEWS Datentechnik GmBH 0 d 149830c8 TPCI200 0 v 1499 EMTEC CO., Ltd 0 v 149a ANDOR Technology Ltd 0 v 149b SEIKO Instruments Inc 0 v 149c OVISLINK Corp. 0 v 149d NEWTEK Inc 0 d 149d0001 Video Toaster for PC 0 v 149e Mapletree Networks Inc. 0 v 149f LECTRON Co Ltd 0 v 14a0 SOFTING GmBH 0 v 14a1 Systembase Co Ltd 0 v 14a2 Millennium Engineering Inc 0 v 14a3 Maverick Networks 0 v 14a4 GVC/BCM Advanced Research 0 v 14a5 XIONICS Document Technologies Inc 0 v 14a6 INOVA Computers GmBH & Co KG 0 v 14a7 MYTHOS Systems Inc 0 v 14a8 FEATRON Technologies Corporation 0 v 14a9 HIVERTEC Inc 0 v 14aa Advanced MOS Technology Inc 0 v 14ab Mentor Graphics Corp. 0 v 14ac Novaweb Technologies Inc 0 v 14ad Time Space Radio AB 0 v 14ae CTI, Inc 0 v 14af Guillemot Corporation 0 d 14af7102 3D Prophet II MX 0 v 14b0 BST Communication Technology Ltd 0 v 14b1 Nextcom K.K. 0 v 14b2 ENNOVATE Networks Inc 0 v 14b3 XPEED Inc 0 d 14b30000 DSL NIC 0 v 14b4 PHILIPS Business Electronics B.V. 0 v 14b5 Creamware GmBH 0 d 14b50200 Scope 0 d 14b50300 Pulsar 0 d 14b50400 PulsarSRB 0 d 14b50600 Pulsar2 0 d 14b50800 DSP-Board 0 d 14b50900 DSP-Board 0 d 14b50a00 DSP-Board 0 d 14b50b00 DSP-Board 0 v 14b6 Quantum Data Corp. 0 v 14b7 PROXIM Inc 0 d 14b70001 Symphony 4110 0 v 14b8 Techsoft Technology Co Ltd 0 v 14b9 AIRONET Wireless Communications 0 d 14b90001 PC4800 0 d 14b90340 PC4800 0 d 14b90350 PC4800 0 d 14b94500 PC4500 0 d 14b94800 Cisco Aironet 340 802.11b Wireless LAN Adapter/Aironet PC4800 0 d 14b9a504 Cisco Aironet Wireless 802.11b 0 d 14b9a505 Cisco Aironet CB20a 802.11a Wireless LAN Adapter 0 d 14b9a506 Cisco Aironet Mini PCI b/g 0 v 14ba INTERNIX Inc. 0 v 14bb SEMTECH Corporation 0 v 14bc Globespan Semiconductor Inc. 0 v 14bd CARDIO Control N.V. 0 v 14be L3 Communications 0 v 14bf SPIDER Communications Inc. 0 v 14c0 COMPAL Electronics Inc 0 v 14c1 MYRICOM Inc. 0 d 14c18043 Myrinet 2000 Scalable Cluster Interconnect 0 v 14c2 DTK Computer 0 v 14c3 MEDIATEK Corp. 0 v 14c4 IWASAKI Information Systems Co Ltd 0 v 14c5 Automation Products AB 0 v 14c6 Data Race Inc 0 v 14c7 Modular Technology Holdings Ltd 0 v 14c8 Turbocomm Tech. Inc. 0 v 14c9 ODIN Telesystems Inc 0 v 14ca PE Logic Corp. 0 v 14cb Billionton Systems Inc 0 v 14cc NAKAYO Telecommunications Inc 0 v 14cd Universal Scientific Ind. 0 v 14ce Whistle Communications 0 v 14cf TEK Microsystems Inc. 0 v 14d0 Ericsson Axe R & D 0 v 14d1 Computer Hi-Tech Co Ltd 0 v 14d2 Titan Electronics Inc 0 d 14d28001 VScom 010L 1 port parallel adaptor 0 d 14d28002 VScom 020L 2 port parallel adaptor 0 d 14d28010 VScom 100L 1 port serial adaptor 0 d 14d28011 VScom 110L 1 port serial and 1 port parallel adaptor 0 d 14d28020 VScom 200L 1 port serial adaptor 0 d 14d28021 VScom 210L 2 port serial and 1 port parallel adaptor 0 d 14d28040 VScom 400L 4 port serial adaptor 0 d 14d28080 VScom 800L 8 port serial adaptor 0 d 14d2a000 VScom 010H 1 port parallel adaptor 0 d 14d2a001 VScom 100H 1 port serial adaptor 0 d 14d2a003 VScom 400H 4 port serial adaptor 0 d 14d2a004 VScom 400HF1 4 port serial adaptor 0 d 14d2a005 VScom 200H 2 port serial adaptor 0 d 14d2e001 VScom 010HV2 1 port parallel adaptor 0 d 14d2e010 VScom 100HV2 1 port serial adaptor 0 d 14d2e020 VScom 200HV2 2 port serial adaptor 0 v 14d3 CIRTECH (UK) Ltd 0 v 14d4 Panacom Technology Corp 0 v 14d5 Nitsuko Corporation 0 v 14d6 Accusys Inc 0 v 14d7 Hirakawa Hewtech Corp 0 v 14d8 HOPF Elektronik GmBH 0 v 14d9 Alliance Semiconductor Corporation 0 Formerly SiPackets, Inc., formerly API NetWorks, Inc., formerly Alpha Processor, Inc. d 14d90010 AP1011/SP1011 HyperTransport-PCI Bridge [Sturgeon] 0 d 14d99000 AS90L10204/10208 HyperTransport to PCI-X Bridge 0 v 14da National Aerospace Laboratories 0 v 14db AFAVLAB Technology Inc 0 d 14db2120 TK9902 0 v 14dc Amplicon Liveline Ltd 0 d 14dc0000 PCI230 0 d 14dc0001 PCI242 0 d 14dc0002 PCI244 0 d 14dc0003 PCI247 0 d 14dc0004 PCI248 0 d 14dc0005 PCI249 0 d 14dc0006 PCI260 0 d 14dc0007 PCI224 0 d 14dc0008 PCI234 0 d 14dc0009 PCI236 0 d 14dc000a PCI272 0 d 14dc000b PCI215 0 v 14dd Boulder Design Labs Inc 0 v 14de Applied Integration Corporation 0 v 14df ASIC Communications Corp 0 v 14e1 INVERTEX 0 v 14e2 INFOLIBRIA 0 v 14e3 AMTELCO 0 v 14e4 Broadcom Corporation 0 d 14e40800 Sentry5 Chipcommon I/O Controller 0 d 14e40804 Sentry5 PCI Bridge 0 d 14e40805 Sentry5 MIPS32 CPU 0 d 14e40806 Sentry5 Ethernet Controller 0 d 14e4080b Sentry5 Crypto Accelerator 0 d 14e4080f Sentry5 DDR/SDR RAM Controller 0 d 14e40811 Sentry5 External Interface Core 0 d 14e40816 BCM3302 Sentry5 MIPS32 CPU 0 d 14e41644 NetXtreme BCM5700 Gigabit Ethernet 0 s 14e4164410140277 Broadcom Vigil B5700 1000Base-T 0 s 14e41644102800d1 Broadcom BCM5700 0 s 14e4164410280106 Broadcom BCM5700 0 s 14e4164410280109 Broadcom BCM5700 1000Base-T 0 s 14e416441028010a Broadcom BCM5700 1000BaseTX 0 s 14e4164410b71000 3C996-T 1000Base-T 0 s 14e4164410b71001 3C996B-T 1000Base-T 0 s 14e4164410b71002 3C996C-T 1000Base-T 0 s 14e4164410b71003 3C997-T 1000Base-T Dual Port 0 s 14e4164410b71004 3C996-SX 1000Base-SX 0 s 14e4164410b71005 3C997-SX 1000Base-SX Dual Port 0 s 14e4164410b71008 3C942 Gigabit LOM (31X31) 0 s 14e4164414e40002 NetXtreme 1000Base-SX 0 s 14e4164414e40003 NetXtreme 1000Base-SX 0 s 14e4164414e40004 NetXtreme 1000Base-T 0 s 14e4164414e41028 NetXtreme 1000BaseTX 0 s 14e4164414e41644 BCM5700 1000Base-T 0 d 14e41645 NetXtreme BCM5701 Gigabit Ethernet 0 s 14e416450e11007c NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T) 0 s 14e416450e11007d NC6770 Gigabit Server Adapter (PCI-X, 1000-SX) 0 s 14e416450e110085 NC7780 Gigabit Server Adapter (embedded, WOL) 0 s 14e416450e110099 NC7780 Gigabit Server Adapter (embedded, WOL) 0 s 14e416450e11009a NC7770 Gigabit Server Adapter (PCI-X, 10/100/1000-T) 0 s 14e416450e1100c1 NC6770 Gigabit Server Adapter (PCI-X, 1000-SX) 0 s 14e4164510280121 Broadcom BCM5701 1000Base-T 0 s 14e41645103c128a HP 1000Base-T (PCI) [A7061A] 0 s 14e41645103c128b HP 1000Base-SX (PCI) [A7073A] 0 s 14e41645103c12a4 HP Core Lan 1000Base-T 0 s 14e41645103c12c1 HP IOX Core Lan 1000Base-T [A7109AX] 0 s 14e4164510a98010 SGI IO9 Gigabit Ethernet (Copper) 0 s 14e4164510a98011 SGI Gigabit Ethernet (Copper) 0 s 14e4164510a98012 SGI Gigabit Ethernet (Fiber) 0 s 14e4164510b71004 3C996-SX 1000Base-SX 0 s 14e4164510b71006 3C996B-T 1000Base-T 0 s 14e4164510b71007 3C1000-T 1000Base-T 0 s 14e4164510b71008 3C940-BR01 1000Base-T 0 s 14e4164514e40001 BCM5701 1000Base-T 0 s 14e4164514e40005 BCM5701 1000Base-T 0 s 14e4164514e40006 BCM5701 1000Base-T 0 s 14e4164514e40007 BCM5701 1000Base-SX 0 s 14e4164514e40008 BCM5701 1000Base-T 0 s 14e4164514e48008 BCM5701 1000Base-T 0 d 14e41646 NetXtreme BCM5702 Gigabit Ethernet 0 s 14e416460e1100bb NC7760 1000BaseTX 0 s 14e4164610280126 Broadcom BCM5702 1000BaseTX 0 s 14e4164614e48009 BCM5702 1000BaseTX 0 d 14e41647 NetXtreme BCM5703 Gigabit Ethernet 0 s 14e416470e110099 NC7780 1000BaseTX 0 s 14e416470e11009a NC7770 1000BaseTX 0 s 14e4164710a98010 SGI IO9 Gigabit Ethernet (Copper) 0 s 14e4164714e40009 BCM5703 1000BaseTX 0 s 14e4164714e4000a BCM5703 1000BaseSX 0 s 14e4164714e4000b BCM5703 1000BaseTX 0 s 14e4164714e48009 BCM5703 1000BaseTX 0 s 14e4164714e4800a BCM5703 1000BaseTX 0 d 14e41648 NetXtreme BCM5704 Gigabit Ethernet 0 s 14e416480e1100cf NC7772 Gigabit Server Adapter (PCI-X, 10,100,1000-T) 0 s 14e416480e1100d0 NC7782 Gigabit Server Adapter (PCI-X, 10,100,1000-T) 0 s 14e416480e1100d1 NC7783 Gigabit Server Adapter (PCI-X, 10,100,1000-T) 0 s 14e4164810b72000 3C998-T Dual Port 10/100/1000 PCI-X 0 s 14e4164810b73000 3C999-T Quad Port 10/100/1000 PCI-X 0 s 14e4164811661648 NetXtreme CIOB-E 1000Base-T 0 d 14e4164a NetXtreme II BCM5706 Gigabit Ethernet 0 d 14e4164d NetXtreme BCM5702FE Gigabit Ethernet 0 d 14e41653 NetXtreme BCM5705 Gigabit Ethernet 0 s 14e416530e1100e3 NC7761 Gigabit Server Adapter 0 d 14e41654 NetXtreme BCM5705_2 Gigabit Ethernet 0 s 14e416540e1100e3 NC7761 Gigabit Server Adapter 0 s 14e41654103c3100 NC1020 HP ProLiant Gigabit Server Adapter 32 PCI 0 d 14e41659 NetXtreme BCM5721 Gigabit Ethernet PCI Express 0 d 14e4165d NetXtreme BCM5705M Gigabit Ethernet 0 d 14e4165e NetXtreme BCM5705M_2 Gigabit Ethernet 0 s 14e4165e103c0890 NC6000 laptop 0 d 14e4166e 570x 10/100 Integrated Controller 0 d 14e41677 NetXtreme BCM5751 Gigabit Ethernet PCI Express 0 s 14e4167710280179 Optiplex GX280 0 d 14e4167d NetXtreme BCM5751M Gigabit Ethernet PCI Express 0 d 14e4167e NetXtreme BCM5751F Fast Ethernet PCI Express 0 d 14e41696 NetXtreme BCM5782 Gigabit Ethernet 0 s 14e41696103c12bc HP d530 CMT (DG746A) 0 s 14e4169614e4000d NetXtreme BCM5782 1000Base-T 0 d 14e4169c NetXtreme BCM5788 Gigabit Ethernet 0 d 14e4169d NetLink BCM5789 Gigabit Ethernet PCI Express 0 d 14e416a6 NetXtreme BCM5702X Gigabit Ethernet 0 s 14e416a60e1100bb NC7760 Gigabit Server Adapter (PCI-X, 10/100/1000-T) 0 s 14e416a610280126 BCM5702 1000Base-T 0 s 14e416a614e4000c BCM5702 1000Base-T 0 s 14e416a614e48009 BCM5702 1000Base-T 0 d 14e416a7 NetXtreme BCM5703X Gigabit Ethernet 0 s 14e416a70e1100ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T) 0 s 14e416a70e1100cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T) 0 s 14e416a714e40009 NetXtreme BCM5703 1000Base-T 0 s 14e416a714e4000a NetXtreme BCM5703 1000Base-SX 0 s 14e416a714e4000b NetXtreme BCM5703 1000Base-T 0 s 14e416a714e4800a NetXtreme BCM5703 1000Base-T 0 d 14e416a8 NetXtreme BCM5704S Gigabit Ethernet 0 s 14e416a810b72001 3C998-SX Dual Port 1000-SX PCI-X 0 d 14e416aa NetXtreme II BCM5706S Gigabit Ethernet 0 d 14e416c6 NetXtreme BCM5702A3 Gigabit Ethernet 0 s 14e416c610b71100 3C1000B-T 10/100/1000 PCI 0 s 14e416c614e4000c BCM5702 1000Base-T 0 s 14e416c614e48009 BCM5702 1000Base-T 0 d 14e416c7 NetXtreme BCM5703 Gigabit Ethernet 0 s 14e416c70e1100ca NC7771 Gigabit Server Adapter (PCI-X, 10,100,1000-T) 0 s 14e416c70e1100cb NC7781 Gigabit Server Adapter (PCI-X, 10,100,1000-T) 0 s 14e416c7103c12c3 HP Combo FC/GigE-SX [A9782A] 0 s 14e416c7103c12ca HP Combo FC/GigE-T [A9784A] 0 s 14e416c714e40009 NetXtreme BCM5703 1000Base-T 0 s 14e416c714e4000a NetXtreme BCM5703 1000Base-SX 0 d 14e416dd NetLink BCM5781 Gigabit Ethernet PCI Express 0 d 14e416f7 NetXtreme BCM5753 Gigabit Ethernet PCI Express 0 d 14e416fd NetXtreme BCM5753M Gigabit Ethernet PCI Express 0 d 14e416fe NetXtreme BCM5753F Fast Ethernet PCI Express 0 d 14e4170c BCM4401-B0 100Base-TX 0 d 14e4170d NetXtreme BCM5901 100Base-TX 0 s 14e4170d10140545 ThinkPad R40e (2684-HVG) builtin ethernet controller 0 d 14e4170e NetXtreme BCM5901 100Base-TX 0 d 14e43352 BCM3352 0 d 14e43360 BCM3360 0 d 14e44210 BCM4210 iLine10 HomePNA 2.0 0 d 14e44211 BCM4211 iLine10 HomePNA 2.0 + V.90 56k modem 0 d 14e44212 BCM4212 v.90 56k modem 0 d 14e44301 BCM4303 802.11b Wireless LAN Controller 0 s 14e4430110280407 TrueMobile 1180 Onboard WLAN 0 s 14e4430110430120 WL-103b Wireless LAN PC Card 0 d 14e44305 BCM4307 V.90 56k Modem 0 d 14e44306 BCM4307 Ethernet Controller 0 d 14e44307 BCM4307 802.11b Wireless LAN Controller 0 d 14e44310 BCM4310 Chipcommon I/OController 0 d 14e44312 BCM4310 UART 0 d 14e44313 BCM4310 Ethernet Controller 0 d 14e44315 BCM4310 USB Controller 0 d 14e44320 BCM4306 802.11b/g Wireless LAN Controller 0 s 14e4432010280001 TrueMobile 1300 WLAN Mini-PCI Card 0 s 14e4432010280003 Wireless 1350 WLAN Mini-PCI Card 0 s 14e443201043100f WL-100G 0 s 14e4432014e44320 Linksys WMP54G PCI 0 s 14e4432017374320 WPC54G 0 s 14e4432017997010 Belkin F5D7010 54g Wireless Network card 0 d 14e44321 BCM4306 802.11a Wireless LAN Controller 0 d 14e44322 BCM4306 UART 0 d 14e44324 BCM4309 802.11a/b/g 0 s 14e4432410280001 Truemobile 1400 0 s 14e4432410280003 Truemobile 1450 MiniPCI 0 d 14e44325 BCM43xG 802.11b/g 0 s 14e4432514140003 Wireless Notebook Adapter MN-720 0 s 14e4432514140004 Wireless PCI Adapter MN-730 0 d 14e44326 BCM4307 Chipcommon I/O Controller? 0 probably this is a correct ID... d 14e44401 BCM4401 100Base-T 0 s 14e44401104380a8 A7V8X motherboard 0 d 14e44402 BCM4402 Integrated 10/100BaseT 0 d 14e44403 BCM4402 V.90 56k Modem 0 d 14e44410 BCM4413 iLine32 HomePNA 2.0 0 d 14e44411 BCM4413 V.90 56k modem 0 d 14e44412 BCM4412 10/100BaseT 0 d 14e44430 BCM44xx CardBus iLine32 HomePNA 2.0 0 d 14e44432 BCM4432 CardBus 10/100BaseT 0 d 14e44610 BCM4610 Sentry5 PCI to SB Bridge 0 d 14e44611 BCM4610 Sentry5 iLine32 HomePNA 1.0 0 d 14e44612 BCM4610 Sentry5 V.90 56k Modem 0 d 14e44613 BCM4610 Sentry5 Ethernet Controller 0 d 14e44614 BCM4610 Sentry5 External Interface 0 d 14e44615 BCM4610 Sentry5 USB Controller 0 d 14e44704 BCM4704 PCI to SB Bridge 0 d 14e44705 BCM4704 Sentry5 802.11b Wireless LAN Controller 0 d 14e44706 BCM4704 Sentry5 Ethernet Controller 0 d 14e44707 BCM4704 Sentry5 USB Controller 0 d 14e44708 BCM4704 Crypto Accelerator 0 d 14e44710 BCM4710 Sentry5 PCI to SB Bridge 0 d 14e44711 BCM47xx Sentry5 iLine32 HomePNA 2.0 0 d 14e44712 BCM47xx V.92 56k modem 0 d 14e44713 Sentry5 Ethernet Controller 0 d 14e44714 BCM47xx Sentry5 External Interface 0 d 14e44715 Sentry5 USB Controller 0 d 14e44716 BCM47xx Sentry5 USB Host Controller 0 d 14e44717 BCM47xx Sentry5 USB Device Controller 0 d 14e44718 Sentry5 Crypto Accelerator 0 d 14e44720 BCM4712 MIPS CPU 0 d 14e45365 BCM5365P Sentry5 Host Bridge 0 d 14e45600 BCM5600 StrataSwitch 24+2 Ethernet Switch Controller 0 d 14e45605 BCM5605 StrataSwitch 24+2 Ethernet Switch Controller 0 d 14e45615 BCM5615 StrataSwitch 24+2 Ethernet Switch Controller 0 d 14e45625 BCM5625 StrataSwitch 24+2 Ethernet Switch Controller 0 d 14e45645 BCM5645 StrataSwitch 24+2 Ethernet Switch Controller 0 d 14e45670 BCM5670 8-Port 10GE Ethernet Switch Fabric 0 d 14e45680 BCM5680 G-Switch 8 Port Gigabit Ethernet Switch Controller 0 d 14e45690 BCM5690 12-port Multi-Layer Gigabit Ethernet Switch 0 d 14e45691 BCM5691 GE/10GE 8+2 Gigabit Ethernet Switch Controller 0 d 14e45820 BCM5820 Crypto Accelerator 0 d 14e45821 BCM5821 Crypto Accelerator 0 d 14e45822 BCM5822 Crypto Accelerator 0 d 14e45823 BCM5823 Crypto Accelerator 0 d 14e45824 BCM5824 Crypto Accelerator 0 d 14e45840 BCM5840 Crypto Accelerator 0 d 14e45841 BCM5841 Crypto Accelerator 0 d 14e45850 BCM5850 Crypto Accelerator 0 v 14e5 Pixelfusion Ltd 0 v 14e6 SHINING Technology Inc 0 v 14e7 3CX 0 v 14e8 RAYCER Inc 0 v 14e9 GARNETS System CO Ltd 0 v 14ea Planex Communications, Inc 0 d 14eaab06 FNW-3603-TX CardBus Fast Ethernet 0 d 14eaab07 RTL81xx RealTek Ethernet 0 v 14eb SEIKO EPSON Corp 0 v 14ec ACQIRIS 0 v 14ed DATAKINETICS Ltd 0 v 14ee MASPRO KENKOH Corp 0 v 14ef CARRY Computer ENG. CO Ltd 0 v 14f0 CANON RESEACH CENTRE FRANCE 0 v 14f1 Conexant 0 d 14f11002 HCF 56k Modem 0 d 14f11003 HCF 56k Modem 0 d 14f11004 HCF 56k Modem 0 d 14f11005 HCF 56k Modem 0 d 14f11006 HCF 56k Modem 0 d 14f11022 HCF 56k Modem 0 d 14f11023 HCF 56k Modem 0 d 14f11024 HCF 56k Modem 0 d 14f11025 HCF 56k Modem 0 d 14f11026 HCF 56k Modem 0 d 14f11032 HCF 56k Modem 0 d 14f11033 HCF 56k Data/Fax Modem 0 s 14f1103310338077 NEC 0 s 14f11033122d4027 Dell Zeus - MDP3880-W(B) Data Fax Modem 0 s 14f11033122d4030 Dell Mercury - MDP3880-U(B) Data Fax Modem 0 s 14f11033122d4034 Dell Thor - MDP3880-W(U) Data Fax Modem 0 s 14f1103313e0020d Dell Copper 0 s 14f1103313e0020e Dell Silver 0 s 14f1103313e00261 IBM 0 s 14f1103313e00290 Compaq Goldwing 0 s 14f1103313e002a0 IBM 0 s 14f1103313e002b0 IBM 0 s 14f1103313e002c0 Compaq Scooter 0 s 14f1103313e002d0 IBM 0 s 14f11033144f1500 IBM P85-DF (1) 0 s 14f11033144f1501 IBM P85-DF (2) 0 s 14f11033144f150a IBM P85-DF (3) 0 s 14f11033144f150b IBM P85-DF Low Profile (1) 0 s 14f11033144f1510 IBM P85-DF Low Profile (2) 0 d 14f11034 HCF 56k Data/Fax/Voice Modem 0 d 14f11035 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 s 14f1103510cf1098 Fujitsu P85-DFSV 0 d 14f11036 HCF 56k Data/Fax/Voice/Spkp Modem 0 s 14f11036104d8067 HCF 56k Modem 0 s 14f11036122d4029 MDP3880SP-W 0 s 14f11036122d4031 MDP3880SP-U 0 s 14f1103613e00209 Dell Titanium 0 s 14f1103613e0020a Dell Graphite 0 s 14f1103613e00260 Gateway Red Owl 0 s 14f1103613e00270 Gateway White Horse 0 d 14f11052 HCF 56k Data/Fax Modem (Worldwide) 0 d 14f11053 HCF 56k Data/Fax Modem (Worldwide) 0 d 14f11054 HCF 56k Data/Fax/Voice Modem (Worldwide) 0 d 14f11055 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (Worldwide) 0 d 14f11056 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide) 0 d 14f11057 HCF 56k Data/Fax/Voice/Spkp Modem (Worldwide) 0 d 14f11059 HCF 56k Data/Fax/Voice Modem (Worldwide) 0 d 14f11063 HCF 56k Data/Fax Modem 0 d 14f11064 HCF 56k Data/Fax/Voice Modem 0 d 14f11065 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 d 14f11066 HCF 56k Data/Fax/Voice/Spkp Modem 0 s 14f11066122d4033 Dell Athena - MDP3900V-U 0 d 14f11433 HCF 56k Data/Fax Modem 0 d 14f11434 HCF 56k Data/Fax/Voice Modem 0 d 14f11435 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 d 14f11436 HCF 56k Data/Fax Modem 0 d 14f11453 HCF 56k Data/Fax Modem 0 s 14f1145313e00240 IBM 0 s 14f1145313e00250 IBM 0 s 14f11453144f1502 IBM P95-DF (1) 0 s 14f11453144f1503 IBM P95-DF (2) 0 d 14f11454 HCF 56k Data/Fax/Voice Modem 0 d 14f11455 HCF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 d 14f11456 HCF 56k Data/Fax/Voice/Spkp Modem 0 s 14f11456122d4035 Dell Europa - MDP3900V-W 0 s 14f11456122d4302 Dell MP3930V-W(C) MiniPCI 0 d 14f11610 ADSL AccessRunner PCI Arbitration Device 0 d 14f11611 AccessRunner PCI ADSL Interface Device 0 d 14f11620 ADSL AccessRunner V2 PCI Arbitration Device 0 d 14f11621 AccessRunner V2 PCI ADSL Interface Device 0 d 14f11622 AccessRunner V2 PCI ADSL Yukon WAN Adapter 0 d 14f11803 HCF 56k Modem 0 s 14f118030e110023 623-LAN Grizzly 0 s 14f118030e110043 623-LAN Yogi 0 d 14f11815 HCF 56k Modem 0 s 14f118150e110022 Grizzly 0 s 14f118150e110042 Yogi 0 d 14f12003 HSF 56k Data/Fax Modem 0 d 14f12004 HSF 56k Data/Fax/Voice Modem 0 d 14f12005 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 d 14f12006 HSF 56k Data/Fax/Voice/Spkp Modem 0 d 14f12013 HSF 56k Data/Fax Modem 0 s 14f120130e11b195 Bear 0 s 14f120130e11b196 Seminole 1 0 s 14f120130e11b1be Seminole 2 0 s 14f1201310258013 Acer 0 s 14f120131033809d NEC 0 s 14f12013103380bc NEC 0 s 14f12013155d6793 HP 0 s 14f12013155d8850 E Machines 0 d 14f12014 HSF 56k Data/Fax/Voice Modem 0 d 14f12015 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem 0 d 14f12016 HSF 56k Data/Fax/Voice/Spkp Modem 0 d 14f12043 HSF 56k Data/Fax Modem (WorldW SmartDAA) 0 d 14f12044 HSF 56k Data/Fax/Voice Modem (WorldW SmartDAA) 0 d 14f12045 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (WorldW SmartDAA) 0 d 14f12046 HSF 56k Data/Fax/Voice/Spkp Modem (WorldW SmartDAA) 0 d 14f12063 HSF 56k Data/Fax Modem (SmartDAA) 0 d 14f12064 HSF 56k Data/Fax/Voice Modem (SmartDAA) 0 d 14f12065 HSF 56k Data/Fax/Voice/Spkp (w/Handset) Modem (SmartDAA) 0 d 14f12066 HSF 56k Data/Fax/Voice/Spkp Modem (SmartDAA) 0 d 14f12093 HSF 56k Modem 0 s 14f12093155d2f07 Legend 0 d 14f12143 HSF 56k Data/Fax/Cell Modem (Mob WorldW SmartDAA) 0 d 14f12144 HSF 56k Data/Fax/Voice/Cell Modem (Mob WorldW SmartDAA) 0 d 14f12145 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob WorldW SmartDAA) 0 d 14f12146 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob WorldW SmartDAA) 0 d 14f12163 HSF 56k Data/Fax/Cell Modem (Mob SmartDAA) 0 d 14f12164 HSF 56k Data/Fax/Voice/Cell Modem (Mob SmartDAA) 0 d 14f12165 HSF 56k Data/Fax/Voice/Spkp (w/HS)/Cell Modem (Mob SmartDAA) 0 d 14f12166 HSF 56k Data/Fax/Voice/Spkp/Cell Modem (Mob SmartDAA) 0 d 14f12343 HSF 56k Data/Fax CardBus Modem (Mob WorldW SmartDAA) 0 d 14f12344 HSF 56k Data/Fax/Voice CardBus Modem (Mob WorldW SmartDAA) 0 d 14f12345 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob WorldW SmartDAA) 0 d 14f12346 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob WorldW SmartDAA) 0 d 14f12363 HSF 56k Data/Fax CardBus Modem (Mob SmartDAA) 0 d 14f12364 HSF 56k Data/Fax/Voice CardBus Modem (Mob SmartDAA) 0 d 14f12365 HSF 56k Data/Fax/Voice/Spkp (w/HS) CardBus Modem (Mob SmartDAA) 0 d 14f12366 HSF 56k Data/Fax/Voice/Spkp CardBus Modem (Mob SmartDAA) 0 d 14f12443 HSF 56k Data/Fax Modem (Mob WorldW SmartDAA) 0 s 14f12443104d8075 Modem 0 s 14f12443104d8083 Modem 0 s 14f12443104d8097 Modem 0 d 14f12444 HSF 56k Data/Fax/Voice Modem (Mob WorldW SmartDAA) 0 d 14f12445 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob WorldW SmartDAA) 0 d 14f12446 HSF 56k Data/Fax/Voice/Spkp Modem (Mob WorldW SmartDAA) 0 d 14f12463 HSF 56k Data/Fax Modem (Mob SmartDAA) 0 d 14f12464 HSF 56k Data/Fax/Voice Modem (Mob SmartDAA) 0 d 14f12465 HSF 56k Data/Fax/Voice/Spkp (w/HS) Modem (Mob SmartDAA) 0 d 14f12466 HSF 56k Data/Fax/Voice/Spkp Modem (Mob SmartDAA) 0 d 14f12f00 HSF 56k HSFi Modem 0 s 14f12f0013e08d84 IBM HSFi V.90 0 s 14f12f0013e08d85 Compaq Stinger 0 s 14f12f0014f12004 Dynalink 56PMi 0 d 14f12f02 HSF 56k HSFi Data/Fax 0 d 14f12f11 HSF 56k HSFi Modem 0 d 14f18234 RS8234 ATM SAR Controller [ServiceSAR Plus] 0 d 14f18800 Winfast TV2000 XP 0 v 14f2 MOBILITY Electronics 0 d 14f20120 EV1000 bridge 0 d 14f20121 EV1000 Parallel port 0 d 14f20122 EV1000 Serial port 0 d 14f20123 EV1000 Keyboard controller 0 d 14f20124 EV1000 Mouse controller 0 v 14f3 BroadLogic 0 d 14f32030 2030 DVB-S Satellite Reciever 0 d 14f32050 2050 DVB-T Terrestrial (Cable) Reciever 0 d 14f32060 2060 ATSC Terrestrial (Cable) Reciever 0 v 14f4 TOKYO Electronic Industry CO Ltd 0 v 14f5 SOPAC Ltd 0 v 14f6 COYOTE Technologies LLC 0 v 14f7 WOLF Technology Inc 0 v 14f8 AUDIOCODES Inc 0 d 14f82077 TP-240 dual span E1 VoIP PCI card 0 v 14f9 AG COMMUNICATIONS 0 v 14fa WANDEL & GOCHERMANN 0 v 14fb TRANSAS MARINE (UK) Ltd 0 v 14fc Quadrics Ltd 0 d 14fc0000 QsNet Elan3 Network Adapter 0 d 14fc0001 QsNetII Elan4 Network Adapter 0 v 14fd JAPAN Computer Industry Inc 0 v 14fe ARCHTEK TELECOM Corp 0 v 14ff TWINHEAD INTERNATIONAL Corp 0 v 1500 DELTA Electronics, Inc 0 d 15001360 RTL81xx RealTek Ethernet 0 v 1501 BANKSOFT CANADA Ltd 0 v 1502 MITSUBISHI ELECTRIC LOGISTICS SUPPORT Co Ltd 0 v 1503 KAWASAKI LSI USA Inc 0 v 1504 KAISER Electronics 0 v 1505 ITA INGENIEURBURO FUR TESTAUFGABEN GmbH 0 v 1506 CHAMELEON Systems Inc 0 v 1507 Motorola ?? / HTEC 0 Should be HTEC Ltd, but there are no known HTEC chips and 1507 is already used by mistake by Motorola (see vendor ID 1057). d 15070001 MPC105 [Eagle] 0 d 15070002 MPC106 [Grackle] 0 d 15070003 MPC8240 [Kahlua] 0 d 15070100 MC145575 [HFC-PCI] 0 d 15070431 KTI829c 100VG 0 d 15074801 Raven 0 d 15074802 Falcon 0 d 15074803 Hawk 0 d 15074806 CPX8216 0 v 1508 HONDA CONNECTORS/MHOTRONICS Inc 0 v 1509 FIRST INTERNATIONAL Computer Inc 0 v 150a FORVUS RESEARCH Inc 0 v 150b YAMASHITA Systems Corp 0 v 150c KYOPAL CO Ltd 0 v 150d WARPSPPED Inc 0 v 150e C-PORT Corp 0 v 150f INTEC GmbH 0 v 1510 BEHAVIOR TECH Computer Corp 0 v 1511 CENTILLIUM Technology Corp 0 v 1512 ROSUN Technologies Inc 0 v 1513 Raychem 0 v 1514 TFL LAN Inc 0 v 1515 Advent design 0 v 1516 MYSON Technology Inc 0 d 15160800 MTD-8xx 100/10M Ethernet PCI Adapter 0 d 15160803 SURECOM EP-320X-S 100/10M Ethernet PCI Adapter 0 s 15160803132010bd SURECOM EP-320X-S 100/10M Ethernet PCI Adapter 0 d 15160891 MTD-8xx 100/10M Ethernet PCI Adapter 0 v 1517 ECHOTEK Corp 0 v 1518 PEP MODULAR Computers GmbH 0 v 1519 TELEFON AKTIEBOLAGET LM Ericsson 0 v 151a Globetek 0 d 151a1002 PCI-1002 0 d 151a1004 PCI-1004 0 d 151a1008 PCI-1008 0 v 151b COMBOX Ltd 0 v 151c DIGITAL AUDIO LABS Inc 0 v 151d Fujitsu Computer Products Of America 0 v 151e MATRIX Corp 0 v 151f TOPIC SEMICONDUCTOR Corp 0 d 151f0000 TP560 Data/Fax/Voice 56k modem 0 v 1520 CHAPLET System Inc 0 v 1521 BELL Corp 0 v 1522 MainPine Ltd 0 d 15220100 PCI <-> IOBus Bridge 0 s 1522010015220200 RockForceDUO 2 Port V.92/V.44 Data/Fax/Voice Modem 0 s 1522010015220300 RockForceQUATRO 4 Port V.92/V.44 Data/Fax/Voice Modem 0 s 1522010015220400 RockForceDUO+ 2 Port V.92/V.44 Data/Fax/Voice Modem 0 s 1522010015220500 RockForceQUATRO+ 4 Port V.92/V.44 Data/Fax/Voice Modem 0 s 1522010015220600 RockForce+ 2 Port V.90 Data/Fax/Voice Modem 0 s 1522010015220700 RockForce+ 4 Port V.90 Data/Fax/Voice Modem 0 s 1522010015220800 RockForceOCTO+ 8 Port V.92/V.44 Data/Fax/Voice Modem 0 s 1522010015220c00 RockForceDUO+ 2 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem 0 s 1522010015220d00 RockForceQUATRO+ 4 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem 0 s 1522010015221d00 RockForceOCTO+ 8 Port V.92/V.44 Data, V.34 Super-G3 Fax, Voice Modem 0 this is a correction to a recent entry. 1522:0E00 should be 1522:1D00 v 1523 MUSIC Semiconductors 0 v 1524 ENE Technology Inc 0 d 15240510 CB710 Memory Card Reader Controller 0 d 15240610 PCI Smart Card Reader Controller 0 d 15241211 CB1211 Cardbus Controller 0 d 15241225 CB1225 Cardbus Controller 0 d 15241410 CB1410 Cardbus Controller 0 s 152414101025005a TravelMate 290 0 d 15241411 CB-710/2/4 Cardbus Controller 0 d 15241412 CB-712/4 Cardbus Controller 0 d 15241420 CB1420 Cardbus Controller 0 d 15241421 CB-720/2/4 Cardbus Controller 0 d 15241422 CB-722/4 Cardbus Controller 0 v 1525 IMPACT Technologies 0 v 1526 ISS, Inc 0 v 1527 SOLECTRON 0 v 1528 ACKSYS 0 v 1529 AMERICAN MICROSystems Inc 0 v 152a QUICKTURN DESIGN Systems 0 v 152b FLYTECH Technology CO Ltd 0 v 152c MACRAIGOR Systems LLC 0 v 152d QUANTA Computer Inc 0 v 152e MELEC Inc 0 v 152f PHILIPS - CRYPTO 0 v 1530 ACQIS Technology Inc 0 v 1531 CHRYON Corp 0 v 1532 ECHELON Corp 0 v 1533 BALTIMORE 0 v 1534 ROAD Corp 0 v 1535 EVERGREEN Technologies Inc 0 v 1537 DATALEX COMMUNCATIONS 0 v 1538 ARALION Inc 0 d 15380303 ARS106S Ultra ATA 133/100/66 Host Controller 0 v 1539 ATELIER INFORMATIQUES et ELECTRONIQUE ETUDES S.A. 0 v 153a ONO SOKKI 0 v 153b TERRATEC Electronic GmbH 0 d 153b1144 Aureon 5.1 0 d 153b1147 Aureon 5.1 Sky 0 Terratec seems to use several IDs for the same card. d 153b1158 Philips Semiconductors SAA7134 (rev 01) [Terratec Cinergy 600 TV] 0 v 153c ANTAL Electronic 0 v 153d FILANET Corp 0 v 153e TECHWELL Inc 0 v 153f MIPS DENMARK 0 v 1540 PROVIDEO MULTIMEDIA Co Ltd 0 v 1541 MACHONE Communications 0 v 1542 VIVID Technology Inc 0 v 1543 SILICON Laboratories 0 d 15433052 Intel 537 [Winmodem] 0 d 15434c22 Si3036 MC'97 DAA 0 v 1544 DCM DATA Systems 0 v 1545 VISIONTEK 0 v 1546 IOI Technology Corp 0 v 1547 MITUTOYO Corp 0 v 1548 JET PROPULSION Laboratory 0 v 1549 INTERCONNECT Systems Solutions 0 v 154a MAX Technologies Inc 0 v 154b COMPUTEX Co Ltd 0 v 154c VISUAL Technology Inc 0 v 154d PAN INTERNATIONAL Industrial Corp 0 v 154e SERVOTEST Ltd 0 v 154f STRATABEAM Technology 0 v 1550 OPEN NETWORK Co Ltd 0 v 1551 SMART Electronic DEVELOPMENT GmBH 0 v 1552 RACAL AIRTECH Ltd 0 v 1553 CHICONY Electronics Co Ltd 0 v 1554 PROLINK Microsystems Corp 0 v 1555 GESYTEC GmBH 0 v 1556 PLD APPLICATIONS 0 v 1557 MEDIASTAR Co Ltd 0 v 1558 CLEVO/KAPOK Computer 0 v 1559 SI LOGIC Ltd 0 v 155a INNOMEDIA Inc 0 v 155b PROTAC INTERNATIONAL Corp 0 v 155c Cemax-Icon Inc 0 v 155d Mac System Co Ltd 0 v 155e LP Elektronik GmbH 0 v 155f Perle Systems Ltd 0 v 1560 Terayon Communications Systems 0 v 1561 Viewgraphics Inc 0 v 1562 Symbol Technologies 0 v 1563 A-Trend Technology Co Ltd 0 v 1564 Yamakatsu Electronics Industry Co Ltd 0 v 1565 Biostar Microtech Int'l Corp 0 v 1566 Ardent Technologies Inc 0 v 1567 Jungsoft 0 v 1568 DDK Electronics Inc 0 v 1569 Palit Microsystems Inc. 0 v 156a Avtec Systems 0 v 156b 2wire Inc 0 v 156c Vidac Electronics GmbH 0 v 156d Alpha-Top Corp 0 v 156e Alfa Inc 0 v 156f M-Systems Flash Disk Pioneers Ltd 0 v 1570 Lecroy Corp 0 v 1571 Contemporary Controls 0 d 1571a001 CCSI PCI20-485 ARCnet 0 d 1571a002 CCSI PCI20-485D ARCnet 0 d 1571a003 CCSI PCI20-485X ARCnet 0 d 1571a004 CCSI PCI20-CXB ARCnet 0 d 1571a005 CCSI PCI20-CXS ARCnet 0 d 1571a006 CCSI PCI20-FOG-SMA ARCnet 0 d 1571a007 CCSI PCI20-FOG-ST ARCnet 0 d 1571a008 CCSI PCI20-TB5 ARCnet 0 d 1571a009 CCSI PCI20-5-485 5Mbit ARCnet 0 d 1571a00a CCSI PCI20-5-485D 5Mbit ARCnet 0 d 1571a00b CCSI PCI20-5-485X 5Mbit ARCnet 0 d 1571a00c CCSI PCI20-5-FOG-ST 5Mbit ARCnet 0 d 1571a00d CCSI PCI20-5-FOG-SMA 5Mbit ARCnet 0 d 1571a201 CCSI PCI22-485 10Mbit ARCnet 0 d 1571a202 CCSI PCI22-485D 10Mbit ARCnet 0 d 1571a203 CCSI PCI22-485X 10Mbit ARCnet 0 d 1571a204 CCSI PCI22-CHB 10Mbit ARCnet 0 d 1571a205 CCSI PCI22-FOG_ST 10Mbit ARCnet 0 d 1571a206 CCSI PCI22-THB 10Mbit ARCnet 0 v 1572 Otis Elevator Company 0 v 1573 Lattice - Vantis 0 v 1574 Fairchild Semiconductor 0 v 1575 Voltaire Advanced Data Security Ltd 0 v 1576 Viewcast COM 0 v 1578 HITT 0 v 1579 Dual Technology Corp 0 v 157a Japan Elecronics Ind Inc 0 v 157b Star Multimedia Corp 0 v 157c Eurosoft (UK) 0 d 157c8001 Fix2000 PCI Y2K Compliance Card 0 v 157d Gemflex Networks 0 v 157e Transition Networks 0 v 157f PX Instruments Technology Ltd 0 v 1580 Primex Aerospace Co 0 v 1581 SEH Computertechnik GmbH 0 v 1582 Cytec Corp 0 v 1583 Inet Technologies Inc 0 v 1584 Uniwill Computer Corp 0 v 1585 Logitron 0 v 1586 Lancast Inc 0 v 1587 Konica Corp 0 v 1588 Solidum Systems Corp 0 v 1589 Atlantek Microsystems Pty Ltd 0 v 158a Digalog Systems Inc 0 v 158b Allied Data Technologies 0 v 158c Hitachi Semiconductor & Devices Sales Co Ltd 0 v 158d Point Multimedia Systems 0 v 158e Lara Technology Inc 0 v 158f Ditect Coop 0 v 1590 3pardata Inc 0 v 1591 ARN 0 v 1592 Syba Tech Ltd 0 d 15920781 Multi-IO Card 0 d 15920782 Parallel Port Card 2xEPP 0 d 15920783 Multi-IO Card 0 d 15920785 Multi-IO Card 0 d 15920786 Multi-IO Card 0 d 15920787 Multi-IO Card 0 d 15920788 Multi-IO Card 0 d 1592078a Multi-IO Card 0 v 1593 Bops Inc 0 v 1594 Netgame Ltd 0 v 1595 Diva Systems Corp 0 v 1596 Folsom Research Inc 0 v 1597 Memec Design Services 0 v 1598 Granite Microsystems 0 v 1599 Delta Electronics Inc 0 v 159a General Instrument 0 v 159b Faraday Technology Corp 0 v 159c Stratus Computer Systems 0 v 159d Ningbo Harrison Electronics Co Ltd 0 v 159e A-Max Technology Co Ltd 0 v 159f Galea Network Security 0 v 15a0 Compumaster SRL 0 v 15a1 Geocast Network Systems 0 v 15a2 Catalyst Enterprises Inc 0 d 15a20001 TA700 PCI Bus Analyzer/Exerciser 0 v 15a3 Italtel 0 v 15a4 X-Net OY 0 v 15a5 Toyota Macs Inc 0 v 15a6 Sunlight Ultrasound Technologies Ltd 0 v 15a7 SSE Telecom Inc 0 v 15a8 Shanghai Communications Technologies Center 0 v 15aa Moreton Bay 0 v 15ab Bluesteel Networks Inc 0 v 15ac North Atlantic Instruments 0 v 15ad VMware Inc 0 d 15ad0405 [VMware SVGA II] PCI Display Adapter 0 d 15ad0710 Virtual SVGA 0 d 15ad0720 VMware High-Speed Virtual NIC [vmxnet] 0 v 15ae Amersham Pharmacia Biotech 0 v 15b0 Zoltrix International Ltd 0 v 15b1 Source Technology Inc 0 v 15b2 Mosaid Technologies Inc 0 v 15b3 Mellanox Technologies 0 d 15b35274 MT21108 InfiniBridge 0 d 15b35a44 MT23108 InfiniHost 0 d 15b35a45 MT23108 [Infinihost HCA Flash Recovery] 0 d 15b35a46 MT23108 PCI Bridge 0 d 15b35e8c MT24204 [InfiniHost III Lx HCA] 0 d 15b35e8d MT24204 [InfiniHost III Lx HCA Flash Recovery] 0 d 15b36278 MT25208 InfiniHost III Ex (Tavor compatibility mode) 0 d 15b36279 MT25208 [InfiniHost III Ex HCA Flash Recovery] 0 d 15b36282 MT25208 InfiniHost III Ex 0 v 15b4 CCI/TRIAD 0 v 15b5 Cimetrics Inc 0 v 15b6 Texas Memory Systems Inc 0 v 15b7 Sandisk Corp 0 v 15b8 ADDI-DATA GmbH 0 v 15b9 Maestro Digital Communications 0 v 15ba Impacct Technology Corp 0 v 15bb Portwell Inc 0 v 15bc Agilent Technologies 0 d 15bc2922 64 Bit, 133MHz PCI-X Exerciser & Protocol Checker 0 d 15bc2928 64 Bit, 66MHz PCI Exerciser & Analyzer 0 d 15bc2929 64 Bit, 133MHz PCI-X Analyzer & Exerciser 0 v 15bd DFI Inc 0 v 15be Sola Electronics 0 v 15bf High Tech Computer Corp (HTC) 0 v 15c0 BVM Ltd 0 v 15c1 Quantel 0 v 15c2 Newer Technology Inc 0 v 15c3 Taiwan Mycomp Co Ltd 0 v 15c4 EVSX Inc 0 v 15c5 Procomp Informatics Ltd 0 d 15c58010 1394b - 1394 Firewire 3-Port Host Adapter Card 0 v 15c6 Technical University of Budapest 0 v 15c7 Tateyama System Laboratory Co Ltd 0 d 15c70349 Tateyama C-PCI PLC/NC card Rev.01A 0 v 15c8 Penta Media Co Ltd 0 v 15c9 Serome Technology Inc 0 v 15ca Bitboys OY 0 v 15cb AG Electronics Ltd 0 v 15cc Hotrail Inc 0 v 15cd Dreamtech Co Ltd 0 v 15ce Genrad Inc 0 v 15cf Hilscher GmbH 0 v 15d1 Infineon Technologies AG 0 v 15d2 FIC (First International Computer Inc) 0 v 15d3 NDS Technologies Israel Ltd 0 v 15d4 Iwill Corp 0 v 15d5 Tatung Co 0 v 15d6 Entridia Corp 0 v 15d7 Rockwell-Collins Inc 0 v 15d8 Cybernetics Technology Co Ltd 0 v 15d9 Super Micro Computer Inc 0 v 15da Cyberfirm Inc 0 v 15db Applied Computing Systems Inc 0 v 15dc Litronic Inc 0 d 15dc0001 Argus 300 PCI Cryptography Module 0 v 15dd Sigmatel Inc 0 v 15de Malleable Technologies Inc 0 v 15df Infinilink Corp 0 v 15e0 Cacheflow Inc 0 v 15e1 Voice Technologies Group Inc 0 v 15e2 Quicknet Technologies Inc 0 v 15e3 Networth Technologies Inc 0 v 15e4 VSN Systemen BV 0 v 15e5 Valley technologies Inc 0 v 15e6 Agere Inc 0 v 15e7 Get Engineering Corp 0 v 15e8 National Datacomm Corp 0 d 15e80130 Wireless PCI Card 0 v 15e9 Pacific Digital Corp 0 d 15e91841 ADMA-100 DiscStaQ ATA Controller 0 v 15ea Tokyo Denshi Sekei K.K. 0 v 15eb Drsearch GmbH 0 v 15ec Beckhoff GmbH 0 d 15ec3101 FC3101 Profibus DP 1 Channel PCI 0 d 15ec5102 FC5102 0 v 15ed Macrolink Inc 0 v 15ee In Win Development Inc 0 v 15ef Intelligent Paradigm Inc 0 v 15f0 B-Tree Systems Inc 0 v 15f1 Times N Systems Inc 0 v 15f2 Diagnostic Instruments Inc 0 v 15f3 Digitmedia Corp 0 v 15f4 Valuesoft 0 v 15f5 Power Micro Research 0 v 15f6 Extreme Packet Device Inc 0 v 15f7 Banctec 0 v 15f8 Koga Electronics Co 0 v 15f9 Zenith Electronics Corp 0 v 15fa J.P. Axzam Corp 0 v 15fb Zilog Inc 0 v 15fc Techsan Electronics Co Ltd 0 v 15fd N-CUBED.NET 0 v 15fe Kinpo Electronics Inc 0 v 15ff Fastpoint Technologies Inc 0 v 1600 Northrop Grumman - Canada Ltd 0 v 1601 Tenta Technology 0 v 1602 Prosys-tec Inc 0 v 1603 Nokia Wireless Communications 0 v 1604 Central System Research Co Ltd 0 v 1605 Pairgain Technologies 0 v 1606 Europop AG 0 v 1607 Lava Semiconductor Manufacturing Inc 0 v 1608 Automated Wagering International 0 v 1609 Scimetric Instruments Inc 0 v 1612 Telesynergy Research Inc. 0 v 1619 FarSite Communications Ltd 0 d 16190400 FarSync T2P (2 port X.21/V.35/V.24) 0 d 16190440 FarSync T4P (4 port X.21/V.35/V.24) 0 v 161f Rioworks 0 www.rioworks.com v 1626 TDK Semiconductor Corp. 0 d 16268410 RTL81xx Fast Ethernet 0 v 1629 Kongsberg Spacetec AS 0 d 16291003 Format synchronizer v3.0 0 d 16292002 Fast Universal Data Output 0 v 1637 Linksys 0 This seems to occur on their 802.11b Wireless card WMP-11 d 16373874 Linksys 802.11b WMP11 PCI Wireless card 0 v 1638 Standard Microsystems Corp [SMC] 0 d 16381100 SMC2602W EZConnect / Addtron AWA-100 / Eumitcom PCI WL11000 0 v 163c Smart Link Ltd. 0 d 163c3052 SmartLink SmartPCI562 56K Modem 0 d 163c5449 SmartPCI561 Modem 0 v 1657 Brocade Communications Systems, Inc. 0 v 165a Epix Inc 0 d 165ac100 PIXCI(R) CL1 Camera Link Video Capture Board [custom QL5232] 0 d 165ad200 PIXCI(R) D2X Digital Video Capture Board [custom QL5232] 0 d 165ad300 PIXCI(R) D3X Digital Video Capture Board [custom QL5232] 0 v 165d Hsing Tech. Enterprise Co., Ltd. 0 v 1661 Worldspace Corp. 0 v 1668 Actiontec Electronics Inc 0 d 16680100 Mini-PCI bridge 0 v 166d Broadcom Corporation 0 Formerly SiByte, Inc. d 166d0001 SiByte BCM1125/1125H/1250 System-on-a-Chip PCI 0 d 166d0002 SiByte BCM1125H/1250 System-on-a-Chip HyperTransport 0 v 1677 Bernecker + Rainer 0 d 1677104e 5LS172.6 B&R Dual CAN Interface Card 0 d 167712d7 5LS172.61 B&R Dual CAN Interface Card 0 v 1681 Hercules 0 d 16810010 Hercules 3d Prophet II Ultra 64MB [ 350 MHz NV15BR core, 128-bit DDR @ 460 MHz, 1.5v AGP4x ] 0 More specs, more accurate desc. v 1688 CastleNet Technology Inc. 0 d 16881170 WLAN 802.11b card 0 v 168c Atheros Communications, Inc. 0 d 168c0007 AR5000 802.11a Wireless Adapter 0 d 168c0011 AR5210 802.11a NIC 0 d 168c0012 AR5211 802.11ab NIC 0 d 168c0013 AR5212 802.11abg NIC 0 s 168c001311863202 D-link DWL-G650 B3 Wireless cardbus adapter 0 s 168c001311863203 DWL-G520 Wireless PCI Adapter 0 s 168c001311863a13 DWL-G520 Wireless PCI Adapter rev. B 0 s 168c001311863a94 C54C Wireless 801.11g cardbus 0 s 168c001313854d00 Netgear WG311T Wireless PCI Adapter 0 s 168c001314b70a60 8482-WD ORiNOCO 11a/b/g Wireless PCI Adapter 0 s 168c0013168c0013 WG511T Wireless CardBus Adapter 0 s 168c0013168c1025 DWL-G650B2 Wireless CardBus Adapter 0 s 168c0013168c2026 Netgate 5354MP ARIES a(108Mb turbo)/b/g MiniPCI Adapter 0 d 168c1014 AR5212 802.11abg NIC 0 v 16a5 Tekram Technology Co.,Ltd. 0 v 16ab Global Sun Technology Inc 0 d 16ab1100 GL24110P 0 d 16ab1101 PLX9052 PCMCIA-to-PCI Wireless LAN 0 d 16ab1102 PCMCIA-to-PCI Wireless Network Bridge 0 v 16ae Safenet Inc 0 d 16ae1141 SafeXcel-1141 0 v 16b4 Aspex Semiconductor Ltd 0 v 16be Creatix Polymedia GmbH 0 v 16ca CENATEK Inc 0 d 16ca0001 Rocket Drive DL 0 v 16cd Densitron Technologies 0 v 16df PIKA Technologies Inc. 0 www.pikatechnologies.com v 16e3 European Space Agency 0 d 16e31e0f LEON2FT Processor 0 v 16ec U.S. Robotics 0 d 16ec00ff USR997900 10/100 Mbps PCI Network Card 0 d 16ec3685 Wireless Access PCI Adapter Model 022415 0 v 16ed Sycron N. V. 0 d 16ed1001 UMIO communication card 0 v 16f3 Jetway Information Co., Ltd. 0 v 16f4 Vweb Corp 0 d 16f48000 VW2010 0 v 16f6 VideoTele.com, Inc. 0 v 1702 Internet Machines Corporation (IMC) 0 www.internetmachines.com v 1705 Digital First, Inc. 0 v 170b NetOctave 0 d 170b0100 NSP2000-SSL crypto accelerator 0 v 170c YottaYotta Inc. 0 v 1725 Vitesse Semiconductor 0 Seems to be a 2nd ID for Vitesse Semiconductor d 17257174 VSC7174 PCI/PCI-X Serial ATA Host Bus Controller 0 v 172a Accelerated Encryption 0 v 1734 Fujitsu Siemens Computer GmbH 0 v 1737 Linksys 0 d 17370013 WMP54G Wireless Pci Card 0 d 17370015 WMP54GS Wireless Pci Card 0 d 17371032 Gigabit Network Adapter 0 s 1737103217370015 EG1032 v2 Instant Gigabit Network Adapter 0 d 17371064 Gigabit Network Adapter 0 s 1737106417370016 EG1064 v2 Instant Gigabit Network Adapter 0 d 1737ab08 21x4x DEC-Tulip compatible 10/100 Ethernet 0 d 1737ab09 21x4x DEC-Tulip compatible 10/100 Ethernet 0 v 173b Altima (nee Broadcom) 0 d 173b03e8 AC1000 Gigabit Ethernet 0 d 173b03e9 AC1001 Gigabit Ethernet 0 d 173b03ea AC9100 Gigabit Ethernet 0 s 173b03ea173b0001 AC1002 0 d 173b03eb AC1003 Gigabit Ethernet 0 v 1743 Peppercon AG 0 d 17438139 ROL/F-100 Fast Ethernet Adapter with ROL 0 v 1749 RLX Technologies 0 v 174b PC Partner Limited 0 v 174d WellX Telecom SA 0 v 175c AudioScience Inc 0 v 175e Sanera Systems, Inc. 0 v 1787 Hightech Information System Ltd. 0 v 1796 Research Centre Juelich 0 also used by Struck Innovative Systeme for joint developments d 17960001 SIS1100 [Gigabit link] 0 d 17960002 HOTlink 0 d 17960003 Counter Timer 0 d 17960004 CAMAC Controller 0 d 17960005 PROFIBUS 0 d 17960006 AMCC HOTlink 0 v 1797 JumpTec h, GMBH 0 v 1799 Belkin 0 d 17996001 Wireless PCI Card - F5D6001 0 d 17996020 Wireless PCMCIA Card - F5D6020 0 d 17996060 Wireless PDA Card - F5D6060 0 d 17997000 Wireless PCI Card - F5D7000 0 v 17a0 Genesys Logic, Inc 0 d 17a08033 GL880S USB 1.1 controller 0 d 17a08034 GL880S USB 2.0 controller 0 v 17af Hightech Information System Ltd. 0 v 17b3 Hawking Technologies 0 d 17b3ab08 PN672TX 10/100 Ethernet 0 v 17b4 Indra Networks, Inc. 0 d 17b40011 WebEnhance 100 GZIP Compression Card 0 v 17c0 Wistron Corp. 0 v 17c2 Newisys, Inc. 0 v 17cc NetChip Technology, Inc 0 d 17cc2280 USB 2.0 0 v 17d5 S2io Inc. 0 S2io ships 10Gb PCI-X Ethernet adapters www.s2io.com v 17ee Connect Components Ltd 0 http://www.connect3d.com v 17fe Linksys, A Division of Cisco Systems 0 d 17fe2220 [AirConn] INPROCOMM IPN 2220 Wireless LAN Adapter (rev 01) 0 v 1813 Ambient Technologies Inc 0 d 18134000 HaM controllerless modem 0 s 1813400016be0001 V9x HAM Data Fax Modem 0 d 18134100 HaM plus Data Fax Modem 0 s 1813410016be0002 V9x HAM 1394 0 v 1814 RaLink 0 d 18140101 Wireless PCI Adpator RT2400 / RT2460 0 d 18140201 Ralink RT2500 802.11 Cardbus Reference Card 0 s 181402011371001e CWC-854 Wireless-G CardBus Adapter 0 s 181402011371001f CWM-854 Wireless-G Mini PCI Adapter 0 s 1814020113710020 CWP-854 Wireless-G PCI Adapter 0 v 1820 InfiniCon Systems Inc. 0 v 1822 Twinhan Technology Co. Ltd 0 v 182d SiteCom Europe BV 0 d 182d3069 ISDN PCI DC-105V2 0 HFC-based ISDN card v 1830 Credence Systems Corporation 0 v 183b MikroM GmbH 0 d 183b08a7 MVC100 DVI 0 d 183b08a8 MVC101 SDI 0 d 183b08a9 MVC102 DVI+Audio 0 v 1849 ASRock Incorporation 0 v 1851 Microtune, Inc. 0 v 1852 Anritsu Corp. 0 v 1867 Topspin Communications 0 d 18675a44 MT23108 PCI-X HCA 0 d 18675a45 MT23108 PCI-X HCA flash recovery 0 d 18675a46 MT23108 PCI-X HCA bridge 0 d 18676278 MT25208 InfiniHost III Ex (Tavor compatibility mode) 0 d 18676282 MT25208 InfiniHost III Ex 0 v 1888 Varisys Ltd 0 d 18880301 VMFX1 FPGA PMC module 0 d 18880601 VSM2 dual PMC carrier 0 d 18880710 VS14x series PowerPC PCI board 0 d 18880720 VS24x series PowerPC PCI board 0 v 1894 KNC One 0 found e.g. on KNC DVB-S card v 1896 B&B Electronics Manufacturing Company, Inc. 0 v 18a1 Astute Networks Inc. 0 v 18ac DViCO Corporation 0 d 18acd810 FusionHDTV 3 Gold 0 v 18bc Info-Tek Corp. 0 v 18c8 Cray Inc 0 assigned to Octigabay System, which has been acquired by Cray v 18c9 ARVOO Engineering BV 0 v 18ca XGI - Xabre Graphics Inc 0 d 18ca0040 Volari V8 0 v 18e6 MPL AG 0 d 18e60001 OSCI [Octal Serial Communication Interface] 0 v 18f7 Commtech, Inc. 0 d 18f70001 Fastcom ESCC-PCI-335 0 d 18f70002 Fastcom 422/4-PCI-335 0 d 18f70004 Fastcom 422/2-PCI-335 0 d 18f70005 Fastcom IGESCC-PCI-ISO/1 0 d 18f7000a Fastcom 232/4-PCI-335 0 v 18fb Resilience Corporation 0 v 1a08 Sierra semiconductor 0 d 1a080000 SC15064 0 v 1b13 Jaton Corp 0 v 1c1c Symphony 0 d 1c1c0001 82C101 0 v 1d44 DPT 0 d 1d44a400 PM2x24/PM3224 0 v 1de1 Tekram Technology Co.,Ltd. 0 d 1de10391 TRM-S1040 0 d 1de12020 DC-390 0 d 1de1690c 690c 0 d 1de1dc29 DC290 0 v 1fc0 Tumsan Oy 0 d 1fc00300 E2200 Dual E1/Rawpipe Card 0 v 2000 Smart Link Ltd. 0 v 2001 Temporal Research Ltd 0 v 2003 Smart Link Ltd. 0 v 2004 Smart Link Ltd. 0 v 21c3 21st Century Computer Corp. 0 v 2348 Racore 0 d 23482010 8142 100VG/AnyLAN 0 v 2646 Kingston Technologies 0 v 270b Xantel Corporation 0 v 270f Chaintech Computer Co. Ltd 0 v 2711 AVID Technology Inc. 0 v 2a15 3D Vision(?) 0 v 3000 Hansol Electronics Inc. 0 v 3142 Post Impression Systems. 0 v 3388 Hint Corp 0 d 33880013 HiNT HC4 PCI to ISDN bridge, Multimedia audio controller 0 d 33880014 HiNT HC4 PCI to ISDN bridge, Network controller 0 d 33880020 HB6 Universal PCI-PCI bridge (transparent mode) 0 d 33880021 HB6 Universal PCI-PCI bridge (non-transparent mode) 0 s 338800214c531050 CT7 mainboard 0 s 338800214c531080 CT8 mainboard 0 s 338800214c5310a0 CA3/CR3 mainboard 0 s 338800214c533010 PPCI mezzanine (32-bit PMC) 0 s 338800214c533011 PPCI mezzanine (64-bit PMC) 0 d 33880022 HiNT HB4 PCI-PCI Bridge (PCI6150) 0 d 33880026 HB2 PCI-PCI Bridge 0 d 3388101a E.Band [AudioTrak Inca88] 0 d 3388101b E.Band [AudioTrak Inca88] 0 d 33888011 VXPro II Chipset 0 s 3388801133888011 VXPro II Chipset CPU to PCI Bridge 0 d 33888012 VXPro II Chipset 0 s 3388801233888012 VXPro II Chipset PCI to ISA Bridge 0 d 33888013 VXPro II IDE 0 s 3388801333888013 VXPro II Chipset EIDE Controller 0 v 3411 Quantum Designs (H.K.) Inc 0 v 3513 ARCOM Control Systems Ltd 0 v 3842 eVga.com. Corp. 0 v 38ef 4Links 0 v 3d3d 3DLabs 0 d 3d3d0001 GLINT 300SX 0 d 3d3d0002 GLINT 500TX 0 d 3d3d0003 GLINT Delta 0 d 3d3d0004 Permedia 0 d 3d3d0005 Permedia 0 d 3d3d0006 GLINT MX 0 d 3d3d0007 3D Extreme 0 d 3d3d0008 GLINT Gamma G1 0 d 3d3d0009 Permedia II 2D+3D 0 s 3d3d000910400011 AccelStar II 0 s 3d3d000913e91000 6221L-4U 0 s 3d3d00093d3d0100 AccelStar II 3D Accelerator 0 s 3d3d00093d3d0111 Permedia 3:16 0 s 3d3d00093d3d0114 Santa Ana 0 s 3d3d00093d3d0116 Oxygen GVX1 0 s 3d3d00093d3d0119 Scirocco 0 s 3d3d00093d3d0120 Santa Ana PCL 0 s 3d3d00093d3d0125 Oxygen VX1 0 s 3d3d00093d3d0127 Permedia3 Create! 0 d 3d3d000a GLINT R3 0 s 3d3d000a3d3d0121 Oxygen VX1 0 d 3d3d000c GLINT R3 [Oxygen VX1] 0 s 3d3d000c3d3d0144 Oxygen VX1-4X AGP [Permedia 4] 0 d 3d3d000d GLint R4 rev A 0 d 3d3d0011 GLint R4 rev B 0 d 3d3d0012 GLint R5 rev A 0 d 3d3d0013 GLint R5 rev B 0 d 3d3d0020 VP10 visual processor 0 d 3d3d0022 VP10 visual processor 0 P10 generic II d 3d3d0024 VP9 visual processor 0 d 3d3d0100 Permedia II 2D+3D 0 d 3d3d07a1 Wildcat III 6210 0 d 3d3d07a2 Sun XVR-500 Graphics Accelerator 0 d 3d3d07a3 Wildcat IV 7210 0 d 3d3d1004 Permedia 0 d 3d3d3d04 Permedia 0 d 3d3dffff Glint VGA 0 v 4005 Avance Logic Inc. 0 d 40050300 ALS300 PCI Audio Device 0 d 40050308 ALS300+ PCI Audio Device 0 d 40050309 PCI Input Controller 0 d 40051064 ALG-2064 0 d 40052064 ALG-2064i 0 d 40052128 ALG-2364A GUI Accelerator 0 d 40052301 ALG-2301 0 d 40052302 ALG-2302 0 d 40052303 AVG-2302 GUI Accelerator 0 d 40052364 ALG-2364A 0 d 40052464 ALG-2464 0 d 40052501 ALG-2564A/25128A 0 d 40054000 ALS4000 Audio Chipset 0 s 4005400040054000 ALS4000 Audio Chipset 0 d 40054710 ALC200/200P 0 v 4033 Addtron Technology Co, Inc. 0 d 40331360 RTL8139 Ethernet 0 v 4143 Digital Equipment Corp 0 v 4144 Alpha Data 0 v 416c Aladdin Knowledge Systems 0 d 416c0100 AladdinCARD 0 d 416c0200 CPC 0 v 4444 Internext Compression Inc 0 d 44440016 iTVC16 (CX23416) MPEG-2 Encoder 0 s 4444001600704009 WinTV PVR 250 0 d 44440803 iTVC15 MPEG-2 Encoder 0 s 4444080300704000 WinTV PVR-350 0 s 4444080300704001 WinTV PVR-250 0 v 4468 Bridgeport machines 0 v 4594 Cogetec Informatique Inc 0 v 45fb Baldor Electric Company 0 v 4680 Umax Computer Corp 0 v 4843 Hercules Computer Technology Inc 0 v 4916 RedCreek Communications Inc 0 d 49161960 RedCreek PCI adapter 0 v 4943 Growth Networks 0 v 494f ACCES I/O Products, Inc. 0 d 494f10e8 LPCI-COM-8SM 0 v 4978 Axil Computer Inc 0 v 4a14 NetVin 0 d 4a145000 NV5000SC 0 s 4a1450004a145000 RT8029-Based Ethernet Adapter 0 v 4b10 Buslogic Inc. 0 v 4c48 LUNG HWA Electronics 0 v 4c53 SBS Technologies 0 d 4c530000 PLUSTEST device 0 s 4c5300004c533000 PLUSTEST card (PC104+) 0 s 4c5300004c533001 PLUSTEST card (PMC) 0 d 4c530001 PLUSTEST-MM device 0 s 4c5300014c533002 PLUSTEST-MM card (PMC) 0 v 4ca1 Seanix Technology Inc 0 v 4d51 MediaQ Inc. 0 d 4d510200 MQ-200 0 v 4d54 Microtechnica Co Ltd 0 v 4ddc ILC Data Device Corp 0 d 4ddc0100 DD-42924I5-300 (ARINC 429 Data Bus) 0 d 4ddc0801 BU-65570I1 MIL-STD-1553 Test and Simulation 0 d 4ddc0802 BU-65570I2 MIL-STD-1553 Test and Simulation 0 d 4ddc0811 BU-65572I1 MIL-STD-1553 Test and Simulation 0 d 4ddc0812 BU-65572I2 MIL-STD-1553 Test and Simulation 0 d 4ddc0881 BU-65570T1 MIL-STD-1553 Test and Simulation 0 d 4ddc0882 BU-65570T2 MIL-STD-1553 Test and Simulation 0 d 4ddc0891 BU-65572T1 MIL-STD-1553 Test and Simulation 0 d 4ddc0892 BU-65572T2 MIL-STD-1553 Test and Simulation 0 d 4ddc0901 BU-65565C1 MIL-STD-1553 Data Bus 0 d 4ddc0902 BU-65565C2 MIL-STD-1553 Data Bus 0 d 4ddc0903 BU-65565C3 MIL-STD-1553 Data Bus 0 d 4ddc0904 BU-65565C4 MIL-STD-1553 Data Bus 0 d 4ddc0b01 BU-65569I1 MIL-STD-1553 Data Bus 0 d 4ddc0b02 BU-65569I2 MIL-STD-1553 Data Bus 0 d 4ddc0b03 BU-65569I3 MIL-STD-1553 Data Bus 0 d 4ddc0b04 BU-65569I4 MIL-STD-1553 Data Bus 0 v 5046 GemTek Technology Corporation 0 d 50461001 PCI Radio 0 v 5053 Voyetra Technologies 0 d 50532010 Daytona Audio Adapter 0 v 5136 S S Technologies 0 v 5143 Qualcomm Inc 0 v 5145 Ensoniq (Old) 0 d 51453031 Concert AudioPCI 0 v 5168 Animation Technologies Inc. 0 v 5301 Alliance Semiconductor Corp. 0 d 53010001 ProMotion aT3D 0 v 5333 S3 Inc. 0 d 53330551 Plato/PX (system) 0 d 53335631 86c325 [ViRGE] 0 d 53338800 86c866 [Vision 866] 0 d 53338801 86c964 [Vision 964] 0 d 53338810 86c764_0 [Trio 32 vers 0] 0 d 53338811 86c764/765 [Trio32/64/64V+] 0 d 53338812 86cM65 [Aurora64V+] 0 d 53338813 86c764_3 [Trio 32/64 vers 3] 0 d 53338814 86c767 [Trio 64UV+] 0 d 53338815 86cM65 [Aurora 128] 0 d 5333883d 86c988 [ViRGE/VX] 0 d 53338870 FireGL 0 d 53338880 86c868 [Vision 868 VRAM] vers 0 0 d 53338881 86c868 [Vision 868 VRAM] vers 1 0 d 53338882 86c868 [Vision 868 VRAM] vers 2 0 d 53338883 86c868 [Vision 868 VRAM] vers 3 0 d 533388b0 86c928 [Vision 928 VRAM] vers 0 0 d 533388b1 86c928 [Vision 928 VRAM] vers 1 0 d 533388b2 86c928 [Vision 928 VRAM] vers 2 0 d 533388b3 86c928 [Vision 928 VRAM] vers 3 0 d 533388c0 86c864 [Vision 864 DRAM] vers 0 0 d 533388c1 86c864 [Vision 864 DRAM] vers 1 0 d 533388c2 86c864 [Vision 864-P DRAM] vers 2 0 d 533388c3 86c864 [Vision 864-P DRAM] vers 3 0 d 533388d0 86c964 [Vision 964 VRAM] vers 0 0 d 533388d1 86c964 [Vision 964 VRAM] vers 1 0 d 533388d2 86c964 [Vision 964-P VRAM] vers 2 0 d 533388d3 86c964 [Vision 964-P VRAM] vers 3 0 d 533388f0 86c968 [Vision 968 VRAM] rev 0 0 d 533388f1 86c968 [Vision 968 VRAM] rev 1 0 d 533388f2 86c968 [Vision 968 VRAM] rev 2 0 d 533388f3 86c968 [Vision 968 VRAM] rev 3 0 d 53338900 86c755 [Trio 64V2/DX] 0 s 5333890053338900 86C775 Trio64V2/DX 0 d 53338901 86c775/86c785 [Trio 64V2/DX or /GX] 0 s 5333890153338901 86C775 Trio64V2/DX, 86C785 Trio64V2/GX 0 d 53338902 Plato/PX 0 d 53338903 Trio 3D business multimedia 0 d 53338904 Trio 64 3D 0 s 53338904101400db Integrated Trio3D 0 s 5333890453338904 86C365 Trio3D AGP 0 d 53338905 Trio 64V+ family 0 d 53338906 Trio 64V+ family 0 d 53338907 Trio 64V+ family 0 d 53338908 Trio 64V+ family 0 d 53338909 Trio 64V+ family 0 d 5333890a Trio 64V+ family 0 d 5333890b Trio 64V+ family 0 d 5333890c Trio 64V+ family 0 d 5333890d Trio 64V+ family 0 d 5333890e Trio 64V+ family 0 d 5333890f Trio 64V+ family 0 d 53338a01 ViRGE/DX or /GX 0 s 53338a010e11b032 ViRGE/GX 0 s 53338a0110b41617 Nitro 3D 0 s 53338a0110b41717 Nitro 3D 0 s 53338a0153338a01 ViRGE/DX 0 d 53338a10 ViRGE/GX2 0 s 53338a1010928a10 Stealth 3D 4000 0 d 53338a13 86c368 [Trio 3D/2X] 0 s 53338a1353338a13 Trio3D/2X 0 d 53338a20 86c794 [Savage 3D] 0 s 53338a2053338a20 86C391 Savage3D 0 d 53338a21 86c390 [Savage 3D/MV] 0 s 53338a2153338a21 86C390 Savage3D/MV 0 d 53338a22 Savage 4 0 s 53338a2210338068 Savage 4 0 s 53338a2210338069 Savage 4 0 s 53338a2210338110 Savage4 LT 0 s 53338a22105d0018 SR9 8Mb SDRAM 0 s 53338a22105d002a SR9 Pro 16Mb SDRAM 0 s 53338a22105d003a SR9 Pro 32Mb SDRAM 0 s 53338a22105d092f SR9 Pro+ 16Mb SGRAM 0 s 53338a2210924207 Stealth III S540 0 s 53338a2210924800 Stealth III S540 0 s 53338a2210924807 SpeedStar A90 0 s 53338a2210924808 Stealth III S540 0 s 53338a2210924809 Stealth III S540 0 s 53338a221092480e Stealth III S540 0 s 53338a2210924904 Stealth III S520 0 s 53338a2210924905 SpeedStar A200 0 s 53338a2210924a09 Stealth III S540 0 s 53338a2210924a0b Stealth III S540 Xtreme 0 s 53338a2210924a0f Stealth III S540 0 s 53338a2210924e01 Stealth III S540 0 s 53338a221102101d 3d Blaster Savage 4 0 s 53338a221102101e 3d Blaster Savage 4 0 s 53338a2253338100 86C394-397 Savage4 SDRAM 100 0 s 53338a2253338110 86C394-397 Savage4 SDRAM 110 0 s 53338a2253338125 86C394-397 Savage4 SDRAM 125 0 s 53338a2253338143 86C394-397 Savage4 SDRAM 143 0 s 53338a2253338a22 86C394-397 Savage4 0 s 53338a2253338a2e 86C394-397 Savage4 32bit 0 s 53338a2253339125 86C394-397 Savage4 SGRAM 125 0 s 53338a2253339143 86C394-397 Savage4 SGRAM 143 0 d 53338a23 Savage 4 0 d 53338a25 ProSavage PM133 0 d 53338a26 ProSavage KM133 0 d 53338c00 ViRGE/M3 0 d 53338c01 ViRGE/MX 0 s 53338c0111790001 ViRGE/MX 0 d 53338c02 ViRGE/MX+ 0 d 53338c03 ViRGE/MX+MV 0 d 53338c10 86C270-294 Savage/MX-MV 0 d 53338c11 82C270-294 Savage/MX 0 d 53338c12 86C270-294 Savage/IX-MV 0 s 53338c121014017f ThinkPad T20 0 d 53338c13 86C270-294 Savage/IX 0 s 53338c1311790001 Magnia Z310 0 d 53338c22 SuperSavage MX/128 0 d 53338c24 SuperSavage MX/64 0 d 53338c26 SuperSavage MX/64C 0 d 53338c2a SuperSavage IX/128 SDR 0 d 53338c2b SuperSavage IX/128 DDR 0 d 53338c2c SuperSavage IX/64 SDR 0 d 53338c2d SuperSavage IX/64 DDR 0 d 53338c2e SuperSavage IX/C SDR 0 s 53338c2e101401fc ThinkPad T23 (2647-4MG) 0 d 53338c2f SuperSavage IX/C DDR 0 d 53338d01 86C380 [ProSavageDDR K4M266] 0 d 53338d02 VT8636A [ProSavage KN133] AGP4X VGA Controller (TwisterK) 0 d 53338d03 VT8751 [ProSavageDDR P4M266] 0 d 53338d04 VT8375 [ProSavage8 KM266/KL266] 0 d 53339102 86C410 Savage 2000 0 s 5333910210925932 Viper II Z200 0 s 5333910210925934 Viper II Z200 0 s 5333910210925952 Viper II Z200 0 s 5333910210925954 Viper II Z200 0 s 5333910210925a35 Viper II Z200 0 s 5333910210925a37 Viper II Z200 0 s 5333910210925a55 Viper II Z200 0 s 5333910210925a57 Viper II Z200 0 d 5333ca00 SonicVibes 0 v 544c Teralogic Inc 0 d 544c0350 TL880-based HDTV/ATSC tuner 0 v 5455 Technische University Berlin 0 d 54554458 S5933 0 v 5519 Cnet Technologies, Inc. 0 v 5544 Dunord Technologies 0 d 55440001 I-30xx Scanner Interface 0 v 5555 Genroco, Inc 0 d 55550003 TURBOstor HFP-832 [HiPPI NIC] 0 v 5654 VoiceTronix Pty Ltd 0 d 56543132 OpenSwitch12 0 v 5700 Netpower 0 v 5851 Exacq Technologies 0 v 6356 UltraStor 0 v 6374 c't Magazin fr Computertechnik 0 d 63746773 GPPCI 0 v 6409 Logitec Corp. 0 v 6666 Decision Computer International Co. 0 d 66660001 PCCOM4 0 d 66660002 PCCOM8 0 v 7604 O.N. Electronic Co Ltd. 0 v 7bde MIDAC Corporation 0 v 7fed PowerTV 0 v 8008 Quancom Electronic GmbH 0 d 80080010 WDOG1 [PCI-Watchdog 1] 0 d 80080011 PWDOG2 [PCI-Watchdog 2] 0 v 807d Asustek Computer, Inc. 0 Wrong ID used in subsystem ID of AsusTek PCI-USB2 PCI card. v 8086 Intel Corp. 0 d 80860007 82379AB 0 d 80860008 Extended Express System Support Controller 0 s 8086000800081000 WorldMark 4300 INCA ASIC 0 d 80860039 21145 Fast Ethernet 0 d 80860122 82437FX 0 d 80860309 80303 I/O Processor PCI-to-PCI Bridge 0 d 8086030d 80312 I/O Companion Chip PCI-to-PCI Bridge 0 d 80860326 6700/6702PXH I/OxAPIC Interrupt Controller A 0 d 80860327 6700PXH I/OxAPIC Interrupt Controller B 0 d 80860329 6700PXH PCI Express-to-PCI Bridge A 0 d 8086032a 6700PXH PCI Express-to-PCI Bridge B 0 d 8086032c 6702PXH PCI Express-to-PCI Bridge A 0 d 80860330 80332 [Dobson] I/O processor 0 A-segment bridge d 80860331 80332 [Dobson] I/O processor 0 A-segment IOAPIC d 80860332 80332 [Dobson] I/O processor 0 B-segment bridge d 80860333 80332 [Dobson] I/O processor 0 B-segment IOAPIC d 80860334 80332 [Dobson] I/O processor 0 Address Translation Unit (ATU) d 80860335 80331 [Lindsay] I/O processor 0 PCI-X bridge d 80860336 80331 [Lindsay] I/O processor 0 Address Translation Unit (ATU) d 80860340 41210 [Lanai] Serial to Parallel PCI Bridge 0 A-segment bridge d 80860341 41210 [Lanai] Serial to Parallel PCI Bridge 0 B-segment bridge d 80860482 82375EB/SB PCI to EISA Bridge 0 d 80860483 82424TX/ZX [Saturn] CPU to PCI bridge 0 d 80860484 82378ZB/IB, 82379AB (SIO, SIO.A) PCI to ISA Bridge 0 d 80860486 82425EX/ZX [Aries] PCIset with ISA bridge 0 d 808604a3 82434LX/NX [Mercury/Neptune] Processor to PCI bridge 0 d 808604d0 82437FX [Triton FX] 0 d 80860500 E8870 Processor bus control 0 d 80860501 E8870 Memory controller 0 d 80860502 E8870 Scalability Port 0 0 and registers common to both SPs d 80860503 E8870 Scalability Port 1 0 and global performance monitoring d 80860510 E8870IO Hub Interface Port 0 registers (8-bit compatibility port) 0 d 80860511 E8870IO Hub Interface Port 1 registers 0 d 80860512 E8870IO Hub Interface Port 2 registers 0 d 80860513 E8870IO Hub Interface Port 3 registers 0 d 80860514 E8870IO Hub Interface Port 4 registers 0 d 80860515 E8870IO General SIOH registers 0 d 80860516 E8870IO RAS registers 0 d 80860530 E8870SP Scalability Port 0 registers 0 d 80860531 E8870SP Scalability Port 1 registers 0 d 80860532 E8870SP Scalability Port 2 registers 0 d 80860533 E8870SP Scalability Port 3 registers 0 d 80860534 E8870SP Scalability Port 4 registers 0 d 80860535 E8870SP Scalability Port 5 registers 0 d 80860536 E8870SP Interleave registers 0 and 1 0 (bi-interleave 0) and global registers that are neither per-port nor per-interleave d 80860537 E8870SP Interleave registers 2 and 3 0 (bi-interleave 1) d 80860600 RAID Controller 0 s 80860600808601c1 ICP Vortex GDT8546RZ 0 s 80860600808601f7 SCRU32 0 d 8086061f 80303 I/O Processor 0 uninitialized SRCU32 RAID Controller d 80860960 80960RP [i960 RP Microprocessor/Bridge] 0 d 80860962 80960RM [i960RM Bridge] 0 d 80860964 80960RP [i960 RP Microprocessor/Bridge] 0 d 80861000 82542 Gigabit Ethernet Controller 0 s 808610000e11b0df NC1632 Gigabit Ethernet Adapter (1000-SX) 0 s 808610000e11b0e0 NC1633 Gigabit Ethernet Adapter (1000-LX) 0 s 808610000e11b123 NC1634 Gigabit Ethernet Adapter (1000-SX) 0 s 8086100010140119 Netfinity Gigabit Ethernet SX Adapter 0 s 8086100080861000 PRO/1000 Gigabit Server Adapter 0 d 80861001 82543GC Gigabit Ethernet Controller (Fiber) 0 s 808610010e11004a NC6136 Gigabit Server Adapter 0 s 80861001101401ea Netfinity Gigabit Ethernet SX Adapter 0 s 8086100180861002 PRO/1000 F Server Adapter 0 s 8086100180861003 PRO/1000 F Server Adapter 0 d 80861002 Pro 100 LAN+Modem 56 Cardbus II 0 s 808610028086200e Pro 100 LAN+Modem 56 Cardbus II 0 s 8086100280862013 Pro 100 SR Mobile Combo Adapter 0 s 8086100280862017 Pro 100 S Combo Mobile Adapter 0 d 80861004 82543GC Gigabit Ethernet Controller (Copper) 0 s 808610040e110049 NC7132 Gigabit Upgrade Module 0 s 808610040e11b1a4 NC7131 Gigabit Server Adapter 0 s 80861004101410f2 Gigabit Ethernet Server Adapter 0 s 8086100480861004 PRO/1000 T Server Adapter 0 s 8086100480862004 PRO/1000 T Server Adapter 0 d 80861008 82544EI Gigabit Ethernet Controller (Copper) 0 s 8086100810140269 iSeries 1000/100/10 Ethernet Adapter 0 s 808610081028011c PRO/1000 XT Network Connection 0 s 8086100880861107 PRO/1000 XT Server Adapter 0 s 8086100880862107 PRO/1000 XT Server Adapter 0 s 8086100880862110 PRO/1000 XT Server Adapter 0 s 8086100880863108 PRO/1000 XT Network Connection 0 d 80861009 82544EI Gigabit Ethernet Controller (Fiber) 0 s 8086100910140268 iSeries Gigabit Ethernet Adapter 0 s 8086100980861109 PRO/1000 XF Server Adapter 0 s 8086100980862109 PRO/1000 XF Server Adapter 0 d 8086100c 82544GC Gigabit Ethernet Controller (Copper) 0 s 8086100c80861112 PRO/1000 T Desktop Adapter 0 s 8086100c80862112 PRO/1000 T Desktop Adapter 0 d 8086100d 82544GC Gigabit Ethernet Controller (LOM) 0 s 8086100d10280123 PRO/1000 XT Network Connection 0 s 8086100d1079891f 82544GC Based Network Connection 0 s 8086100d4c531080 CT8 mainboard 0 s 8086100d8086110d 82544GC Based Network Connection 0 d 8086100e 82540EM Gigabit Ethernet Controller 0 s 8086100e10140265 PRO/1000 MT Network Connection 0 s 8086100e10140267 PRO/1000 MT Network Connection 0 s 8086100e1014026a PRO/1000 MT Network Connection 0 s 8086100e1028002e Optiplex GX260 0 s 8086100e10280151 PRO/1000 MT Network Connection 0 s 8086100e107b8920 PRO/1000 MT Desktop Adapter 0 s 8086100e8086001e PRO/1000 MT Desktop Adapter 0 s 8086100e8086002e PRO/1000 MT Desktop Adapter 0 d 8086100f 82545EM Gigabit Ethernet Controller (Copper) 0 s 8086100f10140269 iSeries 1000/100/10 Ethernet Adapter 0 s 8086100f1014028e PRO/1000 MT Network Connection 0 s 8086100f80861000 PRO/1000 MT Network Connection 0 s 8086100f80861001 PRO/1000 MT Server Adapter 0 d 80861010 82546EB Gigabit Ethernet Controller (Copper) 0 s 808610101014027c PRO/1000 MT Dual Port Network Adapter 0 s 8086101018fb7872 RESlink-X 0 s 808610104c531080 CT8 mainboard 0 s 808610104c5310a0 CA3/CR3 mainboard 0 s 8086101080861011 PRO/1000 MT Dual Port Server Adapter 0 s 808610108086101a PRO/1000 MT Dual Port Network Adapter 0 s 8086101080863424 SE7501HG2 Mainboard 0 d 80861011 82545EM Gigabit Ethernet Controller (Fiber) 0 s 8086101110140268 iSeries Gigabit Ethernet Adapter 0 s 8086101180861002 PRO/1000 MF Server Adapter 0 s 8086101180861003 PRO/1000 MF Server Adapter (LX) 0 d 80861012 82546EB Gigabit Ethernet Controller (Fiber) 0 s 8086101280861012 PRO/1000 MF Dual Port Server Adapter 0 d 80861013 82541EI Gigabit Ethernet Controller (Copper) 0 s 8086101380860013 PRO/1000 MT Network Connection 0 s 8086101380861013 IBM ThinkCentre Network Card 0 s 8086101380861113 PRO/1000 MT Desktop Adapter 0 d 80861014 82541ER Gigabit Ethernet Controller 0 d 80861015 82540EM Gigabit Ethernet Controller (LOM) 0 d 80861016 82540EP Gigabit Ethernet Controller (LOM) 0 s 808610161014052c PRO/1000 MT Mobile Connection 0 s 8086101611790001 PRO/1000 MT Mobile Connection 0 s 8086101680861016 PRO/1000 MT Mobile Connection 0 d 80861017 82540EP Gigabit Ethernet Controller (LOM) 0 s 8086101780861017 PR0/1000 MT Desktop Connection 0 d 80861018 82541EI Gigabit Ethernet Controller 0 Update controller name from 82541EP to 82541EI s 8086101880861018 PRO/1000 MT Desktop Adapter 0 d 80861019 82547EI Gigabit Ethernet Controller (LOM) 0 s 8086101914581019 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 8086101980861019 PRO/1000 CT Desktop Connection 0 s 808610198086301f D865PERL mainboard 0 s 8086101980863427 S875WP1-E mainboard 0 d 8086101d 82546EB Gigabit Ethernet Controller 0 s 8086101d80861000 PRO/1000 MT Quad Port Server Adapter 0 d 8086101e 82540EP Gigabit Ethernet Controller (Mobile) 0 s 8086101e10140549 PRO/1000 MT Mobile Connection 0 s 8086101e11790001 PRO/1000 MT Mobile Connection 0 s 8086101e8086101e PRO/1000 MT Mobile Connection 0 d 80861026 82545GM Gigabit Ethernet Controller 0 s 8086102680861000 PRO/1000 MT Server Connection 0 s 8086102680861001 PRO/1000 MT Server Adapter 0 s 8086102680861002 PRO/1000 MT Server Adapter 0 s 8086102680861026 PRO/1000 MT Server Connection 0 d 80861027 82545GM Gigabit Ethernet Controller 0 s 8086102780861001 PRO/1000 MF Server Adapter(LX) 0 s 8086102780861002 PRO/1000 MF Server Adapter(LX) 0 s 8086102780861003 PRO/1000 MF Server Adapter(LX) 0 s 8086102780861027 PRO/1000 MF Server Adapter 0 d 80861028 82545GM Gigabit Ethernet Controller 0 s 8086102880861028 PRO/1000 MB Server Adapter 0 d 80861029 82559 Ethernet Controller 0 d 80861030 82559 InBusiness 10/100 0 d 80861031 82801CAM (ICH3) PRO/100 VE (LOM) Ethernet Controller 0 s 8086103110140209 ThinkPad A/T/X Series 0 s 80861031104d80e7 Vaio PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 80861031107b5350 EtherExpress PRO/100 VE 0 s 8086103111790001 EtherExpress PRO/100 VE 0 s 80861031144dc000 EtherExpress PRO/100 VE 0 s 80861031144dc001 EtherExpress PRO/100 VE 0 s 80861031144dc003 EtherExpress PRO/100 VE 0 s 80861031144dc006 vpr Matrix 170B4 0 d 80861032 82801CAM (ICH3) PRO/100 VE Ethernet Controller 0 d 80861033 82801CAM (ICH3) PRO/100 VM (LOM) Ethernet Controller 0 d 80861034 82801CAM (ICH3) PRO/100 VM Ethernet Controller 0 d 80861035 82801CAM (ICH3)/82562EH (LOM) Ethernet Controller 0 d 80861036 82801CAM (ICH3) 82562EH Ethernet Controller 0 d 80861037 82801CAM (ICH3) Chipset Ethernet Controller 0 d 80861038 82801CAM (ICH3) PRO/100 VM (KM) Ethernet Controller 0 d 80861039 82801DB PRO/100 VE (LOM) Ethernet Controller 0 s 8086103910140267 NetVista A30p 0 d 8086103a 82801DB PRO/100 VE (CNR) Ethernet Controller 0 d 8086103b 82801DB PRO/100 VM (LOM) Ethernet Controller 0 d 8086103c 82801DB PRO/100 VM (CNR) Ethernet Controller 0 d 8086103d 82801DB PRO/100 VE (MOB) Ethernet Controller 0 d 8086103e 82801DB PRO/100 VM (MOB) Ethernet Controller 0 d 80861040 536EP Data Fax Modem 0 s 8086104016be1040 V.9X DSP Data Fax Modem 0 d 80861043 PRO/Wireless LAN 2100 3B Mini PCI Adapter 0 s 8086104380862527 MIM2000/Centrino 0 d 80861048 PRO/10GbE LR Server Adapter 0 s 808610488086a01f PRO/10GbE LR Server Adapter 0 s 808610488086a11f PRO/10GbE LR Server Adapter 0 d 80861050 82562EZ 10/100 Ethernet Controller 0 s 808610501462728c 865PE Neo2 (MS-6728) 0 s 808610501462758c MS-6758 (875P Neo) 0 s 8086105080863427 S875WP1-E mainboard 0 d 80861051 82801EB/ER (ICH5/ICH5R) integrated LAN Controller 0 d 80861059 82551QM Ethernet Controller 0 d 80861064 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller 0 ICH-6 Component d 80861065 82562ET/EZ/GT/GZ - PRO/100 VE Ethernet Controller 0 ICH-6 Component d 80861066 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller 0 ICH-6 Component d 80861067 82562 EM/EX/GX - PRO/100 VM Ethernet Controller 0 ICH-6 Component d 80861068 82562ET/EZ/GT/GZ - PRO/100 VE (LOM) Ethernet Controller Mobile 0 ICH-6 Component d 80861069 82562 EM/EX/GX - PRO/100 VM (LOM) Ethernet Controller Mobile 0 ICH-6 Component d 8086106a 82562G \t- PRO/100 VE (LOM) Ethernet Controller 0 ICH-6 Component d 8086106b 82562G \t- PRO/100 VE Ethernet Controller Mobile 0 ICH-6 Component d 80861075 82547GI Gigabit Ethernet Controller 0 s 8086107510280165 PowerEdge 750 0 s 8086107580860075 PRO/1000 CT Network Connection 0 s 8086107580861075 PRO/1000 CT Network Connection 0 d 80861076 82541GI/PI Gigabit Ethernet Controller 0 s 8086107610280165 PowerEdge 750 0 s 8086107680860076 PRO/1000 MT Network Connection 0 s 8086107680861076 PRO/1000 MT Network Connection 0 s 8086107680861176 PRO/1000 MT Desktop Adapter 0 s 8086107680861276 PRO/1000 MT Desktop Adapter 0 d 80861077 82541GI Gigabit Ethernet Controller 0 s 8086107711790001 PRO/1000 MT Mobile Connection 0 s 8086107780860077 PRO/1000 MT Mobile Connection 0 s 8086107780861077 PRO/1000 MT Mobile Connection 0 d 80861078 82541EI Gigabit Ethernet Controller 0 s 8086107880861078 PRO/1000 MT Network Connection 0 d 80861079 82546GB Gigabit Ethernet Controller 0 s 80861079103c12a6 HP Dual Port 1000Base-T [A9900A] 0 s 80861079103c12cf HP Core Dual Port 1000Base-T [AB352A] 0 s 808610794c531090 Cx9 / Vx9 mainboard 0 s 808610794c5310b0 CL9 mainboard 0 s 8086107980860079 PRO/1000 MT Dual Port Network Connection 0 s 8086107980861079 PRO/1000 MT Dual Port Network Connection 0 s 8086107980861179 PRO/1000 MT Dual Port Network Connection 0 s 808610798086117a PRO/1000 MT Dual Port Server Adapter 0 d 8086107a 82546GB Gigabit Ethernet Controller 0 s 8086107a103c12a8 HP Dual Port 1000base-SX [A9899A] 0 s 8086107a8086107a PRO/1000 MF Dual Port Server Adapter 0 s 8086107a8086127a PRO/1000 MF Dual Port Server Adapter 0 d 8086107b 82546GB Gigabit Ethernet Controller 0 s 8086107b8086007b PRO/1000 MB Dual Port Server Connection 0 s 8086107b8086107b PRO/1000 MB Dual Port Server Connection 0 d 80861107 PRO/1000 MF Server Adapter (LX) 0 d 80861130 82815 815 Chipset Host Bridge and Memory Controller Hub 0 s 8086113010251016 Travelmate 612 TX 0 s 8086113010438027 TUSL2-C Mainboard 0 s 80861130104d80df Vaio PCG-FX403 0 s 8086113080864532 D815EEA2 mainboard 0 s 8086113080864557 D815EGEW Mainboard 0 d 80861131 82815 815 Chipset AGP Bridge 0 d 80861132 82815 CGC [Chipset Graphics Controller] 0 s 8086113210251016 Travelmate 612 TX 0 s 80861132104d80df Vaio PCG-FX403 0 s 8086113280864532 D815EEA2 Mainboard 0 s 8086113280864557 D815EGEW Mainboard 0 d 80861161 82806AA PCI64 Hub Advanced Programmable Interrupt Controller 0 s 8086116180861161 82806AA PCI64 Hub APIC 0 d 80861162 Xscale 80200 Big Endian Companion Chip 0 d 80861200 Intel IXP1200 Network Processor 0 s 80861200172a0000 AEP SSL Accelerator 0 d 80861209 8255xER/82551IT Fast Ethernet Controller 0 s 808612094c531050 CT7 mainboard 0 s 808612094c531051 CE7 mainboard 0 s 808612094c531070 PC6 mainboard 0 d 80861221 82092AA PCI to PCMCIA Bridge 0 d 80861222 82092AA IDE Controller 0 d 80861223 SAA7116 0 d 80861225 82452KX/GX [Orion] 0 d 80861226 82596 PRO/10 PCI 0 d 80861227 82865 EtherExpress PRO/100A 0 d 80861228 82556 EtherExpress PRO/100 Smart 0 d 80861229 82557/8/9 [Ethernet Pro 100] 0 the revision field differentiates between them (1-3 is 82557, 4-5 is 82558, 6-8 is 82559, 9 is 82559ER) s 808612290e113001 82559 Fast Ethernet LOM with Alert on LAN* 0 s 808612290e113002 82559 Fast Ethernet LOM with Alert on LAN* 0 s 808612290e113003 82559 Fast Ethernet LOM with Alert on LAN* 0 s 808612290e113004 82559 Fast Ethernet LOM with Alert on LAN* 0 s 808612290e113005 82559 Fast Ethernet LOM with Alert on LAN* 0 s 808612290e113006 82559 Fast Ethernet LOM with Alert on LAN* 0 s 808612290e113007 82559 Fast Ethernet LOM with Alert on LAN* 0 s 808612290e11b01e NC3120 Fast Ethernet NIC 0 s 808612290e11b01f NC3122 Fast Ethernet NIC (dual port) 0 s 808612290e11b02f NC1120 Ethernet NIC 0 s 808612290e11b04a Netelligent 10/100TX NIC with Wake on LAN 0 s 808612290e11b0c6 NC3161 Fast Ethernet NIC (embedded, WOL) 0 s 808612290e11b0c7 NC3160 Fast Ethernet NIC (embedded) 0 s 808612290e11b0d7 NC3121 Fast Ethernet NIC (WOL) 0 s 808612290e11b0dd NC3131 Fast Ethernet NIC (dual port) 0 s 808612290e11b0de NC3132 Fast Ethernet Module (dual port) 0 s 808612290e11b0e1 NC3133 Fast Ethernet Module (100-FX) 0 s 808612290e11b134 NC3163 Fast Ethernet NIC (embedded, WOL) 0 s 808612290e11b13c NC3162 Fast Ethernet NIC (embedded) 0 s 808612290e11b144 NC3123 Fast Ethernet NIC (WOL) 0 s 808612290e11b163 NC3134 Fast Ethernet NIC (dual port) 0 s 808612290e11b164 NC3135 Fast Ethernet Upgrade Module (dual port) 0 s 808612290e11b1a4 NC7131 Gigabit Server Adapter 0 s 808612291014005c 82558B Ethernet Pro 10/100 0 s 80861229101401bc 82559 Fast Ethernet LAN On Motherboard 0 s 80861229101401f1 10/100 Ethernet Server Adapter 0 s 80861229101401f2 10/100 Ethernet Server Adapter 0 s 8086122910140207 Ethernet Pro/100 S 0 s 8086122910140232 10/100 Dual Port Server Adapter 0 s 808612291014023a ThinkPad R30 0 s 808612291014105c Netfinity 10/100 0 s 8086122910142205 ThinkPad A22p 0 s 808612291014305c 10/100 EtherJet Management Adapter 0 s 808612291014405c 10/100 EtherJet Adapter with Alert on LAN 0 s 808612291014505c 10/100 EtherJet Secure Management Adapter 0 s 808612291014605c 10/100 EtherJet Secure Management Adapter 0 s 808612291014705c 10/100 Netfinity 10/100 Ethernet Security Adapter 0 s 808612291014805c 10/100 Netfinity 10/100 Ethernet Security Adapter 0 s 808612291028009b PowerEdge 2500/2550 0 s 80861229102800ce PowerEdge 1400 0 s 8086122910338000 PC-9821X-B06 0 s 8086122910338016 PK-UG-X006 0 s 808612291033801f PK-UG-X006 0 s 8086122910338026 PK-UG-X006 0 s 8086122910338063 82559-based Fast Ethernet Adapter 0 s 8086122910338064 82559-based Fast Ethernet Adapter 0 s 80861229103c10c0 NetServer 10/100TX 0 s 80861229103c10c3 NetServer 10/100TX 0 s 80861229103c10ca NetServer 10/100TX 0 s 80861229103c10cb NetServer 10/100TX 0 s 80861229103c10e3 NetServer 10/100TX 0 s 80861229103c10e4 NetServer 10/100TX 0 s 80861229103c1200 NetServer 10/100TX 0 s 8086122910c31100 SmartEther100 SC1100 0 s 8086122910cf1115 8255x-based Ethernet Adapter (10/100) 0 s 8086122910cf1143 8255x-based Ethernet Adapter (10/100) 0 s 8086122911790001 8255x-based Ethernet Adapter (10/100) 0 s 8086122911790002 PCI FastEther LAN on Docker 0 s 8086122911790003 8255x-based Fast Ethernet 0 s 8086122912592560 AT-2560 100 0 s 8086122912592561 AT-2560 100 FX Ethernet Adapter 0 s 8086122912660001 NE10/100 Adapter 0 s 8086122913e91000 6221L-4U 0 s 80861229144d2501 SEM-2000 MiniPCI LAN Adapter 0 s 80861229144d2502 SEM-2100IL MiniPCI LAN Adapter 0 s 8086122916681100 EtherExpress PRO/100B (TX) (MiniPCI Ethernet+Modem) 0 s 808612294c531080 CT8 mainboard 0 s 8086122980860001 EtherExpress PRO/100B (TX) 0 s 8086122980860002 EtherExpress PRO/100B (T4) 0 s 8086122980860003 EtherExpress PRO/10+ 0 s 8086122980860004 EtherExpress PRO/100 WfM 0 s 8086122980860005 82557 10/100 0 s 8086122980860006 82557 10/100 with Wake on LAN 0 s 8086122980860007 82558 10/100 Adapter 0 s 8086122980860008 82558 10/100 with Wake on LAN 0 s 8086122980860009 EtherExpress PRO/100+ 0 s 808612298086000a EtherExpress PRO/100+ Management Adapter 0 s 808612298086000b EtherExpress PRO/100+ 0 s 808612298086000c EtherExpress PRO/100+ Management Adapter 0 s 808612298086000d EtherExpress PRO/100+ Alert On LAN II* Adapter 0 s 808612298086000e EtherExpress PRO/100+ Management Adapter with Alert On LAN* 0 s 808612298086000f EtherExpress PRO/100 Desktop Adapter 0 s 8086122980860010 EtherExpress PRO/100 S Management Adapter 0 s 8086122980860011 EtherExpress PRO/100 S Management Adapter 0 s 8086122980860012 EtherExpress PRO/100 S Advanced Management Adapter (D) 0 s 8086122980860013 EtherExpress PRO/100 S Advanced Management Adapter (E) 0 s 8086122980860030 EtherExpress PRO/100 Management Adapter with Alert On LAN* GC 0 s 8086122980860031 EtherExpress PRO/100 Desktop Adapter 0 s 8086122980860040 EtherExpress PRO/100 S Desktop Adapter 0 s 8086122980860041 EtherExpress PRO/100 S Desktop Adapter 0 s 8086122980860042 EtherExpress PRO/100 Desktop Adapter 0 s 8086122980860050 EtherExpress PRO/100 S Desktop Adapter 0 s 8086122980861009 EtherExpress PRO/100+ Server Adapter 0 s 808612298086100c EtherExpress PRO/100+ Server Adapter (PILA8470B) 0 s 8086122980861012 EtherExpress PRO/100 S Server Adapter (D) 0 s 8086122980861013 EtherExpress PRO/100 S Server Adapter (E) 0 s 8086122980861015 EtherExpress PRO/100 S Dual Port Server Adapter 0 s 8086122980861017 EtherExpress PRO/100+ Dual Port Server Adapter 0 s 8086122980861030 EtherExpress PRO/100+ Management Adapter with Alert On LAN* G Server 0 s 8086122980861040 EtherExpress PRO/100 S Server Adapter 0 s 8086122980861041 EtherExpress PRO/100 S Server Adapter 0 s 8086122980861042 EtherExpress PRO/100 Server Adapter 0 s 8086122980861050 EtherExpress PRO/100 S Server Adapter 0 s 8086122980861051 EtherExpress PRO/100 Server Adapter 0 s 8086122980861052 EtherExpress PRO/100 Server Adapter 0 s 80861229808610f0 EtherExpress PRO/100+ Dual Port Adapter 0 s 8086122980862009 EtherExpress PRO/100 S Mobile Adapter 0 s 808612298086200d EtherExpress PRO/100 Cardbus 0 s 808612298086200e EtherExpress PRO/100 LAN+V90 Cardbus Modem 0 s 808612298086200f EtherExpress PRO/100 SR Mobile Adapter 0 s 8086122980862010 EtherExpress PRO/100 S Mobile Combo Adapter 0 s 8086122980862013 EtherExpress PRO/100 SR Mobile Combo Adapter 0 s 8086122980862016 EtherExpress PRO/100 S Mobile Adapter 0 s 8086122980862017 EtherExpress PRO/100 S Combo Mobile Adapter 0 s 8086122980862018 EtherExpress PRO/100 SR Mobile Adapter 0 s 8086122980862019 EtherExpress PRO/100 SR Combo Mobile Adapter 0 s 8086122980862101 EtherExpress PRO/100 P Mobile Adapter 0 s 8086122980862102 EtherExpress PRO/100 SP Mobile Adapter 0 s 8086122980862103 EtherExpress PRO/100 SP Mobile Adapter 0 s 8086122980862104 EtherExpress PRO/100 SP Mobile Adapter 0 s 8086122980862105 EtherExpress PRO/100 SP Mobile Adapter 0 s 8086122980862106 EtherExpress PRO/100 P Mobile Adapter 0 s 8086122980862107 EtherExpress PRO/100 Network Connection 0 s 8086122980862108 EtherExpress PRO/100 Network Connection 0 s 8086122980862200 EtherExpress PRO/100 P Mobile Combo Adapter 0 s 8086122980862201 EtherExpress PRO/100 P Mobile Combo Adapter 0 s 8086122980862202 EtherExpress PRO/100 SP Mobile Combo Adapter 0 s 8086122980862203 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862204 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862205 EtherExpress PRO/100 SP Mobile Combo Adapter 0 s 8086122980862206 EtherExpress PRO/100 SP Mobile Combo Adapter 0 s 8086122980862207 EtherExpress PRO/100 SP Mobile Combo Adapter 0 s 8086122980862208 EtherExpress PRO/100 P Mobile Combo Adapter 0 s 8086122980862402 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862407 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862408 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862409 EtherExpress PRO/100+ MiniPCI 0 s 808612298086240f EtherExpress PRO/100+ MiniPCI 0 s 8086122980862410 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862411 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862412 EtherExpress PRO/100+ MiniPCI 0 s 8086122980862413 EtherExpress PRO/100+ MiniPCI 0 s 8086122980863000 82559 Fast Ethernet LAN on Motherboard 0 s 8086122980863001 82559 Fast Ethernet LOM with Basic Alert on LAN* 0 s 8086122980863002 82559 Fast Ethernet LOM with Alert on LAN II* 0 s 8086122980863006 EtherExpress PRO/100 S Network Connection 0 s 8086122980863007 EtherExpress PRO/100 S Network Connection 0 s 8086122980863008 EtherExpress PRO/100 Network Connection 0 s 8086122980863010 EtherExpress PRO/100 S Network Connection 0 s 8086122980863011 EtherExpress PRO/100 S Network Connection 0 s 8086122980863012 EtherExpress PRO/100 Network Connection 0 s 8086122980863411 SDS2 Mainboard 0 d 8086122d 430FX - 82437FX TSC [Triton I] 0 d 8086122e 82371FB PIIX ISA [Triton I] 0 d 80861230 82371FB PIIX IDE [Triton I] 0 d 80861231 DSVD Modem 0 d 80861234 430MX - 82371MX Mobile PCI I/O IDE Xcelerator (MPIIX) 0 d 80861235 430MX - 82437MX Mob. System Ctrlr (MTSC) & 82438MX Data Path (MTDP) 0 d 80861237 440FX - 82441FX PMC [Natoma] 0 d 80861239 82371FB PIIX IDE Interface 0 d 8086123b 82380PB PCI to PCI Docking Bridge 0 d 8086123c 82380AB (MISA) Mobile PCI-to-ISA Bridge 0 d 8086123d 683053 Programmable Interrupt Device 0 d 8086123e 82466GX (IHPC) Integrated Hot-Plug Controller 0 in" hidden" mode d 8086123f 82466GX Integrated Hot-Plug Controller (IHPC) 0 d 80861240 82752 (752) AGP Graphics Accelerator 0 d 8086124b 82380FB (MPCI2) Mobile Docking Controller 0 d 80861250 430HX - 82439HX TXC [Triton II] 0 d 80861360 82806AA PCI64 Hub PCI Bridge 0 d 80861361 82806AA PCI64 Hub Controller (HRes) 0 s 8086136180861361 82806AA PCI64 Hub Controller (HRes) 0 s 8086136180868000 82806AA PCI64 Hub Controller (HRes) 0 d 80861460 82870P2 P64H2 Hub PCI Bridge 0 d 80861461 82870P2 P64H2 I/OxAPIC 0 s 8086146115d93480 P4DP6 0 s 808614614c531090 Cx9 / Vx9 mainboard 0 d 80861462 82870P2 P64H2 Hot Plug Controller 0 d 80861960 80960RP [i960RP Microprocessor] 0 s 80861960101e0431 MegaRAID 431 RAID Controller 0 s 80861960101e0438 MegaRAID 438 Ultra2 LVD RAID Controller 0 s 80861960101e0466 MegaRAID 466 Express Plus RAID Controller 0 s 80861960101e0467 MegaRAID 467 Enterprise 1500 RAID Controller 0 s 80861960101e0490 MegaRAID 490 Express 300 RAID Controller 0 s 80861960101e0762 MegaRAID 762 Express RAID Controller 0 s 80861960101e09a0 PowerEdge Expandable RAID Controller 2/SC 0 s 8086196010280467 PowerEdge Expandable RAID Controller 2/DC 0 s 8086196010281111 PowerEdge Expandable RAID Controller 2/SC 0 s 80861960103c03a2 MegaRAID 0 s 80861960103c10c6 MegaRAID 438, HP NetRAID-3Si 0 s 80861960103c10c7 MegaRAID T5, Integrated HP NetRAID 0 s 80861960103c10cc MegaRAID, Integrated HP NetRAID 0 s 80861960103c10cd HP NetRAID-1Si 0 s 80861960105a0000 SuperTrak 0 s 80861960105a2168 SuperTrak Pro 0 s 80861960105a5168 SuperTrak66/100 0 s 8086196011111111 MegaRAID 466, PowerEdge Expandable RAID Controller 2/SC 0 s 8086196011111112 PowerEdge Expandable RAID Controller 2/SC 0 s 80861960113c03a2 MegaRAID 0 s 80861960e4bf1010 CG1-RADIO 0 s 80861960e4bf1020 CU2-QUARTET 0 s 80861960e4bf1040 CU1-CHORUS 0 s 80861960e4bf3100 CX1-BAND 0 d 80861962 80960RM [i960RM Microprocessor] 0 s 80861962105a0000 SuperTrak SX6000 I2O CPU 0 d 80861a21 82840 840 (Carmel) Chipset Host Bridge (Hub A) 0 d 80861a23 82840 840 (Carmel) Chipset AGP Bridge 0 d 80861a24 82840 840 (Carmel) Chipset PCI Bridge (Hub B) 0 d 80861a30 82845 845 (Brookdale) Chipset Host Bridge 0 s 80861a301028010e Optiplex GX240 0 d 80861a31 82845 845 (Brookdale) Chipset AGP Bridge 0 d 80862410 82801AA ISA Bridge (LPC) 0 d 80862411 82801AA IDE 0 d 80862412 82801AA USB 0 d 80862413 82801AA SMBus 0 d 80862415 82801AA AC'97 Audio 0 s 8086241510280095 Precision Workstation 220 Integrated Digital Audio 0 s 8086241511d40040 SoundMAX Integrated Digital Audio 0 s 8086241511d40048 SoundMAX Integrated Digital Audio 0 s 8086241511d45340 SoundMAX Integrated Digital Audio 0 d 80862416 82801AA AC'97 Modem 0 d 80862418 82801AA PCI Bridge 0 d 80862420 82801AB ISA Bridge (LPC) 0 d 80862421 82801AB IDE 0 d 80862422 82801AB USB 0 d 80862423 82801AB SMBus 0 d 80862425 82801AB AC'97 Audio 0 s 8086242511d40040 SoundMAX Integrated Digital Audio 0 s 8086242511d40048 SoundMAX Integrated Digital Audio 0 d 80862426 82801AB AC'97 Modem 0 d 80862428 82801AB PCI Bridge 0 d 80862440 82801BA ISA Bridge (LPC) 0 d 80862442 82801BA/BAM USB (Hub #1) 0 s 80862442101401c6 Netvista A40/A40p 0 s 8086244210251016 Travelmate 612 TX 0 s 808624421028010e Optiplex GX240 0 s 8086244210438027 TUSL2-C Mainboard 0 s 80862442104d80df Vaio PCG-FX403 0 s 80862442147b0507 TH7II-RAID 0 s 8086244280864532 D815EEA2 mainboard 0 s 8086244280864557 D815EGEW Mainboard 0 d 80862443 82801BA/BAM SMBus 0 s 80862443101401c6 Netvista A40/A40p 0 s 8086244310251016 Travelmate 612 TX 0 s 808624431028010e Optiplex GX240 0 s 8086244310438027 TUSL2-C Mainboard 0 s 80862443104d80df Vaio PCG-FX403 0 s 80862443147b0507 TH7II-RAID 0 s 8086244380864532 D815EEA2 mainboard 0 s 8086244380864557 D815EGEW Mainboard 0 d 80862444 82801BA/BAM USB (Hub #2) 0 s 8086244410251016 Travelmate 612 TX 0 s 808624441028010e Optiplex GX240 0 s 8086244410438027 TUSL2-C Mainboard 0 s 80862444104d80df Vaio PCG-FX403 0 s 80862444147b0507 TH7II-RAID 0 s 8086244480864532 D815EEA2 mainboard 0 d 80862445 82801BA/BAM AC'97 Audio 0 s 80862445101401c6 Netvista A40/A40p 0 s 8086244510251016 Travelmate 612 TX 0 s 80862445104d80df Vaio PCG-FX403 0 s 8086244514623370 STAC9721 AC 0 s 80862445147b0507 TH7II-RAID 0 s 8086244580864557 D815EGEW Mainboard 0 d 80862446 82801BA/BAM AC'97 Modem 0 s 8086244610251016 Travelmate 612 TX 0 s 80862446104d80df Vaio PCG-FX403 0 d 80862448 82801 Mobile PCI Bridge 0 d 80862449 82801BA/BAM/CA/CAM Ethernet Controller 0 s 808624490e110012 EtherExpress PRO/100 VM 0 s 808624490e110091 EtherExpress PRO/100 VE 0 s 80862449101401ce EtherExpress PRO/100 VE 0 s 80862449101401dc EtherExpress PRO/100 VE 0 s 80862449101401eb EtherExpress PRO/100 VE 0 s 80862449101401ec EtherExpress PRO/100 VE 0 s 8086244910140202 EtherExpress PRO/100 VE 0 s 8086244910140205 EtherExpress PRO/100 VE 0 s 8086244910140217 EtherExpress PRO/100 VE 0 s 8086244910140234 EtherExpress PRO/100 VE 0 s 808624491014023d EtherExpress PRO/100 VE 0 s 8086244910140244 EtherExpress PRO/100 VE 0 s 8086244910140245 EtherExpress PRO/100 VE 0 s 8086244910140265 PRO/100 VE Desktop Connection 0 s 8086244910140267 PRO/100 VE Desktop Connection 0 s 808624491014026a PRO/100 VE Desktop Connection 0 s 80862449109f315d EtherExpress PRO/100 VE 0 s 80862449109f3181 EtherExpress PRO/100 VE 0 s 808624491179ff01 PRO/100 VE Network Connection 0 s 8086244911867801 EtherExpress PRO/100 VE 0 s 80862449144d2602 HomePNA 1M CNR 0 s 8086244980863010 EtherExpress PRO/100 VE 0 s 8086244980863011 EtherExpress PRO/100 VM 0 s 8086244980863012 82562EH based Phoneline 0 s 8086244980863013 EtherExpress PRO/100 VE 0 s 8086244980863014 EtherExpress PRO/100 VM 0 s 8086244980863015 82562EH based Phoneline 0 s 8086244980863016 EtherExpress PRO/100 P Mobile Combo 0 s 8086244980863017 EtherExpress PRO/100 P Mobile 0 s 8086244980863018 EtherExpress PRO/100 0 d 8086244a 82801BAM IDE U100 0 s 8086244a10251016 Travelmate 612TX 0 s 8086244a104d80df Vaio PCG-FX403 0 d 8086244b 82801BA IDE U100 0 s 8086244b101401c6 Netvista A40/A40p 0 s 8086244b1028010e Optiplex GX240 0 s 8086244b10438027 TUSL2-C Mainboard 0 s 8086244b147b0507 TH7II-RAID 0 s 8086244b80864532 D815EEA2 mainboard 0 s 8086244b80864557 D815EGEW Mainboard 0 d 8086244c 82801BAM ISA Bridge (LPC) 0 d 8086244e 82801 PCI Bridge 0 s 8086244e10140267 NetVista A30p 0 d 80862450 82801E ISA Bridge (LPC) 0 d 80862452 82801E USB 0 d 80862453 82801E SMBus 0 d 80862459 82801E Ethernet Controller 0 0 d 8086245b 82801E IDE U100 0 d 8086245d 82801E Ethernet Controller 1 0 d 8086245e 82801E PCI Bridge 0 d 80862480 82801CA LPC Interface Controller 0 d 80862482 82801CA/CAM USB (Hub #1) 0 s 8086248210140220 ThinkPad A/T/X Series 0 s 80862482104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 8086248215d93480 P4DP6 0 s 8086248280861958 vpr Matrix 170B4 0 s 8086248280863424 SE7501HG2 Mainboard 0 s 8086248280864541 Latitude C640 0 d 80862483 82801CA/CAM SMBus Controller 0 s 8086248310140220 ThinkPad A/T/X Series 0 s 80862483104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 8086248315d93480 P4DP6 0 s 8086248380861958 vpr Matrix 170B4 0 d 80862484 82801CA/CAM USB (Hub #2) 0 s 8086248410140220 ThinkPad A/T/X Series 0 s 80862484104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 8086248415d93480 P4DP6 0 s 8086248480861958 vpr Matrix 170B4 0 d 80862485 82801CA/CAM AC'97 Audio Controller 0 s 8086248510135959 Crystal WMD Audio Codec 0 s 8086248510140222 ThinkPad T23 (2647-4MG) or A30/A30p (2652/2653) 0 s 8086248510140508 ThinkPad T30 0 s 808624851014051c ThinkPad A/T/X Series 0 s 80862485104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 80862485144dc006 vpr Matrix 170B4 0 d 80862486 82801CA/CAM AC'97 Modem Controller 0 s 8086248610140223 ThinkPad A/T/X Series 0 s 8086248610140503 ThinkPad R31 2656BBG 0 s 808624861014051a ThinkPad A/T/X Series 0 s 80862486101f1025 Acer 620 Series 0 s 80862486104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 8086248611790001 Toshiba Satellite 1110 Z15 internal Modem 0 s 80862486134d4c21 Dell Inspiron 2100 internal modem 0 s 80862486144d2115 vpr Matrix 170B4 internal modem 0 s 8086248614f15421 MD56ORD V.92 MDC Modem 0 d 80862487 82801CA/CAM USB (Hub #3) 0 s 8086248710140220 ThinkPad A/T/X Series 0 s 80862487104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 8086248715d93480 P4DP6 0 s 8086248780861958 vpr Matrix 170B4 0 d 8086248a 82801CAM IDE U100 0 s 8086248a10140220 ThinkPad A/T/X Series 0 s 8086248a104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 s 8086248a80861958 vpr Matrix 170B4 0 s 8086248a80864541 Latitude C640 0 d 8086248b 82801CA Ultra ATA Storage Controller 0 s 8086248b15d93480 P4DP6 0 d 8086248c 82801CAM ISA Bridge (LPC) 0 d 808624c0 82801DB/DBL (ICH4/ICH4-L) LPC Interface Bridge 0 s 808624c010140267 NetVista A30p 0 s 808624c014625800 845PE Max (MS-6580) 0 d 808624c1 82801DBL (ICH4-L) IDE Controller 0 d 808624c2 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #1 0 s 808624c210140267 NetVista A30p 0 s 808624c21025005a TravelMate 290 0 s 808624c210280126 Optiplex GX260 0 s 808624c210280163 Latitude D505 0 s 808624c2103c0890 NC6000 laptop 0 s 808624c210718160 MIM2000 0 s 808624c214625800 845PE Max (MS-6580) 0 s 808624c215092990 Averatec 5110H laptop 0 s 808624c24c531090 Cx9 / Vx9 mainboard 0 d 808624c3 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) SMBus Controller 0 s 808624c310140267 NetVista A30p 0 s 808624c31025005a TravelMate 290 0 s 808624c310280126 Optiplex GX260 0 s 808624c3103c0890 NC6000 laptop 0 s 808624c310718160 MIM2000 0 s 808624c3145824c2 GA-8PE667 Ultra 0 s 808624c314625800 845PE Max (MS-6580) 0 s 808624c34c531090 Cx9 / Vx9 mainboard 0 d 808624c4 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #2 0 s 808624c410140267 NetVista A30p 0 s 808624c41025005a TravelMate 290 0 s 808624c410280126 Optiplex GX260 0 s 808624c410280163 Latitude D505 0 s 808624c4103c0890 NC6000 laptop 0 s 808624c410718160 MIM2000 0 s 808624c414625800 845PE Max (MS-6580) 0 s 808624c415092990 Averatec 5110H 0 s 808624c44c531090 Cx9 / Vx9 mainboard 0 d 808624c5 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Audio Controller 0 s 808624c50e1100b8 Analog Devices Inc. codec [SoundMAX] 0 s 808624c510140267 NetVista A30p 0 s 808624c51025005a TravelMate 290 0 s 808624c510280163 Latitude D505 0 s 808624c5103c0890 NC6000 laptop 0 s 808624c510718160 MIM2000 0 s 808624c51458a002 GA-8PE667 Ultra 0 s 808624c514625800 845PE Max (MS-6580) 0 d 808624c6 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) AC'97 Modem Controller 0 s 808624c61025005a TravelMate 290 0 s 808624c6103c0890 NC6000 laptop 0 s 808624c610718160 MIM2000 0 d 808624c7 82801DB/DBL/DBM (ICH4/ICH4-L/ICH4-M) USB UHCI Controller #3 0 s 808624c710140267 NetVista A30p 0 s 808624c71025005a TravelMate 290 0 s 808624c710280126 Optiplex GX260 0 s 808624c710280163 Latitude D505 0 s 808624c7103c0890 NC6000 laptop 0 s 808624c710718160 MIM2000 0 s 808624c714625800 845PE Max (MS-6580) 0 s 808624c715092990 Averatec 5110H 0 s 808624c74c531090 Cx9 / Vx9 mainboard 0 d 808624ca 82801DBM (ICH4-M) IDE Controller 0 s 808624ca1025005a TravelMate 290 0 s 808624ca10280163 Latitude D505 0 s 808624ca103c0890 NC6000 laptop 0 s 808624ca10718160 MIM2000 0 d 808624cb 82801DB (ICH4) IDE Controller 0 s 808624cb10140267 NetVista A30p 0 s 808624cb10280126 Optiplex GX260 0 s 808624cb145824c2 GA-8PE667 Ultra 0 s 808624cb14625800 845PE Max (MS-6580) 0 s 808624cb4c531090 Cx9 / Vx9 mainboard 0 d 808624cc 82801DBM (ICH4-M) LPC Interface Bridge 0 d 808624cd 82801DB/DBM (ICH4/ICH4-M) USB2 EHCI Controller 0 s 808624cd10140267 NetVista A30p 0 s 808624cd1025005a TravelMate 290 0 s 808624cd10280126 Optiplex GX260 0 s 808624cd10280163 Latitude D505 0 s 808624cd103c0890 NC6000 laptop 0 s 808624cd10718160 MIM2000 0 s 808624cd14623981 845PE Max (MS-6580) 0 s 808624cd15091968 Averatec 5110H 0 s 808624cd4c531090 Cx9 / Vx9 mainboard 0 d 808624d0 82801EB/ER (ICH5/ICH5R) LPC Interface Bridge 0 d 808624d1 82801EB (ICH5) SATA Controller 0 s 808624d1103c12bc d530 CMT (DG746A) 0 s 808624d1145824d1 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 808624d114627280 865PE Neo2 (MS-6728) 0 s 808624d180863427 S875WP1-E mainboard 0 s 808624d18086524c D865PERL mainboard 0 d 808624d2 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #1 0 s 808624d2103c12bc d530 CMT (DG746A) 0 s 808624d2104380a6 P4P800 Mainboard 0 s 808624d2145824d2 GA-8KNXP motherboard (875P) 0 s 808624d214627280 865PE Neo2 (MS-6728) 0 s 808624d280863427 S875WP1-E mainboard 0 s 808624d28086524c D865PERL mainboard 0 d 808624d3 82801EB/ER (ICH5/ICH5R) SMBus Controller 0 s 808624d3104380a6 P4P800 Mainboard 0 s 808624d3145824d2 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 808624d314627280 865PE Neo2 (MS-6728) 0 s 808624d380863427 S875WP1-E mainboard 0 s 808624d38086524c D865PERL mainboard 0 d 808624d4 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #2 0 s 808624d4103c12bc d530 CMT (DG746A) 0 s 808624d4104380a6 P4P800 Mainboard 0 s 808624d4145824d2 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 808624d414627280 865PE Neo2 (MS-6728) 0 s 808624d480863427 S875WP1-E mainboard 0 s 808624d48086524c D865PERL mainboard 0 d 808624d5 82801EB/ER (ICH5/ICH5R) AC'97 Audio Controller 0 s 808624d5103c12bc Analog Devices codec [SoundMAX Integrated Digital Audio] 0 s 808624d5104380f3 P4P800 Mainboard 0 s 808624d51458a002 GA-8KNXP motherboard (875P) 0 s 808624d514627280 865PE Neo2 (MS-6728) 0 s 808624d58086a000 D865PERL mainboard 0 d 808624d6 82801EB/ER (ICH5/ICH5R) AC'97 Modem Controller 0 d 808624d7 82801EB/ER (ICH5/ICH5R) USB UHCI #3 0 s 808624d7103c12bc d530 CMT (DG746A) 0 s 808624d7104380a6 P4P800 Mainboard 0 s 808624d7145824d2 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 808624d714627280 865PE Neo2 (MS-6728) 0 s 808624d780863427 S875WP1-E mainboard 0 s 808624d78086524c D865PERL mainboard 0 d 808624db 82801EB/ER (ICH5/ICH5R) IDE Controller 0 s 808624db103c12bc d530 CMT (DG746A) 0 s 808624db104380a6 P4P800 Mainboard 0 s 808624db145824d2 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 808624db14627280 865PE Neo2 (MS-6728) 0 s 808624db14627580 MSI 875P 0 s 808624db80863427 S875WP1-E mainboard 0 s 808624db8086524c D865PERL mainboard 0 d 808624dc 82801EB (ICH5) LPC Interface Bridge 0 d 808624dd 82801EB/ER (ICH5/ICH5R) USB2 EHCI Controller 0 s 808624dd103c12bc d530 CMT (DG746A) 0 s 808624dd104380a6 P4P800 Mainboard 0 s 808624dd14585006 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 808624dd14627280 865PE Neo2 (MS-6728) 0 s 808624dd80863427 S875WP1-E mainboard 0 s 808624dd8086524c D865PERL mainboard 0 d 808624de 82801EB/ER (ICH5/ICH5R) USB UHCI Controller #4 0 s 808624de104380a6 P4P800 Mainboard 0 s 808624de145824d2 GA-8IPE1000 Pro2 motherboard (865PE) 0 s 808624de14627280 865PE Neo2 (MS-6728) 0 s 808624de80863427 S875WP1-E mainboard 0 s 808624de8086524c D865PERL mainboard 0 d 808624df 82801ER (ICH5R) SATA Controller 0 d 80862500 82820 820 (Camino) Chipset Host Bridge (MCH) 0 s 8086250010280095 Precision Workstation 220 Chipset 0 s 808625001043801c P3C-2000 system chipset 0 d 80862501 82820 820 (Camino) Chipset Host Bridge (MCH) 0 s 808625011043801c P3C-2000 system chipset 0 d 8086250b 82820 820 (Camino) Chipset Host Bridge 0 d 8086250f 82820 820 (Camino) Chipset AGP Bridge 0 d 80862520 82805AA MTH Memory Translator Hub 0 d 80862521 82804AA MRH-S Memory Repeater Hub for SDRAM 0 d 80862530 82850 850 (Tehama) Chipset Host Bridge (MCH) 0 s 80862530147b0507 TH7II-RAID 0 d 80862531 82860 860 (Wombat) Chipset Host Bridge (MCH) 0 d 80862532 82850 850 (Tehama) Chipset AGP Bridge 0 d 80862533 82860 860 (Wombat) Chipset AGP Bridge 0 d 80862534 82860 860 (Wombat) Chipset PCI Bridge 0 d 80862540 E7500 Memory Controller Hub 0 s 8086254015d93480 P4DP6 0 d 80862541 E7500/E7501 Host RASUM Controller 0 s 8086254115d93480 P4DP6 0 s 808625414c531090 Cx9 / Vx9 mainboard 0 s 8086254180863424 SE7501HG2 Mainboard 0 d 80862543 E7500/E7501 Hub Interface B PCI-to-PCI Bridge 0 d 80862544 E7500/E7501 Hub Interface B RASUM Controller 0 s 808625444c531090 Cx9 / Vx9 mainboard 0 d 80862545 E7500/E7501 Hub Interface C PCI-to-PCI Bridge 0 d 80862546 E7500/E7501 Hub Interface C RASUM Controller 0 d 80862547 E7500/E7501 Hub Interface D PCI-to-PCI Bridge 0 d 80862548 E7500/E7501 Hub Interface D RASUM Controller 0 d 8086254c E7501 Memory Controller Hub 0 s 8086254c4c531090 Cx9 / Vx9 mainboard 0 s 8086254c80863424 SE7501HG2 Mainboard 0 d 80862550 E7505 Memory Controller Hub 0 d 80862551 E7505/E7205 Series RAS Controller 0 d 80862552 E7505/E7205 PCI-to-AGP Bridge 0 d 80862553 E7505 Hub Interface B PCI-to-PCI Bridge 0 d 80862554 E7505 Hub Interface B PCI-to-PCI Bridge RAS Controller 0 d 8086255d E7205 Memory Controller Hub 0 d 80862560 82845G/GL[Brookdale-G]/GE/PE DRAM Controller/Host-Hub Interface 0 s 8086256010280126 Optiplex GX260 0 s 8086256014582560 GA-8PE667 Ultra 0 s 8086256014625800 845PE Max (MS-6580) 0 d 80862561 82845G/GL[Brookdale-G]/GE/PE Host-to-AGP Bridge 0 d 80862562 82845G/GL[Brookdale-G]/GE Chipset Integrated Graphics Device 0 s 8086256210140267 NetVista A30p 0 d 80862570 82865G/PE/P DRAM Controller/Host-Hub Interface 0 s 80862570104380f2 P4P800 Mainboard 0 s 8086257014582570 GA-8IPE1000 Pro2 motherboard (865PE) 0 d 80862571 82865G/PE/P PCI to AGP Controller 0 d 80862572 82865G Integrated Graphics Device 0 d 80862573 82865G/PE/P PCI to CSA Bridge 0 d 80862576 82865G/PE/P Processor to I/O Memory Interface 0 d 80862578 82875P/E7210 Memory Controller Hub 0 s 8086257814582578 GA-8KNXP motherboard (875P) 0 s 8086257814627580 MS-6758 (875P Neo) 0 s 8086257815d94580 Super Micro Computer Inc. P4SCE 0 Motherboard P4SCE d 80862579 82875P Processor to AGP Controller 0 d 8086257b 82875P/E7210 Processor to PCI to CSA Bridge 0 d 8086257e 82875P/E7210 Processor to I/O Memory Interface 0 d 80862580 915G/P/GV Processor to I/O Controller 0 d 80862581 915G/P/GV PCI Express Root Port 0 d 80862582 82915G Express Chipset Family Graphics Controller 0 s 8086258210281079 Optiplex GX280 0 d 80862584 925X/XE Memory Controller Hub 0 d 80862585 925X/XE PCI Express Root Port 0 d 80862588 E7220/E7221 Memory Controller Hub 0 d 80862589 E7220/E7221 PCI Express Root Port 0 d 8086258a E7221 Integrated Graphics Controller 0 d 80862590 Mobile Memory Controller Hub 0 d 80862591 Mobile Memory Controller Hub PCI Express Port 0 d 80862592 Mobile Graphics Controller 0 d 808625a1 6300ESB LPC Interface Controller 0 d 808625a2 6300ESB PATA Storage Controller 0 s 808625a24c5310b0 CL9 mainboard 0 d 808625a3 6300ESB SATA Storage Controller 0 s 808625a34c5310b0 CL9 mainboard 0 d 808625a4 6300ESB SMBus Controller 0 s 808625a44c5310b0 CL9 mainboard 0 d 808625a6 6300ESB AC'97 Audio Controller 0 s 808625a64c5310b0 CL9 mainboard 0 d 808625a7 6300ESB AC'97 Modem Controller 0 d 808625a9 6300ESB USB Universal Host Controller 0 s 808625a94c5310b0 CL9 mainboard 0 d 808625aa 6300ESB USB Universal Host Controller 0 s 808625aa4c5310b0 CL9 mainboard 0 d 808625ab 6300ESB Watchdog Timer 0 s 808625ab4c5310b0 CL9 mainboard 0 d 808625ac 6300ESB I/O Advanced Programmable Interrupt Controller 0 s 808625ac4c5310b0 CL9 mainboard 0 d 808625ad 6300ESB USB2 Enhanced Host Controller 0 d 808625ae 6300ESB 64-bit PCI-X Bridge 0 d 808625b0 6300ESB SATA RAID Controller 0 d 80862600 Server Hub Interface 0 d 80862601 Server Hub PCI Express x4 Port D 0 d 80862602 Server Hub PCI Express x4 Port C0 0 d 80862603 Server Hub PCI Express x4 Port C1 0 d 80862604 Server Hub PCI Express x4 Port B0 0 d 80862605 Server Hub PCI Express x4 Port B1 0 d 80862606 Server Hub PCI Express x4 Port A0 0 d 80862607 Server Hub PCI Express x4 Port A1 0 d 80862608 Server Hub PCI Express x8 Port C 0 d 80862609 Server Hub PCI Express x8 Port B 0 d 8086260a Server Hub PCI Express x8 Port A 0 d 8086260c Server Hub IMI Registers 0 d 80862610 Server Hub System Bus, Boot, and Interrupt Registers 0 d 80862611 Server Hub Address Mapping Registers 0 d 80862612 Server Hub RAS Registers 0 d 80862613 Server Hub Reserved Registers 0 d 80862614 Server Hub Reserved Registers 0 d 80862615 Server Hub Miscellaneous Registers 0 d 80862617 Server Hub Reserved Registers 0 d 80862618 Server Hub Reserved Registers 0 d 80862619 Server Hub Reserved Registers 0 d 8086261a Server Hub Reserved Registers 0 d 8086261b Server Hub Reserved Registers 0 d 8086261c Server Hub Reserved Registers 0 d 8086261d Server Hub Reserved Registers 0 d 8086261e Server Hub Reserved Registers 0 d 80862620 External Memory Bridge 0 d 80862621 External Memory Bridge Control Registers 0 d 80862622 External Memory Bridge Memory Interleaving Registers 0 d 80862623 External Memory Bridge DDR Initialization and Calibration 0 d 80862624 External Memory Bridge Reserved Registers 0 d 80862625 External Memory Bridge Reserved Registers 0 d 80862626 External Memory Bridge Reserved Registers 0 d 80862627 External Memory Bridge Reserved Registers 0 d 80862640 82801FB/FR (ICH6/ICH6R) LPC Interface Bridge 0 d 80862641 82801FBM (ICH6M) LPC Interface Bridge 0 d 80862642 82801FW/FRW (ICH6W/ICH6RW) LPC Interface Bridge 0 d 80862651 82801FB/FW (ICH6/ICH6W) SATA Controller 0 s 8086265110280179 Optiplex GX280 0 d 80862652 82801FR/FRW (ICH6R/ICH6RW) SATA Controller 0 d 80862653 82801FBM (ICH6M) SATA Controller 0 d 80862658 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #1 0 s 8086265810280179 Optiplex GX280 0 d 80862659 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #2 0 s 8086265910280179 Optiplex GX280 0 d 8086265a 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #3 0 s 8086265a10280179 Optiplex GX280 0 d 8086265b 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB UHCI #4 0 s 8086265b10280179 Optiplex GX280 0 d 8086265c 82801FB/FBM/FR/FW/FRW (ICH6 Family) USB2 EHCI Controller 0 s 8086265c10280179 Optiplex GX280 0 d 80862660 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 1 0 d 80862662 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 2 0 d 80862664 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 3 0 d 80862666 82801FB/FBM/FR/FW/FRW (ICH6 Family) PCI Express Port 4 0 d 80862668 82801FB/FBM/FR/FW/FRW (ICH6 Family) High Definition Audio Controller 0 d 8086266a 82801FB/FBM/FR/FW/FRW (ICH6 Family) SMBus Controller 0 s 8086266a10280179 Optiplex GX280 0 d 8086266c 82801FB/FBM/FR/FW/FRW (ICH6 Family) LAN Controller 0 d 8086266d 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Modem Controller 0 d 8086266e 82801FB/FBM/FR/FW/FRW (ICH6 Family) AC'97 Audio Controller 0 s 8086266e10280179 Optiplex GX280 0 d 8086266f 82801FB/FBM/FR/FW/FRW (ICH6 Family) IDE Controller 0 d 80862782 82915G Express Chipset Family Graphics Controller 0 d 80862792 Mobile Graphics Controller 0 d 80863092 Integrated RAID 0 d 80863200 GD31244 PCI-X SATA HBA 0 d 80863340 82855PM Processor to I/O Controller 0 s 808633401025005a TravelMate 290 0 s 80863340103c0890 NC6000 laptop 0 d 80863341 82855PM Processor to AGP Controller 0 d 80863575 82830 830 Chipset Host Bridge 0 s 808635751014021d ThinkPad A/T/X Series 0 s 80863575104d80e7 VAIO PCG-GR214EP/GR214MP/GR215MP/GR314MP/GR315MP 0 d 80863576 82830 830 Chipset AGP Bridge 0 d 80863577 82830 CGC [Chipset Graphics Controller] 0 s 8086357710140513 ThinkPad A/T/X Series 0 d 80863578 82830 830 Chipset Host Bridge 0 d 80863580 82852/82855 GM/GME/PM/GMV Processor to I/O Controller 0 s 8086358010280163 Latitude D505 0 s 808635804c5310b0 CL9 mainboard 0 d 80863581 82852/82855 GM/GME/PM/GMV Processor to AGP Controller 0 d 80863582 82852/855GM Integrated Graphics Device 0 s 8086358210280163 Latitude D505 0 s 808635824c5310b0 CL9 mainboard 0 d 80863584 82852/82855 GM/GME/PM/GMV Processor to I/O Controller 0 s 8086358410280163 Latitude D505 0 s 808635844c5310b0 CL9 mainboard 0 d 80863585 82852/82855 GM/GME/PM/GMV Processor to I/O Controller 0 s 8086358510280163 Latitude D505 0 s 808635854c5310b0 CL9 mainboard 0 d 80863590 E7520 Memory Controller Hub 0 d 80863591 E7525/E7520 Error Reporting Registers 0 d 80863592 E7320 Memory Controller Hub 0 d 80863593 E7320 Error Reporting Registers 0 d 80863594 E7520 DMA Controller 0 d 80863595 E7525/E7520/E7320 PCI Express Port A 0 d 80863596 E7525/E7520/E7320 PCI Express Port A1 0 d 80863597 E7525/E7520 PCI Express Port B 0 d 80863598 E7520 PCI Express Port B1 0 d 80863599 E7520 PCI Express Port C 0 d 8086359a E7520 PCI Express Port C1 0 d 8086359b E7525/E7520/E7320 Extended Configuration Registers 0 d 8086359e E7525 Memory Controller Hub 0 d 80864220 PRO/Wireless 2200BG 0 d 80864223 PRO/Wireless 2915ABG MiniPCI Adapter 0 d 80865200 EtherExpress PRO/100 Intelligent Server 0 d 80865201 EtherExpress PRO/100 Intelligent Server 0 s 8086520180860001 EtherExpress PRO/100 Server Ethernet Adapter 0 d 8086530d 80310 IOP [IO Processor] 0 d 80867000 82371SB PIIX3 ISA [Natoma/Triton II] 0 d 80867010 82371SB PIIX3 IDE [Natoma/Triton II] 0 d 80867020 82371SB PIIX3 USB [Natoma/Triton II] 0 d 80867030 430VX - 82437VX TVX [Triton VX] 0 d 80867050 Intel Intercast Video Capture Card 0 d 80867100 430TX - 82439TX MTXC 0 d 80867110 82371AB/EB/MB PIIX4 ISA 0 s 8086711015ad1976 virtualHW v3 0 d 80867111 82371AB/EB/MB PIIX4 IDE 0 s 8086711115ad1976 virtualHW v3 0 d 80867112 82371AB/EB/MB PIIX4 USB 0 s 8086711215ad1976 virtualHW v3 0 d 80867113 82371AB/EB/MB PIIX4 ACPI 0 s 8086711315ad1976 virtualHW v3 0 d 80867120 82810 GMCH [Graphics Memory Controller Hub] 0 s 808671204c531040 CL7 mainboard 0 s 808671204c531060 PC7 mainboard 0 d 80867121 82810 CGC [Chipset Graphics Controller] 0 s 808671214c531040 CL7 mainboard 0 s 808671214c531060 PC7 mainboard 0 s 8086712180864341 Cayman (CA810) Mainboard 0 d 80867122 82810 DC-100 GMCH [Graphics Memory Controller Hub] 0 d 80867123 82810 DC-100 CGC [Chipset Graphics Controller] 0 d 80867124 82810E DC-133 GMCH [Graphics Memory Controller Hub] 0 d 80867125 82810E DC-133 CGC [Chipset Graphics Controller] 0 d 80867126 82810 DC-133 System and Graphics Controller 0 d 80867128 82810-M DC-100 System and Graphics Controller 0 d 8086712a 82810-M DC-133 System and Graphics Controller 0 d 80867180 440LX/EX - 82443LX/EX Host bridge 0 d 80867181 440LX/EX - 82443LX/EX AGP bridge 0 d 80867190 440BX/ZX/DX - 82443BX/ZX/DX Host bridge 0 s 808671900e110500 Armada 1750 Laptop System Chipset 0 s 808671900e11b110 Armada M700/E500 0 s 8086719011790001 Toshiba Tecra 8100 Laptop System Chipset 0 s 8086719015ad1976 virtualHW v3 0 s 808671904c531050 CT7 mainboard 0 s 808671904c531051 CE7 mainboard 0 d 80867191 440BX/ZX/DX - 82443BX/ZX/DX AGP bridge 0 d 80867192 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) 0 s 808671920e110460 Armada 1700 Laptop System Chipset 0 s 808671924c531000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard 0 d 80867194 82440MX Host Bridge 0 s 8086719410330000 Versa Note Vxi 0 s 808671944c5310a0 CA3/CR3 mainboard 0 d 80867195 82440MX AC'97 Audio Controller 0 s 80867195103380cc Versa Note VXi 0 s 8086719510cf1099 QSound_SigmaTel Stac97 PCI Audio 0 s 8086719511d40040 SoundMAX Integrated Digital Audio 0 s 8086719511d40048 SoundMAX Integrated Digital Audio 0 d 80867196 82440MX AC'97 Modem Controller 0 d 80867198 82440MX ISA Bridge 0 d 80867199 82440MX EIDE Controller 0 d 8086719a 82440MX USB Universal Host Controller 0 d 8086719b 82440MX Power Management Controller 0 d 808671a0 440GX - 82443GX Host bridge 0 s 808671a04c531050 CT7 mainboard 0 s 808671a04c531051 CE7 mainboard 0 d 808671a1 440GX - 82443GX AGP bridge 0 d 808671a2 440GX - 82443GX Host bridge (AGP disabled) 0 s 808671a24c531000 CC7/CR7/CP7/VC7/VP7/VR7 mainboard 0 d 80867600 82372FB PIIX5 ISA 0 d 80867601 82372FB PIIX5 IDE 0 d 80867602 82372FB PIIX5 USB 0 d 80867603 82372FB PIIX5 SMBus 0 d 80867800 82740 (i740) AGP Graphics Accelerator 0 s 80867800003d0008 Starfighter AGP 0 s 80867800003d000b Starfighter AGP 0 s 8086780010920100 Stealth II G460 0 s 8086780010b4201a Lightspeed 740 0 s 8086780010b4202f Lightspeed 740 0 s 8086780080860000 Terminator 2x/i 0 s 8086780080860100 Intel740 Graphics Accelerator 0 d 808684c4 450KX/GX [Orion] - 82454KX/GX PCI bridge 0 d 808684c5 450KX/GX [Orion] - 82453KX/GX Memory controller 0 d 808684ca 450NX - 82451NX Memory & I/O Controller 0 d 808684cb 450NX - 82454NX/84460GX PCI Expander Bridge 0 d 808684e0 460GX - 84460GX System Address Controller (SAC) 0 d 808684e1 460GX - 84460GX System Data Controller (SDC) 0 d 808684e2 460GX - 84460GX AGP Bridge (GXB function 2) 0 d 808684e3 460GX - 84460GX Memory Address Controller (MAC) 0 d 808684e4 460GX - 84460GX Memory Data Controller (MDC) 0 d 808684e6 460GX - 82466GX Wide and fast PCI eXpander Bridge (WXB) 0 d 808684ea 460GX - 84460GX AGP Bridge (GXB function 1) 0 d 80868500 IXP4XX - Intel Network Processor family. IXP420, IXP421, IXP422, IXP425 and IXC1100 0 d 80869000 IXP2000 Family Network Processor 0 d 80869001 IXP2400 Network Processor 0 d 80869004 IXP2800 Network Processor 0 d 80869621 Integrated RAID 0 d 80869622 Integrated RAID 0 d 80869641 Integrated RAID 0 d 808696a1 Integrated RAID 0 d 8086a01f PRO/10GbE LR Server Adapter 0 retail verson d 8086a11f PRO/10GbE LR Server Adapter 0 OEM version d 8086b152 21152 PCI-to-PCI Bridge 0 d 8086b154 21154 PCI-to-PCI Bridge 0 observed, and documented in Intel revision note; new mask of 1011:0026 d 8086b555 21555 Non transparent PCI-to-PCI Bridge 0 s 8086b55512d9000a PCI VoIP Gateway 0 s 8086b5554c531050 CT7 mainboard 0 s 8086b5554c531051 CE7 mainboard 0 s 8086b555e4bf1000 CC8-1-BLUES 0 d 8086ffff 450NX/GX [Orion] - 82453KX/GX Memory controller [BUG] 0 v 8401 TRENDware International Inc. 0 v 8800 Trigem Computer Inc. 0 d 88002008 Video assistent component 0 v 8866 T-Square Design Inc. 0 v 8888 Silicon Magic 0 v 8c4a Winbond 0 8c4a is not Winbond but there is a board misprogrammed d 8c4a1980 W89C940 misprogrammed [ne2k] 0 v 8e0e Computone Corporation 0 v 8e2e KTI 0 d 8e2e3000 ET32P2 0 v 9004 Adaptec 0 d 90040078 AHA-2940U_CN 0 d 90041078 AIC-7810 0 d 90041160 AIC-1160 [Family Fibre Channel Adapter] 0 d 90042178 AIC-7821 0 d 90043860 AHA-2930CU 0 d 90043b78 AHA-4844W/4844UW 0 d 90045075 AIC-755x 0 d 90045078 AHA-7850 0 s 9004507890047850 AHA-2904/Integrated AIC-7850 0 d 90045175 AIC-755x 0 d 90045178 AIC-7851 0 d 90045275 AIC-755x 0 d 90045278 AIC-7852 0 d 90045375 AIC-755x 0 d 90045378 AIC-7850 0 d 90045475 AIC-755x 0 d 90045478 AIC-7850 0 d 90045575 AVA-2930 0 d 90045578 AIC-7855 0 d 90045647 ANA-7711 TCP Offload Engine 0 s 9004564790047710 ANA-7711F TCP Offload Engine - Optical 0 s 9004564790047711 ANA-7711LP TCP Offload Engine - Copper 0 d 90045675 AIC-755x 0 d 90045678 AIC-7856 0 d 90045775 AIC-755x 0 d 90045778 AIC-7850 0 d 90045800 AIC-5800 0 d 90045900 ANA-5910/5930/5940 ATM155 & 25 LAN Adapter 0 d 90045905 ANA-5910A/5930A/5940A ATM Adapter 0 d 90046038 AIC-3860 0 d 90046075 AIC-1480 / APA-1480 0 s 9004607590047560 AIC-1480 / APA-1480 Cardbus 0 d 90046078 AIC-7860 0 d 90046178 AIC-7861 0 s 9004617890047861 AHA-2940AU Single 0 d 90046278 AIC-7860 0 d 90046378 AIC-7860 0 d 90046478 AIC-786x 0 d 90046578 AIC-786x 0 d 90046678 AIC-786x 0 d 90046778 AIC-786x 0 d 90046915 ANA620xx/ANA69011A 0 s 9004691590040008 ANA69011A/TX 10/100 0 s 9004691590040009 ANA69011A/TX 10/100 0 s 9004691590040010 ANA62022 2-port 10/100 0 s 9004691590040018 ANA62044 4-port 10/100 0 s 9004691590040019 ANA62044 4-port 10/100 0 s 9004691590040020 ANA62022 2-port 10/100 0 s 9004691590040028 ANA69011A/TX 10/100 0 s 9004691590048008 ANA69011A/TX 64 bit 10/100 0 s 9004691590048009 ANA69011A/TX 64 bit 10/100 0 s 9004691590048010 ANA62022 2-port 64 bit 10/100 0 s 9004691590048018 ANA62044 4-port 64 bit 10/100 0 s 9004691590048019 ANA62044 4-port 64 bit 10/100 0 s 9004691590048020 ANA62022 2-port 64 bit 10/100 0 s 9004691590048028 ANA69011A/TX 64 bit 10/100 0 d 90047078 AHA-294x / AIC-7870 0 d 90047178 AHA-2940/2940W / AIC-7871 0 d 90047278 AHA-3940/3940W / AIC-7872 0 d 90047378 AHA-3985 / AIC-7873 0 d 90047478 AHA-2944/2944W / AIC-7874 0 d 90047578 AHA-3944/3944W / AIC-7875 0 d 90047678 AHA-4944W/UW / AIC-7876 0 d 90047710 ANA-7711F Network Accelerator Card (NAC) - Optical 0 d 90047711 ANA-7711C Network Accelerator Card (NAC) - Copper 0 d 90047778 AIC-787x 0 d 90047810 AIC-7810 0 d 90047815 AIC-7815 RAID+Memory Controller IC 0 s 9004781590047815 ARO-1130U2 RAID Controller 0 s 9004781590047840 AIC-7815 RAID+Memory Controller IC 0 d 90047850 AIC-7850 0 d 90047855 AHA-2930 0 d 90047860 AIC-7860 0 d 90047870 AIC-7870 0 d 90047871 AHA-2940 0 d 90047872 AHA-3940 0 d 90047873 AHA-3980 0 d 90047874 AHA-2944 0 d 90047880 AIC-7880P 0 d 90047890 AIC-7890 0 d 90047891 AIC-789x 0 d 90047892 AIC-789x 0 d 90047893 AIC-789x 0 d 90047894 AIC-789x 0 d 90047895 AHA-2940U/UW / AHA-39xx / AIC-7895 0 s 9004789590047890 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B 0 s 9004789590047891 AHA-2940U/2940UW Dual 0 s 9004789590047892 AHA-3940AU/AUW/AUWD/UWD 0 s 9004789590047894 AHA-3944AUWD 0 s 9004789590047895 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B 0 s 9004789590047896 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B 0 s 9004789590047897 AHA-2940U/2940UW Dual AHA-394xAU/AUW/AUWD AIC-7895B 0 d 90047896 AIC-789x 0 d 90047897 AIC-789x 0 d 90048078 AIC-7880U 0 s 9004807890047880 AIC-7880P Ultra/Ultra Wide SCSI Chipset 0 d 90048178 AHA-2940U/UW/D / AIC-7881U 0 s 9004817890047881 AHA-2940UW SCSI Host Adapter 0 d 90048278 AHA-3940U/UW/UWD / AIC-7882U 0 d 90048378 AHA-3940U/UW / AIC-7883U 0 d 90048478 AHA-2944UW / AIC-7884U 0 d 90048578 AHA-3944U/UWD / AIC-7885 0 d 90048678 AHA-4944UW / AIC-7886 0 d 90048778 AHA-2940UW Pro / AIC-788x 0 s 9004877890047887 2940UW Pro Ultra-Wide SCSI Controller 0 d 90048878 AHA-2930UW / AIC-7888 0 s 9004887890047888 AHA-2930UW SCSI Controller 0 d 90048b78 ABA-1030 0 d 9004ec78 AHA-4944W/UW 0 v 9005 Adaptec 0 d 90050010 AHA-2940U2/U2W 0 s 9005001090052180 AHA-2940U2 SCSI Controller 0 s 9005001090058100 AHA-2940U2B SCSI Controller 0 s 900500109005a100 AHA-2940U2B SCSI Controller 0 s 900500109005a180 AHA-2940U2W SCSI Controller 0 s 900500109005e100 AHA-2950U2B SCSI Controller 0 d 90050011 AHA-2930U2 0 d 90050013 78902 0 s 9005001390050003 AAA-131U2 Array1000 1 Channel RAID Controller 0 s 900500139005000f AIC7890_ARO 0 d 9005001f AHA-2940U2/U2W / 7890/7891 0 s 9005001f9005000f 2940U2W SCSI Controller 0 s 9005001f9005a180 2940U2W SCSI Controller 0 d 90050020 AIC-7890 0 d 9005002f AIC-7890 0 d 90050030 AIC-7890 0 d 9005003f AIC-7890 0 d 90050050 AHA-3940U2x/395U2x 0 s 900500509005f500 AHA-3950U2B 0 s 900500509005ffff AHA-3950U2B 0 d 90050051 AHA-3950U2D 0 s 900500519005b500 AHA-3950U2D 0 d 90050053 AIC-7896 SCSI Controller 0 s 900500539005ffff AIC-7896 SCSI Controller mainboard implementation 0 d 9005005f AIC-7896U2/7897U2 0 d 90050080 AIC-7892A U160/m 0 s 900500800e11e2a0 Compaq 64-Bit/66MHz Wide Ultra3 SCSI Adapter 0 s 9005008090056220 AHA-29160C 0 s 90050080900562a0 29160N Ultra160 SCSI Controller 0 s 900500809005e220 29160LP Low Profile Ultra160 SCSI Controller 0 s 900500809005e2a0 29160 Ultra160 SCSI Controller 0 d 90050081 AIC-7892B U160/m 0 s 90050081900562a1 19160 Ultra160 SCSI Controller 0 d 90050083 AIC-7892D U160/m 0 d 9005008f AIC-7892P U160/m 0 s 9005008f11790001 Magnia Z310 0 s 9005008f15d99005 Onboard SCSI Host Adapter 0 d 900500c0 AHA-3960D / AIC-7899A U160/m 0 s 900500c00e11f620 Compaq 64-Bit/66MHz Dual Channel Wide Ultra3 SCSI Adapter 0 s 900500c09005f620 AHA-3960D U160/m 0 d 900500c1 AIC-7899B U160/m 0 d 900500c3 AIC-7899D U160/m 0 d 900500c5 RAID subsystem HBA 0 s 900500c5102800c5 PowerEdge 2400,2500,2550,4400 0 d 900500cf AIC-7899P U160/m 0 s 900500cf102800ce PowerEdge 1400 0 s 900500cf102800d1 PowerEdge 2550 0 s 900500cf102800d9 PowerEdge 2500 0 s 900500cf10f12462 Thunder K7 S2462 0 s 900500cf15d99005 Onboard SCSI Host Adapter 0 s 900500cf80863411 SDS2 Mainboard 0 d 90050250 ServeRAID Controller 0 s 9005025010140279 ServeRAID-xx 0 s 900502501014028c ServeRAID-xx 0 d 90050279 ServeRAID 6M 0 from kernel sources d 90050283 AAC-RAID 0 s 9005028390050283 Catapult 0 d 90050284 AAC-RAID 0 s 9005028490050284 Tomcat 0 d 90050285 AAC-RAID 0 s 900502850e110295 SATA 6Ch (Bearcat) 0 s 9005028510280287 PowerEdge Expandable RAID Controller 320/DC 0 s 9005028510280291 CERC SATA RAID 2 PCI SATA 6ch (DellCorsair) 0 s 9005028517aa0286 Legend S220 (Legend Crusader) 0 s 9005028517aa0287 Legend S230 (Legend Vulcan) 0 s 9005028590050285 2200S (Vulcan) 0 s 9005028590050286 2120S (Crusader) 0 s 9005028590050287 2200S (Vulcan-2m) 0 s 9005028590050288 3230S (Harrier) 0 s 9005028590050289 3240S (Tornado) 0 s 900502859005028a ASR-2020S PCI-X ZCR (Skyhawk) 0 s 900502859005028b ASR-2020S SO-DIMM PCI-X ZCR (Terminator) 0 s 9005028590050290 AAR-2410SA PCI SATA 4ch (Jaguar II) 0 s 9005028590050292 AAR-2810SA PCI SATA 8ch (Corsair-8) 0 s 9005028590050293 AAR-21610SA PCI SATA 16ch (Corsair-16) 0 s 9005028590050294 ESD SO-DIMM PCI-X SATA ZCR (Prowler) 0 d 90050286 AAC-RAID (Rocket) 0 s 900502869005028c ASR-2230S + ASR-2230SLP PCI-X (Lancer) 0 d 90058000 ASC-29320A U320 0 d 9005800f AIC-7901 U320 0 d 90058010 ASC-39320 U320 0 d 90058011 ASC-32320D U320 0 s 900580110e1100ac ASC-39320D U320 0 s 9005801190050041 ASC-39320D U320 0 d 90058012 ASC-29320 U320 0 d 90058013 ASC-29320B U320 0 d 90058014 ASC-29320LP U320 0 d 90058015 ASC-39320B U320 0 d 90058016 ASC-39320A U320 0 d 90058017 ASC-29320ALP U320 0 d 9005801c ASC-39320D U320 0 d 9005801d AIC-7902B U320 0 d 9005801e AIC-7901A U320 0 d 9005801f AIC-7902 U320 0 d 90058080 ASC-29320A U320 w/HostRAID 0 d 9005808f AIC-7901 U320 w/HostRAID 0 d 90058090 ASC-39320 U320 w/HostRAID 0 d 90058091 ASC-39320D U320 w/HostRAID 0 d 90058092 ASC-29320 U320 w/HostRAID 0 d 90058093 ASC-29320B U320 w/HostRAID 0 d 90058094 ASC-29320LP U320 w/HostRAID 0 d 90058095 ASC-39320(B) U320 w/HostRAID 0 d 90058096 ASC-39320A U320 w/HostRAID 0 d 90058097 ASC-29320ALP U320 w/HostRAID 0 d 9005809c ASC-39320D(B) U320 w/HostRAID 0 d 9005809d AIC-7902(B) U320 w/HostRAID 0 d 9005809e AIC-7901A U320 w/HostRAID 0 d 9005809f AIC-7902 U320 w/HostRAID 0 v 907f Atronics 0 d 907f2015 IDE-2015PL 0 v 919a Gigapixel Corp 0 v 9412 Holtek 0 d 94126565 6565 0 v 9699 Omni Media Technology Inc 0 d 96996565 6565 0 v 9710 NetMos Technology 0 d 97107780 USB IRDA-port 0 d 97109815 PCI 9815 Multi-I/O Controller 0 s 9710981510000020 2P0S (2 port parallel adaptor) 0 d 97109835 PCI 9835 Multi-I/O Controller 0 s 9710983510000002 2S (16C550 UART) 0 s 9710983510000012 1P2S 0 d 97109845 PCI 9845 Multi-I/O Controller 0 s 9710984510000004 0P4S (4 port 16550A serial card) 0 s 9710984510000006 0P6S (6 port 16550a serial card) 0 d 97109855 PCI 9855 Multi-I/O Controller 0 s 9710985510000014 1P4S 0 v 9902 Stargen Inc. 0 d 99020001 SG2010 PCI over Starfabric Bridge 0 d 99020002 SG2010 PCI to Starfabric Gateway 0 d 99020003 SG1010 Starfabric Switch and PCI Bridge 0 v a0a0 AOPEN Inc. 0 v a0f1 UNISYS Corporation 0 v a200 NEC Corporation 0 v a259 Hewlett Packard 0 v a25b Hewlett Packard GmbH PL24-MKT 0 v a304 Sony 0 v a727 3Com Corporation 0 d a7270013 3CRPAG175 Wireless PC Card 0 v aa42 Scitex Digital Video 0 v ac1e Digital Receiver Technology Inc 0 v ac3d Actuality Systems 0 v aecb Adrienne Electronics Corporation 0 v b1b3 Shiva Europe Limited 0 v bd11 Pinnacle Systems, Inc. (Wrong ID) 0 Pinnacle should be 11bd, but they got it wrong several times --mj v c001 TSI Telsys 0 v c0a9 Micron/Crucial Technology 0 v c0de Motorola 0 v c0fe Motion Engineering, Inc. 0 v ca50 Varian Australia Pty Ltd 0 v cafe Chrysalis-ITS 0 v cccc Catapult Communications 0 v cddd Tyzx, Inc. 0 d cddd0101 DeepSea 1 High Speed Stereo Vision Frame Grabber 0 d cddd0200 DeepSea 2 High Speed Stereo Vision Frame Grabber 0 v d4d4 Dy4 Systems Inc 0 d d4d40601 PCI Mezzanine Card 0 v d531 I+ME ACTIA GmbH 0 v d84d Exsys 0 v dead Indigita Corporation 0 v e000 Winbond 0 d e000e000 W89C940 0 v e159 Tiger Jet Network Inc. 0 see also : http://www.schoenfeld.de/inside/Inside_CWMK3.txt maybe a misuse of TJN id or it use the TJN 3XX chip for other applic d e1590001 Tiger3XX Modem/ISDN interface 0 s e159000100590001 128k ISDN-S/T Adapter 0 s e159000100590003 128k ISDN-U Adapter 0 d e1590002 Tiger100APC ISDN chipset 0 v e4bf EKF Elektronik GmbH 0 v e55e Essence Technology, Inc. 0 Innovative and scalable network IC vendor v ea01 Eagle Technology 0 v ea60 RME 0 The main chip of all these devices is by Xilinx -> It could also be a Xilinx ID. d ea609896 Digi32 0 d ea609897 Digi32 Pro 0 d ea609898 Digi32/8 0 v eabb Aashima Technology B.V. 0 v eace Endace Measurement Systems, Ltd 0 d eace3100 DAG 3.10 OC-3/OC-12 0 d eace3200 DAG 3.2x OC-3/OC-12 0 d eace320e DAG 3.2E Fast Ethernet 0 d eace340e DAG 3.4E Fast Ethernet 0 d eace341e DAG 3.41E Fast Ethernet 0 d eace3500 DAG 3.5 OC-3/OC-12 0 d eace351c DAG 3.5ECM Fast Ethernet 0 d eace4100 DAG 4.10 OC-48 0 d eace4110 DAG 4.11 OC-48 0 d eace4220 DAG 4.2 OC-48 0 d eace422e DAG 4.2E Dual Gigabit Ethernet 0 v ec80 Belkin Corporation 0 d ec80ec00 F5D6000 0 v ecc0 Echo Digital Audio Corporation 0 d ecc00050 Gina24_301 0 d ecc00051 Gina24_361 0 d ecc00060 Layla24 0 d ecc00070 Mona_301_80 0 d ecc00071 Mona_301_66 0 d ecc00072 Mona_361 0 d ecc00080 Mia 0 v edd8 ARK Logic Inc 0 d edd8a091 1000PV [Stingray] 0 d edd8a099 2000PV [Stingray] 0 d edd8a0a1 2000MT 0 d edd8a0a9 2000MI 0 v f1d0 AJA Video 0 d f1d0cafe KONA SD SMPTE 259M I/O 0 All boards I have seen have this ID not efac, though all docs say efac... d f1d0efac KONA SD SMPTE 259M I/O 0 d f1d0facd KONA HD SMPTE 292M I/O 0 v fa57 Interagon AS 0 d fa570001 PMC [Pattern Matching Chip] 0 v febd Ultraview Corp. 0 v feda Broadcom Inc (nee Epigram) 0 d fedaa0fa BCM4210 iLine10 HomePNA 2.0 0 d fedaa10e BCM4230 iLine10 HomePNA 2.0 0 v fede Fedetec Inc. 0 IT & Telecom company, develops PCI Trunk cards d fede0003 TABIC PCI v3 0 v fffe VMWare Inc 0 d fffe0405 Virtual SVGA 4.0 0 d fffe0710 Virtual SVGA 0 v ffff Illegal Vendor ID 0 xine-lib-1.2/contrib/libdha/ports.c0000644000175000017500000001315414647725152015066 0ustar meme/* (C) 2002 - library implementation by Nick Kyrshev XFree86 3.3.3 scanpci.c, modified for GATOS/win/gfxdump by Øyvind Aabling. */ /* $XConsortium: scanpci.c /main/25 1996/10/27 11:48:40 kaleb $ */ /* * name: scanpci.c * * purpose: This program will scan for and print details of * devices on the PCI bus. * author: Robin Cutshaw (robin@xfree86.org) * * supported O/S's: SVR4, UnixWare, SCO, Solaris, * FreeBSD, NetBSD, 386BSD, BSDI BSD/386, * Linux, Mach/386, ISC * DOS (WATCOM 9.5 compiler) * * compiling: [g]cc scanpci.c -o scanpci * for SVR4 (not Solaris), UnixWare use: * [g]cc -DSVR4 scanpci.c -o scanpci * for DOS, watcom 9.5: * wcc386p -zq -omaxet -7 -4s -s -w3 -d2 name.c * and link with PharLap or other dos extender for exe * */ /* $XFree86: xc/programs/Xserver/hw/xfree86/etc/scanpci.c,v 3.34.2.17 1998/11/10 11:55:40 dawes Exp $ */ /* * Copyright 1995 by Robin Cutshaw * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the names of the above listed copyright holder(s) * not be used in advertising or publicity pertaining to distribution of * the software without specific, written prior permission. The above listed * copyright holder(s) make(s) no representations about the suitability of this * software for any purpose. It is provided "as is" without express or * implied warranty. * * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE * LIABLE FOR ANY SPECIAL, 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. * */ #include #include #include #include #include #include #include #ifdef ARCH_ALPHA #include #endif #include #include "libdha.h" #include "AsmMacros.h" #include "kernelhelper/dhahelper.h" /* OS depended stuff */ #if defined (linux) #include "sysdep/pci_linux.c" #elif defined (__FreeBSD_kernel__) #include "sysdep/pci_freebsd.c" #elif defined (__386BSD__) #include "sysdep/pci_386bsd.c" #elif defined (__NetBSD__) #include "sysdep/pci_netbsd.c" #elif defined (__OpenBSD__) #include "sysdep/pci_openbsd.c" #elif defined (__bsdi__) #include "sysdep/pci_bsdi.c" #elif defined (Lynx) #include "sysdep/pci_lynx.c" #elif defined (MACH386) #include "sysdep/pci_mach386.c" #elif defined (__SVR4) #if !defined(SVR4) #define SVR4 #endif #include "sysdep/pci_svr4.c" #elif defined (SCO) #include "sysdep/pci_sco.c" #elif defined (ISC) #include "sysdep/pci_isc.c" #elif defined (__EMX__) #include "sysdep/pci_os2.c" #elif defined (_WIN32) || defined(__CYGWIN__) #include "sysdep/pci_win32.c" #else #include "sysdep/pci_generic_os.c" #endif static int dhahelper_fd=-1; static unsigned dhahelper_counter=0; int enable_app_io( void ) { if((dhahelper_fd=open("/dev/dhahelper",O_RDWR)) < 0) return enable_os_io(); dhahelper_counter++; return 0; } int disable_app_io( void ) { dhahelper_counter--; if(dhahelper_fd > 0) { if(!dhahelper_counter) { close(dhahelper_fd); dhahelper_fd = -1; } } else return disable_os_io(); return 0; } unsigned char INPORT8(unsigned idx) { if (dhahelper_fd > 0) { dhahelper_port_t _port; _port.operation = PORT_OP_READ; _port.addr = idx; _port.size = 1; if (ioctl(dhahelper_fd, DHAHELPER_PORT, &_port) == 0) return _port.value; } return inb(idx); } unsigned short INPORT16(unsigned idx) { if (dhahelper_fd > 0) { dhahelper_port_t _port; _port.operation = PORT_OP_READ; _port.addr = idx; _port.size = 2; if (ioctl(dhahelper_fd, DHAHELPER_PORT, &_port) == 0) return _port.value; } return inw(idx); } unsigned INPORT32(unsigned idx) { if (dhahelper_fd > 0) { dhahelper_port_t _port; _port.operation = PORT_OP_READ; _port.addr = idx; _port.size = 4; if (ioctl(dhahelper_fd, DHAHELPER_PORT, &_port) == 0) return _port.value; } return inl(idx); } void OUTPORT8(unsigned idx,unsigned char val) { if (dhahelper_fd > 0) { dhahelper_port_t _port; _port.operation = PORT_OP_WRITE; _port.addr = idx; _port.size = 1; _port.value = val; if (ioctl(dhahelper_fd, DHAHELPER_PORT, &_port) == 0) return; } else outb(idx,val); } void OUTPORT16(unsigned idx,unsigned short val) { if (dhahelper_fd > 0) { dhahelper_port_t _port; _port.operation = PORT_OP_WRITE; _port.addr = idx; _port.size = 2; _port.value = val; if (ioctl(dhahelper_fd, DHAHELPER_PORT, &_port) == 0) return; } else outw(idx,val); } void OUTPORT32(unsigned idx,unsigned val) { if (dhahelper_fd > 0) { dhahelper_port_t _port; _port.operation = PORT_OP_WRITE; _port.addr = idx; _port.size = 4; _port.value = val; if (ioctl(dhahelper_fd, DHAHELPER_PORT, &_port) == 0) return; } else outl(idx,val); } xine-lib-1.2/contrib/libdha/kernelhelper/0000755000175000017500000000000014647725152016227 5ustar memexine-lib-1.2/contrib/libdha/kernelhelper/dhahelper.h0000644000175000017500000000534414647725151020341 0ustar meme/* Direct Hardware Access kernel helper (C) 2002 Alex Beregszaszi (C) 2002-2003 Nick Kurshev */ #ifndef DHAHELPER_H #define DHAHELPER_H /* #include */ /* feel free to change */ #define DEFAULT_MAJOR 252 /* 240-254 LOCAL/EXPERIMENTAL USE */ #define API_VERSION 0x30 /* 3.0*/ typedef struct dhahelper_port_s { #define PORT_OP_READ 1 #define PORT_OP_WRITE 2 int operation; int size; int addr; // FIXME - switch to void* (64bit) int value; } dhahelper_port_t; typedef struct dhahelper_mtrr_s { #define MTRR_OP_ADD 1 #define MTRR_OP_DEL 2 int operation; long start; long size; int type; int privat; } dhahelper_mtrr_t; typedef struct dhahelper_pci_config_s { #define PCI_OP_READ 0 #define PCI_OP_WRITE 1 int operation; int bus; int dev; int func; int cmd; int size; long ret; } dhahelper_pci_config_t; typedef struct dhahelper_vmi_s { void * virtaddr; unsigned long length; unsigned long *realaddr; }dhahelper_vmi_t; typedef struct dhahelper_mem_s { void * addr; unsigned long length; }dhahelper_mem_t; typedef struct dhahelper_irq_s { unsigned num; int bus, dev, func; int ack_region; unsigned long ack_offset; unsigned int ack_data; }dhahelper_irq_t; typedef struct dhahelper_cpu_flush_s { void *va; unsigned long length; }dhahelper_cpu_flush_t; typedef struct dhahelper_pci_device_s { int bus,card,func; /* PCI/AGP bus:card:func */ unsigned short vendor,device; /* Card vendor+device ID */ unsigned long base0,base1,base2,baserom; /* Memory and I/O base addresses */ unsigned long base3,base4,base5; /* Memory and I/O base addresses */ unsigned char irq,ipin,gnt,lat; /* assigned IRQ parameters for this card */ }dhahelper_pci_device_t; #define DHAHELPER_GET_VERSION _IOW('D', 0, int) #define DHAHELPER_PORT _IOWR('D', 1, dhahelper_port_t) #define DHAHELPER_MTRR _IOWR('D', 2, dhahelper_mtrr_t) #define DHAHELPER_PCI_CONFIG _IOWR('D', 3, dhahelper_pci_config_t) #define DHAHELPER_VIRT_TO_PHYS _IOWR('D', 4, dhahelper_vmi_t) #define DHAHELPER_VIRT_TO_BUS _IOWR('D', 5, dhahelper_vmi_t) #define DHAHELPER_ALLOC_PA _IOWR('D', 6, dhahelper_mem_t) #define DHAHELPER_FREE_PA _IOWR('D', 7, dhahelper_mem_t) #define DHAHELPER_LOCK_MEM _IOWR('D', 8, dhahelper_mem_t) #define DHAHELPER_UNLOCK_MEM _IOWR('D', 9, dhahelper_mem_t) #define DHAHELPER_INSTALL_IRQ _IOWR('D', 10, dhahelper_irq_t) #define DHAHELPER_ACK_IRQ _IOWR('D', 11, dhahelper_irq_t) #define DHAHELPER_FREE_IRQ _IOWR('D', 12, dhahelper_irq_t) #define DHAHELPER_CPU_FLUSH _IOWR('D', 13, dhahelper_cpu_flush_t) #define DHAHELPER_PCI_FIND _IOWR('D', 14, dhahelper_pci_device_t) #endif /* DHAHELPER_H */ xine-lib-1.2/contrib/libdha/kernelhelper/dhahelper.c0000644000175000017500000007465414647725151020346 0ustar meme/* Direct Hardware Access kernel helper (C) 2002 Alex Beregszaszi (C) 2002-2003 Nick Kurshev (C) 2002-2004 Måns Rullgård Accessing hardware from userspace as USER (no root needed!) Tested on 2.2.x (2.2.19), 2.4.x (2.4.3,2.4.17) and 2.6.1. License: GPL WARNING! THIS MODULE VIOLATES SEVERAL SECURITY LINES! DON'T USE IT ON PRODUCTION SYSTEMS, ONLY AT HOME, ON A "SINGLE-USER" SYSTEM. NO WARRANTY! IF YOU WANT TO USE IT ON PRODUCTION SYSTEMS THEN PLEASE READ 'README' FILE TO KNOW HOW TO PREVENT ANONYMOUS ACCESS TO THIS MODULE. Tech: Communication between userspace and kernelspace goes over character device using ioctl. Usage: mknod -m 600 /dev/dhahelper c 252 0 Also you can change the major number, setting the "dhahelper_major" module parameter, the default is 252, specified in dhahelper.h. Note: do not use other than minor==0, the module forbids it. TODO: * select (request?) a "valid" major number (from Linux project? ;) * make security * is pci handling needed? (libdha does this with lowlevel port funcs) * is mttr handling needed? * test on older kernels (2.0.x (?)) */ #ifndef MODULE #define MODULE #endif #ifndef __KERNEL__ #define __KERNEL__ #endif #include #ifdef CONFIG_MODVERSION #define MODVERSION #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) #include #else #include #endif #include #include #include #include #include #include #include #include #include #ifdef CONFIG_MTRR #include #endif #ifdef CONFIG_DEVFS_FS #include #endif #include "dhahelper.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #define pte_offset(p,a) pte_offset_kernel(p,a) #define LockPage(p) SetPageLocked(p) #define UnlockPage(p) ClearPageLocked(p) #define irqreturn(n) return(n) #else #define irqreturn_t void #define irqreturn(n) return #endif MODULE_AUTHOR("Alex Beregszaszi , Nick Kurshev , Måns Rullgård "); MODULE_DESCRIPTION("Provides userspace access to hardware"); #ifdef MODULE_LICENSE MODULE_LICENSE("GPL"); #endif static int dhahelper_major = DEFAULT_MAJOR; MODULE_PARM(dhahelper_major, "i"); MODULE_PARM_DESC(dhahelper_major, "Major number of dhahelper characterdevice"); /* 0 = silent */ /* 1 = report errors (default) */ /* 2 = debug */ static int dhahelper_verbosity = 1; MODULE_PARM(dhahelper_verbosity, "i"); MODULE_PARM_DESC(dhahelper_verbosity, "Level of verbosity (0 = silent, 1 = only errors, 2 = debug)"); static int dhahelper_open(struct inode *inode, struct file *file) { if (dhahelper_verbosity > 1) printk(KERN_DEBUG "dhahelper: device opened\n"); if (MINOR(inode->i_rdev) != 0) return -ENXIO; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) MOD_INC_USE_COUNT; #endif return 0; } static int dhahelper_release(struct inode *inode, struct file *file) { if (dhahelper_verbosity > 1) printk(KERN_DEBUG "dhahelper: device released\n"); if (MINOR(inode->i_rdev) != 0) return -ENXIO; #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) MOD_DEC_USE_COUNT; #endif return 0; } static int dhahelper_get_version(int * arg) { int version = API_VERSION; if (copy_to_user(arg, &version, sizeof(int))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } return 0; } static int dhahelper_port(dhahelper_port_t * arg) { dhahelper_port_t port; if (copy_from_user(&port, arg, sizeof(dhahelper_port_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } switch(port.operation) { case PORT_OP_READ: { switch(port.size) { case 1: port.value = inb(port.addr); break; case 2: port.value = inw(port.addr); break; case 4: port.value = inl(port.addr); break; default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: invalid port read size (%d)\n", port.size); return -EINVAL; } break; } case PORT_OP_WRITE: { switch(port.size) { case 1: outb(port.value, port.addr); break; case 2: outw(port.value, port.addr); break; case 4: outl(port.value, port.addr); break; default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: invalid port write size (%d)\n", port.size); return -EINVAL; } break; } default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: invalid port operation (%d)\n", port.operation); return -EINVAL; } /* copy back only if read was performed */ if (port.operation == PORT_OP_READ) if (copy_to_user(arg, &port, sizeof(dhahelper_port_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } return 0; } /*******************************/ /* Memory management functions */ /* from kernel:/drivers/media/video/bttv-driver.c */ /*******************************/ #define MDEBUG(x) do { } while(0) /* Debug memory management */ /* [DaveM] I've recoded most of this so that: * 1) It's easier to tell what is happening * 2) It's more portable, especially for translating things * out of vmalloc mapped areas in the kernel. * 3) Less unnecessary translations happen. * * The code used to assume that the kernel vmalloc mappings * existed in the page tables of every process, this is simply * not guarenteed. We now use pgd_offset_k which is the * defined way to get at the kernel page tables. */ /* Given PGD from the address space's page table, return the kernel * virtual mapping of the physical memory mapped at ADR. */ static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr) { unsigned long ret = 0UL; pmd_t *pmd; pte_t *ptep, pte; if (!pgd_none(*pgd)) { pmd = pmd_offset(pgd, adr); if (!pmd_none(*pmd)) { ptep = pte_offset(pmd, adr); pte = *ptep; if(pte_present(pte)) { ret = (unsigned long) page_address(pte_page(pte)); ret |= (adr & (PAGE_SIZE - 1)); } } } MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret)); return ret; } static inline unsigned long uvirt_to_bus(unsigned long adr) { unsigned long kva, ret; kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr); ret = virt_to_bus((void *)kva); MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret)); return ret; } static inline unsigned long uvirt_to_pa(unsigned long adr) { unsigned long kva, ret; kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr); ret = virt_to_phys((void *)kva); MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret)); return ret; } static inline unsigned long kvirt_to_bus(unsigned long va) { unsigned long kva, ret; kva = uvirt_to_kva(pgd_offset_k(va), va); ret = virt_to_bus((void *)kva); MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret)); return ret; } /* Here we want the physical address of the memory. * This is used when initializing the contents of the * area and marking the pages as reserved. */ static inline unsigned long kvirt_to_pa(unsigned long va) { unsigned long kva, ret; kva = uvirt_to_kva(pgd_offset_k(va), va); ret = __pa(kva); MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret)); return ret; } static void * rvmalloc(signed long size) { void * mem; unsigned long adr, page; mem=vmalloc_32(size); if (mem) { memset(mem, 0, size); /* Clear the ram out, no junk to the user */ adr=(unsigned long) mem; while (size > 0) { page = kvirt_to_pa(adr); SetPageReserved(virt_to_page(__va(page))); adr+=PAGE_SIZE; size-=PAGE_SIZE; } } return mem; } static int pag_lock(unsigned long addr) { unsigned long page; unsigned long kva; kva = uvirt_to_kva(pgd_offset(current->mm, addr), addr); if(kva) { lock_it: page = uvirt_to_pa((unsigned long)addr); LockPage(virt_to_page(__va(page))); SetPageReserved(virt_to_page(__va(page))); } else { copy_from_user(&page,(char *)addr,1); /* try access it */ kva = uvirt_to_kva(pgd_offset(current->mm, addr), addr); if(kva) goto lock_it; else return EPERM; } return 0; } static int pag_unlock(unsigned long addr) { unsigned long page; unsigned long kva; kva = uvirt_to_kva(pgd_offset(current->mm, addr), addr); if(kva) { page = uvirt_to_pa((unsigned long)addr); UnlockPage(virt_to_page(__va(page))); ClearPageReserved(virt_to_page(__va(page))); return 0; } return EPERM; } static void rvfree(void * mem, signed long size) { unsigned long adr, page; if (mem) { adr=(unsigned long) mem; while (size > 0) { page = kvirt_to_pa(adr); ClearPageReserved(virt_to_page(__va(page))); adr+=PAGE_SIZE; size-=PAGE_SIZE; } vfree(mem); } } static int dhahelper_virt_to_phys(dhahelper_vmi_t *arg) { dhahelper_vmi_t mem; unsigned long i,nitems; char *addr; if (copy_from_user(&mem, arg, sizeof(dhahelper_vmi_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } nitems = mem.length / PAGE_SIZE; if(mem.length % PAGE_SIZE) nitems++; addr = mem.virtaddr; for(i=0;i 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } addr += PAGE_SIZE; } return 0; } static int dhahelper_virt_to_bus(dhahelper_vmi_t *arg) { dhahelper_vmi_t mem; unsigned long i,nitems; char *addr; if (copy_from_user(&mem, arg, sizeof(dhahelper_vmi_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } nitems = mem.length / PAGE_SIZE; if(mem.length % PAGE_SIZE) nitems++; addr = mem.virtaddr; for(i=0;i 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } addr += PAGE_SIZE; } return 0; } static int dhahelper_alloc_pa(dhahelper_mem_t *arg) { dhahelper_mem_t mem; if (copy_from_user(&mem, arg, sizeof(dhahelper_mem_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } mem.addr = rvmalloc(mem.length); if (copy_to_user(arg, &mem, sizeof(dhahelper_mem_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } return 0; } static int dhahelper_free_pa(dhahelper_mem_t *arg) { dhahelper_mem_t mem; if (copy_from_user(&mem, arg, sizeof(dhahelper_mem_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } rvfree(mem.addr,mem.length); return 0; } static int dhahelper_lock_mem(dhahelper_mem_t *arg) { dhahelper_mem_t mem; int retval; unsigned long i,nitems,addr; if (copy_from_user(&mem, arg, sizeof(dhahelper_mem_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } nitems = mem.length / PAGE_SIZE; if(mem.length % PAGE_SIZE) nitems++; addr = (unsigned long)mem.addr; for(i=0;i 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } nitems = mem.length / PAGE_SIZE; if(mem.length % PAGE_SIZE) nitems++; addr = (unsigned long)mem.addr; for(i=0;i 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } if(!(pci = pci_find_slot(my_irq.bus, PCI_DEVFN(my_irq.dev, my_irq.func)))) return -EINVAL; rlen = pci_resource_len(pci, my_irq.ack_region); if(my_irq.ack_offset > rlen - 4) return -EINVAL; irqn = pci->irq; spin_lock_irqsave(&dha_irqs[irqn].lock, dha_irqs[irqn].flags); if(dha_irqs[irqn].handled){ retval = -EBUSY; goto fail; } if(my_irq.ack_region >= 0){ ack_addr = pci_resource_start(pci, my_irq.ack_region); ack_addr += my_irq.ack_offset; #ifdef CONFIG_ALPHA ack_addr += ((struct pci_controller *) pci->sysdata)->dense_mem_base; #endif /* FIXME: Other architectures */ dha_irqs[irqn].ack_addr = phys_to_virt(ack_addr); dha_irqs[irqn].ack_data = my_irq.ack_data; } else { dha_irqs[irqn].ack_addr = 0; } dha_irqs[irqn].lock = SPIN_LOCK_UNLOCKED; dha_irqs[irqn].flags = 0; dha_irqs[irqn].rcvd = 0; dha_irqs[irqn].dev = pci; init_waitqueue_head(&dha_irqs[irqn].wait); dha_irqs[irqn].count = 0; retval = request_irq(irqn, dhahelper_irq_handler, SA_SHIRQ, "dhahelper", pci); if(retval < 0) goto fail; copy_to_user(&arg->num, &irqn, sizeof(irqn)); dha_irqs[irqn].handled = 1; out: spin_unlock_irqrestore(&dha_irqs[irqn].lock, dha_irqs[irqn].flags); return retval; fail: if(retval == -EINVAL){ printk("dhahelper: bad irq number or handler\n"); } else if(retval == -EBUSY){ printk("dhahelper: IRQ %u busy\n", irqn); } else { printk("dhahelper: Could not install irq handler...\n"); } printk("dhahelper: Perhaps you need to let your BIOS assign an IRQ to your video card\n"); goto out; } static int dhahelper_free_irq(dhahelper_irq_t *arg) { dhahelper_irq_t irq; struct pci_dev *pci; int irqn; if (copy_from_user(&irq, arg, sizeof(dhahelper_irq_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } pci = pci_find_slot(irq.bus, PCI_DEVFN(irq.dev, irq.func)); if(!pci) return -EINVAL; irqn = pci->irq; spin_lock_irqsave(&dha_irqs[irqn].lock, dha_irqs[irqn].flags); if(dha_irqs[irqn].handled) { free_irq(irqn, pci); dha_irqs[irqn].handled = 0; printk("IRQ %i: %li\n", irqn, dha_irqs[irqn].count); } spin_unlock_irqrestore(&dha_irqs[irqn].lock, dha_irqs[irqn].flags); return 0; } static int dhahelper_ack_irq(dhahelper_irq_t *arg) { dhahelper_irq_t irq; int retval = 0; DECLARE_WAITQUEUE(wait, current); if (copy_from_user(&irq, arg, sizeof(dhahelper_irq_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } if(irq.num > 255) return -EINVAL; if(!dha_irqs[irq.num].handled) return -ESRCH; add_wait_queue(&dha_irqs[irq.num].wait, &wait); set_current_state(TASK_INTERRUPTIBLE); for(;;){ int r; spin_lock_irqsave(&dha_irqs[irq.num].lock, dha_irqs[irq.num].flags); r = dha_irqs[irq.num].rcvd; spin_unlock_irqrestore(&dha_irqs[irq.num].lock, dha_irqs[irq.num].flags); if(r){ dha_irqs[irq.num].rcvd = 0; break; } if(signal_pending(current)){ retval = -ERESTARTSYS; break; } schedule(); } set_current_state(TASK_RUNNING); remove_wait_queue(&dha_irqs[irq.num].wait, &wait); return retval; } static int dhahelper_cpu_flush(dhahelper_cpu_flush_t *arg) { dhahelper_cpu_flush_t my_l2; if (copy_from_user(&my_l2, arg, sizeof(dhahelper_cpu_flush_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } #if defined(__i386__) /* WBINVD writes all modified cache lines back to main memory */ if(boot_cpu_data.x86 > 3) { __asm __volatile("wbinvd":::"memory"); } #else /* FIXME!!!*/ mb(); /* declared in "asm/system.h" */ #endif return 0; } static struct pci_dev *pdev = NULL; static int dhahelper_pci_find(dhahelper_pci_device_t *arg) { dhahelper_pci_device_t this_dev; pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev); if(pdev) { this_dev.bus = pdev->bus->number; this_dev.card = PCI_SLOT(pdev->devfn); this_dev.func = PCI_FUNC(pdev->devfn); this_dev.vendor = pdev->vendor; this_dev.device = pdev->device; this_dev.base0 = pci_resource_start (pdev, 0); this_dev.base1 = pci_resource_start (pdev, 1); this_dev.base2 = pci_resource_start (pdev, 2); pci_read_config_dword(pdev, pdev->rom_base_reg, (u32*)&this_dev.baserom); this_dev.base3 = pci_resource_start (pdev, 3); this_dev.base4 = pci_resource_start (pdev, 4); this_dev.base5 = pci_resource_start (pdev, 5); pci_read_config_byte(pdev, PCI_INTERRUPT_LINE, &this_dev.irq); pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &this_dev.ipin); pci_read_config_byte(pdev, PCI_MIN_GNT, &this_dev.gnt); pci_read_config_byte(pdev, PCI_MAX_LAT, &this_dev.lat); } else memset(&this_dev,0,sizeof(dhahelper_pci_device_t)); if (copy_to_user(arg, &this_dev, sizeof(dhahelper_pci_device_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } return pdev?0:-ENODATA; } static int dhahelper_pci_config(dhahelper_pci_config_t *arg) { dhahelper_pci_config_t op; struct pci_dev *pdev; if (copy_from_user(&op, arg, sizeof(dhahelper_pci_config_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } pdev = pci_find_slot(op.bus,PCI_DEVFN(op.dev,op.func)); if(!pdev) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: can't identify device\n"); return -EFAULT; } switch(op.operation) { case PCI_OP_READ: switch(op.size) { case 1: pci_read_config_byte(pdev,op.cmd,(u8*)&op.ret); break; case 2: pci_read_config_word(pdev,op.cmd,(u16*)&op.ret); break; case 4: pci_read_config_dword(pdev,op.cmd,(u32*)&op.ret); break; default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: wrong size of pci operation: %u \n",op.size); return -EFAULT; } case PCI_OP_WRITE: switch(op.size) { case 1: pci_write_config_byte(pdev,op.cmd,op.ret); break; case 2: pci_write_config_word(pdev,op.cmd,op.ret); break; case 4: pci_write_config_dword(pdev,op.cmd,op.ret); break; default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: wrong size of pci operation: %u \n",op.size); return -EFAULT; } default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: unknown pci operation %i\n",op.operation); return -EFAULT; } if (copy_to_user(arg, &op, sizeof(dhahelper_pci_device_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } return 0; } static int dhahelper_mtrr(dhahelper_mtrr_t *arg) { #ifdef CONFIG_MTRR dhahelper_mtrr_t op; if (copy_from_user(&op, arg, sizeof(dhahelper_pci_config_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy from userspace\n"); return -EFAULT; } switch(op.operation) { case MTRR_OP_ADD: op.privat = mtrr_add (op.start,op.size,op.type,1); break; case MTRR_OP_DEL: mtrr_del(op.privat, op.start, op.size); break; default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: unknown mtrr operation %i\n",op.operation); return -EFAULT; } if (copy_to_user(arg, &op, sizeof(dhahelper_mtrr_t))) { if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: failed copy to userspace\n"); return -EFAULT; } #endif return 0; } static int dhahelper_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { if (dhahelper_verbosity > 1) printk(KERN_DEBUG "dhahelper: ioctl(cmd=%x, arg=%lx)\n", cmd, arg); if (MINOR(inode->i_rdev) != 0) return -ENXIO; switch(cmd) { case DHAHELPER_GET_VERSION: return dhahelper_get_version((int *)arg); case DHAHELPER_PORT: return dhahelper_port((dhahelper_port_t *)arg); case DHAHELPER_MTRR: return dhahelper_mtrr((dhahelper_mtrr_t *)arg); case DHAHELPER_PCI_CONFIG: return dhahelper_pci_config((dhahelper_pci_config_t *)arg); case DHAHELPER_VIRT_TO_PHYS:return dhahelper_virt_to_phys((dhahelper_vmi_t *)arg); case DHAHELPER_VIRT_TO_BUS: return dhahelper_virt_to_bus((dhahelper_vmi_t *)arg); case DHAHELPER_ALLOC_PA:return dhahelper_alloc_pa((dhahelper_mem_t *)arg); case DHAHELPER_FREE_PA: return dhahelper_free_pa((dhahelper_mem_t *)arg); case DHAHELPER_LOCK_MEM: return dhahelper_lock_mem((dhahelper_mem_t *)arg); case DHAHELPER_UNLOCK_MEM: return dhahelper_unlock_mem((dhahelper_mem_t *)arg); case DHAHELPER_INSTALL_IRQ: return dhahelper_install_irq((dhahelper_irq_t *)arg); case DHAHELPER_ACK_IRQ: return dhahelper_ack_irq((dhahelper_irq_t *)arg); case DHAHELPER_FREE_IRQ: return dhahelper_free_irq((dhahelper_irq_t *)arg); case DHAHELPER_CPU_FLUSH: return dhahelper_cpu_flush((dhahelper_cpu_flush_t *)arg); case DHAHELPER_PCI_FIND: return dhahelper_pci_find((dhahelper_pci_device_t *)arg); default: if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: invalid ioctl (%x)\n", cmd); return -EINVAL; } return 0; } /* fops functions were shamelessly stolen from linux-kernel project ;) */ static loff_t dhahelper_lseek(struct file * file, loff_t offset, int orig) { switch (orig) { case 0: file->f_pos = offset; return file->f_pos; case 1: file->f_pos += offset; return file->f_pos; default: return -EINVAL; } } /* * This funcion reads the *physical* memory. The f_pos points directly to the * memory location. */ static ssize_t dhahelper_read(struct file * file, char * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; unsigned long end_mem; ssize_t read; end_mem = __pa(high_memory); if (p >= end_mem) return 0; if (count > end_mem - p) count = end_mem - p; read = 0; #if defined(__sparc__) || defined(__mc68000__) /* we don't have page 0 mapped on sparc and m68k.. */ if (p < PAGE_SIZE) { unsigned long sz = PAGE_SIZE-p; if (sz > count) sz = count; if (sz > 0) { if (clear_user(buf, sz)) return -EFAULT; buf += sz; p += sz; count -= sz; read += sz; } } #endif if (copy_to_user(buf, __va(p), count)) return -EFAULT; read += count; *ppos += read; return read; } static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp, const char * buf, size_t count, loff_t *ppos) { ssize_t written; written = 0; #if defined(__sparc__) || defined(__mc68000__) /* we don't have page 0 mapped on sparc and m68k.. */ if (realp < PAGE_SIZE) { unsigned long sz = PAGE_SIZE-realp; if (sz > count) sz = count; /* Hmm. Do something? */ buf+=sz; p+=sz; count-=sz; written+=sz; } #endif if (copy_from_user(p, buf, count)) return -EFAULT; written += count; *ppos += written; return written; } static ssize_t dhahelper_write(struct file * file, const char * buf, size_t count, loff_t *ppos) { unsigned long p = *ppos; unsigned long end_mem; end_mem = __pa(high_memory); if (p >= end_mem) return 0; if (count > end_mem - p) count = end_mem - p; return do_write_mem(file, __va(p), p, buf, count, ppos); } #ifndef pgprot_noncached /* * This should probably be per-architecture in */ static inline pgprot_t pgprot_noncached(pgprot_t _prot) { unsigned long prot = pgprot_val(_prot); #if defined(__i386__) || defined(__x86_64__) /* On PPro and successors, PCD alone doesn't always mean uncached because of interactions with the MTRRs. PCD | PWT means definitely uncached. */ if (boot_cpu_data.x86 > 3) prot |= _PAGE_PCD | _PAGE_PWT; #elif defined(__powerpc__) prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; #elif defined(__mc68000__) #ifdef SUN3_PAGE_NOCACHE if (MMU_IS_SUN3) prot |= SUN3_PAGE_NOCACHE; else #endif if (MMU_IS_851 || MMU_IS_030) prot |= _PAGE_NOCACHE030; /* Use no-cache mode, serialized */ else if (MMU_IS_040 || MMU_IS_060) prot = (prot & _CACHEMASK040) | _PAGE_NOCACHE_S; #endif return __pgprot(prot); } #endif /* !pgprot_noncached */ /* * Architectures vary in how they handle caching for addresses * outside of main memory. */ static inline int noncached_address(unsigned long addr) { #if defined(__i386__) /* * On the PPro and successors, the MTRRs are used to set * memory types for physical addresses outside main memory, * so blindly setting PCD or PWT on those pages is wrong. * For Pentiums and earlier, the surround logic should disable * caching for the high addresses through the KEN pin, but * we maintain the tradition of paranoia in this code. */ return !( test_bit(X86_FEATURE_MTRR, boot_cpu_data.x86_capability) || test_bit(X86_FEATURE_K6_MTRR, boot_cpu_data.x86_capability) || test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) || test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) ) && addr >= __pa(high_memory); #else return addr >= __pa(high_memory); #endif } static int dhahelper_mmap(struct file * file, struct vm_area_struct * vma) { unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; int err; /* * Accessing memory above the top the kernel knows about or * through a file pointer that was marked O_SYNC will be * done non-cached. */ if (noncached_address(offset) || (file->f_flags & O_SYNC)) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); /* Don't try to swap out physical pages.. */ vma->vm_flags |= VM_RESERVED; /* * Don't dump addresses that are not real memory to a core file. */ if (offset >= __pa(high_memory) || (file->f_flags & O_SYNC)) vma->vm_flags |= VM_IO; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) err = remap_page_range(vma, vma->vm_start, offset, vma->vm_end-vma->vm_start, vma->vm_page_prot); #else err = remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, vma->vm_page_prot); #endif if(err) return -EAGAIN; return 0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) static struct file_operations dhahelper_fops = { /*llseek*/ dhahelper_lseek, /*read*/ dhahelper_read, /*write*/ dhahelper_write, /*readdir*/ NULL, /*poll*/ NULL, /*ioctl*/ dhahelper_ioctl, /*mmap*/ dhahelper_mmap, /*open*/ dhahelper_open, /*flush*/ NULL, /*release*/ dhahelper_release, /* zero out the last 5 entries too ? */ }; #else static struct file_operations dhahelper_fops = { owner: THIS_MODULE, ioctl: dhahelper_ioctl, open: dhahelper_open, release: dhahelper_release, llseek: dhahelper_lseek, read: dhahelper_read, write: dhahelper_write, mmap: dhahelper_mmap, }; #endif #ifdef CONFIG_DEVFS_FS #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) devfs_handle_t dha_devfsh; static int register_dev(void) { dha_devfsh = devfs_register(NULL, "dhahelper", DEVFS_FL_NONE, dhahelper_major, 0, S_IFCHR | S_IRUSR | S_IWUSR, &dhahelper_fops, NULL); if(!dha_devfsh) return -EIO; return 0; } static void unregister_dev(void) { devfs_unregister(dha_devfsh); } #else /* VERSION < 2.6.0 */ static int register_dev(void) { devfs_mk_cdev(MKDEV(dhahelper_major, 0), S_IFCHR | S_IRUSR | S_IWUSR, "dhahelper"); if(register_chrdev(dhahelper_major, "dhahelper", &dhahelper_fops)) return -EIO; return 0; } static void unregister_dev(void) { devfs_remove("dhahelper"); unregister_chrdev(dhahelper_major, "dhahelper"); } #endif /* VERSION < 2.6.0 */ #else static int register_dev(void) { return register_chrdev(dhahelper_major, "dhahelper", &dhahelper_fops); } static void unregister_dev(void) { unregister_chrdev(dhahelper_major, "dhahelper"); } #endif /* defined CONFIG_DEVFS_FS */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) int init_module(void) #else static int __init init_dhahelper(void) #endif { int err = 0; printk(KERN_INFO "Direct Hardware Access kernel helper (C) Alex Beregszaszi\n"); err = register_dev(); if(err){ if (dhahelper_verbosity > 0) printk(KERN_ERR "dhahelper: unable to register character device (major: %d)\n", dhahelper_major); return err; } memset(dha_irqs, 0, sizeof(dha_irqs)); return 0; } #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) void cleanup_module(void) #else static void __exit exit_dhahelper(void) #endif { unsigned i; for(i=0;i<256;i++) if(dha_irqs[i].handled) free_irq(i, dha_irqs[i].dev); unregister_dev(); } #ifdef EXPORT_NO_SYMBOLS EXPORT_NO_SYMBOLS; #endif #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) module_init(init_dhahelper); module_exit(exit_dhahelper); #endif xine-lib-1.2/contrib/libdha/kernelhelper/Makefile.am0000644000175000017500000000250614647725151020265 0ustar memeinclude $(top_srcdir)/misc/Makefile.common EXTRA_DIST = README dhahelper.c KCFLAGS = -O2 -Wall -D__KERNEL__ -DMODULE -include `echo $(LINUX_INCLUDE) | sed -e 's/\-I//g'`/linux/modversions.h KVERSION = $(shell $(SHELL) -c 'uname -r') moddir = /lib/modules/$(KVERSION)/misc KCOMPILE = $(CC) $(CFLAGS) $(KCFLAGS) $(AM_CPPFLAGS) $(LINUX_INCLUDE) if HAVE_LINUX KERNEL_MODULE = dhahelper.o endif noinst_HEADERS = dhahelper.h EXTRA_PROGRAMS = test test_SOURCES = test.c dhahelper.o: $(KCOMPILE) -c `test -f $*.c || echo '$(srcdir)/'`$*.c nodes: $(MKNOD) -m 666 /dev/dhahelper c 252 0 all: $(KERNEL_MODULE) install-exec-local: $(KERNEL_MODULE) @$(NORMAL_INSTALL) $(mkinstalldirs) $(DESTDIR)$(moddir) @list='$(KERNEL_MODULE)'; \ for p in $$list; do \ if test -f $$p; then \ echo "$(INSTALL) -o root -g root -m 644 $$p $(DESTDIR)$(moddir)/$$p"; \ $(INSTALL) -o root -g root -m 644 $$p $(DESTDIR)$(moddir)/$$p; \ else :; fi; \ done; \ $(DEPMOD) -a if test ! -c /dev/dhahelper; then \ $(MAKE) nodes; \ fi uninstall-local: @$(NORMAL_UNINSTALL) @list='$(KERNEL_MODULE)'; \ for p in $$list; do \ echo "rm -f $(DESTDIR)$(moddir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ rm -f $(DESTDIR)$(moddir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ done xine-lib-1.2/contrib/libdha/kernelhelper/test.c0000644000175000017500000000147314647725151017356 0ustar meme#include #include #include #include #include #include #include #include #include "dhahelper.h" int main(int argc, char *argv[]) { int fd; int ret; fd = open("/dev/dhahelper", O_RDWR); if(fd < 0){ perror("dev/dhahelper"); exit(1); } ioctl(fd, DHAHELPER_GET_VERSION, &ret); printf("api version: %d\n", ret); if (ret != API_VERSION) printf("incompatible api!\n"); { void *mem; unsigned long size=256; mem = mmap(0,size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); printf("allocated to %p\n", mem); if (argc > 1) if (mem != 0) { int i; for (i = 0; i < 256; i++) printf("[%x] ", *(int *)(mem+i)); printf("\n"); } munmap((void *)mem, size); } return(0); } xine-lib-1.2/contrib/libdha/kernelhelper/README0000644000175000017500000000240614647725152017111 0ustar memedhahelper is small driver to provide some kernel function into userspace. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The main reason you need to use dhahelper is for busmastering. (Btw, lacking of possibility to implement conversion of virtual addresses into physical in userspace caused implementing of so-called DRM drivers for Linux from XFree86 side). Second goal (still is unfinished) - provide possibility to control port and physical memory access through groups and access rights of this driver. (Unix way). Installation: ~~~~~~~~~~~~~ just type in this directory: make all install The device node /dev/dhahelper will be created. The initial permissions of this node are restrictive. See below for information on how to make it available to non-root users. Porting: ~~~~~~~~ This driver was developed only for Linux. So if someone will port that on other unices then any patches are gladly accepted. WARNING: ~~~~~~~~ This driver violates some kernel security rules. To keep this driver from anonymous access I suggest you create a new group (e.g. dha) for /dev/dhahelper and set the permissions to 660 (or ug+rw,o-rw). Then do one of the following: - add trusted users to group dha. - make trusted applications SGID to dha. Good luck! xine-lib-1.2/contrib/libdha/.hgignore0000644000175000017500000000012414647725151015346 0ustar meme.libs .deps *.lo *.la pci_dev_ids.c pci_ids.h pci_names.c pci_names.h pci_vendors.h xine-lib-1.2/contrib/libdha/mtrr.c0000644000175000017500000000402414647725151014676 0ustar meme/* mtrr.c - Stuff for optimizing memory access Copyrights: 2002 - Linux version by Nick Kurshev Licence: GPL */ #include "config.h" #include #include #include #include #include #include #include "kernelhelper/dhahelper.h" #include "libdha.h" #if defined (__i386__) && defined (__NetBSD__) #include #if __NetBSD_Version__ > 105240000 #include #include #include #include #endif #endif int mtrr_set_type(unsigned base,unsigned size,int type) { int dhahelper_fd; dhahelper_fd = open("/dev/dhahelper",O_RDWR); if(dhahelper_fd > 0) { int retval; dhahelper_mtrr_t mtrrs; mtrrs.operation = MTRR_OP_ADD; mtrrs.start = base; mtrrs.size = size; mtrrs.type = type; retval = ioctl(dhahelper_fd, DHAHELPER_ACK_IRQ, &mtrrs); close(dhahelper_fd); return retval; } #if defined (__NetBSD__) && (__NetBSD_Version__) > 105240000 { struct mtrr *mtrrp; int n; mtrrp = malloc(sizeof (struct mtrr)); mtrrp->base = base; mtrrp->len = size; mtrrp->type = type; mtrrp->flags = MTRR_VALID | MTRR_PRIVATE; n = 1; if (i386_set_mtrr(mtrrp, &n) < 0) { free(mtrrp); return errno; } free(mtrrp); return 0; } #else { FILE * mtrr_fd; const char * stype; switch(type) { case MTRR_TYPE_UNCACHABLE: stype = "uncachable"; break; case MTRR_TYPE_WRCOMB: stype = "write-combining"; break; case MTRR_TYPE_WRTHROUGH: stype = "write-through"; break; case MTRR_TYPE_WRPROT: stype = "write-protect"; break; case MTRR_TYPE_WRBACK: stype = "write-back"; break; default: return EINVAL; } mtrr_fd = fopen("/proc/mtrr","wt"); if(mtrr_fd) { char sout[256]; unsigned wr_len; sprintf(sout,"base=0x%08X size=0x%08X type=%s\n",base,size,stype); wr_len = fprintf(mtrr_fd,"%s",sout); /*printf("MTRR: %s\n",sout);*/ fclose(mtrr_fd); return wr_len == strlen(sout) ? 0 : EPERM; } } #endif return ENOSYS; } xine-lib-1.2/contrib/libdha/AsmMacros.h0000644000175000017500000001062114647725151015604 0ustar meme/* $XConsortium: AsmMacros.h /main/13 1996/10/25 11:33:12 kaleb $ */ /* * (c) Copyright 1993,1994 by David Wexelblat * * 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 * DAVID WEXELBLAT 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. * * Except as contained in this notice, the name of David Wexelblat shall not be * used in advertising or otherwise to promote the sale, use or other dealings * in this Software without prior written authorization from David Wexelblat. * */ /* * Copyright 1997 * Digital Equipment Corporation. All rights reserved. * This software is furnished under license and may be used and copied only in * accordance with the following terms and conditions. Subject to these * conditions, you may download, copy, install, use, modify and distribute * this software in source and/or binary form. No title or ownership is * transferred hereby. * * 1) Any source code used, modified or distributed must reproduce and retain * this copyright notice and list of conditions as they appear in the source * file. * * 2) No right is granted to use any trade name, trademark, or logo of Digital * Equipment Corporation. Neither the "Digital Equipment Corporation" name * nor any trademark or logo of Digital Equipment Corporation may be used * to endorse or promote products derived from this software without the * prior written permission of Digital Equipment Corporation. * * 3) This software is provided "AS-IS" and any express or implied warranties, * including but not limited to, any implied warranties of merchantability, * fitness for a particular purpose, or non-infringement are disclaimed. In * no event shall DIGITAL be liable for any damages whatsoever, and in * particular, DIGITAL shall not be liable for special, indirect, * consequential, or incidental damages or damages for * lost profits, loss of revenue or loss of use, whether such damages arise * in contract, * negligence, tort, under statute, in equity, at law or otherwise, even if * advised of the possibility of such damage. * */ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/chips/util/AsmMacros.h,v 1.1 2001/11/16 21:13:34 tsi Exp $ */ /* * Modified for readability by Nick Kurshev */ #if defined(__GNUC__) || defined(__ICC) #if defined(__alpha__) #include "sysdep/AsmMacros_alpha.h" #elif defined(__ia64__) #include "sysdep/AsmMacros_ia64.h" #elif defined(__sparc__) #include "sysdep/AsmMacros_sparc.h" #elif defined( __arm32__ ) #include "sysdep/AsmMacros_arm32.h" #elif defined(__powerpc__) #include "sysdep/AsmMacros_powerpc.h" #elif defined (__i386__) #include "sysdep/AsmMacros_x86.h" #else #include "sysdep/AsmMacros_generic.h" #endif #else /* __GNUC__ */ #if defined(_MINIX) && defined(_ACK) /* inb, outb, inw and outw are defined in the library */ /* ... but I've no idea if the same is true for inl & outl */ extern u8_t inb(U16_t); extern void outb(U16_t, U8_t); extern u16_t inw(U16_t); extern void outw(U16_t, U16_t); extern u32_t inl(U16_t); extern void outl(U16_t, U32_t); #else /* not _MINIX and _ACK */ # if defined(__STDC__) && (__STDC__ == 1) # ifndef NCR # define asm __asm # endif # endif # ifdef SVR4 # include # ifndef __USLC__ # define __USLC__ # endif # endif #ifndef SCO325 # include #else # include "../common/scoasm.h" #endif #define intr_disable() asm("cli") #define intr_enable() asm("sti") #endif /* _MINIX and _ACK */ #endif /* __GNUC__ */ xine-lib-1.2/contrib/libmpcdec/0000755000175000017500000000000014647725152014246 5ustar memexine-lib-1.2/contrib/libmpcdec/streaminfo.c0000644000175000017500000002204614647725152016565 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file streaminfo.c /// Implementation of streaminfo reading functions. #include #include static const char * Stringify(mpc_uint32_t profile) // profile is 0...15, where 7...13 is used { static const char na[] = "n.a."; static const char *Names[] = { na, "'Unstable/Experimental'", na, na, na, "'quality 0'", "'quality 1'", "'Telephone'", "'Thumb'", "'Radio'", "'Standard'", "'Xtreme'", "'Insane'", "'BrainDead'", "'quality 9'", "'quality 10'" }; return profile >= sizeof(Names) / sizeof(*Names) ? na : Names[profile]; } void mpc_streaminfo_init(mpc_streaminfo * si) { memset(si, 0, sizeof(mpc_streaminfo)); } /// Reads streaminfo from SV7 header. static mpc_int32_t streaminfo_read_header_sv7(mpc_streaminfo * si, mpc_uint32_t HeaderData[8]) { const mpc_int32_t samplefreqs[4] = { 44100, 48000, 37800, 32000 }; //mpc_uint32_t HeaderData [8]; mpc_uint16_t Estimatedpeak_title = 0; if (si->stream_version > 0x71) { // Update (si->stream_version); return 0; } /* if ( !fp->seek ( si->header_position ) ) // seek to header start return ERROR_CODE_FILE; if ( fp->read ( HeaderData, sizeof HeaderData) != sizeof HeaderData ) return ERROR_CODE_FILE; */ si->bitrate = 0; si->frames = HeaderData[1]; si->is = 0; si->ms = (HeaderData[2] >> 30) & 0x0001; si->max_band = (HeaderData[2] >> 24) & 0x003F; si->block_size = 1; si->profile = (HeaderData[2] << 8) >> 28; si->profile_name = Stringify(si->profile); si->sample_freq = samplefreqs[(HeaderData[2] >> 16) & 0x0003]; Estimatedpeak_title = (mpc_uint16_t) (HeaderData[2] & 0xFFFF); // read the ReplayGain data si->gain_title = (mpc_uint16_t) ((HeaderData[3] >> 16) & 0xFFFF); si->peak_title = (mpc_uint16_t) (HeaderData[3] & 0xFFFF); si->gain_album = (mpc_uint16_t) ((HeaderData[4] >> 16) & 0xFFFF); si->peak_album = (mpc_uint16_t) (HeaderData[4] & 0xFFFF); si->is_true_gapless = (HeaderData[5] >> 31) & 0x0001; // true gapless: used? si->last_frame_samples = (HeaderData[5] >> 20) & 0x07FF; // true gapless: valid samples for last frame si->fast_seek = (HeaderData[5] >> 19) & 0x0001; // fast seeking si->encoder_version = (HeaderData[6] >> 24) & 0x00FF; if (si->encoder_version == 0) { sprintf(si->encoder, "Buschmann 1.7.0...9, Klemm 0.90...1.05"); } else { switch (si->encoder_version % 10) { case 0: sprintf(si->encoder, "Release %u.%u", si->encoder_version / 100, si->encoder_version / 10 % 10); break; case 2: case 4: case 6: case 8: sprintf(si->encoder, "Beta %u.%02u", si->encoder_version / 100, si->encoder_version % 100); break; default: sprintf(si->encoder, "--Alpha-- %u.%02u", si->encoder_version / 100, si->encoder_version % 100); break; } } #if 0 if ( si->peak_title == 0 ) // there is no correct peak_title contained within header si->peak_title = (mpc_uint16_t)(Estimatedpeak_title * 1.18); if ( si->peak_album == 0 ) si->peak_album = si->peak_title; // no correct peak_album, use peak_title si->sample_freq = 44100; // AB: used by all files up to SV7 #else (void)Estimatedpeak_title; #endif si->channels = 2; return ERROR_CODE_OK; } // read information from SV4-SV6 header #ifdef MPC_SUPPORT_SV456 static mpc_int32_t streaminfo_read_header_sv6(mpc_streaminfo * si, mpc_uint32_t HeaderData[8]) { //mpc_uint32_t HeaderData [8]; /* if ( !fp->seek ( si->header_position ) ) // seek to header start return ERROR_CODE_FILE; if ( fp->read ( HeaderData, sizeof HeaderData ) != sizeof HeaderData ) return ERROR_CODE_FILE; */ si->bitrate = (HeaderData[0] >> 23) & 0x01FF; // read the file-header (SV6 and below) si->is = (HeaderData[0] >> 22) & 0x0001; si->ms = (HeaderData[0] >> 21) & 0x0001; si->stream_version = (HeaderData[0] >> 11) & 0x03FF; si->max_band = (HeaderData[0] >> 6) & 0x001F; si->block_size = (HeaderData[0]) & 0x003F; si->profile = 0; si->profile_name = Stringify((mpc_uint32_t) (-1)); if (si->stream_version >= 5) si->frames = HeaderData[1]; // 32 bit else si->frames = (HeaderData[1] >> 16); // 16 bit si->gain_title = 0; // not supported si->peak_title = 0; si->gain_album = 0; si->peak_album = 0; si->last_frame_samples = 0; si->is_true_gapless = 0; si->encoder_version = 0; si->encoder[0] = '\0'; if (si->stream_version == 7) return ERROR_CODE_SV7BETA; // are there any unsupported parameters used? if (si->bitrate != 0) return ERROR_CODE_CBR; if (si->is != 0) return ERROR_CODE_IS; if (si->block_size != 1) return ERROR_CODE_BLOCKSIZE; if (si->stream_version < 6) // Bugfix: last frame was invalid for up to SV5 si->frames -= 1; si->sample_freq = 44100; // AB: used by all files up to SV7 si->channels = 2; if (si->stream_version < 4 || si->stream_version > 7) return ERROR_CODE_INVALIDSV; return ERROR_CODE_OK; } #endif // reads file header and tags mpc_int32_t mpc_streaminfo_read(mpc_streaminfo * si, mpc_reader * r) { mpc_uint32_t HeaderData[8]; mpc_int32_t Error = 0; // get header position if ((si->header_position = JumpID3v2(r)) < 0) { return ERROR_CODE_FILE; } // seek to first byte of mpc data if (!r->seek(r->data, si->header_position)) { return ERROR_CODE_FILE; } if (r->read(r->data, HeaderData, 8 * 4) != 8 * 4) { return ERROR_CODE_FILE; } if (!r->seek(r->data, si->header_position + 6 * 4)) { return ERROR_CODE_FILE; } si->total_file_length = r->get_size(r->data); si->tag_offset = si->total_file_length; if (memcmp(HeaderData, "MP+", 3)) return ERROR_CODE_INVALIDSV; #ifndef MPC_LITTLE_ENDIAN { mpc_uint32_t ptr; for (ptr = 0; ptr < 8; ptr++) { HeaderData[ptr] = mpc_swap32(HeaderData[ptr]); } } #endif si->stream_version = HeaderData[0] >> 24; // stream version 8 if ((si->stream_version & 15) >= 8) { return ERROR_CODE_INVALIDSV; } // stream version 7 else if ((si->stream_version & 15) == 7) { Error = streaminfo_read_header_sv7(si, HeaderData); if (Error != ERROR_CODE_OK) return Error; } #ifdef MPC_SUPPORT_SV456 else { // stream version 4-6 Error = streaminfo_read_header_sv6(si, HeaderData); if (Error != ERROR_CODE_OK) return Error; } #endif // estimation, exact value needs too much time si->pcm_samples = 1152 * si->frames - 576; if (si->pcm_samples > 0) { si->average_bitrate = (si->tag_offset - si->header_position) * 8.0 * si->sample_freq / si->pcm_samples; } else { si->average_bitrate = 0; } return ERROR_CODE_OK; } double mpc_streaminfo_get_length(mpc_streaminfo * si) { return (double)mpc_streaminfo_get_length_samples(si) / (double)si->sample_freq; } mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo * si) { mpc_int64_t samples = (mpc_int64_t) si->frames * MPC_FRAME_LENGTH; if (si->is_true_gapless) { samples -= (MPC_FRAME_LENGTH - si->last_frame_samples); } else { samples -= MPC_DECODER_SYNTH_DELAY; } return samples; } xine-lib-1.2/contrib/libmpcdec/mpcdec/0000755000175000017500000000000014647725152015501 5ustar memexine-lib-1.2/contrib/libmpcdec/mpcdec/reader.h0000644000175000017500000000566714647725152017132 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file reader.h #ifndef _mpcdec_reader_h_ #define _mpcdec_reader_h_ /// \brief Stream reader interface structure. /// /// This is the structure you must supply to the musepack decoding library /// to feed it with raw data. Implement the five member functions to provide /// a functional reader. typedef struct mpc_reader_t { /// Reads size bytes of data into buffer at ptr. mpc_int32_t (*read)(void *t, void *ptr, mpc_int32_t size); /// Seeks to byte position offset. mpc_bool_t (*seek)(void *t, mpc_int32_t offset); /// Returns the current byte offset in the stream. mpc_int32_t (*tell)(void *t); /// Returns the total length of the source stream, in bytes. mpc_int32_t (*get_size)(void *t); /// True if the stream is a seekable stream. mpc_bool_t (*canseek)(void *t); /// Field that can be used to identify a particular instance of /// reader or carry along data associated with that reader. void *data; } mpc_reader; typedef struct mpc_reader_file_t { mpc_reader reader; FILE *file; long file_size; mpc_bool_t is_seekable; } mpc_reader_file; /// Initializes reader with default stdio file reader implementation. Use /// this if you're just reading from a plain file. /// /// \param r reader struct to initalize /// \param input input stream to attach to the reader void mpc_reader_setup_file_reader(mpc_reader_file *r, FILE *input); #endif // _mpcdec_reader_h_ xine-lib-1.2/contrib/libmpcdec/mpcdec/internal.h0000644000175000017500000000477314647725152017501 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file internal.h /// Definitions and structures used only internally by the libmpcdec. #ifndef _mpcdec_internal_h #define _mpcdec_internal_h enum { MPC_DECODER_SYNTH_DELAY = 481 }; /// Big/little endian 32 bit byte swapping routine. static __inline mpc_uint32_t mpc_swap32(mpc_uint32_t val) { return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); } /// Searches for a ID3v2-tag and reads the length (in bytes) of it. /// \param reader supplying raw stream data /// \return size of tag, in bytes /// \return -1 on errors of any kind mpc_int32_t JumpID3v2(mpc_reader* fp); /// helper functions used by multiple files mpc_uint32_t mpc_random_int(mpc_decoder *d); // in synth_filter.c void mpc_decoder_initialisiere_quantisierungstabellen(mpc_decoder *d, double scale_factor); void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData); #endif // _mpcdec_internal_h xine-lib-1.2/contrib/libmpcdec/mpcdec/streaminfo.h0000644000175000017500000001005114647725152020016 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file streaminfo.h #ifndef _mpcdec_streaminfo_h_ #define _mpcdec_streaminfo_h_ typedef mpc_int32_t mpc_streaminfo_off_t; /// \brief mpc stream properties structure /// /// Structure containing all the properties of an mpc stream. Populated /// by the streaminfo_read function. typedef struct mpc_streaminfo { /// @name core mpc stream properties //@{ mpc_uint32_t sample_freq; ///< sample frequency of stream mpc_uint32_t channels; ///< number of channels in stream mpc_streaminfo_off_t header_position; ///< byte offset of position of header in stream mpc_uint32_t stream_version; ///< streamversion of stream mpc_uint32_t bitrate; ///< bitrate of stream file (in bps) double average_bitrate; ///< average bitrate of stream (in bits/sec) mpc_uint32_t frames; ///< number of frames in stream mpc_int64_t pcm_samples; mpc_uint32_t max_band; ///< maximum band-index used in stream (0...31) mpc_uint32_t is; ///< intensity stereo (0: off, 1: on) mpc_uint32_t ms; ///< mid/side stereo (0: off, 1: on) mpc_uint32_t block_size; ///< only needed for SV4...SV6 -> not supported mpc_uint32_t profile; ///< quality profile of stream const char* profile_name; ///< name of profile used by stream //@} /// @name replaygain related fields //@{ mpc_int16_t gain_title; ///< replaygain title value mpc_int16_t gain_album; ///< replaygain album value mpc_uint16_t peak_album; ///< peak album loudness level mpc_uint16_t peak_title; ///< peak title loudness level //@} /// @name true gapless support data //@{ mpc_uint32_t is_true_gapless; ///< true gapless? (0: no, 1: yes) mpc_uint32_t last_frame_samples; ///< number of valid samples within last frame mpc_uint32_t encoder_version; ///< version of encoder used char encoder[256]; ///< encoder name mpc_streaminfo_off_t tag_offset; ///< offset to file tags mpc_streaminfo_off_t total_file_length; ///< total length of underlying file //@} /// @name fast seeking support //@{ mpc_uint32_t fast_seek; ///< support fast seeking ? (0: no, 1: yes) //@} } mpc_streaminfo; #endif // _mpcdec_streaminfo_h_ xine-lib-1.2/contrib/libmpcdec/mpcdec/math.h0000644000175000017500000001225514647725152016610 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file math.h /// Libmpcdec internal math routines. #ifndef _mpcdec_math_h_ #define _mpcdec_math_h_ //#define MPC_FIXED_POINT #define MPC_FIXED_POINT_SHIFT 16 #ifdef MPC_FIXED_POINT #ifdef _WIN32_WCE #include #define MPC_HAVE_MULHIGH #endif #define MPC_FIXED_POINT_SCALE_SHIFT (MPC_FIXED_POINT_SHIFT + MPC_FIXED_POINT_FRACTPART) #define MPC_FIXED_POINT_SCALE (1 << (MPC_FIXED_POINT_SCALE_SHIFT - 1)) //in fixedpoint mode, results in decode output buffer are in -MPC_FIXED_POINT_SCALE ... MPC_FIXED_POINT_SCALE range #define MPC_FIXED_POINT_FRACTPART 14 typedef mpc_int32_t MPC_SAMPLE_FORMAT; typedef mpc_int64_t MPC_SAMPLE_FORMAT_MULTIPLY; #define MAKE_MPC_SAMPLE(X) (MPC_SAMPLE_FORMAT)((double)(X) * (double)(((mpc_int64_t)1)<> MPC_FIXED_POINT_FRACTPART) #define MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z) \ (((MPC_SAMPLE_FORMAT_MULTIPLY)(X) * (MPC_SAMPLE_FORMAT_MULTIPLY)(Y)) >> (Z)) #ifdef _DEBUG static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2) { MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_NOTRUNCATE(item1,item2); assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); return (MPC_SAMPLE_FORMAT)temp; } static inline MPC_SAMPLE_FORMAT MPC_MULTIPLY_EX(MPC_SAMPLE_FORMAT item1,MPC_SAMPLE_FORMAT item2,unsigned shift) { MPC_SAMPLE_FORMAT_MULTIPLY temp = MPC_MULTIPLY_EX_NOTRUNCATE(item1,item2,shift); assert(temp == (MPC_SAMPLE_FORMAT_MULTIPLY)(MPC_SAMPLE_FORMAT)temp); return (MPC_SAMPLE_FORMAT)temp; } #else #define MPC_MULTIPLY(X,Y) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_NOTRUNCATE(X,Y)) #define MPC_MULTIPLY_EX(X,Y,Z) ((MPC_SAMPLE_FORMAT)MPC_MULTIPLY_EX_NOTRUNCATE(X,Y,Z)) #endif #ifdef MPC_HAVE_MULHIGH #define MPC_MULTIPLY_FRACT(X,Y) _MulHigh(X,Y) #else #define MPC_MULTIPLY_FRACT(X,Y) MPC_MULTIPLY_EX(X,Y,32) #endif #define MPC_MAKE_FRACT_CONST(X) (MPC_SAMPLE_FORMAT)((X) * (double)(((mpc_int64_t)1)<<32) ) #define MPC_MULTIPLY_FRACT_CONST(X,Y) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) #define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) ( MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) << (Z) ) #define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y / (1<<(Z)) )) #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) #define MPC_SCALE_CONST(X,Y,Z) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)) #define MPC_SCALE_CONST_SHL(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)-(S)) #define MPC_SCALE_CONST_SHR(X,Y,Z,S) MPC_MULTIPLY_EX(X,MAKE_MPC_SAMPLE_EX(Y,Z),(Z)+(S)) #define MPC_SHR(X,Y) ((X)>>(Y)) #define MPC_SHL(X,Y) ((X)<<(Y)) #else //in floating-point mode, decoded samples are in -1...1 range typedef float MPC_SAMPLE_FORMAT; #define MAKE_MPC_SAMPLE(X) ((MPC_SAMPLE_FORMAT)(X)) #define MAKE_MPC_SAMPLE_EX(X,Y) ((MPC_SAMPLE_FORMAT)(X)) #define MPC_MULTIPLY_FRACT(X,Y) ((X)*(Y)) #define MPC_MAKE_FRACT_CONST(X) (X) #define MPC_MULTIPLY_FRACT_CONST(X,Y) MPC_MULTPLY_FRACT(X,MPC_MAKE_FRACT_CONST(Y)) #define MPC_MULTIPLY_FRACT_CONST_SHR(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) #define MPC_MULTIPLY_FRACT_CONST_FIX(X,Y,Z) MPC_MULTIPLY_FRACT(X,MPC_MAKE_FRACT_CONST( Y )) #define MPC_MULTIPLY_FLOAT_INT(X,Y) ((X)*(Y)) #define MPC_MULTIPLY(X,Y) ((X)*(Y)) #define MPC_MULTIPLY_EX(X,Y,Z) ((X)*(Y)) #define MPC_SCALE_CONST(X,Y,Z) ((X)*(Y)) #define MPC_SCALE_CONST_SHL(X,Y,Z,S) ((X)*(Y)) #define MPC_SCALE_CONST_SHR(X,Y,Z,S) ((X)*(Y)) #define MPC_SHR(X,Y) (X) #define MPC_SHL(X,Y) (X) #endif #endif // _mpcdec_math_h_ xine-lib-1.2/contrib/libmpcdec/mpcdec/config_types.h0000644000175000017500000000360414647725152020346 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ #ifndef __MUSEPACK_CONFIG_TYPES_H__ #define __MUSEPACK_CONFIG_TYPES_H__ #include typedef unsigned char mpc_bool_t; #define TRUE 1 #define FALSE 0 typedef int16_t mpc_int16_t; typedef uint16_t mpc_uint16_t; typedef int32_t mpc_int32_t; typedef uint32_t mpc_uint32_t; typedef int64_t mpc_int64_t; #endif // __MUSEPACK_CONFIG_TYPES_H__ xine-lib-1.2/contrib/libmpcdec/mpcdec/mpcdec.h0000644000175000017500000001232614647725152017111 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file mpcdec.h /// Top level include file for libmpcdec. #ifndef _mpcdec_h_ #define _mpcdec_h_ #ifdef __cplusplus extern "C" { #endif #include #include #include #ifndef WIN32 #include "mpcdec/config_types.h" #else #include "mpcdec/config_win32.h" #endif #include "decoder.h" #include "math.h" #include "reader.h" #include "streaminfo.h" enum { MPC_FRAME_LENGTH = (36 * 32), /// samples per mpc frame MPC_DECODER_BUFFER_LENGTH = 4 * MPC_FRAME_LENGTH /// required buffer size for decoder }; // error codes #define ERROR_CODE_OK 0 #define ERROR_CODE_FILE -1 #define ERROR_CODE_SV7BETA 1 #define ERROR_CODE_CBR 2 #define ERROR_CODE_IS 3 #define ERROR_CODE_BLOCKSIZE 4 #define ERROR_CODE_INVALIDSV 5 /// Initializes a streaminfo structure. /// \param si streaminfo structure to initialize void mpc_streaminfo_init(mpc_streaminfo *si); /// Reads streaminfo header from the mpc stream supplied by r. /// \param si streaminfo pointer to which info will be written /// \param r stream reader to supply raw data /// \return error code mpc_int32_t mpc_streaminfo_read(mpc_streaminfo *si, mpc_reader *r); /// Gets length of stream si, in seconds. /// \return length of stream in seconds double mpc_streaminfo_get_length(mpc_streaminfo *si); /// Returns length of stream si, in samples. /// \return length of stream in samples mpc_int64_t mpc_streaminfo_get_length_samples(mpc_streaminfo *si); /// Sets up decoder library. /// Call this first when preparing to decode an mpc stream. /// \param r reader that will supply raw data to the decoder void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r); /// Initializes mpc decoder with the supplied stream info parameters. /// Call this next after calling mpc_decoder_setup. /// \param si streaminfo structure indicating format of source stream /// \return TRUE if decoder was initalized successfully, FALSE otherwise mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si); /// Call this next after calling mpc_decoder_setup. /// \param si streaminfo structure indicating format of source stream /// \param fast_seeking boolean 0 = use fast seeking if safe, 1 = force fast seeking void mpc_decoder_set_seeking(mpc_decoder *d, mpc_streaminfo *si, mpc_bool_t fast_seeking); void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si); /// Sets decoder sample scaling factor. All decoded samples will be multiplied /// by this factor. /// \param scale_factor multiplicative scaling factor void mpc_decoder_scale_output(mpc_decoder *d, double scale_factor); /// Actually reads data from previously initialized stream. Call /// this iteratively to decode the mpc stream. /// \param buffer destination buffer for decoded samples /// \param vbr_update_acc \todo document me /// \param vbr_update_bits \todo document me /// \return -1 if an error is encountered /// \return 0 if the stream has been completely decoded successfully and there are no more samples /// \return > 0 to indicate the number of bytes that were actually read from the stream. mpc_uint32_t mpc_decoder_decode( mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer, mpc_uint32_t *vbr_update_acc, mpc_uint32_t *vbr_update_bits); mpc_uint32_t mpc_decoder_decode_frame( mpc_decoder *d, mpc_uint32_t *in_buffer, mpc_uint32_t in_len, MPC_SAMPLE_FORMAT *out_buffer); /// Seeks to the specified sample in the source stream. mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample); /// Seeks to specified position in seconds in the source stream. mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds); #ifdef __cplusplus } #endif // __cplusplus #endif // _mpcdec_h_ xine-lib-1.2/contrib/libmpcdec/mpcdec/huffman.h0000644000175000017500000000401714647725152017300 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file huffman.h /// Data structures and functions for huffman coding. #ifndef _mpcdec_huffman_h_ #define _mpcdec_huffman_h_ #ifndef WIN32 #include "mpcdec/config_types.h" #else #include "mpcdec/config_win32.h" #endif #include "decoder.h" struct mpc_decoder_t; // forward declare to break circular dependencies /// Huffman table entry. typedef struct huffman_type_t { mpc_uint32_t Code; mpc_uint16_t Length; mpc_int16_t Value; } HuffmanTyp; #endif // _mpcdec_huffman_h_ xine-lib-1.2/contrib/libmpcdec/mpcdec/requant.h0000644000175000017500000000403414647725152017332 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file requant.h /// Requantization function definitions. #ifndef _mpcdec_requant_h_ #define _mpcdec_requant_h_ #include "mpcdec.h" /* C O N S T A N T S */ extern const mpc_uint32_t Res_bit [18]; // bits per sample for chosen quantizer extern const MPC_SAMPLE_FORMAT __Cc [1 + 18]; // coefficients for requantization extern const mpc_int32_t __Dc [1 + 18]; // offset for requantization #define Cc (__Cc + 1) #define Dc (__Dc + 1) #endif // _mpcdec_requant_h_ xine-lib-1.2/contrib/libmpcdec/mpcdec/decoder.h0000644000175000017500000001055114647725152017261 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file decoder.h #ifndef _mpcdec_decoder_h_ #define _mpcdec_decoder_h_ #include "huffman.h" #include "math.h" #include "mpcdec.h" #include "reader.h" #include "streaminfo.h" #define MPC_SUPPORT_SV456 #define SEEKING_TABLE_SIZE 256u // set it to SLOW_SEEKING_WINDOW to not use fast seeking #define FAST_SEEKING_WINDOW 32 // set it to FAST_SEEKING_WINDOW to only use fast seeking #define SLOW_SEEKING_WINDOW 0x80000000 enum { MPC_V_MEM = 2304, MPC_DECODER_MEMSIZE = 16384, // overall buffer size }; typedef struct { mpc_int32_t L [36]; mpc_int32_t R [36]; } QuantTyp; typedef struct mpc_decoder_t { mpc_reader *r; /// @name internal state variables //@{ mpc_uint32_t dword; /// currently decoded 32bit-word mpc_uint32_t pos; /// bit-position within dword mpc_uint32_t Speicher[MPC_DECODER_MEMSIZE]; /// read-buffer mpc_uint32_t Zaehler; /// actual index within read-buffer mpc_uint32_t samples_to_skip; mpc_uint32_t DecodedFrames; mpc_uint32_t OverallFrames; mpc_int32_t SampleRate; // Sample frequency mpc_uint32_t StreamVersion; // version of bitstream mpc_int32_t Max_Band; mpc_uint32_t MPCHeaderPos; // AB: needed to support ID3v2 mpc_uint32_t FrameWasValid; mpc_uint32_t MS_used; // MS-coding used ? mpc_uint32_t TrueGaplessPresent; mpc_uint32_t WordsRead; // counts amount of decoded dwords // randomizer state variables mpc_uint32_t __r1; mpc_uint32_t __r2; // seeking mpc_uint32_t seeking_table[SEEKING_TABLE_SIZE]; mpc_uint32_t seeking_pwr; // distance between 2 frames in seeking_table = 2^seeking_pwr mpc_uint32_t seeking_table_frames; // last frame in seaking table mpc_uint32_t seeking_window; // number of frames to look for scalefactors mpc_int32_t SCF_Index_L [32] [3]; mpc_int32_t SCF_Index_R [32] [3]; // holds scalefactor-indices QuantTyp Q [32]; // holds quantized samples mpc_int32_t Res_L [32]; mpc_int32_t Res_R [32]; // holds the chosen quantizer for each subband mpc_bool_t DSCF_Flag_L [32]; mpc_bool_t DSCF_Flag_R [32]; // differential SCF used? mpc_int32_t SCFI_L [32]; mpc_int32_t SCFI_R [32]; // describes order of transmitted SCF mpc_bool_t MS_Flag[32]; // MS used? #ifdef MPC_FIXED_POINT unsigned char SCF_shift[256]; #endif MPC_SAMPLE_FORMAT V_L[MPC_V_MEM + 960]; MPC_SAMPLE_FORMAT V_R[MPC_V_MEM + 960]; MPC_SAMPLE_FORMAT Y_L[36][32]; MPC_SAMPLE_FORMAT Y_R[36][32]; MPC_SAMPLE_FORMAT SCF[256]; ///< holds adapted scalefactors (for clipping prevention) //@} } mpc_decoder; #endif // _mpc_decoder_h xine-lib-1.2/contrib/libmpcdec/mpc_decoder.c0000644000175000017500000013435214647725152016666 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file mpc_decoder.c /// Core decoding routines and logic. #include #include #include #include //SV7 tables extern const HuffmanTyp* mpc_table_HuffQ [2] [8]; extern const HuffmanTyp mpc_table_HuffHdr [10]; extern const HuffmanTyp mpc_table_HuffSCFI [ 4]; extern const HuffmanTyp mpc_table_HuffDSCF [16]; #ifdef MPC_SUPPORT_SV456 //SV4/5/6 tables extern const HuffmanTyp* mpc_table_SampleHuff [18]; extern const HuffmanTyp mpc_table_SCFI_Bundle [ 8]; extern const HuffmanTyp mpc_table_DSCF_Entropie [13]; extern const HuffmanTyp mpc_table_Region_A [16]; extern const HuffmanTyp mpc_table_Region_B [ 8]; extern const HuffmanTyp mpc_table_Region_C [ 4]; #endif #ifndef MPC_LITTLE_ENDIAN #define SWAP(X) mpc_swap32(X) #else #define SWAP(X) (X) #endif //------------------------------------------------------------------------------ // types //------------------------------------------------------------------------------ enum { EQ_TAP = 13, // length of FIR filter for EQ DELAY = ((EQ_TAP + 1) / 2), // delay of FIR FIR_BANDS = 4, // number of subbands to be FIR filtered MEMSIZE = MPC_DECODER_MEMSIZE, // overall buffer size MEMSIZE2 = (MEMSIZE/2), // size of one buffer MEMMASK = (MEMSIZE-1) }; //------------------------------------------------------------------------------ // forward declarations //------------------------------------------------------------------------------ void mpc_decoder_read_bitstream_sv6(mpc_decoder *d, mpc_bool_t seeking); void mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t seeking); mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample); void mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band); //------------------------------------------------------------------------------ // utility functions //------------------------------------------------------------------------------ static mpc_int32_t f_read(mpc_decoder *d, void *ptr, mpc_int32_t size) { return d->r->read(d->r->data, ptr, size); } static mpc_bool_t f_seek(mpc_decoder *d, mpc_int32_t offset) { return d->r->seek(d->r->data, offset); } static mpc_int32_t f_read_dword(mpc_decoder *d, mpc_uint32_t * ptr, mpc_uint32_t count) { return f_read(d, ptr, count << 2) >> 2; } static void mpc_decoder_seek(mpc_decoder *d, mpc_uint32_t bitpos) { f_seek(d, (bitpos>>5) * 4 + d->MPCHeaderPos); f_read_dword(d, d->Speicher, MEMSIZE); d->dword = SWAP(d->Speicher[d->Zaehler = 0]); d->pos = bitpos & 31; d->WordsRead = bitpos >> 5; } // jump desired number of bits out of the bitstream static void mpc_decoder_bitstream_jump(mpc_decoder *d, const mpc_uint32_t bits) { d->pos += bits; if (d->pos >= 32) { d->Zaehler = (d->Zaehler + (d->pos >> 5)) & MEMMASK; d->dword = SWAP(d->Speicher[d->Zaehler]); d->WordsRead += d->pos >> 5; d->pos &= 31; } } static void mpc_decoder_update_buffer(mpc_decoder *d, mpc_uint32_t RING) { if ((RING ^ d->Zaehler) & MEMSIZE2 ) { // update buffer f_read_dword(d, d->Speicher + (RING & MEMSIZE2), MEMSIZE2); } } //------------------------------------------------------------------------------ // huffman & bitstream functions //------------------------------------------------------------------------------ /* F U N C T I O N S */ // resets bitstream decoding static void mpc_decoder_reset_bitstream_decode(mpc_decoder *d) { d->dword = 0; d->pos = 0; d->Zaehler = 0; d->WordsRead = 0; } // reports the number of read bits static mpc_uint32_t mpc_decoder_bits_read(mpc_decoder *d) { return 32 * d->WordsRead + d->pos; } // read desired number of bits out of the bitstream (max 31) static mpc_uint32_t mpc_decoder_bitstream_read(mpc_decoder *d, const mpc_uint32_t bits) { mpc_uint32_t out = d->dword; d->pos += bits; if (d->pos < 32) { out >>= (32 - d->pos); } else { d->dword = SWAP(d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]); d->pos -= 32; if (d->pos) { out <<= d->pos; out |= d->dword >> (32 - d->pos); } d->WordsRead++; } return out & ((1 << bits) - 1); } // basic huffman decoding routine // works with maximum lengths up to max_length static mpc_int32_t mpc_decoder_huffman_decode(mpc_decoder *d, const HuffmanTyp *Table, const mpc_uint32_t max_length) { // load preview and decode mpc_uint32_t code = d->dword << d->pos; if (32 - d->pos < max_length) code |= SWAP(d->Speicher[(d->Zaehler + 1) & MEMMASK]) >> (32 - d->pos); while (code < Table->Code) Table++; // set the new position within bitstream without performing a dummy-read if ((d->pos += Table->Length) >= 32) { d->pos -= 32; d->dword = SWAP(d->Speicher[d->Zaehler = (d->Zaehler + 1) & MEMMASK]); d->WordsRead++; } return Table->Value; } // decode SCFI-bundle (sv4,5,6) static void mpc_decoder_scfi_bundle_read(mpc_decoder *d, const HuffmanTyp* Table, mpc_int32_t* SCFI, mpc_bool_t* DSCF) { mpc_uint32_t value = mpc_decoder_huffman_decode(d, Table, 6); *SCFI = value >> 1; *DSCF = value & 1; } static void mpc_decoder_reset_v(mpc_decoder *d) { memset(d->V_L, 0, sizeof d->V_L); memset(d->V_R, 0, sizeof d->V_R); } static void mpc_decoder_reset_synthesis(mpc_decoder *d) { mpc_decoder_reset_v(d); } static void mpc_decoder_reset_y(mpc_decoder *d) { memset(d->Y_L, 0, sizeof d->Y_L); memset(d->Y_R, 0, sizeof d->Y_R); } static void mpc_decoder_reset_globals(mpc_decoder *d) { mpc_decoder_reset_bitstream_decode(d); d->DecodedFrames = 0; d->StreamVersion = 0; d->MS_used = 0; memset(d->Y_L , 0, sizeof d->Y_L ); memset(d->Y_R , 0, sizeof d->Y_R ); memset(d->SCF_Index_L , 0, sizeof d->SCF_Index_L ); memset(d->SCF_Index_R , 0, sizeof d->SCF_Index_R ); memset(d->Res_L , 0, sizeof d->Res_L ); memset(d->Res_R , 0, sizeof d->Res_R ); memset(d->SCFI_L , 0, sizeof d->SCFI_L ); memset(d->SCFI_R , 0, sizeof d->SCFI_R ); memset(d->DSCF_Flag_L , 0, sizeof d->DSCF_Flag_L ); memset(d->DSCF_Flag_R , 0, sizeof d->DSCF_Flag_R ); memset(d->Q , 0, sizeof d->Q ); memset(d->MS_Flag , 0, sizeof d->MS_Flag ); memset(d->seeking_table , 0, sizeof d->seeking_table ); } // Frame decoding. Takes big endian 32 bits words as input mpc_uint32_t mpc_decoder_decode_frame(mpc_decoder *d, mpc_uint32_t *in_buffer, mpc_uint32_t in_len, MPC_SAMPLE_FORMAT *out_buffer) { unsigned int i; mpc_decoder_reset_bitstream_decode(d); if (in_len > sizeof(d->Speicher)) in_len = sizeof(d->Speicher); memcpy(d->Speicher, in_buffer, in_len); for (i = 0; i < (in_len + 3) / 4; i++) d->Speicher[i] = mpc_swap32(d->Speicher[i]); d->dword = SWAP(d->Speicher[0]); switch (d->StreamVersion) { #ifdef MPC_SUPPORT_SV456 case 0x04: case 0x05: case 0x06: mpc_decoder_read_bitstream_sv6(d, FALSE); break; #endif case 0x07: case 0x17: mpc_decoder_read_bitstream_sv7(d, FALSE); break; default: return (mpc_uint32_t)(-1); } mpc_decoder_requantisierung(d, d->Max_Band); mpc_decoder_synthese_filter_float(d, out_buffer); return mpc_decoder_bits_read(d); } static mpc_uint32_t mpc_decoder_decode_internal(mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer) { mpc_uint32_t output_frame_length = MPC_FRAME_LENGTH; mpc_uint32_t FwdJumpInfo = 0; mpc_uint32_t FrameBitCnt = 0; if (d->DecodedFrames >= d->OverallFrames) { return (mpc_uint32_t)(-1); // end of file -> abort decoding } // add seeking info if (d->seeking_table_frames < d->DecodedFrames && (d->DecodedFrames & ((1 << d->seeking_pwr) - 1)) == 0) { d->seeking_table[d->DecodedFrames >> d->seeking_pwr] = mpc_decoder_bits_read(d); d->seeking_table_frames = d->DecodedFrames; } // read jump-info for validity check of frame FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); // decode data and check for validity of frame FrameBitCnt = mpc_decoder_bits_read(d); switch (d->StreamVersion) { #ifdef MPC_SUPPORT_SV456 case 0x04: case 0x05: case 0x06: mpc_decoder_read_bitstream_sv6(d, FALSE); break; #endif case 0x07: case 0x17: mpc_decoder_read_bitstream_sv7(d, FALSE); break; default: return (mpc_uint32_t)(-1); } d->FrameWasValid = mpc_decoder_bits_read(d) - FrameBitCnt == FwdJumpInfo; // synthesize signal mpc_decoder_requantisierung(d, d->Max_Band); mpc_decoder_synthese_filter_float(d, buffer); d->DecodedFrames++; // cut off first MPC_DECODER_SYNTH_DELAY zero-samples if (d->DecodedFrames == d->OverallFrames && d->StreamVersion >= 6) { // reconstruct exact filelength mpc_int32_t mod_block = mpc_decoder_bitstream_read(d, 11); mpc_int32_t FilterDecay; if (mod_block == 0) { // Encoder bugfix mod_block = 1152; } FilterDecay = (mod_block + MPC_DECODER_SYNTH_DELAY) % MPC_FRAME_LENGTH; // additional FilterDecay samples are needed for decay of synthesis filter if (MPC_DECODER_SYNTH_DELAY + mod_block >= MPC_FRAME_LENGTH) { if (!d->TrueGaplessPresent) { mpc_decoder_reset_y(d); } else { mpc_decoder_bitstream_read(d, 20); mpc_decoder_read_bitstream_sv7(d, FALSE); mpc_decoder_requantisierung(d, d->Max_Band); } mpc_decoder_synthese_filter_float(d, buffer + 2304); output_frame_length = MPC_FRAME_LENGTH + FilterDecay; } else { // there are only FilterDecay samples needed for this frame output_frame_length = FilterDecay; } } if (d->samples_to_skip) { if (output_frame_length < d->samples_to_skip) { d->samples_to_skip -= output_frame_length; output_frame_length = 0; } else { output_frame_length -= d->samples_to_skip; memmove( buffer, buffer + d->samples_to_skip * 2, output_frame_length * 2 * sizeof (MPC_SAMPLE_FORMAT)); d->samples_to_skip = 0; } } return output_frame_length; } mpc_uint32_t mpc_decoder_decode( mpc_decoder *d, MPC_SAMPLE_FORMAT *buffer, mpc_uint32_t *vbr_update_acc, mpc_uint32_t *vbr_update_bits) { for(;;) { //const mpc_int32_t MaxBrokenFrames = 0; // PluginSettings.MaxBrokenFrames mpc_uint32_t RING = d->Zaehler; mpc_int32_t vbr_ring = (RING << 5) + d->pos; mpc_uint32_t valid_samples = mpc_decoder_decode_internal(d, buffer); if (valid_samples == (mpc_uint32_t)(-1) ) { return 0; } /**************** ERROR CONCEALMENT *****************/ if (d->FrameWasValid == 0 ) { // error occurred in bitstream return (mpc_uint32_t)(-1); } else { if (vbr_update_acc && vbr_update_bits) { (*vbr_update_acc) ++; vbr_ring = (d->Zaehler << 5) + d->pos - vbr_ring; if (vbr_ring < 0) { vbr_ring += 524288; } (*vbr_update_bits) += vbr_ring; } } mpc_decoder_update_buffer(d, RING); if (valid_samples > 0) { return valid_samples; } } } void mpc_decoder_requantisierung(mpc_decoder *d, const mpc_int32_t Last_Band) { mpc_int32_t Band; mpc_int32_t n; MPC_SAMPLE_FORMAT facL; MPC_SAMPLE_FORMAT facR; MPC_SAMPLE_FORMAT templ; MPC_SAMPLE_FORMAT tempr; MPC_SAMPLE_FORMAT* YL; MPC_SAMPLE_FORMAT* YR; mpc_int32_t* L; mpc_int32_t* R; #ifdef MPC_FIXED_POINT #if MPC_FIXED_POINT_FRACTPART == 14 #define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \ MPC_MULTIPLY_EX(CcVal, d->SCF[SCF_idx], d->SCF_shift[SCF_idx]) #else #error FIXME, Cc table is in 18.14 format #endif #else #define MPC_MULTIPLY_SCF(CcVal, SCF_idx) \ MPC_MULTIPLY(CcVal, d->SCF[SCF_idx]) #endif // requantization and scaling of subband-samples for ( Band = 0; Band <= Last_Band; Band++ ) { // setting pointers YL = d->Y_L[0] + Band; YR = d->Y_R[0] + Band; L = d->Q[Band].L; R = d->Q[Band].R; /************************** MS-coded **************************/ if ( d->MS_Flag [Band] ) { if ( d->Res_L [Band] ) { if ( d->Res_R [Band] ) { // M!=0, S!=0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = (templ = MPC_MULTIPLY_FLOAT_INT(facL,*L++))+(tempr = MPC_MULTIPLY_FLOAT_INT(facR,*R++)); *YR = templ - tempr; } } else { // M!=0, S==0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YR = *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); } } } else { if (d->Res_R[Band]) // M==0, S!=0 { facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YR = - (*YL = MPC_MULTIPLY_FLOAT_INT(facR,*(R++))); } } else { // M==0, S==0 for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { *YR = *YL = 0; } } } } /************************** LR-coded **************************/ else { if ( d->Res_L [Band] ) { if ( d->Res_R [Band] ) { // L!=0, R!=0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); for (n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); for (; n < 24; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); for (; n < 36; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } } else { // L!=0, R==0 facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][0]); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][1]); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } facL = MPC_MULTIPLY_SCF( Cc[d->Res_L[Band]] , (unsigned char)d->SCF_Index_L[Band][2]); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = MPC_MULTIPLY_FLOAT_INT(facL,*L++); *YR = 0; } } } else { if ( d->Res_R [Band] ) { // L==0, R!=0 facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][0]); for ( n = 0; n < 12; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][1]); for ( ; n < 24; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } facR = MPC_MULTIPLY_SCF( Cc[d->Res_R[Band]] , (unsigned char)d->SCF_Index_R[Band][2]); for ( ; n < 36; n++, YL += 32, YR += 32 ) { *YL = 0; *YR = MPC_MULTIPLY_FLOAT_INT(facR,*R++); } } else { // L==0, R==0 for ( n = 0; n < 36; n++, YL += 32, YR += 32 ) { *YR = *YL = 0; } } } } } } #ifdef MPC_SUPPORT_SV456 static const unsigned char Q_res[32][16] = { {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,17}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,3,4,5,6,17,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, {0,1,2,17,0,0,0,0,0,0,0,0,0,0,0,0}, }; /****************************************** SV 6 ******************************************/ void mpc_decoder_read_bitstream_sv6(mpc_decoder *d, mpc_bool_t seeking) { mpc_int32_t n,k; mpc_int32_t Max_used_Band=0; const HuffmanTyp *Table; const HuffmanTyp *x1; const HuffmanTyp *x2; mpc_int32_t *L; mpc_int32_t *R; mpc_int32_t *ResL = d->Res_L; mpc_int32_t *ResR = d->Res_R; /************************ HEADER **************************/ ResL = d->Res_L; ResR = d->Res_R; for (n=0; n <= d->Max_Band; ++n, ++ResL, ++ResR) { if (n<11) Table = mpc_table_Region_A; else if (n>=11 && n<=22) Table = mpc_table_Region_B; else /*if (n>=23)*/ Table = mpc_table_Region_C; *ResL = Q_res[n][mpc_decoder_huffman_decode(d, Table, 14)]; if (d->MS_used) { d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1); } *ResR = Q_res[n][mpc_decoder_huffman_decode(d, Table, 14)]; // only perform the following procedure up to the maximum non-zero subband if (*ResL || *ResR) Max_used_Band = n; } /************************* SCFI-Bundle *****************************/ ResL = d->Res_L; ResR = d->Res_R; for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR) { if (*ResL) mpc_decoder_scfi_bundle_read(d, mpc_table_SCFI_Bundle, &(d->SCFI_L[n]), &(d->DSCF_Flag_L[n])); if (*ResR) mpc_decoder_scfi_bundle_read(d, mpc_table_SCFI_Bundle, &(d->SCFI_R[n]), &(d->DSCF_Flag_R[n])); } /***************************** SCFI ********************************/ ResL = d->Res_L; ResR = d->Res_R; L = d->SCF_Index_L[0]; R = d->SCF_Index_R[0]; for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3) { if (*ResL) { /*********** DSCF ************/ if (d->DSCF_Flag_L[n]==1) { switch (d->SCFI_L[n]) { case 3: L[0] = L[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); L[1] = L[0]; L[2] = L[1]; break; case 1: L[0] = L[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); L[1] = L[0] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); L[2] = L[1]; break; case 2: L[0] = L[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); L[1] = L[0]; L[2] = L[1] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); break; case 0: L[0] = L[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); L[1] = L[0] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); L[2] = L[1] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); break; default: return; } if (L[0] > 1024) L[0] = 0x8080; if (L[1] > 1024) L[1] = 0x8080; if (L[2] > 1024) L[2] = 0x8080; } /************ SCF ************/ else { switch (d->SCFI_L[n]) { case 3: L[0] = mpc_decoder_bitstream_read(d, 6); L[1] = L[0]; L[2] = L[1]; break; case 1: L[0] = mpc_decoder_bitstream_read(d, 6); L[1] = mpc_decoder_bitstream_read(d, 6); L[2] = L[1]; break; case 2: L[0] = mpc_decoder_bitstream_read(d, 6); L[1] = L[0]; L[2] = mpc_decoder_bitstream_read(d, 6); break; case 0: L[0] = mpc_decoder_bitstream_read(d, 6); L[1] = mpc_decoder_bitstream_read(d, 6); L[2] = mpc_decoder_bitstream_read(d, 6); break; default: return; } } } if (*ResR) { /*********** DSCF ************/ if (d->DSCF_Flag_R[n]==1) { switch (d->SCFI_R[n]) { case 3: R[0] = R[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); R[1] = R[0]; R[2] = R[1]; break; case 1: R[0] = R[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); R[1] = R[0] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); R[2] = R[1]; break; case 2: R[0] = R[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); R[1] = R[0]; R[2] = R[1] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); break; case 0: R[0] = R[2] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); R[1] = R[0] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); R[2] = R[1] + mpc_decoder_huffman_decode(d, mpc_table_DSCF_Entropie, 6); break; default: return; } if (R[0] > 1024) R[0] = 0x8080; if (R[1] > 1024) R[1] = 0x8080; if (R[2] > 1024) R[2] = 0x8080; } /************ SCF ************/ else { switch (d->SCFI_R[n]) { case 3: R[0] = mpc_decoder_bitstream_read(d, 6); R[1] = R[0]; R[2] = R[1]; break; case 1: R[0] = mpc_decoder_bitstream_read(d, 6); R[1] = mpc_decoder_bitstream_read(d, 6); R[2] = R[1]; break; case 2: R[0] = mpc_decoder_bitstream_read(d, 6); R[1] = R[0]; R[2] = mpc_decoder_bitstream_read(d, 6); break; case 0: R[0] = mpc_decoder_bitstream_read(d, 6); R[1] = mpc_decoder_bitstream_read(d, 6); R[2] = mpc_decoder_bitstream_read(d, 6); break; default: return; break; } } } } if (seeking == TRUE) return; /**************************** Samples ****************************/ ResL = d->Res_L; ResR = d->Res_R; for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR) { // setting pointers x1 = mpc_table_SampleHuff[*ResL]; x2 = mpc_table_SampleHuff[*ResR]; L = d->Q[n].L; R = d->Q[n].R; if (x1!=NULL || x2!=NULL) for (k=0; k<36; ++k) { if (x1 != NULL) *L++ = mpc_decoder_huffman_decode(d, x1, 8); if (x2 != NULL) *R++ = mpc_decoder_huffman_decode(d, x2, 8); } if (*ResL>7 || *ResR>7) for (k=0; k<36; ++k) { if (*ResL>7) *L++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - Dc[*ResL]; if (*ResR>7) *R++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - Dc[*ResR]; } } } #endif //MPC_SUPPORT_SV456 /****************************************** SV 7 ******************************************/ void mpc_decoder_read_bitstream_sv7(mpc_decoder *d, mpc_bool_t seeking) { // these arrays hold decoding results for bundled quantizers (3- and 5-step) static const mpc_int32_t idx30[] = { -1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1,-1, 0, 1}; static const mpc_int32_t idx31[] = { -1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1,-1,-1,-1, 0, 0, 0, 1, 1, 1}; static const mpc_int32_t idx32[] = { -1,-1,-1,-1,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1}; static const mpc_int32_t idx50[] = { -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2}; static const mpc_int32_t idx51[] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2}; mpc_int32_t n,k; mpc_int32_t Max_used_Band=0; const HuffmanTyp *Table; mpc_int32_t idx; mpc_int32_t *L ,*R; mpc_int32_t *ResL,*ResR; mpc_uint32_t tmp; /***************************** Header *****************************/ ResL = d->Res_L; ResR = d->Res_R; // first subband *ResL = mpc_decoder_bitstream_read(d, 4); *ResR = mpc_decoder_bitstream_read(d, 4); if (d->MS_used && !(*ResL==0 && *ResR==0)) { d->MS_Flag[0] = mpc_decoder_bitstream_read(d, 1); } // consecutive subbands ++ResL; ++ResR; // increase pointers for (n=1; n <= d->Max_Band; ++n, ++ResL, ++ResR) { idx = mpc_decoder_huffman_decode(d, mpc_table_HuffHdr, 9); *ResL = (idx!=4) ? *(ResL-1) + idx : (int) mpc_decoder_bitstream_read(d, 4); idx = mpc_decoder_huffman_decode(d, mpc_table_HuffHdr, 9); *ResR = (idx!=4) ? *(ResR-1) + idx : (int) mpc_decoder_bitstream_read(d, 4); if (d->MS_used && !(*ResL==0 && *ResR==0)) { d->MS_Flag[n] = mpc_decoder_bitstream_read(d, 1); } // only perform following procedures up to the maximum non-zero subband if (*ResL!=0 || *ResR!=0) { Max_used_Band = n; } } /****************************** SCFI ******************************/ L = d->SCFI_L; R = d->SCFI_R; ResL = d->Res_L; ResR = d->Res_R; for (n=0; n <= Max_used_Band; ++n, ++L, ++R, ++ResL, ++ResR) { if (*ResL) *L = mpc_decoder_huffman_decode(d, mpc_table_HuffSCFI, 3); if (*ResR) *R = mpc_decoder_huffman_decode(d, mpc_table_HuffSCFI, 3); } /**************************** SCF/DSCF ****************************/ ResL = d->Res_L; ResR = d->Res_R; L = d->SCF_Index_L[0]; R = d->SCF_Index_R[0]; for (n=0; n<=Max_used_Band; ++n, ++ResL, ++ResR, L+=3, R+=3) { if (*ResL) { switch (d->SCFI_L[n]) { case 1: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[1] = (idx!=8) ? L[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); L[2] = L[1]; break; case 3: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); L[1] = L[0]; L[2] = L[1]; break; case 2: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); L[1] = L[0]; idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[2] = (idx!=8) ? L[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); break; case 0: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[0] = (idx!=8) ? L[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[1] = (idx!=8) ? L[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); L[2] = (idx!=8) ? L[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); break; default: return; } if (L[0] > 1024) L[0] = 0x8080; if (L[1] > 1024) L[1] = 0x8080; if (L[2] > 1024) L[2] = 0x8080; } if (*ResR) { switch (d->SCFI_R[n]) { case 1: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[1] = (idx!=8) ? R[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); R[2] = R[1]; break; case 3: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); R[1] = R[0]; R[2] = R[1]; break; case 2: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); R[1] = R[0]; idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[2] = (idx!=8) ? R[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); break; case 0: idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[0] = (idx!=8) ? R[2] + idx : (int) mpc_decoder_bitstream_read(d, 6); idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[1] = (idx!=8) ? R[0] + idx : (int) mpc_decoder_bitstream_read(d, 6); idx = mpc_decoder_huffman_decode(d, mpc_table_HuffDSCF, 6); R[2] = (idx!=8) ? R[1] + idx : (int) mpc_decoder_bitstream_read(d, 6); break; default: return; } if (R[0] > 1024) R[0] = 0x8080; if (R[1] > 1024) R[1] = 0x8080; if (R[2] > 1024) R[2] = 0x8080; } } if (seeking == TRUE) return; /***************************** Samples ****************************/ ResL = d->Res_L; ResR = d->Res_R; L = d->Q[0].L; R = d->Q[0].R; for (n=0; n <= Max_used_Band; ++n, ++ResL, ++ResR, L+=36, R+=36) { /************** links **************/ switch (*ResL) { case -2: case -3: case -4: case -5: case -6: case -7: case -8: case -9: case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: L += 36; break; case -1: for (k=0; k<36; k++ ) { tmp = mpc_random_int(d); *L++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; } break; case 0: L += 36;// increase pointer break; case 1: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][1]; for (k=0; k<12; ++k) { idx = mpc_decoder_huffman_decode(d, Table, 9); *L++ = idx30[idx]; *L++ = idx31[idx]; *L++ = idx32[idx]; } break; case 2: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][2]; for (k=0; k<18; ++k) { idx = mpc_decoder_huffman_decode(d, Table, 10); *L++ = idx50[idx]; *L++ = idx51[idx]; } break; case 3: case 4: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL]; for (k=0; k<36; ++k) *L++ = mpc_decoder_huffman_decode(d, Table, 5); break; case 5: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL]; for (k=0; k<36; ++k) *L++ = mpc_decoder_huffman_decode(d, Table, 8); break; case 6: case 7: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResL]; for (k=0; k<36; ++k) *L++ = mpc_decoder_huffman_decode(d, Table, 14); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: tmp = Dc[*ResL]; for (k=0; k<36; ++k) *L++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResL]) - tmp; break; default: return; } /************** rechts **************/ switch (*ResR) { case -2: case -3: case -4: case -5: case -6: case -7: case -8: case -9: case -10: case -11: case -12: case -13: case -14: case -15: case -16: case -17: R += 36; break; case -1: for (k=0; k<36; k++ ) { tmp = mpc_random_int(d); *R++ = ((tmp >> 24) & 0xFF) + ((tmp >> 16) & 0xFF) + ((tmp >> 8) & 0xFF) + ((tmp >> 0) & 0xFF) - 510; } break; case 0: R += 36;// increase pointer break; case 1: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][1]; for (k=0; k<12; ++k) { idx = mpc_decoder_huffman_decode(d, Table, 9); *R++ = idx30[idx]; *R++ = idx31[idx]; *R++ = idx32[idx]; } break; case 2: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][2]; for (k=0; k<18; ++k) { idx = mpc_decoder_huffman_decode(d, Table, 10); *R++ = idx50[idx]; *R++ = idx51[idx]; } break; case 3: case 4: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR]; for (k=0; k<36; ++k) *R++ = mpc_decoder_huffman_decode(d, Table, 5); break; case 5: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR]; for (k=0; k<36; ++k) *R++ = mpc_decoder_huffman_decode(d, Table, 8); break; case 6: case 7: Table = mpc_table_HuffQ[mpc_decoder_bitstream_read(d, 1)][*ResR]; for (k=0; k<36; ++k) *R++ = mpc_decoder_huffman_decode(d, Table, 14); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: case 16: case 17: tmp = Dc[*ResR]; for (k=0; k<36; ++k) *R++ = (mpc_int32_t)mpc_decoder_bitstream_read(d, Res_bit[*ResR]) - tmp; break; default: return; } } } void mpc_decoder_setup(mpc_decoder *d, mpc_reader *r) { d->r = r; d->MPCHeaderPos = 0; d->StreamVersion = 0; d->MS_used = 0; d->FrameWasValid = 0; d->OverallFrames = 0; d->DecodedFrames = 0; d->TrueGaplessPresent = 0; d->WordsRead = 0; d->Max_Band = 0; d->SampleRate = 0; d->__r1 = 1; d->__r2 = 1; d->Max_Band = 0; d->seeking_window = FAST_SEEKING_WINDOW; mpc_decoder_reset_bitstream_decode(d); mpc_decoder_initialisiere_quantisierungstabellen(d, 1.0f); #if 0 mpc_decoder_init_huffman_sv6(d); mpc_decoder_init_huffman_sv7(d); #endif } static mpc_uint32_t get_initial_fpos(mpc_decoder *d) { mpc_uint32_t fpos = 0; switch ( d->StreamVersion ) { // setting position to the beginning of the data-bitstream case 0x04: fpos = 48; break; case 0x05: case 0x06: fpos = 64; break; case 0x07: case 0x17: fpos = 200; break; } return fpos; } void mpc_decoder_set_streaminfo(mpc_decoder *d, mpc_streaminfo *si) { mpc_decoder_reset_synthesis(d); mpc_decoder_reset_globals(d); d->StreamVersion = si->stream_version; d->MS_used = si->ms; d->Max_Band = si->max_band; d->OverallFrames = si->frames; d->MPCHeaderPos = si->header_position; d->TrueGaplessPresent = si->is_true_gapless; d->SampleRate = (mpc_int32_t)si->sample_freq; d->samples_to_skip = MPC_DECODER_SYNTH_DELAY; } mpc_bool_t mpc_decoder_initialize(mpc_decoder *d, mpc_streaminfo *si) { mpc_decoder_set_streaminfo(d, si); // AB: setting position to the beginning of the data-bitstream mpc_decoder_seek(d, get_initial_fpos(d)); d->seeking_pwr = 0; while( d->OverallFrames > ((mpc_int64_t) SEEKING_TABLE_SIZE << d->seeking_pwr) ) d->seeking_pwr++; d->seeking_table_frames = 0; d->seeking_table[0] = get_initial_fpos(d); return TRUE; } void mpc_decoder_set_seeking(mpc_decoder *d, mpc_streaminfo *si, mpc_bool_t fast_seeking) { d->seeking_window = FAST_SEEKING_WINDOW; if (si->fast_seek == 0 && fast_seeking == 0) d->seeking_window = SLOW_SEEKING_WINDOW; } mpc_bool_t mpc_decoder_seek_seconds(mpc_decoder *d, double seconds) { return mpc_decoder_seek_sample(d, (mpc_int64_t)(seconds * (double)d->SampleRate + 0.5)); } mpc_bool_t mpc_decoder_seek_sample(mpc_decoder *d, mpc_int64_t destsample) { mpc_uint32_t fpos; mpc_uint32_t fwd; fwd = (mpc_uint32_t) (destsample / MPC_FRAME_LENGTH); d->samples_to_skip = MPC_DECODER_SYNTH_DELAY + (mpc_uint32_t)(destsample % MPC_FRAME_LENGTH); // resetting synthesis filter to avoid "clicks" mpc_decoder_reset_synthesis(d); // prevent from desired position out of allowed range fwd = fwd < d->OverallFrames ? fwd : d->OverallFrames; if (fwd > d->DecodedFrames + d->seeking_window || fwd < d->DecodedFrames) { memset(d->SCF_Index_L, 1, sizeof d->SCF_Index_L ); memset(d->SCF_Index_R, 1, sizeof d->SCF_Index_R ); } if (d->seeking_table_frames > d->DecodedFrames || fwd < d->DecodedFrames) { d->DecodedFrames = 0; if (fwd > d->seeking_window) d->DecodedFrames = (fwd - d->seeking_window) & ((~0u) << d->seeking_pwr); if (d->DecodedFrames > d->seeking_table_frames) d->DecodedFrames = d->seeking_table_frames; fpos = d->seeking_table[d->DecodedFrames >> d->seeking_pwr]; mpc_decoder_seek(d, fpos); } // read the last 32 frames before the desired position to scan the scalefactors (artifactless jumping) for ( ; d->DecodedFrames < fwd; d->DecodedFrames++ ) { mpc_uint32_t RING = d->Zaehler; mpc_uint32_t FwdJumpInfo; // add seeking info if (d->seeking_table_frames < d->DecodedFrames && (d->DecodedFrames & ((1 << d->seeking_pwr) - 1)) == 0) { d->seeking_table[d->DecodedFrames >> d->seeking_pwr] = mpc_decoder_bits_read(d); d->seeking_table_frames = d->DecodedFrames; } // read jump-info FwdJumpInfo = mpc_decoder_bitstream_read(d, 20); FwdJumpInfo += mpc_decoder_bits_read(d); if (fwd <= d->DecodedFrames + d->seeking_window) { if (d->StreamVersion >= 7) { mpc_decoder_read_bitstream_sv7(d, TRUE); } else { #ifdef MPC_SUPPORT_SV456 mpc_decoder_read_bitstream_sv6(d, TRUE); #else return FALSE; #endif } } mpc_decoder_bitstream_jump(d, FwdJumpInfo - mpc_decoder_bits_read(d)); // update buffer mpc_decoder_update_buffer(d, RING); } return TRUE; } xine-lib-1.2/contrib/libmpcdec/Makefile.am0000644000175000017500000000113114647725152016276 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) EXTRA_DIST = diff_from_libmpcdec_1.2.5.patch COPYING if ENABLE_MUSEPACK if !WITH_EXTERNAL_LIBMPCDEC noinst_LTLIBRARIES = libmpcdec.la endif endif libmpcdec_la_SOURCES = \ huffsv46.c \ huffsv7.c \ idtag.c \ mpc_decoder.c \ mpc_reader.c \ requant.c \ streaminfo.c \ synth_filter.c \ mpcdec/config_types.h \ mpcdec/decoder.h \ mpcdec/huffman.h \ mpcdec/internal.h \ mpcdec/math.h \ mpcdec/mpcdec.h \ mpcdec/reader.h \ mpcdec/requant.h \ mpcdec/streaminfo.h xine-lib-1.2/contrib/libmpcdec/synth_filter.c0000644000175000017500000005572014647725152017135 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file synth_filter.c /// Synthesis functions. /// \todo document me #include #include /* C O N S T A N T S */ #undef _ #define MPC_FIXED_POINT_SYNTH_FIX 2 #ifdef MPC_FIXED_POINT #define _(value) MPC_MAKE_FRACT_CONST((double)value/(double)(0x40000)) #else #define _(value) MAKE_MPC_SAMPLE((double)value/(double)(0x10000)) #endif static const MPC_SAMPLE_FORMAT Di_opt [32] [16] = { { _( 0), _( -29), _( 213), _( -459), _( 2037), _(-5153), _( 6574), _(-37489), _(75038), _(37489), _(6574), _( 5153), _(2037), _( 459), _(213), _(29) }, { _( -1), _( -31), _( 218), _( -519), _( 2000), _(-5517), _( 5959), _(-39336), _(74992), _(35640), _(7134), _( 4788), _(2063), _( 401), _(208), _(26) }, { _( -1), _( -35), _( 222), _( -581), _( 1952), _(-5879), _( 5288), _(-41176), _(74856), _(33791), _(7640), _( 4425), _(2080), _( 347), _(202), _(24) }, { _( -1), _( -38), _( 225), _( -645), _( 1893), _(-6237), _( 4561), _(-43006), _(74630), _(31947), _(8092), _( 4063), _(2087), _( 294), _(196), _(21) }, { _( -1), _( -41), _( 227), _( -711), _( 1822), _(-6589), _( 3776), _(-44821), _(74313), _(30112), _(8492), _( 3705), _(2085), _( 244), _(190), _(19) }, { _( -1), _( -45), _( 228), _( -779), _( 1739), _(-6935), _( 2935), _(-46617), _(73908), _(28289), _(8840), _( 3351), _(2075), _( 197), _(183), _(17) }, { _( -1), _( -49), _( 228), _( -848), _( 1644), _(-7271), _( 2037), _(-48390), _(73415), _(26482), _(9139), _( 3004), _(2057), _( 153), _(176), _(16) }, { _( -2), _( -53), _( 227), _( -919), _( 1535), _(-7597), _( 1082), _(-50137), _(72835), _(24694), _(9389), _( 2663), _(2032), _( 111), _(169), _(14) }, { _( -2), _( -58), _( 224), _( -991), _( 1414), _(-7910), _( 70), _(-51853), _(72169), _(22929), _(9592), _( 2330), _(2001), _( 72), _(161), _(13) }, { _( -2), _( -63), _( 221), _(-1064), _( 1280), _(-8209), _( -998), _(-53534), _(71420), _(21189), _(9750), _( 2006), _(1962), _( 36), _(154), _(11) }, { _( -2), _( -68), _( 215), _(-1137), _( 1131), _(-8491), _( -2122), _(-55178), _(70590), _(19478), _(9863), _( 1692), _(1919), _( 2), _(147), _(10) }, { _( -3), _( -73), _( 208), _(-1210), _( 970), _(-8755), _( -3300), _(-56778), _(69679), _(17799), _(9935), _( 1388), _(1870), _( -29), _(139), _( 9) }, { _( -3), _( -79), _( 200), _(-1283), _( 794), _(-8998), _( -4533), _(-58333), _(68692), _(16155), _(9966), _( 1095), _(1817), _( -57), _(132), _( 8) }, { _( -4), _( -85), _( 189), _(-1356), _( 605), _(-9219), _( -5818), _(-59838), _(67629), _(14548), _(9959), _( 814), _(1759), _( -83), _(125), _( 7) }, { _( -4), _( -91), _( 177), _(-1428), _( 402), _(-9416), _( -7154), _(-61289), _(66494), _(12980), _(9916), _( 545), _(1698), _(-106), _(117), _( 7) }, { _( -5), _( -97), _( 163), _(-1498), _( 185), _(-9585), _( -8540), _(-62684), _(65290), _(11455), _(9838), _( 288), _(1634), _(-127), _(111), _( 6) }, { _( -5), _(-104), _( 146), _(-1567), _( -45), _(-9727), _( -9975), _(-64019), _(64019), _( 9975), _(9727), _( 45), _(1567), _(-146), _(104), _( 5) }, { _( -6), _(-111), _( 127), _(-1634), _( -288), _(-9838), _(-11455), _(-65290), _(62684), _( 8540), _(9585), _( -185), _(1498), _(-163), _( 97), _( 5) }, { _( -7), _(-117), _( 106), _(-1698), _( -545), _(-9916), _(-12980), _(-66494), _(61289), _( 7154), _(9416), _( -402), _(1428), _(-177), _( 91), _( 4) }, { _( -7), _(-125), _( 83), _(-1759), _( -814), _(-9959), _(-14548), _(-67629), _(59838), _( 5818), _(9219), _( -605), _(1356), _(-189), _( 85), _( 4) }, { _( -8), _(-132), _( 57), _(-1817), _(-1095), _(-9966), _(-16155), _(-68692), _(58333), _( 4533), _(8998), _( -794), _(1283), _(-200), _( 79), _( 3) }, { _( -9), _(-139), _( 29), _(-1870), _(-1388), _(-9935), _(-17799), _(-69679), _(56778), _( 3300), _(8755), _( -970), _(1210), _(-208), _( 73), _( 3) }, { _(-10), _(-147), _( -2), _(-1919), _(-1692), _(-9863), _(-19478), _(-70590), _(55178), _( 2122), _(8491), _(-1131), _(1137), _(-215), _( 68), _( 2) }, { _(-11), _(-154), _( -36), _(-1962), _(-2006), _(-9750), _(-21189), _(-71420), _(53534), _( 998), _(8209), _(-1280), _(1064), _(-221), _( 63), _( 2) }, { _(-13), _(-161), _( -72), _(-2001), _(-2330), _(-9592), _(-22929), _(-72169), _(51853), _( -70), _(7910), _(-1414), _( 991), _(-224), _( 58), _( 2) }, { _(-14), _(-169), _(-111), _(-2032), _(-2663), _(-9389), _(-24694), _(-72835), _(50137), _(-1082), _(7597), _(-1535), _( 919), _(-227), _( 53), _( 2) }, { _(-16), _(-176), _(-153), _(-2057), _(-3004), _(-9139), _(-26482), _(-73415), _(48390), _(-2037), _(7271), _(-1644), _( 848), _(-228), _( 49), _( 1) }, { _(-17), _(-183), _(-197), _(-2075), _(-3351), _(-8840), _(-28289), _(-73908), _(46617), _(-2935), _(6935), _(-1739), _( 779), _(-228), _( 45), _( 1) }, { _(-19), _(-190), _(-244), _(-2085), _(-3705), _(-8492), _(-30112), _(-74313), _(44821), _(-3776), _(6589), _(-1822), _( 711), _(-227), _( 41), _( 1) }, { _(-21), _(-196), _(-294), _(-2087), _(-4063), _(-8092), _(-31947), _(-74630), _(43006), _(-4561), _(6237), _(-1893), _( 645), _(-225), _( 38), _( 1) }, { _(-24), _(-202), _(-347), _(-2080), _(-4425), _(-7640), _(-33791), _(-74856), _(41176), _(-5288), _(5879), _(-1952), _( 581), _(-222), _( 35), _( 1) }, { _(-26), _(-208), _(-401), _(-2063), _(-4788), _(-7134), _(-35640), _(-74992), _(39336), _(-5959), _(5517), _(-2000), _( 519), _(-218), _( 31), _( 1) } }; #undef _ static void Calculate_New_V ( const MPC_SAMPLE_FORMAT * Sample, MPC_SAMPLE_FORMAT * V ) { // Calculating new V-buffer values for left channel // calculate new V-values (ISO-11172-3, p. 39) // based upon fast-MDCT algorithm by Byeong Gi Lee /*static*/ MPC_SAMPLE_FORMAT A00, A01, A02, A03, A04, A05, A06, A07, A08, A09, A10, A11, A12, A13, A14, A15; /*static*/ MPC_SAMPLE_FORMAT B00, B01, B02, B03, B04, B05, B06, B07, B08, B09, B10, B11, B12, B13, B14, B15; MPC_SAMPLE_FORMAT tmp; A00 = Sample[ 0] + Sample[31]; A01 = Sample[ 1] + Sample[30]; A02 = Sample[ 2] + Sample[29]; A03 = Sample[ 3] + Sample[28]; A04 = Sample[ 4] + Sample[27]; A05 = Sample[ 5] + Sample[26]; A06 = Sample[ 6] + Sample[25]; A07 = Sample[ 7] + Sample[24]; A08 = Sample[ 8] + Sample[23]; A09 = Sample[ 9] + Sample[22]; A10 = Sample[10] + Sample[21]; A11 = Sample[11] + Sample[20]; A12 = Sample[12] + Sample[19]; A13 = Sample[13] + Sample[18]; A14 = Sample[14] + Sample[17]; A15 = Sample[15] + Sample[16]; B00 = A00 + A15; B01 = A01 + A14; B02 = A02 + A13; B03 = A03 + A12; B04 = A04 + A11; B05 = A05 + A10; B06 = A06 + A09; B07 = A07 + A08;; B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); A00 = B00 + B07; A01 = B01 + B06; A02 = B02 + B05; A03 = B03 + B04; A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); A08 = B08 + B15; A09 = B09 + B14; A10 = B10 + B13; A11 = B11 + B12; A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); B00 = A00 + A03; B01 = A01 + A02; B02 = MPC_MULTIPLY_FRACT_CONST_FIX((A00 - A03) , 0.5411961079f , 1); B03 = MPC_MULTIPLY_FRACT_CONST_FIX((A01 - A02) , 1.3065630198f , 2); B04 = A04 + A07; B05 = A05 + A06; B06 = MPC_MULTIPLY_FRACT_CONST_FIX((A04 - A07) , 0.5411961079f , 1); B07 = MPC_MULTIPLY_FRACT_CONST_FIX((A05 - A06) , 1.3065630198f , 2); B08 = A08 + A11; B09 = A09 + A10; B10 = MPC_MULTIPLY_FRACT_CONST_FIX((A08 - A11) , 0.5411961079f , 1); B11 = MPC_MULTIPLY_FRACT_CONST_FIX((A09 - A10) , 1.3065630198f , 2); B12 = A12 + A15; B13 = A13 + A14; B14 = MPC_MULTIPLY_FRACT_CONST_FIX((A12 - A15) , 0.5411961079f , 1); B15 = MPC_MULTIPLY_FRACT_CONST_FIX((A13 - A14) , 1.3065630198f , 2); A00 = B00 + B01; A01 = MPC_MULTIPLY_FRACT_CONST_FIX((B00 - B01) , 0.7071067691f , 1); A02 = B02 + B03; A03 = MPC_MULTIPLY_FRACT_CONST_FIX((B02 - B03) , 0.7071067691f , 1); A04 = B04 + B05; A05 = MPC_MULTIPLY_FRACT_CONST_FIX((B04 - B05) , 0.7071067691f , 1); A06 = B06 + B07; A07 = MPC_MULTIPLY_FRACT_CONST_FIX((B06 - B07) , 0.7071067691f , 1); A08 = B08 + B09; A09 = MPC_MULTIPLY_FRACT_CONST_FIX((B08 - B09) , 0.7071067691f , 1); A10 = B10 + B11; A11 = MPC_MULTIPLY_FRACT_CONST_FIX((B10 - B11) , 0.7071067691f , 1); A12 = B12 + B13; A13 = MPC_MULTIPLY_FRACT_CONST_FIX((B12 - B13) , 0.7071067691f , 1); A14 = B14 + B15; A15 = MPC_MULTIPLY_FRACT_CONST_FIX((B14 - B15) , 0.7071067691f , 1); V[48] = -A00; V[ 0] = A01; V[40] = -A02 - (V[ 8] = A03); V[36] = -((V[ 4] = A05 + (V[12] = A07)) + A06); V[44] = - A04 - A06 - A07; V[ 6] = (V[10] = A11 + (V[14] = A15)) + A13; V[38] = (V[34] = -(V[ 2] = A09 + A13 + A15) - A14) + A09 - A10 - A11; V[46] = (tmp = -(A12 + A14 + A15)) - A08; V[42] = tmp - A10 - A11; A00 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 0] - Sample[31]) , 0.5006030202f , MPC_FIXED_POINT_SYNTH_FIX); A01 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 1] - Sample[30]) , 0.5054709315f , MPC_FIXED_POINT_SYNTH_FIX); A02 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 2] - Sample[29]) , 0.5154473186f , MPC_FIXED_POINT_SYNTH_FIX); A03 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 3] - Sample[28]) , 0.5310425758f , MPC_FIXED_POINT_SYNTH_FIX); A04 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 4] - Sample[27]) , 0.5531039238f , MPC_FIXED_POINT_SYNTH_FIX); A05 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 5] - Sample[26]) , 0.5829349756f , MPC_FIXED_POINT_SYNTH_FIX); A06 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 6] - Sample[25]) , 0.6225041151f , MPC_FIXED_POINT_SYNTH_FIX); A07 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 7] - Sample[24]) , 0.6748083234f , MPC_FIXED_POINT_SYNTH_FIX); A08 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 8] - Sample[23]) , 0.7445362806f , MPC_FIXED_POINT_SYNTH_FIX); A09 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[ 9] - Sample[22]) , 0.8393496275f , MPC_FIXED_POINT_SYNTH_FIX); A10 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[10] - Sample[21]) , 0.9725682139f , MPC_FIXED_POINT_SYNTH_FIX); #if MPC_FIXED_POINT_SYNTH_FIX>=2 A11 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[11] - Sample[20]) , 1.1694399118f , MPC_FIXED_POINT_SYNTH_FIX); A12 = MPC_MULTIPLY_FRACT_CONST_SHR((Sample[12] - Sample[19]) , 1.4841645956f , MPC_FIXED_POINT_SYNTH_FIX); #else A11 = MPC_SCALE_CONST_SHR ((Sample[11] - Sample[20]) , 1.1694399118f , 30, MPC_FIXED_POINT_SYNTH_FIX); A12 = MPC_SCALE_CONST_SHR ((Sample[12] - Sample[19]) , 1.4841645956f , 30, MPC_FIXED_POINT_SYNTH_FIX); #endif A13 = MPC_SCALE_CONST_SHR ((Sample[13] - Sample[18]) , 2.0577809811f , 29, MPC_FIXED_POINT_SYNTH_FIX); A14 = MPC_SCALE_CONST_SHR ((Sample[14] - Sample[17]) , 3.4076085091f , 29, MPC_FIXED_POINT_SYNTH_FIX); A15 = MPC_SCALE_CONST_SHR ((Sample[15] - Sample[16]) , 10.1900081635f, 27 ,MPC_FIXED_POINT_SYNTH_FIX); B00 = A00 + A15; B01 = A01 + A14; B02 = A02 + A13; B03 = A03 + A12; B04 = A04 + A11; B05 = A05 + A10; B06 = A06 + A09; B07 = A07 + A08; B08 = MPC_SCALE_CONST((A00 - A15) , 0.5024192929f , 31); B09 = MPC_SCALE_CONST((A01 - A14) , 0.5224986076f , 31); B10 = MPC_SCALE_CONST((A02 - A13) , 0.5669440627f , 31); B11 = MPC_SCALE_CONST((A03 - A12) , 0.6468217969f , 31); B12 = MPC_SCALE_CONST((A04 - A11) , 0.7881546021f , 31); B13 = MPC_SCALE_CONST((A05 - A10) , 1.0606776476f , 30); B14 = MPC_SCALE_CONST((A06 - A09) , 1.7224471569f , 30); B15 = MPC_SCALE_CONST((A07 - A08) , 5.1011486053f , 28); A00 = B00 + B07; A01 = B01 + B06; A02 = B02 + B05; A03 = B03 + B04; A04 = MPC_SCALE_CONST((B00 - B07) , 0.5097956061f , 31); A05 = MPC_SCALE_CONST((B01 - B06) , 0.6013448834f , 31); A06 = MPC_SCALE_CONST((B02 - B05) , 0.8999761939f , 31); A07 = MPC_SCALE_CONST((B03 - B04) , 2.5629155636f , 29); A08 = B08 + B15; A09 = B09 + B14; A10 = B10 + B13; A11 = B11 + B12; A12 = MPC_SCALE_CONST((B08 - B15) , 0.5097956061f , 31); A13 = MPC_SCALE_CONST((B09 - B14) , 0.6013448834f , 31); A14 = MPC_SCALE_CONST((B10 - B13) , 0.8999761939f , 31); A15 = MPC_SCALE_CONST((B11 - B12) , 2.5629155636f , 29); B00 = A00 + A03; B01 = A01 + A02; B02 = MPC_SCALE_CONST((A00 - A03) , 0.5411961079f , 31); B03 = MPC_SCALE_CONST((A01 - A02) , 1.3065630198f , 30); B04 = A04 + A07; B05 = A05 + A06; B06 = MPC_SCALE_CONST((A04 - A07) , 0.5411961079f , 31); B07 = MPC_SCALE_CONST((A05 - A06) , 1.3065630198f , 30); B08 = A08 + A11; B09 = A09 + A10; B10 = MPC_SCALE_CONST((A08 - A11) , 0.5411961079f , 31); B11 = MPC_SCALE_CONST((A09 - A10) , 1.3065630198f , 30); B12 = A12 + A15; B13 = A13 + A14; B14 = MPC_SCALE_CONST((A12 - A15) , 0.5411961079f , 31); B15 = MPC_SCALE_CONST((A13 - A14) , 1.3065630198f , 30); A00 = MPC_SHL(B00 + B01, MPC_FIXED_POINT_SYNTH_FIX); A01 = MPC_SCALE_CONST_SHL((B00 - B01) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A02 = MPC_SHL(B02 + B03, MPC_FIXED_POINT_SYNTH_FIX); A03 = MPC_SCALE_CONST_SHL((B02 - B03) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A04 = MPC_SHL(B04 + B05, MPC_FIXED_POINT_SYNTH_FIX); A05 = MPC_SCALE_CONST_SHL((B04 - B05) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A06 = MPC_SHL(B06 + B07, MPC_FIXED_POINT_SYNTH_FIX); A07 = MPC_SCALE_CONST_SHL((B06 - B07) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A08 = MPC_SHL(B08 + B09, MPC_FIXED_POINT_SYNTH_FIX); A09 = MPC_SCALE_CONST_SHL((B08 - B09) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A10 = MPC_SHL(B10 + B11, MPC_FIXED_POINT_SYNTH_FIX); A11 = MPC_SCALE_CONST_SHL((B10 - B11) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A12 = MPC_SHL(B12 + B13, MPC_FIXED_POINT_SYNTH_FIX); A13 = MPC_SCALE_CONST_SHL((B12 - B13) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); A14 = MPC_SHL(B14 + B15, MPC_FIXED_POINT_SYNTH_FIX); A15 = MPC_SCALE_CONST_SHL((B14 - B15) , 0.7071067691f , 31, MPC_FIXED_POINT_SYNTH_FIX); // mehrfach verwendete Ausdrcke: A04+A06+A07, A09+A13+A15 V[ 5] = (V[11] = (V[13] = A07 + (V[15] = A15)) + A11) + A05 + A13; V[ 7] = (V[ 9] = A03 + A11 + A15) + A13; V[33] = -(V[ 1] = A01 + A09 + A13 + A15) - A14; V[35] = -(V[ 3] = A05 + A07 + A09 + A13 + A15) - A06 - A14; V[37] = (tmp = -(A10 + A11 + A13 + A14 + A15)) - A05 - A06 - A07; V[39] = tmp - A02 - A03; // abhngig vom Befehl drber V[41] = (tmp += A13 - A12) - A02 - A03; // abhngig vom Befehl 2 drber V[43] = tmp - A04 - A06 - A07; // abhngig von Befehlen 1 und 3 drber V[47] = (tmp = -(A08 + A12 + A14 + A15)) - A00; V[45] = tmp - A04 - A06 - A07; // abhngig vom Befehl drber V[32] = -V[ 0]; V[31] = -V[ 1]; V[30] = -V[ 2]; V[29] = -V[ 3]; V[28] = -V[ 4]; V[27] = -V[ 5]; V[26] = -V[ 6]; V[25] = -V[ 7]; V[24] = -V[ 8]; V[23] = -V[ 9]; V[22] = -V[10]; V[21] = -V[11]; V[20] = -V[12]; V[19] = -V[13]; V[18] = -V[14]; V[17] = -V[15]; V[63] = V[33]; V[62] = V[34]; V[61] = V[35]; V[60] = V[36]; V[59] = V[37]; V[58] = V[38]; V[57] = V[39]; V[56] = V[40]; V[55] = V[41]; V[54] = V[42]; V[53] = V[43]; V[52] = V[44]; V[51] = V[45]; V[50] = V[46]; V[49] = V[47]; } static void Synthese_Filter_float_internal(MPC_SAMPLE_FORMAT * OutData,MPC_SAMPLE_FORMAT * V,const MPC_SAMPLE_FORMAT * Y) { mpc_uint32_t n; for ( n = 0; n < 36; n++, Y += 32 ) { V -= 64; Calculate_New_V ( Y, V ); { MPC_SAMPLE_FORMAT * Data = OutData; const MPC_SAMPLE_FORMAT * D = (const MPC_SAMPLE_FORMAT *) &Di_opt; mpc_int32_t k; //mpc_int32_t tmp; for ( k = 0; k < 32; k++, D += 16, V++ ) { *Data = MPC_SHL( MPC_MULTIPLY_FRACT(V[ 0],D[ 0]) + MPC_MULTIPLY_FRACT(V[ 96],D[ 1]) + MPC_MULTIPLY_FRACT(V[128],D[ 2]) + MPC_MULTIPLY_FRACT(V[224],D[ 3]) + MPC_MULTIPLY_FRACT(V[256],D[ 4]) + MPC_MULTIPLY_FRACT(V[352],D[ 5]) + MPC_MULTIPLY_FRACT(V[384],D[ 6]) + MPC_MULTIPLY_FRACT(V[480],D[ 7]) + MPC_MULTIPLY_FRACT(V[512],D[ 8]) + MPC_MULTIPLY_FRACT(V[608],D[ 9]) + MPC_MULTIPLY_FRACT(V[640],D[10]) + MPC_MULTIPLY_FRACT(V[736],D[11]) + MPC_MULTIPLY_FRACT(V[768],D[12]) + MPC_MULTIPLY_FRACT(V[864],D[13]) + MPC_MULTIPLY_FRACT(V[896],D[14]) + MPC_MULTIPLY_FRACT(V[992],D[15]) , 2); Data += 2; } V -= 32;//bleh OutData+=64; } } } void mpc_decoder_synthese_filter_float(mpc_decoder *d, MPC_SAMPLE_FORMAT* OutData) { /********* left channel ********/ memmove(d->V_L + MPC_V_MEM, d->V_L, 960 * sizeof(MPC_SAMPLE_FORMAT) ); Synthese_Filter_float_internal( OutData, (MPC_SAMPLE_FORMAT *)(d->V_L + MPC_V_MEM), (MPC_SAMPLE_FORMAT *)(d->Y_L [0])); /******** right channel ********/ memmove(d->V_R + MPC_V_MEM, d->V_R, 960 * sizeof(MPC_SAMPLE_FORMAT) ); Synthese_Filter_float_internal( OutData + 1, (MPC_SAMPLE_FORMAT *)(d->V_R + MPC_V_MEM), (MPC_SAMPLE_FORMAT *)(d->Y_R [0])); } /*******************************************/ /* */ /* dithered synthesis */ /* */ /*******************************************/ static const unsigned char Parity [256] = { // parity 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 }; /* * This is a simple random number generator with good quality for audio purposes. * It consists of two polycounters with opposite rotation direction and different * periods. The periods are coprime, so the total period is the product of both. * * ------------------------------------------------------------------------------------------------- * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| * | ------------------------------------------------------------------------------------------------- * | | | | | | | * | +--+--+--+-XOR-+--------+ * | | * +--------------------------------------------------------------------------------------+ * * ------------------------------------------------------------------------------------------------- * |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+ * ------------------------------------------------------------------------------------------------- | * | | | | | * +--+----XOR----+--+ | * | | * +----------------------------------------------------------------------------------------+ * * * The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481, * which gives a period of 18.410.713.077.675.721.215. The result is the * XORed values of both generators. */ mpc_uint32_t mpc_random_int(mpc_decoder *d) { #if 1 mpc_uint32_t t1, t2, t3, t4; t3 = t1 = d->__r1; t4 = t2 = d->__r2; // Parity calculation is done via table lookup, this is also available t1 &= 0xF5; t2 >>= 25; // on CPUs without parity, can be implemented in C and avoid unpredictable t1 = Parity [t1]; t2 &= 0x63; // jumps and slow rotate through the carry flag operations. t1 <<= 31; t2 = Parity [t2]; return (d->__r1 = (t3 >> 1) | t1 ) ^ (d->__r2 = (t4 + t4) | t2 ); #else return (d->__r1 = (d->__r1 >> 1) | ((mpc_uint32_t)Parity [d->__r1 & 0xF5] << 31) ) ^ (d->__r2 = (d->__r2 << 1) | (mpc_uint32_t)Parity [(d->__r2 >> 25) & 0x63] ); #endif } xine-lib-1.2/contrib/libmpcdec/huffsv46.c0000644000175000017500000001357214647725152016075 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file huffsv46.c /// Implementations of huffman decoding for streamversions < 7. #include #include #include #ifdef MPC_SUPPORT_SV456 const HuffmanTyp mpc_table_SCFI_Bundle [ 8] = {{2147483648u,1,7},{1073741824u,2,3},{939524096u,5,1},{805306368u,5,2},{738197504u,6,0},{671088640u,6,6},{536870912u,5,4},{0u,3,5},}; const HuffmanTyp mpc_table_DSCF_Entropie [13] = {{3758096384u,3,1},{3489660928u,4,3},{3355443200u,5,5},{3221225472u,5,-3},{2952790016u,4,-2},{2684354560u,4,4},{2147483648u,3,-1},{1610612736u,3,2},{1476395008u,5,-5},{1409286144u,6,6},{1342177280u,6,-6},{1073741824u,4,-4},{0u,2,0},}; const HuffmanTyp mpc_table_Region_A [16] = {{2147483648u,1,1},{2013265920u,5,3},{1946157056u,6,4},{1912602624u,7,7},{1895825408u,8,8},{1887436800u,9,9},{1883242496u,10,10},{1881145344u,11,11},{1880096768u,12,12},{1879572480u,13,13},{1879310336u,14,14},{1879048192u,14,15},{1744830464u,5,5},{1610612736u,5,6},{1073741824u,3,0},{0u,2,2},}; const HuffmanTyp mpc_table_Region_B [ 8] = {{2147483648u,1,1},{1073741824u,2,0},{536870912u,3,2},{268435456u,4,3},{134217728u,5,4},{67108864u,6,5},{33554432u,7,6},{0u,7,7},}; const HuffmanTyp mpc_table_Region_C [ 4] = {{2147483648u,1,0},{1073741824u,2,1},{536870912u,3,2},{0u,3,3},}; static const HuffmanTyp mpc_table_Entropie_1 [ 3] = {{2147483648u,1,0},{1073741824u,2,-1},{0u,2,1},}; static const HuffmanTyp mpc_table_Entropie_2 [ 5] = {{3221225472u,2,0},{2684354560u,3,2},{2147483648u,3,-2},{1073741824u,2,1},{0u,2,-1},}; static const HuffmanTyp mpc_table_Entropie_3 [ 7] = {{3221225472u,2,0},{2684354560u,3,-2},{2415919104u,4,2},{2281701376u,5,-3},{2147483648u,5,3},{1073741824u,2,-1},{0u,2,1},}; static const HuffmanTyp mpc_table_Entropie_4 [ 9] = {{4026531840u,4,3},{3758096384u,4,-3},{3221225472u,3,1},{2684354560u,3,-1},{2147483648u,3,2},{1610612736u,3,-2},{1342177280u,4,-4},{1073741824u,4,4},{0u,2,0},}; static const HuffmanTyp mpc_table_Entropie_5 [15] = {{4026531840u,4,-2},{3892314112u,5,-5},{3825205248u,6,-7},{3758096384u,6,7},{3489660928u,4,-3},{3221225472u,4,3},{3087007744u,5,-6},{2952790016u,5,6},{2684354560u,4,4},{2147483648u,3,0},{1610612736u,3,1},{1073741824u,3,-1},{805306368u,4,-4},{536870912u,4,5},{0u,3,2},}; static const HuffmanTyp mpc_table_Entropie_6 [31] = {{4160749568u,5,-4},{4026531840u,5,5},{3892314112u,5,-5},{3825205248u,6,10},{3758096384u,6,-10},{3623878656u,5,-6},{3489660928u,5,6},{3355443200u,5,7},{3221225472u,5,-7},{3087007744u,5,-8},{3019898880u,6,-11},{2986344448u,7,14},{2952790016u,7,-14},{2818572288u,5,8},{2751463424u,6,11},{2684354560u,6,-13},{2415919104u,4,0},{2147483648u,4,1},{1879048192u,4,-1},{1610612736u,4,3},{1342177280u,4,2},{1207959552u,5,-9},{1140850688u,6,12},{1073741824u,6,13},{805306368u,4,-3},{536870912u,4,-2},{402653184u,5,9},{335544320u,6,-12},{301989888u,7,15},{268435456u,7,-15},{0u,4,4},}; static const HuffmanTyp mpc_table_Entropie_7 [63] = {{4278190080u,8,28},{4261412864u,8,26},{4227858432u,7,-20},{4160749568u,6,8},{4093640704u,6,-8},{4026531840u,6,-9},{3959422976u,6,9},{3925868544u,7,20},{3892314112u,7,21},{3825205248u,6,-10},{3758096384u,6,-11},{3690987520u,6,10},{3623878656u,6,11},{3590324224u,7,-21},{3573547008u,8,29},{3556769792u,8,-29},{3489660928u,6,13},{3422552064u,6,-13},{3355443200u,6,-12},{3288334336u,6,12},{3254779904u,7,-22},{3221225472u,7,22},{3154116608u,6,14},{3087007744u,6,15},{3019898880u,6,-14},{2986344448u,7,-23},{2952790016u,7,23},{2885681152u,6,-15},{2818572288u,6,-16},{2751463424u,6,16},{2717908992u,7,27},{2684354560u,7,-27},{2617245696u,6,17},{2550136832u,6,-17},{2533359616u,8,-30},{2516582400u,8,30},{2483027968u,7,24},{2415919104u,6,-18},{2281701376u,5,-1},{2147483648u,5,1},{2113929216u,7,-24},{2080374784u,7,25},{2013265920u,6,18},{1879048192u,5,-3},{1744830464u,5,3},{1610612736u,5,5},{1476395008u,5,0},{1342177280u,5,-2},{1275068416u,6,19},{1207959552u,6,-19},{1073741824u,5,-5},{939524096u,5,-4},{805306368u,5,-7},{671088640u,5,2},{536870912u,5,4},{402653184u,5,7},{369098752u,7,-25},{335544320u,7,-26},{301989888u,7,-28},{285212672u,8,-31},{268435456u,8,31},{134217728u,5,6},{0u,5,-6},}; const HuffmanTyp* mpc_table_SampleHuff [18] = { NULL,mpc_table_Entropie_1,mpc_table_Entropie_2,mpc_table_Entropie_3,mpc_table_Entropie_4,mpc_table_Entropie_5,mpc_table_Entropie_6,mpc_table_Entropie_7,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; #endif //#ifdef MPC_SUPPORT_SV456 xine-lib-1.2/contrib/libmpcdec/diff_from_libmpcdec_1.2.5.patch0000644000175000017500000000077514647725152021760 0ustar memeUse xine's os_types.h file. Define MPC_LITTLE_ENDIAN when needed. Index: libmpcdec/mpcdec/config_types.h =================================================================== --- libmpcdec.orig/mpcdec/config_types.h +++ libmpcdec/mpcdec/config_types.h @@ -35,7 +35,11 @@ #ifndef __MUSEPACK_CONFIG_TYPES_H__ #define __MUSEPACK_CONFIG_TYPES_H__ -#include +#include "os_types.h" + +#ifndef WORDS_BIGENDIAN +# define MPC_LITTLE_ENDIAN +#endif typedef unsigned char mpc_bool_t; #define TRUE 1 xine-lib-1.2/contrib/libmpcdec/huffsv7.c0000644000175000017500000002304114647725152016002 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file huffsv7.c /// Implementations of sv7 huffman decoding functions. #include #include #include const HuffmanTyp mpc_table_HuffHdr [10] = {{2147483648u,1,0},{1610612736u,3,1},{1577058304u,7,-4},{1568669696u,9,3},{1560281088u,9,4},{1543503872u,8,-5},{1476395008u,6,2},{1342177280u,5,-3},{1073741824u,4,-2},{0u,2,-1},}; const HuffmanTyp mpc_table_HuffSCFI [ 4] = {{2147483648u,1,1},{1610612736u,3,2},{1073741824u,3,0},{0u,2,3},}; const HuffmanTyp mpc_table_HuffDSCF [16] = {{4160749568u,5,5},{4026531840u,5,-4},{3758096384u,4,3},{3489660928u,4,-3},{3221225472u,4,8},{2684354560u,3,1},{2415919104u,4,0},{2281701376u,5,-5},{2214592512u,6,7},{2147483648u,6,-7},{1610612736u,3,-1},{1073741824u,3,2},{805306368u,4,4},{671088640u,5,6},{536870912u,5,-6},{0u,3,-2},}; static const HuffmanTyp mpc_table_HuffQ1 [2] [3*3*3] = { {{3758096384u,3,13},{3690987520u,6,26},{3623878656u,6,0},{3556769792u,6,20},{3489660928u,6,6},{3221225472u,4,14},{2952790016u,4,12},{2684354560u,4,4},{2415919104u,4,22},{2348810240u,6,8},{2281701376u,6,18},{2214592512u,6,24},{2147483648u,6,2},{1879048192u,4,16},{1610612736u,4,10},{1476395008u,5,17},{1342177280u,5,9},{1207959552u,5,1},{1073741824u,5,25},{939524096u,5,5},{805306368u,5,21},{671088640u,5,3},{536870912u,5,11},{402653184u,5,15},{268435456u,5,23},{134217728u,5,19},{0u,5,7},}, {{2147483648u,1,13},{2113929216u,7,15},{2080374784u,7,1},{2046820352u,7,11},{2013265920u,7,7},{1979711488u,7,17},{1946157056u,7,25},{1912602624u,7,19},{1904214016u,9,8},{1895825408u,9,18},{1887436800u,9,2},{1879048192u,9,24},{1845493760u,7,3},{1811939328u,7,23},{1778384896u,7,21},{1744830464u,7,5},{1728053248u,8,0},{1711276032u,8,26},{1694498816u,8,6},{1677721600u,8,20},{1610612736u,6,9},{1342177280u,4,14},{1073741824u,4,12},{805306368u,4,4},{536870912u,4,22},{268435456u,4,16},{0u,4,10},}, }; static const HuffmanTyp mpc_table_HuffQ2 [2] [5*5] = { {{4026531840u,4,13},{3758096384u,4,17},{3489660928u,4,7},{3221225472u,4,11},{3154116608u,6,1},{3087007744u,6,23},{3053453312u,7,4},{3019898880u,7,20},{2986344448u,7,0},{2952790016u,7,24},{2818572288u,5,22},{2684354560u,5,10},{2147483648u,3,12},{2013265920u,5,2},{1879048192u,5,14},{1610612736u,4,6},{1342177280u,4,18},{1073741824u,4,8},{805306368u,4,16},{671088640u,5,9},{536870912u,5,5},{402653184u,5,15},{268435456u,5,21},{134217728u,5,19},{0u,5,3},}, {{4160749568u,5,18},{4026531840u,5,6},{3892314112u,5,8},{3875536896u,8,3},{3871342592u,10,24},{3867148288u,10,4},{3862953984u,10,0},{3858759680u,10,20},{3825205248u,7,23},{3791650816u,7,1},{3758096384u,7,19},{3623878656u,5,16},{3590324224u,7,15},{3556769792u,7,21},{3523215360u,7,9},{3489660928u,7,5},{3422552064u,6,2},{3355443200u,6,10},{3288334336u,6,14},{3221225472u,6,22},{2147483648u,2,12},{1610612736u,3,13},{1073741824u,3,17},{536870912u,3,11},{0u,3,7},}, }; static const HuffmanTyp mpc_table_HuffQ3 [2] [ 7] = { {{3758096384u,3,1},{3489660928u,4,3},{3221225472u,4,-3},{2684354560u,3,2},{2147483648u,3,-2},{1073741824u,2,0},{0u,2,-1},}, {{3221225472u,2,0},{2147483648u,2,-1},{1073741824u,2,1},{805306368u,4,-2},{671088640u,5,3},{536870912u,5,-3},{0u,3,2},}, }; static const HuffmanTyp mpc_table_HuffQ4 [2] [ 9] = { {{3758096384u,3,0},{3221225472u,3,-1},{2684354560u,3,1},{2147483648u,3,-2},{1610612736u,3,2},{1342177280u,4,-4},{1073741824u,4,4},{536870912u,3,3},{0u,3,-3},}, {{3758096384u,3,1},{3489660928u,4,2},{3221225472u,4,-3},{2147483648u,2,0},{1610612736u,3,-2},{1342177280u,4,3},{1207959552u,5,-4},{1073741824u,5,4},{0u,2,-1},}, }; static const HuffmanTyp mpc_table_HuffQ5 [2] [15] = { {{4026531840u,4,2},{3892314112u,5,5},{3825205248u,6,-7},{3758096384u,6,7},{3489660928u,4,-3},{3221225472u,4,3},{3087007744u,5,-6},{2952790016u,5,6},{2684354560u,4,-4},{2415919104u,4,4},{2147483648u,4,-5},{1610612736u,3,0},{1073741824u,3,-1},{536870912u,3,1},{0u,3,-2},}, {{4026531840u,4,3},{3892314112u,5,4},{3858759680u,7,6},{3841982464u,8,-7},{3825205248u,8,7},{3758096384u,6,-6},{3221225472u,3,0},{2684354560u,3,-1},{2147483648u,3,1},{1610612736u,3,-2},{1073741824u,3,2},{939524096u,5,-5},{805306368u,5,5},{536870912u,4,-4},{0u,3,-3},}, }; static const HuffmanTyp mpc_table_HuffQ6 [2] [31] = { {{4160749568u,5,3},{4026531840u,5,-4},{3959422976u,6,-11},{3892314112u,6,12},{3758096384u,5,4},{3623878656u,5,6},{3489660928u,5,-5},{3355443200u,5,5},{3221225472u,5,7},{3087007744u,5,-7},{3019898880u,6,-12},{2952790016u,6,-13},{2818572288u,5,-6},{2684354560u,5,8},{2550136832u,5,-8},{2415919104u,5,9},{2281701376u,5,-9},{2214592512u,6,13},{2181038080u,7,-15},{2147483648u,7,15},{1879048192u,4,0},{1744830464u,5,-10},{1610612736u,5,10},{1342177280u,4,-1},{1073741824u,4,2},{805306368u,4,1},{536870912u,4,-2},{469762048u,6,14},{402653184u,6,-14},{268435456u,5,11},{0u,4,-3},}, {{4160749568u,5,-6},{4026531840u,5,6},{3758096384u,4,1},{3489660928u,4,-1},{3456106496u,7,10},{3422552064u,7,-10},{3405774848u,8,-11},{3397386240u,9,-12},{3395289088u,11,13},{3394764800u,13,15},{3394240512u,13,-14},{3393716224u,13,14},{3393191936u,13,-15},{3388997632u,10,-13},{3372220416u,8,11},{3355443200u,8,12},{3288334336u,6,-9},{3221225472u,6,9},{2952790016u,4,-2},{2684354560u,4,2},{2415919104u,4,3},{2147483648u,4,-3},{2013265920u,5,-7},{1879048192u,5,7},{1610612736u,4,-4},{1342177280u,4,4},{1207959552u,5,-8},{1073741824u,5,8},{805306368u,4,5},{536870912u,4,-5},{0u,3,0},}, }; static const HuffmanTyp mpc_table_HuffQ7 [2] [63] = { {{4227858432u,6,7},{4160749568u,6,8},{4093640704u,6,9},{4026531840u,6,-8},{3959422976u,6,11},{3925868544u,7,21},{3909091328u,8,-28},{3892314112u,8,28},{3825205248u,6,-9},{3791650816u,7,-22},{3758096384u,7,-21},{3690987520u,6,-10},{3623878656u,6,-11},{3556769792u,6,10},{3489660928u,6,12},{3422552064u,6,-13},{3388997632u,7,22},{3355443200u,7,23},{3288334336u,6,-12},{3221225472u,6,13},{3154116608u,6,14},{3087007744u,6,-14},{3053453312u,7,-23},{3036676096u,8,-29},{3019898880u,8,29},{2952790016u,6,-15},{2885681152u,6,15},{2818572288u,6,16},{2751463424u,6,-16},{2717908992u,7,-24},{2684354560u,7,24},{2617245696u,6,17},{2583691264u,7,-25},{2566914048u,8,-30},{2550136832u,8,30},{2483027968u,6,-17},{2415919104u,6,18},{2348810240u,6,-18},{2315255808u,7,25},{2281701376u,7,26},{2214592512u,6,19},{2181038080u,7,-26},{2147483648u,7,-27},{2013265920u,5,2},{1946157056u,6,-19},{1879048192u,6,20},{1744830464u,5,-1},{1728053248u,8,-31},{1711276032u,8,31},{1677721600u,7,27},{1610612736u,6,-20},{1476395008u,5,1},{1342177280u,5,-5},{1207959552u,5,-3},{1073741824u,5,3},{939524096u,5,0},{805306368u,5,-2},{671088640u,5,-4},{536870912u,5,4},{402653184u,5,5},{268435456u,5,-6},{134217728u,5,6},{0u,5,-7},}, {{4160749568u,5,-1},{4026531840u,5,2},{3892314112u,5,-2},{3758096384u,5,3},{3741319168u,8,-20},{3737124864u,10,24},{3736862720u,14,28},{3736600576u,14,-28},{3736338432u,14,-30},{3736076288u,14,30},{3735027712u,12,-27},{3734765568u,14,29},{3734503424u,14,-29},{3734241280u,14,31},{3733979136u,14,-31},{3732930560u,12,27},{3724541952u,9,-22},{3690987520u,7,-17},{3623878656u,6,-11},{3489660928u,5,-3},{3355443200u,5,4},{3221225472u,5,-4},{3187671040u,7,17},{3170893824u,8,20},{3162505216u,9,22},{3158310912u,10,-25},{3154116608u,10,-26},{3087007744u,6,12},{2952790016u,5,5},{2818572288u,5,-5},{2684354560u,5,6},{2550136832u,5,-6},{2483027968u,6,-12},{2449473536u,7,-18},{2415919104u,7,18},{2348810240u,6,13},{2281701376u,6,-13},{2147483648u,5,-7},{2080374784u,6,14},{2063597568u,8,21},{2046820352u,8,-21},{2013265920u,7,-19},{1879048192u,5,7},{1744830464u,5,8},{1677721600u,6,-14},{1610612736u,6,-15},{1476395008u,5,-8},{1409286144u,6,15},{1375731712u,7,19},{1371537408u,10,25},{1367343104u,10,26},{1358954496u,9,-23},{1350565888u,9,23},{1342177280u,9,-24},{1207959552u,5,-9},{1073741824u,5,9},{1006632960u,6,16},{939524096u,6,-16},{805306368u,5,10},{536870912u,4,0},{402653184u,5,-10},{268435456u,5,11},{0u,4,1},}, }; const HuffmanTyp* mpc_table_HuffQ [2] [8] = { {0,mpc_table_HuffQ1[0],mpc_table_HuffQ2[0],mpc_table_HuffQ3[0],mpc_table_HuffQ4[0],mpc_table_HuffQ5[0],mpc_table_HuffQ6[0],mpc_table_HuffQ7[0]}, {0,mpc_table_HuffQ1[1],mpc_table_HuffQ2[1],mpc_table_HuffQ3[1],mpc_table_HuffQ4[1],mpc_table_HuffQ5[1],mpc_table_HuffQ6[1],mpc_table_HuffQ7[1]}, }; xine-lib-1.2/contrib/libmpcdec/requant.c0000644000175000017500000000763414647725152016103 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file requant.c /// Requantization function implementations. /// \todo document me #include #include /* C O N S T A N T S */ // bits per sample for chosen quantizer const mpc_uint32_t Res_bit [18] = { 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; // coefficients for requantization // 65536/step bzw. 65536/(2*D+1) #define _(X) MAKE_MPC_SAMPLE_EX(X,14) const MPC_SAMPLE_FORMAT __Cc [1 + 18] = { _(111.285962475327f), // 32768/2/255*sqrt(3) _(65536.000000000000f), _(21845.333333333332f), _(13107.200000000001f), _(9362.285714285713f), _(7281.777777777777f), _(4369.066666666666f), _(2114.064516129032f), _(1040.253968253968f), _(516.031496062992f), _(257.003921568627f), _(128.250489236790f), _(64.062561094819f), _(32.015632633121f), _(16.003907203907f), _(8.000976681723f), _(4.000244155527f), _(2.000061037018f), _(1.000015259021f) }; #undef _ // offset for requantization // 2*D+1 = steps of quantizer const mpc_int32_t __Dc [1 + 18] = { 2, 0, 1, 2, 3, 4, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767 }; #ifdef MPC_FIXED_POINT static mpc_uint32_t find_shift(double fval) { mpc_int64_t val = (mpc_int64_t)fval; mpc_uint32_t ptr = 0; if (val<0) val = -val; while(val) {val>>=1;ptr++;} return ptr > 31 ? 0 : 31 - ptr; } #endif /* F U N C T I O N S */ #define SET_SCF(N,X) d->SCF[N] = MAKE_MPC_SAMPLE_EX(X,d->SCF_shift[N] = (unsigned char)find_shift(X)); void mpc_decoder_scale_output(mpc_decoder *d, double factor) { mpc_int32_t n; double f1; double f2; #ifndef MPC_FIXED_POINT factor *= 1.0 / (double)(1<<(MPC_FIXED_POINT_SHIFT-1)); #else factor *= 1.0 / (double)(1<<(16 - MPC_FIXED_POINT_SHIFT)); #endif f1 = f2 = factor; // handles +1.58...-98.41 dB, where's scf[n] / scf[n-1] = 1.20050805774840750476 SET_SCF(1,factor); f1 *= 0.83298066476582673961; f2 *= 1/0.83298066476582673961; for ( n = 1; n <= 128; n++ ) { SET_SCF((unsigned char)(1+n),f1); SET_SCF((unsigned char)(1-n),f2); f1 *= 0.83298066476582673961; f2 *= 1/0.83298066476582673961; } } void mpc_decoder_initialisiere_quantisierungstabellen(mpc_decoder *d, double scale_factor) { mpc_decoder_scale_output(d, scale_factor); } xine-lib-1.2/contrib/libmpcdec/COPYING0000644000175000017500000000303314647725152015300 0ustar memeCopyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. xine-lib-1.2/contrib/libmpcdec/idtag.c0000644000175000017500000000553414647725152015511 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file idtag.c /// Rudimentary id3tag handling routines, just enough to skip id3v2 tags, /// if present. #include #include mpc_int32_t JumpID3v2 (mpc_reader* r) { unsigned char tmp [10]; #if 0 mpc_uint32_t Unsynchronisation; // ID3v2.4-flag mpc_uint32_t ExtHeaderPresent; // ID3v2.4-flag mpc_uint32_t ExperimentalFlag; // ID3v2.4-flag #endif mpc_uint32_t FooterPresent; // ID3v2.4-flag mpc_int32_t ret; // seek to first byte of mpc data if (!r->seek (r->data, 0)) { return 0; } r->read(r->data, tmp, sizeof(tmp)); // check id3-tag if ( 0 != memcmp ( tmp, "ID3", 3) ) return 0; // read flags #if 0 Unsynchronisation = tmp[5] & 0x80; ExtHeaderPresent = tmp[5] & 0x40; ExperimentalFlag = tmp[5] & 0x20; #endif FooterPresent = tmp[5] & 0x10; if ( tmp[5] & 0x0F ) return -1; // not (yet???) allowed if ( (tmp[6] | tmp[7] | tmp[8] | tmp[9]) & 0x80 ) return -1; // not allowed // read HeaderSize (syncsave: 4 * $0xxxxxxx = 28 significant bits) ret = tmp[6] << 21; ret += tmp[7] << 14; ret += tmp[8] << 7; ret += tmp[9] ; ret += 10; if ( FooterPresent ) ret += 10; return ret; } xine-lib-1.2/contrib/libmpcdec/mpc_reader.c0000644000175000017500000000566014647725152016522 0ustar meme/* Copyright (c) 2005, The Musepack Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the The Musepack Development Team 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 COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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. */ /// \file mpc_reader.c /// Contains implementations for simple file-based mpc_reader #include /// mpc_reader callback implementations static mpc_int32_t read_impl(void *data, void *ptr, mpc_int32_t size) { mpc_reader_file *d = (mpc_reader_file *) data; return (mpc_int32_t) fread(ptr, 1, size, d->file); } static mpc_bool_t seek_impl(void *data, mpc_int32_t offset) { mpc_reader_file *d = (mpc_reader_file *) data; return d->is_seekable ? fseek(d->file, offset, SEEK_SET) == 0 : FALSE; } static mpc_int32_t tell_impl(void *data) { mpc_reader_file *d = (mpc_reader_file *) data; return ftell(d->file); } static mpc_int32_t get_size_impl(void *data) { mpc_reader_file *d = (mpc_reader_file *) data; return d->file_size; } static mpc_bool_t canseek_impl(void *data) { mpc_reader_file *d = (mpc_reader_file *) data; return d->is_seekable; } void mpc_reader_setup_file_reader(mpc_reader_file *p_reader, FILE *input) { p_reader->reader.seek = seek_impl; p_reader->reader.read = read_impl; p_reader->reader.tell = tell_impl; p_reader->reader.get_size = get_size_impl; p_reader->reader.canseek = canseek_impl; p_reader->reader.data = p_reader; // point back to ourselves p_reader->file = input; p_reader->is_seekable = TRUE; fseek(input, 0, SEEK_END); p_reader->file_size = ftell(input); fseek(input, 0, SEEK_SET); } xine-lib-1.2/contrib/libdca/0000755000175000017500000000000014647725151013541 5ustar memexine-lib-1.2/contrib/libdca/tables_quantization.h0000644000175000017500000001037314647725151017776 0ustar meme/* * tables_quantization.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ static const int scale_factor_quant6[] = { 1, 2, 2, 3, 3, 4, 6, 7, 10, 12, 16, 20, 26, 34, 44, 56, 72, 93, 120, 155, 200, 257, 331, 427, 550, 708, 912, 1175, 1514, 1950, 2512, 3236, 4169, 5370, 6918, 8913, 11482, 14791, 19055, 24547, 31623, 40738, 52481, 67608, 87096, 112202, 144544, 186209, 239883, 309030, 398107, 512861, 660693, 851138, 1096478, 1412538, 1819701, 2344229, 3019952, 3890451, 5011872, 6456542, 8317638, 0 }; static const int scale_factor_quant7[] = { 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 6, 7, 7, 8, 10, 11, 12, 14, 16, 18, 20, 23, 26, 30, 34, 38, 44, 50, 56, 64, 72, 82, 93, 106, 120, 136, 155, 176, 200, 226, 257, 292, 331, 376, 427, 484, 550, 624, 708, 804, 912, 1035, 1175, 1334, 1514, 1718, 1950, 2213, 2512, 2851, 3236, 3673, 4169, 4732, 5370, 6095, 6918, 7852, 8913, 10116, 11482, 13032, 14791, 16788, 19055, 21627, 24547, 27861, 31623, 35892, 40738, 46238, 52481, 59566, 67608, 76736, 87096, 98855, 112202, 127350, 144544, 164059, 186209, 211349, 239883, 272270, 309030, 350752, 398107, 451856, 512861, 582103, 660693, 749894, 851138, 966051, 1096478, 1244515, 1412538, 1603245, 1819701, 2065380, 2344229, 2660725, 3019952, 3427678, 3890451, 4415704, 5011872, 5688529, 6456542, 7328245, 8317638, 0, 0, 0 }; /* 20bits unsigned fractional binary codes */ static const int lossy_quant[] = { 0, 6710886, 4194304, 3355443, 2474639, 2097152, 1761608, 1426063, 796918, 461373, 251658, 146801, 79692, 46137, 27263, 16777, 10486, 5872, 3355, 1887, 1258, 713, 336, 168, 84, 42, 21, 0, 0, 0, 0, 0 }; static const double lossy_quant_d[] = { 0, 1.6, 1.0, 0.8, 0.59, 0.50, 0.42, 0.34, 0.19, 0.11, 0.06, 0.035, 0.019, 0.011, 0.0065, 0.0040, 0.0025, 0.0014, 0.0008, 0.00045, 0.00030, 0.00017, 0.00008, 0.00004, 0.00002, 0.00001, 0.000005, 0, 0, 0, 0, 0 }; /* 20bits unsigned fractional binary codes */ static const int lossless_quant[] = { 0, 4194304, 2097152, 1384120, 1048576, 696254, 524288, 348127, 262144, 131072, 65431, 33026, 16450, 8208, 4100, 2049, 1024, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1, 0, 0, 0, 0, 0 }; static const double lossless_quant_d[] = { 0, 1.0, 0.5, 0.33, 0.25, 0.166, 0.125, 0.083, 0.0625, 0.03125, 0.0156, 7.874E-3, 3.922E-3, 1.957E-3, 9.775E-4, 4.885E-4, 2.442E-4, 1.221E-4, 6.104E-5, 3.052E-5, 1.526E-5, 7.629E-6, 3.815E-6, 1.907E-6, 9.537E-7, 4.768E-7, 2.384E-7, 0, 0, 0, 0, 0 }; xine-lib-1.2/contrib/libdca/dca_internal.h0000644000175000017500000002007114647725151016335 0ustar meme/* * dca_internal.h * Copyright (C) 2004 Gildas Bazin * Copyright (C) 2000-2003 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #define DCA_SUBFRAMES_MAX (16) #define DCA_PRIM_CHANNELS_MAX (5) #define DCA_SUBBANDS (32) #define DCA_ABITS_MAX (32) /* Should be 28 */ #define DCA_SUBSUBFAMES_MAX (4) #define DCA_LFE_MAX (3) struct dca_state_s { /* Frame header */ int frame_type; /* type of the current frame */ int samples_deficit; /* deficit sample count */ int crc_present; /* crc is present in the bitstream */ int sample_blocks; /* number of PCM sample blocks */ int frame_size; /* primary frame byte size */ int amode; /* audio channels arrangement */ int sample_rate; /* audio sampling rate */ int bit_rate; /* transmission bit rate */ int downmix; /* embedded downmix enabled */ int dynrange; /* embedded dynamic range flag */ int timestamp; /* embedded time stamp flag */ int aux_data; /* auxiliary data flag */ int hdcd; /* source material is mastered in HDCD */ int ext_descr; /* extension audio descriptor flag */ int ext_coding; /* extended coding flag */ int aspf; /* audio sync word insertion flag */ int lfe; /* low frequency effects flag */ int predictor_history; /* predictor history flag */ int header_crc; /* header crc check bytes */ int multirate_inter; /* multirate interpolator switch */ int version; /* encoder software revision */ int copy_history; /* copy history */ int source_pcm_res; /* source pcm resolution */ int front_sum; /* front sum/difference flag */ int surround_sum; /* surround sum/difference flag */ int dialog_norm; /* dialog normalisation parameter */ /* Primary audio coding header */ int subframes; /* number of subframes */ int prim_channels; /* number of primary audio channels */ /* subband activity count */ int subband_activity[DCA_PRIM_CHANNELS_MAX]; /* high frequency vq start subband */ int vq_start_subband[DCA_PRIM_CHANNELS_MAX]; /* joint intensity coding index */ int joint_intensity[DCA_PRIM_CHANNELS_MAX]; /* transient mode code book */ int transient_huffman[DCA_PRIM_CHANNELS_MAX]; /* scale factor code book */ int scalefactor_huffman[DCA_PRIM_CHANNELS_MAX]; /* bit allocation quantizer select */ int bitalloc_huffman[DCA_PRIM_CHANNELS_MAX]; /* quantization index codebook select */ int quant_index_huffman[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; /* scale factor adjustment */ float scalefactor_adj[DCA_PRIM_CHANNELS_MAX][DCA_ABITS_MAX]; /* Primary audio coding side information */ int subsubframes; /* number of subsubframes */ int partial_samples; /* partial subsubframe samples count */ /* prediction mode (ADPCM used or not) */ int prediction_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; /* prediction VQ coefs */ int prediction_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; /* bit allocation index */ int bitalloc[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; /* transition mode (transients) */ int transition_mode[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; /* scale factors (2 if transient)*/ int scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][2]; /* joint subband scale factors codebook */ int joint_huff[DCA_PRIM_CHANNELS_MAX]; /* joint subband scale factors */ int joint_scale_factor[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; /* stereo downmix coefficients */ int downmix_coef[DCA_PRIM_CHANNELS_MAX][2]; /* dynamic range coefficient */ int dynrange_coef; /* VQ encoded high frequency subbands */ int high_freq_vq[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS]; /* Low frequency effect data */ double lfe_data[2*DCA_SUBSUBFAMES_MAX*DCA_LFE_MAX * 2 /*history*/]; int lfe_scale_factor; /* Subband samples history (for ADPCM) */ double subband_samples_hist[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][4]; double subband_fir_hist[DCA_PRIM_CHANNELS_MAX][512]; double subband_fir_noidea[DCA_PRIM_CHANNELS_MAX][64]; /* Audio output */ level_t clev; /* centre channel mix level */ level_t slev; /* surround channels mix level */ int output; /* type of output */ level_t level; /* output level */ sample_t bias; /* output bias */ sample_t * samples; /* pointer to the internal audio samples buffer */ int downmixed; int dynrnge; /* apply dynamic range */ level_t dynrng; /* dynamic range */ void * dynrngdata; /* dynamic range callback funtion and data */ level_t (* dynrngcall) (level_t range, void * dynrngdata); /* Bitstream handling */ uint32_t * buffer_start; uint32_t bits_left; uint32_t current_word; int word_mode; /* 16/14 bits word format (1 -> 16, 0 -> 14) */ int bigendian_mode; /* endianness (1 -> be, 0 -> le) */ /* Current position in DTS frame */ int current_subframe; int current_subsubframe; /* Pre-calculated cosine modulation coefs for the QMF */ double cos_mod[544]; /* Debug flag */ int debug_flag; }; #define LEVEL_PLUS6DB 2.0 #define LEVEL_PLUS3DB 1.4142135623730951 #define LEVEL_3DB 0.7071067811865476 #define LEVEL_45DB 0.5946035575013605 #define LEVEL_6DB 0.5 int dca_downmix_init (int input, int flags, level_t * level, level_t clev, level_t slev); int dca_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, level_t clev, level_t slev); void dca_downmix (sample_t * samples, int acmod, int output, sample_t bias, level_t clev, level_t slev); void dca_upmix (sample_t * samples, int acmod, int output); #define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5))) #ifndef LIBDCA_FIXED typedef sample_t quantizer_t; #define SAMPLE(x) (x) #define LEVEL(x) (x) #define MUL(a,b) ((a) * (b)) #define MUL_L(a,b) ((a) * (b)) #define MUL_C(a,b) ((a) * (b)) #define DIV(a,b) ((a) / (b)) #define BIAS(x) ((x) + bias) #else /* LIBDCA_FIXED */ typedef int16_t quantizer_t; #define SAMPLE(x) (sample_t)((x) * (1 << 30)) #define LEVEL(x) (level_t)((x) * (1 << 26)) #if 0 #define MUL(a,b) ((int)(((int64_t)(a) * (b) + (1 << 29)) >> 30)) #define MUL_L(a,b) ((int)(((int64_t)(a) * (b) + (1 << 25)) >> 26)) #elif 1 #define MUL(a,b) \ ({ int32_t _ta=(a), _tb=(b), _tc; \ _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)(((_tc >> 14))+ (((_ta >> 16)*(_tb >> 16)) << 2 )); }) #define MUL_L(a,b) \ ({ int32_t _ta=(a), _tb=(b), _tc; \ _tc=(_ta & 0xffff)*(_tb >> 16)+(_ta >> 16)*(_tb & 0xffff); (int32_t)((_tc >> 10) + (((_ta >> 16)*(_tb >> 16)) << 6)); }) #else #define MUL(a,b) (((a) >> 15) * ((b) >> 15)) #define MUL_L(a,b) (((a) >> 13) * ((b) >> 13)) #endif #define MUL_C(a,b) MUL_L (a, LEVEL (b)) #define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b)) #define BIAS(x) (x) #endif xine-lib-1.2/contrib/libdca/tables_huffman.h0000644000175000017500000015334514647725151016703 0ustar meme/* * huffman_tables.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ typedef struct huff_entry_s { int length; int code; int value; } huff_entry_t; static const huff_entry_t bitalloc_a_12[] = { { 1, 0, 1}, { 2, 2, 2}, { 3, 6, 3}, { 4, 14, 4}, { 5, 30, 5}, { 6, 62, 6}, { 8, 255, 7}, { 8, 254, 8}, { 9, 507, 9}, { 9, 506, 10}, { 9, 505, 11}, { 9, 504, 12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_12[] = { { 1, 1, 1}, { 2, 0, 2}, { 3, 2, 3}, { 5, 15, 4}, { 5, 12, 5}, { 6, 29, 6}, { 7, 57, 7}, { 7, 56, 8}, { 7, 55, 9}, { 7, 54, 10}, { 7, 53, 11}, { 7, 52, 12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_12[] = { { 2, 0, 1}, { 3, 7, 2}, { 3, 5, 3}, { 3, 4, 4}, { 3, 2, 5}, { 4, 13, 6}, { 4, 12, 7}, { 4, 6, 8}, { 5, 15, 9}, { 6, 29, 10}, { 7, 57, 11}, { 7, 56, 12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_d_12[] = { { 2, 3, 1}, { 2, 2, 2}, { 2, 0, 3}, { 3, 2, 4}, { 4, 6, 5}, { 5, 14, 6}, { 6, 30, 7}, { 7, 62, 8}, { 8, 126, 9}, { 9, 254, 10}, {10, 511, 11}, {10, 510, 12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_e_12[] = { { 1, 1, 1}, { 2, 0, 2}, { 3, 2, 3}, { 4, 6, 4}, { 5, 14, 5}, { 7, 63, 6}, { 7, 61, 7}, { 8, 124, 8}, { 8, 121, 9}, { 8, 120, 10}, { 9, 251, 11}, { 9, 250, 12}, { 0, 0, 0} }; static const huff_entry_t *const bitalloc_12[] = { bitalloc_a_12, bitalloc_b_12, bitalloc_c_12, bitalloc_d_12, bitalloc_e_12 }; static const huff_entry_t scales_a_129[] = { { 2, 1, 0}, { 3, 6, 1}, { 3, 5, -1}, { 3, 0, 2}, { 4, 15, -2}, { 4, 8, 3}, { 4, 3, -3}, { 5, 28, 4}, { 5, 19, -4}, { 5, 4, 5}, { 6, 59, -5}, { 6, 36, 6}, { 6, 11, -6}, { 7, 75, 7}, { 7, 74, -7}, { 8, 233, 8}, { 8, 232, -8}, { 8, 41, 9}, { 8, 40, -9}, { 9, 87, 10}, { 9, 86,-10}, {10, 937, 11}, {10, 936,-11}, {11, 1877, 12}, {11, 1876,-12}, {11, 341, 13}, {11, 340,-13}, {12, 686, 14}, {12, 685,-14}, {13, 1375, 15}, {13, 1374,-15}, {13, 1369, 16}, {13, 1368,-16}, {13, 1359, 17}, {13, 1358,-17}, {13, 1357, 18}, {13, 1356,-18}, {13, 1355, 19}, {13, 1354,-19}, {13, 1353, 20}, {13, 1352,-20}, {13, 1351, 21}, {13, 1350,-21}, {13, 1349, 22}, {13, 1348,-22}, {13, 1347, 23}, {13, 1346,-23}, {13, 1345, 24}, {13, 1344,-24}, {14, 15103, 25}, {14, 15102,-25}, {14, 15101, 26}, {14, 15100,-26}, {14, 15099, 27}, {14, 15098,-27}, {14, 15097, 28}, {14, 15096,-28}, {14, 15095, 29}, {14, 15094,-29}, {14, 15093, 30}, {14, 15092,-30}, {14, 15091, 31}, {14, 15090,-31}, {14, 15089, 32}, {14, 15088,-32}, {14, 15087, 33}, {14, 15086,-33}, {14, 15085, 34}, {14, 15084,-34}, {14, 15083, 35}, {14, 15082,-35}, {14, 15081, 36}, {14, 15080,-36}, {14, 15079, 37}, {14, 15078,-37}, {14, 15077, 38}, {14, 15076,-38}, {14, 15075, 39}, {14, 15074,-39}, {14, 15073, 40}, {14, 15072,-40}, {14, 15071, 41}, {14, 15070,-41}, {14, 15069, 42}, {14, 15068,-42}, {14, 15067, 43}, {14, 15066,-43}, {14, 15065, 44}, {14, 15064,-44}, {14, 15063, 45}, {14, 15062,-45}, {14, 15061, 46}, {14, 15060,-46}, {14, 15059, 47}, {14, 15058,-47}, {14, 15057, 48}, {14, 15056,-48}, {14, 15055, 49}, {14, 15054,-49}, {14, 15053, 50}, {14, 15052,-50}, {14, 15051, 51}, {14, 15050,-51}, {14, 15049, 52}, {14, 15048,-52}, {14, 15047, 53}, {14, 15046,-53}, {14, 15045, 54}, {14, 15044,-54}, {14, 15043, 55}, {14, 15042,-55}, {14, 15041, 56}, {14, 15040,-56}, {14, 15039, 57}, {14, 15038,-57}, {14, 15037, 58}, {14, 15036,-58}, {14, 15035, 59}, {14, 15034,-59}, {14, 15033, 60}, {14, 15032,-60}, {14, 15031, 61}, {14, 15030,-61}, {14, 15029, 62}, {14, 15028,-62}, {14, 15027, 63}, {14, 15026,-63}, {14, 15025, 64}, {14, 15024,-64}, { 0, 0, 0} }; static const huff_entry_t scales_b_129[] = { { 3, 3, 0}, { 3, 2, 1}, { 3, 1, -1}, { 4, 15, 2}, { 4, 14, -2}, { 4, 12, 3}, { 4, 11, -3}, { 4, 10, 4}, { 4, 9, -4}, { 4, 0, 5}, { 5, 27, -5}, { 5, 17, 6}, { 5, 16, -6}, { 6, 53, 7}, { 6, 52, -7}, { 6, 5, 8}, { 6, 4, -8}, { 7, 13, 9}, { 7, 12, -9}, { 8, 29, 10}, { 8, 28,-10}, { 9, 60, 11}, {10, 127,-11}, {11, 253, 12}, {11, 252,-12}, {12, 491, 13}, {12, 490,-13}, {13, 979, 14}, {13, 978,-14}, {14, 1955, 15}, {14, 1954,-15}, {14, 1953, 16}, {14, 1952,-16}, {15, 4031, 17}, {15, 4030,-17}, {15, 4029, 18}, {15, 4028,-18}, {15, 4027, 19}, {15, 4026,-19}, {15, 4025, 20}, {15, 4024,-20}, {15, 4023, 21}, {15, 4022,-21}, {15, 4021, 22}, {15, 4020,-22}, {15, 4019, 23}, {15, 4018,-23}, {15, 4017, 24}, {15, 4016,-24}, {15, 4015, 25}, {15, 4014,-25}, {15, 4013, 26}, {15, 4012,-26}, {15, 4011, 27}, {15, 4010,-27}, {15, 4009, 28}, {15, 4008,-28}, {15, 4007, 29}, {15, 4006,-29}, {15, 4005, 30}, {15, 4004,-30}, {15, 4003, 31}, {15, 4002,-31}, {15, 4001, 32}, {15, 4000,-32}, {15, 3999, 33}, {15, 3998,-33}, {15, 3997, 34}, {15, 3996,-34}, {15, 3995, 35}, {15, 3994,-35}, {15, 3993, 36}, {15, 3992,-36}, {15, 3991, 37}, {15, 3990,-37}, {15, 3989, 38}, {15, 3988,-38}, {15, 3987, 39}, {15, 3986,-39}, {15, 3985, 40}, {15, 3984,-40}, {15, 3983, 41}, {15, 3982,-41}, {15, 3981, 42}, {15, 3980,-42}, {15, 3979, 43}, {15, 3978,-43}, {15, 3977, 44}, {15, 3976,-44}, {15, 3975, 45}, {15, 3974,-45}, {15, 3973, 46}, {15, 3972,-46}, {15, 3971, 47}, {15, 3970,-47}, {15, 3969, 48}, {15, 3968,-48}, {15, 3967, 49}, {15, 3966,-49}, {15, 3965, 50}, {15, 3964,-50}, {15, 3963, 51}, {15, 3962,-51}, {15, 3961, 52}, {15, 3960,-52}, {15, 3959, 53}, {15, 3958,-53}, {15, 3957, 54}, {15, 3956,-54}, {15, 3955, 55}, {15, 3954,-55}, {15, 3953, 56}, {15, 3952,-56}, {15, 3951, 57}, {15, 3950,-57}, {15, 3949, 58}, {15, 3948,-58}, {15, 3947, 59}, {15, 3946,-59}, {15, 3945, 60}, {15, 3944,-60}, {15, 3943, 61}, {15, 3942,-61}, {15, 3941, 62}, {15, 3940,-62}, {15, 3939, 63}, {15, 3938,-63}, {15, 3937, 64}, {15, 3936,-64}, { 0, 0, 0} }; static const huff_entry_t scales_c_129[] = { { 3, 4, 0}, { 3, 1, 1}, { 3, 0, -1}, { 4, 13, 2}, { 4, 12, -2}, { 4, 7, 3}, { 4, 6, -3}, { 5, 31, 4}, { 5, 30, -4}, { 5, 23, 5}, { 5, 22, -5}, { 5, 11, 6}, { 5, 10, -6}, { 6, 59, 7}, { 6, 58, -7}, { 6, 43, 8}, { 6, 42, -8}, { 6, 19, 9}, { 6, 18, -9}, { 7, 115, 10}, { 7, 114,-10}, { 7, 83, 11}, { 7, 82,-11}, { 7, 35, 12}, { 7, 34,-12}, { 8, 227, 13}, { 8, 226,-13}, { 8, 162, 14}, { 8, 161,-14}, { 8, 66, 15}, { 8, 65,-15}, { 9, 450, 16}, { 9, 449,-16}, { 9, 321, 17}, { 9, 320,-17}, { 9, 129, 18}, { 9, 128,-18}, {10, 897, 19}, {10, 896,-19}, {10, 652, 20}, {10, 271,-20}, {10, 268, 21}, {11, 1807,-21}, {11, 1308, 22}, {11, 1307,-22}, {11, 540, 23}, {11, 539,-23}, {12, 3612, 24}, {12, 3611,-24}, {12, 2613, 25}, {12, 2612,-25}, {12, 1077, 26}, {12, 1076,-26}, {13, 7226, 27}, {13, 7221,-27}, {13, 2167, 28}, {13, 2166,-28}, {13, 2164, 29}, {14, 14455,-29}, {14, 14441, 30}, {14, 14440,-30}, {14, 4331, 31}, {14, 4330,-31}, {15, 28909, 32}, {15, 28908,-32}, {15, 28879, 33}, {15, 28878,-33}, {15, 28877, 34}, {15, 28876,-34}, {15, 28875, 35}, {15, 28874,-35}, {15, 28873, 36}, {15, 28872,-36}, {15, 28871, 37}, {15, 28870,-37}, {15, 28869, 38}, {15, 28868,-38}, {15, 28867, 39}, {15, 28866,-39}, {15, 28865, 40}, {15, 28864,-40}, {15, 20991, 41}, {15, 20990,-41}, {15, 20989, 42}, {15, 20988,-42}, {15, 20987, 43}, {15, 20986,-43}, {15, 20985, 44}, {15, 20984,-44}, {15, 20983, 45}, {15, 20982,-45}, {15, 20981, 46}, {15, 20980,-46}, {15, 20979, 47}, {15, 20978,-47}, {15, 20977, 48}, {15, 20976,-48}, {15, 20975, 49}, {15, 20974,-49}, {15, 20973, 50}, {15, 20972,-50}, {15, 20971, 51}, {15, 20970,-51}, {15, 20969, 52}, {15, 20968,-52}, {15, 20967, 53}, {15, 20966,-53}, {15, 20965, 54}, {15, 20964,-54}, {15, 20963, 55}, {15, 20962,-55}, {15, 20961, 56}, {15, 20960,-56}, {15, 20959, 57}, {15, 20958,-57}, {15, 20957, 58}, {15, 20956,-58}, {15, 20955, 59}, {15, 20954,-59}, {15, 20953, 60}, {15, 20952,-60}, {15, 20951, 61}, {15, 20950,-61}, {15, 20949, 62}, {15, 20948,-62}, {15, 20947, 63}, {15, 20946,-63}, {15, 20945, 64}, {15, 20944,-64}, { 0, 0, 0} }; static const huff_entry_t scales_d_129[] = { { 2, 0, 0}, { 3, 5, 1}, { 3, 4, -1}, { 4, 15, 2}, { 4, 14, -2}, { 4, 7, 3}, { 4, 6, -3}, { 5, 26, 4}, { 5, 25, -4}, { 5, 10, 5}, { 5, 9, -5}, { 6, 54, 6}, { 6, 49, -6}, { 6, 22, 7}, { 6, 17, -7}, { 7, 110, 8}, { 7, 97, -8}, { 7, 46, 9}, { 7, 33, -9}, { 8, 193, 10}, { 8, 192,-10}, { 8, 65, 11}, { 8, 64,-11}, { 9, 444, 12}, { 9, 191,-12}, { 9, 188, 13}, {10, 895,-13}, {10, 890, 14}, {10, 381,-14}, {10, 378, 15}, {11, 1789,-15}, {11, 761, 16}, {11, 760,-16}, {12, 3577, 17}, {12, 3576,-17}, {12, 1519, 18}, {12, 1518,-18}, {12, 1516, 19}, {13, 7151,-19}, {13, 7128, 20}, {13, 3035,-20}, {14, 14301, 21}, {14, 14300,-21}, {14, 6069, 22}, {14, 6068,-22}, {15, 28599, 23}, {15, 28598,-23}, {15, 28597, 24}, {15, 28596,-24}, {15, 28595, 25}, {15, 28594,-25}, {15, 28593, 26}, {15, 28592,-26}, {15, 28591, 27}, {15, 28590,-27}, {15, 28589, 28}, {15, 28588,-28}, {15, 28587, 29}, {15, 28586,-29}, {15, 28585, 30}, {15, 28584,-30}, {15, 28583, 31}, {15, 28582,-31}, {15, 28581, 32}, {15, 28580,-32}, {15, 28579, 33}, {15, 28578,-33}, {15, 28577, 34}, {15, 28576,-34}, {15, 28575, 35}, {15, 28574,-35}, {15, 28573, 36}, {15, 28572,-36}, {15, 28571, 37}, {15, 28570,-37}, {15, 28569, 38}, {15, 28568,-38}, {15, 28567, 39}, {15, 28566,-39}, {15, 28565, 40}, {15, 28564,-40}, {15, 28563, 41}, {15, 28562,-41}, {15, 28561, 42}, {15, 28560,-42}, {15, 28559, 43}, {15, 28558,-43}, {15, 28557, 44}, {15, 28556,-44}, {15, 28555, 45}, {15, 28554,-45}, {15, 28553, 46}, {15, 28552,-46}, {15, 28551, 47}, {15, 28550,-47}, {15, 28549, 48}, {15, 28548,-48}, {15, 28547, 49}, {15, 28546,-49}, {15, 28545, 50}, {15, 28544,-50}, {15, 28543, 51}, {15, 28542,-51}, {15, 28541, 52}, {15, 28540,-52}, {15, 28539, 53}, {15, 28538,-53}, {15, 28537, 54}, {15, 28536,-54}, {15, 28535, 55}, {15, 28534,-55}, {15, 28533, 56}, {15, 28532,-56}, {15, 28531, 57}, {15, 28530,-57}, {15, 28529, 58}, {15, 28528,-58}, {15, 28527, 59}, {15, 28526,-59}, {15, 28525, 60}, {15, 28524,-60}, {15, 28523, 61}, {15, 28522,-61}, {15, 28521, 62}, {15, 28520,-62}, {15, 28519, 63}, {15, 28518,-63}, {15, 28517, 64}, {15, 28516,-64}, { 0, 0, 0} }; static const huff_entry_t scales_e_129[] = { { 4, 14, 0}, { 4, 11, 1}, { 4, 10, -1}, { 4, 7, 2}, { 4, 6, -2}, { 4, 3, 3}, { 4, 2, -3}, { 5, 31, 4}, { 5, 30, -4}, { 5, 25, 5}, { 5, 24, -5}, { 5, 17, 6}, { 5, 16, -6}, { 5, 9, 7}, { 5, 8, -7}, { 5, 1, 8}, { 5, 0, -8}, { 6, 53, 9}, { 6, 52, -9}, { 6, 37, 10}, { 6, 36,-10}, { 6, 21, 11}, { 6, 20,-11}, { 6, 5, 12}, { 6, 4,-12}, { 7, 109, 13}, { 7, 108,-13}, { 7, 77, 14}, { 7, 76,-14}, { 7, 45, 15}, { 7, 44,-15}, { 7, 13, 16}, { 7, 12,-16}, { 8, 221, 17}, { 8, 220,-17}, { 8, 157, 18}, { 8, 156,-18}, { 8, 93, 19}, { 8, 92,-19}, { 8, 29, 20}, { 8, 28,-20}, { 9, 445, 21}, { 9, 444,-21}, { 9, 317, 22}, { 9, 316,-22}, { 9, 189, 23}, { 9, 188,-23}, { 9, 61, 24}, { 9, 60,-24}, {10, 892, 25}, {10, 639,-25}, {10, 637, 26}, {10, 636,-26}, {10, 381, 27}, {10, 380,-27}, {10, 125, 28}, {10, 124,-28}, {11, 1788, 29}, {11, 1787,-29}, {11, 1276, 30}, {11, 767,-30}, {11, 764, 31}, {11, 255,-31}, {11, 252, 32}, {12, 3583,-32}, {12, 3579, 33}, {12, 3578,-33}, {12, 2555, 34}, {12, 2554,-34}, {12, 1531, 35}, {12, 1530,-35}, {12, 507, 36}, {12, 506,-36}, {13, 7160, 37}, {13, 7147,-37}, {13, 7144, 38}, {13, 3067,-38}, {13, 3065, 39}, {13, 3064,-39}, {13, 1017, 40}, {13, 1016,-40}, {14, 14330, 41}, {14, 14329,-41}, {14, 14291, 42}, {14, 14290,-42}, {14, 6132, 43}, {14, 2039,-43}, {14, 2038, 44}, {14, 2037,-44}, {15, 28663, 45}, {15, 28662,-45}, {15, 28585, 46}, {15, 28584,-46}, {15, 12267, 47}, {15, 12266,-47}, {15, 4073, 48}, {15, 4072,-48}, {16, 57315, 49}, {16, 57314,-49}, {16, 57313, 50}, {16, 57312,-50}, {16, 57311, 51}, {16, 57310,-51}, {16, 57309, 52}, {16, 57308,-52}, {16, 57307, 53}, {16, 57306,-53}, {16, 57305, 54}, {16, 57304,-54}, {16, 57303, 55}, {16, 57302,-55}, {16, 57301, 56}, {16, 57300,-56}, {16, 57299, 57}, {16, 57298,-57}, {16, 57297, 58}, {16, 57296,-58}, {16, 57295, 59}, {16, 57294,-59}, {16, 57293, 60}, {16, 57292,-60}, {16, 57291, 61}, {16, 57290,-61}, {16, 57289, 62}, {16, 57288,-62}, {16, 57175, 63}, {16, 57174,-63}, {16, 57173, 64}, {16, 57172,-64}, { 0, 0, 0} }; static const huff_entry_t *const scales_129[] = { scales_a_129, scales_b_129, scales_c_129, scales_d_129, scales_e_129 }; static const huff_entry_t bitalloc_a_3[] = { { 1, 0, 0}, { 2, 2, 1}, { 2, 3, -1}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_4[] = { { 1, 0, 0}, { 2, 2, 1}, { 3, 6, 2}, { 3, 7, 3}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_4[] = { { 2, 2, 0}, { 3, 6, 1}, { 3, 7, 2}, { 1, 0, 3}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_4[] = { { 3, 6, 0}, { 3, 7, 1}, { 1, 0, 2}, { 2, 2, 3}, { 0, 0, 0} }; static const huff_entry_t bitalloc_d_4[] = { { 2, 0, 0}, { 2, 1, 1}, { 2, 2, 2}, { 2, 3, 3}, { 0, 0, 0} }; static const huff_entry_t *const tmode[] = { bitalloc_a_4, bitalloc_b_4, bitalloc_c_4, bitalloc_d_4 }; static const huff_entry_t bitalloc_a_5[] = { { 1, 0, 0}, { 2, 2, 1}, { 3, 6, -1}, { 4, 14, 2}, { 4, 15, -2}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_5[] = { { 2, 2, 0}, { 2, 0, 1}, { 2, 1, -1}, { 3, 6, 2}, { 3, 7, -2}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_5[] = { { 1, 0, 0}, { 3, 4, 1}, { 3, 5, -1}, { 3, 6, 2}, { 3, 7, -2}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_7[] = { { 1, 0, 0}, { 3, 6, 1}, { 3, 5, -1}, { 3, 4, 2}, { 4, 14, -2}, { 5, 31, 3}, { 5, 30, -3}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_7[] = { { 2, 3, 0}, { 2, 1, 1}, { 2, 0, -1}, { 3, 4, 2}, { 4, 11, -2}, { 5, 21, 3}, { 5, 20, -3}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_7[] = { { 2, 3, 0}, { 2, 2, 1}, { 2, 1, -1}, { 4, 3, 2}, { 4, 2, -2}, { 4, 1, 3}, { 4, 0, -3}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_9[] = { { 1, 0, 0}, { 3, 7, 1}, { 3, 5, -1}, { 4, 13, 2}, { 4, 9, -2}, { 4, 8, 3}, { 5, 25, -3}, { 6, 49, 4}, { 6, 48, -4}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_9[] = { { 2, 2, 0}, { 2, 0, 1}, { 3, 7, -1}, { 3, 3, 2}, { 3, 2, -2}, { 5, 27, 3}, { 5, 26, -3}, { 5, 25, 4}, { 5, 24, -4}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_9[] = { { 2, 2, 0}, { 2, 0, 1}, { 3, 7, -1}, { 3, 6, 2}, { 3, 2, -2}, { 4, 6, 3}, { 5, 15, -3}, { 6, 29, 4}, { 6, 28, -4}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_13[] = { { 1, 0, 0}, { 3, 4, 1}, { 4, 15, -1}, { 4, 13, 2}, { 4, 12, -2}, { 4, 10, 3}, { 5, 29, -3}, { 5, 22, 4}, { 6, 57, -4}, { 6, 47, 5}, { 6, 46, -5}, { 7, 113, 6}, { 7, 112, -6}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_13[] = { { 2, 0, 0}, { 3, 6, 1}, { 3, 5, -1}, { 3, 2, 2}, { 4, 15, -2}, { 4, 9, 3}, { 4, 7, -3}, { 4, 6, 4}, { 5, 29, -4}, { 5, 17, 5}, { 5, 16, -5}, { 6, 57, 6}, { 6, 56, -6}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_13[] = { { 3, 5, 0}, { 3, 4, 1}, { 3, 3, -1}, { 3, 2, 2}, { 3, 0, -2}, { 4, 15, 3}, { 4, 14, -3}, { 4, 12, 4}, { 4, 3, -4}, { 5, 27, 5}, { 5, 26, -5}, { 5, 5, 6}, { 5, 4, -6}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_17[] = { { 2, 1, 0}, { 3, 7, 1}, { 3, 6, -1}, { 3, 4, 2}, { 3, 1, -2}, { 4, 11, 3}, { 4, 10, -3}, { 4, 0, 4}, { 5, 3, -4}, { 6, 4, 5}, { 7, 11, -5}, { 8, 20, 6}, { 9, 43, -6}, {10, 84, 7}, {11, 171, -7}, {12, 341, 8}, {12, 340, -8}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_17[] = { { 2, 0, 0}, { 3, 6, 1}, { 3, 5, -1}, { 3, 2, 2}, { 4, 15, -2}, { 4, 9, 3}, { 4, 8, -3}, { 5, 29, 4}, { 5, 28, -4}, { 5, 14, 5}, { 5, 13, -5}, { 6, 30, 6}, { 6, 25, -6}, { 6, 24, 7}, { 7, 63, -7}, { 8, 125, 8}, { 8, 124, -8}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_17[] = { { 3, 6, 0}, { 3, 4, 1}, { 3, 3, -1}, { 3, 0, 2}, { 4, 15, -2}, { 4, 11, 3}, { 4, 10, -3}, { 4, 4, 4}, { 4, 3, -4}, { 5, 29, 5}, { 5, 28, -5}, { 5, 10, 6}, { 5, 5, -6}, { 5, 4, 7}, { 6, 23, -7}, { 7, 45, 8}, { 7, 44, -8}, { 0, 0, 0} }; static const huff_entry_t bitalloc_d_17[] = { { 1, 0, 0}, { 3, 7, 1}, { 3, 6, -1}, { 4, 11, 2}, { 4, 10, -2}, { 5, 19, 3}, { 5, 18, -3}, { 6, 35, 4}, { 6, 34, -4}, { 7, 67, 5}, { 7, 66, -5}, { 8, 131, 6}, { 8, 130, -6}, { 9, 259, 7}, { 9, 258, -7}, { 9, 257, 8}, { 9, 256, -8}, { 0, 0, 0} }; static const huff_entry_t bitalloc_e_17[] = { { 1, 0, 0}, { 3, 5, 1}, { 3, 4, -1}, { 4, 12, 2}, { 5, 31, -2}, { 5, 28, 3}, { 5, 27, -3}, { 6, 60, 4}, { 6, 59, -4}, { 6, 53, 5}, { 6, 52, -5}, { 7, 122, 6}, { 7, 117, -6}, { 8, 247, 7}, { 8, 246, -7}, { 8, 233, 8}, { 8, 232, -8}, { 0, 0, 0} }; static const huff_entry_t bitalloc_f_17[] = { { 3, 6, 0}, { 3, 5, 1}, { 3, 4, -1}, { 3, 2, 2}, { 3, 1, -2}, { 4, 15, 3}, { 4, 14, -3}, { 4, 6, 4}, { 4, 1, -4}, { 5, 14, 5}, { 5, 1, -5}, { 6, 31, 6}, { 6, 30, -6}, { 6, 0, 7}, { 7, 3, -7}, { 8, 5, 8}, { 8, 4, -8}, { 0, 0, 0} }; static const huff_entry_t bitalloc_g_17[] = { { 2, 2, 0}, { 3, 7, 1}, { 3, 6, -1}, { 3, 1, 2}, { 3, 0, -2}, { 4, 5, 3}, { 4, 4, -3}, { 5, 14, 4}, { 5, 13, -4}, { 6, 30, 5}, { 6, 25, -5}, { 7, 62, 6}, { 7, 49, -6}, { 8, 127, 7}, { 8, 126, -7}, { 8, 97, 8}, { 8, 96, -8}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_25[] = { { 3, 6, 0}, { 3, 4, 1}, { 3, 3, -1}, { 3, 1, 2}, { 3, 0, -2}, { 4, 15, 3}, { 4, 14, -3}, { 4, 5, 4}, { 4, 4, -4}, { 5, 22, 5}, { 5, 21, -5}, { 6, 47, 6}, { 6, 46, -6}, { 7, 83, 7}, { 7, 82, -7}, { 8, 163, 8}, { 8, 162, -8}, { 8, 160, 9}, { 9, 323, -9}, {10, 644, 10}, {11, 1291,-10}, {12, 2580, 11}, {13, 5163,-11}, {14, 10325, 12}, {14, 10324,-12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_25[] = { { 3, 5, 0}, { 3, 2, 1}, { 3, 1, -1}, { 4, 15, 2}, { 4, 14, -2}, { 4, 9, 3}, { 4, 8, -3}, { 4, 6, 4}, { 4, 1, -4}, { 5, 26, 5}, { 5, 25, -5}, { 5, 15, 6}, { 5, 14, -6}, { 6, 55, 7}, { 6, 54, -7}, { 6, 49, 8}, { 6, 48, -8}, { 6, 1, 9}, { 6, 0, -9}, { 7, 6, 10}, { 7, 5,-10}, { 7, 4, 11}, { 8, 15,-11}, { 9, 29, 12}, { 9, 28,-12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_25[] = { { 3, 1, 0}, { 4, 15, 1}, { 4, 14, -1}, { 4, 12, 2}, { 4, 11, -2}, { 4, 9, 3}, { 4, 8, -3}, { 4, 6, 4}, { 4, 5, -4}, { 4, 1, 5}, { 4, 0, -5}, { 5, 26, 6}, { 5, 21, -6}, { 5, 15, 7}, { 5, 14, -7}, { 5, 8, 8}, { 6, 55, -8}, { 6, 41, 9}, { 6, 40, -9}, { 6, 18, 10}, { 7, 109,-10}, { 7, 108, 11}, { 7, 39,-11}, { 8, 77, 12}, { 8, 76,-12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_d_25[] = { { 2, 2, 0}, { 3, 7, 1}, { 3, 6, -1}, { 3, 1, 2}, { 3, 0, -2}, { 4, 5, 3}, { 4, 4, -3}, { 5, 13, 4}, { 5, 12, -4}, { 6, 29, 5}, { 6, 28, -5}, { 7, 62, 6}, { 7, 61, -6}, { 8, 126, 7}, { 8, 121, -7}, { 9, 255, 8}, { 9, 254, -8}, {10, 483, 9}, {10, 482, -9}, {11, 963, 10}, {11, 962,-10}, {12, 1923, 11}, {12, 1922,-11}, {12, 1921, 12}, {12, 1920,-12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_e_25[] = { { 2, 3, 0}, { 3, 3, 1}, { 3, 2, -1}, { 4, 11, 2}, { 4, 10, -2}, { 4, 1, 3}, { 4, 0, -3}, { 5, 17, 4}, { 5, 16, -4}, { 5, 5, 5}, { 5, 4, -5}, { 6, 38, 6}, { 6, 37, -6}, { 6, 14, 7}, { 6, 13, -7}, { 7, 79, 8}, { 7, 78, -8}, { 7, 72, 9}, { 7, 31, -9}, { 7, 25, 10}, { 7, 24,-10}, { 8, 147, 11}, { 8, 146,-11}, { 8, 61, 12}, { 8, 60,-12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_f_25[] = { { 3, 1, 0}, { 3, 0, 1}, { 4, 15, -1}, { 4, 14, 2}, { 4, 13, -2}, { 4, 11, 3}, { 4, 10, -3}, { 4, 8, 4}, { 4, 7, -4}, { 4, 5, 5}, { 4, 4, -5}, { 5, 24, 6}, { 5, 19, -6}, { 5, 13, 7}, { 5, 12, -7}, { 6, 37, 8}, { 6, 36, -8}, { 7, 102, 9}, { 7, 101, -9}, { 8, 207, 10}, { 8, 206,-10}, { 8, 200, 11}, { 9, 403,-11}, {10, 805, 12}, {10, 804,-12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_g_25[] = { { 2, 1, 0}, { 3, 6, 1}, { 3, 5, -1}, { 3, 0, 2}, { 4, 15, -2}, { 4, 8, 3}, { 4, 3, -3}, { 5, 28, 4}, { 5, 19, -4}, { 5, 4, 5}, { 6, 59, -5}, { 6, 36, 6}, { 6, 11, -6}, { 7, 116, 7}, { 7, 75, -7}, { 7, 21, 8}, { 7, 20, -8}, { 8, 149, 9}, { 8, 148, -9}, { 9, 470, 10}, { 9, 469,-10}, {10, 943, 11}, {10, 942,-11}, {10, 937, 12}, {10, 936,-12}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_33[] = { { 3, 2, 0}, { 3, 1, 1}, { 3, 0, -1}, { 4, 14, 2}, { 4, 13, -2}, { 4, 12, 3}, { 4, 11, -3}, { 4, 9, 4}, { 4, 8, -4}, { 4, 6, 5}, { 5, 31, -5}, { 5, 20, 6}, { 5, 15, -6}, { 6, 61, 7}, { 6, 60, -7}, { 6, 29, 8}, { 6, 28, -8}, { 7, 85, 9}, { 7, 84, -9}, { 8, 174, 10}, { 8, 173,-10}, { 9, 351, 11}, { 9, 350,-11}, {10, 691, 12}, {10, 690,-12}, {11, 1379, 13}, {11, 1378,-13}, {12, 2755, 14}, {12, 2754,-14}, {13, 5507, 15}, {13, 5506,-15}, {13, 5505, 16}, {13, 5504,-16}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_33[] = { { 3, 1, 0}, { 4, 15, 1}, { 4, 14, -1}, { 4, 11, 2}, { 4, 10, -2}, { 4, 8, 3}, { 4, 7, -3}, { 4, 4, 4}, { 4, 1, -4}, { 5, 27, 5}, { 5, 26, -5}, { 5, 19, 6}, { 5, 18, -6}, { 5, 12, 7}, { 5, 11, -7}, { 5, 1, 8}, { 5, 0, -8}, { 6, 50, 9}, { 6, 49, -9}, { 6, 26, 10}, { 6, 21,-10}, { 7, 103, 11}, { 7, 102,-11}, { 7, 96, 12}, { 7, 55,-12}, { 7, 41, 13}, { 7, 40,-13}, { 8, 194, 14}, { 8, 109,-14}, { 8, 108, 15}, { 9, 391,-15}, {10, 781, 16}, {10, 780,-16}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_33[] = { { 4, 13, 0}, { 4, 11, 1}, { 4, 10, -1}, { 4, 8, 2}, { 4, 7, -2}, { 4, 4, 3}, { 4, 3, -3}, { 4, 2, 4}, { 4, 1, -4}, { 5, 30, 5}, { 5, 29, -5}, { 5, 25, 6}, { 5, 24, -6}, { 5, 19, 7}, { 5, 18, -7}, { 5, 11, 8}, { 5, 10, -8}, { 5, 0, 9}, { 6, 63, -9}, { 6, 62, 10}, { 6, 57,-10}, { 6, 27, 11}, { 6, 26,-11}, { 6, 24, 12}, { 6, 3,-12}, { 7, 113, 13}, { 7, 112,-13}, { 7, 50, 14}, { 7, 5,-14}, { 7, 4, 15}, { 8, 103,-15}, { 9, 205, 16}, { 9, 204,-16}, { 0, 0, 0} }; static const huff_entry_t bitalloc_d_33[] = { { 2, 1, 0}, { 3, 6, 1}, { 3, 5, -1}, { 3, 0, 2}, { 4, 15, -2}, { 4, 8, 3}, { 4, 3, -3}, { 5, 28, 4}, { 5, 19, -4}, { 5, 4, 5}, { 6, 59, -5}, { 6, 36, 6}, { 6, 11, -6}, { 7, 116, 7}, { 7, 75, -7}, { 7, 21, 8}, { 7, 20, -8}, { 8, 149, 9}, { 8, 148, -9}, { 9, 469, 10}, { 9, 468,-10}, {10, 941, 11}, {10, 940,-11}, {11, 1885, 12}, {11, 1884,-12}, {12, 3773, 13}, {12, 3772,-13}, {13, 7551, 14}, {13, 7550,-14}, {14, 15099, 15}, {14, 15098,-15}, {14, 15097, 16}, {14, 15096,-16}, { 0, 0, 0} }; static const huff_entry_t bitalloc_e_33[] = { { 2, 2, 0}, { 3, 2, 1}, { 3, 1, -1}, { 4, 12, 2}, { 4, 7, -2}, { 4, 0, 3}, { 5, 31, -3}, { 5, 27, 4}, { 5, 26, -4}, { 5, 3, 5}, { 5, 2, -5}, { 6, 59, 6}, { 6, 58, -6}, { 6, 27, 7}, { 6, 26, -7}, { 7, 123, 8}, { 7, 122, -8}, { 7, 120, 9}, { 7, 115, -9}, { 7, 112, 10}, { 7, 51,-10}, { 7, 49, 11}, { 7, 48,-11}, { 8, 242, 12}, { 8, 229,-12}, { 8, 227, 13}, { 8, 226,-13}, { 8, 101, 14}, { 8, 100,-14}, { 9, 487, 15}, { 9, 486,-15}, { 9, 457, 16}, { 9, 456,-16}, { 0, 0, 0} }; static const huff_entry_t bitalloc_f_33[] = { { 4, 13, 0}, { 4, 12, 1}, { 4, 11, -1}, { 4, 9, 2}, { 4, 8, -2}, { 4, 7, 3}, { 4, 6, -3}, { 4, 4, 4}, { 4, 3, -4}, { 4, 1, 5}, { 4, 0, -5}, { 5, 30, 6}, { 5, 29, -6}, { 5, 21, 7}, { 5, 20, -7}, { 5, 10, 8}, { 5, 5, -8}, { 6, 63, 9}, { 6, 62, -9}, { 6, 56, 10}, { 6, 23,-10}, { 6, 9, 11}, { 6, 8,-11}, { 7, 45, 12}, { 7, 44,-12}, { 8, 230, 13}, { 8, 229,-13}, { 9, 463, 14}, { 9, 462,-14}, { 9, 456, 15}, {10, 915,-15}, {11, 1829, 16}, {11, 1828,-16}, { 0, 0, 0} }; static const huff_entry_t bitalloc_g_33[] = { { 3, 6, 0}, { 3, 3, 1}, { 3, 2, -1}, { 4, 15, 2}, { 4, 14, -2}, { 4, 9, 3}, { 4, 8, -3}, { 4, 1, 4}, { 4, 0, -4}, { 5, 22, 5}, { 5, 21, -5}, { 5, 6, 6}, { 5, 5, -6}, { 6, 46, 7}, { 6, 41, -7}, { 6, 14, 8}, { 6, 9, -8}, { 7, 94, 9}, { 7, 81, -9}, { 7, 30, 10}, { 7, 17,-10}, { 8, 191, 11}, { 8, 190,-11}, { 8, 63, 12}, { 8, 62,-12}, { 8, 32, 13}, { 9, 323,-13}, { 9, 321, 14}, { 9, 320,-14}, { 9, 67, 15}, { 9, 66,-15}, {10, 645, 16}, {10, 644,-16}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_65[] = { { 4, 6, 0}, { 4, 5, 1}, { 4, 4, -1}, { 4, 2, 2}, { 4, 1, -2}, { 4, 0, 3}, { 5, 31, -3}, { 5, 29, 4}, { 5, 28, -4}, { 5, 27, 5}, { 5, 26, -5}, { 5, 24, 6}, { 5, 23, -6}, { 5, 21, 7}, { 5, 20, -7}, { 5, 18, 8}, { 5, 17, -8}, { 5, 14, 9}, { 5, 7, -9}, { 5, 6, 10}, { 6, 61,-10}, { 6, 50, 11}, { 6, 45,-11}, { 6, 38, 12}, { 6, 33,-12}, { 6, 31, 13}, { 6, 30,-13}, { 7, 120, 14}, { 7, 103,-14}, { 7, 89, 15}, { 7, 88,-15}, { 7, 65, 16}, { 7, 64,-16}, { 8, 205, 17}, { 8, 204,-17}, { 8, 157, 18}, { 8, 156,-18}, { 9, 486, 19}, { 9, 485,-19}, { 9, 318, 20}, { 9, 317,-20}, {10, 975, 21}, {10, 974,-21}, {10, 639, 22}, {10, 638,-22}, {11, 1939, 23}, {11, 1938,-23}, {11, 1936, 24}, {11, 1267,-24}, {11, 1264, 25}, {12, 3875,-25}, {12, 2532, 26}, {12, 2531,-26}, {13, 7749, 27}, {13, 7748,-27}, {13, 5061, 28}, {13, 5060,-28}, {14, 10133, 29}, {14, 10132,-29}, {15, 20269, 30}, {15, 20268,-30}, {16, 40543, 31}, {16, 40542,-31}, {16, 40541, 32}, {16, 40540,-32}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_65[] = { { 4, 4, 0}, { 4, 2, 1}, { 4, 1, -1}, { 5, 30, 2}, { 5, 29, -2}, { 5, 26, 3}, { 5, 25, -3}, { 5, 23, 4}, { 5, 22, -4}, { 5, 19, 5}, { 5, 18, -5}, { 5, 16, 6}, { 5, 15, -6}, { 5, 12, 7}, { 5, 11, -7}, { 5, 7, 8}, { 5, 6, -8}, { 6, 63, 9}, { 6, 62, -9}, { 6, 56, 10}, { 6, 55,-10}, { 6, 49, 11}, { 6, 48,-11}, { 6, 41, 12}, { 6, 40,-12}, { 6, 34, 13}, { 6, 29,-13}, { 6, 26, 14}, { 6, 21,-14}, { 6, 20, 15}, { 6, 3,-15}, { 6, 0, 16}, { 7, 115,-16}, { 7, 109, 17}, { 7, 108,-17}, { 7, 86, 18}, { 7, 85,-18}, { 7, 70, 19}, { 7, 57,-19}, { 7, 56, 20}, { 7, 55,-20}, { 7, 4, 21}, { 7, 3,-21}, { 8, 229, 22}, { 8, 228,-22}, { 8, 175, 23}, { 8, 174,-23}, { 8, 143, 24}, { 8, 142,-24}, { 8, 108, 25}, { 8, 11,-25}, { 8, 10, 26}, { 8, 5,-26}, { 9, 339, 27}, { 9, 338,-27}, { 9, 336, 28}, { 9, 219,-28}, { 9, 9, 29}, { 9, 8,-29}, {10, 674, 30}, {10, 437,-30}, {10, 436, 31}, {11, 1351,-31}, {12, 2701, 32}, {12, 2700,-32}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_65[] = { { 5, 28, 0}, { 5, 25, 1}, { 5, 24, -1}, { 5, 23, 2}, { 5, 22, -2}, { 5, 19, 3}, { 5, 18, -3}, { 5, 16, 4}, { 5, 15, -4}, { 5, 13, 5}, { 5, 12, -5}, { 5, 10, 6}, { 5, 9, -6}, { 5, 7, 7}, { 5, 6, -7}, { 5, 4, 8}, { 5, 3, -8}, { 5, 1, 9}, { 5, 0, -9}, { 6, 62, 10}, { 6, 61,-10}, { 6, 59, 11}, { 6, 58,-11}, { 6, 54, 12}, { 6, 53,-12}, { 6, 43, 13}, { 6, 42,-13}, { 6, 40, 14}, { 6, 35,-14}, { 6, 29, 15}, { 6, 28,-15}, { 6, 17, 16}, { 6, 16,-16}, { 6, 11, 17}, { 6, 10,-17}, { 6, 4, 18}, { 7, 127,-18}, { 7, 121, 19}, { 7, 120,-19}, { 7, 110, 20}, { 7, 105,-20}, { 7, 83, 21}, { 7, 82,-21}, { 7, 68, 22}, { 7, 47,-22}, { 7, 46, 23}, { 7, 45,-23}, { 7, 11, 24}, { 7, 10,-24}, { 8, 252, 25}, { 8, 223,-25}, { 8, 209, 26}, { 8, 208,-26}, { 8, 138, 27}, { 8, 89,-27}, { 8, 88, 28}, { 9, 507,-28}, { 9, 445, 29}, { 9, 444,-29}, { 9, 278, 30}, {10, 1013,-30}, {10, 1012, 31}, {10, 559,-31}, {11, 1117, 32}, {11, 1116,-32}, { 0, 0, 0} }; static const huff_entry_t bitalloc_d_65[] = { { 3, 4, 0}, { 3, 1, 1}, { 3, 0, -1}, { 4, 13, 2}, { 4, 12, -2}, { 4, 7, 3}, { 4, 6, -3}, { 5, 31, 4}, { 5, 30, -4}, { 5, 23, 5}, { 5, 22, -5}, { 5, 11, 6}, { 5, 10, -6}, { 6, 59, 7}, { 6, 58, -7}, { 6, 43, 8}, { 6, 42, -8}, { 6, 19, 9}, { 6, 18, -9}, { 7, 115, 10}, { 7, 114,-10}, { 7, 83, 11}, { 7, 82,-11}, { 7, 35, 12}, { 7, 34,-12}, { 8, 227, 13}, { 8, 226,-13}, { 8, 163, 14}, { 8, 162,-14}, { 8, 160, 15}, { 8, 67,-15}, { 8, 64, 16}, { 9, 451,-16}, { 9, 448, 17}, { 9, 323,-17}, { 9, 132, 18}, { 9, 131,-18}, {10, 900, 19}, {10, 899,-19}, {10, 644, 20}, {10, 267,-20}, {10, 261, 21}, {10, 260,-21}, {11, 1797, 22}, {11, 1796,-22}, {11, 533, 23}, {11, 532,-23}, {12, 3605, 24}, {12, 3604,-24}, {12, 2582, 25}, {12, 2581,-25}, {13, 7215, 26}, {13, 7214,-26}, {13, 5167, 27}, {13, 5166,-27}, {13, 5160, 28}, {14, 14427,-28}, {14, 10323, 29}, {14, 10322,-29}, {15, 28853, 30}, {15, 28852,-30}, {15, 28851, 31}, {15, 28850,-31}, {15, 28849, 32}, {15, 28848,-32}, { 0, 0, 0} }; static const huff_entry_t bitalloc_e_65[] = { { 3, 4, 0}, { 3, 0, 1}, { 4, 15, -1}, { 4, 7, 2}, { 4, 6, -2}, { 5, 29, 3}, { 5, 28, -3}, { 5, 23, 4}, { 5, 22, -4}, { 5, 10, 5}, { 5, 9, -5}, { 5, 6, 6}, { 5, 5, -6}, { 6, 54, 7}, { 6, 53, -7}, { 6, 48, 8}, { 6, 43, -8}, { 6, 40, 9}, { 6, 23, -9}, { 6, 16, 10}, { 6, 15,-10}, { 6, 9, 11}, { 6, 8,-11}, { 7, 105, 12}, { 7, 104,-12}, { 7, 100, 13}, { 7, 99,-13}, { 7, 84, 14}, { 7, 83,-14}, { 7, 45, 15}, { 7, 44,-15}, { 7, 29, 16}, { 7, 28,-16}, { 8, 221, 17}, { 8, 220,-17}, { 8, 206, 18}, { 8, 205,-18}, { 8, 202, 19}, { 8, 197,-19}, { 8, 171, 20}, { 8, 170,-20}, { 8, 164, 21}, { 8, 71,-21}, { 8, 69, 22}, { 8, 68,-22}, { 9, 446, 23}, { 9, 445,-23}, { 9, 415, 24}, { 9, 414,-24}, { 9, 408, 25}, { 9, 407,-25}, { 9, 393, 26}, { 9, 392,-26}, { 9, 331, 27}, { 9, 330,-27}, { 9, 141, 28}, { 9, 140,-28}, {10, 895, 29}, {10, 894,-29}, {10, 889, 30}, {10, 888,-30}, {10, 819, 31}, {10, 818,-31}, {10, 813, 32}, {10, 812,-32}, { 0, 0, 0} }; static const huff_entry_t bitalloc_f_65[] = { { 3, 6, 0}, { 3, 3, 1}, { 3, 2, -1}, { 4, 15, 2}, { 4, 14, -2}, { 4, 9, 3}, { 4, 8, -3}, { 4, 1, 4}, { 4, 0, -4}, { 5, 21, 5}, { 5, 20, -5}, { 5, 5, 6}, { 5, 4, -6}, { 6, 45, 7}, { 6, 44, -7}, { 6, 13, 8}, { 6, 12, -8}, { 7, 93, 9}, { 7, 92, -9}, { 7, 29, 10}, { 7, 28,-10}, { 8, 189, 11}, { 8, 188,-11}, { 8, 61, 12}, { 8, 60,-12}, { 9, 381, 13}, { 9, 380,-13}, { 9, 125, 14}, { 9, 124,-14}, {10, 765, 15}, {10, 764,-15}, {10, 252, 16}, {11, 1535,-16}, {11, 1532, 17}, {11, 511,-17}, {11, 506, 18}, {12, 3069,-18}, {12, 3067, 19}, {12, 3066,-19}, {12, 1015, 20}, {12, 1014,-20}, {13, 6136, 21}, {13, 2043,-21}, {13, 2035, 22}, {13, 2034,-22}, {14, 12275, 23}, {14, 12274,-23}, {14, 4085, 24}, {14, 4084,-24}, {14, 4083, 25}, {14, 4082,-25}, {14, 4081, 26}, {14, 4080,-26}, {14, 4079, 27}, {14, 4078,-27}, {14, 4077, 28}, {14, 4076,-28}, {14, 4075, 29}, {14, 4074,-29}, {14, 4073, 30}, {14, 4072,-30}, {14, 4067, 31}, {14, 4066,-31}, {14, 4065, 32}, {14, 4064,-32}, { 0, 0, 0} }; static const huff_entry_t bitalloc_g_65[] = { { 4, 14, 0}, { 4, 11, 1}, { 4, 10, -1}, { 4, 8, 2}, { 4, 6, -2}, { 4, 4, 3}, { 4, 3, -3}, { 4, 0, 4}, { 5, 31, -4}, { 5, 26, 5}, { 5, 25, -5}, { 5, 18, 6}, { 5, 15, -6}, { 5, 10, 7}, { 5, 5, -7}, { 5, 2, 8}, { 6, 61, -8}, { 6, 54, 9}, { 6, 49, -9}, { 6, 38, 10}, { 6, 29,-10}, { 6, 22, 11}, { 6, 9,-11}, { 6, 6, 12}, { 7, 121,-12}, { 7, 110, 13}, { 7, 97,-13}, { 7, 78, 14}, { 7, 57,-14}, { 7, 46, 15}, { 7, 17,-15}, { 7, 14, 16}, { 8, 241,-16}, { 8, 223, 17}, { 8, 222,-17}, { 8, 159, 18}, { 8, 158,-18}, { 8, 95, 19}, { 8, 94,-19}, { 8, 31, 20}, { 8, 30,-20}, { 9, 480, 21}, { 9, 387,-21}, { 9, 384, 22}, { 9, 227,-22}, { 9, 225, 23}, { 9, 224,-23}, { 9, 65, 24}, { 9, 64,-24}, {10, 962, 25}, {10, 773,-25}, {10, 771, 26}, {10, 770,-26}, {10, 452, 27}, {10, 135,-27}, {10, 133, 28}, {10, 132,-28}, {11, 1927, 29}, {11, 1926,-29}, {11, 1545, 30}, {11, 1544,-30}, {11, 907, 31}, {11, 906,-31}, {11, 269, 32}, {11, 268,-32}, { 0, 0, 0} }; static const huff_entry_t bitalloc_a_129[] = { { 4, 8, 0}, { 4, 10, 1}, { 4, 9, -1}, { 4, 0, 2}, { 5, 31, -2}, { 5, 24, 3}, { 5, 23, -3}, { 5, 12, 4}, { 5, 11, -4}, { 5, 5, 5}, { 5, 4, -5}, { 6, 60, 6}, { 6, 58, -6}, { 6, 54, 7}, { 6, 53, -7}, { 6, 45, 8}, { 6, 44, -8}, { 6, 28, 9}, { 6, 27, -9}, { 6, 19, 10}, { 6, 18,-10}, { 6, 14, 11}, { 6, 13,-11}, { 6, 6, 12}, { 6, 5,-12}, { 7, 122, 13}, { 7, 119,-13}, { 7, 113, 14}, { 7, 112,-14}, { 7, 104, 15}, { 7, 103,-15}, { 7, 100, 16}, { 7, 63,-16}, { 7, 60, 17}, { 7, 59,-17}, { 7, 52, 18}, { 7, 43,-18}, { 7, 40, 19}, { 7, 35,-19}, { 7, 32, 20}, { 7, 31,-20}, { 7, 15, 21}, { 7, 14,-21}, { 8, 247, 22}, { 8, 246,-22}, { 8, 231, 23}, { 8, 230,-23}, { 8, 223, 24}, { 8, 222,-24}, { 8, 211, 25}, { 8, 210,-25}, { 8, 203, 26}, { 8, 202,-26}, { 8, 123, 27}, { 8, 122,-27}, { 8, 116, 28}, { 8, 107,-28}, { 8, 84, 29}, { 8, 83,-29}, { 8, 68, 30}, { 8, 67,-30}, { 8, 60, 31}, { 8, 51,-31}, { 8, 49, 32}, { 8, 48,-32}, { 8, 17, 33}, { 8, 16,-33}, { 9, 474, 34}, { 9, 473,-34}, { 9, 458, 35}, { 9, 457,-35}, { 9, 442, 36}, { 9, 441,-36}, { 9, 411, 37}, { 9, 410,-37}, { 9, 251, 38}, { 9, 250,-38}, { 9, 248, 39}, { 9, 235,-39}, { 9, 213, 40}, { 9, 212,-40}, { 9, 170, 41}, { 9, 165,-41}, { 9, 139, 42}, { 9, 138,-42}, { 9, 132, 43}, { 9, 123,-43}, { 9, 101, 44}, { 9, 100,-44}, { 9, 37, 45}, { 9, 36,-45}, {10, 950, 46}, {10, 945,-46}, {10, 919, 47}, {10, 918,-47}, {10, 912, 48}, {10, 887,-48}, {10, 881, 49}, {10, 880,-49}, {10, 818, 50}, {10, 817,-50}, {10, 499, 51}, {10, 498,-51}, {10, 469, 52}, {10, 468,-52}, {10, 343, 53}, {10, 342,-53}, {10, 329, 54}, {10, 328,-54}, {10, 267, 55}, {10, 266,-55}, {10, 245, 56}, {10, 244,-56}, {10, 79, 57}, {10, 78,-57}, {10, 77, 58}, {10, 76,-58}, {11, 1903, 59}, {11, 1902,-59}, {11, 1889, 60}, {11, 1888,-60}, {11, 1827, 61}, {11, 1826,-61}, {11, 1773, 62}, {11, 1772,-62}, {11, 1639, 63}, {11, 1638,-63}, {11, 1633, 64}, {11, 1632,-64}, { 0, 0, 0} }; static const huff_entry_t bitalloc_b_129[] = { { 5, 10, 0}, { 5, 7, 1}, { 5, 6, -1}, { 5, 4, 2}, { 5, 3, -2}, { 5, 0, 3}, { 6, 63, -3}, { 6, 60, 4}, { 6, 59, -4}, { 6, 57, 5}, { 6, 56, -5}, { 6, 53, 6}, { 6, 52, -6}, { 6, 50, 7}, { 6, 49, -7}, { 6, 46, 8}, { 6, 45, -8}, { 6, 43, 9}, { 6, 42, -9}, { 6, 39, 10}, { 6, 38,-10}, { 6, 35, 11}, { 6, 34,-11}, { 6, 32, 12}, { 6, 31,-12}, { 6, 28, 13}, { 6, 27,-13}, { 6, 25, 14}, { 6, 24,-14}, { 6, 22, 15}, { 6, 19,-15}, { 6, 16, 16}, { 6, 11,-16}, { 6, 5, 17}, { 6, 4,-17}, { 7, 125, 18}, { 7, 124,-18}, { 7, 122, 19}, { 7, 117,-19}, { 7, 110, 20}, { 7, 109,-20}, { 7, 103, 21}, { 7, 102,-21}, { 7, 96, 22}, { 7, 95,-22}, { 7, 89, 23}, { 7, 88,-23}, { 7, 81, 24}, { 7, 80,-24}, { 7, 74, 25}, { 7, 73,-25}, { 7, 66, 26}, { 7, 61,-26}, { 7, 59, 27}, { 7, 58,-27}, { 7, 52, 28}, { 7, 47,-28}, { 7, 37, 29}, { 7, 36,-29}, { 7, 21, 30}, { 7, 20,-30}, { 7, 6, 31}, { 7, 5,-31}, { 8, 247, 32}, { 8, 246,-32}, { 8, 223, 33}, { 8, 222,-33}, { 8, 217, 34}, { 8, 216,-34}, { 8, 189, 35}, { 8, 188,-35}, { 8, 166, 36}, { 8, 165,-36}, { 8, 151, 37}, { 8, 150,-37}, { 8, 144, 38}, { 8, 135,-38}, { 8, 121, 39}, { 8, 120,-39}, { 8, 106, 40}, { 8, 93,-40}, { 8, 71, 41}, { 8, 70,-41}, { 8, 68, 42}, { 8, 15,-42}, { 8, 9, 43}, { 8, 8,-43}, { 9, 466, 44}, { 9, 465,-44}, { 9, 391, 45}, { 9, 390,-45}, { 9, 388, 46}, { 9, 335,-46}, { 9, 329, 47}, { 9, 328,-47}, { 9, 269, 48}, { 9, 268,-48}, { 9, 215, 49}, { 9, 214,-49}, { 9, 184, 50}, { 9, 139,-50}, { 9, 29, 51}, { 9, 28,-51}, {10, 934, 52}, {10, 929,-52}, {10, 779, 53}, {10, 778,-53}, {10, 668, 54}, {10, 583,-54}, {10, 582, 55}, {10, 581,-55}, {10, 371, 56}, {10, 370,-56}, {10, 276, 57}, {11, 1871,-57}, {11, 1857, 58}, {11, 1856,-58}, {11, 1338, 59}, {11, 1161,-59}, {11, 1160, 60}, {11, 555,-60}, {12, 3741, 61}, {12, 3740,-61}, {12, 2678, 62}, {12, 1109,-62}, {12, 1108, 63}, {13, 5359,-63}, {14, 10717, 64}, {14, 10716,-64}, { 0, 0, 0} }; static const huff_entry_t bitalloc_c_129[] = { { 6, 58, 0}, { 6, 55, 1}, { 6, 54, -1}, { 6, 52, 2}, { 6, 51, -2}, { 6, 49, 3}, { 6, 48, -3}, { 6, 46, 4}, { 6, 45, -4}, { 6, 43, 5}, { 6, 42, -5}, { 6, 40, 6}, { 6, 39, -6}, { 6, 37, 7}, { 6, 36, -7}, { 6, 34, 8}, { 6, 33, -8}, { 6, 30, 9}, { 6, 29, -9}, { 6, 27, 10}, { 6, 26,-10}, { 6, 24, 11}, { 6, 23,-11}, { 6, 21, 12}, { 6, 20,-12}, { 6, 18, 13}, { 6, 17,-13}, { 6, 14, 14}, { 6, 13,-14}, { 6, 12, 15}, { 6, 11,-15}, { 6, 8, 16}, { 6, 7,-16}, { 6, 6, 17}, { 6, 5,-17}, { 6, 3, 18}, { 6, 2,-18}, { 7, 127, 19}, { 7, 126,-19}, { 7, 124, 20}, { 7, 123,-20}, { 7, 121, 21}, { 7, 120,-21}, { 7, 118, 22}, { 7, 115,-22}, { 7, 113, 23}, { 7, 112,-23}, { 7, 106, 24}, { 7, 101,-24}, { 7, 95, 25}, { 7, 94,-25}, { 7, 88, 26}, { 7, 83,-26}, { 7, 77, 27}, { 7, 76,-27}, { 7, 70, 28}, { 7, 65,-28}, { 7, 64, 29}, { 7, 63,-29}, { 7, 56, 30}, { 7, 51,-30}, { 7, 45, 31}, { 7, 44,-31}, { 7, 39, 32}, { 7, 38,-32}, { 7, 31, 33}, { 7, 30,-33}, { 7, 20, 34}, { 7, 19,-34}, { 7, 18, 35}, { 7, 9,-35}, { 7, 3, 36}, { 7, 2,-36}, { 7, 0, 37}, { 8, 251,-37}, { 8, 245, 38}, { 8, 244,-38}, { 8, 238, 39}, { 8, 229,-39}, { 8, 215, 40}, { 8, 214,-40}, { 8, 200, 41}, { 8, 179,-41}, { 8, 165, 42}, { 8, 164,-42}, { 8, 143, 43}, { 8, 142,-43}, { 8, 124, 44}, { 8, 115,-44}, { 8, 101, 45}, { 8, 100,-45}, { 8, 66, 46}, { 8, 65,-46}, { 8, 43, 47}, { 8, 42,-47}, { 8, 17, 48}, { 8, 16,-48}, { 8, 2, 49}, { 9, 501,-49}, { 9, 479, 50}, { 9, 478,-50}, { 9, 456, 51}, { 9, 403,-51}, { 9, 357, 52}, { 9, 356,-52}, { 9, 251, 53}, { 9, 250,-53}, { 9, 228, 54}, { 9, 135,-54}, { 9, 129, 55}, { 9, 128,-55}, { 9, 6, 56}, {10, 1001,-56}, {10, 1000, 57}, {10, 915,-57}, {10, 805, 58}, {10, 804,-58}, {10, 458, 59}, {10, 269,-59}, {10, 268, 60}, {10, 15,-60}, {11, 1829, 61}, {11, 1828,-61}, {11, 918, 62}, {11, 29,-62}, {11, 28, 63}, {12, 1839,-63}, {13, 3677, 64}, {13, 3676,-64}, { 0, 0, 0} }; static const huff_entry_t bitalloc_d_129[] = { { 4, 9, 0}, { 4, 6, 1}, { 4, 5, -1}, { 4, 2, 2}, { 4, 1, -2}, { 5, 30, 3}, { 5, 29, -3}, { 5, 26, 4}, { 5, 25, -4}, { 5, 22, 5}, { 5, 21, -5}, { 5, 16, 6}, { 5, 15, -6}, { 5, 8, 7}, { 5, 7, -7}, { 5, 0, 8}, { 6, 63, -8}, { 6, 56, 9}, { 6, 55, -9}, { 6, 48, 10}, { 6, 47,-10}, { 6, 40, 11}, { 6, 35,-11}, { 6, 28, 12}, { 6, 19,-12}, { 6, 12, 13}, { 6, 3,-13}, { 7, 124, 14}, { 7, 115,-14}, { 7, 108, 15}, { 7, 99,-15}, { 7, 92, 16}, { 7, 83,-16}, { 7, 68, 17}, { 7, 59,-17}, { 7, 36, 18}, { 7, 27,-18}, { 7, 4, 19}, { 8, 251,-19}, { 8, 228, 20}, { 8, 219,-20}, { 8, 196, 21}, { 8, 187,-21}, { 8, 164, 22}, { 8, 139,-22}, { 8, 116, 23}, { 8, 75,-23}, { 8, 52, 24}, { 8, 11,-24}, { 9, 501, 25}, { 9, 500,-25}, { 9, 437, 26}, { 9, 436,-26}, { 9, 373, 27}, { 9, 372,-27}, { 9, 277, 28}, { 9, 276,-28}, { 9, 149, 29}, { 9, 148,-29}, { 9, 21, 30}, { 9, 20,-30}, {10, 917, 31}, {10, 916,-31}, {10, 789, 32}, {10, 788,-32}, {10, 661, 33}, {10, 660,-33}, {10, 469, 34}, {10, 468,-34}, {10, 214, 35}, {10, 213,-35}, {11, 1838, 36}, {11, 1837,-36}, {11, 1582, 37}, {11, 1581,-37}, {11, 1326, 38}, {11, 1325,-38}, {11, 942, 39}, {11, 941,-39}, {11, 431, 40}, {11, 430,-40}, {12, 3679, 41}, {12, 3678,-41}, {12, 3167, 42}, {12, 3166,-42}, {12, 3160, 43}, {12, 2655,-43}, {12, 2648, 44}, {12, 1887,-44}, {12, 1880, 45}, {12, 851,-45}, {12, 849, 46}, {12, 848,-46}, {13, 7346, 47}, {13, 7345,-47}, {13, 6322, 48}, {13, 5309,-48}, {13, 3773, 49}, {13, 3772,-49}, {13, 3762, 50}, {13, 1701,-50}, {14, 14695, 51}, {14, 14694,-51}, {14, 14688, 52}, {14, 12647,-52}, {14, 10617, 53}, {14, 10616,-53}, {14, 10596, 54}, {14, 7527,-54}, {14, 3401, 55}, {14, 3400,-55}, {15, 29378, 56}, {15, 25293,-56}, {15, 21195, 57}, {15, 21194,-57}, {15, 15053, 58}, {15, 15052,-58}, {16, 58759, 59}, {16, 58758,-59}, {16, 50585, 60}, {16, 50584,-60}, {16, 42399, 61}, {16, 42398,-61}, {16, 42397, 62}, {16, 42396,-62}, {16, 42395, 63}, {16, 42394,-63}, {16, 42393, 64}, {16, 42392,-64}, { 0, 0, 0} }; static const huff_entry_t bitalloc_e_129[] = { { 5, 12, 0}, { 5, 11, 1}, { 5, 10, -1}, { 5, 9, 2}, { 5, 8, -2}, { 5, 7, 3}, { 5, 6, -3}, { 5, 4, 4}, { 5, 3, -4}, { 5, 2, 5}, { 5, 1, -5}, { 5, 0, 6}, { 6, 63, -6}, { 6, 61, 7}, { 6, 60, -7}, { 6, 59, 8}, { 6, 58, -8}, { 6, 56, 9}, { 6, 55, -9}, { 6, 53, 10}, { 6, 52,-10}, { 6, 51, 11}, { 6, 50,-11}, { 6, 47, 12}, { 6, 46,-12}, { 6, 45, 13}, { 6, 44,-13}, { 6, 42, 14}, { 6, 41,-14}, { 6, 38, 15}, { 6, 37,-15}, { 6, 36, 16}, { 6, 35,-16}, { 6, 32, 17}, { 6, 31,-17}, { 6, 29, 18}, { 6, 28,-18}, { 6, 26, 19}, { 6, 11,-19}, { 7, 125, 20}, { 7, 124,-20}, { 7, 109, 21}, { 7, 108,-21}, { 7, 98, 22}, { 7, 97,-22}, { 7, 87, 23}, { 7, 86,-23}, { 7, 79, 24}, { 7, 78,-24}, { 7, 68, 25}, { 7, 67,-25}, { 7, 60, 26}, { 7, 55,-26}, { 7, 21, 27}, { 7, 20,-27}, { 8, 230, 28}, { 8, 229,-28}, { 8, 198, 29}, { 8, 193,-29}, { 8, 163, 30}, { 8, 162,-30}, { 8, 139, 31}, { 8, 138,-31}, { 8, 123, 32}, { 8, 122,-32}, { 8, 108, 33}, { 9, 463,-33}, { 9, 457, 34}, { 9, 456,-34}, { 9, 385, 35}, { 9, 384,-35}, { 9, 321, 36}, { 9, 320,-36}, { 9, 266, 37}, { 9, 265,-37}, { 9, 218, 38}, {10, 925,-38}, {10, 798, 39}, {10, 797,-39}, {10, 646, 40}, {10, 645,-40}, {10, 535, 41}, {10, 534,-41}, {10, 528, 42}, {10, 439,-42}, {11, 1848, 43}, {11, 1599,-43}, {11, 1592, 44}, {11, 1295,-44}, {11, 1288, 45}, {11, 1059,-45}, {11, 877, 46}, {11, 876,-46}, {12, 3197, 47}, {12, 3196,-47}, {12, 2589, 48}, {12, 2588,-48}, {12, 2117, 49}, {12, 2116,-49}, {13, 7398, 50}, {13, 7397,-50}, {13, 6374, 51}, {13, 6373,-51}, {13, 5158, 52}, {13, 5157,-52}, {14, 14799, 53}, {14, 14798,-53}, {14, 12751, 54}, {14, 12750,-54}, {14, 10318, 55}, {14, 10313,-55}, {15, 29587, 56}, {15, 29586,-56}, {15, 29584, 57}, {15, 25491,-57}, {15, 20625, 58}, {15, 20624,-58}, {16, 59171, 59}, {16, 59170,-59}, {16, 50980, 60}, {16, 41277,-60}, {16, 50981, 61}, {16, 41278,-61}, {16, 50978, 62}, {16, 41279,-62}, {16, 50979, 63}, {16, 50976,-63}, {16, 50977, 64}, {16, 41276,-64}, { 0, 0, 0} }; static const huff_entry_t bitalloc_f_129[] = { { 6, 56, 0}, { 6, 55, 1}, { 6, 54, -1}, { 6, 52, 2}, { 6, 51, -2}, { 6, 50, 3}, { 6, 49, -3}, { 6, 48, 4}, { 6, 47, -4}, { 6, 46, 5}, { 6, 45, -5}, { 6, 44, 6}, { 6, 43, -6}, { 6, 41, 7}, { 6, 40, -7}, { 6, 39, 8}, { 6, 38, -8}, { 6, 36, 9}, { 6, 35, -9}, { 6, 34, 10}, { 6, 33,-10}, { 6, 31, 11}, { 6, 30,-11}, { 6, 29, 12}, { 6, 28,-12}, { 6, 26, 13}, { 6, 25,-13}, { 6, 23, 14}, { 6, 22,-14}, { 6, 21, 15}, { 6, 20,-15}, { 6, 18, 16}, { 6, 17,-16}, { 6, 15, 17}, { 6, 14,-17}, { 6, 12, 18}, { 6, 11,-18}, { 6, 9, 19}, { 6, 8,-19}, { 6, 7, 20}, { 6, 6,-20}, { 6, 3, 21}, { 6, 2,-21}, { 6, 1, 22}, { 6, 0,-22}, { 7, 125, 23}, { 7, 124,-23}, { 7, 123, 24}, { 7, 122,-24}, { 7, 120, 25}, { 7, 119,-25}, { 7, 116, 26}, { 7, 115,-26}, { 7, 114, 27}, { 7, 107,-27}, { 7, 84, 28}, { 7, 75,-28}, { 7, 65, 29}, { 7, 64,-29}, { 7, 54, 30}, { 7, 49,-30}, { 7, 39, 31}, { 7, 38,-31}, { 7, 27, 32}, { 7, 26,-32}, { 7, 20, 33}, { 7, 11,-33}, { 7, 10, 34}, { 7, 9,-34}, { 8, 254, 35}, { 8, 253,-35}, { 8, 243, 36}, { 8, 242,-36}, { 8, 235, 37}, { 8, 234,-37}, { 8, 213, 38}, { 8, 212,-38}, { 8, 149, 39}, { 8, 148,-39}, { 8, 110, 40}, { 8, 97,-40}, { 8, 66, 41}, { 8, 65,-41}, { 8, 43, 42}, { 8, 42,-42}, { 8, 16, 43}, { 9, 511,-43}, { 9, 505, 44}, { 9, 504,-44}, { 9, 474, 45}, { 9, 473,-45}, { 9, 343, 46}, { 9, 342,-46}, { 9, 340, 47}, { 9, 223,-47}, { 9, 192, 48}, { 9, 135,-48}, { 9, 129, 49}, { 9, 128,-49}, { 9, 34, 50}, {10, 1021,-50}, {10, 951, 51}, {10, 950,-51}, {10, 944, 52}, {10, 683,-52}, {10, 445, 53}, {10, 444,-53}, {10, 269, 54}, {10, 268,-54}, {10, 71, 55}, {10, 70,-55}, {11, 2040, 56}, {11, 1891,-56}, {11, 1364, 57}, {11, 775,-57}, {11, 774, 58}, {11, 773,-58}, {12, 4083, 59}, {12, 4082,-59}, {12, 3780, 60}, {12, 2731,-60}, {12, 1545, 61}, {12, 1544,-61}, {13, 7562, 62}, {13, 5461,-62}, {13, 5460, 63}, {14, 15127,-63}, {15, 30253, 64}, {15, 30252,-64}, { 0, 0, 0} }; static const huff_entry_t bitalloc_g_129[] = { { 4, 0, 0}, { 5, 29, 1}, { 5, 28, -1}, { 5, 25, 2}, { 5, 24, -2}, { 5, 21, 3}, { 5, 20, -3}, { 5, 17, 4}, { 5, 16, -4}, { 5, 13, 5}, { 5, 12, -5}, { 5, 9, 6}, { 5, 8, -6}, { 5, 5, 7}, { 5, 4, -7}, { 6, 63, 8}, { 6, 62, -8}, { 6, 55, 9}, { 6, 54, -9}, { 6, 47, 10}, { 6, 46,-10}, { 6, 39, 11}, { 6, 38,-11}, { 6, 31, 12}, { 6, 30,-12}, { 6, 23, 13}, { 6, 22,-13}, { 6, 15, 14}, { 6, 14,-14}, { 6, 7, 15}, { 6, 6,-15}, { 7, 123, 16}, { 7, 122,-16}, { 7, 107, 17}, { 7, 106,-17}, { 7, 91, 18}, { 7, 90,-18}, { 7, 75, 19}, { 7, 74,-19}, { 7, 59, 20}, { 7, 58,-20}, { 7, 43, 21}, { 7, 42,-21}, { 7, 27, 22}, { 7, 26,-22}, { 7, 11, 23}, { 7, 10,-23}, { 7, 8, 24}, { 8, 243,-24}, { 8, 240, 25}, { 8, 211,-25}, { 8, 208, 26}, { 8, 179,-26}, { 8, 176, 27}, { 8, 147,-27}, { 8, 144, 28}, { 8, 115,-28}, { 8, 112, 29}, { 8, 83,-29}, { 8, 80, 30}, { 8, 51,-30}, { 8, 48, 31}, { 8, 19,-31}, { 9, 484, 32}, { 9, 483,-32}, { 9, 421, 33}, { 9, 420,-33}, { 9, 357, 34}, { 9, 356,-34}, { 9, 293, 35}, { 9, 292,-35}, { 9, 229, 36}, { 9, 228,-36}, { 9, 226, 37}, { 9, 165,-37}, { 9, 162, 38}, { 9, 101,-38}, { 9, 98, 39}, { 9, 37,-39}, {10, 970, 40}, {10, 965,-40}, {10, 839, 41}, {10, 838,-41}, {10, 711, 42}, {10, 710,-42}, {10, 708, 43}, {10, 583,-43}, {10, 580, 44}, {10, 455,-44}, {10, 329, 45}, {10, 328,-45}, {10, 201, 46}, {10, 200,-46}, {10, 198, 47}, {10, 73,-47}, {11, 1942, 48}, {11, 1929,-48}, {11, 1675, 49}, {11, 1674,-49}, {11, 1672, 50}, {11, 1419,-50}, {11, 1165, 51}, {11, 1164,-51}, {11, 1162, 52}, {11, 909,-52}, {11, 655, 53}, {11, 654,-53}, {11, 652, 54}, {11, 399,-54}, {11, 145, 55}, {11, 144,-55}, {12, 3886, 56}, {12, 3857,-56}, {12, 3347, 57}, {12, 3346,-57}, {12, 2837, 58}, {12, 2836,-58}, {12, 2327, 59}, {12, 2326,-59}, {12, 1817, 60}, {12, 1816,-60}, {12, 1307, 61}, {12, 1306,-61}, {12, 797, 62}, {12, 796,-62}, {13, 7775, 63}, {13, 7774,-63}, {13, 7713, 64}, {13, 7712,-64}, { 0, 0, 0} }; static const huff_entry_t *const bitalloc_select[11][8] = { { 0 }, { bitalloc_a_3, 0 }, { bitalloc_a_5, bitalloc_b_5, bitalloc_c_5, 0 }, { bitalloc_a_7, bitalloc_b_7, bitalloc_c_7, 0 }, { bitalloc_a_9, bitalloc_b_9, bitalloc_c_9, 0 }, { bitalloc_a_13, bitalloc_b_13, bitalloc_c_13, 0 }, { bitalloc_a_17, bitalloc_b_17, bitalloc_c_17, bitalloc_d_17, bitalloc_e_17, bitalloc_f_17, bitalloc_g_17, 0 }, { bitalloc_a_25, bitalloc_b_25, bitalloc_c_25, bitalloc_d_25, bitalloc_e_25, bitalloc_f_25, bitalloc_g_25, 0 }, { bitalloc_a_33, bitalloc_b_33, bitalloc_c_33, bitalloc_d_33, bitalloc_e_33, bitalloc_f_33, bitalloc_g_33, 0 }, { bitalloc_a_65, bitalloc_b_65, bitalloc_c_65, bitalloc_d_65, bitalloc_e_65, bitalloc_f_65, bitalloc_g_65, 0 }, { bitalloc_a_129, bitalloc_b_129, bitalloc_c_129, bitalloc_d_129, bitalloc_e_129, bitalloc_f_129, bitalloc_g_129, 0 }, }; static int InverseQ( dca_state_t * state, const huff_entry_t * huff ) { int value = 0; int length = 0, j; while( 1 ) { length++; value <<= 1; value |= bitstream_get (state, 1); for( j = 0; huff[j].length != 0 && huff[j].length < length; j++ ); if( huff[j].length == 0 ) break; for( ; huff[j].length == length; j++ ) { if( huff[j].code == value ) return huff[j].value; } } return 0; } xine-lib-1.2/contrib/libdca/tables_adpcm.h0000644000175000017500000037723014647725151016344 0ustar meme/* * tables_adpcm.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* 16bits signed fractional Q13 binary codes */ static const int16_t adpcm_vb[4096][4] = { { 9928, -2618, -1093, -1263 }, { 11077, -2876, -1747, -308 }, { 10503, -1082, -1426, -1167 }, { 9337, -2403, -1495, 274 }, { 10698, -2529, -532, -1122 }, { 10368, -3974, -1264, -750 }, { 10070, -3667, 346, 863 }, { 10278, -3093, 311, -576 }, { 9894, -1330, -1428, -860 }, { 10544, -1923, -1058, -971 }, { 10996, -1632, -841, -1404 }, { 11832, -3465, 1658, -1990 }, { 10852, -688, -2658, -499 }, { 10546, -1749, -147, -1733 }, { 10801, -1004, -708, -1453 }, { 10588, -441, -2113, -952 }, { 10141, -3331, -582, -1432 }, { 9608, -2590, 383, 258 }, { 11422, -3265, 229, -1544 }, { 10460, -1338, -713, -1568 }, { 10306, -1721, -1660, -603 }, { 9580, -1812, -1235, -1061 }, { 11471, -2285, -1617, -607 }, { 10081, -2225, -1408, -868 }, { 10715, -2624, -1367, -704 }, { 10616, -1871, -2770, -35 }, { 9352, -2340, -1024, -1566 }, { 11065, -1458, -1926, -735 }, { 11334, -2056, -1041, -1144 }, { 9825, -2048, -794, -1536 }, { 11850, -2695, -1123, -867 }, { 10654, -2226, -1891, -373 }, { 10024, -1557, -808, -1069 }, { 11142, -1266, -3238, 128 }, { 11729, -3282, -514, -1011 }, { 11402, -2094, -2335, -189 }, { 10195, -3658, 181, -1875 }, { 11431, -2626, -404, -1377 }, { 11001, -3868, -619, -1077 }, { 10894, -2559, 274, -1758 }, { 9633, -1482, -2253, -773 }, { 11245, -3321, 830, -1972 }, { 9768, -2701, -199, -1859 }, { 10500, -2042, 525, -2043 }, { 11669, -4069, 293, -1468 }, { 9192, -1991, -583, -61 }, { 10057, -3220, -2015, -473 }, { 9497, -2315, -2490, -467 }, { 10455, -3069, -1194, -1007 }, { 9994, -1936, -60, -1225 }, { 9295, -2156, -1761, -1134 }, { 10085, -3748, -1026, 197 }, { 9334, -2360, 804, -351 }, { 11561, -2553, 1352, -2313 }, { 12837, -3998, 1195, -1958 }, { 10114, -1100, -2414, -394 }, { 9341, -2530, 315, 755 }, { 10131, -3164, 1411, -674 }, { 9535, -905, -1551, 579 }, { 11717, -1519, -3051, 91 }, { 9824, -2911, -2775, 192 }, { 9662, -2934, -561, 1450 }, { 11085, -3392, -1298, -659 }, { 8955, -2102, -1899, 703 }, { 8607, -1742, -4348, 814 }, { 7640, -2063, -3617, 52 }, { 7074, -826, -4325, 4375 }, { 7714, 584, -4238, 1927 }, { 6355, -952, -4912, 3127 }, { 7069, -660, -6413, 4087 }, { 8313, -132, -2964, -876 }, { 6952, -1422, -3962, -24 }, { 9299, -734, -3088, -263 }, { 9484, -574, -4513, 466 }, { 7246, -91, -3735, -704 }, { 8325, -1417, -3090, -530 }, { 6469, -1226, -4757, 829 }, { 6652, -368, -5682, 1393 }, { 7971, -1278, -2284, 1205 }, { 7229, -699, -3556, 1840 }, { 7994, 1284, -2729, 732 }, { 9005, -698, -4522, 2189 }, { 6963, 197, -2727, 380 }, { 8527, 135, -3991, -213 }, { 8840, 934, -3014, -567 }, { 10125, 418, -3284, -371 }, { 6367, 361, -2318, 2554 }, { 7892, 172, -5247, 4673 }, { 6674, 387, -5424, 4398 }, { 6240, 684, -4047, 1219 }, { 11170, -794, -5081, 1195 }, { 11765, -648, -6265, 2052 }, { 10845, -775, -3837, 366 }, { 12496, -689, -8260, 3562 }, { 7893, -1166, -4972, 988 }, { 8592, 1052, -5986, 3087 }, { 7277, 1874, -5685, 3579 }, { 6900, 2016, -4809, 3491 }, { 8530, -2405, -3250, 1986 }, { 9426, 494, -7067, 5038 }, { 10285, 564, -8210, 5370 }, { 8749, -2207, -3980, 2852 }, { 9653, -2686, -4300, 1400 }, { 9770, -2286, -5663, 4233 }, { 8490, -4, -7048, 4496 }, { 7697, -1209, -5328, 3183 }, { 6451, 801, -4324, -554 }, { 7387, 1806, -5265, 545 }, { 7450, -2302, -4445, 1418 }, { 8817, -1370, -5827, 2168 }, { 10324, -2406, -5629, 2579 }, { 8863, -2578, -3537, 467 }, { 6901, -1624, -3169, 3392 }, { 7846, 156, -6948, 3381 }, { 7928, -1115, -5972, 4816 }, { 6089, -599, -4368, -320 }, { 7833, 1246, -3960, -621 }, { 8931, 2521, -6768, 2052 }, { 8900, 1944, -4126, 40 }, { 7661, -34, -2855, 2480 }, { 5873, 474, -3262, 3712 }, { 7535, -234, -4699, 216 }, { 5856, 143, -5142, 73 }, { 8944, -106, -5874, 3663 }, { 7134, 426, -5879, 2895 }, { 10199, 1011, -4762, 369 }, { 8454, 264, -5971, 1291 }, { 7822, -2449, -4333, 4540 }, { 6200, -2758, -2632, 1497 }, { 6070, -4315, -2699, 414 }, { 7047, -3739, -3210, 1060 }, { 5675, -3801, -2717, -407 }, { 4789, -4063, -2628, -744 }, { 4023, -3366, -3133, -726 }, { 4296, -2407, -3381, -513 }, { 4388, -2931, -2820, 1512 }, { 4559, -4233, -1941, 1976 }, { 6702, -3208, -1755, 1680 }, { 4416, -3521, -1052, 2984 }, { 7154, -4266, -1203, 3732 }, { 3625, -4242, -3244, 1395 }, { 6518, -2856, -1304, 2887 }, { 6170, -1949, -3014, 3973 }, { 5189, -2451, -4020, 3477 }, { 6218, -2988, -1921, 3844 }, { 4827, -3688, -1928, 3343 }, { 6668, -3991, -2805, 3095 }, { 5297, -3115, -3684, 2390 }, { 5354, -4614, -2662, 1504 }, { 4196, -3091, -4147, 1135 }, { 3540, -2893, -4007, 100 }, { 5569, -1602, -4007, 1909 }, { 4341, -2091, -4272, 252 }, { 5559, -2878, -3832, 498 }, { 4548, -4479, -2898, -27 }, { 5176, -2494, -4635, 1476 }, { 3294, -3485, -3738, 716 }, { 4920, -1229, -4195, -365 }, { 3257, -3518, -3349, 2862 }, { 5286, -1948, -3485, -778 }, { 6502, -3051, -152, 2854 }, { 5864, -4192, -1076, 3451 }, { 4656, -3122, -3448, 179 }, { 5907, -754, -1596, 3116 }, { 7229, -3680, -1590, 2892 }, { 5107, -3888, -3364, 806 }, { 6764, -2635, -3450, 134 }, { 5258, -2827, -2844, -1052 }, { 5798, -1725, -4305, 205 }, { 5404, -1213, -3362, 449 }, { 6224, -2738, -3046, -581 }, { 4223, -2438, -2725, 3745 }, { 4751, -3411, -2123, 116 }, { 3868, -3000, -3954, 2297 }, { 6819, -2899, -4277, 2825 }, { 4207, -4754, -2808, 865 }, { 4804, -1494, -1997, 4688 }, { 5282, -2213, -548, 3559 }, { 5580, -1912, -566, 4370 }, { 6168, -2857, -672, 4053 }, { 6583, -4515, -2850, 1670 }, { 6511, -3093, -3988, 1421 }, { 4646, -1790, -1443, 3650 }, { 5915, -924, -2020, 896 }, { 7814, -4181, -3152, 2007 }, { 6190, -2238, -4817, 2279 }, { 4737, -4034, -3288, 1835 }, { 8161, -3633, -3423, 3137 }, { 7415, -2351, -2088, 4290 }, { 4106, -2517, -62, 2905 }, { 4909, -3145, -614, 4112 }, { 4938, -3281, -397, 1100 }, { -173, 919, 1589, -5363 }, { -13, 796, -295, -6655 }, { -1860, -829, 1141, -4555 }, { 2298, -838, -664, -5005 }, { -884, -1097, 2074, -4613 }, { -101, 281, 2846, -4535 }, { 1166, 453, 2429, -5910 }, { 879, -664, 2370, -5452 }, { 1415, -370, -1699, -4727 }, { -1413, 1277, -669, -6649 }, { 2133, 304, -968, -4624 }, { 380, 586, -2087, -4892 }, { 1336, 275, -82, -5789 }, { -2459, 1057, -34, -5416 }, { 2278, -1758, 866, -5653 }, { 1945, -2295, -149, -5302 }, { 1287, -3525, 996, -5255 }, { 2297, 803, 1177, -6067 }, { 187, -180, -619, -6202 }, { -793, -2537, 1554, -5057 }, { -2703, -204, -629, -5853 }, { -1007, -146, 313, -5582 }, { 830, 357, 869, -6363 }, { -228, -575, -3177, -4433 }, { -1001, -1553, -142, -5708 }, { -1644, 1683, 1721, -4533 }, { 893, 1924, -15, -5791 }, { 2195, 2061, -262, -5471 }, { 3031, 270, 311, -5096 }, { 1912, 1638, -1523, -4677 }, { -3142, -55, 253, -4914 }, { 356, -1680, 343, -6123 }, { -2241, -1734, -976, -5939 }, { -2196, -2893, 547, -4938 }, { -1245, 126, -1916, -5419 }, { -249, -3755, -1422, -5594 }, { 575, -2683, -1926, -4566 }, { -762, 1885, 192, -5880 }, { -811, -2562, -1068, -6013 }, { -2264, -3086, -976, -4775 }, { 70, -1215, 2880, -4410 }, { 714, -3760, 2916, -4691 }, { -244, -3404, 1740, -4493 }, { 684, -5137, -328, -5608 }, { -529, -3825, -1786, -4535 }, { -713, -4743, -1118, -5546 }, { 2718, -3788, 1798, -5708 }, { -1639, -3679, -1564, -6095 }, { 1693, -2642, -1389, -4539 }, { 505, -1573, -1651, -4878 }, { -835, -2256, -1941, -5352 }, { 1464, -411, 1993, -6441 }, { 493, -3184, -145, -6148 }, { -1413, 499, -1617, -6479 }, { -294, 1722, -1419, -5725 }, { -2937, -1528, -175, -4624 }, { -594, -5911, -56, -6146 }, { -300, -4275, 1156, -5947 }, { 552, -2643, 2669, -3959 }, { 905, -4158, 1789, -5809 }, { 1336, -2009, 2108, -5903 }, { 1555, -3600, 1110, -6759 }, { -1294, -3464, 77, -6084 }, { -1139, -4006, -1270, -4181 }, { -5094, -3296, 1092, -2847 }, { -5503, -2883, 1984, -2067 }, { -4671, -4218, -1417, -4132 }, { -3763, -3818, 1262, -3082 }, { -5132, -3430, 2928, -728 }, { -5957, -2877, 1251, -2446 }, { -4425, -2319, -212, -4276 }, { -6201, -1993, 1774, -2182 }, { -5500, -3836, 2201, -1396 }, { -6934, -2334, 2366, -1293 }, { -6124, -4140, 1337, -1977 }, { -6553, -4186, 1756, -1325 }, { -5126, -1258, 744, -3656 }, { -5167, -1390, 1581, -2895 }, { -4525, -3398, 2429, -1865 }, { -4076, -3183, 2027, -2510 }, { -6191, -3274, 1838, -1814 }, { -4454, -2753, 2723, -1185 }, { -6655, -4797, 251, -2595 }, { -6332, -2232, 1832, 217 }, { -5869, -1698, 134, 340 }, { -6614, -1045, 2126, -1932 }, { -4859, -2107, 2010, -2435 }, { -6274, -1622, 2808, -1374 }, { -3119, -3209, 521, -3988 }, { -5676, -2082, -420, -2711 }, { -7073, -3623, 696, -2343 }, { -5986, -4224, 572, -2454 }, { -4340, -4521, 882, -2771 }, { -6178, -1933, 535, -1444 }, { -4923, -4163, 1744, -2066 }, { -6410, -1519, 1058, -2683 }, { -5077, -1185, 856, -2216 }, { -7091, -2444, 687, -2597 }, { -5284, -2165, 3239, -993 }, { -4763, -1497, 197, -3179 }, { -4128, -4958, -396, -3578 }, { -5054, -3878, -647, -2672 }, { -7005, -3348, 1679, -1579 }, { -5767, -1017, 2582, -1915 }, { -7069, -2787, 1331, -2070 }, { -5532, -2296, 706, -2950 }, { -5059, -3543, -821, -3637 }, { -6639, -1835, 1016, -696 }, { -5611, -5220, -694, -3371 }, { -5994, -2803, 2933, -729 }, { -5948, -619, 1596, -2676 }, { -5486, -4419, 153, -3265 }, { -4329, -3440, 1646, -1439 }, { -4083, -3978, 177, -3569 }, { -4289, -2599, 1224, -3075 }, { -5707, -3253, 1912, -759 }, { -6606, -3437, 2562, -571 }, { -5254, -2444, 769, -352 }, { -6545, -3154, 582, -1103 }, { -5328, -2241, 2566, -1775 }, { -7216, -1936, 1538, -1983 }, { -3730, -2451, 426, -3869 }, { -5110, -1385, 2031, -1169 }, { -6470, -2715, 269, -3123 }, { -5806, -2480, -97, -3832 }, { -3683, -4916, -490, -4330 }, { -6341, -2083, -669, -115 }, { -4913, -4079, -837, -4673 }, { -3274, -2497, 2334, -2652 }, { -1286, -1731, 2550, -3756 }, { -3375, -877, 926, -3977 }, { -2525, -2079, 2879, -2625 }, { -5308, -504, 3111, -1607 }, { -4904, 460, 4093, -1232 }, { -1993, 1616, 4656, -1913 }, { -3481, -1176, 3119, -2236 }, { -4132, -1502, 2339, -2545 }, { -2542, 1151, 3569, -2550 }, { -4381, 430, 3147, -2082 }, { -3888, 867, 3899, -1657 }, { -2861, 1290, 4202, -1979 }, { -3893, -253, 2363, -2764 }, { -1705, 688, 3827, -2923 }, { -2223, 2312, 3700, -3148 }, { -1986, -720, 5021, -795 }, { -3177, 242, 1952, -3352 }, { -1854, 1509, 2528, -3815 }, { -3173, 97, 5019, -706 }, { -2689, -145, 1375, -3915 }, { -4838, -385, 2488, -2427 }, { -4557, -355, 1603, -3060 }, { -3522, 1832, 3292, -2674 }, { -3769, 780, 2378, -2704 }, { -4323, -1932, 3414, -1169 }, { -2740, 1158, 2729, -3273 }, { -3647, 210, 1464, -2892 }, { -2342, -2097, 1513, -3727 }, { -4422, -1242, 3130, -1833 }, { -1308, -1039, 4290, -1875 }, { -1754, -2535, 3298, -2314 }, { -4102, -186, 4037, -1094 }, { -1008, 1570, 3290, 171 }, { -3322, -2621, 2791, -1536 }, { -2539, -2597, 3442, -1672 }, { -3411, -2015, 3670, -1174 }, { -2097, 730, 5581, -1399 }, { -1510, -74, 4820, -2004 }, { -4086, -868, 4425, -771 }, { -956, -986, 3640, -2925 }, { -2087, -1250, 3464, -2458 }, { -3308, -2411, 1334, -3667 }, { -2264, -389, 4004, -1854 }, { -680, 239, 4058, -3388 }, { -1357, 30, 2993, -3658 }, { -3601, -552, 1177, -1136 }, { -2641, 442, 4374, -1625 }, { -2525, 770, 1640, -3895 }, { -3172, -891, 3893, -1608 }, { -2996, 13, 3277, -2414 }, { -899, 1055, 4470, -2501 }, { -422, -584, 3475, -3787 }, { -1978, -593, 2566, -3415 }, { -3150, -1280, 2362, -3047 }, { -3592, 224, 1026, -3932 }, { -4840, -1189, 3633, -879 }, { -3952, -2255, 2916, -1826 }, { -1695, 28, 1810, -349 }, { -745, -2484, 3308, -3293 }, { -1016, 1563, 5365, -1823 }, { -2172, -1787, 4266, -1287 }, { -1241, -1951, 3982, -2413 }, { -2009, -2639, 2330, -3480 }, { 5105, -1618, -2588, -2015 }, { 6497, -1523, -3218, -910 }, { 6526, -2305, -2029, -1790 }, { 5289, -99, -3436, -400 }, { 5781, -1623, -1577, -2617 }, { 5259, -670, -3125, -1700 }, { 6343, -1256, -331, -3222 }, { 7967, -678, -2195, -1462 }, { 6119, -695, -2988, -1538 }, { 6108, 494, -3359, -1548 }, { 5067, 969, -2328, -2707 }, { 7595, -435, -1497, -2056 }, { 6929, -719, -2420, -1665 }, { 5190, 584, -2982, -2103 }, { 6106, -444, -1411, -2739 }, { 5584, 289, -1804, -2803 }, { 5276, 227, -1180, -3361 }, { 7544, -1525, -1834, -1725 }, { 5986, -1470, -2606, -1701 }, { 5096, -765, -1712, -3006 }, { 5423, -149, -3933, -1157 }, { 7651, 26, -2445, -1507 }, { 4745, -464, -1735, -2362 }, { 5352, -1011, -1094, -1999 }, { 6300, -672, -542, -1950 }, { 6675, -1020, -1318, -1059 }, { 7218, -2036, -603, -2462 }, { 7755, -1514, -2430, -1229 }, { 5041, 449, -1056, -2405 }, { 6710, -2277, -1344, -2284 }, { 6824, -1347, -2254, 251 }, { 6068, -1857, -983, -1316 }, { 5603, -2177, -2730, -1477 }, { 5838, -1059, -3604, -970 }, { 5076, -789, -335, -2413 }, { 6191, -1634, -2000, -2129 }, { 5092, -1292, -2543, -1034 }, { 5305, 435, -1710, -1850 }, { 6140, 561, -2176, -2380 }, { 6752, 348, -2496, -1890 }, { 6405, 273, -1098, -2778 }, { 6942, -1340, -496, -1381 }, { 5238, -687, -2454, -2349 }, { 6959, -882, -1833, -2061 }, { 6292, -253, -2125, -2199 }, { 5838, -574, -759, -3215 }, { 6954, -1484, -640, -2771 }, { 7498, -1706, -1210, -2154 }, { 6772, -1003, -1235, -2532 }, { 6014, 228, -2154, -1108 }, { 6943, -2178, -2644, -1122 }, { 7262, -763, -3056, -1090 }, { 6273, -1478, -1072, 177 }, { 4734, 425, -2912, 357 }, { 7129, 168, -1537, -2327 }, { 7204, -434, -746, -2660 }, { 6879, 57, -3087, -1310 }, { 4623, -610, -718, -3459 }, { 6565, -543, -1998, -339 }, { 4752, -277, -2066, -1405 }, { 7435, -1416, -1904, -505 }, { 4076, 150, -1222, -3556 }, { 7082, -28, -1456, -1174 }, { 5941, -446, -1326, -1158 }, { 3870, -1648, -2474, -2589 }, { 858, 37, -3387, -3721 }, { 3557, -1503, -1664, -3383 }, { 3336, -1972, -3079, -2216 }, { 3186, 60, -4185, -863 }, { 3456, -773, -3066, -2457 }, { 4131, -913, -2060, -2601 }, { 4431, -691, -4114, -972 }, { 3461, -334, -3680, -1751 }, { 2006, -459, -2214, -3827 }, { 1322, 32, -2816, -3203 }, { 4425, -1897, -2791, -1946 }, { 4504, 23, -3421, -1909 }, { 3090, -885, -2366, -3264 }, { 3209, -2363, -3730, -834 }, { 3312, -1471, -3641, -1579 }, { 4184, -1669, -3323, -1248 }, { 2190, -931, -3302, -2944 }, { 2947, -229, -4791, -1195 }, { 2020, -1626, -2700, -3125 }, { 2214, -326, -4352, -1683 }, { 3286, -2619, -2412, -2458 }, { 1000, -2571, -4129, -2158 }, { 2496, -2627, -3611, -1433 }, { 2043, -2191, -2167, -3827 }, { 2571, -2544, -1915, -3222 }, { 2022, -1501, -3856, -2165 }, { 2685, -1180, -1461, -4038 }, { 1610, -2313, -4391, -1173 }, { 2340, -2490, -4215, -516 }, { 1742, -2615, -3632, -2146 }, { 523, -1293, -4246, -2442 }, { 3725, -2723, -3014, -1576 }, { 3554, -1381, -4200, -824 }, { 1291, -1594, -4777, -1430 }, { 1452, 515, -2960, -3830 }, { 4264, -894, -3305, -1826 }, { 2606, -1452, -4522, -966 }, { 1196, -830, -4807, -1816 }, { 1054, -775, -2616, -4071 }, { 4206, 415, -4344, -1132 }, { 3044, 491, -4126, -1934 }, { 988, -901, -3353, -3443 }, { 1729, -3063, -2267, -3370 }, { 3915, 912, -2989, -2387 }, { 3781, 300, -2457, -3050 }, { 2712, 924, -1350, -1206 }, { 4230, 405, -2343, 665 }, { 1878, -873, -225, -29 }, { 3510, 56, -1334, -3420 }, { 2850, 1447, -2651, -3150 }, { 1510, -706, -4125, -2483 }, { 3115, 793, -1692, -3894 }, { 2667, 213, -2973, -2786 }, { 1184, -2384, -3051, -3173 }, { 2139, 796, -2079, -3697 }, { 1464, -1483, -3726, -2754 }, { 2407, -1148, -3915, -1569 }, { 2612, -1779, -3217, -2271 }, { 2406, -2870, -2937, -2496 }, { 2140, 126, -3646, -2758 }, { 2952, -1036, 268, -1423 }, { 93, -1931, -3841, -3535 }, { 389, -2953, -3383, -3343 }, { 8652, -5511, -1662, 565 }, { 7427, -2791, -2535, -842 }, { 8541, -4253, -1407, -988 }, { 8018, -3203, -2998, 105 }, { 7231, -3926, -958, 1308 }, { 7331, -3690, -363, 2586 }, { 6803, -3646, -2226, -903 }, { 8163, -2811, -477, -2235 }, { 9356, -3818, -1685, -684 }, { 8466, -2854, -302, -698 }, { 8458, -3224, 517, 279 }, { 8074, -2619, -1326, 2596 }, { 8779, -2761, -2527, -441 }, { 6533, -2887, -899, -696 }, { 7394, -2305, -1642, -120 }, { 8281, -3780, -22, 1305 }, { 9158, -4413, -779, 901 }, { 9031, -5240, -1109, 1678 }, { 8717, -3650, 410, -1075 }, { 7317, -3197, -818, -2264 }, { 7934, -2385, -1214, -1886 }, { 8256, -4441, -291, -587 }, { 7358, -3395, 1090, -270 }, { 9446, -4910, -1343, -473 }, { 8187, -4726, -808, 1166 }, { 7504, -3845, -47, 267 }, { 8029, -2146, -1283, -383 }, { 7461, -2705, -853, 783 }, { 9367, -3636, -645, -354 }, { 8955, -3473, -308, -1947 }, { 8676, -2683, -2099, 1485 }, { 7481, -3003, -871, -444 }, { 8015, -2839, -1673, 1175 }, { 6947, -4643, -1527, -1047 }, { 7622, -2575, -137, -960 }, { 9388, -4279, -707, -1322 }, { 8382, -5259, -1283, -565 }, { 6856, -4138, -1030, 630 }, { 8659, -2571, -1124, -1666 }, { 8763, -3807, -537, 2543 }, { 8049, -3578, -2186, -604 }, { 8272, -2351, -1985, -1214 }, { 6855, -3796, -1527, -1631 }, { 7178, -2896, -1600, -1756 }, { 7040, -2888, -89, -1586 }, { 6261, -3403, -264, 998 }, { 7756, -4699, -1543, -834 }, { 7682, -4622, -758, -1721 }, { 8839, -4232, -2932, 1959 }, { 9363, -4679, -1956, 39 }, { 7883, -3616, -1414, -1432 }, { 8828, -3188, -1356, -1312 }, { 7746, -3987, -121, -2424 }, { 9262, -3256, -693, 818 }, { 7670, -3420, -148, 3504 }, { 7344, -3183, 608, 1595 }, { 8976, -4139, -1848, 1304 }, { 6708, -4131, 33, -852 }, { 7840, -4429, -2275, 79 }, { 8980, -3858, -2838, 453 }, { 7815, -4604, -2563, 944 }, { 8372, -4422, -1783, 3071 }, { 8623, -5128, -1754, 2888 }, { 7462, -3281, 889, 920 }, { 8416, -59, -1320, -1825 }, { 7928, -1488, -414, -2499 }, { 8110, -977, -1047, -2042 }, { 8278, -687, -1597, -1550 }, { 7988, -174, -977, -2106 }, { 8609, -1547, -1628, -1527 }, { 9000, -1798, -946, -1761 }, { 8954, -872, -1404, -1594 }, { 8939, 466, -748, -1212 }, { 9549, -329, -177, -1360 }, { 9411, -18, -1126, -1568 }, { 8859, -782, -488, -1338 }, { 8955, -218, -43, -1209 }, { 9131, -69, -453, -1001 }, { 9069, -1519, -1091, -1199 }, { 9247, -1309, -566, -1146 }, { 8528, -1617, -287, -1313 }, { 7763, -745, -149, -2040 }, { 8294, -343, 257, -2633 }, { 10149, -893, -552, -1649 }, { 9398, -915, 218, -2042 }, { 9703, -1194, -675, -1592 }, { 9586, -700, -427, -1710 }, { 8930, 497, -1445, -1218 }, { 9285, -1323, -163, -1552 }, { 8431, -1289, -985, -1404 }, { 8965, -655, 653, -1483 }, { 9542, -1001, -951, -1128 }, { 9205, -647, -37, -882 }, { 8603, -56, 514, -1793 }, { 9300, -12, -1324, -567 }, { 8773, 238, -184, -1456 }, { 9941, -1306, -69, -1792 }, { 9360, 279, -376, -1919 }, { 9180, -285, 95, -2170 }, { 9922, -501, -970, -1570 }, { 8341, -1493, -856, -2092 }, { 8780, -981, -850, -1014 }, { 9721, -548, -1504, -1094 }, { 9973, -1493, 482, -2105 }, { 8707, -333, -1027, -1087 }, { 9098, -469, -315, -1723 }, { 8879, -1050, -661, -2020 }, { 8857, 602, -866, -1918 }, { 8945, -1025, -2154, -1071 }, { 8484, -1930, -468, -2179 }, { 9177, -1903, -224, -2112 }, { 8652, -137, -2097, -1214 }, { 9063, -973, -1405, -772 }, { 9328, -456, 662, -2469 }, { 10101, -697, 127, -2113 }, { 9685, 811, -2359, -1024 }, { 8586, -94, -460, -1982 }, { 7924, -141, -509, -2513 }, { 7773, -669, -107, -2835 }, { 8636, -1064, -46, -2409 }, { 9748, 596, -1815, -1349 }, { 8924, 304, 547, -2614 }, { 9442, 746, -1153, -1679 }, { 9454, -278, -529, -1976 }, { 8488, 561, -32, -2160 }, { 10083, -63, -1544, -1364 }, { 9390, -1278, 568, -1131 }, { 9740, -49, -2253, -910 }, { 3636, -2391, -1115, -3614 }, { 6014, -3204, -1902, -1808 }, { 5787, -3497, -1116, -2590 }, { 4365, -3046, -1632, -2668 }, { 4733, -2192, -2029, -2468 }, { 5412, -2753, -1633, -2464 }, { 4455, -3375, -767, -3399 }, { 4456, -1644, -983, -2841 }, { 4039, -2523, 38, -3967 }, { 3406, -2662, 72, -4757 }, { 4279, -2005, 1055, -4399 }, { 4321, -1377, -860, -3786 }, { 3743, -5739, -651, -3047 }, { 3528, -5510, 361, -4060 }, { 6496, -4886, -136, -2689 }, { 4513, -5254, 551, -4010 }, { 6557, -3413, -92, -3063 }, { 4186, -2059, 187, 47 }, { 6210, -4117, -1256, -1985 }, { 6038, -4343, 351, -2124 }, { 4305, -4780, -2077, -1897 }, { 4480, -3815, -2228, -1533 }, { 5582, -3689, 1221, -3429 }, { 5532, -4874, 1195, -2765 }, { 6518, -2853, -905, -2568 }, { 5467, -2192, 470, -4115 }, { 4139, -1577, 240, -3493 }, { 5281, -1926, -729, -3340 }, { 5214, -2870, 1359, -4289 }, { 3046, -3510, -1536, -3214 }, { 5433, -2881, -1230, -1184 }, { 4861, -3932, -1071, -2791 }, { 5693, -4234, -1906, -1502 }, { 4004, -3935, -1804, -2383 }, { 3728, -3792, 681, -4773 }, { 3621, -3030, -1951, -2598 }, { 5133, -3903, 44, -3700 }, { 3561, -3451, 1183, -5301 }, { 5026, -2762, -2341, -1780 }, { 5841, -2492, -467, -3210 }, { 5591, -1791, 497, -2472 }, { 5054, -3898, -1822, -2097 }, { 5813, -2792, 83, -1469 }, { 4432, -4497, 1670, -5193 }, { 5338, -4653, -1109, -2200 }, { 3239, -4401, -648, -3655 }, { 2147, -3598, -1200, -4242 }, { 4417, -2271, -1552, -3210 }, { 6494, -4360, 852, -3565 }, { 2393, -6358, -856, -4524 }, { 4959, -4196, -847, -1403 }, { 4924, -5438, -226, -3026 }, { 4254, -5303, -1306, -2424 }, { 4121, -3126, -2334, -1981 }, { 3437, -4443, -1464, -2953 }, { 3203, -3459, -529, -4339 }, { 5896, -5945, 543, -3246 }, { 1987, -4733, -220, -4863 }, { 4358, -4431, -514, -3081 }, { 4583, -2416, -492, -2287 }, { 2943, -5035, 419, -4927 }, { 5358, -5129, 987, -4309 }, { 4460, -3392, 1752, -5634 }, { 3415, -4633, 1507, -5945 }, { 811, -4692, -445, 2333 }, { 1009, -5613, -1857, 1360 }, { 1338, -2712, -2720, 3036 }, { 1002, -3754, -2582, 2344 }, { 750, -4608, -2334, 714 }, { 2043, -3207, -2822, 2173 }, { -140, -4654, -2953, 357 }, { -54, -4026, -2376, 2695 }, { 1858, -5022, -717, 2287 }, { 2064, -3894, -722, 3255 }, { 2727, -4558, -332, 2603 }, { 1810, -5378, 283, 1826 }, { 3935, -4326, 762, 3383 }, { -767, -4697, -2510, 1922 }, { 2146, -4312, -3090, 1641 }, { 54, -5881, -2114, 921 }, { 1992, -5766, -640, 1574 }, { 1200, -5371, -1114, 1828 }, { 2973, -5337, 34, 2266 }, { 1531, -5018, -2817, 1192 }, { 3078, -4570, 117, 1990 }, { 924, -4286, -1388, 2713 }, { 142, -5058, -2848, 1487 }, { -106, -6180, -881, 842 }, { 673, -5433, -229, 1596 }, { 783, -5710, -2784, 562 }, { 1935, -5729, -2009, 856 }, { -410, -3375, -3326, 2734 }, { 234, -3000, -2628, 3260 }, { 733, -3405, -3806, 1589 }, { 771, -4285, -3544, 1314 }, { 1192, -3563, -3960, 2178 }, { 206, -5555, -1250, 1546 }, { -130, -3815, -1210, 3041 }, { 646, -3940, -393, 2992 }, { -184, -4931, -1767, 1925 }, { 2746, -5120, -2275, 1464 }, { 2440, -3731, -3352, 2729 }, { -490, -4942, -3779, 997 }, { 68, -2636, -4167, 3778 }, { 48, -3986, -4118, 2106 }, { -978, -5486, -1336, 1390 }, { 1126, -5297, -855, 640 }, { -472, -3975, -3622, 1557 }, { 2456, -5344, -1523, 1648 }, { -774, -5652, -2417, 1147 }, { 995, -6122, -812, 1132 }, { 3282, -4571, -1763, 2175 }, { 3655, -3862, -676, 3568 }, { 3038, -3647, -1672, 3381 }, { 2595, -2964, -2772, 3263 }, { 4176, -3353, -1148, 4354 }, { 1603, -3442, -1500, 3444 }, { 828, -6226, -1783, 678 }, { 1421, -3333, -3080, 3403 }, { 1121, -4727, -1924, 1984 }, { -186, -5083, -682, 1796 }, { 819, -2778, -3488, 530 }, { 421, -2873, -3832, 2596 }, { 2164, -4263, -1605, 2282 }, { 585, -4437, -682, -491 }, { -644, -4452, -1157, 2325 }, { 1991, -4299, 210, 2834 }, { 2135, -3632, -2113, 665 }, { -7482, -2724, -2662, -1380 }, { -6983, -2166, -3756, -3509 }, { -7085, -1439, -2397, -3112 }, { -7760, -3049, -3319, -2822 }, { -8413, -2760, -4406, -3298 }, { -5995, -3943, -1260, -3750 }, { -7879, -1554, -3464, -2606 }, { -6314, -2034, -3878, -1681 }, { -8849, -2084, -1399, -1231 }, { -7153, -2602, -1384, -817 }, { -8041, -2571, -407, -2785 }, { -7246, -2233, -1578, 260 }, { -7336, -3883, -4061, -1342 }, { -7619, -3908, -2342, 382 }, { -8684, -3724, -1662, -727 }, { -7850, -2922, -1770, -3449 }, { -6766, -2034, -1293, -1988 }, { -6895, -2116, -968, -3744 }, { -7136, -5147, -2618, -2809 }, { -8224, -3724, -2519, -1589 }, { -6711, -2750, -3021, -219 }, { -8059, -1638, -1102, -3175 }, { -8710, -4839, -3963, -3143 }, { -9363, -4965, -3257, -1002 }, { -6099, -1751, -3157, -395 }, { -6453, -3216, -4597, -483 }, { -7879, -5477, -839, -2638 }, { -7202, -4038, -526, -2856 }, { -8022, -1228, -1910, -1646 }, { -9117, -1393, -1582, -2535 }, { -9095, -2693, -636, -2605 }, { -9076, -2580, -3481, -2519 }, { -8327, -4859, -2422, 83 }, { -8368, -2129, -2324, -2173 }, { -8554, -4563, -3842, -2007 }, { -10462, -4261, -1934, -2084 }, { -9717, -3187, -2294, -1896 }, { -9625, -3889, -3020, -3224 }, { -9857, -4955, -4239, -2184 }, { -9752, -2351, -2277, -3129 }, { -7219, -1302, -2639, -1603 }, { -7477, -4360, -3718, -559 }, { -5680, -2033, -2326, -3078 }, { -10190, -5548, -4643, -3601 }, { -9431, -4121, -879, -2479 }, { -8365, -5450, -2020, -1439 }, { -6289, -5178, -1605, -3845 }, { -8319, -3866, -687, -2792 }, { -8131, -1031, -3608, -3947 }, { -10510, -2560, -1199, -2082 }, { -11015, -3640, -2748, -3041 }, { -8762, -5022, -5231, -1162 }, { -10153, -2715, -4648, -4859 }, { -7930, -5205, -1900, -3600 }, { -9561, -3548, -4812, -3722 }, { -7663, -4709, -1180, -1475 }, { -9073, -5707, -1815, -2980 }, { -8602, -2363, -2675, -3770 }, { -9967, -5614, -3575, -3838 }, { -8324, -1005, -2131, -3254 }, { -10331, -5737, -2550, -2940 }, { -8234, -3354, -3361, -4479 }, { -8140, -1951, -4526, -4545 }, { -6679, -2662, -2284, -4182 }, { -1122, -1514, -6427, -212 }, { 54, -1660, -5424, -1404 }, { 254, -2778, -5222, 846 }, { -267, -1661, -6577, 814 }, { -305, -2021, -5759, 1484 }, { -1791, -2446, -6867, -86 }, { -2929, -3158, -6603, -1799 }, { -1391, -3189, -5557, -1053 }, { -1602, -884, -6767, -1213 }, { -361, -318, -6219, -44 }, { -4078, -2635, -5523, -433 }, { -956, 478, -4382, 1470 }, { -3300, -2462, -6021, -2721 }, { 708, -2434, -5085, -540 }, { -2435, -3607, -5647, -2110 }, { -491, -1134, -4681, -2886 }, { 87, -3435, -4641, -1194 }, { -586, -2927, -4784, 366 }, { -1394, -2326, -6021, 350 }, { 97, -2519, -4678, -2120 }, { -1547, -1907, -5069, -2993 }, { 268, -3724, -4719, 127 }, { -827, -1190, -5912, 1144 }, { -3959, -2322, -6898, -1974 }, { -2728, -2228, -6426, -562 }, { -456, -666, -5785, -1609 }, { 531, -1096, -5731, -656 }, { -3569, -688, -3915, 110 }, { -4752, -1725, -4393, -377 }, { -3210, -3315, -6960, -840 }, { -688, -3416, -4971, 1221 }, { -1833, 77, -6491, -2434 }, { -239, -255, -6850, -886 }, { -2112, -1490, -6291, -2689 }, { -1544, -4579, -5198, -1261 }, { -2771, -4014, -5520, 683 }, { -1635, -2829, -5512, 1214 }, { -958, -2582, -4823, 2360 }, { -2077, -4566, -4642, 365 }, { -3112, -4214, -5960, -823 }, { -2467, -2510, -4858, 1467 }, { -1561, -3399, -5822, 211 }, { -775, -1081, -4424, 2636 }, { -1263, 25, -6378, -1392 }, { -3476, -366, -5417, -1393 }, { -3176, -1476, -4149, 1466 }, { -2479, 518, -4448, -257 }, { -2992, 158, -4660, -1279 }, { -1320, -3872, -4479, 1147 }, { -1475, -312, -5318, 539 }, { -3527, -1679, -5860, -1681 }, { -3397, -3438, -5593, 1866 }, { -4089, -2439, -4763, 1275 }, { -748, -4513, -4687, -48 }, { -2166, -4531, -4691, -2856 }, { -2385, -853, -6035, -627 }, { -1194, -4091, -4472, -1963 }, { -682, -3234, -4084, -3033 }, { -3255, -5015, -5328, -12 }, { -2313, -3436, -4601, -155 }, { -2792, -1038, -6947, -2019 }, { -1244, -1526, -5771, -1882 }, { -4679, -3731, -5506, 283 }, { -3062, -66, -3558, -758 }, { -4895, -1187, 4751, 3728 }, { -7600, -2752, 3320, 4613 }, { -5703, -2975, 3944, 2659 }, { -4972, -1257, -246, 2952 }, { -4221, -2487, 1702, 4295 }, { -2900, -1529, 2458, 4935 }, { -5061, 407, 2416, 4050 }, { -6931, -3478, 2761, 2213 }, { -6037, -3921, 3192, 1866 }, { -6113, -811, 2407, 3782 }, { -5878, -1716, 1207, 3478 }, { -5953, -2853, 2207, 2712 }, { -6807, -3223, 2749, 3595 }, { -3272, -3157, 1389, 3788 }, { -5368, -1904, 1980, 5077 }, { -7235, -1398, 3075, 4548 }, { -4765, -3487, 2755, 2796 }, { -7658, -4435, 2694, 2582 }, { -6997, -4282, 456, 3832 }, { -5563, -3115, -63, 3713 }, { -4244, -4220, 1450, 2767 }, { -3801, -2194, 190, 4303 }, { -5458, -4119, 1958, 2274 }, { -7300, -3469, 3514, 3193 }, { -4594, -2067, 775, 4752 }, { -3389, -1654, 1464, 5412 }, { -4845, -3483, 964, 3437 }, { -6007, -2818, 1666, 4659 }, { -8709, -5007, 1757, 3287 }, { -5833, -4389, 1025, 3171 }, { -5788, -1780, 3944, 3661 }, { -4430, -920, 1938, 4753 }, { -7066, -1857, 4591, 4538 }, { -3549, -513, 1427, 5317 }, { -7517, -1220, 2883, 3049 }, { -7605, -2687, 1874, 2735 }, { -8718, -4035, 2676, 3730 }, { -7990, -3907, 1185, 2607 }, { -6058, -1744, 3349, 5157 }, { -5954, 565, 3161, 3250 }, { -6478, -612, 1930, 2271 }, { -6535, -1445, -2, 1618 }, { -8963, -4151, 1192, 4044 }, { -7227, -3570, 1600, 4234 }, { -4674, 79, 595, 3015 }, { -3974, 430, 2727, 5137 }, { -5299, 9, 3714, 4779 }, { -6779, -2699, -8, 2436 }, { -7016, -1145, 1293, 2310 }, { -6955, -3312, 1534, 1801 }, { -4025, 740, 1850, 4054 }, { -9589, -3460, 4154, 5270 }, { -4404, -1181, 4298, 5173 }, { -7356, -4583, -18, 2644 }, { -6516, -1235, 4439, 6234 }, { -3453, -301, 4344, 4464 }, { -4643, 1530, 3315, 4340 }, { -4575, -2557, 3754, 3682 }, { -3643, -3501, 2051, 2997 }, { -5412, -2475, 2301, 1579 }, { -5846, 259, 1360, 2348 }, { -5258, -1358, 1050, 838 }, { -5542, -219, 6377, 5750 }, { -5713, -2952, 922, 899 }, { -2049, -1135, 5206, 1033 }, { -1693, -1886, 4835, -106 }, { -2344, -3504, 4232, -13 }, { -2475, -2334, 5043, 1126 }, { -787, -2549, 3880, 2138 }, { -3159, -2341, 4830, 2887 }, { -1780, -1009, 6240, 2061 }, { -4327, -3363, 2818, 886 }, { -3376, -2743, 4104, 207 }, { -3250, -4640, 2718, 1498 }, { -382, -1075, 4382, 3460 }, { -2416, -4168, 3530, 816 }, { -1756, -2708, 4861, 622 }, { -1879, -2097, 5156, 2889 }, { -2496, -2418, 3722, 2671 }, { -2717, -3252, 3341, 1944 }, { -4063, -4091, 3306, 267 }, { -3549, -3808, 3747, 842 }, { -2635, 546, 5794, 1894 }, { -1857, -1121, 4383, 3964 }, { -2226, -2166, 3489, 3678 }, { -3492, -660, 5323, 1063 }, { -3033, -3130, 4382, 1828 }, { -2703, -625, 6369, 2851 }, { -1656, -2842, 4584, -528 }, { -4781, -2622, 4390, 2097 }, { -413, -2045, 5081, 3035 }, { -3810, -2662, 4532, 1095 }, { -3144, -1858, 5215, 1880 }, { -3562, -1795, 4928, 670 }, { -4800, -1509, 5189, 1859 }, { -1085, -3832, 4169, 900 }, { -1969, -3270, 2857, 2878 }, { -4267, -4140, 3176, 1805 }, { -5145, -3727, 3524, 1168 }, { -1346, -1876, 5501, 1748 }, { -4998, -2945, 3699, 338 }, { -3458, -3096, 3406, -635 }, { -1751, -3209, 3508, 395 }, { -2507, 170, 5987, 705 }, { -3756, -1072, 5647, 3536 }, { -2870, -1439, 5026, 3212 }, { -3913, -3225, 3669, 2144 }, { -3739, 226, 5747, 764 }, { -2052, -820, 5266, 3093 }, { -3214, -3820, 2409, 2391 }, { -4398, -2588, 3501, -218 }, { -4484, -1763, 4180, -198 }, { -3368, -1525, 4362, -134 }, { -2407, 224, 4905, 3533 }, { -1369, -2937, 4728, 1788 }, { -4848, -1707, 4159, 851 }, { -3454, -1749, 4281, 3230 }, { -1990, -3853, 3487, 1735 }, { -3117, 92, 6155, 4075 }, { -2676, -2472, 4078, -589 }, { -1547, -2012, 2626, 1835 }, { -4275, -588, 4824, 725 }, { -601, -2249, 3736, 3548 }, { -4060, -61, 5333, 3097 }, { -4303, 7, 6551, 3054 }, { -5003, -1029, 5786, 3319 }, { -2810, -728, 5392, 199 }, { -1232, -200, 5228, 3121 }, { 2621, 165, -6255, 298 }, { 3669, 537, -6844, 1564 }, { 1598, -1190, -6235, 2523 }, { 2164, -32, -6894, 1383 }, { 853, -1597, -6069, 1449 }, { 1377, -1661, -5266, 108 }, { 2660, 48, -5172, -517 }, { 1903, -391, -5677, 1010 }, { 3792, 206, -5274, -11 }, { 1239, 2776, -2929, 2721 }, { 4071, 149, -7259, 3125 }, { 1436, -480, -6156, -196 }, { 1373, -1960, -5005, 3122 }, { 3413, -1271, -5176, 3283 }, { 3060, -68, -6495, 2238 }, { 2700, -2075, -4681, 91 }, { 2928, -1728, -5168, 1858 }, { 4424, 828, -4471, 88 }, { 2672, -2604, -4038, 2753 }, { 5223, -123, -6749, 2295 }, { 4237, -420, -5538, 1353 }, { 4744, -1281, -4097, 4708 }, { 1103, -2764, -4751, 2024 }, { 3747, -1913, -3911, 3960 }, { 2470, -1416, -5542, 615 }, { 4847, -1354, -5334, 1733 }, { 5336, 88, -7593, 4007 }, { 2388, -2880, -4807, 1037 }, { 4495, 1391, -5685, -139 }, { 5253, 1637, -6450, 1533 }, { 1199, 795, -5515, 1261 }, { 1397, -1259, -4252, 3838 }, { 746, 70, -6640, 604 }, { 1584, 166, -4972, 3072 }, { 380, -999, -5397, 2267 }, { 2974, 1707, -3242, 5360 }, { 5202, -403, -5453, 2832 }, { 3718, -1731, -4760, 714 }, { 4150, -975, -4792, 61 }, { 2925, -818, -4841, 15 }, { 5301, 577, -4006, 3259 }, { 5265, 1986, -5679, 3028 }, { 3752, 1928, -4509, 3729 }, { 3278, 1925, -6370, 1247 }, { 5107, 1721, -4853, 3127 }, { 3279, 2982, -2515, 4005 }, { 4622, 668, -6204, 759 }, { 6034, 317, -5763, 4818 }, { -558, 57, -3785, 2817 }, { 4476, 1616, -3965, 4536 }, { 5953, 2056, -8215, 2715 }, { 4387, 2613, -7463, 868 }, { 5834, 1088, -4736, 4924 }, { 6473, -856, -6991, 4172 }, { 4959, -293, -5162, 76 }, { 2731, -843, -6119, 3847 }, { 3245, 1202, -6833, 616 }, { 2553, 1383, -3829, 3859 }, { 4332, 2099, -3480, 3622 }, { 2110, 2683, -2728, 3990 }, { 876, 1167, -3290, 3466 }, { 3991, 1709, -2410, 4077 }, { 5105, 939, -2584, 3256 }, { 4719, 688, -1566, 3040 }, { -3632, 4335, 1266, -3303 }, { -4956, 3207, 1312, -2806 }, { -4669, 2627, 2663, -2435 }, { -4282, 3708, 2303, -3038 }, { -4536, 2297, -175, -3350 }, { -5234, 2503, -139, -880 }, { -3978, 1512, 1092, -3619 }, { -4519, 4649, 1363, -2455 }, { -5118, 3132, 1961, -1577 }, { -5196, 3379, -182, -1378 }, { -6420, 4486, 2397, -1993 }, { -5030, 5046, 1292, -1118 }, { -4559, 2573, -927, -1406 }, { -3501, 3730, 691, -4930 }, { -4364, 2758, 1007, -3909 }, { -4026, 2839, -1559, -2340 }, { -5037, 4053, 836, -1571 }, { -4727, 5136, 1110, -3588 }, { -5245, 2799, -999, -2164 }, { -4954, 1501, 422, -3963 }, { -5994, 2726, 1462, -2833 }, { -5621, 5159, 2038, -2512 }, { -4991, 2291, 1917, -3151 }, { -5469, 4382, -148, -2978 }, { -5858, 1983, 807, -2720 }, { -4709, 3556, 952, -467 }, { -2489, 2362, 1714, -4230 }, { -4717, 5004, -1180, -3672 }, { -5914, 3653, 1359, -1317 }, { -5506, 2995, 780, -1059 }, { -5287, 3945, 2480, -2293 }, { -3849, 4358, 322, -1770 }, { -3911, 3570, 252, -3185 }, { -3660, 5128, 158, -3719 }, { -4599, 3277, -503, -2727 }, { -3673, 3760, -1252, -3339 }, { -5161, 2337, 388, -1943 }, { -3529, 2216, 2156, -3080 }, { -4309, 4331, 1808, -1460 }, { -4782, 3820, 480, -2504 }, { -4166, 3544, -378, -1567 }, { -5572, 2466, -418, -2909 }, { -6096, 2930, 119, -1878 }, { -5963, 3554, 1011, -2233 }, { -6433, 4335, 935, -2930 }, { -5004, 3314, -1352, -3430 }, { -6042, 3463, -1008, -3940 }, { -4671, 2214, -640, -5040 }, { -2795, 3759, 1412, -3803 }, { -3647, 4436, 729, -515 }, { -3594, 1033, 56, -4148 }, { -2908, 3027, 2889, -3485 }, { -3338, 2234, 313, -4285 }, { -3825, 4497, -561, -2634 }, { -6167, 3012, -48, -3149 }, { -4828, 3515, -969, -4475 }, { -5789, 2757, -539, -4173 }, { -2452, 3067, 564, -4249 }, { -4921, 1358, 1331, -2889 }, { -3127, 4239, -1045, -1523 }, { -4780, 2326, -1118, -3446 }, { -3908, 5546, 152, -2622 }, { -6972, 2976, 337, -2809 }, { -4839, 4613, -35, -4077 }, { -1408, 4822, -1149, -4997 }, { -981, 4979, -912, -6304 }, { -2098, 5689, -888, -2878 }, { -3343, 4814, -657, -4434 }, { -2461, 3601, -967, -4869 }, { -2652, 3944, 87, -5520 }, { -1104, 6076, 174, -6407 }, { 355, 5370, -1721, -5869 }, { 1242, 4497, -1107, -5091 }, { -89, 4002, -1491, -5182 }, { 1059, 5693, -1591, -4905 }, { 1323, 4682, -2078, -4768 }, { 818, 3996, -549, -5468 }, { -287, 4529, 929, -5543 }, { -919, 5519, -2791, -2844 }, { -1407, 5679, -3289, -3974 }, { -189, 6530, -3547, -4002 }, { -900, 7039, -3371, -4855 }, { -2983, 7211, -363, -4835 }, { -814, 6503, -104, -5106 }, { -2386, 6896, 809, -4919 }, { 845, 4492, 352, -6621 }, { -1998, 7237, -1646, -4231 }, { -3380, 6251, 471, -4577 }, { -1908, 7059, 84, -5726 }, { -340, 6346, -803, -6265 }, { -2279, 5834, -47, -4633 }, { -1532, 5286, -1748, -1901 }, { -2757, 6188, -453, -3415 }, { -1255, 6405, -2043, -6357 }, { 918, 5581, -121, -5667 }, { 1840, 5336, -821, -5034 }, { -2475, 4992, -1825, -3104 }, { -2413, 5606, -1789, -4298 }, { 132, 5128, -2389, -4442 }, { 223, 6400, -2653, -4742 }, { -673, 5012, 680, -4582 }, { -1657, 6624, -349, -3596 }, { -755, 6289, -1860, -3978 }, { -572, 6894, -1946, -5207 }, { -1141, 4756, -2665, -5586 }, { -1073, 4269, -431, -4030 }, { 186, 5761, 916, -5868 }, { -1907, 4836, 1017, -5106 }, { -963, 3363, -1248, -6348 }, { -3262, 4774, -1818, -5858 }, { 847, 3812, -2538, -4302 }, { -1223, 5903, 1360, -5479 }, { -1094, 6923, -1244, -2381 }, { 267, 6276, -709, -2846 }, { -157, 5840, 1124, -4266 }, { 889, 3206, -910, -5305 }, { -1736, 3344, 582, -4838 }, { -2357, 5676, -2695, -6277 }, { -1916, 6901, -986, -5397 }, { -3062, 6028, -695, -5687 }, { 1836, 3566, -1357, -5226 }, { -2176, 4938, 646, -3872 }, { -2199, 3055, -208, -6124 }, { -236, 3032, -821, -5325 }, { -3989, 7277, -565, -3899 }, { -595, 4362, 74, -5975 }, { 684, 5874, -841, -4424 }, { -2731, 6305, -2389, -5465 }, { -5775, 1325, -56, -2528 }, { -7029, -534, -1890, -3278 }, { -5798, -15, -2734, -2210 }, { -5504, -1198, -353, -3659 }, { -5079, 960, -894, -4336 }, { -6073, -36, -133, -3014 }, { -5782, -259, -1025, -3986 }, { -6843, 1262, -807, -1639 }, { -5263, -918, -3290, -579 }, { -4840, 461, -2158, -533 }, { -6014, -50, -620, 504 }, { -5843, 241, -1359, -282 }, { -5898, 577, 769, -3271 }, { -6833, -946, -466, -3347 }, { -6026, 1459, -512, -729 }, { -7361, 747, -388, -1110 }, { -6391, 2142, -1160, -2513 }, { -6995, 304, 498, -2673 }, { -6757, 679, -386, -433 }, { -5222, 1688, -1093, -1032 }, { -5019, 575, 184, -3627 }, { -4237, 628, -3507, -1243 }, { -7479, -456, -1722, -1486 }, { -6464, 713, -1273, -1153 }, { -6255, 1682, -606, -3607 }, { -7033, 1497, -71, -1955 }, { -6694, 1556, -1721, -3214 }, { -6114, -356, 813, -2575 }, { -5308, 632, -1851, -1636 }, { -5742, -911, -1733, 383 }, { -6083, -387, -2313, -879 }, { -6535, -530, -1505, -2083 }, { -4896, 1223, -2750, -1816 }, { -6392, -463, -3247, -2093 }, { -5373, 1264, -2706, -3042 }, { -3894, -1390, -1020, -891 }, { -6179, 1168, -1966, -1922 }, { -5162, 1668, -1617, -1916 }, { -6453, 920, -1169, -2432 }, { -6130, 2005, -536, -1519 }, { -6552, -98, -518, -1938 }, { -7528, 355, -1101, -1772 }, { -5745, 610, -247, -1360 }, { -7003, 177, -2064, -1958 }, { -6956, -570, -2220, -4225 }, { -7830, 791, -1394, -2774 }, { -7634, 480, -3171, -4224 }, { -7913, 1154, -350, -2381 }, { -5063, 1704, -1804, -2977 }, { -4887, -524, -2703, 188 }, { -5551, 406, -1620, -3063 }, { -7109, 1342, 381, -3021 }, { -6846, 631, -458, -3398 }, { -4606, -605, 11, -3930 }, { -8134, -225, -1738, -2648 }, { -7043, 402, -2734, -3059 }, { -7417, 1825, -2545, -4389 }, { -6971, -236, -1031, -665 }, { -5752, 2111, -1632, -3808 }, { -7660, -78, -624, -3135 }, { -6358, 619, -1951, -3911 }, { -8134, 408, -1935, -3695 }, { -6335, 1911, -2368, -4505 }, { -7116, 2163, -344, -2753 }, { 2357, 4488, 2220, -5682 }, { 1385, 3206, 2300, -5305 }, { 1419, 2557, 5203, -3516 }, { 262, 4315, 3920, -1847 }, { 3316, 3187, 1612, -5609 }, { 1729, 2350, 1673, -6068 }, { 1603, 6126, 1467, -2839 }, { -1339, 3316, 3691, -3530 }, { -563, 4618, 3180, -4548 }, { 463, 4624, 3111, -5614 }, { 1246, 5455, 3356, -5720 }, { 480, 2149, 5422, -2893 }, { 1768, 4827, 913, -5579 }, { -149, 5381, 4366, -3297 }, { 985, 3672, 2644, -92 }, { -258, 2911, 5817, -2213 }, { 3428, 3289, 3351, -3541 }, { -666, 3295, 4727, -2869 }, { 35, 6641, 4160, -4052 }, { 623, 6787, 3156, -4560 }, { 2654, 4360, 4676, -4632 }, { 1386, 5246, 4834, -4497 }, { 3488, 4574, 3856, -5946 }, { 383, 4481, 4168, -4110 }, { 1753, 3652, 4288, -3326 }, { 1344, 4905, 2508, -4660 }, { 1580, 4106, 3104, -2224 }, { 2027, 5038, 1683, -1554 }, { 446, 3699, 5872, -3013 }, { 4637, 4087, 3578, -5018 }, { 2629, 3560, 5331, -4900 }, { 1527, 6674, 2523, -4131 }, { -1437, 2804, 2528, -4464 }, { -229, 3355, 2016, -5537 }, { 3666, 3418, 4374, -4581 }, { 1192, 3799, 923, -6596 }, { 2040, 2956, 448, -5322 }, { 2468, 5768, 4029, -5869 }, { 3438, 6516, 3529, -6667 }, { 2737, 5495, 680, -5535 }, { 3896, 5727, 1801, -4958 }, { 4988, 4957, 3592, -6518 }, { -542, 4416, 5794, -2787 }, { 4136, 4354, 2064, -4696 }, { 3067, 5936, 1207, -3396 }, { 2789, 4966, 2405, -3854 }, { 1731, 3270, 3251, -1063 }, { 1767, 5537, 2084, -2349 }, { 465, 3116, 4532, -837 }, { 1499, 2627, 4610, -2212 }, { 122, 3095, 3642, -3552 }, { 2542, 2866, 2705, -6402 }, { 3134, 4323, 698, -4785 }, { 731, 1859, 3112, -5242 }, { 2553, 2980, 3241, -4846 }, { 1329, 5310, 1607, -6624 }, { 2468, 1858, 3476, -1034 }, { -172, 4996, 2000, -5562 }, { 2621, 4220, 1574, -3386 }, { -333, 1832, 3362, -4117 }, { 2169, 6762, 3065, -6225 }, { 2844, 5528, 3223, -4765 }, { 526, 5175, 1644, -4267 }, { 2922, 4426, 2414, -2610 }, { 452, 1399, -4516, -2636 }, { 2872, 1720, -4667, -1435 }, { 1279, 702, -5424, -1984 }, { 2187, 870, -5021, -1341 }, { 583, -144, -4628, -2464 }, { 3, 2237, -5284, -2827 }, { -19, 1005, -5460, -1819 }, { 2897, 2084, -5885, -515 }, { -400, 3370, -5527, -2947 }, { 1505, 2593, -5518, -1802 }, { 1341, 4534, -5094, -1899 }, { 3241, 3670, -5493, -1252 }, { -1287, 921, -5994, -1675 }, { 627, 408, -6652, -364 }, { -260, 1127, -4849, -3247 }, { 371, 3400, -5976, -2285 }, { 1533, 1566, -6373, -610 }, { 2462, 4274, -6184, -1254 }, { 1782, 3363, -6222, -1381 }, { 572, 4650, -5673, -2754 }, { 2674, 3414, -4460, -2154 }, { 3614, 3820, -6883, -398 }, { 1136, -1, -5511, -1112 }, { -1773, 1137, -5647, -2377 }, { -753, 2104, -6085, -2565 }, { -204, 3025, -4731, -1418 }, { -1486, 1438, -4380, -216 }, { 302, 858, -5786, -264 }, { 3486, 1495, -5234, -783 }, { 888, 2327, -3423, -3720 }, { -259, 772, -6596, -1311 }, { -1197, 2073, -5174, -1826 }, { 1500, 3470, -4462, -2645 }, { 3072, 1960, -3277, -2264 }, { 1841, 952, -4324, -2340 }, { 1994, 2200, -3940, -2923 }, { -1782, 1699, -4667, -1075 }, { -1464, 2906, -3468, -375 }, { 366, 2380, -3747, 1467 }, { -545, 1645, -4619, 376 }, { 1724, 2350, -2374, -3512 }, { 3184, 2628, -2996, -3275 }, { 734, 2010, -6239, -1479 }, { 524, 3756, -4496, -3263 }, { 1492, 3570, -3494, -3600 }, { -932, 618, -5389, -2894 }, { -133, 2161, -4083, -3267 }, { 786, 774, -3279, -3731 }, { 1078, 803, -3843, -3007 }, { -332, 3405, -3347, 40 }, { -17, 6, -4005, -3690 }, { -189, 4372, -4488, -2561 }, { -450, 3846, -3790, -1370 }, { 362, 2212, -5272, -15 }, { -1529, 791, -6802, -2296 }, { 2145, 4241, -4474, 376 }, { 1813, 2426, -2932, -2726 }, { -542, 4557, -3140, -1080 }, { 1192, 3784, -4371, -20 }, { 2784, 5188, -6399, -1394 }, { 431, 4561, -3673, -1398 }, { 1382, 3096, -4083, 1253 }, { 1209, 4224, -2930, 1500 }, { 2798, 2684, -6676, -606 }, { -2396, 1510, -5381, -2713 }, { -2625, 2542, -4032, -2880 }, { -1231, 3967, -4098, -2886 }, { -1393, 2374, -3862, -4525 }, { -2495, 1665, -1637, -5445 }, { -3854, 1759, -1750, -4944 }, { -2373, 1668, -2856, -6251 }, { -2668, 1981, -886, -4557 }, { -2927, 4427, -3451, -6172 }, { -1925, 2596, -4696, -2527 }, { -3202, 2847, -3928, -5896 }, { -3332, 1665, -5025, -3412 }, { -3212, 3115, -4155, -4062 }, { -1013, 3205, -5133, -3751 }, { -2022, 4595, -3947, -5611 }, { -3556, 1755, -3715, -2300 }, { -1784, 4114, -2723, -1773 }, { -3586, 4081, -2733, -4942 }, { -1608, 3685, -4154, -4573 }, { -3368, 4042, -4452, -6227 }, { -1407, 3881, -5729, -3719 }, { -2751, 3281, -5077, -4999 }, { -3791, 2410, -4906, -5288 }, { -730, 2303, -4217, -3755 }, { -1812, 2311, -5492, -3709 }, { -610, 4336, -3915, -3783 }, { -2841, 4337, -4278, -4430 }, { -1662, 4666, -4661, -3964 }, { -589, 5209, -4923, -3682 }, { -4155, 2234, -4076, -4218 }, { -3951, 2770, -2665, -2805 }, { -2302, 3228, -3717, -1908 }, { -3129, 4373, -2264, -2851 }, { -447, 1363, -3578, -4323 }, { -2648, 4237, -3159, -3071 }, { -4072, 3241, -3541, -4605 }, { -4507, 3458, -2339, -3838 }, { -1646, 997, -4926, -3970 }, { -3025, 1614, -3940, -1242 }, { -1337, 1756, -3163, -5529 }, { -3203, 1865, -3282, -4354 }, { -1646, 2118, -2203, -6018 }, { 174, 1871, -2707, -4639 }, { -2607, 1485, -4778, -4750 }, { -2199, 3991, -3134, -4879 }, { -2962, 3323, -2816, -2419 }, { -5286, 2495, -4548, -5395 }, { -2810, 3710, -2274, -4211 }, { -330, 3006, -2993, -4678 }, { -1187, 2411, -2743, -5196 }, { -664, 4033, -3101, -5641 }, { -1458, 3602, -2816, -5371 }, { -4116, 4923, -3321, -5630 }, { -4165, 2528, -2592, -4798 }, { -2759, 3080, -2333, -5719 }, { -5157, 3011, -5526, -6348 }, { -3095, 2126, -5881, -4234 }, { -4377, 3849, -3600, -6099 }, { -1994, 4947, -5235, -4753 }, { -1067, 600, -3258, -5133 }, { -4992, 3302, -2208, -5051 }, { -3377, 2981, -1655, -4815 }, { -3325, 2446, -1787, -6116 }, { -2341, 2737, -3240, -6347 }, { -2258, -3732, 3710, -1235 }, { -1558, -3849, 2694, -3012 }, { -599, -4837, 3050, -2951 }, { -2246, -5433, 2798, -1910 }, { -2255, -4989, 3260, 270 }, { -3026, -5353, 2693, -1036 }, { -1151, -6097, 1097, -3782 }, { -3391, -6012, 2130, -1303 }, { -2850, -4422, 3375, -480 }, { -1138, -3779, 1491, -4162 }, { -551, -3892, 3787, -2082 }, { -3221, -3676, 3144, -1202 }, { -3023, -5196, 2650, 605 }, { -1756, -5729, 2646, 321 }, { -2693, -4409, 494, -4797 }, { -1913, -4573, 3372, -1730 }, { -1277, -3604, 4061, -993 }, { -420, -4993, 1351, -4796 }, { -3052, -5333, 1435, -1242 }, { -602, -5034, 3869, -1141 }, { -2436, -4680, 1665, -3019 }, { -2657, -3658, 1459, -3391 }, { -1220, -6246, 2749, -525 }, { -3838, -4844, 2265, -1735 }, { -1247, -5679, 3356, -1417 }, { -917, -5448, 3342, 105 }, { -1756, -6839, 2276, -2350 }, { -412, -5206, 1764, -3539 }, { -1439, -6915, 1442, -3750 }, { -1381, -4439, 3863, -282 }, { -3482, -4953, 2726, -336 }, { -1376, -5931, 1714, -1987 }, { -1716, -4405, 2608, 105 }, { -1590, -5191, 2652, -2704 }, { -2149, -6442, 2453, -1263 }, { -3426, -3832, 2334, -1829 }, { -2747, -5948, 2362, -173 }, { -2435, -3267, 2966, -1710 }, { -3979, -4282, 2705, -775 }, { -356, -4238, 2544, -4343 }, { -1363, -6471, 2817, -1836 }, { -2878, -5117, 218, -3149 }, { -3539, -5196, 1710, -2356 }, { -2888, -4537, 2746, -1701 }, { -1870, -4439, 1496, -4121 }, { -1486, -3388, 3349, -2145 }, { -3333, -4138, 1467, -2876 }, { -345, -5340, 1012, -1190 }, { -1672, -4992, 2289, -1029 }, { -2146, -5528, 3038, -635 }, { -316, -3656, 3426, -3152 }, { -2695, -5812, 2336, -2050 }, { -2067, -6052, 737, -3258 }, { -2664, -4205, -350, -1266 }, { -617, -5406, 80, -4853 }, { -2418, -3825, 1853, -1326 }, { -1961, -4339, 583, -4315 }, { -1495, -5141, -133, -5205 }, { -3208, -6440, 1691, -2069 }, { -2632, -3633, 2325, -2761 }, { -2624, -5670, 1252, -3676 }, { -3687, -5608, 687, -2833 }, { -3320, -5707, 16, -3877 }, { -2738, -6112, 84, -5135 }, { 2277, -5661, 3076, 843 }, { 1555, -5769, 2821, -5236 }, { 536, -6381, 603, -4910 }, { 734, -4609, 3314, -4092 }, { 1836, -4547, 3267, -4322 }, { -13, -5976, 3752, -1607 }, { 1423, -6318, 2336, 398 }, { 365, -7779, 1498, -534 }, { 2104, -8366, 2946, -1345 }, { 143, -5545, 1898, -3756 }, { 655, -6852, 1430, 148 }, { 4, -6653, 2397, -59 }, { 2346, -5996, 4562, -934 }, { 1229, -7104, 2963, -598 }, { -528, -7048, 2887, -1790 }, { 1451, -6857, 3900, -1637 }, { 554, -6018, 3336, 9 }, { 3278, -5758, 4034, 129 }, { 3541, -7145, 4905, -1575 }, { 2339, -6907, 3464, -301 }, { 2775, -7301, 1667, -3894 }, { 539, -7887, 991, -4156 }, { 2115, -7421, 3131, -3075 }, { 2803, -8546, 2564, -5836 }, { 2869, -5833, 1620, -4561 }, { 2591, -7281, 3215, -4719 }, { -1228, -8477, 706, -4782 }, { 1967, -5243, 4813, -1940 }, { 701, -7010, 2273, -3893 }, { 915, -8470, 1918, -5620 }, { -94, -6715, 156, -3873 }, { 1074, -5607, 4389, -1017 }, { 2739, -6551, 1227, -3521 }, { 725, -7835, 2701, -1291 }, { -493, -7475, 2263, -1075 }, { -412, -6508, 2984, -744 }, { 665, -5451, 3725, -2692 }, { 1499, -8129, 3564, -2072 }, { 2870, -6333, 4487, -2108 }, { 706, -5007, 3911, -152 }, { -482, -8660, 1483, -2900 }, { 2481, -6596, 2518, -1715 }, { 1403, -6414, 1398, -5387 }, { 652, -6267, 583, -5942 }, { 694, -7540, 646, -6272 }, { 2275, -7614, 256, -5015 }, { 1416, -9727, 1900, -3153 }, { 2760, -6433, 3875, -3771 }, { 2325, -11196, 2182, -5155 }, { 1223, -11061, 1377, -5097 }, { 108, -10603, 307, -4952 }, { -118, -8268, 1650, -1572 }, { 1839, -7943, 1755, -612 }, { 2501, -9056, 981, -2969 }, { 2902, -8476, 1491, -5780 }, { 1995, -11175, 1585, -3643 }, { 696, -8212, 828, -2474 }, { 1526, -8649, 1380, -1210 }, { 461, -7253, 3222, -2229 }, { 2966, -8641, 4121, -3271 }, { 833, -6039, 2361, -1086 }, { 3565, -7312, 1980, -5427 }, { 2850, -8671, 3760, -1846 }, { 2643, -7281, 2163, -173 }, { 3463, -3706, -3132, -923 }, { 1315, -3825, -3443, 2 }, { 2594, -4083, -3815, 670 }, { 1826, -4291, -2741, -155 }, { 868, -3749, -4175, -298 }, { 2008, -4237, -3897, -517 }, { 1242, -3493, -4335, -1335 }, { -88, -4142, -3390, -1529 }, { 2176, -3488, -3822, -975 }, { 1706, -5188, -3415, -637 }, { 2717, -6159, -2333, -882 }, { 1276, -3978, -4361, 537 }, { 2471, -5556, -2866, -208 }, { 799, -4673, -4086, 56 }, { 1901, -4786, -3533, 270 }, { 3036, -3902, -3606, -333 }, { 2249, -3317, -4319, -144 }, { 2594, -4207, -2105, -2930 }, { 4008, -4774, -2626, -902 }, { 1038, -3659, -3496, -2454 }, { 2725, -3597, -3298, -1535 }, { 1662, -5803, -2813, 175 }, { 705, -3757, -3441, -1484 }, { 1860, -5987, -2821, -886 }, { 3786, -4918, -2199, -1929 }, { 3683, -4235, -2547, -1287 }, { 2531, -4896, -2956, -1593 }, { 1005, -5585, -3324, -180 }, { 1625, -5229, -1756, -3642 }, { 1494, -5041, -2989, -2685 }, { 2718, -4655, -3224, -867 }, { 2374, -6640, -1745, -2975 }, { 2133, -6436, -2477, -1499 }, { 1833, -4418, -3523, -1512 }, { 1128, -4910, -2658, -1106 }, { 689, -4777, -2831, -2085 }, { 3593, -5280, -2627, -315 }, { 3264, -3771, -2673, -1861 }, { 3202, -5602, -2409, 402 }, { 552, -4618, -2221, -3002 }, { 3095, -5356, -2666, -1083 }, { 3401, -4609, -3146, 45 }, { 3051, -4662, -2192, -2232 }, { 2798, -5552, -2462, -1941 }, { 2354, -5815, -2223, -2619 }, { 192, -3708, -2807, -2658 }, { 1886, -4226, -1862, -3529 }, { 2526, -3976, -2819, -2332 }, { 1577, -3870, -2711, -2806 }, { 1288, -5588, -3382, -1403 }, { 2711, -5399, -1564, -3253 }, { 1459, -5492, -2222, -322 }, { 2823, -5091, -2886, 776 }, { 3559, -5821, -2109, -1360 }, { 1587, -6331, -2760, -1909 }, { 2139, -5213, -2874, -2120 }, { 1318, -4337, -3695, -2098 }, { 821, -4471, -1849, -565 }, { 3329, -4782, -1725, -89 }, { 582, -4914, -4105, -1119 }, { 417, -4144, -4072, -2529 }, { -199, -3803, -2765, -4042 }, { 2731, -4283, -2143, 1 }, { 2911, -6187, -1951, -2116 }, { 1573, -6094, -493, -2838 }, { 2081, -6927, -864, -3211 }, { 1058, -7826, 79, -364 }, { 3147, -5570, -684, -978 }, { 3572, -5856, 1060, 1824 }, { 1143, -6702, -1478, 338 }, { 2341, -7220, -88, 260 }, { 3639, -6861, 668, 815 }, { 2227, -6268, -1706, 446 }, { 3390, -6082, -353, 1302 }, { 1123, -7556, -1237, -430 }, { 1729, -7742, 729, -218 }, { 1457, -6774, 587, 579 }, { 505, -6919, -569, 371 }, { 1106, -7245, 78, 158 }, { 2755, -6745, -1122, 338 }, { 3069, -6040, -1415, 986 }, { 2174, -7064, -1430, -283 }, { 1390, -8626, -446, -3031 }, { 3534, -6890, -431, 547 }, { 2267, -9618, 475, -2994 }, { 3672, -7673, 75, -115 }, { 2131, -7560, -1206, -750 }, { 2972, -7477, -685, -262 }, { 1604, -6637, -672, 699 }, { 1666, -7577, -577, -240 }, { 1591, -6554, -2158, -94 }, { 2348, -6286, -353, 1123 }, { 2017, -8810, -412, -1805 }, { 2892, -6713, -1765, -554 }, { 2500, -6828, -1995, -1197 }, { 3877, -6639, -224, -1655 }, { 2392, -7872, -91, -333 }, { 3562, -7370, -532, -2836 }, { 2552, -7614, 164, -1805 }, { 990, -6104, 218, 438 }, { 910, -7861, 312, -1195 }, { 1472, -6327, 372, -640 }, { 1576, -7143, -1983, -843 }, { 422, -7625, -457, -278 }, { 1797, -8532, 405, -1011 }, { 1088, -7396, -238, -2277 }, { 3209, -6753, -1431, -2072 }, { 2617, -6839, 100, -2573 }, { 2575, -8573, -387, -3188 }, { 3618, -6971, -1190, -321 }, { 2205, -7361, -1695, -2008 }, { 2985, -6297, 1464, 1179 }, { 2804, -7310, 1053, 338 }, { 1362, -6074, -1163, -840 }, { 3336, -6325, -1794, 21 }, { 2836, -8109, 818, -329 }, { 2791, -5879, 560, 1546 }, { 2392, -6064, 135, 100 }, { 1838, -6194, 596, 1085 }, { 1926, -7515, -414, -4901 }, { 3225, -7298, -1202, -1189 }, { 3960, -7558, -659, -719 }, { 3442, -6647, -1692, -1095 }, { 3381, -6441, 262, -886 }, { 1431, -8150, -1186, -1406 }, { 340, -8498, -150, -899 }, { 3004, -8149, -260, -953 }, { 2749, -6611, 563, 873 }, { -6647, -1325, -4517, -4691 }, { -6005, -1657, -4089, -3797 }, { -3157, 588, -5213, -3068 }, { -3311, -1425, -6329, -3726 }, { -5866, -819, -3857, -2744 }, { -5001, -1799, -1075, -4621 }, { -5330, -2650, -2672, -4664 }, { -4930, -539, -2363, -4010 }, { -2984, 10, -3863, -5749 }, { -1055, -2106, -3713, -4267 }, { -5476, -502, -4279, -6504 }, { -5231, -1543, -5018, -6425 }, { -5134, -363, -3165, -5109 }, { -3953, -771, -4107, -6393 }, { -2159, -563, -3652, -5342 }, { -3888, -2321, -919, -5057 }, { -1236, -597, -4235, -4193 }, { -4053, 675, -3083, -6174 }, { -2793, -1089, -5396, -3460 }, { -3000, -44, -2209, -6575 }, { -3336, -1531, -4313, -5160 }, { -2127, 128, -4851, -3692 }, { -3321, 136, -2067, -5660 }, { -5215, 1404, -4374, -4356 }, { -2747, 400, -6340, -3691 }, { -3926, -599, -5361, -5006 }, { -2875, -2592, -5143, -4092 }, { -4991, -1958, -5322, -4891 }, { -4965, -1318, -6652, -5333 }, { -4920, -1691, -3388, -5561 }, { -3644, -3354, -2688, -5982 }, { -5076, -919, -4563, -2984 }, { -6114, 250, -3884, -3915 }, { -4014, 744, -3973, -1924 }, { -5543, -1041, -5557, -3847 }, { -4711, -1352, -5649, -2603 }, { -3362, 775, -5305, -4879 }, { -5001, 107, -3554, -2888 }, { -6258, -1651, -6356, -6566 }, { -4529, 407, -5003, -3865 }, { -5154, 550, -5278, -5465 }, { -4195, -467, -1894, -3129 }, { -5022, 1127, -3349, -3314 }, { -6075, 1250, -4313, -5641 }, { -2677, -2283, -2312, -5903 }, { -4113, 193, -1195, -4833 }, { -3940, -1048, -1389, -5079 }, { -3703, 917, -4043, -4451 }, { -3366, -4231, -1534, -5488 }, { -3326, -3583, -2091, -4903 }, { -5144, 1254, -2532, -4949 }, { -5982, -870, -2545, -4555 }, { -3925, -157, -5367, -2281 }, { -6419, -746, -5668, -4371 }, { -5787, 518, -7096, -5805 }, { -4258, 954, -6453, -4321 }, { -4771, -695, -4158, -1639 }, { -7078, -760, -5195, -5877 }, { -7348, 83, -4101, -4586 }, { -2430, 184, -2874, -1679 }, { -2284, -3943, -2924, -5034 }, { -1804, -1785, -3002, -4710 }, { -4399, -2772, -1815, -4637 }, { -6340, -2626, -2824, -5191 }, { -4998, -5168, -3480, 1905 }, { -3958, -5492, -1599, 1579 }, { -2471, -3755, -276, 3182 }, { -3033, -5779, -1063, 1554 }, { -2936, -4829, -1290, 2386 }, { -1835, -5073, -3051, 1299 }, { -1724, -3771, -3935, 2324 }, { -5070, -2550, -3692, 768 }, { -4326, -5333, -297, 1878 }, { -3472, -5619, -3094, 992 }, { -3027, -4384, -3038, 2265 }, { -3201, -5332, 67, 2200 }, { -1681, -4373, -1947, 2461 }, { -3221, -3329, -4238, 2564 }, { -1262, -2968, -2915, 3227 }, { -3419, -1878, -3373, 2110 }, { -2244, -5583, -2012, 1288 }, { -1971, -5266, -990, 1812 }, { -2975, -2778, -452, 4063 }, { -2198, -1165, -3298, 2965 }, { -4782, -4894, -4767, 664 }, { -6002, -3950, -2806, 2025 }, { -3142, -3162, -2859, 3295 }, { -3262, -3340, -4123, 1596 }, { -4014, -3918, -1955, 3361 }, { -1700, -3463, -1346, 3449 }, { -4245, -4445, -4743, 1644 }, { -4180, -3969, -401, 3281 }, { -2782, -5240, -4117, 1156 }, { -5744, -4040, -1439, 3470 }, { -5063, -4663, -323, 3172 }, { -4531, -3319, -844, 3988 }, { -6226, -5125, -2064, 2976 }, { -3115, -3267, -1531, 3898 }, { -4628, -4421, -2864, 2808 }, { -4559, -2989, -3442, 2024 }, { -1775, -4487, -656, 2477 }, { -2664, -1865, -1884, 4081 }, { -1828, -2575, -3894, 3378 }, { -6441, -3677, -2025, 1677 }, { -4141, -2156, -1191, 3474 }, { -4802, -1623, -1727, 2160 }, { -5474, -2745, -1475, 2498 }, { -3664, -1056, -1975, 2491 }, { -4672, -3062, -2235, 2933 }, { -4205, -5960, -2849, 1517 }, { -4995, -5708, -1739, 1805 }, { -4892, -6080, -4793, 872 }, { -4270, -4172, -4263, 2185 }, { -4687, -1470, -2905, 1023 }, { -6446, -5017, -3919, 1000 }, { -6046, -5538, -3943, 2006 }, { -6028, -3750, -3953, 771 }, { -5959, -4582, -5024, 824 }, { -5818, -2576, -2249, 1326 }, { -5659, -5345, -1119, 2500 }, { -3346, -4155, 606, 2749 }, { -5680, -4827, -2501, 1838 }, { -6193, -2543, -1295, 840 }, { -6871, -4925, -3512, 1801 }, { -5605, -1788, -1895, 779 }, { -3922, -5712, -4644, 510 }, { -4745, -3869, -4533, 99 }, { -2984, -4907, -399, 1497 }, { 1847, -478, 3061, -5812 }, { 4450, -1116, 3609, -6570 }, { 3139, 99, 3007, -5532 }, { 2590, -3782, 3138, -4770 }, { 1881, 1204, 5778, -3404 }, { 3631, 2060, 5566, -5038 }, { 3461, 1961, 5167, -3800 }, { 2947, 273, 4536, -4389 }, { 4453, -1730, 5788, -4370 }, { 4032, 1805, 2666, -4534 }, { 3487, -944, 2313, -6028 }, { 1313, 34, 4210, -4067 }, { 5632, -1502, 5825, -5855 }, { 7736, -547, 4879, -5476 }, { 4906, -1512, 4760, -5760 }, { 3843, 447, 1091, -4958 }, { 2982, -1135, 5442, -4386 }, { 3579, 271, 3031, -6770 }, { 3932, -211, 4688, -5507 }, { 4411, 1720, 2387, -5584 }, { 5379, -479, 4575, -6280 }, { 3613, -362, 2012, -4885 }, { 3744, -2013, 4493, -5073 }, { 5693, 109, 4379, -3362 }, { 5475, -621, 5317, -3985 }, { 6411, -673, 5708, -4752 }, { 4933, -796, 7262, -4290 }, { 2804, 444, 6276, -3655 }, { 4120, -517, 6078, -4531 }, { 5119, 841, 3486, -3910 }, { 4738, 1539, 3525, -2970 }, { 5086, 370, 5895, -5640 }, { 4235, 2716, 4589, -5044 }, { 3691, 682, 6199, -4700 }, { 6111, -570, 6271, -6528 }, { 2611, 1277, 3756, -4802 }, { 4395, 970, 3807, -5879 }, { 5225, 2299, 3242, -4333 }, { 5144, 1778, 4946, -5545 }, { 2989, -3016, 3247, -5495 }, { 2983, 920, 2071, -6059 }, { 5270, -903, 4434, -2350 }, { 6415, -585, 3970, -3554 }, { 3866, -197, 5216, -2884 }, { 3767, -1298, 6702, -3315 }, { 6299, 2620, 5284, -6824 }, { 6654, 646, 3653, -4927 }, { 4770, 3047, 5160, -6287 }, { 5364, 434, 2919, -5207 }, { 2998, 1344, 4801, -2456 }, { 3896, 1013, 3773, -1864 }, { 2115, 655, 2999, -6344 }, { 5170, -981, 2849, -4464 }, { 2735, -2159, 2717, -5776 }, { 2430, -1952, 4392, -4559 }, { 6143, -1180, 3659, -4746 }, { 4978, -1483, 1726, -4875 }, { 3486, -2383, 3306, -4301 }, { 1434, -1372, 4171, -4770 }, { 3354, -2627, 1525, -5093 }, { 6790, 2386, 3995, -5909 }, { 1475, -2674, 3451, -4204 }, { 1999, -3494, 3693, -5556 }, { 4764, -2848, 2856, -5589 }, { -3677, 5131, 2827, -2934 }, { -2844, 7078, 2852, -3580 }, { -3902, 6434, 4118, -1911 }, { -1769, 7530, 3492, -3541 }, { -1937, 5679, -447, -1127 }, { -2456, 4680, 4196, -2407 }, { -2778, 8241, 1698, -4288 }, { -2876, 6104, 5182, -2387 }, { -2802, 7341, 4463, -2938 }, { -1025, 6267, 4752, -3201 }, { -2349, 5413, 2041, -3794 }, { -2252, 8225, 2856, -4269 }, { -1465, 4967, 4976, -2500 }, { -636, 7565, 3517, -4233 }, { -1905, 5618, 3904, -2942 }, { -302, 6816, 3343, -3316 }, { -2210, 4156, 2817, -3511 }, { -717, 6568, 1863, -2951 }, { -3873, 5682, 2164, -575 }, { -2878, 5835, 440, -2597 }, { -3228, 7701, 2610, -2514 }, { -3608, 8888, 3377, -2468 }, { -2582, 9717, 2519, -3126 }, { -5238, 6202, 2866, -2831 }, { -3428, 7370, 3056, -335 }, { -1681, 8836, 1210, -2010 }, { -3276, 6724, 1156, -3930 }, { -894, 8149, 827, -1258 }, { -2965, 8631, 2549, -1320 }, { -3961, 6902, 3581, 55 }, { -1894, 7745, 1750, -841 }, { -821, 6844, 850, -676 }, { -608, 6948, -4, -1376 }, { 615, 6524, 1089, -1147 }, { -2972, 5668, 1091, -489 }, { -157, 4649, 2904, -413 }, { 673, 5121, 1498, -66 }, { -390, 5902, 1611, -245 }, { -2349, 5478, 4772, -1320 }, { 88, 6798, 1972, -1859 }, { -1213, 5120, 2991, 200 }, { -2347, 6040, 2839, 376 }, { -578, 5976, 3364, -1796 }, { -1391, 5872, 3002, -965 }, { -564, 4496, 3946, -1186 }, { -2299, 6386, 3135, -2176 }, { -2131, 5641, 2011, 1223 }, { -772, 5807, 1124, 895 }, { -2837, 6758, 2297, -740 }, { -3091, 6298, 1415, -2126 }, { -4197, 6036, 1843, -3022 }, { -41, 6459, 92, 344 }, { -2241, 6860, 2095, -4396 }, { -1931, 7088, 2117, -2135 }, { -2375, 4422, 1688, -3169 }, { -1742, 6674, 1538, -119 }, { -4818, 7749, 4192, -1577 }, { -2004, 5672, 193, -430 }, { -3825, 6042, 2128, -1898 }, { -1108, 8033, 2119, -3013 }, { -2370, 5453, 1721, 266 }, { -1570, 7134, 614, -2638 }, { -1519, 8752, 3503, -4330 }, { -2050, 3845, 2907, -1126 }, { 5085, 4412, -335, -1923 }, { 3618, 1423, -613, -4012 }, { 4481, 3729, 589, -4631 }, { 4270, 3216, -1763, -3168 }, { 4241, 1796, -1701, -2796 }, { 4787, 2338, -487, -3639 }, { 2915, 3429, -621, -4753 }, { 5175, 1660, -1265, -3223 }, { 4280, 4057, -684, -4079 }, { 4980, 4419, -1455, -2719 }, { 5436, 2464, 387, -4197 }, { 4507, 4018, 1121, -3314 }, { 6020, 2401, -413, -3201 }, { 4200, 3789, -333, -2813 }, { 5229, 2493, -1194, -1878 }, { 5851, 2695, -492, -2292 }, { 5743, 3288, -697, -1221 }, { 5692, 2612, 979, -2227 }, { 5085, 2067, 1046, -1214 }, { 3163, 2240, -2098, -3435 }, { 5228, 1898, 145, -2397 }, { 5860, 3976, -418, -2872 }, { 6008, 3399, 1027, -3506 }, { 4126, 2035, 1865, -893 }, { 5375, 3596, 511, -2362 }, { 1937, 1493, -852, -122 }, { 3473, 4849, 547, -2603 }, { 4631, 2977, 1141, -1768 }, { 6149, 3050, -71, -1886 }, { 4069, 4353, -289, -1429 }, { 2884, 1225, -1388, 365 }, { 5485, 2518, -235, -571 }, { 1216, 4375, 1443, 398 }, { 4988, 3106, 107, -1435 }, { 4511, 2801, 307, -444 }, { 3235, 4386, 327, -676 }, { 2055, 3708, 1657, -305 }, { 5839, 2374, 290, -1385 }, { 5110, 3305, 1936, -4206 }, { 6416, 2920, 338, -2736 }, { 3350, 2824, -1269, -3881 }, { 4840, 1815, 464, 186 }, { 2399, 3332, 238, 1238 }, { 3516, 1363, 1582, 688 }, { 3582, 1874, 154, -4770 }, { 3261, 2878, 886, 283 }, { 3877, 2658, -327, 884 }, { 4151, 3436, 2173, -2923 }, { 3592, 3674, 1281, -1295 }, { 4561, 3730, -1114, -1747 }, { 4595, 3625, -558, -575 }, { 2577, 2348, 2267, 120 }, { 5242, 3299, 32, -3412 }, { 4264, 3637, 709, -2320 }, { 6556, 3570, -838, -2472 }, { 5745, 4014, -940, -1973 }, { 5629, 4475, 477, -3328 }, { 5269, 3199, 1682, -3085 }, { 4432, 2416, 1145, -3299 }, { 4465, 2505, 2162, -2186 }, { 4643, 4941, -88, -2885 }, { 4568, 5231, 552, -3915 }, { 5667, 3075, -1406, -2963 }, { 5418, 5259, -771, -2818 }, { -256, -7875, 511, -471 }, { -1813, -7971, -424, -396 }, { -306, -7006, 862, 282 }, { -2306, -6422, -1440, 508 }, { -245, -6787, 375, -100 }, { -1309, -6065, -20, 779 }, { -1656, -6047, -641, 1307 }, { -1496, -6522, 964, 726 }, { -2291, -6588, -202, 795 }, { -762, -7522, 1454, -558 }, { -2270, -7004, -834, -580 }, { -1139, -7078, 259, 362 }, { -2535, -7568, -1040, 49 }, { -3786, -7280, 934, -476 }, { -3336, -6368, 606, 1056 }, { -3602, -6924, 52, 714 }, { -2278, -6550, 1674, 204 }, { -2855, -5765, 930, 1530 }, { -2889, -7325, -215, 305 }, { -2749, -6080, -237, 1452 }, { -985, -6667, 1577, 400 }, { -2036, -6083, 380, 1267 }, { -2077, -7460, 380, -30 }, { -1775, -7175, 1540, -386 }, { -3065, -6927, 989, 168 }, { -2836, -7602, 117, -3392 }, { -1058, -6396, 593, -3078 }, { -844, -6062, 999, -236 }, { -3261, -6951, 1491, -720 }, { -2186, -8484, 75, -1287 }, { -2882, -7756, 456, -510 }, { -1800, -6879, 960, -1183 }, { -2554, -7241, 1614, -1474 }, { -2608, -5305, 392, 851 }, { -2973, -6562, -859, 858 }, { -2640, -5989, 1031, -416 }, { -977, -8366, 705, -1434 }, { -1213, -7409, -77, -1390 }, { -1335, -6657, 2125, -123 }, { -2544, -6862, 1852, -737 }, { -3235, -6422, 1752, -103 }, { -1300, -7557, 939, -348 }, { -3476, -7579, 202, -109 }, { -2482, -6572, 753, 619 }, { -2554, -8136, -648, -429 }, { -1012, -7870, -3, -421 }, { -3604, -6247, 32, -3102 }, { -1486, -7271, 2013, -1021 }, { -578, -6799, -523, 405 }, { -2841, -5948, 1644, 911 }, { -2411, -7473, 1084, -484 }, { -2238, -6033, 294, -1059 }, { -3459, -6470, -201, -790 }, { -2027, -6009, 1833, 805 }, { -1433, -8047, 1531, -1754 }, { -3258, -7884, 763, -1422 }, { -1544, -6928, -729, 478 }, { -2314, -8415, 74, -3757 }, { -3201, -5684, 95, -2214 }, { -2423, -8694, 725, -3631 }, { -3545, -7071, 1162, -1798 }, { -294, -9662, 403, -2274 }, { -2290, -5460, 1196, 402 }, { -1603, -6713, 903, -2363 }, { 4121, 2491, -3142, -2482 }, { 4500, 3305, -3671, -1567 }, { 5973, 3172, -1348, -534 }, { 4830, 3379, -1549, 643 }, { 5214, 3938, -2641, -2302 }, { 4639, 4826, -5532, -847 }, { 5639, 2731, -2170, -963 }, { 6084, 3487, -3525, -1346 }, { 5971, 3154, -2190, -2316 }, { 5618, 4865, -6927, 116 }, { 5345, 3568, -7391, 709 }, { 5429, 5078, -3811, -1524 }, { 6960, 2037, -3515, -1096 }, { 7092, 2531, -4557, -588 }, { 6061, 4247, -5651, -478 }, { 4595, 3684, -4907, -827 }, { 7497, 3213, -3048, -424 }, { 5996, 2137, -3098, -1745 }, { 6198, 5199, -2223, -2274 }, { 6888, 2851, -2768, -1675 }, { 6114, 4210, -2316, -954 }, { 7127, 4242, -3041, -1408 }, { 6126, 3668, -1517, -1427 }, { 6245, 6129, -4225, -1186 }, { 6816, 3213, -2101, -964 }, { 5345, 5276, -2643, -847 }, { 6592, 4665, -4338, 484 }, { 6746, 3751, -3443, 124 }, { 5453, 1980, -2738, 2606 }, { 4662, 2179, -4226, -1059 }, { 5571, 3208, -3554, 174 }, { 5256, 4447, -1815, -1481 }, { 5400, 2570, -1210, 235 }, { 7056, 2549, -2674, 318 }, { 4574, 4340, -2892, -130 }, { 6203, 4587, -3273, -305 }, { 5103, 1925, -2715, -2137 }, { 3905, 4296, -1700, 247 }, { 4421, 4605, -3299, 811 }, { 5671, 1273, -3870, -924 }, { 5486, 1805, -4901, 133 }, { 6437, 2578, -1828, -106 }, { 5530, 5253, -5058, 1223 }, { 4816, 2025, -1215, 1443 }, { 3457, 3525, -2456, 3217 }, { 3316, 2595, -1108, 2459 }, { 3068, 3810, -2207, 1926 }, { 6351, 5436, -6470, 600 }, { 6324, 4240, -5365, 2416 }, { 4851, 4774, -4075, 1878 }, { 4900, 3679, -5198, 1078 }, { 8347, 3633, -4565, -171 }, { 5244, 5718, -3853, 173 }, { 3960, 3492, -2939, 2105 }, { 6070, 3473, -2351, 161 }, { 8228, 3034, -3360, -901 }, { 7006, 3985, -1940, -1926 }, { 7123, 4681, -4301, -878 }, { 5122, 4097, -1851, -449 }, { 6200, 2060, -2251, 1049 }, { 7106, 3844, -7209, 2625 }, { 7108, 3370, -6734, 533 }, { 6859, 2849, -3992, 1360 }, { 5458, 2278, -3253, 1131 }, { -1072, -2109, 4783, -1073 }, { -319, -2604, 4257, -2418 }, { 2466, 1300, 3476, -314 }, { 2847, -1502, 5296, -141 }, { 1667, -1273, 5559, -2725 }, { 2877, -3402, 6434, 204 }, { 53, -2637, 5275, -1181 }, { 1091, -2215, 5803, -1549 }, { 2397, -922, 4327, 1182 }, { 219, -3747, 4647, -1564 }, { -29, -2705, 4812, 1277 }, { 1499, -2608, 5648, 1407 }, { 2139, -2399, 4202, 2791 }, { -426, -2064, 5528, 151 }, { 2560, -2803, 6179, -2806 }, { 4537, -2479, 3797, 1095 }, { 888, -3357, 5341, -415 }, { 4460, -1814, 5388, -1227 }, { 3920, -3268, 6364, -703 }, { 3343, -4698, 4410, 784 }, { 309, -1897, 6306, 1223 }, { 958, -3318, 4254, -3167 }, { -99, 1596, 6018, -1983 }, { -429, -853, 6407, 878 }, { 1170, -1322, 6290, -417 }, { 2288, -505, 6303, -1999 }, { 3312, -1674, 6749, -2494 }, { -415, -3401, 4721, -371 }, { -189, -1210, 4844, -2002 }, { 888, -4142, 4377, 130 }, { 2469, -4381, 5398, -2492 }, { 2879, -2912, 5094, -2598 }, { -717, -617, 5650, -685 }, { 1470, -3863, 5352, -1684 }, { 3935, -96, 3823, -730 }, { 3769, -430, 3168, 694 }, { 2556, 385, 3539, 512 }, { 77, -1415, 5111, 2655 }, { 2724, -2158, 6715, -822 }, { 1832, 1001, 5385, -1900 }, { 900, 2198, 4464, -559 }, { 441, 69, 5921, -1743 }, { -1161, 738, 6732, -308 }, { 257, 2035, 4091, 736 }, { 1607, 1288, 4355, -23 }, { -13, 1316, 4180, 1672 }, { 1511, 1336, 3057, 1435 }, { 2189, -3813, 4530, 939 }, { 3632, -706, 2646, 1375 }, { 4266, -3761, 4241, 1077 }, { 3101, -427, 5273, -1202 }, { 2293, 276, 4810, -313 }, { 3430, -1851, 3101, 2045 }, { 3453, -2979, 5142, 942 }, { 1683, -3281, 4802, 2002 }, { 3954, -4715, 5611, 578 }, { 1272, -155, 5085, 454 }, { 128, -194, 5095, 1409 }, { 820, 880, 5797, -2658 }, { -1095, 656, 5774, 1095 }, { 813, -1669, 4320, -3251 }, { -119, 518, 6372, -651 }, { 2922, -4299, 6115, -877 }, { 4205, -4273, 4004, 2642 }, { -1211, -3892, 224, 3127 }, { -34, -4371, 1321, 2318 }, { 77, -6326, 1201, 828 }, { 3995, -3775, 1958, 3233 }, { 178, -3301, 1985, 3318 }, { 2330, -3801, 1033, 3195 }, { 1413, -5536, 826, 1709 }, { 2468, -3499, 3653, 3631 }, { 741, -4617, 1723, 2008 }, { 1246, -3043, 2978, 3949 }, { -343, -4308, 2258, 2189 }, { -682, -4640, 454, 2272 }, { 1236, -4829, 2491, 1642 }, { -512, -3766, 1182, 3052 }, { 119, -3939, 3712, 971 }, { -1145, -4624, 1360, 2281 }, { 101, -4746, 2866, 1255 }, { -1500, -5455, 539, 1637 }, { -969, -5909, 1414, 1128 }, { -1261, -4939, -231, 2022 }, { -226, -5345, 1207, 705 }, { 2712, -5109, 3205, 1866 }, { -476, -5913, 273, 1208 }, { -2039, -4464, 624, 2545 }, { -2351, -3930, 2019, 2673 }, { -2675, -4849, 1522, 1990 }, { -1524, -3461, 1446, 3204 }, { 477, -5314, 1710, 1577 }, { 656, -3729, 2346, 2511 }, { 550, -5917, 1975, 1040 }, { 1728, -4704, 3067, 1058 }, { -9, -5247, 506, 1760 }, { -574, -5135, 1675, 1672 }, { 2129, -3781, 3444, 2313 }, { 1144, -4439, 2214, 2529 }, { 1292, -4160, 3185, 1833 }, { 2445, -3262, 2534, 3227 }, { 2266, -4401, 2023, 2400 }, { -587, -3602, 3408, 2067 }, { -885, -4951, 3228, 1174 }, { -728, -2711, 2807, 3552 }, { 1019, -3043, 3195, 2954 }, { 1888, -4615, 1140, 2454 }, { 660, -5616, 754, 800 }, { -1975, -5371, 1649, 1585 }, { -1544, -5436, 2422, 1081 }, { -422, -5882, 2390, 750 }, { 1336, -5557, 2441, 1230 }, { 136, -4001, 267, 2854 }, { -522, -3289, 2226, 2728 }, { -971, -4580, 2471, 708 }, { 704, -5306, 3300, 1001 }, { 325, -3464, 3555, 2398 }, { 794, -3686, 848, 3169 }, { 660, -3017, 4584, 3242 }, { -1486, -3978, 2170, 1644 }, { -1615, -4650, 2688, 1844 }, { 750, -4578, 538, 2239 }, { 1668, -5849, 1455, 1031 }, { 3486, -4681, 2030, 2183 }, { 2642, -5429, 1696, 1761 }, { 4491, -4502, 3538, 2767 }, { 3545, -4528, 3514, 2982 }, { 3269, -3676, 2758, 3966 }, { 5572, 1146, 209, -3379 }, { 7459, 1053, 593, -1896 }, { 4480, 200, -310, -4259 }, { 5577, -939, 242, -3992 }, { 8142, 442, 1257, -3083 }, { 5442, 1261, 1424, -3236 }, { 6260, -183, 3125, -2532 }, { 7179, 889, 1618, -2548 }, { 6416, 932, 2379, -2487 }, { 7094, 2560, 961, -3392 }, { 7322, 463, 2732, -3735 }, { 6632, 1577, 1912, -3272 }, { 6312, 1349, 3028, -3460 }, { 6105, 386, 1213, -977 }, { 5478, 1158, 1114, -486 }, { 6493, 410, 1686, -2180 }, { 6378, 1881, 1333, -2240 }, { 5711, 812, 1958, -1300 }, { 6844, 877, 730, -1189 }, { 6824, -245, 2249, -2000 }, { 7515, 1521, 1251, -3058 }, { 6697, 1051, 1300, -1749 }, { 6476, 1425, 811, -2773 }, { 7350, 465, -76, -2849 }, { 6975, 2095, 567, -2492 }, { 4691, 1736, 2660, -2289 }, { 7837, 1456, 340, -2767 }, { 7930, 507, 838, -2074 }, { 6106, 1502, 766, -1110 }, { 4891, -659, 835, -3954 }, { 7250, 141, 1369, -1523 }, { 7651, 67, 1651, -2298 }, { 7364, -305, 601, -3132 }, { 7179, 193, 2491, -2871 }, { 6504, -272, 2167, -1322 }, { 4456, 983, 2300, -421 }, { 4817, 457, 1695, 371 }, { 6914, 555, 850, -3159 }, { 5904, 1030, 202, -1959 }, { 6258, 880, 2233, -4503 }, { 6029, 10, 2130, -3600 }, { 6449, 985, 1129, -3963 }, { 6616, -18, -111, -3285 }, { 4496, 775, 817, -4276 }, { 6134, 2338, 1470, -2973 }, { 6911, 152, 430, -1946 }, { 4053, 991, 3218, -1193 }, { 5435, 1285, 3124, -2412 }, { 5507, 1836, 1935, -1988 }, { 5240, 689, 2189, -2670 }, { 6638, 1719, 606, -1799 }, { 5556, -180, 129, -2595 }, { 5644, 1918, 1281, -4316 }, { 6410, 1088, -282, -3117 }, { 6503, 1841, 312, -3514 }, { 6947, 20, 1358, -3886 }, { 5464, 2109, 2398, -3194 }, { 5616, -407, 2140, -498 }, { 6121, 2707, 2379, -4096 }, { 7303, 1846, 2266, -4095 }, { 5444, 470, 2718, -1553 }, { 5817, -645, 3285, -1349 }, { 5625, 1427, 1103, -1991 }, { 6041, -806, 1196, -2943 }, { 3050, -5722, 4070, -5460 }, { 3420, -4386, 4078, -5155 }, { 6020, -3982, 7268, -2689 }, { 7502, -4317, 7894, -3973 }, { 4156, -3558, 5247, -4316 }, { 4725, -4401, 7290, -1540 }, { 6688, -5122, 8216, -3210 }, { 9176, -6576, 9276, -4963 }, { 8706, -5708, 7987, -4621 }, { 7060, -3535, 6532, -3308 }, { 5600, -2719, 5363, -1568 }, { 4661, -2803, 6263, -4716 }, { 3673, -3636, 6147, -3433 }, { 5305, -2585, 6073, -2638 }, { 7614, -1962, 6079, -5266 }, { 6760, -3366, 7382, -4322 }, { 6385, -3883, 4797, -1353 }, { 8182, -5120, 4298, -4641 }, { 9130, -6198, 4975, -3063 }, { 7421, -5436, 5576, -3713 }, { 3483, -4898, 5443, -2745 }, { 4907, -5643, 6390, -4105 }, { 8119, -7008, 7992, -6764 }, { 6528, -6122, 6967, -5590 }, { 5890, -4190, 6624, -5688 }, { 6815, -7934, 7275, -5456 }, { 5434, -4306, 5169, -5378 }, { 4364, -6436, 5376, -2604 }, { 8152, -3404, 5913, -5048 }, { 7983, -4863, 4262, -2461 }, { 8023, -6188, 6238, -5062 }, { 6753, -3692, 3935, -3723 }, { 6826, -4760, 3284, -4051 }, { 7224, -7423, 4492, -3875 }, { 6904, -2590, 6587, -6248 }, { 6106, -1944, 7345, -5506 }, { 4956, -2990, 7808, -3146 }, { 6908, -6885, 5949, -1288 }, { 7162, -6058, 3419, -3401 }, { 7015, -7080, 6907, -3018 }, { 6971, -6832, 5646, -3273 }, { 8014, -5546, 5471, -1544 }, { 6792, -2220, 5105, -2879 }, { 8494, -3974, 4408, -3999 }, { 9591, -4866, 6027, -4558 }, { 5264, -5161, 6101, -738 }, { 5803, -6141, 5197, -5231 }, { 4657, -6822, 3232, -5189 }, { 4791, -5135, 3809, -4665 }, { 6108, -5103, 2379, -3873 }, { 4680, -3909, 3234, -5093 }, { 5802, -3853, 3795, -4984 }, { 4360, -7483, 4802, -3877 }, { 5429, -7517, 5911, -3717 }, { 6866, -2280, 4880, -4634 }, { 10131, -4628, 4414, -4092 }, { 10811, -5189, 7746, -5337 }, { 5663, -8941, 5287, -5680 }, { 8023, -5991, 7403, -2796 }, { 9669, -6919, 6525, -4932 }, { 7275, -3796, 4962, -2547 }, { 8848, -4806, 5677, -3080 }, { 8128, -4308, 7749, -6569 }, { 4032, -5196, 2282, -6239 }, { 6593, 700, -229, 304 }, { 8260, 539, -66, -1259 }, { 6605, 176, -814, -109 }, { 8057, 0, -1, -136 }, { 7382, -38, -484, -1129 }, { 8373, -929, 682, -454 }, { 7674, 690, -1278, 546 }, { 7326, -517, 406, -1283 }, { 7612, -1715, -1167, 1175 }, { 8590, 441, -782, -710 }, { 8572, -1202, -291, 260 }, { 7308, -147, -1785, 414 }, { 6787, -353, -672, 934 }, { 5177, -133, 179, 82 }, { 4161, -34, 447, 1497 }, { 5997, -902, 1533, -121 }, { 5727, -871, -1370, 945 }, { 8386, -252, 293, -823 }, { 6573, -1354, 682, 616 }, { 7650, -2096, 725, 457 }, { 8122, 78, 636, -1400 }, { 8421, 428, -1620, 131 }, { 7341, -1292, -717, 186 }, { 7998, -49, -720, 266 }, { 5987, -351, 669, 844 }, { 7314, -1620, 250, -603 }, { 7219, -1562, -572, 1994 }, { 8682, -358, -290, -388 }, { 5810, 155, -178, 1199 }, { 7246, -12, 1042, -786 }, { 7357, -923, 1468, -475 }, { 7801, 621, -212, -724 }, { 5346, -514, 1210, 1356 }, { 8459, 36, -127, -779 }, { 6878, -2429, 854, 1750 }, { 7280, -1401, -1353, 2845 }, { 7579, -2148, -1463, 2087 }, { 6637, 946, -872, 750 }, { 4807, -1100, 1289, 2602 }, { 4495, 219, 1551, 1128 }, { 7639, 506, 446, -1107 }, { 6359, 188, 1009, -115 }, { 6641, -1820, 1655, 723 }, { 5394, -2382, 1604, 2542 }, { 6021, -2644, 2396, 1407 }, { 4698, 882, 245, 1525 }, { 8103, 573, -798, -349 }, { 8045, -519, 997, -1092 }, { 7571, -122, 227, -338 }, { 5347, -1200, 630, 1718 }, { 7070, 790, 218, -544 }, { 7440, 728, -527, -20 }, { 6402, -355, 197, -736 }, { 4031, 771, 866, 1895 }, { 6009, 896, 445, -31 }, { 5160, 1098, -856, 1784 }, { 7980, -886, -1293, 1396 }, { 6318, -1361, 2423, 252 }, { 7547, -699, 133, 506 }, { 8562, -2344, 940, 264 }, { 5890, 1187, -1425, 2194 }, { 6558, -645, -1311, 2621 }, { 4634, -1671, 2075, 1623 }, { 5614, 105, -816, 2376 }, { 6646, 1558, -1365, 630 }, { 6998, 1150, -2117, -990 }, { 6555, 2311, -1093, -1783 }, { 6682, 1430, -2391, -1940 }, { 7861, 1555, -2977, -1188 }, { 6745, 1723, -459, -2085 }, { 7504, 1229, -1666, -2060 }, { 7937, 671, -2128, -1529 }, { 7139, 991, -735, -2632 }, { 6867, 1592, -1303, -2324 }, { 6401, 2230, -1732, -2508 }, { 7201, 2184, -2169, -1988 }, { 6636, 2190, -995, -2840 }, { 7620, 2306, -2089, -651 }, { 7584, 1875, -1438, -631 }, { 9214, 1561, -2464, -1139 }, { 6154, 1318, -1237, -2917 }, { 7917, 2847, -1797, -1599 }, { 8309, 2029, -2555, -465 }, { 8204, 1282, -584, -2405 }, { 8440, 1035, -1147, -1137 }, { 7107, 1858, -60, -1568 }, { 6781, 2912, -873, -1463 }, { 7603, 1316, -319, -1249 }, { 7833, 1335, -78, -1849 }, { 7930, 1141, -1016, -695 }, { 7883, 1610, -1017, -1314 }, { 8069, 1409, -1811, -196 }, { 8319, 1031, -582, -1590 }, { 5948, 1537, -2153, -2373 }, { 8684, 1171, -1871, -850 }, { 8357, 2484, -2411, -1292 }, { 6516, 2092, -193, -1167 }, { 6112, 1697, 22, -525 }, { 7161, 703, -602, -1879 }, { 6047, 2351, -807, -219 }, { 8072, 1854, -1817, -1553 }, { 6956, 1304, 76, -1011 }, { 6607, 1481, -544, -162 }, { 6958, 2541, -265, -1938 }, { 6416, 2514, -777, -850 }, { 7272, 2110, -899, -1171 }, { 7741, 2153, -283, -2614 }, { 6482, 2041, -1758, -1221 }, { 6762, 940, -1862, -2281 }, { 5610, 1194, -1691, -1561 }, { 7833, 2164, -823, -1952 }, { 5460, 1438, -848, 1189 }, { 6011, 1377, -771, -1557 }, { 7679, 544, -1134, -2214 }, { 7209, 1292, -2714, -1564 }, { 5567, 1200, -404, -169 }, { 5853, 1461, -1465, -518 }, { 6782, 689, -844, -860 }, { 7330, 1337, -1152, -71 }, { 7189, 1506, -653, -685 }, { 6860, 2116, -1403, -240 }, { 8804, 1516, -1391, -1760 }, { 7210, 2689, -1498, -989 }, { 7030, 3022, -1441, -2083 }, { 5649, 1836, -407, 525 }, { 7451, 3099, -717, -2464 }, { 7384, 1656, -2007, 398 }, { 6504, 707, -1919, -134 }, { -1851, 3639, -2279, -695 }, { -4037, 1644, -77, 1329 }, { -4025, 1960, -1565, -567 }, { -3430, 2495, -795, 368 }, { -4771, 2480, 993, 756 }, { -3431, 2058, -2539, -971 }, { -3802, 3418, 380, 217 }, { -3074, 3350, -1652, -1056 }, { -3705, 326, -1650, 1535 }, { -3122, 1281, -1192, 1607 }, { -4601, 1367, -968, 53 }, { -3808, 958, 44, 2560 }, { -2079, 2530, -1485, 1166 }, { -3707, 343, -2889, 180 }, { -5249, 1431, -31, 688 }, { -4990, 125, -704, 1270 }, { -2771, 1334, -2446, 746 }, { -2292, 994, -1527, 2630 }, { -1261, 3070, -2519, 268 }, { -2544, 3890, -1057, -552 }, { -4421, 255, -1980, 530 }, { -2951, 454, -13, 3643 }, { -2262, 1815, -370, 2880 }, { -2383, 3657, -649, 576 }, { -3541, -161, -1389, 2550 }, { -4241, 1575, 1325, 2561 }, { -2767, 4037, 1221, 1578 }, { -3748, 2697, 1148, 1801 }, { -4686, 2385, -220, 0 }, { -1531, 1645, -2751, 1327 }, { -45, 4032, -799, 2298 }, { -2915, 2280, 709, 2495 }, { -1199, 3278, -406, 2346 }, { -2471, 116, -2706, 2060 }, { -2440, 2173, -2894, -344 }, { -3375, 2287, 1781, 3226 }, { -2153, 3568, 1827, 2918 }, { -862, 2267, -1626, 2527 }, { -2698, 1135, 301, 4239 }, { -2364, 2123, 1010, 3710 }, { -2447, 3281, -81, 1408 }, { -2660, 4735, 472, 258 }, { -1053, 3097, 2682, 2398 }, { -3366, -1037, -1152, -868 }, { -643, 4242, 2212, 1259 }, { 971, 3991, 934, 643 }, { -1617, 2002, 2139, 2195 }, { -4897, 972, 784, 1719 }, { -1275, 2992, 1039, 3821 }, { -392, 4973, -209, 1821 }, { -1028, 4718, -1479, -137 }, { 50, 3914, 553, 2210 }, { 678, 4364, 359, 1303 }, { -582, 4911, 514, 1671 }, { 1276, 3914, -1252, 2934 }, { -1496, 3984, 857, 2330 }, { 772, 4744, -655, 2332 }, { -799, 5283, -439, 624 }, { 1341, 2937, 650, 2027 }, { -1739, 4892, 1275, 1702 }, { -892, 2596, -151, 3951 }, { -3532, 1090, 1292, 32 }, { 321, 3146, 2647, 1475 }, { 264, 4199, -1591, 1317 }, { -452, -2357, 2266, 4192 }, { 3022, -1033, -2389, 5678 }, { -1162, -1342, 3543, 4990 }, { -474, -1477, -1223, 5016 }, { -699, -2857, 900, 3835 }, { -461, -2255, -117, 4626 }, { 1204, -2062, -1211, 4403 }, { 2192, -3035, -337, 3966 }, { 108, -831, 279, 5643 }, { 1457, -620, -2908, 5276 }, { -2527, -78, 1085, 5460 }, { -1978, -1918, -949, 4733 }, { 32, 367, -1904, 5166 }, { 1890, -1665, 440, 4752 }, { -518, -348, 2816, 4891 }, { 3695, -2490, -1374, 4603 }, { 246, -1965, 3549, 3969 }, { 1100, -3111, 656, 3737 }, { -1379, 870, -414, 4575 }, { 628, -357, -1227, 6179 }, { -1129, -1318, -2457, 4576 }, { -425, -98, -73, 6336 }, { 367, -887, 2990, 4207 }, { 2091, -1251, 2444, 3557 }, { -1759, -1610, 2046, 5273 }, { 3210, 1414, -20, 2616 }, { 3303, -2636, 1005, 4237 }, { -327, -3107, -640, 3687 }, { -197, 764, 572, 5486 }, { 646, -767, 1388, 5464 }, { 104, 2742, -228, 3907 }, { -236, 1829, -579, 4585 }, { -2150, -474, -1525, 4006 }, { -23, -2632, -2400, 3892 }, { -12, -1739, -2910, 4867 }, { -2310, -368, -102, 4583 }, { -1991, -2061, 533, 4531 }, { 3884, -1446, -153, 4393 }, { 1568, 14, -289, 5268 }, { -1376, -253, -2797, 3417 }, { 3193, -2577, 2475, 3566 }, { 3418, 617, 1350, 1857 }, { 3792, -24, -272, 3370 }, { 153, 1159, 2906, 2877 }, { 511, 2162, 1548, 2741 }, { 262, 819, -2791, 3734 }, { 4232, -2015, 1486, 3477 }, { 2943, -1110, -1014, 5480 }, { 2842, 369, 703, 3476 }, { 3011, 1634, -933, 3553 }, { 4412, -1548, -942, 5021 }, { -1405, 593, 2372, 5267 }, { 2093, 2129, 896, 2365 }, { 4845, -1980, 0, 3823 }, { -2140, 81, 3278, 5637 }, { 1484, 2665, -324, 3653 }, { 10, 192, 1620, 5291 }, { 2152, 738, -2269, 5000 }, { 2102, 2748, -1652, 4707 }, { 2855, -2131, -387, 5188 }, { 1173, 676, 1338, 3277 }, { 2340, -2329, -2064, 4095 }, { 861, -2024, 1296, 5055 }, { 2189, 3225, -695, 2626 }, { 6196, -7079, 1943, -822 }, { 4547, -4813, 3261, 1856 }, { 4243, -6904, 3443, 448 }, { 4581, -7503, 946, 506 }, { 6626, -7754, 3427, 470 }, { 3407, -9088, 3269, -1496 }, { 4079, -6464, 2304, 777 }, { 5621, -9336, 2684, -768 }, { 5351, -6464, 5238, -214 }, { 5961, -8007, 1724, -3091 }, { 4213, -8067, 603, -246 }, { 7208, -7403, 3168, -1738 }, { 6098, -7700, 329, -1379 }, { 6525, -6735, 4248, -1072 }, { 6073, -6241, 2167, -2378 }, { 4609, -9218, 3051, -1033 }, { 6813, -7283, 1581, -1897 }, { 6126, -6275, 2789, 681 }, { 4423, -6538, 1621, -1692 }, { 6272, -8298, 3167, -1855 }, { 6172, -8558, 4498, -1169 }, { 4844, -8588, 1647, -366 }, { 6209, -8807, 1581, -369 }, { 5389, -8059, 550, -192 }, { 6654, -9775, 2504, -1063 }, { 7103, -7998, 806, 530 }, { 5662, -6736, 1565, -3620 }, { 4165, -9564, 4191, -2131 }, { 4526, -7181, 576, -2875 }, { 4633, -8623, 2807, -4742 }, { 3709, -7794, 1815, 34 }, { 3634, -8622, 2313, -826 }, { 6991, -8447, 2063, -3198 }, { 7757, -9486, 2255, -558 }, { 4149, -7778, 4728, -1696 }, { 5767, -7427, 1113, 707 }, { 4592, -6261, 2329, 1864 }, { 3159, -10498, 1677, -4273 }, { 3534, -9010, 2437, -3565 }, { 4479, -10821, 2715, -4942 }, { 3207, -9805, 3054, -3886 }, { 4627, -8189, 3018, -2354 }, { 5527, -10566, 3244, -2749 }, { 4346, -10127, 3335, -3084 }, { 6132, -10085, 3316, -1308 }, { 5629, -9704, 2178, -3058 }, { 3603, -8538, 1246, -624 }, { 3737, -8488, 395, -3167 }, { 5465, -11414, 2810, -4640 }, { 5306, -7745, 2721, -3988 }, { 7000, -9111, 1695, -1409 }, { 6663, -7741, 2466, -4079 }, { 4083, -7175, 1836, -4831 }, { 3613, -9926, 1342, -3455 }, { 6588, -8033, 457, -258 }, { 4720, -8102, 17, -1209 }, { 7414, -8709, 1294, -344 }, { 5437, -10030, 4043, -1704 }, { 4862, -9281, 1558, -1431 }, { 6800, -6403, 5113, 862 }, { 4623, -8242, 2667, -228 }, { 5919, -5083, 3348, 2135 }, { 5985, -8889, 2733, -5105 }, { 5029, -5767, 4407, 719 }, { 354, -6158, -838, -3001 }, { 351, -5943, -2104, -1534 }, { -633, -7190, -25, -4798 }, { -1595, -7235, -3812, -1400 }, { 103, -6197, -2933, -78 }, { -1722, -5020, -3441, -4333 }, { -1963, -5644, -4365, -270 }, { -846, -5743, -3477, 196 }, { -191, -5348, -4054, -469 }, { -2515, -7754, -3495, -818 }, { -2090, -6710, -2701, 117 }, { -546, -7036, -1398, 163 }, { -278, -7091, -2662, -536 }, { -622, -7962, -2731, -1464 }, { -1555, -8118, -3612, -2057 }, { -1094, -6280, -2314, 505 }, { -2556, -8538, -4024, -2247 }, { 109, -7134, -3107, -1823 }, { -900, -6954, -3340, -717 }, { -605, -7113, -3656, -2154 }, { 837, -6263, -3211, -2177 }, { -417, -5810, -3871, -1469 }, { -1318, -5649, -4207, -3198 }, { 413, -6765, -2082, -33 }, { -3101, -6450, -4362, -766 }, { 755, -6489, -2967, -846 }, { 1117, -7106, -2452, -1352 }, { -1202, -8387, -3072, -2897 }, { -365, -4894, -3561, -2937 }, { -2372, -8776, -265, -4441 }, { -1224, -8678, -896, -5074 }, { -755, -10096, -600, -6623 }, { 300, -8206, -225, -4568 }, { -1176, -6824, -2633, -3527 }, { -2006, -5443, -1526, -5849 }, { -1115, -5540, -2363, -4785 }, { 1059, -6812, -2543, -2654 }, { -1976, -6861, -3062, -5508 }, { -379, -5328, -2321, -3624 }, { -2108, -5860, -4518, -1915 }, { -379, -7885, -1329, -594 }, { 774, -5389, -581, -5213 }, { -2601, -5083, -1849, -4921 }, { -176, -5580, 74, -5075 }, { -204, -6780, -190, -6232 }, { 418, -7594, -1987, -820 }, { -1873, -8529, -2926, -1609 }, { 1340, -6362, -919, -4975 }, { 577, -7990, -2044, -1873 }, { -2572, -7413, -1745, -2224 }, { -2037, -7030, -1461, -7138 }, { -2559, -8756, -2039, -5836 }, { -2079, -6764, -1209, -5669 }, { -1613, -7801, -2006, -685 }, { -1865, -6583, -722, -3529 }, { -589, -6358, -1377, -1003 }, { -540, -7514, -1331, -3542 }, { 419, -6192, -1677, -4927 }, { -2786, -8763, -2966, -5065 }, { -2172, -8411, -1726, -4675 }, { -3382, -9833, -3497, -5722 }, { -2433, -10169, -2077, -5775 }, { -424, -9451, -1096, -3658 }, { -537, -8522, -910, -1897 }, { -5550, 2807, 1683, -693 }, { -6395, 635, 3573, -1246 }, { -7544, 2280, 2140, 44 }, { -8751, 1136, 2951, -794 }, { -5605, 2709, 2052, 916 }, { -7650, 654, 869, 135 }, { -6939, 967, 1409, 870 }, { -7834, 2123, 3310, 974 }, { -6935, 2818, 1274, -1678 }, { -5605, 2233, 1013, 471 }, { -7095, 1849, 1648, 198 }, { -6636, 1634, 712, -37 }, { -7279, 978, 296, -315 }, { -7664, 3504, 3292, -216 }, { -7836, 1209, 1221, -257 }, { -7913, 2201, 1765, -1529 }, { -7077, 3783, 2632, -1407 }, { -5565, 1645, 1410, -622 }, { -6494, 2879, 1181, -759 }, { -7073, 3137, 3010, 550 }, { -7249, 1839, 847, -805 }, { -6630, 2197, 282, -1096 }, { -8836, 1573, 1988, -1090 }, { -7809, 1274, 836, -1198 }, { -7895, 2970, 3511, -1097 }, { -6960, 1664, 1356, -2442 }, { -6582, 2866, 2273, 307 }, { -7221, 821, 2851, -1435 }, { -6015, 1703, 2001, -2367 }, { -8082, 1034, 2103, 239 }, { -5952, 1912, 301, -465 }, { -6099, 841, 379, 567 }, { -6343, 50, 494, 658 }, { -6586, 983, 591, -893 }, { -5500, 869, 2187, -2479 }, { -6482, 60, 1545, -979 }, { -6705, 515, 1974, -53 }, { -6460, 1755, 1325, -1275 }, { -6093, 2617, 2465, -623 }, { -7330, 2161, 594, -2115 }, { -7324, 762, 1593, -2004 }, { -6385, 679, 1510, -2514 }, { -6159, 241, 2976, -1631 }, { -8583, 3030, 4045, -162 }, { -6299, 66, 2209, -2103 }, { -5428, 1279, 3267, -1846 }, { -6438, 1335, 2728, -1631 }, { -8012, 1070, 2428, -1151 }, { -6201, 2781, 2349, -1918 }, { -5918, 1139, 3121, -148 }, { -6314, 2481, 3137, -1808 }, { -7180, 1722, 2435, -1602 }, { -6750, 1829, 3763, -1145 }, { -6713, 1777, 2221, 1212 }, { -7479, 1835, 3627, -479 }, { -7299, 10, 2406, -1593 }, { -8249, 3129, 996, -2870 }, { -8374, 1534, 1333, -1882 }, { -7507, 3353, 1598, -2299 }, { -7379, 2701, 2326, -1167 }, { -8440, 2276, 2796, -542 }, { -10348, 1527, 2649, -1165 }, { -8184, 3614, 2574, -1738 }, { -5539, 1574, 1733, 1138 }, { 9404, -7652, 67, 79 }, { 8654, -3972, 1358, -60 }, { 8617, -4794, 117, 2318 }, { 7886, -4505, 1784, 1200 }, { 8636, -6125, 3879, -1003 }, { 9654, -6836, 1816, 205 }, { 9374, -6553, 913, 1875 }, { 8020, -6150, 1134, 2390 }, { 7786, -4970, 2078, -1857 }, { 8691, -6119, 711, 708 }, { 9039, -5568, 2944, -1902 }, { 9955, -5048, 1433, -601 }, { 8089, -6927, 3093, -2846 }, { 8487, -7024, 2415, 19 }, { 9388, -5287, 3577, -2655 }, { 8591, -7371, 2300, -996 }, { 9104, -4763, 1453, -2558 }, { 7615, -5457, 596, 164 }, { 9860, -7047, 3433, -614 }, { 8756, -4404, 2235, -964 }, { 9462, -4660, 299, -1822 }, { 10119, -5550, 2689, -1273 }, { 10915, -7471, 2705, -1007 }, { 11433, -7090, 1410, -1198 }, { 9882, -7431, 2965, -1895 }, { 7628, -5219, 769, -2661 }, { 8169, -5318, 2262, 70 }, { 8846, -6320, 1939, -754 }, { 7147, -5593, 1248, -971 }, { 10652, -5485, 935, 137 }, { 7778, -6533, 2564, -1932 }, { 8878, -5173, 1214, -361 }, { 9828, -4943, 282, 510 }, { 10042, -6134, 3895, -1914 }, { 7965, -6630, 3566, -433 }, { 8573, -4502, 3574, -1209 }, { 8398, -4801, 1031, -1347 }, { 10136, -7772, 2612, 1547 }, { 9890, -7280, 1768, -1083 }, { 8407, -6585, -706, -58 }, { 7976, -7582, 229, -131 }, { 10481, -8866, 1166, -147 }, { 10914, -4342, 3189, -2412 }, { 10440, -5198, -104, -1109 }, { 11227, -6530, 2381, -2449 }, { 8487, -8064, 1086, 230 }, { 9975, -6123, -857, -134 }, { 8339, -6498, 1232, -2337 }, { 11042, -4506, 1119, -2098 }, { 12563, -5592, 1837, -2062 }, { 11801, -5590, 632, -1296 }, { 10152, -5617, 1511, -1917 }, { 7800, -6473, 51, -1337 }, { 7941, -5560, 2438, -3270 }, { 6554, -3834, 2100, 1476 }, { 9065, -5520, -226, -1120 }, { 10794, -7120, -243, 122 }, { 10429, -6968, 272, -806 }, { 8942, -8914, 1442, -392 }, { 9969, -5051, 2033, -2953 }, { 7275, -4152, 3058, -64 }, { 11127, -5488, 4589, -3227 }, { 9626, -6666, 2739, -2958 }, { 6943, -5362, 4470, 1008 }, { -7456, -967, 2936, -1002 }, { -8622, -333, 6962, 2606 }, { -7486, -3392, 3668, 1287 }, { -8053, -827, 5148, 1097 }, { -6610, 454, 4952, 96 }, { -7701, -1982, 3161, -468 }, { -7307, -1132, 4071, -36 }, { -8125, -271, 5199, 3862 }, { -9182, -1950, 2813, 1878 }, { -9855, -952, 4794, 3010 }, { -7241, 1431, 4202, 2468 }, { -9646, 157, 4766, 1046 }, { -9371, 1230, 6009, 2958 }, { -11514, -64, 8630, 5248 }, { -6766, 565, 2766, 2140 }, { -8426, -9, 2852, 1271 }, { -11291, -1113, 5087, 2937 }, { -8297, 2092, 4495, 1264 }, { -9983, 735, 3809, -51 }, { -9048, -1000, 3191, -308 }, { -7331, -1987, 2655, 1391 }, { -7144, -21, 4333, 2161 }, { -6032, -1540, 3543, 896 }, { -7987, -1036, 1985, 1529 }, { -9264, 2004, 5194, 290 }, { -11308, -840, 5754, 1654 }, { -9130, -2398, 4292, 2973 }, { -6248, 838, 3563, 1223 }, { -6819, -2760, 3511, 119 }, { -7213, -2006, 4364, 762 }, { -5431, -1047, 4533, 166 }, { -7098, -641, 2021, 639 }, { -8628, -2249, 3588, 399 }, { -6352, -1498, 3560, -648 }, { -7033, -2190, 4870, 2562 }, { -7405, -46, 3772, -581 }, { -6104, 796, 5143, 1965 }, { -5787, 943, 5784, 3030 }, { -8367, 1465, 7192, 4097 }, { -8259, 789, 5694, 1963 }, { -10614, -1899, 5748, 2645 }, { -8258, -805, 3698, 2275 }, { -6877, -972, 6431, 3160 }, { -6483, 363, 7018, 3129 }, { -6283, -1358, 5191, 1524 }, { -8853, -3157, 4119, 1741 }, { -6086, -267, 3883, -835 }, { -7254, 1032, 6613, 4017 }, { -11470, -3350, 4649, 3426 }, { -6743, 481, 6148, 1239 }, { -5394, -166, 5309, 3165 }, { -7958, 1068, 4268, -240 }, { -10520, 2256, 7916, 2828 }, { -5132, -4, 5739, 1176 }, { -8643, 120, 3255, -629 }, { -9631, 1974, 8870, 4362 }, { -10663, -1221, 3733, 589 }, { -8224, -1843, 5806, 2655 }, { -8282, 1255, 8647, 3478 }, { -12311, -1505, 9043, 6256 }, { -11312, -856, 7136, 4681 }, { -11944, -722, 7941, 3309 }, { -7868, -463, 6846, 4196 }, { -8679, -241, 7410, 5347 }, { 6759, -4680, -508, 1220 }, { 5176, -6111, 944, 121 }, { 6843, -5667, -1368, -533 }, { 5616, -5884, -1471, -695 }, { 6030, -5089, -1808, -940 }, { 7444, -5463, -52, 1881 }, { 4207, -6079, -506, 1571 }, { 6785, -4410, -649, 3084 }, { 4838, -5214, 2026, 2998 }, { 4201, -5790, 645, 1811 }, { 6930, -5129, -1940, 1698 }, { 6332, -4627, 692, 3027 }, { 6285, -4314, -106, 3644 }, { 6255, -5450, -1975, 742 }, { 4199, -4676, -459, 1796 }, { 5592, -5500, 1345, 1300 }, { 4358, -5556, -2236, 114 }, { 4620, -5875, -1563, 888 }, { 4892, -7550, -327, -419 }, { 4734, -7085, 7, 613 }, { 3883, -5562, -1969, 1080 }, { 5610, -4990, -204, 834 }, { 4117, -6482, -1271, 341 }, { 6585, -5107, 892, 1169 }, { 6632, -3683, 302, 3002 }, { 6326, -5351, -983, -1250 }, { 4382, -7192, -730, -158 }, { 5227, -6540, -451, 1123 }, { 5468, -6472, -870, -1471 }, { 5191, -6402, -1365, -127 }, { 7407, -6317, -973, -336 }, { 4611, -6530, -820, -1980 }, { 4963, -5159, -2050, -966 }, { 4414, -5691, -211, -998 }, { 5954, -5873, 750, -1749 }, { 4394, -4796, -1268, 254 }, { 7161, -6214, -1010, 689 }, { 4965, -3598, 2372, 1711 }, { 6248, -6180, 981, 864 }, { 6473, -5336, 525, -600 }, { 4591, -6864, -1131, -900 }, { 6314, -6440, -1021, -375 }, { 5838, -6209, -1199, 944 }, { 5308, -5283, -2100, 1267 }, { 4342, -5860, -1637, -1356 }, { 5680, -4388, -1227, -104 }, { 4900, -4098, 1449, 4046 }, { 4677, -4284, -106, 3190 }, { 7574, -6173, -848, 1859 }, { 6493, -7207, -131, 726 }, { 5513, -5261, -2117, 4 }, { 6191, -7352, -193, -505 }, { 5885, -4333, 324, -134 }, { 6162, -6081, -312, -2044 }, { 4216, -6200, -1810, -572 }, { 5652, -7035, -696, -197 }, { 7131, -7189, -366, -60 }, { 5032, -4803, -1514, 2832 }, { 7386, -4610, -606, 3489 }, { 4211, -5031, 1221, 3047 }, { 4050, -4653, 1584, 1469 }, { 6852, -5302, -1861, 206 }, { 7736, -4816, -1794, 3359 }, { 6290, -3439, 1522, 2454 }, { 1768, 5990, -5560, -2594 }, { 3903, 5326, -1530, -1501 }, { 2472, 3738, -2117, -4240 }, { 3260, 5448, -904, -4733 }, { 1435, 7297, -3676, -4102 }, { 4096, 5951, -656, -3312 }, { 2178, 6009, -3146, -3724 }, { 3787, 5493, -5473, -1633 }, { 2998, 7286, -3334, -3571 }, { 2894, 6576, -4708, -2804 }, { 830, 6163, -4286, -3348 }, { 4755, 5569, -1730, -2739 }, { 4604, 6065, -3562, -2605 }, { 2749, 5141, -3986, -2775 }, { 3942, 4875, -2143, -3340 }, { 2819, 8517, -2004, -2724 }, { 2146, 6298, -689, -3093 }, { 5196, 6504, -3393, -1475 }, { 1851, 8386, -1748, -1420 }, { 3474, 8572, -3534, -2688 }, { 4503, 7560, -3561, -2245 }, { 4433, 6219, -2393, -1575 }, { 3506, 7248, -2275, -1977 }, { 3490, 7409, -3147, -604 }, { 4214, 6447, -3520, 516 }, { 619, 7034, -829, -1705 }, { 1732, 7395, -356, -2208 }, { 1226, 5204, -3294, -3732 }, { 2027, 5619, -1813, -4146 }, { 3078, 5877, 47, -2651 }, { 1654, 5458, 424, -682 }, { 3163, 5464, -2026, -270 }, { 2884, 5375, -685, -530 }, { 2950, 7286, -35, -2967 }, { 1986, 5066, -597, 482 }, { 3459, 4308, -3845, -2333 }, { 3155, 7037, -1346, -4345 }, { 2193, 6696, -717, -1319 }, { 3677, 5089, -3892, -487 }, { 2186, 5136, -4186, -1492 }, { 773, 5796, -917, 817 }, { 2489, 6546, -3570, -2117 }, { 1223, 6469, -1362, -33 }, { 271, 6061, -1466, -1725 }, { 2540, 5171, -1847, 1032 }, { 2548, 5251, -2697, 1677 }, { 771, 7600, -768, -632 }, { 4710, 6647, -4736, -1275 }, { 1369, 5917, -2971, -1056 }, { 163, 5239, -3499, -2275 }, { 2104, 4285, -3211, -3286 }, { 1107, 7411, -1972, -1671 }, { 2196, 7262, -2310, -1926 }, { -244, 6439, -1745, -839 }, { 3293, 3832, -2890, -3000 }, { 419, 6443, -379, -407 }, { 3077, 4930, -1156, -2869 }, { 2131, 5874, -2330, 224 }, { 690, 6538, -2212, -2841 }, { 1602, 4421, -2515, 1542 }, { 3318, 9373, -3032, -3477 }, { 5646, 7462, -5153, -1463 }, { 4139, 7137, -1539, -3321 }, { 3481, 9077, -1645, -3653 }, { -7747, 375, -106, -543 }, { -8587, -1379, -586, -461 }, { -10146, -892, 2094, 694 }, { -8103, 382, 504, -325 }, { -8548, -92, 94, -656 }, { -7460, 38, 152, 388 }, { -8266, -271, -459, -883 }, { -7935, -664, -1026, -802 }, { -8341, -109, 853, 161 }, { -8802, -1355, 1099, 630 }, { -8957, -6, 1108, -669 }, { -7260, -1520, -43, -407 }, { -7555, -174, 668, -2562 }, { -9014, -126, 227, -1191 }, { -8184, 769, 290, -1375 }, { -9476, 55, 962, -1528 }, { -8679, 541, 755, -1030 }, { -9842, -1626, 838, -1588 }, { -8513, -702, 788, -1998 }, { -10101, -1558, -366, -1841 }, { -8135, 78, 1479, -1813 }, { -9128, -454, 313, -1786 }, { -7554, -1084, 831, -2442 }, { -7576, -701, 2068, -1665 }, { -7791, -1481, 1587, -1808 }, { -6701, -596, -97, 802 }, { -7418, -15, 684, -963 }, { -7127, -477, -139, -426 }, { -8097, -110, -36, -264 }, { -7620, -1922, -590, -101 }, { -7647, -1201, 279, 660 }, { -7856, -1974, 758, -2271 }, { -8496, -167, 2232, -1143 }, { -8506, -1359, 624, -740 }, { -7274, -1052, 1062, -139 }, { -7800, -217, 91, -1794 }, { -7030, -1694, -955, 615 }, { -9020, -1864, 101, -2182 }, { -9400, -740, 598, -667 }, { -8448, -1184, 2024, -1272 }, { -8812, -570, -897, -2384 }, { -10559, -1286, 538, -1536 }, { -8728, -888, -1089, -1397 }, { -7080, -1185, 636, -1252 }, { -9880, 233, 2344, -782 }, { -7952, -1326, -378, -1947 }, { -7207, -378, 1408, -2237 }, { -8467, -1545, 902, -1987 }, { -9163, -1474, 924, -1739 }, { -8159, -992, -77, -2744 }, { -8343, 148, -423, -1573 }, { -9105, -649, -254, -1214 }, { -8939, 456, 281, -1905 }, { -8837, 179, -394, -2634 }, { -9145, 757, 1547, -1319 }, { -9775, -723, 441, -1680 }, { -8910, -686, 1529, -1525 }, { -9492, -1134, 2064, -938 }, { -6111, -943, 677, -31 }, { -7411, -613, -814, 46 }, { -9479, -922, -430, -2061 }, { -11298, -1268, 1318, -1117 }, { -8190, 832, 671, -2214 }, { -10453, -550, 1672, -886 }, { 1044, 9353, -1651, -5423 }, { 1034, 8149, -455, -6166 }, { 761, 8293, -3214, -4838 }, { 938, 8077, 164, -5130 }, { 1295, 8673, 2582, -5490 }, { -314, 7973, -2395, -5231 }, { -507, 9012, -2497, -5775 }, { 2396, 8314, -1022, -4673 }, { -1516, 8501, 1950, -4969 }, { -308, 7401, 1549, -4866 }, { -112, 8340, 3003, -4920 }, { -50, 9315, 1371, -5666 }, { -659, 9449, 2496, -5547 }, { 2573, 9148, -2270, -4783 }, { 830, 7104, -438, -3907 }, { 522, 10672, -677, -6483 }, { -1190, 10108, -510, -6518 }, { -427, 8271, -579, -6315 }, { 1602, 8113, -1927, -4418 }, { -2266, 8180, 448, -5190 }, { -1633, 8816, -226, -5771 }, { 759, 9481, -105, -5813 }, { 2254, 6679, -466, -5662 }, { -88, 6946, 895, -5958 }, { -1705, 10009, 1394, -5574 }, { 748, 7943, 540, -6692 }, { 1411, 7009, 232, -6145 }, { 697, 7290, -1221, -5342 }, { -1764, 10580, 1944, -3981 }, { -1334, 9124, 1195, -3903 }, { -905, 10067, 635, -5039 }, { 664, 10680, 49, -4625 }, { 1374, 9536, -777, -3591 }, { 252, 9698, -597, -2931 }, { 824, 9164, -1014, -2144 }, { 2438, 10569, -2289, -4424 }, { 2101, 7102, 507, -3614 }, { 294, 8051, -432, -1518 }, { -665, 10337, 547, -2852 }, { 1168, 11989, -492, -5427 }, { 1344, 6416, 302, -5061 }, { -1727, 12264, 1507, -4543 }, { 674, 10889, -902, -3605 }, { -582, 9504, 300, -3618 }, { 641, 7654, 689, -2109 }, { 2065, 9243, 508, -4367 }, { 1055, 8373, 688, -3144 }, { -641, 8185, 986, -3307 }, { 1120, 7426, 1785, -3757 }, { 1660, 8070, -593, -3104 }, { 2002, 9467, -1722, -3475 }, { 2361, 8368, 100, -3709 }, { -772, 7845, -613, -4988 }, { 1485, 7430, 1896, -6127 }, { -432, 7823, -947, -2882 }, { 313, 11122, -760, -4871 }, { 412, 8412, -283, -4231 }, { 1585, 10402, -1884, -3267 }, { 321, 6952, 773, -3016 }, { -105, 9014, 121, -2249 }, { 1585, 10313, -977, -4812 }, { 1619, 11869, 1306, -6876 }, { -1168, 8886, -81, -2500 }, { -395, 10886, 733, -6490 }, { -4949, 4274, 3992, -1054 }, { -4241, 5299, 4262, -1584 }, { -2710, 3862, 4552, -1673 }, { -4608, 2472, 3672, -1715 }, { -2843, 2816, 4003, -2326 }, { -5229, 2964, 5636, 90 }, { -4924, 3442, 5015, -1096 }, { -1281, 3313, 5537, -2066 }, { -3808, 1939, 4351, -919 }, { -1915, 2585, 4939, -1614 }, { -3470, 1843, 5562, -682 }, { -3800, 870, 5827, 144 }, { -4985, 1452, 4728, -709 }, { -3745, 2750, 7220, 259 }, { -1875, 1900, 6514, -826 }, { -4329, 1574, 7192, 1304 }, { -5408, 1444, 6208, 631 }, { -3327, 5312, 5707, -1541 }, { -6966, 3334, 4034, 1028 }, { -7484, 4245, 4218, -212 }, { -6567, 5839, 4539, -512 }, { -5715, 5935, 3747, -1186 }, { -6410, 4881, 3356, -1610 }, { -5146, 2590, 2850, 2172 }, { -5196, 4095, 2569, -373 }, { -5043, 6025, 4318, 692 }, { -5525, 4884, 3513, 370 }, { -6804, 7533, 5812, -488 }, { -5657, 2480, 4061, 1234 }, { -3155, 1472, 6071, 1188 }, { -3427, 5217, 3442, 858 }, { -4698, 3013, 5517, 2586 }, { -4449, 2226, 5418, 3580 }, { -6395, 3547, 5487, 2028 }, { -3500, 5019, 4787, 1 }, { -4038, 2578, 3073, 3151 }, { -2750, 1955, 4469, 3856 }, { -5696, 1659, 6118, 2469 }, { -4350, 1241, 6840, 3126 }, { -5565, 5058, 5196, 1314 }, { -1642, 4190, 3948, 607 }, { -1233, 4108, 4850, -640 }, { -997, 3428, 3239, 1378 }, { -6488, 2741, 6926, 2792 }, { -4188, 3763, 4235, 2018 }, { -3210, 3224, 5646, 1427 }, { -5526, 6909, 5070, -627 }, { -2815, 3994, 3425, 1903 }, { -2163, 2734, 5423, 145 }, { -4149, 4247, 2355, 734 }, { -410, 2521, 4138, -16 }, { -2411, 2385, 4927, 2105 }, { -6077, 3591, 3114, 594 }, { -4186, 4834, 5926, -1004 }, { -7315, 3369, 5966, 448 }, { -7042, 5721, 5771, 238 }, { -4466, 3907, 3535, -1751 }, { -2116, 3970, 6163, -1392 }, { -7239, 2143, 8407, 3630 }, { -5431, 4486, 6486, -42 }, { -1874, 1617, 6333, 519 }, { -6478, 2629, 4634, -505 }, { -7784, 2342, 7216, 1365 }, { -1154, 1432, 4831, 1544 }, { -4964, -5801, 1797, 506 }, { -4436, -6905, 1059, -1237 }, { -5400, -6886, 884, -290 }, { -6259, -7103, 523, -227 }, { -4819, -6450, 1412, -450 }, { -4056, -6213, 1725, -943 }, { -5642, -6091, 1357, 605 }, { -4196, -5678, 2187, -173 }, { -4726, -5126, 2470, 321 }, { -6642, -5091, 1507, -1005 }, { -5304, -5250, 1944, 1579 }, { -7179, -5520, 1468, -425 }, { -6033, -4895, 1876, -955 }, { -6595, -5143, 2207, 1291 }, { -4224, -4943, 1846, 1792 }, { -7128, -6950, 539, 724 }, { -4369, -4901, 2590, 1103 }, { -7413, -5696, 1712, 1440 }, { -5885, -6821, 418, 871 }, { -6828, -5599, 710, -1563 }, { -6123, -5817, 1358, 1631 }, { -5291, -5622, 578, 2138 }, { -7171, -6004, 347, 2208 }, { -6083, -5251, 2132, 425 }, { -4329, -5721, 407, -2993 }, { -5326, -5056, 1119, -1837 }, { -5485, -5856, 185, -2389 }, { -6529, -5178, 403, -697 }, { -6719, -4412, 2726, 871 }, { -5126, -5629, 1835, -771 }, { -5622, -4361, 2973, 858 }, { -5282, -5895, 45, -335 }, { -4357, -5656, 1696, -1558 }, { -7139, -6659, 627, -409 }, { -4415, -6328, 35, 1306 }, { -7639, -6110, 1134, 197 }, { -3626, -5592, 2019, 901 }, { -3547, -5064, 1176, 1738 }, { -5075, -3899, 2087, 266 }, { -4086, -6311, 1479, 360 }, { -6210, -5220, -199, -1477 }, { -3910, -5063, 1356, -15 }, { -7616, -4977, 461, 2401 }, { -6118, -6131, 1258, -563 }, { -6127, -4968, 1286, -27 }, { -4121, -5852, 1113, 1476 }, { -5157, -4881, 1162, -662 }, { -4637, -5031, 1179, 709 }, { -5509, -5452, -397, 1224 }, { -4597, -6861, 646, 467 }, { -6247, -4043, 468, 278 }, { -5336, -6465, 874, -1472 }, { -6998, -6346, 78, -1798 }, { -4915, -4530, 2756, -203 }, { -6048, -4373, 1468, 1052 }, { -4273, -7100, 942, -323 }, { -6552, -4287, 2351, 69 }, { -6954, -4613, 722, 1521 }, { -4201, -5361, 763, -1562 }, { -6881, -5596, -748, 669 }, { -6695, -3547, -34, 1299 }, { -3981, -5728, 84, 111 }, { -4663, -4809, 2173, -1031 }, { -6599, -6077, 1303, 256 }, { -7596, -4265, -5791, -4140 }, { -6610, -2758, -5288, -3936 }, { -5880, -3865, -6563, -3088 }, { -7228, -5510, -7677, -3912 }, { -8854, -6553, -8318, -5361 }, { -9362, -5249, -6413, -4319 }, { -4418, -3110, -6368, -4358 }, { -5544, -4203, -6863, -5013 }, { -3056, -4316, -5567, -3181 }, { -3078, -5999, -5051, -2657 }, { -5884, -6292, -5756, -4013 }, { -4825, -4549, -5535, -4053 }, { -4443, -6126, -5316, -1368 }, { -3972, -6341, -6098, -2686 }, { -5751, -2781, -5398, -6230 }, { -4466, -6135, -5570, -3679 }, { -4291, -5992, -3564, -5189 }, { -7189, -4429, -7279, -6082 }, { -5076, -4433, -2748, -5366 }, { -6225, -2825, -6833, -5663 }, { -2989, -4792, -3960, -4492 }, { -7836, -7773, -7722, -5741 }, { -6559, -5703, -5844, -5589 }, { -7612, -5438, -4136, -3774 }, { -4218, -4176, -6591, -2333 }, { -4837, -5063, -6581, 322 }, { -6590, -5990, -2980, -3847 }, { -5558, -2971, -5489, -1932 }, { -7001, -5323, -4975, -1697 }, { -4694, -2688, -6904, -3044 }, { -8511, -5379, -5767, -2549 }, { -7548, -5412, -6522, -2572 }, { -6597, -4973, -6423, -1274 }, { -6415, -4022, -5168, -1072 }, { -5528, -5530, -7218, -2345 }, { -4845, -4805, -5943, -1227 }, { -6049, -7150, -6744, -2161 }, { -9061, -7299, -8542, -4375 }, { -5010, -5546, -5416, -82 }, { -4135, -4205, -5109, -3373 }, { -3311, -5869, -4007, -5061 }, { -5993, -6472, -3962, -4718 }, { -2966, -5832, -2821, -6305 }, { -4851, -5152, -2067, -3930 }, { -3620, -4441, -3362, -5836 }, { -4469, -5221, -4534, -5592 }, { -4022, -6335, -4321, -6107 }, { -4899, -4503, -3084, -3725 }, { -4490, -8276, -4620, -6236 }, { -6591, -4342, -7365, -4063 }, { -6498, -5057, -5553, 485 }, { -6060, -2714, -7093, -4144 }, { -6199, -7774, -7094, -4057 }, { -7536, -6424, -6415, -4265 }, { -7439, -2454, -6348, -4827 }, { -5333, -7565, -4417, -4639 }, { -4353, -7103, -4197, -2689 }, { -5229, -6549, -5129, -6804 }, { -6129, -7701, -5236, -4836 }, { -6797, -3983, -3884, -4406 }, { -6624, -4467, -4745, -5052 }, { -3324, -7596, -2720, -6553 }, { -5473, -6284, -1704, -4511 }, { -4131, -7263, -3180, -5196 }, { -7116, -5565, -3469, 685 }, { -6002, -6021, -3858, 576 }, { -3144, -8203, -1291, -434 }, { -6096, -7027, -4004, 1353 }, { -3943, -7709, -2344, -36 }, { -4510, -6767, -2642, 631 }, { -3657, -11541, -2570, -3984 }, { -5959, -8854, -1333, -867 }, { -6699, -8866, -1606, -344 }, { -3836, -7961, -2334, -2028 }, { -3430, -8045, -3037, -672 }, { -3868, -9184, -3635, -1819 }, { -4258, -9060, -2621, -1008 }, { -3595, -8693, -2022, -752 }, { -4573, -8048, -3166, -2622 }, { -4852, -7903, -1405, 256 }, { -4591, -7057, -1560, 965 }, { -6963, -7655, -980, 808 }, { -5179, -6641, -3356, 1196 }, { -7102, -6941, -2798, 2123 }, { -6867, -5834, -3320, -770 }, { -5977, -7369, -2500, -778 }, { -6160, -6400, -934, -2543 }, { -6741, -7608, -355, -1289 }, { -6856, -6466, -1433, -1643 }, { -4786, -6292, -4970, 376 }, { -5407, -8866, -2255, -400 }, { -3814, -6506, -1387, -3620 }, { -4998, -6137, -1200, -4092 }, { -5123, -9557, -2849, -1306 }, { -4259, -6444, -4395, -338 }, { -5221, -6810, -883, 1225 }, { -6137, -6215, -2165, 554 }, { -3895, -6557, -3176, -1829 }, { -3886, -8188, -87, -954 }, { -7243, -6707, -2216, -316 }, { -5592, -7606, 85, -432 }, { -3957, -7945, -504, -144 }, { -4617, -7624, 218, -312 }, { -4797, -8737, -844, -1051 }, { -4478, -8516, -1401, -454 }, { -4557, -7058, -302, -2332 }, { -6623, -7736, -271, -50 }, { -3157, -7532, -1111, -2207 }, { -3590, -7300, -1271, 517 }, { -4442, -7306, -507, 590 }, { -6458, -7524, -2807, 666 }, { -4991, -8466, -3363, -785 }, { -7474, -7541, -1056, -1839 }, { -7501, -8316, -938, -180 }, { -5329, -7739, -579, -2341 }, { -4549, -7063, -176, -3539 }, { -5191, -8612, -1504, -4250 }, { -3083, -7058, -2251, 32 }, { -4003, -7043, -1093, -791 }, { -5523, -8093, -678, -114 }, { -3022, -10265, -2070, -3109 }, { -3905, -6274, -182, -3652 }, { -3269, -9217, -551, -2650 }, { -3138, -9314, -1726, -1704 }, { -4420, -10339, -1744, -3459 }, { -4163, -8609, -2298, -4113 }, { -5566, -6505, -1241, -463 }, { -3130, -9746, -2352, -4884 }, { -7825, -3439, 1451, -1468 }, { -8451, -3318, 2360, -435 }, { -8462, -4130, 1438, -1024 }, { -9425, -4564, 1328, -689 }, { -11014, -3202, 2278, 2080 }, { -8269, -2761, -146, -440 }, { -7497, -2618, -166, 413 }, { -8250, -3060, 522, -2133 }, { -8365, -5366, 1347, -451 }, { -8589, -3979, 2943, 714 }, { -8111, -2572, 1272, -1748 }, { -7830, -5193, 605, -1484 }, { -8119, -4736, 2141, 256 }, { -7724, -4769, 1463, -812 }, { -7363, -3911, 2540, 4 }, { -7974, -3397, 2363, 1366 }, { -7359, -4204, 1752, -958 }, { -7622, -3505, 660, 916 }, { -9934, -3665, 3165, 828 }, { -8721, -4162, 62, 1718 }, { -9433, -4768, 2722, 1234 }, { -7960, -4496, 138, 1528 }, { -8198, -3454, -443, 631 }, { -7756, -2246, 655, 1137 }, { -8841, -3145, 1113, 829 }, { -7817, -3298, 1251, 230 }, { -9413, -2733, 323, -1862 }, { -9408, -4168, 1270, 1549 }, { -9037, -3892, -942, 283 }, { -8255, -3849, 1301, 1762 }, { -9057, -3987, -41, -682 }, { -9441, -4187, 2019, -111 }, { -9740, -3178, 1602, -871 }, { -8344, -2474, 1461, 1506 }, { -9752, -2925, 1996, 1243 }, { -9199, -3796, 180, 537 }, { -9060, -2405, 1140, -1562 }, { -9348, -2376, 309, -162 }, { -10786, -3182, -5, -1500 }, { -8142, -4540, -434, -826 }, { -7528, -2341, 1104, -73 }, { -9360, -2658, 3062, 56 }, { -8267, -2335, 2000, -1193 }, { -12169, -3154, 1287, -640 }, { -11398, -2120, 946, -1163 }, { -8940, -4559, 328, -1696 }, { -11025, -4213, 2813, 840 }, { -9224, -3581, 2224, 2039 }, { -8943, -3337, 1248, -1298 }, { -7900, -4042, 485, -2080 }, { -9221, -1947, 2191, -880 }, { -10762, -1800, 2516, -324 }, { -10095, -2238, 981, -1335 }, { -11908, -2808, 3255, 645 }, { -10640, -4105, 1283, -595 }, { -7663, -2863, 2467, -797 }, { -10712, -3854, 3710, 1538 }, { -10823, -2893, 1408, -801 }, { -9874, -3832, 256, -1638 }, { -10394, -3391, 2315, -94 }, { -11525, -4079, 4153, 2122 }, { -9546, -2088, 1541, 481 }, { -8731, -2433, 1042, 2160 }, { -7852, -3977, -1370, 1677 }, { 7072, -3420, 1398, -1741 }, { 6180, -1976, 1280, -3557 }, { 7692, -1793, 2844, -1700 }, { 8363, -1773, 3104, -2679 }, { 9213, -3266, 3756, -3542 }, { 9650, -2644, 1426, -1318 }, { 7712, -2796, 3686, -1975 }, { 7316, -3517, 2821, -622 }, { 7434, -2594, 2305, -2264 }, { 7237, -1797, 255, -3114 }, { 8663, -1983, 1338, -3056 }, { 6616, -952, 4059, -2652 }, { 8823, -1327, 1362, -1356 }, { 9938, -1722, 1287, -2362 }, { 7207, -1057, 1913, -1315 }, { 7508, -1585, 870, -1982 }, { 8217, -3680, 1417, -3170 }, { 8329, -2541, 1684, -585 }, { 8062, -2335, 252, -2800 }, { 8204, -4108, 3097, -2569 }, { 7701, -3367, 576, -3008 }, { 7350, -786, 2414, -2129 }, { 6948, -2568, 1607, -225 }, { 7684, -2387, 1308, -3449 }, { 8306, -3458, 2394, -1454 }, { 8438, -2781, 1043, -1362 }, { 9175, -2076, 2144, -1987 }, { 8347, -2709, 3489, -4301 }, { 5696, -2377, 2870, 851 }, { 8825, -1243, 2219, -2603 }, { 8801, -1614, 584, -2513 }, { 8413, -384, 1421, -2244 }, { 9228, -3050, 3279, -2164 }, { 6342, -2698, 3547, -107 }, { 10053, -2476, 2837, -3168 }, { 7439, -604, 3177, -3991 }, { 7749, -1064, 4329, -4855 }, { 8655, -2177, 2252, -3519 }, { 8490, -228, 1958, -3233 }, { 10513, -2968, 1911, -2340 }, { 8146, -862, 1884, -1723 }, { 7788, -666, 3004, -2891 }, { 7785, -1620, 4133, -3417 }, { 10262, -3731, 3455, -2971 }, { 8570, -905, 4519, -4649 }, { 9129, -2562, 463, -2465 }, { 9451, -3587, 1904, -3056 }, { 6549, -2236, 3010, -4523 }, { 7175, -2684, 2967, -3458 }, { 9872, -3278, 1054, -2472 }, { 9153, -931, 1217, -2565 }, { 8789, -3469, 753, -2568 }, { 6683, -3791, 1797, -3968 }, { 6801, -1977, 2311, -452 }, { 6336, -1572, 2612, -3264 }, { 7996, -1008, 730, -2964 }, { 7521, -1059, 1573, -3694 }, { 8148, -3973, 2600, -3572 }, { 7765, -1532, 2528, -3856 }, { 7404, -3918, 4472, -143 }, { 8894, -1398, 3299, -3685 }, { 5768, -2041, 1487, -637 }, { 5131, -2865, 2463, -811 }, { 6439, -1568, 3500, -1550 }, { -8878, -6798, -5319, -1452 }, { -6332, -9713, -3112, -990 }, { -8444, -6316, -3694, -687 }, { -6123, -10840, -3637, -4358 }, { -4784, -9580, -4577, -2581 }, { -6108, -10515, -4859, -2524 }, { -7605, -7518, -2327, -2797 }, { -9662, -8775, -2467, -2010 }, { -6494, -7523, -4715, -118 }, { -8290, -8982, -1672, -317 }, { -8798, -11051, -3888, -1426 }, { -6273, -6623, -6791, -142 }, { -8313, -7668, -2141, -1275 }, { -6453, -8412, -3589, -4102 }, { -6747, -7750, -5690, -2498 }, { -7814, -6693, -3174, -2446 }, { -10383, -10130, -3931, -2364 }, { -10606, -8467, -5539, -2772 }, { -9475, -6671, -3305, -2271 }, { -8982, -9457, -5635, -4005 }, { -10111, -7965, -6515, -4180 }, { -7301, -6479, -5364, 720 }, { -9543, -8999, -7921, -912 }, { -9534, -8562, -3469, -384 }, { -7601, -10344, -3205, -1127 }, { -8088, -8620, -4954, -2888 }, { -8202, -8406, -7038, -3775 }, { -7312, -8324, -3334, -1775 }, { -8566, -9262, -8071, -4174 }, { -7068, -11300, -5573, -2907 }, { -8295, -8952, -4366, -1544 }, { -11104, -10210, -2285, -384 }, { -5213, -7520, -5008, -1339 }, { -5889, -7940, -5987, -1385 }, { -10816, -8201, -4153, -1485 }, { -10277, -8919, -6315, -1652 }, { -5888, -10320, -3821, -1733 }, { -10497, -7181, -6083, -3032 }, { -7721, -9724, -6591, -5336 }, { -5688, -7894, -3486, -2552 }, { -10014, -10500, -3247, -820 }, { -6301, -8765, -4506, -2923 }, { -8261, -7847, -6213, -1552 }, { -10212, -7481, -8113, -3954 }, { -6938, -10874, -6074, -4703 }, { -7183, -10968, -4446, -1773 }, { -7120, -9193, -1966, -2509 }, { -6234, -9263, -2313, -4284 }, { -8503, -9857, -2429, -608 }, { -9372, -7844, -8391, -2120 }, { -7951, -7157, -6535, -11 }, { -7256, -9473, -2172, -660 }, { -10063, -9612, -2515, -15 }, { -6684, -9134, -6109, -4206 }, { -8204, -11932, -5220, -2306 }, { -9710, -6706, -4115, -3275 }, { -6855, -7078, -2409, -4447 }, { -7344, -7673, -4479, -4116 }, { -8851, -6842, -4927, -2948 }, { -8927, -10452, -5633, -2194 }, { -8627, -9002, -7176, -1575 }, { -8209, -9722, -7021, -3324 }, { -3770, -10249, -3623, -4816 }, { -8183, -7465, -4090, 646 }, { -8163, -7149, 200, 498 }, { -8289, -6266, 686, -206 }, { -10030, -6241, -1032, -1864 }, { -8793, -8327, -773, -169 }, { -9149, -6215, 969, -15 }, { -8303, -5859, -7, 2006 }, { -9682, -7283, 255, 1322 }, { -9293, -7227, 71, -231 }, { -8525, -6215, 287, -837 }, { -10477, -5379, 1159, 1449 }, { -10726, -7856, -130, 102 }, { -8694, -7461, -1210, 690 }, { -9367, -5324, 1103, 3170 }, { -10686, -8055, -831, 1633 }, { -9201, -6873, -2704, 2258 }, { -8421, -5358, -1405, 226 }, { -9066, -5830, -307, -1571 }, { -11150, -7381, -2746, -900 }, { -9978, -5925, -2006, -437 }, { -9464, -4741, -273, 1061 }, { -10543, -6684, -1113, 1660 }, { -10073, -5576, 1083, -269 }, { -8826, -5763, 1600, 1486 }, { -10445, -9071, -1253, -64 }, { -12085, -5799, 2, 769 }, { -12939, -6663, 1650, 1437 }, { -10932, -6434, -1252, -649 }, { -11650, -7826, -2053, 710 }, { -12122, -6733, -1889, -731 }, { -9093, -6095, -2463, -842 }, { -10977, -4364, 469, 420 }, { -11488, -6908, -521, 893 }, { -9669, -5478, -842, 337 }, { -10606, -5203, -632, -1361 }, { -10198, -6284, 1662, 1277 }, { -10135, -5292, 2435, 3493 }, { -11027, -6561, 655, 56 }, { -10977, -5030, 1127, -358 }, { -12766, -3986, 1348, -335 }, { -14244, -7731, 264, 317 }, { -15124, -10309, -508, 1447 }, { -12821, -8638, -608, 137 }, { -13076, -8693, -2852, -431 }, { -11156, -5546, -2252, -1600 }, { -8692, -7366, -819, -1223 }, { -12507, -9816, -1714, -121 }, { -10712, -6666, 544, 3349 }, { -12462, -5890, -2491, -2318 }, { -12468, -7226, 437, 232 }, { -11300, -5226, 2068, 687 }, { -11994, -8320, -626, 2728 }, { -12222, -5476, 1142, 18 }, { -10277, -8122, -2418, 2003 }, { -13418, -6115, -3563, -2802 }, { -14759, -9834, -1243, 21 }, { -13699, -5665, 1525, 507 }, { -16269, -9476, -701, 163 }, { -12677, -5437, -247, -1019 }, { -11827, -4295, -181, -1243 }, { -12847, -4496, 2984, 1123 }, { -13860, -7915, -1166, -547 }, { -12276, -8145, -2290, -1527 }, { -11417, -4830, 2983, 1854 }, { -11793, -6002, 1163, 1940 }, { 11443, -4920, -3235, 3151 }, { 11300, -6616, -1506, 1175 }, { 9198, -4628, -2060, 2390 }, { 10532, -4027, -643, 912 }, { 9902, -3573, -1606, 1327 }, { 9653, -3536, -2240, 1869 }, { 9948, -5171, -423, 2662 }, { 12316, -4004, -1989, 281 }, { 12125, -4800, -1265, -163 }, { 10650, -2617, -2337, 1462 }, { 9909, -4968, -2376, 916 }, { 12944, -4647, -1958, 460 }, { 12988, -5283, -1141, 41 }, { 12321, -2915, -3621, 1025 }, { 11449, -2894, -2728, 351 }, { 12087, -3041, -2002, -32 }, { 11558, -4031, -1343, -399 }, { 12983, -3740, -3516, 1245 }, { 12099, -2515, -2752, 225 }, { 12515, -3465, -2701, 550 }, { 14683, -5022, -5272, 2996 }, { 12260, -3383, -1215, -528 }, { 13810, -5422, -2443, 1166 }, { 13421, -5378, -1886, 721 }, { 12961, -4259, -2594, 796 }, { 12266, -2104, -4768, 1591 }, { 13523, -4710, -3045, 1342 }, { 12437, -2099, -5610, 2117 }, { 11850, -2183, -3497, 661 }, { 12275, -3936, -597, -697 }, { 12459, -5253, -517, -544 }, { 12835, -4094, -1322, -168 }, { 14360, -5677, -3305, 1859 }, { 13905, -4552, -4309, 2117 }, { 11559, -3412, -1847, -81 }, { 13379, -3167, -5764, 2746 }, { 11910, -1634, -4342, 1052 }, { 12662, -4742, 71, -974 }, { 13057, -3254, -4424, 1705 }, { 15046, -5706, -4851, 3019 }, { 14162, -4142, -5514, 2843 }, { 12764, -1845, -6684, 2888 }, { 13714, -2374, -7838, 3857 }, { 13295, -1663, -8293, 4073 }, { 10032, -4152, -3403, 1421 }, { 10942, -5386, -2222, 950 }, { 10532, -6385, -1750, 1925 }, { 10273, -5972, -1534, 643 }, { 10605, -4782, -1695, 27 }, { 10988, -5153, -1123, -341 }, { 11629, -5884, -1060, 48 }, { 10441, -4045, -2431, 311 }, { 10788, -3595, -4171, 1807 }, { 12110, -5686, -2127, 976 }, { 11746, -4773, -2639, 891 }, { 11541, -5299, -3031, 1732 }, { 11416, -2559, -5359, 2198 }, { 11583, -5376, -704, 677 }, { 10416, -3214, -3516, 872 }, { 9651, -5435, -1618, 3255 }, { 9973, -5133, -996, 3923 }, { 11707, -4643, -430, -796 }, { 10994, -2709, -3587, 2302 }, { 10716, -5118, -645, 270 }, { 14100, -10314, 1095, 1531 }, { 12944, -8049, 1105, -741 }, { 13276, -7035, -511, 274 }, { 14008, -7254, -283, 139 }, { 11594, -6536, -91, 1671 }, { 11732, -8645, 746, 15 }, { 14613, -7085, -1578, 1183 }, { 13083, -6224, -750, -4 }, { 13988, -6256, -1592, 820 }, { 14678, -8683, 441, 126 }, { 15571, -8872, -521, 1139 }, { 15642, -9533, 341, 697 }, { 15960, -9586, -168, 1121 }, { 15464, -10239, 1433, -1 }, { 14934, -7887, -1046, 1080 }, { 15252, -7630, -1899, 1628 }, { 15485, -8384, -1234, 1484 }, { 15962, -8638, -1815, 1931 }, { 16501, -10664, 398, 1167 }, { 16146, -10145, 411, 918 }, { 14573, -7475, -697, 601 }, { 14302, -7996, 28, 257 }, { 14769, -6792, -2286, 1574 }, { 14144, -6137, -2169, 1257 }, { 14770, -6271, -3111, 1933 }, { 14110, -8312, 1083, -531 }, { 15235, -6991, -2993, 2174 }, { 13222, -5805, 547, -891 }, { 14796, -8762, 1254, -246 }, { 16040, -9181, -1005, 1551 }, { 16487, -10086, -373, 1420 }, { 15077, -9479, 966, 51 }, { 13026, -6468, 932, -1080 }, { 12703, -6152, -33, -573 }, { 15641, -6810, -4128, 2874 }, { 13282, -7673, 1583, -1283 }, { 12373, -7150, 1512, -917 }, { 12992, -7751, -678, 783 }, { 10907, -6858, -313, 2597 }, { 13026, -8963, 125, 2152 }, { 12770, -9946, 1957, -505 }, { 12482, -6849, -1268, 833 }, { 13790, -6181, -138, -279 }, { 12709, -8382, 2044, 227 }, { 12244, -6630, 203, -457 }, { 14209, -6816, -1032, 632 }, { 15134, -8267, -288, 640 }, { 13619, -6157, -1090, 356 }, { 14044, -7413, 725, -484 }, { 12958, -7753, 2585, -1980 }, { 13188, -8396, 2306, -1558 }, { 14379, -9980, 2132, -688 }, { 14275, -9857, 1162, 179 }, { 13690, -8648, 1621, -889 }, { 11770, -6829, -746, 278 }, { 12732, -8202, 286, 90 }, { 13630, -10146, 1867, -207 }, { 12072, -8740, 1299, -645 }, { 12852, -9492, 1226, 62 }, { 11792, -7382, -54, -116 }, { 13779, -9014, 487, 351 }, { 11951, -7729, 121, 834 }, { 11970, -9781, 2276, -4 }, { 12680, -7984, 2787, -787 }, { 13300, -14488, 6408, -1927 }, { 13635, -15355, 9153, -3073 }, { 12804, -13566, 5517, -1625 }, { 16624, -10854, 1690, 28 }, { 20387, -18532, 6162, -261 }, { 16515, -12642, 3392, -519 }, { 15800, -11095, 2151, -202 }, { 16824, -11790, 1651, 599 }, { 17604, -13213, 2563, 538 }, { 17892, -14177, 3562, 147 }, { 16987, -11399, 869, 1052 }, { 17003, -12456, 2442, 265 }, { 21657, -21806, 9198, -1250 }, { 16825, -13341, 3980, -686 }, { 17525, -12714, 1887, 805 }, { 16419, -11034, 1216, 617 }, { 20931, -19939, 7469, -684 }, { 18452, -15390, 4573, -191 }, { 14778, -10077, 2841, -1209 }, { 17402, -13319, 3042, 160 }, { 19365, -17922, 7087, -1061 }, { 16298, -11941, 2810, -351 }, { 19087, -16176, 4775, -84 }, { 17666, -12289, 938, 1224 }, { 18581, -15894, 5132, -430 }, { 19823, -16717, 4142, 545 }, { 19960, -19423, 8400, -1492 }, { 18973, -16817, 5906, -594 }, { 19079, -15431, 3528, 503 }, { 16667, -12485, 4467, -1302 }, { 19791, -17797, 6196, -529 }, { 20005, -17606, 5354, -20 }, { 20123, -18599, 6886, -728 }, { 19068, -14805, 2394, 1105 }, { 14443, -13723, 5631, -2029 }, { 14730, -14231, 5631, -1450 }, { 16089, -15959, 7271, -2029 }, { 13473, -11200, 3236, -924 }, { 14413, -10902, 2347, -267 }, { 17666, -18662, 11381, -3496 }, { 14749, -11042, 3305, -275 }, { 15304, -10486, 1869, -240 }, { 14809, -12126, 3369, -616 }, { 16896, -16561, 7307, -1845 }, { 15782, -14336, 5380, -1264 }, { 16395, -15520, 6415, -1588 }, { 13681, -11114, 2584, -320 }, { 14244, -12326, 4480, -1632 }, { 15247, -13119, 4265, -898 }, { 13987, -12091, 3469, -597 }, { 13941, -12770, 4240, -839 }, { 13771, -13627, 5252, -1384 }, { 15010, -16074, 7592, -2249 }, { 15852, -17226, 8619, -2655 }, { 18921, -16916, 6875, -1501 }, { 14909, -11678, 2768, -295 }, { 18988, -18353, 8424, -2070 }, { 15457, -15080, 6218, -1513 }, { 14916, -15512, 6949, -1883 }, { 18108, -14702, 4681, -701 }, { 17600, -15733, 5616, -775 }, { 14070, -13683, 6472, -2626 }, { 13832, -11914, 5201, -2232 }, { 18846, -19009, 9192, -1961 }, { -11981, -10994, -6324, -2264 }, { -10976, -9047, -6546, -3828 }, { -11288, -10532, -7014, -4191 }, { -10139, -10189, -7799, -2688 }, { -10555, -9988, -9181, -2040 }, { -11596, -11339, -10022, -2707 }, { -13400, -13395, -11306, -4206 }, { -9774, -12281, -7466, -4133 }, { -10842, -13125, -8777, -4956 }, { -11964, -15082, -9779, -5095 }, { -9382, -10188, -9053, -4927 }, { -11562, -11296, -3651, -985 }, { -9287, -10083, -7918, -4069 }, { -12821, -16556, -11410, -6195 }, { -12628, -8959, -4521, -1113 }, { -13845, -11581, -3649, -681 }, { -12685, -10269, -5483, -1275 }, { -14988, -12874, -5107, -1189 }, { -13761, -11367, -6202, -1804 }, { -13225, -11249, -7820, -3354 }, { -14809, -11992, -3202, -312 }, { -15620, -15519, -10210, -3433 }, { -12954, -10200, -3139, -611 }, { -11536, -9981, -5284, -923 }, { -13034, -12417, -4612, -1098 }, { -16911, -15505, -6123, -1352 }, { -17396, -17685, -8330, -2171 }, { -14120, -10764, -2265, -99 }, { -12598, -7367, -5406, -3530 }, { -14143, -12793, -10909, -5226 }, { -14692, -16871, -11626, -5554 }, { -12581, -11197, -9194, -3837 }, { -16752, -16726, -9746, -2808 }, { -10600, -10358, -6560, -1227 }, { -14573, -13312, -8957, -3393 }, { -10172, -8463, -8579, -3387 }, { -11418, -12421, -5522, -1842 }, { -11855, -14204, -6669, -2625 }, { -13308, -8191, -3941, -2194 }, { -10007, -12266, -5022, -1811 }, { -13532, -15771, -9497, -3175 }, { -11760, -11148, -10339, -5529 }, { -12149, -12763, -11198, -3697 }, { -12029, -12119, -8555, -1792 }, { -16995, -19957, -11447, -3471 }, { -13144, -14504, -9988, -3191 }, { -9938, -11064, -6139, -3162 }, { -8873, -11550, -8294, -6550 }, { -9303, -13010, -6150, -2711 }, { -15463, -10469, -1766, -170 }, { -15985, -11693, -3007, -650 }, { -17142, -10671, -1434, 47 }, { -16063, -13858, -4817, -1058 }, { -19446, -19599, -9594, -2464 }, { -20076, -18744, -8313, -1889 }, { -15047, -16085, -7590, -2250 }, { -13481, -16195, -8552, -2998 }, { -13829, -14869, -6704, -1932 }, { -16357, -18484, -9802, -2959 }, { -10551, -8393, -9303, -5070 }, { -11345, -9156, -5641, -3107 }, { -13217, -13449, -9270, -4541 }, { -11988, -13732, -9995, -6374 }, { -11007, -9519, -5168, -4107 }, { 9930, -7858, 8061, -4375 }, { 8274, -7867, 5992, -2096 }, { 9692, -9675, 7621, -3670 }, { 9589, -8110, 6509, -3010 }, { 12617, -11976, 10122, -5360 }, { 11867, -8895, 7948, -5323 }, { 10388, -10482, 9234, -4324 }, { 8188, -8220, 7810, -2737 }, { 10407, -8787, 4806, -1930 }, { 10348, -8845, 9233, -6614 }, { 9422, -7091, 4820, -2878 }, { 9758, -9796, 5584, -2256 }, { 10188, -7994, 5347, -3343 }, { 11133, -7455, 4015, -2306 }, { 10676, -10744, 6093, -2629 }, { 11522, -12184, 7848, -3375 }, { 8805, -9883, 5317, -3071 }, { 9498, -9654, 6555, -3592 }, { 10488, -8008, 4066, -1252 }, { 11261, -8930, 6068, -2738 }, { 12180, -10397, 5027, -1531 }, { 9138, -8531, 3601, -1959 }, { 8107, -8380, 4970, -2061 }, { 9737, -13248, 6438, -2617 }, { 11178, -10423, 2622, -522 }, { 9572, -12372, 5199, -2019 }, { 12057, -12144, 4147, -1099 }, { 9047, -9925, 2516, -665 }, { 10790, -8030, 5882, -4386 }, { 7199, -8426, 6337, -2841 }, { 7778, -8285, 3529, -3442 }, { 7559, -10569, 3484, -1332 }, { 9404, -8115, 7484, -5541 }, { 7792, -11976, 5546, -2573 }, { 9313, -10264, 7661, -5195 }, { 6701, -10725, 4370, -1784 }, { 4918, -11361, 4507, -4527 }, { 5147, -12305, 3978, -5556 }, { 6525, -9899, 4481, -3129 }, { 7538, -12855, 6060, -4826 }, { 8659, -12111, 7159, -4430 }, { 8440, -11304, 4547, -1747 }, { 9216, -10918, 3507, -1195 }, { 6165, -9254, 4771, -4677 }, { 9163, -11019, 5637, -4935 }, { 13441, -11509, 6676, -2434 }, { 7912, -9398, 6663, -4048 }, { 11723, -13745, 8131, -4148 }, { 6065, -10257, 5005, -6327 }, { 11618, -12417, 5336, -1894 }, { 8891, -13924, 8407, -6131 }, { 9622, -12563, 7908, -5109 }, { 11479, -10315, 8349, -3991 }, { 11676, -14103, 6611, -2330 }, { 11951, -8953, 3829, -1550 }, { 10486, -8044, 10493, -5920 }, { 11801, -10769, 9763, -5305 }, { 6109, -8676, 5827, -1346 }, { 7030, -9611, 5624, -5761 }, { 12808, -12886, 8683, -4148 }, { 13213, -10464, 6381, -3189 }, { 11796, -13681, 10703, -6075 }, { 9639, -7949, 9625, -3944 }, { 8538, -6997, 5309, 453 } }; xine-lib-1.2/contrib/libdca/Makefile.am0000644000175000017500000000104014647725151015570 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) EXTRA_DIST = COPYING if ENABLE_DTS if !WITH_EXTERNAL_LIBDTS noinst_LTLIBRARIES = libdca.la endif endif libdca_la_SOURCES = \ bitstream.c \ bitstream.h \ dca_internal.h \ downmix.c \ parse.c \ tables.h \ tables_adpcm.h \ tables_fir.h \ tables_huffman.h \ tables_quantization.h \ tables_vq.h \ include/dca.h \ include/dts.h libdca_la_LIBADD = -lm libdca_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir)/include xine-lib-1.2/contrib/libdca/bitstream.h0000644000175000017500000000413514647725151015707 0ustar meme/* * bitstream.h * Copyright (C) 2004 Gildas Bazin * Copyright (C) 2000-2003 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef WORDS_BIGENDIAN # define swab32(x) (x) #else # define swab32(x)\ (((uint32_t)(((uint8_t*)&x)[0]) << 24u) | \ ((uint32_t)(((uint8_t*)&x)[1]) << 16u) | \ ((uint32_t)(((uint8_t*)&x)[2]) << 8u) | \ ((uint32_t)(((uint8_t*)&x)[3]))) #endif #ifdef WORDS_BIGENDIAN # define swable32(x)\ ((((uint8_t*)&x)[0] << 16) | (((uint8_t*)&x)[1] << 24) | \ (((uint8_t*)&x)[2]) | (((uint8_t*)&x)[3] << 8)) #else # define swable32(x)\ ((((uint32_t)x) >> 16) | (((uint32_t)x) << 16)) #endif void dca_bitstream_init (dca_state_t * state, uint8_t * buf, int word_mode, int endian_mode); uint32_t dca_bitstream_get_bh (dca_state_t * state, uint32_t num_bits); static inline uint32_t bitstream_get (dca_state_t * state, uint32_t num_bits) { uint32_t result; if (num_bits < state->bits_left) { result = (state->current_word << (32 - state->bits_left)) >> (32 - num_bits); state->bits_left -= num_bits; return result; } return dca_bitstream_get_bh (state, num_bits); } xine-lib-1.2/contrib/libdca/parse.c0000644000175000017500000012073514647725151015027 0ustar meme/* * parse.c * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include #include #include #ifndef M_PI #define M_PI 3.1415926535897932384626433832795029 #endif #include "dca.h" #include "dca_internal.h" #include "bitstream.h" #include "tables.h" #include "tables_huffman.h" #include "tables_quantization.h" #include "tables_adpcm.h" #include "tables_fir.h" #include "tables_vq.h" /* #define DEBUG_PARSE */ #if defined(HAVE_MEMALIGN) && !defined(__cplusplus) /* some systems have memalign() but no declaration for it */ void * memalign (size_t align, size_t size); #else /* assume malloc alignment is sufficient */ #define memalign(align,size) malloc (size) #endif static int decode_blockcode (int code, int levels, int *values); static void qmf_32_subbands (dca_state_t * state, int chans, double samples_in[32][8], sample_t *samples_out); static void lfe_interpolation_fir (int nDecimationSelect, int nNumDeciSample, double *samples_in, sample_t *samples_out, sample_t bias); static void pre_calc_cosmod( dca_state_t * state ); dca_state_t * dca_init (uint32_t mm_accel) { dca_state_t * state; int i; (void)mm_accel; state = (dca_state_t *) malloc (sizeof (dca_state_t)); if (state == NULL) return NULL; memset (state, 0, sizeof(dca_state_t)); state->samples = (sample_t *) memalign (16, 256 * 12 * sizeof (sample_t)); if (state->samples == NULL) { free (state); return NULL; } for (i = 0; i < 256 * 12; i++) state->samples[i] = 0; /* Pre-calculate cosine modulation coefficients */ pre_calc_cosmod( state ); state->downmixed = 1; return state; } sample_t * dca_samples (dca_state_t * state) { return state->samples; } int dca_blocks_num (dca_state_t * state) { /* 8 samples per subsubframe and per subband */ return state->sample_blocks / 8; } static int syncinfo (dca_state_t * state, int * flags, int * sample_rate, int * bit_rate, int * frame_length) { int frame_size; /* Sync code */ bitstream_get (state, 32); /* Frame type */ bitstream_get (state, 1); /* Samples deficit */ bitstream_get (state, 5); /* CRC present */ bitstream_get (state, 1); *frame_length = (bitstream_get (state, 7) + 1) * 32; if (*frame_length < 6 * 32) return 0; frame_size = bitstream_get (state, 14) + 1; if (frame_size < 96) return 0; if (!state->word_mode) frame_size = frame_size * 8 / 14 * 2; /* Audio channel arrangement */ *flags = bitstream_get (state, 6); if (*flags > 63) return 0; *sample_rate = bitstream_get (state, 4); if ((size_t)*sample_rate >= sizeof (dca_sample_rates) / sizeof (int)) return 0; *sample_rate = dca_sample_rates[ *sample_rate ]; if (!*sample_rate) return 0; *bit_rate = bitstream_get (state, 5); if ((size_t)*bit_rate >= sizeof (dca_bit_rates) / sizeof (int)) return 0; *bit_rate = dca_bit_rates[ *bit_rate ]; if (!*bit_rate) return 0; /* LFE */ bitstream_get (state, 10); if (bitstream_get (state, 2)) *flags |= DCA_LFE; return frame_size; } int dca_syncinfo (dca_state_t * state, uint8_t * buf, int * flags, int * sample_rate, int * bit_rate, int * frame_length) { /* * Look for sync code */ /* 14 bits and little endian bitstream */ if (buf[0] == 0xff && buf[1] == 0x1f && buf[2] == 0x00 && buf[3] == 0xe8 && (buf[4] & 0xf0) == 0xf0 && buf[5] == 0x07) { int frame_size; dca_bitstream_init (state, buf, 0, 0); frame_size = syncinfo (state, flags, sample_rate, bit_rate, frame_length); return frame_size; } /* 14 bits and big endian bitstream */ if (buf[0] == 0x1f && buf[1] == 0xff && buf[2] == 0xe8 && buf[3] == 0x00 && buf[4] == 0x07 && (buf[5] & 0xf0) == 0xf0) { int frame_size; dca_bitstream_init (state, buf, 0, 1); frame_size = syncinfo (state, flags, sample_rate, bit_rate, frame_length); return frame_size; } /* 16 bits and little endian bitstream */ if (buf[0] == 0xfe && buf[1] == 0x7f && buf[2] == 0x01 && buf[3] == 0x80) { int frame_size; dca_bitstream_init (state, buf, 1, 0); frame_size = syncinfo (state, flags, sample_rate, bit_rate, frame_length); return frame_size; } /* 16 bits and big endian bitstream */ if (buf[0] == 0x7f && buf[1] == 0xfe && buf[2] == 0x80 && buf[3] == 0x01) { int frame_size; dca_bitstream_init (state, buf, 1, 1); frame_size = syncinfo (state, flags, sample_rate, bit_rate, frame_length); return frame_size; } return 0; } int dca_frame (dca_state_t * state, uint8_t * buf, int * flags, level_t * level, sample_t bias) { int i, j; static const float adj_table[] = { 1.0, 1.1250, 1.2500, 1.4375 }; dca_bitstream_init (state, buf, state->word_mode, state->bigendian_mode); /* Sync code */ bitstream_get (state, 32); /* Frame header */ state->frame_type = bitstream_get (state, 1); state->samples_deficit = bitstream_get (state, 5) + 1; state->crc_present = bitstream_get (state, 1); state->sample_blocks = bitstream_get (state, 7) + 1; state->frame_size = bitstream_get (state, 14) + 1; state->amode = bitstream_get (state, 6); state->sample_rate = bitstream_get (state, 4); state->bit_rate = bitstream_get (state, 5); state->downmix = bitstream_get (state, 1); state->dynrange = bitstream_get (state, 1); state->timestamp = bitstream_get (state, 1); state->aux_data = bitstream_get (state, 1); state->hdcd = bitstream_get (state, 1); state->ext_descr = bitstream_get (state, 3); state->ext_coding = bitstream_get (state, 1); state->aspf = bitstream_get (state, 1); state->lfe = bitstream_get (state, 2); state->predictor_history = bitstream_get (state, 1); /* TODO: check CRC */ if (state->crc_present) state->header_crc = bitstream_get (state, 16); state->multirate_inter = bitstream_get (state, 1); state->version = bitstream_get (state, 4); state->copy_history = bitstream_get (state, 2); state->source_pcm_res = bitstream_get (state, 3); state->front_sum = bitstream_get (state, 1); state->surround_sum = bitstream_get (state, 1); state->dialog_norm = bitstream_get (state, 4); /* FIME: channels mixing levels */ state->clev = state->slev = 1; state->output = dca_downmix_init (state->amode, *flags, level, state->clev, state->slev); if (state->output < 0) return 1; if (state->lfe && (*flags & DCA_LFE)) state->output |= DCA_LFE; *flags = state->output; state->dynrng = state->level = MUL_C (*level, 2); state->bias = bias; state->dynrnge = 1; state->dynrngcall = NULL; #ifdef DEBUG_PARSE fprintf (stderr, "frame type: %i\n", state->frame_type); fprintf (stderr, "samples deficit: %i\n", state->samples_deficit); fprintf (stderr, "crc present: %i\n", state->crc_present); fprintf (stderr, "sample blocks: %i (%i samples)\n", state->sample_blocks, state->sample_blocks * 32); fprintf (stderr, "frame size: %i bytes\n", state->frame_size); fprintf (stderr, "amode: %i (%i channels)\n", state->amode, dca_channels[state->amode]); fprintf (stderr, "sample rate: %i (%i Hz)\n", state->sample_rate, dca_sample_rates[state->sample_rate]); fprintf (stderr, "bit rate: %i (%i bits/s)\n", state->bit_rate, dca_bit_rates[state->bit_rate]); fprintf (stderr, "downmix: %i\n", state->downmix); fprintf (stderr, "dynrange: %i\n", state->dynrange); fprintf (stderr, "timestamp: %i\n", state->timestamp); fprintf (stderr, "aux_data: %i\n", state->aux_data); fprintf (stderr, "hdcd: %i\n", state->hdcd); fprintf (stderr, "ext descr: %i\n", state->ext_descr); fprintf (stderr, "ext coding: %i\n", state->ext_coding); fprintf (stderr, "aspf: %i\n", state->aspf); fprintf (stderr, "lfe: %i\n", state->lfe); fprintf (stderr, "predictor history: %i\n", state->predictor_history); fprintf (stderr, "header crc: %i\n", state->header_crc); fprintf (stderr, "multirate inter: %i\n", state->multirate_inter); fprintf (stderr, "version number: %i\n", state->version); fprintf (stderr, "copy history: %i\n", state->copy_history); fprintf (stderr, "source pcm resolution: %i (%i bits/sample)\n", state->source_pcm_res, dca_bits_per_sample[state->source_pcm_res]); fprintf (stderr, "front sum: %i\n", state->front_sum); fprintf (stderr, "surround sum: %i\n", state->surround_sum); fprintf (stderr, "dialog norm: %i\n", state->dialog_norm); fprintf (stderr, "\n"); #endif /* Primary audio coding header */ state->subframes = bitstream_get (state, 4) + 1; if (state->subframes > DCA_SUBFRAMES_MAX) state->subframes = DCA_SUBFRAMES_MAX; state->prim_channels = bitstream_get (state, 3) + 1; if (state->prim_channels > DCA_PRIM_CHANNELS_MAX) state->prim_channels = DCA_PRIM_CHANNELS_MAX; #ifdef DEBUG_PARSE fprintf (stderr, "subframes: %i\n", state->subframes); fprintf (stderr, "prim channels: %i\n", state->prim_channels); #endif for (i = 0; i < state->prim_channels; i++) { state->subband_activity[i] = bitstream_get (state, 5) + 2; #ifdef DEBUG_PARSE fprintf (stderr, "subband activity: %i\n", state->subband_activity[i]); #endif if (state->subband_activity[i] > DCA_SUBBANDS) state->subband_activity[i] = DCA_SUBBANDS; } for (i = 0; i < state->prim_channels; i++) { state->vq_start_subband[i] = bitstream_get (state, 5) + 1; #ifdef DEBUG_PARSE fprintf (stderr, "vq start subband: %i\n", state->vq_start_subband[i]); #endif if (state->vq_start_subband[i] > DCA_SUBBANDS) state->vq_start_subband[i] = DCA_SUBBANDS; } for (i = 0; i < state->prim_channels; i++) { state->joint_intensity[i] = bitstream_get (state, 3); #ifdef DEBUG_PARSE fprintf (stderr, "joint intensity: %i\n", state->joint_intensity[i]); if (state->joint_intensity[i]) {fprintf (stderr, "JOINTINTENSITY\n");} #endif } for (i = 0; i < state->prim_channels; i++) { state->transient_huffman[i] = bitstream_get (state, 2); #ifdef DEBUG_PARSE fprintf (stderr, "transient mode codebook: %i\n", state->transient_huffman[i]); #endif } for (i = 0; i < state->prim_channels; i++) { state->scalefactor_huffman[i] = bitstream_get (state, 3); #ifdef DEBUG_PARSE fprintf (stderr, "scale factor codebook: %i\n", state->scalefactor_huffman[i]); #endif } for (i = 0; i < state->prim_channels; i++) { state->bitalloc_huffman[i] = bitstream_get (state, 3); /* There might be a way not to trash the whole frame, but for * now we must bail out or we will buffer overflow later. */ if (state->bitalloc_huffman[i] == 7) return 1; #ifdef DEBUG_PARSE fprintf (stderr, "bit allocation quantizer: %i\n", state->bitalloc_huffman[i]); #endif } /* Get codebooks quantization indexes */ for (i = 0; i < state->prim_channels; i++) { state->quant_index_huffman[i][0] = 0; /* Not transmitted */ state->quant_index_huffman[i][1] = bitstream_get (state, 1); } for (j = 2; j < 6; j++) for (i = 0; i < state->prim_channels; i++) state->quant_index_huffman[i][j] = bitstream_get (state, 2); for (j = 6; j < 11; j++) for (i = 0; i < state->prim_channels; i++) state->quant_index_huffman[i][j] = bitstream_get (state, 3); for (j = 11; j < 27; j++) for (i = 0; i < state->prim_channels; i++) state->quant_index_huffman[i][j] = 0; /* Not transmitted */ #ifdef DEBUG_PARSE for (i = 0; i < state->prim_channels; i++) { fprintf( stderr, "quant index huff:" ); for (j = 0; j < 11; j++) fprintf (stderr, " %i", state->quant_index_huffman[i][j]); fprintf (stderr, "\n"); } #endif /* Get scale factor adjustment */ for (j = 0; j < 11; j++) { for (i = 0; i < state->prim_channels; i++) state->scalefactor_adj[i][j] = 1; } for (i = 0; i < state->prim_channels; i++) { if (state->quant_index_huffman[i][1] == 0) { /* Transmitted only if quant_index_huffman=0 (Huffman code used) */ state->scalefactor_adj[i][1] = adj_table[bitstream_get (state, 2)]; } } for (j = 2; j < 6; j++) for (i = 0; i < state->prim_channels; i++) if (state->quant_index_huffman[i][j] < 3) { /* Transmitted only if quant_index_huffman < 3 */ state->scalefactor_adj[i][j] = adj_table[bitstream_get (state, 2)]; } for (j = 6; j < 11; j++) for (i = 0; i < state->prim_channels; i++) if (state->quant_index_huffman[i][j] < 7) { /* Transmitted only if quant_index_huffman < 7 */ state->scalefactor_adj[i][j] = adj_table[bitstream_get (state, 2)]; } #ifdef DEBUG_PARSE for (i = 0; i < state->prim_channels; i++) { fprintf (stderr, "scalefac adj:"); for (j = 0; j < 11; j++) fprintf (stderr, " %1.3f", state->scalefactor_adj[i][j]); fprintf (stderr, "\n"); } #endif if (state->crc_present) { /* Audio header CRC check */ bitstream_get (state, 16); } state->current_subframe = 0; state->current_subsubframe = 0; return 0; } static int dca_subframe_header (dca_state_t * state) { /* Primary audio coding side information */ int j, k; /* Subsubframe count */ state->subsubframes = bitstream_get (state, 2) + 1; #ifdef DEBUG_PARSE fprintf (stderr, "subsubframes: %i\n", state->subsubframes); #endif /* Partial subsubframe sample count */ state->partial_samples = bitstream_get (state, 3); #ifdef DEBUG_PARSE fprintf (stderr, "partial samples: %i\n", state->partial_samples); #endif /* Get prediction mode for each subband */ for (j = 0; j < state->prim_channels; j++) { for (k = 0; k < state->subband_activity[j]; k++) state->prediction_mode[j][k] = bitstream_get (state, 1); #ifdef DEBUG_PARSE fprintf (stderr, "prediction mode:"); for (k = 0; k < state->subband_activity[j]; k++) fprintf (stderr, " %i", state->prediction_mode[j][k]); fprintf (stderr, "\n"); #endif } /* Get prediction codebook */ for (j = 0; j < state->prim_channels; j++) { for (k = 0; k < state->subband_activity[j]; k++) { if (state->prediction_mode[j][k] > 0) { /* (Prediction coefficient VQ address) */ state->prediction_vq[j][k] = bitstream_get (state, 12); #ifdef DEBUG_PARSE fprintf (stderr, "prediction coefs: %f, %f, %f, %f\n", (double)adpcm_vb[state->prediction_vq[j][k]][0]/8192, (double)adpcm_vb[state->prediction_vq[j][k]][1]/8192, (double)adpcm_vb[state->prediction_vq[j][k]][2]/8192, (double)adpcm_vb[state->prediction_vq[j][k]][3]/8192); #endif } } } /* Bit allocation index */ for (j = 0; j < state->prim_channels; j++) { for (k = 0; k < state->vq_start_subband[j]; k++) { if (state->bitalloc_huffman[j] == 6) state->bitalloc[j][k] = bitstream_get (state, 5); else if (state->bitalloc_huffman[j] == 5) state->bitalloc[j][k] = bitstream_get (state, 4); else { state->bitalloc[j][k] = InverseQ (state, bitalloc_12[state->bitalloc_huffman[j]]); } if (state->bitalloc[j][k] > 26) { fprintf (stderr, "bitalloc index [%i][%i] too big (%i)\n", j, k, state->bitalloc[j][k]); return -1; } } #ifdef DEBUG_PARSE fprintf (stderr, "bitalloc index: "); for (k = 0; k < state->vq_start_subband[j]; k++) fprintf (stderr, "%2.2i ", state->bitalloc[j][k]); fprintf (stderr, "\n"); #endif } /* Transition mode */ for (j = 0; j < state->prim_channels; j++) { for (k = 0; k < state->subband_activity[j]; k++) { state->transition_mode[j][k] = 0; if (state->subsubframes > 1 && k < state->vq_start_subband[j] && state->bitalloc[j][k] > 0) { /* tmode cannot overflow since transient_huffman[j] < 4 */ state->transition_mode[j][k] = InverseQ (state, tmode[state->transient_huffman[j]]); } } #ifdef DEBUG_PARSE fprintf (stderr, "Transition mode:"); for (k = 0; k < state->subband_activity[j]; k++) fprintf (stderr, " %i", state->transition_mode[j][k]); fprintf (stderr, "\n"); #endif } /* Scale factors */ for (j = 0; j < state->prim_channels; j++) { const int *scale_table; int scale_sum; for (k = 0; k < state->subband_activity[j]; k++) { state->scale_factor[j][k][0] = 0; state->scale_factor[j][k][1] = 0; } if (state->scalefactor_huffman[j] == 6) scale_table = scale_factor_quant7; else scale_table = scale_factor_quant6; /* When huffman coded, only the difference is encoded */ scale_sum = 0; for (k = 0; k < state->subband_activity[j]; k++) { if (k >= state->vq_start_subband[j] || state->bitalloc[j][k] > 0) { if (state->scalefactor_huffman[j] < 5) { /* huffman encoded */ scale_sum += InverseQ (state, scales_129[state->scalefactor_huffman[j]]); } else if (state->scalefactor_huffman[j] == 5) { scale_sum = bitstream_get (state, 6); } else if (state->scalefactor_huffman[j] == 6) { scale_sum = bitstream_get (state, 7); } state->scale_factor[j][k][0] = scale_table[scale_sum]; } if (k < state->vq_start_subband[j] && state->transition_mode[j][k]) { /* Get second scale factor */ if (state->scalefactor_huffman[j] < 5) { /* huffman encoded */ scale_sum += InverseQ (state, scales_129[state->scalefactor_huffman[j]]); } else if (state->scalefactor_huffman[j] == 5) { scale_sum = bitstream_get (state, 6); } else if (state->scalefactor_huffman[j] == 6) { scale_sum = bitstream_get (state, 7); } state->scale_factor[j][k][1] = scale_table[scale_sum]; } } #ifdef DEBUG_PARSE fprintf (stderr, "Scale factor:"); for (k = 0; k < state->subband_activity[j]; k++) { if (k >= state->vq_start_subband[j] || state->bitalloc[j][k] > 0) fprintf (stderr, " %i", state->scale_factor[j][k][0]); if (k < state->vq_start_subband[j] && state->transition_mode[j][k]) fprintf (stderr, " %i(t)", state->scale_factor[j][k][1]); } fprintf (stderr, "\n"); #endif } /* Joint subband scale factor codebook select */ for (j = 0; j < state->prim_channels; j++) { /* Transmitted only if joint subband coding enabled */ if (state->joint_intensity[j] > 0) state->joint_huff[j] = bitstream_get (state, 3); } /* Scale factors for joint subband coding */ for (j = 0; j < state->prim_channels; j++) { int source_channel; /* Transmitted only if joint subband coding enabled */ if (state->joint_intensity[j] > 0) { int scale = 0; source_channel = state->joint_intensity[j] - 1; /* When huffman coded, only the difference is encoded * (is this valid as well for joint scales ???) */ for (k = state->subband_activity[j]; k < state->subband_activity[source_channel]; k++) { if (state->joint_huff[j] < 5) { /* huffman encoded */ scale = InverseQ (state, scales_129[state->joint_huff[j]]); } else if (state->joint_huff[j] == 5) { scale = bitstream_get (state, 6); } else if (state->joint_huff[j] == 6) { scale = bitstream_get (state, 7); } scale += 64; /* bias */ state->joint_scale_factor[j][k] = scale;/*joint_scale_table[scale];*/ } if (!(state->debug_flag & 0x02)) { fprintf (stderr, "Joint stereo coding not supported\n"); state->debug_flag |= 0x02; } #ifdef DEBUG_PARSE fprintf (stderr, "Joint scale factor index:\n"); for (k = state->subband_activity[j]; k < state->subband_activity[source_channel]; k++) fprintf (stderr, " %i", state->joint_scale_factor[j][k]); fprintf (stderr, "\n"); #endif } } /* Stereo downmix coefficients */ if (state->prim_channels > 2 && state->downmix) { for (j = 0; j < state->prim_channels; j++) { state->downmix_coef[j][0] = bitstream_get (state, 7); state->downmix_coef[j][1] = bitstream_get (state, 7); } } /* Dynamic range coefficient */ if (state->dynrange) state->dynrange_coef = bitstream_get (state, 8); /* Side information CRC check word */ if (state->crc_present) { bitstream_get (state, 16); } /* * Primary audio data arrays */ /* VQ encoded high frequency subbands */ for (j = 0; j < state->prim_channels; j++) { for (k = state->vq_start_subband[j]; k < state->subband_activity[j]; k++) { /* 1 vector -> 32 samples */ state->high_freq_vq[j][k] = bitstream_get (state, 10); #ifdef DEBUG_PARSE fprintf( stderr, "VQ index: %i\n", state->high_freq_vq[j][k] ); #endif } } /* Low frequency effect data */ if (state->lfe) { /* LFE samples */ int lfe_samples = 2 * state->lfe * state->subsubframes; double lfe_scale; for (j = lfe_samples; j < lfe_samples * 2; j++) { /* Signed 8 bits int */ state->lfe_data[j] = (signed int)(signed char)bitstream_get (state, 8); } /* Scale factor index */ state->lfe_scale_factor = scale_factor_quant7[bitstream_get (state, 8)]; /* Quantization step size * scale factor */ lfe_scale = 0.035 * state->lfe_scale_factor; for (j = lfe_samples; j < lfe_samples * 2; j++) state->lfe_data[j] *= lfe_scale; #ifdef DEBUG_PARSE fprintf (stderr, "LFE samples:\n"); for (j = lfe_samples; j < lfe_samples * 2; j++) fprintf (stderr, " %f", state->lfe_data[j]); fprintf (stderr, "\n"); #endif } return 0; } static int dca_subsubframe (dca_state_t * state) { int k, l; int subsubframe = state->current_subsubframe; const double *quant_step_table; /* FIXME */ double subband_samples[DCA_PRIM_CHANNELS_MAX][DCA_SUBBANDS][8]; /* * Audio data */ /* Select quantization step size table */ if (state->bit_rate == 0x1f) quant_step_table = lossless_quant_d; else quant_step_table = lossy_quant_d; for (k = 0; k < state->prim_channels; k++) { for (l = 0; l < state->vq_start_subband[k] ; l++) { int m; /* Select the mid-tread linear quantizer */ int abits = state->bitalloc[k][l]; double quant_step_size = quant_step_table[abits]; double rscale; /* * Determine quantization index code book and its type */ /* Select quantization index code book */ int sel = state->quant_index_huffman[k][abits]; /* Determine its type */ int q_type = 1; /* (Assume Huffman type by default) */ if (abits >= 11 || !bitalloc_select[abits][sel]) { /* Not Huffman type */ if (abits <= 7) q_type = 3; /* Block code */ else q_type = 2; /* No further encoding */ } if (abits == 0) q_type = 0; /* No bits allocated */ /* * Extract bits from the bit stream */ switch (q_type) { case 0: /* No bits allocated */ for (m=0; m<8; m++) subband_samples[k][l][m] = 0; break; case 1: /* Huffman code */ for (m=0; m<8; m++) subband_samples[k][l][m] = InverseQ (state, bitalloc_select[abits][sel]); break; case 2: /* No further encoding */ for (m=0; m<8; m++) { /* Extract (signed) quantization index */ int q_index = bitstream_get (state, abits - 3); if( q_index & (1 << (abits - 4)) ) { q_index = (1 << (abits - 3)) - q_index; q_index = -q_index; } subband_samples[k][l][m] = q_index; } break; case 3: /* Block code */ { int block_code1, block_code2, size, levels; int block[8]; switch (abits) { case 1: size = 7; levels = 3; break; case 2: size = 10; levels = 5; break; case 3: size = 12; levels = 7; break; case 4: size = 13; levels = 9; break; case 5: size = 15; levels = 13; break; case 6: size = 17; levels = 17; break; case 7: default: size = 19; levels = 25; break; } block_code1 = bitstream_get (state, size); /* Should test return value */ decode_blockcode (block_code1, levels, block); block_code2 = bitstream_get (state, size); decode_blockcode (block_code2, levels, &block[4]); for (m=0; m<8; m++) subband_samples[k][l][m] = block[m]; } break; default: /* Undefined */ fprintf (stderr, "Unknown quantization index codebook"); return -1; } /* * Account for quantization step and scale factor */ /* Deal with transients */ if (state->transition_mode[k][l] && subsubframe >= state->transition_mode[k][l]) rscale = quant_step_size * state->scale_factor[k][l][1]; else rscale = quant_step_size * state->scale_factor[k][l][0]; /* Adjustment */ rscale *= state->scalefactor_adj[k][sel]; for (m=0; m<8; m++) subband_samples[k][l][m] *= rscale; /* * Inverse ADPCM if in prediction mode */ if (state->prediction_mode[k][l]) { int n; for (m=0; m<8; m++) { for (n=1; n<=4; n++) if (m-n >= 0) subband_samples[k][l][m] += (adpcm_vb[state->prediction_vq[k][l]][n-1] * subband_samples[k][l][m-n]/8192); else if (state->predictor_history) subband_samples[k][l][m] += (adpcm_vb[state->prediction_vq[k][l]][n-1] * state->subband_samples_hist[k][l][m-n+4]/8192); } } } /* * Decode VQ encoded high frequencies */ for (l = state->vq_start_subband[k]; l < state->subband_activity[k]; l++) { /* 1 vector -> 32 samples but we only need the 8 samples * for this subsubframe. */ int m; if (!(state->debug_flag & 0x01)) { fprintf (stderr, "Stream with high frequencies VQ coding\n"); state->debug_flag |= 0x01; } for (m=0; m<8; m++) { subband_samples[k][l][m] = high_freq_vq[state->high_freq_vq[k][l]][subsubframe*8+m] * (double)state->scale_factor[k][l][0] / 16.0; } } } /* Check for DSYNC after subsubframe */ if (state->aspf || subsubframe == state->subsubframes - 1) { if (0xFFFF == bitstream_get (state, 16)) /* 0xFFFF */ { #ifdef DEBUG_PARSE fprintf( stderr, "Got subframe DSYNC\n" ); #endif } else { fprintf( stderr, "Didn't get subframe DSYNC\n" ); } } /* Backup predictor history for adpcm */ for (k = 0; k < state->prim_channels; k++) { for (l = 0; l < state->vq_start_subband[k] ; l++) { int m; for (m = 0; m < 4; m++) state->subband_samples_hist[k][l][m] = subband_samples[k][l][4+m]; } } /* 32 subbands QMF */ for (k = 0; k < state->prim_channels; k++) { qmf_32_subbands (state, k, subband_samples[k], &state->samples[256*k]); } /* Down/Up mixing */ if (state->prim_channels < dca_channels[state->output & DCA_CHANNEL_MASK]) { dca_upmix (state->samples, state->amode, state->output); } else if (state->prim_channels > dca_channels[state->output & DCA_CHANNEL_MASK]) { dca_downmix (state->samples, state->amode, state->output, state->bias, state->clev, state->slev); } else if (state->bias) { for ( k = 0; k < 256*state->prim_channels; k++ ) state->samples[k] += state->bias; } /* Generate LFE samples for this subsubframe FIXME!!! */ if (state->output & DCA_LFE) { int lfe_samples = 2 * state->lfe * state->subsubframes; int i_channels = dca_channels[state->output & DCA_CHANNEL_MASK]; lfe_interpolation_fir (state->lfe, 2 * state->lfe, state->lfe_data + lfe_samples + 2 * state->lfe * subsubframe, &state->samples[256*i_channels], state->bias); /* Outputs 20bits pcm samples */ } return 0; } static int dca_subframe_footer (dca_state_t * state) { int aux_data_count = 0, i; int lfe_samples; /* * Unpack optional information */ /* Time code stamp */ if (state->timestamp) bitstream_get (state, 32); /* Auxiliary data byte count */ if (state->aux_data) aux_data_count = bitstream_get (state, 6); /* Auxiliary data bytes */ for(i = 0; i < aux_data_count; i++) bitstream_get (state, 8); /* Optional CRC check bytes */ if (state->crc_present && (state->downmix || state->dynrange)) bitstream_get (state, 16); /* Backup LFE samples history */ lfe_samples = 2 * state->lfe * state->subsubframes; for (i = 0; i < lfe_samples; i++) { state->lfe_data[i] = state->lfe_data[i+lfe_samples]; } #ifdef DEBUG_PARSE fprintf( stderr, "\n" ); #endif return 0; } int dca_block (dca_state_t * state) { /* Sanity check */ if (state->current_subframe >= state->subframes) { fprintf (stderr, "check failed: %i>%i", state->current_subframe, state->subframes); return -1; } if (!state->current_subsubframe) { #ifdef DEBUG_PARSE fprintf (stderr, "DSYNC dca_subframe_header\n"); #endif /* Read subframe header */ if (dca_subframe_header (state)) return -1; } /* Read subsubframe */ #ifdef DEBUG_PARSE fprintf (stderr, "DSYNC dca_subsubframe\n"); #endif if (dca_subsubframe (state)) return -1; /* Update state */ state->current_subsubframe++; if (state->current_subsubframe >= state->subsubframes) { state->current_subsubframe = 0; state->current_subframe++; } if (state->current_subframe >= state->subframes) { #ifdef DEBUG_PARSE fprintf(stderr, "DSYNC dca_subframe_footer\n"); #endif /* Read subframe footer */ if (dca_subframe_footer (state)) return -1; } return 0; } /* Very compact version of the block code decoder that does not use table * look-up but is slightly slower */ int decode_blockcode( int code, int levels, int *values ) { int i; int offset = (levels - 1) >> 1; for (i = 0; i < 4; i++) { values[i] = (code % levels) - offset; code /= levels; } if (code == 0) return 1; else { fprintf (stderr, "ERROR: block code look-up failed\n"); return 0; } } static void pre_calc_cosmod( dca_state_t * state ) { int i, j, k; for (j=0,k=0;k<16;k++) for (i=0;i<16;i++) state->cos_mod[j++] = cos((2*i+1)*(2*k+1)*M_PI/64); for (k=0;k<16;k++) for (i=0;i<16;i++) state->cos_mod[j++] = cos((i)*(2*k+1)*M_PI/32); for (k=0;k<16;k++) state->cos_mod[j++] = 0.25/(2*cos((2*k+1)*M_PI/128)); for (k=0;k<16;k++) state->cos_mod[j++] = -0.25/(2.0*sin((2*k+1)*M_PI/128)); } static void qmf_32_subbands (dca_state_t * state, int chans, double samples_in[32][8], sample_t *samples_out) { static const double scale = 1.4142135623730951 /* sqrt(2) */ * 32768.0; const double *prCoeff; int i, j, k; double raXin[32]; double *subband_fir_hist = state->subband_fir_hist[chans]; double *subband_fir_hist2 = state->subband_fir_noidea[chans]; int nChIndex = 0, NumSubband = 32, nStart = 0, nEnd = 8, nSubIndex; /* Select filter */ if (!state->multirate_inter) /* Non-perfect reconstruction */ prCoeff = fir_32bands_nonperfect; else /* Perfect reconstruction */ prCoeff = fir_32bands_perfect; /* Reconstructed channel sample index */ for (nSubIndex=nStart; nSubIndexsubband_activity[chans]; i++) raXin[i] = samples_in[i][nSubIndex]; /* Clear inactive subbands */ for (i=state->subband_activity[chans]; icos_mod[j++]; } for (k=0;k<16;k++) { B[k] = 0.0; for (i=0;i<16;i++) { if(i>0) B[k]+=(raXin[2*i]+raXin[2*i-1])*state->cos_mod[j++]; else B[k]+=(raXin[2*i])*state->cos_mod[j++]; } SUM[k]=A[k]+B[k]; DIFF[k]=A[k]-B[k]; } /* Store history */ for (k=0;k<16;k++) subband_fir_hist[k]=state->cos_mod[j++]*SUM[k]; for (k=0;k<16;k++) subband_fir_hist[32-k-1]=state->cos_mod[j++]*DIFF[k]; /* Multiply by filter coefficients */ for (k=31,i=0;i<32;i++,k--) for (j=0;j<512;j+=64) subband_fir_hist2[i] += prCoeff[i+j]* (subband_fir_hist[i+j] - subband_fir_hist[j+k]); for (k=31,i=0;i<32;i++,k--) for (j=0;j<512;j+=64) subband_fir_hist2[32+i] += prCoeff[32+i+j]* (-subband_fir_hist[i+j] - subband_fir_hist[j+k]); /* Create 32 PCM output samples */ for (i=0;i<32;i++) samples_out[nChIndex++] = subband_fir_hist2[i] / scale; /* Update working arrays */ for (i=511;i>=32;i--) subband_fir_hist[i] = subband_fir_hist[i-32]; for (i=0;idynrange = 0; if (call) { state->dynrange = 1; state->dynrngcall = call; state->dynrngdata = data; } } void dca_free (dca_state_t * state) { free (state->samples); free (state); } xine-lib-1.2/contrib/libdca/downmix.c0000644000175000017500000004371214647725151015401 0ustar meme/* * downmix.c * Copyright (C) 2004 Gildas Bazin * Copyright (C) 2000-2003 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "dca.h" #include "dca_internal.h" #define CONVERT(acmod,output) (((output) << DCA_CHANNEL_BITS) + (acmod)) int dca_downmix_init (int input, int flags, level_t * level, level_t clev, level_t slev) { static const uint8_t table[11][10] = { /* DCA_MONO */ {DCA_MONO, DCA_MONO, DCA_MONO, DCA_MONO, DCA_MONO, DCA_MONO, DCA_MONO, DCA_MONO, DCA_MONO, DCA_MONO}, /* DCA_CHANNEL */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO}, /* DCA_STEREO */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO}, /* DCA_STEREO_SUMDIFF */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO}, /* DCA_STEREO_TOTAL */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO}, /* DCA_3F */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_3F, DCA_3F, DCA_3F, DCA_3F, DCA_3F}, /* DCA_2F1R */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_2F1R, DCA_2F1R, DCA_2F1R, DCA_2F1R, DCA_2F1R}, /* DCA_3F1R */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_3F, DCA_3F1R, DCA_3F1R, DCA_3F1R, DCA_3F1R}, /* DCA_2F2R */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_2F2R, DCA_2F2R, DCA_2F2R, DCA_2F2R}, /* DCA_3F2R */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_3F, DCA_3F2R, DCA_3F2R, DCA_3F2R, DCA_3F2R}, /* DCA_4F2R */ {DCA_MONO, DCA_CHANNEL, DCA_STEREO, DCA_STEREO, DCA_STEREO, DCA_4F2R, DCA_4F2R, DCA_4F2R, DCA_4F2R, DCA_4F2R}, }; int output; output = flags & DCA_CHANNEL_MASK; if (output > DCA_CHANNEL_MAX || input > 9) return -1; output = table[output][input]; if (output == DCA_STEREO && (input == DCA_DOLBY || (input == DCA_3F && clev == LEVEL (LEVEL_3DB)))) output = DCA_DOLBY; if (flags & DCA_ADJUST_LEVEL) { level_t adjust; switch (CONVERT (input & 7, output)) { case CONVERT (DCA_3F, DCA_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev); break; case CONVERT (DCA_STEREO, DCA_MONO): case CONVERT (DCA_2F2R, DCA_2F1R): case CONVERT (DCA_3F2R, DCA_3F1R): level_3db: adjust = LEVEL (LEVEL_3DB); break; case CONVERT (DCA_3F2R, DCA_2F1R): if (clev < LEVEL (LEVEL_PLUS3DB - 1)) goto level_3db; /* fall through */ case CONVERT (DCA_3F, DCA_STEREO): case CONVERT (DCA_3F1R, DCA_2F1R): case CONVERT (DCA_3F1R, DCA_2F2R): case CONVERT (DCA_3F2R, DCA_2F2R): adjust = DIV (1, LEVEL (1) + clev); break; case CONVERT (DCA_2F1R, DCA_MONO): adjust = DIV (LEVEL_PLUS3DB, LEVEL (2) + slev); break; case CONVERT (DCA_2F1R, DCA_STEREO): case CONVERT (DCA_3F1R, DCA_3F): adjust = DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB)); break; case CONVERT (DCA_3F1R, DCA_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5)); break; case CONVERT (DCA_3F1R, DCA_STEREO): adjust = DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB)); break; case CONVERT (DCA_2F2R, DCA_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + slev); break; case CONVERT (DCA_2F2R, DCA_STEREO): case CONVERT (DCA_3F2R, DCA_3F): adjust = DIV (1, LEVEL (1) + slev); break; case CONVERT (DCA_3F2R, DCA_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + slev); break; case CONVERT (DCA_3F2R, DCA_STEREO): adjust = DIV (1, LEVEL (1) + clev + slev); break; case CONVERT (DCA_MONO, DCA_DOLBY): adjust = LEVEL (LEVEL_PLUS3DB); break; case CONVERT (DCA_3F, DCA_DOLBY): case CONVERT (DCA_2F1R, DCA_DOLBY): adjust = LEVEL (1 / (1 + LEVEL_3DB)); break; case CONVERT (DCA_3F1R, DCA_DOLBY): case CONVERT (DCA_2F2R, DCA_DOLBY): adjust = LEVEL (1 / (1 + 2 * LEVEL_3DB)); break; case CONVERT (DCA_3F2R, DCA_DOLBY): adjust = LEVEL (1 / (1 + 3 * LEVEL_3DB)); break; default: return output; } *level = MUL_L (*level, adjust); } return output; } int dca_downmix_coeff (level_t * coeff, int acmod, int output, level_t level, level_t clev, level_t slev) { level_t level_3db; level_3db = MUL_C (level, LEVEL_3DB); switch (CONVERT (acmod, output & DCA_CHANNEL_MASK)) { case CONVERT (DCA_CHANNEL, DCA_CHANNEL): case CONVERT (DCA_MONO, DCA_MONO): case CONVERT (DCA_STEREO, DCA_STEREO): case CONVERT (DCA_3F, DCA_3F): case CONVERT (DCA_2F1R, DCA_2F1R): case CONVERT (DCA_3F1R, DCA_3F1R): case CONVERT (DCA_2F2R, DCA_2F2R): case CONVERT (DCA_3F2R, DCA_3F2R): case CONVERT (DCA_STEREO, DCA_DOLBY): coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level; return 0; case CONVERT (DCA_CHANNEL, DCA_MONO): coeff[0] = coeff[1] = MUL_C (level, LEVEL_6DB); return 3; case CONVERT (DCA_STEREO, DCA_MONO): coeff[0] = coeff[1] = level_3db; return 3; case CONVERT (DCA_3F, DCA_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); return 7; case CONVERT (DCA_2F1R, DCA_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (DCA_2F2R, DCA_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (DCA_3F1R, DCA_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (DCA_3F2R, DCA_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = MUL_C (MUL_L (level_3db, clev), LEVEL_PLUS6DB); coeff[3] = coeff[4] = MUL_L (level_3db, slev); return 31; case CONVERT (DCA_MONO, DCA_DOLBY): coeff[0] = level_3db; return 0; case CONVERT (DCA_3F, DCA_DOLBY): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = level_3db; return 7; case CONVERT (DCA_3F, DCA_STEREO): case CONVERT (DCA_3F1R, DCA_2F1R): case CONVERT (DCA_3F2R, DCA_2F2R): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = MUL_L (level, clev); return 7; case CONVERT (DCA_2F1R, DCA_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 7; case CONVERT (DCA_2F1R, DCA_STEREO): coeff[0] = coeff[1] = level; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (DCA_3F1R, DCA_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = level_3db; return 15; case CONVERT (DCA_3F1R, DCA_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (DCA_2F2R, DCA_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 15; case CONVERT (DCA_2F2R, DCA_STEREO): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = MUL_L (level, slev); return 15; case CONVERT (DCA_3F2R, DCA_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (DCA_3F2R, DCA_2F1R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (DCA_3F2R, DCA_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = MUL_L (level, slev); return 31; case CONVERT (DCA_3F1R, DCA_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = MUL_L (level_3db, slev); return 13; case CONVERT (DCA_3F2R, DCA_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = MUL_L (level, slev); return 29; case CONVERT (DCA_2F2R, DCA_2F1R): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 12; case CONVERT (DCA_3F2R, DCA_3F1R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = level_3db; return 24; case CONVERT (DCA_2F1R, DCA_2F2R): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 0; case CONVERT (DCA_3F1R, DCA_2F2R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = level_3db; return 7; case CONVERT (DCA_3F1R, DCA_3F2R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = level_3db; return 0; } return -1; /* NOTREACHED */ } static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias) { int i; for (i = 0; i < 256; i++) dest[i] += BIAS (src[i]); } static void mix3to1 (sample_t * samples, sample_t bias) { int i; for (i = 0; i < 256; i++) samples[i] += BIAS (samples[i + 256] + samples[i + 512]); } static void mix4to1 (sample_t * samples, sample_t bias) { int i; for (i = 0; i < 256; i++) samples[i] += BIAS (samples[i + 256] + samples[i + 512] + samples[i + 768]); } static void mix5to1 (sample_t * samples, sample_t bias) { int i; for (i = 0; i < 256; i++) samples[i] += BIAS (samples[i + 256] + samples[i + 512] + samples[i + 768] + samples[i + 1024]); } static void mix3to2 (sample_t * samples, sample_t bias) { int i; sample_t common; for (i = 0; i < 256; i++) { common = BIAS (samples[i]); samples[i] = samples[i + 256] + common; samples[i + 256] = samples[i + 512] + common; } } static void mix21to2 (sample_t * left, sample_t * right, sample_t bias) { int i; sample_t common; for (i = 0; i < 256; i++) { common = BIAS (right[i + 256]); left[i] += common; right[i] += common; } } static void mix21toS (sample_t * samples, sample_t bias) { int i; sample_t surround; for (i = 0; i < 256; i++) { surround = samples[i + 512]; samples[i] += BIAS (-surround); samples[i + 256] += BIAS (surround); } } static void mix31to2 (sample_t * samples, sample_t bias) { int i; sample_t common; for (i = 0; i < 256; i++) { common = BIAS (samples[i] + samples[i + 768]); samples[i] = samples[i + 256] + common; samples[i + 256] = samples[i + 512] + common; } } static void mix31toS (sample_t * samples, sample_t bias) { int i; sample_t common, surround; for (i = 0; i < 256; i++) { common = BIAS (samples[i]); surround = samples[i + 768]; samples[i] = samples[i + 256] + common - surround; samples[i + 256] = samples[i + 512] + common + surround; } } static void mix22toS (sample_t * samples, sample_t bias) { int i; sample_t surround; for (i = 0; i < 256; i++) { surround = samples[i + 512] + samples[i + 768]; samples[i] += BIAS (-surround); samples[i + 256] += BIAS (surround); } } static void mix32to2 (sample_t * samples, sample_t bias) { int i; sample_t common; for (i = 0; i < 256; i++) { common = BIAS (samples[i]); samples[i] = common + samples[i + 256] + samples[i + 768]; samples[i + 256] = common + samples[i + 512] + samples[i + 1024]; } } static void mix32toS (sample_t * samples, sample_t bias) { int i; sample_t common, surround; for (i = 0; i < 256; i++) { common = BIAS (samples[i]); surround = samples[i + 768] + samples[i + 1024]; samples[i] = samples[i + 256] + common - surround; samples[i + 256] = samples[i + 512] + common + surround; } } static void move2to1 (sample_t * src, sample_t * dest, sample_t bias) { int i; for (i = 0; i < 256; i++) dest[i] = BIAS (src[i] + src[i + 256]); } static void zero (sample_t * samples) { int i; for (i = 0; i < 256; i++) samples[i] = 0; } void dca_downmix (sample_t * samples, int acmod, int output, sample_t bias, level_t clev, level_t slev) { (void)clev; switch (CONVERT (acmod, output & DCA_CHANNEL_MASK)) { case CONVERT (DCA_CHANNEL, DCA_MONO): case CONVERT (DCA_STEREO, DCA_MONO): mix_2to1: mix2to1 (samples, samples + 256, bias); break; case CONVERT (DCA_2F1R, DCA_MONO): if (slev == 0) goto mix_2to1; /* fall through */ case CONVERT (DCA_3F, DCA_MONO): mix_3to1: mix3to1 (samples, bias); break; case CONVERT (DCA_3F1R, DCA_MONO): if (slev == 0) goto mix_3to1; /* fall through */ case CONVERT (DCA_2F2R, DCA_MONO): if (slev == 0) goto mix_2to1; /* fall through */ mix4to1 (samples, bias); break; case CONVERT (DCA_3F2R, DCA_MONO): if (slev == 0) goto mix_3to1; /* fall through */ mix5to1 (samples, bias); break; case CONVERT (DCA_MONO, DCA_DOLBY): memcpy (samples + 256, samples, 256 * sizeof (sample_t)); break; case CONVERT (DCA_3F, DCA_STEREO): case CONVERT (DCA_3F, DCA_DOLBY): mix_3to2: mix3to2 (samples, bias); break; case CONVERT (DCA_2F1R, DCA_STEREO): if (slev == 0) break; mix21to2 (samples, samples + 256, bias); break; case CONVERT (DCA_2F1R, DCA_DOLBY): mix21toS (samples, bias); break; case CONVERT (DCA_3F1R, DCA_STEREO): if (slev == 0) goto mix_3to2; /* fall through */ mix31to2 (samples, bias); break; case CONVERT (DCA_3F1R, DCA_DOLBY): mix31toS (samples, bias); break; case CONVERT (DCA_2F2R, DCA_STEREO): if (slev == 0) break; mix2to1 (samples, samples + 512, bias); mix2to1 (samples + 256, samples + 768, bias); break; case CONVERT (DCA_2F2R, DCA_DOLBY): mix22toS (samples, bias); break; case CONVERT (DCA_3F2R, DCA_STEREO): if (slev == 0) goto mix_3to2; /* fall through */ mix32to2 (samples, bias); break; case CONVERT (DCA_3F2R, DCA_DOLBY): mix32toS (samples, bias); break; case CONVERT (DCA_3F1R, DCA_3F): if (slev == 0) break; mix21to2 (samples, samples + 512, bias); break; case CONVERT (DCA_3F2R, DCA_3F): if (slev == 0) break; mix2to1 (samples, samples + 768, bias); mix2to1 (samples + 512, samples + 1024, bias); break; case CONVERT (DCA_3F1R, DCA_2F1R): mix3to2 (samples, bias); memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); break; case CONVERT (DCA_2F2R, DCA_2F1R): mix2to1 (samples + 512, samples + 768, bias); break; case CONVERT (DCA_3F2R, DCA_2F1R): mix3to2 (samples, bias); move2to1 (samples + 768, samples + 512, bias); break; case CONVERT (DCA_3F2R, DCA_3F1R): mix2to1 (samples + 768, samples + 1024, bias); break; case CONVERT (DCA_2F1R, DCA_2F2R): memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t)); break; case CONVERT (DCA_3F1R, DCA_2F2R): mix3to2 (samples, bias); memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); break; case CONVERT (DCA_3F2R, DCA_2F2R): mix3to2 (samples, bias); memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t)); break; case CONVERT (DCA_3F1R, DCA_3F2R): memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t)); break; } } void dca_upmix (sample_t * samples, int acmod, int output) { switch (CONVERT (acmod, output & DCA_CHANNEL_MASK)) { case CONVERT (DCA_3F2R, DCA_MONO): zero (samples + 1024); /* fall through */ case CONVERT (DCA_3F1R, DCA_MONO): case CONVERT (DCA_2F2R, DCA_MONO): zero (samples + 768); /* fall through */ case CONVERT (DCA_3F, DCA_MONO): case CONVERT (DCA_2F1R, DCA_MONO): zero (samples + 512); /* fall through */ case CONVERT (DCA_CHANNEL, DCA_MONO): case CONVERT (DCA_STEREO, DCA_MONO): zero (samples + 256); break; case CONVERT (DCA_3F2R, DCA_STEREO): case CONVERT (DCA_3F2R, DCA_DOLBY): zero (samples + 1024); /* fall through */ case CONVERT (DCA_3F1R, DCA_STEREO): case CONVERT (DCA_3F1R, DCA_DOLBY): zero (samples + 768); /* fall through */ case CONVERT (DCA_3F, DCA_STEREO): case CONVERT (DCA_3F, DCA_DOLBY): mix_3to2: memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t)); zero (samples + 256); break; case CONVERT (DCA_2F2R, DCA_STEREO): case CONVERT (DCA_2F2R, DCA_DOLBY): zero (samples + 768); /* fall through */ case CONVERT (DCA_2F1R, DCA_STEREO): case CONVERT (DCA_2F1R, DCA_DOLBY): zero (samples + 512); break; case CONVERT (DCA_3F2R, DCA_3F): zero (samples + 1024); /* fall through */ case CONVERT (DCA_3F1R, DCA_3F): case CONVERT (DCA_2F2R, DCA_2F1R): zero (samples + 768); break; case CONVERT (DCA_3F2R, DCA_3F1R): zero (samples + 1024); break; case CONVERT (DCA_3F2R, DCA_2F1R): zero (samples + 1024); /* fall through */ case CONVERT (DCA_3F1R, DCA_2F1R): mix_31to21: memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t)); goto mix_3to2; case CONVERT (DCA_3F2R, DCA_2F2R): memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t)); goto mix_31to21; } } xine-lib-1.2/contrib/libdca/include/0000755000175000017500000000000014647725151015164 5ustar memexine-lib-1.2/contrib/libdca/include/dts.h0000644000175000017500000000351014647725151016126 0ustar meme/* * dts.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef LIBDCA_COMPAT_H # define LIBDCA_COMPAT_H 1 # include typedef struct dca_state_s dts_state_t; # define DTS_MONO DCA_MONO # define DTS_CHANNEL DCA_CHANNEL # define DTS_STEREO DCA_STEREO # define DTS_STEREO_SUMDIFF DCA_STEREO_SUMDIFF # define DTS_STEREO_TOTAL DCA_STEREO_TOTAL # define DTS_3F DCA_3F # define DTS_2F1R DCA_2F1R # define DTS_3F1R DCA_3F1R # define DTS_2F2R DCA_2F2R # define DTS_3F2R DCA_3F2R # define DTS_4F2R DCA_4F2R # define DTS_DOLBY DCA_DOLBY # define DTS_CHANNEL_MAX DCA_CHANNEL_MAX # define DTS_CHANNEL_BITS DCA_CHANNEL_BITS # define DTS_CHANNEL_MASK DCA_CHANNEL_MASK # define DTS_LFE DCA_LFE # define DTS_ADJUST_LEVEL DCA_ADJUST_LEVEL # define dts_init dca_init # define dts_syncinfo dca_syncinfo # define dts_frame dca_frame # define dts_dynrng dca_dynrng # define dts_blocks_num dca_blocks_num # define dts_block dca_block # define dts_samples dca_samples # define dts_free dca_free #endif xine-lib-1.2/contrib/libdca/include/dca.h0000644000175000017500000000461714647725151016074 0ustar meme/* * dca.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef LIBDCA_DCA_H #define LIBDCA_DCA_H /* x86 accelerations */ #define MM_ACCEL_X86_MMX 0x80000000 #define MM_ACCEL_X86_3DNOW 0x40000000 #define MM_ACCEL_X86_MMXEXT 0x20000000 uint32_t mm_accel (void); #if defined(LIBDCA_FIXED) typedef int32_t sample_t; typedef int32_t level_t; #elif defined(LIBDCA_DOUBLE) typedef double sample_t; typedef double level_t; #else typedef float sample_t; typedef float level_t; #endif typedef struct dca_state_s dca_state_t; #define DCA_MONO 0 #define DCA_CHANNEL 1 #define DCA_STEREO 2 #define DCA_STEREO_SUMDIFF 3 #define DCA_STEREO_TOTAL 4 #define DCA_3F 5 #define DCA_2F1R 6 #define DCA_3F1R 7 #define DCA_2F2R 8 #define DCA_3F2R 9 #define DCA_4F2R 10 #define DCA_DOLBY 101 /* FIXME */ #define DCA_CHANNEL_MAX DCA_3F2R /* We don't handle anything above that */ #define DCA_CHANNEL_BITS 6 #define DCA_CHANNEL_MASK 0x3F #define DCA_LFE 0x80 #define DCA_ADJUST_LEVEL 0x100 dca_state_t * dca_init (uint32_t mm_accel); int dca_syncinfo (dca_state_t *state, uint8_t * buf, int * flags, int * sample_rate, int * bit_rate, int *frame_length); int dca_frame (dca_state_t * state, uint8_t * buf, int * flags, level_t * level, sample_t bias); void dca_dynrng (dca_state_t * state, level_t (* call) (level_t, void *), void * data); int dca_blocks_num (dca_state_t * state); int dca_block (dca_state_t * state); sample_t * dca_samples (dca_state_t * state); void dca_free (dca_state_t * state); #endif /* LIBDCA_DCA_H */ xine-lib-1.2/contrib/libdca/tables.h0000644000175000017500000000307714647725151015173 0ustar meme/* * tables.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ static const int dca_sample_rates[] = { 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 96000, 192000 }; static const int dca_bit_rates[] = { 32000, 56000, 64000, 96000, 112000, 128000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000, 768000, 896000, 1024000, 1152000, 1280000, 1344000, 1408000, 1411200, 1472000, 1536000, 1920000, 2048000, 3072000, 3840000, 1/*open*/, 2/*variable*/, 3/*lossless*/ }; static const uint8_t dca_channels[] = { 1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8 }; static const uint8_t dca_bits_per_sample[] = { 16, 16, 20, 20, 0, 24, 24 }; xine-lib-1.2/contrib/libdca/tables_fir.h0000644000175000017500000012013214647725151016023 0ustar meme/* * fir.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ static const double fir_32bands_perfect[] = { +1.135985195E-010, -6.022448247E-007, +9.742954035E-007, +7.018770981E-011, -6.628192182E-007, +1.085227950E-006, -1.608403011E-008, -6.982898526E-007, +1.162929266E-006, -5.083275667E-008, -7.020648809E-007, +1.194632091E-006, -1.543309907E-007, -6.767839409E-007, +1.179182050E-006, -3.961981463E-007, -6.262345096E-007, +1.033426656E-006, -7.342250683E-007, -5.564140224E-007, +9.451737242E-007, -3.970030775E-007, +7.003467317E-007, +1.975324267E-006, -4.741137047E-007, +8.419976893E-007, +1.190443072E-006, +5.234479659E-007, +6.402664354E-008, -1.470520488E-006, +2.014677420E-007, -3.246264413E-008, -1.853591357E-006, +7.834767501E-008, -3.809887872E-008, +7.198007665E-007, +8.434094667E-008, +3.086857760E-006, -6.702406963E-010, +6.437721822E-008, +6.084746474E-006, -1.613285505E-009, +1.189317118E-006, +9.561075785E-006, -2.682709610E-009, +2.497214155E-006, +1.309637537E-005, -3.399493131E-009, +3.617151151E-006, +2.263354872E-005, +1.314406006E-008, +3.157242645E-006, +2.847247197E-005, +7.506701927E-009, +2.319611212E-006, +3.415624451E-005, +2.788728892E-008, +7.869333785E-006, +3.946387005E-005, +1.444918922E-007, +9.826449968E-006, +4.425736552E-005, +3.132386439E-007, +1.177108606E-005, +4.839275425E-005, +1.399798180E-006, +1.379448349E-005, +5.176846025E-005, +2.032118118E-006, +1.571428584E-005, +5.429694284E-005, +2.715013807E-006, +1.743183020E-005, +5.595519906E-005, +3.453840463E-006, +1.884208177E-005, +4.916387297E-006, +4.195037945E-006, +1.987093310E-005, +9.299508747E-006, +4.896494374E-006, +2.042970118E-005, +1.356193479E-005, +5.516381407E-006, -3.144468428E-005, +1.751866148E-005, +6.015239251E-006, -3.334947178E-005, +2.093936746E-005, +6.361419310E-006, -3.460439257E-005, +2.362549276E-005, +8.006985809E-006, -3.515914432E-005, +2.537086584E-005, +8.087732567E-006, -3.495384954E-005, +2.618136386E-005, +7.941360309E-006, -3.397853652E-005, +2.554462844E-005, +7.568834008E-006, -3.225446198E-005, +3.018750249E-005, +6.986399967E-006, -2.978993689E-005, +2.570833203E-005, +6.225028756E-006, -2.677291741E-005, +1.985177369E-005, +5.315936960E-006, -1.806914770E-005, +1.191342653E-005, +4.429412002E-006, -1.776598037E-005, +2.525620175E-006, +3.332600045E-006, -1.661818715E-005, -1.521241393E-005, +8.427224429E-007, -1.207003334E-005, -1.617751332E-005, +4.341498823E-007, -6.993315310E-006, +1.992636317E-005, +9.458596395E-008, -5.633860383E-007, +1.774702469E-005, +2.975164826E-008, -9.984935332E-007, +4.624524081E-005, +5.610509834E-005, -5.729619297E-004, +4.244441516E-004, +6.568001118E-005, -6.358824321E-004, +2.206075296E-004, +7.513730816E-005, -7.021900383E-004, -2.719412748E-007, +8.413690375E-005, -7.698345580E-004, -2.382978710E-004, +8.757545584E-005, -8.385353722E-004, -4.935106263E-004, +9.517164290E-005, -9.078957955E-004, -7.658848190E-004, +1.020687996E-004, -9.775133803E-004, -1.055365428E-003, +1.084438481E-004, -1.046945457E-003, -1.361547387E-003, +1.140582463E-004, -1.115717343E-003, -1.684492454E-003, +1.187910311E-004, -1.183370827E-003, -2.023874084E-003, +1.224978914E-004, -1.252829796E-003, -2.379294252E-003, +1.250260248E-004, -1.316190348E-003, -2.750317100E-003, +1.262027217E-004, -1.376571832E-003, -3.136433195E-003, +1.226499153E-004, -1.433344092E-003, -3.537061159E-003, +1.213575742E-004, -1.485876855E-003, -3.951539751E-003, +1.180980107E-004, -1.533520175E-003, -4.379155114E-003, +1.126275165E-004, -1.575609902E-003, -4.819062538E-003, +1.047207043E-004, -1.611457788E-003, -5.270531867E-003, +9.417100227E-005, -1.640390139E-003, -5.732392892E-003, +8.078388782E-005, -1.661288203E-003, -6.203945260E-003, +6.447290798E-005, -1.674512983E-003, -6.683901884E-003, +4.491530854E-005, -1.678415807E-003, -7.170005701E-003, +2.470704203E-005, -1.672798418E-003, -7.664063945E-003, -1.714242217E-006, -1.656501088E-003, -8.162760176E-003, -3.193307566E-005, -1.633993932E-003, -8.665001951E-003, -6.541742187E-005, -1.593449386E-003, -9.170533158E-003, -1.024175072E-004, +1.542080659E-003, -9.676489048E-003, -1.312203676E-004, +1.479332102E-003, -1.018219907E-002, -1.774113771E-004, +1.395521569E-003, -1.068630442E-002, -2.233728592E-004, +1.303116791E-003, -1.118756086E-002, -2.682086197E-004, +1.196175464E-003, -1.168460958E-002, -3.347633174E-004, +1.073757303E-003, -1.217562053E-002, -3.906481725E-004, +9.358961834E-004, -1.265939046E-002, -4.490280990E-004, +7.817269652E-004, -1.313448418E-002, -5.099929986E-004, +6.114174030E-004, -1.359948888E-002, -1.405300573E-002, +1.572482102E-002, +4.935106263E-004, -1.449365262E-002, +1.533095632E-002, +2.382978710E-004, -1.492007636E-002, +1.492007636E-002, +2.719412748E-007, -1.533095632E-002, +1.449365262E-002, -2.206075296E-004, -1.572482102E-002, +1.405300573E-002, -4.244441516E-004, -1.610082202E-002, +1.359948888E-002, -6.114174030E-004, -1.645756140E-002, +1.313448418E-002, -7.817269652E-004, -1.679391414E-002, +1.265939046E-002, -9.358961834E-004, -1.710879989E-002, +1.217562053E-002, -1.073757303E-003, -1.740120351E-002, +1.168460958E-002, -1.196175464E-003, -1.767017506E-002, +1.118756086E-002, -1.303116791E-003, -1.791484281E-002, +1.068630442E-002, -1.395521569E-003, -1.813439466E-002, +1.018219907E-002, -1.479332102E-003, -1.832821220E-002, +9.676489048E-003, -1.542080659E-003, -1.849545911E-002, +9.170533158E-003, +1.593449386E-003, -1.863567345E-002, +8.665001951E-003, +1.633993932E-003, -1.874836907E-002, +8.162760176E-003, +1.656501088E-003, -1.883326657E-002, +7.664063945E-003, +1.672798418E-003, -1.889026538E-002, +7.170005701E-003, +1.678415807E-003, -1.891860925E-002, +6.683901884E-003, +1.674512983E-003, +1.891860925E-002, +6.203945260E-003, +1.661288203E-003, +1.889026538E-002, +5.732392892E-003, +1.640390139E-003, +1.883326657E-002, +5.270531867E-003, +1.611457788E-003, +1.874836907E-002, +4.819062538E-003, +1.575609902E-003, +1.863567345E-002, +4.379155114E-003, +1.533520175E-003, +1.849545911E-002, +3.951539751E-003, +1.485876855E-003, +1.832821220E-002, +3.537061159E-003, +1.433344092E-003, +1.813439466E-002, +3.136433195E-003, +1.376571832E-003, +1.791484281E-002, +2.750317100E-003, +1.316190348E-003, +1.767017506E-002, +2.379294252E-003, +1.252829796E-003, +1.740120351E-002, +2.023874084E-003, +1.183370827E-003, +1.710879989E-002, +1.684492454E-003, +1.115717343E-003, +1.679391414E-002, +1.361547387E-003, +1.046945457E-003, +1.645756140E-002, +1.055365428E-003, +9.775133803E-004, +1.610082202E-002, +7.658848190E-004, +9.078957955E-004, +8.385353722E-004, -8.757545584E-005, -6.084746474E-006, +7.698345580E-004, -8.413690375E-005, -3.086857760E-006, +7.021900383E-004, -7.513730816E-005, -7.198007665E-007, +6.358824321E-004, -6.568001118E-005, +1.853591357E-006, +5.729619297E-004, -5.610509834E-005, +1.470520488E-006, +5.099929986E-004, -4.624524081E-005, +9.984935332E-007, +4.490280990E-004, -1.774702469E-005, +5.633860383E-007, +3.906481725E-004, -1.992636317E-005, +6.993315310E-006, +3.347633174E-004, +1.617751332E-005, +1.207003334E-005, +2.682086197E-004, +1.521241393E-005, +1.661818715E-005, +2.233728592E-004, -2.525620175E-006, +1.776598037E-005, +1.774113771E-004, -1.191342653E-005, +1.806914770E-005, +1.312203676E-004, -1.985177369E-005, +2.677291741E-005, +1.024175072E-004, -2.570833203E-005, +2.978993689E-005, +6.541742187E-005, -3.018750249E-005, +3.225446198E-005, +3.193307566E-005, -2.554462844E-005, +3.397853652E-005, +1.714242217E-006, -2.618136386E-005, +3.495384954E-005, -2.470704203E-005, -2.537086584E-005, +3.515914432E-005, -4.491530854E-005, -2.362549276E-005, +3.460439257E-005, -6.447290798E-005, -2.093936746E-005, +3.334947178E-005, -8.078388782E-005, -1.751866148E-005, +3.144468428E-005, -9.417100227E-005, -1.356193479E-005, -2.042970118E-005, -1.047207043E-004, -9.299508747E-006, -1.987093310E-005, -1.126275165E-004, -4.916387297E-006, -1.884208177E-005, -1.180980107E-004, -5.595519906E-005, -1.743183020E-005, -1.213575742E-004, -5.429694284E-005, -1.571428584E-005, -1.226499153E-004, -5.176846025E-005, -1.379448349E-005, -1.262027217E-004, -4.839275425E-005, -1.177108606E-005, -1.250260248E-004, -4.425736552E-005, -9.826449968E-006, -1.224978914E-004, -3.946387005E-005, -7.869333785E-006, -1.187910311E-004, -3.415624451E-005, -2.319611212E-006, -1.140582463E-004, -2.847247197E-005, -3.157242645E-006, -1.084438481E-004, -2.263354872E-005, -3.617151151E-006, -1.020687996E-004, -1.309637537E-005, -2.497214155E-006, -9.517164290E-005, -9.561075785E-006, -1.189317118E-006, -6.437721822E-008, -4.195037945E-006, -1.194632091E-006, -8.434094667E-008, -3.453840463E-006, -1.162929266E-006, +3.809887872E-008, -2.715013807E-006, -1.085227950E-006, +3.246264413E-008, -2.032118118E-006, -9.742954035E-007, -6.402664354E-008, -1.399798180E-006, -8.419976893E-007, -2.975164826E-008, -3.132386439E-007, -7.003467317E-007, -9.458596395E-008, -1.444918922E-007, +5.564140224E-007, -4.341498823E-007, -2.788728892E-008, +6.262345096E-007, -8.427224429E-007, -7.506701927E-009, +6.767839409E-007, -3.332600045E-006, -1.314406006E-008, +7.020648809E-007, -4.429412002E-006, +3.399493131E-009, +6.982898526E-007, -5.315936960E-006, +2.682709610E-009, +6.628192182E-007, -6.225028756E-006, +1.613285505E-009, +6.022448247E-007, -6.986399967E-006, +6.702406963E-010, +4.741137047E-007, -7.568834008E-006, -7.834767501E-008, +3.970030775E-007, -7.941360309E-006, -2.014677420E-007, +7.342250683E-007, -8.087732567E-006, -5.234479659E-007, +3.961981463E-007, -8.006985809E-006, -1.190443072E-006, +1.543309907E-007, -6.361419310E-006, -1.975324267E-006, +5.083275667E-008, -6.015239251E-006, -9.451737242E-007, +1.608403011E-008, -5.516381407E-006, -1.033426656E-006, -7.018770981E-011, -4.896494374E-006, -1.179182050E-006, -1.135985195E-010 }; static const double fir_32bands_nonperfect[] = { -1.390191784E-007, -1.693738625E-007, -2.030677564E-007, -2.404238444E-007, -2.818143514E-007, -3.276689142E-007, -3.784752209E-007, -4.347855338E-007, -4.972276315E-007, -5.665120852E-007, -6.434325428E-007, -7.288739425E-007, -8.238164355E-007, -9.293416952E-007, -1.046637067E-006, -1.176999604E-006, -1.321840614E-006, -1.482681114E-006, -1.661159786E-006, -1.859034001E-006, -2.078171747E-006, -2.320550948E-006, -2.588257530E-006, -2.883470643E-006, -3.208459020E-006, -3.565570978E-006, -3.957220997E-006, -4.385879038E-006, -4.854050530E-006, -5.364252502E-006, -5.918994248E-006, -6.520755960E-006, -7.171964626E-006, -7.874960829E-006, -8.631964192E-006, -9.445050637E-006, -1.031611009E-005, -1.124680875E-005, -1.223855270E-005, -1.329243969E-005, -1.440921824E-005, -1.558924305E-005, -1.683242772E-005, -1.813820381E-005, -1.950545993E-005, -2.093250441E-005, -2.241701623E-005, -2.395598858E-005, -2.554569073E-005, -2.718161704E-005, -2.885844333E-005, -3.056998685E-005, -3.230916263E-005, -3.406793985E-005, -3.583733633E-005, -3.760734762E-005, -3.936696885E-005, -4.110412556E-005, -4.280570283E-005, -4.445751256E-005, -4.604430433E-005, -4.754976908E-005, -4.895655002E-005, -5.024627535E-005, +5.139957648E-005, +5.239612074E-005, +5.321469871E-005, +5.383323878E-005, +5.422891263E-005, +5.437819709E-005, +5.425697600E-005, +5.384063843E-005, +5.310418419E-005, +5.202236207E-005, +5.056979353E-005, +4.872112549E-005, +4.645117951E-005, +4.373511547E-005, +4.054862075E-005, +3.686808850E-005, +3.267079956E-005, +2.793515523E-005, +2.264085742E-005, +1.676913780E-005, +1.030297699E-005, +3.227306706E-006, -4.470633485E-006, -1.280130618E-005, -2.177240640E-005, -3.138873581E-005, -4.165195787E-005, -5.256036457E-005, -6.410864444E-005, -7.628766616E-005, -8.908427117E-005, -1.024810626E-004, -1.164562127E-004, -1.309833024E-004, -1.460311323E-004, -1.615635992E-004, -1.775395358E-004, -1.939126523E-004, -2.106313768E-004, -2.276388550E-004, -2.448728774E-004, -2.622658503E-004, -2.797449124E-004, -2.972317743E-004, -3.146430245E-004, -3.318900708E-004, -3.488793736E-004, -3.655125911E-004, -3.816867538E-004, -3.972945851E-004, -4.122247046E-004, -4.263620067E-004, -4.395879805E-004, -4.517810594E-004, -4.628172028E-004, -4.725702747E-004, -4.809123348E-004, -4.877146275E-004, -4.928477574E-004, -4.961824161E-004, -4.975944757E-004, -4.969481961E-004, -4.941228544E-004, -4.889960401E-004, +4.814492422E-004, +4.713678791E-004, +4.586426076E-004, +4.431701091E-004, +4.248536134E-004, +4.036037717E-004, +3.793396754E-004, +3.519894381E-004, +3.214911267E-004, +2.877934603E-004, +2.508567995E-004, +2.106537577E-004, +1.671699720E-004, +1.204049113E-004, +7.037253090E-005, +1.710198012E-005, -3.936182839E-005, -9.895755647E-005, -1.616069785E-004, -2.272142592E-004, -2.956659591E-004, -3.668301215E-004, -4.405563814E-004, -5.166754709E-004, -5.949990009E-004, -6.753197522E-004, -7.574109477E-004, -8.410271257E-004, -9.259034996E-004, -1.011756598E-003, -1.098284614E-003, -1.185167348E-003, -1.272067428E-003, -1.358630019E-003, -1.444484224E-003, -1.529243193E-003, -1.612505526E-003, -1.693855622E-003, -1.772865304E-003, -1.849094522E-003, -1.922092517E-003, -1.991399564E-003, -2.056547208E-003, -2.117061289E-003, -2.172462177E-003, -2.222266514E-003, -2.265989315E-003, -2.303145360E-003, -2.333251061E-003, -2.355825622E-003, -2.370394068E-003, -2.376487479E-003, -2.373647178E-003, -2.361423569E-003, -2.339380793E-003, -2.307097195E-003, -2.264167881E-003, -2.210205887E-003, -2.144844970E-003, -2.067740774E-003, -1.978572691E-003, -1.877046190E-003, -1.762894331E-003, -1.635878929E-003, +1.495792647E-003, +1.342460280E-003, +1.175740734E-003, +9.955273708E-004, +8.017504588E-004, +5.943773431E-004, +3.734139318E-004, +1.389056415E-004, -1.090620208E-004, -3.703625989E-004, -6.448282511E-004, -9.322494152E-004, -1.232374110E-003, -1.544908970E-003, -1.869517611E-003, -2.205822384E-003, -2.553403843E-003, -2.911801683E-003, -3.280514618E-003, -3.659002949E-003, -4.046686925E-003, -4.442950245E-003, -4.847140983E-003, -5.258570891E-003, -5.676518660E-003, -6.100233644E-003, -6.528933067E-003, -6.961807609E-003, -7.398022339E-003, -7.836719044E-003, -8.277016692E-003, -8.718019351E-003, -9.158811532E-003, -9.598465636E-003, -1.003604382E-002, -1.047059800E-002, -1.090117730E-002, -1.132682897E-002, -1.174659748E-002, -1.215953380E-002, -1.256469358E-002, -1.296114177E-002, -1.334795821E-002, -1.372423489E-002, -1.408908330E-002, -1.444163360E-002, -1.478104480E-002, -1.510649733E-002, -1.541720331E-002, -1.571240649E-002, -1.599138230E-002, -1.625344716E-002, -1.649795473E-002, -1.672429405E-002, -1.693190821E-002, -1.712027565E-002, -1.728892699E-002, -1.743743755E-002, -1.756543480E-002, -1.767260395E-002, -1.775865816E-002, -1.782339066E-002, -1.786663756E-002, -1.788828894E-002, +1.788828894E-002, +1.786663756E-002, +1.782339066E-002, +1.775865816E-002, +1.767260395E-002, +1.756543480E-002, +1.743743755E-002, +1.728892699E-002, +1.712027565E-002, +1.693190821E-002, +1.672429405E-002, +1.649795473E-002, +1.625344716E-002, +1.599138230E-002, +1.571240649E-002, +1.541720331E-002, +1.510649733E-002, +1.478104480E-002, +1.444163360E-002, +1.408908330E-002, +1.372423489E-002, +1.334795821E-002, +1.296114177E-002, +1.256469358E-002, +1.215953380E-002, +1.174659748E-002, +1.132682897E-002, +1.090117730E-002, +1.047059800E-002, +1.003604382E-002, +9.598465636E-003, +9.158811532E-003, +8.718019351E-003, +8.277016692E-003, +7.836719044E-003, +7.398022339E-003, +6.961807609E-003, +6.528933067E-003, +6.100233644E-003, +5.676518660E-003, +5.258570891E-003, +4.847140983E-003, +4.442950245E-003, +4.046686925E-003, +3.659002949E-003, +3.280514618E-003, +2.911801683E-003, +2.553403843E-003, +2.205822384E-003, +1.869517611E-003, +1.544908970E-003, +1.232374110E-003, +9.322494152E-004, +6.448282511E-004, +3.703625989E-004, +1.090620208E-004, -1.389056415E-004, -3.734139318E-004, -5.943773431E-004, -8.017504588E-004, -9.955273708E-004, -1.175740734E-003, -1.342460280E-003, -1.495792647E-003, +1.635878929E-003, +1.762894331E-003, +1.877046190E-003, +1.978572691E-003, +2.067740774E-003, +2.144844970E-003, +2.210205887E-003, +2.264167881E-003, +2.307097195E-003, +2.339380793E-003, +2.361423569E-003, +2.373647178E-003, +2.376487479E-003, +2.370394068E-003, +2.355825622E-003, +2.333251061E-003, +2.303145360E-003, +2.265989315E-003, +2.222266514E-003, +2.172462177E-003, +2.117061289E-003, +2.056547208E-003, +1.991399564E-003, +1.922092517E-003, +1.849094522E-003, +1.772865304E-003, +1.693855622E-003, +1.612505526E-003, +1.529243193E-003, +1.444484224E-003, +1.358630019E-003, +1.272067428E-003, +1.185167348E-003, +1.098284614E-003, +1.011756598E-003, +9.259034996E-004, +8.410271257E-004, +7.574109477E-004, +6.753197522E-004, +5.949990009E-004, +5.166754709E-004, +4.405563814E-004, +3.668301215E-004, +2.956659591E-004, +2.272142592E-004, +1.616069785E-004, +9.895755647E-005, +3.936182839E-005, -1.710198012E-005, -7.037253090E-005, -1.204049113E-004, -1.671699720E-004, -2.106537577E-004, -2.508567995E-004, -2.877934603E-004, -3.214911267E-004, -3.519894381E-004, -3.793396754E-004, -4.036037717E-004, -4.248536134E-004, -4.431701091E-004, -4.586426076E-004, -4.713678791E-004, -4.814492422E-004, +4.889960401E-004, +4.941228544E-004, +4.969481961E-004, +4.975944757E-004, +4.961824161E-004, +4.928477574E-004, +4.877146275E-004, +4.809123348E-004, +4.725702747E-004, +4.628172028E-004, +4.517810594E-004, +4.395879805E-004, +4.263620067E-004, +4.122247046E-004, +3.972945851E-004, +3.816867538E-004, +3.655125911E-004, +3.488793736E-004, +3.318900708E-004, +3.146430245E-004, +2.972317743E-004, +2.797449124E-004, +2.622658503E-004, +2.448728774E-004, +2.276388550E-004, +2.106313768E-004, +1.939126523E-004, +1.775395358E-004, +1.615635992E-004, +1.460311323E-004, +1.309833024E-004, +1.164562127E-004, +1.024810626E-004, +8.908427117E-005, +7.628766616E-005, +6.410864444E-005, +5.256036457E-005, +4.165195787E-005, +3.138873581E-005, +2.177240640E-005, +1.280130618E-005, +4.470633485E-006, -3.227306706E-006, -1.030297699E-005, -1.676913780E-005, -2.264085742E-005, -2.793515523E-005, -3.267079956E-005, -3.686808850E-005, -4.054862075E-005, -4.373511547E-005, -4.645117951E-005, -4.872112549E-005, -5.056979353E-005, -5.202236207E-005, -5.310418419E-005, -5.384063843E-005, -5.425697600E-005, -5.437819709E-005, -5.422891263E-005, -5.383323878E-005, -5.321469871E-005, -5.239612074E-005, -5.139957648E-005, +5.024627535E-005, +4.895655002E-005, +4.754976908E-005, +4.604430433E-005, +4.445751256E-005, +4.280570283E-005, +4.110412556E-005, +3.936696885E-005, +3.760734762E-005, +3.583733633E-005, +3.406793985E-005, +3.230916263E-005, +3.056998685E-005, +2.885844333E-005, +2.718161704E-005, +2.554569073E-005, +2.395598858E-005, +2.241701623E-005, +2.093250441E-005, +1.950545993E-005, +1.813820381E-005, +1.683242772E-005, +1.558924305E-005, +1.440921824E-005, +1.329243969E-005, +1.223855270E-005, +1.124680875E-005, +1.031611009E-005, +9.445050637E-006, +8.631964192E-006, +7.874960829E-006, +7.171964626E-006, +6.520755960E-006, +5.918994248E-006, +5.364252502E-006, +4.854050530E-006, +4.385879038E-006, +3.957220997E-006, +3.565570978E-006, +3.208459020E-006, +2.883470643E-006, +2.588257530E-006, +2.320550948E-006, +2.078171747E-006, +1.859034001E-006, +1.661159786E-006, +1.482681114E-006, +1.321840614E-006, +1.176999604E-006, +1.046637067E-006, +9.293416952E-007, +8.238164355E-007, +7.288739425E-007, +6.434325428E-007, +5.665120852E-007, +4.972276315E-007, +4.347855338E-007, +3.784752209E-007, +3.276689142E-007, +2.818143514E-007, +2.404238444E-007, +2.030677564E-007, +1.693738625E-007, +1.390191784E-007 }; static const double lfe_fir_64[] = { 2.6584343868307770E-004, 8.1793652498163280E-005, 9.4393239123746760E-005, 1.0821702744578940E-004, 1.2333714403212070E-004, 1.3974857574794440E-004, 1.5759580128360540E-004, 1.7699223826639360E-004, 1.9817386055365200E-004, 2.2118473134469240E-004, 2.4602311896160240E-004, 2.7261159266345200E-004, 3.0138631700538100E-004, 3.3283955417573450E-004, 3.6589911906048660E-004, 4.0182814700528980E-004, 4.4018754852004350E-004, 4.8127761692740020E-004, 5.2524596685543660E-004, 5.7215924607589840E-004, 6.2221300322562460E-004, 6.7555153509601950E-004, 7.3241489008069040E-004, 7.9285167157649990E-004, 8.5701106581836940E-004, 9.2511920956894760E-004, 9.9747709464281800E-004, 1.0739302961155770E-003, 1.1550235794857140E-003, 1.2406768510118130E-003, 1.3312589144334200E-003, 1.4268938684836030E-003, 1.5278297942131760E-003, 1.6342115122824910E-003, 1.7463274998590350E-003, 1.8643775256350640E-003, 1.9886041991412640E-003, 2.1191518753767010E-003, 2.2563596721738580E-003, 2.4004334118217230E-003, 2.5515670422464610E-003, 2.7100932784378530E-003, 2.8761904686689380E-003, 3.0501529108732940E-003, 3.2322725746780640E-003, 3.4227769356220960E-003, 3.6219672765582800E-003, 3.8300913292914630E-003, 4.0474990382790560E-003, 4.2744171805679800E-003, 4.5111598446965220E-003, 4.7580120153725150E-003, 5.0153112970292570E-003, 5.2832840010523800E-003, 5.5623454973101620E-003, 5.8526843786239620E-003, 6.1547122895717620E-003, 6.4686913974583150E-003, 6.7949919030070300E-003, 7.1338820271193980E-003, 7.4857366271317010E-003, 7.8508658334612850E-003, 8.2296309992671010E-003, 8.6223213002085690E-003, 9.0293306857347480E-003, 9.4509534537792200E-003, 9.8875602707266800E-003, 1.0339494794607160E-002, 1.0807084850966930E-002, 1.1290682479739190E-002, 1.1790650896728040E-002, 1.2307321652770040E-002, 1.2841059826314450E-002, 1.3392185792326930E-002, 1.3961089774966240E-002, 1.4548087492585180E-002, 1.5153550542891020E-002, 1.5777811408042910E-002, 1.6421230509877200E-002, 1.7084129154682160E-002, 1.7766902223229410E-002, 1.8469827249646190E-002, 1.9193304702639580E-002, 1.9937623292207720E-002, 2.0703161135315900E-002, 2.1490212529897690E-002, 2.2299138829112050E-002, 2.3130238056182860E-002, 2.3983856663107870E-002, 2.4860285222530360E-002, 2.5759860873222350E-002, 2.6682861149311060E-002, 2.7629608288407320E-002, 2.8600392863154410E-002, 2.9595496132969860E-002, 3.0615204945206640E-002, 3.1659796833992000E-002, 3.2729536294937140E-002, 3.3824689686298370E-002, 3.4945506602525710E-002, 3.6092240363359450E-002, 3.7265110760927200E-002, 3.8464374840259550E-002, 3.9690230041742320E-002, 4.0942888706922530E-002, 4.2222552001476290E-002, 4.3529424816370010E-002, 4.4863656163215640E-002, 4.6225443482398990E-002, 4.7614917159080510E-002, 4.9032241106033330E-002, 5.0477534532547000E-002, 5.1950931549072270E-002, 5.3452525287866590E-002, 5.4982420057058330E-002, 5.6540694087743760E-002, 5.8127421885728840E-002, 5.9742655605077740E-002, 6.1386436223983760E-002, 6.3058786094188690E-002, 6.4759708940982820E-002, 6.6489234566688540E-002, 6.8247318267822270E-002, 7.0033922791481020E-002, 7.1849010884761810E-002, 7.3692522943019870E-002, 7.5564362108707430E-002, 7.7464438974857330E-002, 7.9392634332180020E-002, 8.1348828971385960E-002, 8.3332858979702000E-002, 8.5344567894935610E-002, 8.7383769452571870E-002, 8.9450262486934660E-002, 9.1543838381767280E-002, 9.3664251267910000E-002, 9.5811240375041960E-002, 9.7984537482261660E-002, 1.0018386691808700E-001, 1.0240890830755230E-001, 1.0465932637453080E-001, 1.0693479329347610E-001, 1.0923493653535840E-001, 1.1155936866998670E-001, 1.1390769481658940E-001, 1.1627949774265290E-001, 1.1867434531450270E-001, 1.2109176814556120E-001, 1.2353130429983140E-001, 1.2599244713783260E-001, 1.2847468256950380E-001, 1.3097748160362240E-001, 1.3350030779838560E-001, 1.3604259490966800E-001, 1.3860376179218290E-001, 1.4118319749832150E-001, 1.4378026127815250E-001, 1.4639437198638920E-001, 1.4902481436729430E-001, 1.5167096257209780E-001, 1.5433208644390100E-001, 1.5700751543045040E-001, 1.5969651937484740E-001, 1.6239835321903230E-001, 1.6511227190494540E-001, 1.6783750057220460E-001, 1.7057323455810550E-001, 1.7331869900226590E-001, 1.7607308924198150E-001, 1.7883554100990300E-001, 1.8160524964332580E-001, 1.8438133597373960E-001, 1.8716295063495640E-001, 1.8994916975498200E-001, 1.9273911416530610E-001, 1.9553191959857940E-001, 1.9832661747932440E-001, 2.0112232863903040E-001, 2.0391805469989780E-001, 2.0671287178993220E-001, 2.0950584113597870E-001, 2.1229594945907590E-001, 2.1508227288722990E-001, 2.1786379814147950E-001, 2.2063951194286350E-001, 2.2340846061706540E-001, 2.2616961598396300E-001, 2.2892196476459500E-001, 2.3166447877883910E-001, 2.3439615964889520E-001, 2.3711597919464110E-001, 2.3982289433479310E-001, 2.4251587688922880E-001, 2.4519388377666480E-001, 2.4785590171813960E-001, 2.5050088763237000E-001, 2.5312781333923340E-001, 2.5573557615280150E-001, 2.5832322239875800E-001, 2.6088967919349670E-001, 2.6343390345573420E-001, 2.6595494151115420E-001, 2.6845166087150580E-001, 2.7092313766479490E-001, 2.7336826920509340E-001, 2.7578607201576240E-001, 2.7817553281784060E-001, 2.8053569793701170E-001, 2.8286558389663700E-001, 2.8516408801078800E-001, 2.8743034601211550E-001, 2.8966337442398070E-001, 2.9186218976974480E-001, 2.9402589797973640E-001, 2.9615348577499390E-001, 2.9824411869049070E-001, 3.0029675364494320E-001, 3.0231067538261420E-001, 3.0428490042686460E-001, 3.0621853470802300E-001, 3.0811080336570740E-001, 3.0996081233024600E-001, 3.1176769733428960E-001, 3.1353080272674560E-001, 3.1524917483329780E-001, 3.1692212820053100E-001, 3.1854888796806340E-001, 3.2012873888015740E-001, 3.2166096568107600E-001, 3.2314485311508180E-001, 3.2457971572875980E-001, 3.2596495747566220E-001, 3.2729989290237420E-001, 3.2858389616012580E-001, 3.2981643080711360E-001, 3.3099696040153500E-001, 3.3212485909461980E-001, 3.3319962024688720E-001, 3.3422079682350160E-001, 3.3518791198730470E-001, 3.3610042929649360E-001, 3.3695802092552180E-001, 3.3776029944419860E-001, 3.3850681781768800E-001, 3.3919724822044380E-001, 3.3983129262924200E-001, 3.4040865302085880E-001, 3.4092903137207030E-001, 3.4139221906661980E-001, 3.4179797768592840E-001, 3.4214612841606140E-001, 3.4243649244308470E-001, 3.4266895055770880E-001, 3.4284341335296630E-001, 3.4295973181724550E-001, 3.4301793575286860E-001, 3.4301793575286860E-001, 3.4295973181724550E-001, 3.4284341335296630E-001, 3.4266895055770880E-001, 3.4243649244308470E-001, 3.4214612841606140E-001, 3.4179797768592840E-001, 3.4139221906661980E-001, 3.4092903137207030E-001, 3.4040865302085880E-001, 3.3983129262924200E-001, 3.3919724822044380E-001, 3.3850681781768800E-001, 3.3776029944419860E-001, 3.3695802092552180E-001, 3.3610042929649360E-001, 3.3518791198730470E-001, 3.3422079682350160E-001, 3.3319962024688720E-001, 3.3212485909461980E-001, 3.3099696040153500E-001, 3.2981643080711360E-001, 3.2858389616012580E-001, 3.2729989290237420E-001, 3.2596495747566220E-001, 3.2457971572875980E-001, 3.2314485311508180E-001, 3.2166096568107600E-001, 3.2012873888015740E-001, 3.1854888796806340E-001, 3.1692212820053100E-001, 3.1524917483329780E-001, 3.1353080272674560E-001, 3.1176769733428960E-001, 3.0996081233024600E-001, 3.0811080336570740E-001, 3.0621853470802300E-001, 3.0428490042686460E-001, 3.0231067538261420E-001, 3.0029675364494320E-001, 2.9824411869049070E-001, 2.9615348577499390E-001, 2.9402589797973640E-001, 2.9186218976974480E-001, 2.8966337442398070E-001, 2.8743034601211550E-001, 2.8516408801078800E-001, 2.8286558389663700E-001, 2.8053569793701170E-001, 2.7817553281784060E-001, 2.7578607201576240E-001, 2.7336826920509340E-001, 2.7092313766479490E-001, 2.6845166087150580E-001, 2.6595494151115420E-001, 2.6343390345573420E-001, 2.6088967919349670E-001, 2.5832322239875800E-001, 2.5573557615280150E-001, 2.5312781333923340E-001, 2.5050088763237000E-001, 2.4785590171813960E-001, 2.4519388377666480E-001, 2.4251587688922880E-001, 2.3982289433479310E-001, 2.3711597919464110E-001, 2.3439615964889520E-001, 2.3166447877883910E-001, 2.2892196476459500E-001, 2.2616961598396300E-001, 2.2340846061706540E-001, 2.2063951194286350E-001, 2.1786379814147950E-001, 2.1508227288722990E-001, 2.1229594945907590E-001, 2.0950584113597870E-001, 2.0671287178993220E-001, 2.0391805469989780E-001, 2.0112232863903040E-001, 1.9832661747932440E-001, 1.9553191959857940E-001, 1.9273911416530610E-001, 1.8994916975498200E-001, 1.8716295063495640E-001, 1.8438133597373960E-001, 1.8160524964332580E-001, 1.7883554100990300E-001, 1.7607308924198150E-001, 1.7331869900226590E-001, 1.7057323455810550E-001, 1.6783750057220460E-001, 1.6511227190494540E-001, 1.6239835321903230E-001, 1.5969651937484740E-001, 1.5700751543045040E-001, 1.5433208644390100E-001, 1.5167096257209780E-001, 1.4902481436729430E-001, 1.4639437198638920E-001, 1.4378026127815250E-001, 1.4118319749832150E-001, 1.3860376179218290E-001, 1.3604259490966800E-001, 1.3350030779838560E-001, 1.3097748160362240E-001, 1.2847468256950380E-001, 1.2599244713783260E-001, 1.2353130429983140E-001, 1.2109176814556120E-001, 1.1867434531450270E-001, 1.1627949774265290E-001, 1.1390769481658940E-001, 1.1155936866998670E-001, 1.0923493653535840E-001, 1.0693479329347610E-001, 1.0465932637453080E-001, 1.0240890830755230E-001, 1.0018386691808700E-001, 9.7984537482261660E-002, 9.5811240375041960E-002, 9.3664251267910000E-002, 9.1543838381767280E-002, 8.9450262486934660E-002, 8.7383769452571870E-002, 8.5344567894935610E-002, 8.3332858979702000E-002, 8.1348828971385960E-002, 7.9392634332180020E-002, 7.7464438974857330E-002, 7.5564362108707430E-002, 7.3692522943019870E-002, 7.1849010884761810E-002, 7.0033922791481020E-002, 6.8247318267822270E-002, 6.6489234566688540E-002, 6.4759708940982820E-002, 6.3058786094188690E-002, 6.1386436223983760E-002, 5.9742655605077740E-002, 5.8127421885728840E-002, 5.6540694087743760E-002, 5.4982420057058330E-002, 5.3452525287866590E-002, 5.1950931549072270E-002, 5.0477534532547000E-002, 4.9032241106033330E-002, 4.7614917159080510E-002, 4.6225443482398990E-002, 4.4863656163215640E-002, 4.3529424816370010E-002, 4.2222552001476290E-002, 4.0942888706922530E-002, 3.9690230041742320E-002, 3.8464374840259550E-002, 3.7265110760927200E-002, 3.6092240363359450E-002, 3.4945506602525710E-002, 3.3824689686298370E-002, 3.2729536294937140E-002, 3.1659796833992000E-002, 3.0615204945206640E-002, 2.9595496132969860E-002, 2.8600392863154410E-002, 2.7629608288407320E-002, 2.6682861149311060E-002, 2.5759860873222350E-002, 2.4860285222530360E-002, 2.3983856663107870E-002, 2.3130238056182860E-002, 2.2299138829112050E-002, 2.1490212529897690E-002, 2.0703161135315900E-002, 1.9937623292207720E-002, 1.9193304702639580E-002, 1.8469827249646190E-002, 1.7766902223229410E-002, 1.7084129154682160E-002, 1.6421230509877200E-002, 1.5777811408042910E-002, 1.5153550542891020E-002, 1.4548087492585180E-002, 1.3961089774966240E-002, 1.3392185792326930E-002, 1.2841059826314450E-002, 1.2307321652770040E-002, 1.1790650896728040E-002, 1.1290682479739190E-002, 1.0807084850966930E-002, 1.0339494794607160E-002, 9.8875602707266800E-003, 9.4509534537792200E-003, 9.0293306857347480E-003, 8.6223213002085690E-003, 8.2296309992671010E-003, 7.8508658334612850E-003, 7.4857366271317010E-003, 7.1338820271193980E-003, 6.7949919030070300E-003, 6.4686913974583150E-003, 6.1547122895717620E-003, 5.8526843786239620E-003, 5.5623454973101620E-003, 5.2832840010523800E-003, 5.0153112970292570E-003, 4.7580120153725150E-003, 4.5111598446965220E-003, 4.2744171805679800E-003, 4.0474990382790560E-003, 3.8300913292914630E-003, 3.6219672765582800E-003, 3.4227769356220960E-003, 3.2322725746780640E-003, 3.0501529108732940E-003, 2.8761904686689380E-003, 2.7100932784378530E-003, 2.5515670422464610E-003, 2.4004334118217230E-003, 2.2563596721738580E-003, 2.1191518753767010E-003, 1.9886041991412640E-003, 1.8643775256350640E-003, 1.7463274998590350E-003, 1.6342115122824910E-003, 1.5278297942131760E-003, 1.4268938684836030E-003, 1.3312589144334200E-003, 1.2406768510118130E-003, 1.1550235794857140E-003, 1.0739302961155770E-003, 9.9747709464281800E-004, 9.2511920956894760E-004, 8.5701106581836940E-004, 7.9285167157649990E-004, 7.3241489008069040E-004, 6.7555153509601950E-004, 6.2221300322562460E-004, 5.7215924607589840E-004, 5.2524596685543660E-004, 4.8127761692740020E-004, 4.4018754852004350E-004, 4.0182814700528980E-004, 3.6589911906048660E-004, 3.3283955417573450E-004, 3.0138631700538100E-004, 2.7261159266345200E-004, 2.4602311896160240E-004, 2.2118473134469240E-004, 1.9817386055365200E-004, 1.7699223826639360E-004, 1.5759580128360540E-004, 1.3974857574794440E-004, 1.2333714403212070E-004, 1.0821702744578940E-004, 9.4393239123746760E-005, 8.1793652498163280E-005, 2.6584343868307770E-004 }; static const double lfe_fir_128[] = { 0.00053168571, 0.00016358691, 0.00018878609, 0.00021643363, 0.00024667382, 0.00027949660, 0.00031519096, 0.00035398375, 0.00039634691, 0.00044236859, 0.00049204525, 0.00054522208, 0.00060277141, 0.00066567765, 0.00073179678, 0.00080365466, 0.00088037323, 0.00096255314, 0.00105048984, 0.00114431616, 0.00124442333, 0.00135110028, 0.00146482687, 0.00158570008, 0.00171401864, 0.00185023469, 0.00199495023, 0.00214785640, 0.00231004250, 0.00248134881, 0.00266251224, 0.00285378192, 0.00305565330, 0.00326841651, 0.00349264755, 0.00372874714, 0.00397720048, 0.00423829490, 0.00451271003, 0.00480085658, 0.00510312291, 0.00542017492, 0.00575236930, 0.00610029325, 0.00646453211, 0.00684553990, 0.00724391919, 0.00766016589, 0.00809498038, 0.00854881573, 0.00902230106, 0.00951600447, 0.01003060210, 0.01056654565, 0.01112466771, 0.01170534454, 0.01230939943, 0.01293735672, 0.01358995494, 0.01426773332, 0.01497144438, 0.01570170000, 0.01645922661, 0.01724460535, 0.01805862412, 0.01890186779, 0.01977507770, 0.02067894675, 0.02161412500, 0.02258131653, 0.02358125709, 0.02461459488, 0.02568206564, 0.02678431384, 0.02792212367, 0.02909611352, 0.03030703776, 0.03155555204, 0.03284239396, 0.03416819125, 0.03553372994, 0.03693958372, 0.03838652745, 0.03987516090, 0.04140623659, 0.04298033938, 0.04459818453, 0.04626038298, 0.04796761274, 0.04972046614, 0.05151961371, 0.05336561054, 0.05525910854, 0.05720067024, 0.05919086933, 0.06123027951, 0.06331945211, 0.06545893103, 0.06764923781, 0.06989086419, 0.07218432426, 0.07453006506, 0.07692859322, 0.07938029617, 0.08188561350, 0.08444493264, 0.08705867827, 0.08972713351, 0.09245070815, 0.09522963315, 0.09806428105, 0.10095486045, 0.10390164703, 0.10690483451, 0.10996460915, 0.11308115721, 0.11625462025, 0.11948505789, 0.12277261168, 0.12611730397, 0.12951917946, 0.13297818601, 0.13649433851, 0.14006754756, 0.14369773865, 0.14738474786, 0.15112841129, 0.15492856503, 0.15878495574, 0.16269733012, 0.16666537523, 0.17068879306, 0.17476719618, 0.17890018225, 0.18308731914, 0.18732811511, 0.19162209332, 0.19596865773, 0.20036731660, 0.20481738448, 0.20931822062, 0.21386915445, 0.21846942604, 0.22311829031, 0.22781492770, 0.23255851865, 0.23734821379, 0.24218304455, 0.24706205726, 0.25198432803, 0.25694879889, 0.26195442677, 0.26700007915, 0.27208462358, 0.27720692754, 0.28236576915, 0.28755992651, 0.29278811812, 0.29804900289, 0.30334126949, 0.30866351724, 0.31401440501, 0.31939238310, 0.32479602098, 0.33022382855, 0.33567428589, 0.34114575386, 0.34663668275, 0.35214546323, 0.35767036676, 0.36320972443, 0.36876192689, 0.37432509661, 0.37989753485, 0.38547745347, 0.39106300473, 0.39665243030, 0.40224379301, 0.40783521533, 0.41342487931, 0.41901078820, 0.42459106445, 0.43016362190, 0.43572667241, 0.44127810001, 0.44681602716, 0.45233830810, 0.45784294605, 0.46332800388, 0.46879136562, 0.47423094511, 0.47964480519, 0.48503074050, 0.49038675427, 0.49571081996, 0.50100076199, 0.50625455379, 0.51147013903, 0.51664537191, 0.52177828550, 0.52686679363, 0.53190881014, 0.53690224886, 0.54184508324, 0.54673534632, 0.55157101154, 0.55634999275, 0.56107026339, 0.56572991610, 0.57032698393, 0.57485944033, 0.57932555676, 0.58372318745, 0.58805054426, 0.59230577946, 0.59648692608, 0.60059231520, 0.60462015867, 0.60856848955, 0.61243581772, 0.61622029543, 0.61992025375, 0.62353414297, 0.62706029415, 0.63049703836, 0.63384294510, 0.63709646463, 0.64025616646, 0.64332056046, 0.64628833532, 0.64915806055, 0.65192854404, 0.65459835529, 0.65716648102, 0.65963155031, 0.66199249029, 0.66424828768, 0.66639786959, 0.66844022274, 0.67037439346, 0.67219948769, 0.67391467094, 0.67551922798, 0.67701220512, 0.67839306593, 0.67966115475, 0.68081587553, 0.68185669184, 0.68278300762, 0.68359452486, 0.68429082632, 0.68487155437, 0.68533653021, 0.68568539619, 0.68591803312, 0.68603444099, 0.68603444099, 0.68591803312, 0.68568539619, 0.68533653021, 0.68487155437, 0.68429082632, 0.68359452486, 0.68278300762, 0.68185669184, 0.68081587553, 0.67966115475, 0.67839306593, 0.67701220512, 0.67551922798, 0.67391467094, 0.67219948769, 0.67037439346, 0.66844022274, 0.66639786959, 0.66424828768, 0.66199249029, 0.65963155031, 0.65716648102, 0.65459835529, 0.65192854404, 0.64915806055, 0.64628833532, 0.64332056046, 0.64025616646, 0.63709646463, 0.63384294510, 0.63049703836, 0.62706029415, 0.62353414297, 0.61992025375, 0.61622029543, 0.61243581772, 0.60856848955, 0.60462015867, 0.60059231520, 0.59648692608, 0.59230577946, 0.58805054426, 0.58372318745, 0.57932555676, 0.57485944033, 0.57032698393, 0.56572991610, 0.56107026339, 0.55634999275, 0.55157101154, 0.54673534632, 0.54184508324, 0.53690224886, 0.53190881014, 0.52686679363, 0.52177828550, 0.51664537191, 0.51147013903, 0.50625455379, 0.50100076199, 0.49571081996, 0.49038675427, 0.48503074050, 0.47964480519, 0.47423094511, 0.46879136562, 0.46332800388, 0.45784294605, 0.45233830810, 0.44681602716, 0.44127810001, 0.43572667241, 0.43016362190, 0.42459106445, 0.41901078820, 0.41342487931, 0.40783521533, 0.40224379301, 0.39665243030, 0.39106300473, 0.38547745347, 0.37989753485, 0.37432509661, 0.36876192689, 0.36320972443, 0.35767036676, 0.35214546323, 0.34663668275, 0.34114575386, 0.33567428589, 0.33022382855, 0.32479602098, 0.31939238310, 0.31401440501, 0.30866351724, 0.30334126949, 0.29804900289, 0.29278811812, 0.28755992651, 0.28236576915, 0.27720692754, 0.27208462358, 0.26700007915, 0.26195442677, 0.25694879889, 0.25198432803, 0.24706205726, 0.24218304455, 0.23734821379, 0.23255851865, 0.22781492770, 0.22311829031, 0.21846942604, 0.21386915445, 0.20931822062, 0.20481738448, 0.20036731660, 0.19596865773, 0.19162209332, 0.18732811511, 0.18308731914, 0.17890018225, 0.17476719618, 0.17068879306, 0.16666537523, 0.16269733012, 0.15878495574, 0.15492856503, 0.15112841129, 0.14738474786, 0.14369773865, 0.14006754756, 0.13649433851, 0.13297818601, 0.12951917946, 0.12611730397, 0.12277261168, 0.11948505789, 0.11625462025, 0.11308115721, 0.10996460915, 0.10690483451, 0.10390164703, 0.10095486045, 0.09806428105, 0.09522963315, 0.09245070815, 0.08972713351, 0.08705867827, 0.08444493264, 0.08188561350, 0.07938029617, 0.07692859322, 0.07453006506, 0.07218432426, 0.06989086419, 0.06764923781, 0.06545893103, 0.06331945211, 0.06123027951, 0.05919086933, 0.05720067024, 0.05525910854, 0.05336561054, 0.05151961371, 0.04972046614, 0.04796761274, 0.04626038298, 0.04459818453, 0.04298033938, 0.04140623659, 0.03987516090, 0.03838652745, 0.03693958372, 0.03553372994, 0.03416819125, 0.03284239396, 0.03155555204, 0.03030703776, 0.02909611352, 0.02792212367, 0.02678431384, 0.02568206564, 0.02461459488, 0.02358125709, 0.02258131653, 0.02161412500, 0.02067894675, 0.01977507770, 0.01890186779, 0.01805862412, 0.01724460535, 0.01645922661, 0.01570170000, 0.01497144438, 0.01426773332, 0.01358995494, 0.01293735672, 0.01230939943, 0.01170534454, 0.01112466771, 0.01056654565, 0.01003060210, 0.00951600447, 0.00902230106, 0.00854881573, 0.00809498038, 0.00766016589, 0.00724391919, 0.00684553990, 0.00646453211, 0.00610029325, 0.00575236930, 0.00542017492, 0.00510312291, 0.00480085658, 0.00451271003, 0.00423829490, 0.00397720048, 0.00372874714, 0.00349264755, 0.00326841651, 0.00305565330, 0.00285378192, 0.00266251224, 0.00248134881, 0.00231004250, 0.00214785640, 0.00199495023, 0.00185023469, 0.00171401864, 0.00158570008, 0.00146482687, 0.00135110028, 0.00124442333, 0.00114431616, 0.00105048984, 0.00096255314, 0.00088037323, 0.00080365466, 0.00073179678, 0.00066567765, 0.00060277141, 0.00054522208, 0.00049204525, 0.00044236859, 0.00039634691, 0.00035398375, 0.00031519096, 0.00027949660, 0.00024667382, 0.00021643363, 0.00018878609, 0.00016358691, 0.00053168571 }; xine-lib-1.2/contrib/libdca/COPYING0000644000175000017500000004310314647725151014575 0ustar meme GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. xine-lib-1.2/contrib/libdca/bitstream.c0000644000175000017500000000601114647725151015675 0ustar meme/* * bitstream.c * Copyright (C) 2004 Gildas Bazin * Copyright (C) 2000-2003 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #include #include #include "dca.h" #include "dca_internal.h" #include "bitstream.h" #define BUFFER_SIZE 4096 void dca_bitstream_init (dca_state_t * state, uint8_t * buf, int word_mode, int bigendian_mode) { intptr_t align; align = (uintptr_t)buf & 3; state->buffer_start = (uint32_t *) ((uintptr_t)buf - align); state->bits_left = 0; state->current_word = 0; state->word_mode = word_mode; state->bigendian_mode = bigendian_mode; bitstream_get (state, align * 8); } static inline void bitstream_fill_current (dca_state_t * state) { uint32_t tmp; tmp = *(state->buffer_start++); if (state->bigendian_mode) state->current_word = swab32 (tmp); else state->current_word = swable32 (tmp); if (!state->word_mode) { state->current_word = (state->current_word & 0x00003FFF) | ((state->current_word & 0x3FFF0000 ) >> 2); } } /* * The fast paths for _get is in the * bitstream.h header file so it can be inlined. * * The "bottom half" of this routine is suffixed _bh * * -ah */ uint32_t dca_bitstream_get_bh (dca_state_t * state, uint32_t num_bits) { uint32_t result = 0; if (state->bits_left) { num_bits -= state->bits_left; result = ((state->current_word << (32 - state->bits_left)) >> (32 - state->bits_left)); } if ( !state->word_mode && num_bits > 28 ) { bitstream_fill_current (state); result = (result << 28) | state->current_word; num_bits -= 28; } bitstream_fill_current (state); if ( state->word_mode ) { if (num_bits != 0) result = (result << num_bits) | (state->current_word >> (32 - num_bits)); state->bits_left = 32 - num_bits; } else { if (num_bits != 0) result = (result << num_bits) | (state->current_word >> (28 - num_bits)); state->bits_left = 28 - num_bits; } return result; } xine-lib-1.2/contrib/libdca/tables_vq.h0000644000175000017500000041003214647725151015672 0ustar meme/* * tables_vq.h * Copyright (C) 2004 Gildas Bazin * * This file is part of libdca, a free DTS Coherent Acoustics stream decoder. * See http://www.videolan.org/developers/libdca.html for updates. * * libdca is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdca is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* 8bits signed fractional Q4 binary codes */ static const int8_t high_freq_vq[1024][32] = { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { -4, -2, 2, 1, -16, -10, 1, 3, 1, 0, 6, 1, -3, 7, 1, -22, 2, -4, -3, 11, 14, 6, -1, 1, -13, 29, -28, 10, 10, -8, 0, -9 }, { -8, 8, -7, 10, -3, -12, -5, -8, 1, -2, 9, -2, -5, -18, 1, 9, -8, -8, 3, 41, 7, -9, -9, 22, -42, -29, 14, -18, -14, -32, 1, -15 }, { -16, 8, 15, 16, -16, 5, 2, 7, -6, -16, -7, 1, 1, -3, -2, 0, 8, 20, -26, -11, 2, -17, 0, -3, -34, -37, 10, 44, -2, 22, 2, -4 }, { 7, 14, 5, 6, 15, -1, 3, -3, -9, -23, -5, -14, 8, -1, -14, -6, -5, -8, 54, 31, -6, 18, 2, -19, -2, -11, -30, -6, -19, 2, -2, -14 }, { 1, 2, -2, -1, -3, -3, 1, -5, 1, -3, -4, -8, 5, -4, 0, 1, 3, 7, -5, -4, -3, -12, 3, -2, -3, 12, -53, -51, 6, -1, 6, 8 }, { 0, -1, 5, 1, -6, -8, 7, 5, -18, -4, -1, 1, 0, -3, -3, -14, -1, -6, 0, -14, -1, -1, 5, -3, -11, 1, -20, 10, 2, 19, -2, -2 }, { 2, 4, 3, 0, 5, 0, 3, 1, -2, 0, -6, -3, -4, -5, -3, -3, -7, 0, -34, 4, -43, 17, 0, -53, -13, -7, 24, 14, 5, -18, 9, -20 }, { 1, 0, -3, 2, 3, -5, -2, 7, -21, 5, -25, 23, 11, -28, 2, 1, -11, 9, 13, -6, -12, 5, 7, 2, 4, -11, -6, -1, 8, 0, 1, -2 }, { 2, -4, -6, -4, 0, -5, -29, 13, -6, -22, -3, -43, 12, -41, 5, 24, 18, -9, -36, -6, 4, -7, -4, 13, 4, -15, -1, -5, 1, 2, -5, 4 }, { 0, -1, 13, -6, -5, 1, 0, -3, 1, -5, 19, -22, 31, -27, 4, -15, -6, 15, 9, -13, 1, -9, 10, -17, 4, -1, -1, 4, 2, 0, -3, -5 }, { -7, 3, -8, 13, 19, -12, 8, -19, -3, -2, -24, 31, 14, 0, 7, -13, -18, 0, 3, 6, 13, -2, 1, -12, -21, 9, -2, 30, 21, -14, 2, -14 }, { -3, -7, 8, -1, -2, -9, 6, 1, -7, 7, 13, 3, -1, -10, 30, 4, -10, 12, 5, 6, -13, -7, -4, -2, -2, 7, -3, -6, 3, 4, 1, 2 }, { -8, 9, 2, -3, -5, 2, 0, 9, 3, 7, -4, -16, -13, 3, 23, -27, 18, 46, -38, 6, 4, 43, -1, 0, 8, -7, -4, -1, 11, -7, 6, -3 }, { 1, 1, 18, -8, -6, 0, 3, 4, 22, -3, -4, -2, -4, -11, 40, -7, -3, -13, -14, -7, -10, 14, 7, 5, -14, 11, -5, 7, 21, -2, 9, -3 }, { 0, 0, -2, 4, -2, 0, 2, 0, -1, 2, -1, 0, 0, 2, 2, 2, -1, 1, -3, -1, -15, -2, -63, -27, -21, -47, -14, 1, -14, 10, 0, 2 }, { 1, 0, -4, 0, -3, -9, 4, 2, 6, -6, 0, -5, 11, -7, -15, 6, -7, -6, 3, 7, -15, -5, 23, -13, -6, 12, -8, 9, 2, -3, 3, 4 }, { 6, 0, 3, 0, -2, -4, 2, 1, 1, -1, 1, -2, -1, -4, -22, -15, -46, -66, 10, 20, 2, -17, 12, -6, 1, -2, -2, 0, 1, -5, 1, 2 }, { -1, 0, 0, 1, 0, -4, 0, 1, -10, -3, -8, 5, 7, -11, 2, -11, 29, -25, 11, 10, 0, -1, 5, -7, -2, -5, -2, 4, 4, -3, 5, -2 }, { 1, -1, -1, -3, -2, 1, -8, -3, 2, -2, 4, -5, -1, -7, -2, 1, -14, -7, 3, -30, -15, -14, 3, -4, -1, 3, -13, -1, -3, 1, 2, 3 }, { -1, -2, -3, 2, 2, -3, 3, 1, -3, 2, 0, -4, 6, 5, -5, 10, -57, 3, 22, -50, 1, -2, -5, -6, -1, 5, 1, 2, 2, 1, -2, 2 }, { 2, 0, -1, -7, 2, 1, 3, 2, 0, 4, 3, -2, 3, -3, 4, -4, 24, -35, -3, 38, -6, -5, 15, 20, 3, 16, -7, -5, 0, -4, -5, 0 }, { 0, 1, 0, 0, 0, -1, -1, 1, 1, -1, 1, -2, 0, 0, 0, 0, 0, -1, -2, -1, -5, -2, -43, -3, 46, -52, -10, 7, -8, 11, -2, -1 }, { 0, 0, -1, 0, -1, 2, -41, 33, -44, -48, -15, -26, -9, 6, 3, 3, -3, 2, 2, 2, 2, -1, -1, -2, 1, 3, 0, 0, 5, 2, 3, 1 }, { -4, 1, 6, 1, -6, -1, -2, 1, -14, -4, 0, -5, -2, 2, -2, 0, -6, 1, 0, 8, -21, 32, -3, -36, -6, -2, -1, -7, 3, 0, 1, -6 }, { -3, -2, 3, 0, 2, 2, 8, -4, -4, 6, 2, 1, 3, -6, 4, 3, 13, 0, -12, -1, 25, -20, -2, -23, -15, 7, -3, -11, -3, 6, -1, 0 }, { 0, 0, -3, -1, 0, 0, -2, -1, -2, -2, 1, -1, 0, 0, 10, 3, -2, 3, 3, -7, -6, -5, 0, -4, -60, -16, -6, 38, 5, 6, -5, 0 }, { 0, 1, 0, 0, 0, 0, 0, 0, 1, -1, -1, 0, 1, 0, 0, 1, 0, 0, -1, 0, -8, 2, -9, 10, 40, 31, -56, -21, 4, 20, -4, 7 }, { -2, -2, 0, 4, -3, -1, 7, 3, 1, 3, -8, 0, 3, 1, 2, 5, 1, -2, 14, 5, 4, 5, 5, 5, -5, 9, -66, 0, -20, -2, -8, 4 }, { -2, -1, 4, -1, -8, -2, -4, -1, -3, -3, 2, -7, -3, 5, 7, -2, 45, 31, -17, -16, -2, -2, -1, -22, 1, -1, -3, 3, 5, -3, 5, -1 }, { -4, 0, 7, 5, 8, 7, 2, 9, -9, -9, -7, -11, -3, -8, 17, -4, 34, 32, 18, 22, 1, 2, 1, -7, -5, 6, -1, 6, 4, 10, -2, -7 }, { 6, 0, 14, 9, 6, -1, -2, -3, 4, -6, -8, 4, 7, -1, 28, 38, 15, -1, 16, -11, 5, 8, 4, -10, 3, -10, -17, 5, 3, 3, 3, 1 }, { 1, 1, 2, -1, 2, 1, 0, 0, -1, 0, 0, -2, 1, -3, 0, 1, 2, -2, -4, -2, 0, -1, 1, -3, 1, 1, 1, -1, 8, 8, 66, 33 }, { -5, 2, -3, -7, 2, -8, -4, 10, 17, -18, -7, 4, -4, -7, -6, -6, -5, 5, -12, 2, 0, 6, 8, -2, 1, 4, -11, 2, 1, 8, 31, 19 }, { 6, 9, 16, -6, -6, -1, -2, -3, -11, -2, 7, 7, 17, 3, 4, 10, 2, 5, -13, 8, 7, 1, 4, 5, 7, 6, 7, -8, 9, -8, 33, 6 }, { 3, -1, 1, 0, -7, -5, 0, 14, -7, 1, -7, 1, 2, -4, 7, 10, -16, 12, 1, -6, 3, 8, -1, 10, -13, -6, -12, -23, 12, -3, 30, 14 }, { -2, -15, 0, 8, 3, -19, 5, -3, 2, 3, 13, 7, 14, -3, -10, 0, 8, 5, -6, -16, -8, -8, 14, 2, -1, 1, -9, -11, 11, -5, 27, 9 }, { -8, 6, -4, 4, -4, -1, 5, 4, 1, -7, -5, -4, -15, 1, 9, 0, 8, 4, 1, -17, 11, -2, -19, -1, -6, -8, 3, -12, 3, -17, 33, -10 }, { -3, -1, 2, 7, 7, -2, 9, 8, -18, -1, -13, -10, -3, -3, 11, 8, -2, -12, -8, 1, 4, 9, 14, 10, -3, 0, 2, 1, -2, 3, 31, 10 }, { -3, -10, 8, -1, -5, -11, 7, -5, 3, 6, 1, 4, -16, 10, 5, -4, -2, -10, -1, 13, 6, -5, -7, 12, 7, -3, -17, 1, 12, -4, 29, 8 }, { 1, 2, 5, 2, -6, -7, 0, -1, 6, -1, 10, 6, -4, 5, 2, 2, -2, -8, -6, -11, 14, -13, 27, 3, -2, -12, 5, -16, 2, -26, 20, 15 }, { -1, -3, -5, -3, -3, 6, -1, 3, -5, 1, 7, 2, 1, 0, -1, -1, 0, -1, 9, 7, -6, -3, 4, -5, -4, 8, -8, -25, -8, -4, 34, 23 }, { -1, -2, 1, 1, -1, -2, -1, 1, -1, 0, 0, 0, 0, -2, -1, 1, 0, 2, 1, -1, 4, 0, 0, 1, -1, 0, 5, 3, 12, -9, 68, -16 }, { 10, 0, -8, 14, -6, 1, -12, 0, 0, -3, -5, -11, -6, 12, 9, -10, -3, 5, 0, 7, 11, 2, 4, -3, -8, -3, 7, 4, 3, -3, 34, 4 }, { -12, 13, -5, 7, -11, -2, -1, 1, -4, -14, -21, 3, -3, -3, -4, -7, -9, -4, 3, -17, -2, -13, 10, -2, 12, -4, 0, -9, 1, -5, 31, 10 }, { -10, 6, 5, 6, 4, -7, 10, 0, -28, -3, 0, -11, -1, -5, 16, -10, -16, 7, 20, 2, -4, 2, -5, 0, 15, 6, 5, -10, 7, -9, 20, 4 }, { 1, -7, -2, -7, 4, -3, -2, -7, -1, -14, 6, -16, 4, -5, -4, -6, -5, 0, -2, 2, -6, 9, -5, 4, -18, 8, -10, 8, 15, 0, 32, 1 }, { -5, 7, -3, 7, 15, -4, 0, -16, 9, 5, -5, 5, 4, -3, -12, -9, -18, 10, 2, 2, -3, 7, 3, -1, 6, -9, -10, 3, 15, -4, 35, -7 }, { -1, -10, 2, 2, -4, -2, 10, 2, -1, 2, -2, 1, -1, -14, -11, 3, -8, 5, -8, -2, 6, -1, -7, 1, 7, 5, 7, 8, 30, -4, 30, 14 }, { 2, -2, 1, 2, 3, -8, 3, 0, -2, 0, -9, 2, 1, 4, -6, -1, -2, 5, 0, 1, -2, 12, 6, -3, 9, -3, 4, -12, 21, -39, 24, -2 }, { 3, 5, 1, -2, -2, -2, -3, 6, -8, -2, -11, -8, -1, 4, 2, 2, -4, -10, 12, -5, -11, 1, -15, -34, -11, -7, -11, -1, 7, -14, 38, -1 }, { -4, 4, 8, 9, 8, 1, -5, -9, 4, -2, 15, -4, 11, -15, 20, -1, -1, -3, 4, -9, -2, -2, -2, 8, 6, 12, -5, 0, 11, -12, 27, -4 }, { 0, 8, -4, 3, -11, 6, -11, 2, 3, 0, 5, -8, -7, -6, -9, -21, 4, -11, -1, -16, -7, 16, -3, 7, -7, 4, -5, 0, 11, -7, 31, 3 }, { 1, 3, 4, 11, -11, -2, -3, -6, 6, 5, 0, 3, -9, -6, 4, -4, 0, 4, -8, 13, -6, -13, -1, -5, -1, 4, 0, 0, 9, -22, 24, 18 }, { -7, 3, 10, -13, -6, 6, -6, 6, 22, 1, 0, -14, 2, 3, 7, -1, 8, 20, -1, 5, -4, 13, 9, -9, -9, 6, 0, -4, 0, -8, 31, -4 }, { -3, -4, 0, 1, 7, 3, -7, 0, 5, -2, 1, 3, 3, 1, -5, -2, 5, 2, -11, 4, 0, -1, 12, 0, -3, -13, 15, 8, -6, -27, 34, 0 }, { -3, -3, 10, -4, 2, -1, -3, 0, -1, -1, -4, 2, 6, -2, 12, 1, 3, -6, -7, -6, -5, 4, -19, -6, -8, -34, -4, -8, 10, -7, 23, 10 }, { -7, 0, -1, -6, 8, 4, -4, 2, -5, -8, -7, -9, -8, 5, 9, 7, -6, 1, -12, -12, -1, -16, 5, 0, 16, 3, -7, -8, 27, -4, 23, 15 }, { -8, 4, 8, 5, 6, 11, -3, 5, 3, -1, -11, 6, -5, 0, 2, -6, -3, -6, 4, -1, 5, -5, -12, -6, 7, -5, 9, 3, 6, -7, 29, 1 }, { 1, 3, -2, -2, -6, -2, 1, 6, -6, -3, 1, 2, 3, 4, 1, 5, -1, 0, 4, 2, 11, 6, 2, -3, 13, -9, -19, 18, -15, -10, 36, 21 }, { -3, -3, 2, -1, -7, 6, -4, 1, -3, -1, -2, 2, 3, -7, -3, 0, -2, 0, -2, 6, -19, 3, -8, 2, -6, 7, -1, 0, 29, -6, 28, -10 }, { -5, 1, -3, -7, -12, -4, 1, 1, -1, 13, -10, -1, -9, -5, -13, 6, 13, 3, -4, 2, 3, 11, 2, 6, -25, -16, -6, 0, 14, -1, 27, 16 }, { -6, -1, -7, -5, -2, -5, -5, -1, 9, 1, 0, 3, -8, -12, -6, 5, -6, 5, 3, -9, 1, 4, -7, -10, -9, -7, -17, -5, -15, -23, 25, 3 }, { -8, -2, 9, -3, -4, 3, -1, 8, -7, -7, -5, -4, -2, 9, 4, -1, -7, -4, -5, -16, 3, -6, 18, -13, -9, 16, -15, 8, 15, -10, 24, 5 }, { 1, -38, 2, 34, 9, 10, 11, 2, 2, -6, 3, 2, -2, 5, 4, -7, -1, 1, 4, 0, 3, 1, -8, -1, -6, 5, 4, 2, -4, 5, 2, -1 }, { 1, -22, 15, 18, -2, 10, -16, -9, -8, -11, 8, 4, 0, 7, -14, -5, -1, -7, 12, 17, 9, 5, -7, -4, -12, -6, 7, 0, 7, 2, -2, 1 }, { -11, -29, 7, 10, 19, -1, -8, -9, 7, 1, 9, 6, 8, -7, -14, 8, -3, -11, -13, 0, -7, -23, -2, -8, 12, 9, 2, 14, 19, 1, -1, 5 }, { -24, -27, -11, 36, 2, 6, -3, 4, -6, 8, 0, 12, -1, -4, -6, 3, 4, -1, 2, -3, -2, 3, 2, -1, -2, -4, 0, -1, -2, 7, 2, 3 }, { -9, -24, 11, 13, -10, -12, 12, -2, 7, 4, 8, 13, -3, -3, 2, 9, -3, -4, 4, 13, 5, 13, -6, -3, 1, 15, 7, -3, 0, 19, -2, -9 }, { -8, -15, 7, 14, -4, -5, 2, -18, -19, -2, 2, 17, 16, 6, -10, 10, -9, 14, -1, -5, -1, -6, -7, 2, 9, 11, 13, 6, -5, -12, 3, 2 }, { -10, -37, 13, 1, 3, -14, 0, -20, 4, -3, 8, 2, -2, -3, -9, -5, -3, -17, -1, 13, -11, 2, -6, 4, 4, 0, 3, 1, -9, -4, -5, -4 }, { -2, -22, -5, 46, -8, 5, 9, -11, 8, 7, 7, -1, -1, -2, -7, 2, -3, 3, -1, -2, 7, 0, 2, -1, 1, -2, -2, -3, 6, 0, -4, -6 }, { -16, -27, 15, 16, -4, 14, -7, -26, 2, -2, 6, 5, -3, 11, 0, 2, 3, 9, -7, -1, 2, -4, -4, -1, 6, 10, 1, 1, -3, -2, 3, 0 }, { -3, -22, 10, 26, 1, 2, -3, 3, 17, -3, -7, 9, 1, -21, -4, 5, 3, 0, -7, -6, 3, 3, -8, -7, -9, 3, 7, 1, -8, 12, 6, -7 }, { -9, -25, 3, 18, 9, -6, -11, 0, -5, -12, 9, -8, -7, -6, -6, 22, 2, -6, -3, 15, 3, 2, -2, 9, 14, -10, -7, 15, 13, 6, -2, 11 }, { 5, -20, -5, 28, 11, 10, -4, -4, 0, -7, 3, 5, 2, -5, -8, 2, 6, 10, 9, -9, -18, 3, 14, 1, 3, -3, -1, -6, 7, 7, 2, -1 }, { -8, -30, 7, 12, 10, 8, 7, -13, -16, 0, 1, -1, -6, -11, -15, 4, 1, -2, 10, -15, 1, 11, -2, 8, 9, -7, -7, 9, -5, 2, 7, -18 }, { -10, -32, 10, 11, 3, -1, 3, -5, 5, 2, 14, -6, 3, 1, 5, -15, -11, 6, 20, 4, 0, -12, -7, 3, 1, -1, 10, 6, -1, -9, -4, -1 }, { 1, -25, -14, 12, -11, 9, 9, -16, -24, -17, 22, -9, 11, -30, -3, -4, 6, -7, 9, 2, -1, -5, -6, 2, -1, -1, 10, 1, -3, 3, 4, 8 }, { -14, -26, -6, 9, 8, 17, -11, -24, -7, -4, -8, -2, 10, 2, 2, -1, 2, 13, 12, -7, 4, -6, -10, 6, 6, -13, -11, -7, -16, 0, -2, 5 }, { -4, -30, -13, 12, 16, -6, 12, -16, -13, 5, 15, -2, -2, -10, -7, 7, 11, -1, -4, -2, -4, 7, 4, -8, 1, 3, 0, 11, 3, -2, -5, 4 }, { -4, -21, 20, 22, 2, 20, -8, 1, -12, -5, -9, 4, -10, -17, -3, -8, -3, 3, -12, 1, -3, 0, 7, 4, 7, 7, -3, 7, 5, 3, 1, -5 }, { -12, -20, 2, 29, 11, -6, 9, -7, -6, -4, 0, 6, 17, -13, -2, -10, -17, -1, -18, 2, 0, 14, -6, 1, 0, 3, 2, -10, 1, -5, -2, 5 }, { 16, -37, -1, 26, -2, -14, 1, -5, -14, 2, 2, 3, 6, 1, 1, 4, 0, -1, 0, -2, -2, 4, 9, -6, 0, -2, 10, -7, -2, 4, 1, 0 }, { -9, -24, -12, 5, 5, 3, -17, -14, 4, 3, 2, -4, 10, -22, -8, -3, 6, 1, 12, -8, 4, 1, 9, -1, 18, -3, 6, 5, 3, -5, 9, -5 }, { -14, -33, -2, 20, -13, -10, 2, -7, -1, 11, -9, -8, 18, -3, 1, 8, 0, -2, 10, 7, -2, -13, 9, -3, -4, 5, -2, -2, -1, -5, 1, -7 }, { -10, -23, 8, 14, 1, 7, 1, -3, -7, 4, 1, 1, 8, -7, 15, -14, 13, 14, 2, 5, -13, -5, -8, -1, 6, 3, 6, 9, 6, 15, 14, 5 }, { -13, -25, -10, 13, -17, -24, -7, -13, -6, -10, -8, 2, 0, -13, -10, -4, -8, 4, -9, 9, -4, 4, -3, -3, 3, 3, -5, -9, 1, -2, 11, 2 }, { -12, -23, 1, 18, -11, -2, 5, 9, -5, 5, 14, -9, -3, -2, -6, 2, -2, 11, -13, 1, -3, 11, -9, -4, -2, -6, 8, 10, 1, 4, 2, 1 }, { -5, -18, 16, 22, 2, 0, 8, -6, -9, -7, 10, -16, 23, 10, -11, -1, 7, 2, 7, 2, 1, -5, 6, 1, 0, -4, 9, 2, -3, 1, 0, -4 }, { -3, -26, 14, 11, 2, -9, 17, -2, -1, -5, -16, -9, -5, 10, -13, 1, 6, 12, 10, 11, 0, 0, -3, -14, 6, -2, 0, 4, -5, -1, -7, -1 }, { -10, -33, 1, 8, 11, -5, 1, -6, 7, 4, 5, 6, 1, -2, -10, -5, -6, 12, -11, 5, -10, 4, 12, -1, -1, -3, 4, -1, 9, 0, 16, -17 }, { -14, -37, 7, 7, -2, 5, -8, -11, 2, -13, 4, -19, 1, 8, 8, 4, -9, 2, -4, 3, 12, 2, 4, -4, -8, 8, 1, 4, 8, -1, 6, -2 }, { -6, -30, 18, 17, 1, -22, -3, 4, -7, -10, 7, 0, -8, 8, -1, 4, 2, 8, 6, -2, 2, 7, 4, 4, 3, -6, 2, 1, -3, 1, -1, -5 }, { -17, -18, -3, 22, -8, 1, 9, -2, -17, 20, -5, -5, -12, -5, 4, -5, -9, 8, -2, 16, -3, 0, 19, -8, 8, 1, 2, -4, 0, 11, 0, -3 }, { -9, -23, 3, 10, 4, 4, -3, -2, -2, -2, 1, -22, 11, 0, -2, 5, -2, 14, -9, -11, -4, 7, 5, 32, 1, -3, -7, 0, 21, -9, 7, -6 }, { 0, 0, 0, 2, -1, 1, 0, 1, 3, 0, 0, 1, 0, 1, 0, 1, -3, 0, -1, -2, 0, -1, -1, -3, -1, 1, -4, 1, -1, -5, -69, -19 }, { -3, -5, -8, -12, 4, -3, -19, -11, -5, 0, -14, 7, 18, -6, 7, 22, 8, 14, 15, 10, 3, -1, -3, 5, -1, 7, -7, 1, -6, 3, -26, -11 }, { -1, -6, 4, -4, -5, -16, 0, -6, -3, 11, 1, 0, 9, 5, 16, 3, -4, -33, -4, 4, -7, 0, 1, 6, -11, -2, -13, -2, -18, 20, -25, -16 }, { 4, 0, -1, 0, -5, 1, 0, 2, 0, 11, -10, 4, -10, 7, 16, 2, 16, 15, 2, -1, 2, 9, 2, 8, -3, -5, -2, 0, -3, 0, -33, -2 }, { -3, -15, 10, 10, -9, -1, 7, 3, 5, -5, -8, -8, -3, 15, -9, 4, 12, 13, -13, -14, 10, -6, 9, 22, -27, 23, -1, 5, -24, 2, -30, 5 }, { 0, -2, 7, -5, -5, 3, 5, 3, -3, -5, 2, 1, -4, 3, -3, -1, 1, -2, 10, 22, -3, -4, -2, -2, -7, 3, 8, 1, 14, 4, -37, 9 }, { -3, -4, -1, 1, -4, 0, 6, 2, 6, -7, -10, -10, -1, -4, 11, -3, 7, -6, 4, -12, -1, 5, 1, -7, 10, -6, 17, -4, 8, 3, -40, 13 }, { 2, 12, 4, -7, 14, -3, 16, -2, 18, 2, 13, 5, 5, 1, 11, -1, 0, 9, 2, -6, -1, 2, -6, 2, -5, 3, 5, 1, -1, 1, -32, -7 }, { -16, 11, 7, -4, 2, -5, -9, 9, 11, 11, 15, -13, -11, 11, 9, 4, 3, -8, -10, 12, 12, 0, 0, -16, -9, 13, 2, 9, 4, -13, -33, 3 }, { 6, 4, 5, 4, 3, -1, 5, 6, 4, 2, -11, -1, -15, -11, -1, 1, 11, -3, -2, 24, -4, -6, -25, -10, -15, -8, 0, 0, -5, 4, -30, 2 }, { 10, -3, -6, 1, -9, -5, 6, 9, -10, -3, 8, -1, 4, -1, 11, -11, 3, 9, 11, -3, 6, -17, 5, -8, -33, 9, -13, 19, -2, 9, -25, 2 }, { 0, 0, -1, -3, 0, -2, 1, 0, 0, 2, 1, 0, -2, 0, -1, 2, 0, -1, 4, -1, 2, -3, 4, -2, 3, 3, 1, 0, -15, 12, -63, 27 }, { -2, 14, 9, -1, 3, 0, 1, 1, -19, 15, 3, 4, 0, -10, 1, -5, 3, 0, -5, -10, 2, -16, -4, 8, -12, -6, 7, -5, -10, -1, -33, -4 }, { 0, 3, 1, 3, 1, 2, 4, 4, 9, -6, -8, -5, 1, -12, 3, 8, -10, 6, -1, 1, 13, -5, -5, 2, -4, 13, -18, -10, -7, -9, -33, 10 }, { -6, -3, -12, 5, -1, 11, -6, 0, -2, 1, 2, -7, 3, 1, 3, -2, 1, 8, -10, 7, -1, -3, 3, 0, 13, 1, 6, 7, -16, -7, -39, 8 }, { -6, -1, 11, 6, -3, 8, 3, -5, 3, 0, -5, -2, -6, -3, -4, 2, -3, 13, -11, 1, 7, 5, 19, -5, -3, -15, -1, 7, -1, 6, -33, 8 }, { -7, 3, -4, -3, -4, 1, 6, -5, -5, 6, -8, -1, -7, 4, -1, -6, -2, 1, 7, 0, 1, 1, -5, 2, -2, 0, -13, -2, -31, -14, -39, -12 }, { -10, 9, 0, -3, 1, -1, -1, 0, 1, -5, -1, -4, -2, 5, 2, -7, 18, -8, -2, -19, -7, -7, -12, -14, -11, -1, -9, -13, -7, -12, -31, -9 }, { -3, -16, 10, 9, 1, -10, -12, 2, -2, 2, 7, -3, -3, 1, -4, -5, -9, 5, 7, 3, -1, 4, -11, -8, 4, 13, -10, 13, 10, -4, -36, 1 }, { -7, -12, 4, -20, -7, -7, 2, 11, -1, -2, 3, -12, 1, 0, -6, -7, 6, 4, 13, 3, -3, 4, 3, -6, -12, 5, -5, -22, -13, -8, -37, -6 }, { -7, 5, 3, 5, 7, 9, -14, -3, 10, 17, -1, 1, -12, 5, -6, 0, -4, -9, 0, -11, -14, 3, 13, 6, -25, -8, -12, 4, -10, 18, -30, -1 }, { -10, 6, -10, 6, 6, 1, -10, 0, -7, 5, -2, 17, -18, -4, 0, -3, -16, -6, -3, -8, 5, 1, -4, 6, -7, 16, 6, 10, -1, 0, -32, -11 }, { -1, 9, 9, -5, 4, 9, 6, 9, -4, -2, 7, 11, 4, 2, -5, -4, -6, 0, 2, -3, -1, 5, 10, 0, 12, -10, -18, -3, -1, 14, -33, 2 }, { 4, -8, -18, -4, -5, -11, 4, -10, -4, 9, 13, -12, 1, -6, 1, 2, 4, -9, 8, 3, -6, 21, 13, -1, -2, 1, -2, 6, -7, 0, -30, 1 }, { 6, -1, 2, -3, -1, -4, 6, -4, 0, 4, 2, 2, -9, 2, 6, 3, -2, 4, -1, 9, -6, 0, 7, -8, 5, 19, -2, 9, -5, 2, -33, -8 }, { 2, 1, 12, -5, -8, 8, 3, -2, -4, 1, -2, 5, -4, -9, -8, -8, 7, -11, -4, 6, -10, 7, -1, -1, -2, -1, 16, 32, -7, 20, -33, -6 }, { -18, 2, 6, 13, 9, 9, -1, 3, -17, 24, -2, -6, 28, 8, -2, 6, 3, -10, -34, -16, -13, -4, -15, -11, -12, -3, -10, 4, -8, 4, -31, -4 }, { -11, 0, 18, 2, -16, -9, -13, -2, -2, -12, -3, -22, 30, 0, 8, 3, 9, -4, -16, 1, 0, -11, 15, -2, -4, 6, -5, 6, 1, 2, -25, -12 }, { 14, -1, 5, 7, 3, -15, -8, 1, 5, -2, 12, 13, 11, -25, 3, 1, 0, -2, -4, -16, -23, 0, -5, -17, 7, 5, -9, 6, -5, 2, -32, -7 }, { 3, -1, 6, 14, 2, -12, -9, -9, 4, 7, 4, 6, 5, -8, 4, 2, 4, 5, -2, 8, 8, -6, 0, 10, -20, -1, 3, -1, 8, 23, -33, -5 }, { -3, 11, -6, 3, -4, 5, 7, 3, 4, 5, -2, 3, -1, 30, 6, 1, 8, -6, 0, 0, -9, 6, -9, 4, 2, 9, -6, 1, -12, 0, -34, 18 }, { -17, 13, 0, 1, 9, -4, -11, 0, 7, 0, -10, -4, -1, 6, -6, 4, 1, 6, -9, 3, -5, -6, -11, 2, -4, 14, 23, -3, 2, 5, -30, 12 }, { -14, 5, -27, 2, 0, 7, 1, 4, 30, 8, 7, 5, 1, -1, 0, 5, 8, -10, 48, -11, 12, 33, 6, 8, -15, 20, -2, -5, 32, 5, -19, 10 }, { -16, -4, -12, -7, -2, 0, 8, -6, -20, -18, 16, -3, 0, 31, -2, 11, 2, -9, 49, -19, -12, -23, 10, 26, 16, -2, 4, -21, -14, 13, -11, -9 }, { -5, -9, -1, 3, -5, -21, 2, 10, 0, 0, 10, -21, -7, 7, -26, -9, 22, 32, 58, 11, -3, 11, -5, -8, -13, 6, -5, -9, 1, 10, 14, -8 }, { 7, 7, 10, 3, -2, -1, -11, -11, -6, -43, -3, 14, -19, -18, 19, 18, -32, 10, 45, -6, 6, 21, -20, -12, 2, 4, 6, 6, -4, 3, 3, 1 }, { 21, 22, -3, -2, -11, -6, -1, -2, 8, 8, 32, -21, 7, 28, -4, -6, -3, -2, 50, 2, 2, 27, -5, -8, 12, 7, -5, -1, -4, -17, 27, 6 }, { 13, 7, 2, -6, -12, 2, -10, -5, -17, 11, 4, 17, -12, -2, 5, -17, 37, -16, 48, -14, -18, 29, 8, 24, 11, -5, -9, 11, -1, 1, -13, -3 }, { 1, 1, -1, 2, 0, 0, 0, -1, 1, -1, 7, 2, -3, 3, 0, 6, 2, 10, 54, -25, 7, 54, -5, -6, -1, -15, 9, 13, -24, -15, -12, 3 }, { 21, 5, 8, 3, -3, -4, -2, -4, 3, -11, -5, -8, 9, 16, 8, -9, -10, -3, 46, -46, 2, 1, -10, 10, 17, 11, -20, -36, 10, 14, 0, -5 }, { 7, -13, -6, -9, -24, 45, 2, 8, 8, 0, 17, 20, 12, -24, 1, -7, -15, -3, 46, -13, -2, 20, 1, -13, -11, -13, 2, 15, 1, 10, -1, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, -1, -16, -9, 31, -69, -34, 26, 7, 17, -1, -6, -1, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -4, -5, -20, 18, -82, 22, 3, -7, 9, 4, 6, 2, -4, -1, 0, -2, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, -1, 15, -5, 62, -36, 4, 52, -7, 5, 0, 6, 1, 2, 1, 1, -1, 0 }, { 3, -19, 19, -20, 13, -4, -11, 8, 8, -16, 10, 1, -14, 30, 1, -33, 10, -11, 45, -30, 3, -4, -3, -13, 7, 12, 3, -22, 3, -2, -4, -2 }, { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 1, 11, 8, 70, 48, -10, 21, 4, 9, -9, -9, -4, -6, 0, -1, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, -1, 80, 2, -15, -36, -10, -5, -2, 8, -2, 2, 0, 0, 0, 0 }, { 10, 8, -8, -8, -24, 12, -1, 0, 20, 9, -1, -2, 2, -2, 12, -10, -2, -13, 35, -43, 44, 15, -10, -25, 4, 10, -3, -5, -5, 7, -1, 3 }, { 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, -2, -1, -18, 9, 49, -72, 7, -8, 7, -5, 2, 3, 2, -2, 1, -2, -3, 1 }, { -1, 4, -3, 10, 19, 4, 3, 20, 6, -24, 6, 9, 8, 15, 18, 18, -36, 19, 57, -11, 4, -3, 8, 7, 2, -3, -2, -9, -15, -2, 12, -4 }, { 20, 3, 11, -9, -4, 22, 42, -25, 1, 5, -10, -19, 0, 9, -16, 5, 2, 10, 44, -29, 17, -3, -9, -2, -1, 8, 14, -7, -1, 16, -5, 1 }, { -7, 16, -11, 12, 6, 33, -15, 14, -23, 2, -26, 8, 2, 10, 0, -5, 8, -8, 38, -38, -4, 5, 5, 5, 1, 22, -15, 7, 6, 0, 4, 28 }, { -1, -12, 2, 10, -2, 0, 7, 17, 12, 22, -4, 10, 25, 29, 5, 18, 4, 1, 27, -39, 31, 17, 2, 2, 22, -23, 13, 16, 1, -7, -4, -5 }, { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -2, 0, -14, 0, -7, -11, 49, -22, -4, 19, 17, -39, 4, -29, 10, 2, 36, -4, 23, -1 }, { -2, -2, -2, -2, 1, 15, -5, -7, -16, -8, -19, 16, -3, -20, 36, -9, -3, 20, 39, -20, 0, 2, 27, -16, 10, 10, -14, -22, -16, -3, 13, -8 }, { 5, -9, 6, -25, 7, 37, 13, -10, -5, 3, -5, 7, 18, -22, -7, 9, -5, -4, 50, -11, -4, -5, -5, 8, -4, -2, -4, -27, 14, 20, 7, -9 }, { 0, -14, -10, -27, -14, -17, -6, 26, 10, 2, 14, -12, -5, 0, 8, 9, 0, -28, 55, -7, -12, -7, 4, -10, 10, 7, -12, 11, 3, 5, 9, -8 }, { 2, 23, 4, -2, -1, -20, -2, 14, 10, -9, -9, -24, 10, 0, 11, -12, 12, 11, 49, -25, -2, 29, 7, -13, 21, -10, 11, -17, 3, 1, -8, 5 }, { 3, 0, -14, -6, 18, -2, 17, -9, -19, 9, -5, 9, 14, 6, 19, -3, 27, 1, 41, -21, 20, -15, 33, 0, 26, 14, 7, 10, 3, 20, -3, -12 }, { -1, 16, 15, -8, 3, -8, -8, 21, -5, -16, -29, 4, 1, -6, -4, -28, 2, 31, 37, -26, -2, 13, 24, 8, -9, -6, -29, 10, 7, 2, 7, 8 }, { -10, -10, 11, 13, -32, 2, 16, 9, 14, 23, -15, -13, 24, 13, 4, -27, 14, 12, 31, -18, 17, 23, -2, -7, -14, 9, -17, -6, -10, 20, 9, 6 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 5, 1, 89, 8, 10, -6, 2, -1, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, -1, 4, -7, 64, -50, 7, 37, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, { -2, 5, 3, -4, -4, -3, 2, -3, 3, -3, 5, 4, 1, -6, -1, 1, 6, -2, 50, -35, -7, 43, 7, -7, -5, -26, 24, 21, 3, -15, 5, 6 }, { -8, 21, -19, 33, -8, 22, -11, 17, 3, 0, 0, -2, 1, -3, 6, -1, 10, -8, 4, -11, -4, -5, 0, 8, -4, 3, 1, -4, 4, 2, 8, 4 }, { -7, 5, -20, 9, -22, 3, -14, 1, 6, 13, 23, -2, -4, -7, 2, 0, 11, 4, 6, 3, -7, -11, -7, 4, 5, 5, -12, 8, 2, 4, 7, -3 }, { -7, 6, -4, 20, -20, 16, -2, 7, 6, 16, 11, 12, -7, -7, 5, 3, -9, -4, 1, 2, 5, 2, 1, -9, -2, -17, -4, 6, -10, 7, -7, -6 }, { -9, 18, -17, 12, -24, 1, -1, 4, 14, 9, 4, 3, 2, 8, -12, -14, 4, -8, -4, 7, 7, 6, -1, 13, -9, -4, -1, 1, 0, -4, 15, 8 }, { -25, 2, -11, 6, -5, 24, -28, -5, 8, 12, -2, 6, 8, -3, 8, -9, -1, -5, -1, -5, 6, -1, -1, -1, -4, 8, -12, -2, -13, 7, 2, 1 }, { -14, 14, -18, 20, -10, 12, -2, 9, 1, 0, 12, -2, 15, -10, 26, -17, 16, -11, 10, -10, 9, -2, 4, -8, 2, -3, 4, 4, 2, -3, -5, 1 }, { -18, 12, -18, 21, -6, 12, -6, 13, -25, 18, 1, 11, -9, -5, 0, 10, -5, 3, -3, 8, -9, 7, 4, 2, -9, 0, 5, 0, 2, -3, 9, -8 }, { -4, 16, 1, 18, -30, 9, 1, 6, -8, 13, 13, -12, -6, -1, 13, 7, 6, 2, -15, -3, 5, 5, 1, -6, 1, -5, 0, 2, -16, 0, 3, -4 }, { -21, 1, -2, 6, -43, 18, -1, 5, -1, 4, 6, -2, -1, -3, -1, -3, 0, 1, 2, -9, 0, -1, 0, -2, 0, -1, -1, -2, 6, 0, 1, -2 }, { -23, 10, 4, 7, -32, -11, -18, 2, -2, -7, -6, -3, -3, -12, 19, 3, -5, -6, 16, -6, 16, 2, 16, 16, 8, -2, 13, 8, -15, -11, 2, 10 }, { -8, 2, -13, 2, -29, 24, -20, 19, 1, 10, -4, 10, 1, 2, -9, 11, -1, -2, 9, -5, 19, -7, 16, -9, -2, -18, 11, 1, 1, 0, 7, -3 }, { -6, 3, 4, 13, -26, 10, -10, 28, -7, 28, 1, 7, 0, -14, 5, 7, 4, -4, 3, -2, 3, 3, -11, 7, 6, 4, 0, -1, 2, -1, -3, 2 }, { -6, 16, -31, 13, -10, 17, -6, 4, -14, 4, 4, -1, -10, 12, -5, 1, -14, 15, 0, -8, 1, -5, 3, 3, 9, -5, 7, -20, 7, 4, 11, -5 }, { -19, 3, -17, 14, -12, 16, -22, 18, 14, 8, -2, 4, 10, 12, -14, 4, -3, 2, 3, 7, -7, 7, -6, 2, -2, -4, -5, 0, -5, -2, 2, 1 }, { -9, -7, -11, 24, -36, -9, -11, 5, 7, -12, -13, 18, -2, 20, 1, -4, -1, -10, 15, -6, 14, 1, 0, 2, 1, 2, -9, -16, -11, 7, 13, 0 }, { -24, 24, -18, 18, -22, 14, -11, 13, -12, 11, -10, 11, -7, 11, -5, -4, -1, 1, 5, 2, 3, -1, 1, -5, 7, -4, 5, -6, 8, -7, 8, -6 }, { -6, 18, -22, 22, 5, 11, -1, 6, 19, 22, 8, 4, -8, 20, -2, 15, -6, -18, 0, -33, -9, -12, -1, 6, 5, 2, 5, 5, -5, -17, -3, -3 }, { 1, 11, -16, 9, -18, 11, -4, 18, 20, 26, -10, 8, 1, -11, 8, -4, 0, 7, 3, 5, 2, 2, 10, -2, -4, 4, -4, -2, 1, -4, -5, -1 }, { -10, 6, -1, 18, -17, 27, -3, 10, -2, 12, -7, -9, 1, 1, -1, 7, -12, -1, -7, -6, -1, 8, 3, -15, 8, 9, 3, -7, 4, -1, 1, -1 }, { -14, 6, -16, 22, 2, 5, 0, 5, -18, 11, 6, -3, 22, -20, -9, -3, 6, -6, -7, -15, 1, 15, -8, 11, 8, -3, -8, 1, -8, 2, 6, -2 }, { -21, 5, -19, 19, -7, 4, -7, 0, -8, 6, 12, 5, -3, -22, -13, -6, -1, -3, -2, -14, 6, -3, 1, -8, -7, -5, -6, 11, -3, -10, -5, 2 }, { -1, 9, -12, 15, -6, 6, -19, 14, -9, 11, 3, 12, -17, -3, 8, -4, -3, -4, 1, -5, 4, 5, -7, -15, -7, 15, -6, -5, 1, -5, -3, 1 }, { -12, 20, -15, 20, -14, 3, -14, 9, -6, 33, -13, 6, -2, 8, -6, 7, -5, -6, -3, -3, 0, 8, -3, -3, 1, -2, 2, 2, 6, -5, -5, -2 }, { -7, 12, -18, 12, -18, 10, -4, 8, 2, 4, 8, 9, 0, 3, -8, 3, 6, -12, -4, 1, 25, -5, -9, 6, -7, 0, -9, -7, 3, -5, -4, -4 }, { -18, 12, -10, 11, -22, 0, -15, 5, -2, 2, -3, 6, -4, -4, -3, -15, -2, -3, 21, 6, -12, -11, 19, 3, 3, -14, 7, 0, -11, -22, -10, 0 }, { -15, 2, -30, 15, -17, 13, -16, 8, -7, 10, -8, 2, 11, 3, 10, -7, 7, -22, 12, -10, 3, -12, 6, -10, 12, -10, 7, -8, 5, 2, 9, 1 }, { -9, 11, -14, 6, -10, 21, 5, 12, -5, 5, 7, 21, 6, 2, -2, -1, -1, 4, 2, -20, -18, -1, -14, 3, -1, 4, -7, 10, 1, 11, 4, -4 }, { -22, 8, -30, 13, -21, -4, 4, -1, 12, 9, -2, -3, 2, -6, 4, -13, -2, 8, 8, 1, -7, 3, -4, -5, -1, -7, -2, 8, 8, 7, 8, 0 }, { -6, -4, -35, 16, -13, 15, -11, 14, -7, 9, -1, 11, 7, 0, 13, 10, -1, 8, 1, 1, -2, 8, -1, 2, 2, 3, -10, -1, 7, -13, -3, -7 }, { -15, 7, -16, 14, -18, 17, -6, 14, 3, 4, 7, -3, 10, -22, 5, -15, 4, -4, -11, 15, -15, 11, -11, 20, 1, 0, 2, 1, 11, -3, 11, -7 }, { -12, 3, 5, 16, -37, -1, 15, 15, -15, 10, 3, -10, 1, 15, 7, -15, -13, 8, 9, -3, 2, 12, -8, 2, -5, 0, -3, 4, 5, -9, -4, 5 }, { -16, 26, -4, 14, -22, 26, 6, -3, -8, 4, 21, 6, 16, -4, -11, 7, -10, 3, 3, 7, -4, 2, -9, 8, -2, 2, 5, -2, -4, -2, 7, -1 }, { -7, -10, 4, 3, 2, -4, -12, -10, -4, -5, 16, 19, -16, 1, 2, -9, -10, 0, 9, 7, -8, 3, 12, 8, -6, -11, -13, -1, -3, -20, 6, -5 }, { -14, -17, 3, -5, 14, -12, -12, 8, -6, -25, 21, 21, 10, -8, -12, 4, 10, -4, 3, -9, 11, 9, 0, 4, 2, -15, 1, -14, 4, 1, 0, -4 }, { -4, -9, -3, -1, 6, 3, -6, 6, -10, -4, 14, 8, 2, -3, -12, -19, 0, 11, -20, 1, 6, -2, -27, -6, 10, -17, -14, -17, -9, 8, -8, 3 }, { -12, -13, 16, -4, -2, 12, -7, -11, 2, -13, 3, 7, -16, -18, -1, -12, -2, 1, -12, -9, -2, -6, 2, 9, -22, -3, -4, -14, -7, 7, -1, 2 }, { -7, -8, -8, 15, 15, 18, 15, 16, -4, -37, 11, 15, -12, -1, -3, 3, 6, 6, 0, -5, -3, -5, 9, 1, 1, -11, -1, -8, -6, 2, 3, 0 }, { -6, 7, -5, -12, 13, 10, -18, -4, -3, -21, 6, 16, -15, -7, -12, -9, 1, -12, -1, 10, -2, -1, -3, 4, -4, 1, -16, -1, 12, -9, 5, 9 }, { -14, -5, 9, 3, 4, 26, -28, 3, -6, -24, 4, 5, 3, 13, 5, -1, 3, -1, 3, 1, 1, -5, 3, 0, -7, -8, -7, -3, 3, -5, 4, 0 }, { -4, 2, -10, -6, 25, 26, -6, 10, -6, -8, 15, 11, -6, -3, 2, -7, 5, 14, 9, -1, 0, -12, 4, -4, -10, 1, -3, 3, -2, -2, -6, -1 }, { -10, 8, -15, -10, 19, 17, -8, 0, -3, -7, 7, 5, -13, -1, 7, -7, 1, 13, -12, -13, 17, -12, 1, 26, -18, -3, -5, -6, 4, 5, 8, 1 }, { 2, -5, 3, 0, 0, 0, 2, -3, -2, -5, 7, 13, -4, 9, 0, -5, 4, -1, -11, -8, -4, 0, -13, 2, -47, -23, -8, -11, -4, 4, -2, -3 }, { -18, -4, 4, 5, -1, 17, -12, -8, 1, -12, 7, 20, -12, 3, -2, -11, 16, 12, -6, 1, -13, -16, -6, -3, -3, -5, 4, -12, -5, -9, 10, 1 }, { -11, 0, 4, 7, 7, 8, 3, -1, 3, -19, 32, 8, -19, -8, 2, 4, -12, 15, -16, 3, 1, 9, -2, 1, -2, 8, 5, 6, -4, -1, 11, -8 }, { 3, -1, 4, -2, 14, 32, -9, -23, -10, -12, 22, 15, -1, -2, 10, 0, 4, 6, -8, 4, -15, -2, -1, -4, 0, -8, 4, 1, -8, 3, 4, 1 }, { -17, -12, 6, -8, 16, 13, -20, -8, -1, -16, 10, 21, -19, 11, -9, -5, 7, 18, -6, 7, -7, -18, 13, 2, -2, 8, -12, -9, 2, 4, -5, 16 }, { 4, 0, 17, -11, 12, 7, -12, 5, -1, -25, 30, -8, -7, -6, -4, -7, 9, 8, 7, 3, 3, -16, 8, 0, -2, -2, -18, -3, -4, -5, 1, 4 }, { -3, -6, 6, -16, 17, 6, -3, 2, -9, -17, 12, 11, 11, 2, -20, 8, 1, 1, 0, 2, -2, -6, -21, -13, -9, -15, -1, -8, -6, -8, 0, -2 }, { -11, -7, 6, -9, 3, 6, 8, 16, 4, -5, 23, 26, -10, -3, 4, 0, 2, 2, -4, 4, -2, -12, 12, 10, -11, 0, -10, -16, 3, 0, 0, -10 }, { -5, -16, 10, -6, 27, 13, -3, 4, -2, -13, 15, 5, 2, 5, 3, -4, 13, 12, -11, -7, 0, 1, 11, 12, 2, 13, -15, -8, 9, -2, 3, 8 }, { -5, -8, 4, 3, 9, 3, -11, 10, 14, -25, 14, 8, -2, 5, -12, -21, 2, 10, -7, 2, -3, 2, 0, 2, -1, -3, -5, -6, -1, -16, 2, 8 }, { -1, 5, 1, -11, 5, 9, -7, 8, -13, -12, 4, 12, -4, 1, -1, -1, 27, 29, 10, 15, 2, -6, -3, 4, -21, 10, -9, -11, -6, -1, -9, -3 }, { -6, -3, -1, -6, 11, -5, 0, -2, -5, -31, 11, 3, -1, 5, -3, 4, 5, 7, -10, 5, -10, -13, 4, 12, -15, -2, 2, -7, 1, -9, -3, -10 }, { -3, -7, 17, -8, -5, 36, 8, -7, -8, -20, 12, 8, 1, -1, 3, 0, 1, 4, -10, 3, 1, 4, -2, -3, -2, -3, -10, 4, -1, -7, 3, 2 }, { -13, -3, -5, 9, 22, 6, -23, 3, -10, -7, 17, 17, 18, -14, -8, -8, 2, 4, -8, 2, -3, -8, 6, 4, -1, 7, 0, 0, -3, 0, -12, -3 }, { -3, -10, -15, -3, 9, 3, -23, -9, -13, -18, 12, 13, -2, 0, 1, 8, -1, 2, -7, -12, -5, 14, 2, 1, -22, 6, -10, -8, -9, 28, -7, -14 }, { -3, 1, 2, -1, 13, 7, -2, -7, 1, -3, 6, 9, -3, -2, 4, -2, 2, 1, -10, -2, -2, -22, -2, -7, -10, -5, -11, -27, -12, -16, 4, -7 }, { 2, -6, -3, 1, 8, 0, -2, 12, -3, -4, 58, 15, -10, -4, -2, 2, -2, 0, -2, -6, 2, 4, -1, 1, -4, 1, -1, -5, -4, -3, 3, 1 }, { 10, -1, 0, 5, 21, 7, -14, 6, -3, -16, 15, 17, -16, 13, 3, -6, -4, 6, -12, -5, 1, -4, -7, -8, 2, 3, -6, 6, -1, -8, 5, 4 }, { -6, -2, -8, -11, 15, 10, 0, 8, -6, -15, 33, 8, -2, 18, -15, -11, 5, -1, 0, 15, -15, -4, -4, -1, 10, 7, -13, 4, -4, 0, 8, 3 }, { -7, -2, 0, -2, 0, -2, -4, -5, -14, -16, 12, 38, 7, 12, 6, -4, 0, -1, 0, 3, -2, -6, 0, 2, -9, 1, 0, -1, 0, -2, 4, 1 }, { -8, -4, 18, 1, 14, 5, -12, -3, 20, -17, 5, 19, -11, -8, 11, -3, 3, 9, -7, -8, 9, -17, 2, 15, -10, -11, 5, -5, 7, 15, -6, -2 }, { -7, 2, 38, 5, 19, 16, -5, 4, -13, -20, 0, 4, -4, 6, 4, 2, -7, 6, -8, -2, -5, -7, 6, 3, -4, -3, -2, -3, 7, -6, -4, 0 }, { -11, -12, 8, -15, -3, 14, -7, -22, -11, 2, 22, 14, -19, 2, -19, -6, 1, 3, -18, 14, 2, -6, -2, -8, -3, -6, 5, -7, -8, -4, 1, 1 }, { 8, 7, 25, -21, 12, -6, -5, -4, -10, 6, 0, 10, 1, -12, 18, -5, -15, 4, 1, 14, -1, 5, 8, -7, 1, -7, -3, 9, 10, 1, -1, 0 }, { 9, 10, 32, -15, 8, 2, 11, -7, -18, -8, 2, -6, -9, -16, -3, 3, -1, 3, 1, -5, 4, -2, 1, -8, 0, -6, -3, -11, 1, 5, 0, 0 }, { 14, 0, 23, -25, 22, 3, 7, 10, 0, -2, 7, 8, 0, 10, 0, 0, 3, 2, 3, -10, 0, 10, 0, -7, 0, 10, -1, -5, -7, 1, -1, 2 }, { 12, 0, 25, -18, -5, -4, 13, -10, 3, -6, 7, 21, 0, -16, 3, -10, -6, 5, -7, -3, 2, 5, 3, -6, 4, 9, -8, 12, -2, 3, 2, 4 }, { 31, 15, 27, -20, 10, -7, 15, -10, 9, -8, 4, -5, 3, -3, 5, 6, 11, -2, -12, -2, 6, -2, 1, 2, -1, -1, 1, 1, 3, 1, 1, 2 }, { 12, -4, 13, -23, 12, -6, 2, 4, -3, 13, 6, -7, 5, -19, -7, 18, 1, -7, 7, 1, 16, -7, 3, 0, 3, 0, -12, 8, -11, 9, 4, 7 }, { 29, 1, 3, -22, -5, 6, 0, 12, -14, 11, 1, 6, -3, 4, 6, -2, 4, -13, 12, 1, 1, 3, -11, 9, -10, -1, -7, 16, -11, -1, 3, 9 }, { 4, 4, 36, -23, -5, -8, -15, 1, -6, 3, 13, -1, -5, -7, 4, 9, 2, -11, -3, 5, 1, 3, -6, -1, -4, -4, -2, 2, 3, -1, -5, -2 }, { 19, 10, 6, -17, 2, -4, -2, -4, -3, 13, 2, 2, -13, -7, -3, -11, 9, -6, 1, -9, -5, 4, -5, -9, -18, -7, -11, 9, 4, -11, 8, 4 }, { 16, -3, 9, -16, 18, -2, -12, -16, -11, 11, -18, 16, -13, 6, 2, 8, 3, 8, -4, -16, 10, -11, -1, -3, -8, 5, -9, -4, 9, -4, 0, -3 }, { 14, 15, 3, -23, -5, 7, -8, -6, 2, 17, 2, 12, -8, -12, 13, -1, -9, 3, 1, 1, 19, 15, 4, -1, 1, 2, -3, 2, -3, 1, 5, 3 }, { 32, 5, -10, -47, -5, -1, 4, 11, -7, 0, 2, -2, 1, -7, 6, -4, 6, 2, -4, -2, 2, -2, 0, -4, 1, -6, -5, 2, -2, -1, -3, -4 }, { 20, 8, 10, -21, -7, -9, -16, 12, 1, 4, 6, -5, 9, -11, -7, 4, -11, 28, -3, 2, 4, -6, 10, -8, -5, -5, -9, 9, -2, -1, 6, -5 }, { 38, 3, 23, -25, -6, -18, 3, -10, -8, 6, -10, 1, -10, 2, 2, 0, -7, 2, -4, 5, -1, 8, -3, 0, 3, 3, -1, 1, 0, -4, -4, 0 }, { 20, 5, 16, -22, 24, -18, 2, -12, -14, -7, -3, 10, 2, 7, -10, 2, -8, 1, 8, -1, 4, 1, 4, -2, 5, -9, -18, -8, -13, 5, -11, 10 }, { 14, 8, -12, -16, 9, -11, -3, -6, -25, -7, 6, 5, -7, -16, 10, 2, -7, -1, -9, -3, 16, 4, 3, 3, -3, -3, -15, 13, -3, 4, 13, -7 }, { 16, -9, 19, -23, 7, -19, -3, -5, -15, 11, -21, 21, -16, 18, -1, 6, 10, -10, 18, -14, 16, -15, 6, -5, -9, 5, -17, 13, -10, 13, 0, 10 }, { 8, -4, 4, -24, 8, -21, -18, 9, -11, 4, -6, 17, 5, -9, -2, -2, 2, 15, -2, -3, -2, 1, 7, -13, 15, -10, -8, -11, 3, 3, -1, -1 }, { 14, 17, 6, -32, 5, -17, -2, 0, 15, -1, -5, 16, 1, -5, -2, 9, -3, 8, 4, -2, -2, -4, -3, 1, 0, 7, -3, 4, -5, 0, -7, 2 }, { 24, 6, 22, -12, 8, 3, -14, 4, -7, 8, 6, 5, 6, 1, 6, -12, 15, 10, 4, 11, 9, 6, -7, -4, 10, -9, 2, -1, -5, 11, 15, 3 }, { 17, 12, 3, -23, 5, -1, -2, 1, -9, -1, -3, 1, 8, 1, -5, 17, 11, 0, -2, -11, 7, 4, 0, -27, -7, 1, 2, -8, 9, 7, 5, 3 }, { 12, 10, 12, -10, -4, 5, -1, 2, -24, 5, -8, 2, 6, -17, 19, 5, 12, -2, 16, -7, -6, -14, 4, 1, -3, 13, -16, 5, -1, 4, 1, 1 }, { 31, 9, 11, -17, 10, -3, -7, 7, 1, 2, 2, 4, -3, -1, 11, 4, -5, -8, 1, 4, 15, -6, -28, 1, 8, 3, -6, 5, 17, -2, 2, -4 }, { 11, 19, 16, -26, 0, -7, -7, 2, -13, -15, -12, 9, -3, 27, 8, 4, -6, 1, 4, -6, 11, -1, -6, -7, -3, 0, -6, 4, -6, -7, -3, -1 }, { 10, 18, 16, -32, 19, -9, -4, -3, -7, 8, 8, -3, -11, -2, -6, -16, 13, 13, -6, -1, 10, -2, -2, -9, 0, -3, 9, 4, 11, -2, -6, 6 }, { 9, 4, 19, -33, 4, 7, -12, 36, -3, -1, 8, -2, 2, -8, -9, -4, -8, 0, 1, -1, 0, -4, -4, 3, 0, 3, 6, 0, -6, 2, 0, -2 }, { 25, 7, 15, -12, 2, -24, -1, 24, -4, 4, 9, 0, -2, -9, 4, 6, 3, 13, -3, 1, 5, -1, -3, -5, -1, 7, -2, 3, 4, 4, 1, 0 }, { 19, 6, 8, -20, 9, -9, 5, -4, -13, 7, 11, -3, 5, -13, -9, 6, -11, -1, 0, 4, 11, 26, 3, 6, -7, 12, 6, -3, 1, -9, 7, 1 }, { 15, 6, 19, -23, -3, -9, 3, 16, -6, -4, 6, -5, -10, 1, 16, -14, 2, 0, 2, -13, -3, 8, -6, 3, 1, 1, 2, -5, 12, -4, -8, -3 }, { 14, 4, 16, -20, 1, 12, 0, 6, -3, 9, 4, 16, 10, -16, 5, 7, 5, -4, -4, -18, -3, -11, -4, 4, -7, 3, 13, 7, 3, 3, 2, -7 }, { 22, 3, -1, -30, 18, -3, -9, 9, -2, 11, -16, -2, -14, 12, 0, 4, -5, 4, -1, 3, -20, 12, 4, -10, -2, -2, -12, -12, 10, 6, 11, -3 }, { 15, 7, 2, -21, 5, 4, 9, -9, -33, 7, 7, 3, -6, -14, -8, 10, 12, 0, 2, -1, 5, 4, -2, 0, -7, 0, 2, 4, 0, 1, -3, 8 }, { -7, 0, 12, 3, 0, -6, 8, -4, 0, 2, 14, -15, 2, -7, -31, -3, 14, 0, 14, -15, -1, -4, -15, 10, 1, -3, 1, 2, 5, 2, -8, 1 }, { -2, 5, 1, 0, -3, 3, 3, -6, -1, 2, -4, 1, -19, 0, -11, 18, 11, 10, 21, 5, 6, 2, 10, 3, -6, 0, -2, 13, 5, -1, -2, 9 }, { -9, 1, -5, 0, 0, -15, 8, 4, 8, 3, 8, 12, -13, -2, -39, -2, 4, -4, 5, -3, -4, 3, -3, 3, 10, 5, 3, 2, -3, 5, -2, 8 }, { -9, 6, 6, -8, 12, -12, 23, -18, 4, -15, -5, 2, -20, 13, -7, 7, 7, -12, 14, -12, 6, 1, 1, -3, -8, 9, 0, 1, -7, 3, 7, -6 }, { -18, 13, 4, 3, -10, -30, -10, -6, -14, 1, -7, -4, -35, 5, -25, 11, 9, 8, 19, -4, -7, -3, -18, -8, 1, 5, 10, -4, -14, -9, 3, -4 }, { -6, -1, 4, -9, -9, 4, 20, 0, 0, 3, 11, 7, -16, -17, -20, 11, -6, -14, 1, 4, 19, 2, -8, 6, -15, 3, 6, -5, -14, 3, 7, 2 }, { 1, 6, -2, -8, -5, -3, 3, -8, 21, 1, 3, 16, -14, -2, -9, -4, 13, -2, 18, 14, 14, 19, -13, 5, -10, 2, -3, 3, 5, 5, 1, -1 }, { -1, -5, -6, -2, -11, -7, 5, -4, 5, -1, 0, 3, -3, 2, -19, 18, 16, 4, 14, -22, -2, -11, -22, 1, -1, 11, 1, 2, 11, -10, 7, -12 }, { 1, 4, 5, -1, -9, -5, 1, 12, 5, 6, 12, 9, -24, 23, 1, 20, 14, -11, 13, 5, -2, -2, 5, 6, 2, 1, -9, 6, 10, 5, -4, 11 }, { -1, -1, 1, 7, -3, -4, 8, -16, 15, -1, -7, 9, -22, -11, -11, 10, 16, 9, -2, 4, 13, 10, 6, 16, 4, 7, 1, -8, -7, -14, -7, 4 }, { 1, 3, -6, 0, 15, -9, -4, 0, 4, 6, 12, 9, -6, -5, -22, 17, 7, -11, 15, -5, 1, 3, -19, 0, -15, -3, 16, 5, 5, -7, -11, 12 }, { -2, -1, 13, 2, 4, -24, 37, -5, -2, -6, 12, 7, -2, -23, -4, 9, 2, -3, 3, 2, 3, 3, -14, 11, 0, -4, -2, -2, 3, 10, -10, 4 }, { 2, 9, 8, -6, -28, 14, 28, -11, 18, -11, 0, 2, -2, 4, -12, 3, 6, 0, 7, -7, -6, 2, 5, -1, -1, -1, 5, 2, 3, 0, -3, 9 }, { -7, 14, 5, -10, -3, 7, 4, -5, 7, -8, -7, 4, -12, 14, -16, 25, 3, 0, 1, -5, 12, -10, 0, -10, 0, 12, 12, 17, 12, 10, -1, 0 }, { -4, -2, 5, -2, -17, -3, 5, -5, 7, -17, 1, 5, -4, 4, -20, 0, 11, -15, 13, -8, 10, 1, 1, 5, -12, 9, -8, 0, 6, -1, -11, 4 }, { -3, 12, 13, -15, -7, -7, 0, 5, 33, 3, 3, -6, -13, -7, -15, 10, 3, 3, 3, -5, 2, 7, -1, 0, -12, 2, 11, -6, -9, 0, 5, 11 }, { -8, 5, 10, -7, -14, -4, 13, 0, 18, -3, -6, 7, 1, -6, 0, 21, 8, -7, 10, -8, -3, 17, -9, 0, -5, 1, 4, 8, -3, 11, -5, 0 }, { -8, 8, -3, -8, 8, -11, 16, -16, 17, 0, 8, 16, -17, 10, -16, 10, -8, 6, 11, 0, 10, 7, 4, 5, 7, -5, -5, -6, -7, -5, -1, 16 }, { -6, 0, 6, 1, -8, -8, 8, -7, -5, -10, -11, 8, -19, 6, -7, 13, 5, -3, 4, -8, 7, -1, -18, 9, 0, -5, 6, 26, 3, 8, 2, 4 }, { -2, -2, 23, -2, -20, 2, 7, -7, -6, -15, 3, 9, -19, -2, -10, 7, -2, 7, 9, 11, 0, 4, -4, 6, 9, -2, 4, -3, 4, 3, 2, 8 }, { -6, 12, 10, -10, -7, 4, 17, 11, -6, 1, 12, 11, -18, 8, -12, 4, 1, 13, 6, -13, 23, 9, -5, 8, -2, -5, 1, 3, 0, -2, -4, 4 }, { 7, 1, 7, -17, -8, 8, -1, -7, 5, -6, 4, -3, -16, 9, -24, 18, -3, 10, 13, -11, -6, -11, -4, 10, 0, 11, 8, 2, 6, -5, -11, 4 }, { -4, 1, -5, -10, 0, -3, 9, -2, 4, -1, 1, 5, -41, -10, -7, 4, -3, 3, 1, 0, -12, 4, -3, 0, 2, -1, -2, -5, 3, 2, -7, 5 }, { -2, 1, 4, 4, -3, -6, 1, 0, 12, -5, 11, 0, -17, -3, -1, 11, 4, 1, 27, -12, 0, -14, 2, -15, -3, -9, 0, -7, -3, 15, -8, 6 }, { -6, 4, 9, 2, 4, 3, 7, -10, 28, 1, -2, 48, 7, 0, -10, 10, 1, -9, 2, -1, 0, 3, -5, 5, -4, -2, 7, 7, 1, 3, 2, 5 }, { -3, 3, -1, 3, -9, 0, -1, 3, 2, -6, 39, -14, -12, 5, -19, 21, 7, -6, 4, -1, -4, 0, -4, 1, 0, -9, 1, 10, 0, -2, 0, 7 }, { 4, 2, -29, 12, 5, -3, 16, -6, 15, -13, -4, -1, -13, 22, -16, 17, 16, 4, 9, -4, 4, -6, -4, 11, -8, 7, 8, 4, 3, -3, -7, -13 }, { 0, 3, 3, -6, -4, 0, 9, 0, 5, 0, 10, 10, 4, -13, -12, 16, 23, -4, -12, -6, -4, 20, 2, 0, -4, 23, 1, 8, 11, -4, -5, 15 }, { -6, 4, -15, -9, -1, -19, 12, -30, -17, -4, 1, -13, -13, 4, -3, 26, 5, -25, 11, -14, -6, -13, 0, -7, 9, 2, 8, -1, -8, 1, -8, 13 }, { 1, 6, 1, -4, -4, 1, 2, 0, -3, 2, 10, 6, -6, -2, -11, 4, 32, 15, 15, -47, -8, 3, -12, 4, -5, 4, -1, 0, -5, 5, 1, -7 }, { 2, -1, 0, 0, -1, -6, 0, -6, 4, -4, 5, 9, -5, 1, -3, 51, 4, -5, 4, -14, -1, -4, -3, 1, -4, -1, 0, 2, -8, 0, 1, 2 }, { 0, 4, -2, -7, -2, -9, 6, -8, 11, -3, -6, 3, -11, -8, -12, 8, 11, 5, 19, 3, -24, 19, -14, 11, -5, -18, -8, -12, -5, -4, -1, 4 }, { 16, 9, 10, 14, -18, -2, -18, -27, 10, -5, 12, 14, 4, 0, -2, -6, -12, -7, -1, 3, 4, 7, 11, 10, 5, -5, -7, -16, -3, -6, 6, 9 }, { 7, 15, -9, 10, -19, 4, -5, -37, -2, -4, 8, 2, 4, -1, 1, 9, -5, -5, -12, 1, -1, -8, 3, -3, 4, 6, 9, 3, 3, -1, 2, 4 }, { 13, 17, 3, 9, -7, -7, -15, -17, -8, -13, -4, -8, 19, 2, 16, 25, 7, 15, 2, 16, -5, -6, -10, -9, -7, -6, -2, -7, 7, 2, 4, 5 }, { 24, 7, 9, 8, -13, -2, 0, -4, 1, -13, 3, 6, 7, 10, -4, 15, 5, 7, -4, 5, -5, 3, 13, -7, 5, 15, -11, -2, 7, 5, 8, 6 }, { 17, 6, -15, 23, -2, -1, -6, -2, 0, -4, 11, -3, 12, 15, 6, -8, -15, 10, -9, 7, -1, -11, 2, -8, -4, 3, 4, -10, 4, 4, 11, 1 }, { 21, 12, -3, 6, -8, 8, -11, -8, -5, -5, 3, 7, -1, -5, 12, 15, -10, -11, 3, 15, 8, 4, 2, -15, 0, 14, 1, -8, -1, 3, 10, -7 }, { 16, 12, 5, 13, -6, 15, -23, 0, -17, -9, 0, 4, -9, 13, 6, 18, 0, 0, -4, -1, 0, 14, 5, -1, 8, -4, -8, -6, 5, -2, -2, 0 }, { 14, 16, -1, 12, -15, -9, -6, -20, 4, 6, 8, 9, 3, 1, -9, -4, -1, -11, 9, 11, -12, 1, -14, -7, 2, -8, 11, 9, -4, 10, 4, -16 }, { 13, 10, 3, 7, 0, -8, -33, -6, 4, -4, 19, -2, 14, 6, 5, 7, 6, -3, -1, -10, -10, -9, 4, -3, 5, 9, 2, 2, 10, 9, -2, -3 }, { 11, 10, 25, 18, -1, -6, -21, -21, -11, -16, 6, 5, 14, 4, 8, 7, 0, -10, -7, -9, -5, -4, 3, -1, 1, 6, -1, 6, -2, 2, -3, -9 }, { 15, 9, 5, 22, -17, 15, -9, 7, 7, -9, 13, 9, 10, -1, 8, -3, -2, 6, 1, 17, 8, -14, 7, -3, 12, 9, 1, 0, 1, -5, 17, -18 }, { 25, 19, -17, 12, -4, -10, 1, -13, -19, -7, -3, 9, 6, -2, 3, 1, 4, -2, -11, -14, -1, -7, -5, -9, 7, -1, -3, 4, -5, 1, 0, -1 }, { 20, 8, -3, -10, -24, 3, -6, -2, 0, -12, 14, 6, 7, 11, 4, 7, -12, -5, -8, -10, 5, -1, -4, 4, 16, 7, -14, 6, -1, -2, -7, -11 }, { 16, 18, 17, 1, -15, -6, -5, -3, -1, -19, 8, -2, 2, 8, 12, -19, -12, 8, 0, -3, -1, -1, 4, -14, 9, -1, -12, -1, -7, 10, -3, 5 }, { 18, 12, -7, 7, 0, -3, -13, 0, -1, -4, 9, -2, 6, -1, 0, 1, 15, -21, 1, -8, 25, -19, 13, -9, 2, 12, 5, -7, -3, -1, -3, 1 }, { 13, 16, -4, 9, -2, 2, -1, -19, -7, -4, 18, -6, 14, 18, -5, 4, -6, -3, -19, -14, -1, -12, 10, 6, 7, 17, -12, -13, -10, -4, 5, 4 }, { 27, 17, 4, 14, -9, -2, -4, -8, 0, -6, 14, -11, -7, 2, -3, -3, -2, -3, -13, 12, 16, 1, -5, -9, -10, -11, -2, 3, -7, 5, 11, -7 }, { 7, 17, -16, -2, -14, -28, -7, -8, 15, -10, 7, 15, 8, 17, 13, -1, 4, -7, -12, -11, 0, 0, 2, 3, -3, 7, -6, 6, 1, -16, 1, -2 }, { 23, 11, -9, 15, -23, -4, -6, -4, 2, -9, -7, 9, -8, 3, -13, -4, 8, 18, -6, -2, 1, -5, 6, -14, -5, -2, -6, -5, -3, -2, 4, -5 }, { 12, 13, 18, 18, -35, 2, 7, -17, 3, -11, 6, 9, -3, -2, 10, -4, 3, 3, -2, -7, 0, 2, -4, 0, -4, 0, -6, 5, 10, 4, -3, -1 }, { 19, 11, 1, 20, -14, 4, -9, -13, -2, 11, 0, 17, -1, -1, -1, -1, -5, -8, 0, 5, -1, -8, 5, -1, 3, 2, -12, 21, -2, -24, 5, 7 }, { 15, 15, -15, 17, -14, -22, 3, -4, -11, -3, -7, 1, 18, 10, 1, 10, -6, -3, 8, 2, -7, 0, -2, 1, 1, 2, -9, -2, 1, 2, -3, 4 }, { 45, 13, 8, 17, -5, 2, -16, 2, 8, -2, 8, -15, 4, 5, -1, 7, -6, -2, -6, 2, -3, 0, 0, -9, -1, 7, 2, 3, -3, -3, -1, 5 }, { 1, 18, -8, 18, -12, -10, 3, 4, -22, -12, 20, 8, -3, 9, 2, 10, -10, -3, 9, 3, 6, -3, 10, -1, -3, 2, -2, 4, 2, 3, -3, -18 }, { 9, 10, -5, 9, -35, -21, -18, -16, -1, -12, -6, -7, -15, -19, 12, 4, 4, 9, -7, 2, 14, 1, 4, 0, -1, 6, -7, 2, 1, 1, -4, 4 }, { 31, 8, -17, 35, -8, 1, -5, -6, -7, -6, 10, -2, -3, 6, 9, 3, -6, -2, 3, 3, 5, -3, 0, 6, 0, 1, -5, -3, -2, -4, -1, 0 }, { 18, 4, -8, 7, -8, -15, -1, -16, 12, 18, 3, 19, 2, 4, 8, 8, 0, -5, -8, -12, 10, -5, 0, 1, 0, 4, -3, 16, 11, 11, -2, -6 }, { 27, 15, -17, -10, -23, -22, -1, -14, -4, -7, 20, -2, -7, 6, 15, -5, 32, 4, 9, -11, -3, -8, 11, -4, -1, -4, -8, -6, -4, -5, -2, -7 }, { 22, 4, -7, 2, -15, -11, -17, -10, 2, 0, 15, 11, 7, 12, -8, 6, -10, -18, -6, -12, 7, 3, 22, 3, -7, 14, -5, -2, -13, -7, -1, -7 }, { 18, 13, 9, 24, -4, -19, -9, -11, 13, 8, 2, 4, -1, 8, 14, 10, -12, 0, 0, 5, 10, 5, 4, -1, 5, 1, -1, 11, 2, -4, 0, -9 }, { 15, 19, -5, 1, -4, -10, -8, -27, 6, 8, 5, 10, 4, 11, 5, -5, -11, 0, -11, -14, -4, -9, -8, -8, 6, -9, 4, -5, -1, 1, 5, -4 }, { 18, 1, -13, 14, -14, 9, -15, -7, 12, 1, 13, -4, -20, 12, 10, 12, -12, 7, 1, -13, 10, -6, 5, -3, 4, 8, 10, -13, -3, -6, 9, -3 }, { 19, -14, 5, -8, -6, 2, -5, 5, -3, -1, -28, 11, 18, -6, -4, -2, 11, 14, -43, -42, 9, 2, 20, -23, 6, 32, 0, 5, 0, 6, 9, 5 }, { 8, 11, -14, -1, 7, 12, -7, 2, -16, 2, 10, -3, -1, -7, -7, -1, 1, -10, -60, -23, -18, 42, -13, 9, 18, -11, 0, 1, 0, 2, -5, 1 }, { -5, -1, 2, 0, 3, -3, 3, -2, -6, 0, -3, -3, 7, 2, 0, -2, -2, 3, -34, -15, 37, 47, 10, 20, 9, 1, 3, -21, -25, -33, -14, 8 }, { 5, 6, 2, -2, -2, -2, 6, 5, -5, 7, -3, 1, -5, -13, 9, 3, -17, -19, -2, -79, -12, -7, -8, -6, -2, -2, -1, -1, -7, -13, 6, -1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 0, 3, 4, -87, 6, -11, 16, -9, -1, 8, 0, 5, 0, 1, 2, 1 }, { -5, 6, 2, -24, 5, -9, -7, 0, 7, 3, -3, 16, -14, -16, 0, 18, 15, -9, -14, -28, -17, 53, 14, -6, -28, -1, -3, -10, -7, -14, 19, -15 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -3, 0, -13, 0, -53, 3, -22, 63, 19, 16, 1, -11, 0, -3, 0, -3, 0, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -6, -43, -43, -2, 65, -13, -4, 9, 1, 1, 2, 1, 0, 0, 1 }, { 0, 1, 0, 0, -1, 0, 1, 1, 0, 0, 1, 2, -1, -1, -3, -1, -23, 1, -61, -55, 3, -28, -6, -4, -4, 8, 2, 1, 1, -1, 0, 0 }, { 0, 1, -1, 1, -1, 0, -1, 0, 1, -1, 0, 1, -1, 0, -9, -4, -48, -19, -52, -46, 11, -12, 5, -14, 0, -10, 0, 0, -1, -2, -1, 0 }, { 0, -3, -1, -4, 2, -1, -7, 3, 1, 3, -1, 1, -3, 0, -7, 0, 3, -7, -61, -51, -4, -21, -16, -21, -11, 14, -7, 8, 3, -5, 1, 2 }, { 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, -1, 9, -3, 56, -11, -6, -67, -1, 13, 0, 7, 1, -9, -1, -1, 0, 0, 1, 0 }, { 14, 9, -2, 14, -10, -10, 9, -5, 1, -8, -23, 30, 8, -7, 23, 8, 2, 10, -1, -27, -17, 57, 22, 4, -5, 2, -12, -6, 2, -7, -4, -9 }, { 1, 5, 12, -2, -2, -3, 2, -3, 6, 0, 4, -2, -8, -6, 0, 16, -15, 29, -55, -29, -24, 29, 3, 10, 6, 13, 10, -5, 21, 11, -14, 5 }, { 4, 2, 26, -6, 10, 11, -23, -10, -27, -20, 3, -24, -11, -10, -13, 25, -10, 5, -9, -36, -7, 43, 3, -13, 6, 13, -2, 0, 1, 3, -3, -4 }, { -1, 0, -1, 0, 0, 0, 0, -1, 1, 0, -1, 0, 0, 0, -1, 1, -12, 12, -26, -64, -15, 29, 37, -7, -3, -12, -5, 14, 8, -8, -10, -2 }, { 19, -4, -11, -16, 8, 14, 5, 19, 3, 22, -11, -21, -1, -6, -11, 11, 10, -24, -23, -40, -8, 20, 17, 5, 13, -6, 3, 14, -20, -8, 3, 28 }, { 2, -12, 10, -14, -18, 26, -22, 4, -2, 5, -21, 8, 3, 1, 19, 0, -12, 24, -14, -40, 15, 29, -15, 6, 15, 1, -19, 2, 4, 7, -12, -3 }, { 0, 17, 13, 7, -5, -11, 2, -19, 3, 38, -21, -3, -6, -4, 7, 1, 1, -5, -40, -10, -2, 35, 8, 8, -10, -8, -9, 33, 4, 4, 0, -2 }, { -2, -12, 7, 29, -24, 2, 16, -1, -7, 16, 10, -2, -2, -2, 13, -2, -37, 15, -22, -40, -11, 33, 10, -1, 8, 10, 6, 8, 9, 0, -12, 2 }, { 15, -8, -9, -2, 7, -17, 7, 19, 14, 4, 12, 27, 11, 10, 4, 11, -15, 14, -13, -48, 5, 18, 0, -9, -36, -11, 2, 4, 5, 5, -15, -12 }, { -12, 0, 3, 4, 7, -5, 5, -14, -24, -18, -6, -15, -8, -20, 1, -7, -33, -28, -40, -38, -18, -10, -5, 17, -12, 4, 3, -5, 5, -13, 4, -7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -3, -9, -49, -60, -5, 45, -1, 6, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 3, -2, 9, -29, -11, 55, 8, 32, -36, -13, -7, 37, 4, 11, 0, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, -1, -39, -4, -30, 63, 28, -17, -6, 10, 7, -14, -9, 11, 9, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 13, -2, -50, -32, 22, 51, 4, 7, 6, 11, -20, -13, 9, -5, 21, -4 }, { -8, 2, 1, 22, -31, -6, -25, -3, -3, 1, -15, -11, -2, -3, 4, -13, -9, 15, -18, 37, -7, -37, 12, -13, -11, -25, -10, -11, -22, 7, 16, 7 }, { 14, 10, 4, -10, -1, -5, -7, -3, 16, 13, -5, -15, 5, 11, -1, 8, -27, 7, -12, 49, 17, -22, 9, -2, -9, -1, 2, -15, -1, 41, -18, -17 }, { -4, -9, -15, -3, 3, 4, 4, 2, 7, -3, -7, -8, -5, 17, -19, -7, 36, -9, -38, 17, 1, -48, 11, -18, -13, -2, -8, 4, -10, -5, 21, 11 }, { 15, -13, 4, 2, 1, -5, -2, 1, -10, 7, -1, 3, -6, 0, 11, -11, 8, 20, -17, 51, -17, -41, 2, 15, 4, 8, -2, 16, -32, -1, 17, 6 }, { -8, 8, -18, -5, 4, 6, -3, 8, 0, -4, 2, 0, -1, -4, 5, 8, 30, 30, -8, 70, 2, 8, 2, 0, 7, 1, 13, -1, -6, -7, -11, 2 }, { -8, -7, 9, -10, -13, 6, -11, -14, 13, 25, -26, 5, 2, -5, -5, 5, -8, 4, 0, 33, 12, -38, -4, 6, 13, 6, 25, 34, -1, 25, -19, -5 }, { 18, 3, -17, 4, -8, 7, 20, 1, -1, 5, -5, -2, -8, 8, -35, 15, 24, 43, -5, 51, 5, -12, -3, 1, -2, 3, -3, -3, -9, 8, -9, 2 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 10, 24, 76, -2, -22, 11, -1, 4, 33, 4, 1, -1, 1, 2, 0 }, { 0, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 2, 0, 24, 13, 32, 70, 26, 5, -21, -9, -6, -15, 2, -2, 2, 4, 1, 1 }, { 5, -4, -11, 4, -4, 22, 10, -2, 13, -11, -4, -21, -17, 0, -7, 4, 10, -34, 11, 52, 2, -46, -5, 0, 0, -1, 2, 4, -9, 1, 1, -7 }, { 0, 1, 1, 0, -1, 0, 1, 0, 1, 1, 0, 1, 0, 0, -3, 1, -8, 9, -1, 64, -13, -61, -3, 3, -5, 10, 1, 3, -1, -1, -1, -1 }, { 0, 1, 0, -1, 0, -1, 0, 0, 1, 0, 0, 0, 1, 1, 2, 1, 10, -2, -31, 79, -10, 27, 0, -1, 3, 8, 1, 1, 0, -1, 0, -1 }, { 3, 12, 10, 26, -19, 10, -9, 6, -4, -15, 10, 3, -16, 6, 11, -19, 3, 10, 18, 44, 5, -30, 5, -9, 21, 4, 20, 10, 14, -25, 8, -17 }, { 0, 0, 0, 1, -1, 0, -1, 0, 1, 0, 1, 1, 0, 0, -6, -2, 8, -8, 13, 69, 26, -19, -25, -17, 16, 6, -12, 22, 2, -6, 9, 5 }, { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 10, -18, 70, -2, -52, -1, -7, 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, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, { 0, -1, 0, 1, 0, -1, -1, 0, 0, 1, -2, 1, 0, 0, -4, -1, -34, -15, -33, 56, 9, -42, 9, 10, 6, 9, -8, -11, 0, -6, 15, 5 }, { 10, 2, -14, -3, -15, -35, -1, 7, -18, 14, 8, -1, -15, -26, 6, -15, -18, 22, 9, 33, 0, -32, -9, 3, -11, 7, 4, -1, 5, 30, 9, 1 }, { 4, 15, 0, 6, -5, -11, 9, 6, 6, 6, 14, 2, -1, 10, -24, -25, -2, -4, -1, 37, 2, -29, 14, -9, 22, 17, -2, 33, 10, -25, 11, -11 }, { 0, 5, 2, 18, -12, 21, 22, 33, -7, 21, -9, -7, 7, -15, -7, 16, 7, 0, -14, 44, 10, -25, 5, -4, 15, -8, 10, -4, 5, 9, -1, 16 }, { 3, 13, 12, 12, 8, 25, -23, 8, -22, -3, -18, -8, 15, 12, 9, 19, 0, 0, -9, 49, -27, -15, -9, -15, 12, -8, -16, -7, 13, 5, 13, 2 }, { 12, -6, 7, -2, 20, -9, -14, 12, 13, -5, -17, 22, -8, -4, 2, 7, -13, -2, -15, 43, -5, -30, 27, 4, 10, -27, 5, 27, -10, -10, -18, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, -1, 10, -18, 70, -2, -52, -1, -7, 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, 10, -18, 70, -2, -52, -1, -7, 0, 0, 0, 0, 0, 0, 0, 0 }, { 15, -13, -20, 16, 2, 13, 5, -11, -8, -5, -3, 2, 24, -23, 30, -7, 11, 30, -15, 43, 5, -15, 15, -3, -14, 1, -23, 8, 3, 9, 4, -11 }, { 16, -18, 7, -4, 31, -15, -9, -13, 20, -12, -6, 0, 12, -6, -2, 4, 3, -3, -1, 0, 1, 3, 3, -2, 1, 6, 4, 0, -3, 2, -5, 1 }, { 38, -5, -13, -4, 8, -15, 11, 1, 2, -4, -1, 9, 13, 4, -12, -7, 0, -2, 7, 2, -6, -2, -3, -2, 3, -4, 6, 15, 1, 1, -11, -2 }, { 47, -22, 9, -26, 3, -5, 2, -7, 4, -2, 2, -2, 3, 0, 3, -4, 3, -3, 2, -3, 7, -3, -1, 1, 1, -5, 5, 0, 2, -5, -3, -2 }, { 14, -16, 2, -6, 7, -2, -7, -4, -4, -7, 14, -3, 7, -19, -14, -17, -29, 6, 26, 16, -5, 13, -4, -1, 21, 14, 1, 3, -6, 0, -7, -1 }, { 29, -11, 5, -3, 4, 11, 4, -10, 1, -22, -3, -10, 5, 4, 2, 8, -2, -7, -12, -12, -8, -3, -18, -2, -9, -5, -1, -3, 2, -14, -14, 7 }, { 28, -12, 5, 3, 9, -7, 0, -2, 2, 1, 4, 0, -7, -3, -2, 4, 4, 14, 8, -1, -4, 14, -7, 17, -2, -2, -9, 2, 19, -7, 9, -8 }, { 31, -18, -22, 8, 15, -5, -10, -15, 1, 10, 6, 7, 6, -8, 2, -1, 12, -3, 3, -1, 1, 5, -6, -4, 0, 1, 7, -10, -2, 4, -3, -4 }, { 53, -30, -4, 12, 2, 3, -3, -3, 0, 1, 6, 5, -5, -4, -7, 1, 0, 2, 1, 3, 1, 5, 0, 2, 2, -1, 0, 4, 2, 0, -2, 0 }, { 27, -18, -3, -2, 4, -8, 3, -2, -11, 2, 10, -8, -8, -4, 0, -2, 8, 0, 9, 0, -16, 11, 1, -6, 13, -3, -10, -13, -15, 25, 1, 0 }, { 35, -5, -1, -8, 23, 11, -14, -3, 2, -2, 8, -6, 17, -2, 7, 0, -2, 10, -17, 13, -2, -2, 11, 11, -14, 2, -2, -3, -8, -1, -12, -5 }, { 29, -9, 7, 3, 2, -10, 0, 3, 9, 0, -3, 5, 1, -10, 10, -5, 3, 6, -20, -9, -6, -4, 1, 0, 12, 17, -8, 9, 3, -1, -9, 0 }, { 15, -16, 18, -19, 16, -15, 17, -18, 13, -16, 17, -14, 15, -9, 13, -17, 9, -7, 4, -5, 3, -4, -3, 0, -6, 7, -9, 7, -2, 7, -9, 9 }, { 21, -10, 7, -2, 12, -7, 13, -17, 11, -2, 20, 3, 5, -11, -6, -6, -15, 0, -9, 5, -11, 7, -1, 7, 8, -10, -9, 3, -5, 9, -8, -2 }, { 23, -22, 15, -5, 16, -4, -3, -12, 9, 3, -1, -2, -8, 2, -2, -16, 3, 4, -2, -6, -7, 12, -8, 2, -14, 2, -7, 11, -2, 6, -4, -1 }, { 34, -17, -4, 8, 4, -6, 1, 8, 4, 16, 3, 6, 12, -1, -1, -15, 6, 4, -7, -6, 6, 0, 2, 1, -2, 2, 3, 3, -3, -2, 8, -6 }, { 18, -18, 2, -2, 10, 1, 18, -23, -3, -10, 0, 4, 20, -19, -3, -4, 2, 8, 6, 1, -3, 1, 1, 3, 5, -1, -11, 3, -7, 5, -1, 1 }, { 15, -14, 2, 3, 10, -8, 12, -13, 13, -15, 6, -8, -4, -10, 14, -9, 24, 2, -7, -18, 13, -11, 8, 14, -6, -2, 3, -1, -4, 7, -7, -4 }, { 20, -12, 13, 5, -1, -10, 15, -6, 8, -1, -3, -10, 17, 0, -6, -19, 2, -1, 8, -3, -16, 0, -3, 2, -2, 0, 8, -9, 0, 1, -10, -9 }, { 32, 0, -9, -5, -1, 5, 13, -11, 8, 3, 11, -11, 0, -8, -2, -14, 7, 10, 6, -5, 1, 10, 2, 12, -10, 4, 4, 6, 4, 0, -7, -10 }, { 16, -14, 10, -7, 11, -11, 11, -11, 18, -13, 8, -15, 16, -11, 13, -9, 8, -7, 12, -11, 7, -6, 3, -5, 9, -5, 4, -1, 7, -4, 8, -3 }, { 24, -27, -1, 5, 8, -5, 12, 7, 4, -3, 3, -1, -9, -11, -13, -5, 10, 0, -13, 7, 1, -5, 4, -9, 7, -3, 13, 2, -5, -3, -17, -2 }, { 23, -19, 15, 1, -10, -18, -12, -6, 8, -3, 12, 0, -12, -10, -4, -4, 8, -10, 4, 2, -2, -8, 13, -3, -2, -6, 2, -3, 5, -2, 2, 11 }, { 25, -12, 4, 2, 24, -3, 3, -6, 14, 11, 0, -21, -3, -3, 1, -8, 7, 0, 0, 3, 3, -6, -7, 6, 2, 1, -4, 5, -1, 10, -2, 9 }, { 24, -8, -6, 7, 16, -12, 13, -1, 11, -21, 2, -6, 3, -12, 0, 9, 4, 11, -7, 1, 4, 1, -8, 3, 3, -6, 3, 3, 0, -8, 8, 4 }, { 25, -21, 13, 14, 13, -18, 4, -3, 0, -5, -4, 5, -3, 0, 4, 12, 7, 3, 5, -5, 2, -2, 3, -10, 2, -9, -15, 6, 1, 7, -5, 1 }, { 23, -16, -2, 10, 4, -1, 3, 1, 32, 3, -5, -2, 9, 10, -1, -4, -6, 2, 9, -1, 14, 12, -6, -1, -17, -2, -4, -9, -7, -6, -8, 3 }, { 50, -8, 5, 2, -11, 10, 0, 0, 6, -3, 7, 0, -3, -2, -3, 0, 6, -4, 2, -5, -9, 0, 3, 10, 1, -7, -2, -3, -6, -9, 1, -2 }, { 28, -17, 0, -2, 2, -9, 1, 5, -4, -1, 0, 0, 19, -27, 5, -12, 7, -14, -3, -6, 10, -2, -4, -2, 4, -5, -2, -7, 1, 7, -9, 4 }, { 22, -19, -6, -6, 3, -22, 3, 5, 20, -8, -14, -5, 1, 1, 20, 2, 16, 6, 3, 14, 4, 3, 5, 1, 5, -7, -10, -6, 3, -6, 1, -14 }, { 29, -14, -8, 13, 8, -10, -6, 4, 4, -6, 5, -7, 1, 12, 14, 11, -7, 1, 2, -9, -11, -9, 0, 4, -1, 7, 10, 4, 4, 20, -1, -11 }, { 18, -9, 4, 1, 7, -29, 12, 1, -1, -9, -2, -1, -2, 2, 9, -8, -13, 5, 4, -13, -4, 2, -5, -7, -6, 14, -10, -34, -3, 1, -3, -13 }, { 38, -9, 24, 8, 11, 4, -6, -11, -2, -12, 1, 1, -11, -8, -5, -2, -15, -8, 8, 0, 1, -7, 5, 4, -1, 8, -2, 11, -3, -1, -5, -5 }, { -20, 11, -4, 24, -11, 1, 15, 4, 0, -28, -10, -1, 10, 10, -6, 5, -6, 2, 7, -2, 1, -2, -6, -3, -7, 1, 2, 12, -1, 7, 0, -2 }, { -9, 10, -23, 27, -4, -17, 20, -6, 14, -17, 5, -1, 5, -9, -7, 5, -6, 4, -2, 9, 0, 8, 0, 1, -3, -3, -5, -8, 5, -2, -2, 12 }, { -10, 19, 4, 9, 1, -16, 17, -2, 9, -29, -16, -11, -4, 7, -5, 4, -1, -3, 3, 2, 3, -4, 5, -12, -2, 6, 5, -4, 4, 1, 4, 10 }, { -20, 10, -24, 14, -5, 11, 9, 0, 16, -20, 10, -5, -6, -6, -1, 2, -4, 5, -16, 8, -2, 5, 5, -11, 9, -11, 4, -11, -1, -1, 4, 3 }, { -9, 11, 3, 19, 24, 4, 5, -14, 30, -17, -4, -2, -17, 7, 2, 3, 1, 3, -7, -4, 2, -3, 1, 4, -1, -1, 3, -12, -2, 3, -3, 10 }, { -19, 18, 11, 19, 19, 19, 10, 4, 13, 6, 5, 4, 8, 3, -2, 12, -6, -2, 7, -6, 15, 12, 16, 16, 18, -3, -4, -20, 0, 10, -9, -3 }, { -21, 9, 20, 12, 0, -3, 5, -9, 15, -13, 5, -5, -6, 24, 2, 9, -5, 2, -7, 2, 5, 7, -5, 2, 15, 3, 1, -1, -4, -2, 7, 0 }, { -18, 16, 13, 15, 2, -10, 14, -11, 4, -11, 5, 12, 12, 20, 8, 30, 2, 11, -9, 7, 0, -3, -16, -5, -6, 5, -4, -21, 0, 5, 6, 1 }, { -26, 8, -13, 9, 6, -10, 2, -11, 7, -4, 6, -19, -11, -6, -12, 16, 0, 5, -7, 8, 5, 6, 17, -9, 10, -10, 5, -3, -11, 2, 4, 10 }, { -11, 17, -3, 22, -5, 18, 3, 1, 4, -5, 14, -27, 5, -7, -4, -5, -10, 11, 1, 15, 1, 1, -6, -5, 10, -22, -7, -7, -15, 13, -4, 5 }, { -17, 14, -7, 13, 3, 0, 13, -6, 9, -14, -22, -1, 1, 19, 14, -3, 4, -13, -13, 2, -4, 8, -2, -2, 13, -12, 13, -12, -7, -5, -3, 6 }, { -17, 17, -1, 33, 6, 3, 9, -16, 3, -14, -8, 6, -17, 8, 3, 13, 8, -6, 3, 1, -2, 0, -2, 8, 4, 9, 13, -10, 4, -17, 0, -6 }, { -20, 7, 7, 21, 1, -3, 7, -3, -2, -12, 9, -7, 2, -3, 14, 1, -1, -7, 12, -10, 5, -20, 11, -2, 0, -24, -17, 6, 6, -4, 3, -1 }, { -8, 10, 6, 7, -1, -6, 28, -6, 10, -33, 1, -20, 0, -12, 10, 1, -6, 8, -3, -1, -10, 8, 5, 0, 10, -2, 8, 16, -5, -3, -7, 4 }, { -17, 13, 3, 15, 1, -5, 27, -5, 6, -6, 12, 2, -4, 8, -1, -3, -2, 12, -15, 3, 4, 1, 2, -9, 0, -16, -21, 2, -4, 16, -7, 4 }, { -15, 20, 8, 17, 5, -14, 15, -11, 21, -11, 13, -13, 2, -15, -13, 1, -5, 5, 2, 10, -9, 4, -1, 3, 2, -4, 13, -5, 1, -4, 5, -3 }, { -21, 8, 2, 16, -1, 2, 15, -16, 13, -12, -12, -7, -8, 2, -7, 11, -8, 5, 2, -7, 16, -4, 1, -7, 3, -15, 6, -5, -8, 2, -8, 5 }, { -15, 17, -6, 3, -3, 3, 9, -7, 14, -23, 11, 1, -1, 4, 7, 6, -1, -14, 7, 6, -8, 5, 1, -15, 10, -9, 2, -3, -1, 4, -10, -4 }, { -10, 18, 3, 11, 1, 4, 14, -14, 7, -4, 15, -10, 10, -11, 10, -4, 5, -14, 10, 4, 15, -12, 15, -13, 20, -15, 14, -15, 8, -11, 4, -6 }, { -7, 23, 2, 20, 7, 8, 19, -5, 9, -16, -8, -17, -5, 1, 5, -6, -8, 1, -6, -4, 10, 6, 6, 2, -11, -4, 0, 2, 4, 7, 9, -4 }, { -15, 20, -5, 22, 11, -8, 9, -5, 10, -13, -8, 8, 2, -2, -3, 7, 6, 10, 1, 2, -5, -9, 1, 10, 16, -22, -7, 0, 7, 7, 6, 1 }, { -26, 19, -5, 3, 5, 25, 18, -5, 9, -14, -8, -6, -2, -6, 2, 3, -8, -2, -7, 7, -3, 7, 3, 4, -8, 0, 1, -8, -4, -2, -2, 1 }, { -20, 14, -10, 6, -3, 7, 8, -32, -2, -7, -2, -10, 16, -12, -9, 15, -2, -5, -6, 2, -7, 5, 9, 1, 6, -7, -1, 0, -2, -4, -7, 3 }, { -14, 16, 4, 11, -8, 1, 23, -4, 17, -13, -10, 1, 12, 9, 12, -4, 7, -1, -1, 5, -8, -6, 3, 3, -6, -3, -18, 0, 18, 20, 4, -2 }, { -33, 19, -10, 30, 15, 2, -3, -1, -4, -14, 7, -7, -1, 7, -8, 9, -1, -3, -5, 2, 2, 4, 0, 5, 0, 0, 2, 3, 3, -3, -3, 4 }, { -6, 20, 0, 5, 17, -10, 18, -17, 9, -16, 4, -13, -6, 2, -14, 14, -28, 9, -12, 25, -4, 7, 7, -8, 6, -6, -2, -10, 2, -11, -1, 2 }, { -12, 14, 12, 52, -3, 5, -5, 4, 8, -13, 2, -5, -4, 2, -2, -1, -2, 3, 3, 5, 2, 3, 0, 1, -5, 2, -4, -3, 1, -5, -2, 0 }, { -13, 6, 9, 24, 0, 8, 14, -15, 18, -9, -11, -8, 3, 15, -2, -4, -9, 4, -3, 12, 14, -13, 11, -4, 2, -4, 0, -6, -6, -6, -14, -1 }, { -10, 28, 3, 12, 9, 3, 11, -28, 6, -11, -7, 4, 0, 7, 8, -9, 0, -6, 0, -16, 4, 7, 4, 4, 7, 3, 4, -7, 0, -3, -10, 6 }, { -11, 14, -2, 19, -1, -1, 7, 9, -2, -27, 10, -14, 15, -4, 12, -4, 2, -2, -6, 12, -6, 0, -5, -4, -5, 1, 3, -11, 5, -9, 3, -8 }, { -18, 7, 13, 16, -4, 3, 9, -10, 10, -10, -3, -22, -4, -12, 3, -16, 0, -3, -16, 8, -11, 1, 10, -7, 15, 3, 0, -1, -13, 8, 1, 6 }, { -20, 10, -10, 10, 8, -1, 6, 0, 16, -12, 9, -10, -1, -5, -4, -13, 13, 16, -8, 12, -2, 14, 18, 13, 0, -16, 2, -5, -5, -5, -4, 3 }, { -14, 5, -7, -17, 5, -13, 23, 20, -4, -1, 1, -6, 13, 5, -1, 4, -14, -2, -7, 8, 3, 2, 2, -7, 2, -1, 4, 7, 3, -9, -1, -5 }, { -19, 3, -24, -28, -9, -7, 19, 3, 2, 19, 7, 5, -13, 8, -15, -17, 3, -11, 4, 13, 3, 2, -1, -3, -4, -4, 2, 0, -5, -6, 6, 2 }, { -17, 18, -30, -20, -2, -3, 1, 15, -1, -11, 6, -4, 11, 11, -4, -5, -10, 0, 0, 1, 3, -7, 8, 2, 5, 1, 5, -5, 1, 6, 4, 1 }, { -6, 1, -30, -25, -1, -8, -2, -9, -17, 16, 3, -1, -2, -9, -6, -7, -3, 12, 6, -4, -10, 0, 10, -8, -6, -5, -3, -11, -4, 0, -1, -3 }, { -1, -1, -34, -28, 1, -10, 2, 9, 4, 16, 2, 6, 14, 17, 0, 7, -4, 4, 4, 4, 0, 1, -1, -5, 8, 1, -4, 1, -9, -2, 5, 6 }, { -11, 14, 1, -31, -7, -24, 9, 7, 6, 5, -13, 1, -1, 3, 4, -1, -2, -8, -6, 3, 5, -4, -6, 7, -2, 5, 3, 3, 0, 0, -5, 2 }, { -25, 8, -11, -18, 1, -4, 8, -3, -4, 15, 6, -5, 8, 2, 3, 4, -4, 5, 6, 8, -7, 6, 1, -11, -15, -13, 9, -4, -14, 10, 12, 7 }, { -20, 11, -15, -25, 3, 4, 18, 13, -4, -5, -9, -1, -5, -2, -2, -7, 16, 5, -4, -5, -7, -2, -3, -9, 11, -2, 0, -7, -17, -6, -11, 6 }, { -11, 18, -5, -20, -15, -3, 9, 11, -20, 12, 5, 5, 11, -3, 7, 1, 10, -6, -3, -3, 3, 3, 14, -7, 10, -17, 9, -11, -2, -6, 7, -12 }, { -20, 8, -14, -17, -9, -13, -3, 0, -27, -14, -3, -14, 4, 3, 6, -6, 7, 4, 23, 9, 11, 9, 3, -4, 9, 2, 4, -1, -6, 1, -8, -11 }, { -9, 14, 2, -37, -7, 13, 6, -11, -6, 9, 18, -11, -6, 2, 12, 4, -1, 3, 1, -2, -2, 1, -9, -4, -2, -3, 3, 5, -6, 0, -2, -8 }, { -29, 8, -1, -13, -2, 8, 23, 2, -10, 7, 13, -6, -5, 11, 13, 0, -10, -13, 11, -12, -10, 6, 4, 6, 4, 3, 6, -5, -9, -2, -1, 3 }, { -18, 6, -10, -55, -4, -11, -2, 0, 1, -3, -9, -6, 3, -2, -1, 6, 3, -1, 3, 1, -4, -7, -2, 6, 3, -2, -1, -3, -2, 0, 4, 1 }, { -14, 5, 3, -21, -8, -16, -4, -2, -11, 27, 15, -20, 3, 0, 1, 1, 2, -5, -5, 4, 1, -9, 5, -3, 3, 0, -4, -2, -11, -4, -3, 7 }, { -17, -1, -9, -17, -8, -18, 12, -13, -9, 13, -3, 3, 3, -3, 1, -2, 0, 16, -9, 6, 12, 9, 5, 11, 2, -15, 1, -4, -16, 7, -4, -12 }, { -18, 8, -6, -11, -8, -7, 13, 7, 1, 6, 8, -1, 21, -4, 14, 15, 18, -4, -3, 15, 0, 9, 4, 7, 3, -1, 9, -2, 0, 7, -8, 2 }, { -10, 7, -18, -29, 3, 12, 12, 9, 11, 4, -1, -15, 1, -1, 8, -2, -2, 10, -15, -1, 0, 6, 12, -6, -1, 10, -6, -3, -11, -4, 9, -6 }, { -14, 14, -9, -21, -12, -2, -1, -7, -5, -10, 5, -8, 0, 6, 9, -11, 11, -3, -5, 3, 8, 15, -2, -4, -22, 4, -6, 12, 2, 13, 6, -7 }, { -12, 11, -5, -29, -25, 4, 12, -13, -11, -7, 4, 2, 2, -5, 5, 8, 7, -5, -5, 6, 3, -10, 1, -6, 6, -6, -5, -1, -2, -4, 7, 6 }, { -15, 11, -5, -16, 0, -13, 26, -23, -6, -3, 5, -2, -2, 21, -6, -3, -5, -1, 6, -1, 0, -13, 2, -3, -9, -1, -4, -3, 5, -4, 12, -16 }, { -9, 9, -1, -17, -3, -6, 12, 6, -18, -2, 11, -14, -6, 3, 14, -12, -11, -5, 14, 2, 5, -8, -4, -11, 2, -5, 16, 6, -7, -4, 8, 13 }, { -13, 5, 3, -28, -14, 0, 6, 23, 5, 4, -1, -17, 1, -3, 0, 0, 5, 4, 0, -18, 14, 10, 4, 2, 5, -2, 4, -3, 2, 0, 2, 0 }, { -15, 4, -13, -16, -3, -12, -2, 2, 7, 10, 9, 3, 11, 4, 23, 14, 9, 16, 4, 1, -12, -3, 4, -7, -15, -7, -10, -14, -6, -8, -1, -6 }, { -7, 10, -5, -10, -3, -13, 16, -1, -12, 7, -3, -12, 2, 13, 13, 2, 17, 15, -13, 1, -5, -2, 3, -1, 1, -3, 6, -3, -12, -16, 7, -7 }, { -11, -5, -12, -30, -6, -22, 1, 4, -6, -3, 12, 6, 7, 0, 16, 6, -2, 0, -22, -2, -9, 2, -13, 8, 6, -8, 4, -7, -1, -6, 4, 6 }, { -14, 5, 1, -27, -4, 2, 1, 14, -11, -7, -8, -4, 1, 8, 0, -6, -13, 11, -12, -7, -5, 1, 10, 7, 3, -2, 0, 6, -8, 2, 10, -1 }, { -10, 10, -25, -13, -20, -4, 19, 3, 13, 5, 5, 7, -8, 2, 4, 2, 3, -1, -1, -9, 14, 10, 9, 14, 3, 3, -6, 0, -5, 4, 1, -1 }, { -9, 15, -18, -17, 4, -11, 6, 7, -12, 8, -1, -11, 2, 3, 7, 16, -3, -9, 7, -12, 23, 0, 6, 7, -14, -9, 8, 1, -2, 6, -2, -1 }, { -6, 9, -16, -26, -14, -11, 9, -6, 5, -2, 13, 17, 21, 7, 18, -19, 6, -23, -2, -15, -2, 2, -10, -8, 2, 1, -2, 4, -3, -4, -5, -4 }, { 0, 6, -5, -28, -17, -32, 2, -10, 11, 3, -5, 9, 10, 3, 11, 11, -3, 12, -2, 2, 4, -6, 9, -4, -4, -4, -4, -9, 2, 0, 2, 4 }, { 0, -8, -18, -34, -9, -7, -4, -11, 10, 15, 11, -1, -8, 15, 6, -13, 9, 2, -4, -12, 0, -1, 19, 12, 6, 5, 0, -3, -10, -12, 3, -5 }, { -10, 6, -9, -17, -12, -11, 9, -6, 11, 11, 18, -7, 0, 16, 4, 2, -6, 3, -12, -1, 0, 1, -5, -22, -2, -12, 0, 6, 17, 5, 5, 6 }, { 12, -5, 7, 1, -5, -2, -1, 2, 2, -4, -3, -3, -3, -2, -29, 11, 5, -13, -73, 24, 12, 4, -14, -10, 5, 1, 0, -11, -7, -7, 7, 3 }, { 10, -3, -1, -3, 4, -11, -5, -2, -8, 7, 9, 2, -8, -6, 6, 7, 21, 17, -54, 47, -14, -10, 14, 19, 13, 21, -4, 3, 1, 2, -4, 2 }, { -12, 4, -16, -12, 5, -9, -4, 19, -7, -22, -22, -17, 3, 0, -6, 8, 23, -4, -55, -28, 2, -26, 2, 1, 4, 0, -13, 6, 0, 10, -7, -11 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, 35, -1, -67, -35, -24, -24, -6, 2, 2, -2, 1, 3, 2, 0, -1, 1 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 5, 0, 41, -4, -73, -15, 18, 4, 17, 8, -1, -16, -1, -2, 1, 0, 0, 0 }, { -4, -4, 4, 6, -1, 2, -16, -10, -15, -10, 21, -2, -6, -2, 14, -7, 10, -5, -55, 34, -12, 11, -13, -2, 2, 28, -26, 0, 7, 4, 21, -7 }, { 2, 1, 15, -22, 10, -3, 14, -6, -2, 15, -2, -7, 20, 6, -15, -7, 23, 10, -60, 8, -4, 29, -22, 2, -13, 9, -10, 12, -1, -3, 4, 7 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, -1, -2, 11, -5, -21, -11, -60, -27, -17, -39, 6, 36, 0, -8, 2, 2, 0, 0, -2, 3 }, { 2, -5, 9, -17, -1, 2, -3, -6, 8, 12, 7, -6, -33, -11, -14, -40, 10, 36, -46, 0, -19, 5, 0, -10, 3, 12, -6, -8, 6, -12, -7, 1 }, { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 1, 0, -2, 0, 4, -2, -87, -3, -2, 2, -2, 20, 2, 6, -1, 6, 0, 0, 2, -1 }, { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 1, 1, 7, -76, 41, -7, -24, 0, -6, 3, 6, 0, -2, -1, 1, 0, 0 }, { 0, -3, 4, 2, 3, 2, 2, 0, 3, -1, 4, 0, -1, 4, -2, -4, -32, -11, -64, -29, -9, -43, 2, -11, -1, -7, 0, -4, -2, -2, -2, 2 }, { 10, -20, 3, -3, 13, 13, 0, -4, 2, 7, -8, 7, -2, 2, -20, -20, -19, 3, -47, -18, -16, -6, -15, -42, -17, 14, -6, 8, 12, -10, 11, -12 }, { -3, -2, -2, -1, -1, 4, -3, -1, -6, -2, 3, 2, -3, 6, -1, -9, 10, 13, -68, -9, 26, 3, 5, 3, -21, 10, -15, 21, -22, 19, 11, -14 }, { 1, 5, 18, -19, -29, -13, -2, 18, -10, 20, 2, 10, -10, 11, 1, 8, -16, -17, -41, 10, -14, -25, 0, -14, -19, 17, 7, -12, 14, -11, 14, 5 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, -1, -43, 5, 6, -12, -48, 19, 8, -38, -8, -3, 22, -21, -10, 15, 20, -9, -5, 8 }, { 0, 0, 0, 0, -1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 6, -3, 22, -14, -71, -24, -2, -33, 23, 7, -8, 7, -3, 2, -4, 1, -8, -2 }, { 1, 0, -1, 2, 0, -2, 0, 0, -1, 0, 4, 0, 26, -1, 10, -11, -17, -32, -58, 14, -14, -11, -2, 15, 2, -8, 12, 10, -9, 13, -33, -14 }, { 15, -17, -19, 7, -8, -15, -32, -22, 7, 12, 18, 0, 0, -15, -4, 16, 37, -2, -46, 11, 2, -8, -10, -8, 14, 9, -4, 5, 7, -17, 4, 3 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -2, 0, -5, 3, -85, 23, -9, -17, -2, -2, 0, 0, 0, 0, 0, 0, 0, 0 }, { 16, 65, -2, -2, 4, 3, 0, -7, 3, 1, 3, 1, 0, 5, 1, -5, 0, 2, -1, 3, 0, 0, -1, -2, 6, 0, -2, 0, 0, -1, 1, 1 }, { 5, 37, -4, 8, -4, -1, 9, 17, 6, -7, 5, -1, 11, 6, -4, 7, -2, 4, 1, -3, 11, 3, 3, -9, 6, 0, -2, -4, -5, 4, -12, -11 }, { 15, 24, -14, 2, 6, 17, 26, 5, 8, 11, -9, -7, -6, -8, 3, -5, 9, 10, -3, 10, 0, 1, 4, -9, 4, 9, 3, 0, 4, 0, -5, 3 }, { 9, 36, -9, -8, 7, 7, 4, 3, -1, -16, -2, 7, -5, -6, 6, 12, -11, -12, 9, -1, -3, -9, 12, 6, -6, 2, 2, 5, 0, 5, 6, -6 }, { 25, 39, -5, 24, 3, 10, 3, -6, 13, -8, 3, -7, 2, -10, -5, 2, -2, 3, 5, -2, 1, 5, -2, 3, -4, 1, -5, -4, 0, 1, -2, 0 }, { 16, 27, -1, 0, -14, 6, 4, -5, 7, -2, -6, 0, -3, -5, 2, -1, -1, -19, 5, -8, 0, 11, 12, 5, 0, 3, 10, 6, -14, 14, -13, -15 }, { 12, 23, -14, 2, 1, 4, -3, 16, 7, -8, 2, -8, 8, 6, -8, -7, -3, 0, 2, 8, -13, 7, 13, -6, -4, 6, -13, -16, 14, 11, -7, 5 }, { 16, 28, -7, -1, 6, -3, 9, 0, -7, 3, 0, 3, -12, 20, 8, 9, 8, 23, 8, -13, -2, 4, 9, 3, -5, 13, 5, -2, 12, 14, 5, -1 }, { 19, 37, 19, 5, 7, 5, 10, 5, 19, 10, 14, 0, 2, 5, 1, -4, -4, 2, 2, -5, -2, -1, 2, -6, -4, -4, -5, -3, 2, -2, -2, -2 }, { 24, 21, 1, -11, -10, 17, -14, 14, 6, -1, -6, -1, 0, -13, -1, -12, -2, -5, 6, -4, -12, 14, 5, -2, -8, -8, 15, -7, -30, -12, 4, 0 }, { 11, 26, -3, 3, 5, -1, -2, 3, -2, 10, 15, -4, 10, -28, 10, -17, -8, 1, 2, -7, -1, -6, -15, -1, 4, 5, -7, 9, 0, -5, -4, 4 }, { 18, 32, 1, 2, -7, 4, 15, 2, -9, -2, 12, -11, 7, 11, 13, 2, 0, 5, 9, -10, 16, 3, -3, 5, -9, -23, 2, -2, -1, 5, 2, 11 }, { 35, 24, -20, 2, 4, -1, 5, 14, -10, -9, 8, -7, 0, 5, -7, -7, 11, 1, 5, 3, 2, 0, -2, 3, 0, 1, 4, 0, -2, -8, 0, -4 }, { 9, 35, -1, 2, -1, -19, -3, 12, -1, 8, 8, -13, -1, -2, 2, 5, -8, -1, 13, -2, 11, 1, 0, -10, 0, -3, -7, 2, 1, -12, 3, 12 }, { 20, 27, -12, -12, 7, 4, -1, -13, -1, -9, 2, 13, -11, 5, 7, -9, 9, 1, 1, 8, -9, 0, -6, 7, 4, 2, -2, 7, 3, -2, 1, -9 }, { 8, 37, -20, -5, 0, -21, 10, -8, 3, 19, -9, 7, -3, -8, 10, -2, 0, 5, 6, -4, -2, -1, 0, -7, 6, 1, 0, 4, -5, 6, -8, 2 }, { 8, 27, 1, -3, -5, 1, 6, 0, 15, 2, 17, -1, 3, -17, 10, 5, 5, -6, -6, 6, -10, 18, -5, 0, 0, 13, 7, 10, -5, -6, -2, -4 }, { 14, 29, -20, -4, -3, 1, -5, -1, 2, 12, -10, -3, 4, -18, 4, 14, -4, -1, -9, 15, -2, 2, -5, -3, 2, 9, -2, -14, -3, 4, -4, -7 }, { 23, 23, -23, -11, 27, 4, 4, -1, 7, 0, -5, 9, 2, -11, 3, 7, -2, -5, 2, -7, -7, 13, -3, -6, 2, 3, 3, -4, -1, -8, 5, -2 }, { 16, 26, -6, 8, -9, -1, -2, -1, -8, 4, -2, 0, -12, 9, -1, 0, -17, -9, 30, -5, -15, -16, -13, 0, 10, -11, -7, -3, -1, 0, -11, -2 }, { 12, 32, -4, -5, 10, 19, -10, 4, -12, 5, -6, 9, -12, -6, -6, -8, 4, 1, 3, 0, 8, 0, -3, -4, -7, -4, 10, 8, 6, 5, -1, 4 }, { 46, 42, -3, -14, -2, -6, 6, -2, -5, -1, -3, -3, 1, -1, 3, 1, 1, 4, -1, 2, 3, 1, -2, 6, 0, -1, -2, 4, -2, -1, 2, 2 }, { 9, 33, -13, 4, -11, 3, -8, 22, 12, -2, 4, 0, -16, 5, 4, -1, 7, -6, -9, 1, 7, 5, 0, -5, 5, -1, 10, 3, -2, -1, 3, -2 }, { 9, 30, 6, -3, 6, 1, -7, 5, 11, 14, 7, 1, 0, 2, 2, -1, 8, 7, -6, -13, -10, -2, 1, -6, 10, 7, 6, 5, -2, -5, -1, -16 }, { 9, 28, -11, -10, 9, -10, 15, 8, 4, 9, -4, -7, 0, -5, 9, 8, -7, 2, -15, -23, 4, -4, 4, 16, -8, -3, 0, -8, 14, 5, -3, 15 }, { 17, 26, -5, -5, -1, -8, 20, 18, -7, -2, 4, -7, -8, -5, -4, 16, 0, 0, -7, -2, -13, -5, -2, 3, 12, 1, 3, -5, 2, 2, 0, -1 }, { 11, 37, 7, -23, 6, -1, 15, 13, 4, -9, 7, 5, 3, -3, -5, -8, -2, 3, -5, -1, -8, 7, 2, 13, 1, 3, 0, -3, -1, 2, 0, -2 }, { 21, 33, 7, 20, 21, -10, 6, -5, -5, -6, -9, 2, 10, 0, 8, -4, 10, 2, -2, -2, 0, -10, -6, -2, 0, -5, 3, -11, 3, -9, -3, 1 }, { 6, 30, -15, -8, 16, 1, 4, 6, 4, 5, 8, -3, 8, -9, -1, -6, 8, 2, -2, 4, -2, 5, 11, -21, 3, -10, 16, -11, 24, 10, 14, -6 }, { 15, 36, -3, -9, -20, 12, 0, -7, -18, -4, -8, -9, 9, -7, -3, -1, 2, 7, -5, -8, 6, 2, 2, -1, 7, 1, 1, -3, 3, -4, -8, 1 }, { 16, 34, 21, 3, -9, 10, 7, 9, -7, 1, -4, -9, -4, -5, -5, 3, 3, -19, 1, 5, 4, -2, -6, -5, -10, -11, -8, -2, 2, -5, -8, -7 }, { 28, 29, -3, 18, -2, 0, -6, 12, -2, 10, -11, -4, -13, -12, -6, -4, 0, 4, -1, -8, 6, 4, 12, 11, 10, 10, -3, -6, 1, 2, 1, 7 }, { 3, 8, 22, -8, 3, 36, -8, -1, 9, 6, -13, -14, 8, -1, 1, 2, -2, -8, 0, 3, 1, 2, -1, 5, -1, -8, 0, -2, 2, 2, -1, 1 }, { 0, 6, 0, 0, 4, 13, -7, -16, -6, 15, -14, -21, -9, -10, -10, -6, -21, 5, 4, 2, 12, 4, 12, 11, -4, -6, -6, -10, -7, -18, 1, 4 }, { -1, 3, 10, 1, -1, 15, 4, -7, -16, 3, 0, -22, 10, 2, -3, -2, 13, 5, -8, 16, -5, 4, 0, -11, -10, -22, 0, -4, -17, 5, 2, 1 }, { 12, 8, -4, -9, 14, 40, -21, 0, 1, -15, -10, -12, 12, 6, -10, 2, 8, 6, -12, -10, -11, 1, 0, -11, 2, 1, 13, 0, 6, 3, 8, 4 }, { -10, 3, 5, -4, -3, 3, 0, -9, 2, 8, -22, -23, 17, 8, -17, -3, 14, -8, -4, 1, -8, 3, 0, 5, -1, -3, -2, -4, 1, -10, 0, -2 }, { 0, -1, 5, -7, 4, 12, -2, 0, -7, 2, -16, -15, 12, 21, -7, -4, 7, -7, -11, -15, -7, -9, -5, -8, 0, -6, 8, -3, -8, 22, -7, -9 }, { 7, 19, 4, -9, 24, 22, 2, -6, 8, 13, -14, -20, -4, 11, 8, -4, -1, 2, 0, -7, 5, -17, -3, 3, -6, 5, 3, 4, -5, -7, -3, 14 }, { -2, 6, 2, 8, -2, 5, -4, -2, -10, 3, -45, -30, -3, -3, -12, -4, -3, -3, -1, 9, -6, -6, 5, -4, 0, 5, -1, -2, -1, 0, -6, -1 }, { -3, 14, -16, -10, 10, 0, -2, -40, -9, 12, 2, -19, 15, -4, 4, 3, 3, -4, 7, 1, -4, -5, 0, 4, -1, 0, -9, -2, -4, -1, -2, 0 }, { 7, 16, 2, -7, 8, 2, 0, 1, 5, 21, -10, -26, 7, 2, -9, -7, -3, -16, 8, 5, 5, -6, 10, 4, -14, -6, 5, 3, -2, -2, -4, 1 }, { -9, 14, -1, 3, 3, 11, 1, -5, -3, 13, -16, -18, 20, 6, -5, 0, -3, 2, 8, 4, -19, -9, 12, 0, -8, 2, 2, 1, 6, 13, -7, -11 }, { 2, 5, 16, -4, 19, 15, 4, 0, -11, 7, -10, -10, -16, 18, -11, -12, -9, -4, 7, -4, -4, -17, 1, 1, -8, -3, -3, 5, -2, -6, -11, -5 }, { 2, 12, 0, -9, -10, 14, 6, 2, -3, 2, -12, -28, 12, 1, -1, 2, 0, -3, -4, 7, 16, 5, -7, 8, -4, -3, -1, 3, -12, 4, -17, -5 }, { -4, 7, 11, 6, 1, 14, -4, -6, 5, 5, -6, -24, 23, -9, -15, 13, -7, -9, -15, 10, -1, 8, -5, 1, 12, 6, 2, 0, 4, -2, 9, -10 }, { 1, 5, 11, 3, 6, 12, -3, 8, -21, 5, -7, -20, 12, -2, -9, -3, 17, -7, -8, -9, -14, 3, -13, 18, -8, 9, 2, -8, 4, -8, -5, -2 }, { -3, -3, -1, 5, -2, 15, 3, 2, 1, -8, 1, -39, -6, 13, -13, 0, -2, -5, -6, -3, 0, -5, -2, 15, -9, 5, -3, -6, -2, 7, 0, -13 }, { 2, 8, 5, -12, -13, 22, 8, -16, 11, 5, -2, -32, -2, -4, 11, 5, 5, -6, 1, 3, 1, 5, 3, 6, -5, 4, 4, -8, 8, 4, 1, 3 }, { 13, 9, 5, -4, 9, 18, -11, 2, -1, 15, -10, -19, -2, 14, 0, -10, 1, 1, -18, 3, 2, -6, -8, 20, 7, -8, 16, 9, 9, -13, -3, -2 }, { -13, 11, 11, -9, -10, 13, -3, -18, 2, 10, 5, -21, 6, 15, -11, -21, 3, 14, 0, -12, 9, -1, -2, -4, 3, -3, -9, -8, -5, -2, -8, 2 }, { 3, 3, 11, 4, 0, 13, 1, -8, 10, 13, -6, -26, 2, 12, -3, -5, 12, -2, 1, 8, -7, -17, -19, 5, 10, 7, -3, 2, -3, 0, 5, 0 }, { 5, 0, 3, -3, -9, 5, -15, -5, -5, 17, -5, -31, 0, 13, 13, 5, -1, -6, -14, 7, -8, 9, -14, -2, -16, -4, -4, -6, 6, -6, -10, 6 }, { 13, 3, 1, 7, -3, 4, -1, -2, -1, 4, -8, -32, -1, -4, 0, 3, -10, 7, 10, -10, 4, -1, 6, 2, -16, -9, 4, 3, 13, -23, -3, -4 }, { 4, 11, -4, -9, 4, 11, -12, -12, -12, 6, 1, -28, -3, 14, 18, -2, -12, 7, 15, -3, -5, -7, -3, 2, -6, 4, 4, -2, -5, -3, 2, -13 }, { 8, 7, -7, 0, 13, 7, -8, -7, 8, 36, -10, -22, 3, 23, -3, -10, -3, 11, 1, -7, 3, 3, -1, -7, -4, 2, 3, 2, 5, 3, -4, -1 }, { -1, 1, 13, 1, -6, -1, -6, -9, -18, 17, -5, -37, -1, -1, -6, -4, 1, -6, -15, 2, 17, -9, 0, -3, 0, 4, 0, -5, 0, 4, 1, -5 }, { 0, 14, 5, 0, -7, 2, -6, 17, -6, -9, 7, -16, -5, 23, -14, -13, 8, -15, 11, 10, -11, -13, -33, -5, -2, 1, 6, 8, 0, -13, -9, 5 }, { 11, 7, -2, -8, 9, 11, 25, -14, 7, 3, -1, -33, 14, 8, -6, -19, 3, 3, 2, -1, -3, -1, -2, -10, -3, 1, 2, 1, 4, 2, -3, 4 }, { -2, 8, 4, -2, 9, 13, -4, -2, -15, -3, 19, -37, 9, 25, -9, 2, -5, -2, -2, -4, 4, 2, 2, 0, 3, 3, 3, 5, -2, -3, -4, -3 }, { 10, 13, -1, -15, 4, 6, -18, -4, 25, 1, -23, -17, 15, 13, -8, -8, 7, 4, -5, 3, 6, 9, -7, 6, 0, -5, 8, 0, -6, -1, -2, -2 }, { 1, 3, 9, -5, 27, 15, -9, -31, -1, 23, -2, -9, 1, 8, -1, -7, -2, -8, -4, -4, -2, -1, 3, 5, 0, 0, -1, 1, -7, 7, -3, -3 }, { -8, 7, 3, -6, 8, 3, -11, -2, 36, 14, 1, -30, 6, 10, -12, -6, -6, -2, -4, -3, -5, 0, 9, 4, -5, -5, -8, 12, 4, -3, 1, -8 }, { -2, 9, 33, 0, 12, -3, -7, -4, -4, -1, 6, -25, 11, -6, -9, -11, -2, -4, -2, 6, -1, -3, -6, 15, -6, 3, 10, -4, 1, 0, 5, 8 }, { -22, -21, -9, -19, -5, -7, -12, -15, -8, 9, -19, 14, -7, -4, 5, -8, -2, 7, 1, -3, 4, -4, 6, 11, 2, 6, -3, -5, 2, -2, 0, -3 }, { -32, -13, 3, -24, 3, -8, 4, 1, -10, 14, -15, 0, 4, 6, -1, 6, 7, -1, 6, 4, -3, -17, 1, 4, -6, -1, 1, 0, 3, 3, -7, -4 }, { -32, -11, 7, -8, -12, 13, -5, -22, -4, 12, -16, 2, 0, 4, 0, 1, 0, 6, -5, -8, 2, 6, 5, 0, -3, -6, 5, 6, 5, 5, 13, -4 }, { -44, -33, 6, -4, 2, 0, -9, 10, 3, 4, 7, 0, -1, 7, 5, 1, 1, -3, 1, 6, -1, 0, 2, 3, -4, 0, 0, 1, 0, -1, -2, -1 }, { -30, -18, -24, -8, 5, 0, -2, 14, 7, 0, 1, 12, 6, 4, -9, 7, 5, 7, -11, -5, 1, -8, -1, 2, 2, -9, 7, -1, 7, 5, 6, 6 }, { -22, -20, -13, -9, 20, -3, 10, -8, 6, -4, 2, -7, 10, 8, 0, -1, 2, -3, 6, -19, 2, 4, 3, 3, -7, 2, -1, -6, 1, 1, 6, -2 }, { -27, -8, -1, 3, -1, -11, 24, 4, -1, 1, -8, 8, 5, -11, 15, -3, -15, -1, -1, -13, -1, 1, -5, 5, 2, 3, -9, 0, 4, 3, -7, 6 }, { -33, -16, -1, -8, 10, -23, 6, 13, -1, -3, -9, 0, 5, -7, -5, -12, -2, 3, 3, 6, -2, -3, 2, -3, 9, -6, -3, -2, 0, 5, -3, -4 }, { -22, -17, 11, -3, 3, 1, -1, -5, 17, 2, -15, -2, 10, -9, 6, 14, -16, -12, 20, -1, -7, 6, -3, -12, 1, 10, -10, -1, 7, -3, -1, 10 }, { -28, -13, 1, -3, -1, -1, 0, 3, 3, 5, 1, 10, -10, -3, 7, 2, 4, 19, -1, -1, 10, 5, -8, 1, 11, -15, -4, -3, -5, 4, -13, 3 }, { -22, -13, 42, -20, 5, -13, 7, -11, 1, 1, -1, 1, 6, 3, 6, -11, 3, 3, -2, 0, -4, 4, -3, -1, -5, 2, 0, 0, -9, -1, 4, 4 }, { -26, -15, -2, -6, -4, -2, 16, 8, 21, 8, 1, -3, -10, 7, -8, -12, -5, 12, -9, 3, -2, -3, 18, 1, -12, -15, -4, 5, -3, 0, 12, 7 }, { -26, -16, 5, 6, 14, -3, 15, 6, 1, -7, -13, 16, -15, 5, 11, -2, 9, -7, -4, -2, 0, 0, -2, 7, -8, -6, -5, 2, 7, -3, 2, 12 }, { -31, -17, -8, -30, 4, 14, 6, -6, 6, -11, 0, 3, -4, 0, 0, -4, 0, -4, 1, 4, 3, 4, 0, -5, 3, 2, 2, 0, 2, 1, 3, 5 }, { -61, -10, 4, 10, 4, 7, 0, -3, 0, 1, 0, -3, 0, 1, 0, -2, -1, 1, 2, -2, 4, -3, 1, 1, -1, 1, -2, -4, -4, 4, 0, 0 }, { -28, -13, -8, -4, 3, -3, 2, 1, 11, 14, 3, 9, 1, 13, 3, 5, -3, -2, -2, -12, -14, -9, -11, -15, -12, -5, -4, -12, 3, -3, 0, -5 }, { -41, 0, 12, -24, 13, 4, 5, 16, -5, -4, 0, 0, 13, -4, 1, -9, 9, -6, -1, 6, -2, 5, 2, 9, 6, -9, -8, 8, -2, -3, -6, -4 }, { -26, -19, -2, -15, 4, -14, 6, 0, 26, 20, 8, 9, 9, 3, -4, -5, -8, 1, 0, -1, 5, 9, 3, 4, 4, 7, 1, 3, -2, -2, -10, 0 }, { -29, -18, 9, -4, 1, -5, -14, -12, 5, -10, -5, 4, -5, 0, -1, -1, 4, -5, 7, -16, -11, 2, 7, -15, 2, -4, 6, -4, -6, 7, -3, 7 }, { -27, -16, 9, -14, 3, -8, 9, 0, 7, -4, -3, -7, 0, -10, -1, 2, 1, -2, 15, -10, 14, 7, 6, 17, 3, -4, 3, -10, 8, -8, 3, 11 }, { -21, -20, -8, -8, 4, 5, -3, -2, 0, -5, 14, -10, 11, -4, 13, 0, 5, -11, 19, -18, 18, 3, -5, -3, -4, -8, 11, -10, 10, 3, 4, -9 }, { -35, -15, 13, -12, 4, 0, -2, -4, -12, -3, -8, -24, -7, 1, 7, 8, -3, 0, -2, -1, 3, -2, -2, -6, 8, 1, 0, 1, -6, -1, 2, -6 }, { -19, -14, 13, -10, 9, -1, 1, 3, -12, 5, -16, 7, 13, 9, 4, -4, 6, -5, 4, 9, -3, 17, -4, 12, -11, -6, -5, -6, 13, 2, 7, -9 }, { -34, -8, -4, 1, 2, -1, 3, 6, -20, -11, 8, -1, 4, 2, -9, 4, -4, -5, 16, 10, -4, 14, -13, 1, -6, 0, 2, -10, 0, -3, -3, 7 }, { -36, -10, -8, -3, 2, -2, 14, -4, -1, -7, -4, 10, -1, -3, 15, -11, 0, 2, 3, -1, 4, 0, 8, -1, 0, 18, -11, -5, 15, -5, 13, -12 }, { -22, -13, 14, -20, 15, 25, 16, 10, 8, -2, -10, -5, -1, -8, 11, 8, -1, -2, -4, 1, 2, -1, -7, 0, 0, 0, -3, 0, 2, -1, 0, 2 }, { -31, -22, 7, 6, -2, 5, -20, 14, -6, 7, 0, 14, 3, -7, 3, -6, -2, 1, -3, -5, 1, -10, 1, -24, 6, -2, 3, -7, 1, -7, 8, 7 }, { -25, -20, -3, -9, 10, 6, 12, 7, 5, 4, -3, 6, -1, -5, -6, -8, 3, 5, 6, 5, -10, 10, -4, -15, -15, -2, -9, 2, 18, 1, 8, 12 }, { -24, -19, -2, -4, -7, 11, 6, 9, 16, 2, -7, 18, 6, -7, 6, 6, -2, -9, 3, 12, -2, 3, -1, 6, 7, 8, 0, 8, -11, 8, 4, 2 }, { -26, -20, -12, -12, -2, -3, 1, -5, -1, -2, 0, 3, 7, 9, -2, 2, 9, 22, 13, 4, -4, -1, -2, -14, 5, 15, -8, -5, -7, -11, -14, -6 }, { -21, -18, -1, -4, 0, 3, 7, -2, 10, 8, -8, -1, 15, 1, -9, 3, 1, 3, -5, -2, 2, 4, 0, -1, 10, 2, -19, -8, 8, 30, -7, 8 }, { -25, -6, 26, 4, -8, 4, -2, 21, 5, -4, -16, 5, 13, 4, -10, -1, -6, -2, 2, -10, -13, 1, 3, -3, -6, -8, 2, 11, 1, -7, 0, 5 }, { 0, -1, -2, 19, -12, -48, -6, 11, 8, -2, -4, -2, -7, 5, -3, 2, -2, -1, -1, -7, 0, -3, -3, -4, -4, 4, 1, 3, -3, -1, -2, -5 }, { -11, -8, -28, 18, 16, -24, -8, 19, 4, 8, -12, 9, -4, -2, 4, -7, 6, 2, 3, 3, -4, 0, 1, -6, -4, -2, 2, 6, 0, -3, 1, -16 }, { -9, -5, -26, 7, -3, -37, -16, -2, 2, -7, 4, -13, 0, -4, -6, -5, -6, -4, 0, 3, 4, -3, -4, -4, 4, -3, 9, -4, -2, 2, 7, -4 }, { 2, 9, -18, 7, 29, -24, -1, 7, 14, 10, 3, -3, -2, -5, 6, -10, -6, -3, -8, 0, 5, 1, 4, 3, -12, 2, 6, 1, 3, 4, 1, -3 }, { -20, 2, 8, 20, -9, -24, -4, 18, 3, 11, -1, -11, 6, 9, -1, -3, 1, -1, -15, 3, 15, 9, 3, 2, -13, 2, -8, 8, 1, -1, 1, -8 }, { -12, 5, -11, 6, 19, -26, -17, -6, 4, 14, 6, -8, 9, 5, -6, -5, 2, -1, 20, 1, -11, -10, -18, 20, -7, 0, -3, 4, 2, 0, 10, 4 }, { -15, 1, -2, 13, -8, -21, -22, 4, 4, 3, 3, -7, -31, 4, -10, -14, 0, 8, 4, 5, 8, 11, 2, -8, 6, 7, 0, -2, 6, 8, 8, 7 }, { -13, -10, -9, 12, 19, -16, -3, -2, 9, 2, 11, -29, -1, 9, 4, -3, 1, -10, -10, 16, 1, 7, -7, -6, -4, -1, -5, 3, 6, 0, 3, 1 }, { -17, -1, -5, 19, 12, -9, -21, -5, 2, 12, -7, -7, -3, 8, 7, -2, 6, -9, -9, 1, -4, 1, 1, 3, -14, 2, -8, 0, 10, 1, -12, -6 }, { -13, -5, 8, 15, 0, -20, -2, 20, 8, -8, 8, -19, 12, 10, 2, -11, 0, 12, 1, -11, 0, -11, -15, 5, -11, 2, 4, -4, -11, 5, -4, -5 }, { 3, -11, -7, 8, 0, -17, -26, 15, 19, -7, 10, -9, -5, -5, 14, -25, 0, -8, 2, -9, -3, 9, 1, -6, 4, -4, 3, -9, -1, 6, 2, 2 }, { -12, 5, 5, 9, 14, -18, -19, 4, 2, 16, 14, -21, -15, -9, -1, 16, 12, -11, -10, -5, -7, 4, 15, -8, -5, -1, 1, 14, 13, -7, -1, -4 }, { -10, -5, -1, 8, 7, -23, -10, 14, 6, 11, 10, -16, -3, 16, 6, 0, 0, 9, 6, -2, -7, 1, 22, 5, 3, -8, 0, 3, -2, -10, 3, 0 }, { -2, -14, 2, 16, 15, -17, -17, 6, 19, 4, -10, -15, -1, 15, 11, -14, -8, 5, 8, 8, -2, -8, -11, 10, 10, -8, -14, 2, 13, 4, -2, -12 }, { -10, 3, 6, 4, 19, -23, -19, 1, 4, -9, -30, 3, -6, 18, 0, 2, 0, -11, 0, 3, 7, -2, 8, 5, 2, -3, 6, -9, 1, -4, 7, -6 }, { 9, 5, -2, 21, 20, -33, -13, 7, -10, 8, 8, -15, -6, -4, 1, 5, 3, 7, -2, -9, -1, 4, -6, 1, 0, 9, -1, -5, 2, 1, -3, 3 }, { -9, -3, 3, 15, -3, -30, -7, -7, -25, 6, 2, -6, 1, 19, 1, -12, 1, -8, -13, 9, 13, 1, 8, 2, 5, 15, -2, 3, -9, 0, -4, 4 }, { -6, -12, -17, 25, 22, -13, -10, 9, 2, 11, -7, -16, 4, 6, 1, 0, 0, 18, -4, -5, 4, -2, -1, -5, 0, -4, 6, 1, 6, -1, 7, 0 }, { -1, 0, -10, 8, 8, -27, 0, -2, 29, 16, -2, -4, 9, -1, 2, 0, 6, 10, 6, 4, 2, -7, 9, -18, 3, 3, 3, -10, 17, 10, 9, -6 }, { -3, -12, -6, 11, 20, -32, 5, 21, 3, -4, -9, 2, -10, 1, 7, -4, 5, 0, 0, -1, -8, -9, -7, 4, -10, 5, 0, 2, -5, 4, 9, 1 }, { -5, -1, -5, 1, 2, -19, -13, 1, 6, 12, 2, -16, -17, 11, 10, 13, 16, -12, -11, 3, -6, 0, 6, 4, -3, 1, 8, 2, 5, -11, 3, -14 }, { -19, 5, 10, 11, 2, -23, -9, 16, -2, 7, 0, -11, -7, 10, 6, -7, 26, -15, -4, 8, 6, -4, 7, -9, -15, 1, 8, -4, 4, 2, -12, 16 }, { -11, 1, 11, -4, 1, -31, -13, -1, 8, 5, 4, -2, 0, 13, 7, -17, 7, -10, -6, 1, 4, -1, 2, -9, -4, 9, 3, 3, -4, -5, 3, 4 }, { -3, 1, 10, -1, 0, -15, -22, 4, 40, -11, -4, -3, -14, 9, 11, -1, 9, -1, -6, 6, 3, -6, 0, 0, -12, 7, -2, 0, 9, 3, 1, 3 }, { -1, -1, -1, 14, 8, -24, -14, -8, 5, 8, 5, -12, -17, 8, 2, 7, 10, -8, 0, 4, -6, -6, -10, 8, 4, -12, 3, -9, -12, 5, 4, -3 }, { -5, 1, -11, 8, 9, -24, 0, 2, 2, 14, -12, -13, 1, 6, 7, 0, 7, -6, 9, 26, 11, -14, 8, 10, 1, 9, 0, 11, -2, 6, 2, -10 }, { -13, 1, 4, 34, 19, -17, -15, 0, 3, -2, -7, -1, 0, -3, -3, -1, 1, -1, -10, 8, 5, 0, -8, 4, -17, 9, -2, 0, 0, 6, 2, -3 }, { -6, -4, 1, 2, 2, -14, -29, 0, 9, 34, -3, -5, -14, 6, -10, -9, -5, -1, 0, 3, 3, 0, 1, -1, -2, -1, -1, -3, -3, -4, 3, -3 }, { -4, 6, 3, 14, 14, -8, -29, 31, 11, 14, -4, -5, -6, 10, 6, -9, -1, -11, -7, 1, 7, 4, 1, -6, 4, 0, 10, -7, -5, -1, 2, 4 }, { -4, -4, -2, 14, 6, -32, -6, -14, 14, -5, -11, 10, -18, -4, 6, -8, 9, 5, -4, 1, -4, 5, -2, -9, 3, 5, 2, -10, -6, -17, 3, 17 }, { -16, 9, 21, 19, 4, -20, -17, 14, 9, 15, -6, -17, -1, 1, 6, -3, 1, 1, 8, -3, -6, 6, 9, 4, 9, -9, -5, 1, -1, 0, -1, 2 }, { -7, -5, 3, 19, 1, -20, -9, 14, 21, -7, -18, -9, 26, -7, -17, -7, 12, 6, 0, -9, -6, 14, 9, -9, -8, 4, 15, -7, -9, -1, 9, 1 }, { -20, 30, -6, 11, 24, -4, 0, -6, -2, 8, -4, 12, -8, -17, 0, 5, -4, 1, -1, 3, -3, 5, 3, 3, 7, -2, -3, -2, 4, 0, 0, -1 }, { -35, 17, 6, 1, -9, -1, -16, 3, -20, -13, 8, 7, -4, -7, -4, -20, 7, 12, -5, 5, -5, -11, 12, -1, 15, -9, -6, 16, -4, -9, -13, 4 }, { -21, 36, -19, 9, 0, -7, -8, 9, -4, -3, 3, 0, 7, -8, -2, -2, -11, 13, -1, 5, -3, 7, 2, 3, -1, -2, -5, 1, -1, -2, -5, -3 }, { -12, 33, -4, 1, -12, -9, 0, -13, -1, 2, -8, 4, -10, 6, -16, -7, -1, -4, -10, 15, -1, 0, -5, -8, 5, 5, -3, 0, 2, -7, 1, -7 }, { -14, 32, 5, -7, -15, 3, -5, 8, 14, 5, 9, 13, 3, 18, -3, 7, 4, -10, -10, 10, -1, 2, 0, -2, -11, 5, -3, -4, 2, 2, 7, 4 }, { -14, 34, 1, 20, -1, -12, 0, -3, -7, -4, 7, 18, 9, -3, 14, -7, -9, -20, -7, -4, -13, 12, 1, 12, 5, -6, 2, -4, 0, -15, 1, 3 }, { -21, 23, 7, -8, 3, -13, -3, 0, -6, -2, -7, 6, -12, 9, -6, -2, -2, -4, -1, 6, 9, 5, -9, 15, 0, 8, -8, 7, 6, -15, 3, -5 }, { -27, 32, -1, -4, -2, 4, -10, 12, -3, 8, 13, 7, 0, -15, 4, -2, 3, 5, 7, -4, 9, -12, -1, -2, -1, -4, 0, -4, 2, -5, 6, -6 }, { -17, 29, 15, 0, -1, -4, -10, 13, 12, -1, -8, -10, -10, 4, 7, -2, 6, -5, -13, 19, 6, 1, -7, 2, -9, -2, 12, -4, -8, -3, 2, 4 }, { -38, 27, 16, -15, -6, 3, -7, -4, 0, -1, 6, -2, -3, -6, 6, -6, -3, 0, 2, 0, -4, 6, 1, -1, 0, 4, -1, 3, 4, 1, -2, 5 }, { -33, 40, -4, 2, 1, 0, 0, -10, -14, 0, -7, 4, -1, 3, -2, 5, 7, 6, -1, 4, 1, 3, 1, -7, 1, -4, 5, 7, 0, 4, 3, -4 }, { -20, 25, 12, -4, 16, -4, 2, 2, -14, -2, -3, 29, -1, 1, 3, 1, 9, -5, 2, -8, -3, 1, -7, -2, -7, 1, 0, 4, 16, -2, -1, -1 }, { -10, 30, 17, 3, -5, -2, 0, -5, -22, 4, 5, 5, -3, -18, -6, 10, -5, -7, 2, 8, 7, -7, -11, -2, 0, -3, 3, 2, 11, -4, 4, -4 }, { -11, 30, 11, 4, -3, -8, 1, -2, 4, 18, 3, 1, -1, 0, -8, -4, -3, 10, 13, 14, 5, -5, 1, 1, -10, 2, 15, 4, 9, -1, -5, -3 }, { -17, 32, 18, -18, -3, -5, 6, 10, 1, -15, -5, 9, 8, -12, -10, -6, 11, 9, -5, -8, -7, 10, 5, -10, -14, -4, -3, 1, 9, -11, 2, 1 }, { -13, 28, -11, -1, 2, -16, -2, 7, -24, 0, 3, 6, 3, -1, -8, -7, -12, 2, 2, -20, 10, 4, 0, -13, -2, -2, 1, 8, -14, 0, 4, 1 }, { -14, 23, 12, 8, 8, -26, 2, -4, -14, 13, -14, 15, 3, -9, -1, -13, -10, -2, -10, 6, -16, 12, 8, 0, 9, -10, -7, -4, -4, 7, -8, 8 }, { -20, 45, 10, -14, 4, 16, 8, -9, 1, -8, 10, 5, -7, -2, 2, -5, -1, 0, -5, 4, -6, -2, 4, 1, 3, 4, -4, 2, -2, -2, 5, 1 }, { -20, 26, -4, 1, 7, 4, -8, 1, -5, -13, 2, 13, -7, -3, 6, -6, 22, 0, 5, 11, -4, -11, 8, -9, 2, -2, -4, -2, 2, -13, -4, -8 }, { -28, 18, 17, 3, -8, -23, -16, -6, 5, -10, 14, 10, 5, -1, -8, 4, -2, 13, -3, -2, 3, 4, 3, -2, -3, -4, 0, 1, 3, 4, 0, 4 }, { -12, 32, -6, -16, 18, 12, -16, 0, 7, 13, -4, 5, -8, -1, -3, 4, 6, -2, -1, -13, 4, -1, 3, 12, -3, -10, 1, 6, 8, -11, -2, 4 }, { -18, 26, 2, 5, 0, -9, -17, 14, 5, 1, 7, -3, -8, -3, 11, 7, -5, -12, -8, 7, 0, -7, 2, -12, -9, 13, -11, 9, 6, -11, -5, 11 }, { -24, 22, -15, -9, 8, 1, -7, -12, -9, 3, 11, 15, 14, -11, 12, -15, -5, 7, -2, 0, -8, 3, 3, -1, 2, 11, -11, 14, -6, 13, 1, -6 }, { -20, 28, 18, -4, -6, -5, 12, 14, 2, 10, -13, -6, -8, -6, -13, -1, -26, 22, -3, -14, 6, 0, 10, -15, -13, -9, 6, -7, 1, -5, -4, -1 }, { -19, 26, -8, -3, -14, -6, -9, -4, -8, 15, -8, 3, -12, -4, -2, -7, -5, 3, 13, -3, -4, -25, 4, -1, 5, -12, -1, -13, 5, 2, 0, 6 }, { -18, 43, 14, -8, 1, -23, -2, -2, 1, 3, -7, 0, 0, 8, -1, -3, -5, 1, 5, 2, 0, -2, -2, -2, 1, -1, -1, -7, 0, 3, -3, 9 }, { -11, 30, 10, -14, 3, 1, 10, -11, 1, -7, -4, 14, 2, 1, -9, 1, -11, -2, -7, 5, -11, 1, 3, 14, 1, -16, -8, 3, -5, 7, -4, 4 }, { -18, 24, 6, 3, 8, 7, -22, -7, -7, 3, -8, 4, 23, 9, 3, -1, 3, 6, 7, -1, -7, 6, 4, 1, -3, 1, -6, -1, 2, -7, 3, 3 }, { -15, 38, -7, -1, -11, 2, -17, -24, 24, 8, 7, -4, -5, 2, 2, -7, 1, 4, 0, -9, 5, 0, -1, 1, -1, -5, -6, 3, 0, 7, 8, -3 }, { -14, 22, 1, -5, 9, -12, -9, -5, -6, 5, 7, 8, -1, -4, -9, -3, -33, -16, -9, -1, 12, -11, 17, -7, -3, -1, -7, 3, 2, -3, 16, -4 }, { -14, 20, 6, 4, -10, -4, -4, -4, 1, -7, 2, 6, 8, -12, 4, 1, -1, 12, 10, 3, -14, -10, -3, 18, -2, 33, -5, -17, 17, -5, 9, 7 }, { -12, 23, 13, 0, -11, -8, -11, 12, -5, -9, -16, 11, 6, 4, 12, -5, 5, -13, 7, -12, -3, 1, 2, 12, 1, -4, -1, 5, 4, 11, -12, -3 }, { 15, 2, 14, 7, 1, 2, 1, 12, 10, 23, 4, 6, -20, -10, 4, 26, -6, 13, 4, 3, 2, -11, 5, -7, -10, 4, 9, 1, 10, -4, 11, 4 }, { 17, 15, 31, 17, 18, 16, 11, 24, 2, 4, 2, 3, -8, -3, 7, -3, -5, -7, -2, -6, -4, -5, -4, -1, -4, -2, -5, -6, 2, -1, 4, -2 }, { 16, 8, 15, 14, 3, 7, 21, 9, 8, 15, 21, 6, 8, 12, 5, -5, 7, -3, 10, 2, -3, 8, 6, 0, 5, 5, 6, -3, 2, 4, 0, -5 }, { 5, -4, 6, 12, 6, 13, 24, 17, -5, 17, -1, -6, -7, -10, -8, -18, 3, -2, 2, 7, -15, -11, 12, -3, -2, -2, -4, -7, 2, 0, 5, 5 }, { 10, -6, 8, 11, 12, 20, 22, -11, -3, 15, -3, 15, -2, -2, 0, 2, 5, -8, 4, -5, -9, -4, -1, 2, -1, -3, 1, 3, 13, -1, 9, 7 }, { -5, 8, 5, 11, 14, -5, 14, -9, 2, 35, 8, 15, 1, -2, 2, -2, 4, -9, -3, -14, -12, -2, -2, -4, -2, -8, -3, 1, -6, 3, 10, 0 }, { 16, 0, -6, 15, -3, 4, 4, 3, 3, 20, 5, -4, 10, 9, -9, -3, -10, -2, -7, 11, -11, -10, 17, -1, 3, -15, 2, 9, -15, -10, 16, 10 }, { 14, 4, -7, 19, 3, 0, 19, 8, 16, 34, -9, 6, -13, -1, 6, 5, -1, -2, 4, 3, 2, 1, 1, -1, 0, -7, 2, -1, 1, 0, 6, -1 }, { 1, 6, 9, 13, 9, 10, 15, 16, 10, 18, 13, 17, 3, -1, -7, 2, -15, -11, -10, -4, -13, -6, -17, -13, -6, -14, 1, -10, 6, 4, -1, -1 }, { 13, 1, 7, 10, 14, 13, -7, 5, 5, 28, 14, 14, -2, 2, 3, -3, -13, -4, 10, -9, 19, -4, -3, 4, -5, -5, 0, 5, -5, 0, 3, -4 }, { 1, 0, 6, 22, 9, 18, 18, -3, 5, 10, 12, -2, 1, -3, -8, -12, 9, -10, -7, 1, -1, 19, 0, 2, -8, -11, -10, 9, 6, 11, 0, 3 }, { 10, 11, 19, 44, 0, 14, 1, -7, 6, 22, 2, -1, 9, 2, 0, -4, 4, 0, -6, -6, 3, 0, 0, -2, 2, -5, 1, -2, 0, 1, 1, 1 }, { 5, 7, 0, 32, 30, 26, 5, 4, -7, -3, 15, -6, 3, -10, 7, 6, -8, -7, 2, -13, -5, -1, -3, 7, 3, -2, -8, 0, 6, 4, 5, 0 }, { 9, 8, -2, 4, 2, 11, 4, 29, -5, 14, 8, -5, -14, 8, 0, 9, 8, -10, 5, -15, -6, -9, 9, -1, 18, -16, 9, -21, -3, -13, -2, 8 }, { 25, 7, -9, 23, 20, 18, 6, 16, -9, 8, 8, -5, 11, 13, -8, 7, 4, 10, -2, -1, -7, -9, -7, -9, -4, 1, 1, -5, -10, 8, 4, -5 }, { 9, 2, 16, 14, -5, 14, 1, 0, -21, 17, -1, 9, 12, -3, -3, 4, -4, 14, 10, 3, 0, -10, 7, 4, 4, -11, 2, 4, -1, -3, 9, -1 }, { 17, 8, 11, 26, 15, -3, 14, -1, 12, 9, 10, -8, 8, -18, -11, -3, -14, -7, 7, -3, -3, -4, 1, -7, -3, 2, -3, 16, 10, 0, 9, 6 }, { 9, 8, 3, 8, 18, 14, 11, 1, 10, 6, 1, -4, -16, -2, 14, -2, 1, 8, 12, 14, 3, -3, 8, 8, 12, -15, 3, -3, 3, -2, 14, 10 }, { 22, -3, -11, 13, -7, 11, 4, 11, 3, 14, 0, -6, -2, -9, 4, 2, -2, 0, -5, -27, -10, 3, -1, 5, 8, -24, -3, -11, -3, 2, 11, -1 }, { 19, 2, 8, 36, 5, -6, 3, 15, -3, -4, -5, 14, -10, 1, -12, -10, -3, -4, 3, -2, 1, -8, 4, 3, 5, -3, 0, 4, 8, -2, 8, 4 }, { 8, 14, 15, 9, -4, 10, 5, 11, 9, 10, 8, 9, -15, 15, 6, -8, -10, -13, 5, -8, -20, -13, -6, -11, -1, -3, -6, -4, -1, 0, 13, 15 }, { -2, -1, 9, 12, 2, 2, 13, 3, -23, 33, 15, 2, -4, -1, 3, 8, 8, 6, 6, -7, 8, 6, 9, -1, 3, -8, 0, -4, 1, -8, 11, -1 }, { 6, 5, -6, 16, 2, -3, 31, 21, -9, 12, 0, -1, -4, 1, -12, 3, -13, -18, 2, -11, -9, 2, -8, -6, 11, -3, -1, 0, -1, 0, 13, 5 }, { 5, -1, 2, 0, 25, 5, 10, 16, -5, 21, 14, 12, 13, 2, -5, 5, 5, -3, -2, -14, 0, -12, 7, 11, -1, -7, 19, -1, -1, -1, 8, -1 }, { 10, 7, 3, 11, 0, 8, 22, 3, 3, 19, -4, 12, 15, 9, 5, 15, 2, 1, 2, -10, -10, 0, 2, -1, 0, 1, -12, -1, 21, 16, 9, -7 }, { 11, -4, -5, 24, -7, 11, 20, 11, -15, 18, 5, -13, -15, 0, -5, 9, 1, 0, -1, -9, 4, -8, 6, -8, 1, -2, -7, 20, 9, 3, 9, 3 }, { 20, 0, -12, -6, 9, 31, 9, 12, 8, 27, 15, 7, -16, 5, -3, -7, -1, -9, -2, -7, -3, 4, -8, -3, 3, -6, -2, -2, -3, -6, -1, 2 }, { 6, -6, 48, 8, -3, 19, 12, 11, -7, 2, 3, 0, -1, 1, 8, -4, 4, -6, 0, -4, -4, -3, 3, 6, 3, -13, -8, 5, -3, -7, 8, 5 }, { 7, -2, 6, 11, 12, 2, 14, 4, -5, 12, 2, 9, 4, 2, 0, -1, 2, 0, -15, -9, -16, -2, 8, -17, -5, -22, -19, -5, -1, -10, 1, -2 }, { 11, -9, 3, 12, 6, 6, 1, 17, -6, 19, 14, 7, -7, -1, -1, -9, 9, -11, -17, 0, -6, 16, 0, 1, 9, -24, 3, 3, -9, -3, 3, -2 }, { 9, 0, 1, 8, 1, 7, 2, -5, -3, 8, -1, 7, 2, 6, -3, -6, 5, -2, 6, -2, -4, -3, 0, -3, 13, -50, 1, -2, 2, 4, 4, 3 }, { 7, 0, 26, 21, -4, 2, 17, 8, 7, 11, -7, 1, -1, -15, -1, -15, -11, -4, -17, -4, 1, -7, 3, 6, 3, -9, 2, 3, 6, 10, 6, 12 }, { 1, -2, 2, -1, -10, -4, 6, -3, -5, -2, -8, 2, 2, 2, 8, 0, 1, 1, 6, 0, 11, 13, 3, 4, 0, -12, 11, -5, 19, 20, 2, 5 }, { 5, 3, -13, -2, 1, -12, 11, -7, -12, 7, 10, 0, 7, 0, -2, 4, -6, -9, -11, -12, -23, 12, 10, -3, 0, 6, 19, -1, 24, 18, 9, 12 }, { 6, -3, 2, 5, 2, 2, -2, -5, -8, -11, -4, 3, -8, -4, 5, -3, -16, -4, 3, -12, -4, 3, 32, 7, 2, 8, 32, -18, -1, 12, 1, 7 }, { 0, -8, -1, 0, -8, 7, -8, -1, -1, 4, -12, -1, 3, 0, 1, -18, 8, 8, -14, -10, -11, 19, 9, 5, -7, 6, 8, -4, 26, 12, -1, 6 }, { 3, 5, -14, 7, 14, 8, 20, -13, -16, -10, -2, 17, -7, 4, -8, -9, 14, -5, 3, -4, -12, 7, 14, -10, -19, -20, 35, 8, 13, 14, -2, 9 }, { -2, -4, -1, 1, -3, 0, -1, 1, 2, 2, 6, 0, 0, 4, 5, -2, 3, 3, 3, -2, -7, -3, -3, -1, 6, -2, 29, 22, 13, 34, 0, 14 }, { -3, -9, 3, 1, 5, -4, 2, 0, 7, -9, 0, 2, -5, -3, 0, 6, -1, -1, -1, 2, 2, 4, 8, 7, 20, -6, 7, 16, 33, 20, 6, -1 }, { -11, 1, -3, -3, -11, 3, -9, -25, -1, -16, 4, -8, 15, 1, -2, 7, 8, 23, 2, 18, -13, 16, 3, -7, 6, 3, 16, -8, 12, 16, 3, 4 }, { 0, 5, 5, -5, 1, -1, 2, -3, -2, 1, -13, 2, 2, 10, 6, 7, 18, 18, 7, 9, 8, 9, 21, 14, 7, 12, 15, 14, 15, 12, 11, 5 }, { 1, -5, 11, -2, 17, 8, 3, 0, -1, 6, 11, -7, 6, 6, 7, 5, -15, 14, 1, 11, 4, 10, 12, 1, 2, 4, 30, 1, 11, 1, 6, 13 }, { 2, 4, 3, -7, 5, 8, -11, 7, -5, 9, -10, 6, 8, -10, -3, 10, 1, -29, -4, -26, 5, -8, 13, 4, 3, 6, 35, 1, 3, 6, 3, 0 }, { -2, 1, 0, 0, -1, -3, -7, -3, -9, -3, -1, -6, 3, 4, 4, 0, 5, -1, -2, -2, -1, -4, -10, 8, 0, -6, 10, -4, 46, 12, 2, 28 }, { 4, -1, 4, 1, 0, 4, -2, -2, -2, -1, 2, -4, 1, 5, 0, -3, 1, 1, -2, 0, 1, -2, -1, -1, 3, -6, 35, -11, 13, 53, -3, -1 }, { -5, -2, 0, -13, -16, 5, -12, -11, 1, -30, 3, -18, -24, -8, -5, -19, 1, -3, -8, 7, -7, -8, 15, -19, 4, 10, 30, 24, 6, 1, -9, 10 }, { -4, 8, -7, -4, -6, 12, -1, -9, -4, 2, -9, 3, 2, -2, 4, 2, 22, 9, 4, -5, 0, 5, -2, -9, -3, 1, 18, -12, 18, 16, 4, 16 }, { -5, -8, -3, -5, -3, 6, -7, -3, -2, -5, -3, 1, 2, 2, 4, -6, 10, 3, 12, -3, 20, 0, 27, -4, 16, 5, 18, -3, 23, 4, 12, 11 }, { 0, 1, 0, 1, -2, 1, 2, 1, -1, 0, -2, 2, -2, -4, 1, -2, -2, -1, -5, -2, 0, 0, -2, 2, 9, 7, 63, 5, 12, -1, 1, 0 }, { 4, -3, -7, -5, -11, -5, -12, -10, -10, -12, -15, -12, -14, -14, 1, 1, 10, -10, 16, 6, 2, 9, 11, 9, 9, 8, 12, -1, 13, 12, 6, 3 }, { 7, -3, -2, 4, 6, -8, 2, -3, -12, -5, -9, -8, -10, 15, -2, -4, 8, 9, 7, -13, -18, 34, -5, 7, 12, 22, 16, -11, 13, 25, -15, -11 }, { -3, -2, 0, -4, 1, 0, -3, -13, -7, 13, 12, -7, -10, 13, 19, 6, 16, 15, -12, -15, -3, 34, 1, 5, 1, -9, 11, 21, 8, 17, -5, -6 }, { 3, -5, 0, -4, 0, 4, -11, 4, -7, -3, -1, -8, 3, -2, 2, 1, 11, 5, 6, 14, -3, 2, -4, -7, 0, 31, 15, -2, 24, 11, 5, 4 }, { -1, -4, -9, 5, -8, -18, -4, -9, -20, -18, 7, -14, -16, 3, 8, -3, 29, 11, -13, -13, 7, 1, 17, 6, 6, 21, 11, 1, 14, -8, 2, 5 }, { -3, 8, -10, -6, 12, 2, 1, 3, 3, 3, 3, -6, -8, -14, 15, -5, 16, 4, 16, 0, 7, -1, 0, 16, 2, 1, 22, 4, 19, 13, -11, 1 }, { 2, -3, 10, 20, -4, -1, -8, 5, -8, -9, -6, -2, -4, -7, 8, -10, 0, 8, -6, 1, -8, 14, 13, 5, 17, -6, 26, -1, 7, -1, 0, 12 }, { -4, -7, -31, -2, -7, -1, 5, -5, -5, -12, 4, -7, -6, 3, 15, -2, 5, -2, 7, -1, 10, 7, 8, -1, 14, 20, 14, 9, 16, 16, 8, 24 }, { -7, 0, -3, -6, 1, 3, -13, -6, -4, -4, -5, -9, -1, -10, -4, -8, 2, 0, -1, 1, 24, 24, 21, 31, 5, 2, 11, 12, 7, 4, 3, 6 }, { -3, -5, 6, -4, -3, -1, 2, -1, -2, 1, 0, -8, -1, 2, 0, -4, 6, 22, -1, -5, 8, 12, -1, -2, 28, 27, 20, -27, 14, 1, 2, -3 }, { 1, -5, -2, -2, 6, -2, 9, 1, -2, -5, 3, 4, 11, 5, 2, 8, -3, -1, 1, -2, -3, -5, 5, 8, 49, 12, 8, -3, 9, 20, 12, 17 }, { -6, 0, 1, 7, 0, 9, -2, -4, 8, 0, -2, -10, 0, 7, 21, -1, 0, 1, 17, -7, -5, 2, 4, 16, -2, 17, 14, -20, 15, 14, 4, 15 }, { 0, 3, -4, 9, -4, 0, 6, 4, -6, -6, -5, -7, 2, -9, -10, -2, -5, 0, -3, -21, 9, 14, -11, 13, 29, 2, 25, 4, 22, -1, 2, -3 }, { 2, 12, -11, 2, 16, 9, -4, 7, 1, -10, -15, 11, -4, 3, -2, 4, 4, -5, -10, 1, 4, 19, -15, 6, -4, -2, 30, -7, 11, 21, -12, 5 }, { -2, -3, -2, 4, -1, -5, -3, -7, -5, 1, 0, -6, 1, -6, 7, 0, 8, -7, -3, -2, 2, 14, 2, -3, -26, -1, 26, 22, 32, 1, -2, 6 }, { 1, -38, -1, -20, -2, -3, -6, -4, 2, 2, 7, 0, 3, 5, 3, 10, 6, 1, -3, -5, 7, 5, -5, -4, 8, 3, 1, -14, -1, -9, -5, -4 }, { -5, -26, -7, -19, -10, -5, -11, 5, -11, -25, -8, -14, -9, -16, -8, -6, -17, -14, -1, -1, 6, 2, 2, 2, 3, 0, 2, 8, -8, 3, 0, -3 }, { 17, -49, -3, -23, -1, 11, 7, 3, 4, -4, 0, 0, -1, 4, 2, 4, -2, -4, 2, -2, -1, -2, 2, 0, 0, -1, 0, 0, 1, 2, 0, 0 }, { 4, -34, -6, -9, 1, 21, -7, 3, -2, -1, -3, 18, 2, -16, 7, -3, 8, 7, -5, 7, 2, 4, 8, -6, -7, -2, -5, -1, 4, 1, 2, -4 }, { 5, -29, 13, -2, -14, 3, 1, 18, -15, 4, -8, 8, -10, 8, 2, 1, -8, 15, 3, -10, -4, -4, -2, 0, -3, -4, 2, -3, -4, -3, 12, -6 }, { 13, -20, 3, -18, -17, 4, -14, 13, 28, 11, -8, -6, 16, 6, 0, 10, 3, 4, -9, 13, 5, -7, 12, -5, 0, -7, 5, 1, 3, 3, 2, 1 }, { 3, -27, -5, -11, -21, -11, -12, 0, -5, 7, -22, 1, 3, 5, 0, -5, 8, 7, 1, -5, -7, 2, -5, 4, 1, 3, -8, -2, 0, 4, -2, 6 }, { 31, -45, 0, -1, -12, 1, 2, -6, 4, 3, -1, 3, 3, 0, 5, 3, -5, 12, 4, 6, 2, 1, -2, 1, 3, 2, 5, 2, 2, 2, 3, -1 }, { 9, -45, 6, 5, -1, -17, -2, 18, -3, 2, 0, 1, 0, -1, 10, 8, -7, -2, -5, -8, 6, -1, 0, 4, 6, -3, 12, -1, -2, 0, 5, -7 }, { 3, -26, -2, -12, -12, 2, -10, 16, -3, 12, 4, 5, 11, 8, -16, -17, -2, -3, -3, 2, 5, -9, 13, 1, 10, 11, 3, 5, -2, 2, 2, -7 }, { 8, -26, 32, -7, -5, 22, 2, 14, -10, -8, -7, 3, 3, 7, 0, -5, 0, -1, -3, 0, 8, 4, -5, -7, 6, -1, 4, 8, 1, 1, 7, -6 }, { 4, -31, 2, -14, 2, 0, 1, 8, -6, -1, 17, -3, 13, -6, 5, -10, -2, -10, -2, -10, -3, 7, 1, 5, -8, 8, -14, -3, -15, 7, -10, -6 }, { 16, -27, 13, -4, -23, 7, -9, 6, -7, 5, 4, 2, -1, -3, 23, -18, 7, 0, -3, 4, -3, 9, -6, -2, -1, 8, -6, 2, 6, -3, 2, -2 }, { -1, -35, -2, -8, 11, -1, -7, -3, -2, 11, 7, 6, -6, -10, 9, 6, -3, -5, -6, -3, 9, 16, -16, -9, -20, 12, 3, 5, -3, 1, -9, 4 }, { 2, -24, 1, -12, -16, 5, -4, 3, -4, -1, -11, -11, -8, -14, 14, 10, -8, 20, 8, -3, -11, 1, 1, -4, -4, -7, -3, 15, 2, -6, -2, 7 }, { 9, -21, 2, -19, -7, -5, -8, 25, 3, 17, 5, -3, 9, -12, 8, 2, -4, 3, 3, 1, 11, -9, -4, -3, 4, 3, -22, 6, 4, 6, 11, -5 }, { 16, -23, 13, -17, -21, -12, 5, 9, -20, 7, 6, -6, 0, 2, -9, 6, -6, -13, -7, -1, 5, -3, 5, -7, -10, 1, 0, 8, -9, 11, 0, -8 }, { 10, -26, -9, -7, -19, -4, 6, 16, -7, 5, -4, 4, 8, 0, 4, -1, 6, -7, 1, -8, -11, 10, -14, 0, -16, 6, -3, 5, -1, 14, 12, 1 }, { 8, -27, 12, -14, -1, -1, -19, 10, -11, 21, -14, 9, -8, -3, 8, -1, 12, -13, 3, -4, -2, 0, -9, 0, -7, 2, -3, 12, 1, -3, 3, 1 }, { 18, -20, -14, -14, -16, -3, -24, 6, -17, 2, -3, -11, 2, -3, 12, 10, 10, 1, 10, 7, 8, 5, 5, 4, -1, 7, 2, 2, 0, 4, 7, 0 }, { 0, -30, 9, -16, -18, 15, 12, -3, 4, -4, -5, -11, -4, -12, -10, 0, 2, -2, -4, -1, 2, 0, -1, -6, 2, -3, 4, -5, 7, 3, 5, 7 }, { 25, -24, -1, -6, -9, 6, -13, -2, 3, 15, -3, 11, 4, -8, -11, 2, 0, -9, -2, 7, 4, 8, 5, -8, 5, 6, -1, -11, -15, -5, 0, 11 }, { 0, -34, -7, -11, -7, 9, -3, 19, 4, -8, 3, -11, 11, -3, -9, 12, 9, 9, 2, 1, -7, 1, -3, 0, -6, -2, -1, 3, 0, -7, -2, -5 }, { 6, -34, -4, -5, -3, -9, 2, 9, -1, 9, -5, -3, -26, -12, 8, -6, -7, 11, -8, 4, 4, 1, -1, 0, 8, 9, -4, 7, -1, 1, -3, -1 }, { 3, -30, 5, 6, -10, 3, -7, 6, 3, 3, -26, -19, -3, 1, 7, 5, -4, -5, 6, 10, 13, -10, 4, -7, -4, 5, -3, 9, -6, 3, 9, 5 }, { 4, -24, 9, -19, 2, -4, -5, 8, -3, 2, 0, -15, -1, 9, -4, 22, 6, 9, 3, 7, 11, -9, 0, -3, 4, 5, -5, 10, -8, 5, -7, -3 }, { 8, -27, 7, -3, -1, 2, -9, 13, 7, 12, -4, -6, -6, 5, 0, 7, 5, 1, 15, -3, -4, 0, -5, -2, 7, -5, -7, 1, -2, 13, -8, 13 }, { 17, -22, -15, -11, -8, 16, -14, 18, 2, -1, 14, -7, 14, -6, -6, -7, -8, 17, 6, 4, 4, -7, -5, -9, -14, -6, -1, 9, -3, 1, 6, -5 }, { 25, -30, 2, -12, -13, 18, -18, 16, 8, -3, 10, -8, -3, -1, -6, 3, -5, -7, 4, 6, 7, 1, 1, -11, -5, 6, 2, -4, 9, -1, -5, -2 }, { 7, -23, 7, -15, -1, -3, -1, 0, -10, 12, 2, 5, -4, 0, 4, 6, -1, 5, -9, -1, -1, -7, 1, 17, 9, -17, -16, 8, 4, -14, 11, 14 }, { 0, -31, 7, -13, 3, -11, -7, 6, 1, -11, 8, -7, 15, -3, 16, -11, -1, -15, 16, -3, 5, 0, -2, -2, -6, 11, 5, 6, 5, -5, 6, 3 }, { 13, -24, -2, -20, -10, 7, -3, -1, 15, 2, 6, -5, -7, -10, -20, 1, -4, 14, 8, -2, 3, -13, -3, 1, -4, 1, -3, 2, 8, -7, 16, -4 }, { 1, -2, -2, -3, -4, -7, 0, 3, 6, 7, 3, 2, 1, -2, -1, 0, -6, 4, 2, -4, -3, -4, 5, 9, 5, 0, -3, -3, -4, -7, -31, -50 }, { -1, -3, 7, 2, -1, 2, 4, 6, 0, 10, -2, 0, -20, -6, -3, 9, -20, -22, -1, -1, 15, 9, -12, 10, -13, -20, 12, 3, 5, 6, -7, -26 }, { 0, 4, -2, -14, -12, 6, -13, 11, -10, 3, 22, 6, 16, -2, -5, 1, -3, -11, 0, -7, 5, -5, 0, 1, -1, -6, 8, 8, 10, 9, -5, -27 }, { -5, 10, -2, 7, 9, -9, 5, -9, 5, 4, -15, 14, 1, 3, -10, 5, 0, -2, 7, 3, -13, 6, 9, -6, 5, -14, -17, -1, 11, 14, -2, -26 }, { 0, 6, -3, 0, -8, 6, 0, 1, 4, -8, 2, -5, 4, 7, 15, 11, 9, 19, -2, 14, -8, 7, -1, 3, -3, -3, -10, -2, 12, -2, -12, -29 }, { -12, -5, 0, -3, -2, 6, 3, -3, 2, -2, 1, 11, 2, -7, 5, 1, 2, -2, -14, 0, -1, -5, 3, 8, -28, -26, 6, -6, 3, 8, -10, -27 }, { -1, -3, 6, 2, 4, 15, 1, 0, 2, -2, -2, 13, 3, 6, 0, 6, -1, -4, -1, -5, 8, -1, 5, -5, -15, 11, -8, -5, 14, -6, -14, -29 }, { -5, -6, 0, 1, 0, 6, -3, 2, -5, -1, 5, -3, 2, -10, 3, 4, 3, 0, 13, -3, -1, 4, -4, -6, 2, 9, 8, 2, -3, 28, -11, -31 }, { 1, -4, -10, -9, -4, -3, -15, -6, 1, 5, -3, -6, 5, -6, -22, 27, -13, 5, 3, -7, -4, 20, -7, -12, -1, -24, -4, -13, -8, -11, -15, -21 }, { -6, -4, 19, -6, 2, 11, -6, 1, -3, -10, 9, -9, 12, -10, 2, 1, -9, 1, 15, 7, -5, 5, -29, -35, 4, -30, 9, 9, 19, 17, 2, -17 }, { -3, 3, -3, 1, 2, 5, -1, 5, -2, -3, 1, -3, -8, 3, -4, -2, -4, -1, 12, 0, 2, -8, -6, -4, 16, -1, -14, -2, 25, -6, -15, -36 }, { 0, -1, 3, -4, -4, -1, 7, -4, 8, 0, 10, 9, -4, 1, 10, -1, -3, -13, -5, -4, -1, -4, 8, 11, 14, -7, -5, 16, 12, 13, -1, -28 }, { 1, -2, 2, -3, -8, 10, 4, 9, 12, 3, 5, 0, 8, -3, -6, 2, 16, -11, 11, 0, 1, 6, 1, 18, -10, -16, -1, -4, 5, -14, -15, -20 }, { 1, -12, 5, 4, -7, 8, -1, -17, -2, -9, -14, -11, 6, -9, 5, -4, 3, -2, 7, 18, -5, 5, 6, -1, -11, -2, -10, -3, 8, -3, -2, -32 }, { -12, 5, 20, -5, -6, -11, -6, -6, -13, 4, -6, 19, -8, 2, 3, -9, -4, -4, -1, 9, -1, 21, -1, 7, 15, -10, -1, -3, 9, -3, 2, -24 }, { 0, -3, 2, -6, 4, -1, -9, -2, -1, -3, 6, -1, -5, -6, -5, -8, 0, -2, -6, 9, -4, 3, 2, -13, 1, -7, 23, -13, 4, -3, -15, -33 }, { -7, 2, -15, 11, -10, 14, 0, -11, 3, -1, 12, -4, -4, 9, 11, -13, -13, -3, -14, 1, 3, 6, -5, 8, 0, 5, 5, -10, 4, 5, -6, -30 }, { -6, 4, 0, -5, 4, 1, -1, -1, 3, 6, 5, -2, -5, 0, -2, 5, -4, -2, -4, -2, 4, 7, -7, -1, 1, -4, -3, -19, 37, 12, 10, -40 }, { -7, 2, -7, -12, 17, 11, -7, 2, 2, 3, 1, -1, 3, 4, -2, -5, 9, -9, 6, 4, 9, 12, 11, -5, 2, -1, 0, 9, 5, -7, -2, -24 }, { -7, 6, 1, 3, 1, 0, 6, 0, 4, -12, -2, -2, 1, -9, 10, -2, 11, -1, 21, -12, 15, -5, 10, -5, 5, -5, 14, -6, 5, -7, -3, -29 }, { -2, 0, -5, -2, -3, 1, -3, 0, 4, 2, 3, 0, 2, -2, 7, -2, 3, -5, 2, -1, 6, -4, 0, -3, 8, -11, 19, -8, 22, -34, 13, -35 }, { -1, -3, -1, 9, 11, -3, -3, -1, 7, 18, 11, -5, 2, -12, -11, 18, 9, -5, 1, -6, -9, 12, 1, -3, -3, -9, -14, 9, 9, 8, -6, -26 }, { 0, 5, -5, -1, -1, -2, 4, 6, 8, 2, -1, -2, 5, 1, -5, -4, 1, 1, 18, 1, 7, -10, 3, -2, 12, -1, -15, 9, 12, -14, 13, -38 }, { 3, 0, -8, -1, 0, 8, -9, -3, -8, 16, 3, 16, -5, -9, 0, -1, -7, -1, -4, 13, 7, 0, 1, 2, -1, -16, 0, -2, 1, 8, -8, -28 }, { 7, 9, -5, -3, -2, 2, 0, 3, 11, -6, -4, -2, -2, -5, 28, -18, -6, 2, 15, -10, -15, -10, -2, 0, -2, -2, 4, -3, 7, 11, 5, -30 }, { 9, 0, -7, -1, -4, -7, 2, 2, 9, -2, 2, 3, -8, -6, -6, 3, -10, 4, 10, 5, 21, -4, 14, -18, 1, 3, -10, -2, 6, 14, -8, -26 }, { -14, -1, 2, 3, -3, 7, 1, -22, -1, -1, 0, 1, 12, -14, 3, -5, 0, 10, -3, 1, -5, 12, -3, 10, -8, -22, -11, -13, -7, -10, -13, -25 }, { -2, -5, -4, -4, -9, -18, 9, -3, -5, 17, 13, 5, 6, 11, 3, 8, 20, 4, 2, 9, 8, 5, 6, 1, 7, -7, -6, -2, -7, 0, -17, -23 }, { -5, -5, 2, 0, 6, 2, -2, 2, -3, 4, 4, 0, -5, -2, -4, 6, 8, 10, -1, 1, -5, 5, -14, -2, -11, 8, 6, 25, 7, -1, 0, -43 }, { -4, 0, 4, -2, 7, 0, 3, 17, 5, 2, -5, 1, 21, 3, -2, -10, -16, -9, 7, -12, 9, -8, 2, 5, -5, -10, -2, -11, -5, -1, -9, -30 }, { -2, 3, 1, -4, -1, 0, 8, 1, 12, 4, -1, -1, 3, -17, 13, 9, 0, 7, -6, -5, 9, 1, 5, 4, -10, -18, 0, 14, 11, -4, -16, -28 }, { -1, 0, 2, -1, 4, 1, -1, 1, -1, -2, -1, -2, 3, 0, 0, -1, -1, 1, 2, -2, 3, 3, -2, 4, -2, -1, -6, 1, -1, -1, 6, -70 }, { 7, 3, -11, -1, 12, -4, -14, 4, 4, -4, 4, -2, 2, -12, -4, 15, -17, -4, -3, 6, 8, -5, 22, -22, 5, -11, 15, -4, 4, -1, -21, -1 }, { 10, -2, -13, 11, 4, 14, 4, 9, 8, 8, 19, 15, 14, 15, 5, 10, 8, 15, -5, 4, 14, -8, 1, 1, 2, 1, -1, -3, 21, 8, -29, 13 }, { -6, 0, -6, 6, -1, 2, 8, -4, -5, 4, -4, -5, 0, -2, -4, 0, 9, -2, 1, -2, 26, -19, 21, -10, 4, 1, -8, 5, 22, -10, -13, 15 }, { 11, -5, 1, 0, 6, 3, 7, -2, -2, -3, -5, -1, -2, -6, 1, 1, -8, -5, -13, 13, -2, -3, -1, -9, -28, 4, 2, -11, 18, -20, -24, 9 }, { 7, 4, -3, 6, 6, -6, -7, -5, -7, -4, -4, 0, -7, -5, -6, -5, 2, -13, -12, 2, 0, 5, 18, 15, -13, -7, 13, -20, 16, -10, -19, 6 }, { 5, -8, -1, 5, 10, 2, -1, -10, -11, 23, 8, -5, -8, 4, -5, -4, -5, -5, -11, -8, 5, 1, 7, -9, -9, -6, 12, 14, 17, -12, -22, 3 }, { -5, -8, -3, 3, 12, -1, 0, -4, -5, 1, 1, 6, 1, 5, -5, 7, -2, 7, 1, 6, 6, 2, 0, -5, 17, -4, -5, -24, 13, -20, -27, 14 }, { -1, 2, -3, 1, -3, 1, -3, 0, -2, 3, -2, 1, 2, -1, -2, -1, -2, -5, 5, -2, 0, -7, 1, -6, 8, 8, 11, -5, 24, -43, -13, 2 }, { -2, 4, 7, -3, -4, 4, 13, -4, 0, 0, -2, 9, 0, -3, -6, 1, -7, 1, -1, 10, 0, 5, -1, -24, 25, -15, 7, 2, 22, -10, -21, 0 }, { -5, 2, 6, -2, 13, 3, 5, -12, -11, 16, 6, 10, -5, 0, -3, 6, 5, -5, -5, 10, 12, 10, 11, -7, 8, -14, 2, -15, 13, -14, -8, -3 }, { 5, 6, -7, -5, 5, 2, 9, 5, 0, -1, -4, 2, 8, 0, 3, 5, -12, 3, -3, -6, 2, -1, -5, 14, 11, -20, -21, -25, 24, -1, -10, 6 }, { -5, 5, -2, 9, 4, -4, -1, -6, 11, -6, 5, 0, 2, -3, 6, -1, -17, -18, -4, -13, 9, -1, 9, -7, -4, -8, 2, -3, 12, -31, -18, 5 }, { -7, -11, 6, -8, 4, -3, -12, 0, -1, -6, -3, 0, 5, 9, 7, 2, 1, -8, -6, 8, 2, -5, 7, -1, 16, -10, 16, -12, 18, -1, -25, -12 }, { 3, -12, 1, 2, -2, -18, -8, -15, -10, -9, 2, -7, 11, -11, 2, -1, -1, -1, -9, -6, 3, -14, -2, -1, 2, -13, -7, -9, 19, -5, -17, 2 }, { 7, 1, -8, 7, 17, -13, -10, 5, 7, 1, -6, 4, 9, -4, 0, 3, 8, 1, -14, -9, 4, 7, -9, 0, 6, -5, -12, -2, 25, -2, -19, 1 }, { 7, -3, 6, -3, 1, 6, -7, 0, 10, 0, 4, -5, -17, -4, 4, -1, 0, -3, -7, 19, 24, -1, 21, 8, 10, 9, 8, -1, 23, -2, -18, -2 }, { 3, -3, 0, 5, 8, -2, -9, 2, 9, 6, 19, 8, 2, 6, -9, -2, -4, -3, -8, 7, -7, -8, 5, 4, 26, -6, 7, 18, 24, 0, -13, 4 }, { 0, -13, -11, -1, 3, -9, 5, 4, -7, 3, 0, 2, -1, 4, -5, 2, 9, -2, -11, 15, 1, -21, 1, -1, 0, 4, -14, -4, 24, -16, -13, 1 }, { 1, -9, -8, 0, 0, -4, 11, -1, 14, 16, 0, 17, -2, -9, -12, 0, -1, -14, -9, -14, 0, -2, 19, 4, 6, 4, 4, -11, 8, -17, -19, -5 }, { -3, 1, 2, 12, -4, -18, -1, -4, -7, 14, -3, 2, 0, -7, -8, 12, -5, -9, 14, 12, -9, -2, 4, -6, 4, 18, -1, -25, 22, 2, -23, -5 }, { -2, 0, 0, 0, 1, 3, 5, -1, 5, -2, -2, 2, -3, 0, 1, 2, 0, -1, 2, -1, -9, -6, -7, -4, -2, 4, -7, -5, 64, -3, -25, 4 }, { 12, -2, -3, 0, 8, -9, 13, -7, 6, -3, -12, 12, 15, -9, -4, 2, 9, -4, -12, 3, 14, 1, 7, -15, 15, 0, -6, -12, 0, -3, -20, 6 }, { 2, -1, -4, 5, 9, 6, -7, 2, -2, -7, -2, 0, -1, -18, -4, -6, -15, -5, 11, 5, -10, -1, 2, 7, 12, -19, -7, 8, 21, -4, -15, 4 }, { 4, 2, 5, 5, -5, 1, 3, 2, -8, 13, 0, -5, -2, -14, -11, 6, 2, 17, 8, -13, 26, -2, 5, -15, -4, -14, 12, -9, 13, -21, -23, -4 }, { 2, -3, -2, -3, 3, -2, 6, 9, -9, 13, 4, 2, 12, -3, -3, 1, -17, -22, -3, 4, 3, -2, 1, -9, 1, -6, 11, -13, 14, 0, -15, 6 }, { -16, -4, 17, -2, -20, -11, 11, 10, 5, -8, 16, 2, -17, -14, 11, 11, -6, -11, -7, 12, 12, -10, -6, 5, 8, -4, -2, -5, 28, 3, -13, 4 }, { 0, -3, 3, -7, 6, 8, -12, 20, -19, 18, -11, 10, -5, 0, -9, 11, 3, 0, -2, 9, -7, -5, 18, 3, -2, -16, 1, 6, 12, -7, -16, 1 }, { 4, 1, 5, -5, 15, 2, -8, 3, 5, -11, 15, -3, 8, -8, -1, 7, 4, 7, -2, 6, -9, 5, 12, 2, 33, -2, -6, -18, 4, 0, -18, 11 }, { 3, -1, 1, -1, 0, 1, 4, -1, -5, 0, 1, 0, 4, 2, -1, 4, -3, 2, 0, -2, 4, 6, -1, 6, 42, 19, -4, -37, 19, 1, -15, -4 }, { 2, 0, -5, 0, 10, 0, 0, -5, 3, 0, 0, -3, -3, 0, 2, -4, -10, 2, -6, 4, 4, 1, 27, -7, 17, -34, 5, -9, 15, -16, -7, -5 }, { -2, 7, 7, -2, 9, -2, -15, 11, 11, 7, 5, 1, 15, 1, -9, 31, 2, -15, 2, 4, 3, 4, -1, -8, 2, -7, 6, -17, 11, -14, -11, 2 }, { 1, 1, -11, 9, 9, -6, -14, -11, -10, 8, -3, 11, 16, -9, -8, -13, -8, 9, 0, 6, 6, -2, 13, -8, -2, 3, 13, -3, 10, -6, -17, 4 }, { 14, 5, 4, -6, -12, 10, -7, 8, 21, -8, -30, 15, -2, 1, 11, -9, -5, 1, 0, -1, -1, -6, -2, 3, -5, 7, 9, 5, -5, 2, 0, 1 }, { -1, 2, 20, -17, -15, 3, 3, 7, 11, -17, -13, -6, -3, 18, 17, -15, -4, -4, -5, 22, 14, -14, -2, -10, -7, 11, 8, -7, -3, 0, -7, 11 }, { 7, -11, -7, -8, -14, 22, 5, 2, 6, 13, -12, -2, 10, 3, 0, -21, -4, 20, 3, 10, 21, -10, -12, 8, 11, 2, -5, 2, 1, 3, -1, 15 }, { -1, -2, -1, -2, -13, 8, -4, 0, 7, -2, -17, 8, 18, 5, 3, 8, -8, -2, 3, -4, 14, -18, -13, 14, 15, -13, -1, -2, 4, 11, 1, 12 }, { 13, -6, -4, -16, -17, 16, 21, -2, 5, -11, -9, 19, 21, -17, -3, -17, 3, 12, 8, -12, -6, 1, -7, 9, 9, -7, -5, -1, -3, 5, -6, -4 }, { 11, 5, 12, -20, -6, 10, 4, 12, 8, -5, -10, 15, 13, 14, 10, -15, -13, 1, 6, 14, 15, -17, -13, 4, -5, 10, 7, -6, -8, -3, -4, 12 }, { 25, -1, 7, -5, -7, 11, 1, 17, 13, -15, -14, -4, 5, 3, 8, -3, -2, 2, 0, 6, 16, -12, -6, -4, 4, -3, 7, -10, -3, -7, -13, 7 }, { -8, 10, -3, -13, 5, 2, 4, 9, 9, -17, -13, 2, 11, 1, 6, -4, 8, -10, 4, 1, 19, -15, -4, 12, 31, 7, -5, -17, -4, 9, -2, 7 }, { 14, -6, -6, -6, -14, 13, 17, -5, 4, -14, -9, 7, 7, -9, 3, -16, -15, 11, 11, 6, 4, -11, -19, 3, 5, 8, 13, -14, -14, 3, -4, 12 }, { -2, -4, 10, -4, -7, -1, 27, 5, 2, -16, -18, 4, 12, -2, -3, -2, -1, 1, -8, -12, 3, -4, 8, 15, 2, 4, 9, -13, -14, 9, -7, 5 }, { 4, 2, -10, -5, -7, 2, 1, 4, -1, -6, -15, 6, 1, 10, 5, -10, -9, -1, 13, -3, 5, -21, -11, 8, 8, 5, 27, -21, -18, -5, -1, 15 }, { 11, 1, -16, -8, -11, 0, 5, -8, -12, -13, -17, 22, 4, -6, -1, -18, -10, 0, 19, 2, -2, -8, -7, -3, 2, -2, -9, -17, -5, 4, 4, 10 }, { 8, -6, -19, -5, -4, 12, 14, 15, 10, -9, -1, -9, 19, 12, 0, -1, 2, 4, 7, 9, 16, -16, -14, 9, -4, 3, 1, 0, -2, 10, -1, -1 }, { 12, -8, 12, -9, 0, 25, 7, 9, 2, -31, -9, -4, 15, 4, -5, 1, -10, 11, 8, 10, 0, -6, 5, 11, -1, -6, 4, -10, -9, 6, 4, 5 }, { 14, 6, -17, -2, 17, 12, -9, 2, 0, -25, -14, 5, 20, 14, 8, -20, 5, 2, -2, -3, 9, -13, -3, -1, -6, 3, 7, -6, 0, 2, 3, 1 }, { 8, 4, -15, -3, 10, 18, -4, 13, 8, -22, -10, 9, 19, -15, 7, -5, -13, 12, -4, 9, 2, -9, -6, 0, 2, 1, -9, -6, 6, 1, -1, 11 }, { 4, 1, 4, -5, -10, 18, 7, 2, -4, -9, -11, 0, 32, -7, 4, -16, -1, 0, 6, 3, 6, -3, -14, 16, 9, -2, 7, -1, 0, -5, 5, -3 }, { -3, 2, 3, -8, -6, 4, 6, 2, 4, -12, -15, 2, 8, 8, 9, -3, -18, 6, 34, 11, 12, -15, -1, 2, 9, 2, -4, -4, 2, 4, 2, -3 }, { 18, -6, -12, -8, -1, 15, 20, -4, -1, -11, -5, 6, 6, -11, -15, -7, 3, 7, 10, 2, 8, -10, -5, 8, 15, -5, 5, -17, -13, 13, 11, 7 }, { 8, -4, -6, -1, -14, -3, 6, -2, 1, -5, -1, 10, 10, -15, 5, 0, -10, -4, -3, 7, -4, -19, -15, 27, 11, 18, 3, -19, -2, 6, 0, 12 }, { 12, 0, -5, 0, 4, -5, 1, 5, 10, -7, -11, 21, 29, 1, -2, 1, -4, -11, -1, 13, 11, -20, -1, 4, 4, 4, -5, 6, -13, -2, 11, 9 }, { 2, -7, -7, -3, -10, -1, 20, 12, 1, -19, -19, -1, 5, 4, -7, -25, 14, 1, -3, 2, 12, -4, -3, -3, -2, 6, 1, 0, 3, 2, 5, -1 }, { 12, -8, 3, -12, -10, 10, 13, 0, 23, -14, -18, 10, 0, 15, 3, -12, -3, -5, 5, -4, 2, -14, -10, 8, 2, 9, -1, -11, -3, 5, 13, 2 }, { 9, -6, 7, -7, -30, 17, 6, 13, 1, -14, 0, -1, 6, -9, 8, 3, -4, 0, -1, -7, -5, -13, -19, -3, -4, 4, -6, -2, -13, 1, -2, 3 }, { 10, 1, 3, -18, -26, 17, 4, -16, 4, -3, -13, -4, -6, -11, -4, -21, 7, 8, 2, 5, 13, -6, 1, 5, 8, 7, 9, -6, -6, 1, -1, 2 }, { -3, -1, 0, -2, -2, 0, -1, 3, 4, -14, -8, -9, 13, 2, 50, -23, -8, 8, 7, 11, 16, 3, -7, 0, -2, 6, 5, -1, 1, -2, 4, 3 }, { 1, 3, 1, 1, -6, 3, 6, 6, 2, -2, -3, 10, 2, -8, -5, -5, 5, 4, 4, -2, 10, -8, -40, -1, 21, 8, 3, -4, -1, 13, 4, 7 }, { 2, 0, -4, -8, 5, 2, 7, -5, 5, -8, -4, -1, 12, 2, 12, -13, -9, 0, 1, -12, 9, -43, 1, -5, 12, 1, 3, 6, 1, -1, 3, -2 }, { 6, -2, -1, 1, 0, 4, 8, 14, 4, -7, -23, -5, 23, -17, -6, -15, -8, 7, 10, -1, 7, -16, 4, -6, 2, 3, -3, -3, -1, 8, -1, 4 }, { 10, 4, -4, 1, 7, -3, 2, 11, 4, -6, -3, 8, 5, 4, 1, -45, -6, -4, 4, 2, 1, -14, -10, 1, 1, 6, 2, -8, -1, -3, 3, 3 }, { 1, -1, 2, -3, -8, 9, 3, 3, -2, -5, -8, 8, 7, -7, -4, -6, 5, -9, 11, -2, 46, -5, -1, 9, -2, 0, 3, -5, -3, -5, 7, 0 }, { -4, 1, -2, -1, -11, 11, 8, -3, -2, -10, 0, 4, 9, 9, -17, -17, -34, -4, -5, -7, -3, -12, -3, 11, 18, 3, -2, -5, -18, -5, -3, 6 }, { 7, -5, -3, 1, -4, -3, -5, -1, 2, 5, -2, 3, -10, 12, -18, -5, -10, 12, -9, 4, -6, 2, 0, 16, -17, 15, 14, -12, -10, -2, -9, -1 }, { 4, -5, -3, -5, -3, -1, 7, 18, -7, 12, 3, 5, -8, -4, -20, 1, -25, 1, -8, 13, -10, 8, -19, -1, -8, 10, 6, -9, -1, 0, 12, 4 }, { -4, 5, 0, -1, 2, 5, -8, -2, -6, 4, -8, 9, 3, 2, -7, 4, -25, 13, -23, 10, 14, 15, -11, 3, -18, 4, 16, -4, 1, -10, -10, 3 }, { 5, -3, -1, -3, 4, 1, -3, -4, -5, 1, -12, 14, -7, 11, -15, 6, -6, 24, -4, 13, -1, 15, -13, 8, 3, 7, -5, 2, 2, 0, 3, -7 }, { -3, 1, 0, 8, 6, -1, 6, 5, -5, -2, -12, 4, 0, -2, -3, 5, -6, 0, -8, 9, -10, 4, -28, 12, -20, 11, -13, 7, -18, 1, -11, 1 }, { 1, -4, -15, 5, 0, -13, -5, 13, -11, 4, -4, -5, 5, -14, -16, 0, -14, 5, -20, 12, 10, -7, -5, 6, 6, 22, 6, -4, -2, 3, 8, 11 }, { 13, -11, -2, 16, 16, -7, 0, 20, -7, -1, 0, 5, -9, 12, -2, -5, -22, 5, -10, 12, -6, 11, 9, 21, -8, 15, 4, 0, -8, -4, -4, 10 }, { 18, -4, -13, 0, 1, -15, -1, -3, 2, 10, -1, 6, 1, -4, -20, -5, -8, 6, -8, 17, -5, 5, -10, 8, -22, 6, -5, -2, 8, -17, 8, 2 }, { 1, -2, -9, 6, -31, -8, -8, 8, 0, 5, -9, -4, 2, 3, -12, 11, -18, 10, -5, 3, -11, 13, -6, 11, -3, 12, -7, 3, -9, -1, 2, 11 }, { -9, -6, 21, -8, -15, 4, -11, 12, -11, 17, -1, 2, -6, 0, -15, 13, -12, 19, 0, 2, -6, -3, -9, 10, 3, 17, -2, 5, -10, -3, 0, 1 }, { 4, -6, 5, -10, 1, -5, 1, 0, 0, 0, 2, 7, -2, 2, -2, 0, -4, 3, -4, 1, -12, 6, -49, 16, -10, 13, 0, -2, 8, 6, 1, 8 }, { 5, -8, -7, 9, 13, -5, 7, 0, 10, 11, -4, -3, -1, 13, -14, 6, -15, -6, -14, 16, 15, 1, -18, -4, -20, 20, -7, -1, -9, -2, -10, 10 }, { -12, 4, 0, 10, 0, 3, 8, 4, -27, -1, -2, 19, -4, 2, -13, 3, 1, 9, -12, 1, -22, 19, -5, 4, -9, 12, 2, -9, -8, 11, -3, 7 }, { 4, -5, 11, -6, 17, -17, 5, -4, -2, -6, 1, -5, 2, 4, -14, 6, -20, 19, -20, 12, -21, 5, -14, 13, -2, 11, 4, -3, 0, -10, -4, -2 }, { -2, -1, -3, 8, -9, -7, -22, -3, -24, 13, -2, 10, -15, 5, -9, 4, -7, 0, -5, 15, -8, 11, -13, 6, -4, 19, -8, 12, -4, 6, 9, 7 }, { 2, -3, 2, -1, 0, 3, 1, 2, 1, -4, -2, -3, 1, 5, -12, 6, -16, 14, -23, 10, -14, 17, -15, 16, -2, 9, -25, 9, -10, 16, 4, 9 }, { -3, 7, -8, -3, 2, 2, -4, -8, -9, 10, 3, -11, 25, -10, -28, 27, -9, 7, -13, 9, -2, 4, -12, -8, -14, 6, 7, -10, 3, 3, -3, 5 }, { -8, -3, 1, -10, 8, -3, -9, -4, 13, 7, 2, 4, -10, 4, 3, 7, -18, 2, -22, 15, 4, 20, -7, 5, -6, 13, -1, 4, -7, -6, 6, 13 }, { -2, 3, 0, 2, -4, -2, 0, 0, 1, 2, -2, -5, 0, 1, -4, 0, -2, -3, 1, 2, -1, 2, -8, -1, -24, 68, -3, 8, 3, 3, -1, -1 }, { -15, -2, -9, -7, -1, 8, -14, 8, 3, 6, 0, -1, -8, 8, -23, 2, -14, 17, -15, 8, -4, 7, -18, 0, -8, -3, -1, -4, -10, 4, -1, 4 }, { 8, 0, 2, -7, 0, 5, 1, 3, -11, 4, -8, 14, 3, 20, 1, 26, -11, 13, -13, 20, -2, 0, -8, 2, -6, 6, -1, 9, 3, -6, -3, 10 }, { 5, 0, -1, -7, 10, 1, -3, 5, 4, 7, -5, -1, -3, -1, 12, -3, -15, 7, -9, 22, -19, 8, -9, 4, -23, 13, -14, 6, -6, -14, -4, 7 }, { 14, -5, -8, -10, 25, 3, -23, -7, -28, 0, -1, -9, 4, 1, -13, 20, -8, 10, -16, 8, 12, -13, -21, 5, -13, 11, -2, 1, 12, -7, 2, -10 }, { -5, -4, 9, 5, -6, 35, -7, 8, 15, 2, -1, -9, -6, 2, -18, 7, -15, 6, -3, 2, 8, 12, -30, 7, -4, 20, 2, 6, 13, -6, -4, 0 }, { 1, 8, -9, 9, -5, 12, -9, 16, -9, 16, -17, 14, -13, 15, -18, 14, -15, 17, -12, 14, -13, 7, -16, 13, -9, 5, -11, 10, -9, 6, -12, 13 }, { -10, -4, 5, 3, 1, 6, 8, -14, -5, 15, 7, 4, 8, 7, -22, 8, -7, -8, -15, 26, 1, 13, -3, 17, -5, 9, -2, 4, -6, 3, -8, 9 }, { 8, -3, 2, 3, 3, 1, -2, -1, -11, 8, -4, 0, -6, -5, -1, 13, -37, 9, 1, -6, -10, -2, -10, 11, 8, 13, -3, -2, -6, 8, -4, 13 }, { 3, 2, -3, -4, -4, 7, -8, 9, -8, 9, -20, 12, -19, 15, -18, 17, -15, 7, -1, 20, -11, 6, -6, 3, 1, 9, 2, -14, -2, -2, 2, 1 }, { -7, 1, -1, -3, -6, 4, 4, -3, 3, -1, 5, -4, 3, 2, -1, 9, -59, 5, -4, 30, 3, 3, -2, -3, -1, 2, 2, 1, -1, -1, -2, 1 }, { 0, -3, 2, 0, -1, -8, 0, 2, -3, 4, -4, 1, 10, 6, -6, 8, -7, 4, 10, 11, -41, 27, -20, 3, -3, 8, 1, 11, -5, -8, 0, 4 }, { 5, 1, 4, -2, 1, 2, -1, 6, -7, 2, 11, 4, 0, 0, -8, 7, -10, 0, 0, 8, 2, 10, -1, 1, -2, 44, -2, -21, -12, -3, -1, 2 }, { -4, 4, -2, -2, 6, -8, 2, 1, -10, 14, 8, 6, 5, 1, -2, 4, -13, 4, 2, 5, 10, -2, -21, 32, -3, 18, 9, -6, -9, -9, 10, 2 }, { 9, -16, -6, -2, 1, 4, 22, 2, -2, 1, -3, -2, -9, 3, 16, 19, -24, -6, -6, -5, -8, -7, 8, -7, -1, -12, 5, -3, 0, 4, 2, -3 }, { 10, 3, -16, -4, -1, 13, 4, 4, 1, -3, 1, -6, -14, 18, 3, 8, -8, -28, -16, 4, 4, 2, 12, 7, 9, -4, -4, 5, -1, -1, 2, 2 }, { -5, -13, -22, -3, -8, 21, -2, -9, 21, -4, -9, 5, -8, 15, 5, 1, -5, -9, -7, -2, -5, -5, -1, -5, -5, -5, 3, 10, -4, 0, -7, -2 }, { 5, -10, -18, 2, 20, 4, 13, -10, 8, -15, -11, -3, -1, 16, 10, 9, -8, 6, 7, -5, 6, 11, 5, 17, -4, 7, -11, 5, -3, -6, 2, 1 }, { 3, -5, -19, 1, 1, -3, -2, -25, -11, -17, 0, -13, -4, 10, 10, 2, -5, 4, 0, 3, -3, -5, -10, -2, 13, -22, 0, 3, -11, -5, 7, -1 }, { 12, -14, -29, 6, -1, 10, 7, -17, -12, 14, 3, 9, -9, 9, 7, 6, -3, -13, 0, 5, 3, -1, -6, -1, 0, 2, 4, -12, -5, -1, 2, 11 }, { 12, -15, -7, -2, -12, 17, 20, -16, -2, -12, -6, 15, -6, 12, 11, 9, 7, -6, 7, -4, -19, 6, 2, 2, 3, -11, -10, -4, -5, -3, 3, 2 }, { 11, -22, -6, 0, 8, 18, 3, -11, -4, -7, -15, -17, -12, 6, 16, 4, -9, 4, -5, 3, 6, -16, 10, -7, -7, -3, 5, 0, 1, -15, -4, 5 }, { 12, -22, -16, 5, -6, 8, 12, -4, -9, -17, -11, 3, 5, 8, -17, 0, 11, -4, -13, -6, 2, -1, -1, 3, 3, -11, -12, -1, 1, 1, 12, -2 }, { 8, -10, -33, -5, -3, -6, 1, -7, -8, -4, -6, -1, 5, -4, -6, -12, -16, -8, 11, 8, -14, 7, 12, 11, 4, -14, -3, 6, -7, -5, -3, 3 }, { 0, -8, -7, 2, -4, 24, 2, -9, -11, -3, -7, 11, -12, 17, 1, -1, 3, -5, -7, 12, 4, 11, 0, 3, 2, -18, -3, 4, 7, -6, 3, 15 }, { 10, -15, -16, -2, -4, -9, 7, -15, -6, 2, -16, 13, -8, 7, 19, -21, -4, -12, -9, -3, -3, 6, 11, -3, -1, -19, 3, -7, -9, -4, 3, -6 }, { -5, -10, -21, 0, -3, -7, 18, -21, 15, -5, -12, -4, -13, 2, 6, -9, -9, -11, -4, 13, -3, 6, 4, -1, 7, -9, -4, 9, 5, 2, 6, 3 }, { 15, -1, -27, -2, 10, 3, 7, -8, 9, -2, 7, 1, -2, -5, 18, 9, -11, -17, -2, 7, -9, 11, 10, 0, -8, 6, -16, -3, 2, -7, 3, 11 }, { 4, -9, -39, 19, 6, -13, 13, -5, -5, -15, -2, 9, 0, 4, 14, 6, -10, -4, -5, 2, -4, -2, 5, -11, 3, 3, -2, -2, -7, 9, 7, -10 }, { 5, -11, -8, 10, -2, 12, 16, 0, 12, -2, -6, 8, 14, 8, 7, 1, 18, -30, 4, 10, -4, -6, 2, -11, 9, -10, -8, 5, 0, 0, -7, 6 }, { -1, -16, -10, 11, 0, 13, 12, -4, -4, -5, -21, 12, 4, 13, 14, -7, 6, -16, -13, 8, 2, 9, 15, -12, 1, -9, -22, 10, -9, 9, 9, -7 }, { 4, -12, -27, 1, -2, 11, 15, 3, 14, -14, -9, 0, -9, 16, 22, 10, 16, -10, 5, -5, -9, 1, 1, 6, 6, -4, 2, -17, -5, -6, -15, -1 }, { 7, -12, -17, 1, -9, 5, 20, -7, 3, 23, -8, -8, -8, -1, 13, 17, -7, -13, 4, -4, 7, 14, 8, 11, -3, -3, 4, 0, 4, 6, -1, -9 }, { 7, -15, -15, -4, 10, 12, 3, -13, 6, 14, 9, -8, -15, 14, 23, -5, -10, -5, 1, 15, -10, -7, 1, 9, 4, -13, -10, 10, 7, -3, 2, 3 }, { 4, -10, -14, 0, 3, 4, 0, -9, -3, -4, -11, 2, -17, 8, 2, 15, 6, -12, -12, 15, -5, 17, 18, 3, -3, -3, -4, -6, -8, 13, 4, 10 }, { -2, -18, -26, 10, -4, 10, 13, 4, -4, -16, -7, -17, -3, 5, -4, 2, -15, -10, -1, -8, -7, -3, 2, 2, 8, -10, -7, 2, 2, -4, 4, -1 }, { 4, -19, -5, -1, -1, -6, 2, -8, 10, -16, -28, -6, 8, -1, 11, 28, 2, -10, -4, 6, -6, 6, 11, 15, -4, -2, 7, 3, 7, -7, 4, 1 }, { -3, -6, -10, -5, 13, 18, 10, -15, -5, -3, -13, 5, 1, 2, 18, -5, -10, -10, -7, 4, 2, 1, 5, 4, 2, 5, 4, 8, -9, -17, 7, 7 }, { 20, -12, -2, -4, 5, 14, 7, -11, -1, -16, -6, -4, -11, 17, 14, 0, -8, -10, -8, 10, 3, 5, 10, -16, 3, -8, -14, 10, 3, 9, 0, 3 }, { 12, -10, -36, 0, 7, 15, 2, -16, 2, -1, 0, -1, 5, 4, 5, -3, 1, -10, 5, -1, -15, -3, -12, 12, 2, 5, -1, 5, 6, -3, -2, 2 }, { 17, -15, -31, 23, -4, 15, -2, -3, 6, -7, -5, 1, -12, 4, 6, 8, -10, 8, 3, 5, -4, 1, 5, 3, -1, -4, -3, 1, 10, -4, -2, -2 }, { 6, -18, -5, 12, 10, 12, 14, -11, 15, 2, -9, -6, -5, -2, -9, 4, -5, -28, -4, 14, 0, -16, 9, 14, -1, 3, -4, -4, 2, 1, 0, 4 }, { -5, -14, -31, 8, 16, 7, 13, -13, 5, 6, -16, 10, -5, 2, -2, 2, 14, -5, 8, -5, 7, -16, 6, -13, -5, 0, -5, 8, -3, -1, 4, 3 }, { 1, -2, -1, 0, 6, 5, 2, -4, -3, -1, 0, 1, 4, 2, 43, 28, -12, -35, -2, -2, -7, -1, 0, 2, -1, -2, -2, 1, -4, 0, -2, 3 }, { 2, -9, -22, 12, 3, 3, -7, -4, -19, -22, -14, -4, -1, 21, 9, -3, -15, -16, -13, 1, -11, 4, -9, 1, -7, -1, -1, 0, -2, 9, -13, -3 }, { -1, -3, -23, 0, 2, 12, 3, -9, -4, 7, 3, 9, -10, 1, 27, 28, 0, 9, -15, -2, -2, 1, 6, 8, -8, 7, -3, 20, 0, 0, -1, -6 }, { -1, 11, 8, -2, 1, 5, -6, -1, 4, 2, -4, 0, -1, -5, 4, -6, -10, -12, 19, 1, -7, 9, -8, -9, -16, -11, -2, 12, 14, 4, 4, 34 }, { 17, 7, -6, 1, 4, -10, -5, 4, -11, 3, -18, 4, 14, -13, -3, 1, 0, 0, -11, 0, 7, -17, -4, 4, -11, -6, -8, 18, 0, 0, 0, 26 }, { -6, -7, -1, -1, 11, -8, 1, 3, 2, 11, -6, -6, 10, -3, 1, -3, 7, 4, -12, -8, 0, -9, 8, -22, -5, 0, -6, 22, -2, 11, -13, 24 }, { -3, 4, 0, 3, 9, 10, -1, 3, -9, -12, 1, -5, 18, 0, -3, 8, 25, 15, -8, 2, 2, -2, 4, 8, 9, -1, -5, 10, -3, 1, -1, 23 }, { -5, 2, -9, -1, -3, 0, 3, -1, -10, -4, 0, -13, 16, 9, -1, -14, 2, 6, -2, -6, -5, -2, -7, 7, 5, 3, 11, -2, -14, 0, -9, 30 }, { 4, 6, 6, 5, -3, -1, 4, 5, 10, 0, 5, -4, 7, -11, 14, 14, 7, 34, -9, 0, -10, 22, -7, -1, 7, -9, 2, -8, 0, -7, -5, 29 }, { -4, 3, -1, -4, -3, 5, 1, -4, 0, 2, 4, 2, 1, -1, -10, 1, 6, -6, -4, 1, 4, -3, -3, -5, 0, 3, 7, -12, 0, -2, -10, 55 }, { 5, 9, -1, 0, 4, 9, -21, -9, 4, 2, 6, -7, 11, -7, 1, -5, 0, -4, 2, -3, -13, -8, 0, -9, -4, 2, 16, -2, -15, -7, -11, 31 }, { 8, 2, -1, 0, 3, -5, -5, 5, 1, -1, -9, 1, 0, -6, -2, -1, 5, 2, 0, 0, 12, 20, -19, 1, 8, -12, -11, 0, 6, -5, 2, 31 }, { -1, -1, -2, 1, -1, 3, -9, -5, 8, -2, 5, -1, 0, -2, 4, -2, -3, -12, 0, -2, 3, 0, 9, 4, -1, 21, -8, 3, -4, 9, -6, 30 }, { -4, 0, -7, 17, 10, -12, -2, -10, -12, -3, 10, 0, 11, -4, -13, -3, 5, 6, 10, 7, -8, 0, -7, -13, 1, 0, -2, 7, -12, 4, -3, 24 }, { -13, 9, 4, -2, 2, -4, -14, -1, -3, -5, -10, 4, 13, -2, 5, 13, 8, 3, -2, 1, 5, -6, 7, -18, -10, 1, -1, 5, 4, 1, 0, 25 }, { -5, -1, 18, 12, 8, 8, -16, -1, 1, 1, 1, -4, -5, 3, 3, 4, 4, -11, -12, -16, -6, 2, 12, -13, 0, 9, 7, 9, -9, 0, -10, 24 }, { -4, 1, -3, 0, 2, -4, 4, 1, 5, 0, -3, 2, -3, -2, 2, -1, 1, 4, -1, -2, -2, 1, -1, -1, -4, -1, -4, -2, -6, 6, 12, 69 }, { 8, 5, 11, 0, -15, -4, 13, 6, 0, -4, 9, 1, -5, -3, 15, 0, 1, 6, -5, 0, 1, 6, 5, 8, 0, 7, 1, -1, -4, -11, -9, 41 }, { -4, -9, 32, -6, 0, 7, -4, 6, -6, 1, -6, -2, 4, -8, -5, -3, -16, -1, -2, -6, 1, 15, 0, 21, 3, -3, -4, 3, -12, 16, 2, 27 }, { -6, -5, 1, -9, -5, 3, 7, -3, 5, 5, 14, 13, 20, -7, -1, 12, -1, 10, -11, -11, -7, -4, -14, 7, -14, 13, 22, 18, -1, 0, 14, 28 }, { -8, 3, -2, 0, 5, 6, -1, -4, 1, 3, -7, 3, 1, -15, 4, -9, 22, -10, -9, -4, 1, 8, -4, 9, -15, 2, -6, -4, -16, 12, -10, 23 }, { 0, 0, 2, 0, -1, 3, -3, -1, 3, -5, 7, 1, 5, -5, -8, 1, 13, -15, -5, -7, 12, -6, -2, 3, 10, -5, -8, 17, -5, -11, -14, 23 }, { -7, -4, 6, -4, 5, -6, -5, 2, -4, 11, 9, -4, 2, -2, -4, 6, 15, 3, -3, 18, -15, -2, -6, 3, 3, -20, 17, 11, -4, 2, 3, 29 }, { 6, 1, -6, 2, 3, 0, 0, -3, 3, 3, -1, 3, -4, -6, -6, -7, -3, -2, -7, -2, -4, 5, 3, -5, -20, -13, -4, 10, -14, -29, 14, 37 }, { 3, 4, 3, -6, -4, 5, 0, 3, 2, 3, 0, -2, 4, 0, -3, -5, -4, 4, -4, 4, 4, 3, 1, -4, -4, -9, -14, 20, -30, 3, -18, 33 }, { 0, 2, 5, -2, -4, -2, -1, 2, -6, -3, -2, -2, 2, -5, -1, 4, 3, 2, -3, 0, -1, -1, -10, -7, 2, -4, -18, 2, -37, -1, 12, 40 }, { -7, 2, -1, 0, -2, 4, -8, 1, -4, 12, 7, 4, 15, -7, 1, -9, 18, 0, 12, -17, -3, -1, 0, 0, 0, 2, -6, 0, -4, -3, -1, 26 }, { -6, 4, 8, -5, -6, -2, 2, -1, 1, -1, -15, 8, 7, -1, -17, -4, 1, 5, 6, -11, -6, 14, 17, -5, -15, 11, 8, 0, -3, -15, -6, 28 }, { -1, 0, 0, 0, 1, 0, -1, 0, 1, 3, 2, -2, 3, -1, -1, 2, 2, -1, -1, -7, 1, 2, -9, 0, -1, -4, -18, 7, -10, 49, -13, 32 }, { -1, -3, 4, 1, 2, -5, 1, -7, -1, 5, -9, 4, 4, 25, 1, -1, 2, -5, 2, -7, 17, -2, 10, -5, 0, 2, -15, 3, -9, 7, -9, 30 }, { -5, -1, 0, 2, 1, -1, 2, 5, -33, 3, -5, 14, 11, 7, 5, -3, 2, -8, -4, -2, -7, -6, 4, -8, -1, -8, 2, -2, -8, -1, -4, 27 }, { -1, 0, -1, -2, 1, -1, -2, -1, 2, 0, 1, 2, 2, 4, 1, 3, 4, 2, 1, -7, -4, 1, -3, -4, -35, -25, 17, 10, -3, -26, -7, 32 }, { -5, 1, 6, -2, 6, 6, -9, 3, -1, -4, 5, -4, -2, -2, -9, 2, -5, 2, 2, 4, 3, 5, -5, -16, -31, -12, -11, 2, -19, 20, -2, 21 }, { -5, 2, 7, -7, -7, 5, -7, 2, 0, 0, -4, 3, -1, 0, -1, -2, 0, -3, 5, -11, -8, -3, -7, -7, 28, -11, -7, 0, -16, -11, -4, 29 }, { 2, 1, -3, -2, -1, 3, 4, 0, 1, 0, -1, -5, 4, -5, -12, 2, -2, -5, -22, -2, -1, 11, 8, -7, -12, 0, -34, 6, -5, 11, -8, 19 }, { -1, -3, 5, 11, 18, -2, -2, -5, -2, 4, -1, 8, 5, -6, 1, -1, 2, 8, 4, -5, -8, -2, 5, -18, 7, 12, 7, 19, -18, 2, -6, -13 }, { 9, 0, 0, 5, 4, 3, -6, 4, 1, -4, 5, -1, -4, 8, 8, 6, -8, -6, 0, 6, -3, 3, 5, -3, 17, 31, 16, 10, -13, 0, -9, -19 }, { 12, -10, 2, -2, -2, -1, -3, 6, -12, -5, -2, 14, -16, 4, 12, 12, 17, 4, 7, -16, 7, -6, 11, 7, 7, 2, -25, 23, -24, 5, -7, -9 }, { 10, 4, 13, 10, 10, 3, -6, 3, 3, 2, -1, -6, 8, 4, 10, 0, 1, 2, -4, 2, -3, -8, 0, -1, 9, 9, -10, -3, -29, 1, -1, -27 }, { 2, 2, 0, 7, 9, -2, -10, -1, -1, 1, -9, -5, 8, 4, 1, 2, -10, 1, 13, 12, -3, 15, -9, 2, -7, 1, -10, 23, -20, -18, -9, -15 }, { -3, -5, -1, 8, 0, -5, -1, 4, 7, -1, -7, 2, -8, -5, 11, 7, -6, 3, -3, -9, 7, 9, -22, 1, 6, -4, 14, 27, -25, -14, 3, -5 }, { 1, 3, 8, 4, 7, 6, 12, -17, -15, 1, -8, -10, 7, -14, -8, 6, -2, -2, -11, -11, -7, 13, -2, -2, 4, 5, -5, 13, -23, -6, -17, -8 }, { -5, 4, -14, -5, -4, -5, 6, 5, -8, -5, -2, -11, -7, -12, 3, -11, 2, -6, 4, -10, -5, -7, 14, 5, 23, 11, 7, 12, -16, -6, -4, -16 }, { 5, 6, 2, 5, -2, -5, -5, -6, -5, -19, -13, -1, -3, -13, 5, 0, 6, -2, -2, -6, -7, -7, -1, -9, 4, 14, 17, -12, -27, 3, 0, -1 }, { 7, -1, 9, -10, 8, 2, -7, -2, 5, 2, -3, -7, 3, 0, 6, 4, 12, 5, 11, 14, -13, -1, 8, 1, 13, 9, 12, 12, -18, -14, -11, -16 }, { -7, -5, -6, -5, 0, -1, -3, 2, 2, 1, 4, 9, 2, 3, 5, -2, 2, 1, 8, 0, 3, 0, -2, 2, 1, 7, 29, 0, -36, -5, -9, -21 }, { 14, -6, -9, 0, -1, -8, -8, -11, 2, 2, -9, -12, 12, -4, 5, 3, -5, -9, 11, -1, -3, 12, -21, -3, 12, 5, 3, 11, -18, -15, 1, -2 }, { -1, 3, -9, -3, 7, -7, -18, 2, 4, 12, -10, 2, 8, -3, -14, 13, 17, -5, 5, -9, 13, -3, -7, -18, 17, -2, 5, 7, -20, -3, -6, -11 }, { -3, 3, 3, -1, 1, -6, -5, 1, 5, -3, -14, -6, -5, -8, 14, -6, 7, -1, 5, 1, 15, -1, -7, -4, 6, -11, 9, -2, -37, 16, -7, -3 }, { -1, 0, 6, 1, -3, -9, 0, 11, -8, 2, -2, 0, 5, 2, 12, -10, 10, 13, 2, 7, -6, 2, -10, -10, 21, -5, 5, 5, -12, -23, 3, -14 }, { 6, 0, -2, 1, 0, 1, 0, -4, 1, 1, 8, -2, 2, -5, -2, 1, 8, -4, -1, -1, 4, -1, 2, 6, 32, 1, -5, -20, -40, -4, -18, -14 }, { 2, 2, -7, -2, 4, 4, -1, 2, 0, -2, -4, -7, 3, 5, 0, -5, 1, 2, -6, 4, -1, -2, -1, -15, 8, 3, 9, 46, -7, -18, 6, -11 }, { 5, 5, 16, 21, 3, -11, -4, 11, -12, 2, 4, -12, -1, 11, 8, 1, -4, 11, -11, -21, 1, 1, -11, 3, 13, 1, 5, 12, -25, 1, -3, -2 }, { 1, 6, -7, 4, 2, 3, 1, -5, 8, 9, -15, 3, -3, -14, 17, 4, -8, 14, -2, -8, -4, 5, 8, -7, 8, 9, 7, 6, -29, -17, 8, 4 }, { -7, -7, 4, 0, 13, 1, 0, 4, 4, -16, -10, -7, 5, 9, -15, -10, -10, 8, -4, -1, -11, -1, -10, -15, 3, 3, 14, 10, -19, 2, -18, -12 }, { -4, 0, 2, 0, 5, -2, -9, 0, 4, -4, 2, -1, -2, 2, -4, 9, 2, -6, -4, -2, -1, -3, -3, -1, 2, 5, -1, 11, -24, -44, -9, -15 }, { -1, -10, 6, 21, 11, 15, -7, 10, -14, -9, -8, -8, 4, 6, 19, 1, -6, 1, -5, -17, -8, -10, 9, 5, 11, 18, -1, 10, -16, -7, -9, -8 }, { 3, -5, 0, 0, -2, -2, -6, 4, -4, 1, -1, 0, 7, -3, 4, -4, -7, 7, 17, -20, 6, 4, 1, -6, -12, 31, 13, 19, -14, -10, -7, -2 }, { -2, 6, -10, 3, 9, 6, -14, 15, 2, -5, 2, -11, 9, -8, 4, 6, 20, -15, -3, -3, -1, 32, -21, 6, 1, 9, 11, 17, -19, 6, -1, -3 }, { 8, 10, -2, 0, -8, -16, 7, 7, 6, 10, 4, -14, 7, -6, 21, -7, 10, 5, 5, 0, -7, 2, -6, 0, -7, 11, -9, 15, -20, -7, -11, 2 }, { 0, -7, 5, 2, 0, -3, -6, -4, -2, -1, -4, -5, -13, -1, 27, -9, -6, -11, -7, 1, 11, -4, -4, -14, -2, 11, 6, 10, -19, -6, -15, 2 }, { 0, 7, -1, 2, -7, -15, -2, -3, 13, -5, -5, 12, 3, 0, 5, -5, -22, 2, 7, 22, 13, 0, -1, 2, 3, 2, -7, 7, -27, -4, -4, -12 }, { 11, 1, -16, 6, -15, 1, 3, 2, 0, 2, -3, 2, 5, -2, -5, 9, 5, -3, 3, -2, -11, 3, 9, 6, 9, 3, -1, 12, -41, 8, -6, 9 }, { 3, -7, 3, 2, 5, 5, 0, -1, 1, 3, -5, -2, -13, 7, -1, -2, -2, -6, 4, -6, 0, 2, -2, 2, 4, 1, -4, 1, -47, -21, 7, -6 }, { 3, 16, -7, 13, -4, -2, 10, -3, -1, 18, -13, 7, -13, -4, 8, 4, 8, 9, -5, 13, 8, -5, 3, -6, 7, 18, -8, 10, -25, -3, -12, -12 }, { 1, -1, -1, 0, 2, 5, -5, -3, 0, -5, -1, 0, -4, -8, -2, 3, 2, -2, -17, -6, -4, 1, 33, -6, -20, -6, 8, 31, -26, -8, -1, -4 }, { 3, -3, -3, 5, -3, -2, 1, 7, 0, 3, 6, 3, 6, -2, 9, 15, -10, -3, -15, -5, -3, -4, -6, -30, 17, -8, -2, 2, -20, 0, -8, -2 }, { -2, -1, -1, -1, 3, -5, -2, -3, 4, -2, 0, 5, 8, -3, 1, -4, 1, 1, -3, 4, 4, -14, 3, 11, -5, 3, -3, 7, -3, 13, 23, -16 }, { 2, -6, 1, -3, 5, 0, -6, -11, -7, -4, -1, 2, -7, -1, -1, 7, 1, -2, 6, 12, -6, 8, -13, 17, 25, -23, -19, -7, -12, 9, 16, -17 }, { 9, 4, 4, 4, -3, -1, 6, -2, -3, 0, 13, -4, -7, 14, 1, -7, 0, -5, 3, -19, -3, 5, 3, 9, -1, 9, -13, 13, -17, 4, 21, -26 }, { 0, -5, 0, 0, -4, -5, 2, -6, -4, 5, -7, 10, 0, 2, 0, -2, -2, 0, 4, -6, 7, -2, 6, 5, -5, 2, -12, 1, -29, 29, 27, 12 }, { 9, -10, -22, 6, -1, -1, 9, -14, -12, -2, 1, -1, 10, -11, -16, 0, 3, 11, 13, -14, -9, -2, -1, 6, 4, -14, 0, -10, -2, 16, 17, -11 }, { 2, 0, -1, -2, 4, 3, -6, -2, 1, -1, 1, 3, -4, 1, 3, -4, -1, -1, 4, -1, 1, 0, 1, 6, -5, -7, 2, 1, -47, -3, 50, -17 }, { 8, -4, -11, -7, 11, 11, 14, -7, 12, -7, 6, 2, 13, -6, -3, -2, -14, 6, 6, 6, 0, 2, -1, 5, -20, 2, -1, 4, -5, 6, 21, -11 }, { -2, -9, 3, 0, -6, 7, 8, -8, 1, -3, 4, 1, 5, -2, -3, -7, 4, 7, -12, -9, -2, 10, -6, 13, 6, 5, 20, 2, -15, 9, 28, -7 }, { 0, -5, -6, -6, -6, 1, -6, 6, -2, 4, 8, -3, 12, -1, -4, -2, 6, 16, -14, 9, -14, -2, -8, -27, -3, 18, -1, -7, -3, 8, 23, -23 }, { 1, 4, -9, -1, -5, 10, -2, 1, -11, 1, -9, 4, 7, 14, -9, -2, -3, 2, -5, -1, -6, -10, -7, 11, 20, 2, 3, -19, 3, 15, 30, -9 }, { 7, 2, -14, -4, 0, -2, 5, 2, 5, -2, 8, -3, -7, 6, 6, -11, -14, 1, 10, -1, -7, -8, 1, 10, 3, -6, -15, -12, -17, 4, 30, -6 }, { 4, 2, 1, -2, 3, 0, 1, 0, 2, 0, 1, 6, -7, 0, 3, 4, 4, -4, -2, -5, -2, 2, -1, -2, 0, -2, -11, -7, -3, 42, 24, -14 }, { 4, 1, 3, 2, 0, -2, -3, -2, 2, -1, 4, 11, -2, 2, 3, -4, -5, 9, 2, -4, -9, 5, 8, -1, -7, 1, 24, -13, -28, 20, 15, -22 }, { -3, 7, 6, 3, -2, -5, -10, -2, -2, -1, -6, -6, -2, -14, -16, -6, -5, 0, 18, 0, 9, 1, 7, -13, -5, -6, -9, 11, -15, 9, 22, -11 }, { 9, -2, 6, 5, 2, 9, -10, 1, 1, 5, -4, 12, 2, 2, -10, -7, -4, -6, 7, 9, 6, 15, 6, 6, -10, 10, 5, -13, -5, 6, 24, -12 }, { 1, 3, -3, -3, 8, 1, -6, 2, -5, -3, 7, 2, 14, 6, 9, -6, -5, -4, 27, 7, -3, 8, -6, 3, -8, 8, 22, -5, -6, -2, 22, -17 }, { -2, -2, 3, 10, 9, 9, 12, -15, -1, -11, -13, 3, -2, 1, -3, -11, 7, 9, 16, -3, -10, -5, -5, 1, 8, -3, 9, 9, -5, 3, 31, -12 }, { 7, -5, 10, -4, -8, 2, 16, -2, 10, 10, -3, -2, 3, -8, -3, 3, -13, -6, 15, 20, -9, -3, -12, 1, -2, -16, 8, 8, -1, 16, 22, -5 }, { 5, -3, -15, -2, 12, -8, 8, -5, 2, -8, 20, -18, 14, -4, 3, 3, 7, -13, -16, 1, -10, 7, 16, 7, 4, -14, -4, -5, -9, 8, 23, -6 }, { 5, -4, -5, -4, 1, 8, 4, -7, -5, 8, 10, 6, -6, -10, -2, 6, 9, -17, -14, 11, 12, -3, -13, -7, 2, 18, 3, -25, -16, 18, 22, -5 }, { 5, 6, -7, -20, -4, 2, 8, 4, -24, -4, 1, 4, -5, -2, 1, -10, -2, 9, 3, -4, -3, -4, -4, -4, 10, 10, 3, 0, -6, 25, 21, -11 }, { 0, 7, -1, 14, -6, -4, -10, 5, 4, 4, 4, -5, 3, 4, -1, -7, 8, -19, 0, 6, 2, 3, -18, -3, -6, 2, 8, 14, -26, 22, 27, -13 }, { -2, -6, 7, -5, 12, -7, 8, -1, 3, -2, 4, 1, 8, -2, 0, 14, 6, -5, 6, -4, -7, 7, -21, 8, 1, 8, -9, -4, -3, 11, 25, -13 }, { 4, 4, -1, -6, 4, 9, -8, 1, -3, -10, -2, 0, 15, -9, -16, 11, 1, 1, 6, 3, -9, -5, 16, 26, 1, -14, 1, -3, -14, 7, 15, -9 }, { -12, -2, -9, -13, 2, 6, 14, 0, 1, 0, -1, -13, 0, 10, -1, 6, 9, -7, 8, 8, 19, 6, -1, 9, 10, -4, 1, -7, -22, -2, 29, -7 }, { 2, 4, 13, -12, -8, -4, -5, 13, 12, -5, -3, -3, -4, 1, -1, 10, 15, -6, -1, -11, -30, 4, 15, -1, 9, -7, 0, -2, -7, 10, 25, -16 }, { 7, -15, -7, -7, -1, -5, -5, -11, -20, 10, 3, -10, -3, 5, 20, -4, 0, -2, -2, 17, 2, 0, -3, 3, 6, 5, -1, -12, -3, 15, 22, -16 }, { 4, -1, 3, 4, -5, 0, -1, -5, -24, -29, 4, -9, 1, -3, 0, 0, 0, -4, 7, -4, -4, -4, 3, 1, -6, 5, -3, -5, -10, 3, 25, -10 }, { -2, -1, -1, 4, 4, -1, 2, 0, -4, -4, 2, -1, -3, -1, -2, -2, 1, -3, -5, -1, 2, -3, -4, -4, -3, 5, -9, 1, -11, 7, 46, -46 }, { 0, -9, 3, 4, 4, 3, -5, -6, 5, -4, 4, -2, 1, 7, -4, -10, 13, 1, 3, -6, 4, -4, 7, 2, -19, -25, -3, -16, -12, 16, 20, -1 }, { 18, 6, 4, -12, 0, -14, 9, -6, -1, -4, -5, 2, 1, 12, 4, 2, 7, 0, 2, 5, -11, -5, -2, 2, -4, 10, 0, -9, -7, 9, 25, -8 }, { 5, 0, -6, 5, 6, 3, 3, -10, -5, 1, -1, 4, 3, -11, -8, 5, 4, -5, 5, -5, -7, -5, 11, 5, 20, -8, -16, 21, -4, 27, 23, -5 } }; xine-lib-1.2/contrib/README.contrib0000644000175000017500000000162714647725151014650 0ustar memeThe contrib/ subdirectory for xine-lib contains the code for libraries that are not developed by the xine project, but are rather imported from other projects. These libraries are imported either because they need to be patched to fix bugs not yet fixed in any released version, to make it simpler for the users to have the library installed, or because there's no proper release done by that project. This README file should explain how to upgrade the code present in the contrib/ directory with new sources from the development project. libxdg-basedir -------------- The libxdg-basedir project is a (really) small library used to provide the proper access to XDG directories as described by the XDG Base Directory Specification (0.6 version). The library can be found at https://n.ethz.ch/student/nevillm/download/libxdg-basedir/ , and it's imported in xine-lib as it's far from commonly found on distributions. xine-lib-1.2/contrib/Makefile.am0000644000175000017500000000067114647725151014363 0ustar memeSUBDIRS = \ a52dec \ gsm610 \ libdca \ libfaad \ libmad \ libmpcdec \ libxdg-basedir \ nosefart if BUILD_DHA_KMOD SUBDIRS += libdha endif # vidix depends on portions of dha if ENABLE_VIDIX if !BUILD_DHA_KMOD SUBDIRS += libdha endif SUBDIRS += vidix endif # Does anyone know what this is good for? # It just resolves full path, and triggers an automake warning... # srcdir = $(shell cd @srcdir@; pwd) EXTRA_DIST = README.contrib xine-lib-1.2/contrib/libfaad/0000755000175000017500000000000014647725152013706 5ustar memexine-lib-1.2/contrib/libfaad/output.h0000644000175000017500000000317314647725151015422 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: output.h,v 1.26 2009/01/26 23:51:15 menno Exp $ **/ #ifndef __OUTPUT_H__ #define __OUTPUT_H__ #ifdef __cplusplus extern "C" { #endif void* output_to_PCM(NeAACDecStruct *hDecoder, real_t **input, void *samplebuffer, uint8_t channels, uint16_t frame_len, uint8_t format); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/hcr.c0000644000175000017500000004055114647725151014632 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcr.c,v 1.26 2009/01/26 23:51:15 menno Exp $ **/ #include "common.h" #include "structs.h" #include #include #include "specrec.h" #include "huffman.h" /* ISO/IEC 14496-3/Amd.1 * 8.5.3.3: Huffman Codeword Reordering for AAC spectral data (HCR) * * HCR devides the spectral data in known fixed size segments, and * sorts it by the importance of the data. The importance is firstly * the (lower) position in the spectrum, and secondly the largest * value in the used codebook. * The most important data is written at the start of each segment * (at known positions), the remaining data is interleaved inbetween, * with the writing direction alternating. * Data length is not increased. */ #ifdef ERROR_RESILIENCE /* 8.5.3.3.1 Pre-sorting */ #define NUM_CB 6 #define NUM_CB_ER 22 #define MAX_CB 32 #define VCB11_FIRST 16 #define VCB11_LAST 31 static const uint8_t PreSortCB_STD[NUM_CB] = { 11, 9, 7, 5, 3, 1}; static const uint8_t PreSortCB_ER[NUM_CB_ER] = { 11, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 9, 7, 5, 3, 1}; /* 8.5.3.3.2 Derivation of segment width */ static const uint8_t maxCwLen[MAX_CB] = {0, 11, 9, 20, 16, 13, 11, 14, 12, 17, 14, 49, 0, 0, 0, 0, 14, 17, 21, 21, 25, 25, 29, 29, 29, 29, 33, 33, 33, 37, 37, 41}; #define segmentWidth(cb) min(maxCwLen[cb], ics->length_of_longest_codeword) /* bit-twiddling helpers */ static const uint8_t S[] = {1, 2, 4, 8, 16}; static const uint32_t B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF}; typedef struct { uint8_t cb; uint8_t decoded; uint16_t sp_offset; bits_t bits; } codeword_t; /* rewind and reverse */ /* 32 bit version */ static uint32_t rewrev_word(uint32_t v, const uint8_t len) { /* 32 bit reverse */ v = ((v >> S[0]) & B[0]) | ((v << S[0]) & ~B[0]); v = ((v >> S[1]) & B[1]) | ((v << S[1]) & ~B[1]); v = ((v >> S[2]) & B[2]) | ((v << S[2]) & ~B[2]); v = ((v >> S[3]) & B[3]) | ((v << S[3]) & ~B[3]); v = ((v >> S[4]) & B[4]) | ((v << S[4]) & ~B[4]); /* shift off low bits */ v >>= (32 - len); return v; } /* 64 bit version */ static void rewrev_lword(uint32_t *hi, uint32_t *lo, const uint8_t len) { if (len <= 32) { *hi = 0; *lo = rewrev_word(*lo, len); } else { uint32_t t = *hi, v = *lo; /* double 32 bit reverse */ v = ((v >> S[0]) & B[0]) | ((v << S[0]) & ~B[0]); t = ((t >> S[0]) & B[0]) | ((t << S[0]) & ~B[0]); v = ((v >> S[1]) & B[1]) | ((v << S[1]) & ~B[1]); t = ((t >> S[1]) & B[1]) | ((t << S[1]) & ~B[1]); v = ((v >> S[2]) & B[2]) | ((v << S[2]) & ~B[2]); t = ((t >> S[2]) & B[2]) | ((t << S[2]) & ~B[2]); v = ((v >> S[3]) & B[3]) | ((v << S[3]) & ~B[3]); t = ((t >> S[3]) & B[3]) | ((t << S[3]) & ~B[3]); v = ((v >> S[4]) & B[4]) | ((v << S[4]) & ~B[4]); t = ((t >> S[4]) & B[4]) | ((t << S[4]) & ~B[4]); /* last 32<>32 bit swap is implicit below */ /* shift off low bits (this is really only one 64 bit shift) */ *lo = (t >> (64 - len)) | (v << (len - 32)); *hi = v >> (64 - len); } } /* bits_t version */ static void rewrev_bits(bits_t *bits) { if (bits->len == 0) return; rewrev_lword(&bits->bufb, &bits->bufa, bits->len); } /* merge bits of a to b */ static void concat_bits(bits_t *b, bits_t *a) { uint32_t bl, bh, al, ah; if (a->len == 0) return; al = a->bufa; ah = a->bufb; if (b->len > 32) { /* maskoff superfluous high b bits */ bl = b->bufa; bh = b->bufb & ((1 << (b->len-32)) - 1); /* left shift a b->len bits */ ah = al << (b->len - 32); al = 0; } else { bl = b->bufa & ((1 << (b->len)) - 1); bh = 0; ah = (ah << (b->len)) | (al >> (32 - b->len)); al = al << b->len; } /* merge */ b->bufa = bl | al; b->bufb = bh | ah; b->len += a->len; } static uint8_t is_good_cb(uint8_t this_CB, uint8_t this_sec_CB) { /* only want spectral data CB's */ if ((this_sec_CB > ZERO_HCB && this_sec_CB <= ESC_HCB) || (this_sec_CB >= VCB11_FIRST && this_sec_CB <= VCB11_LAST)) { if (this_CB < ESC_HCB) { /* normal codebook pairs */ return ((this_sec_CB == this_CB) || (this_sec_CB == this_CB + 1)); } else { /* escape codebook */ return (this_sec_CB == this_CB); } } return 0; } static void read_segment(bits_t *segment, uint8_t segwidth, bitfile *ld) { segment->len = segwidth; if (segwidth > 32) { segment->bufb = faad_getbits(ld, segwidth - 32); segment->bufa = faad_getbits(ld, 32); } else { segment->bufa = faad_getbits(ld, segwidth); segment->bufb = 0; } } static void fill_in_codeword(codeword_t *codeword, uint16_t index, uint16_t sp, uint8_t cb) { codeword[index].sp_offset = sp; codeword[index].cb = cb; codeword[index].decoded = 0; codeword[index].bits.len = 0; } uint8_t reordered_spectral_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld, int16_t *spectral_data) { uint16_t PCWs_done; uint16_t numberOfSegments, numberOfSets, numberOfCodewords; codeword_t codeword[512]; bits_t segment[512]; uint16_t sp_offset[8]; uint16_t g, i, sortloop, set, bitsread; #ifdef HCR_CWCOUNT uint16_t bitsleft, codewordsleft; #endif uint8_t w_idx, sfb, this_CB, last_CB, this_sec_CB; const uint16_t nshort = hDecoder->frameLength/8; const uint16_t sp_data_len = ics->length_of_reordered_spectral_data; const uint8_t *PreSortCb; /* no data (e.g. silence) */ if (sp_data_len == 0) return 0; /* since there is spectral data, at least one codeword has nonzero length */ if (ics->length_of_longest_codeword == 0) return 10; if (sp_data_len < ics->length_of_longest_codeword) return 10; sp_offset[0] = 0; for (g = 1; g < ics->num_window_groups; g++) { sp_offset[g] = sp_offset[g-1] + nshort*ics->window_group_length[g-1]; } PCWs_done = 0; numberOfSegments = 0; numberOfCodewords = 0; bitsread = 0; /* VCB11 code books in use */ if (hDecoder->aacSectionDataResilienceFlag) { PreSortCb = PreSortCB_ER; last_CB = NUM_CB_ER; } else { PreSortCb = PreSortCB_STD; last_CB = NUM_CB; } /* step 1: decode PCW's (set 0), and stuff data in easier-to-use format */ for (sortloop = 0; sortloop < last_CB; sortloop++) { /* select codebook to process this pass */ this_CB = PreSortCb[sortloop]; /* loop over sfbs */ for (sfb = 0; sfb < ics->max_sfb; sfb++) { /* loop over all in this sfb, 4 lines per loop */ for (w_idx = 0; 4*w_idx < (min(ics->swb_offset[sfb+1], ics->swb_offset_max) - ics->swb_offset[sfb]); w_idx++) { for(g = 0; g < ics->num_window_groups; g++) { for (i = 0; i < ics->num_sec[g]; i++) { /* check whether sfb used here is the one we want to process */ if ((ics->sect_start[g][i] <= sfb) && (ics->sect_end[g][i] > sfb)) { /* check whether codebook used here is the one we want to process */ this_sec_CB = ics->sect_cb[g][i]; if (is_good_cb(this_CB, this_sec_CB)) { /* precalculate some stuff */ uint16_t sect_sfb_size = ics->sect_sfb_offset[g][sfb+1] - ics->sect_sfb_offset[g][sfb]; uint8_t inc = (this_sec_CB < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN; uint16_t group_cws_count = (4*ics->window_group_length[g])/inc; uint8_t segwidth = segmentWidth(this_sec_CB); uint16_t cws; /* read codewords until end of sfb or end of window group (shouldn't only 1 trigger?) */ for (cws = 0; (cws < group_cws_count) && ((cws + w_idx*group_cws_count) < sect_sfb_size); cws++) { uint16_t sp = sp_offset[g] + ics->sect_sfb_offset[g][sfb] + inc * (cws + w_idx*group_cws_count); /* read and decode PCW */ if (!PCWs_done) { /* read in normal segments */ if (bitsread + segwidth <= sp_data_len) { read_segment(&segment[numberOfSegments], segwidth, ld); bitsread += segwidth; huffman_spectral_data_2(this_sec_CB, &segment[numberOfSegments], &spectral_data[sp]); /* keep leftover bits */ rewrev_bits(&segment[numberOfSegments]); numberOfSegments++; } else { /* remaining stuff after last segment, we unfortunately couldn't read this in earlier because it might not fit in 64 bits. since we already decoded (and removed) the PCW it is now guaranteed to fit */ if (bitsread < sp_data_len) { const uint8_t additional_bits = sp_data_len - bitsread; read_segment(&segment[numberOfSegments], additional_bits, ld); segment[numberOfSegments].len += segment[numberOfSegments-1].len; rewrev_bits(&segment[numberOfSegments]); if (segment[numberOfSegments-1].len > 32) { segment[numberOfSegments-1].bufb = segment[numberOfSegments].bufb + showbits_hcr(&segment[numberOfSegments-1], segment[numberOfSegments-1].len - 32); segment[numberOfSegments-1].bufa = segment[numberOfSegments].bufa + showbits_hcr(&segment[numberOfSegments-1], 32); } else { segment[numberOfSegments-1].bufa = segment[numberOfSegments].bufa + showbits_hcr(&segment[numberOfSegments-1], segment[numberOfSegments-1].len); segment[numberOfSegments-1].bufb = segment[numberOfSegments].bufb; } segment[numberOfSegments-1].len += additional_bits; } bitsread = sp_data_len; PCWs_done = 1; fill_in_codeword(codeword, 0, sp, this_sec_CB); } } else { fill_in_codeword(codeword, numberOfCodewords - numberOfSegments, sp, this_sec_CB); } numberOfCodewords++; } } } } } } } } if (numberOfSegments == 0) return 10; numberOfSets = numberOfCodewords / numberOfSegments; /* step 2: decode nonPCWs */ for (set = 1; set <= numberOfSets; set++) { uint16_t trial; for (trial = 0; trial < numberOfSegments; trial++) { uint16_t codewordBase; for (codewordBase = 0; codewordBase < numberOfSegments; codewordBase++) { const uint16_t segment_idx = (trial + codewordBase) % numberOfSegments; const uint16_t codeword_idx = codewordBase + set*numberOfSegments - numberOfSegments; /* data up */ if (codeword_idx >= numberOfCodewords - numberOfSegments) break; if (!codeword[codeword_idx].decoded && segment[segment_idx].len > 0) { uint8_t tmplen; if (codeword[codeword_idx].bits.len != 0) concat_bits(&segment[segment_idx], &codeword[codeword_idx].bits); tmplen = segment[segment_idx].len; if (huffman_spectral_data_2(codeword[codeword_idx].cb, &segment[segment_idx], &spectral_data[codeword[codeword_idx].sp_offset]) >= 0) { codeword[codeword_idx].decoded = 1; } else { codeword[codeword_idx].bits = segment[segment_idx]; codeword[codeword_idx].bits.len = tmplen; } } } } for (i = 0; i < numberOfSegments; i++) rewrev_bits(&segment[i]); } #ifdef HCR_CWCOUNT // Seems to give false errors bitsleft = 0; for (i = 0; i < numberOfSegments && !bitsleft; i++) bitsleft += segment[i].len; if (bitsleft) return 10; codewordsleft = 0; for (i = 0; (i < numberOfCodewords - numberOfSegments) && (!codewordsleft); i++) if (!codeword[i].decoded) codewordsleft++; if (codewordsleft) return 10; #endif return 0; } #endif xine-lib-1.2/contrib/libfaad/is.h0000644000175000017500000000367414647725152014504 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: is.h,v 1.20 2007/11/01 12:33:31 menno Exp $ **/ #ifndef __IS_H__ #define __IS_H__ #ifdef __cplusplus extern "C" { #endif #include "syntax.h" void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec, uint16_t frame_len); static INLINE int8_t is_intensity(ic_stream *ics, uint8_t group, uint8_t sfb) { switch (ics->sfb_cb[group][sfb]) { case INTENSITY_HCB: return 1; case INTENSITY_HCB2: return -1; default: return 0; } } static INLINE int8_t invert_intensity(ic_stream *ics, uint8_t group, uint8_t sfb) { if (ics->ms_mask_present == 1) return (1-2*ics->ms_used[group][sfb]); return 1; } #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/analysis.h0000644000175000017500000000312714647725151015704 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: analysis.h,v 1.18 2007/11/01 12:33:29 menno Exp $ **/ #ifndef __ANALYSIS_H__ #define __ANALYSIS_H__ #ifdef __cplusplus extern "C" { #endif #ifdef ANALYSIS #define DEBUGDEC ,uint8_t print,uint16_t var,uint8_t *dbg #define DEBUGVAR(A,B,C) ,A,B,C extern uint16_t dbg_count; #else #define DEBUGDEC #define DEBUGVAR(A,B,C) #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/common.c0000644000175000017500000004131614647725152015347 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: common.c,v 1.27 2008/03/23 23:03:28 menno Exp $ **/ /* just some common functions that could be used anywhere */ #include "common.h" #include "structs.h" #include #include "syntax.h" /* Returns the sample rate index based on the samplerate */ uint8_t get_sr_index(const uint32_t samplerate) { if (92017 <= samplerate) return 0; if (75132 <= samplerate) return 1; if (55426 <= samplerate) return 2; if (46009 <= samplerate) return 3; if (37566 <= samplerate) return 4; if (27713 <= samplerate) return 5; if (23004 <= samplerate) return 6; if (18783 <= samplerate) return 7; if (13856 <= samplerate) return 8; if (11502 <= samplerate) return 9; if (9391 <= samplerate) return 10; if (16428320 <= samplerate) return 11; return 11; } /* Returns the sample rate based on the sample rate index */ uint32_t get_sample_rate(const uint8_t sr_index) { static const uint32_t sample_rates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000 }; if (sr_index < 12) return sample_rates[sr_index]; return 0; } uint8_t max_pred_sfb(const uint8_t sr_index) { static const uint8_t pred_sfb_max[] = { 33, 33, 38, 40, 40, 40, 41, 41, 37, 37, 37, 34 }; if (sr_index < 12) return pred_sfb_max[sr_index]; return 0; } uint8_t max_tns_sfb(const uint8_t sr_index, const uint8_t object_type, const uint8_t is_short) { /* entry for each sampling rate * 1 Main/LC long window * 2 Main/LC short window * 3 SSR long window * 4 SSR short window */ static const uint8_t tns_sbf_max[][4] = { {31, 9, 28, 7}, /* 96000 */ {31, 9, 28, 7}, /* 88200 */ {34, 10, 27, 7}, /* 64000 */ {40, 14, 26, 6}, /* 48000 */ {42, 14, 26, 6}, /* 44100 */ {51, 14, 26, 6}, /* 32000 */ {46, 14, 29, 7}, /* 24000 */ {46, 14, 29, 7}, /* 22050 */ {42, 14, 23, 8}, /* 16000 */ {42, 14, 23, 8}, /* 12000 */ {42, 14, 23, 8}, /* 11025 */ {39, 14, 19, 7}, /* 8000 */ {39, 14, 19, 7}, /* 7350 */ {0,0,0,0}, {0,0,0,0}, {0,0,0,0} }; uint8_t i = 0; if (is_short) i++; if (object_type == SSR) i += 2; return tns_sbf_max[sr_index][i]; } /* Returns 0 if an object type is decodable, otherwise returns -1 */ int8_t can_decode_ot(const uint8_t object_type) { switch (object_type) { case LC: return 0; case MAIN: #ifdef MAIN_DEC return 0; #else return -1; #endif case SSR: #ifdef SSR_DEC return 0; #else return -1; #endif case LTP: #ifdef LTP_DEC return 0; #else return -1; #endif /* ER object types */ #ifdef ERROR_RESILIENCE case ER_LC: #ifdef DRM case DRM_ER_LC: #endif return 0; case ER_LTP: #ifdef LTP_DEC return 0; #else return -1; #endif case LD: #ifdef LD_DEC return 0; #else return -1; #endif #endif } return -1; } void *faad_malloc(size_t size) { #if 0 // defined(_WIN32) && !defined(_WIN32_WCE) return _aligned_malloc(size, 16); #else // #ifdef 0 return malloc(size); #endif // #ifdef 0 } /* common free function */ void faad_free(void *b) { #if 0 // defined(_WIN32) && !defined(_WIN32_WCE) _aligned_free(b); #else free(b); } #endif static const uint8_t Parity [256] = { // parity 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0,1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1, 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 }; /* TJ. these are now part of NeAACDecHandle static uint32_t __r1 = 1; static uint32_t __r2 = 1; */ /* * This is a simple random number generator with good quality for audio purposes. * It consists of two polycounters with opposite rotation direction and different * periods. The periods are coprime, so the total period is the product of both. * * ------------------------------------------------------------------------------------------------- * +-> |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| * | ------------------------------------------------------------------------------------------------- * | | | | | | | * | +--+--+--+-XOR-+--------+ * | | * +--------------------------------------------------------------------------------------+ * * ------------------------------------------------------------------------------------------------- * |31:30:29:28:27:26:25:24:23:22:21:20:19:18:17:16:15:14:13:12:11:10: 9: 8: 7: 6: 5: 4: 3: 2: 1: 0| <-+ * ------------------------------------------------------------------------------------------------- | * | | | | | * +--+----XOR----+--+ | * | | * +----------------------------------------------------------------------------------------+ * * * The first has an period of 3*5*17*257*65537, the second of 7*47*73*178481, * which gives a period of 18.410.713.077.675.721.215. The result is the * XORed values of both generators. */ uint32_t ne_rng(uint32_t *__r1, uint32_t *__r2) { uint32_t t1, t2, t3, t4; t3 = t1 = *__r1; t4 = t2 = *__r2; // Parity calculation is done via table lookup, this is also available t1 &= 0xF5; t2 >>= 25; // on CPUs without parity, can be implemented in C and avoid unpredictable t1 = Parity [t1]; t2 &= 0x63; // jumps and slow rotate through the carry flag operations. t1 <<= 31; t2 = Parity [t2]; return (*__r1 = (t3 >> 1) | t1 ) ^ (*__r2 = (t4 + t4) | t2 ); } static uint32_t ones32(uint32_t x) { x -= ((x >> 1) & 0x55555555); x = (((x >> 2) & 0x33333333) + (x & 0x33333333)); x = (((x >> 4) + x) & 0x0f0f0f0f); x += (x >> 8); x += (x >> 16); return (x & 0x0000003f); } #ifdef FIXED_POINT static uint32_t floor_log2(uint32_t x) { #if 1 x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return (ones32(x) - 1); #else uint32_t count = 0; while (x >>= 1) count++; return count; #endif } #endif /* returns position of first bit that is not 0 from msb, * starting count at lsb */ uint32_t wl_min_lzc(uint32_t x) { #if 1 x |= (x >> 1); x |= (x >> 2); x |= (x >> 4); x |= (x >> 8); x |= (x >> 16); return (ones32(x)); #else uint32_t count = 0; while (x >>= 1) count++; return (count + 1); #endif } #ifdef FIXED_POINT #define TABLE_BITS 6 /* just take the maximum number of bits for interpolation */ #define INTERP_BITS (REAL_BITS-TABLE_BITS) static const real_t pow2_tab[] = { REAL_CONST(1.000000000000000), REAL_CONST(1.010889286051701), REAL_CONST(1.021897148654117), REAL_CONST(1.033024879021228), REAL_CONST(1.044273782427414), REAL_CONST(1.055645178360557), REAL_CONST(1.067140400676824), REAL_CONST(1.078760797757120), REAL_CONST(1.090507732665258), REAL_CONST(1.102382583307841), REAL_CONST(1.114386742595892), REAL_CONST(1.126521618608242), REAL_CONST(1.138788634756692), REAL_CONST(1.151189229952983), REAL_CONST(1.163724858777578), REAL_CONST(1.176396991650281), REAL_CONST(1.189207115002721), REAL_CONST(1.202156731452703), REAL_CONST(1.215247359980469), REAL_CONST(1.228480536106870), REAL_CONST(1.241857812073484), REAL_CONST(1.255380757024691), REAL_CONST(1.269050957191733), REAL_CONST(1.282870016078778), REAL_CONST(1.296839554651010), REAL_CONST(1.310961211524764), REAL_CONST(1.325236643159741), REAL_CONST(1.339667524053303), REAL_CONST(1.354255546936893), REAL_CONST(1.369002422974591), REAL_CONST(1.383909881963832), REAL_CONST(1.398979672538311), REAL_CONST(1.414213562373095), REAL_CONST(1.429613338391970), REAL_CONST(1.445180806977047), REAL_CONST(1.460917794180647), REAL_CONST(1.476826145939499), REAL_CONST(1.492907728291265), REAL_CONST(1.509164427593423), REAL_CONST(1.525598150744538), REAL_CONST(1.542210825407941), REAL_CONST(1.559004400237837), REAL_CONST(1.575980845107887), REAL_CONST(1.593142151342267), REAL_CONST(1.610490331949254), REAL_CONST(1.628027421857348), REAL_CONST(1.645755478153965), REAL_CONST(1.663676580326736), REAL_CONST(1.681792830507429), REAL_CONST(1.700106353718524), REAL_CONST(1.718619298122478), REAL_CONST(1.737333835273706), REAL_CONST(1.756252160373300), REAL_CONST(1.775376492526521), REAL_CONST(1.794709075003107), REAL_CONST(1.814252175500399), REAL_CONST(1.834008086409342), REAL_CONST(1.853979125083386), REAL_CONST(1.874167634110300), REAL_CONST(1.894575981586966), REAL_CONST(1.915206561397147), REAL_CONST(1.936061793492294), REAL_CONST(1.957144124175400), REAL_CONST(1.978456026387951), REAL_CONST(2.000000000000000) }; static const real_t log2_tab[] = { REAL_CONST(0.000000000000000), REAL_CONST(0.022367813028455), REAL_CONST(0.044394119358453), REAL_CONST(0.066089190457772), REAL_CONST(0.087462841250339), REAL_CONST(0.108524456778169), REAL_CONST(0.129283016944966), REAL_CONST(0.149747119504682), REAL_CONST(0.169925001442312), REAL_CONST(0.189824558880017), REAL_CONST(0.209453365628950), REAL_CONST(0.228818690495881), REAL_CONST(0.247927513443585), REAL_CONST(0.266786540694901), REAL_CONST(0.285402218862248), REAL_CONST(0.303780748177103), REAL_CONST(0.321928094887362), REAL_CONST(0.339850002884625), REAL_CONST(0.357552004618084), REAL_CONST(0.375039431346925), REAL_CONST(0.392317422778760), REAL_CONST(0.409390936137702), REAL_CONST(0.426264754702098), REAL_CONST(0.442943495848728), REAL_CONST(0.459431618637297), REAL_CONST(0.475733430966398), REAL_CONST(0.491853096329675), REAL_CONST(0.507794640198696), REAL_CONST(0.523561956057013), REAL_CONST(0.539158811108031), REAL_CONST(0.554588851677637), REAL_CONST(0.569855608330948), REAL_CONST(0.584962500721156), REAL_CONST(0.599912842187128), REAL_CONST(0.614709844115208), REAL_CONST(0.629356620079610), REAL_CONST(0.643856189774725), REAL_CONST(0.658211482751795), REAL_CONST(0.672425341971496), REAL_CONST(0.686500527183218), REAL_CONST(0.700439718141092), REAL_CONST(0.714245517666123), REAL_CONST(0.727920454563199), REAL_CONST(0.741466986401147), REAL_CONST(0.754887502163469), REAL_CONST(0.768184324776926), REAL_CONST(0.781359713524660), REAL_CONST(0.794415866350106), REAL_CONST(0.807354922057604), REAL_CONST(0.820178962415188), REAL_CONST(0.832890014164742), REAL_CONST(0.845490050944375), REAL_CONST(0.857980995127572), REAL_CONST(0.870364719583405), REAL_CONST(0.882643049361841), REAL_CONST(0.894817763307943), REAL_CONST(0.906890595608519), REAL_CONST(0.918863237274595), REAL_CONST(0.930737337562886), REAL_CONST(0.942514505339240), REAL_CONST(0.954196310386875), REAL_CONST(0.965784284662087), REAL_CONST(0.977279923499917), REAL_CONST(0.988684686772166), REAL_CONST(1.000000000000000) }; real_t pow2_fix(real_t val) { uint32_t x1, x2; uint32_t errcorr; uint32_t index_frac; real_t retval; int32_t whole = (val >> REAL_BITS); /* rest = [0..1] */ int32_t rest = val - (whole << REAL_BITS); /* index into pow2_tab */ int32_t index = rest >> (REAL_BITS-TABLE_BITS); if (val == 0) return (1<> (REAL_BITS-TABLE_BITS-INTERP_BITS); index_frac = index_frac & ((1< 0) { retval = 1 << whole; } else { retval = REAL_CONST(1) >> -whole; } x1 = pow2_tab[index & ((1<> INTERP_BITS; if (whole > 0) { retval = retval * (errcorr + x1); } else { retval = MUL_R(retval, (errcorr + x1)); } return retval; } int32_t pow2_int(real_t val) { uint32_t x1, x2; uint32_t errcorr; uint32_t index_frac; real_t retval; int32_t whole = (val >> REAL_BITS); /* rest = [0..1] */ int32_t rest = val - (whole << REAL_BITS); /* index into pow2_tab */ int32_t index = rest >> (REAL_BITS-TABLE_BITS); if (val == 0) return 1; /* leave INTERP_BITS bits */ index_frac = rest >> (REAL_BITS-TABLE_BITS-INTERP_BITS); index_frac = index_frac & ((1< 0) retval = 1 << whole; else retval = 0; x1 = pow2_tab[index & ((1<> INTERP_BITS; retval = MUL_R(retval, (errcorr + x1)); return retval; } /* ld(x) = ld(x*y/y) = ld(x/y) + ld(y), with y=2^N and [1 <= (x/y) < 2] */ int32_t log2_int(uint32_t val) { uint32_t frac; uint32_t whole = (val); int32_t exp = 0; uint32_t index; uint32_t index_frac; uint32_t x1, x2; uint32_t errcorr; /* error */ if (val == 0) return -10000; exp = floor_log2(val); exp -= REAL_BITS; /* frac = [1..2] */ if (exp >= 0) frac = val >> exp; else frac = val << -exp; /* index in the log2 table */ index = frac >> (REAL_BITS-TABLE_BITS); /* leftover part for linear interpolation */ index_frac = frac & ((1<<(REAL_BITS-TABLE_BITS))-1); /* leave INTERP_BITS bits */ index_frac = index_frac >> (REAL_BITS-TABLE_BITS-INTERP_BITS); x1 = log2_tab[index & ((1<> INTERP_BITS; return ((exp+REAL_BITS) << REAL_BITS) + errcorr + x1; } /* ld(x) = ld(x*y/y) = ld(x/y) + ld(y), with y=2^N and [1 <= (x/y) < 2] */ real_t log2_fix(uint32_t val) { uint32_t frac; uint32_t whole = (val >> REAL_BITS); int8_t exp = 0; uint32_t index; uint32_t index_frac; uint32_t x1, x2; uint32_t errcorr; /* error */ if (val == 0) return -100000; exp = floor_log2(val); exp -= REAL_BITS; /* frac = [1..2] */ if (exp >= 0) frac = val >> exp; else frac = val << -exp; /* index in the log2 table */ index = frac >> (REAL_BITS-TABLE_BITS); /* leftover part for linear interpolation */ index_frac = frac & ((1<<(REAL_BITS-TABLE_BITS))-1); /* leave INTERP_BITS bits */ index_frac = index_frac >> (REAL_BITS-TABLE_BITS-INTERP_BITS); x1 = log2_tab[index & ((1<> INTERP_BITS; return (exp << REAL_BITS) + errcorr + x1; } #endif xine-lib-1.2/contrib/libfaad/tns.h0000644000175000017500000000332014647725152014661 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: tns.h,v 1.23 2007/11/01 12:33:41 menno Exp $ **/ #ifndef __TNS_H__ #define __TNS_H__ #ifdef __cplusplus extern "C" { #endif #define TNS_MAX_ORDER 20 void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, uint8_t object_type, real_t *spec, uint16_t frame_len); void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, uint8_t object_type, real_t *spec, uint16_t frame_len); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/common.h0000644000175000017500000002122714647725152015353 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: common.h,v 1.77 2009/02/05 00:51:03 menno Exp $ **/ #ifndef __COMMON_H__ #define __COMMON_H__ #ifdef __cplusplus extern "C" { #endif #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "neaacdec.h" #if 1 #define INLINE __inline #else #define INLINE inline #endif #if 0 //defined(_WIN32) && !defined(_WIN32_WCE) #define ALIGN __declspec(align(16)) #else #define ALIGN #endif #ifndef max #define max(a, b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a, b) (((a) < (b)) ? (a) : (b)) #endif /* COMPILE TIME DEFINITIONS */ /* use double precision */ /* #define USE_DOUBLE_PRECISION */ /* use fixed point reals */ //#define FIXED_POINT //#define BIG_IQ_TABLE /* Use if target platform has address generators with autoincrement */ //#define PREFER_POINTERS #ifdef _WIN32_WCE #define FIXED_POINT #endif #ifdef __BFIN__ #define FIXED_POINT #endif #define ERROR_RESILIENCE /* Allow decoding of MAIN profile AAC */ #define MAIN_DEC /* Allow decoding of SSR profile AAC */ //#define SSR_DEC /* Allow decoding of LTP profile AAC */ #define LTP_DEC /* Allow decoding of LD profile AAC */ #define LD_DEC /* Allow decoding of Digital Radio Mondiale (DRM) */ //#define DRM //#define DRM_PS /* LD can't do without LTP */ #ifdef LD_DEC #ifndef ERROR_RESILIENCE #define ERROR_RESILIENCE #endif #ifndef LTP_DEC #define LTP_DEC #endif #endif #define ALLOW_SMALL_FRAMELENGTH // Define LC_ONLY_DECODER if you want a pure AAC LC decoder (independant of SBR_DEC and PS_DEC) //#define LC_ONLY_DECODER #ifdef LC_ONLY_DECODER #undef LD_DEC #undef LTP_DEC #undef MAIN_DEC #undef SSR_DEC #undef DRM #undef ALLOW_SMALL_FRAMELENGTH #undef ERROR_RESILIENCE #endif #define SBR_DEC //#define SBR_LOW_POWER #define PS_DEC #ifdef SBR_LOW_POWER #undef PS_DEC #endif /* FIXED POINT: No MAIN decoding */ #ifdef FIXED_POINT # ifdef MAIN_DEC # undef MAIN_DEC # endif #endif // FIXED_POINT #ifdef DRM # ifndef ALLOW_SMALL_FRAMELENGTH # define ALLOW_SMALL_FRAMELENGTH # endif # undef LD_DEC # undef LTP_DEC # undef MAIN_DEC # undef SSR_DEC #endif #ifdef FIXED_POINT #define DIV_R(A, B) (((int64_t)A << REAL_BITS)/B) #define DIV_C(A, B) (((int64_t)A << COEF_BITS)/B) #else #define DIV_R(A, B) ((A)/(B)) #define DIV_C(A, B) ((A)/(B)) #endif #ifndef SBR_LOW_POWER #define qmf_t complex_t #define QMF_RE(A) RE(A) #define QMF_IM(A) IM(A) #else #define qmf_t real_t #define QMF_RE(A) (A) #define QMF_IM(A) #endif /* END COMPILE TIME DEFINITIONS */ #if defined(_WIN32) && !defined(__MINGW32__) #include typedef unsigned __int64 uint64_t; typedef unsigned __int32 uint32_t; typedef unsigned __int16 uint16_t; typedef unsigned __int8 uint8_t; typedef signed __int64 int64_t; typedef signed __int32 int32_t; typedef signed __int16 int16_t; typedef signed __int8 int8_t; typedef float float32_t; #else #include #if HAVE_SYS_TYPES_H # include #endif #if HAVE_SYS_STAT_H # include #endif #include #include #include #if HAVE_STRINGS_H # include #endif #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # else /* we need these... */ #ifndef __TCS__ typedef unsigned long long uint64_t; typedef signed long long int64_t; #else typedef unsigned long uint64_t; typedef signed long int64_t; #endif typedef unsigned long uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; typedef signed long int32_t; typedef signed short int16_t; typedef signed char int8_t; # endif #endif #if HAVE_UNISTD_H //# include #endif #ifndef HAVE_FLOAT32_T typedef float float32_t; #endif #include #endif #ifdef WORDS_BIGENDIAN #define ARCH_IS_BIG_ENDIAN #endif /* FIXED_POINT doesn't work with MAIN and SSR yet */ #ifdef FIXED_POINT #undef MAIN_DEC #undef SSR_DEC #endif #if defined(FIXED_POINT) #include "fixed.h" #elif defined(USE_DOUBLE_PRECISION) typedef double real_t; #include #define MUL_R(A,B) ((A)*(B)) #define MUL_C(A,B) ((A)*(B)) #define MUL_F(A,B) ((A)*(B)) /* Complex multiplication */ static INLINE void ComplexMult(real_t *y1, real_t *y2, real_t x1, real_t x2, real_t c1, real_t c2) { *y1 = MUL_F(x1, c1) + MUL_F(x2, c2); *y2 = MUL_F(x2, c1) - MUL_F(x1, c2); } #define REAL_CONST(A) ((real_t)(A)) #define COEF_CONST(A) ((real_t)(A)) #define Q2_CONST(A) ((real_t)(A)) #define FRAC_CONST(A) ((real_t)(A)) /* pure fractional part */ #else /* Normal floating point operation */ typedef float real_t; #define MUL_R(A,B) ((A)*(B)) #define MUL_C(A,B) ((A)*(B)) #define MUL_F(A,B) ((A)*(B)) #define REAL_CONST(A) ((real_t)(A)) #define COEF_CONST(A) ((real_t)(A)) #define Q2_CONST(A) ((real_t)(A)) #define FRAC_CONST(A) ((real_t)(A)) /* pure fractional part */ /* Complex multiplication */ static INLINE void ComplexMult(real_t *y1, real_t *y2, real_t x1, real_t x2, real_t c1, real_t c2) { *y1 = MUL_F(x1, c1) + MUL_F(x2, c2); *y2 = MUL_F(x2, c1) - MUL_F(x1, c2); } #if defined(_WIN32) && !defined(__MINGW32__) #define HAS_LRINTF static INLINE int lrintf(float f) { int i; __asm { fld f fistp i } return i; } #elif (defined(__i386__) && defined(__GNUC__) && \ !defined(__CYGWIN__) && !defined(__MINGW32__)) #ifndef HAVE_LRINTF #define HAS_LRINTF // from http://www.stereopsis.com/FPU.html static INLINE int lrintf(float f) { int i; __asm__ __volatile__ ( "flds %1 \n\t" "fistpl %0 \n\t" : "=m" (i) : "m" (f)); return i; } #endif /* HAVE_LRINTF */ #endif #ifdef __ICL /* only Intel C compiler has fmath ??? */ #include #define sin sinf #define cos cosf #define log logf #define floor floorf #define ceil ceilf #define sqrt sqrtf #else #ifdef HAVE_LRINTF # define HAS_LRINTF # define _ISOC9X_SOURCE 1 # define _ISOC99_SOURCE 1 # define __USE_ISOC9X 1 # define __USE_ISOC99 1 #endif #include #ifdef HAVE_SINF # define sin sinf #error #endif #ifdef HAVE_COSF # define cos cosf #endif #ifdef HAVE_LOGF # define log logf #endif #ifdef HAVE_EXPF # define exp expf #endif #ifdef HAVE_FLOORF # define floor floorf #endif #ifdef HAVE_CEILF # define ceil ceilf #endif #ifdef HAVE_SQRTF # define sqrt sqrtf #endif #endif #endif #ifndef HAS_LRINTF /* standard cast */ #define lrintf(f) ((int32_t)(f)) #endif typedef real_t complex_t[2]; #define RE(A) A[0] #define IM(A) A[1] /* common functions */ uint8_t cpu_has_sse(void); uint32_t ne_rng(uint32_t *__r1, uint32_t *__r2); uint32_t wl_min_lzc(uint32_t x); #ifdef FIXED_POINT #define LOG2_MIN_INF REAL_CONST(-10000) int32_t log2_int(uint32_t val); int32_t log2_fix(uint32_t val); int32_t pow2_int(real_t val); real_t pow2_fix(real_t val); #endif uint8_t get_sr_index(const uint32_t samplerate); uint8_t max_pred_sfb(const uint8_t sr_index); uint8_t max_tns_sfb(const uint8_t sr_index, const uint8_t object_type, const uint8_t is_short); uint32_t get_sample_rate(const uint8_t sr_index); int8_t can_decode_ot(const uint8_t object_type); void *faad_malloc(size_t size); void faad_free(void *b); //#define PROFILE #ifdef PROFILE static int64_t faad_get_ts() { __asm { rdtsc } } #endif #ifndef M_PI #define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 /* PI/2 */ #define M_PI_2 1.57079632679489661923 #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/error.c0000644000175000017500000000541714647725152015212 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: error.c,v 1.33 2008/09/19 23:31:39 menno Exp $ **/ #include "common.h" #include "error.h" const char *err_msg[] = { "No error", "Gain control not yet implemented", "Pulse coding not allowed in short blocks", "Invalid huffman codebook", "Scalefactor out of range", "Unable to find ADTS syncword", "Channel coupling not yet implemented", "Channel configuration not allowed in error resilient frame", "Bit error in error resilient scalefactor decoding", "Error decoding huffman scalefactor (bitstream error)", "Error decoding huffman codeword (bitstream error)", "Non existent huffman codebook number found", "Invalid number of channels", "Maximum number of bitstream elements exceeded", "Input data buffer too small", "Array index out of range", "Maximum number of scalefactor bands exceeded", "Quantised value out of range", "LTP lag out of range", "Invalid SBR parameter decoded", "SBR called without being initialised", "Unexpected channel configuration change", "Error in program_config_element", "First SBR frame is not the same as first AAC frame", "Unexpected fill element with SBR data", "Not all elements were provided with SBR data", "LTP decoding not available", "Output data buffer too small", "CRC error in DRM data", "PNS not allowed in DRM data stream", "No standard extension payload allowed in DRM", "PCE shall be the first element in a frame", "Bitstream value not allowed by specification", "MAIN prediction not initialised" }; xine-lib-1.2/contrib/libfaad/sbr_tf_grid.c0000644000175000017500000001473014647725152016343 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_tf_grid.c,v 1.20 2008/09/19 22:50:20 menno Exp $ **/ /* Time/Frequency grid */ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include #include "sbr_syntax.h" #include "sbr_tf_grid.h" /* static function declarations */ #if 0 static int16_t rel_bord_lead(sbr_info *sbr, uint8_t ch, uint8_t l); static int16_t rel_bord_trail(sbr_info *sbr, uint8_t ch, uint8_t l); #endif static uint8_t middleBorder(sbr_info *sbr, uint8_t ch); /* function constructs new time border vector */ /* first build into temp vector to be able to use previous vector on error */ uint8_t envelope_time_border_vector(sbr_info *sbr, uint8_t ch) { uint8_t l, border, temp; uint8_t t_E_temp[6] = {0}; t_E_temp[0] = sbr->rate * sbr->abs_bord_lead[ch]; t_E_temp[sbr->L_E[ch]] = sbr->rate * sbr->abs_bord_trail[ch]; switch (sbr->bs_frame_class[ch]) { case FIXFIX: switch (sbr->L_E[ch]) { case 4: temp = (sbr->numTimeSlots / 4); t_E_temp[3] = sbr->rate * 3 * temp; t_E_temp[2] = sbr->rate * 2 * temp; t_E_temp[1] = sbr->rate * temp; break; case 2: t_E_temp[1] = sbr->rate * (sbr->numTimeSlots / 2); break; default: break; } break; case FIXVAR: if (sbr->L_E[ch] > 1) { int8_t i = sbr->L_E[ch]; border = sbr->abs_bord_trail[ch]; for (l = 0; l < (sbr->L_E[ch] - 1); l++) { if (border < sbr->bs_rel_bord[ch][l]) return 1; border -= sbr->bs_rel_bord[ch][l]; t_E_temp[--i] = sbr->rate * border; } } break; case VARFIX: if (sbr->L_E[ch] > 1) { int8_t i = 1; border = sbr->abs_bord_lead[ch]; for (l = 0; l < (sbr->L_E[ch] - 1); l++) { border += sbr->bs_rel_bord[ch][l]; if (sbr->rate * border + sbr->tHFAdj > sbr->numTimeSlotsRate+sbr->tHFGen) return 1; t_E_temp[i++] = sbr->rate * border; } } break; case VARVAR: if (sbr->bs_num_rel_0[ch]) { int8_t i = 1; border = sbr->abs_bord_lead[ch]; for (l = 0; l < sbr->bs_num_rel_0[ch]; l++) { border += sbr->bs_rel_bord_0[ch][l]; if (sbr->rate * border + sbr->tHFAdj > sbr->numTimeSlotsRate+sbr->tHFGen) return 1; t_E_temp[i++] = sbr->rate * border; } } if (sbr->bs_num_rel_1[ch]) { int8_t i = sbr->L_E[ch]; border = sbr->abs_bord_trail[ch]; for (l = 0; l < sbr->bs_num_rel_1[ch]; l++) { if (border < sbr->bs_rel_bord_1[ch][l]) return 1; border -= sbr->bs_rel_bord_1[ch][l]; t_E_temp[--i] = sbr->rate * border; } } break; } /* no error occured, we can safely use this t_E vector */ for (l = 0; l < 6; l++) { sbr->t_E[ch][l] = t_E_temp[l]; } return 0; } void noise_floor_time_border_vector(sbr_info *sbr, uint8_t ch) { sbr->t_Q[ch][0] = sbr->t_E[ch][0]; if (sbr->L_E[ch] == 1) { sbr->t_Q[ch][1] = sbr->t_E[ch][1]; sbr->t_Q[ch][2] = 0; } else { uint8_t index = middleBorder(sbr, ch); sbr->t_Q[ch][1] = sbr->t_E[ch][index]; sbr->t_Q[ch][2] = sbr->t_E[ch][sbr->L_E[ch]]; } } #if 0 static int16_t rel_bord_lead(sbr_info *sbr, uint8_t ch, uint8_t l) { uint8_t i; int16_t acc = 0; switch (sbr->bs_frame_class[ch]) { case FIXFIX: return sbr->numTimeSlots/sbr->L_E[ch]; case FIXVAR: return 0; case VARFIX: for (i = 0; i < l; i++) { acc += sbr->bs_rel_bord[ch][i]; } return acc; case VARVAR: for (i = 0; i < l; i++) { acc += sbr->bs_rel_bord_0[ch][i]; } return acc; } return 0; } static int16_t rel_bord_trail(sbr_info *sbr, uint8_t ch, uint8_t l) { uint8_t i; int16_t acc = 0; switch (sbr->bs_frame_class[ch]) { case FIXFIX: case VARFIX: return 0; case FIXVAR: for (i = 0; i < l; i++) { acc += sbr->bs_rel_bord[ch][i]; } return acc; case VARVAR: for (i = 0; i < l; i++) { acc += sbr->bs_rel_bord_1[ch][i]; } return acc; } return 0; } #endif static uint8_t middleBorder(sbr_info *sbr, uint8_t ch) { int8_t retval = 0; switch (sbr->bs_frame_class[ch]) { case FIXFIX: retval = sbr->L_E[ch]/2; break; case VARFIX: if (sbr->bs_pointer[ch] == 0) retval = 1; else if (sbr->bs_pointer[ch] == 1) retval = sbr->L_E[ch] - 1; else retval = sbr->bs_pointer[ch] - 1; break; case FIXVAR: case VARVAR: if (sbr->bs_pointer[ch] > 1) retval = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch]; else retval = sbr->L_E[ch] - 1; break; } return (retval > 0) ? retval : 0; } #endif xine-lib-1.2/contrib/libfaad/iq_table.h0000644000175000017500000200011714647725152015640 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: iq_table.h,v 1.20 2007/11/01 12:33:31 menno Exp $ **/ #ifndef IQ_TABLE_H__ #define IQ_TABLE_H__ #ifdef __cplusplus extern "C" { #endif /* !!!DON'T CHANGE IQ_TABLE_SIZE!!! */ #ifndef FIXED_POINT #define IQ_TABLE_SIZE 8192 #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif ALIGN static const real_t iq_table[IQ_TABLE_SIZE] = { 0, 1, 2.5198420997897464, 4.3267487109222245, 6.3496042078727974, 8.5498797333834844, 10.902723556992836, 13.390518279406722, 15.999999999999998, 18.720754407467133, 21.544346900318832, 24.463780996262464, 27.47314182127996, 30.567350940369842, 33.741991698453212, 36.993181114957046, 40.317473596635935, 43.711787041189993, 47.173345095760126, 50.699631325716943, 54.288352331898118, 57.937407704003519, 61.6448652744185, 65.408940536585988, 69.227979374755591, 73.100443455321638, 77.024897778591622, 80.999999999999986, 85.024491212518527, 89.097187944889555, 93.216975178615741, 97.382800224133163, 101.59366732596474, 105.84863288986224, 110.14680124343441, 114.4873208566006, 118.86938096020653, 123.29220851090024, 127.75506545836058, 132.25724627755247, 136.79807573413572, 141.37690685569191, 145.99311908523086, 150.6461165966291, 155.33532675434674, 160.06019870205279, 164.82020206673349, 169.61482576651861, 174.44357691188537, 179.30597979112557, 184.20157493201927, 189.12991823257562, 194.09058015449685, 199.08314497371677, 204.1072100829694, 209.16238534187647, 214.24829247050752, 219.36456448277784, 224.51084515641216, 229.6867885365223, 234.89205847013176, 240.12632816923249, 245.38927980018505, 250.68060409747261, 255.99999999999991, 261.34717430828869, 266.72184136106449, 272.12372272986045, 277.55254693037961, 283.0080491494619, 288.48997098659891, 293.99806020902247, 299.53207051947408, 305.0917613358298, 310.67689758182206, 316.28724948815585, 321.92259240337177, 327.58270661385535, 333.26737717243742, 338.97639373507025, 344.70955040510125, 350.46664558470013, 356.24748183302603, 362.05186573075139, 367.87960775058258, 373.73052213344511, 379.60442677002078, 385.50114308734607, 391.42049594019937, 397.36231350702371, 403.32642719014467, 409.31267152006262, 415.32088406360799, 421.35090533576471, 427.40257871497619, 433.4757503617617, 439.5702691404793, 445.68598654408271, 451.82275662172759, 457.98043590909128, 464.15888336127773, 470.35796028818726, 476.5775302922363, 482.81745920832043, 489.07761504591741, 495.35786793323581, 501.65809006331688, 507.97815564200368, 514.31794083769648, 520.67732373281672, 527.05618427690604, 533.45440424129174, 539.87186717525128, 546.30845836361505, 552.76406478574609, 559.23857507584194, 565.73187948450413, 572.24386984152341, 578.77443951983378, 585.32348340058843, 591.89089783931263, 598.47658063309257, 605.08043098876044, 611.70234949203643, 618.3422380775919, 624.99999999999977, 631.67553980553748, 638.36876330481164, 645.07957754617485, 651.80789078990415, 658.55361248311499, 665.31665323538357, 672.09692479505225, 678.8943400261943, 685.70881288621433, 692.540258404062, 699.38859265903977, 706.25373276018058, 713.13559682617972, 720.03410396586037, 726.94917425915435, 733.88072873858209, 740.82868937121543, 747.79297904110535, 754.77352153216191, 761.77024151147043, 768.78306451302956, 775.81191692189896, 782.85672595874246, 789.91741966475445, 796.99392688695798, 804.08617726386274, 811.19410121147098, 818.31762990962227, 825.45669528866563, 832.61123001644864, 839.78116748561604, 846.96644180120552, 854.16698776853514, 861.38274088137143, 868.61363731036977, 875.85961389178203, 883.12060811641959, 890.39655811886757, 897.68740266694181, 904.99308115138172, 912.31353357577188, 919.64870054668756, 926.99852326405619, 934.36294351172899, 941.74190364825859, 949.13534659787422, 956.54321584165211, 963.96545540887348, 971.40200986856541, 978.85282432122176, 986.31784439069588, 993.7970162162635, 1001.29028644485, 1008.797602223418, 1016.3189111915103, 1023.8541614739464, 1031.4033016736653, 1038.9662808647138, 1046.5430485853758, 1054.1335548314366, 1061.7377500495838, 1069.3555851309357, 1076.9870114046978, 1084.6319806319441, 1092.2904449995174, 1099.9623571140482, 1107.6476699960892, 1115.3463370743607, 1123.058312180106, 1130.7835495415541, 1138.5220037784854, 1146.273629896901, 1154.0383832837879, 1161.816219701986, 1169.607095285146, 1177.4109665327808, 1185.2277903054078, 1193.0575238197798, 1200.9001246442001, 1208.7555506939248, 1216.6237602266442, 1224.5047118380478, 1232.3983644574657, 1240.3046773435874, 1248.2236100802568, 1256.1551225723395, 1264.099175041662, 1272.0557280230228, 1280.0247423602691, 1288.0061792024444, 1295.9999999999995, 1304.006166501068, 1312.0246407478062, 1320.0553850727929, 1328.0983620954903, 1336.1535347187651, 1344.2208661254647, 1352.3003197750522, 1360.3918594002962, 1368.4954490040145, 1376.6110528558709, 1384.7386354892244, 1392.8781616980295, 1401.0295965337855, 1409.1929053025353, 1417.3680535619119, 1425.5550071182327, 1433.7537320236374, 1441.9641945732744, 1450.1863613025282, 1458.4201989842913, 1466.6656746262797, 1474.9227554683875, 1483.1914089800841, 1491.4716028578516, 1499.7633050226596, 1508.0664836174794, 1516.3811070048375, 1524.7071437644029, 1533.0445626906128, 1541.3933327903342, 1549.7534232805581, 1558.1248035861302, 1566.507443337515, 1574.9013123685909, 1583.3063807144795, 1591.7226186094069, 1600.1499964845941, 1608.58848496618, 1617.0380548731737, 1625.4986772154357, 1633.9703231916887, 1642.4529641875577, 1650.9465717736346, 1659.4511177035752, 1667.9665739122186, 1676.4929125137353, 1685.030105799801, 1693.5781262377957, 1702.136946469027, 1710.7065393069795, 1719.2868777355877, 1727.8779349075323, 1736.4796841425596, 1745.092098925825, 1753.7151529062583, 1762.3488198949503, 1770.9930738635628, 1779.6478889427597, 1788.3132394206564, 1796.9890997412947, 1805.6754445031333, 1814.3722484575621, 1823.0794865074322, 1831.7971337056094, 1840.5251652535437, 1849.2635564998579, 1858.0122829389563, 1866.7713202096493, 1875.5406440937966, 1884.3202305149687, 1893.110055537124, 1901.9100953633042, 1910.7203263343454, 1919.5407249276057, 1928.3712677557098, 1937.2119315653083, 1946.0626932358525, 1954.923529778386, 1963.79441833435, 1972.6753361744036, 1981.5662606972594, 1990.467169428533, 1999.3780400196069, 2008.2988502465078, 2017.2295780087982, 2026.1702013284819, 2035.1206983489212, 2044.0810473337688, 2053.0512266659125, 2062.0312148464309, 2071.0209904935646, 2080.0205323416958, 2089.0298192403443, 2098.0488301531714, 2107.0775441569995, 2116.115940440839, 2125.1639983049317, 2134.2216971597995, 2143.2890165253098, 2152.3659360297484, 2161.4524354089031, 2170.5484945051617, 2179.6540932666144, 2188.7692117461711, 2197.8938301006888, 2207.0279285901042, 2216.1714875765838, 2225.324487523676, 2234.4869089954782, 2243.6587326558101, 2252.8399392673982, 2262.0305096910702, 2271.2304248849537, 2280.4396659036897, 2289.6582138976523, 2298.8860501121762, 2308.1231558867926, 2317.3695126544767, 2326.6251019409005, 2335.8899053636933, 2345.1639046317132, 2354.4470815443233, 2363.7394179906792, 2373.0408959490205, 2382.3514974859731, 2391.6712047558558, 2400.9999999999991, 2410.3378655460651, 2419.6847838073813, 2429.0407372822747, 2438.4057085534191, 2447.7796802871858, 2457.1626352330004, 2466.5545562227112, 2475.9554261699564, 2485.3652280695474, 2494.7839449968492, 2504.2115601071737, 2513.6480566351788, 2523.0934178942675, 2532.5476272760025, 2542.0106682495189, 2551.482524360948, 2560.9631792328441, 2570.4526165636184, 2579.9508201269791, 2589.4577737713744, 2598.9734614194458, 2608.4978670674823, 2618.0309747848837, 2627.5727687136259, 2637.1232330677353, 2646.6823521327647, 2656.2501102652768, 2665.8264918923328, 2675.4114815109842, 2685.0050636877722, 2694.6072230582295, 2704.2179443263894, 2713.8372122642972, 2723.4650117115279, 2733.1013275747096, 2742.7461448270483, 2752.3994485078601, 2762.0612237221085, 2771.7314556399419, 2781.4101294962406, 2791.0972305901655, 2800.7927442847094, 2810.4966560062589, 2820.2089512441521, 2829.9296155502466, 2839.6586345384894, 2849.3959938844923, 2859.1416793251065, 2868.8956766580086, 2878.6579717412847, 2888.4285504930212, 2898.2073988908974, 2907.9945029717837, 2917.789848831344, 2927.5934226236377, 2937.4052105607311, 2947.2251989123079, 2957.0533740052865, 2966.8897222234368, 2976.734230007005, 2986.5868838523397, 2996.4476703115197, 3006.3165759919889, 3016.1935875561908, 3026.0786917212095, 3035.9718752584108, 3045.8731249930906, 3055.7824278041207, 3065.6997706236039, 3075.625140436528, 3085.5585242804245, 3095.4999092450298, 3105.4492824719491, 3115.4066311543256, 3125.3719425365089, 3135.3452039137287, 3145.3264026317715, 3155.3155260866592, 3165.3125617243295, 3175.3174970403229, 3185.3303195794679, 3195.35101693557, 3205.3795767511078, 3215.4159867169251, 3225.460234571929, 3235.5123081027928, 3245.5721951436558, 3255.63988357583, 3265.7153613275095, 3275.7986163734795, 3285.8896367348289, 3295.9884104786665, 3306.0949257178395, 3316.2091706106517, 3326.331133360588, 3336.4608022160378, 3346.5981654700231, 3356.7432114599264, 3366.8959285672249, 3377.0563052172211, 3387.2243298787821, 3397.3999910640764, 3407.5832773283128, 3417.7741772694862, 3427.9726795281199, 3438.1787727870123, 3448.3924457709873, 3458.6136872466445, 3468.8424860221107, 3479.0788309467976, 3489.3227109111554, 3499.5741148464344, 3509.8330317244445, 3520.0994505573185, 3530.3733603972751, 3540.6547503363886, 3550.9436095063534, 3561.239927078258, 3571.5436922623535, 3581.8548943078308, 3592.1735225025936, 3602.4995661730372, 3612.8330146838275, 3623.1738574376814, 3633.5220838751502, 3643.8776834744031, 3654.2406457510142, 3664.6109602577494, 3674.9886165843564, 3685.3736043573545, 3695.7659132398294, 3706.1655329312248, 3716.5724531671399, 3726.9866637191262, 3737.4081543944876, 3747.8369150360782, 3758.2729355221072, 3768.7162057659411, 3779.1667157159077, 3789.6244553551055, 3800.0894147012082, 3810.5615838062768, 3821.0409527565694, 3831.5275116723533, 3842.0212507077194, 3852.522160050396, 3863.0302299215673, 3873.5454505756893, 3884.0678123003108, 3894.5973054158922, 3905.1339202756285, 3915.6776472652732, 3926.2284768029604, 3936.7863993390338, 3947.3514053558706, 3957.9234853677135, 3968.5026299204969, 3979.0888295916798, 3989.6820749900776, 4000.2823567556948, 4010.8896655595613, 4021.5039921035655, 4032.1253271202945, 4042.7536613728694, 4053.3889856547858, 4064.0312907897551, 4074.6805676315448, 4085.3368070638221, 4095.9999999999982, 4106.6701373830711, 4117.347210185475, 4128.0312094089259, 4138.722126084268, 4149.4199512713267, 4160.1246760587583, 4170.8362915638982, 4181.5547889326181, 4192.2801593391769, 4203.0123939860741, 4213.7514841039101, 4224.4974209512384, 4235.2501958144258, 4246.0098000075095, 4256.7762248720574, 4267.549461777031, 4278.3295021186423, 4289.1163373202198, 4299.9099588320714, 4310.7103581313495, 4321.5175267219138, 4332.3314561342004, 4343.152137925088, 4353.9795636777671, 4364.8137250016052, 4375.6546135320223, 4386.5022209303588, 4397.3565388837469, 4408.2175591049827, 4419.0852733324018, 4429.9596733297531, 4440.8407508860728, 4451.7284978155603, 4462.6229059574571, 4473.5239671759227, 4484.4316733599126, 4495.3460164230582, 4506.2669883035496, 4517.1945809640119, 4528.1287863913894, 4539.069596596828, 4550.0170036155587, 4560.9709995067806, 4571.931576353546, 4582.898726262647, 4593.8724413645004, 4604.8527138130348, 4615.8395357855816, 4626.8328994827571, 4637.8327971283588, 4648.8392209692511, 4659.8521632752563, 4670.8716163390473, 4681.8975724760394, 4692.9300240242837, 4703.9689633443595, 4715.0143828192668, 4726.0662748543255, 4737.1246318770682, 4748.1894463371373, 4759.2607107061804, 4770.3384174777493, 4781.4225591671993, 4792.5131283115852, 4803.6101174695614, 4814.7135192212854, 4825.8233261683154, 4836.9395309335096, 4848.0621261609349, 4859.1911045157631, 4870.3264586841779, 4881.4681813732768, 4892.6162653109768, 4903.7707032459193, 4914.931487947375, 4926.0986122051509, 4937.2720688294967, 4948.4518506510112, 4959.637950520555, 4970.8303613091521, 4982.0290759079044, 4993.2340872278974, 5004.4453882001153, 5015.6629717753467, 5026.8868309241007, 5038.1169586365131, 5049.353347922266, 5060.5959918104927, 5071.8448833496996, 5083.1000156076734, 5094.3613816713996, 5105.6289746469747, 5116.9027876595246, 5128.18281385312, 5139.4690463906918, 5150.7614784539473, 5162.0601032432933, 5173.3649139777472, 5184.6759038948594, 5195.9930662506322, 5207.3163943194386, 5218.6458813939435, 5229.9815207850224, 5241.3233058216847, 5252.6712298509919, 5264.025286237983, 5275.3854683655954, 5286.7517696345885, 5298.1241834634639, 5309.5027032883945, 5320.887322563146, 5332.2780347589978, 5343.6748333646756, 5355.0777118862716, 5366.4866638471722, 5377.901682787985, 5389.3227622664635, 5400.749895857437, 5412.1830771527357, 5423.622299761123, 5435.067557308219, 5446.5188434364318, 5457.9761518048872, 5469.4394760893592, 5480.9088099821975, 5492.3841471922606, 5503.8654814448455, 5515.3528064816201, 5526.846116060552, 5538.3454039558474, 5549.8506639578736, 5561.3618898731029, 5572.8790755240361, 5584.4022147491451, 5595.9313014027975, 5607.4663293552012, 5619.0072924923297, 5630.5541847158656, 5642.1069999431284, 5653.665732107017, 5665.230375155943, 5676.8009230537655, 5688.3773697797333, 5699.9597093284156, 5711.5479357096474, 5723.1420429484588, 5734.7420250850209, 5746.347876174581, 5757.9595902874016, 5769.5771615087006, 5781.2005839385911, 5792.8298516920213, 5804.4649588987149, 5816.1058997031105, 5827.7526682643065, 5839.4052587559972, 5851.0636653664196, 5862.7278822982908, 5874.3979037687541, 5886.0737240093204, 5897.7553372658094, 5909.4427377982956, 5921.1359198810505, 5932.8348778024874, 5944.5396058651031, 5956.2500983854261, 5967.9663496939575, 5979.6883541351208, 5991.4161060672022, 6003.1495998623004, 6014.8888299062692, 6026.6337905986684, 6038.3844763527022, 6050.1408815951781, 6061.9030007664414, 6073.6708283203316, 6085.4443587241267, 6097.2235864584891, 6109.0085060174197, 6120.7991119081998, 6132.595398651345, 6144.3973607805519, 6156.2049928426459, 6168.0182893975361, 6179.8372450181578, 6191.6618542904307, 6203.4921118132024, 6215.3280121982016, 6227.1695500699925, 6239.0167200659189, 6250.8695168360628, 6262.7279350431891, 6274.5919693627056, 6286.4616144826068, 6298.3368651034316, 6310.2177159382172, 6322.1041617124456, 6333.9961971640032, 6345.8938170431311, 6357.7970161123785, 6369.7057891465583, 6381.6201309327007, 6393.5400362700075, 6405.4654999698032, 6417.3965168554978, 6429.3330817625329, 6441.2751895383453, 6453.2228350423138, 6465.176013145724, 6477.134718731716, 6489.0989466952469, 6501.0686919430445, 6513.0439493935628, 6525.0247139769417, 6537.010980634961, 6549.002744321001, 6560.9999999999973, 6573.0027426483985, 6585.0109672541284, 6597.0246688165371, 6609.0438423463656, 6621.0684828657004, 6633.0985854079354, 6645.134145017727, 6657.1751567509573, 6669.2216156746908, 6681.2735168671343, 6693.3308554176001, 6705.3936264264594, 6717.461825005108, 6729.535446275926, 6741.6144853722335, 6753.6989374382601, 6765.7887976290967, 6777.8840611106634, 6789.9847230596661, 6802.0907786635626, 6814.2022231205201, 6826.3190516393797, 6838.4412594396181, 6850.5688417513074, 6862.701793815083, 6874.840110882099, 6886.9837882139991, 6899.1328210828724, 6911.2872047712199, 6923.4469345719199, 6935.6120057881863, 6947.7824137335365, 6959.9581537317536, 6972.1392211168532, 6984.3256112330409, 6996.5173194346862, 7008.7143410862773, 7020.9166715623942, 7033.1243062476678, 7045.3372405367481, 7057.5554698342685, 7069.7789895548103, 7082.0077951228714, 7094.2418819728273, 7106.4812455489018, 7118.7258813051285, 7130.9757847053224, 7143.2309512230404, 7155.4913763415516, 7167.7570555538041, 7180.0279843623894, 7192.3041582795131, 7204.5855728269571, 7216.8722235360519, 7229.1641059476406, 7241.4612156120484, 7253.7635480890503, 7266.0710989478375, 7278.3838637669869, 7290.7018381344296, 7303.0250176474174, 7315.3533979124932, 7327.6869745454596, 7340.0257431713462, 7352.3696994243801, 7364.7188389479543, 7377.0731573945968, 7389.4326504259407, 7401.7973137126937, 7414.1671429346061, 7426.5421337804428, 7438.922281947951, 7451.3075831438346, 7463.6980330837177, 7476.0936274921214, 7488.4943621024304, 7500.9002326568652, 7513.3112349064522, 7525.7273646109943, 7538.1486175390446, 7550.5749894678729, 7563.0064761834419, 7575.4430734803736, 7587.8847771619248, 7600.3315830399597, 7612.7834869349153, 7625.24048467578, 7637.7025721000637, 7650.1697450537677, 7662.6419993913596, 7675.1193309757446, 7687.6017356782404, 7700.0892093785433, 7712.5817479647112, 7725.079347333125, 7737.5820033884729, 7750.0897120437139, 7762.6024692200581, 7775.1202708469355, 7787.6431128619733, 7800.1709912109645, 7812.7039018478481, 7825.2418407346768, 7837.7848038415968, 7850.3327871468155, 7862.8857866365806, 7875.4437983051539, 7888.006818154784, 7900.5748421956796, 7913.1478664459901, 7925.725886931772, 7938.3088996869719, 7950.8969007533951, 7963.4898861806851, 7976.0878520262959, 7988.6907943554688, 8001.2987092412086, 8013.911592764257, 8026.5294410130691, 8039.1522500837891, 8051.7800160802271, 8064.412735113835, 8077.0504033036796, 8089.6930167764222, 8102.3405716662946, 8114.9930641150731, 8127.6504902720571, 8140.3128462940449, 8152.9801283453098, 8165.6523325975786, 8178.3294552300049, 8191.0114924291529, 8203.6984403889655, 8216.3902953107463, 8229.0870534031419, 8241.7887108821069, 8254.4952639708936, 8267.2067089000211, 8279.9230419072574, 8292.6442592375952, 8305.3703571432306, 8318.101331883543, 8330.8371797250657, 8343.577896941475, 8356.3234798135582, 8369.0739246291978, 8381.8292276833508, 8394.5893852780209, 8407.3543937222421, 8420.1242493320569, 8432.8989484304948, 8445.6784873475499, 8458.4628624201578, 8471.2520699921806, 8484.0461064143838, 8496.8449680444082, 8509.6486512467636, 8522.4571523927953, 8535.270467860666, 8548.0885940353437, 8560.9115273085663, 8573.7392640788403, 8586.5718007514006, 8599.4091337382069, 8612.2512594579148, 8625.0981743358552, 8637.9498748040205, 8650.8063573010386, 8663.6676182721567, 8676.533654169225, 8689.4044614506638, 8702.2800365814601, 8715.1603760331418, 8728.0454762837508, 8740.9353338178389, 8753.8299451264356, 8766.7293067070332, 8779.6334150635721, 8792.5422667064158, 8805.4558581523324, 8818.3741859244819, 8831.2972465523908, 8844.2250365719356, 8857.1575525253265, 8870.0947909610859, 8883.0367484340295, 8895.9834215052524, 8908.934806742107, 8921.8909007181846, 8934.8517000132997, 8947.817201213471, 8960.7874009109, 8973.7622957039603, 8986.7418821971733, 8999.7261570011924, 9012.7151167327884, 9025.7087580148236, 9038.7070774762469, 9051.7100717520643, 9064.7177374833282, 9077.7300713171153, 9090.7470699065179, 9103.7687299106146, 9116.7950479944648, 9129.8260208290812, 9142.8616450914233, 9155.9019174643727, 9168.9468346367157, 9181.9963933031358, 9195.0505901641845, 9208.1094219262741, 9221.1728853016557, 9234.240977008405, 9247.3136937704076, 9260.3910323173386, 9273.472989384647, 9286.5595617135423, 9299.6507460509747, 9312.7465391496207, 9325.8469377678684, 9338.9519386698012, 9352.0615386251757, 9365.1757344094131, 9378.2945228035842, 9391.4179005943843, 9404.5458645741273, 9417.6784115407263, 9430.8155382976747, 9443.9572416540359, 9457.1035184244265, 9470.2543654290002, 9483.4097794934296, 9496.5697574488931, 9509.7342961320664, 9522.9033923850911, 9536.0770430555804, 9549.2552449965824, 9562.4379950665825, 9575.6252901294793, 9588.8171270545736, 9602.0135027165488, 9615.2144139954635, 9628.4198577767274, 9641.629830951093, 9654.844330414644, 9668.0633530687719, 9681.286895820167, 9694.5149555808002, 9707.7475292679192, 9720.9846138040157, 9734.2262061168276, 9747.4723031393187, 9760.7229018096641, 9773.9779990712323, 9787.2375918725811, 9800.5016771674327, 9813.7702519146696, 9827.0433130783094, 9840.3208576275028, 9853.602882536512, 9866.8893847846994, 9880.1803613565116, 9893.4758092414686, 9906.7757254341523, 9920.0801069341851, 9933.3889507462245, 9946.7022538799429, 9960.0200133500221, 9973.3422261761298, 9986.6688893829159, 9999.9999999999945, 10013.335555061929, 10026.675551608221, 10040.019986683301, 10053.368857336509, 10066.722160622081, 10080.079893599144, 10093.442053331697, 10106.808636888598, 10120.179641343551, 10133.555063775095, 10146.934901266595, 10160.31915090622, 10173.707809786936, 10187.100875006496, 10200.498343667417, 10213.900212876984, 10227.306479747222, 10240.717141394889, 10254.132194941467, 10267.551637513146, 10280.975466240814, 10294.40367826004, 10307.836270711066, 10321.273240738796, 10334.71458549278, 10348.160302127204, 10361.610387800878, 10375.064839677221, 10388.523654924258, 10401.986830714593, 10415.454364225412, 10428.926252638465, 10442.402493140049, 10455.883082921007, 10469.368019176709, 10482.85729910704, 10496.350919916393, 10509.848878813653, 10523.351173012188, 10536.857799729838, 10550.3687561889, 10563.884039616123, 10577.403647242685, 10590.927576304197, 10604.455824040679, 10617.988387696556, 10631.525264520642, 10645.066451766135, 10658.611946690598, 10672.161746555956, 10685.715848628475, 10699.274250178762, 10712.836948481747, 10726.403940816675, 10739.975224467091, 10753.550796720834, 10767.130654870027, 10780.714796211059, 10794.303218044579, 10807.895917675487, 10821.492892412922, 10835.094139570248, 10848.699656465047, 10862.309440419107, 10875.923488758415, 10889.541798813138, 10903.16436791762, 10916.791193410372, 10930.422272634056, 10944.05760293548, 10957.697181665582, 10971.341006179427, 10984.98907383619, 10998.641381999149, 11012.297928035676, 11025.958709317223, 11039.623723219316, 11053.292967121541, 11066.966438407539, 11080.64413446499, 11094.326052685608, 11108.012190465128, 11121.702545203296, 11135.397114303863, 11149.095895174571, 11162.798885227143, 11176.506081877278, 11190.217482544635, 11203.933084652828, 11217.652885629415, 11231.376882905886, 11245.105073917659, 11258.837456104062, 11272.574026908333, 11286.314783777601, 11300.059724162888, 11313.808845519083, 11327.562145304952, 11341.319620983111, 11355.081270020033, 11368.847089886023, 11382.617078055218, 11396.391232005579, 11410.169549218874, 11423.952027180676, 11437.738663380349, 11451.529455311042, 11465.324400469679, 11479.123496356951, 11492.926740477304, 11506.734130338931, 11520.545663453764, 11534.361337337466, 11548.181149509423, 11562.005097492724, 11575.83317881417, 11589.665391004253, 11603.501731597149, 11617.342198130715, 11631.186788146468, 11645.035499189589, 11658.888328808911, 11672.745274556904, 11686.606333989675, 11700.471504666955, 11714.340784152086, 11728.214170012021, 11742.091659817312, 11755.973251142101, 11769.858941564111, 11783.748728664636, 11797.642610028539, 11811.540583244237, 11825.442645903697, 11839.34879560242, 11853.259029939445, 11867.173346517333, 11881.091742942155, 11895.014216823492, 11908.940765774427, 11922.871387411526, 11936.806079354839, 11950.744839227897, 11964.687664657684, 11978.634553274653, 11992.585502712702, 12006.540510609168, 12020.499574604828, 12034.462692343877, 12048.429861473938, 12062.401079646032, 12076.376344514589, 12090.355653737433, 12104.339004975769, 12118.326395894188, 12132.317824160644, 12146.313287446457, 12160.312783426305, 12174.316309778205, 12188.323864183525, 12202.335444326955, 12216.351047896511, 12230.370672583531, 12244.394316082657, 12258.421976091831, 12272.453650312296, 12286.489336448574, 12300.529032208471, 12314.572735303058, 12328.620443446678, 12342.672154356922, 12356.727865754638, 12370.787575363909, 12384.851280912055, 12398.918980129623, 12412.990670750381, 12427.066350511306, 12441.146017152583, 12455.229668417589, 12469.317302052901, 12483.40891580827, 12497.50450743663, 12511.604074694078, 12525.707615339878, 12539.815127136444, 12553.926607849342, 12568.042055247275, 12582.161467102082, 12596.284841188726, 12610.41217528529, 12624.543467172971, 12638.678714636069, 12652.817915461985, 12666.961067441209, 12681.108168367316, 12695.259216036962, 12709.414208249869, 12723.573142808827, 12737.736017519681, 12751.902830191326, 12766.073578635704, 12780.248260667788, 12794.426874105588, 12808.609416770132, 12822.795886485468, 12836.986281078653, 12851.180598379744, 12865.378836221802, 12879.580992440871, 12893.787064875984, 12907.997051369144, 12922.210949765335, 12936.428757912496, 12950.650473661524, 12964.876094866273, 12979.105619383534, 12993.339045073039, 13007.576369797454, 13021.817591422368, 13036.062707816285, 13050.311716850629, 13064.564616399723, 13078.821404340792, 13093.082078553954, 13107.346636922217, 13121.615077331464, 13135.887397670458, 13150.163595830827, 13164.44366970706, 13178.727617196502, 13193.015436199352, 13207.307124618648, 13221.602680360265, 13235.902101332911, 13250.205385448118, 13264.512530620239, 13278.823534766434, 13293.138395806676, 13307.457111663734, 13321.779680263176, 13336.106099533356, 13350.436367405409, 13364.77048181325, 13379.108440693562, 13393.450241985796, 13407.795883632158, 13422.145363577607, 13436.498679769853, 13450.855830159346, 13465.216812699266, 13479.581625345529, 13493.950266056772, 13508.32273279435, 13522.699023522329, 13537.079136207483, 13551.463068819286, 13565.850819329906, 13580.2423857142, 13594.63776594971, 13609.036958016657, 13623.439959897927, 13637.846769579081, 13652.257385048335, 13666.67180429656, 13681.090025317284, 13695.512046106669, 13709.937864663521, 13724.367478989278, 13738.800887088004, 13753.238086966385, 13767.679076633727, 13782.123854101939, 13796.572417385545, 13811.024764501659, 13825.480893469998, 13839.94080231286, 13854.404489055134, 13868.871951724283, 13883.34318835034, 13897.818196965914, 13912.296975606168, 13926.779522308825, 13941.26583511416, 13955.755912064991, 13970.249751206682, 13984.747350587126, 13999.248708256751, 14013.753822268511, 14028.262690677873, 14042.775311542828, 14057.291682923867, 14071.811802883994, 14086.335669488704, 14100.863280805994, 14115.394634906341, 14129.92972986271, 14144.468563750548, 14159.01113464777, 14173.55744063476, 14188.107479794369, 14202.661250211901, 14217.218749975118, 14231.779977174227, 14246.344929901879, 14260.913606253163, 14275.486004325601, 14290.062122219146, 14304.641958036171, 14319.225509881464, 14333.812775862236, 14348.403754088098, 14362.998442671067, 14377.59683972556, 14392.198943368388, 14406.804751718748, 14421.414262898223, 14436.027475030774, 14450.64438624274, 14465.264994662828, 14479.889298422106, 14494.517295654005, 14509.148984494313, 14523.784363081166, 14538.423429555049, 14553.066182058781, 14567.712618737527, 14582.362737738777, 14597.016537212348, 14611.674015310382, 14626.33517018734, 14640.999999999993, 14655.668502907418, 14670.340677071003, 14685.016520654426, 14699.696031823671, 14714.379208746999, 14729.066049594967, 14743.756552540408, 14758.45071575843, 14773.148537426418, 14787.850015724018, 14802.555148833142, 14817.263934937961, 14831.976372224897, 14846.692458882624, 14861.41219310206, 14876.135573076363, 14890.862597000923, 14905.593263073371, 14920.327569493558, 14935.065514463557, 14949.807096187662, 14964.552312872382, 14979.301162726431, 14994.053643960735, 15008.809754788414, 15023.569493424788, 15038.332858087369, 15053.099846995858, 15067.870458372134, 15082.644690440264, 15097.422541426484, 15112.204009559202, 15126.989093068994, 15141.777790188597, 15156.570099152905, 15171.366018198967, 15186.165545565986, 15200.968679495301, 15215.775418230402, 15230.585760016909, 15245.399703102579, 15260.217245737298, 15275.038386173073, 15289.863122664035, 15304.691453466432, 15319.523376838621, 15334.358891041069, 15349.197994336346, 15364.040684989128, 15378.886961266177, 15393.736821436356, 15408.590263770609, 15423.447286541972, 15438.307888025554, 15453.172066498542, 15468.039820240196, 15482.91114753184, 15497.786046656869, 15512.664515900733, 15527.546553550939, 15542.432157897045, 15557.32132723066, 15572.214059845435, 15587.110354037064, 15602.010208103273, 15616.913620343823, 15631.820589060506, 15646.731112557136, 15661.645189139546, 15676.562817115593, 15691.483994795139, 15706.408720490062, 15721.336992514242, 15736.268809183561, 15751.204168815901, 15766.143069731135, 15781.085510251132, 15796.03148869974, 15810.981003402798, 15825.934052688119, 15840.890634885489, 15855.850748326673, 15870.814391345401, 15885.781562277361, 15900.752259460214, 15915.726481233565, 15930.704225938984, 15945.685491919978, 15960.670277522009, 15975.658581092481, 15990.65040098073, 16005.645735538035, 16020.644583117599, 16035.646942074556, 16050.652810765967, 16065.662187550806, 16080.675070789974, 16095.691458846273, 16110.711350084424, 16125.734742871053, 16140.761635574685, 16155.792026565747, 16170.825914216561, 16185.863296901338, 16200.904172996183, 16215.948540879079, 16230.996398929899, 16246.047745530386, 16261.102579064163, 16276.160897916721, 16291.22270047542, 16306.287985129484, 16321.356750269995, 16336.428994289896, 16351.504715583982, 16366.5839125489, 16381.666583583141, 16396.752727087041, 16411.842341462776, 16426.935425114363, 16442.031976447644, 16457.131993870298, 16472.235475791829, 16487.342420623561, 16502.452826778641, 16517.566692672033, 16532.684016720516, 16547.804797342676, 16562.929032958902, 16578.056721991394, 16593.18786286415, 16608.322454002962, 16623.460493835417, 16638.601980790896, 16653.746913300558, 16668.895289797354, 16684.047108716015, 16699.202368493046, 16714.361067566726, 16729.523204377107, 16744.688777366009, 16759.857784977012, 16775.030225655464, 16790.206097848466, 16805.385400004874, 16820.568130575302, 16835.754288012104, 16850.943870769381, 16866.136877302983, 16881.333306070494, 16896.53315553123, 16911.736424146249, 16926.943110378332, 16942.153212691992, 16957.366729553454, 16972.583659430682, 16987.804000793338, 17003.027752112816, 17018.254911862205, 17033.485478516312, 17048.719450551645, 17063.956826446421, 17079.197604680547, 17094.44178373563, 17109.689362094967, 17124.940338243552, 17140.194710668064, 17155.452477856852, 17170.713638299967, 17185.978190489128, 17201.246132917724, 17216.517464080825, 17231.792182475165, 17247.070286599141, 17262.351774952826, 17277.636646037936, 17292.924898357855, 17308.216530417623, 17323.511540723921, 17338.809927785089, 17354.111690111105, 17369.416826213594, 17384.725334605821, 17400.037213802683, 17415.352462320716, 17430.67107867809, 17445.993061394587, 17461.318408991636, 17476.647119992274, 17491.979192921168, 17507.314626304586, 17522.653418670423, 17537.995568548187, 17553.341074468986, 17568.689934965536, 17584.042148572156, 17599.397713824768, 17614.75662926089, 17630.118893419625, 17645.484504841683, 17660.853462069354, 17676.225763646511, 17691.601408118619, 17706.980394032718, 17722.362719937424, 17737.748384382936, 17753.137385921014, 17768.529723104999, 17783.92539448979, 17799.324398631856, 17814.726734089225, 17830.13239942148, 17845.541393189767, 17860.95371395678, 17876.369360286772, 17891.788330745527, 17907.210623900395, 17922.636238320254, 17938.065172575527, 17953.497425238176, 17968.932994881692, 17984.371880081104, 17999.814079412972, 18015.259591455371, 18030.708414787914, 18046.160547991731, 18061.615989649465, 18077.074738345284, 18092.536792664861, 18108.002151195393, 18123.470812525571, 18138.942775245599, 18154.418037947191, 18169.896599223546, 18185.37845766938, 18200.863611880886, 18216.352060455767, 18231.843801993204, 18247.338835093873, 18262.837158359936, 18278.338770395032, 18293.84366980429, 18309.351855194309, 18324.863325173166, 18340.378078350412, 18355.896113337069, 18371.417428745623, 18386.942023190033, 18402.469895285718, 18418.00104364955, 18433.53546689987, 18449.073163656474, 18464.614132540602, 18480.158372174956, 18495.705881183676, 18511.256658192357, 18526.810701828035, 18542.368010719183, 18557.928583495715, 18573.492418788985, 18589.059515231773, 18604.629871458303, 18620.203486104212, 18635.78035780658, 18651.360485203899, 18666.943866936086, 18682.53050164448, 18698.120387971841, 18713.713524562332, 18729.30991006154, 18744.909543116457, 18760.512422375479, 18776.118546488418, 18791.727914106479, 18807.340523882274, 18822.95637446981, 18838.575464524489, 18854.197792703111, 18869.823357663863, 18885.452158066328, 18901.08419257147, 18916.719459841639, 18932.357958540564, 18947.999687333362, 18963.644644886521, 18979.292829867907, 18994.944240946759, 19010.598876793687, 19026.256736080668, 19041.917817481048, 19057.582119669532, 19073.2496413222, 19088.920381116473, 19104.594337731145, 19120.271509846356, 19135.951896143604, 19151.635495305738, 19167.322306016948, 19183.012326962784, 19198.705556830122, 19214.401994307198, 19230.101638083579, 19245.804486850167, 19261.510539299208, 19277.219794124274, 19292.932250020265, 19308.647905683421, 19324.366759811302, 19340.088811102793, 19355.8140582581, 19371.542499978754, 19387.2741349676, 19403.008961928797, 19418.746979567823, 19434.488186591469, 19450.232581707827, 19465.980163626304, 19481.730931057613, 19497.484882713761, 19513.242017308068, 19529.002333555141, 19544.765830170898, 19560.532505872539, 19576.302359378566, 19592.075389408761, 19607.851594684209, 19623.630973927269, 19639.41352586159, 19655.199249212103, 19670.988142705017, 19686.780205067826, 19702.575435029288, 19718.373831319448, 19734.175392669615, 19749.980117812371, 19765.788005481569, 19781.599054412323, 19797.413263341008, 19813.230631005274, 19829.051156144014, 19844.874837497395, 19860.701673806827, 19876.531663814985, 19892.364806265789, 19908.201099904403, 19924.040543477258, 19939.883135732012, 19955.728875417579, 19971.577761284105, 19987.429792082985, 20003.284966566847, 20019.14328348956, 20035.004741606219, 20050.869339673161, 20066.737076447946, 20082.607950689362, 20098.481961157428, 20114.359106613385, 20130.239385819699, 20146.122797540058, 20162.009340539353, 20177.899013583716, 20193.791815440476, 20209.687744878182, 20225.586800666591, 20241.488981576669, 20257.394286380597, 20273.302713851754, 20289.214262764715, 20305.128931895277, 20321.046720020415, 20336.967625918318, 20352.891648368361, 20368.818786151114, 20384.749038048347, 20400.682402843009, 20416.618879319249, 20432.558466262391, 20448.501162458953, 20464.446966696629, 20480.395877764302, 20496.347894452025, 20512.303015551031, 20528.261239853735, 20544.22256615372, 20560.186993245738, 20576.15451992572, 20592.125144990758, 20608.098867239107, 20624.075685470198, 20640.055598484618, 20656.038605084115, 20672.024704071595, 20688.013894251126, 20704.006174427926, 20720.001543408373, 20735.999999999989, 20752.001543011454, 20768.006171252597, 20784.013883534382, 20800.024678668931, 20816.038555469506, 20832.055512750507, 20848.075549327474, 20864.098664017085, 20880.124855637161, 20896.154123006647, 20912.186464945626, 20928.221880275312, 20944.260367818049, 20960.301926397311, 20976.346554837684, 20992.394251964895, 21008.445016605787, 21024.498847588318, 21040.555743741574, 21056.615703895754, 21072.678726882168, 21088.744811533252, 21104.813956682538, 21120.886161164683, 21136.961423815443, 21153.039743471683, 21169.121118971379, 21185.205549153605, 21201.293032858535, 21217.383568927453, 21233.477156202731, 21249.573793527841, 21265.673479747358, 21281.776213706937, 21297.881994253334, 21313.990820234398, 21330.102690499054, 21346.21760389733, 21362.335559280327, 21378.456555500241, 21394.580591410333, 21410.707665864964, 21426.83777771956, 21442.970925830628, 21459.107109055756, 21475.246326253604, 21491.388576283895, 21507.533858007431, 21523.682170286087, 21539.833511982797, 21555.987881961566, 21572.145279087465, 21588.305702226615, 21604.469150246216, 21620.635622014521, 21636.805116400832, 21652.977632275521, 21669.153168510009, 21685.331723976764, 21701.513297549318, 21717.697888102244, 21733.885494511167, 21750.076115652759, 21766.269750404736, 21782.466397645861, 21798.666056255934, 21814.868725115801, 21831.074403107345, 21847.283089113484, 21863.494782018177, 21879.709480706417, 21895.927184064229, 21912.147890978667, 21928.371600337818, 21944.598311030797, 21960.828021947746, 21977.060731979829, 21993.296440019243, 22009.535144959198, 22025.77684569393, 22042.021541118691, 22058.269230129757, 22074.519911624411, 22090.773584500959, 22107.030247658717, 22123.289899998013, 22139.552540420187, 22155.818167827587, 22172.086781123569, 22188.358379212495, 22204.632960999726, 22220.910525391639, 22237.191071295601, 22253.474597619981, 22269.761103274148, 22286.050587168469, 22302.343048214312, 22318.638485324027, 22334.936897410968, 22351.23828338947, 22367.542642174871, 22383.849972683485, 22400.160273832618, 22416.473544540564, 22432.789783726603, 22449.108990310986, 22465.431163214958, 22481.75630136074, 22498.084403671528, 22514.415469071497, 22530.749496485802, 22547.086484840562, 22563.426433062879, 22579.769340080824, 22596.115204823436, 22612.464026220721, 22628.815803203655, 22645.170534704179, 22661.5282196552, 22677.888856990587, 22694.252445645168, 22710.618984554734, 22726.988472656034, 22743.360908886778, 22759.736292185622, 22776.114621492186, 22792.495895747044, 22808.880113891719, 22825.267274868678, 22841.657377621348, 22858.050421094096, 22874.446404232243, 22890.845325982053, 22907.247185290722, 22923.651981106406, 22940.059712378195, 22956.470378056114, 22972.883977091129, 22989.300508435153, 23005.719971041017, 23022.142363862498, 23038.567685854305, 23054.995935972078, 23071.427113172387, 23087.86121641273, 23104.298244651531, 23120.738196848146, 23137.181071962848, 23153.626868956846, 23170.075586792263, 23186.527224432142, 23202.981780840448, 23219.439254982066, 23235.899645822796, 23252.362952329357, 23268.829173469378, 23285.298308211408, 23301.770355524899, 23318.245314380223, 23334.723183748658, 23351.203962602387, 23367.687649914504, 23384.174244659007, 23400.663745810798, 23417.15615234568, 23433.651463240367, 23450.149677472462, 23466.650794020472, 23483.154811863806, 23499.661729982763, 23516.171547358543, 23532.684262973235, 23549.199875809823, 23565.718384852185, 23582.239789085092, 23598.764087494197, 23615.291279066041, 23631.821362788058, 23648.354337648565, 23664.890202636761, 23681.428956742733, 23697.970598957443, 23714.515128272738, 23731.062543681343, 23747.612844176863, 23764.166028753778, 23780.72209640744, 23797.281046134085, 23813.842876930816, 23830.407587795606, 23846.975177727301, 23863.545645725622, 23880.11899079115, 23896.695211925336, 23913.274308130498, 23929.856278409821, 23946.441121767348, 23963.028837207989, 23979.619423737513, 23996.212880362549, 24012.809206090584, 24029.408399929966, 24046.010460889898, 24062.615387980433, 24079.223180212492, 24095.833836597827, 24112.447356149063, 24129.063737879667, 24145.682980803951, 24162.305083937081, 24178.930046295067, 24195.557866894767, 24212.188544753884, 24228.822078890964, 24245.458468325389, 24262.097712077397, 24278.739809168052, 24295.384758619261, 24312.032559453768, 24328.683210695162, 24345.336711367858, 24361.993060497109, 24378.652257108995, 24395.314300230442, 24411.979188889192, 24428.646922113825, 24445.317498933746, 24461.990918379193, 24478.667179481225, 24495.346281271726, 24512.028222783407, 24528.713003049801, 24545.400621105266, 24562.091075984976, 24578.784366724925, 24595.480492361927, 24612.179451933614, 24628.881244478438, 24645.585869035654, 24662.293324645343, 24679.003610348394, 24695.716725186514, 24712.432668202211, 24729.151438438807, 24745.873034940436, 24762.597456752032, 24779.324702919344, 24796.054772488926, 24812.787664508123, 24829.5233780251, 24846.261912088819, 24863.003265749034, 24879.747438056307, 24896.494428062004, 24913.244234818278, 24929.996857378079, 24946.752294795166, 24963.510546124078, 24980.271610420157, 24997.035486739525, 25013.802174139113, 25030.571671676629, 25047.343978410572, 25064.119093400237, 25080.897015705697, 25097.677744387816, 25114.461278508239, 25131.2476171294, 25148.036759314517, 25164.828704127583, 25181.623450633375, 25198.42099789745, 25215.221344986145, 25232.024490966574, 25248.830434906627, 25265.639175874974, 25282.450712941049, 25299.265045175071, 25316.082171648024, 25332.902091431668, 25349.724803598532, 25366.550307221914, 25383.378601375884, 25400.209685135269, 25417.043557575678, 25433.880217773472, 25450.719664805783, 25467.561897750507, 25484.406915686297, 25501.254717692573, 25518.105302849512, 25534.958670238051, 25551.814818939893, 25568.67374803748, 25585.535456614027, 25602.399943753502, 25619.267208540619, 25636.137250060852, 25653.010067400432, 25669.885659646327, 25686.76402588627, 25703.645165208734, 25720.529076702944, 25737.415759458876, 25754.305212567244, 25771.197435119517, 25788.092426207899, 25804.990184925344, 25821.890710365547, 25838.794001622944, 25855.700057792714, 25872.608877970775, 25889.520461253778, 25906.434806739118, 25923.351913524923, 25940.271780710063, 25957.194407394138, 25974.11979267748, 25991.047935661154, 26007.978835446964, 26024.912491137442, 26041.848901835841, 26058.788066646157, 26075.729984673108, 26092.674655022136, 26109.622076799409, 26126.572249111829, 26143.525171067016, 26160.480841773315, 26177.43926033979, 26194.400425876229, 26211.364337493149, 26228.330994301767, 26245.30039541404, 26262.272539942627, 26279.247427000919, 26296.225055703002, 26313.205425163702, 26330.188534498539, 26347.174382823756, 26364.162969256304, 26381.154292913852, 26398.148352914774, 26415.145148378149, 26432.144678423778, 26449.146942172156, 26466.151938744493, 26483.159667262702, 26500.170126849403, 26517.183316627921, 26534.199235722277, 26551.217883257199, 26568.239258358124, 26585.263360151173, 26602.290187763181, 26619.319740321676, 26636.352016954883, 26653.387016791727, 26670.424738961825, 26687.465182595493, 26704.508346823739, 26721.554230778267, 26738.602833591467, 26755.65415439643, 26772.708192326929, 26789.764946517433, 26806.824416103096, 26823.886600219761, 26840.95149800396, 26858.019108592915, 26875.089431124517, 26892.162464737365, 26909.238208570721, 26926.316661764544, 26943.397823459472, 26960.481692796813, 26977.568268918571, 26994.657550967422, 27011.749538086722, 27028.844229420498, 27045.941624113464, 27063.041721311005, 27080.144520159181, 27097.250019804727, 27114.35821939505, 27131.469118078236, 27148.582715003027, 27165.699009318858, 27182.818000175819, 27199.939686724665, 27217.064068116837, 27234.191143504428, 27251.320912040203, 27268.453372877593, 27285.588525170693, 27302.726368074269, 27319.866900743735, 27337.010122335181, 27354.156032005358, 27371.304628911668, 27388.455912212183, 27405.609881065626, 27422.766534631384, 27439.925872069507, 27457.087892540683, 27474.252595206275, 27491.419979228293, 27508.5900437694, 27525.762787992917, 27542.93821106281, 27560.116312143706, 27577.297090400876, 27594.480545000242, 27611.666675108383, 27628.855479892518, 27646.046958520514, 27663.241110160889, 27680.437933982801, 27697.637429156068, 27714.839594851132, 27732.04443023909, 27749.251934491687, 27766.462106781299, 27783.674946280949, 27800.890452164302, 27818.108623605654, 27835.329459779954, 27852.55295986278, 27869.779123030345, 27887.007948459504, 27904.239435327745, 27921.473582813196, 27938.710390094613, 27955.949856351392, 27973.19198076355, 27990.436762511745, 28007.684200777272, 28024.934294742041, 28042.187043588601, 28059.442446500128, 28076.700502660427, 28093.961211253929, 28111.224571465693, 28128.490582481401, 28145.759243487362, 28163.030553670509, 28180.304512218394, 28197.581118319198, 28214.860371161725, 28232.14226993539, 28249.42681383024, 28266.71400203693, 28284.003833746745, 28301.296308151585, 28318.591424443959, 28335.889181817001, 28353.189579464462, 28370.492616580705, 28387.798292360701, 28405.106606000048, 28422.417556694945, 28439.731143642206, 28457.047366039264, 28474.366223084147, 28491.687713975512, 28509.011837912611, 28526.338594095305, 28543.667981724069, 28560.999999999982, 28578.334648124732, 28595.671925300605, 28613.011830730498, 28630.354363617909, 28647.699523166943, 28665.0473085823, 28682.397719069289, 28699.750753833818, 28717.10641208239, 28734.464693022121, 28751.825595860708, 28769.189119806462, 28786.55526406828, 28803.924027855664, 28821.295410378701, 28838.669410848088, 28856.046028475103, 28873.425262471628, 28890.80711205013, 28908.191576423673, 28925.578654805915, 28942.968346411097, 28960.360650454055, 28977.755566150216, 28995.153092715591, 29012.553229366786, 29029.955975320987, 29047.361329795975, 29064.769292010107, 29082.179861182336, 29099.593036532187, 29117.00881727978, 29134.427202645813, 29151.848191851568, 29169.271784118911, 29186.697978670283, 29204.126774728706, 29221.55817151779, 29238.992168261717, 29256.42876418525, 29273.867958513725, 29291.309750473058, 29308.754139289747, 29326.201124190855, 29343.65070440403, 29361.102879157483, 29378.557647680012, 29396.015009200975, 29413.474962950309, 29430.937508158524, 29448.402644056692, 29465.870369876469, 29483.340684850071, 29500.81358821028, 29518.289079190454, 29535.767157024511, 29553.247820946945, 29570.731070192807, 29588.216903997723, 29605.70532159787, 29623.19632223, 29640.689905131429, 29658.186069540028, 29675.684814694236, 29693.186139833047, 29710.690044196028, 29728.196527023298, 29745.705587555527, 29763.217225033964, 29780.731438700397, 29798.248227797183, 29815.76759156723, 29833.289529254005, 29850.81404010153, 29868.341123354381, 29885.870778257693, 29903.403004057145, 29920.937799998974, 29938.475165329975, 29956.015099297485, 29973.557601149394, 29991.102670134147, 30008.650305500738, 30026.200506498706, 30043.753272378144, 30061.308602389683, 30078.866495784507, 30096.426951814352, 30113.989969731494, 30131.55554878875, 30149.123688239491, 30166.694387337629, 30184.267645337608, 30201.843461494434, 30219.42183506364, 30237.002765301309, 30254.586251464058, 30272.172292809046, 30289.760888593977, 30307.35203807709, 30324.94574051716, 30342.541995173502, 30360.140801305966, 30377.742158174944, 30395.346065041358, 30412.952521166666, 30430.561525812864, 30448.173078242475, 30465.787177718561, 30483.403823504719, 30501.02301486507, 30518.644751064272, 30536.269031367516, 30553.895855040515, 30571.525221349519, 30589.157129561307, 30606.791578943175, 30624.428568762964, 30642.06809828903, 30659.710166790261, 30677.35477353607, 30695.001917796391, 30712.651598841687, 30730.303815942945, 30747.958568371676, 30765.615855399912, 30783.275676300211, 30800.938030345646, 30818.602916809814, 30836.270334966837, 30853.940284091354, 30871.612763458521, 30889.287772344011, 30906.965310024025, 30924.645375775272, 30942.327968874983, 30960.013088600903, 30977.700734231294, 30995.390905044929, 31013.083600321101, 31030.778819339619, 31048.476561380798, 31066.17682572547, 31083.879611654978, 31101.584918451179, 31119.29274539644, 31137.003091773637, 31154.715956866155, 31172.431339957893, 31190.14924033326, 31207.869657277162, 31225.592590075023, 31243.318038012771, 31261.046000376838, 31278.776476454172, 31296.50946553221, 31314.24496689891, 31331.98297984272, 31349.7235036526, 31367.466537618013, 31385.212081028923, 31402.960133175795, 31420.710693349596, 31438.463760841791, 31456.219334944351, 31473.977414949743, 31491.738000150934, 31509.501089841389, 31527.266683315069, 31545.034779866437, 31562.80537879045, 31580.578479382562, 31598.35408093872, 31616.132182755369, 31633.91278412945, 31651.695884358396, 31669.481482740131, 31687.269578573076, 31705.060171156143, 31722.853259788735, 31740.648843770748, 31758.446922402567, 31776.247494985066, 31794.050560819614, 31811.85611920806, 31829.664169452753, 31847.474710856521, 31865.287742722685, 31883.103264355046, 31900.921275057899, 31918.741774136019, 31936.564760894671, 31954.390234639599, 31972.21819467704, 31990.048640313704, 32007.881570856793, 32025.716985613984, 32043.554883893445, 32061.395265003815, 32079.238128254223, 32097.083472954269, 32114.931298414049, 32132.781603944117, 32150.634388855524, 32168.48965245979, 32186.347394068915, 32204.207612995371, 32222.07030855212, 32239.935480052583, 32257.803126810672, 32275.673248140767, 32293.545843357719, 32311.420911776862, 32329.298452713996, 32347.178465485395, 32365.060949407813, 32382.945903798463, 32400.83332797504, 32418.723221255706, 32436.615582959093, 32454.510412404306, 32472.407708910916, 32490.307471798966, 32508.209700388961, 32526.114394001877, 32544.021551959166, 32561.931173582732, 32579.843258194956, 32597.757805118679, 32615.674813677211, 32633.594283194328, 32651.516212994258, 32669.440602401712, 32687.367450741847, 32705.296757340297, 32723.228521523146, 32741.162742616943, 32759.099419948703, 32777.038552845901, 32794.980140636464, 32812.924182648792, 32830.87067821173, 32848.819626654593, 32866.77102730715, 32884.724879499619, 32902.681182562686, 32920.639935827494, 32938.601138625643, 32956.56479028918, 32974.530890150607, 32992.499437542894, 33010.470431799447, 33028.443872254145, 33046.419758241311, 33064.39808909571, 33082.378864152583, 33100.36208274759, 33118.347744216881, 33136.335847897026, 33154.326393125062, 33172.31937923847, 33190.314805575174, 33208.312671473555, 33226.312976272442, 33244.315719311111, 33262.320899929284, 33280.328517467125, 33298.33857126526, 33316.351060664747, 33334.365985007091, 33352.383343634239, 33370.403135888591, 33388.42536111299, 33406.450018650721, 33424.477107845501, 33442.506628041512, 33460.53857858335, 33478.572958816083, 33496.609768085189, 33514.649005736617, 33532.690671116739, 33550.734763572356, 33568.781282450735, 33586.830227099563, 33604.881596866973, 33622.935391101528, 33640.991609152239, 33659.050250368542, 33677.111314100322, 33695.174799697881, 33713.240706511984, 33731.309033893805, 33749.37978119497, 33767.452947767531, 33785.528532963974, 33803.606536137209, 33821.686956640602, 33839.769793827938, 33857.855047053425, 33875.942715671707, 33894.032799037872, 33912.125296507431, 33930.220207436316, 33948.317531180888, 33966.417267097961, 33984.519414544746, 34002.623972878901, 34020.730941458511, 34038.840319642077, 34056.952106788536, 34075.066302257255, 34093.182905408015, 34111.301915601027, 34129.42333219693, 34147.547154556785, 34165.673382042078, 34183.80201401472, 34201.933049837033, 34220.06648887178, 34238.202330482141, 34256.340574031703, 34274.481218884495, 34292.624264404949, 34310.769709957938, 34328.91755490873, 34347.067798623029, 34365.220440466954, 34383.375479807051, 34401.532916010263, 34419.692748443973, 34437.854976475966, 34456.01959947445, 34474.18661680806, 34492.356027845817, 34510.527831957188, 34528.702028512052, 34546.878616880676, 34565.05759643377, 34583.238966542449, 34601.422726578232, 34619.608875913065, 34637.797413919296, 34655.988339969692, 34674.181653437423, 34692.37735369608, 34710.575440119668, 34728.775912082579, 34746.978768959649, 34765.184010126082, 34783.391634957537, 34801.60164283005, 34819.814033120063, 34838.028805204456, 34856.24595846048, 34874.465492265823, 34892.687405998557, 34910.911699037177, 34929.138370760564, 34947.367420548027, 34965.598847779271, 34983.832651834389, 35002.068832093908, 35020.307387938738, 35038.548318750189, 35056.79162390998, 35075.03730280025, 35093.285354803513, 35111.535779302685, 35129.788575681116, 35148.043743322516, 35166.301281611013, 35184.561189931141, 35202.823467667826, 35221.088114206388, 35239.355128932555, 35257.624511232447, 35275.896260492584, 35294.170376099886, 35312.446857441668, 35330.725703905628, 35349.006914879887, 35367.290489752944, 35385.576427913686, 35403.864728751418, 35422.155391655811, 35440.448416016967, 35458.743801225341, 35477.041546671804, 35495.341651747622, 35513.644115844436, 35531.948938354304, 35550.256118669655, 35568.565656183309, 35586.877550288496, 35605.191800378816, 35623.508405848268, 35641.827366091238, 35660.148680502505, 35678.472348477233, 35696.798369410979, 35715.126742699678, 35733.457467739659, 35751.790543927644, 35770.125970660738, 35788.46374733642, 35806.803873352568, 35825.146348107453, 35843.49117099971, 35861.838341428367, 35880.187858792851, 35898.539722492955, 35916.893931928862, 35935.250486501129, 35953.609385610718, 35971.970628658957, 35990.334215047558, 36008.700144178612, 36027.068415454596, 36045.439028278372, 36063.811982053165, 36082.187276182609, 36100.564910070694, 36118.944883121789, 36137.327194740654, 36155.711844332429, 36174.098831302617, 36192.488155057115, 36210.87981500219, 36229.273810544473, 36247.670141091003, 36266.068806049167, 36284.469804826738, 36302.873136831862, 36321.278801473069, 36339.686798159251, 36358.097126299683, 36376.509785304013, 36394.924774582258, 36413.342093544816, 36431.761741602444, 36450.183718166292, 36468.608022647859, 36487.034654459028, 36505.463613012063, 36523.894897719583, 36542.328507994578, 36560.764443250409, 36579.202702900831, 36597.643286359926, 36616.086193042182, 36634.531422362437, 36652.978973735895, 36671.428846578143, 36689.881040305125, 36708.335554333149, 36726.792388078902, 36745.251540959427, 36763.713012392138, 36782.176801794812, 36800.642908585593, 36819.111332182983, 36837.582072005869, 36856.055127473483, 36874.530498005421, 36893.008183021651, 36911.488181942506, 36929.970494188674, 36948.455119181206, 36966.942056341519, 36985.431305091392, 37003.922864852961, 37022.416735048733, 37040.912915101559, 37059.411404434657, 37077.91220247162, 37096.415308636388, 37114.920722353243, 37133.428443046862, 37151.938470142253, 37170.450803064785, 37188.965441240209, 37207.482384094597, 37226.001631054402, 37244.523181546429, 37263.047034997842, 37281.573190836149, 37300.101648489224, 37318.632407385296, 37337.165466952945, 37355.700826621112, 37374.238485819085, 37392.778443976509, 37411.320700523385, 37429.865254890057, 37448.412106507232, 37466.961254805974, 37485.512699217681, 37504.066439174116, 37522.622474107404, 37541.180803449992, 37559.741426634704, 37578.304343094693, 37596.869552263488, 37615.43705357494, 37634.006846463279, 37652.578930363044, 37671.153304709165, 37689.729968936896, 37708.308922481847, 37726.890164779965, 37745.473695267559, 37764.059513381275, 37782.647618558112, 37801.238010235415, 37819.830687850859, 37838.425650842495, 37857.022898648691, 37875.622430708172, 37894.224246460013, 37912.828345343616, 37931.434726798747, 37950.043390265506, 37968.654335184328, 37987.267560995999, 38005.883067141665, 38024.500853062775, 38043.120918201159, 38061.743261998963, 38080.367883898682, 38098.994783343158, 38117.623959775563, 38136.255412639417, 38154.889141378575, 38173.525145437234, 38192.163424259939, 38210.803977291551, 38229.446803977284, 38248.091903762703, 38266.739276093685, 38285.388920416466, 38304.040836177606, 38322.695022824002, 38341.351479802899, 38360.010206561863, 38378.671202548816, 38397.334467211993, 38415.999999999978, 38434.667800361683, 38453.33786774637, 38472.010201603611, 38490.684801383337, 38509.361666535784, 38528.040796511552, 38546.722190761553, 38565.405848737035, 38584.091769889594, 38602.779953671132, 38621.470399533908, 38640.163106930493, 38658.858075313794, 38677.555304137059, 38696.254792853862, 38714.956540918094, 38733.660547783991, 38752.366812906112, 38771.075335739348, 38789.78611573892, 38808.499152360368, 38827.214445059573, 38845.931993292739, 38864.651796516388, 38883.373854187383, 38902.098165762916, 38920.824730700486, 38939.553548457938, 38958.284618493431, 38977.017940265461, 38995.753513232834, 39014.491336854699, 39033.231410590517, 39051.973733900079, 39070.718306243485, 39089.465127081188, 39108.214195873945, 39126.965512082832, 39145.719075169261, 39164.474884594965, 39183.232939821988, 39201.99324031271, 39220.755785529815, 39239.52057493633, 39258.287607995589, 39277.056884171245, 39295.828402927284, 39314.602163728006, 39333.378166038019, 39352.15640932227, 39370.936893046004, 39389.719616674811, 39408.504579674584, 39427.291781511522, 39446.081221652174, 39464.872899563372, 39483.666814712291, 39502.462966566411, 39521.261354593538, 39540.06197826178, 39558.864837039568, 39577.669930395656, 39596.47725779911, 39615.286818719302, 39634.098612625923, 39652.912638988993, 39671.728897278823, 39690.547386966064, 39709.368107521652, 39728.191058416858, 39747.016239123259, 39765.84364911275, 39784.673287857528, 39803.505154830105, 39822.339249503319, 39841.175571350293, 39860.014119844491, 39878.854894459677, 39897.697894669909, 39916.54311994958, 39935.390569773372, 39954.240243616303, 39973.092140953675, 39991.946261261117, 40010.802604014549, 40029.661168690225, 40048.521954764678, 40067.384961714779, 40086.250189017679, 40105.117636150855, 40123.98730259209, 40142.859187819471, 40161.733291311379, 40180.609612546526, 40199.488151003912, 40218.368906162854, 40237.25187750296, 40256.137064504153, 40275.024466646668, 40293.914083411029, 40312.805914278084, 40331.699958728961, 40350.596216245103, 40369.494686308273, 40388.39536840051, 40407.298262004173, 40426.20336660192, 40445.110681676706, 40464.020206711793, 40482.931941190756, 40501.845884597446, 40520.762036416032, 40539.680396130985, 40558.600963227072, 40577.523737189367, 40596.448717503234, 40615.375903654342, 40634.305295128659, 40653.236891412453, 40672.170691992294, 40691.106696355047, 40710.044903987873, 40728.985314378238, 40747.927927013901, 40766.872741382918, 40785.819756973651, 40804.768973274746, 40823.720389775161, 40842.674005964131, 40861.629821331211, 40880.587835366234, 40899.548047559321, 40918.510457400931, 40937.475064381761, 40956.441867992849, 40975.410867725499, 40994.382063071331, 41013.355453522236, 41032.331038570417, 41051.308817708363, 41070.288790428858, 41089.270956224987, 41108.255314590111, 41127.241865017888, 41146.23060700229, 41165.221540037543, 41184.214663618193, 41203.209977239079, 41222.207480395307, 41241.207172582297, 41260.209053295752, 41279.213122031659, 41298.219378286303, 41317.227821556255, 41336.23845133838, 41355.251267129832, 41374.266268428037, 41393.283454730743, 41412.302825535953, 41431.324380341983, 41450.348118647416, 41469.374039951144, 41488.402143752326, 41507.432429550427, 41526.464896845187, 41545.499545136627, 41564.536373925075, 41583.575382711126, 41602.616570995662, 41621.659938279874, 41640.705484065205, 41659.753207853406, 41678.803109146495, 41697.855187446803, 41716.909442256911, 41735.965873079709, 41755.02447941836, 41774.085260776315, 41793.148216657297, 41812.213346565331, 41831.280650004708, 41850.350126480014, 41869.421775496106, 41888.495596558132, 41907.571589171515, 41926.649752841957, 41945.730087075463, 41964.812591378286, 41983.897265256979, 42002.984108218378, 42022.073119769593, 42041.164299418015, 42060.257646671307, 42079.353161037419, 42098.450842024591, 42117.550689141324, 42136.652701896404, 42155.756879798893, 42174.863222358137, 42193.971729083758, 42213.082399485655, 42232.195233074002, 42251.310229359246, 42270.427387852127, 42289.546708063644, 42308.668189505079, 42327.791831687995, 42346.917634124227, 42366.045596325886, 42385.175717805352, 42404.307998075295, 42423.442436648642, 42442.579033038608, 42461.717786758672, 42480.858697322597, 42500.001764244422, 42519.146987038446, 42538.294365219248, 42557.443898301688, 42576.595585800882, 42595.749427232236, 42614.90542211142, 42634.063569954378, 42653.223870277317, 42672.386322596729, 42691.55092642938, 42710.717681292292, 42729.886586702756, 42749.057642178363, 42768.23084723694, 42787.406201396603, 42806.58370417574, 42825.76335509299, 42844.945153667286, 42864.129099417805, 42883.315191864014, 42902.503430525649, 42921.693814922692, 42940.88634457541, 42960.081019004348, 42979.277837730297, 42998.476800274322, 43017.677906157769, 43036.881154902228, 43056.086546029583, 43075.294079061961, 43094.503753521763, 43113.715568931671, 43132.929524814601, 43152.145620693766, 43171.363856092619, 43190.584230534907, 43209.806743544621, 43229.031394646016, 43248.258183363621, 43267.487109222224, 43286.718171746885, 43305.951370462906, 43325.186704895881, 43344.42417457165, 43363.663779016322, 43382.905517756262, 43402.149390318104, 43421.395396228749, 43440.643535015348, 43459.89380620532, 43479.146209326354, 43498.400743906379, 43517.657409473606, 43536.916205556496, 43556.177131683784, 43575.44018738444, 43594.705372187724, 43613.972685623135, 43633.242127220445, 43652.513696509668, 43671.787393021099, 43691.063216285271, 43710.341165833001, 43729.621241195346, 43748.903441903625, 43768.187767489413, 43787.474217484552, 43806.762791421126, 43826.053488831501, 43845.346309248278, 43864.641252204325, 43883.938317232765, 43903.237503866971, 43922.538811640596, 43941.842240087513, 43961.147788741881, 43980.455457138101, 43999.765244810835, 44019.077151295001, 44038.391176125755, 44057.70731883854, 44077.02557896902, 44096.345956053141, 44115.668449627083, 44134.993059227287, 44154.319784390456, 44173.648624653535, 44192.979579553728, 44212.312648628489, 44231.647831415532, 44250.985127452805, 44270.324536278538, 44289.666057431183, 44309.009690449464, 44328.355434872348, 44347.703290239064, 44367.053256089079, 44386.405331962109, 44405.759517398139, 44425.115811937387, 44444.474215120332, 44463.834726487694, 44483.197345580462, 44502.562071939843, 44521.928905107328, 44541.297844624634, 44560.668890033732, 44580.042040876848, 44599.417296696454, 44618.794657035272, 44638.174121436256, 44657.555689442641, 44676.939360597877, 44696.325134445673, 44715.713010530002, 44735.102988395054, 44754.495067585296, 44773.88924764542, 44793.285528120374, 44812.683908555344, 44832.084388495779, 44851.486967487363, 44870.891645076015, 44890.298420807922, 44909.707294229491, 44929.118264887409, 44948.531332328566, 44967.946496100136, 44987.363755749502, 45006.783110824319, 45026.204560872473, 45045.628105442098, 45065.053744081561, 45084.48147633949, 45103.911301764747, 45123.343219906426, 45142.777230313885, 45162.21333253671, 45181.651526124733, 45201.091810628037, 45220.534185596924, 45239.978650581965, 45259.425205133957, 45278.873848803938, 45298.324581143192, 45317.777401703235, 45337.232310035848, 45356.68930569302, 45376.148388226997, 45395.60955719027, 45415.072812135557, 45434.538152615823, 45454.005578184282, 45473.475088394356, 45492.946682799746, 45512.420360954362, 45531.896122412363, 45551.373966728155, 45570.853893456362, 45590.33590215187, 45609.819992369776, 45629.306163665438, 45648.794415594442, 45668.284747712612, 45687.777159576006, 45707.27165074092, 45726.768220763894, 45746.266869201696, 45765.767595611323, 45785.270399550034, 45804.775280575297, 45824.282238244828, 45843.79127211657, 45863.302381748719, 45882.815566699683, 45902.33082652813, 45921.848160792935, 45941.367569053225, 45960.889050868354, 45980.41260579793, 45999.938233401757, 46019.465933239902, 46038.995704872657, 46058.527547860547, 46078.06146176433, 46097.597446144995, 46117.135500563774, 46136.675624582109, 46156.217817761702, 46175.762079664462, 46195.308409852543, 46214.856807888333, 46234.407273334444, 46253.959805753715, 46273.51440470924, 46293.071069764315, 46312.629800482478, 46332.190596427499, 46351.753457163381, 46371.318382254351, 46390.885371264863, 46410.45442375962, 46430.025539303526, 46449.598717461733, 46469.17395779962, 46488.751259882782, 46508.33062327707, 46527.912047548532, 46547.495532263471, 46567.081076988397, 46586.668681290059, 46606.258344735434, 46625.850066891719, 46645.443847326351, 46665.039685606986, 46684.637581301497, 46704.237533978005, 46723.839543204842, 46743.443608550573, 46763.049729583989, 46782.657905874104, 46802.268136990162, 46821.880422501628, 46841.494761978196, 46861.111154989776, 46880.729601106526, 46900.350099898795, 46919.97265093719, 46939.597253792526, 46959.223908035841, 46978.852613238392, 46998.483368971691, 47018.11617480743, 47037.751030317551, 47057.387935074221, 47077.026888649809, 47096.66789061694, 47116.310940548428, 47135.956038017328, 47155.603182596918, 47175.252373860698, 47194.903611382375, 47214.556894735892, 47234.212223495422, 47253.869597235338, 47273.52901553025, 47293.19047795498, 47312.853984084577, 47332.519533494306, 47352.187125759658, 47371.856760456343, 47391.528437160297, 47411.202155447652, 47430.877914894787, 47450.555715078299, 47470.235555574982, 47489.917435961863, 47509.601355816201, 47529.287314715453, 47548.975312237308, 47568.665347959672, 47588.357421460656, 47608.051532318605, 47627.747680112072, 47647.445864419846, 47667.14608482091, 47686.848340894474, 47706.552632219973, 47726.258958377046, 47745.967318945557, 47765.677713505589, 47785.390141637428, 47805.104602921601, 47824.821096938824, 47844.539623270044, 47864.260181496429, 47883.982771199349, 47903.707391960394, 47923.434043361369, 47943.162724984308, 47962.893436411439, 47982.626177225218, 48002.36094700831, 48022.097745343599, 48041.836571814172, 48061.57742600335, 48081.32030749465, 48101.065215871815, 48120.81215071879, 48140.56111161974, 48160.312098159047, 48180.065109921306, 48199.820146491307, 48219.577207454073, 48239.336292394844, 48259.097400899045, 48278.860532552339, 48298.625686940592, 48318.392863649875, 48338.162062266485, 48357.933282376915, 48377.706523567889, 48397.481785426316, 48417.259067539344, 48437.038369494308, 48456.819690878765, 48476.603031280487, 48496.388390287451, 48516.175767487839, 48535.965162470042, 48555.756574822684, 48575.550004134566, 48595.345449994718, 48615.142911992378, 48634.942389716991, 48654.743882758201, 48674.547390705877, 48694.352913150084, 48714.160449681112, 48733.969999889443, 48753.781563365759, 48773.595139700978, 48793.410728486211, 48813.228329312769, 48833.047941772187, 48852.869565456189, 48872.693199956717, 48892.518844865925, 48912.346499776155, 48932.176164279976, 48952.007837970152, 48971.841520439666, 48991.677211281676, 49011.514910089587, 49031.354616456978, 49051.196329977654, 49071.04005024561, 49090.885776855059, 49110.733509400408, 49130.583247476279, 49150.434990677488, 49170.288738599062, 49190.144490836232, 49210.002246984441, 49229.86200663932, 49249.723769396718, 49269.587534852675, 49289.453302603448, 49309.32107224549, 49329.190843375451, 49349.062615590192, 49368.936388486785, 49388.812161662492, 49408.689934714785, 49428.569707241324, 49448.45147883999, 49468.335249108866, 49488.22101764621, 49508.108784050521, 49527.99854792047, 49547.890308854934, 49567.784066453009, 49587.679820313977, 49607.57757003732, 49627.477315222721, 49647.379055470075, 49667.28279037946, 49687.188519551179, 49707.096242585707, 49727.005959083741, 49746.917668646165, 49766.831370874068, 49786.747065368734, 49806.66475173166, 49826.584429564515, 49846.506098469203, 49866.429758047794, 49886.355407902578, 49906.283047636032, 49926.212676850846, 49946.144295149883, 49966.077902136225, 49986.013497413151, 50005.951080584135, 50025.890651252834, 50045.832209023123, 50065.775753499074, 50085.721284284933, 50105.668800985164, 50125.618303204428, 50145.569790547575, 50165.523262619652, 50185.478719025901, 50205.436159371769, 50225.395583262893, 50245.356990305103, 50265.320380104429, 50285.285752267104, 50305.253106399534, 50325.222442108337, 50345.193759000336, 50365.16705668252, 50385.142334762102, 50405.119592846473, 50425.098830543218, 50445.080047460127, 50465.063243205179, 50485.048417386541, 50505.035569612577, 50525.024699491856, 50545.015806633128, 50565.008890645338, 50585.003951137631, 50605.00098771933, 50624.999999999971, 50645.000987589265, 50665.003950097132, 50685.008887133677, 50705.015798309192, 50725.024683234165, 50745.035541519283, 50765.048372775411, 50785.063176613621, 50805.079952645159, 50825.098700481489, 50845.119419734241, 50865.142110015244, 50885.166770936521, 50905.193402110279, 50925.222003148934, 50945.252573665071, 50965.285113271471, 50985.319621581119, 51005.356098207172, 51025.394542762981, 51045.434954862096, 51065.477334118244, 51085.521680145357, 51105.567992557546, 51125.616270969113, 51145.66651499454, 51165.718724248516, 51185.772898345916, 51205.829036901778, 51225.887139531362, 51245.947205850105, 51266.009235473619, 51286.073228017718, 51306.139183098399, 51326.207100331856, 51346.276979334456, 51366.348819722756, 51386.42262111351, 51406.498383123653, 51426.57610537031, 51446.655787470787, 51466.737429042587, 51486.82102970338, 51506.906589071048, 51526.994106763632, 51547.083582399391, 51567.175015596738, 51587.268405974297, 51607.363753150858, 51627.461056745415, 51647.56031637713, 51667.661531665362, 51687.764702229651, 51707.869827689727, 51727.976907665499, 51748.085941777055, 51768.196929644677, 51788.309870888836, 51808.42476513017, 51828.541611989524, 51848.660411087905, 51868.781162046515, 51888.90386448674, 51909.028518030143, 51929.155122298485, 51949.283676913685, 51969.414181497872, 51989.546635673345, 52009.681039062583, 52029.817391288263, 52049.955691973213, 52070.095940740481, 52090.238137213273, 52110.382281014987, 52130.5283717692, 52150.676409099666, 52170.826392630333, 52190.97832198532, 52211.132196788931, 52231.288016665654, 52251.445781240145, 52271.60549013727, 52291.76714298204, 52311.930739399664, 52332.096279015546, 52352.263761455244, 52372.433186344519, 52392.604553309284, 52412.777861975665, 52432.953111969946, 52453.130302918595, 52473.309434448267, 52493.490506185793, 52513.67351775818, 52533.858468792605, 52554.045358916446, 52574.234187757254, 52594.42495494274, 52614.617660100812, 52634.812302859558, 52655.008882847229, 52675.20739969227, 52695.407853023295, 52715.610242469098, 52735.814567658657, 52756.02082822111, 52776.229023785803, 52796.439153982225, 52816.651218440056, 52836.865216789171, 52857.081148659599, 52877.29901368155, 52897.518811485425, 52917.740541701773, 52937.964203961354, 52958.18979789508, 52978.417323134046, 52998.646779309529, 53018.878166052978, 53039.111482996006, 53059.346729770419, 53079.583906008193, 53099.823011341483, 53120.0640454026, 53140.307007824063, 53160.551898238533, 53180.79871627887, 53201.047461578091, 53221.2981337694, 53241.550732486176, 53261.805257361964, 53282.061708030487, 53302.32008412564, 53322.580385281493, 53342.842611132299, 53363.106761312469, 53383.372835456597, 53403.640833199453, 53423.910754175973, 53444.18259802126, 53464.456364370613, 53484.732052859479, 53505.009663123499, 53525.289194798468, 53545.570647520362, 53565.854020925333, 53586.139314649699, 53606.426528329954, 53626.715661602764, 53647.006714104959, 53667.299685473547, 53687.59457534572, 53707.891383358816, 53728.190109150361, 53748.490752358055, 53768.793312619753, 53789.09778957349, 53809.404182857485, 53829.712492110106, 53850.022716969899, 53870.334857075584, 53890.648912066055, 53910.964881580367, 53931.28276525774, 53951.602562737586, 53971.924273659461, 53992.24789766311, 54012.57343438844, 54032.90088347553, 54053.23024456462, 54073.561517296133, 54093.894701310644, 54114.22979624891, 54134.566801751855, 54154.90571746057, 54175.246543016314, 54195.589278060506, 54215.933922234755, 54236.280475180814, 54256.628936540626, 54276.97930595628, 54297.331583070045, 54317.685767524359, 54338.041858961828, 54358.399857025215, 54378.759761357462, 54399.121571601667, 54419.485287401105, 54439.850908399218, 54460.218434239614, 54480.587864566056, 54500.95919902248, 54521.332437252997, 54541.707578901878, 54562.084623613555, 54582.46357103264, 54602.844420803893, 54623.227172572246, 54643.611825982807, 54663.998380680838, 54684.386836311773, 54704.777192521207, 54725.169448954897, 54745.563605258772, 54765.959661078923, 54786.357616061614, 54806.757469853255, 54827.159222100439, 54847.562872449904, 54867.968420548583, 54888.375866043534, 54908.785208582012, 54929.196447811417, 54949.609583379322, 54970.024614933463, 54990.441542121727, 55010.86036459219, 55031.28108199306, 55051.703693972733, 55072.128200179759, 55092.554600262847, 55112.982893870874, 55133.413080652877, 55153.845160258061, 55174.279132335789, 55194.714996535586, 55215.152752507143, 55235.592399900306, 55256.033938365079, 55276.477367551655, 55296.92268711036, 55317.369896691685, 55337.818995946305, 55358.269984525024, 55378.72286207883, 55399.177628258869, 55419.634282716441, 55440.092825103013, 55460.553255070205, 55481.015572269804, 55501.479776353764, 55521.945866974187, 55542.413843783339, 55562.883706433655, 55583.355454577715, 55603.82908786826, 55624.304605958219, 55644.782008500639, 55665.261295148754, 55685.742465555952, 55706.225519375774, 55726.710456261928, 55747.197275868275, 55767.685977848843, 55788.176561857814, 55808.669027549528, 55829.163374578478, 55849.659602599328, 55870.157711266889, 55890.657700236145, 55911.159569162221, 55931.663317700411, 55952.168945506164, 55972.676452235086, 55993.185837542944, 56013.697101085651, 56034.210242519301, 56054.72526150012, 56075.242157684508, 56095.760930729011, 56116.281580290342, 56136.804106025367, 56157.328507591104, 56177.85478464474, 56198.382936843598, 56218.912963845185, 56239.444865307138, 56259.978640887268, 56280.514290243525, 56301.051813034042, 56321.591208917082, 56342.13247755108, 56362.675618594607, 56383.220631706419, 56403.767516545398, 56424.316272770608, 56444.866900041241, 56465.419398016667, 56485.973766356394, 56506.530004720102, 56527.088112767611, 56547.648090158902, 56568.209936554107, 56588.773651613519, 56609.339234997584, 56629.9066863669, 56650.47600538221, 56671.04719170442, 56691.620244994599, 56712.195164913959, 56732.771951123868, 56753.350603285835, 56773.931121061541, 56794.513504112823, 56815.097752101647, 56835.683864690152, 56856.271841540627, 56876.86168231551, 56897.453386677393, 56918.046954289028, 56938.642384813298, 56959.239677913261, 56979.838833252121, 57000.439850493225, 57021.04272930009, 57041.647469336371, 57062.254070265873, 57082.862531752558, 57103.472853460553, 57124.085035054108, 57144.699076197649, 57165.314976555739, 57185.932735793103, 57206.552353574611, 57227.173829565276, 57247.797163430281, 57268.42235483494, 57289.049403444733, 57309.678308925286, 57330.30907094237, 57350.941689161911, 57371.576163249985, 57392.212492872815, 57412.850677696784, 57433.490717388406, 57454.132611614368, 57474.776360041491, 57495.421962336746, 57516.069418167266, 57536.718727200314, 57557.36988910332, 57578.022903543861, 57598.677770189643, 57619.334488708548, 57639.993058768589, 57660.653480037938, 57681.315752184906, 57701.979874877965, 57722.64584778573, 57743.31367057695, 57763.983342920546, 57784.654864485572, 57805.328234941233, 57826.003453956881, 57846.680521202026, 57867.359436346305, 57888.040199059527, 57908.722809011633, 57929.407265872709, 57950.093569313001, 57970.781719002895, 57991.471714612911, 58012.16355581375, 58032.857242276223, 58053.552773671312, 58074.25014967013, 58094.949369943948, 58115.650434164185, 58136.353342002389, 58157.058093130276, 58177.764687219693, 58198.47312394264, 58219.183402971255, 58239.895523977837, 58260.609486634821, 58281.325290614775, 58302.042935590434, 58322.762421234678, 58343.483747220511, 58364.206913221096, 58384.931918909751, 58405.658763959924, 58426.3874480452, 58447.117970839339, 58467.85033201622, 58488.584531249864, 58509.320568214462, 58530.058442584334, 58550.798154033931, 58571.539702237875, 58592.283086870906, 58613.028307607929, 58633.775364123983, 58654.52425609425, 58675.274983194053, 58696.027545098877, 58716.781941484325, 58737.538172026158, 58758.296236400274, 58779.056134282728, 58799.817865349694, 58820.581429277503, 58841.346825742643, 58862.114054421712, 58882.883114991484, 58903.654007128847, 58924.426730510851, 58945.201284814684, 58965.977669717664, 58986.755884897269, 59007.535930031117, 59028.317804796949, 59049.101508872664, 59069.887041936301, 59090.674403666046, 59111.463593740213, 59132.254611837263, 59153.047457635803, 59173.84213081457, 59194.638631052461, 59215.436958028506, 59236.237111421855, 59257.039090911829, 59277.842896177877, 59298.648526899589, 59319.455982756685, 59340.26526342905, 59361.076368596696, 59381.889297939757, 59402.704051138542, 59423.520627873484, 59444.339027825139, 59465.159250674224, 59485.9812961016, 59506.805163788253, 59527.630853415307, 59548.458364664046, 59569.287697215863, 59590.118850752311, 59610.951824955089, 59631.786619506012, 59652.623234087048, 59673.461668380311, 59694.301922068029, 59715.143994832593, 59735.987886356525, 59756.833596322482, 59777.681124413255, 59798.530470311794, 59819.381633701159, 59840.234614264569, 59861.089411685381, 59881.94602564707, 59902.804455833269, 59923.664701927737, 59944.526763614384, 59965.390640577243, 59986.256332500488, 60007.123839068438, 60027.993159965539, 60048.864294876381, 60069.737243485688, 60090.612005478324, 60111.488580539284, 60132.366968353708, 60153.247168606867, 60174.129180984164, 60195.013005171153, 60215.898640853513, 60236.786087717061, 60257.675345447751, 60278.566413731671, 60299.459292255044, 60320.353980704247, 60341.25047876576, 60362.148786126229, 60383.048902472423, 60403.950827491237, 60424.854560869717, 60445.76010229504, 60466.667451454516, 60487.57660803559, 60508.487571725847, 60529.400342212997, 60550.314919184893, 60571.231302329521, 60592.149491335003, 60613.069485889588, 60633.991285681674, 60654.914890399785, 60675.840299732568, 60696.767513368832, 60717.696530997484, 60738.627352307602, 60759.55997698837, 60780.494404729128, 60801.430635219323, 60822.368668148556, 60843.308503206565, 60864.250140083204, 60885.193578468468, 60906.138818052495, 60927.085858525541, 60948.034699578006, 60968.985340900421, 60989.937782183442, 61010.892023117864, 61031.848063394616, 61052.805902704764, 61073.765540739492, 61094.726977190134, 61115.690211748137, 61136.655244105103, 61157.622073952742, 61178.590700982917, 61199.561124887616, 61220.533345358948, 61241.507362089171, 61262.483174770663, 61283.460783095943, 61304.440186757645, 61325.421385448557, 61346.404378861582, 61367.389166689762, 61388.375748626262, 61409.364124364387, 61430.354293597571, 61451.346256019373, 61472.340011323497, 61493.335559203762, 61514.332899354122, 61535.332031468672, 61556.332955241618, 61577.335670367313, 61598.340176540238, 61619.346473454993, 61640.354560806329, 61661.3644382891, 61682.376105598312, 61703.389562429089, 61724.404808476691, 61745.42184343651, 61766.440667004063, 61787.461278874987, 61808.483678745069, 61829.507866310203, 61850.533841266435, 61871.561603309929, 61892.591152136971, 61913.622487443987, 61934.655608927525, 61955.690516284267, 61976.727209211022, 61997.765687404724, 62018.805950562448, 62039.847998381381, 62060.891830558845, 62081.93744679229, 62102.984846779298, 62124.034030217575, 62145.084996804966, 62166.137746239416, 62187.19227821903, 62208.248592442025, 62229.306688606739, 62250.366566411656, 62271.428225555377, 62292.491665736627, 62313.556886654267, 62334.623888007271, 62355.692669494762, 62376.763230815974, 62397.835571670272, 62418.909691757144, 62439.98559077621, 62461.063268427228, 62482.142724410049, 62503.223958424685, 62524.306970171267, 62545.39175935003, 62566.478325661366, 62587.566668805768, 62608.656788483881, 62629.748684396451, 62650.842356244357, 62671.937803728622, 62693.035026550366, 62714.134024410858, 62735.234797011479, 62756.337344053733, 62777.441665239276, 62798.547760269852, 62819.655628847358, 62840.765270673801, 62861.876685451323, 62882.989872882186, 62904.104832668774, 62925.221564513602, 62946.340068119309, 62967.460343188657, 62988.582389424526, 63009.70620652994, 63030.831794208025, 63051.959152162039, 63073.08828009537, 63094.219177711529, 63115.351844714154, 63136.486280806988, 63157.622485693922, 63178.760459078956, 63199.900200666219, 63221.041710159967, 63242.184987264569, 63263.330031684534, 63284.476843124474, 63305.625421289144, 63326.775765883409, 63347.927876612259, 63369.081753180813, 63390.237395294316, 63411.39480265812, 63432.553974977716, 63453.714911958712, 63474.877613306839, 63496.042078727944, 63517.208307927998, 63538.376300613119, 63559.546056489504, 63580.717575263516, 63601.890856641607, 63623.065900330374, 63644.242706036515, 63665.421273466869, 63686.601602328381, 63707.783692328136, 63728.967543173334, 63750.153154571279, 63771.340526229418, 63792.529657855317, 63813.720549156649, 63834.913199841227, 63856.107609616978, 63877.303778191941, 63898.501705274284, 63919.7013905723, 63940.902833794404, 63962.106034649114, 63983.310992845094, 64004.517708091109, 64025.726180096048, 64046.936408568938, 64068.1483932189, 64089.362133755196, 64110.577629887193, 64131.794881324393, 64153.013887776404, 64174.234648952966, 64195.457164563937, 64216.681434319289, 64237.907457929112, 64259.135235103626, 64280.36476555316, 64301.596048988169, 64322.829085119236, 64344.06387365704, 64365.300414312398, 64386.538706796251, 64407.778750819634, 64429.020546093721, 64450.26409232981, 64471.509389239291, 64492.756436533709, 64514.005233924705, 64535.255781124033, 64556.50807784358, 64577.762123795357, 64599.017918691468, 64620.275462244172, 64641.534754165805, 64662.795794168844, 64684.058581965895, 64705.323117269661, 64726.589399792974, 64747.857429248776, 64769.127205350138, 64790.398727810236, 64811.671996342375, 64832.947010659969, 64854.223770476558, 64875.502275505794, 64896.782525461451, 64918.064520057414, 64939.348259007682, 64960.633742026388, 64981.920968827762, 65003.209939126165, 65024.500652636067, 65045.793109072067, 65067.087308148861, 65088.383249581282, 65109.680933084259, 65130.980358372864, 65152.28152516226, 65173.584433167736, 65194.889082104703, 65216.195471688683, 65237.503601635319, 65258.813471660353, 65280.125081479666, 65301.438430809241, 65322.753519365178, 65344.070346863708, 65365.388913021146, 65386.709217553958, 65408.031260178701, 65429.355040612056, 65450.680558570821, 65472.00781377191, 65493.336805932355, 65514.66753476928, 65535.999999999956, 65557.334201341757, 65578.670138512171, 65600.007811228788, 65621.347219209332, 65642.688362171626, 65664.031239833639, 65685.375851913413, 65706.722198129137, 65728.070278199084, 65749.420091841661, 65770.771638775404, 65792.124918718939, 65813.479931391004, 65834.836676510458, 65856.195153796303, 65877.5553629676, 65898.917303743554, 65920.280975843489, 65941.646378986843, 65963.013512893158, 65984.382377282076, 66005.752971873386, 66027.125296386963, 66048.499350542799, 66069.875134061018, 66091.252646661844, 66112.631888065618, 66134.01285799277, 66155.395556163887, 66176.779982299631, 66198.166136120795, 66219.554017348273, 66240.943625703105, 66262.334960906388, 66283.728022679396, 66305.122810743444, 66326.519324820023, 66347.917564630698, 66369.317529897162, 66390.719220341227, 66412.122635684791, 66433.527775649884, 66454.934639958636, 66476.343228333324, 66497.753540496284, 66519.165576169995, 66540.57933507704, 66561.994816940118, 66583.412021482043, 66604.830948425733, 66626.251597494222, 66647.673968410629, 66669.098060898235, 66690.523874680381, 66711.951409480564, 66733.380665022371, 66754.811641029475, 66776.244337225711, 66797.678753334985, 66819.11488908132, 66840.552744188884, 66861.992318381905, 66883.433611384738, 66904.876622921889, 66926.321352717903, 66947.767800497502, 66969.215965985466, 66990.665848906734, 67012.117448986304, 67033.570765949335, 67055.025799521056, 67076.482549426815, 67097.941015392076, 67119.401197142433, 67140.863094403554, 67162.326706901222, 67183.792034361351, 67205.259076509959, 67226.72783307315, 67248.198303777172, 67269.670488348347, 67291.144386513144, 67312.619997998088, 67334.09732252988, 67355.576359835293, 67377.057109641188, 67398.53957167457, 67420.023745662547, 67441.50963133233, 67462.99722841123, 67484.486536626689, 67505.977555706224, 67527.470285377494, 67548.964725368263, 67570.460875406367, 67591.9587352198, 67613.458304536631, 67634.95958308503, 67656.462570593329, 67677.967266789899, 67699.473671403248, 67720.981784162024, 67742.491604794923, 67764.003133030797, 67785.516368598575, 67807.031311227314, 67828.547960646174, 67850.066316584402, 67871.58637877139, 67893.108146936589, 67914.63162080961, 67936.156800120138, 67957.683684597971, 67979.212273973011, 68000.742567975263, 68022.274566334876, 68043.808268782057, 68065.343675047145, 68086.880784860579, 68108.419597952918, 68129.960114054789, 68151.502332896969, 68173.04625421032, 68194.591877725834, 68216.139203174564, 68237.688230287706, 68259.238958796544, 68280.791388432481, 68302.345518927032, 68323.901350011787, 68345.458881418483, 68367.018112878912, 68388.579044125028, 68410.141674888844, 68431.706004902502, 68453.272033898262, 68474.839761608455, 68496.409187765545, 68517.980312102081, 68539.553134350732, 68561.127654244279, 68582.70387151558, 68604.281785897634, 68625.861397123503, 68647.44270492639, 68669.025709039604, 68690.610409196524, 68712.196805130661, 68733.784896575627, 68755.374683265123, 68776.966164932994, 68798.559341313128, 68820.154212139591, 68841.750777146473, 68863.349036068044, 68884.948988638629, 68906.550634592684, 68928.153973664739, 68949.75900558944, 68971.365730101577, 68992.974146935987, 69014.584255827634, 69036.196056511588, 69057.809548723017, 69079.424732197207, 69101.041606669532, 69122.660171875468, 69144.280427550606, 69165.902373430625, 69187.526009251334, 69209.151334748618, 69230.778349658474, 69252.40705371699, 69274.037446660412, 69295.669528225, 69317.303298147192, 69338.938756163494, 69360.575902010532, 69382.214735425005, 69403.855256143754, 69425.497463903681, 69447.141358441833, 69468.78693949533, 69490.434206801394, 69512.083160097391, 69533.733799120717, 69555.386123608929, 69577.04013329967, 69598.695827930685, 69620.353207239794, 69642.012270964973, 69663.67301884426, 69685.335450615792, 69706.999566017839, 69728.665364788743, 69750.332846666963, 69772.002011391058, 69793.672858699691, 69815.345388331611, 69837.019600025669, 69858.695493520849, 69880.373068556204, 69902.052324870907, 69923.733262204216, 69945.415880295492, 69967.100178884211, 69988.786157709939, 70010.473816512356, 70032.163155031216, 70053.854173006403, 70075.546870177874, 70097.241246285717, 70118.937301070109, 70140.635034271298, 70162.334445629691, 70184.035534885741, 70205.738301780017, 70227.442746053217, 70249.1488674461, 70270.856665699539, 70292.566140554511, 70314.277291752107, 70335.990119033493, 70357.704622139936, 70379.420800812819, 70401.138654793613, 70422.85818382389, 70444.579387645339, 70466.302265999722, 70488.026818628918, 70509.753045274876, 70531.480945679708, 70553.210519585555, 70574.941766734701, 70596.674686869505, 70618.409279732456, 70640.145545066101, 70661.883482613106, 70683.623092116264, 70705.364373318414, 70727.107325962526, 70748.851949791671, 70770.598244549008, 70792.346209977783, 70814.095845821372, 70835.847151823225, 70857.600127726895, 70879.354773276034, 70901.111088214413, 70922.869072285859, 70944.628725234332, 70966.390046803877, 70988.153036738629, 71009.917694782853, 71031.684020680885, 71053.45201417715, 71075.221675016204, 71096.993002942661, 71118.765997701266, 71140.540659036851, 71162.316986694335, 71184.09498041874, 71205.874639955218, 71227.655965048951, 71249.438955445294, 71271.223610889632, 71293.009931127483, 71314.797915904477, 71336.587564966307, 71358.378878058764, 71380.171854927772, 71401.966495319313, 71423.762798979486, 71445.560765654489, 71467.360395090596, 71489.161687034211, 71510.964641231811, 71532.769257429973, 71554.575535375348, 71576.383474814749, 71598.19307549503, 71620.004337163133, 71641.817259566145, 71663.631842451214, 71685.4480855656, 71707.26598865664, 71729.085551471784, 71750.906773758586, 71772.729655264673, 71794.554195737772, 71816.380394925713, 71838.208252576442, 71860.037768437964, 71881.868942258385, 71903.701773785942, 71925.536262768932, 71947.372408955751, 71969.210212094898, 71991.049671934976, 72012.890788224686, 72034.73356071279, 72056.577989148165, 72078.424073279821, 72100.271812856794, 72122.121207628254, 72143.97225734347, 72165.824961751801, 72187.679320602692, 72209.53533364569, 72231.393000630429, 72253.252321306645, 72275.113295424177, 72296.975922732949, 72318.840202982959, 72340.706135924338, 72362.573721307272, 72384.442958882093, 72406.313848399179, 72428.186389609036, 72450.060582262216, 72471.936426109431, 72493.813920901433, 72515.693066389096, 72537.573862323392, 72559.456308455352, 72581.340404536139, 72603.226150316987, 72625.113545549248, 72647.002589984331, 72668.893283373764, 72690.785625469172, 72712.679616022273, 72734.575254784853, 72756.472541508803, 72778.371475946144, 72800.272057848939, 72822.174286969355, 72844.07816305969, 72865.983685872285, 72887.890855159596, 72909.799670674183, 72931.710132168693, 72953.622239395845, 72975.535992108475, 72997.451390059519, 73019.368433001961, 73041.287120688925, 73063.207452873612, 73085.129429309294, 73107.053049749389, 73128.978313947344, 73150.905221656736, 73172.833772631217, 73194.763966624567, 73216.695803390612, 73238.62928268328, 73260.564404256627, 73282.501167864757, 73304.439573261901, 73326.379620202337, 73348.321308440485, 73370.264637730841, 73392.209607827957, 73414.156218486532, 73436.104469461323, 73458.054360507173, 73480.005891379056, 73501.959061831993, 73523.913871621116, 73545.870320501665, 73567.828408228932, 73589.78813455833, 73611.749499245358, 73633.712502045615, 73655.677142714747, 73677.643421008557, 73699.611336682879, 73721.580889493693, 73743.552079197019, 73765.524905548999, 73787.499368305856, 73809.475467223907, 73831.453202059551, 73853.432572569291, 73875.413578509717, 73897.396219637507, 73919.380495709411, 73941.36640648231, 73963.353951713143, 73985.343131158952, 74007.333944576865, 74029.326391724098, 74051.320472357969, 74073.316186235883, 74095.313533115303, 74117.312512753837, 74139.313124909138, 74161.315369338976, 74183.319245801191, 74205.324754053727, 74227.331893854629, 74249.340664961986, 74271.351067134034, 74293.363100129049, 74315.376763705441, 74337.392057621662, 74359.408981636298, 74381.427535508003, 74403.447718995507, 74425.469531857671, 74447.492973853383, 74469.518044741693, 74491.54474428168, 74513.573072232539, 74535.603028353551, 74557.634612404087, 74579.667824143602, 74601.702663331642, 74623.739129727837, 74645.777223091936, 74667.816943183716, 74689.858289763113, 74711.901262590094, 74733.945861424741, 74755.992086027225, 74778.039936157802, 74800.089411576817, 74822.140512044702, 74844.193237321961, 74866.24758716923, 74888.303561347187, 74910.36115961663, 74932.420381738411, 74954.481227473516, 74976.543696582972, 74998.607788827925, 75020.673503969607, 75042.740841769322, 75064.809801988464, 75086.88038438854, 75108.952588731103, 75131.026414777836, 75153.101862290467, 75175.178931030852, 75197.257620760924, 75219.33793124267, 75241.419862238225, 75263.503413509738, 75285.588584819503, 75307.675375929874, 75329.763786603318, 75351.853816602365, 75373.945465689612, 75396.038733627807, 75418.133620179724, 75440.230125108254, 75462.32824817636, 75484.427989147109, 75506.529347783653, 75528.63232384919, 75550.736917107075, 75572.843127320695, 75594.950954253538, 75617.060397669193, 75639.171457331307, 75661.284133003646, 75683.398424450032, 75705.514331434402, 75727.631853720741, 75749.750991073175, 75771.871743255862, 75793.994110033076, 75816.118091169177, 75838.243686428585, 75860.370895575848, 75882.499718375562, 75904.630154592422, 75926.762203991224, 75948.895866336825, 75971.031141394182, 75993.168028928325, 76015.306528704401, 76037.4466404876, 76059.588364043215, 76081.731699136653, 76103.876645533353, 76126.023202998884, 76148.171371298871, 76170.321150199044, 76192.472539465205, 76214.625538863256, 76236.780148159174, 76258.936367119008, 76281.094195508922, 76303.253633095141, 76325.414679643975, 76347.577334921851, 76369.741598695226, 76391.907470730686, 76414.074950794879, 76436.244038654564, 76458.414734076548, 76480.587036827754, 76502.760946675175, 76524.936463385893, 76547.11358672705, 76569.292316465915, 76591.472652369819, 76613.654594206164, 76635.838141742468, 76658.023294746308, 76680.210052985349, 76702.398416227341, 76724.588384240138, 76746.779956791637, 76768.973133649866, 76791.167914582897, 76813.364299358902, 76835.562287746157, 76857.761879512967, 76879.963074427797, 76902.165872259109, 76924.37027277553, 76946.576275745727, 76968.783880938441, 76990.993088122515, 77013.203897066895, 77035.416307540567, 77057.630319312622, 77079.845932152239, 77102.063145828695, 77124.281960111301, 77146.50237476948, 77168.724389572759, 77190.948004290723, 77213.173218693031, 77235.400032549442, 77257.628445629802, 77279.858457704031, 77302.090068542122, 77324.323277914169, 77346.558085590339, 77368.794491340886, 77391.032494936138, 77413.272096146524, 77435.51329474253, 77457.756090494731, 77480.000483173804, 77502.246472550498, 77524.494058395634, 77546.743240480107, 77568.994018574944, 77591.246392451198, 77613.500361880026, 77635.755926632657, 77658.013086480438, 77680.271841194757, 77702.532190547092, 77724.794134309021, 77747.057672252195, 77769.322804148323, 77791.589529769248, 77813.857848886837, 77836.127761273063, 77858.399266699998, 77880.67236493979, 77902.947055764627, 77925.223338946831, 77947.50121425878, 77969.780681472927, 77992.061740361838, 78014.344390698127, 78036.628632254491, 78058.914464803747, 78081.201888118725, 78103.490901972415, 78125.781506137821, 78148.073700388064, 78170.367484496339, 78192.662858235926, 78214.959821380166, 78237.258373702498, 78259.558514976452, 78281.860244975614, 78304.163563473659, 78326.468470244363, 78348.77496506153, 78371.083047699125, 78393.392717931114, 78415.703975531578, 78438.016820274701, 78460.331251934695, 78482.647270285903, 78504.964875102727, 78527.284066159627, 78549.604843231195, 78571.927206092048, 78594.251154516911, 78616.576688280606, 78638.903807157985, 78661.232510924034, 78683.562799353778, 78705.894672222363, 78728.228129304945, 78750.563170376859, 78772.899795213423, 78795.238003590101, 78817.577795282399, 78839.919170065928, 78862.262127716356, 78884.606668009452, 78906.952790721043, 78929.300495627045, 78951.64978250346, 78974.000651126378, 78996.353101271932, 79018.707132716358, 79041.062745235977, 79063.41993860717, 79085.778712606436, 79108.139067010285, 79130.501001595389, 79152.864516138419, 79175.22961041618, 79197.596284205531, 79219.96453728342, 79242.33436942687, 79264.705780412987, 79287.078770018954, 79309.453338022009, 79331.829484199508, 79354.207208328866, 79376.586510187582, 79398.967389553218, 79421.349846203433, 79443.733879915948, 79466.119490468584, 79488.50667763922, 79510.895441205823, 79533.285780946433, 79555.677696639163, 79578.071188062226, 79600.466254993895, 79622.862897212515, 79645.261114496549, 79667.660906624471, 79690.062273374875, 79712.465214526455, 79734.869729857935, 79757.275819148126, 79779.683482175955, 79802.092718720378, 79824.503528560454, 79846.915911475327, 79869.329867244203, 79891.745395646343, 79914.162496461155, 79936.581169468045, 79959.001414446553, 79981.423231176261, 80003.846619436852, 80026.271579008084, 80048.698109669771, 80071.12621120183, 80093.555883384237, 80115.987125997053, 80138.419938820414, 80160.854321634528, 80183.290274219689, 80205.727796356281, 80228.166887824715, 80250.607548405547, 80273.049777879336, 80295.493576026798, 80317.938942628651, 80340.385877465727, 80362.834380318949, 80385.28445096928, 80407.736089197788, 80430.189294785596, 80452.644067513917, 80475.100407164035, 80497.558313517322, 80520.017786355209, 80542.478825459213, 80564.941430610925, 80587.405601592007, 80609.871338184195, 80632.338640169342, 80654.8075073293, 80677.277939446067, 80699.749936301683, 80722.223497678278, 80744.698623358039, 80767.17531312324, 80789.653566756242, 80812.133384039465, 80834.614764755403, 80857.097708686648, 80879.582215615854, 80902.068285325731, 80924.555917599093, 80947.045112218824, 80969.535868967869, 80992.028187629272, 81014.522067986123, 81037.017509821613, 81059.514512919006, 81082.013077061609, 81104.513202032831, 81127.014887616184, 81149.518133595193, 81172.022939753486, 81194.529305874807, 81217.037231742899, 81239.546717141639, 81262.057761854958, 81284.570365666848, 81307.084528361403, 81329.600249722775, 81352.117529535186, 81374.636367582949, 81397.156763650448, 81419.678717522125, 81442.202228982511, 81464.727297816222, 81487.253923807933, 81509.782106742379, 81532.311846404409, 81554.843142578902, 81577.375995050839, 81599.910403605274, 81622.446368027333, 81644.983888102215, 81667.522963615178, 81690.063594351581, 81712.605780096841, 81735.149520636449, 81757.694815755967, 81780.241665241047, 81802.79006887741, 81825.340026450824, 81847.891537747171, 81870.444602552379, 81892.999220652477, 81915.555391833506, 81938.113115881672, 81960.672392583176, 81983.233221724338, 82005.795603091537, 82028.359536471224, 82050.925021649906, 82073.492058414209, 82096.060646550788, 82118.630785846399, 82141.202476087841, 82163.775717062032, 82186.35050855593, 82208.926850356569, 82231.504742251054, 82254.084184026578, 82276.665175470393, 82299.24771636985, 82321.831806512317, 82344.417445685307, 82367.004633676348, 82389.593370273054, 82412.183655263143, 82434.775488434374, 82457.368869574595, 82479.963798471697, 82502.560274913689, 82525.158298688606, 82547.757869584602, 82570.35898738986, 82592.961651892678, 82615.565862881398, 82638.171620144421, 82660.778923470265, 82683.387772647475, 82705.998167464713, 82728.610107710658, 82751.223593174116, 82773.83862364394, 82796.45519890904, 82819.073318758441, 82841.692982981185, 82864.314191366429, 82886.936943703375, 82909.561239781324, 82932.187079389638, 82954.814462317736, 82977.443388355125, 83000.073857291369, 83022.70586891612, 83045.339423019104, 83067.974519390089, 83090.611157818959, 83113.249338095629, 83135.8890600101, 83158.530323352461, 83181.173127912858, 83203.817473481497, 83226.463359848669, 83249.11078680474, 83271.759754140134, 83294.410261645375, 83317.062309111003, 83339.715896327703, 83362.371023086147, 83385.027689177165, 83407.685894391587, 83430.345638520361, 83453.006921354478, 83475.669742685001, 83498.334102303095, 83520.999999999942, 83543.667435566866, 83566.336408795192, 83589.006919476349, 83611.678967401851, 83634.352552363242, 83657.027674152167, 83679.704332560359, 83702.382527379552, 83725.062258401638, 83747.743525418511, 83770.42632822218, 83793.110666604684, 83815.796540358162, 83838.483949274829, 83861.172893146941, 83883.863371766842, 83906.555384926964, 83929.248932419752, 83951.944014037799, 83974.640629573696, 83997.338778820151, 84020.038461569929, 84042.739677615857, 84065.442426750829, 84088.146708767847, 84110.852523459922, 84133.559870620171, 84156.268750041796, 84178.979161518029, 84201.691104842204, 84224.404579807713, 84247.119586208006, 84269.83612383662, 84292.55419248715, 84315.273791953281, 84337.994922028738, 84360.717582507335, 84383.441773182945, 84406.167493849513, 84428.894744301069, 84451.623524331691, 84474.353833735542, 84497.085672306828, 84519.819039839858, 84542.553936128999, 84565.290360968676, 84588.028314153402, 84610.767795477717, 84633.508804736295, 84656.251341723822, 84678.995406235073, 84701.740998064924, 84724.488117008252, 84747.236762860062, 84769.986935415407, 84792.73863446941, 84815.491859817252, 84838.246611254188, 84861.002888575575, 84883.760691576768, 84906.520020053256, 84929.28087380057, 84952.043252614312, 84974.807156290146, 84997.572584623806, 85020.339537411113, 85043.108014447949, 85065.878015530237, 85088.649540453989, 85111.422589015303, 85134.197161010321, 85156.973256235244, 85179.750874486374, 85202.530015560071, 85225.310679252725, 85248.092865360857, 85270.876573681016, 85293.661804009811, 85316.448556143951, 85339.236829880188, 85362.026625015351, 85384.817941346351, 85407.610778670132, 85430.405136783724, 85453.201015484257, 85475.998414568865, 85498.797333834795, 85521.597773079353, 85544.399732099904, 85567.203210693886, 85590.008208658808, 85612.814725792239, 85635.62276189182, 85658.432316755265, 85681.243390180331, 85704.055981964877, 85726.870091906807, 85749.685719804082, 85772.502865454764, 85795.321528656961, 85818.141709208852, 85840.963406908675, 85863.78662155474, 85886.611352945445, 85909.437600879217, 85932.26536515457, 85955.094645570091, 85977.92544192441, 86000.757754016275, 86023.591581644432, 86046.426924607746, 86069.263782705122, 86092.102155735556, 86114.942043498071, 86137.783445791807, 86160.626362415918, 86183.470793169676, 86206.316737852379, 86229.164196263402, 86252.013168202204, 86274.863653468303, 86297.715651861261, 86320.569163180728, 86343.424187226425, 86366.280723798132, 86389.138772695675, 86411.998333718977, 86434.859406668009, 86457.721991342827, 86480.586087543532, 86503.451695070296, 86526.318813723352, 86549.187443303032, 86572.057583609683, 86594.929234443756, 86617.802395605773, 86640.677066896271, 86663.553248115903, 86686.43093906538, 86709.310139545443, 86732.190849356964, 86755.073068300815, 86777.956796177954, 86800.842032789442, 86823.728777936354, 86846.617031419853, 86869.506793041175, 86892.398062601613, 86915.290839902518, 86938.185124745316, 86961.080916931489, 86983.978216262592, 87006.87702254027, 87029.777335566177, 87052.67915514209, 87075.582481069796, 87098.487313151185, 87121.39365118822, 87144.301494982894, 87167.210844337285, 87190.121699053532, 87213.034058933845, 87235.947923780506, 87258.863293395829, 87281.780167582241, 87304.698546142172, 87327.618428878181, 87350.539815592856, 87373.462706088845, 87396.387100168897, 87419.312997635774, 87442.240398292357, 87465.16930194154, 87488.099708386319, 87511.031617429733, 87533.965028874911, 87556.899942525008, 87579.836358183282, 87602.774275653021, 87625.713694737613, 87648.654615240492, 87671.597036965148, 87694.540959715145, 87717.486383294105, 87740.433307505737, 87763.381732153779, 87786.331657042057, 87809.283081974456, 87832.236006754916, 87855.190431187453, 87878.146355076155, 87901.103778225151, 87924.062700438633, 87947.023121520891, 87969.985041276246, 87992.948459509105, 88015.913376023906, 88038.879790625171, 88061.847703117513, 88084.817113305573, 88107.788020994049, 88130.760425987726, 88153.734328091465, 88176.709727110137, 88199.686622848749, 88222.665015112303, 88245.644903705906, 88268.626288434709, 88291.609169103947, 88314.593545518903, 88337.579417484914, 88360.566784807408, 88383.555647291854, 88406.546004743795, 88429.537856968818, 88452.531203772611, 88475.52604496089, 88498.522380339447, 88521.52020971413, 88544.519532890874, 88567.520349675644, 88590.522659874507, 88613.526463293543, 88636.531759738922, 88659.538549016899, 88682.546830933745, 88705.556605295846, 88728.567871909589, 88751.580630581491, 88774.594881118086, 88797.610623325963, 88820.62785701183, 88843.646581982393, 88866.666798044462, 88889.688505004888, 88912.711702670611, 88935.7363908486, 88958.762569345898, 88981.790237969632, 89004.81939652696, 89027.850044825114, 89050.882182671412, 89073.9158098732, 89096.950926237885, 89119.987531572973, 89143.025625686001, 89166.065208384563, 89189.106279476357, 89212.148838769106, 89235.192886070581, 89258.238421188667, 89281.285443931265, 89304.333954106376, 89327.383951522017, 89350.435435986306, 89373.488407307406, 89396.542865293537, 89419.598809753006, 89442.656240494165, 89465.715157325409, 89488.775560055219, 89511.837448492137, 89534.900822444746, 89557.965681721733, 89581.032026131812, 89604.099855483742, 89627.169169586399, 89650.239968248672, 89673.312251279538, 89696.386018488018, 89719.461269683205, 89742.53800467425, 89765.616223270365, 89788.69592528083, 89811.777110514988, 89834.859778782207, 89857.943929891975, 89881.029563653807, 89904.116679877261, 89927.205278372014, 89950.29535894774, 89973.386921414218, 89996.479965581268, 90019.574491258769, 90042.670498256688, 90065.767986385021, 90088.866955453836, 90111.967405273259, 90135.069335653476, 90158.172746404758, 90181.277637337407, 90204.384008261797, 90227.49185898836, 90250.601189327586, 90273.711999090039, 90296.824288086325, 90319.938056127125, 90343.053303023189, 90366.170028585286, 90389.288232624298, 90412.407914951138, 90435.529075376777, 90458.651713712257, 90481.775829768681, 90504.901423357209, 90528.028494289058, 90551.157042375504, 90574.287067427911, 90597.418569257643, 90620.551547676194, 90643.686002495073, 90666.821933525847, 90689.959340580186, 90713.098223469773, 90736.238582006365, 90759.380416001804, 90782.523725267951, 90805.668509616764, 90828.814768860233, 90851.962502810435, 90875.11171127946, 90898.262394079517, 90921.414551022855, 90944.568181921743, 90967.72328658856, 90990.879864835719, 91014.037916475718, 91037.19744132107, 91060.358439184391, 91083.520909878338, 91106.684853215629, 91129.850269009039, 91153.017157071401, 91176.185517215621, 91199.355349254649, 91222.526653001492, 91245.699428269247, 91268.873674871036, 91292.049392620058, 91315.226581329553, 91338.405240812834, 91361.585370883287, 91384.766971354344, 91407.950042039476, 91431.134582752245, 91454.320593306256, 91477.508073515171, 91500.697023192712, 91523.887442152685, 91547.07933020893, 91570.272687175326, 91593.467512865856, 91616.663807094534, 91639.861569675442, 91663.060800422725, 91686.261499150554, 91709.463665673218, 91732.66729980502, 91755.872401360321, 91779.078970153569, 91802.287005999257, 91825.49650871192, 91848.707478106167, 91871.91991399668, 91895.133816198169, 91918.349184525418, 91941.566018793281, 91964.784318816659, 91988.004084410495, 92011.22531538982, 92034.448011569708, 92057.672172765277, 92080.897798791746, 92104.124889464365, 92127.353444598411, 92150.58346400928, 92173.814947512379, 92197.04789492322, 92220.282306057314, 92243.518180730272, 92266.755518757753, 92289.994319955469, 92313.234584139194, 92336.476311124774, 92359.719500728082, 92382.964152765067, 92406.210267051734, 92429.457843404161, 92452.706881638471, 92475.957381570814, 92499.209343017443, 92522.462765794655, 92545.717649718805, 92568.973994606305, 92592.231800273614, 92615.491066537259, 92638.751793213814, 92662.01398011994, 92685.277627072326, 92708.54273388772, 92731.809300382942, 92755.077326374871, 92778.346811680414, 92801.617756116568, 92824.890159500384, 92848.164021648947, 92871.439342379424, 92894.716121509016, 92917.994358855023, 92941.274054234746, 92964.555207465572, 92987.837818364962, 93011.121886750407, 93034.407412439468, 93057.694395249753, 93080.982834998955, 93104.272731504767, 93127.564084584999, 93150.856894057491, 93174.15115974014, 93197.446881450916, 93220.744059007804, 93244.04269222889, 93267.342780932304, 93290.644324936235, 93313.947324058914, 93337.251778118633, 93360.557686933767, 93383.865050322696, 93407.173868103928, 93430.484140095941, 93453.795866117362, 93477.109045986799, 93500.423679522952, 93523.739766544561, 93547.057306870454, 93570.376300319491, 93593.696746710571, 93617.018645862699, 93640.341997594893, 93663.666801726242, 93686.993058075881, 93710.320766463032, 93733.64992670693, 93756.980538626914, 93780.312602042337, 93803.646116772637, 93826.981082637285, 93850.317499455836, 93873.655367047861, 93896.994685233032, 93920.335453831038, 93943.677672661666, 93967.021341544707, 93990.366460300051, 94013.713028747632, 94037.061046707429, 94060.410513999494, 94083.761430443905, 94107.113795860845, 94130.467610070496, 94153.822872893157, 94177.179584149111, 94200.537743658759, 94223.897351242529, 94247.25840672091, 94270.620909914433, 94293.98486064373, 94317.350258729421, 94340.71710399224, 94364.085396252936, 94387.455135332348, 94410.82632105134, 94434.198953230851, 94457.573031691878, 94480.948556255447, 94504.325526742658, 94527.70394297468, 94551.083804772716, 94574.465111958023, 94597.847864351934, 94621.232061775823, 94644.617704051096, 94668.004790999272, 94691.393322441872, 94714.783298200506, 94738.174718096794, 94761.567581952477, 94784.961889589307, 94808.357640829097, 94831.754835493703, 94855.153473405066, 94878.553554385173, 94901.955078256055, 94925.358044839784, 94948.762453958523, 94972.168305434476, 94995.575599089891, 95018.984334747074, 95042.394512228391, 95065.806131356265, 95089.219191953176, 95112.633693841635, 95136.04963684424, 95159.467020783617, 95182.885845482466, 95206.306110763529, 95229.727816449609, 95253.150962363579, 95276.575548328314, 95300.001574166803, 95323.429039702052, 95346.857944757154, 95370.288289155214, 95393.720072719429, 95417.153295273019, 95440.587956639298, 95464.024056641589, 95487.461595103305, 95510.900571847902, 95534.340986698866, 95557.782839479783, 95581.226130014256, 95604.670858125959, 95628.117023638595, 95651.564626375985, 95675.013666161918, 95698.464142820303, 95721.916056175076, 95745.369406050231, 95768.824192269807, 95792.280414657915, 95815.738073038709, 95839.197167236387, 95862.657697075221, 95886.11966237954, 95909.583062973688, 95933.047898682111, 95956.514169329268, 95979.981874739708, 96003.451014738006, 96026.921589148798, 96050.393597796792, 96073.867040506724, 96097.341917103375, 96120.818227411626, 96144.295971256375, 96167.775148462577, 96191.255758855244, 96214.737802259449, 96238.221278500292, 96261.70618740299, 96285.192528792715, 96308.680302494788, 96332.169508334526, 96355.660146137321, 96379.152215728609, 96402.645716933868, 96426.14064957868, 96449.637013488609, 96473.134808489311, 96496.63403440651, 96520.134691065963, 96543.636778293469, 96567.140295914898, 96590.645243756153, 96614.151621643221, 96637.659429402134, 96661.168666858954, 96684.679333839798, 96708.191430170875, 96731.70495567839, 96755.219910188665, 96778.736293528011, 96802.254105522836, 96825.77334599958, 96849.29401478474, 96872.816111704873, 96896.339636586577, 96919.864589256511, 96943.390969541389, 96966.918777267958, 96990.448012263048, 97013.978674353522, 97037.510763366285, 97061.044279128328, 97084.579221466673, 97108.115590208385, 97131.653385180587, 97155.19260621049, 97178.733253125291, 97202.2753257523, 97225.81882391886, 97249.363747452342, 97272.910096180189, 97296.457869929916, 97320.007068529041, 97343.557691805196, 97367.109739586012, 97390.663211699197, 97414.218107972498, 97437.774428233737, 97461.332172310766, 97484.891340031507, 97508.451931223899, 97532.013945715982, 97555.577383335811, 97579.142243911512, 97602.708527271257, 97626.276233243261, 97649.845361655811, 97673.415912337223, 97696.987885115886, 97720.561279820206, 97744.1360962787, 97767.712334319876, 97791.289993772341, 97814.869074464703, 97838.449576225685, 97862.031498883996, 97885.614842268449, 97909.199606207883, 97932.785790531183, 97956.37339506732, 97979.962419645264, 98003.552864094076, 98027.144728242856, 98050.738011920766, 98074.332714956996, 98097.928837180807, 98121.526378421506, 98145.125338508456, 98168.725717271067, 98192.327514538789, 98215.930730141132, 98239.535363907664, 98263.141415668011, 98286.748885251814, 98310.357772488816, 98333.968077208759, 98357.579799241488, 98381.192938416847, 98404.807494564782, 98428.42346751524, 98452.040857098269, 98475.659663143917, 98499.27988548232, 98522.901523943656, 98546.524578358163, 98570.149048556093, 98593.774934367786, 98617.402235623624, 98641.030952154048, 98664.661083789513, 98688.292630360564, 98711.925591697771, 98735.559967631794, 98759.195757993293, 98782.832962613014, 98806.471581321734, 98830.111613950285, 98853.753060329575, 98877.39592029051, 98901.040193664099, 98924.68588028138, 98948.33297997342, 98971.981492571387, 98995.63141790645, 99019.282755809851, 99042.935506112874, 99066.589668646877, 99090.245243243233, 99113.902229733401, 99137.560627948857, 99161.220437721131, 99184.881658881859, 99208.544291262631, 99232.208334695169, 99255.87378901121, 99279.540654042547, 99303.208929621018, 99326.878615578535, 99350.549711746993, 99374.222217958435, 99397.896134044888, 99421.571459838422, 99445.248195171211, 99468.926339875441, 99492.605893783344, 99516.286856727209, 99539.969228539398, 99563.653009052287, 99587.338198098325, 99611.024795510006, 99634.712801119866, 99658.402214760499, 99682.093036264545, 99705.785265464699, 99729.478902193689, 99753.173946284325, 99776.870397569437, 99800.56825588191, 99824.267521054688, 99847.968192920773, 99871.670271313182, 99895.373756065004, 99919.078647009388, 99942.78494397951, 99966.492646808634, 99990.20175533001, 100013.91226937699, 100037.62418878295, 100061.33751338134, 100085.05224300563, 100108.76837748935, 100132.4859166661, 100156.2048603695, 100179.92520843323, 100203.64696069101, 100227.37011697664, 100251.09467712394, 100274.82064096678, 100298.54800833909, 100322.27677907483, 100346.00695300807, 100369.73852997283, 100393.47150980328, 100417.20589233354, 100440.94167739789, 100464.67886483055, 100488.41745446586, 100512.1574461382, 100535.89883968196, 100559.64163493161, 100583.38583172169, 100607.13142988674, 100630.87842926137, 100654.62682968024, 100678.37663097809, 100702.12783298964, 100725.88043554971, 100749.63443849317, 100773.38984165489, 100797.14664486986, 100820.90484797307, 100844.66445079957, 100868.42545318443, 100892.18785496285, 100915.95165596998, 100939.71685604109, 100963.48345501146, 100987.25145271645, 101011.02084899142, 101034.79164367182, 101058.56383659317, 101082.33742759094, 101106.11241650078, 101129.88880315828, 101153.66658739912, 101177.44576905905, 101201.22634797383, 101225.00832397929, 101248.7916969113, 101272.57646660579, 101296.36263289873, 101320.15019562612, 101343.93915462404, 101367.7295097286, 101391.52126077596, 101415.31440760233, 101439.10895004397, 101462.9048879372, 101486.70222111834, 101510.50094942382, 101534.30107269008, 101558.10259075361, 101581.90550345098, 101605.70981061876, 101629.5155120936, 101653.32260771218, 101677.13109731126, 101700.9409807276, 101724.75225779804, 101748.56492835947, 101772.37899224881, 101796.19444930303, 101820.01129935916, 101843.82954225427, 101867.64917782549, 101891.47020590997, 101915.29262634492, 101939.11643896763, 101962.94164361537, 101986.76824012553, 102010.59622833549, 102034.42560808272, 102058.25637920471, 102082.08854153901, 102105.9220949232, 102129.75703919494, 102153.59337419191, 102177.43109975185, 102201.27021571253, 102225.1107219118, 102248.95261818753, 102272.79590437764, 102296.64058032009, 102320.48664585294, 102344.33410081422, 102368.18294504205, 102392.03317837461, 102415.88480065008, 102439.73781170673, 102463.59221138287, 102487.44799951684, 102511.30517594704, 102535.1637405119, 102559.02369304992, 102582.88503339965, 102606.74776139967, 102630.61187688859, 102654.4773797051, 102678.34426968795, 102702.21254667587, 102726.08221050771, 102749.95326102231, 102773.8256980586, 102797.69952145554, 102821.57473105213, 102845.45132668741, 102869.32930820051, 102893.20867543056, 102917.08942821674, 102940.97156639832, 102964.85508981455, 102988.73999830478, 103012.6262917084, 103036.51396986481, 103060.40303261351, 103084.293479794, 103108.18531124585, 103132.07852680866, 103155.97312632212, 103179.8691096259, 103203.76647655977, 103227.66522696352, 103251.56536067701, 103275.46687754011, 103299.36977739276, 103323.27406007495, 103347.1797254267, 103371.0867732881, 103394.99520349925, 103418.90501590034, 103442.81621033157, 103466.72878663319, 103490.64274464553, 103514.55808420894, 103538.4748051638, 103562.39290735057, 103586.31239060973, 103610.23325478184, 103634.15549970744, 103658.07912522719, 103682.00413118176, 103705.93051741188, 103729.85828375829, 103753.78743006183, 103777.71795616332, 103801.64986190372, 103825.58314712394, 103849.51781166498, 103873.4538553679, 103897.39127807376, 103921.33007962372, 103945.27025985894, 103969.21181862066, 103993.15475575015, 104017.0990710887, 104041.0447644777, 104064.99183575854, 104088.94028477269, 104112.89011136163, 104136.84131536692, 104160.79389663014, 104184.74785499295, 104208.70319029699, 104232.65990238401, 104256.61799109577, 104280.57745627411, 104304.53829776087, 104328.50051539797, 104352.46410902737, 104376.42907849104, 104400.39542363105, 104424.36314428948, 104448.33224030846, 104472.3027115302, 104496.27455779689, 104520.24777895081, 104544.22237483428, 104568.19834528965, 104592.17569015936, 104616.15440928582, 104640.13450251156, 104664.1159696791, 104688.09881063103, 104712.08302520998, 104736.06861325864, 104760.05557461972, 104784.043909136, 104808.03361665027, 104832.0246970054, 104856.01715004431, 104880.01097560991, 104904.00617354522, 104928.00274369326, 104952.00068589712, 104975.99999999993, 105000.00068584486, 105024.00274327511, 105048.00617213396, 105072.0109722647, 105096.0171435107, 105120.02468571534, 105144.03359872208, 105168.04388237436, 105192.05553651576, 105216.06856098982, 105240.08295564017, 105264.09872031047, 105288.11585484444, 105312.13435908582, 105336.1542328784, 105360.17547606604, 105384.19808849262, 105408.22207000206, 105432.24742043833, 105456.27413964548, 105480.30222746753, 105504.33168374863, 105528.36250833291, 105552.39470106458, 105576.42826178786, 105600.46319034706, 105624.49948658649, 105648.53715035053, 105672.5761814836, 105696.61657983017, 105720.65834523473, 105744.70147754184, 105768.7459765961, 105792.79184224214, 105816.83907432464, 105840.88767268835, 105864.93763717801, 105888.98896763846, 105913.04166391456, 105937.09572585119, 105961.15115329332, 105985.20794608595, 106009.26610407409, 106033.32562710284, 106057.38651501729, 106081.44876766266, 106105.51238488412, 106129.57736652695, 106153.64371243643, 106177.71142245791, 106201.78049643678, 106225.85093421848, 106249.92273564848, 106273.99590057228, 106298.07042883546, 106322.14632028362, 106346.22357476239, 106370.30219211751, 106394.38217219469, 106418.46351483969, 106442.54621989837, 106466.63028721658, 106490.71571664025, 106514.80250801529, 106538.89066118775, 106562.98017600364, 106587.07105230905, 106611.16328995011, 106635.25688877302, 106659.35184862395, 106683.44816934918, 106707.54585079502, 106731.64489280782, 106755.74529523395, 106779.84705791986, 106803.95018071201, 106828.05466345693, 106852.16050600118, 106876.26770819137, 106900.37626987413, 106924.48619089619, 106948.59747110425, 106972.71011034511, 106996.82410846559, 107020.93946531253, 107045.05618073288, 107069.17425457356, 107093.29368668159, 107117.41447690397, 107141.53662508781, 107165.66013108024, 107189.7849947284, 107213.91121587952, 107238.03879438085, 107262.16773007967, 107286.29802282334, 107310.42967245923, 107334.56267883476, 107358.69704179741, 107382.83276119467, 107406.96983687414, 107431.10826868335, 107455.24805646999, 107479.38920008171, 107503.53169936626, 107527.67555417139, 107551.82076434491, 107575.96732973469, 107600.11525018861, 107624.26452555459, 107648.41515568066, 107672.56714041479, 107696.72047960508, 107720.87517309963, 107745.03122074658, 107769.18862239413, 107793.34737789053, 107817.50748708403, 107841.66894982298, 107865.83176595572, 107889.99593533068, 107914.16145779629, 107938.32833320105, 107962.49656139348, 107986.66614222217, 108010.83707553572, 108035.00936118282, 108059.18299901215, 108083.35798887245, 108107.53433061253, 108131.71202408121, 108155.89106912735, 108180.07146559987, 108204.25321334775, 108228.43631221994, 108252.62076206553, 108276.80656273357, 108300.99371407321, 108325.18221593359, 108349.37206816394, 108373.56327061349, 108397.75582313156, 108421.94972556747, 108446.1449777706, 108470.34157959036, 108494.53953087622, 108518.73883147769, 108542.93948124432, 108567.14148002568, 108591.34482767139, 108615.54952403114, 108639.75556895464, 108663.96296229165, 108688.17170389196, 108712.38179360541, 108736.59323128188, 108760.80601677128, 108785.02014992358, 108809.23563058881, 108833.45245861699, 108857.67063385822, 108881.89015616261, 108906.11102538036, 108930.33324136167, 108954.55680395682, 108978.78171301607, 109003.00796838976, 109027.23556992831, 109051.46451748211, 109075.69481090162, 109099.92645003737, 109124.15943473989, 109148.39376485976, 109172.62944024763, 109196.86646075416, 109221.10482623006, 109245.34453652608, 109269.58559149304, 109293.82799098175, 109318.07173484311, 109342.31682292801, 109366.56325508743, 109390.81103117237, 109415.06015103387, 109439.31061452301, 109463.56242149093, 109487.8155717888, 109512.07006526781, 109536.3259017792, 109560.58308117429, 109584.8416033044, 109609.1014680209, 109633.36267517522, 109657.62522461878, 109681.88911620311, 109706.15434977971, 109730.4209252002, 109754.68884231619, 109778.95810097932, 109803.22870104131, 109827.50064235389, 109851.77392476884, 109876.04854813802, 109900.32451231324, 109924.60181714644, 109948.88046248957, 109973.1604481946, 109997.44177411357, 110021.72444009855, 110046.00844600165, 110070.29379167501, 110094.58047697082, 110118.86850174134, 110143.15786583882, 110167.44856911557, 110191.74061142397, 110216.03399261639, 110240.32871254528, 110264.62477106311, 110288.9221680224, 110313.22090327571, 110337.52097667565, 110361.82238807483, 110386.12513732594, 110410.42922428172, 110434.73464879491, 110459.04141071832, 110483.34950990479, 110507.6589462072, 110531.96971947847, 110556.28182957157, 110580.5952763395, 110604.91005963532, 110629.22617931209, 110653.54363522294, 110677.86242722106, 110702.18255515963, 110726.50401889188, 110750.82681827113, 110775.1509531507, 110799.47642338395, 110823.80322882428, 110848.13136932514, 110872.46084474004, 110896.79165492248, 110921.12379972603, 110945.4572790043, 110969.79209261097, 110994.12824039967, 111018.46572222417, 111042.80453793822, 111067.14468739564, 111091.48617045028, 111115.82898695602, 111140.1731367668, 111164.51861973655, 111188.86543571933, 111213.21358456917, 111237.56306614014, 111261.91388028639, 111286.26602686207, 111310.61950572141, 111334.97431671864, 111359.33045970804, 111383.68793454397, 111408.04674108078, 111432.40687917286, 111456.76834867468, 111481.13114944073, 111505.49528132551, 111529.86074418361, 111554.22753786964, 111578.59566223821, 111602.96511714405, 111627.33590244185, 111651.7080179864, 111676.08146363248, 111700.45623923496, 111724.8323446487, 111749.20977972864, 111773.58854432974, 111797.96863830699, 111822.35006151545, 111846.73281381019, 111871.11689504632, 111895.50230507903, 111919.8890437635, 111944.27711095495, 111968.6665065087, 111993.05723028004, 112017.44928212435, 112041.842661897, 112066.23736945343, 112090.63340464912, 112115.03076733962, 112139.42945738042, 112163.82947462716, 112188.23081893545, 112212.63349016097, 112237.03748815943, 112261.44281278658, 112285.84946389822, 112310.25744135017, 112334.66674499828, 112359.07737469849, 112383.48933030672, 112407.90261167898, 112432.31721867126, 112456.73315113965, 112481.15040894024, 112505.56899192919, 112529.98889996267, 112554.41013289688, 112578.8326905881, 112603.25657289263, 112627.68177966679, 112652.10831076698, 112676.53616604958, 112700.96534537108, 112725.39584858794, 112749.82767555672, 112774.26082613398, 112798.6953001763, 112823.13109754038, 112847.56821808286, 112872.00666166049, 112896.44642813003, 112920.88751734827, 112945.32992917208, 112969.77366345831, 112994.21872006389, 113018.66509884578, 113043.11279966099, 113067.56182236652, 113092.01216681948, 113116.46383287695, 113140.9168203961, 113165.37112923413, 113189.82675924824, 113214.28371029573, 113238.74198223387, 113263.20157492002, 113287.66248821157, 113312.12472196593, 113336.58827604055, 113361.05315029295, 113385.51934458067, 113409.98685876124, 113434.45569269233, 113458.92584623155, 113483.39731923661, 113507.87011156522, 113532.34422307517, 113556.81965362425, 113581.2964030703, 113605.77447127122, 113630.25385808491, 113654.73456336933, 113679.2165869825, 113703.69992878241, 113728.18458862718, 113752.67056637487, 113777.15786188368, 113801.64647501177, 113826.13640561736, 113850.62765355874, 113875.12021869418, 113899.61410088204, 113924.1092999807, 113948.60581584855, 113973.10364834407, 113997.60279732574, 114022.1032626521, 114046.60504418171, 114071.10814177318, 114095.61255528514, 114120.11828457628, 114144.62532950533, 114169.13368993104, 114193.6433657122, 114218.15435670764, 114242.66666277625, 114267.18028377694, 114291.69521956862, 114316.21147001031, 114340.72903496103, 114365.24791427983, 114389.7681078258, 114414.2896154581, 114438.81243703589, 114463.33657241837, 114487.8620214648, 114512.38878403447, 114536.91685998671, 114561.44624918087, 114585.97695147636, 114610.5089667326, 114635.04229480909, 114659.57693556532, 114684.11288886084, 114708.65015455526, 114733.18873250818, 114757.72862257928, 114782.26982462825, 114806.81233851484, 114831.35616409882, 114855.90130123998, 114880.44774979822, 114904.99550963337, 114929.5445806054, 114954.09496257425, 114978.64665539992, 115003.19965894247, 115027.75397306195, 115052.30959761847, 115076.86653247218, 115101.42477748329, 115125.984332512, 115150.54519741859, 115175.10737206334, 115199.67085630659, 115224.23565000873, 115248.80175303014, 115273.3691652313, 115297.93788647266, 115322.50791661476, 115347.07925551817, 115371.65190304347, 115396.22585905129, 115420.80112340231, 115445.37769595724, 115469.95557657682, 115494.53476512182, 115519.11526145306, 115543.69706543141, 115568.28017691776, 115592.86459577303, 115617.4503218582, 115642.03735503425, 115666.62569516223, 115691.21534210323, 115715.80629571836, 115740.39855586876, 115764.99212241563, 115789.58699522018, 115814.18317414368, 115838.78065904744, 115863.37944979276, 115887.97954624105, 115912.5809482537, 115937.18365569216, 115961.78766841792, 115986.39298629249, 116010.99960917742, 116035.60753693432, 116060.21676942479, 116084.82730651053, 116109.43914805322, 116134.0522939146, 116158.66674395646, 116183.2824980406, 116207.89955602887, 116232.51791778316, 116257.13758316539, 116281.75855203751, 116306.38082426153, 116331.00439969949, 116355.62927821343, 116380.25545966547, 116404.88294391775, 116429.51173083246, 116454.14182027178, 116478.77321209799, 116503.40590617337, 116528.03990236025, 116552.67520052097, 116577.31180051794, 116601.94970221359, 116626.5889054704, 116651.22941015086, 116675.87121611751, 116700.51432323294, 116725.15873135976, 116749.8044403606, 116774.45145009817, 116799.0997604352, 116823.74937123443, 116848.40028235866, 116873.05249367072, 116897.70600503348, 116922.36081630984, 116947.01692736275, 116971.67433805518, 116996.33304825013, 117020.99305781067, 117045.65436659988, 117070.31697448085, 117094.98088131678, 117119.64608697082, 117144.31259130624, 117168.98039418629, 117193.64949547425, 117218.31989503348, 117242.99159272734, 117267.66458841923, 117292.33888197262, 117317.01447325097, 117341.6913621178, 117366.36954843666, 117391.04903207115, 117415.72981288488, 117440.41189074152, 117465.09526550474, 117489.77993703831, 117514.46590520597, 117539.15316987153, 117563.84173089883, 117588.53158815173, 117613.22274149416, 117637.91519079007, 117662.60893590341, 117687.30397669821, 117712.00031303853, 117736.69794478847, 117761.39687181212, 117786.09709397367, 117810.7986111373, 117835.50142316725, 117860.20552992777, 117884.91093128319, 117909.6176270978, 117934.32561723603, 117959.03490156225, 117983.74547994092, 118008.45735223651, 118033.17051831353, 118057.88497803656, 118082.60073127014, 118107.31777787894, 118132.03611772758, 118156.75575068076, 118181.47667660323, 118206.19889535972, 118230.92240681504, 118255.64721083404, 118280.37330728157, 118305.10069602253, 118329.82937692189, 118354.55934984458, 118379.29061465565, 118404.02317122012, 118428.75701940308, 118453.49215906965, 118478.22859008498, 118502.96631231424, 118527.70532562268, 118552.44562987552, 118577.18722493808, 118601.93011067568, 118626.67428695368, 118651.41975363747, 118676.16651059251, 118700.91455768423, 118725.66389477813, 118750.41452173979, 118775.16643843475, 118799.91964472862, 118824.67414048707, 118849.42992557574, 118874.18699986035, 118898.94536320666, 118923.70501548045, 118948.46595654752, 118973.22818627374, 118997.99170452499, 119022.7565111672, 119047.52260606633, 119072.28998908834, 119097.0586600993, 119121.82861896523, 119146.59986555226, 119171.3723997265, 119196.14622135412, 119220.92133030134, 119245.69772643436, 119270.47540961947, 119295.25437972297, 119320.03463661121, 119344.81618015055, 119369.5990102074, 119394.38312664822, 119419.16852933947, 119443.95521814766, 119468.74319293935, 119493.53245358112, 119518.32299993958, 119543.11483188139, 119567.90794927324, 119592.70235198183, 119617.49803987393, 119642.29501281632, 119667.09327067583, 119691.89281331931, 119716.69364061367, 119741.49575242582, 119766.29914862274, 119791.10382907141, 119815.90979363887, 119840.71704219218, 119865.52557459843, 119890.33539072477, 119915.14649043836, 119939.95887360642, 119964.77254009615, 119989.58748977486, 120014.40372250983, 120039.22123816841, 120064.04003661797, 120088.86011772591, 120113.6814813597, 120138.5041273868, 120163.3280556747, 120188.15326609099, 120212.97975850321, 120237.807532779, 120262.63658878599, 120287.46692639188, 120312.29854546436, 120337.13144587121, 120361.9656274802, 120386.80109015915, 120411.63783377589, 120436.47585819835, 120461.31516329442, 120486.15574893207, 120510.99761497928, 120535.84076130406, 120560.68518777451, 120585.53089425867, 120610.3778806247, 120635.22614674074, 120660.07569247499, 120684.92651769568, 120709.77862227106, 120734.63200606944, 120759.48666895913, 120784.3426108085, 120809.19983148595, 120834.05833085992, 120858.91810879884, 120883.77916517125, 120908.64149984565, 120933.5051126906, 120958.37000357473, 120983.23617236665, 121008.10361893504, 121032.97234314861, 121057.84234487606, 121082.71362398617, 121107.58618034775, 121132.46001382964, 121157.33512430069, 121182.21151162982, 121207.08917568595, 121231.96811633807, 121256.84833345517, 121281.72982690629, 121306.61259656049, 121331.49664228689, 121356.38196395461, 121381.26856143285, 121406.15643459078, 121431.04558329767, 121455.93600742276, 121480.82770683538, 121505.72068140487, 121530.61493100057, 121555.51045549192, 121580.40725474835, 121605.30532863933, 121630.20467703436, 121655.10529980299, 121680.00719681478, 121704.91036793934, 121729.81481304632, 121754.72053200539, 121779.62752468624, 121804.53579095862, 121829.44533069231, 121854.3561437571, 121879.26823002285, 121904.1815893594, 121929.09622163669, 121954.01212672464, 121978.92930449323, 122003.84775481246, 122028.76747755238, 122053.68847258303, 122078.61073977455, 122103.53427899707, 122128.45909012076, 122153.38517301581, 122178.31252755247, 122203.24115360099, 122228.17105103172, 122253.10221971494, 122278.03465952107, 122302.96837032049, 122327.90335198362, 122352.83960438096, 122377.777127383, 122402.71592086025, 122427.65598468333, 122452.59731872278, 122477.53992284928, 122502.48379693348, 122527.42894084606, 122552.37535445779, 122577.32303763942, 122602.27199026172, 122627.22221219557, 122652.17370331181, 122677.12646348133, 122702.08049257506, 122727.03579046397, 122751.99235701906, 122776.95019211136, 122801.9092956119, 122826.8696673918, 122851.83130732219, 122876.79421527422, 122901.75839111909, 122926.72383472799, 122951.69054597223, 122976.65852472307, 123001.62777085182, 123026.59828422987, 123051.57006472857, 123076.54311221937, 123101.5174265737, 123126.49300766307, 123151.46985535898, 123176.44796953299, 123201.42735005668, 123226.40799680166, 123251.38990963959, 123276.37308844214, 123301.35753308103, 123326.343243428, 123351.33021935483, 123376.31846073334, 123401.30796743535, 123426.29873933276, 123451.29077629748, 123476.28407820144, 123501.2786449166, 123526.27447631498, 123551.27157226863, 123576.26993264959, 123601.26955732999, 123626.27044618195, 123651.27259907764, 123676.27601588926, 123701.28069648903, 123726.28664074924, 123751.29384854218, 123776.30231974016, 123801.31205421555, 123826.32305184075, 123851.33531248817, 123876.34883603029, 123901.36362233957, 123926.37967128855, 123951.39698274979, 123976.41555659588, 124001.43539269941, 124026.45649093305, 124051.47885116948, 124076.50247328142, 124101.5273571416, 124126.55350262282, 124151.58090959788, 124176.60957793961, 124201.63950752091, 124226.67069821467, 124251.70314989384, 124276.73686243138, 124301.7718357003, 124326.80806957364, 124351.84556392446, 124376.88431862585, 124401.92433355095, 124426.96560857294, 124452.00814356498, 124477.05193840031, 124502.0969929522, 124527.14330709392, 124552.19088069882, 124577.23971364023, 124602.28980579154, 124627.34115702618, 124652.3937672176, 124677.44763623926, 124702.50276396469, 124727.55915026742, 124752.61679502104, 124777.67569809916, 124802.73585937542, 124827.79727872348, 124852.85995601704, 124877.92389112986, 124902.98908393568, 124928.05553430831, 124953.1232421216, 124978.19220724938, 125003.26242956554, 125028.33390894404, 125053.40664525882, 125078.48063838384, 125103.55588819318, 125128.63239456083, 125153.71015736091, 125178.78917646752, 125203.86945175481, 125228.95098309696, 125254.03377036817, 125279.1178134427, 125304.20311219479, 125329.28966649878, 125354.37747622898, 125379.46654125977, 125404.55686146552, 125429.6484367207, 125454.74126689974, 125479.83535187715, 125504.93069152744, 125530.02728572517, 125555.12513434493, 125580.22423726133, 125605.32459434902, 125630.4262054827, 125655.52907053704, 125680.63318938682, 125705.73856190679, 125730.84518797178, 125755.9530674566, 125781.06220023613, 125806.17258618528, 125831.28422517896, 125856.39711709213, 125881.51126179981, 125906.62665917698, 125931.74330909875, 125956.86121144016, 125981.98036607634, 126007.10077288245, 126032.22243173365, 126057.34534250517, 126082.46950507225, 126107.59491931014, 126132.72158509417, 126157.84950229966, 126182.97867080198, 126208.10909047653, 126233.24076119871, 126258.37368284403, 126283.50785528794, 126308.64327840599, 126333.77995207369, 126358.91787616667, 126384.0570505605, 126409.19747513086, 126434.3391497534, 126459.48207430386, 126484.62624865794, 126509.77167269142, 126534.9183462801, 126560.06626929982, 126585.21544162642, 126610.36586313581, 126635.51753370393, 126660.67045320668, 126685.82462152008, 126710.98003852014, 126736.13670408291, 126761.29461808444, 126786.45378040087, 126811.61419090834, 126836.77584948298, 126861.93875600102, 126887.10291033868, 126912.26831237224, 126937.43496197795, 126962.60285903217, 126987.77200341123, 127012.94239499152, 127038.11403364947, 127063.2869192615, 127088.46105170409, 127113.63643085376, 127138.81305658702, 127163.99092878048, 127189.17004731069, 127214.35041205429, 127239.53202288797, 127264.71487968838, 127289.89898233226, 127315.08433069635, 127340.27092465744, 127365.45876409234, 127390.64784887788, 127415.83817889093, 127441.02975400841, 127466.22257410725, 127491.41663906439, 127516.61194875685, 127541.80850306165, 127567.00630185583, 127592.20534501647, 127617.4056324207, 127642.60716394568, 127667.80993946856, 127693.01395886653, 127718.21922201688, 127743.42572879682, 127768.63347908368, 127793.84247275478, 127819.05270968749, 127844.26418975917, 127869.47691284724, 127894.69087882918, 127919.90608758242, 127945.12253898452, 127970.34023291297, 127995.55916924537, 128020.77934785932, 128046.00076863244, 128071.22343144237, 128096.44733616684, 128121.67248268353, 128146.89887087021, 128172.12650060465, 128197.35537176467, 128222.5854842281, 128247.81683787282, 128273.04943257671, 128298.28326821771, 128323.51834467379, 128348.75466182294, 128373.99221954317, 128399.23101771252, 128424.47105620909, 128449.71233491098, 128474.95485369631, 128500.19861244329, 128525.44361103009, 128550.68984933494, 128575.93732723613, 128601.18604461191, 128626.43600134061, 128651.68719730059, 128676.93963237021, 128702.1933064279, 128727.44821935208, 128752.70437102125, 128777.96176131385, 128803.22039010846, 128828.48025728362, 128853.74136271792, 128879.00370628996, 128904.26728787841, 128929.53210736193, 128954.79816461923, 128980.06545952905, 129005.33399197015, 129030.60376182134, 129055.87476896142, 129081.14701326926, 129106.42049462376, 129131.6952129038, 129156.97116798835, 129182.24835975636, 129207.52678808685, 129232.80645285884, 129258.08735395141, 129283.36949124365, 129308.65286461466, 129333.9374739436, 129359.22331910966, 129384.51039999202, 129409.79871646997, 129435.08826842274, 129460.37905572963, 129485.67107826998, 129510.96433592314, 129536.25882856851, 129561.55455608548, 129586.85151835352, 129612.14971525209, 129637.4491466607, 129662.74981245887, 129688.0517125262, 129713.35484674224, 129738.65921498663, 129763.96481713903, 129789.27165307909, 129814.57972268655, 129839.88902584116, 129865.19956242264, 129890.51133231082, 129915.82433538554, 129941.13857152662, 129966.45404061397, 129991.7707425275, 130017.08867714716, 130042.4078443529, 130067.72824402474, 130093.04987604271, 130118.37274028687, 130143.69683663732, 130169.02216497416, 130194.34872517755, 130219.67651712766, 130245.0055407047, 130270.33579578891, 130295.66728226055, 130320.99999999991, 130346.33394888733, 130371.66912880314, 130397.00553962773, 130422.34318124152, 130447.68205352494, 130473.02215635845, 130498.36348962256, 130523.70605319779, 130549.0498469647, 130574.39487080388, 130599.74112459592, 130625.08860822149, 130650.43732156123, 130675.78726449587, 130701.13843690613, 130726.49083867275, 130751.84446967654, 130777.19932979831, 130802.5554189189, 130827.91273691918, 130853.27128368006, 130878.63105908247, 130903.99206300738, 130929.35429533575, 130954.71775594862, 130980.08244472703, 131005.44836155206, 131030.81550630482, 131056.18387886642, 131081.55347911804, 131106.92430694087, 131132.29636221612, 131157.66964482504, 131183.0441546489, 131208.41989156904, 131233.79685546676, 131259.17504622342, 131284.55446372041, 131309.93510783918, 131335.31697846117, 131360.70007546784, 131386.0843987407, 131411.46994816128, 131436.85672361116, 131462.24472497194, 131487.63395212521, 131513.02440495262, 131538.41608333588, 131563.80898715663, 131589.2031162967, 131614.59847063778, 131639.9950500617, 131665.39285445024, 131690.79188368531, 131716.19213764873, 131741.59361622241, 131766.99631928833, 131792.40024672839, 131817.80539842462, 131843.21177425905, 131868.61937411371, 131894.02819787065, 131919.43824541202, 131944.84951661993, 131970.26201137656, 131995.67572956407, 132021.09067106468, 132046.50683576067, 132071.9242235343, 132097.34283426782, 132122.76266784366, 132148.1837241441, 132173.60600305157, 132199.02950444847, 132224.45422821722, 132249.88017424036, 132275.30734240031, 132300.73573257966, 132326.16534466096, 132351.59617852676, 132377.02823405969, 132402.46151114244, 132427.89600965759, 132453.33172948789, 132478.76867051609, 132504.20683262491, 132529.64621569714, 132555.08681961559, 132580.5286442631, 132605.97168952253, 132631.41595527678, 132656.86144140881, 132682.30814780149, 132707.75607433787, 132733.20522090094, 132758.65558737374, 132784.10717363929, 132809.55997958075, 132835.01400508118, 132860.46925002377, 132885.92571429166, 132911.38339776811, 132936.84230033628, 132962.30242187946, 132987.76376228096, 133013.22632142407, 133038.69009919214, 133064.15509546854, 133089.62131013666, 133115.08874307995, 133140.55739418184, 133166.02726332581, 133191.49835039541, 133216.97065527414, 133242.44417784561, 133267.91891799335, 133293.39487560102, 133318.87205055228, 133344.35044273079, 133369.83005202023, 133395.31087830439, 133420.79292146701, 133446.27618139185, 133471.76065796276, 133497.24635106357, 133522.73326057816, 133548.22138639039, 133573.71072838426, 133599.20128644365, 133624.69306045261, 133650.1860502951, 133675.68025585517, 133701.1756770169, 133726.67231366437, 133752.17016568172, 133777.66923295305, 133803.16951536259, 133828.67101279454, 133854.17372513309, 133879.67765226253, 133905.18279406714, 133930.68915043125, 133956.19672123916, 133981.70550637526, 134007.21550572399, 134032.7267191697, 134058.23914659687, 134083.75278789, 134109.26764293358, 134134.78371161217, 134160.30099381026, 134185.8194894125, 134211.33919830353, 134236.8601203679, 134262.38225549037, 134287.90560355558, 134313.43016444831, 134338.95593805326, 134364.48292425525, 134390.01112293909, 134415.54053398955, 134441.07115729159, 134466.60299273001, 134492.1360401898, 134517.67029955584, 134543.20577071316, 134568.74245354676, 134594.28034794159, 134619.81945378278, 134645.35977095537, 134670.90129934452, 134696.4440388353, 134721.98798931291, 134747.53315066252, 134773.07952276937, 134798.62710551871, 134824.17589879577, 134849.72590248589, 134875.27711647438, 134900.82954064661, 134926.38317488792, 134951.93801908373, 134977.49407311951, 135003.05133688069, 135028.60981025276, 135054.16949312127, 135079.73038537172, 135105.29248688967, 135130.85579756077, 135156.42031727062, 135181.98604590484, 135207.55298334916, 135233.12112948924, 135258.69048421088, 135284.26104739975, 135309.83281894168, 135335.4057987225, 135360.97998662802, 135386.55538254412, 135412.13198635669, 135437.70979795168, 135463.28881721498, 135488.86904403262, 135514.45047829056, 135540.03311987486, 135565.61696867159, 135591.20202456677, 135616.78828744654, 135642.37575719706, 135667.96443370447, 135693.55431685498, 135719.14540653475, 135744.73770263011, 135770.33120502727, 135795.92591361253, 135821.52182827223, 135847.11894889272, 135872.7172753604, 135898.31680756161, 135923.91754538284, 135949.51948871053, 135975.12263743114, 136000.72699143123, 136026.33255059729, 136051.93931481591, 136077.54728397369, 136103.15645795723, 136128.76683665317, 136154.37841994822, 136179.99120772901, 136205.60519988232, 136231.2203962949, 136256.83679685349, 136282.45440144493, 136308.07320995603, 136333.69322227367, 136359.31443828469, 136384.93685787608, 136410.56048093468, 136436.18530734754, 136461.81133700156, 136487.43856978384, 136513.06700558143, 136538.6966442813, 136564.32748577066, 136589.95952993655, 136615.59277666616, 136641.22722584667, 136666.86287736523, 136692.49973110916, 136718.13778696564, 136743.77704482197, 136769.41750456547, 136795.05916608346, 136820.70202926331, 136846.34609399244, 136871.99136015819, 136897.63782764805, 136923.28549634948, 136948.93436614997, 136974.58443693706, 137000.23570859825, 137025.88818102115, 137051.54185409332, 137077.19672770242, 137102.85280173609, 137128.51007608202, 137154.16855062786, 137179.82822526142, 137205.48909987041, 137231.15117434258, 137256.8144485658, 137282.47892242789, 137308.14459581667, 137333.81146862009, 137359.47954072602, 137385.14881202241, 137410.81928239719, 137436.49095173844, 137462.16381993407, 137487.83788687221, 137513.51315244089, 137539.18961652822, 137564.86727902229, 137590.54613981131, 137616.22619878338, 137641.90745582676, 137667.58991082967, 137693.27356368033, 137718.95841426702, 137744.64446247809, 137770.33170820182, 137796.02015132661, 137821.70979174081, 137847.40062933284, 137873.09266399115, 137898.78589560417, 137924.48032406042, 137950.17594924837, 137975.8727710566, 138001.57078937365, 138027.27000408815, 138052.97041508864, 138078.67202226384, 138104.3748255024, 138130.07882469296, 138155.78401972432, 138181.49041048516, 138207.1979968643, 138232.9067787505, 138258.61675603263, 138284.32792859949, 138310.04029633995, 138335.75385914298, 138361.46861689744, 138387.18456949232, 138412.90171681659, 138438.62005875923, 138464.33959520931, 138490.06032605586, 138515.78225118798, 138541.50537049473, 138567.2296838653, 138592.95519118884, 138618.68189235451, 138644.40978725153, 138670.13887576913, 138695.86915779658, 138721.60063322316, 138747.33330193823, 138773.06716383106, 138798.80221879104, 138824.53846670757, 138850.27590747006, 138876.01454096794, 138901.7543670907, 138927.49538572782, 138953.2375967688, 138978.9810001032, 139004.72559562061, 139030.47138321059, 139056.2183627628, 139081.96653416683, 139107.71589731239, 139133.46645208917, 139159.21819838689, 139184.97113609532, 139210.72526510421, 139236.48058530336, 139262.23709658257, 139287.99479883176, 139313.75369194071, 139339.51377579942, 139365.27505029776, 139391.03751532568, 139416.80117077316, 139442.56601653024, 139468.33205248689, 139494.09927853322, 139519.86769455927, 139545.63730045516, 139571.408096111, 139597.18008141697, 139622.95325626322, 139648.72762054001, 139674.5031741375, 139700.27991694602, 139726.05784885579, 139751.83696975713, 139777.61727954043, 139803.39877809596, 139829.18146531415, 139854.96534108539, 139880.75040530015, 139906.53665784886, 139932.32409862199, 139958.11272751007, 139983.90254440365, 140009.69354919327, 140035.48574176949, 140061.27912202294, 140087.07368984428, 140112.86944512415, 140138.66638775321, 140164.4645176222, 140190.26383462184, 140216.06433864293, 140241.86602957622, 140267.66890731253, 140293.47297174268, 140319.27822275754, 140345.08466024802, 140370.89228410498, 140396.70109421943, 140422.51109048226, 140448.32227278448, 140474.13464101712, 140499.94819507122, 140525.76293483781, 140551.57886020801, 140577.3959710729, 140603.21426732364, 140629.03374885136, 140654.85441554731, 140680.67626730262, 140706.49930400858, 140732.32352555645, 140758.1489318375, 140783.97552274304, 140809.80329816442, 140835.63225799298, 140861.46240212015, 140887.29373043729, 140913.12624283586, 140938.95993920733, 140964.79481944317, 140990.63088343487, 141016.46813107401, 141042.30656225214, 141068.14617686081, 141093.98697479168, 141119.82895593636, 141145.6721201865, 141171.51646743377, 141197.36199756994, 141223.20871048668, 141249.05660607578, 141274.90568422904, 141300.75594483822, 141326.6073877952, 141352.4600129918, 141378.31382031992, 141404.16880967148, 141430.02498093838, 141455.8823340126, 141481.74086878612, 141507.60058515094, 141533.46148299909, 141559.32356222265, 141585.18682271364, 141611.05126436421, 141636.9168870665, 141662.78369071262, 141688.65167519479, 141714.5208404052, 141740.39118623605, 141766.26271257963, 141792.1354193282, 141818.00930637406, 141843.88437360956, 141869.760620927, 141895.6380482188, 141921.51665537735, 141947.39644229505, 141973.27740886438, 141999.15955497778, 142025.04288052776, 142050.92738540689, 142076.81306950765, 142102.69993272264, 142128.58797494444, 142154.47719606571, 142180.36759597904, 142206.25917457714, 142232.15193175265, 142258.04586739838, 142283.94098140698, 142309.83727367126, 142335.73474408401, 142361.63339253806, 142387.5332189262, 142413.43422314132, 142439.33640507635, 142465.23976462413, 142491.14430167765, 142517.05001612983, 142542.95690787368, 142568.86497680223, 142594.77422280848, 142620.68464578551, 142646.5962456264, 142672.50902222423, 142698.42297547215, 142724.33810526333, 142750.25441149093, 142776.17189404817, 142802.09055282827, 142828.01038772447, 142853.93139863008, 142879.85358543837, 142905.77694804268, 142931.70148633636, 142957.62720021277, 142983.55408956532, 143009.48215428743, 143035.41139427255, 143061.34180941415, 143087.27339960571, 143113.20616474075, 143139.14010471283, 143165.07521941551, 143191.01150874238, 143216.94897258704, 143242.88761084314, 143268.82742340435, 143294.76841016437, 143320.71057101688, 143346.65390585564, 143372.59841457437, 143398.54409706692, 143424.49095322701, 143450.43898294857, 143476.38818612538, 143502.33856265133, 143528.29011242036, 143554.24283532638, 143580.19673126334, 143606.1518001252, 143632.10804180597, 143658.06545619969, 143684.02404320039, 143709.98380270213, 143735.944734599, 143761.90683878519, 143787.87011515474, 143813.83456360188, 143839.8001840208, 143865.76697630569, 143891.73494035081, 143917.7040760504, 143943.67438329876, 143969.6458619902, 143995.61851201905, 144021.59233327967, 144047.56732566646, 144073.54348907378, 144099.52082339607, 144125.49932852783, 144151.4790043635, 144177.45985079758, 144203.44186772458, 144229.42505503909, 144255.40941263564, 144281.39494040885, 144307.38163825331, 144333.36950606373, 144359.35854373468, 144385.34875116093, 144411.34012823718, 144437.33267485813, 144463.32639091855, 144489.32127631325, 144515.31733093705, 144541.31455468474, 144567.3129474512, 144593.3125091313, 144619.31323961995, 144645.31513881206, 144671.31820660262, 144697.32244288657, 144723.32784755889, 144749.33442051467, 144775.34216164888, 144801.35107085665, 144827.36114803303, 144853.37239307314, 144879.38480587213, 144905.39838632516, 144931.41313432742, 144957.4290497741, 144983.44613256046, 145009.46438258173, 145035.48379973322, 145061.50438391021, 145087.52613500805, 145113.54905292206, 145139.57313754765, 145165.59838878017, 145191.62480651509, 145217.65239064783, 145243.68114107384, 145269.71105768863, 145295.74214038774, 145321.77438906668, 145347.80780362099, 145373.84238394629, 145399.87812993818, 145425.91504149229, 145451.95311850426, 145477.9923608698, 145504.03276848458, 145530.07434124436, 145556.11707904484, 145582.16098178181, 145608.20604935108, 145634.25228164849, 145660.29967856981, 145686.34824001096, 145712.39796586783, 145738.4488560363, 145764.50091041232, 145790.55412889185, 145816.60851137087, 145842.66405774537, 145868.72076791141, 145894.77864176501, 145920.83767920226, 145946.89788011924, 145972.95924441208, 145999.02177197693, 146025.08546270995, 146051.15031650732, 146077.21633326527, 146103.28351288004, 146129.35185524789, 146155.42136026506, 146181.49202782792, 146207.56385783272, 146233.63685017588, 146259.71100475377, 146285.78632146274, 146311.86280019928, 146337.94044085976, 146364.01924334071, 146390.09920753856, 146416.18033334985, 146442.26262067116, 146468.34606939898, 146494.43067942993, 146520.51645066062, 146546.60338298764, 146572.69147630769, 146598.78073051744, 146624.87114551352, 146650.96272119274, 146677.05545745179, 146703.14935418745, 146729.2444112965, 146755.34062867577, 146781.43800622207, 146807.53654383228, 146833.63624140329, 146859.73709883197, 146885.83911601527, 146911.94229285014, 146938.04662923355, 146964.15212506248, 146990.25878023397, 147016.36659464505, 147042.47556819281, 147068.58570077427, 147094.6969922866, 147120.80944262692, 147146.92305169237, 147173.03781938017, 147199.15374558745, 147225.27083021149, 147251.38907314953, 147277.50847429881, 147303.62903355664, 147329.75075082036, 147355.87362598727, 147381.99765895473, 147408.12284962015, 147434.24919788091, 147460.37670363448, 147486.50536677826, 147512.63518720976, 147538.76616482646, 147564.89829952587, 147591.03159120557, 147617.16603976308, 147643.30164509601, 147669.43840710199, 147695.57632567859, 147721.71540072354, 147747.85563213445, 147773.99701980909, 147800.13956364512, 147826.28326354033, 147852.42811939248, 147878.57413109933, 147904.72129855872, 147930.86962166851, 147957.01910032652, 147983.16973443062, 148009.32152387875, 148035.47446856883, 148061.62856839882, 148087.78382326665, 148113.94023307035, 148140.09779770792, 148166.25651707739, 148192.41639107687, 148218.57741960438, 148244.73960255808, 148270.90293983606, 148297.0674313365, 148323.23307695755, 148349.39987659742, 148375.56783015432, 148401.73693752653, 148427.90719861226, 148454.07861330983, 148480.25118151752, 148506.42490313368, 148532.59977805667, 148558.77580618486, 148584.95298741665, 148611.13132165043, 148637.31080878471, 148663.49144871789, 148689.6732413485, 148715.85618657502, 148742.040284296, 148768.22553440998, 148794.41193681557, 148820.59949141133, 148846.78819809589, 148872.97805676793, 148899.16906732606, 148925.36122966901, 148951.55454369547, 148977.74900930419, 149003.9446263939, 149030.1413948634, 149056.33931461151, 149082.53838553699, 149108.73860753875, 149134.9399805156, 149161.14250436646, 149187.34617899026, 149213.5510042859, 149239.75698015234, 149265.96410648854, 149292.17238319354, 149318.38181016635, 149344.59238730598, 149370.80411451156, 149397.01699168212, 149423.23101871679, 149449.44619551473, 149475.66252197503, 149501.87999799693, 149528.0986234796, 149554.31839832227, 149580.53932242419, 149606.76139568459, 149632.98461800278, 149659.20898927809, 149685.43450940982, 149711.66117829733, 149737.88899584001, 149764.11796193724, 149790.34807648844, 149816.57933939309, 149842.81175055061, 149869.04530986046, 149895.28001722222, 149921.51587253538, 149947.75287569952, 149973.99102661415, 150000.23032517891, 150026.47077129342, 150052.71236485732, 150078.95510577026, 150105.1989939319, 150131.444029242, 150157.69021160025, 150183.93754090639, 150210.18601706024, 150236.43563996154, 150262.68640951012, 150288.93832560582, 150315.19138814852, 150341.44559703805, 150367.70095217437, 150393.95745345735, 150420.21510078697, 150446.47389406321, 150472.73383318601, 150498.99491805542, 150525.25714857146, 150551.52052463419, 150577.78504614369, 150604.05071300003, 150630.31752510337, 150656.58548235384, 150682.85458465159, 150709.1248318968, 150735.39622398972, 150761.66876083051, 150787.9424423195, 150814.21726835691, 150840.49323884305, 150866.77035367821, 150893.04861276277, 150919.32801599705, 150945.60856328148, 150971.89025451642, 150998.17308960229, 151024.45706843957, 151050.74219092872, 151077.02845697021, 151103.31586646455, 151129.60441931229, 151155.894115414, 151182.1849546702, 151208.47693698155, 151234.77006224863, 151261.06433037209, 151287.35974125259, 151313.65629479082, 151339.95399088747, 151366.25282944329, 151392.55281035902, 151418.85393353543, 151445.1561988733, 151471.45960627345, 151497.76415563675, 151524.06984686397, 151550.37667985607, 151576.68465451393, 151602.99377073845, 151629.30402843058, 151655.61542749128, 151681.92796782157, 151708.24164932242, 151734.55647189484, 151760.87243543993, 151787.18953985872, 151813.50778505235, 151839.82717092187, 151866.14769736846, 151892.46936429327, 151918.79217159748, 151945.11611918229, 151971.44120694889, 151997.76743479856, 152024.09480263255, 152050.42331035214, 152076.75295785864, 152103.08374505339, 152129.41567183775, 152155.74873811303, 152182.08294378067, 152208.41828874208, 152234.75477289871, 152261.09239615197, 152287.43115840337, 152313.77105955439, 152340.11209950657, 152366.45427816146, 152392.79759542056, 152419.14205118554, 152445.48764535793, 152471.8343778394, 152498.18224853161, 152524.53125733617, 152550.88140415482, 152577.23268888926, 152603.58511144121, 152629.93867171241, 152656.29336960468, 152682.64920501978, 152709.00617785956, 152735.36428802583, 152761.72353542043, 152788.08391994529, 152814.44544150229, 152840.80809999333, 152867.17189532038, 152893.53682738543, 152919.90289609041, 152946.27010133737, 152972.63844302832, 152999.00792106529, 153025.37853535041, 153051.7502857857, 153078.12317227334, 153104.4971947154, 153130.8723530141, 153157.24864707157, 153183.62607679001, 153210.00464207167, 153236.38434281875, 153262.76517893354, 153289.14715031831, 153315.53025687535, 153341.91449850702, 153368.2998751156, 153394.68638660354, 153421.07403287315, 153447.46281382689, 153473.85272936718, 153500.24377939643, 153526.63596381716, 153553.02928253182, 153579.42373544298, 153605.81932245308, 153632.21604346478, 153658.61389838057, 153685.0128871031, 153711.41300953497, 153737.81426557881, 153764.21665513728, 153790.62017811305, 153817.02483440886, 153843.43062392739, 153869.83754657139, 153896.24560224367, 153922.65479084692, 153949.06511228404, 153975.4765664578, 154001.88915327107, 154028.30287262669, 154054.71772442761, 154081.13370857667, 154107.55082497682, 154133.96907353101, 154160.38845414223, 154186.80896671346, 154213.23061114774, 154239.65338734805, 154266.07729521746, 154292.50233465908, 154318.92850557598, 154345.35580787127, 154371.7842414481, 154398.21380620965, 154424.64450205903, 154451.07632889951, 154477.50928663427, 154503.94337516659, 154530.37859439969, 154556.81494423689, 154583.25242458144, 154609.69103533673, 154636.13077640603, 154662.57164769279, 154689.01364910032, 154715.45678053208, 154741.90104189145, 154768.34643308193, 154794.79295400696, 154821.24060457002, 154847.68938467462, 154874.13929422433, 154900.59033312264, 154927.04250127316, 154953.49579857948, 154979.95022494521, 155006.40578027396, 155032.86246446942, 155059.32027743524, 155085.77921907514, 155112.2392892928, 155138.70048799197, 155165.16281507642, 155191.62627044989, 155218.09085401625, 155244.55656567923, 155271.02340534274, 155297.49137291059, 155323.96046828668, 155350.4306913749, 155376.90204207919, 155403.37452030348, 155429.84812595171, 155456.32285892789, 155482.79871913602, 155509.27570648011, 155535.75382086422, 155562.23306219239, 155588.71343036872, 155615.19492529731, 155641.67754688227, 155668.16129502779, 155694.64616963797, 155721.13217061706, 155747.61929786921, 155774.10755129869, 155800.59693080973, 155827.08743630661, 155853.57906769359, 155880.07182487496, 155906.56570775513, 155933.06071623837, 155959.55685022907, 155986.05410963166, 156012.5524943505, 156039.05200429002, 156065.55263935472, 156092.054399449, 156118.5572844774, 156145.06129434443, 156171.5664289546, 156198.07268821247, 156224.5800720226, 156251.08858028959, 156277.59821291809, 156304.10896981266, 156330.62085087801, 156357.1338560188, 156383.64798513969, 156410.16323814544, 156436.67961494075, 156463.1971154304, 156489.71573951913, 156516.23548711176, 156542.75635811311, 156569.27835242799, 156595.80146996127, 156622.32571061782, 156648.85107430254, 156675.37756092031, 156701.90517037612, 156728.43390257491, 156754.96375742162, 156781.49473482129, 156808.02683467892, 156834.5600568995, 156861.09440138817, 156887.62986804993, 156914.16645678994, 156940.70416751326, 156967.24300012505, 156993.78295453047, 157020.32403063469, 157046.8662283429, 157073.40954756032, 157099.9539881922, 157126.49955014378, 157153.04623332032, 157179.59403762716, 157206.14296296958, 157232.69300925292, 157259.24417638258, 157285.79646426387, 157312.34987280221, 157338.90440190304, 157365.46005147175, 157392.01682141385, 157418.57471163478, 157445.13372204005, 157471.69385253513, 157498.25510302564, 157524.81747341706, 157551.38096361503, 157577.9455735251, 157604.51130305286, 157631.07815210402, 157657.64612058419, 157684.21520839902, 157710.78541545427, 157737.35674165559, 157763.92918690876, 157790.50275111952, 157817.07743419363, 157843.65323603692, 157870.23015655516, 157896.80819565422, 157923.3873532399, 157949.96762921812, 157976.54902349479, 158003.13153597576, 158029.71516656701, 158056.29991517449, 158082.88578170416, 158109.47276606198, 158136.06086815402, 158162.65008788629, 158189.24042516484, 158215.83187989573, 158242.42445198505, 158269.01814133892, 158295.61294786347, 158322.20887146486, 158348.80591204923, 158375.4040695228, 158402.00334379176, 158428.60373476235, 158455.2052423408, 158481.80786643337, 158508.41160694641, 158535.01646378616, 158561.62243685898, 158588.2295260712, 158614.8377313292, 158641.44705253936, 158668.05748960807, 158694.66904244179, 158721.28171094693, 158747.89549502998, 158774.5103945974, 158801.12640955573, 158827.74353981143, 158854.36178527112, 158880.9811458413, 158907.60162142856, 158934.22321193956, 158960.84591728085, 158987.46973735912, 159014.09467208097, 159040.72072135314, 159067.3478850823, 159093.97616317519, 159120.60555553852, 159147.23606207906, 159173.8676827036, 159200.50041731889, 159227.13426583182, 159253.76922814918, 159280.40530417781, 159307.04249382461, 159333.68079699649, 159360.32021360032, 159386.96074354305, 159413.60238673165, 159440.24514307309, 159466.88901247433, 159493.53399484244, 159520.18009008438, 159546.82729810724, 159573.47561881805, 159600.12505212394, 159626.77559793202, 159653.42725614941, 159680.08002668325, 159706.73390944069, 159733.38890432892, 159760.04501125516, 159786.70223012666, 159813.36056085059, 159840.02000333427, 159866.68055748497, 159893.34222320997, 159920.00500041663, 159946.66888901225, 159973.33388890422, 159999.99999999988, 160026.66722220668, 160053.33555543202, 160080.0049995833, 160106.67555456801, 160133.3472202936, 160160.0199966676, 160186.6938835975, 160213.36888099083, 160240.04498875517, 160266.72220679806, 160293.40053502709, 160320.07997334987, 160346.76052167406, 160373.44217990729, 160400.1249479572, 160426.80882573154, 160453.49381313793, 160480.17991008417, 160506.86711647795, 160533.55543222709, 160560.24485723933, 160586.93539142248, 160613.62703468435, 160640.31978693281, 160667.01364807569, 160693.70861802087, 160720.40469667627, 160747.1018839498, 160773.80017974938, 160800.49958398298, 160827.20009655855, 160853.90171738411, 160880.60444636765, 160907.30828341722, 160934.01322844089, 160960.71928134665, 160987.42644204266, 161014.13471043704, 161040.84408643784, 161067.55456995327, 161094.26616089148, 161120.97885916062, 161147.69266466892, 161174.40757732463, 161201.12359703594, 161227.84072371112, 161254.55895725847, 161281.27829758628, 161307.99874460287, 161334.72029821656, 161361.44295833571, 161388.1667248687, 161414.89159772391, 161441.61757680977, 161468.34466203468, 161495.07285330712, 161521.80215053557, 161548.53255362847, 161575.26406249436, 161601.99667704175, 161628.7303971792, 161655.46522281526, 161682.20115385848, 161708.93819021754, 161735.67633180099, 161762.41557851751, 161789.15593027571, 161815.89738698432, 161842.63994855201, 161869.38361488748, 161896.1283858995, 161922.87426149679, 161949.62124158812, 161976.36932608229, 162003.1185148881, 162029.8688079144, 162056.62020507001, 162083.37270626382, 162110.12631140469, 162136.88102040152, 162163.63683316324, 162190.39374959879, 162217.15176961714, 162243.91089312723, 162270.67112003808, 162297.43245025873, 162324.19488369819, 162350.9584202655, 162377.72305986975, 162404.48880242003, 162431.25564782543, 162458.02359599507, 162484.79264683815, 162511.56280026378, 162538.33405618116, 162565.10641449949, 162591.87987512801, 162618.65443797593, 162645.43010295252, 162672.20686996708, 162698.98473892888, 162725.76370974723, 162752.54378233149, 162779.32495659095, 162806.10723243505, 162832.89060977317, 162859.67508851466, 162886.46066856899, 162913.24734984562, 162940.03513225398, 162966.82401570358, 162993.6140001039, 163020.40508536444, 163047.19727139481, 163073.99055810447, 163100.78494540305, 163127.58043320014, 163154.37702140535, 163181.17470992831, 163207.97349867865, 163234.77338756606, 163261.57437650024, 163288.37646539087, 163315.17965414765, 163341.98394268038, 163368.78933089875, 163395.59581871261, 163422.40340603172, 163449.2120927659, 163476.02187882498, 163502.83276411882, 163529.6447485573, 163556.45783205028, 163583.2720145077, 163610.08729583945, 163636.90367595552, 163663.72115476584, 163690.53973218042, 163717.35940810922, 163744.18018246227, 163771.00205514964, 163797.82502608138, 163824.64909516752, 163851.4742623182, 163878.3005274435, 163905.12789045356, 163931.95635125853, 163958.78590976857, 163985.61656589387, 164012.44831954464, 164039.28117063109, 164066.11511906344, 164092.95016475199, 164119.78630760699, 164146.62354753874, 164173.46188445756, 164200.30131827376, 164227.14184889771, 164253.98347623978, 164280.82620021031, 164307.67002071979, 164334.51493767856, 164361.3609509971, 164388.20806058586, 164415.05626635533, 164441.905568216, 164468.75596607837, 164495.607459853, 164522.4600494504, 164549.31373478117, 164576.16851575591, 164603.02439228518, 164629.88136427966, 164656.73943164994, 164683.59859430668, 164710.45885216061, 164737.32020512238, 164764.1826531027, 164791.04619601235, 164817.91083376206, 164844.77656626256, 164871.64339342469, 164898.51131515924, 164925.38033137703, 164952.25044198887, 164979.1216469057, 165005.9939460383, 165032.86733929763, 165059.7418265946, 165086.61740784015, 165113.4940829452 }; #else #ifdef BIG_IQ_TABLE #define IQ_TABLE_SIZE 8192 #else #define IQ_TABLE_SIZE 1026 #endif ALIGN static const real_t iq_table[IQ_TABLE_SIZE] = { REAL_CONST(0.0), REAL_CONST(1.0/8.0), REAL_CONST(2.5198420997897464/8.0), REAL_CONST(4.3267487109222245/8.0), REAL_CONST(6.3496042078727974/8.0), REAL_CONST(8.5498797333834844/8.0), REAL_CONST(10.902723556992836/8.0), REAL_CONST(13.390518279406722/8.0), REAL_CONST(15.999999999999998/8.0), REAL_CONST(18.720754407467133/8.0), REAL_CONST(21.544346900318832/8.0), REAL_CONST(24.463780996262464/8.0), REAL_CONST(27.47314182127996/8.0), REAL_CONST(30.567350940369842/8.0), REAL_CONST(33.741991698453212/8.0), REAL_CONST(36.993181114957046/8.0), REAL_CONST(40.317473596635935/8.0), REAL_CONST(43.711787041189993/8.0), REAL_CONST(47.173345095760126/8.0), REAL_CONST(50.699631325716943/8.0), REAL_CONST(54.288352331898118/8.0), REAL_CONST(57.937407704003519/8.0), REAL_CONST(61.6448652744185/8.0), REAL_CONST(65.408940536585988/8.0), REAL_CONST(69.227979374755591/8.0), REAL_CONST(73.100443455321638/8.0), REAL_CONST(77.024897778591622/8.0), REAL_CONST(80.999999999999986/8.0), REAL_CONST(85.024491212518527/8.0), REAL_CONST(89.097187944889555/8.0), REAL_CONST(93.216975178615741/8.0), REAL_CONST(97.382800224133163/8.0), REAL_CONST(101.59366732596474/8.0), REAL_CONST(105.84863288986224/8.0), REAL_CONST(110.14680124343441/8.0), REAL_CONST(114.4873208566006/8.0), REAL_CONST(118.86938096020653/8.0), REAL_CONST(123.29220851090024/8.0), REAL_CONST(127.75506545836058/8.0), REAL_CONST(132.25724627755247/8.0), REAL_CONST(136.79807573413572/8.0), REAL_CONST(141.37690685569191/8.0), REAL_CONST(145.99311908523086/8.0), REAL_CONST(150.6461165966291/8.0), REAL_CONST(155.33532675434674/8.0), REAL_CONST(160.06019870205279/8.0), REAL_CONST(164.82020206673349/8.0), REAL_CONST(169.61482576651861/8.0), REAL_CONST(174.44357691188537/8.0), REAL_CONST(179.30597979112557/8.0), REAL_CONST(184.20157493201927/8.0), REAL_CONST(189.12991823257562/8.0), REAL_CONST(194.09058015449685/8.0), REAL_CONST(199.08314497371677/8.0), REAL_CONST(204.1072100829694/8.0), REAL_CONST(209.16238534187647/8.0), REAL_CONST(214.24829247050752/8.0), REAL_CONST(219.36456448277784/8.0), REAL_CONST(224.51084515641216/8.0), REAL_CONST(229.6867885365223/8.0), REAL_CONST(234.89205847013176/8.0), REAL_CONST(240.12632816923249/8.0), REAL_CONST(245.38927980018505/8.0), REAL_CONST(250.68060409747261/8.0), REAL_CONST(255.99999999999991/8.0), REAL_CONST(261.34717430828869/8.0), REAL_CONST(266.72184136106449/8.0), REAL_CONST(272.12372272986045/8.0), REAL_CONST(277.55254693037961/8.0), REAL_CONST(283.0080491494619/8.0), REAL_CONST(288.48997098659891/8.0), REAL_CONST(293.99806020902247/8.0), REAL_CONST(299.53207051947408/8.0), REAL_CONST(305.0917613358298/8.0), REAL_CONST(310.67689758182206/8.0), REAL_CONST(316.28724948815585/8.0), REAL_CONST(321.92259240337177/8.0), REAL_CONST(327.58270661385535/8.0), REAL_CONST(333.26737717243742/8.0), REAL_CONST(338.97639373507025/8.0), REAL_CONST(344.70955040510125/8.0), REAL_CONST(350.46664558470013/8.0), REAL_CONST(356.24748183302603/8.0), REAL_CONST(362.05186573075139/8.0), REAL_CONST(367.87960775058258/8.0), REAL_CONST(373.73052213344511/8.0), REAL_CONST(379.60442677002078/8.0), REAL_CONST(385.50114308734607/8.0), REAL_CONST(391.42049594019937/8.0), REAL_CONST(397.36231350702371/8.0), REAL_CONST(403.32642719014467/8.0), REAL_CONST(409.31267152006262/8.0), REAL_CONST(415.32088406360799/8.0), REAL_CONST(421.35090533576471/8.0), REAL_CONST(427.40257871497619/8.0), REAL_CONST(433.4757503617617/8.0), REAL_CONST(439.5702691404793/8.0), REAL_CONST(445.68598654408271/8.0), REAL_CONST(451.82275662172759/8.0), REAL_CONST(457.98043590909128/8.0), REAL_CONST(464.15888336127773/8.0), REAL_CONST(470.35796028818726/8.0), REAL_CONST(476.5775302922363/8.0), REAL_CONST(482.81745920832043/8.0), REAL_CONST(489.07761504591741/8.0), REAL_CONST(495.35786793323581/8.0), REAL_CONST(501.65809006331688/8.0), REAL_CONST(507.97815564200368/8.0), REAL_CONST(514.31794083769648/8.0), REAL_CONST(520.67732373281672/8.0), REAL_CONST(527.05618427690604/8.0), REAL_CONST(533.45440424129174/8.0), REAL_CONST(539.87186717525128/8.0), REAL_CONST(546.30845836361505/8.0), REAL_CONST(552.76406478574609/8.0), REAL_CONST(559.23857507584194/8.0), REAL_CONST(565.73187948450413/8.0), REAL_CONST(572.24386984152341/8.0), REAL_CONST(578.77443951983378/8.0), REAL_CONST(585.32348340058843/8.0), REAL_CONST(591.89089783931263/8.0), REAL_CONST(598.47658063309257/8.0), REAL_CONST(605.08043098876044/8.0), REAL_CONST(611.70234949203643/8.0), REAL_CONST(618.3422380775919/8.0), REAL_CONST(624.99999999999977/8.0), REAL_CONST(631.67553980553748/8.0), REAL_CONST(638.36876330481164/8.0), REAL_CONST(645.07957754617485/8.0), REAL_CONST(651.80789078990415/8.0), REAL_CONST(658.55361248311499/8.0), REAL_CONST(665.31665323538357/8.0), REAL_CONST(672.09692479505225/8.0), REAL_CONST(678.8943400261943/8.0), REAL_CONST(685.70881288621433/8.0), REAL_CONST(692.540258404062/8.0), REAL_CONST(699.38859265903977/8.0), REAL_CONST(706.25373276018058/8.0), REAL_CONST(713.13559682617972/8.0), REAL_CONST(720.03410396586037/8.0), REAL_CONST(726.94917425915435/8.0), REAL_CONST(733.88072873858209/8.0), REAL_CONST(740.82868937121543/8.0), REAL_CONST(747.79297904110535/8.0), REAL_CONST(754.77352153216191/8.0), REAL_CONST(761.77024151147043/8.0), REAL_CONST(768.78306451302956/8.0), REAL_CONST(775.81191692189896/8.0), REAL_CONST(782.85672595874246/8.0), REAL_CONST(789.91741966475445/8.0), REAL_CONST(796.99392688695798/8.0), REAL_CONST(804.08617726386274/8.0), REAL_CONST(811.19410121147098/8.0), REAL_CONST(818.31762990962227/8.0), REAL_CONST(825.45669528866563/8.0), REAL_CONST(832.61123001644864/8.0), REAL_CONST(839.78116748561604/8.0), REAL_CONST(846.96644180120552/8.0), REAL_CONST(854.16698776853514/8.0), REAL_CONST(861.38274088137143/8.0), REAL_CONST(868.61363731036977/8.0), REAL_CONST(875.85961389178203/8.0), REAL_CONST(883.12060811641959/8.0), REAL_CONST(890.39655811886757/8.0), REAL_CONST(897.68740266694181/8.0), REAL_CONST(904.99308115138172/8.0), REAL_CONST(912.31353357577188/8.0), REAL_CONST(919.64870054668756/8.0), REAL_CONST(926.99852326405619/8.0), REAL_CONST(934.36294351172899/8.0), REAL_CONST(941.74190364825859/8.0), REAL_CONST(949.13534659787422/8.0), REAL_CONST(956.54321584165211/8.0), REAL_CONST(963.96545540887348/8.0), REAL_CONST(971.40200986856541/8.0), REAL_CONST(978.85282432122176/8.0), REAL_CONST(986.31784439069588/8.0), REAL_CONST(993.7970162162635/8.0), REAL_CONST(1001.29028644485/8.0), REAL_CONST(1008.797602223418/8.0), REAL_CONST(1016.3189111915103/8.0), REAL_CONST(1023.8541614739464/8.0), REAL_CONST(1031.4033016736653/8.0), REAL_CONST(1038.9662808647138/8.0), REAL_CONST(1046.5430485853758/8.0), REAL_CONST(1054.1335548314366/8.0), REAL_CONST(1061.7377500495838/8.0), REAL_CONST(1069.3555851309357/8.0), REAL_CONST(1076.9870114046978/8.0), REAL_CONST(1084.6319806319441/8.0), REAL_CONST(1092.2904449995174/8.0), REAL_CONST(1099.9623571140482/8.0), REAL_CONST(1107.6476699960892/8.0), REAL_CONST(1115.3463370743607/8.0), REAL_CONST(1123.058312180106/8.0), REAL_CONST(1130.7835495415541/8.0), REAL_CONST(1138.5220037784854/8.0), REAL_CONST(1146.273629896901/8.0), REAL_CONST(1154.0383832837879/8.0), REAL_CONST(1161.816219701986/8.0), REAL_CONST(1169.607095285146/8.0), REAL_CONST(1177.4109665327808/8.0), REAL_CONST(1185.2277903054078/8.0), REAL_CONST(1193.0575238197798/8.0), REAL_CONST(1200.9001246442001/8.0), REAL_CONST(1208.7555506939248/8.0), REAL_CONST(1216.6237602266442/8.0), REAL_CONST(1224.5047118380478/8.0), REAL_CONST(1232.3983644574657/8.0), REAL_CONST(1240.3046773435874/8.0), REAL_CONST(1248.2236100802568/8.0), REAL_CONST(1256.1551225723395/8.0), REAL_CONST(1264.099175041662/8.0), REAL_CONST(1272.0557280230228/8.0), REAL_CONST(1280.0247423602691/8.0), REAL_CONST(1288.0061792024444/8.0), REAL_CONST(1295.9999999999995/8.0), REAL_CONST(1304.006166501068/8.0), REAL_CONST(1312.0246407478062/8.0), REAL_CONST(1320.0553850727929/8.0), REAL_CONST(1328.0983620954903/8.0), REAL_CONST(1336.1535347187651/8.0), REAL_CONST(1344.2208661254647/8.0), REAL_CONST(1352.3003197750522/8.0), REAL_CONST(1360.3918594002962/8.0), REAL_CONST(1368.4954490040145/8.0), REAL_CONST(1376.6110528558709/8.0), REAL_CONST(1384.7386354892244/8.0), REAL_CONST(1392.8781616980295/8.0), REAL_CONST(1401.0295965337855/8.0), REAL_CONST(1409.1929053025353/8.0), REAL_CONST(1417.3680535619119/8.0), REAL_CONST(1425.5550071182327/8.0), REAL_CONST(1433.7537320236374/8.0), REAL_CONST(1441.9641945732744/8.0), REAL_CONST(1450.1863613025282/8.0), REAL_CONST(1458.4201989842913/8.0), REAL_CONST(1466.6656746262797/8.0), REAL_CONST(1474.9227554683875/8.0), REAL_CONST(1483.1914089800841/8.0), REAL_CONST(1491.4716028578516/8.0), REAL_CONST(1499.7633050226596/8.0), REAL_CONST(1508.0664836174794/8.0), REAL_CONST(1516.3811070048375/8.0), REAL_CONST(1524.7071437644029/8.0), REAL_CONST(1533.0445626906128/8.0), REAL_CONST(1541.3933327903342/8.0), REAL_CONST(1549.7534232805581/8.0), REAL_CONST(1558.1248035861302/8.0), REAL_CONST(1566.507443337515/8.0), REAL_CONST(1574.9013123685909/8.0), REAL_CONST(1583.3063807144795/8.0), REAL_CONST(1591.7226186094069/8.0), REAL_CONST(1600.1499964845941/8.0), REAL_CONST(1608.58848496618/8.0), REAL_CONST(1617.0380548731737/8.0), REAL_CONST(1625.4986772154357/8.0), REAL_CONST(1633.9703231916887/8.0), REAL_CONST(1642.4529641875577/8.0), REAL_CONST(1650.9465717736346/8.0), REAL_CONST(1659.4511177035752/8.0), REAL_CONST(1667.9665739122186/8.0), REAL_CONST(1676.4929125137353/8.0), REAL_CONST(1685.030105799801/8.0), REAL_CONST(1693.5781262377957/8.0), REAL_CONST(1702.136946469027/8.0), REAL_CONST(1710.7065393069795/8.0), REAL_CONST(1719.2868777355877/8.0), REAL_CONST(1727.8779349075323/8.0), REAL_CONST(1736.4796841425596/8.0), REAL_CONST(1745.092098925825/8.0), REAL_CONST(1753.7151529062583/8.0), REAL_CONST(1762.3488198949503/8.0), REAL_CONST(1770.9930738635628/8.0), REAL_CONST(1779.6478889427597/8.0), REAL_CONST(1788.3132394206564/8.0), REAL_CONST(1796.9890997412947/8.0), REAL_CONST(1805.6754445031333/8.0), REAL_CONST(1814.3722484575621/8.0), REAL_CONST(1823.0794865074322/8.0), REAL_CONST(1831.7971337056094/8.0), REAL_CONST(1840.5251652535437/8.0), REAL_CONST(1849.2635564998579/8.0), REAL_CONST(1858.0122829389563/8.0), REAL_CONST(1866.7713202096493/8.0), REAL_CONST(1875.5406440937966/8.0), REAL_CONST(1884.3202305149687/8.0), REAL_CONST(1893.110055537124/8.0), REAL_CONST(1901.9100953633042/8.0), REAL_CONST(1910.7203263343454/8.0), REAL_CONST(1919.5407249276057/8.0), REAL_CONST(1928.3712677557098/8.0), REAL_CONST(1937.2119315653083/8.0), REAL_CONST(1946.0626932358525/8.0), REAL_CONST(1954.923529778386/8.0), REAL_CONST(1963.79441833435/8.0), REAL_CONST(1972.6753361744036/8.0), REAL_CONST(1981.5662606972594/8.0), REAL_CONST(1990.467169428533/8.0), REAL_CONST(1999.3780400196069/8.0), REAL_CONST(2008.2988502465078/8.0), REAL_CONST(2017.2295780087982/8.0), REAL_CONST(2026.1702013284819/8.0), REAL_CONST(2035.1206983489212/8.0), REAL_CONST(2044.0810473337688/8.0), REAL_CONST(2053.0512266659125/8.0), REAL_CONST(2062.0312148464309/8.0), REAL_CONST(2071.0209904935646/8.0), REAL_CONST(2080.0205323416958/8.0), REAL_CONST(2089.0298192403443/8.0), REAL_CONST(2098.0488301531714/8.0), REAL_CONST(2107.0775441569995/8.0), REAL_CONST(2116.115940440839/8.0), REAL_CONST(2125.1639983049317/8.0), REAL_CONST(2134.2216971597995/8.0), REAL_CONST(2143.2890165253098/8.0), REAL_CONST(2152.3659360297484/8.0), REAL_CONST(2161.4524354089031/8.0), REAL_CONST(2170.5484945051617/8.0), REAL_CONST(2179.6540932666144/8.0), REAL_CONST(2188.7692117461711/8.0), REAL_CONST(2197.8938301006888/8.0), REAL_CONST(2207.0279285901042/8.0), REAL_CONST(2216.1714875765838/8.0), REAL_CONST(2225.324487523676/8.0), REAL_CONST(2234.4869089954782/8.0), REAL_CONST(2243.6587326558101/8.0), REAL_CONST(2252.8399392673982/8.0), REAL_CONST(2262.0305096910702/8.0), REAL_CONST(2271.2304248849537/8.0), REAL_CONST(2280.4396659036897/8.0), REAL_CONST(2289.6582138976523/8.0), REAL_CONST(2298.8860501121762/8.0), REAL_CONST(2308.1231558867926/8.0), REAL_CONST(2317.3695126544767/8.0), REAL_CONST(2326.6251019409005/8.0), REAL_CONST(2335.8899053636933/8.0), REAL_CONST(2345.1639046317132/8.0), REAL_CONST(2354.4470815443233/8.0), REAL_CONST(2363.7394179906792/8.0), REAL_CONST(2373.0408959490205/8.0), REAL_CONST(2382.3514974859731/8.0), REAL_CONST(2391.6712047558558/8.0), REAL_CONST(2400.9999999999991/8.0), REAL_CONST(2410.3378655460651/8.0), REAL_CONST(2419.6847838073813/8.0), REAL_CONST(2429.0407372822747/8.0), REAL_CONST(2438.4057085534191/8.0), REAL_CONST(2447.7796802871858/8.0), REAL_CONST(2457.1626352330004/8.0), REAL_CONST(2466.5545562227112/8.0), REAL_CONST(2475.9554261699564/8.0), REAL_CONST(2485.3652280695474/8.0), REAL_CONST(2494.7839449968492/8.0), REAL_CONST(2504.2115601071737/8.0), REAL_CONST(2513.6480566351788/8.0), REAL_CONST(2523.0934178942675/8.0), REAL_CONST(2532.5476272760025/8.0), REAL_CONST(2542.0106682495189/8.0), REAL_CONST(2551.482524360948/8.0), REAL_CONST(2560.9631792328441/8.0), REAL_CONST(2570.4526165636184/8.0), REAL_CONST(2579.9508201269791/8.0), REAL_CONST(2589.4577737713744/8.0), REAL_CONST(2598.9734614194458/8.0), REAL_CONST(2608.4978670674823/8.0), REAL_CONST(2618.0309747848837/8.0), REAL_CONST(2627.5727687136259/8.0), REAL_CONST(2637.1232330677353/8.0), REAL_CONST(2646.6823521327647/8.0), REAL_CONST(2656.2501102652768/8.0), REAL_CONST(2665.8264918923328/8.0), REAL_CONST(2675.4114815109842/8.0), REAL_CONST(2685.0050636877722/8.0), REAL_CONST(2694.6072230582295/8.0), REAL_CONST(2704.2179443263894/8.0), REAL_CONST(2713.8372122642972/8.0), REAL_CONST(2723.4650117115279/8.0), REAL_CONST(2733.1013275747096/8.0), REAL_CONST(2742.7461448270483/8.0), REAL_CONST(2752.3994485078601/8.0), REAL_CONST(2762.0612237221085/8.0), REAL_CONST(2771.7314556399419/8.0), REAL_CONST(2781.4101294962406/8.0), REAL_CONST(2791.0972305901655/8.0), REAL_CONST(2800.7927442847094/8.0), REAL_CONST(2810.4966560062589/8.0), REAL_CONST(2820.2089512441521/8.0), REAL_CONST(2829.9296155502466/8.0), REAL_CONST(2839.6586345384894/8.0), REAL_CONST(2849.3959938844923/8.0), REAL_CONST(2859.1416793251065/8.0), REAL_CONST(2868.8956766580086/8.0), REAL_CONST(2878.6579717412847/8.0), REAL_CONST(2888.4285504930212/8.0), REAL_CONST(2898.2073988908974/8.0), REAL_CONST(2907.9945029717837/8.0), REAL_CONST(2917.789848831344/8.0), REAL_CONST(2927.5934226236377/8.0), REAL_CONST(2937.4052105607311/8.0), REAL_CONST(2947.2251989123079/8.0), REAL_CONST(2957.0533740052865/8.0), REAL_CONST(2966.8897222234368/8.0), REAL_CONST(2976.734230007005/8.0), REAL_CONST(2986.5868838523397/8.0), REAL_CONST(2996.4476703115197/8.0), REAL_CONST(3006.3165759919889/8.0), REAL_CONST(3016.1935875561908/8.0), REAL_CONST(3026.0786917212095/8.0), REAL_CONST(3035.9718752584108/8.0), REAL_CONST(3045.8731249930906/8.0), REAL_CONST(3055.7824278041207/8.0), REAL_CONST(3065.6997706236039/8.0), REAL_CONST(3075.625140436528/8.0), REAL_CONST(3085.5585242804245/8.0), REAL_CONST(3095.4999092450298/8.0), REAL_CONST(3105.4492824719491/8.0), REAL_CONST(3115.4066311543256/8.0), REAL_CONST(3125.3719425365089/8.0), REAL_CONST(3135.3452039137287/8.0), REAL_CONST(3145.3264026317715/8.0), REAL_CONST(3155.3155260866592/8.0), REAL_CONST(3165.3125617243295/8.0), REAL_CONST(3175.3174970403229/8.0), REAL_CONST(3185.3303195794679/8.0), REAL_CONST(3195.35101693557/8.0), REAL_CONST(3205.3795767511078/8.0), REAL_CONST(3215.4159867169251/8.0), REAL_CONST(3225.460234571929/8.0), REAL_CONST(3235.5123081027928/8.0), REAL_CONST(3245.5721951436558/8.0), REAL_CONST(3255.63988357583/8.0), REAL_CONST(3265.7153613275095/8.0), REAL_CONST(3275.7986163734795/8.0), REAL_CONST(3285.8896367348289/8.0), REAL_CONST(3295.9884104786665/8.0), REAL_CONST(3306.0949257178395/8.0), REAL_CONST(3316.2091706106517/8.0), REAL_CONST(3326.331133360588/8.0), REAL_CONST(3336.4608022160378/8.0), REAL_CONST(3346.5981654700231/8.0), REAL_CONST(3356.7432114599264/8.0), REAL_CONST(3366.8959285672249/8.0), REAL_CONST(3377.0563052172211/8.0), REAL_CONST(3387.2243298787821/8.0), REAL_CONST(3397.3999910640764/8.0), REAL_CONST(3407.5832773283128/8.0), REAL_CONST(3417.7741772694862/8.0), REAL_CONST(3427.9726795281199/8.0), REAL_CONST(3438.1787727870123/8.0), REAL_CONST(3448.3924457709873/8.0), REAL_CONST(3458.6136872466445/8.0), REAL_CONST(3468.8424860221107/8.0), REAL_CONST(3479.0788309467976/8.0), REAL_CONST(3489.3227109111554/8.0), REAL_CONST(3499.5741148464344/8.0), REAL_CONST(3509.8330317244445/8.0), REAL_CONST(3520.0994505573185/8.0), REAL_CONST(3530.3733603972751/8.0), REAL_CONST(3540.6547503363886/8.0), REAL_CONST(3550.9436095063534/8.0), REAL_CONST(3561.239927078258/8.0), REAL_CONST(3571.5436922623535/8.0), REAL_CONST(3581.8548943078308/8.0), REAL_CONST(3592.1735225025936/8.0), REAL_CONST(3602.4995661730372/8.0), REAL_CONST(3612.8330146838275/8.0), REAL_CONST(3623.1738574376814/8.0), REAL_CONST(3633.5220838751502/8.0), REAL_CONST(3643.8776834744031/8.0), REAL_CONST(3654.2406457510142/8.0), REAL_CONST(3664.6109602577494/8.0), REAL_CONST(3674.9886165843564/8.0), REAL_CONST(3685.3736043573545/8.0), REAL_CONST(3695.7659132398294/8.0), REAL_CONST(3706.1655329312248/8.0), REAL_CONST(3716.5724531671399/8.0), REAL_CONST(3726.9866637191262/8.0), REAL_CONST(3737.4081543944876/8.0), REAL_CONST(3747.8369150360782/8.0), REAL_CONST(3758.2729355221072/8.0), REAL_CONST(3768.7162057659411/8.0), REAL_CONST(3779.1667157159077/8.0), REAL_CONST(3789.6244553551055/8.0), REAL_CONST(3800.0894147012082/8.0), REAL_CONST(3810.5615838062768/8.0), REAL_CONST(3821.0409527565694/8.0), REAL_CONST(3831.5275116723533/8.0), REAL_CONST(3842.0212507077194/8.0), REAL_CONST(3852.522160050396/8.0), REAL_CONST(3863.0302299215673/8.0), REAL_CONST(3873.5454505756893/8.0), REAL_CONST(3884.0678123003108/8.0), REAL_CONST(3894.5973054158922/8.0), REAL_CONST(3905.1339202756285/8.0), REAL_CONST(3915.6776472652732/8.0), REAL_CONST(3926.2284768029604/8.0), REAL_CONST(3936.7863993390338/8.0), REAL_CONST(3947.3514053558706/8.0), REAL_CONST(3957.9234853677135/8.0), REAL_CONST(3968.5026299204969/8.0), REAL_CONST(3979.0888295916798/8.0), REAL_CONST(3989.6820749900776/8.0), REAL_CONST(4000.2823567556948/8.0), REAL_CONST(4010.8896655595613/8.0), REAL_CONST(4021.5039921035655/8.0), REAL_CONST(4032.1253271202945/8.0), REAL_CONST(4042.7536613728694/8.0), REAL_CONST(4053.3889856547858/8.0), REAL_CONST(4064.0312907897551/8.0), REAL_CONST(4074.6805676315448/8.0), REAL_CONST(4085.3368070638221/8.0), REAL_CONST(4095.9999999999982/8.0), REAL_CONST(4106.6701373830711/8.0), REAL_CONST(4117.347210185475/8.0), REAL_CONST(4128.0312094089259/8.0), REAL_CONST(4138.722126084268/8.0), REAL_CONST(4149.4199512713267/8.0), REAL_CONST(4160.1246760587583/8.0), REAL_CONST(4170.8362915638982/8.0), REAL_CONST(4181.5547889326181/8.0), REAL_CONST(4192.2801593391769/8.0), REAL_CONST(4203.0123939860741/8.0), REAL_CONST(4213.7514841039101/8.0), REAL_CONST(4224.4974209512384/8.0), REAL_CONST(4235.2501958144258/8.0), REAL_CONST(4246.0098000075095/8.0), REAL_CONST(4256.7762248720574/8.0), REAL_CONST(4267.549461777031/8.0), REAL_CONST(4278.3295021186423/8.0), REAL_CONST(4289.1163373202198/8.0), REAL_CONST(4299.9099588320714/8.0), REAL_CONST(4310.7103581313495/8.0), REAL_CONST(4321.5175267219138/8.0), REAL_CONST(4332.3314561342004/8.0), REAL_CONST(4343.152137925088/8.0), REAL_CONST(4353.9795636777671/8.0), REAL_CONST(4364.8137250016052/8.0), REAL_CONST(4375.6546135320223/8.0), REAL_CONST(4386.5022209303588/8.0), REAL_CONST(4397.3565388837469/8.0), REAL_CONST(4408.2175591049827/8.0), REAL_CONST(4419.0852733324018/8.0), REAL_CONST(4429.9596733297531/8.0), REAL_CONST(4440.8407508860728/8.0), REAL_CONST(4451.7284978155603/8.0), REAL_CONST(4462.6229059574571/8.0), REAL_CONST(4473.5239671759227/8.0), REAL_CONST(4484.4316733599126/8.0), REAL_CONST(4495.3460164230582/8.0), REAL_CONST(4506.2669883035496/8.0), REAL_CONST(4517.1945809640119/8.0), REAL_CONST(4528.1287863913894/8.0), REAL_CONST(4539.069596596828/8.0), REAL_CONST(4550.0170036155587/8.0), REAL_CONST(4560.9709995067806/8.0), REAL_CONST(4571.931576353546/8.0), REAL_CONST(4582.898726262647/8.0), REAL_CONST(4593.8724413645004/8.0), REAL_CONST(4604.8527138130348/8.0), REAL_CONST(4615.8395357855816/8.0), REAL_CONST(4626.8328994827571/8.0), REAL_CONST(4637.8327971283588/8.0), REAL_CONST(4648.8392209692511/8.0), REAL_CONST(4659.8521632752563/8.0), REAL_CONST(4670.8716163390473/8.0), REAL_CONST(4681.8975724760394/8.0), REAL_CONST(4692.9300240242837/8.0), REAL_CONST(4703.9689633443595/8.0), REAL_CONST(4715.0143828192668/8.0), REAL_CONST(4726.0662748543255/8.0), REAL_CONST(4737.1246318770682/8.0), REAL_CONST(4748.1894463371373/8.0), REAL_CONST(4759.2607107061804/8.0), REAL_CONST(4770.3384174777493/8.0), REAL_CONST(4781.4225591671993/8.0), REAL_CONST(4792.5131283115852/8.0), REAL_CONST(4803.6101174695614/8.0), REAL_CONST(4814.7135192212854/8.0), REAL_CONST(4825.8233261683154/8.0), REAL_CONST(4836.9395309335096/8.0), REAL_CONST(4848.0621261609349/8.0), REAL_CONST(4859.1911045157631/8.0), REAL_CONST(4870.3264586841779/8.0), REAL_CONST(4881.4681813732768/8.0), REAL_CONST(4892.6162653109768/8.0), REAL_CONST(4903.7707032459193/8.0), REAL_CONST(4914.931487947375/8.0), REAL_CONST(4926.0986122051509/8.0), REAL_CONST(4937.2720688294967/8.0), REAL_CONST(4948.4518506510112/8.0), REAL_CONST(4959.637950520555/8.0), REAL_CONST(4970.8303613091521/8.0), REAL_CONST(4982.0290759079044/8.0), REAL_CONST(4993.2340872278974/8.0), REAL_CONST(5004.4453882001153/8.0), REAL_CONST(5015.6629717753467/8.0), REAL_CONST(5026.8868309241007/8.0), REAL_CONST(5038.1169586365131/8.0), REAL_CONST(5049.353347922266/8.0), REAL_CONST(5060.5959918104927/8.0), REAL_CONST(5071.8448833496996/8.0), REAL_CONST(5083.1000156076734/8.0), REAL_CONST(5094.3613816713996/8.0), REAL_CONST(5105.6289746469747/8.0), REAL_CONST(5116.9027876595246/8.0), REAL_CONST(5128.18281385312/8.0), REAL_CONST(5139.4690463906918/8.0), REAL_CONST(5150.7614784539473/8.0), REAL_CONST(5162.0601032432933/8.0), REAL_CONST(5173.3649139777472/8.0), REAL_CONST(5184.6759038948594/8.0), REAL_CONST(5195.9930662506322/8.0), REAL_CONST(5207.3163943194386/8.0), REAL_CONST(5218.6458813939435/8.0), REAL_CONST(5229.9815207850224/8.0), REAL_CONST(5241.3233058216847/8.0), REAL_CONST(5252.6712298509919/8.0), REAL_CONST(5264.025286237983/8.0), REAL_CONST(5275.3854683655954/8.0), REAL_CONST(5286.7517696345885/8.0), REAL_CONST(5298.1241834634639/8.0), REAL_CONST(5309.5027032883945/8.0), REAL_CONST(5320.887322563146/8.0), REAL_CONST(5332.2780347589978/8.0), REAL_CONST(5343.6748333646756/8.0), REAL_CONST(5355.0777118862716/8.0), REAL_CONST(5366.4866638471722/8.0), REAL_CONST(5377.901682787985/8.0), REAL_CONST(5389.3227622664635/8.0), REAL_CONST(5400.749895857437/8.0), REAL_CONST(5412.1830771527357/8.0), REAL_CONST(5423.622299761123/8.0), REAL_CONST(5435.067557308219/8.0), REAL_CONST(5446.5188434364318/8.0), REAL_CONST(5457.9761518048872/8.0), REAL_CONST(5469.4394760893592/8.0), REAL_CONST(5480.9088099821975/8.0), REAL_CONST(5492.3841471922606/8.0), REAL_CONST(5503.8654814448455/8.0), REAL_CONST(5515.3528064816201/8.0), REAL_CONST(5526.846116060552/8.0), REAL_CONST(5538.3454039558474/8.0), REAL_CONST(5549.8506639578736/8.0), REAL_CONST(5561.3618898731029/8.0), REAL_CONST(5572.8790755240361/8.0), REAL_CONST(5584.4022147491451/8.0), REAL_CONST(5595.9313014027975/8.0), REAL_CONST(5607.4663293552012/8.0), REAL_CONST(5619.0072924923297/8.0), REAL_CONST(5630.5541847158656/8.0), REAL_CONST(5642.1069999431284/8.0), REAL_CONST(5653.665732107017/8.0), REAL_CONST(5665.230375155943/8.0), REAL_CONST(5676.8009230537655/8.0), REAL_CONST(5688.3773697797333/8.0), REAL_CONST(5699.9597093284156/8.0), REAL_CONST(5711.5479357096474/8.0), REAL_CONST(5723.1420429484588/8.0), REAL_CONST(5734.7420250850209/8.0), REAL_CONST(5746.347876174581/8.0), REAL_CONST(5757.9595902874016/8.0), REAL_CONST(5769.5771615087006/8.0), REAL_CONST(5781.2005839385911/8.0), REAL_CONST(5792.8298516920213/8.0), REAL_CONST(5804.4649588987149/8.0), REAL_CONST(5816.1058997031105/8.0), REAL_CONST(5827.7526682643065/8.0), REAL_CONST(5839.4052587559972/8.0), REAL_CONST(5851.0636653664196/8.0), REAL_CONST(5862.7278822982908/8.0), REAL_CONST(5874.3979037687541/8.0), REAL_CONST(5886.0737240093204/8.0), REAL_CONST(5897.7553372658094/8.0), REAL_CONST(5909.4427377982956/8.0), REAL_CONST(5921.1359198810505/8.0), REAL_CONST(5932.8348778024874/8.0), REAL_CONST(5944.5396058651031/8.0), REAL_CONST(5956.2500983854261/8.0), REAL_CONST(5967.9663496939575/8.0), REAL_CONST(5979.6883541351208/8.0), REAL_CONST(5991.4161060672022/8.0), REAL_CONST(6003.1495998623004/8.0), REAL_CONST(6014.8888299062692/8.0), REAL_CONST(6026.6337905986684/8.0), REAL_CONST(6038.3844763527022/8.0), REAL_CONST(6050.1408815951781/8.0), REAL_CONST(6061.9030007664414/8.0), REAL_CONST(6073.6708283203316/8.0), REAL_CONST(6085.4443587241267/8.0), REAL_CONST(6097.2235864584891/8.0), REAL_CONST(6109.0085060174197/8.0), REAL_CONST(6120.7991119081998/8.0), REAL_CONST(6132.595398651345/8.0), REAL_CONST(6144.3973607805519/8.0), REAL_CONST(6156.2049928426459/8.0), REAL_CONST(6168.0182893975361/8.0), REAL_CONST(6179.8372450181578/8.0), REAL_CONST(6191.6618542904307/8.0), REAL_CONST(6203.4921118132024/8.0), REAL_CONST(6215.3280121982016/8.0), REAL_CONST(6227.1695500699925/8.0), REAL_CONST(6239.0167200659189/8.0), REAL_CONST(6250.8695168360628/8.0), REAL_CONST(6262.7279350431891/8.0), REAL_CONST(6274.5919693627056/8.0), REAL_CONST(6286.4616144826068/8.0), REAL_CONST(6298.3368651034316/8.0), REAL_CONST(6310.2177159382172/8.0), REAL_CONST(6322.1041617124456/8.0), REAL_CONST(6333.9961971640032/8.0), REAL_CONST(6345.8938170431311/8.0), REAL_CONST(6357.7970161123785/8.0), REAL_CONST(6369.7057891465583/8.0), REAL_CONST(6381.6201309327007/8.0), REAL_CONST(6393.5400362700075/8.0), REAL_CONST(6405.4654999698032/8.0), REAL_CONST(6417.3965168554978/8.0), REAL_CONST(6429.3330817625329/8.0), REAL_CONST(6441.2751895383453/8.0), REAL_CONST(6453.2228350423138/8.0), REAL_CONST(6465.176013145724/8.0), REAL_CONST(6477.134718731716/8.0), REAL_CONST(6489.0989466952469/8.0), REAL_CONST(6501.0686919430445/8.0), REAL_CONST(6513.0439493935628/8.0), REAL_CONST(6525.0247139769417/8.0), REAL_CONST(6537.010980634961/8.0), REAL_CONST(6549.002744321001/8.0), REAL_CONST(6560.9999999999973/8.0), REAL_CONST(6573.0027426483985/8.0), REAL_CONST(6585.0109672541284/8.0), REAL_CONST(6597.0246688165371/8.0), REAL_CONST(6609.0438423463656/8.0), REAL_CONST(6621.0684828657004/8.0), REAL_CONST(6633.0985854079354/8.0), REAL_CONST(6645.134145017727/8.0), REAL_CONST(6657.1751567509573/8.0), REAL_CONST(6669.2216156746908/8.0), REAL_CONST(6681.2735168671343/8.0), REAL_CONST(6693.3308554176001/8.0), REAL_CONST(6705.3936264264594/8.0), REAL_CONST(6717.461825005108/8.0), REAL_CONST(6729.535446275926/8.0), REAL_CONST(6741.6144853722335/8.0), REAL_CONST(6753.6989374382601/8.0), REAL_CONST(6765.7887976290967/8.0), REAL_CONST(6777.8840611106634/8.0), REAL_CONST(6789.9847230596661/8.0), REAL_CONST(6802.0907786635626/8.0), REAL_CONST(6814.2022231205201/8.0), REAL_CONST(6826.3190516393797/8.0), REAL_CONST(6838.4412594396181/8.0), REAL_CONST(6850.5688417513074/8.0), REAL_CONST(6862.701793815083/8.0), REAL_CONST(6874.840110882099/8.0), REAL_CONST(6886.9837882139991/8.0), REAL_CONST(6899.1328210828724/8.0), REAL_CONST(6911.2872047712199/8.0), REAL_CONST(6923.4469345719199/8.0), REAL_CONST(6935.6120057881863/8.0), REAL_CONST(6947.7824137335365/8.0), REAL_CONST(6959.9581537317536/8.0), REAL_CONST(6972.1392211168532/8.0), REAL_CONST(6984.3256112330409/8.0), REAL_CONST(6996.5173194346862/8.0), REAL_CONST(7008.7143410862773/8.0), REAL_CONST(7020.9166715623942/8.0), REAL_CONST(7033.1243062476678/8.0), REAL_CONST(7045.3372405367481/8.0), REAL_CONST(7057.5554698342685/8.0), REAL_CONST(7069.7789895548103/8.0), REAL_CONST(7082.0077951228714/8.0), REAL_CONST(7094.2418819728273/8.0), REAL_CONST(7106.4812455489018/8.0), REAL_CONST(7118.7258813051285/8.0), REAL_CONST(7130.9757847053224/8.0), REAL_CONST(7143.2309512230404/8.0), REAL_CONST(7155.4913763415516/8.0), REAL_CONST(7167.7570555538041/8.0), REAL_CONST(7180.0279843623894/8.0), REAL_CONST(7192.3041582795131/8.0), REAL_CONST(7204.5855728269571/8.0), REAL_CONST(7216.8722235360519/8.0), REAL_CONST(7229.1641059476406/8.0), REAL_CONST(7241.4612156120484/8.0), REAL_CONST(7253.7635480890503/8.0), REAL_CONST(7266.0710989478375/8.0), REAL_CONST(7278.3838637669869/8.0), REAL_CONST(7290.7018381344296/8.0), REAL_CONST(7303.0250176474174/8.0), REAL_CONST(7315.3533979124932/8.0), REAL_CONST(7327.6869745454596/8.0), REAL_CONST(7340.0257431713462/8.0), REAL_CONST(7352.3696994243801/8.0), REAL_CONST(7364.7188389479543/8.0), REAL_CONST(7377.0731573945968/8.0), REAL_CONST(7389.4326504259407/8.0), REAL_CONST(7401.7973137126937/8.0), REAL_CONST(7414.1671429346061/8.0), REAL_CONST(7426.5421337804428/8.0), REAL_CONST(7438.922281947951/8.0), REAL_CONST(7451.3075831438346/8.0), REAL_CONST(7463.6980330837177/8.0), REAL_CONST(7476.0936274921214/8.0), REAL_CONST(7488.4943621024304/8.0), REAL_CONST(7500.9002326568652/8.0), REAL_CONST(7513.3112349064522/8.0), REAL_CONST(7525.7273646109943/8.0), REAL_CONST(7538.1486175390446/8.0), REAL_CONST(7550.5749894678729/8.0), REAL_CONST(7563.0064761834419/8.0), REAL_CONST(7575.4430734803736/8.0), REAL_CONST(7587.8847771619248/8.0), REAL_CONST(7600.3315830399597/8.0), REAL_CONST(7612.7834869349153/8.0), REAL_CONST(7625.24048467578/8.0), REAL_CONST(7637.7025721000637/8.0), REAL_CONST(7650.1697450537677/8.0), REAL_CONST(7662.6419993913596/8.0), REAL_CONST(7675.1193309757446/8.0), REAL_CONST(7687.6017356782404/8.0), REAL_CONST(7700.0892093785433/8.0), REAL_CONST(7712.5817479647112/8.0), REAL_CONST(7725.079347333125/8.0), REAL_CONST(7737.5820033884729/8.0), REAL_CONST(7750.0897120437139/8.0), REAL_CONST(7762.6024692200581/8.0), REAL_CONST(7775.1202708469355/8.0), REAL_CONST(7787.6431128619733/8.0), REAL_CONST(7800.1709912109645/8.0), REAL_CONST(7812.7039018478481/8.0), REAL_CONST(7825.2418407346768/8.0), REAL_CONST(7837.7848038415968/8.0), REAL_CONST(7850.3327871468155/8.0), REAL_CONST(7862.8857866365806/8.0), REAL_CONST(7875.4437983051539/8.0), REAL_CONST(7888.006818154784/8.0), REAL_CONST(7900.5748421956796/8.0), REAL_CONST(7913.1478664459901/8.0), REAL_CONST(7925.725886931772/8.0), REAL_CONST(7938.3088996869719/8.0), REAL_CONST(7950.8969007533951/8.0), REAL_CONST(7963.4898861806851/8.0), REAL_CONST(7976.0878520262959/8.0), REAL_CONST(7988.6907943554688/8.0), REAL_CONST(8001.2987092412086/8.0), REAL_CONST(8013.911592764257/8.0), REAL_CONST(8026.5294410130691/8.0), REAL_CONST(8039.1522500837891/8.0), REAL_CONST(8051.7800160802271/8.0), REAL_CONST(8064.412735113835/8.0), REAL_CONST(8077.0504033036796/8.0), REAL_CONST(8089.6930167764222/8.0), REAL_CONST(8102.3405716662946/8.0), REAL_CONST(8114.9930641150731/8.0), REAL_CONST(8127.6504902720571/8.0), REAL_CONST(8140.3128462940449/8.0), REAL_CONST(8152.9801283453098/8.0), REAL_CONST(8165.6523325975786/8.0), REAL_CONST(8178.3294552300049/8.0), REAL_CONST(8191.0114924291529/8.0), REAL_CONST(8203.6984403889655/8.0), REAL_CONST(8216.3902953107463/8.0), REAL_CONST(8229.0870534031419/8.0), REAL_CONST(8241.7887108821069/8.0), REAL_CONST(8254.4952639708936/8.0), REAL_CONST(8267.2067089000211/8.0), REAL_CONST(8279.9230419072574/8.0), REAL_CONST(8292.6442592375952/8.0), REAL_CONST(8305.3703571432306/8.0), REAL_CONST(8318.101331883543/8.0), REAL_CONST(8330.8371797250657/8.0), REAL_CONST(8343.577896941475/8.0), REAL_CONST(8356.3234798135582/8.0), REAL_CONST(8369.0739246291978/8.0), REAL_CONST(8381.8292276833508/8.0), REAL_CONST(8394.5893852780209/8.0), REAL_CONST(8407.3543937222421/8.0), REAL_CONST(8420.1242493320569/8.0), REAL_CONST(8432.8989484304948/8.0), REAL_CONST(8445.6784873475499/8.0), REAL_CONST(8458.4628624201578/8.0), REAL_CONST(8471.2520699921806/8.0), REAL_CONST(8484.0461064143838/8.0), REAL_CONST(8496.8449680444082/8.0), REAL_CONST(8509.6486512467636/8.0), REAL_CONST(8522.4571523927953/8.0), REAL_CONST(8535.270467860666/8.0), REAL_CONST(8548.0885940353437/8.0), REAL_CONST(8560.9115273085663/8.0), REAL_CONST(8573.7392640788403/8.0), REAL_CONST(8586.5718007514006/8.0), REAL_CONST(8599.4091337382069/8.0), REAL_CONST(8612.2512594579148/8.0), REAL_CONST(8625.0981743358552/8.0), REAL_CONST(8637.9498748040205/8.0), REAL_CONST(8650.8063573010386/8.0), REAL_CONST(8663.6676182721567/8.0), REAL_CONST(8676.533654169225/8.0), REAL_CONST(8689.4044614506638/8.0), REAL_CONST(8702.2800365814601/8.0), REAL_CONST(8715.1603760331418/8.0), REAL_CONST(8728.0454762837508/8.0), REAL_CONST(8740.9353338178389/8.0), REAL_CONST(8753.8299451264356/8.0), REAL_CONST(8766.7293067070332/8.0), REAL_CONST(8779.6334150635721/8.0), REAL_CONST(8792.5422667064158/8.0), REAL_CONST(8805.4558581523324/8.0), REAL_CONST(8818.3741859244819/8.0), REAL_CONST(8831.2972465523908/8.0), REAL_CONST(8844.2250365719356/8.0), REAL_CONST(8857.1575525253265/8.0), REAL_CONST(8870.0947909610859/8.0), REAL_CONST(8883.0367484340295/8.0), REAL_CONST(8895.9834215052524/8.0), REAL_CONST(8908.934806742107/8.0), REAL_CONST(8921.8909007181846/8.0), REAL_CONST(8934.8517000132997/8.0), REAL_CONST(8947.817201213471/8.0), REAL_CONST(8960.7874009109/8.0), REAL_CONST(8973.7622957039603/8.0), REAL_CONST(8986.7418821971733/8.0), REAL_CONST(8999.7261570011924/8.0), REAL_CONST(9012.7151167327884/8.0), REAL_CONST(9025.7087580148236/8.0), REAL_CONST(9038.7070774762469/8.0), REAL_CONST(9051.7100717520643/8.0), REAL_CONST(9064.7177374833282/8.0), REAL_CONST(9077.7300713171153/8.0), REAL_CONST(9090.7470699065179/8.0), REAL_CONST(9103.7687299106146/8.0), REAL_CONST(9116.7950479944648/8.0), REAL_CONST(9129.8260208290812/8.0), REAL_CONST(9142.8616450914233/8.0), REAL_CONST(9155.9019174643727/8.0), REAL_CONST(9168.9468346367157/8.0), REAL_CONST(9181.9963933031358/8.0), REAL_CONST(9195.0505901641845/8.0), REAL_CONST(9208.1094219262741/8.0), REAL_CONST(9221.1728853016557/8.0), REAL_CONST(9234.240977008405/8.0), REAL_CONST(9247.3136937704076/8.0), REAL_CONST(9260.3910323173386/8.0), REAL_CONST(9273.472989384647/8.0), REAL_CONST(9286.5595617135423/8.0), REAL_CONST(9299.6507460509747/8.0), REAL_CONST(9312.7465391496207/8.0), REAL_CONST(9325.8469377678684/8.0), REAL_CONST(9338.9519386698012/8.0), REAL_CONST(9352.0615386251757/8.0), REAL_CONST(9365.1757344094131/8.0), REAL_CONST(9378.2945228035842/8.0), REAL_CONST(9391.4179005943843/8.0), REAL_CONST(9404.5458645741273/8.0), REAL_CONST(9417.6784115407263/8.0), REAL_CONST(9430.8155382976747/8.0), REAL_CONST(9443.9572416540359/8.0), REAL_CONST(9457.1035184244265/8.0), REAL_CONST(9470.2543654290002/8.0), REAL_CONST(9483.4097794934296/8.0), REAL_CONST(9496.5697574488931/8.0), REAL_CONST(9509.7342961320664/8.0), REAL_CONST(9522.9033923850911/8.0), REAL_CONST(9536.0770430555804/8.0), REAL_CONST(9549.2552449965824/8.0), REAL_CONST(9562.4379950665825/8.0), REAL_CONST(9575.6252901294793/8.0), REAL_CONST(9588.8171270545736/8.0), REAL_CONST(9602.0135027165488/8.0), REAL_CONST(9615.2144139954635/8.0), REAL_CONST(9628.4198577767274/8.0), REAL_CONST(9641.629830951093/8.0), REAL_CONST(9654.844330414644/8.0), REAL_CONST(9668.0633530687719/8.0), REAL_CONST(9681.286895820167/8.0), REAL_CONST(9694.5149555808002/8.0), REAL_CONST(9707.7475292679192/8.0), REAL_CONST(9720.9846138040157/8.0), REAL_CONST(9734.2262061168276/8.0), REAL_CONST(9747.4723031393187/8.0), REAL_CONST(9760.7229018096641/8.0), REAL_CONST(9773.9779990712323/8.0), REAL_CONST(9787.2375918725811/8.0), REAL_CONST(9800.5016771674327/8.0), REAL_CONST(9813.7702519146696/8.0), REAL_CONST(9827.0433130783094/8.0), REAL_CONST(9840.3208576275028/8.0), REAL_CONST(9853.602882536512/8.0), REAL_CONST(9866.8893847846994/8.0), REAL_CONST(9880.1803613565116/8.0), REAL_CONST(9893.4758092414686/8.0), REAL_CONST(9906.7757254341523/8.0), REAL_CONST(9920.0801069341851/8.0), REAL_CONST(9933.3889507462245/8.0), REAL_CONST(9946.7022538799429/8.0), REAL_CONST(9960.0200133500221/8.0), REAL_CONST(9973.3422261761298/8.0), REAL_CONST(9986.6688893829159/8.0), REAL_CONST(9999.9999999999945/8.0), REAL_CONST(10013.335555061929/8.0), REAL_CONST(10026.675551608221/8.0), REAL_CONST(10040.019986683301/8.0), REAL_CONST(10053.368857336509/8.0), REAL_CONST(10066.722160622081/8.0), REAL_CONST(10080.079893599144/8.0), REAL_CONST(10093.442053331697/8.0), REAL_CONST(10106.808636888598/8.0), REAL_CONST(10120.179641343551/8.0), REAL_CONST(10133.555063775095/8.0), REAL_CONST(10146.934901266595/8.0), REAL_CONST(10160.31915090622/8.0), REAL_CONST(10173.707809786936/8.0), REAL_CONST(10187.100875006496/8.0), REAL_CONST(10200.498343667417/8.0), REAL_CONST(10213.900212876984/8.0), REAL_CONST(10227.306479747222/8.0), REAL_CONST(10240.717141394889/8.0), REAL_CONST(10254.132194941467/8.0), REAL_CONST(10267.551637513146/8.0), REAL_CONST(10280.975466240814/8.0), REAL_CONST(10294.40367826004/8.0), REAL_CONST(10307.836270711066/8.0), REAL_CONST(10321.273240738796/8.0), REAL_CONST(10334.71458549278/8.0) #ifdef BIG_IQ_TABLE ,REAL_CONST(10348.160302127204/8.0), REAL_CONST(10361.610387800878/8.0), REAL_CONST(10375.064839677221/8.0), REAL_CONST(10388.523654924258/8.0), REAL_CONST(10401.986830714593/8.0), REAL_CONST(10415.454364225412/8.0), REAL_CONST(10428.926252638465/8.0), REAL_CONST(10442.402493140049/8.0), REAL_CONST(10455.883082921007/8.0), REAL_CONST(10469.368019176709/8.0), REAL_CONST(10482.85729910704/8.0), REAL_CONST(10496.350919916393/8.0), REAL_CONST(10509.848878813653/8.0), REAL_CONST(10523.351173012188/8.0), REAL_CONST(10536.857799729838/8.0), REAL_CONST(10550.3687561889/8.0), REAL_CONST(10563.884039616123/8.0), REAL_CONST(10577.403647242685/8.0), REAL_CONST(10590.927576304197/8.0), REAL_CONST(10604.455824040679/8.0), REAL_CONST(10617.988387696556/8.0), REAL_CONST(10631.525264520642/8.0), REAL_CONST(10645.066451766135/8.0), REAL_CONST(10658.611946690598/8.0), REAL_CONST(10672.161746555956/8.0), REAL_CONST(10685.715848628475/8.0), REAL_CONST(10699.274250178762/8.0), REAL_CONST(10712.836948481747/8.0), REAL_CONST(10726.403940816675/8.0), REAL_CONST(10739.975224467091/8.0), REAL_CONST(10753.550796720834/8.0), REAL_CONST(10767.130654870027/8.0), REAL_CONST(10780.714796211059/8.0), REAL_CONST(10794.303218044579/8.0), REAL_CONST(10807.895917675487/8.0), REAL_CONST(10821.492892412922/8.0), REAL_CONST(10835.094139570248/8.0), REAL_CONST(10848.699656465047/8.0), REAL_CONST(10862.309440419107/8.0), REAL_CONST(10875.923488758415/8.0), REAL_CONST(10889.541798813138/8.0), REAL_CONST(10903.16436791762/8.0), REAL_CONST(10916.791193410372/8.0), REAL_CONST(10930.422272634056/8.0), REAL_CONST(10944.05760293548/8.0), REAL_CONST(10957.697181665582/8.0), REAL_CONST(10971.341006179427/8.0), REAL_CONST(10984.98907383619/8.0), REAL_CONST(10998.641381999149/8.0), REAL_CONST(11012.297928035676/8.0), REAL_CONST(11025.958709317223/8.0), REAL_CONST(11039.623723219316/8.0), REAL_CONST(11053.292967121541/8.0), REAL_CONST(11066.966438407539/8.0), REAL_CONST(11080.64413446499/8.0), REAL_CONST(11094.326052685608/8.0), REAL_CONST(11108.012190465128/8.0), REAL_CONST(11121.702545203296/8.0), REAL_CONST(11135.397114303863/8.0), REAL_CONST(11149.095895174571/8.0), REAL_CONST(11162.798885227143/8.0), REAL_CONST(11176.506081877278/8.0), REAL_CONST(11190.217482544635/8.0), REAL_CONST(11203.933084652828/8.0), REAL_CONST(11217.652885629415/8.0), REAL_CONST(11231.376882905886/8.0), REAL_CONST(11245.105073917659/8.0), REAL_CONST(11258.837456104062/8.0), REAL_CONST(11272.574026908333/8.0), REAL_CONST(11286.314783777601/8.0), REAL_CONST(11300.059724162888/8.0), REAL_CONST(11313.808845519083/8.0), REAL_CONST(11327.562145304952/8.0), REAL_CONST(11341.319620983111/8.0), REAL_CONST(11355.081270020033/8.0), REAL_CONST(11368.847089886023/8.0), REAL_CONST(11382.617078055218/8.0), REAL_CONST(11396.391232005579/8.0), REAL_CONST(11410.169549218874/8.0), REAL_CONST(11423.952027180676/8.0), REAL_CONST(11437.738663380349/8.0), REAL_CONST(11451.529455311042/8.0), REAL_CONST(11465.324400469679/8.0), REAL_CONST(11479.123496356951/8.0), REAL_CONST(11492.926740477304/8.0), REAL_CONST(11506.734130338931/8.0), REAL_CONST(11520.545663453764/8.0), REAL_CONST(11534.361337337466/8.0), REAL_CONST(11548.181149509423/8.0), REAL_CONST(11562.005097492724/8.0), REAL_CONST(11575.83317881417/8.0), REAL_CONST(11589.665391004253/8.0), REAL_CONST(11603.501731597149/8.0), REAL_CONST(11617.342198130715/8.0), REAL_CONST(11631.186788146468/8.0), REAL_CONST(11645.035499189589/8.0), REAL_CONST(11658.888328808911/8.0), REAL_CONST(11672.745274556904/8.0), REAL_CONST(11686.606333989675/8.0), REAL_CONST(11700.471504666955/8.0), REAL_CONST(11714.340784152086/8.0), REAL_CONST(11728.214170012021/8.0), REAL_CONST(11742.091659817312/8.0), REAL_CONST(11755.973251142101/8.0), REAL_CONST(11769.858941564111/8.0), REAL_CONST(11783.748728664636/8.0), REAL_CONST(11797.642610028539/8.0), REAL_CONST(11811.540583244237/8.0), REAL_CONST(11825.442645903697/8.0), REAL_CONST(11839.34879560242/8.0), REAL_CONST(11853.259029939445/8.0), REAL_CONST(11867.173346517333/8.0), REAL_CONST(11881.091742942155/8.0), REAL_CONST(11895.014216823492/8.0), REAL_CONST(11908.940765774427/8.0), REAL_CONST(11922.871387411526/8.0), REAL_CONST(11936.806079354839/8.0), REAL_CONST(11950.744839227897/8.0), REAL_CONST(11964.687664657684/8.0), REAL_CONST(11978.634553274653/8.0), REAL_CONST(11992.585502712702/8.0), REAL_CONST(12006.540510609168/8.0), REAL_CONST(12020.499574604828/8.0), REAL_CONST(12034.462692343877/8.0), REAL_CONST(12048.429861473938/8.0), REAL_CONST(12062.401079646032/8.0), REAL_CONST(12076.376344514589/8.0), REAL_CONST(12090.355653737433/8.0), REAL_CONST(12104.339004975769/8.0), REAL_CONST(12118.326395894188/8.0), REAL_CONST(12132.317824160644/8.0), REAL_CONST(12146.313287446457/8.0), REAL_CONST(12160.312783426305/8.0), REAL_CONST(12174.316309778205/8.0), REAL_CONST(12188.323864183525/8.0), REAL_CONST(12202.335444326955/8.0), REAL_CONST(12216.351047896511/8.0), REAL_CONST(12230.370672583531/8.0), REAL_CONST(12244.394316082657/8.0), REAL_CONST(12258.421976091831/8.0), REAL_CONST(12272.453650312296/8.0), REAL_CONST(12286.489336448574/8.0), REAL_CONST(12300.529032208471/8.0), REAL_CONST(12314.572735303058/8.0), REAL_CONST(12328.620443446678/8.0), REAL_CONST(12342.672154356922/8.0), REAL_CONST(12356.727865754638/8.0), REAL_CONST(12370.787575363909/8.0), REAL_CONST(12384.851280912055/8.0), REAL_CONST(12398.918980129623/8.0), REAL_CONST(12412.990670750381/8.0), REAL_CONST(12427.066350511306/8.0), REAL_CONST(12441.146017152583/8.0), REAL_CONST(12455.229668417589/8.0), REAL_CONST(12469.317302052901/8.0), REAL_CONST(12483.40891580827/8.0), REAL_CONST(12497.50450743663/8.0), REAL_CONST(12511.604074694078/8.0), REAL_CONST(12525.707615339878/8.0), REAL_CONST(12539.815127136444/8.0), REAL_CONST(12553.926607849342/8.0), REAL_CONST(12568.042055247275/8.0), REAL_CONST(12582.161467102082/8.0), REAL_CONST(12596.284841188726/8.0), REAL_CONST(12610.41217528529/8.0), REAL_CONST(12624.543467172971/8.0), REAL_CONST(12638.678714636069/8.0), REAL_CONST(12652.817915461985/8.0), REAL_CONST(12666.961067441209/8.0), REAL_CONST(12681.108168367316/8.0), REAL_CONST(12695.259216036962/8.0), REAL_CONST(12709.414208249869/8.0), REAL_CONST(12723.573142808827/8.0), REAL_CONST(12737.736017519681/8.0), REAL_CONST(12751.902830191326/8.0), REAL_CONST(12766.073578635704/8.0), REAL_CONST(12780.248260667788/8.0), REAL_CONST(12794.426874105588/8.0), REAL_CONST(12808.609416770132/8.0), REAL_CONST(12822.795886485468/8.0), REAL_CONST(12836.986281078653/8.0), REAL_CONST(12851.180598379744/8.0), REAL_CONST(12865.378836221802/8.0), REAL_CONST(12879.580992440871/8.0), REAL_CONST(12893.787064875984/8.0), REAL_CONST(12907.997051369144/8.0), REAL_CONST(12922.210949765335/8.0), REAL_CONST(12936.428757912496/8.0), REAL_CONST(12950.650473661524/8.0), REAL_CONST(12964.876094866273/8.0), REAL_CONST(12979.105619383534/8.0), REAL_CONST(12993.339045073039/8.0), REAL_CONST(13007.576369797454/8.0), REAL_CONST(13021.817591422368/8.0), REAL_CONST(13036.062707816285/8.0), REAL_CONST(13050.311716850629/8.0), REAL_CONST(13064.564616399723/8.0), REAL_CONST(13078.821404340792/8.0), REAL_CONST(13093.082078553954/8.0), REAL_CONST(13107.346636922217/8.0), REAL_CONST(13121.615077331464/8.0), REAL_CONST(13135.887397670458/8.0), REAL_CONST(13150.163595830827/8.0), REAL_CONST(13164.44366970706/8.0), REAL_CONST(13178.727617196502/8.0), REAL_CONST(13193.015436199352/8.0), REAL_CONST(13207.307124618648/8.0), REAL_CONST(13221.602680360265/8.0), REAL_CONST(13235.902101332911/8.0), REAL_CONST(13250.205385448118/8.0), REAL_CONST(13264.512530620239/8.0), REAL_CONST(13278.823534766434/8.0), REAL_CONST(13293.138395806676/8.0), REAL_CONST(13307.457111663734/8.0), REAL_CONST(13321.779680263176/8.0), REAL_CONST(13336.106099533356/8.0), REAL_CONST(13350.436367405409/8.0), REAL_CONST(13364.77048181325/8.0), REAL_CONST(13379.108440693562/8.0), REAL_CONST(13393.450241985796/8.0), REAL_CONST(13407.795883632158/8.0), REAL_CONST(13422.145363577607/8.0), REAL_CONST(13436.498679769853/8.0), REAL_CONST(13450.855830159346/8.0), REAL_CONST(13465.216812699266/8.0), REAL_CONST(13479.581625345529/8.0), REAL_CONST(13493.950266056772/8.0), REAL_CONST(13508.32273279435/8.0), REAL_CONST(13522.699023522329/8.0), REAL_CONST(13537.079136207483/8.0), REAL_CONST(13551.463068819286/8.0), REAL_CONST(13565.850819329906/8.0), REAL_CONST(13580.2423857142/8.0), REAL_CONST(13594.63776594971/8.0), REAL_CONST(13609.036958016657/8.0), REAL_CONST(13623.439959897927/8.0), REAL_CONST(13637.846769579081/8.0), REAL_CONST(13652.257385048335/8.0), REAL_CONST(13666.67180429656/8.0), REAL_CONST(13681.090025317284/8.0), REAL_CONST(13695.512046106669/8.0), REAL_CONST(13709.937864663521/8.0), REAL_CONST(13724.367478989278/8.0), REAL_CONST(13738.800887088004/8.0), REAL_CONST(13753.238086966385/8.0), REAL_CONST(13767.679076633727/8.0), REAL_CONST(13782.123854101939/8.0), REAL_CONST(13796.572417385545/8.0), REAL_CONST(13811.024764501659/8.0), REAL_CONST(13825.480893469998/8.0), REAL_CONST(13839.94080231286/8.0), REAL_CONST(13854.404489055134/8.0), REAL_CONST(13868.871951724283/8.0), REAL_CONST(13883.34318835034/8.0), REAL_CONST(13897.818196965914/8.0), REAL_CONST(13912.296975606168/8.0), REAL_CONST(13926.779522308825/8.0), REAL_CONST(13941.26583511416/8.0), REAL_CONST(13955.755912064991/8.0), REAL_CONST(13970.249751206682/8.0), REAL_CONST(13984.747350587126/8.0), REAL_CONST(13999.248708256751/8.0), REAL_CONST(14013.753822268511/8.0), REAL_CONST(14028.262690677873/8.0), REAL_CONST(14042.775311542828/8.0), REAL_CONST(14057.291682923867/8.0), REAL_CONST(14071.811802883994/8.0), REAL_CONST(14086.335669488704/8.0), REAL_CONST(14100.863280805994/8.0), REAL_CONST(14115.394634906341/8.0), REAL_CONST(14129.92972986271/8.0), REAL_CONST(14144.468563750548/8.0), REAL_CONST(14159.01113464777/8.0), REAL_CONST(14173.55744063476/8.0), REAL_CONST(14188.107479794369/8.0), REAL_CONST(14202.661250211901/8.0), REAL_CONST(14217.218749975118/8.0), REAL_CONST(14231.779977174227/8.0), REAL_CONST(14246.344929901879/8.0), REAL_CONST(14260.913606253163/8.0), REAL_CONST(14275.486004325601/8.0), REAL_CONST(14290.062122219146/8.0), REAL_CONST(14304.641958036171/8.0), REAL_CONST(14319.225509881464/8.0), REAL_CONST(14333.812775862236/8.0), REAL_CONST(14348.403754088098/8.0), REAL_CONST(14362.998442671067/8.0), REAL_CONST(14377.59683972556/8.0), REAL_CONST(14392.198943368388/8.0), REAL_CONST(14406.804751718748/8.0), REAL_CONST(14421.414262898223/8.0), REAL_CONST(14436.027475030774/8.0), REAL_CONST(14450.64438624274/8.0), REAL_CONST(14465.264994662828/8.0), REAL_CONST(14479.889298422106/8.0), REAL_CONST(14494.517295654005/8.0), REAL_CONST(14509.148984494313/8.0), REAL_CONST(14523.784363081166/8.0), REAL_CONST(14538.423429555049/8.0), REAL_CONST(14553.066182058781/8.0), REAL_CONST(14567.712618737527/8.0), REAL_CONST(14582.362737738777/8.0), REAL_CONST(14597.016537212348/8.0), REAL_CONST(14611.674015310382/8.0), REAL_CONST(14626.33517018734/8.0), REAL_CONST(14640.999999999993/8.0), REAL_CONST(14655.668502907418/8.0), REAL_CONST(14670.340677071003/8.0), REAL_CONST(14685.016520654426/8.0), REAL_CONST(14699.696031823671/8.0), REAL_CONST(14714.379208746999/8.0), REAL_CONST(14729.066049594967/8.0), REAL_CONST(14743.756552540408/8.0), REAL_CONST(14758.45071575843/8.0), REAL_CONST(14773.148537426418/8.0), REAL_CONST(14787.850015724018/8.0), REAL_CONST(14802.555148833142/8.0), REAL_CONST(14817.263934937961/8.0), REAL_CONST(14831.976372224897/8.0), REAL_CONST(14846.692458882624/8.0), REAL_CONST(14861.41219310206/8.0), REAL_CONST(14876.135573076363/8.0), REAL_CONST(14890.862597000923/8.0), REAL_CONST(14905.593263073371/8.0), REAL_CONST(14920.327569493558/8.0), REAL_CONST(14935.065514463557/8.0), REAL_CONST(14949.807096187662/8.0), REAL_CONST(14964.552312872382/8.0), REAL_CONST(14979.301162726431/8.0), REAL_CONST(14994.053643960735/8.0), REAL_CONST(15008.809754788414/8.0), REAL_CONST(15023.569493424788/8.0), REAL_CONST(15038.332858087369/8.0), REAL_CONST(15053.099846995858/8.0), REAL_CONST(15067.870458372134/8.0), REAL_CONST(15082.644690440264/8.0), REAL_CONST(15097.422541426484/8.0), REAL_CONST(15112.204009559202/8.0), REAL_CONST(15126.989093068994/8.0), REAL_CONST(15141.777790188597/8.0), REAL_CONST(15156.570099152905/8.0), REAL_CONST(15171.366018198967/8.0), REAL_CONST(15186.165545565986/8.0), REAL_CONST(15200.968679495301/8.0), REAL_CONST(15215.775418230402/8.0), REAL_CONST(15230.585760016909/8.0), REAL_CONST(15245.399703102579/8.0), REAL_CONST(15260.217245737298/8.0), REAL_CONST(15275.038386173073/8.0), REAL_CONST(15289.863122664035/8.0), REAL_CONST(15304.691453466432/8.0), REAL_CONST(15319.523376838621/8.0), REAL_CONST(15334.358891041069/8.0), REAL_CONST(15349.197994336346/8.0), REAL_CONST(15364.040684989128/8.0), REAL_CONST(15378.886961266177/8.0), REAL_CONST(15393.736821436356/8.0), REAL_CONST(15408.590263770609/8.0), REAL_CONST(15423.447286541972/8.0), REAL_CONST(15438.307888025554/8.0), REAL_CONST(15453.172066498542/8.0), REAL_CONST(15468.039820240196/8.0), REAL_CONST(15482.91114753184/8.0), REAL_CONST(15497.786046656869/8.0), REAL_CONST(15512.664515900733/8.0), REAL_CONST(15527.546553550939/8.0), REAL_CONST(15542.432157897045/8.0), REAL_CONST(15557.32132723066/8.0), REAL_CONST(15572.214059845435/8.0), REAL_CONST(15587.110354037064/8.0), REAL_CONST(15602.010208103273/8.0), REAL_CONST(15616.913620343823/8.0), REAL_CONST(15631.820589060506/8.0), REAL_CONST(15646.731112557136/8.0), REAL_CONST(15661.645189139546/8.0), REAL_CONST(15676.562817115593/8.0), REAL_CONST(15691.483994795139/8.0), REAL_CONST(15706.408720490062/8.0), REAL_CONST(15721.336992514242/8.0), REAL_CONST(15736.268809183561/8.0), REAL_CONST(15751.204168815901/8.0), REAL_CONST(15766.143069731135/8.0), REAL_CONST(15781.085510251132/8.0), REAL_CONST(15796.03148869974/8.0), REAL_CONST(15810.981003402798/8.0), REAL_CONST(15825.934052688119/8.0), REAL_CONST(15840.890634885489/8.0), REAL_CONST(15855.850748326673/8.0), REAL_CONST(15870.814391345401/8.0), REAL_CONST(15885.781562277361/8.0), REAL_CONST(15900.752259460214/8.0), REAL_CONST(15915.726481233565/8.0), REAL_CONST(15930.704225938984/8.0), REAL_CONST(15945.685491919978/8.0), REAL_CONST(15960.670277522009/8.0), REAL_CONST(15975.658581092481/8.0), REAL_CONST(15990.65040098073/8.0), REAL_CONST(16005.645735538035/8.0), REAL_CONST(16020.644583117599/8.0), REAL_CONST(16035.646942074556/8.0), REAL_CONST(16050.652810765967/8.0), REAL_CONST(16065.662187550806/8.0), REAL_CONST(16080.675070789974/8.0), REAL_CONST(16095.691458846273/8.0), REAL_CONST(16110.711350084424/8.0), REAL_CONST(16125.734742871053/8.0), REAL_CONST(16140.761635574685/8.0), REAL_CONST(16155.792026565747/8.0), REAL_CONST(16170.825914216561/8.0), REAL_CONST(16185.863296901338/8.0), REAL_CONST(16200.904172996183/8.0), REAL_CONST(16215.948540879079/8.0), REAL_CONST(16230.996398929899/8.0), REAL_CONST(16246.047745530386/8.0), REAL_CONST(16261.102579064163/8.0), REAL_CONST(16276.160897916721/8.0), REAL_CONST(16291.22270047542/8.0), REAL_CONST(16306.287985129484/8.0), REAL_CONST(16321.356750269995/8.0), REAL_CONST(16336.428994289896/8.0), REAL_CONST(16351.504715583982/8.0), REAL_CONST(16366.5839125489/8.0), REAL_CONST(16381.666583583141/8.0), REAL_CONST(16396.752727087041/8.0), REAL_CONST(16411.842341462776/8.0), REAL_CONST(16426.935425114363/8.0), REAL_CONST(16442.031976447644/8.0), REAL_CONST(16457.131993870298/8.0), REAL_CONST(16472.235475791829/8.0), REAL_CONST(16487.342420623561/8.0), REAL_CONST(16502.452826778641/8.0), REAL_CONST(16517.566692672033/8.0), REAL_CONST(16532.684016720516/8.0), REAL_CONST(16547.804797342676/8.0), REAL_CONST(16562.929032958902/8.0), REAL_CONST(16578.056721991394/8.0), REAL_CONST(16593.18786286415/8.0), REAL_CONST(16608.322454002962/8.0), REAL_CONST(16623.460493835417/8.0), REAL_CONST(16638.601980790896/8.0), REAL_CONST(16653.746913300558/8.0), REAL_CONST(16668.895289797354/8.0), REAL_CONST(16684.047108716015/8.0), REAL_CONST(16699.202368493046/8.0), REAL_CONST(16714.361067566726/8.0), REAL_CONST(16729.523204377107/8.0), REAL_CONST(16744.688777366009/8.0), REAL_CONST(16759.857784977012/8.0), REAL_CONST(16775.030225655464/8.0), REAL_CONST(16790.206097848466/8.0), REAL_CONST(16805.385400004874/8.0), REAL_CONST(16820.568130575302/8.0), REAL_CONST(16835.754288012104/8.0), REAL_CONST(16850.943870769381/8.0), REAL_CONST(16866.136877302983/8.0), REAL_CONST(16881.333306070494/8.0), REAL_CONST(16896.53315553123/8.0), REAL_CONST(16911.736424146249/8.0), REAL_CONST(16926.943110378332/8.0), REAL_CONST(16942.153212691992/8.0), REAL_CONST(16957.366729553454/8.0), REAL_CONST(16972.583659430682/8.0), REAL_CONST(16987.804000793338/8.0), REAL_CONST(17003.027752112816/8.0), REAL_CONST(17018.254911862205/8.0), REAL_CONST(17033.485478516312/8.0), REAL_CONST(17048.719450551645/8.0), REAL_CONST(17063.956826446421/8.0), REAL_CONST(17079.197604680547/8.0), REAL_CONST(17094.44178373563/8.0), REAL_CONST(17109.689362094967/8.0), REAL_CONST(17124.940338243552/8.0), REAL_CONST(17140.194710668064/8.0), REAL_CONST(17155.452477856852/8.0), REAL_CONST(17170.713638299967/8.0), REAL_CONST(17185.978190489128/8.0), REAL_CONST(17201.246132917724/8.0), REAL_CONST(17216.517464080825/8.0), REAL_CONST(17231.792182475165/8.0), REAL_CONST(17247.070286599141/8.0), REAL_CONST(17262.351774952826/8.0), REAL_CONST(17277.636646037936/8.0), REAL_CONST(17292.924898357855/8.0), REAL_CONST(17308.216530417623/8.0), REAL_CONST(17323.511540723921/8.0), REAL_CONST(17338.809927785089/8.0), REAL_CONST(17354.111690111105/8.0), REAL_CONST(17369.416826213594/8.0), REAL_CONST(17384.725334605821/8.0), REAL_CONST(17400.037213802683/8.0), REAL_CONST(17415.352462320716/8.0), REAL_CONST(17430.67107867809/8.0), REAL_CONST(17445.993061394587/8.0), REAL_CONST(17461.318408991636/8.0), REAL_CONST(17476.647119992274/8.0), REAL_CONST(17491.979192921168/8.0), REAL_CONST(17507.314626304586/8.0), REAL_CONST(17522.653418670423/8.0), REAL_CONST(17537.995568548187/8.0), REAL_CONST(17553.341074468986/8.0), REAL_CONST(17568.689934965536/8.0), REAL_CONST(17584.042148572156/8.0), REAL_CONST(17599.397713824768/8.0), REAL_CONST(17614.75662926089/8.0), REAL_CONST(17630.118893419625/8.0), REAL_CONST(17645.484504841683/8.0), REAL_CONST(17660.853462069354/8.0), REAL_CONST(17676.225763646511/8.0), REAL_CONST(17691.601408118619/8.0), REAL_CONST(17706.980394032718/8.0), REAL_CONST(17722.362719937424/8.0), REAL_CONST(17737.748384382936/8.0), REAL_CONST(17753.137385921014/8.0), REAL_CONST(17768.529723104999/8.0), REAL_CONST(17783.92539448979/8.0), REAL_CONST(17799.324398631856/8.0), REAL_CONST(17814.726734089225/8.0), REAL_CONST(17830.13239942148/8.0), REAL_CONST(17845.541393189767/8.0), REAL_CONST(17860.95371395678/8.0), REAL_CONST(17876.369360286772/8.0), REAL_CONST(17891.788330745527/8.0), REAL_CONST(17907.210623900395/8.0), REAL_CONST(17922.636238320254/8.0), REAL_CONST(17938.065172575527/8.0), REAL_CONST(17953.497425238176/8.0), REAL_CONST(17968.932994881692/8.0), REAL_CONST(17984.371880081104/8.0), REAL_CONST(17999.814079412972/8.0), REAL_CONST(18015.259591455371/8.0), REAL_CONST(18030.708414787914/8.0), REAL_CONST(18046.160547991731/8.0), REAL_CONST(18061.615989649465/8.0), REAL_CONST(18077.074738345284/8.0), REAL_CONST(18092.536792664861/8.0), REAL_CONST(18108.002151195393/8.0), REAL_CONST(18123.470812525571/8.0), REAL_CONST(18138.942775245599/8.0), REAL_CONST(18154.418037947191/8.0), REAL_CONST(18169.896599223546/8.0), REAL_CONST(18185.37845766938/8.0), REAL_CONST(18200.863611880886/8.0), REAL_CONST(18216.352060455767/8.0), REAL_CONST(18231.843801993204/8.0), REAL_CONST(18247.338835093873/8.0), REAL_CONST(18262.837158359936/8.0), REAL_CONST(18278.338770395032/8.0), REAL_CONST(18293.84366980429/8.0), REAL_CONST(18309.351855194309/8.0), REAL_CONST(18324.863325173166/8.0), REAL_CONST(18340.378078350412/8.0), REAL_CONST(18355.896113337069/8.0), REAL_CONST(18371.417428745623/8.0), REAL_CONST(18386.942023190033/8.0), REAL_CONST(18402.469895285718/8.0), REAL_CONST(18418.00104364955/8.0), REAL_CONST(18433.53546689987/8.0), REAL_CONST(18449.073163656474/8.0), REAL_CONST(18464.614132540602/8.0), REAL_CONST(18480.158372174956/8.0), REAL_CONST(18495.705881183676/8.0), REAL_CONST(18511.256658192357/8.0), REAL_CONST(18526.810701828035/8.0), REAL_CONST(18542.368010719183/8.0), REAL_CONST(18557.928583495715/8.0), REAL_CONST(18573.492418788985/8.0), REAL_CONST(18589.059515231773/8.0), REAL_CONST(18604.629871458303/8.0), REAL_CONST(18620.203486104212/8.0), REAL_CONST(18635.78035780658/8.0), REAL_CONST(18651.360485203899/8.0), REAL_CONST(18666.943866936086/8.0), REAL_CONST(18682.53050164448/8.0), REAL_CONST(18698.120387971841/8.0), REAL_CONST(18713.713524562332/8.0), REAL_CONST(18729.30991006154/8.0), REAL_CONST(18744.909543116457/8.0), REAL_CONST(18760.512422375479/8.0), REAL_CONST(18776.118546488418/8.0), REAL_CONST(18791.727914106479/8.0), REAL_CONST(18807.340523882274/8.0), REAL_CONST(18822.95637446981/8.0), REAL_CONST(18838.575464524489/8.0), REAL_CONST(18854.197792703111/8.0), REAL_CONST(18869.823357663863/8.0), REAL_CONST(18885.452158066328/8.0), REAL_CONST(18901.08419257147/8.0), REAL_CONST(18916.719459841639/8.0), REAL_CONST(18932.357958540564/8.0), REAL_CONST(18947.999687333362/8.0), REAL_CONST(18963.644644886521/8.0), REAL_CONST(18979.292829867907/8.0), REAL_CONST(18994.944240946759/8.0), REAL_CONST(19010.598876793687/8.0), REAL_CONST(19026.256736080668/8.0), REAL_CONST(19041.917817481048/8.0), REAL_CONST(19057.582119669532/8.0), REAL_CONST(19073.2496413222/8.0), REAL_CONST(19088.920381116473/8.0), REAL_CONST(19104.594337731145/8.0), REAL_CONST(19120.271509846356/8.0), REAL_CONST(19135.951896143604/8.0), REAL_CONST(19151.635495305738/8.0), REAL_CONST(19167.322306016948/8.0), REAL_CONST(19183.012326962784/8.0), REAL_CONST(19198.705556830122/8.0), REAL_CONST(19214.401994307198/8.0), REAL_CONST(19230.101638083579/8.0), REAL_CONST(19245.804486850167/8.0), REAL_CONST(19261.510539299208/8.0), REAL_CONST(19277.219794124274/8.0), REAL_CONST(19292.932250020265/8.0), REAL_CONST(19308.647905683421/8.0), REAL_CONST(19324.366759811302/8.0), REAL_CONST(19340.088811102793/8.0), REAL_CONST(19355.8140582581/8.0), REAL_CONST(19371.542499978754/8.0), REAL_CONST(19387.2741349676/8.0), REAL_CONST(19403.008961928797/8.0), REAL_CONST(19418.746979567823/8.0), REAL_CONST(19434.488186591469/8.0), REAL_CONST(19450.232581707827/8.0), REAL_CONST(19465.980163626304/8.0), REAL_CONST(19481.730931057613/8.0), REAL_CONST(19497.484882713761/8.0), REAL_CONST(19513.242017308068/8.0), REAL_CONST(19529.002333555141/8.0), REAL_CONST(19544.765830170898/8.0), REAL_CONST(19560.532505872539/8.0), REAL_CONST(19576.302359378566/8.0), REAL_CONST(19592.075389408761/8.0), REAL_CONST(19607.851594684209/8.0), REAL_CONST(19623.630973927269/8.0), REAL_CONST(19639.41352586159/8.0), REAL_CONST(19655.199249212103/8.0), REAL_CONST(19670.988142705017/8.0), REAL_CONST(19686.780205067826/8.0), REAL_CONST(19702.575435029288/8.0), REAL_CONST(19718.373831319448/8.0), REAL_CONST(19734.175392669615/8.0), REAL_CONST(19749.980117812371/8.0), REAL_CONST(19765.788005481569/8.0), REAL_CONST(19781.599054412323/8.0), REAL_CONST(19797.413263341008/8.0), REAL_CONST(19813.230631005274/8.0), REAL_CONST(19829.051156144014/8.0), REAL_CONST(19844.874837497395/8.0), REAL_CONST(19860.701673806827/8.0), REAL_CONST(19876.531663814985/8.0), REAL_CONST(19892.364806265789/8.0), REAL_CONST(19908.201099904403/8.0), REAL_CONST(19924.040543477258/8.0), REAL_CONST(19939.883135732012/8.0), REAL_CONST(19955.728875417579/8.0), REAL_CONST(19971.577761284105/8.0), REAL_CONST(19987.429792082985/8.0), REAL_CONST(20003.284966566847/8.0), REAL_CONST(20019.14328348956/8.0), REAL_CONST(20035.004741606219/8.0), REAL_CONST(20050.869339673161/8.0), REAL_CONST(20066.737076447946/8.0), REAL_CONST(20082.607950689362/8.0), REAL_CONST(20098.481961157428/8.0), REAL_CONST(20114.359106613385/8.0), REAL_CONST(20130.239385819699/8.0), REAL_CONST(20146.122797540058/8.0), REAL_CONST(20162.009340539353/8.0), REAL_CONST(20177.899013583716/8.0), REAL_CONST(20193.791815440476/8.0), REAL_CONST(20209.687744878182/8.0), REAL_CONST(20225.586800666591/8.0), REAL_CONST(20241.488981576669/8.0), REAL_CONST(20257.394286380597/8.0), REAL_CONST(20273.302713851754/8.0), REAL_CONST(20289.214262764715/8.0), REAL_CONST(20305.128931895277/8.0), REAL_CONST(20321.046720020415/8.0), REAL_CONST(20336.967625918318/8.0), REAL_CONST(20352.891648368361/8.0), REAL_CONST(20368.818786151114/8.0), REAL_CONST(20384.749038048347/8.0), REAL_CONST(20400.682402843009/8.0), REAL_CONST(20416.618879319249/8.0), REAL_CONST(20432.558466262391/8.0), REAL_CONST(20448.501162458953/8.0), REAL_CONST(20464.446966696629/8.0), REAL_CONST(20480.395877764302/8.0), REAL_CONST(20496.347894452025/8.0), REAL_CONST(20512.303015551031/8.0), REAL_CONST(20528.261239853735/8.0), REAL_CONST(20544.22256615372/8.0), REAL_CONST(20560.186993245738/8.0), REAL_CONST(20576.15451992572/8.0), REAL_CONST(20592.125144990758/8.0), REAL_CONST(20608.098867239107/8.0), REAL_CONST(20624.075685470198/8.0), REAL_CONST(20640.055598484618/8.0), REAL_CONST(20656.038605084115/8.0), REAL_CONST(20672.024704071595/8.0), REAL_CONST(20688.013894251126/8.0), REAL_CONST(20704.006174427926/8.0), REAL_CONST(20720.001543408373/8.0), REAL_CONST(20735.999999999989/8.0), REAL_CONST(20752.001543011454/8.0), REAL_CONST(20768.006171252597/8.0), REAL_CONST(20784.013883534382/8.0), REAL_CONST(20800.024678668931/8.0), REAL_CONST(20816.038555469506/8.0), REAL_CONST(20832.055512750507/8.0), REAL_CONST(20848.075549327474/8.0), REAL_CONST(20864.098664017085/8.0), REAL_CONST(20880.124855637161/8.0), REAL_CONST(20896.154123006647/8.0), REAL_CONST(20912.186464945626/8.0), REAL_CONST(20928.221880275312/8.0), REAL_CONST(20944.260367818049/8.0), REAL_CONST(20960.301926397311/8.0), REAL_CONST(20976.346554837684/8.0), REAL_CONST(20992.394251964895/8.0), REAL_CONST(21008.445016605787/8.0), REAL_CONST(21024.498847588318/8.0), REAL_CONST(21040.555743741574/8.0), REAL_CONST(21056.615703895754/8.0), REAL_CONST(21072.678726882168/8.0), REAL_CONST(21088.744811533252/8.0), REAL_CONST(21104.813956682538/8.0), REAL_CONST(21120.886161164683/8.0), REAL_CONST(21136.961423815443/8.0), REAL_CONST(21153.039743471683/8.0), REAL_CONST(21169.121118971379/8.0), REAL_CONST(21185.205549153605/8.0), REAL_CONST(21201.293032858535/8.0), REAL_CONST(21217.383568927453/8.0), REAL_CONST(21233.477156202731/8.0), REAL_CONST(21249.573793527841/8.0), REAL_CONST(21265.673479747358/8.0), REAL_CONST(21281.776213706937/8.0), REAL_CONST(21297.881994253334/8.0), REAL_CONST(21313.990820234398/8.0), REAL_CONST(21330.102690499054/8.0), REAL_CONST(21346.21760389733/8.0), REAL_CONST(21362.335559280327/8.0), REAL_CONST(21378.456555500241/8.0), REAL_CONST(21394.580591410333/8.0), REAL_CONST(21410.707665864964/8.0), REAL_CONST(21426.83777771956/8.0), REAL_CONST(21442.970925830628/8.0), REAL_CONST(21459.107109055756/8.0), REAL_CONST(21475.246326253604/8.0), REAL_CONST(21491.388576283895/8.0), REAL_CONST(21507.533858007431/8.0), REAL_CONST(21523.682170286087/8.0), REAL_CONST(21539.833511982797/8.0), REAL_CONST(21555.987881961566/8.0), REAL_CONST(21572.145279087465/8.0), REAL_CONST(21588.305702226615/8.0), REAL_CONST(21604.469150246216/8.0), REAL_CONST(21620.635622014521/8.0), REAL_CONST(21636.805116400832/8.0), REAL_CONST(21652.977632275521/8.0), REAL_CONST(21669.153168510009/8.0), REAL_CONST(21685.331723976764/8.0), REAL_CONST(21701.513297549318/8.0), REAL_CONST(21717.697888102244/8.0), REAL_CONST(21733.885494511167/8.0), REAL_CONST(21750.076115652759/8.0), REAL_CONST(21766.269750404736/8.0), REAL_CONST(21782.466397645861/8.0), REAL_CONST(21798.666056255934/8.0), REAL_CONST(21814.868725115801/8.0), REAL_CONST(21831.074403107345/8.0), REAL_CONST(21847.283089113484/8.0), REAL_CONST(21863.494782018177/8.0), REAL_CONST(21879.709480706417/8.0), REAL_CONST(21895.927184064229/8.0), REAL_CONST(21912.147890978667/8.0), REAL_CONST(21928.371600337818/8.0), REAL_CONST(21944.598311030797/8.0), REAL_CONST(21960.828021947746/8.0), REAL_CONST(21977.060731979829/8.0), REAL_CONST(21993.296440019243/8.0), REAL_CONST(22009.535144959198/8.0), REAL_CONST(22025.77684569393/8.0), REAL_CONST(22042.021541118691/8.0), REAL_CONST(22058.269230129757/8.0), REAL_CONST(22074.519911624411/8.0), REAL_CONST(22090.773584500959/8.0), REAL_CONST(22107.030247658717/8.0), REAL_CONST(22123.289899998013/8.0), REAL_CONST(22139.552540420187/8.0), REAL_CONST(22155.818167827587/8.0), REAL_CONST(22172.086781123569/8.0), REAL_CONST(22188.358379212495/8.0), REAL_CONST(22204.632960999726/8.0), REAL_CONST(22220.910525391639/8.0), REAL_CONST(22237.191071295601/8.0), REAL_CONST(22253.474597619981/8.0), REAL_CONST(22269.761103274148/8.0), REAL_CONST(22286.050587168469/8.0), REAL_CONST(22302.343048214312/8.0), REAL_CONST(22318.638485324027/8.0), REAL_CONST(22334.936897410968/8.0), REAL_CONST(22351.23828338947/8.0), REAL_CONST(22367.542642174871/8.0), REAL_CONST(22383.849972683485/8.0), REAL_CONST(22400.160273832618/8.0), REAL_CONST(22416.473544540564/8.0), REAL_CONST(22432.789783726603/8.0), REAL_CONST(22449.108990310986/8.0), REAL_CONST(22465.431163214958/8.0), REAL_CONST(22481.75630136074/8.0), REAL_CONST(22498.084403671528/8.0), REAL_CONST(22514.415469071497/8.0), REAL_CONST(22530.749496485802/8.0), REAL_CONST(22547.086484840562/8.0), REAL_CONST(22563.426433062879/8.0), REAL_CONST(22579.769340080824/8.0), REAL_CONST(22596.115204823436/8.0), REAL_CONST(22612.464026220721/8.0), REAL_CONST(22628.815803203655/8.0), REAL_CONST(22645.170534704179/8.0), REAL_CONST(22661.5282196552/8.0), REAL_CONST(22677.888856990587/8.0), REAL_CONST(22694.252445645168/8.0), REAL_CONST(22710.618984554734/8.0), REAL_CONST(22726.988472656034/8.0), REAL_CONST(22743.360908886778/8.0), REAL_CONST(22759.736292185622/8.0), REAL_CONST(22776.114621492186/8.0), REAL_CONST(22792.495895747044/8.0), REAL_CONST(22808.880113891719/8.0), REAL_CONST(22825.267274868678/8.0), REAL_CONST(22841.657377621348/8.0), REAL_CONST(22858.050421094096/8.0), REAL_CONST(22874.446404232243/8.0), REAL_CONST(22890.845325982053/8.0), REAL_CONST(22907.247185290722/8.0), REAL_CONST(22923.651981106406/8.0), REAL_CONST(22940.059712378195/8.0), REAL_CONST(22956.470378056114/8.0), REAL_CONST(22972.883977091129/8.0), REAL_CONST(22989.300508435153/8.0), REAL_CONST(23005.719971041017/8.0), REAL_CONST(23022.142363862498/8.0), REAL_CONST(23038.567685854305/8.0), REAL_CONST(23054.995935972078/8.0), REAL_CONST(23071.427113172387/8.0), REAL_CONST(23087.86121641273/8.0), REAL_CONST(23104.298244651531/8.0), REAL_CONST(23120.738196848146/8.0), REAL_CONST(23137.181071962848/8.0), REAL_CONST(23153.626868956846/8.0), REAL_CONST(23170.075586792263/8.0), REAL_CONST(23186.527224432142/8.0), REAL_CONST(23202.981780840448/8.0), REAL_CONST(23219.439254982066/8.0), REAL_CONST(23235.899645822796/8.0), REAL_CONST(23252.362952329357/8.0), REAL_CONST(23268.829173469378/8.0), REAL_CONST(23285.298308211408/8.0), REAL_CONST(23301.770355524899/8.0), REAL_CONST(23318.245314380223/8.0), REAL_CONST(23334.723183748658/8.0), REAL_CONST(23351.203962602387/8.0), REAL_CONST(23367.687649914504/8.0), REAL_CONST(23384.174244659007/8.0), REAL_CONST(23400.663745810798/8.0), REAL_CONST(23417.15615234568/8.0), REAL_CONST(23433.651463240367/8.0), REAL_CONST(23450.149677472462/8.0), REAL_CONST(23466.650794020472/8.0), REAL_CONST(23483.154811863806/8.0), REAL_CONST(23499.661729982763/8.0), REAL_CONST(23516.171547358543/8.0), REAL_CONST(23532.684262973235/8.0), REAL_CONST(23549.199875809823/8.0), REAL_CONST(23565.718384852185/8.0), REAL_CONST(23582.239789085092/8.0), REAL_CONST(23598.764087494197/8.0), REAL_CONST(23615.291279066041/8.0), REAL_CONST(23631.821362788058/8.0), REAL_CONST(23648.354337648565/8.0), REAL_CONST(23664.890202636761/8.0), REAL_CONST(23681.428956742733/8.0), REAL_CONST(23697.970598957443/8.0), REAL_CONST(23714.515128272738/8.0), REAL_CONST(23731.062543681343/8.0), REAL_CONST(23747.612844176863/8.0), REAL_CONST(23764.166028753778/8.0), REAL_CONST(23780.72209640744/8.0), REAL_CONST(23797.281046134085/8.0), REAL_CONST(23813.842876930816/8.0), REAL_CONST(23830.407587795606/8.0), REAL_CONST(23846.975177727301/8.0), REAL_CONST(23863.545645725622/8.0), REAL_CONST(23880.11899079115/8.0), REAL_CONST(23896.695211925336/8.0), REAL_CONST(23913.274308130498/8.0), REAL_CONST(23929.856278409821/8.0), REAL_CONST(23946.441121767348/8.0), REAL_CONST(23963.028837207989/8.0), REAL_CONST(23979.619423737513/8.0), REAL_CONST(23996.212880362549/8.0), REAL_CONST(24012.809206090584/8.0), REAL_CONST(24029.408399929966/8.0), REAL_CONST(24046.010460889898/8.0), REAL_CONST(24062.615387980433/8.0), REAL_CONST(24079.223180212492/8.0), REAL_CONST(24095.833836597827/8.0), REAL_CONST(24112.447356149063/8.0), REAL_CONST(24129.063737879667/8.0), REAL_CONST(24145.682980803951/8.0), REAL_CONST(24162.305083937081/8.0), REAL_CONST(24178.930046295067/8.0), REAL_CONST(24195.557866894767/8.0), REAL_CONST(24212.188544753884/8.0), REAL_CONST(24228.822078890964/8.0), REAL_CONST(24245.458468325389/8.0), REAL_CONST(24262.097712077397/8.0), REAL_CONST(24278.739809168052/8.0), REAL_CONST(24295.384758619261/8.0), REAL_CONST(24312.032559453768/8.0), REAL_CONST(24328.683210695162/8.0), REAL_CONST(24345.336711367858/8.0), REAL_CONST(24361.993060497109/8.0), REAL_CONST(24378.652257108995/8.0), REAL_CONST(24395.314300230442/8.0), REAL_CONST(24411.979188889192/8.0), REAL_CONST(24428.646922113825/8.0), REAL_CONST(24445.317498933746/8.0), REAL_CONST(24461.990918379193/8.0), REAL_CONST(24478.667179481225/8.0), REAL_CONST(24495.346281271726/8.0), REAL_CONST(24512.028222783407/8.0), REAL_CONST(24528.713003049801/8.0), REAL_CONST(24545.400621105266/8.0), REAL_CONST(24562.091075984976/8.0), REAL_CONST(24578.784366724925/8.0), REAL_CONST(24595.480492361927/8.0), REAL_CONST(24612.179451933614/8.0), REAL_CONST(24628.881244478438/8.0), REAL_CONST(24645.585869035654/8.0), REAL_CONST(24662.293324645343/8.0), REAL_CONST(24679.003610348394/8.0), REAL_CONST(24695.716725186514/8.0), REAL_CONST(24712.432668202211/8.0), REAL_CONST(24729.151438438807/8.0), REAL_CONST(24745.873034940436/8.0), REAL_CONST(24762.597456752032/8.0), REAL_CONST(24779.324702919344/8.0), REAL_CONST(24796.054772488926/8.0), REAL_CONST(24812.787664508123/8.0), REAL_CONST(24829.5233780251/8.0), REAL_CONST(24846.261912088819/8.0), REAL_CONST(24863.003265749034/8.0), REAL_CONST(24879.747438056307/8.0), REAL_CONST(24896.494428062004/8.0), REAL_CONST(24913.244234818278/8.0), REAL_CONST(24929.996857378079/8.0), REAL_CONST(24946.752294795166/8.0), REAL_CONST(24963.510546124078/8.0), REAL_CONST(24980.271610420157/8.0), REAL_CONST(24997.035486739525/8.0), REAL_CONST(25013.802174139113/8.0), REAL_CONST(25030.571671676629/8.0), REAL_CONST(25047.343978410572/8.0), REAL_CONST(25064.119093400237/8.0), REAL_CONST(25080.897015705697/8.0), REAL_CONST(25097.677744387816/8.0), REAL_CONST(25114.461278508239/8.0), REAL_CONST(25131.2476171294/8.0), REAL_CONST(25148.036759314517/8.0), REAL_CONST(25164.828704127583/8.0), REAL_CONST(25181.623450633375/8.0), REAL_CONST(25198.42099789745/8.0), REAL_CONST(25215.221344986145/8.0), REAL_CONST(25232.024490966574/8.0), REAL_CONST(25248.830434906627/8.0), REAL_CONST(25265.639175874974/8.0), REAL_CONST(25282.450712941049/8.0), REAL_CONST(25299.265045175071/8.0), REAL_CONST(25316.082171648024/8.0), REAL_CONST(25332.902091431668/8.0), REAL_CONST(25349.724803598532/8.0), REAL_CONST(25366.550307221914/8.0), REAL_CONST(25383.378601375884/8.0), REAL_CONST(25400.209685135269/8.0), REAL_CONST(25417.043557575678/8.0), REAL_CONST(25433.880217773472/8.0), REAL_CONST(25450.719664805783/8.0), REAL_CONST(25467.561897750507/8.0), REAL_CONST(25484.406915686297/8.0), REAL_CONST(25501.254717692573/8.0), REAL_CONST(25518.105302849512/8.0), REAL_CONST(25534.958670238051/8.0), REAL_CONST(25551.814818939893/8.0), REAL_CONST(25568.67374803748/8.0), REAL_CONST(25585.535456614027/8.0), REAL_CONST(25602.399943753502/8.0), REAL_CONST(25619.267208540619/8.0), REAL_CONST(25636.137250060852/8.0), REAL_CONST(25653.010067400432/8.0), REAL_CONST(25669.885659646327/8.0), REAL_CONST(25686.76402588627/8.0), REAL_CONST(25703.645165208734/8.0), REAL_CONST(25720.529076702944/8.0), REAL_CONST(25737.415759458876/8.0), REAL_CONST(25754.305212567244/8.0), REAL_CONST(25771.197435119517/8.0), REAL_CONST(25788.092426207899/8.0), REAL_CONST(25804.990184925344/8.0), REAL_CONST(25821.890710365547/8.0), REAL_CONST(25838.794001622944/8.0), REAL_CONST(25855.700057792714/8.0), REAL_CONST(25872.608877970775/8.0), REAL_CONST(25889.520461253778/8.0), REAL_CONST(25906.434806739118/8.0), REAL_CONST(25923.351913524923/8.0), REAL_CONST(25940.271780710063/8.0), REAL_CONST(25957.194407394138/8.0), REAL_CONST(25974.11979267748/8.0), REAL_CONST(25991.047935661154/8.0), REAL_CONST(26007.978835446964/8.0), REAL_CONST(26024.912491137442/8.0), REAL_CONST(26041.848901835841/8.0), REAL_CONST(26058.788066646157/8.0), REAL_CONST(26075.729984673108/8.0), REAL_CONST(26092.674655022136/8.0), REAL_CONST(26109.622076799409/8.0), REAL_CONST(26126.572249111829/8.0), REAL_CONST(26143.525171067016/8.0), REAL_CONST(26160.480841773315/8.0), REAL_CONST(26177.43926033979/8.0), REAL_CONST(26194.400425876229/8.0), REAL_CONST(26211.364337493149/8.0), REAL_CONST(26228.330994301767/8.0), REAL_CONST(26245.30039541404/8.0), REAL_CONST(26262.272539942627/8.0), REAL_CONST(26279.247427000919/8.0), REAL_CONST(26296.225055703002/8.0), REAL_CONST(26313.205425163702/8.0), REAL_CONST(26330.188534498539/8.0), REAL_CONST(26347.174382823756/8.0), REAL_CONST(26364.162969256304/8.0), REAL_CONST(26381.154292913852/8.0), REAL_CONST(26398.148352914774/8.0), REAL_CONST(26415.145148378149/8.0), REAL_CONST(26432.144678423778/8.0), REAL_CONST(26449.146942172156/8.0), REAL_CONST(26466.151938744493/8.0), REAL_CONST(26483.159667262702/8.0), REAL_CONST(26500.170126849403/8.0), REAL_CONST(26517.183316627921/8.0), REAL_CONST(26534.199235722277/8.0), REAL_CONST(26551.217883257199/8.0), REAL_CONST(26568.239258358124/8.0), REAL_CONST(26585.263360151173/8.0), REAL_CONST(26602.290187763181/8.0), REAL_CONST(26619.319740321676/8.0), REAL_CONST(26636.352016954883/8.0), REAL_CONST(26653.387016791727/8.0), REAL_CONST(26670.424738961825/8.0), REAL_CONST(26687.465182595493/8.0), REAL_CONST(26704.508346823739/8.0), REAL_CONST(26721.554230778267/8.0), REAL_CONST(26738.602833591467/8.0), REAL_CONST(26755.65415439643/8.0), REAL_CONST(26772.708192326929/8.0), REAL_CONST(26789.764946517433/8.0), REAL_CONST(26806.824416103096/8.0), REAL_CONST(26823.886600219761/8.0), REAL_CONST(26840.95149800396/8.0), REAL_CONST(26858.019108592915/8.0), REAL_CONST(26875.089431124517/8.0), REAL_CONST(26892.162464737365/8.0), REAL_CONST(26909.238208570721/8.0), REAL_CONST(26926.316661764544/8.0), REAL_CONST(26943.397823459472/8.0), REAL_CONST(26960.481692796813/8.0), REAL_CONST(26977.568268918571/8.0), REAL_CONST(26994.657550967422/8.0), REAL_CONST(27011.749538086722/8.0), REAL_CONST(27028.844229420498/8.0), REAL_CONST(27045.941624113464/8.0), REAL_CONST(27063.041721311005/8.0), REAL_CONST(27080.144520159181/8.0), REAL_CONST(27097.250019804727/8.0), REAL_CONST(27114.35821939505/8.0), REAL_CONST(27131.469118078236/8.0), REAL_CONST(27148.582715003027/8.0), REAL_CONST(27165.699009318858/8.0), REAL_CONST(27182.818000175819/8.0), REAL_CONST(27199.939686724665/8.0), REAL_CONST(27217.064068116837/8.0), REAL_CONST(27234.191143504428/8.0), REAL_CONST(27251.320912040203/8.0), REAL_CONST(27268.453372877593/8.0), REAL_CONST(27285.588525170693/8.0), REAL_CONST(27302.726368074269/8.0), REAL_CONST(27319.866900743735/8.0), REAL_CONST(27337.010122335181/8.0), REAL_CONST(27354.156032005358/8.0), REAL_CONST(27371.304628911668/8.0), REAL_CONST(27388.455912212183/8.0), REAL_CONST(27405.609881065626/8.0), REAL_CONST(27422.766534631384/8.0), REAL_CONST(27439.925872069507/8.0), REAL_CONST(27457.087892540683/8.0), REAL_CONST(27474.252595206275/8.0), REAL_CONST(27491.419979228293/8.0), REAL_CONST(27508.5900437694/8.0), REAL_CONST(27525.762787992917/8.0), REAL_CONST(27542.93821106281/8.0), REAL_CONST(27560.116312143706/8.0), REAL_CONST(27577.297090400876/8.0), REAL_CONST(27594.480545000242/8.0), REAL_CONST(27611.666675108383/8.0), REAL_CONST(27628.855479892518/8.0), REAL_CONST(27646.046958520514/8.0), REAL_CONST(27663.241110160889/8.0), REAL_CONST(27680.437933982801/8.0), REAL_CONST(27697.637429156068/8.0), REAL_CONST(27714.839594851132/8.0), REAL_CONST(27732.04443023909/8.0), REAL_CONST(27749.251934491687/8.0), REAL_CONST(27766.462106781299/8.0), REAL_CONST(27783.674946280949/8.0), REAL_CONST(27800.890452164302/8.0), REAL_CONST(27818.108623605654/8.0), REAL_CONST(27835.329459779954/8.0), REAL_CONST(27852.55295986278/8.0), REAL_CONST(27869.779123030345/8.0), REAL_CONST(27887.007948459504/8.0), REAL_CONST(27904.239435327745/8.0), REAL_CONST(27921.473582813196/8.0), REAL_CONST(27938.710390094613/8.0), REAL_CONST(27955.949856351392/8.0), REAL_CONST(27973.19198076355/8.0), REAL_CONST(27990.436762511745/8.0), REAL_CONST(28007.684200777272/8.0), REAL_CONST(28024.934294742041/8.0), REAL_CONST(28042.187043588601/8.0), REAL_CONST(28059.442446500128/8.0), REAL_CONST(28076.700502660427/8.0), REAL_CONST(28093.961211253929/8.0), REAL_CONST(28111.224571465693/8.0), REAL_CONST(28128.490582481401/8.0), REAL_CONST(28145.759243487362/8.0), REAL_CONST(28163.030553670509/8.0), REAL_CONST(28180.304512218394/8.0), REAL_CONST(28197.581118319198/8.0), REAL_CONST(28214.860371161725/8.0), REAL_CONST(28232.14226993539/8.0), REAL_CONST(28249.42681383024/8.0), REAL_CONST(28266.71400203693/8.0), REAL_CONST(28284.003833746745/8.0), REAL_CONST(28301.296308151585/8.0), REAL_CONST(28318.591424443959/8.0), REAL_CONST(28335.889181817001/8.0), REAL_CONST(28353.189579464462/8.0), REAL_CONST(28370.492616580705/8.0), REAL_CONST(28387.798292360701/8.0), REAL_CONST(28405.106606000048/8.0), REAL_CONST(28422.417556694945/8.0), REAL_CONST(28439.731143642206/8.0), REAL_CONST(28457.047366039264/8.0), REAL_CONST(28474.366223084147/8.0), REAL_CONST(28491.687713975512/8.0), REAL_CONST(28509.011837912611/8.0), REAL_CONST(28526.338594095305/8.0), REAL_CONST(28543.667981724069/8.0), REAL_CONST(28560.999999999982/8.0), REAL_CONST(28578.334648124732/8.0), REAL_CONST(28595.671925300605/8.0), REAL_CONST(28613.011830730498/8.0), REAL_CONST(28630.354363617909/8.0), REAL_CONST(28647.699523166943/8.0), REAL_CONST(28665.0473085823/8.0), REAL_CONST(28682.397719069289/8.0), REAL_CONST(28699.750753833818/8.0), REAL_CONST(28717.10641208239/8.0), REAL_CONST(28734.464693022121/8.0), REAL_CONST(28751.825595860708/8.0), REAL_CONST(28769.189119806462/8.0), REAL_CONST(28786.55526406828/8.0), REAL_CONST(28803.924027855664/8.0), REAL_CONST(28821.295410378701/8.0), REAL_CONST(28838.669410848088/8.0), REAL_CONST(28856.046028475103/8.0), REAL_CONST(28873.425262471628/8.0), REAL_CONST(28890.80711205013/8.0), REAL_CONST(28908.191576423673/8.0), REAL_CONST(28925.578654805915/8.0), REAL_CONST(28942.968346411097/8.0), REAL_CONST(28960.360650454055/8.0), REAL_CONST(28977.755566150216/8.0), REAL_CONST(28995.153092715591/8.0), REAL_CONST(29012.553229366786/8.0), REAL_CONST(29029.955975320987/8.0), REAL_CONST(29047.361329795975/8.0), REAL_CONST(29064.769292010107/8.0), REAL_CONST(29082.179861182336/8.0), REAL_CONST(29099.593036532187/8.0), REAL_CONST(29117.00881727978/8.0), REAL_CONST(29134.427202645813/8.0), REAL_CONST(29151.848191851568/8.0), REAL_CONST(29169.271784118911/8.0), REAL_CONST(29186.697978670283/8.0), REAL_CONST(29204.126774728706/8.0), REAL_CONST(29221.55817151779/8.0), REAL_CONST(29238.992168261717/8.0), REAL_CONST(29256.42876418525/8.0), REAL_CONST(29273.867958513725/8.0), REAL_CONST(29291.309750473058/8.0), REAL_CONST(29308.754139289747/8.0), REAL_CONST(29326.201124190855/8.0), REAL_CONST(29343.65070440403/8.0), REAL_CONST(29361.102879157483/8.0), REAL_CONST(29378.557647680012/8.0), REAL_CONST(29396.015009200975/8.0), REAL_CONST(29413.474962950309/8.0), REAL_CONST(29430.937508158524/8.0), REAL_CONST(29448.402644056692/8.0), REAL_CONST(29465.870369876469/8.0), REAL_CONST(29483.340684850071/8.0), REAL_CONST(29500.81358821028/8.0), REAL_CONST(29518.289079190454/8.0), REAL_CONST(29535.767157024511/8.0), REAL_CONST(29553.247820946945/8.0), REAL_CONST(29570.731070192807/8.0), REAL_CONST(29588.216903997723/8.0), REAL_CONST(29605.70532159787/8.0), REAL_CONST(29623.19632223/8.0), REAL_CONST(29640.689905131429/8.0), REAL_CONST(29658.186069540028/8.0), REAL_CONST(29675.684814694236/8.0), REAL_CONST(29693.186139833047/8.0), REAL_CONST(29710.690044196028/8.0), REAL_CONST(29728.196527023298/8.0), REAL_CONST(29745.705587555527/8.0), REAL_CONST(29763.217225033964/8.0), REAL_CONST(29780.731438700397/8.0), REAL_CONST(29798.248227797183/8.0), REAL_CONST(29815.76759156723/8.0), REAL_CONST(29833.289529254005/8.0), REAL_CONST(29850.81404010153/8.0), REAL_CONST(29868.341123354381/8.0), REAL_CONST(29885.870778257693/8.0), REAL_CONST(29903.403004057145/8.0), REAL_CONST(29920.937799998974/8.0), REAL_CONST(29938.475165329975/8.0), REAL_CONST(29956.015099297485/8.0), REAL_CONST(29973.557601149394/8.0), REAL_CONST(29991.102670134147/8.0), REAL_CONST(30008.650305500738/8.0), REAL_CONST(30026.200506498706/8.0), REAL_CONST(30043.753272378144/8.0), REAL_CONST(30061.308602389683/8.0), REAL_CONST(30078.866495784507/8.0), REAL_CONST(30096.426951814352/8.0), REAL_CONST(30113.989969731494/8.0), REAL_CONST(30131.55554878875/8.0), REAL_CONST(30149.123688239491/8.0), REAL_CONST(30166.694387337629/8.0), REAL_CONST(30184.267645337608/8.0), REAL_CONST(30201.843461494434/8.0), REAL_CONST(30219.42183506364/8.0), REAL_CONST(30237.002765301309/8.0), REAL_CONST(30254.586251464058/8.0), REAL_CONST(30272.172292809046/8.0), REAL_CONST(30289.760888593977/8.0), REAL_CONST(30307.35203807709/8.0), REAL_CONST(30324.94574051716/8.0), REAL_CONST(30342.541995173502/8.0), REAL_CONST(30360.140801305966/8.0), REAL_CONST(30377.742158174944/8.0), REAL_CONST(30395.346065041358/8.0), REAL_CONST(30412.952521166666/8.0), REAL_CONST(30430.561525812864/8.0), REAL_CONST(30448.173078242475/8.0), REAL_CONST(30465.787177718561/8.0), REAL_CONST(30483.403823504719/8.0), REAL_CONST(30501.02301486507/8.0), REAL_CONST(30518.644751064272/8.0), REAL_CONST(30536.269031367516/8.0), REAL_CONST(30553.895855040515/8.0), REAL_CONST(30571.525221349519/8.0), REAL_CONST(30589.157129561307/8.0), REAL_CONST(30606.791578943175/8.0), REAL_CONST(30624.428568762964/8.0), REAL_CONST(30642.06809828903/8.0), REAL_CONST(30659.710166790261/8.0), REAL_CONST(30677.35477353607/8.0), REAL_CONST(30695.001917796391/8.0), REAL_CONST(30712.651598841687/8.0), REAL_CONST(30730.303815942945/8.0), REAL_CONST(30747.958568371676/8.0), REAL_CONST(30765.615855399912/8.0), REAL_CONST(30783.275676300211/8.0), REAL_CONST(30800.938030345646/8.0), REAL_CONST(30818.602916809814/8.0), REAL_CONST(30836.270334966837/8.0), REAL_CONST(30853.940284091354/8.0), REAL_CONST(30871.612763458521/8.0), REAL_CONST(30889.287772344011/8.0), REAL_CONST(30906.965310024025/8.0), REAL_CONST(30924.645375775272/8.0), REAL_CONST(30942.327968874983/8.0), REAL_CONST(30960.013088600903/8.0), REAL_CONST(30977.700734231294/8.0), REAL_CONST(30995.390905044929/8.0), REAL_CONST(31013.083600321101/8.0), REAL_CONST(31030.778819339619/8.0), REAL_CONST(31048.476561380798/8.0), REAL_CONST(31066.17682572547/8.0), REAL_CONST(31083.879611654978/8.0), REAL_CONST(31101.584918451179/8.0), REAL_CONST(31119.29274539644/8.0), REAL_CONST(31137.003091773637/8.0), REAL_CONST(31154.715956866155/8.0), REAL_CONST(31172.431339957893/8.0), REAL_CONST(31190.14924033326/8.0), REAL_CONST(31207.869657277162/8.0), REAL_CONST(31225.592590075023/8.0), REAL_CONST(31243.318038012771/8.0), REAL_CONST(31261.046000376838/8.0), REAL_CONST(31278.776476454172/8.0), REAL_CONST(31296.50946553221/8.0), REAL_CONST(31314.24496689891/8.0), REAL_CONST(31331.98297984272/8.0), REAL_CONST(31349.7235036526/8.0), REAL_CONST(31367.466537618013/8.0), REAL_CONST(31385.212081028923/8.0), REAL_CONST(31402.960133175795/8.0), REAL_CONST(31420.710693349596/8.0), REAL_CONST(31438.463760841791/8.0), REAL_CONST(31456.219334944351/8.0), REAL_CONST(31473.977414949743/8.0), REAL_CONST(31491.738000150934/8.0), REAL_CONST(31509.501089841389/8.0), REAL_CONST(31527.266683315069/8.0), REAL_CONST(31545.034779866437/8.0), REAL_CONST(31562.80537879045/8.0), REAL_CONST(31580.578479382562/8.0), REAL_CONST(31598.35408093872/8.0), REAL_CONST(31616.132182755369/8.0), REAL_CONST(31633.91278412945/8.0), REAL_CONST(31651.695884358396/8.0), REAL_CONST(31669.481482740131/8.0), REAL_CONST(31687.269578573076/8.0), REAL_CONST(31705.060171156143/8.0), REAL_CONST(31722.853259788735/8.0), REAL_CONST(31740.648843770748/8.0), REAL_CONST(31758.446922402567/8.0), REAL_CONST(31776.247494985066/8.0), REAL_CONST(31794.050560819614/8.0), REAL_CONST(31811.85611920806/8.0), REAL_CONST(31829.664169452753/8.0), REAL_CONST(31847.474710856521/8.0), REAL_CONST(31865.287742722685/8.0), REAL_CONST(31883.103264355046/8.0), REAL_CONST(31900.921275057899/8.0), REAL_CONST(31918.741774136019/8.0), REAL_CONST(31936.564760894671/8.0), REAL_CONST(31954.390234639599/8.0), REAL_CONST(31972.21819467704/8.0), REAL_CONST(31990.048640313704/8.0), REAL_CONST(32007.881570856793/8.0), REAL_CONST(32025.716985613984/8.0), REAL_CONST(32043.554883893445/8.0), REAL_CONST(32061.395265003815/8.0), REAL_CONST(32079.238128254223/8.0), REAL_CONST(32097.083472954269/8.0), REAL_CONST(32114.931298414049/8.0), REAL_CONST(32132.781603944117/8.0), REAL_CONST(32150.634388855524/8.0), REAL_CONST(32168.48965245979/8.0), REAL_CONST(32186.347394068915/8.0), REAL_CONST(32204.207612995371/8.0), REAL_CONST(32222.07030855212/8.0), REAL_CONST(32239.935480052583/8.0), REAL_CONST(32257.803126810672/8.0), REAL_CONST(32275.673248140767/8.0), REAL_CONST(32293.545843357719/8.0), REAL_CONST(32311.420911776862/8.0), REAL_CONST(32329.298452713996/8.0), REAL_CONST(32347.178465485395/8.0), REAL_CONST(32365.060949407813/8.0), REAL_CONST(32382.945903798463/8.0), REAL_CONST(32400.83332797504/8.0), REAL_CONST(32418.723221255706/8.0), REAL_CONST(32436.615582959093/8.0), REAL_CONST(32454.510412404306/8.0), REAL_CONST(32472.407708910916/8.0), REAL_CONST(32490.307471798966/8.0), REAL_CONST(32508.209700388961/8.0), REAL_CONST(32526.114394001877/8.0), REAL_CONST(32544.021551959166/8.0), REAL_CONST(32561.931173582732/8.0), REAL_CONST(32579.843258194956/8.0), REAL_CONST(32597.757805118679/8.0), REAL_CONST(32615.674813677211/8.0), REAL_CONST(32633.594283194328/8.0), REAL_CONST(32651.516212994258/8.0), REAL_CONST(32669.440602401712/8.0), REAL_CONST(32687.367450741847/8.0), REAL_CONST(32705.296757340297/8.0), REAL_CONST(32723.228521523146/8.0), REAL_CONST(32741.162742616943/8.0), REAL_CONST(32759.099419948703/8.0), REAL_CONST(32777.038552845901/8.0), REAL_CONST(32794.980140636464/8.0), REAL_CONST(32812.924182648792/8.0), REAL_CONST(32830.87067821173/8.0), REAL_CONST(32848.819626654593/8.0), REAL_CONST(32866.77102730715/8.0), REAL_CONST(32884.724879499619/8.0), REAL_CONST(32902.681182562686/8.0), REAL_CONST(32920.639935827494/8.0), REAL_CONST(32938.601138625643/8.0), REAL_CONST(32956.56479028918/8.0), REAL_CONST(32974.530890150607/8.0), REAL_CONST(32992.499437542894/8.0), REAL_CONST(33010.470431799447/8.0), REAL_CONST(33028.443872254145/8.0), REAL_CONST(33046.419758241311/8.0), REAL_CONST(33064.39808909571/8.0), REAL_CONST(33082.378864152583/8.0), REAL_CONST(33100.36208274759/8.0), REAL_CONST(33118.347744216881/8.0), REAL_CONST(33136.335847897026/8.0), REAL_CONST(33154.326393125062/8.0), REAL_CONST(33172.31937923847/8.0), REAL_CONST(33190.314805575174/8.0), REAL_CONST(33208.312671473555/8.0), REAL_CONST(33226.312976272442/8.0), REAL_CONST(33244.315719311111/8.0), REAL_CONST(33262.320899929284/8.0), REAL_CONST(33280.328517467125/8.0), REAL_CONST(33298.33857126526/8.0), REAL_CONST(33316.351060664747/8.0), REAL_CONST(33334.365985007091/8.0), REAL_CONST(33352.383343634239/8.0), REAL_CONST(33370.403135888591/8.0), REAL_CONST(33388.42536111299/8.0), REAL_CONST(33406.450018650721/8.0), REAL_CONST(33424.477107845501/8.0), REAL_CONST(33442.506628041512/8.0), REAL_CONST(33460.53857858335/8.0), REAL_CONST(33478.572958816083/8.0), REAL_CONST(33496.609768085189/8.0), REAL_CONST(33514.649005736617/8.0), REAL_CONST(33532.690671116739/8.0), REAL_CONST(33550.734763572356/8.0), REAL_CONST(33568.781282450735/8.0), REAL_CONST(33586.830227099563/8.0), REAL_CONST(33604.881596866973/8.0), REAL_CONST(33622.935391101528/8.0), REAL_CONST(33640.991609152239/8.0), REAL_CONST(33659.050250368542/8.0), REAL_CONST(33677.111314100322/8.0), REAL_CONST(33695.174799697881/8.0), REAL_CONST(33713.240706511984/8.0), REAL_CONST(33731.309033893805/8.0), REAL_CONST(33749.37978119497/8.0), REAL_CONST(33767.452947767531/8.0), REAL_CONST(33785.528532963974/8.0), REAL_CONST(33803.606536137209/8.0), REAL_CONST(33821.686956640602/8.0), REAL_CONST(33839.769793827938/8.0), REAL_CONST(33857.855047053425/8.0), REAL_CONST(33875.942715671707/8.0), REAL_CONST(33894.032799037872/8.0), REAL_CONST(33912.125296507431/8.0), REAL_CONST(33930.220207436316/8.0), REAL_CONST(33948.317531180888/8.0), REAL_CONST(33966.417267097961/8.0), REAL_CONST(33984.519414544746/8.0), REAL_CONST(34002.623972878901/8.0), REAL_CONST(34020.730941458511/8.0), REAL_CONST(34038.840319642077/8.0), REAL_CONST(34056.952106788536/8.0), REAL_CONST(34075.066302257255/8.0), REAL_CONST(34093.182905408015/8.0), REAL_CONST(34111.301915601027/8.0), REAL_CONST(34129.42333219693/8.0), REAL_CONST(34147.547154556785/8.0), REAL_CONST(34165.673382042078/8.0), REAL_CONST(34183.80201401472/8.0), REAL_CONST(34201.933049837033/8.0), REAL_CONST(34220.06648887178/8.0), REAL_CONST(34238.202330482141/8.0), REAL_CONST(34256.340574031703/8.0), REAL_CONST(34274.481218884495/8.0), REAL_CONST(34292.624264404949/8.0), REAL_CONST(34310.769709957938/8.0), REAL_CONST(34328.91755490873/8.0), REAL_CONST(34347.067798623029/8.0), REAL_CONST(34365.220440466954/8.0), REAL_CONST(34383.375479807051/8.0), REAL_CONST(34401.532916010263/8.0), REAL_CONST(34419.692748443973/8.0), REAL_CONST(34437.854976475966/8.0), REAL_CONST(34456.01959947445/8.0), REAL_CONST(34474.18661680806/8.0), REAL_CONST(34492.356027845817/8.0), REAL_CONST(34510.527831957188/8.0), REAL_CONST(34528.702028512052/8.0), REAL_CONST(34546.878616880676/8.0), REAL_CONST(34565.05759643377/8.0), REAL_CONST(34583.238966542449/8.0), REAL_CONST(34601.422726578232/8.0), REAL_CONST(34619.608875913065/8.0), REAL_CONST(34637.797413919296/8.0), REAL_CONST(34655.988339969692/8.0), REAL_CONST(34674.181653437423/8.0), REAL_CONST(34692.37735369608/8.0), REAL_CONST(34710.575440119668/8.0), REAL_CONST(34728.775912082579/8.0), REAL_CONST(34746.978768959649/8.0), REAL_CONST(34765.184010126082/8.0), REAL_CONST(34783.391634957537/8.0), REAL_CONST(34801.60164283005/8.0), REAL_CONST(34819.814033120063/8.0), REAL_CONST(34838.028805204456/8.0), REAL_CONST(34856.24595846048/8.0), REAL_CONST(34874.465492265823/8.0), REAL_CONST(34892.687405998557/8.0), REAL_CONST(34910.911699037177/8.0), REAL_CONST(34929.138370760564/8.0), REAL_CONST(34947.367420548027/8.0), REAL_CONST(34965.598847779271/8.0), REAL_CONST(34983.832651834389/8.0), REAL_CONST(35002.068832093908/8.0), REAL_CONST(35020.307387938738/8.0), REAL_CONST(35038.548318750189/8.0), REAL_CONST(35056.79162390998/8.0), REAL_CONST(35075.03730280025/8.0), REAL_CONST(35093.285354803513/8.0), REAL_CONST(35111.535779302685/8.0), REAL_CONST(35129.788575681116/8.0), REAL_CONST(35148.043743322516/8.0), REAL_CONST(35166.301281611013/8.0), REAL_CONST(35184.561189931141/8.0), REAL_CONST(35202.823467667826/8.0), REAL_CONST(35221.088114206388/8.0), REAL_CONST(35239.355128932555/8.0), REAL_CONST(35257.624511232447/8.0), REAL_CONST(35275.896260492584/8.0), REAL_CONST(35294.170376099886/8.0), REAL_CONST(35312.446857441668/8.0), REAL_CONST(35330.725703905628/8.0), REAL_CONST(35349.006914879887/8.0), REAL_CONST(35367.290489752944/8.0), REAL_CONST(35385.576427913686/8.0), REAL_CONST(35403.864728751418/8.0), REAL_CONST(35422.155391655811/8.0), REAL_CONST(35440.448416016967/8.0), REAL_CONST(35458.743801225341/8.0), REAL_CONST(35477.041546671804/8.0), REAL_CONST(35495.341651747622/8.0), REAL_CONST(35513.644115844436/8.0), REAL_CONST(35531.948938354304/8.0), REAL_CONST(35550.256118669655/8.0), REAL_CONST(35568.565656183309/8.0), REAL_CONST(35586.877550288496/8.0), REAL_CONST(35605.191800378816/8.0), REAL_CONST(35623.508405848268/8.0), REAL_CONST(35641.827366091238/8.0), REAL_CONST(35660.148680502505/8.0), REAL_CONST(35678.472348477233/8.0), REAL_CONST(35696.798369410979/8.0), REAL_CONST(35715.126742699678/8.0), REAL_CONST(35733.457467739659/8.0), REAL_CONST(35751.790543927644/8.0), REAL_CONST(35770.125970660738/8.0), REAL_CONST(35788.46374733642/8.0), REAL_CONST(35806.803873352568/8.0), REAL_CONST(35825.146348107453/8.0), REAL_CONST(35843.49117099971/8.0), REAL_CONST(35861.838341428367/8.0), REAL_CONST(35880.187858792851/8.0), REAL_CONST(35898.539722492955/8.0), REAL_CONST(35916.893931928862/8.0), REAL_CONST(35935.250486501129/8.0), REAL_CONST(35953.609385610718/8.0), REAL_CONST(35971.970628658957/8.0), REAL_CONST(35990.334215047558/8.0), REAL_CONST(36008.700144178612/8.0), REAL_CONST(36027.068415454596/8.0), REAL_CONST(36045.439028278372/8.0), REAL_CONST(36063.811982053165/8.0), REAL_CONST(36082.187276182609/8.0), REAL_CONST(36100.564910070694/8.0), REAL_CONST(36118.944883121789/8.0), REAL_CONST(36137.327194740654/8.0), REAL_CONST(36155.711844332429/8.0), REAL_CONST(36174.098831302617/8.0), REAL_CONST(36192.488155057115/8.0), REAL_CONST(36210.87981500219/8.0), REAL_CONST(36229.273810544473/8.0), REAL_CONST(36247.670141091003/8.0), REAL_CONST(36266.068806049167/8.0), REAL_CONST(36284.469804826738/8.0), REAL_CONST(36302.873136831862/8.0), REAL_CONST(36321.278801473069/8.0), REAL_CONST(36339.686798159251/8.0), REAL_CONST(36358.097126299683/8.0), REAL_CONST(36376.509785304013/8.0), REAL_CONST(36394.924774582258/8.0), REAL_CONST(36413.342093544816/8.0), REAL_CONST(36431.761741602444/8.0), REAL_CONST(36450.183718166292/8.0), REAL_CONST(36468.608022647859/8.0), REAL_CONST(36487.034654459028/8.0), REAL_CONST(36505.463613012063/8.0), REAL_CONST(36523.894897719583/8.0), REAL_CONST(36542.328507994578/8.0), REAL_CONST(36560.764443250409/8.0), REAL_CONST(36579.202702900831/8.0), REAL_CONST(36597.643286359926/8.0), REAL_CONST(36616.086193042182/8.0), REAL_CONST(36634.531422362437/8.0), REAL_CONST(36652.978973735895/8.0), REAL_CONST(36671.428846578143/8.0), REAL_CONST(36689.881040305125/8.0), REAL_CONST(36708.335554333149/8.0), REAL_CONST(36726.792388078902/8.0), REAL_CONST(36745.251540959427/8.0), REAL_CONST(36763.713012392138/8.0), REAL_CONST(36782.176801794812/8.0), REAL_CONST(36800.642908585593/8.0), REAL_CONST(36819.111332182983/8.0), REAL_CONST(36837.582072005869/8.0), REAL_CONST(36856.055127473483/8.0), REAL_CONST(36874.530498005421/8.0), REAL_CONST(36893.008183021651/8.0), REAL_CONST(36911.488181942506/8.0), REAL_CONST(36929.970494188674/8.0), REAL_CONST(36948.455119181206/8.0), REAL_CONST(36966.942056341519/8.0), REAL_CONST(36985.431305091392/8.0), REAL_CONST(37003.922864852961/8.0), REAL_CONST(37022.416735048733/8.0), REAL_CONST(37040.912915101559/8.0), REAL_CONST(37059.411404434657/8.0), REAL_CONST(37077.91220247162/8.0), REAL_CONST(37096.415308636388/8.0), REAL_CONST(37114.920722353243/8.0), REAL_CONST(37133.428443046862/8.0), REAL_CONST(37151.938470142253/8.0), REAL_CONST(37170.450803064785/8.0), REAL_CONST(37188.965441240209/8.0), REAL_CONST(37207.482384094597/8.0), REAL_CONST(37226.001631054402/8.0), REAL_CONST(37244.523181546429/8.0), REAL_CONST(37263.047034997842/8.0), REAL_CONST(37281.573190836149/8.0), REAL_CONST(37300.101648489224/8.0), REAL_CONST(37318.632407385296/8.0), REAL_CONST(37337.165466952945/8.0), REAL_CONST(37355.700826621112/8.0), REAL_CONST(37374.238485819085/8.0), REAL_CONST(37392.778443976509/8.0), REAL_CONST(37411.320700523385/8.0), REAL_CONST(37429.865254890057/8.0), REAL_CONST(37448.412106507232/8.0), REAL_CONST(37466.961254805974/8.0), REAL_CONST(37485.512699217681/8.0), REAL_CONST(37504.066439174116/8.0), REAL_CONST(37522.622474107404/8.0), REAL_CONST(37541.180803449992/8.0), REAL_CONST(37559.741426634704/8.0), REAL_CONST(37578.304343094693/8.0), REAL_CONST(37596.869552263488/8.0), REAL_CONST(37615.43705357494/8.0), REAL_CONST(37634.006846463279/8.0), REAL_CONST(37652.578930363044/8.0), REAL_CONST(37671.153304709165/8.0), REAL_CONST(37689.729968936896/8.0), REAL_CONST(37708.308922481847/8.0), REAL_CONST(37726.890164779965/8.0), REAL_CONST(37745.473695267559/8.0), REAL_CONST(37764.059513381275/8.0), REAL_CONST(37782.647618558112/8.0), REAL_CONST(37801.238010235415/8.0), REAL_CONST(37819.830687850859/8.0), REAL_CONST(37838.425650842495/8.0), REAL_CONST(37857.022898648691/8.0), REAL_CONST(37875.622430708172/8.0), REAL_CONST(37894.224246460013/8.0), REAL_CONST(37912.828345343616/8.0), REAL_CONST(37931.434726798747/8.0), REAL_CONST(37950.043390265506/8.0), REAL_CONST(37968.654335184328/8.0), REAL_CONST(37987.267560995999/8.0), REAL_CONST(38005.883067141665/8.0), REAL_CONST(38024.500853062775/8.0), REAL_CONST(38043.120918201159/8.0), REAL_CONST(38061.743261998963/8.0), REAL_CONST(38080.367883898682/8.0), REAL_CONST(38098.994783343158/8.0), REAL_CONST(38117.623959775563/8.0), REAL_CONST(38136.255412639417/8.0), REAL_CONST(38154.889141378575/8.0), REAL_CONST(38173.525145437234/8.0), REAL_CONST(38192.163424259939/8.0), REAL_CONST(38210.803977291551/8.0), REAL_CONST(38229.446803977284/8.0), REAL_CONST(38248.091903762703/8.0), REAL_CONST(38266.739276093685/8.0), REAL_CONST(38285.388920416466/8.0), REAL_CONST(38304.040836177606/8.0), REAL_CONST(38322.695022824002/8.0), REAL_CONST(38341.351479802899/8.0), REAL_CONST(38360.010206561863/8.0), REAL_CONST(38378.671202548816/8.0), REAL_CONST(38397.334467211993/8.0), REAL_CONST(38415.999999999978/8.0), REAL_CONST(38434.667800361683/8.0), REAL_CONST(38453.33786774637/8.0), REAL_CONST(38472.010201603611/8.0), REAL_CONST(38490.684801383337/8.0), REAL_CONST(38509.361666535784/8.0), REAL_CONST(38528.040796511552/8.0), REAL_CONST(38546.722190761553/8.0), REAL_CONST(38565.405848737035/8.0), REAL_CONST(38584.091769889594/8.0), REAL_CONST(38602.779953671132/8.0), REAL_CONST(38621.470399533908/8.0), REAL_CONST(38640.163106930493/8.0), REAL_CONST(38658.858075313794/8.0), REAL_CONST(38677.555304137059/8.0), REAL_CONST(38696.254792853862/8.0), REAL_CONST(38714.956540918094/8.0), REAL_CONST(38733.660547783991/8.0), REAL_CONST(38752.366812906112/8.0), REAL_CONST(38771.075335739348/8.0), REAL_CONST(38789.78611573892/8.0), REAL_CONST(38808.499152360368/8.0), REAL_CONST(38827.214445059573/8.0), REAL_CONST(38845.931993292739/8.0), REAL_CONST(38864.651796516388/8.0), REAL_CONST(38883.373854187383/8.0), REAL_CONST(38902.098165762916/8.0), REAL_CONST(38920.824730700486/8.0), REAL_CONST(38939.553548457938/8.0), REAL_CONST(38958.284618493431/8.0), REAL_CONST(38977.017940265461/8.0), REAL_CONST(38995.753513232834/8.0), REAL_CONST(39014.491336854699/8.0), REAL_CONST(39033.231410590517/8.0), REAL_CONST(39051.973733900079/8.0), REAL_CONST(39070.718306243485/8.0), REAL_CONST(39089.465127081188/8.0), REAL_CONST(39108.214195873945/8.0), REAL_CONST(39126.965512082832/8.0), REAL_CONST(39145.719075169261/8.0), REAL_CONST(39164.474884594965/8.0), REAL_CONST(39183.232939821988/8.0), REAL_CONST(39201.99324031271/8.0), REAL_CONST(39220.755785529815/8.0), REAL_CONST(39239.52057493633/8.0), REAL_CONST(39258.287607995589/8.0), REAL_CONST(39277.056884171245/8.0), REAL_CONST(39295.828402927284/8.0), REAL_CONST(39314.602163728006/8.0), REAL_CONST(39333.378166038019/8.0), REAL_CONST(39352.15640932227/8.0), REAL_CONST(39370.936893046004/8.0), REAL_CONST(39389.719616674811/8.0), REAL_CONST(39408.504579674584/8.0), REAL_CONST(39427.291781511522/8.0), REAL_CONST(39446.081221652174/8.0), REAL_CONST(39464.872899563372/8.0), REAL_CONST(39483.666814712291/8.0), REAL_CONST(39502.462966566411/8.0), REAL_CONST(39521.261354593538/8.0), REAL_CONST(39540.06197826178/8.0), REAL_CONST(39558.864837039568/8.0), REAL_CONST(39577.669930395656/8.0), REAL_CONST(39596.47725779911/8.0), REAL_CONST(39615.286818719302/8.0), REAL_CONST(39634.098612625923/8.0), REAL_CONST(39652.912638988993/8.0), REAL_CONST(39671.728897278823/8.0), REAL_CONST(39690.547386966064/8.0), REAL_CONST(39709.368107521652/8.0), REAL_CONST(39728.191058416858/8.0), REAL_CONST(39747.016239123259/8.0), REAL_CONST(39765.84364911275/8.0), REAL_CONST(39784.673287857528/8.0), REAL_CONST(39803.505154830105/8.0), REAL_CONST(39822.339249503319/8.0), REAL_CONST(39841.175571350293/8.0), REAL_CONST(39860.014119844491/8.0), REAL_CONST(39878.854894459677/8.0), REAL_CONST(39897.697894669909/8.0), REAL_CONST(39916.54311994958/8.0), REAL_CONST(39935.390569773372/8.0), REAL_CONST(39954.240243616303/8.0), REAL_CONST(39973.092140953675/8.0), REAL_CONST(39991.946261261117/8.0), REAL_CONST(40010.802604014549/8.0), REAL_CONST(40029.661168690225/8.0), REAL_CONST(40048.521954764678/8.0), REAL_CONST(40067.384961714779/8.0), REAL_CONST(40086.250189017679/8.0), REAL_CONST(40105.117636150855/8.0), REAL_CONST(40123.98730259209/8.0), REAL_CONST(40142.859187819471/8.0), REAL_CONST(40161.733291311379/8.0), REAL_CONST(40180.609612546526/8.0), REAL_CONST(40199.488151003912/8.0), REAL_CONST(40218.368906162854/8.0), REAL_CONST(40237.25187750296/8.0), REAL_CONST(40256.137064504153/8.0), REAL_CONST(40275.024466646668/8.0), REAL_CONST(40293.914083411029/8.0), REAL_CONST(40312.805914278084/8.0), REAL_CONST(40331.699958728961/8.0), REAL_CONST(40350.596216245103/8.0), REAL_CONST(40369.494686308273/8.0), REAL_CONST(40388.39536840051/8.0), REAL_CONST(40407.298262004173/8.0), REAL_CONST(40426.20336660192/8.0), REAL_CONST(40445.110681676706/8.0), REAL_CONST(40464.020206711793/8.0), REAL_CONST(40482.931941190756/8.0), REAL_CONST(40501.845884597446/8.0), REAL_CONST(40520.762036416032/8.0), REAL_CONST(40539.680396130985/8.0), REAL_CONST(40558.600963227072/8.0), REAL_CONST(40577.523737189367/8.0), REAL_CONST(40596.448717503234/8.0), REAL_CONST(40615.375903654342/8.0), REAL_CONST(40634.305295128659/8.0), REAL_CONST(40653.236891412453/8.0), REAL_CONST(40672.170691992294/8.0), REAL_CONST(40691.106696355047/8.0), REAL_CONST(40710.044903987873/8.0), REAL_CONST(40728.985314378238/8.0), REAL_CONST(40747.927927013901/8.0), REAL_CONST(40766.872741382918/8.0), REAL_CONST(40785.819756973651/8.0), REAL_CONST(40804.768973274746/8.0), REAL_CONST(40823.720389775161/8.0), REAL_CONST(40842.674005964131/8.0), REAL_CONST(40861.629821331211/8.0), REAL_CONST(40880.587835366234/8.0), REAL_CONST(40899.548047559321/8.0), REAL_CONST(40918.510457400931/8.0), REAL_CONST(40937.475064381761/8.0), REAL_CONST(40956.441867992849/8.0), REAL_CONST(40975.410867725499/8.0), REAL_CONST(40994.382063071331/8.0), REAL_CONST(41013.355453522236/8.0), REAL_CONST(41032.331038570417/8.0), REAL_CONST(41051.308817708363/8.0), REAL_CONST(41070.288790428858/8.0), REAL_CONST(41089.270956224987/8.0), REAL_CONST(41108.255314590111/8.0), REAL_CONST(41127.241865017888/8.0), REAL_CONST(41146.23060700229/8.0), REAL_CONST(41165.221540037543/8.0), REAL_CONST(41184.214663618193/8.0), REAL_CONST(41203.209977239079/8.0), REAL_CONST(41222.207480395307/8.0), REAL_CONST(41241.207172582297/8.0), REAL_CONST(41260.209053295752/8.0), REAL_CONST(41279.213122031659/8.0), REAL_CONST(41298.219378286303/8.0), REAL_CONST(41317.227821556255/8.0), REAL_CONST(41336.23845133838/8.0), REAL_CONST(41355.251267129832/8.0), REAL_CONST(41374.266268428037/8.0), REAL_CONST(41393.283454730743/8.0), REAL_CONST(41412.302825535953/8.0), REAL_CONST(41431.324380341983/8.0), REAL_CONST(41450.348118647416/8.0), REAL_CONST(41469.374039951144/8.0), REAL_CONST(41488.402143752326/8.0), REAL_CONST(41507.432429550427/8.0), REAL_CONST(41526.464896845187/8.0), REAL_CONST(41545.499545136627/8.0), REAL_CONST(41564.536373925075/8.0), REAL_CONST(41583.575382711126/8.0), REAL_CONST(41602.616570995662/8.0), REAL_CONST(41621.659938279874/8.0), REAL_CONST(41640.705484065205/8.0), REAL_CONST(41659.753207853406/8.0), REAL_CONST(41678.803109146495/8.0), REAL_CONST(41697.855187446803/8.0), REAL_CONST(41716.909442256911/8.0), REAL_CONST(41735.965873079709/8.0), REAL_CONST(41755.02447941836/8.0), REAL_CONST(41774.085260776315/8.0), REAL_CONST(41793.148216657297/8.0), REAL_CONST(41812.213346565331/8.0), REAL_CONST(41831.280650004708/8.0), REAL_CONST(41850.350126480014/8.0), REAL_CONST(41869.421775496106/8.0), REAL_CONST(41888.495596558132/8.0), REAL_CONST(41907.571589171515/8.0), REAL_CONST(41926.649752841957/8.0), REAL_CONST(41945.730087075463/8.0), REAL_CONST(41964.812591378286/8.0), REAL_CONST(41983.897265256979/8.0), REAL_CONST(42002.984108218378/8.0), REAL_CONST(42022.073119769593/8.0), REAL_CONST(42041.164299418015/8.0), REAL_CONST(42060.257646671307/8.0), REAL_CONST(42079.353161037419/8.0), REAL_CONST(42098.450842024591/8.0), REAL_CONST(42117.550689141324/8.0), REAL_CONST(42136.652701896404/8.0), REAL_CONST(42155.756879798893/8.0), REAL_CONST(42174.863222358137/8.0), REAL_CONST(42193.971729083758/8.0), REAL_CONST(42213.082399485655/8.0), REAL_CONST(42232.195233074002/8.0), REAL_CONST(42251.310229359246/8.0), REAL_CONST(42270.427387852127/8.0), REAL_CONST(42289.546708063644/8.0), REAL_CONST(42308.668189505079/8.0), REAL_CONST(42327.791831687995/8.0), REAL_CONST(42346.917634124227/8.0), REAL_CONST(42366.045596325886/8.0), REAL_CONST(42385.175717805352/8.0), REAL_CONST(42404.307998075295/8.0), REAL_CONST(42423.442436648642/8.0), REAL_CONST(42442.579033038608/8.0), REAL_CONST(42461.717786758672/8.0), REAL_CONST(42480.858697322597/8.0), REAL_CONST(42500.001764244422/8.0), REAL_CONST(42519.146987038446/8.0), REAL_CONST(42538.294365219248/8.0), REAL_CONST(42557.443898301688/8.0), REAL_CONST(42576.595585800882/8.0), REAL_CONST(42595.749427232236/8.0), REAL_CONST(42614.90542211142/8.0), REAL_CONST(42634.063569954378/8.0), REAL_CONST(42653.223870277317/8.0), REAL_CONST(42672.386322596729/8.0), REAL_CONST(42691.55092642938/8.0), REAL_CONST(42710.717681292292/8.0), REAL_CONST(42729.886586702756/8.0), REAL_CONST(42749.057642178363/8.0), REAL_CONST(42768.23084723694/8.0), REAL_CONST(42787.406201396603/8.0), REAL_CONST(42806.58370417574/8.0), REAL_CONST(42825.76335509299/8.0), REAL_CONST(42844.945153667286/8.0), REAL_CONST(42864.129099417805/8.0), REAL_CONST(42883.315191864014/8.0), REAL_CONST(42902.503430525649/8.0), REAL_CONST(42921.693814922692/8.0), REAL_CONST(42940.88634457541/8.0), REAL_CONST(42960.081019004348/8.0), REAL_CONST(42979.277837730297/8.0), REAL_CONST(42998.476800274322/8.0), REAL_CONST(43017.677906157769/8.0), REAL_CONST(43036.881154902228/8.0), REAL_CONST(43056.086546029583/8.0), REAL_CONST(43075.294079061961/8.0), REAL_CONST(43094.503753521763/8.0), REAL_CONST(43113.715568931671/8.0), REAL_CONST(43132.929524814601/8.0), REAL_CONST(43152.145620693766/8.0), REAL_CONST(43171.363856092619/8.0), REAL_CONST(43190.584230534907/8.0), REAL_CONST(43209.806743544621/8.0), REAL_CONST(43229.031394646016/8.0), REAL_CONST(43248.258183363621/8.0), REAL_CONST(43267.487109222224/8.0), REAL_CONST(43286.718171746885/8.0), REAL_CONST(43305.951370462906/8.0), REAL_CONST(43325.186704895881/8.0), REAL_CONST(43344.42417457165/8.0), REAL_CONST(43363.663779016322/8.0), REAL_CONST(43382.905517756262/8.0), REAL_CONST(43402.149390318104/8.0), REAL_CONST(43421.395396228749/8.0), REAL_CONST(43440.643535015348/8.0), REAL_CONST(43459.89380620532/8.0), REAL_CONST(43479.146209326354/8.0), REAL_CONST(43498.400743906379/8.0), REAL_CONST(43517.657409473606/8.0), REAL_CONST(43536.916205556496/8.0), REAL_CONST(43556.177131683784/8.0), REAL_CONST(43575.44018738444/8.0), REAL_CONST(43594.705372187724/8.0), REAL_CONST(43613.972685623135/8.0), REAL_CONST(43633.242127220445/8.0), REAL_CONST(43652.513696509668/8.0), REAL_CONST(43671.787393021099/8.0), REAL_CONST(43691.063216285271/8.0), REAL_CONST(43710.341165833001/8.0), REAL_CONST(43729.621241195346/8.0), REAL_CONST(43748.903441903625/8.0), REAL_CONST(43768.187767489413/8.0), REAL_CONST(43787.474217484552/8.0), REAL_CONST(43806.762791421126/8.0), REAL_CONST(43826.053488831501/8.0), REAL_CONST(43845.346309248278/8.0), REAL_CONST(43864.641252204325/8.0), REAL_CONST(43883.938317232765/8.0), REAL_CONST(43903.237503866971/8.0), REAL_CONST(43922.538811640596/8.0), REAL_CONST(43941.842240087513/8.0), REAL_CONST(43961.147788741881/8.0), REAL_CONST(43980.455457138101/8.0), REAL_CONST(43999.765244810835/8.0), REAL_CONST(44019.077151295001/8.0), REAL_CONST(44038.391176125755/8.0), REAL_CONST(44057.70731883854/8.0), REAL_CONST(44077.02557896902/8.0), REAL_CONST(44096.345956053141/8.0), REAL_CONST(44115.668449627083/8.0), REAL_CONST(44134.993059227287/8.0), REAL_CONST(44154.319784390456/8.0), REAL_CONST(44173.648624653535/8.0), REAL_CONST(44192.979579553728/8.0), REAL_CONST(44212.312648628489/8.0), REAL_CONST(44231.647831415532/8.0), REAL_CONST(44250.985127452805/8.0), REAL_CONST(44270.324536278538/8.0), REAL_CONST(44289.666057431183/8.0), REAL_CONST(44309.009690449464/8.0), REAL_CONST(44328.355434872348/8.0), REAL_CONST(44347.703290239064/8.0), REAL_CONST(44367.053256089079/8.0), REAL_CONST(44386.405331962109/8.0), REAL_CONST(44405.759517398139/8.0), REAL_CONST(44425.115811937387/8.0), REAL_CONST(44444.474215120332/8.0), REAL_CONST(44463.834726487694/8.0), REAL_CONST(44483.197345580462/8.0), REAL_CONST(44502.562071939843/8.0), REAL_CONST(44521.928905107328/8.0), REAL_CONST(44541.297844624634/8.0), REAL_CONST(44560.668890033732/8.0), REAL_CONST(44580.042040876848/8.0), REAL_CONST(44599.417296696454/8.0), REAL_CONST(44618.794657035272/8.0), REAL_CONST(44638.174121436256/8.0), REAL_CONST(44657.555689442641/8.0), REAL_CONST(44676.939360597877/8.0), REAL_CONST(44696.325134445673/8.0), REAL_CONST(44715.713010530002/8.0), REAL_CONST(44735.102988395054/8.0), REAL_CONST(44754.495067585296/8.0), REAL_CONST(44773.88924764542/8.0), REAL_CONST(44793.285528120374/8.0), REAL_CONST(44812.683908555344/8.0), REAL_CONST(44832.084388495779/8.0), REAL_CONST(44851.486967487363/8.0), REAL_CONST(44870.891645076015/8.0), REAL_CONST(44890.298420807922/8.0), REAL_CONST(44909.707294229491/8.0), REAL_CONST(44929.118264887409/8.0), REAL_CONST(44948.531332328566/8.0), REAL_CONST(44967.946496100136/8.0), REAL_CONST(44987.363755749502/8.0), REAL_CONST(45006.783110824319/8.0), REAL_CONST(45026.204560872473/8.0), REAL_CONST(45045.628105442098/8.0), REAL_CONST(45065.053744081561/8.0), REAL_CONST(45084.48147633949/8.0), REAL_CONST(45103.911301764747/8.0), REAL_CONST(45123.343219906426/8.0), REAL_CONST(45142.777230313885/8.0), REAL_CONST(45162.21333253671/8.0), REAL_CONST(45181.651526124733/8.0), REAL_CONST(45201.091810628037/8.0), REAL_CONST(45220.534185596924/8.0), REAL_CONST(45239.978650581965/8.0), REAL_CONST(45259.425205133957/8.0), REAL_CONST(45278.873848803938/8.0), REAL_CONST(45298.324581143192/8.0), REAL_CONST(45317.777401703235/8.0), REAL_CONST(45337.232310035848/8.0), REAL_CONST(45356.68930569302/8.0), REAL_CONST(45376.148388226997/8.0), REAL_CONST(45395.60955719027/8.0), REAL_CONST(45415.072812135557/8.0), REAL_CONST(45434.538152615823/8.0), REAL_CONST(45454.005578184282/8.0), REAL_CONST(45473.475088394356/8.0), REAL_CONST(45492.946682799746/8.0), REAL_CONST(45512.420360954362/8.0), REAL_CONST(45531.896122412363/8.0), REAL_CONST(45551.373966728155/8.0), REAL_CONST(45570.853893456362/8.0), REAL_CONST(45590.33590215187/8.0), REAL_CONST(45609.819992369776/8.0), REAL_CONST(45629.306163665438/8.0), REAL_CONST(45648.794415594442/8.0), REAL_CONST(45668.284747712612/8.0), REAL_CONST(45687.777159576006/8.0), REAL_CONST(45707.27165074092/8.0), REAL_CONST(45726.768220763894/8.0), REAL_CONST(45746.266869201696/8.0), REAL_CONST(45765.767595611323/8.0), REAL_CONST(45785.270399550034/8.0), REAL_CONST(45804.775280575297/8.0), REAL_CONST(45824.282238244828/8.0), REAL_CONST(45843.79127211657/8.0), REAL_CONST(45863.302381748719/8.0), REAL_CONST(45882.815566699683/8.0), REAL_CONST(45902.33082652813/8.0), REAL_CONST(45921.848160792935/8.0), REAL_CONST(45941.367569053225/8.0), REAL_CONST(45960.889050868354/8.0), REAL_CONST(45980.41260579793/8.0), REAL_CONST(45999.938233401757/8.0), REAL_CONST(46019.465933239902/8.0), REAL_CONST(46038.995704872657/8.0), REAL_CONST(46058.527547860547/8.0), REAL_CONST(46078.06146176433/8.0), REAL_CONST(46097.597446144995/8.0), REAL_CONST(46117.135500563774/8.0), REAL_CONST(46136.675624582109/8.0), REAL_CONST(46156.217817761702/8.0), REAL_CONST(46175.762079664462/8.0), REAL_CONST(46195.308409852543/8.0), REAL_CONST(46214.856807888333/8.0), REAL_CONST(46234.407273334444/8.0), REAL_CONST(46253.959805753715/8.0), REAL_CONST(46273.51440470924/8.0), REAL_CONST(46293.071069764315/8.0), REAL_CONST(46312.629800482478/8.0), REAL_CONST(46332.190596427499/8.0), REAL_CONST(46351.753457163381/8.0), REAL_CONST(46371.318382254351/8.0), REAL_CONST(46390.885371264863/8.0), REAL_CONST(46410.45442375962/8.0), REAL_CONST(46430.025539303526/8.0), REAL_CONST(46449.598717461733/8.0), REAL_CONST(46469.17395779962/8.0), REAL_CONST(46488.751259882782/8.0), REAL_CONST(46508.33062327707/8.0), REAL_CONST(46527.912047548532/8.0), REAL_CONST(46547.495532263471/8.0), REAL_CONST(46567.081076988397/8.0), REAL_CONST(46586.668681290059/8.0), REAL_CONST(46606.258344735434/8.0), REAL_CONST(46625.850066891719/8.0), REAL_CONST(46645.443847326351/8.0), REAL_CONST(46665.039685606986/8.0), REAL_CONST(46684.637581301497/8.0), REAL_CONST(46704.237533978005/8.0), REAL_CONST(46723.839543204842/8.0), REAL_CONST(46743.443608550573/8.0), REAL_CONST(46763.049729583989/8.0), REAL_CONST(46782.657905874104/8.0), REAL_CONST(46802.268136990162/8.0), REAL_CONST(46821.880422501628/8.0), REAL_CONST(46841.494761978196/8.0), REAL_CONST(46861.111154989776/8.0), REAL_CONST(46880.729601106526/8.0), REAL_CONST(46900.350099898795/8.0), REAL_CONST(46919.97265093719/8.0), REAL_CONST(46939.597253792526/8.0), REAL_CONST(46959.223908035841/8.0), REAL_CONST(46978.852613238392/8.0), REAL_CONST(46998.483368971691/8.0), REAL_CONST(47018.11617480743/8.0), REAL_CONST(47037.751030317551/8.0), REAL_CONST(47057.387935074221/8.0), REAL_CONST(47077.026888649809/8.0), REAL_CONST(47096.66789061694/8.0), REAL_CONST(47116.310940548428/8.0), REAL_CONST(47135.956038017328/8.0), REAL_CONST(47155.603182596918/8.0), REAL_CONST(47175.252373860698/8.0), REAL_CONST(47194.903611382375/8.0), REAL_CONST(47214.556894735892/8.0), REAL_CONST(47234.212223495422/8.0), REAL_CONST(47253.869597235338/8.0), REAL_CONST(47273.52901553025/8.0), REAL_CONST(47293.19047795498/8.0), REAL_CONST(47312.853984084577/8.0), REAL_CONST(47332.519533494306/8.0), REAL_CONST(47352.187125759658/8.0), REAL_CONST(47371.856760456343/8.0), REAL_CONST(47391.528437160297/8.0), REAL_CONST(47411.202155447652/8.0), REAL_CONST(47430.877914894787/8.0), REAL_CONST(47450.555715078299/8.0), REAL_CONST(47470.235555574982/8.0), REAL_CONST(47489.917435961863/8.0), REAL_CONST(47509.601355816201/8.0), REAL_CONST(47529.287314715453/8.0), REAL_CONST(47548.975312237308/8.0), REAL_CONST(47568.665347959672/8.0), REAL_CONST(47588.357421460656/8.0), REAL_CONST(47608.051532318605/8.0), REAL_CONST(47627.747680112072/8.0), REAL_CONST(47647.445864419846/8.0), REAL_CONST(47667.14608482091/8.0), REAL_CONST(47686.848340894474/8.0), REAL_CONST(47706.552632219973/8.0), REAL_CONST(47726.258958377046/8.0), REAL_CONST(47745.967318945557/8.0), REAL_CONST(47765.677713505589/8.0), REAL_CONST(47785.390141637428/8.0), REAL_CONST(47805.104602921601/8.0), REAL_CONST(47824.821096938824/8.0), REAL_CONST(47844.539623270044/8.0), REAL_CONST(47864.260181496429/8.0), REAL_CONST(47883.982771199349/8.0), REAL_CONST(47903.707391960394/8.0), REAL_CONST(47923.434043361369/8.0), REAL_CONST(47943.162724984308/8.0), REAL_CONST(47962.893436411439/8.0), REAL_CONST(47982.626177225218/8.0), REAL_CONST(48002.36094700831/8.0), REAL_CONST(48022.097745343599/8.0), REAL_CONST(48041.836571814172/8.0), REAL_CONST(48061.57742600335/8.0), REAL_CONST(48081.32030749465/8.0), REAL_CONST(48101.065215871815/8.0), REAL_CONST(48120.81215071879/8.0), REAL_CONST(48140.56111161974/8.0), REAL_CONST(48160.312098159047/8.0), REAL_CONST(48180.065109921306/8.0), REAL_CONST(48199.820146491307/8.0), REAL_CONST(48219.577207454073/8.0), REAL_CONST(48239.336292394844/8.0), REAL_CONST(48259.097400899045/8.0), REAL_CONST(48278.860532552339/8.0), REAL_CONST(48298.625686940592/8.0), REAL_CONST(48318.392863649875/8.0), REAL_CONST(48338.162062266485/8.0), REAL_CONST(48357.933282376915/8.0), REAL_CONST(48377.706523567889/8.0), REAL_CONST(48397.481785426316/8.0), REAL_CONST(48417.259067539344/8.0), REAL_CONST(48437.038369494308/8.0), REAL_CONST(48456.819690878765/8.0), REAL_CONST(48476.603031280487/8.0), REAL_CONST(48496.388390287451/8.0), REAL_CONST(48516.175767487839/8.0), REAL_CONST(48535.965162470042/8.0), REAL_CONST(48555.756574822684/8.0), REAL_CONST(48575.550004134566/8.0), REAL_CONST(48595.345449994718/8.0), REAL_CONST(48615.142911992378/8.0), REAL_CONST(48634.942389716991/8.0), REAL_CONST(48654.743882758201/8.0), REAL_CONST(48674.547390705877/8.0), REAL_CONST(48694.352913150084/8.0), REAL_CONST(48714.160449681112/8.0), REAL_CONST(48733.969999889443/8.0), REAL_CONST(48753.781563365759/8.0), REAL_CONST(48773.595139700978/8.0), REAL_CONST(48793.410728486211/8.0), REAL_CONST(48813.228329312769/8.0), REAL_CONST(48833.047941772187/8.0), REAL_CONST(48852.869565456189/8.0), REAL_CONST(48872.693199956717/8.0), REAL_CONST(48892.518844865925/8.0), REAL_CONST(48912.346499776155/8.0), REAL_CONST(48932.176164279976/8.0), REAL_CONST(48952.007837970152/8.0), REAL_CONST(48971.841520439666/8.0), REAL_CONST(48991.677211281676/8.0), REAL_CONST(49011.514910089587/8.0), REAL_CONST(49031.354616456978/8.0), REAL_CONST(49051.196329977654/8.0), REAL_CONST(49071.04005024561/8.0), REAL_CONST(49090.885776855059/8.0), REAL_CONST(49110.733509400408/8.0), REAL_CONST(49130.583247476279/8.0), REAL_CONST(49150.434990677488/8.0), REAL_CONST(49170.288738599062/8.0), REAL_CONST(49190.144490836232/8.0), REAL_CONST(49210.002246984441/8.0), REAL_CONST(49229.86200663932/8.0), REAL_CONST(49249.723769396718/8.0), REAL_CONST(49269.587534852675/8.0), REAL_CONST(49289.453302603448/8.0), REAL_CONST(49309.32107224549/8.0), REAL_CONST(49329.190843375451/8.0), REAL_CONST(49349.062615590192/8.0), REAL_CONST(49368.936388486785/8.0), REAL_CONST(49388.812161662492/8.0), REAL_CONST(49408.689934714785/8.0), REAL_CONST(49428.569707241324/8.0), REAL_CONST(49448.45147883999/8.0), REAL_CONST(49468.335249108866/8.0), REAL_CONST(49488.22101764621/8.0), REAL_CONST(49508.108784050521/8.0), REAL_CONST(49527.99854792047/8.0), REAL_CONST(49547.890308854934/8.0), REAL_CONST(49567.784066453009/8.0), REAL_CONST(49587.679820313977/8.0), REAL_CONST(49607.57757003732/8.0), REAL_CONST(49627.477315222721/8.0), REAL_CONST(49647.379055470075/8.0), REAL_CONST(49667.28279037946/8.0), REAL_CONST(49687.188519551179/8.0), REAL_CONST(49707.096242585707/8.0), REAL_CONST(49727.005959083741/8.0), REAL_CONST(49746.917668646165/8.0), REAL_CONST(49766.831370874068/8.0), REAL_CONST(49786.747065368734/8.0), REAL_CONST(49806.66475173166/8.0), REAL_CONST(49826.584429564515/8.0), REAL_CONST(49846.506098469203/8.0), REAL_CONST(49866.429758047794/8.0), REAL_CONST(49886.355407902578/8.0), REAL_CONST(49906.283047636032/8.0), REAL_CONST(49926.212676850846/8.0), REAL_CONST(49946.144295149883/8.0), REAL_CONST(49966.077902136225/8.0), REAL_CONST(49986.013497413151/8.0), REAL_CONST(50005.951080584135/8.0), REAL_CONST(50025.890651252834/8.0), REAL_CONST(50045.832209023123/8.0), REAL_CONST(50065.775753499074/8.0), REAL_CONST(50085.721284284933/8.0), REAL_CONST(50105.668800985164/8.0), REAL_CONST(50125.618303204428/8.0), REAL_CONST(50145.569790547575/8.0), REAL_CONST(50165.523262619652/8.0), REAL_CONST(50185.478719025901/8.0), REAL_CONST(50205.436159371769/8.0), REAL_CONST(50225.395583262893/8.0), REAL_CONST(50245.356990305103/8.0), REAL_CONST(50265.320380104429/8.0), REAL_CONST(50285.285752267104/8.0), REAL_CONST(50305.253106399534/8.0), REAL_CONST(50325.222442108337/8.0), REAL_CONST(50345.193759000336/8.0), REAL_CONST(50365.16705668252/8.0), REAL_CONST(50385.142334762102/8.0), REAL_CONST(50405.119592846473/8.0), REAL_CONST(50425.098830543218/8.0), REAL_CONST(50445.080047460127/8.0), REAL_CONST(50465.063243205179/8.0), REAL_CONST(50485.048417386541/8.0), REAL_CONST(50505.035569612577/8.0), REAL_CONST(50525.024699491856/8.0), REAL_CONST(50545.015806633128/8.0), REAL_CONST(50565.008890645338/8.0), REAL_CONST(50585.003951137631/8.0), REAL_CONST(50605.00098771933/8.0), REAL_CONST(50624.999999999971/8.0), REAL_CONST(50645.000987589265/8.0), REAL_CONST(50665.003950097132/8.0), REAL_CONST(50685.008887133677/8.0), REAL_CONST(50705.015798309192/8.0), REAL_CONST(50725.024683234165/8.0), REAL_CONST(50745.035541519283/8.0), REAL_CONST(50765.048372775411/8.0), REAL_CONST(50785.063176613621/8.0), REAL_CONST(50805.079952645159/8.0), REAL_CONST(50825.098700481489/8.0), REAL_CONST(50845.119419734241/8.0), REAL_CONST(50865.142110015244/8.0), REAL_CONST(50885.166770936521/8.0), REAL_CONST(50905.193402110279/8.0), REAL_CONST(50925.222003148934/8.0), REAL_CONST(50945.252573665071/8.0), REAL_CONST(50965.285113271471/8.0), REAL_CONST(50985.319621581119/8.0), REAL_CONST(51005.356098207172/8.0), REAL_CONST(51025.394542762981/8.0), REAL_CONST(51045.434954862096/8.0), REAL_CONST(51065.477334118244/8.0), REAL_CONST(51085.521680145357/8.0), REAL_CONST(51105.567992557546/8.0), REAL_CONST(51125.616270969113/8.0), REAL_CONST(51145.66651499454/8.0), REAL_CONST(51165.718724248516/8.0), REAL_CONST(51185.772898345916/8.0), REAL_CONST(51205.829036901778/8.0), REAL_CONST(51225.887139531362/8.0), REAL_CONST(51245.947205850105/8.0), REAL_CONST(51266.009235473619/8.0), REAL_CONST(51286.073228017718/8.0), REAL_CONST(51306.139183098399/8.0), REAL_CONST(51326.207100331856/8.0), REAL_CONST(51346.276979334456/8.0), REAL_CONST(51366.348819722756/8.0), REAL_CONST(51386.42262111351/8.0), REAL_CONST(51406.498383123653/8.0), REAL_CONST(51426.57610537031/8.0), REAL_CONST(51446.655787470787/8.0), REAL_CONST(51466.737429042587/8.0), REAL_CONST(51486.82102970338/8.0), REAL_CONST(51506.906589071048/8.0), REAL_CONST(51526.994106763632/8.0), REAL_CONST(51547.083582399391/8.0), REAL_CONST(51567.175015596738/8.0), REAL_CONST(51587.268405974297/8.0), REAL_CONST(51607.363753150858/8.0), REAL_CONST(51627.461056745415/8.0), REAL_CONST(51647.56031637713/8.0), REAL_CONST(51667.661531665362/8.0), REAL_CONST(51687.764702229651/8.0), REAL_CONST(51707.869827689727/8.0), REAL_CONST(51727.976907665499/8.0), REAL_CONST(51748.085941777055/8.0), REAL_CONST(51768.196929644677/8.0), REAL_CONST(51788.309870888836/8.0), REAL_CONST(51808.42476513017/8.0), REAL_CONST(51828.541611989524/8.0), REAL_CONST(51848.660411087905/8.0), REAL_CONST(51868.781162046515/8.0), REAL_CONST(51888.90386448674/8.0), REAL_CONST(51909.028518030143/8.0), REAL_CONST(51929.155122298485/8.0), REAL_CONST(51949.283676913685/8.0), REAL_CONST(51969.414181497872/8.0), REAL_CONST(51989.546635673345/8.0), REAL_CONST(52009.681039062583/8.0), REAL_CONST(52029.817391288263/8.0), REAL_CONST(52049.955691973213/8.0), REAL_CONST(52070.095940740481/8.0), REAL_CONST(52090.238137213273/8.0), REAL_CONST(52110.382281014987/8.0), REAL_CONST(52130.5283717692/8.0), REAL_CONST(52150.676409099666/8.0), REAL_CONST(52170.826392630333/8.0), REAL_CONST(52190.97832198532/8.0), REAL_CONST(52211.132196788931/8.0), REAL_CONST(52231.288016665654/8.0), REAL_CONST(52251.445781240145/8.0), REAL_CONST(52271.60549013727/8.0), REAL_CONST(52291.76714298204/8.0), REAL_CONST(52311.930739399664/8.0), REAL_CONST(52332.096279015546/8.0), REAL_CONST(52352.263761455244/8.0), REAL_CONST(52372.433186344519/8.0), REAL_CONST(52392.604553309284/8.0), REAL_CONST(52412.777861975665/8.0), REAL_CONST(52432.953111969946/8.0), REAL_CONST(52453.130302918595/8.0), REAL_CONST(52473.309434448267/8.0), REAL_CONST(52493.490506185793/8.0), REAL_CONST(52513.67351775818/8.0), REAL_CONST(52533.858468792605/8.0), REAL_CONST(52554.045358916446/8.0), REAL_CONST(52574.234187757254/8.0), REAL_CONST(52594.42495494274/8.0), REAL_CONST(52614.617660100812/8.0), REAL_CONST(52634.812302859558/8.0), REAL_CONST(52655.008882847229/8.0), REAL_CONST(52675.20739969227/8.0), REAL_CONST(52695.407853023295/8.0), REAL_CONST(52715.610242469098/8.0), REAL_CONST(52735.814567658657/8.0), REAL_CONST(52756.02082822111/8.0), REAL_CONST(52776.229023785803/8.0), REAL_CONST(52796.439153982225/8.0), REAL_CONST(52816.651218440056/8.0), REAL_CONST(52836.865216789171/8.0), REAL_CONST(52857.081148659599/8.0), REAL_CONST(52877.29901368155/8.0), REAL_CONST(52897.518811485425/8.0), REAL_CONST(52917.740541701773/8.0), REAL_CONST(52937.964203961354/8.0), REAL_CONST(52958.18979789508/8.0), REAL_CONST(52978.417323134046/8.0), REAL_CONST(52998.646779309529/8.0), REAL_CONST(53018.878166052978/8.0), REAL_CONST(53039.111482996006/8.0), REAL_CONST(53059.346729770419/8.0), REAL_CONST(53079.583906008193/8.0), REAL_CONST(53099.823011341483/8.0), REAL_CONST(53120.0640454026/8.0), REAL_CONST(53140.307007824063/8.0), REAL_CONST(53160.551898238533/8.0), REAL_CONST(53180.79871627887/8.0), REAL_CONST(53201.047461578091/8.0), REAL_CONST(53221.2981337694/8.0), REAL_CONST(53241.550732486176/8.0), REAL_CONST(53261.805257361964/8.0), REAL_CONST(53282.061708030487/8.0), REAL_CONST(53302.32008412564/8.0), REAL_CONST(53322.580385281493/8.0), REAL_CONST(53342.842611132299/8.0), REAL_CONST(53363.106761312469/8.0), REAL_CONST(53383.372835456597/8.0), REAL_CONST(53403.640833199453/8.0), REAL_CONST(53423.910754175973/8.0), REAL_CONST(53444.18259802126/8.0), REAL_CONST(53464.456364370613/8.0), REAL_CONST(53484.732052859479/8.0), REAL_CONST(53505.009663123499/8.0), REAL_CONST(53525.289194798468/8.0), REAL_CONST(53545.570647520362/8.0), REAL_CONST(53565.854020925333/8.0), REAL_CONST(53586.139314649699/8.0), REAL_CONST(53606.426528329954/8.0), REAL_CONST(53626.715661602764/8.0), REAL_CONST(53647.006714104959/8.0), REAL_CONST(53667.299685473547/8.0), REAL_CONST(53687.59457534572/8.0), REAL_CONST(53707.891383358816/8.0), REAL_CONST(53728.190109150361/8.0), REAL_CONST(53748.490752358055/8.0), REAL_CONST(53768.793312619753/8.0), REAL_CONST(53789.09778957349/8.0), REAL_CONST(53809.404182857485/8.0), REAL_CONST(53829.712492110106/8.0), REAL_CONST(53850.022716969899/8.0), REAL_CONST(53870.334857075584/8.0), REAL_CONST(53890.648912066055/8.0), REAL_CONST(53910.964881580367/8.0), REAL_CONST(53931.28276525774/8.0), REAL_CONST(53951.602562737586/8.0), REAL_CONST(53971.924273659461/8.0), REAL_CONST(53992.24789766311/8.0), REAL_CONST(54012.57343438844/8.0), REAL_CONST(54032.90088347553/8.0), REAL_CONST(54053.23024456462/8.0), REAL_CONST(54073.561517296133/8.0), REAL_CONST(54093.894701310644/8.0), REAL_CONST(54114.22979624891/8.0), REAL_CONST(54134.566801751855/8.0), REAL_CONST(54154.90571746057/8.0), REAL_CONST(54175.246543016314/8.0), REAL_CONST(54195.589278060506/8.0), REAL_CONST(54215.933922234755/8.0), REAL_CONST(54236.280475180814/8.0), REAL_CONST(54256.628936540626/8.0), REAL_CONST(54276.97930595628/8.0), REAL_CONST(54297.331583070045/8.0), REAL_CONST(54317.685767524359/8.0), REAL_CONST(54338.041858961828/8.0), REAL_CONST(54358.399857025215/8.0), REAL_CONST(54378.759761357462/8.0), REAL_CONST(54399.121571601667/8.0), REAL_CONST(54419.485287401105/8.0), REAL_CONST(54439.850908399218/8.0), REAL_CONST(54460.218434239614/8.0), REAL_CONST(54480.587864566056/8.0), REAL_CONST(54500.95919902248/8.0), REAL_CONST(54521.332437252997/8.0), REAL_CONST(54541.707578901878/8.0), REAL_CONST(54562.084623613555/8.0), REAL_CONST(54582.46357103264/8.0), REAL_CONST(54602.844420803893/8.0), REAL_CONST(54623.227172572246/8.0), REAL_CONST(54643.611825982807/8.0), REAL_CONST(54663.998380680838/8.0), REAL_CONST(54684.386836311773/8.0), REAL_CONST(54704.777192521207/8.0), REAL_CONST(54725.169448954897/8.0), REAL_CONST(54745.563605258772/8.0), REAL_CONST(54765.959661078923/8.0), REAL_CONST(54786.357616061614/8.0), REAL_CONST(54806.757469853255/8.0), REAL_CONST(54827.159222100439/8.0), REAL_CONST(54847.562872449904/8.0), REAL_CONST(54867.968420548583/8.0), REAL_CONST(54888.375866043534/8.0), REAL_CONST(54908.785208582012/8.0), REAL_CONST(54929.196447811417/8.0), REAL_CONST(54949.609583379322/8.0), REAL_CONST(54970.024614933463/8.0), REAL_CONST(54990.441542121727/8.0), REAL_CONST(55010.86036459219/8.0), REAL_CONST(55031.28108199306/8.0), REAL_CONST(55051.703693972733/8.0), REAL_CONST(55072.128200179759/8.0), REAL_CONST(55092.554600262847/8.0), REAL_CONST(55112.982893870874/8.0), REAL_CONST(55133.413080652877/8.0), REAL_CONST(55153.845160258061/8.0), REAL_CONST(55174.279132335789/8.0), REAL_CONST(55194.714996535586/8.0), REAL_CONST(55215.152752507143/8.0), REAL_CONST(55235.592399900306/8.0), REAL_CONST(55256.033938365079/8.0), REAL_CONST(55276.477367551655/8.0), REAL_CONST(55296.92268711036/8.0), REAL_CONST(55317.369896691685/8.0), REAL_CONST(55337.818995946305/8.0), REAL_CONST(55358.269984525024/8.0), REAL_CONST(55378.72286207883/8.0), REAL_CONST(55399.177628258869/8.0), REAL_CONST(55419.634282716441/8.0), REAL_CONST(55440.092825103013/8.0), REAL_CONST(55460.553255070205/8.0), REAL_CONST(55481.015572269804/8.0), REAL_CONST(55501.479776353764/8.0), REAL_CONST(55521.945866974187/8.0), REAL_CONST(55542.413843783339/8.0), REAL_CONST(55562.883706433655/8.0), REAL_CONST(55583.355454577715/8.0), REAL_CONST(55603.82908786826/8.0), REAL_CONST(55624.304605958219/8.0), REAL_CONST(55644.782008500639/8.0), REAL_CONST(55665.261295148754/8.0), REAL_CONST(55685.742465555952/8.0), REAL_CONST(55706.225519375774/8.0), REAL_CONST(55726.710456261928/8.0), REAL_CONST(55747.197275868275/8.0), REAL_CONST(55767.685977848843/8.0), REAL_CONST(55788.176561857814/8.0), REAL_CONST(55808.669027549528/8.0), REAL_CONST(55829.163374578478/8.0), REAL_CONST(55849.659602599328/8.0), REAL_CONST(55870.157711266889/8.0), REAL_CONST(55890.657700236145/8.0), REAL_CONST(55911.159569162221/8.0), REAL_CONST(55931.663317700411/8.0), REAL_CONST(55952.168945506164/8.0), REAL_CONST(55972.676452235086/8.0), REAL_CONST(55993.185837542944/8.0), REAL_CONST(56013.697101085651/8.0), REAL_CONST(56034.210242519301/8.0), REAL_CONST(56054.72526150012/8.0), REAL_CONST(56075.242157684508/8.0), REAL_CONST(56095.760930729011/8.0), REAL_CONST(56116.281580290342/8.0), REAL_CONST(56136.804106025367/8.0), REAL_CONST(56157.328507591104/8.0), REAL_CONST(56177.85478464474/8.0), REAL_CONST(56198.382936843598/8.0), REAL_CONST(56218.912963845185/8.0), REAL_CONST(56239.444865307138/8.0), REAL_CONST(56259.978640887268/8.0), REAL_CONST(56280.514290243525/8.0), REAL_CONST(56301.051813034042/8.0), REAL_CONST(56321.591208917082/8.0), REAL_CONST(56342.13247755108/8.0), REAL_CONST(56362.675618594607/8.0), REAL_CONST(56383.220631706419/8.0), REAL_CONST(56403.767516545398/8.0), REAL_CONST(56424.316272770608/8.0), REAL_CONST(56444.866900041241/8.0), REAL_CONST(56465.419398016667/8.0), REAL_CONST(56485.973766356394/8.0), REAL_CONST(56506.530004720102/8.0), REAL_CONST(56527.088112767611/8.0), REAL_CONST(56547.648090158902/8.0), REAL_CONST(56568.209936554107/8.0), REAL_CONST(56588.773651613519/8.0), REAL_CONST(56609.339234997584/8.0), REAL_CONST(56629.9066863669/8.0), REAL_CONST(56650.47600538221/8.0), REAL_CONST(56671.04719170442/8.0), REAL_CONST(56691.620244994599/8.0), REAL_CONST(56712.195164913959/8.0), REAL_CONST(56732.771951123868/8.0), REAL_CONST(56753.350603285835/8.0), REAL_CONST(56773.931121061541/8.0), REAL_CONST(56794.513504112823/8.0), REAL_CONST(56815.097752101647/8.0), REAL_CONST(56835.683864690152/8.0), REAL_CONST(56856.271841540627/8.0), REAL_CONST(56876.86168231551/8.0), REAL_CONST(56897.453386677393/8.0), REAL_CONST(56918.046954289028/8.0), REAL_CONST(56938.642384813298/8.0), REAL_CONST(56959.239677913261/8.0), REAL_CONST(56979.838833252121/8.0), REAL_CONST(57000.439850493225/8.0), REAL_CONST(57021.04272930009/8.0), REAL_CONST(57041.647469336371/8.0), REAL_CONST(57062.254070265873/8.0), REAL_CONST(57082.862531752558/8.0), REAL_CONST(57103.472853460553/8.0), REAL_CONST(57124.085035054108/8.0), REAL_CONST(57144.699076197649/8.0), REAL_CONST(57165.314976555739/8.0), REAL_CONST(57185.932735793103/8.0), REAL_CONST(57206.552353574611/8.0), REAL_CONST(57227.173829565276/8.0), REAL_CONST(57247.797163430281/8.0), REAL_CONST(57268.42235483494/8.0), REAL_CONST(57289.049403444733/8.0), REAL_CONST(57309.678308925286/8.0), REAL_CONST(57330.30907094237/8.0), REAL_CONST(57350.941689161911/8.0), REAL_CONST(57371.576163249985/8.0), REAL_CONST(57392.212492872815/8.0), REAL_CONST(57412.850677696784/8.0), REAL_CONST(57433.490717388406/8.0), REAL_CONST(57454.132611614368/8.0), REAL_CONST(57474.776360041491/8.0), REAL_CONST(57495.421962336746/8.0), REAL_CONST(57516.069418167266/8.0), REAL_CONST(57536.718727200314/8.0), REAL_CONST(57557.36988910332/8.0), REAL_CONST(57578.022903543861/8.0), REAL_CONST(57598.677770189643/8.0), REAL_CONST(57619.334488708548/8.0), REAL_CONST(57639.993058768589/8.0), REAL_CONST(57660.653480037938/8.0), REAL_CONST(57681.315752184906/8.0), REAL_CONST(57701.979874877965/8.0), REAL_CONST(57722.64584778573/8.0), REAL_CONST(57743.31367057695/8.0), REAL_CONST(57763.983342920546/8.0), REAL_CONST(57784.654864485572/8.0), REAL_CONST(57805.328234941233/8.0), REAL_CONST(57826.003453956881/8.0), REAL_CONST(57846.680521202026/8.0), REAL_CONST(57867.359436346305/8.0), REAL_CONST(57888.040199059527/8.0), REAL_CONST(57908.722809011633/8.0), REAL_CONST(57929.407265872709/8.0), REAL_CONST(57950.093569313001/8.0), REAL_CONST(57970.781719002895/8.0), REAL_CONST(57991.471714612911/8.0), REAL_CONST(58012.16355581375/8.0), REAL_CONST(58032.857242276223/8.0), REAL_CONST(58053.552773671312/8.0), REAL_CONST(58074.25014967013/8.0), REAL_CONST(58094.949369943948/8.0), REAL_CONST(58115.650434164185/8.0), REAL_CONST(58136.353342002389/8.0), REAL_CONST(58157.058093130276/8.0), REAL_CONST(58177.764687219693/8.0), REAL_CONST(58198.47312394264/8.0), REAL_CONST(58219.183402971255/8.0), REAL_CONST(58239.895523977837/8.0), REAL_CONST(58260.609486634821/8.0), REAL_CONST(58281.325290614775/8.0), REAL_CONST(58302.042935590434/8.0), REAL_CONST(58322.762421234678/8.0), REAL_CONST(58343.483747220511/8.0), REAL_CONST(58364.206913221096/8.0), REAL_CONST(58384.931918909751/8.0), REAL_CONST(58405.658763959924/8.0), REAL_CONST(58426.3874480452/8.0), REAL_CONST(58447.117970839339/8.0), REAL_CONST(58467.85033201622/8.0), REAL_CONST(58488.584531249864/8.0), REAL_CONST(58509.320568214462/8.0), REAL_CONST(58530.058442584334/8.0), REAL_CONST(58550.798154033931/8.0), REAL_CONST(58571.539702237875/8.0), REAL_CONST(58592.283086870906/8.0), REAL_CONST(58613.028307607929/8.0), REAL_CONST(58633.775364123983/8.0), REAL_CONST(58654.52425609425/8.0), REAL_CONST(58675.274983194053/8.0), REAL_CONST(58696.027545098877/8.0), REAL_CONST(58716.781941484325/8.0), REAL_CONST(58737.538172026158/8.0), REAL_CONST(58758.296236400274/8.0), REAL_CONST(58779.056134282728/8.0), REAL_CONST(58799.817865349694/8.0), REAL_CONST(58820.581429277503/8.0), REAL_CONST(58841.346825742643/8.0), REAL_CONST(58862.114054421712/8.0), REAL_CONST(58882.883114991484/8.0), REAL_CONST(58903.654007128847/8.0), REAL_CONST(58924.426730510851/8.0), REAL_CONST(58945.201284814684/8.0), REAL_CONST(58965.977669717664/8.0), REAL_CONST(58986.755884897269/8.0), REAL_CONST(59007.535930031117/8.0), REAL_CONST(59028.317804796949/8.0), REAL_CONST(59049.101508872664/8.0), REAL_CONST(59069.887041936301/8.0), REAL_CONST(59090.674403666046/8.0), REAL_CONST(59111.463593740213/8.0), REAL_CONST(59132.254611837263/8.0), REAL_CONST(59153.047457635803/8.0), REAL_CONST(59173.84213081457/8.0), REAL_CONST(59194.638631052461/8.0), REAL_CONST(59215.436958028506/8.0), REAL_CONST(59236.237111421855/8.0), REAL_CONST(59257.039090911829/8.0), REAL_CONST(59277.842896177877/8.0), REAL_CONST(59298.648526899589/8.0), REAL_CONST(59319.455982756685/8.0), REAL_CONST(59340.26526342905/8.0), REAL_CONST(59361.076368596696/8.0), REAL_CONST(59381.889297939757/8.0), REAL_CONST(59402.704051138542/8.0), REAL_CONST(59423.520627873484/8.0), REAL_CONST(59444.339027825139/8.0), REAL_CONST(59465.159250674224/8.0), REAL_CONST(59485.9812961016/8.0), REAL_CONST(59506.805163788253/8.0), REAL_CONST(59527.630853415307/8.0), REAL_CONST(59548.458364664046/8.0), REAL_CONST(59569.287697215863/8.0), REAL_CONST(59590.118850752311/8.0), REAL_CONST(59610.951824955089/8.0), REAL_CONST(59631.786619506012/8.0), REAL_CONST(59652.623234087048/8.0), REAL_CONST(59673.461668380311/8.0), REAL_CONST(59694.301922068029/8.0), REAL_CONST(59715.143994832593/8.0), REAL_CONST(59735.987886356525/8.0), REAL_CONST(59756.833596322482/8.0), REAL_CONST(59777.681124413255/8.0), REAL_CONST(59798.530470311794/8.0), REAL_CONST(59819.381633701159/8.0), REAL_CONST(59840.234614264569/8.0), REAL_CONST(59861.089411685381/8.0), REAL_CONST(59881.94602564707/8.0), REAL_CONST(59902.804455833269/8.0), REAL_CONST(59923.664701927737/8.0), REAL_CONST(59944.526763614384/8.0), REAL_CONST(59965.390640577243/8.0), REAL_CONST(59986.256332500488/8.0), REAL_CONST(60007.123839068438/8.0), REAL_CONST(60027.993159965539/8.0), REAL_CONST(60048.864294876381/8.0), REAL_CONST(60069.737243485688/8.0), REAL_CONST(60090.612005478324/8.0), REAL_CONST(60111.488580539284/8.0), REAL_CONST(60132.366968353708/8.0), REAL_CONST(60153.247168606867/8.0), REAL_CONST(60174.129180984164/8.0), REAL_CONST(60195.013005171153/8.0), REAL_CONST(60215.898640853513/8.0), REAL_CONST(60236.786087717061/8.0), REAL_CONST(60257.675345447751/8.0), REAL_CONST(60278.566413731671/8.0), REAL_CONST(60299.459292255044/8.0), REAL_CONST(60320.353980704247/8.0), REAL_CONST(60341.25047876576/8.0), REAL_CONST(60362.148786126229/8.0), REAL_CONST(60383.048902472423/8.0), REAL_CONST(60403.950827491237/8.0), REAL_CONST(60424.854560869717/8.0), REAL_CONST(60445.76010229504/8.0), REAL_CONST(60466.667451454516/8.0), REAL_CONST(60487.57660803559/8.0), REAL_CONST(60508.487571725847/8.0), REAL_CONST(60529.400342212997/8.0), REAL_CONST(60550.314919184893/8.0), REAL_CONST(60571.231302329521/8.0), REAL_CONST(60592.149491335003/8.0), REAL_CONST(60613.069485889588/8.0), REAL_CONST(60633.991285681674/8.0), REAL_CONST(60654.914890399785/8.0), REAL_CONST(60675.840299732568/8.0), REAL_CONST(60696.767513368832/8.0), REAL_CONST(60717.696530997484/8.0), REAL_CONST(60738.627352307602/8.0), REAL_CONST(60759.55997698837/8.0), REAL_CONST(60780.494404729128/8.0), REAL_CONST(60801.430635219323/8.0), REAL_CONST(60822.368668148556/8.0), REAL_CONST(60843.308503206565/8.0), REAL_CONST(60864.250140083204/8.0), REAL_CONST(60885.193578468468/8.0), REAL_CONST(60906.138818052495/8.0), REAL_CONST(60927.085858525541/8.0), REAL_CONST(60948.034699578006/8.0), REAL_CONST(60968.985340900421/8.0), REAL_CONST(60989.937782183442/8.0), REAL_CONST(61010.892023117864/8.0), REAL_CONST(61031.848063394616/8.0), REAL_CONST(61052.805902704764/8.0), REAL_CONST(61073.765540739492/8.0), REAL_CONST(61094.726977190134/8.0), REAL_CONST(61115.690211748137/8.0), REAL_CONST(61136.655244105103/8.0), REAL_CONST(61157.622073952742/8.0), REAL_CONST(61178.590700982917/8.0), REAL_CONST(61199.561124887616/8.0), REAL_CONST(61220.533345358948/8.0), REAL_CONST(61241.507362089171/8.0), REAL_CONST(61262.483174770663/8.0), REAL_CONST(61283.460783095943/8.0), REAL_CONST(61304.440186757645/8.0), REAL_CONST(61325.421385448557/8.0), REAL_CONST(61346.404378861582/8.0), REAL_CONST(61367.389166689762/8.0), REAL_CONST(61388.375748626262/8.0), REAL_CONST(61409.364124364387/8.0), REAL_CONST(61430.354293597571/8.0), REAL_CONST(61451.346256019373/8.0), REAL_CONST(61472.340011323497/8.0), REAL_CONST(61493.335559203762/8.0), REAL_CONST(61514.332899354122/8.0), REAL_CONST(61535.332031468672/8.0), REAL_CONST(61556.332955241618/8.0), REAL_CONST(61577.335670367313/8.0), REAL_CONST(61598.340176540238/8.0), REAL_CONST(61619.346473454993/8.0), REAL_CONST(61640.354560806329/8.0), REAL_CONST(61661.3644382891/8.0), REAL_CONST(61682.376105598312/8.0), REAL_CONST(61703.389562429089/8.0), REAL_CONST(61724.404808476691/8.0), REAL_CONST(61745.42184343651/8.0), REAL_CONST(61766.440667004063/8.0), REAL_CONST(61787.461278874987/8.0), REAL_CONST(61808.483678745069/8.0), REAL_CONST(61829.507866310203/8.0), REAL_CONST(61850.533841266435/8.0), REAL_CONST(61871.561603309929/8.0), REAL_CONST(61892.591152136971/8.0), REAL_CONST(61913.622487443987/8.0), REAL_CONST(61934.655608927525/8.0), REAL_CONST(61955.690516284267/8.0), REAL_CONST(61976.727209211022/8.0), REAL_CONST(61997.765687404724/8.0), REAL_CONST(62018.805950562448/8.0), REAL_CONST(62039.847998381381/8.0), REAL_CONST(62060.891830558845/8.0), REAL_CONST(62081.93744679229/8.0), REAL_CONST(62102.984846779298/8.0), REAL_CONST(62124.034030217575/8.0), REAL_CONST(62145.084996804966/8.0), REAL_CONST(62166.137746239416/8.0), REAL_CONST(62187.19227821903/8.0), REAL_CONST(62208.248592442025/8.0), REAL_CONST(62229.306688606739/8.0), REAL_CONST(62250.366566411656/8.0), REAL_CONST(62271.428225555377/8.0), REAL_CONST(62292.491665736627/8.0), REAL_CONST(62313.556886654267/8.0), REAL_CONST(62334.623888007271/8.0), REAL_CONST(62355.692669494762/8.0), REAL_CONST(62376.763230815974/8.0), REAL_CONST(62397.835571670272/8.0), REAL_CONST(62418.909691757144/8.0), REAL_CONST(62439.98559077621/8.0), REAL_CONST(62461.063268427228/8.0), REAL_CONST(62482.142724410049/8.0), REAL_CONST(62503.223958424685/8.0), REAL_CONST(62524.306970171267/8.0), REAL_CONST(62545.39175935003/8.0), REAL_CONST(62566.478325661366/8.0), REAL_CONST(62587.566668805768/8.0), REAL_CONST(62608.656788483881/8.0), REAL_CONST(62629.748684396451/8.0), REAL_CONST(62650.842356244357/8.0), REAL_CONST(62671.937803728622/8.0), REAL_CONST(62693.035026550366/8.0), REAL_CONST(62714.134024410858/8.0), REAL_CONST(62735.234797011479/8.0), REAL_CONST(62756.337344053733/8.0), REAL_CONST(62777.441665239276/8.0), REAL_CONST(62798.547760269852/8.0), REAL_CONST(62819.655628847358/8.0), REAL_CONST(62840.765270673801/8.0), REAL_CONST(62861.876685451323/8.0), REAL_CONST(62882.989872882186/8.0), REAL_CONST(62904.104832668774/8.0), REAL_CONST(62925.221564513602/8.0), REAL_CONST(62946.340068119309/8.0), REAL_CONST(62967.460343188657/8.0), REAL_CONST(62988.582389424526/8.0), REAL_CONST(63009.70620652994/8.0), REAL_CONST(63030.831794208025/8.0), REAL_CONST(63051.959152162039/8.0), REAL_CONST(63073.08828009537/8.0), REAL_CONST(63094.219177711529/8.0), REAL_CONST(63115.351844714154/8.0), REAL_CONST(63136.486280806988/8.0), REAL_CONST(63157.622485693922/8.0), REAL_CONST(63178.760459078956/8.0), REAL_CONST(63199.900200666219/8.0), REAL_CONST(63221.041710159967/8.0), REAL_CONST(63242.184987264569/8.0), REAL_CONST(63263.330031684534/8.0), REAL_CONST(63284.476843124474/8.0), REAL_CONST(63305.625421289144/8.0), REAL_CONST(63326.775765883409/8.0), REAL_CONST(63347.927876612259/8.0), REAL_CONST(63369.081753180813/8.0), REAL_CONST(63390.237395294316/8.0), REAL_CONST(63411.39480265812/8.0), REAL_CONST(63432.553974977716/8.0), REAL_CONST(63453.714911958712/8.0), REAL_CONST(63474.877613306839/8.0), REAL_CONST(63496.042078727944/8.0), REAL_CONST(63517.208307927998/8.0), REAL_CONST(63538.376300613119/8.0), REAL_CONST(63559.546056489504/8.0), REAL_CONST(63580.717575263516/8.0), REAL_CONST(63601.890856641607/8.0), REAL_CONST(63623.065900330374/8.0), REAL_CONST(63644.242706036515/8.0), REAL_CONST(63665.421273466869/8.0), REAL_CONST(63686.601602328381/8.0), REAL_CONST(63707.783692328136/8.0), REAL_CONST(63728.967543173334/8.0), REAL_CONST(63750.153154571279/8.0), REAL_CONST(63771.340526229418/8.0), REAL_CONST(63792.529657855317/8.0), REAL_CONST(63813.720549156649/8.0), REAL_CONST(63834.913199841227/8.0), REAL_CONST(63856.107609616978/8.0), REAL_CONST(63877.303778191941/8.0), REAL_CONST(63898.501705274284/8.0), REAL_CONST(63919.7013905723/8.0), REAL_CONST(63940.902833794404/8.0), REAL_CONST(63962.106034649114/8.0), REAL_CONST(63983.310992845094/8.0), REAL_CONST(64004.517708091109/8.0), REAL_CONST(64025.726180096048/8.0), REAL_CONST(64046.936408568938/8.0), REAL_CONST(64068.1483932189/8.0), REAL_CONST(64089.362133755196/8.0), REAL_CONST(64110.577629887193/8.0), REAL_CONST(64131.794881324393/8.0), REAL_CONST(64153.013887776404/8.0), REAL_CONST(64174.234648952966/8.0), REAL_CONST(64195.457164563937/8.0), REAL_CONST(64216.681434319289/8.0), REAL_CONST(64237.907457929112/8.0), REAL_CONST(64259.135235103626/8.0), REAL_CONST(64280.36476555316/8.0), REAL_CONST(64301.596048988169/8.0), REAL_CONST(64322.829085119236/8.0), REAL_CONST(64344.06387365704/8.0), REAL_CONST(64365.300414312398/8.0), REAL_CONST(64386.538706796251/8.0), REAL_CONST(64407.778750819634/8.0), REAL_CONST(64429.020546093721/8.0), REAL_CONST(64450.26409232981/8.0), REAL_CONST(64471.509389239291/8.0), REAL_CONST(64492.756436533709/8.0), REAL_CONST(64514.005233924705/8.0), REAL_CONST(64535.255781124033/8.0), REAL_CONST(64556.50807784358/8.0), REAL_CONST(64577.762123795357/8.0), REAL_CONST(64599.017918691468/8.0), REAL_CONST(64620.275462244172/8.0), REAL_CONST(64641.534754165805/8.0), REAL_CONST(64662.795794168844/8.0), REAL_CONST(64684.058581965895/8.0), REAL_CONST(64705.323117269661/8.0), REAL_CONST(64726.589399792974/8.0), REAL_CONST(64747.857429248776/8.0), REAL_CONST(64769.127205350138/8.0), REAL_CONST(64790.398727810236/8.0), REAL_CONST(64811.671996342375/8.0), REAL_CONST(64832.947010659969/8.0), REAL_CONST(64854.223770476558/8.0), REAL_CONST(64875.502275505794/8.0), REAL_CONST(64896.782525461451/8.0), REAL_CONST(64918.064520057414/8.0), REAL_CONST(64939.348259007682/8.0), REAL_CONST(64960.633742026388/8.0), REAL_CONST(64981.920968827762/8.0), REAL_CONST(65003.209939126165/8.0), REAL_CONST(65024.500652636067/8.0), REAL_CONST(65045.793109072067/8.0), REAL_CONST(65067.087308148861/8.0), REAL_CONST(65088.383249581282/8.0), REAL_CONST(65109.680933084259/8.0), REAL_CONST(65130.980358372864/8.0), REAL_CONST(65152.28152516226/8.0), REAL_CONST(65173.584433167736/8.0), REAL_CONST(65194.889082104703/8.0), REAL_CONST(65216.195471688683/8.0), REAL_CONST(65237.503601635319/8.0), REAL_CONST(65258.813471660353/8.0), REAL_CONST(65280.125081479666/8.0), REAL_CONST(65301.438430809241/8.0), REAL_CONST(65322.753519365178/8.0), REAL_CONST(65344.070346863708/8.0), REAL_CONST(65365.388913021146/8.0), REAL_CONST(65386.709217553958/8.0), REAL_CONST(65408.031260178701/8.0), REAL_CONST(65429.355040612056/8.0), REAL_CONST(65450.680558570821/8.0), REAL_CONST(65472.00781377191/8.0), REAL_CONST(65493.336805932355/8.0), REAL_CONST(65514.66753476928/8.0), REAL_CONST(65535.999999999956/8.0), REAL_CONST(65557.334201341757/8.0), REAL_CONST(65578.670138512171/8.0), REAL_CONST(65600.007811228788/8.0), REAL_CONST(65621.347219209332/8.0), REAL_CONST(65642.688362171626/8.0), REAL_CONST(65664.031239833639/8.0), REAL_CONST(65685.375851913413/8.0), REAL_CONST(65706.722198129137/8.0), REAL_CONST(65728.070278199084/8.0), REAL_CONST(65749.420091841661/8.0), REAL_CONST(65770.771638775404/8.0), REAL_CONST(65792.124918718939/8.0), REAL_CONST(65813.479931391004/8.0), REAL_CONST(65834.836676510458/8.0), REAL_CONST(65856.195153796303/8.0), REAL_CONST(65877.5553629676/8.0), REAL_CONST(65898.917303743554/8.0), REAL_CONST(65920.280975843489/8.0), REAL_CONST(65941.646378986843/8.0), REAL_CONST(65963.013512893158/8.0), REAL_CONST(65984.382377282076/8.0), REAL_CONST(66005.752971873386/8.0), REAL_CONST(66027.125296386963/8.0), REAL_CONST(66048.499350542799/8.0), REAL_CONST(66069.875134061018/8.0), REAL_CONST(66091.252646661844/8.0), REAL_CONST(66112.631888065618/8.0), REAL_CONST(66134.01285799277/8.0), REAL_CONST(66155.395556163887/8.0), REAL_CONST(66176.779982299631/8.0), REAL_CONST(66198.166136120795/8.0), REAL_CONST(66219.554017348273/8.0), REAL_CONST(66240.943625703105/8.0), REAL_CONST(66262.334960906388/8.0), REAL_CONST(66283.728022679396/8.0), REAL_CONST(66305.122810743444/8.0), REAL_CONST(66326.519324820023/8.0), REAL_CONST(66347.917564630698/8.0), REAL_CONST(66369.317529897162/8.0), REAL_CONST(66390.719220341227/8.0), REAL_CONST(66412.122635684791/8.0), REAL_CONST(66433.527775649884/8.0), REAL_CONST(66454.934639958636/8.0), REAL_CONST(66476.343228333324/8.0), REAL_CONST(66497.753540496284/8.0), REAL_CONST(66519.165576169995/8.0), REAL_CONST(66540.57933507704/8.0), REAL_CONST(66561.994816940118/8.0), REAL_CONST(66583.412021482043/8.0), REAL_CONST(66604.830948425733/8.0), REAL_CONST(66626.251597494222/8.0), REAL_CONST(66647.673968410629/8.0), REAL_CONST(66669.098060898235/8.0), REAL_CONST(66690.523874680381/8.0), REAL_CONST(66711.951409480564/8.0), REAL_CONST(66733.380665022371/8.0), REAL_CONST(66754.811641029475/8.0), REAL_CONST(66776.244337225711/8.0), REAL_CONST(66797.678753334985/8.0), REAL_CONST(66819.11488908132/8.0), REAL_CONST(66840.552744188884/8.0), REAL_CONST(66861.992318381905/8.0), REAL_CONST(66883.433611384738/8.0), REAL_CONST(66904.876622921889/8.0), REAL_CONST(66926.321352717903/8.0), REAL_CONST(66947.767800497502/8.0), REAL_CONST(66969.215965985466/8.0), REAL_CONST(66990.665848906734/8.0), REAL_CONST(67012.117448986304/8.0), REAL_CONST(67033.570765949335/8.0), REAL_CONST(67055.025799521056/8.0), REAL_CONST(67076.482549426815/8.0), REAL_CONST(67097.941015392076/8.0), REAL_CONST(67119.401197142433/8.0), REAL_CONST(67140.863094403554/8.0), REAL_CONST(67162.326706901222/8.0), REAL_CONST(67183.792034361351/8.0), REAL_CONST(67205.259076509959/8.0), REAL_CONST(67226.72783307315/8.0), REAL_CONST(67248.198303777172/8.0), REAL_CONST(67269.670488348347/8.0), REAL_CONST(67291.144386513144/8.0), REAL_CONST(67312.619997998088/8.0), REAL_CONST(67334.09732252988/8.0), REAL_CONST(67355.576359835293/8.0), REAL_CONST(67377.057109641188/8.0), REAL_CONST(67398.53957167457/8.0), REAL_CONST(67420.023745662547/8.0), REAL_CONST(67441.50963133233/8.0), REAL_CONST(67462.99722841123/8.0), REAL_CONST(67484.486536626689/8.0), REAL_CONST(67505.977555706224/8.0), REAL_CONST(67527.470285377494/8.0), REAL_CONST(67548.964725368263/8.0), REAL_CONST(67570.460875406367/8.0), REAL_CONST(67591.9587352198/8.0), REAL_CONST(67613.458304536631/8.0), REAL_CONST(67634.95958308503/8.0), REAL_CONST(67656.462570593329/8.0), REAL_CONST(67677.967266789899/8.0), REAL_CONST(67699.473671403248/8.0), REAL_CONST(67720.981784162024/8.0), REAL_CONST(67742.491604794923/8.0), REAL_CONST(67764.003133030797/8.0), REAL_CONST(67785.516368598575/8.0), REAL_CONST(67807.031311227314/8.0), REAL_CONST(67828.547960646174/8.0), REAL_CONST(67850.066316584402/8.0), REAL_CONST(67871.58637877139/8.0), REAL_CONST(67893.108146936589/8.0), REAL_CONST(67914.63162080961/8.0), REAL_CONST(67936.156800120138/8.0), REAL_CONST(67957.683684597971/8.0), REAL_CONST(67979.212273973011/8.0), REAL_CONST(68000.742567975263/8.0), REAL_CONST(68022.274566334876/8.0), REAL_CONST(68043.808268782057/8.0), REAL_CONST(68065.343675047145/8.0), REAL_CONST(68086.880784860579/8.0), REAL_CONST(68108.419597952918/8.0), REAL_CONST(68129.960114054789/8.0), REAL_CONST(68151.502332896969/8.0), REAL_CONST(68173.04625421032/8.0), REAL_CONST(68194.591877725834/8.0), REAL_CONST(68216.139203174564/8.0), REAL_CONST(68237.688230287706/8.0), REAL_CONST(68259.238958796544/8.0), REAL_CONST(68280.791388432481/8.0), REAL_CONST(68302.345518927032/8.0), REAL_CONST(68323.901350011787/8.0), REAL_CONST(68345.458881418483/8.0), REAL_CONST(68367.018112878912/8.0), REAL_CONST(68388.579044125028/8.0), REAL_CONST(68410.141674888844/8.0), REAL_CONST(68431.706004902502/8.0), REAL_CONST(68453.272033898262/8.0), REAL_CONST(68474.839761608455/8.0), REAL_CONST(68496.409187765545/8.0), REAL_CONST(68517.980312102081/8.0), REAL_CONST(68539.553134350732/8.0), REAL_CONST(68561.127654244279/8.0), REAL_CONST(68582.70387151558/8.0), REAL_CONST(68604.281785897634/8.0), REAL_CONST(68625.861397123503/8.0), REAL_CONST(68647.44270492639/8.0), REAL_CONST(68669.025709039604/8.0), REAL_CONST(68690.610409196524/8.0), REAL_CONST(68712.196805130661/8.0), REAL_CONST(68733.784896575627/8.0), REAL_CONST(68755.374683265123/8.0), REAL_CONST(68776.966164932994/8.0), REAL_CONST(68798.559341313128/8.0), REAL_CONST(68820.154212139591/8.0), REAL_CONST(68841.750777146473/8.0), REAL_CONST(68863.349036068044/8.0), REAL_CONST(68884.948988638629/8.0), REAL_CONST(68906.550634592684/8.0), REAL_CONST(68928.153973664739/8.0), REAL_CONST(68949.75900558944/8.0), REAL_CONST(68971.365730101577/8.0), REAL_CONST(68992.974146935987/8.0), REAL_CONST(69014.584255827634/8.0), REAL_CONST(69036.196056511588/8.0), REAL_CONST(69057.809548723017/8.0), REAL_CONST(69079.424732197207/8.0), REAL_CONST(69101.041606669532/8.0), REAL_CONST(69122.660171875468/8.0), REAL_CONST(69144.280427550606/8.0), REAL_CONST(69165.902373430625/8.0), REAL_CONST(69187.526009251334/8.0), REAL_CONST(69209.151334748618/8.0), REAL_CONST(69230.778349658474/8.0), REAL_CONST(69252.40705371699/8.0), REAL_CONST(69274.037446660412/8.0), REAL_CONST(69295.669528225/8.0), REAL_CONST(69317.303298147192/8.0), REAL_CONST(69338.938756163494/8.0), REAL_CONST(69360.575902010532/8.0), REAL_CONST(69382.214735425005/8.0), REAL_CONST(69403.855256143754/8.0), REAL_CONST(69425.497463903681/8.0), REAL_CONST(69447.141358441833/8.0), REAL_CONST(69468.78693949533/8.0), REAL_CONST(69490.434206801394/8.0), REAL_CONST(69512.083160097391/8.0), REAL_CONST(69533.733799120717/8.0), REAL_CONST(69555.386123608929/8.0), REAL_CONST(69577.04013329967/8.0), REAL_CONST(69598.695827930685/8.0), REAL_CONST(69620.353207239794/8.0), REAL_CONST(69642.012270964973/8.0), REAL_CONST(69663.67301884426/8.0), REAL_CONST(69685.335450615792/8.0), REAL_CONST(69706.999566017839/8.0), REAL_CONST(69728.665364788743/8.0), REAL_CONST(69750.332846666963/8.0), REAL_CONST(69772.002011391058/8.0), REAL_CONST(69793.672858699691/8.0), REAL_CONST(69815.345388331611/8.0), REAL_CONST(69837.019600025669/8.0), REAL_CONST(69858.695493520849/8.0), REAL_CONST(69880.373068556204/8.0), REAL_CONST(69902.052324870907/8.0), REAL_CONST(69923.733262204216/8.0), REAL_CONST(69945.415880295492/8.0), REAL_CONST(69967.100178884211/8.0), REAL_CONST(69988.786157709939/8.0), REAL_CONST(70010.473816512356/8.0), REAL_CONST(70032.163155031216/8.0), REAL_CONST(70053.854173006403/8.0), REAL_CONST(70075.546870177874/8.0), REAL_CONST(70097.241246285717/8.0), REAL_CONST(70118.937301070109/8.0), REAL_CONST(70140.635034271298/8.0), REAL_CONST(70162.334445629691/8.0), REAL_CONST(70184.035534885741/8.0), REAL_CONST(70205.738301780017/8.0), REAL_CONST(70227.442746053217/8.0), REAL_CONST(70249.1488674461/8.0), REAL_CONST(70270.856665699539/8.0), REAL_CONST(70292.566140554511/8.0), REAL_CONST(70314.277291752107/8.0), REAL_CONST(70335.990119033493/8.0), REAL_CONST(70357.704622139936/8.0), REAL_CONST(70379.420800812819/8.0), REAL_CONST(70401.138654793613/8.0), REAL_CONST(70422.85818382389/8.0), REAL_CONST(70444.579387645339/8.0), REAL_CONST(70466.302265999722/8.0), REAL_CONST(70488.026818628918/8.0), REAL_CONST(70509.753045274876/8.0), REAL_CONST(70531.480945679708/8.0), REAL_CONST(70553.210519585555/8.0), REAL_CONST(70574.941766734701/8.0), REAL_CONST(70596.674686869505/8.0), REAL_CONST(70618.409279732456/8.0), REAL_CONST(70640.145545066101/8.0), REAL_CONST(70661.883482613106/8.0), REAL_CONST(70683.623092116264/8.0), REAL_CONST(70705.364373318414/8.0), REAL_CONST(70727.107325962526/8.0), REAL_CONST(70748.851949791671/8.0), REAL_CONST(70770.598244549008/8.0), REAL_CONST(70792.346209977783/8.0), REAL_CONST(70814.095845821372/8.0), REAL_CONST(70835.847151823225/8.0), REAL_CONST(70857.600127726895/8.0), REAL_CONST(70879.354773276034/8.0), REAL_CONST(70901.111088214413/8.0), REAL_CONST(70922.869072285859/8.0), REAL_CONST(70944.628725234332/8.0), REAL_CONST(70966.390046803877/8.0), REAL_CONST(70988.153036738629/8.0), REAL_CONST(71009.917694782853/8.0), REAL_CONST(71031.684020680885/8.0), REAL_CONST(71053.45201417715/8.0), REAL_CONST(71075.221675016204/8.0), REAL_CONST(71096.993002942661/8.0), REAL_CONST(71118.765997701266/8.0), REAL_CONST(71140.540659036851/8.0), REAL_CONST(71162.316986694335/8.0), REAL_CONST(71184.09498041874/8.0), REAL_CONST(71205.874639955218/8.0), REAL_CONST(71227.655965048951/8.0), REAL_CONST(71249.438955445294/8.0), REAL_CONST(71271.223610889632/8.0), REAL_CONST(71293.009931127483/8.0), REAL_CONST(71314.797915904477/8.0), REAL_CONST(71336.587564966307/8.0), REAL_CONST(71358.378878058764/8.0), REAL_CONST(71380.171854927772/8.0), REAL_CONST(71401.966495319313/8.0), REAL_CONST(71423.762798979486/8.0), REAL_CONST(71445.560765654489/8.0), REAL_CONST(71467.360395090596/8.0), REAL_CONST(71489.161687034211/8.0), REAL_CONST(71510.964641231811/8.0), REAL_CONST(71532.769257429973/8.0), REAL_CONST(71554.575535375348/8.0), REAL_CONST(71576.383474814749/8.0), REAL_CONST(71598.19307549503/8.0), REAL_CONST(71620.004337163133/8.0), REAL_CONST(71641.817259566145/8.0), REAL_CONST(71663.631842451214/8.0), REAL_CONST(71685.4480855656/8.0), REAL_CONST(71707.26598865664/8.0), REAL_CONST(71729.085551471784/8.0), REAL_CONST(71750.906773758586/8.0), REAL_CONST(71772.729655264673/8.0), REAL_CONST(71794.554195737772/8.0), REAL_CONST(71816.380394925713/8.0), REAL_CONST(71838.208252576442/8.0), REAL_CONST(71860.037768437964/8.0), REAL_CONST(71881.868942258385/8.0), REAL_CONST(71903.701773785942/8.0), REAL_CONST(71925.536262768932/8.0), REAL_CONST(71947.372408955751/8.0), REAL_CONST(71969.210212094898/8.0), REAL_CONST(71991.049671934976/8.0), REAL_CONST(72012.890788224686/8.0), REAL_CONST(72034.73356071279/8.0), REAL_CONST(72056.577989148165/8.0), REAL_CONST(72078.424073279821/8.0), REAL_CONST(72100.271812856794/8.0), REAL_CONST(72122.121207628254/8.0), REAL_CONST(72143.97225734347/8.0), REAL_CONST(72165.824961751801/8.0), REAL_CONST(72187.679320602692/8.0), REAL_CONST(72209.53533364569/8.0), REAL_CONST(72231.393000630429/8.0), REAL_CONST(72253.252321306645/8.0), REAL_CONST(72275.113295424177/8.0), REAL_CONST(72296.975922732949/8.0), REAL_CONST(72318.840202982959/8.0), REAL_CONST(72340.706135924338/8.0), REAL_CONST(72362.573721307272/8.0), REAL_CONST(72384.442958882093/8.0), REAL_CONST(72406.313848399179/8.0), REAL_CONST(72428.186389609036/8.0), REAL_CONST(72450.060582262216/8.0), REAL_CONST(72471.936426109431/8.0), REAL_CONST(72493.813920901433/8.0), REAL_CONST(72515.693066389096/8.0), REAL_CONST(72537.573862323392/8.0), REAL_CONST(72559.456308455352/8.0), REAL_CONST(72581.340404536139/8.0), REAL_CONST(72603.226150316987/8.0), REAL_CONST(72625.113545549248/8.0), REAL_CONST(72647.002589984331/8.0), REAL_CONST(72668.893283373764/8.0), REAL_CONST(72690.785625469172/8.0), REAL_CONST(72712.679616022273/8.0), REAL_CONST(72734.575254784853/8.0), REAL_CONST(72756.472541508803/8.0), REAL_CONST(72778.371475946144/8.0), REAL_CONST(72800.272057848939/8.0), REAL_CONST(72822.174286969355/8.0), REAL_CONST(72844.07816305969/8.0), REAL_CONST(72865.983685872285/8.0), REAL_CONST(72887.890855159596/8.0), REAL_CONST(72909.799670674183/8.0), REAL_CONST(72931.710132168693/8.0), REAL_CONST(72953.622239395845/8.0), REAL_CONST(72975.535992108475/8.0), REAL_CONST(72997.451390059519/8.0), REAL_CONST(73019.368433001961/8.0), REAL_CONST(73041.287120688925/8.0), REAL_CONST(73063.207452873612/8.0), REAL_CONST(73085.129429309294/8.0), REAL_CONST(73107.053049749389/8.0), REAL_CONST(73128.978313947344/8.0), REAL_CONST(73150.905221656736/8.0), REAL_CONST(73172.833772631217/8.0), REAL_CONST(73194.763966624567/8.0), REAL_CONST(73216.695803390612/8.0), REAL_CONST(73238.62928268328/8.0), REAL_CONST(73260.564404256627/8.0), REAL_CONST(73282.501167864757/8.0), REAL_CONST(73304.439573261901/8.0), REAL_CONST(73326.379620202337/8.0), REAL_CONST(73348.321308440485/8.0), REAL_CONST(73370.264637730841/8.0), REAL_CONST(73392.209607827957/8.0), REAL_CONST(73414.156218486532/8.0), REAL_CONST(73436.104469461323/8.0), REAL_CONST(73458.054360507173/8.0), REAL_CONST(73480.005891379056/8.0), REAL_CONST(73501.959061831993/8.0), REAL_CONST(73523.913871621116/8.0), REAL_CONST(73545.870320501665/8.0), REAL_CONST(73567.828408228932/8.0), REAL_CONST(73589.78813455833/8.0), REAL_CONST(73611.749499245358/8.0), REAL_CONST(73633.712502045615/8.0), REAL_CONST(73655.677142714747/8.0), REAL_CONST(73677.643421008557/8.0), REAL_CONST(73699.611336682879/8.0), REAL_CONST(73721.580889493693/8.0), REAL_CONST(73743.552079197019/8.0), REAL_CONST(73765.524905548999/8.0), REAL_CONST(73787.499368305856/8.0), REAL_CONST(73809.475467223907/8.0), REAL_CONST(73831.453202059551/8.0), REAL_CONST(73853.432572569291/8.0), REAL_CONST(73875.413578509717/8.0), REAL_CONST(73897.396219637507/8.0), REAL_CONST(73919.380495709411/8.0), REAL_CONST(73941.36640648231/8.0), REAL_CONST(73963.353951713143/8.0), REAL_CONST(73985.343131158952/8.0), REAL_CONST(74007.333944576865/8.0), REAL_CONST(74029.326391724098/8.0), REAL_CONST(74051.320472357969/8.0), REAL_CONST(74073.316186235883/8.0), REAL_CONST(74095.313533115303/8.0), REAL_CONST(74117.312512753837/8.0), REAL_CONST(74139.313124909138/8.0), REAL_CONST(74161.315369338976/8.0), REAL_CONST(74183.319245801191/8.0), REAL_CONST(74205.324754053727/8.0), REAL_CONST(74227.331893854629/8.0), REAL_CONST(74249.340664961986/8.0), REAL_CONST(74271.351067134034/8.0), REAL_CONST(74293.363100129049/8.0), REAL_CONST(74315.376763705441/8.0), REAL_CONST(74337.392057621662/8.0), REAL_CONST(74359.408981636298/8.0), REAL_CONST(74381.427535508003/8.0), REAL_CONST(74403.447718995507/8.0), REAL_CONST(74425.469531857671/8.0), REAL_CONST(74447.492973853383/8.0), REAL_CONST(74469.518044741693/8.0), REAL_CONST(74491.54474428168/8.0), REAL_CONST(74513.573072232539/8.0), REAL_CONST(74535.603028353551/8.0), REAL_CONST(74557.634612404087/8.0), REAL_CONST(74579.667824143602/8.0), REAL_CONST(74601.702663331642/8.0), REAL_CONST(74623.739129727837/8.0), REAL_CONST(74645.777223091936/8.0), REAL_CONST(74667.816943183716/8.0), REAL_CONST(74689.858289763113/8.0), REAL_CONST(74711.901262590094/8.0), REAL_CONST(74733.945861424741/8.0), REAL_CONST(74755.992086027225/8.0), REAL_CONST(74778.039936157802/8.0), REAL_CONST(74800.089411576817/8.0), REAL_CONST(74822.140512044702/8.0), REAL_CONST(74844.193237321961/8.0), REAL_CONST(74866.24758716923/8.0), REAL_CONST(74888.303561347187/8.0), REAL_CONST(74910.36115961663/8.0), REAL_CONST(74932.420381738411/8.0), REAL_CONST(74954.481227473516/8.0), REAL_CONST(74976.543696582972/8.0), REAL_CONST(74998.607788827925/8.0), REAL_CONST(75020.673503969607/8.0), REAL_CONST(75042.740841769322/8.0), REAL_CONST(75064.809801988464/8.0), REAL_CONST(75086.88038438854/8.0), REAL_CONST(75108.952588731103/8.0), REAL_CONST(75131.026414777836/8.0), REAL_CONST(75153.101862290467/8.0), REAL_CONST(75175.178931030852/8.0), REAL_CONST(75197.257620760924/8.0), REAL_CONST(75219.33793124267/8.0), REAL_CONST(75241.419862238225/8.0), REAL_CONST(75263.503413509738/8.0), REAL_CONST(75285.588584819503/8.0), REAL_CONST(75307.675375929874/8.0), REAL_CONST(75329.763786603318/8.0), REAL_CONST(75351.853816602365/8.0), REAL_CONST(75373.945465689612/8.0), REAL_CONST(75396.038733627807/8.0), REAL_CONST(75418.133620179724/8.0), REAL_CONST(75440.230125108254/8.0), REAL_CONST(75462.32824817636/8.0), REAL_CONST(75484.427989147109/8.0), REAL_CONST(75506.529347783653/8.0), REAL_CONST(75528.63232384919/8.0), REAL_CONST(75550.736917107075/8.0), REAL_CONST(75572.843127320695/8.0), REAL_CONST(75594.950954253538/8.0), REAL_CONST(75617.060397669193/8.0), REAL_CONST(75639.171457331307/8.0), REAL_CONST(75661.284133003646/8.0), REAL_CONST(75683.398424450032/8.0), REAL_CONST(75705.514331434402/8.0), REAL_CONST(75727.631853720741/8.0), REAL_CONST(75749.750991073175/8.0), REAL_CONST(75771.871743255862/8.0), REAL_CONST(75793.994110033076/8.0), REAL_CONST(75816.118091169177/8.0), REAL_CONST(75838.243686428585/8.0), REAL_CONST(75860.370895575848/8.0), REAL_CONST(75882.499718375562/8.0), REAL_CONST(75904.630154592422/8.0), REAL_CONST(75926.762203991224/8.0), REAL_CONST(75948.895866336825/8.0), REAL_CONST(75971.031141394182/8.0), REAL_CONST(75993.168028928325/8.0), REAL_CONST(76015.306528704401/8.0), REAL_CONST(76037.4466404876/8.0), REAL_CONST(76059.588364043215/8.0), REAL_CONST(76081.731699136653/8.0), REAL_CONST(76103.876645533353/8.0), REAL_CONST(76126.023202998884/8.0), REAL_CONST(76148.171371298871/8.0), REAL_CONST(76170.321150199044/8.0), REAL_CONST(76192.472539465205/8.0), REAL_CONST(76214.625538863256/8.0), REAL_CONST(76236.780148159174/8.0), REAL_CONST(76258.936367119008/8.0), REAL_CONST(76281.094195508922/8.0), REAL_CONST(76303.253633095141/8.0), REAL_CONST(76325.414679643975/8.0), REAL_CONST(76347.577334921851/8.0), REAL_CONST(76369.741598695226/8.0), REAL_CONST(76391.907470730686/8.0), REAL_CONST(76414.074950794879/8.0), REAL_CONST(76436.244038654564/8.0), REAL_CONST(76458.414734076548/8.0), REAL_CONST(76480.587036827754/8.0), REAL_CONST(76502.760946675175/8.0), REAL_CONST(76524.936463385893/8.0), REAL_CONST(76547.11358672705/8.0), REAL_CONST(76569.292316465915/8.0), REAL_CONST(76591.472652369819/8.0), REAL_CONST(76613.654594206164/8.0), REAL_CONST(76635.838141742468/8.0), REAL_CONST(76658.023294746308/8.0), REAL_CONST(76680.210052985349/8.0), REAL_CONST(76702.398416227341/8.0), REAL_CONST(76724.588384240138/8.0), REAL_CONST(76746.779956791637/8.0), REAL_CONST(76768.973133649866/8.0), REAL_CONST(76791.167914582897/8.0), REAL_CONST(76813.364299358902/8.0), REAL_CONST(76835.562287746157/8.0), REAL_CONST(76857.761879512967/8.0), REAL_CONST(76879.963074427797/8.0), REAL_CONST(76902.165872259109/8.0), REAL_CONST(76924.37027277553/8.0), REAL_CONST(76946.576275745727/8.0), REAL_CONST(76968.783880938441/8.0), REAL_CONST(76990.993088122515/8.0), REAL_CONST(77013.203897066895/8.0), REAL_CONST(77035.416307540567/8.0), REAL_CONST(77057.630319312622/8.0), REAL_CONST(77079.845932152239/8.0), REAL_CONST(77102.063145828695/8.0), REAL_CONST(77124.281960111301/8.0), REAL_CONST(77146.50237476948/8.0), REAL_CONST(77168.724389572759/8.0), REAL_CONST(77190.948004290723/8.0), REAL_CONST(77213.173218693031/8.0), REAL_CONST(77235.400032549442/8.0), REAL_CONST(77257.628445629802/8.0), REAL_CONST(77279.858457704031/8.0), REAL_CONST(77302.090068542122/8.0), REAL_CONST(77324.323277914169/8.0), REAL_CONST(77346.558085590339/8.0), REAL_CONST(77368.794491340886/8.0), REAL_CONST(77391.032494936138/8.0), REAL_CONST(77413.272096146524/8.0), REAL_CONST(77435.51329474253/8.0), REAL_CONST(77457.756090494731/8.0), REAL_CONST(77480.000483173804/8.0), REAL_CONST(77502.246472550498/8.0), REAL_CONST(77524.494058395634/8.0), REAL_CONST(77546.743240480107/8.0), REAL_CONST(77568.994018574944/8.0), REAL_CONST(77591.246392451198/8.0), REAL_CONST(77613.500361880026/8.0), REAL_CONST(77635.755926632657/8.0), REAL_CONST(77658.013086480438/8.0), REAL_CONST(77680.271841194757/8.0), REAL_CONST(77702.532190547092/8.0), REAL_CONST(77724.794134309021/8.0), REAL_CONST(77747.057672252195/8.0), REAL_CONST(77769.322804148323/8.0), REAL_CONST(77791.589529769248/8.0), REAL_CONST(77813.857848886837/8.0), REAL_CONST(77836.127761273063/8.0), REAL_CONST(77858.399266699998/8.0), REAL_CONST(77880.67236493979/8.0), REAL_CONST(77902.947055764627/8.0), REAL_CONST(77925.223338946831/8.0), REAL_CONST(77947.50121425878/8.0), REAL_CONST(77969.780681472927/8.0), REAL_CONST(77992.061740361838/8.0), REAL_CONST(78014.344390698127/8.0), REAL_CONST(78036.628632254491/8.0), REAL_CONST(78058.914464803747/8.0), REAL_CONST(78081.201888118725/8.0), REAL_CONST(78103.490901972415/8.0), REAL_CONST(78125.781506137821/8.0), REAL_CONST(78148.073700388064/8.0), REAL_CONST(78170.367484496339/8.0), REAL_CONST(78192.662858235926/8.0), REAL_CONST(78214.959821380166/8.0), REAL_CONST(78237.258373702498/8.0), REAL_CONST(78259.558514976452/8.0), REAL_CONST(78281.860244975614/8.0), REAL_CONST(78304.163563473659/8.0), REAL_CONST(78326.468470244363/8.0), REAL_CONST(78348.77496506153/8.0), REAL_CONST(78371.083047699125/8.0), REAL_CONST(78393.392717931114/8.0), REAL_CONST(78415.703975531578/8.0), REAL_CONST(78438.016820274701/8.0), REAL_CONST(78460.331251934695/8.0), REAL_CONST(78482.647270285903/8.0), REAL_CONST(78504.964875102727/8.0), REAL_CONST(78527.284066159627/8.0), REAL_CONST(78549.604843231195/8.0), REAL_CONST(78571.927206092048/8.0), REAL_CONST(78594.251154516911/8.0), REAL_CONST(78616.576688280606/8.0), REAL_CONST(78638.903807157985/8.0), REAL_CONST(78661.232510924034/8.0), REAL_CONST(78683.562799353778/8.0), REAL_CONST(78705.894672222363/8.0), REAL_CONST(78728.228129304945/8.0), REAL_CONST(78750.563170376859/8.0), REAL_CONST(78772.899795213423/8.0), REAL_CONST(78795.238003590101/8.0), REAL_CONST(78817.577795282399/8.0), REAL_CONST(78839.919170065928/8.0), REAL_CONST(78862.262127716356/8.0), REAL_CONST(78884.606668009452/8.0), REAL_CONST(78906.952790721043/8.0), REAL_CONST(78929.300495627045/8.0), REAL_CONST(78951.64978250346/8.0), REAL_CONST(78974.000651126378/8.0), REAL_CONST(78996.353101271932/8.0), REAL_CONST(79018.707132716358/8.0), REAL_CONST(79041.062745235977/8.0), REAL_CONST(79063.41993860717/8.0), REAL_CONST(79085.778712606436/8.0), REAL_CONST(79108.139067010285/8.0), REAL_CONST(79130.501001595389/8.0), REAL_CONST(79152.864516138419/8.0), REAL_CONST(79175.22961041618/8.0), REAL_CONST(79197.596284205531/8.0), REAL_CONST(79219.96453728342/8.0), REAL_CONST(79242.33436942687/8.0), REAL_CONST(79264.705780412987/8.0), REAL_CONST(79287.078770018954/8.0), REAL_CONST(79309.453338022009/8.0), REAL_CONST(79331.829484199508/8.0), REAL_CONST(79354.207208328866/8.0), REAL_CONST(79376.586510187582/8.0), REAL_CONST(79398.967389553218/8.0), REAL_CONST(79421.349846203433/8.0), REAL_CONST(79443.733879915948/8.0), REAL_CONST(79466.119490468584/8.0), REAL_CONST(79488.50667763922/8.0), REAL_CONST(79510.895441205823/8.0), REAL_CONST(79533.285780946433/8.0), REAL_CONST(79555.677696639163/8.0), REAL_CONST(79578.071188062226/8.0), REAL_CONST(79600.466254993895/8.0), REAL_CONST(79622.862897212515/8.0), REAL_CONST(79645.261114496549/8.0), REAL_CONST(79667.660906624471/8.0), REAL_CONST(79690.062273374875/8.0), REAL_CONST(79712.465214526455/8.0), REAL_CONST(79734.869729857935/8.0), REAL_CONST(79757.275819148126/8.0), REAL_CONST(79779.683482175955/8.0), REAL_CONST(79802.092718720378/8.0), REAL_CONST(79824.503528560454/8.0), REAL_CONST(79846.915911475327/8.0), REAL_CONST(79869.329867244203/8.0), REAL_CONST(79891.745395646343/8.0), REAL_CONST(79914.162496461155/8.0), REAL_CONST(79936.581169468045/8.0), REAL_CONST(79959.001414446553/8.0), REAL_CONST(79981.423231176261/8.0), REAL_CONST(80003.846619436852/8.0), REAL_CONST(80026.271579008084/8.0), REAL_CONST(80048.698109669771/8.0), REAL_CONST(80071.12621120183/8.0), REAL_CONST(80093.555883384237/8.0), REAL_CONST(80115.987125997053/8.0), REAL_CONST(80138.419938820414/8.0), REAL_CONST(80160.854321634528/8.0), REAL_CONST(80183.290274219689/8.0), REAL_CONST(80205.727796356281/8.0), REAL_CONST(80228.166887824715/8.0), REAL_CONST(80250.607548405547/8.0), REAL_CONST(80273.049777879336/8.0), REAL_CONST(80295.493576026798/8.0), REAL_CONST(80317.938942628651/8.0), REAL_CONST(80340.385877465727/8.0), REAL_CONST(80362.834380318949/8.0), REAL_CONST(80385.28445096928/8.0), REAL_CONST(80407.736089197788/8.0), REAL_CONST(80430.189294785596/8.0), REAL_CONST(80452.644067513917/8.0), REAL_CONST(80475.100407164035/8.0), REAL_CONST(80497.558313517322/8.0), REAL_CONST(80520.017786355209/8.0), REAL_CONST(80542.478825459213/8.0), REAL_CONST(80564.941430610925/8.0), REAL_CONST(80587.405601592007/8.0), REAL_CONST(80609.871338184195/8.0), REAL_CONST(80632.338640169342/8.0), REAL_CONST(80654.8075073293/8.0), REAL_CONST(80677.277939446067/8.0), REAL_CONST(80699.749936301683/8.0), REAL_CONST(80722.223497678278/8.0), REAL_CONST(80744.698623358039/8.0), REAL_CONST(80767.17531312324/8.0), REAL_CONST(80789.653566756242/8.0), REAL_CONST(80812.133384039465/8.0), REAL_CONST(80834.614764755403/8.0), REAL_CONST(80857.097708686648/8.0), REAL_CONST(80879.582215615854/8.0), REAL_CONST(80902.068285325731/8.0), REAL_CONST(80924.555917599093/8.0), REAL_CONST(80947.045112218824/8.0), REAL_CONST(80969.535868967869/8.0), REAL_CONST(80992.028187629272/8.0), REAL_CONST(81014.522067986123/8.0), REAL_CONST(81037.017509821613/8.0), REAL_CONST(81059.514512919006/8.0), REAL_CONST(81082.013077061609/8.0), REAL_CONST(81104.513202032831/8.0), REAL_CONST(81127.014887616184/8.0), REAL_CONST(81149.518133595193/8.0), REAL_CONST(81172.022939753486/8.0), REAL_CONST(81194.529305874807/8.0), REAL_CONST(81217.037231742899/8.0), REAL_CONST(81239.546717141639/8.0), REAL_CONST(81262.057761854958/8.0), REAL_CONST(81284.570365666848/8.0), REAL_CONST(81307.084528361403/8.0), REAL_CONST(81329.600249722775/8.0), REAL_CONST(81352.117529535186/8.0), REAL_CONST(81374.636367582949/8.0), REAL_CONST(81397.156763650448/8.0), REAL_CONST(81419.678717522125/8.0), REAL_CONST(81442.202228982511/8.0), REAL_CONST(81464.727297816222/8.0), REAL_CONST(81487.253923807933/8.0), REAL_CONST(81509.782106742379/8.0), REAL_CONST(81532.311846404409/8.0), REAL_CONST(81554.843142578902/8.0), REAL_CONST(81577.375995050839/8.0), REAL_CONST(81599.910403605274/8.0), REAL_CONST(81622.446368027333/8.0), REAL_CONST(81644.983888102215/8.0), REAL_CONST(81667.522963615178/8.0), REAL_CONST(81690.063594351581/8.0), REAL_CONST(81712.605780096841/8.0), REAL_CONST(81735.149520636449/8.0), REAL_CONST(81757.694815755967/8.0), REAL_CONST(81780.241665241047/8.0), REAL_CONST(81802.79006887741/8.0), REAL_CONST(81825.340026450824/8.0), REAL_CONST(81847.891537747171/8.0), REAL_CONST(81870.444602552379/8.0), REAL_CONST(81892.999220652477/8.0), REAL_CONST(81915.555391833506/8.0), REAL_CONST(81938.113115881672/8.0), REAL_CONST(81960.672392583176/8.0), REAL_CONST(81983.233221724338/8.0), REAL_CONST(82005.795603091537/8.0), REAL_CONST(82028.359536471224/8.0), REAL_CONST(82050.925021649906/8.0), REAL_CONST(82073.492058414209/8.0), REAL_CONST(82096.060646550788/8.0), REAL_CONST(82118.630785846399/8.0), REAL_CONST(82141.202476087841/8.0), REAL_CONST(82163.775717062032/8.0), REAL_CONST(82186.35050855593/8.0), REAL_CONST(82208.926850356569/8.0), REAL_CONST(82231.504742251054/8.0), REAL_CONST(82254.084184026578/8.0), REAL_CONST(82276.665175470393/8.0), REAL_CONST(82299.24771636985/8.0), REAL_CONST(82321.831806512317/8.0), REAL_CONST(82344.417445685307/8.0), REAL_CONST(82367.004633676348/8.0), REAL_CONST(82389.593370273054/8.0), REAL_CONST(82412.183655263143/8.0), REAL_CONST(82434.775488434374/8.0), REAL_CONST(82457.368869574595/8.0), REAL_CONST(82479.963798471697/8.0), REAL_CONST(82502.560274913689/8.0), REAL_CONST(82525.158298688606/8.0), REAL_CONST(82547.757869584602/8.0), REAL_CONST(82570.35898738986/8.0), REAL_CONST(82592.961651892678/8.0), REAL_CONST(82615.565862881398/8.0), REAL_CONST(82638.171620144421/8.0), REAL_CONST(82660.778923470265/8.0), REAL_CONST(82683.387772647475/8.0), REAL_CONST(82705.998167464713/8.0), REAL_CONST(82728.610107710658/8.0), REAL_CONST(82751.223593174116/8.0), REAL_CONST(82773.83862364394/8.0), REAL_CONST(82796.45519890904/8.0), REAL_CONST(82819.073318758441/8.0), REAL_CONST(82841.692982981185/8.0), REAL_CONST(82864.314191366429/8.0), REAL_CONST(82886.936943703375/8.0), REAL_CONST(82909.561239781324/8.0), REAL_CONST(82932.187079389638/8.0), REAL_CONST(82954.814462317736/8.0), REAL_CONST(82977.443388355125/8.0), REAL_CONST(83000.073857291369/8.0), REAL_CONST(83022.70586891612/8.0), REAL_CONST(83045.339423019104/8.0), REAL_CONST(83067.974519390089/8.0), REAL_CONST(83090.611157818959/8.0), REAL_CONST(83113.249338095629/8.0), REAL_CONST(83135.8890600101/8.0), REAL_CONST(83158.530323352461/8.0), REAL_CONST(83181.173127912858/8.0), REAL_CONST(83203.817473481497/8.0), REAL_CONST(83226.463359848669/8.0), REAL_CONST(83249.11078680474/8.0), REAL_CONST(83271.759754140134/8.0), REAL_CONST(83294.410261645375/8.0), REAL_CONST(83317.062309111003/8.0), REAL_CONST(83339.715896327703/8.0), REAL_CONST(83362.371023086147/8.0), REAL_CONST(83385.027689177165/8.0), REAL_CONST(83407.685894391587/8.0), REAL_CONST(83430.345638520361/8.0), REAL_CONST(83453.006921354478/8.0), REAL_CONST(83475.669742685001/8.0), REAL_CONST(83498.334102303095/8.0), REAL_CONST(83520.999999999942/8.0), REAL_CONST(83543.667435566866/8.0), REAL_CONST(83566.336408795192/8.0), REAL_CONST(83589.006919476349/8.0), REAL_CONST(83611.678967401851/8.0), REAL_CONST(83634.352552363242/8.0), REAL_CONST(83657.027674152167/8.0), REAL_CONST(83679.704332560359/8.0), REAL_CONST(83702.382527379552/8.0), REAL_CONST(83725.062258401638/8.0), REAL_CONST(83747.743525418511/8.0), REAL_CONST(83770.42632822218/8.0), REAL_CONST(83793.110666604684/8.0), REAL_CONST(83815.796540358162/8.0), REAL_CONST(83838.483949274829/8.0), REAL_CONST(83861.172893146941/8.0), REAL_CONST(83883.863371766842/8.0), REAL_CONST(83906.555384926964/8.0), REAL_CONST(83929.248932419752/8.0), REAL_CONST(83951.944014037799/8.0), REAL_CONST(83974.640629573696/8.0), REAL_CONST(83997.338778820151/8.0), REAL_CONST(84020.038461569929/8.0), REAL_CONST(84042.739677615857/8.0), REAL_CONST(84065.442426750829/8.0), REAL_CONST(84088.146708767847/8.0), REAL_CONST(84110.852523459922/8.0), REAL_CONST(84133.559870620171/8.0), REAL_CONST(84156.268750041796/8.0), REAL_CONST(84178.979161518029/8.0), REAL_CONST(84201.691104842204/8.0), REAL_CONST(84224.404579807713/8.0), REAL_CONST(84247.119586208006/8.0), REAL_CONST(84269.83612383662/8.0), REAL_CONST(84292.55419248715/8.0), REAL_CONST(84315.273791953281/8.0), REAL_CONST(84337.994922028738/8.0), REAL_CONST(84360.717582507335/8.0), REAL_CONST(84383.441773182945/8.0), REAL_CONST(84406.167493849513/8.0), REAL_CONST(84428.894744301069/8.0), REAL_CONST(84451.623524331691/8.0), REAL_CONST(84474.353833735542/8.0), REAL_CONST(84497.085672306828/8.0), REAL_CONST(84519.819039839858/8.0), REAL_CONST(84542.553936128999/8.0), REAL_CONST(84565.290360968676/8.0), REAL_CONST(84588.028314153402/8.0), REAL_CONST(84610.767795477717/8.0), REAL_CONST(84633.508804736295/8.0), REAL_CONST(84656.251341723822/8.0), REAL_CONST(84678.995406235073/8.0), REAL_CONST(84701.740998064924/8.0), REAL_CONST(84724.488117008252/8.0), REAL_CONST(84747.236762860062/8.0), REAL_CONST(84769.986935415407/8.0), REAL_CONST(84792.73863446941/8.0), REAL_CONST(84815.491859817252/8.0), REAL_CONST(84838.246611254188/8.0), REAL_CONST(84861.002888575575/8.0), REAL_CONST(84883.760691576768/8.0), REAL_CONST(84906.520020053256/8.0), REAL_CONST(84929.28087380057/8.0), REAL_CONST(84952.043252614312/8.0), REAL_CONST(84974.807156290146/8.0), REAL_CONST(84997.572584623806/8.0), REAL_CONST(85020.339537411113/8.0), REAL_CONST(85043.108014447949/8.0), REAL_CONST(85065.878015530237/8.0), REAL_CONST(85088.649540453989/8.0), REAL_CONST(85111.422589015303/8.0), REAL_CONST(85134.197161010321/8.0), REAL_CONST(85156.973256235244/8.0), REAL_CONST(85179.750874486374/8.0), REAL_CONST(85202.530015560071/8.0), REAL_CONST(85225.310679252725/8.0), REAL_CONST(85248.092865360857/8.0), REAL_CONST(85270.876573681016/8.0), REAL_CONST(85293.661804009811/8.0), REAL_CONST(85316.448556143951/8.0), REAL_CONST(85339.236829880188/8.0), REAL_CONST(85362.026625015351/8.0), REAL_CONST(85384.817941346351/8.0), REAL_CONST(85407.610778670132/8.0), REAL_CONST(85430.405136783724/8.0), REAL_CONST(85453.201015484257/8.0), REAL_CONST(85475.998414568865/8.0), REAL_CONST(85498.797333834795/8.0), REAL_CONST(85521.597773079353/8.0), REAL_CONST(85544.399732099904/8.0), REAL_CONST(85567.203210693886/8.0), REAL_CONST(85590.008208658808/8.0), REAL_CONST(85612.814725792239/8.0), REAL_CONST(85635.62276189182/8.0), REAL_CONST(85658.432316755265/8.0), REAL_CONST(85681.243390180331/8.0), REAL_CONST(85704.055981964877/8.0), REAL_CONST(85726.870091906807/8.0), REAL_CONST(85749.685719804082/8.0), REAL_CONST(85772.502865454764/8.0), REAL_CONST(85795.321528656961/8.0), REAL_CONST(85818.141709208852/8.0), REAL_CONST(85840.963406908675/8.0), REAL_CONST(85863.78662155474/8.0), REAL_CONST(85886.611352945445/8.0), REAL_CONST(85909.437600879217/8.0), REAL_CONST(85932.26536515457/8.0), REAL_CONST(85955.094645570091/8.0), REAL_CONST(85977.92544192441/8.0), REAL_CONST(86000.757754016275/8.0), REAL_CONST(86023.591581644432/8.0), REAL_CONST(86046.426924607746/8.0), REAL_CONST(86069.263782705122/8.0), REAL_CONST(86092.102155735556/8.0), REAL_CONST(86114.942043498071/8.0), REAL_CONST(86137.783445791807/8.0), REAL_CONST(86160.626362415918/8.0), REAL_CONST(86183.470793169676/8.0), REAL_CONST(86206.316737852379/8.0), REAL_CONST(86229.164196263402/8.0), REAL_CONST(86252.013168202204/8.0), REAL_CONST(86274.863653468303/8.0), REAL_CONST(86297.715651861261/8.0), REAL_CONST(86320.569163180728/8.0), REAL_CONST(86343.424187226425/8.0), REAL_CONST(86366.280723798132/8.0), REAL_CONST(86389.138772695675/8.0), REAL_CONST(86411.998333718977/8.0), REAL_CONST(86434.859406668009/8.0), REAL_CONST(86457.721991342827/8.0), REAL_CONST(86480.586087543532/8.0), REAL_CONST(86503.451695070296/8.0), REAL_CONST(86526.318813723352/8.0), REAL_CONST(86549.187443303032/8.0), REAL_CONST(86572.057583609683/8.0), REAL_CONST(86594.929234443756/8.0), REAL_CONST(86617.802395605773/8.0), REAL_CONST(86640.677066896271/8.0), REAL_CONST(86663.553248115903/8.0), REAL_CONST(86686.43093906538/8.0), REAL_CONST(86709.310139545443/8.0), REAL_CONST(86732.190849356964/8.0), REAL_CONST(86755.073068300815/8.0), REAL_CONST(86777.956796177954/8.0), REAL_CONST(86800.842032789442/8.0), REAL_CONST(86823.728777936354/8.0), REAL_CONST(86846.617031419853/8.0), REAL_CONST(86869.506793041175/8.0), REAL_CONST(86892.398062601613/8.0), REAL_CONST(86915.290839902518/8.0), REAL_CONST(86938.185124745316/8.0), REAL_CONST(86961.080916931489/8.0), REAL_CONST(86983.978216262592/8.0), REAL_CONST(87006.87702254027/8.0), REAL_CONST(87029.777335566177/8.0), REAL_CONST(87052.67915514209/8.0), REAL_CONST(87075.582481069796/8.0), REAL_CONST(87098.487313151185/8.0), REAL_CONST(87121.39365118822/8.0), REAL_CONST(87144.301494982894/8.0), REAL_CONST(87167.210844337285/8.0), REAL_CONST(87190.121699053532/8.0), REAL_CONST(87213.034058933845/8.0), REAL_CONST(87235.947923780506/8.0), REAL_CONST(87258.863293395829/8.0), REAL_CONST(87281.780167582241/8.0), REAL_CONST(87304.698546142172/8.0), REAL_CONST(87327.618428878181/8.0), REAL_CONST(87350.539815592856/8.0), REAL_CONST(87373.462706088845/8.0), REAL_CONST(87396.387100168897/8.0), REAL_CONST(87419.312997635774/8.0), REAL_CONST(87442.240398292357/8.0), REAL_CONST(87465.16930194154/8.0), REAL_CONST(87488.099708386319/8.0), REAL_CONST(87511.031617429733/8.0), REAL_CONST(87533.965028874911/8.0), REAL_CONST(87556.899942525008/8.0), REAL_CONST(87579.836358183282/8.0), REAL_CONST(87602.774275653021/8.0), REAL_CONST(87625.713694737613/8.0), REAL_CONST(87648.654615240492/8.0), REAL_CONST(87671.597036965148/8.0), REAL_CONST(87694.540959715145/8.0), REAL_CONST(87717.486383294105/8.0), REAL_CONST(87740.433307505737/8.0), REAL_CONST(87763.381732153779/8.0), REAL_CONST(87786.331657042057/8.0), REAL_CONST(87809.283081974456/8.0), REAL_CONST(87832.236006754916/8.0), REAL_CONST(87855.190431187453/8.0), REAL_CONST(87878.146355076155/8.0), REAL_CONST(87901.103778225151/8.0), REAL_CONST(87924.062700438633/8.0), REAL_CONST(87947.023121520891/8.0), REAL_CONST(87969.985041276246/8.0), REAL_CONST(87992.948459509105/8.0), REAL_CONST(88015.913376023906/8.0), REAL_CONST(88038.879790625171/8.0), REAL_CONST(88061.847703117513/8.0), REAL_CONST(88084.817113305573/8.0), REAL_CONST(88107.788020994049/8.0), REAL_CONST(88130.760425987726/8.0), REAL_CONST(88153.734328091465/8.0), REAL_CONST(88176.709727110137/8.0), REAL_CONST(88199.686622848749/8.0), REAL_CONST(88222.665015112303/8.0), REAL_CONST(88245.644903705906/8.0), REAL_CONST(88268.626288434709/8.0), REAL_CONST(88291.609169103947/8.0), REAL_CONST(88314.593545518903/8.0), REAL_CONST(88337.579417484914/8.0), REAL_CONST(88360.566784807408/8.0), REAL_CONST(88383.555647291854/8.0), REAL_CONST(88406.546004743795/8.0), REAL_CONST(88429.537856968818/8.0), REAL_CONST(88452.531203772611/8.0), REAL_CONST(88475.52604496089/8.0), REAL_CONST(88498.522380339447/8.0), REAL_CONST(88521.52020971413/8.0), REAL_CONST(88544.519532890874/8.0), REAL_CONST(88567.520349675644/8.0), REAL_CONST(88590.522659874507/8.0), REAL_CONST(88613.526463293543/8.0), REAL_CONST(88636.531759738922/8.0), REAL_CONST(88659.538549016899/8.0), REAL_CONST(88682.546830933745/8.0), REAL_CONST(88705.556605295846/8.0), REAL_CONST(88728.567871909589/8.0), REAL_CONST(88751.580630581491/8.0), REAL_CONST(88774.594881118086/8.0), REAL_CONST(88797.610623325963/8.0), REAL_CONST(88820.62785701183/8.0), REAL_CONST(88843.646581982393/8.0), REAL_CONST(88866.666798044462/8.0), REAL_CONST(88889.688505004888/8.0), REAL_CONST(88912.711702670611/8.0), REAL_CONST(88935.7363908486/8.0), REAL_CONST(88958.762569345898/8.0), REAL_CONST(88981.790237969632/8.0), REAL_CONST(89004.81939652696/8.0), REAL_CONST(89027.850044825114/8.0), REAL_CONST(89050.882182671412/8.0), REAL_CONST(89073.9158098732/8.0), REAL_CONST(89096.950926237885/8.0), REAL_CONST(89119.987531572973/8.0), REAL_CONST(89143.025625686001/8.0), REAL_CONST(89166.065208384563/8.0), REAL_CONST(89189.106279476357/8.0), REAL_CONST(89212.148838769106/8.0), REAL_CONST(89235.192886070581/8.0), REAL_CONST(89258.238421188667/8.0), REAL_CONST(89281.285443931265/8.0), REAL_CONST(89304.333954106376/8.0), REAL_CONST(89327.383951522017/8.0), REAL_CONST(89350.435435986306/8.0), REAL_CONST(89373.488407307406/8.0), REAL_CONST(89396.542865293537/8.0), REAL_CONST(89419.598809753006/8.0), REAL_CONST(89442.656240494165/8.0), REAL_CONST(89465.715157325409/8.0), REAL_CONST(89488.775560055219/8.0), REAL_CONST(89511.837448492137/8.0), REAL_CONST(89534.900822444746/8.0), REAL_CONST(89557.965681721733/8.0), REAL_CONST(89581.032026131812/8.0), REAL_CONST(89604.099855483742/8.0), REAL_CONST(89627.169169586399/8.0), REAL_CONST(89650.239968248672/8.0), REAL_CONST(89673.312251279538/8.0), REAL_CONST(89696.386018488018/8.0), REAL_CONST(89719.461269683205/8.0), REAL_CONST(89742.53800467425/8.0), REAL_CONST(89765.616223270365/8.0), REAL_CONST(89788.69592528083/8.0), REAL_CONST(89811.777110514988/8.0), REAL_CONST(89834.859778782207/8.0), REAL_CONST(89857.943929891975/8.0), REAL_CONST(89881.029563653807/8.0), REAL_CONST(89904.116679877261/8.0), REAL_CONST(89927.205278372014/8.0), REAL_CONST(89950.29535894774/8.0), REAL_CONST(89973.386921414218/8.0), REAL_CONST(89996.479965581268/8.0), REAL_CONST(90019.574491258769/8.0), REAL_CONST(90042.670498256688/8.0), REAL_CONST(90065.767986385021/8.0), REAL_CONST(90088.866955453836/8.0), REAL_CONST(90111.967405273259/8.0), REAL_CONST(90135.069335653476/8.0), REAL_CONST(90158.172746404758/8.0), REAL_CONST(90181.277637337407/8.0), REAL_CONST(90204.384008261797/8.0), REAL_CONST(90227.49185898836/8.0), REAL_CONST(90250.601189327586/8.0), REAL_CONST(90273.711999090039/8.0), REAL_CONST(90296.824288086325/8.0), REAL_CONST(90319.938056127125/8.0), REAL_CONST(90343.053303023189/8.0), REAL_CONST(90366.170028585286/8.0), REAL_CONST(90389.288232624298/8.0), REAL_CONST(90412.407914951138/8.0), REAL_CONST(90435.529075376777/8.0), REAL_CONST(90458.651713712257/8.0), REAL_CONST(90481.775829768681/8.0), REAL_CONST(90504.901423357209/8.0), REAL_CONST(90528.028494289058/8.0), REAL_CONST(90551.157042375504/8.0), REAL_CONST(90574.287067427911/8.0), REAL_CONST(90597.418569257643/8.0), REAL_CONST(90620.551547676194/8.0), REAL_CONST(90643.686002495073/8.0), REAL_CONST(90666.821933525847/8.0), REAL_CONST(90689.959340580186/8.0), REAL_CONST(90713.098223469773/8.0), REAL_CONST(90736.238582006365/8.0), REAL_CONST(90759.380416001804/8.0), REAL_CONST(90782.523725267951/8.0), REAL_CONST(90805.668509616764/8.0), REAL_CONST(90828.814768860233/8.0), REAL_CONST(90851.962502810435/8.0), REAL_CONST(90875.11171127946/8.0), REAL_CONST(90898.262394079517/8.0), REAL_CONST(90921.414551022855/8.0), REAL_CONST(90944.568181921743/8.0), REAL_CONST(90967.72328658856/8.0), REAL_CONST(90990.879864835719/8.0), REAL_CONST(91014.037916475718/8.0), REAL_CONST(91037.19744132107/8.0), REAL_CONST(91060.358439184391/8.0), REAL_CONST(91083.520909878338/8.0), REAL_CONST(91106.684853215629/8.0), REAL_CONST(91129.850269009039/8.0), REAL_CONST(91153.017157071401/8.0), REAL_CONST(91176.185517215621/8.0), REAL_CONST(91199.355349254649/8.0), REAL_CONST(91222.526653001492/8.0), REAL_CONST(91245.699428269247/8.0), REAL_CONST(91268.873674871036/8.0), REAL_CONST(91292.049392620058/8.0), REAL_CONST(91315.226581329553/8.0), REAL_CONST(91338.405240812834/8.0), REAL_CONST(91361.585370883287/8.0), REAL_CONST(91384.766971354344/8.0), REAL_CONST(91407.950042039476/8.0), REAL_CONST(91431.134582752245/8.0), REAL_CONST(91454.320593306256/8.0), REAL_CONST(91477.508073515171/8.0), REAL_CONST(91500.697023192712/8.0), REAL_CONST(91523.887442152685/8.0), REAL_CONST(91547.07933020893/8.0), REAL_CONST(91570.272687175326/8.0), REAL_CONST(91593.467512865856/8.0), REAL_CONST(91616.663807094534/8.0), REAL_CONST(91639.861569675442/8.0), REAL_CONST(91663.060800422725/8.0), REAL_CONST(91686.261499150554/8.0), REAL_CONST(91709.463665673218/8.0), REAL_CONST(91732.66729980502/8.0), REAL_CONST(91755.872401360321/8.0), REAL_CONST(91779.078970153569/8.0), REAL_CONST(91802.287005999257/8.0), REAL_CONST(91825.49650871192/8.0), REAL_CONST(91848.707478106167/8.0), REAL_CONST(91871.91991399668/8.0), REAL_CONST(91895.133816198169/8.0), REAL_CONST(91918.349184525418/8.0), REAL_CONST(91941.566018793281/8.0), REAL_CONST(91964.784318816659/8.0), REAL_CONST(91988.004084410495/8.0), REAL_CONST(92011.22531538982/8.0), REAL_CONST(92034.448011569708/8.0), REAL_CONST(92057.672172765277/8.0), REAL_CONST(92080.897798791746/8.0), REAL_CONST(92104.124889464365/8.0), REAL_CONST(92127.353444598411/8.0), REAL_CONST(92150.58346400928/8.0), REAL_CONST(92173.814947512379/8.0), REAL_CONST(92197.04789492322/8.0), REAL_CONST(92220.282306057314/8.0), REAL_CONST(92243.518180730272/8.0), REAL_CONST(92266.755518757753/8.0), REAL_CONST(92289.994319955469/8.0), REAL_CONST(92313.234584139194/8.0), REAL_CONST(92336.476311124774/8.0), REAL_CONST(92359.719500728082/8.0), REAL_CONST(92382.964152765067/8.0), REAL_CONST(92406.210267051734/8.0), REAL_CONST(92429.457843404161/8.0), REAL_CONST(92452.706881638471/8.0), REAL_CONST(92475.957381570814/8.0), REAL_CONST(92499.209343017443/8.0), REAL_CONST(92522.462765794655/8.0), REAL_CONST(92545.717649718805/8.0), REAL_CONST(92568.973994606305/8.0), REAL_CONST(92592.231800273614/8.0), REAL_CONST(92615.491066537259/8.0), REAL_CONST(92638.751793213814/8.0), REAL_CONST(92662.01398011994/8.0), REAL_CONST(92685.277627072326/8.0), REAL_CONST(92708.54273388772/8.0), REAL_CONST(92731.809300382942/8.0), REAL_CONST(92755.077326374871/8.0), REAL_CONST(92778.346811680414/8.0), REAL_CONST(92801.617756116568/8.0), REAL_CONST(92824.890159500384/8.0), REAL_CONST(92848.164021648947/8.0), REAL_CONST(92871.439342379424/8.0), REAL_CONST(92894.716121509016/8.0), REAL_CONST(92917.994358855023/8.0), REAL_CONST(92941.274054234746/8.0), REAL_CONST(92964.555207465572/8.0), REAL_CONST(92987.837818364962/8.0), REAL_CONST(93011.121886750407/8.0), REAL_CONST(93034.407412439468/8.0), REAL_CONST(93057.694395249753/8.0), REAL_CONST(93080.982834998955/8.0), REAL_CONST(93104.272731504767/8.0), REAL_CONST(93127.564084584999/8.0), REAL_CONST(93150.856894057491/8.0), REAL_CONST(93174.15115974014/8.0), REAL_CONST(93197.446881450916/8.0), REAL_CONST(93220.744059007804/8.0), REAL_CONST(93244.04269222889/8.0), REAL_CONST(93267.342780932304/8.0), REAL_CONST(93290.644324936235/8.0), REAL_CONST(93313.947324058914/8.0), REAL_CONST(93337.251778118633/8.0), REAL_CONST(93360.557686933767/8.0), REAL_CONST(93383.865050322696/8.0), REAL_CONST(93407.173868103928/8.0), REAL_CONST(93430.484140095941/8.0), REAL_CONST(93453.795866117362/8.0), REAL_CONST(93477.109045986799/8.0), REAL_CONST(93500.423679522952/8.0), REAL_CONST(93523.739766544561/8.0), REAL_CONST(93547.057306870454/8.0), REAL_CONST(93570.376300319491/8.0), REAL_CONST(93593.696746710571/8.0), REAL_CONST(93617.018645862699/8.0), REAL_CONST(93640.341997594893/8.0), REAL_CONST(93663.666801726242/8.0), REAL_CONST(93686.993058075881/8.0), REAL_CONST(93710.320766463032/8.0), REAL_CONST(93733.64992670693/8.0), REAL_CONST(93756.980538626914/8.0), REAL_CONST(93780.312602042337/8.0), REAL_CONST(93803.646116772637/8.0), REAL_CONST(93826.981082637285/8.0), REAL_CONST(93850.317499455836/8.0), REAL_CONST(93873.655367047861/8.0), REAL_CONST(93896.994685233032/8.0), REAL_CONST(93920.335453831038/8.0), REAL_CONST(93943.677672661666/8.0), REAL_CONST(93967.021341544707/8.0), REAL_CONST(93990.366460300051/8.0), REAL_CONST(94013.713028747632/8.0), REAL_CONST(94037.061046707429/8.0), REAL_CONST(94060.410513999494/8.0), REAL_CONST(94083.761430443905/8.0), REAL_CONST(94107.113795860845/8.0), REAL_CONST(94130.467610070496/8.0), REAL_CONST(94153.822872893157/8.0), REAL_CONST(94177.179584149111/8.0), REAL_CONST(94200.537743658759/8.0), REAL_CONST(94223.897351242529/8.0), REAL_CONST(94247.25840672091/8.0), REAL_CONST(94270.620909914433/8.0), REAL_CONST(94293.98486064373/8.0), REAL_CONST(94317.350258729421/8.0), REAL_CONST(94340.71710399224/8.0), REAL_CONST(94364.085396252936/8.0), REAL_CONST(94387.455135332348/8.0), REAL_CONST(94410.82632105134/8.0), REAL_CONST(94434.198953230851/8.0), REAL_CONST(94457.573031691878/8.0), REAL_CONST(94480.948556255447/8.0), REAL_CONST(94504.325526742658/8.0), REAL_CONST(94527.70394297468/8.0), REAL_CONST(94551.083804772716/8.0), REAL_CONST(94574.465111958023/8.0), REAL_CONST(94597.847864351934/8.0), REAL_CONST(94621.232061775823/8.0), REAL_CONST(94644.617704051096/8.0), REAL_CONST(94668.004790999272/8.0), REAL_CONST(94691.393322441872/8.0), REAL_CONST(94714.783298200506/8.0), REAL_CONST(94738.174718096794/8.0), REAL_CONST(94761.567581952477/8.0), REAL_CONST(94784.961889589307/8.0), REAL_CONST(94808.357640829097/8.0), REAL_CONST(94831.754835493703/8.0), REAL_CONST(94855.153473405066/8.0), REAL_CONST(94878.553554385173/8.0), REAL_CONST(94901.955078256055/8.0), REAL_CONST(94925.358044839784/8.0), REAL_CONST(94948.762453958523/8.0), REAL_CONST(94972.168305434476/8.0), REAL_CONST(94995.575599089891/8.0), REAL_CONST(95018.984334747074/8.0), REAL_CONST(95042.394512228391/8.0), REAL_CONST(95065.806131356265/8.0), REAL_CONST(95089.219191953176/8.0), REAL_CONST(95112.633693841635/8.0), REAL_CONST(95136.04963684424/8.0), REAL_CONST(95159.467020783617/8.0), REAL_CONST(95182.885845482466/8.0), REAL_CONST(95206.306110763529/8.0), REAL_CONST(95229.727816449609/8.0), REAL_CONST(95253.150962363579/8.0), REAL_CONST(95276.575548328314/8.0), REAL_CONST(95300.001574166803/8.0), REAL_CONST(95323.429039702052/8.0), REAL_CONST(95346.857944757154/8.0), REAL_CONST(95370.288289155214/8.0), REAL_CONST(95393.720072719429/8.0), REAL_CONST(95417.153295273019/8.0), REAL_CONST(95440.587956639298/8.0), REAL_CONST(95464.024056641589/8.0), REAL_CONST(95487.461595103305/8.0), REAL_CONST(95510.900571847902/8.0), REAL_CONST(95534.340986698866/8.0), REAL_CONST(95557.782839479783/8.0), REAL_CONST(95581.226130014256/8.0), REAL_CONST(95604.670858125959/8.0), REAL_CONST(95628.117023638595/8.0), REAL_CONST(95651.564626375985/8.0), REAL_CONST(95675.013666161918/8.0), REAL_CONST(95698.464142820303/8.0), REAL_CONST(95721.916056175076/8.0), REAL_CONST(95745.369406050231/8.0), REAL_CONST(95768.824192269807/8.0), REAL_CONST(95792.280414657915/8.0), REAL_CONST(95815.738073038709/8.0), REAL_CONST(95839.197167236387/8.0), REAL_CONST(95862.657697075221/8.0), REAL_CONST(95886.11966237954/8.0), REAL_CONST(95909.583062973688/8.0), REAL_CONST(95933.047898682111/8.0), REAL_CONST(95956.514169329268/8.0), REAL_CONST(95979.981874739708/8.0), REAL_CONST(96003.451014738006/8.0), REAL_CONST(96026.921589148798/8.0), REAL_CONST(96050.393597796792/8.0), REAL_CONST(96073.867040506724/8.0), REAL_CONST(96097.341917103375/8.0), REAL_CONST(96120.818227411626/8.0), REAL_CONST(96144.295971256375/8.0), REAL_CONST(96167.775148462577/8.0), REAL_CONST(96191.255758855244/8.0), REAL_CONST(96214.737802259449/8.0), REAL_CONST(96238.221278500292/8.0), REAL_CONST(96261.70618740299/8.0), REAL_CONST(96285.192528792715/8.0), REAL_CONST(96308.680302494788/8.0), REAL_CONST(96332.169508334526/8.0), REAL_CONST(96355.660146137321/8.0), REAL_CONST(96379.152215728609/8.0), REAL_CONST(96402.645716933868/8.0), REAL_CONST(96426.14064957868/8.0), REAL_CONST(96449.637013488609/8.0), REAL_CONST(96473.134808489311/8.0), REAL_CONST(96496.63403440651/8.0), REAL_CONST(96520.134691065963/8.0), REAL_CONST(96543.636778293469/8.0), REAL_CONST(96567.140295914898/8.0), REAL_CONST(96590.645243756153/8.0), REAL_CONST(96614.151621643221/8.0), REAL_CONST(96637.659429402134/8.0), REAL_CONST(96661.168666858954/8.0), REAL_CONST(96684.679333839798/8.0), REAL_CONST(96708.191430170875/8.0), REAL_CONST(96731.70495567839/8.0), REAL_CONST(96755.219910188665/8.0), REAL_CONST(96778.736293528011/8.0), REAL_CONST(96802.254105522836/8.0), REAL_CONST(96825.77334599958/8.0), REAL_CONST(96849.29401478474/8.0), REAL_CONST(96872.816111704873/8.0), REAL_CONST(96896.339636586577/8.0), REAL_CONST(96919.864589256511/8.0), REAL_CONST(96943.390969541389/8.0), REAL_CONST(96966.918777267958/8.0), REAL_CONST(96990.448012263048/8.0), REAL_CONST(97013.978674353522/8.0), REAL_CONST(97037.510763366285/8.0), REAL_CONST(97061.044279128328/8.0), REAL_CONST(97084.579221466673/8.0), REAL_CONST(97108.115590208385/8.0), REAL_CONST(97131.653385180587/8.0), REAL_CONST(97155.19260621049/8.0), REAL_CONST(97178.733253125291/8.0), REAL_CONST(97202.2753257523/8.0), REAL_CONST(97225.81882391886/8.0), REAL_CONST(97249.363747452342/8.0), REAL_CONST(97272.910096180189/8.0), REAL_CONST(97296.457869929916/8.0), REAL_CONST(97320.007068529041/8.0), REAL_CONST(97343.557691805196/8.0), REAL_CONST(97367.109739586012/8.0), REAL_CONST(97390.663211699197/8.0), REAL_CONST(97414.218107972498/8.0), REAL_CONST(97437.774428233737/8.0), REAL_CONST(97461.332172310766/8.0), REAL_CONST(97484.891340031507/8.0), REAL_CONST(97508.451931223899/8.0), REAL_CONST(97532.013945715982/8.0), REAL_CONST(97555.577383335811/8.0), REAL_CONST(97579.142243911512/8.0), REAL_CONST(97602.708527271257/8.0), REAL_CONST(97626.276233243261/8.0), REAL_CONST(97649.845361655811/8.0), REAL_CONST(97673.415912337223/8.0), REAL_CONST(97696.987885115886/8.0), REAL_CONST(97720.561279820206/8.0), REAL_CONST(97744.1360962787/8.0), REAL_CONST(97767.712334319876/8.0), REAL_CONST(97791.289993772341/8.0), REAL_CONST(97814.869074464703/8.0), REAL_CONST(97838.449576225685/8.0), REAL_CONST(97862.031498883996/8.0), REAL_CONST(97885.614842268449/8.0), REAL_CONST(97909.199606207883/8.0), REAL_CONST(97932.785790531183/8.0), REAL_CONST(97956.37339506732/8.0), REAL_CONST(97979.962419645264/8.0), REAL_CONST(98003.552864094076/8.0), REAL_CONST(98027.144728242856/8.0), REAL_CONST(98050.738011920766/8.0), REAL_CONST(98074.332714956996/8.0), REAL_CONST(98097.928837180807/8.0), REAL_CONST(98121.526378421506/8.0), REAL_CONST(98145.125338508456/8.0), REAL_CONST(98168.725717271067/8.0), REAL_CONST(98192.327514538789/8.0), REAL_CONST(98215.930730141132/8.0), REAL_CONST(98239.535363907664/8.0), REAL_CONST(98263.141415668011/8.0), REAL_CONST(98286.748885251814/8.0), REAL_CONST(98310.357772488816/8.0), REAL_CONST(98333.968077208759/8.0), REAL_CONST(98357.579799241488/8.0), REAL_CONST(98381.192938416847/8.0), REAL_CONST(98404.807494564782/8.0), REAL_CONST(98428.42346751524/8.0), REAL_CONST(98452.040857098269/8.0), REAL_CONST(98475.659663143917/8.0), REAL_CONST(98499.27988548232/8.0), REAL_CONST(98522.901523943656/8.0), REAL_CONST(98546.524578358163/8.0), REAL_CONST(98570.149048556093/8.0), REAL_CONST(98593.774934367786/8.0), REAL_CONST(98617.402235623624/8.0), REAL_CONST(98641.030952154048/8.0), REAL_CONST(98664.661083789513/8.0), REAL_CONST(98688.292630360564/8.0), REAL_CONST(98711.925591697771/8.0), REAL_CONST(98735.559967631794/8.0), REAL_CONST(98759.195757993293/8.0), REAL_CONST(98782.832962613014/8.0), REAL_CONST(98806.471581321734/8.0), REAL_CONST(98830.111613950285/8.0), REAL_CONST(98853.753060329575/8.0), REAL_CONST(98877.39592029051/8.0), REAL_CONST(98901.040193664099/8.0), REAL_CONST(98924.68588028138/8.0), REAL_CONST(98948.33297997342/8.0), REAL_CONST(98971.981492571387/8.0), REAL_CONST(98995.63141790645/8.0), REAL_CONST(99019.282755809851/8.0), REAL_CONST(99042.935506112874/8.0), REAL_CONST(99066.589668646877/8.0), REAL_CONST(99090.245243243233/8.0), REAL_CONST(99113.902229733401/8.0), REAL_CONST(99137.560627948857/8.0), REAL_CONST(99161.220437721131/8.0), REAL_CONST(99184.881658881859/8.0), REAL_CONST(99208.544291262631/8.0), REAL_CONST(99232.208334695169/8.0), REAL_CONST(99255.87378901121/8.0), REAL_CONST(99279.540654042547/8.0), REAL_CONST(99303.208929621018/8.0), REAL_CONST(99326.878615578535/8.0), REAL_CONST(99350.549711746993/8.0), REAL_CONST(99374.222217958435/8.0), REAL_CONST(99397.896134044888/8.0), REAL_CONST(99421.571459838422/8.0), REAL_CONST(99445.248195171211/8.0), REAL_CONST(99468.926339875441/8.0), REAL_CONST(99492.605893783344/8.0), REAL_CONST(99516.286856727209/8.0), REAL_CONST(99539.969228539398/8.0), REAL_CONST(99563.653009052287/8.0), REAL_CONST(99587.338198098325/8.0), REAL_CONST(99611.024795510006/8.0), REAL_CONST(99634.712801119866/8.0), REAL_CONST(99658.402214760499/8.0), REAL_CONST(99682.093036264545/8.0), REAL_CONST(99705.785265464699/8.0), REAL_CONST(99729.478902193689/8.0), REAL_CONST(99753.173946284325/8.0), REAL_CONST(99776.870397569437/8.0), REAL_CONST(99800.56825588191/8.0), REAL_CONST(99824.267521054688/8.0), REAL_CONST(99847.968192920773/8.0), REAL_CONST(99871.670271313182/8.0), REAL_CONST(99895.373756065004/8.0), REAL_CONST(99919.078647009388/8.0), REAL_CONST(99942.78494397951/8.0), REAL_CONST(99966.492646808634/8.0), REAL_CONST(99990.20175533001/8.0), REAL_CONST(100013.91226937699/8.0), REAL_CONST(100037.62418878295/8.0), REAL_CONST(100061.33751338134/8.0), REAL_CONST(100085.05224300563/8.0), REAL_CONST(100108.76837748935/8.0), REAL_CONST(100132.4859166661/8.0), REAL_CONST(100156.2048603695/8.0), REAL_CONST(100179.92520843323/8.0), REAL_CONST(100203.64696069101/8.0), REAL_CONST(100227.37011697664/8.0), REAL_CONST(100251.09467712394/8.0), REAL_CONST(100274.82064096678/8.0), REAL_CONST(100298.54800833909/8.0), REAL_CONST(100322.27677907483/8.0), REAL_CONST(100346.00695300807/8.0), REAL_CONST(100369.73852997283/8.0), REAL_CONST(100393.47150980328/8.0), REAL_CONST(100417.20589233354/8.0), REAL_CONST(100440.94167739789/8.0), REAL_CONST(100464.67886483055/8.0), REAL_CONST(100488.41745446586/8.0), REAL_CONST(100512.1574461382/8.0), REAL_CONST(100535.89883968196/8.0), REAL_CONST(100559.64163493161/8.0), REAL_CONST(100583.38583172169/8.0), REAL_CONST(100607.13142988674/8.0), REAL_CONST(100630.87842926137/8.0), REAL_CONST(100654.62682968024/8.0), REAL_CONST(100678.37663097809/8.0), REAL_CONST(100702.12783298964/8.0), REAL_CONST(100725.88043554971/8.0), REAL_CONST(100749.63443849317/8.0), REAL_CONST(100773.38984165489/8.0), REAL_CONST(100797.14664486986/8.0), REAL_CONST(100820.90484797307/8.0), REAL_CONST(100844.66445079957/8.0), REAL_CONST(100868.42545318443/8.0), REAL_CONST(100892.18785496285/8.0), REAL_CONST(100915.95165596998/8.0), REAL_CONST(100939.71685604109/8.0), REAL_CONST(100963.48345501146/8.0), REAL_CONST(100987.25145271645/8.0), REAL_CONST(101011.02084899142/8.0), REAL_CONST(101034.79164367182/8.0), REAL_CONST(101058.56383659317/8.0), REAL_CONST(101082.33742759094/8.0), REAL_CONST(101106.11241650078/8.0), REAL_CONST(101129.88880315828/8.0), REAL_CONST(101153.66658739912/8.0), REAL_CONST(101177.44576905905/8.0), REAL_CONST(101201.22634797383/8.0), REAL_CONST(101225.00832397929/8.0), REAL_CONST(101248.7916969113/8.0), REAL_CONST(101272.57646660579/8.0), REAL_CONST(101296.36263289873/8.0), REAL_CONST(101320.15019562612/8.0), REAL_CONST(101343.93915462404/8.0), REAL_CONST(101367.7295097286/8.0), REAL_CONST(101391.52126077596/8.0), REAL_CONST(101415.31440760233/8.0), REAL_CONST(101439.10895004397/8.0), REAL_CONST(101462.9048879372/8.0), REAL_CONST(101486.70222111834/8.0), REAL_CONST(101510.50094942382/8.0), REAL_CONST(101534.30107269008/8.0), REAL_CONST(101558.10259075361/8.0), REAL_CONST(101581.90550345098/8.0), REAL_CONST(101605.70981061876/8.0), REAL_CONST(101629.5155120936/8.0), REAL_CONST(101653.32260771218/8.0), REAL_CONST(101677.13109731126/8.0), REAL_CONST(101700.9409807276/8.0), REAL_CONST(101724.75225779804/8.0), REAL_CONST(101748.56492835947/8.0), REAL_CONST(101772.37899224881/8.0), REAL_CONST(101796.19444930303/8.0), REAL_CONST(101820.01129935916/8.0), REAL_CONST(101843.82954225427/8.0), REAL_CONST(101867.64917782549/8.0), REAL_CONST(101891.47020590997/8.0), REAL_CONST(101915.29262634492/8.0), REAL_CONST(101939.11643896763/8.0), REAL_CONST(101962.94164361537/8.0), REAL_CONST(101986.76824012553/8.0), REAL_CONST(102010.59622833549/8.0), REAL_CONST(102034.42560808272/8.0), REAL_CONST(102058.25637920471/8.0), REAL_CONST(102082.08854153901/8.0), REAL_CONST(102105.9220949232/8.0), REAL_CONST(102129.75703919494/8.0), REAL_CONST(102153.59337419191/8.0), REAL_CONST(102177.43109975185/8.0), REAL_CONST(102201.27021571253/8.0), REAL_CONST(102225.1107219118/8.0), REAL_CONST(102248.95261818753/8.0), REAL_CONST(102272.79590437764/8.0), REAL_CONST(102296.64058032009/8.0), REAL_CONST(102320.48664585294/8.0), REAL_CONST(102344.33410081422/8.0), REAL_CONST(102368.18294504205/8.0), REAL_CONST(102392.03317837461/8.0), REAL_CONST(102415.88480065008/8.0), REAL_CONST(102439.73781170673/8.0), REAL_CONST(102463.59221138287/8.0), REAL_CONST(102487.44799951684/8.0), REAL_CONST(102511.30517594704/8.0), REAL_CONST(102535.1637405119/8.0), REAL_CONST(102559.02369304992/8.0), REAL_CONST(102582.88503339965/8.0), REAL_CONST(102606.74776139967/8.0), REAL_CONST(102630.61187688859/8.0), REAL_CONST(102654.4773797051/8.0), REAL_CONST(102678.34426968795/8.0), REAL_CONST(102702.21254667587/8.0), REAL_CONST(102726.08221050771/8.0), REAL_CONST(102749.95326102231/8.0), REAL_CONST(102773.8256980586/8.0), REAL_CONST(102797.69952145554/8.0), REAL_CONST(102821.57473105213/8.0), REAL_CONST(102845.45132668741/8.0), REAL_CONST(102869.32930820051/8.0), REAL_CONST(102893.20867543056/8.0), REAL_CONST(102917.08942821674/8.0), REAL_CONST(102940.97156639832/8.0), REAL_CONST(102964.85508981455/8.0), REAL_CONST(102988.73999830478/8.0), REAL_CONST(103012.6262917084/8.0), REAL_CONST(103036.51396986481/8.0), REAL_CONST(103060.40303261351/8.0), REAL_CONST(103084.293479794/8.0), REAL_CONST(103108.18531124585/8.0), REAL_CONST(103132.07852680866/8.0), REAL_CONST(103155.97312632212/8.0), REAL_CONST(103179.8691096259/8.0), REAL_CONST(103203.76647655977/8.0), REAL_CONST(103227.66522696352/8.0), REAL_CONST(103251.56536067701/8.0), REAL_CONST(103275.46687754011/8.0), REAL_CONST(103299.36977739276/8.0), REAL_CONST(103323.27406007495/8.0), REAL_CONST(103347.1797254267/8.0), REAL_CONST(103371.0867732881/8.0), REAL_CONST(103394.99520349925/8.0), REAL_CONST(103418.90501590034/8.0), REAL_CONST(103442.81621033157/8.0), REAL_CONST(103466.72878663319/8.0), REAL_CONST(103490.64274464553/8.0), REAL_CONST(103514.55808420894/8.0), REAL_CONST(103538.4748051638/8.0), REAL_CONST(103562.39290735057/8.0), REAL_CONST(103586.31239060973/8.0), REAL_CONST(103610.23325478184/8.0), REAL_CONST(103634.15549970744/8.0), REAL_CONST(103658.07912522719/8.0), REAL_CONST(103682.00413118176/8.0), REAL_CONST(103705.93051741188/8.0), REAL_CONST(103729.85828375829/8.0), REAL_CONST(103753.78743006183/8.0), REAL_CONST(103777.71795616332/8.0), REAL_CONST(103801.64986190372/8.0), REAL_CONST(103825.58314712394/8.0), REAL_CONST(103849.51781166498/8.0), REAL_CONST(103873.4538553679/8.0), REAL_CONST(103897.39127807376/8.0), REAL_CONST(103921.33007962372/8.0), REAL_CONST(103945.27025985894/8.0), REAL_CONST(103969.21181862066/8.0), REAL_CONST(103993.15475575015/8.0), REAL_CONST(104017.0990710887/8.0), REAL_CONST(104041.0447644777/8.0), REAL_CONST(104064.99183575854/8.0), REAL_CONST(104088.94028477269/8.0), REAL_CONST(104112.89011136163/8.0), REAL_CONST(104136.84131536692/8.0), REAL_CONST(104160.79389663014/8.0), REAL_CONST(104184.74785499295/8.0), REAL_CONST(104208.70319029699/8.0), REAL_CONST(104232.65990238401/8.0), REAL_CONST(104256.61799109577/8.0), REAL_CONST(104280.57745627411/8.0), REAL_CONST(104304.53829776087/8.0), REAL_CONST(104328.50051539797/8.0), REAL_CONST(104352.46410902737/8.0), REAL_CONST(104376.42907849104/8.0), REAL_CONST(104400.39542363105/8.0), REAL_CONST(104424.36314428948/8.0), REAL_CONST(104448.33224030846/8.0), REAL_CONST(104472.3027115302/8.0), REAL_CONST(104496.27455779689/8.0), REAL_CONST(104520.24777895081/8.0), REAL_CONST(104544.22237483428/8.0), REAL_CONST(104568.19834528965/8.0), REAL_CONST(104592.17569015936/8.0), REAL_CONST(104616.15440928582/8.0), REAL_CONST(104640.13450251156/8.0), REAL_CONST(104664.1159696791/8.0), REAL_CONST(104688.09881063103/8.0), REAL_CONST(104712.08302520998/8.0), REAL_CONST(104736.06861325864/8.0), REAL_CONST(104760.05557461972/8.0), REAL_CONST(104784.043909136/8.0), REAL_CONST(104808.03361665027/8.0), REAL_CONST(104832.0246970054/8.0), REAL_CONST(104856.01715004431/8.0), REAL_CONST(104880.01097560991/8.0), REAL_CONST(104904.00617354522/8.0), REAL_CONST(104928.00274369326/8.0), REAL_CONST(104952.00068589712/8.0), REAL_CONST(104975.99999999993/8.0), REAL_CONST(105000.00068584486/8.0), REAL_CONST(105024.00274327511/8.0), REAL_CONST(105048.00617213396/8.0), REAL_CONST(105072.0109722647/8.0), REAL_CONST(105096.0171435107/8.0), REAL_CONST(105120.02468571534/8.0), REAL_CONST(105144.03359872208/8.0), REAL_CONST(105168.04388237436/8.0), REAL_CONST(105192.05553651576/8.0), REAL_CONST(105216.06856098982/8.0), REAL_CONST(105240.08295564017/8.0), REAL_CONST(105264.09872031047/8.0), REAL_CONST(105288.11585484444/8.0), REAL_CONST(105312.13435908582/8.0), REAL_CONST(105336.1542328784/8.0), REAL_CONST(105360.17547606604/8.0), REAL_CONST(105384.19808849262/8.0), REAL_CONST(105408.22207000206/8.0), REAL_CONST(105432.24742043833/8.0), REAL_CONST(105456.27413964548/8.0), REAL_CONST(105480.30222746753/8.0), REAL_CONST(105504.33168374863/8.0), REAL_CONST(105528.36250833291/8.0), REAL_CONST(105552.39470106458/8.0), REAL_CONST(105576.42826178786/8.0), REAL_CONST(105600.46319034706/8.0), REAL_CONST(105624.49948658649/8.0), REAL_CONST(105648.53715035053/8.0), REAL_CONST(105672.5761814836/8.0), REAL_CONST(105696.61657983017/8.0), REAL_CONST(105720.65834523473/8.0), REAL_CONST(105744.70147754184/8.0), REAL_CONST(105768.7459765961/8.0), REAL_CONST(105792.79184224214/8.0), REAL_CONST(105816.83907432464/8.0), REAL_CONST(105840.88767268835/8.0), REAL_CONST(105864.93763717801/8.0), REAL_CONST(105888.98896763846/8.0), REAL_CONST(105913.04166391456/8.0), REAL_CONST(105937.09572585119/8.0), REAL_CONST(105961.15115329332/8.0), REAL_CONST(105985.20794608595/8.0), REAL_CONST(106009.26610407409/8.0), REAL_CONST(106033.32562710284/8.0), REAL_CONST(106057.38651501729/8.0), REAL_CONST(106081.44876766266/8.0), REAL_CONST(106105.51238488412/8.0), REAL_CONST(106129.57736652695/8.0), REAL_CONST(106153.64371243643/8.0), REAL_CONST(106177.71142245791/8.0), REAL_CONST(106201.78049643678/8.0), REAL_CONST(106225.85093421848/8.0), REAL_CONST(106249.92273564848/8.0), REAL_CONST(106273.99590057228/8.0), REAL_CONST(106298.07042883546/8.0), REAL_CONST(106322.14632028362/8.0), REAL_CONST(106346.22357476239/8.0), REAL_CONST(106370.30219211751/8.0), REAL_CONST(106394.38217219469/8.0), REAL_CONST(106418.46351483969/8.0), REAL_CONST(106442.54621989837/8.0), REAL_CONST(106466.63028721658/8.0), REAL_CONST(106490.71571664025/8.0), REAL_CONST(106514.80250801529/8.0), REAL_CONST(106538.89066118775/8.0), REAL_CONST(106562.98017600364/8.0), REAL_CONST(106587.07105230905/8.0), REAL_CONST(106611.16328995011/8.0), REAL_CONST(106635.25688877302/8.0), REAL_CONST(106659.35184862395/8.0), REAL_CONST(106683.44816934918/8.0), REAL_CONST(106707.54585079502/8.0), REAL_CONST(106731.64489280782/8.0), REAL_CONST(106755.74529523395/8.0), REAL_CONST(106779.84705791986/8.0), REAL_CONST(106803.95018071201/8.0), REAL_CONST(106828.05466345693/8.0), REAL_CONST(106852.16050600118/8.0), REAL_CONST(106876.26770819137/8.0), REAL_CONST(106900.37626987413/8.0), REAL_CONST(106924.48619089619/8.0), REAL_CONST(106948.59747110425/8.0), REAL_CONST(106972.71011034511/8.0), REAL_CONST(106996.82410846559/8.0), REAL_CONST(107020.93946531253/8.0), REAL_CONST(107045.05618073288/8.0), REAL_CONST(107069.17425457356/8.0), REAL_CONST(107093.29368668159/8.0), REAL_CONST(107117.41447690397/8.0), REAL_CONST(107141.53662508781/8.0), REAL_CONST(107165.66013108024/8.0), REAL_CONST(107189.7849947284/8.0), REAL_CONST(107213.91121587952/8.0), REAL_CONST(107238.03879438085/8.0), REAL_CONST(107262.16773007967/8.0), REAL_CONST(107286.29802282334/8.0), REAL_CONST(107310.42967245923/8.0), REAL_CONST(107334.56267883476/8.0), REAL_CONST(107358.69704179741/8.0), REAL_CONST(107382.83276119467/8.0), REAL_CONST(107406.96983687414/8.0), REAL_CONST(107431.10826868335/8.0), REAL_CONST(107455.24805646999/8.0), REAL_CONST(107479.38920008171/8.0), REAL_CONST(107503.53169936626/8.0), REAL_CONST(107527.67555417139/8.0), REAL_CONST(107551.82076434491/8.0), REAL_CONST(107575.96732973469/8.0), REAL_CONST(107600.11525018861/8.0), REAL_CONST(107624.26452555459/8.0), REAL_CONST(107648.41515568066/8.0), REAL_CONST(107672.56714041479/8.0), REAL_CONST(107696.72047960508/8.0), REAL_CONST(107720.87517309963/8.0), REAL_CONST(107745.03122074658/8.0), REAL_CONST(107769.18862239413/8.0), REAL_CONST(107793.34737789053/8.0), REAL_CONST(107817.50748708403/8.0), REAL_CONST(107841.66894982298/8.0), REAL_CONST(107865.83176595572/8.0), REAL_CONST(107889.99593533068/8.0), REAL_CONST(107914.16145779629/8.0), REAL_CONST(107938.32833320105/8.0), REAL_CONST(107962.49656139348/8.0), REAL_CONST(107986.66614222217/8.0), REAL_CONST(108010.83707553572/8.0), REAL_CONST(108035.00936118282/8.0), REAL_CONST(108059.18299901215/8.0), REAL_CONST(108083.35798887245/8.0), REAL_CONST(108107.53433061253/8.0), REAL_CONST(108131.71202408121/8.0), REAL_CONST(108155.89106912735/8.0), REAL_CONST(108180.07146559987/8.0), REAL_CONST(108204.25321334775/8.0), REAL_CONST(108228.43631221994/8.0), REAL_CONST(108252.62076206553/8.0), REAL_CONST(108276.80656273357/8.0), REAL_CONST(108300.99371407321/8.0), REAL_CONST(108325.18221593359/8.0), REAL_CONST(108349.37206816394/8.0), REAL_CONST(108373.56327061349/8.0), REAL_CONST(108397.75582313156/8.0), REAL_CONST(108421.94972556747/8.0), REAL_CONST(108446.1449777706/8.0), REAL_CONST(108470.34157959036/8.0), REAL_CONST(108494.53953087622/8.0), REAL_CONST(108518.73883147769/8.0), REAL_CONST(108542.93948124432/8.0), REAL_CONST(108567.14148002568/8.0), REAL_CONST(108591.34482767139/8.0), REAL_CONST(108615.54952403114/8.0), REAL_CONST(108639.75556895464/8.0), REAL_CONST(108663.96296229165/8.0), REAL_CONST(108688.17170389196/8.0), REAL_CONST(108712.38179360541/8.0), REAL_CONST(108736.59323128188/8.0), REAL_CONST(108760.80601677128/8.0), REAL_CONST(108785.02014992358/8.0), REAL_CONST(108809.23563058881/8.0), REAL_CONST(108833.45245861699/8.0), REAL_CONST(108857.67063385822/8.0), REAL_CONST(108881.89015616261/8.0), REAL_CONST(108906.11102538036/8.0), REAL_CONST(108930.33324136167/8.0), REAL_CONST(108954.55680395682/8.0), REAL_CONST(108978.78171301607/8.0), REAL_CONST(109003.00796838976/8.0), REAL_CONST(109027.23556992831/8.0), REAL_CONST(109051.46451748211/8.0), REAL_CONST(109075.69481090162/8.0), REAL_CONST(109099.92645003737/8.0), REAL_CONST(109124.15943473989/8.0), REAL_CONST(109148.39376485976/8.0), REAL_CONST(109172.62944024763/8.0), REAL_CONST(109196.86646075416/8.0), REAL_CONST(109221.10482623006/8.0), REAL_CONST(109245.34453652608/8.0), REAL_CONST(109269.58559149304/8.0), REAL_CONST(109293.82799098175/8.0), REAL_CONST(109318.07173484311/8.0), REAL_CONST(109342.31682292801/8.0), REAL_CONST(109366.56325508743/8.0), REAL_CONST(109390.81103117237/8.0), REAL_CONST(109415.06015103387/8.0), REAL_CONST(109439.31061452301/8.0), REAL_CONST(109463.56242149093/8.0), REAL_CONST(109487.8155717888/8.0), REAL_CONST(109512.07006526781/8.0), REAL_CONST(109536.3259017792/8.0), REAL_CONST(109560.58308117429/8.0), REAL_CONST(109584.8416033044/8.0), REAL_CONST(109609.1014680209/8.0), REAL_CONST(109633.36267517522/8.0), REAL_CONST(109657.62522461878/8.0), REAL_CONST(109681.88911620311/8.0), REAL_CONST(109706.15434977971/8.0), REAL_CONST(109730.4209252002/8.0), REAL_CONST(109754.68884231619/8.0), REAL_CONST(109778.95810097932/8.0), REAL_CONST(109803.22870104131/8.0), REAL_CONST(109827.50064235389/8.0), REAL_CONST(109851.77392476884/8.0), REAL_CONST(109876.04854813802/8.0), REAL_CONST(109900.32451231324/8.0), REAL_CONST(109924.60181714644/8.0), REAL_CONST(109948.88046248957/8.0), REAL_CONST(109973.1604481946/8.0), REAL_CONST(109997.44177411357/8.0), REAL_CONST(110021.72444009855/8.0), REAL_CONST(110046.00844600165/8.0), REAL_CONST(110070.29379167501/8.0), REAL_CONST(110094.58047697082/8.0), REAL_CONST(110118.86850174134/8.0), REAL_CONST(110143.15786583882/8.0), REAL_CONST(110167.44856911557/8.0), REAL_CONST(110191.74061142397/8.0), REAL_CONST(110216.03399261639/8.0), REAL_CONST(110240.32871254528/8.0), REAL_CONST(110264.62477106311/8.0), REAL_CONST(110288.9221680224/8.0), REAL_CONST(110313.22090327571/8.0), REAL_CONST(110337.52097667565/8.0), REAL_CONST(110361.82238807483/8.0), REAL_CONST(110386.12513732594/8.0), REAL_CONST(110410.42922428172/8.0), REAL_CONST(110434.73464879491/8.0), REAL_CONST(110459.04141071832/8.0), REAL_CONST(110483.34950990479/8.0), REAL_CONST(110507.6589462072/8.0), REAL_CONST(110531.96971947847/8.0), REAL_CONST(110556.28182957157/8.0), REAL_CONST(110580.5952763395/8.0), REAL_CONST(110604.91005963532/8.0), REAL_CONST(110629.22617931209/8.0), REAL_CONST(110653.54363522294/8.0), REAL_CONST(110677.86242722106/8.0), REAL_CONST(110702.18255515963/8.0), REAL_CONST(110726.50401889188/8.0), REAL_CONST(110750.82681827113/8.0), REAL_CONST(110775.1509531507/8.0), REAL_CONST(110799.47642338395/8.0), REAL_CONST(110823.80322882428/8.0), REAL_CONST(110848.13136932514/8.0), REAL_CONST(110872.46084474004/8.0), REAL_CONST(110896.79165492248/8.0), REAL_CONST(110921.12379972603/8.0), REAL_CONST(110945.4572790043/8.0), REAL_CONST(110969.79209261097/8.0), REAL_CONST(110994.12824039967/8.0), REAL_CONST(111018.46572222417/8.0), REAL_CONST(111042.80453793822/8.0), REAL_CONST(111067.14468739564/8.0), REAL_CONST(111091.48617045028/8.0), REAL_CONST(111115.82898695602/8.0), REAL_CONST(111140.1731367668/8.0), REAL_CONST(111164.51861973655/8.0), REAL_CONST(111188.86543571933/8.0), REAL_CONST(111213.21358456917/8.0), REAL_CONST(111237.56306614014/8.0), REAL_CONST(111261.91388028639/8.0), REAL_CONST(111286.26602686207/8.0), REAL_CONST(111310.61950572141/8.0), REAL_CONST(111334.97431671864/8.0), REAL_CONST(111359.33045970804/8.0), REAL_CONST(111383.68793454397/8.0), REAL_CONST(111408.04674108078/8.0), REAL_CONST(111432.40687917286/8.0), REAL_CONST(111456.76834867468/8.0), REAL_CONST(111481.13114944073/8.0), REAL_CONST(111505.49528132551/8.0), REAL_CONST(111529.86074418361/8.0), REAL_CONST(111554.22753786964/8.0), REAL_CONST(111578.59566223821/8.0), REAL_CONST(111602.96511714405/8.0), REAL_CONST(111627.33590244185/8.0), REAL_CONST(111651.7080179864/8.0), REAL_CONST(111676.08146363248/8.0), REAL_CONST(111700.45623923496/8.0), REAL_CONST(111724.8323446487/8.0), REAL_CONST(111749.20977972864/8.0), REAL_CONST(111773.58854432974/8.0), REAL_CONST(111797.96863830699/8.0), REAL_CONST(111822.35006151545/8.0), REAL_CONST(111846.73281381019/8.0), REAL_CONST(111871.11689504632/8.0), REAL_CONST(111895.50230507903/8.0), REAL_CONST(111919.8890437635/8.0), REAL_CONST(111944.27711095495/8.0), REAL_CONST(111968.6665065087/8.0), REAL_CONST(111993.05723028004/8.0), REAL_CONST(112017.44928212435/8.0), REAL_CONST(112041.842661897/8.0), REAL_CONST(112066.23736945343/8.0), REAL_CONST(112090.63340464912/8.0), REAL_CONST(112115.03076733962/8.0), REAL_CONST(112139.42945738042/8.0), REAL_CONST(112163.82947462716/8.0), REAL_CONST(112188.23081893545/8.0), REAL_CONST(112212.63349016097/8.0), REAL_CONST(112237.03748815943/8.0), REAL_CONST(112261.44281278658/8.0), REAL_CONST(112285.84946389822/8.0), REAL_CONST(112310.25744135017/8.0), REAL_CONST(112334.66674499828/8.0), REAL_CONST(112359.07737469849/8.0), REAL_CONST(112383.48933030672/8.0), REAL_CONST(112407.90261167898/8.0), REAL_CONST(112432.31721867126/8.0), REAL_CONST(112456.73315113965/8.0), REAL_CONST(112481.15040894024/8.0), REAL_CONST(112505.56899192919/8.0), REAL_CONST(112529.98889996267/8.0), REAL_CONST(112554.41013289688/8.0), REAL_CONST(112578.8326905881/8.0), REAL_CONST(112603.25657289263/8.0), REAL_CONST(112627.68177966679/8.0), REAL_CONST(112652.10831076698/8.0), REAL_CONST(112676.53616604958/8.0), REAL_CONST(112700.96534537108/8.0), REAL_CONST(112725.39584858794/8.0), REAL_CONST(112749.82767555672/8.0), REAL_CONST(112774.26082613398/8.0), REAL_CONST(112798.6953001763/8.0), REAL_CONST(112823.13109754038/8.0), REAL_CONST(112847.56821808286/8.0), REAL_CONST(112872.00666166049/8.0), REAL_CONST(112896.44642813003/8.0), REAL_CONST(112920.88751734827/8.0), REAL_CONST(112945.32992917208/8.0), REAL_CONST(112969.77366345831/8.0), REAL_CONST(112994.21872006389/8.0), REAL_CONST(113018.66509884578/8.0), REAL_CONST(113043.11279966099/8.0), REAL_CONST(113067.56182236652/8.0), REAL_CONST(113092.01216681948/8.0), REAL_CONST(113116.46383287695/8.0), REAL_CONST(113140.9168203961/8.0), REAL_CONST(113165.37112923413/8.0), REAL_CONST(113189.82675924824/8.0), REAL_CONST(113214.28371029573/8.0), REAL_CONST(113238.74198223387/8.0), REAL_CONST(113263.20157492002/8.0), REAL_CONST(113287.66248821157/8.0), REAL_CONST(113312.12472196593/8.0), REAL_CONST(113336.58827604055/8.0), REAL_CONST(113361.05315029295/8.0), REAL_CONST(113385.51934458067/8.0), REAL_CONST(113409.98685876124/8.0), REAL_CONST(113434.45569269233/8.0), REAL_CONST(113458.92584623155/8.0), REAL_CONST(113483.39731923661/8.0), REAL_CONST(113507.87011156522/8.0), REAL_CONST(113532.34422307517/8.0), REAL_CONST(113556.81965362425/8.0), REAL_CONST(113581.2964030703/8.0), REAL_CONST(113605.77447127122/8.0), REAL_CONST(113630.25385808491/8.0), REAL_CONST(113654.73456336933/8.0), REAL_CONST(113679.2165869825/8.0), REAL_CONST(113703.69992878241/8.0), REAL_CONST(113728.18458862718/8.0), REAL_CONST(113752.67056637487/8.0), REAL_CONST(113777.15786188368/8.0), REAL_CONST(113801.64647501177/8.0), REAL_CONST(113826.13640561736/8.0), REAL_CONST(113850.62765355874/8.0), REAL_CONST(113875.12021869418/8.0), REAL_CONST(113899.61410088204/8.0), REAL_CONST(113924.1092999807/8.0), REAL_CONST(113948.60581584855/8.0), REAL_CONST(113973.10364834407/8.0), REAL_CONST(113997.60279732574/8.0), REAL_CONST(114022.1032626521/8.0), REAL_CONST(114046.60504418171/8.0), REAL_CONST(114071.10814177318/8.0), REAL_CONST(114095.61255528514/8.0), REAL_CONST(114120.11828457628/8.0), REAL_CONST(114144.62532950533/8.0), REAL_CONST(114169.13368993104/8.0), REAL_CONST(114193.6433657122/8.0), REAL_CONST(114218.15435670764/8.0), REAL_CONST(114242.66666277625/8.0), REAL_CONST(114267.18028377694/8.0), REAL_CONST(114291.69521956862/8.0), REAL_CONST(114316.21147001031/8.0), REAL_CONST(114340.72903496103/8.0), REAL_CONST(114365.24791427983/8.0), REAL_CONST(114389.7681078258/8.0), REAL_CONST(114414.2896154581/8.0), REAL_CONST(114438.81243703589/8.0), REAL_CONST(114463.33657241837/8.0), REAL_CONST(114487.8620214648/8.0), REAL_CONST(114512.38878403447/8.0), REAL_CONST(114536.91685998671/8.0), REAL_CONST(114561.44624918087/8.0), REAL_CONST(114585.97695147636/8.0), REAL_CONST(114610.5089667326/8.0), REAL_CONST(114635.04229480909/8.0), REAL_CONST(114659.57693556532/8.0), REAL_CONST(114684.11288886084/8.0), REAL_CONST(114708.65015455526/8.0), REAL_CONST(114733.18873250818/8.0), REAL_CONST(114757.72862257928/8.0), REAL_CONST(114782.26982462825/8.0), REAL_CONST(114806.81233851484/8.0), REAL_CONST(114831.35616409882/8.0), REAL_CONST(114855.90130123998/8.0), REAL_CONST(114880.44774979822/8.0), REAL_CONST(114904.99550963337/8.0), REAL_CONST(114929.5445806054/8.0), REAL_CONST(114954.09496257425/8.0), REAL_CONST(114978.64665539992/8.0), REAL_CONST(115003.19965894247/8.0), REAL_CONST(115027.75397306195/8.0), REAL_CONST(115052.30959761847/8.0), REAL_CONST(115076.86653247218/8.0), REAL_CONST(115101.42477748329/8.0), REAL_CONST(115125.984332512/8.0), REAL_CONST(115150.54519741859/8.0), REAL_CONST(115175.10737206334/8.0), REAL_CONST(115199.67085630659/8.0), REAL_CONST(115224.23565000873/8.0), REAL_CONST(115248.80175303014/8.0), REAL_CONST(115273.3691652313/8.0), REAL_CONST(115297.93788647266/8.0), REAL_CONST(115322.50791661476/8.0), REAL_CONST(115347.07925551817/8.0), REAL_CONST(115371.65190304347/8.0), REAL_CONST(115396.22585905129/8.0), REAL_CONST(115420.80112340231/8.0), REAL_CONST(115445.37769595724/8.0), REAL_CONST(115469.95557657682/8.0), REAL_CONST(115494.53476512182/8.0), REAL_CONST(115519.11526145306/8.0), REAL_CONST(115543.69706543141/8.0), REAL_CONST(115568.28017691776/8.0), REAL_CONST(115592.86459577303/8.0), REAL_CONST(115617.4503218582/8.0), REAL_CONST(115642.03735503425/8.0), REAL_CONST(115666.62569516223/8.0), REAL_CONST(115691.21534210323/8.0), REAL_CONST(115715.80629571836/8.0), REAL_CONST(115740.39855586876/8.0), REAL_CONST(115764.99212241563/8.0), REAL_CONST(115789.58699522018/8.0), REAL_CONST(115814.18317414368/8.0), REAL_CONST(115838.78065904744/8.0), REAL_CONST(115863.37944979276/8.0), REAL_CONST(115887.97954624105/8.0), REAL_CONST(115912.5809482537/8.0), REAL_CONST(115937.18365569216/8.0), REAL_CONST(115961.78766841792/8.0), REAL_CONST(115986.39298629249/8.0), REAL_CONST(116010.99960917742/8.0), REAL_CONST(116035.60753693432/8.0), REAL_CONST(116060.21676942479/8.0), REAL_CONST(116084.82730651053/8.0), REAL_CONST(116109.43914805322/8.0), REAL_CONST(116134.0522939146/8.0), REAL_CONST(116158.66674395646/8.0), REAL_CONST(116183.2824980406/8.0), REAL_CONST(116207.89955602887/8.0), REAL_CONST(116232.51791778316/8.0), REAL_CONST(116257.13758316539/8.0), REAL_CONST(116281.75855203751/8.0), REAL_CONST(116306.38082426153/8.0), REAL_CONST(116331.00439969949/8.0), REAL_CONST(116355.62927821343/8.0), REAL_CONST(116380.25545966547/8.0), REAL_CONST(116404.88294391775/8.0), REAL_CONST(116429.51173083246/8.0), REAL_CONST(116454.14182027178/8.0), REAL_CONST(116478.77321209799/8.0), REAL_CONST(116503.40590617337/8.0), REAL_CONST(116528.03990236025/8.0), REAL_CONST(116552.67520052097/8.0), REAL_CONST(116577.31180051794/8.0), REAL_CONST(116601.94970221359/8.0), REAL_CONST(116626.5889054704/8.0), REAL_CONST(116651.22941015086/8.0), REAL_CONST(116675.87121611751/8.0), REAL_CONST(116700.51432323294/8.0), REAL_CONST(116725.15873135976/8.0), REAL_CONST(116749.8044403606/8.0), REAL_CONST(116774.45145009817/8.0), REAL_CONST(116799.0997604352/8.0), REAL_CONST(116823.74937123443/8.0), REAL_CONST(116848.40028235866/8.0), REAL_CONST(116873.05249367072/8.0), REAL_CONST(116897.70600503348/8.0), REAL_CONST(116922.36081630984/8.0), REAL_CONST(116947.01692736275/8.0), REAL_CONST(116971.67433805518/8.0), REAL_CONST(116996.33304825013/8.0), REAL_CONST(117020.99305781067/8.0), REAL_CONST(117045.65436659988/8.0), REAL_CONST(117070.31697448085/8.0), REAL_CONST(117094.98088131678/8.0), REAL_CONST(117119.64608697082/8.0), REAL_CONST(117144.31259130624/8.0), REAL_CONST(117168.98039418629/8.0), REAL_CONST(117193.64949547425/8.0), REAL_CONST(117218.31989503348/8.0), REAL_CONST(117242.99159272734/8.0), REAL_CONST(117267.66458841923/8.0), REAL_CONST(117292.33888197262/8.0), REAL_CONST(117317.01447325097/8.0), REAL_CONST(117341.6913621178/8.0), REAL_CONST(117366.36954843666/8.0), REAL_CONST(117391.04903207115/8.0), REAL_CONST(117415.72981288488/8.0), REAL_CONST(117440.41189074152/8.0), REAL_CONST(117465.09526550474/8.0), REAL_CONST(117489.77993703831/8.0), REAL_CONST(117514.46590520597/8.0), REAL_CONST(117539.15316987153/8.0), REAL_CONST(117563.84173089883/8.0), REAL_CONST(117588.53158815173/8.0), REAL_CONST(117613.22274149416/8.0), REAL_CONST(117637.91519079007/8.0), REAL_CONST(117662.60893590341/8.0), REAL_CONST(117687.30397669821/8.0), REAL_CONST(117712.00031303853/8.0), REAL_CONST(117736.69794478847/8.0), REAL_CONST(117761.39687181212/8.0), REAL_CONST(117786.09709397367/8.0), REAL_CONST(117810.7986111373/8.0), REAL_CONST(117835.50142316725/8.0), REAL_CONST(117860.20552992777/8.0), REAL_CONST(117884.91093128319/8.0), REAL_CONST(117909.6176270978/8.0), REAL_CONST(117934.32561723603/8.0), REAL_CONST(117959.03490156225/8.0), REAL_CONST(117983.74547994092/8.0), REAL_CONST(118008.45735223651/8.0), REAL_CONST(118033.17051831353/8.0), REAL_CONST(118057.88497803656/8.0), REAL_CONST(118082.60073127014/8.0), REAL_CONST(118107.31777787894/8.0), REAL_CONST(118132.03611772758/8.0), REAL_CONST(118156.75575068076/8.0), REAL_CONST(118181.47667660323/8.0), REAL_CONST(118206.19889535972/8.0), REAL_CONST(118230.92240681504/8.0), REAL_CONST(118255.64721083404/8.0), REAL_CONST(118280.37330728157/8.0), REAL_CONST(118305.10069602253/8.0), REAL_CONST(118329.82937692189/8.0), REAL_CONST(118354.55934984458/8.0), REAL_CONST(118379.29061465565/8.0), REAL_CONST(118404.02317122012/8.0), REAL_CONST(118428.75701940308/8.0), REAL_CONST(118453.49215906965/8.0), REAL_CONST(118478.22859008498/8.0), REAL_CONST(118502.96631231424/8.0), REAL_CONST(118527.70532562268/8.0), REAL_CONST(118552.44562987552/8.0), REAL_CONST(118577.18722493808/8.0), REAL_CONST(118601.93011067568/8.0), REAL_CONST(118626.67428695368/8.0), REAL_CONST(118651.41975363747/8.0), REAL_CONST(118676.16651059251/8.0), REAL_CONST(118700.91455768423/8.0), REAL_CONST(118725.66389477813/8.0), REAL_CONST(118750.41452173979/8.0), REAL_CONST(118775.16643843475/8.0), REAL_CONST(118799.91964472862/8.0), REAL_CONST(118824.67414048707/8.0), REAL_CONST(118849.42992557574/8.0), REAL_CONST(118874.18699986035/8.0), REAL_CONST(118898.94536320666/8.0), REAL_CONST(118923.70501548045/8.0), REAL_CONST(118948.46595654752/8.0), REAL_CONST(118973.22818627374/8.0), REAL_CONST(118997.99170452499/8.0), REAL_CONST(119022.7565111672/8.0), REAL_CONST(119047.52260606633/8.0), REAL_CONST(119072.28998908834/8.0), REAL_CONST(119097.0586600993/8.0), REAL_CONST(119121.82861896523/8.0), REAL_CONST(119146.59986555226/8.0), REAL_CONST(119171.3723997265/8.0), REAL_CONST(119196.14622135412/8.0), REAL_CONST(119220.92133030134/8.0), REAL_CONST(119245.69772643436/8.0), REAL_CONST(119270.47540961947/8.0), REAL_CONST(119295.25437972297/8.0), REAL_CONST(119320.03463661121/8.0), REAL_CONST(119344.81618015055/8.0), REAL_CONST(119369.5990102074/8.0), REAL_CONST(119394.38312664822/8.0), REAL_CONST(119419.16852933947/8.0), REAL_CONST(119443.95521814766/8.0), REAL_CONST(119468.74319293935/8.0), REAL_CONST(119493.53245358112/8.0), REAL_CONST(119518.32299993958/8.0), REAL_CONST(119543.11483188139/8.0), REAL_CONST(119567.90794927324/8.0), REAL_CONST(119592.70235198183/8.0), REAL_CONST(119617.49803987393/8.0), REAL_CONST(119642.29501281632/8.0), REAL_CONST(119667.09327067583/8.0), REAL_CONST(119691.89281331931/8.0), REAL_CONST(119716.69364061367/8.0), REAL_CONST(119741.49575242582/8.0), REAL_CONST(119766.29914862274/8.0), REAL_CONST(119791.10382907141/8.0), REAL_CONST(119815.90979363887/8.0), REAL_CONST(119840.71704219218/8.0), REAL_CONST(119865.52557459843/8.0), REAL_CONST(119890.33539072477/8.0), REAL_CONST(119915.14649043836/8.0), REAL_CONST(119939.95887360642/8.0), REAL_CONST(119964.77254009615/8.0), REAL_CONST(119989.58748977486/8.0), REAL_CONST(120014.40372250983/8.0), REAL_CONST(120039.22123816841/8.0), REAL_CONST(120064.04003661797/8.0), REAL_CONST(120088.86011772591/8.0), REAL_CONST(120113.6814813597/8.0), REAL_CONST(120138.5041273868/8.0), REAL_CONST(120163.3280556747/8.0), REAL_CONST(120188.15326609099/8.0), REAL_CONST(120212.97975850321/8.0), REAL_CONST(120237.807532779/8.0), REAL_CONST(120262.63658878599/8.0), REAL_CONST(120287.46692639188/8.0), REAL_CONST(120312.29854546436/8.0), REAL_CONST(120337.13144587121/8.0), REAL_CONST(120361.9656274802/8.0), REAL_CONST(120386.80109015915/8.0), REAL_CONST(120411.63783377589/8.0), REAL_CONST(120436.47585819835/8.0), REAL_CONST(120461.31516329442/8.0), REAL_CONST(120486.15574893207/8.0), REAL_CONST(120510.99761497928/8.0), REAL_CONST(120535.84076130406/8.0), REAL_CONST(120560.68518777451/8.0), REAL_CONST(120585.53089425867/8.0), REAL_CONST(120610.3778806247/8.0), REAL_CONST(120635.22614674074/8.0), REAL_CONST(120660.07569247499/8.0), REAL_CONST(120684.92651769568/8.0), REAL_CONST(120709.77862227106/8.0), REAL_CONST(120734.63200606944/8.0), REAL_CONST(120759.48666895913/8.0), REAL_CONST(120784.3426108085/8.0), REAL_CONST(120809.19983148595/8.0), REAL_CONST(120834.05833085992/8.0), REAL_CONST(120858.91810879884/8.0), REAL_CONST(120883.77916517125/8.0), REAL_CONST(120908.64149984565/8.0), REAL_CONST(120933.5051126906/8.0), REAL_CONST(120958.37000357473/8.0), REAL_CONST(120983.23617236665/8.0), REAL_CONST(121008.10361893504/8.0), REAL_CONST(121032.97234314861/8.0), REAL_CONST(121057.84234487606/8.0), REAL_CONST(121082.71362398617/8.0), REAL_CONST(121107.58618034775/8.0), REAL_CONST(121132.46001382964/8.0), REAL_CONST(121157.33512430069/8.0), REAL_CONST(121182.21151162982/8.0), REAL_CONST(121207.08917568595/8.0), REAL_CONST(121231.96811633807/8.0), REAL_CONST(121256.84833345517/8.0), REAL_CONST(121281.72982690629/8.0), REAL_CONST(121306.61259656049/8.0), REAL_CONST(121331.49664228689/8.0), REAL_CONST(121356.38196395461/8.0), REAL_CONST(121381.26856143285/8.0), REAL_CONST(121406.15643459078/8.0), REAL_CONST(121431.04558329767/8.0), REAL_CONST(121455.93600742276/8.0), REAL_CONST(121480.82770683538/8.0), REAL_CONST(121505.72068140487/8.0), REAL_CONST(121530.61493100057/8.0), REAL_CONST(121555.51045549192/8.0), REAL_CONST(121580.40725474835/8.0), REAL_CONST(121605.30532863933/8.0), REAL_CONST(121630.20467703436/8.0), REAL_CONST(121655.10529980299/8.0), REAL_CONST(121680.00719681478/8.0), REAL_CONST(121704.91036793934/8.0), REAL_CONST(121729.81481304632/8.0), REAL_CONST(121754.72053200539/8.0), REAL_CONST(121779.62752468624/8.0), REAL_CONST(121804.53579095862/8.0), REAL_CONST(121829.44533069231/8.0), REAL_CONST(121854.3561437571/8.0), REAL_CONST(121879.26823002285/8.0), REAL_CONST(121904.1815893594/8.0), REAL_CONST(121929.09622163669/8.0), REAL_CONST(121954.01212672464/8.0), REAL_CONST(121978.92930449323/8.0), REAL_CONST(122003.84775481246/8.0), REAL_CONST(122028.76747755238/8.0), REAL_CONST(122053.68847258303/8.0), REAL_CONST(122078.61073977455/8.0), REAL_CONST(122103.53427899707/8.0), REAL_CONST(122128.45909012076/8.0), REAL_CONST(122153.38517301581/8.0), REAL_CONST(122178.31252755247/8.0), REAL_CONST(122203.24115360099/8.0), REAL_CONST(122228.17105103172/8.0), REAL_CONST(122253.10221971494/8.0), REAL_CONST(122278.03465952107/8.0), REAL_CONST(122302.96837032049/8.0), REAL_CONST(122327.90335198362/8.0), REAL_CONST(122352.83960438096/8.0), REAL_CONST(122377.777127383/8.0), REAL_CONST(122402.71592086025/8.0), REAL_CONST(122427.65598468333/8.0), REAL_CONST(122452.59731872278/8.0), REAL_CONST(122477.53992284928/8.0), REAL_CONST(122502.48379693348/8.0), REAL_CONST(122527.42894084606/8.0), REAL_CONST(122552.37535445779/8.0), REAL_CONST(122577.32303763942/8.0), REAL_CONST(122602.27199026172/8.0), REAL_CONST(122627.22221219557/8.0), REAL_CONST(122652.17370331181/8.0), REAL_CONST(122677.12646348133/8.0), REAL_CONST(122702.08049257506/8.0), REAL_CONST(122727.03579046397/8.0), REAL_CONST(122751.99235701906/8.0), REAL_CONST(122776.95019211136/8.0), REAL_CONST(122801.9092956119/8.0), REAL_CONST(122826.8696673918/8.0), REAL_CONST(122851.83130732219/8.0), REAL_CONST(122876.79421527422/8.0), REAL_CONST(122901.75839111909/8.0), REAL_CONST(122926.72383472799/8.0), REAL_CONST(122951.69054597223/8.0), REAL_CONST(122976.65852472307/8.0), REAL_CONST(123001.62777085182/8.0), REAL_CONST(123026.59828422987/8.0), REAL_CONST(123051.57006472857/8.0), REAL_CONST(123076.54311221937/8.0), REAL_CONST(123101.5174265737/8.0), REAL_CONST(123126.49300766307/8.0), REAL_CONST(123151.46985535898/8.0), REAL_CONST(123176.44796953299/8.0), REAL_CONST(123201.42735005668/8.0), REAL_CONST(123226.40799680166/8.0), REAL_CONST(123251.38990963959/8.0), REAL_CONST(123276.37308844214/8.0), REAL_CONST(123301.35753308103/8.0), REAL_CONST(123326.343243428/8.0), REAL_CONST(123351.33021935483/8.0), REAL_CONST(123376.31846073334/8.0), REAL_CONST(123401.30796743535/8.0), REAL_CONST(123426.29873933276/8.0), REAL_CONST(123451.29077629748/8.0), REAL_CONST(123476.28407820144/8.0), REAL_CONST(123501.2786449166/8.0), REAL_CONST(123526.27447631498/8.0), REAL_CONST(123551.27157226863/8.0), REAL_CONST(123576.26993264959/8.0), REAL_CONST(123601.26955732999/8.0), REAL_CONST(123626.27044618195/8.0), REAL_CONST(123651.27259907764/8.0), REAL_CONST(123676.27601588926/8.0), REAL_CONST(123701.28069648903/8.0), REAL_CONST(123726.28664074924/8.0), REAL_CONST(123751.29384854218/8.0), REAL_CONST(123776.30231974016/8.0), REAL_CONST(123801.31205421555/8.0), REAL_CONST(123826.32305184075/8.0), REAL_CONST(123851.33531248817/8.0), REAL_CONST(123876.34883603029/8.0), REAL_CONST(123901.36362233957/8.0), REAL_CONST(123926.37967128855/8.0), REAL_CONST(123951.39698274979/8.0), REAL_CONST(123976.41555659588/8.0), REAL_CONST(124001.43539269941/8.0), REAL_CONST(124026.45649093305/8.0), REAL_CONST(124051.47885116948/8.0), REAL_CONST(124076.50247328142/8.0), REAL_CONST(124101.5273571416/8.0), REAL_CONST(124126.55350262282/8.0), REAL_CONST(124151.58090959788/8.0), REAL_CONST(124176.60957793961/8.0), REAL_CONST(124201.63950752091/8.0), REAL_CONST(124226.67069821467/8.0), REAL_CONST(124251.70314989384/8.0), REAL_CONST(124276.73686243138/8.0), REAL_CONST(124301.7718357003/8.0), REAL_CONST(124326.80806957364/8.0), REAL_CONST(124351.84556392446/8.0), REAL_CONST(124376.88431862585/8.0), REAL_CONST(124401.92433355095/8.0), REAL_CONST(124426.96560857294/8.0), REAL_CONST(124452.00814356498/8.0), REAL_CONST(124477.05193840031/8.0), REAL_CONST(124502.0969929522/8.0), REAL_CONST(124527.14330709392/8.0), REAL_CONST(124552.19088069882/8.0), REAL_CONST(124577.23971364023/8.0), REAL_CONST(124602.28980579154/8.0), REAL_CONST(124627.34115702618/8.0), REAL_CONST(124652.3937672176/8.0), REAL_CONST(124677.44763623926/8.0), REAL_CONST(124702.50276396469/8.0), REAL_CONST(124727.55915026742/8.0), REAL_CONST(124752.61679502104/8.0), REAL_CONST(124777.67569809916/8.0), REAL_CONST(124802.73585937542/8.0), REAL_CONST(124827.79727872348/8.0), REAL_CONST(124852.85995601704/8.0), REAL_CONST(124877.92389112986/8.0), REAL_CONST(124902.98908393568/8.0), REAL_CONST(124928.05553430831/8.0), REAL_CONST(124953.1232421216/8.0), REAL_CONST(124978.19220724938/8.0), REAL_CONST(125003.26242956554/8.0), REAL_CONST(125028.33390894404/8.0), REAL_CONST(125053.40664525882/8.0), REAL_CONST(125078.48063838384/8.0), REAL_CONST(125103.55588819318/8.0), REAL_CONST(125128.63239456083/8.0), REAL_CONST(125153.71015736091/8.0), REAL_CONST(125178.78917646752/8.0), REAL_CONST(125203.86945175481/8.0), REAL_CONST(125228.95098309696/8.0), REAL_CONST(125254.03377036817/8.0), REAL_CONST(125279.1178134427/8.0), REAL_CONST(125304.20311219479/8.0), REAL_CONST(125329.28966649878/8.0), REAL_CONST(125354.37747622898/8.0), REAL_CONST(125379.46654125977/8.0), REAL_CONST(125404.55686146552/8.0), REAL_CONST(125429.6484367207/8.0), REAL_CONST(125454.74126689974/8.0), REAL_CONST(125479.83535187715/8.0), REAL_CONST(125504.93069152744/8.0), REAL_CONST(125530.02728572517/8.0), REAL_CONST(125555.12513434493/8.0), REAL_CONST(125580.22423726133/8.0), REAL_CONST(125605.32459434902/8.0), REAL_CONST(125630.4262054827/8.0), REAL_CONST(125655.52907053704/8.0), REAL_CONST(125680.63318938682/8.0), REAL_CONST(125705.73856190679/8.0), REAL_CONST(125730.84518797178/8.0), REAL_CONST(125755.9530674566/8.0), REAL_CONST(125781.06220023613/8.0), REAL_CONST(125806.17258618528/8.0), REAL_CONST(125831.28422517896/8.0), REAL_CONST(125856.39711709213/8.0), REAL_CONST(125881.51126179981/8.0), REAL_CONST(125906.62665917698/8.0), REAL_CONST(125931.74330909875/8.0), REAL_CONST(125956.86121144016/8.0), REAL_CONST(125981.98036607634/8.0), REAL_CONST(126007.10077288245/8.0), REAL_CONST(126032.22243173365/8.0), REAL_CONST(126057.34534250517/8.0), REAL_CONST(126082.46950507225/8.0), REAL_CONST(126107.59491931014/8.0), REAL_CONST(126132.72158509417/8.0), REAL_CONST(126157.84950229966/8.0), REAL_CONST(126182.97867080198/8.0), REAL_CONST(126208.10909047653/8.0), REAL_CONST(126233.24076119871/8.0), REAL_CONST(126258.37368284403/8.0), REAL_CONST(126283.50785528794/8.0), REAL_CONST(126308.64327840599/8.0), REAL_CONST(126333.77995207369/8.0), REAL_CONST(126358.91787616667/8.0), REAL_CONST(126384.0570505605/8.0), REAL_CONST(126409.19747513086/8.0), REAL_CONST(126434.3391497534/8.0), REAL_CONST(126459.48207430386/8.0), REAL_CONST(126484.62624865794/8.0), REAL_CONST(126509.77167269142/8.0), REAL_CONST(126534.9183462801/8.0), REAL_CONST(126560.06626929982/8.0), REAL_CONST(126585.21544162642/8.0), REAL_CONST(126610.36586313581/8.0), REAL_CONST(126635.51753370393/8.0), REAL_CONST(126660.67045320668/8.0), REAL_CONST(126685.82462152008/8.0), REAL_CONST(126710.98003852014/8.0), REAL_CONST(126736.13670408291/8.0), REAL_CONST(126761.29461808444/8.0), REAL_CONST(126786.45378040087/8.0), REAL_CONST(126811.61419090834/8.0), REAL_CONST(126836.77584948298/8.0), REAL_CONST(126861.93875600102/8.0), REAL_CONST(126887.10291033868/8.0), REAL_CONST(126912.26831237224/8.0), REAL_CONST(126937.43496197795/8.0), REAL_CONST(126962.60285903217/8.0), REAL_CONST(126987.77200341123/8.0), REAL_CONST(127012.94239499152/8.0), REAL_CONST(127038.11403364947/8.0), REAL_CONST(127063.2869192615/8.0), REAL_CONST(127088.46105170409/8.0), REAL_CONST(127113.63643085376/8.0), REAL_CONST(127138.81305658702/8.0), REAL_CONST(127163.99092878048/8.0), REAL_CONST(127189.17004731069/8.0), REAL_CONST(127214.35041205429/8.0), REAL_CONST(127239.53202288797/8.0), REAL_CONST(127264.71487968838/8.0), REAL_CONST(127289.89898233226/8.0), REAL_CONST(127315.08433069635/8.0), REAL_CONST(127340.27092465744/8.0), REAL_CONST(127365.45876409234/8.0), REAL_CONST(127390.64784887788/8.0), REAL_CONST(127415.83817889093/8.0), REAL_CONST(127441.02975400841/8.0), REAL_CONST(127466.22257410725/8.0), REAL_CONST(127491.41663906439/8.0), REAL_CONST(127516.61194875685/8.0), REAL_CONST(127541.80850306165/8.0), REAL_CONST(127567.00630185583/8.0), REAL_CONST(127592.20534501647/8.0), REAL_CONST(127617.4056324207/8.0), REAL_CONST(127642.60716394568/8.0), REAL_CONST(127667.80993946856/8.0), REAL_CONST(127693.01395886653/8.0), REAL_CONST(127718.21922201688/8.0), REAL_CONST(127743.42572879682/8.0), REAL_CONST(127768.63347908368/8.0), REAL_CONST(127793.84247275478/8.0), REAL_CONST(127819.05270968749/8.0), REAL_CONST(127844.26418975917/8.0), REAL_CONST(127869.47691284724/8.0), REAL_CONST(127894.69087882918/8.0), REAL_CONST(127919.90608758242/8.0), REAL_CONST(127945.12253898452/8.0), REAL_CONST(127970.34023291297/8.0), REAL_CONST(127995.55916924537/8.0), REAL_CONST(128020.77934785932/8.0), REAL_CONST(128046.00076863244/8.0), REAL_CONST(128071.22343144237/8.0), REAL_CONST(128096.44733616684/8.0), REAL_CONST(128121.67248268353/8.0), REAL_CONST(128146.89887087021/8.0), REAL_CONST(128172.12650060465/8.0), REAL_CONST(128197.35537176467/8.0), REAL_CONST(128222.5854842281/8.0), REAL_CONST(128247.81683787282/8.0), REAL_CONST(128273.04943257671/8.0), REAL_CONST(128298.28326821771/8.0), REAL_CONST(128323.51834467379/8.0), REAL_CONST(128348.75466182294/8.0), REAL_CONST(128373.99221954317/8.0), REAL_CONST(128399.23101771252/8.0), REAL_CONST(128424.47105620909/8.0), REAL_CONST(128449.71233491098/8.0), REAL_CONST(128474.95485369631/8.0), REAL_CONST(128500.19861244329/8.0), REAL_CONST(128525.44361103009/8.0), REAL_CONST(128550.68984933494/8.0), REAL_CONST(128575.93732723613/8.0), REAL_CONST(128601.18604461191/8.0), REAL_CONST(128626.43600134061/8.0), REAL_CONST(128651.68719730059/8.0), REAL_CONST(128676.93963237021/8.0), REAL_CONST(128702.1933064279/8.0), REAL_CONST(128727.44821935208/8.0), REAL_CONST(128752.70437102125/8.0), REAL_CONST(128777.96176131385/8.0), REAL_CONST(128803.22039010846/8.0), REAL_CONST(128828.48025728362/8.0), REAL_CONST(128853.74136271792/8.0), REAL_CONST(128879.00370628996/8.0), REAL_CONST(128904.26728787841/8.0), REAL_CONST(128929.53210736193/8.0), REAL_CONST(128954.79816461923/8.0), REAL_CONST(128980.06545952905/8.0), REAL_CONST(129005.33399197015/8.0), REAL_CONST(129030.60376182134/8.0), REAL_CONST(129055.87476896142/8.0), REAL_CONST(129081.14701326926/8.0), REAL_CONST(129106.42049462376/8.0), REAL_CONST(129131.6952129038/8.0), REAL_CONST(129156.97116798835/8.0), REAL_CONST(129182.24835975636/8.0), REAL_CONST(129207.52678808685/8.0), REAL_CONST(129232.80645285884/8.0), REAL_CONST(129258.08735395141/8.0), REAL_CONST(129283.36949124365/8.0), REAL_CONST(129308.65286461466/8.0), REAL_CONST(129333.9374739436/8.0), REAL_CONST(129359.22331910966/8.0), REAL_CONST(129384.51039999202/8.0), REAL_CONST(129409.79871646997/8.0), REAL_CONST(129435.08826842274/8.0), REAL_CONST(129460.37905572963/8.0), REAL_CONST(129485.67107826998/8.0), REAL_CONST(129510.96433592314/8.0), REAL_CONST(129536.25882856851/8.0), REAL_CONST(129561.55455608548/8.0), REAL_CONST(129586.85151835352/8.0), REAL_CONST(129612.14971525209/8.0), REAL_CONST(129637.4491466607/8.0), REAL_CONST(129662.74981245887/8.0), REAL_CONST(129688.0517125262/8.0), REAL_CONST(129713.35484674224/8.0), REAL_CONST(129738.65921498663/8.0), REAL_CONST(129763.96481713903/8.0), REAL_CONST(129789.27165307909/8.0), REAL_CONST(129814.57972268655/8.0), REAL_CONST(129839.88902584116/8.0), REAL_CONST(129865.19956242264/8.0), REAL_CONST(129890.51133231082/8.0), REAL_CONST(129915.82433538554/8.0), REAL_CONST(129941.13857152662/8.0), REAL_CONST(129966.45404061397/8.0), REAL_CONST(129991.7707425275/8.0), REAL_CONST(130017.08867714716/8.0), REAL_CONST(130042.4078443529/8.0), REAL_CONST(130067.72824402474/8.0), REAL_CONST(130093.04987604271/8.0), REAL_CONST(130118.37274028687/8.0), REAL_CONST(130143.69683663732/8.0), REAL_CONST(130169.02216497416/8.0), REAL_CONST(130194.34872517755/8.0), REAL_CONST(130219.67651712766/8.0), REAL_CONST(130245.0055407047/8.0), REAL_CONST(130270.33579578891/8.0), REAL_CONST(130295.66728226055/8.0), REAL_CONST(130320.99999999991/8.0), REAL_CONST(130346.33394888733/8.0), REAL_CONST(130371.66912880314/8.0), REAL_CONST(130397.00553962773/8.0), REAL_CONST(130422.34318124152/8.0), REAL_CONST(130447.68205352494/8.0), REAL_CONST(130473.02215635845/8.0), REAL_CONST(130498.36348962256/8.0), REAL_CONST(130523.70605319779/8.0), REAL_CONST(130549.0498469647/8.0), REAL_CONST(130574.39487080388/8.0), REAL_CONST(130599.74112459592/8.0), REAL_CONST(130625.08860822149/8.0), REAL_CONST(130650.43732156123/8.0), REAL_CONST(130675.78726449587/8.0), REAL_CONST(130701.13843690613/8.0), REAL_CONST(130726.49083867275/8.0), REAL_CONST(130751.84446967654/8.0), REAL_CONST(130777.19932979831/8.0), REAL_CONST(130802.5554189189/8.0), REAL_CONST(130827.91273691918/8.0), REAL_CONST(130853.27128368006/8.0), REAL_CONST(130878.63105908247/8.0), REAL_CONST(130903.99206300738/8.0), REAL_CONST(130929.35429533575/8.0), REAL_CONST(130954.71775594862/8.0), REAL_CONST(130980.08244472703/8.0), REAL_CONST(131005.44836155206/8.0), REAL_CONST(131030.81550630482/8.0), REAL_CONST(131056.18387886642/8.0), REAL_CONST(131081.55347911804/8.0), REAL_CONST(131106.92430694087/8.0), REAL_CONST(131132.29636221612/8.0), REAL_CONST(131157.66964482504/8.0), REAL_CONST(131183.0441546489/8.0), REAL_CONST(131208.41989156904/8.0), REAL_CONST(131233.79685546676/8.0), REAL_CONST(131259.17504622342/8.0), REAL_CONST(131284.55446372041/8.0), REAL_CONST(131309.93510783918/8.0), REAL_CONST(131335.31697846117/8.0), REAL_CONST(131360.70007546784/8.0), REAL_CONST(131386.0843987407/8.0), REAL_CONST(131411.46994816128/8.0), REAL_CONST(131436.85672361116/8.0), REAL_CONST(131462.24472497194/8.0), REAL_CONST(131487.63395212521/8.0), REAL_CONST(131513.02440495262/8.0), REAL_CONST(131538.41608333588/8.0), REAL_CONST(131563.80898715663/8.0), REAL_CONST(131589.2031162967/8.0), REAL_CONST(131614.59847063778/8.0), REAL_CONST(131639.9950500617/8.0), REAL_CONST(131665.39285445024/8.0), REAL_CONST(131690.79188368531/8.0), REAL_CONST(131716.19213764873/8.0), REAL_CONST(131741.59361622241/8.0), REAL_CONST(131766.99631928833/8.0), REAL_CONST(131792.40024672839/8.0), REAL_CONST(131817.80539842462/8.0), REAL_CONST(131843.21177425905/8.0), REAL_CONST(131868.61937411371/8.0), REAL_CONST(131894.02819787065/8.0), REAL_CONST(131919.43824541202/8.0), REAL_CONST(131944.84951661993/8.0), REAL_CONST(131970.26201137656/8.0), REAL_CONST(131995.67572956407/8.0), REAL_CONST(132021.09067106468/8.0), REAL_CONST(132046.50683576067/8.0), REAL_CONST(132071.9242235343/8.0), REAL_CONST(132097.34283426782/8.0), REAL_CONST(132122.76266784366/8.0), REAL_CONST(132148.1837241441/8.0), REAL_CONST(132173.60600305157/8.0), REAL_CONST(132199.02950444847/8.0), REAL_CONST(132224.45422821722/8.0), REAL_CONST(132249.88017424036/8.0), REAL_CONST(132275.30734240031/8.0), REAL_CONST(132300.73573257966/8.0), REAL_CONST(132326.16534466096/8.0), REAL_CONST(132351.59617852676/8.0), REAL_CONST(132377.02823405969/8.0), REAL_CONST(132402.46151114244/8.0), REAL_CONST(132427.89600965759/8.0), REAL_CONST(132453.33172948789/8.0), REAL_CONST(132478.76867051609/8.0), REAL_CONST(132504.20683262491/8.0), REAL_CONST(132529.64621569714/8.0), REAL_CONST(132555.08681961559/8.0), REAL_CONST(132580.5286442631/8.0), REAL_CONST(132605.97168952253/8.0), REAL_CONST(132631.41595527678/8.0), REAL_CONST(132656.86144140881/8.0), REAL_CONST(132682.30814780149/8.0), REAL_CONST(132707.75607433787/8.0), REAL_CONST(132733.20522090094/8.0), REAL_CONST(132758.65558737374/8.0), REAL_CONST(132784.10717363929/8.0), REAL_CONST(132809.55997958075/8.0), REAL_CONST(132835.01400508118/8.0), REAL_CONST(132860.46925002377/8.0), REAL_CONST(132885.92571429166/8.0), REAL_CONST(132911.38339776811/8.0), REAL_CONST(132936.84230033628/8.0), REAL_CONST(132962.30242187946/8.0), REAL_CONST(132987.76376228096/8.0), REAL_CONST(133013.22632142407/8.0), REAL_CONST(133038.69009919214/8.0), REAL_CONST(133064.15509546854/8.0), REAL_CONST(133089.62131013666/8.0), REAL_CONST(133115.08874307995/8.0), REAL_CONST(133140.55739418184/8.0), REAL_CONST(133166.02726332581/8.0), REAL_CONST(133191.49835039541/8.0), REAL_CONST(133216.97065527414/8.0), REAL_CONST(133242.44417784561/8.0), REAL_CONST(133267.91891799335/8.0), REAL_CONST(133293.39487560102/8.0), REAL_CONST(133318.87205055228/8.0), REAL_CONST(133344.35044273079/8.0), REAL_CONST(133369.83005202023/8.0), REAL_CONST(133395.31087830439/8.0), REAL_CONST(133420.79292146701/8.0), REAL_CONST(133446.27618139185/8.0), REAL_CONST(133471.76065796276/8.0), REAL_CONST(133497.24635106357/8.0), REAL_CONST(133522.73326057816/8.0), REAL_CONST(133548.22138639039/8.0), REAL_CONST(133573.71072838426/8.0), REAL_CONST(133599.20128644365/8.0), REAL_CONST(133624.69306045261/8.0), REAL_CONST(133650.1860502951/8.0), REAL_CONST(133675.68025585517/8.0), REAL_CONST(133701.1756770169/8.0), REAL_CONST(133726.67231366437/8.0), REAL_CONST(133752.17016568172/8.0), REAL_CONST(133777.66923295305/8.0), REAL_CONST(133803.16951536259/8.0), REAL_CONST(133828.67101279454/8.0), REAL_CONST(133854.17372513309/8.0), REAL_CONST(133879.67765226253/8.0), REAL_CONST(133905.18279406714/8.0), REAL_CONST(133930.68915043125/8.0), REAL_CONST(133956.19672123916/8.0), REAL_CONST(133981.70550637526/8.0), REAL_CONST(134007.21550572399/8.0), REAL_CONST(134032.7267191697/8.0), REAL_CONST(134058.23914659687/8.0), REAL_CONST(134083.75278789/8.0), REAL_CONST(134109.26764293358/8.0), REAL_CONST(134134.78371161217/8.0), REAL_CONST(134160.30099381026/8.0), REAL_CONST(134185.8194894125/8.0), REAL_CONST(134211.33919830353/8.0), REAL_CONST(134236.8601203679/8.0), REAL_CONST(134262.38225549037/8.0), REAL_CONST(134287.90560355558/8.0), REAL_CONST(134313.43016444831/8.0), REAL_CONST(134338.95593805326/8.0), REAL_CONST(134364.48292425525/8.0), REAL_CONST(134390.01112293909/8.0), REAL_CONST(134415.54053398955/8.0), REAL_CONST(134441.07115729159/8.0), REAL_CONST(134466.60299273001/8.0), REAL_CONST(134492.1360401898/8.0), REAL_CONST(134517.67029955584/8.0), REAL_CONST(134543.20577071316/8.0), REAL_CONST(134568.74245354676/8.0), REAL_CONST(134594.28034794159/8.0), REAL_CONST(134619.81945378278/8.0), REAL_CONST(134645.35977095537/8.0), REAL_CONST(134670.90129934452/8.0), REAL_CONST(134696.4440388353/8.0), REAL_CONST(134721.98798931291/8.0), REAL_CONST(134747.53315066252/8.0), REAL_CONST(134773.07952276937/8.0), REAL_CONST(134798.62710551871/8.0), REAL_CONST(134824.17589879577/8.0), REAL_CONST(134849.72590248589/8.0), REAL_CONST(134875.27711647438/8.0), REAL_CONST(134900.82954064661/8.0), REAL_CONST(134926.38317488792/8.0), REAL_CONST(134951.93801908373/8.0), REAL_CONST(134977.49407311951/8.0), REAL_CONST(135003.05133688069/8.0), REAL_CONST(135028.60981025276/8.0), REAL_CONST(135054.16949312127/8.0), REAL_CONST(135079.73038537172/8.0), REAL_CONST(135105.29248688967/8.0), REAL_CONST(135130.85579756077/8.0), REAL_CONST(135156.42031727062/8.0), REAL_CONST(135181.98604590484/8.0), REAL_CONST(135207.55298334916/8.0), REAL_CONST(135233.12112948924/8.0), REAL_CONST(135258.69048421088/8.0), REAL_CONST(135284.26104739975/8.0), REAL_CONST(135309.83281894168/8.0), REAL_CONST(135335.4057987225/8.0), REAL_CONST(135360.97998662802/8.0), REAL_CONST(135386.55538254412/8.0), REAL_CONST(135412.13198635669/8.0), REAL_CONST(135437.70979795168/8.0), REAL_CONST(135463.28881721498/8.0), REAL_CONST(135488.86904403262/8.0), REAL_CONST(135514.45047829056/8.0), REAL_CONST(135540.03311987486/8.0), REAL_CONST(135565.61696867159/8.0), REAL_CONST(135591.20202456677/8.0), REAL_CONST(135616.78828744654/8.0), REAL_CONST(135642.37575719706/8.0), REAL_CONST(135667.96443370447/8.0), REAL_CONST(135693.55431685498/8.0), REAL_CONST(135719.14540653475/8.0), REAL_CONST(135744.73770263011/8.0), REAL_CONST(135770.33120502727/8.0), REAL_CONST(135795.92591361253/8.0), REAL_CONST(135821.52182827223/8.0), REAL_CONST(135847.11894889272/8.0), REAL_CONST(135872.7172753604/8.0), REAL_CONST(135898.31680756161/8.0), REAL_CONST(135923.91754538284/8.0), REAL_CONST(135949.51948871053/8.0), REAL_CONST(135975.12263743114/8.0), REAL_CONST(136000.72699143123/8.0), REAL_CONST(136026.33255059729/8.0), REAL_CONST(136051.93931481591/8.0), REAL_CONST(136077.54728397369/8.0), REAL_CONST(136103.15645795723/8.0), REAL_CONST(136128.76683665317/8.0), REAL_CONST(136154.37841994822/8.0), REAL_CONST(136179.99120772901/8.0), REAL_CONST(136205.60519988232/8.0), REAL_CONST(136231.2203962949/8.0), REAL_CONST(136256.83679685349/8.0), REAL_CONST(136282.45440144493/8.0), REAL_CONST(136308.07320995603/8.0), REAL_CONST(136333.69322227367/8.0), REAL_CONST(136359.31443828469/8.0), REAL_CONST(136384.93685787608/8.0), REAL_CONST(136410.56048093468/8.0), REAL_CONST(136436.18530734754/8.0), REAL_CONST(136461.81133700156/8.0), REAL_CONST(136487.43856978384/8.0), REAL_CONST(136513.06700558143/8.0), REAL_CONST(136538.6966442813/8.0), REAL_CONST(136564.32748577066/8.0), REAL_CONST(136589.95952993655/8.0), REAL_CONST(136615.59277666616/8.0), REAL_CONST(136641.22722584667/8.0), REAL_CONST(136666.86287736523/8.0), REAL_CONST(136692.49973110916/8.0), REAL_CONST(136718.13778696564/8.0), REAL_CONST(136743.77704482197/8.0), REAL_CONST(136769.41750456547/8.0), REAL_CONST(136795.05916608346/8.0), REAL_CONST(136820.70202926331/8.0), REAL_CONST(136846.34609399244/8.0), REAL_CONST(136871.99136015819/8.0), REAL_CONST(136897.63782764805/8.0), REAL_CONST(136923.28549634948/8.0), REAL_CONST(136948.93436614997/8.0), REAL_CONST(136974.58443693706/8.0), REAL_CONST(137000.23570859825/8.0), REAL_CONST(137025.88818102115/8.0), REAL_CONST(137051.54185409332/8.0), REAL_CONST(137077.19672770242/8.0), REAL_CONST(137102.85280173609/8.0), REAL_CONST(137128.51007608202/8.0), REAL_CONST(137154.16855062786/8.0), REAL_CONST(137179.82822526142/8.0), REAL_CONST(137205.48909987041/8.0), REAL_CONST(137231.15117434258/8.0), REAL_CONST(137256.8144485658/8.0), REAL_CONST(137282.47892242789/8.0), REAL_CONST(137308.14459581667/8.0), REAL_CONST(137333.81146862009/8.0), REAL_CONST(137359.47954072602/8.0), REAL_CONST(137385.14881202241/8.0), REAL_CONST(137410.81928239719/8.0), REAL_CONST(137436.49095173844/8.0), REAL_CONST(137462.16381993407/8.0), REAL_CONST(137487.83788687221/8.0), REAL_CONST(137513.51315244089/8.0), REAL_CONST(137539.18961652822/8.0), REAL_CONST(137564.86727902229/8.0), REAL_CONST(137590.54613981131/8.0), REAL_CONST(137616.22619878338/8.0), REAL_CONST(137641.90745582676/8.0), REAL_CONST(137667.58991082967/8.0), REAL_CONST(137693.27356368033/8.0), REAL_CONST(137718.95841426702/8.0), REAL_CONST(137744.64446247809/8.0), REAL_CONST(137770.33170820182/8.0), REAL_CONST(137796.02015132661/8.0), REAL_CONST(137821.70979174081/8.0), REAL_CONST(137847.40062933284/8.0), REAL_CONST(137873.09266399115/8.0), REAL_CONST(137898.78589560417/8.0), REAL_CONST(137924.48032406042/8.0), REAL_CONST(137950.17594924837/8.0), REAL_CONST(137975.8727710566/8.0), REAL_CONST(138001.57078937365/8.0), REAL_CONST(138027.27000408815/8.0), REAL_CONST(138052.97041508864/8.0), REAL_CONST(138078.67202226384/8.0), REAL_CONST(138104.3748255024/8.0), REAL_CONST(138130.07882469296/8.0), REAL_CONST(138155.78401972432/8.0), REAL_CONST(138181.49041048516/8.0), REAL_CONST(138207.1979968643/8.0), REAL_CONST(138232.9067787505/8.0), REAL_CONST(138258.61675603263/8.0), REAL_CONST(138284.32792859949/8.0), REAL_CONST(138310.04029633995/8.0), REAL_CONST(138335.75385914298/8.0), REAL_CONST(138361.46861689744/8.0), REAL_CONST(138387.18456949232/8.0), REAL_CONST(138412.90171681659/8.0), REAL_CONST(138438.62005875923/8.0), REAL_CONST(138464.33959520931/8.0), REAL_CONST(138490.06032605586/8.0), REAL_CONST(138515.78225118798/8.0), REAL_CONST(138541.50537049473/8.0), REAL_CONST(138567.2296838653/8.0), REAL_CONST(138592.95519118884/8.0), REAL_CONST(138618.68189235451/8.0), REAL_CONST(138644.40978725153/8.0), REAL_CONST(138670.13887576913/8.0), REAL_CONST(138695.86915779658/8.0), REAL_CONST(138721.60063322316/8.0), REAL_CONST(138747.33330193823/8.0), REAL_CONST(138773.06716383106/8.0), REAL_CONST(138798.80221879104/8.0), REAL_CONST(138824.53846670757/8.0), REAL_CONST(138850.27590747006/8.0), REAL_CONST(138876.01454096794/8.0), REAL_CONST(138901.7543670907/8.0), REAL_CONST(138927.49538572782/8.0), REAL_CONST(138953.2375967688/8.0), REAL_CONST(138978.9810001032/8.0), REAL_CONST(139004.72559562061/8.0), REAL_CONST(139030.47138321059/8.0), REAL_CONST(139056.2183627628/8.0), REAL_CONST(139081.96653416683/8.0), REAL_CONST(139107.71589731239/8.0), REAL_CONST(139133.46645208917/8.0), REAL_CONST(139159.21819838689/8.0), REAL_CONST(139184.97113609532/8.0), REAL_CONST(139210.72526510421/8.0), REAL_CONST(139236.48058530336/8.0), REAL_CONST(139262.23709658257/8.0), REAL_CONST(139287.99479883176/8.0), REAL_CONST(139313.75369194071/8.0), REAL_CONST(139339.51377579942/8.0), REAL_CONST(139365.27505029776/8.0), REAL_CONST(139391.03751532568/8.0), REAL_CONST(139416.80117077316/8.0), REAL_CONST(139442.56601653024/8.0), REAL_CONST(139468.33205248689/8.0), REAL_CONST(139494.09927853322/8.0), REAL_CONST(139519.86769455927/8.0), REAL_CONST(139545.63730045516/8.0), REAL_CONST(139571.408096111/8.0), REAL_CONST(139597.18008141697/8.0), REAL_CONST(139622.95325626322/8.0), REAL_CONST(139648.72762054001/8.0), REAL_CONST(139674.5031741375/8.0), REAL_CONST(139700.27991694602/8.0), REAL_CONST(139726.05784885579/8.0), REAL_CONST(139751.83696975713/8.0), REAL_CONST(139777.61727954043/8.0), REAL_CONST(139803.39877809596/8.0), REAL_CONST(139829.18146531415/8.0), REAL_CONST(139854.96534108539/8.0), REAL_CONST(139880.75040530015/8.0), REAL_CONST(139906.53665784886/8.0), REAL_CONST(139932.32409862199/8.0), REAL_CONST(139958.11272751007/8.0), REAL_CONST(139983.90254440365/8.0), REAL_CONST(140009.69354919327/8.0), REAL_CONST(140035.48574176949/8.0), REAL_CONST(140061.27912202294/8.0), REAL_CONST(140087.07368984428/8.0), REAL_CONST(140112.86944512415/8.0), REAL_CONST(140138.66638775321/8.0), REAL_CONST(140164.4645176222/8.0), REAL_CONST(140190.26383462184/8.0), REAL_CONST(140216.06433864293/8.0), REAL_CONST(140241.86602957622/8.0), REAL_CONST(140267.66890731253/8.0), REAL_CONST(140293.47297174268/8.0), REAL_CONST(140319.27822275754/8.0), REAL_CONST(140345.08466024802/8.0), REAL_CONST(140370.89228410498/8.0), REAL_CONST(140396.70109421943/8.0), REAL_CONST(140422.51109048226/8.0), REAL_CONST(140448.32227278448/8.0), REAL_CONST(140474.13464101712/8.0), REAL_CONST(140499.94819507122/8.0), REAL_CONST(140525.76293483781/8.0), REAL_CONST(140551.57886020801/8.0), REAL_CONST(140577.3959710729/8.0), REAL_CONST(140603.21426732364/8.0), REAL_CONST(140629.03374885136/8.0), REAL_CONST(140654.85441554731/8.0), REAL_CONST(140680.67626730262/8.0), REAL_CONST(140706.49930400858/8.0), REAL_CONST(140732.32352555645/8.0), REAL_CONST(140758.1489318375/8.0), REAL_CONST(140783.97552274304/8.0), REAL_CONST(140809.80329816442/8.0), REAL_CONST(140835.63225799298/8.0), REAL_CONST(140861.46240212015/8.0), REAL_CONST(140887.29373043729/8.0), REAL_CONST(140913.12624283586/8.0), REAL_CONST(140938.95993920733/8.0), REAL_CONST(140964.79481944317/8.0), REAL_CONST(140990.63088343487/8.0), REAL_CONST(141016.46813107401/8.0), REAL_CONST(141042.30656225214/8.0), REAL_CONST(141068.14617686081/8.0), REAL_CONST(141093.98697479168/8.0), REAL_CONST(141119.82895593636/8.0), REAL_CONST(141145.6721201865/8.0), REAL_CONST(141171.51646743377/8.0), REAL_CONST(141197.36199756994/8.0), REAL_CONST(141223.20871048668/8.0), REAL_CONST(141249.05660607578/8.0), REAL_CONST(141274.90568422904/8.0), REAL_CONST(141300.75594483822/8.0), REAL_CONST(141326.6073877952/8.0), REAL_CONST(141352.4600129918/8.0), REAL_CONST(141378.31382031992/8.0), REAL_CONST(141404.16880967148/8.0), REAL_CONST(141430.02498093838/8.0), REAL_CONST(141455.8823340126/8.0), REAL_CONST(141481.74086878612/8.0), REAL_CONST(141507.60058515094/8.0), REAL_CONST(141533.46148299909/8.0), REAL_CONST(141559.32356222265/8.0), REAL_CONST(141585.18682271364/8.0), REAL_CONST(141611.05126436421/8.0), REAL_CONST(141636.9168870665/8.0), REAL_CONST(141662.78369071262/8.0), REAL_CONST(141688.65167519479/8.0), REAL_CONST(141714.5208404052/8.0), REAL_CONST(141740.39118623605/8.0), REAL_CONST(141766.26271257963/8.0), REAL_CONST(141792.1354193282/8.0), REAL_CONST(141818.00930637406/8.0), REAL_CONST(141843.88437360956/8.0), REAL_CONST(141869.760620927/8.0), REAL_CONST(141895.6380482188/8.0), REAL_CONST(141921.51665537735/8.0), REAL_CONST(141947.39644229505/8.0), REAL_CONST(141973.27740886438/8.0), REAL_CONST(141999.15955497778/8.0), REAL_CONST(142025.04288052776/8.0), REAL_CONST(142050.92738540689/8.0), REAL_CONST(142076.81306950765/8.0), REAL_CONST(142102.69993272264/8.0), REAL_CONST(142128.58797494444/8.0), REAL_CONST(142154.47719606571/8.0), REAL_CONST(142180.36759597904/8.0), REAL_CONST(142206.25917457714/8.0), REAL_CONST(142232.15193175265/8.0), REAL_CONST(142258.04586739838/8.0), REAL_CONST(142283.94098140698/8.0), REAL_CONST(142309.83727367126/8.0), REAL_CONST(142335.73474408401/8.0), REAL_CONST(142361.63339253806/8.0), REAL_CONST(142387.5332189262/8.0), REAL_CONST(142413.43422314132/8.0), REAL_CONST(142439.33640507635/8.0), REAL_CONST(142465.23976462413/8.0), REAL_CONST(142491.14430167765/8.0), REAL_CONST(142517.05001612983/8.0), REAL_CONST(142542.95690787368/8.0), REAL_CONST(142568.86497680223/8.0), REAL_CONST(142594.77422280848/8.0), REAL_CONST(142620.68464578551/8.0), REAL_CONST(142646.5962456264/8.0), REAL_CONST(142672.50902222423/8.0), REAL_CONST(142698.42297547215/8.0), REAL_CONST(142724.33810526333/8.0), REAL_CONST(142750.25441149093/8.0), REAL_CONST(142776.17189404817/8.0), REAL_CONST(142802.09055282827/8.0), REAL_CONST(142828.01038772447/8.0), REAL_CONST(142853.93139863008/8.0), REAL_CONST(142879.85358543837/8.0), REAL_CONST(142905.77694804268/8.0), REAL_CONST(142931.70148633636/8.0), REAL_CONST(142957.62720021277/8.0), REAL_CONST(142983.55408956532/8.0), REAL_CONST(143009.48215428743/8.0), REAL_CONST(143035.41139427255/8.0), REAL_CONST(143061.34180941415/8.0), REAL_CONST(143087.27339960571/8.0), REAL_CONST(143113.20616474075/8.0), REAL_CONST(143139.14010471283/8.0), REAL_CONST(143165.07521941551/8.0), REAL_CONST(143191.01150874238/8.0), REAL_CONST(143216.94897258704/8.0), REAL_CONST(143242.88761084314/8.0), REAL_CONST(143268.82742340435/8.0), REAL_CONST(143294.76841016437/8.0), REAL_CONST(143320.71057101688/8.0), REAL_CONST(143346.65390585564/8.0), REAL_CONST(143372.59841457437/8.0), REAL_CONST(143398.54409706692/8.0), REAL_CONST(143424.49095322701/8.0), REAL_CONST(143450.43898294857/8.0), REAL_CONST(143476.38818612538/8.0), REAL_CONST(143502.33856265133/8.0), REAL_CONST(143528.29011242036/8.0), REAL_CONST(143554.24283532638/8.0), REAL_CONST(143580.19673126334/8.0), REAL_CONST(143606.1518001252/8.0), REAL_CONST(143632.10804180597/8.0), REAL_CONST(143658.06545619969/8.0), REAL_CONST(143684.02404320039/8.0), REAL_CONST(143709.98380270213/8.0), REAL_CONST(143735.944734599/8.0), REAL_CONST(143761.90683878519/8.0), REAL_CONST(143787.87011515474/8.0), REAL_CONST(143813.83456360188/8.0), REAL_CONST(143839.8001840208/8.0), REAL_CONST(143865.76697630569/8.0), REAL_CONST(143891.73494035081/8.0), REAL_CONST(143917.7040760504/8.0), REAL_CONST(143943.67438329876/8.0), REAL_CONST(143969.6458619902/8.0), REAL_CONST(143995.61851201905/8.0), REAL_CONST(144021.59233327967/8.0), REAL_CONST(144047.56732566646/8.0), REAL_CONST(144073.54348907378/8.0), REAL_CONST(144099.52082339607/8.0), REAL_CONST(144125.49932852783/8.0), REAL_CONST(144151.4790043635/8.0), REAL_CONST(144177.45985079758/8.0), REAL_CONST(144203.44186772458/8.0), REAL_CONST(144229.42505503909/8.0), REAL_CONST(144255.40941263564/8.0), REAL_CONST(144281.39494040885/8.0), REAL_CONST(144307.38163825331/8.0), REAL_CONST(144333.36950606373/8.0), REAL_CONST(144359.35854373468/8.0), REAL_CONST(144385.34875116093/8.0), REAL_CONST(144411.34012823718/8.0), REAL_CONST(144437.33267485813/8.0), REAL_CONST(144463.32639091855/8.0), REAL_CONST(144489.32127631325/8.0), REAL_CONST(144515.31733093705/8.0), REAL_CONST(144541.31455468474/8.0), REAL_CONST(144567.3129474512/8.0), REAL_CONST(144593.3125091313/8.0), REAL_CONST(144619.31323961995/8.0), REAL_CONST(144645.31513881206/8.0), REAL_CONST(144671.31820660262/8.0), REAL_CONST(144697.32244288657/8.0), REAL_CONST(144723.32784755889/8.0), REAL_CONST(144749.33442051467/8.0), REAL_CONST(144775.34216164888/8.0), REAL_CONST(144801.35107085665/8.0), REAL_CONST(144827.36114803303/8.0), REAL_CONST(144853.37239307314/8.0), REAL_CONST(144879.38480587213/8.0), REAL_CONST(144905.39838632516/8.0), REAL_CONST(144931.41313432742/8.0), REAL_CONST(144957.4290497741/8.0), REAL_CONST(144983.44613256046/8.0), REAL_CONST(145009.46438258173/8.0), REAL_CONST(145035.48379973322/8.0), REAL_CONST(145061.50438391021/8.0), REAL_CONST(145087.52613500805/8.0), REAL_CONST(145113.54905292206/8.0), REAL_CONST(145139.57313754765/8.0), REAL_CONST(145165.59838878017/8.0), REAL_CONST(145191.62480651509/8.0), REAL_CONST(145217.65239064783/8.0), REAL_CONST(145243.68114107384/8.0), REAL_CONST(145269.71105768863/8.0), REAL_CONST(145295.74214038774/8.0), REAL_CONST(145321.77438906668/8.0), REAL_CONST(145347.80780362099/8.0), REAL_CONST(145373.84238394629/8.0), REAL_CONST(145399.87812993818/8.0), REAL_CONST(145425.91504149229/8.0), REAL_CONST(145451.95311850426/8.0), REAL_CONST(145477.9923608698/8.0), REAL_CONST(145504.03276848458/8.0), REAL_CONST(145530.07434124436/8.0), REAL_CONST(145556.11707904484/8.0), REAL_CONST(145582.16098178181/8.0), REAL_CONST(145608.20604935108/8.0), REAL_CONST(145634.25228164849/8.0), REAL_CONST(145660.29967856981/8.0), REAL_CONST(145686.34824001096/8.0), REAL_CONST(145712.39796586783/8.0), REAL_CONST(145738.4488560363/8.0), REAL_CONST(145764.50091041232/8.0), REAL_CONST(145790.55412889185/8.0), REAL_CONST(145816.60851137087/8.0), REAL_CONST(145842.66405774537/8.0), REAL_CONST(145868.72076791141/8.0), REAL_CONST(145894.77864176501/8.0), REAL_CONST(145920.83767920226/8.0), REAL_CONST(145946.89788011924/8.0), REAL_CONST(145972.95924441208/8.0), REAL_CONST(145999.02177197693/8.0), REAL_CONST(146025.08546270995/8.0), REAL_CONST(146051.15031650732/8.0), REAL_CONST(146077.21633326527/8.0), REAL_CONST(146103.28351288004/8.0), REAL_CONST(146129.35185524789/8.0), REAL_CONST(146155.42136026506/8.0), REAL_CONST(146181.49202782792/8.0), REAL_CONST(146207.56385783272/8.0), REAL_CONST(146233.63685017588/8.0), REAL_CONST(146259.71100475377/8.0), REAL_CONST(146285.78632146274/8.0), REAL_CONST(146311.86280019928/8.0), REAL_CONST(146337.94044085976/8.0), REAL_CONST(146364.01924334071/8.0), REAL_CONST(146390.09920753856/8.0), REAL_CONST(146416.18033334985/8.0), REAL_CONST(146442.26262067116/8.0), REAL_CONST(146468.34606939898/8.0), REAL_CONST(146494.43067942993/8.0), REAL_CONST(146520.51645066062/8.0), REAL_CONST(146546.60338298764/8.0), REAL_CONST(146572.69147630769/8.0), REAL_CONST(146598.78073051744/8.0), REAL_CONST(146624.87114551352/8.0), REAL_CONST(146650.96272119274/8.0), REAL_CONST(146677.05545745179/8.0), REAL_CONST(146703.14935418745/8.0), REAL_CONST(146729.2444112965/8.0), REAL_CONST(146755.34062867577/8.0), REAL_CONST(146781.43800622207/8.0), REAL_CONST(146807.53654383228/8.0), REAL_CONST(146833.63624140329/8.0), REAL_CONST(146859.73709883197/8.0), REAL_CONST(146885.83911601527/8.0), REAL_CONST(146911.94229285014/8.0), REAL_CONST(146938.04662923355/8.0), REAL_CONST(146964.15212506248/8.0), REAL_CONST(146990.25878023397/8.0), REAL_CONST(147016.36659464505/8.0), REAL_CONST(147042.47556819281/8.0), REAL_CONST(147068.58570077427/8.0), REAL_CONST(147094.6969922866/8.0), REAL_CONST(147120.80944262692/8.0), REAL_CONST(147146.92305169237/8.0), REAL_CONST(147173.03781938017/8.0), REAL_CONST(147199.15374558745/8.0), REAL_CONST(147225.27083021149/8.0), REAL_CONST(147251.38907314953/8.0), REAL_CONST(147277.50847429881/8.0), REAL_CONST(147303.62903355664/8.0), REAL_CONST(147329.75075082036/8.0), REAL_CONST(147355.87362598727/8.0), REAL_CONST(147381.99765895473/8.0), REAL_CONST(147408.12284962015/8.0), REAL_CONST(147434.24919788091/8.0), REAL_CONST(147460.37670363448/8.0), REAL_CONST(147486.50536677826/8.0), REAL_CONST(147512.63518720976/8.0), REAL_CONST(147538.76616482646/8.0), REAL_CONST(147564.89829952587/8.0), REAL_CONST(147591.03159120557/8.0), REAL_CONST(147617.16603976308/8.0), REAL_CONST(147643.30164509601/8.0), REAL_CONST(147669.43840710199/8.0), REAL_CONST(147695.57632567859/8.0), REAL_CONST(147721.71540072354/8.0), REAL_CONST(147747.85563213445/8.0), REAL_CONST(147773.99701980909/8.0), REAL_CONST(147800.13956364512/8.0), REAL_CONST(147826.28326354033/8.0), REAL_CONST(147852.42811939248/8.0), REAL_CONST(147878.57413109933/8.0), REAL_CONST(147904.72129855872/8.0), REAL_CONST(147930.86962166851/8.0), REAL_CONST(147957.01910032652/8.0), REAL_CONST(147983.16973443062/8.0), REAL_CONST(148009.32152387875/8.0), REAL_CONST(148035.47446856883/8.0), REAL_CONST(148061.62856839882/8.0), REAL_CONST(148087.78382326665/8.0), REAL_CONST(148113.94023307035/8.0), REAL_CONST(148140.09779770792/8.0), REAL_CONST(148166.25651707739/8.0), REAL_CONST(148192.41639107687/8.0), REAL_CONST(148218.57741960438/8.0), REAL_CONST(148244.73960255808/8.0), REAL_CONST(148270.90293983606/8.0), REAL_CONST(148297.0674313365/8.0), REAL_CONST(148323.23307695755/8.0), REAL_CONST(148349.39987659742/8.0), REAL_CONST(148375.56783015432/8.0), REAL_CONST(148401.73693752653/8.0), REAL_CONST(148427.90719861226/8.0), REAL_CONST(148454.07861330983/8.0), REAL_CONST(148480.25118151752/8.0), REAL_CONST(148506.42490313368/8.0), REAL_CONST(148532.59977805667/8.0), REAL_CONST(148558.77580618486/8.0), REAL_CONST(148584.95298741665/8.0), REAL_CONST(148611.13132165043/8.0), REAL_CONST(148637.31080878471/8.0), REAL_CONST(148663.49144871789/8.0), REAL_CONST(148689.6732413485/8.0), REAL_CONST(148715.85618657502/8.0), REAL_CONST(148742.040284296/8.0), REAL_CONST(148768.22553440998/8.0), REAL_CONST(148794.41193681557/8.0), REAL_CONST(148820.59949141133/8.0), REAL_CONST(148846.78819809589/8.0), REAL_CONST(148872.97805676793/8.0), REAL_CONST(148899.16906732606/8.0), REAL_CONST(148925.36122966901/8.0), REAL_CONST(148951.55454369547/8.0), REAL_CONST(148977.74900930419/8.0), REAL_CONST(149003.9446263939/8.0), REAL_CONST(149030.1413948634/8.0), REAL_CONST(149056.33931461151/8.0), REAL_CONST(149082.53838553699/8.0), REAL_CONST(149108.73860753875/8.0), REAL_CONST(149134.9399805156/8.0), REAL_CONST(149161.14250436646/8.0), REAL_CONST(149187.34617899026/8.0), REAL_CONST(149213.5510042859/8.0), REAL_CONST(149239.75698015234/8.0), REAL_CONST(149265.96410648854/8.0), REAL_CONST(149292.17238319354/8.0), REAL_CONST(149318.38181016635/8.0), REAL_CONST(149344.59238730598/8.0), REAL_CONST(149370.80411451156/8.0), REAL_CONST(149397.01699168212/8.0), REAL_CONST(149423.23101871679/8.0), REAL_CONST(149449.44619551473/8.0), REAL_CONST(149475.66252197503/8.0), REAL_CONST(149501.87999799693/8.0), REAL_CONST(149528.0986234796/8.0), REAL_CONST(149554.31839832227/8.0), REAL_CONST(149580.53932242419/8.0), REAL_CONST(149606.76139568459/8.0), REAL_CONST(149632.98461800278/8.0), REAL_CONST(149659.20898927809/8.0), REAL_CONST(149685.43450940982/8.0), REAL_CONST(149711.66117829733/8.0), REAL_CONST(149737.88899584001/8.0), REAL_CONST(149764.11796193724/8.0), REAL_CONST(149790.34807648844/8.0), REAL_CONST(149816.57933939309/8.0), REAL_CONST(149842.81175055061/8.0), REAL_CONST(149869.04530986046/8.0), REAL_CONST(149895.28001722222/8.0), REAL_CONST(149921.51587253538/8.0), REAL_CONST(149947.75287569952/8.0), REAL_CONST(149973.99102661415/8.0), REAL_CONST(150000.23032517891/8.0), REAL_CONST(150026.47077129342/8.0), REAL_CONST(150052.71236485732/8.0), REAL_CONST(150078.95510577026/8.0), REAL_CONST(150105.1989939319/8.0), REAL_CONST(150131.444029242/8.0), REAL_CONST(150157.69021160025/8.0), REAL_CONST(150183.93754090639/8.0), REAL_CONST(150210.18601706024/8.0), REAL_CONST(150236.43563996154/8.0), REAL_CONST(150262.68640951012/8.0), REAL_CONST(150288.93832560582/8.0), REAL_CONST(150315.19138814852/8.0), REAL_CONST(150341.44559703805/8.0), REAL_CONST(150367.70095217437/8.0), REAL_CONST(150393.95745345735/8.0), REAL_CONST(150420.21510078697/8.0), REAL_CONST(150446.47389406321/8.0), REAL_CONST(150472.73383318601/8.0), REAL_CONST(150498.99491805542/8.0), REAL_CONST(150525.25714857146/8.0), REAL_CONST(150551.52052463419/8.0), REAL_CONST(150577.78504614369/8.0), REAL_CONST(150604.05071300003/8.0), REAL_CONST(150630.31752510337/8.0), REAL_CONST(150656.58548235384/8.0), REAL_CONST(150682.85458465159/8.0), REAL_CONST(150709.1248318968/8.0), REAL_CONST(150735.39622398972/8.0), REAL_CONST(150761.66876083051/8.0), REAL_CONST(150787.9424423195/8.0), REAL_CONST(150814.21726835691/8.0), REAL_CONST(150840.49323884305/8.0), REAL_CONST(150866.77035367821/8.0), REAL_CONST(150893.04861276277/8.0), REAL_CONST(150919.32801599705/8.0), REAL_CONST(150945.60856328148/8.0), REAL_CONST(150971.89025451642/8.0), REAL_CONST(150998.17308960229/8.0), REAL_CONST(151024.45706843957/8.0), REAL_CONST(151050.74219092872/8.0), REAL_CONST(151077.02845697021/8.0), REAL_CONST(151103.31586646455/8.0), REAL_CONST(151129.60441931229/8.0), REAL_CONST(151155.894115414/8.0), REAL_CONST(151182.1849546702/8.0), REAL_CONST(151208.47693698155/8.0), REAL_CONST(151234.77006224863/8.0), REAL_CONST(151261.06433037209/8.0), REAL_CONST(151287.35974125259/8.0), REAL_CONST(151313.65629479082/8.0), REAL_CONST(151339.95399088747/8.0), REAL_CONST(151366.25282944329/8.0), REAL_CONST(151392.55281035902/8.0), REAL_CONST(151418.85393353543/8.0), REAL_CONST(151445.1561988733/8.0), REAL_CONST(151471.45960627345/8.0), REAL_CONST(151497.76415563675/8.0), REAL_CONST(151524.06984686397/8.0), REAL_CONST(151550.37667985607/8.0), REAL_CONST(151576.68465451393/8.0), REAL_CONST(151602.99377073845/8.0), REAL_CONST(151629.30402843058/8.0), REAL_CONST(151655.61542749128/8.0), REAL_CONST(151681.92796782157/8.0), REAL_CONST(151708.24164932242/8.0), REAL_CONST(151734.55647189484/8.0), REAL_CONST(151760.87243543993/8.0), REAL_CONST(151787.18953985872/8.0), REAL_CONST(151813.50778505235/8.0), REAL_CONST(151839.82717092187/8.0), REAL_CONST(151866.14769736846/8.0), REAL_CONST(151892.46936429327/8.0), REAL_CONST(151918.79217159748/8.0), REAL_CONST(151945.11611918229/8.0), REAL_CONST(151971.44120694889/8.0), REAL_CONST(151997.76743479856/8.0), REAL_CONST(152024.09480263255/8.0), REAL_CONST(152050.42331035214/8.0), REAL_CONST(152076.75295785864/8.0), REAL_CONST(152103.08374505339/8.0), REAL_CONST(152129.41567183775/8.0), REAL_CONST(152155.74873811303/8.0), REAL_CONST(152182.08294378067/8.0), REAL_CONST(152208.41828874208/8.0), REAL_CONST(152234.75477289871/8.0), REAL_CONST(152261.09239615197/8.0), REAL_CONST(152287.43115840337/8.0), REAL_CONST(152313.77105955439/8.0), REAL_CONST(152340.11209950657/8.0), REAL_CONST(152366.45427816146/8.0), REAL_CONST(152392.79759542056/8.0), REAL_CONST(152419.14205118554/8.0), REAL_CONST(152445.48764535793/8.0), REAL_CONST(152471.8343778394/8.0), REAL_CONST(152498.18224853161/8.0), REAL_CONST(152524.53125733617/8.0), REAL_CONST(152550.88140415482/8.0), REAL_CONST(152577.23268888926/8.0), REAL_CONST(152603.58511144121/8.0), REAL_CONST(152629.93867171241/8.0), REAL_CONST(152656.29336960468/8.0), REAL_CONST(152682.64920501978/8.0), REAL_CONST(152709.00617785956/8.0), REAL_CONST(152735.36428802583/8.0), REAL_CONST(152761.72353542043/8.0), REAL_CONST(152788.08391994529/8.0), REAL_CONST(152814.44544150229/8.0), REAL_CONST(152840.80809999333/8.0), REAL_CONST(152867.17189532038/8.0), REAL_CONST(152893.53682738543/8.0), REAL_CONST(152919.90289609041/8.0), REAL_CONST(152946.27010133737/8.0), REAL_CONST(152972.63844302832/8.0), REAL_CONST(152999.00792106529/8.0), REAL_CONST(153025.37853535041/8.0), REAL_CONST(153051.7502857857/8.0), REAL_CONST(153078.12317227334/8.0), REAL_CONST(153104.4971947154/8.0), REAL_CONST(153130.8723530141/8.0), REAL_CONST(153157.24864707157/8.0), REAL_CONST(153183.62607679001/8.0), REAL_CONST(153210.00464207167/8.0), REAL_CONST(153236.38434281875/8.0), REAL_CONST(153262.76517893354/8.0), REAL_CONST(153289.14715031831/8.0), REAL_CONST(153315.53025687535/8.0), REAL_CONST(153341.91449850702/8.0), REAL_CONST(153368.2998751156/8.0), REAL_CONST(153394.68638660354/8.0), REAL_CONST(153421.07403287315/8.0), REAL_CONST(153447.46281382689/8.0), REAL_CONST(153473.85272936718/8.0), REAL_CONST(153500.24377939643/8.0), REAL_CONST(153526.63596381716/8.0), REAL_CONST(153553.02928253182/8.0), REAL_CONST(153579.42373544298/8.0), REAL_CONST(153605.81932245308/8.0), REAL_CONST(153632.21604346478/8.0), REAL_CONST(153658.61389838057/8.0), REAL_CONST(153685.0128871031/8.0), REAL_CONST(153711.41300953497/8.0), REAL_CONST(153737.81426557881/8.0), REAL_CONST(153764.21665513728/8.0), REAL_CONST(153790.62017811305/8.0), REAL_CONST(153817.02483440886/8.0), REAL_CONST(153843.43062392739/8.0), REAL_CONST(153869.83754657139/8.0), REAL_CONST(153896.24560224367/8.0), REAL_CONST(153922.65479084692/8.0), REAL_CONST(153949.06511228404/8.0), REAL_CONST(153975.4765664578/8.0), REAL_CONST(154001.88915327107/8.0), REAL_CONST(154028.30287262669/8.0), REAL_CONST(154054.71772442761/8.0), REAL_CONST(154081.13370857667/8.0), REAL_CONST(154107.55082497682/8.0), REAL_CONST(154133.96907353101/8.0), REAL_CONST(154160.38845414223/8.0), REAL_CONST(154186.80896671346/8.0), REAL_CONST(154213.23061114774/8.0), REAL_CONST(154239.65338734805/8.0), REAL_CONST(154266.07729521746/8.0), REAL_CONST(154292.50233465908/8.0), REAL_CONST(154318.92850557598/8.0), REAL_CONST(154345.35580787127/8.0), REAL_CONST(154371.7842414481/8.0), REAL_CONST(154398.21380620965/8.0), REAL_CONST(154424.64450205903/8.0), REAL_CONST(154451.07632889951/8.0), REAL_CONST(154477.50928663427/8.0), REAL_CONST(154503.94337516659/8.0), REAL_CONST(154530.37859439969/8.0), REAL_CONST(154556.81494423689/8.0), REAL_CONST(154583.25242458144/8.0), REAL_CONST(154609.69103533673/8.0), REAL_CONST(154636.13077640603/8.0), REAL_CONST(154662.57164769279/8.0), REAL_CONST(154689.01364910032/8.0), REAL_CONST(154715.45678053208/8.0), REAL_CONST(154741.90104189145/8.0), REAL_CONST(154768.34643308193/8.0), REAL_CONST(154794.79295400696/8.0), REAL_CONST(154821.24060457002/8.0), REAL_CONST(154847.68938467462/8.0), REAL_CONST(154874.13929422433/8.0), REAL_CONST(154900.59033312264/8.0), REAL_CONST(154927.04250127316/8.0), REAL_CONST(154953.49579857948/8.0), REAL_CONST(154979.95022494521/8.0), REAL_CONST(155006.40578027396/8.0), REAL_CONST(155032.86246446942/8.0), REAL_CONST(155059.32027743524/8.0), REAL_CONST(155085.77921907514/8.0), REAL_CONST(155112.2392892928/8.0), REAL_CONST(155138.70048799197/8.0), REAL_CONST(155165.16281507642/8.0), REAL_CONST(155191.62627044989/8.0), REAL_CONST(155218.09085401625/8.0), REAL_CONST(155244.55656567923/8.0), REAL_CONST(155271.02340534274/8.0), REAL_CONST(155297.49137291059/8.0), REAL_CONST(155323.96046828668/8.0), REAL_CONST(155350.4306913749/8.0), REAL_CONST(155376.90204207919/8.0), REAL_CONST(155403.37452030348/8.0), REAL_CONST(155429.84812595171/8.0), REAL_CONST(155456.32285892789/8.0), REAL_CONST(155482.79871913602/8.0), REAL_CONST(155509.27570648011/8.0), REAL_CONST(155535.75382086422/8.0), REAL_CONST(155562.23306219239/8.0), REAL_CONST(155588.71343036872/8.0), REAL_CONST(155615.19492529731/8.0), REAL_CONST(155641.67754688227/8.0), REAL_CONST(155668.16129502779/8.0), REAL_CONST(155694.64616963797/8.0), REAL_CONST(155721.13217061706/8.0), REAL_CONST(155747.61929786921/8.0), REAL_CONST(155774.10755129869/8.0), REAL_CONST(155800.59693080973/8.0), REAL_CONST(155827.08743630661/8.0), REAL_CONST(155853.57906769359/8.0), REAL_CONST(155880.07182487496/8.0), REAL_CONST(155906.56570775513/8.0), REAL_CONST(155933.06071623837/8.0), REAL_CONST(155959.55685022907/8.0), REAL_CONST(155986.05410963166/8.0), REAL_CONST(156012.5524943505/8.0), REAL_CONST(156039.05200429002/8.0), REAL_CONST(156065.55263935472/8.0), REAL_CONST(156092.054399449/8.0), REAL_CONST(156118.5572844774/8.0), REAL_CONST(156145.06129434443/8.0), REAL_CONST(156171.5664289546/8.0), REAL_CONST(156198.07268821247/8.0), REAL_CONST(156224.5800720226/8.0), REAL_CONST(156251.08858028959/8.0), REAL_CONST(156277.59821291809/8.0), REAL_CONST(156304.10896981266/8.0), REAL_CONST(156330.62085087801/8.0), REAL_CONST(156357.1338560188/8.0), REAL_CONST(156383.64798513969/8.0), REAL_CONST(156410.16323814544/8.0), REAL_CONST(156436.67961494075/8.0), REAL_CONST(156463.1971154304/8.0), REAL_CONST(156489.71573951913/8.0), REAL_CONST(156516.23548711176/8.0), REAL_CONST(156542.75635811311/8.0), REAL_CONST(156569.27835242799/8.0), REAL_CONST(156595.80146996127/8.0), REAL_CONST(156622.32571061782/8.0), REAL_CONST(156648.85107430254/8.0), REAL_CONST(156675.37756092031/8.0), REAL_CONST(156701.90517037612/8.0), REAL_CONST(156728.43390257491/8.0), REAL_CONST(156754.96375742162/8.0), REAL_CONST(156781.49473482129/8.0), REAL_CONST(156808.02683467892/8.0), REAL_CONST(156834.5600568995/8.0), REAL_CONST(156861.09440138817/8.0), REAL_CONST(156887.62986804993/8.0), REAL_CONST(156914.16645678994/8.0), REAL_CONST(156940.70416751326/8.0), REAL_CONST(156967.24300012505/8.0), REAL_CONST(156993.78295453047/8.0), REAL_CONST(157020.32403063469/8.0), REAL_CONST(157046.8662283429/8.0), REAL_CONST(157073.40954756032/8.0), REAL_CONST(157099.9539881922/8.0), REAL_CONST(157126.49955014378/8.0), REAL_CONST(157153.04623332032/8.0), REAL_CONST(157179.59403762716/8.0), REAL_CONST(157206.14296296958/8.0), REAL_CONST(157232.69300925292/8.0), REAL_CONST(157259.24417638258/8.0), REAL_CONST(157285.79646426387/8.0), REAL_CONST(157312.34987280221/8.0), REAL_CONST(157338.90440190304/8.0), REAL_CONST(157365.46005147175/8.0), REAL_CONST(157392.01682141385/8.0), REAL_CONST(157418.57471163478/8.0), REAL_CONST(157445.13372204005/8.0), REAL_CONST(157471.69385253513/8.0), REAL_CONST(157498.25510302564/8.0), REAL_CONST(157524.81747341706/8.0), REAL_CONST(157551.38096361503/8.0), REAL_CONST(157577.9455735251/8.0), REAL_CONST(157604.51130305286/8.0), REAL_CONST(157631.07815210402/8.0), REAL_CONST(157657.64612058419/8.0), REAL_CONST(157684.21520839902/8.0), REAL_CONST(157710.78541545427/8.0), REAL_CONST(157737.35674165559/8.0), REAL_CONST(157763.92918690876/8.0), REAL_CONST(157790.50275111952/8.0), REAL_CONST(157817.07743419363/8.0), REAL_CONST(157843.65323603692/8.0), REAL_CONST(157870.23015655516/8.0), REAL_CONST(157896.80819565422/8.0), REAL_CONST(157923.3873532399/8.0), REAL_CONST(157949.96762921812/8.0), REAL_CONST(157976.54902349479/8.0), REAL_CONST(158003.13153597576/8.0), REAL_CONST(158029.71516656701/8.0), REAL_CONST(158056.29991517449/8.0), REAL_CONST(158082.88578170416/8.0), REAL_CONST(158109.47276606198/8.0), REAL_CONST(158136.06086815402/8.0), REAL_CONST(158162.65008788629/8.0), REAL_CONST(158189.24042516484/8.0), REAL_CONST(158215.83187989573/8.0), REAL_CONST(158242.42445198505/8.0), REAL_CONST(158269.01814133892/8.0), REAL_CONST(158295.61294786347/8.0), REAL_CONST(158322.20887146486/8.0), REAL_CONST(158348.80591204923/8.0), REAL_CONST(158375.4040695228/8.0), REAL_CONST(158402.00334379176/8.0), REAL_CONST(158428.60373476235/8.0), REAL_CONST(158455.2052423408/8.0), REAL_CONST(158481.80786643337/8.0), REAL_CONST(158508.41160694641/8.0), REAL_CONST(158535.01646378616/8.0), REAL_CONST(158561.62243685898/8.0), REAL_CONST(158588.2295260712/8.0), REAL_CONST(158614.8377313292/8.0), REAL_CONST(158641.44705253936/8.0), REAL_CONST(158668.05748960807/8.0), REAL_CONST(158694.66904244179/8.0), REAL_CONST(158721.28171094693/8.0), REAL_CONST(158747.89549502998/8.0), REAL_CONST(158774.5103945974/8.0), REAL_CONST(158801.12640955573/8.0), REAL_CONST(158827.74353981143/8.0), REAL_CONST(158854.36178527112/8.0), REAL_CONST(158880.9811458413/8.0), REAL_CONST(158907.60162142856/8.0), REAL_CONST(158934.22321193956/8.0), REAL_CONST(158960.84591728085/8.0), REAL_CONST(158987.46973735912/8.0), REAL_CONST(159014.09467208097/8.0), REAL_CONST(159040.72072135314/8.0), REAL_CONST(159067.3478850823/8.0), REAL_CONST(159093.97616317519/8.0), REAL_CONST(159120.60555553852/8.0), REAL_CONST(159147.23606207906/8.0), REAL_CONST(159173.8676827036/8.0), REAL_CONST(159200.50041731889/8.0), REAL_CONST(159227.13426583182/8.0), REAL_CONST(159253.76922814918/8.0), REAL_CONST(159280.40530417781/8.0), REAL_CONST(159307.04249382461/8.0), REAL_CONST(159333.68079699649/8.0), REAL_CONST(159360.32021360032/8.0), REAL_CONST(159386.96074354305/8.0), REAL_CONST(159413.60238673165/8.0), REAL_CONST(159440.24514307309/8.0), REAL_CONST(159466.88901247433/8.0), REAL_CONST(159493.53399484244/8.0), REAL_CONST(159520.18009008438/8.0), REAL_CONST(159546.82729810724/8.0), REAL_CONST(159573.47561881805/8.0), REAL_CONST(159600.12505212394/8.0), REAL_CONST(159626.77559793202/8.0), REAL_CONST(159653.42725614941/8.0), REAL_CONST(159680.08002668325/8.0), REAL_CONST(159706.73390944069/8.0), REAL_CONST(159733.38890432892/8.0), REAL_CONST(159760.04501125516/8.0), REAL_CONST(159786.70223012666/8.0), REAL_CONST(159813.36056085059/8.0), REAL_CONST(159840.02000333427/8.0), REAL_CONST(159866.68055748497/8.0), REAL_CONST(159893.34222320997/8.0), REAL_CONST(159920.00500041663/8.0), REAL_CONST(159946.66888901225/8.0), REAL_CONST(159973.33388890422/8.0), REAL_CONST(159999.99999999988/8.0), REAL_CONST(160026.66722220668/8.0), REAL_CONST(160053.33555543202/8.0), REAL_CONST(160080.0049995833/8.0), REAL_CONST(160106.67555456801/8.0), REAL_CONST(160133.3472202936/8.0), REAL_CONST(160160.0199966676/8.0), REAL_CONST(160186.6938835975/8.0), REAL_CONST(160213.36888099083/8.0), REAL_CONST(160240.04498875517/8.0), REAL_CONST(160266.72220679806/8.0), REAL_CONST(160293.40053502709/8.0), REAL_CONST(160320.07997334987/8.0), REAL_CONST(160346.76052167406/8.0), REAL_CONST(160373.44217990729/8.0), REAL_CONST(160400.1249479572/8.0), REAL_CONST(160426.80882573154/8.0), REAL_CONST(160453.49381313793/8.0), REAL_CONST(160480.17991008417/8.0), REAL_CONST(160506.86711647795/8.0), REAL_CONST(160533.55543222709/8.0), REAL_CONST(160560.24485723933/8.0), REAL_CONST(160586.93539142248/8.0), REAL_CONST(160613.62703468435/8.0), REAL_CONST(160640.31978693281/8.0), REAL_CONST(160667.01364807569/8.0), REAL_CONST(160693.70861802087/8.0), REAL_CONST(160720.40469667627/8.0), REAL_CONST(160747.1018839498/8.0), REAL_CONST(160773.80017974938/8.0), REAL_CONST(160800.49958398298/8.0), REAL_CONST(160827.20009655855/8.0), REAL_CONST(160853.90171738411/8.0), REAL_CONST(160880.60444636765/8.0), REAL_CONST(160907.30828341722/8.0), REAL_CONST(160934.01322844089/8.0), REAL_CONST(160960.71928134665/8.0), REAL_CONST(160987.42644204266/8.0), REAL_CONST(161014.13471043704/8.0), REAL_CONST(161040.84408643784/8.0), REAL_CONST(161067.55456995327/8.0), REAL_CONST(161094.26616089148/8.0), REAL_CONST(161120.97885916062/8.0), REAL_CONST(161147.69266466892/8.0), REAL_CONST(161174.40757732463/8.0), REAL_CONST(161201.12359703594/8.0), REAL_CONST(161227.84072371112/8.0), REAL_CONST(161254.55895725847/8.0), REAL_CONST(161281.27829758628/8.0), REAL_CONST(161307.99874460287/8.0), REAL_CONST(161334.72029821656/8.0), REAL_CONST(161361.44295833571/8.0), REAL_CONST(161388.1667248687/8.0), REAL_CONST(161414.89159772391/8.0), REAL_CONST(161441.61757680977/8.0), REAL_CONST(161468.34466203468/8.0), REAL_CONST(161495.07285330712/8.0), REAL_CONST(161521.80215053557/8.0), REAL_CONST(161548.53255362847/8.0), REAL_CONST(161575.26406249436/8.0), REAL_CONST(161601.99667704175/8.0), REAL_CONST(161628.7303971792/8.0), REAL_CONST(161655.46522281526/8.0), REAL_CONST(161682.20115385848/8.0), REAL_CONST(161708.93819021754/8.0), REAL_CONST(161735.67633180099/8.0), REAL_CONST(161762.41557851751/8.0), REAL_CONST(161789.15593027571/8.0), REAL_CONST(161815.89738698432/8.0), REAL_CONST(161842.63994855201/8.0), REAL_CONST(161869.38361488748/8.0), REAL_CONST(161896.1283858995/8.0), REAL_CONST(161922.87426149679/8.0), REAL_CONST(161949.62124158812/8.0), REAL_CONST(161976.36932608229/8.0), REAL_CONST(162003.1185148881/8.0), REAL_CONST(162029.8688079144/8.0), REAL_CONST(162056.62020507001/8.0), REAL_CONST(162083.37270626382/8.0), REAL_CONST(162110.12631140469/8.0), REAL_CONST(162136.88102040152/8.0), REAL_CONST(162163.63683316324/8.0), REAL_CONST(162190.39374959879/8.0), REAL_CONST(162217.15176961714/8.0), REAL_CONST(162243.91089312723/8.0), REAL_CONST(162270.67112003808/8.0), REAL_CONST(162297.43245025873/8.0), REAL_CONST(162324.19488369819/8.0), REAL_CONST(162350.9584202655/8.0), REAL_CONST(162377.72305986975/8.0), REAL_CONST(162404.48880242003/8.0), REAL_CONST(162431.25564782543/8.0), REAL_CONST(162458.02359599507/8.0), REAL_CONST(162484.79264683815/8.0), REAL_CONST(162511.56280026378/8.0), REAL_CONST(162538.33405618116/8.0), REAL_CONST(162565.10641449949/8.0), REAL_CONST(162591.87987512801/8.0), REAL_CONST(162618.65443797593/8.0), REAL_CONST(162645.43010295252/8.0), REAL_CONST(162672.20686996708/8.0), REAL_CONST(162698.98473892888/8.0), REAL_CONST(162725.76370974723/8.0), REAL_CONST(162752.54378233149/8.0), REAL_CONST(162779.32495659095/8.0), REAL_CONST(162806.10723243505/8.0), REAL_CONST(162832.89060977317/8.0), REAL_CONST(162859.67508851466/8.0), REAL_CONST(162886.46066856899/8.0), REAL_CONST(162913.24734984562/8.0), REAL_CONST(162940.03513225398/8.0), REAL_CONST(162966.82401570358/8.0), REAL_CONST(162993.6140001039/8.0), REAL_CONST(163020.40508536444/8.0), REAL_CONST(163047.19727139481/8.0), REAL_CONST(163073.99055810447/8.0), REAL_CONST(163100.78494540305/8.0), REAL_CONST(163127.58043320014/8.0), REAL_CONST(163154.37702140535/8.0), REAL_CONST(163181.17470992831/8.0), REAL_CONST(163207.97349867865/8.0), REAL_CONST(163234.77338756606/8.0), REAL_CONST(163261.57437650024/8.0), REAL_CONST(163288.37646539087/8.0), REAL_CONST(163315.17965414765/8.0), REAL_CONST(163341.98394268038/8.0), REAL_CONST(163368.78933089875/8.0), REAL_CONST(163395.59581871261/8.0), REAL_CONST(163422.40340603172/8.0), REAL_CONST(163449.2120927659/8.0), REAL_CONST(163476.02187882498/8.0), REAL_CONST(163502.83276411882/8.0), REAL_CONST(163529.6447485573/8.0), REAL_CONST(163556.45783205028/8.0), REAL_CONST(163583.2720145077/8.0), REAL_CONST(163610.08729583945/8.0), REAL_CONST(163636.90367595552/8.0), REAL_CONST(163663.72115476584/8.0), REAL_CONST(163690.53973218042/8.0), REAL_CONST(163717.35940810922/8.0), REAL_CONST(163744.18018246227/8.0), REAL_CONST(163771.00205514964/8.0), REAL_CONST(163797.82502608138/8.0), REAL_CONST(163824.64909516752/8.0), REAL_CONST(163851.4742623182/8.0), REAL_CONST(163878.3005274435/8.0), REAL_CONST(163905.12789045356/8.0), REAL_CONST(163931.95635125853/8.0), REAL_CONST(163958.78590976857/8.0), REAL_CONST(163985.61656589387/8.0), REAL_CONST(164012.44831954464/8.0), REAL_CONST(164039.28117063109/8.0), REAL_CONST(164066.11511906344/8.0), REAL_CONST(164092.95016475199/8.0), REAL_CONST(164119.78630760699/8.0), REAL_CONST(164146.62354753874/8.0), REAL_CONST(164173.46188445756/8.0), REAL_CONST(164200.30131827376/8.0), REAL_CONST(164227.14184889771/8.0), REAL_CONST(164253.98347623978/8.0), REAL_CONST(164280.82620021031/8.0), REAL_CONST(164307.67002071979/8.0), REAL_CONST(164334.51493767856/8.0), REAL_CONST(164361.3609509971/8.0), REAL_CONST(164388.20806058586/8.0), REAL_CONST(164415.05626635533/8.0), REAL_CONST(164441.905568216/8.0), REAL_CONST(164468.75596607837/8.0), REAL_CONST(164495.607459853/8.0), REAL_CONST(164522.4600494504/8.0), REAL_CONST(164549.31373478117/8.0), REAL_CONST(164576.16851575591/8.0), REAL_CONST(164603.02439228518/8.0), REAL_CONST(164629.88136427966/8.0), REAL_CONST(164656.73943164994/8.0), REAL_CONST(164683.59859430668/8.0), REAL_CONST(164710.45885216061/8.0), REAL_CONST(164737.32020512238/8.0), REAL_CONST(164764.1826531027/8.0), REAL_CONST(164791.04619601235/8.0), REAL_CONST(164817.91083376206/8.0), REAL_CONST(164844.77656626256/8.0), REAL_CONST(164871.64339342469/8.0), REAL_CONST(164898.51131515924/8.0), REAL_CONST(164925.38033137703/8.0), REAL_CONST(164952.25044198887/8.0), REAL_CONST(164979.1216469057/8.0), REAL_CONST(165005.9939460383/8.0), REAL_CONST(165032.86733929763/8.0), REAL_CONST(165059.7418265946/8.0), REAL_CONST(165086.61740784015/8.0), REAL_CONST(165113.4940829452/8.0) #endif }; #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/rvlc.h0000644000175000017500000000317414647725152015032 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: rvlc.h,v 1.17 2007/11/01 12:33:34 menno Exp $ **/ #ifndef __RVLC_SCF_H__ #define __RVLC_SCF_H__ #ifdef __cplusplus extern "C" { #endif typedef struct { int8_t index; uint8_t len; uint32_t cw; } rvlc_huff_table; #define ESC_VAL 7 uint8_t rvlc_scale_factor_data(ic_stream *ics, bitfile *ld); uint8_t rvlc_decode_scale_factors(ic_stream *ics, bitfile *ld); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/diff_from_faad2-2.6.1.patch0000644000175000017500000000036214647725152020362 0ustar meme--- faad2/libfaad/common.h 2007-11-01 13:33:30.000000000 +0100 +++ faad2/libfaad/common.h 2007-11-01 18:51:01.480721384 +0100 @@ -36,7 +36,7 @@ #endif #ifdef HAVE_CONFIG_H -# include "../config.h" +# include #endif #if 1 xine-lib-1.2/contrib/libfaad/ssr_win.h0000644000175000017500000003274014647725152015551 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. ** ** $Id: ssr_win.h,v 1.16 2007/11/01 12:33:39 menno Exp $ **/ #ifndef __SSR_WIN_H__ #define __SSR_WIN_H__ #ifdef __cplusplus extern "C" { #endif #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif static const real_t sine_short_32[] = { 0.0245412290, 0.0735645667, 0.1224106774, 0.1709618866, 0.2191012502, 0.2667127550, 0.3136817515, 0.3598950505, 0.4052413106, 0.4496113360, 0.4928981960, 0.5349976420, 0.5758082271, 0.6152316332, 0.6531728506, 0.6895405650, 0.7242470980, 0.7572088838, 0.7883464694, 0.8175848126, 0.8448535800, 0.8700870275, 0.8932242990, 0.9142097831, 0.9329928160, 0.9495282173, 0.9637760520, 0.9757021666, 0.9852776527, 0.9924795628, 0.9972904325, 0.9996988177 }; static const real_t sine_long_256[] = { 0.0030679568, 0.0092037553, 0.0153392069, 0.0214740802, 0.0276081469, 0.0337411724, 0.0398729295, 0.0460031852, 0.0521317050, 0.0582582653, 0.0643826351, 0.0705045760, 0.0766238645, 0.0827402696, 0.0888535529, 0.0949634984, 0.1010698676, 0.1071724296, 0.1132709533, 0.1193652153, 0.1254549921, 0.1315400302, 0.1376201212, 0.1436950415, 0.1497645378, 0.1558284014, 0.1618863940, 0.1679383069, 0.1739838719, 0.1800229102, 0.1860551536, 0.1920804083, 0.1980984211, 0.2041089684, 0.2101118416, 0.2161068022, 0.2220936269, 0.2280720919, 0.2340419590, 0.2400030345, 0.2459550500, 0.2518978119, 0.2578310966, 0.2637546957, 0.2696683407, 0.2755718231, 0.2814649343, 0.2873474658, 0.2932191789, 0.2990798354, 0.3049292266, 0.3107671738, 0.3165933788, 0.3224076927, 0.3282098472, 0.3339996636, 0.3397769034, 0.3455413282, 0.3512927592, 0.3570309579, 0.3627557456, 0.3684668541, 0.3741640747, 0.3798472285, 0.3855160773, 0.3911703825, 0.3968099952, 0.4024346471, 0.4080441594, 0.4136383235, 0.4192169011, 0.4247796834, 0.4303264916, 0.4358570874, 0.4413712919, 0.4468688369, 0.4523496032, 0.4578133225, 0.4632597864, 0.4686888456, 0.4741002321, 0.4794937670, 0.4848692715, 0.4902265072, 0.4955652654, 0.5008853674, 0.5061866641, 0.5114688873, 0.5167317986, 0.5219752789, 0.5271991491, 0.5324031115, 0.5375871062, 0.5427507758, 0.5478940606, 0.5530167222, 0.5581185222, 0.5631993413, 0.5682589412, 0.5732972026, 0.5783138275, 0.5833086967, 0.5882815719, 0.5932323337, 0.5981607437, 0.6030666232, 0.6079497933, 0.6128100753, 0.6176473498, 0.6224613190, 0.6272518039, 0.6320187449, 0.6367619038, 0.6414810419, 0.6461760402, 0.6508467197, 0.6554928422, 0.6601143479, 0.6647109985, 0.6692826152, 0.6738290191, 0.6783500314, 0.6828455329, 0.6873153448, 0.6917592883, 0.6961771250, 0.7005687952, 0.7049341202, 0.7092728615, 0.7135848999, 0.7178700566, 0.7221282125, 0.7263591886, 0.7305628061, 0.7347388864, 0.7388873696, 0.7430079579, 0.7471006513, 0.7511651516, 0.7552013993, 0.7592092156, 0.7631884217, 0.7671388984, 0.7710605264, 0.7749531269, 0.7788165212, 0.7826505899, 0.7864552140, 0.7902302146, 0.7939754725, 0.7976908684, 0.8013761640, 0.8050313592, 0.8086562157, 0.8122506142, 0.8158144355, 0.8193475604, 0.8228498101, 0.8263210654, 0.8297612667, 0.8331701756, 0.8365477324, 0.8398938179, 0.8432082534, 0.8464909792, 0.8497417569, 0.8529606462, 0.8561473489, 0.8593018055, 0.8624239564, 0.8655136228, 0.8685707450, 0.8715950847, 0.8745866418, 0.8775452971, 0.8804709315, 0.8833633661, 0.8862225413, 0.8890483975, 0.8918406963, 0.8945994973, 0.8973246217, 0.9000158906, 0.9026733041, 0.9052967429, 0.9078861475, 0.9104412794, 0.9129621983, 0.9154487252, 0.9179008007, 0.9203183055, 0.9227011204, 0.9250492454, 0.9273625612, 0.9296408892, 0.9318842888, 0.9340925813, 0.9362657070, 0.9384035468, 0.9405061007, 0.9425731897, 0.9446048737, 0.9466009140, 0.9485613704, 0.9504860640, 0.9523749948, 0.9542281032, 0.9560452700, 0.9578264356, 0.9595715404, 0.9612805247, 0.9629532695, 0.9645897746, 0.9661900401, 0.9677538276, 0.9692812562, 0.9707721472, 0.9722265005, 0.9736442566, 0.9750253558, 0.9763697386, 0.9776773453, 0.9789481759, 0.9801821709, 0.9813792109, 0.9825392962, 0.9836624265, 0.9847484827, 0.9857975245, 0.9868094325, 0.9877841473, 0.9887216687, 0.9896219969, 0.9904850721, 0.9913108945, 0.9920993447, 0.9928504229, 0.9935641289, 0.9942404628, 0.9948793054, 0.9954807758, 0.9960446954, 0.9965711236, 0.9970600605, 0.9975114465, 0.9979252815, 0.9983015656, 0.9986402392, 0.9989413023, 0.9992047548, 0.9994305968, 0.9996188283, 0.9997693896, 0.9998823404, 0.9999576211, 0.9999952912 }; static const real_t kbd_short_32[] = { 0.0000875914060105, 0.0009321760265333, 0.0032114611466596, 0.0081009893216786, 0.0171240286619181, 0.0320720743527833, 0.0548307856028528, 0.0871361822564870, 0.1302923415174603, 0.1848955425508276, 0.2506163195331889, 0.3260874142923209, 0.4089316830907141, 0.4959414909423747, 0.5833939894958904, 0.6674601983218376, 0.7446454751465113, 0.8121892962974020, 0.8683559394406505, 0.9125649996381605, 0.9453396205809574, 0.9680864942677585, 0.9827581789763112, 0.9914756203467121, 0.9961964092194694, 0.9984956609571091, 0.9994855586984285, 0.9998533730714648, 0.9999671864476404, 0.9999948432453556, 0.9999995655238333, 0.9999999961638728 }; static const real_t kbd_long_256[] = { 0.0005851230124487, 0.0009642149851497, 0.0013558207534965, 0.0017771849644394, 0.0022352533849672, 0.0027342299070304, 0.0032773001022195, 0.0038671998069216, 0.0045064443384152, 0.0051974336885144, 0.0059425050016407, 0.0067439602523141, 0.0076040812644888, 0.0085251378135895, 0.0095093917383048, 0.0105590986429280, 0.0116765080854300, 0.0128638627792770, 0.0141233971318631, 0.0154573353235409, 0.0168678890600951, 0.0183572550877256, 0.0199276125319803, 0.0215811201042484, 0.0233199132076965, 0.0251461009666641, 0.0270617631981826, 0.0290689473405856, 0.0311696653515848, 0.0333658905863535, 0.0356595546648444, 0.0380525443366107, 0.0405466983507029, 0.0431438043376910, 0.0458455957104702, 0.0486537485902075, 0.0515698787635492, 0.0545955386770205, 0.0577322144743916, 0.0609813230826460, 0.0643442093520723, 0.0678221432558827, 0.0714163171546603, 0.0751278431308314, 0.0789577503982528, 0.0829069827918993, 0.0869763963425241, 0.0911667569410503, 0.0954787380973307, 0.0999129187977865, 0.1044697814663005, 0.1091497100326053, 0.1139529881122542, 0.1188797973021148, 0.1239302155951605, 0.1291042159181728, 0.1344016647957880, 0.1398223211441467, 0.1453658351972151, 0.1510317475686540, 0.1568194884519144, 0.1627283769610327, 0.1687576206143887, 0.1749063149634756, 0.1811734433685097, 0.1875578769224857, 0.1940583745250518, 0.2006735831073503, 0.2074020380087318, 0.2142421635060113, 0.2211922734956977, 0.2282505723293797, 0.2354151558022098, 0.2426840122941792, 0.2500550240636293, 0.2575259686921987, 0.2650945206801527, 0.2727582531907993, 0.2805146399424422, 0.2883610572460804, 0.2962947861868143, 0.3043130149466800, 0.3124128412663888, 0.3205912750432127, 0.3288452410620226, 0.3371715818562547, 0.3455670606953511, 0.3540283646950029, 0.3625521080463003, 0.3711348353596863, 0.3797730251194006, 0.3884630932439016, 0.3972013967475546, 0.4059842374986933, 0.4148078660689724, 0.4236684856687616, 0.4325622561631607, 0.4414852981630577, 0.4504336971855032, 0.4594035078775303, 0.4683907582974173, 0.4773914542472655, 0.4864015836506502, 0.4954171209689973, 0.5044340316502417, 0.5134482766032377, 0.5224558166913167, 0.5314526172383208, 0.5404346525403849, 0.5493979103766972, 0.5583383965124314, 0.5672521391870222, 0.5761351935809411, 0.5849836462541291, 0.5937936195492526, 0.6025612759529649, 0.6112828224083939, 0.6199545145721097, 0.6285726610088878, 0.6371336273176413, 0.6456338401819751, 0.6540697913388968, 0.6624380414593221, 0.6707352239341151, 0.6789580485595255, 0.6871033051160131, 0.6951678668345944, 0.7031486937449871, 0.7110428359000029, 0.7188474364707993, 0.7265597347077880, 0.7341770687621900, 0.7416968783634273, 0.7491167073477523, 0.7564342060337386, 0.7636471334404891, 0.7707533593446514, 0.7777508661725849, 0.7846377507242818, 0.7914122257259034, 0.7980726212080798, 0.8046173857073919, 0.8110450872887550, 0.8173544143867162, 0.8235441764639875, 0.8296133044858474, 0.8355608512093652, 0.8413859912867303, 0.8470880211822968, 0.8526663589032990, 0.8581205435445334, 0.8634502346476508, 0.8686552113760616, 0.8737353715068081, 0.8786907302411250, 0.8835214188357692, 0.8882276830575707, 0.8928098814640207, 0.8972684835130879, 0.9016040675058185, 0.9058173183656508, 0.9099090252587376, 0.9138800790599416, 0.9177314696695282, 0.9214642831859411, 0.9250796989403991, 0.9285789863994010, 0.9319635019415643, 0.9352346855155568, 0.9383940571861993, 0.9414432135761304, 0.9443838242107182, 0.9472176277741918, 0.9499464282852282, 0.9525720912004834, 0.9550965394547873, 0.9575217494469370, 0.9598497469802043, 0.9620826031668507, 0.9642224303060783, 0.9662713777449607, 0.9682316277319895, 0.9701053912729269, 0.9718949039986892, 0.9736024220549734, 0.9752302180233160, 0.9767805768831932, 0.9782557920246753, 0.9796581613210076, 0.9809899832703159, 0.9822535532154261, 0.9834511596505429, 0.9845850806232530, 0.9856575802399989, 0.9866709052828243, 0.9876272819448033, 0.9885289126911557, 0.9893779732525968, 0.9901766097569984, 0.9909269360049311, 0.9916310308941294, 0.9922909359973702, 0.9929086532976777, 0.9934861430841844, 0.9940253220113651, 0.9945280613237534, 0.9949961852476154, 0.9954314695504363, 0.9958356402684387, 0.9962103726017252, 0.9965572899760172, 0.9968779632693499, 0.9971739102014799, 0.9974465948831872, 0.9976974275220812, 0.9979277642809907, 0.9981389072844972, 0.9983321047686901, 0.9985085513687731, 0.9986693885387259, 0.9988157050968516, 0.9989485378906924, 0.9990688725744943, 0.9991776444921379, 0.9992757396582338, 0.9993639958299003, 0.9994432036616085, 0.9995141079353859, 0.9995774088586188, 0.9996337634216871, 0.9996837868076957, 0.9997280538466377, 0.9997671005064359, 0.9998014254134544, 0.9998314913952471, 0.9998577270385304, 0.9998805282555989, 0.9999002598526793, 0.9999172570940037, 0.9999318272557038, 0.9999442511639580, 0.9999547847121726, 0.9999636603523446, 0.9999710885561258, 0.9999772592414866, 0.9999823431612708, 0.9999864932503106, 0.9999898459281599, 0.9999925223548691, 0.9999946296375997, 0.9999962619864214, 0.9999975018180320, 0.9999984208055542, 0.9999990808746198, 0.9999995351446231, 0.9999998288155155 }; #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/cfft_tab.h0000644000175000017500000036330614647725151015641 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: cfft_tab.h,v 1.21 2007/11/01 12:33:29 menno Exp $ **/ #ifndef __CFFT_TAB_H__ #define __CFFT_TAB_H__ #ifdef __cplusplus extern "C" { #endif #ifdef FIXED_POINT ALIGN static const complex_t cfft_tab_512[] = { { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.999924719333649), FRAC_CONST(0.012271538376808) }, { FRAC_CONST(0.999698817729950), FRAC_CONST(0.024541229009628) }, { FRAC_CONST(0.999322354793549), FRAC_CONST(0.036807224154472) }, { FRAC_CONST(0.998795449733734), FRAC_CONST(0.049067676067352) }, { FRAC_CONST(0.998118102550507), FRAC_CONST(0.061320740729570) }, { FRAC_CONST(0.997290432453156), FRAC_CONST(0.073564566671848) }, { FRAC_CONST(0.996312618255615), FRAC_CONST(0.085797317326069) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.993906974792480), FRAC_CONST(0.110222205519676) }, { FRAC_CONST(0.992479562759399), FRAC_CONST(0.122410677373409) }, { FRAC_CONST(0.990902662277222), FRAC_CONST(0.134580716490746) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.987301409244537), FRAC_CONST(0.158858150243759) }, { FRAC_CONST(0.985277652740479), FRAC_CONST(0.170961901545525) }, { FRAC_CONST(0.983105480670929), FRAC_CONST(0.183039888739586) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.978317379951477), FRAC_CONST(0.207111388444901) }, { FRAC_CONST(0.975702106952667), FRAC_CONST(0.219101235270500) }, { FRAC_CONST(0.972939968109131), FRAC_CONST(0.231058120727539) }, { FRAC_CONST(0.970031261444092), FRAC_CONST(0.242980197072029) }, { FRAC_CONST(0.966976463794708), FRAC_CONST(0.254865676164627) }, { FRAC_CONST(0.963776051998138), FRAC_CONST(0.266712784767151) }, { FRAC_CONST(0.960430502891541), FRAC_CONST(0.278519690036774) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.953306019306183), FRAC_CONST(0.302005946636200) }, { FRAC_CONST(0.949528157711029), FRAC_CONST(0.313681751489639) }, { FRAC_CONST(0.945607304573059), FRAC_CONST(0.325310319662094) }, { FRAC_CONST(0.941544055938721), FRAC_CONST(0.336889863014221) }, { FRAC_CONST(0.937339007854462), FRAC_CONST(0.348418682813644) }, { FRAC_CONST(0.932992815971375), FRAC_CONST(0.359895050525665) }, { FRAC_CONST(0.928506076335907), FRAC_CONST(0.371317207813263) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.919113874435425), FRAC_CONST(0.393992066383362) }, { FRAC_CONST(0.914209723472595), FRAC_CONST(0.405241340398788) }, { FRAC_CONST(0.909167945384979), FRAC_CONST(0.416429579257965) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.898674488067627), FRAC_CONST(0.438616245985031) }, { FRAC_CONST(0.893224298954010), FRAC_CONST(0.449611335992813) }, { FRAC_CONST(0.887639641761780), FRAC_CONST(0.460538715124130) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.876070082187653), FRAC_CONST(0.482183754444122) }, { FRAC_CONST(0.870086967945099), FRAC_CONST(0.492898225784302) }, { FRAC_CONST(0.863972842693329), FRAC_CONST(0.503538370132446) }, { FRAC_CONST(0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(0.851355195045471), FRAC_CONST(0.524589717388153) }, { FRAC_CONST(0.844853579998016), FRAC_CONST(0.534997642040253) }, { FRAC_CONST(0.838224709033966), FRAC_CONST(0.545324981212616) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.824589252471924), FRAC_CONST(0.565731823444366) }, { FRAC_CONST(0.817584812641144), FRAC_CONST(0.575808227062225) }, { FRAC_CONST(0.810457170009613), FRAC_CONST(0.585797905921936) }, { FRAC_CONST(0.803207516670227), FRAC_CONST(0.595699310302734) }, { FRAC_CONST(0.795836925506592), FRAC_CONST(0.605511009693146) }, { FRAC_CONST(0.788346409797668), FRAC_CONST(0.615231633186340) }, { FRAC_CONST(0.780737221240997), FRAC_CONST(0.624859511852264) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.765167236328125), FRAC_CONST(0.643831551074982) }, { FRAC_CONST(0.757208824157715), FRAC_CONST(0.653172850608826) }, { FRAC_CONST(0.749136388301849), FRAC_CONST(0.662415802478790) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.732654273509979), FRAC_CONST(0.680601000785828) }, { FRAC_CONST(0.724247097969055), FRAC_CONST(0.689540565013886) }, { FRAC_CONST(0.715730786323547), FRAC_CONST(0.698376297950745) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.698376238346100), FRAC_CONST(0.715730845928192) }, { FRAC_CONST(0.689540505409241), FRAC_CONST(0.724247097969055) }, { FRAC_CONST(0.680601000785828), FRAC_CONST(0.732654273509979) }, { FRAC_CONST(0.671558916568756), FRAC_CONST(0.740951180458069) }, { FRAC_CONST(0.662415742874146), FRAC_CONST(0.749136388301849) }, { FRAC_CONST(0.653172791004181), FRAC_CONST(0.757208883762360) }, { FRAC_CONST(0.643831551074982), FRAC_CONST(0.765167295932770) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.624859452247620), FRAC_CONST(0.780737280845642) }, { FRAC_CONST(0.615231573581696), FRAC_CONST(0.788346409797668) }, { FRAC_CONST(0.605511009693146), FRAC_CONST(0.795836925506592) }, { FRAC_CONST(0.595699310302734), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(0.585797846317291), FRAC_CONST(0.810457170009613) }, { FRAC_CONST(0.575808167457581), FRAC_CONST(0.817584812641144) }, { FRAC_CONST(0.565731823444366), FRAC_CONST(0.824589312076569) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.545324981212616), FRAC_CONST(0.838224709033966) }, { FRAC_CONST(0.534997642040253), FRAC_CONST(0.844853579998016) }, { FRAC_CONST(0.524589657783508), FRAC_CONST(0.851355195045471) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.503538429737091), FRAC_CONST(0.863972842693329) }, { FRAC_CONST(0.492898195981979), FRAC_CONST(0.870086967945099) }, { FRAC_CONST(0.482183724641800), FRAC_CONST(0.876070141792297) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.460538715124130), FRAC_CONST(0.887639641761780) }, { FRAC_CONST(0.449611306190491), FRAC_CONST(0.893224298954010) }, { FRAC_CONST(0.438616186380386), FRAC_CONST(0.898674488067627) }, { FRAC_CONST(0.427555114030838), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(0.416429549455643), FRAC_CONST(0.909168004989624) }, { FRAC_CONST(0.405241280794144), FRAC_CONST(0.914209783077240) }, { FRAC_CONST(0.393991947174072), FRAC_CONST(0.919113874435425) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.371317148208618), FRAC_CONST(0.928506076335907) }, { FRAC_CONST(0.359894961118698), FRAC_CONST(0.932992815971375) }, { FRAC_CONST(0.348418682813644), FRAC_CONST(0.937339007854462) }, { FRAC_CONST(0.336889833211899), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(0.325310230255127), FRAC_CONST(0.945607364177704) }, { FRAC_CONST(0.313681662082672), FRAC_CONST(0.949528217315674) }, { FRAC_CONST(0.302005946636200), FRAC_CONST(0.953306019306183) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.278519600629807), FRAC_CONST(0.960430562496185) }, { FRAC_CONST(0.266712754964828), FRAC_CONST(0.963776051998138) }, { FRAC_CONST(0.254865646362305), FRAC_CONST(0.966976463794708) }, { FRAC_CONST(0.242980122566223), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.231058135628700), FRAC_CONST(0.972939968109131) }, { FRAC_CONST(0.219101220369339), FRAC_CONST(0.975702106952667) }, { FRAC_CONST(0.207111328840256), FRAC_CONST(0.978317379951477) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.183039888739586), FRAC_CONST(0.983105480670929) }, { FRAC_CONST(0.170961856842041), FRAC_CONST(0.985277652740479) }, { FRAC_CONST(0.158858075737953), FRAC_CONST(0.987301409244537) }, { FRAC_CONST(0.146730497479439), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(0.134580686688423), FRAC_CONST(0.990902662277222) }, { FRAC_CONST(0.122410625219345), FRAC_CONST(0.992479562759399) }, { FRAC_CONST(0.110222116112709), FRAC_CONST(0.993906974792480) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.085797272622585), FRAC_CONST(0.996312618255615) }, { FRAC_CONST(0.073564492166042), FRAC_CONST(0.997290432453156) }, { FRAC_CONST(0.061320748180151), FRAC_CONST(0.998118102550507) }, { FRAC_CONST(0.049067649990320), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(0.036807164549828), FRAC_CONST(0.999322414398193) }, { FRAC_CONST(0.024541135877371), FRAC_CONST(0.999698817729950) }, { FRAC_CONST(0.012271529063582), FRAC_CONST(0.999924719333649) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.012271616607904), FRAC_CONST(0.999924719333649) }, { FRAC_CONST(-0.024541223421693), FRAC_CONST(0.999698817729950) }, { FRAC_CONST(-0.036807250231504), FRAC_CONST(0.999322354793549) }, { FRAC_CONST(-0.049067739397287), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.061320833861828), FRAC_CONST(0.998118102550507) }, { FRAC_CONST(-0.073564574122429), FRAC_CONST(0.997290432453156) }, { FRAC_CONST(-0.085797362029552), FRAC_CONST(0.996312618255615) }, { FRAC_CONST(-0.098017223179340), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.110222205519676), FRAC_CONST(0.993906974792480) }, { FRAC_CONST(-0.122410707175732), FRAC_CONST(0.992479503154755) }, { FRAC_CONST(-0.134580776095390), FRAC_CONST(0.990902602672577) }, { FRAC_CONST(-0.146730571985245), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(-0.158858165144920), FRAC_CONST(0.987301409244537) }, { FRAC_CONST(-0.170961946249008), FRAC_CONST(0.985277652740479) }, { FRAC_CONST(-0.183039978146553), FRAC_CONST(0.983105480670929) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.207111418247223), FRAC_CONST(0.978317379951477) }, { FRAC_CONST(-0.219101309776306), FRAC_CONST(0.975702106952667) }, { FRAC_CONST(-0.231058210134506), FRAC_CONST(0.972939908504486) }, { FRAC_CONST(-0.242980197072029), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(-0.254865705966949), FRAC_CONST(0.966976463794708) }, { FRAC_CONST(-0.266712844371796), FRAC_CONST(0.963776051998138) }, { FRAC_CONST(-0.278519690036774), FRAC_CONST(0.960430502891541) }, { FRAC_CONST(-0.290284723043442), FRAC_CONST(0.956940293312073) }, { FRAC_CONST(-0.302006036043167), FRAC_CONST(0.953306019306183) }, { FRAC_CONST(-0.313681721687317), FRAC_CONST(0.949528157711029) }, { FRAC_CONST(-0.325310319662094), FRAC_CONST(0.945607304573059) }, { FRAC_CONST(-0.336889922618866), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(-0.348418772220612), FRAC_CONST(0.937338948249817) }, { FRAC_CONST(-0.359895050525665), FRAC_CONST(0.932992815971375) }, { FRAC_CONST(-0.371317237615585), FRAC_CONST(0.928506076335907) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.393992036581039), FRAC_CONST(0.919113874435425) }, { FRAC_CONST(-0.405241340398788), FRAC_CONST(0.914209723472595) }, { FRAC_CONST(-0.416429519653320), FRAC_CONST(0.909168004989624) }, { FRAC_CONST(-0.427555084228516), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(-0.438616245985031), FRAC_CONST(0.898674428462982) }, { FRAC_CONST(-0.449611365795136), FRAC_CONST(0.893224298954010) }, { FRAC_CONST(-0.460538804531097), FRAC_CONST(0.887639582157135) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.482183903455734), FRAC_CONST(0.876070022583008) }, { FRAC_CONST(-0.492898166179657), FRAC_CONST(0.870087027549744) }, { FRAC_CONST(-0.503538370132446), FRAC_CONST(0.863972842693329) }, { FRAC_CONST(-0.514102756977081), FRAC_CONST(0.857728600502014) }, { FRAC_CONST(-0.524589717388153), FRAC_CONST(0.851355135440826) }, { FRAC_CONST(-0.534997701644897), FRAC_CONST(0.844853520393372) }, { FRAC_CONST(-0.545325100421906), FRAC_CONST(0.838224649429321) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.565731763839722), FRAC_CONST(0.824589312076569) }, { FRAC_CONST(-0.575808167457581), FRAC_CONST(0.817584812641144) }, { FRAC_CONST(-0.585797905921936), FRAC_CONST(0.810457170009613) }, { FRAC_CONST(-0.595699369907379), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(-0.605511128902435), FRAC_CONST(0.795836865901947) }, { FRAC_CONST(-0.615231692790985), FRAC_CONST(0.788346350193024) }, { FRAC_CONST(-0.624859631061554), FRAC_CONST(0.780737102031708) }, { FRAC_CONST(-0.634393274784088), FRAC_CONST(0.773010492324829) }, { FRAC_CONST(-0.643831551074982), FRAC_CONST(0.765167236328125) }, { FRAC_CONST(-0.653172850608826), FRAC_CONST(0.757208824157715) }, { FRAC_CONST(-0.662415802478790), FRAC_CONST(0.749136328697205) }, { FRAC_CONST(-0.671559035778046), FRAC_CONST(0.740951061248779) }, { FRAC_CONST(-0.680601119995117), FRAC_CONST(0.732654154300690) }, { FRAC_CONST(-0.689540684223175), FRAC_CONST(0.724246978759766) }, { FRAC_CONST(-0.698376238346100), FRAC_CONST(0.715730845928192) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.715730845928192), FRAC_CONST(0.698376238346100) }, { FRAC_CONST(-0.724247157573700), FRAC_CONST(0.689540505409241) }, { FRAC_CONST(-0.732654333114624), FRAC_CONST(0.680600941181183) }, { FRAC_CONST(-0.740951240062714), FRAC_CONST(0.671558856964111) }, { FRAC_CONST(-0.749136507511139), FRAC_CONST(0.662415623664856) }, { FRAC_CONST(-0.757208824157715), FRAC_CONST(0.653172850608826) }, { FRAC_CONST(-0.765167295932770), FRAC_CONST(0.643831551074982) }, { FRAC_CONST(-0.773010492324829), FRAC_CONST(0.634393274784088) }, { FRAC_CONST(-0.780737280845642), FRAC_CONST(0.624859452247620) }, { FRAC_CONST(-0.788346469402313), FRAC_CONST(0.615231513977051) }, { FRAC_CONST(-0.795836985111237), FRAC_CONST(0.605510950088501) }, { FRAC_CONST(-0.803207635879517), FRAC_CONST(0.595699131488800) }, { FRAC_CONST(-0.810457170009613), FRAC_CONST(0.585797846317291) }, { FRAC_CONST(-0.817584812641144), FRAC_CONST(0.575808167457581) }, { FRAC_CONST(-0.824589312076569), FRAC_CONST(0.565731763839722) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.838224768638611), FRAC_CONST(0.545324862003326) }, { FRAC_CONST(-0.844853639602661), FRAC_CONST(0.534997463226318) }, { FRAC_CONST(-0.851355314254761), FRAC_CONST(0.524589538574219) }, { FRAC_CONST(-0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(-0.863972842693329), FRAC_CONST(0.503538370132446) }, { FRAC_CONST(-0.870087027549744), FRAC_CONST(0.492898136377335) }, { FRAC_CONST(-0.876070141792297), FRAC_CONST(0.482183694839478) }, { FRAC_CONST(-0.881921350955963), FRAC_CONST(0.471396625041962) }, { FRAC_CONST(-0.887639701366425), FRAC_CONST(0.460538566112518) }, { FRAC_CONST(-0.893224298954010), FRAC_CONST(0.449611365795136) }, { FRAC_CONST(-0.898674488067627), FRAC_CONST(0.438616245985031) }, { FRAC_CONST(-0.903989315032959), FRAC_CONST(0.427555054426193) }, { FRAC_CONST(-0.909168004989624), FRAC_CONST(0.416429489850998) }, { FRAC_CONST(-0.914209783077240), FRAC_CONST(0.405241221189499) }, { FRAC_CONST(-0.919113874435425), FRAC_CONST(0.393991917371750) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.928506076335907), FRAC_CONST(0.371317237615585) }, { FRAC_CONST(-0.932992815971375), FRAC_CONST(0.359895050525665) }, { FRAC_CONST(-0.937339007854462), FRAC_CONST(0.348418653011322) }, { FRAC_CONST(-0.941544115543365), FRAC_CONST(0.336889803409576) }, { FRAC_CONST(-0.945607364177704), FRAC_CONST(0.325310200452805) }, { FRAC_CONST(-0.949528217315674), FRAC_CONST(0.313681602478027) }, { FRAC_CONST(-0.953306078910828), FRAC_CONST(0.302005797624588) }, { FRAC_CONST(-0.956940352916718), FRAC_CONST(0.290284723043442) }, { FRAC_CONST(-0.960430502891541), FRAC_CONST(0.278519690036774) }, { FRAC_CONST(-0.963776051998138), FRAC_CONST(0.266712725162506) }, { FRAC_CONST(-0.966976463794708), FRAC_CONST(0.254865586757660) }, { FRAC_CONST(-0.970031261444092), FRAC_CONST(0.242980077862740) }, { FRAC_CONST(-0.972939968109131), FRAC_CONST(0.231057971715927) }, { FRAC_CONST(-0.975702166557312), FRAC_CONST(0.219101071357727) }, { FRAC_CONST(-0.978317379951477), FRAC_CONST(0.207111403346062) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.983105480670929), FRAC_CONST(0.183039844036102) }, { FRAC_CONST(-0.985277652740479), FRAC_CONST(0.170961812138557) }, { FRAC_CONST(-0.987301409244537), FRAC_CONST(0.158858031034470) }, { FRAC_CONST(-0.989176511764526), FRAC_CONST(0.146730333566666) }, { FRAC_CONST(-0.990902662277222), FRAC_CONST(0.134580522775650) }, { FRAC_CONST(-0.992479503154755), FRAC_CONST(0.122410699725151) }, { FRAC_CONST(-0.993906974792480), FRAC_CONST(0.110222198069096) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(0.098017096519470) }, { FRAC_CONST(-0.996312618255615), FRAC_CONST(0.085797227919102) }, { FRAC_CONST(-0.997290492057800), FRAC_CONST(0.073564447462559) }, { FRAC_CONST(-0.998118102550507), FRAC_CONST(0.061320584267378) }, { FRAC_CONST(-0.998795449733734), FRAC_CONST(0.049067486077547) }, { FRAC_CONST(-0.999322354793549), FRAC_CONST(0.036807239055634) }, { FRAC_CONST(-0.999698817729950), FRAC_CONST(0.024541210383177) }, { FRAC_CONST(-0.999924719333649), FRAC_CONST(0.012271485291421) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.999698817729950), FRAC_CONST(0.024541229009628) }, { FRAC_CONST(0.998795449733734), FRAC_CONST(0.049067676067352) }, { FRAC_CONST(0.997290432453156), FRAC_CONST(0.073564566671848) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.992479562759399), FRAC_CONST(0.122410677373409) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.985277652740479), FRAC_CONST(0.170961901545525) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.975702106952667), FRAC_CONST(0.219101235270500) }, { FRAC_CONST(0.970031261444092), FRAC_CONST(0.242980197072029) }, { FRAC_CONST(0.963776051998138), FRAC_CONST(0.266712784767151) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.949528157711029), FRAC_CONST(0.313681751489639) }, { FRAC_CONST(0.941544055938721), FRAC_CONST(0.336889863014221) }, { FRAC_CONST(0.932992815971375), FRAC_CONST(0.359895050525665) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.914209723472595), FRAC_CONST(0.405241340398788) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.893224298954010), FRAC_CONST(0.449611335992813) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.870086967945099), FRAC_CONST(0.492898225784302) }, { FRAC_CONST(0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(0.844853579998016), FRAC_CONST(0.534997642040253) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.817584812641144), FRAC_CONST(0.575808227062225) }, { FRAC_CONST(0.803207516670227), FRAC_CONST(0.595699310302734) }, { FRAC_CONST(0.788346409797668), FRAC_CONST(0.615231633186340) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.757208824157715), FRAC_CONST(0.653172850608826) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.724247097969055), FRAC_CONST(0.689540565013886) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.689540505409241), FRAC_CONST(0.724247097969055) }, { FRAC_CONST(0.671558916568756), FRAC_CONST(0.740951180458069) }, { FRAC_CONST(0.653172791004181), FRAC_CONST(0.757208883762360) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.615231573581696), FRAC_CONST(0.788346409797668) }, { FRAC_CONST(0.595699310302734), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(0.575808167457581), FRAC_CONST(0.817584812641144) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.534997642040253), FRAC_CONST(0.844853579998016) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.492898195981979), FRAC_CONST(0.870086967945099) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.449611306190491), FRAC_CONST(0.893224298954010) }, { FRAC_CONST(0.427555114030838), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(0.405241280794144), FRAC_CONST(0.914209783077240) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.359894961118698), FRAC_CONST(0.932992815971375) }, { FRAC_CONST(0.336889833211899), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(0.313681662082672), FRAC_CONST(0.949528217315674) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.266712754964828), FRAC_CONST(0.963776051998138) }, { FRAC_CONST(0.242980122566223), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.219101220369339), FRAC_CONST(0.975702106952667) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.170961856842041), FRAC_CONST(0.985277652740479) }, { FRAC_CONST(0.146730497479439), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(0.122410625219345), FRAC_CONST(0.992479562759399) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.073564492166042), FRAC_CONST(0.997290432453156) }, { FRAC_CONST(0.049067649990320), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(0.024541135877371), FRAC_CONST(0.999698817729950) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.998795449733734), FRAC_CONST(0.049067676067352) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.970031261444092), FRAC_CONST(0.242980197072029) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.941544055938721), FRAC_CONST(0.336889863014221) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.803207516670227), FRAC_CONST(0.595699310302734) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.671558916568756), FRAC_CONST(0.740951180458069) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.595699310302734), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.427555114030838), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.336889833211899), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.242980122566223), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.146730497479439), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.049067649990320), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.049067739397287), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.098017223179340), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.146730571985245), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.242980197072029), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(-0.290284723043442), FRAC_CONST(0.956940293312073) }, { FRAC_CONST(-0.336889922618866), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.427555084228516), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.514102756977081), FRAC_CONST(0.857728600502014) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.595699369907379), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(-0.634393274784088), FRAC_CONST(0.773010492324829) }, { FRAC_CONST(-0.671559035778046), FRAC_CONST(0.740951061248779) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.740951240062714), FRAC_CONST(0.671558856964111) }, { FRAC_CONST(-0.773010492324829), FRAC_CONST(0.634393274784088) }, { FRAC_CONST(-0.803207635879517), FRAC_CONST(0.595699131488800) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(-0.881921350955963), FRAC_CONST(0.471396625041962) }, { FRAC_CONST(-0.903989315032959), FRAC_CONST(0.427555054426193) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.941544115543365), FRAC_CONST(0.336889803409576) }, { FRAC_CONST(-0.956940352916718), FRAC_CONST(0.290284723043442) }, { FRAC_CONST(-0.970031261444092), FRAC_CONST(0.242980077862740) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.989176511764526), FRAC_CONST(0.146730333566666) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(0.098017096519470) }, { FRAC_CONST(-0.998795449733734), FRAC_CONST(0.049067486077547) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.997290432453156), FRAC_CONST(0.073564566671848) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.975702106952667), FRAC_CONST(0.219101235270500) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.932992815971375), FRAC_CONST(0.359895050525665) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.870086967945099), FRAC_CONST(0.492898225784302) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.788346469402313), FRAC_CONST(0.615231573581696) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.689540505409241), FRAC_CONST(0.724247097969055) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.575808227062225), FRAC_CONST(0.817584812641144) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.449611306190491), FRAC_CONST(0.893224298954010) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.313681751489639), FRAC_CONST(0.949528157711029) }, { FRAC_CONST(0.242980241775513), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.170961856842041), FRAC_CONST(0.985277652740479) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.024541255086660), FRAC_CONST(0.999698817729950) }, { FRAC_CONST(-0.049067739397287), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.122410707175732), FRAC_CONST(0.992479503154755) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.266712725162506), FRAC_CONST(0.963776051998138) }, { FRAC_CONST(-0.336889803409576), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(-0.405241340398788), FRAC_CONST(0.914209723472595) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.534997701644897), FRAC_CONST(0.844853520393372) }, { FRAC_CONST(-0.595699369907379), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(-0.653172850608826), FRAC_CONST(0.757208824157715) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.757208824157715), FRAC_CONST(0.653172850608826) }, { FRAC_CONST(-0.803207516670227), FRAC_CONST(0.595699369907379) }, { FRAC_CONST(-0.844853520393372), FRAC_CONST(0.534997701644897) }, { FRAC_CONST(-0.881921231746674), FRAC_CONST(0.471396833658218) }, { FRAC_CONST(-0.914209783077240), FRAC_CONST(0.405241221189499) }, { FRAC_CONST(-0.941544115543365), FRAC_CONST(0.336889803409576) }, { FRAC_CONST(-0.963776051998138), FRAC_CONST(0.266712725162506) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.992479503154755), FRAC_CONST(0.122410699725151) }, { FRAC_CONST(-0.998795449733734), FRAC_CONST(0.049067724496126) }, { FRAC_CONST(-0.999698817729950), FRAC_CONST(-0.024541147053242) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(-0.098017267882824) }, { FRAC_CONST(-0.985277652740479), FRAC_CONST(-0.170961990952492) }, { FRAC_CONST(-0.970031261444092), FRAC_CONST(-0.242980241775513) }, { FRAC_CONST(-0.949528157711029), FRAC_CONST(-0.313681781291962) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.893224298954010), FRAC_CONST(-0.449611306190491) }, { FRAC_CONST(-0.857728660106659), FRAC_CONST(-0.514102697372437) }, { FRAC_CONST(-0.817584872245789), FRAC_CONST(-0.575808107852936) }, { FRAC_CONST(-0.773010551929474), FRAC_CONST(-0.634393215179443) }, { FRAC_CONST(-0.724247038364410), FRAC_CONST(-0.689540624618530) }, { FRAC_CONST(-0.671558916568756), FRAC_CONST(-0.740951180458069) }, { FRAC_CONST(-0.615231573581696), FRAC_CONST(-0.788346469402313) }, { FRAC_CONST(-0.555570006370544), FRAC_CONST(-0.831469774246216) }, { FRAC_CONST(-0.492898195981979), FRAC_CONST(-0.870086967945099) }, { FRAC_CONST(-0.427554935216904), FRAC_CONST(-0.903989374637604) }, { FRAC_CONST(-0.359895110130310), FRAC_CONST(-0.932992756366730) }, { FRAC_CONST(-0.290284544229507), FRAC_CONST(-0.956940352916718) }, { FRAC_CONST(-0.219101369380951), FRAC_CONST(-0.975702106952667) }, { FRAC_CONST(-0.146730408072472), FRAC_CONST(-0.989176511764526) }, { FRAC_CONST(-0.073564760386944), FRAC_CONST(-0.997290432453156) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.881921231746674), FRAC_CONST(0.471396833658218) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(-0.098017267882824) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.773010551929474), FRAC_CONST(-0.634393215179443) }, { FRAC_CONST(-0.555570006370544), FRAC_CONST(-0.831469774246216) }, { FRAC_CONST(-0.290284544229507), FRAC_CONST(-0.956940352916718) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.000000011924881), FRAC_CONST(-1.000000000000000) } }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const complex_t cfft_tab_480[] = { { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.999914348125458), FRAC_CONST(0.013089596293867) }, { FRAC_CONST(0.999657332897186), FRAC_CONST(0.026176949962974) }, { FRAC_CONST(0.999229013919830), FRAC_CONST(0.039259817451239) }, { FRAC_CONST(0.998629510402679), FRAC_CONST(0.052335958927870) }, { FRAC_CONST(0.997858941555023), FRAC_CONST(0.065403133630753) }, { FRAC_CONST(0.996917307376862), FRAC_CONST(0.078459098935127) }, { FRAC_CONST(0.995804905891418), FRAC_CONST(0.091501623392105) }, { FRAC_CONST(0.994521915912628), FRAC_CONST(0.104528464376926) }, { FRAC_CONST(0.993068456649780), FRAC_CONST(0.117537401616573) }, { FRAC_CONST(0.991444885730743), FRAC_CONST(0.130526199936867) }, { FRAC_CONST(0.989651381969452), FRAC_CONST(0.143492624163628) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.985556066036224), FRAC_CONST(0.169349506497383) }, { FRAC_CONST(0.983254909515381), FRAC_CONST(0.182235524058342) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.978147625923157), FRAC_CONST(0.207911700010300) }, { FRAC_CONST(0.975342333316803), FRAC_CONST(0.220697447657585) }, { FRAC_CONST(0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(0.969230890274048), FRAC_CONST(0.246153295040131) }, { FRAC_CONST(0.965925812721252), FRAC_CONST(0.258819043636322) }, { FRAC_CONST(0.962455213069916), FRAC_CONST(0.271440446376801) }, { FRAC_CONST(0.958819746971130), FRAC_CONST(0.284015357494354) }, { FRAC_CONST(0.955019950866699), FRAC_CONST(0.296541601419449) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.946930110454559), FRAC_CONST(0.321439445018768) }, { FRAC_CONST(0.942641496658325), FRAC_CONST(0.333806872367859) }, { FRAC_CONST(0.938191354274750), FRAC_CONST(0.346117079257965) }, { FRAC_CONST(0.933580398559570), FRAC_CONST(0.358367949724197) }, { FRAC_CONST(0.928809583187103), FRAC_CONST(0.370557427406311) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.918791174888611), FRAC_CONST(0.394743889570236) }, { FRAC_CONST(0.913545429706573), FRAC_CONST(0.406736642122269) }, { FRAC_CONST(0.908143162727356), FRAC_CONST(0.418659746646881) }, { FRAC_CONST(0.902585268020630), FRAC_CONST(0.430511116981506) }, { FRAC_CONST(0.896872758865356), FRAC_CONST(0.442288726568222) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.884987652301788), FRAC_CONST(0.465614527463913) }, { FRAC_CONST(0.878817081451416), FRAC_CONST(0.477158784866333) }, { FRAC_CONST(0.872496008872986), FRAC_CONST(0.488621264696121) }, { FRAC_CONST(0.866025388240814), FRAC_CONST(0.500000000000000) }, { FRAC_CONST(0.859406411647797), FRAC_CONST(0.511293113231659) }, { FRAC_CONST(0.852640151977539), FRAC_CONST(0.522498548030853) }, { FRAC_CONST(0.845727801322937), FRAC_CONST(0.533614516258240) }, { FRAC_CONST(0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.824126183986664), FRAC_CONST(0.566406250000000) }, { FRAC_CONST(0.816641509532928), FRAC_CONST(0.577145218849182) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.801253795623779), FRAC_CONST(0.598324596881866) }, { FRAC_CONST(0.793353319168091), FRAC_CONST(0.608761429786682) }, { FRAC_CONST(0.785316884517670), FRAC_CONST(0.619093954563141) }, { FRAC_CONST(0.777145922183990), FRAC_CONST(0.629320383071899) }, { FRAC_CONST(0.768841803073883), FRAC_CONST(0.639438986778259) }, { FRAC_CONST(0.760405957698822), FRAC_CONST(0.649448096752167) }, { FRAC_CONST(0.751839756965637), FRAC_CONST(0.659345865249634) }, { FRAC_CONST(0.743144810199738), FRAC_CONST(0.669130623340607) }, { FRAC_CONST(0.734322488307953), FRAC_CONST(0.678800761699677) }, { FRAC_CONST(0.725374400615692), FRAC_CONST(0.688354551792145) }, { FRAC_CONST(0.716301918029785), FRAC_CONST(0.697790503501892) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.697790443897247), FRAC_CONST(0.716301977634430) }, { FRAC_CONST(0.688354551792145), FRAC_CONST(0.725374400615692) }, { FRAC_CONST(0.678800702095032), FRAC_CONST(0.734322547912598) }, { FRAC_CONST(0.669130563735962), FRAC_CONST(0.743144869804382) }, { FRAC_CONST(0.659345805644989), FRAC_CONST(0.751839816570282) }, { FRAC_CONST(0.649448037147522), FRAC_CONST(0.760405957698822) }, { FRAC_CONST(0.639438986778259), FRAC_CONST(0.768841862678528) }, { FRAC_CONST(0.629320383071899), FRAC_CONST(0.777145981788635) }, { FRAC_CONST(0.619093954563141), FRAC_CONST(0.785316944122314) }, { FRAC_CONST(0.608761370182037), FRAC_CONST(0.793353378772736) }, { FRAC_CONST(0.598324596881866), FRAC_CONST(0.801253855228424) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.577145159244537), FRAC_CONST(0.816641569137573) }, { FRAC_CONST(0.566406250000000), FRAC_CONST(0.824126183986664) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.544638991355896), FRAC_CONST(0.838670611381531) }, { FRAC_CONST(0.533614516258240), FRAC_CONST(0.845727801322937) }, { FRAC_CONST(0.522498488426209), FRAC_CONST(0.852640211582184) }, { FRAC_CONST(0.511293113231659), FRAC_CONST(0.859406411647797) }, { FRAC_CONST(0.499999970197678), FRAC_CONST(0.866025447845459) }, { FRAC_CONST(0.488621175289154), FRAC_CONST(0.872496068477631) }, { FRAC_CONST(0.477158755064011), FRAC_CONST(0.878817141056061) }, { FRAC_CONST(0.465614467859268), FRAC_CONST(0.884987652301788) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.442288666963577), FRAC_CONST(0.896872758865356) }, { FRAC_CONST(0.430511027574539), FRAC_CONST(0.902585327625275) }, { FRAC_CONST(0.418659746646881), FRAC_CONST(0.908143162727356) }, { FRAC_CONST(0.406736612319946), FRAC_CONST(0.913545489311218) }, { FRAC_CONST(0.394743800163269), FRAC_CONST(0.918791234493256) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.370557397603989), FRAC_CONST(0.928809583187103) }, { FRAC_CONST(0.358367860317230), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(0.346117049455643), FRAC_CONST(0.938191354274750) }, { FRAC_CONST(0.333806812763214), FRAC_CONST(0.942641496658325) }, { FRAC_CONST(0.321439474821091), FRAC_CONST(0.946930110454559) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.296541512012482), FRAC_CONST(0.955019950866699) }, { FRAC_CONST(0.284015327692032), FRAC_CONST(0.958819746971130) }, { FRAC_CONST(0.271440386772156), FRAC_CONST(0.962455272674561) }, { FRAC_CONST(0.258819073438644), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(0.246153265237808), FRAC_CONST(0.969230890274048) }, { FRAC_CONST(0.233445301651955), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(0.220697447657585), FRAC_CONST(0.975342333316803) }, { FRAC_CONST(0.207911655306816), FRAC_CONST(0.978147625923157) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.182235524058342), FRAC_CONST(0.983254909515381) }, { FRAC_CONST(0.169349446892738), FRAC_CONST(0.985556066036224) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(0.143492594361305), FRAC_CONST(0.989651381969452) }, { FRAC_CONST(0.130526125431061), FRAC_CONST(0.991444885730743) }, { FRAC_CONST(0.117537401616573), FRAC_CONST(0.993068456649780) }, { FRAC_CONST(0.104528419673443), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(0.091501533985138), FRAC_CONST(0.995804905891418) }, { FRAC_CONST(0.078459084033966), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(0.065403074026108), FRAC_CONST(0.997858941555023) }, { FRAC_CONST(0.052335973829031), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(0.039259787648916), FRAC_CONST(0.999229013919830) }, { FRAC_CONST(0.026176875457168), FRAC_CONST(0.999657332897186) }, { FRAC_CONST(0.013089597225189), FRAC_CONST(0.999914348125458) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.013089684769511), FRAC_CONST(0.999914348125458) }, { FRAC_CONST(-0.026176963001490), FRAC_CONST(0.999657332897186) }, { FRAC_CONST(-0.039259877055883), FRAC_CONST(0.999229013919830) }, { FRAC_CONST(-0.052336059510708), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(-0.065403163433075), FRAC_CONST(0.997858941555023) }, { FRAC_CONST(-0.078459173440933), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(-0.091501623392105), FRAC_CONST(0.995804905891418) }, { FRAC_CONST(-0.104528509080410), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.117537491023541), FRAC_CONST(0.993068456649780) }, { FRAC_CONST(-0.130526214838028), FRAC_CONST(0.991444885730743) }, { FRAC_CONST(-0.143492683768272), FRAC_CONST(0.989651381969452) }, { FRAC_CONST(-0.156434446573257), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.169349536299706), FRAC_CONST(0.985556066036224) }, { FRAC_CONST(-0.182235598564148), FRAC_CONST(0.983254909515381) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.207911744713783), FRAC_CONST(0.978147566318512) }, { FRAC_CONST(-0.220697522163391), FRAC_CONST(0.975342273712158) }, { FRAC_CONST(-0.233445391058922), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(-0.246153354644775), FRAC_CONST(0.969230890274048) }, { FRAC_CONST(-0.258819162845612), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(-0.271440476179123), FRAC_CONST(0.962455213069916) }, { FRAC_CONST(-0.284015417098999), FRAC_CONST(0.958819687366486) }, { FRAC_CONST(-0.296541571617126), FRAC_CONST(0.955019950866699) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.321439564228058), FRAC_CONST(0.946930110454559) }, { FRAC_CONST(-0.333806872367859), FRAC_CONST(0.942641496658325) }, { FRAC_CONST(-0.346117109060287), FRAC_CONST(0.938191294670105) }, { FRAC_CONST(-0.358367949724197), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(-0.370557487010956), FRAC_CONST(0.928809523582459) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.394743859767914), FRAC_CONST(0.918791234493256) }, { FRAC_CONST(-0.406736701726913), FRAC_CONST(0.913545429706573) }, { FRAC_CONST(-0.418659836053848), FRAC_CONST(0.908143103122711) }, { FRAC_CONST(-0.430511116981506), FRAC_CONST(0.902585268020630) }, { FRAC_CONST(-0.442288637161255), FRAC_CONST(0.896872758865356) }, { FRAC_CONST(-0.453990608453751), FRAC_CONST(0.891006469726563) }, { FRAC_CONST(-0.465614557266235), FRAC_CONST(0.884987592697144) }, { FRAC_CONST(-0.477158725261688), FRAC_CONST(0.878817141056061) }, { FRAC_CONST(-0.488621354103088), FRAC_CONST(0.872495949268341) }, { FRAC_CONST(-0.500000059604645), FRAC_CONST(0.866025388240814) }, { FRAC_CONST(-0.511293053627014), FRAC_CONST(0.859406411647797) }, { FRAC_CONST(-0.522498667240143), FRAC_CONST(0.852640092372894) }, { FRAC_CONST(-0.533614575862885), FRAC_CONST(0.845727801322937) }, { FRAC_CONST(-0.544639050960541), FRAC_CONST(0.838670551776886) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.566406309604645), FRAC_CONST(0.824126124382019) }, { FRAC_CONST(-0.577145218849182), FRAC_CONST(0.816641569137573) }, { FRAC_CONST(-0.587785184383392), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.598324656486511), FRAC_CONST(0.801253736019135) }, { FRAC_CONST(-0.608761429786682), FRAC_CONST(0.793353319168091) }, { FRAC_CONST(-0.619093894958496), FRAC_CONST(0.785316944122314) }, { FRAC_CONST(-0.629320502281189), FRAC_CONST(0.777145862579346) }, { FRAC_CONST(-0.639439046382904), FRAC_CONST(0.768841803073883) }, { FRAC_CONST(-0.649448037147522), FRAC_CONST(0.760405957698822) }, { FRAC_CONST(-0.659345924854279), FRAC_CONST(0.751839697360992) }, { FRAC_CONST(-0.669130682945251), FRAC_CONST(0.743144810199738) }, { FRAC_CONST(-0.678800761699677), FRAC_CONST(0.734322488307953) }, { FRAC_CONST(-0.688354671001434), FRAC_CONST(0.725374281406403) }, { FRAC_CONST(-0.697790503501892), FRAC_CONST(0.716301858425140) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.716302037239075), FRAC_CONST(0.697790324687958) }, { FRAC_CONST(-0.725374460220337), FRAC_CONST(0.688354492187500) }, { FRAC_CONST(-0.734322547912598), FRAC_CONST(0.678800702095032) }, { FRAC_CONST(-0.743144929409027), FRAC_CONST(0.669130444526672) }, { FRAC_CONST(-0.751839876174927), FRAC_CONST(0.659345746040344) }, { FRAC_CONST(-0.760406017303467), FRAC_CONST(0.649448037147522) }, { FRAC_CONST(-0.768841803073883), FRAC_CONST(0.639439046382904) }, { FRAC_CONST(-0.777146041393280), FRAC_CONST(0.629320263862610) }, { FRAC_CONST(-0.785316944122314), FRAC_CONST(0.619093894958496) }, { FRAC_CONST(-0.793353319168091), FRAC_CONST(0.608761429786682) }, { FRAC_CONST(-0.801253914833069), FRAC_CONST(0.598324477672577) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(-0.816641569137573), FRAC_CONST(0.577145218849182) }, { FRAC_CONST(-0.824126303195953), FRAC_CONST(0.566406130790710) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(-0.845727920532227), FRAC_CONST(0.533614337444305) }, { FRAC_CONST(-0.852640211582184), FRAC_CONST(0.522498488426209) }, { FRAC_CONST(-0.859406411647797), FRAC_CONST(0.511293053627014) }, { FRAC_CONST(-0.866025388240814), FRAC_CONST(0.500000059604645) }, { FRAC_CONST(-0.872496068477631), FRAC_CONST(0.488621145486832) }, { FRAC_CONST(-0.878817141056061), FRAC_CONST(0.477158725261688) }, { FRAC_CONST(-0.884987652301788), FRAC_CONST(0.465614557266235) }, { FRAC_CONST(-0.891006588935852), FRAC_CONST(0.453990370035172) }, { FRAC_CONST(-0.896872758865356), FRAC_CONST(0.442288637161255) }, { FRAC_CONST(-0.902585268020630), FRAC_CONST(0.430511116981506) }, { FRAC_CONST(-0.908143222332001), FRAC_CONST(0.418659597635269) }, { FRAC_CONST(-0.913545489311218), FRAC_CONST(0.406736582517624) }, { FRAC_CONST(-0.918791234493256), FRAC_CONST(0.394743859767914) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.928809583187103), FRAC_CONST(0.370557337999344) }, { FRAC_CONST(-0.933580458164215), FRAC_CONST(0.358367919921875) }, { FRAC_CONST(-0.938191413879395), FRAC_CONST(0.346116900444031) }, { FRAC_CONST(-0.942641556262970), FRAC_CONST(0.333806753158569) }, { FRAC_CONST(-0.946930170059204), FRAC_CONST(0.321439445018768) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.955020010471344), FRAC_CONST(0.296541452407837) }, { FRAC_CONST(-0.958819746971130), FRAC_CONST(0.284015297889709) }, { FRAC_CONST(-0.962455213069916), FRAC_CONST(0.271440476179123) }, { FRAC_CONST(-0.965925872325897), FRAC_CONST(0.258818924427032) }, { FRAC_CONST(-0.969230949878693), FRAC_CONST(0.246153235435486) }, { FRAC_CONST(-0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(-0.975342333316803), FRAC_CONST(0.220697283744812) }, { FRAC_CONST(-0.978147625923157), FRAC_CONST(0.207911610603333) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.983254909515381), FRAC_CONST(0.182235360145569) }, { FRAC_CONST(-0.985556066036224), FRAC_CONST(0.169349402189255) }, { FRAC_CONST(-0.987688362598419), FRAC_CONST(0.156434446573257) }, { FRAC_CONST(-0.989651441574097), FRAC_CONST(0.143492430448532) }, { FRAC_CONST(-0.991444885730743), FRAC_CONST(0.130526080727577) }, { FRAC_CONST(-0.993068456649780), FRAC_CONST(0.117537356913090) }, { FRAC_CONST(-0.994521915912628), FRAC_CONST(0.104528494179249) }, { FRAC_CONST(-0.995804965496063), FRAC_CONST(0.091501489281654) }, { FRAC_CONST(-0.996917366981506), FRAC_CONST(0.078459039330482) }, { FRAC_CONST(-0.997858941555023), FRAC_CONST(0.065403148531914) }, { FRAC_CONST(-0.998629570007324), FRAC_CONST(0.052335809916258) }, { FRAC_CONST(-0.999229013919830), FRAC_CONST(0.039259742945433) }, { FRAC_CONST(-0.999657332897186), FRAC_CONST(0.026176951825619) }, { FRAC_CONST(-0.999914348125458), FRAC_CONST(0.013089434243739) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.999657332897186), FRAC_CONST(0.026176949962974) }, { FRAC_CONST(0.998629510402679), FRAC_CONST(0.052335958927870) }, { FRAC_CONST(0.996917307376862), FRAC_CONST(0.078459098935127) }, { FRAC_CONST(0.994521915912628), FRAC_CONST(0.104528464376926) }, { FRAC_CONST(0.991444885730743), FRAC_CONST(0.130526199936867) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.983254909515381), FRAC_CONST(0.182235524058342) }, { FRAC_CONST(0.978147625923157), FRAC_CONST(0.207911700010300) }, { FRAC_CONST(0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(0.965925812721252), FRAC_CONST(0.258819043636322) }, { FRAC_CONST(0.958819746971130), FRAC_CONST(0.284015357494354) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.942641496658325), FRAC_CONST(0.333806872367859) }, { FRAC_CONST(0.933580398559570), FRAC_CONST(0.358367949724197) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.913545429706573), FRAC_CONST(0.406736642122269) }, { FRAC_CONST(0.902585268020630), FRAC_CONST(0.430511116981506) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.878817081451416), FRAC_CONST(0.477158784866333) }, { FRAC_CONST(0.866025388240814), FRAC_CONST(0.500000000000000) }, { FRAC_CONST(0.852640151977539), FRAC_CONST(0.522498548030853) }, { FRAC_CONST(0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(0.824126183986664), FRAC_CONST(0.566406250000000) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.793353319168091), FRAC_CONST(0.608761429786682) }, { FRAC_CONST(0.777145922183990), FRAC_CONST(0.629320383071899) }, { FRAC_CONST(0.760405957698822), FRAC_CONST(0.649448096752167) }, { FRAC_CONST(0.743144810199738), FRAC_CONST(0.669130623340607) }, { FRAC_CONST(0.725374400615692), FRAC_CONST(0.688354551792145) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.688354551792145), FRAC_CONST(0.725374400615692) }, { FRAC_CONST(0.669130563735962), FRAC_CONST(0.743144869804382) }, { FRAC_CONST(0.649448037147522), FRAC_CONST(0.760405957698822) }, { FRAC_CONST(0.629320383071899), FRAC_CONST(0.777145981788635) }, { FRAC_CONST(0.608761370182037), FRAC_CONST(0.793353378772736) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.566406250000000), FRAC_CONST(0.824126183986664) }, { FRAC_CONST(0.544638991355896), FRAC_CONST(0.838670611381531) }, { FRAC_CONST(0.522498488426209), FRAC_CONST(0.852640211582184) }, { FRAC_CONST(0.499999970197678), FRAC_CONST(0.866025447845459) }, { FRAC_CONST(0.477158755064011), FRAC_CONST(0.878817141056061) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.430511027574539), FRAC_CONST(0.902585327625275) }, { FRAC_CONST(0.406736612319946), FRAC_CONST(0.913545489311218) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.358367860317230), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(0.333806812763214), FRAC_CONST(0.942641496658325) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.284015327692032), FRAC_CONST(0.958819746971130) }, { FRAC_CONST(0.258819073438644), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(0.233445301651955), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(0.207911655306816), FRAC_CONST(0.978147625923157) }, { FRAC_CONST(0.182235524058342), FRAC_CONST(0.983254909515381) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(0.130526125431061), FRAC_CONST(0.991444885730743) }, { FRAC_CONST(0.104528419673443), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(0.078459084033966), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(0.052335973829031), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(0.026176875457168), FRAC_CONST(0.999657332897186) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.026176963001490), FRAC_CONST(0.999657332897186) }, { FRAC_CONST(-0.052336059510708), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(-0.078459173440933), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(-0.104528509080410), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.130526214838028), FRAC_CONST(0.991444885730743) }, { FRAC_CONST(-0.156434446573257), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.182235598564148), FRAC_CONST(0.983254909515381) }, { FRAC_CONST(-0.207911744713783), FRAC_CONST(0.978147566318512) }, { FRAC_CONST(-0.233445391058922), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(-0.258819162845612), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(-0.284015417098999), FRAC_CONST(0.958819687366486) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.333806872367859), FRAC_CONST(0.942641496658325) }, { FRAC_CONST(-0.358367949724197), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.406736701726913), FRAC_CONST(0.913545429706573) }, { FRAC_CONST(-0.430511116981506), FRAC_CONST(0.902585268020630) }, { FRAC_CONST(-0.453990608453751), FRAC_CONST(0.891006469726563) }, { FRAC_CONST(-0.477158725261688), FRAC_CONST(0.878817141056061) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.998629510402679), FRAC_CONST(0.052335958927870) }, { FRAC_CONST(0.994521915912628), FRAC_CONST(0.104528464376926) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.978147625923157), FRAC_CONST(0.207911700010300) }, { FRAC_CONST(0.965925812721252), FRAC_CONST(0.258819043636322) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.933580398559570), FRAC_CONST(0.358367949724197) }, { FRAC_CONST(0.913545429706573), FRAC_CONST(0.406736642122269) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.866025388240814), FRAC_CONST(0.500000000000000) }, { FRAC_CONST(0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.777145922183990), FRAC_CONST(0.629320383071899) }, { FRAC_CONST(0.743144810199738), FRAC_CONST(0.669130623340607) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.669130563735962), FRAC_CONST(0.743144869804382) }, { FRAC_CONST(0.629320383071899), FRAC_CONST(0.777145981788635) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.544638991355896), FRAC_CONST(0.838670611381531) }, { FRAC_CONST(0.499999970197678), FRAC_CONST(0.866025447845459) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.406736612319946), FRAC_CONST(0.913545489311218) }, { FRAC_CONST(0.358367860317230), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.258819073438644), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(0.207911655306816), FRAC_CONST(0.978147625923157) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(0.104528419673443), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(0.052335973829031), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.052336059510708), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(-0.104528509080410), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.156434446573257), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.207911744713783), FRAC_CONST(0.978147566318512) }, { FRAC_CONST(-0.258819162845612), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.358367949724197), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(-0.406736701726913), FRAC_CONST(0.913545429706573) }, { FRAC_CONST(-0.453990608453751), FRAC_CONST(0.891006469726563) }, { FRAC_CONST(-0.500000059604645), FRAC_CONST(0.866025388240814) }, { FRAC_CONST(-0.544639050960541), FRAC_CONST(0.838670551776886) }, { FRAC_CONST(-0.587785184383392), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.629320502281189), FRAC_CONST(0.777145862579346) }, { FRAC_CONST(-0.669130682945251), FRAC_CONST(0.743144810199738) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.743144929409027), FRAC_CONST(0.669130444526672) }, { FRAC_CONST(-0.777146041393280), FRAC_CONST(0.629320263862610) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(-0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(-0.866025388240814), FRAC_CONST(0.500000059604645) }, { FRAC_CONST(-0.891006588935852), FRAC_CONST(0.453990370035172) }, { FRAC_CONST(-0.913545489311218), FRAC_CONST(0.406736582517624) }, { FRAC_CONST(-0.933580458164215), FRAC_CONST(0.358367919921875) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.965925872325897), FRAC_CONST(0.258818924427032) }, { FRAC_CONST(-0.978147625923157), FRAC_CONST(0.207911610603333) }, { FRAC_CONST(-0.987688362598419), FRAC_CONST(0.156434446573257) }, { FRAC_CONST(-0.994521915912628), FRAC_CONST(0.104528494179249) }, { FRAC_CONST(-0.998629570007324), FRAC_CONST(0.052335809916258) }, { FRAC_CONST(-1.000000000000000), FRAC_CONST(-0.000000087422777) }, { FRAC_CONST(-0.998629510402679), FRAC_CONST(-0.052335985004902) }, { FRAC_CONST(-0.994521856307983), FRAC_CONST(-0.104528672993183) }, { FRAC_CONST(-0.987688302993774), FRAC_CONST(-0.156434610486031) }, { FRAC_CONST(-0.978147566318512), FRAC_CONST(-0.207911789417267) }, { FRAC_CONST(-0.965925812721252), FRAC_CONST(-0.258819073438644) }, { FRAC_CONST(-0.951056540012360), FRAC_CONST(-0.309016972780228) }, { FRAC_CONST(-0.933580398559570), FRAC_CONST(-0.358368098735809) }, { FRAC_CONST(-0.913545429706573), FRAC_CONST(-0.406736731529236) }, { FRAC_CONST(-0.891006529331207), FRAC_CONST(-0.453990548849106) }, { FRAC_CONST(-0.866025269031525), FRAC_CONST(-0.500000178813934) }, { FRAC_CONST(-0.838670492172241), FRAC_CONST(-0.544639170169830) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(-0.777145922183990), FRAC_CONST(-0.629320442676544) }, { FRAC_CONST(-0.743144810199738), FRAC_CONST(-0.669130623340607) }, { FRAC_CONST(-0.707106649875641), FRAC_CONST(-0.707106888294220) }, { FRAC_CONST(-0.669130504131317), FRAC_CONST(-0.743144869804382) }, { FRAC_CONST(-0.629320323467255), FRAC_CONST(-0.777145981788635) }, { FRAC_CONST(-0.587785065174103), FRAC_CONST(-0.809017121791840) }, { FRAC_CONST(-0.544639110565186), FRAC_CONST(-0.838670551776886) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.996917307376862), FRAC_CONST(0.078459098935127) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.852640151977539), FRAC_CONST(0.522498548030853) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.760405957698822), FRAC_CONST(0.649448096752167) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.649448037147522), FRAC_CONST(0.760405957698822) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.522498488426209), FRAC_CONST(0.852640211582184) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.233445301651955), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(0.078459084033966), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.156434446573257), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.453990608453751), FRAC_CONST(0.891006469726563) }, { FRAC_CONST(-0.587785184383392), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(-0.891006588935852), FRAC_CONST(0.453990370035172) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.987688362598419), FRAC_CONST(0.156434446573257) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.760405957698822), FRAC_CONST(0.649448096752167) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.078459173440933), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.522498667240143), FRAC_CONST(0.852640092372894) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.852640211582184), FRAC_CONST(0.522498488426209) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.996917366981506), FRAC_CONST(0.078459039330482) }, { FRAC_CONST(-0.987688302993774), FRAC_CONST(-0.156434610486031) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(-0.649447917938232), FRAC_CONST(-0.760406076908112) }, { FRAC_CONST(-0.453990221023560), FRAC_CONST(-0.891006648540497) }, { FRAC_CONST(-0.233445450663567), FRAC_CONST(-0.972369909286499) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.309017121791840), FRAC_CONST(-0.951056480407715) } }; #endif ALIGN static const complex_t cfft_tab_64[] = { { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.881921231746674), FRAC_CONST(0.471396833658218) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(-0.098017267882824) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.773010551929474), FRAC_CONST(-0.634393215179443) }, { FRAC_CONST(-0.555570006370544), FRAC_CONST(-0.831469774246216) }, { FRAC_CONST(-0.290284544229507), FRAC_CONST(-0.956940352916718) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.000000011924881), FRAC_CONST(-1.000000000000000) } }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const complex_t cfft_tab_60[] = { { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.994521915912628), FRAC_CONST(0.104528464376926) }, { FRAC_CONST(0.978147625923157), FRAC_CONST(0.207911700010300) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.913545429706573), FRAC_CONST(0.406736642122269) }, { FRAC_CONST(0.866025388240814), FRAC_CONST(0.500000000000000) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.743144810199738), FRAC_CONST(0.669130623340607) }, { FRAC_CONST(0.669130563735962), FRAC_CONST(0.743144869804382) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.499999970197678), FRAC_CONST(0.866025447845459) }, { FRAC_CONST(0.406736612319946), FRAC_CONST(0.913545489311218) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.207911655306816), FRAC_CONST(0.978147625923157) }, { FRAC_CONST(0.104528419673443), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.104528509080410), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.207911744713783), FRAC_CONST(0.978147566318512) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.406736701726913), FRAC_CONST(0.913545429706573) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.978147625923157), FRAC_CONST(0.207911700010300) }, { FRAC_CONST(0.913545429706573), FRAC_CONST(0.406736642122269) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.669130563735962), FRAC_CONST(0.743144869804382) }, { FRAC_CONST(0.499999970197678), FRAC_CONST(0.866025447845459) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.104528419673443), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.104528509080410), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.500000059604645), FRAC_CONST(0.866025388240814) }, { FRAC_CONST(-0.669130682945251), FRAC_CONST(0.743144810199738) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(-0.913545489311218), FRAC_CONST(0.406736582517624) }, { FRAC_CONST(-0.978147625923157), FRAC_CONST(0.207911610603333) }, { FRAC_CONST(-1.000000000000000), FRAC_CONST(-0.000000087422777) }, { FRAC_CONST(-0.978147566318512), FRAC_CONST(-0.207911789417267) }, { FRAC_CONST(-0.913545429706573), FRAC_CONST(-0.406736731529236) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(-0.669130504131317), FRAC_CONST(-0.743144869804382) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.309017121791840), FRAC_CONST(-0.951056480407715) } }; #endif #ifdef LD_DEC ALIGN static const complex_t cfft_tab_256[] = { { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.999698817729950), FRAC_CONST(0.024541229009628) }, { FRAC_CONST(0.998795449733734), FRAC_CONST(0.049067676067352) }, { FRAC_CONST(0.997290432453156), FRAC_CONST(0.073564566671848) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.992479562759399), FRAC_CONST(0.122410677373409) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.985277652740479), FRAC_CONST(0.170961901545525) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.975702106952667), FRAC_CONST(0.219101235270500) }, { FRAC_CONST(0.970031261444092), FRAC_CONST(0.242980197072029) }, { FRAC_CONST(0.963776051998138), FRAC_CONST(0.266712784767151) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.949528157711029), FRAC_CONST(0.313681751489639) }, { FRAC_CONST(0.941544055938721), FRAC_CONST(0.336889863014221) }, { FRAC_CONST(0.932992815971375), FRAC_CONST(0.359895050525665) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.914209723472595), FRAC_CONST(0.405241340398788) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.893224298954010), FRAC_CONST(0.449611335992813) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.870086967945099), FRAC_CONST(0.492898225784302) }, { FRAC_CONST(0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(0.844853579998016), FRAC_CONST(0.534997642040253) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.817584812641144), FRAC_CONST(0.575808227062225) }, { FRAC_CONST(0.803207516670227), FRAC_CONST(0.595699310302734) }, { FRAC_CONST(0.788346409797668), FRAC_CONST(0.615231633186340) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.757208824157715), FRAC_CONST(0.653172850608826) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.724247097969055), FRAC_CONST(0.689540565013886) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.689540505409241), FRAC_CONST(0.724247097969055) }, { FRAC_CONST(0.671558916568756), FRAC_CONST(0.740951180458069) }, { FRAC_CONST(0.653172791004181), FRAC_CONST(0.757208883762360) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.615231573581696), FRAC_CONST(0.788346409797668) }, { FRAC_CONST(0.595699310302734), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(0.575808167457581), FRAC_CONST(0.817584812641144) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.534997642040253), FRAC_CONST(0.844853579998016) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.492898195981979), FRAC_CONST(0.870086967945099) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.449611306190491), FRAC_CONST(0.893224298954010) }, { FRAC_CONST(0.427555114030838), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(0.405241280794144), FRAC_CONST(0.914209783077240) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.359894961118698), FRAC_CONST(0.932992815971375) }, { FRAC_CONST(0.336889833211899), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(0.313681662082672), FRAC_CONST(0.949528217315674) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.266712754964828), FRAC_CONST(0.963776051998138) }, { FRAC_CONST(0.242980122566223), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.219101220369339), FRAC_CONST(0.975702106952667) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.170961856842041), FRAC_CONST(0.985277652740479) }, { FRAC_CONST(0.146730497479439), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(0.122410625219345), FRAC_CONST(0.992479562759399) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.073564492166042), FRAC_CONST(0.997290432453156) }, { FRAC_CONST(0.049067649990320), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(0.024541135877371), FRAC_CONST(0.999698817729950) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.998795449733734), FRAC_CONST(0.049067676067352) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.970031261444092), FRAC_CONST(0.242980197072029) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.941544055938721), FRAC_CONST(0.336889863014221) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.803207516670227), FRAC_CONST(0.595699310302734) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.671558916568756), FRAC_CONST(0.740951180458069) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.595699310302734), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.427555114030838), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.336889833211899), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.242980122566223), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.146730497479439), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.049067649990320), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.049067739397287), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.098017223179340), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.146730571985245), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.242980197072029), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(-0.290284723043442), FRAC_CONST(0.956940293312073) }, { FRAC_CONST(-0.336889922618866), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.427555084228516), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.514102756977081), FRAC_CONST(0.857728600502014) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.595699369907379), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(-0.634393274784088), FRAC_CONST(0.773010492324829) }, { FRAC_CONST(-0.671559035778046), FRAC_CONST(0.740951061248779) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.740951240062714), FRAC_CONST(0.671558856964111) }, { FRAC_CONST(-0.773010492324829), FRAC_CONST(0.634393274784088) }, { FRAC_CONST(-0.803207635879517), FRAC_CONST(0.595699131488800) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(-0.881921350955963), FRAC_CONST(0.471396625041962) }, { FRAC_CONST(-0.903989315032959), FRAC_CONST(0.427555054426193) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.941544115543365), FRAC_CONST(0.336889803409576) }, { FRAC_CONST(-0.956940352916718), FRAC_CONST(0.290284723043442) }, { FRAC_CONST(-0.970031261444092), FRAC_CONST(0.242980077862740) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.989176511764526), FRAC_CONST(0.146730333566666) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(0.098017096519470) }, { FRAC_CONST(-0.998795449733734), FRAC_CONST(0.049067486077547) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.997290432453156), FRAC_CONST(0.073564566671848) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.975702106952667), FRAC_CONST(0.219101235270500) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.932992815971375), FRAC_CONST(0.359895050525665) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.870086967945099), FRAC_CONST(0.492898225784302) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.788346469402313), FRAC_CONST(0.615231573581696) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.689540505409241), FRAC_CONST(0.724247097969055) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.575808227062225), FRAC_CONST(0.817584812641144) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.449611306190491), FRAC_CONST(0.893224298954010) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.313681751489639), FRAC_CONST(0.949528157711029) }, { FRAC_CONST(0.242980241775513), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.170961856842041), FRAC_CONST(0.985277652740479) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.024541255086660), FRAC_CONST(0.999698817729950) }, { FRAC_CONST(-0.049067739397287), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.122410707175732), FRAC_CONST(0.992479503154755) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.266712725162506), FRAC_CONST(0.963776051998138) }, { FRAC_CONST(-0.336889803409576), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(-0.405241340398788), FRAC_CONST(0.914209723472595) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.534997701644897), FRAC_CONST(0.844853520393372) }, { FRAC_CONST(-0.595699369907379), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(-0.653172850608826), FRAC_CONST(0.757208824157715) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.757208824157715), FRAC_CONST(0.653172850608826) }, { FRAC_CONST(-0.803207516670227), FRAC_CONST(0.595699369907379) }, { FRAC_CONST(-0.844853520393372), FRAC_CONST(0.534997701644897) }, { FRAC_CONST(-0.881921231746674), FRAC_CONST(0.471396833658218) }, { FRAC_CONST(-0.914209783077240), FRAC_CONST(0.405241221189499) }, { FRAC_CONST(-0.941544115543365), FRAC_CONST(0.336889803409576) }, { FRAC_CONST(-0.963776051998138), FRAC_CONST(0.266712725162506) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.992479503154755), FRAC_CONST(0.122410699725151) }, { FRAC_CONST(-0.998795449733734), FRAC_CONST(0.049067724496126) }, { FRAC_CONST(-0.999698817729950), FRAC_CONST(-0.024541147053242) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(-0.098017267882824) }, { FRAC_CONST(-0.985277652740479), FRAC_CONST(-0.170961990952492) }, { FRAC_CONST(-0.970031261444092), FRAC_CONST(-0.242980241775513) }, { FRAC_CONST(-0.949528157711029), FRAC_CONST(-0.313681781291962) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.893224298954010), FRAC_CONST(-0.449611306190491) }, { FRAC_CONST(-0.857728660106659), FRAC_CONST(-0.514102697372437) }, { FRAC_CONST(-0.817584872245789), FRAC_CONST(-0.575808107852936) }, { FRAC_CONST(-0.773010551929474), FRAC_CONST(-0.634393215179443) }, { FRAC_CONST(-0.724247038364410), FRAC_CONST(-0.689540624618530) }, { FRAC_CONST(-0.671558916568756), FRAC_CONST(-0.740951180458069) }, { FRAC_CONST(-0.615231573581696), FRAC_CONST(-0.788346469402313) }, { FRAC_CONST(-0.555570006370544), FRAC_CONST(-0.831469774246216) }, { FRAC_CONST(-0.492898195981979), FRAC_CONST(-0.870086967945099) }, { FRAC_CONST(-0.427554935216904), FRAC_CONST(-0.903989374637604) }, { FRAC_CONST(-0.359895110130310), FRAC_CONST(-0.932992756366730) }, { FRAC_CONST(-0.290284544229507), FRAC_CONST(-0.956940352916718) }, { FRAC_CONST(-0.219101369380951), FRAC_CONST(-0.975702106952667) }, { FRAC_CONST(-0.146730408072472), FRAC_CONST(-0.989176511764526) }, { FRAC_CONST(-0.073564760386944), FRAC_CONST(-0.997290432453156) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.881921231746674), FRAC_CONST(0.471396833658218) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(-0.098017267882824) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.773010551929474), FRAC_CONST(-0.634393215179443) }, { FRAC_CONST(-0.555570006370544), FRAC_CONST(-0.831469774246216) }, { FRAC_CONST(-0.290284544229507), FRAC_CONST(-0.956940352916718) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.000000011924881), FRAC_CONST(-1.000000000000000) } }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const complex_t cfft_tab_240[] = { { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.999657332897186), FRAC_CONST(0.026176949962974) }, { FRAC_CONST(0.998629510402679), FRAC_CONST(0.052335958927870) }, { FRAC_CONST(0.996917307376862), FRAC_CONST(0.078459098935127) }, { FRAC_CONST(0.994521915912628), FRAC_CONST(0.104528464376926) }, { FRAC_CONST(0.991444885730743), FRAC_CONST(0.130526199936867) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.983254909515381), FRAC_CONST(0.182235524058342) }, { FRAC_CONST(0.978147625923157), FRAC_CONST(0.207911700010300) }, { FRAC_CONST(0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(0.965925812721252), FRAC_CONST(0.258819043636322) }, { FRAC_CONST(0.958819746971130), FRAC_CONST(0.284015357494354) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.942641496658325), FRAC_CONST(0.333806872367859) }, { FRAC_CONST(0.933580398559570), FRAC_CONST(0.358367949724197) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.913545429706573), FRAC_CONST(0.406736642122269) }, { FRAC_CONST(0.902585268020630), FRAC_CONST(0.430511116981506) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.878817081451416), FRAC_CONST(0.477158784866333) }, { FRAC_CONST(0.866025388240814), FRAC_CONST(0.500000000000000) }, { FRAC_CONST(0.852640151977539), FRAC_CONST(0.522498548030853) }, { FRAC_CONST(0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(0.824126183986664), FRAC_CONST(0.566406250000000) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.793353319168091), FRAC_CONST(0.608761429786682) }, { FRAC_CONST(0.777145922183990), FRAC_CONST(0.629320383071899) }, { FRAC_CONST(0.760405957698822), FRAC_CONST(0.649448096752167) }, { FRAC_CONST(0.743144810199738), FRAC_CONST(0.669130623340607) }, { FRAC_CONST(0.725374400615692), FRAC_CONST(0.688354551792145) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.688354551792145), FRAC_CONST(0.725374400615692) }, { FRAC_CONST(0.669130563735962), FRAC_CONST(0.743144869804382) }, { FRAC_CONST(0.649448037147522), FRAC_CONST(0.760405957698822) }, { FRAC_CONST(0.629320383071899), FRAC_CONST(0.777145981788635) }, { FRAC_CONST(0.608761370182037), FRAC_CONST(0.793353378772736) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.566406250000000), FRAC_CONST(0.824126183986664) }, { FRAC_CONST(0.544638991355896), FRAC_CONST(0.838670611381531) }, { FRAC_CONST(0.522498488426209), FRAC_CONST(0.852640211582184) }, { FRAC_CONST(0.499999970197678), FRAC_CONST(0.866025447845459) }, { FRAC_CONST(0.477158755064011), FRAC_CONST(0.878817141056061) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.430511027574539), FRAC_CONST(0.902585327625275) }, { FRAC_CONST(0.406736612319946), FRAC_CONST(0.913545489311218) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.358367860317230), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(0.333806812763214), FRAC_CONST(0.942641496658325) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.284015327692032), FRAC_CONST(0.958819746971130) }, { FRAC_CONST(0.258819073438644), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(0.233445301651955), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(0.207911655306816), FRAC_CONST(0.978147625923157) }, { FRAC_CONST(0.182235524058342), FRAC_CONST(0.983254909515381) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(0.130526125431061), FRAC_CONST(0.991444885730743) }, { FRAC_CONST(0.104528419673443), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(0.078459084033966), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(0.052335973829031), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(0.026176875457168), FRAC_CONST(0.999657332897186) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.026176963001490), FRAC_CONST(0.999657332897186) }, { FRAC_CONST(-0.052336059510708), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(-0.078459173440933), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(-0.104528509080410), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.130526214838028), FRAC_CONST(0.991444885730743) }, { FRAC_CONST(-0.156434446573257), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.182235598564148), FRAC_CONST(0.983254909515381) }, { FRAC_CONST(-0.207911744713783), FRAC_CONST(0.978147566318512) }, { FRAC_CONST(-0.233445391058922), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(-0.258819162845612), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(-0.284015417098999), FRAC_CONST(0.958819687366486) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.333806872367859), FRAC_CONST(0.942641496658325) }, { FRAC_CONST(-0.358367949724197), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.406736701726913), FRAC_CONST(0.913545429706573) }, { FRAC_CONST(-0.430511116981506), FRAC_CONST(0.902585268020630) }, { FRAC_CONST(-0.453990608453751), FRAC_CONST(0.891006469726563) }, { FRAC_CONST(-0.477158725261688), FRAC_CONST(0.878817141056061) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.998629510402679), FRAC_CONST(0.052335958927870) }, { FRAC_CONST(0.994521915912628), FRAC_CONST(0.104528464376926) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.978147625923157), FRAC_CONST(0.207911700010300) }, { FRAC_CONST(0.965925812721252), FRAC_CONST(0.258819043636322) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.933580398559570), FRAC_CONST(0.358367949724197) }, { FRAC_CONST(0.913545429706573), FRAC_CONST(0.406736642122269) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.866025388240814), FRAC_CONST(0.500000000000000) }, { FRAC_CONST(0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.777145922183990), FRAC_CONST(0.629320383071899) }, { FRAC_CONST(0.743144810199738), FRAC_CONST(0.669130623340607) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.669130563735962), FRAC_CONST(0.743144869804382) }, { FRAC_CONST(0.629320383071899), FRAC_CONST(0.777145981788635) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.544638991355896), FRAC_CONST(0.838670611381531) }, { FRAC_CONST(0.499999970197678), FRAC_CONST(0.866025447845459) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.406736612319946), FRAC_CONST(0.913545489311218) }, { FRAC_CONST(0.358367860317230), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.258819073438644), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(0.207911655306816), FRAC_CONST(0.978147625923157) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(0.104528419673443), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(0.052335973829031), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.052336059510708), FRAC_CONST(0.998629510402679) }, { FRAC_CONST(-0.104528509080410), FRAC_CONST(0.994521915912628) }, { FRAC_CONST(-0.156434446573257), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.207911744713783), FRAC_CONST(0.978147566318512) }, { FRAC_CONST(-0.258819162845612), FRAC_CONST(0.965925812721252) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.358367949724197), FRAC_CONST(0.933580458164215) }, { FRAC_CONST(-0.406736701726913), FRAC_CONST(0.913545429706573) }, { FRAC_CONST(-0.453990608453751), FRAC_CONST(0.891006469726563) }, { FRAC_CONST(-0.500000059604645), FRAC_CONST(0.866025388240814) }, { FRAC_CONST(-0.544639050960541), FRAC_CONST(0.838670551776886) }, { FRAC_CONST(-0.587785184383392), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.629320502281189), FRAC_CONST(0.777145862579346) }, { FRAC_CONST(-0.669130682945251), FRAC_CONST(0.743144810199738) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.743144929409027), FRAC_CONST(0.669130444526672) }, { FRAC_CONST(-0.777146041393280), FRAC_CONST(0.629320263862610) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(-0.838670551776886), FRAC_CONST(0.544639050960541) }, { FRAC_CONST(-0.866025388240814), FRAC_CONST(0.500000059604645) }, { FRAC_CONST(-0.891006588935852), FRAC_CONST(0.453990370035172) }, { FRAC_CONST(-0.913545489311218), FRAC_CONST(0.406736582517624) }, { FRAC_CONST(-0.933580458164215), FRAC_CONST(0.358367919921875) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.965925872325897), FRAC_CONST(0.258818924427032) }, { FRAC_CONST(-0.978147625923157), FRAC_CONST(0.207911610603333) }, { FRAC_CONST(-0.987688362598419), FRAC_CONST(0.156434446573257) }, { FRAC_CONST(-0.994521915912628), FRAC_CONST(0.104528494179249) }, { FRAC_CONST(-0.998629570007324), FRAC_CONST(0.052335809916258) }, { FRAC_CONST(-1.000000000000000), FRAC_CONST(-0.000000087422777) }, { FRAC_CONST(-0.998629510402679), FRAC_CONST(-0.052335985004902) }, { FRAC_CONST(-0.994521856307983), FRAC_CONST(-0.104528672993183) }, { FRAC_CONST(-0.987688302993774), FRAC_CONST(-0.156434610486031) }, { FRAC_CONST(-0.978147566318512), FRAC_CONST(-0.207911789417267) }, { FRAC_CONST(-0.965925812721252), FRAC_CONST(-0.258819073438644) }, { FRAC_CONST(-0.951056540012360), FRAC_CONST(-0.309016972780228) }, { FRAC_CONST(-0.933580398559570), FRAC_CONST(-0.358368098735809) }, { FRAC_CONST(-0.913545429706573), FRAC_CONST(-0.406736731529236) }, { FRAC_CONST(-0.891006529331207), FRAC_CONST(-0.453990548849106) }, { FRAC_CONST(-0.866025269031525), FRAC_CONST(-0.500000178813934) }, { FRAC_CONST(-0.838670492172241), FRAC_CONST(-0.544639170169830) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(-0.777145922183990), FRAC_CONST(-0.629320442676544) }, { FRAC_CONST(-0.743144810199738), FRAC_CONST(-0.669130623340607) }, { FRAC_CONST(-0.707106649875641), FRAC_CONST(-0.707106888294220) }, { FRAC_CONST(-0.669130504131317), FRAC_CONST(-0.743144869804382) }, { FRAC_CONST(-0.629320323467255), FRAC_CONST(-0.777145981788635) }, { FRAC_CONST(-0.587785065174103), FRAC_CONST(-0.809017121791840) }, { FRAC_CONST(-0.544639110565186), FRAC_CONST(-0.838670551776886) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.996917307376862), FRAC_CONST(0.078459098935127) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.852640151977539), FRAC_CONST(0.522498548030853) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.760405957698822), FRAC_CONST(0.649448096752167) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.649448037147522), FRAC_CONST(0.760405957698822) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.522498488426209), FRAC_CONST(0.852640211582184) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.233445301651955), FRAC_CONST(0.972369909286499) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(0.078459084033966), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.987688362598419), FRAC_CONST(0.156434476375580) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.453990519046783), FRAC_CONST(0.891006529331207) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.156434446573257), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.453990608453751), FRAC_CONST(0.891006469726563) }, { FRAC_CONST(-0.587785184383392), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(-0.891006588935852), FRAC_CONST(0.453990370035172) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.987688362598419), FRAC_CONST(0.156434446573257) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.972369909286499), FRAC_CONST(0.233445376157761) }, { FRAC_CONST(0.891006529331207), FRAC_CONST(0.453990519046783) }, { FRAC_CONST(0.760405957698822), FRAC_CONST(0.649448096752167) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.156434372067451), FRAC_CONST(0.987688362598419) }, { FRAC_CONST(-0.078459173440933), FRAC_CONST(0.996917307376862) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.522498667240143), FRAC_CONST(0.852640092372894) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.852640211582184), FRAC_CONST(0.522498488426209) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.996917366981506), FRAC_CONST(0.078459039330482) }, { FRAC_CONST(-0.987688302993774), FRAC_CONST(-0.156434610486031) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(-0.649447917938232), FRAC_CONST(-0.760406076908112) }, { FRAC_CONST(-0.453990221023560), FRAC_CONST(-0.891006648540497) }, { FRAC_CONST(-0.233445450663567), FRAC_CONST(-0.972369909286499) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.951056540012360), FRAC_CONST(0.309017002582550) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.809017002582550), FRAC_CONST(0.587785243988037) }, { FRAC_CONST(0.309016972780228), FRAC_CONST(0.951056540012360) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.809017062187195), FRAC_CONST(0.587785184383392) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.587785243988037), FRAC_CONST(0.809017002582550) }, { FRAC_CONST(-0.309017032384872), FRAC_CONST(0.951056480407715) }, { FRAC_CONST(-0.951056599617004), FRAC_CONST(0.309016793966293) }, { FRAC_CONST(-0.809016942977905), FRAC_CONST(-0.587785363197327) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.309017121791840), FRAC_CONST(-0.951056480407715) } }; #endif #endif ALIGN static const complex_t cfft_tab_128[] = { { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.998795449733734), FRAC_CONST(0.049067676067352) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.989176511764526), FRAC_CONST(0.146730467677116) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.970031261444092), FRAC_CONST(0.242980197072029) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.941544055938721), FRAC_CONST(0.336889863014221) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.903989315032959), FRAC_CONST(0.427555084228516) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.803207516670227), FRAC_CONST(0.595699310302734) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.740951120853424), FRAC_CONST(0.671558976173401) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.671558916568756), FRAC_CONST(0.740951180458069) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.595699310302734), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.514102697372437), FRAC_CONST(0.857728660106659) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.427555114030838), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.336889833211899), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.242980122566223), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.146730497479439), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(0.049067649990320), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.049067739397287), FRAC_CONST(0.998795449733734) }, { FRAC_CONST(-0.098017223179340), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.146730571985245), FRAC_CONST(0.989176511764526) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.242980197072029), FRAC_CONST(0.970031261444092) }, { FRAC_CONST(-0.290284723043442), FRAC_CONST(0.956940293312073) }, { FRAC_CONST(-0.336889922618866), FRAC_CONST(0.941544055938721) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.427555084228516), FRAC_CONST(0.903989315032959) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.514102756977081), FRAC_CONST(0.857728600502014) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.595699369907379), FRAC_CONST(0.803207516670227) }, { FRAC_CONST(-0.634393274784088), FRAC_CONST(0.773010492324829) }, { FRAC_CONST(-0.671559035778046), FRAC_CONST(0.740951061248779) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.740951240062714), FRAC_CONST(0.671558856964111) }, { FRAC_CONST(-0.773010492324829), FRAC_CONST(0.634393274784088) }, { FRAC_CONST(-0.803207635879517), FRAC_CONST(0.595699131488800) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.857728600502014), FRAC_CONST(0.514102756977081) }, { FRAC_CONST(-0.881921350955963), FRAC_CONST(0.471396625041962) }, { FRAC_CONST(-0.903989315032959), FRAC_CONST(0.427555054426193) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.941544115543365), FRAC_CONST(0.336889803409576) }, { FRAC_CONST(-0.956940352916718), FRAC_CONST(0.290284723043442) }, { FRAC_CONST(-0.970031261444092), FRAC_CONST(0.242980077862740) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.989176511764526), FRAC_CONST(0.146730333566666) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(0.098017096519470) }, { FRAC_CONST(-0.998795449733734), FRAC_CONST(0.049067486077547) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.995184719562531), FRAC_CONST(0.098017141222954) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.881921231746674), FRAC_CONST(0.471396744251251) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.773010432720184), FRAC_CONST(0.634393334388733) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.471396654844284), FRAC_CONST(0.881921291351318) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.290284633636475), FRAC_CONST(0.956940352916718) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.980785250663757), FRAC_CONST(0.195090323686600) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.555570185184479), FRAC_CONST(0.831469655036926) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.195090234279633), FRAC_CONST(0.980785310268402) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.382683515548706), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.555570363998413), FRAC_CONST(0.831469535827637) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.831469655036926), FRAC_CONST(0.555570185184479) }, { FRAC_CONST(-0.923879623413086), FRAC_CONST(0.382683277130127) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.956940352916718), FRAC_CONST(0.290284663438797) }, { FRAC_CONST(0.831469595432281), FRAC_CONST(0.555570244789124) }, { FRAC_CONST(0.634393274784088), FRAC_CONST(0.773010432720184) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(0.098017133772373), FRAC_CONST(0.995184719562531) }, { FRAC_CONST(-0.195090323686600), FRAC_CONST(0.980785250663757) }, { FRAC_CONST(-0.471396833658218), FRAC_CONST(0.881921231746674) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.881921231746674), FRAC_CONST(0.471396833658218) }, { FRAC_CONST(-0.980785310268402), FRAC_CONST(0.195090308785439) }, { FRAC_CONST(-0.995184719562531), FRAC_CONST(-0.098017267882824) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(-0.773010551929474), FRAC_CONST(-0.634393215179443) }, { FRAC_CONST(-0.555570006370544), FRAC_CONST(-0.831469774246216) }, { FRAC_CONST(-0.290284544229507), FRAC_CONST(-0.956940352916718) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.923879504203796), FRAC_CONST(0.382683455944061) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.000000043711388), FRAC_CONST(1.000000000000000) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.382683426141739), FRAC_CONST(0.923879504203796) }, { FRAC_CONST(-0.707106769084930), FRAC_CONST(0.707106769084930) }, { FRAC_CONST(-0.923879504203796), FRAC_CONST(-0.382683426141739) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(1.000000000000000), FRAC_CONST(0.000000000000000) }, { FRAC_CONST(0.000000011924881), FRAC_CONST(-1.000000000000000) } }; #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/lt_predict.h0000644000175000017500000000406214647725152016212 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: lt_predict.h,v 1.20 2007/11/01 12:33:31 menno Exp $ **/ #ifdef LTP_DEC #ifndef __LT_PREDICT_H__ #define __LT_PREDICT_H__ #ifdef __cplusplus extern "C" { #endif #include "filtbank.h" uint8_t is_ltp_ot(uint8_t object_type); void lt_prediction(ic_stream *ics, ltp_info *ltp, real_t *spec, int16_t *lt_pred_stat, fb_info *fb, uint8_t win_shape, uint8_t win_shape_prev, uint8_t sr_index, uint8_t object_type, uint16_t frame_len); void lt_update_state(int16_t *lt_pred_stat, real_t *time, real_t *overlap, uint16_t frame_len, uint8_t object_type); #ifdef __cplusplus } #endif #endif #endif xine-lib-1.2/contrib/libfaad/ps_syntax.c0000644000175000017500000006075014647725152016112 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ps_syntax.c,v 1.11 2007/11/01 12:33:33 menno Exp $ **/ #include "common.h" #ifdef PS_DEC #include "bits.h" #include "ps_dec.h" /* type definitaions */ typedef const int8_t (*ps_huff_tab)[2]; /* static data tables */ static const uint8_t nr_iid_par_tab[] = { 10, 20, 34, 10, 20, 34, 0, 0 }; static const uint8_t nr_ipdopd_par_tab[] = { 5, 11, 17, 5, 11, 17, 0, 0 }; static const uint8_t nr_icc_par_tab[] = { 10, 20, 34, 10, 20, 34, 0, 0 }; static const uint8_t num_env_tab[][4] = { { 0, 1, 2, 4 }, { 1, 2, 3, 4 } }; /* binary lookup huffman tables */ static const int8_t f_huff_iid_def[][2] = { { /*0*/ -31, 1 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 1x */ { /*1*/ -30, /*-1*/ -32 }, /* index 2: 3 bits: 10x */ { 4, 5 }, /* index 3: 3 bits: 11x */ { /*2*/ -29, /*-2*/ -33 }, /* index 4: 4 bits: 110x */ { 6, 7 }, /* index 5: 4 bits: 111x */ { /*3*/ -28, /*-3*/ -34 }, /* index 6: 5 bits: 1110x */ { 8, 9 }, /* index 7: 5 bits: 1111x */ { /*-4*/ -35, /*4*/ -27 }, /* index 8: 6 bits: 11110x */ { /*5*/ -26, 10 }, /* index 9: 6 bits: 11111x */ { /*-5*/ -36, 11 }, /* index 10: 7 bits: 111111x */ { /*6*/ -25, 12 }, /* index 11: 8 bits: 1111111x */ { /*-6*/ -37, 13 }, /* index 12: 9 bits: 11111111x */ { /*-7*/ -38, 14 }, /* index 13: 10 bits: 111111111x */ { /*7*/ -24, 15 }, /* index 14: 11 bits: 1111111111x */ { 16, 17 }, /* index 15: 12 bits: 11111111111x */ { /*8*/ -23, /*-8*/ -39 }, /* index 16: 13 bits: 111111111110x */ { 18, 19 }, /* index 17: 13 bits: 111111111111x */ { /*9*/ -22, /*10*/ -21 }, /* index 18: 14 bits: 1111111111110x */ { 20, 21 }, /* index 19: 14 bits: 1111111111111x */ { /*-9*/ -40, /*11*/ -20 }, /* index 20: 15 bits: 11111111111110x */ { 22, 23 }, /* index 21: 15 bits: 11111111111111x */ { /*-10*/ -41, 24 }, /* index 22: 16 bits: 111111111111110x */ { 25, 26 }, /* index 23: 16 bits: 111111111111111x */ { /*-11*/ -42, /*-14*/ -45 }, /* index 24: 17 bits: 1111111111111101x */ { /*-13*/ -44, /*-12*/ -43 }, /* index 25: 17 bits: 1111111111111110x */ { /*12*/ -19, 27 }, /* index 26: 17 bits: 1111111111111111x */ { /*13*/ -18, /*14*/ -17 } /* index 27: 18 bits: 11111111111111111x */ }; static const int8_t t_huff_iid_def[][2] = { { /*0*/ -31, 1 }, /* index 0: 1 bits: x */ { /*-1*/ -32, 2 }, /* index 1: 2 bits: 1x */ { /*1*/ -30, 3 }, /* index 2: 3 bits: 11x */ { /*-2*/ -33, 4 }, /* index 3: 4 bits: 111x */ { /*2*/ -29, 5 }, /* index 4: 5 bits: 1111x */ { /*-3*/ -34, 6 }, /* index 5: 6 bits: 11111x */ { /*3*/ -28, 7 }, /* index 6: 7 bits: 111111x */ { /*-4*/ -35, 8 }, /* index 7: 8 bits: 1111111x */ { /*4*/ -27, 9 }, /* index 8: 9 bits: 11111111x */ { /*-5*/ -36, 10 }, /* index 9: 10 bits: 111111111x */ { /*5*/ -26, 11 }, /* index 10: 11 bits: 1111111111x */ { /*-6*/ -37, 12 }, /* index 11: 12 bits: 11111111111x */ { /*6*/ -25, 13 }, /* index 12: 13 bits: 111111111111x */ { /*7*/ -24, 14 }, /* index 13: 14 bits: 1111111111111x */ { /*-7*/ -38, 15 }, /* index 14: 15 bits: 11111111111111x */ { 16, 17 }, /* index 15: 16 bits: 111111111111111x */ { /*8*/ -23, /*-8*/ -39 }, /* index 16: 17 bits: 1111111111111110x */ { 18, 19 }, /* index 17: 17 bits: 1111111111111111x */ { 20, 21 }, /* index 18: 18 bits: 11111111111111110x */ { 22, 23 }, /* index 19: 18 bits: 11111111111111111x */ { /*9*/ -22, /*-14*/ -45 }, /* index 20: 19 bits: 111111111111111100x */ { /*-13*/ -44, /*-12*/ -43 }, /* index 21: 19 bits: 111111111111111101x */ { 24, 25 }, /* index 22: 19 bits: 111111111111111110x */ { 26, 27 }, /* index 23: 19 bits: 111111111111111111x */ { /*-11*/ -42, /*-10*/ -41 }, /* index 24: 20 bits: 1111111111111111100x */ { /*-9*/ -40, /*10*/ -21 }, /* index 25: 20 bits: 1111111111111111101x */ { /*11*/ -20, /*12*/ -19 }, /* index 26: 20 bits: 1111111111111111110x */ { /*13*/ -18, /*14*/ -17 } /* index 27: 20 bits: 1111111111111111111x */ }; static const int8_t f_huff_iid_fine[][2] = { { 1, /*0*/ -31 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 0x */ { 4, /*-1*/ -32 }, /* index 2: 3 bits: 00x */ { /*1*/ -30, 5 }, /* index 3: 3 bits: 01x */ { /*-2*/ -33, /*2*/ -29 }, /* index 4: 4 bits: 000x */ { 6, 7 }, /* index 5: 4 bits: 011x */ { /*-3*/ -34, /*3*/ -28 }, /* index 6: 5 bits: 0110x */ { 8, 9 }, /* index 7: 5 bits: 0111x */ { /*-4*/ -35, /*4*/ -27 }, /* index 8: 6 bits: 01110x */ { 10, 11 }, /* index 9: 6 bits: 01111x */ { /*-5*/ -36, /*5*/ -26 }, /* index 10: 7 bits: 011110x */ { 12, 13 }, /* index 11: 7 bits: 011111x */ { /*-6*/ -37, /*6*/ -25 }, /* index 12: 8 bits: 0111110x */ { 14, 15 }, /* index 13: 8 bits: 0111111x */ { /*7*/ -24, 16 }, /* index 14: 9 bits: 01111110x */ { 17, 18 }, /* index 15: 9 bits: 01111111x */ { 19, /*-8*/ -39 }, /* index 16: 10 bits: 011111101x */ { /*8*/ -23, 20 }, /* index 17: 10 bits: 011111110x */ { 21, /*-7*/ -38 }, /* index 18: 10 bits: 011111111x */ { /*10*/ -21, 22 }, /* index 19: 11 bits: 0111111010x */ { 23, /*-9*/ -40 }, /* index 20: 11 bits: 0111111101x */ { /*9*/ -22, 24 }, /* index 21: 11 bits: 0111111110x */ { /*-11*/ -42, /*11*/ -20 }, /* index 22: 12 bits: 01111110101x */ { 25, 26 }, /* index 23: 12 bits: 01111111010x */ { 27, /*-10*/ -41 }, /* index 24: 12 bits: 01111111101x */ { 28, /*-12*/ -43 }, /* index 25: 13 bits: 011111110100x */ { /*12*/ -19, 29 }, /* index 26: 13 bits: 011111110101x */ { 30, 31 }, /* index 27: 13 bits: 011111111010x */ { 32, /*-14*/ -45 }, /* index 28: 14 bits: 0111111101000x */ { /*14*/ -17, 33 }, /* index 29: 14 bits: 0111111101011x */ { 34, /*-13*/ -44 }, /* index 30: 14 bits: 0111111110100x */ { /*13*/ -18, 35 }, /* index 31: 14 bits: 0111111110101x */ { 36, 37 }, /* index 32: 15 bits: 01111111010000x */ { 38, /*-15*/ -46 }, /* index 33: 15 bits: 01111111010111x */ { /*15*/ -16, 39 }, /* index 34: 15 bits: 01111111101000x */ { 40, 41 }, /* index 35: 15 bits: 01111111101011x */ { 42, 43 }, /* index 36: 16 bits: 011111110100000x */ { /*-17*/ -48, /*17*/ -14 }, /* index 37: 16 bits: 011111110100001x */ { 44, 45 }, /* index 38: 16 bits: 011111110101110x */ { 46, 47 }, /* index 39: 16 bits: 011111111010001x */ { 48, 49 }, /* index 40: 16 bits: 011111111010110x */ { /*-16*/ -47, /*16*/ -15 }, /* index 41: 16 bits: 011111111010111x */ { /*-21*/ -52, /*21*/ -10 }, /* index 42: 17 bits: 0111111101000000x */ { /*-19*/ -50, /*19*/ -12 }, /* index 43: 17 bits: 0111111101000001x */ { /*-18*/ -49, /*18*/ -13 }, /* index 44: 17 bits: 0111111101011100x */ { 50, 51 }, /* index 45: 17 bits: 0111111101011101x */ { 52, 53 }, /* index 46: 17 bits: 0111111110100010x */ { 54, 55 }, /* index 47: 17 bits: 0111111110100011x */ { 56, 57 }, /* index 48: 17 bits: 0111111110101100x */ { 58, 59 }, /* index 49: 17 bits: 0111111110101101x */ { /*-26*/ -57, /*-25*/ -56 }, /* index 50: 18 bits: 01111111010111010x */ { /*-28*/ -59, /*-27*/ -58 }, /* index 51: 18 bits: 01111111010111011x */ { /*-22*/ -53, /*22*/ -9 }, /* index 52: 18 bits: 01111111101000100x */ { /*-24*/ -55, /*-23*/ -54 }, /* index 53: 18 bits: 01111111101000101x */ { /*25*/ -6, /*26*/ -5 }, /* index 54: 18 bits: 01111111101000110x */ { /*23*/ -8, /*24*/ -7 }, /* index 55: 18 bits: 01111111101000111x */ { /*29*/ -2, /*30*/ -1 }, /* index 56: 18 bits: 01111111101011000x */ { /*27*/ -4, /*28*/ -3 }, /* index 57: 18 bits: 01111111101011001x */ { /*-30*/ -61, /*-29*/ -60 }, /* index 58: 18 bits: 01111111101011010x */ { /*-20*/ -51, /*20*/ -11 } /* index 59: 18 bits: 01111111101011011x */ }; static const int8_t t_huff_iid_fine[][2] = { { 1, /*0*/ -31 }, /* index 0: 1 bits: x */ { /*1*/ -30, 2 }, /* index 1: 2 bits: 0x */ { 3, /*-1*/ -32 }, /* index 2: 3 bits: 01x */ { 4, 5 }, /* index 3: 4 bits: 010x */ { 6, 7 }, /* index 4: 5 bits: 0100x */ { /*-2*/ -33, /*2*/ -29 }, /* index 5: 5 bits: 0101x */ { 8, /*-3*/ -34 }, /* index 6: 6 bits: 01000x */ { /*3*/ -28, 9 }, /* index 7: 6 bits: 01001x */ { /*-4*/ -35, /*4*/ -27 }, /* index 8: 7 bits: 010000x */ { 10, 11 }, /* index 9: 7 bits: 010011x */ { /*5*/ -26, 12 }, /* index 10: 8 bits: 0100110x */ { 13, 14 }, /* index 11: 8 bits: 0100111x */ { /*-6*/ -37, /*6*/ -25 }, /* index 12: 9 bits: 01001101x */ { 15, 16 }, /* index 13: 9 bits: 01001110x */ { 17, /*-5*/ -36 }, /* index 14: 9 bits: 01001111x */ { 18, /*-7*/ -38 }, /* index 15: 10 bits: 010011100x */ { /*7*/ -24, 19 }, /* index 16: 10 bits: 010011101x */ { 20, 21 }, /* index 17: 10 bits: 010011110x */ { /*9*/ -22, 22 }, /* index 18: 11 bits: 0100111000x */ { 23, 24 }, /* index 19: 11 bits: 0100111011x */ { /*-8*/ -39, /*8*/ -23 }, /* index 20: 11 bits: 0100111100x */ { 25, 26 }, /* index 21: 11 bits: 0100111101x */ { /*11*/ -20, 27 }, /* index 22: 12 bits: 01001110001x */ { 28, 29 }, /* index 23: 12 bits: 01001110110x */ { /*-10*/ -41, /*10*/ -21 }, /* index 24: 12 bits: 01001110111x */ { 30, 31 }, /* index 25: 12 bits: 01001111010x */ { 32, /*-9*/ -40 }, /* index 26: 12 bits: 01001111011x */ { 33, /*-13*/ -44 }, /* index 27: 13 bits: 010011100011x */ { /*13*/ -18, 34 }, /* index 28: 13 bits: 010011101100x */ { 35, 36 }, /* index 29: 13 bits: 010011101101x */ { 37, /*-12*/ -43 }, /* index 30: 13 bits: 010011110100x */ { /*12*/ -19, 38 }, /* index 31: 13 bits: 010011110101x */ { 39, /*-11*/ -42 }, /* index 32: 13 bits: 010011110110x */ { 40, 41 }, /* index 33: 14 bits: 0100111000110x */ { 42, 43 }, /* index 34: 14 bits: 0100111011001x */ { 44, 45 }, /* index 35: 14 bits: 0100111011010x */ { 46, /*-15*/ -46 }, /* index 36: 14 bits: 0100111011011x */ { /*15*/ -16, 47 }, /* index 37: 14 bits: 0100111101000x */ { /*-14*/ -45, /*14*/ -17 }, /* index 38: 14 bits: 0100111101011x */ { 48, 49 }, /* index 39: 14 bits: 0100111101100x */ { /*-21*/ -52, /*-20*/ -51 }, /* index 40: 15 bits: 01001110001100x */ { /*18*/ -13, /*19*/ -12 }, /* index 41: 15 bits: 01001110001101x */ { /*-19*/ -50, /*-18*/ -49 }, /* index 42: 15 bits: 01001110110010x */ { 50, 51 }, /* index 43: 15 bits: 01001110110011x */ { 52, 53 }, /* index 44: 15 bits: 01001110110100x */ { 54, 55 }, /* index 45: 15 bits: 01001110110101x */ { 56, /*-17*/ -48 }, /* index 46: 15 bits: 01001110110110x */ { /*17*/ -14, 57 }, /* index 47: 15 bits: 01001111010001x */ { 58, /*-16*/ -47 }, /* index 48: 15 bits: 01001111011000x */ { /*16*/ -15, 59 }, /* index 49: 15 bits: 01001111011001x */ { /*-26*/ -57, /*26*/ -5 }, /* index 50: 16 bits: 010011101100110x */ { /*-28*/ -59, /*-27*/ -58 }, /* index 51: 16 bits: 010011101100111x */ { /*29*/ -2, /*30*/ -1 }, /* index 52: 16 bits: 010011101101000x */ { /*27*/ -4, /*28*/ -3 }, /* index 53: 16 bits: 010011101101001x */ { /*-30*/ -61, /*-29*/ -60 }, /* index 54: 16 bits: 010011101101010x */ { /*-25*/ -56, /*25*/ -6 }, /* index 55: 16 bits: 010011101101011x */ { /*-24*/ -55, /*24*/ -7 }, /* index 56: 16 bits: 010011101101100x */ { /*-23*/ -54, /*23*/ -8 }, /* index 57: 16 bits: 010011110100011x */ { /*-22*/ -53, /*22*/ -9 }, /* index 58: 16 bits: 010011110110000x */ { /*20*/ -11, /*21*/ -10 } /* index 59: 16 bits: 010011110110011x */ }; static const int8_t f_huff_icc[][2] = { { /*0*/ -31, 1 }, /* index 0: 1 bits: x */ { /*1*/ -30, 2 }, /* index 1: 2 bits: 1x */ { /*-1*/ -32, 3 }, /* index 2: 3 bits: 11x */ { /*2*/ -29, 4 }, /* index 3: 4 bits: 111x */ { /*-2*/ -33, 5 }, /* index 4: 5 bits: 1111x */ { /*3*/ -28, 6 }, /* index 5: 6 bits: 11111x */ { /*-3*/ -34, 7 }, /* index 6: 7 bits: 111111x */ { /*4*/ -27, 8 }, /* index 7: 8 bits: 1111111x */ { /*5*/ -26, 9 }, /* index 8: 9 bits: 11111111x */ { /*-4*/ -35, 10 }, /* index 9: 10 bits: 111111111x */ { /*6*/ -25, 11 }, /* index 10: 11 bits: 1111111111x */ { /*-5*/ -36, 12 }, /* index 11: 12 bits: 11111111111x */ { /*7*/ -24, 13 }, /* index 12: 13 bits: 111111111111x */ { /*-6*/ -37, /*-7*/ -38 } /* index 13: 14 bits: 1111111111111x */ }; static const int8_t t_huff_icc[][2] = { { /*0*/ -31, 1 }, /* index 0: 1 bits: x */ { /*1*/ -30, 2 }, /* index 1: 2 bits: 1x */ { /*-1*/ -32, 3 }, /* index 2: 3 bits: 11x */ { /*2*/ -29, 4 }, /* index 3: 4 bits: 111x */ { /*-2*/ -33, 5 }, /* index 4: 5 bits: 1111x */ { /*3*/ -28, 6 }, /* index 5: 6 bits: 11111x */ { /*-3*/ -34, 7 }, /* index 6: 7 bits: 111111x */ { /*4*/ -27, 8 }, /* index 7: 8 bits: 1111111x */ { /*-4*/ -35, 9 }, /* index 8: 9 bits: 11111111x */ { /*5*/ -26, 10 }, /* index 9: 10 bits: 111111111x */ { /*-5*/ -36, 11 }, /* index 10: 11 bits: 1111111111x */ { /*6*/ -25, 12 }, /* index 11: 12 bits: 11111111111x */ { /*-6*/ -37, 13 }, /* index 12: 13 bits: 111111111111x */ { /*-7*/ -38, /*7*/ -24 } /* index 13: 14 bits: 1111111111111x */ }; static const int8_t f_huff_ipd[][2] = { { 1, /*0*/ -31 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 0x */ { /*1*/ -30, 4 }, /* index 2: 3 bits: 00x */ { 5, 6 }, /* index 3: 3 bits: 01x */ { /*4*/ -27, /*5*/ -26 }, /* index 4: 4 bits: 001x */ { /*3*/ -28, /*6*/ -25 }, /* index 5: 4 bits: 010x */ { /*2*/ -29, /*7*/ -24 } /* index 6: 4 bits: 011x */ }; static const int8_t t_huff_ipd[][2] = { { 1, /*0*/ -31 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 0x */ { 4, 5 }, /* index 2: 3 bits: 00x */ { /*1*/ -30, /*7*/ -24 }, /* index 3: 3 bits: 01x */ { /*5*/ -26, 6 }, /* index 4: 4 bits: 000x */ { /*2*/ -29, /*6*/ -25 }, /* index 5: 4 bits: 001x */ { /*4*/ -27, /*3*/ -28 } /* index 6: 5 bits: 0001x */ }; static const int8_t f_huff_opd[][2] = { { 1, /*0*/ -31 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 0x */ { /*7*/ -24, /*1*/ -30 }, /* index 2: 3 bits: 00x */ { 4, 5 }, /* index 3: 3 bits: 01x */ { /*3*/ -28, /*6*/ -25 }, /* index 4: 4 bits: 010x */ { /*2*/ -29, 6 }, /* index 5: 4 bits: 011x */ { /*5*/ -26, /*4*/ -27 } /* index 6: 5 bits: 0111x */ }; static const int8_t t_huff_opd[][2] = { { 1, /*0*/ -31 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 0x */ { 4, 5 }, /* index 2: 3 bits: 00x */ { /*1*/ -30, /*7*/ -24 }, /* index 3: 3 bits: 01x */ { /*5*/ -26, /*2*/ -29 }, /* index 4: 4 bits: 000x */ { /*6*/ -25, 6 }, /* index 5: 4 bits: 001x */ { /*4*/ -27, /*3*/ -28 } /* index 6: 5 bits: 0011x */ }; /* static function declarations */ static uint16_t ps_extension(ps_info *ps, bitfile *ld, const uint8_t ps_extension_id, const uint16_t num_bits_left); static void huff_data(bitfile *ld, const uint8_t dt, const uint8_t nr_par, ps_huff_tab t_huff, ps_huff_tab f_huff, int8_t *par); static INLINE int8_t ps_huff_dec(bitfile *ld, ps_huff_tab t_huff); uint16_t ps_data(ps_info *ps, bitfile *ld, uint8_t *header) { uint8_t tmp, n; uint16_t bits = (uint16_t)faad_get_processed_bits(ld); *header = 0; /* check for new PS header */ if (faad_get1bit(ld DEBUGVAR(1,1000,"ps_data(): enable_ps_header"))) { *header = 1; ps->header_read = 1; ps->use34hybrid_bands = 0; /* Inter-channel Intensity Difference (IID) parameters enabled */ ps->enable_iid = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1001,"ps_data(): enable_iid")); if (ps->enable_iid) { ps->iid_mode = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,1002,"ps_data(): iid_mode")); ps->nr_iid_par = nr_iid_par_tab[ps->iid_mode]; ps->nr_ipdopd_par = nr_ipdopd_par_tab[ps->iid_mode]; if (ps->iid_mode == 2 || ps->iid_mode == 5) ps->use34hybrid_bands = 1; /* IPD freq res equal to IID freq res */ ps->ipd_mode = ps->iid_mode; } /* Inter-channel Coherence (ICC) parameters enabled */ ps->enable_icc = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1003,"ps_data(): enable_icc")); if (ps->enable_icc) { ps->icc_mode = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,1004,"ps_data(): icc_mode")); ps->nr_icc_par = nr_icc_par_tab[ps->icc_mode]; if (ps->icc_mode == 2 || ps->icc_mode == 5) ps->use34hybrid_bands = 1; } /* PS extension layer enabled */ ps->enable_ext = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1005,"ps_data(): enable_ext")); } /* we are here, but no header has been read yet */ if (ps->header_read == 0) { ps->ps_data_available = 0; return 1; } ps->frame_class = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1006,"ps_data(): frame_class")); tmp = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,1007,"ps_data(): num_env_idx")); ps->num_env = num_env_tab[ps->frame_class][tmp]; if (ps->frame_class) { for (n = 1; n < ps->num_env+1; n++) { ps->border_position[n] = (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,1008,"ps_data(): border_position")) + 1; } } if (ps->enable_iid) { for (n = 0; n < ps->num_env; n++) { ps->iid_dt[n] = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1009,"ps_data(): iid_dt")); /* iid_data */ if (ps->iid_mode < 3) { huff_data(ld, ps->iid_dt[n], ps->nr_iid_par, t_huff_iid_def, f_huff_iid_def, ps->iid_index[n]); } else { huff_data(ld, ps->iid_dt[n], ps->nr_iid_par, t_huff_iid_fine, f_huff_iid_fine, ps->iid_index[n]); } } } if (ps->enable_icc) { for (n = 0; n < ps->num_env; n++) { ps->icc_dt[n] = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1010,"ps_data(): icc_dt")); /* icc_data */ huff_data(ld, ps->icc_dt[n], ps->nr_icc_par, t_huff_icc, f_huff_icc, ps->icc_index[n]); } } if (ps->enable_ext) { uint16_t num_bits_left; uint16_t cnt = (uint16_t)faad_getbits(ld, 4 DEBUGVAR(1,1011,"ps_data(): ps_extension_size")); if (cnt == 15) { cnt += (uint16_t)faad_getbits(ld, 8 DEBUGVAR(1,1012,"ps_data(): esc_count")); } num_bits_left = 8 * cnt; while (num_bits_left > 7) { uint8_t ps_extension_id = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,1013,"ps_data(): ps_extension_size")); num_bits_left -= 2; num_bits_left -= ps_extension(ps, ld, ps_extension_id, num_bits_left); } faad_getbits(ld, num_bits_left DEBUGVAR(1,1014,"ps_data(): fill_bits")); } bits = (uint16_t)faad_get_processed_bits(ld) - bits; ps->ps_data_available = 1; return bits; } static uint16_t ps_extension(ps_info *ps, bitfile *ld, const uint8_t ps_extension_id, const uint16_t num_bits_left) { uint8_t n; uint16_t bits = (uint16_t)faad_get_processed_bits(ld); /* FIXME: test */ (void)num_bits_left; if (ps_extension_id == 0) { ps->enable_ipdopd = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1015,"ps_extension(): enable_ipdopd")); if (ps->enable_ipdopd) { for (n = 0; n < ps->num_env; n++) { ps->ipd_dt[n] = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1016,"ps_extension(): ipd_dt")); /* ipd_data */ huff_data(ld, ps->ipd_dt[n], ps->nr_ipdopd_par, t_huff_ipd, f_huff_ipd, ps->ipd_index[n]); ps->opd_dt[n] = (uint8_t)faad_get1bit(ld DEBUGVAR(1,1017,"ps_extension(): opd_dt")); /* opd_data */ huff_data(ld, ps->opd_dt[n], ps->nr_ipdopd_par, t_huff_opd, f_huff_opd, ps->opd_index[n]); } } faad_get1bit(ld DEBUGVAR(1,1018,"ps_extension(): reserved_ps")); } /* return number of bits read */ bits = (uint16_t)faad_get_processed_bits(ld) - bits; return bits; } /* read huffman data coded in either the frequency or the time direction */ static void huff_data(bitfile *ld, const uint8_t dt, const uint8_t nr_par, ps_huff_tab t_huff, ps_huff_tab f_huff, int8_t *par) { uint8_t n; if (dt) { /* coded in time direction */ for (n = 0; n < nr_par; n++) { par[n] = ps_huff_dec(ld, t_huff); } } else { /* coded in frequency direction */ par[0] = ps_huff_dec(ld, f_huff); for (n = 1; n < nr_par; n++) { par[n] = ps_huff_dec(ld, f_huff); } } } /* binary search huffman decoding */ static INLINE int8_t ps_huff_dec(bitfile *ld, ps_huff_tab t_huff) { uint8_t bit; int16_t index = 0; while (index >= 0) { bit = (uint8_t)faad_get1bit(ld); index = t_huff[index][bit]; } return index + 31; } #endif xine-lib-1.2/contrib/libfaad/fixed.h0000644000175000017500000001777714647725152015201 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: fixed.h,v 1.32 2007/11/01 12:33:30 menno Exp $ **/ #ifndef __FIXED_H__ #define __FIXED_H__ #ifdef __cplusplus extern "C" { #endif #if defined(_WIN32_WCE) && defined(_ARM_) #include #endif #define COEF_BITS 28 #define COEF_PRECISION (1 << COEF_BITS) #define REAL_BITS 14 // MAXIMUM OF 14 FOR FIXED POINT SBR #define REAL_PRECISION (1 << REAL_BITS) /* FRAC is the fractional only part of the fixed point number [0.0..1.0) */ #define FRAC_SIZE 32 /* frac is a 32 bit integer */ #define FRAC_BITS 31 #define FRAC_PRECISION ((uint32_t)(1 << FRAC_BITS)) #define FRAC_MAX 0x7FFFFFFF typedef int32_t real_t; #define REAL_CONST(A) (((A) >= 0) ? ((real_t)((A)*(REAL_PRECISION)+0.5)) : ((real_t)((A)*(REAL_PRECISION)-0.5))) #define COEF_CONST(A) (((A) >= 0) ? ((real_t)((A)*(COEF_PRECISION)+0.5)) : ((real_t)((A)*(COEF_PRECISION)-0.5))) #define FRAC_CONST(A) (((A) == 1.00) ? ((real_t)FRAC_MAX) : (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5)))) //#define FRAC_CONST(A) (((A) >= 0) ? ((real_t)((A)*(FRAC_PRECISION)+0.5)) : ((real_t)((A)*(FRAC_PRECISION)-0.5))) #define Q2_BITS 22 #define Q2_PRECISION (1 << Q2_BITS) #define Q2_CONST(A) (((A) >= 0) ? ((real_t)((A)*(Q2_PRECISION)+0.5)) : ((real_t)((A)*(Q2_PRECISION)-0.5))) #if defined(_WIN32) && !defined(_WIN32_WCE) /* multiply with real shift */ static INLINE real_t MUL_R(real_t A, real_t B) { _asm { mov eax,A imul B shrd eax,edx,REAL_BITS } } /* multiply with coef shift */ static INLINE real_t MUL_C(real_t A, real_t B) { _asm { mov eax,A imul B shrd eax,edx,COEF_BITS } } static INLINE real_t MUL_Q2(real_t A, real_t B) { _asm { mov eax,A imul B shrd eax,edx,Q2_BITS } } static INLINE real_t MUL_SHIFT6(real_t A, real_t B) { _asm { mov eax,A imul B shrd eax,edx,6 } } static INLINE real_t MUL_SHIFT23(real_t A, real_t B) { _asm { mov eax,A imul B shrd eax,edx,23 } } #if 1 static INLINE real_t _MulHigh(real_t A, real_t B) { _asm { mov eax,A imul B mov eax,edx } } /* multiply with fractional shift */ static INLINE real_t MUL_F(real_t A, real_t B) { return _MulHigh(A,B) << (FRAC_SIZE-FRAC_BITS); } /* Complex multiplication */ static INLINE void ComplexMult(real_t *y1, real_t *y2, real_t x1, real_t x2, real_t c1, real_t c2) { *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS); *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS); } #else static INLINE real_t MUL_F(real_t A, real_t B) { _asm { mov eax,A imul B shrd eax,edx,FRAC_BITS } } /* Complex multiplication */ static INLINE void ComplexMult(real_t *y1, real_t *y2, real_t x1, real_t x2, real_t c1, real_t c2) { *y1 = MUL_F(x1, c1) + MUL_F(x2, c2); *y2 = MUL_F(x2, c1) - MUL_F(x1, c2); } #endif #elif defined(__GNUC__) && defined (__arm__) /* taken from MAD */ #define arm_mul(x, y, SCALEBITS) \ ({ \ uint32_t __hi; \ uint32_t __lo; \ uint32_t __result; \ asm("smull %0, %1, %3, %4\n\t" \ "movs %0, %0, lsr %5\n\t" \ "adc %2, %0, %1, lsl %6" \ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ : "%r" (x), "r" (y), \ "M" (SCALEBITS), "M" (32 - (SCALEBITS)) \ : "cc"); \ __result; \ }) static INLINE real_t MUL_R(real_t A, real_t B) { return arm_mul(A, B, REAL_BITS); } static INLINE real_t MUL_C(real_t A, real_t B) { return arm_mul(A, B, COEF_BITS); } static INLINE real_t MUL_Q2(real_t A, real_t B) { return arm_mul(A, B, Q2_BITS); } static INLINE real_t MUL_SHIFT6(real_t A, real_t B) { return arm_mul(A, B, 6); } static INLINE real_t MUL_SHIFT23(real_t A, real_t B) { return arm_mul(A, B, 23); } static INLINE real_t _MulHigh(real_t x, real_t y) { uint32_t __lo; uint32_t __hi; asm("smull\t%0, %1, %2, %3" : "=&r"(__lo),"=&r"(__hi) : "%r"(x),"r"(y) : "cc"); return __hi; } static INLINE real_t MUL_F(real_t A, real_t B) { return _MulHigh(A, B) << (FRAC_SIZE-FRAC_BITS); } /* Complex multiplication */ static INLINE void ComplexMult(real_t *y1, real_t *y2, real_t x1, real_t x2, real_t c1, real_t c2) { int32_t tmp, yt1, yt2; asm("smull %0, %1, %4, %6\n\t" "smlal %0, %1, %5, %7\n\t" "rsb %3, %4, #0\n\t" "smull %0, %2, %5, %6\n\t" "smlal %0, %2, %3, %7" : "=&r" (tmp), "=&r" (yt1), "=&r" (yt2), "=r" (x1) : "3" (x1), "r" (x2), "r" (c1), "r" (c2) : "cc" ); *y1 = yt1 << (FRAC_SIZE-FRAC_BITS); *y2 = yt2 << (FRAC_SIZE-FRAC_BITS); } #else /* multiply with real shift */ #define MUL_R(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (REAL_BITS-1))) >> REAL_BITS) /* multiply with coef shift */ #define MUL_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS) /* multiply with fractional shift */ #if defined(_WIN32_WCE) && defined(_ARM_) /* eVC for PocketPC has an intrinsic function that returns only the high 32 bits of a 32x32 bit multiply */ static INLINE real_t MUL_F(real_t A, real_t B) { return _MulHigh(A,B) << (32-FRAC_BITS); } #else #ifdef __BFIN__ #define _MulHigh(X,Y) ({ int __xxo; \ asm ( \ "a1 = %2.H * %1.L (IS,M);\n\t" \ "a0 = %1.H * %2.H, a1+= %1.H * %2.L (IS,M);\n\t"\ "a1 = a1 >>> 16;\n\t" \ "%0 = (a0 += a1);\n\t" \ : "=d" (__xxo) : "d" (X), "d" (Y) : "A0","A1"); __xxo; }) #define MUL_F(X,Y) ({ int __xxo; \ asm ( \ "a1 = %2.H * %1.L (M);\n\t" \ "a0 = %1.H * %2.H, a1+= %1.H * %2.L (M);\n\t" \ "a1 = a1 >>> 16;\n\t" \ "%0 = (a0 += a1);\n\t" \ : "=d" (__xxo) : "d" (X), "d" (Y) : "A0","A1"); __xxo; }) #else #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE) #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS) #endif #endif #define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS) #define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6) #define MUL_SHIFT23(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (23-1))) >> 23) /* Complex multiplication */ static INLINE void ComplexMult(real_t *y1, real_t *y2, real_t x1, real_t x2, real_t c1, real_t c2) { *y1 = (_MulHigh(x1, c1) + _MulHigh(x2, c2))<<(FRAC_SIZE-FRAC_BITS); *y2 = (_MulHigh(x2, c1) - _MulHigh(x1, c2))<<(FRAC_SIZE-FRAC_BITS); } #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ssr.h0000644000175000017500000000420114647725152014663 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ssr.h,v 1.19 2007/11/01 12:33:36 menno Exp $ **/ #ifndef __SSR_H__ #define __SSR_H__ #ifdef __cplusplus extern "C" { #endif #define SSR_BANDS 4 #define PQFTAPS 96 void ssr_decode(ssr_info *ssr, fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *freq_in, real_t *time_out, real_t *overlap, real_t ipqf_buffer[SSR_BANDS][96/4], real_t *prev_fmd, uint16_t frame_len); static void ssr_gain_control(ssr_info *ssr, real_t *data, real_t *output, real_t *overlap, real_t *prev_fmd, uint8_t band, uint8_t window_sequence, uint16_t frame_len); static void ssr_gc_function(ssr_info *ssr, real_t *prev_fmd, real_t *gc_function, uint8_t window_sequence, uint16_t frame_len); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_qmf.h0000644000175000017500000000355714647725152015522 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_qmf.h,v 1.25 2007/11/01 12:33:36 menno Exp $ **/ #ifndef __SBR_QMF_H__ #define __SBR_QMF_H__ #ifdef __cplusplus extern "C" { #endif qmfa_info *qmfa_init(uint8_t channels); void qmfa_end(qmfa_info *qmfa); qmfs_info *qmfs_init(uint8_t channels); void qmfs_end(qmfs_info *qmfs); void sbr_qmf_analysis_32 (sbr_info *sbr, qmfa_info *qmfa, const real_t *input, qmf_t X[][64], uint8_t offset, uint8_t kx); void sbr_qmf_synthesis_32 (sbr_info *sbr, qmfs_info *qmfs, qmf_t X[][64], real_t *output); void sbr_qmf_synthesis_64 (sbr_info *sbr, qmfs_info *qmfs, qmf_t X[][64], real_t *output); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_hfgen.c0000644000175000017500000005270614647725152016021 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_hfgen.c,v 1.26 2007/11/01 12:33:35 menno Exp $ **/ /* High Frequency generation */ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include "sbr_syntax.h" #include "sbr_hfgen.h" #include "sbr_fbt.h" /* static function declarations */ #ifdef SBR_LOW_POWER static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], complex_t *alpha_0, complex_t *alpha_1, real_t *rxx); static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg); #else static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], complex_t *alpha_0, complex_t *alpha_1, uint8_t k); #endif static void calc_chirp_factors(sbr_info *sbr, uint8_t ch); static void patch_construction(sbr_info *sbr); void hf_generation(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], qmf_t Xhigh[MAX_NTSRHFG][64] #ifdef SBR_LOW_POWER ,real_t *deg #endif ,uint8_t ch) { uint8_t l, i, x; ALIGN complex_t alpha_0[64], alpha_1[64]; #ifdef SBR_LOW_POWER ALIGN real_t rxx[64]; #endif uint8_t offset = sbr->tHFAdj; uint8_t first = sbr->t_E[ch][0]; uint8_t last = sbr->t_E[ch][sbr->L_E[ch]]; calc_chirp_factors(sbr, ch); #ifdef SBR_LOW_POWER memset(deg, 0, 64*sizeof(real_t)); #endif if ((ch == 0) && (sbr->Reset)) patch_construction(sbr); /* calculate the prediction coefficients */ #ifdef SBR_LOW_POWER calc_prediction_coef_lp(sbr, Xlow, alpha_0, alpha_1, rxx); calc_aliasing_degree(sbr, rxx, deg); #endif /* actual HF generation */ for (i = 0; i < sbr->noPatches; i++) { for (x = 0; x < sbr->patchNoSubbands[i]; x++) { real_t a0_r, a0_i, a1_r, a1_i; real_t bw, bw2; uint8_t q, p, k, g; /* find the low and high band for patching */ k = sbr->kx + x; for (q = 0; q < i; q++) { k += sbr->patchNoSubbands[q]; } p = sbr->patchStartSubband[i] + x; #ifdef SBR_LOW_POWER if (x != 0 /*x < sbr->patchNoSubbands[i]-1*/) deg[k] = deg[p]; else deg[k] = 0; #endif g = sbr->table_map_k_to_g[k]; bw = sbr->bwArray[ch][g]; bw2 = MUL_C(bw, bw); /* do the patching */ /* with or without filtering */ if (bw2 > 0) { real_t temp1_r, temp2_r, temp3_r; #ifndef SBR_LOW_POWER real_t temp1_i, temp2_i, temp3_i; calc_prediction_coef(sbr, Xlow, alpha_0, alpha_1, p); #endif a0_r = MUL_C(RE(alpha_0[p]), bw); a1_r = MUL_C(RE(alpha_1[p]), bw2); #ifndef SBR_LOW_POWER a0_i = MUL_C(IM(alpha_0[p]), bw); a1_i = MUL_C(IM(alpha_1[p]), bw2); #endif temp2_r = QMF_RE(Xlow[first - 2 + offset][p]); temp3_r = QMF_RE(Xlow[first - 1 + offset][p]); #ifndef SBR_LOW_POWER temp2_i = QMF_IM(Xlow[first - 2 + offset][p]); temp3_i = QMF_IM(Xlow[first - 1 + offset][p]); #endif for (l = first; l < last; l++) { temp1_r = temp2_r; temp2_r = temp3_r; temp3_r = QMF_RE(Xlow[l + offset][p]); #ifndef SBR_LOW_POWER temp1_i = temp2_i; temp2_i = temp3_i; temp3_i = QMF_IM(Xlow[l + offset][p]); #endif #ifdef SBR_LOW_POWER QMF_RE(Xhigh[l + offset][k]) = temp3_r +(MUL_R(a0_r, temp2_r) + MUL_R(a1_r, temp1_r)); #else QMF_RE(Xhigh[l + offset][k]) = temp3_r +(MUL_R(a0_r, temp2_r) - MUL_R(a0_i, temp2_i) + MUL_R(a1_r, temp1_r) - MUL_R(a1_i, temp1_i)); QMF_IM(Xhigh[l + offset][k]) = temp3_i +(MUL_R(a0_i, temp2_r) + MUL_R(a0_r, temp2_i) + MUL_R(a1_i, temp1_r) + MUL_R(a1_r, temp1_i)); #endif } } else { for (l = first; l < last; l++) { QMF_RE(Xhigh[l + offset][k]) = QMF_RE(Xlow[l + offset][p]); #ifndef SBR_LOW_POWER QMF_IM(Xhigh[l + offset][k]) = QMF_IM(Xlow[l + offset][p]); #endif } } } } if (sbr->Reset) { limiter_frequency_table(sbr); } } typedef struct { complex_t r01; complex_t r02; complex_t r11; complex_t r12; complex_t r22; real_t det; } acorr_coef; #ifdef SBR_LOW_POWER static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], uint8_t bd, uint8_t len) { real_t r01 = 0, r02 = 0, r11 = 0; int8_t j; uint8_t offset = sbr->tHFAdj; #ifdef FIXED_POINT const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); uint32_t maxi = 0; uint32_t pow2, exp; #else const real_t rel = 1 / (1 + 1e-6f); #endif #ifdef FIXED_POINT mask = 0; for (j = (offset-2); j < (len + offset); j++) { real_t x; x = QMF_RE(buffer[j][bd])>>REAL_BITS; mask |= x ^ (x >> 31); } exp = wl_min_lzc(mask); /* improves accuracy */ if (exp > 0) exp -= 1; for (j = offset; j < len + offset; j++) { real_t buf_j = ((QMF_RE(buffer[j][bd])+(1<<(exp-1)))>>exp); real_t buf_j_1 = ((QMF_RE(buffer[j-1][bd])+(1<<(exp-1)))>>exp); real_t buf_j_2 = ((QMF_RE(buffer[j-2][bd])+(1<<(exp-1)))>>exp); /* normalisation with rounding */ r01 += MUL_R(buf_j, buf_j_1); r02 += MUL_R(buf_j, buf_j_2); r11 += MUL_R(buf_j_1, buf_j_1); } RE(ac->r12) = r01 - MUL_R(((QMF_RE(buffer[len+offset-1][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp)) + MUL_R(((QMF_RE(buffer[offset-1][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp)); RE(ac->r22) = r11 - MUL_R(((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[len+offset-2][bd])+(1<<(exp-1)))>>exp)) + MUL_R(((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[offset-2][bd])+(1<<(exp-1)))>>exp)); #else for (j = offset; j < len + offset; j++) { r01 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-1][bd]); r02 += QMF_RE(buffer[j][bd]) * QMF_RE(buffer[j-2][bd]); r11 += QMF_RE(buffer[j-1][bd]) * QMF_RE(buffer[j-1][bd]); } RE(ac->r12) = r01 - QMF_RE(buffer[len+offset-1][bd]) * QMF_RE(buffer[len+offset-2][bd]) + QMF_RE(buffer[offset-1][bd]) * QMF_RE(buffer[offset-2][bd]); RE(ac->r22) = r11 - QMF_RE(buffer[len+offset-2][bd]) * QMF_RE(buffer[len+offset-2][bd]) + QMF_RE(buffer[offset-2][bd]) * QMF_RE(buffer[offset-2][bd]); #endif RE(ac->r01) = r01; RE(ac->r02) = r02; RE(ac->r11) = r11; ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(MUL_R(RE(ac->r12), RE(ac->r12)), rel); } #else static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t buffer[MAX_NTSRHFG][64], uint8_t bd, uint8_t len) { real_t r01r = 0, r01i = 0, r02r = 0, r02i = 0, r11r = 0; real_t temp1_r, temp1_i, temp2_r, temp2_i, temp3_r, temp3_i, temp4_r, temp4_i, temp5_r, temp5_i; #ifdef FIXED_POINT const real_t rel = FRAC_CONST(0.999999); // 1 / (1 + 1e-6f); uint32_t mask, exp; real_t pow2_to_exp; #else const real_t rel = 1 / (1 + 1e-6f); #endif int8_t j; uint8_t offset = sbr->tHFAdj; #ifdef FIXED_POINT mask = 0; for (j = (offset-2); j < (len + offset); j++) { real_t x; x = QMF_RE(buffer[j][bd])>>REAL_BITS; mask |= x ^ (x >> 31); x = QMF_IM(buffer[j][bd])>>REAL_BITS; mask |= x ^ (x >> 31); } exp = wl_min_lzc(mask); /* improves accuracy */ if (exp > 0) exp -= 1; pow2_to_exp = 1<<(exp-1); temp2_r = (QMF_RE(buffer[offset-2][bd]) + pow2_to_exp) >> exp; temp2_i = (QMF_IM(buffer[offset-2][bd]) + pow2_to_exp) >> exp; temp3_r = (QMF_RE(buffer[offset-1][bd]) + pow2_to_exp) >> exp; temp3_i = (QMF_IM(buffer[offset-1][bd]) + pow2_to_exp) >> exp; // Save these because they are needed after loop temp4_r = temp2_r; temp4_i = temp2_i; temp5_r = temp3_r; temp5_i = temp3_i; for (j = offset; j < len + offset; j++) { temp1_r = temp2_r; // temp1_r = (QMF_RE(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; temp1_i = temp2_i; // temp1_i = (QMF_IM(buffer[offset-2][bd] + (1<<(exp-1))) >> exp; temp2_r = temp3_r; // temp2_r = (QMF_RE(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; temp2_i = temp3_i; // temp2_i = (QMF_IM(buffer[offset-1][bd] + (1<<(exp-1))) >> exp; temp3_r = (QMF_RE(buffer[j][bd]) + pow2_to_exp) >> exp; temp3_i = (QMF_IM(buffer[j][bd]) + pow2_to_exp) >> exp; r01r += MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i); r01i += MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i); r02r += MUL_R(temp3_r, temp1_r) + MUL_R(temp3_i, temp1_i); r02i += MUL_R(temp3_i, temp1_r) - MUL_R(temp3_r, temp1_i); r11r += MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i); } // These are actual values in temporary variable at this point // temp1_r = (QMF_RE(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; // temp1_i = (QMF_IM(buffer[len+offset-1-2][bd] + (1<<(exp-1))) >> exp; // temp2_r = (QMF_RE(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; // temp2_i = (QMF_IM(buffer[len+offset-1-1][bd] + (1<<(exp-1))) >> exp; // temp3_r = (QMF_RE(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; // temp3_i = (QMF_IM(buffer[len+offset-1][bd]) + (1<<(exp-1))) >> exp; // temp4_r = (QMF_RE(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; // temp4_i = (QMF_IM(buffer[offset-2][bd]) + (1<<(exp-1))) >> exp; // temp5_r = (QMF_RE(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; // temp5_i = (QMF_IM(buffer[offset-1][bd]) + (1<<(exp-1))) >> exp; RE(ac->r12) = r01r - (MUL_R(temp3_r, temp2_r) + MUL_R(temp3_i, temp2_i)) + (MUL_R(temp5_r, temp4_r) + MUL_R(temp5_i, temp4_i)); IM(ac->r12) = r01i - (MUL_R(temp3_i, temp2_r) - MUL_R(temp3_r, temp2_i)) + (MUL_R(temp5_i, temp4_r) - MUL_R(temp5_r, temp4_i)); RE(ac->r22) = r11r - (MUL_R(temp2_r, temp2_r) + MUL_R(temp2_i, temp2_i)) + (MUL_R(temp4_r, temp4_r) + MUL_R(temp4_i, temp4_i)); #else temp2_r = QMF_RE(buffer[offset-2][bd]); temp2_i = QMF_IM(buffer[offset-2][bd]); temp3_r = QMF_RE(buffer[offset-1][bd]); temp3_i = QMF_IM(buffer[offset-1][bd]); // Save these because they are needed after loop temp4_r = temp2_r; temp4_i = temp2_i; temp5_r = temp3_r; temp5_i = temp3_i; for (j = offset; j < len + offset; j++) { temp1_r = temp2_r; // temp1_r = QMF_RE(buffer[j-2][bd]; temp1_i = temp2_i; // temp1_i = QMF_IM(buffer[j-2][bd]; temp2_r = temp3_r; // temp2_r = QMF_RE(buffer[j-1][bd]; temp2_i = temp3_i; // temp2_i = QMF_IM(buffer[j-1][bd]; temp3_r = QMF_RE(buffer[j][bd]); temp3_i = QMF_IM(buffer[j][bd]); r01r += temp3_r * temp2_r + temp3_i * temp2_i; r01i += temp3_i * temp2_r - temp3_r * temp2_i; r02r += temp3_r * temp1_r + temp3_i * temp1_i; r02i += temp3_i * temp1_r - temp3_r * temp1_i; r11r += temp2_r * temp2_r + temp2_i * temp2_i; } // These are actual values in temporary variable at this point // temp1_r = QMF_RE(buffer[len+offset-1-2][bd]; // temp1_i = QMF_IM(buffer[len+offset-1-2][bd]; // temp2_r = QMF_RE(buffer[len+offset-1-1][bd]; // temp2_i = QMF_IM(buffer[len+offset-1-1][bd]; // temp3_r = QMF_RE(buffer[len+offset-1][bd]); // temp3_i = QMF_IM(buffer[len+offset-1][bd]); // temp4_r = QMF_RE(buffer[offset-2][bd]); // temp4_i = QMF_IM(buffer[offset-2][bd]); // temp5_r = QMF_RE(buffer[offset-1][bd]); // temp5_i = QMF_IM(buffer[offset-1][bd]); RE(ac->r12) = r01r - (temp3_r * temp2_r + temp3_i * temp2_i) + (temp5_r * temp4_r + temp5_i * temp4_i); IM(ac->r12) = r01i - (temp3_i * temp2_r - temp3_r * temp2_i) + (temp5_i * temp4_r - temp5_r * temp4_i); RE(ac->r22) = r11r - (temp2_r * temp2_r + temp2_i * temp2_i) + (temp4_r * temp4_r + temp4_i * temp4_i); #endif RE(ac->r01) = r01r; IM(ac->r01) = r01i; RE(ac->r02) = r02r; IM(ac->r02) = r02i; RE(ac->r11) = r11r; ac->det = MUL_R(RE(ac->r11), RE(ac->r22)) - MUL_F(rel, (MUL_R(RE(ac->r12), RE(ac->r12)) + MUL_R(IM(ac->r12), IM(ac->r12)))); } #endif /* calculate linear prediction coefficients using the covariance method */ #ifndef SBR_LOW_POWER static void calc_prediction_coef(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], complex_t *alpha_0, complex_t *alpha_1, uint8_t k) { real_t tmp; acorr_coef ac; auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); if (ac.det == 0) { RE(alpha_1[k]) = 0; IM(alpha_1[k]) = 0; } else { #ifdef FIXED_POINT tmp = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))); RE(alpha_1[k]) = DIV_R(tmp, ac.det); tmp = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))); IM(alpha_1[k]) = DIV_R(tmp, ac.det); #else tmp = REAL_CONST(1.0) / ac.det; RE(alpha_1[k]) = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))) * tmp; IM(alpha_1[k]) = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11))) * tmp; #endif } if (RE(ac.r11) == 0) { RE(alpha_0[k]) = 0; IM(alpha_0[k]) = 0; } else { #ifdef FIXED_POINT tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))); RE(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))); IM(alpha_0[k]) = DIV_R(tmp, RE(ac.r11)); #else tmp = 1.0f / RE(ac.r11); RE(alpha_0[k]) = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))) * tmp; IM(alpha_0[k]) = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12))) * tmp; #endif } if ((MUL_R(RE(alpha_0[k]),RE(alpha_0[k])) + MUL_R(IM(alpha_0[k]),IM(alpha_0[k])) >= REAL_CONST(16)) || (MUL_R(RE(alpha_1[k]),RE(alpha_1[k])) + MUL_R(IM(alpha_1[k]),IM(alpha_1[k])) >= REAL_CONST(16))) { RE(alpha_0[k]) = 0; IM(alpha_0[k]) = 0; RE(alpha_1[k]) = 0; IM(alpha_1[k]) = 0; } } #else static void calc_prediction_coef_lp(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], complex_t *alpha_0, complex_t *alpha_1, real_t *rxx) { uint8_t k; real_t tmp; acorr_coef ac; for (k = 1; k < sbr->f_master[0]; k++) { auto_correlation(sbr, &ac, Xlow, k, sbr->numTimeSlotsRate + 6); if (ac.det == 0) { RE(alpha_0[k]) = 0; RE(alpha_1[k]) = 0; } else { tmp = MUL_R(RE(ac.r01), RE(ac.r22)) - MUL_R(RE(ac.r12), RE(ac.r02)); RE(alpha_0[k]) = DIV_R(tmp, (-ac.det)); tmp = MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11)); RE(alpha_1[k]) = DIV_R(tmp, ac.det); } if ((RE(alpha_0[k]) >= REAL_CONST(4)) || (RE(alpha_1[k]) >= REAL_CONST(4))) { RE(alpha_0[k]) = REAL_CONST(0); RE(alpha_1[k]) = REAL_CONST(0); } /* reflection coefficient */ if (RE(ac.r11) == 0) { rxx[k] = COEF_CONST(0.0); } else { rxx[k] = DIV_C(RE(ac.r01), RE(ac.r11)); rxx[k] = -rxx[k]; if (rxx[k] > COEF_CONST(1.0)) rxx[k] = COEF_CONST(1.0); if (rxx[k] < COEF_CONST(-1.0)) rxx[k] = COEF_CONST(-1.0); } } } static void calc_aliasing_degree(sbr_info *sbr, real_t *rxx, real_t *deg) { uint8_t k; rxx[0] = COEF_CONST(0.0); deg[1] = COEF_CONST(0.0); for (k = 2; k < sbr->k0; k++) { deg[k] = 0.0; if ((k % 2 == 0) && (rxx[k] < COEF_CONST(0.0))) { if (rxx[k-1] < 0.0) { deg[k] = COEF_CONST(1.0); if (rxx[k-2] > COEF_CONST(0.0)) { deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } else if (rxx[k-2] > COEF_CONST(0.0)) { deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } if ((k % 2 == 1) && (rxx[k] > COEF_CONST(0.0))) { if (rxx[k-1] > COEF_CONST(0.0)) { deg[k] = COEF_CONST(1.0); if (rxx[k-2] < COEF_CONST(0.0)) { deg[k-1] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } else if (rxx[k-2] < COEF_CONST(0.0)) { deg[k] = COEF_CONST(1.0) - MUL_C(rxx[k-1], rxx[k-1]); } } } } #endif /* FIXED POINT: bwArray = COEF */ static real_t mapNewBw(uint8_t invf_mode, uint8_t invf_mode_prev) { switch (invf_mode) { case 1: /* LOW */ if (invf_mode_prev == 0) /* NONE */ return COEF_CONST(0.6); else return COEF_CONST(0.75); case 2: /* MID */ return COEF_CONST(0.9); case 3: /* HIGH */ return COEF_CONST(0.98); default: /* NONE */ if (invf_mode_prev == 1) /* LOW */ return COEF_CONST(0.6); else return COEF_CONST(0.0); } } /* FIXED POINT: bwArray = COEF */ static void calc_chirp_factors(sbr_info *sbr, uint8_t ch) { uint8_t i; for (i = 0; i < sbr->N_Q; i++) { sbr->bwArray[ch][i] = mapNewBw(sbr->bs_invf_mode[ch][i], sbr->bs_invf_mode_prev[ch][i]); if (sbr->bwArray[ch][i] < sbr->bwArray_prev[ch][i]) sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.75)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.25)); else sbr->bwArray[ch][i] = MUL_F(sbr->bwArray[ch][i], FRAC_CONST(0.90625)) + MUL_F(sbr->bwArray_prev[ch][i], FRAC_CONST(0.09375)); if (sbr->bwArray[ch][i] < COEF_CONST(0.015625)) sbr->bwArray[ch][i] = COEF_CONST(0.0); if (sbr->bwArray[ch][i] >= COEF_CONST(0.99609375)) sbr->bwArray[ch][i] = COEF_CONST(0.99609375); sbr->bwArray_prev[ch][i] = sbr->bwArray[ch][i]; sbr->bs_invf_mode_prev[ch][i] = sbr->bs_invf_mode[ch][i]; } } static void patch_construction(sbr_info *sbr) { uint8_t i, k; uint8_t odd, sb; uint8_t msb = sbr->k0; uint8_t usb = sbr->kx; uint8_t goalSbTab[] = { 21, 23, 32, 43, 46, 64, 85, 93, 128, 0, 0, 0 }; /* (uint8_t)(2.048e6/sbr->sample_rate + 0.5); */ uint8_t goalSb = goalSbTab[get_sr_index(sbr->sample_rate)]; sbr->noPatches = 0; if (goalSb < (sbr->kx + sbr->M)) { for (i = 0, k = 0; sbr->f_master[i] < goalSb; i++) k = i+1; } else { k = sbr->N_master; } if (sbr->N_master == 0) { sbr->noPatches = 0; sbr->patchNoSubbands[0] = 0; sbr->patchStartSubband[0] = 0; return; } do { uint8_t j = k + 1; do { j--; sb = sbr->f_master[j]; odd = (sb - 2 + sbr->k0) % 2; } while (sb > (sbr->k0 - 1 + msb - odd)); sbr->patchNoSubbands[sbr->noPatches] = max(sb - usb, 0); sbr->patchStartSubband[sbr->noPatches] = sbr->k0 - odd - sbr->patchNoSubbands[sbr->noPatches]; if (sbr->patchNoSubbands[sbr->noPatches] > 0) { usb = sb; msb = sb; sbr->noPatches++; } else { msb = sbr->kx; } if (sbr->f_master[k] - sb < 3) k = sbr->N_master; } while (sb != (sbr->kx + sbr->M)); if ((sbr->patchNoSubbands[sbr->noPatches-1] < 3) && (sbr->noPatches > 1)) { sbr->noPatches--; } sbr->noPatches = min(sbr->noPatches, 5); } #endif xine-lib-1.2/contrib/libfaad/decoder.c0000644000175000017500000011021614647725151015457 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: decoder.c,v 1.117 2009/02/05 00:51:03 menno Exp $ **/ /* xine does this by itself #define USE_LATM */ #include "common.h" #include "structs.h" #include #include #include #include "mp4.h" #include "syntax.h" #include "error.h" #include "output.h" #include "filtbank.h" #include "drc.h" #ifdef SBR_DEC #include "sbr_dec.h" #include "sbr_syntax.h" #endif #ifdef SSR_DEC #include "ssr.h" #endif #ifdef ANALYSIS uint16_t dbg_count; #endif /* static function declarations */ static void* aac_frame_decode(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, unsigned char *buffer, unsigned long buffer_size, void **sample_buffer2, unsigned long sample_buffer_size); static void create_channel_config(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo); const char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode) { if (errcode >= NUM_ERROR_MESSAGES) return NULL; return err_msg[errcode]; } unsigned long NEAACDECAPI NeAACDecGetCapabilities(void) { uint32_t cap = 0; /* can't do without it */ cap += LC_DEC_CAP; #ifdef MAIN_DEC cap += MAIN_DEC_CAP; #endif #ifdef LTP_DEC cap += LTP_DEC_CAP; #endif #ifdef LD_DEC cap += LD_DEC_CAP; #endif #ifdef ERROR_RESILIENCE cap += ERROR_RESILIENCE_CAP; #endif #ifdef FIXED_POINT cap += FIXED_POINT_CAP; #endif return cap; } const unsigned char mes[] = { 0x67,0x20,0x61,0x20,0x20,0x20,0x6f,0x20,0x72,0x20,0x65,0x20,0x6e,0x20,0x20,0x20,0x74,0x20,0x68,0x20,0x67,0x20,0x69,0x20,0x72,0x20,0x79,0x20,0x70,0x20,0x6f,0x20,0x63 }; NeAACDecHandle NEAACDECAPI NeAACDecOpen(void) { uint8_t i; NeAACDecStruct *hDecoder = NULL; if ((hDecoder = (NeAACDecStruct*)faad_malloc(sizeof(NeAACDecStruct))) == NULL) return NULL; memset(hDecoder, 0, sizeof(NeAACDecStruct)); hDecoder->cmes = mes; hDecoder->config.outputFormat = FAAD_FMT_16BIT; hDecoder->config.defObjectType = MAIN; hDecoder->config.defSampleRate = 44100; /* Default: 44.1kHz */ hDecoder->config.downMatrix = 0; hDecoder->adts_header_present = 0; hDecoder->adif_header_present = 0; hDecoder->latm_header_present = 0; #ifdef ERROR_RESILIENCE hDecoder->aacSectionDataResilienceFlag = 0; hDecoder->aacScalefactorDataResilienceFlag = 0; hDecoder->aacSpectralDataResilienceFlag = 0; #endif hDecoder->frameLength = 1024; hDecoder->frame = 0; hDecoder->sample_buffer = NULL; hDecoder->__r1 = 1; hDecoder->__r2 = 1; for (i = 0; i < MAX_CHANNELS; i++) { hDecoder->window_shape_prev[i] = 0; hDecoder->time_out[i] = NULL; hDecoder->fb_intermed[i] = NULL; #ifdef SSR_DEC hDecoder->ssr_overlap[i] = NULL; hDecoder->prev_fmd[i] = NULL; #endif #ifdef MAIN_DEC hDecoder->pred_stat[i] = NULL; #endif #ifdef LTP_DEC hDecoder->ltp_lag[i] = 0; hDecoder->lt_pred_stat[i] = NULL; #endif } #ifdef SBR_DEC for (i = 0; i < MAX_SYNTAX_ELEMENTS; i++) { hDecoder->sbr[i] = NULL; } #endif hDecoder->drc = drc_init(REAL_CONST(1.0), REAL_CONST(1.0)); return hDecoder; } NeAACDecConfigurationPtr NEAACDECAPI NeAACDecGetCurrentConfiguration(NeAACDecHandle hpDecoder) { NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; if (hDecoder) { NeAACDecConfigurationPtr config = &(hDecoder->config); return config; } return NULL; } unsigned char NEAACDECAPI NeAACDecSetConfiguration(NeAACDecHandle hpDecoder, NeAACDecConfigurationPtr config) { NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; if (hDecoder && config) { /* check if we can decode this object type */ if (can_decode_ot(config->defObjectType) < 0) return 0; hDecoder->config.defObjectType = config->defObjectType; /* samplerate: anything but 0 should be possible */ if (config->defSampleRate == 0) return 0; hDecoder->config.defSampleRate = config->defSampleRate; /* check output format */ #ifdef FIXED_POINT if ((config->outputFormat < 1) || (config->outputFormat > 4)) return 0; #else if ((config->outputFormat < 1) || (config->outputFormat > 5)) return 0; #endif hDecoder->config.outputFormat = config->outputFormat; if (config->downMatrix > 1) return 0; hDecoder->config.downMatrix = config->downMatrix; /* OK */ return 1; } return 0; } #ifdef USE_LATM static int latmCheck(latm_header *latm, bitfile *ld) { uint32_t good=0, bad=0, bits, m; while (ld->bytes_left) { bits = faad_latm_frame(latm, ld); if(bits==-1U) bad++; else { good++; while(bits>0) { m = min(bits, 8); faad_getbits(ld, m); bits -= m; } } } return (good>0); } #endif long NEAACDECAPI NeAACDecInit(NeAACDecHandle hpDecoder, unsigned char *buffer, unsigned long buffer_size, unsigned long *samplerate, unsigned char *channels) { uint32_t bits = 0; bitfile ld; adif_header adif; adts_header adts; NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; if ((hDecoder == NULL) || (samplerate == NULL) || (channels == NULL)) return -1; hDecoder->sf_index = get_sr_index(hDecoder->config.defSampleRate); hDecoder->object_type = hDecoder->config.defObjectType; *samplerate = get_sample_rate(hDecoder->sf_index); *channels = 1; if (buffer != NULL) { #ifdef USE_LATM int is_latm; latm_header *l = &hDecoder->latm_config; #endif faad_initbits(&ld, buffer, buffer_size); #ifdef USE_LATM memset(l, 0, sizeof(latm_header)); is_latm = latmCheck(l, &ld); l->inited = 0; l->frameLength = 0; faad_rewindbits(&ld); if(is_latm && l->ASCbits>0) { int32_t x; hDecoder->latm_header_present = 1; x = NeAACDecInit2(hDecoder, l->ASC, (l->ASCbits+7)/8, samplerate, channels); if(x!=0) hDecoder->latm_header_present = 0; return x; } else #endif /* Check if an ADIF header is present */ if ((buffer[0] == 'A') && (buffer[1] == 'D') && (buffer[2] == 'I') && (buffer[3] == 'F')) { hDecoder->adif_header_present = 1; get_adif_header(&adif, &ld); faad_byte_align(&ld); hDecoder->sf_index = adif.pce[0].sf_index; hDecoder->object_type = adif.pce[0].object_type + 1; *samplerate = get_sample_rate(hDecoder->sf_index); *channels = adif.pce[0].channels; memcpy(&(hDecoder->pce), &(adif.pce[0]), sizeof(program_config)); hDecoder->pce_set = 1; bits = bit2byte(faad_get_processed_bits(&ld)); /* Check if an ADTS header is present */ } else if (faad_showbits(&ld, 12) == 0xfff) { hDecoder->adts_header_present = 1; adts.old_format = hDecoder->config.useOldADTSFormat; adts_frame(&adts, &ld); hDecoder->sf_index = adts.sf_index; hDecoder->object_type = adts.profile + 1; *samplerate = get_sample_rate(hDecoder->sf_index); *channels = (adts.channel_configuration > 6) ? 2 : adts.channel_configuration; } if (ld.error) { faad_endbits(&ld); return -1; } faad_endbits(&ld); } #if (defined(PS_DEC) || defined(DRM_PS)) /* check if we have a mono file */ if (*channels == 1) { /* upMatrix to 2 channels for implicit signalling of PS */ *channels = 2; } #endif hDecoder->channelConfiguration = *channels; #ifdef SBR_DEC /* implicit signalling */ if (*samplerate <= 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0)) { *samplerate *= 2; hDecoder->forceUpSampling = 1; } else if (*samplerate > 24000 && (hDecoder->config.dontUpSampleImplicitSBR == 0)) { hDecoder->downSampledSBR = 1; } #endif /* must be done before frameLength is divided by 2 for LD */ #ifdef SSR_DEC if (hDecoder->object_type == SSR) hDecoder->fb = ssr_filter_bank_init(hDecoder->frameLength/SSR_BANDS); else #endif hDecoder->fb = filter_bank_init(hDecoder->frameLength); #ifdef LD_DEC if (hDecoder->object_type == LD) hDecoder->frameLength >>= 1; #endif if (can_decode_ot(hDecoder->object_type) < 0) return -1; return bits; } /* Init the library using a DecoderSpecificInfo */ char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hpDecoder, unsigned char *pBuffer, unsigned long SizeOfDecoderSpecificInfo, unsigned long *samplerate, unsigned char *channels) { NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; int8_t rc; mp4AudioSpecificConfig mp4ASC; if((hDecoder == NULL) || (pBuffer == NULL) || (SizeOfDecoderSpecificInfo < 2) || (samplerate == NULL) || (channels == NULL)) { return -1; } hDecoder->adif_header_present = 0; hDecoder->adts_header_present = 0; /* decode the audio specific config */ rc = AudioSpecificConfig2(pBuffer, SizeOfDecoderSpecificInfo, &mp4ASC, &(hDecoder->pce), hDecoder->latm_header_present); /* copy the relevant info to the decoder handle */ *samplerate = mp4ASC.samplingFrequency; if (mp4ASC.channelsConfiguration) { *channels = mp4ASC.channelsConfiguration; } else { *channels = hDecoder->pce.channels; hDecoder->pce_set = 1; } #if (defined(PS_DEC) || defined(DRM_PS)) /* check if we have a mono file */ if (*channels == 1) { /* upMatrix to 2 channels for implicit signalling of PS */ *channels = 2; } #endif hDecoder->sf_index = mp4ASC.samplingFrequencyIndex; hDecoder->object_type = mp4ASC.objectTypeIndex; #ifdef ERROR_RESILIENCE hDecoder->aacSectionDataResilienceFlag = mp4ASC.aacSectionDataResilienceFlag; hDecoder->aacScalefactorDataResilienceFlag = mp4ASC.aacScalefactorDataResilienceFlag; hDecoder->aacSpectralDataResilienceFlag = mp4ASC.aacSpectralDataResilienceFlag; #endif #ifdef SBR_DEC hDecoder->sbr_present_flag = mp4ASC.sbr_present_flag; hDecoder->downSampledSBR = mp4ASC.downSampledSBR; if (hDecoder->config.dontUpSampleImplicitSBR == 0) hDecoder->forceUpSampling = mp4ASC.forceUpSampling; else hDecoder->forceUpSampling = 0; /* AAC core decoder samplerate is 2 times as low */ if (((hDecoder->sbr_present_flag == 1)&&(!hDecoder->downSampledSBR)) || hDecoder->forceUpSampling == 1) { hDecoder->sf_index = get_sr_index(mp4ASC.samplingFrequency / 2); } #endif if (rc != 0) { return rc; } hDecoder->channelConfiguration = mp4ASC.channelsConfiguration; if (mp4ASC.frameLengthFlag) #ifdef ALLOW_SMALL_FRAMELENGTH hDecoder->frameLength = 960; #else return -1; #endif /* must be done before frameLength is divided by 2 for LD */ #ifdef SSR_DEC if (hDecoder->object_type == SSR) hDecoder->fb = ssr_filter_bank_init(hDecoder->frameLength/SSR_BANDS); else #endif hDecoder->fb = filter_bank_init(hDecoder->frameLength); #ifdef LD_DEC if (hDecoder->object_type == LD) hDecoder->frameLength >>= 1; #endif return 0; } #ifdef DRM char NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hpDecoder, unsigned long samplerate, unsigned char channels) { NeAACDecStruct** hDecoder = (NeAACDecStruct**)hpDecoder; if (hDecoder == NULL) return 1; /* error */ NeAACDecClose(*hDecoder); *hDecoder = NeAACDecOpen(); /* Special object type defined for DRM */ (*hDecoder)->config.defObjectType = DRM_ER_LC; (*hDecoder)->config.defSampleRate = samplerate; #ifdef ERROR_RESILIENCE // This shoudl always be defined for DRM (*hDecoder)->aacSectionDataResilienceFlag = 1; /* VCB11 */ (*hDecoder)->aacScalefactorDataResilienceFlag = 0; /* no RVLC */ (*hDecoder)->aacSpectralDataResilienceFlag = 1; /* HCR */ #endif (*hDecoder)->frameLength = 960; (*hDecoder)->sf_index = get_sr_index((*hDecoder)->config.defSampleRate); (*hDecoder)->object_type = (*hDecoder)->config.defObjectType; if ((channels == DRMCH_STEREO) || (channels == DRMCH_SBR_STEREO)) (*hDecoder)->channelConfiguration = 2; else (*hDecoder)->channelConfiguration = 1; #ifdef SBR_DEC if ((channels == DRMCH_MONO) || (channels == DRMCH_STEREO)) (*hDecoder)->sbr_present_flag = 0; else (*hDecoder)->sbr_present_flag = 1; #endif (*hDecoder)->fb = filter_bank_init((*hDecoder)->frameLength); return 0; } #endif void NEAACDECAPI NeAACDecClose(NeAACDecHandle hpDecoder) { uint8_t i; NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; if (hDecoder == NULL) return; #ifdef PROFILE printf("AAC decoder total: %I64d cycles\n", hDecoder->cycles); printf("requant: %I64d cycles\n", hDecoder->requant_cycles); printf("spectral_data: %I64d cycles\n", hDecoder->spectral_cycles); printf("scalefactors: %I64d cycles\n", hDecoder->scalefac_cycles); printf("output: %I64d cycles\n", hDecoder->output_cycles); #endif for (i = 0; i < MAX_CHANNELS; i++) { if (hDecoder->time_out[i]) faad_free(hDecoder->time_out[i]); if (hDecoder->fb_intermed[i]) faad_free(hDecoder->fb_intermed[i]); #ifdef SSR_DEC if (hDecoder->ssr_overlap[i]) faad_free(hDecoder->ssr_overlap[i]); if (hDecoder->prev_fmd[i]) faad_free(hDecoder->prev_fmd[i]); #endif #ifdef MAIN_DEC if (hDecoder->pred_stat[i]) faad_free(hDecoder->pred_stat[i]); #endif #ifdef LTP_DEC if (hDecoder->lt_pred_stat[i]) faad_free(hDecoder->lt_pred_stat[i]); #endif } #ifdef SSR_DEC if (hDecoder->object_type == SSR) ssr_filter_bank_end(hDecoder->fb); else #endif filter_bank_end(hDecoder->fb); drc_end(hDecoder->drc); if (hDecoder->sample_buffer) faad_free(hDecoder->sample_buffer); #ifdef SBR_DEC for (i = 0; i < MAX_SYNTAX_ELEMENTS; i++) { if (hDecoder->sbr[i]) sbrDecodeEnd(hDecoder->sbr[i]); } #endif if (hDecoder) faad_free(hDecoder); } void NEAACDECAPI NeAACDecPostSeekReset(NeAACDecHandle hpDecoder, long frame) { NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; if (hDecoder) { hDecoder->postSeekResetFlag = 1; if (frame != -1) hDecoder->frame = frame; } } static void create_channel_config(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo) { hInfo->num_front_channels = 0; hInfo->num_side_channels = 0; hInfo->num_back_channels = 0; hInfo->num_lfe_channels = 0; memset(hInfo->channel_position, 0, MAX_CHANNELS*sizeof(uint8_t)); if (hDecoder->downMatrix) { hInfo->num_front_channels = 2; hInfo->channel_position[0] = FRONT_CHANNEL_LEFT; hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT; return; } /* check if there is a PCE */ if (hDecoder->pce_set) { uint8_t i, chpos = 0; uint8_t chdir, back_center = 0; hInfo->num_front_channels = hDecoder->pce.num_front_channels; hInfo->num_side_channels = hDecoder->pce.num_side_channels; hInfo->num_back_channels = hDecoder->pce.num_back_channels; hInfo->num_lfe_channels = hDecoder->pce.num_lfe_channels; chdir = hInfo->num_front_channels; if (chdir & 1) { #if (defined(PS_DEC) || defined(DRM_PS)) /* When PS is enabled output is always stereo */ hInfo->channel_position[chpos++] = FRONT_CHANNEL_LEFT; hInfo->channel_position[chpos++] = FRONT_CHANNEL_RIGHT; #else hInfo->channel_position[chpos++] = FRONT_CHANNEL_CENTER; chdir--; #endif } for (i = 0; i < chdir; i += 2) { hInfo->channel_position[chpos++] = FRONT_CHANNEL_LEFT; hInfo->channel_position[chpos++] = FRONT_CHANNEL_RIGHT; } for (i = 0; i < hInfo->num_side_channels; i += 2) { hInfo->channel_position[chpos++] = SIDE_CHANNEL_LEFT; hInfo->channel_position[chpos++] = SIDE_CHANNEL_RIGHT; } chdir = hInfo->num_back_channels; if (chdir & 1) { back_center = 1; chdir--; } for (i = 0; i < chdir; i += 2) { hInfo->channel_position[chpos++] = BACK_CHANNEL_LEFT; hInfo->channel_position[chpos++] = BACK_CHANNEL_RIGHT; } if (back_center) { hInfo->channel_position[chpos++] = BACK_CHANNEL_CENTER; } for (i = 0; i < hInfo->num_lfe_channels; i++) { hInfo->channel_position[chpos++] = LFE_CHANNEL; } } else { switch (hDecoder->channelConfiguration) { case 1: #if (defined(PS_DEC) || defined(DRM_PS)) /* When PS is enabled output is always stereo */ hInfo->num_front_channels = 2; hInfo->channel_position[0] = FRONT_CHANNEL_LEFT; hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT; #else hInfo->num_front_channels = 1; hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; #endif break; case 2: hInfo->num_front_channels = 2; hInfo->channel_position[0] = FRONT_CHANNEL_LEFT; hInfo->channel_position[1] = FRONT_CHANNEL_RIGHT; break; case 3: hInfo->num_front_channels = 3; hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; break; case 4: hInfo->num_front_channels = 3; hInfo->num_back_channels = 1; hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; hInfo->channel_position[3] = BACK_CHANNEL_CENTER; break; case 5: hInfo->num_front_channels = 3; hInfo->num_back_channels = 2; hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; hInfo->channel_position[3] = BACK_CHANNEL_LEFT; hInfo->channel_position[4] = BACK_CHANNEL_RIGHT; break; case 6: hInfo->num_front_channels = 3; hInfo->num_back_channels = 2; hInfo->num_lfe_channels = 1; hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; hInfo->channel_position[3] = BACK_CHANNEL_LEFT; hInfo->channel_position[4] = BACK_CHANNEL_RIGHT; hInfo->channel_position[5] = LFE_CHANNEL; break; case 7: hInfo->num_front_channels = 3; hInfo->num_side_channels = 2; hInfo->num_back_channels = 2; hInfo->num_lfe_channels = 1; hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; hInfo->channel_position[1] = FRONT_CHANNEL_LEFT; hInfo->channel_position[2] = FRONT_CHANNEL_RIGHT; hInfo->channel_position[3] = SIDE_CHANNEL_LEFT; hInfo->channel_position[4] = SIDE_CHANNEL_RIGHT; hInfo->channel_position[5] = BACK_CHANNEL_LEFT; hInfo->channel_position[6] = BACK_CHANNEL_RIGHT; hInfo->channel_position[7] = LFE_CHANNEL; break; default: /* channelConfiguration == 0 || channelConfiguration > 7 */ { uint8_t i; uint8_t ch = hDecoder->fr_channels - hDecoder->has_lfe; if (ch & 1) /* there's either a center front or a center back channel */ { uint8_t ch1 = (ch-1)/2; if (hDecoder->first_syn_ele == ID_SCE) { hInfo->num_front_channels = ch1 + 1; hInfo->num_back_channels = ch1; hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; for (i = 1; i <= ch1; i+=2) { hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; } for (i = ch1+1; i < ch; i+=2) { hInfo->channel_position[i] = BACK_CHANNEL_LEFT; hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; } } else { hInfo->num_front_channels = ch1; hInfo->num_back_channels = ch1 + 1; for (i = 0; i < ch1; i+=2) { hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; } for (i = ch1; i < ch-1; i+=2) { hInfo->channel_position[i] = BACK_CHANNEL_LEFT; hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; } hInfo->channel_position[ch-1] = BACK_CHANNEL_CENTER; } } else { uint8_t ch1 = (ch)/2; hInfo->num_front_channels = ch1; hInfo->num_back_channels = ch1; if (ch1 & 1) { hInfo->channel_position[0] = FRONT_CHANNEL_CENTER; for (i = 1; i <= ch1; i+=2) { hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; } for (i = ch1+1; i < ch-1; i+=2) { hInfo->channel_position[i] = BACK_CHANNEL_LEFT; hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; } hInfo->channel_position[ch-1] = BACK_CHANNEL_CENTER; } else { for (i = 0; i < ch1; i+=2) { hInfo->channel_position[i] = FRONT_CHANNEL_LEFT; hInfo->channel_position[i+1] = FRONT_CHANNEL_RIGHT; } for (i = ch1; i < ch; i+=2) { hInfo->channel_position[i] = BACK_CHANNEL_LEFT; hInfo->channel_position[i+1] = BACK_CHANNEL_RIGHT; } } } hInfo->num_lfe_channels = hDecoder->has_lfe; for (i = ch; i < hDecoder->fr_channels; i++) { hInfo->channel_position[i] = LFE_CHANNEL; } } break; } } } void* NEAACDECAPI NeAACDecDecode(NeAACDecHandle hpDecoder, NeAACDecFrameInfo *hInfo, unsigned char *buffer, unsigned long buffer_size) { NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; return aac_frame_decode(hDecoder, hInfo, buffer, buffer_size, NULL, 0); } void* NEAACDECAPI NeAACDecDecode2(NeAACDecHandle hpDecoder, NeAACDecFrameInfo *hInfo, unsigned char *buffer, unsigned long buffer_size, void **sample_buffer, unsigned long sample_buffer_size) { NeAACDecStruct* hDecoder = (NeAACDecStruct*)hpDecoder; if ((sample_buffer == NULL) || (sample_buffer_size == 0)) { hInfo->error = 27; return NULL; } return aac_frame_decode(hDecoder, hInfo, buffer, buffer_size, sample_buffer, sample_buffer_size); } #ifdef DRM #define ERROR_STATE_INIT 6 static void conceal_output(NeAACDecStruct *hDecoder, uint16_t frame_len, uint8_t out_ch, void *sample_buffer) { return; } #endif static void* aac_frame_decode(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, unsigned char *buffer, unsigned long buffer_size, void **sample_buffer2, unsigned long sample_buffer_size) { uint16_t i; uint8_t channels = 0; uint8_t output_channels = 0; bitfile ld = BITFILE_INIT; uint32_t bitsconsumed; uint16_t frame_len; void *sample_buffer; #ifdef USE_LATM uint32_t startbit=0, endbit=0, payload_bits=0; #endif #ifdef PROFILE int64_t count = faad_get_ts(); #endif /* safety checks */ if ((hDecoder == NULL) || (hInfo == NULL) || (buffer == NULL)) { return NULL; } #if 0 printf("%d\n", buffer_size*8); #endif frame_len = hDecoder->frameLength; memset(hInfo, 0, sizeof(NeAACDecFrameInfo)); memset(hDecoder->internal_channel, 0, MAX_CHANNELS*sizeof(hDecoder->internal_channel[0])); #ifdef USE_TIME_LIMIT if ((TIME_LIMIT * get_sample_rate(hDecoder->sf_index)) > hDecoder->TL_count) { hDecoder->TL_count += 1024; } else { hInfo->error = (NUM_ERROR_MESSAGES-1); goto error; } #endif /* check for some common metadata tag types in the bitstream * No need to return an error */ /* ID3 */ if (buffer_size >= 128) { if (memcmp(buffer, "TAG", 3) == 0) { /* found it */ hInfo->bytesconsumed = 128; /* 128 bytes fixed size */ /* no error, but no output either */ return NULL; } } /* initialize the bitstream */ faad_initbits(&ld, buffer, buffer_size); #if 0 { int i; for (i = 0; i < ((buffer_size+3)>>2); i++) { uint8_t *buf; uint32_t temp = 0; buf = faad_getbitbuffer(&ld, 32); //temp = getdword((void*)buf); temp = *((uint32_t*)buf); printf("0x%.8X\n", temp); free(buf); } faad_endbits(&ld); faad_initbits(&ld, buffer, buffer_size); } #endif #ifdef USE_LATM if(hDecoder->latm_header_present) { payload_bits = faad_latm_frame(&hDecoder->latm_config, &ld); startbit = faad_get_processed_bits(&ld); if(payload_bits == -1U) { hInfo->error = 1; goto error; } } #endif #ifdef DRM if (hDecoder->object_type == DRM_ER_LC) { /* We do not support stereo right now */ if (0) //(hDecoder->channelConfiguration == 2) { hInfo->error = 28; // Throw CRC error goto error; } faad_getbits(&ld, 8 DEBUGVAR(1,1,"NeAACDecDecode(): skip CRC")); } #endif if (hDecoder->adts_header_present) { adts_header adts; adts.old_format = hDecoder->config.useOldADTSFormat; if ((hInfo->error = adts_frame(&adts, &ld)) > 0) goto error; /* MPEG2 does byte_alignment() here, * but ADTS header is always multiple of 8 bits in MPEG2 * so not needed to actually do it. */ } #ifdef ANALYSIS dbg_count = 0; #endif /* decode the complete bitstream */ #ifdef DRM if (/*(hDecoder->object_type == 6) ||*/ (hDecoder->object_type == DRM_ER_LC)) { DRM_aac_scalable_main_element(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc); } else { #endif raw_data_block(hDecoder, hInfo, &ld, &hDecoder->pce, hDecoder->drc); #ifdef DRM } #endif #ifdef USE_LATM if(hDecoder->latm_header_present) { endbit = faad_get_processed_bits(&ld); if(endbit-startbit > payload_bits) fprintf(stderr, "\r\nERROR, too many payload bits read: %u > %d. Please. report with a link to a sample\n", endbit-startbit, payload_bits); if(hDecoder->latm_config.otherDataLenBits > 0) faad_getbits(&ld, hDecoder->latm_config.otherDataLenBits); faad_byte_align(&ld); } #endif channels = hDecoder->fr_channels; if (hInfo->error > 0) goto error; /* safety check */ if (channels == 0 || channels > MAX_CHANNELS) { /* invalid number of channels */ hInfo->error = 12; goto error; } /* no more bit reading after this */ bitsconsumed = faad_get_processed_bits(&ld); hInfo->bytesconsumed = bit2byte(bitsconsumed); if (ld.error) { hInfo->error = 14; goto error; } faad_endbits(&ld); if (!hDecoder->adts_header_present && !hDecoder->adif_header_present #ifdef USE_LATM && !hDecoder->latm_header_present #endif ) { if (hDecoder->channelConfiguration == 0) hDecoder->channelConfiguration = channels; if (channels == 8) /* 7.1 */ hDecoder->channelConfiguration = 7; if (channels == 7) /* not a standard channelConfiguration */ hDecoder->channelConfiguration = 0; } if ((channels == 5 || channels == 6) && hDecoder->config.downMatrix) { hDecoder->downMatrix = 1; output_channels = 2; } else { output_channels = channels; } #if (defined(PS_DEC) || defined(DRM_PS)) hDecoder->upMatrix = 0; /* check if we have a mono file */ if (output_channels == 1) { /* upMatrix to 2 channels for implicit signalling of PS */ hDecoder->upMatrix = 1; output_channels = 2; } #endif /* Make a channel configuration based on either a PCE or a channelConfiguration */ create_channel_config(hDecoder, hInfo); /* number of samples in this frame */ hInfo->samples = frame_len*output_channels; /* number of channels in this frame */ hInfo->channels = output_channels; /* samplerate */ hInfo->samplerate = get_sample_rate(hDecoder->sf_index); /* object type */ hInfo->object_type = hDecoder->object_type; /* sbr */ hInfo->sbr = NO_SBR; /* header type */ hInfo->header_type = RAW; if (hDecoder->adif_header_present) hInfo->header_type = ADIF; if (hDecoder->adts_header_present) hInfo->header_type = ADTS; #ifdef USE_LATM if (hDecoder->latm_header_present) hInfo->header_type = LATM; #endif #if (defined(PS_DEC) || defined(DRM_PS)) hInfo->ps = hDecoder->ps_used_global; #endif /* check if frame has channel elements */ if (channels == 0) { hDecoder->frame++; return NULL; } /* allocate the buffer for the final samples */ if ((hDecoder->sample_buffer == NULL) || (hDecoder->alloced_channels != output_channels)) { static const uint8_t str[] = { sizeof(int16_t), sizeof(int32_t), sizeof(int32_t), sizeof(float32_t), sizeof(double), sizeof(int16_t), sizeof(int16_t), sizeof(int16_t), sizeof(int16_t), 0, 0, 0 }; uint8_t stride = str[hDecoder->config.outputFormat-1]; #ifdef SBR_DEC if (((hDecoder->sbr_present_flag == 1)&&(!hDecoder->downSampledSBR)) || (hDecoder->forceUpSampling == 1)) { stride = 2 * stride; } #endif /* check if we want to use internal sample_buffer */ if (sample_buffer_size == 0) { if (hDecoder->sample_buffer) faad_free(hDecoder->sample_buffer); hDecoder->sample_buffer = NULL; hDecoder->sample_buffer = faad_malloc(frame_len*output_channels*stride); } else if (sample_buffer_size < (unsigned int)(frame_len*output_channels*stride)) { /* provided sample buffer is not big enough */ hInfo->error = 27; return NULL; } hDecoder->alloced_channels = output_channels; } if (sample_buffer_size == 0) { sample_buffer = hDecoder->sample_buffer; } else { sample_buffer = *sample_buffer2; } #ifdef SBR_DEC if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) { uint8_t ele; /* this data is different when SBR is used or when the data is upsampled */ if (!hDecoder->downSampledSBR) { frame_len *= 2; hInfo->samples *= 2; hInfo->samplerate *= 2; } /* check if every element was provided with SBR data */ for (ele = 0; ele < hDecoder->fr_ch_ele; ele++) { if (hDecoder->sbr[ele] == NULL) { hInfo->error = 25; goto error; } } /* sbr */ if (hDecoder->sbr_present_flag == 1) { hInfo->object_type = HE_AAC; hInfo->sbr = SBR_UPSAMPLED; } else { hInfo->sbr = NO_SBR_UPSAMPLED; } if (hDecoder->downSampledSBR) { hInfo->sbr = SBR_DOWNSAMPLED; } } #endif sample_buffer = output_to_PCM(hDecoder, hDecoder->time_out, sample_buffer, output_channels, frame_len, hDecoder->config.outputFormat); #ifdef DRM //conceal_output(hDecoder, frame_len, output_channels, sample_buffer); #endif hDecoder->postSeekResetFlag = 0; hDecoder->frame++; #ifdef LD_DEC if (hDecoder->object_type != LD) { #endif if (hDecoder->frame <= 1) hInfo->samples = 0; #ifdef LD_DEC } else { /* LD encoders will give lower delay */ if (hDecoder->frame <= 0) hInfo->samples = 0; } #endif /* cleanup */ #ifdef ANALYSIS fflush(stdout); #endif #ifdef PROFILE count = faad_get_ts() - count; hDecoder->cycles += count; #endif return sample_buffer; error: #ifdef DRM hDecoder->error_state = ERROR_STATE_INIT; #endif /* reset filterbank state */ for (i = 0; i < MAX_CHANNELS; i++) { if (hDecoder->fb_intermed[i] != NULL) { memset(hDecoder->fb_intermed[i], 0, hDecoder->frameLength*sizeof(real_t)); } } #ifdef SBR_DEC for (i = 0; i < MAX_SYNTAX_ELEMENTS; i++) { if (hDecoder->sbr[i] != NULL) { sbrReset(hDecoder->sbr[i]); } } #endif faad_endbits(&ld); /* cleanup */ #ifdef ANALYSIS fflush(stdout); #endif return NULL; } xine-lib-1.2/contrib/libfaad/drc.h0000644000175000017500000000305114647725151014625 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: drc.h,v 1.22 2007/11/01 12:33:30 menno Exp $ **/ #ifndef __DRC_H__ #define __DRC_H__ #ifdef __cplusplus extern "C" { #endif #define DRC_REF_LEVEL 20*4 /* -20 dB */ drc_info *drc_init(real_t cut, real_t boost); void drc_end(drc_info *drc); void drc_decode(drc_info *drc, real_t *spec); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ms.c0000644000175000017500000000534014647725151014472 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ms.c,v 1.21 2007/11/01 12:33:32 menno Exp $ **/ #include "common.h" #include "structs.h" #include "syntax.h" #include "ms.h" #include "is.h" #include "pns.h" void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec, uint16_t frame_len) { uint8_t g, b, sfb; uint8_t group = 0; uint16_t nshort = frame_len/8; uint16_t i, k; real_t tmp; if (ics->ms_mask_present >= 1) { for (g = 0; g < ics->num_window_groups; g++) { for (b = 0; b < ics->window_group_length[g]; b++) { for (sfb = 0; sfb < ics->max_sfb; sfb++) { /* If intensity stereo coding or noise substitution is on for a particular scalefactor band, no M/S stereo decoding is carried out. */ if ((ics->ms_used[g][sfb] || ics->ms_mask_present == 2) && !is_intensity(icsr, g, sfb) && !is_noise(ics, g, sfb)) { for (i = ics->swb_offset[sfb]; i < min(ics->swb_offset[sfb+1], ics->swb_offset_max); i++) { k = (group*nshort) + i; tmp = l_spec[k] - r_spec[k]; l_spec[k] = l_spec[k] + r_spec[k]; r_spec[k] = tmp; } } } group++; } } } } xine-lib-1.2/contrib/libfaad/bits.h0000644000175000017500000003112614647725152015023 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: bits.h,v 1.45 2007/11/01 12:33:29 menno Exp $ **/ #ifndef __BITS_H__ #define __BITS_H__ #ifdef __cplusplus extern "C" { #endif #include "xine/attributes.h" #include "analysis.h" #ifdef ANALYSIS #include #endif #define BYTE_NUMBIT 8 #define BYTE_NUMBIT_LD 3 //#define bit2byte(a) ((a+7)/BYTE_NUMBIT) #define bit2byte(a) ((a+7)>>BYTE_NUMBIT_LD) typedef struct _bitfile { /* bit input */ uint32_t bufa; uint32_t bufb; uint32_t bits_left; uint32_t buffer_size; /* size of the buffer in bytes */ uint32_t bytes_left; uint8_t error; uint32_t *tail; uint32_t *start; const void *buffer; } bitfile; #define BITFILE_INIT {0, 0, 0, 0, 0, 0, NULL, NULL, NULL} #if 0 static uint32_t const bitmask[] = { 0x0, 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF /* added bitmask 32, correct?!?!?! */ , 0xFFFFFFFF }; #endif void faad_initbits(bitfile *ld, const void *buffer, const uint32_t buffer_size); void faad_endbits(bitfile *ld); void faad_initbits_rev(bitfile *ld, void *buffer, uint32_t bits_in_buffer); uint8_t faad_byte_align(bitfile *ld); uint32_t faad_get_processed_bits(bitfile *ld); void faad_flushbits_ex(bitfile *ld, uint32_t bits); void faad_rewindbits(bitfile *ld); void faad_resetbits(bitfile *ld, int bits); uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits DEBUGDEC); #ifdef DRM void *faad_origbitbuffer(bitfile *ld); uint32_t faad_origbitbuffer_size(bitfile *ld); #endif /* circumvent memory alignment errors on ARM */ static INLINE uint32_t getdword(void *mem) { uint32_t tmp; #ifndef ARCH_IS_BIG_ENDIAN ((uint8_t*)&tmp)[0] = ((uint8_t*)mem)[3]; ((uint8_t*)&tmp)[1] = ((uint8_t*)mem)[2]; ((uint8_t*)&tmp)[2] = ((uint8_t*)mem)[1]; ((uint8_t*)&tmp)[3] = ((uint8_t*)mem)[0]; #else ((uint8_t*)&tmp)[0] = ((uint8_t*)mem)[0]; ((uint8_t*)&tmp)[1] = ((uint8_t*)mem)[1]; ((uint8_t*)&tmp)[2] = ((uint8_t*)mem)[2]; ((uint8_t*)&tmp)[3] = ((uint8_t*)mem)[3]; #endif return tmp; } /* reads only n bytes from the stream instead of the standard 4 */ static /*INLINE*/ __attr_unused uint32_t getdword_n(void *mem, int n) { uint32_t tmp = 0; #ifndef ARCH_IS_BIG_ENDIAN switch (n) { case 3: ((uint8_t*)&tmp)[1] = ((uint8_t*)mem)[2]; /* fall through */ case 2: ((uint8_t*)&tmp)[2] = ((uint8_t*)mem)[1]; /* fall through */ case 1: ((uint8_t*)&tmp)[3] = ((uint8_t*)mem)[0]; /* fall through */ default: break; } #else switch (n) { case 3: ((uint8_t*)&tmp)[2] = ((uint8_t*)mem)[2]; /* fall through */ case 2: ((uint8_t*)&tmp)[1] = ((uint8_t*)mem)[1]; /* fall through */ case 1: ((uint8_t*)&tmp)[0] = ((uint8_t*)mem)[0]; /* fall through */ default: break; } #endif return tmp; } static INLINE uint32_t faad_showbits(bitfile *ld, uint32_t bits) { if (bits <= ld->bits_left) { //return (ld->bufa >> (ld->bits_left - bits)) & bitmask[bits]; return (ld->bufa << (32 - ld->bits_left)) >> (32 - bits); } bits -= ld->bits_left; //return ((ld->bufa & bitmask[ld->bits_left]) << bits) | (ld->bufb >> (32 - bits)); return ((ld->bufa & ((1<bits_left)-1)) << bits) | (ld->bufb >> (32 - bits)); } static INLINE void faad_flushbits(bitfile *ld, uint32_t bits) { /* do nothing if error */ if (ld->error != 0) return; if (bits < ld->bits_left) { ld->bits_left -= bits; } else { faad_flushbits_ex(ld, bits); } } /* return next n bits (right adjusted) */ static /*INLINE*/ uint32_t faad_getbits(bitfile *ld, uint32_t n DEBUGDEC) { uint32_t ret; if (n == 0) return 0; ret = faad_showbits(ld, n); faad_flushbits(ld, n); #ifdef ANALYSIS if (print) fprintf(stdout, "%4d %2d bits, val: %4d, variable: %d %s\n", dbg_count++, n, ret, var, dbg); #endif return ret; } static INLINE uint8_t faad_get1bit(bitfile *ld DEBUGDEC) { uint8_t r; if (ld->bits_left > 0) { ld->bits_left--; r = (uint8_t)((ld->bufa >> ld->bits_left) & 1); return r; } /* bits_left == 0 */ #if 0 r = (uint8_t)(ld->bufb >> 31); faad_flushbits_ex(ld, 1); #else r = (uint8_t)faad_getbits(ld, 1); #endif return r; } /* reversed bitreading routines */ static INLINE uint32_t faad_showbits_rev(bitfile *ld, uint32_t bits) { uint8_t i; uint32_t B = 0; if (bits <= ld->bits_left) { for (i = 0; i < bits; i++) { if (ld->bufa & (1 << (i + (32 - ld->bits_left)))) B |= (1 << (bits - i - 1)); } return B; } else { for (i = 0; i < ld->bits_left; i++) { if (ld->bufa & (1 << (i + (32 - ld->bits_left)))) B |= (1 << (bits - i - 1)); } for (i = 0; i < bits - ld->bits_left; i++) { if (ld->bufb & (1 << (i + (32-ld->bits_left)))) B |= (1 << (bits - ld->bits_left - i - 1)); } return B; } } static INLINE void faad_flushbits_rev(bitfile *ld, uint32_t bits) { /* do nothing if error */ if (ld->error != 0) return; if (bits < ld->bits_left) { ld->bits_left -= bits; } else { uint32_t tmp; ld->bufa = ld->bufb; tmp = getdword(ld->start); ld->bufb = tmp; ld->start--; ld->bits_left += (32 - bits); if (ld->bytes_left < 4) { ld->error = 1; ld->bytes_left = 0; } else { ld->bytes_left -= 4; } // if (ld->bytes_left == 0) // ld->no_more_reading = 1; } } static /*INLINE*/ __attr_unused uint32_t faad_getbits_rev(bitfile *ld, uint32_t n DEBUGDEC) { uint32_t ret; if (n == 0) return 0; ret = faad_showbits_rev(ld, n); faad_flushbits_rev(ld, n); #ifdef ANALYSIS if (print) fprintf(stdout, "%4d %2d bits, val: %4d, variable: %d %s\n", dbg_count++, n, ret, var, dbg); #endif return ret; } #ifdef DRM /* CRC lookup table for G8 polynome in DRM standard */ static const uint8_t crc_table_G8[256] = { 0x0, 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, 0x2, 0x51, 0x4c, 0x6b, 0x76, 0x87, 0x9a, 0xbd, 0xa0, 0xf3, 0xee, 0xc9, 0xd4, 0x6f, 0x72, 0x55, 0x48, 0x1b, 0x6, 0x21, 0x3c, 0x4a, 0x57, 0x70, 0x6d, 0x3e, 0x23, 0x4, 0x19, 0xa2, 0xbf, 0x98, 0x85, 0xd6, 0xcb, 0xec, 0xf1, 0x13, 0xe, 0x29, 0x34, 0x67, 0x7a, 0x5d, 0x40, 0xfb, 0xe6, 0xc1, 0xdc, 0x8f, 0x92, 0xb5, 0xa8, 0xde, 0xc3, 0xe4, 0xf9, 0xaa, 0xb7, 0x90, 0x8d, 0x36, 0x2b, 0xc, 0x11, 0x42, 0x5f, 0x78, 0x65, 0x94, 0x89, 0xae, 0xb3, 0xe0, 0xfd, 0xda, 0xc7, 0x7c, 0x61, 0x46, 0x5b, 0x8, 0x15, 0x32, 0x2f, 0x59, 0x44, 0x63, 0x7e, 0x2d, 0x30, 0x17, 0xa, 0xb1, 0xac, 0x8b, 0x96, 0xc5, 0xd8, 0xff, 0xe2, 0x26, 0x3b, 0x1c, 0x1, 0x52, 0x4f, 0x68, 0x75, 0xce, 0xd3, 0xf4, 0xe9, 0xba, 0xa7, 0x80, 0x9d, 0xeb, 0xf6, 0xd1, 0xcc, 0x9f, 0x82, 0xa5, 0xb8, 0x3, 0x1e, 0x39, 0x24, 0x77, 0x6a, 0x4d, 0x50, 0xa1, 0xbc, 0x9b, 0x86, 0xd5, 0xc8, 0xef, 0xf2, 0x49, 0x54, 0x73, 0x6e, 0x3d, 0x20, 0x7, 0x1a, 0x6c, 0x71, 0x56, 0x4b, 0x18, 0x5, 0x22, 0x3f, 0x84, 0x99, 0xbe, 0xa3, 0xf0, 0xed, 0xca, 0xd7, 0x35, 0x28, 0xf, 0x12, 0x41, 0x5c, 0x7b, 0x66, 0xdd, 0xc0, 0xe7, 0xfa, 0xa9, 0xb4, 0x93, 0x8e, 0xf8, 0xe5, 0xc2, 0xdf, 0x8c, 0x91, 0xb6, 0xab, 0x10, 0xd, 0x2a, 0x37, 0x64, 0x79, 0x5e, 0x43, 0xb2, 0xaf, 0x88, 0x95, 0xc6, 0xdb, 0xfc, 0xe1, 0x5a, 0x47, 0x60, 0x7d, 0x2e, 0x33, 0x14, 0x9, 0x7f, 0x62, 0x45, 0x58, 0xb, 0x16, 0x31, 0x2c, 0x97, 0x8a, 0xad, 0xb0, 0xe3, 0xfe, 0xd9, 0xc4, }; static uint8_t faad_check_CRC(bitfile *ld, uint16_t len) { int bytes, rem; unsigned int CRC; unsigned int r=255; /* Initialize to all ones */ /* CRC polynome used x^8 + x^4 + x^3 + x^2 +1 */ #define GPOLY 0435 faad_rewindbits(ld); CRC = (unsigned int) ~faad_getbits(ld, 8 DEBUGVAR(1,999,"faad_check_CRC(): CRC")) & 0xFF; /* CRC is stored inverted */ bytes = len >> 3; rem = len & 0x7; for (; bytes > 0; bytes--) { r = crc_table_G8[( r ^ faad_getbits(ld, 8 DEBUGVAR(1,998,"")) ) & 0xFF]; } for (; rem > 0; rem--) { r = ( (r << 1) ^ (( ( faad_get1bit(ld DEBUGVAR(1,998,"")) & 1) ^ ((r >> 7) & 1)) * GPOLY )) & 0xFF; } if (r != CRC) // if (0) { return 28; } else { return 0; } } static const uint8_t tabFlipbits[256] = { 0,128,64,192,32,160,96,224,16,144,80,208,48,176,112,240, 8,136,72,200,40,168,104,232,24,152,88,216,56,184,120,248, 4,132,68,196,36,164,100,228,20,148,84,212,52,180,116,244, 12,140,76,204,44,172,108,236,28,156,92,220,60,188,124,252, 2,130,66,194,34,162,98,226,18,146,82,210,50,178,114,242, 10,138,74,202,42,170,106,234,26,154,90,218,58,186,122,250, 6,134,70,198,38,166,102,230,22,150,86,214,54,182,118,246, 14,142,78,206,46,174,110,238,30,158,94,222,62,190,126,254, 1,129,65,193,33,161,97,225,17,145,81,209,49,177,113,241, 9,137,73,201,41,169,105,233,25,153,89,217,57,185,121,249, 5,133,69,197,37,165,101,229,21,149,85,213,53,181,117,245, 13,141,77,205,45,173,109,237,29,157,93,221,61,189,125,253, 3,131,67,195,35,163,99,227,19,147,83,211,51,179,115,243, 11,139,75,203,43,171,107,235,27,155,91,219,59,187,123,251, 7,135,71,199,39,167,103,231,23,151,87,215,55,183,119,247, 15,143,79,207,47,175,111,239,31,159,95,223,63,191,127,255 }; #endif #ifdef ERROR_RESILIENCE /* Modified bit reading functions for HCR */ typedef struct { /* bit input */ uint32_t bufa; uint32_t bufb; int8_t len; } bits_t; static INLINE uint32_t showbits_hcr(bits_t *ld, uint8_t bits) { if (bits == 0) return 0; if (ld->len <= 32) { /* huffman_spectral_data_2 needs to read more than may be available, bits maybe > ld->len, deliver 0 than */ if (ld->len >= bits) return ((ld->bufa >> (ld->len - bits)) & (0xFFFFFFFF >> (32 - bits))); else return ((ld->bufa << (bits - ld->len)) & (0xFFFFFFFF >> (32 - bits))); } else { if ((ld->len - bits) < 32) { return ( (ld->bufb & (0xFFFFFFFF >> (64 - ld->len))) << (bits - ld->len + 32)) | (ld->bufa >> (ld->len - bits)); } else { return ((ld->bufb >> (ld->len - bits - 32)) & (0xFFFFFFFF >> (32 - bits))); } } } /* return 1 if position is outside of buffer, 0 otherwise */ static INLINE int8_t flushbits_hcr( bits_t *ld, uint8_t bits) { ld->len -= bits; if (ld->len <0) { ld->len = 0; return 1; } else { return 0; } } static INLINE int8_t getbits_hcr(bits_t *ld, uint8_t n, uint32_t *result) { *result = showbits_hcr(ld, n); return flushbits_hcr(ld, n); } static INLINE int8_t get1bit_hcr(bits_t *ld, uint8_t *result) { uint32_t res; int8_t ret; ret = getbits_hcr(ld, 1, &res); *result = (int8_t)(res & 1); return ret; } #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ssr_fb.c0000644000175000017500000001531614647725152015336 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ssr_fb.c,v 1.17 2007/11/01 12:33:36 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SSR_DEC #include #include #include "syntax.h" #include "filtbank.h" #include "mdct.h" #include "ssr_fb.h" #include "ssr_win.h" fb_info *ssr_filter_bank_init(uint16_t frame_len) { uint16_t nshort = frame_len/8; fb_info *fb = (fb_info*)faad_malloc(sizeof(fb_info)); memset(fb, 0, sizeof(fb_info)); /* normal */ fb->mdct256 = faad_mdct_init(2*nshort); fb->mdct2048 = faad_mdct_init(2*frame_len); fb->long_window[0] = sine_long_256; fb->short_window[0] = sine_short_32; fb->long_window[1] = kbd_long_256; fb->short_window[1] = kbd_short_32; return fb; } void ssr_filter_bank_end(fb_info *fb) { faad_mdct_end(fb->mdct256); faad_mdct_end(fb->mdct2048); if (fb) faad_free(fb); } static INLINE void imdct_ssr(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t len) { mdct_info *mdct; switch (len) { case 512: mdct = fb->mdct2048; break; case 64: mdct = fb->mdct256; break; } faad_imdct(mdct, in_data, out_data); } /* NON-overlapping inverse filterbank for use with SSR */ void ssr_ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *freq_in, real_t *time_out, uint16_t frame_len) { int16_t i; real_t *transf_buf; const real_t *window_long; const real_t *window_long_prev; const real_t *window_short; const real_t *window_short_prev; uint16_t nlong = frame_len; uint16_t nshort = frame_len/8; uint16_t trans = nshort/2; uint16_t nflat_ls = (nlong-nshort)/2; transf_buf = (real_t*)faad_malloc(2*nlong*sizeof(real_t)); window_long = fb->long_window[window_shape]; window_long_prev = fb->long_window[window_shape_prev]; window_short = fb->short_window[window_shape]; window_short_prev = fb->short_window[window_shape_prev]; switch (window_sequence) { case ONLY_LONG_SEQUENCE: imdct_ssr(fb, freq_in, transf_buf, 2*nlong); for (i = nlong-1; i >= 0; i--) { time_out[i] = MUL_R_C(transf_buf[i],window_long_prev[i]); time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]); } break; case LONG_START_SEQUENCE: imdct_ssr(fb, freq_in, transf_buf, 2*nlong); for (i = 0; i < nlong; i++) time_out[i] = MUL_R_C(transf_buf[i],window_long_prev[i]); for (i = 0; i < nflat_ls; i++) time_out[nlong+i] = transf_buf[nlong+i]; for (i = 0; i < nshort; i++) time_out[nlong+nflat_ls+i] = MUL_R_C(transf_buf[nlong+nflat_ls+i],window_short[nshort-i-1]); for (i = 0; i < nflat_ls; i++) time_out[nlong+nflat_ls+nshort+i] = 0; break; case EIGHT_SHORT_SEQUENCE: imdct_ssr(fb, freq_in+0*nshort, transf_buf+2*nshort*0, 2*nshort); imdct_ssr(fb, freq_in+1*nshort, transf_buf+2*nshort*1, 2*nshort); imdct_ssr(fb, freq_in+2*nshort, transf_buf+2*nshort*2, 2*nshort); imdct_ssr(fb, freq_in+3*nshort, transf_buf+2*nshort*3, 2*nshort); imdct_ssr(fb, freq_in+4*nshort, transf_buf+2*nshort*4, 2*nshort); imdct_ssr(fb, freq_in+5*nshort, transf_buf+2*nshort*5, 2*nshort); imdct_ssr(fb, freq_in+6*nshort, transf_buf+2*nshort*6, 2*nshort); imdct_ssr(fb, freq_in+7*nshort, transf_buf+2*nshort*7, 2*nshort); for(i = nshort-1; i >= 0; i--) { time_out[i+0*nshort] = MUL_R_C(transf_buf[nshort*0+i],window_short_prev[i]); time_out[i+1*nshort] = MUL_R_C(transf_buf[nshort*1+i],window_short[i]); time_out[i+2*nshort] = MUL_R_C(transf_buf[nshort*2+i],window_short_prev[i]); time_out[i+3*nshort] = MUL_R_C(transf_buf[nshort*3+i],window_short[i]); time_out[i+4*nshort] = MUL_R_C(transf_buf[nshort*4+i],window_short_prev[i]); time_out[i+5*nshort] = MUL_R_C(transf_buf[nshort*5+i],window_short[i]); time_out[i+6*nshort] = MUL_R_C(transf_buf[nshort*6+i],window_short_prev[i]); time_out[i+7*nshort] = MUL_R_C(transf_buf[nshort*7+i],window_short[i]); time_out[i+8*nshort] = MUL_R_C(transf_buf[nshort*8+i],window_short_prev[i]); time_out[i+9*nshort] = MUL_R_C(transf_buf[nshort*9+i],window_short[i]); time_out[i+10*nshort] = MUL_R_C(transf_buf[nshort*10+i],window_short_prev[i]); time_out[i+11*nshort] = MUL_R_C(transf_buf[nshort*11+i],window_short[i]); time_out[i+12*nshort] = MUL_R_C(transf_buf[nshort*12+i],window_short_prev[i]); time_out[i+13*nshort] = MUL_R_C(transf_buf[nshort*13+i],window_short[i]); time_out[i+14*nshort] = MUL_R_C(transf_buf[nshort*14+i],window_short_prev[i]); time_out[i+15*nshort] = MUL_R_C(transf_buf[nshort*15+i],window_short[i]); } break; case LONG_STOP_SEQUENCE: imdct_ssr(fb, freq_in, transf_buf, 2*nlong); for (i = 0; i < nflat_ls; i++) time_out[i] = 0; for (i = 0; i < nshort; i++) time_out[nflat_ls+i] = MUL_R_C(transf_buf[nflat_ls+i],window_short_prev[i]); for (i = 0; i < nflat_ls; i++) time_out[nflat_ls+nshort+i] = transf_buf[nflat_ls+nshort+i]; for (i = 0; i < nlong; i++) time_out[nlong+i] = MUL_R_C(transf_buf[nlong+i],window_long[nlong-1-i]); break; } faad_free(transf_buf); } #endif xine-lib-1.2/contrib/libfaad/Makefile.am0000644000175000017500000000320214647725152015737 0ustar memeinclude $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) if ENABLE_FAAD if !WITH_EXTERNAL_FAAD noinst_LTLIBRARIES = libfaad.la endif endif libfaad_la_SOURCES = \ bits.c \ cfft.c \ common.c \ decoder.c \ drc.c \ drm_dec.c \ error.c \ filtbank.c \ hcr.c \ huffman.c \ ic_predict.c \ is.c \ lt_predict.c \ mdct.c \ mp4.c \ ms.c \ output.c \ pns.c \ ps_dec.c \ ps_syntax.c \ pulse.c \ rvlc.c \ sbr_dct.c \ sbr_dec.c \ sbr_e_nf.c \ sbr_fbt.c \ sbr_hfadj.c \ sbr_hfgen.c \ sbr_huff.c \ sbr_qmf.c \ sbr_syntax.c \ sbr_tf_grid.c \ specrec.c \ ssr.c \ ssr_fb.c \ ssr_ipqf.c \ syntax.c \ tns.c \ analysis.h \ bits.h \ cfft.h \ cfft_tab.h \ common.h \ drc.h \ drm_dec.h \ error.h \ filtbank.h \ fixed.h \ huffman.h \ ic_predict.h \ is.h \ iq_table.h \ kbd_win.h \ lt_predict.h \ mdct.h \ mdct_tab.h \ mp4.h \ ms.h \ output.h \ pns.h \ ps_dec.h \ ps_tables.h \ pulse.h \ rvlc.h \ sbr_dct.h \ sbr_dec.h \ sbr_e_nf.h \ sbr_fbt.h \ sbr_hfadj.h \ sbr_hfgen.h \ sbr_huff.h \ sbr_noise.h \ sbr_qmf.h \ sbr_qmf_c.h \ sbr_syntax.h \ sbr_tf_grid.h \ sine_win.h \ specrec.h \ ssr.h \ ssr_fb.h \ ssr_ipqf.h \ ssr_win.h \ structs.h \ syntax.h \ tns.h \ neaacdec.h \ codebook/hcb.h \ codebook/hcb_1.h \ codebook/hcb_2.h \ codebook/hcb_3.h \ codebook/hcb_4.h \ codebook/hcb_5.h \ codebook/hcb_6.h \ codebook/hcb_7.h \ codebook/hcb_8.h \ codebook/hcb_9.h \ codebook/hcb_10.h \ codebook/hcb_11.h \ codebook/hcb_sf.h libfaad_la_CFLAGS = $(AM_CFLAGS) libfaad_la_LIBADD = -lm xine-lib-1.2/contrib/libfaad/huffman.c0000644000175000017500000003650314647725152015505 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: huffman.c,v 1.26 2007/11/01 12:33:30 menno Exp $ **/ #include "common.h" #include "structs.h" #include #ifdef ANALYSIS #include #endif #include "bits.h" #include "huffman.h" #include "codebook/hcb.h" /* static function declarations */ static INLINE void huffman_sign_bits(bitfile *ld, int16_t *sp, uint8_t len); static INLINE int16_t huffman_getescape(bitfile *ld, int16_t sp); static uint8_t huffman_2step_quad(uint8_t cb, bitfile *ld, int16_t *sp); static uint8_t huffman_2step_quad_sign(uint8_t cb, bitfile *ld, int16_t *sp); static uint8_t huffman_2step_pair(uint8_t cb, bitfile *ld, int16_t *sp); static uint8_t huffman_2step_pair_sign(uint8_t cb, bitfile *ld, int16_t *sp); static uint8_t huffman_binary_quad(uint8_t cb, bitfile *ld, int16_t *sp); static uint8_t huffman_binary_quad_sign(uint8_t cb, bitfile *ld, int16_t *sp); static uint8_t huffman_binary_pair(uint8_t cb, bitfile *ld, int16_t *sp); static uint8_t huffman_binary_pair_sign(uint8_t cb, bitfile *ld, int16_t *sp); static int16_t huffman_codebook(uint8_t i); static void vcb11_check_LAV(uint8_t cb, int16_t *sp); int8_t huffman_scale_factor(bitfile *ld) { uint16_t offset = 0; while (hcb_sf[offset][1]) { uint8_t b = faad_get1bit(ld DEBUGVAR(1,255,"huffman_scale_factor()")); offset += hcb_sf[offset][b]; if (offset > 240) { /* printf("ERROR: offset into hcb_sf = %d >240!\n", offset); */ return -1; } } return hcb_sf[offset][0]; } static const hcb *hcb_table[] = { 0, hcb1_1, hcb2_1, 0, hcb4_1, 0, hcb6_1, 0, hcb8_1, 0, hcb10_1, hcb11_1 }; static const hcb_2_quad *hcb_2_quad_table[] = { 0, hcb1_2, hcb2_2, 0, hcb4_2, 0, 0, 0, 0, 0, 0, 0 }; static const hcb_2_pair *hcb_2_pair_table[] = { 0, 0, 0, 0, 0, 0, hcb6_2, 0, hcb8_2, 0, hcb10_2, hcb11_2 }; static const hcb_bin_pair *hcb_bin_table[] = { 0, 0, 0, 0, 0, hcb5, 0, hcb7, 0, hcb9, 0, 0 }; static const uint8_t hcbN[] = { 0, 5, 5, 0, 5, 0, 5, 0, 5, 0, 6, 5 }; /* defines whether a huffman codebook is unsigned or not */ /* Table 4.6.2 */ static const uint8_t unsigned_cb[] = { 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, /* codebook 16 to 31 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; static const int hcb_2_quad_table_size[] = { 0, 114, 86, 0, 185, 0, 0, 0, 0, 0, 0, 0 }; static const int hcb_2_pair_table_size[] = { 0, 0, 0, 0, 0, 0, 126, 0, 83, 0, 210, 373 }; static const int hcb_bin_table_size[] = { 0, 0, 0, 161, 0, 161, 0, 127, 0, 337, 0, 0 }; static INLINE void huffman_sign_bits(bitfile *ld, int16_t *sp, uint8_t len) { uint8_t i; for (i = 0; i < len; i++) { if(sp[i]) { if(faad_get1bit(ld DEBUGVAR(1,5,"huffman_sign_bits(): sign bit")) & 1) { sp[i] = -sp[i]; } } } } static INLINE int16_t huffman_getescape(bitfile *ld, int16_t sp) { uint8_t neg, i; int16_t j; int16_t off; if (sp < 0) { if (sp != -16) return sp; neg = 1; } else { if (sp != 16) return sp; neg = 0; } for (i = 4; ; i++) { if (faad_get1bit(ld DEBUGVAR(1,6,"huffman_getescape(): escape size")) == 0) { break; } } off = (int16_t)faad_getbits(ld, i DEBUGVAR(1,9,"huffman_getescape(): escape")); j = off | (1< hcb_2_quad_table_size[cb]) { /* printf("ERROR: offset into hcb_2_quad_table = %d >%d!\n", offset, hcb_2_quad_table_size[cb]); */ return 10; } sp[0] = hcb_2_quad_table[cb][offset].x; sp[1] = hcb_2_quad_table[cb][offset].y; sp[2] = hcb_2_quad_table[cb][offset].v; sp[3] = hcb_2_quad_table[cb][offset].w; return 0; } static uint8_t huffman_2step_quad_sign(uint8_t cb, bitfile *ld, int16_t *sp) { uint8_t err = huffman_2step_quad(cb, ld, sp); huffman_sign_bits(ld, sp, QUAD_LEN); return err; } static uint8_t huffman_2step_pair(uint8_t cb, bitfile *ld, int16_t *sp) { uint32_t cw; uint16_t offset = 0; uint8_t extra_bits; cw = faad_showbits(ld, hcbN[cb]); offset = hcb_table[cb][cw].offset; extra_bits = hcb_table[cb][cw].extra_bits; if (extra_bits) { /* we know for sure it's more than hcbN[cb] bits long */ faad_flushbits(ld, hcbN[cb]); offset += (uint16_t)faad_showbits(ld, extra_bits); faad_flushbits(ld, hcb_2_pair_table[cb][offset].bits - hcbN[cb]); } else { faad_flushbits(ld, hcb_2_pair_table[cb][offset].bits); } if (offset > hcb_2_pair_table_size[cb]) { /* printf("ERROR: offset into hcb_2_pair_table = %d >%d!\n", offset, hcb_2_pair_table_size[cb]); */ return 10; } sp[0] = hcb_2_pair_table[cb][offset].x; sp[1] = hcb_2_pair_table[cb][offset].y; return 0; } static uint8_t huffman_2step_pair_sign(uint8_t cb, bitfile *ld, int16_t *sp) { uint8_t err = huffman_2step_pair(cb, ld, sp); huffman_sign_bits(ld, sp, PAIR_LEN); return err; } static uint8_t huffman_binary_quad(uint8_t cb, bitfile *ld, int16_t *sp) { uint16_t offset = 0; while (!hcb3[offset].is_leaf) { uint8_t b = faad_get1bit(ld DEBUGVAR(1,255,"huffman_spectral_data():3")); offset += hcb3[offset].data[b]; } if (offset > hcb_bin_table_size[cb]) { /* printf("ERROR: offset into hcb_bin_table = %d >%d!\n", offset, hcb_bin_table_size[cb]); */ return 10; } sp[0] = hcb3[offset].data[0]; sp[1] = hcb3[offset].data[1]; sp[2] = hcb3[offset].data[2]; sp[3] = hcb3[offset].data[3]; return 0; } static uint8_t huffman_binary_quad_sign(uint8_t cb, bitfile *ld, int16_t *sp) { uint8_t err = huffman_binary_quad(cb, ld, sp); huffman_sign_bits(ld, sp, QUAD_LEN); return err; } static uint8_t huffman_binary_pair(uint8_t cb, bitfile *ld, int16_t *sp) { uint16_t offset = 0; while (!hcb_bin_table[cb][offset].is_leaf) { uint8_t b = faad_get1bit(ld DEBUGVAR(1,255,"huffman_spectral_data():9")); offset += hcb_bin_table[cb][offset].data[b]; } if (offset > hcb_bin_table_size[cb]) { /* printf("ERROR: offset into hcb_bin_table = %d >%d!\n", offset, hcb_bin_table_size[cb]); */ return 10; } sp[0] = hcb_bin_table[cb][offset].data[0]; sp[1] = hcb_bin_table[cb][offset].data[1]; return 0; } static uint8_t huffman_binary_pair_sign(uint8_t cb, bitfile *ld, int16_t *sp) { uint8_t err = huffman_binary_pair(cb, ld, sp); huffman_sign_bits(ld, sp, PAIR_LEN); return err; } static int16_t huffman_codebook(uint8_t i) { static const uint32_t data = 16428320; if (i == 0) return (int16_t)(data >> 16) & 0xFFFF; else return (int16_t)data & 0xFFFF; } static void vcb11_check_LAV(uint8_t cb, int16_t *sp) { static const uint16_t vcb11_LAV_tab[] = { 16, 31, 47, 63, 95, 127, 159, 191, 223, 255, 319, 383, 511, 767, 1023, 2047 }; uint16_t max = 0; if (cb < 16 || cb > 31) return; max = vcb11_LAV_tab[cb - 16]; if ((abs(sp[0]) > max) || (abs(sp[1]) > max)) { sp[0] = 0; sp[1] = 0; } } uint8_t huffman_spectral_data(uint8_t cb, bitfile *ld, int16_t *sp) { switch (cb) { case 1: /* 2-step method for data quadruples */ case 2: return huffman_2step_quad(cb, ld, sp); case 3: /* binary search for data quadruples */ return huffman_binary_quad_sign(cb, ld, sp); case 4: /* 2-step method for data quadruples */ return huffman_2step_quad_sign(cb, ld, sp); case 5: /* binary search for data pairs */ return huffman_binary_pair(cb, ld, sp); case 6: /* 2-step method for data pairs */ return huffman_2step_pair(cb, ld, sp); case 7: /* binary search for data pairs */ case 9: return huffman_binary_pair_sign(cb, ld, sp); case 8: /* 2-step method for data pairs */ case 10: return huffman_2step_pair_sign(cb, ld, sp); case 12: { uint8_t err = huffman_2step_pair(11, ld, sp); sp[0] = huffman_codebook(0); sp[1] = huffman_codebook(1); return err; } case 11: { uint8_t err = huffman_2step_pair_sign(11, ld, sp); sp[0] = huffman_getescape(ld, sp[0]); sp[1] = huffman_getescape(ld, sp[1]); return err; } #ifdef ERROR_RESILIENCE /* VCB11 uses codebook 11 */ case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: { uint8_t err = huffman_2step_pair_sign(11, ld, sp); sp[0] = huffman_getescape(ld, sp[0]); sp[1] = huffman_getescape(ld, sp[1]); /* check LAV (Largest Absolute Value) */ /* this finds errors in the ESCAPE signal */ vcb11_check_LAV(cb, sp); return err; } #endif default: /* Non existent codebook number, something went wrong */ return 11; } return 0; } #ifdef ERROR_RESILIENCE /* Special version of huffman_spectral_data Will not read from a bitfile but a bits_t structure. Will keep track of the bits decoded and return the number of bits remaining. Do not read more than ld->len, return -1 if codeword would be longer */ int8_t huffman_spectral_data_2(uint8_t cb, bits_t *ld, int16_t *sp) { uint32_t cw; uint16_t offset = 0; uint8_t extra_bits; uint8_t i, vcb11 = 0; switch (cb) { case 1: /* 2-step method for data quadruples */ case 2: case 4: cw = showbits_hcr(ld, hcbN[cb]); offset = hcb_table[cb][cw].offset; extra_bits = hcb_table[cb][cw].extra_bits; if (extra_bits) { /* we know for sure it's more than hcbN[cb] bits long */ if ( flushbits_hcr(ld, hcbN[cb]) ) return -1; offset += (uint16_t)showbits_hcr(ld, extra_bits); if ( flushbits_hcr(ld, hcb_2_quad_table[cb][offset].bits - hcbN[cb]) ) return -1; } else { if ( flushbits_hcr(ld, hcb_2_quad_table[cb][offset].bits) ) return -1; } sp[0] = hcb_2_quad_table[cb][offset].x; sp[1] = hcb_2_quad_table[cb][offset].y; sp[2] = hcb_2_quad_table[cb][offset].v; sp[3] = hcb_2_quad_table[cb][offset].w; break; case 6: /* 2-step method for data pairs */ case 8: case 10: case 11: /* VCB11 uses codebook 11 */ case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31: if (cb >= 16) { /* store the virtual codebook */ vcb11 = cb; cb = 11; } cw = showbits_hcr(ld, hcbN[cb]); offset = hcb_table[cb][cw].offset; extra_bits = hcb_table[cb][cw].extra_bits; if (extra_bits) { /* we know for sure it's more than hcbN[cb] bits long */ if ( flushbits_hcr(ld, hcbN[cb]) ) return -1; offset += (uint16_t)showbits_hcr(ld, extra_bits); if ( flushbits_hcr(ld, hcb_2_pair_table[cb][offset].bits - hcbN[cb]) ) return -1; } else { if ( flushbits_hcr(ld, hcb_2_pair_table[cb][offset].bits) ) return -1; } sp[0] = hcb_2_pair_table[cb][offset].x; sp[1] = hcb_2_pair_table[cb][offset].y; break; case 3: /* binary search for data quadruples */ while (!hcb3[offset].is_leaf) { uint8_t b; if ( get1bit_hcr(ld, &b) ) return -1; offset += hcb3[offset].data[b]; } sp[0] = hcb3[offset].data[0]; sp[1] = hcb3[offset].data[1]; sp[2] = hcb3[offset].data[2]; sp[3] = hcb3[offset].data[3]; break; case 5: /* binary search for data pairs */ case 7: case 9: while (!hcb_bin_table[cb][offset].is_leaf) { uint8_t b; if (get1bit_hcr(ld, &b) ) return -1; offset += hcb_bin_table[cb][offset].data[b]; } sp[0] = hcb_bin_table[cb][offset].data[0]; sp[1] = hcb_bin_table[cb][offset].data[1]; break; } /* decode sign bits */ if (unsigned_cb[cb]) { for(i = 0; i < ((cb < FIRST_PAIR_HCB) ? QUAD_LEN : PAIR_LEN); i++) { if(sp[i]) { uint8_t b; if ( get1bit_hcr(ld, &b) ) return -1; if (b != 0) { sp[i] = -sp[i]; } } } } /* decode huffman escape bits */ if ((cb == ESC_HCB) || (cb >= 16)) { uint8_t k; for (k = 0; k < 2; k++) { if ((sp[k] == 16) || (sp[k] == -16)) { uint8_t neg, i; int32_t j; uint32_t off; neg = (sp[k] < 0) ? 1 : 0; for (i = 4; ; i++) { uint8_t b; if (get1bit_hcr(ld, &b)) return -1; if (b == 0) break; } if (getbits_hcr(ld, i, &off)) return -1; j = off + (1<len; } #endif xine-lib-1.2/contrib/libfaad/cfft.h0000644000175000017500000000321214647725152014777 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: cfft.h,v 1.24 2007/11/01 12:33:29 menno Exp $ **/ #ifndef __CFFT_H__ #define __CFFT_H__ #ifdef __cplusplus extern "C" { #endif typedef struct { uint16_t n; uint16_t ifac[15]; complex_t *work; complex_t *tab; } cfft_info; void cfftf(cfft_info *cfft, complex_t *c); void cfftb(cfft_info *cfft, complex_t *c); cfft_info *cffti(uint16_t n); void cfftu(cfft_info *cfft); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_dct.h0000644000175000017500000000334314647725151015501 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_dct.h,v 1.19 2007/11/01 12:33:34 menno Exp $ **/ #ifndef __SBR_DCT_H__ #define __SBR_DCT_H__ #ifdef __cplusplus extern "C" { #endif void dct4_kernel(real_t * in_real, real_t * in_imag, real_t * out_real, real_t * out_imag); void DCT3_32_unscaled(real_t *y, real_t *x); void DCT4_32(real_t *y, real_t *x); void DST4_32(real_t *y, real_t *x); void DCT2_32_unscaled(real_t *y, real_t *x); void DCT4_16(real_t *y, real_t *x); void DCT2_16_unscaled(real_t *y, real_t *x); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ssr_fb.h0000644000175000017500000000351314647725152015337 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. ** ** $Id: ssr_fb.h,v 1.16 2007/11/01 12:33:36 menno Exp $ **/ #ifndef __SSR_FB_H__ #define __SSR_FB_H__ #ifdef __cplusplus extern "C" { #endif fb_info *ssr_filter_bank_init(uint16_t frame_len); void ssr_filter_bank_end(fb_info *fb); /*non overlapping inverse filterbank */ void ssr_ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *freq_in, real_t *time_out, uint16_t frame_len); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/pns.h0000644000175000017500000000352414647725152014663 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: pns.h,v 1.27 2007/11/01 12:33:33 menno Exp $ **/ #ifndef __PNS_H__ #define __PNS_H__ #ifdef __cplusplus extern "C" { #endif #include "syntax.h" #define NOISE_OFFSET 90 void pns_decode(ic_stream *ics_left, ic_stream *ics_right, real_t *spec_left, real_t *spec_right, uint16_t frame_len, uint8_t channel_pair, uint8_t object_type, /* RNG states */ uint32_t *__r1, uint32_t *__r2); static INLINE uint8_t is_noise(ic_stream *ics, uint8_t group, uint8_t sfb) { if (ics->sfb_cb[group][sfb] == NOISE_HCB) return 1; return 0; } #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/mp4.h0000644000175000017500000000353114647725152014561 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: mp4.h,v 1.28 2009/02/05 00:51:03 menno Exp $ **/ #ifndef __MP4_H__ #define __MP4_H__ #ifdef __cplusplus extern "C" { #endif #include "neaacdec.h" int8_t AudioSpecificConfig2(uint8_t *pBuffer, uint32_t buffer_size, mp4AudioSpecificConfig *mp4ASC, program_config *pce, uint8_t short_form); int8_t AudioSpecificConfigFromBitfile(bitfile *ld, mp4AudioSpecificConfig *mp4ASC, program_config *pce, uint32_t bsize, uint8_t short_form); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ps_dec.h0000644000175000017500000001017714647725151015321 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ps_dec.h,v 1.13 2009/01/26 22:32:31 menno Exp $ **/ #ifndef __PS_DEC_H__ #define __PS_DEC_H__ #ifdef __cplusplus extern "C" { #endif #include "bits.h" #define EXTENSION_ID_PS 2 #define MAX_PS_ENVELOPES 5 #define NO_ALLPASS_LINKS 3 typedef struct { /* bitstream parameters */ uint8_t enable_iid; uint8_t enable_icc; uint8_t enable_ext; uint8_t iid_mode; uint8_t icc_mode; uint8_t nr_iid_par; uint8_t nr_ipdopd_par; uint8_t nr_icc_par; uint8_t frame_class; uint8_t num_env; uint8_t border_position[MAX_PS_ENVELOPES+1]; uint8_t iid_dt[MAX_PS_ENVELOPES]; uint8_t icc_dt[MAX_PS_ENVELOPES]; uint8_t enable_ipdopd; uint8_t ipd_mode; uint8_t ipd_dt[MAX_PS_ENVELOPES]; uint8_t opd_dt[MAX_PS_ENVELOPES]; /* indices */ int8_t iid_index_prev[34]; int8_t icc_index_prev[34]; int8_t ipd_index_prev[17]; int8_t opd_index_prev[17]; int8_t iid_index[MAX_PS_ENVELOPES][34]; int8_t icc_index[MAX_PS_ENVELOPES][34]; int8_t ipd_index[MAX_PS_ENVELOPES][17]; int8_t opd_index[MAX_PS_ENVELOPES][17]; int8_t ipd_index_1[17]; int8_t opd_index_1[17]; int8_t ipd_index_2[17]; int8_t opd_index_2[17]; /* ps data was correctly read */ uint8_t ps_data_available; /* a header has been read */ uint8_t header_read; /* hybrid filterbank parameters */ void *hyb; uint8_t use34hybrid_bands; uint8_t numTimeSlotsRate; /**/ uint8_t num_groups; uint8_t num_hybrid_groups; uint8_t nr_par_bands; uint8_t nr_allpass_bands; uint8_t decay_cutoff; uint8_t *group_border; uint16_t *map_group2bk; /* filter delay handling */ uint8_t saved_delay; uint8_t delay_buf_index_ser[NO_ALLPASS_LINKS]; uint8_t num_sample_delay_ser[NO_ALLPASS_LINKS]; uint8_t delay_D[64]; uint8_t delay_buf_index_delay[64]; complex_t delay_Qmf[14][64]; /* 14 samples delay max, 64 QMF channels */ complex_t delay_SubQmf[2][32]; /* 2 samples delay max (SubQmf is always allpass filtered) */ complex_t delay_Qmf_ser[NO_ALLPASS_LINKS][5][64]; /* 5 samples delay max (table 8.34), 64 QMF channels */ complex_t delay_SubQmf_ser[NO_ALLPASS_LINKS][5][32]; /* 5 samples delay max (table 8.34) */ /* transients */ real_t alpha_decay; real_t alpha_smooth; real_t P_PeakDecayNrg[34]; real_t P_prev[34]; real_t P_SmoothPeakDecayDiffNrg_prev[34]; /* mixing and phase */ complex_t h11_prev[50]; complex_t h12_prev[50]; complex_t h21_prev[50]; complex_t h22_prev[50]; uint8_t phase_hist; complex_t ipd_prev[20][2]; complex_t opd_prev[20][2]; } ps_info; /* ps_syntax.c */ uint16_t ps_data(ps_info *ps, bitfile *ld, uint8_t *header); /* ps_dec.c */ ps_info *ps_init(uint8_t sr_index, uint8_t numTimeSlotsRate); void ps_free(ps_info *ps); uint8_t ps_decode(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/specrec.c0000644000175000017500000013206214647725152015502 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: specrec.c,v 1.62 2009/01/26 23:51:15 menno Exp $ **/ /* Spectral reconstruction: - grouping/sectioning - inverse quantization - applying scalefactors */ #include "common.h" #include "structs.h" #include #include #include "specrec.h" #include "filtbank.h" #include "syntax.h" #include "iq_table.h" #include "ms.h" #include "is.h" #include "pns.h" #include "tns.h" #include "drc.h" #include "lt_predict.h" #include "ic_predict.h" #ifdef SSR_DEC #include "ssr.h" #include "ssr_fb.h" #endif /* static function declarations */ static uint8_t quant_to_spec(NeAACDecStruct *hDecoder, ic_stream *ics, int16_t *quant_data, real_t *spec_data, uint16_t frame_len); #ifdef LD_DEC ALIGN static const uint8_t num_swb_512_window[] = { 0, 0, 0, 36, 36, 37, 31, 31, 0, 0, 0, 0 }; ALIGN static const uint8_t num_swb_480_window[] = { 0, 0, 0, 35, 35, 37, 30, 30, 0, 0, 0, 0 }; #endif ALIGN static const uint8_t num_swb_960_window[] = { 40, 40, 45, 49, 49, 49, 46, 46, 42, 42, 42, 40 }; ALIGN static const uint8_t num_swb_1024_window[] = { 41, 41, 47, 49, 49, 51, 47, 47, 43, 43, 43, 40 }; ALIGN static const uint8_t num_swb_128_window[] = { 12, 12, 12, 14, 14, 14, 15, 15, 15, 15, 15, 15 }; ALIGN 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 }; ALIGN static const uint16_t swb_offset_128_96[] = { 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128 }; ALIGN 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 }; ALIGN static const uint16_t swb_offset_128_64[] = { 0, 4, 8, 12, 16, 20, 24, 32, 40, 48, 64, 92, 128 }; ALIGN 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 }; #ifdef LD_DEC ALIGN 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 }; ALIGN 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 }; #endif ALIGN static const uint16_t swb_offset_128_48[] = { 0, 4, 8, 12, 16, 20, 28, 36, 44, 56, 68, 80, 96, 112, 128 }; ALIGN 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 }; #ifdef LD_DEC ALIGN 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 }; ALIGN 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 }; #endif ALIGN 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 }; #ifdef LD_DEC ALIGN 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 }; ALIGN 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 }; #endif ALIGN static const uint16_t swb_offset_128_24[] = { 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 64, 76, 92, 108, 128 }; ALIGN 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 }; ALIGN static const uint16_t swb_offset_128_16[] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 60, 72, 88, 108, 128 }; ALIGN 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 }; ALIGN static const uint16_t swb_offset_128_8[] = { 0, 4, 8, 12, 16, 20, 24, 28, 36, 44, 52, 60, 72, 88, 108, 128 }; ALIGN static const uint16_t *swb_offset_1024_window[] = { swb_offset_1024_96, /* 96000 */ swb_offset_1024_96, /* 88200 */ swb_offset_1024_64, /* 64000 */ swb_offset_1024_48, /* 48000 */ swb_offset_1024_48, /* 44100 */ swb_offset_1024_32, /* 32000 */ swb_offset_1024_24, /* 24000 */ swb_offset_1024_24, /* 22050 */ swb_offset_1024_16, /* 16000 */ swb_offset_1024_16, /* 12000 */ swb_offset_1024_16, /* 11025 */ swb_offset_1024_8 /* 8000 */ }; #ifdef LD_DEC ALIGN static const uint16_t *swb_offset_512_window[] = { 0, /* 96000 */ 0, /* 88200 */ 0, /* 64000 */ swb_offset_512_48, /* 48000 */ swb_offset_512_48, /* 44100 */ swb_offset_512_32, /* 32000 */ swb_offset_512_24, /* 24000 */ swb_offset_512_24, /* 22050 */ 0, /* 16000 */ 0, /* 12000 */ 0, /* 11025 */ 0 /* 8000 */ }; ALIGN static const uint16_t *swb_offset_480_window[] = { 0, /* 96000 */ 0, /* 88200 */ 0, /* 64000 */ swb_offset_480_48, /* 48000 */ swb_offset_480_48, /* 44100 */ swb_offset_480_32, /* 32000 */ swb_offset_480_24, /* 24000 */ swb_offset_480_24, /* 22050 */ 0, /* 16000 */ 0, /* 12000 */ 0, /* 11025 */ 0 /* 8000 */ }; #endif ALIGN static const uint16_t *swb_offset_128_window[] = { swb_offset_128_96, /* 96000 */ swb_offset_128_96, /* 88200 */ swb_offset_128_64, /* 64000 */ swb_offset_128_48, /* 48000 */ swb_offset_128_48, /* 44100 */ swb_offset_128_48, /* 32000 */ swb_offset_128_24, /* 24000 */ swb_offset_128_24, /* 22050 */ swb_offset_128_16, /* 16000 */ swb_offset_128_16, /* 12000 */ swb_offset_128_16, /* 11025 */ swb_offset_128_8 /* 8000 */ }; #define bit_set(A, B) ((A) & (1<<(B))) /* 4.5.2.3.4 */ /* - determine the number of windows in a window_sequence named num_windows - determine the number of window_groups named num_window_groups - determine the number of windows in each group named window_group_length[g] - determine the total number of scalefactor window bands named num_swb for the actual window type - determine swb_offset[swb], the offset of the first coefficient in scalefactor window band named swb of the window actually used - determine sect_sfb_offset[g][section],the offset of the first coefficient in section named section. This offset depends on window_sequence and scale_factor_grouping and is needed to decode the spectral_data(). */ uint8_t window_grouping_info(NeAACDecStruct *hDecoder, ic_stream *ics) { uint8_t i, g; uint8_t sf_index = hDecoder->sf_index; switch (ics->window_sequence) { case ONLY_LONG_SEQUENCE: case LONG_START_SEQUENCE: case LONG_STOP_SEQUENCE: ics->num_windows = 1; ics->num_window_groups = 1; ics->window_group_length[ics->num_window_groups-1] = 1; #ifdef LD_DEC if (hDecoder->object_type == LD) { if (hDecoder->frameLength == 512) ics->num_swb = num_swb_512_window[sf_index]; else /* if (hDecoder->frameLength == 480) */ ics->num_swb = num_swb_480_window[sf_index]; } else #endif { if (hDecoder->frameLength == 1024) ics->num_swb = num_swb_1024_window[sf_index]; else /* if (hDecoder->frameLength == 960) */ ics->num_swb = num_swb_960_window[sf_index]; } if (ics->max_sfb > ics->num_swb) { return 32; } /* preparation of sect_sfb_offset for long blocks */ /* also copy the last value! */ #ifdef LD_DEC if (hDecoder->object_type == LD) { if (hDecoder->frameLength == 512) { for (i = 0; i < ics->num_swb; i++) { ics->sect_sfb_offset[0][i] = swb_offset_512_window[sf_index][i]; ics->swb_offset[i] = swb_offset_512_window[sf_index][i]; } } else /* if (hDecoder->frameLength == 480) */ { for (i = 0; i < ics->num_swb; i++) { ics->sect_sfb_offset[0][i] = swb_offset_480_window[sf_index][i]; ics->swb_offset[i] = swb_offset_480_window[sf_index][i]; } } ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength; ics->swb_offset[ics->num_swb] = hDecoder->frameLength; ics->swb_offset_max = hDecoder->frameLength; } else #endif { for (i = 0; i < ics->num_swb; i++) { ics->sect_sfb_offset[0][i] = swb_offset_1024_window[sf_index][i]; ics->swb_offset[i] = swb_offset_1024_window[sf_index][i]; } ics->sect_sfb_offset[0][ics->num_swb] = hDecoder->frameLength; ics->swb_offset[ics->num_swb] = hDecoder->frameLength; ics->swb_offset_max = hDecoder->frameLength; } return 0; case EIGHT_SHORT_SEQUENCE: ics->num_windows = 8; ics->num_window_groups = 1; ics->window_group_length[ics->num_window_groups-1] = 1; ics->num_swb = num_swb_128_window[sf_index]; if (ics->max_sfb > ics->num_swb) { return 32; } for (i = 0; i < ics->num_swb; i++) ics->swb_offset[i] = swb_offset_128_window[sf_index][i]; ics->swb_offset[ics->num_swb] = hDecoder->frameLength/8; ics->swb_offset_max = hDecoder->frameLength/8; for (i = 0; i < ics->num_windows-1; i++) { if (bit_set(ics->scale_factor_grouping, 6-i) == 0) { ics->num_window_groups += 1; ics->window_group_length[ics->num_window_groups-1] = 1; } else { ics->window_group_length[ics->num_window_groups-1] += 1; } } /* preparation of sect_sfb_offset for short blocks */ for (g = 0; g < ics->num_window_groups; g++) { uint16_t width; uint8_t sect_sfb = 0; uint16_t offset = 0; for (i = 0; i < ics->num_swb; i++) { if (i+1 == ics->num_swb) { width = (hDecoder->frameLength/8) - swb_offset_128_window[sf_index][i]; } else { width = swb_offset_128_window[sf_index][i+1] - swb_offset_128_window[sf_index][i]; } width *= ics->window_group_length[g]; ics->sect_sfb_offset[g][sect_sfb++] = offset; offset += width; } ics->sect_sfb_offset[g][sect_sfb] = offset; } return 0; default: return 32; } } /* iquant() */ /* output = sign(input)*abs(input)^(4/3) */ /**/ static INLINE real_t iquant(int16_t q, const real_t *tab, uint8_t *error) { #ifdef FIXED_POINT /* For FIXED_POINT the iq_table is prescaled by 3 bits (iq_table[]/8) */ /* BIG_IQ_TABLE allows you to use the full 8192 value table, if this is not * defined a 1026 value table and interpolation will be used */ #ifndef BIG_IQ_TABLE static const real_t errcorr[] = { REAL_CONST(0), REAL_CONST(1.0/8.0), REAL_CONST(2.0/8.0), REAL_CONST(3.0/8.0), REAL_CONST(4.0/8.0), REAL_CONST(5.0/8.0), REAL_CONST(6.0/8.0), REAL_CONST(7.0/8.0), REAL_CONST(0) }; real_t x1, x2; #endif int16_t sgn = 1; if (q < 0) { q = -q; sgn = -1; } if (q < IQ_TABLE_SIZE) { //#define IQUANT_PRINT #ifdef IQUANT_PRINT //printf("0x%.8X\n", sgn * tab[q]); printf("%d\n", sgn * tab[q]); #endif return sgn * tab[q]; } #ifndef BIG_IQ_TABLE if (q >= 8192) { *error = 17; return 0; } /* linear interpolation */ x1 = tab[q>>3]; x2 = tab[(q>>3) + 1]; return sgn * 16 * (MUL_R(errcorr[q&7],(x2-x1)) + x1); #else *error = 17; return 0; #endif #else if (q < 0) { /* tab contains a value for all possible q [0,8192] */ if (-q < IQ_TABLE_SIZE) return -tab[-q]; *error = 17; return 0; } else { /* tab contains a value for all possible q [0,8192] */ if (q < IQ_TABLE_SIZE) return tab[q]; *error = 17; return 0; } #endif } #ifndef FIXED_POINT ALIGN static const real_t pow2sf_tab[] = { 2.9802322387695313E-008, 5.9604644775390625E-008, 1.1920928955078125E-007, 2.384185791015625E-007, 4.76837158203125E-007, 9.5367431640625E-007, 1.9073486328125E-006, 3.814697265625E-006, 7.62939453125E-006, 1.52587890625E-005, 3.0517578125E-005, 6.103515625E-005, 0.0001220703125, 0.000244140625, 0.00048828125, 0.0009765625, 0.001953125, 0.00390625, 0.0078125, 0.015625, 0.03125, 0.0625, 0.125, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0, 16.0, 32.0, 64.0, 128.0, 256.0, 512.0, 1024.0, 2048.0, 4096.0, 8192.0, 16384.0, 32768.0, 65536.0, 131072.0, 262144.0, 524288.0, 1048576.0, 2097152.0, 4194304.0, 8388608.0, 16777216.0, 33554432.0, 67108864.0, 134217728.0, 268435456.0, 536870912.0, 1073741824.0, 2147483648.0, 4294967296.0, 8589934592.0, 17179869184.0, 34359738368.0, 68719476736.0, 137438953472.0, 274877906944.0 }; #endif /* quant_to_spec: perform dequantisation and scaling * and in case of short block it also does the deinterleaving */ /* For ONLY_LONG_SEQUENCE windows (num_window_groups = 1, window_group_length[0] = 1) the spectral data is in ascending spectral order. For the EIGHT_SHORT_SEQUENCE window, the spectral order depends on the grouping in the following manner: - Groups are ordered sequentially - Within a group, a scalefactor band consists of the spectral data of all grouped SHORT_WINDOWs for the associated scalefactor window band. To clarify via example, the length of a group is in the range of one to eight SHORT_WINDOWs. - If there are eight groups each with length one (num_window_groups = 8, window_group_length[0..7] = 1), the result is a sequence of eight spectra, each in ascending spectral order. - If there is only one group with length eight (num_window_groups = 1, window_group_length[0] = 8), the result is that spectral data of all eight SHORT_WINDOWs is interleaved by scalefactor window bands. - Within a scalefactor window band, the coefficients are in ascending spectral order. */ static uint8_t quant_to_spec(NeAACDecStruct *hDecoder, ic_stream *ics, int16_t *quant_data, real_t *spec_data, uint16_t frame_len) { ALIGN static const real_t pow2_table[] = { COEF_CONST(1.0), COEF_CONST(1.1892071150027210667174999705605), /* 2^0.25 */ COEF_CONST(1.4142135623730950488016887242097), /* 2^0.5 */ COEF_CONST(1.6817928305074290860622509524664) /* 2^0.75 */ }; const real_t *tab = iq_table; uint8_t g, sfb, win; uint16_t width, bin, k, gindex, wa, wb; uint8_t error = 0; /* Init error flag */ #ifndef FIXED_POINT real_t scf; #endif (void)frame_len; /* FIXME: check */ k = 0; gindex = 0; for (g = 0; g < ics->num_window_groups; g++) { uint16_t j = 0; uint16_t gincrease = 0; uint16_t win_inc = ics->swb_offset[ics->num_swb]; for (sfb = 0; sfb < ics->num_swb; sfb++) { int32_t exp, frac; width = ics->swb_offset[sfb+1] - ics->swb_offset[sfb]; /* this could be scalefactor for IS or PNS, those can be negative or bigger then 255 */ /* just ignore them */ if (ics->scale_factors[g][sfb] < 0 || ics->scale_factors[g][sfb] > 255) { exp = 0; frac = 0; } else { /* ics->scale_factors[g][sfb] must be between 0 and 255 */ exp = (ics->scale_factors[g][sfb] /* - 100 */) >> 2; /* frac must always be > 0 */ frac = (ics->scale_factors[g][sfb] /* - 100 */) & 3; } #ifdef FIXED_POINT exp -= 25; /* IMDCT pre-scaling */ if (hDecoder->object_type == LD) { exp -= 6 /*9*/; } else { if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) exp -= 4 /*7*/; else exp -= 7 /*10*/; } #else (void)hDecoder; #endif wa = gindex + j; #ifndef FIXED_POINT scf = pow2sf_tab[exp/*+25*/] * pow2_table[frac]; #endif for (win = 0; win < ics->window_group_length[g]; win++) { for (bin = 0; bin < width; bin += 4) { #ifndef FIXED_POINT wb = wa + bin; spec_data[wb+0] = iquant(quant_data[k+0], tab, &error) * scf; spec_data[wb+1] = iquant(quant_data[k+1], tab, &error) * scf; spec_data[wb+2] = iquant(quant_data[k+2], tab, &error) * scf; spec_data[wb+3] = iquant(quant_data[k+3], tab, &error) * scf; #else real_t iq0 = iquant(quant_data[k+0], tab, &error); real_t iq1 = iquant(quant_data[k+1], tab, &error); real_t iq2 = iquant(quant_data[k+2], tab, &error); real_t iq3 = iquant(quant_data[k+3], tab, &error); wb = wa + bin; if (exp < 0) { spec_data[wb+0] = iq0 >>= -exp; spec_data[wb+1] = iq1 >>= -exp; spec_data[wb+2] = iq2 >>= -exp; spec_data[wb+3] = iq3 >>= -exp; } else { spec_data[wb+0] = iq0 <<= exp; spec_data[wb+1] = iq1 <<= exp; spec_data[wb+2] = iq2 <<= exp; spec_data[wb+3] = iq3 <<= exp; } if (frac != 0) { spec_data[wb+0] = MUL_C(spec_data[wb+0],pow2_table[frac]); spec_data[wb+1] = MUL_C(spec_data[wb+1],pow2_table[frac]); spec_data[wb+2] = MUL_C(spec_data[wb+2],pow2_table[frac]); spec_data[wb+3] = MUL_C(spec_data[wb+3],pow2_table[frac]); } //#define SCFS_PRINT #ifdef SCFS_PRINT printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+0]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+1]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+2]); printf("%d\n", spec_data[gindex+(win*win_inc)+j+bin+3]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+0]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+1]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+2]); //printf("0x%.8X\n", spec_data[gindex+(win*win_inc)+j+bin+3]); #endif #endif gincrease += 4; k += 4; } wa += win_inc; } j += width; } gindex += gincrease; } return error; } static uint8_t allocate_single_channel(NeAACDecStruct *hDecoder, uint8_t channel, uint8_t output_channels) { int mul = 1; #ifdef MAIN_DEC /* MAIN object type prediction */ if (hDecoder->object_type == MAIN) { /* allocate the state only when needed */ if (hDecoder->pred_stat[channel] != NULL) { faad_free(hDecoder->pred_stat[channel]); hDecoder->pred_stat[channel] = NULL; } hDecoder->pred_stat[channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state)); reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength); } #endif #ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { /* allocate the state only when needed */ if (hDecoder->lt_pred_stat[channel] != NULL) { faad_free(hDecoder->lt_pred_stat[channel]); hDecoder->lt_pred_stat[channel] = NULL; } hDecoder->lt_pred_stat[channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t)); memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t)); } #endif if (hDecoder->time_out[channel] != NULL) { faad_free(hDecoder->time_out[channel]); hDecoder->time_out[channel] = NULL; } { mul = 1; #ifdef SBR_DEC hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 0; if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) { /* SBR requires 2 times as much output data */ mul = 2; hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 1; } #endif hDecoder->time_out[channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[channel], 0, mul*hDecoder->frameLength*sizeof(real_t)); } #if (defined(PS_DEC) || defined(DRM_PS)) if (output_channels == 2) { if (hDecoder->time_out[channel+1] != NULL) { faad_free(hDecoder->time_out[channel+1]); hDecoder->time_out[channel+1] = NULL; } hDecoder->time_out[channel+1] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[channel+1], 0, mul*hDecoder->frameLength*sizeof(real_t)); } #endif if (hDecoder->fb_intermed[channel] != NULL) { faad_free(hDecoder->fb_intermed[channel]); hDecoder->fb_intermed[channel] = NULL; } hDecoder->fb_intermed[channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t)); #ifdef SSR_DEC if (hDecoder->object_type == SSR) { if (hDecoder->ssr_overlap[channel] == NULL) { hDecoder->ssr_overlap[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->ssr_overlap[channel], 0, 2*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->prev_fmd[channel] == NULL) { uint16_t k; hDecoder->prev_fmd[channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); for (k = 0; k < 2*hDecoder->frameLength; k++) hDecoder->prev_fmd[channel][k] = REAL_CONST(-1); } } #endif return 0; } static uint8_t allocate_channel_pair(NeAACDecStruct *hDecoder, uint8_t channel, uint8_t paired_channel) { int mul = 1; #ifdef MAIN_DEC /* MAIN object type prediction */ if (hDecoder->object_type == MAIN) { /* allocate the state only when needed */ if (hDecoder->pred_stat[channel] == NULL) { hDecoder->pred_stat[channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state)); reset_all_predictors(hDecoder->pred_stat[channel], hDecoder->frameLength); } if (hDecoder->pred_stat[paired_channel] == NULL) { hDecoder->pred_stat[paired_channel] = (pred_state*)faad_malloc(hDecoder->frameLength * sizeof(pred_state)); reset_all_predictors(hDecoder->pred_stat[paired_channel], hDecoder->frameLength); } } #endif #ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { /* allocate the state only when needed */ if (hDecoder->lt_pred_stat[channel] == NULL) { hDecoder->lt_pred_stat[channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t)); memset(hDecoder->lt_pred_stat[channel], 0, hDecoder->frameLength*4 * sizeof(int16_t)); } if (hDecoder->lt_pred_stat[paired_channel] == NULL) { hDecoder->lt_pred_stat[paired_channel] = (int16_t*)faad_malloc(hDecoder->frameLength*4 * sizeof(int16_t)); memset(hDecoder->lt_pred_stat[paired_channel], 0, hDecoder->frameLength*4 * sizeof(int16_t)); } } #endif if (hDecoder->time_out[channel] == NULL) { mul = 1; #ifdef SBR_DEC hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 0; if ((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) { /* SBR requires 2 times as much output data */ mul = 2; hDecoder->sbr_alloced[hDecoder->fr_ch_ele] = 1; } #endif hDecoder->time_out[channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[channel], 0, mul*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->time_out[paired_channel] == NULL) { hDecoder->time_out[paired_channel] = (real_t*)faad_malloc(mul*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->time_out[paired_channel], 0, mul*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->fb_intermed[channel] == NULL) { hDecoder->fb_intermed[channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->fb_intermed[channel], 0, hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->fb_intermed[paired_channel] == NULL) { hDecoder->fb_intermed[paired_channel] = (real_t*)faad_malloc(hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->fb_intermed[paired_channel], 0, hDecoder->frameLength*sizeof(real_t)); } #ifdef SSR_DEC if (hDecoder->object_type == SSR) { if (hDecoder->ssr_overlap[cpe->channel] == NULL) { hDecoder->ssr_overlap[cpe->channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->ssr_overlap[cpe->channel], 0, 2*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->ssr_overlap[cpe->paired_channel] == NULL) { hDecoder->ssr_overlap[cpe->paired_channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); memset(hDecoder->ssr_overlap[cpe->paired_channel], 0, 2*hDecoder->frameLength*sizeof(real_t)); } if (hDecoder->prev_fmd[cpe->channel] == NULL) { uint16_t k; hDecoder->prev_fmd[cpe->channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); for (k = 0; k < 2*hDecoder->frameLength; k++) hDecoder->prev_fmd[cpe->channel][k] = REAL_CONST(-1); } if (hDecoder->prev_fmd[cpe->paired_channel] == NULL) { uint16_t k; hDecoder->prev_fmd[cpe->paired_channel] = (real_t*)faad_malloc(2*hDecoder->frameLength*sizeof(real_t)); for (k = 0; k < 2*hDecoder->frameLength; k++) hDecoder->prev_fmd[cpe->paired_channel][k] = REAL_CONST(-1); } } #endif return 0; } uint8_t reconstruct_single_channel(NeAACDecStruct *hDecoder, ic_stream *ics, element *sce, int16_t *spec_data) { uint8_t retval; int output_channels; ALIGN real_t spec_coef[1024]; #ifdef PROFILE int64_t count = faad_get_ts(); #endif /* always allocate 2 channels, PS can always "suddenly" turn up */ #if ( (defined(DRM) && defined(DRM_PS)) ) output_channels = 2; #elif defined(PS_DEC) if (hDecoder->ps_used[hDecoder->fr_ch_ele]) output_channels = 2; else output_channels = 1; #else output_channels = 1; #endif if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 0) { /* element_output_channels not set yet */ hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels; } else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != output_channels) { /* element inconsistency */ /* this only happens if PS is actually found but not in the first frame * this means that there is only 1 bitstream element! */ /* reset the allocation */ hDecoder->element_alloced[hDecoder->fr_ch_ele] = 0; hDecoder->element_output_channels[hDecoder->fr_ch_ele] = output_channels; //return 21; } if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0) { retval = allocate_single_channel(hDecoder, sce->channel, output_channels); if (retval > 0) return retval; hDecoder->element_alloced[hDecoder->fr_ch_ele] = 1; } /* dequantisation and scaling */ retval = quant_to_spec(hDecoder, ics, spec_data, spec_coef, hDecoder->frameLength); if (retval > 0) return retval; #ifdef PROFILE count = faad_get_ts() - count; hDecoder->requant_cycles += count; #endif /* pns decoding */ pns_decode(ics, NULL, spec_coef, NULL, hDecoder->frameLength, 0, hDecoder->object_type, &(hDecoder->__r1), &(hDecoder->__r2)); #ifdef MAIN_DEC /* MAIN object type prediction */ if (hDecoder->object_type == MAIN) { if (!hDecoder->pred_stat[sce->channel]) return 33; /* intra channel prediction */ ic_prediction(ics, spec_coef, hDecoder->pred_stat[sce->channel], hDecoder->frameLength, hDecoder->sf_index); /* In addition, for scalefactor bands coded by perceptual noise substitution the predictors belonging to the corresponding spectral coefficients are reset. */ pns_reset_pred_state(ics, hDecoder->pred_stat[sce->channel]); } #endif #ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { #ifdef LD_DEC if (hDecoder->object_type == LD) { if (ics->ltp.data_present) { if (ics->ltp.lag_update) hDecoder->ltp_lag[sce->channel] = ics->ltp.lag; } ics->ltp.lag = hDecoder->ltp_lag[sce->channel]; } #endif /* long term prediction */ lt_prediction(ics, &(ics->ltp), spec_coef, hDecoder->lt_pred_stat[sce->channel], hDecoder->fb, ics->window_shape, hDecoder->window_shape_prev[sce->channel], hDecoder->sf_index, hDecoder->object_type, hDecoder->frameLength); } #endif /* tns decoding */ tns_decode_frame(ics, &(ics->tns), hDecoder->sf_index, hDecoder->object_type, spec_coef, hDecoder->frameLength); /* drc decoding */ if (hDecoder->drc->present) { if (!hDecoder->drc->exclude_mask[sce->channel] || !hDecoder->drc->excluded_chns_present) drc_decode(hDecoder->drc, spec_coef); } /* filter bank */ #ifdef SSR_DEC if (hDecoder->object_type != SSR) #endif { ifilter_bank(hDecoder->fb, ics->window_sequence, ics->window_shape, hDecoder->window_shape_prev[sce->channel], spec_coef, hDecoder->time_out[sce->channel], hDecoder->fb_intermed[sce->channel], hDecoder->object_type, hDecoder->frameLength); } #ifdef SSR_DEC else { ssr_decode(&(ics->ssr), hDecoder->fb, ics->window_sequence, ics->window_shape, hDecoder->window_shape_prev[sce->channel], spec_coef, hDecoder->time_out[sce->channel], hDecoder->ssr_overlap[sce->channel], hDecoder->ipqf_buffer[sce->channel], hDecoder->prev_fmd[sce->channel], hDecoder->frameLength); } #endif /* save window shape for next frame */ hDecoder->window_shape_prev[sce->channel] = ics->window_shape; #ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { lt_update_state(hDecoder->lt_pred_stat[sce->channel], hDecoder->time_out[sce->channel], hDecoder->fb_intermed[sce->channel], hDecoder->frameLength, hDecoder->object_type); } #endif #ifdef SBR_DEC if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) && hDecoder->sbr_alloced[hDecoder->fr_ch_ele]) { int ele = hDecoder->fr_ch_ele; int ch = sce->channel; /* following case can happen when forceUpSampling == 1 */ if (hDecoder->sbr[ele] == NULL) { hDecoder->sbr[ele] = sbrDecodeInit(hDecoder->frameLength, hDecoder->element_id[ele], 2*get_sample_rate(hDecoder->sf_index), hDecoder->downSampledSBR #ifdef DRM , 0 #endif ); } if (sce->ics1.window_sequence == EIGHT_SHORT_SEQUENCE) hDecoder->sbr[ele]->maxAACLine = 8*min(sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)], sce->ics1.swb_offset_max); else hDecoder->sbr[ele]->maxAACLine = min(sce->ics1.swb_offset[max(sce->ics1.max_sfb-1, 0)], sce->ics1.swb_offset_max); /* check if any of the PS tools is used */ #if (defined(PS_DEC) || defined(DRM_PS)) if (hDecoder->ps_used[ele] == 0) #endif { retval = sbrDecodeSingleFrame(hDecoder->sbr[ele], hDecoder->time_out[ch], hDecoder->postSeekResetFlag, hDecoder->downSampledSBR); } #if (defined(PS_DEC) || defined(DRM_PS)) else { retval = sbrDecodeSingleFramePS(hDecoder->sbr[ele], hDecoder->time_out[ch], hDecoder->time_out[ch+1], hDecoder->postSeekResetFlag, hDecoder->downSampledSBR); } #endif if (retval > 0) return retval; } else if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) && !hDecoder->sbr_alloced[hDecoder->fr_ch_ele]) { return 23; } #endif /* copy L to R when no PS is used */ #if (defined(PS_DEC) || defined(DRM_PS)) if ((hDecoder->ps_used[hDecoder->fr_ch_ele] == 0) && (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2)) { int ele = hDecoder->fr_ch_ele; int ch = sce->channel; int frame_size = (hDecoder->sbr_alloced[ele]) ? 2 : 1; frame_size *= hDecoder->frameLength*sizeof(real_t); memcpy(hDecoder->time_out[ch+1], hDecoder->time_out[ch], frame_size); } #endif return 0; } uint8_t reconstruct_channel_pair(NeAACDecStruct *hDecoder, ic_stream *ics1, ic_stream *ics2, element *cpe, int16_t *spec_data1, int16_t *spec_data2) { uint8_t retval; ALIGN real_t spec_coef1[1024]; ALIGN real_t spec_coef2[1024]; #ifdef PROFILE int64_t count = faad_get_ts(); #endif if (hDecoder->element_alloced[hDecoder->fr_ch_ele] == 0) { retval = allocate_channel_pair(hDecoder, cpe->channel, (uint8_t)cpe->paired_channel); if (retval > 0) return retval; hDecoder->element_alloced[hDecoder->fr_ch_ele] = 1; } /* dequantisation and scaling */ retval = quant_to_spec(hDecoder, ics1, spec_data1, spec_coef1, hDecoder->frameLength); if (retval > 0) return retval; retval = quant_to_spec(hDecoder, ics2, spec_data2, spec_coef2, hDecoder->frameLength); if (retval > 0) return retval; #ifdef PROFILE count = faad_get_ts() - count; hDecoder->requant_cycles += count; #endif /* pns decoding */ if (ics1->ms_mask_present) { pns_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength, 1, hDecoder->object_type, &(hDecoder->__r1), &(hDecoder->__r2)); } else { pns_decode(ics1, NULL, spec_coef1, NULL, hDecoder->frameLength, 0, hDecoder->object_type, &(hDecoder->__r1), &(hDecoder->__r2)); pns_decode(ics2, NULL, spec_coef2, NULL, hDecoder->frameLength, 0, hDecoder->object_type, &(hDecoder->__r1), &(hDecoder->__r2)); } /* mid/side decoding */ ms_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength); #if 0 { int i; for (i = 0; i < 1024; i++) { //printf("%d\n", spec_coef1[i]); printf("0x%.8X\n", spec_coef1[i]); } for (i = 0; i < 1024; i++) { //printf("%d\n", spec_coef2[i]); printf("0x%.8X\n", spec_coef2[i]); } } #endif /* intensity stereo decoding */ is_decode(ics1, ics2, spec_coef1, spec_coef2, hDecoder->frameLength); #if 0 { int i; for (i = 0; i < 1024; i++) { printf("%d\n", spec_coef1[i]); //printf("0x%.8X\n", spec_coef1[i]); } for (i = 0; i < 1024; i++) { printf("%d\n", spec_coef2[i]); //printf("0x%.8X\n", spec_coef2[i]); } } #endif #ifdef MAIN_DEC /* MAIN object type prediction */ if (hDecoder->object_type == MAIN) { /* intra channel prediction */ ic_prediction(ics1, spec_coef1, hDecoder->pred_stat[cpe->channel], hDecoder->frameLength, hDecoder->sf_index); ic_prediction(ics2, spec_coef2, hDecoder->pred_stat[cpe->paired_channel], hDecoder->frameLength, hDecoder->sf_index); /* In addition, for scalefactor bands coded by perceptual noise substitution the predictors belonging to the corresponding spectral coefficients are reset. */ pns_reset_pred_state(ics1, hDecoder->pred_stat[cpe->channel]); pns_reset_pred_state(ics2, hDecoder->pred_stat[cpe->paired_channel]); } #endif #ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { ltp_info *ltp1 = &(ics1->ltp); ltp_info *ltp2 = (cpe->common_window) ? &(ics2->ltp2) : &(ics2->ltp); #ifdef LD_DEC if (hDecoder->object_type == LD) { if (ltp1->data_present) { if (ltp1->lag_update) hDecoder->ltp_lag[cpe->channel] = ltp1->lag; } ltp1->lag = hDecoder->ltp_lag[cpe->channel]; if (ltp2->data_present) { if (ltp2->lag_update) hDecoder->ltp_lag[cpe->paired_channel] = ltp2->lag; } ltp2->lag = hDecoder->ltp_lag[cpe->paired_channel]; } #endif /* long term prediction */ lt_prediction(ics1, ltp1, spec_coef1, hDecoder->lt_pred_stat[cpe->channel], hDecoder->fb, ics1->window_shape, hDecoder->window_shape_prev[cpe->channel], hDecoder->sf_index, hDecoder->object_type, hDecoder->frameLength); lt_prediction(ics2, ltp2, spec_coef2, hDecoder->lt_pred_stat[cpe->paired_channel], hDecoder->fb, ics2->window_shape, hDecoder->window_shape_prev[cpe->paired_channel], hDecoder->sf_index, hDecoder->object_type, hDecoder->frameLength); } #endif /* tns decoding */ tns_decode_frame(ics1, &(ics1->tns), hDecoder->sf_index, hDecoder->object_type, spec_coef1, hDecoder->frameLength); tns_decode_frame(ics2, &(ics2->tns), hDecoder->sf_index, hDecoder->object_type, spec_coef2, hDecoder->frameLength); /* drc decoding */ if (hDecoder->drc->present) { if (!hDecoder->drc->exclude_mask[cpe->channel] || !hDecoder->drc->excluded_chns_present) drc_decode(hDecoder->drc, spec_coef1); if (!hDecoder->drc->exclude_mask[cpe->paired_channel] || !hDecoder->drc->excluded_chns_present) drc_decode(hDecoder->drc, spec_coef2); } /* filter bank */ #ifdef SSR_DEC if (hDecoder->object_type != SSR) #endif { ifilter_bank(hDecoder->fb, ics1->window_sequence, ics1->window_shape, hDecoder->window_shape_prev[cpe->channel], spec_coef1, hDecoder->time_out[cpe->channel], hDecoder->fb_intermed[cpe->channel], hDecoder->object_type, hDecoder->frameLength); ifilter_bank(hDecoder->fb, ics2->window_sequence, ics2->window_shape, hDecoder->window_shape_prev[cpe->paired_channel], spec_coef2, hDecoder->time_out[cpe->paired_channel], hDecoder->fb_intermed[cpe->paired_channel], hDecoder->object_type, hDecoder->frameLength); } #ifdef SSR_DEC else { ssr_decode(&(ics1->ssr), hDecoder->fb, ics1->window_sequence, ics1->window_shape, hDecoder->window_shape_prev[cpe->channel], spec_coef1, hDecoder->time_out[cpe->channel], hDecoder->ssr_overlap[cpe->channel], hDecoder->ipqf_buffer[cpe->channel], hDecoder->prev_fmd[cpe->channel], hDecoder->frameLength); ssr_decode(&(ics2->ssr), hDecoder->fb, ics2->window_sequence, ics2->window_shape, hDecoder->window_shape_prev[cpe->paired_channel], spec_coef2, hDecoder->time_out[cpe->paired_channel], hDecoder->ssr_overlap[cpe->paired_channel], hDecoder->ipqf_buffer[cpe->paired_channel], hDecoder->prev_fmd[cpe->paired_channel], hDecoder->frameLength); } #endif /* save window shape for next frame */ hDecoder->window_shape_prev[cpe->channel] = ics1->window_shape; hDecoder->window_shape_prev[cpe->paired_channel] = ics2->window_shape; #ifdef LTP_DEC if (is_ltp_ot(hDecoder->object_type)) { lt_update_state(hDecoder->lt_pred_stat[cpe->channel], hDecoder->time_out[cpe->channel], hDecoder->fb_intermed[cpe->channel], hDecoder->frameLength, hDecoder->object_type); lt_update_state(hDecoder->lt_pred_stat[cpe->paired_channel], hDecoder->time_out[cpe->paired_channel], hDecoder->fb_intermed[cpe->paired_channel], hDecoder->frameLength, hDecoder->object_type); } #endif #ifdef SBR_DEC if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) && hDecoder->sbr_alloced[hDecoder->fr_ch_ele]) { int ele = hDecoder->fr_ch_ele; int ch0 = cpe->channel; int ch1 = cpe->paired_channel; /* following case can happen when forceUpSampling == 1 */ if (hDecoder->sbr[ele] == NULL) { hDecoder->sbr[ele] = sbrDecodeInit(hDecoder->frameLength, hDecoder->element_id[ele], 2*get_sample_rate(hDecoder->sf_index), hDecoder->downSampledSBR #ifdef DRM , 0 #endif ); } if (cpe->ics1.window_sequence == EIGHT_SHORT_SEQUENCE) hDecoder->sbr[ele]->maxAACLine = 8*min(cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)], cpe->ics1.swb_offset_max); else hDecoder->sbr[ele]->maxAACLine = min(cpe->ics1.swb_offset[max(cpe->ics1.max_sfb-1, 0)], cpe->ics1.swb_offset_max); retval = sbrDecodeCoupleFrame(hDecoder->sbr[ele], hDecoder->time_out[ch0], hDecoder->time_out[ch1], hDecoder->postSeekResetFlag, hDecoder->downSampledSBR); if (retval > 0) return retval; } else if (((hDecoder->sbr_present_flag == 1) || (hDecoder->forceUpSampling == 1)) && !hDecoder->sbr_alloced[hDecoder->fr_ch_ele]) { return 23; } #endif return 0; } xine-lib-1.2/contrib/libfaad/cfft.c0000644000175000017500000010350614647725152015001 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: cfft.c,v 1.35 2007/11/01 12:33:29 menno Exp $ **/ /* * Algorithmically based on Fortran-77 FFTPACK * by Paul N. Swarztrauber(Version 4, 1985). * * Does even sized fft only */ /* isign is +1 for backward and -1 for forward transforms */ #include "common.h" #include "structs.h" #include #include "cfft.h" #include "cfft_tab.h" /* static function declarations */ static void passf2pos(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa); static void passf2neg(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa); static void passf3(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const int8_t isign); static void passf4pos(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const complex_t *wa3); static void passf4neg(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const complex_t *wa3); static void passf5(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const complex_t *wa3, const complex_t *wa4, const int8_t isign); INLINE void cfftf1(uint16_t n, complex_t *c, complex_t *ch, const uint16_t *ifac, const complex_t *wa, const int8_t isign); static void cffti1(uint16_t n, complex_t *wa, uint16_t *ifac); /*---------------------------------------------------------------------- passf2, passf3, passf4, passf5. Complex FFT passes fwd and bwd. ----------------------------------------------------------------------*/ static void passf2pos(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa) { uint16_t i, k, ah, ac; if (ido == 1) { for (k = 0; k < l1; k++) { ah = 2*k; ac = 4*k; RE(ch[ah]) = RE(cc[ac]) + RE(cc[ac+1]); RE(ch[ah+l1]) = RE(cc[ac]) - RE(cc[ac+1]); IM(ch[ah]) = IM(cc[ac]) + IM(cc[ac+1]); IM(ch[ah+l1]) = IM(cc[ac]) - IM(cc[ac+1]); } } else { for (k = 0; k < l1; k++) { ah = k*ido; ac = 2*k*ido; for (i = 0; i < ido; i++) { complex_t t2; RE(ch[ah+i]) = RE(cc[ac+i]) + RE(cc[ac+i+ido]); RE(t2) = RE(cc[ac+i]) - RE(cc[ac+i+ido]); IM(ch[ah+i]) = IM(cc[ac+i]) + IM(cc[ac+i+ido]); IM(t2) = IM(cc[ac+i]) - IM(cc[ac+i+ido]); #if 1 ComplexMult(&IM(ch[ah+i+l1*ido]), &RE(ch[ah+i+l1*ido]), IM(t2), RE(t2), RE(wa[i]), IM(wa[i])); #else ComplexMult(&RE(ch[ah+i+l1*ido]), &IM(ch[ah+i+l1*ido]), RE(t2), IM(t2), RE(wa[i]), IM(wa[i])); #endif } } } } static void passf2neg(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa) { uint16_t i, k, ah, ac; if (ido == 1) { for (k = 0; k < l1; k++) { ah = 2*k; ac = 4*k; RE(ch[ah]) = RE(cc[ac]) + RE(cc[ac+1]); RE(ch[ah+l1]) = RE(cc[ac]) - RE(cc[ac+1]); IM(ch[ah]) = IM(cc[ac]) + IM(cc[ac+1]); IM(ch[ah+l1]) = IM(cc[ac]) - IM(cc[ac+1]); } } else { for (k = 0; k < l1; k++) { ah = k*ido; ac = 2*k*ido; for (i = 0; i < ido; i++) { complex_t t2; RE(ch[ah+i]) = RE(cc[ac+i]) + RE(cc[ac+i+ido]); RE(t2) = RE(cc[ac+i]) - RE(cc[ac+i+ido]); IM(ch[ah+i]) = IM(cc[ac+i]) + IM(cc[ac+i+ido]); IM(t2) = IM(cc[ac+i]) - IM(cc[ac+i+ido]); #if 1 ComplexMult(&RE(ch[ah+i+l1*ido]), &IM(ch[ah+i+l1*ido]), RE(t2), IM(t2), RE(wa[i]), IM(wa[i])); #else ComplexMult(&IM(ch[ah+i+l1*ido]), &RE(ch[ah+i+l1*ido]), IM(t2), RE(t2), RE(wa[i]), IM(wa[i])); #endif } } } } static void passf3(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const int8_t isign) { static real_t taur = FRAC_CONST(-0.5); static real_t taui = FRAC_CONST(0.866025403784439); uint16_t i, k, ac, ah; complex_t c2, c3, d2, d3, t2; if (ido == 1) { if (isign == 1) { for (k = 0; k < l1; k++) { ac = 3*k+1; ah = k; RE(t2) = RE(cc[ac]) + RE(cc[ac+1]); IM(t2) = IM(cc[ac]) + IM(cc[ac+1]); RE(c2) = RE(cc[ac-1]) + MUL_F(RE(t2),taur); IM(c2) = IM(cc[ac-1]) + MUL_F(IM(t2),taur); RE(ch[ah]) = RE(cc[ac-1]) + RE(t2); IM(ch[ah]) = IM(cc[ac-1]) + IM(t2); RE(c3) = MUL_F((RE(cc[ac]) - RE(cc[ac+1])), taui); IM(c3) = MUL_F((IM(cc[ac]) - IM(cc[ac+1])), taui); RE(ch[ah+l1]) = RE(c2) - IM(c3); IM(ch[ah+l1]) = IM(c2) + RE(c3); RE(ch[ah+2*l1]) = RE(c2) + IM(c3); IM(ch[ah+2*l1]) = IM(c2) - RE(c3); } } else { for (k = 0; k < l1; k++) { ac = 3*k+1; ah = k; RE(t2) = RE(cc[ac]) + RE(cc[ac+1]); IM(t2) = IM(cc[ac]) + IM(cc[ac+1]); RE(c2) = RE(cc[ac-1]) + MUL_F(RE(t2),taur); IM(c2) = IM(cc[ac-1]) + MUL_F(IM(t2),taur); RE(ch[ah]) = RE(cc[ac-1]) + RE(t2); IM(ch[ah]) = IM(cc[ac-1]) + IM(t2); RE(c3) = MUL_F((RE(cc[ac]) - RE(cc[ac+1])), taui); IM(c3) = MUL_F((IM(cc[ac]) - IM(cc[ac+1])), taui); RE(ch[ah+l1]) = RE(c2) + IM(c3); IM(ch[ah+l1]) = IM(c2) - RE(c3); RE(ch[ah+2*l1]) = RE(c2) - IM(c3); IM(ch[ah+2*l1]) = IM(c2) + RE(c3); } } } else { if (isign == 1) { for (k = 0; k < l1; k++) { for (i = 0; i < ido; i++) { ac = i + (3*k+1)*ido; ah = i + k * ido; RE(t2) = RE(cc[ac]) + RE(cc[ac+ido]); RE(c2) = RE(cc[ac-ido]) + MUL_F(RE(t2),taur); IM(t2) = IM(cc[ac]) + IM(cc[ac+ido]); IM(c2) = IM(cc[ac-ido]) + MUL_F(IM(t2),taur); RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2); IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2); RE(c3) = MUL_F((RE(cc[ac]) - RE(cc[ac+ido])), taui); IM(c3) = MUL_F((IM(cc[ac]) - IM(cc[ac+ido])), taui); RE(d2) = RE(c2) - IM(c3); IM(d3) = IM(c2) - RE(c3); RE(d3) = RE(c2) + IM(c3); IM(d2) = IM(c2) + RE(c3); #if 1 ComplexMult(&IM(ch[ah+l1*ido]), &RE(ch[ah+l1*ido]), IM(d2), RE(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&IM(ch[ah+2*l1*ido]), &RE(ch[ah+2*l1*ido]), IM(d3), RE(d3), RE(wa2[i]), IM(wa2[i])); #else ComplexMult(&RE(ch[ah+l1*ido]), &IM(ch[ah+l1*ido]), RE(d2), IM(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&RE(ch[ah+2*l1*ido]), &IM(ch[ah+2*l1*ido]), RE(d3), IM(d3), RE(wa2[i]), IM(wa2[i])); #endif } } } else { for (k = 0; k < l1; k++) { for (i = 0; i < ido; i++) { ac = i + (3*k+1)*ido; ah = i + k * ido; RE(t2) = RE(cc[ac]) + RE(cc[ac+ido]); RE(c2) = RE(cc[ac-ido]) + MUL_F(RE(t2),taur); IM(t2) = IM(cc[ac]) + IM(cc[ac+ido]); IM(c2) = IM(cc[ac-ido]) + MUL_F(IM(t2),taur); RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2); IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2); RE(c3) = MUL_F((RE(cc[ac]) - RE(cc[ac+ido])), taui); IM(c3) = MUL_F((IM(cc[ac]) - IM(cc[ac+ido])), taui); RE(d2) = RE(c2) + IM(c3); IM(d3) = IM(c2) + RE(c3); RE(d3) = RE(c2) - IM(c3); IM(d2) = IM(c2) - RE(c3); #if 1 ComplexMult(&RE(ch[ah+l1*ido]), &IM(ch[ah+l1*ido]), RE(d2), IM(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&RE(ch[ah+2*l1*ido]), &IM(ch[ah+2*l1*ido]), RE(d3), IM(d3), RE(wa2[i]), IM(wa2[i])); #else ComplexMult(&IM(ch[ah+l1*ido]), &RE(ch[ah+l1*ido]), IM(d2), RE(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&IM(ch[ah+2*l1*ido]), &RE(ch[ah+2*l1*ido]), IM(d3), RE(d3), RE(wa2[i]), IM(wa2[i])); #endif } } } } } static void passf4pos(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const complex_t *wa3) { uint16_t i, k, ac, ah; if (ido == 1) { for (k = 0; k < l1; k++) { complex_t t1, t2, t3, t4; ac = 4*k; ah = k; RE(t2) = RE(cc[ac]) + RE(cc[ac+2]); RE(t1) = RE(cc[ac]) - RE(cc[ac+2]); IM(t2) = IM(cc[ac]) + IM(cc[ac+2]); IM(t1) = IM(cc[ac]) - IM(cc[ac+2]); RE(t3) = RE(cc[ac+1]) + RE(cc[ac+3]); IM(t4) = RE(cc[ac+1]) - RE(cc[ac+3]); IM(t3) = IM(cc[ac+3]) + IM(cc[ac+1]); RE(t4) = IM(cc[ac+3]) - IM(cc[ac+1]); RE(ch[ah]) = RE(t2) + RE(t3); RE(ch[ah+2*l1]) = RE(t2) - RE(t3); IM(ch[ah]) = IM(t2) + IM(t3); IM(ch[ah+2*l1]) = IM(t2) - IM(t3); RE(ch[ah+l1]) = RE(t1) + RE(t4); RE(ch[ah+3*l1]) = RE(t1) - RE(t4); IM(ch[ah+l1]) = IM(t1) + IM(t4); IM(ch[ah+3*l1]) = IM(t1) - IM(t4); } } else { for (k = 0; k < l1; k++) { ac = 4*k*ido; ah = k*ido; for (i = 0; i < ido; i++) { complex_t c2, c3, c4, t1, t2, t3, t4; RE(t2) = RE(cc[ac+i]) + RE(cc[ac+i+2*ido]); RE(t1) = RE(cc[ac+i]) - RE(cc[ac+i+2*ido]); IM(t2) = IM(cc[ac+i]) + IM(cc[ac+i+2*ido]); IM(t1) = IM(cc[ac+i]) - IM(cc[ac+i+2*ido]); RE(t3) = RE(cc[ac+i+ido]) + RE(cc[ac+i+3*ido]); IM(t4) = RE(cc[ac+i+ido]) - RE(cc[ac+i+3*ido]); IM(t3) = IM(cc[ac+i+3*ido]) + IM(cc[ac+i+ido]); RE(t4) = IM(cc[ac+i+3*ido]) - IM(cc[ac+i+ido]); RE(c2) = RE(t1) + RE(t4); RE(c4) = RE(t1) - RE(t4); IM(c2) = IM(t1) + IM(t4); IM(c4) = IM(t1) - IM(t4); RE(ch[ah+i]) = RE(t2) + RE(t3); RE(c3) = RE(t2) - RE(t3); IM(ch[ah+i]) = IM(t2) + IM(t3); IM(c3) = IM(t2) - IM(t3); #if 1 ComplexMult(&IM(ch[ah+i+l1*ido]), &RE(ch[ah+i+l1*ido]), IM(c2), RE(c2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&IM(ch[ah+i+2*l1*ido]), &RE(ch[ah+i+2*l1*ido]), IM(c3), RE(c3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&IM(ch[ah+i+3*l1*ido]), &RE(ch[ah+i+3*l1*ido]), IM(c4), RE(c4), RE(wa3[i]), IM(wa3[i])); #else ComplexMult(&RE(ch[ah+i+l1*ido]), &IM(ch[ah+i+l1*ido]), RE(c2), IM(c2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&RE(ch[ah+i+2*l1*ido]), &IM(ch[ah+i+2*l1*ido]), RE(c3), IM(c3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&RE(ch[ah+i+3*l1*ido]), &IM(ch[ah+i+3*l1*ido]), RE(c4), IM(c4), RE(wa3[i]), IM(wa3[i])); #endif } } } } static void passf4neg(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const complex_t *wa3) { uint16_t i, k, ac, ah; if (ido == 1) { for (k = 0; k < l1; k++) { complex_t t1, t2, t3, t4; ac = 4*k; ah = k; RE(t2) = RE(cc[ac]) + RE(cc[ac+2]); RE(t1) = RE(cc[ac]) - RE(cc[ac+2]); IM(t2) = IM(cc[ac]) + IM(cc[ac+2]); IM(t1) = IM(cc[ac]) - IM(cc[ac+2]); RE(t3) = RE(cc[ac+1]) + RE(cc[ac+3]); IM(t4) = RE(cc[ac+1]) - RE(cc[ac+3]); IM(t3) = IM(cc[ac+3]) + IM(cc[ac+1]); RE(t4) = IM(cc[ac+3]) - IM(cc[ac+1]); RE(ch[ah]) = RE(t2) + RE(t3); RE(ch[ah+2*l1]) = RE(t2) - RE(t3); IM(ch[ah]) = IM(t2) + IM(t3); IM(ch[ah+2*l1]) = IM(t2) - IM(t3); RE(ch[ah+l1]) = RE(t1) - RE(t4); RE(ch[ah+3*l1]) = RE(t1) + RE(t4); IM(ch[ah+l1]) = IM(t1) - IM(t4); IM(ch[ah+3*l1]) = IM(t1) + IM(t4); } } else { for (k = 0; k < l1; k++) { ac = 4*k*ido; ah = k*ido; for (i = 0; i < ido; i++) { complex_t c2, c3, c4, t1, t2, t3, t4; RE(t2) = RE(cc[ac+i]) + RE(cc[ac+i+2*ido]); RE(t1) = RE(cc[ac+i]) - RE(cc[ac+i+2*ido]); IM(t2) = IM(cc[ac+i]) + IM(cc[ac+i+2*ido]); IM(t1) = IM(cc[ac+i]) - IM(cc[ac+i+2*ido]); RE(t3) = RE(cc[ac+i+ido]) + RE(cc[ac+i+3*ido]); IM(t4) = RE(cc[ac+i+ido]) - RE(cc[ac+i+3*ido]); IM(t3) = IM(cc[ac+i+3*ido]) + IM(cc[ac+i+ido]); RE(t4) = IM(cc[ac+i+3*ido]) - IM(cc[ac+i+ido]); RE(c2) = RE(t1) - RE(t4); RE(c4) = RE(t1) + RE(t4); IM(c2) = IM(t1) - IM(t4); IM(c4) = IM(t1) + IM(t4); RE(ch[ah+i]) = RE(t2) + RE(t3); RE(c3) = RE(t2) - RE(t3); IM(ch[ah+i]) = IM(t2) + IM(t3); IM(c3) = IM(t2) - IM(t3); #if 1 ComplexMult(&RE(ch[ah+i+l1*ido]), &IM(ch[ah+i+l1*ido]), RE(c2), IM(c2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&RE(ch[ah+i+2*l1*ido]), &IM(ch[ah+i+2*l1*ido]), RE(c3), IM(c3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&RE(ch[ah+i+3*l1*ido]), &IM(ch[ah+i+3*l1*ido]), RE(c4), IM(c4), RE(wa3[i]), IM(wa3[i])); #else ComplexMult(&IM(ch[ah+i+l1*ido]), &RE(ch[ah+i+l1*ido]), IM(c2), RE(c2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&IM(ch[ah+i+2*l1*ido]), &RE(ch[ah+i+2*l1*ido]), IM(c3), RE(c3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&IM(ch[ah+i+3*l1*ido]), &RE(ch[ah+i+3*l1*ido]), IM(c4), RE(c4), RE(wa3[i]), IM(wa3[i])); #endif } } } } static void passf5(const uint16_t ido, const uint16_t l1, const complex_t *cc, complex_t *ch, const complex_t *wa1, const complex_t *wa2, const complex_t *wa3, const complex_t *wa4, const int8_t isign) { static real_t tr11 = FRAC_CONST(0.309016994374947); static real_t ti11 = FRAC_CONST(0.951056516295154); static real_t tr12 = FRAC_CONST(-0.809016994374947); static real_t ti12 = FRAC_CONST(0.587785252292473); uint16_t i, k, ac, ah; complex_t c2, c3, c4, c5, d3, d4, d5, d2, t2, t3, t4, t5; if (ido == 1) { if (isign == 1) { for (k = 0; k < l1; k++) { ac = 5*k + 1; ah = k; RE(t2) = RE(cc[ac]) + RE(cc[ac+3]); IM(t2) = IM(cc[ac]) + IM(cc[ac+3]); RE(t3) = RE(cc[ac+1]) + RE(cc[ac+2]); IM(t3) = IM(cc[ac+1]) + IM(cc[ac+2]); RE(t4) = RE(cc[ac+1]) - RE(cc[ac+2]); IM(t4) = IM(cc[ac+1]) - IM(cc[ac+2]); RE(t5) = RE(cc[ac]) - RE(cc[ac+3]); IM(t5) = IM(cc[ac]) - IM(cc[ac+3]); RE(ch[ah]) = RE(cc[ac-1]) + RE(t2) + RE(t3); IM(ch[ah]) = IM(cc[ac-1]) + IM(t2) + IM(t3); RE(c2) = RE(cc[ac-1]) + MUL_F(RE(t2),tr11) + MUL_F(RE(t3),tr12); IM(c2) = IM(cc[ac-1]) + MUL_F(IM(t2),tr11) + MUL_F(IM(t3),tr12); RE(c3) = RE(cc[ac-1]) + MUL_F(RE(t2),tr12) + MUL_F(RE(t3),tr11); IM(c3) = IM(cc[ac-1]) + MUL_F(IM(t2),tr12) + MUL_F(IM(t3),tr11); ComplexMult(&RE(c5), &RE(c4), ti11, ti12, RE(t5), RE(t4)); ComplexMult(&IM(c5), &IM(c4), ti11, ti12, IM(t5), IM(t4)); RE(ch[ah+l1]) = RE(c2) - IM(c5); IM(ch[ah+l1]) = IM(c2) + RE(c5); RE(ch[ah+2*l1]) = RE(c3) - IM(c4); IM(ch[ah+2*l1]) = IM(c3) + RE(c4); RE(ch[ah+3*l1]) = RE(c3) + IM(c4); IM(ch[ah+3*l1]) = IM(c3) - RE(c4); RE(ch[ah+4*l1]) = RE(c2) + IM(c5); IM(ch[ah+4*l1]) = IM(c2) - RE(c5); } } else { for (k = 0; k < l1; k++) { ac = 5*k + 1; ah = k; RE(t2) = RE(cc[ac]) + RE(cc[ac+3]); IM(t2) = IM(cc[ac]) + IM(cc[ac+3]); RE(t3) = RE(cc[ac+1]) + RE(cc[ac+2]); IM(t3) = IM(cc[ac+1]) + IM(cc[ac+2]); RE(t4) = RE(cc[ac+1]) - RE(cc[ac+2]); IM(t4) = IM(cc[ac+1]) - IM(cc[ac+2]); RE(t5) = RE(cc[ac]) - RE(cc[ac+3]); IM(t5) = IM(cc[ac]) - IM(cc[ac+3]); RE(ch[ah]) = RE(cc[ac-1]) + RE(t2) + RE(t3); IM(ch[ah]) = IM(cc[ac-1]) + IM(t2) + IM(t3); RE(c2) = RE(cc[ac-1]) + MUL_F(RE(t2),tr11) + MUL_F(RE(t3),tr12); IM(c2) = IM(cc[ac-1]) + MUL_F(IM(t2),tr11) + MUL_F(IM(t3),tr12); RE(c3) = RE(cc[ac-1]) + MUL_F(RE(t2),tr12) + MUL_F(RE(t3),tr11); IM(c3) = IM(cc[ac-1]) + MUL_F(IM(t2),tr12) + MUL_F(IM(t3),tr11); ComplexMult(&RE(c4), &RE(c5), ti12, ti11, RE(t5), RE(t4)); ComplexMult(&IM(c4), &IM(c5), ti12, ti11, IM(t5), IM(t4)); RE(ch[ah+l1]) = RE(c2) + IM(c5); IM(ch[ah+l1]) = IM(c2) - RE(c5); RE(ch[ah+2*l1]) = RE(c3) + IM(c4); IM(ch[ah+2*l1]) = IM(c3) - RE(c4); RE(ch[ah+3*l1]) = RE(c3) - IM(c4); IM(ch[ah+3*l1]) = IM(c3) + RE(c4); RE(ch[ah+4*l1]) = RE(c2) - IM(c5); IM(ch[ah+4*l1]) = IM(c2) + RE(c5); } } } else { if (isign == 1) { for (k = 0; k < l1; k++) { for (i = 0; i < ido; i++) { ac = i + (k*5 + 1) * ido; ah = i + k * ido; RE(t2) = RE(cc[ac]) + RE(cc[ac+3*ido]); IM(t2) = IM(cc[ac]) + IM(cc[ac+3*ido]); RE(t3) = RE(cc[ac+ido]) + RE(cc[ac+2*ido]); IM(t3) = IM(cc[ac+ido]) + IM(cc[ac+2*ido]); RE(t4) = RE(cc[ac+ido]) - RE(cc[ac+2*ido]); IM(t4) = IM(cc[ac+ido]) - IM(cc[ac+2*ido]); RE(t5) = RE(cc[ac]) - RE(cc[ac+3*ido]); IM(t5) = IM(cc[ac]) - IM(cc[ac+3*ido]); RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2) + RE(t3); IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2) + IM(t3); RE(c2) = RE(cc[ac-ido]) + MUL_F(RE(t2),tr11) + MUL_F(RE(t3),tr12); IM(c2) = IM(cc[ac-ido]) + MUL_F(IM(t2),tr11) + MUL_F(IM(t3),tr12); RE(c3) = RE(cc[ac-ido]) + MUL_F(RE(t2),tr12) + MUL_F(RE(t3),tr11); IM(c3) = IM(cc[ac-ido]) + MUL_F(IM(t2),tr12) + MUL_F(IM(t3),tr11); ComplexMult(&RE(c5), &RE(c4), ti11, ti12, RE(t5), RE(t4)); ComplexMult(&IM(c5), &IM(c4), ti11, ti12, IM(t5), IM(t4)); IM(d2) = IM(c2) + RE(c5); IM(d3) = IM(c3) + RE(c4); RE(d4) = RE(c3) + IM(c4); RE(d5) = RE(c2) + IM(c5); RE(d2) = RE(c2) - IM(c5); IM(d5) = IM(c2) - RE(c5); RE(d3) = RE(c3) - IM(c4); IM(d4) = IM(c3) - RE(c4); #if 1 ComplexMult(&IM(ch[ah+l1*ido]), &RE(ch[ah+l1*ido]), IM(d2), RE(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&IM(ch[ah+2*l1*ido]), &RE(ch[ah+2*l1*ido]), IM(d3), RE(d3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&IM(ch[ah+3*l1*ido]), &RE(ch[ah+3*l1*ido]), IM(d4), RE(d4), RE(wa3[i]), IM(wa3[i])); ComplexMult(&IM(ch[ah+4*l1*ido]), &RE(ch[ah+4*l1*ido]), IM(d5), RE(d5), RE(wa4[i]), IM(wa4[i])); #else ComplexMult(&RE(ch[ah+l1*ido]), &IM(ch[ah+l1*ido]), RE(d2), IM(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&RE(ch[ah+2*l1*ido]), &IM(ch[ah+2*l1*ido]), RE(d3), IM(d3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&RE(ch[ah+3*l1*ido]), &IM(ch[ah+3*l1*ido]), RE(d4), IM(d4), RE(wa3[i]), IM(wa3[i])); ComplexMult(&RE(ch[ah+4*l1*ido]), &IM(ch[ah+4*l1*ido]), RE(d5), IM(d5), RE(wa4[i]), IM(wa4[i])); #endif } } } else { for (k = 0; k < l1; k++) { for (i = 0; i < ido; i++) { ac = i + (k*5 + 1) * ido; ah = i + k * ido; RE(t2) = RE(cc[ac]) + RE(cc[ac+3*ido]); IM(t2) = IM(cc[ac]) + IM(cc[ac+3*ido]); RE(t3) = RE(cc[ac+ido]) + RE(cc[ac+2*ido]); IM(t3) = IM(cc[ac+ido]) + IM(cc[ac+2*ido]); RE(t4) = RE(cc[ac+ido]) - RE(cc[ac+2*ido]); IM(t4) = IM(cc[ac+ido]) - IM(cc[ac+2*ido]); RE(t5) = RE(cc[ac]) - RE(cc[ac+3*ido]); IM(t5) = IM(cc[ac]) - IM(cc[ac+3*ido]); RE(ch[ah]) = RE(cc[ac-ido]) + RE(t2) + RE(t3); IM(ch[ah]) = IM(cc[ac-ido]) + IM(t2) + IM(t3); RE(c2) = RE(cc[ac-ido]) + MUL_F(RE(t2),tr11) + MUL_F(RE(t3),tr12); IM(c2) = IM(cc[ac-ido]) + MUL_F(IM(t2),tr11) + MUL_F(IM(t3),tr12); RE(c3) = RE(cc[ac-ido]) + MUL_F(RE(t2),tr12) + MUL_F(RE(t3),tr11); IM(c3) = IM(cc[ac-ido]) + MUL_F(IM(t2),tr12) + MUL_F(IM(t3),tr11); ComplexMult(&RE(c4), &RE(c5), ti12, ti11, RE(t5), RE(t4)); ComplexMult(&IM(c4), &IM(c5), ti12, ti11, IM(t5), IM(t4)); IM(d2) = IM(c2) - RE(c5); IM(d3) = IM(c3) - RE(c4); RE(d4) = RE(c3) - IM(c4); RE(d5) = RE(c2) - IM(c5); RE(d2) = RE(c2) + IM(c5); IM(d5) = IM(c2) + RE(c5); RE(d3) = RE(c3) + IM(c4); IM(d4) = IM(c3) + RE(c4); #if 1 ComplexMult(&RE(ch[ah+l1*ido]), &IM(ch[ah+l1*ido]), RE(d2), IM(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&RE(ch[ah+2*l1*ido]), &IM(ch[ah+2*l1*ido]), RE(d3), IM(d3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&RE(ch[ah+3*l1*ido]), &IM(ch[ah+3*l1*ido]), RE(d4), IM(d4), RE(wa3[i]), IM(wa3[i])); ComplexMult(&RE(ch[ah+4*l1*ido]), &IM(ch[ah+4*l1*ido]), RE(d5), IM(d5), RE(wa4[i]), IM(wa4[i])); #else ComplexMult(&IM(ch[ah+l1*ido]), &RE(ch[ah+l1*ido]), IM(d2), RE(d2), RE(wa1[i]), IM(wa1[i])); ComplexMult(&IM(ch[ah+2*l1*ido]), &RE(ch[ah+2*l1*ido]), IM(d3), RE(d3), RE(wa2[i]), IM(wa2[i])); ComplexMult(&IM(ch[ah+3*l1*ido]), &RE(ch[ah+3*l1*ido]), IM(d4), RE(d4), RE(wa3[i]), IM(wa3[i])); ComplexMult(&IM(ch[ah+4*l1*ido]), &RE(ch[ah+4*l1*ido]), IM(d5), RE(d5), RE(wa4[i]), IM(wa4[i])); #endif } } } } } /*---------------------------------------------------------------------- cfftf1, cfftf, cfftb, cffti1, cffti. Complex FFTs. ----------------------------------------------------------------------*/ static INLINE void cfftf1pos(uint16_t n, complex_t *c, complex_t *ch, const uint16_t *ifac, const complex_t *wa, const int8_t isign) { uint16_t i; uint16_t k1, l1, l2; uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido /*, idl1 */; nf = ifac[1]; na = 0; l1 = 1; iw = 0; for (k1 = 2; k1 <= nf+1; k1++) { ip = ifac[k1]; l2 = ip*l1; ido = n / l2; /* idl1 = ido*l1; */ switch (ip) { case 4: ix2 = iw + ido; ix3 = ix2 + ido; if (na == 0) passf4pos((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw], &wa[ix2], &wa[ix3]); else passf4pos((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw], &wa[ix2], &wa[ix3]); na = 1 - na; break; case 2: if (na == 0) passf2pos((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw]); else passf2pos((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw]); na = 1 - na; break; case 3: ix2 = iw + ido; if (na == 0) passf3((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw], &wa[ix2], isign); else passf3((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw], &wa[ix2], isign); na = 1 - na; break; case 5: ix2 = iw + ido; ix3 = ix2 + ido; ix4 = ix3 + ido; if (na == 0) passf5((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign); else passf5((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign); na = 1 - na; break; } l1 = l2; iw += (ip-1) * ido; } if (na == 0) return; for (i = 0; i < n; i++) { RE(c[i]) = RE(ch[i]); IM(c[i]) = IM(ch[i]); } } static INLINE void cfftf1neg(uint16_t n, complex_t *c, complex_t *ch, const uint16_t *ifac, const complex_t *wa, const int8_t isign) { uint16_t i; uint16_t k1, l1, l2; uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido /*, idl1 */; nf = ifac[1]; na = 0; l1 = 1; iw = 0; for (k1 = 2; k1 <= nf+1; k1++) { ip = ifac[k1]; l2 = ip*l1; ido = n / l2; /* idl1 = ido*l1; */ switch (ip) { case 4: ix2 = iw + ido; ix3 = ix2 + ido; if (na == 0) passf4neg((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw], &wa[ix2], &wa[ix3]); else passf4neg((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw], &wa[ix2], &wa[ix3]); na = 1 - na; break; case 2: if (na == 0) passf2neg((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw]); else passf2neg((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw]); na = 1 - na; break; case 3: ix2 = iw + ido; if (na == 0) passf3((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw], &wa[ix2], isign); else passf3((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw], &wa[ix2], isign); na = 1 - na; break; case 5: ix2 = iw + ido; ix3 = ix2 + ido; ix4 = ix3 + ido; if (na == 0) passf5((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)c, ch, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign); else passf5((const uint16_t)ido, (const uint16_t)l1, (const complex_t*)ch, c, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4], isign); na = 1 - na; break; } l1 = l2; iw += (ip-1) * ido; } if (na == 0) return; for (i = 0; i < n; i++) { RE(c[i]) = RE(ch[i]); IM(c[i]) = IM(ch[i]); } } void cfftf(cfft_info *cfft, complex_t *c) { cfftf1neg(cfft->n, c, cfft->work, (const uint16_t*)cfft->ifac, (const complex_t*)cfft->tab, -1); } void cfftb(cfft_info *cfft, complex_t *c) { cfftf1pos(cfft->n, c, cfft->work, (const uint16_t*)cfft->ifac, (const complex_t*)cfft->tab, +1); } static void cffti1(uint16_t n, complex_t *wa, uint16_t *ifac) { static uint16_t ntryh[4] = {3, 4, 2, 5}; #ifndef FIXED_POINT real_t arg, argh, argld, fi; uint16_t ido, ipm; uint16_t i1, k1, l1, l2; uint16_t ld, ii, ip; #endif uint16_t ntry = 0, i, j; uint16_t ib; uint16_t nf, nl, nq, nr; nl = n; nf = 0; j = 0; startloop: j++; if (j <= 4) ntry = ntryh[j-1]; else ntry += 2; do { nq = nl / ntry; nr = nl - ntry*nq; if (nr != 0) goto startloop; nf++; ifac[nf+1] = ntry; nl = nq; if (ntry == 2 && nf != 1) { for (i = 2; i <= nf; i++) { ib = nf - i + 2; ifac[ib+1] = ifac[ib]; } ifac[2] = 2; } } while (nl != 1); ifac[0] = n; ifac[1] = nf; #ifndef FIXED_POINT argh = (real_t)2.0*(real_t)M_PI / (real_t)n; i = 0; l1 = 1; for (k1 = 1; k1 <= nf; k1++) { ip = ifac[k1+1]; ld = 0; l2 = l1*ip; ido = n / l2; ipm = ip - 1; for (j = 0; j < ipm; j++) { i1 = i; RE(wa[i]) = 1.0; IM(wa[i]) = 0.0; ld += l1; fi = 0; argld = ld*argh; for (ii = 0; ii < ido; ii++) { i++; fi++; arg = fi * argld; RE(wa[i]) = (real_t)cos(arg); #if 1 IM(wa[i]) = (real_t)sin(arg); #else IM(wa[i]) = (real_t)-sin(arg); #endif } if (ip > 5) { RE(wa[i1]) = RE(wa[i]); IM(wa[i1]) = IM(wa[i]); } } l1 = l2; } #endif } cfft_info *cffti(uint16_t n) { cfft_info *cfft = (cfft_info*)faad_malloc(sizeof(cfft_info)); cfft->n = n; cfft->work = (complex_t*)faad_malloc(n*sizeof(complex_t)); #ifndef FIXED_POINT cfft->tab = (complex_t*)faad_malloc(n*sizeof(complex_t)); cffti1(n, cfft->tab, cfft->ifac); #else cffti1(n, NULL, cfft->ifac); switch (n) { case 64: cfft->tab = (complex_t*)cfft_tab_64; break; case 512: cfft->tab = (complex_t*)cfft_tab_512; break; #ifdef LD_DEC case 256: cfft->tab = (complex_t*)cfft_tab_256; break; #endif #ifdef ALLOW_SMALL_FRAMELENGTH case 60: cfft->tab = (complex_t*)cfft_tab_60; break; case 480: cfft->tab = (complex_t*)cfft_tab_480; break; #ifdef LD_DEC case 240: cfft->tab = (complex_t*)cfft_tab_240; break; #endif #endif case 128: cfft->tab = (complex_t*)cfft_tab_128; break; } #endif return cfft; } void cfftu(cfft_info *cfft) { if (cfft->work) faad_free(cfft->work); #ifndef FIXED_POINT if (cfft->tab) faad_free(cfft->tab); #endif if (cfft) faad_free(cfft); } xine-lib-1.2/contrib/libfaad/sine_win.h0000644000175000017500000043221314647725152015677 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sine_win.h,v 1.19 2007/11/01 12:33:36 menno Exp $ **/ #ifndef __SINE_WIN_H__ #define __SINE_WIN_H__ #ifdef __cplusplus extern "C" { #endif #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif ALIGN static const real_t sine_long_1024[] = { FRAC_CONST(0.00076699031874270449), FRAC_CONST(0.002300969151425805), FRAC_CONST(0.0038349425697062275), FRAC_CONST(0.0053689069639963425), FRAC_CONST(0.0069028587247297558), FRAC_CONST(0.0084367942423697988), FRAC_CONST(0.0099707099074180308), FRAC_CONST(0.011504602110422714), FRAC_CONST(0.013038467241987334), FRAC_CONST(0.014572301692779064), FRAC_CONST(0.016106101853537287), FRAC_CONST(0.017639864115082053), FRAC_CONST(0.019173584868322623), FRAC_CONST(0.020707260504265895), FRAC_CONST(0.022240887414024961), FRAC_CONST(0.023774461988827555), FRAC_CONST(0.025307980620024571), FRAC_CONST(0.026841439699098531), FRAC_CONST(0.028374835617672099), FRAC_CONST(0.029908164767516555), FRAC_CONST(0.031441423540560301), FRAC_CONST(0.032974608328897335), FRAC_CONST(0.03450771552479575), FRAC_CONST(0.036040741520706229), FRAC_CONST(0.037573682709270494), FRAC_CONST(0.039106535483329888), FRAC_CONST(0.040639296235933736), FRAC_CONST(0.042171961360347947), FRAC_CONST(0.043704527250063421), FRAC_CONST(0.04523699029880459), FRAC_CONST(0.046769346900537863), FRAC_CONST(0.048301593449480144), FRAC_CONST(0.049833726340107277), FRAC_CONST(0.051365741967162593), FRAC_CONST(0.052897636725665324), FRAC_CONST(0.054429407010919133), FRAC_CONST(0.055961049218520569), FRAC_CONST(0.057492559744367566), FRAC_CONST(0.059023934984667931), FRAC_CONST(0.060555171335947788), FRAC_CONST(0.062086265195060088), FRAC_CONST(0.063617212959193106), FRAC_CONST(0.065148011025878833), FRAC_CONST(0.066678655793001557), FRAC_CONST(0.068209143658806329), FRAC_CONST(0.069739471021907307), FRAC_CONST(0.071269634281296401), FRAC_CONST(0.072799629836351673), FRAC_CONST(0.074329454086845756), FRAC_CONST(0.075859103432954447), FRAC_CONST(0.077388574275265049), FRAC_CONST(0.078917863014784942), FRAC_CONST(0.080446966052950014), FRAC_CONST(0.081975879791633066), FRAC_CONST(0.083504600633152432), FRAC_CONST(0.085033124980280275), FRAC_CONST(0.08656144923625117), FRAC_CONST(0.088089569804770507), FRAC_CONST(0.089617483090022959), FRAC_CONST(0.091145185496681005), FRAC_CONST(0.09267267342991331), FRAC_CONST(0.094199943295393204), FRAC_CONST(0.095726991499307162), FRAC_CONST(0.097253814448363271), FRAC_CONST(0.098780408549799623), FRAC_CONST(0.10030677021139286), FRAC_CONST(0.10183289584146653), FRAC_CONST(0.10335878184889961), FRAC_CONST(0.10488442464313497), FRAC_CONST(0.10640982063418768), FRAC_CONST(0.10793496623265365), FRAC_CONST(0.10945985784971798), FRAC_CONST(0.11098449189716339), FRAC_CONST(0.11250886478737869), FRAC_CONST(0.1140329729333672), FRAC_CONST(0.11555681274875526), FRAC_CONST(0.11708038064780059), FRAC_CONST(0.11860367304540072), FRAC_CONST(0.1201266863571015), FRAC_CONST(0.12164941699910553), FRAC_CONST(0.12317186138828048), FRAC_CONST(0.12469401594216764), FRAC_CONST(0.12621587707899035), FRAC_CONST(0.12773744121766231), FRAC_CONST(0.12925870477779614), FRAC_CONST(0.13077966417971171), FRAC_CONST(0.13230031584444465), FRAC_CONST(0.13382065619375472), FRAC_CONST(0.13534068165013421), FRAC_CONST(0.13686038863681638), FRAC_CONST(0.13837977357778389), FRAC_CONST(0.13989883289777721), FRAC_CONST(0.14141756302230302), FRAC_CONST(0.14293596037764267), FRAC_CONST(0.14445402139086047), FRAC_CONST(0.14597174248981221), FRAC_CONST(0.14748912010315357), FRAC_CONST(0.14900615066034845), FRAC_CONST(0.1505228305916774), FRAC_CONST(0.15203915632824605), FRAC_CONST(0.15355512430199345), FRAC_CONST(0.15507073094570051), FRAC_CONST(0.15658597269299843), FRAC_CONST(0.15810084597837698), FRAC_CONST(0.15961534723719306), FRAC_CONST(0.16112947290567881), FRAC_CONST(0.16264321942095031), FRAC_CONST(0.16415658322101581), FRAC_CONST(0.16566956074478412), FRAC_CONST(0.16718214843207294), FRAC_CONST(0.16869434272361733), FRAC_CONST(0.17020614006107807), FRAC_CONST(0.17171753688704997), FRAC_CONST(0.17322852964507032), FRAC_CONST(0.1747391147796272), FRAC_CONST(0.17624928873616788), FRAC_CONST(0.17775904796110717), FRAC_CONST(0.17926838890183575), FRAC_CONST(0.18077730800672859), FRAC_CONST(0.1822858017251533), FRAC_CONST(0.18379386650747845), FRAC_CONST(0.1853014988050819), FRAC_CONST(0.18680869507035927), FRAC_CONST(0.18831545175673212), FRAC_CONST(0.18982176531865641), FRAC_CONST(0.1913276322116309), FRAC_CONST(0.19283304889220523), FRAC_CONST(0.1943380118179886), FRAC_CONST(0.19584251744765785), FRAC_CONST(0.19734656224096592), FRAC_CONST(0.19885014265875009), FRAC_CONST(0.20035325516294045), FRAC_CONST(0.20185589621656805), FRAC_CONST(0.20335806228377332), FRAC_CONST(0.20485974982981442), FRAC_CONST(0.20636095532107551), FRAC_CONST(0.20786167522507507), FRAC_CONST(0.20936190601047416), FRAC_CONST(0.21086164414708486), FRAC_CONST(0.21236088610587842), FRAC_CONST(0.21385962835899375), FRAC_CONST(0.21535786737974555), FRAC_CONST(0.21685559964263262), FRAC_CONST(0.21835282162334632), FRAC_CONST(0.2198495297987787), FRAC_CONST(0.22134572064703081), FRAC_CONST(0.22284139064742112), FRAC_CONST(0.2243365362804936), FRAC_CONST(0.22583115402802617), FRAC_CONST(0.22732524037303886), FRAC_CONST(0.22881879179980222), FRAC_CONST(0.23031180479384544), FRAC_CONST(0.23180427584196478), FRAC_CONST(0.23329620143223159), FRAC_CONST(0.23478757805400097), FRAC_CONST(0.23627840219791957), FRAC_CONST(0.23776867035593419), FRAC_CONST(0.23925837902129998), FRAC_CONST(0.24074752468858843), FRAC_CONST(0.24223610385369601), FRAC_CONST(0.24372411301385216), FRAC_CONST(0.24521154866762754), FRAC_CONST(0.24669840731494241), FRAC_CONST(0.24818468545707478), FRAC_CONST(0.24967037959666857), FRAC_CONST(0.25115548623774192), FRAC_CONST(0.25264000188569552), FRAC_CONST(0.25412392304732062), FRAC_CONST(0.25560724623080738), FRAC_CONST(0.25708996794575312), FRAC_CONST(0.25857208470317034), FRAC_CONST(0.26005359301549519), FRAC_CONST(0.26153448939659552), FRAC_CONST(0.263014770361779), FRAC_CONST(0.26449443242780163), FRAC_CONST(0.26597347211287559), FRAC_CONST(0.26745188593667762), FRAC_CONST(0.26892967042035726), FRAC_CONST(0.27040682208654482), FRAC_CONST(0.27188333745935972), FRAC_CONST(0.27335921306441868), FRAC_CONST(0.27483444542884394), FRAC_CONST(0.27630903108127108), FRAC_CONST(0.27778296655185769), FRAC_CONST(0.27925624837229118), FRAC_CONST(0.28072887307579719), FRAC_CONST(0.28220083719714756), FRAC_CONST(0.28367213727266843), FRAC_CONST(0.28514276984024867), FRAC_CONST(0.28661273143934779), FRAC_CONST(0.28808201861100413), FRAC_CONST(0.28955062789784303), FRAC_CONST(0.29101855584408509), FRAC_CONST(0.29248579899555388), FRAC_CONST(0.29395235389968466), FRAC_CONST(0.29541821710553201), FRAC_CONST(0.29688338516377827), FRAC_CONST(0.2983478546267414), FRAC_CONST(0.29981162204838335), FRAC_CONST(0.30127468398431795), FRAC_CONST(0.30273703699181914), FRAC_CONST(0.30419867762982911), FRAC_CONST(0.30565960245896612), FRAC_CONST(0.3071198080415331), FRAC_CONST(0.30857929094152509), FRAC_CONST(0.31003804772463789), FRAC_CONST(0.31149607495827591), FRAC_CONST(0.3129533692115602), FRAC_CONST(0.31440992705533666), FRAC_CONST(0.31586574506218396), FRAC_CONST(0.31732081980642174), FRAC_CONST(0.31877514786411848), FRAC_CONST(0.32022872581309986), FRAC_CONST(0.32168155023295658), FRAC_CONST(0.32313361770505233), FRAC_CONST(0.32458492481253215), FRAC_CONST(0.32603546814033024), FRAC_CONST(0.327485244275178), FRAC_CONST(0.3289342498056122), FRAC_CONST(0.33038248132198278), FRAC_CONST(0.33182993541646111), FRAC_CONST(0.33327660868304793), FRAC_CONST(0.33472249771758122), FRAC_CONST(0.33616759911774452), FRAC_CONST(0.33761190948307462), FRAC_CONST(0.33905542541496964), FRAC_CONST(0.34049814351669716), FRAC_CONST(0.34194006039340219), FRAC_CONST(0.34338117265211504), FRAC_CONST(0.34482147690175929), FRAC_CONST(0.34626096975316001), FRAC_CONST(0.34769964781905138), FRAC_CONST(0.34913750771408497), FRAC_CONST(0.35057454605483751), FRAC_CONST(0.35201075945981908), FRAC_CONST(0.35344614454948081), FRAC_CONST(0.35488069794622279), FRAC_CONST(0.35631441627440241), FRAC_CONST(0.3577472961603419), FRAC_CONST(0.3591793342323365), FRAC_CONST(0.36061052712066227), FRAC_CONST(0.36204087145758418), FRAC_CONST(0.36347036387736376), FRAC_CONST(0.36489900101626732), FRAC_CONST(0.36632677951257359), FRAC_CONST(0.36775369600658198), FRAC_CONST(0.36917974714062002), FRAC_CONST(0.37060492955905167), FRAC_CONST(0.37202923990828501), FRAC_CONST(0.3734526748367803), FRAC_CONST(0.37487523099505754), FRAC_CONST(0.37629690503570479), FRAC_CONST(0.37771769361338564), FRAC_CONST(0.37913759338484732), FRAC_CONST(0.38055660100892852), FRAC_CONST(0.38197471314656722), FRAC_CONST(0.38339192646080866), FRAC_CONST(0.38480823761681288), FRAC_CONST(0.38622364328186298), FRAC_CONST(0.38763814012537273), FRAC_CONST(0.38905172481889438), FRAC_CONST(0.39046439403612659), FRAC_CONST(0.39187614445292235), FRAC_CONST(0.3932869727472964), FRAC_CONST(0.39469687559943356), FRAC_CONST(0.39610584969169627), FRAC_CONST(0.39751389170863233), FRAC_CONST(0.39892099833698291), FRAC_CONST(0.40032716626569009), FRAC_CONST(0.40173239218590501), FRAC_CONST(0.4031366727909953), FRAC_CONST(0.404540004776553), FRAC_CONST(0.40594238484040251), FRAC_CONST(0.40734380968260797), FRAC_CONST(0.40874427600548136), FRAC_CONST(0.41014378051359024), FRAC_CONST(0.41154231991376522), FRAC_CONST(0.41293989091510808), FRAC_CONST(0.4143364902289991), FRAC_CONST(0.41573211456910536), FRAC_CONST(0.41712676065138787), FRAC_CONST(0.4185204251941097), FRAC_CONST(0.41991310491784362), FRAC_CONST(0.42130479654547964), FRAC_CONST(0.42269549680223295), FRAC_CONST(0.42408520241565156), FRAC_CONST(0.4254739101156238), FRAC_CONST(0.42686161663438643), FRAC_CONST(0.42824831870653196), FRAC_CONST(0.42963401306901638), FRAC_CONST(0.43101869646116703), FRAC_CONST(0.43240236562469014), FRAC_CONST(0.43378501730367852), FRAC_CONST(0.43516664824461926), FRAC_CONST(0.4365472551964012), FRAC_CONST(0.43792683491032286), FRAC_CONST(0.43930538414009995), FRAC_CONST(0.4406828996418729), FRAC_CONST(0.4420593781742147), FRAC_CONST(0.44343481649813848), FRAC_CONST(0.44480921137710488), FRAC_CONST(0.44618255957703007), FRAC_CONST(0.44755485786629301), FRAC_CONST(0.44892610301574326), FRAC_CONST(0.45029629179870861), FRAC_CONST(0.45166542099100249), FRAC_CONST(0.45303348737093158), FRAC_CONST(0.45440048771930358), FRAC_CONST(0.45576641881943464), FRAC_CONST(0.45713127745715698), FRAC_CONST(0.45849506042082627), FRAC_CONST(0.45985776450132954), FRAC_CONST(0.46121938649209238), FRAC_CONST(0.46257992318908681), FRAC_CONST(0.46393937139083852), FRAC_CONST(0.4652977278984346), FRAC_CONST(0.46665498951553092), FRAC_CONST(0.46801115304835983), FRAC_CONST(0.46936621530573752), FRAC_CONST(0.4707201730990716), FRAC_CONST(0.47207302324236866), FRAC_CONST(0.47342476255224153), FRAC_CONST(0.47477538784791712), FRAC_CONST(0.47612489595124358), FRAC_CONST(0.47747328368669806), FRAC_CONST(0.47882054788139389), FRAC_CONST(0.48016668536508839), FRAC_CONST(0.48151169297018986), FRAC_CONST(0.48285556753176567), FRAC_CONST(0.48419830588754903), FRAC_CONST(0.48553990487794696), FRAC_CONST(0.48688036134604734), FRAC_CONST(0.48821967213762679), FRAC_CONST(0.48955783410115744), FRAC_CONST(0.49089484408781509), FRAC_CONST(0.49223069895148602), FRAC_CONST(0.49356539554877477), FRAC_CONST(0.49489893073901126), FRAC_CONST(0.49623130138425825), FRAC_CONST(0.49756250434931915), FRAC_CONST(0.49889253650174459), FRAC_CONST(0.50022139471184068), FRAC_CONST(0.50154907585267539), FRAC_CONST(0.50287557680008699), FRAC_CONST(0.50420089443269034), FRAC_CONST(0.50552502563188539), FRAC_CONST(0.50684796728186321), FRAC_CONST(0.5081697162696146), FRAC_CONST(0.50949026948493636), FRAC_CONST(0.51080962382043904), FRAC_CONST(0.51212777617155469), FRAC_CONST(0.51344472343654346), FRAC_CONST(0.5147604625165012), FRAC_CONST(0.51607499031536663), FRAC_CONST(0.51738830373992906), FRAC_CONST(0.51870039969983495), FRAC_CONST(0.52001127510759604), FRAC_CONST(0.52132092687859566), FRAC_CONST(0.52262935193109661), FRAC_CONST(0.5239365471862486), FRAC_CONST(0.52524250956809471), FRAC_CONST(0.52654723600357944), FRAC_CONST(0.52785072342255523), FRAC_CONST(0.52915296875779061), FRAC_CONST(0.53045396894497632), FRAC_CONST(0.53175372092273332), FRAC_CONST(0.53305222163261945), FRAC_CONST(0.53434946801913752), FRAC_CONST(0.53564545702974109), FRAC_CONST(0.53694018561484291), FRAC_CONST(0.5382336507278217), FRAC_CONST(0.53952584932502889), FRAC_CONST(0.54081677836579667), FRAC_CONST(0.54210643481244392), FRAC_CONST(0.5433948156302848), FRAC_CONST(0.54468191778763453), FRAC_CONST(0.54596773825581757), FRAC_CONST(0.54725227400917409), FRAC_CONST(0.54853552202506739), FRAC_CONST(0.54981747928389091), FRAC_CONST(0.55109814276907543), FRAC_CONST(0.55237750946709607), FRAC_CONST(0.55365557636747931), FRAC_CONST(0.55493234046281037), FRAC_CONST(0.55620779874873993), FRAC_CONST(0.55748194822399155), FRAC_CONST(0.55875478589036831), FRAC_CONST(0.56002630875276038), FRAC_CONST(0.56129651381915147), FRAC_CONST(0.56256539810062656), FRAC_CONST(0.56383295861137817), FRAC_CONST(0.56509919236871398), FRAC_CONST(0.56636409639306384), FRAC_CONST(0.56762766770798623), FRAC_CONST(0.56888990334017586), FRAC_CONST(0.5701508003194703), FRAC_CONST(0.57141035567885723), FRAC_CONST(0.57266856645448116), FRAC_CONST(0.57392542968565075), FRAC_CONST(0.57518094241484508), FRAC_CONST(0.57643510168772183), FRAC_CONST(0.5776879045531228), FRAC_CONST(0.57893934806308178), FRAC_CONST(0.58018942927283168), FRAC_CONST(0.58143814524081017), FRAC_CONST(0.58268549302866846), FRAC_CONST(0.58393146970127618), FRAC_CONST(0.58517607232673041), FRAC_CONST(0.5864192979763605), FRAC_CONST(0.58766114372473666), FRAC_CONST(0.58890160664967572), FRAC_CONST(0.59014068383224882), FRAC_CONST(0.59137837235678758), FRAC_CONST(0.59261466931089113), FRAC_CONST(0.59384957178543363), FRAC_CONST(0.59508307687456996), FRAC_CONST(0.59631518167574371), FRAC_CONST(0.59754588328969316), FRAC_CONST(0.59877517882045872), FRAC_CONST(0.60000306537538894), FRAC_CONST(0.6012295400651485), FRAC_CONST(0.60245460000372375), FRAC_CONST(0.60367824230843037), FRAC_CONST(0.60490046409991982), FRAC_CONST(0.60612126250218612), FRAC_CONST(0.60734063464257293), FRAC_CONST(0.60855857765177945), FRAC_CONST(0.60977508866386843), FRAC_CONST(0.61099016481627166), FRAC_CONST(0.61220380324979795), FRAC_CONST(0.61341600110863859), FRAC_CONST(0.61462675554037505), FRAC_CONST(0.61583606369598509), FRAC_CONST(0.61704392272984976), FRAC_CONST(0.61825032979976025), FRAC_CONST(0.61945528206692402), FRAC_CONST(0.62065877669597214), FRAC_CONST(0.62186081085496536), FRAC_CONST(0.62306138171540126), FRAC_CONST(0.62426048645222065), FRAC_CONST(0.62545812224381436), FRAC_CONST(0.62665428627202935), FRAC_CONST(0.62784897572217646), FRAC_CONST(0.629042187783036), FRAC_CONST(0.63023391964686437), FRAC_CONST(0.63142416850940186), FRAC_CONST(0.63261293156987741), FRAC_CONST(0.63380020603101728), FRAC_CONST(0.63498598909904946), FRAC_CONST(0.63617027798371217), FRAC_CONST(0.63735306989825913), FRAC_CONST(0.63853436205946679), FRAC_CONST(0.63971415168764045), FRAC_CONST(0.64089243600662138), FRAC_CONST(0.64206921224379254), FRAC_CONST(0.64324447763008585), FRAC_CONST(0.64441822939998838), FRAC_CONST(0.64559046479154869), FRAC_CONST(0.64676118104638392), FRAC_CONST(0.64793037540968534), FRAC_CONST(0.64909804513022595), FRAC_CONST(0.65026418746036585), FRAC_CONST(0.65142879965605982), FRAC_CONST(0.65259187897686244), FRAC_CONST(0.65375342268593606), FRAC_CONST(0.65491342805005603), FRAC_CONST(0.6560718923396176), FRAC_CONST(0.65722881282864254), FRAC_CONST(0.65838418679478505), FRAC_CONST(0.65953801151933866), FRAC_CONST(0.6606902842872423), FRAC_CONST(0.66184100238708687), FRAC_CONST(0.66299016311112147), FRAC_CONST(0.66413776375526001), FRAC_CONST(0.66528380161908718), FRAC_CONST(0.66642827400586524), FRAC_CONST(0.66757117822254031), FRAC_CONST(0.66871251157974798), FRAC_CONST(0.66985227139182102), FRAC_CONST(0.67099045497679422), FRAC_CONST(0.67212705965641173), FRAC_CONST(0.67326208275613297), FRAC_CONST(0.67439552160513905), FRAC_CONST(0.67552737353633852), FRAC_CONST(0.67665763588637495), FRAC_CONST(0.6777863059956315), FRAC_CONST(0.67891338120823841), FRAC_CONST(0.68003885887207893), FRAC_CONST(0.68116273633879543), FRAC_CONST(0.68228501096379557), FRAC_CONST(0.68340568010625868), FRAC_CONST(0.6845247411291423), FRAC_CONST(0.68564219139918747), FRAC_CONST(0.68675802828692589), FRAC_CONST(0.68787224916668555), FRAC_CONST(0.68898485141659704), FRAC_CONST(0.69009583241859995), FRAC_CONST(0.69120518955844845), FRAC_CONST(0.69231292022571822), FRAC_CONST(0.69341902181381176), FRAC_CONST(0.69452349171996552), FRAC_CONST(0.69562632734525487), FRAC_CONST(0.6967275260946012), FRAC_CONST(0.69782708537677729), FRAC_CONST(0.69892500260441415), FRAC_CONST(0.70002127519400625), FRAC_CONST(0.70111590056591866), FRAC_CONST(0.70220887614439187), FRAC_CONST(0.70330019935754873), FRAC_CONST(0.70438986763740041), FRAC_CONST(0.7054778784198521), FRAC_CONST(0.70656422914470951), FRAC_CONST(0.70764891725568435), FRAC_CONST(0.70873194020040065), FRAC_CONST(0.70981329543040084), FRAC_CONST(0.71089298040115168), FRAC_CONST(0.71197099257204999), FRAC_CONST(0.71304732940642923), FRAC_CONST(0.71412198837156471), FRAC_CONST(0.71519496693868001), FRAC_CONST(0.71626626258295312), FRAC_CONST(0.71733587278352173), FRAC_CONST(0.71840379502348972), FRAC_CONST(0.71947002678993299), FRAC_CONST(0.72053456557390527), FRAC_CONST(0.72159740887044366), FRAC_CONST(0.72265855417857561), FRAC_CONST(0.72371799900132339), FRAC_CONST(0.72477574084571128), FRAC_CONST(0.72583177722277037), FRAC_CONST(0.72688610564754497), FRAC_CONST(0.72793872363909862), FRAC_CONST(0.72898962872051931), FRAC_CONST(0.73003881841892615), FRAC_CONST(0.73108629026547423), FRAC_CONST(0.73213204179536129), FRAC_CONST(0.73317607054783274), FRAC_CONST(0.73421837406618817), FRAC_CONST(0.73525894989778673), FRAC_CONST(0.73629779559405306), FRAC_CONST(0.73733490871048279), FRAC_CONST(0.73837028680664851), FRAC_CONST(0.73940392744620576), FRAC_CONST(0.74043582819689802), FRAC_CONST(0.74146598663056329), FRAC_CONST(0.74249440032313918), FRAC_CONST(0.74352106685466912), FRAC_CONST(0.74454598380930725), FRAC_CONST(0.74556914877532543), FRAC_CONST(0.74659055934511731), FRAC_CONST(0.74761021311520515), FRAC_CONST(0.74862810768624533), FRAC_CONST(0.74964424066303348), FRAC_CONST(0.75065860965451059), FRAC_CONST(0.75167121227376843), FRAC_CONST(0.75268204613805523), FRAC_CONST(0.75369110886878121), FRAC_CONST(0.75469839809152439), FRAC_CONST(0.75570391143603588), FRAC_CONST(0.75670764653624567), FRAC_CONST(0.75770960103026808), FRAC_CONST(0.75870977256040739), FRAC_CONST(0.75970815877316344), FRAC_CONST(0.76070475731923692), FRAC_CONST(0.76169956585353527), FRAC_CONST(0.76269258203517787), FRAC_CONST(0.76368380352750187), FRAC_CONST(0.76467322799806714), FRAC_CONST(0.76566085311866239), FRAC_CONST(0.76664667656531038), FRAC_CONST(0.76763069601827327), FRAC_CONST(0.76861290916205827), FRAC_CONST(0.76959331368542294), FRAC_CONST(0.7705719072813807), FRAC_CONST(0.7715486876472063), FRAC_CONST(0.77252365248444133), FRAC_CONST(0.77349679949889905), FRAC_CONST(0.77446812640067086), FRAC_CONST(0.77543763090413043), FRAC_CONST(0.77640531072794039), FRAC_CONST(0.7773711635950562), FRAC_CONST(0.77833518723273309), FRAC_CONST(0.7792973793725303), FRAC_CONST(0.78025773775031659), FRAC_CONST(0.78121626010627609), FRAC_CONST(0.7821729441849129), FRAC_CONST(0.78312778773505731), FRAC_CONST(0.78408078850986995), FRAC_CONST(0.78503194426684808), FRAC_CONST(0.78598125276783015), FRAC_CONST(0.7869287117790017), FRAC_CONST(0.78787431907090011), FRAC_CONST(0.78881807241842017), FRAC_CONST(0.78975996960081907), FRAC_CONST(0.79070000840172161), FRAC_CONST(0.79163818660912577), FRAC_CONST(0.79257450201540758), FRAC_CONST(0.79350895241732666), FRAC_CONST(0.79444153561603059), FRAC_CONST(0.79537224941706119), FRAC_CONST(0.79630109163035911), FRAC_CONST(0.7972280600702687), FRAC_CONST(0.79815315255554375), FRAC_CONST(0.79907636690935235), FRAC_CONST(0.79999770095928191), FRAC_CONST(0.8009171525373443), FRAC_CONST(0.80183471947998131), FRAC_CONST(0.80275039962806916), FRAC_CONST(0.80366419082692409), FRAC_CONST(0.804576090926307), FRAC_CONST(0.80548609778042912), FRAC_CONST(0.80639420924795624), FRAC_CONST(0.80730042319201445), FRAC_CONST(0.80820473748019472), FRAC_CONST(0.80910714998455813), FRAC_CONST(0.81000765858164114), FRAC_CONST(0.81090626115245967), FRAC_CONST(0.81180295558251536), FRAC_CONST(0.81269773976179949), FRAC_CONST(0.81359061158479851), FRAC_CONST(0.81448156895049861), FRAC_CONST(0.81537060976239129), FRAC_CONST(0.81625773192847739), FRAC_CONST(0.81714293336127297), FRAC_CONST(0.81802621197781344), FRAC_CONST(0.81890756569965895), FRAC_CONST(0.81978699245289899), FRAC_CONST(0.82066449016815746), FRAC_CONST(0.82154005678059761), FRAC_CONST(0.82241369022992639), FRAC_CONST(0.82328538846040011), FRAC_CONST(0.82415514942082857), FRAC_CONST(0.82502297106458022), FRAC_CONST(0.82588885134958678), FRAC_CONST(0.82675278823834852), FRAC_CONST(0.8276147796979384), FRAC_CONST(0.82847482370000713), FRAC_CONST(0.82933291822078825), FRAC_CONST(0.83018906124110237), FRAC_CONST(0.83104325074636232), FRAC_CONST(0.83189548472657759), FRAC_CONST(0.83274576117635946), FRAC_CONST(0.83359407809492514), FRAC_CONST(0.83444043348610319), FRAC_CONST(0.83528482535833737), FRAC_CONST(0.83612725172469216), FRAC_CONST(0.83696771060285702), FRAC_CONST(0.83780620001515094), FRAC_CONST(0.8386427179885273), FRAC_CONST(0.83947726255457855), FRAC_CONST(0.84030983174954077), FRAC_CONST(0.84114042361429808), FRAC_CONST(0.84196903619438768), FRAC_CONST(0.84279566754000412), FRAC_CONST(0.84362031570600404), FRAC_CONST(0.84444297875191066), FRAC_CONST(0.84526365474191822), FRAC_CONST(0.84608234174489694), FRAC_CONST(0.84689903783439735), FRAC_CONST(0.84771374108865427), FRAC_CONST(0.84852644959059265), FRAC_CONST(0.84933716142783067), FRAC_CONST(0.85014587469268521), FRAC_CONST(0.85095258748217573), FRAC_CONST(0.85175729789802912), FRAC_CONST(0.85256000404668397), FRAC_CONST(0.85336070403929543), FRAC_CONST(0.85415939599173873), FRAC_CONST(0.85495607802461482), FRAC_CONST(0.85575074826325392), FRAC_CONST(0.85654340483771996), FRAC_CONST(0.85733404588281559), FRAC_CONST(0.85812266953808602), FRAC_CONST(0.8589092739478239), FRAC_CONST(0.85969385726107261), FRAC_CONST(0.86047641763163207), FRAC_CONST(0.86125695321806206), FRAC_CONST(0.86203546218368721), FRAC_CONST(0.86281194269660033), FRAC_CONST(0.86358639292966799), FRAC_CONST(0.86435881106053403), FRAC_CONST(0.86512919527162369), FRAC_CONST(0.86589754375014882), FRAC_CONST(0.86666385468811102), FRAC_CONST(0.86742812628230692), FRAC_CONST(0.86819035673433131), FRAC_CONST(0.86895054425058238), FRAC_CONST(0.86970868704226556), FRAC_CONST(0.87046478332539767), FRAC_CONST(0.8712188313208109), FRAC_CONST(0.8719708292541577), FRAC_CONST(0.8727207753559143), FRAC_CONST(0.87346866786138488), FRAC_CONST(0.8742145050107063), FRAC_CONST(0.87495828504885154), FRAC_CONST(0.8757000062256346), FRAC_CONST(0.87643966679571361), FRAC_CONST(0.87717726501859594), FRAC_CONST(0.87791279915864173), FRAC_CONST(0.87864626748506813), FRAC_CONST(0.87937766827195318), FRAC_CONST(0.88010699979824036), FRAC_CONST(0.88083426034774204), FRAC_CONST(0.88155944820914378), FRAC_CONST(0.8822825616760086), FRAC_CONST(0.88300359904678072), FRAC_CONST(0.88372255862478966), FRAC_CONST(0.8844394387182537), FRAC_CONST(0.88515423764028511), FRAC_CONST(0.88586695370889279), FRAC_CONST(0.88657758524698704), FRAC_CONST(0.88728613058238315), FRAC_CONST(0.88799258804780556), FRAC_CONST(0.88869695598089171), FRAC_CONST(0.88939923272419552), FRAC_CONST(0.89009941662519221), FRAC_CONST(0.89079750603628149), FRAC_CONST(0.89149349931479138), FRAC_CONST(0.89218739482298248), FRAC_CONST(0.89287919092805168), FRAC_CONST(0.89356888600213602), FRAC_CONST(0.89425647842231604), FRAC_CONST(0.89494196657062075), FRAC_CONST(0.89562534883403), FRAC_CONST(0.89630662360447966), FRAC_CONST(0.89698578927886397), FRAC_CONST(0.89766284425904075), FRAC_CONST(0.89833778695183419), FRAC_CONST(0.89901061576903907), FRAC_CONST(0.89968132912742393), FRAC_CONST(0.9003499254487356), FRAC_CONST(0.90101640315970233), FRAC_CONST(0.90168076069203773), FRAC_CONST(0.9023429964824442), FRAC_CONST(0.90300310897261704), FRAC_CONST(0.90366109660924798), FRAC_CONST(0.90431695784402832), FRAC_CONST(0.90497069113365325), FRAC_CONST(0.90562229493982516), FRAC_CONST(0.90627176772925766), FRAC_CONST(0.90691910797367803), FRAC_CONST(0.90756431414983252), FRAC_CONST(0.9082073847394887), FRAC_CONST(0.90884831822943912), FRAC_CONST(0.90948711311150543), FRAC_CONST(0.91012376788254157), FRAC_CONST(0.91075828104443757), FRAC_CONST(0.91139065110412232), FRAC_CONST(0.91202087657356823), FRAC_CONST(0.9126489559697939), FRAC_CONST(0.91327488781486776), FRAC_CONST(0.91389867063591168), FRAC_CONST(0.91452030296510445), FRAC_CONST(0.91513978333968526), FRAC_CONST(0.91575711030195672), FRAC_CONST(0.91637228239928914), FRAC_CONST(0.91698529818412289), FRAC_CONST(0.91759615621397295), FRAC_CONST(0.9182048550514309), FRAC_CONST(0.91881139326416994), FRAC_CONST(0.91941576942494696), FRAC_CONST(0.92001798211160657), FRAC_CONST(0.92061802990708386), FRAC_CONST(0.92121591139940873), FRAC_CONST(0.92181162518170812), FRAC_CONST(0.92240516985220988), FRAC_CONST(0.92299654401424625), FRAC_CONST(0.92358574627625656), FRAC_CONST(0.9241727752517912), FRAC_CONST(0.92475762955951391), FRAC_CONST(0.9253403078232062), FRAC_CONST(0.92592080867176996), FRAC_CONST(0.92649913073923051), FRAC_CONST(0.9270752726647401), FRAC_CONST(0.92764923309258118), FRAC_CONST(0.92822101067216944), FRAC_CONST(0.92879060405805702), FRAC_CONST(0.9293580119099355), FRAC_CONST(0.92992323289263956), FRAC_CONST(0.93048626567614978), FRAC_CONST(0.93104710893559517), FRAC_CONST(0.93160576135125783), FRAC_CONST(0.93216222160857432), FRAC_CONST(0.93271648839814025), FRAC_CONST(0.93326856041571205), FRAC_CONST(0.93381843636221096), FRAC_CONST(0.9343661149437259), FRAC_CONST(0.93491159487151609), FRAC_CONST(0.93545487486201462), FRAC_CONST(0.9359959536368313), FRAC_CONST(0.9365348299227555), FRAC_CONST(0.93707150245175919), FRAC_CONST(0.93760596996099999), FRAC_CONST(0.93813823119282436), FRAC_CONST(0.93866828489477017), FRAC_CONST(0.9391961298195699), FRAC_CONST(0.93972176472515334), FRAC_CONST(0.94024518837465088), FRAC_CONST(0.94076639953639607), FRAC_CONST(0.94128539698392866), FRAC_CONST(0.94180217949599765), FRAC_CONST(0.94231674585656378), FRAC_CONST(0.94282909485480271), FRAC_CONST(0.94333922528510772), FRAC_CONST(0.94384713594709269), FRAC_CONST(0.94435282564559475), FRAC_CONST(0.94485629319067721), FRAC_CONST(0.94535753739763229), FRAC_CONST(0.94585655708698391), FRAC_CONST(0.94635335108449059), FRAC_CONST(0.946847918221148), FRAC_CONST(0.94734025733319194), FRAC_CONST(0.94783036726210101), FRAC_CONST(0.94831824685459909), FRAC_CONST(0.94880389496265838), FRAC_CONST(0.94928731044350201), FRAC_CONST(0.94976849215960668), FRAC_CONST(0.95024743897870523), FRAC_CONST(0.95072414977378961), FRAC_CONST(0.95119862342311323), FRAC_CONST(0.95167085881019386), FRAC_CONST(0.95214085482381583), FRAC_CONST(0.95260861035803324), FRAC_CONST(0.9530741243121722), FRAC_CONST(0.95353739559083328), FRAC_CONST(0.95399842310389449), FRAC_CONST(0.95445720576651349), FRAC_CONST(0.95491374249913052), FRAC_CONST(0.95536803222747024), FRAC_CONST(0.95582007388254542), FRAC_CONST(0.95626986640065814), FRAC_CONST(0.95671740872340305), FRAC_CONST(0.9571626997976701), FRAC_CONST(0.95760573857564624), FRAC_CONST(0.9580465240148186), FRAC_CONST(0.9584850550779761), FRAC_CONST(0.95892133073321306), FRAC_CONST(0.95935534995393079), FRAC_CONST(0.9597871117188399), FRAC_CONST(0.96021661501196343), FRAC_CONST(0.96064385882263847), FRAC_CONST(0.96106884214551935), FRAC_CONST(0.961491563980579), FRAC_CONST(0.9619120233331121), FRAC_CONST(0.9623302192137374), FRAC_CONST(0.96274615063839941), FRAC_CONST(0.96315981662837136), FRAC_CONST(0.96357121621025721), FRAC_CONST(0.96398034841599411), FRAC_CONST(0.96438721228285429), FRAC_CONST(0.9647918068534479), FRAC_CONST(0.96519413117572472), FRAC_CONST(0.96559418430297683), FRAC_CONST(0.96599196529384057), FRAC_CONST(0.96638747321229879), FRAC_CONST(0.96678070712768327), FRAC_CONST(0.96717166611467664), FRAC_CONST(0.96756034925331436), FRAC_CONST(0.9679467556289878), FRAC_CONST(0.9683308843324453), FRAC_CONST(0.96871273445979478), FRAC_CONST(0.9690923051125061), FRAC_CONST(0.96946959539741295), FRAC_CONST(0.96984460442671483), FRAC_CONST(0.97021733131797916), FRAC_CONST(0.97058777519414363), FRAC_CONST(0.97095593518351797), FRAC_CONST(0.97132181041978616), FRAC_CONST(0.97168540004200854), FRAC_CONST(0.9720467031946235), FRAC_CONST(0.97240571902744977), FRAC_CONST(0.97276244669568857), FRAC_CONST(0.97311688535992513), FRAC_CONST(0.97346903418613095), FRAC_CONST(0.9738188923456661), FRAC_CONST(0.97416645901528032), FRAC_CONST(0.97451173337711572), FRAC_CONST(0.97485471461870843), FRAC_CONST(0.97519540193299037), FRAC_CONST(0.97553379451829136), FRAC_CONST(0.97586989157834103), FRAC_CONST(0.97620369232227056), FRAC_CONST(0.97653519596461447), FRAC_CONST(0.97686440172531264), FRAC_CONST(0.97719130882971228), FRAC_CONST(0.97751591650856928), FRAC_CONST(0.97783822399805043), FRAC_CONST(0.97815823053973505), FRAC_CONST(0.97847593538061683), FRAC_CONST(0.97879133777310567), FRAC_CONST(0.97910443697502925), FRAC_CONST(0.97941523224963478), FRAC_CONST(0.97972372286559117), FRAC_CONST(0.98002990809698998), FRAC_CONST(0.98033378722334796), FRAC_CONST(0.98063535952960812), FRAC_CONST(0.98093462430614164), FRAC_CONST(0.98123158084874973), FRAC_CONST(0.98152622845866466), FRAC_CONST(0.9818185664425525), FRAC_CONST(0.98210859411251361), FRAC_CONST(0.98239631078608469), FRAC_CONST(0.98268171578624086), FRAC_CONST(0.98296480844139644), FRAC_CONST(0.98324558808540707), FRAC_CONST(0.98352405405757126), FRAC_CONST(0.98380020570263149), FRAC_CONST(0.98407404237077645), FRAC_CONST(0.9843455634176419), FRAC_CONST(0.9846147682043126), FRAC_CONST(0.9848816560973237), FRAC_CONST(0.98514622646866223), FRAC_CONST(0.98540847869576842), FRAC_CONST(0.98566841216153755), FRAC_CONST(0.98592602625432113), FRAC_CONST(0.98618132036792827), FRAC_CONST(0.98643429390162707), FRAC_CONST(0.98668494626014669), FRAC_CONST(0.98693327685367771), FRAC_CONST(0.98717928509787434), FRAC_CONST(0.98742297041385541), FRAC_CONST(0.98766433222820571), FRAC_CONST(0.98790336997297779), FRAC_CONST(0.98814008308569257), FRAC_CONST(0.98837447100934128), FRAC_CONST(0.98860653319238645), FRAC_CONST(0.98883626908876354), FRAC_CONST(0.98906367815788154), FRAC_CONST(0.98928875986462517), FRAC_CONST(0.98951151367935519), FRAC_CONST(0.98973193907791057), FRAC_CONST(0.98995003554160899), FRAC_CONST(0.9901658025572484), FRAC_CONST(0.99037923961710816), FRAC_CONST(0.99059034621895015), FRAC_CONST(0.99079912186602037), FRAC_CONST(0.99100556606704937), FRAC_CONST(0.99120967833625406), FRAC_CONST(0.99141145819333854), FRAC_CONST(0.99161090516349537), FRAC_CONST(0.99180801877740643), FRAC_CONST(0.99200279857124452), FRAC_CONST(0.99219524408667392), FRAC_CONST(0.99238535487085167), FRAC_CONST(0.99257313047642881), FRAC_CONST(0.99275857046155114), FRAC_CONST(0.99294167438986047), FRAC_CONST(0.99312244183049558), FRAC_CONST(0.99330087235809328), FRAC_CONST(0.99347696555278919), FRAC_CONST(0.99365072100021912), FRAC_CONST(0.99382213829151966), FRAC_CONST(0.99399121702332938), FRAC_CONST(0.99415795679778973), FRAC_CONST(0.99432235722254581), FRAC_CONST(0.9944844179107476), FRAC_CONST(0.99464413848105071), FRAC_CONST(0.99480151855761711), FRAC_CONST(0.99495655777011638), FRAC_CONST(0.99510925575372611), FRAC_CONST(0.99525961214913339), FRAC_CONST(0.9954076266025349), FRAC_CONST(0.99555329876563847), FRAC_CONST(0.99569662829566352), FRAC_CONST(0.99583761485534161), FRAC_CONST(0.99597625811291779), FRAC_CONST(0.99611255774215113), FRAC_CONST(0.99624651342231552), FRAC_CONST(0.99637812483820021), FRAC_CONST(0.99650739168011082), FRAC_CONST(0.9966343136438699), FRAC_CONST(0.996758890430818), FRAC_CONST(0.99688112174781385), FRAC_CONST(0.99700100730723529), FRAC_CONST(0.99711854682697998), FRAC_CONST(0.99723374003046616), FRAC_CONST(0.99734658664663323), FRAC_CONST(0.99745708640994191), FRAC_CONST(0.99756523906037575), FRAC_CONST(0.997671044343441), FRAC_CONST(0.99777450201016782), FRAC_CONST(0.99787561181711015), FRAC_CONST(0.99797437352634699), FRAC_CONST(0.99807078690548234), FRAC_CONST(0.99816485172764624), FRAC_CONST(0.99825656777149518), FRAC_CONST(0.99834593482121237), FRAC_CONST(0.99843295266650844), FRAC_CONST(0.99851762110262221), FRAC_CONST(0.99859993993032037), FRAC_CONST(0.99867990895589909), FRAC_CONST(0.99875752799118334), FRAC_CONST(0.99883279685352799), FRAC_CONST(0.99890571536581829), FRAC_CONST(0.99897628335646982), FRAC_CONST(0.99904450065942929), FRAC_CONST(0.99911036711417489), FRAC_CONST(0.99917388256571638), FRAC_CONST(0.99923504686459585), FRAC_CONST(0.99929385986688779), FRAC_CONST(0.99935032143419944), FRAC_CONST(0.9994044314336713), FRAC_CONST(0.99945618973797734), FRAC_CONST(0.99950559622532531), FRAC_CONST(0.99955265077945699), FRAC_CONST(0.99959735328964838), FRAC_CONST(0.9996397036507102), FRAC_CONST(0.99967970176298793), FRAC_CONST(0.99971734753236219), FRAC_CONST(0.99975264087024884), FRAC_CONST(0.99978558169359921), FRAC_CONST(0.99981616992490041), FRAC_CONST(0.99984440549217524), FRAC_CONST(0.99987028832898295), FRAC_CONST(0.99989381837441849), FRAC_CONST(0.99991499557311347), FRAC_CONST(0.999933819875236), FRAC_CONST(0.99995029123649048), FRAC_CONST(0.99996440961811828), FRAC_CONST(0.99997617498689761), FRAC_CONST(0.9999855873151432), FRAC_CONST(0.99999264658070719), FRAC_CONST(0.99999735276697821), FRAC_CONST(0.99999970586288223) }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const real_t sine_long_960[] = { FRAC_CONST(0.00081812299560725323), FRAC_CONST(0.0024543667964602917), FRAC_CONST(0.0040906040262347889), FRAC_CONST(0.0057268303042312674), FRAC_CONST(0.0073630412497795667), FRAC_CONST(0.0089992324822505774), FRAC_CONST(0.010635399621067975), FRAC_CONST(0.012271538285719924), FRAC_CONST(0.013907644095770845), FRAC_CONST(0.015543712670873098), FRAC_CONST(0.017179739630778748), FRAC_CONST(0.018815720595351273), FRAC_CONST(0.020451651184577292), FRAC_CONST(0.022087527018578291), FRAC_CONST(0.023723343717622358), FRAC_CONST(0.025359096902135895), FRAC_CONST(0.02699478219271537), FRAC_CONST(0.028630395210139003), FRAC_CONST(0.030265931575378519), FRAC_CONST(0.031901386909610863), FRAC_CONST(0.033536756834229922), FRAC_CONST(0.035172036970858266), FRAC_CONST(0.036807222941358832), FRAC_CONST(0.038442310367846677), FRAC_CONST(0.040077294872700696), FRAC_CONST(0.041712172078575326), FRAC_CONST(0.043346937608412288), FRAC_CONST(0.044981587085452281), FRAC_CONST(0.046616116133246711), FRAC_CONST(0.048250520375669431), FRAC_CONST(0.049884795436928406), FRAC_CONST(0.051518936941577477), FRAC_CONST(0.053152940514528055), FRAC_CONST(0.05478680178106083), FRAC_CONST(0.056420516366837495), FRAC_CONST(0.05805407989791244), FRAC_CONST(0.059687488000744485), FRAC_CONST(0.061320736302208578), FRAC_CONST(0.062953820429607482), FRAC_CONST(0.064586736010683557), FRAC_CONST(0.066219478673630344), FRAC_CONST(0.06785204404710439), FRAC_CONST(0.069484427760236861), FRAC_CONST(0.071116625442645326), FRAC_CONST(0.072748632724445372), FRAC_CONST(0.07438044523626236), FRAC_CONST(0.076012058609243122), FRAC_CONST(0.077643468475067631), FRAC_CONST(0.079274670465960706), FRAC_CONST(0.080905660214703745), FRAC_CONST(0.082536433354646319), FRAC_CONST(0.084166985519717977), FRAC_CONST(0.085797312344439894), FRAC_CONST(0.08742740946393647), FRAC_CONST(0.089057272513947183), FRAC_CONST(0.090686897130838162), FRAC_CONST(0.092316278951613845), FRAC_CONST(0.093945413613928788), FRAC_CONST(0.095574296756099186), FRAC_CONST(0.097202924017114667), FRAC_CONST(0.098831291036649963), FRAC_CONST(0.10045939345507648), FRAC_CONST(0.10208722691347409), FRAC_CONST(0.10371478705364276), FRAC_CONST(0.10534206951811415), FRAC_CONST(0.10696906995016341), FRAC_CONST(0.10859578399382072), FRAC_CONST(0.11022220729388306), FRAC_CONST(0.11184833549592579), FRAC_CONST(0.11347416424631435), FRAC_CONST(0.11509968919221586), FRAC_CONST(0.11672490598161089), FRAC_CONST(0.11834981026330495), FRAC_CONST(0.11997439768694031), FRAC_CONST(0.12159866390300751), FRAC_CONST(0.12322260456285709), FRAC_CONST(0.12484621531871121), FRAC_CONST(0.12646949182367517), FRAC_CONST(0.12809242973174936), FRAC_CONST(0.12971502469784052), FRAC_CONST(0.13133727237777362), FRAC_CONST(0.13295916842830346), FRAC_CONST(0.13458070850712617), FRAC_CONST(0.13620188827289101), FRAC_CONST(0.1378227033852118), FRAC_CONST(0.13944314950467873), FRAC_CONST(0.14106322229286994), FRAC_CONST(0.14268291741236291), FRAC_CONST(0.14430223052674654), FRAC_CONST(0.1459211573006321), FRAC_CONST(0.14753969339966552), FRAC_CONST(0.14915783449053857), FRAC_CONST(0.15077557624100058), FRAC_CONST(0.15239291431987001), FRAC_CONST(0.1540098443970461), FRAC_CONST(0.15562636214352044), FRAC_CONST(0.15724246323138855), FRAC_CONST(0.15885814333386142), FRAC_CONST(0.16047339812527725), FRAC_CONST(0.16208822328111283), FRAC_CONST(0.16370261447799525), FRAC_CONST(0.16531656739371339), FRAC_CONST(0.16693007770722967), FRAC_CONST(0.16854314109869134), FRAC_CONST(0.17015575324944232), FRAC_CONST(0.17176790984203447), FRAC_CONST(0.17337960656023954), FRAC_CONST(0.1749908390890603), FRAC_CONST(0.17660160311474243), FRAC_CONST(0.17821189432478593), FRAC_CONST(0.17982170840795647), FRAC_CONST(0.18143104105429744), FRAC_CONST(0.18303988795514095), FRAC_CONST(0.1846482448031197), FRAC_CONST(0.18625610729217834), FRAC_CONST(0.1878634711175852), FRAC_CONST(0.18947033197594348), FRAC_CONST(0.19107668556520319), FRAC_CONST(0.19268252758467228), FRAC_CONST(0.19428785373502844), FRAC_CONST(0.19589265971833042), FRAC_CONST(0.19749694123802966), FRAC_CONST(0.19910069399898173), FRAC_CONST(0.20070391370745785), FRAC_CONST(0.20230659607115639), FRAC_CONST(0.20390873679921437), FRAC_CONST(0.20551033160221882), FRAC_CONST(0.20711137619221856), FRAC_CONST(0.2087118662827353), FRAC_CONST(0.21031179758877552), FRAC_CONST(0.21191116582684155), FRAC_CONST(0.21350996671494335), FRAC_CONST(0.21510819597260972), FRAC_CONST(0.21670584932089998), FRAC_CONST(0.2183029224824154), FRAC_CONST(0.21989941118131037), FRAC_CONST(0.22149531114330431), FRAC_CONST(0.22309061809569264), FRAC_CONST(0.22468532776735861), FRAC_CONST(0.22627943588878449), FRAC_CONST(0.22787293819206314), FRAC_CONST(0.22946583041090929), FRAC_CONST(0.23105810828067114), FRAC_CONST(0.23264976753834157), FRAC_CONST(0.23424080392256985), FRAC_CONST(0.2358312131736727), FRAC_CONST(0.23742099103364595), FRAC_CONST(0.23901013324617584), FRAC_CONST(0.24059863555665045), FRAC_CONST(0.24218649371217096), FRAC_CONST(0.24377370346156332), FRAC_CONST(0.24536026055538934), FRAC_CONST(0.24694616074595824), FRAC_CONST(0.24853139978733788), FRAC_CONST(0.25011597343536629), FRAC_CONST(0.25169987744766298), FRAC_CONST(0.25328310758364025), FRAC_CONST(0.25486565960451457), FRAC_CONST(0.25644752927331788), FRAC_CONST(0.25802871235490898), FRAC_CONST(0.25960920461598508), FRAC_CONST(0.26118900182509258), FRAC_CONST(0.26276809975263904), FRAC_CONST(0.264346494170904), FRAC_CONST(0.26592418085405067), FRAC_CONST(0.26750115557813692), FRAC_CONST(0.2690774141211269), FRAC_CONST(0.27065295226290209), FRAC_CONST(0.2722277657852728), FRAC_CONST(0.27380185047198918), FRAC_CONST(0.27537520210875299), FRAC_CONST(0.2769478164832283), FRAC_CONST(0.27851968938505312), FRAC_CONST(0.28009081660585067), FRAC_CONST(0.28166119393924061), FRAC_CONST(0.28323081718085019), FRAC_CONST(0.28479968212832563), FRAC_CONST(0.28636778458134327), FRAC_CONST(0.28793512034162105), FRAC_CONST(0.2895016852129294), FRAC_CONST(0.29106747500110264), FRAC_CONST(0.29263248551405047), FRAC_CONST(0.2941967125617686), FRAC_CONST(0.29576015195635058), FRAC_CONST(0.29732279951199847), FRAC_CONST(0.29888465104503475), FRAC_CONST(0.30044570237391266), FRAC_CONST(0.30200594931922808), FRAC_CONST(0.30356538770373032), FRAC_CONST(0.30512401335233358), FRAC_CONST(0.30668182209212791), FRAC_CONST(0.3082388097523906), FRAC_CONST(0.30979497216459695), FRAC_CONST(0.31135030516243201), FRAC_CONST(0.3129048045818012), FRAC_CONST(0.31445846626084178), FRAC_CONST(0.31601128603993378), FRAC_CONST(0.31756325976171151), FRAC_CONST(0.31911438327107416), FRAC_CONST(0.32066465241519732), FRAC_CONST(0.32221406304354389), FRAC_CONST(0.3237626110078754), FRAC_CONST(0.32531029216226293), FRAC_CONST(0.32685710236309828), FRAC_CONST(0.32840303746910487), FRAC_CONST(0.32994809334134939), FRAC_CONST(0.3314922658432522), FRAC_CONST(0.33303555084059877), FRAC_CONST(0.33457794420155085), FRAC_CONST(0.33611944179665709), FRAC_CONST(0.33766003949886464), FRAC_CONST(0.33919973318352969), FRAC_CONST(0.34073851872842903), FRAC_CONST(0.34227639201377064), FRAC_CONST(0.34381334892220483), FRAC_CONST(0.34534938533883547), FRAC_CONST(0.34688449715123082), FRAC_CONST(0.34841868024943456), FRAC_CONST(0.34995193052597684), FRAC_CONST(0.35148424387588523), FRAC_CONST(0.3530156161966958), FRAC_CONST(0.35454604338846402), FRAC_CONST(0.35607552135377557), FRAC_CONST(0.35760404599775775), FRAC_CONST(0.35913161322809023), FRAC_CONST(0.36065821895501554), FRAC_CONST(0.36218385909135092), FRAC_CONST(0.36370852955249849), FRAC_CONST(0.36523222625645668), FRAC_CONST(0.36675494512383078), FRAC_CONST(0.36827668207784414), FRAC_CONST(0.36979743304434909), FRAC_CONST(0.37131719395183754), FRAC_CONST(0.37283596073145214), FRAC_CONST(0.37435372931699717), FRAC_CONST(0.37587049564494951), FRAC_CONST(0.37738625565446909), FRAC_CONST(0.37890100528741022), FRAC_CONST(0.38041474048833229), FRAC_CONST(0.38192745720451066), FRAC_CONST(0.38343915138594736), FRAC_CONST(0.38494981898538222), FRAC_CONST(0.38645945595830333), FRAC_CONST(0.38796805826295838), FRAC_CONST(0.38947562186036483), FRAC_CONST(0.39098214271432141), FRAC_CONST(0.39248761679141814), FRAC_CONST(0.3939920400610481), FRAC_CONST(0.39549540849541737), FRAC_CONST(0.39699771806955625), FRAC_CONST(0.39849896476132979), FRAC_CONST(0.39999914455144892), FRAC_CONST(0.40149825342348083), FRAC_CONST(0.4029962873638599), FRAC_CONST(0.40449324236189854), FRAC_CONST(0.40598911440979762), FRAC_CONST(0.40748389950265762), FRAC_CONST(0.40897759363848879), FRAC_CONST(0.41047019281822261), FRAC_CONST(0.41196169304572178), FRAC_CONST(0.4134520903277914), FRAC_CONST(0.41494138067418929), FRAC_CONST(0.41642956009763715), FRAC_CONST(0.41791662461383078), FRAC_CONST(0.41940257024145089), FRAC_CONST(0.42088739300217382), FRAC_CONST(0.42237108892068231), FRAC_CONST(0.42385365402467584), FRAC_CONST(0.42533508434488143), FRAC_CONST(0.42681537591506419), FRAC_CONST(0.42829452477203828), FRAC_CONST(0.42977252695567697), FRAC_CONST(0.43124937850892364), FRAC_CONST(0.4327250754778022), FRAC_CONST(0.43419961391142781), FRAC_CONST(0.43567298986201736), FRAC_CONST(0.43714519938489987), FRAC_CONST(0.43861623853852766), FRAC_CONST(0.44008610338448595), FRAC_CONST(0.44155478998750436), FRAC_CONST(0.44302229441546676), FRAC_CONST(0.4444886127394222), FRAC_CONST(0.44595374103359531), FRAC_CONST(0.44741767537539667), FRAC_CONST(0.44888041184543348), FRAC_CONST(0.45034194652752002), FRAC_CONST(0.45180227550868812), FRAC_CONST(0.45326139487919759), FRAC_CONST(0.45471930073254679), FRAC_CONST(0.45617598916548296), FRAC_CONST(0.45763145627801283), FRAC_CONST(0.45908569817341294), FRAC_CONST(0.46053871095824001), FRAC_CONST(0.46199049074234161), FRAC_CONST(0.46344103363886635), FRAC_CONST(0.46489033576427435), FRAC_CONST(0.46633839323834758), FRAC_CONST(0.46778520218420055), FRAC_CONST(0.46923075872829029), FRAC_CONST(0.47067505900042683), FRAC_CONST(0.47211809913378361), FRAC_CONST(0.47355987526490806), FRAC_CONST(0.47500038353373153), FRAC_CONST(0.47643962008357982), FRAC_CONST(0.47787758106118372), FRAC_CONST(0.47931426261668875), FRAC_CONST(0.48074966090366611), FRAC_CONST(0.48218377207912272), FRAC_CONST(0.48361659230351117), FRAC_CONST(0.48504811774074069), FRAC_CONST(0.48647834455818684), FRAC_CONST(0.48790726892670194), FRAC_CONST(0.48933488702062544), FRAC_CONST(0.49076119501779414), FRAC_CONST(0.49218618909955225), FRAC_CONST(0.4936098654507618), FRAC_CONST(0.49503222025981269), FRAC_CONST(0.49645324971863303), FRAC_CONST(0.49787295002269943), FRAC_CONST(0.49929131737104687), FRAC_CONST(0.50070834796627917), FRAC_CONST(0.50212403801457872), FRAC_CONST(0.50353838372571758), FRAC_CONST(0.50495138131306638), FRAC_CONST(0.50636302699360547), FRAC_CONST(0.50777331698793449), FRAC_CONST(0.50918224752028263), FRAC_CONST(0.51058981481851906), FRAC_CONST(0.51199601511416237), FRAC_CONST(0.51340084464239111), FRAC_CONST(0.51480429964205421), FRAC_CONST(0.51620637635567967), FRAC_CONST(0.51760707102948678), FRAC_CONST(0.51900637991339404), FRAC_CONST(0.5204042992610306), FRAC_CONST(0.52180082532974559), FRAC_CONST(0.5231959543806185), FRAC_CONST(0.52458968267846895), FRAC_CONST(0.52598200649186677), FRAC_CONST(0.52737292209314235), FRAC_CONST(0.52876242575839572), FRAC_CONST(0.53015051376750777), FRAC_CONST(0.53153718240414882), FRAC_CONST(0.53292242795578992), FRAC_CONST(0.53430624671371152), FRAC_CONST(0.53568863497301467), FRAC_CONST(0.5370695890326298), FRAC_CONST(0.5384491051953274), FRAC_CONST(0.53982717976772743), FRAC_CONST(0.54120380906030963), FRAC_CONST(0.54257898938742311), FRAC_CONST(0.54395271706729609), FRAC_CONST(0.54532498842204646), FRAC_CONST(0.54669579977769045), FRAC_CONST(0.54806514746415402), FRAC_CONST(0.54943302781528081), FRAC_CONST(0.55079943716884383), FRAC_CONST(0.55216437186655387), FRAC_CONST(0.55352782825406999), FRAC_CONST(0.55488980268100907), FRAC_CONST(0.55625029150095584), FRAC_CONST(0.55760929107147217), FRAC_CONST(0.55896679775410718), FRAC_CONST(0.56032280791440714), FRAC_CONST(0.56167731792192455), FRAC_CONST(0.56303032415022869), FRAC_CONST(0.56438182297691453), FRAC_CONST(0.56573181078361312), FRAC_CONST(0.56708028395600085), FRAC_CONST(0.56842723888380908), FRAC_CONST(0.56977267196083425), FRAC_CONST(0.57111657958494688), FRAC_CONST(0.5724589581581021), FRAC_CONST(0.57379980408634845), FRAC_CONST(0.57513911377983773), FRAC_CONST(0.57647688365283478), FRAC_CONST(0.57781311012372738), FRAC_CONST(0.57914778961503466), FRAC_CONST(0.58048091855341843), FRAC_CONST(0.5818124933696911), FRAC_CONST(0.58314251049882604), FRAC_CONST(0.58447096637996743), FRAC_CONST(0.58579785745643886), FRAC_CONST(0.5871231801757536), FRAC_CONST(0.58844693098962408), FRAC_CONST(0.58976910635397084), FRAC_CONST(0.59108970272893235), FRAC_CONST(0.59240871657887517), FRAC_CONST(0.59372614437240179), FRAC_CONST(0.59504198258236196), FRAC_CONST(0.5963562276858605), FRAC_CONST(0.59766887616426767), FRAC_CONST(0.5989799245032289), FRAC_CONST(0.60028936919267273), FRAC_CONST(0.60159720672682204), FRAC_CONST(0.60290343360420195), FRAC_CONST(0.60420804632765002), FRAC_CONST(0.60551104140432543), FRAC_CONST(0.60681241534571839), FRAC_CONST(0.60811216466765883), FRAC_CONST(0.60941028589032709), FRAC_CONST(0.61070677553826169), FRAC_CONST(0.61200163014036979), FRAC_CONST(0.61329484622993602), FRAC_CONST(0.6145864203446314), FRAC_CONST(0.61587634902652377), FRAC_CONST(0.61716462882208556), FRAC_CONST(0.61845125628220421), FRAC_CONST(0.61973622796219074), FRAC_CONST(0.6210195404217892), FRAC_CONST(0.62230119022518593), FRAC_CONST(0.62358117394101897), FRAC_CONST(0.62485948814238634), FRAC_CONST(0.62613612940685637), FRAC_CONST(0.62741109431647646), FRAC_CONST(0.62868437945778133), FRAC_CONST(0.62995598142180387), FRAC_CONST(0.6312258968040827), FRAC_CONST(0.63249412220467238), FRAC_CONST(0.63376065422815175), FRAC_CONST(0.63502548948363347), FRAC_CONST(0.63628862458477287), FRAC_CONST(0.63755005614977711), FRAC_CONST(0.63880978080141437), FRAC_CONST(0.6400677951670225), FRAC_CONST(0.6413240958785188), FRAC_CONST(0.64257867957240766), FRAC_CONST(0.6438315428897915), FRAC_CONST(0.64508268247637779), FRAC_CONST(0.64633209498248945), FRAC_CONST(0.64757977706307335), FRAC_CONST(0.64882572537770888), FRAC_CONST(0.65006993659061751), FRAC_CONST(0.65131240737067142), FRAC_CONST(0.65255313439140239), FRAC_CONST(0.65379211433101081), FRAC_CONST(0.65502934387237444), FRAC_CONST(0.6562648197030575), FRAC_CONST(0.65749853851531959), FRAC_CONST(0.65873049700612374), FRAC_CONST(0.65996069187714679), FRAC_CONST(0.66118911983478657), FRAC_CONST(0.66241577759017178), FRAC_CONST(0.66364066185917048), FRAC_CONST(0.66486376936239888), FRAC_CONST(0.66608509682523009), FRAC_CONST(0.66730464097780284), FRAC_CONST(0.66852239855503071), FRAC_CONST(0.66973836629660977), FRAC_CONST(0.67095254094702894), FRAC_CONST(0.67216491925557675), FRAC_CONST(0.67337549797635199), FRAC_CONST(0.67458427386827102), FRAC_CONST(0.67579124369507693), FRAC_CONST(0.67699640422534846), FRAC_CONST(0.67819975223250772), FRAC_CONST(0.6794012844948305), FRAC_CONST(0.68060099779545302), FRAC_CONST(0.68179888892238183), FRAC_CONST(0.6829949546685018), FRAC_CONST(0.68418919183158522), FRAC_CONST(0.68538159721429948), FRAC_CONST(0.6865721676242168), FRAC_CONST(0.68776089987382172), FRAC_CONST(0.68894779078052026), FRAC_CONST(0.69013283716664853), FRAC_CONST(0.69131603585948032), FRAC_CONST(0.69249738369123692), FRAC_CONST(0.69367687749909468), FRAC_CONST(0.69485451412519361), FRAC_CONST(0.69603029041664599), FRAC_CONST(0.6972042032255451), FRAC_CONST(0.6983762494089728), FRAC_CONST(0.69954642582900894), FRAC_CONST(0.70071472935273893), FRAC_CONST(0.70188115685226271), FRAC_CONST(0.703045705204703), FRAC_CONST(0.70420837129221303), FRAC_CONST(0.70536915200198613), FRAC_CONST(0.70652804422626281), FRAC_CONST(0.70768504486233985), FRAC_CONST(0.70884015081257845), FRAC_CONST(0.70999335898441229), FRAC_CONST(0.711144666290356), FRAC_CONST(0.71229406964801356), FRAC_CONST(0.71344156598008623), FRAC_CONST(0.71458715221438096), FRAC_CONST(0.71573082528381871), FRAC_CONST(0.71687258212644234), FRAC_CONST(0.7180124196854254), FRAC_CONST(0.71915033490907943), FRAC_CONST(0.72028632475086318), FRAC_CONST(0.72142038616938997), FRAC_CONST(0.72255251612843596), FRAC_CONST(0.72368271159694852), FRAC_CONST(0.72481096954905444), FRAC_CONST(0.72593728696406756), FRAC_CONST(0.72706166082649704), FRAC_CONST(0.72818408812605595), FRAC_CONST(0.72930456585766834), FRAC_CONST(0.73042309102147851), FRAC_CONST(0.73153966062285747), FRAC_CONST(0.73265427167241282), FRAC_CONST(0.73376692118599507), FRAC_CONST(0.73487760618470677), FRAC_CONST(0.73598632369490979), FRAC_CONST(0.73709307074823405), FRAC_CONST(0.73819784438158409), FRAC_CONST(0.73930064163714881), FRAC_CONST(0.74040145956240788), FRAC_CONST(0.74150029521014049), FRAC_CONST(0.74259714563843304), FRAC_CONST(0.74369200791068657), FRAC_CONST(0.74478487909562552), FRAC_CONST(0.74587575626730485), FRAC_CONST(0.74696463650511791), FRAC_CONST(0.74805151689380456), FRAC_CONST(0.74913639452345926), FRAC_CONST(0.75021926648953785), FRAC_CONST(0.75130012989286621), FRAC_CONST(0.7523789818396478), FRAC_CONST(0.75345581944147111), FRAC_CONST(0.75453063981531809), FRAC_CONST(0.75560344008357094), FRAC_CONST(0.75667421737402052), FRAC_CONST(0.7577429688198738), FRAC_CONST(0.75880969155976163), FRAC_CONST(0.75987438273774599), FRAC_CONST(0.76093703950332836), FRAC_CONST(0.76199765901145666), FRAC_CONST(0.76305623842253345), FRAC_CONST(0.76411277490242291), FRAC_CONST(0.76516726562245885), FRAC_CONST(0.76621970775945258), FRAC_CONST(0.76727009849569949), FRAC_CONST(0.76831843501898767), FRAC_CONST(0.76936471452260458), FRAC_CONST(0.77040893420534517), FRAC_CONST(0.77145109127151923), FRAC_CONST(0.77249118293095853), FRAC_CONST(0.77352920639902467), FRAC_CONST(0.77456515889661659), FRAC_CONST(0.77559903765017746), FRAC_CONST(0.7766308398917029), FRAC_CONST(0.77766056285874774), FRAC_CONST(0.77868820379443371), FRAC_CONST(0.77971375994745684), FRAC_CONST(0.78073722857209438), FRAC_CONST(0.7817586069282132), FRAC_CONST(0.78277789228127592), FRAC_CONST(0.78379508190234881), FRAC_CONST(0.78481017306810918), FRAC_CONST(0.78582316306085265), FRAC_CONST(0.78683404916849986), FRAC_CONST(0.78784282868460476), FRAC_CONST(0.78884949890836087), FRAC_CONST(0.78985405714460888), FRAC_CONST(0.7908565007038445), FRAC_CONST(0.79185682690222425), FRAC_CONST(0.79285503306157412), FRAC_CONST(0.79385111650939566), FRAC_CONST(0.79484507457887377), FRAC_CONST(0.79583690460888357), FRAC_CONST(0.79682660394399751), FRAC_CONST(0.79781416993449272), FRAC_CONST(0.79879959993635785), FRAC_CONST(0.7997828913113002), FRAC_CONST(0.80076404142675273), FRAC_CONST(0.80174304765588156), FRAC_CONST(0.80271990737759213), FRAC_CONST(0.80369461797653707), FRAC_CONST(0.80466717684312306), FRAC_CONST(0.80563758137351682), FRAC_CONST(0.80660582896965372), FRAC_CONST(0.80757191703924336), FRAC_CONST(0.80853584299577752), FRAC_CONST(0.80949760425853612), FRAC_CONST(0.81045719825259477), FRAC_CONST(0.81141462240883167), FRAC_CONST(0.81236987416393436), FRAC_CONST(0.81332295096040608), FRAC_CONST(0.81427385024657373), FRAC_CONST(0.81522256947659355), FRAC_CONST(0.81616910611045879), FRAC_CONST(0.817113457614006), FRAC_CONST(0.81805562145892186), FRAC_CONST(0.81899559512275044), FRAC_CONST(0.81993337608889916), FRAC_CONST(0.82086896184664637), FRAC_CONST(0.8218023498911472), FRAC_CONST(0.82273353772344116), FRAC_CONST(0.82366252285045805), FRAC_CONST(0.82458930278502529), FRAC_CONST(0.82551387504587381), FRAC_CONST(0.82643623715764558), FRAC_CONST(0.82735638665089983), FRAC_CONST(0.82827432106211907), FRAC_CONST(0.82919003793371693), FRAC_CONST(0.83010353481404364), FRAC_CONST(0.83101480925739324), FRAC_CONST(0.83192385882400965), FRAC_CONST(0.83283068108009373), FRAC_CONST(0.8337352735978093), FRAC_CONST(0.83463763395529011), FRAC_CONST(0.83553775973664579), FRAC_CONST(0.83643564853196872), FRAC_CONST(0.83733129793734051), FRAC_CONST(0.83822470555483797), FRAC_CONST(0.83911586899254031), FRAC_CONST(0.84000478586453453), FRAC_CONST(0.84089145379092289), FRAC_CONST(0.84177587039782842), FRAC_CONST(0.84265803331740163), FRAC_CONST(0.84353794018782702), FRAC_CONST(0.844415588653329), FRAC_CONST(0.8452909763641786), FRAC_CONST(0.84616410097669936), FRAC_CONST(0.84703496015327406), FRAC_CONST(0.84790355156235053), FRAC_CONST(0.84876987287844818), FRAC_CONST(0.8496339217821639), FRAC_CONST(0.85049569596017938), FRAC_CONST(0.85135519310526508), FRAC_CONST(0.85221241091628896), FRAC_CONST(0.85306734709822085), FRAC_CONST(0.85391999936213903), FRAC_CONST(0.85477036542523732), FRAC_CONST(0.85561844301082923), FRAC_CONST(0.85646422984835635), FRAC_CONST(0.85730772367339259), FRAC_CONST(0.85814892222765116), FRAC_CONST(0.85898782325899026), FRAC_CONST(0.85982442452141961), FRAC_CONST(0.86065872377510555), FRAC_CONST(0.86149071878637817), FRAC_CONST(0.8623204073277364), FRAC_CONST(0.86314778717785412), FRAC_CONST(0.8639728561215867), FRAC_CONST(0.86479561194997623), FRAC_CONST(0.86561605246025763), FRAC_CONST(0.86643417545586487), FRAC_CONST(0.8672499787464365), FRAC_CONST(0.86806346014782154), FRAC_CONST(0.8688746174820855), FRAC_CONST(0.86968344857751589), FRAC_CONST(0.87048995126862883), FRAC_CONST(0.87129412339617363), FRAC_CONST(0.87209596280713941), FRAC_CONST(0.8728954673547612), FRAC_CONST(0.87369263489852422), FRAC_CONST(0.87448746330417149), FRAC_CONST(0.87527995044370765), FRAC_CONST(0.8760700941954066), FRAC_CONST(0.87685789244381551), FRAC_CONST(0.87764334307976144), FRAC_CONST(0.87842644400035663), FRAC_CONST(0.8792071931090043), FRAC_CONST(0.87998558831540408), FRAC_CONST(0.88076162753555787), FRAC_CONST(0.88153530869177488), FRAC_CONST(0.88230662971267804), FRAC_CONST(0.88307558853320878), FRAC_CONST(0.88384218309463292), FRAC_CONST(0.8846064113445461), FRAC_CONST(0.88536827123687933), FRAC_CONST(0.88612776073190425), FRAC_CONST(0.88688487779623937), FRAC_CONST(0.88763962040285393), FRAC_CONST(0.8883919865310751), FRAC_CONST(0.88914197416659235), FRAC_CONST(0.88988958130146301), FRAC_CONST(0.8906348059341177), FRAC_CONST(0.89137764606936609), FRAC_CONST(0.89211809971840139), FRAC_CONST(0.89285616489880615), FRAC_CONST(0.89359183963455813), FRAC_CONST(0.89432512195603453), FRAC_CONST(0.89505600990001799), FRAC_CONST(0.89578450150970124), FRAC_CONST(0.8965105948346932), FRAC_CONST(0.89723428793102367), FRAC_CONST(0.89795557886114807), FRAC_CONST(0.89867446569395382), FRAC_CONST(0.89939094650476448), FRAC_CONST(0.90010501937534515), FRAC_CONST(0.900816682393908), FRAC_CONST(0.90152593365511691), FRAC_CONST(0.90223277126009283), FRAC_CONST(0.90293719331641886), FRAC_CONST(0.90363919793814496), FRAC_CONST(0.90433878324579353), FRAC_CONST(0.90503594736636439), FRAC_CONST(0.90573068843333915), FRAC_CONST(0.90642300458668679), FRAC_CONST(0.90711289397286898), FRAC_CONST(0.90780035474484411), FRAC_CONST(0.90848538506207266), FRAC_CONST(0.90916798309052227), FRAC_CONST(0.90984814700267291), FRAC_CONST(0.9105258749775208), FRAC_CONST(0.91120116520058425), FRAC_CONST(0.91187401586390815), FRAC_CONST(0.91254442516606893), FRAC_CONST(0.9132123913121788), FRAC_CONST(0.91387791251389161), FRAC_CONST(0.91454098698940678), FRAC_CONST(0.91520161296347435), FRAC_CONST(0.91585978866739981), FRAC_CONST(0.91651551233904871), FRAC_CONST(0.91716878222285148), FRAC_CONST(0.91781959656980805), FRAC_CONST(0.91846795363749245), FRAC_CONST(0.91911385169005766), FRAC_CONST(0.9197572889982405), FRAC_CONST(0.9203982638393654), FRAC_CONST(0.92103677449734989), FRAC_CONST(0.92167281926270861), FRAC_CONST(0.92230639643255874), FRAC_CONST(0.92293750431062316), FRAC_CONST(0.92356614120723612), FRAC_CONST(0.92419230543934783), FRAC_CONST(0.92481599533052783), FRAC_CONST(0.92543720921097061), FRAC_CONST(0.92605594541749991), FRAC_CONST(0.92667220229357261), FRAC_CONST(0.92728597818928349), FRAC_CONST(0.9278972714613698), FRAC_CONST(0.92850608047321548), FRAC_CONST(0.9291124035948557), FRAC_CONST(0.92971623920298097), FRAC_CONST(0.93031758568094147), FRAC_CONST(0.93091644141875196), FRAC_CONST(0.93151280481309506), FRAC_CONST(0.93210667426732674), FRAC_CONST(0.93269804819147983), FRAC_CONST(0.93328692500226818), FRAC_CONST(0.93387330312309147), FRAC_CONST(0.93445718098403896), FRAC_CONST(0.93503855702189376), FRAC_CONST(0.9356174296801375), FRAC_CONST(0.93619379740895381), FRAC_CONST(0.93676765866523259), FRAC_CONST(0.93733901191257496), FRAC_CONST(0.93790785562129597), FRAC_CONST(0.93847418826842988), FRAC_CONST(0.93903800833773399), FRAC_CONST(0.93959931431969212), FRAC_CONST(0.94015810471151917), FRAC_CONST(0.94071437801716529), FRAC_CONST(0.94126813274731924), FRAC_CONST(0.94181936741941319), FRAC_CONST(0.94236808055762578), FRAC_CONST(0.94291427069288691), FRAC_CONST(0.94345793636288133), FRAC_CONST(0.94399907611205225), FRAC_CONST(0.9445376884916058), FRAC_CONST(0.94507377205951448), FRAC_CONST(0.94560732538052128), FRAC_CONST(0.94613834702614352), FRAC_CONST(0.94666683557467624), FRAC_CONST(0.94719278961119657), FRAC_CONST(0.94771620772756759), FRAC_CONST(0.94823708852244104), FRAC_CONST(0.94875543060126255), FRAC_CONST(0.94927123257627433), FRAC_CONST(0.94978449306651924), FRAC_CONST(0.95029521069784428), FRAC_CONST(0.9508033841029051), FRAC_CONST(0.95130901192116835), FRAC_CONST(0.9518120927989161), FRAC_CONST(0.95231262538924943), FRAC_CONST(0.95281060835209208), FRAC_CONST(0.95330604035419386), FRAC_CONST(0.95379892006913403), FRAC_CONST(0.95428924617732525), FRAC_CONST(0.95477701736601728), FRAC_CONST(0.95526223232929941), FRAC_CONST(0.95574488976810545), FRAC_CONST(0.95622498839021619), FRAC_CONST(0.95670252691026292), FRAC_CONST(0.95717750404973156), FRAC_CONST(0.95764991853696524), FRAC_CONST(0.95811976910716812), FRAC_CONST(0.95858705450240911), FRAC_CONST(0.95905177347162429), FRAC_CONST(0.95951392477062125), FRAC_CONST(0.95997350716208196), FRAC_CONST(0.96043051941556579), FRAC_CONST(0.96088496030751369), FRAC_CONST(0.96133682862125036), FRAC_CONST(0.96178612314698864), FRAC_CONST(0.96223284268183173), FRAC_CONST(0.9626769860297768), FRAC_CONST(0.96311855200171881), FRAC_CONST(0.96355753941545252), FRAC_CONST(0.96399394709567654), FRAC_CONST(0.96442777387399625), FRAC_CONST(0.96485901858892686), FRAC_CONST(0.96528768008589627), FRAC_CONST(0.96571375721724895), FRAC_CONST(0.96613724884224783), FRAC_CONST(0.96655815382707866), FRAC_CONST(0.96697647104485207), FRAC_CONST(0.96739219937560694), FRAC_CONST(0.96780533770631338), FRAC_CONST(0.96821588493087585), FRAC_CONST(0.9686238399501359), FRAC_CONST(0.96902920167187501), FRAC_CONST(0.96943196901081796), FRAC_CONST(0.96983214088863534), FRAC_CONST(0.9702297162339466), FRAC_CONST(0.97062469398232287), FRAC_CONST(0.97101707307629004), FRAC_CONST(0.97140685246533098), FRAC_CONST(0.97179403110588902), FRAC_CONST(0.97217860796137046), FRAC_CONST(0.97256058200214734), FRAC_CONST(0.97293995220556007), FRAC_CONST(0.97331671755592064), FRAC_CONST(0.97369087704451474), FRAC_CONST(0.97406242966960455), FRAC_CONST(0.97443137443643235), FRAC_CONST(0.97479771035722163), FRAC_CONST(0.97516143645118103), FRAC_CONST(0.97552255174450631), FRAC_CONST(0.97588105527038305), FRAC_CONST(0.97623694606898959), FRAC_CONST(0.97659022318749911), FRAC_CONST(0.97694088568008242), FRAC_CONST(0.97728893260791039), FRAC_CONST(0.97763436303915685), FRAC_CONST(0.97797717604900047), FRAC_CONST(0.97831737071962765), FRAC_CONST(0.97865494614023485), FRAC_CONST(0.97898990140703124), FRAC_CONST(0.97932223562324061), FRAC_CONST(0.97965194789910426), FRAC_CONST(0.9799790373518833), FRAC_CONST(0.98030350310586067), FRAC_CONST(0.98062534429234405), FRAC_CONST(0.98094456004966768), FRAC_CONST(0.98126114952319499), FRAC_CONST(0.98157511186532054), FRAC_CONST(0.98188644623547261), FRAC_CONST(0.98219515180011563), FRAC_CONST(0.98250122773275184), FRAC_CONST(0.98280467321392362), FRAC_CONST(0.98310548743121629), FRAC_CONST(0.98340366957925973), FRAC_CONST(0.98369921885973044), FRAC_CONST(0.98399213448135414), FRAC_CONST(0.98428241565990748), FRAC_CONST(0.98457006161822058), FRAC_CONST(0.98485507158617835), FRAC_CONST(0.98513744480072363), FRAC_CONST(0.98541718050585803), FRAC_CONST(0.98569427795264519), FRAC_CONST(0.98596873639921168), FRAC_CONST(0.98624055511074971), FRAC_CONST(0.98650973335951875), FRAC_CONST(0.98677627042484772), FRAC_CONST(0.98704016559313645), FRAC_CONST(0.98730141815785832), FRAC_CONST(0.98756002741956173), FRAC_CONST(0.9878159926858715), FRAC_CONST(0.98806931327149194), FRAC_CONST(0.98831998849820735), FRAC_CONST(0.98856801769488489), FRAC_CONST(0.98881340019747566), FRAC_CONST(0.98905613534901682), FRAC_CONST(0.98929622249963345), FRAC_CONST(0.98953366100653983), FRAC_CONST(0.98976845023404181), FRAC_CONST(0.99000058955353776), FRAC_CONST(0.99023007834352106), FRAC_CONST(0.99045691598958097), FRAC_CONST(0.99068110188440506), FRAC_CONST(0.99090263542778001), FRAC_CONST(0.99112151602659404), FRAC_CONST(0.99133774309483769), FRAC_CONST(0.99155131605360625), FRAC_CONST(0.99176223433110056), FRAC_CONST(0.99197049736262888), FRAC_CONST(0.99217610459060845), FRAC_CONST(0.99237905546456673), FRAC_CONST(0.99257934944114334), FRAC_CONST(0.99277698598409092), FRAC_CONST(0.99297196456427694), FRAC_CONST(0.99316428465968509), FRAC_CONST(0.99335394575541669), FRAC_CONST(0.99354094734369169), FRAC_CONST(0.99372528892385081), FRAC_CONST(0.99390697000235606), FRAC_CONST(0.99408599009279242), FRAC_CONST(0.99426234871586938), FRAC_CONST(0.99443604539942176), FRAC_CONST(0.99460707967841133), FRAC_CONST(0.99477545109492771), FRAC_CONST(0.99494115919819004), FRAC_CONST(0.99510420354454787), FRAC_CONST(0.99526458369748239), FRAC_CONST(0.99542229922760772), FRAC_CONST(0.99557734971267187), FRAC_CONST(0.9957297347375581), FRAC_CONST(0.99587945389428578), FRAC_CONST(0.99602650678201154), FRAC_CONST(0.99617089300703077), FRAC_CONST(0.996312612182778), FRAC_CONST(0.99645166392982831), FRAC_CONST(0.99658804787589839), FRAC_CONST(0.99672176365584741), FRAC_CONST(0.99685281091167788), FRAC_CONST(0.99698118929253687), FRAC_CONST(0.99710689845471678), FRAC_CONST(0.99722993806165661), FRAC_CONST(0.99735030778394196), FRAC_CONST(0.99746800729930707), FRAC_CONST(0.99758303629263489), FRAC_CONST(0.99769539445595812), FRAC_CONST(0.99780508148846014), FRAC_CONST(0.99791209709647588), FRAC_CONST(0.99801644099349218), FRAC_CONST(0.99811811290014918), FRAC_CONST(0.9982171125442405), FRAC_CONST(0.9983134396607144), FRAC_CONST(0.99840709399167404), FRAC_CONST(0.99849807528637868), FRAC_CONST(0.99858638330124405), FRAC_CONST(0.99867201779984294), FRAC_CONST(0.99875497855290607), FRAC_CONST(0.99883526533832245), FRAC_CONST(0.99891287794114036), FRAC_CONST(0.99898781615356746), FRAC_CONST(0.99906007977497147), FRAC_CONST(0.99912966861188113), FRAC_CONST(0.99919658247798593), FRAC_CONST(0.99926082119413751), FRAC_CONST(0.99932238458834954), FRAC_CONST(0.999381272495798), FRAC_CONST(0.99943748475882255), FRAC_CONST(0.9994910212269259), FRAC_CONST(0.99954188175677483), FRAC_CONST(0.99959006621220048), FRAC_CONST(0.99963557446419837), FRAC_CONST(0.99967840639092931), FRAC_CONST(0.99971856187771946), FRAC_CONST(0.99975604081706027), FRAC_CONST(0.99979084310860955), FRAC_CONST(0.99982296865919107), FRAC_CONST(0.99985241738279484), FRAC_CONST(0.99987918920057806), FRAC_CONST(0.99990328404086426), FRAC_CONST(0.9999247018391445), FRAC_CONST(0.99994344253807688), FRAC_CONST(0.99995950608748674), FRAC_CONST(0.99997289244436727), FRAC_CONST(0.99998360157287902), FRAC_CONST(0.9999916334443506), FRAC_CONST(0.99999698803727821), FRAC_CONST(0.99999966533732598) }; #endif ALIGN static const real_t sine_short_128[] = { FRAC_CONST(0.0061358846491544753), FRAC_CONST(0.01840672990580482), FRAC_CONST(0.030674803176636626), FRAC_CONST(0.04293825693494082), FRAC_CONST(0.055195244349689934), FRAC_CONST(0.067443919563664051), FRAC_CONST(0.079682437971430126), FRAC_CONST(0.091908956497132724), FRAC_CONST(0.10412163387205459), FRAC_CONST(0.11631863091190475), FRAC_CONST(0.12849811079379317), FRAC_CONST(0.14065823933284921), FRAC_CONST(0.15279718525844344), FRAC_CONST(0.16491312048996989), FRAC_CONST(0.17700422041214875), FRAC_CONST(0.18906866414980619), FRAC_CONST(0.2011046348420919), FRAC_CONST(0.21311031991609136), FRAC_CONST(0.22508391135979283), FRAC_CONST(0.2370236059943672), FRAC_CONST(0.24892760574572015), FRAC_CONST(0.26079411791527551), FRAC_CONST(0.27262135544994898), FRAC_CONST(0.28440753721127188), FRAC_CONST(0.29615088824362379), FRAC_CONST(0.30784964004153487), FRAC_CONST(0.31950203081601569), FRAC_CONST(0.33110630575987643), FRAC_CONST(0.34266071731199438), FRAC_CONST(0.35416352542049034), FRAC_CONST(0.36561299780477385), FRAC_CONST(0.37700741021641826), FRAC_CONST(0.38834504669882625), FRAC_CONST(0.39962419984564679), FRAC_CONST(0.41084317105790391), FRAC_CONST(0.42200027079979968), FRAC_CONST(0.43309381885315196), FRAC_CONST(0.4441221445704292), FRAC_CONST(0.45508358712634384), FRAC_CONST(0.46597649576796618), FRAC_CONST(0.47679923006332209), FRAC_CONST(0.487550160148436), FRAC_CONST(0.49822766697278187), FRAC_CONST(0.50883014254310699), FRAC_CONST(0.51935599016558964), FRAC_CONST(0.52980362468629461), FRAC_CONST(0.54017147272989285), FRAC_CONST(0.55045797293660481), FRAC_CONST(0.56066157619733603), FRAC_CONST(0.57078074588696726), FRAC_CONST(0.58081395809576453), FRAC_CONST(0.59075970185887416), FRAC_CONST(0.60061647938386897), FRAC_CONST(0.61038280627630948), FRAC_CONST(0.6200572117632891), FRAC_CONST(0.62963823891492698), FRAC_CONST(0.63912444486377573), FRAC_CONST(0.64851440102211244), FRAC_CONST(0.65780669329707864), FRAC_CONST(0.66699992230363747), FRAC_CONST(0.67609270357531592), FRAC_CONST(0.68508366777270036), FRAC_CONST(0.693971460889654), FRAC_CONST(0.7027547444572253), FRAC_CONST(0.71143219574521643), FRAC_CONST(0.72000250796138165), FRAC_CONST(0.7284643904482252), FRAC_CONST(0.73681656887736979), FRAC_CONST(0.74505778544146595), FRAC_CONST(0.75318679904361241), FRAC_CONST(0.76120238548426178), FRAC_CONST(0.76910333764557959), FRAC_CONST(0.77688846567323244), FRAC_CONST(0.78455659715557524), FRAC_CONST(0.79210657730021239), FRAC_CONST(0.79953726910790501), FRAC_CONST(0.80684755354379922), FRAC_CONST(0.8140363297059483), FRAC_CONST(0.82110251499110465), FRAC_CONST(0.8280450452577558), FRAC_CONST(0.83486287498638001), FRAC_CONST(0.84155497743689833), FRAC_CONST(0.84812034480329712), FRAC_CONST(0.85455798836540053), FRAC_CONST(0.86086693863776731), FRAC_CONST(0.86704624551569265), FRAC_CONST(0.87309497841829009), FRAC_CONST(0.87901222642863341), FRAC_CONST(0.88479709843093779), FRAC_CONST(0.89044872324475788), FRAC_CONST(0.89596624975618511), FRAC_CONST(0.90134884704602203), FRAC_CONST(0.90659570451491533), FRAC_CONST(0.91170603200542988), FRAC_CONST(0.9166790599210427), FRAC_CONST(0.9215140393420419), FRAC_CONST(0.92621024213831127), FRAC_CONST(0.93076696107898371), FRAC_CONST(0.9351835099389475), FRAC_CONST(0.93945922360218992), FRAC_CONST(0.94359345816196039), FRAC_CONST(0.94758559101774109), FRAC_CONST(0.95143502096900834), FRAC_CONST(0.95514116830577067), FRAC_CONST(0.9587034748958716), FRAC_CONST(0.96212140426904158), FRAC_CONST(0.9653944416976894), FRAC_CONST(0.96852209427441727), FRAC_CONST(0.97150389098625178), FRAC_CONST(0.97433938278557586), FRAC_CONST(0.97702814265775439), FRAC_CONST(0.97956976568544052), FRAC_CONST(0.98196386910955524), FRAC_CONST(0.98421009238692903), FRAC_CONST(0.98630809724459867), FRAC_CONST(0.98825756773074946), FRAC_CONST(0.99005821026229712), FRAC_CONST(0.99170975366909953), FRAC_CONST(0.9932119492347945), FRAC_CONST(0.99456457073425542), FRAC_CONST(0.99576741446765982), FRAC_CONST(0.99682029929116567), FRAC_CONST(0.99772306664419164), FRAC_CONST(0.99847558057329477), FRAC_CONST(0.99907772775264536), FRAC_CONST(0.99952941750109314), FRAC_CONST(0.9998305817958234), FRAC_CONST(0.99998117528260111) }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const real_t sine_short_120[] = { FRAC_CONST(0.0065449379673518581), FRAC_CONST(0.019633692460628301), FRAC_CONST(0.032719082821776137), FRAC_CONST(0.045798866936520771), FRAC_CONST(0.058870803651189033), FRAC_CONST(0.071932653156719387), FRAC_CONST(0.084982177372441667), FRAC_CONST(0.09801714032956059), FRAC_CONST(0.11103530855427769), FRAC_CONST(0.12403445145048532), FRAC_CONST(0.13701234168196802), FRAC_CONST(0.14996675555404498), FRAC_CONST(0.16289547339458874), FRAC_CONST(0.17579627993435451), FRAC_CONST(0.18866696468655525), FRAC_CONST(0.2015053223256171), FRAC_CONST(0.21430915306505074), FRAC_CONST(0.2270762630343732), FRAC_CONST(0.23980446465501654), FRAC_CONST(0.25249157701515795), FRAC_CONST(0.26513542624340797), FRAC_CONST(0.27773384588129219), FRAC_CONST(0.29028467725446233), FRAC_CONST(0.3027857698425746), FRAC_CONST(0.31523498164776964), FRAC_CONST(0.32763017956169349), FRAC_CONST(0.33996923973099424), FRAC_CONST(0.35225004792123354), FRAC_CONST(0.36447049987914965), FRAC_CONST(0.37662850169321077), FRAC_CONST(0.38872197015239557), FRAC_CONST(0.40074883310314097), FRAC_CONST(0.41270702980439467), FRAC_CONST(0.42459451128071307), FRAC_CONST(0.43640924067334208), FRAC_CONST(0.44814919358922256), FRAC_CONST(0.45981235844785984), FRAC_CONST(0.47139673682599764), FRAC_CONST(0.48290034380003727), FRAC_CONST(0.49432120828614462), FRAC_CONST(0.50565737337798455), FRAC_CONST(0.51690689668202761), FRAC_CONST(0.52806785065036799), FRAC_CONST(0.53913832291100017), FRAC_CONST(0.55011641659549337), FRAC_CONST(0.56100025066400983), FRAC_CONST(0.57178796022761225), FRAC_CONST(0.58247769686780215), FRAC_CONST(0.59306762895323706), FRAC_CONST(0.60355594195357143), FRAC_CONST(0.61394083875036642), FRAC_CONST(0.62422053994501758), FRAC_CONST(0.63439328416364549), FRAC_CONST(0.64445732835889735), FRAC_CONST(0.65441094810861034), FRAC_CONST(0.66425243791128175), FRAC_CONST(0.67398011147829784), FRAC_CONST(0.68359230202287125), FRAC_CONST(0.69308736254563585), FRAC_CONST(0.70246366611685174), FRAC_CONST(0.71171960615517138), FRAC_CONST(0.72085359670291882), FRAC_CONST(0.7298640726978356), FRAC_CONST(0.73874949024124625), FRAC_CONST(0.74750832686259672), FRAC_CONST(0.75613908178032285), FRAC_CONST(0.76464027615900032), FRAC_CONST(0.77301045336273699), FRAC_CONST(0.78124817920475853), FRAC_CONST(0.78935204219315003), FRAC_CONST(0.79732065377270711), FRAC_CONST(0.80515264856285829), FRAC_CONST(0.81284668459161513), FRAC_CONST(0.82040144352551359), FRAC_CONST(0.82781563089550203), FRAC_CONST(0.83508797631874299), FRAC_CONST(0.84221723371628654), FRAC_CONST(0.84920218152657889), FRAC_CONST(0.85604162291477137), FRAC_CONST(0.86273438597779184), FRAC_CONST(0.86927932394514362), FRAC_CONST(0.87567531537539967), FRAC_CONST(0.88192126434835494), FRAC_CONST(0.88801610065280734), FRAC_CONST(0.89395877996993212), FRAC_CONST(0.8997482840522214), FRAC_CONST(0.90538362089795521), FRAC_CONST(0.91086382492117568), FRAC_CONST(0.91618795711713596), FRAC_CONST(0.92135510522319242), FRAC_CONST(0.9263643838751181), FRAC_CONST(0.93121493475880346), FRAC_CONST(0.93590592675732565), FRAC_CONST(0.94043655609335486), FRAC_CONST(0.94480604646687805), FRAC_CONST(0.94901364918821385), FRAC_CONST(0.95305864330629697), FRAC_CONST(0.95694033573220882), FRAC_CONST(0.9606580613579353), FRAC_CONST(0.96421118317032928), FRAC_CONST(0.96759909236025976), FRAC_CONST(0.9708212084269281), FRAC_CONST(0.97387697927733363), FRAC_CONST(0.97676588132087239), FRAC_CONST(0.97948741955905139), FRAC_CONST(0.98204112767030394), FRAC_CONST(0.98442656808989171), FRAC_CONST(0.98664333208487898), FRAC_CONST(0.98869103982416728), FRAC_CONST(0.99056934044357725), FRAC_CONST(0.99227791210596705), FRAC_CONST(0.99381646205637808), FRAC_CONST(0.99518472667219682), FRAC_CONST(0.99638247150832537), FRAC_CONST(0.99740949133735191), FRAC_CONST(0.99826561018471593), FRAC_CONST(0.99895068135886012), FRAC_CONST(0.99946458747636568), FRAC_CONST(0.99980724048206482), FRAC_CONST(0.99997858166412923) }; #endif #ifdef LD_DEC ALIGN static const real_t sine_mid_512[] = { FRAC_CONST(0.0015339801862847655), FRAC_CONST(0.0046019261204485705), FRAC_CONST(0.007669828739531097), FRAC_CONST(0.010737659167264491), FRAC_CONST(0.013805388528060391), FRAC_CONST(0.01687298794728171), FRAC_CONST(0.019940428551514441), FRAC_CONST(0.023007681468839369), FRAC_CONST(0.026074717829103901), FRAC_CONST(0.029141508764193722), FRAC_CONST(0.032208025408304586), FRAC_CONST(0.035274238898213947), FRAC_CONST(0.038340120373552694), FRAC_CONST(0.041405640977076739), FRAC_CONST(0.044470771854938668), FRAC_CONST(0.047535484156959303), FRAC_CONST(0.050599749036899282), FRAC_CONST(0.05366353765273052), FRAC_CONST(0.056726821166907748), FRAC_CONST(0.059789570746639868), FRAC_CONST(0.062851757564161406), FRAC_CONST(0.065913352797003805), FRAC_CONST(0.068974327628266746), FRAC_CONST(0.072034653246889332), FRAC_CONST(0.075094300847921305), FRAC_CONST(0.078153241632794232), FRAC_CONST(0.081211446809592441), FRAC_CONST(0.084268887593324071), FRAC_CONST(0.087325535206192059), FRAC_CONST(0.090381360877864983), FRAC_CONST(0.093436335845747787), FRAC_CONST(0.096490431355252593), FRAC_CONST(0.099543618660069319), FRAC_CONST(0.10259586902243628), FRAC_CONST(0.10564715371341062), FRAC_CONST(0.10869744401313872), FRAC_CONST(0.11174671121112659), FRAC_CONST(0.11479492660651008), FRAC_CONST(0.11784206150832498), FRAC_CONST(0.12088808723577708), FRAC_CONST(0.12393297511851216), FRAC_CONST(0.12697669649688587), FRAC_CONST(0.13001922272223335), FRAC_CONST(0.13306052515713906), FRAC_CONST(0.1361005751757062), FRAC_CONST(0.1391393441638262), FRAC_CONST(0.14217680351944803), FRAC_CONST(0.14521292465284746), FRAC_CONST(0.14824767898689603), FRAC_CONST(0.15128103795733022), FRAC_CONST(0.1543129730130201), FRAC_CONST(0.15734345561623825), FRAC_CONST(0.16037245724292828), FRAC_CONST(0.16339994938297323), FRAC_CONST(0.1664259035404641), FRAC_CONST(0.16945029123396796), FRAC_CONST(0.17247308399679595), FRAC_CONST(0.17549425337727143), FRAC_CONST(0.17851377093899751), FRAC_CONST(0.18153160826112497), FRAC_CONST(0.18454773693861962), FRAC_CONST(0.1875621285825296), FRAC_CONST(0.19057475482025274), FRAC_CONST(0.19358558729580361), FRAC_CONST(0.19659459767008022), FRAC_CONST(0.19960175762113097), FRAC_CONST(0.20260703884442113), FRAC_CONST(0.20561041305309924), FRAC_CONST(0.20861185197826349), FRAC_CONST(0.21161132736922755), FRAC_CONST(0.21460881099378676), FRAC_CONST(0.21760427463848364), FRAC_CONST(0.22059769010887351), FRAC_CONST(0.22358902922978999), FRAC_CONST(0.22657826384561), FRAC_CONST(0.22956536582051887), FRAC_CONST(0.23255030703877524), FRAC_CONST(0.23553305940497549), FRAC_CONST(0.23851359484431842), FRAC_CONST(0.24149188530286933), FRAC_CONST(0.24446790274782415), FRAC_CONST(0.24744161916777327), FRAC_CONST(0.25041300657296522), FRAC_CONST(0.25338203699557016), FRAC_CONST(0.25634868248994291), FRAC_CONST(0.25931291513288623), FRAC_CONST(0.26227470702391359), FRAC_CONST(0.26523403028551179), FRAC_CONST(0.26819085706340318), FRAC_CONST(0.27114515952680801), FRAC_CONST(0.27409690986870638), FRAC_CONST(0.2770460803060999), FRAC_CONST(0.27999264308027322), FRAC_CONST(0.28293657045705539), FRAC_CONST(0.28587783472708062), FRAC_CONST(0.28881640820604948), FRAC_CONST(0.29175226323498926), FRAC_CONST(0.29468537218051433), FRAC_CONST(0.2976157074350862), FRAC_CONST(0.30054324141727345), FRAC_CONST(0.30346794657201132), FRAC_CONST(0.30638979537086092), FRAC_CONST(0.30930876031226873), FRAC_CONST(0.31222481392182488), FRAC_CONST(0.31513792875252244), FRAC_CONST(0.31804807738501495), FRAC_CONST(0.32095523242787521), FRAC_CONST(0.32385936651785285), FRAC_CONST(0.32676045232013173), FRAC_CONST(0.32965846252858749), FRAC_CONST(0.33255336986604422), FRAC_CONST(0.3354451470845316), FRAC_CONST(0.33833376696554113), FRAC_CONST(0.34121920232028236), FRAC_CONST(0.34410142598993881), FRAC_CONST(0.34698041084592368), FRAC_CONST(0.34985612979013492), FRAC_CONST(0.35272855575521073), FRAC_CONST(0.35559766170478385), FRAC_CONST(0.35846342063373654), FRAC_CONST(0.36132580556845428), FRAC_CONST(0.36418478956707989), FRAC_CONST(0.36704034571976718), FRAC_CONST(0.3698924471489341), FRAC_CONST(0.37274106700951576), FRAC_CONST(0.37558617848921722), FRAC_CONST(0.37842775480876556), FRAC_CONST(0.38126576922216238), FRAC_CONST(0.38410019501693504), FRAC_CONST(0.38693100551438858), FRAC_CONST(0.38975817406985641), FRAC_CONST(0.39258167407295147), FRAC_CONST(0.39540147894781635), FRAC_CONST(0.39821756215337356), FRAC_CONST(0.40102989718357562), FRAC_CONST(0.40383845756765407), FRAC_CONST(0.40664321687036903), FRAC_CONST(0.40944414869225759), FRAC_CONST(0.41224122666988289), FRAC_CONST(0.41503442447608163), FRAC_CONST(0.41782371582021227), FRAC_CONST(0.42060907444840251), FRAC_CONST(0.42339047414379605), FRAC_CONST(0.42616788872679962), FRAC_CONST(0.42894129205532949), FRAC_CONST(0.43171065802505726), FRAC_CONST(0.43447596056965565), FRAC_CONST(0.43723717366104409), FRAC_CONST(0.43999427130963326), FRAC_CONST(0.44274722756457002), FRAC_CONST(0.44549601651398174), FRAC_CONST(0.44824061228521989), FRAC_CONST(0.45098098904510386), FRAC_CONST(0.45371712100016387), FRAC_CONST(0.45644898239688392), FRAC_CONST(0.45917654752194409), FRAC_CONST(0.46189979070246273), FRAC_CONST(0.46461868630623782), FRAC_CONST(0.46733320874198842), FRAC_CONST(0.47004333245959562), FRAC_CONST(0.47274903195034279), FRAC_CONST(0.47545028174715587), FRAC_CONST(0.47814705642484301), FRAC_CONST(0.48083933060033396), FRAC_CONST(0.48352707893291874), FRAC_CONST(0.48621027612448642), FRAC_CONST(0.48888889691976317), FRAC_CONST(0.4915629161065499), FRAC_CONST(0.49423230851595967), FRAC_CONST(0.49689704902265447), FRAC_CONST(0.49955711254508184), FRAC_CONST(0.50221247404571079), FRAC_CONST(0.50486310853126759), FRAC_CONST(0.50750899105297087), FRAC_CONST(0.51015009670676681), FRAC_CONST(0.51278640063356296), FRAC_CONST(0.51541787801946293), FRAC_CONST(0.51804450409599934), FRAC_CONST(0.52066625414036716), FRAC_CONST(0.52328310347565643), FRAC_CONST(0.52589502747108463), FRAC_CONST(0.52850200154222848), FRAC_CONST(0.531104001151255), FRAC_CONST(0.53370100180715296), FRAC_CONST(0.53629297906596318), FRAC_CONST(0.53887990853100842), FRAC_CONST(0.54146176585312344), FRAC_CONST(0.54403852673088382), FRAC_CONST(0.54661016691083486), FRAC_CONST(0.54917666218771966), FRAC_CONST(0.55173798840470734), FRAC_CONST(0.55429412145362), FRAC_CONST(0.5568450372751601), FRAC_CONST(0.55939071185913614), FRAC_CONST(0.56193112124468947), FRAC_CONST(0.5644662415205195), FRAC_CONST(0.56699604882510868), FRAC_CONST(0.56952051934694714), FRAC_CONST(0.57203962932475705), FRAC_CONST(0.57455335504771576), FRAC_CONST(0.57706167285567944), FRAC_CONST(0.57956455913940563), FRAC_CONST(0.58206199034077544), FRAC_CONST(0.58455394295301533), FRAC_CONST(0.58704039352091797), FRAC_CONST(0.58952131864106394), FRAC_CONST(0.59199669496204099), FRAC_CONST(0.59446649918466443), FRAC_CONST(0.5969307080621965), FRAC_CONST(0.59938929840056454), FRAC_CONST(0.60184224705858003), FRAC_CONST(0.60428953094815596), FRAC_CONST(0.60673112703452448), FRAC_CONST(0.60916701233645321), FRAC_CONST(0.61159716392646191), FRAC_CONST(0.61402155893103838), FRAC_CONST(0.61644017453085365), FRAC_CONST(0.61885298796097632), FRAC_CONST(0.62125997651108755), FRAC_CONST(0.62366111752569453), FRAC_CONST(0.62605638840434352), FRAC_CONST(0.62844576660183271), FRAC_CONST(0.63082922962842447), FRAC_CONST(0.63320675505005719), FRAC_CONST(0.63557832048855611), FRAC_CONST(0.63794390362184406), FRAC_CONST(0.64030348218415167), FRAC_CONST(0.64265703396622686), FRAC_CONST(0.64500453681554393), FRAC_CONST(0.64734596863651206), FRAC_CONST(0.64968130739068319), FRAC_CONST(0.6520105310969595), FRAC_CONST(0.65433361783180044), FRAC_CONST(0.65665054572942894), FRAC_CONST(0.65896129298203732), FRAC_CONST(0.66126583783999227), FRAC_CONST(0.66356415861203977), FRAC_CONST(0.66585623366550972), FRAC_CONST(0.66814204142651845), FRAC_CONST(0.67042156038017309), FRAC_CONST(0.67269476907077286), FRAC_CONST(0.67496164610201193), FRAC_CONST(0.67722217013718033), FRAC_CONST(0.67947631989936497), FRAC_CONST(0.68172407417164971), FRAC_CONST(0.6839654117973154), FRAC_CONST(0.68620031168003859), FRAC_CONST(0.68842875278409044), FRAC_CONST(0.6906507141345346), FRAC_CONST(0.69286617481742463), FRAC_CONST(0.69507511398000088), FRAC_CONST(0.69727751083088652), FRAC_CONST(0.69947334464028377), FRAC_CONST(0.70166259474016845), FRAC_CONST(0.70384524052448494), FRAC_CONST(0.70602126144933974), FRAC_CONST(0.70819063703319529), FRAC_CONST(0.71035334685706231), FRAC_CONST(0.71250937056469232), FRAC_CONST(0.71465868786276898), FRAC_CONST(0.71680127852109954), FRAC_CONST(0.71893712237280438), FRAC_CONST(0.72106619931450811), FRAC_CONST(0.72318848930652735), FRAC_CONST(0.72530397237306066), FRAC_CONST(0.72741262860237577), FRAC_CONST(0.7295144381469969), FRAC_CONST(0.73160938122389252), FRAC_CONST(0.73369743811466026), FRAC_CONST(0.73577858916571348), FRAC_CONST(0.73785281478846598), FRAC_CONST(0.73992009545951609), FRAC_CONST(0.74198041172083096), FRAC_CONST(0.74403374417992918), FRAC_CONST(0.74608007351006378), FRAC_CONST(0.74811938045040349), FRAC_CONST(0.75015164580621496), FRAC_CONST(0.7521768504490427), FRAC_CONST(0.75419497531688917), FRAC_CONST(0.75620600141439454), FRAC_CONST(0.75820990981301528), FRAC_CONST(0.76020668165120242), FRAC_CONST(0.7621962981345789), FRAC_CONST(0.76417874053611667), FRAC_CONST(0.76615399019631281), FRAC_CONST(0.76812202852336531), FRAC_CONST(0.7700828369933479), FRAC_CONST(0.77203639715038441), FRAC_CONST(0.77398269060682279), FRAC_CONST(0.77592169904340758), FRAC_CONST(0.77785340420945304), FRAC_CONST(0.77977778792301444), FRAC_CONST(0.78169483207105939), FRAC_CONST(0.7836045186096382), FRAC_CONST(0.78550682956405393), FRAC_CONST(0.78740174702903132), FRAC_CONST(0.78928925316888565), FRAC_CONST(0.79116933021769009), FRAC_CONST(0.79304196047944364), FRAC_CONST(0.79490712632823701), FRAC_CONST(0.79676481020841872), FRAC_CONST(0.79861499463476082), FRAC_CONST(0.80045766219262271), FRAC_CONST(0.80229279553811572), FRAC_CONST(0.8041203773982657), FRAC_CONST(0.80594039057117628), FRAC_CONST(0.80775281792619036), FRAC_CONST(0.80955764240405126), FRAC_CONST(0.81135484701706373), FRAC_CONST(0.81314441484925359), FRAC_CONST(0.81492632905652662), FRAC_CONST(0.81670057286682785), FRAC_CONST(0.81846712958029866), FRAC_CONST(0.82022598256943469), FRAC_CONST(0.82197711527924155), FRAC_CONST(0.82372051122739132), FRAC_CONST(0.82545615400437744), FRAC_CONST(0.82718402727366902), FRAC_CONST(0.82890411477186487), FRAC_CONST(0.8306164003088462), FRAC_CONST(0.83232086776792968), FRAC_CONST(0.83401750110601813), FRAC_CONST(0.8357062843537526), FRAC_CONST(0.83738720161566194), FRAC_CONST(0.83906023707031263), FRAC_CONST(0.84072537497045807), FRAC_CONST(0.84238259964318596), FRAC_CONST(0.84403189549006641), FRAC_CONST(0.84567324698729907), FRAC_CONST(0.84730663868585832), FRAC_CONST(0.84893205521163961), FRAC_CONST(0.85054948126560337), FRAC_CONST(0.85215890162391983), FRAC_CONST(0.8537603011381113), FRAC_CONST(0.85535366473519603), FRAC_CONST(0.85693897741782865), FRAC_CONST(0.85851622426444274), FRAC_CONST(0.86008539042939014), FRAC_CONST(0.8616464611430813), FRAC_CONST(0.86319942171212416), FRAC_CONST(0.86474425751946238), FRAC_CONST(0.86628095402451299), FRAC_CONST(0.86780949676330321), FRAC_CONST(0.86932987134860673), FRAC_CONST(0.87084206347007886), FRAC_CONST(0.87234605889439154), FRAC_CONST(0.87384184346536675), FRAC_CONST(0.87532940310411078), FRAC_CONST(0.87680872380914576), FRAC_CONST(0.87827979165654146), FRAC_CONST(0.87974259280004741), FRAC_CONST(0.88119711347122198), FRAC_CONST(0.88264333997956279), FRAC_CONST(0.88408125871263499), FRAC_CONST(0.88551085613619995), FRAC_CONST(0.88693211879434208), FRAC_CONST(0.88834503330959624), FRAC_CONST(0.88974958638307289), FRAC_CONST(0.89114576479458318), FRAC_CONST(0.89253355540276469), FRAC_CONST(0.89391294514520325), FRAC_CONST(0.89528392103855758), FRAC_CONST(0.89664647017868015), FRAC_CONST(0.89800057974073988), FRAC_CONST(0.89934623697934146), FRAC_CONST(0.90068342922864686), FRAC_CONST(0.90201214390249307), FRAC_CONST(0.90333236849451182), FRAC_CONST(0.90464409057824624), FRAC_CONST(0.90594729780726846), FRAC_CONST(0.90724197791529593), FRAC_CONST(0.90852811871630612), FRAC_CONST(0.90980570810465222), FRAC_CONST(0.91107473405517625), FRAC_CONST(0.91233518462332275), FRAC_CONST(0.91358704794525081), FRAC_CONST(0.91483031223794609), FRAC_CONST(0.91606496579933161), FRAC_CONST(0.91729099700837791), FRAC_CONST(0.91850839432521225), FRAC_CONST(0.91971714629122736), FRAC_CONST(0.92091724152918952), FRAC_CONST(0.92210866874334507), FRAC_CONST(0.92329141671952764), FRAC_CONST(0.9244654743252626), FRAC_CONST(0.92563083050987272), FRAC_CONST(0.92678747430458175), FRAC_CONST(0.92793539482261789), FRAC_CONST(0.92907458125931575), FRAC_CONST(0.93020502289221907), FRAC_CONST(0.93132670908118043), FRAC_CONST(0.93243962926846236), FRAC_CONST(0.93354377297883617), FRAC_CONST(0.93463912981968078), FRAC_CONST(0.93572568948108037), FRAC_CONST(0.93680344173592156), FRAC_CONST(0.93787237643998989), FRAC_CONST(0.93893248353206449), FRAC_CONST(0.93998375303401394), FRAC_CONST(0.94102617505088926), FRAC_CONST(0.94205973977101731), FRAC_CONST(0.94308443746609349), FRAC_CONST(0.94410025849127266), FRAC_CONST(0.94510719328526061), FRAC_CONST(0.94610523237040334), FRAC_CONST(0.94709436635277722), FRAC_CONST(0.94807458592227623), FRAC_CONST(0.94904588185270056), FRAC_CONST(0.950008245001843), FRAC_CONST(0.95096166631157508), FRAC_CONST(0.95190613680793223), FRAC_CONST(0.95284164760119872), FRAC_CONST(0.95376818988599033), FRAC_CONST(0.95468575494133834), FRAC_CONST(0.95559433413077111), FRAC_CONST(0.95649391890239499), FRAC_CONST(0.95738450078897586), FRAC_CONST(0.95826607140801767), FRAC_CONST(0.95913862246184189), FRAC_CONST(0.96000214573766585), FRAC_CONST(0.96085663310767966), FRAC_CONST(0.96170207652912254), FRAC_CONST(0.96253846804435916), FRAC_CONST(0.96336579978095405), FRAC_CONST(0.96418406395174572), FRAC_CONST(0.96499325285492032), FRAC_CONST(0.96579335887408357), FRAC_CONST(0.96658437447833312), FRAC_CONST(0.96736629222232851), FRAC_CONST(0.96813910474636233), FRAC_CONST(0.96890280477642887), FRAC_CONST(0.96965738512429245), FRAC_CONST(0.9704028386875555), FRAC_CONST(0.97113915844972509), FRAC_CONST(0.9718663374802794), FRAC_CONST(0.97258436893473221), FRAC_CONST(0.97329324605469825), FRAC_CONST(0.97399296216795583), FRAC_CONST(0.97468351068851067), FRAC_CONST(0.97536488511665687), FRAC_CONST(0.97603707903903902), FRAC_CONST(0.97670008612871184), FRAC_CONST(0.97735390014519996), FRAC_CONST(0.97799851493455714), FRAC_CONST(0.9786339244294231), FRAC_CONST(0.97926012264908202), FRAC_CONST(0.97987710369951764), FRAC_CONST(0.98048486177346938), FRAC_CONST(0.98108339115048659), FRAC_CONST(0.98167268619698311), FRAC_CONST(0.98225274136628937), FRAC_CONST(0.98282355119870524), FRAC_CONST(0.98338511032155118), FRAC_CONST(0.98393741344921892), FRAC_CONST(0.98448045538322093), FRAC_CONST(0.98501423101223984), FRAC_CONST(0.98553873531217606), FRAC_CONST(0.98605396334619544), FRAC_CONST(0.98655991026477541), FRAC_CONST(0.98705657130575097), FRAC_CONST(0.98754394179435923), FRAC_CONST(0.98802201714328353), FRAC_CONST(0.98849079285269659), FRAC_CONST(0.98895026451030299), FRAC_CONST(0.98940042779138038), FRAC_CONST(0.98984127845882053), FRAC_CONST(0.99027281236316911), FRAC_CONST(0.99069502544266463), FRAC_CONST(0.99110791372327678), FRAC_CONST(0.9915114733187439), FRAC_CONST(0.99190570043060933), FRAC_CONST(0.99229059134825737), FRAC_CONST(0.99266614244894802), FRAC_CONST(0.99303235019785141), FRAC_CONST(0.99338921114808065), FRAC_CONST(0.9937367219407246), FRAC_CONST(0.99407487930487937), FRAC_CONST(0.9944036800576791), FRAC_CONST(0.9947231211043257), FRAC_CONST(0.99503319943811863), FRAC_CONST(0.99533391214048228), FRAC_CONST(0.99562525638099431), FRAC_CONST(0.99590722941741172), FRAC_CONST(0.99617982859569687), FRAC_CONST(0.99644305135004263), FRAC_CONST(0.99669689520289606), FRAC_CONST(0.99694135776498216), FRAC_CONST(0.99717643673532619), FRAC_CONST(0.9974021299012753), FRAC_CONST(0.99761843513851955), FRAC_CONST(0.99782535041111164), FRAC_CONST(0.99802287377148624), FRAC_CONST(0.99821100336047819), FRAC_CONST(0.99838973740734016), FRAC_CONST(0.99855907422975931), FRAC_CONST(0.99871901223387294), FRAC_CONST(0.99886954991428356), FRAC_CONST(0.99901068585407338), FRAC_CONST(0.99914241872481691), FRAC_CONST(0.99926474728659442), FRAC_CONST(0.99937767038800285), FRAC_CONST(0.99948118696616695), FRAC_CONST(0.99957529604674922), FRAC_CONST(0.99965999674395922), FRAC_CONST(0.99973528826056168), FRAC_CONST(0.99980116988788426), FRAC_CONST(0.99985764100582386), FRAC_CONST(0.9999047010828529), FRAC_CONST(0.99994234967602391), FRAC_CONST(0.99997058643097414), FRAC_CONST(0.9999894110819284), FRAC_CONST(0.99999882345170188) }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const real_t sine_mid_480[] = { FRAC_CONST(0.0016362454436240478), FRAC_CONST(0.00490871880799799), FRAC_CONST(0.0081811396039371282), FRAC_CONST(0.011453472786443779), FRAC_CONST(0.014725683311458524), FRAC_CONST(0.017997736136235509), FRAC_CONST(0.021269596219717739), FRAC_CONST(0.024541228522912285), FRAC_CONST(0.027812598009265607), FRAC_CONST(0.03108366964503869), FRAC_CONST(0.034354408399682276), FRAC_CONST(0.037624779246211978), FRAC_CONST(0.04089474716158345), FRAC_CONST(0.044164277127067358), FRAC_CONST(0.047433334128624507), FRAC_CONST(0.050701883157280733), FRAC_CONST(0.053969889209501881), FRAC_CONST(0.057237317287568618), FRAC_CONST(0.060504132399951269), FRAC_CONST(0.063770299561684493), FRAC_CONST(0.06703578379474201), FRAC_CONST(0.070300550128411174), FRAC_CONST(0.073564563599667426), FRAC_CONST(0.076827789253548759), FRAC_CONST(0.080090192143530081), FRAC_CONST(0.083351737331897449), FRAC_CONST(0.086612389890122182), FRAC_CONST(0.089872114899234967), FRAC_CONST(0.093130877450199795), FRAC_CONST(0.096388642644287828), FRAC_CONST(0.09964537559345106), FRAC_CONST(0.1029010414206961), FRAC_CONST(0.10615560526045748), FRAC_CONST(0.10940903225897117), FRAC_CONST(0.11266128757464781), FRAC_CONST(0.11591233637844581), FRAC_CONST(0.11916214385424433), FRAC_CONST(0.1224106751992162), FRAC_CONST(0.12565789562420052), FRAC_CONST(0.12890377035407541), FRAC_CONST(0.13214826462813015), FRAC_CONST(0.13539134370043773), FRAC_CONST(0.13863297284022669), FRAC_CONST(0.14187311733225325), FRAC_CONST(0.14511174247717309), FRAC_CONST(0.14834881359191271), FRAC_CONST(0.15158429601004111), FRAC_CONST(0.15481815508214106), FRAC_CONST(0.1580503561761798), FRAC_CONST(0.16128086467788047), FRAC_CONST(0.16450964599109233), FRAC_CONST(0.16773666553816149), FRAC_CONST(0.17096188876030122), FRAC_CONST(0.17418528111796186), FRAC_CONST(0.17740680809120093), FRAC_CONST(0.18062643518005275), FRAC_CONST(0.18384412790489776), FRAC_CONST(0.18705985180683199), FRAC_CONST(0.19027357244803589), FRAC_CONST(0.19348525541214331), FRAC_CONST(0.19669486630460997), FRAC_CONST(0.19990237075308173), FRAC_CONST(0.20310773440776286), FRAC_CONST(0.20631092294178383), FRAC_CONST(0.20951190205156878), FRAC_CONST(0.21271063745720317), FRAC_CONST(0.21590709490280058), FRAC_CONST(0.2191012401568698), FRAC_CONST(0.22229303901268133), FRAC_CONST(0.22548245728863364), FRAC_CONST(0.22866946082861941), FRAC_CONST(0.23185401550239115), FRAC_CONST(0.23503608720592667), FRAC_CONST(0.23821564186179459), FRAC_CONST(0.24139264541951888), FRAC_CONST(0.24456706385594387), FRAC_CONST(0.24773886317559846), FRAC_CONST(0.25090800941106001), FRAC_CONST(0.25407446862331851), FRAC_CONST(0.25723820690213967), FRAC_CONST(0.26039919036642817), FRAC_CONST(0.26355738516459076), FRAC_CONST(0.26671275747489837), FRAC_CONST(0.2698652735058486), FRAC_CONST(0.27301489949652735), FRAC_CONST(0.27616160171697068), FRAC_CONST(0.27930534646852595), FRAC_CONST(0.28244610008421245), FRAC_CONST(0.2855838289290823), FRAC_CONST(0.28871849940058025), FRAC_CONST(0.29185007792890405), FRAC_CONST(0.29497853097736348), FRAC_CONST(0.2981038250427398), FRAC_CONST(0.30122592665564446), FRAC_CONST(0.30434480238087736), FRAC_CONST(0.30746041881778519), FRAC_CONST(0.31057274260061901), FRAC_CONST(0.31368174039889146), FRAC_CONST(0.31678737891773395), FRAC_CONST(0.31988962489825296), FRAC_CONST(0.32298844511788638), FRAC_CONST(0.32608380639075912), FRAC_CONST(0.32917567556803889), FRAC_CONST(0.33226401953829071), FRAC_CONST(0.33534880522783189), FRAC_CONST(0.33842999960108583), FRAC_CONST(0.34150756966093632), FRAC_CONST(0.34458148244908043), FRAC_CONST(0.34765170504638188), FRAC_CONST(0.35071820457322322), FRAC_CONST(0.35378094818985806), FRAC_CONST(0.35683990309676283), FRAC_CONST(0.35989503653498811), FRAC_CONST(0.36294631578650921), FRAC_CONST(0.36599370817457672), FRAC_CONST(0.36903718106406647), FRAC_CONST(0.37207670186182878), FRAC_CONST(0.37511223801703802), FRAC_CONST(0.37814375702154046), FRAC_CONST(0.38117122641020335), FRAC_CONST(0.38419461376126157), FRAC_CONST(0.38721388669666562), FRAC_CONST(0.39022901288242801), FRAC_CONST(0.39323996002896966), FRAC_CONST(0.39624669589146555), FRAC_CONST(0.39924918827019029), FRAC_CONST(0.40224740501086254), FRAC_CONST(0.40524131400498986), FRAC_CONST(0.40823088319021217), FRAC_CONST(0.41121608055064529), FRAC_CONST(0.41419687411722372), FRAC_CONST(0.41717323196804335), FRAC_CONST(0.42014512222870243), FRAC_CONST(0.42311251307264408), FRAC_CONST(0.42607537272149631), FRAC_CONST(0.4290336694454126), FRAC_CONST(0.43198737156341183), FRAC_CONST(0.43493644744371707), FRAC_CONST(0.43788086550409511), FRAC_CONST(0.44082059421219388), FRAC_CONST(0.44375560208588088), FRAC_CONST(0.44668585769357955), FRAC_CONST(0.4496113296546066), FRAC_CONST(0.45253198663950756), FRAC_CONST(0.45544779737039259), FRAC_CONST(0.45835873062127125), FRAC_CONST(0.46126475521838717), FRAC_CONST(0.46416584004055156), FRAC_CONST(0.46706195401947659), FRAC_CONST(0.46995306614010829), FRAC_CONST(0.47283914544095862), FRAC_CONST(0.47572016101443682), FRAC_CONST(0.47859608200718085), FRAC_CONST(0.4814668776203872), FRAC_CONST(0.48433251711014125), FRAC_CONST(0.4871929697877464), FRAC_CONST(0.49004820502005247), FRAC_CONST(0.49289819222978404), FRAC_CONST(0.49574290089586776), FRAC_CONST(0.49858230055375902), FRAC_CONST(0.50141636079576901), FRAC_CONST(0.50424505127138919), FRAC_CONST(0.50706834168761705), FRAC_CONST(0.50988620180928057), FRAC_CONST(0.51269860145936175), FRAC_CONST(0.51550551051931948), FRAC_CONST(0.51830689892941317), FRAC_CONST(0.5211027366890234), FRAC_CONST(0.52389299385697385), FRAC_CONST(0.52667764055185196), FRAC_CONST(0.52945664695232897), FRAC_CONST(0.53222998329747884), FRAC_CONST(0.53499761988709726), FRAC_CONST(0.53775952708201991), FRAC_CONST(0.54051567530443978), FRAC_CONST(0.54326603503822357), FRAC_CONST(0.54601057682922816), FRAC_CONST(0.54874927128561579), FRAC_CONST(0.55148208907816942), FRAC_CONST(0.55420900094060566), FRAC_CONST(0.55692997766988939), FRAC_CONST(0.559644990126546), FRAC_CONST(0.56235400923497314), FRAC_CONST(0.56505700598375252), FRAC_CONST(0.56775395142596052), FRAC_CONST(0.57044481667947822), FRAC_CONST(0.57312957292730071), FRAC_CONST(0.57580819141784534), FRAC_CONST(0.57848064346525996), FRAC_CONST(0.58114690044973039), FRAC_CONST(0.58380693381778626), FRAC_CONST(0.58646071508260733), FRAC_CONST(0.58910821582432815), FRAC_CONST(0.5917494076903429), FRAC_CONST(0.5943842623956086), FRAC_CONST(0.59701275172294799), FRAC_CONST(0.59963484752335228), FRAC_CONST(0.60225052171628191), FRAC_CONST(0.60485974628996786), FRAC_CONST(0.60746249330171098), FRAC_CONST(0.61005873487818185), FRAC_CONST(0.61264844321571899), FRAC_CONST(0.61523159058062682), FRAC_CONST(0.61780814930947225), FRAC_CONST(0.62037809180938108), FRAC_CONST(0.62294139055833397), FRAC_CONST(0.6254980181054608), FRAC_CONST(0.62804794707133416), FRAC_CONST(0.63059115014826372), FRAC_CONST(0.63312760010058777), FRAC_CONST(0.63565726976496484), FRAC_CONST(0.63818013205066515), FRAC_CONST(0.64069615993986073), FRAC_CONST(0.64320532648791406), FRAC_CONST(0.64570760482366729), FRAC_CONST(0.64820296814972966), FRAC_CONST(0.65069138974276486), FRAC_CONST(0.65317284295377676), FRAC_CONST(0.65564730120839498), FRAC_CONST(0.65811473800715958), FRAC_CONST(0.660575126925805), FRAC_CONST(0.66302844161554231), FRAC_CONST(0.6654746558033422), FRAC_CONST(0.66791374329221598), FRAC_CONST(0.67034567796149647), FRAC_CONST(0.67277043376711676), FRAC_CONST(0.67518798474189046), FRAC_CONST(0.67759830499578866), FRAC_CONST(0.68000136871621808), FRAC_CONST(0.68239715016829683), FRAC_CONST(0.6847856236951303), FRAC_CONST(0.68716676371808583), FRAC_CONST(0.68954054473706683), FRAC_CONST(0.69190694133078579), FRAC_CONST(0.69426592815703603), FRAC_CONST(0.69661747995296419), FRAC_CONST(0.69896157153533944), FRAC_CONST(0.70129817780082437), FRAC_CONST(0.7036272737262429), FRAC_CONST(0.70594883436884903), FRAC_CONST(0.70826283486659336), FRAC_CONST(0.71056925043838959), FRAC_CONST(0.71286805638437978), FRAC_CONST(0.71515922808619936), FRAC_CONST(0.71744274100723993), FRAC_CONST(0.71971857069291278), FRAC_CONST(0.7219866927709101), FRAC_CONST(0.72424708295146689), FRAC_CONST(0.72649971702762028), FRAC_CONST(0.72874457087546896), FRAC_CONST(0.73098162045443171), FRAC_CONST(0.73321084180750484), FRAC_CONST(0.73543221106151868), FRAC_CONST(0.73764570442739286), FRAC_CONST(0.73985129820039208), FRAC_CONST(0.74204896876037885), FRAC_CONST(0.7442386925720671), FRAC_CONST(0.74642044618527381), FRAC_CONST(0.74859420623517081), FRAC_CONST(0.75075994944253421), FRAC_CONST(0.75291765261399446), FRAC_CONST(0.75506729264228367), FRAC_CONST(0.75720884650648446), FRAC_CONST(0.75934229127227548), FRAC_CONST(0.76146760409217706), FRAC_CONST(0.76358476220579641), FRAC_CONST(0.7656937429400712), FRAC_CONST(0.76779452370951196), FRAC_CONST(0.76988708201644451), FRAC_CONST(0.77197139545125026), FRAC_CONST(0.7740474416926072), FRAC_CONST(0.77611519850772781), FRAC_CONST(0.77817464375259782), FRAC_CONST(0.78022575537221317), FRAC_CONST(0.78226851140081632), FRAC_CONST(0.78430288996213138), FRAC_CONST(0.78632886926959822), FRAC_CONST(0.78834642762660623), FRAC_CONST(0.79035554342672631), FRAC_CONST(0.79235619515394229), FRAC_CONST(0.79434836138288134), FRAC_CONST(0.79633202077904397), FRAC_CONST(0.79830715209903147), FRAC_CONST(0.8002737341907743), FRAC_CONST(0.80223174599375802), FRAC_CONST(0.80418116653924954), FRAC_CONST(0.80612197495052085), FRAC_CONST(0.80805415044307316), FRAC_CONST(0.80997767232485907), FRAC_CONST(0.81189251999650469), FRAC_CONST(0.81379867295152986), FRAC_CONST(0.81569611077656778), FRAC_CONST(0.81758481315158371), FRAC_CONST(0.81946475985009259), FRAC_CONST(0.82133593073937561), FRAC_CONST(0.82319830578069586), FRAC_CONST(0.82505186502951278), FRAC_CONST(0.82689658863569615), FRAC_CONST(0.82873245684373809), FRAC_CONST(0.83055944999296494), FRAC_CONST(0.83237754851774781), FRAC_CONST(0.83418673294771239), FRAC_CONST(0.83598698390794668), FRAC_CONST(0.83777828211920935), FRAC_CONST(0.83956060839813562), FRAC_CONST(0.84133394365744296), FRAC_CONST(0.84309826890613537), FRAC_CONST(0.84485356524970701), FRAC_CONST(0.84659981389034411), FRAC_CONST(0.84833699612712676), FRAC_CONST(0.85006509335622882), FRAC_CONST(0.8517840870711173), FRAC_CONST(0.85349395886275037), FRAC_CONST(0.85519469041977514), FRAC_CONST(0.85688626352872277), FRAC_CONST(0.85856866007420429), FRAC_CONST(0.86024186203910447), FRAC_CONST(0.86190585150477417), FRAC_CONST(0.86356061065122347), FRAC_CONST(0.86520612175731115), FRAC_CONST(0.86684236720093533), FRAC_CONST(0.86846932945922151), FRAC_CONST(0.87008699110871135), FRAC_CONST(0.87169533482554817), FRAC_CONST(0.87329434338566281), FRAC_CONST(0.87488399966495822), FRAC_CONST(0.87646428663949283), FRAC_CONST(0.87803518738566277), FRAC_CONST(0.87959668508038291), FRAC_CONST(0.88114876300126743), FRAC_CONST(0.88269140452680916), FRAC_CONST(0.8842245931365561), FRAC_CONST(0.88574831241129048), FRAC_CONST(0.88726254603320276), FRAC_CONST(0.88876727778606746), FRAC_CONST(0.89026249155541637), FRAC_CONST(0.8917481713287112), FRAC_CONST(0.89322430119551532), FRAC_CONST(0.89469086534766362), FRAC_CONST(0.89614784807943237), FRAC_CONST(0.89759523378770689), FRAC_CONST(0.89903300697214927), FRAC_CONST(0.9004611522353636), FRAC_CONST(0.90187965428306172), FRAC_CONST(0.90328849792422594), FRAC_CONST(0.90468766807127299), FRAC_CONST(0.90607714974021469), FRAC_CONST(0.90745692805081868), FRAC_CONST(0.90882698822676755), FRAC_CONST(0.91018731559581767), FRAC_CONST(0.91153789558995579), FRAC_CONST(0.91287871374555518), FRAC_CONST(0.91420975570353069), FRAC_CONST(0.9155310072094921), FRAC_CONST(0.91684245411389753), FRAC_CONST(0.91814408237220391), FRAC_CONST(0.91943587804501858), FRAC_CONST(0.92071782729824769), FRAC_CONST(0.92198991640324446), FRAC_CONST(0.92325213173695675), FRAC_CONST(0.92450445978207241), FRAC_CONST(0.92574688712716402), FRAC_CONST(0.92697940046683291), FRAC_CONST(0.92820198660185149), FRAC_CONST(0.92941463243930444), FRAC_CONST(0.93061732499272909), FRAC_CONST(0.93181005138225426), FRAC_CONST(0.93299279883473885), FRAC_CONST(0.93416555468390772), FRAC_CONST(0.93532830637048769), FRAC_CONST(0.93648104144234268), FRAC_CONST(0.93762374755460598), FRAC_CONST(0.93875641246981323), FRAC_CONST(0.93987902405803303), FRAC_CONST(0.94099157029699743), FRAC_CONST(0.94209403927222979), FRAC_CONST(0.94318641917717327), FRAC_CONST(0.9442686983133165), FRAC_CONST(0.94534086509031956), FRAC_CONST(0.9464029080261378), FRAC_CONST(0.94745481574714419), FRAC_CONST(0.94849657698825252), FRAC_CONST(0.94952818059303667), FRAC_CONST(0.95054961551385087), FRAC_CONST(0.95156087081194762), FRAC_CONST(0.95256193565759528), FRAC_CONST(0.95355279933019343), FRAC_CONST(0.9545334512183884), FRAC_CONST(0.95550388082018611), FRAC_CONST(0.95646407774306541), FRAC_CONST(0.95741403170408834), FRAC_CONST(0.95835373253001133), FRAC_CONST(0.95928317015739362), FRAC_CONST(0.96020233463270466), FRAC_CONST(0.96111121611243155), FRAC_CONST(0.96200980486318388), FRAC_CONST(0.96289809126179782), FRAC_CONST(0.96377606579543984), FRAC_CONST(0.96464371906170809), FRAC_CONST(0.96550104176873297), FRAC_CONST(0.96634802473527726), FRAC_CONST(0.96718465889083372), FRAC_CONST(0.96801093527572268), FRAC_CONST(0.96882684504118799), FRAC_CONST(0.96963237944949143), FRAC_CONST(0.97042752987400682), FRAC_CONST(0.97121228779931179), FRAC_CONST(0.97198664482127939), FRAC_CONST(0.97275059264716823), FRAC_CONST(0.97350412309571066), FRAC_CONST(0.97424722809720088), FRAC_CONST(0.97497989969358168), FRAC_CONST(0.97570213003852857), FRAC_CONST(0.97641391139753486), FRAC_CONST(0.97711523614799412), FRAC_CONST(0.97780609677928154), FRAC_CONST(0.97848648589283505), FRAC_CONST(0.97915639620223371), FRAC_CONST(0.9798158205332762), FRAC_CONST(0.98046475182405801), FRAC_CONST(0.98110318312504607), FRAC_CONST(0.98173110759915416), FRAC_CONST(0.98234851852181571), FRAC_CONST(0.98295540928105563), FRAC_CONST(0.9835517733775615), FRAC_CONST(0.98413760442475307), FRAC_CONST(0.98471289614885038), FRAC_CONST(0.98527764238894122), FRAC_CONST(0.98583183709704714), FRAC_CONST(0.98637547433818806), FRAC_CONST(0.98690854829044583), FRAC_CONST(0.98743105324502667), FRAC_CONST(0.98794298360632238), FRAC_CONST(0.98844433389196995), FRAC_CONST(0.98893509873291074), FRAC_CONST(0.98941527287344755), FRAC_CONST(0.98988485117130098), FRAC_CONST(0.99034382859766479), FRAC_CONST(0.99079220023725967), FRAC_CONST(0.99122996128838525), FRAC_CONST(0.9916571070629725), FRAC_CONST(0.99207363298663342), FRAC_CONST(0.99247953459870997), FRAC_CONST(0.99287480755232194), FRAC_CONST(0.99325944761441354), FRAC_CONST(0.99363345066579889), FRAC_CONST(0.99399681270120555), FRAC_CONST(0.99434952982931812), FRAC_CONST(0.9946915982728195), FRAC_CONST(0.99502301436843166), FRAC_CONST(0.99534377456695422), FRAC_CONST(0.9956538754333033), FRAC_CONST(0.99595331364654771), FRAC_CONST(0.99624208599994479), FRAC_CONST(0.99652018940097464), FRAC_CONST(0.99678762087137318), FRAC_CONST(0.99704437754716424), FRAC_CONST(0.99729045667869021), FRAC_CONST(0.99752585563064111), FRAC_CONST(0.99775057188208349), FRAC_CONST(0.9979646030264866), FRAC_CONST(0.99816794677174903), FRAC_CONST(0.9983606009402225), FRAC_CONST(0.99854256346873571), FRAC_CONST(0.99871383240861611), FRAC_CONST(0.99887440592571108), FRAC_CONST(0.99902428230040718), FRAC_CONST(0.99916345992764877), FRAC_CONST(0.99929193731695531), FRAC_CONST(0.99940971309243731), FRAC_CONST(0.99951678599281069), FRAC_CONST(0.99961315487141078), FRAC_CONST(0.99969881869620425), FRAC_CONST(0.99977377654980037), FRAC_CONST(0.99983802762946083), FRAC_CONST(0.99989157124710804), FRAC_CONST(0.9999344068293331), FRAC_CONST(0.99996653391740109), FRAC_CONST(0.99998795216725689), FRAC_CONST(0.99999866134952808) }; #endif ALIGN static const real_t ld_mid_512[] = { FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0.0061358846491544753), FRAC_CONST(0.01840672990580482), FRAC_CONST(0.030674803176636626), FRAC_CONST(0.04293825693494082), FRAC_CONST(0.055195244349689934), FRAC_CONST(0.067443919563664051), FRAC_CONST(0.079682437971430126), FRAC_CONST(0.091908956497132724), FRAC_CONST(0.10412163387205459), FRAC_CONST(0.11631863091190475), FRAC_CONST(0.12849811079379317), FRAC_CONST(0.14065823933284921), FRAC_CONST(0.15279718525844344), FRAC_CONST(0.16491312048996989), FRAC_CONST(0.17700422041214875), FRAC_CONST(0.18906866414980619), FRAC_CONST(0.2011046348420919), FRAC_CONST(0.21311031991609136), FRAC_CONST(0.22508391135979283), FRAC_CONST(0.2370236059943672), FRAC_CONST(0.24892760574572015), FRAC_CONST(0.26079411791527551), FRAC_CONST(0.27262135544994898), FRAC_CONST(0.28440753721127188), FRAC_CONST(0.29615088824362379), FRAC_CONST(0.30784964004153487), FRAC_CONST(0.31950203081601569), FRAC_CONST(0.33110630575987643), FRAC_CONST(0.34266071731199438), FRAC_CONST(0.35416352542049034), FRAC_CONST(0.36561299780477385), FRAC_CONST(0.37700741021641826), FRAC_CONST(0.38834504669882625), FRAC_CONST(0.39962419984564679), FRAC_CONST(0.41084317105790391), FRAC_CONST(0.42200027079979968), FRAC_CONST(0.43309381885315196), FRAC_CONST(0.4441221445704292), FRAC_CONST(0.45508358712634384), FRAC_CONST(0.46597649576796618), FRAC_CONST(0.47679923006332209), FRAC_CONST(0.487550160148436), FRAC_CONST(0.49822766697278187), FRAC_CONST(0.50883014254310699), FRAC_CONST(0.51935599016558964), FRAC_CONST(0.52980362468629461), FRAC_CONST(0.54017147272989285), FRAC_CONST(0.55045797293660481), FRAC_CONST(0.56066157619733603), FRAC_CONST(0.57078074588696726), FRAC_CONST(0.58081395809576453), FRAC_CONST(0.59075970185887416), FRAC_CONST(0.60061647938386897), FRAC_CONST(0.61038280627630948), FRAC_CONST(0.6200572117632891), FRAC_CONST(0.62963823891492698), FRAC_CONST(0.63912444486377573), FRAC_CONST(0.64851440102211244), FRAC_CONST(0.65780669329707864), FRAC_CONST(0.66699992230363747), FRAC_CONST(0.67609270357531592), FRAC_CONST(0.68508366777270036), FRAC_CONST(0.693971460889654), FRAC_CONST(0.7027547444572253), FRAC_CONST(0.71143219574521643), FRAC_CONST(0.72000250796138165), FRAC_CONST(0.7284643904482252), FRAC_CONST(0.73681656887736979), FRAC_CONST(0.74505778544146595), FRAC_CONST(0.75318679904361241), FRAC_CONST(0.76120238548426178), FRAC_CONST(0.76910333764557959), FRAC_CONST(0.77688846567323244), FRAC_CONST(0.78455659715557524), FRAC_CONST(0.79210657730021239), FRAC_CONST(0.79953726910790501), FRAC_CONST(0.80684755354379922), FRAC_CONST(0.8140363297059483), FRAC_CONST(0.82110251499110465), FRAC_CONST(0.8280450452577558), FRAC_CONST(0.83486287498638001), FRAC_CONST(0.84155497743689833), FRAC_CONST(0.84812034480329712), FRAC_CONST(0.85455798836540053), FRAC_CONST(0.86086693863776731), FRAC_CONST(0.86704624551569265), FRAC_CONST(0.87309497841829009), FRAC_CONST(0.87901222642863341), FRAC_CONST(0.88479709843093779), FRAC_CONST(0.89044872324475788), FRAC_CONST(0.89596624975618511), FRAC_CONST(0.90134884704602203), FRAC_CONST(0.90659570451491533), FRAC_CONST(0.91170603200542988), FRAC_CONST(0.9166790599210427), FRAC_CONST(0.9215140393420419), FRAC_CONST(0.92621024213831127), FRAC_CONST(0.93076696107898371), FRAC_CONST(0.9351835099389475), FRAC_CONST(0.93945922360218992), FRAC_CONST(0.94359345816196039), FRAC_CONST(0.94758559101774109), FRAC_CONST(0.95143502096900834), FRAC_CONST(0.95514116830577067), FRAC_CONST(0.9587034748958716), FRAC_CONST(0.96212140426904158), FRAC_CONST(0.9653944416976894), FRAC_CONST(0.96852209427441727), FRAC_CONST(0.97150389098625178), FRAC_CONST(0.97433938278557586), FRAC_CONST(0.97702814265775439), FRAC_CONST(0.97956976568544052), FRAC_CONST(0.98196386910955524), FRAC_CONST(0.98421009238692903), FRAC_CONST(0.98630809724459867), FRAC_CONST(0.98825756773074946), FRAC_CONST(0.99005821026229712), FRAC_CONST(0.99170975366909953), FRAC_CONST(0.9932119492347945), FRAC_CONST(0.99456457073425542), FRAC_CONST(0.99576741446765982), FRAC_CONST(0.99682029929116567), FRAC_CONST(0.99772306664419164), FRAC_CONST(0.99847558057329477), FRAC_CONST(0.99907772775264536), FRAC_CONST(0.99952941750109314), FRAC_CONST(0.9998305817958234), FRAC_CONST(0.99998117528260111), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const real_t ld_mid_480[] = { FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0.0065449379673518581), FRAC_CONST(0.019633692460628301), FRAC_CONST(0.032719082821776137), FRAC_CONST(0.045798866936520771), FRAC_CONST(0.058870803651189033), FRAC_CONST(0.071932653156719387), FRAC_CONST(0.084982177372441667), FRAC_CONST(0.09801714032956059), FRAC_CONST(0.11103530855427769), FRAC_CONST(0.12403445145048532), FRAC_CONST(0.13701234168196802), FRAC_CONST(0.14996675555404498), FRAC_CONST(0.16289547339458874), FRAC_CONST(0.17579627993435451), FRAC_CONST(0.18866696468655525), FRAC_CONST(0.2015053223256171), FRAC_CONST(0.21430915306505074), FRAC_CONST(0.2270762630343732), FRAC_CONST(0.23980446465501654), FRAC_CONST(0.25249157701515795), FRAC_CONST(0.26513542624340797), FRAC_CONST(0.27773384588129219), FRAC_CONST(0.29028467725446233), FRAC_CONST(0.3027857698425746), FRAC_CONST(0.31523498164776964), FRAC_CONST(0.32763017956169349), FRAC_CONST(0.33996923973099424), FRAC_CONST(0.35225004792123354), FRAC_CONST(0.36447049987914965), FRAC_CONST(0.37662850169321077), FRAC_CONST(0.38872197015239557), FRAC_CONST(0.40074883310314097), FRAC_CONST(0.41270702980439467), FRAC_CONST(0.42459451128071307), FRAC_CONST(0.43640924067334208), FRAC_CONST(0.44814919358922256), FRAC_CONST(0.45981235844785984), FRAC_CONST(0.47139673682599764), FRAC_CONST(0.48290034380003727), FRAC_CONST(0.49432120828614462), FRAC_CONST(0.50565737337798455), FRAC_CONST(0.51690689668202761), FRAC_CONST(0.52806785065036799), FRAC_CONST(0.53913832291100017), FRAC_CONST(0.55011641659549337), FRAC_CONST(0.56100025066400983), FRAC_CONST(0.57178796022761225), FRAC_CONST(0.58247769686780215), FRAC_CONST(0.59306762895323706), FRAC_CONST(0.60355594195357143), FRAC_CONST(0.61394083875036642), FRAC_CONST(0.62422053994501758), FRAC_CONST(0.63439328416364549), FRAC_CONST(0.64445732835889735), FRAC_CONST(0.65441094810861034), FRAC_CONST(0.66425243791128175), FRAC_CONST(0.67398011147829784), FRAC_CONST(0.68359230202287125), FRAC_CONST(0.69308736254563585), FRAC_CONST(0.70246366611685174), FRAC_CONST(0.71171960615517138), FRAC_CONST(0.72085359670291882), FRAC_CONST(0.7298640726978356), FRAC_CONST(0.73874949024124625), FRAC_CONST(0.74750832686259672), FRAC_CONST(0.75613908178032285), FRAC_CONST(0.76464027615900032), FRAC_CONST(0.77301045336273699), FRAC_CONST(0.78124817920475853), FRAC_CONST(0.78935204219315003), FRAC_CONST(0.79732065377270711), FRAC_CONST(0.80515264856285829), FRAC_CONST(0.81284668459161513), FRAC_CONST(0.82040144352551359), FRAC_CONST(0.82781563089550203), FRAC_CONST(0.83508797631874299), FRAC_CONST(0.84221723371628654), FRAC_CONST(0.84920218152657889), FRAC_CONST(0.85604162291477137), FRAC_CONST(0.86273438597779184), FRAC_CONST(0.86927932394514362), FRAC_CONST(0.87567531537539967), FRAC_CONST(0.88192126434835494), FRAC_CONST(0.88801610065280734), FRAC_CONST(0.89395877996993212), FRAC_CONST(0.8997482840522214), FRAC_CONST(0.90538362089795521), FRAC_CONST(0.91086382492117568), FRAC_CONST(0.91618795711713596), FRAC_CONST(0.92135510522319242), FRAC_CONST(0.9263643838751181), FRAC_CONST(0.93121493475880346), FRAC_CONST(0.93590592675732565), FRAC_CONST(0.94043655609335486), FRAC_CONST(0.94480604646687805), FRAC_CONST(0.94901364918821385), FRAC_CONST(0.95305864330629697), FRAC_CONST(0.95694033573220882), FRAC_CONST(0.9606580613579353), FRAC_CONST(0.96421118317032928), FRAC_CONST(0.96759909236025976), FRAC_CONST(0.9708212084269281), FRAC_CONST(0.97387697927733363), FRAC_CONST(0.97676588132087239), FRAC_CONST(0.97948741955905139), FRAC_CONST(0.98204112767030394), FRAC_CONST(0.98442656808989171), FRAC_CONST(0.98664333208487898), FRAC_CONST(0.98869103982416728), FRAC_CONST(0.99056934044357725), FRAC_CONST(0.99227791210596705), FRAC_CONST(0.99381646205637808), FRAC_CONST(0.99518472667219682), FRAC_CONST(0.99638247150832537), FRAC_CONST(0.99740949133735191), FRAC_CONST(0.99826561018471593), FRAC_CONST(0.99895068135886012), FRAC_CONST(0.99946458747636568), FRAC_CONST(0.99980724048206482), FRAC_CONST(0.99997858166412923), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }; #endif #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_tf_grid.h0000644000175000017500000000304014647725151016337 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_tf_grid.h,v 1.17 2007/11/01 12:33:36 menno Exp $ **/ #ifndef __SBR_TF_GRID_H__ #define __SBR_TF_GRID_H__ #ifdef __cplusplus extern "C" { #endif uint8_t envelope_time_border_vector(sbr_info *sbr, uint8_t ch); void noise_floor_time_border_vector(sbr_info *sbr, uint8_t ch); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/bits.c0000644000175000017500000001454214647725151015020 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: bits.c,v 1.44 2007/11/01 12:33:29 menno Exp $ **/ #include "common.h" #include "structs.h" #include #include "bits.h" /* initialize buffer, call once before first getbits or showbits */ void faad_initbits(bitfile *ld, const void *_buffer, const uint32_t buffer_size) { uint32_t tmp; if (ld == NULL) return; // useless //memset(ld, 0, sizeof(bitfile)); if (buffer_size == 0 || _buffer == NULL) { ld->error = 1; return; } ld->buffer = _buffer; ld->buffer_size = buffer_size; ld->bytes_left = buffer_size; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)ld->buffer); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)ld->buffer, ld->bytes_left); ld->bytes_left = 0; } ld->bufa = tmp; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)ld->buffer + 1); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)ld->buffer + 1, ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->start = (uint32_t*)ld->buffer; ld->tail = ((uint32_t*)ld->buffer + 2); ld->bits_left = 32; ld->error = 0; } void faad_endbits(bitfile *ld) { // void (void)ld; } uint32_t faad_get_processed_bits(bitfile *ld) { return (uint32_t)(8 * (4*(ld->tail - ld->start) - 4) - (ld->bits_left)); } uint8_t faad_byte_align(bitfile *ld) { int remainder = (32 - ld->bits_left) & 0x7; if (remainder) { faad_flushbits(ld, 8 - remainder); return (uint8_t)(8 - remainder); } return 0; } void faad_flushbits_ex(bitfile *ld, uint32_t bits) { uint32_t tmp; ld->bufa = ld->bufb; if (ld->bytes_left >= 4) { tmp = getdword(ld->tail); ld->bytes_left -= 4; } else { tmp = getdword_n(ld->tail, ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->tail++; ld->bits_left += (32 - bits); //ld->bytes_left -= 4; // if (ld->bytes_left == 0) // ld->no_more_reading = 1; // if (ld->bytes_left < 0) // ld->error = 1; } /* rewind to beginning */ void faad_rewindbits(bitfile *ld) { uint32_t tmp; ld->bytes_left = ld->buffer_size; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)&ld->start[0]); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)&ld->start[0], ld->bytes_left); ld->bytes_left = 0; } ld->bufa = tmp; if (ld->bytes_left >= 4) { tmp = getdword((uint32_t*)&ld->start[1]); ld->bytes_left -= 4; } else { tmp = getdword_n((uint32_t*)&ld->start[1], ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->bits_left = 32; ld->tail = &ld->start[2]; } /* reset to a certain point */ void faad_resetbits(bitfile *ld, int bits) { uint32_t tmp; int words = bits >> 5; int remainder = bits & 0x1F; ld->bytes_left = ld->buffer_size - words*4; if (ld->bytes_left >= 4) { tmp = getdword(&ld->start[words]); ld->bytes_left -= 4; } else { tmp = getdword_n(&ld->start[words], ld->bytes_left); ld->bytes_left = 0; } ld->bufa = tmp; if (ld->bytes_left >= 4) { tmp = getdword(&ld->start[words+1]); ld->bytes_left -= 4; } else { tmp = getdword_n(&ld->start[words+1], ld->bytes_left); ld->bytes_left = 0; } ld->bufb = tmp; ld->bits_left = 32 - remainder; ld->tail = &ld->start[words+2]; /* recheck for reading too many bytes */ ld->error = 0; // if (ld->bytes_left == 0) // ld->no_more_reading = 1; // if (ld->bytes_left < 0) // ld->error = 1; } uint8_t *faad_getbitbuffer(bitfile *ld, uint32_t bits DEBUGDEC) { int i; unsigned int temp; int bytes = bits >> 3; int remainder = bits & 0x7; uint8_t *buffer = (uint8_t*)faad_malloc((bytes+1)*sizeof(uint8_t)); for (i = 0; i < bytes; i++) { buffer[i] = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(print,var,dbg)); } if (remainder) { temp = faad_getbits(ld, remainder DEBUGVAR(print,var,dbg)) << (8-remainder); buffer[bytes] = (uint8_t)temp; } return buffer; } #ifdef DRM /* return the original data buffer */ void *faad_origbitbuffer(bitfile *ld) { return (void*)ld->start; } /* return the original data buffer size */ uint32_t faad_origbitbuffer_size(bitfile *ld) { return ld->buffer_size; } #endif /* reversed bit reading routines, used for RVLC and HCR */ void faad_initbits_rev(bitfile *ld, void *buffer, uint32_t bits_in_buffer) { uint32_t tmp; int32_t index; ld->buffer_size = bit2byte(bits_in_buffer); index = (bits_in_buffer+31)/32 - 1; ld->start = (uint32_t*)buffer + index - 2; tmp = getdword((uint32_t*)buffer + index); ld->bufa = tmp; tmp = getdword((uint32_t*)buffer + index - 1); ld->bufb = tmp; ld->tail = (uint32_t*)buffer + index; ld->bits_left = bits_in_buffer % 32; if (ld->bits_left == 0) ld->bits_left = 32; ld->bytes_left = ld->buffer_size; ld->error = 0; } /* EOF */ xine-lib-1.2/contrib/libfaad/mdct.h0000644000175000017500000000312314647725151015004 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: mdct.h,v 1.30 2007/11/01 12:33:31 menno Exp $ **/ #ifndef __MDCT_H__ #define __MDCT_H__ #ifdef __cplusplus extern "C" { #endif mdct_info *faad_mdct_init(uint16_t N); void faad_mdct_end(mdct_info *mdct); void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out); void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/filtbank.h0000644000175000017500000000411014647725152015645 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: filtbank.h,v 1.27 2007/11/01 12:33:30 menno Exp $ **/ #ifndef __FILTBANK_H__ #define __FILTBANK_H__ #ifdef __cplusplus extern "C" { #endif fb_info *filter_bank_init(uint16_t frame_len); void filter_bank_end(fb_info *fb); #ifdef LTP_DEC void filter_bank_ltp(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *in_data, real_t *out_mdct, uint8_t object_type, uint16_t frame_len); #endif void ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *freq_in, real_t *time_out, real_t *overlap, uint8_t object_type, uint16_t frame_len); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_hfadj.h0000644000175000017500000000341414647725151016002 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_hfadj.h,v 1.19 2007/11/01 12:33:35 menno Exp $ **/ #ifndef __SBR_HFADJ_H__ #define __SBR_HFADJ_H__ #ifdef __cplusplus extern "C" { #endif typedef struct { real_t G_lim_boost[MAX_L_E][MAX_M]; real_t Q_M_lim_boost[MAX_L_E][MAX_M]; real_t S_M_boost[MAX_L_E][MAX_M]; } sbr_hfadj_info; #define SBR_HFADJ_INFO_INIT {{{0}}, {{0}}, {{0}}} uint8_t hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64] #ifdef SBR_LOW_POWER ,real_t *deg #endif ,uint8_t ch); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/huffman.h0000644000175000017500000000314414647725152015505 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: huffman.h,v 1.28 2007/11/01 12:33:30 menno Exp $ **/ #ifndef __HUFFMAN_H__ #define __HUFFMAN_H__ #ifdef __cplusplus extern "C" { #endif int8_t huffman_scale_factor(bitfile *ld); uint8_t huffman_spectral_data(uint8_t cb, bitfile *ld, int16_t *sp); #ifdef ERROR_RESILIENCE int8_t huffman_spectral_data_2(uint8_t cb, bits_t *ld, int16_t *sp); #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ic_predict.h0000644000175000017500000003412314647725151016166 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ic_predict.h,v 1.23 2007/11/01 12:33:31 menno Exp $ **/ #ifdef MAIN_DEC #ifndef __IC_PREDICT_H__ #define __IC_PREDICT_H__ #ifdef __cplusplus extern "C" { #endif #define ALPHA REAL_CONST(0.90625) #define A REAL_CONST(0.953125) void pns_reset_pred_state(ic_stream *ics, pred_state *state); void reset_all_predictors(pred_state *state, uint16_t frame_len); void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state, uint16_t frame_len, uint8_t sf_index); ALIGN static const real_t mnt_table[128] = { COEF_CONST(0.9531250000), COEF_CONST(0.9453125000), COEF_CONST(0.9375000000), COEF_CONST(0.9296875000), COEF_CONST(0.9257812500), COEF_CONST(0.9179687500), COEF_CONST(0.9101562500), COEF_CONST(0.9023437500), COEF_CONST(0.8984375000), COEF_CONST(0.8906250000), COEF_CONST(0.8828125000), COEF_CONST(0.8789062500), COEF_CONST(0.8710937500), COEF_CONST(0.8671875000), COEF_CONST(0.8593750000), COEF_CONST(0.8515625000), COEF_CONST(0.8476562500), COEF_CONST(0.8398437500), COEF_CONST(0.8359375000), COEF_CONST(0.8281250000), COEF_CONST(0.8242187500), COEF_CONST(0.8203125000), COEF_CONST(0.8125000000), COEF_CONST(0.8085937500), COEF_CONST(0.8007812500), COEF_CONST(0.7968750000), COEF_CONST(0.7929687500), COEF_CONST(0.7851562500), COEF_CONST(0.7812500000), COEF_CONST(0.7773437500), COEF_CONST(0.7734375000), COEF_CONST(0.7656250000), COEF_CONST(0.7617187500), COEF_CONST(0.7578125000), COEF_CONST(0.7539062500), COEF_CONST(0.7500000000), COEF_CONST(0.7421875000), COEF_CONST(0.7382812500), COEF_CONST(0.7343750000), COEF_CONST(0.7304687500), COEF_CONST(0.7265625000), COEF_CONST(0.7226562500), COEF_CONST(0.7187500000), COEF_CONST(0.7148437500), COEF_CONST(0.7109375000), COEF_CONST(0.7070312500), COEF_CONST(0.6992187500), COEF_CONST(0.6953125000), COEF_CONST(0.6914062500), COEF_CONST(0.6875000000), COEF_CONST(0.6835937500), COEF_CONST(0.6796875000), COEF_CONST(0.6796875000), COEF_CONST(0.6757812500), COEF_CONST(0.6718750000), COEF_CONST(0.6679687500), COEF_CONST(0.6640625000), COEF_CONST(0.6601562500), COEF_CONST(0.6562500000), COEF_CONST(0.6523437500), COEF_CONST(0.6484375000), COEF_CONST(0.6445312500), COEF_CONST(0.6406250000), COEF_CONST(0.6406250000), COEF_CONST(0.6367187500), COEF_CONST(0.6328125000), COEF_CONST(0.6289062500), COEF_CONST(0.6250000000), COEF_CONST(0.6210937500), COEF_CONST(0.6210937500), COEF_CONST(0.6171875000), COEF_CONST(0.6132812500), COEF_CONST(0.6093750000), COEF_CONST(0.6054687500), COEF_CONST(0.6054687500), COEF_CONST(0.6015625000), COEF_CONST(0.5976562500), COEF_CONST(0.5937500000), COEF_CONST(0.5937500000), COEF_CONST(0.5898437500), COEF_CONST(0.5859375000), COEF_CONST(0.5820312500), COEF_CONST(0.5820312500), COEF_CONST(0.5781250000), COEF_CONST(0.5742187500), COEF_CONST(0.5742187500), COEF_CONST(0.5703125000), COEF_CONST(0.5664062500), COEF_CONST(0.5664062500), COEF_CONST(0.5625000000), COEF_CONST(0.5585937500), COEF_CONST(0.5585937500), COEF_CONST(0.5546875000), COEF_CONST(0.5507812500), COEF_CONST(0.5507812500), COEF_CONST(0.5468750000), COEF_CONST(0.5429687500), COEF_CONST(0.5429687500), COEF_CONST(0.5390625000), COEF_CONST(0.5390625000), COEF_CONST(0.5351562500), COEF_CONST(0.5312500000), COEF_CONST(0.5312500000), COEF_CONST(0.5273437500), COEF_CONST(0.5273437500), COEF_CONST(0.5234375000), COEF_CONST(0.5195312500), COEF_CONST(0.5195312500), COEF_CONST(0.5156250000), COEF_CONST(0.5156250000), COEF_CONST(0.5117187500), COEF_CONST(0.5117187500), COEF_CONST(0.5078125000), COEF_CONST(0.5078125000), COEF_CONST(0.5039062500), COEF_CONST(0.5039062500), COEF_CONST(0.5000000000), COEF_CONST(0.4980468750), COEF_CONST(0.4960937500), COEF_CONST(0.4941406250), COEF_CONST(0.4921875000), COEF_CONST(0.4902343750), COEF_CONST(0.4882812500), COEF_CONST(0.4863281250), COEF_CONST(0.4843750000), COEF_CONST(0.4824218750), COEF_CONST(0.4804687500), COEF_CONST(0.4785156250) }; ALIGN static const real_t exp_table[128] = { COEF_CONST(0.50000000000000000000000000000000000000000000000000), COEF_CONST(0.25000000000000000000000000000000000000000000000000), COEF_CONST(0.12500000000000000000000000000000000000000000000000), COEF_CONST(0.06250000000000000000000000000000000000000000000000), COEF_CONST(0.03125000000000000000000000000000000000000000000000), COEF_CONST(0.01562500000000000000000000000000000000000000000000), COEF_CONST(0.00781250000000000000000000000000000000000000000000), COEF_CONST(0.00390625000000000000000000000000000000000000000000), COEF_CONST(0.00195312500000000000000000000000000000000000000000), COEF_CONST(0.00097656250000000000000000000000000000000000000000), COEF_CONST(0.00048828125000000000000000000000000000000000000000), COEF_CONST(0.00024414062500000000000000000000000000000000000000), COEF_CONST(0.00012207031250000000000000000000000000000000000000), COEF_CONST(0.00006103515625000000000000000000000000000000000000), COEF_CONST(0.00003051757812500000000000000000000000000000000000), COEF_CONST(0.00001525878906250000000000000000000000000000000000), COEF_CONST(0.00000762939453125000000000000000000000000000000000), COEF_CONST(0.00000381469726562500000000000000000000000000000000), COEF_CONST(0.00000190734863281250000000000000000000000000000000), COEF_CONST(0.00000095367431640625000000000000000000000000000000), COEF_CONST(0.00000047683715820312500000000000000000000000000000), COEF_CONST(0.00000023841857910156250000000000000000000000000000), COEF_CONST(0.00000011920928955078125000000000000000000000000000), COEF_CONST(0.00000005960464477539062500000000000000000000000000), COEF_CONST(0.00000002980232238769531300000000000000000000000000), COEF_CONST(0.00000001490116119384765600000000000000000000000000), COEF_CONST(0.00000000745058059692382810000000000000000000000000), COEF_CONST(0.00000000372529029846191410000000000000000000000000), COEF_CONST(0.00000000186264514923095700000000000000000000000000), COEF_CONST(0.00000000093132257461547852000000000000000000000000), COEF_CONST(0.00000000046566128730773926000000000000000000000000), COEF_CONST(0.00000000023283064365386963000000000000000000000000), COEF_CONST(0.00000000011641532182693481000000000000000000000000), COEF_CONST(0.00000000005820766091346740700000000000000000000000), COEF_CONST(0.00000000002910383045673370400000000000000000000000), COEF_CONST(0.00000000001455191522836685200000000000000000000000), COEF_CONST(0.00000000000727595761418342590000000000000000000000), COEF_CONST(0.00000000000363797880709171300000000000000000000000), COEF_CONST(0.00000000000181898940354585650000000000000000000000), COEF_CONST(0.00000000000090949470177292824000000000000000000000), COEF_CONST(0.00000000000045474735088646412000000000000000000000), COEF_CONST(0.00000000000022737367544323206000000000000000000000), COEF_CONST(0.00000000000011368683772161603000000000000000000000), COEF_CONST(0.00000000000005684341886080801500000000000000000000), COEF_CONST(0.00000000000002842170943040400700000000000000000000), COEF_CONST(0.00000000000001421085471520200400000000000000000000), COEF_CONST(0.00000000000000710542735760100190000000000000000000), COEF_CONST(0.00000000000000355271367880050090000000000000000000), COEF_CONST(0.00000000000000177635683940025050000000000000000000), COEF_CONST(0.00000000000000088817841970012523000000000000000000), COEF_CONST(0.00000000000000044408920985006262000000000000000000), COEF_CONST(0.00000000000000022204460492503131000000000000000000), COEF_CONST(0.00000000000000011102230246251565000000000000000000), COEF_CONST(0.00000000000000005551115123125782700000000000000000), COEF_CONST(0.00000000000000002775557561562891400000000000000000), COEF_CONST(0.00000000000000001387778780781445700000000000000000), COEF_CONST(0.00000000000000000693889390390722840000000000000000), COEF_CONST(0.00000000000000000346944695195361420000000000000000), COEF_CONST(0.00000000000000000173472347597680710000000000000000), COEF_CONST(0.00000000000000000086736173798840355000000000000000), COEF_CONST(0.00000000000000000043368086899420177000000000000000), COEF_CONST(0.00000000000000000021684043449710089000000000000000), COEF_CONST(0.00000000000000000010842021724855044000000000000000), COEF_CONST(0.00000000000000000005421010862427522200000000000000), COEF_CONST(0.00000000000000000002710505431213761100000000000000), COEF_CONST(0.00000000000000000001355252715606880500000000000000), COEF_CONST(0.00000000000000000000677626357803440270000000000000), COEF_CONST(0.00000000000000000000338813178901720140000000000000), COEF_CONST(0.00000000000000000000169406589450860070000000000000), COEF_CONST(0.00000000000000000000084703294725430034000000000000), COEF_CONST(0.00000000000000000000042351647362715017000000000000), COEF_CONST(0.00000000000000000000021175823681357508000000000000), COEF_CONST(0.00000000000000000000010587911840678754000000000000), COEF_CONST(0.00000000000000000000005293955920339377100000000000), COEF_CONST(0.00000000000000000000002646977960169688600000000000), COEF_CONST(0.00000000000000000000001323488980084844300000000000), COEF_CONST(0.00000000000000000000000661744490042422140000000000), COEF_CONST(0.00000000000000000000000330872245021211070000000000), COEF_CONST(0.00000000000000000000000165436122510605530000000000), COEF_CONST(0.00000000000000000000000082718061255302767000000000), COEF_CONST(0.00000000000000000000000041359030627651384000000000), COEF_CONST(0.00000000000000000000000020679515313825692000000000), COEF_CONST(0.00000000000000000000000010339757656912846000000000), COEF_CONST(0.00000000000000000000000005169878828456423000000000), COEF_CONST(0.00000000000000000000000002584939414228211500000000), COEF_CONST(0.00000000000000000000000001292469707114105700000000), COEF_CONST(0.00000000000000000000000000646234853557052870000000), COEF_CONST(0.00000000000000000000000000323117426778526440000000), COEF_CONST(0.00000000000000000000000000161558713389263220000000), COEF_CONST(0.00000000000000000000000000080779356694631609000000), COEF_CONST(0.00000000000000000000000000040389678347315804000000), COEF_CONST(0.00000000000000000000000000020194839173657902000000), COEF_CONST(0.00000000000000000000000000010097419586828951000000), COEF_CONST(0.00000000000000000000000000005048709793414475600000), COEF_CONST(0.00000000000000000000000000002524354896707237800000), COEF_CONST(0.00000000000000000000000000001262177448353618900000), COEF_CONST(0.00000000000000000000000000000631088724176809440000), COEF_CONST(0.00000000000000000000000000000315544362088404720000), COEF_CONST(0.00000000000000000000000000000157772181044202360000), COEF_CONST(0.00000000000000000000000000000078886090522101181000), COEF_CONST(0.00000000000000000000000000000039443045261050590000), COEF_CONST(0.00000000000000000000000000000019721522630525295000), COEF_CONST(0.00000000000000000000000000000009860761315262647600), COEF_CONST(0.00000000000000000000000000000004930380657631323800), COEF_CONST(0.00000000000000000000000000000002465190328815661900), COEF_CONST(0.00000000000000000000000000000001232595164407830900), COEF_CONST(0.00000000000000000000000000000000616297582203915470), COEF_CONST(0.00000000000000000000000000000000308148791101957740), COEF_CONST(0.00000000000000000000000000000000154074395550978870), COEF_CONST(0.00000000000000000000000000000000077037197775489434), COEF_CONST(0.00000000000000000000000000000000038518598887744717), COEF_CONST(0.00000000000000000000000000000000019259299443872359), COEF_CONST(0.00000000000000000000000000000000009629649721936179), COEF_CONST(0.00000000000000000000000000000000004814824860968090), COEF_CONST(0.00000000000000000000000000000000002407412430484045), COEF_CONST(0.00000000000000000000000000000000001203706215242022), COEF_CONST(0.00000000000000000000000000000000000601853107621011), COEF_CONST(0.00000000000000000000000000000000000300926553810506), COEF_CONST(0.00000000000000000000000000000000000150463276905253), COEF_CONST(0.00000000000000000000000000000000000075231638452626), COEF_CONST(0.00000000000000000000000000000000000037615819226313), COEF_CONST(0.00000000000000000000000000000000000018807909613157), COEF_CONST(0.00000000000000000000000000000000000009403954806578), COEF_CONST(0.00000000000000000000000000000000000004701977403289), COEF_CONST(0.00000000000000000000000000000000000002350988701645), COEF_CONST(0.00000000000000000000000000000000000001175494350822), COEF_CONST(0.0 /* 0000000000000000000000000000000000000587747175411 "floating point underflow" */), COEF_CONST(0.0) }; #ifdef __cplusplus } #endif #endif #endif xine-lib-1.2/contrib/libfaad/pulse.h0000644000175000017500000000273014647725151015210 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: pulse.h,v 1.20 2007/11/01 12:33:34 menno Exp $ **/ #ifndef __PULSE_H__ #define __PULSE_H__ #ifdef __cplusplus extern "C" { #endif uint8_t pulse_decode(ic_stream *ics, int16_t *spec_coef, uint16_t framelen); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ms.h0000644000175000017500000000276614647725152014511 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ms.h,v 1.19 2007/11/01 12:33:32 menno Exp $ **/ #ifndef __MS_H__ #define __MS_H__ #ifdef __cplusplus extern "C" { #endif void ms_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec, uint16_t frame_len); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/structs.h0000644000175000017500000002461614647725152015577 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: structs.h,v 1.49 2009/01/26 23:51:15 menno Exp $ **/ #ifndef __STRUCTS_H__ #define __STRUCTS_H__ #ifdef __cplusplus extern "C" { #endif #include "cfft.h" #ifdef SBR_DEC #include "sbr_dec.h" #endif #define MAX_CHANNELS 64 #define MAX_SYNTAX_ELEMENTS 48 #define MAX_WINDOW_GROUPS 8 #define MAX_SFB 51 #define MAX_LTP_SFB 40 #define MAX_LTP_SFB_S 8 /* used to save the prediction state */ typedef struct { int16_t r[2]; int16_t COR[2]; int16_t VAR[2]; } pred_state; typedef struct { uint16_t N; cfft_info *cfft; complex_t *sincos; #ifdef PROFILE int64_t cycles; int64_t fft_cycles; #endif } mdct_info; typedef struct { const real_t *long_window[2]; const real_t *short_window[2]; #ifdef LD_DEC const real_t *ld_window[2]; #endif mdct_info *mdct256; #ifdef LD_DEC mdct_info *mdct1024; #endif mdct_info *mdct2048; #ifdef PROFILE int64_t cycles; #endif } fb_info; typedef struct { uint8_t present; uint8_t num_bands; uint8_t pce_instance_tag; uint8_t excluded_chns_present; uint8_t band_top[17]; uint8_t prog_ref_level; uint8_t dyn_rng_sgn[17]; uint8_t dyn_rng_ctl[17]; uint8_t exclude_mask[MAX_CHANNELS]; uint8_t additional_excluded_chns[MAX_CHANNELS]; real_t ctrl1; real_t ctrl2; } drc_info; typedef struct { uint8_t element_instance_tag; uint8_t object_type; uint8_t sf_index; uint8_t num_front_channel_elements; uint8_t num_side_channel_elements; uint8_t num_back_channel_elements; uint8_t num_lfe_channel_elements; uint8_t num_assoc_data_elements; uint8_t num_valid_cc_elements; uint8_t mono_mixdown_present; uint8_t mono_mixdown_element_number; uint8_t stereo_mixdown_present; uint8_t stereo_mixdown_element_number; uint8_t matrix_mixdown_idx_present; uint8_t pseudo_surround_enable; uint8_t matrix_mixdown_idx; uint8_t front_element_is_cpe[16]; uint8_t front_element_tag_select[16]; uint8_t side_element_is_cpe[16]; uint8_t side_element_tag_select[16]; uint8_t back_element_is_cpe[16]; uint8_t back_element_tag_select[16]; uint8_t lfe_element_tag_select[16]; uint8_t assoc_data_element_tag_select[16]; uint8_t cc_element_is_ind_sw[16]; uint8_t valid_cc_element_tag_select[16]; uint8_t channels; uint8_t comment_field_bytes; uint8_t comment_field_data[257]; /* extra added values */ uint8_t num_front_channels; uint8_t num_side_channels; uint8_t num_back_channels; uint8_t num_lfe_channels; uint8_t sce_channel[16]; uint8_t cpe_channel[16]; } program_config; typedef struct { uint16_t syncword; uint8_t id; uint8_t layer; uint8_t protection_absent; uint8_t profile; uint8_t sf_index; uint8_t private_bit; uint8_t channel_configuration; uint8_t original; uint8_t home; uint8_t emphasis; uint8_t copyright_identification_bit; uint8_t copyright_identification_start; uint16_t aac_frame_length; uint16_t adts_buffer_fullness; uint8_t no_raw_data_blocks_in_frame; uint16_t crc_check; /* control param */ uint8_t old_format; } adts_header; typedef struct { uint8_t copyright_id_present; int8_t copyright_id[10]; uint8_t original_copy; uint8_t home; uint8_t bitstream_type; uint32_t bitrate; uint8_t num_program_config_elements; uint32_t adif_buffer_fullness; /* maximum of 16 PCEs */ program_config pce[16]; } adif_header; #ifdef LTP_DEC typedef struct { uint8_t last_band; uint8_t data_present; uint16_t lag; uint8_t lag_update; uint8_t coef; uint8_t long_used[MAX_SFB]; uint8_t short_used[8]; uint8_t short_lag_present[8]; uint8_t short_lag[8]; } ltp_info; #endif #ifdef MAIN_DEC typedef struct { uint8_t limit; uint8_t predictor_reset; uint8_t predictor_reset_group_number; uint8_t prediction_used[MAX_SFB]; } pred_info; #endif typedef struct { uint8_t number_pulse; uint8_t pulse_start_sfb; uint8_t pulse_offset[4]; uint8_t pulse_amp[4]; } pulse_info; typedef struct { uint8_t n_filt[8]; uint8_t coef_res[8]; uint8_t length[8][4]; uint8_t order[8][4]; uint8_t direction[8][4]; uint8_t coef_compress[8][4]; uint8_t coef[8][4][32]; } tns_info; #ifdef SSR_DEC typedef struct { uint8_t max_band; uint8_t adjust_num[4][8]; uint8_t alevcode[4][8][8]; uint8_t aloccode[4][8][8]; } ssr_info; #endif typedef struct { uint8_t max_sfb; uint8_t num_swb; uint8_t num_window_groups; uint8_t num_windows; uint8_t window_sequence; uint8_t window_group_length[8]; uint8_t window_shape; uint8_t scale_factor_grouping; uint16_t sect_sfb_offset[8][15*8]; uint16_t swb_offset[52]; uint16_t swb_offset_max; uint8_t sect_cb[8][15*8]; uint16_t sect_start[8][15*8]; uint16_t sect_end[8][15*8]; uint8_t sfb_cb[8][8*15]; uint8_t num_sec[8]; /* number of sections in a group */ uint8_t global_gain; int16_t scale_factors[8][51]; /* [0..255] */ uint8_t ms_mask_present; uint8_t ms_used[MAX_WINDOW_GROUPS][MAX_SFB]; uint8_t noise_used; uint8_t is_used; uint8_t pulse_data_present; uint8_t tns_data_present; uint8_t gain_control_data_present; uint8_t predictor_data_present; pulse_info pul; tns_info tns; #ifdef MAIN_DEC pred_info pred; #endif #ifdef LTP_DEC ltp_info ltp; ltp_info ltp2; #endif #ifdef SSR_DEC ssr_info ssr; #endif #ifdef ERROR_RESILIENCE /* ER HCR data */ uint16_t length_of_reordered_spectral_data; uint8_t length_of_longest_codeword; /* ER RLVC data */ uint8_t sf_concealment; uint8_t rev_global_gain; uint16_t length_of_rvlc_sf; uint16_t dpcm_noise_nrg; uint8_t sf_escapes_present; uint8_t length_of_rvlc_escapes; uint16_t dpcm_noise_last_position; #endif } ic_stream; /* individual channel stream */ typedef struct { uint8_t channel; int16_t paired_channel; uint8_t element_instance_tag; uint8_t common_window; ic_stream ics1; ic_stream ics2; } element; /* syntax element (SCE, CPE, LFE) */ /* FIXME: do we need to 0 fill all of it (no glitches heared without so far)? */ #define ELEMENT_INIT {.channel = 0} #define MAX_ASC_BYTES 64 typedef struct { int inited; int version, versionA; int framelen_type; int useSameStreamMux; int allStreamsSameTimeFraming; int numSubFrames; int numPrograms; int numLayers; int otherDataPresent; uint32_t otherDataLenBits; uint32_t frameLength; uint8_t ASC[MAX_ASC_BYTES]; uint32_t ASCbits; } latm_header; typedef struct { uint8_t adts_header_present; uint8_t adif_header_present; uint8_t latm_header_present; uint8_t sf_index; uint8_t object_type; uint8_t channelConfiguration; #ifdef ERROR_RESILIENCE uint8_t aacSectionDataResilienceFlag; uint8_t aacScalefactorDataResilienceFlag; uint8_t aacSpectralDataResilienceFlag; #endif uint16_t frameLength; uint8_t postSeekResetFlag; uint32_t frame; uint8_t downMatrix; uint8_t upMatrix; uint8_t first_syn_ele; uint8_t has_lfe; /* number of channels in current frame */ uint8_t fr_channels; /* number of elements in current frame */ uint8_t fr_ch_ele; /* element_output_channels: determines the number of channels the element will output */ uint8_t element_output_channels[MAX_SYNTAX_ELEMENTS]; /* element_alloced: determines whether the data needed for the element is allocated or not */ uint8_t element_alloced[MAX_SYNTAX_ELEMENTS]; /* alloced_channels: determines the number of channels where output data is allocated for */ uint8_t alloced_channels; /* output data buffer */ void *sample_buffer; uint8_t window_shape_prev[MAX_CHANNELS]; #ifdef LTP_DEC uint16_t ltp_lag[MAX_CHANNELS]; #endif fb_info *fb; drc_info *drc; real_t *time_out[MAX_CHANNELS]; real_t *fb_intermed[MAX_CHANNELS]; #ifdef SBR_DEC int8_t sbr_present_flag; int8_t forceUpSampling; int8_t downSampledSBR; /* determines whether SBR data is allocated for the gives element */ uint8_t sbr_alloced[MAX_SYNTAX_ELEMENTS]; sbr_info *sbr[MAX_SYNTAX_ELEMENTS]; #endif #if (defined(PS_DEC) || defined(DRM_PS)) uint8_t ps_used[MAX_SYNTAX_ELEMENTS]; uint8_t ps_used_global; #endif #ifdef SSR_DEC real_t *ssr_overlap[MAX_CHANNELS]; real_t *prev_fmd[MAX_CHANNELS]; real_t ipqf_buffer[MAX_CHANNELS][4][96/4]; #endif #ifdef MAIN_DEC pred_state *pred_stat[MAX_CHANNELS]; #endif #ifdef LTP_DEC int16_t *lt_pred_stat[MAX_CHANNELS]; #endif #ifdef DRM uint8_t error_state; #endif /* RNG states */ uint32_t __r1; uint32_t __r2; /* Program Config Element */ uint8_t pce_set; program_config pce; uint8_t element_id[MAX_CHANNELS]; uint8_t internal_channel[MAX_CHANNELS]; /* Configuration data */ NeAACDecConfiguration config; #ifdef PROFILE int64_t cycles; int64_t spectral_cycles; int64_t output_cycles; int64_t scalefac_cycles; int64_t requant_cycles; #endif latm_header latm_config; const unsigned char *cmes; } NeAACDecStruct; #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/pulse.c0000644000175000017500000000361114647725152015203 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: pulse.c,v 1.21 2007/11/01 12:33:34 menno Exp $ **/ #include "common.h" #include "structs.h" #include "syntax.h" #include "pulse.h" uint8_t pulse_decode(ic_stream *ics, int16_t *spec_data, uint16_t framelen) { uint8_t i; uint16_t k; pulse_info *pul = &(ics->pul); k = min(ics->swb_offset[pul->pulse_start_sfb], ics->swb_offset_max); for (i = 0; i <= pul->number_pulse; i++) { k += pul->pulse_offset[i]; if (k >= framelen) return 15; /* should not be possible */ if (spec_data[k] > 0) spec_data[k] += pul->pulse_amp[i]; else spec_data[k] -= pul->pulse_amp[i]; } return 0; } xine-lib-1.2/contrib/libfaad/codebook/0000755000175000017500000000000014647725152015473 5ustar memexine-lib-1.2/contrib/libfaad/codebook/hcb_9.h0000644000175000017500000002746014647725151016640 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_9.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* Binary search huffman table HCB_9 */ static const hcb_bin_pair hcb9[] = { { /* 0 */ 0, { 1, 2 } }, { /* 1 */ 1, { 0, 0 } }, { /* 2 */ 0, { 1, 2 } }, { /* 3 */ 0, { 2, 3 } }, { /* 4 */ 0, { 3, 4 } }, { /* 5 */ 1, { 1, 0 } }, { /* 6 */ 1, { 0, 1 } }, { /* 7 */ 0, { 2, 3 } }, { /* 8 */ 0, { 3, 4 } }, { /* 9 */ 1, { 1, 1 } }, { /* 10 */ 0, { 3, 4 } }, { /* 11 */ 0, { 4, 5 } }, { /* 12 */ 0, { 5, 6 } }, { /* 13 */ 0, { 6, 7 } }, { /* 14 */ 0, { 7, 8 } }, { /* 15 */ 0, { 8, 9 } }, { /* 16 */ 0, { 9, 10 } }, { /* 17 */ 0, { 10, 11 } }, { /* 18 */ 0, { 11, 12 } }, { /* 19 */ 1, { 2, 1 } }, { /* 20 */ 1, { 1, 2 } }, { /* 21 */ 1, { 2, 0 } }, { /* 22 */ 1, { 0, 2 } }, { /* 23 */ 0, { 8, 9 } }, { /* 24 */ 0, { 9, 10 } }, { /* 25 */ 0, { 10, 11 } }, { /* 26 */ 0, { 11, 12 } }, { /* 27 */ 0, { 12, 13 } }, { /* 28 */ 0, { 13, 14 } }, { /* 29 */ 0, { 14, 15 } }, { /* 30 */ 0, { 15, 16 } }, { /* 31 */ 1, { 3, 1 } }, { /* 32 */ 1, { 2, 2 } }, { /* 33 */ 1, { 1, 3 } }, { /* 34 */ 0, { 13, 14 } }, { /* 35 */ 0, { 14, 15 } }, { /* 36 */ 0, { 15, 16 } }, { /* 37 */ 0, { 16, 17 } }, { /* 38 */ 0, { 17, 18 } }, { /* 39 */ 0, { 18, 19 } }, { /* 40 */ 0, { 19, 20 } }, { /* 41 */ 0, { 20, 21 } }, { /* 42 */ 0, { 21, 22 } }, { /* 43 */ 0, { 22, 23 } }, { /* 44 */ 0, { 23, 24 } }, { /* 45 */ 0, { 24, 25 } }, { /* 46 */ 0, { 25, 26 } }, { /* 47 */ 1, { 3, 0 } }, { /* 48 */ 1, { 0, 3 } }, { /* 49 */ 1, { 2, 3 } }, { /* 50 */ 1, { 3, 2 } }, { /* 51 */ 1, { 1, 4 } }, { /* 52 */ 1, { 4, 1 } }, { /* 53 */ 1, { 2, 4 } }, { /* 54 */ 1, { 1, 5 } }, { /* 55 */ 0, { 18, 19 } }, { /* 56 */ 0, { 19, 20 } }, { /* 57 */ 0, { 20, 21 } }, { /* 58 */ 0, { 21, 22 } }, { /* 59 */ 0, { 22, 23 } }, { /* 60 */ 0, { 23, 24 } }, { /* 61 */ 0, { 24, 25 } }, { /* 62 */ 0, { 25, 26 } }, { /* 63 */ 0, { 26, 27 } }, { /* 64 */ 0, { 27, 28 } }, { /* 65 */ 0, { 28, 29 } }, { /* 66 */ 0, { 29, 30 } }, { /* 67 */ 0, { 30, 31 } }, { /* 68 */ 0, { 31, 32 } }, { /* 69 */ 0, { 32, 33 } }, { /* 70 */ 0, { 33, 34 } }, { /* 71 */ 0, { 34, 35 } }, { /* 72 */ 0, { 35, 36 } }, { /* 73 */ 1, { 4, 2 } }, { /* 74 */ 1, { 3, 3 } }, { /* 75 */ 1, { 0, 4 } }, { /* 76 */ 1, { 4, 0 } }, { /* 77 */ 1, { 5, 1 } }, { /* 78 */ 1, { 2, 5 } }, { /* 79 */ 1, { 1, 6 } }, { /* 80 */ 1, { 3, 4 } }, { /* 81 */ 1, { 5, 2 } }, { /* 82 */ 1, { 6, 1 } }, { /* 83 */ 1, { 4, 3 } }, { /* 84 */ 0, { 25, 26 } }, { /* 85 */ 0, { 26, 27 } }, { /* 86 */ 0, { 27, 28 } }, { /* 87 */ 0, { 28, 29 } }, { /* 88 */ 0, { 29, 30 } }, { /* 89 */ 0, { 30, 31 } }, { /* 90 */ 0, { 31, 32 } }, { /* 91 */ 0, { 32, 33 } }, { /* 92 */ 0, { 33, 34 } }, { /* 93 */ 0, { 34, 35 } }, { /* 94 */ 0, { 35, 36 } }, { /* 95 */ 0, { 36, 37 } }, { /* 96 */ 0, { 37, 38 } }, { /* 97 */ 0, { 38, 39 } }, { /* 98 */ 0, { 39, 40 } }, { /* 99 */ 0, { 40, 41 } }, { /* 00 */ 0, { 41, 42 } }, { /* 01 */ 0, { 42, 43 } }, { /* 02 */ 0, { 43, 44 } }, { /* 03 */ 0, { 44, 45 } }, { /* 04 */ 0, { 45, 46 } }, { /* 05 */ 0, { 46, 47 } }, { /* 06 */ 0, { 47, 48 } }, { /* 07 */ 0, { 48, 49 } }, { /* 08 */ 0, { 49, 50 } }, { /* 09 */ 1, { 0, 5 } }, { /* 10 */ 1, { 2, 6 } }, { /* 11 */ 1, { 5, 0 } }, { /* 12 */ 1, { 1, 7 } }, { /* 13 */ 1, { 3, 5 } }, { /* 14 */ 1, { 1, 8 } }, { /* 15 */ 1, { 8, 1 } }, { /* 16 */ 1, { 4, 4 } }, { /* 17 */ 1, { 5, 3 } }, { /* 18 */ 1, { 6, 2 } }, { /* 19 */ 1, { 7, 1 } }, { /* 20 */ 1, { 0, 6 } }, { /* 21 */ 1, { 8, 2 } }, { /* 22 */ 1, { 2, 8 } }, { /* 23 */ 1, { 3, 6 } }, { /* 24 */ 1, { 2, 7 } }, { /* 25 */ 1, { 4, 5 } }, { /* 26 */ 1, { 9, 1 } }, { /* 27 */ 1, { 1, 9 } }, { /* 28 */ 1, { 7, 2 } }, { /* 29 */ 0, { 30, 31 } }, { /* 30 */ 0, { 31, 32 } }, { /* 31 */ 0, { 32, 33 } }, { /* 32 */ 0, { 33, 34 } }, { /* 33 */ 0, { 34, 35 } }, { /* 34 */ 0, { 35, 36 } }, { /* 35 */ 0, { 36, 37 } }, { /* 36 */ 0, { 37, 38 } }, { /* 37 */ 0, { 38, 39 } }, { /* 38 */ 0, { 39, 40 } }, { /* 39 */ 0, { 40, 41 } }, { /* 40 */ 0, { 41, 42 } }, { /* 41 */ 0, { 42, 43 } }, { /* 42 */ 0, { 43, 44 } }, { /* 43 */ 0, { 44, 45 } }, { /* 44 */ 0, { 45, 46 } }, { /* 45 */ 0, { 46, 47 } }, { /* 46 */ 0, { 47, 48 } }, { /* 47 */ 0, { 48, 49 } }, { /* 48 */ 0, { 49, 50 } }, { /* 49 */ 0, { 50, 51 } }, { /* 50 */ 0, { 51, 52 } }, { /* 51 */ 0, { 52, 53 } }, { /* 52 */ 0, { 53, 54 } }, { /* 53 */ 0, { 54, 55 } }, { /* 54 */ 0, { 55, 56 } }, { /* 55 */ 0, { 56, 57 } }, { /* 56 */ 0, { 57, 58 } }, { /* 57 */ 0, { 58, 59 } }, { /* 58 */ 0, { 59, 60 } }, { /* 59 */ 1, { 6, 0 } }, { /* 60 */ 1, { 5, 4 } }, { /* 61 */ 1, { 6, 3 } }, { /* 62 */ 1, { 8, 3 } }, { /* 63 */ 1, { 0, 7 } }, { /* 64 */ 1, { 9, 2 } }, { /* 65 */ 1, { 3, 8 } }, { /* 66 */ 1, { 4, 6 } }, { /* 67 */ 1, { 3, 7 } }, { /* 68 */ 1, { 0, 8 } }, { /* 69 */ 1, { 10, 1 } }, { /* 70 */ 1, { 6, 4 } }, { /* 71 */ 1, { 2, 9 } }, { /* 72 */ 1, { 5, 5 } }, { /* 73 */ 1, { 8, 0 } }, { /* 74 */ 1, { 7, 0 } }, { /* 75 */ 1, { 7, 3 } }, { /* 76 */ 1, { 10, 2 } }, { /* 77 */ 1, { 9, 3 } }, { /* 78 */ 1, { 8, 4 } }, { /* 79 */ 1, { 1, 10 } }, { /* 80 */ 1, { 7, 4 } }, { /* 81 */ 1, { 6, 5 } }, { /* 82 */ 1, { 5, 6 } }, { /* 83 */ 1, { 4, 8 } }, { /* 84 */ 1, { 4, 7 } }, { /* 85 */ 1, { 3, 9 } }, { /* 86 */ 1, { 11, 1 } }, { /* 87 */ 1, { 5, 8 } }, { /* 88 */ 1, { 9, 0 } }, { /* 89 */ 1, { 8, 5 } }, { /* 90 */ 0, { 29, 30 } }, { /* 91 */ 0, { 30, 31 } }, { /* 92 */ 0, { 31, 32 } }, { /* 93 */ 0, { 32, 33 } }, { /* 94 */ 0, { 33, 34 } }, { /* 95 */ 0, { 34, 35 } }, { /* 96 */ 0, { 35, 36 } }, { /* 97 */ 0, { 36, 37 } }, { /* 98 */ 0, { 37, 38 } }, { /* 99 */ 0, { 38, 39 } }, { /* 00 */ 0, { 39, 40 } }, { /* 01 */ 0, { 40, 41 } }, { /* 02 */ 0, { 41, 42 } }, { /* 03 */ 0, { 42, 43 } }, { /* 04 */ 0, { 43, 44 } }, { /* 05 */ 0, { 44, 45 } }, { /* 06 */ 0, { 45, 46 } }, { /* 07 */ 0, { 46, 47 } }, { /* 08 */ 0, { 47, 48 } }, { /* 09 */ 0, { 48, 49 } }, { /* 10 */ 0, { 49, 50 } }, { /* 11 */ 0, { 50, 51 } }, { /* 12 */ 0, { 51, 52 } }, { /* 13 */ 0, { 52, 53 } }, { /* 14 */ 0, { 53, 54 } }, { /* 15 */ 0, { 54, 55 } }, { /* 16 */ 0, { 55, 56 } }, { /* 17 */ 0, { 56, 57 } }, { /* 18 */ 0, { 57, 58 } }, { /* 19 */ 1, { 10, 3 } }, { /* 20 */ 1, { 2, 10 } }, { /* 21 */ 1, { 0, 9 } }, { /* 22 */ 1, { 11, 2 } }, { /* 23 */ 1, { 9, 4 } }, { /* 24 */ 1, { 6, 6 } }, { /* 25 */ 1, { 12, 1 } }, { /* 26 */ 1, { 4, 9 } }, { /* 27 */ 1, { 8, 6 } }, { /* 28 */ 1, { 1, 11 } }, { /* 29 */ 1, { 9, 5 } }, { /* 30 */ 1, { 10, 4 } }, { /* 31 */ 1, { 5, 7 } }, { /* 32 */ 1, { 7, 5 } }, { /* 33 */ 1, { 2, 11 } }, { /* 34 */ 1, { 1, 12 } }, { /* 35 */ 1, { 12, 2 } }, { /* 36 */ 1, { 11, 3 } }, { /* 37 */ 1, { 3, 10 } }, { /* 38 */ 1, { 5, 9 } }, { /* 39 */ 1, { 6, 7 } }, { /* 40 */ 1, { 8, 7 } }, { /* 41 */ 1, { 11, 4 } }, { /* 42 */ 1, { 0, 10 } }, { /* 43 */ 1, { 7, 6 } }, { /* 44 */ 1, { 12, 3 } }, { /* 45 */ 1, { 10, 0 } }, { /* 46 */ 1, { 10, 5 } }, { /* 47 */ 1, { 4, 10 } }, { /* 48 */ 1, { 6, 8 } }, { /* 49 */ 1, { 2, 12 } }, { /* 50 */ 1, { 9, 6 } }, { /* 51 */ 1, { 9, 7 } }, { /* 52 */ 1, { 4, 11 } }, { /* 53 */ 1, { 11, 0 } }, { /* 54 */ 1, { 6, 9 } }, { /* 55 */ 1, { 3, 11 } }, { /* 56 */ 1, { 5, 10 } }, { /* 57 */ 0, { 20, 21 } }, { /* 58 */ 0, { 21, 22 } }, { /* 59 */ 0, { 22, 23 } }, { /* 60 */ 0, { 23, 24 } }, { /* 61 */ 0, { 24, 25 } }, { /* 62 */ 0, { 25, 26 } }, { /* 63 */ 0, { 26, 27 } }, { /* 64 */ 0, { 27, 28 } }, { /* 65 */ 0, { 28, 29 } }, { /* 66 */ 0, { 29, 30 } }, { /* 67 */ 0, { 30, 31 } }, { /* 68 */ 0, { 31, 32 } }, { /* 69 */ 0, { 32, 33 } }, { /* 70 */ 0, { 33, 34 } }, { /* 71 */ 0, { 34, 35 } }, { /* 72 */ 0, { 35, 36 } }, { /* 73 */ 0, { 36, 37 } }, { /* 74 */ 0, { 37, 38 } }, { /* 75 */ 0, { 38, 39 } }, { /* 76 */ 0, { 39, 40 } }, { /* 77 */ 1, { 8, 8 } }, { /* 78 */ 1, { 7, 8 } }, { /* 79 */ 1, { 12, 5 } }, { /* 80 */ 1, { 3, 12 } }, { /* 81 */ 1, { 11, 5 } }, { /* 82 */ 1, { 7, 7 } }, { /* 83 */ 1, { 12, 4 } }, { /* 84 */ 1, { 11, 6 } }, { /* 85 */ 1, { 10, 6 } }, { /* 86 */ 1, { 4, 12 } }, { /* 87 */ 1, { 7, 9 } }, { /* 88 */ 1, { 5, 11 } }, { /* 89 */ 1, { 0, 11 } }, { /* 90 */ 1, { 12, 6 } }, { /* 91 */ 1, { 6, 10 } }, { /* 92 */ 1, { 12, 0 } }, { /* 93 */ 1, { 10, 7 } }, { /* 94 */ 1, { 5, 12 } }, { /* 95 */ 1, { 7, 10 } }, { /* 96 */ 1, { 9, 8 } }, { /* 97 */ 1, { 0, 12 } }, { /* 98 */ 1, { 11, 7 } }, { /* 99 */ 1, { 8, 9 } }, { /* 00 */ 1, { 9, 9 } }, { /* 01 */ 1, { 10, 8 } }, { /* 02 */ 1, { 7, 11 } }, { /* 03 */ 1, { 12, 7 } }, { /* 04 */ 1, { 6, 11 } }, { /* 05 */ 1, { 8, 11 } }, { /* 06 */ 1, { 11, 8 } }, { /* 07 */ 1, { 7, 12 } }, { /* 08 */ 1, { 6, 12 } }, { /* 09 */ 0, { 8, 9 } }, { /* 10 */ 0, { 9, 10 } }, { /* 11 */ 0, { 10, 11 } }, { /* 12 */ 0, { 11, 12 } }, { /* 13 */ 0, { 12, 13 } }, { /* 14 */ 0, { 13, 14 } }, { /* 15 */ 0, { 14, 15 } }, { /* 16 */ 0, { 15, 16 } }, { /* 17 */ 1, { 8, 10 } }, { /* 18 */ 1, { 10, 9 } }, { /* 19 */ 1, { 8, 12 } }, { /* 20 */ 1, { 9, 10 } }, { /* 21 */ 1, { 9, 11 } }, { /* 22 */ 1, { 9, 12 } }, { /* 23 */ 1, { 10, 11 } }, { /* 24 */ 1, { 12, 9 } }, { /* 25 */ 1, { 10, 10 } }, { /* 26 */ 1, { 11, 9 } }, { /* 27 */ 1, { 12, 8 } }, { /* 28 */ 1, { 11, 10 } }, { /* 29 */ 1, { 12, 10 } }, { /* 30 */ 1, { 12, 11 } }, { /* 31 */ 0, { 2, 3 } }, { /* 32 */ 0, { 3, 4 } }, { /* 33 */ 1, { 10, 12 } }, { /* 34 */ 1, { 11, 11 } }, { /* 35 */ 1, { 11, 12 } }, { /* 36 */ 1, { 12, 12 } } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_11.h0000644000175000017500000002321314647725151016701 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_11.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* 2-step huffman table HCB_11 */ /* 1st step: 5 bits * 2^5 = 32 entries * * Used to find offset into 2nd step table and number of extra bits to get */ static const hcb hcb11_1[] = { /* 4 bits */ { /* 00000 */ 0, 0 }, { /* */ 0, 0 }, { /* 00010 */ 1, 0 }, { /* */ 1, 0 }, /* 5 bits */ { /* 00100 */ 2, 0 }, { /* 00101 */ 3, 0 }, { /* 00110 */ 4, 0 }, { /* 00111 */ 5, 0 }, { /* 01000 */ 6, 0 }, { /* 01001 */ 7, 0 }, /* 6 bits */ { /* 01010 */ 8, 1 }, { /* 01011 */ 10, 1 }, { /* 01100 */ 12, 1 }, /* 6/7 bits */ { /* 01101 */ 14, 2 }, /* 7 bits */ { /* 01110 */ 18, 2 }, { /* 01111 */ 22, 2 }, { /* 10000 */ 26, 2 }, /* 7/8 bits */ { /* 10001 */ 30, 3 }, /* 8 bits */ { /* 10010 */ 38, 3 }, { /* 10011 */ 46, 3 }, { /* 10100 */ 54, 3 }, { /* 10101 */ 62, 3 }, { /* 10110 */ 70, 3 }, { /* 10111 */ 78, 3 }, /* 8/9 bits */ { /* 11000 */ 86, 4 }, /* 9 bits */ { /* 11001 */ 102, 4 }, { /* 11010 */ 118, 4 }, { /* 11011 */ 134, 4 }, /* 9/10 bits */ { /* 11100 */ 150, 5 }, /* 10 bits */ { /* 11101 */ 182, 5 }, { /* 11110 */ 214, 5 }, /* 10/11/12 bits */ { /* 11111 */ 246, 7 } }; /* 2nd step table * * Gives size of codeword and actual data (x,y,v,w) */ static const hcb_2_pair hcb11_2[] = { /* 4 */ { 4, 0, 0 }, { 4, 1, 1 }, /* 5 */ { 5, 16, 16 }, { 5, 1, 0 }, { 5, 0, 1 }, { 5, 2, 1 }, { 5, 1, 2 }, { 5, 2, 2 }, /* 6 */ { 6, 1, 3 }, { 6, 3, 1 }, { 6, 3, 2 }, { 6, 2, 0 }, { 6, 2, 3 }, { 6, 0, 2 }, /* 6/7 */ { 6, 3, 3 }, { 6, 3, 3 }, { 7, 4, 1 }, { 7, 1, 4 }, /* 7 */ { 7, 4, 2 }, { 7, 2, 4 }, { 7, 4, 3 }, { 7, 3, 4 }, { 7, 3, 0 }, { 7, 0, 3 }, { 7, 5, 1 }, { 7, 5, 2 }, { 7, 2, 5 }, { 7, 4, 4 }, { 7, 1, 5 }, { 7, 5, 3 }, /* 7/8 */ { 7, 3, 5 }, { 7, 3, 5 }, { 7, 5, 4 }, { 7, 5, 4 }, { 8, 4, 5 }, { 8, 6, 2 }, { 8, 2, 6 }, { 8, 6, 1 }, /* 8 */ { 8, 6, 3 }, { 8, 3, 6 }, { 8, 1, 6 }, { 8, 4, 16 }, { 8, 3, 16 }, { 8, 16, 5 }, { 8, 16, 3 }, { 8, 16, 4 }, { 8, 6, 4 }, { 8, 16, 6 }, { 8, 4, 0 }, { 8, 4, 6 }, { 8, 0, 4 }, { 8, 2, 16 }, { 8, 5, 5 }, { 8, 5, 16 }, { 8, 16, 7 }, { 8, 16, 2 }, { 8, 16, 8 }, { 8, 2, 7 }, { 8, 7, 2 }, { 8, 3, 7 }, { 8, 6, 5 }, { 8, 5, 6 }, { 8, 6, 16 }, { 8, 16, 10 }, { 8, 7, 3 }, { 8, 7, 1 }, { 8, 16, 9 }, { 8, 7, 16 }, { 8, 1, 16 }, { 8, 1, 7 }, { 8, 4, 7 }, { 8, 16, 11 }, { 8, 7, 4 }, { 8, 16, 12 }, { 8, 8, 16 }, { 8, 16, 1 }, { 8, 6, 6 }, { 8, 9, 16 }, { 8, 2, 8 }, { 8, 5, 7 }, { 8, 10, 16 }, { 8, 16, 13 }, { 8, 8, 3 }, { 8, 8, 2 }, { 8, 3, 8 }, { 8, 5, 0 }, /* 8/9 */ { 8, 16, 14 }, { 8, 16, 14 }, { 8, 11, 16 }, { 8, 11, 16 }, { 8, 7, 5 }, { 8, 7, 5 }, { 8, 4, 8 }, { 8, 4, 8 }, { 8, 6, 7 }, { 8, 6, 7 }, { 8, 7, 6 }, { 8, 7, 6 }, { 8, 0, 5 }, { 8, 0, 5 }, { 9, 8, 4 }, { 9, 16, 15 }, /* 9 */ { 9, 12, 16 }, { 9, 1, 8 }, { 9, 8, 1 }, { 9, 14, 16 }, { 9, 5, 8 }, { 9, 13, 16 }, { 9, 3, 9 }, { 9, 8, 5 }, { 9, 7, 7 }, { 9, 2, 9 }, { 9, 8, 6 }, { 9, 9, 2 }, { 9, 9, 3 }, { 9, 15, 16 }, { 9, 4, 9 }, { 9, 6, 8 }, { 9, 6, 0 }, { 9, 9, 4 }, { 9, 5, 9 }, { 9, 8, 7 }, { 9, 7, 8 }, { 9, 1, 9 }, { 9, 10, 3 }, { 9, 0, 6 }, { 9, 10, 2 }, { 9, 9, 1 }, { 9, 9, 5 }, { 9, 4, 10 }, { 9, 2, 10 }, { 9, 9, 6 }, { 9, 3, 10 }, { 9, 6, 9 }, { 9, 10, 4 }, { 9, 8, 8 }, { 9, 10, 5 }, { 9, 9, 7 }, { 9, 11, 3 }, { 9, 1, 10 }, { 9, 7, 0 }, { 9, 10, 6 }, { 9, 7, 9 }, { 9, 3, 11 }, { 9, 5, 10 }, { 9, 10, 1 }, { 9, 4, 11 }, { 9, 11, 2 }, { 9, 13, 2 }, { 9, 6, 10 }, /* 9/10 */ { 9, 13, 3 }, { 9, 13, 3 }, { 9, 2, 11 }, { 9, 2, 11 }, { 9, 16, 0 }, { 9, 16, 0 }, { 9, 5, 11 }, { 9, 5, 11 }, { 9, 11, 5 }, { 9, 11, 5 }, { 10, 11, 4 }, { 10, 9, 8 }, { 10, 7, 10 }, { 10, 8, 9 }, { 10, 0, 16 }, { 10, 4, 13 }, { 10, 0, 7 }, { 10, 3, 13 }, { 10, 11, 6 }, { 10, 13, 1 }, { 10, 13, 4 }, { 10, 12, 3 }, { 10, 2, 13 }, { 10, 13, 5 }, { 10, 8, 10 }, { 10, 6, 11 }, { 10, 10, 8 }, { 10, 10, 7 }, { 10, 14, 2 }, { 10, 12, 4 }, { 10, 1, 11 }, { 10, 4, 12 }, /* 10 */ { 10, 11, 1 }, { 10, 3, 12 }, { 10, 1, 13 }, { 10, 12, 2 }, { 10, 7, 11 }, { 10, 3, 14 }, { 10, 5, 12 }, { 10, 5, 13 }, { 10, 14, 4 }, { 10, 4, 14 }, { 10, 11, 7 }, { 10, 14, 3 }, { 10, 12, 5 }, { 10, 13, 6 }, { 10, 12, 6 }, { 10, 8, 0 }, { 10, 11, 8 }, { 10, 2, 12 }, { 10, 9, 9 }, { 10, 14, 5 }, { 10, 6, 13 }, { 10, 10, 10 }, { 10, 15, 2 }, { 10, 8, 11 }, { 10, 9, 10 }, { 10, 14, 6 }, { 10, 10, 9 }, { 10, 5, 14 }, { 10, 11, 9 }, { 10, 14, 1 }, { 10, 2, 14 }, { 10, 6, 12 }, { 10, 1, 12 }, { 10, 13, 8 }, { 10, 0, 8 }, { 10, 13, 7 }, { 10, 7, 12 }, { 10, 12, 7 }, { 10, 7, 13 }, { 10, 15, 3 }, { 10, 12, 1 }, { 10, 6, 14 }, { 10, 2, 15 }, { 10, 15, 5 }, { 10, 15, 4 }, { 10, 1, 14 }, { 10, 9, 11 }, { 10, 4, 15 }, { 10, 14, 7 }, { 10, 8, 13 }, { 10, 13, 9 }, { 10, 8, 12 }, { 10, 5, 15 }, { 10, 3, 15 }, { 10, 10, 11 }, { 10, 11, 10 }, { 10, 12, 8 }, { 10, 15, 6 }, { 10, 15, 7 }, { 10, 8, 14 }, { 10, 15, 1 }, { 10, 7, 14 }, { 10, 9, 0 }, { 10, 0, 9 }, /* 10/11/12 */ { 10, 9, 13 }, { 10, 9, 13 }, { 10, 9, 13 }, { 10, 9, 13 }, { 10, 9, 12 }, { 10, 9, 12 }, { 10, 9, 12 }, { 10, 9, 12 }, { 10, 12, 9 }, { 10, 12, 9 }, { 10, 12, 9 }, { 10, 12, 9 }, { 10, 14, 8 }, { 10, 14, 8 }, { 10, 14, 8 }, { 10, 14, 8 }, { 10, 10, 13 }, { 10, 10, 13 }, { 10, 10, 13 }, { 10, 10, 13 }, { 10, 14, 9 }, { 10, 14, 9 }, { 10, 14, 9 }, { 10, 14, 9 }, { 10, 12, 10 }, { 10, 12, 10 }, { 10, 12, 10 }, { 10, 12, 10 }, { 10, 6, 15 }, { 10, 6, 15 }, { 10, 6, 15 }, { 10, 6, 15 }, { 10, 7, 15 }, { 10, 7, 15 }, { 10, 7, 15 }, { 10, 7, 15 }, { 11, 9, 14 }, { 11, 9, 14 }, { 11, 15, 8 }, { 11, 15, 8 }, { 11, 11, 11 }, { 11, 11, 11 }, { 11, 11, 14 }, { 11, 11, 14 }, { 11, 1, 15 }, { 11, 1, 15 }, { 11, 10, 12 }, { 11, 10, 12 }, { 11, 10, 14 }, { 11, 10, 14 }, { 11, 13, 11 }, { 11, 13, 11 }, { 11, 13, 10 }, { 11, 13, 10 }, { 11, 11, 13 }, { 11, 11, 13 }, { 11, 11, 12 }, { 11, 11, 12 }, { 11, 8, 15 }, { 11, 8, 15 }, { 11, 14, 11 }, { 11, 14, 11 }, { 11, 13, 12 }, { 11, 13, 12 }, { 11, 12, 13 }, { 11, 12, 13 }, { 11, 15, 9 }, { 11, 15, 9 }, { 11, 14, 10 }, { 11, 14, 10 }, { 11, 10, 0 }, { 11, 10, 0 }, { 11, 12, 11 }, { 11, 12, 11 }, { 11, 9, 15 }, { 11, 9, 15 }, { 11, 0, 10 }, { 11, 0, 10 }, { 11, 12, 12 }, { 11, 12, 12 }, { 11, 11, 0 }, { 11, 11, 0 }, { 11, 12, 14 }, { 11, 12, 14 }, { 11, 10, 15 }, { 11, 10, 15 }, { 11, 13, 13 }, { 11, 13, 13 }, { 11, 0, 13 }, { 11, 0, 13 }, { 11, 14, 12 }, { 11, 14, 12 }, { 11, 15, 10 }, { 11, 15, 10 }, { 11, 15, 11 }, { 11, 15, 11 }, { 11, 11, 15 }, { 11, 11, 15 }, { 11, 14, 13 }, { 11, 14, 13 }, { 11, 13, 0 }, { 11, 13, 0 }, { 11, 0, 11 }, { 11, 0, 11 }, { 11, 13, 14 }, { 11, 13, 14 }, { 11, 15, 12 }, { 11, 15, 12 }, { 11, 15, 13 }, { 11, 15, 13 }, { 11, 12, 15 }, { 11, 12, 15 }, { 11, 14, 0 }, { 11, 14, 0 }, { 11, 14, 14 }, { 11, 14, 14 }, { 11, 13, 15 }, { 11, 13, 15 }, { 11, 12, 0 }, { 11, 12, 0 }, { 11, 14, 15 }, { 11, 14, 15 }, { 12, 0, 14 }, { 12, 0, 12 }, { 12, 15, 14 }, { 12, 15, 0 }, { 12, 0, 15 }, { 12, 15, 15 } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_1.h0000644000175000017500000001364314647725152016627 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_1.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* 2-step huffman table HCB_1 */ /* 1st step: 5 bits * 2^5 = 32 entries * * Used to find offset into 2nd step table and number of extra bits to get */ static const hcb hcb1_1[] = { { /* 00000 */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* 10000 */ 1, 0 }, { /* 10001 */ 2, 0 }, { /* 10010 */ 3, 0 }, { /* 10011 */ 4, 0 }, { /* 10100 */ 5, 0 }, { /* 10101 */ 6, 0 }, { /* 10110 */ 7, 0 }, { /* 10111 */ 8, 0 }, /* 7 bit codewords */ { /* 11000 */ 9, 2 }, { /* 11001 */ 13, 2 }, { /* 11010 */ 17, 2 }, { /* 11011 */ 21, 2 }, { /* 11100 */ 25, 2 }, { /* 11101 */ 29, 2 }, /* 9 bit codewords */ { /* 11110 */ 33, 4 }, /* 9/10/11 bit codewords */ { /* 11111 */ 49, 6 } }; /* 2nd step table * * Gives size of codeword and actual data (x,y,v,w) */ static const hcb_2_quad hcb1_2[] = { /* 1 bit codeword */ { 1, 0, 0, 0, 0 }, /* 5 bit codewords */ { 5, 1, 0, 0, 0 }, { 5, -1, 0, 0, 0 }, { 5, 0, 0, 0, -1 }, { 5, 0, 1, 0, 0 }, { 5, 0, 0, 0, 1 }, { 5, 0, 0, -1, 0 }, { 5, 0, 0, 1, 0 }, { 5, 0, -1, 0, 0 }, /* 7 bit codewords */ /* first 5 bits: 11000 */ { 7, 1, -1, 0, 0 }, { 7, -1, 1, 0, 0 }, { 7, 0, 0, -1, 1 }, { 7, 0, 1, -1, 0 }, /* first 5 bits: 11001 */ { 7, 0, -1, 1, 0 }, { 7, 0, 0, 1, -1 }, { 7, 1, 1, 0, 0 }, { 7, 0, 0, -1, -1 }, /* first 5 bits: 11010 */ { 7, -1, -1, 0, 0 }, { 7, 0, -1, -1, 0 }, { 7, 1, 0, -1, 0 }, { 7, 0, 1, 0, -1 }, /* first 5 bits: 11011 */ { 7, -1, 0, 1, 0 }, { 7, 0, 0, 1, 1 }, { 7, 1, 0, 1, 0 }, { 7, 0, -1, 0, 1 }, /* first 5 bits: 11100 */ { 7, 0, 1, 1, 0 }, { 7, 0, 1, 0, 1 }, { 7, -1, 0, -1, 0 }, { 7, 1, 0, 0, 1 }, /* first 5 bits: 11101 */ { 7, -1, 0, 0, -1 }, { 7, 1, 0, 0, -1 }, { 7, -1, 0, 0, 1 }, { 7, 0, -1, 0, -1 }, /* 9 bit codeword */ /* first 5 bits: 11110 */ { 9, 1, 1, -1, 0 }, { 9, -1, 1, -1, 0 }, { 9, 1, -1, 1, 0 }, { 9, 0, 1, 1, -1 }, { 9, 0, 1, -1, 1 }, { 9, 0, -1, 1, 1 }, { 9, 0, -1, 1, -1 }, { 9, 1, -1, -1, 0 }, { 9, 1, 0, -1, 1 }, { 9, 0, 1, -1, -1 }, { 9, -1, 1, 1, 0 }, { 9, -1, 0, 1, -1 }, { 9, -1, -1, 1, 0 }, { 9, 0, -1, -1, 1 }, { 9, 1, -1, 0, 1 }, { 9, 1, -1, 0, -1 }, /* 9/10/11 bit codewords */ /* first 5 bits: 11111 */ /* 9 bit: reading 11 bits -> 2 too much so 4 entries for each codeword */ { 9, -1, 1, 0, -1 }, { 9, -1, 1, 0, -1 }, { 9, -1, 1, 0, -1 }, { 9, -1, 1, 0, -1 }, { 9, -1, -1, -1, 0 }, { 9, -1, -1, -1, 0 }, { 9, -1, -1, -1, 0 }, { 9, -1, -1, -1, 0 }, { 9, 0, -1, -1, -1 }, { 9, 0, -1, -1, -1 }, { 9, 0, -1, -1, -1 }, { 9, 0, -1, -1, -1 }, { 9, 0, 1, 1, 1 }, { 9, 0, 1, 1, 1 }, { 9, 0, 1, 1, 1 }, { 9, 0, 1, 1, 1 }, { 9, 1, 0, 1, -1 }, { 9, 1, 0, 1, -1 }, { 9, 1, 0, 1, -1 }, { 9, 1, 0, 1, -1 }, { 9, 1, 1, 0, 1 }, { 9, 1, 1, 0, 1 }, { 9, 1, 1, 0, 1 }, { 9, 1, 1, 0, 1 }, { 9, -1, 1, 0, 1 }, { 9, -1, 1, 0, 1 }, { 9, -1, 1, 0, 1 }, { 9, -1, 1, 0, 1 }, { 9, 1, 1, 1, 0 }, { 9, 1, 1, 1, 0 }, { 9, 1, 1, 1, 0 }, { 9, 1, 1, 1, 0 }, /* 10 bit: reading 11 bits -> 1 too much so 2 entries for each codeword */ { 10, -1, -1, 0, 1 }, { 10, -1, -1, 0, 1 }, { 10, -1, 0, -1, -1 }, { 10, -1, 0, -1, -1 }, { 10, 1, 1, 0, -1 }, { 10, 1, 1, 0, -1 }, { 10, 1, 0, -1, -1 }, { 10, 1, 0, -1, -1 }, { 10, -1, 0, -1, 1 }, { 10, -1, 0, -1, 1 }, { 10, -1, -1, 0, -1 }, { 10, -1, -1, 0, -1 }, { 10, -1, 0, 1, 1 }, { 10, -1, 0, 1, 1 }, { 10, 1, 0, 1, 1 }, { 10, 1, 0, 1, 1 }, /* 11 bit */ { 11, 1, -1, 1, -1 }, { 11, -1, 1, -1, 1 }, { 11, -1, 1, 1, -1 }, { 11, 1, -1, -1, 1 }, { 11, 1, 1, 1, 1 }, { 11, -1, -1, 1, 1 }, { 11, 1, 1, -1, -1 }, { 11, -1, -1, 1, -1 }, { 11, -1, -1, -1, -1 }, { 11, 1, 1, -1, 1 }, { 11, 1, -1, 1, 1 }, { 11, -1, 1, 1, 1 }, { 11, -1, 1, -1, -1 }, { 11, -1, -1, -1, 1 }, { 11, 1, -1, -1, -1 }, { 11, 1, 1, 1, -1 } }; xine-lib-1.2/contrib/libfaad/codebook/hcb.h0000644000175000017500000000737714647725152016416 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb.h,v 1.8 2007/11/01 12:34:10 menno Exp $ **/ #ifndef __HCB_H__ #define __HCB_H__ #ifdef __cplusplus extern "C" { #endif /* * Optimal huffman decoding for AAC taken from: * "SELECTING AN OPTIMAL HUFFMAN DECODER FOR AAC" by * VLADIMIR Z. MESAROVIC , RAGHUNATH RAO, MIROSLAV V. DOKIC, and SACHIN DEO * AES paper 5436 * * 2 methods are used for huffman decoding: * - binary search * - 2-step table lookup * * The choice of the "optimal" method is based on the fact that if the * memory size for the Two-step is exorbitantly high then the decision * is Binary search for that codebook. However, for marginally more memory * size, if Twostep outperforms even the best case of Binary then the * decision is Two-step for that codebook. * * The following methods are used for the different tables. * codebook "optimal" method * HCB_1 2-Step * HCB_2 2-Step * HCB_3 Binary * HCB_4 2-Step * HCB_5 Binary * HCB_6 2-Step * HCB_7 Binary * HCB_8 2-Step * HCB_9 Binary * HCB_10 2-Step * HCB_11 2-Step * HCB_SF Binary * */ #define ZERO_HCB 0 #define FIRST_PAIR_HCB 5 #define ESC_HCB 11 #define QUAD_LEN 4 #define PAIR_LEN 2 #define NOISE_HCB 13 #define INTENSITY_HCB2 14 #define INTENSITY_HCB 15 /* 1st step table */ typedef struct { uint8_t offset; uint8_t extra_bits; } hcb; /* 2nd step table with quadruple data */ typedef struct { uint8_t bits; int8_t x; int8_t y; } hcb_2_pair; typedef struct { uint8_t bits; int8_t x; int8_t y; int8_t v; int8_t w; } hcb_2_quad; /* binary search table */ typedef struct { uint8_t is_leaf; int8_t data[4]; } hcb_bin_quad; typedef struct { uint8_t is_leaf; int8_t data[2]; } hcb_bin_pair; static const hcb *hcb_table[]; static const hcb_2_quad *hcb_2_quad_table[]; static const hcb_2_pair *hcb_2_pair_table[]; static const hcb_bin_pair *hcb_bin_table[]; static const uint8_t hcbN[]; static const uint8_t unsigned_cb[]; static const int hcb_2_quad_table_size[]; static const int hcb_2_pair_table_size[]; static const int hcb_bin_table_size[]; #include "codebook/hcb_1.h" #include "codebook/hcb_2.h" #include "codebook/hcb_3.h" #include "codebook/hcb_4.h" #include "codebook/hcb_5.h" #include "codebook/hcb_6.h" #include "codebook/hcb_7.h" #include "codebook/hcb_8.h" #include "codebook/hcb_9.h" #include "codebook/hcb_10.h" #include "codebook/hcb_11.h" #include "codebook/hcb_sf.h" #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/codebook/hcb_5.h0000644000175000017500000001465714647725151016640 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_5.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* Binary search huffman table HCB_5 */ static const hcb_bin_pair hcb5[] = { { /* 0 */ 0, { 1, 2 } }, { /* 1 */ 1, { 0, 0 } }, /* 0 */ { /* 2 */ 0, { 1, 2 } }, { /* 3 */ 0, { 2, 3 } }, { /* 4 */ 0, { 3, 4 } }, { /* 5 */ 0, { 4, 5 } }, { /* 6 */ 0, { 5, 6 } }, { /* 7 */ 0, { 6, 7 } }, { /* 8 */ 0, { 7, 8 } }, { /* 9 */ 1, { -1, 0 } }, /* 1000 */ { /* 10 */ 1, { 1, 0 } }, /* 1001 */ { /* 11 */ 1, { 0, 1 } }, /* 1010 */ { /* 12 */ 1, { 0, -1 } }, /* 1011 */ { /* 13 */ 0, { 4, 5 } }, { /* 14 */ 0, { 5, 6 } }, { /* 15 */ 0, { 6, 7 } }, { /* 16 */ 0, { 7, 8 } }, { /* 17 */ 1, { 1, -1 } }, { /* 18 */ 1, { -1, 1 } }, { /* 19 */ 1, { -1, -1 } }, { /* 20 */ 1, { 1, 1 } }, { /* 21 */ 0, { 4, 5 } }, { /* 22 */ 0, { 5, 6 } }, { /* 23 */ 0, { 6, 7 } }, { /* 24 */ 0, { 7, 8 } }, { /* 25 */ 0, { 8, 9 } }, { /* 26 */ 0, { 9, 10 } }, { /* 27 */ 0, { 10, 11 } }, { /* 28 */ 0, { 11, 12 } }, { /* 29 */ 0, { 12, 13 } }, { /* 30 */ 0, { 13, 14 } }, { /* 31 */ 0, { 14, 15 } }, { /* 32 */ 0, { 15, 16 } }, { /* 33 */ 1, { -2, 0 } }, { /* 34 */ 1, { 0, 2 } }, { /* 35 */ 1, { 2, 0 } }, { /* 36 */ 1, { 0, -2 } }, { /* 37 */ 0, { 12, 13 } }, { /* 38 */ 0, { 13, 14 } }, { /* 39 */ 0, { 14, 15 } }, { /* 40 */ 0, { 15, 16 } }, { /* 41 */ 0, { 16, 17 } }, { /* 42 */ 0, { 17, 18 } }, { /* 43 */ 0, { 18, 19 } }, { /* 44 */ 0, { 19, 20 } }, { /* 45 */ 0, { 20, 21 } }, { /* 46 */ 0, { 21, 22 } }, { /* 47 */ 0, { 22, 23 } }, { /* 48 */ 0, { 23, 24 } }, { /* 49 */ 1, { -2, -1 } }, { /* 50 */ 1, { 2, 1 } }, { /* 51 */ 1, { -1, -2 } }, { /* 52 */ 1, { 1, 2 } }, { /* 53 */ 1, { -2, 1 } }, { /* 54 */ 1, { 2, -1 } }, { /* 55 */ 1, { -1, 2 } }, { /* 56 */ 1, { 1, -2 } }, { /* 57 */ 1, { -3, 0 } }, { /* 58 */ 1, { 3, 0 } }, { /* 59 */ 1, { 0, -3 } }, { /* 60 */ 1, { 0, 3 } }, { /* 61 */ 0, { 12, 13 } }, { /* 62 */ 0, { 13, 14 } }, { /* 63 */ 0, { 14, 15 } }, { /* 64 */ 0, { 15, 16 } }, { /* 65 */ 0, { 16, 17 } }, { /* 66 */ 0, { 17, 18 } }, { /* 67 */ 0, { 18, 19 } }, { /* 68 */ 0, { 19, 20 } }, { /* 69 */ 0, { 20, 21 } }, { /* 70 */ 0, { 21, 22 } }, { /* 71 */ 0, { 22, 23 } }, { /* 72 */ 0, { 23, 24 } }, { /* 73 */ 1, { -3, -1 } }, { /* 74 */ 1, { 1, 3 } }, { /* 75 */ 1, { 3, 1 } }, { /* 76 */ 1, { -1, -3 } }, { /* 77 */ 1, { -3, 1 } }, { /* 78 */ 1, { 3, -1 } }, { /* 79 */ 1, { 1, -3 } }, { /* 80 */ 1, { -1, 3 } }, { /* 81 */ 1, { -2, 2 } }, { /* 82 */ 1, { 2, 2 } }, { /* 83 */ 1, { -2, -2 } }, { /* 84 */ 1, { 2, -2 } }, { /* 85 */ 0, { 12, 13 } }, { /* 86 */ 0, { 13, 14 } }, { /* 87 */ 0, { 14, 15 } }, { /* 88 */ 0, { 15, 16 } }, { /* 89 */ 0, { 16, 17 } }, { /* 90 */ 0, { 17, 18 } }, { /* 91 */ 0, { 18, 19 } }, { /* 92 */ 0, { 19, 20 } }, { /* 93 */ 0, { 20, 21 } }, { /* 94 */ 0, { 21, 22 } }, { /* 95 */ 0, { 22, 23 } }, { /* 96 */ 0, { 23, 24 } }, { /* 97 */ 1, { -3, -2 } }, { /* 98 */ 1, { 3, -2 } }, { /* 99 */ 1, { -2, 3 } }, { /* 00 */ 1, { 2, -3 } }, { /* 01 */ 1, { 3, 2 } }, { /* 02 */ 1, { 2, 3 } }, { /* 03 */ 1, { -3, 2 } }, { /* 04 */ 1, { -2, -3 } }, { /* 05 */ 1, { 0, -4 } }, { /* 06 */ 1, { -4, 0 } }, { /* 07 */ 1, { 4, 1 } }, { /* 08 */ 1, { 4, 0 } }, { /* 09 */ 0, { 12, 13 } }, { /* 10 */ 0, { 13, 14 } }, { /* 11 */ 0, { 14, 15 } }, { /* 12 */ 0, { 15, 16 } }, { /* 13 */ 0, { 16, 17 } }, { /* 14 */ 0, { 17, 18 } }, { /* 15 */ 0, { 18, 19 } }, { /* 16 */ 0, { 19, 20 } }, { /* 17 */ 0, { 20, 21 } }, { /* 18 */ 0, { 21, 22 } }, { /* 19 */ 0, { 22, 23 } }, { /* 20 */ 0, { 23, 24 } }, { /* 21 */ 1, { -4, -1 } }, { /* 22 */ 1, { 0, 4 } }, { /* 23 */ 1, { 4, -1 } }, { /* 24 */ 1, { -1, -4 } }, { /* 25 */ 1, { 1, 4 } }, { /* 26 */ 1, { -1, 4 } }, { /* 27 */ 1, { -4, 1 } }, { /* 28 */ 1, { 1, -4 } }, { /* 29 */ 1, { 3, -3 } }, { /* 30 */ 1, { -3, -3 } }, { /* 31 */ 1, { -3, 3 } }, { /* 32 */ 1, { -2, 4 } }, { /* 33 */ 1, { -4, -2 } }, { /* 34 */ 1, { 4, 2 } }, { /* 35 */ 1, { 2, -4 } }, { /* 36 */ 1, { 2, 4 } }, { /* 37 */ 1, { 3, 3 } }, { /* 38 */ 1, { -4, 2 } }, { /* 39 */ 0, { 6, 7 } }, { /* 40 */ 0, { 7, 8 } }, { /* 41 */ 0, { 8, 9 } }, { /* 42 */ 0, { 9, 10 } }, { /* 43 */ 0, { 10, 11 } }, { /* 44 */ 0, { 11, 12 } }, { /* 45 */ 1, { -2, -4 } }, { /* 46 */ 1, { 4, -2 } }, { /* 47 */ 1, { 3, -4 } }, { /* 48 */ 1, { -4, -3 } }, { /* 49 */ 1, { -4, 3 } }, { /* 50 */ 1, { 3, 4 } }, { /* 51 */ 1, { -3, 4 } }, { /* 52 */ 1, { 4, 3 } }, { /* 53 */ 1, { 4, -3 } }, { /* 54 */ 1, { -3, -4 } }, { /* 55 */ 0, { 2, 3 } }, { /* 56 */ 0, { 3, 4 } }, { /* 57 */ 1, { 4, -4 } }, { /* 58 */ 1, { -4, 4 } }, { /* 59 */ 1, { 4, 4 } }, { /* 60 */ 1, { -4, -4 } } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_7.h0000644000175000017500000001233214647725152016627 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_7.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* Binary search huffman table HCB_7 */ static const hcb_bin_pair hcb7[] = { { /* 0 */ 0, { 1, 2 } }, { /* 1 */ 1, { 0, 0 } }, { /* 2 */ 0, { 1, 2 } }, { /* 3 */ 0, { 2, 3 } }, { /* 4 */ 0, { 3, 4 } }, { /* 5 */ 1, { 1, 0 } }, { /* 6 */ 1, { 0, 1 } }, { /* 7 */ 0, { 2, 3 } }, { /* 8 */ 0, { 3, 4 } }, { /* 9 */ 1, { 1, 1 } }, { /* 10 */ 0, { 3, 4 } }, { /* 11 */ 0, { 4, 5 } }, { /* 12 */ 0, { 5, 6 } }, { /* 13 */ 0, { 6, 7 } }, { /* 14 */ 0, { 7, 8 } }, { /* 15 */ 0, { 8, 9 } }, { /* 16 */ 0, { 9, 10 } }, { /* 17 */ 0, { 10, 11 } }, { /* 18 */ 0, { 11, 12 } }, { /* 19 */ 1, { 2, 1 } }, { /* 20 */ 1, { 1, 2 } }, { /* 21 */ 1, { 2, 0 } }, { /* 22 */ 1, { 0, 2 } }, { /* 23 */ 0, { 8, 9 } }, { /* 24 */ 0, { 9, 10 } }, { /* 25 */ 0, { 10, 11 } }, { /* 26 */ 0, { 11, 12 } }, { /* 27 */ 0, { 12, 13 } }, { /* 28 */ 0, { 13, 14 } }, { /* 29 */ 0, { 14, 15 } }, { /* 30 */ 0, { 15, 16 } }, { /* 31 */ 1, { 3, 1 } }, { /* 32 */ 1, { 1, 3 } }, { /* 33 */ 1, { 2, 2 } }, { /* 34 */ 1, { 3, 0 } }, { /* 35 */ 1, { 0, 3 } }, { /* 36 */ 0, { 11, 12 } }, { /* 37 */ 0, { 12, 13 } }, { /* 38 */ 0, { 13, 14 } }, { /* 39 */ 0, { 14, 15 } }, { /* 40 */ 0, { 15, 16 } }, { /* 41 */ 0, { 16, 17 } }, { /* 42 */ 0, { 17, 18 } }, { /* 43 */ 0, { 18, 19 } }, { /* 44 */ 0, { 19, 20 } }, { /* 45 */ 0, { 20, 21 } }, { /* 46 */ 0, { 21, 22 } }, { /* 47 */ 1, { 2, 3 } }, { /* 48 */ 1, { 3, 2 } }, { /* 49 */ 1, { 1, 4 } }, { /* 50 */ 1, { 4, 1 } }, { /* 51 */ 1, { 1, 5 } }, { /* 52 */ 1, { 5, 1 } }, { /* 53 */ 1, { 3, 3 } }, { /* 54 */ 1, { 2, 4 } }, { /* 55 */ 1, { 0, 4 } }, { /* 56 */ 1, { 4, 0 } }, { /* 57 */ 0, { 12, 13 } }, { /* 58 */ 0, { 13, 14 } }, { /* 59 */ 0, { 14, 15 } }, { /* 60 */ 0, { 15, 16 } }, { /* 61 */ 0, { 16, 17 } }, { /* 62 */ 0, { 17, 18 } }, { /* 63 */ 0, { 18, 19 } }, { /* 64 */ 0, { 19, 20 } }, { /* 65 */ 0, { 20, 21 } }, { /* 66 */ 0, { 21, 22 } }, { /* 67 */ 0, { 22, 23 } }, { /* 68 */ 0, { 23, 24 } }, { /* 69 */ 1, { 4, 2 } }, { /* 70 */ 1, { 2, 5 } }, { /* 71 */ 1, { 5, 2 } }, { /* 72 */ 1, { 0, 5 } }, { /* 73 */ 1, { 6, 1 } }, { /* 74 */ 1, { 5, 0 } }, { /* 75 */ 1, { 1, 6 } }, { /* 76 */ 1, { 4, 3 } }, { /* 77 */ 1, { 3, 5 } }, { /* 78 */ 1, { 3, 4 } }, { /* 79 */ 1, { 5, 3 } }, { /* 80 */ 1, { 2, 6 } }, { /* 81 */ 1, { 6, 2 } }, { /* 82 */ 1, { 1, 7 } }, { /* 83 */ 0, { 10, 11 } }, { /* 84 */ 0, { 11, 12 } }, { /* 85 */ 0, { 12, 13 } }, { /* 86 */ 0, { 13, 14 } }, { /* 87 */ 0, { 14, 15 } }, { /* 88 */ 0, { 15, 16 } }, { /* 89 */ 0, { 16, 17 } }, { /* 90 */ 0, { 17, 18 } }, { /* 91 */ 0, { 18, 19 } }, { /* 92 */ 0, { 19, 20 } }, { /* 93 */ 1, { 3, 6 } }, { /* 94 */ 1, { 0, 6 } }, { /* 95 */ 1, { 6, 0 } }, { /* 96 */ 1, { 4, 4 } }, { /* 97 */ 1, { 7, 1 } }, { /* 98 */ 1, { 4, 5 } }, { /* 99 */ 1, { 7, 2 } }, { /* 00 */ 1, { 5, 4 } }, { /* 01 */ 1, { 6, 3 } }, { /* 02 */ 1, { 2, 7 } }, { /* 03 */ 1, { 7, 3 } }, { /* 04 */ 1, { 6, 4 } }, { /* 05 */ 1, { 5, 5 } }, { /* 06 */ 1, { 4, 6 } }, { /* 07 */ 1, { 3, 7 } }, { /* 08 */ 0, { 5, 6 } }, { /* 09 */ 0, { 6, 7 } }, { /* 10 */ 0, { 7, 8 } }, { /* 11 */ 0, { 8, 9 } }, { /* 12 */ 0, { 9, 10 } }, { /* 13 */ 1, { 7, 0 } }, { /* 14 */ 1, { 0, 7 } }, { /* 15 */ 1, { 6, 5 } }, { /* 16 */ 1, { 5, 6 } }, { /* 17 */ 1, { 7, 4 } }, { /* 18 */ 1, { 4, 7 } }, { /* 19 */ 1, { 5, 7 } }, { /* 20 */ 1, { 7, 5 } }, { /* 21 */ 0, { 2, 3 } }, { /* 22 */ 0, { 3, 4 } }, { /* 23 */ 1, { 7, 6 } }, { /* 24 */ 1, { 6, 6 } }, { /* 25 */ 1, { 6, 7 } }, { /* 26 */ 1, { 7, 7 } } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_4.h0000644000175000017500000001715314647725152016632 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_4.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* 2-step huffman table HCB_4 */ /* 1st step: 5 bits * 2^5 = 32 entries * * Used to find offset into 2nd step table and number of extra bits to get */ static const hcb hcb4_1[] = { /* 4 bit codewords */ { /* 00000 */ 0, 0 }, { /* */ 0, 0 }, { /* 00010 */ 1, 0 }, { /* */ 1, 0 }, { /* 00100 */ 2, 0 }, { /* */ 2, 0 }, { /* 00110 */ 3, 0 }, { /* */ 3, 0 }, { /* 01000 */ 4, 0 }, { /* */ 4, 0 }, { /* 01010 */ 5, 0 }, { /* */ 5, 0 }, { /* 01100 */ 6, 0 }, { /* */ 6, 0 }, { /* 01110 */ 7, 0 }, { /* */ 7, 0 }, { /* 10000 */ 8, 0 }, { /* */ 8, 0 }, { /* 10010 */ 9, 0 }, { /* */ 9, 0 }, /* 5 bit codewords */ { /* 10100 */ 10, 0 }, { /* 10101 */ 11, 0 }, { /* 10110 */ 12, 0 }, { /* 10111 */ 13, 0 }, { /* 11000 */ 14, 0 }, { /* 11001 */ 15, 0 }, /* 7 bit codewords */ { /* 11010 */ 16, 2 }, { /* 11011 */ 20, 2 }, /* 7/8 bit codewords */ { /* 11100 */ 24, 3 }, /* 8 bit codewords */ { /* 11101 */ 32, 3 }, /* 8/9 bit codewords */ { /* 11110 */ 40, 4 }, /* 9/10/11/12 bit codewords */ { /* 11111 */ 56, 7 } }; /* 2nd step table * * Gives size of codeword and actual data (x,y,v,w) */ static const hcb_2_quad hcb4_2[] = { /* 4 bit codewords */ { 4, 1, 1, 1, 1 }, { 4, 0, 1, 1, 1 }, { 4, 1, 1, 0, 1 }, { 4, 1, 1, 1, 0 }, { 4, 1, 0, 1, 1 }, { 4, 1, 0, 0, 0 }, { 4, 1, 1, 0, 0 }, { 4, 0, 0, 0, 0 }, { 4, 0, 0, 1, 1 }, { 4, 1, 0, 1, 0 }, /* 5 bit codewords */ { 5, 1, 0, 0, 1 }, { 5, 0, 1, 1, 0 }, { 5, 0, 0, 0, 1 }, { 5, 0, 1, 0, 1 }, { 5, 0, 0, 1, 0 }, { 5, 0, 1, 0, 0 }, /* 7 bit codewords */ /* first 5 bits: 11010 */ { 7, 2, 1, 1, 1 }, { 7, 1, 1, 2, 1 }, { 7, 1, 2, 1, 1 }, { 7, 1, 1, 1, 2 }, /* first 5 bits: 11011 */ { 7, 2, 1, 1, 0 }, { 7, 2, 1, 0, 1 }, { 7, 1, 2, 1, 0 }, { 7, 2, 0, 1, 1 }, /* 7/8 bit codewords */ /* first 5 bits: 11100 */ { 7, 0, 1, 2, 1 }, { 7, 0, 1, 2, 1 }, { 8, 0, 1, 1, 2 }, { 8, 1, 1, 2, 0 }, { 8, 0, 2, 1, 1 }, { 8, 1, 0, 1, 2 }, { 8, 1, 2, 0, 1 }, { 8, 1, 1, 0, 2 }, /* 8 bit codewords */ { 8, 1, 0, 2, 1 }, { 8, 2, 1, 0, 0 }, { 8, 2, 0, 1, 0 }, { 8, 1, 2, 0, 0 }, { 8, 2, 0, 0, 1 }, { 8, 0, 1, 0, 2 }, { 8, 0, 2, 1, 0 }, { 8, 0, 0, 1, 2 }, /* 8/9 bit codewords */ { 8, 0, 1, 2, 0 }, { 8, 0, 1, 2, 0 }, { 8, 0, 2, 0, 1 }, { 8, 0, 2, 0, 1 }, { 8, 1, 0, 0, 2 }, { 8, 1, 0, 0, 2 }, { 8, 0, 0, 2, 1 }, { 8, 0, 0, 2, 1 }, { 8, 1, 0, 2, 0 }, { 8, 1, 0, 2, 0 }, { 8, 2, 0, 0, 0 }, { 8, 2, 0, 0, 0 }, { 8, 0, 0, 0, 2 }, { 8, 0, 0, 0, 2 }, { 9, 0, 2, 0, 0 }, { 9, 0, 0, 2, 0 }, /* 9/10/11 bit codewords */ /* 9 bit codewords repeated 2^3 = 8 times */ { 9, 1, 2, 2, 1 }, { 9, 1, 2, 2, 1 }, { 9, 1, 2, 2, 1 }, { 9, 1, 2, 2, 1 }, { 9, 1, 2, 2, 1 }, { 9, 1, 2, 2, 1 }, { 9, 1, 2, 2, 1 }, { 9, 1, 2, 2, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 2, 1, 1 }, { 9, 2, 1, 2, 1 }, { 9, 2, 1, 2, 1 }, { 9, 2, 1, 2, 1 }, { 9, 2, 1, 2, 1 }, { 9, 2, 1, 2, 1 }, { 9, 2, 1, 2, 1 }, { 9, 2, 1, 2, 1 }, { 9, 2, 1, 2, 1 }, { 9, 1, 1, 2, 2 }, { 9, 1, 1, 2, 2 }, { 9, 1, 1, 2, 2 }, { 9, 1, 1, 2, 2 }, { 9, 1, 1, 2, 2 }, { 9, 1, 1, 2, 2 }, { 9, 1, 1, 2, 2 }, { 9, 1, 1, 2, 2 }, { 9, 1, 2, 1, 2 }, { 9, 1, 2, 1, 2 }, { 9, 1, 2, 1, 2 }, { 9, 1, 2, 1, 2 }, { 9, 1, 2, 1, 2 }, { 9, 1, 2, 1, 2 }, { 9, 1, 2, 1, 2 }, { 9, 1, 2, 1, 2 }, { 9, 2, 1, 1, 2 }, { 9, 2, 1, 1, 2 }, { 9, 2, 1, 1, 2 }, { 9, 2, 1, 1, 2 }, { 9, 2, 1, 1, 2 }, { 9, 2, 1, 1, 2 }, { 9, 2, 1, 1, 2 }, { 9, 2, 1, 1, 2 }, /* 10 bit codewords repeated 2^2 = 4 times */ { 10, 1, 2, 2, 0 }, { 10, 1, 2, 2, 0 }, { 10, 1, 2, 2, 0 }, { 10, 1, 2, 2, 0 }, { 10, 2, 2, 1, 0 }, { 10, 2, 2, 1, 0 }, { 10, 2, 2, 1, 0 }, { 10, 2, 2, 1, 0 }, { 10, 2, 1, 2, 0 }, { 10, 2, 1, 2, 0 }, { 10, 2, 1, 2, 0 }, { 10, 2, 1, 2, 0 }, { 10, 0, 2, 2, 1 }, { 10, 0, 2, 2, 1 }, { 10, 0, 2, 2, 1 }, { 10, 0, 2, 2, 1 }, { 10, 0, 1, 2, 2 }, { 10, 0, 1, 2, 2 }, { 10, 0, 1, 2, 2 }, { 10, 0, 1, 2, 2 }, { 10, 2, 2, 0, 1 }, { 10, 2, 2, 0, 1 }, { 10, 2, 2, 0, 1 }, { 10, 2, 2, 0, 1 }, { 10, 0, 2, 1, 2 }, { 10, 0, 2, 1, 2 }, { 10, 0, 2, 1, 2 }, { 10, 0, 2, 1, 2 }, { 10, 2, 0, 2, 1 }, { 10, 2, 0, 2, 1 }, { 10, 2, 0, 2, 1 }, { 10, 2, 0, 2, 1 }, { 10, 1, 0, 2, 2 }, { 10, 1, 0, 2, 2 }, { 10, 1, 0, 2, 2 }, { 10, 1, 0, 2, 2 }, { 10, 2, 2, 2, 1 }, { 10, 2, 2, 2, 1 }, { 10, 2, 2, 2, 1 }, { 10, 2, 2, 2, 1 }, { 10, 1, 2, 0, 2 }, { 10, 1, 2, 0, 2 }, { 10, 1, 2, 0, 2 }, { 10, 1, 2, 0, 2 }, { 10, 2, 0, 1, 2 }, { 10, 2, 0, 1, 2 }, { 10, 2, 0, 1, 2 }, { 10, 2, 0, 1, 2 }, { 10, 2, 1, 0, 2 }, { 10, 2, 1, 0, 2 }, { 10, 2, 1, 0, 2 }, { 10, 2, 1, 0, 2 }, { 10, 1, 2, 2, 2 }, { 10, 1, 2, 2, 2 }, { 10, 1, 2, 2, 2 }, { 10, 1, 2, 2, 2 }, /* 11 bit codewords repeated 2^1 = 2 times */ { 11, 2, 1, 2, 2 }, { 11, 2, 1, 2, 2 }, { 11, 2, 2, 1, 2 }, { 11, 2, 2, 1, 2 }, { 11, 0, 2, 2, 0 }, { 11, 0, 2, 2, 0 }, { 11, 2, 2, 0, 0 }, { 11, 2, 2, 0, 0 }, { 11, 0, 0, 2, 2 }, { 11, 0, 0, 2, 2 }, { 11, 2, 0, 2, 0 }, { 11, 2, 0, 2, 0 }, { 11, 0, 2, 0, 2 }, { 11, 0, 2, 0, 2 }, { 11, 2, 0, 0, 2 }, { 11, 2, 0, 0, 2 }, { 11, 2, 2, 2, 2 }, { 11, 2, 2, 2, 2 }, { 11, 0, 2, 2, 2 }, { 11, 0, 2, 2, 2 }, { 11, 2, 2, 2, 0 }, { 11, 2, 2, 2, 0 }, /* 12 bit codewords */ { 12, 2, 2, 0, 2 }, { 12, 2, 0, 2, 2 }, }; xine-lib-1.2/contrib/libfaad/codebook/hcb_sf.h0000644000175000017500000001646514647725152017104 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_sf.h,v 1.7 2007/11/01 12:34:11 menno Exp $ **/ /* Binary search huffman table HCB_SF */ static const uint8_t hcb_sf[][2] = { { /* 0 */ 1, 2 }, { /* 1 */ 60, 0 }, { /* 2 */ 1, 2 }, { /* 3 */ 2, 3 }, { /* 4 */ 3, 4 }, { /* 5 */ 59, 0 }, { /* 6 */ 3, 4 }, { /* 7 */ 4, 5 }, { /* 8 */ 5, 6 }, { /* 9 */ 61, 0 }, { /* 10 */ 58, 0 }, { /* 11 */ 62, 0 }, { /* 12 */ 3, 4 }, { /* 13 */ 4, 5 }, { /* 14 */ 5, 6 }, { /* 15 */ 57, 0 }, { /* 16 */ 63, 0 }, { /* 17 */ 4, 5 }, { /* 18 */ 5, 6 }, { /* 19 */ 6, 7 }, { /* 20 */ 7, 8 }, { /* 21 */ 56, 0 }, { /* 22 */ 64, 0 }, { /* 23 */ 55, 0 }, { /* 24 */ 65, 0 }, { /* 25 */ 4, 5 }, { /* 26 */ 5, 6 }, { /* 27 */ 6, 7 }, { /* 28 */ 7, 8 }, { /* 29 */ 66, 0 }, { /* 30 */ 54, 0 }, { /* 31 */ 67, 0 }, { /* 32 */ 5, 6 }, { /* 33 */ 6, 7 }, { /* 34 */ 7, 8 }, { /* 35 */ 8, 9 }, { /* 36 */ 9, 10 }, { /* 37 */ 53, 0 }, { /* 38 */ 68, 0 }, { /* 39 */ 52, 0 }, { /* 40 */ 69, 0 }, { /* 41 */ 51, 0 }, { /* 42 */ 5, 6 }, { /* 43 */ 6, 7 }, { /* 44 */ 7, 8 }, { /* 45 */ 8, 9 }, { /* 46 */ 9, 10 }, { /* 47 */ 70, 0 }, { /* 48 */ 50, 0 }, { /* 49 */ 49, 0 }, { /* 50 */ 71, 0 }, { /* 51 */ 6, 7 }, { /* 52 */ 7, 8 }, { /* 53 */ 8, 9 }, { /* 54 */ 9, 10 }, { /* 55 */ 10, 11 }, { /* 56 */ 11, 12 }, { /* 57 */ 72, 0 }, { /* 58 */ 48, 0 }, { /* 59 */ 73, 0 }, { /* 60 */ 47, 0 }, { /* 61 */ 74, 0 }, { /* 62 */ 46, 0 }, { /* 63 */ 6, 7 }, { /* 64 */ 7, 8 }, { /* 65 */ 8, 9 }, { /* 66 */ 9, 10 }, { /* 67 */ 10, 11 }, { /* 68 */ 11, 12 }, { /* 69 */ 76, 0 }, { /* 70 */ 75, 0 }, { /* 71 */ 77, 0 }, { /* 72 */ 78, 0 }, { /* 73 */ 45, 0 }, { /* 74 */ 43, 0 }, { /* 75 */ 6, 7 }, { /* 76 */ 7, 8 }, { /* 77 */ 8, 9 }, { /* 78 */ 9, 10 }, { /* 79 */ 10, 11 }, { /* 80 */ 11, 12 }, { /* 81 */ 44, 0 }, { /* 82 */ 79, 0 }, { /* 83 */ 42, 0 }, { /* 84 */ 41, 0 }, { /* 85 */ 80, 0 }, { /* 86 */ 40, 0 }, { /* 87 */ 6, 7 }, { /* 88 */ 7, 8 }, { /* 89 */ 8, 9 }, { /* 90 */ 9, 10 }, { /* 91 */ 10, 11 }, { /* 92 */ 11, 12 }, { /* 93 */ 81, 0 }, { /* 94 */ 39, 0 }, { /* 95 */ 82, 0 }, { /* 96 */ 38, 0 }, { /* 97 */ 83, 0 }, { /* 98 */ 7, 8 }, { /* 99 */ 8, 9 }, { /* 00 */ 9, 10 }, { /* 01 */ 10, 11 }, { /* 02 */ 11, 12 }, { /* 03 */ 12, 13 }, { /* 04 */ 13, 14 }, { /* 05 */ 37, 0 }, { /* 06 */ 35, 0 }, { /* 07 */ 85, 0 }, { /* 08 */ 33, 0 }, { /* 09 */ 36, 0 }, { /* 10 */ 34, 0 }, { /* 11 */ 84, 0 }, { /* 12 */ 32, 0 }, { /* 13 */ 6, 7 }, { /* 14 */ 7, 8 }, { /* 15 */ 8, 9 }, { /* 16 */ 9, 10 }, { /* 17 */ 10, 11 }, { /* 18 */ 11, 12 }, { /* 19 */ 87, 0 }, { /* 20 */ 89, 0 }, { /* 21 */ 30, 0 }, { /* 22 */ 31, 0 }, { /* 23 */ 8, 9 }, { /* 24 */ 9, 10 }, { /* 25 */ 10, 11 }, { /* 26 */ 11, 12 }, { /* 27 */ 12, 13 }, { /* 28 */ 13, 14 }, { /* 29 */ 14, 15 }, { /* 30 */ 15, 16 }, { /* 31 */ 86, 0 }, { /* 32 */ 29, 0 }, { /* 33 */ 26, 0 }, { /* 34 */ 27, 0 }, { /* 35 */ 28, 0 }, { /* 36 */ 24, 0 }, { /* 37 */ 88, 0 }, { /* 38 */ 9, 10 }, { /* 39 */ 10, 11 }, { /* 40 */ 11, 12 }, { /* 41 */ 12, 13 }, { /* 42 */ 13, 14 }, { /* 43 */ 14, 15 }, { /* 44 */ 15, 16 }, { /* 45 */ 16, 17 }, { /* 46 */ 17, 18 }, { /* 47 */ 25, 0 }, { /* 48 */ 22, 0 }, { /* 49 */ 23, 0 }, { /* 50 */ 15, 16 }, { /* 51 */ 16, 17 }, { /* 52 */ 17, 18 }, { /* 53 */ 18, 19 }, { /* 54 */ 19, 20 }, { /* 55 */ 20, 21 }, { /* 56 */ 21, 22 }, { /* 57 */ 22, 23 }, { /* 58 */ 23, 24 }, { /* 59 */ 24, 25 }, { /* 60 */ 25, 26 }, { /* 61 */ 26, 27 }, { /* 62 */ 27, 28 }, { /* 63 */ 28, 29 }, { /* 64 */ 29, 30 }, { /* 65 */ 90, 0 }, { /* 66 */ 21, 0 }, { /* 67 */ 19, 0 }, { /* 68 */ 3, 0 }, { /* 69 */ 1, 0 }, { /* 70 */ 2, 0 }, { /* 71 */ 0, 0 }, { /* 72 */ 23, 24 }, { /* 73 */ 24, 25 }, { /* 74 */ 25, 26 }, { /* 75 */ 26, 27 }, { /* 76 */ 27, 28 }, { /* 77 */ 28, 29 }, { /* 78 */ 29, 30 }, { /* 79 */ 30, 31 }, { /* 80 */ 31, 32 }, { /* 81 */ 32, 33 }, { /* 82 */ 33, 34 }, { /* 83 */ 34, 35 }, { /* 84 */ 35, 36 }, { /* 85 */ 36, 37 }, { /* 86 */ 37, 38 }, { /* 87 */ 38, 39 }, { /* 88 */ 39, 40 }, { /* 89 */ 40, 41 }, { /* 90 */ 41, 42 }, { /* 91 */ 42, 43 }, { /* 92 */ 43, 44 }, { /* 93 */ 44, 45 }, { /* 94 */ 45, 46 }, { /* 95 */ 98, 0 }, { /* 96 */ 99, 0 }, { /* 97 */ 100, 0 }, { /* 98 */ 101, 0 }, { /* 99 */ 102, 0 }, { /* 00 */ 117, 0 }, { /* 01 */ 97, 0 }, { /* 02 */ 91, 0 }, { /* 03 */ 92, 0 }, { /* 04 */ 93, 0 }, { /* 05 */ 94, 0 }, { /* 06 */ 95, 0 }, { /* 07 */ 96, 0 }, { /* 08 */ 104, 0 }, { /* 09 */ 111, 0 }, { /* 10 */ 112, 0 }, { /* 11 */ 113, 0 }, { /* 12 */ 114, 0 }, { /* 13 */ 115, 0 }, { /* 14 */ 116, 0 }, { /* 15 */ 110, 0 }, { /* 16 */ 105, 0 }, { /* 17 */ 106, 0 }, { /* 18 */ 107, 0 }, { /* 19 */ 108, 0 }, { /* 20 */ 109, 0 }, { /* 21 */ 118, 0 }, { /* 22 */ 6, 0 }, { /* 23 */ 8, 0 }, { /* 24 */ 9, 0 }, { /* 25 */ 10, 0 }, { /* 26 */ 5, 0 }, { /* 27 */ 103, 0 }, { /* 28 */ 120, 0 }, { /* 29 */ 119, 0 }, { /* 30 */ 4, 0 }, { /* 31 */ 7, 0 }, { /* 32 */ 15, 0 }, { /* 33 */ 16, 0 }, { /* 34 */ 18, 0 }, { /* 35 */ 20, 0 }, { /* 36 */ 17, 0 }, { /* 37 */ 11, 0 }, { /* 38 */ 12, 0 }, { /* 39 */ 14, 0 }, { /* 40 */ 13, 0 } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_6.h0000644000175000017500000001163514647725152016633 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_6.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* 2-step huffman table HCB_6 */ /* 1st step: 5 bits * 2^5 = 32 entries * * Used to find offset into 2nd step table and number of extra bits to get */ static const hcb hcb6_1[] = { /* 4 bit codewords */ { /* 00000 */ 0, 0 }, { /* */ 0, 0 }, { /* 00010 */ 1, 0 }, { /* */ 1, 0 }, { /* 00100 */ 2, 0 }, { /* */ 2, 0 }, { /* 00110 */ 3, 0 }, { /* */ 3, 0 }, { /* 01000 */ 4, 0 }, { /* */ 4, 0 }, { /* 01010 */ 5, 0 }, { /* */ 5, 0 }, { /* 01100 */ 6, 0 }, { /* */ 6, 0 }, { /* 01110 */ 7, 0 }, { /* */ 7, 0 }, { /* 10000 */ 8, 0 }, { /* */ 8, 0 }, /* 6 bit codewords */ { /* 10010 */ 9, 1 }, { /* 10011 */ 11, 1 }, { /* 10100 */ 13, 1 }, { /* 10101 */ 15, 1 }, { /* 10110 */ 17, 1 }, { /* 10111 */ 19, 1 }, { /* 11000 */ 21, 1 }, { /* 11001 */ 23, 1 }, /* 7 bit codewords */ { /* 11010 */ 25, 2 }, { /* 11011 */ 29, 2 }, { /* 11100 */ 33, 2 }, /* 7/8 bit codewords */ { /* 11101 */ 37, 3 }, /* 8/9 bit codewords */ { /* 11110 */ 45, 4 }, /* 9/10/11 bit codewords */ { /* 11111 */ 61, 6 } }; /* 2nd step table * * Gives size of codeword and actual data (x,y,v,w) */ static const hcb_2_pair hcb6_2[] = { /* 4 bit codewords */ { 4, 0, 0 }, { 4, 1, 0 }, { 4, 0, -1 }, { 4, 0, 1 }, { 4, -1, 0 }, { 4, 1, 1 }, { 4, -1, 1 }, { 4, 1, -1 }, { 4, -1, -1 }, /* 6 bit codewords */ { 6, 2, -1 }, { 6, 2, 1 }, { 6, -2, 1 }, { 6, -2, -1 }, { 6, -2, 0 }, { 6, -1, 2 }, { 6, 2, 0 }, { 6, 1, -2 }, { 6, 1, 2 }, { 6, 0, -2 }, { 6, -1, -2 }, { 6, 0, 2 }, { 6, 2, -2 }, { 6, -2, 2 }, { 6, -2, -2 }, { 6, 2, 2 }, /* 7 bit codewords */ { 7, -3, 1 }, { 7, 3, 1 }, { 7, 3, -1 }, { 7, -1, 3 }, { 7, -3, -1 }, { 7, 1, 3 }, { 7, 1, -3 }, { 7, -1, -3 }, { 7, 3, 0 }, { 7, -3, 0 }, { 7, 0, -3 }, { 7, 0, 3 }, /* 7/8 bit codewords */ { 7, 3, 2 }, { 7, 3, 2 }, { 8, -3, -2 }, { 8, -2, 3 }, { 8, 2, 3 }, { 8, 3, -2 }, { 8, 2, -3 }, { 8, -2, -3 }, /* 8 bit codewords */ { 8, -3, 2 }, { 8, -3, 2 }, { 8, 3, 3 }, { 8, 3, 3 }, { 9, 3, -3 }, { 9, -3, -3 }, { 9, -3, 3 }, { 9, 1, -4 }, { 9, -1, -4 }, { 9, 4, 1 }, { 9, -4, 1 }, { 9, -4, -1 }, { 9, 1, 4 }, { 9, 4, -1 }, { 9, -1, 4 }, { 9, 0, -4 }, /* 9/10/11 bit codewords */ { 9, -4, 2 }, { 9, -4, 2 }, { 9, -4, 2 }, { 9, -4, 2 }, { 9, -4, -2 }, { 9, -4, -2 }, { 9, -4, -2 }, { 9, -4, -2 }, { 9, 2, 4 }, { 9, 2, 4 }, { 9, 2, 4 }, { 9, 2, 4 }, { 9, -2, -4 }, { 9, -2, -4 }, { 9, -2, -4 }, { 9, -2, -4 }, { 9, -4, 0 }, { 9, -4, 0 }, { 9, -4, 0 }, { 9, -4, 0 }, { 9, 4, 2 }, { 9, 4, 2 }, { 9, 4, 2 }, { 9, 4, 2 }, { 9, 4, -2 }, { 9, 4, -2 }, { 9, 4, -2 }, { 9, 4, -2 }, { 9, -2, 4 }, { 9, -2, 4 }, { 9, -2, 4 }, { 9, -2, 4 }, { 9, 4, 0 }, { 9, 4, 0 }, { 9, 4, 0 }, { 9, 4, 0 }, { 9, 2, -4 }, { 9, 2, -4 }, { 9, 2, -4 }, { 9, 2, -4 }, { 9, 0, 4 }, { 9, 0, 4 }, { 9, 0, 4 }, { 9, 0, 4 }, { 10, -3, -4 }, { 10, -3, -4 }, { 10, -3, 4 }, { 10, -3, 4 }, { 10, 3, -4 }, { 10, 3, -4 }, { 10, 4, -3 }, { 10, 4, -3 }, { 10, 3, 4 }, { 10, 3, 4 }, { 10, 4, 3 }, { 10, 4, 3 }, { 10, -4, 3 }, { 10, -4, 3 }, { 10, -4, -3 }, { 10, -4, -3 }, { 11, 4, 4 }, { 11, -4, 4 }, { 11, -4, -4 }, { 11, 4, -4 } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_10.h0000644000175000017500000001735314647725152016711 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_10.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* 2-step huffman table HCB_10 */ /* 1st step: 6 bits * 2^6 = 64 entries * * Used to find offset into 2nd step table and number of extra bits to get */ static const hcb hcb10_1[] = { /* 4 bit codewords */ { /* 000000 */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* 000100 */ 1, 0 }, { /* */ 1, 0 }, { /* */ 1, 0 }, { /* */ 1, 0 }, { /* 001000 */ 2, 0 }, { /* */ 2, 0 }, { /* */ 2, 0 }, { /* */ 2, 0 }, /* 5 bit codewords */ { /* 001100 */ 3, 0 }, { /* */ 3, 0 }, { /* 001110 */ 4, 0 }, { /* */ 4, 0 }, { /* 010000 */ 5, 0 }, { /* */ 5, 0 }, { /* 010010 */ 6, 0 }, { /* */ 6, 0 }, { /* 010100 */ 7, 0 }, { /* */ 7, 0 }, { /* 010110 */ 8, 0 }, { /* */ 8, 0 }, { /* 011000 */ 9, 0 }, { /* */ 9, 0 }, { /* 011010 */ 10, 0 }, { /* */ 10, 0 }, /* 6 bit codewords */ { /* 011100 */ 11, 0 }, { /* 011101 */ 12, 0 }, { /* 011110 */ 13, 0 }, { /* 011111 */ 14, 0 }, { /* 100000 */ 15, 0 }, { /* 100001 */ 16, 0 }, { /* 100010 */ 17, 0 }, { /* 100011 */ 18, 0 }, { /* 100100 */ 19, 0 }, { /* 100101 */ 20, 0 }, { /* 100110 */ 21, 0 }, { /* 100111 */ 22, 0 }, { /* 101000 */ 23, 0 }, { /* 101001 */ 24, 0 }, /* 7 bit codewords */ { /* 101010 */ 25, 1 }, { /* 101011 */ 27, 1 }, { /* 101100 */ 29, 1 }, { /* 101101 */ 31, 1 }, { /* 101110 */ 33, 1 }, { /* 101111 */ 35, 1 }, { /* 110000 */ 37, 1 }, { /* 110001 */ 39, 1 }, /* 7/8 bit codewords */ { /* 110010 */ 41, 2 }, /* 8 bit codewords */ { /* 110011 */ 45, 2 }, { /* 110100 */ 49, 2 }, { /* 110101 */ 53, 2 }, { /* 110110 */ 57, 2 }, { /* 110111 */ 61, 2 }, /* 8/9 bit codewords */ { /* 111000 */ 65, 3 }, /* 9 bit codewords */ { /* 111001 */ 73, 3 }, { /* 111010 */ 81, 3 }, { /* 111011 */ 89, 3 }, /* 9/10 bit codewords */ { /* 111100 */ 97, 4 }, /* 10 bit codewords */ { /* 111101 */ 113, 4 }, { /* 111110 */ 129, 4 }, /* 10/11/12 bit codewords */ { /* 111111 */ 145, 6 } }; /* 2nd step table * * Gives size of codeword and actual data (x,y,v,w) */ static const hcb_2_pair hcb10_2[] = { /* 4 bit codewords */ { 4, 1, 1 }, { 4, 1, 2 }, { 4, 2, 1 }, /* 5 bit codewords */ { 5, 2, 2 }, { 5, 1, 0 }, { 5, 0, 1 }, { 5, 1, 3 }, { 5, 3, 2 }, { 5, 3, 1 }, { 5, 2, 3 }, { 5, 3, 3 }, /* 6 bit codewords */ { 6, 2, 0 }, { 6, 0, 2 }, { 6, 2, 4 }, { 6, 4, 2 }, { 6, 1, 4 }, { 6, 4, 1 }, { 6, 0, 0 }, { 6, 4, 3 }, { 6, 3, 4 }, { 6, 3, 0 }, { 6, 0, 3 }, { 6, 4, 4 }, { 6, 2, 5 }, { 6, 5, 2 }, /* 7 bit codewords */ { 7, 1, 5 }, { 7, 5, 1 }, { 7, 5, 3 }, { 7, 3, 5 }, { 7, 5, 4 }, { 7, 4, 5 }, { 7, 6, 2 }, { 7, 2, 6 }, { 7, 6, 3 }, { 7, 4, 0 }, { 7, 6, 1 }, { 7, 0, 4 }, { 7, 1, 6 }, { 7, 3, 6 }, { 7, 5, 5 }, { 7, 6, 4 }, /* 7/8 bit codewords */ { 7, 4, 6 }, { 7, 4, 6 }, { 8, 6, 5 }, { 8, 7, 2 }, /* 8 bit codewords */ { 8, 3, 7 }, { 8, 2, 7 }, { 8, 5, 6 }, { 8, 8, 2 }, { 8, 7, 3 }, { 8, 5, 0 }, { 8, 7, 1 }, { 8, 0, 5 }, { 8, 8, 1 }, { 8, 1, 7 }, { 8, 8, 3 }, { 8, 7, 4 }, { 8, 4, 7 }, { 8, 2, 8 }, { 8, 6, 6 }, { 8, 7, 5 }, { 8, 1, 8 }, { 8, 3, 8 }, { 8, 8, 4 }, { 8, 4, 8 }, /* 8/9 bit codewords */ { 8, 5, 7 }, { 8, 5, 7 }, { 8, 8, 5 }, { 8, 8, 5 }, { 8, 5, 8 }, { 8, 5, 8 }, { 9, 7, 6 }, { 9, 6, 7 }, /* 9 bit codewords */ { 9, 9, 2 }, { 9, 6, 0 }, { 9, 6, 8 }, { 9, 9, 3 }, { 9, 3, 9 }, { 9, 9, 1 }, { 9, 2, 9 }, { 9, 0, 6 }, { 9, 8, 6 }, { 9, 9, 4 }, { 9, 4, 9 }, { 9, 10, 2 }, { 9, 1, 9 }, { 9, 7, 7 }, { 9, 8, 7 }, { 9, 9, 5 }, { 9, 7, 8 }, { 9, 10, 3 }, { 9, 5, 9 }, { 9, 10, 4 }, { 9, 2, 10 }, { 9, 10, 1 }, { 9, 3, 10 }, { 9, 9, 6 }, /* 9/10 bit codewords */ { 9, 6, 9 }, { 9, 6, 9 }, { 9, 8, 0 }, { 9, 8, 0 }, { 9, 4, 10 }, { 9, 4, 10 }, { 9, 7, 0 }, { 9, 7, 0 }, { 9, 11, 2 }, { 9, 11, 2 }, { 10, 7, 9 }, { 10, 11, 3 }, { 10, 10, 6 }, { 10, 1, 10 }, { 10, 11, 1 }, { 10, 9, 7 }, /* 10 bit codewords */ { 10, 0, 7 }, { 10, 8, 8 }, { 10, 10, 5 }, { 10, 3, 11 }, { 10, 5, 10 }, { 10, 8, 9 }, { 10, 11, 5 }, { 10, 0, 8 }, { 10, 11, 4 }, { 10, 2, 11 }, { 10, 7, 10 }, { 10, 6, 10 }, { 10, 10, 7 }, { 10, 4, 11 }, { 10, 1, 11 }, { 10, 12, 2 }, { 10, 9, 8 }, { 10, 12, 3 }, { 10, 11, 6 }, { 10, 5, 11 }, { 10, 12, 4 }, { 10, 11, 7 }, { 10, 12, 5 }, { 10, 3, 12 }, { 10, 6, 11 }, { 10, 9, 0 }, { 10, 10, 8 }, { 10, 10, 0 }, { 10, 12, 1 }, { 10, 0, 9 }, { 10, 4, 12 }, { 10, 9, 9 }, /* 10/11/12 bit codewords */ { 10, 12, 6 }, { 10, 12, 6 }, { 10, 12, 6 }, { 10, 12, 6 }, { 10, 2, 12 }, { 10, 2, 12 }, { 10, 2, 12 }, { 10, 2, 12 }, { 10, 8, 10 }, { 10, 8, 10 }, { 10, 8, 10 }, { 10, 8, 10 }, { 11, 9, 10 }, { 11, 9, 10 }, { 11, 1, 12 }, { 11, 1, 12 }, { 11, 11, 8 }, { 11, 11, 8 }, { 11, 12, 7 }, { 11, 12, 7 }, { 11, 7, 11 }, { 11, 7, 11 }, { 11, 5, 12 }, { 11, 5, 12 }, { 11, 6, 12 }, { 11, 6, 12 }, { 11, 10, 9 }, { 11, 10, 9 }, { 11, 8, 11 }, { 11, 8, 11 }, { 11, 12, 8 }, { 11, 12, 8 }, { 11, 0, 10 }, { 11, 0, 10 }, { 11, 7, 12 }, { 11, 7, 12 }, { 11, 11, 0 }, { 11, 11, 0 }, { 11, 10, 10 }, { 11, 10, 10 }, { 11, 11, 9 }, { 11, 11, 9 }, { 11, 11, 10 }, { 11, 11, 10 }, { 11, 0, 11 }, { 11, 0, 11 }, { 11, 11, 11 }, { 11, 11, 11 }, { 11, 9, 11 }, { 11, 9, 11 }, { 11, 10, 11 }, { 11, 10, 11 }, { 11, 12, 0 }, { 11, 12, 0 }, { 11, 8, 12 }, { 11, 8, 12 }, { 12, 12, 9 }, { 12, 10, 12 }, { 12, 9, 12 }, { 12, 11, 12 }, { 12, 12, 11 }, { 12, 0, 12 }, { 12, 12, 10 }, { 12, 12, 12 } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_3.h0000644000175000017500000002074414647725152016631 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_3.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* Binary search huffman table HCB_3 */ static const hcb_bin_quad hcb3[] = { { /* 0 */ 0, { 1, 2, 0, 0 } }, { /* 1 */ 1, { 0, 0, 0, 0 } }, /* 0 */ { /* 2 */ 0, { 1, 2, 0, 0 } }, { /* 3 */ 0, { 2, 3, 0, 0 } }, { /* 4 */ 0, { 3, 4, 0, 0 } }, { /* 5 */ 0, { 4, 5, 0, 0 } }, { /* 6 */ 0, { 5, 6, 0, 0 } }, { /* 7 */ 0, { 6, 7, 0, 0 } }, { /* 8 */ 0, { 7, 8, 0, 0 } }, { /* 9 */ 1, { 1, 0, 0, 0 } }, /* 1000 */ { /* 10 */ 1, { 0, 0, 0, 1 } }, /* 1001 */ { /* 11 */ 1, { 0, 1, 0, 0 } }, /* 1010 */ { /* 12 */ 1, { 0, 0, 1, 0 } }, /* 1011 */ { /* 13 */ 0, { 4, 5, 0, 0 } }, { /* 14 */ 0, { 5, 6, 0, 0 } }, { /* 15 */ 0, { 6, 7, 0, 0 } }, { /* 16 */ 0, { 7, 8, 0, 0 } }, { /* 17 */ 1, { 1, 1, 0, 0 } }, { /* 18 */ 1, { 0, 0, 1, 1 } }, { /* 19 */ 0, { 6, 7, 0, 0 } }, { /* 20 */ 0, { 7, 8, 0, 0 } }, { /* 21 */ 0, { 8, 9, 0, 0 } }, { /* 22 */ 0, { 9, 10, 0, 0 } }, { /* 23 */ 0, { 10, 11, 0, 0 } }, { /* 24 */ 0, { 11, 12, 0, 0 } }, { /* 25 */ 1, { 0, 1, 1, 0 } }, /* 110100 */ { /* 26 */ 1, { 0, 1, 0, 1 } }, /* 110101 */ { /* 27 */ 1, { 1, 0, 1, 0 } }, /* 110110 */ { /* 28 */ 1, { 0, 1, 1, 1 } }, /* 110111 */ { /* 29 */ 1, { 1, 0, 0, 1 } }, /* 111000 */ { /* 30 */ 1, { 1, 1, 1, 0 } }, /* 111001 */ { /* 31 */ 0, { 6, 7, 0, 0 } }, { /* 32 */ 0, { 7, 8, 0, 0 } }, { /* 33 */ 0, { 8, 9, 0, 0 } }, { /* 34 */ 0, { 9, 10, 0, 0 } }, { /* 35 */ 0, { 10, 11, 0, 0 } }, { /* 36 */ 0, { 11, 12, 0, 0 } }, { /* 37 */ 1, { 1, 1, 1, 1 } }, /* 1110100 */ { /* 38 */ 1, { 1, 0, 1, 1 } }, /* 1110101 */ { /* 39 */ 1, { 1, 1, 0, 1 } }, /* 1110110 */ { /* 40 */ 0, { 9, 10, 0, 0 } }, { /* 41 */ 0, { 10, 11, 0, 0 } }, { /* 42 */ 0, { 11, 12, 0, 0 } }, { /* 43 */ 0, { 12, 13, 0, 0 } }, { /* 44 */ 0, { 13, 14, 0, 0 } }, { /* 45 */ 0, { 14, 15, 0, 0 } }, { /* 46 */ 0, { 15, 16, 0, 0 } }, { /* 47 */ 0, { 16, 17, 0, 0 } }, { /* 48 */ 0, { 17, 18, 0, 0 } }, { /* 49 */ 1, { 2, 0, 0, 0 } }, /* 11101110 */ { /* 50 */ 1, { 0, 0, 0, 2 } }, /* 11101111 */ { /* 51 */ 1, { 0, 0, 1, 2 } }, /* 11110000 */ { /* 52 */ 1, { 2, 1, 0, 0 } }, /* 11110001 */ { /* 53 */ 1, { 1, 2, 1, 0 } }, /* 11110010 */ { /* 54 */ 0, { 13, 14, 0, 0 } }, { /* 55 */ 0, { 14, 15, 0, 0 } }, { /* 56 */ 0, { 15, 16, 0, 0 } }, { /* 57 */ 0, { 16, 17, 0, 0 } }, { /* 58 */ 0, { 17, 18, 0, 0 } }, { /* 59 */ 0, { 18, 19, 0, 0 } }, { /* 60 */ 0, { 19, 20, 0, 0 } }, { /* 61 */ 0, { 20, 21, 0, 0 } }, { /* 62 */ 0, { 21, 22, 0, 0 } }, { /* 63 */ 0, { 22, 23, 0, 0 } }, { /* 64 */ 0, { 23, 24, 0, 0 } }, { /* 65 */ 0, { 24, 25, 0, 0 } }, { /* 66 */ 0, { 25, 26, 0, 0 } }, { /* 67 */ 1, { 0, 0, 2, 1 } }, { /* 68 */ 1, { 0, 1, 2, 1 } }, { /* 69 */ 1, { 1, 2, 0, 0 } }, { /* 70 */ 1, { 0, 1, 1, 2 } }, { /* 71 */ 1, { 2, 1, 1, 0 } }, { /* 72 */ 1, { 0, 0, 2, 0 } }, { /* 73 */ 1, { 0, 2, 1, 0 } }, { /* 74 */ 1, { 0, 1, 2, 0 } }, { /* 75 */ 1, { 0, 2, 0, 0 } }, { /* 76 */ 1, { 0, 1, 0, 2 } }, { /* 77 */ 1, { 2, 0, 1, 0 } }, { /* 78 */ 1, { 1, 2, 1, 1 } }, { /* 79 */ 1, { 0, 2, 1, 1 } }, { /* 80 */ 1, { 1, 1, 2, 0 } }, { /* 81 */ 1, { 1, 1, 2, 1 } }, { /* 82 */ 0, { 11, 12, 0, 0 } }, { /* 83 */ 0, { 12, 13, 0, 0 } }, { /* 84 */ 0, { 13, 14, 0, 0 } }, { /* 85 */ 0, { 14, 15, 0, 0 } }, { /* 86 */ 0, { 15, 16, 0, 0 } }, { /* 87 */ 0, { 16, 17, 0, 0 } }, { /* 88 */ 0, { 17, 18, 0, 0 } }, { /* 89 */ 0, { 18, 19, 0, 0 } }, { /* 90 */ 0, { 19, 20, 0, 0 } }, { /* 91 */ 0, { 20, 21, 0, 0 } }, { /* 92 */ 0, { 21, 22, 0, 0 } }, { /* 93 */ 1, { 1, 2, 0, 1 } }, /* 1111101010 */ { /* 94 */ 1, { 1, 0, 2, 0 } }, /* 1111101011 */ { /* 95 */ 1, { 1, 0, 2, 1 } }, /* 1111101100 */ { /* 96 */ 1, { 0, 2, 0, 1 } }, /* 1111101101 */ { /* 97 */ 1, { 2, 1, 1, 1 } }, /* 1111101110 */ { /* 98 */ 1, { 1, 1, 1, 2 } }, /* 1111101111 */ { /* 99 */ 1, { 2, 1, 0, 1 } }, /* 1111110000 */ { /* 00 */ 1, { 1, 0, 1, 2 } }, /* 1111110001 */ { /* 01 */ 1, { 0, 0, 2, 2 } }, /* 1111110010 */ { /* 02 */ 1, { 0, 1, 2, 2 } }, /* 1111110011 */ { /* 03 */ 1, { 2, 2, 1, 0 } }, /* 1111110100 */ { /* 04 */ 1, { 1, 2, 2, 0 } }, /* 1111110101 */ { /* 05 */ 1, { 1, 0, 0, 2 } }, /* 1111110110 */ { /* 06 */ 1, { 2, 0, 0, 1 } }, /* 1111110111 */ { /* 07 */ 1, { 0, 2, 2, 1 } }, /* 1111111000 */ { /* 08 */ 0, { 7, 8, 0, 0 } }, { /* 09 */ 0, { 8, 9, 0, 0 } }, { /* 10 */ 0, { 9, 10, 0, 0 } }, { /* 11 */ 0, { 10, 11, 0, 0 } }, { /* 12 */ 0, { 11, 12, 0, 0 } }, { /* 13 */ 0, { 12, 13, 0, 0 } }, { /* 14 */ 0, { 13, 14, 0, 0 } }, { /* 15 */ 1, { 2, 2, 0, 0 } }, /* 11111110010 */ { /* 16 */ 1, { 1, 2, 2, 1 } }, /* 11111110011 */ { /* 17 */ 1, { 1, 1, 0, 2 } }, /* 11111110100 */ { /* 18 */ 1, { 2, 0, 1, 1 } }, /* 11111110101 */ { /* 19 */ 1, { 1, 1, 2, 2 } }, /* 11111110110 */ { /* 20 */ 1, { 2, 2, 1, 1 } }, /* 11111110111 */ { /* 21 */ 1, { 0, 2, 2, 0 } }, /* 11111111000 */ { /* 22 */ 1, { 0, 2, 1, 2 } }, /* 11111111001 */ { /* 23 */ 0, { 6, 7, 0, 0 } }, { /* 24 */ 0, { 7, 8, 0, 0 } }, { /* 25 */ 0, { 8, 9, 0, 0 } }, { /* 26 */ 0, { 9, 10, 0, 0 } }, { /* 27 */ 0, { 10, 11, 0, 0 } }, { /* 28 */ 0, { 11, 12, 0, 0 } }, { /* 29 */ 1, { 1, 0, 2, 2 } }, /* 111111110100 */ { /* 30 */ 1, { 2, 2, 0, 1 } }, /* 111111110101 */ { /* 31 */ 1, { 2, 1, 2, 0 } }, /* 111111110110 */ { /* 32 */ 1, { 2, 2, 2, 0 } }, /* 111111110111 */ { /* 33 */ 1, { 0, 2, 2, 2 } }, /* 111111111000 */ { /* 34 */ 1, { 2, 2, 2, 1 } }, /* 111111111001 */ { /* 35 */ 1, { 2, 1, 2, 1 } }, /* 111111111010 */ { /* 36 */ 1, { 1, 2, 1, 2 } }, /* 111111111011 */ { /* 37 */ 1, { 1, 2, 2, 2 } }, /* 111111111100 */ { /* 38 */ 0, { 3, 4, 0, 0 } }, { /* 39 */ 0, { 4, 5, 0, 0 } }, { /* 40 */ 0, { 5, 6, 0, 0 } }, { /* 41 */ 1, { 0, 2, 0, 2 } }, /* 1111111111010 */ { /* 42 */ 1, { 2, 0, 2, 0 } }, /* 1111111111011 */ { /* 43 */ 1, { 1, 2, 0, 2 } }, /* 1111111111100 */ { /* 44 */ 0, { 3, 4, 0, 0 } }, { /* 45 */ 0, { 4, 5, 0, 0 } }, { /* 46 */ 0, { 5, 6, 0, 0 } }, { /* 47 */ 1, { 2, 0, 2, 1 } }, /* 11111111111010 */ { /* 48 */ 1, { 2, 1, 1, 2 } }, /* 11111111111011 */ { /* 49 */ 1, { 2, 1, 0, 2 } }, /* 11111111111100 */ { /* 50 */ 0, { 3, 4, 0, 0 } }, { /* 51 */ 0, { 4, 5, 0, 0 } }, { /* 52 */ 0, { 5, 6, 0, 0 } }, { /* 53 */ 1, { 2, 2, 2, 2 } }, /* 111111111111010 */ { /* 54 */ 1, { 2, 2, 1, 2 } }, /* 111111111111011 */ { /* 55 */ 1, { 2, 1, 2, 2 } }, /* 111111111111100 */ { /* 56 */ 1, { 2, 0, 1, 2 } }, /* 111111111111101 */ { /* 57 */ 1, { 2, 0, 0, 2 } }, /* 111111111111110 */ { /* 58 */ 0, { 1, 2, 0, 0 } }, { /* 59 */ 1, { 2, 2, 0, 2 } }, /* 1111111111111110 */ { /* 60 */ 1, { 2, 0, 2, 2 } } /* 1111111111111111 */ }; xine-lib-1.2/contrib/libfaad/codebook/hcb_2.h0000644000175000017500000001175714647725152016634 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_2.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* 2-step huffman table HCB_2 */ /* 1st step: 5 bits * 2^5 = 32 entries * * Used to find offset into 2nd step table and number of extra bits to get */ static const hcb hcb2_1[] = { { /* 00000 */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* 00100 */ 1, 0 }, { /* */ 1, 0 }, { /* 00110 */ 2, 0 }, { /* 00111 */ 3, 0 }, { /* 01000 */ 4, 0 }, { /* 01001 */ 5, 0 }, { /* 01010 */ 6, 0 }, { /* 01011 */ 7, 0 }, { /* 01100 */ 8, 0 }, /* 6 bit codewords */ { /* 01101 */ 9, 1 }, { /* 01110 */ 11, 1 }, { /* 01111 */ 13, 1 }, { /* 10000 */ 15, 1 }, { /* 10001 */ 17, 1 }, { /* 10010 */ 19, 1 }, { /* 10011 */ 21, 1 }, { /* 10100 */ 23, 1 }, { /* 10101 */ 25, 1 }, { /* 10110 */ 27, 1 }, { /* 10111 */ 29, 1 }, { /* 11000 */ 31, 1 }, /* 7 bit codewords */ { /* 11001 */ 33, 2 }, { /* 11010 */ 37, 2 }, { /* 11011 */ 41, 2 }, /* 7/8 bit codewords */ { /* 11100 */ 45, 3 }, /* 8 bit codewords */ { /* 11101 */ 53, 3 }, { /* 11110 */ 61, 3 }, /* 8/9 bit codewords */ { /* 11111 */ 69, 4 } }; /* 2nd step table * * Gives size of codeword and actual data (x,y,v,w) */ static const hcb_2_quad hcb2_2[] = { /* 3 bit codeword */ { 3, 0, 0, 0, 0 }, /* 4 bit codeword */ { 4, 1, 0, 0, 0 }, /* 5 bit codewords */ { 5, -1, 0, 0, 0 }, { 5, 0, 0, 0, 1 }, { 5, 0, 0, -1, 0 }, { 5, 0, 0, 0, -1 }, { 5, 0, -1, 0, 0 }, { 5, 0, 0, 1, 0 }, { 5, 0, 1, 0, 0 }, /* 6 bit codewords */ { 6, 0, -1, 1, 0 }, { 6, -1, 1, 0, 0 }, { 6, 0, 1, -1, 0 }, { 6, 0, 0, 1, -1 }, { 6, 0, 1, 0, -1 }, { 6, 0, 0, -1, 1 }, { 6, -1, 0, 0, -1 }, { 6, 1, -1, 0, 0 }, { 6, 1, 0, -1, 0 }, { 6, -1, -1, 0, 0 }, { 6, 0, 0, -1, -1 }, { 6, 1, 0, 1, 0 }, { 6, 1, 0, 0, 1 }, { 6, 0, -1, 0, 1 }, { 6, -1, 0, 1, 0 }, { 6, 0, 1, 0, 1 }, { 6, 0, -1, -1, 0 }, { 6, -1, 0, 0, 1 }, { 6, 0, -1, 0, -1 }, { 6, -1, 0, -1, 0 }, { 6, 1, 1, 0, 0 }, { 6, 0, 1, 1, 0 }, { 6, 0, 0, 1, 1 }, { 6, 1, 0, 0, -1 }, /* 7 bit codewords */ { 7, 0, 1, -1, 1 }, { 7, 1, 0, -1, 1 }, { 7, -1, 1, -1, 0 }, { 7, 0, -1, 1, -1 }, { 7, 1, -1, 1, 0 }, { 7, 1, 1, 0, -1 }, { 7, 1, 0, 1, 1 }, { 7, -1, 1, 1, 0 }, { 7, 0, -1, -1, 1 }, { 7, 1, 1, 1, 0 }, { 7, -1, 0, 1, -1 }, { 7, -1, -1, -1, 0 }, /* 7/8 bit codewords */ { 7, -1, 0, -1, 1 }, { 7, -1, 0, -1, 1 }, { 7, 1, -1, -1, 0 }, { 7, 1, -1, -1, 0 }, { 7, 1, 1, -1, 0 }, { 7, 1, 1, -1, 0 }, { 8, 1, -1, 0, 1 }, { 8, -1, 1, 0, -1 }, /* 8 bit codewords */ { 8, -1, -1, 1, 0 }, { 8, -1, 0, 1, 1 }, { 8, -1, -1, 0, 1 }, { 8, -1, -1, 0, -1 }, { 8, 0, -1, -1, -1 }, { 8, 1, 0, 1, -1 }, { 8, 1, 0, -1, -1 }, { 8, 0, 1, -1, -1 }, { 8, 0, 1, 1, 1 }, { 8, -1, 1, 0, 1 }, { 8, -1, 0, -1, -1 }, { 8, 0, 1, 1, -1 }, { 8, 1, -1, 0, -1 }, { 8, 0, -1, 1, 1 }, { 8, 1, 1, 0, 1 }, { 8, 1, -1, 1, -1 }, /* 8/9 bit codewords */ { 8, -1, 1, -1, 1 }, { 8, -1, 1, -1, 1 }, { 9, 1, -1, -1, 1 }, { 9, -1, -1, -1, -1 }, { 9, -1, 1, 1, -1 }, { 9, -1, 1, 1, 1 }, { 9, 1, 1, 1, 1 }, { 9, -1, -1, 1, -1 }, { 9, 1, -1, 1, 1 }, { 9, -1, 1, -1, -1 }, { 9, -1, -1, 1, 1 }, { 9, 1, 1, -1, -1 }, { 9, 1, -1, -1, -1 }, { 9, -1, -1, -1, 1 }, { 9, 1, 1, -1, 1 }, { 9, 1, 1, 1, -1 } }; xine-lib-1.2/contrib/libfaad/codebook/hcb_8.h0000644000175000017500000001047214647725152016633 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: hcb_8.h,v 1.5 2007/11/01 12:34:11 menno Exp $ **/ /* 2-step huffman table HCB_8 */ /* 1st step: 5 bits * 2^5 = 32 entries * * Used to find offset into 2nd step table and number of extra bits to get */ static const hcb hcb8_1[] = { /* 3 bit codeword */ { /* 00000 */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, { /* */ 0, 0 }, /* 4 bit codewords */ { /* 00100 */ 1, 0 }, { /* */ 1, 0 }, { /* 00110 */ 2, 0 }, { /* */ 2, 0 }, { /* 01000 */ 3, 0 }, { /* */ 3, 0 }, { /* 01010 */ 4, 0 }, { /* */ 4, 0 }, { /* 01100 */ 5, 0 }, { /* */ 5, 0 }, /* 5 bit codewords */ { /* 01110 */ 6, 0 }, { /* 01111 */ 7, 0 }, { /* 10000 */ 8, 0 }, { /* 10001 */ 9, 0 }, { /* 10010 */ 10, 0 }, { /* 10011 */ 11, 0 }, { /* 10100 */ 12, 0 }, /* 6 bit codewords */ { /* 10101 */ 13, 1 }, { /* 10110 */ 15, 1 }, { /* 10111 */ 17, 1 }, { /* 11000 */ 19, 1 }, { /* 11001 */ 21, 1 }, /* 7 bit codewords */ { /* 11010 */ 23, 2 }, { /* 11011 */ 27, 2 }, { /* 11100 */ 31, 2 }, /* 7/8 bit codewords */ { /* 11101 */ 35, 3 }, /* 8 bit codewords */ { /* 11110 */ 43, 3 }, /* 8/9/10 bit codewords */ { /* 11111 */ 51, 5 } }; /* 2nd step table * * Gives size of codeword and actual data (x,y,v,w) */ static const hcb_2_pair hcb8_2[] = { /* 3 bit codeword */ { 3, 1, 1 }, /* 4 bit codewords */ { 4, 2, 1 }, { 4, 1, 0 }, { 4, 1, 2 }, { 4, 0, 1 }, { 4, 2, 2 }, /* 5 bit codewords */ { 5, 0, 0 }, { 5, 2, 0 }, { 5, 0, 2 }, { 5, 3, 1 }, { 5, 1, 3 }, { 5, 3, 2 }, { 5, 2, 3 }, /* 6 bit codewords */ { 6, 3, 3 }, { 6, 4, 1 }, { 6, 1, 4 }, { 6, 4, 2 }, { 6, 2, 4 }, { 6, 3, 0 }, { 6, 0, 3 }, { 6, 4, 3 }, { 6, 3, 4 }, { 6, 5, 2 }, /* 7 bit codewords */ { 7, 5, 1 }, { 7, 2, 5 }, { 7, 1, 5 }, { 7, 5, 3 }, { 7, 3, 5 }, { 7, 4, 4 }, { 7, 5, 4 }, { 7, 0, 4 }, { 7, 4, 5 }, { 7, 4, 0 }, { 7, 2, 6 }, { 7, 6, 2 }, /* 7/8 bit codewords */ { 7, 6, 1 }, { 7, 6, 1 }, { 7, 1, 6 }, { 7, 1, 6 }, { 8, 3, 6 }, { 8, 6, 3 }, { 8, 5, 5 }, { 8, 5, 0 }, /* 8 bit codewords */ { 8, 6, 4 }, { 8, 0, 5 }, { 8, 4, 6 }, { 8, 7, 1 }, { 8, 7, 2 }, { 8, 2, 7 }, { 8, 6, 5 }, { 8, 7, 3 }, /* 8/9/10 bit codewords */ { 8, 1, 7 }, { 8, 1, 7 }, { 8, 1, 7 }, { 8, 1, 7 }, { 8, 5, 6 }, { 8, 5, 6 }, { 8, 5, 6 }, { 8, 5, 6 }, { 8, 3, 7 }, { 8, 3, 7 }, { 8, 3, 7 }, { 8, 3, 7 }, { 9, 6, 6 }, { 9, 6, 6 }, { 9, 7, 4 }, { 9, 7, 4 }, { 9, 6, 0 }, { 9, 6, 0 }, { 9, 4, 7 }, { 9, 4, 7 }, { 9, 0, 6 }, { 9, 0, 6 }, { 9, 7, 5 }, { 9, 7, 5 }, { 9, 7, 6 }, { 9, 7, 6 }, { 9, 6, 7 }, { 9, 6, 7 }, { 10, 5, 7 }, { 10, 7, 0 }, { 10, 0, 7 }, { 10, 7, 7 } }; xine-lib-1.2/contrib/libfaad/pns.c0000644000175000017500000002142714647725152014660 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: pns.c,v 1.38 2007/11/01 12:33:32 menno Exp $ **/ #include "common.h" #include "structs.h" #include "pns.h" /* static function declarations */ static void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size, uint8_t sub, /* RNG states */ uint32_t *__r1, uint32_t *__r2); #ifdef FIXED_POINT #define DIV(A, B) (((int64_t)A << REAL_BITS)/B) #define step(shift) \ if ((0x40000000l >> shift) + root <= value) \ { \ value -= (0x40000000l >> shift) + root; \ root = (root >> 1) | (0x40000000l >> shift); \ } else { \ root = root >> 1; \ } /* fixed point square root approximation */ /* !!!! ONLY WORKS FOR EVEN %REAL_BITS% !!!! */ real_t fp_sqrt(real_t value) { real_t root = 0; step( 0); step( 2); step( 4); step( 6); step( 8); step(10); step(12); step(14); step(16); step(18); step(20); step(22); step(24); step(26); step(28); step(30); if (root < value) ++root; root <<= (REAL_BITS/2); return root; } static real_t const pow2_table[] = { COEF_CONST(1.0), COEF_CONST(1.18920711500272), COEF_CONST(1.41421356237310), COEF_CONST(1.68179283050743) }; #endif /* The function gen_rand_vector(addr, size) generates a vector of length with signed random values of average energy MEAN_NRG per random value. A suitable random number generator can be realized using one multiplication/accumulation per random value. */ static INLINE void gen_rand_vector(real_t *spec, int16_t scale_factor, uint16_t size, uint8_t sub, /* RNG states */ uint32_t *__r1, uint32_t *__r2) { #ifndef FIXED_POINT uint16_t i; real_t energy = 0.0; real_t scale = (real_t)1.0/(real_t)size; (void)sub; for (i = 0; i < size; i++) { real_t tmp = scale*(real_t)(int32_t)ne_rng(__r1, __r2); spec[i] = tmp; energy += tmp*tmp; } scale = (real_t)1.0/(real_t)sqrt(energy); scale *= (real_t)pow(2.0, 0.25 * scale_factor); for (i = 0; i < size; i++) { spec[i] *= scale; } #else uint16_t i; real_t energy = 0, scale; int32_t exp, frac; for (i = 0; i < size; i++) { /* this can be replaced by a 16 bit random generator!!!! */ real_t tmp = (int32_t)ne_rng(__r1, __r2); if (tmp < 0) tmp = -(tmp & ((1<<(REAL_BITS-1))-1)); else tmp = (tmp & ((1<<(REAL_BITS-1))-1)); energy += MUL_R(tmp,tmp); spec[i] = tmp; } energy = fp_sqrt(energy); if (energy > 0) { scale = DIV(REAL_CONST(1),energy); exp = scale_factor >> 2; frac = scale_factor & 3; /* IMDCT pre-scaling */ exp -= sub; if (exp < 0) scale >>= -exp; else scale <<= exp; if (frac) scale = MUL_C(scale, pow2_table[frac]); for (i = 0; i < size; i++) { spec[i] = MUL_R(spec[i], scale); } } #endif } void pns_decode(ic_stream *ics_left, ic_stream *ics_right, real_t *spec_left, real_t *spec_right, uint16_t frame_len, uint8_t channel_pair, uint8_t object_type, /* RNG states */ uint32_t *__r1, uint32_t *__r2) { uint8_t g, sfb, b; uint16_t size, offs; uint8_t group = 0; uint16_t nshort = frame_len >> 3; uint8_t sub = 0; #ifdef FIXED_POINT /* IMDCT scaling */ if (object_type == LD) { sub = 9 /*9*/; } else { if (ics_left->window_sequence == EIGHT_SHORT_SEQUENCE) sub = 7 /*7*/; else sub = 10 /*10*/; } #else (void)object_type; #endif for (g = 0; g < ics_left->num_window_groups; g++) { /* Do perceptual noise substitution decoding */ for (b = 0; b < ics_left->window_group_length[g]; b++) { for (sfb = 0; sfb < ics_left->max_sfb; sfb++) { if (is_noise(ics_left, g, sfb)) { #ifdef LTP_DEC /* Simultaneous use of LTP and PNS is not prevented in the syntax. If both LTP, and PNS are enabled on the same scalefactor band, PNS takes precedence, and no prediction is applied to this band. */ ics_left->ltp.long_used[sfb] = 0; ics_left->ltp2.long_used[sfb] = 0; #endif #ifdef MAIN_DEC /* For scalefactor bands coded using PNS the corresponding predictors are switched to "off". */ ics_left->pred.prediction_used[sfb] = 0; #endif offs = ics_left->swb_offset[sfb]; size = min(ics_left->swb_offset[sfb+1], ics_left->swb_offset_max) - offs; /* Generate random vector */ gen_rand_vector(&spec_left[(group*nshort)+offs], ics_left->scale_factors[g][sfb], size, sub, __r1, __r2); } /* From the spec: If the same scalefactor band and group is coded by perceptual noise substitution in both channels of a channel pair, the correlation of the noise signal can be controlled by means of the ms_used field: While the default noise generation process works independently for each channel (separate generation of random vectors), the same random vector is used for both channels if ms_used[] is set for a particular scalefactor band and group. In this case, no M/S stereo coding is carried out (because M/S stereo coding and noise substitution coding are mutually exclusive). If the same scalefactor band and group is coded by perceptual noise substitution in only one channel of a channel pair the setting of ms_used[] is not evaluated. */ if (channel_pair) { if (is_noise(ics_right, g, sfb)) { if (((ics_left->ms_mask_present == 1) && (ics_left->ms_used[g][sfb])) || (ics_left->ms_mask_present == 2)) { uint16_t c; offs = ics_right->swb_offset[sfb]; size = min(ics_right->swb_offset[sfb+1], ics_right->swb_offset_max) - offs; for (c = 0; c < size; c++) { spec_right[(group*nshort) + offs + c] = spec_left[(group*nshort) + offs + c]; } } else /*if (ics_left->ms_mask_present == 0)*/ { #ifdef LTP_DEC ics_right->ltp.long_used[sfb] = 0; ics_right->ltp2.long_used[sfb] = 0; #endif #ifdef MAIN_DEC ics_right->pred.prediction_used[sfb] = 0; #endif offs = ics_right->swb_offset[sfb]; size = min(ics_right->swb_offset[sfb+1], ics_right->swb_offset_max) - offs; /* Generate random vector */ gen_rand_vector(&spec_right[(group*nshort)+offs], ics_right->scale_factors[g][sfb], size, sub, __r1, __r2); } } } } /* sfb */ group++; } /* b */ } /* g */ } xine-lib-1.2/contrib/libfaad/sbr_qmf_c.h0000644000175000017500000005315714647725151016024 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_qmf_c.h,v 1.17 2007/11/01 12:33:36 menno Exp $ **/ #ifndef __SBR_QMF_C_H__ #define __SBR_QMF_C_H__ #ifdef __cplusplus extern "C" { #endif #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif ALIGN static const real_t qmf_c[640] = { FRAC_CONST(0), FRAC_CONST(-0.00055252865047), FRAC_CONST(-0.00056176925738), FRAC_CONST(-0.00049475180896), FRAC_CONST(-0.00048752279712), FRAC_CONST(-0.00048937912498), FRAC_CONST(-0.00050407143497), FRAC_CONST(-0.00052265642972), FRAC_CONST(-0.00054665656337), FRAC_CONST(-0.00056778025613), FRAC_CONST(-0.00058709304852), FRAC_CONST(-0.00061327473938), FRAC_CONST(-0.00063124935319), FRAC_CONST(-0.00065403333621), FRAC_CONST(-0.00067776907764), FRAC_CONST(-0.00069416146273), FRAC_CONST(-0.00071577364744), FRAC_CONST(-0.00072550431222), FRAC_CONST(-0.00074409418541), FRAC_CONST(-0.00074905980532), FRAC_CONST(-0.0007681371927), FRAC_CONST(-0.00077248485949), FRAC_CONST(-0.00078343322877), FRAC_CONST(-0.00077798694927), FRAC_CONST(-0.000780366471), FRAC_CONST(-0.00078014496257), FRAC_CONST(-0.0007757977331), FRAC_CONST(-0.00076307935757), FRAC_CONST(-0.00075300014201), FRAC_CONST(-0.00073193571525), FRAC_CONST(-0.00072153919876), FRAC_CONST(-0.00069179375372), FRAC_CONST(-0.00066504150893), FRAC_CONST(-0.00063415949025), FRAC_CONST(-0.0005946118933), FRAC_CONST(-0.00055645763906), FRAC_CONST(-0.00051455722108), FRAC_CONST(-0.00046063254803), FRAC_CONST(-0.00040951214522), FRAC_CONST(-0.00035011758756), FRAC_CONST(-0.00028969811748), FRAC_CONST(-0.0002098337344), FRAC_CONST(-0.00014463809349), FRAC_CONST(-6.173344072E-005), FRAC_CONST(1.349497418E-005), FRAC_CONST(0.00010943831274), FRAC_CONST(0.00020430170688), FRAC_CONST(0.00029495311041), FRAC_CONST(0.0004026540216), FRAC_CONST(0.00051073884952), FRAC_CONST(0.00062393761391), FRAC_CONST(0.00074580258865), FRAC_CONST(0.00086084433262), FRAC_CONST(0.00098859883015), FRAC_CONST(0.00112501551307), FRAC_CONST(0.00125778846475), FRAC_CONST(0.00139024948272), FRAC_CONST(0.00154432198471), FRAC_CONST(0.00168680832531), FRAC_CONST(0.00183482654224), FRAC_CONST(0.00198411407369), FRAC_CONST(0.00214615835557), FRAC_CONST(0.00230172547746), FRAC_CONST(0.00246256169126), FRAC_CONST(0.00262017586902), FRAC_CONST(0.00278704643465), FRAC_CONST(0.00294694477165), FRAC_CONST(0.00311254206525), FRAC_CONST(0.00327396134847), FRAC_CONST(0.00344188741828), FRAC_CONST(0.00360082681231), FRAC_CONST(0.00376039229104), FRAC_CONST(0.00392074323703), FRAC_CONST(0.00408197531935), FRAC_CONST(0.0042264269227), FRAC_CONST(0.00437307196781), FRAC_CONST(0.00452098527825), FRAC_CONST(0.00466064606118), FRAC_CONST(0.00479325608498), FRAC_CONST(0.00491376035745), FRAC_CONST(0.00503930226013), FRAC_CONST(0.00514073539032), FRAC_CONST(0.00524611661324), FRAC_CONST(0.00534716811982), FRAC_CONST(0.00541967759307), FRAC_CONST(0.00548760401507), FRAC_CONST(0.00554757145088), FRAC_CONST(0.00559380230045), FRAC_CONST(0.00562206432097), FRAC_CONST(0.00564551969164), FRAC_CONST(0.00563891995151), FRAC_CONST(0.00562661141932), FRAC_CONST(0.0055917128663), FRAC_CONST(0.005540436394), FRAC_CONST(0.0054753783077), FRAC_CONST(0.0053838975897), FRAC_CONST(0.00527157587272), FRAC_CONST(0.00513822754514), FRAC_CONST(0.00498396877629), FRAC_CONST(0.004810946906), FRAC_CONST(0.00460395301471), FRAC_CONST(0.00438018617447), FRAC_CONST(0.0041251642327), FRAC_CONST(0.00384564081246), FRAC_CONST(0.00354012465507), FRAC_CONST(0.00320918858098), FRAC_CONST(0.00284467578623), FRAC_CONST(0.00245085400321), FRAC_CONST(0.0020274176185), FRAC_CONST(0.00157846825768), FRAC_CONST(0.00109023290512), FRAC_CONST(0.0005832264248), FRAC_CONST(2.760451905E-005), FRAC_CONST(-0.00054642808664), FRAC_CONST(-0.00115681355227), FRAC_CONST(-0.00180394725893), FRAC_CONST(-0.00248267236449), FRAC_CONST(-0.003193377839), FRAC_CONST(-0.00394011240522), FRAC_CONST(-0.004722259624), FRAC_CONST(-0.00553372111088), FRAC_CONST(-0.00637922932685), FRAC_CONST(-0.00726158168517), FRAC_CONST(-0.00817982333726), FRAC_CONST(-0.00913253296085), FRAC_CONST(-0.01011502154986), FRAC_CONST(-0.01113155480321), FRAC_CONST(-0.01218499959508), FRAC_CONST(0.01327182200351), FRAC_CONST(0.01439046660792), FRAC_CONST(0.01554055533423), FRAC_CONST(0.01673247129989), FRAC_CONST(0.01794333813443), FRAC_CONST(0.01918724313698), FRAC_CONST(0.02045317933555), FRAC_CONST(0.02174675502535), FRAC_CONST(0.02306801692862), FRAC_CONST(0.02441609920285), FRAC_CONST(0.02578758475467), FRAC_CONST(0.02718594296329), FRAC_CONST(0.02860721736385), FRAC_CONST(0.03005026574279), FRAC_CONST(0.03150176087389), FRAC_CONST(0.03297540810337), FRAC_CONST(0.03446209487686), FRAC_CONST(0.03596975605542), FRAC_CONST(0.03748128504252), FRAC_CONST(0.03900536794745), FRAC_CONST(0.04053491705584), FRAC_CONST(0.04206490946367), FRAC_CONST(0.04360975421304), FRAC_CONST(0.04514884056413), FRAC_CONST(0.04668430272642), FRAC_CONST(0.04821657200672), FRAC_CONST(0.04973857556014), FRAC_CONST(0.05125561555216), FRAC_CONST(0.05276307465207), FRAC_CONST(0.05424527683589), FRAC_CONST(0.05571736482138), FRAC_CONST(0.05716164501299), FRAC_CONST(0.0585915683626), FRAC_CONST(0.05998374801761), FRAC_CONST(0.06134551717207), FRAC_CONST(0.06268578081172), FRAC_CONST(0.06397158980681), FRAC_CONST(0.0652247106438), FRAC_CONST(0.06643675122104), FRAC_CONST(0.06760759851228), FRAC_CONST(0.06870438283512), FRAC_CONST(0.06976302447127), FRAC_CONST(0.07076287107266), FRAC_CONST(0.07170026731102), FRAC_CONST(0.07256825833083), FRAC_CONST(0.07336202550803), FRAC_CONST(0.07410036424342), FRAC_CONST(0.07474525581194), FRAC_CONST(0.07531373362019), FRAC_CONST(0.07580083586584), FRAC_CONST(0.07619924793396), FRAC_CONST(0.07649921704119), FRAC_CONST(0.07670934904245), FRAC_CONST(0.07681739756964), FRAC_CONST(0.07682300113923), FRAC_CONST(0.07672049241746), FRAC_CONST(0.07650507183194), FRAC_CONST(0.07617483218536), FRAC_CONST(0.07573057565061), FRAC_CONST(0.0751576255287), FRAC_CONST(0.07446643947564), FRAC_CONST(0.0736406005762), FRAC_CONST(0.07267746427299), FRAC_CONST(0.07158263647903), FRAC_CONST(0.07035330735093), FRAC_CONST(0.06896640131951), FRAC_CONST(0.06745250215166), FRAC_CONST(0.06576906686508), FRAC_CONST(0.06394448059633), FRAC_CONST(0.06196027790387), FRAC_CONST(0.0598166570809), FRAC_CONST(0.05751526919867), FRAC_CONST(0.05504600343009), FRAC_CONST(0.05240938217366), FRAC_CONST(0.04959786763445), FRAC_CONST(0.04663033051701), FRAC_CONST(0.04347687821958), FRAC_CONST(0.04014582784127), FRAC_CONST(0.03664181168133), FRAC_CONST(0.03295839306691), FRAC_CONST(0.02908240060125), FRAC_CONST(0.02503075618909), FRAC_CONST(0.02079970728622), FRAC_CONST(0.01637012582228), FRAC_CONST(0.01176238327857), FRAC_CONST(0.00696368621617), FRAC_CONST(0.00197656014503), FRAC_CONST(-0.00320868968304), FRAC_CONST(-0.00857117491366), FRAC_CONST(-0.01412888273558), FRAC_CONST(-0.01988341292573), FRAC_CONST(-0.02582272888064), FRAC_CONST(-0.03195312745332), FRAC_CONST(-0.03827765720822), FRAC_CONST(-0.04478068215856), FRAC_CONST(-0.05148041767934), FRAC_CONST(-0.05837053268336), FRAC_CONST(-0.06544098531359), FRAC_CONST(-0.07269433008129), FRAC_CONST(-0.08013729344279), FRAC_CONST(-0.08775475365593), FRAC_CONST(-0.09555333528914), FRAC_CONST(-0.10353295311463), FRAC_CONST(-0.1116826931773), FRAC_CONST(-0.120007798468), FRAC_CONST(-0.12850028503878), FRAC_CONST(-0.13715517611934), FRAC_CONST(-0.1459766491187), FRAC_CONST(-0.15496070710605), FRAC_CONST(-0.16409588556669), FRAC_CONST(-0.17338081721706), FRAC_CONST(-0.18281725485142), FRAC_CONST(-0.19239667457267), FRAC_CONST(-0.20212501768103), FRAC_CONST(-0.21197358538056), FRAC_CONST(-0.22196526964149), FRAC_CONST(-0.23206908706791), FRAC_CONST(-0.24230168845974), FRAC_CONST(-0.25264803095722), FRAC_CONST(-0.26310532994603), FRAC_CONST(-0.27366340405625), FRAC_CONST(-0.28432141891085), FRAC_CONST(-0.29507167170646), FRAC_CONST(-0.30590985751916), FRAC_CONST(-0.31682789136456), FRAC_CONST(-0.32781137272105), FRAC_CONST(-0.33887226938665), FRAC_CONST(-0.3499914122931), FRAC_CONST(0.36115899031355), FRAC_CONST(0.37237955463061), FRAC_CONST(0.38363500139043), FRAC_CONST(0.39492117615675), FRAC_CONST(0.40623176767625), FRAC_CONST(0.41756968968409), FRAC_CONST(0.42891199207373), FRAC_CONST(0.44025537543665), FRAC_CONST(0.45159965356824), FRAC_CONST(0.46293080852757), FRAC_CONST(0.47424532146115), FRAC_CONST(0.48552530911099), FRAC_CONST(0.49677082545707), FRAC_CONST(0.50798175000434), FRAC_CONST(0.51912349702391), FRAC_CONST(0.53022408956855), FRAC_CONST(0.54125534487322), FRAC_CONST(0.55220512585061), FRAC_CONST(0.5630789140137), FRAC_CONST(0.57385241316923), FRAC_CONST(0.58454032354679), FRAC_CONST(0.59511230862496), FRAC_CONST(0.6055783538918), FRAC_CONST(0.61591099320291), FRAC_CONST(0.62612426956055), FRAC_CONST(0.63619801077286), FRAC_CONST(0.64612696959461), FRAC_CONST(0.65590163024671), FRAC_CONST(0.66551398801627), FRAC_CONST(0.67496631901712), FRAC_CONST(0.68423532934598), FRAC_CONST(0.69332823767032), FRAC_CONST(0.70223887193539), FRAC_CONST(0.71094104263095), FRAC_CONST(0.71944626349561), FRAC_CONST(0.72774489002994), FRAC_CONST(0.73582117582769), FRAC_CONST(0.74368278636488), FRAC_CONST(0.75131374561237), FRAC_CONST(0.75870807608242), FRAC_CONST(0.76586748650939), FRAC_CONST(0.77277808813327), FRAC_CONST(0.77942875190216), FRAC_CONST(0.7858353120392), FRAC_CONST(0.79197358416424), FRAC_CONST(0.797846641377), FRAC_CONST(0.80344857518505), FRAC_CONST(0.80876950044491), FRAC_CONST(0.81381912706217), FRAC_CONST(0.81857760046468), FRAC_CONST(0.82304198905409), FRAC_CONST(0.8272275347336), FRAC_CONST(0.8311038457152), FRAC_CONST(0.83469373618402), FRAC_CONST(0.83797173378865), FRAC_CONST(0.84095413924722), FRAC_CONST(0.84362382812005), FRAC_CONST(0.84598184698206), FRAC_CONST(0.84803157770763), FRAC_CONST(0.84978051984268), FRAC_CONST(0.85119715249343), FRAC_CONST(0.85230470352147), FRAC_CONST(0.85310209497017), FRAC_CONST(0.85357205739107), FRAC_CONST(0.85373856005937 /*max*/), FRAC_CONST(0.85357205739107), FRAC_CONST(0.85310209497017), FRAC_CONST(0.85230470352147), FRAC_CONST(0.85119715249343), FRAC_CONST(0.84978051984268), FRAC_CONST(0.84803157770763), FRAC_CONST(0.84598184698206), FRAC_CONST(0.84362382812005), FRAC_CONST(0.84095413924722), FRAC_CONST(0.83797173378865), FRAC_CONST(0.83469373618402), FRAC_CONST(0.8311038457152), FRAC_CONST(0.8272275347336), FRAC_CONST(0.82304198905409), FRAC_CONST(0.81857760046468), FRAC_CONST(0.81381912706217), FRAC_CONST(0.80876950044491), FRAC_CONST(0.80344857518505), FRAC_CONST(0.797846641377), FRAC_CONST(0.79197358416424), FRAC_CONST(0.7858353120392), FRAC_CONST(0.77942875190216), FRAC_CONST(0.77277808813327), FRAC_CONST(0.76586748650939), FRAC_CONST(0.75870807608242), FRAC_CONST(0.75131374561237), FRAC_CONST(0.74368278636488), FRAC_CONST(0.73582117582769), FRAC_CONST(0.72774489002994), FRAC_CONST(0.71944626349561), FRAC_CONST(0.71094104263095), FRAC_CONST(0.70223887193539), FRAC_CONST(0.69332823767032), FRAC_CONST(0.68423532934598), FRAC_CONST(0.67496631901712), FRAC_CONST(0.66551398801627), FRAC_CONST(0.65590163024671), FRAC_CONST(0.64612696959461), FRAC_CONST(0.63619801077286), FRAC_CONST(0.62612426956055), FRAC_CONST(0.61591099320291), FRAC_CONST(0.6055783538918), FRAC_CONST(0.59511230862496), FRAC_CONST(0.58454032354679), FRAC_CONST(0.57385241316923), FRAC_CONST(0.5630789140137), FRAC_CONST(0.55220512585061), FRAC_CONST(0.54125534487322), FRAC_CONST(0.53022408956855), FRAC_CONST(0.51912349702391), FRAC_CONST(0.50798175000434), FRAC_CONST(0.49677082545707), FRAC_CONST(0.48552530911099), FRAC_CONST(0.47424532146115), FRAC_CONST(0.46293080852757), FRAC_CONST(0.45159965356824), FRAC_CONST(0.44025537543665), FRAC_CONST(0.42891199207373), FRAC_CONST(0.41756968968409), FRAC_CONST(0.40623176767625), FRAC_CONST(0.39492117615675), FRAC_CONST(0.38363500139043), FRAC_CONST(0.37237955463061), FRAC_CONST(-0.36115899031355), FRAC_CONST(-0.3499914122931), FRAC_CONST(-0.33887226938665), FRAC_CONST(-0.32781137272105), FRAC_CONST(-0.31682789136456), FRAC_CONST(-0.30590985751916), FRAC_CONST(-0.29507167170646), FRAC_CONST(-0.28432141891085), FRAC_CONST(-0.27366340405625), FRAC_CONST(-0.26310532994603), FRAC_CONST(-0.25264803095722), FRAC_CONST(-0.24230168845974), FRAC_CONST(-0.23206908706791), FRAC_CONST(-0.22196526964149), FRAC_CONST(-0.21197358538056), FRAC_CONST(-0.20212501768103), FRAC_CONST(-0.19239667457267), FRAC_CONST(-0.18281725485142), FRAC_CONST(-0.17338081721706), FRAC_CONST(-0.16409588556669), FRAC_CONST(-0.15496070710605), FRAC_CONST(-0.1459766491187), FRAC_CONST(-0.13715517611934), FRAC_CONST(-0.12850028503878), FRAC_CONST(-0.120007798468), FRAC_CONST(-0.1116826931773), FRAC_CONST(-0.10353295311463), FRAC_CONST(-0.09555333528914), FRAC_CONST(-0.08775475365593), FRAC_CONST(-0.08013729344279), FRAC_CONST(-0.07269433008129), FRAC_CONST(-0.06544098531359), FRAC_CONST(-0.05837053268336), FRAC_CONST(-0.05148041767934), FRAC_CONST(-0.04478068215856), FRAC_CONST(-0.03827765720822), FRAC_CONST(-0.03195312745332), FRAC_CONST(-0.02582272888064), FRAC_CONST(-0.01988341292573), FRAC_CONST(-0.01412888273558), FRAC_CONST(-0.00857117491366), FRAC_CONST(-0.00320868968304), FRAC_CONST(0.00197656014503), FRAC_CONST(0.00696368621617), FRAC_CONST(0.01176238327857), FRAC_CONST(0.01637012582228), FRAC_CONST(0.02079970728622), FRAC_CONST(0.02503075618909), FRAC_CONST(0.02908240060125), FRAC_CONST(0.03295839306691), FRAC_CONST(0.03664181168133), FRAC_CONST(0.04014582784127), FRAC_CONST(0.04347687821958), FRAC_CONST(0.04663033051701), FRAC_CONST(0.04959786763445), FRAC_CONST(0.05240938217366), FRAC_CONST(0.05504600343009), FRAC_CONST(0.05751526919867), FRAC_CONST(0.0598166570809), FRAC_CONST(0.06196027790387), FRAC_CONST(0.06394448059633), FRAC_CONST(0.06576906686508), FRAC_CONST(0.06745250215166), FRAC_CONST(0.06896640131951), FRAC_CONST(0.07035330735093), FRAC_CONST(0.07158263647903), FRAC_CONST(0.07267746427299), FRAC_CONST(0.0736406005762), FRAC_CONST(0.07446643947564), FRAC_CONST(0.0751576255287), FRAC_CONST(0.07573057565061), FRAC_CONST(0.07617483218536), FRAC_CONST(0.07650507183194), FRAC_CONST(0.07672049241746), FRAC_CONST(0.07682300113923), FRAC_CONST(0.07681739756964), FRAC_CONST(0.07670934904245), FRAC_CONST(0.07649921704119), FRAC_CONST(0.07619924793396), FRAC_CONST(0.07580083586584), FRAC_CONST(0.07531373362019), FRAC_CONST(0.07474525581194), FRAC_CONST(0.07410036424342), FRAC_CONST(0.07336202550803), FRAC_CONST(0.07256825833083), FRAC_CONST(0.07170026731102), FRAC_CONST(0.07076287107266), FRAC_CONST(0.06976302447127), FRAC_CONST(0.06870438283512), FRAC_CONST(0.06760759851228), FRAC_CONST(0.06643675122104), FRAC_CONST(0.0652247106438), FRAC_CONST(0.06397158980681), FRAC_CONST(0.06268578081172), FRAC_CONST(0.06134551717207), FRAC_CONST(0.05998374801761), FRAC_CONST(0.0585915683626), FRAC_CONST(0.05716164501299), FRAC_CONST(0.05571736482138), FRAC_CONST(0.05424527683589), FRAC_CONST(0.05276307465207), FRAC_CONST(0.05125561555216), FRAC_CONST(0.04973857556014), FRAC_CONST(0.04821657200672), FRAC_CONST(0.04668430272642), FRAC_CONST(0.04514884056413), FRAC_CONST(0.04360975421304), FRAC_CONST(0.04206490946367), FRAC_CONST(0.04053491705584), FRAC_CONST(0.03900536794745), FRAC_CONST(0.03748128504252), FRAC_CONST(0.03596975605542), FRAC_CONST(0.03446209487686), FRAC_CONST(0.03297540810337), FRAC_CONST(0.03150176087389), FRAC_CONST(0.03005026574279), FRAC_CONST(0.02860721736385), FRAC_CONST(0.02718594296329), FRAC_CONST(0.02578758475467), FRAC_CONST(0.02441609920285), FRAC_CONST(0.02306801692862), FRAC_CONST(0.02174675502535), FRAC_CONST(0.02045317933555), FRAC_CONST(0.01918724313698), FRAC_CONST(0.01794333813443), FRAC_CONST(0.01673247129989), FRAC_CONST(0.01554055533423), FRAC_CONST(0.01439046660792), FRAC_CONST(-0.01327182200351), FRAC_CONST(-0.01218499959508), FRAC_CONST(-0.01113155480321), FRAC_CONST(-0.01011502154986), FRAC_CONST(-0.00913253296085), FRAC_CONST(-0.00817982333726), FRAC_CONST(-0.00726158168517), FRAC_CONST(-0.00637922932685), FRAC_CONST(-0.00553372111088), FRAC_CONST(-0.004722259624), FRAC_CONST(-0.00394011240522), FRAC_CONST(-0.003193377839), FRAC_CONST(-0.00248267236449), FRAC_CONST(-0.00180394725893), FRAC_CONST(-0.00115681355227), FRAC_CONST(-0.00054642808664), FRAC_CONST(2.760451905E-005), FRAC_CONST(0.0005832264248), FRAC_CONST(0.00109023290512), FRAC_CONST(0.00157846825768), FRAC_CONST(0.0020274176185), FRAC_CONST(0.00245085400321), FRAC_CONST(0.00284467578623), FRAC_CONST(0.00320918858098), FRAC_CONST(0.00354012465507), FRAC_CONST(0.00384564081246), FRAC_CONST(0.0041251642327), FRAC_CONST(0.00438018617447), FRAC_CONST(0.00460395301471), FRAC_CONST(0.004810946906), FRAC_CONST(0.00498396877629), FRAC_CONST(0.00513822754514), FRAC_CONST(0.00527157587272), FRAC_CONST(0.0053838975897), FRAC_CONST(0.0054753783077), FRAC_CONST(0.005540436394), FRAC_CONST(0.0055917128663), FRAC_CONST(0.00562661141932), FRAC_CONST(0.00563891995151), FRAC_CONST(0.00564551969164), FRAC_CONST(0.00562206432097), FRAC_CONST(0.00559380230045), FRAC_CONST(0.00554757145088), FRAC_CONST(0.00548760401507), FRAC_CONST(0.00541967759307), FRAC_CONST(0.00534716811982), FRAC_CONST(0.00524611661324), FRAC_CONST(0.00514073539032), FRAC_CONST(0.00503930226013), FRAC_CONST(0.00491376035745), FRAC_CONST(0.00479325608498), FRAC_CONST(0.00466064606118), FRAC_CONST(0.00452098527825), FRAC_CONST(0.00437307196781), FRAC_CONST(0.0042264269227), FRAC_CONST(0.00408197531935), FRAC_CONST(0.00392074323703), FRAC_CONST(0.00376039229104), FRAC_CONST(0.00360082681231), FRAC_CONST(0.00344188741828), FRAC_CONST(0.00327396134847), FRAC_CONST(0.00311254206525), FRAC_CONST(0.00294694477165), FRAC_CONST(0.00278704643465), FRAC_CONST(0.00262017586902), FRAC_CONST(0.00246256169126), FRAC_CONST(0.00230172547746), FRAC_CONST(0.00214615835557), FRAC_CONST(0.00198411407369), FRAC_CONST(0.00183482654224), FRAC_CONST(0.00168680832531), FRAC_CONST(0.00154432198471), FRAC_CONST(0.00139024948272), FRAC_CONST(0.00125778846475), FRAC_CONST(0.00112501551307), FRAC_CONST(0.00098859883015), FRAC_CONST(0.00086084433262), FRAC_CONST(0.00074580258865), FRAC_CONST(0.00062393761391), FRAC_CONST(0.00051073884952), FRAC_CONST(0.0004026540216), FRAC_CONST(0.00029495311041), FRAC_CONST(0.00020430170688), FRAC_CONST(0.00010943831274), FRAC_CONST(1.349497418E-005), FRAC_CONST(-6.173344072E-005), FRAC_CONST(-0.00014463809349), FRAC_CONST(-0.0002098337344), FRAC_CONST(-0.00028969811748), FRAC_CONST(-0.00035011758756), FRAC_CONST(-0.00040951214522), FRAC_CONST(-0.00046063254803), FRAC_CONST(-0.00051455722108), FRAC_CONST(-0.00055645763906), FRAC_CONST(-0.0005946118933), FRAC_CONST(-0.00063415949025), FRAC_CONST(-0.00066504150893), FRAC_CONST(-0.00069179375372), FRAC_CONST(-0.00072153919876), FRAC_CONST(-0.00073193571525), FRAC_CONST(-0.00075300014201), FRAC_CONST(-0.00076307935757), FRAC_CONST(-0.0007757977331), FRAC_CONST(-0.00078014496257), FRAC_CONST(-0.000780366471), FRAC_CONST(-0.00077798694927), FRAC_CONST(-0.00078343322877), FRAC_CONST(-0.00077248485949), FRAC_CONST(-0.0007681371927), FRAC_CONST(-0.00074905980532), FRAC_CONST(-0.00074409418541), FRAC_CONST(-0.00072550431222), FRAC_CONST(-0.00071577364744), FRAC_CONST(-0.00069416146273), FRAC_CONST(-0.00067776907764), FRAC_CONST(-0.00065403333621), FRAC_CONST(-0.00063124935319), FRAC_CONST(-0.00061327473938), FRAC_CONST(-0.00058709304852), FRAC_CONST(-0.00056778025613), FRAC_CONST(-0.00054665656337), FRAC_CONST(-0.00052265642972), FRAC_CONST(-0.00050407143497), FRAC_CONST(-0.00048937912498), FRAC_CONST(-0.00048752279712), FRAC_CONST(-0.00049475180896), FRAC_CONST(-0.00056176925738), FRAC_CONST(-0.00055252865047) }; #endif xine-lib-1.2/contrib/libfaad/drc.c0000644000175000017500000001204614647725152014625 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: drc.c,v 1.28 2007/11/01 12:33:30 menno Exp $ **/ #include "common.h" #include "structs.h" #include #include #include "syntax.h" #include "drc.h" drc_info *drc_init(real_t cut, real_t boost) { drc_info *drc = (drc_info*)faad_malloc(sizeof(drc_info)); memset(drc, 0, sizeof(drc_info)); drc->ctrl1 = cut; drc->ctrl2 = boost; drc->num_bands = 1; drc->band_top[0] = 1024/4 - 1; drc->dyn_rng_sgn[0] = 1; drc->dyn_rng_ctl[0] = 0; return drc; } void drc_end(drc_info *drc) { if (drc) faad_free(drc); } #ifdef FIXED_POINT static real_t drc_pow2_table[] = { COEF_CONST(0.5146511183), COEF_CONST(0.5297315472), COEF_CONST(0.5452538663), COEF_CONST(0.5612310242), COEF_CONST(0.5776763484), COEF_CONST(0.5946035575), COEF_CONST(0.6120267717), COEF_CONST(0.6299605249), COEF_CONST(0.6484197773), COEF_CONST(0.6674199271), COEF_CONST(0.6869768237), COEF_CONST(0.7071067812), COEF_CONST(0.7278265914), COEF_CONST(0.7491535384), COEF_CONST(0.7711054127), COEF_CONST(0.7937005260), COEF_CONST(0.8169577266), COEF_CONST(0.8408964153), COEF_CONST(0.8655365610), COEF_CONST(0.8908987181), COEF_CONST(0.9170040432), COEF_CONST(0.9438743127), COEF_CONST(0.9715319412), COEF_CONST(1.0000000000), COEF_CONST(1.0293022366), COEF_CONST(1.0594630944), COEF_CONST(1.0905077327), COEF_CONST(1.1224620483), COEF_CONST(1.1553526969), COEF_CONST(1.1892071150), COEF_CONST(1.2240535433), COEF_CONST(1.2599210499), COEF_CONST(1.2968395547), COEF_CONST(1.3348398542), COEF_CONST(1.3739536475), COEF_CONST(1.4142135624), COEF_CONST(1.4556531828), COEF_CONST(1.4983070769), COEF_CONST(1.5422108254), COEF_CONST(1.5874010520), COEF_CONST(1.6339154532), COEF_CONST(1.6817928305), COEF_CONST(1.7310731220), COEF_CONST(1.7817974363), COEF_CONST(1.8340080864), COEF_CONST(1.8877486254), COEF_CONST(1.9430638823) }; #endif void drc_decode(drc_info *drc, real_t *spec) { uint16_t i, bd, top; #ifdef FIXED_POINT int32_t exp, frac; #else real_t factor, exp; #endif uint16_t bottom = 0; if (drc->num_bands == 1) drc->band_top[0] = 1024/4 - 1; for (bd = 0; bd < drc->num_bands; bd++) { top = 4 * (drc->band_top[bd] + 1); #ifndef FIXED_POINT /* Decode DRC gain factor */ if (drc->dyn_rng_sgn[bd]) /* compress */ exp = -drc->ctrl1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/REAL_CONST(24.0); else /* boost */ exp = drc->ctrl2 * (drc->dyn_rng_ctl[bd] + (DRC_REF_LEVEL - drc->prog_ref_level))/REAL_CONST(24.0); factor = (real_t)pow(2.0, exp); /* Apply gain factor */ for (i = bottom; i < top; i++) spec[i] *= factor; #else /* Decode DRC gain factor */ if (drc->dyn_rng_sgn[bd]) /* compress */ { exp = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/ 24; frac = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24; } else { /* boost */ exp = (drc->dyn_rng_ctl[bd] + (DRC_REF_LEVEL - drc->prog_ref_level))/ 24; frac = (drc->dyn_rng_ctl[bd] + (DRC_REF_LEVEL - drc->prog_ref_level)) % 24; } /* Apply gain factor */ if (exp < 0) { for (i = bottom; i < top; i++) { spec[i] >>= -exp; if (frac) spec[i] = MUL_R(spec[i],drc_pow2_table[frac+23]); } } else { for (i = bottom; i < top; i++) { spec[i] <<= exp; if (frac) spec[i] = MUL_R(spec[i],drc_pow2_table[frac+23]); } } #endif bottom = top; } } xine-lib-1.2/contrib/libfaad/sbr_hfgen.h0000644000175000017500000000314414647725152016016 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_hfgen.h,v 1.20 2007/11/01 12:33:35 menno Exp $ **/ #ifndef __SBR_HFGEN_H__ #define __SBR_HFGEN_H__ #ifdef __cplusplus extern "C" { #endif void hf_generation(sbr_info *sbr, qmf_t Xlow[MAX_NTSRHFG][64], qmf_t Xhigh[MAX_NTSRHFG][64] #ifdef SBR_LOW_POWER ,real_t *deg #endif ,uint8_t ch); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/mdct_tab.h0000644000175000017500000074642114647725152015652 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: mdct_tab.h,v 1.7 2007/11/01 12:33:32 menno Exp $ **/ #ifndef __MDCT_TAB_H__ #define __MDCT_TAB_H__ #ifdef __cplusplus extern "C" { #endif #ifdef FIXED_POINT /* 256 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_2048[] = { { FRAC_CONST(0.999999926465718), FRAC_CONST(0.000383495187571) }, { FRAC_CONST(0.999994043728986), FRAC_CONST(0.003451449920136) }, { FRAC_CONST(0.999978748667469), FRAC_CONST(0.006519372166339) }, { FRAC_CONST(0.999954041425130), FRAC_CONST(0.009587233049729) }, { FRAC_CONST(0.999919922234523), FRAC_CONST(0.012655003694430) }, { FRAC_CONST(0.999876391416790), FRAC_CONST(0.015722655225417) }, { FRAC_CONST(0.999823449381662), FRAC_CONST(0.018790158768785) }, { FRAC_CONST(0.999761096627447), FRAC_CONST(0.021857485452022) }, { FRAC_CONST(0.999689333741034), FRAC_CONST(0.024924606404281) }, { FRAC_CONST(0.999608161397882), FRAC_CONST(0.027991492756653) }, { FRAC_CONST(0.999517580362017), FRAC_CONST(0.031058115642435) }, { FRAC_CONST(0.999417591486022), FRAC_CONST(0.034124446197403) }, { FRAC_CONST(0.999308195711029), FRAC_CONST(0.037190455560088) }, { FRAC_CONST(0.999189394066715), FRAC_CONST(0.040256114872041) }, { FRAC_CONST(0.999061187671285), FRAC_CONST(0.043321395278110) }, { FRAC_CONST(0.998923577731466), FRAC_CONST(0.046386267926707) }, { FRAC_CONST(0.998776565542496), FRAC_CONST(0.049450703970085) }, { FRAC_CONST(0.998620152488109), FRAC_CONST(0.052514674564603) }, { FRAC_CONST(0.998454340040525), FRAC_CONST(0.055578150871005) }, { FRAC_CONST(0.998279129760433), FRAC_CONST(0.058641104054683) }, { FRAC_CONST(0.998094523296980), FRAC_CONST(0.061703505285957) }, { FRAC_CONST(0.997900522387752), FRAC_CONST(0.064765325740340) }, { FRAC_CONST(0.997697128858759), FRAC_CONST(0.067826536598811) }, { FRAC_CONST(0.997484344624418), FRAC_CONST(0.070887109048088) }, { FRAC_CONST(0.997262171687536), FRAC_CONST(0.073947014280897) }, { FRAC_CONST(0.997030612139289), FRAC_CONST(0.077006223496246) }, { FRAC_CONST(0.996789668159205), FRAC_CONST(0.080064707899691) }, { FRAC_CONST(0.996539342015138), FRAC_CONST(0.083122438703613) }, { FRAC_CONST(0.996279636063255), FRAC_CONST(0.086179387127485) }, { FRAC_CONST(0.996010552748006), FRAC_CONST(0.089235524398144) }, { FRAC_CONST(0.995732094602106), FRAC_CONST(0.092290821750062) }, { FRAC_CONST(0.995444264246510), FRAC_CONST(0.095345250425618) }, { FRAC_CONST(0.995147064390386), FRAC_CONST(0.098398781675364) }, { FRAC_CONST(0.994840497831093), FRAC_CONST(0.101451386758302) }, { FRAC_CONST(0.994524567454152), FRAC_CONST(0.104503036942151) }, { FRAC_CONST(0.994199276233219), FRAC_CONST(0.107553703503616) }, { FRAC_CONST(0.993864627230060), FRAC_CONST(0.110603357728662) }, { FRAC_CONST(0.993520623594518), FRAC_CONST(0.113651970912782) }, { FRAC_CONST(0.993167268564487), FRAC_CONST(0.116699514361268) }, { FRAC_CONST(0.992804565465879), FRAC_CONST(0.119745959389480) }, { FRAC_CONST(0.992432517712594), FRAC_CONST(0.122791277323117) }, { FRAC_CONST(0.992051128806486), FRAC_CONST(0.125835439498487) }, { FRAC_CONST(0.991660402337333), FRAC_CONST(0.128878417262777) }, { FRAC_CONST(0.991260341982802), FRAC_CONST(0.131920181974320) }, { FRAC_CONST(0.990850951508414), FRAC_CONST(0.134960705002869) }, { FRAC_CONST(0.990432234767506), FRAC_CONST(0.137999957729863) }, { FRAC_CONST(0.990004195701201), FRAC_CONST(0.141037911548698) }, { FRAC_CONST(0.989566838338365), FRAC_CONST(0.144074537864995) }, { FRAC_CONST(0.989120166795573), FRAC_CONST(0.147109808096872) }, { FRAC_CONST(0.988664185277066), FRAC_CONST(0.150143693675208) }, { FRAC_CONST(0.988198898074718), FRAC_CONST(0.153176166043918) }, { FRAC_CONST(0.987724309567987), FRAC_CONST(0.156207196660216) }, { FRAC_CONST(0.987240424223882), FRAC_CONST(0.159236756994888) }, { FRAC_CONST(0.986747246596917), FRAC_CONST(0.162264818532558) }, { FRAC_CONST(0.986244781329065), FRAC_CONST(0.165291352771958) }, { FRAC_CONST(0.985733033149723), FRAC_CONST(0.168316331226195) }, { FRAC_CONST(0.985212006875659), FRAC_CONST(0.171339725423019) }, { FRAC_CONST(0.984681707410971), FRAC_CONST(0.174361506905094) }, { FRAC_CONST(0.984142139747039), FRAC_CONST(0.177381647230260) }, { FRAC_CONST(0.983593308962479), FRAC_CONST(0.180400117971807) }, { FRAC_CONST(0.983035220223096), FRAC_CONST(0.183416890718739) }, { FRAC_CONST(0.982467878781833), FRAC_CONST(0.186431937076042) }, { FRAC_CONST(0.981891289978725), FRAC_CONST(0.189445228664950) }, { FRAC_CONST(0.981305459240845), FRAC_CONST(0.192456737123217) }, { FRAC_CONST(0.980710392082254), FRAC_CONST(0.195466434105377) }, { FRAC_CONST(0.980106094103952), FRAC_CONST(0.198474291283016) }, { FRAC_CONST(0.979492570993821), FRAC_CONST(0.201480280345038) }, { FRAC_CONST(0.978869828526574), FRAC_CONST(0.204484372997927) }, { FRAC_CONST(0.978237872563701), FRAC_CONST(0.207486540966021) }, { FRAC_CONST(0.977596709053412), FRAC_CONST(0.210486755991770) }, { FRAC_CONST(0.976946344030582), FRAC_CONST(0.213484989836008) }, { FRAC_CONST(0.976286783616694), FRAC_CONST(0.216481214278217) }, { FRAC_CONST(0.975618034019782), FRAC_CONST(0.219475401116790) }, { FRAC_CONST(0.974940101534372), FRAC_CONST(0.222467522169302) }, { FRAC_CONST(0.974252992541423), FRAC_CONST(0.225457549272769) }, { FRAC_CONST(0.973556713508266), FRAC_CONST(0.228445454283916) }, { FRAC_CONST(0.972851270988544), FRAC_CONST(0.231431209079446) }, { FRAC_CONST(0.972136671622152), FRAC_CONST(0.234414785556295) }, { FRAC_CONST(0.971412922135171), FRAC_CONST(0.237396155631907) }, { FRAC_CONST(0.970680029339806), FRAC_CONST(0.240375291244489) }, { FRAC_CONST(0.969938000134324), FRAC_CONST(0.243352164353285) }, { FRAC_CONST(0.969186841502986), FRAC_CONST(0.246326746938829) }, { FRAC_CONST(0.968426560515983), FRAC_CONST(0.249299011003218) }, { FRAC_CONST(0.967657164329370), FRAC_CONST(0.252268928570371) }, { FRAC_CONST(0.966878660184996), FRAC_CONST(0.255236471686292) }, { FRAC_CONST(0.966091055410439), FRAC_CONST(0.258201612419335) }, { FRAC_CONST(0.965294357418935), FRAC_CONST(0.261164322860466) }, { FRAC_CONST(0.964488573709308), FRAC_CONST(0.264124575123528) }, { FRAC_CONST(0.963673711865903), FRAC_CONST(0.267082341345496) }, { FRAC_CONST(0.962849779558509), FRAC_CONST(0.270037593686751) }, { FRAC_CONST(0.962016784542291), FRAC_CONST(0.272990304331330) }, { FRAC_CONST(0.961174734657714), FRAC_CONST(0.275940445487197) }, { FRAC_CONST(0.960323637830474), FRAC_CONST(0.278887989386500) }, { FRAC_CONST(0.959463502071418), FRAC_CONST(0.281832908285833) }, { FRAC_CONST(0.958594335476470), FRAC_CONST(0.284775174466498) }, { FRAC_CONST(0.957716146226559), FRAC_CONST(0.287714760234765) }, { FRAC_CONST(0.956828942587535), FRAC_CONST(0.290651637922133) }, { FRAC_CONST(0.955932732910098), FRAC_CONST(0.293585779885591) }, { FRAC_CONST(0.955027525629714), FRAC_CONST(0.296517158507877) }, { FRAC_CONST(0.954113329266539), FRAC_CONST(0.299445746197740) }, { FRAC_CONST(0.953190152425337), FRAC_CONST(0.302371515390196) }, { FRAC_CONST(0.952258003795400), FRAC_CONST(0.305294438546792) }, { FRAC_CONST(0.951316892150466), FRAC_CONST(0.308214488155861) }, { FRAC_CONST(0.950366826348636), FRAC_CONST(0.311131636732785) }, { FRAC_CONST(0.949407815332292), FRAC_CONST(0.314045856820251) }, { FRAC_CONST(0.948439868128010), FRAC_CONST(0.316957120988508) }, { FRAC_CONST(0.947462993846478), FRAC_CONST(0.319865401835631) }, { FRAC_CONST(0.946477201682409), FRAC_CONST(0.322770671987771) }, { FRAC_CONST(0.945482500914454), FRAC_CONST(0.325672904099420) }, { FRAC_CONST(0.944478900905116), FRAC_CONST(0.328572070853664) }, { FRAC_CONST(0.943466411100659), FRAC_CONST(0.331468144962441) }, { FRAC_CONST(0.942445041031025), FRAC_CONST(0.334361099166799) }, { FRAC_CONST(0.941414800309736), FRAC_CONST(0.337250906237151) }, { FRAC_CONST(0.940375698633812), FRAC_CONST(0.340137538973532) }, { FRAC_CONST(0.939327745783671), FRAC_CONST(0.343020970205856) }, { FRAC_CONST(0.938270951623047), FRAC_CONST(0.345901172794169) }, { FRAC_CONST(0.937205326098888), FRAC_CONST(0.348778119628908) }, { FRAC_CONST(0.936130879241267), FRAC_CONST(0.351651783631155) }, { FRAC_CONST(0.935047621163287), FRAC_CONST(0.354522137752887) }, { FRAC_CONST(0.933955562060987), FRAC_CONST(0.357389154977241) }, { FRAC_CONST(0.932854712213241), FRAC_CONST(0.360252808318757) }, { FRAC_CONST(0.931745081981669), FRAC_CONST(0.363113070823639) }, { FRAC_CONST(0.930626681810532), FRAC_CONST(0.365969915570009) }, { FRAC_CONST(0.929499522226639), FRAC_CONST(0.368823315668154) }, { FRAC_CONST(0.928363613839244), FRAC_CONST(0.371673244260787) }, { FRAC_CONST(0.927218967339952), FRAC_CONST(0.374519674523293) }, { FRAC_CONST(0.926065593502609), FRAC_CONST(0.377362579663988) }, { FRAC_CONST(0.924903503183211), FRAC_CONST(0.380201932924366) }, { FRAC_CONST(0.923732707319793), FRAC_CONST(0.383037707579352) }, { FRAC_CONST(0.922553216932333), FRAC_CONST(0.385869876937555) }, { FRAC_CONST(0.921365043122642), FRAC_CONST(0.388698414341519) }, { FRAC_CONST(0.920168197074266), FRAC_CONST(0.391523293167972) }, { FRAC_CONST(0.918962690052376), FRAC_CONST(0.394344486828080) }, { FRAC_CONST(0.917748533403661), FRAC_CONST(0.397161968767692) }, { FRAC_CONST(0.916525738556228), FRAC_CONST(0.399975712467595) }, { FRAC_CONST(0.915294317019487), FRAC_CONST(0.402785691443764) }, { FRAC_CONST(0.914054280384047), FRAC_CONST(0.405591879247604) }, { FRAC_CONST(0.912805640321604), FRAC_CONST(0.408394249466208) }, { FRAC_CONST(0.911548408584834), FRAC_CONST(0.411192775722600) }, { FRAC_CONST(0.910282597007282), FRAC_CONST(0.413987431675985) }, { FRAC_CONST(0.909008217503247), FRAC_CONST(0.416778191021998) }, { FRAC_CONST(0.907725282067676), FRAC_CONST(0.419565027492947) }, { FRAC_CONST(0.906433802776045), FRAC_CONST(0.422347914858067) }, { FRAC_CONST(0.905133791784250), FRAC_CONST(0.425126826923762) }, { FRAC_CONST(0.903825261328488), FRAC_CONST(0.427901737533854) }, { FRAC_CONST(0.902508223725146), FRAC_CONST(0.430672620569827) }, { FRAC_CONST(0.901182691370685), FRAC_CONST(0.433439449951074) }, { FRAC_CONST(0.899848676741519), FRAC_CONST(0.436202199635144) }, { FRAC_CONST(0.898506192393902), FRAC_CONST(0.438960843617984) }, { FRAC_CONST(0.897155250963809), FRAC_CONST(0.441715355934187) }, { FRAC_CONST(0.895795865166814), FRAC_CONST(0.444465710657234) }, { FRAC_CONST(0.894428047797974), FRAC_CONST(0.447211881899738) }, { FRAC_CONST(0.893051811731707), FRAC_CONST(0.449953843813691) }, { FRAC_CONST(0.891667169921672), FRAC_CONST(0.452691570590701) }, { FRAC_CONST(0.890274135400645), FRAC_CONST(0.455425036462242) }, { FRAC_CONST(0.888872721280396), FRAC_CONST(0.458154215699893) }, { FRAC_CONST(0.887462940751569), FRAC_CONST(0.460879082615579) }, { FRAC_CONST(0.886044807083556), FRAC_CONST(0.463599611561814) }, { FRAC_CONST(0.884618333624370), FRAC_CONST(0.466315776931944) }, { FRAC_CONST(0.883183533800523), FRAC_CONST(0.469027553160387) }, { FRAC_CONST(0.881740421116898), FRAC_CONST(0.471734914722871) }, { FRAC_CONST(0.880289009156621), FRAC_CONST(0.474437836136679) }, { FRAC_CONST(0.878829311580933), FRAC_CONST(0.477136291960885) }, { FRAC_CONST(0.877361342129065), FRAC_CONST(0.479830256796594) }, { FRAC_CONST(0.875885114618104), FRAC_CONST(0.482519705287184) }, { FRAC_CONST(0.874400642942865), FRAC_CONST(0.485204612118542) }, { FRAC_CONST(0.872907941075761), FRAC_CONST(0.487884952019301) }, { FRAC_CONST(0.871407023066671), FRAC_CONST(0.490560699761082) }, { FRAC_CONST(0.869897903042806), FRAC_CONST(0.493231830158728) }, { FRAC_CONST(0.868380595208580), FRAC_CONST(0.495898318070542) }, { FRAC_CONST(0.866855113845470), FRAC_CONST(0.498560138398525) }, { FRAC_CONST(0.865321473311890), FRAC_CONST(0.501217266088610) }, { FRAC_CONST(0.863779688043047), FRAC_CONST(0.503869676130899) }, { FRAC_CONST(0.862229772550811), FRAC_CONST(0.506517343559899) }, { FRAC_CONST(0.860671741423578), FRAC_CONST(0.509160243454755) }, { FRAC_CONST(0.859105609326130), FRAC_CONST(0.511798350939487) }, { FRAC_CONST(0.857531390999499), FRAC_CONST(0.514431641183223) }, { FRAC_CONST(0.855949101260827), FRAC_CONST(0.517060089400432) }, { FRAC_CONST(0.854358755003227), FRAC_CONST(0.519683670851158) }, { FRAC_CONST(0.852760367195645), FRAC_CONST(0.522302360841255) }, { FRAC_CONST(0.851153952882715), FRAC_CONST(0.524916134722613) }, { FRAC_CONST(0.849539527184621), FRAC_CONST(0.527524967893398) }, { FRAC_CONST(0.847917105296951), FRAC_CONST(0.530128835798279) }, { FRAC_CONST(0.846286702490560), FRAC_CONST(0.532727713928659) }, { FRAC_CONST(0.844648334111418), FRAC_CONST(0.535321577822907) }, { FRAC_CONST(0.843002015580473), FRAC_CONST(0.537910403066589) }, { FRAC_CONST(0.841347762393502), FRAC_CONST(0.540494165292695) }, { FRAC_CONST(0.839685590120966), FRAC_CONST(0.543072840181872) }, { FRAC_CONST(0.838015514407864), FRAC_CONST(0.545646403462649) }, { FRAC_CONST(0.836337550973584), FRAC_CONST(0.548214830911668) }, { FRAC_CONST(0.834651715611756), FRAC_CONST(0.550778098353912) }, { FRAC_CONST(0.832958024190107), FRAC_CONST(0.553336181662932) }, { FRAC_CONST(0.831256492650303), FRAC_CONST(0.555889056761074) }, { FRAC_CONST(0.829547137007809), FRAC_CONST(0.558436699619704) }, { FRAC_CONST(0.827829973351730), FRAC_CONST(0.560979086259438) }, { FRAC_CONST(0.826105017844665), FRAC_CONST(0.563516192750365) }, { FRAC_CONST(0.824372286722551), FRAC_CONST(0.566047995212271) }, { FRAC_CONST(0.822631796294515), FRAC_CONST(0.568574469814869) }, { FRAC_CONST(0.820883562942715), FRAC_CONST(0.571095592778017) }, { FRAC_CONST(0.819127603122188), FRAC_CONST(0.573611340371945) }, { FRAC_CONST(0.817363933360698), FRAC_CONST(0.576121688917478) }, { FRAC_CONST(0.815592570258577), FRAC_CONST(0.578626614786261) }, { FRAC_CONST(0.813813530488567), FRAC_CONST(0.581126094400978) }, { FRAC_CONST(0.812026830795670), FRAC_CONST(0.583620104235573) }, { FRAC_CONST(0.810232487996982), FRAC_CONST(0.586108620815476) }, { FRAC_CONST(0.808430518981543), FRAC_CONST(0.588591620717823) }, { FRAC_CONST(0.806620940710170), FRAC_CONST(0.591069080571671) }, { FRAC_CONST(0.804803770215303), FRAC_CONST(0.593540977058226) }, { FRAC_CONST(0.802979024600843), FRAC_CONST(0.596007286911057) }, { FRAC_CONST(0.801146721041991), FRAC_CONST(0.598467986916314) }, { FRAC_CONST(0.799306876785086), FRAC_CONST(0.600923053912954) }, { FRAC_CONST(0.797459509147442), FRAC_CONST(0.603372464792950) }, { FRAC_CONST(0.795604635517188), FRAC_CONST(0.605816196501515) }, { FRAC_CONST(0.793742273353100), FRAC_CONST(0.608254226037314) }, { FRAC_CONST(0.791872440184440), FRAC_CONST(0.610686530452686) }, { FRAC_CONST(0.789995153610791), FRAC_CONST(0.613113086853855) }, { FRAC_CONST(0.788110431301888), FRAC_CONST(0.615533872401147) }, { FRAC_CONST(0.786218290997456), FRAC_CONST(0.617948864309208) }, { FRAC_CONST(0.784318750507039), FRAC_CONST(0.620358039847214) }, { FRAC_CONST(0.782411827709837), FRAC_CONST(0.622761376339086) }, { FRAC_CONST(0.780497540554532), FRAC_CONST(0.625158851163708) }, { FRAC_CONST(0.778575907059125), FRAC_CONST(0.627550441755132) }, { FRAC_CONST(0.776646945310762), FRAC_CONST(0.629936125602796) }, { FRAC_CONST(0.774710673465566), FRAC_CONST(0.632315880251738) }, { FRAC_CONST(0.772767109748464), FRAC_CONST(0.634689683302798) }, { FRAC_CONST(0.770816272453019), FRAC_CONST(0.637057512412839) }, { FRAC_CONST(0.768858179941253), FRAC_CONST(0.639419345294951) }, { FRAC_CONST(0.766892850643481), FRAC_CONST(0.641775159718664) }, { FRAC_CONST(0.764920303058128), FRAC_CONST(0.644124933510155) }, { FRAC_CONST(0.762940555751566), FRAC_CONST(0.646468644552458) }, { FRAC_CONST(0.760953627357928), FRAC_CONST(0.648806270785673) }, { FRAC_CONST(0.758959536578942), FRAC_CONST(0.651137790207170) }, { FRAC_CONST(0.756958302183750), FRAC_CONST(0.653463180871802) }, { FRAC_CONST(0.754949943008733), FRAC_CONST(0.655782420892106) }, { FRAC_CONST(0.752934477957330), FRAC_CONST(0.658095488438511) }, { FRAC_CONST(0.750911925999868), FRAC_CONST(0.660402361739545) }, { FRAC_CONST(0.748882306173375), FRAC_CONST(0.662703019082037) }, { FRAC_CONST(0.746845637581407), FRAC_CONST(0.664997438811325) }, { FRAC_CONST(0.744801939393863), FRAC_CONST(0.667285599331456) }, { FRAC_CONST(0.742751230846809), FRAC_CONST(0.669567479105392) }, { FRAC_CONST(0.740693531242296), FRAC_CONST(0.671843056655212) }, { FRAC_CONST(0.738628859948175), FRAC_CONST(0.674112310562312) }, { FRAC_CONST(0.736557236397919), FRAC_CONST(0.676375219467612) }, { FRAC_CONST(0.734478680090438), FRAC_CONST(0.678631762071749) }, { FRAC_CONST(0.732393210589896), FRAC_CONST(0.680881917135287) }, { FRAC_CONST(0.730300847525525), FRAC_CONST(0.683125663478909) }, { FRAC_CONST(0.728201610591445), FRAC_CONST(0.685362979983619) }, { FRAC_CONST(0.726095519546471), FRAC_CONST(0.687593845590942) }, { FRAC_CONST(0.723982594213936), FRAC_CONST(0.689818239303122) }, { FRAC_CONST(0.721862854481496), FRAC_CONST(0.692036140183319) }, { FRAC_CONST(0.719736320300951), FRAC_CONST(0.694247527355803) }, { FRAC_CONST(0.717603011688049), FRAC_CONST(0.696452380006158) }, { FRAC_CONST(0.715462948722304), FRAC_CONST(0.698650677381469) }, { FRAC_CONST(0.713316151546803), FRAC_CONST(0.700842398790526) }, { FRAC_CONST(0.711162640368018), FRAC_CONST(0.703027523604011) }, { FRAC_CONST(0.709002435455618), FRAC_CONST(0.705206031254698) }, { FRAC_CONST(0.706835557142274), FRAC_CONST(0.707377901237642) }, { FRAC_CONST(0.704662025823469), FRAC_CONST(0.709543113110377) }, { FRAC_CONST(0.702481861957308), FRAC_CONST(0.711701646493103) }, { FRAC_CONST(0.700295086064324), FRAC_CONST(0.713853481068882) }, { FRAC_CONST(0.698101718727284), FRAC_CONST(0.715998596583829) }, { FRAC_CONST(0.695901780590997), FRAC_CONST(0.718136972847297) }, { FRAC_CONST(0.693695292362118), FRAC_CONST(0.720268589732077) }, { FRAC_CONST(0.691482274808956), FRAC_CONST(0.722393427174578) }, { FRAC_CONST(0.689262748761273), FRAC_CONST(0.724511465175020) }, { FRAC_CONST(0.687036735110096), FRAC_CONST(0.726622683797623) }, { FRAC_CONST(0.684804254807511), FRAC_CONST(0.728727063170794) }, { FRAC_CONST(0.682565328866473), FRAC_CONST(0.730824583487312) }, { FRAC_CONST(0.680319978360607), FRAC_CONST(0.732915225004518) }, { FRAC_CONST(0.678068224424007), FRAC_CONST(0.734998968044497) }, { FRAC_CONST(0.675810088251037), FRAC_CONST(0.737075792994266) }, { FRAC_CONST(0.673545591096136), FRAC_CONST(0.739145680305957) }, { FRAC_CONST(0.671274754273613), FRAC_CONST(0.741208610497004) }, { FRAC_CONST(0.668997599157450), FRAC_CONST(0.743264564150321) }, { FRAC_CONST(0.666714147181098), FRAC_CONST(0.745313521914490) }, { FRAC_CONST(0.664424419837275), FRAC_CONST(0.747355464503940) }, { FRAC_CONST(0.662128438677769), FRAC_CONST(0.749390372699130) }, { FRAC_CONST(0.659826225313227), FRAC_CONST(0.751418227346727) }, { FRAC_CONST(0.657517801412960), FRAC_CONST(0.753439009359794) }, { FRAC_CONST(0.655203188704732), FRAC_CONST(0.755452699717958) }, { FRAC_CONST(0.652882408974559), FRAC_CONST(0.757459279467601) }, { FRAC_CONST(0.650555484066504), FRAC_CONST(0.759458729722028) }, { FRAC_CONST(0.648222435882470), FRAC_CONST(0.761451031661654) }, { FRAC_CONST(0.645883286381996), FRAC_CONST(0.763436166534172) }, { FRAC_CONST(0.643538057582048), FRAC_CONST(0.765414115654738) }, { FRAC_CONST(0.641186771556811), FRAC_CONST(0.767384860406142) }, { FRAC_CONST(0.638829450437486), FRAC_CONST(0.769348382238982) }, { FRAC_CONST(0.636466116412077), FRAC_CONST(0.771304662671845) }, { FRAC_CONST(0.634096791725184), FRAC_CONST(0.773253683291473) }, { FRAC_CONST(0.631721498677792), FRAC_CONST(0.775195425752941) }, { FRAC_CONST(0.629340259627066), FRAC_CONST(0.777129871779832) }, { FRAC_CONST(0.626953096986133), FRAC_CONST(0.779057003164401) }, { FRAC_CONST(0.624560033223877), FRAC_CONST(0.780976801767754) }, { FRAC_CONST(0.622161090864727), FRAC_CONST(0.782889249520015) }, { FRAC_CONST(0.619756292488441), FRAC_CONST(0.784794328420499) }, { FRAC_CONST(0.617345660729897), FRAC_CONST(0.786692020537877) }, { FRAC_CONST(0.614929218278880), FRAC_CONST(0.788582308010347) }, { FRAC_CONST(0.612506987879866), FRAC_CONST(0.790465173045805) }, { FRAC_CONST(0.610078992331810), FRAC_CONST(0.792340597922007) }, { FRAC_CONST(0.607645254487931), FRAC_CONST(0.794208564986741) }, { FRAC_CONST(0.605205797255497), FRAC_CONST(0.796069056657988) }, { FRAC_CONST(0.602760643595607), FRAC_CONST(0.797922055424093) }, { FRAC_CONST(0.600309816522980), FRAC_CONST(0.799767543843926) }, { FRAC_CONST(0.597853339105734), FRAC_CONST(0.801605504547046) }, { FRAC_CONST(0.595391234465169), FRAC_CONST(0.803435920233868) }, { FRAC_CONST(0.592923525775551), FRAC_CONST(0.805258773675822) }, { FRAC_CONST(0.590450236263896), FRAC_CONST(0.807074047715518) }, { FRAC_CONST(0.587971389209745), FRAC_CONST(0.808881725266904) }, { FRAC_CONST(0.585487007944951), FRAC_CONST(0.810681789315431) }, { FRAC_CONST(0.582997115853458), FRAC_CONST(0.812474222918210) }, { FRAC_CONST(0.580501736371077), FRAC_CONST(0.814259009204175) }, { FRAC_CONST(0.578000892985270), FRAC_CONST(0.816036131374237) }, { FRAC_CONST(0.575494609234928), FRAC_CONST(0.817805572701444) }, { FRAC_CONST(0.572982908710149), FRAC_CONST(0.819567316531142) }, { FRAC_CONST(0.570465815052013), FRAC_CONST(0.821321346281127) }, { FRAC_CONST(0.567943351952366), FRAC_CONST(0.823067645441802) }, { FRAC_CONST(0.565415543153590), FRAC_CONST(0.824806197576334) }, { FRAC_CONST(0.562882412448385), FRAC_CONST(0.826536986320810) }, { FRAC_CONST(0.560343983679541), FRAC_CONST(0.828259995384386) }, { FRAC_CONST(0.557800280739717), FRAC_CONST(0.829975208549444) }, { FRAC_CONST(0.555251327571214), FRAC_CONST(0.831682609671745) }, { FRAC_CONST(0.552697148165750), FRAC_CONST(0.833382182680580) }, { FRAC_CONST(0.550137766564234), FRAC_CONST(0.835073911578919) }, { FRAC_CONST(0.547573206856540), FRAC_CONST(0.836757780443567) }, { FRAC_CONST(0.545003493181281), FRAC_CONST(0.838433773425308) }, { FRAC_CONST(0.542428649725581), FRAC_CONST(0.840101874749058) }, { FRAC_CONST(0.539848700724848), FRAC_CONST(0.841762068714012) }, { FRAC_CONST(0.537263670462543), FRAC_CONST(0.843414339693793) }, { FRAC_CONST(0.534673583269956), FRAC_CONST(0.845058672136595) }, { FRAC_CONST(0.532078463525974), FRAC_CONST(0.846695050565337) }, { FRAC_CONST(0.529478335656852), FRAC_CONST(0.848323459577802) }, { FRAC_CONST(0.526873224135985), FRAC_CONST(0.849943883846782) }, { FRAC_CONST(0.524263153483673), FRAC_CONST(0.851556308120229) }, { FRAC_CONST(0.521648148266897), FRAC_CONST(0.853160717221390) }, { FRAC_CONST(0.519028233099081), FRAC_CONST(0.854757096048957) }, { FRAC_CONST(0.516403432639864), FRAC_CONST(0.856345429577204) }, { FRAC_CONST(0.513773771594868), FRAC_CONST(0.857925702856130) }, { FRAC_CONST(0.511139274715464), FRAC_CONST(0.859497901011602) }, { FRAC_CONST(0.508499966798541), FRAC_CONST(0.861062009245491) }, { FRAC_CONST(0.505855872686269), FRAC_CONST(0.862618012835817) }, { FRAC_CONST(0.503207017265869), FRAC_CONST(0.864165897136879) }, { FRAC_CONST(0.500553425469378), FRAC_CONST(0.865705647579402) }, { FRAC_CONST(0.497895122273411), FRAC_CONST(0.867237249670668) }, { FRAC_CONST(0.495232132698931), FRAC_CONST(0.868760688994655) }, { FRAC_CONST(0.492564481811011), FRAC_CONST(0.870275951212172) }, { FRAC_CONST(0.489892194718595), FRAC_CONST(0.871783022060993) }, { FRAC_CONST(0.487215296574269), FRAC_CONST(0.873281887355994) }, { FRAC_CONST(0.484533812574016), FRAC_CONST(0.874772532989284) }, { FRAC_CONST(0.481847767956986), FRAC_CONST(0.876254944930338) }, { FRAC_CONST(0.479157188005253), FRAC_CONST(0.877729109226132) }, { FRAC_CONST(0.476462098043581), FRAC_CONST(0.879195012001267) }, { FRAC_CONST(0.473762523439183), FRAC_CONST(0.880652639458111) }, { FRAC_CONST(0.471058489601483), FRAC_CONST(0.882101977876918) }, { FRAC_CONST(0.468350021981877), FRAC_CONST(0.883543013615962) }, { FRAC_CONST(0.465637146073494), FRAC_CONST(0.884975733111667) }, { FRAC_CONST(0.462919887410955), FRAC_CONST(0.886400122878730) }, { FRAC_CONST(0.460198271570134), FRAC_CONST(0.887816169510255) }, { FRAC_CONST(0.457472324167916), FRAC_CONST(0.889223859677868) }, { FRAC_CONST(0.454742070861955), FRAC_CONST(0.890623180131856) }, { FRAC_CONST(0.452007537350437), FRAC_CONST(0.892014117701280) }, { FRAC_CONST(0.449268749371830), FRAC_CONST(0.893396659294108) }, { FRAC_CONST(0.446525732704651), FRAC_CONST(0.894770791897330) }, { FRAC_CONST(0.443778513167218), FRAC_CONST(0.896136502577087) }, { FRAC_CONST(0.441027116617407), FRAC_CONST(0.897493778478790) }, { FRAC_CONST(0.438271568952410), FRAC_CONST(0.898842606827242) }, { FRAC_CONST(0.435511896108492), FRAC_CONST(0.900182974926757) }, { FRAC_CONST(0.432748124060744), FRAC_CONST(0.901514870161279) }, { FRAC_CONST(0.429980278822841), FRAC_CONST(0.902838279994503) }, { FRAC_CONST(0.427208386446796), FRAC_CONST(0.904153191969992) }, { FRAC_CONST(0.424432473022717), FRAC_CONST(0.905459593711293) }, { FRAC_CONST(0.421652564678558), FRAC_CONST(0.906757472922057) }, { FRAC_CONST(0.418868687579875), FRAC_CONST(0.908046817386148) }, { FRAC_CONST(0.416080867929579), FRAC_CONST(0.909327614967767) }, { FRAC_CONST(0.413289131967691), FRAC_CONST(0.910599853611559) }, { FRAC_CONST(0.410493505971093), FRAC_CONST(0.911863521342729) }, { FRAC_CONST(0.407694016253280), FRAC_CONST(0.913118606267154) }, { FRAC_CONST(0.404890689164118), FRAC_CONST(0.914365096571498) }, { FRAC_CONST(0.402083551089587), FRAC_CONST(0.915602980523320) }, { FRAC_CONST(0.399272628451541), FRAC_CONST(0.916832246471184) }, { FRAC_CONST(0.396457947707454), FRAC_CONST(0.918052882844770) }, { FRAC_CONST(0.393639535350173), FRAC_CONST(0.919264878154985) }, { FRAC_CONST(0.390817417907669), FRAC_CONST(0.920468220994067) }, { FRAC_CONST(0.387991621942785), FRAC_CONST(0.921662900035695) }, { FRAC_CONST(0.385162174052990), FRAC_CONST(0.922848904035094) }, { FRAC_CONST(0.382329100870125), FRAC_CONST(0.924026221829144) }, { FRAC_CONST(0.379492429060153), FRAC_CONST(0.925194842336480) }, { FRAC_CONST(0.376652185322910), FRAC_CONST(0.926354754557603) }, { FRAC_CONST(0.373808396391851), FRAC_CONST(0.927505947574975) }, { FRAC_CONST(0.370961089033802), FRAC_CONST(0.928648410553131) }, { FRAC_CONST(0.368110290048703), FRAC_CONST(0.929782132738772) }, { FRAC_CONST(0.365256026269360), FRAC_CONST(0.930907103460875) }, { FRAC_CONST(0.362398324561191), FRAC_CONST(0.932023312130786) }, { FRAC_CONST(0.359537211821973), FRAC_CONST(0.933130748242325) }, { FRAC_CONST(0.356672714981588), FRAC_CONST(0.934229401371881) }, { FRAC_CONST(0.353804861001772), FRAC_CONST(0.935319261178512) }, { FRAC_CONST(0.350933676875858), FRAC_CONST(0.936400317404042) }, { FRAC_CONST(0.348059189628526), FRAC_CONST(0.937472559873159) }, { FRAC_CONST(0.345181426315543), FRAC_CONST(0.938535978493509) }, { FRAC_CONST(0.342300414023514), FRAC_CONST(0.939590563255789) }, { FRAC_CONST(0.339416179869623), FRAC_CONST(0.940636304233848) }, { FRAC_CONST(0.336528751001382), FRAC_CONST(0.941673191584771) }, { FRAC_CONST(0.333638154596371), FRAC_CONST(0.942701215548982) }, { FRAC_CONST(0.330744417861983), FRAC_CONST(0.943720366450326) }, { FRAC_CONST(0.327847568035171), FRAC_CONST(0.944730634696168) }, { FRAC_CONST(0.324947632382188), FRAC_CONST(0.945732010777477) }, { FRAC_CONST(0.322044638198335), FRAC_CONST(0.946724485268921) }, { FRAC_CONST(0.319138612807696), FRAC_CONST(0.947708048828952) }, { FRAC_CONST(0.316229583562890), FRAC_CONST(0.948682692199895) }, { FRAC_CONST(0.313317577844809), FRAC_CONST(0.949648406208035) }, { FRAC_CONST(0.310402623062359), FRAC_CONST(0.950605181763705) }, { FRAC_CONST(0.307484746652204), FRAC_CONST(0.951553009861369) }, { FRAC_CONST(0.304563976078509), FRAC_CONST(0.952491881579706) }, { FRAC_CONST(0.301640338832679), FRAC_CONST(0.953421788081700) }, { FRAC_CONST(0.298713862433100), FRAC_CONST(0.954342720614716) }, { FRAC_CONST(0.295784574424884), FRAC_CONST(0.955254670510587) }, { FRAC_CONST(0.292852502379605), FRAC_CONST(0.956157629185692) }, { FRAC_CONST(0.289917673895041), FRAC_CONST(0.957051588141041) }, { FRAC_CONST(0.286980116594916), FRAC_CONST(0.957936538962351) }, { FRAC_CONST(0.284039858128637), FRAC_CONST(0.958812473320129) }, { FRAC_CONST(0.281096926171038), FRAC_CONST(0.959679382969747) }, { FRAC_CONST(0.278151348422115), FRAC_CONST(0.960537259751520) }, { FRAC_CONST(0.275203152606767), FRAC_CONST(0.961386095590786) }, { FRAC_CONST(0.272252366474537), FRAC_CONST(0.962225882497979) }, { FRAC_CONST(0.269299017799346), FRAC_CONST(0.963056612568704) }, { FRAC_CONST(0.266343134379238), FRAC_CONST(0.963878277983814) }, { FRAC_CONST(0.263384744036113), FRAC_CONST(0.964690871009481) }, { FRAC_CONST(0.260423874615468), FRAC_CONST(0.965494383997270) }, { FRAC_CONST(0.257460553986133), FRAC_CONST(0.966288809384210) }, { FRAC_CONST(0.254494810040011), FRAC_CONST(0.967074139692867) }, { FRAC_CONST(0.251526670691813), FRAC_CONST(0.967850367531414) }, { FRAC_CONST(0.248556163878797), FRAC_CONST(0.968617485593698) }, { FRAC_CONST(0.245583317560504), FRAC_CONST(0.969375486659311) }, { FRAC_CONST(0.242608159718497), FRAC_CONST(0.970124363593660) }, { FRAC_CONST(0.239630718356094), FRAC_CONST(0.970864109348029) }, { FRAC_CONST(0.236651021498106), FRAC_CONST(0.971594716959650) }, { FRAC_CONST(0.233669097190577), FRAC_CONST(0.972316179551765) }, { FRAC_CONST(0.230684973500512), FRAC_CONST(0.973028490333694) }, { FRAC_CONST(0.227698678515621), FRAC_CONST(0.973731642600896) }, { FRAC_CONST(0.224710240344050), FRAC_CONST(0.974425629735035) }, { FRAC_CONST(0.221719687114115), FRAC_CONST(0.975110445204039) }, { FRAC_CONST(0.218727046974045), FRAC_CONST(0.975786082562164) }, { FRAC_CONST(0.215732348091706), FRAC_CONST(0.976452535450054) }, { FRAC_CONST(0.212735618654346), FRAC_CONST(0.977109797594801) }, { FRAC_CONST(0.209736886868323), FRAC_CONST(0.977757862810003) }, { FRAC_CONST(0.206736180958844), FRAC_CONST(0.978396724995823) }, { FRAC_CONST(0.203733529169694), FRAC_CONST(0.979026378139048) }, { FRAC_CONST(0.200728959762976), FRAC_CONST(0.979646816313141) }, { FRAC_CONST(0.197722501018842), FRAC_CONST(0.980258033678304) }, { FRAC_CONST(0.194714181235226), FRAC_CONST(0.980860024481524) }, { FRAC_CONST(0.191704028727580), FRAC_CONST(0.981452783056636) }, { FRAC_CONST(0.188692071828605), FRAC_CONST(0.982036303824369) }, { FRAC_CONST(0.185678338887988), FRAC_CONST(0.982610581292405) }, { FRAC_CONST(0.182662858272129), FRAC_CONST(0.983175610055424) }, { FRAC_CONST(0.179645658363882), FRAC_CONST(0.983731384795162) }, { FRAC_CONST(0.176626767562281), FRAC_CONST(0.984277900280454) }, { FRAC_CONST(0.173606214282275), FRAC_CONST(0.984815151367289) }, { FRAC_CONST(0.170584026954464), FRAC_CONST(0.985343132998855) }, { FRAC_CONST(0.167560234024824), FRAC_CONST(0.985861840205587) }, { FRAC_CONST(0.164534863954446), FRAC_CONST(0.986371268105216) }, { FRAC_CONST(0.161507945219266), FRAC_CONST(0.986871411902812) }, { FRAC_CONST(0.158479506309796), FRAC_CONST(0.987362266890832) }, { FRAC_CONST(0.155449575730856), FRAC_CONST(0.987843828449162) }, { FRAC_CONST(0.152418182001307), FRAC_CONST(0.988316092045160) }, { FRAC_CONST(0.149385353653780), FRAC_CONST(0.988779053233702) }, { FRAC_CONST(0.146351119234411), FRAC_CONST(0.989232707657220) }, { FRAC_CONST(0.143315507302572), FRAC_CONST(0.989677051045747) }, { FRAC_CONST(0.140278546430595), FRAC_CONST(0.990112079216954) }, { FRAC_CONST(0.137240265203516), FRAC_CONST(0.990537788076189) }, { FRAC_CONST(0.134200692218792), FRAC_CONST(0.990954173616519) }, { FRAC_CONST(0.131159856086043), FRAC_CONST(0.991361231918763) }, { FRAC_CONST(0.128117785426777), FRAC_CONST(0.991758959151536) }, { FRAC_CONST(0.125074508874121), FRAC_CONST(0.992147351571276) }, { FRAC_CONST(0.122030055072553), FRAC_CONST(0.992526405522286) }, { FRAC_CONST(0.118984452677633), FRAC_CONST(0.992896117436766) }, { FRAC_CONST(0.115937730355728), FRAC_CONST(0.993256483834846) }, { FRAC_CONST(0.112889916783750), FRAC_CONST(0.993607501324622) }, { FRAC_CONST(0.109841040648883), FRAC_CONST(0.993949166602181) }, { FRAC_CONST(0.106791130648307), FRAC_CONST(0.994281476451642) }, { FRAC_CONST(0.103740215488939), FRAC_CONST(0.994604427745176) }, { FRAC_CONST(0.100688323887154), FRAC_CONST(0.994918017443043) }, { FRAC_CONST(0.097635484568517), FRAC_CONST(0.995222242593618) }, { FRAC_CONST(0.094581726267515), FRAC_CONST(0.995517100333418) }, { FRAC_CONST(0.091527077727285), FRAC_CONST(0.995802587887129) }, { FRAC_CONST(0.088471567699341), FRAC_CONST(0.996078702567634) }, { FRAC_CONST(0.085415224943307), FRAC_CONST(0.996345441776036) }, { FRAC_CONST(0.082358078226647), FRAC_CONST(0.996602803001684) }, { FRAC_CONST(0.079300156324388), FRAC_CONST(0.996850783822197) }, { FRAC_CONST(0.076241488018856), FRAC_CONST(0.997089381903483) }, { FRAC_CONST(0.073182102099403), FRAC_CONST(0.997318594999769) }, { FRAC_CONST(0.070122027362134), FRAC_CONST(0.997538420953611) }, { FRAC_CONST(0.067061292609637), FRAC_CONST(0.997748857695926) }, { FRAC_CONST(0.063999926650714), FRAC_CONST(0.997949903246001) }, { FRAC_CONST(0.060937958300107), FRAC_CONST(0.998141555711521) }, { FRAC_CONST(0.057875416378229), FRAC_CONST(0.998323813288578) }, { FRAC_CONST(0.054812329710890), FRAC_CONST(0.998496674261695) }, { FRAC_CONST(0.051748727129028), FRAC_CONST(0.998660137003838) }, { FRAC_CONST(0.048684637468439), FRAC_CONST(0.998814199976435) }, { FRAC_CONST(0.045620089569500), FRAC_CONST(0.998958861729386) }, { FRAC_CONST(0.042555112276904), FRAC_CONST(0.999094120901079) }, { FRAC_CONST(0.039489734439384), FRAC_CONST(0.999219976218404) }, { FRAC_CONST(0.036423984909444), FRAC_CONST(0.999336426496761) }, { FRAC_CONST(0.033357892543086), FRAC_CONST(0.999443470640078) }, { FRAC_CONST(0.030291486199539), FRAC_CONST(0.999541107640813) }, { FRAC_CONST(0.027224794740988), FRAC_CONST(0.999629336579970) }, { FRAC_CONST(0.024157847032300), FRAC_CONST(0.999708156627105) }, { FRAC_CONST(0.021090671940755), FRAC_CONST(0.999777567040333) }, { FRAC_CONST(0.018023298335774), FRAC_CONST(0.999837567166337) }, { FRAC_CONST(0.014955755088644), FRAC_CONST(0.999888156440373) }, { FRAC_CONST(0.011888071072252), FRAC_CONST(0.999929334386276) }, { FRAC_CONST(0.008820275160808), FRAC_CONST(0.999961100616463) }, { FRAC_CONST(0.005752396229574), FRAC_CONST(0.999983454831938) }, { FRAC_CONST(0.002684463154596), FRAC_CONST(0.999996396822294) } }; /* 64 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_256[] = { { FRAC_CONST(0.999995293809576), FRAC_CONST(0.003067956762966) }, { FRAC_CONST(0.999618822495179), FRAC_CONST(0.027608145778966) }, { FRAC_CONST(0.998640218180265), FRAC_CONST(0.052131704680283) }, { FRAC_CONST(0.997060070339483), FRAC_CONST(0.076623861392031) }, { FRAC_CONST(0.994879330794806), FRAC_CONST(0.101069862754828) }, { FRAC_CONST(0.992099313142192), FRAC_CONST(0.125454983411546) }, { FRAC_CONST(0.988721691960324), FRAC_CONST(0.149764534677322) }, { FRAC_CONST(0.984748501801904), FRAC_CONST(0.173983873387464) }, { FRAC_CONST(0.980182135968117), FRAC_CONST(0.198098410717954) }, { FRAC_CONST(0.975025345066994), FRAC_CONST(0.222093620973204) }, { FRAC_CONST(0.969281235356549), FRAC_CONST(0.245955050335795) }, { FRAC_CONST(0.962953266873684), FRAC_CONST(0.269668325572915) }, { FRAC_CONST(0.956045251349996), FRAC_CONST(0.293219162694259) }, { FRAC_CONST(0.948561349915730), FRAC_CONST(0.316593375556166) }, { FRAC_CONST(0.940506070593268), FRAC_CONST(0.339776884406827) }, { FRAC_CONST(0.931884265581668), FRAC_CONST(0.362755724367397) }, { FRAC_CONST(0.922701128333879), FRAC_CONST(0.385516053843919) }, { FRAC_CONST(0.912962190428398), FRAC_CONST(0.408044162864979) }, { FRAC_CONST(0.902673318237259), FRAC_CONST(0.430326481340083) }, { FRAC_CONST(0.891840709392343), FRAC_CONST(0.452349587233771) }, { FRAC_CONST(0.880470889052161), FRAC_CONST(0.474100214650550) }, { FRAC_CONST(0.868570705971341), FRAC_CONST(0.495565261825773) }, { FRAC_CONST(0.856147328375194), FRAC_CONST(0.516731799017650) }, { FRAC_CONST(0.843208239641845), FRAC_CONST(0.537587076295645) }, { FRAC_CONST(0.829761233794523), FRAC_CONST(0.558118531220556) }, { FRAC_CONST(0.815814410806734), FRAC_CONST(0.578313796411656) }, { FRAC_CONST(0.801376171723140), FRAC_CONST(0.598160706996342) }, { FRAC_CONST(0.786455213599086), FRAC_CONST(0.617647307937804) }, { FRAC_CONST(0.771060524261814), FRAC_CONST(0.636761861236284) }, { FRAC_CONST(0.755201376896537), FRAC_CONST(0.655492852999615) }, { FRAC_CONST(0.738887324460615), FRAC_CONST(0.673829000378756) }, { FRAC_CONST(0.722128193929215), FRAC_CONST(0.691759258364158) }, { FRAC_CONST(0.704934080375905), FRAC_CONST(0.709272826438866) }, { FRAC_CONST(0.687315340891759), FRAC_CONST(0.726359155084346) }, { FRAC_CONST(0.669282588346636), FRAC_CONST(0.743007952135122) }, { FRAC_CONST(0.650846684996381), FRAC_CONST(0.759209188978388) }, { FRAC_CONST(0.632018735939809), FRAC_CONST(0.774953106594874) }, { FRAC_CONST(0.612810082429410), FRAC_CONST(0.790230221437310) }, { FRAC_CONST(0.593232295039800), FRAC_CONST(0.805031331142964) }, { FRAC_CONST(0.573297166698042), FRAC_CONST(0.819347520076797) }, { FRAC_CONST(0.553016705580028), FRAC_CONST(0.833170164701913) }, { FRAC_CONST(0.532403127877198), FRAC_CONST(0.846490938774052) }, { FRAC_CONST(0.511468850437971), FRAC_CONST(0.859301818357008) }, { FRAC_CONST(0.490226483288291), FRAC_CONST(0.871595086655951) }, { FRAC_CONST(0.468688822035828), FRAC_CONST(0.883363338665732) }, { FRAC_CONST(0.446868840162374), FRAC_CONST(0.894599485631383) }, { FRAC_CONST(0.424779681209109), FRAC_CONST(0.905296759318119) }, { FRAC_CONST(0.402434650859419), FRAC_CONST(0.915448716088268) }, { FRAC_CONST(0.379847208924051), FRAC_CONST(0.925049240782678) }, { FRAC_CONST(0.357030961233430), FRAC_CONST(0.934092550404259) }, { FRAC_CONST(0.333999651442009), FRAC_CONST(0.942573197601447) }, { FRAC_CONST(0.310767152749611), FRAC_CONST(0.950486073949482) }, { FRAC_CONST(0.287347459544730), FRAC_CONST(0.957826413027533) }, { FRAC_CONST(0.263754678974832), FRAC_CONST(0.964589793289813) }, { FRAC_CONST(0.240003022448742), FRAC_CONST(0.970772140728950) }, { FRAC_CONST(0.216106797076220), FRAC_CONST(0.976369731330021) }, { FRAC_CONST(0.192080397049892), FRAC_CONST(0.981379193313755) }, { FRAC_CONST(0.167938294974731), FRAC_CONST(0.985797509167567) }, { FRAC_CONST(0.143695033150295), FRAC_CONST(0.989622017463201) }, { FRAC_CONST(0.119365214810991), FRAC_CONST(0.992850414459865) }, { FRAC_CONST(0.094963495329639), FRAC_CONST(0.995480755491927) }, { FRAC_CONST(0.070504573389614), FRAC_CONST(0.997511456140303) }, { FRAC_CONST(0.046003182130915), FRAC_CONST(0.998941293186857) }, { FRAC_CONST(0.021474080275470), FRAC_CONST(0.999769405351215) } }; #ifdef LD_DEC /* 256 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_1024[] = { { FRAC_CONST(0.999999705862882), FRAC_CONST(0.000766990318743) }, { FRAC_CONST(0.999976174986898), FRAC_CONST(0.006902858724730) }, { FRAC_CONST(0.999914995573113), FRAC_CONST(0.013038467241987) }, { FRAC_CONST(0.999816169924900), FRAC_CONST(0.019173584868323) }, { FRAC_CONST(0.999679701762988), FRAC_CONST(0.025307980620025) }, { FRAC_CONST(0.999505596225325), FRAC_CONST(0.031441423540560) }, { FRAC_CONST(0.999293859866888), FRAC_CONST(0.037573682709270) }, { FRAC_CONST(0.999044500659429), FRAC_CONST(0.043704527250063) }, { FRAC_CONST(0.998757527991183), FRAC_CONST(0.049833726340107) }, { FRAC_CONST(0.998432952666508), FRAC_CONST(0.055961049218521) }, { FRAC_CONST(0.998070786905482), FRAC_CONST(0.062086265195060) }, { FRAC_CONST(0.997671044343441), FRAC_CONST(0.068209143658806) }, { FRAC_CONST(0.997233740030466), FRAC_CONST(0.074329454086846) }, { FRAC_CONST(0.996758890430818), FRAC_CONST(0.080446966052950) }, { FRAC_CONST(0.996246513422316), FRAC_CONST(0.086561449236251) }, { FRAC_CONST(0.995696628295664), FRAC_CONST(0.092672673429913) }, { FRAC_CONST(0.995109255753726), FRAC_CONST(0.098780408549800) }, { FRAC_CONST(0.994484417910748), FRAC_CONST(0.104884424643135) }, { FRAC_CONST(0.993822138291520), FRAC_CONST(0.110984491897163) }, { FRAC_CONST(0.993122441830496), FRAC_CONST(0.117080380647801) }, { FRAC_CONST(0.992385354870852), FRAC_CONST(0.123171861388280) }, { FRAC_CONST(0.991610905163495), FRAC_CONST(0.129258704777796) }, { FRAC_CONST(0.990799121866020), FRAC_CONST(0.135340681650134) }, { FRAC_CONST(0.989950035541609), FRAC_CONST(0.141417563022303) }, { FRAC_CONST(0.989063678157882), FRAC_CONST(0.147489120103154) }, { FRAC_CONST(0.988140083085693), FRAC_CONST(0.153555124301993) }, { FRAC_CONST(0.987179285097874), FRAC_CONST(0.159615347237193) }, { FRAC_CONST(0.986181320367928), FRAC_CONST(0.165669560744784) }, { FRAC_CONST(0.985146226468662), FRAC_CONST(0.171717536887050) }, { FRAC_CONST(0.984074042370776), FRAC_CONST(0.177759047961107) }, { FRAC_CONST(0.982964808441396), FRAC_CONST(0.183793866507478) }, { FRAC_CONST(0.981818566442553), FRAC_CONST(0.189821765318656) }, { FRAC_CONST(0.980635359529608), FRAC_CONST(0.195842517447658) }, { FRAC_CONST(0.979415232249635), FRAC_CONST(0.201855896216568) }, { FRAC_CONST(0.978158230539735), FRAC_CONST(0.207861675225075) }, { FRAC_CONST(0.976864401725313), FRAC_CONST(0.213859628358994) }, { FRAC_CONST(0.975533794518291), FRAC_CONST(0.219849529798779) }, { FRAC_CONST(0.974166459015280), FRAC_CONST(0.225831154028026) }, { FRAC_CONST(0.972762446695689), FRAC_CONST(0.231804275841965) }, { FRAC_CONST(0.971321810419786), FRAC_CONST(0.237768670355934) }, { FRAC_CONST(0.969844604426715), FRAC_CONST(0.243724113013852) }, { FRAC_CONST(0.968330884332445), FRAC_CONST(0.249670379596669) }, { FRAC_CONST(0.966780707127683), FRAC_CONST(0.255607246230807) }, { FRAC_CONST(0.965194131175725), FRAC_CONST(0.261534489396596) }, { FRAC_CONST(0.963571216210257), FRAC_CONST(0.267451885936678) }, { FRAC_CONST(0.961912023333112), FRAC_CONST(0.273359213064419) }, { FRAC_CONST(0.960216615011963), FRAC_CONST(0.279256248372291) }, { FRAC_CONST(0.958485055077976), FRAC_CONST(0.285142769840249) }, { FRAC_CONST(0.956717408723403), FRAC_CONST(0.291018555844085) }, { FRAC_CONST(0.954913742499131), FRAC_CONST(0.296883385163778) }, { FRAC_CONST(0.953074124312172), FRAC_CONST(0.302737036991819) }, { FRAC_CONST(0.951198623423113), FRAC_CONST(0.308579290941525) }, { FRAC_CONST(0.949287310443502), FRAC_CONST(0.314409927055337) }, { FRAC_CONST(0.947340257333192), FRAC_CONST(0.320228725813100) }, { FRAC_CONST(0.945357537397632), FRAC_CONST(0.326035468140330) }, { FRAC_CONST(0.943339225285108), FRAC_CONST(0.331829935416461) }, { FRAC_CONST(0.941285396983929), FRAC_CONST(0.337611909483075) }, { FRAC_CONST(0.939196129819570), FRAC_CONST(0.343381172652115) }, { FRAC_CONST(0.937071502451759), FRAC_CONST(0.349137507714085) }, { FRAC_CONST(0.934911594871516), FRAC_CONST(0.354880697946223) }, { FRAC_CONST(0.932716488398140), FRAC_CONST(0.360610527120662) }, { FRAC_CONST(0.930486265676150), FRAC_CONST(0.366326779512574) }, { FRAC_CONST(0.928221010672169), FRAC_CONST(0.372029239908285) }, { FRAC_CONST(0.925920808671770), FRAC_CONST(0.377717693613386) }, { FRAC_CONST(0.923585746276257), FRAC_CONST(0.383391926460809) }, { FRAC_CONST(0.921215911399409), FRAC_CONST(0.389051724818894) }, { FRAC_CONST(0.918811393264170), FRAC_CONST(0.394696875599434) }, { FRAC_CONST(0.916372282399289), FRAC_CONST(0.400327166265690) }, { FRAC_CONST(0.913898670635912), FRAC_CONST(0.405942384840403) }, { FRAC_CONST(0.911390651104122), FRAC_CONST(0.411542319913765) }, { FRAC_CONST(0.908848318229439), FRAC_CONST(0.417126760651388) }, { FRAC_CONST(0.906271767729258), FRAC_CONST(0.422695496802233) }, { FRAC_CONST(0.903661096609248), FRAC_CONST(0.428248318706532) }, { FRAC_CONST(0.901016403159702), FRAC_CONST(0.433785017303679) }, { FRAC_CONST(0.898337786951834), FRAC_CONST(0.439305384140100) }, { FRAC_CONST(0.895625348834030), FRAC_CONST(0.444809211377105) }, { FRAC_CONST(0.892879190928052), FRAC_CONST(0.450296291798709) }, { FRAC_CONST(0.890099416625192), FRAC_CONST(0.455766418819435) }, { FRAC_CONST(0.887286130582383), FRAC_CONST(0.461219386492092) }, { FRAC_CONST(0.884439438718254), FRAC_CONST(0.466654989515531) }, { FRAC_CONST(0.881559448209144), FRAC_CONST(0.472073023242369) }, { FRAC_CONST(0.878646267485068), FRAC_CONST(0.477473283686698) }, { FRAC_CONST(0.875700006225635), FRAC_CONST(0.482855567531766) }, { FRAC_CONST(0.872720775355914), FRAC_CONST(0.488219672137627) }, { FRAC_CONST(0.869708687042266), FRAC_CONST(0.493565395548775) }, { FRAC_CONST(0.866663854688111), FRAC_CONST(0.498892536501745) }, { FRAC_CONST(0.863586392929668), FRAC_CONST(0.504200894432690) }, { FRAC_CONST(0.860476417631632), FRAC_CONST(0.509490269484936) }, { FRAC_CONST(0.857334045882816), FRAC_CONST(0.514760462516501) }, { FRAC_CONST(0.854159395991739), FRAC_CONST(0.520011275107596) }, { FRAC_CONST(0.850952587482176), FRAC_CONST(0.525242509568095) }, { FRAC_CONST(0.847713741088654), FRAC_CONST(0.530453968944976) }, { FRAC_CONST(0.844442978751911), FRAC_CONST(0.535645457029741) }, { FRAC_CONST(0.841140423614298), FRAC_CONST(0.540816778365797) }, { FRAC_CONST(0.837806200015151), FRAC_CONST(0.545967738255818) }, { FRAC_CONST(0.834440433486103), FRAC_CONST(0.551098142769075) }, { FRAC_CONST(0.831043250746362), FRAC_CONST(0.556207798748740) }, { FRAC_CONST(0.827614779697938), FRAC_CONST(0.561296513819151) }, { FRAC_CONST(0.824155149420829), FRAC_CONST(0.566364096393064) }, { FRAC_CONST(0.820664490168157), FRAC_CONST(0.571410355678857) }, { FRAC_CONST(0.817142933361273), FRAC_CONST(0.576435101687722) }, { FRAC_CONST(0.813590611584799), FRAC_CONST(0.581438145240810) }, { FRAC_CONST(0.810007658581641), FRAC_CONST(0.586419297976361) }, { FRAC_CONST(0.806394209247956), FRAC_CONST(0.591378372356788) }, { FRAC_CONST(0.802750399628069), FRAC_CONST(0.596315181675744) }, { FRAC_CONST(0.799076366909352), FRAC_CONST(0.601229540065149) }, { FRAC_CONST(0.795372249417061), FRAC_CONST(0.606121262502186) }, { FRAC_CONST(0.791638186609126), FRAC_CONST(0.610990164816272) }, { FRAC_CONST(0.787874319070900), FRAC_CONST(0.615836063695985) }, { FRAC_CONST(0.784080788509870), FRAC_CONST(0.620658776695972) }, { FRAC_CONST(0.780257737750317), FRAC_CONST(0.625458122243814) }, { FRAC_CONST(0.776405310727940), FRAC_CONST(0.630233919646864) }, { FRAC_CONST(0.772523652484441), FRAC_CONST(0.634985989099049) }, { FRAC_CONST(0.768612909162058), FRAC_CONST(0.639714151687640) }, { FRAC_CONST(0.764673227998067), FRAC_CONST(0.644418229399988) }, { FRAC_CONST(0.760704757319237), FRAC_CONST(0.649098045130226) }, { FRAC_CONST(0.756707646536246), FRAC_CONST(0.653753422685936) }, { FRAC_CONST(0.752682046138055), FRAC_CONST(0.658384186794785) }, { FRAC_CONST(0.748628107686245), FRAC_CONST(0.662990163111121) }, { FRAC_CONST(0.744545983809307), FRAC_CONST(0.667571178222540) }, { FRAC_CONST(0.740435828196898), FRAC_CONST(0.672127059656412) }, { FRAC_CONST(0.736297795594053), FRAC_CONST(0.676657635886375) }, { FRAC_CONST(0.732132041795361), FRAC_CONST(0.681162736338795) }, { FRAC_CONST(0.727938723639099), FRAC_CONST(0.685642191399187) }, { FRAC_CONST(0.723717999001324), FRAC_CONST(0.690095832418600) }, { FRAC_CONST(0.719470026789933), FRAC_CONST(0.694523491719966) }, { FRAC_CONST(0.715194966938680), FRAC_CONST(0.698925002604414) }, { FRAC_CONST(0.710892980401152), FRAC_CONST(0.703300199357549) }, { FRAC_CONST(0.706564229144710), FRAC_CONST(0.707648917255684) }, { FRAC_CONST(0.702208876144392), FRAC_CONST(0.711970992572050) }, { FRAC_CONST(0.697827085376777), FRAC_CONST(0.716266262582953) }, { FRAC_CONST(0.693419021813812), FRAC_CONST(0.720534565573905) }, { FRAC_CONST(0.688984851416597), FRAC_CONST(0.724775740845711) }, { FRAC_CONST(0.684524741129142), FRAC_CONST(0.728989628720519) }, { FRAC_CONST(0.680038858872079), FRAC_CONST(0.733176070547833) }, { FRAC_CONST(0.675527373536339), FRAC_CONST(0.737334908710483) }, { FRAC_CONST(0.670990454976794), FRAC_CONST(0.741465986630563) }, { FRAC_CONST(0.666428274005865), FRAC_CONST(0.745569148775325) }, { FRAC_CONST(0.661841002387087), FRAC_CONST(0.749644240663033) }, { FRAC_CONST(0.657228812828643), FRAC_CONST(0.753691108868781) }, { FRAC_CONST(0.652591878976863), FRAC_CONST(0.757709601030268) }, { FRAC_CONST(0.647930375409685), FRAC_CONST(0.761699565853535) }, { FRAC_CONST(0.643244477630086), FRAC_CONST(0.765660853118662) }, { FRAC_CONST(0.638534362059467), FRAC_CONST(0.769593313685423) }, { FRAC_CONST(0.633800206031017), FRAC_CONST(0.773496799498899) }, { FRAC_CONST(0.629042187783036), FRAC_CONST(0.777371163595056) }, { FRAC_CONST(0.624260486452221), FRAC_CONST(0.781216260106276) }, { FRAC_CONST(0.619455282066924), FRAC_CONST(0.785031944266848) }, { FRAC_CONST(0.614626755540375), FRAC_CONST(0.788818072418420) }, { FRAC_CONST(0.609775088663868), FRAC_CONST(0.792574502015408) }, { FRAC_CONST(0.604900464099920), FRAC_CONST(0.796301091630359) }, { FRAC_CONST(0.600003065375389), FRAC_CONST(0.799997700959282) }, { FRAC_CONST(0.595083076874570), FRAC_CONST(0.803664190826924) }, { FRAC_CONST(0.590140683832249), FRAC_CONST(0.807300423192014) }, { FRAC_CONST(0.585176072326730), FRAC_CONST(0.810906261152460) }, { FRAC_CONST(0.580189429272832), FRAC_CONST(0.814481568950499) }, { FRAC_CONST(0.575180942414845), FRAC_CONST(0.818026211977813) }, { FRAC_CONST(0.570150800319470), FRAC_CONST(0.821540056780598) }, { FRAC_CONST(0.565099192368714), FRAC_CONST(0.825022971064580) }, { FRAC_CONST(0.560026308752760), FRAC_CONST(0.828474823700007) }, { FRAC_CONST(0.554932340462810), FRAC_CONST(0.831895484726578) }, { FRAC_CONST(0.549817479283891), FRAC_CONST(0.835284825358337) }, { FRAC_CONST(0.544681917787635), FRAC_CONST(0.838642717988527) }, { FRAC_CONST(0.539525849325029), FRAC_CONST(0.841969036194388) }, { FRAC_CONST(0.534349468019138), FRAC_CONST(0.845263654741918) }, { FRAC_CONST(0.529152968757791), FRAC_CONST(0.848526449590593) }, { FRAC_CONST(0.523936547186249), FRAC_CONST(0.851757297898029) }, { FRAC_CONST(0.518700399699835), FRAC_CONST(0.854956078024615) }, { FRAC_CONST(0.513444723436544), FRAC_CONST(0.858122669538086) }, { FRAC_CONST(0.508169716269615), FRAC_CONST(0.861256953218062) }, { FRAC_CONST(0.502875576800087), FRAC_CONST(0.864358811060534) }, { FRAC_CONST(0.497562504349319), FRAC_CONST(0.867428126282307) }, { FRAC_CONST(0.492230698951486), FRAC_CONST(0.870464783325398) }, { FRAC_CONST(0.486880361346047), FRAC_CONST(0.873468667861385) }, { FRAC_CONST(0.481511692970190), FRAC_CONST(0.876439666795714) }, { FRAC_CONST(0.476124895951244), FRAC_CONST(0.879377668271953) }, { FRAC_CONST(0.470720173099072), FRAC_CONST(0.882282561676009) }, { FRAC_CONST(0.465297727898435), FRAC_CONST(0.885154237640285) }, { FRAC_CONST(0.459857764501330), FRAC_CONST(0.887992588047806) }, { FRAC_CONST(0.454400487719304), FRAC_CONST(0.890797506036281) }, { FRAC_CONST(0.448926103015743), FRAC_CONST(0.893568886002136) }, { FRAC_CONST(0.443434816498138), FRAC_CONST(0.896306623604480) }, { FRAC_CONST(0.437926834910323), FRAC_CONST(0.899010615769039) }, { FRAC_CONST(0.432402365624690), FRAC_CONST(0.901680760692038) }, { FRAC_CONST(0.426861616634386), FRAC_CONST(0.904316957844028) }, { FRAC_CONST(0.421304796545480), FRAC_CONST(0.906919107973678) }, { FRAC_CONST(0.415732114569105), FRAC_CONST(0.909487113111505) }, { FRAC_CONST(0.410143780513590), FRAC_CONST(0.912020876573568) }, { FRAC_CONST(0.404540004776553), FRAC_CONST(0.914520302965104) }, { FRAC_CONST(0.398920998336983), FRAC_CONST(0.916985298184123) }, { FRAC_CONST(0.393286972747297), FRAC_CONST(0.919415769424947) }, { FRAC_CONST(0.387638140125373), FRAC_CONST(0.921811625181708) }, { FRAC_CONST(0.381974713146567), FRAC_CONST(0.924172775251791) }, { FRAC_CONST(0.376296905035705), FRAC_CONST(0.926499130739231) }, { FRAC_CONST(0.370604929559052), FRAC_CONST(0.928790604058057) }, { FRAC_CONST(0.364899001016267), FRAC_CONST(0.931047108935595) }, { FRAC_CONST(0.359179334232337), FRAC_CONST(0.933268560415712) }, { FRAC_CONST(0.353446144549481), FRAC_CONST(0.935454874862015) }, { FRAC_CONST(0.347699647819051), FRAC_CONST(0.937605969961000) }, { FRAC_CONST(0.341940060393402), FRAC_CONST(0.939721764725153) }, { FRAC_CONST(0.336167599117745), FRAC_CONST(0.941802179495998) }, { FRAC_CONST(0.330382481321983), FRAC_CONST(0.943847135947093) }, { FRAC_CONST(0.324584924812532), FRAC_CONST(0.945856557086984) }, { FRAC_CONST(0.318775147864118), FRAC_CONST(0.947830367262101) }, { FRAC_CONST(0.312953369211560), FRAC_CONST(0.949768492159607) }, { FRAC_CONST(0.307119808041533), FRAC_CONST(0.951670858810194) }, { FRAC_CONST(0.301274683984318), FRAC_CONST(0.953537395590833) }, { FRAC_CONST(0.295418217105532), FRAC_CONST(0.955368032227470) }, { FRAC_CONST(0.289550627897843), FRAC_CONST(0.957162699797670) }, { FRAC_CONST(0.283672137272669), FRAC_CONST(0.958921330733213) }, { FRAC_CONST(0.277782966551858), FRAC_CONST(0.960643858822638) }, { FRAC_CONST(0.271883337459360), FRAC_CONST(0.962330219213737) }, { FRAC_CONST(0.265973472112876), FRAC_CONST(0.963980348415994) }, { FRAC_CONST(0.260053593015495), FRAC_CONST(0.965594184302977) }, { FRAC_CONST(0.254123923047321), FRAC_CONST(0.967171666114677) }, { FRAC_CONST(0.248184685457075), FRAC_CONST(0.968712734459795) }, { FRAC_CONST(0.242236103853696), FRAC_CONST(0.970217331317979) }, { FRAC_CONST(0.236278402197920), FRAC_CONST(0.971685400042009) }, { FRAC_CONST(0.230311804793846), FRAC_CONST(0.973116885359925) }, { FRAC_CONST(0.224336536280494), FRAC_CONST(0.974511733377116) }, { FRAC_CONST(0.218352821623346), FRAC_CONST(0.975869891578341) }, { FRAC_CONST(0.212360886105879), FRAC_CONST(0.977191308829712) }, { FRAC_CONST(0.206360955321076), FRAC_CONST(0.978475935380617) }, { FRAC_CONST(0.200353255162940), FRAC_CONST(0.979723722865591) }, { FRAC_CONST(0.194338011817989), FRAC_CONST(0.980934624306142) }, { FRAC_CONST(0.188315451756732), FRAC_CONST(0.982108594112514) }, { FRAC_CONST(0.182285801725153), FRAC_CONST(0.983245588085407) }, { FRAC_CONST(0.176249288736168), FRAC_CONST(0.984345563417642) }, { FRAC_CONST(0.170206140061078), FRAC_CONST(0.985408478695768) }, { FRAC_CONST(0.164156583221016), FRAC_CONST(0.986434293901627) }, { FRAC_CONST(0.158100845978377), FRAC_CONST(0.987422970413855) }, { FRAC_CONST(0.152039156328246), FRAC_CONST(0.988374471009341) }, { FRAC_CONST(0.145971742489812), FRAC_CONST(0.989288759864625) }, { FRAC_CONST(0.139898832897777), FRAC_CONST(0.990165802557248) }, { FRAC_CONST(0.133820656193755), FRAC_CONST(0.991005566067049) }, { FRAC_CONST(0.127737441217662), FRAC_CONST(0.991808018777406) }, { FRAC_CONST(0.121649416999106), FRAC_CONST(0.992573130476429) }, { FRAC_CONST(0.115556812748755), FRAC_CONST(0.993300872358093) }, { FRAC_CONST(0.109459857849718), FRAC_CONST(0.993991217023329) }, { FRAC_CONST(0.103358781848900), FRAC_CONST(0.994644138481051) }, { FRAC_CONST(0.097253814448363), FRAC_CONST(0.995259612149133) }, { FRAC_CONST(0.091145185496681), FRAC_CONST(0.995837614855342) }, { FRAC_CONST(0.085033124980280), FRAC_CONST(0.996378124838200) }, { FRAC_CONST(0.078917863014785), FRAC_CONST(0.996881121747814) }, { FRAC_CONST(0.072799629836352), FRAC_CONST(0.997346586646633) }, { FRAC_CONST(0.066678655793002), FRAC_CONST(0.997774502010168) }, { FRAC_CONST(0.060555171335948), FRAC_CONST(0.998164851727646) }, { FRAC_CONST(0.054429407010919), FRAC_CONST(0.998517621102622) }, { FRAC_CONST(0.048301593449480), FRAC_CONST(0.998832796853528) }, { FRAC_CONST(0.042171961360348), FRAC_CONST(0.999110367114175) }, { FRAC_CONST(0.036040741520706), FRAC_CONST(0.999350321434199) }, { FRAC_CONST(0.029908164767517), FRAC_CONST(0.999552650779457) }, { FRAC_CONST(0.023774461988828), FRAC_CONST(0.999717347532362) }, { FRAC_CONST(0.017639864115082), FRAC_CONST(0.999844405492175) }, { FRAC_CONST(0.011504602110423), FRAC_CONST(0.999933819875236) }, { FRAC_CONST(0.005368906963996), FRAC_CONST(0.999985587315143) } }; #endif // LD_DEC #ifdef ALLOW_SMALL_FRAMELENGTH /* 480 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_1920[] = { { FRAC_CONST(0.999999916334328), FRAC_CONST(0.000409061532028) }, { FRAC_CONST(0.999993223088129), FRAC_CONST(0.003681545574400) }, { FRAC_CONST(0.999975820717897), FRAC_CONST(0.006953990190376) }, { FRAC_CONST(0.999947709409999), FRAC_CONST(0.010226360334704) }, { FRAC_CONST(0.999908889465485), FRAC_CONST(0.013498620962929) }, { FRAC_CONST(0.999859361300084), FRAC_CONST(0.016770737031768) }, { FRAC_CONST(0.999799125444203), FRAC_CONST(0.020042673499487) }, { FRAC_CONST(0.999728182542920), FRAC_CONST(0.023314395326274) }, { FRAC_CONST(0.999646533355977), FRAC_CONST(0.026585867474619) }, { FRAC_CONST(0.999554178757770), FRAC_CONST(0.029857054909681) }, { FRAC_CONST(0.999451119737344), FRAC_CONST(0.033127922599673) }, { FRAC_CONST(0.999337357398377), FRAC_CONST(0.036398435516228) }, { FRAC_CONST(0.999212892959173), FRAC_CONST(0.039668558634781) }, { FRAC_CONST(0.999077727752645), FRAC_CONST(0.042938256934941) }, { FRAC_CONST(0.998931863226306), FRAC_CONST(0.046207495400865) }, { FRAC_CONST(0.998775300942246), FRAC_CONST(0.049476239021636) }, { FRAC_CONST(0.998608042577122), FRAC_CONST(0.052744452791636) }, { FRAC_CONST(0.998430089922136), FRAC_CONST(0.056012101710921) }, { FRAC_CONST(0.998241444883019), FRAC_CONST(0.059279150785597) }, { FRAC_CONST(0.998042109480008), FRAC_CONST(0.062545565028192) }, { FRAC_CONST(0.997832085847824), FRAC_CONST(0.065811309458034) }, { FRAC_CONST(0.997611376235651), FRAC_CONST(0.069076349101624) }, { FRAC_CONST(0.997379983007114), FRAC_CONST(0.072340648993011) }, { FRAC_CONST(0.997137908640245), FRAC_CONST(0.075604174174166) }, { FRAC_CONST(0.996885155727469), FRAC_CONST(0.078866889695354) }, { FRAC_CONST(0.996621726975566), FRAC_CONST(0.082128760615515) }, { FRAC_CONST(0.996347625205645), FRAC_CONST(0.085389752002632) }, { FRAC_CONST(0.996062853353117), FRAC_CONST(0.088649828934106) }, { FRAC_CONST(0.995767414467660), FRAC_CONST(0.091908956497133) }, { FRAC_CONST(0.995461311713186), FRAC_CONST(0.095167099789075) }, { FRAC_CONST(0.995144548367810), FRAC_CONST(0.098424223917834) }, { FRAC_CONST(0.994817127823813), FRAC_CONST(0.101680294002229) }, { FRAC_CONST(0.994479053587606), FRAC_CONST(0.104935275172364) }, { FRAC_CONST(0.994130329279692), FRAC_CONST(0.108189132570007) }, { FRAC_CONST(0.993770958634630), FRAC_CONST(0.111441831348957) }, { FRAC_CONST(0.993400945500988), FRAC_CONST(0.114693336675426) }, { FRAC_CONST(0.993020293841312), FRAC_CONST(0.117943613728403) }, { FRAC_CONST(0.992629007732074), FRAC_CONST(0.121192627700032) }, { FRAC_CONST(0.992227091363634), FRAC_CONST(0.124440343795983) }, { FRAC_CONST(0.991814549040194), FRAC_CONST(0.127686727235827) }, { FRAC_CONST(0.991391385179751), FRAC_CONST(0.130931743253405) }, { FRAC_CONST(0.990957604314048), FRAC_CONST(0.134175357097202) }, { FRAC_CONST(0.990513211088533), FRAC_CONST(0.137417534030720) }, { FRAC_CONST(0.990058210262297), FRAC_CONST(0.140658239332849) }, { FRAC_CONST(0.989592606708036), FRAC_CONST(0.143897438298239) }, { FRAC_CONST(0.989116405411988), FRAC_CONST(0.147135096237670) }, { FRAC_CONST(0.988629611473887), FRAC_CONST(0.150371178478428) }, { FRAC_CONST(0.988132230106905), FRAC_CONST(0.153605650364672) }, { FRAC_CONST(0.987624266637598), FRAC_CONST(0.156838477257806) }, { FRAC_CONST(0.987105726505845), FRAC_CONST(0.160069624536852) }, { FRAC_CONST(0.986576615264794), FRAC_CONST(0.163299057598817) }, { FRAC_CONST(0.986036938580803), FRAC_CONST(0.166526741859069) }, { FRAC_CONST(0.985486702233375), FRAC_CONST(0.169752642751702) }, { FRAC_CONST(0.984925912115099), FRAC_CONST(0.172976725729910) }, { FRAC_CONST(0.984354574231587), FRAC_CONST(0.176198956266353) }, { FRAC_CONST(0.983772694701407), FRAC_CONST(0.179419299853531) }, { FRAC_CONST(0.983180279756024), FRAC_CONST(0.182637722004152) }, { FRAC_CONST(0.982577335739725), FRAC_CONST(0.185854188251500) }, { FRAC_CONST(0.981963869109555), FRAC_CONST(0.189068664149806) }, { FRAC_CONST(0.981339886435250), FRAC_CONST(0.192281115274616) }, { FRAC_CONST(0.980705394399163), FRAC_CONST(0.195491507223158) }, { FRAC_CONST(0.980060399796194), FRAC_CONST(0.198699805614714) }, { FRAC_CONST(0.979404909533716), FRAC_CONST(0.201905976090986) }, { FRAC_CONST(0.978738930631504), FRAC_CONST(0.205109984316464) }, { FRAC_CONST(0.978062470221657), FRAC_CONST(0.208311795978794) }, { FRAC_CONST(0.977375535548522), FRAC_CONST(0.211511376789145) }, { FRAC_CONST(0.976678133968618), FRAC_CONST(0.214708692482577) }, { FRAC_CONST(0.975970272950556), FRAC_CONST(0.217903708818409) }, { FRAC_CONST(0.975251960074958), FRAC_CONST(0.221096391580581) }, { FRAC_CONST(0.974523203034377), FRAC_CONST(0.224286706578026) }, { FRAC_CONST(0.973784009633218), FRAC_CONST(0.227474619645035) }, { FRAC_CONST(0.973034387787646), FRAC_CONST(0.230660096641619) }, { FRAC_CONST(0.972274345525510), FRAC_CONST(0.233843103453878) }, { FRAC_CONST(0.971503890986252), FRAC_CONST(0.237023605994367) }, { FRAC_CONST(0.970723032420820), FRAC_CONST(0.240201570202459) }, { FRAC_CONST(0.969931778191584), FRAC_CONST(0.243376962044711) }, { FRAC_CONST(0.969130136772239), FRAC_CONST(0.246549747515226) }, { FRAC_CONST(0.968318116747721), FRAC_CONST(0.249719892636022) }, { FRAC_CONST(0.967495726814114), FRAC_CONST(0.252887363457390) }, { FRAC_CONST(0.966662975778551), FRAC_CONST(0.256052126058264) }, { FRAC_CONST(0.965819872559127), FRAC_CONST(0.259214146546579) }, { FRAC_CONST(0.964966426184802), FRAC_CONST(0.262373391059634) }, { FRAC_CONST(0.964102645795299), FRAC_CONST(0.265529825764461) }, { FRAC_CONST(0.963228540641012), FRAC_CONST(0.268683416858178) }, { FRAC_CONST(0.962344120082907), FRAC_CONST(0.271834130568359) }, { FRAC_CONST(0.961449393592416), FRAC_CONST(0.274981933153391) }, { FRAC_CONST(0.960544370751341), FRAC_CONST(0.278126790902837) }, { FRAC_CONST(0.959629061251750), FRAC_CONST(0.281268670137799) }, { FRAC_CONST(0.958703474895872), FRAC_CONST(0.284407537211272) }, { FRAC_CONST(0.957767621595993), FRAC_CONST(0.287543358508512) }, { FRAC_CONST(0.956821511374351), FRAC_CONST(0.290676100447394) }, { FRAC_CONST(0.955865154363025), FRAC_CONST(0.293805729478766) }, { FRAC_CONST(0.954898560803832), FRAC_CONST(0.296932212086818) }, { FRAC_CONST(0.953921741048211), FRAC_CONST(0.300055514789431) }, { FRAC_CONST(0.952934705557117), FRAC_CONST(0.303175604138543) }, { FRAC_CONST(0.951937464900908), FRAC_CONST(0.306292446720504) }, { FRAC_CONST(0.950930029759229), FRAC_CONST(0.309406009156434) }, { FRAC_CONST(0.949912410920903), FRAC_CONST(0.312516258102580) }, { FRAC_CONST(0.948884619283808), FRAC_CONST(0.315623160250676) }, { FRAC_CONST(0.947846665854767), FRAC_CONST(0.318726682328294) }, { FRAC_CONST(0.946798561749429), FRAC_CONST(0.321826791099207) }, { FRAC_CONST(0.945740318192145), FRAC_CONST(0.324923453363742) }, { FRAC_CONST(0.944671946515855), FRAC_CONST(0.328016635959131) }, { FRAC_CONST(0.943593458161960), FRAC_CONST(0.331106305759876) }, { FRAC_CONST(0.942504864680205), FRAC_CONST(0.334192429678095) }, { FRAC_CONST(0.941406177728551), FRAC_CONST(0.337274974663880) }, { FRAC_CONST(0.940297409073052), FRAC_CONST(0.340353907705650) }, { FRAC_CONST(0.939178570587730), FRAC_CONST(0.343429195830507) }, { FRAC_CONST(0.938049674254446), FRAC_CONST(0.346500806104585) }, { FRAC_CONST(0.936910732162774), FRAC_CONST(0.349568705633406) }, { FRAC_CONST(0.935761756509868), FRAC_CONST(0.352632861562230) }, { FRAC_CONST(0.934602759600334), FRAC_CONST(0.355693241076410) }, { FRAC_CONST(0.933433753846097), FRAC_CONST(0.358749811401739) }, { FRAC_CONST(0.932254751766271), FRAC_CONST(0.361802539804806) }, { FRAC_CONST(0.931065765987021), FRAC_CONST(0.364851393593340) }, { FRAC_CONST(0.929866809241428), FRAC_CONST(0.367896340116568) }, { FRAC_CONST(0.928657894369357), FRAC_CONST(0.370937346765559) }, { FRAC_CONST(0.927439034317314), FRAC_CONST(0.373974380973575) }, { FRAC_CONST(0.926210242138311), FRAC_CONST(0.377007410216418) }, { FRAC_CONST(0.924971530991726), FRAC_CONST(0.380036402012783) }, { FRAC_CONST(0.923722914143160), FRAC_CONST(0.383061323924602) }, { FRAC_CONST(0.922464404964295), FRAC_CONST(0.386082143557389) }, { FRAC_CONST(0.921196016932755), FRAC_CONST(0.389098828560595) }, { FRAC_CONST(0.919917763631956), FRAC_CONST(0.392111346627946) }, { FRAC_CONST(0.918629658750963), FRAC_CONST(0.395119665497795) }, { FRAC_CONST(0.917331716084346), FRAC_CONST(0.398123752953462) }, { FRAC_CONST(0.916023949532027), FRAC_CONST(0.401123576823585) }, { FRAC_CONST(0.914706373099136), FRAC_CONST(0.404119104982459) }, { FRAC_CONST(0.913379000895858), FRAC_CONST(0.407110305350386) }, { FRAC_CONST(0.912041847137282), FRAC_CONST(0.410097145894012) }, { FRAC_CONST(0.910694926143251), FRAC_CONST(0.413079594626675) }, { FRAC_CONST(0.909338252338207), FRAC_CONST(0.416057619608744) }, { FRAC_CONST(0.907971840251037), FRAC_CONST(0.419031188947965) }, { FRAC_CONST(0.906595704514915), FRAC_CONST(0.422000270799800) }, { FRAC_CONST(0.905209859867151), FRAC_CONST(0.424964833367766) }, { FRAC_CONST(0.903814321149027), FRAC_CONST(0.427924844903780) }, { FRAC_CONST(0.902409103305641), FRAC_CONST(0.430880273708497) }, { FRAC_CONST(0.900994221385748), FRAC_CONST(0.433831088131649) }, { FRAC_CONST(0.899569690541596), FRAC_CONST(0.436777256572384) }, { FRAC_CONST(0.898135526028766), FRAC_CONST(0.439718747479604) }, { FRAC_CONST(0.896691743206008), FRAC_CONST(0.442655529352306) }, { FRAC_CONST(0.895238357535076), FRAC_CONST(0.445587570739915) }, { FRAC_CONST(0.893775384580563), FRAC_CONST(0.448514840242624) }, { FRAC_CONST(0.892302840009734), FRAC_CONST(0.451437306511726) }, { FRAC_CONST(0.890820739592359), FRAC_CONST(0.454354938249958) }, { FRAC_CONST(0.889329099200541), FRAC_CONST(0.457267704211826) }, { FRAC_CONST(0.887827934808551), FRAC_CONST(0.460175573203949) }, { FRAC_CONST(0.886317262492655), FRAC_CONST(0.463078514085383) }, { FRAC_CONST(0.884797098430938), FRAC_CONST(0.465976495767966) }, { FRAC_CONST(0.883267458903136), FRAC_CONST(0.468869487216642) }, { FRAC_CONST(0.881728360290461), FRAC_CONST(0.471757457449795) }, { FRAC_CONST(0.880179819075421), FRAC_CONST(0.474640375539586) }, { FRAC_CONST(0.878621851841649), FRAC_CONST(0.477518210612278) }, { FRAC_CONST(0.877054475273722), FRAC_CONST(0.480390931848569) }, { FRAC_CONST(0.875477706156984), FRAC_CONST(0.483258508483922) }, { FRAC_CONST(0.873891561377366), FRAC_CONST(0.486120909808896) }, { FRAC_CONST(0.872296057921204), FRAC_CONST(0.488978105169472) }, { FRAC_CONST(0.870691212875058), FRAC_CONST(0.491830063967383) }, { FRAC_CONST(0.869077043425529), FRAC_CONST(0.494676755660442) }, { FRAC_CONST(0.867453566859076), FRAC_CONST(0.497518149762867) }, { FRAC_CONST(0.865820800561827), FRAC_CONST(0.500354215845611) }, { FRAC_CONST(0.864178762019399), FRAC_CONST(0.503184923536685) }, { FRAC_CONST(0.862527468816704), FRAC_CONST(0.506010242521482) }, { FRAC_CONST(0.860866938637767), FRAC_CONST(0.508830142543107) }, { FRAC_CONST(0.859197189265532), FRAC_CONST(0.511644593402696) }, { FRAC_CONST(0.857518238581672), FRAC_CONST(0.514453564959741) }, { FRAC_CONST(0.855830104566401), FRAC_CONST(0.517257027132414) }, { FRAC_CONST(0.854132805298278), FRAC_CONST(0.520054949897887) }, { FRAC_CONST(0.852426358954015), FRAC_CONST(0.522847303292655) }, { FRAC_CONST(0.850710783808280), FRAC_CONST(0.525634057412856) }, { FRAC_CONST(0.848986098233506), FRAC_CONST(0.528415182414593) }, { FRAC_CONST(0.847252320699689), FRAC_CONST(0.531190648514252) }, { FRAC_CONST(0.845509469774194), FRAC_CONST(0.533960425988819) }, { FRAC_CONST(0.843757564121554), FRAC_CONST(0.536724485176205) }, { FRAC_CONST(0.841996622503271), FRAC_CONST(0.539482796475555) }, { FRAC_CONST(0.840226663777615), FRAC_CONST(0.542235330347571) }, { FRAC_CONST(0.838447706899422), FRAC_CONST(0.544982057314827) }, { FRAC_CONST(0.836659770919891), FRAC_CONST(0.547722947962084) }, { FRAC_CONST(0.834862874986380), FRAC_CONST(0.550457972936605) }, { FRAC_CONST(0.833057038342201), FRAC_CONST(0.553187102948470) }, { FRAC_CONST(0.831242280326413), FRAC_CONST(0.555910308770889) }, { FRAC_CONST(0.829418620373617), FRAC_CONST(0.558627561240515) }, { FRAC_CONST(0.827586078013746), FRAC_CONST(0.561338831257758) }, { FRAC_CONST(0.825744672871856), FRAC_CONST(0.564044089787093) }, { FRAC_CONST(0.823894424667918), FRAC_CONST(0.566743307857377) }, { FRAC_CONST(0.822035353216601), FRAC_CONST(0.569436456562150) }, { FRAC_CONST(0.820167478427070), FRAC_CONST(0.572123507059955) }, { FRAC_CONST(0.818290820302761), FRAC_CONST(0.574804430574639) }, { FRAC_CONST(0.816405398941175), FRAC_CONST(0.577479198395666) }, { FRAC_CONST(0.814511234533661), FRAC_CONST(0.580147781878420) }, { FRAC_CONST(0.812608347365198), FRAC_CONST(0.582810152444517) }, { FRAC_CONST(0.810696757814178), FRAC_CONST(0.585466281582107) }, { FRAC_CONST(0.808776486352191), FRAC_CONST(0.588116140846181) }, { FRAC_CONST(0.806847553543799), FRAC_CONST(0.590759701858874) }, { FRAC_CONST(0.804909980046325), FRAC_CONST(0.593396936309773) }, { FRAC_CONST(0.802963786609623), FRAC_CONST(0.596027815956215) }, { FRAC_CONST(0.801008994075862), FRAC_CONST(0.598652312623592) }, { FRAC_CONST(0.799045623379300), FRAC_CONST(0.601270398205654) }, { FRAC_CONST(0.797073695546059), FRAC_CONST(0.603882044664808) }, { FRAC_CONST(0.795093231693901), FRAC_CONST(0.606487224032418) }, { FRAC_CONST(0.793104253032005), FRAC_CONST(0.609085908409106) }, { FRAC_CONST(0.791106780860733), FRAC_CONST(0.611678069965050) }, { FRAC_CONST(0.789100836571407), FRAC_CONST(0.614263680940283) }, { FRAC_CONST(0.787086441646080), FRAC_CONST(0.616842713644988) }, { FRAC_CONST(0.785063617657302), FRAC_CONST(0.619415140459796) }, { FRAC_CONST(0.783032386267894), FRAC_CONST(0.621980933836084) }, { FRAC_CONST(0.780992769230711), FRAC_CONST(0.624540066296266) }, { FRAC_CONST(0.778944788388414), FRAC_CONST(0.627092510434089) }, { FRAC_CONST(0.776888465673232), FRAC_CONST(0.629638238914927) }, { FRAC_CONST(0.774823823106730), FRAC_CONST(0.632177224476073) }, { FRAC_CONST(0.772750882799570), FRAC_CONST(0.634709439927031) }, { FRAC_CONST(0.770669666951277), FRAC_CONST(0.637234858149809) }, { FRAC_CONST(0.768580197850002), FRAC_CONST(0.639753452099206) }, { FRAC_CONST(0.766482497872280), FRAC_CONST(0.642265194803105) }, { FRAC_CONST(0.764376589482793), FRAC_CONST(0.644770059362758) }, { FRAC_CONST(0.762262495234126), FRAC_CONST(0.647268018953079) }, { FRAC_CONST(0.760140237766532), FRAC_CONST(0.649759046822928) }, { FRAC_CONST(0.758009839807683), FRAC_CONST(0.652243116295397) }, { FRAC_CONST(0.755871324172429), FRAC_CONST(0.654720200768098) }, { FRAC_CONST(0.753724713762555), FRAC_CONST(0.657190273713446) }, { FRAC_CONST(0.751570031566534), FRAC_CONST(0.659653308678945) }, { FRAC_CONST(0.749407300659280), FRAC_CONST(0.662109279287469) }, { FRAC_CONST(0.747236544201905), FRAC_CONST(0.664558159237545) }, { FRAC_CONST(0.745057785441466), FRAC_CONST(0.666999922303638) }, { FRAC_CONST(0.742871047710719), FRAC_CONST(0.669434542336425) }, { FRAC_CONST(0.740676354427868), FRAC_CONST(0.671861993263083) }, { FRAC_CONST(0.738473729096316), FRAC_CONST(0.674282249087562) }, { FRAC_CONST(0.736263195304409), FRAC_CONST(0.676695283890867) }, { FRAC_CONST(0.734044776725190), FRAC_CONST(0.679101071831334) }, { FRAC_CONST(0.731818497116138), FRAC_CONST(0.681499587144906) }, { FRAC_CONST(0.729584380318920), FRAC_CONST(0.683890804145412) }, { FRAC_CONST(0.727342450259131), FRAC_CONST(0.686274697224838) }, { FRAC_CONST(0.725092730946042), FRAC_CONST(0.688651240853606) }, { FRAC_CONST(0.722835246472338), FRAC_CONST(0.691020409580841) }, { FRAC_CONST(0.720570021013866), FRAC_CONST(0.693382178034651) }, { FRAC_CONST(0.718297078829369), FRAC_CONST(0.695736520922392) }, { FRAC_CONST(0.716016444260233), FRAC_CONST(0.698083413030944) }, { FRAC_CONST(0.713728141730222), FRAC_CONST(0.700422829226978) }, { FRAC_CONST(0.711432195745216), FRAC_CONST(0.702754744457225) }, { FRAC_CONST(0.709128630892954), FRAC_CONST(0.705079133748748) }, { FRAC_CONST(0.706817471842764), FRAC_CONST(0.707395972209203) }, { FRAC_CONST(0.704498743345302), FRAC_CONST(0.709705235027113) }, { FRAC_CONST(0.702172470232289), FRAC_CONST(0.712006897472128) }, { FRAC_CONST(0.699838677416240), FRAC_CONST(0.714300934895292) }, { FRAC_CONST(0.697497389890200), FRAC_CONST(0.716587322729308) }, { FRAC_CONST(0.695148632727480), FRAC_CONST(0.718866036488799) }, { FRAC_CONST(0.692792431081381), FRAC_CONST(0.721137051770570) }, { FRAC_CONST(0.690428810184929), FRAC_CONST(0.723400344253874) }, { FRAC_CONST(0.688057795350606), FRAC_CONST(0.725655889700665) }, { FRAC_CONST(0.685679411970075), FRAC_CONST(0.727903663955865) }, { FRAC_CONST(0.683293685513912), FRAC_CONST(0.730143642947616) }, { FRAC_CONST(0.680900641531330), FRAC_CONST(0.732375802687543) }, { FRAC_CONST(0.678500305649909), FRAC_CONST(0.734600119271009) }, { FRAC_CONST(0.676092703575316), FRAC_CONST(0.736816568877370) }, { FRAC_CONST(0.673677861091036), FRAC_CONST(0.739025127770231) }, { FRAC_CONST(0.671255804058092), FRAC_CONST(0.741225772297702) }, { FRAC_CONST(0.668826558414768), FRAC_CONST(0.743418478892647) }, { FRAC_CONST(0.666390150176334), FRAC_CONST(0.745603224072940) }, { FRAC_CONST(0.663946605434765), FRAC_CONST(0.747779984441716) }, { FRAC_CONST(0.661495950358462), FRAC_CONST(0.749948736687619) }, { FRAC_CONST(0.659038211191971), FRAC_CONST(0.752109457585056) }, { FRAC_CONST(0.656573414255705), FRAC_CONST(0.754262123994441) }, { FRAC_CONST(0.654101585945659), FRAC_CONST(0.756406712862448) }, { FRAC_CONST(0.651622752733128), FRAC_CONST(0.758543201222251) }, { FRAC_CONST(0.649136941164425), FRAC_CONST(0.760671566193777) }, { FRAC_CONST(0.646644177860593), FRAC_CONST(0.762791784983948) }, { FRAC_CONST(0.644144489517126), FRAC_CONST(0.764903834886923) }, { FRAC_CONST(0.641637902903677), FRAC_CONST(0.767007693284345) }, { FRAC_CONST(0.639124444863776), FRAC_CONST(0.769103337645580) }, { FRAC_CONST(0.636604142314538), FRAC_CONST(0.771190745527961) }, { FRAC_CONST(0.634077022246379), FRAC_CONST(0.773269894577026) }, { FRAC_CONST(0.631543111722725), FRAC_CONST(0.775340762526760) }, { FRAC_CONST(0.629002437879721), FRAC_CONST(0.777403327199831) }, { FRAC_CONST(0.626455027925944), FRAC_CONST(0.779457566507828) }, { FRAC_CONST(0.623900909142107), FRAC_CONST(0.781503458451498) }, { FRAC_CONST(0.621340108880771), FRAC_CONST(0.783540981120982) }, { FRAC_CONST(0.618772654566049), FRAC_CONST(0.785570112696050) }, { FRAC_CONST(0.616198573693314), FRAC_CONST(0.787590831446332) }, { FRAC_CONST(0.613617893828905), FRAC_CONST(0.789603115731555) }, { FRAC_CONST(0.611030642609828), FRAC_CONST(0.791606944001769) }, { FRAC_CONST(0.608436847743468), FRAC_CONST(0.793602294797585) }, { FRAC_CONST(0.605836537007281), FRAC_CONST(0.795589146750397) }, { FRAC_CONST(0.603229738248508), FRAC_CONST(0.797567478582619) }, { FRAC_CONST(0.600616479383869), FRAC_CONST(0.799537269107905) }, { FRAC_CONST(0.597996788399267), FRAC_CONST(0.801498497231381) }, { FRAC_CONST(0.595370693349487), FRAC_CONST(0.803451141949871) }, { FRAC_CONST(0.592738222357898), FRAC_CONST(0.805395182352117) }, { FRAC_CONST(0.590099403616149), FRAC_CONST(0.807330597619008) }, { FRAC_CONST(0.587454265383869), FRAC_CONST(0.809257367023803) }, { FRAC_CONST(0.584802835988364), FRAC_CONST(0.811175469932349) }, { FRAC_CONST(0.582145143824311), FRAC_CONST(0.813084885803304) }, { FRAC_CONST(0.579481217353460), FRAC_CONST(0.814985594188359) }, { FRAC_CONST(0.576811085104321), FRAC_CONST(0.816877574732454) }, { FRAC_CONST(0.574134775671867), FRAC_CONST(0.818760807173997) }, { FRAC_CONST(0.571452317717222), FRAC_CONST(0.820635271345081) }, { FRAC_CONST(0.568763739967354), FRAC_CONST(0.822500947171703) }, { FRAC_CONST(0.566069071214772), FRAC_CONST(0.824357814673971) }, { FRAC_CONST(0.563368340317214), FRAC_CONST(0.826205853966327) }, { FRAC_CONST(0.560661576197336), FRAC_CONST(0.828045045257756) }, { FRAC_CONST(0.557948807842409), FRAC_CONST(0.829875368851995) }, { FRAC_CONST(0.555230064304002), FRAC_CONST(0.831696805147750) }, { FRAC_CONST(0.552505374697674), FRAC_CONST(0.833509334638900) }, { FRAC_CONST(0.549774768202663), FRAC_CONST(0.835312937914713) }, { FRAC_CONST(0.547038274061568), FRAC_CONST(0.837107595660044) }, { FRAC_CONST(0.544295921580046), FRAC_CONST(0.838893288655553) }, { FRAC_CONST(0.541547740126486), FRAC_CONST(0.840669997777901) }, { FRAC_CONST(0.538793759131706), FRAC_CONST(0.842437703999961) }, { FRAC_CONST(0.536034008088628), FRAC_CONST(0.844196388391019) }, { FRAC_CONST(0.533268516551970), FRAC_CONST(0.845946032116980) }, { FRAC_CONST(0.530497314137923), FRAC_CONST(0.847686616440563) }, { FRAC_CONST(0.527720430523840), FRAC_CONST(0.849418122721510) }, { FRAC_CONST(0.524937895447912), FRAC_CONST(0.851140532416778) }, { FRAC_CONST(0.522149738708856), FRAC_CONST(0.852853827080745) }, { FRAC_CONST(0.519355990165590), FRAC_CONST(0.854557988365401) }, { FRAC_CONST(0.516556679736915), FRAC_CONST(0.856252998020546) }, { FRAC_CONST(0.513751837401199), FRAC_CONST(0.857938837893991) }, { FRAC_CONST(0.510941493196049), FRAC_CONST(0.859615489931744) }, { FRAC_CONST(0.508125677217994), FRAC_CONST(0.861282936178208) }, { FRAC_CONST(0.505304419622159), FRAC_CONST(0.862941158776375) }, { FRAC_CONST(0.502477750621949), FRAC_CONST(0.864590139968012) }, { FRAC_CONST(0.499645700488717), FRAC_CONST(0.866229862093855) }, { FRAC_CONST(0.496808299551444), FRAC_CONST(0.867860307593799) }, { FRAC_CONST(0.493965578196415), FRAC_CONST(0.869481459007080) }, { FRAC_CONST(0.491117566866892), FRAC_CONST(0.871093298972471) }, { FRAC_CONST(0.488264296062789), FRAC_CONST(0.872695810228461) }, { FRAC_CONST(0.485405796340343), FRAC_CONST(0.874288975613440) }, { FRAC_CONST(0.482542098311789), FRAC_CONST(0.875872778065888) }, { FRAC_CONST(0.479673232645033), FRAC_CONST(0.877447200624553) }, { FRAC_CONST(0.476799230063322), FRAC_CONST(0.879012226428633) }, { FRAC_CONST(0.473920121344914), FRAC_CONST(0.880567838717962) }, { FRAC_CONST(0.471035937322751), FRAC_CONST(0.882114020833179) }, { FRAC_CONST(0.468146708884125), FRAC_CONST(0.883650756215917) }, { FRAC_CONST(0.465252466970353), FRAC_CONST(0.885178028408975) }, { FRAC_CONST(0.462353242576441), FRAC_CONST(0.886695821056495) }, { FRAC_CONST(0.459449066750752), FRAC_CONST(0.888204117904136) }, { FRAC_CONST(0.456539970594675), FRAC_CONST(0.889702902799251) }, { FRAC_CONST(0.453625985262295), FRAC_CONST(0.891192159691058) }, { FRAC_CONST(0.450707141960053), FRAC_CONST(0.892671872630812) }, { FRAC_CONST(0.447783471946415), FRAC_CONST(0.894142025771977) }, { FRAC_CONST(0.444855006531538), FRAC_CONST(0.895602603370393) }, { FRAC_CONST(0.441921777076935), FRAC_CONST(0.897053589784447) }, { FRAC_CONST(0.438983814995137), FRAC_CONST(0.898494969475242) }, { FRAC_CONST(0.436041151749356), FRAC_CONST(0.899926727006758) }, { FRAC_CONST(0.433093818853152), FRAC_CONST(0.901348847046022) }, { FRAC_CONST(0.430141847870093), FRAC_CONST(0.902761314363272) }, { FRAC_CONST(0.427185270413416), FRAC_CONST(0.904164113832116) }, { FRAC_CONST(0.424224118145690), FRAC_CONST(0.905557230429701) }, { FRAC_CONST(0.421258422778478), FRAC_CONST(0.906940649236866) }, { FRAC_CONST(0.418288216071994), FRAC_CONST(0.908314355438308) }, { FRAC_CONST(0.415313529834766), FRAC_CONST(0.909678334322736) }, { FRAC_CONST(0.412334395923293), FRAC_CONST(0.911032571283032) }, { FRAC_CONST(0.409350846241706), FRAC_CONST(0.912377051816407) }, { FRAC_CONST(0.406362912741425), FRAC_CONST(0.913711761524555) }, { FRAC_CONST(0.403370627420818), FRAC_CONST(0.915036686113806) }, { FRAC_CONST(0.400374022324857), FRAC_CONST(0.916351811395282) }, { FRAC_CONST(0.397373129544774), FRAC_CONST(0.917657123285050) }, { FRAC_CONST(0.394367981217720), FRAC_CONST(0.918952607804266) }, { FRAC_CONST(0.391358609526420), FRAC_CONST(0.920238251079332) }, { FRAC_CONST(0.388345046698826), FRAC_CONST(0.921514039342042) }, { FRAC_CONST(0.385327325007776), FRAC_CONST(0.922779958929729) }, { FRAC_CONST(0.382305476770645), FRAC_CONST(0.924035996285410) }, { FRAC_CONST(0.379279534348999), FRAC_CONST(0.925282137957935) }, { FRAC_CONST(0.376249530148250), FRAC_CONST(0.926518370602127) }, { FRAC_CONST(0.373215496617310), FRAC_CONST(0.927744680978929) }, { FRAC_CONST(0.370177466248239), FRAC_CONST(0.928961055955541) }, { FRAC_CONST(0.367135471575903), FRAC_CONST(0.930167482505564) }, { FRAC_CONST(0.364089545177621), FRAC_CONST(0.931363947709140) }, { FRAC_CONST(0.361039719672816), FRAC_CONST(0.932550438753087) }, { FRAC_CONST(0.357986027722671), FRAC_CONST(0.933726942931039) }, { FRAC_CONST(0.354928502029772), FRAC_CONST(0.934893447643582) }, { FRAC_CONST(0.351867175337763), FRAC_CONST(0.936049940398387) }, { FRAC_CONST(0.348802080430994), FRAC_CONST(0.937196408810347) }, { FRAC_CONST(0.345733250134169), FRAC_CONST(0.938332840601705) }, { FRAC_CONST(0.342660717311994), FRAC_CONST(0.939459223602190) }, { FRAC_CONST(0.339584514868829), FRAC_CONST(0.940575545749145) }, { FRAC_CONST(0.336504675748328), FRAC_CONST(0.941681795087657) }, { FRAC_CONST(0.333421232933097), FRAC_CONST(0.942777959770684) }, { FRAC_CONST(0.330334219444328), FRAC_CONST(0.943864028059183) }, { FRAC_CONST(0.327243668341457), FRAC_CONST(0.944939988322235) }, { FRAC_CONST(0.324149612721804), FRAC_CONST(0.946005829037171) }, { FRAC_CONST(0.321052085720218), FRAC_CONST(0.947061538789691) }, { FRAC_CONST(0.317951120508725), FRAC_CONST(0.948107106273994) }, { FRAC_CONST(0.314846750296171), FRAC_CONST(0.949142520292891) }, { FRAC_CONST(0.311739008327867), FRAC_CONST(0.950167769757930) }, { FRAC_CONST(0.308627927885232), FRAC_CONST(0.951182843689513) }, { FRAC_CONST(0.305513542285440), FRAC_CONST(0.952187731217013) }, { FRAC_CONST(0.302395884881056), FRAC_CONST(0.953182421578893) }, { FRAC_CONST(0.299274989059689), FRAC_CONST(0.954166904122818) }, { FRAC_CONST(0.296150888243624), FRAC_CONST(0.955141168305771) }, { FRAC_CONST(0.293023615889471), FRAC_CONST(0.956105203694164) }, { FRAC_CONST(0.289893205487806), FRAC_CONST(0.957058999963955) }, { FRAC_CONST(0.286759690562807), FRAC_CONST(0.958002546900750) }, { FRAC_CONST(0.283623104671904), FRAC_CONST(0.958935834399920) }, { FRAC_CONST(0.280483481405410), FRAC_CONST(0.959858852466706) }, { FRAC_CONST(0.277340854386169), FRAC_CONST(0.960771591216325) }, { FRAC_CONST(0.274195257269191), FRAC_CONST(0.961674040874080) }, { FRAC_CONST(0.271046723741295), FRAC_CONST(0.962566191775459) }, { FRAC_CONST(0.267895287520743), FRAC_CONST(0.963448034366243) }, { FRAC_CONST(0.264740982356888), FRAC_CONST(0.964319559202607) }, { FRAC_CONST(0.261583842029803), FRAC_CONST(0.965180756951218) }, { FRAC_CONST(0.258423900349924), FRAC_CONST(0.966031618389343) }, { FRAC_CONST(0.255261191157689), FRAC_CONST(0.966872134404937) }, { FRAC_CONST(0.252095748323171), FRAC_CONST(0.967702295996750) }, { FRAC_CONST(0.248927605745720), FRAC_CONST(0.968522094274417) }, { FRAC_CONST(0.245756797353599), FRAC_CONST(0.969331520458559) }, { FRAC_CONST(0.242583357103617), FRAC_CONST(0.970130565880871) }, { FRAC_CONST(0.239407318980770), FRAC_CONST(0.970919221984218) }, { FRAC_CONST(0.236228716997876), FRAC_CONST(0.971697480322728) }, { FRAC_CONST(0.233047585195206), FRAC_CONST(0.972465332561878) }, { FRAC_CONST(0.229863957640129), FRAC_CONST(0.973222770478587) }, { FRAC_CONST(0.226677868426735), FRAC_CONST(0.973969785961306) }, { FRAC_CONST(0.223489351675482), FRAC_CONST(0.974706371010097) }, { FRAC_CONST(0.220298441532823), FRAC_CONST(0.975432517736727) }, { FRAC_CONST(0.217105172170841), FRAC_CONST(0.976148218364747) }, { FRAC_CONST(0.213909577786886), FRAC_CONST(0.976853465229579) }, { FRAC_CONST(0.210711692603206), FRAC_CONST(0.977548250778596) }, { FRAC_CONST(0.207511550866582), FRAC_CONST(0.978232567571202) }, { FRAC_CONST(0.204309186847962), FRAC_CONST(0.978906408278914) }, { FRAC_CONST(0.201104634842092), FRAC_CONST(0.979569765685441) }, { FRAC_CONST(0.197897929167148), FRAC_CONST(0.980222632686756) }, { FRAC_CONST(0.194689104164373), FRAC_CONST(0.980865002291179) }, { FRAC_CONST(0.191478194197704), FRAC_CONST(0.981496867619447) }, { FRAC_CONST(0.188265233653407), FRAC_CONST(0.982118221904791) }, { FRAC_CONST(0.185050256939710), FRAC_CONST(0.982729058493005) }, { FRAC_CONST(0.181833298486427), FRAC_CONST(0.983329370842520) }, { FRAC_CONST(0.178614392744603), FRAC_CONST(0.983919152524473) }, { FRAC_CONST(0.175393574186129), FRAC_CONST(0.984498397222776) }, { FRAC_CONST(0.172170877303385), FRAC_CONST(0.985067098734184) }, { FRAC_CONST(0.168946336608867), FRAC_CONST(0.985625250968360) }, { FRAC_CONST(0.165719986634814), FRAC_CONST(0.986172847947943) }, { FRAC_CONST(0.162491861932842), FRAC_CONST(0.986709883808609) }, { FRAC_CONST(0.159261997073573), FRAC_CONST(0.987236352799134) }, { FRAC_CONST(0.156030426646266), FRAC_CONST(0.987752249281460) }, { FRAC_CONST(0.152797185258443), FRAC_CONST(0.988257567730749) }, { FRAC_CONST(0.149562307535523), FRAC_CONST(0.988752302735447) }, { FRAC_CONST(0.146325828120446), FRAC_CONST(0.989236448997339) }, { FRAC_CONST(0.143087781673307), FRAC_CONST(0.989710001331608) }, { FRAC_CONST(0.139848202870981), FRAC_CONST(0.990172954666889) }, { FRAC_CONST(0.136607126406757), FRAC_CONST(0.990625304045323) }, { FRAC_CONST(0.133364586989957), FRAC_CONST(0.991067044622612) }, { FRAC_CONST(0.130120619345575), FRAC_CONST(0.991498171668069) }, { FRAC_CONST(0.126875258213898), FRAC_CONST(0.991918680564670) }, { FRAC_CONST(0.123628538350136), FRAC_CONST(0.992328566809103) }, { FRAC_CONST(0.120380494524051), FRAC_CONST(0.992727826011815) }, { FRAC_CONST(0.117131161519582), FRAC_CONST(0.993116453897061) }, { FRAC_CONST(0.113880574134475), FRAC_CONST(0.993494446302948) }, { FRAC_CONST(0.110628767179910), FRAC_CONST(0.993861799181482) }, { FRAC_CONST(0.107375775480128), FRAC_CONST(0.994218508598608) }, { FRAC_CONST(0.104121633872055), FRAC_CONST(0.994564570734255) }, { FRAC_CONST(0.100866377204933), FRAC_CONST(0.994899981882376) }, { FRAC_CONST(0.097610040339947), FRAC_CONST(0.995224738450986) }, { FRAC_CONST(0.094352658149849), FRAC_CONST(0.995538836962204) }, { FRAC_CONST(0.091094265518583), FRAC_CONST(0.995842274052287) }, { FRAC_CONST(0.087834897340919), FRAC_CONST(0.996135046471667) }, { FRAC_CONST(0.084574588522070), FRAC_CONST(0.996417151084987) }, { FRAC_CONST(0.081313373977324), FRAC_CONST(0.996688584871134) }, { FRAC_CONST(0.078051288631670), FRAC_CONST(0.996949344923269) }, { FRAC_CONST(0.074788367419420), FRAC_CONST(0.997199428448862) }, { FRAC_CONST(0.071524645283840), FRAC_CONST(0.997438832769720) }, { FRAC_CONST(0.068260157176771), FRAC_CONST(0.997667555322013) }, { FRAC_CONST(0.064994938058259), FRAC_CONST(0.997885593656308) }, { FRAC_CONST(0.061729022896176), FRAC_CONST(0.998092945437590) }, { FRAC_CONST(0.058462446665851), FRAC_CONST(0.998289608445286) }, { FRAC_CONST(0.055195244349690), FRAC_CONST(0.998475580573295) }, { FRAC_CONST(0.051927450936806), FRAC_CONST(0.998650859830004) }, { FRAC_CONST(0.048659101422640), FRAC_CONST(0.998815444338313) }, { FRAC_CONST(0.045390230808591), FRAC_CONST(0.998969332335654) }, { FRAC_CONST(0.042120874101635), FRAC_CONST(0.999112522174011) }, { FRAC_CONST(0.038851066313958), FRAC_CONST(0.999245012319936) }, { FRAC_CONST(0.035580842462574), FRAC_CONST(0.999366801354564) }, { FRAC_CONST(0.032310237568951), FRAC_CONST(0.999477887973635) }, { FRAC_CONST(0.029039286658643), FRAC_CONST(0.999578270987499) }, { FRAC_CONST(0.025768024760904), FRAC_CONST(0.999667949321134) }, { FRAC_CONST(0.022496486908322), FRAC_CONST(0.999746922014158) }, { FRAC_CONST(0.019224708136438), FRAC_CONST(0.999815188220837) }, { FRAC_CONST(0.015952723483375), FRAC_CONST(0.999872747210095) }, { FRAC_CONST(0.012680567989461), FRAC_CONST(0.999919598365521) }, { FRAC_CONST(0.009408276696850), FRAC_CONST(0.999955741185376) }, { FRAC_CONST(0.006135884649155), FRAC_CONST(0.999981175282601) }, { FRAC_CONST(0.002863426891064), FRAC_CONST(0.999995900384816) } }; #ifdef LD_DEC /* 240 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_960[] = { { FRAC_CONST(0.999999665337326), FRAC_CONST(0.000818122995607) }, { FRAC_CONST(0.999972892444367), FRAC_CONST(0.007363041249780) }, { FRAC_CONST(0.999903284040864), FRAC_CONST(0.013907644095771) }, { FRAC_CONST(0.999790843108610), FRAC_CONST(0.020451651184577) }, { FRAC_CONST(0.999635574464198), FRAC_CONST(0.026994782192715) }, { FRAC_CONST(0.999437484758823), FRAC_CONST(0.033536756834230) }, { FRAC_CONST(0.999196582477986), FRAC_CONST(0.040077294872701) }, { FRAC_CONST(0.998912877941140), FRAC_CONST(0.046616116133247) }, { FRAC_CONST(0.998586383301244), FRAC_CONST(0.053152940514528) }, { FRAC_CONST(0.998217112544241), FRAC_CONST(0.059687488000744) }, { FRAC_CONST(0.997805081488460), FRAC_CONST(0.066219478673630) }, { FRAC_CONST(0.997350307783942), FRAC_CONST(0.072748632724445) }, { FRAC_CONST(0.996852810911678), FRAC_CONST(0.079274670465961) }, { FRAC_CONST(0.996312612182778), FRAC_CONST(0.085797312344440) }, { FRAC_CONST(0.995729734737558), FRAC_CONST(0.092316278951614) }, { FRAC_CONST(0.995104203544548), FRAC_CONST(0.098831291036650) }, { FRAC_CONST(0.994436045399422), FRAC_CONST(0.105342069518114) }, { FRAC_CONST(0.993725288923851), FRAC_CONST(0.111848335495926) }, { FRAC_CONST(0.992971964564277), FRAC_CONST(0.118349810263305) }, { FRAC_CONST(0.992176104590608), FRAC_CONST(0.124846215318711) }, { FRAC_CONST(0.991337743094838), FRAC_CONST(0.131337272377774) }, { FRAC_CONST(0.990456915989581), FRAC_CONST(0.137822703385212) }, { FRAC_CONST(0.989533661006540), FRAC_CONST(0.144302230526747) }, { FRAC_CONST(0.988568017694885), FRAC_CONST(0.150775576241001) }, { FRAC_CONST(0.987560027419562), FRAC_CONST(0.157242463231389) }, { FRAC_CONST(0.986509733359519), FRAC_CONST(0.163702614477995) }, { FRAC_CONST(0.985417180505858), FRAC_CONST(0.170155753249442) }, { FRAC_CONST(0.984282415659907), FRAC_CONST(0.176601603114742) }, { FRAC_CONST(0.983105487431216), FRAC_CONST(0.183039887955141) }, { FRAC_CONST(0.981886446235473), FRAC_CONST(0.189470331975943) }, { FRAC_CONST(0.980625344292344), FRAC_CONST(0.195892659718330) }, { FRAC_CONST(0.979322235623241), FRAC_CONST(0.202306596071156) }, { FRAC_CONST(0.977977176049000), FRAC_CONST(0.208711866282735) }, { FRAC_CONST(0.976590223187499), FRAC_CONST(0.215108195972610) }, { FRAC_CONST(0.975161436451181), FRAC_CONST(0.221495311143304) }, { FRAC_CONST(0.973690877044515), FRAC_CONST(0.227872938192063) }, { FRAC_CONST(0.972178607961371), FRAC_CONST(0.234240803922570) }, { FRAC_CONST(0.970624693982323), FRAC_CONST(0.240598635556650) }, { FRAC_CONST(0.969029201671875), FRAC_CONST(0.246946160745958) }, { FRAC_CONST(0.967392199375607), FRAC_CONST(0.253283107583640) }, { FRAC_CONST(0.965713757217249), FRAC_CONST(0.259609204615985) }, { FRAC_CONST(0.963993947095677), FRAC_CONST(0.265924180854051) }, { FRAC_CONST(0.962232842681832), FRAC_CONST(0.272227765785273) }, { FRAC_CONST(0.960430519415566), FRAC_CONST(0.278519689385053) }, { FRAC_CONST(0.958587054502409), FRAC_CONST(0.284799682128326) }, { FRAC_CONST(0.956702526910263), FRAC_CONST(0.291067475001103) }, { FRAC_CONST(0.954777017366017), FRAC_CONST(0.297322799511998) }, { FRAC_CONST(0.952810608352092), FRAC_CONST(0.303565387703730) }, { FRAC_CONST(0.950803384102905), FRAC_CONST(0.309794972164597) }, { FRAC_CONST(0.948755430601263), FRAC_CONST(0.316011286039934) }, { FRAC_CONST(0.946666835574676), FRAC_CONST(0.322214063043544) }, { FRAC_CONST(0.944537688491606), FRAC_CONST(0.328403037469105) }, { FRAC_CONST(0.942368080557626), FRAC_CONST(0.334577944201551) }, { FRAC_CONST(0.940158104711519), FRAC_CONST(0.340738518728429) }, { FRAC_CONST(0.937907855621296), FRAC_CONST(0.346884497151231) }, { FRAC_CONST(0.935617429680138), FRAC_CONST(0.353015616196696) }, { FRAC_CONST(0.933286925002268), FRAC_CONST(0.359131613228090) }, { FRAC_CONST(0.930916441418752), FRAC_CONST(0.365232226256457) }, { FRAC_CONST(0.928506080473216), FRAC_CONST(0.371317193951838) }, { FRAC_CONST(0.926055945417500), FRAC_CONST(0.377386255654469) }, { FRAC_CONST(0.923566141207236), FRAC_CONST(0.383439151385947) }, { FRAC_CONST(0.921036774497350), FRAC_CONST(0.389475621860365) }, { FRAC_CONST(0.918467953637492), FRAC_CONST(0.395495408495417) }, { FRAC_CONST(0.915859788667400), FRAC_CONST(0.401498253423481) }, { FRAC_CONST(0.913212391312179), FRAC_CONST(0.407483899502658) }, { FRAC_CONST(0.910525874977521), FRAC_CONST(0.413452090327791) }, { FRAC_CONST(0.907800354744844), FRAC_CONST(0.419402570241451) }, { FRAC_CONST(0.905035947366364), FRAC_CONST(0.425335084344881) }, { FRAC_CONST(0.902232771260093), FRAC_CONST(0.431249378508924) }, { FRAC_CONST(0.899390946504764), FRAC_CONST(0.437145199384900) }, { FRAC_CONST(0.896510594834693), FRAC_CONST(0.443022294415467) }, { FRAC_CONST(0.893591839634558), FRAC_CONST(0.448880411845433) }, { FRAC_CONST(0.890634805934118), FRAC_CONST(0.454719300732547) }, { FRAC_CONST(0.887639620402854), FRAC_CONST(0.460538710958240) }, { FRAC_CONST(0.884606411344546), FRAC_CONST(0.466338393238348) }, { FRAC_CONST(0.881535308691775), FRAC_CONST(0.472118099133784) }, { FRAC_CONST(0.878426444000357), FRAC_CONST(0.477877581061184) }, { FRAC_CONST(0.875279950443708), FRAC_CONST(0.483616592303511) }, { FRAC_CONST(0.872095962807140), FRAC_CONST(0.489334887020625) }, { FRAC_CONST(0.868874617482085), FRAC_CONST(0.495032220259813) }, { FRAC_CONST(0.865616052460258), FRAC_CONST(0.500708347966279) }, { FRAC_CONST(0.862320407327736), FRAC_CONST(0.506363026993605) }, { FRAC_CONST(0.858987823258990), FRAC_CONST(0.511996015114162) }, { FRAC_CONST(0.855618443010829), FRAC_CONST(0.517607071029487) }, { FRAC_CONST(0.852212410916289), FRAC_CONST(0.523195954380619) }, { FRAC_CONST(0.848769872878448), FRAC_CONST(0.528762425758396) }, { FRAC_CONST(0.845290976364179), FRAC_CONST(0.534306246713712) }, { FRAC_CONST(0.841775870397828), FRAC_CONST(0.539827179767727) }, { FRAC_CONST(0.838224705554838), FRAC_CONST(0.545324988422046) }, { FRAC_CONST(0.834637633955290), FRAC_CONST(0.550799437168844) }, { FRAC_CONST(0.831014809257393), FRAC_CONST(0.556250291500956) }, { FRAC_CONST(0.827356386650900), FRAC_CONST(0.561677317921925) }, { FRAC_CONST(0.823662522850458), FRAC_CONST(0.567080283956001) }, { FRAC_CONST(0.819933376088899), FRAC_CONST(0.572458958158102) }, { FRAC_CONST(0.816169106110459), FRAC_CONST(0.577813110123727) }, { FRAC_CONST(0.812369874163934), FRAC_CONST(0.583142510498826) }, { FRAC_CONST(0.808535842995778), FRAC_CONST(0.588446930989624) }, { FRAC_CONST(0.804667176843123), FRAC_CONST(0.593726144372402) }, { FRAC_CONST(0.800764041426753), FRAC_CONST(0.598979924503229) }, { FRAC_CONST(0.796826603943998), FRAC_CONST(0.604208046327650) }, { FRAC_CONST(0.792855033061574), FRAC_CONST(0.609410285890327) }, { FRAC_CONST(0.788849498908361), FRAC_CONST(0.614586420344631) }, { FRAC_CONST(0.784810173068109), FRAC_CONST(0.619736227962191) }, { FRAC_CONST(0.780737228572094), FRAC_CONST(0.624859488142386) }, { FRAC_CONST(0.776630839891703), FRAC_CONST(0.629955981421804) }, { FRAC_CONST(0.772491182930959), FRAC_CONST(0.635025489483633) }, { FRAC_CONST(0.768318435018988), FRAC_CONST(0.640067795167023) }, { FRAC_CONST(0.764112774902423), FRAC_CONST(0.645082682476378) }, { FRAC_CONST(0.759874382737746), FRAC_CONST(0.650069936590618) }, { FRAC_CONST(0.755603440083571), FRAC_CONST(0.655029343872374) }, { FRAC_CONST(0.751300129892866), FRAC_CONST(0.659960691877147) }, { FRAC_CONST(0.746964636505118), FRAC_CONST(0.664863769362399) }, { FRAC_CONST(0.742597145638433), FRAC_CONST(0.669738366296610) }, { FRAC_CONST(0.738197844381584), FRAC_CONST(0.674584273868271) }, { FRAC_CONST(0.733766921185995), FRAC_CONST(0.679401284494831) }, { FRAC_CONST(0.729304565857668), FRAC_CONST(0.684189191831585) }, { FRAC_CONST(0.724810969549055), FRAC_CONST(0.688947790780520) }, { FRAC_CONST(0.720286324750863), FRAC_CONST(0.693676877499095) }, { FRAC_CONST(0.715730825283819), FRAC_CONST(0.698376249408973) }, { FRAC_CONST(0.711144666290356), FRAC_CONST(0.703045705204703) }, { FRAC_CONST(0.706528044226263), FRAC_CONST(0.707685044862340) }, { FRAC_CONST(0.701881156852263), FRAC_CONST(0.712294069648014) }, { FRAC_CONST(0.697204203225545), FRAC_CONST(0.716872582126442) }, { FRAC_CONST(0.692497383691237), FRAC_CONST(0.721420386169390) }, { FRAC_CONST(0.687760899873822), FRAC_CONST(0.725937286964068) }, { FRAC_CONST(0.682994954668502), FRAC_CONST(0.730423091021479) }, { FRAC_CONST(0.678199752232508), FRAC_CONST(0.734877606184707) }, { FRAC_CONST(0.673375497976352), FRAC_CONST(0.739300641637149) }, { FRAC_CONST(0.668522398555031), FRAC_CONST(0.743692007910687) }, { FRAC_CONST(0.663640661859171), FRAC_CONST(0.748051516893805) }, { FRAC_CONST(0.658730497006124), FRAC_CONST(0.752378981839648) }, { FRAC_CONST(0.653792114331011), FRAC_CONST(0.756674217374021) }, { FRAC_CONST(0.648825725377709), FRAC_CONST(0.760937039503328) }, { FRAC_CONST(0.643831542889792), FRAC_CONST(0.765167265622459) }, { FRAC_CONST(0.638809780801414), FRAC_CONST(0.769364714522605) }, { FRAC_CONST(0.633760654228152), FRAC_CONST(0.773529206399025) }, { FRAC_CONST(0.628684379457781), FRAC_CONST(0.777660562858748) }, { FRAC_CONST(0.623581173941019), FRAC_CONST(0.781758606928213) }, { FRAC_CONST(0.618451256282204), FRAC_CONST(0.785823163060853) }, { FRAC_CONST(0.613294846229936), FRAC_CONST(0.789854057144609) }, { FRAC_CONST(0.608112164667659), FRAC_CONST(0.793851116509396) }, { FRAC_CONST(0.602903433604202), FRAC_CONST(0.797814169934493) }, { FRAC_CONST(0.597668876164268), FRAC_CONST(0.801743047655882) }, { FRAC_CONST(0.592408716578875), FRAC_CONST(0.805637581373517) }, { FRAC_CONST(0.587123180175754), FRAC_CONST(0.809497604258536) }, { FRAC_CONST(0.581812493369691), FRAC_CONST(0.813322950960406) }, { FRAC_CONST(0.576476883652835), FRAC_CONST(0.817113457614006) }, { FRAC_CONST(0.571116579584947), FRAC_CONST(0.820868961846646) }, { FRAC_CONST(0.565731810783613), FRAC_CONST(0.824589302785025) }, { FRAC_CONST(0.560322807914407), FRAC_CONST(0.828274321062119) }, { FRAC_CONST(0.554889802681009), FRAC_CONST(0.831923858824010) }, { FRAC_CONST(0.549433027815281), FRAC_CONST(0.835537759736646) }, { FRAC_CONST(0.543952717067296), FRAC_CONST(0.839115868992540) }, { FRAC_CONST(0.538449105195327), FRAC_CONST(0.842658033317402) }, { FRAC_CONST(0.532922427955790), FRAC_CONST(0.846164100976699) }, { FRAC_CONST(0.527372922093142), FRAC_CONST(0.849633921782164) }, { FRAC_CONST(0.521800825329746), FRAC_CONST(0.853067347098221) }, { FRAC_CONST(0.516206376355680), FRAC_CONST(0.856464229848356) }, { FRAC_CONST(0.510589814818519), FRAC_CONST(0.859824424521420) }, { FRAC_CONST(0.504951381313066), FRAC_CONST(0.863147787177854) }, { FRAC_CONST(0.499291317371047), FRAC_CONST(0.866434175455865) }, { FRAC_CONST(0.493609865450762), FRAC_CONST(0.869683448577516) }, { FRAC_CONST(0.487907268926702), FRAC_CONST(0.872895467354761) }, { FRAC_CONST(0.482183772079123), FRAC_CONST(0.876070094195407) }, { FRAC_CONST(0.476439620083580), FRAC_CONST(0.879207193109004) }, { FRAC_CONST(0.470675059000427), FRAC_CONST(0.882306629712678) }, { FRAC_CONST(0.464890335764274), FRAC_CONST(0.885368271236879) }, { FRAC_CONST(0.459085698173413), FRAC_CONST(0.888391986531075) }, { FRAC_CONST(0.453261394879198), FRAC_CONST(0.891377646069366) }, { FRAC_CONST(0.447417675375397), FRAC_CONST(0.894325121956035) }, { FRAC_CONST(0.441554789987504), FRAC_CONST(0.897234287931024) }, { FRAC_CONST(0.435672989862017), FRAC_CONST(0.900105019375345) }, { FRAC_CONST(0.429772526955677), FRAC_CONST(0.902937193316419) }, { FRAC_CONST(0.423853654024676), FRAC_CONST(0.905730688433339) }, { FRAC_CONST(0.417916624613831), FRAC_CONST(0.908485385062073) }, { FRAC_CONST(0.411961693045722), FRAC_CONST(0.911201165200584) }, { FRAC_CONST(0.405989114409798), FRAC_CONST(0.913877912513892) }, { FRAC_CONST(0.399999144551449), FRAC_CONST(0.916515512339049) }, { FRAC_CONST(0.393992040061048), FRAC_CONST(0.919113851690058) }, { FRAC_CONST(0.387968058262959), FRAC_CONST(0.921672819262709) }, { FRAC_CONST(0.381927457204511), FRAC_CONST(0.924192305439348) }, { FRAC_CONST(0.375870495644949), FRAC_CONST(0.926672202293573) }, { FRAC_CONST(0.369797433044349), FRAC_CONST(0.929112403594856) }, { FRAC_CONST(0.363708529552499), FRAC_CONST(0.931512804813095) }, { FRAC_CONST(0.357604045997758), FRAC_CONST(0.933873303123091) }, { FRAC_CONST(0.351484243875885), FRAC_CONST(0.936193797408954) }, { FRAC_CONST(0.345349385338836), FRAC_CONST(0.938474188268430) }, { FRAC_CONST(0.339199733183530), FRAC_CONST(0.940714378017165) }, { FRAC_CONST(0.333035550840599), FRAC_CONST(0.942914270692887) }, { FRAC_CONST(0.326857102363098), FRAC_CONST(0.945073772059514) }, { FRAC_CONST(0.320664652415198), FRAC_CONST(0.947192789611197) }, { FRAC_CONST(0.314458466260842), FRAC_CONST(0.949271232576274) }, { FRAC_CONST(0.308238809752391), FRAC_CONST(0.951309011921168) }, { FRAC_CONST(0.302005949319228), FRAC_CONST(0.953306040354194) }, { FRAC_CONST(0.295760151956351), FRAC_CONST(0.955262232329299) }, { FRAC_CONST(0.289501685212929), FRAC_CONST(0.957177504049732) }, { FRAC_CONST(0.283230817180850), FRAC_CONST(0.959051773471624) }, { FRAC_CONST(0.276947816483228), FRAC_CONST(0.960884960307514) }, { FRAC_CONST(0.270652952262902), FRAC_CONST(0.962676986029777) }, { FRAC_CONST(0.264346494170904), FRAC_CONST(0.964427773873996) }, { FRAC_CONST(0.258028712354909), FRAC_CONST(0.966137248842248) }, { FRAC_CONST(0.251699877447663), FRAC_CONST(0.967805337706313) }, { FRAC_CONST(0.245360260555389), FRAC_CONST(0.969431969010818) }, { FRAC_CONST(0.239010133246176), FRAC_CONST(0.971017073076290) }, { FRAC_CONST(0.232649767538342), FRAC_CONST(0.972560582002147) }, { FRAC_CONST(0.226279435888785), FRAC_CONST(0.974062429669605) }, { FRAC_CONST(0.219899411181310), FRAC_CONST(0.975522551744506) }, { FRAC_CONST(0.213509966714943), FRAC_CONST(0.976940885680082) }, { FRAC_CONST(0.207111376192219), FRAC_CONST(0.978317370719628) }, { FRAC_CONST(0.200703913707458), FRAC_CONST(0.979651947899104) }, { FRAC_CONST(0.194287853735029), FRAC_CONST(0.980944560049668) }, { FRAC_CONST(0.187863471117585), FRAC_CONST(0.982195151800116) }, { FRAC_CONST(0.181431041054297), FRAC_CONST(0.983403669579260) }, { FRAC_CONST(0.174990839089060), FRAC_CONST(0.984570061618221) }, { FRAC_CONST(0.168543141098691), FRAC_CONST(0.985694277952645) }, { FRAC_CONST(0.162088223281113), FRAC_CONST(0.986776270424848) }, { FRAC_CONST(0.155626362143520), FRAC_CONST(0.987815992685872) }, { FRAC_CONST(0.149157834490539), FRAC_CONST(0.988813400197476) }, { FRAC_CONST(0.142682917412363), FRAC_CONST(0.989768450234042) }, { FRAC_CONST(0.136201888272891), FRAC_CONST(0.990681101884405) }, { FRAC_CONST(0.129715024697841), FRAC_CONST(0.991551316053606) }, { FRAC_CONST(0.123222604562857), FRAC_CONST(0.992379055464567) }, { FRAC_CONST(0.116724905981611), FRAC_CONST(0.993164284659685) }, { FRAC_CONST(0.110222207293883), FRAC_CONST(0.993906970002356) }, { FRAC_CONST(0.103714787053643), FRAC_CONST(0.994607079678411) }, { FRAC_CONST(0.097202924017115), FRAC_CONST(0.995264583697482) }, { FRAC_CONST(0.090686897130838), FRAC_CONST(0.995879453894286) }, { FRAC_CONST(0.084166985519718), FRAC_CONST(0.996451663929828) }, { FRAC_CONST(0.077643468475068), FRAC_CONST(0.996981189292537) }, { FRAC_CONST(0.071116625442645), FRAC_CONST(0.997468007299307) }, { FRAC_CONST(0.064586736010684), FRAC_CONST(0.997912097096476) }, { FRAC_CONST(0.058054079897912), FRAC_CONST(0.998313439660714) }, { FRAC_CONST(0.051518936941578), FRAC_CONST(0.998672017799843) }, { FRAC_CONST(0.044981587085452), FRAC_CONST(0.998987816153567) }, { FRAC_CONST(0.038442310367847), FRAC_CONST(0.999260821194138) }, { FRAC_CONST(0.031901386909611), FRAC_CONST(0.999491021226926) }, { FRAC_CONST(0.025359096902136), FRAC_CONST(0.999678406390929) }, { FRAC_CONST(0.018815720595351), FRAC_CONST(0.999822968659191) }, { FRAC_CONST(0.012271538285720), FRAC_CONST(0.999924701839145) }, { FRAC_CONST(0.005726830304231), FRAC_CONST(0.999983601572879) } }; #endif // LD_DEC /* 60 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_240[] = { { FRAC_CONST(0.999994645401696), FRAC_CONST(0.003272486506527) }, { FRAC_CONST(0.999566308502021), FRAC_CONST(0.029448173247963) }, { FRAC_CONST(0.998452918783950), FRAC_CONST(0.055603677682425) }, { FRAC_CONST(0.996655239309180), FRAC_CONST(0.081721074133668) }, { FRAC_CONST(0.994174502117428), FRAC_CONST(0.107782463042759) }, { FRAC_CONST(0.991012407382049), FRAC_CONST(0.133769983235535) }, { FRAC_CONST(0.987171122244825), FRAC_CONST(0.159665824163761) }, { FRAC_CONST(0.982653279330712), FRAC_CONST(0.185452238111591) }, { FRAC_CONST(0.977461974943572), FRAC_CONST(0.211111552358965) }, { FRAC_CONST(0.971600766944121), FRAC_CONST(0.236626181293610) }, { FRAC_CONST(0.965073672311547), FRAC_CONST(0.261978638463337) }, { FRAC_CONST(0.957885164390477), FRAC_CONST(0.287151548560387) }, { FRAC_CONST(0.950040169825165), FRAC_CONST(0.312127659329594) }, { FRAC_CONST(0.941544065183021), FRAC_CONST(0.336889853392220) }, { FRAC_CONST(0.932402673269775), FRAC_CONST(0.361421159977355) }, { FRAC_CONST(0.922622259138823), FRAC_CONST(0.385704766552831) }, { FRAC_CONST(0.912209525797468), FRAC_CONST(0.409724030347695) }, { FRAC_CONST(0.901171609613013), FRAC_CONST(0.433462489758331) }, { FRAC_CONST(0.889516075421856), FRAC_CONST(0.456903875630421) }, { FRAC_CONST(0.877250911344924), FRAC_CONST(0.480032122409011) }, { FRAC_CONST(0.864384523313017), FRAC_CONST(0.502831379149042) }, { FRAC_CONST(0.850925729305802), FRAC_CONST(0.525286020378792) }, { FRAC_CONST(0.836883753308409), FRAC_CONST(0.547380656808797) }, { FRAC_CONST(0.822268218989775), FRAC_CONST(0.569100145878898) }, { FRAC_CONST(0.807089143107059), FRAC_CONST(0.590429602136201) }, { FRAC_CONST(0.791356928640660), FRAC_CONST(0.611354407436816) }, { FRAC_CONST(0.775082357664531), FRAC_CONST(0.631860220964409) }, { FRAC_CONST(0.758276583956687), FRAC_CONST(0.651932989058674) }, { FRAC_CONST(0.740951125354959), FRAC_CONST(0.671558954847018) }, { FRAC_CONST(0.723117855863248), FRAC_CONST(0.690724667672829) }, { FRAC_CONST(0.704788997513670), FRAC_CONST(0.709416992313883) }, { FRAC_CONST(0.685977111990193), FRAC_CONST(0.727623117984575) }, { FRAC_CONST(0.666695092019479), FRAC_CONST(0.745330567115786) }, { FRAC_CONST(0.646956152534857), FRAC_CONST(0.762527203906388) }, { FRAC_CONST(0.626773821619469), FRAC_CONST(0.779201242640517) }, { FRAC_CONST(0.606161931234795), FRAC_CONST(0.795341255764910) }, { FRAC_CONST(0.585134607740916), FRAC_CONST(0.810936181720784) }, { FRAC_CONST(0.563706262215017), FRAC_CONST(0.825975332524873) }, { FRAC_CONST(0.541891580574752), FRAC_CONST(0.840448401094438) }, { FRAC_CONST(0.519705513513249), FRAC_CONST(0.854345468311227) }, { FRAC_CONST(0.497163266252654), FRAC_CONST(0.867657009819544) }, { FRAC_CONST(0.474280288123229), FRAC_CONST(0.880373902553765) }, { FRAC_CONST(0.451072261975153), FRAC_CONST(0.892487430990834) }, { FRAC_CONST(0.427555093430282), FRAC_CONST(0.903989293123443) }, { FRAC_CONST(0.403744899981227), FRAC_CONST(0.914871606149819) }, { FRAC_CONST(0.379657999945233), FRAC_CONST(0.925126911876195) }, { FRAC_CONST(0.355310901280416), FRAC_CONST(0.934748181828292) }, { FRAC_CONST(0.330720290272038), FRAC_CONST(0.943728822068278) }, { FRAC_CONST(0.305903020096554), FRAC_CONST(0.952062677713924) }, { FRAC_CONST(0.280876099271292), FRAC_CONST(0.959744037156857) }, { FRAC_CONST(0.255656679997665), FRAC_CONST(0.966767635977008) }, { FRAC_CONST(0.230262046405902), FRAC_CONST(0.973128660550580) }, { FRAC_CONST(0.204709602709380), FRAC_CONST(0.978822751349072) }, { FRAC_CONST(0.179016861276633), FRAC_CONST(0.983846005927077) }, { FRAC_CONST(0.153201430629259), FRAC_CONST(0.988194981596825) }, { FRAC_CONST(0.127281003373913), FRAC_CONST(0.991866697787626) }, { FRAC_CONST(0.101273344076683), FRAC_CONST(0.994858638088611) }, { FRAC_CONST(0.075196277088140), FRAC_CONST(0.997168751973348) }, { FRAC_CONST(0.049067674327418), FRAC_CONST(0.998795456205172) }, { FRAC_CONST(0.022905443033697), FRAC_CONST(0.999737635922260) } }; #endif // ALLOW_SMALL_FRAMELENGTH #ifdef SSR_DEC /* 128 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_512[] = { { FRAC_CONST(0.999998823451702), FRAC_CONST(0.001533980186285) }, { FRAC_CONST(0.999904701082853), FRAC_CONST(0.013805388528060) }, { FRAC_CONST(0.999659996743959), FRAC_CONST(0.026074717829104) }, { FRAC_CONST(0.999264747286594), FRAC_CONST(0.038340120373553) }, { FRAC_CONST(0.998719012233873), FRAC_CONST(0.050599749036899) }, { FRAC_CONST(0.998022873771486), FRAC_CONST(0.062851757564161) }, { FRAC_CONST(0.997176436735326), FRAC_CONST(0.075094300847921) }, { FRAC_CONST(0.996179828595697), FRAC_CONST(0.087325535206192) }, { FRAC_CONST(0.995033199438119), FRAC_CONST(0.099543618660069) }, { FRAC_CONST(0.993736721940725), FRAC_CONST(0.111746711211127) }, { FRAC_CONST(0.992290591348257), FRAC_CONST(0.123932975118512) }, { FRAC_CONST(0.990695025442665), FRAC_CONST(0.136100575175706) }, { FRAC_CONST(0.988950264510303), FRAC_CONST(0.148247678986896) }, { FRAC_CONST(0.987056571305751), FRAC_CONST(0.160372457242928) }, { FRAC_CONST(0.985014231012240), FRAC_CONST(0.172473083996796) }, { FRAC_CONST(0.982823551198705), FRAC_CONST(0.184547736938620) }, { FRAC_CONST(0.980484861773469), FRAC_CONST(0.196594597670080) }, { FRAC_CONST(0.977998514934557), FRAC_CONST(0.208611851978263) }, { FRAC_CONST(0.975364885116657), FRAC_CONST(0.220597690108874) }, { FRAC_CONST(0.972584368934732), FRAC_CONST(0.232550307038775) }, { FRAC_CONST(0.969657385124292), FRAC_CONST(0.244467902747824) }, { FRAC_CONST(0.966584374478333), FRAC_CONST(0.256348682489943) }, { FRAC_CONST(0.963365799780954), FRAC_CONST(0.268190857063403) }, { FRAC_CONST(0.960002145737666), FRAC_CONST(0.279992643080273) }, { FRAC_CONST(0.956493918902395), FRAC_CONST(0.291752263234989) }, { FRAC_CONST(0.952841647601199), FRAC_CONST(0.303467946572011) }, { FRAC_CONST(0.949045881852701), FRAC_CONST(0.315137928752522) }, { FRAC_CONST(0.945107193285261), FRAC_CONST(0.326760452320132) }, { FRAC_CONST(0.941026175050889), FRAC_CONST(0.338333766965541) }, { FRAC_CONST(0.936803441735922), FRAC_CONST(0.349856129790135) }, { FRAC_CONST(0.932439629268462), FRAC_CONST(0.361325805568454) }, { FRAC_CONST(0.927935394822618), FRAC_CONST(0.372741067009516) }, { FRAC_CONST(0.923291416719528), FRAC_CONST(0.384100195016935) }, { FRAC_CONST(0.918508394325212), FRAC_CONST(0.395401478947816) }, { FRAC_CONST(0.913587047945251), FRAC_CONST(0.406643216870369) }, { FRAC_CONST(0.908528118716306), FRAC_CONST(0.417823715820212) }, { FRAC_CONST(0.903332368494512), FRAC_CONST(0.428941292055329) }, { FRAC_CONST(0.898000579740740), FRAC_CONST(0.439994271309633) }, { FRAC_CONST(0.892533555402765), FRAC_CONST(0.450980989045104) }, { FRAC_CONST(0.886932118794342), FRAC_CONST(0.461899790702463) }, { FRAC_CONST(0.881197113471222), FRAC_CONST(0.472749031950343) }, { FRAC_CONST(0.875329403104111), FRAC_CONST(0.483527078932919) }, { FRAC_CONST(0.869329871348607), FRAC_CONST(0.494232308515960) }, { FRAC_CONST(0.863199421712124), FRAC_CONST(0.504863108531268) }, { FRAC_CONST(0.856938977417829), FRAC_CONST(0.515417878019463) }, { FRAC_CONST(0.850549481265603), FRAC_CONST(0.525895027471085) }, { FRAC_CONST(0.844031895490066), FRAC_CONST(0.536292979065963) }, { FRAC_CONST(0.837387201615662), FRAC_CONST(0.546610166910835) }, { FRAC_CONST(0.830616400308846), FRAC_CONST(0.556845037275160) }, { FRAC_CONST(0.823720511227391), FRAC_CONST(0.566996048825109) }, { FRAC_CONST(0.816700572866828), FRAC_CONST(0.577061672855679) }, { FRAC_CONST(0.809557642404051), FRAC_CONST(0.587040393520918) }, { FRAC_CONST(0.802292795538116), FRAC_CONST(0.596930708062197) }, { FRAC_CONST(0.794907126328237), FRAC_CONST(0.606731127034524) }, { FRAC_CONST(0.787401747029031), FRAC_CONST(0.616440174530854) }, { FRAC_CONST(0.779777787923015), FRAC_CONST(0.626056388404344) }, { FRAC_CONST(0.772036397150385), FRAC_CONST(0.635578320488556) }, { FRAC_CONST(0.764178740536117), FRAC_CONST(0.645004536815544) }, { FRAC_CONST(0.756206001414395), FRAC_CONST(0.654333617831800) }, { FRAC_CONST(0.748119380450404), FRAC_CONST(0.663564158612040) }, { FRAC_CONST(0.739920095459516), FRAC_CONST(0.672694769070773) }, { FRAC_CONST(0.731609381223893), FRAC_CONST(0.681724074171650) }, { FRAC_CONST(0.723188489306527), FRAC_CONST(0.690650714134535) }, { FRAC_CONST(0.714658687862769), FRAC_CONST(0.699473344640284) }, { FRAC_CONST(0.706021261449340), FRAC_CONST(0.708190637033195) }, { FRAC_CONST(0.697277510830887), FRAC_CONST(0.716801278521100) }, { FRAC_CONST(0.688428752784091), FRAC_CONST(0.725303972373061) }, { FRAC_CONST(0.679476319899365), FRAC_CONST(0.733697438114660) }, { FRAC_CONST(0.670421560380173), FRAC_CONST(0.741980411720831) }, { FRAC_CONST(0.661265837839992), FRAC_CONST(0.750151645806215) }, { FRAC_CONST(0.652010531096960), FRAC_CONST(0.758209909813015) }, { FRAC_CONST(0.642657033966227), FRAC_CONST(0.766153990196313) }, { FRAC_CONST(0.633206755050057), FRAC_CONST(0.773982690606823) }, { FRAC_CONST(0.623661117525695), FRAC_CONST(0.781694832071059) }, { FRAC_CONST(0.614021558931038), FRAC_CONST(0.789289253168886) }, { FRAC_CONST(0.604289530948156), FRAC_CONST(0.796764810208419) }, { FRAC_CONST(0.594466499184665), FRAC_CONST(0.804120377398266) }, { FRAC_CONST(0.584553942953015), FRAC_CONST(0.811354847017064) }, { FRAC_CONST(0.574553355047716), FRAC_CONST(0.818467129580299) }, { FRAC_CONST(0.564466241520520), FRAC_CONST(0.825456154004377) }, { FRAC_CONST(0.554294121453620), FRAC_CONST(0.832320867767930) }, { FRAC_CONST(0.544038526730884), FRAC_CONST(0.839060237070313) }, { FRAC_CONST(0.533701001807153), FRAC_CONST(0.845673246987299) }, { FRAC_CONST(0.523283103475656), FRAC_CONST(0.852158901623920) }, { FRAC_CONST(0.512786400633563), FRAC_CONST(0.858516224264443) }, { FRAC_CONST(0.502212474045711), FRAC_CONST(0.864744257519462) }, { FRAC_CONST(0.491562916106550), FRAC_CONST(0.870842063470079) }, { FRAC_CONST(0.480839330600334), FRAC_CONST(0.876808723809146) }, { FRAC_CONST(0.470043332459596), FRAC_CONST(0.882643339979563) }, { FRAC_CONST(0.459176547521944), FRAC_CONST(0.888345033309596) }, { FRAC_CONST(0.448240612285220), FRAC_CONST(0.893912945145203) }, { FRAC_CONST(0.437237173661044), FRAC_CONST(0.899346236979341) }, { FRAC_CONST(0.426167888726800), FRAC_CONST(0.904644090578246) }, { FRAC_CONST(0.415034424476082), FRAC_CONST(0.909805708104652) }, { FRAC_CONST(0.403838457567654), FRAC_CONST(0.914830312237946) }, { FRAC_CONST(0.392581674072952), FRAC_CONST(0.919717146291227) }, { FRAC_CONST(0.381265769222162), FRAC_CONST(0.924465474325263) }, { FRAC_CONST(0.369892447148934), FRAC_CONST(0.929074581259316) }, { FRAC_CONST(0.358463420633737), FRAC_CONST(0.933543772978836) }, { FRAC_CONST(0.346980410845924), FRAC_CONST(0.937872376439990) }, { FRAC_CONST(0.335445147084532), FRAC_CONST(0.942059739771017) }, { FRAC_CONST(0.323859366517853), FRAC_CONST(0.946105232370403) }, { FRAC_CONST(0.312224813921825), FRAC_CONST(0.950008245001843) }, { FRAC_CONST(0.300543241417273), FRAC_CONST(0.953768189885990) }, { FRAC_CONST(0.288816408206049), FRAC_CONST(0.957384500788976) }, { FRAC_CONST(0.277046080306100), FRAC_CONST(0.960856633107680) }, { FRAC_CONST(0.265234030285512), FRAC_CONST(0.964184063951746) }, { FRAC_CONST(0.253382036995570), FRAC_CONST(0.967366292222329) }, { FRAC_CONST(0.241491885302869), FRAC_CONST(0.970402838687556) }, { FRAC_CONST(0.229565365820519), FRAC_CONST(0.973293246054698) }, { FRAC_CONST(0.217604274638484), FRAC_CONST(0.976037079039039) }, { FRAC_CONST(0.205610413053099), FRAC_CONST(0.978633924429423) }, { FRAC_CONST(0.193585587295804), FRAC_CONST(0.981083391150487) }, { FRAC_CONST(0.181531608261125), FRAC_CONST(0.983385110321551) }, { FRAC_CONST(0.169450291233968), FRAC_CONST(0.985538735312176) }, { FRAC_CONST(0.157343455616238), FRAC_CONST(0.987543941794359) }, { FRAC_CONST(0.145212924652848), FRAC_CONST(0.989400427791380) }, { FRAC_CONST(0.133060525157139), FRAC_CONST(0.991107913723277) }, { FRAC_CONST(0.120888087235777), FRAC_CONST(0.992666142448948) }, { FRAC_CONST(0.108697444013139), FRAC_CONST(0.994074879304879) }, { FRAC_CONST(0.096490431355253), FRAC_CONST(0.995333912140482) }, { FRAC_CONST(0.084268887593324), FRAC_CONST(0.996443051350043) }, { FRAC_CONST(0.072034653246889), FRAC_CONST(0.997402129901275) }, { FRAC_CONST(0.059789570746640), FRAC_CONST(0.998211003360478) }, { FRAC_CONST(0.047535484156959), FRAC_CONST(0.998869549914284) }, { FRAC_CONST(0.035274238898214), FRAC_CONST(0.999377670388003) }, { FRAC_CONST(0.023007681468839), FRAC_CONST(0.999735288260562) }, { FRAC_CONST(0.010737659167265), FRAC_CONST(0.999942349676024) } }; /* 16 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_64[] = { { FRAC_CONST(0.999924701839145), FRAC_CONST(0.012271538285720) }, { FRAC_CONST(0.993906970002356), FRAC_CONST(0.110222207293883) }, { FRAC_CONST(0.978317370719628), FRAC_CONST(0.207111376192219) }, { FRAC_CONST(0.953306040354194), FRAC_CONST(0.302005949319228) }, { FRAC_CONST(0.919113851690058), FRAC_CONST(0.393992040061048) }, { FRAC_CONST(0.876070094195407), FRAC_CONST(0.482183772079123) }, { FRAC_CONST(0.824589302785025), FRAC_CONST(0.565731810783613) }, { FRAC_CONST(0.765167265622459), FRAC_CONST(0.643831542889791) }, { FRAC_CONST(0.698376249408973), FRAC_CONST(0.715730825283819) }, { FRAC_CONST(0.624859488142386), FRAC_CONST(0.780737228572094) }, { FRAC_CONST(0.545324988422046), FRAC_CONST(0.838224705554838) }, { FRAC_CONST(0.460538710958240), FRAC_CONST(0.887639620402854) }, { FRAC_CONST(0.371317193951838), FRAC_CONST(0.928506080473215) }, { FRAC_CONST(0.278519689385053), FRAC_CONST(0.960430519415566) }, { FRAC_CONST(0.183039887955141), FRAC_CONST(0.983105487431216) }, { FRAC_CONST(0.085797312344440), FRAC_CONST(0.996312612182778) } }; #endif // SSR_DEC #else // FIXED_POINT /* 256 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_2048[] = { { FRAC_CONST(0.031249997702054), FRAC_CONST(0.000011984224612) }, { FRAC_CONST(0.031249813866531), FRAC_CONST(0.000107857810004) }, { FRAC_CONST(0.031249335895858), FRAC_CONST(0.000203730380198) }, { FRAC_CONST(0.031248563794535), FRAC_CONST(0.000299601032804) }, { FRAC_CONST(0.031247497569829), FRAC_CONST(0.000395468865451) }, { FRAC_CONST(0.031246137231775), FRAC_CONST(0.000491332975794) }, { FRAC_CONST(0.031244482793177), FRAC_CONST(0.000587192461525) }, { FRAC_CONST(0.031242534269608), FRAC_CONST(0.000683046420376) }, { FRAC_CONST(0.031240291679407), FRAC_CONST(0.000778893950134) }, { FRAC_CONST(0.031237755043684), FRAC_CONST(0.000874734148645) }, { FRAC_CONST(0.031234924386313), FRAC_CONST(0.000970566113826) }, { FRAC_CONST(0.031231799733938), FRAC_CONST(0.001066388943669) }, { FRAC_CONST(0.031228381115970), FRAC_CONST(0.001162201736253) }, { FRAC_CONST(0.031224668564585), FRAC_CONST(0.001258003589751) }, { FRAC_CONST(0.031220662114728), FRAC_CONST(0.001353793602441) }, { FRAC_CONST(0.031216361804108), FRAC_CONST(0.001449570872710) }, { FRAC_CONST(0.031211767673203), FRAC_CONST(0.001545334499065) }, { FRAC_CONST(0.031206879765253), FRAC_CONST(0.001641083580144) }, { FRAC_CONST(0.031201698126266), FRAC_CONST(0.001736817214719) }, { FRAC_CONST(0.031196222805014), FRAC_CONST(0.001832534501709) }, { FRAC_CONST(0.031190453853031), FRAC_CONST(0.001928234540186) }, { FRAC_CONST(0.031184391324617), FRAC_CONST(0.002023916429386) }, { FRAC_CONST(0.031178035276836), FRAC_CONST(0.002119579268713) }, { FRAC_CONST(0.031171385769513), FRAC_CONST(0.002215222157753) }, { FRAC_CONST(0.031164442865236), FRAC_CONST(0.002310844196278) }, { FRAC_CONST(0.031157206629353), FRAC_CONST(0.002406444484258) }, { FRAC_CONST(0.031149677129975), FRAC_CONST(0.002502022121865) }, { FRAC_CONST(0.031141854437973), FRAC_CONST(0.002597576209488) }, { FRAC_CONST(0.031133738626977), FRAC_CONST(0.002693105847734) }, { FRAC_CONST(0.031125329773375), FRAC_CONST(0.002788610137442) }, { FRAC_CONST(0.031116627956316), FRAC_CONST(0.002884088179689) }, { FRAC_CONST(0.031107633257703), FRAC_CONST(0.002979539075801) }, { FRAC_CONST(0.031098345762200), FRAC_CONST(0.003074961927355) }, { FRAC_CONST(0.031088765557222), FRAC_CONST(0.003170355836197) }, { FRAC_CONST(0.031078892732942), FRAC_CONST(0.003265719904442) }, { FRAC_CONST(0.031068727382288), FRAC_CONST(0.003361053234488) }, { FRAC_CONST(0.031058269600939), FRAC_CONST(0.003456354929021) }, { FRAC_CONST(0.031047519487329), FRAC_CONST(0.003551624091024) }, { FRAC_CONST(0.031036477142640), FRAC_CONST(0.003646859823790) }, { FRAC_CONST(0.031025142670809), FRAC_CONST(0.003742061230921) }, { FRAC_CONST(0.031013516178519), FRAC_CONST(0.003837227416347) }, { FRAC_CONST(0.031001597775203), FRAC_CONST(0.003932357484328) }, { FRAC_CONST(0.030989387573042), FRAC_CONST(0.004027450539462) }, { FRAC_CONST(0.030976885686963), FRAC_CONST(0.004122505686697) }, { FRAC_CONST(0.030964092234638), FRAC_CONST(0.004217522031340) }, { FRAC_CONST(0.030951007336485), FRAC_CONST(0.004312498679058) }, { FRAC_CONST(0.030937631115663), FRAC_CONST(0.004407434735897) }, { FRAC_CONST(0.030923963698074), FRAC_CONST(0.004502329308281) }, { FRAC_CONST(0.030910005212362), FRAC_CONST(0.004597181503027) }, { FRAC_CONST(0.030895755789908), FRAC_CONST(0.004691990427350) }, { FRAC_CONST(0.030881215564835), FRAC_CONST(0.004786755188872) }, { FRAC_CONST(0.030866384674000), FRAC_CONST(0.004881474895632) }, { FRAC_CONST(0.030851263256996), FRAC_CONST(0.004976148656090) }, { FRAC_CONST(0.030835851456154), FRAC_CONST(0.005070775579142) }, { FRAC_CONST(0.030820149416533), FRAC_CONST(0.005165354774124) }, { FRAC_CONST(0.030804157285929), FRAC_CONST(0.005259885350819) }, { FRAC_CONST(0.030787875214864), FRAC_CONST(0.005354366419469) }, { FRAC_CONST(0.030771303356593), FRAC_CONST(0.005448797090784) }, { FRAC_CONST(0.030754441867095), FRAC_CONST(0.005543176475946) }, { FRAC_CONST(0.030737290905077), FRAC_CONST(0.005637503686619) }, { FRAC_CONST(0.030719850631972), FRAC_CONST(0.005731777834961) }, { FRAC_CONST(0.030702121211932), FRAC_CONST(0.005825998033626) }, { FRAC_CONST(0.030684102811835), FRAC_CONST(0.005920163395780) }, { FRAC_CONST(0.030665795601276), FRAC_CONST(0.006014273035101) }, { FRAC_CONST(0.030647199752570), FRAC_CONST(0.006108326065793) }, { FRAC_CONST(0.030628315440748), FRAC_CONST(0.006202321602594) }, { FRAC_CONST(0.030609142843557), FRAC_CONST(0.006296258760782) }, { FRAC_CONST(0.030589682141455), FRAC_CONST(0.006390136656185) }, { FRAC_CONST(0.030569933517616), FRAC_CONST(0.006483954405188) }, { FRAC_CONST(0.030549897157919), FRAC_CONST(0.006577711124743) }, { FRAC_CONST(0.030529573250956), FRAC_CONST(0.006671405932375) }, { FRAC_CONST(0.030508961988022), FRAC_CONST(0.006765037946194) }, { FRAC_CONST(0.030488063563118), FRAC_CONST(0.006858606284900) }, { FRAC_CONST(0.030466878172949), FRAC_CONST(0.006952110067791) }, { FRAC_CONST(0.030445406016919), FRAC_CONST(0.007045548414774) }, { FRAC_CONST(0.030423647297133), FRAC_CONST(0.007138920446372) }, { FRAC_CONST(0.030401602218392), FRAC_CONST(0.007232225283733) }, { FRAC_CONST(0.030379270988192), FRAC_CONST(0.007325462048634) }, { FRAC_CONST(0.030356653816724), FRAC_CONST(0.007418629863497) }, { FRAC_CONST(0.030333750916869), FRAC_CONST(0.007511727851390) }, { FRAC_CONST(0.030310562504198), FRAC_CONST(0.007604755136040) }, { FRAC_CONST(0.030287088796968), FRAC_CONST(0.007697710841838) }, { FRAC_CONST(0.030263330016124), FRAC_CONST(0.007790594093851) }, { FRAC_CONST(0.030239286385293), FRAC_CONST(0.007883404017824) }, { FRAC_CONST(0.030214958130781), FRAC_CONST(0.007976139740197) }, { FRAC_CONST(0.030190345481576), FRAC_CONST(0.008068800388104) }, { FRAC_CONST(0.030165448669342), FRAC_CONST(0.008161385089390) }, { FRAC_CONST(0.030140267928416), FRAC_CONST(0.008253892972610) }, { FRAC_CONST(0.030114803495809), FRAC_CONST(0.008346323167047) }, { FRAC_CONST(0.030089055611203), FRAC_CONST(0.008438674802711) }, { FRAC_CONST(0.030063024516947), FRAC_CONST(0.008530947010354) }, { FRAC_CONST(0.030036710458054), FRAC_CONST(0.008623138921475) }, { FRAC_CONST(0.030010113682202), FRAC_CONST(0.008715249668328) }, { FRAC_CONST(0.029983234439732), FRAC_CONST(0.008807278383932) }, { FRAC_CONST(0.029956072983640), FRAC_CONST(0.008899224202078) }, { FRAC_CONST(0.029928629569580), FRAC_CONST(0.008991086257336) }, { FRAC_CONST(0.029900904455860), FRAC_CONST(0.009082863685067) }, { FRAC_CONST(0.029872897903441), FRAC_CONST(0.009174555621425) }, { FRAC_CONST(0.029844610175929), FRAC_CONST(0.009266161203371) }, { FRAC_CONST(0.029816041539579), FRAC_CONST(0.009357679568679) }, { FRAC_CONST(0.029787192263292), FRAC_CONST(0.009449109855944) }, { FRAC_CONST(0.029758062618606), FRAC_CONST(0.009540451204587) }, { FRAC_CONST(0.029728652879702), FRAC_CONST(0.009631702754871) }, { FRAC_CONST(0.029698963323395), FRAC_CONST(0.009722863647900) }, { FRAC_CONST(0.029668994229134), FRAC_CONST(0.009813933025633) }, { FRAC_CONST(0.029638745879000), FRAC_CONST(0.009904910030891) }, { FRAC_CONST(0.029608218557702), FRAC_CONST(0.009995793807363) }, { FRAC_CONST(0.029577412552575), FRAC_CONST(0.010086583499618) }, { FRAC_CONST(0.029546328153577), FRAC_CONST(0.010177278253107) }, { FRAC_CONST(0.029514965653285), FRAC_CONST(0.010267877214177) }, { FRAC_CONST(0.029483325346896), FRAC_CONST(0.010358379530076) }, { FRAC_CONST(0.029451407532220), FRAC_CONST(0.010448784348962) }, { FRAC_CONST(0.029419212509679), FRAC_CONST(0.010539090819911) }, { FRAC_CONST(0.029386740582307), FRAC_CONST(0.010629298092923) }, { FRAC_CONST(0.029353992055740), FRAC_CONST(0.010719405318933) }, { FRAC_CONST(0.029320967238220), FRAC_CONST(0.010809411649818) }, { FRAC_CONST(0.029287666440590), FRAC_CONST(0.010899316238403) }, { FRAC_CONST(0.029254089976290), FRAC_CONST(0.010989118238474) }, { FRAC_CONST(0.029220238161353), FRAC_CONST(0.011078816804778) }, { FRAC_CONST(0.029186111314406), FRAC_CONST(0.011168411093039) }, { FRAC_CONST(0.029151709756664), FRAC_CONST(0.011257900259961) }, { FRAC_CONST(0.029117033811927), FRAC_CONST(0.011347283463239) }, { FRAC_CONST(0.029082083806579), FRAC_CONST(0.011436559861563) }, { FRAC_CONST(0.029046860069582), FRAC_CONST(0.011525728614630) }, { FRAC_CONST(0.029011362932476), FRAC_CONST(0.011614788883150) }, { FRAC_CONST(0.028975592729373), FRAC_CONST(0.011703739828853) }, { FRAC_CONST(0.028939549796957), FRAC_CONST(0.011792580614500) }, { FRAC_CONST(0.028903234474475), FRAC_CONST(0.011881310403886) }, { FRAC_CONST(0.028866647103744), FRAC_CONST(0.011969928361855) }, { FRAC_CONST(0.028829788029135), FRAC_CONST(0.012058433654299) }, { FRAC_CONST(0.028792657597583), FRAC_CONST(0.012146825448172) }, { FRAC_CONST(0.028755256158571), FRAC_CONST(0.012235102911499) }, { FRAC_CONST(0.028717584064137), FRAC_CONST(0.012323265213377) }, { FRAC_CONST(0.028679641668864), FRAC_CONST(0.012411311523990) }, { FRAC_CONST(0.028641429329882), FRAC_CONST(0.012499241014612) }, { FRAC_CONST(0.028602947406859), FRAC_CONST(0.012587052857618) }, { FRAC_CONST(0.028564196262001), FRAC_CONST(0.012674746226488) }, { FRAC_CONST(0.028525176260050), FRAC_CONST(0.012762320295819) }, { FRAC_CONST(0.028485887768276), FRAC_CONST(0.012849774241331) }, { FRAC_CONST(0.028446331156478), FRAC_CONST(0.012937107239875) }, { FRAC_CONST(0.028406506796976), FRAC_CONST(0.013024318469437) }, { FRAC_CONST(0.028366415064615), FRAC_CONST(0.013111407109155) }, { FRAC_CONST(0.028326056336751), FRAC_CONST(0.013198372339315) }, { FRAC_CONST(0.028285430993258), FRAC_CONST(0.013285213341368) }, { FRAC_CONST(0.028244539416515), FRAC_CONST(0.013371929297933) }, { FRAC_CONST(0.028203381991411), FRAC_CONST(0.013458519392807) }, { FRAC_CONST(0.028161959105334), FRAC_CONST(0.013544982810971) }, { FRAC_CONST(0.028120271148172), FRAC_CONST(0.013631318738598) }, { FRAC_CONST(0.028078318512309), FRAC_CONST(0.013717526363062) }, { FRAC_CONST(0.028036101592619), FRAC_CONST(0.013803604872943) }, { FRAC_CONST(0.027993620786463), FRAC_CONST(0.013889553458039) }, { FRAC_CONST(0.027950876493687), FRAC_CONST(0.013975371309367) }, { FRAC_CONST(0.027907869116616), FRAC_CONST(0.014061057619178) }, { FRAC_CONST(0.027864599060052), FRAC_CONST(0.014146611580959) }, { FRAC_CONST(0.027821066731270), FRAC_CONST(0.014232032389445) }, { FRAC_CONST(0.027777272540012), FRAC_CONST(0.014317319240622) }, { FRAC_CONST(0.027733216898487), FRAC_CONST(0.014402471331737) }, { FRAC_CONST(0.027688900221361), FRAC_CONST(0.014487487861307) }, { FRAC_CONST(0.027644322925762), FRAC_CONST(0.014572368029123) }, { FRAC_CONST(0.027599485431266), FRAC_CONST(0.014657111036262) }, { FRAC_CONST(0.027554388159903), FRAC_CONST(0.014741716085090) }, { FRAC_CONST(0.027509031536144), FRAC_CONST(0.014826182379271) }, { FRAC_CONST(0.027463415986904), FRAC_CONST(0.014910509123778) }, { FRAC_CONST(0.027417541941533), FRAC_CONST(0.014994695524894) }, { FRAC_CONST(0.027371409831816), FRAC_CONST(0.015078740790225) }, { FRAC_CONST(0.027325020091965), FRAC_CONST(0.015162644128704) }, { FRAC_CONST(0.027278373158618), FRAC_CONST(0.015246404750603) }, { FRAC_CONST(0.027231469470833), FRAC_CONST(0.015330021867534) }, { FRAC_CONST(0.027184309470088), FRAC_CONST(0.015413494692460) }, { FRAC_CONST(0.027136893600268), FRAC_CONST(0.015496822439704) }, { FRAC_CONST(0.027089222307671), FRAC_CONST(0.015580004324954) }, { FRAC_CONST(0.027041296040997), FRAC_CONST(0.015663039565269) }, { FRAC_CONST(0.026993115251345), FRAC_CONST(0.015745927379091) }, { FRAC_CONST(0.026944680392213), FRAC_CONST(0.015828666986247) }, { FRAC_CONST(0.026895991919487), FRAC_CONST(0.015911257607961) }, { FRAC_CONST(0.026847050291442), FRAC_CONST(0.015993698466859) }, { FRAC_CONST(0.026797855968734), FRAC_CONST(0.016075988786976) }, { FRAC_CONST(0.026748409414401), FRAC_CONST(0.016158127793763) }, { FRAC_CONST(0.026698711093851), FRAC_CONST(0.016240114714099) }, { FRAC_CONST(0.026648761474864), FRAC_CONST(0.016321948776289) }, { FRAC_CONST(0.026598561027585), FRAC_CONST(0.016403629210082) }, { FRAC_CONST(0.026548110224519), FRAC_CONST(0.016485155246669) }, { FRAC_CONST(0.026497409540530), FRAC_CONST(0.016566526118696) }, { FRAC_CONST(0.026446459452830), FRAC_CONST(0.016647741060271) }, { FRAC_CONST(0.026395260440982), FRAC_CONST(0.016728799306966) }, { FRAC_CONST(0.026343812986890), FRAC_CONST(0.016809700095831) }, { FRAC_CONST(0.026292117574797), FRAC_CONST(0.016890442665397) }, { FRAC_CONST(0.026240174691280), FRAC_CONST(0.016971026255683) }, { FRAC_CONST(0.026187984825246), FRAC_CONST(0.017051450108208) }, { FRAC_CONST(0.026135548467924), FRAC_CONST(0.017131713465990) }, { FRAC_CONST(0.026082866112867), FRAC_CONST(0.017211815573560) }, { FRAC_CONST(0.026029938255941), FRAC_CONST(0.017291755676967) }, { FRAC_CONST(0.025976765395322), FRAC_CONST(0.017371533023784) }, { FRAC_CONST(0.025923348031494), FRAC_CONST(0.017451146863116) }, { FRAC_CONST(0.025869686667242), FRAC_CONST(0.017530596445607) }, { FRAC_CONST(0.025815781807646), FRAC_CONST(0.017609881023449) }, { FRAC_CONST(0.025761633960080), FRAC_CONST(0.017688999850383) }, { FRAC_CONST(0.025707243634204), FRAC_CONST(0.017767952181715) }, { FRAC_CONST(0.025652611341960), FRAC_CONST(0.017846737274313) }, { FRAC_CONST(0.025597737597568), FRAC_CONST(0.017925354386623) }, { FRAC_CONST(0.025542622917522), FRAC_CONST(0.018003802778671) }, { FRAC_CONST(0.025487267820581), FRAC_CONST(0.018082081712071) }, { FRAC_CONST(0.025431672827768), FRAC_CONST(0.018160190450031) }, { FRAC_CONST(0.025375838462365), FRAC_CONST(0.018238128257362) }, { FRAC_CONST(0.025319765249906), FRAC_CONST(0.018315894400484) }, { FRAC_CONST(0.025263453718173), FRAC_CONST(0.018393488147432) }, { FRAC_CONST(0.025206904397193), FRAC_CONST(0.018470908767865) }, { FRAC_CONST(0.025150117819228), FRAC_CONST(0.018548155533070) }, { FRAC_CONST(0.025093094518776), FRAC_CONST(0.018625227715971) }, { FRAC_CONST(0.025035835032562), FRAC_CONST(0.018702124591135) }, { FRAC_CONST(0.024978339899534), FRAC_CONST(0.018778845434780) }, { FRAC_CONST(0.024920609660858), FRAC_CONST(0.018855389524780) }, { FRAC_CONST(0.024862644859912), FRAC_CONST(0.018931756140672) }, { FRAC_CONST(0.024804446042284), FRAC_CONST(0.019007944563666) }, { FRAC_CONST(0.024746013755764), FRAC_CONST(0.019083954076646) }, { FRAC_CONST(0.024687348550337), FRAC_CONST(0.019159783964183) }, { FRAC_CONST(0.024628450978184), FRAC_CONST(0.019235433512536) }, { FRAC_CONST(0.024569321593670), FRAC_CONST(0.019310902009663) }, { FRAC_CONST(0.024509960953345), FRAC_CONST(0.019386188745225) }, { FRAC_CONST(0.024450369615932), FRAC_CONST(0.019461293010596) }, { FRAC_CONST(0.024390548142329), FRAC_CONST(0.019536214098866) }, { FRAC_CONST(0.024330497095598), FRAC_CONST(0.019610951304848) }, { FRAC_CONST(0.024270217040961), FRAC_CONST(0.019685503925087) }, { FRAC_CONST(0.024209708545799), FRAC_CONST(0.019759871257867) }, { FRAC_CONST(0.024148972179639), FRAC_CONST(0.019834052603212) }, { FRAC_CONST(0.024088008514157), FRAC_CONST(0.019908047262901) }, { FRAC_CONST(0.024026818123164), FRAC_CONST(0.019981854540467) }, { FRAC_CONST(0.023965401582609), FRAC_CONST(0.020055473741208) }, { FRAC_CONST(0.023903759470567), FRAC_CONST(0.020128904172192) }, { FRAC_CONST(0.023841892367236), FRAC_CONST(0.020202145142264) }, { FRAC_CONST(0.023779800854935), FRAC_CONST(0.020275195962052) }, { FRAC_CONST(0.023717485518092), FRAC_CONST(0.020348055943974) }, { FRAC_CONST(0.023654946943242), FRAC_CONST(0.020420724402244) }, { FRAC_CONST(0.023592185719023), FRAC_CONST(0.020493200652878) }, { FRAC_CONST(0.023529202436167), FRAC_CONST(0.020565484013703) }, { FRAC_CONST(0.023465997687496), FRAC_CONST(0.020637573804361) }, { FRAC_CONST(0.023402572067918), FRAC_CONST(0.020709469346314) }, { FRAC_CONST(0.023338926174419), FRAC_CONST(0.020781169962854) }, { FRAC_CONST(0.023275060606058), FRAC_CONST(0.020852674979108) }, { FRAC_CONST(0.023210975963963), FRAC_CONST(0.020923983722044) }, { FRAC_CONST(0.023146672851322), FRAC_CONST(0.020995095520475) }, { FRAC_CONST(0.023082151873380), FRAC_CONST(0.021066009705072) }, { FRAC_CONST(0.023017413637435), FRAC_CONST(0.021136725608363) }, { FRAC_CONST(0.022952458752826), FRAC_CONST(0.021207242564742) }, { FRAC_CONST(0.022887287830934), FRAC_CONST(0.021277559910478) }, { FRAC_CONST(0.022821901485173), FRAC_CONST(0.021347676983716) }, { FRAC_CONST(0.022756300330983), FRAC_CONST(0.021417593124488) }, { FRAC_CONST(0.022690484985827), FRAC_CONST(0.021487307674717) }, { FRAC_CONST(0.022624456069185), FRAC_CONST(0.021556819978223) }, { FRAC_CONST(0.022558214202547), FRAC_CONST(0.021626129380729) }, { FRAC_CONST(0.022491760009405), FRAC_CONST(0.021695235229869) }, { FRAC_CONST(0.022425094115252), FRAC_CONST(0.021764136875192) }, { FRAC_CONST(0.022358217147572), FRAC_CONST(0.021832833668171) }, { FRAC_CONST(0.022291129735838), FRAC_CONST(0.021901324962204) }, { FRAC_CONST(0.022223832511501), FRAC_CONST(0.021969610112625) }, { FRAC_CONST(0.022156326107988), FRAC_CONST(0.022037688476709) }, { FRAC_CONST(0.022088611160696), FRAC_CONST(0.022105559413676) }, { FRAC_CONST(0.022020688306983), FRAC_CONST(0.022173222284699) }, { FRAC_CONST(0.021952558186166), FRAC_CONST(0.022240676452909) }, { FRAC_CONST(0.021884221439510), FRAC_CONST(0.022307921283403) }, { FRAC_CONST(0.021815678710228), FRAC_CONST(0.022374956143245) }, { FRAC_CONST(0.021746930643469), FRAC_CONST(0.022441780401478) }, { FRAC_CONST(0.021677977886316), FRAC_CONST(0.022508393429127) }, { FRAC_CONST(0.021608821087780), FRAC_CONST(0.022574794599206) }, { FRAC_CONST(0.021539460898790), FRAC_CONST(0.022640983286719) }, { FRAC_CONST(0.021469897972190), FRAC_CONST(0.022706958868676) }, { FRAC_CONST(0.021400132962735), FRAC_CONST(0.022772720724087) }, { FRAC_CONST(0.021330166527077), FRAC_CONST(0.022838268233979) }, { FRAC_CONST(0.021259999323769), FRAC_CONST(0.022903600781391) }, { FRAC_CONST(0.021189632013250), FRAC_CONST(0.022968717751391) }, { FRAC_CONST(0.021119065257845), FRAC_CONST(0.023033618531071) }, { FRAC_CONST(0.021048299721754), FRAC_CONST(0.023098302509561) }, { FRAC_CONST(0.020977336071050), FRAC_CONST(0.023162769078031) }, { FRAC_CONST(0.020906174973670), FRAC_CONST(0.023227017629698) }, { FRAC_CONST(0.020834817099409), FRAC_CONST(0.023291047559828) }, { FRAC_CONST(0.020763263119915), FRAC_CONST(0.023354858265748) }, { FRAC_CONST(0.020691513708680), FRAC_CONST(0.023418449146848) }, { FRAC_CONST(0.020619569541038), FRAC_CONST(0.023481819604585) }, { FRAC_CONST(0.020547431294155), FRAC_CONST(0.023544969042494) }, { FRAC_CONST(0.020475099647023), FRAC_CONST(0.023607896866186) }, { FRAC_CONST(0.020402575280455), FRAC_CONST(0.023670602483363) }, { FRAC_CONST(0.020329858877078), FRAC_CONST(0.023733085303813) }, { FRAC_CONST(0.020256951121327), FRAC_CONST(0.023795344739427) }, { FRAC_CONST(0.020183852699437), FRAC_CONST(0.023857380204193) }, { FRAC_CONST(0.020110564299439), FRAC_CONST(0.023919191114211) }, { FRAC_CONST(0.020037086611150), FRAC_CONST(0.023980776887692) }, { FRAC_CONST(0.019963420326171), FRAC_CONST(0.024042136944968) }, { FRAC_CONST(0.019889566137877), FRAC_CONST(0.024103270708495) }, { FRAC_CONST(0.019815524741412), FRAC_CONST(0.024164177602859) }, { FRAC_CONST(0.019741296833681), FRAC_CONST(0.024224857054779) }, { FRAC_CONST(0.019666883113346), FRAC_CONST(0.024285308493120) }, { FRAC_CONST(0.019592284280817), FRAC_CONST(0.024345531348888) }, { FRAC_CONST(0.019517501038246), FRAC_CONST(0.024405525055242) }, { FRAC_CONST(0.019442534089523), FRAC_CONST(0.024465289047500) }, { FRAC_CONST(0.019367384140264), FRAC_CONST(0.024524822763141) }, { FRAC_CONST(0.019292051897809), FRAC_CONST(0.024584125641809) }, { FRAC_CONST(0.019216538071215), FRAC_CONST(0.024643197125323) }, { FRAC_CONST(0.019140843371246), FRAC_CONST(0.024702036657681) }, { FRAC_CONST(0.019064968510369), FRAC_CONST(0.024760643685063) }, { FRAC_CONST(0.018988914202748), FRAC_CONST(0.024819017655836) }, { FRAC_CONST(0.018912681164234), FRAC_CONST(0.024877158020562) }, { FRAC_CONST(0.018836270112363), FRAC_CONST(0.024935064232003) }, { FRAC_CONST(0.018759681766343), FRAC_CONST(0.024992735745123) }, { FRAC_CONST(0.018682916847054), FRAC_CONST(0.025050172017095) }, { FRAC_CONST(0.018605976077037), FRAC_CONST(0.025107372507308) }, { FRAC_CONST(0.018528860180486), FRAC_CONST(0.025164336677369) }, { FRAC_CONST(0.018451569883247), FRAC_CONST(0.025221063991110) }, { FRAC_CONST(0.018374105912805), FRAC_CONST(0.025277553914591) }, { FRAC_CONST(0.018296468998280), FRAC_CONST(0.025333805916107) }, { FRAC_CONST(0.018218659870421), FRAC_CONST(0.025389819466194) }, { FRAC_CONST(0.018140679261596), FRAC_CONST(0.025445594037630) }, { FRAC_CONST(0.018062527905790), FRAC_CONST(0.025501129105445) }, { FRAC_CONST(0.017984206538592), FRAC_CONST(0.025556424146920) }, { FRAC_CONST(0.017905715897192), FRAC_CONST(0.025611478641598) }, { FRAC_CONST(0.017827056720375), FRAC_CONST(0.025666292071285) }, { FRAC_CONST(0.017748229748511), FRAC_CONST(0.025720863920056) }, { FRAC_CONST(0.017669235723550), FRAC_CONST(0.025775193674260) }, { FRAC_CONST(0.017590075389012), FRAC_CONST(0.025829280822525) }, { FRAC_CONST(0.017510749489986), FRAC_CONST(0.025883124855762) }, { FRAC_CONST(0.017431258773116), FRAC_CONST(0.025936725267170) }, { FRAC_CONST(0.017351603986600), FRAC_CONST(0.025990081552242) }, { FRAC_CONST(0.017271785880180), FRAC_CONST(0.026043193208768) }, { FRAC_CONST(0.017191805205132), FRAC_CONST(0.026096059736841) }, { FRAC_CONST(0.017111662714267), FRAC_CONST(0.026148680638861) }, { FRAC_CONST(0.017031359161915), FRAC_CONST(0.026201055419541) }, { FRAC_CONST(0.016950895303924), FRAC_CONST(0.026253183585908) }, { FRAC_CONST(0.016870271897651), FRAC_CONST(0.026305064647313) }, { FRAC_CONST(0.016789489701954), FRAC_CONST(0.026356698115431) }, { FRAC_CONST(0.016708549477186), FRAC_CONST(0.026408083504269) }, { FRAC_CONST(0.016627451985187), FRAC_CONST(0.026459220330167) }, { FRAC_CONST(0.016546197989277), FRAC_CONST(0.026510108111806) }, { FRAC_CONST(0.016464788254250), FRAC_CONST(0.026560746370212) }, { FRAC_CONST(0.016383223546365), FRAC_CONST(0.026611134628757) }, { FRAC_CONST(0.016301504633341), FRAC_CONST(0.026661272413168) }, { FRAC_CONST(0.016219632284346), FRAC_CONST(0.026711159251530) }, { FRAC_CONST(0.016137607269996), FRAC_CONST(0.026760794674288) }, { FRAC_CONST(0.016055430362340), FRAC_CONST(0.026810178214254) }, { FRAC_CONST(0.015973102334858), FRAC_CONST(0.026859309406613) }, { FRAC_CONST(0.015890623962454), FRAC_CONST(0.026908187788922) }, { FRAC_CONST(0.015807996021446), FRAC_CONST(0.026956812901119) }, { FRAC_CONST(0.015725219289558), FRAC_CONST(0.027005184285527) }, { FRAC_CONST(0.015642294545918), FRAC_CONST(0.027053301486856) }, { FRAC_CONST(0.015559222571044), FRAC_CONST(0.027101164052208) }, { FRAC_CONST(0.015476004146842), FRAC_CONST(0.027148771531083) }, { FRAC_CONST(0.015392640056594), FRAC_CONST(0.027196123475380) }, { FRAC_CONST(0.015309131084956), FRAC_CONST(0.027243219439406) }, { FRAC_CONST(0.015225478017946), FRAC_CONST(0.027290058979875) }, { FRAC_CONST(0.015141681642938), FRAC_CONST(0.027336641655915) }, { FRAC_CONST(0.015057742748656), FRAC_CONST(0.027382967029073) }, { FRAC_CONST(0.014973662125164), FRAC_CONST(0.027429034663317) }, { FRAC_CONST(0.014889440563862), FRAC_CONST(0.027474844125040) }, { FRAC_CONST(0.014805078857474), FRAC_CONST(0.027520394983066) }, { FRAC_CONST(0.014720577800046), FRAC_CONST(0.027565686808654) }, { FRAC_CONST(0.014635938186934), FRAC_CONST(0.027610719175499) }, { FRAC_CONST(0.014551160814797), FRAC_CONST(0.027655491659740) }, { FRAC_CONST(0.014466246481592), FRAC_CONST(0.027700003839960) }, { FRAC_CONST(0.014381195986567), FRAC_CONST(0.027744255297195) }, { FRAC_CONST(0.014296010130247), FRAC_CONST(0.027788245614933) }, { FRAC_CONST(0.014210689714436), FRAC_CONST(0.027831974379120) }, { FRAC_CONST(0.014125235542201), FRAC_CONST(0.027875441178165) }, { FRAC_CONST(0.014039648417870), FRAC_CONST(0.027918645602941) }, { FRAC_CONST(0.013953929147020), FRAC_CONST(0.027961587246792) }, { FRAC_CONST(0.013868078536476), FRAC_CONST(0.028004265705534) }, { FRAC_CONST(0.013782097394294), FRAC_CONST(0.028046680577462) }, { FRAC_CONST(0.013695986529763), FRAC_CONST(0.028088831463351) }, { FRAC_CONST(0.013609746753390), FRAC_CONST(0.028130717966461) }, { FRAC_CONST(0.013523378876898), FRAC_CONST(0.028172339692540) }, { FRAC_CONST(0.013436883713214), FRAC_CONST(0.028213696249828) }, { FRAC_CONST(0.013350262076462), FRAC_CONST(0.028254787249062) }, { FRAC_CONST(0.013263514781960), FRAC_CONST(0.028295612303478) }, { FRAC_CONST(0.013176642646205), FRAC_CONST(0.028336171028814) }, { FRAC_CONST(0.013089646486871), FRAC_CONST(0.028376463043317) }, { FRAC_CONST(0.013002527122799), FRAC_CONST(0.028416487967743) }, { FRAC_CONST(0.012915285373990), FRAC_CONST(0.028456245425361) }, { FRAC_CONST(0.012827922061597), FRAC_CONST(0.028495735041960) }, { FRAC_CONST(0.012740438007915), FRAC_CONST(0.028534956445849) }, { FRAC_CONST(0.012652834036379), FRAC_CONST(0.028573909267859) }, { FRAC_CONST(0.012565110971550), FRAC_CONST(0.028612593141354) }, { FRAC_CONST(0.012477269639111), FRAC_CONST(0.028651007702224) }, { FRAC_CONST(0.012389310865858), FRAC_CONST(0.028689152588899) }, { FRAC_CONST(0.012301235479693), FRAC_CONST(0.028727027442343) }, { FRAC_CONST(0.012213044309615), FRAC_CONST(0.028764631906065) }, { FRAC_CONST(0.012124738185712), FRAC_CONST(0.028801965626115) }, { FRAC_CONST(0.012036317939156), FRAC_CONST(0.028839028251097) }, { FRAC_CONST(0.011947784402191), FRAC_CONST(0.028875819432161) }, { FRAC_CONST(0.011859138408130), FRAC_CONST(0.028912338823015) }, { FRAC_CONST(0.011770380791341), FRAC_CONST(0.028948586079925) }, { FRAC_CONST(0.011681512387245), FRAC_CONST(0.028984560861718) }, { FRAC_CONST(0.011592534032306), FRAC_CONST(0.029020262829785) }, { FRAC_CONST(0.011503446564022), FRAC_CONST(0.029055691648087) }, { FRAC_CONST(0.011414250820918), FRAC_CONST(0.029090846983152) }, { FRAC_CONST(0.011324947642537), FRAC_CONST(0.029125728504087) }, { FRAC_CONST(0.011235537869437), FRAC_CONST(0.029160335882573) }, { FRAC_CONST(0.011146022343175), FRAC_CONST(0.029194668792871) }, { FRAC_CONST(0.011056401906305), FRAC_CONST(0.029228726911828) }, { FRAC_CONST(0.010966677402371), FRAC_CONST(0.029262509918876) }, { FRAC_CONST(0.010876849675891), FRAC_CONST(0.029296017496036) }, { FRAC_CONST(0.010786919572361), FRAC_CONST(0.029329249327922) }, { FRAC_CONST(0.010696887938235), FRAC_CONST(0.029362205101743) }, { FRAC_CONST(0.010606755620926), FRAC_CONST(0.029394884507308) }, { FRAC_CONST(0.010516523468793), FRAC_CONST(0.029427287237024) }, { FRAC_CONST(0.010426192331137), FRAC_CONST(0.029459412985906) }, { FRAC_CONST(0.010335763058187), FRAC_CONST(0.029491261451573) }, { FRAC_CONST(0.010245236501099), FRAC_CONST(0.029522832334255) }, { FRAC_CONST(0.010154613511943), FRAC_CONST(0.029554125336796) }, { FRAC_CONST(0.010063894943698), FRAC_CONST(0.029585140164654) }, { FRAC_CONST(0.009973081650240), FRAC_CONST(0.029615876525905) }, { FRAC_CONST(0.009882174486340), FRAC_CONST(0.029646334131247) }, { FRAC_CONST(0.009791174307650), FRAC_CONST(0.029676512694001) }, { FRAC_CONST(0.009700081970699), FRAC_CONST(0.029706411930116) }, { FRAC_CONST(0.009608898332881), FRAC_CONST(0.029736031558168) }, { FRAC_CONST(0.009517624252453), FRAC_CONST(0.029765371299366) }, { FRAC_CONST(0.009426260588521), FRAC_CONST(0.029794430877553) }, { FRAC_CONST(0.009334808201034), FRAC_CONST(0.029823210019210) }, { FRAC_CONST(0.009243267950778), FRAC_CONST(0.029851708453456) }, { FRAC_CONST(0.009151640699363), FRAC_CONST(0.029879925912053) }, { FRAC_CONST(0.009059927309220), FRAC_CONST(0.029907862129408) }, { FRAC_CONST(0.008968128643591), FRAC_CONST(0.029935516842573) }, { FRAC_CONST(0.008876245566520), FRAC_CONST(0.029962889791254) }, { FRAC_CONST(0.008784278942845), FRAC_CONST(0.029989980717805) }, { FRAC_CONST(0.008692229638191), FRAC_CONST(0.030016789367235) }, { FRAC_CONST(0.008600098518961), FRAC_CONST(0.030043315487212) }, { FRAC_CONST(0.008507886452329), FRAC_CONST(0.030069558828062) }, { FRAC_CONST(0.008415594306230), FRAC_CONST(0.030095519142772) }, { FRAC_CONST(0.008323222949351), FRAC_CONST(0.030121196186994) }, { FRAC_CONST(0.008230773251129), FRAC_CONST(0.030146589719046) }, { FRAC_CONST(0.008138246081733), FRAC_CONST(0.030171699499915) }, { FRAC_CONST(0.008045642312067), FRAC_CONST(0.030196525293257) }, { FRAC_CONST(0.007952962813750), FRAC_CONST(0.030221066865402) }, { FRAC_CONST(0.007860208459119), FRAC_CONST(0.030245323985357) }, { FRAC_CONST(0.007767380121212), FRAC_CONST(0.030269296424803) }, { FRAC_CONST(0.007674478673766), FRAC_CONST(0.030292983958103) }, { FRAC_CONST(0.007581504991203), FRAC_CONST(0.030316386362302) }, { FRAC_CONST(0.007488459948628), FRAC_CONST(0.030339503417126) }, { FRAC_CONST(0.007395344421816), FRAC_CONST(0.030362334904989) }, { FRAC_CONST(0.007302159287206), FRAC_CONST(0.030384880610993) }, { FRAC_CONST(0.007208905421891), FRAC_CONST(0.030407140322928) }, { FRAC_CONST(0.007115583703613), FRAC_CONST(0.030429113831278) }, { FRAC_CONST(0.007022195010752), FRAC_CONST(0.030450800929220) }, { FRAC_CONST(0.006928740222316), FRAC_CONST(0.030472201412626) }, { FRAC_CONST(0.006835220217939), FRAC_CONST(0.030493315080068) }, { FRAC_CONST(0.006741635877866), FRAC_CONST(0.030514141732814) }, { FRAC_CONST(0.006647988082948), FRAC_CONST(0.030534681174838) }, { FRAC_CONST(0.006554277714635), FRAC_CONST(0.030554933212813) }, { FRAC_CONST(0.006460505654964), FRAC_CONST(0.030574897656119) }, { FRAC_CONST(0.006366672786553), FRAC_CONST(0.030594574316845) }, { FRAC_CONST(0.006272779992593), FRAC_CONST(0.030613963009786) }, { FRAC_CONST(0.006178828156839), FRAC_CONST(0.030633063552447) }, { FRAC_CONST(0.006084818163601), FRAC_CONST(0.030651875765048) }, { FRAC_CONST(0.005990750897737), FRAC_CONST(0.030670399470520) }, { FRAC_CONST(0.005896627244644), FRAC_CONST(0.030688634494512) }, { FRAC_CONST(0.005802448090250), FRAC_CONST(0.030706580665388) }, { FRAC_CONST(0.005708214321004), FRAC_CONST(0.030724237814232) }, { FRAC_CONST(0.005613926823871), FRAC_CONST(0.030741605774849) }, { FRAC_CONST(0.005519586486321), FRAC_CONST(0.030758684383764) }, { FRAC_CONST(0.005425194196321), FRAC_CONST(0.030775473480228) }, { FRAC_CONST(0.005330750842327), FRAC_CONST(0.030791972906214) }, { FRAC_CONST(0.005236257313276), FRAC_CONST(0.030808182506425) }, { FRAC_CONST(0.005141714498576), FRAC_CONST(0.030824102128288) }, { FRAC_CONST(0.005047123288102), FRAC_CONST(0.030839731621963) }, { FRAC_CONST(0.004952484572181), FRAC_CONST(0.030855070840339) }, { FRAC_CONST(0.004857799241589), FRAC_CONST(0.030870119639036) }, { FRAC_CONST(0.004763068187541), FRAC_CONST(0.030884877876411) }, { FRAC_CONST(0.004668292301681), FRAC_CONST(0.030899345413553) }, { FRAC_CONST(0.004573472476075), FRAC_CONST(0.030913522114288) }, { FRAC_CONST(0.004478609603205), FRAC_CONST(0.030927407845180) }, { FRAC_CONST(0.004383704575956), FRAC_CONST(0.030941002475530) }, { FRAC_CONST(0.004288758287610), FRAC_CONST(0.030954305877381) }, { FRAC_CONST(0.004193771631837), FRAC_CONST(0.030967317925516) }, { FRAC_CONST(0.004098745502689), FRAC_CONST(0.030980038497461) }, { FRAC_CONST(0.004003680794587), FRAC_CONST(0.030992467473486) }, { FRAC_CONST(0.003908578402316), FRAC_CONST(0.031004604736602) }, { FRAC_CONST(0.003813439221017), FRAC_CONST(0.031016450172571) }, { FRAC_CONST(0.003718264146176), FRAC_CONST(0.031028003669899) }, { FRAC_CONST(0.003623054073616), FRAC_CONST(0.031039265119839) }, { FRAC_CONST(0.003527809899492), FRAC_CONST(0.031050234416394) }, { FRAC_CONST(0.003432532520278), FRAC_CONST(0.031060911456318) }, { FRAC_CONST(0.003337222832760), FRAC_CONST(0.031071296139114) }, { FRAC_CONST(0.003241881734029), FRAC_CONST(0.031081388367037) }, { FRAC_CONST(0.003146510121474), FRAC_CONST(0.031091188045095) }, { FRAC_CONST(0.003051108892766), FRAC_CONST(0.031100695081051) }, { FRAC_CONST(0.002955678945860), FRAC_CONST(0.031109909385419) }, { FRAC_CONST(0.002860221178978), FRAC_CONST(0.031118830871473) }, { FRAC_CONST(0.002764736490604), FRAC_CONST(0.031127459455239) }, { FRAC_CONST(0.002669225779478), FRAC_CONST(0.031135795055501) }, { FRAC_CONST(0.002573689944583), FRAC_CONST(0.031143837593803) }, { FRAC_CONST(0.002478129885137), FRAC_CONST(0.031151586994444) }, { FRAC_CONST(0.002382546500589), FRAC_CONST(0.031159043184484) }, { FRAC_CONST(0.002286940690606), FRAC_CONST(0.031166206093743) }, { FRAC_CONST(0.002191313355067), FRAC_CONST(0.031173075654800) }, { FRAC_CONST(0.002095665394051), FRAC_CONST(0.031179651802998) }, { FRAC_CONST(0.001999997707835), FRAC_CONST(0.031185934476438) }, { FRAC_CONST(0.001904311196878), FRAC_CONST(0.031191923615985) }, { FRAC_CONST(0.001808606761820), FRAC_CONST(0.031197619165268) }, { FRAC_CONST(0.001712885303465), FRAC_CONST(0.031203021070678) }, { FRAC_CONST(0.001617147722782), FRAC_CONST(0.031208129281370) }, { FRAC_CONST(0.001521394920889), FRAC_CONST(0.031212943749264) }, { FRAC_CONST(0.001425627799047), FRAC_CONST(0.031217464429043) }, { FRAC_CONST(0.001329847258653), FRAC_CONST(0.031221691278159) }, { FRAC_CONST(0.001234054201231), FRAC_CONST(0.031225624256825) }, { FRAC_CONST(0.001138249528420), FRAC_CONST(0.031229263328024) }, { FRAC_CONST(0.001042434141971), FRAC_CONST(0.031232608457502) }, { FRAC_CONST(0.000946608943736), FRAC_CONST(0.031235659613775) }, { FRAC_CONST(0.000850774835656), FRAC_CONST(0.031238416768124) }, { FRAC_CONST(0.000754932719759), FRAC_CONST(0.031240879894597) }, { FRAC_CONST(0.000659083498149), FRAC_CONST(0.031243048970010) }, { FRAC_CONST(0.000563228072993), FRAC_CONST(0.031244923973948) }, { FRAC_CONST(0.000467367346520), FRAC_CONST(0.031246504888762) }, { FRAC_CONST(0.000371502221008), FRAC_CONST(0.031247791699571) }, { FRAC_CONST(0.000275633598775), FRAC_CONST(0.031248784394264) }, { FRAC_CONST(0.000179762382174), FRAC_CONST(0.031249482963498) }, { FRAC_CONST(0.000083889473581), FRAC_CONST(0.031249887400697) } }; /* 64 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_256[] = { { FRAC_CONST(0.088387931675923), FRAC_CONST(0.000271171628935) }, { FRAC_CONST(0.088354655998507), FRAC_CONST(0.002440238387037) }, { FRAC_CONST(0.088268158780110), FRAC_CONST(0.004607835236780) }, { FRAC_CONST(0.088128492123423), FRAC_CONST(0.006772656498875) }, { FRAC_CONST(0.087935740158418), FRAC_CONST(0.008933398165942) }, { FRAC_CONST(0.087690018991670), FRAC_CONST(0.011088758687994) }, { FRAC_CONST(0.087391476636423), FRAC_CONST(0.013237439756448) }, { FRAC_CONST(0.087040292923427), FRAC_CONST(0.015378147086172) }, { FRAC_CONST(0.086636679392621), FRAC_CONST(0.017509591195118) }, { FRAC_CONST(0.086180879165703), FRAC_CONST(0.019630488181053) }, { FRAC_CONST(0.085673166799686), FRAC_CONST(0.021739560494940) }, { FRAC_CONST(0.085113848121515), FRAC_CONST(0.023835537710479) }, { FRAC_CONST(0.084503260043847), FRAC_CONST(0.025917157289369) }, { FRAC_CONST(0.083841770362110), FRAC_CONST(0.027983165341813) }, { FRAC_CONST(0.083129777532952), FRAC_CONST(0.030032317381813) }, { FRAC_CONST(0.082367710434230), FRAC_CONST(0.032063379076803) }, { FRAC_CONST(0.081556028106671), FRAC_CONST(0.034075126991164) }, { FRAC_CONST(0.080695219477356), FRAC_CONST(0.036066349323177) }, { FRAC_CONST(0.079785803065216), FRAC_CONST(0.038035846634965) }, { FRAC_CONST(0.078828326668693), FRAC_CONST(0.039982432574992) }, { FRAC_CONST(0.077823367035766), FRAC_CONST(0.041904934592675) }, { FRAC_CONST(0.076771529516540), FRAC_CONST(0.043802194644686) }, { FRAC_CONST(0.075673447698606), FRAC_CONST(0.045673069892513) }, { FRAC_CONST(0.074529783025390), FRAC_CONST(0.047516433390863) }, { FRAC_CONST(0.073341224397728), FRAC_CONST(0.049331174766491) }, { FRAC_CONST(0.072108487758894), FRAC_CONST(0.051116200887052) }, { FRAC_CONST(0.070832315663343), FRAC_CONST(0.052870436519557) }, { FRAC_CONST(0.069513476829429), FRAC_CONST(0.054592824978055) }, { FRAC_CONST(0.068152765676348), FRAC_CONST(0.056282328760143) }, { FRAC_CONST(0.066751001845620), FRAC_CONST(0.057937930171918) }, { FRAC_CONST(0.065309029707361), FRAC_CONST(0.059558631940996) }, { FRAC_CONST(0.063827717851668), FRAC_CONST(0.061143457817234) }, { FRAC_CONST(0.062307958565413), FRAC_CONST(0.062691453160784) }, { FRAC_CONST(0.060750667294763), FRAC_CONST(0.064201685517134) }, { FRAC_CONST(0.059156782093749), FRAC_CONST(0.065673245178784) }, { FRAC_CONST(0.057527263059216), FRAC_CONST(0.067105245733220) }, { FRAC_CONST(0.055863091752499), FRAC_CONST(0.068496824596852) }, { FRAC_CONST(0.054165270608165), FRAC_CONST(0.069847143534609) }, { FRAC_CONST(0.052434822330188), FRAC_CONST(0.071155389164853) }, { FRAC_CONST(0.050672789275903), FRAC_CONST(0.072420773449336) }, { FRAC_CONST(0.048880232828135), FRAC_CONST(0.073642534167879) }, { FRAC_CONST(0.047058232755862), FRAC_CONST(0.074819935377512) }, { FRAC_CONST(0.045207886563797), FRAC_CONST(0.075952267855771) }, { FRAC_CONST(0.043330308831298), FRAC_CONST(0.077038849527912) }, { FRAC_CONST(0.041426630540984), FRAC_CONST(0.078079025877766) }, { FRAC_CONST(0.039497998397473), FRAC_CONST(0.079072170341994) }, { FRAC_CONST(0.037545574136653), FRAC_CONST(0.080017684687506) }, { FRAC_CONST(0.035570533825892), FRAC_CONST(0.080914999371817) }, { FRAC_CONST(0.033574067155622), FRAC_CONST(0.081763573886112) }, { FRAC_CONST(0.031557376722714), FRAC_CONST(0.082562897080836) }, { FRAC_CONST(0.029521677306074), FRAC_CONST(0.083312487473584) }, { FRAC_CONST(0.027468195134911), FRAC_CONST(0.084011893539132) }, { FRAC_CONST(0.025398167150101), FRAC_CONST(0.084660693981419) }, { FRAC_CONST(0.023312840259098), FRAC_CONST(0.085258497987320) }, { FRAC_CONST(0.021213470584847), FRAC_CONST(0.085804945462053) }, { FRAC_CONST(0.019101322709138), FRAC_CONST(0.086299707246093) }, { FRAC_CONST(0.016977668910873), FRAC_CONST(0.086742485313442) }, { FRAC_CONST(0.014843788399692), FRAC_CONST(0.087133012951149) }, { FRAC_CONST(0.012700966545425), FRAC_CONST(0.087471054919968) }, { FRAC_CONST(0.010550494103830), FRAC_CONST(0.087756407596056) }, { FRAC_CONST(0.008393666439096), FRAC_CONST(0.087988899093631) }, { FRAC_CONST(0.006231782743558), FRAC_CONST(0.088168389368510) }, { FRAC_CONST(0.004066145255116), FRAC_CONST(0.088294770302461) }, { FRAC_CONST(0.001898058472816), FRAC_CONST(0.088367965768336) } }; #ifdef LD_DEC /* 128 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_1024[] = { { FRAC_CONST(0.044194160825012), FRAC_CONST(0.000033896503468) }, { FRAC_CONST(0.044193120897389), FRAC_CONST(0.000305066138364) }, { FRAC_CONST(0.044190417123742), FRAC_CONST(0.000576224287693) }, { FRAC_CONST(0.044186049605866), FRAC_CONST(0.000847360742503) }, { FRAC_CONST(0.044180018508197), FRAC_CONST(0.001118465294660) }, { FRAC_CONST(0.044172324057802), FRAC_CONST(0.001389527737231) }, { FRAC_CONST(0.044162966544372), FRAC_CONST(0.001660537864867) }, { FRAC_CONST(0.044151946320213), FRAC_CONST(0.001931485474192) }, { FRAC_CONST(0.044139263800230), FRAC_CONST(0.002202360364180) }, { FRAC_CONST(0.044124919461912), FRAC_CONST(0.002473152336546) }, { FRAC_CONST(0.044108913845316), FRAC_CONST(0.002743851196123) }, { FRAC_CONST(0.044091247553044), FRAC_CONST(0.003014446751254) }, { FRAC_CONST(0.044071921250223), FRAC_CONST(0.003284928814169) }, { FRAC_CONST(0.044050935664476), FRAC_CONST(0.003555287201370) }, { FRAC_CONST(0.044028291585898), FRAC_CONST(0.003825511734018) }, { FRAC_CONST(0.044003989867028), FRAC_CONST(0.004095592238311) }, { FRAC_CONST(0.043978031422810), FRAC_CONST(0.004365518545871) }, { FRAC_CONST(0.043950417230565), FRAC_CONST(0.004635280494126) }, { FRAC_CONST(0.043921148329953), FRAC_CONST(0.004904867926689) }, { FRAC_CONST(0.043890225822930), FRAC_CONST(0.005174270693748) }, { FRAC_CONST(0.043857650873712), FRAC_CONST(0.005443478652439) }, { FRAC_CONST(0.043823424708727), FRAC_CONST(0.005712481667236) }, { FRAC_CONST(0.043787548616571), FRAC_CONST(0.005981269610326) }, { FRAC_CONST(0.043750023947958), FRAC_CONST(0.006249832361997) }, { FRAC_CONST(0.043710852115672), FRAC_CONST(0.006518159811011) }, { FRAC_CONST(0.043670034594508), FRAC_CONST(0.006786241854993) }, { FRAC_CONST(0.043627572921225), FRAC_CONST(0.007054068400804) }, { FRAC_CONST(0.043583468694479), FRAC_CONST(0.007321629364927) }, { FRAC_CONST(0.043537723574771), FRAC_CONST(0.007588914673843) }, { FRAC_CONST(0.043490339284377), FRAC_CONST(0.007855914264410) }, { FRAC_CONST(0.043441317607290), FRAC_CONST(0.008122618084246) }, { FRAC_CONST(0.043390660389149), FRAC_CONST(0.008389016092101) }, { FRAC_CONST(0.043338369537168), FRAC_CONST(0.008655098258243) }, { FRAC_CONST(0.043284447020070), FRAC_CONST(0.008920854564826) }, { FRAC_CONST(0.043228894868005), FRAC_CONST(0.009186275006278) }, { FRAC_CONST(0.043171715172482), FRAC_CONST(0.009451349589667) }, { FRAC_CONST(0.043112910086283), FRAC_CONST(0.009716068335087) }, { FRAC_CONST(0.043052481823387), FRAC_CONST(0.009980421276025) }, { FRAC_CONST(0.042990432658884), FRAC_CONST(0.010244398459743) }, { FRAC_CONST(0.042926764928889), FRAC_CONST(0.010507989947649) }, { FRAC_CONST(0.042861481030457), FRAC_CONST(0.010771185815673) }, { FRAC_CONST(0.042794583421490), FRAC_CONST(0.011033976154639) }, { FRAC_CONST(0.042726074620644), FRAC_CONST(0.011296351070639) }, { FRAC_CONST(0.042655957207238), FRAC_CONST(0.011558300685406) }, { FRAC_CONST(0.042584233821153), FRAC_CONST(0.011819815136685) }, { FRAC_CONST(0.042510907162732), FRAC_CONST(0.012080884578604) }, { FRAC_CONST(0.042435979992684), FRAC_CONST(0.012341499182048) }, { FRAC_CONST(0.042359455131975), FRAC_CONST(0.012601649135022) }, { FRAC_CONST(0.042281335461721), FRAC_CONST(0.012861324643029) }, { FRAC_CONST(0.042201623923085), FRAC_CONST(0.013120515929433) }, { FRAC_CONST(0.042120323517160), FRAC_CONST(0.013379213235827) }, { FRAC_CONST(0.042037437304862), FRAC_CONST(0.013637406822406) }, { FRAC_CONST(0.041952968406809), FRAC_CONST(0.013895086968325) }, { FRAC_CONST(0.041866920003207), FRAC_CONST(0.014152243972073) }, { FRAC_CONST(0.041779295333730), FRAC_CONST(0.014408868151835) }, { FRAC_CONST(0.041690097697398), FRAC_CONST(0.014664949845855) }, { FRAC_CONST(0.041599330452450), FRAC_CONST(0.014920479412801) }, { FRAC_CONST(0.041506997016224), FRAC_CONST(0.015175447232131) }, { FRAC_CONST(0.041413100865019), FRAC_CONST(0.015429843704450) }, { FRAC_CONST(0.041317645533974), FRAC_CONST(0.015683659251874) }, { FRAC_CONST(0.041220634616927), FRAC_CONST(0.015936884318392) }, { FRAC_CONST(0.041122071766285), FRAC_CONST(0.016189509370223) }, { FRAC_CONST(0.041021960692883), FRAC_CONST(0.016441524896177) }, { FRAC_CONST(0.040920305165846), FRAC_CONST(0.016692921408010) }, { FRAC_CONST(0.040817109012449), FRAC_CONST(0.016943689440788) }, { FRAC_CONST(0.040712376117967), FRAC_CONST(0.017193819553235) }, { FRAC_CONST(0.040606110425535), FRAC_CONST(0.017443302328094) }, { FRAC_CONST(0.040498315935996), FRAC_CONST(0.017692128372479) }, { FRAC_CONST(0.040388996707752), FRAC_CONST(0.017940288318230) }, { FRAC_CONST(0.040278156856609), FRAC_CONST(0.018187772822267) }, { FRAC_CONST(0.040165800555627), FRAC_CONST(0.018434572566936) }, { FRAC_CONST(0.040051932034955), FRAC_CONST(0.018680678260367) }, { FRAC_CONST(0.039936555581679), FRAC_CONST(0.018926080636820) }, { FRAC_CONST(0.039819675539659), FRAC_CONST(0.019170770457035) }, { FRAC_CONST(0.039701296309360), FRAC_CONST(0.019414738508577) }, { FRAC_CONST(0.039581422347694), FRAC_CONST(0.019657975606187) }, { FRAC_CONST(0.039460058167849), FRAC_CONST(0.019900472592126) }, { FRAC_CONST(0.039337208339116), FRAC_CONST(0.020142220336521) }, { FRAC_CONST(0.039212877486723), FRAC_CONST(0.020383209737704) }, { FRAC_CONST(0.039087070291656), FRAC_CONST(0.020623431722561) }, { FRAC_CONST(0.038959791490485), FRAC_CONST(0.020862877246870) }, { FRAC_CONST(0.038831045875184), FRAC_CONST(0.021101537295642) }, { FRAC_CONST(0.038700838292953), FRAC_CONST(0.021339402883462) }, { FRAC_CONST(0.038569173646034), FRAC_CONST(0.021576465054824) }, { FRAC_CONST(0.038436056891527), FRAC_CONST(0.021812714884472) }, { FRAC_CONST(0.038301493041202), FRAC_CONST(0.022048143477734) }, { FRAC_CONST(0.038165487161312), FRAC_CONST(0.022282741970855) }, { FRAC_CONST(0.038028044372402), FRAC_CONST(0.022516501531335) }, { FRAC_CONST(0.037889169849115), FRAC_CONST(0.022749413358259) }, { FRAC_CONST(0.037748868819998), FRAC_CONST(0.022981468682628) }, { FRAC_CONST(0.037607146567305), FRAC_CONST(0.023212658767690) }, { FRAC_CONST(0.037464008426800), FRAC_CONST(0.023442974909269) }, { FRAC_CONST(0.037319459787553), FRAC_CONST(0.023672408436094) }, { FRAC_CONST(0.037173506091737), FRAC_CONST(0.023900950710120) }, { FRAC_CONST(0.037026152834428), FRAC_CONST(0.024128593126861) }, { FRAC_CONST(0.036877405563392), FRAC_CONST(0.024355327115708) }, { FRAC_CONST(0.036727269878879), FRAC_CONST(0.024581144140255) }, { FRAC_CONST(0.036575751433414), FRAC_CONST(0.024806035698618) }, { FRAC_CONST(0.036422855931580), FRAC_CONST(0.025029993323758) }, { FRAC_CONST(0.036268589129807), FRAC_CONST(0.025253008583796) }, { FRAC_CONST(0.036112956836151), FRAC_CONST(0.025475073082334) }, { FRAC_CONST(0.035955964910083), FRAC_CONST(0.025696178458769) }, { FRAC_CONST(0.035797619262257), FRAC_CONST(0.025916316388609) }, { FRAC_CONST(0.035637925854300), FRAC_CONST(0.026135478583784) }, { FRAC_CONST(0.035476890698576), FRAC_CONST(0.026353656792963) }, { FRAC_CONST(0.035314519857970), FRAC_CONST(0.026570842801858) }, { FRAC_CONST(0.035150819445650), FRAC_CONST(0.026787028433540) }, { FRAC_CONST(0.034985795624846), FRAC_CONST(0.027002205548742) }, { FRAC_CONST(0.034819454608610), FRAC_CONST(0.027216366046166) }, { FRAC_CONST(0.034651802659589), FRAC_CONST(0.027429501862792) }, { FRAC_CONST(0.034482846089783), FRAC_CONST(0.027641604974175) }, { FRAC_CONST(0.034312591260311), FRAC_CONST(0.027852667394755) }, { FRAC_CONST(0.034141044581172), FRAC_CONST(0.028062681178149) }, { FRAC_CONST(0.033968212511001), FRAC_CONST(0.028271638417458) }, { FRAC_CONST(0.033794101556828), FRAC_CONST(0.028479531245560) }, { FRAC_CONST(0.033618718273831), FRAC_CONST(0.028686351835407) }, { FRAC_CONST(0.033442069265093), FRAC_CONST(0.028892092400321) }, { FRAC_CONST(0.033264161181349), FRAC_CONST(0.029096745194286) }, { FRAC_CONST(0.033085000720737), FRAC_CONST(0.029300302512241) }, { FRAC_CONST(0.032904594628548), FRAC_CONST(0.029502756690366) }, { FRAC_CONST(0.032722949696969), FRAC_CONST(0.029704100106376) }, { FRAC_CONST(0.032540072764829), FRAC_CONST(0.029904325179807) }, { FRAC_CONST(0.032355970717341), FRAC_CONST(0.030103424372297) }, { FRAC_CONST(0.032170650485843), FRAC_CONST(0.030301390187873) }, { FRAC_CONST(0.031984119047537), FRAC_CONST(0.030498215173235) }, { FRAC_CONST(0.031796383425227), FRAC_CONST(0.030693891918034) }, { FRAC_CONST(0.031607450687052), FRAC_CONST(0.030888413055150) }, { FRAC_CONST(0.031417327946223), FRAC_CONST(0.031081771260973) }, { FRAC_CONST(0.031226022360754), FRAC_CONST(0.031273959255676) }, { FRAC_CONST(0.031033541133193), FRAC_CONST(0.031464969803488) }, { FRAC_CONST(0.030839891510348), FRAC_CONST(0.031654795712972) }, { FRAC_CONST(0.030645080783018), FRAC_CONST(0.031843429837288) }, { FRAC_CONST(0.030449116285718), FRAC_CONST(0.032030865074469) }, { FRAC_CONST(0.030252005396399), FRAC_CONST(0.032217094367684) }, { FRAC_CONST(0.030053755536176), FRAC_CONST(0.032402110705505) }, { FRAC_CONST(0.029854374169043), FRAC_CONST(0.032585907122172) }, { FRAC_CONST(0.029653868801596), FRAC_CONST(0.032768476697853) }, { FRAC_CONST(0.029452246982750), FRAC_CONST(0.032949812558907) }, { FRAC_CONST(0.029249516303451), FRAC_CONST(0.033129907878142) }, { FRAC_CONST(0.029045684396395), FRAC_CONST(0.033308755875070) }, { FRAC_CONST(0.028840758935738), FRAC_CONST(0.033486349816166) }, { FRAC_CONST(0.028634747636808), FRAC_CONST(0.033662683015118) }, { FRAC_CONST(0.028427658255815), FRAC_CONST(0.033837748833080) }, { FRAC_CONST(0.028219498589555), FRAC_CONST(0.034011540678924) }, { FRAC_CONST(0.028010276475123), FRAC_CONST(0.034184052009485) }, { FRAC_CONST(0.027799999789613), FRAC_CONST(0.034355276329809) }, { FRAC_CONST(0.027588676449824), FRAC_CONST(0.034525207193396) }, { FRAC_CONST(0.027376314411959), FRAC_CONST(0.034693838202447) }, { FRAC_CONST(0.027162921671330), FRAC_CONST(0.034861163008098) }, { FRAC_CONST(0.026948506262053), FRAC_CONST(0.035027175310665) }, { FRAC_CONST(0.026733076256746), FRAC_CONST(0.035191868859880) }, { FRAC_CONST(0.026516639766228), FRAC_CONST(0.035355237455122) }, { FRAC_CONST(0.026299204939210), FRAC_CONST(0.035517274945657) }, { FRAC_CONST(0.026080779961991), FRAC_CONST(0.035677975230865) }, { FRAC_CONST(0.025861373058146), FRAC_CONST(0.035837332260471) }, { FRAC_CONST(0.025640992488223), FRAC_CONST(0.035995340034772) }, { FRAC_CONST(0.025419646549425), FRAC_CONST(0.036151992604866) }, { FRAC_CONST(0.025197343575302), FRAC_CONST(0.036307284072871) }, { FRAC_CONST(0.024974091935435), FRAC_CONST(0.036461208592152) }, { FRAC_CONST(0.024749900035122), FRAC_CONST(0.036613760367538) }, { FRAC_CONST(0.024524776315061), FRAC_CONST(0.036764933655540) }, { FRAC_CONST(0.024298729251033), FRAC_CONST(0.036914722764569) }, { FRAC_CONST(0.024071767353583), FRAC_CONST(0.037063122055150) }, { FRAC_CONST(0.023843899167697), FRAC_CONST(0.037210125940135) }, { FRAC_CONST(0.023615133272485), FRAC_CONST(0.037355728884908) }, { FRAC_CONST(0.023385478280852), FRAC_CONST(0.037499925407603) }, { FRAC_CONST(0.023154942839179), FRAC_CONST(0.037642710079302) }, { FRAC_CONST(0.022923535626995), FRAC_CONST(0.037784077524241) }, { FRAC_CONST(0.022691265356652), FRAC_CONST(0.037924022420018) }, { FRAC_CONST(0.022458140772993), FRAC_CONST(0.038062539497785) }, { FRAC_CONST(0.022224170653027), FRAC_CONST(0.038199623542453) }, { FRAC_CONST(0.021989363805598), FRAC_CONST(0.038335269392885) }, { FRAC_CONST(0.021753729071049), FRAC_CONST(0.038469471942092) }, { FRAC_CONST(0.021517275320897), FRAC_CONST(0.038602226137423) }, { FRAC_CONST(0.021280011457490), FRAC_CONST(0.038733526980758) }, { FRAC_CONST(0.021041946413679), FRAC_CONST(0.038863369528695) }, { FRAC_CONST(0.020803089152479), FRAC_CONST(0.038991748892734) }, { FRAC_CONST(0.020563448666730), FRAC_CONST(0.039118660239466) }, { FRAC_CONST(0.020323033978761), FRAC_CONST(0.039244098790750) }, { FRAC_CONST(0.020081854140050), FRAC_CONST(0.039368059823895) }, { FRAC_CONST(0.019839918230880), FRAC_CONST(0.039490538671839) }, { FRAC_CONST(0.019597235360003), FRAC_CONST(0.039611530723322) }, { FRAC_CONST(0.019353814664291), FRAC_CONST(0.039731031423061) }, { FRAC_CONST(0.019109665308395), FRAC_CONST(0.039849036271924) }, { FRAC_CONST(0.018864796484402), FRAC_CONST(0.039965540827094) }, { FRAC_CONST(0.018619217411483), FRAC_CONST(0.040080540702240) }, { FRAC_CONST(0.018372937335552), FRAC_CONST(0.040194031567683) }, { FRAC_CONST(0.018125965528915), FRAC_CONST(0.040306009150554) }, { FRAC_CONST(0.017878311289921), FRAC_CONST(0.040416469234963) }, { FRAC_CONST(0.017629983942612), FRAC_CONST(0.040525407662148) }, { FRAC_CONST(0.017380992836371), FRAC_CONST(0.040632820330639) }, { FRAC_CONST(0.017131347345575), FRAC_CONST(0.040738703196411) }, { FRAC_CONST(0.016881056869233), FRAC_CONST(0.040843052273033) }, { FRAC_CONST(0.016630130830641), FRAC_CONST(0.040945863631822) }, { FRAC_CONST(0.016378578677023), FRAC_CONST(0.041047133401988) }, { FRAC_CONST(0.016126409879175), FRAC_CONST(0.041146857770781) }, { FRAC_CONST(0.015873633931110), FRAC_CONST(0.041245032983635) }, { FRAC_CONST(0.015620260349699), FRAC_CONST(0.041341655344309) }, { FRAC_CONST(0.015366298674314), FRAC_CONST(0.041436721215026) }, { FRAC_CONST(0.015111758466470), FRAC_CONST(0.041530227016609) }, { FRAC_CONST(0.014856649309460), FRAC_CONST(0.041622169228618) }, { FRAC_CONST(0.014600980808001), FRAC_CONST(0.041712544389481) }, { FRAC_CONST(0.014344762587867), FRAC_CONST(0.041801349096623) }, { FRAC_CONST(0.014088004295529), FRAC_CONST(0.041888580006598) }, { FRAC_CONST(0.013830715597792), FRAC_CONST(0.041974233835211) }, { FRAC_CONST(0.013572906181430), FRAC_CONST(0.042058307357645) }, { FRAC_CONST(0.013314585752822), FRAC_CONST(0.042140797408577) }, { FRAC_CONST(0.013055764037585), FRAC_CONST(0.042221700882306) }, { FRAC_CONST(0.012796450780212), FRAC_CONST(0.042301014732860) }, { FRAC_CONST(0.012536655743699), FRAC_CONST(0.042378735974118) }, { FRAC_CONST(0.012276388709183), FRAC_CONST(0.042454861679919) }, { FRAC_CONST(0.012015659475571), FRAC_CONST(0.042529388984173) }, { FRAC_CONST(0.011754477859172), FRAC_CONST(0.042602315080970) }, { FRAC_CONST(0.011492853693324), FRAC_CONST(0.042673637224683) }, { FRAC_CONST(0.011230796828031), FRAC_CONST(0.042743352730074) }, { FRAC_CONST(0.010968317129584), FRAC_CONST(0.042811458972393) }, { FRAC_CONST(0.010705424480197), FRAC_CONST(0.042877953387479) }, { FRAC_CONST(0.010442128777629), FRAC_CONST(0.042942833471854) }, { FRAC_CONST(0.010178439934815), FRAC_CONST(0.043006096782821) }, { FRAC_CONST(0.009914367879490), FRAC_CONST(0.043067740938551) }, { FRAC_CONST(0.009649922553818), FRAC_CONST(0.043127763618177) }, { FRAC_CONST(0.009385113914016), FRAC_CONST(0.043186162561878) }, { FRAC_CONST(0.009119951929979), FRAC_CONST(0.043242935570968) }, { FRAC_CONST(0.008854446584907), FRAC_CONST(0.043298080507974) }, { FRAC_CONST(0.008588607874926), FRAC_CONST(0.043351595296722) }, { FRAC_CONST(0.008322445808712), FRAC_CONST(0.043403477922409) }, { FRAC_CONST(0.008055970407118), FRAC_CONST(0.043453726431684) }, { FRAC_CONST(0.007789191702791), FRAC_CONST(0.043502338932719) }, { FRAC_CONST(0.007522119739798), FRAC_CONST(0.043549313595281) }, { FRAC_CONST(0.007254764573250), FRAC_CONST(0.043594648650800) }, { FRAC_CONST(0.006987136268915), FRAC_CONST(0.043638342392438) }, { FRAC_CONST(0.006719244902849), FRAC_CONST(0.043680393175148) }, { FRAC_CONST(0.006451100561010), FRAC_CONST(0.043720799415744) }, { FRAC_CONST(0.006182713338881), FRAC_CONST(0.043759559592953) }, { FRAC_CONST(0.005914093341090), FRAC_CONST(0.043796672247476) }, { FRAC_CONST(0.005645250681027), FRAC_CONST(0.043832135982044) }, { FRAC_CONST(0.005376195480466), FRAC_CONST(0.043865949461465) }, { FRAC_CONST(0.005106937869184), FRAC_CONST(0.043898111412683) }, { FRAC_CONST(0.004837487984578), FRAC_CONST(0.043928620624817) }, { FRAC_CONST(0.004567855971284), FRAC_CONST(0.043957475949213) }, { FRAC_CONST(0.004298051980793), FRAC_CONST(0.043984676299484) }, { FRAC_CONST(0.004028086171076), FRAC_CONST(0.044010220651553) }, { FRAC_CONST(0.003757968706190), FRAC_CONST(0.044034108043689) }, { FRAC_CONST(0.003487709755907), FRAC_CONST(0.044056337576546) }, { FRAC_CONST(0.003217319495322), FRAC_CONST(0.044076908413193) }, { FRAC_CONST(0.002946808104477), FRAC_CONST(0.044095819779151) }, { FRAC_CONST(0.002676185767973), FRAC_CONST(0.044113070962418) }, { FRAC_CONST(0.002405462674586), FRAC_CONST(0.044128661313495) }, { FRAC_CONST(0.002134649016890), FRAC_CONST(0.044142590245416) }, { FRAC_CONST(0.001863754990865), FRAC_CONST(0.044154857233763) }, { FRAC_CONST(0.001592790795518), FRAC_CONST(0.044165461816692) }, { FRAC_CONST(0.001321766632497), FRAC_CONST(0.044174403594946) }, { FRAC_CONST(0.001050692705710), FRAC_CONST(0.044181682231873) }, { FRAC_CONST(0.000779579220936), FRAC_CONST(0.044187297453434) }, { FRAC_CONST(0.000508436385446), FRAC_CONST(0.044191249048222) }, { FRAC_CONST(0.000237274407613), FRAC_CONST(0.044193536867459) } }; #endif // LD_DEC #ifdef ALLOW_SMALL_FRAMELENGTH /* 480 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_1920[] = { { FRAC_CONST(0.032274858518097), FRAC_CONST(0.000013202404176) }, { FRAC_CONST(0.032274642494505), FRAC_CONST(0.000118821372483) }, { FRAC_CONST(0.032274080835421), FRAC_CONST(0.000224439068308) }, { FRAC_CONST(0.032273173546860), FRAC_CONST(0.000330054360572) }, { FRAC_CONST(0.032271920638538), FRAC_CONST(0.000435666118218) }, { FRAC_CONST(0.032270322123873), FRAC_CONST(0.000541273210231) }, { FRAC_CONST(0.032268378019984), FRAC_CONST(0.000646874505642) }, { FRAC_CONST(0.032266088347691), FRAC_CONST(0.000752468873546) }, { FRAC_CONST(0.032263453131514), FRAC_CONST(0.000858055183114) }, { FRAC_CONST(0.032260472399674), FRAC_CONST(0.000963632303600) }, { FRAC_CONST(0.032257146184092), FRAC_CONST(0.001069199104358) }, { FRAC_CONST(0.032253474520390), FRAC_CONST(0.001174754454853) }, { FRAC_CONST(0.032249457447888), FRAC_CONST(0.001280297224671) }, { FRAC_CONST(0.032245095009606), FRAC_CONST(0.001385826283535) }, { FRAC_CONST(0.032240387252262), FRAC_CONST(0.001491340501313) }, { FRAC_CONST(0.032235334226272), FRAC_CONST(0.001596838748031) }, { FRAC_CONST(0.032229935985750), FRAC_CONST(0.001702319893890) }, { FRAC_CONST(0.032224192588507), FRAC_CONST(0.001807782809271) }, { FRAC_CONST(0.032218104096050), FRAC_CONST(0.001913226364749) }, { FRAC_CONST(0.032211670573582), FRAC_CONST(0.002018649431111) }, { FRAC_CONST(0.032204892090000), FRAC_CONST(0.002124050879359) }, { FRAC_CONST(0.032197768717898), FRAC_CONST(0.002229429580728) }, { FRAC_CONST(0.032190300533560), FRAC_CONST(0.002334784406698) }, { FRAC_CONST(0.032182487616965), FRAC_CONST(0.002440114229003) }, { FRAC_CONST(0.032174330051782), FRAC_CONST(0.002545417919644) }, { FRAC_CONST(0.032165827925374), FRAC_CONST(0.002650694350905) }, { FRAC_CONST(0.032156981328790), FRAC_CONST(0.002755942395358) }, { FRAC_CONST(0.032147790356771), FRAC_CONST(0.002861160925883) }, { FRAC_CONST(0.032138255107744), FRAC_CONST(0.002966348815672) }, { FRAC_CONST(0.032128375683825), FRAC_CONST(0.003071504938250) }, { FRAC_CONST(0.032118152190814), FRAC_CONST(0.003176628167476) }, { FRAC_CONST(0.032107584738196), FRAC_CONST(0.003281717377568) }, { FRAC_CONST(0.032096673439141), FRAC_CONST(0.003386771443102) }, { FRAC_CONST(0.032085418410500), FRAC_CONST(0.003491789239036) }, { FRAC_CONST(0.032073819772804), FRAC_CONST(0.003596769640711) }, { FRAC_CONST(0.032061877650267), FRAC_CONST(0.003701711523874) }, { FRAC_CONST(0.032049592170778), FRAC_CONST(0.003806613764680) }, { FRAC_CONST(0.032036963465906), FRAC_CONST(0.003911475239711) }, { FRAC_CONST(0.032023991670893), FRAC_CONST(0.004016294825985) }, { FRAC_CONST(0.032010676924657), FRAC_CONST(0.004121071400967) }, { FRAC_CONST(0.031997019369789), FRAC_CONST(0.004225803842586) }, { FRAC_CONST(0.031983019152549), FRAC_CONST(0.004330491029241) }, { FRAC_CONST(0.031968676422869), FRAC_CONST(0.004435131839816) }, { FRAC_CONST(0.031953991334348), FRAC_CONST(0.004539725153692) }, { FRAC_CONST(0.031938964044252), FRAC_CONST(0.004644269850758) }, { FRAC_CONST(0.031923594713510), FRAC_CONST(0.004748764811426) }, { FRAC_CONST(0.031907883506716), FRAC_CONST(0.004853208916638) }, { FRAC_CONST(0.031891830592124), FRAC_CONST(0.004957601047881) }, { FRAC_CONST(0.031875436141648), FRAC_CONST(0.005061940087200) }, { FRAC_CONST(0.031858700330859), FRAC_CONST(0.005166224917208) }, { FRAC_CONST(0.031841623338985), FRAC_CONST(0.005270454421097) }, { FRAC_CONST(0.031824205348907), FRAC_CONST(0.005374627482653) }, { FRAC_CONST(0.031806446547156), FRAC_CONST(0.005478742986267) }, { FRAC_CONST(0.031788347123916), FRAC_CONST(0.005582799816945) }, { FRAC_CONST(0.031769907273017), FRAC_CONST(0.005686796860323) }, { FRAC_CONST(0.031751127191935), FRAC_CONST(0.005790733002674) }, { FRAC_CONST(0.031732007081789), FRAC_CONST(0.005894607130928) }, { FRAC_CONST(0.031712547147340), FRAC_CONST(0.005998418132675) }, { FRAC_CONST(0.031692747596989), FRAC_CONST(0.006102164896182) }, { FRAC_CONST(0.031672608642773), FRAC_CONST(0.006205846310406) }, { FRAC_CONST(0.031652130500364), FRAC_CONST(0.006309461265002) }, { FRAC_CONST(0.031631313389067), FRAC_CONST(0.006413008650337) }, { FRAC_CONST(0.031610157531816), FRAC_CONST(0.006516487357501) }, { FRAC_CONST(0.031588663155172), FRAC_CONST(0.006619896278321) }, { FRAC_CONST(0.031566830489325), FRAC_CONST(0.006723234305370) }, { FRAC_CONST(0.031544659768083), FRAC_CONST(0.006826500331981) }, { FRAC_CONST(0.031522151228878), FRAC_CONST(0.006929693252258) }, { FRAC_CONST(0.031499305112758), FRAC_CONST(0.007032811961088) }, { FRAC_CONST(0.031476121664387), FRAC_CONST(0.007135855354151) }, { FRAC_CONST(0.031452601132040), FRAC_CONST(0.007238822327937) }, { FRAC_CONST(0.031428743767604), FRAC_CONST(0.007341711779751) }, { FRAC_CONST(0.031404549826572), FRAC_CONST(0.007444522607730) }, { FRAC_CONST(0.031380019568042), FRAC_CONST(0.007547253710853) }, { FRAC_CONST(0.031355153254712), FRAC_CONST(0.007649903988952) }, { FRAC_CONST(0.031329951152882), FRAC_CONST(0.007752472342725) }, { FRAC_CONST(0.031304413532445), FRAC_CONST(0.007854957673748) }, { FRAC_CONST(0.031278540666888), FRAC_CONST(0.007957358884484) }, { FRAC_CONST(0.031252332833290), FRAC_CONST(0.008059674878300) }, { FRAC_CONST(0.031225790312316), FRAC_CONST(0.008161904559473) }, { FRAC_CONST(0.031198913388214), FRAC_CONST(0.008264046833205) }, { FRAC_CONST(0.031171702348814), FRAC_CONST(0.008366100605636) }, { FRAC_CONST(0.031144157485525), FRAC_CONST(0.008468064783849) }, { FRAC_CONST(0.031116279093331), FRAC_CONST(0.008569938275893) }, { FRAC_CONST(0.031088067470786), FRAC_CONST(0.008671719990782) }, { FRAC_CONST(0.031059522920014), FRAC_CONST(0.008773408838517) }, { FRAC_CONST(0.031030645746705), FRAC_CONST(0.008875003730092) }, { FRAC_CONST(0.031001436260110), FRAC_CONST(0.008976503577507) }, { FRAC_CONST(0.030971894773039), FRAC_CONST(0.009077907293780) }, { FRAC_CONST(0.030942021601857), FRAC_CONST(0.009179213792959) }, { FRAC_CONST(0.030911817066483), FRAC_CONST(0.009280421990133) }, { FRAC_CONST(0.030881281490382), FRAC_CONST(0.009381530801444) }, { FRAC_CONST(0.030850415200566), FRAC_CONST(0.009482539144097) }, { FRAC_CONST(0.030819218527589), FRAC_CONST(0.009583445936373) }, { FRAC_CONST(0.030787691805541), FRAC_CONST(0.009684250097643) }, { FRAC_CONST(0.030755835372048), FRAC_CONST(0.009784950548375) }, { FRAC_CONST(0.030723649568268), FRAC_CONST(0.009885546210147) }, { FRAC_CONST(0.030691134738883), FRAC_CONST(0.009986036005661) }, { FRAC_CONST(0.030658291232103), FRAC_CONST(0.010086418858753) }, { FRAC_CONST(0.030625119399655), FRAC_CONST(0.010186693694402) }, { FRAC_CONST(0.030591619596781), FRAC_CONST(0.010286859438745) }, { FRAC_CONST(0.030557792182239), FRAC_CONST(0.010386915019088) }, { FRAC_CONST(0.030523637518292), FRAC_CONST(0.010486859363916) }, { FRAC_CONST(0.030489155970710), FRAC_CONST(0.010586691402906) }, { FRAC_CONST(0.030454347908763), FRAC_CONST(0.010686410066936) }, { FRAC_CONST(0.030419213705216), FRAC_CONST(0.010786014288099) }, { FRAC_CONST(0.030383753736329), FRAC_CONST(0.010885502999714) }, { FRAC_CONST(0.030347968381849), FRAC_CONST(0.010984875136338) }, { FRAC_CONST(0.030311858025010), FRAC_CONST(0.011084129633775) }, { FRAC_CONST(0.030275423052523), FRAC_CONST(0.011183265429088) }, { FRAC_CONST(0.030238663854579), FRAC_CONST(0.011282281460612) }, { FRAC_CONST(0.030201580824838), FRAC_CONST(0.011381176667967) }, { FRAC_CONST(0.030164174360430), FRAC_CONST(0.011479949992062) }, { FRAC_CONST(0.030126444861948), FRAC_CONST(0.011578600375117) }, { FRAC_CONST(0.030088392733446), FRAC_CONST(0.011677126760663) }, { FRAC_CONST(0.030050018382430), FRAC_CONST(0.011775528093563) }, { FRAC_CONST(0.030011322219859), FRAC_CONST(0.011873803320018) }, { FRAC_CONST(0.029972304660138), FRAC_CONST(0.011971951387578) }, { FRAC_CONST(0.029932966121114), FRAC_CONST(0.012069971245157) }, { FRAC_CONST(0.029893307024070), FRAC_CONST(0.012167861843041) }, { FRAC_CONST(0.029853327793724), FRAC_CONST(0.012265622132901) }, { FRAC_CONST(0.029813028858222), FRAC_CONST(0.012363251067801) }, { FRAC_CONST(0.029772410649132), FRAC_CONST(0.012460747602215) }, { FRAC_CONST(0.029731473601443), FRAC_CONST(0.012558110692033) }, { FRAC_CONST(0.029690218153558), FRAC_CONST(0.012655339294575) }, { FRAC_CONST(0.029648644747289), FRAC_CONST(0.012752432368600) }, { FRAC_CONST(0.029606753827855), FRAC_CONST(0.012849388874320) }, { FRAC_CONST(0.029564545843872), FRAC_CONST(0.012946207773407) }, { FRAC_CONST(0.029522021247356), FRAC_CONST(0.013042888029011) }, { FRAC_CONST(0.029479180493710), FRAC_CONST(0.013139428605762) }, { FRAC_CONST(0.029436024041725), FRAC_CONST(0.013235828469789) }, { FRAC_CONST(0.029392552353570), FRAC_CONST(0.013332086588727) }, { FRAC_CONST(0.029348765894794), FRAC_CONST(0.013428201931728) }, { FRAC_CONST(0.029304665134313), FRAC_CONST(0.013524173469475) }, { FRAC_CONST(0.029260250544412), FRAC_CONST(0.013620000174189) }, { FRAC_CONST(0.029215522600735), FRAC_CONST(0.013715681019643) }, { FRAC_CONST(0.029170481782283), FRAC_CONST(0.013811214981173) }, { FRAC_CONST(0.029125128571406), FRAC_CONST(0.013906601035686) }, { FRAC_CONST(0.029079463453801), FRAC_CONST(0.014001838161674) }, { FRAC_CONST(0.029033486918505), FRAC_CONST(0.014096925339225) }, { FRAC_CONST(0.028987199457889), FRAC_CONST(0.014191861550031) }, { FRAC_CONST(0.028940601567655), FRAC_CONST(0.014286645777401) }, { FRAC_CONST(0.028893693746829), FRAC_CONST(0.014381277006273) }, { FRAC_CONST(0.028846476497755), FRAC_CONST(0.014475754223221) }, { FRAC_CONST(0.028798950326094), FRAC_CONST(0.014570076416472) }, { FRAC_CONST(0.028751115740811), FRAC_CONST(0.014664242575910) }, { FRAC_CONST(0.028702973254178), FRAC_CONST(0.014758251693091) }, { FRAC_CONST(0.028654523381760), FRAC_CONST(0.014852102761253) }, { FRAC_CONST(0.028605766642418), FRAC_CONST(0.014945794775326) }, { FRAC_CONST(0.028556703558297), FRAC_CONST(0.015039326731945) }, { FRAC_CONST(0.028507334654823), FRAC_CONST(0.015132697629457) }, { FRAC_CONST(0.028457660460698), FRAC_CONST(0.015225906467935) }, { FRAC_CONST(0.028407681507891), FRAC_CONST(0.015318952249187) }, { FRAC_CONST(0.028357398331639), FRAC_CONST(0.015411833976768) }, { FRAC_CONST(0.028306811470432), FRAC_CONST(0.015504550655988) }, { FRAC_CONST(0.028255921466016), FRAC_CONST(0.015597101293927) }, { FRAC_CONST(0.028204728863381), FRAC_CONST(0.015689484899442) }, { FRAC_CONST(0.028153234210760), FRAC_CONST(0.015781700483179) }, { FRAC_CONST(0.028101438059619), FRAC_CONST(0.015873747057582) }, { FRAC_CONST(0.028049340964652), FRAC_CONST(0.015965623636907) }, { FRAC_CONST(0.027996943483779), FRAC_CONST(0.016057329237229) }, { FRAC_CONST(0.027944246178133), FRAC_CONST(0.016148862876456) }, { FRAC_CONST(0.027891249612061), FRAC_CONST(0.016240223574335) }, { FRAC_CONST(0.027837954353113), FRAC_CONST(0.016331410352467) }, { FRAC_CONST(0.027784360972039), FRAC_CONST(0.016422422234315) }, { FRAC_CONST(0.027730470042780), FRAC_CONST(0.016513258245214) }, { FRAC_CONST(0.027676282142466), FRAC_CONST(0.016603917412384) }, { FRAC_CONST(0.027621797851405), FRAC_CONST(0.016694398764938) }, { FRAC_CONST(0.027567017753080), FRAC_CONST(0.016784701333894) }, { FRAC_CONST(0.027511942434143), FRAC_CONST(0.016874824152183) }, { FRAC_CONST(0.027456572484404), FRAC_CONST(0.016964766254662) }, { FRAC_CONST(0.027400908496833), FRAC_CONST(0.017054526678124) }, { FRAC_CONST(0.027344951067546), FRAC_CONST(0.017144104461307) }, { FRAC_CONST(0.027288700795801), FRAC_CONST(0.017233498644904) }, { FRAC_CONST(0.027232158283994), FRAC_CONST(0.017322708271577) }, { FRAC_CONST(0.027175324137651), FRAC_CONST(0.017411732385960) }, { FRAC_CONST(0.027118198965418), FRAC_CONST(0.017500570034678) }, { FRAC_CONST(0.027060783379060), FRAC_CONST(0.017589220266351) }, { FRAC_CONST(0.027003077993454), FRAC_CONST(0.017677682131607) }, { FRAC_CONST(0.026945083426576), FRAC_CONST(0.017765954683088) }, { FRAC_CONST(0.026886800299502), FRAC_CONST(0.017854036975468) }, { FRAC_CONST(0.026828229236397), FRAC_CONST(0.017941928065456) }, { FRAC_CONST(0.026769370864511), FRAC_CONST(0.018029627011808) }, { FRAC_CONST(0.026710225814170), FRAC_CONST(0.018117132875340) }, { FRAC_CONST(0.026650794718768), FRAC_CONST(0.018204444718934) }, { FRAC_CONST(0.026591078214767), FRAC_CONST(0.018291561607551) }, { FRAC_CONST(0.026531076941680), FRAC_CONST(0.018378482608238) }, { FRAC_CONST(0.026470791542075), FRAC_CONST(0.018465206790142) }, { FRAC_CONST(0.026410222661558), FRAC_CONST(0.018551733224515) }, { FRAC_CONST(0.026349370948775), FRAC_CONST(0.018638060984730) }, { FRAC_CONST(0.026288237055398), FRAC_CONST(0.018724189146286) }, { FRAC_CONST(0.026226821636121), FRAC_CONST(0.018810116786819) }, { FRAC_CONST(0.026165125348656), FRAC_CONST(0.018895842986112) }, { FRAC_CONST(0.026103148853718), FRAC_CONST(0.018981366826109) }, { FRAC_CONST(0.026040892815028), FRAC_CONST(0.019066687390916) }, { FRAC_CONST(0.025978357899296), FRAC_CONST(0.019151803766819) }, { FRAC_CONST(0.025915544776223), FRAC_CONST(0.019236715042290) }, { FRAC_CONST(0.025852454118485), FRAC_CONST(0.019321420307998) }, { FRAC_CONST(0.025789086601733), FRAC_CONST(0.019405918656817) }, { FRAC_CONST(0.025725442904582), FRAC_CONST(0.019490209183837) }, { FRAC_CONST(0.025661523708606), FRAC_CONST(0.019574290986376) }, { FRAC_CONST(0.025597329698327), FRAC_CONST(0.019658163163984) }, { FRAC_CONST(0.025532861561211), FRAC_CONST(0.019741824818458) }, { FRAC_CONST(0.025468119987662), FRAC_CONST(0.019825275053848) }, { FRAC_CONST(0.025403105671008), FRAC_CONST(0.019908512976470) }, { FRAC_CONST(0.025337819307501), FRAC_CONST(0.019991537694913) }, { FRAC_CONST(0.025272261596305), FRAC_CONST(0.020074348320047) }, { FRAC_CONST(0.025206433239491), FRAC_CONST(0.020156943965039) }, { FRAC_CONST(0.025140334942028), FRAC_CONST(0.020239323745355) }, { FRAC_CONST(0.025073967411776), FRAC_CONST(0.020321486778774) }, { FRAC_CONST(0.025007331359476), FRAC_CONST(0.020403432185395) }, { FRAC_CONST(0.024940427498748), FRAC_CONST(0.020485159087650) }, { FRAC_CONST(0.024873256546079), FRAC_CONST(0.020566666610309) }, { FRAC_CONST(0.024805819220816), FRAC_CONST(0.020647953880491) }, { FRAC_CONST(0.024738116245157), FRAC_CONST(0.020729020027676) }, { FRAC_CONST(0.024670148344147), FRAC_CONST(0.020809864183709) }, { FRAC_CONST(0.024601916245669), FRAC_CONST(0.020890485482816) }, { FRAC_CONST(0.024533420680433), FRAC_CONST(0.020970883061607) }, { FRAC_CONST(0.024464662381971), FRAC_CONST(0.021051056059087) }, { FRAC_CONST(0.024395642086630), FRAC_CONST(0.021131003616670) }, { FRAC_CONST(0.024326360533561), FRAC_CONST(0.021210724878181) }, { FRAC_CONST(0.024256818464715), FRAC_CONST(0.021290218989868) }, { FRAC_CONST(0.024187016624830), FRAC_CONST(0.021369485100415) }, { FRAC_CONST(0.024116955761430), FRAC_CONST(0.021448522360944) }, { FRAC_CONST(0.024046636624808), FRAC_CONST(0.021527329925030) }, { FRAC_CONST(0.023976059968027), FRAC_CONST(0.021605906948708) }, { FRAC_CONST(0.023905226546906), FRAC_CONST(0.021684252590480) }, { FRAC_CONST(0.023834137120014), FRAC_CONST(0.021762366011328) }, { FRAC_CONST(0.023762792448662), FRAC_CONST(0.021840246374720) }, { FRAC_CONST(0.023691193296893), FRAC_CONST(0.021917892846620) }, { FRAC_CONST(0.023619340431478), FRAC_CONST(0.021995304595495) }, { FRAC_CONST(0.023547234621902), FRAC_CONST(0.022072480792330) }, { FRAC_CONST(0.023474876640361), FRAC_CONST(0.022149420610628) }, { FRAC_CONST(0.023402267261751), FRAC_CONST(0.022226123226426) }, { FRAC_CONST(0.023329407263659), FRAC_CONST(0.022302587818300) }, { FRAC_CONST(0.023256297426359), FRAC_CONST(0.022378813567377) }, { FRAC_CONST(0.023182938532797), FRAC_CONST(0.022454799657339) }, { FRAC_CONST(0.023109331368588), FRAC_CONST(0.022530545274437) }, { FRAC_CONST(0.023035476722006), FRAC_CONST(0.022606049607496) }, { FRAC_CONST(0.022961375383975), FRAC_CONST(0.022681311847926) }, { FRAC_CONST(0.022887028148061), FRAC_CONST(0.022756331189727) }, { FRAC_CONST(0.022812435810462), FRAC_CONST(0.022831106829504) }, { FRAC_CONST(0.022737599170003), FRAC_CONST(0.022905637966469) }, { FRAC_CONST(0.022662519028125), FRAC_CONST(0.022979923802453) }, { FRAC_CONST(0.022587196188874), FRAC_CONST(0.023053963541915) }, { FRAC_CONST(0.022511631458899), FRAC_CONST(0.023127756391950) }, { FRAC_CONST(0.022435825647437), FRAC_CONST(0.023201301562294) }, { FRAC_CONST(0.022359779566306), FRAC_CONST(0.023274598265338) }, { FRAC_CONST(0.022283494029900), FRAC_CONST(0.023347645716133) }, { FRAC_CONST(0.022206969855176), FRAC_CONST(0.023420443132400) }, { FRAC_CONST(0.022130207861645), FRAC_CONST(0.023492989734537) }, { FRAC_CONST(0.022053208871367), FRAC_CONST(0.023565284745628) }, { FRAC_CONST(0.021975973708940), FRAC_CONST(0.023637327391451) }, { FRAC_CONST(0.021898503201489), FRAC_CONST(0.023709116900488) }, { FRAC_CONST(0.021820798178663), FRAC_CONST(0.023780652503931) }, { FRAC_CONST(0.021742859472618), FRAC_CONST(0.023851933435691) }, { FRAC_CONST(0.021664687918017), FRAC_CONST(0.023922958932406) }, { FRAC_CONST(0.021586284352013), FRAC_CONST(0.023993728233451) }, { FRAC_CONST(0.021507649614247), FRAC_CONST(0.024064240580942) }, { FRAC_CONST(0.021428784546832), FRAC_CONST(0.024134495219750) }, { FRAC_CONST(0.021349689994350), FRAC_CONST(0.024204491397504) }, { FRAC_CONST(0.021270366803840), FRAC_CONST(0.024274228364600) }, { FRAC_CONST(0.021190815824791), FRAC_CONST(0.024343705374213) }, { FRAC_CONST(0.021111037909128), FRAC_CONST(0.024412921682298) }, { FRAC_CONST(0.021031033911210), FRAC_CONST(0.024481876547605) }, { FRAC_CONST(0.020950804687815), FRAC_CONST(0.024550569231683) }, { FRAC_CONST(0.020870351098134), FRAC_CONST(0.024618998998889) }, { FRAC_CONST(0.020789674003759), FRAC_CONST(0.024687165116394) }, { FRAC_CONST(0.020708774268678), FRAC_CONST(0.024755066854194) }, { FRAC_CONST(0.020627652759262), FRAC_CONST(0.024822703485116) }, { FRAC_CONST(0.020546310344257), FRAC_CONST(0.024890074284826) }, { FRAC_CONST(0.020464747894775), FRAC_CONST(0.024957178531837) }, { FRAC_CONST(0.020382966284284), FRAC_CONST(0.025024015507516) }, { FRAC_CONST(0.020300966388600), FRAC_CONST(0.025090584496093) }, { FRAC_CONST(0.020218749085876), FRAC_CONST(0.025156884784668) }, { FRAC_CONST(0.020136315256592), FRAC_CONST(0.025222915663218) }, { FRAC_CONST(0.020053665783549), FRAC_CONST(0.025288676424605) }, { FRAC_CONST(0.019970801551857), FRAC_CONST(0.025354166364584) }, { FRAC_CONST(0.019887723448925), FRAC_CONST(0.025419384781811) }, { FRAC_CONST(0.019804432364452), FRAC_CONST(0.025484330977848) }, { FRAC_CONST(0.019720929190419), FRAC_CONST(0.025549004257175) }, { FRAC_CONST(0.019637214821078), FRAC_CONST(0.025613403927192) }, { FRAC_CONST(0.019553290152943), FRAC_CONST(0.025677529298230) }, { FRAC_CONST(0.019469156084779), FRAC_CONST(0.025741379683559) }, { FRAC_CONST(0.019384813517595), FRAC_CONST(0.025804954399392) }, { FRAC_CONST(0.019300263354632), FRAC_CONST(0.025868252764895) }, { FRAC_CONST(0.019215506501354), FRAC_CONST(0.025931274102193) }, { FRAC_CONST(0.019130543865439), FRAC_CONST(0.025994017736379) }, { FRAC_CONST(0.019045376356769), FRAC_CONST(0.026056482995518) }, { FRAC_CONST(0.018960004887419), FRAC_CONST(0.026118669210657) }, { FRAC_CONST(0.018874430371648), FRAC_CONST(0.026180575715833) }, { FRAC_CONST(0.018788653725892), FRAC_CONST(0.026242201848076) }, { FRAC_CONST(0.018702675868750), FRAC_CONST(0.026303546947421) }, { FRAC_CONST(0.018616497720974), FRAC_CONST(0.026364610356909) }, { FRAC_CONST(0.018530120205464), FRAC_CONST(0.026425391422602) }, { FRAC_CONST(0.018443544247254), FRAC_CONST(0.026485889493583) }, { FRAC_CONST(0.018356770773502), FRAC_CONST(0.026546103921965) }, { FRAC_CONST(0.018269800713483), FRAC_CONST(0.026606034062902) }, { FRAC_CONST(0.018182634998576), FRAC_CONST(0.026665679274589) }, { FRAC_CONST(0.018095274562256), FRAC_CONST(0.026725038918274) }, { FRAC_CONST(0.018007720340083), FRAC_CONST(0.026784112358263) }, { FRAC_CONST(0.017919973269692), FRAC_CONST(0.026842898961926) }, { FRAC_CONST(0.017832034290785), FRAC_CONST(0.026901398099707) }, { FRAC_CONST(0.017743904345116), FRAC_CONST(0.026959609145127) }, { FRAC_CONST(0.017655584376488), FRAC_CONST(0.027017531474792) }, { FRAC_CONST(0.017567075330734), FRAC_CONST(0.027075164468401) }, { FRAC_CONST(0.017478378155718), FRAC_CONST(0.027132507508750) }, { FRAC_CONST(0.017389493801313), FRAC_CONST(0.027189559981742) }, { FRAC_CONST(0.017300423219401), FRAC_CONST(0.027246321276391) }, { FRAC_CONST(0.017211167363854), FRAC_CONST(0.027302790784828) }, { FRAC_CONST(0.017121727190533), FRAC_CONST(0.027358967902310) }, { FRAC_CONST(0.017032103657269), FRAC_CONST(0.027414852027226) }, { FRAC_CONST(0.016942297723858), FRAC_CONST(0.027470442561102) }, { FRAC_CONST(0.016852310352050), FRAC_CONST(0.027525738908608) }, { FRAC_CONST(0.016762142505537), FRAC_CONST(0.027580740477564) }, { FRAC_CONST(0.016671795149944), FRAC_CONST(0.027635446678948) }, { FRAC_CONST(0.016581269252819), FRAC_CONST(0.027689856926900) }, { FRAC_CONST(0.016490565783622), FRAC_CONST(0.027743970638730) }, { FRAC_CONST(0.016399685713714), FRAC_CONST(0.027797787234924) }, { FRAC_CONST(0.016308630016347), FRAC_CONST(0.027851306139149) }, { FRAC_CONST(0.016217399666655), FRAC_CONST(0.027904526778260) }, { FRAC_CONST(0.016125995641641), FRAC_CONST(0.027957448582309) }, { FRAC_CONST(0.016034418920170), FRAC_CONST(0.028010070984544) }, { FRAC_CONST(0.015942670482954), FRAC_CONST(0.028062393421421) }, { FRAC_CONST(0.015850751312545), FRAC_CONST(0.028114415332610) }, { FRAC_CONST(0.015758662393324), FRAC_CONST(0.028166136160998) }, { FRAC_CONST(0.015666404711489), FRAC_CONST(0.028217555352697) }, { FRAC_CONST(0.015573979255046), FRAC_CONST(0.028268672357047) }, { FRAC_CONST(0.015481387013797), FRAC_CONST(0.028319486626627) }, { FRAC_CONST(0.015388628979331), FRAC_CONST(0.028369997617257) }, { FRAC_CONST(0.015295706145012), FRAC_CONST(0.028420204788004) }, { FRAC_CONST(0.015202619505968), FRAC_CONST(0.028470107601191) }, { FRAC_CONST(0.015109370059084), FRAC_CONST(0.028519705522399) }, { FRAC_CONST(0.015015958802984), FRAC_CONST(0.028568998020472) }, { FRAC_CONST(0.014922386738030), FRAC_CONST(0.028617984567529) }, { FRAC_CONST(0.014828654866302), FRAC_CONST(0.028666664638963) }, { FRAC_CONST(0.014734764191593), FRAC_CONST(0.028715037713449) }, { FRAC_CONST(0.014640715719398), FRAC_CONST(0.028763103272951) }, { FRAC_CONST(0.014546510456900), FRAC_CONST(0.028810860802724) }, { FRAC_CONST(0.014452149412962), FRAC_CONST(0.028858309791325) }, { FRAC_CONST(0.014357633598114), FRAC_CONST(0.028905449730613) }, { FRAC_CONST(0.014262964024545), FRAC_CONST(0.028952280115756) }, { FRAC_CONST(0.014168141706090), FRAC_CONST(0.028998800445240) }, { FRAC_CONST(0.014073167658220), FRAC_CONST(0.029045010220868) }, { FRAC_CONST(0.013978042898030), FRAC_CONST(0.029090908947771) }, { FRAC_CONST(0.013882768444231), FRAC_CONST(0.029136496134411) }, { FRAC_CONST(0.013787345317136), FRAC_CONST(0.029181771292585) }, { FRAC_CONST(0.013691774538648), FRAC_CONST(0.029226733937433) }, { FRAC_CONST(0.013596057132255), FRAC_CONST(0.029271383587441) }, { FRAC_CONST(0.013500194123014), FRAC_CONST(0.029315719764447) }, { FRAC_CONST(0.013404186537539), FRAC_CONST(0.029359741993647) }, { FRAC_CONST(0.013308035403995), FRAC_CONST(0.029403449803598) }, { FRAC_CONST(0.013211741752084), FRAC_CONST(0.029446842726223) }, { FRAC_CONST(0.013115306613032), FRAC_CONST(0.029489920296820) }, { FRAC_CONST(0.013018731019584), FRAC_CONST(0.029532682054063) }, { FRAC_CONST(0.012922016005985), FRAC_CONST(0.029575127540008) }, { FRAC_CONST(0.012825162607977), FRAC_CONST(0.029617256300097) }, { FRAC_CONST(0.012728171862781), FRAC_CONST(0.029659067883165) }, { FRAC_CONST(0.012631044809089), FRAC_CONST(0.029700561841444) }, { FRAC_CONST(0.012533782487056), FRAC_CONST(0.029741737730567) }, { FRAC_CONST(0.012436385938281), FRAC_CONST(0.029782595109573) }, { FRAC_CONST(0.012338856205805), FRAC_CONST(0.029823133540913) }, { FRAC_CONST(0.012241194334091), FRAC_CONST(0.029863352590452) }, { FRAC_CONST(0.012143401369021), FRAC_CONST(0.029903251827477) }, { FRAC_CONST(0.012045478357878), FRAC_CONST(0.029942830824699) }, { FRAC_CONST(0.011947426349339), FRAC_CONST(0.029982089158259) }, { FRAC_CONST(0.011849246393462), FRAC_CONST(0.030021026407731) }, { FRAC_CONST(0.011750939541676), FRAC_CONST(0.030059642156129) }, { FRAC_CONST(0.011652506846768), FRAC_CONST(0.030097935989909) }, { FRAC_CONST(0.011553949362874), FRAC_CONST(0.030135907498976) }, { FRAC_CONST(0.011455268145464), FRAC_CONST(0.030173556276684) }, { FRAC_CONST(0.011356464251335), FRAC_CONST(0.030210881919845) }, { FRAC_CONST(0.011257538738598), FRAC_CONST(0.030247884028732) }, { FRAC_CONST(0.011158492666665), FRAC_CONST(0.030284562207083) }, { FRAC_CONST(0.011059327096240), FRAC_CONST(0.030320916062102) }, { FRAC_CONST(0.010960043089307), FRAC_CONST(0.030356945204470) }, { FRAC_CONST(0.010860641709118), FRAC_CONST(0.030392649248343) }, { FRAC_CONST(0.010761124020182), FRAC_CONST(0.030428027811361) }, { FRAC_CONST(0.010661491088253), FRAC_CONST(0.030463080514646) }, { FRAC_CONST(0.010561743980319), FRAC_CONST(0.030497806982812) }, { FRAC_CONST(0.010461883764593), FRAC_CONST(0.030532206843968) }, { FRAC_CONST(0.010361911510496), FRAC_CONST(0.030566279729717) }, { FRAC_CONST(0.010261828288652), FRAC_CONST(0.030600025275167) }, { FRAC_CONST(0.010161635170872), FRAC_CONST(0.030633443118931) }, { FRAC_CONST(0.010061333230142), FRAC_CONST(0.030666532903129) }, { FRAC_CONST(0.009960923540617), FRAC_CONST(0.030699294273397) }, { FRAC_CONST(0.009860407177603), FRAC_CONST(0.030731726878888) }, { FRAC_CONST(0.009759785217550), FRAC_CONST(0.030763830372273) }, { FRAC_CONST(0.009659058738038), FRAC_CONST(0.030795604409750) }, { FRAC_CONST(0.009558228817767), FRAC_CONST(0.030827048651045) }, { FRAC_CONST(0.009457296536545), FRAC_CONST(0.030858162759415) }, { FRAC_CONST(0.009356262975275), FRAC_CONST(0.030888946401653) }, { FRAC_CONST(0.009255129215945), FRAC_CONST(0.030919399248091) }, { FRAC_CONST(0.009153896341616), FRAC_CONST(0.030949520972603) }, { FRAC_CONST(0.009052565436412), FRAC_CONST(0.030979311252611) }, { FRAC_CONST(0.008951137585505), FRAC_CONST(0.031008769769084) }, { FRAC_CONST(0.008849613875105), FRAC_CONST(0.031037896206544) }, { FRAC_CONST(0.008747995392451), FRAC_CONST(0.031066690253072) }, { FRAC_CONST(0.008646283225794), FRAC_CONST(0.031095151600306) }, { FRAC_CONST(0.008544478464390), FRAC_CONST(0.031123279943448) }, { FRAC_CONST(0.008442582198486), FRAC_CONST(0.031151074981266) }, { FRAC_CONST(0.008340595519310), FRAC_CONST(0.031178536416098) }, { FRAC_CONST(0.008238519519057), FRAC_CONST(0.031205663953853) }, { FRAC_CONST(0.008136355290878), FRAC_CONST(0.031232457304017) }, { FRAC_CONST(0.008034103928871), FRAC_CONST(0.031258916179656) }, { FRAC_CONST(0.007931766528065), FRAC_CONST(0.031285040297416) }, { FRAC_CONST(0.007829344184412), FRAC_CONST(0.031310829377528) }, { FRAC_CONST(0.007726837994772), FRAC_CONST(0.031336283143813) }, { FRAC_CONST(0.007624249056906), FRAC_CONST(0.031361401323680) }, { FRAC_CONST(0.007521578469457), FRAC_CONST(0.031386183648135) }, { FRAC_CONST(0.007418827331946), FRAC_CONST(0.031410629851778) }, { FRAC_CONST(0.007315996744755), FRAC_CONST(0.031434739672811) }, { FRAC_CONST(0.007213087809115), FRAC_CONST(0.031458512853036) }, { FRAC_CONST(0.007110101627101), FRAC_CONST(0.031481949137863) }, { FRAC_CONST(0.007007039301610), FRAC_CONST(0.031505048276306) }, { FRAC_CONST(0.006903901936357), FRAC_CONST(0.031527810020993) }, { FRAC_CONST(0.006800690635862), FRAC_CONST(0.031550234128164) }, { FRAC_CONST(0.006697406505433), FRAC_CONST(0.031572320357675) }, { FRAC_CONST(0.006594050651161), FRAC_CONST(0.031594068473000) }, { FRAC_CONST(0.006490624179905), FRAC_CONST(0.031615478241233) }, { FRAC_CONST(0.006387128199278), FRAC_CONST(0.031636549433095) }, { FRAC_CONST(0.006283563817639), FRAC_CONST(0.031657281822929) }, { FRAC_CONST(0.006179932144080), FRAC_CONST(0.031677675188707) }, { FRAC_CONST(0.006076234288412), FRAC_CONST(0.031697729312034) }, { FRAC_CONST(0.005972471361157), FRAC_CONST(0.031717443978146) }, { FRAC_CONST(0.005868644473532), FRAC_CONST(0.031736818975914) }, { FRAC_CONST(0.005764754737440), FRAC_CONST(0.031755854097848) }, { FRAC_CONST(0.005660803265456), FRAC_CONST(0.031774549140098) }, { FRAC_CONST(0.005556791170816), FRAC_CONST(0.031792903902453) }, { FRAC_CONST(0.005452719567407), FRAC_CONST(0.031810918188350) }, { FRAC_CONST(0.005348589569753), FRAC_CONST(0.031828591804869) }, { FRAC_CONST(0.005244402293001), FRAC_CONST(0.031845924562742) }, { FRAC_CONST(0.005140158852914), FRAC_CONST(0.031862916276347) }, { FRAC_CONST(0.005035860365855), FRAC_CONST(0.031879566763717) }, { FRAC_CONST(0.004931507948778), FRAC_CONST(0.031895875846539) }, { FRAC_CONST(0.004827102719212), FRAC_CONST(0.031911843350155) }, { FRAC_CONST(0.004722645795254), FRAC_CONST(0.031927469103567) }, { FRAC_CONST(0.004618138295554), FRAC_CONST(0.031942752939435) }, { FRAC_CONST(0.004513581339303), FRAC_CONST(0.031957694694082) }, { FRAC_CONST(0.004408976046222), FRAC_CONST(0.031972294207493) }, { FRAC_CONST(0.004304323536549), FRAC_CONST(0.031986551323320) }, { FRAC_CONST(0.004199624931030), FRAC_CONST(0.032000465888879) }, { FRAC_CONST(0.004094881350902), FRAC_CONST(0.032014037755158) }, { FRAC_CONST(0.003990093917884), FRAC_CONST(0.032027266776813) }, { FRAC_CONST(0.003885263754166), FRAC_CONST(0.032040152812170) }, { FRAC_CONST(0.003780391982394), FRAC_CONST(0.032052695723232) }, { FRAC_CONST(0.003675479725661), FRAC_CONST(0.032064895375674) }, { FRAC_CONST(0.003570528107494), FRAC_CONST(0.032076751638847) }, { FRAC_CONST(0.003465538251839), FRAC_CONST(0.032088264385780) }, { FRAC_CONST(0.003360511283053), FRAC_CONST(0.032099433493181) }, { FRAC_CONST(0.003255448325892), FRAC_CONST(0.032110258841438) }, { FRAC_CONST(0.003150350505494), FRAC_CONST(0.032120740314619) }, { FRAC_CONST(0.003045218947373), FRAC_CONST(0.032130877800478) }, { FRAC_CONST(0.002940054777404), FRAC_CONST(0.032140671190449) }, { FRAC_CONST(0.002834859121810), FRAC_CONST(0.032150120379653) }, { FRAC_CONST(0.002729633107153), FRAC_CONST(0.032159225266897) }, { FRAC_CONST(0.002624377860318), FRAC_CONST(0.032167985754674) }, { FRAC_CONST(0.002519094508504), FRAC_CONST(0.032176401749168) }, { FRAC_CONST(0.002413784179212), FRAC_CONST(0.032184473160250) }, { FRAC_CONST(0.002308448000231), FRAC_CONST(0.032192199901481) }, { FRAC_CONST(0.002203087099626), FRAC_CONST(0.032199581890114) }, { FRAC_CONST(0.002097702605728), FRAC_CONST(0.032206619047093) }, { FRAC_CONST(0.001992295647121), FRAC_CONST(0.032213311297057) }, { FRAC_CONST(0.001886867352628), FRAC_CONST(0.032219658568338) }, { FRAC_CONST(0.001781418851302), FRAC_CONST(0.032225660792960) }, { FRAC_CONST(0.001675951272410), FRAC_CONST(0.032231317906644) }, { FRAC_CONST(0.001570465745428), FRAC_CONST(0.032236629848809) }, { FRAC_CONST(0.001464963400018), FRAC_CONST(0.032241596562566) }, { FRAC_CONST(0.001359445366028), FRAC_CONST(0.032246217994727) }, { FRAC_CONST(0.001253912773470), FRAC_CONST(0.032250494095799) }, { FRAC_CONST(0.001148366752513), FRAC_CONST(0.032254424819990) }, { FRAC_CONST(0.001042808433471), FRAC_CONST(0.032258010125204) }, { FRAC_CONST(0.000937238946789), FRAC_CONST(0.032261249973045) }, { FRAC_CONST(0.000831659423030), FRAC_CONST(0.032264144328817) }, { FRAC_CONST(0.000726070992868), FRAC_CONST(0.032266693161525) }, { FRAC_CONST(0.000620474787068), FRAC_CONST(0.032268896443871) }, { FRAC_CONST(0.000514871936481), FRAC_CONST(0.032270754152261) }, { FRAC_CONST(0.000409263572030), FRAC_CONST(0.032272266266801) }, { FRAC_CONST(0.000303650824695), FRAC_CONST(0.032273432771295) }, { FRAC_CONST(0.000198034825504), FRAC_CONST(0.032274253653254) }, { FRAC_CONST(0.000092416705518), FRAC_CONST(0.032274728903884) } }; #ifdef LD_DEC /* 240 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_960[] = { { FRAC_CONST(0.045643531183573), FRAC_CONST(0.000037342034959) }, { FRAC_CONST(0.045642309173789), FRAC_CONST(0.000336075315362) }, { FRAC_CONST(0.045639131999390), FRAC_CONST(0.000634794199417) }, { FRAC_CONST(0.045633999796474), FRAC_CONST(0.000933485891002) }, { FRAC_CONST(0.045626912784890), FRAC_CONST(0.001232137595157) }, { FRAC_CONST(0.045617871268219), FRAC_CONST(0.001530736518639) }, { FRAC_CONST(0.045606875633772), FRAC_CONST(0.001829269870464) }, { FRAC_CONST(0.045593926352564), FRAC_CONST(0.002127724862455) }, { FRAC_CONST(0.045579023979299), FRAC_CONST(0.002426088709795) }, { FRAC_CONST(0.045562169152346), FRAC_CONST(0.002724348631569) }, { FRAC_CONST(0.045543362593709), FRAC_CONST(0.003022491851315) }, { FRAC_CONST(0.045522605108999), FRAC_CONST(0.003320505597570) }, { FRAC_CONST(0.045499897587396), FRAC_CONST(0.003618377104416) }, { FRAC_CONST(0.045475241001617), FRAC_CONST(0.003916093612031) }, { FRAC_CONST(0.045448636407866), FRAC_CONST(0.004213642367228) }, { FRAC_CONST(0.045420084945797), FRAC_CONST(0.004511010624011) }, { FRAC_CONST(0.045389587838458), FRAC_CONST(0.004808185644112) }, { FRAC_CONST(0.045357146392244), FRAC_CONST(0.005105154697544) }, { FRAC_CONST(0.045322761996840), FRAC_CONST(0.005401905063139) }, { FRAC_CONST(0.045286436125157), FRAC_CONST(0.005698424029100) }, { FRAC_CONST(0.045248170333275), FRAC_CONST(0.005994698893542) }, { FRAC_CONST(0.045207966260374), FRAC_CONST(0.006290716965035) }, { FRAC_CONST(0.045165825628663), FRAC_CONST(0.006586465563151) }, { FRAC_CONST(0.045121750243305), FRAC_CONST(0.006881932019003) }, { FRAC_CONST(0.045075741992343), FRAC_CONST(0.007177103675792) }, { FRAC_CONST(0.045027802846618), FRAC_CONST(0.007471967889347) }, { FRAC_CONST(0.044977934859683), FRAC_CONST(0.007766512028667) }, { FRAC_CONST(0.044926140167717), FRAC_CONST(0.008060723476460) }, { FRAC_CONST(0.044872420989432), FRAC_CONST(0.008354589629687) }, { FRAC_CONST(0.044816779625979), FRAC_CONST(0.008648097900101) }, { FRAC_CONST(0.044759218460849), FRAC_CONST(0.008941235714784) }, { FRAC_CONST(0.044699739959770), FRAC_CONST(0.009233990516688) }, { FRAC_CONST(0.044638346670603), FRAC_CONST(0.009526349765171) }, { FRAC_CONST(0.044575041223233), FRAC_CONST(0.009818300936537) }, { FRAC_CONST(0.044509826329454), FRAC_CONST(0.010109831524568) }, { FRAC_CONST(0.044442704782856), FRAC_CONST(0.010400929041064) }, { FRAC_CONST(0.044373679458701), FRAC_CONST(0.010691581016378) }, { FRAC_CONST(0.044302753313806), FRAC_CONST(0.010981774999945) }, { FRAC_CONST(0.044229929386409), FRAC_CONST(0.011271498560822) }, { FRAC_CONST(0.044155210796046), FRAC_CONST(0.011560739288214) }, { FRAC_CONST(0.044078600743413), FRAC_CONST(0.011849484792012) }, { FRAC_CONST(0.044000102510229), FRAC_CONST(0.012137722703321) }, { FRAC_CONST(0.043919719459097), FRAC_CONST(0.012425440674986) }, { FRAC_CONST(0.043837455033359), FRAC_CONST(0.012712626382127) }, { FRAC_CONST(0.043753312756950), FRAC_CONST(0.012999267522665) }, { FRAC_CONST(0.043667296234245), FRAC_CONST(0.013285351817848) }, { FRAC_CONST(0.043579409149906), FRAC_CONST(0.013570867012776) }, { FRAC_CONST(0.043489655268722), FRAC_CONST(0.013855800876928) }, { FRAC_CONST(0.043398038435451), FRAC_CONST(0.014140141204686) }, { FRAC_CONST(0.043304562574653), FRAC_CONST(0.014423875815857) }, { FRAC_CONST(0.043209231690524), FRAC_CONST(0.014706992556195) }, { FRAC_CONST(0.043112049866720), FRAC_CONST(0.014989479297920) }, { FRAC_CONST(0.043013021266188), FRAC_CONST(0.015271323940241) }, { FRAC_CONST(0.042912150130984), FRAC_CONST(0.015552514409871) }, { FRAC_CONST(0.042809440782090), FRAC_CONST(0.015833038661547) }, { FRAC_CONST(0.042704897619235), FRAC_CONST(0.016112884678543) }, { FRAC_CONST(0.042598525120698), FRAC_CONST(0.016392040473187) }, { FRAC_CONST(0.042490327843124), FRAC_CONST(0.016670494087374) }, { FRAC_CONST(0.042380310421324), FRAC_CONST(0.016948233593079) }, { FRAC_CONST(0.042268477568078), FRAC_CONST(0.017225247092864) }, { FRAC_CONST(0.042154834073934), FRAC_CONST(0.017501522720393) }, { FRAC_CONST(0.042039384807000), FRAC_CONST(0.017777048640940) }, { FRAC_CONST(0.041922134712739), FRAC_CONST(0.018051813051888) }, { FRAC_CONST(0.041803088813754), FRAC_CONST(0.018325804183247) }, { FRAC_CONST(0.041682252209576), FRAC_CONST(0.018599010298148) }, { FRAC_CONST(0.041559630076443), FRAC_CONST(0.018871419693350) }, { FRAC_CONST(0.041435227667079), FRAC_CONST(0.019143020699741) }, { FRAC_CONST(0.041309050310468), FRAC_CONST(0.019413801682838) }, { FRAC_CONST(0.041181103411629), FRAC_CONST(0.019683751043285) }, { FRAC_CONST(0.041051392451382), FRAC_CONST(0.019952857217350) }, { FRAC_CONST(0.040919922986111), FRAC_CONST(0.020221108677421) }, { FRAC_CONST(0.040786700647532), FRAC_CONST(0.020488493932496) }, { FRAC_CONST(0.040651731142446), FRAC_CONST(0.020755001528683) }, { FRAC_CONST(0.040515020252497), FRAC_CONST(0.021020620049682) }, { FRAC_CONST(0.040376573833925), FRAC_CONST(0.021285338117280) }, { FRAC_CONST(0.040236397817314), FRAC_CONST(0.021549144391836) }, { FRAC_CONST(0.040094498207337), FRAC_CONST(0.021812027572768) }, { FRAC_CONST(0.039950881082502), FRAC_CONST(0.022073976399034) }, { FRAC_CONST(0.039805552594888), FRAC_CONST(0.022334979649620) }, { FRAC_CONST(0.039658518969884), FRAC_CONST(0.022595026144014) }, { FRAC_CONST(0.039509786505922), FRAC_CONST(0.022854104742690) }, { FRAC_CONST(0.039359361574204), FRAC_CONST(0.023112204347583) }, { FRAC_CONST(0.039207250618434), FRAC_CONST(0.023369313902565) }, { FRAC_CONST(0.039053460154540), FRAC_CONST(0.023625422393919) }, { FRAC_CONST(0.038897996770393), FRAC_CONST(0.023880518850809) }, { FRAC_CONST(0.038740867125527), FRAC_CONST(0.024134592345752) }, { FRAC_CONST(0.038582077950852), FRAC_CONST(0.024387631995085) }, { FRAC_CONST(0.038421636048370), FRAC_CONST(0.024639626959432) }, { FRAC_CONST(0.038259548290876), FRAC_CONST(0.024890566444167) }, { FRAC_CONST(0.038095821621671), FRAC_CONST(0.025140439699877) }, { FRAC_CONST(0.037930463054261), FRAC_CONST(0.025389236022825) }, { FRAC_CONST(0.037763479672055), FRAC_CONST(0.025636944755403) }, { FRAC_CONST(0.037594878628068), FRAC_CONST(0.025883555286595) }, { FRAC_CONST(0.037424667144605), FRAC_CONST(0.026129057052425) }, { FRAC_CONST(0.037252852512960), FRAC_CONST(0.026373439536415) }, { FRAC_CONST(0.037079442093102), FRAC_CONST(0.026616692270033) }, { FRAC_CONST(0.036904443313354), FRAC_CONST(0.026858804833142) }, { FRAC_CONST(0.036727863670081), FRAC_CONST(0.027099766854444) }, { FRAC_CONST(0.036549710727369), FRAC_CONST(0.027339568011930) }, { FRAC_CONST(0.036369992116697), FRAC_CONST(0.027578198033315) }, { FRAC_CONST(0.036188715536611), FRAC_CONST(0.027815646696484) }, { FRAC_CONST(0.036005888752396), FRAC_CONST(0.028051903829926) }, { FRAC_CONST(0.035821519595745), FRAC_CONST(0.028286959313171) }, { FRAC_CONST(0.035635615964417), FRAC_CONST(0.028520803077226) }, { FRAC_CONST(0.035448185821906), FRAC_CONST(0.028753425105002) }, { FRAC_CONST(0.035259237197095), FRAC_CONST(0.028984815431745) }, { FRAC_CONST(0.035068778183914), FRAC_CONST(0.029214964145465) }, { FRAC_CONST(0.034876816940994), FRAC_CONST(0.029443861387355) }, { FRAC_CONST(0.034683361691315), FRAC_CONST(0.029671497352220) }, { FRAC_CONST(0.034488420721856), FRAC_CONST(0.029897862288892) }, { FRAC_CONST(0.034292002383240), FRAC_CONST(0.030122946500652) }, { FRAC_CONST(0.034094115089375), FRAC_CONST(0.030346740345641) }, { FRAC_CONST(0.033894767317093), FRAC_CONST(0.030569234237276) }, { FRAC_CONST(0.033693967605790), FRAC_CONST(0.030790418644658) }, { FRAC_CONST(0.033491724557057), FRAC_CONST(0.031010284092984) }, { FRAC_CONST(0.033288046834313), FRAC_CONST(0.031228821163949) }, { FRAC_CONST(0.033082943162434), FRAC_CONST(0.031446020496153) }, { FRAC_CONST(0.032876422327378), FRAC_CONST(0.031661872785500) }, { FRAC_CONST(0.032668493175811), FRAC_CONST(0.031876368785596) }, { FRAC_CONST(0.032459164614726), FRAC_CONST(0.032089499308145) }, { FRAC_CONST(0.032248445611061), FRAC_CONST(0.032301255223347) }, { FRAC_CONST(0.032036345191317), FRAC_CONST(0.032511627460281) }, { FRAC_CONST(0.031822872441171), FRAC_CONST(0.032720607007302) }, { FRAC_CONST(0.031608036505083), FRAC_CONST(0.032928184912422) }, { FRAC_CONST(0.031391846585912), FRAC_CONST(0.033134352283693) }, { FRAC_CONST(0.031174311944513), FRAC_CONST(0.033339100289593) }, { FRAC_CONST(0.030955441899347), FRAC_CONST(0.033542420159397) }, { FRAC_CONST(0.030735245826077), FRAC_CONST(0.033744303183559) }, { FRAC_CONST(0.030513733157171), FRAC_CONST(0.033944740714083) }, { FRAC_CONST(0.030290913381494), FRAC_CONST(0.034143724164891) }, { FRAC_CONST(0.030066796043904), FRAC_CONST(0.034341245012195) }, { FRAC_CONST(0.029841390744841), FRAC_CONST(0.034537294794860) }, { FRAC_CONST(0.029614707139919), FRAC_CONST(0.034731865114764) }, { FRAC_CONST(0.029386754939508), FRAC_CONST(0.034924947637164) }, { FRAC_CONST(0.029157543908322), FRAC_CONST(0.035116534091046) }, { FRAC_CONST(0.028927083864999), FRAC_CONST(0.035306616269485) }, { FRAC_CONST(0.028695384681680), FRAC_CONST(0.035495186029992) }, { FRAC_CONST(0.028462456283587), FRAC_CONST(0.035682235294866) }, { FRAC_CONST(0.028228308648598), FRAC_CONST(0.035867756051541) }, { FRAC_CONST(0.027992951806817), FRAC_CONST(0.036051740352923) }, { FRAC_CONST(0.027756395840148), FRAC_CONST(0.036234180317738) }, { FRAC_CONST(0.027518650881862), FRAC_CONST(0.036415068130865) }, { FRAC_CONST(0.027279727116161), FRAC_CONST(0.036594396043672) }, { FRAC_CONST(0.027039634777745), FRAC_CONST(0.036772156374348) }, { FRAC_CONST(0.026798384151369), FRAC_CONST(0.036948341508233) }, { FRAC_CONST(0.026555985571409), FRAC_CONST(0.037122943898140) }, { FRAC_CONST(0.026312449421412), FRAC_CONST(0.037295956064686) }, { FRAC_CONST(0.026067786133656), FRAC_CONST(0.037467370596605) }, { FRAC_CONST(0.025822006188702), FRAC_CONST(0.037637180151068) }, { FRAC_CONST(0.025575120114946), FRAC_CONST(0.037805377454000) }, { FRAC_CONST(0.025327138488165), FRAC_CONST(0.037971955300388) }, { FRAC_CONST(0.025078071931066), FRAC_CONST(0.038136906554591) }, { FRAC_CONST(0.024827931112832), FRAC_CONST(0.038300224150647) }, { FRAC_CONST(0.024576726748663), FRAC_CONST(0.038461901092573) }, { FRAC_CONST(0.024324469599317), FRAC_CONST(0.038621930454668) }, { FRAC_CONST(0.024071170470652), FRAC_CONST(0.038780305381806) }, { FRAC_CONST(0.023816840213160), FRAC_CONST(0.038937019089732) }, { FRAC_CONST(0.023561489721501), FRAC_CONST(0.039092064865353) }, { FRAC_CONST(0.023305129934041), FRAC_CONST(0.039245436067023) }, { FRAC_CONST(0.023047771832380), FRAC_CONST(0.039397126124832) }, { FRAC_CONST(0.022789426440883), FRAC_CONST(0.039547128540881) }, { FRAC_CONST(0.022530104826206), FRAC_CONST(0.039695436889566) }, { FRAC_CONST(0.022269818096825), FRAC_CONST(0.039842044817851) }, { FRAC_CONST(0.022008577402555), FRAC_CONST(0.039986946045542) }, { FRAC_CONST(0.021746393934081), FRAC_CONST(0.040130134365550) }, { FRAC_CONST(0.021483278922467), FRAC_CONST(0.040271603644166) }, { FRAC_CONST(0.021219243638687), FRAC_CONST(0.040411347821316) }, { FRAC_CONST(0.020954299393132), FRAC_CONST(0.040549360910825) }, { FRAC_CONST(0.020688457535133), FRAC_CONST(0.040685637000671) }, { FRAC_CONST(0.020421729452469), FRAC_CONST(0.040820170253240) }, { FRAC_CONST(0.020154126570884), FRAC_CONST(0.040952954905576) }, { FRAC_CONST(0.019885660353596), FRAC_CONST(0.041083985269625) }, { FRAC_CONST(0.019616342300802), FRAC_CONST(0.041213255732484) }, { FRAC_CONST(0.019346183949192), FRAC_CONST(0.041340760756635) }, { FRAC_CONST(0.019075196871451), FRAC_CONST(0.041466494880189) }, { FRAC_CONST(0.018803392675763), FRAC_CONST(0.041590452717113) }, { FRAC_CONST(0.018530783005316), FRAC_CONST(0.041712628957466) }, { FRAC_CONST(0.018257379537800), FRAC_CONST(0.041833018367625) }, { FRAC_CONST(0.017983193984910), FRAC_CONST(0.041951615790509) }, { FRAC_CONST(0.017708238091842), FRAC_CONST(0.042068416145797) }, { FRAC_CONST(0.017432523636792), FRAC_CONST(0.042183414430153) }, { FRAC_CONST(0.017156062430449), FRAC_CONST(0.042296605717432) }, { FRAC_CONST(0.016878866315491), FRAC_CONST(0.042407985158896) }, { FRAC_CONST(0.016600947166078), FRAC_CONST(0.042517547983420) }, { FRAC_CONST(0.016322316887341), FRAC_CONST(0.042625289497698) }, { FRAC_CONST(0.016042987414872), FRAC_CONST(0.042731205086442) }, { FRAC_CONST(0.015762970714219), FRAC_CONST(0.042835290212581) }, { FRAC_CONST(0.015482278780363), FRAC_CONST(0.042937540417454) }, { FRAC_CONST(0.015200923637213), FRAC_CONST(0.043037951321002) }, { FRAC_CONST(0.014918917337087), FRAC_CONST(0.043136518621958) }, { FRAC_CONST(0.014636271960196), FRAC_CONST(0.043233238098025) }, { FRAC_CONST(0.014352999614128), FRAC_CONST(0.043328105606063) }, { FRAC_CONST(0.014069112433327), FRAC_CONST(0.043421117082265) }, { FRAC_CONST(0.013784622578575), FRAC_CONST(0.043512268542327) }, { FRAC_CONST(0.013499542236471), FRAC_CONST(0.043601556081625) }, { FRAC_CONST(0.013213883618907), FRAC_CONST(0.043688975875378) }, { FRAC_CONST(0.012927658962548), FRAC_CONST(0.043774524178812) }, { FRAC_CONST(0.012640880528305), FRAC_CONST(0.043858197327323) }, { FRAC_CONST(0.012353560600813), FRAC_CONST(0.043939991736633) }, { FRAC_CONST(0.012065711487901), FRAC_CONST(0.044019903902940) }, { FRAC_CONST(0.011777345520066), FRAC_CONST(0.044097930403073) }, { FRAC_CONST(0.011488475049948), FRAC_CONST(0.044174067894638) }, { FRAC_CONST(0.011199112451794), FRAC_CONST(0.044248313116156) }, { FRAC_CONST(0.010909270120937), FRAC_CONST(0.044320662887211) }, { FRAC_CONST(0.010618960473257), FRAC_CONST(0.044391114108577) }, { FRAC_CONST(0.010328195944653), FRAC_CONST(0.044459663762361) }, { FRAC_CONST(0.010036988990509), FRAC_CONST(0.044526308912122) }, { FRAC_CONST(0.009745352085163), FRAC_CONST(0.044591046703005) }, { FRAC_CONST(0.009453297721368), FRAC_CONST(0.044653874361857) }, { FRAC_CONST(0.009160838409762), FRAC_CONST(0.044714789197351) }, { FRAC_CONST(0.008867986678328), FRAC_CONST(0.044773788600099) }, { FRAC_CONST(0.008574755071860), FRAC_CONST(0.044830870042761) }, { FRAC_CONST(0.008281156151424), FRAC_CONST(0.044886031080160) }, { FRAC_CONST(0.007987202493820), FRAC_CONST(0.044939269349379) }, { FRAC_CONST(0.007692906691044), FRAC_CONST(0.044990582569869) }, { FRAC_CONST(0.007398281349750), FRAC_CONST(0.045039968543542) }, { FRAC_CONST(0.007103339090706), FRAC_CONST(0.045087425154868) }, { FRAC_CONST(0.006808092548258), FRAC_CONST(0.045132950370962) }, { FRAC_CONST(0.006512554369783), FRAC_CONST(0.045176542241676) }, { FRAC_CONST(0.006216737215155), FRAC_CONST(0.045218198899680) }, { FRAC_CONST(0.005920653756196), FRAC_CONST(0.045257918560541) }, { FRAC_CONST(0.005624316676135), FRAC_CONST(0.045295699522801) }, { FRAC_CONST(0.005327738669067), FRAC_CONST(0.045331540168049) }, { FRAC_CONST(0.005030932439406), FRAC_CONST(0.045365438960992) }, { FRAC_CONST(0.004733910701344), FRAC_CONST(0.045397394449517) }, { FRAC_CONST(0.004436686178303), FRAC_CONST(0.045427405264758) }, { FRAC_CONST(0.004139271602393), FRAC_CONST(0.045455470121152) }, { FRAC_CONST(0.003841679713863), FRAC_CONST(0.045481587816494) }, { FRAC_CONST(0.003543923260561), FRAC_CONST(0.045505757231988) }, { FRAC_CONST(0.003246014997382), FRAC_CONST(0.045527977332297) }, { FRAC_CONST(0.002947967685724), FRAC_CONST(0.045548247165585) }, { FRAC_CONST(0.002649794092941), FRAC_CONST(0.045566565863562) }, { FRAC_CONST(0.002351506991799), FRAC_CONST(0.045582932641515) }, { FRAC_CONST(0.002053119159924), FRAC_CONST(0.045597346798344) }, { FRAC_CONST(0.001754643379257), FRAC_CONST(0.045609807716597) }, { FRAC_CONST(0.001456092435508), FRAC_CONST(0.045620314862489) }, { FRAC_CONST(0.001157479117605), FRAC_CONST(0.045628867785927) }, { FRAC_CONST(0.000858816217149), FRAC_CONST(0.045635466120535) }, { FRAC_CONST(0.000560116527865), FRAC_CONST(0.045640109583661) }, { FRAC_CONST(0.000261392845053), FRAC_CONST(0.045642797976394) } }; #endif // LD_DEC /* 60 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_240[] = { { FRAC_CONST(0.091286604111815), FRAC_CONST(0.000298735779793) }, { FRAC_CONST(0.091247502481454), FRAC_CONST(0.002688238127538) }, { FRAC_CONST(0.091145864370807), FRAC_CONST(0.005075898091152) }, { FRAC_CONST(0.090981759437558), FRAC_CONST(0.007460079287760) }, { FRAC_CONST(0.090755300151030), FRAC_CONST(0.009839147718664) }, { FRAC_CONST(0.090466641715108), FRAC_CONST(0.012211472889198) }, { FRAC_CONST(0.090115981961863), FRAC_CONST(0.014575428926191) }, { FRAC_CONST(0.089703561215976), FRAC_CONST(0.016929395692256) }, { FRAC_CONST(0.089229662130024), FRAC_CONST(0.019271759896156) }, { FRAC_CONST(0.088694609490769), FRAC_CONST(0.021600916198470) }, { FRAC_CONST(0.088098769996564), FRAC_CONST(0.023915268311810) }, { FRAC_CONST(0.087442552006035), FRAC_CONST(0.026213230094844) }, { FRAC_CONST(0.086726405258214), FRAC_CONST(0.028493226639351) }, { FRAC_CONST(0.085950820564309), FRAC_CONST(0.030753695349588) }, { FRAC_CONST(0.085116329471329), FRAC_CONST(0.032993087013213) }, { FRAC_CONST(0.084223503897785), FRAC_CONST(0.035209866863042) }, { FRAC_CONST(0.083272955741727), FRAC_CONST(0.037402515628894) }, { FRAC_CONST(0.082265336461381), FRAC_CONST(0.039569530578832) }, { FRAC_CONST(0.081201336628670), FRAC_CONST(0.041709426549053) }, { FRAC_CONST(0.080081685455930), FRAC_CONST(0.043820736961749) }, { FRAC_CONST(0.078907150296148), FRAC_CONST(0.045902014830227) }, { FRAC_CONST(0.077678536117054), FRAC_CONST(0.047951833750597) }, { FRAC_CONST(0.076396684949434), FRAC_CONST(0.049968788879362) }, { FRAC_CONST(0.075062475310050), FRAC_CONST(0.051951497896226) }, { FRAC_CONST(0.073676821599542), FRAC_CONST(0.053898601951466) }, { FRAC_CONST(0.072240673475749), FRAC_CONST(0.055808766597225) }, { FRAC_CONST(0.070755015202858), FRAC_CONST(0.057680682702068) }, { FRAC_CONST(0.069220864976840), FRAC_CONST(0.059513067348201) }, { FRAC_CONST(0.067639274227625), FRAC_CONST(0.061304664710718) }, { FRAC_CONST(0.066011326898512), FRAC_CONST(0.063054246918278) }, { FRAC_CONST(0.064338138703282), FRAC_CONST(0.064760614894630) }, { FRAC_CONST(0.062620856361546), FRAC_CONST(0.066422599180399) }, { FRAC_CONST(0.060860656812842), FRAC_CONST(0.068039060734572) }, { FRAC_CONST(0.059058746410016), FRAC_CONST(0.069608891715145) }, { FRAC_CONST(0.057216360092450), FRAC_CONST(0.071131016238378) }, { FRAC_CONST(0.055334760539699), FRAC_CONST(0.072604391116154) }, { FRAC_CONST(0.053415237306106), FRAC_CONST(0.074028006570930) }, { FRAC_CONST(0.051459105937014), FRAC_CONST(0.075400886927784) }, { FRAC_CONST(0.049467707067153), FRAC_CONST(0.076722091283096) }, { FRAC_CONST(0.047442405501835), FRAC_CONST(0.077990714149396) }, { FRAC_CONST(0.045384589281588), FRAC_CONST(0.079205886075941) }, { FRAC_CONST(0.043295668730857), FRAC_CONST(0.080366774244592) }, { FRAC_CONST(0.041177075491445), FRAC_CONST(0.081472583040586) }, { FRAC_CONST(0.039030261541332), FRAC_CONST(0.082522554597810) }, { FRAC_CONST(0.036856698199564), FRAC_CONST(0.083515969318206) }, { FRAC_CONST(0.034657875117883), FRAC_CONST(0.084452146364948) }, { FRAC_CONST(0.032435299259796), FRAC_CONST(0.085330444129049) }, { FRAC_CONST(0.030190493867775), FRAC_CONST(0.086150260669096) }, { FRAC_CONST(0.027924997419306), FRAC_CONST(0.086911034123781) }, { FRAC_CONST(0.025640362572491), FRAC_CONST(0.087612243096981) }, { FRAC_CONST(0.023338155101933), FRAC_CONST(0.088253407015092) }, { FRAC_CONST(0.021019952825636), FRAC_CONST(0.088834086456390) }, { FRAC_CONST(0.018687344523641), FRAC_CONST(0.089353883452193) }, { FRAC_CONST(0.016341928849164), FRAC_CONST(0.089812441759604) }, { FRAC_CONST(0.013985313232951), FRAC_CONST(0.090209447105664) }, { FRAC_CONST(0.011619112781631), FRAC_CONST(0.090544627402740) }, { FRAC_CONST(0.009244949170797), FRAC_CONST(0.090817752935000) }, { FRAC_CONST(0.006864449533597), FRAC_CONST(0.091028636515846) }, { FRAC_CONST(0.004479245345574), FRAC_CONST(0.091177133616206) }, { FRAC_CONST(0.002090971306534), FRAC_CONST(0.091263142463585) } }; #endif // ALLOW_SMALL_FRAMELENGTH #ifdef SSR_DEC /* 128 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_512[] = { { FRAC_CONST(0.062499926465731), FRAC_CONST(0.000095873761643) }, { FRAC_CONST(0.062494043817678), FRAC_CONST(0.000862836783004) }, { FRAC_CONST(0.062478749796497), FRAC_CONST(0.001629669864319) }, { FRAC_CONST(0.062454046705412), FRAC_CONST(0.002396257523347) }, { FRAC_CONST(0.062419938264617), FRAC_CONST(0.003162484314806) }, { FRAC_CONST(0.062376429610718), FRAC_CONST(0.003928234847760) }, { FRAC_CONST(0.062323527295958), FRAC_CONST(0.004693393802995) }, { FRAC_CONST(0.062261239287231), FRAC_CONST(0.005457845950387) }, { FRAC_CONST(0.062189574964882), FRAC_CONST(0.006221476166254) }, { FRAC_CONST(0.062108545121295), FRAC_CONST(0.006984169450695) }, { FRAC_CONST(0.062018161959266), FRAC_CONST(0.007745810944907) }, { FRAC_CONST(0.061918439090167), FRAC_CONST(0.008506285948482) }, { FRAC_CONST(0.061809391531894), FRAC_CONST(0.009265479936681) }, { FRAC_CONST(0.061691035706609), FRAC_CONST(0.010023278577683) }, { FRAC_CONST(0.061563389438265), FRAC_CONST(0.010779567749800) }, { FRAC_CONST(0.061426471949919), FRAC_CONST(0.011534233558664) }, { FRAC_CONST(0.061280303860842), FRAC_CONST(0.012287162354380) }, { FRAC_CONST(0.061124907183410), FRAC_CONST(0.013038240748641) }, { FRAC_CONST(0.060960305319791), FRAC_CONST(0.013787355631805) }, { FRAC_CONST(0.060786523058421), FRAC_CONST(0.014534394189923) }, { FRAC_CONST(0.060603586570268), FRAC_CONST(0.015279243921739) }, { FRAC_CONST(0.060411523404896), FRAC_CONST(0.016021792655621) }, { FRAC_CONST(0.060210362486310), FRAC_CONST(0.016761928566463) }, { FRAC_CONST(0.060000134108604), FRAC_CONST(0.017499540192517) }, { FRAC_CONST(0.059780869931400), FRAC_CONST(0.018234516452187) }, { FRAC_CONST(0.059552602975075), FRAC_CONST(0.018966746660751) }, { FRAC_CONST(0.059315367615794), FRAC_CONST(0.019696120547033) }, { FRAC_CONST(0.059069199580329), FRAC_CONST(0.020422528270008) }, { FRAC_CONST(0.058814135940681), FRAC_CONST(0.021145860435346) }, { FRAC_CONST(0.058550215108495), FRAC_CONST(0.021866008111883) }, { FRAC_CONST(0.058277476829279), FRAC_CONST(0.022582862848028) }, { FRAC_CONST(0.057995962176414), FRAC_CONST(0.023296316688095) }, { FRAC_CONST(0.057705713544970), FRAC_CONST(0.024006262188558) }, { FRAC_CONST(0.057406774645326), FRAC_CONST(0.024712592434239) }, { FRAC_CONST(0.057099190496578), FRAC_CONST(0.025415201054398) }, { FRAC_CONST(0.056783007419769), FRAC_CONST(0.026113982238763) }, { FRAC_CONST(0.056458273030907), FRAC_CONST(0.026808830753458) }, { FRAC_CONST(0.056125036233796), FRAC_CONST(0.027499641956852) }, { FRAC_CONST(0.055783347212673), FRAC_CONST(0.028186311815319) }, { FRAC_CONST(0.055433257424646), FRAC_CONST(0.028868736918904) }, { FRAC_CONST(0.055074819591951), FRAC_CONST(0.029546814496896) }, { FRAC_CONST(0.054708087694007), FRAC_CONST(0.030220442433307) }, { FRAC_CONST(0.054333116959288), FRAC_CONST(0.030889519282247) }, { FRAC_CONST(0.053949963857008), FRAC_CONST(0.031553944283204) }, { FRAC_CONST(0.053558686088614), FRAC_CONST(0.032213617376216) }, { FRAC_CONST(0.053159342579100), FRAC_CONST(0.032868439216943) }, { FRAC_CONST(0.052751993468129), FRAC_CONST(0.033518311191623) }, { FRAC_CONST(0.052336700100979), FRAC_CONST(0.034163135431927) }, { FRAC_CONST(0.051913525019303), FRAC_CONST(0.034802814829698) }, { FRAC_CONST(0.051482531951712), FRAC_CONST(0.035437253051569) }, { FRAC_CONST(0.051043785804177), FRAC_CONST(0.036066354553480) }, { FRAC_CONST(0.050597352650253), FRAC_CONST(0.036690024595057) }, { FRAC_CONST(0.050143299721132), FRAC_CONST(0.037308169253887) }, { FRAC_CONST(0.049681695395515), FRAC_CONST(0.037920695439658) }, { FRAC_CONST(0.049212609189314), FRAC_CONST(0.038527510908178) }, { FRAC_CONST(0.048736111745188), FRAC_CONST(0.039128524275271) }, { FRAC_CONST(0.048252274821899), FRAC_CONST(0.039723645030535) }, { FRAC_CONST(0.047761171283507), FRAC_CONST(0.040312783550971) }, { FRAC_CONST(0.047262875088400), FRAC_CONST(0.040895851114488) }, { FRAC_CONST(0.046757461278150), FRAC_CONST(0.041472759913252) }, { FRAC_CONST(0.046245005966220), FRAC_CONST(0.042043423066923) }, { FRAC_CONST(0.045725586326493), FRAC_CONST(0.042607754635728) }, { FRAC_CONST(0.045199280581658), FRAC_CONST(0.043165669633408) }, { FRAC_CONST(0.044666167991423), FRAC_CONST(0.043717084040018) }, { FRAC_CONST(0.044126328840584), FRAC_CONST(0.044261914814575) }, { FRAC_CONST(0.043579844426930), FRAC_CONST(0.044800079907569) }, { FRAC_CONST(0.043026797049006), FRAC_CONST(0.045331498273316) }, { FRAC_CONST(0.042467269993710), FRAC_CONST(0.045856089882166) }, { FRAC_CONST(0.041901347523761), FRAC_CONST(0.046373775732552) }, { FRAC_CONST(0.041329114865000), FRAC_CONST(0.046884477862888) }, { FRAC_CONST(0.040750658193560), FRAC_CONST(0.047388119363313) }, { FRAC_CONST(0.040166064622889), FRAC_CONST(0.047884624387270) }, { FRAC_CONST(0.039575422190629), FRAC_CONST(0.048373918162926) }, { FRAC_CONST(0.038978819845356), FRAC_CONST(0.048855927004441) }, { FRAC_CONST(0.038376347433190), FRAC_CONST(0.049330578323055) }, { FRAC_CONST(0.037768095684260), FRAC_CONST(0.049797800638026) }, { FRAC_CONST(0.037154156199042), FRAC_CONST(0.050257523587392) }, { FRAC_CONST(0.036534621434563), FRAC_CONST(0.050709677938566) }, { FRAC_CONST(0.035909584690482), FRAC_CONST(0.051154195598769) }, { FRAC_CONST(0.035279140095032), FRAC_CONST(0.051591009625274) }, { FRAC_CONST(0.034643382590851), FRAC_CONST(0.052020054235496) }, { FRAC_CONST(0.034002407920680), FRAC_CONST(0.052441264816895) }, { FRAC_CONST(0.033356312612947), FRAC_CONST(0.052854577936706) }, { FRAC_CONST(0.032705193967229), FRAC_CONST(0.053259931351495) }, { FRAC_CONST(0.032049150039598), FRAC_CONST(0.053657264016528) }, { FRAC_CONST(0.031388279627857), FRAC_CONST(0.054046516094966) }, { FRAC_CONST(0.030722682256659), FRAC_CONST(0.054427628966880) }, { FRAC_CONST(0.030052458162521), FRAC_CONST(0.054800545238072) }, { FRAC_CONST(0.029377708278725), FRAC_CONST(0.055165208748723) }, { FRAC_CONST(0.028698534220122), FRAC_CONST(0.055521564581850) }, { FRAC_CONST(0.028015038267826), FRAC_CONST(0.055869559071575) }, { FRAC_CONST(0.027327323353815), FRAC_CONST(0.056209139811209) }, { FRAC_CONST(0.026635493045425), FRAC_CONST(0.056540255661140) }, { FRAC_CONST(0.025939651529755), FRAC_CONST(0.056862856756541) }, { FRAC_CONST(0.025239903597978), FRAC_CONST(0.057176894514872) }, { FRAC_CONST(0.024536354629559), FRAC_CONST(0.057482321643202) }, { FRAC_CONST(0.023829110576385), FRAC_CONST(0.057779092145329) }, { FRAC_CONST(0.023118277946808), FRAC_CONST(0.058067161328707) }, { FRAC_CONST(0.022403963789609), FRAC_CONST(0.058346485811177) }, { FRAC_CONST(0.021686275677870), FRAC_CONST(0.058617023527499) }, { FRAC_CONST(0.020965321692783), FRAC_CONST(0.058878733735689) }, { FRAC_CONST(0.020241210407366), FRAC_CONST(0.059131577023150) }, { FRAC_CONST(0.019514050870114), FRAC_CONST(0.059375515312615) }, { FRAC_CONST(0.018783952588580), FRAC_CONST(0.059610511867874) }, { FRAC_CONST(0.018051025512878), FRAC_CONST(0.059836531299311) }, { FRAC_CONST(0.017315380019131), FRAC_CONST(0.060053539569230) }, { FRAC_CONST(0.016577126892844), FRAC_CONST(0.060261503996984) }, { FRAC_CONST(0.015836377312223), FRAC_CONST(0.060460393263896) }, { FRAC_CONST(0.015093242831429), FRAC_CONST(0.060650177417972) }, { FRAC_CONST(0.014347835363782), FRAC_CONST(0.060830827878419) }, { FRAC_CONST(0.013600267164905), FRAC_CONST(0.061002317439940) }, { FRAC_CONST(0.012850650815819), FRAC_CONST(0.061164620276839) }, { FRAC_CONST(0.012099099205988), FRAC_CONST(0.061317711946905) }, { FRAC_CONST(0.011345725516320), FRAC_CONST(0.061461569395097) }, { FRAC_CONST(0.010590643202123), FRAC_CONST(0.061596170957011) }, { FRAC_CONST(0.009833965976015), FRAC_CONST(0.061721496362147) }, { FRAC_CONST(0.009075807790803), FRAC_CONST(0.061837526736961) }, { FRAC_CONST(0.008316282822321), FRAC_CONST(0.061944244607705) }, { FRAC_CONST(0.007555505452236), FRAC_CONST(0.062041633903059) }, { FRAC_CONST(0.006793590250821), FRAC_CONST(0.062129679956555) }, { FRAC_CONST(0.006030651959703), FRAC_CONST(0.062208369508780) }, { FRAC_CONST(0.005266805474583), FRAC_CONST(0.062277690709378) }, { FRAC_CONST(0.004502165827931), FRAC_CONST(0.062337633118830) }, { FRAC_CONST(0.003736848171665), FRAC_CONST(0.062388187710030) }, { FRAC_CONST(0.002970967759810), FRAC_CONST(0.062429346869643) }, { FRAC_CONST(0.002204639931138), FRAC_CONST(0.062461104399250) }, { FRAC_CONST(0.001437980091802), FRAC_CONST(0.062483455516285) }, { FRAC_CONST(0.000671103697954), FRAC_CONST(0.062496396854751) } }; /* 16 (N/4) complex twiddle factors */ ALIGN static const complex_t mdct_tab_64[] = { { FRAC_CONST(0.176763384336599), FRAC_CONST(0.002169321984356) }, { FRAC_CONST(0.175699589589310), FRAC_CONST(0.019484717553714) }, { FRAC_CONST(0.172943711747111), FRAC_CONST(0.036612464641599) }, { FRAC_CONST(0.168522291420137), FRAC_CONST(0.053387613680577) }, { FRAC_CONST(0.162477909303132), FRAC_CONST(0.069648610815172) }, { FRAC_CONST(0.154868776100077), FRAC_CONST(0.085238853753814) }, { FRAC_CONST(0.145768171923295), FRAC_CONST(0.100008199934509) }, { FRAC_CONST(0.135263740565902), FRAC_CONST(0.113814412479792) }, { FRAC_CONST(0.123456645444178), FRAC_CONST(0.126524530015608) }, { FRAC_CONST(0.110460595338559), FRAC_CONST(0.138016147162030) }, { FRAC_CONST(0.096400749315926), FRAC_CONST(0.148178593363981) }, { FRAC_CONST(0.081412511379371), FRAC_CONST(0.156913998709178) }, { FRAC_CONST(0.065640226453626), FRAC_CONST(0.164138236468888) }, { FRAC_CONST(0.049235790264535), FRAC_CONST(0.169781733284316) }, { FRAC_CONST(0.032357186500177), FRAC_CONST(0.173790139196080) }, { FRAC_CONST(0.015166965341583), FRAC_CONST(0.176124851064031) } }; #endif // SSR_DEC #endif // FIXED_POINT #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/filtbank.c0000644000175000017500000003306514647725152015653 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: filtbank.c,v 1.46 2009/01/26 23:51:15 menno Exp $ **/ #include "common.h" #include "structs.h" #include #include #ifdef _WIN32_WCE #define assert(x) #else #include #endif #include "filtbank.h" #include "syntax.h" #include "kbd_win.h" #include "sine_win.h" #include "mdct.h" fb_info *filter_bank_init(uint16_t frame_len) { uint16_t nshort = frame_len/8; #ifdef LD_DEC uint16_t frame_len_ld = frame_len/2; #endif fb_info *fb = (fb_info*)faad_malloc(sizeof(fb_info)); memset(fb, 0, sizeof(fb_info)); /* normal */ fb->mdct256 = faad_mdct_init(2*nshort); fb->mdct2048 = faad_mdct_init(2*frame_len); #ifdef LD_DEC /* LD */ fb->mdct1024 = faad_mdct_init(2*frame_len_ld); #endif #ifdef ALLOW_SMALL_FRAMELENGTH if (frame_len == 1024) { #endif fb->long_window[0] = sine_long_1024; fb->short_window[0] = sine_short_128; fb->long_window[1] = kbd_long_1024; fb->short_window[1] = kbd_short_128; #ifdef LD_DEC fb->ld_window[0] = sine_mid_512; fb->ld_window[1] = ld_mid_512; #endif #ifdef ALLOW_SMALL_FRAMELENGTH } else /* (frame_len == 960) */ { fb->long_window[0] = sine_long_960; fb->short_window[0] = sine_short_120; fb->long_window[1] = kbd_long_960; fb->short_window[1] = kbd_short_120; #ifdef LD_DEC fb->ld_window[0] = sine_mid_480; fb->ld_window[1] = ld_mid_480; #endif } #endif return fb; } void filter_bank_end(fb_info *fb) { if (fb != NULL) { #ifdef PROFILE printf("FB: %I64d cycles\n", fb->cycles); #endif faad_mdct_end(fb->mdct256); faad_mdct_end(fb->mdct2048); #ifdef LD_DEC faad_mdct_end(fb->mdct1024); #endif faad_free(fb); } } static INLINE void imdct_long(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t len) { #ifdef LD_DEC mdct_info *mdct = NULL; switch (len) { case 2048: case 1920: mdct = fb->mdct2048; break; case 1024: case 960: mdct = fb->mdct1024; break; } faad_imdct(mdct, in_data, out_data); #else faad_imdct(fb->mdct2048, in_data, out_data); #endif } #ifdef LTP_DEC static INLINE void mdct(fb_info *fb, real_t *in_data, real_t *out_data, uint16_t len) { mdct_info *mdct = NULL; switch (len) { case 2048: case 1920: mdct = fb->mdct2048; break; case 256: case 240: mdct = fb->mdct256; break; #ifdef LD_DEC case 1024: case 960: mdct = fb->mdct1024; break; #endif } faad_mdct(mdct, in_data, out_data); } #endif void ifilter_bank(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *freq_in, real_t *time_out, real_t *overlap, uint8_t object_type, uint16_t frame_len) { int16_t i; ALIGN real_t transf_buf[2*1024] = {0}; const real_t *window_long = NULL; const real_t *window_long_prev = NULL; const real_t *window_short = NULL; const real_t *window_short_prev = NULL; uint16_t nlong = frame_len; uint16_t nshort = frame_len/8; uint16_t trans = nshort/2; uint16_t nflat_ls = (nlong-nshort)/2; #ifdef PROFILE int64_t count = faad_get_ts(); #endif /* select windows of current frame and previous frame (Sine or KBD) */ #ifdef LD_DEC if (object_type == LD) { window_long = fb->ld_window[window_shape]; window_long_prev = fb->ld_window[window_shape_prev]; } else { #endif window_long = fb->long_window[window_shape]; window_long_prev = fb->long_window[window_shape_prev]; window_short = fb->short_window[window_shape]; window_short_prev = fb->short_window[window_shape_prev]; #ifdef LD_DEC } #endif #if 0 for (i = 0; i < 1024; i++) { printf("%d\n", freq_in[i]); } #endif #if 0 printf("%d %d\n", window_sequence, window_shape); #endif switch (window_sequence) { case ONLY_LONG_SEQUENCE: /* perform iMDCT */ imdct_long(fb, freq_in, transf_buf, 2*nlong); /* add second half output of previous frame to windowed output of current frame */ for (i = 0; i < nlong; i+=4) { time_out[i] = overlap[i] + MUL_F(transf_buf[i],window_long_prev[i]); time_out[i+1] = overlap[i+1] + MUL_F(transf_buf[i+1],window_long_prev[i+1]); time_out[i+2] = overlap[i+2] + MUL_F(transf_buf[i+2],window_long_prev[i+2]); time_out[i+3] = overlap[i+3] + MUL_F(transf_buf[i+3],window_long_prev[i+3]); } /* window the second half and save as overlap for next frame */ for (i = 0; i < nlong; i+=4) { overlap[i] = MUL_F(transf_buf[nlong+i],window_long[nlong-1-i]); overlap[i+1] = MUL_F(transf_buf[nlong+i+1],window_long[nlong-2-i]); overlap[i+2] = MUL_F(transf_buf[nlong+i+2],window_long[nlong-3-i]); overlap[i+3] = MUL_F(transf_buf[nlong+i+3],window_long[nlong-4-i]); } break; case LONG_START_SEQUENCE: /* perform iMDCT */ imdct_long(fb, freq_in, transf_buf, 2*nlong); /* add second half output of previous frame to windowed output of current frame */ for (i = 0; i < nlong; i+=4) { time_out[i] = overlap[i] + MUL_F(transf_buf[i],window_long_prev[i]); time_out[i+1] = overlap[i+1] + MUL_F(transf_buf[i+1],window_long_prev[i+1]); time_out[i+2] = overlap[i+2] + MUL_F(transf_buf[i+2],window_long_prev[i+2]); time_out[i+3] = overlap[i+3] + MUL_F(transf_buf[i+3],window_long_prev[i+3]); } /* window the second half and save as overlap for next frame */ /* construct second half window using padding with 1's and 0's */ for (i = 0; i < nflat_ls; i++) overlap[i] = transf_buf[nlong+i]; for (i = 0; i < nshort; i++) overlap[nflat_ls+i] = MUL_F(transf_buf[nlong+nflat_ls+i],window_short[nshort-i-1]); for (i = 0; i < nflat_ls; i++) overlap[nflat_ls+nshort+i] = 0; break; case EIGHT_SHORT_SEQUENCE: /* perform iMDCT for each short block */ faad_imdct(fb->mdct256, freq_in+0*nshort, transf_buf+2*nshort*0); faad_imdct(fb->mdct256, freq_in+1*nshort, transf_buf+2*nshort*1); faad_imdct(fb->mdct256, freq_in+2*nshort, transf_buf+2*nshort*2); faad_imdct(fb->mdct256, freq_in+3*nshort, transf_buf+2*nshort*3); faad_imdct(fb->mdct256, freq_in+4*nshort, transf_buf+2*nshort*4); faad_imdct(fb->mdct256, freq_in+5*nshort, transf_buf+2*nshort*5); faad_imdct(fb->mdct256, freq_in+6*nshort, transf_buf+2*nshort*6); faad_imdct(fb->mdct256, freq_in+7*nshort, transf_buf+2*nshort*7); /* add second half output of previous frame to windowed output of current frame */ for (i = 0; i < nflat_ls; i++) time_out[i] = overlap[i]; for(i = 0; i < nshort; i++) { time_out[nflat_ls+ i] = overlap[nflat_ls+ i] + MUL_F(transf_buf[nshort*0+i],window_short_prev[i]); time_out[nflat_ls+1*nshort+i] = overlap[nflat_ls+nshort*1+i] + MUL_F(transf_buf[nshort*1+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*2+i],window_short[i]); time_out[nflat_ls+2*nshort+i] = overlap[nflat_ls+nshort*2+i] + MUL_F(transf_buf[nshort*3+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*4+i],window_short[i]); time_out[nflat_ls+3*nshort+i] = overlap[nflat_ls+nshort*3+i] + MUL_F(transf_buf[nshort*5+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*6+i],window_short[i]); if (i < trans) time_out[nflat_ls+4*nshort+i] = overlap[nflat_ls+nshort*4+i] + MUL_F(transf_buf[nshort*7+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*8+i],window_short[i]); } /* window the second half and save as overlap for next frame */ for(i = 0; i < nshort; i++) { if (i >= trans) overlap[nflat_ls+4*nshort+i-nlong] = MUL_F(transf_buf[nshort*7+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*8+i],window_short[i]); overlap[nflat_ls+5*nshort+i-nlong] = MUL_F(transf_buf[nshort*9+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*10+i],window_short[i]); overlap[nflat_ls+6*nshort+i-nlong] = MUL_F(transf_buf[nshort*11+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*12+i],window_short[i]); overlap[nflat_ls+7*nshort+i-nlong] = MUL_F(transf_buf[nshort*13+i],window_short[nshort-1-i]) + MUL_F(transf_buf[nshort*14+i],window_short[i]); overlap[nflat_ls+8*nshort+i-nlong] = MUL_F(transf_buf[nshort*15+i],window_short[nshort-1-i]); } for (i = 0; i < nflat_ls; i++) overlap[nflat_ls+nshort+i] = 0; break; case LONG_STOP_SEQUENCE: /* perform iMDCT */ imdct_long(fb, freq_in, transf_buf, 2*nlong); /* add second half output of previous frame to windowed output of current frame */ /* construct first half window using padding with 1's and 0's */ for (i = 0; i < nflat_ls; i++) time_out[i] = overlap[i]; for (i = 0; i < nshort; i++) time_out[nflat_ls+i] = overlap[nflat_ls+i] + MUL_F(transf_buf[nflat_ls+i],window_short_prev[i]); for (i = 0; i < nflat_ls; i++) time_out[nflat_ls+nshort+i] = overlap[nflat_ls+nshort+i] + transf_buf[nflat_ls+nshort+i]; /* window the second half and save as overlap for next frame */ for (i = 0; i < nlong; i++) overlap[i] = MUL_F(transf_buf[nlong+i],window_long[nlong-1-i]); break; } #if 0 for (i = 0; i < 1024; i++) { printf("%d\n", time_out[i]); //printf("0x%.8X\n", time_out[i]); } #endif #ifdef PROFILE count = faad_get_ts() - count; fb->cycles += count; #endif } #ifdef LTP_DEC /* only works for LTP -> no overlapping, no short blocks */ void filter_bank_ltp(fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *in_data, real_t *out_mdct, uint8_t object_type, uint16_t frame_len) { int16_t i; ALIGN real_t windowed_buf[2*1024] = {0}; const real_t *window_long = NULL; const real_t *window_long_prev = NULL; const real_t *window_short = NULL; const real_t *window_short_prev = NULL; uint16_t nlong = frame_len; uint16_t nshort = frame_len/8; uint16_t nflat_ls = (nlong-nshort)/2; assert(window_sequence != EIGHT_SHORT_SEQUENCE); #ifdef LD_DEC if (object_type == LD) { window_long = fb->ld_window[window_shape]; window_long_prev = fb->ld_window[window_shape_prev]; } else { #endif window_long = fb->long_window[window_shape]; window_long_prev = fb->long_window[window_shape_prev]; window_short = fb->short_window[window_shape]; window_short_prev = fb->short_window[window_shape_prev]; #ifdef LD_DEC } #endif switch(window_sequence) { case ONLY_LONG_SEQUENCE: for (i = nlong-1; i >= 0; i--) { windowed_buf[i] = MUL_F(in_data[i], window_long_prev[i]); windowed_buf[i+nlong] = MUL_F(in_data[i+nlong], window_long[nlong-1-i]); } mdct(fb, windowed_buf, out_mdct, 2*nlong); break; case LONG_START_SEQUENCE: for (i = 0; i < nlong; i++) windowed_buf[i] = MUL_F(in_data[i], window_long_prev[i]); for (i = 0; i < nflat_ls; i++) windowed_buf[i+nlong] = in_data[i+nlong]; for (i = 0; i < nshort; i++) windowed_buf[i+nlong+nflat_ls] = MUL_F(in_data[i+nlong+nflat_ls], window_short[nshort-1-i]); for (i = 0; i < nflat_ls; i++) windowed_buf[i+nlong+nflat_ls+nshort] = 0; mdct(fb, windowed_buf, out_mdct, 2*nlong); break; case LONG_STOP_SEQUENCE: for (i = 0; i < nflat_ls; i++) windowed_buf[i] = 0; for (i = 0; i < nshort; i++) windowed_buf[i+nflat_ls] = MUL_F(in_data[i+nflat_ls], window_short_prev[i]); for (i = 0; i < nflat_ls; i++) windowed_buf[i+nflat_ls+nshort] = in_data[i+nflat_ls+nshort]; for (i = 0; i < nlong; i++) windowed_buf[i+nlong] = MUL_F(in_data[i+nlong], window_long[nlong-1-i]); mdct(fb, windowed_buf, out_mdct, 2*nlong); break; } } #endif xine-lib-1.2/contrib/libfaad/sbr_huff.h0000644000175000017500000000301114647725151015647 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_huff.h,v 1.21 2007/11/01 12:33:35 menno Exp $ **/ #ifndef __SBR_HUFF_H__ #define __SBR_HUFF_H__ #ifdef __cplusplus extern "C" { #endif void sbr_envelope(bitfile *ld, sbr_info *sbr, uint8_t ch); void sbr_noise(bitfile *ld, sbr_info *sbr, uint8_t ch); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ssr.c0000644000175000017500000001344714647725151014671 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ssr.c,v 1.19 2007/11/01 12:33:36 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SSR_DEC #include "syntax.h" #include "filtbank.h" #include "ssr.h" #include "ssr_fb.h" void ssr_decode(ssr_info *ssr, fb_info *fb, uint8_t window_sequence, uint8_t window_shape, uint8_t window_shape_prev, real_t *freq_in, real_t *time_out, real_t *overlap, real_t ipqf_buffer[SSR_BANDS][96/4], real_t *prev_fmd, uint16_t frame_len) { uint8_t band; uint16_t ssr_frame_len = frame_len/SSR_BANDS; real_t time_tmp[2048] = {0}; real_t output[1024] = {0}; for (band = 0; band < SSR_BANDS; band++) { int16_t j; /* uneven bands have inverted frequency scale */ if (band == 1 || band == 3) { for (j = 0; j < ssr_frame_len/2; j++) { real_t tmp; tmp = freq_in[j + ssr_frame_len*band]; freq_in[j + ssr_frame_len*band] = freq_in[ssr_frame_len - j - 1 + ssr_frame_len*band]; freq_in[ssr_frame_len - j - 1 + ssr_frame_len*band] = tmp; } } /* non-overlapping inverse filterbank for SSR */ ssr_ifilter_bank(fb, window_sequence, window_shape, window_shape_prev, freq_in + band*ssr_frame_len, time_tmp + band*ssr_frame_len, ssr_frame_len); /* gain control */ ssr_gain_control(ssr, time_tmp, output, overlap, prev_fmd, band, window_sequence, ssr_frame_len); } /* inverse pqf to bring subbands together again */ ssr_ipqf(ssr, output, time_out, ipqf_buffer, frame_len, SSR_BANDS); } static void ssr_gain_control(ssr_info *ssr, real_t *data, real_t *output, real_t *overlap, real_t *prev_fmd, uint8_t band, uint8_t window_sequence, uint16_t frame_len) { uint16_t i; real_t gc_function[2*1024/SSR_BANDS]; if (window_sequence != EIGHT_SHORT_SEQUENCE) { ssr_gc_function(ssr, &prev_fmd[band * frame_len*2], gc_function, window_sequence, band, frame_len); for (i = 0; i < frame_len*2; i++) data[band * frame_len*2 + i] *= gc_function[i]; for (i = 0; i < frame_len; i++) { output[band*frame_len + i] = overlap[band*frame_len + i] + data[band*frame_len*2 + i]; } for (i = 0; i < frame_len; i++) { overlap[band*frame_len + i] = data[band*frame_len*2 + frame_len + i]; } } else { uint8_t w; for (w = 0; w < 8; w++) { uint16_t frame_len8 = frame_len/8; uint16_t frame_len16 = frame_len/16; ssr_gc_function(ssr, &prev_fmd[band*frame_len*2 + w*frame_len*2/8], gc_function, window_sequence, frame_len); for (i = 0; i < frame_len8*2; i++) data[band*frame_len*2 + w*frame_len8*2+i] *= gc_function[i]; for (i = 0; i < frame_len8; i++) { overlap[band*frame_len + i + 7*frame_len16 + w*frame_len8] += data[band*frame_len*2 + 2*w*frame_len8 + i]; } for (i = 0; i < frame_len8; i++) { overlap[band*frame_len + i + 7*frame_len16 + (w+1)*frame_len8] = data[band*frame_len*2 + 2*w*frame_len8 + frame_len8 + i]; } } for (i = 0; i < frame_len; i++) output[band*frame_len + i] = overlap[band*frame_len + i]; for (i = 0; i < frame_len; i++) overlap[band*frame_len + i] = overlap[band*frame_len + i + frame_len]; } } static void ssr_gc_function(ssr_info *ssr, real_t *prev_fmd, real_t *gc_function, uint8_t window_sequence, uint8_t band, uint16_t frame_len) { uint16_t i; uint16_t len_area1, len_area2; int32_t aloc[10]; real_t alev[10]; switch (window_sequence) { case ONLY_LONG_SEQUENCE: len_area1 = frame_len/SSR_BANDS; len_area2 = 0; break; case LONG_START_SEQUENCE: len_area1 = (frame_len/SSR_BANDS)*7/32; len_area2 = (frame_len/SSR_BANDS)/16; break; case EIGHT_SHORT_SEQUENCE: len_area1 = (frame_len/8)/SSR_BANDS; len_area2 = 0; break; case LONG_STOP_SEQUENCE: len_area1 = (frame_len/SSR_BANDS); len_area2 = 0; break; } /* decode bitstream information */ /* build array M */ for (i = 0; i < frame_len*2; i++) gc_function[i] = 1; } #endif xine-lib-1.2/contrib/libfaad/sbr_e_nf.h0000644000175000017500000000321314647725151015632 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_e_nf.h,v 1.18 2007/11/01 12:33:35 menno Exp $ **/ #ifndef __SBR_E_NF_H__ #define __SBR_E_NF_H__ #ifdef __cplusplus extern "C" { #endif void extract_envelope_data(sbr_info *sbr, uint8_t ch); void extract_noise_floor_data(sbr_info *sbr, uint8_t ch); #ifndef FIXED_POINT void envelope_noise_dequantisation(sbr_info *sbr, uint8_t ch); void unmap_envelope_noise(sbr_info *sbr); #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_hfadj.c0000644000175000017500000024763714647725152016017 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_hfadj.c,v 1.23 2008/09/19 22:50:20 menno Exp $ **/ /* High Frequency adjustment */ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include "sbr_syntax.h" #include "sbr_hfadj.h" #include "sbr_noise.h" /* static function declarations */ static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch); #ifdef SBR_LOW_POWER static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); #endif static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); uint8_t hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64] #ifdef SBR_LOW_POWER ,real_t *deg /* aliasing degree */ #endif ,uint8_t ch) { ALIGN sbr_hfadj_info adj = SBR_HFADJ_INFO_INIT; uint8_t ret = 0; if (sbr->bs_frame_class[ch] == FIXFIX) { sbr->l_A[ch] = -1; } else if (sbr->bs_frame_class[ch] == VARFIX) { if (sbr->bs_pointer[ch] > 1) sbr->l_A[ch] = sbr->bs_pointer[ch] - 1; else sbr->l_A[ch] = -1; } else { if (sbr->bs_pointer[ch] == 0) sbr->l_A[ch] = -1; else sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch]; } ret = estimate_current_envelope(sbr, &adj, Xsbr, ch); if (ret > 0) return 1; calculate_gain(sbr, &adj, ch); #ifdef SBR_LOW_POWER calc_gain_groups(sbr, &adj, deg, ch); aliasing_reduction(sbr, &adj, deg, ch); #endif hf_assembly(sbr, &adj, Xsbr, ch); return 0; } static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band) { if (sbr->f[ch][l] == HI_RES) { /* in case of using f_table_high we just have 1 to 1 mapping * from bs_add_harmonic[l][k] */ if ((l >= sbr->l_A[ch]) || (sbr->bs_add_harmonic_prev[ch][current_band] && sbr->bs_add_harmonic_flag_prev[ch])) { return sbr->bs_add_harmonic[ch][current_band]; } } else { uint8_t b, lb, ub; /* in case of f_table_low we check if any of the HI_RES bands * within this LO_RES band has bs_add_harmonic[l][k] turned on * (note that borders in the LO_RES table are also present in * the HI_RES table) */ /* find first HI_RES band in current LO_RES band */ lb = 2*current_band - ((sbr->N_high & 1) ? 1 : 0); /* find first HI_RES band in next LO_RES band */ ub = 2*(current_band+1) - ((sbr->N_high & 1) ? 1 : 0); /* check all HI_RES bands in current LO_RES band for sinusoid */ for (b = lb; b < ub; b++) { if ((l >= sbr->l_A[ch]) || (sbr->bs_add_harmonic_prev[ch][b] && sbr->bs_add_harmonic_flag_prev[ch])) { if (sbr->bs_add_harmonic[ch][b] == 1) return 1; } } } return 0; } static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) { uint8_t m, l, j, k, k_l, k_h, p; real_t nrg, div; (void)adj; /* why is this unused? */ if (sbr->bs_interpol_freq == 1) { for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t i, l_i, u_i; l_i = sbr->t_E[ch][l]; u_i = sbr->t_E[ch][l+1]; div = (real_t)(u_i - l_i); if (div == 0) div = 1; for (m = 0; m < sbr->M; m++) { nrg = 0; for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) { #ifdef FIXED_POINT #ifdef SBR_LOW_POWER nrg += ((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS); #else nrg += ((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS) + ((QMF_IM(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_IM(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS); #endif #else nrg += MUL_R(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx])) #ifndef SBR_LOW_POWER + MUL_R(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx])) #endif ; #endif } sbr->E_curr[ch][m][l] = nrg / div; #ifdef SBR_LOW_POWER #ifdef FIXED_POINT sbr->E_curr[ch][m][l] <<= 1; #else sbr->E_curr[ch][m][l] *= 2; #endif #endif } } } else { for (l = 0; l < sbr->L_E[ch]; l++) { for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) { k_l = sbr->f_table_res[sbr->f[ch][l]][p]; k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; for (k = k_l; k < k_h; k++) { uint8_t i, l_i, u_i; nrg = 0; l_i = sbr->t_E[ch][l]; u_i = sbr->t_E[ch][l+1]; div = (real_t)((u_i - l_i)*(k_h - k_l)); if (div == 0) div = 1; for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) { for (j = k_l; j < k_h; j++) { #ifdef FIXED_POINT #ifdef SBR_LOW_POWER nrg += ((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS); #else nrg += ((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS) + ((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS); #endif #else nrg += MUL_R(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j])) #ifndef SBR_LOW_POWER + MUL_R(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j])) #endif ; #endif } } sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; #ifdef SBR_LOW_POWER #ifdef FIXED_POINT sbr->E_curr[ch][k - sbr->kx][l] <<= 1; #else sbr->E_curr[ch][k - sbr->kx][l] *= 2; #endif #endif } } } } return 0; } #ifdef FIXED_POINT #define EPS (1) /* smallest number available in fixed point */ #else #define EPS (1e-12) #endif #ifdef FIXED_POINT /* log2 values of [0..63] */ static const real_t log2_int_tab[] = { LOG2_MIN_INF, REAL_CONST(0.000000000000000), REAL_CONST(1.000000000000000), REAL_CONST(1.584962500721156), REAL_CONST(2.000000000000000), REAL_CONST(2.321928094887362), REAL_CONST(2.584962500721156), REAL_CONST(2.807354922057604), REAL_CONST(3.000000000000000), REAL_CONST(3.169925001442313), REAL_CONST(3.321928094887363), REAL_CONST(3.459431618637297), REAL_CONST(3.584962500721156), REAL_CONST(3.700439718141092), REAL_CONST(3.807354922057604), REAL_CONST(3.906890595608519), REAL_CONST(4.000000000000000), REAL_CONST(4.087462841250339), REAL_CONST(4.169925001442312), REAL_CONST(4.247927513443585), REAL_CONST(4.321928094887362), REAL_CONST(4.392317422778761), REAL_CONST(4.459431618637297), REAL_CONST(4.523561956057013), REAL_CONST(4.584962500721156), REAL_CONST(4.643856189774724), REAL_CONST(4.700439718141093), REAL_CONST(4.754887502163468), REAL_CONST(4.807354922057604), REAL_CONST(4.857980995127572), REAL_CONST(4.906890595608519), REAL_CONST(4.954196310386875), REAL_CONST(5.000000000000000), REAL_CONST(5.044394119358453), REAL_CONST(5.087462841250340), REAL_CONST(5.129283016944966), REAL_CONST(5.169925001442312), REAL_CONST(5.209453365628949), REAL_CONST(5.247927513443585), REAL_CONST(5.285402218862248), REAL_CONST(5.321928094887363), REAL_CONST(5.357552004618084), REAL_CONST(5.392317422778761), REAL_CONST(5.426264754702098), REAL_CONST(5.459431618637297), REAL_CONST(5.491853096329675), REAL_CONST(5.523561956057013), REAL_CONST(5.554588851677637), REAL_CONST(5.584962500721156), REAL_CONST(5.614709844115208), REAL_CONST(5.643856189774724), REAL_CONST(5.672425341971495), REAL_CONST(5.700439718141093), REAL_CONST(5.727920454563200), REAL_CONST(5.754887502163469), REAL_CONST(5.781359713524660), REAL_CONST(5.807354922057605), REAL_CONST(5.832890014164742), REAL_CONST(5.857980995127572), REAL_CONST(5.882643049361842), REAL_CONST(5.906890595608518), REAL_CONST(5.930737337562887), REAL_CONST(5.954196310386876), REAL_CONST(5.977279923499916) }; static const real_t pan_log2_tab[] = { REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453), REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667) }; static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) { /* check for coupled energy/noise data */ if (sbr->bs_coupling == 1) { uint8_t amp0 = (sbr->amp_res[0]) ? 0 : 1; uint8_t amp1 = (sbr->amp_res[1]) ? 0 : 1; real_t tmp = (7 << REAL_BITS) + (sbr->E[0][k][l] << (REAL_BITS-amp0)); real_t pan; /* E[1] should always be even so shifting is OK */ uint8_t E = sbr->E[1][k][l] >> amp1; if (ch == 0) { if (E > 12) { /* negative */ pan = pan_log2_tab[-12 + E]; } else { /* positive */ pan = pan_log2_tab[12 - E] + ((12 - E)<amp_res[ch]) ? 0 : 1; return (6 << REAL_BITS) + (sbr->E[ch][k][l] << (REAL_BITS-amp)); } } static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) { /* check for coupled energy/noise data */ if (sbr->bs_coupling == 1) { real_t tmp = (7 << REAL_BITS) - (sbr->Q[0][k][l] << REAL_BITS); real_t pan; uint8_t Q = sbr->Q[1][k][l]; if (ch == 0) { if (Q > 12) { /* negative */ pan = pan_log2_tab[-12 + Q]; } else { /* positive */ pan = pan_log2_tab[12 - Q] + ((12 - Q)<Q[ch][k][l] << REAL_BITS); } } static const real_t log_Qplus1_pan[31][13] = { { REAL_CONST(0.044383447617292), REAL_CONST(0.169768601655960), REAL_CONST(0.583090126514435), REAL_CONST(1.570089221000671), REAL_CONST(3.092446088790894), REAL_CONST(4.733354568481445), REAL_CONST(6.022367954254150), REAL_CONST(6.692092418670654), REAL_CONST(6.924463272094727), REAL_CONST(6.989034175872803), REAL_CONST(7.005646705627441), REAL_CONST(7.009829998016357), REAL_CONST(7.010877609252930) }, { REAL_CONST(0.022362394258380), REAL_CONST(0.087379962205887), REAL_CONST(0.320804953575134), REAL_CONST(0.988859415054321), REAL_CONST(2.252387046813965), REAL_CONST(3.786596298217773), REAL_CONST(5.044394016265869), REAL_CONST(5.705977916717529), REAL_CONST(5.936291694641113), REAL_CONST(6.000346660614014), REAL_CONST(6.016829967498779), REAL_CONST(6.020981311798096), REAL_CONST(6.022020816802979) }, { REAL_CONST(0.011224525049329), REAL_CONST(0.044351425021887), REAL_CONST(0.169301137328148), REAL_CONST(0.577544987201691), REAL_CONST(1.527246952056885), REAL_CONST(2.887525320053101), REAL_CONST(4.087462902069092), REAL_CONST(4.733354568481445), REAL_CONST(4.959661006927490), REAL_CONST(5.022709369659424), REAL_CONST(5.038940429687500), REAL_CONST(5.043028831481934), REAL_CONST(5.044052600860596) }, { REAL_CONST(0.005623178556561), REAL_CONST(0.022346137091517), REAL_CONST(0.087132595479488), REAL_CONST(0.317482173442841), REAL_CONST(0.956931233406067), REAL_CONST(2.070389270782471), REAL_CONST(3.169924974441528), REAL_CONST(3.786596298217773), REAL_CONST(4.005294322967529), REAL_CONST(4.066420555114746), REAL_CONST(4.082170009613037), REAL_CONST(4.086137294769287), REAL_CONST(4.087131500244141) }, { REAL_CONST(0.002814328996465), REAL_CONST(0.011216334067285), REAL_CONST(0.044224001467228), REAL_CONST(0.167456731200218), REAL_CONST(0.556393325328827), REAL_CONST(1.378511548042297), REAL_CONST(2.321928024291992), REAL_CONST(2.887525320053101), REAL_CONST(3.092446088790894), REAL_CONST(3.150059700012207), REAL_CONST(3.164926528930664), REAL_CONST(3.168673276901245), REAL_CONST(3.169611930847168) }, { REAL_CONST(0.001407850766554), REAL_CONST(0.005619067233056), REAL_CONST(0.022281449288130), REAL_CONST(0.086156636476517), REAL_CONST(0.304854571819305), REAL_CONST(0.847996890544891), REAL_CONST(1.584962487220764), REAL_CONST(2.070389270782471), REAL_CONST(2.252387046813965), REAL_CONST(2.304061651229858), REAL_CONST(2.317430257797241), REAL_CONST(2.320801734924316), REAL_CONST(2.321646213531494) }, { REAL_CONST(0.000704097095877), REAL_CONST(0.002812269143760), REAL_CONST(0.011183738708496), REAL_CONST(0.043721374124289), REAL_CONST(0.160464659333229), REAL_CONST(0.485426813364029), REAL_CONST(1.000000000000000), REAL_CONST(1.378511548042297), REAL_CONST(1.527246952056885), REAL_CONST(1.570089221000671), REAL_CONST(1.581215262413025), REAL_CONST(1.584023833274841), REAL_CONST(1.584727644920349) }, { REAL_CONST(0.000352177477907), REAL_CONST(0.001406819908880), REAL_CONST(0.005602621007711), REAL_CONST(0.022026389837265), REAL_CONST(0.082462236285210), REAL_CONST(0.263034462928772), REAL_CONST(0.584962487220764), REAL_CONST(0.847996890544891), REAL_CONST(0.956931233406067), REAL_CONST(0.988859415054321), REAL_CONST(0.997190535068512), REAL_CONST(0.999296069145203), REAL_CONST(0.999823868274689) }, { REAL_CONST(0.000176099492819), REAL_CONST(0.000703581434209), REAL_CONST(0.002804030198604), REAL_CONST(0.011055230163038), REAL_CONST(0.041820213198662), REAL_CONST(0.137503549456596), REAL_CONST(0.321928083896637), REAL_CONST(0.485426813364029), REAL_CONST(0.556393325328827), REAL_CONST(0.577544987201691), REAL_CONST(0.583090126514435), REAL_CONST(0.584493279457092), REAL_CONST(0.584845066070557) }, { REAL_CONST(0.000088052431238), REAL_CONST(0.000351833587047), REAL_CONST(0.001402696361765), REAL_CONST(0.005538204684854), REAL_CONST(0.021061634644866), REAL_CONST(0.070389263331890), REAL_CONST(0.169925004243851), REAL_CONST(0.263034462928772), REAL_CONST(0.304854571819305), REAL_CONST(0.317482173442841), REAL_CONST(0.320804953575134), REAL_CONST(0.321646571159363), REAL_CONST(0.321857661008835) }, { REAL_CONST(0.000044026888645), REAL_CONST(0.000175927518285), REAL_CONST(0.000701518612914), REAL_CONST(0.002771759871393), REAL_CONST(0.010569252073765), REAL_CONST(0.035623874515295), REAL_CONST(0.087462842464447), REAL_CONST(0.137503549456596), REAL_CONST(0.160464659333229), REAL_CONST(0.167456731200218), REAL_CONST(0.169301137328148), REAL_CONST(0.169768601655960), REAL_CONST(0.169885858893394) }, { REAL_CONST(0.000022013611670), REAL_CONST(0.000088052431238), REAL_CONST(0.000350801943569), REAL_CONST(0.001386545598507), REAL_CONST(0.005294219125062), REAL_CONST(0.017921976745129), REAL_CONST(0.044394120573997), REAL_CONST(0.070389263331890), REAL_CONST(0.082462236285210), REAL_CONST(0.086156636476517), REAL_CONST(0.087132595479488), REAL_CONST(0.087379962205887), REAL_CONST(0.087442122399807) }, { REAL_CONST(0.000011006847672), REAL_CONST(0.000044026888645), REAL_CONST(0.000175411638338), REAL_CONST(0.000693439331371), REAL_CONST(0.002649537986144), REAL_CONST(0.008988817222416), REAL_CONST(0.022367812693119), REAL_CONST(0.035623874515295), REAL_CONST(0.041820213198662), REAL_CONST(0.043721374124289), REAL_CONST(0.044224001467228), REAL_CONST(0.044351425021887), REAL_CONST(0.044383447617292) }, { REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000087708482170), REAL_CONST(0.000346675369656), REAL_CONST(0.001325377263129), REAL_CONST(0.004501323681325), REAL_CONST(0.011227255687118), REAL_CONST(0.017921976745129), REAL_CONST(0.021061634644866), REAL_CONST(0.022026389837265), REAL_CONST(0.022281449288130), REAL_CONST(0.022346137091517), REAL_CONST(0.022362394258380) }, { REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043854910473), REAL_CONST(0.000173348103999), REAL_CONST(0.000662840844598), REAL_CONST(0.002252417383716), REAL_CONST(0.005624548997730), REAL_CONST(0.008988817222416), REAL_CONST(0.010569252073765), REAL_CONST(0.011055230163038), REAL_CONST(0.011183738708496), REAL_CONST(0.011216334067285), REAL_CONST(0.011224525049329) }, { REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000086676649516), REAL_CONST(0.000331544462824), REAL_CONST(0.001126734190620), REAL_CONST(0.002815015614033), REAL_CONST(0.004501323681325), REAL_CONST(0.005294219125062), REAL_CONST(0.005538204684854), REAL_CONST(0.005602621007711), REAL_CONST(0.005619067233056), REAL_CONST(0.005623178556561) }, { REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043338975956), REAL_CONST(0.000165781748365), REAL_CONST(0.000563477107789), REAL_CONST(0.001408194424585), REAL_CONST(0.002252417383716), REAL_CONST(0.002649537986144), REAL_CONST(0.002771759871393), REAL_CONST(0.002804030198604), REAL_CONST(0.002812269143760), REAL_CONST(0.002814328996465) }, { REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000021669651687), REAL_CONST(0.000082893253420), REAL_CONST(0.000281680084299), REAL_CONST(0.000704268983100), REAL_CONST(0.001126734190620), REAL_CONST(0.001325377263129), REAL_CONST(0.001386545598507), REAL_CONST(0.001402696361765), REAL_CONST(0.001406819908880), REAL_CONST(0.001407850766554) }, { REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010834866771), REAL_CONST(0.000041447223339), REAL_CONST(0.000140846910654), REAL_CONST(0.000352177477907), REAL_CONST(0.000563477107789), REAL_CONST(0.000662840844598), REAL_CONST(0.000693439331371), REAL_CONST(0.000701518612914), REAL_CONST(0.000703581434209), REAL_CONST(0.000704097095877) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000020637769921), REAL_CONST(0.000070511166996), REAL_CONST(0.000176099492819), REAL_CONST(0.000281680084299), REAL_CONST(0.000331544462824), REAL_CONST(0.000346675369656), REAL_CONST(0.000350801943569), REAL_CONST(0.000351833587047), REAL_CONST(0.000352177477907) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010318922250), REAL_CONST(0.000035256012779), REAL_CONST(0.000088052431238), REAL_CONST(0.000140846910654), REAL_CONST(0.000165781748365), REAL_CONST(0.000173348103999), REAL_CONST(0.000175411638338), REAL_CONST(0.000175927518285), REAL_CONST(0.000176099492819) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005159470220), REAL_CONST(0.000017542124624), REAL_CONST(0.000044026888645), REAL_CONST(0.000070511166996), REAL_CONST(0.000082893253420), REAL_CONST(0.000086676649516), REAL_CONST(0.000087708482170), REAL_CONST(0.000088052431238), REAL_CONST(0.000088052431238) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002579737384), REAL_CONST(0.000008771088687), REAL_CONST(0.000022013611670), REAL_CONST(0.000035256012779), REAL_CONST(0.000041447223339), REAL_CONST(0.000043338975956), REAL_CONST(0.000043854910473), REAL_CONST(0.000044026888645), REAL_CONST(0.000044026888645) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000004471542070), REAL_CONST(0.000011006847672), REAL_CONST(0.000017542124624), REAL_CONST(0.000020637769921), REAL_CONST(0.000021669651687), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002235772627), REAL_CONST(0.000005503434295), REAL_CONST(0.000008771088687), REAL_CONST(0.000010318922250), REAL_CONST(0.000010834866771), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001031895522), REAL_CONST(0.000002751719876), REAL_CONST(0.000004471542070), REAL_CONST(0.000005159470220), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000515947875), REAL_CONST(0.000001375860506), REAL_CONST(0.000002235772627), REAL_CONST(0.000002579737384), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000000687930424), REAL_CONST(0.000001031895522), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000515947875), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634) } }; static const real_t log_Qplus1[31] = { REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339), REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156), REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453), REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667), REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551), REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641), REAL_CONST(0.000000000000000) }; static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) { /* check for coupled energy/noise data */ if (sbr->bs_coupling == 1) { if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) && (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24)) { if (ch == 0) { return log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]; } else { return log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]; } } else { return 0; } } else { if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30) { return log_Qplus1[sbr->Q[ch][k][l]]; } else { return 0; } } } static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) { /* log2 values of limiter gains */ static const real_t limGain[] = { REAL_CONST(-1.0), REAL_CONST(0.0), REAL_CONST(1.0), REAL_CONST(33.219) }; uint8_t m, l, k; uint8_t current_t_noise_band = 0; uint8_t S_mapped; ALIGN real_t Q_M_lim[MAX_M]; ALIGN real_t G_lim[MAX_M]; ALIGN real_t G_boost; ALIGN real_t S_M[MAX_M]; for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t current_f_noise_band = 0; uint8_t current_res_band = 0; uint8_t current_res_band2 = 0; uint8_t current_hi_res_band = 0; real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) { current_t_noise_band++; } for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) { real_t Q_M = 0; real_t G_max; real_t den = 0; real_t acc1 = 0; real_t acc2 = 0; uint8_t current_res_band_size = 0; uint8_t Q_M_size = 0; uint8_t ml1, ml2; /* bounds of current limiter bands */ ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; /* calculate the accumulated E_orig and E_curr over the limiter band */ for (m = ml1; m < ml2; m++) { if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) { current_res_band_size++; } else { acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)); current_res_band++; current_res_band_size = 1; } acc2 += sbr->E_curr[ch][m][l]; } acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)); if (acc1 == 0) acc1 = LOG2_MIN_INF; else acc1 = log2_int(acc1); /* calculate the maximum gain */ /* ratio of the energy of the original signal and the energy * of the HF generated signal */ G_max = acc1 - log2_int(acc2) + limGain[sbr->bs_limiter_gains]; G_max = min(G_max, limGain[3]); for (m = ml1; m < ml2; m++) { real_t G; real_t E_curr, E_orig; real_t Q_orig, Q_orig_plus1; uint8_t S_index_mapped; /* check if m is on a noise band border */ if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) { /* step to next noise band */ current_f_noise_band++; } /* check if m is on a resolution band border */ if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) { /* accumulate a whole range of equal Q_Ms */ if (Q_M_size > 0) den += pow2_int(log2_int_tab[Q_M_size] + Q_M); Q_M_size = 0; /* step to next resolution band */ current_res_band2++; /* if we move to a new resolution band, we should check if we are * going to add a sinusoid in this band */ S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); } /* check if m is on a HI_RES band border */ if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) { /* step to next HI_RES band */ current_hi_res_band++; } /* find S_index_mapped * S_index_mapped can only be 1 for the m in the middle of the * current HI_RES band */ S_index_mapped = 0; if ((l >= sbr->l_A[ch]) || (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) { /* find the middle subband of the HI_RES frequency band */ if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; } /* find bitstream parameters */ if (sbr->E_curr[ch][m][l] == 0) E_curr = LOG2_MIN_INF; else E_curr = log2_int(sbr->E_curr[ch][m][l]); E_orig = -REAL_CONST(10) + find_log2_E(sbr, current_res_band2, l, ch); Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch); Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch); /* Q_M only depends on E_orig and Q_div2: * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on * a change of current res band (HI or LO) */ Q_M = E_orig + Q_orig - Q_orig_plus1; /* S_M only depends on E_orig, Q_div and S_index_mapped: * S_index_mapped can only be non-zero once per HI_RES band */ if (S_index_mapped == 0) { S_M[m] = LOG2_MIN_INF; /* -inf */ } else { S_M[m] = E_orig - Q_orig_plus1; /* accumulate sinusoid part of the total energy */ den += pow2_int(S_M[m]); } /* calculate gain */ /* ratio of the energy of the original signal and the energy * of the HF generated signal */ /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */ /* scaled by -10 */ G = E_orig - max(-REAL_CONST(10), E_curr); if ((S_mapped == 0) && (delta == 1)) { /* G = G * 1/(1+Q) */ G -= Q_orig_plus1; } else if (S_mapped == 1) { /* G = G * Q/(1+Q) */ G += Q_orig - Q_orig_plus1; } /* limit the additional noise energy level */ /* and apply the limiter */ if (G_max > G) { Q_M_lim[m] = Q_M; G_lim[m] = G; if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) { Q_M_size++; } } else { /* G > G_max */ Q_M_lim[m] = Q_M + G_max - G; G_lim[m] = G_max; /* accumulate limited Q_M */ if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) { den += pow2_int(Q_M_lim[m]); } } /* accumulate the total energy */ /* E_curr changes for every m so we do need to accumulate every m */ den += pow2_int(E_curr + G_lim[m]); } /* accumulate last range of equal Q_Ms */ if (Q_M_size > 0) { den += pow2_int(log2_int_tab[Q_M_size] + Q_M); } /* calculate the final gain */ /* G_boost: [0..2.51188643] */ G_boost = acc1 - log2_int(den /*+ EPS*/); G_boost = min(G_boost, REAL_CONST(1.328771237) /* log2(1.584893192 ^ 2) */); for (m = ml1; m < ml2; m++) { /* apply compensation to gain, noise floor sf's and sinusoid levels */ #ifndef SBR_LOW_POWER adj->G_lim_boost[l][m] = pow2_fix((G_lim[m] + G_boost) >> 1); #else /* sqrt() will be done after the aliasing reduction to save a * few multiplies */ adj->G_lim_boost[l][m] = pow2_fix(G_lim[m] + G_boost); #endif adj->Q_M_lim_boost[l][m] = pow2_fix((Q_M_lim[m] + G_boost) >> 1); if (S_M[m] != LOG2_MIN_INF) { adj->S_M_boost[l][m] = pow2_int((S_M[m] + G_boost) >> 1); } else { adj->S_M_boost[l][m] = 0; } } } } } #else //#define LOG2_TEST #ifdef LOG2_TEST #define LOG2_MIN_INF -100000 __inline float pow2(float val) { return pow(2.0, val); } __inline float log2(float val) { return log(val)/log(2.0); } #define RB 14 float QUANTISE2REAL(float val) { __int32 ival = (__int32)(val * (1<bs_coupling == 1) { real_t amp0 = (sbr->amp_res[0]) ? 1.0 : 0.5; real_t amp1 = (sbr->amp_res[1]) ? 1.0 : 0.5; float tmp = QUANTISE2REAL(7.0 + (real_t)sbr->E[0][k][l] * amp0); float pan; int E = (int)(sbr->E[1][k][l] * amp1); if (ch == 0) { if (E > 12) { /* negative */ pan = QUANTISE2REAL(pan_log2_tab[-12 + E]); } else { /* positive */ pan = QUANTISE2REAL(pan_log2_tab[12 - E] + (12 - E)); } } else { if (E < 12) { /* negative */ pan = QUANTISE2REAL(pan_log2_tab[-E + 12]); } else { /* positive */ pan = QUANTISE2REAL(pan_log2_tab[E - 12] + (E - 12)); } } /* tmp / pan in log2 */ return QUANTISE2REAL(tmp - pan); } else { real_t amp = (sbr->amp_res[ch]) ? 1.0 : 0.5; return QUANTISE2REAL(6.0 + (real_t)sbr->E[ch][k][l] * amp); } } static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) { /* check for coupled energy/noise data */ if (sbr->bs_coupling == 1) { float tmp = QUANTISE2REAL(7.0 - (real_t)sbr->Q[0][k][l]); float pan; int Q = (int)(sbr->Q[1][k][l]); if (ch == 0) { if (Q > 12) { /* negative */ pan = QUANTISE2REAL(pan_log2_tab[-12 + Q]); } else { /* positive */ pan = QUANTISE2REAL(pan_log2_tab[12 - Q] + (12 - Q)); } } else { if (Q < 12) { /* negative */ pan = QUANTISE2REAL(pan_log2_tab[-Q + 12]); } else { /* positive */ pan = QUANTISE2REAL(pan_log2_tab[Q - 12] + (Q - 12)); } } /* tmp / pan in log2 */ return QUANTISE2REAL(tmp - pan); } else { return QUANTISE2REAL(6.0 - (real_t)sbr->Q[ch][k][l]); } } static const real_t log_Qplus1_pan[31][13] = { { REAL_CONST(0.044383447617292), REAL_CONST(0.169768601655960), REAL_CONST(0.583090126514435), REAL_CONST(1.570089221000671), REAL_CONST(3.092446088790894), REAL_CONST(4.733354568481445), REAL_CONST(6.022367954254150), REAL_CONST(6.692092418670654), REAL_CONST(6.924463272094727), REAL_CONST(6.989034175872803), REAL_CONST(7.005646705627441), REAL_CONST(7.009829998016357), REAL_CONST(7.010877609252930) }, { REAL_CONST(0.022362394258380), REAL_CONST(0.087379962205887), REAL_CONST(0.320804953575134), REAL_CONST(0.988859415054321), REAL_CONST(2.252387046813965), REAL_CONST(3.786596298217773), REAL_CONST(5.044394016265869), REAL_CONST(5.705977916717529), REAL_CONST(5.936291694641113), REAL_CONST(6.000346660614014), REAL_CONST(6.016829967498779), REAL_CONST(6.020981311798096), REAL_CONST(6.022020816802979) }, { REAL_CONST(0.011224525049329), REAL_CONST(0.044351425021887), REAL_CONST(0.169301137328148), REAL_CONST(0.577544987201691), REAL_CONST(1.527246952056885), REAL_CONST(2.887525320053101), REAL_CONST(4.087462902069092), REAL_CONST(4.733354568481445), REAL_CONST(4.959661006927490), REAL_CONST(5.022709369659424), REAL_CONST(5.038940429687500), REAL_CONST(5.043028831481934), REAL_CONST(5.044052600860596) }, { REAL_CONST(0.005623178556561), REAL_CONST(0.022346137091517), REAL_CONST(0.087132595479488), REAL_CONST(0.317482173442841), REAL_CONST(0.956931233406067), REAL_CONST(2.070389270782471), REAL_CONST(3.169924974441528), REAL_CONST(3.786596298217773), REAL_CONST(4.005294322967529), REAL_CONST(4.066420555114746), REAL_CONST(4.082170009613037), REAL_CONST(4.086137294769287), REAL_CONST(4.087131500244141) }, { REAL_CONST(0.002814328996465), REAL_CONST(0.011216334067285), REAL_CONST(0.044224001467228), REAL_CONST(0.167456731200218), REAL_CONST(0.556393325328827), REAL_CONST(1.378511548042297), REAL_CONST(2.321928024291992), REAL_CONST(2.887525320053101), REAL_CONST(3.092446088790894), REAL_CONST(3.150059700012207), REAL_CONST(3.164926528930664), REAL_CONST(3.168673276901245), REAL_CONST(3.169611930847168) }, { REAL_CONST(0.001407850766554), REAL_CONST(0.005619067233056), REAL_CONST(0.022281449288130), REAL_CONST(0.086156636476517), REAL_CONST(0.304854571819305), REAL_CONST(0.847996890544891), REAL_CONST(1.584962487220764), REAL_CONST(2.070389270782471), REAL_CONST(2.252387046813965), REAL_CONST(2.304061651229858), REAL_CONST(2.317430257797241), REAL_CONST(2.320801734924316), REAL_CONST(2.321646213531494) }, { REAL_CONST(0.000704097095877), REAL_CONST(0.002812269143760), REAL_CONST(0.011183738708496), REAL_CONST(0.043721374124289), REAL_CONST(0.160464659333229), REAL_CONST(0.485426813364029), REAL_CONST(1.000000000000000), REAL_CONST(1.378511548042297), REAL_CONST(1.527246952056885), REAL_CONST(1.570089221000671), REAL_CONST(1.581215262413025), REAL_CONST(1.584023833274841), REAL_CONST(1.584727644920349) }, { REAL_CONST(0.000352177477907), REAL_CONST(0.001406819908880), REAL_CONST(0.005602621007711), REAL_CONST(0.022026389837265), REAL_CONST(0.082462236285210), REAL_CONST(0.263034462928772), REAL_CONST(0.584962487220764), REAL_CONST(0.847996890544891), REAL_CONST(0.956931233406067), REAL_CONST(0.988859415054321), REAL_CONST(0.997190535068512), REAL_CONST(0.999296069145203), REAL_CONST(0.999823868274689) }, { REAL_CONST(0.000176099492819), REAL_CONST(0.000703581434209), REAL_CONST(0.002804030198604), REAL_CONST(0.011055230163038), REAL_CONST(0.041820213198662), REAL_CONST(0.137503549456596), REAL_CONST(0.321928083896637), REAL_CONST(0.485426813364029), REAL_CONST(0.556393325328827), REAL_CONST(0.577544987201691), REAL_CONST(0.583090126514435), REAL_CONST(0.584493279457092), REAL_CONST(0.584845066070557) }, { REAL_CONST(0.000088052431238), REAL_CONST(0.000351833587047), REAL_CONST(0.001402696361765), REAL_CONST(0.005538204684854), REAL_CONST(0.021061634644866), REAL_CONST(0.070389263331890), REAL_CONST(0.169925004243851), REAL_CONST(0.263034462928772), REAL_CONST(0.304854571819305), REAL_CONST(0.317482173442841), REAL_CONST(0.320804953575134), REAL_CONST(0.321646571159363), REAL_CONST(0.321857661008835) }, { REAL_CONST(0.000044026888645), REAL_CONST(0.000175927518285), REAL_CONST(0.000701518612914), REAL_CONST(0.002771759871393), REAL_CONST(0.010569252073765), REAL_CONST(0.035623874515295), REAL_CONST(0.087462842464447), REAL_CONST(0.137503549456596), REAL_CONST(0.160464659333229), REAL_CONST(0.167456731200218), REAL_CONST(0.169301137328148), REAL_CONST(0.169768601655960), REAL_CONST(0.169885858893394) }, { REAL_CONST(0.000022013611670), REAL_CONST(0.000088052431238), REAL_CONST(0.000350801943569), REAL_CONST(0.001386545598507), REAL_CONST(0.005294219125062), REAL_CONST(0.017921976745129), REAL_CONST(0.044394120573997), REAL_CONST(0.070389263331890), REAL_CONST(0.082462236285210), REAL_CONST(0.086156636476517), REAL_CONST(0.087132595479488), REAL_CONST(0.087379962205887), REAL_CONST(0.087442122399807) }, { REAL_CONST(0.000011006847672), REAL_CONST(0.000044026888645), REAL_CONST(0.000175411638338), REAL_CONST(0.000693439331371), REAL_CONST(0.002649537986144), REAL_CONST(0.008988817222416), REAL_CONST(0.022367812693119), REAL_CONST(0.035623874515295), REAL_CONST(0.041820213198662), REAL_CONST(0.043721374124289), REAL_CONST(0.044224001467228), REAL_CONST(0.044351425021887), REAL_CONST(0.044383447617292) }, { REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000087708482170), REAL_CONST(0.000346675369656), REAL_CONST(0.001325377263129), REAL_CONST(0.004501323681325), REAL_CONST(0.011227255687118), REAL_CONST(0.017921976745129), REAL_CONST(0.021061634644866), REAL_CONST(0.022026389837265), REAL_CONST(0.022281449288130), REAL_CONST(0.022346137091517), REAL_CONST(0.022362394258380) }, { REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043854910473), REAL_CONST(0.000173348103999), REAL_CONST(0.000662840844598), REAL_CONST(0.002252417383716), REAL_CONST(0.005624548997730), REAL_CONST(0.008988817222416), REAL_CONST(0.010569252073765), REAL_CONST(0.011055230163038), REAL_CONST(0.011183738708496), REAL_CONST(0.011216334067285), REAL_CONST(0.011224525049329) }, { REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000086676649516), REAL_CONST(0.000331544462824), REAL_CONST(0.001126734190620), REAL_CONST(0.002815015614033), REAL_CONST(0.004501323681325), REAL_CONST(0.005294219125062), REAL_CONST(0.005538204684854), REAL_CONST(0.005602621007711), REAL_CONST(0.005619067233056), REAL_CONST(0.005623178556561) }, { REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043338975956), REAL_CONST(0.000165781748365), REAL_CONST(0.000563477107789), REAL_CONST(0.001408194424585), REAL_CONST(0.002252417383716), REAL_CONST(0.002649537986144), REAL_CONST(0.002771759871393), REAL_CONST(0.002804030198604), REAL_CONST(0.002812269143760), REAL_CONST(0.002814328996465) }, { REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000021669651687), REAL_CONST(0.000082893253420), REAL_CONST(0.000281680084299), REAL_CONST(0.000704268983100), REAL_CONST(0.001126734190620), REAL_CONST(0.001325377263129), REAL_CONST(0.001386545598507), REAL_CONST(0.001402696361765), REAL_CONST(0.001406819908880), REAL_CONST(0.001407850766554) }, { REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010834866771), REAL_CONST(0.000041447223339), REAL_CONST(0.000140846910654), REAL_CONST(0.000352177477907), REAL_CONST(0.000563477107789), REAL_CONST(0.000662840844598), REAL_CONST(0.000693439331371), REAL_CONST(0.000701518612914), REAL_CONST(0.000703581434209), REAL_CONST(0.000704097095877) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000020637769921), REAL_CONST(0.000070511166996), REAL_CONST(0.000176099492819), REAL_CONST(0.000281680084299), REAL_CONST(0.000331544462824), REAL_CONST(0.000346675369656), REAL_CONST(0.000350801943569), REAL_CONST(0.000351833587047), REAL_CONST(0.000352177477907) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010318922250), REAL_CONST(0.000035256012779), REAL_CONST(0.000088052431238), REAL_CONST(0.000140846910654), REAL_CONST(0.000165781748365), REAL_CONST(0.000173348103999), REAL_CONST(0.000175411638338), REAL_CONST(0.000175927518285), REAL_CONST(0.000176099492819) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005159470220), REAL_CONST(0.000017542124624), REAL_CONST(0.000044026888645), REAL_CONST(0.000070511166996), REAL_CONST(0.000082893253420), REAL_CONST(0.000086676649516), REAL_CONST(0.000087708482170), REAL_CONST(0.000088052431238), REAL_CONST(0.000088052431238) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002579737384), REAL_CONST(0.000008771088687), REAL_CONST(0.000022013611670), REAL_CONST(0.000035256012779), REAL_CONST(0.000041447223339), REAL_CONST(0.000043338975956), REAL_CONST(0.000043854910473), REAL_CONST(0.000044026888645), REAL_CONST(0.000044026888645) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000004471542070), REAL_CONST(0.000011006847672), REAL_CONST(0.000017542124624), REAL_CONST(0.000020637769921), REAL_CONST(0.000021669651687), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002235772627), REAL_CONST(0.000005503434295), REAL_CONST(0.000008771088687), REAL_CONST(0.000010318922250), REAL_CONST(0.000010834866771), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001031895522), REAL_CONST(0.000002751719876), REAL_CONST(0.000004471542070), REAL_CONST(0.000005159470220), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000515947875), REAL_CONST(0.000001375860506), REAL_CONST(0.000002235772627), REAL_CONST(0.000002579737384), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000000687930424), REAL_CONST(0.000001031895522), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000515947875), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269) }, { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634) } }; static const real_t log_Qplus1[31] = { REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339), REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156), REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453), REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667), REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551), REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641), REAL_CONST(0.000000000000000) }; static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) { /* check for coupled energy/noise data */ if (sbr->bs_coupling == 1) { if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) && (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24)) { if (ch == 0) { return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]); } else { return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]); } } else { return 0; } } else { if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30) { return QUANTISE2REAL(log_Qplus1[sbr->Q[ch][k][l]]); } else { return 0; } } } static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) { /* log2 values of limiter gains */ static const real_t limGain[] = { -1.0, 0.0, 1.0, 33.219 }; uint8_t m, l, k; uint8_t current_t_noise_band = 0; uint8_t S_mapped; ALIGN real_t Q_M_lim[MAX_M]; ALIGN real_t G_lim[MAX_M]; ALIGN real_t G_boost; ALIGN real_t S_M[MAX_M]; for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t current_f_noise_band = 0; uint8_t current_res_band = 0; uint8_t current_res_band2 = 0; uint8_t current_hi_res_band = 0; real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) { current_t_noise_band++; } for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) { real_t Q_M = 0; real_t G_max; real_t den = 0; real_t acc1 = 0; real_t acc2 = 0; uint8_t current_res_band_size = 0; uint8_t Q_M_size = 0; uint8_t ml1, ml2; /* bounds of current limiter bands */ ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; /* calculate the accumulated E_orig and E_curr over the limiter band */ for (m = ml1; m < ml2; m++) { if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) { current_res_band_size++; } else { acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch))); current_res_band++; current_res_band_size = 1; } acc2 += QUANTISE2INT(sbr->E_curr[ch][m][l]/1024.0); } acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch))); acc1 = QUANTISE2REAL( log2(EPS + acc1) ); /* calculate the maximum gain */ /* ratio of the energy of the original signal and the energy * of the HF generated signal */ G_max = acc1 - QUANTISE2REAL(log2(EPS + acc2)) + QUANTISE2REAL(limGain[sbr->bs_limiter_gains]); G_max = min(G_max, QUANTISE2REAL(limGain[3])); for (m = ml1; m < ml2; m++) { real_t G; real_t E_curr, E_orig; real_t Q_orig, Q_orig_plus1; uint8_t S_index_mapped; /* check if m is on a noise band border */ if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) { /* step to next noise band */ current_f_noise_band++; } /* check if m is on a resolution band border */ if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) { /* accumulate a whole range of equal Q_Ms */ if (Q_M_size > 0) den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M)); Q_M_size = 0; /* step to next resolution band */ current_res_band2++; /* if we move to a new resolution band, we should check if we are * going to add a sinusoid in this band */ S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); } /* check if m is on a HI_RES band border */ if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) { /* step to next HI_RES band */ current_hi_res_band++; } /* find S_index_mapped * S_index_mapped can only be 1 for the m in the middle of the * current HI_RES band */ S_index_mapped = 0; if ((l >= sbr->l_A[ch]) || (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) { /* find the middle subband of the HI_RES frequency band */ if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; } /* find bitstream parameters */ if (sbr->E_curr[ch][m][l] == 0) E_curr = LOG2_MIN_INF; else E_curr = -10 + log2(sbr->E_curr[ch][m][l]); E_orig = -10 + find_log2_E(sbr, current_res_band2, l, ch); Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch); Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch); /* Q_M only depends on E_orig and Q_div2: * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on * a change of current res band (HI or LO) */ Q_M = E_orig + Q_orig - Q_orig_plus1; /* S_M only depends on E_orig, Q_div and S_index_mapped: * S_index_mapped can only be non-zero once per HI_RES band */ if (S_index_mapped == 0) { S_M[m] = LOG2_MIN_INF; /* -inf */ } else { S_M[m] = E_orig - Q_orig_plus1; /* accumulate sinusoid part of the total energy */ den += pow2(S_M[m]); } /* calculate gain */ /* ratio of the energy of the original signal and the energy * of the HF generated signal */ /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */ /* scaled by -10 */ G = E_orig - max(-10, E_curr); if ((S_mapped == 0) && (delta == 1)) { /* G = G * 1/(1+Q) */ G -= Q_orig_plus1; } else if (S_mapped == 1) { /* G = G * Q/(1+Q) */ G += Q_orig - Q_orig_plus1; } /* limit the additional noise energy level */ /* and apply the limiter */ if (G_max > G) { Q_M_lim[m] = QUANTISE2REAL(Q_M); G_lim[m] = QUANTISE2REAL(G); if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) { Q_M_size++; } } else { /* G > G_max */ Q_M_lim[m] = QUANTISE2REAL(Q_M) + G_max - QUANTISE2REAL(G); G_lim[m] = G_max; /* accumulate limited Q_M */ if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) { den += QUANTISE2INT(pow2(Q_M_lim[m])); } } /* accumulate the total energy */ /* E_curr changes for every m so we do need to accumulate every m */ den += QUANTISE2INT(pow2(E_curr + G_lim[m])); } /* accumulate last range of equal Q_Ms */ if (Q_M_size > 0) { den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M)); } /* calculate the final gain */ /* G_boost: [0..2.51188643] */ G_boost = acc1 - QUANTISE2REAL(log2(den + EPS)); G_boost = min(G_boost, QUANTISE2REAL(1.328771237) /* log2(1.584893192 ^ 2) */); for (m = ml1; m < ml2; m++) { /* apply compensation to gain, noise floor sf's and sinusoid levels */ #ifndef SBR_LOW_POWER adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2((G_lim[m] + G_boost) / 2.0)); #else /* sqrt() will be done after the aliasing reduction to save a * few multiplies */ adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2(G_lim[m] + G_boost)); #endif adj->Q_M_lim_boost[l][m] = QUANTISE2REAL(pow2((Q_M_lim[m] + 10 + G_boost) / 2.0)); if (S_M[m] != LOG2_MIN_INF) { adj->S_M_boost[l][m] = QUANTISE2REAL(pow2((S_M[m] + 10 + G_boost) / 2.0)); } else { adj->S_M_boost[l][m] = 0; } } } } } #else static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) { static const real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 }; uint8_t m, l, k; uint8_t current_t_noise_band = 0; uint8_t S_mapped; ALIGN real_t Q_M_lim[MAX_M]; ALIGN real_t G_lim[MAX_M]; ALIGN real_t G_boost; ALIGN real_t S_M[MAX_M]; for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t current_f_noise_band = 0; uint8_t current_res_band = 0; uint8_t current_res_band2 = 0; uint8_t current_hi_res_band = 0; real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) { current_t_noise_band++; } for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) { real_t G_max; real_t den = 0; real_t acc1 = 0; real_t acc2 = 0; #if 0 uint8_t current_res_band_size = 0; #endif uint8_t ml1, ml2; ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; /* calculate the accumulated E_orig and E_curr over the limiter band */ for (m = ml1; m < ml2; m++) { if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) { current_res_band++; } acc1 += sbr->E_orig[ch][current_res_band][l]; acc2 += sbr->E_curr[ch][m][l]; } /* calculate the maximum gain */ /* ratio of the energy of the original signal and the energy * of the HF generated signal */ G_max = ((EPS + acc1) / (EPS + acc2)) * limGain[sbr->bs_limiter_gains]; G_max = min(G_max, 1e10); for (m = ml1; m < ml2; m++) { real_t Q_M, G; real_t Q_div, Q_div2; uint8_t S_index_mapped; /* check if m is on a noise band border */ if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) { /* step to next noise band */ current_f_noise_band++; } /* check if m is on a resolution band border */ if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) { /* step to next resolution band */ current_res_band2++; /* if we move to a new resolution band, we should check if we are * going to add a sinusoid in this band */ S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); } /* check if m is on a HI_RES band border */ if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) { /* step to next HI_RES band */ current_hi_res_band++; } /* find S_index_mapped * S_index_mapped can only be 1 for the m in the middle of the * current HI_RES band */ S_index_mapped = 0; if ((l >= sbr->l_A[ch]) || (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) { /* find the middle subband of the HI_RES frequency band */ if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; } /* Q_div: [0..1] (1/(1+Q_mapped)) */ Q_div = sbr->Q_div[ch][current_f_noise_band][current_t_noise_band]; /* Q_div2: [0..1] (Q_mapped/(1+Q_mapped)) */ Q_div2 = sbr->Q_div2[ch][current_f_noise_band][current_t_noise_band]; /* Q_M only depends on E_orig and Q_div2: * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on * a change of current noise band */ Q_M = sbr->E_orig[ch][current_res_band2][l] * Q_div2; /* S_M only depends on E_orig, Q_div and S_index_mapped: * S_index_mapped can only be non-zero once per HI_RES band */ if (S_index_mapped == 0) { S_M[m] = 0; } else { S_M[m] = sbr->E_orig[ch][current_res_band2][l] * Q_div; /* accumulate sinusoid part of the total energy */ den += S_M[m]; } /* calculate gain */ /* ratio of the energy of the original signal and the energy * of the HF generated signal */ G = sbr->E_orig[ch][current_res_band2][l] / (1.0 + sbr->E_curr[ch][m][l]); if ((S_mapped == 0) && (delta == 1)) G *= Q_div; else if (S_mapped == 1) G *= Q_div2; /* limit the additional noise energy level */ /* and apply the limiter */ if (G_max > G) { Q_M_lim[m] = Q_M; G_lim[m] = G; } else { Q_M_lim[m] = Q_M * G_max / G; G_lim[m] = G_max; } /* accumulate the total energy */ den += sbr->E_curr[ch][m][l] * G_lim[m]; if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) den += Q_M_lim[m]; } /* G_boost: [0..2.51188643] */ G_boost = (acc1 + EPS) / (den + EPS); G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */); for (m = ml1; m < ml2; m++) { /* apply compensation to gain, noise floor sf's and sinusoid levels */ #ifndef SBR_LOW_POWER adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost); #else /* sqrt() will be done after the aliasing reduction to save a * few multiplies */ adj->G_lim_boost[l][m] = G_lim[m] * G_boost; #endif adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost); if (S_M[m] != 0) { adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost); } else { adj->S_M_boost[l][m] = 0; } } } } } #endif // log2_test #endif #ifdef SBR_LOW_POWER static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) { uint8_t l, k, i; uint8_t grouping; uint8_t S_mapped; for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t current_res_band = 0; i = 0; grouping = 0; S_mapped = get_S_mapped(sbr, ch, l, current_res_band); for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++) { if (k == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) { /* step to next resolution band */ current_res_band++; S_mapped = get_S_mapped(sbr, ch, l, current_res_band); } if (deg[k + 1] && S_mapped == 0) { if (grouping == 0) { sbr->f_group[l][i] = k; grouping = 1; i++; } } else { if (grouping) { if (S_mapped) { sbr->f_group[l][i] = k; } else { sbr->f_group[l][i] = k + 1; } grouping = 0; i++; } } } if (grouping) { sbr->f_group[l][i] = sbr->kx + sbr->M; i++; } sbr->N_G[l] = (uint8_t)(i >> 1); } } static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) { uint8_t l, k, m; real_t E_total, E_total_est, G_target, acc; for (l = 0; l < sbr->L_E[ch]; l++) { for (k = 0; k < sbr->N_G[l]; k++) { E_total_est = E_total = 0; for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++) { /* E_curr: integer */ /* G_lim_boost: fixed point */ /* E_total_est: integer */ /* E_total: integer */ E_total_est += sbr->E_curr[ch][m-sbr->kx][l]; #ifdef FIXED_POINT E_total += MUL_Q2(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]); #else E_total += sbr->E_curr[ch][m-sbr->kx][l] * adj->G_lim_boost[l][m-sbr->kx]; #endif } /* G_target: fixed point */ if ((E_total_est + EPS) == 0) { G_target = 0; } else { #ifdef FIXED_POINT G_target = (((int64_t)(E_total))<f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) { real_t alpha; /* alpha: (COEF) fixed point */ if (m < sbr->kx + sbr->M - 1) { alpha = max(deg[m], deg[m + 1]); } else { alpha = deg[m]; } adj->G_lim_boost[l][m-sbr->kx] = MUL_C(alpha, G_target) + MUL_C((COEF_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]); /* acc: integer */ #ifdef FIXED_POINT acc += MUL_Q2(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]); #else acc += adj->G_lim_boost[l][m-sbr->kx] * sbr->E_curr[ch][m-sbr->kx][l]; #endif } /* acc: fixed point */ if (acc + EPS == 0) { acc = 0; } else { #ifdef FIXED_POINT acc = (((int64_t)(E_total))<f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) { #ifdef FIXED_POINT adj->G_lim_boost[l][m-sbr->kx] = MUL_Q2(acc, adj->G_lim_boost[l][m-sbr->kx]); #else adj->G_lim_boost[l][m-sbr->kx] = acc * adj->G_lim_boost[l][m-sbr->kx]; #endif } } } for (l = 0; l < sbr->L_E[ch]; l++) { for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) { for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) { #ifdef FIXED_POINT adj->G_lim_boost[l][m] = SBR_SQRT_Q2(adj->G_lim_boost[l][m]); #else adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]); #endif } } } } #endif static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) { static const real_t h_smooth[] = { FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084), FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582), FRAC_CONST(0.33333333333333) }; static const int8_t phi_re[] = { 1, 0, -1, 0 }; static const int8_t phi_im[] = { 0, 1, 0, -1 }; uint8_t m, l, i, n; uint16_t fIndexNoise = 0; uint8_t fIndexSine = 0; uint8_t assembly_reset = 0; real_t G_filt, Q_filt; uint8_t h_SL; if (sbr->Reset == 1) { assembly_reset = 1; fIndexNoise = 0; } else { fIndexNoise = sbr->index_noise_prev[ch]; } fIndexSine = sbr->psi_is_prev[ch]; for (l = 0; l < sbr->L_E[ch]; l++) { uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; #ifdef SBR_LOW_POWER h_SL = 0; #else h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; h_SL = (no_noise ? 0 : h_SL); #endif if (assembly_reset) { for (n = 0; n < 4; n++) { memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); } /* reset ringbuffer index */ sbr->GQ_ringbuf_index[ch] = 4; assembly_reset = 0; } for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) { #ifdef SBR_LOW_POWER uint8_t i_min1, i_plus1; uint8_t sinusoids = 0; #endif /* load new values into ringbuffer */ memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); for (m = 0; m < sbr->M; m++) { qmf_t psi; G_filt = 0; Q_filt = 0; #ifndef SBR_LOW_POWER if (h_SL != 0) { uint8_t ri = sbr->GQ_ringbuf_index[ch]; for (n = 0; n <= 4; n++) { real_t curr_h_smooth = h_smooth[n]; ri++; if (ri >= 5) ri -= 5; G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth); Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth); } } else { #endif G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; #ifndef SBR_LOW_POWER } #endif Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt; /* add noise to the output */ fIndexNoise = (fIndexNoise + 1) & 511; /* the smoothed gain values are applied to Xsbr */ /* V is defined, not calculated */ #ifndef FIXED_POINT QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) + MUL_F(Q_filt, RE(V[fIndexNoise])); #else //QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) // + MUL_F(Q_filt, RE(V[fIndexNoise])); QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) + MUL_F(Q_filt, RE(V[fIndexNoise])); #endif if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320; #ifndef SBR_LOW_POWER #ifndef FIXED_POINT QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) + MUL_F(Q_filt, IM(V[fIndexNoise])); #else //QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) // + MUL_F(Q_filt, IM(V[fIndexNoise])); QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) + MUL_F(Q_filt, IM(V[fIndexNoise])); #endif #endif { int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1); QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine]; #ifdef FIXED_POINT QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_RE(psi) << REAL_BITS); #else QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi); #endif #ifndef SBR_LOW_POWER QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine]; #ifdef FIXED_POINT QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_IM(psi) << REAL_BITS); #else QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi); #endif #else i_min1 = (fIndexSine - 1) & 3; i_plus1 = (fIndexSine + 1) & 3; #ifndef FIXED_POINT if ((m == 0) && (phi_re[i_plus1] != 0)) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) += (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815))); if (sbr->M != 0) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815))); } } if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); } if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0)) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815))); } if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) { if (m > 0) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); } if (m + sbr->kx < 64) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) += (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815))); } } #else if ((m == 0) && (phi_re[i_plus1] != 0)) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) += (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][0]<M != 0) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][1]< 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]< 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0)) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][m + 1]<M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) { if (m > 0) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<kx < 64) { QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) += (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m]<S_M_boost[l][m] != 0) sinusoids++; #endif } } fIndexSine = (fIndexSine + 1) & 3; /* update the ringbuffer index used for filtering G and Q with h_smooth */ sbr->GQ_ringbuf_index[ch]++; if (sbr->GQ_ringbuf_index[ch] >= 5) sbr->GQ_ringbuf_index[ch] = 0; } } sbr->index_noise_prev[ch] = fIndexNoise; sbr->psi_is_prev[ch] = fIndexSine; } #endif xine-lib-1.2/contrib/libfaad/tns.c0000644000175000017500000002456114647725152014666 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: tns.c,v 1.40 2007/11/01 12:33:40 menno Exp $ **/ #include "common.h" #include "structs.h" #include "syntax.h" #include "tns.h" /* static function declarations */ static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, uint8_t *coef, real_t *a); static void tns_ar_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, uint8_t order); static void tns_ma_filter(real_t *spectrum, uint16_t size, int8_t inc, real_t *lpc, uint8_t order); #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif static real_t tns_coef_0_3[] = { COEF_CONST(0.0), COEF_CONST(0.4338837391), COEF_CONST(0.7818314825), COEF_CONST(0.9749279122), COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), COEF_CONST(-0.4338837391), COEF_CONST(-0.7818314825), COEF_CONST(-0.9749279122), COEF_CONST(-0.9749279122), COEF_CONST(-0.9848077530), COEF_CONST(-0.8660254038), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433) }; static real_t tns_coef_0_4[] = { COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), COEF_CONST(0.7431448255), COEF_CONST(0.8660254038), COEF_CONST(0.9510565163), COEF_CONST(0.9945218954), COEF_CONST(-0.9957341763), COEF_CONST(-0.9618256432), COEF_CONST(-0.8951632914), COEF_CONST(-0.7980172273), COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) }; static real_t tns_coef_1_3[] = { COEF_CONST(0.0), COEF_CONST(0.4338837391), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), COEF_CONST(0.9749279122), COEF_CONST(0.7818314825), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), COEF_CONST(-0.4338837391), COEF_CONST(-0.7818314825), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433), COEF_CONST(-0.7818314825), COEF_CONST(-0.4338837391), COEF_CONST(-0.6427876097), COEF_CONST(-0.3420201433) }; static real_t tns_coef_1_4[] = { COEF_CONST(0.0), COEF_CONST(0.2079116908), COEF_CONST(0.4067366431), COEF_CONST(0.5877852523), COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178), COEF_CONST(0.9945218954), COEF_CONST(0.9510565163), COEF_CONST(0.8660254038), COEF_CONST(0.7431448255), COEF_CONST(-0.6736956436), COEF_CONST(-0.5264321629), COEF_CONST(-0.3612416662), COEF_CONST(-0.1837495178) }; /* TNS decoding for one channel and frame */ void tns_decode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, uint8_t object_type, real_t *spec, uint16_t frame_len) { uint8_t w, f, tns_order; int8_t inc; int16_t size; uint16_t bottom, top, start, end; uint16_t nshort = frame_len/8; real_t lpc[TNS_MAX_ORDER+1]; if (!ics->tns_data_present) return; for (w = 0; w < ics->num_windows; w++) { bottom = ics->num_swb; for (f = 0; f < tns->n_filt[w]; f++) { top = bottom; bottom = max(top - tns->length[w][f], 0); tns_order = min(tns->order[w][f], TNS_MAX_ORDER); if (!tns_order) continue; tns_decode_coef(tns_order, tns->coef_res[w]+3, tns->coef_compress[w][f], tns->coef[w][f], lpc); start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); start = min(start, ics->max_sfb); start = min(ics->swb_offset[start], ics->swb_offset_max); end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); end = min(end, ics->max_sfb); end = min(ics->swb_offset[end], ics->swb_offset_max); size = end - start; if (size <= 0) continue; if (tns->direction[w][f]) { inc = -1; start = end - 1; } else { inc = 1; } tns_ar_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order); } } } /* TNS encoding for one channel and frame */ void tns_encode_frame(ic_stream *ics, tns_info *tns, uint8_t sr_index, uint8_t object_type, real_t *spec, uint16_t frame_len) { uint8_t w, f, tns_order; int8_t inc; int16_t size; uint16_t bottom, top, start, end; uint16_t nshort = frame_len/8; real_t lpc[TNS_MAX_ORDER+1]; if (!ics->tns_data_present) return; for (w = 0; w < ics->num_windows; w++) { bottom = ics->num_swb; for (f = 0; f < tns->n_filt[w]; f++) { top = bottom; bottom = max(top - tns->length[w][f], 0); tns_order = min(tns->order[w][f], TNS_MAX_ORDER); if (!tns_order) continue; tns_decode_coef(tns_order, tns->coef_res[w]+3, tns->coef_compress[w][f], tns->coef[w][f], lpc); start = min(bottom, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); start = min(start, ics->max_sfb); start = min(ics->swb_offset[start], ics->swb_offset_max); end = min(top, max_tns_sfb(sr_index, object_type, (ics->window_sequence == EIGHT_SHORT_SEQUENCE))); end = min(end, ics->max_sfb); end = min(ics->swb_offset[end], ics->swb_offset_max); size = end - start; if (size <= 0) continue; if (tns->direction[w][f]) { inc = -1; start = end - 1; } else { inc = 1; } tns_ma_filter(&spec[(w*nshort)+start], size, inc, lpc, tns_order); } } } /* Decoder transmitted coefficients for one TNS filter */ static void tns_decode_coef(uint8_t order, uint8_t coef_res_bits, uint8_t coef_compress, uint8_t *coef, real_t *a) { uint8_t i, m; real_t tmp2[TNS_MAX_ORDER+1], b[TNS_MAX_ORDER+1]; /* Conversion to signed integer */ for (i = 0; i < order; i++) { if (coef_compress == 0) { if (coef_res_bits == 3) { tmp2[i] = tns_coef_0_3[coef[i]]; } else { tmp2[i] = tns_coef_0_4[coef[i]]; } } else { if (coef_res_bits == 3) { tmp2[i] = tns_coef_1_3[coef[i]]; } else { tmp2[i] = tns_coef_1_4[coef[i]]; } } } /* Conversion to LPC coefficients */ a[0] = COEF_CONST(1.0); for (m = 1; m <= order; m++) { for (i = 1; i < m; i++) /* loop only while i #include "bits.h" #include "mp4.h" #include "syntax.h" /* defines if an object type can be decoded by this library or not */ static uint8_t ObjectTypesTable[32] = { 0, /* 0 NULL */ #ifdef MAIN_DEC 1, /* 1 AAC Main */ #else 0, /* 1 AAC Main */ #endif 1, /* 2 AAC LC */ #ifdef SSR_DEC 1, /* 3 AAC SSR */ #else 0, /* 3 AAC SSR */ #endif #ifdef LTP_DEC 1, /* 4 AAC LTP */ #else 0, /* 4 AAC LTP */ #endif #ifdef SBR_DEC 1, /* 5 SBR */ #else 0, /* 5 SBR */ #endif 0, /* 6 AAC Scalable */ 0, /* 7 TwinVQ */ 0, /* 8 CELP */ 0, /* 9 HVXC */ 0, /* 10 Reserved */ 0, /* 11 Reserved */ 0, /* 12 TTSI */ 0, /* 13 Main synthetic */ 0, /* 14 Wavetable synthesis */ 0, /* 15 General MIDI */ 0, /* 16 Algorithmic Synthesis and Audio FX */ /* MPEG-4 Version 2 */ #ifdef ERROR_RESILIENCE 1, /* 17 ER AAC LC */ 0, /* 18 (Reserved) */ #ifdef LTP_DEC 1, /* 19 ER AAC LTP */ #else 0, /* 19 ER AAC LTP */ #endif 0, /* 20 ER AAC scalable */ 0, /* 21 ER TwinVQ */ 0, /* 22 ER BSAC */ #ifdef LD_DEC 1, /* 23 ER AAC LD */ #else 0, /* 23 ER AAC LD */ #endif 0, /* 24 ER CELP */ 0, /* 25 ER HVXC */ 0, /* 26 ER HILN */ 0, /* 27 ER Parametric */ #else /* No ER defined */ 0, /* 17 ER AAC LC */ 0, /* 18 (Reserved) */ 0, /* 19 ER AAC LTP */ 0, /* 20 ER AAC scalable */ 0, /* 21 ER TwinVQ */ 0, /* 22 ER BSAC */ 0, /* 23 ER AAC LD */ 0, /* 24 ER CELP */ 0, /* 25 ER HVXC */ 0, /* 26 ER HILN */ 0, /* 27 ER Parametric */ #endif 0, /* 28 (Reserved) */ 0, /* 29 (Reserved) */ 0, /* 30 (Reserved) */ 0 /* 31 (Reserved) */ }; /* Table 1.6.1 */ char NEAACDECAPI NeAACDecAudioSpecificConfig(unsigned char *pBuffer, unsigned long buffer_size, mp4AudioSpecificConfig *mp4ASC) { return AudioSpecificConfig2(pBuffer, buffer_size, mp4ASC, NULL, 0); } int8_t AudioSpecificConfigFromBitfile(bitfile *ld, mp4AudioSpecificConfig *mp4ASC, program_config *pce, uint32_t buffer_size, uint8_t short_form) { int8_t result = 0; uint32_t startpos = faad_get_processed_bits(ld); #ifdef SBR_DEC int8_t bits_to_decode = 0; #endif if (mp4ASC == NULL) return -8; memset(mp4ASC, 0, sizeof(mp4AudioSpecificConfig)); mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,1,"parse_audio_decoder_specific_info(): ObjectTypeIndex")); mp4ASC->samplingFrequencyIndex = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,2,"parse_audio_decoder_specific_info(): SamplingFrequencyIndex")); if(mp4ASC->samplingFrequencyIndex==0x0f) faad_getbits(ld, 24); mp4ASC->channelsConfiguration = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,3,"parse_audio_decoder_specific_info(): ChannelsConfiguration")); mp4ASC->samplingFrequency = get_sample_rate(mp4ASC->samplingFrequencyIndex); if (ObjectTypesTable[mp4ASC->objectTypeIndex] != 1) { return -1; } if (mp4ASC->samplingFrequency == 0) { return -2; } if (mp4ASC->channelsConfiguration > 7) { return -3; } #if (defined(PS_DEC) || defined(DRM_PS)) /* check if we have a mono file */ if (mp4ASC->channelsConfiguration == 1) { /* upMatrix to 2 channels for implicit signalling of PS */ mp4ASC->channelsConfiguration = 2; } #endif #ifdef SBR_DEC mp4ASC->sbr_present_flag = -1; if (mp4ASC->objectTypeIndex == 5) { uint8_t tmp; mp4ASC->sbr_present_flag = 1; tmp = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,5,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex")); /* check for downsampled SBR */ if (tmp == mp4ASC->samplingFrequencyIndex) mp4ASC->downSampledSBR = 1; mp4ASC->samplingFrequencyIndex = tmp; if (mp4ASC->samplingFrequencyIndex == 15) { mp4ASC->samplingFrequency = (uint32_t)faad_getbits(ld, 24 DEBUGVAR(1,6,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex")); } else { mp4ASC->samplingFrequency = get_sample_rate(mp4ASC->samplingFrequencyIndex); } mp4ASC->objectTypeIndex = (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,7,"parse_audio_decoder_specific_info(): ObjectTypeIndex")); } #endif /* get GASpecificConfig */ if (mp4ASC->objectTypeIndex == 1 || mp4ASC->objectTypeIndex == 2 || mp4ASC->objectTypeIndex == 3 || mp4ASC->objectTypeIndex == 4 || mp4ASC->objectTypeIndex == 6 || mp4ASC->objectTypeIndex == 7) { result = GASpecificConfig(ld, mp4ASC, pce); #ifdef ERROR_RESILIENCE } else if (mp4ASC->objectTypeIndex >= ER_OBJECT_START) { /* ER */ result = GASpecificConfig(ld, mp4ASC, pce); mp4ASC->epConfig = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,143,"parse_audio_decoder_specific_info(): epConfig")); if (mp4ASC->epConfig != 0) result = -5; #endif } else { result = -4; } #ifdef SSR_DEC /* shorter frames not allowed for SSR */ if ((mp4ASC->objectTypeIndex == 4) && mp4ASC->frameLengthFlag) return -6; #endif #ifdef SBR_DEC if(short_form) bits_to_decode = 0; else bits_to_decode = (int8_t)(buffer_size*8 - (startpos-faad_get_processed_bits(ld))); if ((mp4ASC->objectTypeIndex != 5) && (bits_to_decode >= 16)) { int16_t syncExtensionType = (int16_t)faad_getbits(ld, 11 DEBUGVAR(1,9,"parse_audio_decoder_specific_info(): syncExtensionType")); if (syncExtensionType == 0x2b7) { uint8_t tmp_OTi = (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,10,"parse_audio_decoder_specific_info(): extensionAudioObjectType")); if (tmp_OTi == 5) { mp4ASC->sbr_present_flag = (uint8_t)faad_get1bit(ld DEBUGVAR(1,11,"parse_audio_decoder_specific_info(): sbr_present_flag")); if (mp4ASC->sbr_present_flag) { uint8_t tmp; /* Don't set OT to SBR until checked that it is actually there */ mp4ASC->objectTypeIndex = tmp_OTi; tmp = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,12,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex")); /* check for downsampled SBR */ if (tmp == mp4ASC->samplingFrequencyIndex) mp4ASC->downSampledSBR = 1; mp4ASC->samplingFrequencyIndex = tmp; if (mp4ASC->samplingFrequencyIndex == 15) { mp4ASC->samplingFrequency = (uint32_t)faad_getbits(ld, 24 DEBUGVAR(1,13,"parse_audio_decoder_specific_info(): extensionSamplingFrequencyIndex")); } else { mp4ASC->samplingFrequency = get_sample_rate(mp4ASC->samplingFrequencyIndex); } } } } } /* no SBR signalled, this could mean either implicit signalling or no SBR in this file */ /* MPEG specification states: assume SBR on files with samplerate <= 24000 Hz */ if (mp4ASC->sbr_present_flag == -1) { if (mp4ASC->samplingFrequency <= 24000) { mp4ASC->samplingFrequency *= 2; mp4ASC->forceUpSampling = 1; } else /* > 24000*/ { mp4ASC->downSampledSBR = 1; } } #endif faad_endbits(ld); return result; } int8_t AudioSpecificConfig2(uint8_t *pBuffer, uint32_t buffer_size, mp4AudioSpecificConfig *mp4ASC, program_config *pce, uint8_t short_form) { uint8_t ret = 0; bitfile ld; faad_initbits(&ld, pBuffer, buffer_size); faad_byte_align(&ld); ret = AudioSpecificConfigFromBitfile(&ld, mp4ASC, pce, buffer_size, short_form); faad_endbits(&ld); return ret; } xine-lib-1.2/contrib/libfaad/sbr_dct.c0000644000175000017500000024015214647725152015476 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_dct.c,v 1.20 2007/11/01 12:33:34 menno Exp $ **/ /* Most of the DCT/DST codes here are generated using Spiral which is GPL * For more info see: http://www.spiral.net/ */ #include "common.h" #ifdef SBR_DEC #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif #include "sbr_dct.h" void DCT4_32(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10; real_t f11, f12, f13, f14, f15, f16, f17, f18, f19, f20; real_t f21, f22, f23, f24, f25, f26, f27, f28, f29, f30; real_t f31, f32, f33, f34, f35, f36, f37, f38, f39, f40; real_t f41, f42, f43, f44, f45, f46, f47, f48, f49, f50; real_t f51, f52, f53, f54, f55, f56, f57, f58, f59, f60; real_t f61, f62, f63, f64, f65, f66, f67, f68, f69, f70; real_t f71, f72, f73, f74, f75, f76, f77, f78, f79, f80; real_t f81, f82, f83, f84, f85, f86, f87, f88, f89, f90; real_t f91, f92, f93, f94, f95, f96, f97, f98, f99, f100; real_t f101, f102, f103, f104, f105, f106, f107, f108, f109, f110; real_t f111, f112, f113, f114, f115, f116, f117, f118, f119, f120; real_t f121, f122, f123, f124, f125, f126, f127, f128, f129, f130; real_t f131, f132, f133, f134, f135, f136, f137, f138, f139, f140; real_t f141, f142, f143, f144, f145, f146, f147, f148, f149, f150; real_t f151, f152, f153, f154, f155, f156, f157, f158, f159, f160; real_t f161, f162, f163, f164, f165, f166, f167, f168, f169, f170; real_t f171, f172, f173, f174, f175, f176, f177, f178, f179, f180; real_t f181, f182, f183, f184, f185, f186, f187, f188, f189, f190; real_t f191, f192, f193, f194, f195, f196, f197, f198, f199, f200; real_t f201, f202, f203, f204, f205, f206, f207, f208, f209, f210; real_t f211, f212, f213, f214, f215, f216, f217, f218, f219, f220; real_t f221, f222, f223, f224, f225, f226, f227, f228, f229, f230; real_t f231, f232, f233, f234, f235, f236, f237, f238, f239, f240; real_t f241, f242, f243, f244, f245, f246, f247, f248, f249, f250; real_t f251, f252, f253, f254, f255, f256, f257, f258, f259, f260; real_t f261, f262, f263, f264, f265, f266, f267, f268, f269, f270; real_t f271, f272, f273, f274, f275, f276, f277, f278, f279, f280; real_t f281, f282, f283, f284, f285, f286, f287, f288, f289, f290; real_t f291, f292, f293, f294, f295, f296, f297, f298, f299, f300; real_t f301, f302, f303, f304, f305, f306, f307, f310, f311, f312; real_t f313, f316, f317, f318, f319, f322, f323, f324, f325, f328; real_t f329, f330, f331, f334, f335, f336, f337, f340, f341, f342; real_t f343, f346, f347, f348, f349, f352, f353, f354, f355, f358; real_t f359, f360, f361, f364, f365, f366, f367, f370, f371, f372; real_t f373, f376, f377, f378, f379, f382, f383, f384, f385, f388; real_t f389, f390, f391, f394, f395, f396, f397; f0 = x[15] - x[16]; f1 = x[15] + x[16]; f2 = MUL_F(FRAC_CONST(0.7071067811865476), f1); f3 = MUL_F(FRAC_CONST(0.7071067811865476), f0); f4 = x[8] - x[23]; f5 = x[8] + x[23]; f6 = MUL_F(FRAC_CONST(0.7071067811865476), f5); f7 = MUL_F(FRAC_CONST(0.7071067811865476), f4); f8 = x[12] - x[19]; f9 = x[12] + x[19]; f10 = MUL_F(FRAC_CONST(0.7071067811865476), f9); f11 = MUL_F(FRAC_CONST(0.7071067811865476), f8); f12 = x[11] - x[20]; f13 = x[11] + x[20]; f14 = MUL_F(FRAC_CONST(0.7071067811865476), f13); f15 = MUL_F(FRAC_CONST(0.7071067811865476), f12); f16 = x[14] - x[17]; f17 = x[14] + x[17]; f18 = MUL_F(FRAC_CONST(0.7071067811865476), f17); f19 = MUL_F(FRAC_CONST(0.7071067811865476), f16); f20 = x[9] - x[22]; f21 = x[9] + x[22]; f22 = MUL_F(FRAC_CONST(0.7071067811865476), f21); f23 = MUL_F(FRAC_CONST(0.7071067811865476), f20); f24 = x[13] - x[18]; f25 = x[13] + x[18]; f26 = MUL_F(FRAC_CONST(0.7071067811865476), f25); f27 = MUL_F(FRAC_CONST(0.7071067811865476), f24); f28 = x[10] - x[21]; f29 = x[10] + x[21]; f30 = MUL_F(FRAC_CONST(0.7071067811865476), f29); f31 = MUL_F(FRAC_CONST(0.7071067811865476), f28); f32 = x[0] - f2; f33 = x[0] + f2; f34 = x[31] - f3; f35 = x[31] + f3; f36 = x[7] - f6; f37 = x[7] + f6; f38 = x[24] - f7; f39 = x[24] + f7; f40 = x[3] - f10; f41 = x[3] + f10; f42 = x[28] - f11; f43 = x[28] + f11; f44 = x[4] - f14; f45 = x[4] + f14; f46 = x[27] - f15; f47 = x[27] + f15; f48 = x[1] - f18; f49 = x[1] + f18; f50 = x[30] - f19; f51 = x[30] + f19; f52 = x[6] - f22; f53 = x[6] + f22; f54 = x[25] - f23; f55 = x[25] + f23; f56 = x[2] - f26; f57 = x[2] + f26; f58 = x[29] - f27; f59 = x[29] + f27; f60 = x[5] - f30; f61 = x[5] + f30; f62 = x[26] - f31; f63 = x[26] + f31; f64 = f39 + f37; f65 = MUL_F(FRAC_CONST(-0.5411961001461969), f39); f66 = MUL_F(FRAC_CONST(0.9238795325112867), f64); f67 = MUL_C(COEF_CONST(1.3065629648763766), f37); f68 = f65 + f66; f69 = f67 - f66; f70 = f38 + f36; f71 = MUL_C(COEF_CONST(1.3065629648763770), f38); f72 = MUL_F(FRAC_CONST(-0.3826834323650904), f70); f73 = MUL_F(FRAC_CONST(0.5411961001461961), f36); f74 = f71 + f72; f75 = f73 - f72; f76 = f47 + f45; f77 = MUL_F(FRAC_CONST(-0.5411961001461969), f47); f78 = MUL_F(FRAC_CONST(0.9238795325112867), f76); f79 = MUL_C(COEF_CONST(1.3065629648763766), f45); f80 = f77 + f78; f81 = f79 - f78; f82 = f46 + f44; f83 = MUL_C(COEF_CONST(1.3065629648763770), f46); f84 = MUL_F(FRAC_CONST(-0.3826834323650904), f82); f85 = MUL_F(FRAC_CONST(0.5411961001461961), f44); f86 = f83 + f84; f87 = f85 - f84; f88 = f55 + f53; f89 = MUL_F(FRAC_CONST(-0.5411961001461969), f55); f90 = MUL_F(FRAC_CONST(0.9238795325112867), f88); f91 = MUL_C(COEF_CONST(1.3065629648763766), f53); f92 = f89 + f90; f93 = f91 - f90; f94 = f54 + f52; f95 = MUL_C(COEF_CONST(1.3065629648763770), f54); f96 = MUL_F(FRAC_CONST(-0.3826834323650904), f94); f97 = MUL_F(FRAC_CONST(0.5411961001461961), f52); f98 = f95 + f96; f99 = f97 - f96; f100 = f63 + f61; f101 = MUL_F(FRAC_CONST(-0.5411961001461969), f63); f102 = MUL_F(FRAC_CONST(0.9238795325112867), f100); f103 = MUL_C(COEF_CONST(1.3065629648763766), f61); f104 = f101 + f102; f105 = f103 - f102; f106 = f62 + f60; f107 = MUL_C(COEF_CONST(1.3065629648763770), f62); f108 = MUL_F(FRAC_CONST(-0.3826834323650904), f106); f109 = MUL_F(FRAC_CONST(0.5411961001461961), f60); f110 = f107 + f108; f111 = f109 - f108; f112 = f33 - f68; f113 = f33 + f68; f114 = f35 - f69; f115 = f35 + f69; f116 = f32 - f74; f117 = f32 + f74; f118 = f34 - f75; f119 = f34 + f75; f120 = f41 - f80; f121 = f41 + f80; f122 = f43 - f81; f123 = f43 + f81; f124 = f40 - f86; f125 = f40 + f86; f126 = f42 - f87; f127 = f42 + f87; f128 = f49 - f92; f129 = f49 + f92; f130 = f51 - f93; f131 = f51 + f93; f132 = f48 - f98; f133 = f48 + f98; f134 = f50 - f99; f135 = f50 + f99; f136 = f57 - f104; f137 = f57 + f104; f138 = f59 - f105; f139 = f59 + f105; f140 = f56 - f110; f141 = f56 + f110; f142 = f58 - f111; f143 = f58 + f111; f144 = f123 + f121; f145 = MUL_F(FRAC_CONST(-0.7856949583871021), f123); f146 = MUL_F(FRAC_CONST(0.9807852804032304), f144); f147 = MUL_C(COEF_CONST(1.1758756024193588), f121); f148 = f145 + f146; f149 = f147 - f146; f150 = f127 + f125; f151 = MUL_F(FRAC_CONST(0.2758993792829431), f127); f152 = MUL_F(FRAC_CONST(0.5555702330196022), f150); f153 = MUL_C(COEF_CONST(1.3870398453221475), f125); f154 = f151 + f152; f155 = f153 - f152; f156 = f122 + f120; f157 = MUL_C(COEF_CONST(1.1758756024193591), f122); f158 = MUL_F(FRAC_CONST(-0.1950903220161287), f156); f159 = MUL_F(FRAC_CONST(0.7856949583871016), f120); f160 = f157 + f158; f161 = f159 - f158; f162 = f126 + f124; f163 = MUL_C(COEF_CONST(1.3870398453221473), f126); f164 = MUL_F(FRAC_CONST(-0.8314696123025455), f162); f165 = MUL_F(FRAC_CONST(-0.2758993792829436), f124); f166 = f163 + f164; f167 = f165 - f164; f168 = f139 + f137; f169 = MUL_F(FRAC_CONST(-0.7856949583871021), f139); f170 = MUL_F(FRAC_CONST(0.9807852804032304), f168); f171 = MUL_C(COEF_CONST(1.1758756024193588), f137); f172 = f169 + f170; f173 = f171 - f170; f174 = f143 + f141; f175 = MUL_F(FRAC_CONST(0.2758993792829431), f143); f176 = MUL_F(FRAC_CONST(0.5555702330196022), f174); f177 = MUL_C(COEF_CONST(1.3870398453221475), f141); f178 = f175 + f176; f179 = f177 - f176; f180 = f138 + f136; f181 = MUL_C(COEF_CONST(1.1758756024193591), f138); f182 = MUL_F(FRAC_CONST(-0.1950903220161287), f180); f183 = MUL_F(FRAC_CONST(0.7856949583871016), f136); f184 = f181 + f182; f185 = f183 - f182; f186 = f142 + f140; f187 = MUL_C(COEF_CONST(1.3870398453221473), f142); f188 = MUL_F(FRAC_CONST(-0.8314696123025455), f186); f189 = MUL_F(FRAC_CONST(-0.2758993792829436), f140); f190 = f187 + f188; f191 = f189 - f188; f192 = f113 - f148; f193 = f113 + f148; f194 = f115 - f149; f195 = f115 + f149; f196 = f117 - f154; f197 = f117 + f154; f198 = f119 - f155; f199 = f119 + f155; f200 = f112 - f160; f201 = f112 + f160; f202 = f114 - f161; f203 = f114 + f161; f204 = f116 - f166; f205 = f116 + f166; f206 = f118 - f167; f207 = f118 + f167; f208 = f129 - f172; f209 = f129 + f172; f210 = f131 - f173; f211 = f131 + f173; f212 = f133 - f178; f213 = f133 + f178; f214 = f135 - f179; f215 = f135 + f179; f216 = f128 - f184; f217 = f128 + f184; f218 = f130 - f185; f219 = f130 + f185; f220 = f132 - f190; f221 = f132 + f190; f222 = f134 - f191; f223 = f134 + f191; f224 = f211 + f209; f225 = MUL_F(FRAC_CONST(-0.8971675863426361), f211); f226 = MUL_F(FRAC_CONST(0.9951847266721968), f224); f227 = MUL_C(COEF_CONST(1.0932018670017576), f209); f228 = f225 + f226; f229 = f227 - f226; f230 = f215 + f213; f231 = MUL_F(FRAC_CONST(-0.4105245275223571), f215); f232 = MUL_F(FRAC_CONST(0.8819212643483549), f230); f233 = MUL_C(COEF_CONST(1.3533180011743529), f213); f234 = f231 + f232; f235 = f233 - f232; f236 = f219 + f217; f237 = MUL_F(FRAC_CONST(0.1386171691990915), f219); f238 = MUL_F(FRAC_CONST(0.6343932841636455), f236); f239 = MUL_C(COEF_CONST(1.4074037375263826), f217); f240 = f237 + f238; f241 = f239 - f238; f242 = f223 + f221; f243 = MUL_F(FRAC_CONST(0.6666556584777466), f223); f244 = MUL_F(FRAC_CONST(0.2902846772544623), f242); f245 = MUL_C(COEF_CONST(1.2472250129866711), f221); f246 = f243 + f244; f247 = f245 - f244; f248 = f210 + f208; f249 = MUL_C(COEF_CONST(1.0932018670017574), f210); f250 = MUL_F(FRAC_CONST(-0.0980171403295605), f248); f251 = MUL_F(FRAC_CONST(0.8971675863426364), f208); f252 = f249 + f250; f253 = f251 - f250; f254 = f214 + f212; f255 = MUL_C(COEF_CONST(1.3533180011743529), f214); f256 = MUL_F(FRAC_CONST(-0.4713967368259979), f254); f257 = MUL_F(FRAC_CONST(0.4105245275223569), f212); f258 = f255 + f256; f259 = f257 - f256; f260 = f218 + f216; f261 = MUL_C(COEF_CONST(1.4074037375263826), f218); f262 = MUL_F(FRAC_CONST(-0.7730104533627369), f260); f263 = MUL_F(FRAC_CONST(-0.1386171691990913), f216); f264 = f261 + f262; f265 = f263 - f262; f266 = f222 + f220; f267 = MUL_C(COEF_CONST(1.2472250129866711), f222); f268 = MUL_F(FRAC_CONST(-0.9569403357322089), f266); f269 = MUL_F(FRAC_CONST(-0.6666556584777469), f220); f270 = f267 + f268; f271 = f269 - f268; f272 = f193 - f228; f273 = f193 + f228; f274 = f195 - f229; f275 = f195 + f229; f276 = f197 - f234; f277 = f197 + f234; f278 = f199 - f235; f279 = f199 + f235; f280 = f201 - f240; f281 = f201 + f240; f282 = f203 - f241; f283 = f203 + f241; f284 = f205 - f246; f285 = f205 + f246; f286 = f207 - f247; f287 = f207 + f247; f288 = f192 - f252; f289 = f192 + f252; f290 = f194 - f253; f291 = f194 + f253; f292 = f196 - f258; f293 = f196 + f258; f294 = f198 - f259; f295 = f198 + f259; f296 = f200 - f264; f297 = f200 + f264; f298 = f202 - f265; f299 = f202 + f265; f300 = f204 - f270; f301 = f204 + f270; f302 = f206 - f271; f303 = f206 + f271; f304 = f275 + f273; f305 = MUL_F(FRAC_CONST(-0.9751575901732920), f275); f306 = MUL_F(FRAC_CONST(0.9996988186962043), f304); f307 = MUL_C(COEF_CONST(1.0242400472191164), f273); y[0] = f305 + f306; y[31] = f307 - f306; f310 = f279 + f277; f311 = MUL_F(FRAC_CONST(-0.8700688593994936), f279); f312 = MUL_F(FRAC_CONST(0.9924795345987100), f310); f313 = MUL_C(COEF_CONST(1.1148902097979263), f277); y[2] = f311 + f312; y[29] = f313 - f312; f316 = f283 + f281; f317 = MUL_F(FRAC_CONST(-0.7566008898816587), f283); f318 = MUL_F(FRAC_CONST(0.9757021300385286), f316); f319 = MUL_C(COEF_CONST(1.1948033701953984), f281); y[4] = f317 + f318; y[27] = f319 - f318; f322 = f287 + f285; f323 = MUL_F(FRAC_CONST(-0.6358464401941451), f287); f324 = MUL_F(FRAC_CONST(0.9495281805930367), f322); f325 = MUL_C(COEF_CONST(1.2632099209919283), f285); y[6] = f323 + f324; y[25] = f325 - f324; f328 = f291 + f289; f329 = MUL_F(FRAC_CONST(-0.5089684416985408), f291); f330 = MUL_F(FRAC_CONST(0.9142097557035307), f328); f331 = MUL_C(COEF_CONST(1.3194510697085207), f289); y[8] = f329 + f330; y[23] = f331 - f330; f334 = f295 + f293; f335 = MUL_F(FRAC_CONST(-0.3771887988789273), f295); f336 = MUL_F(FRAC_CONST(0.8700869911087114), f334); f337 = MUL_C(COEF_CONST(1.3629851833384954), f293); y[10] = f335 + f336; y[21] = f337 - f336; f340 = f299 + f297; f341 = MUL_F(FRAC_CONST(-0.2417766217337384), f299); f342 = MUL_F(FRAC_CONST(0.8175848131515837), f340); f343 = MUL_C(COEF_CONST(1.3933930045694289), f297); y[12] = f341 + f342; y[19] = f343 - f342; f346 = f303 + f301; f347 = MUL_F(FRAC_CONST(-0.1040360035527077), f303); f348 = MUL_F(FRAC_CONST(0.7572088465064845), f346); f349 = MUL_C(COEF_CONST(1.4103816894602612), f301); y[14] = f347 + f348; y[17] = f349 - f348; f352 = f274 + f272; f353 = MUL_F(FRAC_CONST(0.0347065382144002), f274); f354 = MUL_F(FRAC_CONST(0.6895405447370668), f352); f355 = MUL_C(COEF_CONST(1.4137876276885337), f272); y[16] = f353 + f354; y[15] = f355 - f354; f358 = f278 + f276; f359 = MUL_F(FRAC_CONST(0.1731148370459795), f278); f360 = MUL_F(FRAC_CONST(0.6152315905806268), f358); f361 = MUL_C(COEF_CONST(1.4035780182072330), f276); y[18] = f359 + f360; y[13] = f361 - f360; f364 = f282 + f280; f365 = MUL_F(FRAC_CONST(0.3098559453626100), f282); f366 = MUL_F(FRAC_CONST(0.5349976198870972), f364); f367 = MUL_C(COEF_CONST(1.3798511851368043), f280); y[20] = f365 + f366; y[11] = f367 - f366; f370 = f286 + f284; f371 = MUL_F(FRAC_CONST(0.4436129715409088), f286); f372 = MUL_F(FRAC_CONST(0.4496113296546065), f370); f373 = MUL_C(COEF_CONST(1.3428356308501219), f284); y[22] = f371 + f372; y[9] = f373 - f372; f376 = f290 + f288; f377 = MUL_F(FRAC_CONST(0.5730977622997509), f290); f378 = MUL_F(FRAC_CONST(0.3598950365349881), f376); f379 = MUL_C(COEF_CONST(1.2928878353697271), f288); y[24] = f377 + f378; y[7] = f379 - f378; f382 = f294 + f292; f383 = MUL_F(FRAC_CONST(0.6970633083205415), f294); f384 = MUL_F(FRAC_CONST(0.2667127574748984), f382); f385 = MUL_C(COEF_CONST(1.2304888232703382), f292); y[26] = f383 + f384; y[5] = f385 - f384; f388 = f298 + f296; f389 = MUL_F(FRAC_CONST(0.8143157536286401), f298); f390 = MUL_F(FRAC_CONST(0.1709618887603012), f388); f391 = MUL_C(COEF_CONST(1.1562395311492424), f296); y[28] = f389 + f390; y[3] = f391 - f390; f394 = f302 + f300; f395 = MUL_F(FRAC_CONST(0.9237258930790228), f302); f396 = MUL_F(FRAC_CONST(0.0735645635996674), f394); f397 = MUL_C(COEF_CONST(1.0708550202783576), f300); y[30] = f395 + f396; y[1] = f397 - f396; } void DST4_32(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9; real_t f10, f11, f12, f13, f14, f15, f16, f17, f18, f19; real_t f20, f21, f22, f23, f24, f25, f26, f27, f28, f29; real_t f30, f31, f32, f33, f34, f35, f36, f37, f38, f39; real_t f40, f41, f42, f43, f44, f45, f46, f47, f48, f49; real_t f50, f51, f52, f53, f54, f55, f56, f57, f58, f59; real_t f60, f61, f62, f63, f64, f65, f66, f67, f68, f69; real_t f70, f71, f72, f73, f74, f75, f76, f77, f78, f79; real_t f80, f81, f82, f83, f84, f85, f86, f87, f88, f89; real_t f90, f91, f92, f93, f94, f95, f96, f97, f98, f99; real_t f100, f101, f102, f103, f104, f105, f106, f107, f108, f109; real_t f110, f111, f112, f113, f114, f115, f116, f117, f118, f119; real_t f120, f121, f122, f123, f124, f125, f126, f127, f128, f129; real_t f130, f131, f132, f133, f134, f135, f136, f137, f138, f139; real_t f140, f141, f142, f143, f144, f145, f146, f147, f148, f149; real_t f150, f151, f152, f153, f154, f155, f156, f157, f158, f159; real_t f160, f161, f162, f163, f164, f165, f166, f167, f168, f169; real_t f170, f171, f172, f173, f174, f175, f176, f177, f178, f179; real_t f180, f181, f182, f183, f184, f185, f186, f187, f188, f189; real_t f190, f191, f192, f193, f194, f195, f196, f197, f198, f199; real_t f200, f201, f202, f203, f204, f205, f206, f207, f208, f209; real_t f210, f211, f212, f213, f214, f215, f216, f217, f218, f219; real_t f220, f221, f222, f223, f224, f225, f226, f227, f228, f229; real_t f230, f231, f232, f233, f234, f235, f236, f237, f238, f239; real_t f240, f241, f242, f243, f244, f245, f246, f247, f248, f249; real_t f250, f251, f252, f253, f254, f255, f256, f257, f258, f259; real_t f260, f261, f262, f263, f264, f265, f266, f267, f268, f269; real_t f270, f271, f272, f273, f274, f275, f276, f277, f278, f279; real_t f280, f281, f282, f283, f284, f285, f286, f287, f288, f289; real_t f290, f291, f292, f293, f294, f295, f296, f297, f298, f299; real_t f300, f301, f302, f303, f304, f305, f306, f307, f308, f309; real_t f310, f311, f312, f313, f314, f315, f316, f317, f318, f319; real_t f320, f321, f322, f323, f324, f325, f326, f327, f328, f329; real_t f330, f331, f332, f333, f334, f335; f0 = x[0] - x[1]; f1 = x[2] - x[1]; f2 = x[2] - x[3]; f3 = x[4] - x[3]; f4 = x[4] - x[5]; f5 = x[6] - x[5]; f6 = x[6] - x[7]; f7 = x[8] - x[7]; f8 = x[8] - x[9]; f9 = x[10] - x[9]; f10 = x[10] - x[11]; f11 = x[12] - x[11]; f12 = x[12] - x[13]; f13 = x[14] - x[13]; f14 = x[14] - x[15]; f15 = x[16] - x[15]; f16 = x[16] - x[17]; f17 = x[18] - x[17]; f18 = x[18] - x[19]; f19 = x[20] - x[19]; f20 = x[20] - x[21]; f21 = x[22] - x[21]; f22 = x[22] - x[23]; f23 = x[24] - x[23]; f24 = x[24] - x[25]; f25 = x[26] - x[25]; f26 = x[26] - x[27]; f27 = x[28] - x[27]; f28 = x[28] - x[29]; f29 = x[30] - x[29]; f30 = x[30] - x[31]; f31 = MUL_F(FRAC_CONST(0.7071067811865476), f15); f32 = x[0] - f31; f33 = x[0] + f31; f34 = f7 + f23; f35 = MUL_C(COEF_CONST(1.3065629648763766), f7); f36 = MUL_F(FRAC_CONST(-0.9238795325112866), f34); f37 = MUL_F(FRAC_CONST(-0.5411961001461967), f23); f38 = f35 + f36; f39 = f37 - f36; f40 = f33 - f39; f41 = f33 + f39; f42 = f32 - f38; f43 = f32 + f38; f44 = f11 - f19; f45 = f11 + f19; f46 = MUL_F(FRAC_CONST(0.7071067811865476), f45); f47 = f3 - f46; f48 = f3 + f46; f49 = MUL_F(FRAC_CONST(0.7071067811865476), f44); f50 = f49 - f27; f51 = f49 + f27; f52 = f51 + f48; f53 = MUL_F(FRAC_CONST(-0.7856949583871021), f51); f54 = MUL_F(FRAC_CONST(0.9807852804032304), f52); f55 = MUL_C(COEF_CONST(1.1758756024193588), f48); f56 = f53 + f54; f57 = f55 - f54; f58 = f50 + f47; f59 = MUL_F(FRAC_CONST(-0.2758993792829430), f50); f60 = MUL_F(FRAC_CONST(0.8314696123025452), f58); f61 = MUL_C(COEF_CONST(1.3870398453221475), f47); f62 = f59 + f60; f63 = f61 - f60; f64 = f41 - f56; f65 = f41 + f56; f66 = f43 - f62; f67 = f43 + f62; f68 = f42 - f63; f69 = f42 + f63; f70 = f40 - f57; f71 = f40 + f57; f72 = f5 - f9; f73 = f5 + f9; f74 = f13 - f17; f75 = f13 + f17; f76 = f21 - f25; f77 = f21 + f25; f78 = MUL_F(FRAC_CONST(0.7071067811865476), f75); f79 = f1 - f78; f80 = f1 + f78; f81 = f73 + f77; f82 = MUL_C(COEF_CONST(1.3065629648763766), f73); f83 = MUL_F(FRAC_CONST(-0.9238795325112866), f81); f84 = MUL_F(FRAC_CONST(-0.5411961001461967), f77); f85 = f82 + f83; f86 = f84 - f83; f87 = f80 - f86; f88 = f80 + f86; f89 = f79 - f85; f90 = f79 + f85; f91 = MUL_F(FRAC_CONST(0.7071067811865476), f74); f92 = f29 - f91; f93 = f29 + f91; f94 = f76 + f72; f95 = MUL_C(COEF_CONST(1.3065629648763766), f76); f96 = MUL_F(FRAC_CONST(-0.9238795325112866), f94); f97 = MUL_F(FRAC_CONST(-0.5411961001461967), f72); f98 = f95 + f96; f99 = f97 - f96; f100 = f93 - f99; f101 = f93 + f99; f102 = f92 - f98; f103 = f92 + f98; f104 = f101 + f88; f105 = MUL_F(FRAC_CONST(-0.8971675863426361), f101); f106 = MUL_F(FRAC_CONST(0.9951847266721968), f104); f107 = MUL_C(COEF_CONST(1.0932018670017576), f88); f108 = f105 + f106; f109 = f107 - f106; f110 = f90 - f103; f111 = MUL_F(FRAC_CONST(-0.6666556584777466), f103); f112 = MUL_F(FRAC_CONST(0.9569403357322089), f110); f113 = MUL_C(COEF_CONST(1.2472250129866713), f90); f114 = f112 - f111; f115 = f113 - f112; f116 = f102 + f89; f117 = MUL_F(FRAC_CONST(-0.4105245275223571), f102); f118 = MUL_F(FRAC_CONST(0.8819212643483549), f116); f119 = MUL_C(COEF_CONST(1.3533180011743529), f89); f120 = f117 + f118; f121 = f119 - f118; f122 = f87 - f100; f123 = MUL_F(FRAC_CONST(-0.1386171691990915), f100); f124 = MUL_F(FRAC_CONST(0.7730104533627370), f122); f125 = MUL_C(COEF_CONST(1.4074037375263826), f87); f126 = f124 - f123; f127 = f125 - f124; f128 = f65 - f108; f129 = f65 + f108; f130 = f67 - f114; f131 = f67 + f114; f132 = f69 - f120; f133 = f69 + f120; f134 = f71 - f126; f135 = f71 + f126; f136 = f70 - f127; f137 = f70 + f127; f138 = f68 - f121; f139 = f68 + f121; f140 = f66 - f115; f141 = f66 + f115; f142 = f64 - f109; f143 = f64 + f109; f144 = f0 + f30; f145 = MUL_C(COEF_CONST(1.0478631305325901), f0); f146 = MUL_F(FRAC_CONST(-0.9987954562051724), f144); f147 = MUL_F(FRAC_CONST(-0.9497277818777548), f30); f148 = f145 + f146; f149 = f147 - f146; f150 = f4 + f26; f151 = MUL_F(FRAC_CONST(1.2130114330978077), f4); f152 = MUL_F(FRAC_CONST(-0.9700312531945440), f150); f153 = MUL_F(FRAC_CONST(-0.7270510732912803), f26); f154 = f151 + f152; f155 = f153 - f152; f156 = f8 + f22; f157 = MUL_C(COEF_CONST(1.3315443865537255), f8); f158 = MUL_F(FRAC_CONST(-0.9039892931234433), f156); f159 = MUL_F(FRAC_CONST(-0.4764341996931612), f22); f160 = f157 + f158; f161 = f159 - f158; f162 = f12 + f18; f163 = MUL_C(COEF_CONST(1.3989068359730781), f12); f164 = MUL_F(FRAC_CONST(-0.8032075314806453), f162); f165 = MUL_F(FRAC_CONST(-0.2075082269882124), f18); f166 = f163 + f164; f167 = f165 - f164; f168 = f16 + f14; f169 = MUL_C(COEF_CONST(1.4125100802019777), f16); f170 = MUL_F(FRAC_CONST(-0.6715589548470187), f168); f171 = MUL_F(FRAC_CONST(0.0693921705079402), f14); f172 = f169 + f170; f173 = f171 - f170; f174 = f20 + f10; f175 = MUL_C(COEF_CONST(1.3718313541934939), f20); f176 = MUL_F(FRAC_CONST(-0.5141027441932219), f174); f177 = MUL_F(FRAC_CONST(0.3436258658070501), f10); f178 = f175 + f176; f179 = f177 - f176; f180 = f24 + f6; f181 = MUL_C(COEF_CONST(1.2784339185752409), f24); f182 = MUL_F(FRAC_CONST(-0.3368898533922200), f180); f183 = MUL_F(FRAC_CONST(0.6046542117908008), f6); f184 = f181 + f182; f185 = f183 - f182; f186 = f28 + f2; f187 = MUL_C(COEF_CONST(1.1359069844201433), f28); f188 = MUL_F(FRAC_CONST(-0.1467304744553624), f186); f189 = MUL_F(FRAC_CONST(0.8424460355094185), f2); f190 = f187 + f188; f191 = f189 - f188; f192 = f149 - f173; f193 = f149 + f173; f194 = f148 - f172; f195 = f148 + f172; f196 = f155 - f179; f197 = f155 + f179; f198 = f154 - f178; f199 = f154 + f178; f200 = f161 - f185; f201 = f161 + f185; f202 = f160 - f184; f203 = f160 + f184; f204 = f167 - f191; f205 = f167 + f191; f206 = f166 - f190; f207 = f166 + f190; f208 = f192 + f194; f209 = MUL_C(COEF_CONST(1.1758756024193588), f192); f210 = MUL_F(FRAC_CONST(-0.9807852804032304), f208); f211 = MUL_F(FRAC_CONST(-0.7856949583871021), f194); f212 = f209 + f210; f213 = f211 - f210; f214 = f196 + f198; f215 = MUL_C(COEF_CONST(1.3870398453221475), f196); f216 = MUL_F(FRAC_CONST(-0.5555702330196022), f214); f217 = MUL_F(FRAC_CONST(0.2758993792829431), f198); f218 = f215 + f216; f219 = f217 - f216; f220 = f200 + f202; f221 = MUL_F(FRAC_CONST(0.7856949583871022), f200); f222 = MUL_F(FRAC_CONST(0.1950903220161283), f220); f223 = MUL_C(COEF_CONST(1.1758756024193586), f202); f224 = f221 + f222; f225 = f223 - f222; f226 = f204 + f206; f227 = MUL_F(FRAC_CONST(-0.2758993792829430), f204); f228 = MUL_F(FRAC_CONST(0.8314696123025452), f226); f229 = MUL_C(COEF_CONST(1.3870398453221475), f206); f230 = f227 + f228; f231 = f229 - f228; f232 = f193 - f201; f233 = f193 + f201; f234 = f195 - f203; f235 = f195 + f203; f236 = f197 - f205; f237 = f197 + f205; f238 = f199 - f207; f239 = f199 + f207; f240 = f213 - f225; f241 = f213 + f225; f242 = f212 - f224; f243 = f212 + f224; f244 = f219 - f231; f245 = f219 + f231; f246 = f218 - f230; f247 = f218 + f230; f248 = f232 + f234; f249 = MUL_C(COEF_CONST(1.3065629648763766), f232); f250 = MUL_F(FRAC_CONST(-0.9238795325112866), f248); f251 = MUL_F(FRAC_CONST(-0.5411961001461967), f234); f252 = f249 + f250; f253 = f251 - f250; f254 = f236 + f238; f255 = MUL_F(FRAC_CONST(0.5411961001461969), f236); f256 = MUL_F(FRAC_CONST(0.3826834323650898), f254); f257 = MUL_C(COEF_CONST(1.3065629648763766), f238); f258 = f255 + f256; f259 = f257 - f256; f260 = f240 + f242; f261 = MUL_C(COEF_CONST(1.3065629648763766), f240); f262 = MUL_F(FRAC_CONST(-0.9238795325112866), f260); f263 = MUL_F(FRAC_CONST(-0.5411961001461967), f242); f264 = f261 + f262; f265 = f263 - f262; f266 = f244 + f246; f267 = MUL_F(FRAC_CONST(0.5411961001461969), f244); f268 = MUL_F(FRAC_CONST(0.3826834323650898), f266); f269 = MUL_C(COEF_CONST(1.3065629648763766), f246); f270 = f267 + f268; f271 = f269 - f268; f272 = f233 - f237; f273 = f233 + f237; f274 = f235 - f239; f275 = f235 + f239; f276 = f253 - f259; f277 = f253 + f259; f278 = f252 - f258; f279 = f252 + f258; f280 = f241 - f245; f281 = f241 + f245; f282 = f243 - f247; f283 = f243 + f247; f284 = f265 - f271; f285 = f265 + f271; f286 = f264 - f270; f287 = f264 + f270; f288 = f272 - f274; f289 = f272 + f274; f290 = MUL_F(FRAC_CONST(0.7071067811865474), f288); f291 = MUL_F(FRAC_CONST(0.7071067811865474), f289); f292 = f276 - f278; f293 = f276 + f278; f294 = MUL_F(FRAC_CONST(0.7071067811865474), f292); f295 = MUL_F(FRAC_CONST(0.7071067811865474), f293); f296 = f280 - f282; f297 = f280 + f282; f298 = MUL_F(FRAC_CONST(0.7071067811865474), f296); f299 = MUL_F(FRAC_CONST(0.7071067811865474), f297); f300 = f284 - f286; f301 = f284 + f286; f302 = MUL_F(FRAC_CONST(0.7071067811865474), f300); f303 = MUL_F(FRAC_CONST(0.7071067811865474), f301); f304 = f129 - f273; f305 = f129 + f273; f306 = f131 - f281; f307 = f131 + f281; f308 = f133 - f285; f309 = f133 + f285; f310 = f135 - f277; f311 = f135 + f277; f312 = f137 - f295; f313 = f137 + f295; f314 = f139 - f303; f315 = f139 + f303; f316 = f141 - f299; f317 = f141 + f299; f318 = f143 - f291; f319 = f143 + f291; f320 = f142 - f290; f321 = f142 + f290; f322 = f140 - f298; f323 = f140 + f298; f324 = f138 - f302; f325 = f138 + f302; f326 = f136 - f294; f327 = f136 + f294; f328 = f134 - f279; f329 = f134 + f279; f330 = f132 - f287; f331 = f132 + f287; f332 = f130 - f283; f333 = f130 + f283; f334 = f128 - f275; f335 = f128 + f275; y[31] = MUL_F(FRAC_CONST(0.5001506360206510), f305); y[30] = MUL_F(FRAC_CONST(0.5013584524464084), f307); y[29] = MUL_F(FRAC_CONST(0.5037887256810443), f309); y[28] = MUL_F(FRAC_CONST(0.5074711720725553), f311); y[27] = MUL_F(FRAC_CONST(0.5124514794082247), f313); y[26] = MUL_F(FRAC_CONST(0.5187927131053328), f315); y[25] = MUL_F(FRAC_CONST(0.5265773151542700), f317); y[24] = MUL_F(FRAC_CONST(0.5359098169079920), f319); y[23] = MUL_F(FRAC_CONST(0.5469204379855088), f321); y[22] = MUL_F(FRAC_CONST(0.5597698129470802), f323); y[21] = MUL_F(FRAC_CONST(0.5746551840326600), f325); y[20] = MUL_F(FRAC_CONST(0.5918185358574165), f327); y[19] = MUL_F(FRAC_CONST(0.6115573478825099), f329); y[18] = MUL_F(FRAC_CONST(0.6342389366884031), f331); y[17] = MUL_F(FRAC_CONST(0.6603198078137061), f333); y[16] = MUL_F(FRAC_CONST(0.6903721282002123), f335); y[15] = MUL_F(FRAC_CONST(0.7251205223771985), f334); y[14] = MUL_F(FRAC_CONST(0.7654941649730891), f332); y[13] = MUL_F(FRAC_CONST(0.8127020908144905), f330); y[12] = MUL_F(FRAC_CONST(0.8683447152233481), f328); y[11] = MUL_F(FRAC_CONST(0.9345835970364075), f326); y[10] = MUL_C(COEF_CONST(1.0144082649970547), f324); y[9] = MUL_C(COEF_CONST(1.1120716205797176), f322); y[8] = MUL_C(COEF_CONST(1.2338327379765710), f320); y[7] = MUL_C(COEF_CONST(1.3892939586328277), f318); y[6] = MUL_C(COEF_CONST(1.5939722833856311), f316); y[5] = MUL_C(COEF_CONST(1.8746759800084078), f314); y[4] = MUL_C(COEF_CONST(2.2820500680051619), f312); y[3] = MUL_C(COEF_CONST(2.9246284281582162), f310); y[2] = MUL_C(COEF_CONST(4.0846110781292477), f308); y[1] = MUL_C(COEF_CONST(6.7967507116736332), f306); y[0] = MUL_R(REAL_CONST(20.3738781672314530), f304); } #ifdef SBR_LOW_POWER void DCT2_16_unscaled(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10; real_t f11, f12, f13, f14, f15, f16, f17, f18, f19, f20; real_t f21, f22, f23, f24, f25, f26, f27, f28, f31, f32; real_t f33, f34, f37, f38, f39, f40, f41, f42, f43, f44; real_t f45, f46, f47, f48, f49, f51, f53, f54, f57, f58; real_t f59, f60, f61, f62, f63, f64, f65, f66, f67, f68; real_t f69, f70, f71, f72, f73, f74, f75, f76, f77, f78; real_t f79, f80, f81, f82, f83, f84, f85, f86, f87, f88; real_t f89, f90, f91, f92, f95, f96, f97, f98, f101, f102; real_t f103, f104, f107, f108, f109, f110; f0 = x[0] - x[15]; f1 = x[0] + x[15]; f2 = x[1] - x[14]; f3 = x[1] + x[14]; f4 = x[2] - x[13]; f5 = x[2] + x[13]; f6 = x[3] - x[12]; f7 = x[3] + x[12]; f8 = x[4] - x[11]; f9 = x[4] + x[11]; f10 = x[5] - x[10]; f11 = x[5] + x[10]; f12 = x[6] - x[9]; f13 = x[6] + x[9]; f14 = x[7] - x[8]; f15 = x[7] + x[8]; f16 = f1 - f15; f17 = f1 + f15; f18 = f3 - f13; f19 = f3 + f13; f20 = f5 - f11; f21 = f5 + f11; f22 = f7 - f9; f23 = f7 + f9; f24 = f17 - f23; f25 = f17 + f23; f26 = f19 - f21; f27 = f19 + f21; f28 = f25 - f27; y[0] = f25 + f27; y[8] = MUL_F(f28, FRAC_CONST(0.7071067811865476)); f31 = f24 + f26; f32 = MUL_C(f24, COEF_CONST(1.3065629648763766)); f33 = MUL_F(f31, FRAC_CONST(-0.9238795325112866)); f34 = MUL_F(f26, FRAC_CONST(-0.5411961001461967)); y[12] = f32 + f33; y[4] = f34 - f33; f37 = f16 + f22; f38 = MUL_C(f16, COEF_CONST(1.1758756024193588)); f39 = MUL_F(f37, FRAC_CONST(-0.9807852804032304)); f40 = MUL_F(f22, FRAC_CONST(-0.7856949583871021)); f41 = f38 + f39; f42 = f40 - f39; f43 = f18 + f20; f44 = MUL_C(f18, COEF_CONST(1.3870398453221473)); f45 = MUL_F(f43, FRAC_CONST(-0.8314696123025455)); f46 = MUL_F(f20, FRAC_CONST(-0.2758993792829436)); f47 = f44 + f45; f48 = f46 - f45; f49 = f42 - f48; y[2] = f42 + f48; f51 = MUL_F(f49, FRAC_CONST(0.7071067811865476)); y[14] = f41 - f47; f53 = f41 + f47; f54 = MUL_F(f53, FRAC_CONST(0.7071067811865476)); y[10] = f51 - f54; y[6] = f51 + f54; f57 = f2 - f4; f58 = f2 + f4; f59 = f6 - f8; f60 = f6 + f8; f61 = f10 - f12; f62 = f10 + f12; f63 = MUL_F(f60, FRAC_CONST(0.7071067811865476)); f64 = f0 - f63; f65 = f0 + f63; f66 = f58 + f62; f67 = MUL_C(f58, COEF_CONST(1.3065629648763766)); f68 = MUL_F(f66, FRAC_CONST(-0.9238795325112866)); f69 = MUL_F(f62, FRAC_CONST(-0.5411961001461967)); f70 = f67 + f68; f71 = f69 - f68; f72 = f65 - f71; f73 = f65 + f71; f74 = f64 - f70; f75 = f64 + f70; f76 = MUL_F(f59, FRAC_CONST(0.7071067811865476)); f77 = f14 - f76; f78 = f14 + f76; f79 = f61 + f57; f80 = MUL_C(f61, COEF_CONST(1.3065629648763766)); f81 = MUL_F(f79, FRAC_CONST(-0.9238795325112866)); f82 = MUL_F(f57, FRAC_CONST(-0.5411961001461967)); f83 = f80 + f81; f84 = f82 - f81; f85 = f78 - f84; f86 = f78 + f84; f87 = f77 - f83; f88 = f77 + f83; f89 = f86 + f73; f90 = MUL_F(f86, FRAC_CONST(-0.8971675863426361)); f91 = MUL_F(f89, FRAC_CONST(0.9951847266721968)); f92 = MUL_C(f73, COEF_CONST(1.0932018670017576)); y[1] = f90 + f91; y[15] = f92 - f91; f95 = f75 - f88; f96 = MUL_F(f88, FRAC_CONST(-0.6666556584777466)); f97 = MUL_F(f95, FRAC_CONST(0.9569403357322089)); f98 = MUL_C(f75, COEF_CONST(1.2472250129866713)); y[3] = f97 - f96; y[13] = f98 - f97; f101 = f87 + f74; f102 = MUL_F(f87, FRAC_CONST(-0.4105245275223571)); f103 = MUL_F(f101, FRAC_CONST(0.8819212643483549)); f104 = MUL_C(f74, COEF_CONST(1.3533180011743529)); y[5] = f102 + f103; y[11] = f104 - f103; f107 = f72 - f85; f108 = MUL_F(f85, FRAC_CONST(-0.1386171691990915)); f109 = MUL_F(f107, FRAC_CONST(0.7730104533627370)); f110 = MUL_C(f72, COEF_CONST(1.4074037375263826)); y[7] = f109 - f108; y[9] = f110 - f109; } void DCT4_16(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10; real_t f11, f12, f13, f14, f15, f16, f17, f18, f19, f20; real_t f21, f22, f23, f24, f25, f26, f27, f28, f29, f30; real_t f31, f32, f33, f34, f35, f36, f37, f38, f39, f40; real_t f41, f42, f43, f44, f45, f46, f47, f48, f49, f50; real_t f51, f52, f53, f54, f55, f56, f57, f58, f59, f60; real_t f61, f62, f63, f64, f65, f66, f67, f68, f69, f70; real_t f71, f72, f73, f74, f75, f76, f77, f78, f79, f80; real_t f81, f82, f83, f84, f85, f86, f87, f88, f89, f90; real_t f91, f92, f93, f94, f95, f96, f97, f98, f99, f100; real_t f101, f102, f103, f104, f105, f106, f107, f108, f109, f110; real_t f111, f112, f113, f114, f115, f116, f117, f118, f119, f120; real_t f121, f122, f123, f124, f125, f126, f127, f128, f130, f132; real_t f134, f136, f138, f140, f142, f144, f145, f148, f149, f152; real_t f153, f156, f157; f0 = x[0] + x[15]; f1 = MUL_C(COEF_CONST(1.0478631305325901), x[0]); f2 = MUL_F(FRAC_CONST(-0.9987954562051724), f0); f3 = MUL_F(FRAC_CONST(-0.9497277818777548), x[15]); f4 = f1 + f2; f5 = f3 - f2; f6 = x[2] + x[13]; f7 = MUL_C(COEF_CONST(1.2130114330978077), x[2]); f8 = MUL_F(FRAC_CONST(-0.9700312531945440), f6); f9 = MUL_F(FRAC_CONST(-0.7270510732912803), x[13]); f10 = f7 + f8; f11 = f9 - f8; f12 = x[4] + x[11]; f13 = MUL_C(COEF_CONST(1.3315443865537255), x[4]); f14 = MUL_F(FRAC_CONST(-0.9039892931234433), f12); f15 = MUL_F(FRAC_CONST(-0.4764341996931612), x[11]); f16 = f13 + f14; f17 = f15 - f14; f18 = x[6] + x[9]; f19 = MUL_C(COEF_CONST(1.3989068359730781), x[6]); f20 = MUL_F(FRAC_CONST(-0.8032075314806453), f18); f21 = MUL_F(FRAC_CONST(-0.2075082269882124), x[9]); f22 = f19 + f20; f23 = f21 - f20; f24 = x[8] + x[7]; f25 = MUL_C(COEF_CONST(1.4125100802019777), x[8]); f26 = MUL_F(FRAC_CONST(-0.6715589548470187), f24); f27 = MUL_F(FRAC_CONST(0.0693921705079402), x[7]); f28 = f25 + f26; f29 = f27 - f26; f30 = x[10] + x[5]; f31 = MUL_C(COEF_CONST(1.3718313541934939), x[10]); f32 = MUL_F(FRAC_CONST(-0.5141027441932219), f30); f33 = MUL_F(FRAC_CONST(0.3436258658070501), x[5]); f34 = f31 + f32; f35 = f33 - f32; f36 = x[12] + x[3]; f37 = MUL_C(COEF_CONST(1.2784339185752409), x[12]); f38 = MUL_F(FRAC_CONST(-0.3368898533922200), f36); f39 = MUL_F(FRAC_CONST(0.6046542117908008), x[3]); f40 = f37 + f38; f41 = f39 - f38; f42 = x[14] + x[1]; f43 = MUL_C(COEF_CONST(1.1359069844201433), x[14]); f44 = MUL_F(FRAC_CONST(-0.1467304744553624), f42); f45 = MUL_F(FRAC_CONST(0.8424460355094185), x[1]); f46 = f43 + f44; f47 = f45 - f44; f48 = f5 - f29; f49 = f5 + f29; f50 = f4 - f28; f51 = f4 + f28; f52 = f11 - f35; f53 = f11 + f35; f54 = f10 - f34; f55 = f10 + f34; f56 = f17 - f41; f57 = f17 + f41; f58 = f16 - f40; f59 = f16 + f40; f60 = f23 - f47; f61 = f23 + f47; f62 = f22 - f46; f63 = f22 + f46; f64 = f48 + f50; f65 = MUL_C(COEF_CONST(1.1758756024193588), f48); f66 = MUL_F(FRAC_CONST(-0.9807852804032304), f64); f67 = MUL_F(FRAC_CONST(-0.7856949583871021), f50); f68 = f65 + f66; f69 = f67 - f66; f70 = f52 + f54; f71 = MUL_C(COEF_CONST(1.3870398453221475), f52); f72 = MUL_F(FRAC_CONST(-0.5555702330196022), f70); f73 = MUL_F(FRAC_CONST(0.2758993792829431), f54); f74 = f71 + f72; f75 = f73 - f72; f76 = f56 + f58; f77 = MUL_F(FRAC_CONST(0.7856949583871022), f56); f78 = MUL_F(FRAC_CONST(0.1950903220161283), f76); f79 = MUL_C(COEF_CONST(1.1758756024193586), f58); f80 = f77 + f78; f81 = f79 - f78; f82 = f60 + f62; f83 = MUL_F(FRAC_CONST(-0.2758993792829430), f60); f84 = MUL_F(FRAC_CONST(0.8314696123025452), f82); f85 = MUL_C(COEF_CONST(1.3870398453221475), f62); f86 = f83 + f84; f87 = f85 - f84; f88 = f49 - f57; f89 = f49 + f57; f90 = f51 - f59; f91 = f51 + f59; f92 = f53 - f61; f93 = f53 + f61; f94 = f55 - f63; f95 = f55 + f63; f96 = f69 - f81; f97 = f69 + f81; f98 = f68 - f80; f99 = f68 + f80; f100 = f75 - f87; f101 = f75 + f87; f102 = f74 - f86; f103 = f74 + f86; f104 = f88 + f90; f105 = MUL_C(COEF_CONST(1.3065629648763766), f88); f106 = MUL_F(FRAC_CONST(-0.9238795325112866), f104); f107 = MUL_F(FRAC_CONST(-0.5411961001461967), f90); f108 = f105 + f106; f109 = f107 - f106; f110 = f92 + f94; f111 = MUL_F(FRAC_CONST(0.5411961001461969), f92); f112 = MUL_F(FRAC_CONST(0.3826834323650898), f110); f113 = MUL_C(COEF_CONST(1.3065629648763766), f94); f114 = f111 + f112; f115 = f113 - f112; f116 = f96 + f98; f117 = MUL_C(COEF_CONST(1.3065629648763766), f96); f118 = MUL_F(FRAC_CONST(-0.9238795325112866), f116); f119 = MUL_F(FRAC_CONST(-0.5411961001461967), f98); f120 = f117 + f118; f121 = f119 - f118; f122 = f100 + f102; f123 = MUL_F(FRAC_CONST(0.5411961001461969), f100); f124 = MUL_F(FRAC_CONST(0.3826834323650898), f122); f125 = MUL_C(COEF_CONST(1.3065629648763766), f102); f126 = f123 + f124; f127 = f125 - f124; f128 = f89 - f93; y[0] = f89 + f93; f130 = f91 - f95; y[15] = f91 + f95; f132 = f109 - f115; y[3] = f109 + f115; f134 = f108 - f114; y[12] = f108 + f114; f136 = f97 - f101; y[1] = f97 + f101; f138 = f99 - f103; y[14] = f99 + f103; f140 = f121 - f127; y[2] = f121 + f127; f142 = f120 - f126; y[13] = f120 + f126; f144 = f128 - f130; f145 = f128 + f130; y[8] = MUL_F(FRAC_CONST(0.7071067811865474), f144); y[7] = MUL_F(FRAC_CONST(0.7071067811865474), f145); f148 = f132 - f134; f149 = f132 + f134; y[11] = MUL_F(FRAC_CONST(0.7071067811865474), f148); y[4] = MUL_F(FRAC_CONST(0.7071067811865474), f149); f152 = f136 - f138; f153 = f136 + f138; y[9] = MUL_F(FRAC_CONST(0.7071067811865474), f152); y[6] = MUL_F(FRAC_CONST(0.7071067811865474), f153); f156 = f140 - f142; f157 = f140 + f142; y[10] = MUL_F(FRAC_CONST(0.7071067811865474), f156); y[5] = MUL_F(FRAC_CONST(0.7071067811865474), f157); } void DCT3_32_unscaled(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10; real_t f11, f12, f13, f14, f15, f16, f17, f18, f19, f20; real_t f21, f22, f23, f24, f25, f26, f27, f28, f29, f30; real_t f31, f32, f33, f34, f35, f36, f37, f38, f39, f40; real_t f41, f42, f43, f44, f45, f46, f47, f48, f49, f50; real_t f51, f52, f53, f54, f55, f56, f57, f58, f59, f60; real_t f61, f62, f63, f64, f65, f66, f67, f68, f69, f70; real_t f71, f72, f73, f74, f75, f76, f77, f78, f79, f80; real_t f81, f82, f83, f84, f85, f86, f87, f88, f89, f90; real_t f91, f92, f93, f94, f95, f96, f97, f98, f99, f100; real_t f101, f102, f103, f104, f105, f106, f107, f108, f109, f110; real_t f111, f112, f113, f114, f115, f116, f117, f118, f119, f120; real_t f121, f122, f123, f124, f125, f126, f127, f128, f129, f130; real_t f131, f132, f133, f134, f135, f136, f137, f138, f139, f140; real_t f141, f142, f143, f144, f145, f146, f147, f148, f149, f150; real_t f151, f152, f153, f154, f155, f156, f157, f158, f159, f160; real_t f161, f162, f163, f164, f165, f166, f167, f168, f169, f170; real_t f171, f172, f173, f174, f175, f176, f177, f178, f179, f180; real_t f181, f182, f183, f184, f185, f186, f187, f188, f189, f190; real_t f191, f192, f193, f194, f195, f196, f197, f198, f199, f200; real_t f201, f202, f203, f204, f205, f206, f207, f208, f209, f210; real_t f211, f212, f213, f214, f215, f216, f217, f218, f219, f220; real_t f221, f222, f223, f224, f225, f226, f227, f228, f229, f230; real_t f231, f232, f233, f234, f235, f236, f237, f238, f239, f240; real_t f241, f242, f243, f244, f245, f246, f247, f248, f249, f250; real_t f251, f252, f253, f254, f255, f256, f257, f258, f259, f260; real_t f261, f262, f263, f264, f265, f266, f267, f268, f269, f270; real_t f271, f272; f0 = MUL_F(x[16], FRAC_CONST(0.7071067811865476)); f1 = x[0] - f0; f2 = x[0] + f0; f3 = x[8] + x[24]; f4 = MUL_C(x[8], COEF_CONST(1.3065629648763766)); f5 = MUL_F(f3, FRAC_CONST((-0.9238795325112866))); f6 = MUL_F(x[24], FRAC_CONST((-0.5411961001461967))); f7 = f4 + f5; f8 = f6 - f5; f9 = f2 - f8; f10 = f2 + f8; f11 = f1 - f7; f12 = f1 + f7; f13 = x[4] + x[28]; f14 = MUL_C(x[4], COEF_CONST(1.1758756024193588)); f15 = MUL_F(f13, FRAC_CONST((-0.9807852804032304))); f16 = MUL_F(x[28], FRAC_CONST((-0.7856949583871021))); f17 = f14 + f15; f18 = f16 - f15; f19 = x[12] + x[20]; f20 = MUL_C(x[12], COEF_CONST(1.3870398453221473)); f21 = MUL_F(f19, FRAC_CONST((-0.8314696123025455))); f22 = MUL_F(x[20], FRAC_CONST((-0.2758993792829436))); f23 = f20 + f21; f24 = f22 - f21; f25 = f18 - f24; f26 = f18 + f24; f27 = MUL_F(f25, FRAC_CONST(0.7071067811865476)); f28 = f17 - f23; f29 = f17 + f23; f30 = MUL_F(f29, FRAC_CONST(0.7071067811865476)); f31 = f27 - f30; f32 = f27 + f30; f33 = f10 - f26; f34 = f10 + f26; f35 = f12 - f32; f36 = f12 + f32; f37 = f11 - f31; f38 = f11 + f31; f39 = f9 - f28; f40 = f9 + f28; f41 = x[2] + x[30]; f42 = MUL_C(x[2], COEF_CONST(1.0932018670017569)); f43 = MUL_F(f41, FRAC_CONST((-0.9951847266721969))); f44 = MUL_F(x[30], FRAC_CONST((-0.8971675863426368))); f45 = f42 + f43; f46 = f44 - f43; f47 = x[6] + x[26]; f48 = MUL_C(x[6], COEF_CONST(1.2472250129866711)); f49 = MUL_F(f47, FRAC_CONST((-0.9569403357322089))); f50 = MUL_F(x[26], FRAC_CONST((-0.6666556584777469))); f51 = f48 + f49; f52 = f50 - f49; f53 = x[10] + x[22]; f54 = MUL_C(x[10], COEF_CONST(1.3533180011743526)); f55 = MUL_F(f53, FRAC_CONST((-0.8819212643483551))); f56 = MUL_F(x[22], FRAC_CONST((-0.4105245275223575))); f57 = f54 + f55; f58 = f56 - f55; f59 = x[14] + x[18]; f60 = MUL_C(x[14], COEF_CONST(1.4074037375263826)); f61 = MUL_F(f59, FRAC_CONST((-0.7730104533627369))); f62 = MUL_F(x[18], FRAC_CONST((-0.1386171691990913))); f63 = f60 + f61; f64 = f62 - f61; f65 = f46 - f64; f66 = f46 + f64; f67 = f52 - f58; f68 = f52 + f58; f69 = f66 - f68; f70 = f66 + f68; f71 = MUL_F(f69, FRAC_CONST(0.7071067811865476)); f72 = f65 + f67; f73 = MUL_C(f65, COEF_CONST(1.3065629648763766)); f74 = MUL_F(f72, FRAC_CONST((-0.9238795325112866))); f75 = MUL_F(f67, FRAC_CONST((-0.5411961001461967))); f76 = f73 + f74; f77 = f75 - f74; f78 = f45 - f63; f79 = f45 + f63; f80 = f51 - f57; f81 = f51 + f57; f82 = f79 + f81; f83 = MUL_C(f79, COEF_CONST(1.3065629648763770)); f84 = MUL_F(f82, FRAC_CONST((-0.3826834323650904))); f85 = MUL_F(f81, FRAC_CONST(0.5411961001461961)); f86 = f83 + f84; f87 = f85 - f84; f88 = f78 - f80; f89 = f78 + f80; f90 = MUL_F(f89, FRAC_CONST(0.7071067811865476)); f91 = f77 - f87; f92 = f77 + f87; f93 = f71 - f90; f94 = f71 + f90; f95 = f76 - f86; f96 = f76 + f86; f97 = f34 - f70; f98 = f34 + f70; f99 = f36 - f92; f100 = f36 + f92; f101 = f38 - f91; f102 = f38 + f91; f103 = f40 - f94; f104 = f40 + f94; f105 = f39 - f93; f106 = f39 + f93; f107 = f37 - f96; f108 = f37 + f96; f109 = f35 - f95; f110 = f35 + f95; f111 = f33 - f88; f112 = f33 + f88; f113 = x[1] + x[31]; f114 = MUL_C(x[1], COEF_CONST(1.0478631305325901)); f115 = MUL_F(f113, FRAC_CONST((-0.9987954562051724))); f116 = MUL_F(x[31], FRAC_CONST((-0.9497277818777548))); f117 = f114 + f115; f118 = f116 - f115; f119 = x[5] + x[27]; f120 = MUL_C(x[5], COEF_CONST(1.2130114330978077)); f121 = MUL_F(f119, FRAC_CONST((-0.9700312531945440))); f122 = MUL_F(x[27], FRAC_CONST((-0.7270510732912803))); f123 = f120 + f121; f124 = f122 - f121; f125 = x[9] + x[23]; f126 = MUL_C(x[9], COEF_CONST(1.3315443865537255)); f127 = MUL_F(f125, FRAC_CONST((-0.9039892931234433))); f128 = MUL_F(x[23], FRAC_CONST((-0.4764341996931612))); f129 = f126 + f127; f130 = f128 - f127; f131 = x[13] + x[19]; f132 = MUL_C(x[13], COEF_CONST(1.3989068359730781)); f133 = MUL_F(f131, FRAC_CONST((-0.8032075314806453))); f134 = MUL_F(x[19], FRAC_CONST((-0.2075082269882124))); f135 = f132 + f133; f136 = f134 - f133; f137 = x[17] + x[15]; f138 = MUL_C(x[17], COEF_CONST(1.4125100802019777)); f139 = MUL_F(f137, FRAC_CONST((-0.6715589548470187))); f140 = MUL_F(x[15], FRAC_CONST(0.0693921705079402)); f141 = f138 + f139; f142 = f140 - f139; f143 = x[21] + x[11]; f144 = MUL_C(x[21], COEF_CONST(1.3718313541934939)); f145 = MUL_F(f143, FRAC_CONST((-0.5141027441932219))); f146 = MUL_F(x[11], FRAC_CONST(0.3436258658070501)); f147 = f144 + f145; f148 = f146 - f145; f149 = x[25] + x[7]; f150 = MUL_C(x[25], COEF_CONST(1.2784339185752409)); f151 = MUL_F(f149, FRAC_CONST((-0.3368898533922200))); f152 = MUL_F(x[7], FRAC_CONST(0.6046542117908008)); f153 = f150 + f151; f154 = f152 - f151; f155 = x[29] + x[3]; f156 = MUL_C(x[29], COEF_CONST(1.1359069844201433)); f157 = MUL_F(f155, FRAC_CONST((-0.1467304744553624))); f158 = MUL_F(x[3], FRAC_CONST(0.8424460355094185)); f159 = f156 + f157; f160 = f158 - f157; f161 = f118 - f142; f162 = f118 + f142; f163 = f117 - f141; f164 = f117 + f141; f165 = f124 - f148; f166 = f124 + f148; f167 = f123 - f147; f168 = f123 + f147; f169 = f130 - f154; f170 = f130 + f154; f171 = f129 - f153; f172 = f129 + f153; f173 = f136 - f160; f174 = f136 + f160; f175 = f135 - f159; f176 = f135 + f159; f177 = f161 + f163; f178 = MUL_C(f161, COEF_CONST(1.1758756024193588)); f179 = MUL_F(f177, FRAC_CONST((-0.9807852804032304))); f180 = MUL_F(f163, FRAC_CONST((-0.7856949583871021))); f181 = f178 + f179; f182 = f180 - f179; f183 = f165 + f167; f184 = MUL_C(f165, COEF_CONST(1.3870398453221475)); f185 = MUL_F(f183, FRAC_CONST((-0.5555702330196022))); f186 = MUL_F(f167, FRAC_CONST(0.2758993792829431)); f187 = f184 + f185; f188 = f186 - f185; f189 = f169 + f171; f190 = MUL_F(f169, FRAC_CONST(0.7856949583871022)); f191 = MUL_F(f189, FRAC_CONST(0.1950903220161283)); f192 = MUL_C(f171, COEF_CONST(1.1758756024193586)); f193 = f190 + f191; f194 = f192 - f191; f195 = f173 + f175; f196 = MUL_F(f173, FRAC_CONST((-0.2758993792829430))); f197 = MUL_F(f195, FRAC_CONST(0.8314696123025452)); f198 = MUL_C(f175, COEF_CONST(1.3870398453221475)); f199 = f196 + f197; f200 = f198 - f197; f201 = f162 - f170; f202 = f162 + f170; f203 = f164 - f172; f204 = f164 + f172; f205 = f166 - f174; f206 = f166 + f174; f207 = f168 - f176; f208 = f168 + f176; f209 = f182 - f194; f210 = f182 + f194; f211 = f181 - f193; f212 = f181 + f193; f213 = f188 - f200; f214 = f188 + f200; f215 = f187 - f199; f216 = f187 + f199; f217 = f201 + f203; f218 = MUL_C(f201, COEF_CONST(1.3065629648763766)); f219 = MUL_F(f217, FRAC_CONST((-0.9238795325112866))); f220 = MUL_F(f203, FRAC_CONST((-0.5411961001461967))); f221 = f218 + f219; f222 = f220 - f219; f223 = f205 + f207; f224 = MUL_F(f205, FRAC_CONST(0.5411961001461969)); f225 = MUL_F(f223, FRAC_CONST(0.3826834323650898)); f226 = MUL_C(f207, COEF_CONST(1.3065629648763766)); f227 = f224 + f225; f228 = f226 - f225; f229 = f209 + f211; f230 = MUL_C(f209, COEF_CONST(1.3065629648763766)); f231 = MUL_F(f229, FRAC_CONST((-0.9238795325112866))); f232 = MUL_F(f211, FRAC_CONST((-0.5411961001461967))); f233 = f230 + f231; f234 = f232 - f231; f235 = f213 + f215; f236 = MUL_F(f213, FRAC_CONST(0.5411961001461969)); f237 = MUL_F(f235, FRAC_CONST(0.3826834323650898)); f238 = MUL_C(f215, COEF_CONST(1.3065629648763766)); f239 = f236 + f237; f240 = f238 - f237; f241 = f202 - f206; f242 = f202 + f206; f243 = f204 - f208; f244 = f204 + f208; f245 = f222 - f228; f246 = f222 + f228; f247 = f221 - f227; f248 = f221 + f227; f249 = f210 - f214; f250 = f210 + f214; f251 = f212 - f216; f252 = f212 + f216; f253 = f234 - f240; f254 = f234 + f240; f255 = f233 - f239; f256 = f233 + f239; f257 = f241 - f243; f258 = f241 + f243; f259 = MUL_F(f257, FRAC_CONST(0.7071067811865474)); f260 = MUL_F(f258, FRAC_CONST(0.7071067811865474)); f261 = f245 - f247; f262 = f245 + f247; f263 = MUL_F(f261, FRAC_CONST(0.7071067811865474)); f264 = MUL_F(f262, FRAC_CONST(0.7071067811865474)); f265 = f249 - f251; f266 = f249 + f251; f267 = MUL_F(f265, FRAC_CONST(0.7071067811865474)); f268 = MUL_F(f266, FRAC_CONST(0.7071067811865474)); f269 = f253 - f255; f270 = f253 + f255; f271 = MUL_F(f269, FRAC_CONST(0.7071067811865474)); f272 = MUL_F(f270, FRAC_CONST(0.7071067811865474)); y[31] = f98 - f242; y[0] = f98 + f242; y[30] = f100 - f250; y[1] = f100 + f250; y[29] = f102 - f254; y[2] = f102 + f254; y[28] = f104 - f246; y[3] = f104 + f246; y[27] = f106 - f264; y[4] = f106 + f264; y[26] = f108 - f272; y[5] = f108 + f272; y[25] = f110 - f268; y[6] = f110 + f268; y[24] = f112 - f260; y[7] = f112 + f260; y[23] = f111 - f259; y[8] = f111 + f259; y[22] = f109 - f267; y[9] = f109 + f267; y[21] = f107 - f271; y[10] = f107 + f271; y[20] = f105 - f263; y[11] = f105 + f263; y[19] = f103 - f248; y[12] = f103 + f248; y[18] = f101 - f256; y[13] = f101 + f256; y[17] = f99 - f252; y[14] = f99 + f252; y[16] = f97 - f244; y[15] = f97 + f244; } void DCT2_32_unscaled(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10; real_t f11, f12, f13, f14, f15, f16, f17, f18, f19, f20; real_t f21, f22, f23, f24, f25, f26, f27, f28, f29, f30; real_t f31, f32, f33, f34, f35, f36, f37, f38, f39, f40; real_t f41, f42, f43, f44, f45, f46, f47, f48, f49, f50; real_t f51, f52, f53, f54, f55, f56, f57, f58, f59, f60; real_t f63, f64, f65, f66, f69, f70, f71, f72, f73, f74; real_t f75, f76, f77, f78, f79, f80, f81, f83, f85, f86; real_t f89, f90, f91, f92, f93, f94, f95, f96, f97, f98; real_t f99, f100, f101, f102, f103, f104, f105, f106, f107, f108; real_t f109, f110, f111, f112, f113, f114, f115, f116, f117, f118; real_t f119, f120, f121, f122, f123, f124, f127, f128, f129, f130; real_t f133, f134, f135, f136, f139, f140, f141, f142, f145, f146; real_t f147, f148, f149, f150, f151, f152, f153, f154, f155, f156; real_t f157, f158, f159, f160, f161, f162, f163, f164, f165, f166; real_t f167, f168, f169, f170, f171, f172, f173, f174, f175, f176; real_t f177, f178, f179, f180, f181, f182, f183, f184, f185, f186; real_t f187, f188, f189, f190, f191, f192, f193, f194, f195, f196; real_t f197, f198, f199, f200, f201, f202, f203, f204, f205, f206; real_t f207, f208, f209, f210, f211, f212, f213, f214, f215, f216; real_t f217, f218, f219, f220, f221, f222, f223, f224, f225, f226; real_t f227, f228, f229, f230, f231, f232, f233, f234, f235, f236; real_t f237, f238, f239, f240, f241, f242, f243, f244, f247, f248; real_t f249, f250, f253, f254, f255, f256, f259, f260, f261, f262; real_t f265, f266, f267, f268, f271, f272, f273, f274, f277, f278; real_t f279, f280, f283, f284, f285, f286; f0 = x[0] - x[31]; f1 = x[0] + x[31]; f2 = x[1] - x[30]; f3 = x[1] + x[30]; f4 = x[2] - x[29]; f5 = x[2] + x[29]; f6 = x[3] - x[28]; f7 = x[3] + x[28]; f8 = x[4] - x[27]; f9 = x[4] + x[27]; f10 = x[5] - x[26]; f11 = x[5] + x[26]; f12 = x[6] - x[25]; f13 = x[6] + x[25]; f14 = x[7] - x[24]; f15 = x[7] + x[24]; f16 = x[8] - x[23]; f17 = x[8] + x[23]; f18 = x[9] - x[22]; f19 = x[9] + x[22]; f20 = x[10] - x[21]; f21 = x[10] + x[21]; f22 = x[11] - x[20]; f23 = x[11] + x[20]; f24 = x[12] - x[19]; f25 = x[12] + x[19]; f26 = x[13] - x[18]; f27 = x[13] + x[18]; f28 = x[14] - x[17]; f29 = x[14] + x[17]; f30 = x[15] - x[16]; f31 = x[15] + x[16]; f32 = f1 - f31; f33 = f1 + f31; f34 = f3 - f29; f35 = f3 + f29; f36 = f5 - f27; f37 = f5 + f27; f38 = f7 - f25; f39 = f7 + f25; f40 = f9 - f23; f41 = f9 + f23; f42 = f11 - f21; f43 = f11 + f21; f44 = f13 - f19; f45 = f13 + f19; f46 = f15 - f17; f47 = f15 + f17; f48 = f33 - f47; f49 = f33 + f47; f50 = f35 - f45; f51 = f35 + f45; f52 = f37 - f43; f53 = f37 + f43; f54 = f39 - f41; f55 = f39 + f41; f56 = f49 - f55; f57 = f49 + f55; f58 = f51 - f53; f59 = f51 + f53; f60 = f57 - f59; y[0] = f57 + f59; y[16] = MUL_F(FRAC_CONST(0.7071067811865476), f60); f63 = f56 + f58; f64 = MUL_C(COEF_CONST(1.3065629648763766), f56); f65 = MUL_F(FRAC_CONST(-0.9238795325112866), f63); f66 = MUL_F(FRAC_CONST(-0.5411961001461967), f58); y[24] = f64 + f65; y[8] = f66 - f65; f69 = f48 + f54; f70 = MUL_C(COEF_CONST(1.1758756024193588), f48); f71 = MUL_F(FRAC_CONST(-0.9807852804032304), f69); f72 = MUL_F(FRAC_CONST(-0.7856949583871021), f54); f73 = f70 + f71; f74 = f72 - f71; f75 = f50 + f52; f76 = MUL_C(COEF_CONST(1.3870398453221473), f50); f77 = MUL_F(FRAC_CONST(-0.8314696123025455), f75); f78 = MUL_F(FRAC_CONST(-0.2758993792829436), f52); f79 = f76 + f77; f80 = f78 - f77; f81 = f74 - f80; y[4] = f74 + f80; f83 = MUL_F(FRAC_CONST(0.7071067811865476), f81); y[28] = f73 - f79; f85 = f73 + f79; f86 = MUL_F(FRAC_CONST(0.7071067811865476), f85); y[20] = f83 - f86; y[12] = f83 + f86; f89 = f34 - f36; f90 = f34 + f36; f91 = f38 - f40; f92 = f38 + f40; f93 = f42 - f44; f94 = f42 + f44; f95 = MUL_F(FRAC_CONST(0.7071067811865476), f92); f96 = f32 - f95; f97 = f32 + f95; f98 = f90 + f94; f99 = MUL_C(COEF_CONST(1.3065629648763766), f90); f100 = MUL_F(FRAC_CONST(-0.9238795325112866), f98); f101 = MUL_F(FRAC_CONST(-0.5411961001461967), f94); f102 = f99 + f100; f103 = f101 - f100; f104 = f97 - f103; f105 = f97 + f103; f106 = f96 - f102; f107 = f96 + f102; f108 = MUL_F(FRAC_CONST(0.7071067811865476), f91); f109 = f46 - f108; f110 = f46 + f108; f111 = f93 + f89; f112 = MUL_C(COEF_CONST(1.3065629648763766), f93); f113 = MUL_F(FRAC_CONST(-0.9238795325112866), f111); f114 = MUL_F(FRAC_CONST(-0.5411961001461967), f89); f115 = f112 + f113; f116 = f114 - f113; f117 = f110 - f116; f118 = f110 + f116; f119 = f109 - f115; f120 = f109 + f115; f121 = f118 + f105; f122 = MUL_F(FRAC_CONST(-0.8971675863426361), f118); f123 = MUL_F(FRAC_CONST(0.9951847266721968), f121); f124 = MUL_C(COEF_CONST(1.0932018670017576), f105); y[2] = f122 + f123; y[30] = f124 - f123; f127 = f107 - f120; f128 = MUL_F(FRAC_CONST(-0.6666556584777466), f120); f129 = MUL_F(FRAC_CONST(0.9569403357322089), f127); f130 = MUL_C(COEF_CONST(1.2472250129866713), f107); y[6] = f129 - f128; y[26] = f130 - f129; f133 = f119 + f106; f134 = MUL_F(FRAC_CONST(-0.4105245275223571), f119); f135 = MUL_F(FRAC_CONST(0.8819212643483549), f133); f136 = MUL_C(COEF_CONST(1.3533180011743529), f106); y[10] = f134 + f135; y[22] = f136 - f135; f139 = f104 - f117; f140 = MUL_F(FRAC_CONST(-0.1386171691990915), f117); f141 = MUL_F(FRAC_CONST(0.7730104533627370), f139); f142 = MUL_C(COEF_CONST(1.4074037375263826), f104); y[14] = f141 - f140; y[18] = f142 - f141; f145 = f2 - f4; f146 = f2 + f4; f147 = f6 - f8; f148 = f6 + f8; f149 = f10 - f12; f150 = f10 + f12; f151 = f14 - f16; f152 = f14 + f16; f153 = f18 - f20; f154 = f18 + f20; f155 = f22 - f24; f156 = f22 + f24; f157 = f26 - f28; f158 = f26 + f28; f159 = MUL_F(FRAC_CONST(0.7071067811865476), f152); f160 = f0 - f159; f161 = f0 + f159; f162 = f148 + f156; f163 = MUL_C(COEF_CONST(1.3065629648763766), f148); f164 = MUL_F(FRAC_CONST(-0.9238795325112866), f162); f165 = MUL_F(FRAC_CONST(-0.5411961001461967), f156); f166 = f163 + f164; f167 = f165 - f164; f168 = f161 - f167; f169 = f161 + f167; f170 = f160 - f166; f171 = f160 + f166; f172 = f146 + f158; f173 = MUL_C(COEF_CONST(1.1758756024193588), f146); f174 = MUL_F(FRAC_CONST(-0.9807852804032304), f172); f175 = MUL_F(FRAC_CONST(-0.7856949583871021), f158); f176 = f173 + f174; f177 = f175 - f174; f178 = f150 + f154; f179 = MUL_C(COEF_CONST(1.3870398453221473), f150); f180 = MUL_F(FRAC_CONST(-0.8314696123025455), f178); f181 = MUL_F(FRAC_CONST(-0.2758993792829436), f154); f182 = f179 + f180; f183 = f181 - f180; f184 = f177 - f183; f185 = f177 + f183; f186 = MUL_F(FRAC_CONST(0.7071067811865476), f184); f187 = f176 - f182; f188 = f176 + f182; f189 = MUL_F(FRAC_CONST(0.7071067811865476), f188); f190 = f186 - f189; f191 = f186 + f189; f192 = f169 - f185; f193 = f169 + f185; f194 = f171 - f191; f195 = f171 + f191; f196 = f170 - f190; f197 = f170 + f190; f198 = f168 - f187; f199 = f168 + f187; f200 = MUL_F(FRAC_CONST(0.7071067811865476), f151); f201 = f30 - f200; f202 = f30 + f200; f203 = f155 + f147; f204 = MUL_C(COEF_CONST(1.3065629648763766), f155); f205 = MUL_F(FRAC_CONST(-0.9238795325112866), f203); f206 = MUL_F(FRAC_CONST(-0.5411961001461967), f147); f207 = f204 + f205; f208 = f206 - f205; f209 = f202 - f208; f210 = f202 + f208; f211 = f201 - f207; f212 = f201 + f207; f213 = f157 + f145; f214 = MUL_C(COEF_CONST(1.1758756024193588), f157); f215 = MUL_F(FRAC_CONST(-0.9807852804032304), f213); f216 = MUL_F(FRAC_CONST(-0.7856949583871021), f145); f217 = f214 + f215; f218 = f216 - f215; f219 = f153 + f149; f220 = MUL_C(COEF_CONST(1.3870398453221473), f153); f221 = MUL_F(FRAC_CONST(-0.8314696123025455), f219); f222 = MUL_F(FRAC_CONST(-0.2758993792829436), f149); f223 = f220 + f221; f224 = f222 - f221; f225 = f218 - f224; f226 = f218 + f224; f227 = MUL_F(FRAC_CONST(0.7071067811865476), f225); f228 = f217 - f223; f229 = f217 + f223; f230 = MUL_F(FRAC_CONST(0.7071067811865476), f229); f231 = f227 - f230; f232 = f227 + f230; f233 = f210 - f226; f234 = f210 + f226; f235 = f212 - f232; f236 = f212 + f232; f237 = f211 - f231; f238 = f211 + f231; f239 = f209 - f228; f240 = f209 + f228; f241 = f234 + f193; f242 = MUL_F(FRAC_CONST(-0.9497277818777543), f234); f243 = MUL_F(FRAC_CONST(0.9987954562051724), f241); f244 = MUL_C(COEF_CONST(1.0478631305325905), f193); y[1] = f242 + f243; y[31] = f244 - f243; f247 = f195 - f236; f248 = MUL_F(FRAC_CONST(-0.8424460355094192), f236); f249 = MUL_F(FRAC_CONST(0.9891765099647810), f247); f250 = MUL_C(COEF_CONST(1.1359069844201428), f195); y[3] = f249 - f248; y[29] = f250 - f249; f253 = f238 + f197; f254 = MUL_F(FRAC_CONST(-0.7270510732912801), f238); f255 = MUL_F(FRAC_CONST(0.9700312531945440), f253); f256 = MUL_C(COEF_CONST(1.2130114330978079), f197); y[5] = f254 + f255; y[27] = f256 - f255; f259 = f199 - f240; f260 = MUL_F(FRAC_CONST(-0.6046542117908007), f240); f261 = MUL_F(FRAC_CONST(0.9415440651830208), f259); f262 = MUL_C(COEF_CONST(1.2784339185752409), f199); y[7] = f261 - f260; y[25] = f262 - f261; f265 = f239 + f198; f266 = MUL_F(FRAC_CONST(-0.4764341996931611), f239); f267 = MUL_F(FRAC_CONST(0.9039892931234433), f265); f268 = MUL_C(COEF_CONST(1.3315443865537255), f198); y[9] = f266 + f267; y[23] = f268 - f267; f271 = f196 - f237; f272 = MUL_F(FRAC_CONST(-0.3436258658070505), f237); f273 = MUL_F(FRAC_CONST(0.8577286100002721), f271); f274 = MUL_C(COEF_CONST(1.3718313541934939), f196); y[11] = f273 - f272; y[21] = f274 - f273; f277 = f235 + f194; f278 = MUL_F(FRAC_CONST(-0.2075082269882114), f235); f279 = MUL_F(FRAC_CONST(0.8032075314806448), f277); f280 = MUL_C(COEF_CONST(1.3989068359730783), f194); y[13] = f278 + f279; y[19] = f280 - f279; f283 = f192 - f233; f284 = MUL_F(FRAC_CONST(-0.0693921705079408), f233); f285 = MUL_F(FRAC_CONST(0.7409511253549591), f283); f286 = MUL_C(COEF_CONST(1.4125100802019774), f192); y[15] = f285 - f284; y[17] = f286 - f285; } #else #define n 32 #define log2n 5 // w_array_real[i] = cos(2*M_PI*i/32) static const real_t w_array_real[] = { FRAC_CONST(1.000000000000000), FRAC_CONST(0.980785279337272), FRAC_CONST(0.923879528329380), FRAC_CONST(0.831469603195765), FRAC_CONST(0.707106765732237), FRAC_CONST(0.555570210304169), FRAC_CONST(0.382683402077046), FRAC_CONST(0.195090284503576), FRAC_CONST(0.000000000000000), FRAC_CONST(-0.195090370246552), FRAC_CONST(-0.382683482845162), FRAC_CONST(-0.555570282993553), FRAC_CONST(-0.707106827549476), FRAC_CONST(-0.831469651765257), FRAC_CONST(-0.923879561784627), FRAC_CONST(-0.980785296392607) }; // w_array_imag[i] = sin(-2*M_PI*i/32) static const real_t w_array_imag[] = { FRAC_CONST(0.000000000000000), FRAC_CONST(-0.195090327375064), FRAC_CONST(-0.382683442461104), FRAC_CONST(-0.555570246648862), FRAC_CONST(-0.707106796640858), FRAC_CONST(-0.831469627480512), FRAC_CONST(-0.923879545057005), FRAC_CONST(-0.980785287864940), FRAC_CONST(-1.000000000000000), FRAC_CONST(-0.980785270809601), FRAC_CONST(-0.923879511601754), FRAC_CONST(-0.831469578911016), FRAC_CONST(-0.707106734823616), FRAC_CONST(-0.555570173959476), FRAC_CONST(-0.382683361692986), FRAC_CONST(-0.195090241632088) }; // FFT decimation in frequency // 4*16*2+16=128+16=144 multiplications // 6*16*2+10*8+4*16*2=192+80+128=400 additions static void fft_dif(real_t * Real, real_t * Imag) { real_t w_real, w_imag; // For faster access real_t point1_real, point1_imag, point2_real, point2_imag; // For faster access uint32_t j, i, i2, w_index; // Counters // First 2 stages of 32 point FFT decimation in frequency // 4*16*2=64*2=128 multiplications // 6*16*2=96*2=192 additions // Stage 1 of 32 point FFT decimation in frequency for (i = 0; i < 16; i++) { point1_real = Real[i]; point1_imag = Imag[i]; i2 = i+16; point2_real = Real[i2]; point2_imag = Imag[i2]; w_real = w_array_real[i]; w_imag = w_array_imag[i]; // temp1 = x[i] - x[i2] point1_real -= point2_real; point1_imag -= point2_imag; // x[i1] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = (x[i] - x[i2]) * w Real[i2] = (MUL_F(point1_real,w_real) - MUL_F(point1_imag,w_imag)); Imag[i2] = (MUL_F(point1_real,w_imag) + MUL_F(point1_imag,w_real)); } // Stage 2 of 32 point FFT decimation in frequency for (j = 0, w_index = 0; j < 8; j++, w_index += 2) { w_real = w_array_real[w_index]; w_imag = w_array_imag[w_index]; i = j; point1_real = Real[i]; point1_imag = Imag[i]; i2 = i+8; point2_real = Real[i2]; point2_imag = Imag[i2]; // temp1 = x[i] - x[i2] point1_real -= point2_real; point1_imag -= point2_imag; // x[i1] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = (x[i] - x[i2]) * w Real[i2] = (MUL_F(point1_real,w_real) - MUL_F(point1_imag,w_imag)); Imag[i2] = (MUL_F(point1_real,w_imag) + MUL_F(point1_imag,w_real)); i = j+16; point1_real = Real[i]; point1_imag = Imag[i]; i2 = i+8; point2_real = Real[i2]; point2_imag = Imag[i2]; // temp1 = x[i] - x[i2] point1_real -= point2_real; point1_imag -= point2_imag; // x[i1] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = (x[i] - x[i2]) * w Real[i2] = (MUL_F(point1_real,w_real) - MUL_F(point1_imag,w_imag)); Imag[i2] = (MUL_F(point1_real,w_imag) + MUL_F(point1_imag,w_real)); } // Stage 3 of 32 point FFT decimation in frequency // 2*4*2=16 multiplications // 4*4*2+6*4*2=10*8=80 additions for (i = 0; i < n; i += 8) { i2 = i+4; point1_real = Real[i]; point1_imag = Imag[i]; point2_real = Real[i2]; point2_imag = Imag[i2]; // out[i1] = point1 + point2 Real[i] += point2_real; Imag[i] += point2_imag; // out[i2] = point1 - point2 Real[i2] = point1_real - point2_real; Imag[i2] = point1_imag - point2_imag; } w_real = w_array_real[4]; // = sqrt(2)/2 // w_imag = -w_real; // = w_array_imag[4]; // = -sqrt(2)/2 for (i = 1; i < n; i += 8) { i2 = i+4; point1_real = Real[i]; point1_imag = Imag[i]; point2_real = Real[i2]; point2_imag = Imag[i2]; // temp1 = x[i] - x[i2] point1_real -= point2_real; point1_imag -= point2_imag; // x[i1] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = (x[i] - x[i2]) * w Real[i2] = MUL_F(point1_real+point1_imag, w_real); Imag[i2] = MUL_F(point1_imag-point1_real, w_real); } for (i = 2; i < n; i += 8) { i2 = i+4; point1_real = Real[i]; point1_imag = Imag[i]; point2_real = Real[i2]; point2_imag = Imag[i2]; // x[i] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = (x[i] - x[i2]) * (-i) Real[i2] = point1_imag - point2_imag; Imag[i2] = point2_real - point1_real; } w_real = w_array_real[12]; // = -sqrt(2)/2 // w_imag = w_real; // = w_array_imag[12]; // = -sqrt(2)/2 for (i = 3; i < n; i += 8) { i2 = i+4; point1_real = Real[i]; point1_imag = Imag[i]; point2_real = Real[i2]; point2_imag = Imag[i2]; // temp1 = x[i] - x[i2] point1_real -= point2_real; point1_imag -= point2_imag; // x[i1] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = (x[i] - x[i2]) * w Real[i2] = MUL_F(point1_real-point1_imag, w_real); Imag[i2] = MUL_F(point1_real+point1_imag, w_real); } // Stage 4 of 32 point FFT decimation in frequency (no multiplications) // 16*4=64 additions for (i = 0; i < n; i += 4) { i2 = i+2; point1_real = Real[i]; point1_imag = Imag[i]; point2_real = Real[i2]; point2_imag = Imag[i2]; // x[i1] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = x[i] - x[i2] Real[i2] = point1_real - point2_real; Imag[i2] = point1_imag - point2_imag; } for (i = 1; i < n; i += 4) { i2 = i+2; point1_real = Real[i]; point1_imag = Imag[i]; point2_real = Real[i2]; point2_imag = Imag[i2]; // x[i] = x[i] + x[i2] Real[i] += point2_real; Imag[i] += point2_imag; // x[i2] = (x[i] - x[i2]) * (-i) Real[i2] = point1_imag - point2_imag; Imag[i2] = point2_real - point1_real; } // Stage 5 of 32 point FFT decimation in frequency (no multiplications) // 16*4=64 additions for (i = 0; i < n; i += 2) { i2 = i+1; point1_real = Real[i]; point1_imag = Imag[i]; point2_real = Real[i2]; point2_imag = Imag[i2]; // out[i1] = point1 + point2 Real[i] += point2_real; Imag[i] += point2_imag; // out[i2] = point1 - point2 Real[i2] = point1_real - point2_real; Imag[i2] = point1_imag - point2_imag; } #ifdef REORDER_IN_FFT FFTReorder(Real, Imag); #endif // #ifdef REORDER_IN_FFT } #undef n #undef log2n static const real_t dct4_64_tab[] = { COEF_CONST(0.999924719333649), COEF_CONST(0.998118102550507), COEF_CONST(0.993906974792480), COEF_CONST(0.987301409244537), COEF_CONST(0.978317379951477), COEF_CONST(0.966976463794708), COEF_CONST(0.953306019306183), COEF_CONST(0.937339007854462), COEF_CONST(0.919113874435425), COEF_CONST(0.898674488067627), COEF_CONST(0.876070082187653), COEF_CONST(0.851355195045471), COEF_CONST(0.824589252471924), COEF_CONST(0.795836925506592), COEF_CONST(0.765167236328125), COEF_CONST(0.732654273509979), COEF_CONST(0.698376238346100), COEF_CONST(0.662415742874146), COEF_CONST(0.624859452247620), COEF_CONST(0.585797846317291), COEF_CONST(0.545324981212616), COEF_CONST(0.503538429737091), COEF_CONST(0.460538715124130), COEF_CONST(0.416429549455643), COEF_CONST(0.371317148208618), COEF_CONST(0.325310230255127), COEF_CONST(0.278519600629807), COEF_CONST(0.231058135628700), COEF_CONST(0.183039888739586), COEF_CONST(0.134580686688423), COEF_CONST(0.085797272622585), COEF_CONST(0.036807164549828), COEF_CONST(-1.012196302413940), COEF_CONST(-1.059438824653626), COEF_CONST(-1.104129195213318), COEF_CONST(-1.146159529685974), COEF_CONST(-1.185428738594055), COEF_CONST(-1.221842169761658), COEF_CONST(-1.255311965942383), COEF_CONST(-1.285757660865784), COEF_CONST(-1.313105940818787), COEF_CONST(-1.337290763854981), COEF_CONST(-1.358253836631775), COEF_CONST(-1.375944852828980), COEF_CONST(-1.390321016311646), COEF_CONST(-1.401347875595093), COEF_CONST(-1.408998727798462), COEF_CONST(-1.413255214691162), COEF_CONST(-1.414107084274292), COEF_CONST(-1.411552190780640), COEF_CONST(-1.405596733093262), COEF_CONST(-1.396255016326904), COEF_CONST(-1.383549690246582), COEF_CONST(-1.367511272430420), COEF_CONST(-1.348178386688232), COEF_CONST(-1.325597524642944), COEF_CONST(-1.299823284149170), COEF_CONST(-1.270917654037476), COEF_CONST(-1.238950133323669), COEF_CONST(-1.203998088836670), COEF_CONST(-1.166145324707031), COEF_CONST(-1.125483393669128), COEF_CONST(-1.082109928131104), COEF_CONST(-1.036129593849182), COEF_CONST(-0.987653195858002), COEF_CONST(-0.936797380447388), COEF_CONST(-0.883684754371643), COEF_CONST(-0.828443288803101), COEF_CONST(-0.771206021308899), COEF_CONST(-0.712110757827759), COEF_CONST(-0.651300072669983), COEF_CONST(-0.588920354843140), COEF_CONST(-0.525121808052063), COEF_CONST(-0.460058242082596), COEF_CONST(-0.393886327743530), COEF_CONST(-0.326765477657318), COEF_CONST(-0.258857429027557), COEF_CONST(-0.190325915813446), COEF_CONST(-0.121335685253143), COEF_CONST(-0.052053272724152), COEF_CONST(0.017354607582092), COEF_CONST(0.086720645427704), COEF_CONST(0.155877828598022), COEF_CONST(0.224659323692322), COEF_CONST(0.292899727821350), COEF_CONST(0.360434412956238), COEF_CONST(0.427100926637650), COEF_CONST(0.492738455533981), COEF_CONST(0.557188928127289), COEF_CONST(0.620297133922577), COEF_CONST(0.681910991668701), COEF_CONST(0.741881847381592), COEF_CONST(0.800065577030182), COEF_CONST(0.856321990489960), COEF_CONST(0.910515367984772), COEF_CONST(0.962515234947205), COEF_CONST(1.000000000000000), COEF_CONST(0.998795449733734), COEF_CONST(0.995184719562531), COEF_CONST(0.989176511764526), COEF_CONST(0.980785250663757), COEF_CONST(0.970031261444092), COEF_CONST(0.956940352916718), COEF_CONST(0.941544055938721), COEF_CONST(0.923879504203796), COEF_CONST(0.903989315032959), COEF_CONST(0.881921231746674), COEF_CONST(0.857728600502014), COEF_CONST(0.831469595432281), COEF_CONST(0.803207516670227), COEF_CONST(0.773010432720184), COEF_CONST(0.740951120853424), COEF_CONST(0.707106769084930), COEF_CONST(0.671558916568756), COEF_CONST(0.634393274784088), COEF_CONST(0.595699310302734), COEF_CONST(0.555570185184479), COEF_CONST(0.514102697372437), COEF_CONST(0.471396654844284), COEF_CONST(0.427555114030838), COEF_CONST(0.382683426141739), COEF_CONST(0.336889833211899), COEF_CONST(0.290284633636475), COEF_CONST(0.242980122566223), COEF_CONST(0.195090234279633), COEF_CONST(0.146730497479439), COEF_CONST(0.098017133772373), COEF_CONST(0.049067649990320), COEF_CONST(-1.000000000000000), COEF_CONST(-1.047863125801086), COEF_CONST(-1.093201875686646), COEF_CONST(-1.135906934738159), COEF_CONST(-1.175875544548035), COEF_CONST(-1.213011503219605), COEF_CONST(-1.247225046157837), COEF_CONST(-1.278433918952942), COEF_CONST(-1.306562900543213), COEF_CONST(-1.331544399261475), COEF_CONST(-1.353317975997925), COEF_CONST(-1.371831417083740), COEF_CONST(-1.387039899826050), COEF_CONST(-1.398906826972961), COEF_CONST(-1.407403707504273), COEF_CONST(-1.412510156631470), COEF_CONST(0), COEF_CONST(-1.412510156631470), COEF_CONST(-1.407403707504273), COEF_CONST(-1.398906826972961), COEF_CONST(-1.387039899826050), COEF_CONST(-1.371831417083740), COEF_CONST(-1.353317975997925), COEF_CONST(-1.331544399261475), COEF_CONST(-1.306562900543213), COEF_CONST(-1.278433918952942), COEF_CONST(-1.247225046157837), COEF_CONST(-1.213011384010315), COEF_CONST(-1.175875544548035), COEF_CONST(-1.135907053947449), COEF_CONST(-1.093201875686646), COEF_CONST(-1.047863125801086), COEF_CONST(-1.000000000000000), COEF_CONST(-0.949727773666382), COEF_CONST(-0.897167563438416), COEF_CONST(-0.842446029186249), COEF_CONST(-0.785694956779480), COEF_CONST(-0.727051079273224), COEF_CONST(-0.666655659675598), COEF_CONST(-0.604654192924500), COEF_CONST(-0.541196048259735), COEF_CONST(-0.476434230804443), COEF_CONST(-0.410524487495422), COEF_CONST(-0.343625843524933), COEF_CONST(-0.275899350643158), COEF_CONST(-0.207508206367493), COEF_CONST(-0.138617098331451), COEF_CONST(-0.069392144680023), COEF_CONST(0), COEF_CONST(0.069392263889313), COEF_CONST(0.138617157936096), COEF_CONST(0.207508206367493), COEF_CONST(0.275899469852448), COEF_CONST(0.343625962734222), COEF_CONST(0.410524636507034), COEF_CONST(0.476434201002121), COEF_CONST(0.541196107864380), COEF_CONST(0.604654192924500), COEF_CONST(0.666655719280243), COEF_CONST(0.727051138877869), COEF_CONST(0.785695075988770), COEF_CONST(0.842446029186249), COEF_CONST(0.897167563438416), COEF_CONST(0.949727773666382) }; /* size 64 only! */ void dct4_kernel(real_t * in_real, real_t * in_imag, real_t * out_real, real_t * out_imag) { // Tables with bit reverse values for 5 bits, bit reverse of i at i-th position const uint8_t bit_rev_tab[32] = { 0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31 }; uint32_t i, i_rev; /* Step 2: modulate */ // 3*32=96 multiplications // 3*32=96 additions for (i = 0; i < 32; i++) { real_t x_re, x_im, tmp; x_re = in_real[i]; x_im = in_imag[i]; tmp = MUL_C(x_re + x_im, dct4_64_tab[i]); in_real[i] = MUL_C(x_im, dct4_64_tab[i + 64]) + tmp; in_imag[i] = MUL_C(x_re, dct4_64_tab[i + 32]) + tmp; } /* Step 3: FFT, but with output in bit reverse order */ fft_dif(in_real, in_imag); /* Step 4: modulate + bitreverse reordering */ // 3*31+2=95 multiplications // 3*31+2=95 additions for (i = 0; i < 16; i++) { real_t x_re, x_im, tmp; i_rev = bit_rev_tab[i]; x_re = in_real[i_rev]; x_im = in_imag[i_rev]; tmp = MUL_C(x_re + x_im, dct4_64_tab[i + 3*32]); out_real[i] = MUL_C(x_im, dct4_64_tab[i + 5*32]) + tmp; out_imag[i] = MUL_C(x_re, dct4_64_tab[i + 4*32]) + tmp; } // i = 16, i_rev = 1 = rev(16); out_imag[16] = MUL_C(in_imag[1] - in_real[1], dct4_64_tab[16 + 3*32]); out_real[16] = MUL_C(in_real[1] + in_imag[1], dct4_64_tab[16 + 3*32]); for (i = 17; i < 32; i++) { real_t x_re, x_im, tmp; i_rev = bit_rev_tab[i]; x_re = in_real[i_rev]; x_im = in_imag[i_rev]; tmp = MUL_C(x_re + x_im, dct4_64_tab[i + 3*32]); out_real[i] = MUL_C(x_im, dct4_64_tab[i + 5*32]) + tmp; out_imag[i] = MUL_C(x_re, dct4_64_tab[i + 4*32]) + tmp; } } #endif #endif xine-lib-1.2/contrib/libfaad/error.h0000644000175000017500000000270714647725151015215 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: error.h,v 1.27 2008/09/19 23:31:40 menno Exp $ **/ #ifndef __ERROR_H__ #define __ERROR_H__ #ifdef __cplusplus extern "C" { #endif #define NUM_ERROR_MESSAGES 34 extern const char *err_msg[]; #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/lt_predict.c0000644000175000017500000001416714647725152016214 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: lt_predict.c,v 1.27 2007/11/01 12:33:31 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef LTP_DEC #include #include "syntax.h" #include "lt_predict.h" #include "filtbank.h" #include "tns.h" /* static function declarations */ static int16_t real_to_int16(real_t sig_in); /* check if the object type is an object type that can have LTP */ uint8_t is_ltp_ot(uint8_t object_type) { #ifdef LTP_DEC if ((object_type == LTP) #ifdef ERROR_RESILIENCE || (object_type == ER_LTP) #endif #ifdef LD_DEC || (object_type == LD) #endif ) { return 1; } #endif return 0; } ALIGN static const real_t codebook[8] = { REAL_CONST(0.570829), REAL_CONST(0.696616), REAL_CONST(0.813004), REAL_CONST(0.911304), REAL_CONST(0.984900), REAL_CONST(1.067894), REAL_CONST(1.194601), REAL_CONST(1.369533) }; void lt_prediction(ic_stream *ics, ltp_info *ltp, real_t *spec, int16_t *lt_pred_stat, fb_info *fb, uint8_t win_shape, uint8_t win_shape_prev, uint8_t sr_index, uint8_t object_type, uint16_t frame_len) { uint8_t sfb; uint16_t bin, i, num_samples; ALIGN real_t x_est[2048]; ALIGN real_t X_est[2048]; if (ics->window_sequence != EIGHT_SHORT_SEQUENCE) { if (ltp->data_present) { num_samples = frame_len << 1; for(i = 0; i < num_samples; i++) { /* The extra lookback M (N/2 for LD, 0 for LTP) is handled in the buffer updating */ #if 0 x_est[i] = MUL_R_C(lt_pred_stat[num_samples + i - ltp->lag], codebook[ltp->coef]); #else /* lt_pred_stat is a 16 bit int, multiplied with the fixed point real this gives a real for x_est */ x_est[i] = (real_t)lt_pred_stat[num_samples + i - ltp->lag] * codebook[ltp->coef]; #endif } filter_bank_ltp(fb, ics->window_sequence, win_shape, win_shape_prev, x_est, X_est, object_type, frame_len); tns_encode_frame(ics, &(ics->tns), sr_index, object_type, X_est, frame_len); for (sfb = 0; sfb < ltp->last_band; sfb++) { if (ltp->long_used[sfb]) { uint16_t low = ics->swb_offset[sfb]; uint16_t high = min(ics->swb_offset[sfb+1], ics->swb_offset_max); for (bin = low; bin < high; bin++) { spec[bin] += X_est[bin]; } } } } } } #ifdef FIXED_POINT static INLINE int16_t real_to_int16(real_t sig_in) { if (sig_in >= 0) { sig_in += (1 << (REAL_BITS-1)); if (sig_in >= REAL_CONST(32768)) return 32767; } else { sig_in += -(1 << (REAL_BITS-1)); if (sig_in <= REAL_CONST(-32768)) return -32768; } return (sig_in >> REAL_BITS); } #else static INLINE int16_t real_to_int16(real_t sig_in) { if (sig_in >= 0) { #ifndef HAS_LRINTF sig_in += 0.5f; #endif if (sig_in >= 32768.0f) return 32767; } else { #ifndef HAS_LRINTF sig_in += -0.5f; #endif if (sig_in <= -32768.0f) return -32768; } return lrintf(sig_in); } #endif void lt_update_state(int16_t *lt_pred_stat, real_t *time, real_t *overlap, uint16_t frame_len, uint8_t object_type) { uint16_t i; /* * The reference point for index i and the content of the buffer * lt_pred_stat are arranged so that lt_pred_stat(0 ... N/2 - 1) contains the * last aliased half window from the IMDCT, and lt_pred_stat(N/2 ... N-1) * is always all zeros. The rest of lt_pred_stat (i<0) contains the previous * fully reconstructed time domain samples, i.e., output of the decoder. * * These values are shifted up by N*2 to avoid (i<0) * * For the LD object type an extra 512 samples lookback is accomodated here. */ #ifdef LD_DEC if (object_type == LD) { for (i = 0; i < frame_len; i++) { lt_pred_stat[i] /* extra 512 */ = lt_pred_stat[i + frame_len]; lt_pred_stat[frame_len + i] = lt_pred_stat[i + (frame_len * 2)]; lt_pred_stat[(frame_len * 2) + i] = real_to_int16(time[i]); lt_pred_stat[(frame_len * 3) + i] = real_to_int16(overlap[i]); } } else { #endif for (i = 0; i < frame_len; i++) { lt_pred_stat[i] = lt_pred_stat[i + frame_len]; lt_pred_stat[frame_len + i] = real_to_int16(time[i]); lt_pred_stat[(frame_len * 2) + i] = real_to_int16(overlap[i]); #if 0 /* set to zero once upon initialisation */ lt_pred_stat[(frame_len * 3) + i] = 0; #endif } #ifdef LD_DEC } #endif } #endif xine-lib-1.2/contrib/libfaad/sbr_fbt.c0000644000175000017500000005724714647725152015512 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_fbt.c,v 1.21 2007/11/01 12:33:35 menno Exp $ **/ /* Calculate frequency band tables */ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include #include "sbr_syntax.h" #include "sbr_fbt.h" /* static function declarations */ static int32_t find_bands(uint8_t warp, uint8_t bands, uint8_t a0, uint8_t a1); /* calculate the start QMF channel for the master frequency band table */ /* parameter is also called k0 */ uint8_t qmf_start_channel(uint8_t bs_start_freq, uint8_t bs_samplerate_mode, uint32_t sample_rate) { static const uint8_t startMinTable[12] = { 7, 7, 10, 11, 12, 16, 16, 17, 24, 32, 35, 48 }; static const uint8_t offsetIndexTable[12] = { 5, 5, 4, 4, 4, 3, 2, 1, 0, 6, 6, 6 }; static const int8_t offset[7][16] = { { -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7 }, { -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13 }, { -5, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 }, { -6, -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16 }, { -4, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20 }, { -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24 }, { 0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 13, 16, 20, 24, 28, 33 } }; uint8_t startMin = startMinTable[get_sr_index(sample_rate)]; uint8_t offsetIndex = offsetIndexTable[get_sr_index(sample_rate)]; #if 0 /* replaced with table (startMinTable) */ if (sample_rate >= 64000) { startMin = (uint8_t)((5000.*128.)/(float)sample_rate + 0.5); } else if (sample_rate < 32000) { startMin = (uint8_t)((3000.*128.)/(float)sample_rate + 0.5); } else { startMin = (uint8_t)((4000.*128.)/(float)sample_rate + 0.5); } #endif if (bs_samplerate_mode) { return startMin + offset[offsetIndex][bs_start_freq]; #if 0 /* replaced by offsetIndexTable */ switch (sample_rate) { case 16000: return startMin + offset[0][bs_start_freq]; case 22050: return startMin + offset[1][bs_start_freq]; case 24000: return startMin + offset[2][bs_start_freq]; case 32000: return startMin + offset[3][bs_start_freq]; default: if (sample_rate > 64000) { return startMin + offset[5][bs_start_freq]; } else { /* 44100 <= sample_rate <= 64000 */ return startMin + offset[4][bs_start_freq]; } } #endif } else { return startMin + offset[6][bs_start_freq]; } } static int longcmp(const void *a, const void *b) { return ((int)(*(int32_t*)a - *(int32_t*)b)); } /* calculate the stop QMF channel for the master frequency band table */ /* parameter is also called k2 */ uint8_t qmf_stop_channel(uint8_t bs_stop_freq, uint32_t sample_rate, uint8_t k0) { if (bs_stop_freq == 15) { return min(64, k0 * 3); } else if (bs_stop_freq == 14) { return min(64, k0 * 2); } else { static const uint8_t stopMinTable[12] = { 13, 15, 20, 21, 23, 32, 32, 35, 48, 64, 70, 96 }; static const int8_t offset[12][14] = { { 0, 2, 4, 6, 8, 11, 14, 18, 22, 26, 31, 37, 44, 51 }, { 0, 2, 4, 6, 8, 11, 14, 18, 22, 26, 31, 36, 42, 49 }, { 0, 2, 4, 6, 8, 11, 14, 17, 21, 25, 29, 34, 39, 44 }, { 0, 2, 4, 6, 8, 11, 14, 17, 20, 24, 28, 33, 38, 43 }, { 0, 2, 4, 6, 8, 11, 14, 17, 20, 24, 28, 32, 36, 41 }, { 0, 2, 4, 6, 8, 10, 12, 14, 17, 20, 23, 26, 29, 32 }, { 0, 2, 4, 6, 8, 10, 12, 14, 17, 20, 23, 26, 29, 32 }, { 0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 20, 23, 26, 29 }, { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16 }, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, -1, -2, -3, -4, -5, -6, -6, -6, -6, -6, -6, -6, -6 }, { 0, -3, -6, -9, -12, -15, -18, -20, -22, -24, -26, -28, -30, -32 } }; #if 0 uint8_t i; int32_t stopDk[13], stopDk_t[14], k2; #endif uint8_t stopMin = stopMinTable[get_sr_index(sample_rate)]; #if 0 /* replaced by table lookup */ if (sample_rate >= 64000) { stopMin = (uint8_t)((10000.*128.)/(float)sample_rate + 0.5); } else if (sample_rate < 32000) { stopMin = (uint8_t)((6000.*128.)/(float)sample_rate + 0.5); } else { stopMin = (uint8_t)((8000.*128.)/(float)sample_rate + 0.5); } #endif #if 0 /* replaced by table lookup */ /* diverging power series */ for (i = 0; i <= 13; i++) { stopDk_t[i] = (int32_t)(stopMin*pow(64.0/stopMin, i/13.0) + 0.5); } for (i = 0; i < 13; i++) { stopDk[i] = stopDk_t[i+1] - stopDk_t[i]; } /* needed? */ qsort(stopDk, 13, sizeof(stopDk[0]), longcmp); k2 = stopMin; for (i = 0; i < bs_stop_freq; i++) { k2 += stopDk[i]; } return min(64, k2); #endif /* bs_stop_freq <= 13 */ return min(64, stopMin + offset[get_sr_index(sample_rate)][min(bs_stop_freq, 13)]); } return 0; } /* calculate the master frequency table from k0, k2, bs_freq_scale and bs_alter_scale version for bs_freq_scale = 0 */ uint8_t master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2, uint8_t bs_alter_scale) { int8_t incr; uint8_t k; uint8_t dk; uint32_t nrBands, k2Achieved; int32_t k2Diff, vDk[64] = {0}; /* mft only defined for k2 > k0 */ if (k2 <= k0) { sbr->N_master = 0; return 1; } dk = bs_alter_scale ? 2 : 1; #if 0 /* replaced by float-less design */ nrBands = 2 * (int32_t)((float)(k2-k0)/(dk*2) + (-1+dk)/2.0f); #else if (bs_alter_scale) { nrBands = (((k2-k0+2)>>2)<<1); } else { nrBands = (((k2-k0)>>1)<<1); } #endif nrBands = min(nrBands, 63); if (nrBands <= 0) return 1; k2Achieved = k0 + nrBands * dk; k2Diff = k2 - k2Achieved; for (k = 0; k < nrBands; k++) vDk[k] = dk; if (k2Diff) { incr = (k2Diff > 0) ? -1 : 1; k = (uint8_t) ((k2Diff > 0) ? (nrBands-1) : 0); while (k2Diff != 0) { vDk[k] -= incr; k += incr; k2Diff += incr; } } sbr->f_master[0] = k0; for (k = 1; k <= nrBands; k++) sbr->f_master[k] = (uint8_t)(sbr->f_master[k-1] + vDk[k-1]); sbr->N_master = (uint8_t)nrBands; sbr->N_master = (min(sbr->N_master, 64)); #if 0 printf("f_master[%d]: ", nrBands); for (k = 0; k <= nrBands; k++) { printf("%d ", sbr->f_master[k]); } printf("\n"); #endif return 0; } /* This function finds the number of bands using this formula: bands * log(a1/a0)/log(2.0) + 0.5 */ static int32_t find_bands(uint8_t warp, uint8_t bands, uint8_t a0, uint8_t a1) { #ifdef FIXED_POINT /* table with log2() values */ static const real_t log2Table[65] = { COEF_CONST(0.0), COEF_CONST(0.0), COEF_CONST(1.0000000000), COEF_CONST(1.5849625007), COEF_CONST(2.0000000000), COEF_CONST(2.3219280949), COEF_CONST(2.5849625007), COEF_CONST(2.8073549221), COEF_CONST(3.0000000000), COEF_CONST(3.1699250014), COEF_CONST(3.3219280949), COEF_CONST(3.4594316186), COEF_CONST(3.5849625007), COEF_CONST(3.7004397181), COEF_CONST(3.8073549221), COEF_CONST(3.9068905956), COEF_CONST(4.0000000000), COEF_CONST(4.0874628413), COEF_CONST(4.1699250014), COEF_CONST(4.2479275134), COEF_CONST(4.3219280949), COEF_CONST(4.3923174228), COEF_CONST(4.4594316186), COEF_CONST(4.5235619561), COEF_CONST(4.5849625007), COEF_CONST(4.6438561898), COEF_CONST(4.7004397181), COEF_CONST(4.7548875022), COEF_CONST(4.8073549221), COEF_CONST(4.8579809951), COEF_CONST(4.9068905956), COEF_CONST(4.9541963104), COEF_CONST(5.0000000000), COEF_CONST(5.0443941194), COEF_CONST(5.0874628413), COEF_CONST(5.1292830169), COEF_CONST(5.1699250014), COEF_CONST(5.2094533656), COEF_CONST(5.2479275134), COEF_CONST(5.2854022189), COEF_CONST(5.3219280949), COEF_CONST(5.3575520046), COEF_CONST(5.3923174228), COEF_CONST(5.4262647547), COEF_CONST(5.4594316186), COEF_CONST(5.4918530963), COEF_CONST(5.5235619561), COEF_CONST(5.5545888517), COEF_CONST(5.5849625007), COEF_CONST(5.6147098441), COEF_CONST(5.6438561898), COEF_CONST(5.6724253420), COEF_CONST(5.7004397181), COEF_CONST(5.7279204546), COEF_CONST(5.7548875022), COEF_CONST(5.7813597135), COEF_CONST(5.8073549221), COEF_CONST(5.8328900142), COEF_CONST(5.8579809951), COEF_CONST(5.8826430494), COEF_CONST(5.9068905956), COEF_CONST(5.9307373376), COEF_CONST(5.9541963104), COEF_CONST(5.9772799235), COEF_CONST(6.0) }; real_t r0 = log2Table[a0]; /* coef */ real_t r1 = log2Table[a1]; /* coef */ real_t r2 = (r1 - r0); /* coef */ if (warp) r2 = MUL_C(r2, COEF_CONST(1.0/1.3)); /* convert r2 to real and then multiply and round */ r2 = (r2 >> (COEF_BITS-REAL_BITS)) * bands + (1<<(REAL_BITS-1)); return (r2 >> REAL_BITS); #else real_t div = (real_t)log(2.0); if (warp) div *= (real_t)1.3; return (int32_t)(bands * log((float)a1/(float)a0)/div + 0.5); #endif } static real_t find_initial_power(uint8_t bands, uint8_t a0, uint8_t a1) { #ifdef FIXED_POINT /* table with log() values */ static const real_t logTable[65] = { COEF_CONST(0.0), COEF_CONST(0.0), COEF_CONST(0.6931471806), COEF_CONST(1.0986122887), COEF_CONST(1.3862943611), COEF_CONST(1.6094379124), COEF_CONST(1.7917594692), COEF_CONST(1.9459101491), COEF_CONST(2.0794415417), COEF_CONST(2.1972245773), COEF_CONST(2.3025850930), COEF_CONST(2.3978952728), COEF_CONST(2.4849066498), COEF_CONST(2.5649493575), COEF_CONST(2.6390573296), COEF_CONST(2.7080502011), COEF_CONST(2.7725887222), COEF_CONST(2.8332133441), COEF_CONST(2.8903717579), COEF_CONST(2.9444389792), COEF_CONST(2.9957322736), COEF_CONST(3.0445224377), COEF_CONST(3.0910424534), COEF_CONST(3.1354942159), COEF_CONST(3.1780538303), COEF_CONST(3.2188758249), COEF_CONST(3.2580965380), COEF_CONST(3.2958368660), COEF_CONST(3.3322045102), COEF_CONST(3.3672958300), COEF_CONST(3.4011973817), COEF_CONST(3.4339872045), COEF_CONST(3.4657359028), COEF_CONST(3.4965075615), COEF_CONST(3.5263605246), COEF_CONST(3.5553480615), COEF_CONST(3.5835189385), COEF_CONST(3.6109179126), COEF_CONST(3.6375861597), COEF_CONST(3.6635616461), COEF_CONST(3.6888794541), COEF_CONST(3.7135720667), COEF_CONST(3.7376696183), COEF_CONST(3.7612001157), COEF_CONST(3.7841896339), COEF_CONST(3.8066624898), COEF_CONST(3.8286413965), COEF_CONST(3.8501476017), COEF_CONST(3.8712010109), COEF_CONST(3.8918202981), COEF_CONST(3.9120230054), COEF_CONST(3.9318256327), COEF_CONST(3.9512437186), COEF_CONST(3.9702919136), COEF_CONST(3.9889840466), COEF_CONST(4.0073331852), COEF_CONST(4.0253516907), COEF_CONST(4.0430512678), COEF_CONST(4.0604430105), COEF_CONST(4.0775374439), COEF_CONST(4.0943445622), COEF_CONST(4.1108738642), COEF_CONST(4.1271343850), COEF_CONST(4.1431347264), COEF_CONST(4.158883083) }; /* standard Taylor polynomial coefficients for exp(x) around 0 */ /* a polynomial around x=1 is more precise, as most values are around 1.07, but this is just fine already */ static const real_t c1 = COEF_CONST(1.0); static const real_t c2 = COEF_CONST(1.0/2.0); static const real_t c3 = COEF_CONST(1.0/6.0); static const real_t c4 = COEF_CONST(1.0/24.0); real_t r0 = logTable[a0]; /* coef */ real_t r1 = logTable[a1]; /* coef */ real_t r2 = (r1 - r0) / bands; /* coef */ real_t rexp = c1 + MUL_C((c1 + MUL_C((c2 + MUL_C((c3 + MUL_C(c4,r2)), r2)), r2)), r2); return (rexp >> (COEF_BITS-REAL_BITS)); /* real */ #else return (real_t)pow((real_t)a1/(real_t)a0, 1.0/(real_t)bands); #endif } /* version for bs_freq_scale > 0 */ uint8_t master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2, uint8_t bs_freq_scale, uint8_t bs_alter_scale) { uint8_t k, bands, twoRegions; uint8_t k1; uint8_t nrBand0, nrBand1; int32_t vDk0[64] = {0}, vDk1[64] = {0}; int32_t vk0[64] = {0}, vk1[64] = {0}; uint8_t temp1[] = { 6, 5, 4 }; real_t q, qk; int32_t A_1; #ifdef FIXED_POINT real_t rk2, rk0; #endif (void)bs_alter_scale; /* mft only defined for k2 > k0 */ if (k2 <= k0) { sbr->N_master = 0; return 1; } bands = temp1[bs_freq_scale-1]; #ifdef FIXED_POINT rk0 = (real_t)k0 << REAL_BITS; rk2 = (real_t)k2 << REAL_BITS; if (rk2 > MUL_C(rk0, COEF_CONST(2.2449))) #else if ((float)k2/(float)k0 > 2.2449) #endif { twoRegions = 1; k1 = k0 << 1; } else { twoRegions = 0; k1 = k2; } nrBand0 = (uint8_t)(2 * find_bands(0, bands, k0, k1)); nrBand0 = min(nrBand0, 63); if (nrBand0 <= 0) return 1; q = find_initial_power(nrBand0, k0, k1); #ifdef FIXED_POINT qk = (real_t)k0 << REAL_BITS; //A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS); A_1 = k0; #else qk = REAL_CONST(k0); A_1 = (int32_t)(qk + .5); #endif for (k = 0; k <= nrBand0; k++) { int32_t A_0 = A_1; #ifdef FIXED_POINT qk = MUL_R(qk,q); A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS); #else qk *= q; A_1 = (int32_t)(qk + 0.5); #endif vDk0[k] = A_1 - A_0; } /* needed? */ qsort(vDk0, nrBand0, sizeof(vDk0[0]), longcmp); vk0[0] = k0; for (k = 1; k <= nrBand0; k++) { vk0[k] = vk0[k-1] + vDk0[k-1]; if (vDk0[k-1] == 0) return 1; } if (!twoRegions) { for (k = 0; k <= nrBand0; k++) sbr->f_master[k] = (uint8_t) vk0[k]; sbr->N_master = nrBand0; sbr->N_master = min(sbr->N_master, 64); return 0; } nrBand1 = (uint8_t)(2 * find_bands(1 /* warped */, bands, k1, k2)); nrBand1 = min(nrBand1, 63); q = find_initial_power(nrBand1, k1, k2); #ifdef FIXED_POINT qk = (real_t)k1 << REAL_BITS; //A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS); A_1 = k1; #else qk = REAL_CONST(k1); A_1 = (int32_t)(qk + .5); #endif for (k = 0; k <= nrBand1 - 1; k++) { int32_t A_0 = A_1; #ifdef FIXED_POINT qk = MUL_R(qk,q); A_1 = (int32_t)((qk + REAL_CONST(0.5)) >> REAL_BITS); #else qk *= q; A_1 = (int32_t)(qk + 0.5); #endif vDk1[k] = A_1 - A_0; } if (vDk1[0] < vDk0[nrBand0 - 1]) { int32_t change; /* needed? */ qsort(vDk1, nrBand1 + 1, sizeof(vDk1[0]), longcmp); change = vDk0[nrBand0 - 1] - vDk1[0]; vDk1[0] = vDk0[nrBand0 - 1]; vDk1[nrBand1 - 1] = vDk1[nrBand1 - 1] - change; } /* needed? */ qsort(vDk1, nrBand1, sizeof(vDk1[0]), longcmp); vk1[0] = k1; for (k = 1; k <= nrBand1; k++) { vk1[k] = vk1[k-1] + vDk1[k-1]; if (vDk1[k-1] == 0) return 1; } sbr->N_master = nrBand0 + nrBand1; sbr->N_master = min(sbr->N_master, 64); for (k = 0; k <= nrBand0; k++) { sbr->f_master[k] = (uint8_t) vk0[k]; } for (k = nrBand0 + 1; k <= sbr->N_master; k++) { sbr->f_master[k] = (uint8_t) vk1[k - nrBand0]; } #if 0 printf("f_master[%d]: ", sbr->N_master); for (k = 0; k <= sbr->N_master; k++) { printf("%d ", sbr->f_master[k]); } printf("\n"); #endif return 0; } /* calculate the derived frequency border tables from f_master */ uint8_t derived_frequency_table(sbr_info *sbr, uint8_t bs_xover_band, uint8_t k2) { uint8_t k, i; uint32_t minus; /* The following relation shall be satisfied: bs_xover_band < N_Master */ if (sbr->N_master <= bs_xover_band) return 1; sbr->N_high = sbr->N_master - bs_xover_band; sbr->N_low = (sbr->N_high>>1) + (sbr->N_high - ((sbr->N_high>>1)<<1)); sbr->n[0] = sbr->N_low; sbr->n[1] = sbr->N_high; for (k = 0; k <= sbr->N_high; k++) { sbr->f_table_res[HI_RES][k] = sbr->f_master[k + bs_xover_band]; } sbr->M = sbr->f_table_res[HI_RES][sbr->N_high] - sbr->f_table_res[HI_RES][0]; sbr->kx = sbr->f_table_res[HI_RES][0]; if (sbr->kx > 32) return 1; if (sbr->kx + sbr->M > 64) return 1; minus = (sbr->N_high & 1) ? 1 : 0; for (k = 0; k <= sbr->N_low; k++) { if (k == 0) i = 0; else i = (uint8_t)(2*k - minus); sbr->f_table_res[LO_RES][k] = sbr->f_table_res[HI_RES][i]; } #if 0 printf("bs_freq_scale: %d\n", sbr->bs_freq_scale); printf("bs_limiter_bands: %d\n", sbr->bs_limiter_bands); printf("f_table_res[HI_RES][%d]: ", sbr->N_high); for (k = 0; k <= sbr->N_high; k++) { printf("%d ", sbr->f_table_res[HI_RES][k]); } printf("\n"); #endif #if 0 printf("f_table_res[LO_RES][%d]: ", sbr->N_low); for (k = 0; k <= sbr->N_low; k++) { printf("%d ", sbr->f_table_res[LO_RES][k]); } printf("\n"); #endif sbr->N_Q = 0; if (sbr->bs_noise_bands == 0) { sbr->N_Q = 1; } else { #if 0 sbr->N_Q = max(1, (int32_t)(sbr->bs_noise_bands*(log(k2/(float)sbr->kx)/log(2.0)) + 0.5)); #else sbr->N_Q = (uint8_t)(max(1, find_bands(0, sbr->bs_noise_bands, sbr->kx, k2))); #endif sbr->N_Q = min(5, sbr->N_Q); } for (k = 0; k <= sbr->N_Q; k++) { if (k == 0) { i = 0; } else { /* i = i + (int32_t)((sbr->N_low - i)/(sbr->N_Q + 1 - k)); */ i = i + (sbr->N_low - i)/(sbr->N_Q + 1 - k); } sbr->f_table_noise[k] = sbr->f_table_res[LO_RES][i]; } /* build table for mapping k to g in hf patching */ for (k = 0; k < 64; k++) { uint8_t g; for (g = 0; g < sbr->N_Q; g++) { if ((sbr->f_table_noise[g] <= k) && (k < sbr->f_table_noise[g+1])) { sbr->table_map_k_to_g[k] = g; break; } } } #if 0 printf("f_table_noise[%d]: ", sbr->N_Q); for (k = 0; k <= sbr->N_Q; k++) { printf("%d ", sbr->f_table_noise[k] - sbr->kx); } printf("\n"); #endif return 0; } /* TODO: blegh, ugly */ /* Modified to calculate for all possible bs_limiter_bands always * This reduces the number calls to this functions needed (now only on * header reset) */ void limiter_frequency_table(sbr_info *sbr) { #if 0 static const real_t limiterBandsPerOctave[] = { REAL_CONST(1.2), REAL_CONST(2), REAL_CONST(3) }; #else static const real_t limiterBandsCompare[] = { REAL_CONST(1.327152), REAL_CONST(1.185093), REAL_CONST(1.119872) }; #endif uint8_t k, s; int8_t nrLim; #if 0 real_t limBands; #endif sbr->f_table_lim[0][0] = sbr->f_table_res[LO_RES][0] - sbr->kx; sbr->f_table_lim[0][1] = sbr->f_table_res[LO_RES][sbr->N_low] - sbr->kx; sbr->N_L[0] = 1; #if 0 printf("f_table_lim[%d][%d]: ", 0, sbr->N_L[0]); for (k = 0; k <= sbr->N_L[0]; k++) { printf("%d ", sbr->f_table_lim[0][k]); } printf("\n"); #endif for (s = 1; s < 4; s++) { int32_t limTable[100 /*TODO*/] = {0}; uint8_t patchBorders[64/*??*/] = {0}; #if 0 limBands = limiterBandsPerOctave[s - 1]; #endif patchBorders[0] = sbr->kx; for (k = 1; k <= sbr->noPatches; k++) { patchBorders[k] = patchBorders[k-1] + sbr->patchNoSubbands[k-1]; } for (k = 0; k <= sbr->N_low; k++) { limTable[k] = sbr->f_table_res[LO_RES][k]; } for (k = 1; k < sbr->noPatches; k++) { limTable[k+sbr->N_low] = patchBorders[k]; } /* needed */ qsort(limTable, sbr->noPatches + sbr->N_low, sizeof(limTable[0]), longcmp); k = 1; nrLim = sbr->noPatches + sbr->N_low - 1; if (nrLim < 0) // TODO: BIG FAT PROBLEM return; restart: if (k <= nrLim) { real_t nOctaves; if (limTable[k-1] != 0) #if 0 nOctaves = REAL_CONST(log((float)limTable[k]/(float)limTable[k-1])/log(2.0)); #else #ifdef FIXED_POINT nOctaves = DIV_R((limTable[k]<noPatches; i++) { if (limTable[k] == patchBorders[i]) found = 1; } if (found) { found2 = 0; for (i = 0; i <= sbr->noPatches; i++) { if (limTable[k-1] == patchBorders[i]) found2 = 1; } if (found2) { k++; goto restart; } else { /* remove (k-1)th element */ limTable[k-1] = sbr->f_table_res[LO_RES][sbr->N_low]; qsort(limTable, sbr->noPatches + sbr->N_low, sizeof(limTable[0]), longcmp); nrLim--; goto restart; } } } /* remove kth element */ limTable[k] = sbr->f_table_res[LO_RES][sbr->N_low]; qsort(limTable, nrLim, sizeof(limTable[0]), longcmp); nrLim--; goto restart; } else { k++; goto restart; } } sbr->N_L[s] = nrLim; for (k = 0; k <= nrLim; k++) { sbr->f_table_lim[s][k] = limTable[k] - sbr->kx; } #if 0 printf("f_table_lim[%d][%d]: ", s, sbr->N_L[s]); for (k = 0; k <= sbr->N_L[s]; k++) { printf("%d ", sbr->f_table_lim[s][k]); } printf("\n"); #endif } } #endif xine-lib-1.2/contrib/libfaad/ps_dec.c0000644000175000017500000021427414647725152015321 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ps_dec.c,v 1.16 2009/01/26 22:32:31 menno Exp $ **/ #include "common.h" #ifdef PS_DEC #include #include "ps_dec.h" #include "ps_tables.h" /* constants */ #define NEGATE_IPD_MASK (0x1000) #define DECAY_SLOPE FRAC_CONST(0.05) #define COEF_SQRT2 COEF_CONST(1.4142135623731) /* tables */ /* filters are mirrored in coef 6, second half left out */ static const real_t p8_13_20[7] = { FRAC_CONST(0.00746082949812), FRAC_CONST(0.02270420949825), FRAC_CONST(0.04546865930473), FRAC_CONST(0.07266113929591), FRAC_CONST(0.09885108575264), FRAC_CONST(0.11793710567217), FRAC_CONST(0.125) }; static const real_t p2_13_20[7] = { FRAC_CONST(0.0), FRAC_CONST(0.01899487526049), FRAC_CONST(0.0), FRAC_CONST(-0.07293139167538), FRAC_CONST(0.0), FRAC_CONST(0.30596630545168), FRAC_CONST(0.5) }; static const real_t p12_13_34[7] = { FRAC_CONST(0.04081179924692), FRAC_CONST(0.03812810994926), FRAC_CONST(0.05144908135699), FRAC_CONST(0.06399831151592), FRAC_CONST(0.07428313801106), FRAC_CONST(0.08100347892914), FRAC_CONST(0.08333333333333) }; static const real_t p8_13_34[7] = { FRAC_CONST(0.01565675600122), FRAC_CONST(0.03752716391991), FRAC_CONST(0.05417891378782), FRAC_CONST(0.08417044116767), FRAC_CONST(0.10307344158036), FRAC_CONST(0.12222452249753), FRAC_CONST(0.125) }; static const real_t p4_13_34[7] = { FRAC_CONST(-0.05908211155639), FRAC_CONST(-0.04871498374946), FRAC_CONST(0.0), FRAC_CONST(0.07778723915851), FRAC_CONST(0.16486303567403), FRAC_CONST(0.23279856662996), FRAC_CONST(0.25) }; #ifdef PARAM_32KHZ static const uint8_t delay_length_d[2][NO_ALLPASS_LINKS] = { { 1, 2, 3 } /* d_24kHz */, { 3, 4, 5 } /* d_48kHz */ }; #else static const uint8_t delay_length_d[NO_ALLPASS_LINKS] = { 3, 4, 5 /* d_48kHz */ }; #endif static const real_t filter_a[NO_ALLPASS_LINKS] = { /* a(m) = exp(-d_48kHz(m)/7) */ FRAC_CONST(0.65143905753106), FRAC_CONST(0.56471812200776), FRAC_CONST(0.48954165955695) }; static const uint8_t group_border20[10+12 + 1] = { 6, 7, 0, 1, 2, 3, /* 6 subqmf subbands */ 9, 8, /* 2 subqmf subbands */ 10, 11, /* 2 subqmf subbands */ 3, 4, 5, 6, 7, 8, 9, 11, 14, 18, 23, 35, 64 }; static const uint8_t group_border34[32+18 + 1] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, /* 12 subqmf subbands */ 12, 13, 14, 15, 16, 17, 18, 19, /* 8 subqmf subbands */ 20, 21, 22, 23, /* 4 subqmf subbands */ 24, 25, 26, 27, /* 4 subqmf subbands */ 28, 29, 30, 31, /* 4 subqmf subbands */ 32-27, 33-27, 34-27, 35-27, 36-27, 37-27, 38-27, 40-27, 42-27, 44-27, 46-27, 48-27, 51-27, 54-27, 57-27, 60-27, 64-27, 68-27, 91-27 }; static const uint16_t map_group2bk20[10+12] = { (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 0), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 }; static const uint16_t map_group2bk34[32+18] = { 0, 1, 2, 3, 4, 5, 6, 6, 7, (NEGATE_IPD_MASK | 2), (NEGATE_IPD_MASK | 1), (NEGATE_IPD_MASK | 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, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 }; /* type definitions */ typedef struct { uint8_t frame_len; uint8_t resolution20[3]; uint8_t resolution34[5]; qmf_t *work; qmf_t **buffer; qmf_t **temp; } hyb_info; /* static function declarations */ static void ps_data_decode(ps_info *ps); static hyb_info *hybrid_init(uint8_t numTimeSlotsRate); static void channel_filter2(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid); static INLINE void DCT3_4_unscaled(real_t *y, real_t *x); static void channel_filter8(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid); static void hybrid_analysis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34, uint8_t numTimeSlotsRate); static void hybrid_synthesis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34, uint8_t numTimeSlotsRate); static int8_t delta_clip(int8_t i, int8_t min, int8_t max); static void delta_decode(uint8_t enable, int8_t *index, int8_t *index_prev, uint8_t dt_flag, uint8_t nr_par, uint8_t stride, int8_t min_index, int8_t max_index); static void delta_modulo_decode(uint8_t enable, int8_t *index, int8_t *index_prev, uint8_t dt_flag, uint8_t nr_par, uint8_t stride, int8_t and_modulo); static void map20indexto34(int8_t *index, uint8_t bins); #ifdef PS_LOW_POWER static void map34indexto20(int8_t *index, uint8_t bins); #endif static void ps_data_decode(ps_info *ps); static void ps_decorrelate(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]); static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]); /* */ static hyb_info *hybrid_init(uint8_t numTimeSlotsRate) { uint8_t i; hyb_info *hyb = (hyb_info*)faad_malloc(sizeof(hyb_info)); hyb->resolution34[0] = 12; hyb->resolution34[1] = 8; hyb->resolution34[2] = 4; hyb->resolution34[3] = 4; hyb->resolution34[4] = 4; hyb->resolution20[0] = 8; hyb->resolution20[1] = 2; hyb->resolution20[2] = 2; hyb->frame_len = numTimeSlotsRate; hyb->work = (qmf_t*)faad_malloc((hyb->frame_len+12) * sizeof(qmf_t)); memset(hyb->work, 0, (hyb->frame_len+12) * sizeof(qmf_t)); hyb->buffer = (qmf_t**)faad_malloc(5 * sizeof(qmf_t*)); for (i = 0; i < 5; i++) { hyb->buffer[i] = (qmf_t*)faad_malloc(hyb->frame_len * sizeof(qmf_t)); memset(hyb->buffer[i], 0, hyb->frame_len * sizeof(qmf_t)); } hyb->temp = (qmf_t**)faad_malloc(hyb->frame_len * sizeof(qmf_t*)); for (i = 0; i < hyb->frame_len; i++) { hyb->temp[i] = (qmf_t*)faad_malloc(12 /*max*/ * sizeof(qmf_t)); } return hyb; } static void hybrid_free(hyb_info *hyb) { uint8_t i; if (!hyb) return; if (hyb->work) faad_free(hyb->work); for (i = 0; i < 5; i++) { if (hyb->buffer[i]) faad_free(hyb->buffer[i]); } if (hyb->buffer) faad_free(hyb->buffer); for (i = 0; i < hyb->frame_len; i++) { if (hyb->temp[i]) faad_free(hyb->temp[i]); } if (hyb->temp) faad_free(hyb->temp); faad_free(hyb); } /* real filter, size 2 */ static void channel_filter2(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid) { uint8_t i; (void)hyb; /* why is this unused? */ for (i = 0; i < frame_len; i++) { real_t r0 = MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i]))); real_t r1 = MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i]))); real_t r2 = MUL_F(filter[2],(QMF_RE(buffer[2+i]) + QMF_RE(buffer[10+i]))); real_t r3 = MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i]))); real_t r4 = MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i]))); real_t r5 = MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i]))); real_t r6 = MUL_F(filter[6],QMF_RE(buffer[6+i])); real_t i0 = MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i]))); real_t i1 = MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i]))); real_t i2 = MUL_F(filter[2],(QMF_IM(buffer[2+i]) + QMF_IM(buffer[10+i]))); real_t i3 = MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i]))); real_t i4 = MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i]))); real_t i5 = MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i]))); real_t i6 = MUL_F(filter[6],QMF_IM(buffer[6+i])); /* q = 0 */ QMF_RE(X_hybrid[i][0]) = r0 + r1 + r2 + r3 + r4 + r5 + r6; QMF_IM(X_hybrid[i][0]) = i0 + i1 + i2 + i3 + i4 + i5 + i6; /* q = 1 */ QMF_RE(X_hybrid[i][1]) = r0 - r1 + r2 - r3 + r4 - r5 + r6; QMF_IM(X_hybrid[i][1]) = i0 - i1 + i2 - i3 + i4 - i5 + i6; } } /* complex filter, size 4 */ static void channel_filter4(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid) { uint8_t i; real_t input_re1[2], input_re2[2], input_im1[2], input_im2[2]; (void)hyb; /* why is this unused? */ for (i = 0; i < frame_len; i++) { input_re1[0] = -MUL_F(filter[2], (QMF_RE(buffer[i+2]) + QMF_RE(buffer[i+10]))) + MUL_F(filter[6], QMF_RE(buffer[i+6])); input_re1[1] = MUL_F(FRAC_CONST(-0.70710678118655), (MUL_F(filter[1], (QMF_RE(buffer[i+1]) + QMF_RE(buffer[i+11]))) + MUL_F(filter[3], (QMF_RE(buffer[i+3]) + QMF_RE(buffer[i+9]))) - MUL_F(filter[5], (QMF_RE(buffer[i+5]) + QMF_RE(buffer[i+7]))))); input_im1[0] = MUL_F(filter[0], (QMF_IM(buffer[i+0]) - QMF_IM(buffer[i+12]))) - MUL_F(filter[4], (QMF_IM(buffer[i+4]) - QMF_IM(buffer[i+8]))); input_im1[1] = MUL_F(FRAC_CONST(0.70710678118655), (MUL_F(filter[1], (QMF_IM(buffer[i+1]) - QMF_IM(buffer[i+11]))) - MUL_F(filter[3], (QMF_IM(buffer[i+3]) - QMF_IM(buffer[i+9]))) - MUL_F(filter[5], (QMF_IM(buffer[i+5]) - QMF_IM(buffer[i+7]))))); input_re2[0] = MUL_F(filter[0], (QMF_RE(buffer[i+0]) - QMF_RE(buffer[i+12]))) - MUL_F(filter[4], (QMF_RE(buffer[i+4]) - QMF_RE(buffer[i+8]))); input_re2[1] = MUL_F(FRAC_CONST(0.70710678118655), (MUL_F(filter[1], (QMF_RE(buffer[i+1]) - QMF_RE(buffer[i+11]))) - MUL_F(filter[3], (QMF_RE(buffer[i+3]) - QMF_RE(buffer[i+9]))) - MUL_F(filter[5], (QMF_RE(buffer[i+5]) - QMF_RE(buffer[i+7]))))); input_im2[0] = -MUL_F(filter[2], (QMF_IM(buffer[i+2]) + QMF_IM(buffer[i+10]))) + MUL_F(filter[6], QMF_IM(buffer[i+6])); input_im2[1] = MUL_F(FRAC_CONST(-0.70710678118655), (MUL_F(filter[1], (QMF_IM(buffer[i+1]) + QMF_IM(buffer[i+11]))) + MUL_F(filter[3], (QMF_IM(buffer[i+3]) + QMF_IM(buffer[i+9]))) - MUL_F(filter[5], (QMF_IM(buffer[i+5]) + QMF_IM(buffer[i+7]))))); /* q == 0 */ QMF_RE(X_hybrid[i][0]) = input_re1[0] + input_re1[1] + input_im1[0] + input_im1[1]; QMF_IM(X_hybrid[i][0]) = -input_re2[0] - input_re2[1] + input_im2[0] + input_im2[1]; /* q == 1 */ QMF_RE(X_hybrid[i][1]) = input_re1[0] - input_re1[1] - input_im1[0] + input_im1[1]; QMF_IM(X_hybrid[i][1]) = input_re2[0] - input_re2[1] + input_im2[0] - input_im2[1]; /* q == 2 */ QMF_RE(X_hybrid[i][2]) = input_re1[0] - input_re1[1] + input_im1[0] - input_im1[1]; QMF_IM(X_hybrid[i][2]) = -input_re2[0] + input_re2[1] + input_im2[0] - input_im2[1]; /* q == 3 */ QMF_RE(X_hybrid[i][3]) = input_re1[0] + input_re1[1] - input_im1[0] - input_im1[1]; QMF_IM(X_hybrid[i][3]) = input_re2[0] + input_re2[1] + input_im2[0] + input_im2[1]; } } static INLINE void DCT3_4_unscaled(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7, f8; f0 = MUL_F(x[2], FRAC_CONST(0.7071067811865476)); f1 = x[0] - f0; f2 = x[0] + f0; f3 = x[1] + x[3]; f4 = MUL_C(x[1], COEF_CONST(1.3065629648763766)); f5 = MUL_F(f3, FRAC_CONST(-0.9238795325112866)); f6 = MUL_F(x[3], FRAC_CONST(-0.5411961001461967)); f7 = f4 + f5; f8 = f6 - f5; y[3] = f2 - f8; y[0] = f2 + f8; y[2] = f1 - f7; y[1] = f1 + f7; } /* complex filter, size 8 */ static void channel_filter8(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid) { uint8_t i, n; real_t input_re1[4], input_re2[4], input_im1[4], input_im2[4]; real_t x[4]; (void)hyb; /* why is this unused? */ for (i = 0; i < frame_len; i++) { input_re1[0] = MUL_F(filter[6],QMF_RE(buffer[6+i])); input_re1[1] = MUL_F(filter[5],(QMF_RE(buffer[5+i]) + QMF_RE(buffer[7+i]))); input_re1[2] = -MUL_F(filter[0],(QMF_RE(buffer[0+i]) + QMF_RE(buffer[12+i]))) + MUL_F(filter[4],(QMF_RE(buffer[4+i]) + QMF_RE(buffer[8+i]))); input_re1[3] = -MUL_F(filter[1],(QMF_RE(buffer[1+i]) + QMF_RE(buffer[11+i]))) + MUL_F(filter[3],(QMF_RE(buffer[3+i]) + QMF_RE(buffer[9+i]))); input_im1[0] = MUL_F(filter[5],(QMF_IM(buffer[7+i]) - QMF_IM(buffer[5+i]))); input_im1[1] = MUL_F(filter[0],(QMF_IM(buffer[12+i]) - QMF_IM(buffer[0+i]))) + MUL_F(filter[4],(QMF_IM(buffer[8+i]) - QMF_IM(buffer[4+i]))); input_im1[2] = MUL_F(filter[1],(QMF_IM(buffer[11+i]) - QMF_IM(buffer[1+i]))) + MUL_F(filter[3],(QMF_IM(buffer[9+i]) - QMF_IM(buffer[3+i]))); input_im1[3] = MUL_F(filter[2],(QMF_IM(buffer[10+i]) - QMF_IM(buffer[2+i]))); for (n = 0; n < 4; n++) { x[n] = input_re1[n] - input_im1[3-n]; } DCT3_4_unscaled(x, x); QMF_RE(X_hybrid[i][7]) = x[0]; QMF_RE(X_hybrid[i][5]) = x[2]; QMF_RE(X_hybrid[i][3]) = x[3]; QMF_RE(X_hybrid[i][1]) = x[1]; for (n = 0; n < 4; n++) { x[n] = input_re1[n] + input_im1[3-n]; } DCT3_4_unscaled(x, x); QMF_RE(X_hybrid[i][6]) = x[1]; QMF_RE(X_hybrid[i][4]) = x[3]; QMF_RE(X_hybrid[i][2]) = x[2]; QMF_RE(X_hybrid[i][0]) = x[0]; input_im2[0] = MUL_F(filter[6],QMF_IM(buffer[6+i])); input_im2[1] = MUL_F(filter[5],(QMF_IM(buffer[5+i]) + QMF_IM(buffer[7+i]))); input_im2[2] = -MUL_F(filter[0],(QMF_IM(buffer[0+i]) + QMF_IM(buffer[12+i]))) + MUL_F(filter[4],(QMF_IM(buffer[4+i]) + QMF_IM(buffer[8+i]))); input_im2[3] = -MUL_F(filter[1],(QMF_IM(buffer[1+i]) + QMF_IM(buffer[11+i]))) + MUL_F(filter[3],(QMF_IM(buffer[3+i]) + QMF_IM(buffer[9+i]))); input_re2[0] = MUL_F(filter[5],(QMF_RE(buffer[7+i]) - QMF_RE(buffer[5+i]))); input_re2[1] = MUL_F(filter[0],(QMF_RE(buffer[12+i]) - QMF_RE(buffer[0+i]))) + MUL_F(filter[4],(QMF_RE(buffer[8+i]) - QMF_RE(buffer[4+i]))); input_re2[2] = MUL_F(filter[1],(QMF_RE(buffer[11+i]) - QMF_RE(buffer[1+i]))) + MUL_F(filter[3],(QMF_RE(buffer[9+i]) - QMF_RE(buffer[3+i]))); input_re2[3] = MUL_F(filter[2],(QMF_RE(buffer[10+i]) - QMF_RE(buffer[2+i]))); for (n = 0; n < 4; n++) { x[n] = input_im2[n] + input_re2[3-n]; } DCT3_4_unscaled(x, x); QMF_IM(X_hybrid[i][7]) = x[0]; QMF_IM(X_hybrid[i][5]) = x[2]; QMF_IM(X_hybrid[i][3]) = x[3]; QMF_IM(X_hybrid[i][1]) = x[1]; for (n = 0; n < 4; n++) { x[n] = input_im2[n] - input_re2[3-n]; } DCT3_4_unscaled(x, x); QMF_IM(X_hybrid[i][6]) = x[1]; QMF_IM(X_hybrid[i][4]) = x[3]; QMF_IM(X_hybrid[i][2]) = x[2]; QMF_IM(X_hybrid[i][0]) = x[0]; } } static INLINE void DCT3_6_unscaled(real_t *y, real_t *x) { real_t f0, f1, f2, f3, f4, f5, f6, f7; f0 = MUL_F(x[3], FRAC_CONST(0.70710678118655)); f1 = x[0] + f0; f2 = x[0] - f0; f3 = MUL_F((x[1] - x[5]), FRAC_CONST(0.70710678118655)); f4 = MUL_F(x[2], FRAC_CONST(0.86602540378444)) + MUL_F(x[4], FRAC_CONST(0.5)); f5 = f4 - x[4]; f6 = MUL_F(x[1], FRAC_CONST(0.96592582628907)) + MUL_F(x[5], FRAC_CONST(0.25881904510252)); f7 = f6 - f3; y[0] = f1 + f6 + f4; y[1] = f2 + f3 - x[4]; y[2] = f7 + f2 - f5; y[3] = f1 - f7 - f5; y[4] = f1 - f3 - x[4]; y[5] = f2 - f6 + f4; } /* complex filter, size 12 */ static void channel_filter12(hyb_info *hyb, uint8_t frame_len, const real_t *filter, qmf_t *buffer, qmf_t **X_hybrid) { uint8_t i, n; real_t input_re1[6], input_re2[6], input_im1[6], input_im2[6]; real_t out_re1[6], out_re2[6], out_im1[6], out_im2[6]; (void)hyb; /* why is this unused? */ for (i = 0; i < frame_len; i++) { for (n = 0; n < 6; n++) { if (n == 0) { input_re1[0] = MUL_F(QMF_RE(buffer[6+i]), filter[6]); input_re2[0] = MUL_F(QMF_IM(buffer[6+i]), filter[6]); } else { input_re1[6-n] = MUL_F((QMF_RE(buffer[n+i]) + QMF_RE(buffer[12-n+i])), filter[n]); input_re2[6-n] = MUL_F((QMF_IM(buffer[n+i]) + QMF_IM(buffer[12-n+i])), filter[n]); } input_im2[n] = MUL_F((QMF_RE(buffer[n+i]) - QMF_RE(buffer[12-n+i])), filter[n]); input_im1[n] = MUL_F((QMF_IM(buffer[n+i]) - QMF_IM(buffer[12-n+i])), filter[n]); } DCT3_6_unscaled(out_re1, input_re1); DCT3_6_unscaled(out_re2, input_re2); DCT3_6_unscaled(out_im1, input_im1); DCT3_6_unscaled(out_im2, input_im2); for (n = 0; n < 6; n += 2) { QMF_RE(X_hybrid[i][n]) = out_re1[n] - out_im1[n]; QMF_IM(X_hybrid[i][n]) = out_re2[n] + out_im2[n]; QMF_RE(X_hybrid[i][n+1]) = out_re1[n+1] + out_im1[n+1]; QMF_IM(X_hybrid[i][n+1]) = out_re2[n+1] - out_im2[n+1]; QMF_RE(X_hybrid[i][10-n]) = out_re1[n+1] - out_im1[n+1]; QMF_IM(X_hybrid[i][10-n]) = out_re2[n+1] + out_im2[n+1]; QMF_RE(X_hybrid[i][11-n]) = out_re1[n] + out_im1[n]; QMF_IM(X_hybrid[i][11-n]) = out_re2[n] - out_im2[n]; } } } /* Hybrid analysis: further split up QMF subbands * to improve frequency resolution */ static void hybrid_analysis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34, uint8_t numTimeSlotsRate) { uint8_t k, n, band; uint8_t offset = 0; uint8_t qmf_bands = (use34) ? 5 : 3; uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20; for (band = 0; band < qmf_bands; band++) { /* build working buffer */ memcpy(hyb->work, hyb->buffer[band], 12 * sizeof(qmf_t)); /* add new samples */ for (n = 0; n < hyb->frame_len; n++) { QMF_RE(hyb->work[12 + n]) = QMF_RE(X[n + 6 /*delay*/][band]); QMF_IM(hyb->work[12 + n]) = QMF_IM(X[n + 6 /*delay*/][band]); } /* store samples */ memcpy(hyb->buffer[band], hyb->work + hyb->frame_len, 12 * sizeof(qmf_t)); switch(resolution[band]) { case 2: /* Type B real filter, Q[p] = 2 */ channel_filter2(hyb, hyb->frame_len, p2_13_20, hyb->work, hyb->temp); break; case 4: /* Type A complex filter, Q[p] = 4 */ channel_filter4(hyb, hyb->frame_len, p4_13_34, hyb->work, hyb->temp); break; case 8: /* Type A complex filter, Q[p] = 8 */ channel_filter8(hyb, hyb->frame_len, (use34) ? p8_13_34 : p8_13_20, hyb->work, hyb->temp); break; case 12: /* Type A complex filter, Q[p] = 12 */ channel_filter12(hyb, hyb->frame_len, p12_13_34, hyb->work, hyb->temp); break; } for (n = 0; n < hyb->frame_len; n++) { for (k = 0; k < resolution[band]; k++) { QMF_RE(X_hybrid[n][offset + k]) = QMF_RE(hyb->temp[n][k]); QMF_IM(X_hybrid[n][offset + k]) = QMF_IM(hyb->temp[n][k]); } } offset += resolution[band]; } /* group hybrid channels */ if (!use34) { for (n = 0; n < numTimeSlotsRate; n++) { QMF_RE(X_hybrid[n][3]) += QMF_RE(X_hybrid[n][4]); QMF_IM(X_hybrid[n][3]) += QMF_IM(X_hybrid[n][4]); QMF_RE(X_hybrid[n][4]) = 0; QMF_IM(X_hybrid[n][4]) = 0; QMF_RE(X_hybrid[n][2]) += QMF_RE(X_hybrid[n][5]); QMF_IM(X_hybrid[n][2]) += QMF_IM(X_hybrid[n][5]); QMF_RE(X_hybrid[n][5]) = 0; QMF_IM(X_hybrid[n][5]) = 0; } } } static void hybrid_synthesis(hyb_info *hyb, qmf_t X[32][64], qmf_t X_hybrid[32][32], uint8_t use34, uint8_t numTimeSlotsRate) { uint8_t k, n, band; uint8_t offset = 0; uint8_t qmf_bands = (use34) ? 5 : 3; uint8_t *resolution = (use34) ? hyb->resolution34 : hyb->resolution20; (void)numTimeSlotsRate; /* why is this unused? */ for(band = 0; band < qmf_bands; band++) { for (n = 0; n < hyb->frame_len; n++) { QMF_RE(X[n][band]) = 0; QMF_IM(X[n][band]) = 0; for (k = 0; k < resolution[band]; k++) { QMF_RE(X[n][band]) += QMF_RE(X_hybrid[n][offset + k]); QMF_IM(X[n][band]) += QMF_IM(X_hybrid[n][offset + k]); } } offset += resolution[band]; } } /* limits the value i to the range [min,max] */ static int8_t delta_clip(int8_t i, int8_t min, int8_t max) { if (i < min) return min; else if (i > max) return max; else return i; } //int iid = 0; /* delta decode array */ static void delta_decode(uint8_t enable, int8_t *index, int8_t *index_prev, uint8_t dt_flag, uint8_t nr_par, uint8_t stride, int8_t min_index, int8_t max_index) { int8_t i; if (enable == 1) { if (dt_flag == 0) { /* delta coded in frequency direction */ index[0] = 0 + index[0]; index[0] = delta_clip(index[0], min_index, max_index); for (i = 1; i < nr_par; i++) { index[i] = index[i-1] + index[i]; index[i] = delta_clip(index[i], min_index, max_index); } } else { /* delta coded in time direction */ for (i = 0; i < nr_par; i++) { //int8_t tmp2; //int8_t tmp = index[i]; //printf("%d %d\n", index_prev[i*stride], index[i]); //printf("%d\n", index[i]); index[i] = index_prev[i*stride] + index[i]; //tmp2 = index[i]; index[i] = delta_clip(index[i], min_index, max_index); //if (iid) //{ // if (index[i] == 7) // { // printf("%d %d %d\n", index_prev[i*stride], tmp, tmp2); // } //} } } } else { /* set indices to zero */ for (i = 0; i < nr_par; i++) { index[i] = 0; } } /* coarse */ if (stride == 2) { for (i = (nr_par<<1)-1; i > 0; i--) { index[i] = index[i>>1]; } } } /* delta modulo decode array */ /* in: log2 value of the modulo value to allow using AND instead of MOD */ static void delta_modulo_decode(uint8_t enable, int8_t *index, int8_t *index_prev, uint8_t dt_flag, uint8_t nr_par, uint8_t stride, int8_t and_modulo) { int8_t i; if (enable == 1) { if (dt_flag == 0) { /* delta coded in frequency direction */ index[0] = 0 + index[0]; index[0] &= and_modulo; for (i = 1; i < nr_par; i++) { index[i] = index[i-1] + index[i]; index[i] &= and_modulo; } } else { /* delta coded in time direction */ for (i = 0; i < nr_par; i++) { index[i] = index_prev[i*stride] + index[i]; index[i] &= and_modulo; } } } else { /* set indices to zero */ for (i = 0; i < nr_par; i++) { index[i] = 0; } } /* coarse */ if (stride == 2) { index[0] = 0; for (i = (nr_par<<1)-1; i > 0; i--) { index[i] = index[i>>1]; } } } #ifdef PS_LOW_POWER static void map34indexto20(int8_t *index, uint8_t bins) { index[0] = (2*index[0]+index[1])/3; index[1] = (index[1]+2*index[2])/3; index[2] = (2*index[3]+index[4])/3; index[3] = (index[4]+2*index[5])/3; index[4] = (index[6]+index[7])/2; index[5] = (index[8]+index[9])/2; index[6] = index[10]; index[7] = index[11]; index[8] = (index[12]+index[13])/2; index[9] = (index[14]+index[15])/2; index[10] = index[16]; if (bins == 34) { index[11] = index[17]; index[12] = index[18]; index[13] = index[19]; index[14] = (index[20]+index[21])/2; index[15] = (index[22]+index[23])/2; index[16] = (index[24]+index[25])/2; index[17] = (index[26]+index[27])/2; index[18] = (index[28]+index[29]+index[30]+index[31])/4; index[19] = (index[32]+index[33])/2; } } #endif static void map20indexto34(int8_t *index, uint8_t bins) { index[0] = index[0]; index[1] = (index[0] + index[1])/2; index[2] = index[1]; index[3] = index[2]; index[4] = (index[2] + index[3])/2; index[5] = index[3]; index[6] = index[4]; index[7] = index[4]; index[8] = index[5]; index[9] = index[5]; index[10] = index[6]; index[11] = index[7]; index[12] = index[8]; index[13] = index[8]; index[14] = index[9]; index[15] = index[9]; index[16] = index[10]; if (bins == 34) { index[17] = index[11]; index[18] = index[12]; index[19] = index[13]; index[20] = index[14]; index[21] = index[14]; index[22] = index[15]; index[23] = index[15]; index[24] = index[16]; index[25] = index[16]; index[26] = index[17]; index[27] = index[17]; index[28] = index[18]; index[29] = index[18]; index[30] = index[18]; index[31] = index[18]; index[32] = index[19]; index[33] = index[19]; } } /* parse the bitstream data decoded in ps_data() */ static void ps_data_decode(ps_info *ps) { uint8_t env, bin; /* ps data not available, use data from previous frame */ if (ps->ps_data_available == 0) { ps->num_env = 0; } for (env = 0; env < ps->num_env; env++) { int8_t *iid_index_prev; int8_t *icc_index_prev; int8_t *ipd_index_prev; int8_t *opd_index_prev; int8_t num_iid_steps = (ps->iid_mode < 3) ? 7 : 15 /*fine quant*/; if (env == 0) { /* take last envelope from previous frame */ iid_index_prev = ps->iid_index_prev; icc_index_prev = ps->icc_index_prev; ipd_index_prev = ps->ipd_index_prev; opd_index_prev = ps->opd_index_prev; } else { /* take index values from previous envelope */ iid_index_prev = ps->iid_index[env - 1]; icc_index_prev = ps->icc_index[env - 1]; ipd_index_prev = ps->ipd_index[env - 1]; opd_index_prev = ps->opd_index[env - 1]; } // iid = 1; /* delta decode iid parameters */ delta_decode(ps->enable_iid, ps->iid_index[env], iid_index_prev, ps->iid_dt[env], ps->nr_iid_par, (ps->iid_mode == 0 || ps->iid_mode == 3) ? 2 : 1, -num_iid_steps, num_iid_steps); // iid = 0; /* delta decode icc parameters */ delta_decode(ps->enable_icc, ps->icc_index[env], icc_index_prev, ps->icc_dt[env], ps->nr_icc_par, (ps->icc_mode == 0 || ps->icc_mode == 3) ? 2 : 1, 0, 7); /* delta modulo decode ipd parameters */ delta_modulo_decode(ps->enable_ipdopd, ps->ipd_index[env], ipd_index_prev, ps->ipd_dt[env], ps->nr_ipdopd_par, 1, 7); /* delta modulo decode opd parameters */ delta_modulo_decode(ps->enable_ipdopd, ps->opd_index[env], opd_index_prev, ps->opd_dt[env], ps->nr_ipdopd_par, 1, 7); } /* handle error case */ if (ps->num_env == 0) { /* force to 1 */ ps->num_env = 1; if (ps->enable_iid) { for (bin = 0; bin < 34; bin++) ps->iid_index[0][bin] = ps->iid_index_prev[bin]; } else { for (bin = 0; bin < 34; bin++) ps->iid_index[0][bin] = 0; } if (ps->enable_icc) { for (bin = 0; bin < 34; bin++) ps->icc_index[0][bin] = ps->icc_index_prev[bin]; } else { for (bin = 0; bin < 34; bin++) ps->icc_index[0][bin] = 0; } if (ps->enable_ipdopd) { for (bin = 0; bin < 17; bin++) { ps->ipd_index[0][bin] = ps->ipd_index_prev[bin]; ps->opd_index[0][bin] = ps->opd_index_prev[bin]; } } else { for (bin = 0; bin < 17; bin++) { ps->ipd_index[0][bin] = 0; ps->opd_index[0][bin] = 0; } } } /* update previous indices */ for (bin = 0; bin < 34; bin++) ps->iid_index_prev[bin] = ps->iid_index[ps->num_env-1][bin]; for (bin = 0; bin < 34; bin++) ps->icc_index_prev[bin] = ps->icc_index[ps->num_env-1][bin]; for (bin = 0; bin < 17; bin++) { ps->ipd_index_prev[bin] = ps->ipd_index[ps->num_env-1][bin]; ps->opd_index_prev[bin] = ps->opd_index[ps->num_env-1][bin]; } ps->ps_data_available = 0; if (ps->frame_class == 0) { ps->border_position[0] = 0; for (env = 1; env < ps->num_env; env++) { ps->border_position[env] = (env * ps->numTimeSlotsRate) / ps->num_env; } ps->border_position[ps->num_env] = ps->numTimeSlotsRate; } else { ps->border_position[0] = 0; if (ps->border_position[ps->num_env] < ps->numTimeSlotsRate) { for (bin = 0; bin < 34; bin++) { ps->iid_index[ps->num_env][bin] = ps->iid_index[ps->num_env-1][bin]; ps->icc_index[ps->num_env][bin] = ps->icc_index[ps->num_env-1][bin]; } for (bin = 0; bin < 17; bin++) { ps->ipd_index[ps->num_env][bin] = ps->ipd_index[ps->num_env-1][bin]; ps->opd_index[ps->num_env][bin] = ps->opd_index[ps->num_env-1][bin]; } ps->num_env++; ps->border_position[ps->num_env] = ps->numTimeSlotsRate; } for (env = 1; env < ps->num_env; env++) { int8_t thr = ps->numTimeSlotsRate - (ps->num_env - env); if (ps->border_position[env] > thr) { ps->border_position[env] = thr; } else { thr = ps->border_position[env-1]+1; if (ps->border_position[env] < thr) { ps->border_position[env] = thr; } } } } /* make sure that the indices of all parameters can be mapped * to the same hybrid synthesis filterbank */ #ifdef PS_LOW_POWER for (env = 0; env < ps->num_env; env++) { if (ps->iid_mode == 2 || ps->iid_mode == 5) map34indexto20(ps->iid_index[env], 34); if (ps->icc_mode == 2 || ps->icc_mode == 5) map34indexto20(ps->icc_index[env], 34); /* disable ipd/opd */ for (bin = 0; bin < 17; bin++) { ps->aaIpdIndex[env][bin] = 0; ps->aaOpdIndex[env][bin] = 0; } } #else if (ps->use34hybrid_bands) { for (env = 0; env < ps->num_env; env++) { if (ps->iid_mode != 2 && ps->iid_mode != 5) map20indexto34(ps->iid_index[env], 34); if (ps->icc_mode != 2 && ps->icc_mode != 5) map20indexto34(ps->icc_index[env], 34); if (ps->ipd_mode != 2 && ps->ipd_mode != 5) { map20indexto34(ps->ipd_index[env], 17); map20indexto34(ps->opd_index[env], 17); } } } #endif #if 0 for (env = 0; env < ps->num_env; env++) { printf("iid[env:%d]:", env); for (bin = 0; bin < 34; bin++) { printf(" %d", ps->iid_index[env][bin]); } printf("\n"); } for (env = 0; env < ps->num_env; env++) { printf("icc[env:%d]:", env); for (bin = 0; bin < 34; bin++) { printf(" %d", ps->icc_index[env][bin]); } printf("\n"); } for (env = 0; env < ps->num_env; env++) { printf("ipd[env:%d]:", env); for (bin = 0; bin < 17; bin++) { printf(" %d", ps->ipd_index[env][bin]); } printf("\n"); } for (env = 0; env < ps->num_env; env++) { printf("opd[env:%d]:", env); for (bin = 0; bin < 17; bin++) { printf(" %d", ps->opd_index[env][bin]); } printf("\n"); } printf("\n"); #endif } /* decorrelate the mono signal using an allpass filter */ static void ps_decorrelate(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]) { uint8_t gr, n, m, bk; uint8_t temp_delay = 0; uint8_t sb, maxsb; const complex_t *Phi_Fract_SubQmf; uint8_t temp_delay_ser[NO_ALLPASS_LINKS]; real_t P_SmoothPeakDecayDiffNrg, nrg; real_t P[32][34]; real_t G_TransientRatio[32][34] = {{0}}; complex_t inputLeft; /* calm down gcc */ memset (temp_delay_ser, 0, sizeof (temp_delay_ser)); /* chose hybrid filterbank: 20 or 34 band case */ if (ps->use34hybrid_bands) { Phi_Fract_SubQmf = Phi_Fract_SubQmf34; } else{ Phi_Fract_SubQmf = Phi_Fract_SubQmf20; } /* clear the energy values */ for (n = 0; n < 32; n++) { for (bk = 0; bk < 34; bk++) { P[n][bk] = 0; } } /* calculate the energy in each parameter band b(k) */ for (gr = 0; gr < ps->num_groups; gr++) { /* select the parameter index b(k) to which this group belongs */ bk = (~NEGATE_IPD_MASK) & ps->map_group2bk[gr]; /* select the upper subband border for this group */ maxsb = (gr < ps->num_hybrid_groups) ? ps->group_border[gr]+1 : ps->group_border[gr+1]; for (sb = ps->group_border[gr]; sb < maxsb; sb++) { for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++) { #ifdef FIXED_POINT uint32_t in_re, in_im; #endif /* input from hybrid subbands or QMF subbands */ if (gr < ps->num_hybrid_groups) { RE(inputLeft) = QMF_RE(X_hybrid_left[n][sb]); IM(inputLeft) = QMF_IM(X_hybrid_left[n][sb]); } else { RE(inputLeft) = QMF_RE(X_left[n][sb]); IM(inputLeft) = QMF_IM(X_left[n][sb]); } /* accumulate energy */ #ifdef FIXED_POINT /* NOTE: all input is scaled by 2^(-5) because of fixed point QMF * meaning that P will be scaled by 2^(-10) compared to floating point version */ in_re = ((abs(RE(inputLeft))+(1<<(REAL_BITS-1)))>>REAL_BITS); in_im = ((abs(IM(inputLeft))+(1<<(REAL_BITS-1)))>>REAL_BITS); P[n][bk] += in_re*in_re + in_im*in_im; #else P[n][bk] += MUL_R(RE(inputLeft),RE(inputLeft)) + MUL_R(IM(inputLeft),IM(inputLeft)); #endif } } } #if 0 for (n = 0; n < 32; n++) { for (bk = 0; bk < 34; bk++) { #ifdef FIXED_POINT printf("%d %d: %d\n", n, bk, P[n][bk] /*/(float)REAL_PRECISION*/); #else printf("%d %d: %f\n", n, bk, P[n][bk]/1024.0); #endif } } #endif /* calculate transient reduction ratio for each parameter band b(k) */ for (bk = 0; bk < ps->nr_par_bands; bk++) { for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++) { const real_t gamma = COEF_CONST(1.5); ps->P_PeakDecayNrg[bk] = MUL_F(ps->P_PeakDecayNrg[bk], ps->alpha_decay); if (ps->P_PeakDecayNrg[bk] < P[n][bk]) ps->P_PeakDecayNrg[bk] = P[n][bk]; /* apply smoothing filter to peak decay energy */ P_SmoothPeakDecayDiffNrg = ps->P_SmoothPeakDecayDiffNrg_prev[bk]; P_SmoothPeakDecayDiffNrg += MUL_F((ps->P_PeakDecayNrg[bk] - P[n][bk] - ps->P_SmoothPeakDecayDiffNrg_prev[bk]), ps->alpha_smooth); ps->P_SmoothPeakDecayDiffNrg_prev[bk] = P_SmoothPeakDecayDiffNrg; /* apply smoothing filter to energy */ nrg = ps->P_prev[bk]; nrg += MUL_F((P[n][bk] - ps->P_prev[bk]), ps->alpha_smooth); ps->P_prev[bk] = nrg; /* calculate transient ratio */ if (MUL_C(P_SmoothPeakDecayDiffNrg, gamma) <= nrg) { G_TransientRatio[n][bk] = REAL_CONST(1.0); } else { G_TransientRatio[n][bk] = DIV_R(nrg, (MUL_C(P_SmoothPeakDecayDiffNrg, gamma))); } } } #if 0 for (n = 0; n < 32; n++) { for (bk = 0; bk < 34; bk++) { #ifdef FIXED_POINT printf("%d %d: %f\n", n, bk, G_TransientRatio[n][bk]/(float)REAL_PRECISION); #else printf("%d %d: %f\n", n, bk, G_TransientRatio[n][bk]); #endif } } #endif /* apply stereo decorrelation filter to the signal */ for (gr = 0; gr < ps->num_groups; gr++) { if (gr < ps->num_hybrid_groups) maxsb = ps->group_border[gr] + 1; else maxsb = ps->group_border[gr + 1]; /* QMF channel */ for (sb = ps->group_border[gr]; sb < maxsb; sb++) { real_t g_DecaySlope; real_t g_DecaySlope_filt[NO_ALLPASS_LINKS]; /* g_DecaySlope: [0..1] */ if (gr < ps->num_hybrid_groups || sb <= ps->decay_cutoff) { g_DecaySlope = FRAC_CONST(1.0); } else { int8_t decay = ps->decay_cutoff - sb; if (decay <= -20 /* -1/DECAY_SLOPE */) { g_DecaySlope = 0; } else { /* decay(int)*decay_slope(frac) = g_DecaySlope(frac) */ g_DecaySlope = FRAC_CONST(1.0) + DECAY_SLOPE * decay; } } /* calculate g_DecaySlope_filt for every m multiplied by filter_a[m] */ for (m = 0; m < NO_ALLPASS_LINKS; m++) { g_DecaySlope_filt[m] = MUL_F(g_DecaySlope, filter_a[m]); } /* set delay indices */ temp_delay = ps->saved_delay; for (n = 0; n < NO_ALLPASS_LINKS; n++) temp_delay_ser[n] = ps->delay_buf_index_ser[n]; for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++) { complex_t tmp, tmp0, R0; if (gr < ps->num_hybrid_groups) { /* hybrid filterbank input */ RE(inputLeft) = QMF_RE(X_hybrid_left[n][sb]); IM(inputLeft) = QMF_IM(X_hybrid_left[n][sb]); } else { /* QMF filterbank input */ RE(inputLeft) = QMF_RE(X_left[n][sb]); IM(inputLeft) = QMF_IM(X_left[n][sb]); } if (sb > ps->nr_allpass_bands && gr >= ps->num_hybrid_groups) { /* delay */ /* never hybrid subbands here, always QMF subbands */ RE(tmp) = RE(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]); IM(tmp) = IM(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]); RE(R0) = RE(tmp); IM(R0) = IM(tmp); RE(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]) = RE(inputLeft); IM(ps->delay_Qmf[ps->delay_buf_index_delay[sb]][sb]) = IM(inputLeft); } else { /* allpass filter */ uint8_t m; complex_t Phi_Fract; /* fetch parameters */ if (gr < ps->num_hybrid_groups) { /* select data from the hybrid subbands */ RE(tmp0) = RE(ps->delay_SubQmf[temp_delay][sb]); IM(tmp0) = IM(ps->delay_SubQmf[temp_delay][sb]); RE(ps->delay_SubQmf[temp_delay][sb]) = RE(inputLeft); IM(ps->delay_SubQmf[temp_delay][sb]) = IM(inputLeft); RE(Phi_Fract) = RE(Phi_Fract_SubQmf[sb]); IM(Phi_Fract) = IM(Phi_Fract_SubQmf[sb]); } else { /* select data from the QMF subbands */ RE(tmp0) = RE(ps->delay_Qmf[temp_delay][sb]); IM(tmp0) = IM(ps->delay_Qmf[temp_delay][sb]); RE(ps->delay_Qmf[temp_delay][sb]) = RE(inputLeft); IM(ps->delay_Qmf[temp_delay][sb]) = IM(inputLeft); RE(Phi_Fract) = RE(Phi_Fract_Qmf[sb]); IM(Phi_Fract) = IM(Phi_Fract_Qmf[sb]); } /* z^(-2) * Phi_Fract[k] */ ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Phi_Fract), IM(Phi_Fract)); RE(R0) = RE(tmp); IM(R0) = IM(tmp); for (m = 0; m < NO_ALLPASS_LINKS; m++) { complex_t Q_Fract_allpass, tmp2; /* fetch parameters */ if (gr < ps->num_hybrid_groups) { /* select data from the hybrid subbands */ RE(tmp0) = RE(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]); IM(tmp0) = IM(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]); if (ps->use34hybrid_bands) { RE(Q_Fract_allpass) = RE(Q_Fract_allpass_SubQmf34[sb][m]); IM(Q_Fract_allpass) = IM(Q_Fract_allpass_SubQmf34[sb][m]); } else { RE(Q_Fract_allpass) = RE(Q_Fract_allpass_SubQmf20[sb][m]); IM(Q_Fract_allpass) = IM(Q_Fract_allpass_SubQmf20[sb][m]); } } else { /* select data from the QMF subbands */ RE(tmp0) = RE(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]); IM(tmp0) = IM(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]); RE(Q_Fract_allpass) = RE(Q_Fract_allpass_Qmf[sb][m]); IM(Q_Fract_allpass) = IM(Q_Fract_allpass_Qmf[sb][m]); } /* delay by a fraction */ /* z^(-d(m)) * Q_Fract_allpass[k,m] */ ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Q_Fract_allpass), IM(Q_Fract_allpass)); /* -a(m) * g_DecaySlope[k] */ RE(tmp) += -MUL_F(g_DecaySlope_filt[m], RE(R0)); IM(tmp) += -MUL_F(g_DecaySlope_filt[m], IM(R0)); /* -a(m) * g_DecaySlope[k] * Q_Fract_allpass[k,m] * z^(-d(m)) */ RE(tmp2) = RE(R0) + MUL_F(g_DecaySlope_filt[m], RE(tmp)); IM(tmp2) = IM(R0) + MUL_F(g_DecaySlope_filt[m], IM(tmp)); /* store sample */ if (gr < ps->num_hybrid_groups) { RE(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]) = RE(tmp2); IM(ps->delay_SubQmf_ser[m][temp_delay_ser[m]][sb]) = IM(tmp2); } else { RE(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]) = RE(tmp2); IM(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]) = IM(tmp2); } /* store for next iteration (or as output value if last iteration) */ RE(R0) = RE(tmp); IM(R0) = IM(tmp); } } /* select b(k) for reading the transient ratio */ bk = (~NEGATE_IPD_MASK) & ps->map_group2bk[gr]; /* duck if a past transient is found */ RE(R0) = MUL_R(G_TransientRatio[n][bk], RE(R0)); IM(R0) = MUL_R(G_TransientRatio[n][bk], IM(R0)); if (gr < ps->num_hybrid_groups) { /* hybrid */ QMF_RE(X_hybrid_right[n][sb]) = RE(R0); QMF_IM(X_hybrid_right[n][sb]) = IM(R0); } else { /* QMF */ QMF_RE(X_right[n][sb]) = RE(R0); QMF_IM(X_right[n][sb]) = IM(R0); } /* Update delay buffer index */ if (++temp_delay >= 2) { temp_delay = 0; } /* update delay indices */ if (sb > ps->nr_allpass_bands && gr >= ps->num_hybrid_groups) { /* delay_D depends on the samplerate, it can hold the values 14 and 1 */ if (++ps->delay_buf_index_delay[sb] >= ps->delay_D[sb]) { ps->delay_buf_index_delay[sb] = 0; } } for (m = 0; m < NO_ALLPASS_LINKS; m++) { if (++temp_delay_ser[m] >= ps->num_sample_delay_ser[m]) { temp_delay_ser[m] = 0; } } } } } /* update delay indices */ ps->saved_delay = temp_delay; for (m = 0; m < NO_ALLPASS_LINKS; m++) ps->delay_buf_index_ser[m] = temp_delay_ser[m]; } #ifdef FIXED_POINT #define step(shift) \ if ((0x40000000l >> shift) + root <= value) \ { \ value -= (0x40000000l >> shift) + root; \ root = (root >> 1) | (0x40000000l >> shift); \ } else { \ root = root >> 1; \ } /* fixed point square root approximation */ static real_t ps_sqrt(real_t value) { real_t root = 0; step( 0); step( 2); step( 4); step( 6); step( 8); step(10); step(12); step(14); step(16); step(18); step(20); step(22); step(24); step(26); step(28); step(30); if (root < value) ++root; root <<= (REAL_BITS/2); return root; } #else #define ps_sqrt(A) sqrt(A) #endif static const real_t ipdopd_cos_tab[] = { FRAC_CONST(1.000000000000000), FRAC_CONST(0.707106781186548), FRAC_CONST(0.000000000000000), FRAC_CONST(-0.707106781186547), FRAC_CONST(-1.000000000000000), FRAC_CONST(-0.707106781186548), FRAC_CONST(-0.000000000000000), FRAC_CONST(0.707106781186547), FRAC_CONST(1.000000000000000) }; static const real_t ipdopd_sin_tab[] = { FRAC_CONST(0.000000000000000), FRAC_CONST(0.707106781186547), FRAC_CONST(1.000000000000000), FRAC_CONST(0.707106781186548), FRAC_CONST(0.000000000000000), FRAC_CONST(-0.707106781186547), FRAC_CONST(-1.000000000000000), FRAC_CONST(-0.707106781186548), FRAC_CONST(-0.000000000000000) }; static real_t magnitude_c(complex_t c) { #ifdef FIXED_POINT #define ps_abs(A) (((A) > 0) ? (A) : (-(A))) #define ALPHA FRAC_CONST(0.948059448969) #define BETA FRAC_CONST(0.392699081699) real_t abs_inphase = ps_abs(RE(c)); real_t abs_quadrature = ps_abs(IM(c)); if (abs_inphase > abs_quadrature) { return MUL_F(abs_inphase, ALPHA) + MUL_F(abs_quadrature, BETA); } else { return MUL_F(abs_quadrature, ALPHA) + MUL_F(abs_inphase, BETA); } #else return sqrt(RE(c)*RE(c) + IM(c)*IM(c)); #endif } static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64], qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]) { uint8_t n; uint8_t gr; uint8_t bk = 0; uint8_t sb, maxsb; uint8_t env; uint8_t nr_ipdopd_par; /* calm down gcc */ complex_t h11 = {0, 0}, h12 = {0, 0}, h21 = {0, 0}, h22 = {0, 0}; complex_t H11 = {0, 0}, H12 = {0, 0}, H21 = {0, 0}, H22 = {0, 0}; complex_t deltaH11 = {0, 0}, deltaH12 = {0, 0}, deltaH21 = {0, 0}, deltaH22 = {0, 0}; complex_t tempLeft; complex_t tempRight; complex_t phaseLeft; complex_t phaseRight; real_t L; const real_t *sf_iid; uint8_t no_iid_steps; if (ps->iid_mode >= 3) { no_iid_steps = 15; sf_iid = sf_iid_fine; } else { no_iid_steps = 7; sf_iid = sf_iid_normal; } if (ps->ipd_mode == 0 || ps->ipd_mode == 3) { nr_ipdopd_par = 11; /* resolution */ } else { nr_ipdopd_par = ps->nr_ipdopd_par; } for (gr = 0; gr < ps->num_groups; gr++) { bk = (~NEGATE_IPD_MASK) & ps->map_group2bk[gr]; /* use one channel per group in the subqmf domain */ maxsb = (gr < ps->num_hybrid_groups) ? ps->group_border[gr] + 1 : ps->group_border[gr + 1]; for (env = 0; env < ps->num_env; env++) { if (ps->icc_mode < 3) { /* type 'A' mixing as described in 8.6.4.6.2.1 */ real_t c_1, c_2; real_t cosa, sina; real_t cosb, sinb; real_t ab1, ab2; real_t ab3, ab4; /* c_1 = sqrt(2.0 / (1.0 + pow(10.0, quant_iid[no_iid_steps + iid_index] / 10.0))); c_2 = sqrt(2.0 / (1.0 + pow(10.0, quant_iid[no_iid_steps - iid_index] / 10.0))); alpha = 0.5 * acos(quant_rho[icc_index]); beta = alpha * ( c_1 - c_2 ) / sqrt(2.0); */ //printf("%d\n", ps->iid_index[env][bk]); /* calculate the scalefactors c_1 and c_2 from the intensity differences */ c_1 = sf_iid[no_iid_steps + ps->iid_index[env][bk]]; c_2 = sf_iid[no_iid_steps - ps->iid_index[env][bk]]; /* calculate alpha and beta using the ICC parameters */ cosa = cos_alphas[ps->icc_index[env][bk]]; sina = sin_alphas[ps->icc_index[env][bk]]; if (ps->iid_mode >= 3) { if (ps->iid_index[env][bk] < 0) { cosb = cos_betas_fine[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = -sin_betas_fine[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } else { cosb = cos_betas_fine[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = sin_betas_fine[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } } else { if (ps->iid_index[env][bk] < 0) { cosb = cos_betas_normal[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = -sin_betas_normal[-ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } else { cosb = cos_betas_normal[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sinb = sin_betas_normal[ps->iid_index[env][bk]][ps->icc_index[env][bk]]; } } ab1 = MUL_C(cosb, cosa); ab2 = MUL_C(sinb, sina); ab3 = MUL_C(sinb, cosa); ab4 = MUL_C(cosb, sina); /* h_xy: COEF */ RE(h11) = MUL_C(c_2, (ab1 - ab2)); RE(h12) = MUL_C(c_1, (ab1 + ab2)); RE(h21) = MUL_C(c_2, (ab3 + ab4)); RE(h22) = MUL_C(c_1, (ab3 - ab4)); } else { /* type 'B' mixing as described in 8.6.4.6.2.2 */ real_t sina, cosa; real_t cosg, sing; /* real_t c, rho, mu, alpha, gamma; uint8_t i; i = ps->iid_index[env][bk]; c = (real_t)pow(10.0, ((i)?(((i>0)?1:-1)*quant_iid[((i>0)?i:-i)-1]):0.)/20.0); rho = quant_rho[ps->icc_index[env][bk]]; if (rho == 0.0f && c == 1.) { alpha = (real_t)M_PI/4.0f; rho = 0.05f; } else { if (rho <= 0.05f) { rho = 0.05f; } alpha = 0.5f*(real_t)atan( (2.0f*c*rho) / (c*c-1.0f) ); if (alpha < 0.) { alpha += (real_t)M_PI/2.0f; } if (rho < 0.) { alpha += (real_t)M_PI; } } mu = c+1.0f/c; mu = 1+(4.0f*rho*rho-4.0f)/(mu*mu); gamma = (real_t)atan(sqrt((1.0f-sqrt(mu))/(1.0f+sqrt(mu)))); */ if (ps->iid_mode >= 3) { uint8_t abs_iid = abs(ps->iid_index[env][bk]); cosa = sincos_alphas_B_fine[no_iid_steps + ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sina = sincos_alphas_B_fine[30 - (no_iid_steps + ps->iid_index[env][bk])][ps->icc_index[env][bk]]; cosg = cos_gammas_fine[abs_iid][ps->icc_index[env][bk]]; sing = sin_gammas_fine[abs_iid][ps->icc_index[env][bk]]; } else { uint8_t abs_iid = abs(ps->iid_index[env][bk]); cosa = sincos_alphas_B_normal[no_iid_steps + ps->iid_index[env][bk]][ps->icc_index[env][bk]]; sina = sincos_alphas_B_normal[14 - (no_iid_steps + ps->iid_index[env][bk])][ps->icc_index[env][bk]]; cosg = cos_gammas_normal[abs_iid][ps->icc_index[env][bk]]; sing = sin_gammas_normal[abs_iid][ps->icc_index[env][bk]]; } RE(h11) = MUL_C(COEF_SQRT2, MUL_C(cosa, cosg)); RE(h12) = MUL_C(COEF_SQRT2, MUL_C(sina, cosg)); RE(h21) = MUL_C(COEF_SQRT2, MUL_C(-cosa, sing)); RE(h22) = MUL_C(COEF_SQRT2, MUL_C(sina, sing)); } /* calculate phase rotation parameters H_xy */ /* note that the imaginary part of these parameters are only calculated when IPD and OPD are enabled */ if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { int8_t i; real_t xy, pq, xypq; /* ringbuffer index */ i = ps->phase_hist; /* previous value */ #ifdef FIXED_POINT /* divide by 4, shift right 2 bits */ RE(tempLeft) = RE(ps->ipd_prev[bk][i]) >> 2; IM(tempLeft) = IM(ps->ipd_prev[bk][i]) >> 2; RE(tempRight) = RE(ps->opd_prev[bk][i]) >> 2; IM(tempRight) = IM(ps->opd_prev[bk][i]) >> 2; #else RE(tempLeft) = MUL_F(RE(ps->ipd_prev[bk][i]), FRAC_CONST(0.25)); IM(tempLeft) = MUL_F(IM(ps->ipd_prev[bk][i]), FRAC_CONST(0.25)); RE(tempRight) = MUL_F(RE(ps->opd_prev[bk][i]), FRAC_CONST(0.25)); IM(tempRight) = MUL_F(IM(ps->opd_prev[bk][i]), FRAC_CONST(0.25)); #endif /* save current value */ RE(ps->ipd_prev[bk][i]) = ipdopd_cos_tab[abs(ps->ipd_index[env][bk])]; IM(ps->ipd_prev[bk][i]) = ipdopd_sin_tab[abs(ps->ipd_index[env][bk])]; RE(ps->opd_prev[bk][i]) = ipdopd_cos_tab[abs(ps->opd_index[env][bk])]; IM(ps->opd_prev[bk][i]) = ipdopd_sin_tab[abs(ps->opd_index[env][bk])]; /* add current value */ RE(tempLeft) += RE(ps->ipd_prev[bk][i]); IM(tempLeft) += IM(ps->ipd_prev[bk][i]); RE(tempRight) += RE(ps->opd_prev[bk][i]); IM(tempRight) += IM(ps->opd_prev[bk][i]); /* ringbuffer index */ if (i == 0) { i = 2; } i--; /* get value before previous */ #ifdef FIXED_POINT /* dividing by 2, shift right 1 bit */ RE(tempLeft) += (RE(ps->ipd_prev[bk][i]) >> 1); IM(tempLeft) += (IM(ps->ipd_prev[bk][i]) >> 1); RE(tempRight) += (RE(ps->opd_prev[bk][i]) >> 1); IM(tempRight) += (IM(ps->opd_prev[bk][i]) >> 1); #else RE(tempLeft) += MUL_F(RE(ps->ipd_prev[bk][i]), FRAC_CONST(0.5)); IM(tempLeft) += MUL_F(IM(ps->ipd_prev[bk][i]), FRAC_CONST(0.5)); RE(tempRight) += MUL_F(RE(ps->opd_prev[bk][i]), FRAC_CONST(0.5)); IM(tempRight) += MUL_F(IM(ps->opd_prev[bk][i]), FRAC_CONST(0.5)); #endif #if 0 /* original code */ ipd = (float)atan2(IM(tempLeft), RE(tempLeft)); opd = (float)atan2(IM(tempRight), RE(tempRight)); /* phase rotation */ RE(phaseLeft) = (float)cos(opd); IM(phaseLeft) = (float)sin(opd); opd -= ipd; RE(phaseRight) = (float)cos(opd); IM(phaseRight) = (float)sin(opd); #else // x = IM(tempLeft) // y = RE(tempLeft) // p = IM(tempRight) // q = RE(tempRight) // cos(atan2(x,y)) = y/sqrt((x*x) + (y*y)) // sin(atan2(x,y)) = x/sqrt((x*x) + (y*y)) // cos(atan2(x,y)-atan2(p,q)) = (y*q + x*p) / ( sqrt((x*x) + (y*y)) * sqrt((p*p) + (q*q)) ); // sin(atan2(x,y)-atan2(p,q)) = (x*q - y*p) / ( sqrt((x*x) + (y*y)) * sqrt((p*p) + (q*q)) ); xy = magnitude_c(tempRight); pq = magnitude_c(tempLeft); if (xy != 0) { RE(phaseLeft) = DIV_R(RE(tempRight), xy); IM(phaseLeft) = DIV_R(IM(tempRight), xy); } else { RE(phaseLeft) = 0; IM(phaseLeft) = 0; } xypq = MUL_R(xy, pq); if (xypq != 0) { real_t tmp1 = MUL_R(RE(tempRight), RE(tempLeft)) + MUL_R(IM(tempRight), IM(tempLeft)); real_t tmp2 = MUL_R(IM(tempRight), RE(tempLeft)) - MUL_R(RE(tempRight), IM(tempLeft)); RE(phaseRight) = DIV_R(tmp1, xypq); IM(phaseRight) = DIV_R(tmp2, xypq); } else { RE(phaseRight) = 0; IM(phaseRight) = 0; } #endif /* MUL_F(COEF, REAL) = COEF */ IM(h11) = MUL_R(RE(h11), IM(phaseLeft)); IM(h12) = MUL_R(RE(h12), IM(phaseRight)); IM(h21) = MUL_R(RE(h21), IM(phaseLeft)); IM(h22) = MUL_R(RE(h22), IM(phaseRight)); RE(h11) = MUL_R(RE(h11), RE(phaseLeft)); RE(h12) = MUL_R(RE(h12), RE(phaseRight)); RE(h21) = MUL_R(RE(h21), RE(phaseLeft)); RE(h22) = MUL_R(RE(h22), RE(phaseRight)); } /* length of the envelope n_e+1 - n_e (in time samples) */ /* 0 < L <= 32: integer */ L = (real_t)(ps->border_position[env + 1] - ps->border_position[env]); /* obtain final H_xy by means of linear interpolation */ RE(deltaH11) = (RE(h11) - RE(ps->h11_prev[gr])) / L; RE(deltaH12) = (RE(h12) - RE(ps->h12_prev[gr])) / L; RE(deltaH21) = (RE(h21) - RE(ps->h21_prev[gr])) / L; RE(deltaH22) = (RE(h22) - RE(ps->h22_prev[gr])) / L; RE(H11) = RE(ps->h11_prev[gr]); RE(H12) = RE(ps->h12_prev[gr]); RE(H21) = RE(ps->h21_prev[gr]); RE(H22) = RE(ps->h22_prev[gr]); RE(ps->h11_prev[gr]) = RE(h11); RE(ps->h12_prev[gr]) = RE(h12); RE(ps->h21_prev[gr]) = RE(h21); RE(ps->h22_prev[gr]) = RE(h22); /* only calculate imaginary part when needed */ if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { /* obtain final H_xy by means of linear interpolation */ IM(deltaH11) = (IM(h11) - IM(ps->h11_prev[gr])) / L; IM(deltaH12) = (IM(h12) - IM(ps->h12_prev[gr])) / L; IM(deltaH21) = (IM(h21) - IM(ps->h21_prev[gr])) / L; IM(deltaH22) = (IM(h22) - IM(ps->h22_prev[gr])) / L; IM(H11) = IM(ps->h11_prev[gr]); IM(H12) = IM(ps->h12_prev[gr]); IM(H21) = IM(ps->h21_prev[gr]); IM(H22) = IM(ps->h22_prev[gr]); if ((NEGATE_IPD_MASK & ps->map_group2bk[gr]) != 0) { IM(deltaH11) = -IM(deltaH11); IM(deltaH12) = -IM(deltaH12); IM(deltaH21) = -IM(deltaH21); IM(deltaH22) = -IM(deltaH22); IM(H11) = -IM(H11); IM(H12) = -IM(H12); IM(H21) = -IM(H21); IM(H22) = -IM(H22); } IM(ps->h11_prev[gr]) = IM(h11); IM(ps->h12_prev[gr]) = IM(h12); IM(ps->h21_prev[gr]) = IM(h21); IM(ps->h22_prev[gr]) = IM(h22); } /* apply H_xy to the current envelope band of the decorrelated subband */ for (n = ps->border_position[env]; n < ps->border_position[env + 1]; n++) { /* addition finalises the interpolation over every n */ RE(H11) += RE(deltaH11); RE(H12) += RE(deltaH12); RE(H21) += RE(deltaH21); RE(H22) += RE(deltaH22); if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { IM(H11) += IM(deltaH11); IM(H12) += IM(deltaH12); IM(H21) += IM(deltaH21); IM(H22) += IM(deltaH22); } /* channel is an alias to the subband */ for (sb = ps->group_border[gr]; sb < maxsb; sb++) { complex_t inLeft, inRight; /* load decorrelated samples */ if (gr < ps->num_hybrid_groups) { RE(inLeft) = RE(X_hybrid_left[n][sb]); IM(inLeft) = IM(X_hybrid_left[n][sb]); RE(inRight) = RE(X_hybrid_right[n][sb]); IM(inRight) = IM(X_hybrid_right[n][sb]); } else { RE(inLeft) = RE(X_left[n][sb]); IM(inLeft) = IM(X_left[n][sb]); RE(inRight) = RE(X_right[n][sb]); IM(inRight) = IM(X_right[n][sb]); } /* apply mixing */ RE(tempLeft) = MUL_C(RE(H11), RE(inLeft)) + MUL_C(RE(H21), RE(inRight)); IM(tempLeft) = MUL_C(RE(H11), IM(inLeft)) + MUL_C(RE(H21), IM(inRight)); RE(tempRight) = MUL_C(RE(H12), RE(inLeft)) + MUL_C(RE(H22), RE(inRight)); IM(tempRight) = MUL_C(RE(H12), IM(inLeft)) + MUL_C(RE(H22), IM(inRight)); /* only perform imaginary operations when needed */ if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par)) { /* apply rotation */ RE(tempLeft) -= MUL_C(IM(H11), IM(inLeft)) + MUL_C(IM(H21), IM(inRight)); IM(tempLeft) += MUL_C(IM(H11), RE(inLeft)) + MUL_C(IM(H21), RE(inRight)); RE(tempRight) -= MUL_C(IM(H12), IM(inLeft)) + MUL_C(IM(H22), IM(inRight)); IM(tempRight) += MUL_C(IM(H12), RE(inLeft)) + MUL_C(IM(H22), RE(inRight)); } /* store final samples */ if (gr < ps->num_hybrid_groups) { RE(X_hybrid_left[n][sb]) = RE(tempLeft); IM(X_hybrid_left[n][sb]) = IM(tempLeft); RE(X_hybrid_right[n][sb]) = RE(tempRight); IM(X_hybrid_right[n][sb]) = IM(tempRight); } else { RE(X_left[n][sb]) = RE(tempLeft); IM(X_left[n][sb]) = IM(tempLeft); RE(X_right[n][sb]) = RE(tempRight); IM(X_right[n][sb]) = IM(tempRight); } } } /* shift phase smoother's circular buffer index */ ps->phase_hist++; if (ps->phase_hist == 2) { ps->phase_hist = 0; } } } } void ps_free(ps_info *ps) { /* free hybrid filterbank structures */ hybrid_free(ps->hyb); faad_free(ps); } ps_info *ps_init(uint8_t sr_index, uint8_t numTimeSlotsRate) { uint8_t i; uint8_t short_delay_band; ps_info *ps = (ps_info*)faad_malloc(sizeof(ps_info)); memset(ps, 0, sizeof(ps_info)); ps->hyb = hybrid_init(numTimeSlotsRate); ps->numTimeSlotsRate = numTimeSlotsRate; ps->ps_data_available = 0; /* delay stuff*/ ps->saved_delay = 0; for (i = 0; i < 64; i++) { ps->delay_buf_index_delay[i] = 0; } for (i = 0; i < NO_ALLPASS_LINKS; i++) { ps->delay_buf_index_ser[i] = 0; #ifdef PARAM_32KHZ if (sr_index <= 5) /* >= 32 kHz*/ { ps->num_sample_delay_ser[i] = delay_length_d[1][i]; } else { ps->num_sample_delay_ser[i] = delay_length_d[0][i]; } #else (void)sr_index; /* THESE ARE CONSTANTS NOW */ ps->num_sample_delay_ser[i] = delay_length_d[i]; #endif } #ifdef PARAM_32KHZ if (sr_index <= 5) /* >= 32 kHz*/ { short_delay_band = 35; ps->nr_allpass_bands = 22; ps->alpha_decay = FRAC_CONST(0.76592833836465); ps->alpha_smooth = FRAC_CONST(0.25); } else { short_delay_band = 64; ps->nr_allpass_bands = 45; ps->alpha_decay = FRAC_CONST(0.58664621951003); ps->alpha_smooth = FRAC_CONST(0.6); } #else /* THESE ARE CONSTANTS NOW */ short_delay_band = 35; ps->nr_allpass_bands = 22; ps->alpha_decay = FRAC_CONST(0.76592833836465); ps->alpha_smooth = FRAC_CONST(0.25); #endif /* THESE ARE CONSTANT NOW IF PS IS INDEPENDANT OF SAMPLERATE */ for (i = 0; i < short_delay_band; i++) { ps->delay_D[i] = 14; } for (i = short_delay_band; i < 64; i++) { ps->delay_D[i] = 1; } /* mixing and phase */ for (i = 0; i < 50; i++) { RE(ps->h11_prev[i]) = 1; IM(ps->h12_prev[i]) = 1; RE(ps->h11_prev[i]) = 1; IM(ps->h12_prev[i]) = 1; } ps->phase_hist = 0; for (i = 0; i < 20; i++) { RE(ps->ipd_prev[i][0]) = 0; IM(ps->ipd_prev[i][0]) = 0; RE(ps->ipd_prev[i][1]) = 0; IM(ps->ipd_prev[i][1]) = 0; RE(ps->opd_prev[i][0]) = 0; IM(ps->opd_prev[i][0]) = 0; RE(ps->opd_prev[i][1]) = 0; IM(ps->opd_prev[i][1]) = 0; } return ps; } /* main Parametric Stereo decoding function */ uint8_t ps_decode(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]) { #ifndef SBR_LOW_POWER # define QMF_ZERO {0,0} #else # define QMF_ZERO 0 #endif qmf_t X_hybrid_left[32][32] = {{QMF_ZERO}}; qmf_t X_hybrid_right[32][32] = {{QMF_ZERO}}; /* delta decoding of the bitstream data */ ps_data_decode(ps); /* set up some parameters depending on filterbank type */ if (ps->use34hybrid_bands) { ps->group_border = (uint8_t*)group_border34; ps->map_group2bk = (uint16_t*)map_group2bk34; ps->num_groups = 32+18; ps->num_hybrid_groups = 32; ps->nr_par_bands = 34; ps->decay_cutoff = 5; } else { ps->group_border = (uint8_t*)group_border20; ps->map_group2bk = (uint16_t*)map_group2bk20; ps->num_groups = 10+12; ps->num_hybrid_groups = 10; ps->nr_par_bands = 20; ps->decay_cutoff = 3; } /* Perform further analysis on the lowest subbands to get a higher * frequency resolution */ hybrid_analysis((hyb_info*)ps->hyb, X_left, X_hybrid_left, ps->use34hybrid_bands, ps->numTimeSlotsRate); /* decorrelate mono signal */ ps_decorrelate(ps, X_left, X_right, X_hybrid_left, X_hybrid_right); /* apply mixing and phase parameters */ ps_mix_phase(ps, X_left, X_right, X_hybrid_left, X_hybrid_right); /* hybrid synthesis, to rebuild the SBR QMF matrices */ hybrid_synthesis((hyb_info*)ps->hyb, X_left, X_hybrid_left, ps->use34hybrid_bands, ps->numTimeSlotsRate); hybrid_synthesis((hyb_info*)ps->hyb, X_right, X_hybrid_right, ps->use34hybrid_bands, ps->numTimeSlotsRate); return 0; } #endif xine-lib-1.2/contrib/libfaad/is.c0000644000175000017500000000756514647725152014502 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: is.c,v 1.28 2007/11/01 12:33:31 menno Exp $ **/ #include "common.h" #include "structs.h" #include "syntax.h" #include "is.h" #ifdef FIXED_POINT static real_t pow05_table[] = { COEF_CONST(1.68179283050743), /* 0.5^(-3/4) */ COEF_CONST(1.41421356237310), /* 0.5^(-2/4) */ COEF_CONST(1.18920711500272), /* 0.5^(-1/4) */ COEF_CONST(1.0), /* 0.5^( 0/4) */ COEF_CONST(0.84089641525371), /* 0.5^(+1/4) */ COEF_CONST(0.70710678118655), /* 0.5^(+2/4) */ COEF_CONST(0.59460355750136) /* 0.5^(+3/4) */ }; #endif void is_decode(ic_stream *ics, ic_stream *icsr, real_t *l_spec, real_t *r_spec, uint16_t frame_len) { uint8_t g, sfb, b; uint16_t i; #ifndef FIXED_POINT real_t scale; #else int32_t exp, frac; #endif uint16_t nshort = frame_len/8; uint8_t group = 0; for (g = 0; g < icsr->num_window_groups; g++) { /* Do intensity stereo decoding */ for (b = 0; b < icsr->window_group_length[g]; b++) { for (sfb = 0; sfb < icsr->max_sfb; sfb++) { if (is_intensity(icsr, g, sfb)) { #ifdef MAIN_DEC /* For scalefactor bands coded in intensity stereo the corresponding predictors in the right channel are switched to "off". */ ics->pred.prediction_used[sfb] = 0; icsr->pred.prediction_used[sfb] = 0; #endif #ifndef FIXED_POINT scale = (real_t)pow(0.5, (0.25*icsr->scale_factors[g][sfb])); #else exp = icsr->scale_factors[g][sfb] >> 2; frac = icsr->scale_factors[g][sfb] & 3; #endif /* Scale from left to right channel, do not touch left channel */ for (i = icsr->swb_offset[sfb]; i < min(icsr->swb_offset[sfb+1], ics->swb_offset_max); i++) { #ifndef FIXED_POINT r_spec[(group*nshort)+i] = MUL_R(l_spec[(group*nshort)+i], scale); #else if (exp < 0) r_spec[(group*nshort)+i] = l_spec[(group*nshort)+i] << -exp; else r_spec[(group*nshort)+i] = l_spec[(group*nshort)+i] >> exp; r_spec[(group*nshort)+i] = MUL_C(r_spec[(group*nshort)+i], pow05_table[frac + 3]); #endif if (is_intensity(icsr, g, sfb) != invert_intensity(ics, g, sfb)) r_spec[(group*nshort)+i] = -r_spec[(group*nshort)+i]; } } } group++; } } } xine-lib-1.2/contrib/libfaad/sbr_dec.c0000644000175000017500000004421614647725152015462 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_dec.c,v 1.44 2009/01/26 22:32:31 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include #include #include "syntax.h" #include "bits.h" #include "sbr_syntax.h" #include "sbr_qmf.h" #include "sbr_hfgen.h" #include "sbr_hfadj.h" /* static function declarations */ static uint8_t sbr_save_prev_data(sbr_info *sbr, uint8_t ch); static void sbr_save_matrix(sbr_info *sbr, uint8_t ch); sbr_info *sbrDecodeInit(uint16_t framelength, uint8_t id_aac, uint32_t sample_rate, uint8_t downSampledSBR #ifdef DRM , uint8_t IsDRM #endif ) { sbr_info *sbr = faad_malloc(sizeof(sbr_info)); memset(sbr, 0, sizeof(sbr_info)); /* save id of the parent element */ sbr->id_aac = id_aac; sbr->sample_rate = sample_rate; sbr->bs_freq_scale = 2; sbr->bs_alter_scale = 1; sbr->bs_noise_bands = 2; sbr->bs_limiter_bands = 2; sbr->bs_limiter_gains = 2; sbr->bs_interpol_freq = 1; sbr->bs_smoothing_mode = 1; sbr->bs_start_freq = 5; sbr->bs_amp_res = 1; sbr->bs_samplerate_mode = 1; sbr->prevEnvIsShort[0] = -1; sbr->prevEnvIsShort[1] = -1; sbr->header_count = 0; sbr->Reset = 1; #ifdef DRM sbr->Is_DRM_SBR = IsDRM; #endif sbr->tHFGen = T_HFGEN; sbr->tHFAdj = T_HFADJ; sbr->bsco = 0; sbr->bsco_prev = 0; sbr->M_prev = 0; sbr->frame_len = framelength; /* force sbr reset */ sbr->bs_start_freq_prev = -1; if (framelength == 960) { sbr->numTimeSlotsRate = RATE * NO_TIME_SLOTS_960; sbr->numTimeSlots = NO_TIME_SLOTS_960; } else { sbr->numTimeSlotsRate = RATE * NO_TIME_SLOTS; sbr->numTimeSlots = NO_TIME_SLOTS; } sbr->GQ_ringbuf_index[0] = 0; sbr->GQ_ringbuf_index[1] = 0; if (id_aac == ID_CPE) { /* stereo */ uint8_t j; sbr->qmfa[0] = qmfa_init(32); sbr->qmfa[1] = qmfa_init(32); sbr->qmfs[0] = qmfs_init((downSampledSBR)?32:64); sbr->qmfs[1] = qmfs_init((downSampledSBR)?32:64); for (j = 0; j < 5; j++) { sbr->G_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); sbr->G_temp_prev[1][j] = faad_malloc(64*sizeof(real_t)); sbr->Q_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); sbr->Q_temp_prev[1][j] = faad_malloc(64*sizeof(real_t)); } memset(sbr->Xsbr[0], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); memset(sbr->Xsbr[1], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); } else { /* mono */ uint8_t j; sbr->qmfa[0] = qmfa_init(32); sbr->qmfs[0] = qmfs_init((downSampledSBR)?32:64); sbr->qmfs[1] = NULL; for (j = 0; j < 5; j++) { sbr->G_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); sbr->Q_temp_prev[0][j] = faad_malloc(64*sizeof(real_t)); } memset(sbr->Xsbr[0], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); } return sbr; } void sbrDecodeEnd(sbr_info *sbr) { uint8_t j; if (sbr) { qmfa_end(sbr->qmfa[0]); qmfs_end(sbr->qmfs[0]); if (sbr->qmfs[1] != NULL) { qmfa_end(sbr->qmfa[1]); qmfs_end(sbr->qmfs[1]); } for (j = 0; j < 5; j++) { if (sbr->G_temp_prev[0][j]) faad_free(sbr->G_temp_prev[0][j]); if (sbr->Q_temp_prev[0][j]) faad_free(sbr->Q_temp_prev[0][j]); if (sbr->G_temp_prev[1][j]) faad_free(sbr->G_temp_prev[1][j]); if (sbr->Q_temp_prev[1][j]) faad_free(sbr->Q_temp_prev[1][j]); } #ifdef PS_DEC if (sbr->ps != NULL) ps_free(sbr->ps); #endif #ifdef DRM_PS if (sbr->drm_ps != NULL) drm_ps_free(sbr->drm_ps); #endif faad_free(sbr); } } void sbrReset(sbr_info *sbr) { uint8_t j; if (sbr->qmfa[0] != NULL) memset(sbr->qmfa[0]->x, 0, 2 * sbr->qmfa[0]->channels * 10 * sizeof(real_t)); if (sbr->qmfa[1] != NULL) memset(sbr->qmfa[1]->x, 0, 2 * sbr->qmfa[1]->channels * 10 * sizeof(real_t)); if (sbr->qmfs[0] != NULL) memset(sbr->qmfs[0]->v, 0, 2 * sbr->qmfs[0]->channels * 20 * sizeof(real_t)); if (sbr->qmfs[1] != NULL) memset(sbr->qmfs[1]->v, 0, 2 * sbr->qmfs[1]->channels * 20 * sizeof(real_t)); for (j = 0; j < 5; j++) { if (sbr->G_temp_prev[0][j] != NULL) memset(sbr->G_temp_prev[0][j], 0, 64*sizeof(real_t)); if (sbr->G_temp_prev[1][j] != NULL) memset(sbr->G_temp_prev[1][j], 0, 64*sizeof(real_t)); if (sbr->Q_temp_prev[0][j] != NULL) memset(sbr->Q_temp_prev[0][j], 0, 64*sizeof(real_t)); if (sbr->Q_temp_prev[1][j] != NULL) memset(sbr->Q_temp_prev[1][j], 0, 64*sizeof(real_t)); } memset(sbr->Xsbr[0], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); memset(sbr->Xsbr[1], 0, (sbr->numTimeSlotsRate+sbr->tHFGen)*64 * sizeof(qmf_t)); sbr->GQ_ringbuf_index[0] = 0; sbr->GQ_ringbuf_index[1] = 0; sbr->header_count = 0; sbr->Reset = 1; sbr->L_E_prev[0] = 0; sbr->L_E_prev[1] = 0; sbr->bs_freq_scale = 2; sbr->bs_alter_scale = 1; sbr->bs_noise_bands = 2; sbr->bs_limiter_bands = 2; sbr->bs_limiter_gains = 2; sbr->bs_interpol_freq = 1; sbr->bs_smoothing_mode = 1; sbr->bs_start_freq = 5; sbr->bs_amp_res = 1; sbr->bs_samplerate_mode = 1; sbr->prevEnvIsShort[0] = -1; sbr->prevEnvIsShort[1] = -1; sbr->bsco = 0; sbr->bsco_prev = 0; sbr->M_prev = 0; sbr->bs_start_freq_prev = -1; sbr->f_prev[0] = 0; sbr->f_prev[1] = 0; for (j = 0; j < MAX_M; j++) { sbr->E_prev[0][j] = 0; sbr->Q_prev[0][j] = 0; sbr->E_prev[1][j] = 0; sbr->Q_prev[1][j] = 0; sbr->bs_add_harmonic_prev[0][j] = 0; sbr->bs_add_harmonic_prev[1][j] = 0; } sbr->bs_add_harmonic_flag_prev[0] = 0; sbr->bs_add_harmonic_flag_prev[1] = 0; } static uint8_t sbr_save_prev_data(sbr_info *sbr, uint8_t ch) { uint8_t i; /* save data for next frame */ sbr->kx_prev = sbr->kx; sbr->M_prev = sbr->M; sbr->bsco_prev = sbr->bsco; sbr->L_E_prev[ch] = sbr->L_E[ch]; /* sbr->L_E[ch] can become 0 on files with bit errors */ if (sbr->L_E[ch] <= 0) return 19; sbr->f_prev[ch] = sbr->f[ch][sbr->L_E[ch] - 1]; for (i = 0; i < MAX_M; i++) { sbr->E_prev[ch][i] = sbr->E[ch][i][sbr->L_E[ch] - 1]; sbr->Q_prev[ch][i] = sbr->Q[ch][i][sbr->L_Q[ch] - 1]; } for (i = 0; i < MAX_M; i++) { sbr->bs_add_harmonic_prev[ch][i] = sbr->bs_add_harmonic[ch][i]; } sbr->bs_add_harmonic_flag_prev[ch] = sbr->bs_add_harmonic_flag[ch]; if (sbr->l_A[ch] == sbr->L_E[ch]) sbr->prevEnvIsShort[ch] = 0; else sbr->prevEnvIsShort[ch] = -1; return 0; } static void sbr_save_matrix(sbr_info *sbr, uint8_t ch) { uint8_t i; for (i = 0; i < sbr->tHFGen; i++) { memmove(sbr->Xsbr[ch][i], sbr->Xsbr[ch][i+sbr->numTimeSlotsRate], 64 * sizeof(qmf_t)); } for (i = sbr->tHFGen; i < MAX_NTSRHFG; i++) { memset(sbr->Xsbr[ch][i], 0, 64 * sizeof(qmf_t)); } } static uint8_t sbr_process_channel(sbr_info *sbr, real_t *channel_buf, qmf_t X[MAX_NTSR][64], uint8_t ch, uint8_t dont_process, const uint8_t downSampledSBR) { int16_t k, l; uint8_t ret = 0; #ifdef SBR_LOW_POWER ALIGN real_t deg[64]; #endif (void)downSampledSBR; /* why is this unused? */ #ifdef DRM if (sbr->Is_DRM_SBR) { sbr->bsco = max((int32_t)sbr->maxAACLine*32/(int32_t)sbr->frame_len - (int32_t)sbr->kx, 0); } else { #endif sbr->bsco = 0; #ifdef DRM } #endif //#define PRE_QMF_PRINT #ifdef PRE_QMF_PRINT { int i; for (i = 0; i < 1024; i++) { printf("%d\n", channel_buf[i]); } } #endif /* subband analysis */ if (dont_process) sbr_qmf_analysis_32(sbr, sbr->qmfa[ch], channel_buf, sbr->Xsbr[ch], sbr->tHFGen, 32); else sbr_qmf_analysis_32(sbr, sbr->qmfa[ch], channel_buf, sbr->Xsbr[ch], sbr->tHFGen, sbr->kx); if (!dont_process) { #if 1 /* insert high frequencies here */ /* hf generation using patching */ hf_generation(sbr, sbr->Xsbr[ch], sbr->Xsbr[ch] #ifdef SBR_LOW_POWER ,deg #endif ,ch); #endif #if 0 //def SBR_LOW_POWER for (l = sbr->t_E[ch][0]; l < sbr->t_E[ch][sbr->L_E[ch]]; l++) { for (k = 0; k < sbr->kx; k++) { QMF_RE(sbr->Xsbr[ch][sbr->tHFAdj + l][k]) = 0; } } #endif #if 1 /* hf adjustment */ ret = hf_adjustment(sbr, sbr->Xsbr[ch] #ifdef SBR_LOW_POWER ,deg #endif ,ch); #endif if (ret > 0) { dont_process = 1; } } if ((sbr->just_seeked != 0) || dont_process) { for (l = 0; l < sbr->numTimeSlotsRate; l++) { for (k = 0; k < 32; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); #ifndef SBR_LOW_POWER QMF_IM(X[l][k]) = QMF_IM(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); #endif } for (k = 32; k < 64; k++) { QMF_RE(X[l][k]) = 0; #ifndef SBR_LOW_POWER QMF_IM(X[l][k]) = 0; #endif } } } else { for (l = 0; l < sbr->numTimeSlotsRate; l++) { uint8_t kx_band, M_band, bsco_band; if (l < sbr->t_E[ch][0]) { kx_band = sbr->kx_prev; M_band = sbr->M_prev; bsco_band = sbr->bsco_prev; } else { kx_band = sbr->kx; M_band = sbr->M; bsco_band = sbr->bsco; } #ifndef SBR_LOW_POWER for (k = 0; k < kx_band + bsco_band; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); QMF_IM(X[l][k]) = QMF_IM(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = kx_band + bsco_band; k < kx_band + M_band; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); QMF_IM(X[l][k]) = QMF_IM(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = max(kx_band + bsco_band, kx_band + M_band); k < 64; k++) { QMF_RE(X[l][k]) = 0; QMF_IM(X[l][k]) = 0; } #else for (k = 0; k < kx_band + bsco_band; k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = kx_band + bsco_band; k < min(kx_band + M_band, 63); k++) { QMF_RE(X[l][k]) = QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][k]); } for (k = max(kx_band + bsco_band, kx_band + M_band); k < 64; k++) { QMF_RE(X[l][k]) = 0; } QMF_RE(X[l][kx_band - 1 + bsco_band]) += QMF_RE(sbr->Xsbr[ch][l + sbr->tHFAdj][kx_band - 1 + bsco_band]); #endif } } return ret; } uint8_t sbrDecodeCoupleFrame(sbr_info *sbr, real_t *left_chan, real_t *right_chan, const uint8_t just_seeked, const uint8_t downSampledSBR) { uint8_t dont_process = 0; uint8_t ret = 0; ALIGN qmf_t X[MAX_NTSR][64]; if (sbr == NULL) return 20; /* case can occur due to bit errors */ if (sbr->id_aac != ID_CPE) return 21; if (sbr->ret || (sbr->header_count == 0)) { /* don't process just upsample */ dont_process = 1; /* Re-activate reset for next frame */ if (sbr->ret && sbr->Reset) sbr->bs_start_freq_prev = -1; } if (just_seeked) { sbr->just_seeked = 1; } else { sbr->just_seeked = 0; } sbr->ret += sbr_process_channel(sbr, left_chan, X, 0, dont_process, downSampledSBR); /* subband synthesis */ if (downSampledSBR) { sbr_qmf_synthesis_32(sbr, sbr->qmfs[0], X, left_chan); } else { sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X, left_chan); } sbr->ret += sbr_process_channel(sbr, right_chan, X, 1, dont_process, downSampledSBR); /* subband synthesis */ if (downSampledSBR) { sbr_qmf_synthesis_32(sbr, sbr->qmfs[1], X, right_chan); } else { sbr_qmf_synthesis_64(sbr, sbr->qmfs[1], X, right_chan); } if (sbr->bs_header_flag) sbr->just_seeked = 0; if (sbr->header_count != 0 && sbr->ret == 0) { ret = sbr_save_prev_data(sbr, 0); if (ret) return ret; ret = sbr_save_prev_data(sbr, 1); if (ret) return ret; } sbr_save_matrix(sbr, 0); sbr_save_matrix(sbr, 1); sbr->frame++; //#define POST_QMF_PRINT #ifdef POST_QMF_PRINT { int i; for (i = 0; i < 2048; i++) { printf("%d\n", left_chan[i]); } for (i = 0; i < 2048; i++) { printf("%d\n", right_chan[i]); } } #endif return 0; } uint8_t sbrDecodeSingleFrame(sbr_info *sbr, real_t *channel, const uint8_t just_seeked, const uint8_t downSampledSBR) { uint8_t dont_process = 0; uint8_t ret = 0; ALIGN qmf_t X[MAX_NTSR][64]; if (sbr == NULL) return 20; /* case can occur due to bit errors */ if (sbr->id_aac != ID_SCE && sbr->id_aac != ID_LFE) return 21; if (sbr->ret || (sbr->header_count == 0)) { /* don't process just upsample */ dont_process = 1; /* Re-activate reset for next frame */ if (sbr->ret && sbr->Reset) sbr->bs_start_freq_prev = -1; } if (just_seeked) { sbr->just_seeked = 1; } else { sbr->just_seeked = 0; } sbr->ret += sbr_process_channel(sbr, channel, X, 0, dont_process, downSampledSBR); /* subband synthesis */ if (downSampledSBR) { sbr_qmf_synthesis_32(sbr, sbr->qmfs[0], X, channel); } else { sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X, channel); } if (sbr->bs_header_flag) sbr->just_seeked = 0; if (sbr->header_count != 0 && sbr->ret == 0) { ret = sbr_save_prev_data(sbr, 0); if (ret) return ret; } sbr_save_matrix(sbr, 0); sbr->frame++; //#define POST_QMF_PRINT #ifdef POST_QMF_PRINT { int i; for (i = 0; i < 2048; i++) { printf("%d\n", channel[i]); } } #endif return 0; } #if (defined(PS_DEC) || defined(DRM_PS)) uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *right_channel, const uint8_t just_seeked, const uint8_t downSampledSBR) { uint8_t l, k; uint8_t dont_process = 0; uint8_t ret = 0; #ifndef SBR_LOW_POWER # define QMF_ZERO {0,0} #else # define QMF_ZERO 0 #endif ALIGN qmf_t X_left[38][64] = {{QMF_ZERO}}; ALIGN qmf_t X_right[38][64] = {{QMF_ZERO}}; /* must set this to 0 */ if (sbr == NULL) return 20; /* case can occur due to bit errors */ if (sbr->id_aac != ID_SCE && sbr->id_aac != ID_LFE) return 21; if (sbr->ret || (sbr->header_count == 0)) { /* don't process just upsample */ dont_process = 1; /* Re-activate reset for next frame */ if (sbr->ret && sbr->Reset) sbr->bs_start_freq_prev = -1; } if (just_seeked) { sbr->just_seeked = 1; } else { sbr->just_seeked = 0; } if (sbr->qmfs[1] == NULL) { sbr->qmfs[1] = qmfs_init((downSampledSBR)?32:64); } sbr->ret += sbr_process_channel(sbr, left_channel, X_left, 0, dont_process, downSampledSBR); /* copy some extra data for PS */ for (l = sbr->numTimeSlotsRate; l < sbr->numTimeSlotsRate + 6; l++) { for (k = 0; k < 5; k++) { QMF_RE(X_left[l][k]) = QMF_RE(sbr->Xsbr[0][sbr->tHFAdj+l][k]); QMF_IM(X_left[l][k]) = QMF_IM(sbr->Xsbr[0][sbr->tHFAdj+l][k]); } } /* perform parametric stereo */ #ifdef DRM_PS if (sbr->Is_DRM_SBR) { drm_ps_decode(sbr->drm_ps, (sbr->ret > 0), X_left, X_right); } else { #endif #ifdef PS_DEC ps_decode(sbr->ps, X_left, X_right); #endif #ifdef DRM_PS } #endif /* subband synthesis */ if (downSampledSBR) { sbr_qmf_synthesis_32(sbr, sbr->qmfs[0], X_left, left_channel); sbr_qmf_synthesis_32(sbr, sbr->qmfs[1], X_right, right_channel); } else { sbr_qmf_synthesis_64(sbr, sbr->qmfs[0], X_left, left_channel); sbr_qmf_synthesis_64(sbr, sbr->qmfs[1], X_right, right_channel); } if (sbr->bs_header_flag) sbr->just_seeked = 0; if (sbr->header_count != 0 && sbr->ret == 0) { ret = sbr_save_prev_data(sbr, 0); if (ret) return ret; } sbr_save_matrix(sbr, 0); sbr->frame++; return 0; } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_syntax.c0000644000175000017500000007030514647725152016253 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_syntax.c,v 1.39 2009/01/26 22:32:31 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include "sbr_syntax.h" #include "syntax.h" #include "sbr_huff.h" #include "sbr_fbt.h" #include "sbr_tf_grid.h" #include "sbr_e_nf.h" #include "bits.h" #ifdef PS_DEC #include "ps_dec.h" #endif #ifdef DRM_PS #include "drm_dec.h" #endif #include "analysis.h" /* static function declarations */ /* static function declarations */ static void sbr_header(bitfile *ld, sbr_info *sbr); static uint8_t calc_sbr_tables(sbr_info *sbr, uint8_t start_freq, uint8_t stop_freq, uint8_t samplerate_mode, uint8_t freq_scale, uint8_t alter_scale, uint8_t xover_band); static uint8_t sbr_data(bitfile *ld, sbr_info *sbr); static uint16_t sbr_extension(bitfile *ld, sbr_info *sbr, uint8_t bs_extension_id, uint16_t num_bits_left); static uint8_t sbr_single_channel_element(bitfile *ld, sbr_info *sbr); static uint8_t sbr_channel_pair_element(bitfile *ld, sbr_info *sbr); static uint8_t sbr_grid(bitfile *ld, sbr_info *sbr, uint8_t ch); static void sbr_dtdf(bitfile *ld, sbr_info *sbr, uint8_t ch); static void invf_mode(bitfile *ld, sbr_info *sbr, uint8_t ch); static void sinusoidal_coding(bitfile *ld, sbr_info *sbr, uint8_t ch); static void sbr_reset(sbr_info *sbr) { #if 0 printf("%d\n", sbr->bs_start_freq_prev); printf("%d\n", sbr->bs_stop_freq_prev); printf("%d\n", sbr->bs_freq_scale_prev); printf("%d\n", sbr->bs_alter_scale_prev); printf("%d\n", sbr->bs_xover_band_prev); printf("%d\n\n", sbr->bs_noise_bands_prev); #endif /* if these are different from the previous frame: Reset = 1 */ if ((sbr->bs_start_freq != sbr->bs_start_freq_prev) || (sbr->bs_stop_freq != sbr->bs_stop_freq_prev) || (sbr->bs_freq_scale != sbr->bs_freq_scale_prev) || (sbr->bs_alter_scale != sbr->bs_alter_scale_prev) || (sbr->bs_xover_band != sbr->bs_xover_band_prev) || (sbr->bs_noise_bands != sbr->bs_noise_bands_prev)) { sbr->Reset = 1; } else { sbr->Reset = 0; } sbr->bs_start_freq_prev = sbr->bs_start_freq; sbr->bs_stop_freq_prev = sbr->bs_stop_freq; sbr->bs_freq_scale_prev = sbr->bs_freq_scale; sbr->bs_alter_scale_prev = sbr->bs_alter_scale; sbr->bs_xover_band_prev = sbr->bs_xover_band; sbr->bs_noise_bands_prev = sbr->bs_noise_bands; } static uint8_t calc_sbr_tables(sbr_info *sbr, uint8_t start_freq, uint8_t stop_freq, uint8_t samplerate_mode, uint8_t freq_scale, uint8_t alter_scale, uint8_t xover_band) { uint8_t result = 0; uint8_t k2; /* calculate the Master Frequency Table */ sbr->k0 = qmf_start_channel(start_freq, samplerate_mode, sbr->sample_rate); k2 = qmf_stop_channel(stop_freq, sbr->sample_rate, sbr->k0); /* check k0 and k2 */ if (sbr->sample_rate >= 48000) { if ((k2 - sbr->k0) > 32) result += 1; } else if (sbr->sample_rate <= 32000) { if ((k2 - sbr->k0) > 48) result += 1; } else { /* (sbr->sample_rate == 44100) */ if ((k2 - sbr->k0) > 45) result += 1; } if (freq_scale == 0) { result += master_frequency_table_fs0(sbr, sbr->k0, k2, alter_scale); } else { result += master_frequency_table(sbr, sbr->k0, k2, freq_scale, alter_scale); } result += derived_frequency_table(sbr, xover_band, k2); result = (result > 0) ? 1 : 0; return result; } /* table 2 */ uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint16_t cnt, uint8_t psResetFlag) { uint8_t result = 0; uint16_t num_align_bits = 0; uint16_t num_sbr_bits1 = (uint16_t)faad_get_processed_bits(ld); uint16_t num_sbr_bits2; uint8_t saved_start_freq, saved_samplerate_mode; uint8_t saved_stop_freq, saved_freq_scale; uint8_t saved_alter_scale, saved_xover_band; #if (defined(PS_DEC) || defined(DRM_PS)) if (psResetFlag) sbr->psResetFlag = psResetFlag; #endif #ifdef DRM if (!sbr->Is_DRM_SBR) #endif { uint8_t bs_extension_type = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,198,"sbr_bitstream(): bs_extension_type")); if (bs_extension_type == EXT_SBR_DATA_CRC) { sbr->bs_sbr_crc_bits = (uint16_t)faad_getbits(ld, 10 DEBUGVAR(1,199,"sbr_bitstream(): bs_sbr_crc_bits")); } } /* save old header values, in case the new ones are corrupted */ saved_start_freq = sbr->bs_start_freq; saved_samplerate_mode = sbr->bs_samplerate_mode; saved_stop_freq = sbr->bs_stop_freq; saved_freq_scale = sbr->bs_freq_scale; saved_alter_scale = sbr->bs_alter_scale; saved_xover_band = sbr->bs_xover_band; sbr->bs_header_flag = faad_get1bit(ld DEBUGVAR(1,200,"sbr_bitstream(): bs_header_flag")); if (sbr->bs_header_flag) sbr_header(ld, sbr); /* Reset? */ sbr_reset(sbr); /* first frame should have a header */ //if (!(sbr->frame == 0 && sbr->bs_header_flag == 0)) if (sbr->header_count != 0) { if (sbr->Reset || (sbr->bs_header_flag && sbr->just_seeked)) { uint8_t rt = calc_sbr_tables(sbr, sbr->bs_start_freq, sbr->bs_stop_freq, sbr->bs_samplerate_mode, sbr->bs_freq_scale, sbr->bs_alter_scale, sbr->bs_xover_band); /* if an error occured with the new header values revert to the old ones */ if (rt > 0) { calc_sbr_tables(sbr, saved_start_freq, saved_stop_freq, saved_samplerate_mode, saved_freq_scale, saved_alter_scale, saved_xover_band); } } if (result == 0) { result = sbr_data(ld, sbr); /* sbr_data() returning an error means that there was an error in envelope_time_border_vector(). In this case the old time border vector is saved and all the previous data normally read after sbr_grid() is saved. */ /* to be on the safe side, calculate old sbr tables in case of error */ if ((result > 0) && (sbr->Reset || (sbr->bs_header_flag && sbr->just_seeked))) { calc_sbr_tables(sbr, saved_start_freq, saved_stop_freq, saved_samplerate_mode, saved_freq_scale, saved_alter_scale, saved_xover_band); } /* we should be able to safely set result to 0 now, */ /* but practise indicates this doesn't work well */ } } else { result = 1; } num_sbr_bits2 = (uint16_t)faad_get_processed_bits(ld) - num_sbr_bits1; /* check if we read more bits then were available for sbr */ if (8*cnt < num_sbr_bits2) { faad_resetbits(ld, num_sbr_bits1 + 8*cnt); num_sbr_bits2 = 8*cnt; #ifdef PS_DEC /* turn off PS for the unfortunate case that we randomly read some * PS data that looks correct */ sbr->ps_used = 0; #endif /* Make sure it doesn't decode SBR in this frame, or we'll get glitches */ return 1; } #ifdef DRM if (!sbr->Is_DRM_SBR) #endif { /* -4 does not apply, bs_extension_type is re-read in this function */ num_align_bits = 8*cnt /*- 4*/ - num_sbr_bits2; while (num_align_bits > 7) { faad_getbits(ld, 8 DEBUGVAR(1,999,"sbr_bitstream(): num_align_bits")); num_align_bits -= 8; } faad_getbits(ld, num_align_bits DEBUGVAR(1,999,"sbr_bitstream(): num_align_bits")); } return result; } /* table 3 */ static void sbr_header(bitfile *ld, sbr_info *sbr) { uint8_t bs_header_extra_1, bs_header_extra_2; sbr->header_count++; sbr->bs_amp_res = faad_get1bit(ld DEBUGVAR(1,203,"sbr_header(): bs_amp_res")); /* bs_start_freq and bs_stop_freq must define a fequency band that does not exceed 48 channels */ sbr->bs_start_freq = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,204,"sbr_header(): bs_start_freq")); sbr->bs_stop_freq = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,205,"sbr_header(): bs_stop_freq")); sbr->bs_xover_band = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,206,"sbr_header(): bs_xover_band")); faad_getbits(ld, 2 DEBUGVAR(1,207,"sbr_header(): bs_reserved_bits_hdr")); bs_header_extra_1 = (uint8_t)faad_get1bit(ld DEBUGVAR(1,208,"sbr_header(): bs_header_extra_1")); bs_header_extra_2 = (uint8_t)faad_get1bit(ld DEBUGVAR(1,209,"sbr_header(): bs_header_extra_2")); if (bs_header_extra_1) { sbr->bs_freq_scale = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,211,"sbr_header(): bs_freq_scale")); sbr->bs_alter_scale = (uint8_t)faad_get1bit(ld DEBUGVAR(1,212,"sbr_header(): bs_alter_scale")); sbr->bs_noise_bands = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,213,"sbr_header(): bs_noise_bands")); } else { /* Default values */ sbr->bs_freq_scale = 2; sbr->bs_alter_scale = 1; sbr->bs_noise_bands = 2; } if (bs_header_extra_2) { sbr->bs_limiter_bands = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,214,"sbr_header(): bs_limiter_bands")); sbr->bs_limiter_gains = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,215,"sbr_header(): bs_limiter_gains")); sbr->bs_interpol_freq = (uint8_t)faad_get1bit(ld DEBUGVAR(1,216,"sbr_header(): bs_interpol_freq")); sbr->bs_smoothing_mode = (uint8_t)faad_get1bit(ld DEBUGVAR(1,217,"sbr_header(): bs_smoothing_mode")); } else { /* Default values */ sbr->bs_limiter_bands = 2; sbr->bs_limiter_gains = 2; sbr->bs_interpol_freq = 1; sbr->bs_smoothing_mode = 1; } #if 0 /* print the header to screen */ printf("bs_amp_res: %d\n", sbr->bs_amp_res); printf("bs_start_freq: %d\n", sbr->bs_start_freq); printf("bs_stop_freq: %d\n", sbr->bs_stop_freq); printf("bs_xover_band: %d\n", sbr->bs_xover_band); if (bs_header_extra_1) { printf("bs_freq_scale: %d\n", sbr->bs_freq_scale); printf("bs_alter_scale: %d\n", sbr->bs_alter_scale); printf("bs_noise_bands: %d\n", sbr->bs_noise_bands); } if (bs_header_extra_2) { printf("bs_limiter_bands: %d\n", sbr->bs_limiter_bands); printf("bs_limiter_gains: %d\n", sbr->bs_limiter_gains); printf("bs_interpol_freq: %d\n", sbr->bs_interpol_freq); printf("bs_smoothing_mode: %d\n", sbr->bs_smoothing_mode); } printf("\n"); #endif } /* table 4 */ static uint8_t sbr_data(bitfile *ld, sbr_info *sbr) { uint8_t result; #if 0 sbr->bs_samplerate_mode = faad_get1bit(ld DEBUGVAR(1,219,"sbr_data(): bs_samplerate_mode")); #endif sbr->rate = (sbr->bs_samplerate_mode) ? 2 : 1; switch (sbr->id_aac) { case ID_SCE: if ((result = sbr_single_channel_element(ld, sbr)) > 0) return result; break; case ID_CPE: if ((result = sbr_channel_pair_element(ld, sbr)) > 0) return result; break; } return 0; } /* table 5 */ static uint8_t sbr_single_channel_element(bitfile *ld, sbr_info *sbr) { uint8_t result; if (faad_get1bit(ld DEBUGVAR(1,220,"sbr_single_channel_element(): bs_data_extra"))) { faad_getbits(ld, 4 DEBUGVAR(1,221,"sbr_single_channel_element(): bs_reserved_bits_data")); } #ifdef DRM /* bs_coupling, from sbr_channel_pair_base_element(bs_amp_res) */ if (sbr->Is_DRM_SBR) { faad_get1bit(ld); } #endif if ((result = sbr_grid(ld, sbr, 0)) > 0) return result; sbr_dtdf(ld, sbr, 0); invf_mode(ld, sbr, 0); sbr_envelope(ld, sbr, 0); sbr_noise(ld, sbr, 0); #ifndef FIXED_POINT envelope_noise_dequantisation(sbr, 0); #endif memset(sbr->bs_add_harmonic[0], 0, 64*sizeof(uint8_t)); sbr->bs_add_harmonic_flag[0] = faad_get1bit(ld DEBUGVAR(1,223,"sbr_single_channel_element(): bs_add_harmonic_flag[0]")); if (sbr->bs_add_harmonic_flag[0]) sinusoidal_coding(ld, sbr, 0); sbr->bs_extended_data = faad_get1bit(ld DEBUGVAR(1,224,"sbr_single_channel_element(): bs_extended_data[0]")); if (sbr->bs_extended_data) { uint16_t nr_bits_left; #if (defined(PS_DEC) || defined(DRM_PS)) uint8_t ps_ext_read = 0; #endif uint16_t cnt = (uint16_t)faad_getbits(ld, 4 DEBUGVAR(1,225,"sbr_single_channel_element(): bs_extension_size")); if (cnt == 15) { cnt += (uint16_t)faad_getbits(ld, 8 DEBUGVAR(1,226,"sbr_single_channel_element(): bs_esc_count")); } nr_bits_left = 8 * cnt; while (nr_bits_left > 7) { uint16_t tmp_nr_bits = 0; sbr->bs_extension_id = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,227,"sbr_single_channel_element(): bs_extension_id")); tmp_nr_bits += 2; /* allow only 1 PS extension element per extension data */ #if (defined(PS_DEC) || defined(DRM_PS)) #if (defined(PS_DEC) && defined(DRM_PS)) if (sbr->bs_extension_id == EXTENSION_ID_PS || sbr->bs_extension_id == DRM_PARAMETRIC_STEREO) #else #ifdef PS_DEC if (sbr->bs_extension_id == EXTENSION_ID_PS) #else #ifdef DRM_PS if (sbr->bs_extension_id == DRM_PARAMETRIC_STEREO) #endif #endif #endif { if (ps_ext_read == 0) { ps_ext_read = 1; } else { /* to be safe make it 3, will switch to "default" * in sbr_extension() */ #ifdef DRM return 1; #else sbr->bs_extension_id = 3; #endif } } #endif tmp_nr_bits += sbr_extension(ld, sbr, sbr->bs_extension_id, nr_bits_left); /* check if the data read is bigger than the number of available bits */ if (tmp_nr_bits > nr_bits_left) return 1; nr_bits_left -= tmp_nr_bits; } /* Corrigendum */ if (nr_bits_left > 0) { faad_getbits(ld, nr_bits_left DEBUGVAR(1,280,"sbr_single_channel_element(): nr_bits_left")); } } return 0; } /* table 6 */ static uint8_t sbr_channel_pair_element(bitfile *ld, sbr_info *sbr) { uint8_t n, result; if (faad_get1bit(ld DEBUGVAR(1,228,"sbr_single_channel_element(): bs_data_extra"))) { faad_getbits(ld, 4 DEBUGVAR(1,228,"sbr_channel_pair_element(): bs_reserved_bits_data")); faad_getbits(ld, 4 DEBUGVAR(1,228,"sbr_channel_pair_element(): bs_reserved_bits_data")); } sbr->bs_coupling = faad_get1bit(ld DEBUGVAR(1,228,"sbr_channel_pair_element(): bs_coupling")); if (sbr->bs_coupling) { if ((result = sbr_grid(ld, sbr, 0)) > 0) return result; /* need to copy some data from left to right */ sbr->bs_frame_class[1] = sbr->bs_frame_class[0]; sbr->L_E[1] = sbr->L_E[0]; sbr->L_Q[1] = sbr->L_Q[0]; sbr->bs_pointer[1] = sbr->bs_pointer[0]; for (n = 0; n <= sbr->L_E[0]; n++) { sbr->t_E[1][n] = sbr->t_E[0][n]; sbr->f[1][n] = sbr->f[0][n]; } for (n = 0; n <= sbr->L_Q[0]; n++) sbr->t_Q[1][n] = sbr->t_Q[0][n]; sbr_dtdf(ld, sbr, 0); sbr_dtdf(ld, sbr, 1); invf_mode(ld, sbr, 0); /* more copying */ for (n = 0; n < sbr->N_Q; n++) sbr->bs_invf_mode[1][n] = sbr->bs_invf_mode[0][n]; sbr_envelope(ld, sbr, 0); sbr_noise(ld, sbr, 0); sbr_envelope(ld, sbr, 1); sbr_noise(ld, sbr, 1); memset(sbr->bs_add_harmonic[0], 0, 64*sizeof(uint8_t)); memset(sbr->bs_add_harmonic[1], 0, 64*sizeof(uint8_t)); sbr->bs_add_harmonic_flag[0] = faad_get1bit(ld DEBUGVAR(1,231,"sbr_channel_pair_element(): bs_add_harmonic_flag[0]")); if (sbr->bs_add_harmonic_flag[0]) sinusoidal_coding(ld, sbr, 0); sbr->bs_add_harmonic_flag[1] = faad_get1bit(ld DEBUGVAR(1,232,"sbr_channel_pair_element(): bs_add_harmonic_flag[1]")); if (sbr->bs_add_harmonic_flag[1]) sinusoidal_coding(ld, sbr, 1); } else { uint8_t saved_t_E[6] = {0}, saved_t_Q[3] = {0}; uint8_t saved_L_E = sbr->L_E[0]; uint8_t saved_L_Q = sbr->L_Q[0]; uint8_t saved_frame_class = sbr->bs_frame_class[0]; for (n = 0; n < saved_L_E; n++) saved_t_E[n] = sbr->t_E[0][n]; for (n = 0; n < saved_L_Q; n++) saved_t_Q[n] = sbr->t_Q[0][n]; if ((result = sbr_grid(ld, sbr, 0)) > 0) return result; if ((result = sbr_grid(ld, sbr, 1)) > 0) { /* restore first channel data as well */ sbr->bs_frame_class[0] = saved_frame_class; sbr->L_E[0] = saved_L_E; sbr->L_Q[0] = saved_L_Q; for (n = 0; n < 6; n++) sbr->t_E[0][n] = saved_t_E[n]; for (n = 0; n < 3; n++) sbr->t_Q[0][n] = saved_t_Q[n]; return result; } sbr_dtdf(ld, sbr, 0); sbr_dtdf(ld, sbr, 1); invf_mode(ld, sbr, 0); invf_mode(ld, sbr, 1); sbr_envelope(ld, sbr, 0); sbr_envelope(ld, sbr, 1); sbr_noise(ld, sbr, 0); sbr_noise(ld, sbr, 1); memset(sbr->bs_add_harmonic[0], 0, 64*sizeof(uint8_t)); memset(sbr->bs_add_harmonic[1], 0, 64*sizeof(uint8_t)); sbr->bs_add_harmonic_flag[0] = faad_get1bit(ld DEBUGVAR(1,239,"sbr_channel_pair_element(): bs_add_harmonic_flag[0]")); if (sbr->bs_add_harmonic_flag[0]) sinusoidal_coding(ld, sbr, 0); sbr->bs_add_harmonic_flag[1] = faad_get1bit(ld DEBUGVAR(1,240,"sbr_channel_pair_element(): bs_add_harmonic_flag[1]")); if (sbr->bs_add_harmonic_flag[1]) sinusoidal_coding(ld, sbr, 1); } #ifndef FIXED_POINT envelope_noise_dequantisation(sbr, 0); envelope_noise_dequantisation(sbr, 1); if (sbr->bs_coupling) unmap_envelope_noise(sbr); #endif sbr->bs_extended_data = faad_get1bit(ld DEBUGVAR(1,233,"sbr_channel_pair_element(): bs_extended_data[0]")); if (sbr->bs_extended_data) { uint16_t nr_bits_left; uint16_t cnt = (uint16_t)faad_getbits(ld, 4 DEBUGVAR(1,234,"sbr_channel_pair_element(): bs_extension_size")); if (cnt == 15) { cnt += (uint16_t)faad_getbits(ld, 8 DEBUGVAR(1,235,"sbr_channel_pair_element(): bs_esc_count")); } nr_bits_left = 8 * cnt; while (nr_bits_left > 7) { uint16_t tmp_nr_bits = 0; sbr->bs_extension_id = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,236,"sbr_channel_pair_element(): bs_extension_id")); tmp_nr_bits += 2; tmp_nr_bits += sbr_extension(ld, sbr, sbr->bs_extension_id, nr_bits_left); /* check if the data read is bigger than the number of available bits */ if (tmp_nr_bits > nr_bits_left) return 1; nr_bits_left -= tmp_nr_bits; } /* Corrigendum */ if (nr_bits_left > 0) { faad_getbits(ld, nr_bits_left DEBUGVAR(1,280,"sbr_channel_pair_element(): nr_bits_left")); } } return 0; } /* integer log[2](x): input range [0,10) */ static int8_t sbr_log2(const int8_t val) { int8_t log2tab[] = { 0, 0, 1, 2, 2, 3, 3, 3, 3, 4 }; if (val < 10 && val >= 0) return log2tab[val]; else return 0; } /* table 7 */ static uint8_t sbr_grid(bitfile *ld, sbr_info *sbr, uint8_t ch) { uint8_t i, env, rel, result; uint8_t bs_abs_bord, bs_abs_bord_1; uint8_t bs_num_env = 0; uint8_t saved_L_E = sbr->L_E[ch]; uint8_t saved_L_Q = sbr->L_Q[ch]; uint8_t saved_frame_class = sbr->bs_frame_class[ch]; sbr->bs_frame_class[ch] = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,248,"sbr_grid(): bs_frame_class")); switch (sbr->bs_frame_class[ch]) { case FIXFIX: i = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,249,"sbr_grid(): bs_num_env_raw")); bs_num_env = min(1 << i, 5); i = (uint8_t)faad_get1bit(ld DEBUGVAR(1,250,"sbr_grid(): bs_freq_res_flag")); for (env = 0; env < bs_num_env; env++) sbr->f[ch][env] = i; sbr->abs_bord_lead[ch] = 0; sbr->abs_bord_trail[ch] = sbr->numTimeSlots; sbr->n_rel_lead[ch] = bs_num_env - 1; sbr->n_rel_trail[ch] = 0; break; case FIXVAR: bs_abs_bord = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,251,"sbr_grid(): bs_abs_bord")) + sbr->numTimeSlots; bs_num_env = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,252,"sbr_grid(): bs_num_env")) + 1; for (rel = 0; rel < bs_num_env-1; rel++) { sbr->bs_rel_bord[ch][rel] = 2 * (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,253,"sbr_grid(): bs_rel_bord")) + 2; } i = sbr_log2(bs_num_env + 1); sbr->bs_pointer[ch] = (uint8_t)faad_getbits(ld, i DEBUGVAR(1,254,"sbr_grid(): bs_pointer")); for (env = 0; env < bs_num_env; env++) { sbr->f[ch][bs_num_env - env - 1] = (uint8_t)faad_get1bit(ld DEBUGVAR(1,255,"sbr_grid(): bs_freq_res")); } sbr->abs_bord_lead[ch] = 0; sbr->abs_bord_trail[ch] = bs_abs_bord; sbr->n_rel_lead[ch] = 0; sbr->n_rel_trail[ch] = bs_num_env - 1; break; case VARFIX: bs_abs_bord = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,256,"sbr_grid(): bs_abs_bord")); bs_num_env = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,257,"sbr_grid(): bs_num_env")) + 1; for (rel = 0; rel < bs_num_env-1; rel++) { sbr->bs_rel_bord[ch][rel] = 2 * (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,258,"sbr_grid(): bs_rel_bord")) + 2; } i = sbr_log2(bs_num_env + 1); sbr->bs_pointer[ch] = (uint8_t)faad_getbits(ld, i DEBUGVAR(1,259,"sbr_grid(): bs_pointer")); for (env = 0; env < bs_num_env; env++) { sbr->f[ch][env] = (uint8_t)faad_get1bit(ld DEBUGVAR(1,260,"sbr_grid(): bs_freq_res")); } sbr->abs_bord_lead[ch] = bs_abs_bord; sbr->abs_bord_trail[ch] = sbr->numTimeSlots; sbr->n_rel_lead[ch] = bs_num_env - 1; sbr->n_rel_trail[ch] = 0; break; case VARVAR: bs_abs_bord = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,261,"sbr_grid(): bs_abs_bord_0")); bs_abs_bord_1 = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,262,"sbr_grid(): bs_abs_bord_1")) + sbr->numTimeSlots; sbr->bs_num_rel_0[ch] = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,263,"sbr_grid(): bs_num_rel_0")); sbr->bs_num_rel_1[ch] = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,264,"sbr_grid(): bs_num_rel_1")); bs_num_env = min(5, sbr->bs_num_rel_0[ch] + sbr->bs_num_rel_1[ch] + 1); for (rel = 0; rel < sbr->bs_num_rel_0[ch]; rel++) { sbr->bs_rel_bord_0[ch][rel] = 2 * (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,265,"sbr_grid(): bs_rel_bord")) + 2; } for(rel = 0; rel < sbr->bs_num_rel_1[ch]; rel++) { sbr->bs_rel_bord_1[ch][rel] = 2 * (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,266,"sbr_grid(): bs_rel_bord")) + 2; } i = sbr_log2(sbr->bs_num_rel_0[ch] + sbr->bs_num_rel_1[ch] + 2); sbr->bs_pointer[ch] = (uint8_t)faad_getbits(ld, i DEBUGVAR(1,267,"sbr_grid(): bs_pointer")); for (env = 0; env < bs_num_env; env++) { sbr->f[ch][env] = (uint8_t)faad_get1bit(ld DEBUGVAR(1,268,"sbr_grid(): bs_freq_res")); } sbr->abs_bord_lead[ch] = bs_abs_bord; sbr->abs_bord_trail[ch] = bs_abs_bord_1; sbr->n_rel_lead[ch] = sbr->bs_num_rel_0[ch]; sbr->n_rel_trail[ch] = sbr->bs_num_rel_1[ch]; break; } if (sbr->bs_frame_class[ch] == VARVAR) sbr->L_E[ch] = min(bs_num_env, 5); else sbr->L_E[ch] = min(bs_num_env, 4); if (sbr->L_E[ch] <= 0) return 1; if (sbr->L_E[ch] > 1) sbr->L_Q[ch] = 2; else sbr->L_Q[ch] = 1; /* TODO: this code can probably be integrated into the code above! */ if ((result = envelope_time_border_vector(sbr, ch)) > 0) { sbr->bs_frame_class[ch] = saved_frame_class; sbr->L_E[ch] = saved_L_E; sbr->L_Q[ch] = saved_L_Q; return result; } noise_floor_time_border_vector(sbr, ch); #if 0 for (env = 0; env < bs_num_env; env++) { printf("freq_res[ch:%d][env:%d]: %d\n", ch, env, sbr->f[ch][env]); } #endif return 0; } /* table 8 */ static void sbr_dtdf(bitfile *ld, sbr_info *sbr, uint8_t ch) { uint8_t i; for (i = 0; i < sbr->L_E[ch]; i++) { sbr->bs_df_env[ch][i] = faad_get1bit(ld DEBUGVAR(1,269,"sbr_dtdf(): bs_df_env")); } for (i = 0; i < sbr->L_Q[ch]; i++) { sbr->bs_df_noise[ch][i] = faad_get1bit(ld DEBUGVAR(1,270,"sbr_dtdf(): bs_df_noise")); } } /* table 9 */ static void invf_mode(bitfile *ld, sbr_info *sbr, uint8_t ch) { uint8_t n; for (n = 0; n < sbr->N_Q; n++) { sbr->bs_invf_mode[ch][n] = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,271,"invf_mode(): bs_invf_mode")); } } static uint16_t sbr_extension(bitfile *ld, sbr_info *sbr, uint8_t bs_extension_id, uint16_t num_bits_left) { #ifdef PS_DEC uint8_t header; uint16_t ret; #endif (void)num_bits_left; /* FIXME: check */ switch (bs_extension_id) { #ifdef PS_DEC case EXTENSION_ID_PS: if (!sbr->ps) { sbr->ps = ps_init(get_sr_index(sbr->sample_rate), sbr->numTimeSlotsRate); } if (sbr->psResetFlag) { sbr->ps->header_read = 0; } ret = ps_data(sbr->ps, ld, &header); /* enable PS if and only if: a header has been decoded */ if (sbr->ps_used == 0 && header == 1) { sbr->ps_used = 1; } if (header == 1) { sbr->psResetFlag = 0; } return ret; #endif #ifdef DRM_PS case DRM_PARAMETRIC_STEREO: sbr->ps_used = 1; if (!sbr->drm_ps) { sbr->drm_ps = drm_ps_init(); } return drm_ps_data(sbr->drm_ps, ld); #endif default: sbr->bs_extension_data = (uint8_t)faad_getbits(ld, 6 DEBUGVAR(1,279,"sbr_single_channel_element(): bs_extension_data")); return 6; } } /* table 12 */ static void sinusoidal_coding(bitfile *ld, sbr_info *sbr, uint8_t ch) { uint8_t n; for (n = 0; n < sbr->N_high; n++) { sbr->bs_add_harmonic[ch][n] = faad_get1bit(ld DEBUGVAR(1,278,"sinusoidal_coding(): bs_add_harmonic")); } } #endif /* SBR_DEC */ xine-lib-1.2/contrib/libfaad/sbr_fbt.h0000644000175000017500000000407114647725152015502 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_fbt.h,v 1.18 2007/11/01 12:33:35 menno Exp $ **/ #ifndef __SBR_FBT_H__ #define __SBR_FBT_H__ #ifdef __cplusplus extern "C" { #endif uint8_t qmf_start_channel(uint8_t bs_start_freq, uint8_t bs_samplerate_mode, uint32_t sample_rate); uint8_t qmf_stop_channel(uint8_t bs_stop_freq, uint32_t sample_rate, uint8_t k0); uint8_t master_frequency_table_fs0(sbr_info *sbr, uint8_t k0, uint8_t k2, uint8_t bs_alter_scale); uint8_t master_frequency_table(sbr_info *sbr, uint8_t k0, uint8_t k2, uint8_t bs_freq_scale, uint8_t bs_alter_scale); uint8_t derived_frequency_table(sbr_info *sbr, uint8_t bs_xover_band, uint8_t k2); void limiter_frequency_table(sbr_info *sbr); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ssr_ipqf.c0000644000175000017500000001411414647725151015700 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ssr_ipqf.c,v 1.18 2007/11/01 12:33:39 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SSR_DEC #include "ssr.h" #include "ssr_ipqf.h" static real_t **app_pqfbuf; static real_t **pp_q0, **pp_t0, **pp_t1; void gc_set_protopqf(real_t *p_proto) { int j; static const real_t a_half[48] = { 1.2206911375946939E-05, 1.7261986723798209E-05, 1.2300093657077942E-05, -1.0833943097791965E-05, -5.7772498639901686E-05, -1.2764767618947719E-04, -2.0965186675013334E-04, -2.8166673689263850E-04, -3.1234860429017460E-04, -2.6738519958452353E-04, -1.1949424681824722E-04, 1.3965139412648678E-04, 4.8864136409185725E-04, 8.7044629275148344E-04, 1.1949430269934793E-03, 1.3519708175026700E-03, 1.2346314373964412E-03, 7.6953209114159191E-04, -5.2242432579537141E-05, -1.1516092887213454E-03, -2.3538469841711277E-03, -3.4033123072127277E-03, -4.0028551071986133E-03, -3.8745415659693259E-03, -2.8321073426874310E-03, -8.5038892323704195E-04, 1.8856751185350931E-03, 4.9688741735340923E-03, 7.8056704536795926E-03, 9.7027909685901654E-03, 9.9960423120166159E-03, 8.2019366335594487E-03, 4.1642072876103365E-03, -1.8364453822737758E-03, -9.0384863094167686E-03, -1.6241528177129844E-02, -2.1939551286300665E-02, -2.4533179947088161E-02, -2.2591663337768787E-02, -1.5122066420044672E-02, -1.7971713448186293E-03, 1.6903413428575379E-02, 3.9672315874127042E-02, 6.4487527248102796E-02, 8.8850025474701726E-02, 0.1101132906105560 , 0.1258540205143761 , 0.1342239368467012 }; for (j = 0; j < 48; ++j) { p_proto[j] = p_proto[95-j] = a_half[j]; } } void gc_setcoef_eff_pqfsyn(int mm, int kk, real_t *p_proto, real_t ***ppp_q0, real_t ***ppp_t0, real_t ***ppp_t1) { int i, k, n; real_t w; /* Set 1st Mul&Acc Coef's */ *ppp_q0 = (real_t **) calloc(mm, sizeof(real_t *)); for (n = 0; n < mm; ++n) { (*ppp_q0)[n] = (real_t *) calloc(mm, sizeof(real_t)); } for (n = 0; n < mm/2; ++n) { for (i = 0; i < mm; ++i) { w = (2*i+1)*(2*n+1-mm)*M_PI/(4*mm); (*ppp_q0)[n][i] = 2.0 * cos((real_t) w); w = (2*i+1)*(2*(mm+n)+1-mm)*M_PI/(4*mm); (*ppp_q0)[n + mm/2][i] = 2.0 * cos((real_t) w); } } /* Set 2nd Mul&Acc Coef's */ *ppp_t0 = (real_t **) calloc(mm, sizeof(real_t *)); *ppp_t1 = (real_t **) calloc(mm, sizeof(real_t *)); for (n = 0; n < mm; ++n) { (*ppp_t0)[n] = (real_t *) calloc(kk, sizeof(real_t)); (*ppp_t1)[n] = (real_t *) calloc(kk, sizeof(real_t)); } for (n = 0; n < mm; ++n) { for (k = 0; k < kk; ++k) { (*ppp_t0)[n][k] = mm * p_proto[2*k *mm + n]; (*ppp_t1)[n][k] = mm * p_proto[(2*k+1)*mm + n]; if (k%2 != 0) { (*ppp_t0)[n][k] = -(*ppp_t0)[n][k]; (*ppp_t1)[n][k] = -(*ppp_t1)[n][k]; } } } } void ssr_ipqf(ssr_info *ssr, real_t *in_data, real_t *out_data, real_t buffer[SSR_BANDS][96/4], uint16_t frame_len, uint8_t bands) { static int initFlag = 0; real_t a_pqfproto[PQFTAPS]; int i; if (initFlag == 0) { gc_set_protopqf(a_pqfproto); gc_setcoef_eff_pqfsyn(SSR_BANDS, PQFTAPS/(2*SSR_BANDS), a_pqfproto, &pp_q0, &pp_t0, &pp_t1); initFlag = 1; } for (i = 0; i < frame_len / SSR_BANDS; i++) { int l, n, k; int mm = SSR_BANDS; int kk = PQFTAPS/(2*SSR_BANDS); for (n = 0; n < mm; n++) { for (k = 0; k < 2*kk-1; k++) { buffer[n][k] = buffer[n][k+1]; } } for (n = 0; n < mm; n++) { real_t acc = 0.0; for (l = 0; l < mm; l++) { acc += pp_q0[n][l] * in_data[l*frame_len/SSR_BANDS + i]; } buffer[n][2*kk-1] = acc; } for (n = 0; n < mm/2; n++) { real_t acc = 0.0; for (k = 0; k < kk; k++) { acc += pp_t0[n][k] * buffer[n][2*kk-1-2*k]; } for (k = 0; k < kk; ++k) { acc += pp_t1[n][k] * buffer[n + mm/2][2*kk-2-2*k]; } out_data[i*SSR_BANDS + n] = acc; acc = 0.0; for (k = 0; k < kk; k++) { acc += pp_t0[mm-1-n][k] * buffer[n][2*kk-1-2*k]; } for (k = 0; k < kk; k++) { acc -= pp_t1[mm-1-n][k] * buffer[n + mm/2][2*kk-2-2*k]; } out_data[i*SSR_BANDS + mm-1-n] = acc; } } } #endif xine-lib-1.2/contrib/libfaad/syntax.h0000644000175000017500000000712714647725152015414 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: syntax.h,v 1.60 2009/01/26 23:51:17 menno Exp $ **/ #ifndef __SYNTAX_H__ #define __SYNTAX_H__ #ifdef __cplusplus extern "C" { #endif #include "bits.h" #define MAIN 1 #define LC 2 #define SSR 3 #define LTP 4 #define HE_AAC 5 #define LD 23 #define ER_LC 17 #define ER_LTP 19 #define DRM_ER_LC 27 /* special object type for DRM */ /* header types */ #define RAW 0 #define ADIF 1 #define ADTS 2 #define LATM 3 /* SBR signalling */ #define NO_SBR 0 #define SBR_UPSAMPLED 1 #define SBR_DOWNSAMPLED 2 #define NO_SBR_UPSAMPLED 3 /* DRM channel definitions */ #define DRMCH_MONO 1 #define DRMCH_STEREO 2 #define DRMCH_SBR_MONO 3 #define DRMCH_SBR_STEREO 4 #define DRMCH_SBR_PS_STEREO 5 /* First object type that has ER */ #define ER_OBJECT_START 17 /* Bitstream */ #define LEN_SE_ID 3 #define LEN_TAG 4 #define LEN_BYTE 8 #define EXT_FIL 0 #define EXT_FILL_DATA 1 #define EXT_DATA_ELEMENT 2 #define EXT_DYNAMIC_RANGE 11 #define ANC_DATA 0 /* Syntax elements */ #define ID_SCE 0x0 #define ID_CPE 0x1 #define ID_CCE 0x2 #define ID_LFE 0x3 #define ID_DSE 0x4 #define ID_PCE 0x5 #define ID_FIL 0x6 #define ID_END 0x7 #define ONLY_LONG_SEQUENCE 0x0 #define LONG_START_SEQUENCE 0x1 #define EIGHT_SHORT_SEQUENCE 0x2 #define LONG_STOP_SEQUENCE 0x3 #define ZERO_HCB 0 #define FIRST_PAIR_HCB 5 #define ESC_HCB 11 #define QUAD_LEN 4 #define PAIR_LEN 2 #define NOISE_HCB 13 #define INTENSITY_HCB2 14 #define INTENSITY_HCB 15 #define INVALID_SBR_ELEMENT 255 int8_t GASpecificConfig(bitfile *ld, mp4AudioSpecificConfig *mp4ASC, program_config *pce); uint8_t adts_frame(adts_header *adts, bitfile *ld); void get_adif_header(adif_header *adif, bitfile *ld); void raw_data_block(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, program_config *pce, drc_info *drc); uint8_t reordered_spectral_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld, int16_t *spectral_data); #ifdef DRM void DRM_aac_scalable_main_element(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, program_config *pce, drc_info *drc); #endif uint32_t faad_latm_frame(latm_header *latm, bitfile *ld); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/ps_tables.h0000644000175000017500000017271514647725152016050 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ps_tables.h,v 1.8 2007/11/01 12:33:33 menno Exp $ **/ #ifndef __PS_TABLES_H__ #define __PS_TABLES_H__ #ifdef __cplusplus extern "C" { #endif #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif #if 0 #if 0 float f_center_20[12] = { 0.5/4, 1.5/4, 2.5/4, 3.5/4, 4.5/4*0, 5.5/4*0, -1.5/4, -0.5/4, 3.5/2, 2.5/2, 4.5/2, 5.5/2 }; #else float f_center_20[12] = { 0.5/8, 1.5/8, 2.5/8, 3.5/8, 4.5/8*0, 5.5/8*0, -1.5/8, -0.5/8, 3.5/4, 2.5/4, 4.5/4, 5.5/4 }; #endif float f_center_34[32] = { 1/12, 3/12, 5/12, 7/12, 9/12, 11/12, 13/12, 15/12, 17/12, -5/12, -3/12, -1/12, 17/8, 19/8, 5/8, 7/8, 9/8, 11/8, 13/8, 15/8, 9/4, 11/4, 13/4, 7/4, 17/4, 11/4, 13/4, 15/4, 17/4, 19/4, 21/4, 15/4 }; static const real_t frac_delay_q[] = { FRAC_CONST(0.43), FRAC_CONST(0.75), FRAC_CONST(0.347) }; #endif /* RE(ps->Phi_Fract_Qmf[j]) = (float)cos(M_PI*(j+0.5)*(0.39)); */ /* IM(ps->Phi_Fract_Qmf[j]) = (float)sin(M_PI*(j+0.5)*(0.39)); */ static const complex_t Phi_Fract_Qmf[] = { { FRAC_CONST(0.8181497455), FRAC_CONST(0.5750052333) }, { FRAC_CONST(-0.2638730407), FRAC_CONST(0.9645574093) }, { FRAC_CONST(-0.9969173074), FRAC_CONST(0.0784590989) }, { FRAC_CONST(-0.4115143716), FRAC_CONST(-0.9114032984) }, { FRAC_CONST(0.7181262970), FRAC_CONST(-0.6959127784) }, { FRAC_CONST(0.8980275989), FRAC_CONST(0.4399391711) }, { FRAC_CONST(-0.1097343117), FRAC_CONST(0.9939609766) }, { FRAC_CONST(-0.9723699093), FRAC_CONST(0.2334453613) }, { FRAC_CONST(-0.5490227938), FRAC_CONST(-0.8358073831) }, { FRAC_CONST(0.6004202366), FRAC_CONST(-0.7996846437) }, { FRAC_CONST(0.9557930231), FRAC_CONST(0.2940403223) }, { FRAC_CONST(0.0471064523), FRAC_CONST(0.9988898635) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.6730124950), FRAC_CONST(-0.7396311164) }, { FRAC_CONST(0.4679298103), FRAC_CONST(-0.8837656379) }, { FRAC_CONST(0.9900236726), FRAC_CONST(0.1409012377) }, { FRAC_CONST(0.2027872950), FRAC_CONST(0.9792228341) }, { FRAC_CONST(-0.8526401520), FRAC_CONST(0.5224985480) }, { FRAC_CONST(-0.7804304361), FRAC_CONST(-0.6252426505) }, { FRAC_CONST(0.3239174187), FRAC_CONST(-0.9460853338) }, { FRAC_CONST(0.9998766184), FRAC_CONST(-0.0157073177) }, { FRAC_CONST(0.3534748554), FRAC_CONST(0.9354440570) }, { FRAC_CONST(-0.7604059577), FRAC_CONST(0.6494480371) }, { FRAC_CONST(-0.8686315417), FRAC_CONST(-0.4954586625) }, { FRAC_CONST(0.1719291061), FRAC_CONST(-0.9851093292) }, { FRAC_CONST(0.9851093292), FRAC_CONST(-0.1719291061) }, { FRAC_CONST(0.4954586625), FRAC_CONST(0.8686315417) }, { FRAC_CONST(-0.6494480371), FRAC_CONST(0.7604059577) }, { FRAC_CONST(-0.9354440570), FRAC_CONST(-0.3534748554) }, { FRAC_CONST(0.0157073177), FRAC_CONST(-0.9998766184) }, { FRAC_CONST(0.9460853338), FRAC_CONST(-0.3239174187) }, { FRAC_CONST(0.6252426505), FRAC_CONST(0.7804304361) }, { FRAC_CONST(-0.5224985480), FRAC_CONST(0.8526401520) }, { FRAC_CONST(-0.9792228341), FRAC_CONST(-0.2027872950) }, { FRAC_CONST(-0.1409012377), FRAC_CONST(-0.9900236726) }, { FRAC_CONST(0.8837656379), FRAC_CONST(-0.4679298103) }, { FRAC_CONST(0.7396311164), FRAC_CONST(0.6730124950) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9988898635), FRAC_CONST(-0.0471064523) }, { FRAC_CONST(-0.2940403223), FRAC_CONST(-0.9557930231) }, { FRAC_CONST(0.7996846437), FRAC_CONST(-0.6004202366) }, { FRAC_CONST(0.8358073831), FRAC_CONST(0.5490227938) }, { FRAC_CONST(-0.2334453613), FRAC_CONST(0.9723699093) }, { FRAC_CONST(-0.9939609766), FRAC_CONST(0.1097343117) }, { FRAC_CONST(-0.4399391711), FRAC_CONST(-0.8980275989) }, { FRAC_CONST(0.6959127784), FRAC_CONST(-0.7181262970) }, { FRAC_CONST(0.9114032984), FRAC_CONST(0.4115143716) }, { FRAC_CONST(-0.0784590989), FRAC_CONST(0.9969173074) }, { FRAC_CONST(-0.9645574093), FRAC_CONST(0.2638730407) }, { FRAC_CONST(-0.5750052333), FRAC_CONST(-0.8181497455) }, { FRAC_CONST(0.5750052333), FRAC_CONST(-0.8181497455) }, { FRAC_CONST(0.9645574093), FRAC_CONST(0.2638730407) }, { FRAC_CONST(0.0784590989), FRAC_CONST(0.9969173074) }, { FRAC_CONST(-0.9114032984), FRAC_CONST(0.4115143716) }, { FRAC_CONST(-0.6959127784), FRAC_CONST(-0.7181262970) }, { FRAC_CONST(0.4399391711), FRAC_CONST(-0.8980275989) }, { FRAC_CONST(0.9939609766), FRAC_CONST(0.1097343117) }, { FRAC_CONST(0.2334453613), FRAC_CONST(0.9723699093) }, { FRAC_CONST(-0.8358073831), FRAC_CONST(0.5490227938) }, { FRAC_CONST(-0.7996846437), FRAC_CONST(-0.6004202366) }, { FRAC_CONST(0.2940403223), FRAC_CONST(-0.9557930231) }, { FRAC_CONST(0.9988898635), FRAC_CONST(-0.0471064523) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7396311164), FRAC_CONST(0.6730124950) } }; /* RE(Phi_Fract_SubQmf20[j]) = (float)cos(M_PI*f_center_20[j]*0.39); */ /* IM(Phi_Fract_SubQmf20[j]) = (float)sin(M_PI*f_center_20[j]*0.39); */ static const complex_t Phi_Fract_SubQmf20[] = { { FRAC_CONST(0.9882950187), FRAC_CONST(0.1525546312) }, { FRAC_CONST(0.8962930441), FRAC_CONST(0.4434623122) }, { FRAC_CONST(0.7208535671), FRAC_CONST(0.6930873394) }, { FRAC_CONST(0.4783087075), FRAC_CONST(0.8781917691) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(0.8962930441), FRAC_CONST(-0.4434623122) }, { FRAC_CONST(0.9882950187), FRAC_CONST(-0.1525546312) }, { FRAC_CONST(-0.5424415469), FRAC_CONST(0.8400935531) }, { FRAC_CONST(0.0392598175), FRAC_CONST(0.9992290139) }, { FRAC_CONST(-0.9268565774), FRAC_CONST(0.3754155636) }, { FRAC_CONST(-0.9741733670), FRAC_CONST(-0.2258012742) } }; /* RE(Phi_Fract_SubQmf34[j]) = (float)cos(M_PI*f_center_34[j]*0.39); */ /* IM(Phi_Fract_SubQmf34[j]) = (float)sin(M_PI*f_center_34[j]*0.39); */ static const complex_t Phi_Fract_SubQmf34[] = { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) }, { FRAC_CONST(0.3387379348), FRAC_CONST(0.9408807755) }, { FRAC_CONST(0.1873813123), FRAC_CONST(-0.9822872281) }, { FRAC_CONST(-0.7705132365), FRAC_CONST(0.6374239922) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) }, { FRAC_CONST(0.1873813123), FRAC_CONST(-0.9822872281) }, { FRAC_CONST(0.1873813123), FRAC_CONST(-0.9822872281) }, { FRAC_CONST(0.9876883626), FRAC_CONST(-0.1564344615) }, { FRAC_CONST(-0.8607420325), FRAC_CONST(-0.5090414286) } }; /* RE(Q_Fract_allpass_Qmf[j][i]) = (float)cos(M_PI*(j+0.5)*(frac_delay_q[i])); */ /* IM(Q_Fract_allpass_Qmf[j][i]) = (float)sin(M_PI*(j+0.5)*(frac_delay_q[i])); */ static const complex_t Q_Fract_allpass_Qmf[][3] = { { { FRAC_CONST(0.7804303765), FRAC_CONST(0.6252426505) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.8550928831), FRAC_CONST(0.5184748173) } }, { { FRAC_CONST(-0.4399392009), FRAC_CONST(0.8980275393) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.0643581524), FRAC_CONST(0.9979268909) } }, { { FRAC_CONST(-0.9723699093), FRAC_CONST(-0.2334454209) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.9146071672), FRAC_CONST(0.4043435752) } }, { { FRAC_CONST(0.0157073960), FRAC_CONST(-0.9998766184) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7814115286), FRAC_CONST(-0.6240159869) } }, { { FRAC_CONST(0.9792228341), FRAC_CONST(-0.2027871907) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.1920081824), FRAC_CONST(-0.9813933372) } }, { { FRAC_CONST(0.4115142524), FRAC_CONST(0.9114032984) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.9589683414), FRAC_CONST(-0.2835132182) } }, { { FRAC_CONST(-0.7996847630), FRAC_CONST(0.6004201174) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.6947838664), FRAC_CONST(0.7192186117) } }, { { FRAC_CONST(-0.7604058385), FRAC_CONST(-0.6494481564) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.3164770305), FRAC_CONST(0.9486001730) } }, { { FRAC_CONST(0.4679299891), FRAC_CONST(-0.8837655187) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9874414206), FRAC_CONST(0.1579856575) } }, { { FRAC_CONST(0.9645573497), FRAC_CONST(0.2638732493) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.5966450572), FRAC_CONST(-0.8025052547) } }, { { FRAC_CONST(-0.0471066870), FRAC_CONST(0.9988898635) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.4357025325), FRAC_CONST(-0.9000906944) } }, { { FRAC_CONST(-0.9851093888), FRAC_CONST(0.1719288528) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9995546937), FRAC_CONST(-0.0298405960) } }, { { FRAC_CONST(-0.3826831877), FRAC_CONST(-0.9238796234) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.4886211455), FRAC_CONST(0.8724960685) } }, { { FRAC_CONST(0.8181498647), FRAC_CONST(-0.5750049949) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.5477093458), FRAC_CONST(0.8366686702) } }, { { FRAC_CONST(0.7396308780), FRAC_CONST(0.6730127335) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9951074123), FRAC_CONST(-0.0987988561) } }, { { FRAC_CONST(-0.4954589605), FRAC_CONST(0.8686313629) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.3725017905), FRAC_CONST(-0.9280315042) } }, { { FRAC_CONST(-0.9557929039), FRAC_CONST(-0.2940406799) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.6506417990), FRAC_CONST(-0.7593847513) } }, { { FRAC_CONST(0.0784594864), FRAC_CONST(-0.9969173074) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9741733670), FRAC_CONST(0.2258014232) } }, { { FRAC_CONST(0.9900237322), FRAC_CONST(-0.1409008205) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.2502108514), FRAC_CONST(0.9681913853) } }, { { FRAC_CONST(0.3534744382), FRAC_CONST(0.9354441762) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7427945137), FRAC_CONST(0.6695194840) } }, { { FRAC_CONST(-0.8358076215), FRAC_CONST(0.5490224361) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9370992780), FRAC_CONST(-0.3490629196) } }, { { FRAC_CONST(-0.7181259394), FRAC_CONST(-0.6959131360) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.1237744763), FRAC_CONST(-0.9923103452) } }, { { FRAC_CONST(0.5224990249), FRAC_CONST(-0.8526399136) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.8226406574), FRAC_CONST(-0.5685616732) } }, { { FRAC_CONST(0.9460852146), FRAC_CONST(0.3239179254) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.8844994903), FRAC_CONST(0.4665412009) } }, { { FRAC_CONST(-0.1097348556), FRAC_CONST(0.9939609170) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.0047125919), FRAC_CONST(0.9999889135) } }, { { FRAC_CONST(-0.9939610362), FRAC_CONST(0.1097337380) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8888573647), FRAC_CONST(0.4581840038) } }, { { FRAC_CONST(-0.3239168525), FRAC_CONST(-0.9460855722) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8172453642), FRAC_CONST(-0.5762898922) } }, { { FRAC_CONST(0.8526405096), FRAC_CONST(-0.5224980116) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.1331215799), FRAC_CONST(-0.9910997152) } }, { { FRAC_CONST(0.6959123611), FRAC_CONST(0.7181267142) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.9403476119), FRAC_CONST(-0.3402152061) } }, { { FRAC_CONST(-0.5490233898), FRAC_CONST(0.8358070254) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.7364512086), FRAC_CONST(0.6764906645) } }, { { FRAC_CONST(-0.9354437590), FRAC_CONST(-0.3534754813) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.2593250275), FRAC_CONST(0.9657900929) } }, { { FRAC_CONST(0.1409019381), FRAC_CONST(-0.9900235534) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9762582779), FRAC_CONST(0.2166097313) } }, { { FRAC_CONST(0.9969173670), FRAC_CONST(-0.0784583688) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.6434556246), FRAC_CONST(-0.7654833794) } }, { { FRAC_CONST(0.2940396070), FRAC_CONST(0.9557932615) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.3812320232), FRAC_CONST(-0.9244794250) } }, { { FRAC_CONST(-0.8686318994), FRAC_CONST(0.4954580069) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9959943891), FRAC_CONST(-0.0894154981) } }, { { FRAC_CONST(-0.6730118990), FRAC_CONST(-0.7396316528) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.5397993922), FRAC_CONST(0.8417937160) } }, { { FRAC_CONST(0.5750059485), FRAC_CONST(-0.8181492686) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.4968227744), FRAC_CONST(0.8678520322) } }, { { FRAC_CONST(0.9238792062), FRAC_CONST(0.3826842010) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9992290139), FRAC_CONST(-0.0392601527) } }, { { FRAC_CONST(-0.1719299555), FRAC_CONST(0.9851091504) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.4271997511), FRAC_CONST(-0.9041572809) } }, { { FRAC_CONST(-0.9988899231), FRAC_CONST(0.0471055657) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.6041822433), FRAC_CONST(-0.7968461514) } }, { { FRAC_CONST(-0.2638721764), FRAC_CONST(-0.9645576477) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9859085083), FRAC_CONST(0.1672853529) } }, { { FRAC_CONST(0.8837660551), FRAC_CONST(-0.4679289758) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.3075223565), FRAC_CONST(0.9515408874) } }, { { FRAC_CONST(0.6494473219), FRAC_CONST(0.7604066133) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.7015317082), FRAC_CONST(0.7126382589) } }, { { FRAC_CONST(-0.6004210114), FRAC_CONST(0.7996840477) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9562535882), FRAC_CONST(-0.2925389707) } }, { { FRAC_CONST(-0.9114028811), FRAC_CONST(-0.4115152657) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.1827499419), FRAC_CONST(-0.9831594229) } }, { { FRAC_CONST(0.2027882934), FRAC_CONST(-0.9792225957) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.7872582674), FRAC_CONST(-0.6166234016) } }, { { FRAC_CONST(0.9998766780), FRAC_CONST(-0.0157062728) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.9107555747), FRAC_CONST(0.4129458666) } }, { { FRAC_CONST(0.2334443331), FRAC_CONST(0.9723701477) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.0549497530), FRAC_CONST(0.9984891415) } }, { { FRAC_CONST(-0.8980280757), FRAC_CONST(0.4399381876) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.8599416018), FRAC_CONST(0.5103924870) } }, { { FRAC_CONST(-0.6252418160), FRAC_CONST(-0.7804310918) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8501682281), FRAC_CONST(-0.5265110731) } }, { { FRAC_CONST(0.6252435446), FRAC_CONST(-0.7804297209) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.0737608299), FRAC_CONST(-0.9972759485) } }, { { FRAC_CONST(0.8980270624), FRAC_CONST(0.4399402142) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9183775187), FRAC_CONST(-0.3957053721) } }, { { FRAC_CONST(-0.2334465086), FRAC_CONST(0.9723696709) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.7754954696), FRAC_CONST(0.6313531399) } }, { { FRAC_CONST(-0.9998766184), FRAC_CONST(-0.0157085191) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.2012493610), FRAC_CONST(0.9795400500) } }, { { FRAC_CONST(-0.2027861029), FRAC_CONST(-0.9792230725) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9615978599), FRAC_CONST(0.2744622827) } }, { { FRAC_CONST(0.9114037752), FRAC_CONST(-0.4115132093) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.6879743338), FRAC_CONST(-0.7257350087) } }, { { FRAC_CONST(0.6004192233), FRAC_CONST(0.7996854186) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.3254036009), FRAC_CONST(-0.9455752373) } }, { { FRAC_CONST(-0.6494490504), FRAC_CONST(0.7604051232) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9888865948), FRAC_CONST(-0.1486719251) } }, { { FRAC_CONST(-0.8837650418), FRAC_CONST(-0.4679309726) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.5890548825), FRAC_CONST(0.8080930114) } }, { { FRAC_CONST(0.2638743520), FRAC_CONST(-0.9645570517) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.4441666007), FRAC_CONST(0.8959442377) } }, { { FRAC_CONST(0.9988898039), FRAC_CONST(0.0471078083) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9997915030), FRAC_CONST(0.0204183888) } }, { { FRAC_CONST(0.1719277352), FRAC_CONST(0.9851095676) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.4803760946), FRAC_CONST(-0.8770626187) } }, { { FRAC_CONST(-0.9238800406), FRAC_CONST(0.3826821446) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.5555707216), FRAC_CONST(-0.8314692974) } }, { { FRAC_CONST(-0.5750041008), FRAC_CONST(-0.8181505203) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.9941320419), FRAC_CONST(0.1081734300) } } }; /* RE(Q_Fract_allpass_SubQmf20[j][i]) = (float)cos(M_PI*f_center_20[j]*frac_delay_q[i]); */ /* IM(Q_Fract_allpass_SubQmf20[j][i]) = (float)sin(M_PI*f_center_20[j]*frac_delay_q[i]); */ static const complex_t Q_Fract_allpass_SubQmf20[][3] = { { { FRAC_CONST(0.9857769012), FRAC_CONST(0.1680592746) }, { FRAC_CONST(0.9569403529), FRAC_CONST(0.2902846634) }, { FRAC_CONST(0.9907300472), FRAC_CONST(0.1358452588) } }, { { FRAC_CONST(0.8744080663), FRAC_CONST(0.4851911962) }, { FRAC_CONST(0.6343932748), FRAC_CONST(0.7730104327) }, { FRAC_CONST(0.9175986052), FRAC_CONST(0.3975082636) } }, { { FRAC_CONST(0.6642524004), FRAC_CONST(0.7475083470) }, { FRAC_CONST(0.0980171412), FRAC_CONST(0.9951847196) }, { FRAC_CONST(0.7767338753), FRAC_CONST(0.6298289299) } }, { { FRAC_CONST(0.3790524006), FRAC_CONST(0.9253752232) }, { FRAC_CONST(-0.4713967443), FRAC_CONST(0.8819212914) }, { FRAC_CONST(0.5785340071), FRAC_CONST(0.8156582713) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(0.8744080663), FRAC_CONST(-0.4851911962) }, { FRAC_CONST(0.6343932748), FRAC_CONST(-0.7730104327) }, { FRAC_CONST(0.9175986052), FRAC_CONST(-0.3975082636) } }, { { FRAC_CONST(0.9857769012), FRAC_CONST(-0.1680592746) }, { FRAC_CONST(0.9569403529), FRAC_CONST(-0.2902846634) }, { FRAC_CONST(0.9907300472), FRAC_CONST(-0.1358452588) } }, { { FRAC_CONST(-0.7126385570), FRAC_CONST(0.7015314102) }, { FRAC_CONST(-0.5555702448), FRAC_CONST(-0.8314695954) }, { FRAC_CONST(-0.3305967748), FRAC_CONST(0.9437720776) } }, { { FRAC_CONST(-0.1175374240), FRAC_CONST(0.9930684566) }, { FRAC_CONST(-0.9807852507), FRAC_CONST(0.1950903237) }, { FRAC_CONST(0.2066311091), FRAC_CONST(0.9784189463) } }, { { FRAC_CONST(-0.9947921634), FRAC_CONST(0.1019244045) }, { FRAC_CONST(0.5555702448), FRAC_CONST(-0.8314695954) }, { FRAC_CONST(-0.7720130086), FRAC_CONST(0.6356067061) } }, { { FRAC_CONST(-0.8400934935), FRAC_CONST(-0.5424416065) }, { FRAC_CONST(0.9807852507), FRAC_CONST(0.1950903237) }, { FRAC_CONST(-0.9896889329), FRAC_CONST(0.1432335079) } } }; /* RE(Q_Fract_allpass_SubQmf34[j][i]) = (float)cos(M_PI*f_center_34[j]*frac_delay_q[i]); */ /* IM(Q_Fract_allpass_SubQmf34[j][i]) = (float)sin(M_PI*f_center_34[j]*frac_delay_q[i]); */ static const complex_t Q_Fract_allpass_SubQmf34[][3] = { { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(1.0000000000), FRAC_CONST(0.0000000000) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } }, { { FRAC_CONST(0.2181432247), FRAC_CONST(0.9759167433) }, { FRAC_CONST(-0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(0.4623677433), FRAC_CONST(0.8866882324) } }, { { FRAC_CONST(0.6374240518), FRAC_CONST(-0.7705131769) }, { FRAC_CONST(-1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.3446428776), FRAC_CONST(-0.9387338758) } }, { { FRAC_CONST(-0.9048270583), FRAC_CONST(0.4257792532) }, { FRAC_CONST(-0.0000000000), FRAC_CONST(-1.0000000000) }, { FRAC_CONST(-0.5724321604), FRAC_CONST(0.8199520707) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } }, { { FRAC_CONST(0.6374240518), FRAC_CONST(-0.7705131769) }, { FRAC_CONST(-1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.3446428776), FRAC_CONST(-0.9387338758) } }, { { FRAC_CONST(0.6374240518), FRAC_CONST(-0.7705131769) }, { FRAC_CONST(-1.0000000000), FRAC_CONST(0.0000000000) }, { FRAC_CONST(-0.3446428776), FRAC_CONST(-0.9387338758) } }, { { FRAC_CONST(0.8910064697), FRAC_CONST(0.4539906085) }, { FRAC_CONST(0.7071067691), FRAC_CONST(-0.7071067691) }, { FRAC_CONST(0.6730125546), FRAC_CONST(-0.7396310568) } }, { { FRAC_CONST(-0.6129069924), FRAC_CONST(-0.7901550531) }, { FRAC_CONST(0.7071067691), FRAC_CONST(0.7071067691) }, { FRAC_CONST(-0.9917160273), FRAC_CONST(-0.1284494549) } } }; #if 0 static float quant_rho[8] = { FRAC_CONST(1.0), FRAC_CONST(0.937), FRAC_CONST(0.84118), FRAC_CONST(0.60092), FRAC_CONST(0.36764), FRAC_CONST(0.0), FRAC_CONST(-0.589), FRAC_CONST(-1.0) }; static const uint8_t quant_iid_normal[7] = { 2, 4, 7, 10, 14, 18, 25 }; static const uint8_t quant_iid_fine[15] = { 2, 4, 6, 8, 10, 13, 16, 19, 22, 25, 30, 35, 40, 45, 50 }; #endif static const real_t cos_alphas[] = { COEF_CONST(1.0000000000), COEF_CONST(0.9841239700), COEF_CONST(0.9594738210), COEF_CONST(0.8946843079), COEF_CONST(0.8269340931), COEF_CONST(0.7071067812), COEF_CONST(0.4533210856), COEF_CONST(0.0000000000) }; static const real_t sin_alphas[] = { COEF_CONST(0.0000000000), COEF_CONST(0.1774824264), COEF_CONST(0.2817977763), COEF_CONST(0.4466989918), COEF_CONST(0.5622988580), COEF_CONST(0.7071067812), COEF_CONST(0.8913472911), COEF_CONST(1.0000000000) }; static const real_t cos_betas_normal[][8] = { { COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9995871699), COEF_CONST(0.9989419133), COEF_CONST(0.9972204583), COEF_CONST(0.9953790839), COEF_CONST(0.9920112747), COEF_CONST(0.9843408180), COEF_CONST(0.9681727381) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9984497744), COEF_CONST(0.9960279377), COEF_CONST(0.9895738413), COEF_CONST(0.9826814632), COEF_CONST(0.9701058164), COEF_CONST(0.9416098832), COEF_CONST(0.8822105900) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9959398908), COEF_CONST(0.9896038018), COEF_CONST(0.9727589768), COEF_CONST(0.9548355329), COEF_CONST(0.9223070404), COEF_CONST(0.8494349490), COEF_CONST(0.7013005535) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9932417400), COEF_CONST(0.9827071856), COEF_CONST(0.9547730996), COEF_CONST(0.9251668930), COEF_CONST(0.8717461589), COEF_CONST(0.7535520592), COEF_CONST(0.5198827312) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9902068095), COEF_CONST(0.9749613872), COEF_CONST(0.9346538534), COEF_CONST(0.8921231300), COEF_CONST(0.8158851259), COEF_CONST(0.6495964302), COEF_CONST(0.3313370772) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9880510933), COEF_CONST(0.9694670261), COEF_CONST(0.9204347876), COEF_CONST(0.8688622825), COEF_CONST(0.7768516704), COEF_CONST(0.5782161800), COEF_CONST(0.2069970356) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9858996945), COEF_CONST(0.9639898866), COEF_CONST(0.9063034786), COEF_CONST(0.8458214608), COEF_CONST(0.7384262300), COEF_CONST(0.5089811277), COEF_CONST(0.0905465944) } }; static const real_t sin_betas_normal[][8] = { { COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0287313368), COEF_CONST(-0.0459897147), COEF_CONST(-0.0745074328), COEF_CONST(-0.0960233266), COEF_CONST(-0.1261492408), COEF_CONST(-0.1762757894), COEF_CONST(-0.2502829383) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0556601118), COEF_CONST(-0.0890412670), COEF_CONST(-0.1440264301), COEF_CONST(-0.1853028382), COEF_CONST(-0.2426823129), COEF_CONST(-0.3367058477), COEF_CONST(-0.4708550466) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0900207420), COEF_CONST(-0.1438204281), COEF_CONST(-0.2318188366), COEF_CONST(-0.2971348264), COEF_CONST(-0.3864579191), COEF_CONST(-0.5276933461), COEF_CONST(-0.7128657193) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1160639735), COEF_CONST(-0.1851663774), COEF_CONST(-0.2973353800), COEF_CONST(-0.3795605619), COEF_CONST(-0.4899577884), COEF_CONST(-0.6573882369), COEF_CONST(-0.8542376401) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1396082894), COEF_CONST(-0.2223742196), COEF_CONST(-0.3555589603), COEF_CONST(-0.4517923427), COEF_CONST(-0.5782140273), COEF_CONST(-0.7602792104), COEF_CONST(-0.9435124489) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1541266914), COEF_CONST(-0.2452217065), COEF_CONST(-0.3908961522), COEF_CONST(-0.4950538699), COEF_CONST(-0.6296836366), COEF_CONST(-0.8158836002), COEF_CONST(-0.9783415698) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1673373610), COEF_CONST(-0.2659389001), COEF_CONST(-0.4226275012), COEF_CONST(-0.5334660781), COEF_CONST(-0.6743342664), COEF_CONST(-0.8607776784), COEF_CONST(-0.9958922202) } }; static const real_t cos_betas_fine[][8] = { { COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000), COEF_CONST(1.0000000000) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9995871699), COEF_CONST(0.9989419133), COEF_CONST(0.9972204583), COEF_CONST(0.9953790839), COEF_CONST(0.9920112747), COEF_CONST(0.9843408180), COEF_CONST(0.9681727381) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9984497744), COEF_CONST(0.9960279377), COEF_CONST(0.9895738413), COEF_CONST(0.9826814632), COEF_CONST(0.9701058164), COEF_CONST(0.9416098832), COEF_CONST(0.8822105900) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9968361371), COEF_CONST(0.9918968104), COEF_CONST(0.9787540479), COEF_CONST(0.9647515190), COEF_CONST(0.9392903010), COEF_CONST(0.8820167114), COEF_CONST(0.7645325390) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9950262915), COEF_CONST(0.9872675041), COEF_CONST(0.9666584578), COEF_CONST(0.9447588606), COEF_CONST(0.9050918405), COEF_CONST(0.8165997379), COEF_CONST(0.6383824796) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9932417400), COEF_CONST(0.9827071856), COEF_CONST(0.9547730996), COEF_CONST(0.9251668930), COEF_CONST(0.8717461589), COEF_CONST(0.7535520592), COEF_CONST(0.5198827312) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9908827998), COEF_CONST(0.9766855904), COEF_CONST(0.9391249214), COEF_CONST(0.8994531782), COEF_CONST(0.8282352693), COEF_CONST(0.6723983174), COEF_CONST(0.3719473225) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9890240165), COEF_CONST(0.9719459866), COEF_CONST(0.9268448110), COEF_CONST(0.8793388536), COEF_CONST(0.7944023271), COEF_CONST(0.6101812098), COEF_CONST(0.2621501145) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9876350461), COEF_CONST(0.9684073447), COEF_CONST(0.9176973944), COEF_CONST(0.8643930070), COEF_CONST(0.7693796058), COEF_CONST(0.5646720713), COEF_CONST(0.1838899556) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9866247085), COEF_CONST(0.9658349704), COEF_CONST(0.9110590761), COEF_CONST(0.8535668048), COEF_CONST(0.7513165426), COEF_CONST(0.5320914819), COEF_CONST(0.1289530943) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9858996945), COEF_CONST(0.9639898866), COEF_CONST(0.9063034786), COEF_CONST(0.8458214608), COEF_CONST(0.7384262300), COEF_CONST(0.5089811277), COEF_CONST(0.0905465944) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9851245614), COEF_CONST(0.9620180268), COEF_CONST(0.9012265590), COEF_CONST(0.8375623272), COEF_CONST(0.7247108045), COEF_CONST(0.4845204297), COEF_CONST(0.0504115003) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9846869856), COEF_CONST(0.9609052357), COEF_CONST(0.8983639533), COEF_CONST(0.8329098386), COEF_CONST(0.7169983441), COEF_CONST(0.4708245354), COEF_CONST(0.0281732509) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9844406325), COEF_CONST(0.9602788522), COEF_CONST(0.8967533934), COEF_CONST(0.8302936455), COEF_CONST(0.7126658102), COEF_CONST(0.4631492839), COEF_CONST(0.0157851140) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9843020502), COEF_CONST(0.9599265269), COEF_CONST(0.8958477331), COEF_CONST(0.8288229094), COEF_CONST(0.7102315840), COEF_CONST(0.4588429315), COEF_CONST(0.0088578059) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9842241136), COEF_CONST(0.9597283916), COEF_CONST(0.8953385094), COEF_CONST(0.8279961409), COEF_CONST(0.7088635748), COEF_CONST(0.4564246834), COEF_CONST(0.0049751355) } }; static const real_t sin_betas_fine[][8] = { { COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000), COEF_CONST(0.0000000000) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0287313368), COEF_CONST(-0.0459897147), COEF_CONST(-0.0745074328), COEF_CONST(-0.0960233266), COEF_CONST(-0.1261492408), COEF_CONST(-0.1762757894), COEF_CONST(-0.2502829383) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0556601118), COEF_CONST(-0.0890412670), COEF_CONST(-0.1440264301), COEF_CONST(-0.1853028382), COEF_CONST(-0.2426823129), COEF_CONST(-0.3367058477), COEF_CONST(-0.4708550466) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0794840594), COEF_CONST(-0.1270461238), COEF_CONST(-0.2050378347), COEF_CONST(-0.2631625097), COEF_CONST(-0.3431234916), COEF_CONST(-0.4712181245), COEF_CONST(-0.6445851354) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.0996126459), COEF_CONST(-0.1590687758), COEF_CONST(-0.2560691819), COEF_CONST(-0.3277662204), COEF_CONST(-0.4252161335), COEF_CONST(-0.5772043556), COEF_CONST(-0.7697193058) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1160639735), COEF_CONST(-0.1851663774), COEF_CONST(-0.2973353800), COEF_CONST(-0.3795605619), COEF_CONST(-0.4899577884), COEF_CONST(-0.6573882369), COEF_CONST(-0.8542376401) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1347266752), COEF_CONST(-0.2146747714), COEF_CONST(-0.3435758752), COEF_CONST(-0.4370171396), COEF_CONST(-0.5603805303), COEF_CONST(-0.7401895046), COEF_CONST(-0.9282538388) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1477548470), COEF_CONST(-0.2352041647), COEF_CONST(-0.3754446647), COEF_CONST(-0.4761965776), COEF_CONST(-0.6073919186), COEF_CONST(-0.7922618830), COEF_CONST(-0.9650271071) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1567705832), COEF_CONST(-0.2493736450), COEF_CONST(-0.3972801182), COEF_CONST(-0.5028167951), COEF_CONST(-0.6387918458), COEF_CONST(-0.8253153651), COEF_CONST(-0.9829468369) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1630082348), COEF_CONST(-0.2591578860), COEF_CONST(-0.4122758299), COEF_CONST(-0.5209834064), COEF_CONST(-0.6599420072), COEF_CONST(-0.8466868694), COEF_CONST(-0.9916506943) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1673373610), COEF_CONST(-0.2659389001), COEF_CONST(-0.4226275012), COEF_CONST(-0.5334660781), COEF_CONST(-0.6743342664), COEF_CONST(-0.8607776784), COEF_CONST(-0.9958922202) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1718417832), COEF_CONST(-0.2729859267), COEF_CONST(-0.4333482310), COEF_CONST(-0.5463417868), COEF_CONST(-0.6890531546), COEF_CONST(-0.8747799456), COEF_CONST(-0.9987285320) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1743316967), COEF_CONST(-0.2768774604), COEF_CONST(-0.4392518725), COEF_CONST(-0.5534087104), COEF_CONST(-0.6970748701), COEF_CONST(-0.8822268738), COEF_CONST(-0.9996030552) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1757175038), COEF_CONST(-0.2790421580), COEF_CONST(-0.4425306221), COEF_CONST(-0.5573261722), COEF_CONST(-0.7015037013), COEF_CONST(-0.8862802834), COEF_CONST(-0.9998754073) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1764921355), COEF_CONST(-0.2802517850), COEF_CONST(-0.4443611583), COEF_CONST(-0.5595110229), COEF_CONST(-0.7039681080), COEF_CONST(-0.8885173967), COEF_CONST(-0.9999607689) }, { COEF_CONST(0.0000000000), COEF_CONST(-0.1769262394), COEF_CONST(-0.2809295540), COEF_CONST(-0.4453862969), COEF_CONST(-0.5607337966), COEF_CONST(-0.7053456119), COEF_CONST(-0.8897620516), COEF_CONST(-0.9999876239) } }; static const real_t sincos_alphas_B_normal[][8] = { { COEF_CONST(0.0561454100), COEF_CONST(0.0526385859), COEF_CONST(0.0472937334), COEF_CONST(0.0338410641), COEF_CONST(0.0207261065), COEF_CONST(0.0028205635), COEF_CONST(0.0028205635), COEF_CONST(0.0028205635) }, { COEF_CONST(0.1249065138), COEF_CONST(0.1173697697), COEF_CONST(0.1057888284), COEF_CONST(0.0761985131), COEF_CONST(0.0468732723), COEF_CONST(0.0063956103), COEF_CONST(0.0063956103), COEF_CONST(0.0063956103) }, { COEF_CONST(0.1956693050), COEF_CONST(0.1846090179), COEF_CONST(0.1673645109), COEF_CONST(0.1220621836), COEF_CONST(0.0757362479), COEF_CONST(0.0103882630), COEF_CONST(0.0103882630), COEF_CONST(0.0103882630) }, { COEF_CONST(0.3015113269), COEF_CONST(0.2870525790), COEF_CONST(0.2637738799), COEF_CONST(0.1984573949), COEF_CONST(0.1260749909), COEF_CONST(0.0175600126), COEF_CONST(0.0175600126), COEF_CONST(0.0175600126) }, { COEF_CONST(0.4078449476), COEF_CONST(0.3929852420), COEF_CONST(0.3680589270), COEF_CONST(0.2911029124), COEF_CONST(0.1934512363), COEF_CONST(0.0278686716), COEF_CONST(0.0278686716), COEF_CONST(0.0278686716) }, { COEF_CONST(0.5336171261), COEF_CONST(0.5226637762), COEF_CONST(0.5033652606), COEF_CONST(0.4349162672), COEF_CONST(0.3224682122), COEF_CONST(0.0521999036), COEF_CONST(0.0521999036), COEF_CONST(0.0521999036) }, { COEF_CONST(0.6219832023), COEF_CONST(0.6161847276), COEF_CONST(0.6057251063), COEF_CONST(0.5654342668), COEF_CONST(0.4826149915), COEF_CONST(0.1058044758), COEF_CONST(0.1058044758), COEF_CONST(0.1058044758) }, { COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657) }, { COEF_CONST(0.7830305572), COEF_CONST(0.7876016373), COEF_CONST(0.7956739618), COEF_CONST(0.8247933372), COEF_CONST(0.8758325942), COEF_CONST(0.9943869542), COEF_CONST(0.9943869542), COEF_CONST(0.9943869542) }, { COEF_CONST(0.8457261833), COEF_CONST(0.8525388778), COEF_CONST(0.8640737401), COEF_CONST(0.9004708933), COEF_CONST(0.9465802987), COEF_CONST(0.9986366532), COEF_CONST(0.9986366532), COEF_CONST(0.9986366532) }, { COEF_CONST(0.9130511848), COEF_CONST(0.9195447612), COEF_CONST(0.9298024282), COEF_CONST(0.9566917233), COEF_CONST(0.9811098801), COEF_CONST(0.9996115928), COEF_CONST(0.9996115928), COEF_CONST(0.9996115928) }, { COEF_CONST(0.9534625907), COEF_CONST(0.9579148236), COEF_CONST(0.9645845234), COEF_CONST(0.9801095128), COEF_CONST(0.9920207064), COEF_CONST(0.9998458099), COEF_CONST(0.9998458099), COEF_CONST(0.9998458099) }, { COEF_CONST(0.9806699215), COEF_CONST(0.9828120260), COEF_CONST(0.9858950861), COEF_CONST(0.9925224431), COEF_CONST(0.9971278825), COEF_CONST(0.9999460406), COEF_CONST(0.9999460406), COEF_CONST(0.9999460406) }, { COEF_CONST(0.9921685024), COEF_CONST(0.9930882705), COEF_CONST(0.9943886135), COEF_CONST(0.9970926648), COEF_CONST(0.9989008403), COEF_CONST(0.9999795479), COEF_CONST(0.9999795479), COEF_CONST(0.9999795479) }, { COEF_CONST(0.9984226014), COEF_CONST(0.9986136287), COEF_CONST(0.9988810254), COEF_CONST(0.9994272242), COEF_CONST(0.9997851906), COEF_CONST(0.9999960221), COEF_CONST(0.9999960221), COEF_CONST(0.9999960221) } }; static const real_t sincos_alphas_B_fine[][8] = { { COEF_CONST(0.0031622158), COEF_CONST(0.0029630181), COEF_CONST(0.0026599892), COEF_CONST(0.0019002704), COEF_CONST(0.0011626042), COEF_CONST(0.0001580278), COEF_CONST(0.0001580278), COEF_CONST(0.0001580278) }, { COEF_CONST(0.0056232673), COEF_CONST(0.0052689825), COEF_CONST(0.0047302825), COEF_CONST(0.0033791756), COEF_CONST(0.0020674015), COEF_CONST(0.0002811710), COEF_CONST(0.0002811710), COEF_CONST(0.0002811710) }, { COEF_CONST(0.0099994225), COEF_CONST(0.0093696693), COEF_CONST(0.0084117414), COEF_CONST(0.0060093796), COEF_CONST(0.0036766009), COEF_CONST(0.0005000392), COEF_CONST(0.0005000392), COEF_CONST(0.0005000392) }, { COEF_CONST(0.0177799194), COEF_CONST(0.0166607102), COEF_CONST(0.0149581377), COEF_CONST(0.0106875809), COEF_CONST(0.0065392545), COEF_CONST(0.0008893767), COEF_CONST(0.0008893767), COEF_CONST(0.0008893767) }, { COEF_CONST(0.0316069684), COEF_CONST(0.0296211579), COEF_CONST(0.0265987295), COEF_CONST(0.0190113813), COEF_CONST(0.0116349973), COEF_CONST(0.0015826974), COEF_CONST(0.0015826974), COEF_CONST(0.0015826974) }, { COEF_CONST(0.0561454100), COEF_CONST(0.0526385859), COEF_CONST(0.0472937334), COEF_CONST(0.0338410641), COEF_CONST(0.0207261065), COEF_CONST(0.0028205635), COEF_CONST(0.0028205635), COEF_CONST(0.0028205635) }, { COEF_CONST(0.0791834041), COEF_CONST(0.0742798103), COEF_CONST(0.0667907269), COEF_CONST(0.0478705292), COEF_CONST(0.0293500747), COEF_CONST(0.0039966755), COEF_CONST(0.0039966755), COEF_CONST(0.0039966755) }, { COEF_CONST(0.1115021177), COEF_CONST(0.1047141985), COEF_CONST(0.0943053154), COEF_CONST(0.0678120561), COEF_CONST(0.0416669150), COEF_CONST(0.0056813213), COEF_CONST(0.0056813213), COEF_CONST(0.0056813213) }, { COEF_CONST(0.1565355066), COEF_CONST(0.1473258371), COEF_CONST(0.1330924027), COEF_CONST(0.0963282233), COEF_CONST(0.0594509113), COEF_CONST(0.0081277946), COEF_CONST(0.0081277946), COEF_CONST(0.0081277946) }, { COEF_CONST(0.2184643682), COEF_CONST(0.2064579524), COEF_CONST(0.1876265439), COEF_CONST(0.1375744167), COEF_CONST(0.0856896681), COEF_CONST(0.0117817338), COEF_CONST(0.0117817338), COEF_CONST(0.0117817338) }, { COEF_CONST(0.3015113269), COEF_CONST(0.2870525790), COEF_CONST(0.2637738799), COEF_CONST(0.1984573949), COEF_CONST(0.1260749909), COEF_CONST(0.0175600126), COEF_CONST(0.0175600126), COEF_CONST(0.0175600126) }, { COEF_CONST(0.3698741335), COEF_CONST(0.3547727297), COEF_CONST(0.3298252076), COEF_CONST(0.2556265829), COEF_CONST(0.1665990017), COEF_CONST(0.0236344541), COEF_CONST(0.0236344541), COEF_CONST(0.0236344541) }, { COEF_CONST(0.4480623975), COEF_CONST(0.4339410024), COEF_CONST(0.4098613774), COEF_CONST(0.3322709108), COEF_CONST(0.2266784729), COEF_CONST(0.0334094131), COEF_CONST(0.0334094131), COEF_CONST(0.0334094131) }, { COEF_CONST(0.5336171261), COEF_CONST(0.5226637762), COEF_CONST(0.5033652606), COEF_CONST(0.4349162672), COEF_CONST(0.3224682122), COEF_CONST(0.0521999036), COEF_CONST(0.0521999036), COEF_CONST(0.0521999036) }, { COEF_CONST(0.6219832023), COEF_CONST(0.6161847276), COEF_CONST(0.6057251063), COEF_CONST(0.5654342668), COEF_CONST(0.4826149915), COEF_CONST(0.1058044758), COEF_CONST(0.1058044758), COEF_CONST(0.1058044758) }, { COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657), COEF_CONST(0.7071067657) }, { COEF_CONST(0.7830305572), COEF_CONST(0.7876016373), COEF_CONST(0.7956739618), COEF_CONST(0.8247933372), COEF_CONST(0.8758325942), COEF_CONST(0.9943869542), COEF_CONST(0.9943869542), COEF_CONST(0.9943869542) }, { COEF_CONST(0.8457261833), COEF_CONST(0.8525388778), COEF_CONST(0.8640737401), COEF_CONST(0.9004708933), COEF_CONST(0.9465802987), COEF_CONST(0.9986366532), COEF_CONST(0.9986366532), COEF_CONST(0.9986366532) }, { COEF_CONST(0.8940022267), COEF_CONST(0.9009412572), COEF_CONST(0.9121477564), COEF_CONST(0.9431839770), COEF_CONST(0.9739696219), COEF_CONST(0.9994417480), COEF_CONST(0.9994417480), COEF_CONST(0.9994417480) }, { COEF_CONST(0.9290818561), COEF_CONST(0.9349525662), COEF_CONST(0.9440420138), COEF_CONST(0.9667755833), COEF_CONST(0.9860247275), COEF_CONST(0.9997206664), COEF_CONST(0.9997206664), COEF_CONST(0.9997206664) }, { COEF_CONST(0.9534625907), COEF_CONST(0.9579148236), COEF_CONST(0.9645845234), COEF_CONST(0.9801095128), COEF_CONST(0.9920207064), COEF_CONST(0.9998458099), COEF_CONST(0.9998458099), COEF_CONST(0.9998458099) }, { COEF_CONST(0.9758449068), COEF_CONST(0.9784554646), COEF_CONST(0.9822404252), COEF_CONST(0.9904914275), COEF_CONST(0.9963218730), COEF_CONST(0.9999305926), COEF_CONST(0.9999305926), COEF_CONST(0.9999305926) }, { COEF_CONST(0.9876723320), COEF_CONST(0.9890880155), COEF_CONST(0.9911036356), COEF_CONST(0.9953496173), COEF_CONST(0.9982312259), COEF_CONST(0.9999669685), COEF_CONST(0.9999669685), COEF_CONST(0.9999669685) }, { COEF_CONST(0.9937641889), COEF_CONST(0.9945023501), COEF_CONST(0.9955433130), COEF_CONST(0.9976981117), COEF_CONST(0.9991315558), COEF_CONST(0.9999838610), COEF_CONST(0.9999838610), COEF_CONST(0.9999838610) }, { COEF_CONST(0.9968600642), COEF_CONST(0.9972374385), COEF_CONST(0.9977670024), COEF_CONST(0.9988535464), COEF_CONST(0.9995691924), COEF_CONST(0.9999920129), COEF_CONST(0.9999920129), COEF_CONST(0.9999920129) }, { COEF_CONST(0.9984226014), COEF_CONST(0.9986136287), COEF_CONST(0.9988810254), COEF_CONST(0.9994272242), COEF_CONST(0.9997851906), COEF_CONST(0.9999960221), COEF_CONST(0.9999960221), COEF_CONST(0.9999960221) }, { COEF_CONST(0.9995003746), COEF_CONST(0.9995611974), COEF_CONST(0.9996461891), COEF_CONST(0.9998192657), COEF_CONST(0.9999323103), COEF_CONST(0.9999987475), COEF_CONST(0.9999987475), COEF_CONST(0.9999987475) }, { COEF_CONST(0.9998419236), COEF_CONST(0.9998611991), COEF_CONST(0.9998881193), COEF_CONST(0.9999428861), COEF_CONST(0.9999786185), COEF_CONST(0.9999996045), COEF_CONST(0.9999996045), COEF_CONST(0.9999996045) }, { COEF_CONST(0.9999500038), COEF_CONST(0.9999561034), COEF_CONST(0.9999646206), COEF_CONST(0.9999819429), COEF_CONST(0.9999932409), COEF_CONST(0.9999998750), COEF_CONST(0.9999998750), COEF_CONST(0.9999998750) }, { COEF_CONST(0.9999841890), COEF_CONST(0.9999861183), COEF_CONST(0.9999888121), COEF_CONST(0.9999942902), COEF_CONST(0.9999978628), COEF_CONST(0.9999999605), COEF_CONST(0.9999999605), COEF_CONST(0.9999999605) }, { COEF_CONST(0.9999950000), COEF_CONST(0.9999956102), COEF_CONST(0.9999964621), COEF_CONST(0.9999981945), COEF_CONST(0.9999993242), COEF_CONST(0.9999999875), COEF_CONST(0.9999999875), COEF_CONST(0.9999999875) } }; static const real_t cos_gammas_normal[][8] = { { COEF_CONST(1.0000000000), COEF_CONST(0.9841239707), COEF_CONST(0.9594738226), COEF_CONST(0.8946843024), COEF_CONST(0.8269341029), COEF_CONST(0.7245688486), COEF_CONST(0.7245688486), COEF_CONST(0.7245688486) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9849690570), COEF_CONST(0.9617776789), COEF_CONST(0.9020941550), COEF_CONST(0.8436830391), COEF_CONST(0.7846832804), COEF_CONST(0.7846832804), COEF_CONST(0.7846832804) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9871656089), COEF_CONST(0.9676774734), COEF_CONST(0.9199102884), COEF_CONST(0.8785067015), COEF_CONST(0.8464232214), COEF_CONST(0.8464232214), COEF_CONST(0.8464232214) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9913533967), COEF_CONST(0.9786000177), COEF_CONST(0.9496063381), COEF_CONST(0.9277157252), COEF_CONST(0.9133354077), COEF_CONST(0.9133354077), COEF_CONST(0.9133354077) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9948924435), COEF_CONST(0.9875319180), COEF_CONST(0.9716329849), COEF_CONST(0.9604805241), COEF_CONST(0.9535949574), COEF_CONST(0.9535949574), COEF_CONST(0.9535949574) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9977406278), COEF_CONST(0.9945423840), COEF_CONST(0.9878736667), COEF_CONST(0.9833980494), COEF_CONST(0.9807207440), COEF_CONST(0.9807207440), COEF_CONST(0.9807207440) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9990607067), COEF_CONST(0.9977417734), COEF_CONST(0.9950323970), COEF_CONST(0.9932453273), COEF_CONST(0.9921884740), COEF_CONST(0.9921884740), COEF_CONST(0.9921884740) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9998081748), COEF_CONST(0.9995400312), COEF_CONST(0.9989936459), COEF_CONST(0.9986365356), COEF_CONST(0.9984265591), COEF_CONST(0.9984265591), COEF_CONST(0.9984265591) } }; static const real_t cos_gammas_fine[][8] = { { COEF_CONST(1.0000000000), COEF_CONST(0.9841239707), COEF_CONST(0.9594738226), COEF_CONST(0.8946843024), COEF_CONST(0.8269341029), COEF_CONST(0.7245688486), COEF_CONST(0.7245688486), COEF_CONST(0.7245688486) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9849690570), COEF_CONST(0.9617776789), COEF_CONST(0.9020941550), COEF_CONST(0.8436830391), COEF_CONST(0.7846832804), COEF_CONST(0.7846832804), COEF_CONST(0.7846832804) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9871656089), COEF_CONST(0.9676774734), COEF_CONST(0.9199102884), COEF_CONST(0.8785067015), COEF_CONST(0.8464232214), COEF_CONST(0.8464232214), COEF_CONST(0.8464232214) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9899597309), COEF_CONST(0.9750098690), COEF_CONST(0.9402333855), COEF_CONST(0.9129698759), COEF_CONST(0.8943765944), COEF_CONST(0.8943765944), COEF_CONST(0.8943765944) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9926607607), COEF_CONST(0.9819295710), COEF_CONST(0.9580160104), COEF_CONST(0.9404993670), COEF_CONST(0.9293004472), COEF_CONST(0.9293004472), COEF_CONST(0.9293004472) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9948924435), COEF_CONST(0.9875319180), COEF_CONST(0.9716329849), COEF_CONST(0.9604805241), COEF_CONST(0.9535949574), COEF_CONST(0.9535949574), COEF_CONST(0.9535949574) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9972074644), COEF_CONST(0.9932414270), COEF_CONST(0.9849197629), COEF_CONST(0.9792926592), COEF_CONST(0.9759092525), COEF_CONST(0.9759092525), COEF_CONST(0.9759092525) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9985361982), COEF_CONST(0.9964742028), COEF_CONST(0.9922136306), COEF_CONST(0.9893845420), COEF_CONST(0.9877041371), COEF_CONST(0.9877041371), COEF_CONST(0.9877041371) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9992494366), COEF_CONST(0.9981967170), COEF_CONST(0.9960386625), COEF_CONST(0.9946185834), COEF_CONST(0.9937800239), COEF_CONST(0.9937800239), COEF_CONST(0.9937800239) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9996194722), COEF_CONST(0.9990869422), COEF_CONST(0.9979996269), COEF_CONST(0.9972873651), COEF_CONST(0.9968679747), COEF_CONST(0.9968679747), COEF_CONST(0.9968679747) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9998081748), COEF_CONST(0.9995400312), COEF_CONST(0.9989936459), COEF_CONST(0.9986365356), COEF_CONST(0.9984265591), COEF_CONST(0.9984265591), COEF_CONST(0.9984265591) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9999390971), COEF_CONST(0.9998540271), COEF_CONST(0.9996809352), COEF_CONST(0.9995679735), COEF_CONST(0.9995016284), COEF_CONST(0.9995016284), COEF_CONST(0.9995016284) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9999807170), COEF_CONST(0.9999537862), COEF_CONST(0.9998990191), COEF_CONST(0.9998632947), COEF_CONST(0.9998423208), COEF_CONST(0.9998423208), COEF_CONST(0.9998423208) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9999938979), COEF_CONST(0.9999853814), COEF_CONST(0.9999680568), COEF_CONST(0.9999567596), COEF_CONST(0.9999501270), COEF_CONST(0.9999501270), COEF_CONST(0.9999501270) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9999980703), COEF_CONST(0.9999953731), COEF_CONST(0.9999898968), COEF_CONST(0.9999863277), COEF_CONST(0.9999842265), COEF_CONST(0.9999842265), COEF_CONST(0.9999842265) }, { COEF_CONST(1.0000000000), COEF_CONST(0.9999993891), COEF_CONST(0.9999985397), COEF_CONST(0.9999968037), COEF_CONST(0.9999956786), COEF_CONST(0.9999950155), COEF_CONST(0.9999950155), COEF_CONST(0.9999950155) } }; static const real_t sin_gammas_normal[][8] = { { COEF_CONST(0.0000000000), COEF_CONST(0.1774824223), COEF_CONST(0.2817977711), COEF_CONST(0.4466990028), COEF_CONST(0.5622988435), COEF_CONST(0.6892024258), COEF_CONST(0.6892024258), COEF_CONST(0.6892024258) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1727308798), COEF_CONST(0.2738315110), COEF_CONST(0.4315392630), COEF_CONST(0.5368416242), COEF_CONST(0.6198968861), COEF_CONST(0.6198968861), COEF_CONST(0.6198968861) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1596999079), COEF_CONST(0.2521910140), COEF_CONST(0.3921288836), COEF_CONST(0.4777300236), COEF_CONST(0.5325107795), COEF_CONST(0.5325107795), COEF_CONST(0.5325107795) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1312190642), COEF_CONST(0.2057717310), COEF_CONST(0.3134450552), COEF_CONST(0.3732874674), COEF_CONST(0.4072080955), COEF_CONST(0.4072080955), COEF_CONST(0.4072080955) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1009407043), COEF_CONST(0.1574189028), COEF_CONST(0.2364938532), COEF_CONST(0.2783471983), COEF_CONST(0.3010924396), COEF_CONST(0.3010924396), COEF_CONST(0.3010924396) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0671836269), COEF_CONST(0.1043333428), COEF_CONST(0.1552598422), COEF_CONST(0.1814615013), COEF_CONST(0.1954144885), COEF_CONST(0.1954144885), COEF_CONST(0.1954144885) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0433324862), COEF_CONST(0.0671666110), COEF_CONST(0.0995516398), COEF_CONST(0.1160332699), COEF_CONST(0.1247478739), COEF_CONST(0.1247478739), COEF_CONST(0.1247478739) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0195860576), COEF_CONST(0.0303269852), COEF_CONST(0.0448519274), COEF_CONST(0.0522022017), COEF_CONST(0.0560750040), COEF_CONST(0.0560750040), COEF_CONST(0.0560750040) } }; static const real_t sin_gammas_fine[][8] = { { COEF_CONST(0.0000000000), COEF_CONST(0.1774824223), COEF_CONST(0.2817977711), COEF_CONST(0.4466990028), COEF_CONST(0.5622988435), COEF_CONST(0.6892024258), COEF_CONST(0.6892024258), COEF_CONST(0.6892024258) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1727308798), COEF_CONST(0.2738315110), COEF_CONST(0.4315392630), COEF_CONST(0.5368416242), COEF_CONST(0.6198968861), COEF_CONST(0.6198968861), COEF_CONST(0.6198968861) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1596999079), COEF_CONST(0.2521910140), COEF_CONST(0.3921288836), COEF_CONST(0.4777300236), COEF_CONST(0.5325107795), COEF_CONST(0.5325107795), COEF_CONST(0.5325107795) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1413496768), COEF_CONST(0.2221615526), COEF_CONST(0.3405307340), COEF_CONST(0.4080269669), COEF_CONST(0.4473147744), COEF_CONST(0.4473147744), COEF_CONST(0.4473147744) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1209322714), COEF_CONST(0.1892467110), COEF_CONST(0.2867147079), COEF_CONST(0.3397954394), COEF_CONST(0.3693246252), COEF_CONST(0.3693246252), COEF_CONST(0.3693246252) }, { COEF_CONST(0.0000000000), COEF_CONST(0.1009407043), COEF_CONST(0.1574189028), COEF_CONST(0.2364938532), COEF_CONST(0.2783471983), COEF_CONST(0.3010924396), COEF_CONST(0.3010924396), COEF_CONST(0.3010924396) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0746811420), COEF_CONST(0.1160666523), COEF_CONST(0.1730117353), COEF_CONST(0.2024497161), COEF_CONST(0.2181768341), COEF_CONST(0.2181768341), COEF_CONST(0.2181768341) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0540875291), COEF_CONST(0.0838997203), COEF_CONST(0.1245476266), COEF_CONST(0.1453211203), COEF_CONST(0.1563346972), COEF_CONST(0.1563346972), COEF_CONST(0.1563346972) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0387371058), COEF_CONST(0.0600276114), COEF_CONST(0.0889212171), COEF_CONST(0.1036044086), COEF_CONST(0.1113609634), COEF_CONST(0.1113609634), COEF_CONST(0.1113609634) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0275846110), COEF_CONST(0.0427233177), COEF_CONST(0.0632198125), COEF_CONST(0.0736064637), COEF_CONST(0.0790837596), COEF_CONST(0.0790837596), COEF_CONST(0.0790837596) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0195860576), COEF_CONST(0.0303269852), COEF_CONST(0.0448519274), COEF_CONST(0.0522022017), COEF_CONST(0.0560750040), COEF_CONST(0.0560750040), COEF_CONST(0.0560750040) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0110363955), COEF_CONST(0.0170857974), COEF_CONST(0.0252592108), COEF_CONST(0.0293916021), COEF_CONST(0.0315673054), COEF_CONST(0.0315673054), COEF_CONST(0.0315673054) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0062101284), COEF_CONST(0.0096138203), COEF_CONST(0.0142109649), COEF_CONST(0.0165345659), COEF_CONST(0.0177576316), COEF_CONST(0.0177576316), COEF_CONST(0.0177576316) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0034934509), COEF_CONST(0.0054071189), COEF_CONST(0.0079928316), COEF_CONST(0.0092994041), COEF_CONST(0.0099871631), COEF_CONST(0.0099871631), COEF_CONST(0.0099871631) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0019645397), COEF_CONST(0.0030419905), COEF_CONST(0.0044951511), COEF_CONST(0.0052291853), COEF_CONST(0.0056166498), COEF_CONST(0.0056166498), COEF_CONST(0.0056166498) }, { COEF_CONST(0.0000000000), COEF_CONST(0.0011053943), COEF_CONST(0.0017089869), COEF_CONST(0.0025283670), COEF_CONST(0.0029398552), COEF_CONST(0.0031573685), COEF_CONST(0.0031573685), COEF_CONST(0.0031573685) } }; static const real_t sf_iid_normal[] = { COEF_CONST(1.4119827747), COEF_CONST(1.4031381607), COEF_CONST(1.3868767023), COEF_CONST(1.3483997583), COEF_CONST(1.2912493944), COEF_CONST(1.1960374117), COEF_CONST(1.1073724031), COEF_CONST(1.0000000000), COEF_CONST(0.8796171546), COEF_CONST(0.7546485662), COEF_CONST(0.5767799020), COEF_CONST(0.4264014363), COEF_CONST(0.2767182887), COEF_CONST(0.1766446233), COEF_CONST(0.0794016272) }; static const real_t sf_iid_fine[] = { COEF_CONST(1.4142065048), COEF_CONST(1.4141912460), COEF_CONST(1.4141428471), COEF_CONST(1.4139900208), COEF_CONST(1.4135069847), COEF_CONST(1.4119827747), COEF_CONST(1.4097729921), COEF_CONST(1.4053947926), COEF_CONST(1.3967796564), COEF_CONST(1.3800530434), COEF_CONST(1.3483997583), COEF_CONST(1.3139201403), COEF_CONST(1.2643101215), COEF_CONST(1.1960374117), COEF_CONST(1.1073724031), COEF_CONST(1.0000000000), COEF_CONST(0.8796171546), COEF_CONST(0.7546485662), COEF_CONST(0.6336560845), COEF_CONST(0.5230810642), COEF_CONST(0.4264014363), COEF_CONST(0.3089554012), COEF_CONST(0.2213746458), COEF_CONST(0.1576878875), COEF_CONST(0.1119822487), COEF_CONST(0.0794016272), COEF_CONST(0.0446990170), COEF_CONST(0.0251446925), COEF_CONST(0.0141414283), COEF_CONST(0.0079525812), COEF_CONST(0.0044721137) }; #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/rvlc.c0000644000175000017500000003641514647725152015031 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: rvlc.c,v 1.21 2007/11/01 12:33:34 menno Exp $ **/ /* RVLC scalefactor decoding * * RVLC works like this: * 1. Only symmetric huffman codewords are used * 2. Total length of the scalefactor data is stored in the bitsream * 3. Scalefactors are DPCM coded * 4. Next to the starting value for DPCM the ending value is also stored * * With all this it is possible to read the scalefactor data from 2 sides. * If there is a bit error in the scalefactor data it is possible to start * decoding from the other end of the data, to find all but 1 scalefactor. */ #include "common.h" #include "structs.h" #include #include "syntax.h" #include "bits.h" #include "rvlc.h" #ifdef ERROR_RESILIENCE //#define PRINT_RVLC /* static function declarations */ static uint8_t rvlc_decode_sf_forward(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc, uint8_t *is_used); #if 0 static uint8_t rvlc_decode_sf_reverse(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc, uint8_t is_used); #endif static int8_t rvlc_huffman_sf(bitfile *ld_sf, bitfile *ld_esc, int8_t direction); static int8_t rvlc_huffman_esc(bitfile *ld_esc, int8_t direction); uint8_t rvlc_scale_factor_data(ic_stream *ics, bitfile *ld) { uint8_t bits = 9; ics->sf_concealment = faad_get1bit(ld DEBUGVAR(1,149,"rvlc_scale_factor_data(): sf_concealment")); ics->rev_global_gain = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(1,150,"rvlc_scale_factor_data(): rev_global_gain")); if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) bits = 11; /* the number of bits used for the huffman codewords */ ics->length_of_rvlc_sf = (uint16_t)faad_getbits(ld, bits DEBUGVAR(1,151,"rvlc_scale_factor_data(): length_of_rvlc_sf")); if (ics->noise_used) { ics->dpcm_noise_nrg = (uint16_t)faad_getbits(ld, 9 DEBUGVAR(1,152,"rvlc_scale_factor_data(): dpcm_noise_nrg")); ics->length_of_rvlc_sf -= 9; } ics->sf_escapes_present = faad_get1bit(ld DEBUGVAR(1,153,"rvlc_scale_factor_data(): sf_escapes_present")); if (ics->sf_escapes_present) { ics->length_of_rvlc_escapes = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(1,154,"rvlc_scale_factor_data(): length_of_rvlc_escapes")); } if (ics->noise_used) { ics->dpcm_noise_last_position = (uint16_t)faad_getbits(ld, 9 DEBUGVAR(1,155,"rvlc_scale_factor_data(): dpcm_noise_last_position")); } return 0; } uint8_t rvlc_decode_scale_factors(ic_stream *ics, bitfile *ld) { uint8_t result; uint8_t intensity_used = 0; uint8_t *rvlc_sf_buffer = NULL; uint8_t *rvlc_esc_buffer = NULL; bitfile ld_rvlc_sf, ld_rvlc_esc; // bitfile ld_rvlc_sf_rev, ld_rvlc_esc_rev; if (ics->length_of_rvlc_sf > 0) { /* We read length_of_rvlc_sf bits here to put it in a seperate bitfile. */ rvlc_sf_buffer = faad_getbitbuffer(ld, ics->length_of_rvlc_sf DEBUGVAR(1,156,"rvlc_decode_scale_factors(): bitbuffer: length_of_rvlc_sf")); faad_initbits(&ld_rvlc_sf, (void*)rvlc_sf_buffer, bit2byte(ics->length_of_rvlc_sf)); // faad_initbits_rev(&ld_rvlc_sf_rev, (void*)rvlc_sf_buffer, // ics->length_of_rvlc_sf); } if (ics->sf_escapes_present) { /* We read length_of_rvlc_escapes bits here to put it in a seperate bitfile. */ rvlc_esc_buffer = faad_getbitbuffer(ld, ics->length_of_rvlc_escapes DEBUGVAR(1,157,"rvlc_decode_scale_factors(): bitbuffer: length_of_rvlc_escapes")); faad_initbits(&ld_rvlc_esc, (void*)rvlc_esc_buffer, bit2byte(ics->length_of_rvlc_escapes)); // faad_initbits_rev(&ld_rvlc_esc_rev, (void*)rvlc_esc_buffer, // ics->length_of_rvlc_escapes); } /* decode the rvlc scale factors and escapes */ result = rvlc_decode_sf_forward(ics, &ld_rvlc_sf, &ld_rvlc_esc, &intensity_used); // result = rvlc_decode_sf_reverse(ics, &ld_rvlc_sf_rev, // &ld_rvlc_esc_rev, intensity_used); if (rvlc_esc_buffer) faad_free(rvlc_esc_buffer); if (rvlc_sf_buffer) faad_free(rvlc_sf_buffer); if (ics->length_of_rvlc_sf > 0) faad_endbits(&ld_rvlc_sf); if (ics->sf_escapes_present) faad_endbits(&ld_rvlc_esc); return result; } static uint8_t rvlc_decode_sf_forward(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc, uint8_t *intensity_used) { int8_t g, sfb; int8_t t = 0; int8_t error = 0; int8_t noise_pcm_flag = 1; int16_t scale_factor = ics->global_gain; int16_t is_position = 0; int16_t noise_energy = ics->global_gain - 90 - 256; #ifdef PRINT_RVLC printf("\nglobal_gain: %d\n", ics->global_gain); #endif for (g = 0; g < ics->num_window_groups; g++) { for (sfb = 0; sfb < ics->max_sfb; sfb++) { if (error) { ics->scale_factors[g][sfb] = 0; } else { switch (ics->sfb_cb[g][sfb]) { case ZERO_HCB: /* zero book */ ics->scale_factors[g][sfb] = 0; break; case INTENSITY_HCB: /* intensity books */ case INTENSITY_HCB2: *intensity_used = 1; /* decode intensity position */ t = rvlc_huffman_sf(ld_sf, ld_esc, +1); is_position += t; ics->scale_factors[g][sfb] = is_position; break; case NOISE_HCB: /* noise books */ /* decode noise energy */ if (noise_pcm_flag) { int16_t n = ics->dpcm_noise_nrg; noise_pcm_flag = 0; noise_energy += n; } else { t = rvlc_huffman_sf(ld_sf, ld_esc, +1); noise_energy += t; } ics->scale_factors[g][sfb] = noise_energy; break; default: /* spectral books */ /* decode scale factor */ t = rvlc_huffman_sf(ld_sf, ld_esc, +1); scale_factor += t; if (scale_factor < 0) return 4; ics->scale_factors[g][sfb] = scale_factor; break; } #ifdef PRINT_RVLC printf("%3d:%4d%4d\n", sfb, ics->sfb_cb[g][sfb], ics->scale_factors[g][sfb]); #endif if (t == 99) { error = 1; } } } } #ifdef PRINT_RVLC printf("\n\n"); #endif return 0; } #if 0 // not used right now, doesn't work correctly yet static uint8_t rvlc_decode_sf_reverse(ic_stream *ics, bitfile *ld_sf, bitfile *ld_esc, uint8_t intensity_used) { int8_t g, sfb; int8_t t = 0; int8_t error = 0; int8_t noise_pcm_flag = 1, is_pcm_flag = 1, sf_pcm_flag = 1; int16_t scale_factor = ics->rev_global_gain; int16_t is_position = 0; int16_t noise_energy = ics->rev_global_gain; #ifdef PRINT_RVLC printf("\nrev_global_gain: %d\n", ics->rev_global_gain); #endif if (intensity_used) { is_position = rvlc_huffman_sf(ld_sf, ld_esc, -1); #ifdef PRINT_RVLC printf("is_position: %d\n", is_position); #endif } for (g = ics->num_window_groups-1; g >= 0; g--) { for (sfb = ics->max_sfb-1; sfb >= 0; sfb--) { if (error) { ics->scale_factors[g][sfb] = 0; } else { switch (ics->sfb_cb[g][sfb]) { case ZERO_HCB: /* zero book */ ics->scale_factors[g][sfb] = 0; break; case INTENSITY_HCB: /* intensity books */ case INTENSITY_HCB2: if (is_pcm_flag) { is_pcm_flag = 0; ics->scale_factors[g][sfb] = is_position; } else { t = rvlc_huffman_sf(ld_sf, ld_esc, -1); is_position -= t; ics->scale_factors[g][sfb] = (uint8_t)is_position; } break; case NOISE_HCB: /* noise books */ /* decode noise energy */ if (noise_pcm_flag) { noise_pcm_flag = 0; noise_energy = ics->dpcm_noise_last_position; } else { t = rvlc_huffman_sf(ld_sf, ld_esc, -1); noise_energy -= t; } ics->scale_factors[g][sfb] = (uint8_t)noise_energy; break; default: /* spectral books */ if (sf_pcm_flag || (sfb == 0)) { sf_pcm_flag = 0; if (sfb == 0) scale_factor = ics->global_gain; } else { /* decode scale factor */ t = rvlc_huffman_sf(ld_sf, ld_esc, -1); scale_factor -= t; } if (scale_factor < 0) return 4; ics->scale_factors[g][sfb] = (uint8_t)scale_factor; break; } #ifdef PRINT_RVLC printf("%3d:%4d%4d\n", sfb, ics->sfb_cb[g][sfb], ics->scale_factors[g][sfb]); #endif if (t == 99) { error = 1; } } } } #ifdef PRINT_RVLC printf("\n\n"); #endif return 0; } #endif /* index == 99 means not allowed codeword */ static const rvlc_huff_table book_rvlc[] = { /*index length codeword */ { 0, 1, 0 }, /* 0 */ { -1, 3, 5 }, /* 101 */ { 1, 3, 7 }, /* 111 */ { -2, 4, 9 }, /* 1001 */ { -3, 5, 17 }, /* 10001 */ { 2, 5, 27 }, /* 11011 */ { -4, 6, 33 }, /* 100001 */ { 99, 6, 50 }, /* 110010 */ { 3, 6, 51 }, /* 110011 */ { 99, 6, 52 }, /* 110100 */ { -7, 7, 65 }, /* 1000001 */ { 99, 7, 96 }, /* 1100000 */ { 99, 7, 98 }, /* 1100010 */ { 7, 7, 99 }, /* 1100011 */ { 4, 7, 107 }, /* 1101011 */ { -5, 8, 129 }, /* 10000001 */ { 99, 8, 194 }, /* 11000010 */ { 5, 8, 195 }, /* 11000011 */ { 99, 8, 212 }, /* 11010100 */ { 99, 9, 256 }, /* 100000000 */ { -6, 9, 257 }, /* 100000001 */ { 99, 9, 426 }, /* 110101010 */ { 6, 9, 427 }, /* 110101011 */ { 99, 10, 0 } /* Shouldn't come this far */ }; static const rvlc_huff_table book_escape[] = { /*index length codeword */ { 1, 2, 0 }, { 0, 2, 2 }, { 3, 3, 2 }, { 2, 3, 6 }, { 4, 4, 14 }, { 7, 5, 13 }, { 6, 5, 15 }, { 5, 5, 31 }, { 11, 6, 24 }, { 10, 6, 25 }, { 9, 6, 29 }, { 8, 6, 61 }, { 13, 7, 56 }, { 12, 7, 120 }, { 15, 8, 114 }, { 14, 8, 242 }, { 17, 9, 230 }, { 16, 9, 486 }, { 19, 10, 463 }, { 18, 10, 974 }, { 22, 11, 925 }, { 20, 11, 1950 }, { 21, 11, 1951 }, { 23, 12, 1848 }, { 25, 13, 3698 }, { 24, 14, 7399 }, { 26, 15, 14797 }, { 49, 19, 236736 }, { 50, 19, 236737 }, { 51, 19, 236738 }, { 52, 19, 236739 }, { 53, 19, 236740 }, { 27, 20, 473482 }, { 28, 20, 473483 }, { 29, 20, 473484 }, { 30, 20, 473485 }, { 31, 20, 473486 }, { 32, 20, 473487 }, { 33, 20, 473488 }, { 34, 20, 473489 }, { 35, 20, 473490 }, { 36, 20, 473491 }, { 37, 20, 473492 }, { 38, 20, 473493 }, { 39, 20, 473494 }, { 40, 20, 473495 }, { 41, 20, 473496 }, { 42, 20, 473497 }, { 43, 20, 473498 }, { 44, 20, 473499 }, { 45, 20, 473500 }, { 46, 20, 473501 }, { 47, 20, 473502 }, { 48, 20, 473503 }, { 99, 21, 0 } /* Shouldn't come this far */ }; static int8_t rvlc_huffman_sf(bitfile *ld_sf, bitfile *ld_esc, int8_t direction) { uint8_t i, j; int8_t index; uint32_t cw; const rvlc_huff_table *h = book_rvlc; i = h->len; if (direction > 0) cw = faad_getbits(ld_sf, i DEBUGVAR(1,0,"")); else cw = faad_getbits_rev(ld_sf, i DEBUGVAR(1,0,"")); while ((cw != h->cw) && (i < 10)) { h++; j = h->len-i; i += j; cw <<= j; if (direction > 0) cw |= faad_getbits(ld_sf, j DEBUGVAR(1,0,"")); else cw |= faad_getbits_rev(ld_sf, j DEBUGVAR(1,0,"")); } index = h->index; if (index == +ESC_VAL) { int8_t esc = rvlc_huffman_esc(ld_esc, direction); if (esc == 99) return 99; index += esc; #ifdef PRINT_RVLC printf("esc: %d - ", esc); #endif } if (index == -ESC_VAL) { int8_t esc = rvlc_huffman_esc(ld_esc, direction); if (esc == 99) return 99; index -= esc; #ifdef PRINT_RVLC printf("esc: %d - ", esc); #endif } return index; } static int8_t rvlc_huffman_esc(bitfile *ld, int8_t direction) { uint8_t i, j; uint32_t cw; const rvlc_huff_table *h = book_escape; i = h->len; if (direction > 0) cw = faad_getbits(ld, i DEBUGVAR(1,0,"")); else cw = faad_getbits_rev(ld, i DEBUGVAR(1,0,"")); while ((cw != h->cw) && (i < 21)) { h++; j = h->len-i; i += j; cw <<= j; if (direction > 0) cw |= faad_getbits(ld, j DEBUGVAR(1,0,"")); else cw |= faad_getbits_rev(ld, j DEBUGVAR(1,0,"")); } return h->index; } #endif xine-lib-1.2/contrib/libfaad/kbd_win.h0000644000175000017500000023520614647725151015503 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: kbd_win.h,v 1.21 2007/11/01 12:33:31 menno Exp $ **/ #ifndef __KBD_WIN_H__ #define __KBD_WIN_H__ #ifdef __cplusplus extern "C" { #endif #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif ALIGN static const real_t kbd_long_1024[] = { FRAC_CONST(0.00029256153896361), FRAC_CONST(0.00042998567353047), FRAC_CONST(0.00054674074589540), FRAC_CONST(0.00065482304299792), FRAC_CONST(0.00075870195068747), FRAC_CONST(0.00086059331713336), FRAC_CONST(0.00096177541439010), FRAC_CONST(0.0010630609410878), FRAC_CONST(0.0011650036308132), FRAC_CONST(0.0012680012194148), FRAC_CONST(0.0013723517232956), FRAC_CONST(0.0014782864109136), FRAC_CONST(0.0015859901976719), FRAC_CONST(0.0016956148252373), FRAC_CONST(0.0018072876903517), FRAC_CONST(0.0019211179405514), FRAC_CONST(0.0020372007924215), FRAC_CONST(0.0021556206591754), FRAC_CONST(0.0022764534599614), FRAC_CONST(0.0023997683540995), FRAC_CONST(0.0025256290631156), FRAC_CONST(0.0026540948920831), FRAC_CONST(0.0027852215281403), FRAC_CONST(0.0029190616715331), FRAC_CONST(0.0030556655443223), FRAC_CONST(0.0031950812943391), FRAC_CONST(0.0033373553240392), FRAC_CONST(0.0034825325586930), FRAC_CONST(0.0036306566699199), FRAC_CONST(0.0037817702604646), FRAC_CONST(0.0039359150179719), FRAC_CONST(0.0040931318437260), FRAC_CONST(0.0042534609610026), FRAC_CONST(0.0044169420066964), FRAC_CONST(0.0045836141091341), FRAC_CONST(0.0047535159544086), FRAC_CONST(0.0049266858431214), FRAC_CONST(0.0051031617390698), FRAC_CONST(0.0052829813111335), FRAC_CONST(0.0054661819693975), FRAC_CONST(0.0056528008963682), FRAC_CONST(0.0058428750739943), FRAC_CONST(0.0060364413070882), FRAC_CONST(0.0062335362436492), FRAC_CONST(0.0064341963925079), FRAC_CONST(0.0066384581386503), FRAC_CONST(0.0068463577565218), FRAC_CONST(0.0070579314215715), FRAC_CONST(0.0072732152202559), FRAC_CONST(0.0074922451586909), FRAC_CONST(0.0077150571701162), FRAC_CONST(0.0079416871213115), FRAC_CONST(0.0081721708180857), FRAC_CONST(0.0084065440099458), FRAC_CONST(0.0086448423940363), FRAC_CONST(0.0088871016184291), FRAC_CONST(0.0091333572848345), FRAC_CONST(0.0093836449507939), FRAC_CONST(0.0096380001314086), FRAC_CONST(0.0098964583006517), FRAC_CONST(0.010159054892306), FRAC_CONST(0.010425825300561), FRAC_CONST(0.010696804880310), FRAC_CONST(0.010972028947167), FRAC_CONST(0.011251532777236), FRAC_CONST(0.011535351606646), FRAC_CONST(0.011823520630897), FRAC_CONST(0.012116075003993), FRAC_CONST(0.012413049837429), FRAC_CONST(0.012714480198999), FRAC_CONST(0.013020401111478), FRAC_CONST(0.013330847551161), FRAC_CONST(0.013645854446288), FRAC_CONST(0.013965456675352), FRAC_CONST(0.014289689065314), FRAC_CONST(0.014618586389712), FRAC_CONST(0.014952183366697), FRAC_CONST(0.015290514656976), FRAC_CONST(0.015633614861688), FRAC_CONST(0.015981518520214), FRAC_CONST(0.016334260107915), FRAC_CONST(0.016691874033817), FRAC_CONST(0.017054394638241), FRAC_CONST(0.017421856190380), FRAC_CONST(0.017794292885832), FRAC_CONST(0.018171738844085), FRAC_CONST(0.018554228105962), FRAC_CONST(0.018941794631032), FRAC_CONST(0.019334472294980), FRAC_CONST(0.019732294886947), FRAC_CONST(0.020135296106839), FRAC_CONST(0.020543509562604), FRAC_CONST(0.020956968767488), FRAC_CONST(0.021375707137257), FRAC_CONST(0.021799757987407), FRAC_CONST(0.022229154530343), FRAC_CONST(0.022663929872540), FRAC_CONST(0.023104117011689), FRAC_CONST(0.023549748833816), FRAC_CONST(0.024000858110398), FRAC_CONST(0.024457477495451), FRAC_CONST(0.024919639522613), FRAC_CONST(0.025387376602207), FRAC_CONST(0.025860721018295), FRAC_CONST(0.026339704925726), FRAC_CONST(0.026824360347160), FRAC_CONST(0.027314719170100), FRAC_CONST(0.027810813143900), FRAC_CONST(0.028312673876775), FRAC_CONST(0.028820332832801), FRAC_CONST(0.029333821328905), FRAC_CONST(0.029853170531859), FRAC_CONST(0.030378411455255), FRAC_CONST(0.030909574956490), FRAC_CONST(0.031446691733739), FRAC_CONST(0.031989792322926), FRAC_CONST(0.032538907094693), FRAC_CONST(0.033094066251369), FRAC_CONST(0.033655299823935), FRAC_CONST(0.034222637668991), FRAC_CONST(0.034796109465717), FRAC_CONST(0.035375744712844), FRAC_CONST(0.035961572725616), FRAC_CONST(0.036553622632758), FRAC_CONST(0.037151923373446), FRAC_CONST(0.037756503694277), FRAC_CONST(0.038367392146243), FRAC_CONST(0.038984617081711), FRAC_CONST(0.039608206651398), FRAC_CONST(0.040238188801359), FRAC_CONST(0.040874591269976), FRAC_CONST(0.041517441584950), FRAC_CONST(0.042166767060301), FRAC_CONST(0.042822594793376), FRAC_CONST(0.043484951661852), FRAC_CONST(0.044153864320760), FRAC_CONST(0.044829359199509), FRAC_CONST(0.045511462498913), FRAC_CONST(0.046200200188234), FRAC_CONST(0.046895598002228), FRAC_CONST(0.047597681438201), FRAC_CONST(0.048306475753074), FRAC_CONST(0.049022005960455), FRAC_CONST(0.049744296827725), FRAC_CONST(0.050473372873129), FRAC_CONST(0.051209258362879), FRAC_CONST(0.051951977308273), FRAC_CONST(0.052701553462813), FRAC_CONST(0.053458010319350), FRAC_CONST(0.054221371107223), FRAC_CONST(0.054991658789428), FRAC_CONST(0.055768896059787), FRAC_CONST(0.056553105340134), FRAC_CONST(0.057344308777513), FRAC_CONST(0.058142528241393), FRAC_CONST(0.058947785320893), FRAC_CONST(0.059760101322019), FRAC_CONST(0.060579497264926), FRAC_CONST(0.061405993881180), FRAC_CONST(0.062239611611049), FRAC_CONST(0.063080370600799), FRAC_CONST(0.063928290700012), FRAC_CONST(0.064783391458919), FRAC_CONST(0.065645692125747), FRAC_CONST(0.066515211644086), FRAC_CONST(0.067391968650269), FRAC_CONST(0.068275981470777), FRAC_CONST(0.069167268119652), FRAC_CONST(0.070065846295935), FRAC_CONST(0.070971733381121), FRAC_CONST(0.071884946436630), FRAC_CONST(0.072805502201299), FRAC_CONST(0.073733417088896), FRAC_CONST(0.074668707185649), FRAC_CONST(0.075611388247794), FRAC_CONST(0.076561475699152), FRAC_CONST(0.077518984628715), FRAC_CONST(0.078483929788261), FRAC_CONST(0.079456325589986), FRAC_CONST(0.080436186104162), FRAC_CONST(0.081423525056808), FRAC_CONST(0.082418355827392), FRAC_CONST(0.083420691446553), FRAC_CONST(0.084430544593841), FRAC_CONST(0.085447927595483), FRAC_CONST(0.086472852422178), FRAC_CONST(0.087505330686900), FRAC_CONST(0.088545373642744), FRAC_CONST(0.089592992180780), FRAC_CONST(0.090648196827937), FRAC_CONST(0.091710997744919), FRAC_CONST(0.092781404724131), FRAC_CONST(0.093859427187640), FRAC_CONST(0.094945074185163), FRAC_CONST(0.096038354392069), FRAC_CONST(0.097139276107423), FRAC_CONST(0.098247847252041), FRAC_CONST(0.099364075366580), FRAC_CONST(0.10048796760965), FRAC_CONST(0.10161953075597), FRAC_CONST(0.10275877119451), FRAC_CONST(0.10390569492671), FRAC_CONST(0.10506030756469), FRAC_CONST(0.10622261432949), FRAC_CONST(0.10739262004941), FRAC_CONST(0.10857032915821), FRAC_CONST(0.10975574569357), FRAC_CONST(0.11094887329534), FRAC_CONST(0.11214971520402), FRAC_CONST(0.11335827425914), FRAC_CONST(0.11457455289772), FRAC_CONST(0.11579855315274), FRAC_CONST(0.11703027665170), FRAC_CONST(0.11826972461510), FRAC_CONST(0.11951689785504), FRAC_CONST(0.12077179677383), FRAC_CONST(0.12203442136263), FRAC_CONST(0.12330477120008), FRAC_CONST(0.12458284545102), FRAC_CONST(0.12586864286523), FRAC_CONST(0.12716216177615), FRAC_CONST(0.12846340009971), FRAC_CONST(0.12977235533312), FRAC_CONST(0.13108902455375), FRAC_CONST(0.13241340441801), FRAC_CONST(0.13374549116025), FRAC_CONST(0.13508528059173), FRAC_CONST(0.13643276809961), FRAC_CONST(0.13778794864595), FRAC_CONST(0.13915081676677), FRAC_CONST(0.14052136657114), FRAC_CONST(0.14189959174027), FRAC_CONST(0.14328548552671), FRAC_CONST(0.14467904075349), FRAC_CONST(0.14608024981336), FRAC_CONST(0.14748910466804), FRAC_CONST(0.14890559684750), FRAC_CONST(0.15032971744929), FRAC_CONST(0.15176145713790), FRAC_CONST(0.15320080614414), FRAC_CONST(0.15464775426459), FRAC_CONST(0.15610229086100), FRAC_CONST(0.15756440485987), FRAC_CONST(0.15903408475193), FRAC_CONST(0.16051131859170), FRAC_CONST(0.16199609399712), FRAC_CONST(0.16348839814917), FRAC_CONST(0.16498821779156), FRAC_CONST(0.16649553923042), FRAC_CONST(0.16801034833404), FRAC_CONST(0.16953263053270), FRAC_CONST(0.17106237081842), FRAC_CONST(0.17259955374484), FRAC_CONST(0.17414416342714), FRAC_CONST(0.17569618354193), FRAC_CONST(0.17725559732720), FRAC_CONST(0.17882238758238), FRAC_CONST(0.18039653666830), FRAC_CONST(0.18197802650733), FRAC_CONST(0.18356683858343), FRAC_CONST(0.18516295394233), FRAC_CONST(0.18676635319174), FRAC_CONST(0.18837701650148), FRAC_CONST(0.18999492360384), FRAC_CONST(0.19162005379380), FRAC_CONST(0.19325238592940), FRAC_CONST(0.19489189843209), FRAC_CONST(0.19653856928714), FRAC_CONST(0.19819237604409), FRAC_CONST(0.19985329581721), FRAC_CONST(0.20152130528605), FRAC_CONST(0.20319638069594), FRAC_CONST(0.20487849785865), FRAC_CONST(0.20656763215298), FRAC_CONST(0.20826375852540), FRAC_CONST(0.20996685149083), FRAC_CONST(0.21167688513330), FRAC_CONST(0.21339383310678), FRAC_CONST(0.21511766863598), FRAC_CONST(0.21684836451719), FRAC_CONST(0.21858589311922), FRAC_CONST(0.22033022638425), FRAC_CONST(0.22208133582887), FRAC_CONST(0.22383919254503), FRAC_CONST(0.22560376720111), FRAC_CONST(0.22737503004300), FRAC_CONST(0.22915295089517), FRAC_CONST(0.23093749916189), FRAC_CONST(0.23272864382838), FRAC_CONST(0.23452635346201), FRAC_CONST(0.23633059621364), FRAC_CONST(0.23814133981883), FRAC_CONST(0.23995855159925), FRAC_CONST(0.24178219846403), FRAC_CONST(0.24361224691114), FRAC_CONST(0.24544866302890), FRAC_CONST(0.24729141249740), FRAC_CONST(0.24914046059007), FRAC_CONST(0.25099577217522), FRAC_CONST(0.25285731171763), FRAC_CONST(0.25472504328019), FRAC_CONST(0.25659893052556), FRAC_CONST(0.25847893671788), FRAC_CONST(0.26036502472451), FRAC_CONST(0.26225715701781), FRAC_CONST(0.26415529567692), FRAC_CONST(0.26605940238966), FRAC_CONST(0.26796943845439), FRAC_CONST(0.26988536478190), FRAC_CONST(0.27180714189742), FRAC_CONST(0.27373472994256), FRAC_CONST(0.27566808867736), FRAC_CONST(0.27760717748238), FRAC_CONST(0.27955195536071), FRAC_CONST(0.28150238094021), FRAC_CONST(0.28345841247557), FRAC_CONST(0.28542000785059), FRAC_CONST(0.28738712458038), FRAC_CONST(0.28935971981364), FRAC_CONST(0.29133775033492), FRAC_CONST(0.29332117256704), FRAC_CONST(0.29530994257338), FRAC_CONST(0.29730401606034), FRAC_CONST(0.29930334837974), FRAC_CONST(0.30130789453132), FRAC_CONST(0.30331760916521), FRAC_CONST(0.30533244658452), FRAC_CONST(0.30735236074785), FRAC_CONST(0.30937730527195), FRAC_CONST(0.31140723343430), FRAC_CONST(0.31344209817583), FRAC_CONST(0.31548185210356), FRAC_CONST(0.31752644749341), FRAC_CONST(0.31957583629288), FRAC_CONST(0.32162997012390), FRAC_CONST(0.32368880028565), FRAC_CONST(0.32575227775738), FRAC_CONST(0.32782035320134), FRAC_CONST(0.32989297696566), FRAC_CONST(0.33197009908736), FRAC_CONST(0.33405166929523), FRAC_CONST(0.33613763701295), FRAC_CONST(0.33822795136203), FRAC_CONST(0.34032256116495), FRAC_CONST(0.34242141494820), FRAC_CONST(0.34452446094547), FRAC_CONST(0.34663164710072), FRAC_CONST(0.34874292107143), FRAC_CONST(0.35085823023181), FRAC_CONST(0.35297752167598), FRAC_CONST(0.35510074222129), FRAC_CONST(0.35722783841160), FRAC_CONST(0.35935875652060), FRAC_CONST(0.36149344255514), FRAC_CONST(0.36363184225864), FRAC_CONST(0.36577390111444), FRAC_CONST(0.36791956434930), FRAC_CONST(0.37006877693676), FRAC_CONST(0.37222148360070), FRAC_CONST(0.37437762881878), FRAC_CONST(0.37653715682603), FRAC_CONST(0.37870001161834), FRAC_CONST(0.38086613695607), FRAC_CONST(0.38303547636766), FRAC_CONST(0.38520797315322), FRAC_CONST(0.38738357038821), FRAC_CONST(0.38956221092708), FRAC_CONST(0.39174383740701), FRAC_CONST(0.39392839225157), FRAC_CONST(0.39611581767449), FRAC_CONST(0.39830605568342), FRAC_CONST(0.40049904808370), FRAC_CONST(0.40269473648218), FRAC_CONST(0.40489306229101), FRAC_CONST(0.40709396673153), FRAC_CONST(0.40929739083810), FRAC_CONST(0.41150327546197), FRAC_CONST(0.41371156127524), FRAC_CONST(0.41592218877472), FRAC_CONST(0.41813509828594), FRAC_CONST(0.42035022996702), FRAC_CONST(0.42256752381274), FRAC_CONST(0.42478691965848), FRAC_CONST(0.42700835718423), FRAC_CONST(0.42923177591866), FRAC_CONST(0.43145711524314), FRAC_CONST(0.43368431439580), FRAC_CONST(0.43591331247564), FRAC_CONST(0.43814404844658), FRAC_CONST(0.44037646114161), FRAC_CONST(0.44261048926688), FRAC_CONST(0.44484607140589), FRAC_CONST(0.44708314602359), FRAC_CONST(0.44932165147057), FRAC_CONST(0.45156152598727), FRAC_CONST(0.45380270770813), FRAC_CONST(0.45604513466581), FRAC_CONST(0.45828874479543), FRAC_CONST(0.46053347593880), FRAC_CONST(0.46277926584861), FRAC_CONST(0.46502605219277), FRAC_CONST(0.46727377255861), FRAC_CONST(0.46952236445718), FRAC_CONST(0.47177176532752), FRAC_CONST(0.47402191254100), FRAC_CONST(0.47627274340557), FRAC_CONST(0.47852419517009), FRAC_CONST(0.48077620502869), FRAC_CONST(0.48302871012505), FRAC_CONST(0.48528164755674), FRAC_CONST(0.48753495437962), FRAC_CONST(0.48978856761212), FRAC_CONST(0.49204242423966), FRAC_CONST(0.49429646121898), FRAC_CONST(0.49655061548250), FRAC_CONST(0.49880482394273), FRAC_CONST(0.50105902349665), FRAC_CONST(0.50331315103004), FRAC_CONST(0.50556714342194), FRAC_CONST(0.50782093754901), FRAC_CONST(0.51007447028990), FRAC_CONST(0.51232767852971), FRAC_CONST(0.51458049916433), FRAC_CONST(0.51683286910489), FRAC_CONST(0.51908472528213), FRAC_CONST(0.52133600465083), FRAC_CONST(0.52358664419420), FRAC_CONST(0.52583658092832), FRAC_CONST(0.52808575190648), FRAC_CONST(0.53033409422367), FRAC_CONST(0.53258154502092), FRAC_CONST(0.53482804148974), FRAC_CONST(0.53707352087652), FRAC_CONST(0.53931792048690), FRAC_CONST(0.54156117769021), FRAC_CONST(0.54380322992385), FRAC_CONST(0.54604401469766), FRAC_CONST(0.54828346959835), FRAC_CONST(0.55052153229384), FRAC_CONST(0.55275814053768), FRAC_CONST(0.55499323217338), FRAC_CONST(0.55722674513883), FRAC_CONST(0.55945861747062), FRAC_CONST(0.56168878730842), FRAC_CONST(0.56391719289930), FRAC_CONST(0.56614377260214), FRAC_CONST(0.56836846489188), FRAC_CONST(0.57059120836390), FRAC_CONST(0.57281194173835), FRAC_CONST(0.57503060386439), FRAC_CONST(0.57724713372458), FRAC_CONST(0.57946147043912), FRAC_CONST(0.58167355327012), FRAC_CONST(0.58388332162591), FRAC_CONST(0.58609071506528), FRAC_CONST(0.58829567330173), FRAC_CONST(0.59049813620770), FRAC_CONST(0.59269804381879), FRAC_CONST(0.59489533633802), FRAC_CONST(0.59708995413996), FRAC_CONST(0.59928183777495), FRAC_CONST(0.60147092797329), FRAC_CONST(0.60365716564937), FRAC_CONST(0.60584049190582), FRAC_CONST(0.60802084803764), FRAC_CONST(0.61019817553632), FRAC_CONST(0.61237241609393), FRAC_CONST(0.61454351160718), FRAC_CONST(0.61671140418155), FRAC_CONST(0.61887603613527), FRAC_CONST(0.62103735000336), FRAC_CONST(0.62319528854167), FRAC_CONST(0.62534979473088), FRAC_CONST(0.62750081178042), FRAC_CONST(0.62964828313250), FRAC_CONST(0.63179215246597), FRAC_CONST(0.63393236370030), FRAC_CONST(0.63606886099946), FRAC_CONST(0.63820158877577), FRAC_CONST(0.64033049169379), FRAC_CONST(0.64245551467413), FRAC_CONST(0.64457660289729), FRAC_CONST(0.64669370180740), FRAC_CONST(0.64880675711607), FRAC_CONST(0.65091571480603), FRAC_CONST(0.65302052113494), FRAC_CONST(0.65512112263906), FRAC_CONST(0.65721746613689), FRAC_CONST(0.65930949873289), FRAC_CONST(0.66139716782102), FRAC_CONST(0.66348042108842), FRAC_CONST(0.66555920651892), FRAC_CONST(0.66763347239664), FRAC_CONST(0.66970316730947), FRAC_CONST(0.67176824015260), FRAC_CONST(0.67382864013196), FRAC_CONST(0.67588431676768), FRAC_CONST(0.67793521989751), FRAC_CONST(0.67998129968017), FRAC_CONST(0.68202250659876), FRAC_CONST(0.68405879146403), FRAC_CONST(0.68609010541774), FRAC_CONST(0.68811639993588), FRAC_CONST(0.69013762683195), FRAC_CONST(0.69215373826012), FRAC_CONST(0.69416468671849), FRAC_CONST(0.69617042505214), FRAC_CONST(0.69817090645634), FRAC_CONST(0.70016608447958), FRAC_CONST(0.70215591302664), FRAC_CONST(0.70414034636163), FRAC_CONST(0.70611933911096), FRAC_CONST(0.70809284626630), FRAC_CONST(0.71006082318751), FRAC_CONST(0.71202322560554), FRAC_CONST(0.71398000962530), FRAC_CONST(0.71593113172842), FRAC_CONST(0.71787654877613), FRAC_CONST(0.71981621801195), FRAC_CONST(0.72175009706445), FRAC_CONST(0.72367814394990), FRAC_CONST(0.72560031707496), FRAC_CONST(0.72751657523927), FRAC_CONST(0.72942687763803), FRAC_CONST(0.73133118386457), FRAC_CONST(0.73322945391280), FRAC_CONST(0.73512164817975), FRAC_CONST(0.73700772746796), FRAC_CONST(0.73888765298787), FRAC_CONST(0.74076138636020), FRAC_CONST(0.74262888961827), FRAC_CONST(0.74449012521027), FRAC_CONST(0.74634505600152), FRAC_CONST(0.74819364527663), FRAC_CONST(0.75003585674175), FRAC_CONST(0.75187165452661), FRAC_CONST(0.75370100318668), FRAC_CONST(0.75552386770515), FRAC_CONST(0.75734021349500), FRAC_CONST(0.75915000640095), FRAC_CONST(0.76095321270137), FRAC_CONST(0.76274979911019), FRAC_CONST(0.76453973277875), FRAC_CONST(0.76632298129757), FRAC_CONST(0.76809951269819), FRAC_CONST(0.76986929545481), FRAC_CONST(0.77163229848604), FRAC_CONST(0.77338849115651), FRAC_CONST(0.77513784327849), FRAC_CONST(0.77688032511340), FRAC_CONST(0.77861590737340), FRAC_CONST(0.78034456122283), FRAC_CONST(0.78206625827961), FRAC_CONST(0.78378097061667), FRAC_CONST(0.78548867076330), FRAC_CONST(0.78718933170643), FRAC_CONST(0.78888292689189), FRAC_CONST(0.79056943022564), FRAC_CONST(0.79224881607494), FRAC_CONST(0.79392105926949), FRAC_CONST(0.79558613510249), FRAC_CONST(0.79724401933170), FRAC_CONST(0.79889468818046), FRAC_CONST(0.80053811833858), FRAC_CONST(0.80217428696334), FRAC_CONST(0.80380317168028), FRAC_CONST(0.80542475058405), FRAC_CONST(0.80703900223920), FRAC_CONST(0.80864590568089), FRAC_CONST(0.81024544041560), FRAC_CONST(0.81183758642175), FRAC_CONST(0.81342232415032), FRAC_CONST(0.81499963452540), FRAC_CONST(0.81656949894467), FRAC_CONST(0.81813189927991), FRAC_CONST(0.81968681787738), FRAC_CONST(0.82123423755821), FRAC_CONST(0.82277414161874), FRAC_CONST(0.82430651383076), FRAC_CONST(0.82583133844180), FRAC_CONST(0.82734860017528), FRAC_CONST(0.82885828423070), FRAC_CONST(0.83036037628369), FRAC_CONST(0.83185486248609), FRAC_CONST(0.83334172946597), FRAC_CONST(0.83482096432759), FRAC_CONST(0.83629255465130), FRAC_CONST(0.83775648849344), FRAC_CONST(0.83921275438615), FRAC_CONST(0.84066134133716), FRAC_CONST(0.84210223882952), FRAC_CONST(0.84353543682130), FRAC_CONST(0.84496092574524), FRAC_CONST(0.84637869650833), FRAC_CONST(0.84778874049138), FRAC_CONST(0.84919104954855), FRAC_CONST(0.85058561600677), FRAC_CONST(0.85197243266520), FRAC_CONST(0.85335149279457), FRAC_CONST(0.85472279013653), FRAC_CONST(0.85608631890295), FRAC_CONST(0.85744207377513), FRAC_CONST(0.85879004990298), FRAC_CONST(0.86013024290422), FRAC_CONST(0.86146264886346), FRAC_CONST(0.86278726433124), FRAC_CONST(0.86410408632306), FRAC_CONST(0.86541311231838), FRAC_CONST(0.86671434025950), FRAC_CONST(0.86800776855046), FRAC_CONST(0.86929339605590), FRAC_CONST(0.87057122209981), FRAC_CONST(0.87184124646433), FRAC_CONST(0.87310346938840), FRAC_CONST(0.87435789156650), FRAC_CONST(0.87560451414719), FRAC_CONST(0.87684333873173), FRAC_CONST(0.87807436737261), FRAC_CONST(0.87929760257204), FRAC_CONST(0.88051304728038), FRAC_CONST(0.88172070489456), FRAC_CONST(0.88292057925645), FRAC_CONST(0.88411267465117), FRAC_CONST(0.88529699580537), FRAC_CONST(0.88647354788545), FRAC_CONST(0.88764233649580), FRAC_CONST(0.88880336767692), FRAC_CONST(0.88995664790351), FRAC_CONST(0.89110218408260), FRAC_CONST(0.89223998355154), FRAC_CONST(0.89337005407600), FRAC_CONST(0.89449240384793), FRAC_CONST(0.89560704148345), FRAC_CONST(0.89671397602074), FRAC_CONST(0.89781321691786), FRAC_CONST(0.89890477405053), FRAC_CONST(0.89998865770993), FRAC_CONST(0.90106487860034), FRAC_CONST(0.90213344783689), FRAC_CONST(0.90319437694315), FRAC_CONST(0.90424767784873), FRAC_CONST(0.90529336288690), FRAC_CONST(0.90633144479201), FRAC_CONST(0.90736193669708), FRAC_CONST(0.90838485213119), FRAC_CONST(0.90940020501694), FRAC_CONST(0.91040800966776), FRAC_CONST(0.91140828078533), FRAC_CONST(0.91240103345685), FRAC_CONST(0.91338628315231), FRAC_CONST(0.91436404572173), FRAC_CONST(0.91533433739238), FRAC_CONST(0.91629717476594), FRAC_CONST(0.91725257481564), FRAC_CONST(0.91820055488334), FRAC_CONST(0.91914113267664), FRAC_CONST(0.92007432626589), FRAC_CONST(0.92100015408120), FRAC_CONST(0.92191863490944), FRAC_CONST(0.92282978789113), FRAC_CONST(0.92373363251740), FRAC_CONST(0.92463018862687), FRAC_CONST(0.92551947640245), FRAC_CONST(0.92640151636824), FRAC_CONST(0.92727632938624), FRAC_CONST(0.92814393665320), FRAC_CONST(0.92900435969727), FRAC_CONST(0.92985762037477), FRAC_CONST(0.93070374086684), FRAC_CONST(0.93154274367610), FRAC_CONST(0.93237465162328), FRAC_CONST(0.93319948784382), FRAC_CONST(0.93401727578443), FRAC_CONST(0.93482803919967), FRAC_CONST(0.93563180214841), FRAC_CONST(0.93642858899043), FRAC_CONST(0.93721842438279), FRAC_CONST(0.93800133327637), FRAC_CONST(0.93877734091223), FRAC_CONST(0.93954647281807), FRAC_CONST(0.94030875480458), FRAC_CONST(0.94106421296182), FRAC_CONST(0.94181287365556), FRAC_CONST(0.94255476352362), FRAC_CONST(0.94328990947213), FRAC_CONST(0.94401833867184), FRAC_CONST(0.94474007855439), FRAC_CONST(0.94545515680855), FRAC_CONST(0.94616360137644), FRAC_CONST(0.94686544044975), FRAC_CONST(0.94756070246592), FRAC_CONST(0.94824941610434), FRAC_CONST(0.94893161028248), FRAC_CONST(0.94960731415209), FRAC_CONST(0.95027655709525), FRAC_CONST(0.95093936872056), FRAC_CONST(0.95159577885924), FRAC_CONST(0.95224581756115), FRAC_CONST(0.95288951509097), FRAC_CONST(0.95352690192417), FRAC_CONST(0.95415800874314), FRAC_CONST(0.95478286643320), FRAC_CONST(0.95540150607863), FRAC_CONST(0.95601395895871), FRAC_CONST(0.95662025654373), FRAC_CONST(0.95722043049100), FRAC_CONST(0.95781451264084), FRAC_CONST(0.95840253501260), FRAC_CONST(0.95898452980058), FRAC_CONST(0.95956052937008), FRAC_CONST(0.96013056625336), FRAC_CONST(0.96069467314557), FRAC_CONST(0.96125288290073), FRAC_CONST(0.96180522852773), FRAC_CONST(0.96235174318622), FRAC_CONST(0.96289246018262), FRAC_CONST(0.96342741296604), FRAC_CONST(0.96395663512424), FRAC_CONST(0.96448016037959), FRAC_CONST(0.96499802258499), FRAC_CONST(0.96551025571985), FRAC_CONST(0.96601689388602), FRAC_CONST(0.96651797130376), FRAC_CONST(0.96701352230768), FRAC_CONST(0.96750358134269), FRAC_CONST(0.96798818295998), FRAC_CONST(0.96846736181297), FRAC_CONST(0.96894115265327), FRAC_CONST(0.96940959032667), FRAC_CONST(0.96987270976912), FRAC_CONST(0.97033054600270), FRAC_CONST(0.97078313413161), FRAC_CONST(0.97123050933818), FRAC_CONST(0.97167270687887), FRAC_CONST(0.97210976208030), FRAC_CONST(0.97254171033525), FRAC_CONST(0.97296858709871), FRAC_CONST(0.97339042788392), FRAC_CONST(0.97380726825843), FRAC_CONST(0.97421914384017), FRAC_CONST(0.97462609029350), FRAC_CONST(0.97502814332534), FRAC_CONST(0.97542533868127), FRAC_CONST(0.97581771214160), FRAC_CONST(0.97620529951759), FRAC_CONST(0.97658813664749), FRAC_CONST(0.97696625939282), FRAC_CONST(0.97733970363445), FRAC_CONST(0.97770850526884), FRAC_CONST(0.97807270020427), FRAC_CONST(0.97843232435704), FRAC_CONST(0.97878741364771), FRAC_CONST(0.97913800399743), FRAC_CONST(0.97948413132414), FRAC_CONST(0.97982583153895), FRAC_CONST(0.98016314054243), FRAC_CONST(0.98049609422096), FRAC_CONST(0.98082472844313), FRAC_CONST(0.98114907905608), FRAC_CONST(0.98146918188197), FRAC_CONST(0.98178507271438), FRAC_CONST(0.98209678731477), FRAC_CONST(0.98240436140902), FRAC_CONST(0.98270783068385), FRAC_CONST(0.98300723078342), FRAC_CONST(0.98330259730589), FRAC_CONST(0.98359396579995), FRAC_CONST(0.98388137176152), FRAC_CONST(0.98416485063031), FRAC_CONST(0.98444443778651), FRAC_CONST(0.98472016854752), FRAC_CONST(0.98499207816463), FRAC_CONST(0.98526020181980), FRAC_CONST(0.98552457462240), FRAC_CONST(0.98578523160609), FRAC_CONST(0.98604220772560), FRAC_CONST(0.98629553785362), FRAC_CONST(0.98654525677772), FRAC_CONST(0.98679139919726), FRAC_CONST(0.98703399972035), FRAC_CONST(0.98727309286089), FRAC_CONST(0.98750871303556), FRAC_CONST(0.98774089456089), FRAC_CONST(0.98796967165036), FRAC_CONST(0.98819507841154), FRAC_CONST(0.98841714884323), FRAC_CONST(0.98863591683269), FRAC_CONST(0.98885141615285), FRAC_CONST(0.98906368045957), FRAC_CONST(0.98927274328896), FRAC_CONST(0.98947863805473), FRAC_CONST(0.98968139804554), FRAC_CONST(0.98988105642241), FRAC_CONST(0.99007764621618), FRAC_CONST(0.99027120032501), FRAC_CONST(0.99046175151186), FRAC_CONST(0.99064933240208), FRAC_CONST(0.99083397548099), FRAC_CONST(0.99101571309153), FRAC_CONST(0.99119457743191), FRAC_CONST(0.99137060055337), FRAC_CONST(0.99154381435784), FRAC_CONST(0.99171425059582), FRAC_CONST(0.99188194086414), FRAC_CONST(0.99204691660388), FRAC_CONST(0.99220920909823), FRAC_CONST(0.99236884947045), FRAC_CONST(0.99252586868186), FRAC_CONST(0.99268029752989), FRAC_CONST(0.99283216664606), FRAC_CONST(0.99298150649419), FRAC_CONST(0.99312834736847), FRAC_CONST(0.99327271939167), FRAC_CONST(0.99341465251338), FRAC_CONST(0.99355417650825), FRAC_CONST(0.99369132097430), FRAC_CONST(0.99382611533130), FRAC_CONST(0.99395858881910), FRAC_CONST(0.99408877049612), FRAC_CONST(0.99421668923778), FRAC_CONST(0.99434237373503), FRAC_CONST(0.99446585249289), FRAC_CONST(0.99458715382906), FRAC_CONST(0.99470630587254), FRAC_CONST(0.99482333656229), FRAC_CONST(0.99493827364600), FRAC_CONST(0.99505114467878), FRAC_CONST(0.99516197702200), FRAC_CONST(0.99527079784214), FRAC_CONST(0.99537763410962), FRAC_CONST(0.99548251259777), FRAC_CONST(0.99558545988178), FRAC_CONST(0.99568650233767), FRAC_CONST(0.99578566614138), FRAC_CONST(0.99588297726783), FRAC_CONST(0.99597846149005), FRAC_CONST(0.99607214437834), FRAC_CONST(0.99616405129947), FRAC_CONST(0.99625420741595), FRAC_CONST(0.99634263768527), FRAC_CONST(0.99642936685928), FRAC_CONST(0.99651441948352), FRAC_CONST(0.99659781989663), FRAC_CONST(0.99667959222978), FRAC_CONST(0.99675976040620), FRAC_CONST(0.99683834814063), FRAC_CONST(0.99691537893895), FRAC_CONST(0.99699087609774), FRAC_CONST(0.99706486270391), FRAC_CONST(0.99713736163442), FRAC_CONST(0.99720839555593), FRAC_CONST(0.99727798692461), FRAC_CONST(0.99734615798589), FRAC_CONST(0.99741293077431), FRAC_CONST(0.99747832711337), FRAC_CONST(0.99754236861541), FRAC_CONST(0.99760507668158), FRAC_CONST(0.99766647250181), FRAC_CONST(0.99772657705478), FRAC_CONST(0.99778541110799), FRAC_CONST(0.99784299521785), FRAC_CONST(0.99789934972976), FRAC_CONST(0.99795449477828), FRAC_CONST(0.99800845028730), FRAC_CONST(0.99806123597027), FRAC_CONST(0.99811287133042), FRAC_CONST(0.99816337566108), FRAC_CONST(0.99821276804596), FRAC_CONST(0.99826106735952), FRAC_CONST(0.99830829226732), FRAC_CONST(0.99835446122649), FRAC_CONST(0.99839959248609), FRAC_CONST(0.99844370408765), FRAC_CONST(0.99848681386566), FRAC_CONST(0.99852893944805), FRAC_CONST(0.99857009825685), FRAC_CONST(0.99861030750869), FRAC_CONST(0.99864958421549), FRAC_CONST(0.99868794518504), FRAC_CONST(0.99872540702178), FRAC_CONST(0.99876198612738), FRAC_CONST(0.99879769870160), FRAC_CONST(0.99883256074295), FRAC_CONST(0.99886658804953), FRAC_CONST(0.99889979621983), FRAC_CONST(0.99893220065356), FRAC_CONST(0.99896381655254), FRAC_CONST(0.99899465892154), FRAC_CONST(0.99902474256924), FRAC_CONST(0.99905408210916), FRAC_CONST(0.99908269196056), FRAC_CONST(0.99911058634952), FRAC_CONST(0.99913777930986), FRAC_CONST(0.99916428468421), FRAC_CONST(0.99919011612505), FRAC_CONST(0.99921528709576), FRAC_CONST(0.99923981087174), FRAC_CONST(0.99926370054150), FRAC_CONST(0.99928696900779), FRAC_CONST(0.99930962898876), FRAC_CONST(0.99933169301910), FRAC_CONST(0.99935317345126), FRAC_CONST(0.99937408245662), FRAC_CONST(0.99939443202674), FRAC_CONST(0.99941423397457), FRAC_CONST(0.99943349993572), FRAC_CONST(0.99945224136972), FRAC_CONST(0.99947046956130), FRAC_CONST(0.99948819562171), FRAC_CONST(0.99950543049000), FRAC_CONST(0.99952218493439), FRAC_CONST(0.99953846955355), FRAC_CONST(0.99955429477803), FRAC_CONST(0.99956967087154), FRAC_CONST(0.99958460793242), FRAC_CONST(0.99959911589494), FRAC_CONST(0.99961320453077), FRAC_CONST(0.99962688345035), FRAC_CONST(0.99964016210433), FRAC_CONST(0.99965304978499), FRAC_CONST(0.99966555562769), FRAC_CONST(0.99967768861231), FRAC_CONST(0.99968945756473), FRAC_CONST(0.99970087115825), FRAC_CONST(0.99971193791510), FRAC_CONST(0.99972266620792), FRAC_CONST(0.99973306426121), FRAC_CONST(0.99974314015288), FRAC_CONST(0.99975290181568), FRAC_CONST(0.99976235703876), FRAC_CONST(0.99977151346914), FRAC_CONST(0.99978037861326), FRAC_CONST(0.99978895983845), FRAC_CONST(0.99979726437448), FRAC_CONST(0.99980529931507), FRAC_CONST(0.99981307161943), FRAC_CONST(0.99982058811377), FRAC_CONST(0.99982785549283), FRAC_CONST(0.99983488032144), FRAC_CONST(0.99984166903600), FRAC_CONST(0.99984822794606), FRAC_CONST(0.99985456323584), FRAC_CONST(0.99986068096572), FRAC_CONST(0.99986658707386), FRAC_CONST(0.99987228737764), FRAC_CONST(0.99987778757524), FRAC_CONST(0.99988309324717), FRAC_CONST(0.99988820985777), FRAC_CONST(0.99989314275675), FRAC_CONST(0.99989789718072), FRAC_CONST(0.99990247825468), FRAC_CONST(0.99990689099357), FRAC_CONST(0.99991114030376), FRAC_CONST(0.99991523098456), FRAC_CONST(0.99991916772971), FRAC_CONST(0.99992295512891), FRAC_CONST(0.99992659766930), FRAC_CONST(0.99993009973692), FRAC_CONST(0.99993346561824), FRAC_CONST(0.99993669950161), FRAC_CONST(0.99993980547870), FRAC_CONST(0.99994278754604), FRAC_CONST(0.99994564960642), FRAC_CONST(0.99994839547033), FRAC_CONST(0.99995102885747), FRAC_CONST(0.99995355339809), FRAC_CONST(0.99995597263451), FRAC_CONST(0.99995829002249), FRAC_CONST(0.99996050893264), FRAC_CONST(0.99996263265183), FRAC_CONST(0.99996466438460), FRAC_CONST(0.99996660725452), FRAC_CONST(0.99996846430558), FRAC_CONST(0.99997023850356), FRAC_CONST(0.99997193273736), FRAC_CONST(0.99997354982037), FRAC_CONST(0.99997509249183), FRAC_CONST(0.99997656341810), FRAC_CONST(0.99997796519400), FRAC_CONST(0.99997930034415), FRAC_CONST(0.99998057132421), FRAC_CONST(0.99998178052220), FRAC_CONST(0.99998293025975), FRAC_CONST(0.99998402279338), FRAC_CONST(0.99998506031574), FRAC_CONST(0.99998604495686), FRAC_CONST(0.99998697878536), FRAC_CONST(0.99998786380966), FRAC_CONST(0.99998870197921), FRAC_CONST(0.99998949518567), FRAC_CONST(0.99999024526408), FRAC_CONST(0.99999095399401), FRAC_CONST(0.99999162310077), FRAC_CONST(0.99999225425649), FRAC_CONST(0.99999284908128), FRAC_CONST(0.99999340914435), FRAC_CONST(0.99999393596510), FRAC_CONST(0.99999443101421), FRAC_CONST(0.99999489571473), FRAC_CONST(0.99999533144314), FRAC_CONST(0.99999573953040), FRAC_CONST(0.99999612126300), FRAC_CONST(0.99999647788395), FRAC_CONST(0.99999681059383), FRAC_CONST(0.99999712055178), FRAC_CONST(0.99999740887647), FRAC_CONST(0.99999767664709), FRAC_CONST(0.99999792490431), FRAC_CONST(0.99999815465123), FRAC_CONST(0.99999836685427), FRAC_CONST(0.99999856244415), FRAC_CONST(0.99999874231676), FRAC_CONST(0.99999890733405), FRAC_CONST(0.99999905832493), FRAC_CONST(0.99999919608613), FRAC_CONST(0.99999932138304), FRAC_CONST(0.99999943495056), FRAC_CONST(0.99999953749392), FRAC_CONST(0.99999962968950), FRAC_CONST(0.99999971218563), FRAC_CONST(0.99999978560337), FRAC_CONST(0.99999985053727), FRAC_CONST(0.99999990755616), FRAC_CONST(0.99999995720387) }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const real_t kbd_long_960[] = { FRAC_CONST(0.0003021562530949), FRAC_CONST(0.0004452267024786), FRAC_CONST(0.0005674947527496), FRAC_CONST(0.0006812465553466), FRAC_CONST(0.0007910496776387), FRAC_CONST(0.0008991655033895), FRAC_CONST(0.0010068978259384), FRAC_CONST(0.0011150758515751), FRAC_CONST(0.0012242653193642), FRAC_CONST(0.0013348735658205), FRAC_CONST(0.0014472068670273), FRAC_CONST(0.0015615039850448), FRAC_CONST(0.0016779568885263), FRAC_CONST(0.0017967241232412), FRAC_CONST(0.0019179397560955), FRAC_CONST(0.0020417195415393), FRAC_CONST(0.0021681652836642), FRAC_CONST(0.0022973679910599), FRAC_CONST(0.0024294102029937), FRAC_CONST(0.0025643677339078), FRAC_CONST(0.0027023110014772), FRAC_CONST(0.0028433060512612), FRAC_CONST(0.0029874153568025), FRAC_CONST(0.0031346984511728), FRAC_CONST(0.0032852124303662), FRAC_CONST(0.0034390123581190), FRAC_CONST(0.0035961515940931), FRAC_CONST(0.0037566820618961), FRAC_CONST(0.0039206544694386), FRAC_CONST(0.0040881184912194), FRAC_CONST(0.0042591229199617), FRAC_CONST(0.0044337157933972), FRAC_CONST(0.0046119445007641), FRAC_CONST(0.0047938558726415), FRAC_CONST(0.0049794962570131), FRAC_CONST(0.0051689115838900), FRAC_CONST(0.0053621474203763), FRAC_CONST(0.0055592490177131), FRAC_CONST(0.0057602613515573), FRAC_CONST(0.0059652291565289), FRAC_CONST(0.0061741969558843), FRAC_CONST(0.0063872090870253), FRAC_CONST(0.0066043097234387), FRAC_CONST(0.0068255428935640), FRAC_CONST(0.0070509524970088), FRAC_CONST(0.0072805823184660), FRAC_CONST(0.0075144760396340), FRAC_CONST(0.0077526772493942), FRAC_CONST(0.0079952294524673), FRAC_CONST(0.0082421760767325), FRAC_CONST(0.0084935604793733), FRAC_CONST(0.0087494259519870), FRAC_CONST(0.0090098157247792), FRAC_CONST(0.0092747729699467), FRAC_CONST(0.0095443408043399), FRAC_CONST(0.0098185622914832), FRAC_CONST(0.0100974804430226), FRAC_CONST(0.0103811382196612), FRAC_CONST(0.0106695785316351), FRAC_CONST(0.0109628442387771), FRAC_CONST(0.0112609781502091), FRAC_CONST(0.0115640230236993), FRAC_CONST(0.0118720215647169), FRAC_CONST(0.0121850164252137), FRAC_CONST(0.0125030502021561), FRAC_CONST(0.0128261654358321), FRAC_CONST(0.0131544046079532), FRAC_CONST(0.0134878101395681), FRAC_CONST(0.0138264243888068), FRAC_CONST(0.0141702896484671), FRAC_CONST(0.0145194481434592), FRAC_CONST(0.0148739420281182), FRAC_CONST(0.0152338133833959), FRAC_CONST(0.0155991042139432), FRAC_CONST(0.0159698564450882), FRAC_CONST(0.0163461119197227), FRAC_CONST(0.0167279123950996), FRAC_CONST(0.0171152995395520), FRAC_CONST(0.0175083149291368), FRAC_CONST(0.0179070000442104), FRAC_CONST(0.0183113962659409), FRAC_CONST(0.0187215448727609), FRAC_CONST(0.0191374870367659), FRAC_CONST(0.0195592638200623), FRAC_CONST(0.0199869161710679), FRAC_CONST(0.0204204849207691), FRAC_CONST(0.0208600107789370), FRAC_CONST(0.0213055343303066), FRAC_CONST(0.0217570960307201), FRAC_CONST(0.0222147362032386), FRAC_CONST(0.0226784950342228), FRAC_CONST(0.0231484125693867), FRAC_CONST(0.0236245287098244), FRAC_CONST(0.0241068832080138), FRAC_CONST(0.0245955156637973), FRAC_CONST(0.0250904655203431), FRAC_CONST(0.0255917720600868), FRAC_CONST(0.0260994744006559), FRAC_CONST(0.0266136114907790), FRAC_CONST(0.0271342221061795), FRAC_CONST(0.0276613448454576), FRAC_CONST(0.0281950181259587), FRAC_CONST(0.0287352801796329), FRAC_CONST(0.0292821690488833), FRAC_CONST(0.0298357225824074), FRAC_CONST(0.0303959784310299), FRAC_CONST(0.0309629740435296), FRAC_CONST(0.0315367466624615), FRAC_CONST(0.0321173333199732), FRAC_CONST(0.0327047708336193), FRAC_CONST(0.0332990958021720), FRAC_CONST(0.0339003446014307), FRAC_CONST(0.0345085533800302), FRAC_CONST(0.0351237580552491), FRAC_CONST(0.0357459943088193), FRAC_CONST(0.0363752975827358), FRAC_CONST(0.0370117030750704), FRAC_CONST(0.0376552457357870), FRAC_CONST(0.0383059602625614), FRAC_CONST(0.0389638810966056), FRAC_CONST(0.0396290424184964), FRAC_CONST(0.0403014781440112), FRAC_CONST(0.0409812219199691), FRAC_CONST(0.0416683071200799), FRAC_CONST(0.0423627668408009), FRAC_CONST(0.0430646338972016), FRAC_CONST(0.0437739408188385), FRAC_CONST(0.0444907198456388), FRAC_CONST(0.0452150029237951), FRAC_CONST(0.0459468217016708), FRAC_CONST(0.0466862075257170), FRAC_CONST(0.0474331914364021), FRAC_CONST(0.0481878041641539), FRAC_CONST(0.0489500761253148), FRAC_CONST(0.0497200374181119), FRAC_CONST(0.0504977178186404), FRAC_CONST(0.0512831467768636), FRAC_CONST(0.0520763534126273), FRAC_CONST(0.0528773665116913), FRAC_CONST(0.0536862145217772), FRAC_CONST(0.0545029255486345), FRAC_CONST(0.0553275273521232), FRAC_CONST(0.0561600473423164), FRAC_CONST(0.0570005125756209), FRAC_CONST(0.0578489497509179), FRAC_CONST(0.0587053852057233), FRAC_CONST(0.0595698449123695), FRAC_CONST(0.0604423544742077), FRAC_CONST(0.0613229391218317), FRAC_CONST(0.0622116237093247), FRAC_CONST(0.0631084327105284), FRAC_CONST(0.0640133902153352), FRAC_CONST(0.0649265199260043), FRAC_CONST(0.0658478451535027), FRAC_CONST(0.0667773888138695), FRAC_CONST(0.0677151734246072), FRAC_CONST(0.0686612211010977), FRAC_CONST(0.0696155535530446), FRAC_CONST(0.0705781920809429), FRAC_CONST(0.0715491575725758), FRAC_CONST(0.0725284704995383), FRAC_CONST(0.0735161509137906), FRAC_CONST(0.0745122184442388), FRAC_CONST(0.0755166922933461), FRAC_CONST(0.0765295912337720), FRAC_CONST(0.0775509336050437), FRAC_CONST(0.0785807373102561), FRAC_CONST(0.0796190198128044), FRAC_CONST(0.0806657981331473), FRAC_CONST(0.0817210888456026), FRAC_CONST(0.0827849080751753), FRAC_CONST(0.0838572714944183), FRAC_CONST(0.0849381943203265), FRAC_CONST(0.0860276913112652), FRAC_CONST(0.0871257767639319), FRAC_CONST(0.0882324645103534), FRAC_CONST(0.0893477679149177), FRAC_CONST(0.0904716998714418), FRAC_CONST(0.0916042728002747), FRAC_CONST(0.0927454986454381), FRAC_CONST(0.0938953888718020), FRAC_CONST(0.0950539544622996), FRAC_CONST(0.0962212059151784), FRAC_CONST(0.0973971532412897), FRAC_CONST(0.0985818059614169), FRAC_CONST(0.0997751731036425), FRAC_CONST(0.1009772632007537), FRAC_CONST(0.1021880842876888), FRAC_CONST(0.1034076438990227), FRAC_CONST(0.1046359490664932), FRAC_CONST(0.1058730063165681), FRAC_CONST(0.1071188216680533), FRAC_CONST(0.1083734006297428), FRAC_CONST(0.1096367481981100), FRAC_CONST(0.1109088688550422), FRAC_CONST(0.1121897665656167), FRAC_CONST(0.1134794447759207), FRAC_CONST(0.1147779064109143), FRAC_CONST(0.1160851538723372), FRAC_CONST(0.1174011890366591), FRAC_CONST(0.1187260132530751), FRAC_CONST(0.1200596273415457), FRAC_CONST(0.1214020315908810), FRAC_CONST(0.1227532257568719), FRAC_CONST(0.1241132090604651), FRAC_CONST(0.1254819801859856), FRAC_CONST(0.1268595372794049), FRAC_CONST(0.1282458779466558), FRAC_CONST(0.1296409992519942), FRAC_CONST(0.1310448977164081), FRAC_CONST(0.1324575693160745), FRAC_CONST(0.1338790094808633), FRAC_CONST(0.1353092130928902), FRAC_CONST(0.1367481744851168), FRAC_CONST(0.1381958874400010), FRAC_CONST(0.1396523451881945), FRAC_CONST(0.1411175404072910), FRAC_CONST(0.1425914652206223), FRAC_CONST(0.1440741111961058), FRAC_CONST(0.1455654693451402), FRAC_CONST(0.1470655301215526), FRAC_CONST(0.1485742834205956), FRAC_CONST(0.1500917185779945), FRAC_CONST(0.1516178243690463), FRAC_CONST(0.1531525890077689), FRAC_CONST(0.1546960001461024), FRAC_CONST(0.1562480448731608), FRAC_CONST(0.1578087097145364), FRAC_CONST(0.1593779806316558), FRAC_CONST(0.1609558430211876), FRAC_CONST(0.1625422817145027), FRAC_CONST(0.1641372809771871), FRAC_CONST(0.1657408245086070), FRAC_CONST(0.1673528954415270), FRAC_CONST(0.1689734763417811), FRAC_CONST(0.1706025492079969), FRAC_CONST(0.1722400954713725), FRAC_CONST(0.1738860959955082), FRAC_CONST(0.1755405310762898), FRAC_CONST(0.1772033804418275), FRAC_CONST(0.1788746232524467), FRAC_CONST(0.1805542381007349), FRAC_CONST(0.1822422030116404), FRAC_CONST(0.1839384954426268), FRAC_CONST(0.1856430922838810), FRAC_CONST(0.1873559698585756), FRAC_CONST(0.1890771039231862), FRAC_CONST(0.1908064696678625), FRAC_CONST(0.1925440417168546), FRAC_CONST(0.1942897941289937), FRAC_CONST(0.1960437003982277), FRAC_CONST(0.1978057334542116), FRAC_CONST(0.1995758656629525), FRAC_CONST(0.2013540688275098), FRAC_CONST(0.2031403141887507), FRAC_CONST(0.2049345724261595), FRAC_CONST(0.2067368136587033), FRAC_CONST(0.2085470074457521), FRAC_CONST(0.2103651227880538), FRAC_CONST(0.2121911281287646), FRAC_CONST(0.2140249913545346), FRAC_CONST(0.2158666797966480), FRAC_CONST(0.2177161602322188), FRAC_CONST(0.2195733988854414), FRAC_CONST(0.2214383614288963), FRAC_CONST(0.2233110129849106), FRAC_CONST(0.2251913181269740), FRAC_CONST(0.2270792408812093), FRAC_CONST(0.2289747447278976), FRAC_CONST(0.2308777926030592), FRAC_CONST(0.2327883469000885), FRAC_CONST(0.2347063694714437), FRAC_CONST(0.2366318216303919), FRAC_CONST(0.2385646641528076), FRAC_CONST(0.2405048572790267), FRAC_CONST(0.2424523607157545), FRAC_CONST(0.2444071336380283), FRAC_CONST(0.2463691346912334), FRAC_CONST(0.2483383219931741), FRAC_CONST(0.2503146531361985), FRAC_CONST(0.2522980851893767), FRAC_CONST(0.2542885747007335), FRAC_CONST(0.2562860776995335), FRAC_CONST(0.2582905496986215), FRAC_CONST(0.2603019456968142), FRAC_CONST(0.2623202201813464), FRAC_CONST(0.2643453271303700), FRAC_CONST(0.2663772200155053), FRAC_CONST(0.2684158518044454), FRAC_CONST(0.2704611749636135), FRAC_CONST(0.2725131414608710), FRAC_CONST(0.2745717027682799), FRAC_CONST(0.2766368098649151), FRAC_CONST(0.2787084132397296), FRAC_CONST(0.2807864628944707), FRAC_CONST(0.2828709083466482), FRAC_CONST(0.2849616986325523), FRAC_CONST(0.2870587823103237), FRAC_CONST(0.2891621074630737), FRAC_CONST(0.2912716217020546), FRAC_CONST(0.2933872721698803), FRAC_CONST(0.2955090055437973), FRAC_CONST(0.2976367680390041), FRAC_CONST(0.2997705054120213), FRAC_CONST(0.3019101629641097), FRAC_CONST(0.3040556855447379), FRAC_CONST(0.3062070175550981), FRAC_CONST(0.3083641029516701), FRAC_CONST(0.3105268852498334), FRAC_CONST(0.3126953075275265), FRAC_CONST(0.3148693124289546), FRAC_CONST(0.3170488421683428), FRAC_CONST(0.3192338385337370), FRAC_CONST(0.3214242428908514), FRAC_CONST(0.3236199961869606), FRAC_CONST(0.3258210389548392), FRAC_CONST(0.3280273113167459), FRAC_CONST(0.3302387529884521), FRAC_CONST(0.3324553032833160), FRAC_CONST(0.3346769011164010), FRAC_CONST(0.3369034850086373), FRAC_CONST(0.3391349930910280), FRAC_CONST(0.3413713631088974), FRAC_CONST(0.3436125324261830), FRAC_CONST(0.3458584380297697), FRAC_CONST(0.3481090165338656), FRAC_CONST(0.3503642041844199), FRAC_CONST(0.3526239368635820), FRAC_CONST(0.3548881500942010), FRAC_CONST(0.3571567790443668), FRAC_CONST(0.3594297585319891), FRAC_CONST(0.3617070230294185), FRAC_CONST(0.3639885066681048), FRAC_CONST(0.3662741432432950), FRAC_CONST(0.3685638662187693), FRAC_CONST(0.3708576087316147), FRAC_CONST(0.3731553035970366), FRAC_CONST(0.3754568833132069), FRAC_CONST(0.3777622800661488), FRAC_CONST(0.3800714257346570), FRAC_CONST(0.3823842518952546), FRAC_CONST(0.3847006898271841), FRAC_CONST(0.3870206705174334), FRAC_CONST(0.3893441246657958), FRAC_CONST(0.3916709826899639), FRAC_CONST(0.3940011747306560), FRAC_CONST(0.3963346306567764), FRAC_CONST(0.3986712800706062), FRAC_CONST(0.4010110523130271), FRAC_CONST(0.4033538764687756), FRAC_CONST(0.4056996813717284), FRAC_CONST(0.4080483956102172), FRAC_CONST(0.4103999475323736), FRAC_CONST(0.4127542652515031), FRAC_CONST(0.4151112766514873), FRAC_CONST(0.4174709093922143), FRAC_CONST(0.4198330909150365), FRAC_CONST(0.4221977484482556), FRAC_CONST(0.4245648090126334), FRAC_CONST(0.4269341994269293), FRAC_CONST(0.4293058463134616), FRAC_CONST(0.4316796761036958), FRAC_CONST(0.4340556150438547), FRAC_CONST(0.4364335892005536), FRAC_CONST(0.4388135244664580), FRAC_CONST(0.4411953465659639), FRAC_CONST(0.4435789810609000), FRAC_CONST(0.4459643533562509), FRAC_CONST(0.4483513887059016), FRAC_CONST(0.4507400122184019), FRAC_CONST(0.4531301488627497), FRAC_CONST(0.4555217234741947), FRAC_CONST(0.4579146607600593), FRAC_CONST(0.4603088853055777), FRAC_CONST(0.4627043215797521), FRAC_CONST(0.4651008939412254), FRAC_CONST(0.4674985266441709), FRAC_CONST(0.4698971438441951), FRAC_CONST(0.4722966696042580), FRAC_CONST(0.4746970279006055), FRAC_CONST(0.4770981426287164), FRAC_CONST(0.4794999376092619), FRAC_CONST(0.4819023365940778), FRAC_CONST(0.4843052632721476), FRAC_CONST(0.4867086412755978), FRAC_CONST(0.4891123941857028), FRAC_CONST(0.4915164455388997), FRAC_CONST(0.4939207188328126), FRAC_CONST(0.4963251375322855), FRAC_CONST(0.4987296250754225), FRAC_CONST(0.5011341048796359), FRAC_CONST(0.5035385003477012), FRAC_CONST(0.5059427348738168), FRAC_CONST(0.5083467318496706), FRAC_CONST(0.5107504146705106), FRAC_CONST(0.5131537067412193), FRAC_CONST(0.5155565314823923), FRAC_CONST(0.5179588123364193), FRAC_CONST(0.5203604727735667), FRAC_CONST(0.5227614362980630), FRAC_CONST(0.5251616264541841), FRAC_CONST(0.5275609668323384), FRAC_CONST(0.5299593810751532), FRAC_CONST(0.5323567928835578), FRAC_CONST(0.5347531260228663), FRAC_CONST(0.5371483043288580), FRAC_CONST(0.5395422517138538), FRAC_CONST(0.5419348921727899), FRAC_CONST(0.5443261497892862), FRAC_CONST(0.5467159487417104), FRAC_CONST(0.5491042133092364), FRAC_CONST(0.5514908678778958), FRAC_CONST(0.5538758369466227), FRAC_CONST(0.5562590451332913), FRAC_CONST(0.5586404171807443), FRAC_CONST(0.5610198779628133), FRAC_CONST(0.5633973524903286), FRAC_CONST(0.5657727659171199), FRAC_CONST(0.5681460435460047), FRAC_CONST(0.5705171108347663), FRAC_CONST(0.5728858934021188), FRAC_CONST(0.5752523170336598), FRAC_CONST(0.5776163076878088), FRAC_CONST(0.5799777915017323), FRAC_CONST(0.5823366947972535), FRAC_CONST(0.5846929440867458), FRAC_CONST(0.5870464660790119), FRAC_CONST(0.5893971876851449), FRAC_CONST(0.5917450360243719), FRAC_CONST(0.5940899384298793), FRAC_CONST(0.5964318224546208), FRAC_CONST(0.5987706158771039), FRAC_CONST(0.6011062467071583), FRAC_CONST(0.6034386431916822), FRAC_CONST(0.6057677338203681), FRAC_CONST(0.6080934473314057), FRAC_CONST(0.6104157127171639), FRAC_CONST(0.6127344592298474), FRAC_CONST(0.6150496163871310), FRAC_CONST(0.6173611139777690), FRAC_CONST(0.6196688820671789), FRAC_CONST(0.6219728510029997), FRAC_CONST(0.6242729514206247), FRAC_CONST(0.6265691142487051), FRAC_CONST(0.6288612707146283), FRAC_CONST(0.6311493523499663), FRAC_CONST(0.6334332909958958), FRAC_CONST(0.6357130188085891), FRAC_CONST(0.6379884682645743), FRAC_CONST(0.6402595721660647), FRAC_CONST(0.6425262636462578), FRAC_CONST(0.6447884761746012), FRAC_CONST(0.6470461435620266), FRAC_CONST(0.6492991999661505), FRAC_CONST(0.6515475798964411), FRAC_CONST(0.6537912182193508), FRAC_CONST(0.6560300501634142), FRAC_CONST(0.6582640113243098), FRAC_CONST(0.6604930376698862), FRAC_CONST(0.6627170655451516), FRAC_CONST(0.6649360316772256), FRAC_CONST(0.6671498731802533), FRAC_CONST(0.6693585275602818), FRAC_CONST(0.6715619327200959), FRAC_CONST(0.6737600269640164), FRAC_CONST(0.6759527490026566), FRAC_CONST(0.6781400379576392), FRAC_CONST(0.6803218333662715), FRAC_CONST(0.6824980751861787), FRAC_CONST(0.6846687037998949), FRAC_CONST(0.6868336600194123), FRAC_CONST(0.6889928850906855), FRAC_CONST(0.6911463206980928), FRAC_CONST(0.6932939089688525), FRAC_CONST(0.6954355924773949), FRAC_CONST(0.6975713142496884), FRAC_CONST(0.6997010177675195), FRAC_CONST(0.7018246469727265), FRAC_CONST(0.7039421462713862), FRAC_CONST(0.7060534605379528), FRAC_CONST(0.7081585351193496), FRAC_CONST(0.7102573158390105), FRAC_CONST(0.7123497490008750), FRAC_CONST(0.7144357813933307), FRAC_CONST(0.7165153602931092), FRAC_CONST(0.7185884334691287), FRAC_CONST(0.7206549491862871), FRAC_CONST(0.7227148562092042), FRAC_CONST(0.7247681038059106), FRAC_CONST(0.7268146417514855), FRAC_CONST(0.7288544203316418), FRAC_CONST(0.7308873903462577), FRAC_CONST(0.7329135031128549), FRAC_CONST(0.7349327104700221), FRAC_CONST(0.7369449647807855), FRAC_CONST(0.7389502189359237), FRAC_CONST(0.7409484263572271), FRAC_CONST(0.7429395410007016), FRAC_CONST(0.7449235173597176), FRAC_CONST(0.7469003104681008), FRAC_CONST(0.7488698759031670), FRAC_CONST(0.7508321697887005), FRAC_CONST(0.7527871487978728), FRAC_CONST(0.7547347701561059), FRAC_CONST(0.7566749916438754), FRAC_CONST(0.7586077715994560), FRAC_CONST(0.7605330689216074), FRAC_CONST(0.7624508430722016), FRAC_CONST(0.7643610540787891), FRAC_CONST(0.7662636625371070), FRAC_CONST(0.7681586296135255), FRAC_CONST(0.7700459170474343), FRAC_CONST(0.7719254871535672), FRAC_CONST(0.7737973028242671), FRAC_CONST(0.7756613275316875), FRAC_CONST(0.7775175253299340), FRAC_CONST(0.7793658608571425), FRAC_CONST(0.7812062993374951), FRAC_CONST(0.7830388065831744), FRAC_CONST(0.7848633489962533), FRAC_CONST(0.7866798935705233), FRAC_CONST(0.7884884078932579), FRAC_CONST(0.7902888601469138), FRAC_CONST(0.7920812191107668), FRAC_CONST(0.7938654541624850), FRAC_CONST(0.7956415352796368), FRAC_CONST(0.7974094330411343), FRAC_CONST(0.7991691186286133), FRAC_CONST(0.8009205638277465), FRAC_CONST(0.8026637410294932), FRAC_CONST(0.8043986232312831), FRAC_CONST(0.8061251840381346), FRAC_CONST(0.8078433976637077), FRAC_CONST(0.8095532389312917), FRAC_CONST(0.8112546832747255), FRAC_CONST(0.8129477067392539), FRAC_CONST(0.8146322859823164), FRAC_CONST(0.8163083982742698), FRAC_CONST(0.8179760214990457), FRAC_CONST(0.8196351341547393), FRAC_CONST(0.8212857153541345), FRAC_CONST(0.8229277448251595), FRAC_CONST(0.8245612029112778), FRAC_CONST(0.8261860705718113), FRAC_CONST(0.8278023293821971), FRAC_CONST(0.8294099615341773), FRAC_CONST(0.8310089498359212), FRAC_CONST(0.8325992777120815), FRAC_CONST(0.8341809292037831), FRAC_CONST(0.8357538889685445), FRAC_CONST(0.8373181422801330), FRAC_CONST(0.8388736750283521), FRAC_CONST(0.8404204737187619), FRAC_CONST(0.8419585254723335), FRAC_CONST(0.8434878180250348), FRAC_CONST(0.8450083397273509), FRAC_CONST(0.8465200795437368), FRAC_CONST(0.8480230270520029), FRAC_CONST(0.8495171724426350), FRAC_CONST(0.8510025065180464), FRAC_CONST(0.8524790206917633), FRAC_CONST(0.8539467069875448), FRAC_CONST(0.8554055580384357), FRAC_CONST(0.8568555670857525), FRAC_CONST(0.8582967279780043), FRAC_CONST(0.8597290351697464), FRAC_CONST(0.8611524837203691), FRAC_CONST(0.8625670692928198), FRAC_CONST(0.8639727881522599), FRAC_CONST(0.8653696371646555), FRAC_CONST(0.8667576137953045), FRAC_CONST(0.8681367161072958), FRAC_CONST(0.8695069427599065), FRAC_CONST(0.8708682930069319), FRAC_CONST(0.8722207666949527), FRAC_CONST(0.8735643642615368), FRAC_CONST(0.8748990867333771), FRAC_CONST(0.8762249357243662), FRAC_CONST(0.8775419134336067), FRAC_CONST(0.8788500226433579), FRAC_CONST(0.8801492667169208), FRAC_CONST(0.8814396495964587), FRAC_CONST(0.8827211758007560), FRAC_CONST(0.8839938504229149), FRAC_CONST(0.8852576791279895), FRAC_CONST(0.8865126681505587), FRAC_CONST(0.8877588242922386), FRAC_CONST(0.8889961549191320), FRAC_CONST(0.8902246679592184), FRAC_CONST(0.8914443718996848), FRAC_CONST(0.8926552757841945), FRAC_CONST(0.8938573892100969), FRAC_CONST(0.8950507223255798), FRAC_CONST(0.8962352858267605), FRAC_CONST(0.8974110909547198), FRAC_CONST(0.8985781494924783), FRAC_CONST(0.8997364737619142), FRAC_CONST(0.9008860766206249), FRAC_CONST(0.9020269714587307), FRAC_CONST(0.9031591721956235), FRAC_CONST(0.9042826932766591), FRAC_CONST(0.9053975496697941), FRAC_CONST(0.9065037568621681), FRAC_CONST(0.9076013308566311), FRAC_CONST(0.9086902881682180), FRAC_CONST(0.9097706458205682), FRAC_CONST(0.9108424213422940), FRAC_CONST(0.9119056327632955), FRAC_CONST(0.9129602986110235), FRAC_CONST(0.9140064379066919), FRAC_CONST(0.9150440701614393), FRAC_CONST(0.9160732153724396), FRAC_CONST(0.9170938940189634), FRAC_CONST(0.9181061270583908), FRAC_CONST(0.9191099359221748), FRAC_CONST(0.9201053425117579), FRAC_CONST(0.9210923691944400), FRAC_CONST(0.9220710387992010), FRAC_CONST(0.9230413746124764), FRAC_CONST(0.9240034003738882), FRAC_CONST(0.9249571402719298), FRAC_CONST(0.9259026189396085), FRAC_CONST(0.9268398614500427), FRAC_CONST(0.9277688933120170), FRAC_CONST(0.9286897404654957), FRAC_CONST(0.9296024292770939), FRAC_CONST(0.9305069865355076), FRAC_CONST(0.9314034394469048), FRAC_CONST(0.9322918156302762), FRAC_CONST(0.9331721431127471), FRAC_CONST(0.9340444503248519), FRAC_CONST(0.9349087660957711), FRAC_CONST(0.9357651196485313), FRAC_CONST(0.9366135405951697), FRAC_CONST(0.9374540589318637), FRAC_CONST(0.9382867050340261), FRAC_CONST(0.9391115096513655), FRAC_CONST(0.9399285039029165), FRAC_CONST(0.9407377192720349), FRAC_CONST(0.9415391876013639), FRAC_CONST(0.9423329410877687), FRAC_CONST(0.9431190122772415), FRAC_CONST(0.9438974340597782), FRAC_CONST(0.9446682396642262), FRAC_CONST(0.9454314626531054), FRAC_CONST(0.9461871369174033), FRAC_CONST(0.9469352966713429), FRAC_CONST(0.9476759764471278), FRAC_CONST(0.9484092110896616), FRAC_CONST(0.9491350357512457), FRAC_CONST(0.9498534858862532), FRAC_CONST(0.9505645972457831), FRAC_CONST(0.9512684058722927), FRAC_CONST(0.9519649480942105), FRAC_CONST(0.9526542605205314), FRAC_CONST(0.9533363800353921), FRAC_CONST(0.9540113437926313), FRAC_CONST(0.9546791892103320), FRAC_CONST(0.9553399539653500), FRAC_CONST(0.9559936759878265), FRAC_CONST(0.9566403934556893), FRAC_CONST(0.9572801447891388), FRAC_CONST(0.9579129686451244), FRAC_CONST(0.9585389039118085), FRAC_CONST(0.9591579897030224), FRAC_CONST(0.9597702653527108), FRAC_CONST(0.9603757704093711), FRAC_CONST(0.9609745446304828), FRAC_CONST(0.9615666279769324), FRAC_CONST(0.9621520606074324), FRAC_CONST(0.9627308828729358), FRAC_CONST(0.9633031353110477), FRAC_CONST(0.9638688586404335), FRAC_CONST(0.9644280937552258), FRAC_CONST(0.9649808817194311), FRAC_CONST(0.9655272637613366), FRAC_CONST(0.9660672812679171), FRAC_CONST(0.9666009757792454), FRAC_CONST(0.9671283889829055), FRAC_CONST(0.9676495627084089), FRAC_CONST(0.9681645389216160), FRAC_CONST(0.9686733597191652), FRAC_CONST(0.9691760673229058), FRAC_CONST(0.9696727040743406), FRAC_CONST(0.9701633124290767), FRAC_CONST(0.9706479349512860), FRAC_CONST(0.9711266143081750), FRAC_CONST(0.9715993932644684), FRAC_CONST(0.9720663146769026), FRAC_CONST(0.9725274214887337), FRAC_CONST(0.9729827567242596), FRAC_CONST(0.9734323634833574), FRAC_CONST(0.9738762849360358), FRAC_CONST(0.9743145643170059), FRAC_CONST(0.9747472449202687), FRAC_CONST(0.9751743700937215), FRAC_CONST(0.9755959832337850), FRAC_CONST(0.9760121277800496), FRAC_CONST(0.9764228472099433), FRAC_CONST(0.9768281850334235), FRAC_CONST(0.9772281847876897), FRAC_CONST(0.9776228900319223), FRAC_CONST(0.9780123443420448), FRAC_CONST(0.9783965913055132), FRAC_CONST(0.9787756745161313), FRAC_CONST(0.9791496375688939), FRAC_CONST(0.9795185240548578), FRAC_CONST(0.9798823775560431), FRAC_CONST(0.9802412416403639), FRAC_CONST(0.9805951598565897), FRAC_CONST(0.9809441757293399), FRAC_CONST(0.9812883327541090), FRAC_CONST(0.9816276743923267), FRAC_CONST(0.9819622440664515), FRAC_CONST(0.9822920851550995), FRAC_CONST(0.9826172409882086), FRAC_CONST(0.9829377548422400), FRAC_CONST(0.9832536699354163), FRAC_CONST(0.9835650294229984), FRAC_CONST(0.9838718763926001), FRAC_CONST(0.9841742538595437), FRAC_CONST(0.9844722047622547), FRAC_CONST(0.9847657719576983), FRAC_CONST(0.9850549982168574), FRAC_CONST(0.9853399262202529), FRAC_CONST(0.9856205985535073), FRAC_CONST(0.9858970577029519), FRAC_CONST(0.9861693460512790), FRAC_CONST(0.9864375058732389), FRAC_CONST(0.9867015793313820), FRAC_CONST(0.9869616084718489), FRAC_CONST(0.9872176352202061), FRAC_CONST(0.9874697013773301), FRAC_CONST(0.9877178486153397), FRAC_CONST(0.9879621184735767), FRAC_CONST(0.9882025523546365), FRAC_CONST(0.9884391915204485), FRAC_CONST(0.9886720770884069), FRAC_CONST(0.9889012500275530), FRAC_CONST(0.9891267511548089), FRAC_CONST(0.9893486211312621), FRAC_CONST(0.9895669004585049), FRAC_CONST(0.9897816294750255), FRAC_CONST(0.9899928483526520), FRAC_CONST(0.9902005970930525), FRAC_CONST(0.9904049155242876), FRAC_CONST(0.9906058432974180), FRAC_CONST(0.9908034198831690), FRAC_CONST(0.9909976845686489), FRAC_CONST(0.9911886764541239), FRAC_CONST(0.9913764344498495), FRAC_CONST(0.9915609972729590), FRAC_CONST(0.9917424034444086), FRAC_CONST(0.9919206912859797), FRAC_CONST(0.9920958989173397), FRAC_CONST(0.9922680642531603), FRAC_CONST(0.9924372250002933), FRAC_CONST(0.9926034186550070), FRAC_CONST(0.9927666825002789), FRAC_CONST(0.9929270536031491), FRAC_CONST(0.9930845688121325), FRAC_CONST(0.9932392647546895), FRAC_CONST(0.9933911778347579), FRAC_CONST(0.9935403442303433), FRAC_CONST(0.9936867998911693), FRAC_CONST(0.9938305805363887), FRAC_CONST(0.9939717216523539), FRAC_CONST(0.9941102584904481), FRAC_CONST(0.9942462260649764), FRAC_CONST(0.9943796591511174), FRAC_CONST(0.9945105922829353), FRAC_CONST(0.9946390597514524), FRAC_CONST(0.9947650956027824), FRAC_CONST(0.9948887336363228), FRAC_CONST(0.9950100074030103), FRAC_CONST(0.9951289502036336), FRAC_CONST(0.9952455950872091), FRAC_CONST(0.9953599748494155), FRAC_CONST(0.9954721220310890), FRAC_CONST(0.9955820689167787), FRAC_CONST(0.9956898475333619), FRAC_CONST(0.9957954896487196), FRAC_CONST(0.9958990267704713), FRAC_CONST(0.9960004901447701), FRAC_CONST(0.9960999107551559), FRAC_CONST(0.9961973193214694), FRAC_CONST(0.9962927462988245), FRAC_CONST(0.9963862218766388), FRAC_CONST(0.9964777759777242), FRAC_CONST(0.9965674382574342), FRAC_CONST(0.9966552381028704), FRAC_CONST(0.9967412046321465), FRAC_CONST(0.9968253666937095), FRAC_CONST(0.9969077528657186), FRAC_CONST(0.9969883914554805), FRAC_CONST(0.9970673104989413), FRAC_CONST(0.9971445377602348), FRAC_CONST(0.9972201007312871), FRAC_CONST(0.9972940266314749), FRAC_CONST(0.9973663424073412), FRAC_CONST(0.9974370747323638), FRAC_CONST(0.9975062500067785), FRAC_CONST(0.9975738943574574), FRAC_CONST(0.9976400336378379), FRAC_CONST(0.9977046934279079), FRAC_CONST(0.9977678990342401), FRAC_CONST(0.9978296754900812), FRAC_CONST(0.9978900475554902), FRAC_CONST(0.9979490397175296), FRAC_CONST(0.9980066761905056), FRAC_CONST(0.9980629809162593), FRAC_CONST(0.9981179775645063), FRAC_CONST(0.9981716895332257), FRAC_CONST(0.9982241399490979), FRAC_CONST(0.9982753516679893), FRAC_CONST(0.9983253472754841), FRAC_CONST(0.9983741490874634), FRAC_CONST(0.9984217791507299), FRAC_CONST(0.9984682592436778), FRAC_CONST(0.9985136108770075), FRAC_CONST(0.9985578552944850), FRAC_CONST(0.9986010134737439), FRAC_CONST(0.9986431061271304), FRAC_CONST(0.9986841537025921), FRAC_CONST(0.9987241763846056), FRAC_CONST(0.9987631940951476), FRAC_CONST(0.9988012264947044), FRAC_CONST(0.9988382929833222), FRAC_CONST(0.9988744127016956), FRAC_CONST(0.9989096045322947), FRAC_CONST(0.9989438871005292), FRAC_CONST(0.9989772787759494), FRAC_CONST(0.9990097976734847), FRAC_CONST(0.9990414616547146), FRAC_CONST(0.9990722883291779), FRAC_CONST(0.9991022950557125), FRAC_CONST(0.9991314989438310), FRAC_CONST(0.9991599168551279), FRAC_CONST(0.9991875654047181), FRAC_CONST(0.9992144609627068), FRAC_CONST(0.9992406196556911), FRAC_CONST(0.9992660573682882), FRAC_CONST(0.9992907897446957), FRAC_CONST(0.9993148321902777), FRAC_CONST(0.9993381998731797), FRAC_CONST(0.9993609077259696), FRAC_CONST(0.9993829704473038), FRAC_CONST(0.9994044025036201), FRAC_CONST(0.9994252181308537), FRAC_CONST(0.9994454313361775), FRAC_CONST(0.9994650558997651), FRAC_CONST(0.9994841053765757), FRAC_CONST(0.9995025930981609), FRAC_CONST(0.9995205321744921), FRAC_CONST(0.9995379354958073), FRAC_CONST(0.9995548157344778), FRAC_CONST(0.9995711853468930), FRAC_CONST(0.9995870565753632), FRAC_CONST(0.9996024414500382), FRAC_CONST(0.9996173517908444), FRAC_CONST(0.9996317992094352), FRAC_CONST(0.9996457951111574), FRAC_CONST(0.9996593506970310), FRAC_CONST(0.9996724769657434), FRAC_CONST(0.9996851847156547), FRAC_CONST(0.9996974845468164), FRAC_CONST(0.9997093868630000), FRAC_CONST(0.9997209018737374), FRAC_CONST(0.9997320395963699), FRAC_CONST(0.9997428098581069), FRAC_CONST(0.9997532222980933), FRAC_CONST(0.9997632863694836), FRAC_CONST(0.9997730113415246), FRAC_CONST(0.9997824063016426), FRAC_CONST(0.9997914801575380), FRAC_CONST(0.9998002416392840), FRAC_CONST(0.9998086993014300), FRAC_CONST(0.9998168615251084), FRAC_CONST(0.9998247365201450), FRAC_CONST(0.9998323323271717), FRAC_CONST(0.9998396568197407), FRAC_CONST(0.9998467177064404), FRAC_CONST(0.9998535225330116), FRAC_CONST(0.9998600786844637), FRAC_CONST(0.9998663933871905), FRAC_CONST(0.9998724737110845), FRAC_CONST(0.9998783265716498), FRAC_CONST(0.9998839587321121), FRAC_CONST(0.9998893768055266), FRAC_CONST(0.9998945872568815), FRAC_CONST(0.9998995964051983), FRAC_CONST(0.9999044104256269), FRAC_CONST(0.9999090353515359), FRAC_CONST(0.9999134770765971), FRAC_CONST(0.9999177413568642), FRAC_CONST(0.9999218338128448), FRAC_CONST(0.9999257599315647), FRAC_CONST(0.9999295250686255), FRAC_CONST(0.9999331344502529), FRAC_CONST(0.9999365931753376), FRAC_CONST(0.9999399062174669), FRAC_CONST(0.9999430784269460), FRAC_CONST(0.9999461145328103), FRAC_CONST(0.9999490191448277), FRAC_CONST(0.9999517967554878), FRAC_CONST(0.9999544517419835), FRAC_CONST(0.9999569883681778), FRAC_CONST(0.9999594107865607), FRAC_CONST(0.9999617230401926), FRAC_CONST(0.9999639290646355), FRAC_CONST(0.9999660326898712), FRAC_CONST(0.9999680376422052), FRAC_CONST(0.9999699475461585), FRAC_CONST(0.9999717659263435), FRAC_CONST(0.9999734962093266), FRAC_CONST(0.9999751417254756), FRAC_CONST(0.9999767057107922), FRAC_CONST(0.9999781913087290), FRAC_CONST(0.9999796015719915), FRAC_CONST(0.9999809394643231), FRAC_CONST(0.9999822078622751), FRAC_CONST(0.9999834095569596), FRAC_CONST(0.9999845472557860), FRAC_CONST(0.9999856235841805), FRAC_CONST(0.9999866410872889), FRAC_CONST(0.9999876022316609), FRAC_CONST(0.9999885094069193), FRAC_CONST(0.9999893649274085), FRAC_CONST(0.9999901710338274), FRAC_CONST(0.9999909298948430), FRAC_CONST(0.9999916436086862), FRAC_CONST(0.9999923142047299), FRAC_CONST(0.9999929436450469), FRAC_CONST(0.9999935338259505), FRAC_CONST(0.9999940865795161), FRAC_CONST(0.9999946036750835), FRAC_CONST(0.9999950868207405), FRAC_CONST(0.9999955376647868), FRAC_CONST(0.9999959577971798), FRAC_CONST(0.9999963487509599), FRAC_CONST(0.9999967120036571), FRAC_CONST(0.9999970489786785), FRAC_CONST(0.9999973610466748), FRAC_CONST(0.9999976495268890), FRAC_CONST(0.9999979156884846), FRAC_CONST(0.9999981607518545), FRAC_CONST(0.9999983858899099), FRAC_CONST(0.9999985922293493), FRAC_CONST(0.9999987808519092), FRAC_CONST(0.9999989527955938), FRAC_CONST(0.9999991090558848), FRAC_CONST(0.9999992505869332), FRAC_CONST(0.9999993783027293), FRAC_CONST(0.9999994930782556), FRAC_CONST(0.9999995957506171), FRAC_CONST(0.9999996871201549), FRAC_CONST(0.9999997679515386), FRAC_CONST(0.9999998389748399), FRAC_CONST(0.9999999008865869), FRAC_CONST(0.9999999543507984) }; #endif ALIGN static const real_t kbd_short_128[] = { FRAC_CONST(4.3795702929468881e-005), FRAC_CONST(0.00011867384265436617), FRAC_CONST(0.0002307165763996192), FRAC_CONST(0.00038947282760568383), FRAC_CONST(0.00060581272288302553), FRAC_CONST(0.00089199695169487453), FRAC_CONST(0.0012617254423430522), FRAC_CONST(0.0017301724373162003), FRAC_CONST(0.0023140071937421476), FRAC_CONST(0.0030313989666022221), FRAC_CONST(0.0039020049735530842), FRAC_CONST(0.0049469401815512024), FRAC_CONST(0.0061887279335368318), FRAC_CONST(0.0076512306364647726), FRAC_CONST(0.0093595599562652423), FRAC_CONST(0.011339966208377799), FRAC_CONST(0.013619706891715299), FRAC_CONST(0.016226894586323766), FRAC_CONST(0.019190324717288168), FRAC_CONST(0.022539283975960878), FRAC_CONST(0.026303340480472455), FRAC_CONST(0.030512117046644357), FRAC_CONST(0.03519504922365594), FRAC_CONST(0.040381130021856941), FRAC_CONST(0.046098643518702249), FRAC_CONST(0.052374889768730587), FRAC_CONST(0.059235903660769147), FRAC_CONST(0.066706170556282418), FRAC_CONST(0.074808341703430481), FRAC_CONST(0.083562952548726227), FRAC_CONST(0.092988147159339674), FRAC_CONST(0.1030994120216919), FRAC_CONST(0.11390932249409955), FRAC_CONST(0.12542730516149531), FRAC_CONST(0.13765941926783826), FRAC_CONST(0.15060816028651081), FRAC_CONST(0.16427228853114245), FRAC_CONST(0.17864668550988483), FRAC_CONST(0.19372224048676889), FRAC_CONST(0.20948576943658073), FRAC_CONST(0.22591996826744942), FRAC_CONST(0.24300340184133981), FRAC_CONST(0.26071052995068139), FRAC_CONST(0.27901177101369551), FRAC_CONST(0.29787360383626599), FRAC_CONST(0.3172587073594233), FRAC_CONST(0.33712613787396362), FRAC_CONST(0.35743154274286698), FRAC_CONST(0.37812740923363009), FRAC_CONST(0.39916334663203618), FRAC_CONST(0.42048639939189658), FRAC_CONST(0.4420413886774246), FRAC_CONST(0.4637712792815169), FRAC_CONST(0.4856175685594023), FRAC_CONST(0.50752069370766872), FRAC_CONST(0.52942045344797806), FRAC_CONST(0.55125643994680196), FRAC_CONST(0.57296847662071559), FRAC_CONST(0.59449705734411495), FRAC_CONST(0.61578378249506627), FRAC_CONST(0.63677178724712891), FRAC_CONST(0.65740615754163356), FRAC_CONST(0.67763432925662526), FRAC_CONST(0.69740646622548552), FRAC_CONST(0.71667581294953808), FRAC_CONST(0.73539901809352737), FRAC_CONST(0.75353642514900732), FRAC_CONST(0.77105232699609816), FRAC_CONST(0.78791518148597028), FRAC_CONST(0.80409778560147072), FRAC_CONST(0.81957740622770781), FRAC_CONST(0.83433586607383625), FRAC_CONST(0.84835958382689225), FRAC_CONST(0.86163956818294229), FRAC_CONST(0.87417136598406997), FRAC_CONST(0.88595496528524853), FRAC_CONST(0.89699465477567619), FRAC_CONST(0.90729884157670959), FRAC_CONST(0.91687983002436779), FRAC_CONST(0.92575356460899649), FRAC_CONST(0.93393934077779084), FRAC_CONST(0.94145948779657318), FRAC_CONST(0.94833902830402828), FRAC_CONST(0.95460531956280026), FRAC_CONST(0.96028768170574896), FRAC_CONST(0.96541701848104766), FRAC_CONST(0.97002543610646474), FRAC_CONST(0.97414586584250062), FRAC_CONST(0.97781169577969584), FRAC_CONST(0.98105641710392333), FRAC_CONST(0.98391328975491177), FRAC_CONST(0.98641503193166202), FRAC_CONST(0.98859353733226141), FRAC_CONST(0.99047962335771556), FRAC_CONST(0.9921028127769449), FRAC_CONST(0.99349115056397752), FRAC_CONST(0.99467105680259038), FRAC_CONST(0.9956672157341897), FRAC_CONST(0.99650250022834352), FRAC_CONST(0.99719793020823266), FRAC_CONST(0.99777266288955657), FRAC_CONST(0.99824401211201486), FRAC_CONST(0.99862749357391212), FRAC_CONST(0.99893689243401962), FRAC_CONST(0.99918434952623147), FRAC_CONST(0.99938046234161726), FRAC_CONST(0.99953439696357238), FRAC_CONST(0.99965400728430465), FRAC_CONST(0.99974595807027455), FRAC_CONST(0.99981584876278362), FRAC_CONST(0.99986833527824281), FRAC_CONST(0.99990724749057802), FRAC_CONST(0.99993570051598468), FRAC_CONST(0.99995619835942084), FRAC_CONST(0.99997072890647543), FRAC_CONST(0.9999808496399144), FRAC_CONST(0.99998776381655818), FRAC_CONST(0.99999238714961569), FRAC_CONST(0.99999540529959718), FRAC_CONST(0.99999732268176988), FRAC_CONST(0.99999850325054862), FRAC_CONST(0.99999920402413744), FRAC_CONST(0.9999996021706401), FRAC_CONST(0.99999981649545566), FRAC_CONST(0.99999992415545547), FRAC_CONST(0.99999997338493041), FRAC_CONST(0.99999999295825959), FRAC_CONST(0.99999999904096815) }; #ifdef ALLOW_SMALL_FRAMELENGTH ALIGN static const real_t kbd_short_120[] = { FRAC_CONST(0.0000452320086910), FRAC_CONST(0.0001274564692111), FRAC_CONST(0.0002529398385345), FRAC_CONST(0.0004335140496648), FRAC_CONST(0.0006827100966952), FRAC_CONST(0.0010158708222246), FRAC_CONST(0.0014502162869659), FRAC_CONST(0.0020048865156264), FRAC_CONST(0.0027009618393178), FRAC_CONST(0.0035614590925043), FRAC_CONST(0.0046113018122711), FRAC_CONST(0.0058772627936484), FRAC_CONST(0.0073878776584103), FRAC_CONST(0.0091733284512589), FRAC_CONST(0.0112652966728373), FRAC_CONST(0.0136967855861945), FRAC_CONST(0.0165019120857793), FRAC_CONST(0.0197156688892217), FRAC_CONST(0.0233736582950619), FRAC_CONST(0.0275117992367496), FRAC_CONST(0.0321660098468534), FRAC_CONST(0.0373718682174417), FRAC_CONST(0.0431642544948834), FRAC_CONST(0.0495769778717676), FRAC_CONST(0.0566423924273392), FRAC_CONST(0.0643910061132260), FRAC_CONST(0.0728510874761729), FRAC_CONST(0.0820482749475221), FRAC_CONST(0.0920051937045235), FRAC_CONST(0.1027410852163450), FRAC_CONST(0.1142714546239370), FRAC_CONST(0.1266077410648368), FRAC_CONST(0.1397570159398145), FRAC_CONST(0.1537217139274270), FRAC_CONST(0.1684994012857075), FRAC_CONST(0.1840825856392944), FRAC_CONST(0.2004585710384133), FRAC_CONST(0.2176093615976121), FRAC_CONST(0.2355116164824983), FRAC_CONST(0.2541366584185075), FRAC_CONST(0.2734505372545160), FRAC_CONST(0.2934141494343369), FRAC_CONST(0.3139834135200387), FRAC_CONST(0.3351095011824163), FRAC_CONST(0.3567391223361566), FRAC_CONST(0.3788148623608774), FRAC_CONST(0.4012755686250732), FRAC_CONST(0.4240567828288110), FRAC_CONST(0.4470912150133537), FRAC_CONST(0.4703092544619664), FRAC_CONST(0.4936395121456694), FRAC_CONST(0.5170093888596962), FRAC_CONST(0.5403456627591340), FRAC_CONST(0.5635750896430154), FRAC_CONST(0.5866250090612892), FRAC_CONST(0.6094239491338723), FRAC_CONST(0.6319022228794100), FRAC_CONST(0.6539925088563087), FRAC_CONST(0.6756304090216887), FRAC_CONST(0.6967549769155277), FRAC_CONST(0.7173092095766250), FRAC_CONST(0.7372404969921184), FRAC_CONST(0.7565010233699827), FRAC_CONST(0.7750481150999984), FRAC_CONST(0.7928445309277697), FRAC_CONST(0.8098586906021583), FRAC_CONST(0.8260648390616000), FRAC_CONST(0.8414431440907889), FRAC_CONST(0.8559797262966709), FRAC_CONST(0.8696666212110165), FRAC_CONST(0.8825016743142358), FRAC_CONST(0.8944883707784486), FRAC_CONST(0.9056356027326216), FRAC_CONST(0.9159573778427816), FRAC_CONST(0.9254724739583072), FRAC_CONST(0.9342040454819434), FRAC_CONST(0.9421791879559176), FRAC_CONST(0.9494284680976784), FRAC_CONST(0.9559854271440150), FRAC_CONST(0.9618860658493898), FRAC_CONST(0.9671683198119525), FRAC_CONST(0.9718715339497299), FRAC_CONST(0.9760359449042233), FRAC_CONST(0.9797021798981759), FRAC_CONST(0.9829107801140203), FRAC_CONST(0.9857017559923277), FRAC_CONST(0.9881141809867999), FRAC_CONST(0.9901858292742826), FRAC_CONST(0.9919528617340944), FRAC_CONST(0.9934495632180476), FRAC_CONST(0.9947081327749199), FRAC_CONST(0.9957585271195989), FRAC_CONST(0.9966283562984427), FRAC_CONST(0.9973428292485683), FRAC_CONST(0.9979247458259197), FRAC_CONST(0.9983945309245774), FRAC_CONST(0.9987703055583410), FRAC_CONST(0.9990679892449266), FRAC_CONST(0.9993014277313617), FRAC_CONST(0.9994825400228521), FRAC_CONST(0.9996214788122335), FRAC_CONST(0.9997267987294857), FRAC_CONST(0.9998056273097539), FRAC_CONST(0.9998638341781910), FRAC_CONST(0.9999061946325793), FRAC_CONST(0.9999365445321382), FRAC_CONST(0.9999579241373735), FRAC_CONST(0.9999727092594598), FRAC_CONST(0.9999827287418790), FRAC_CONST(0.9999893678912771), FRAC_CONST(0.9999936579844555), FRAC_CONST(0.9999963523959187), FRAC_CONST(0.9999979902130101), FRAC_CONST(0.9999989484358076), FRAC_CONST(0.9999994840031031), FRAC_CONST(0.9999997669534347), FRAC_CONST(0.9999999060327799), FRAC_CONST(0.9999999680107184), FRAC_CONST(0.9999999918774242), FRAC_CONST(0.9999999989770326) }; #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/output.c0000644000175000017500000004257414647725152015426 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: output.c,v 1.47 2009/01/26 23:51:15 menno Exp $ **/ #include "common.h" #include "structs.h" #include "output.h" #ifndef FIXED_POINT #define FLOAT_SCALE (1.0f/(1<<15)) #define DM_MUL REAL_CONST(0.3203772410170407) // 1/(1+sqrt(2) + 1/sqrt(2)) #define RSQRT2 REAL_CONST(0.7071067811865475244) // 1/sqrt(2) static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample, uint8_t down_matrix, uint8_t *internal_channel) { if (!down_matrix) return input[internal_channel[channel]][sample]; if (channel == 0) { return DM_MUL * (input[internal_channel[1]][sample] + input[internal_channel[0]][sample] * RSQRT2 + input[internal_channel[3]][sample] * RSQRT2); } else { return DM_MUL * (input[internal_channel[2]][sample] + input[internal_channel[0]][sample] * RSQRT2 + input[internal_channel[4]][sample] * RSQRT2); } } #ifndef HAS_LRINTF #define CLIP(sample, max, min) \ if (sample >= 0.0f) \ { \ sample += 0.5f; \ if (sample >= max) \ sample = max; \ } else { \ sample += -0.5f; \ if (sample <= min) \ sample = min; \ } #else #define CLIP(sample, max, min) \ if (sample >= 0.0f) \ { \ if (sample >= max) \ sample = max; \ } else { \ if (sample <= min) \ sample = min; \ } #endif #define CONV(a,b) ((a<<1)|(b&0x1)) static void to_PCM_16bit(NeAACDecStruct *hDecoder, real_t **input, uint8_t channels, uint16_t frame_len, int16_t **sample_buffer) { uint8_t ch, ch1; uint16_t i; switch (CONV(channels,hDecoder->downMatrix)) { case CONV(1,0): case CONV(1,1): for(i = 0; i < frame_len; i++) { real_t inp = input[hDecoder->internal_channel[0]][i]; CLIP(inp, 32767.0f, -32768.0f); (*sample_buffer)[i] = (int16_t)lrintf(inp); } break; case CONV(2,0): if (hDecoder->upMatrix) { ch = hDecoder->internal_channel[0]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch][i]; CLIP(inp0, 32767.0f, -32768.0f); (*sample_buffer)[(i*2)+0] = (int16_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int16_t)lrintf(inp0); } } else { ch = hDecoder->internal_channel[0]; ch1 = hDecoder->internal_channel[1]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch ][i]; real_t inp1 = input[ch1][i]; CLIP(inp0, 32767.0f, -32768.0f); CLIP(inp1, 32767.0f, -32768.0f); (*sample_buffer)[(i*2)+0] = (int16_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int16_t)lrintf(inp1); } } break; default: for (ch = 0; ch < channels; ch++) { for(i = 0; i < frame_len; i++) { real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel); CLIP(inp, 32767.0f, -32768.0f); (*sample_buffer)[(i*channels)+ch] = (int16_t)lrintf(inp); } } break; } } static void to_PCM_24bit(NeAACDecStruct *hDecoder, real_t **input, uint8_t channels, uint16_t frame_len, int32_t **sample_buffer) { uint8_t ch, ch1; uint16_t i; switch (CONV(channels,hDecoder->downMatrix)) { case CONV(1,0): case CONV(1,1): for(i = 0; i < frame_len; i++) { real_t inp = input[hDecoder->internal_channel[0]][i]; inp *= 256.0f; CLIP(inp, 8388607.0f, -8388608.0f); (*sample_buffer)[i] = (int32_t)lrintf(inp); } break; case CONV(2,0): if (hDecoder->upMatrix) { ch = hDecoder->internal_channel[0]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch][i]; inp0 *= 256.0f; CLIP(inp0, 8388607.0f, -8388608.0f); (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp0); } } else { ch = hDecoder->internal_channel[0]; ch1 = hDecoder->internal_channel[1]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch ][i]; real_t inp1 = input[ch1][i]; inp0 *= 256.0f; inp1 *= 256.0f; CLIP(inp0, 8388607.0f, -8388608.0f); CLIP(inp1, 8388607.0f, -8388608.0f); (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp1); } } break; default: for (ch = 0; ch < channels; ch++) { for(i = 0; i < frame_len; i++) { real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel); inp *= 256.0f; CLIP(inp, 8388607.0f, -8388608.0f); (*sample_buffer)[(i*channels)+ch] = (int32_t)lrintf(inp); } } break; } } static void to_PCM_32bit(NeAACDecStruct *hDecoder, real_t **input, uint8_t channels, uint16_t frame_len, int32_t **sample_buffer) { uint8_t ch, ch1; uint16_t i; switch (CONV(channels,hDecoder->downMatrix)) { case CONV(1,0): case CONV(1,1): for(i = 0; i < frame_len; i++) { real_t inp = input[hDecoder->internal_channel[0]][i]; inp *= 65536.0f; CLIP(inp, 2147483647.0f, -2147483648.0f); (*sample_buffer)[i] = (int32_t)lrintf(inp); } break; case CONV(2,0): if (hDecoder->upMatrix) { ch = hDecoder->internal_channel[0]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch][i]; inp0 *= 65536.0f; CLIP(inp0, 2147483647.0f, -2147483648.0f); (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp0); } } else { ch = hDecoder->internal_channel[0]; ch1 = hDecoder->internal_channel[1]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch ][i]; real_t inp1 = input[ch1][i]; inp0 *= 65536.0f; inp1 *= 65536.0f; CLIP(inp0, 2147483647.0f, -2147483648.0f); CLIP(inp1, 2147483647.0f, -2147483648.0f); (*sample_buffer)[(i*2)+0] = (int32_t)lrintf(inp0); (*sample_buffer)[(i*2)+1] = (int32_t)lrintf(inp1); } } break; default: for (ch = 0; ch < channels; ch++) { for(i = 0; i < frame_len; i++) { real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel); inp *= 65536.0f; CLIP(inp, 2147483647.0f, -2147483648.0f); (*sample_buffer)[(i*channels)+ch] = (int32_t)lrintf(inp); } } break; } } static void to_PCM_float(NeAACDecStruct *hDecoder, real_t **input, uint8_t channels, uint16_t frame_len, float32_t **sample_buffer) { uint8_t ch, ch1; uint16_t i; switch (CONV(channels,hDecoder->downMatrix)) { case CONV(1,0): case CONV(1,1): for(i = 0; i < frame_len; i++) { real_t inp = input[hDecoder->internal_channel[0]][i]; (*sample_buffer)[i] = inp*FLOAT_SCALE; } break; case CONV(2,0): if (hDecoder->upMatrix) { ch = hDecoder->internal_channel[0]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch][i]; (*sample_buffer)[(i*2)+0] = inp0*FLOAT_SCALE; (*sample_buffer)[(i*2)+1] = inp0*FLOAT_SCALE; } } else { ch = hDecoder->internal_channel[0]; ch1 = hDecoder->internal_channel[1]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch ][i]; real_t inp1 = input[ch1][i]; (*sample_buffer)[(i*2)+0] = inp0*FLOAT_SCALE; (*sample_buffer)[(i*2)+1] = inp1*FLOAT_SCALE; } } break; default: for (ch = 0; ch < channels; ch++) { for(i = 0; i < frame_len; i++) { real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel); (*sample_buffer)[(i*channels)+ch] = inp*FLOAT_SCALE; } } break; } } static void to_PCM_double(NeAACDecStruct *hDecoder, real_t **input, uint8_t channels, uint16_t frame_len, double **sample_buffer) { uint8_t ch, ch1; uint16_t i; switch (CONV(channels,hDecoder->downMatrix)) { case CONV(1,0): case CONV(1,1): for(i = 0; i < frame_len; i++) { real_t inp = input[hDecoder->internal_channel[0]][i]; (*sample_buffer)[i] = (double)inp*FLOAT_SCALE; } break; case CONV(2,0): if (hDecoder->upMatrix) { ch = hDecoder->internal_channel[0]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch][i]; (*sample_buffer)[(i*2)+0] = (double)inp0*FLOAT_SCALE; (*sample_buffer)[(i*2)+1] = (double)inp0*FLOAT_SCALE; } } else { ch = hDecoder->internal_channel[0]; ch1 = hDecoder->internal_channel[1]; for(i = 0; i < frame_len; i++) { real_t inp0 = input[ch ][i]; real_t inp1 = input[ch1][i]; (*sample_buffer)[(i*2)+0] = (double)inp0*FLOAT_SCALE; (*sample_buffer)[(i*2)+1] = (double)inp1*FLOAT_SCALE; } } break; default: for (ch = 0; ch < channels; ch++) { for(i = 0; i < frame_len; i++) { real_t inp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->internal_channel); (*sample_buffer)[(i*channels)+ch] = (double)inp*FLOAT_SCALE; } } break; } } void *output_to_PCM(NeAACDecStruct *hDecoder, real_t **input, void *sample_buffer, uint8_t channels, uint16_t frame_len, uint8_t format) { int16_t *short_sample_buffer = (int16_t*)sample_buffer; int32_t *int_sample_buffer = (int32_t*)sample_buffer; float32_t *float_sample_buffer = (float32_t*)sample_buffer; double *double_sample_buffer = (double*)sample_buffer; #ifdef PROFILE int64_t count = faad_get_ts(); #endif /* Copy output to a standard PCM buffer */ switch (format) { case FAAD_FMT_16BIT: to_PCM_16bit(hDecoder, input, channels, frame_len, &short_sample_buffer); break; case FAAD_FMT_24BIT: to_PCM_24bit(hDecoder, input, channels, frame_len, &int_sample_buffer); break; case FAAD_FMT_32BIT: to_PCM_32bit(hDecoder, input, channels, frame_len, &int_sample_buffer); break; case FAAD_FMT_FLOAT: to_PCM_float(hDecoder, input, channels, frame_len, &float_sample_buffer); break; case FAAD_FMT_DOUBLE: to_PCM_double(hDecoder, input, channels, frame_len, &double_sample_buffer); break; } #ifdef PROFILE count = faad_get_ts() - count; hDecoder->output_cycles += count; #endif return sample_buffer; } #else #define DM_MUL FRAC_CONST(0.3203772410170407) // 1/(1+sqrt(2) + 1/sqrt(2)) #define RSQRT2 FRAC_CONST(0.7071067811865475244) // 1/sqrt(2) static INLINE real_t get_sample(real_t **input, uint8_t channel, uint16_t sample, uint8_t down_matrix, uint8_t up_matrix, uint8_t *internal_channel) { if (up_matrix == 1) return input[internal_channel[0]][sample]; if (!down_matrix) return input[internal_channel[channel]][sample]; if (channel == 0) { real_t C = MUL_F(input[internal_channel[0]][sample], RSQRT2); real_t L_S = MUL_F(input[internal_channel[3]][sample], RSQRT2); real_t cum = input[internal_channel[1]][sample] + C + L_S; return MUL_F(cum, DM_MUL); } else { real_t C = MUL_F(input[internal_channel[0]][sample], RSQRT2); real_t R_S = MUL_F(input[internal_channel[4]][sample], RSQRT2); real_t cum = input[internal_channel[2]][sample] + C + R_S; return MUL_F(cum, DM_MUL); } } void* output_to_PCM(NeAACDecStruct *hDecoder, real_t **input, void *sample_buffer, uint8_t channels, uint16_t frame_len, uint8_t format) { uint8_t ch; uint16_t i; int16_t *short_sample_buffer = (int16_t*)sample_buffer; int32_t *int_sample_buffer = (int32_t*)sample_buffer; /* Copy output to a standard PCM buffer */ for (ch = 0; ch < channels; ch++) { switch (format) { case FAAD_FMT_16BIT: for(i = 0; i < frame_len; i++) { int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix, hDecoder->internal_channel); if (tmp >= 0) { tmp += (1 << (REAL_BITS-1)); if (tmp >= REAL_CONST(32767)) { tmp = REAL_CONST(32767); } } else { tmp += -(1 << (REAL_BITS-1)); if (tmp <= REAL_CONST(-32768)) { tmp = REAL_CONST(-32768); } } tmp >>= REAL_BITS; short_sample_buffer[(i*channels)+ch] = (int16_t)tmp; } break; case FAAD_FMT_24BIT: for(i = 0; i < frame_len; i++) { int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix, hDecoder->internal_channel); if (tmp >= 0) { tmp += (1 << (REAL_BITS-9)); tmp >>= (REAL_BITS-8); if (tmp >= 8388607) { tmp = 8388607; } } else { tmp += -(1 << (REAL_BITS-9)); tmp >>= (REAL_BITS-8); if (tmp <= -8388608) { tmp = -8388608; } } int_sample_buffer[(i*channels)+ch] = (int32_t)tmp; } break; case FAAD_FMT_32BIT: for(i = 0; i < frame_len; i++) { int32_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix, hDecoder->internal_channel); if (tmp >= 0) { tmp += (1 << (16-REAL_BITS-1)); tmp <<= (16-REAL_BITS); } else { tmp += -(1 << (16-REAL_BITS-1)); tmp <<= (16-REAL_BITS); } int_sample_buffer[(i*channels)+ch] = (int32_t)tmp; } break; case FAAD_FMT_FIXED: for(i = 0; i < frame_len; i++) { real_t tmp = get_sample(input, ch, i, hDecoder->downMatrix, hDecoder->upMatrix, hDecoder->internal_channel); int_sample_buffer[(i*channels)+ch] = (int32_t)tmp; } break; } } return sample_buffer; } #endif xine-lib-1.2/contrib/libfaad/sbr_e_nf.c0000644000175000017500000014165014647725152015636 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_e_nf.c,v 1.22 2008/03/23 23:03:29 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include #include "sbr_syntax.h" #include "sbr_e_nf.h" void extract_envelope_data(sbr_info *sbr, uint8_t ch) { uint8_t l, k; for (l = 0; l < sbr->L_E[ch]; l++) { if (sbr->bs_df_env[ch][l] == 0) { for (k = 1; k < sbr->n[sbr->f[ch][l]]; k++) { sbr->E[ch][k][l] = sbr->E[ch][k - 1][l] + sbr->E[ch][k][l]; if (sbr->E[ch][k][l] < 0) sbr->E[ch][k][l] = 0; } } else { /* bs_df_env == 1 */ uint8_t g = (l == 0) ? sbr->f_prev[ch] : sbr->f[ch][l-1]; int16_t E_prev; if (sbr->f[ch][l] == g) { for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++) { if (l == 0) E_prev = sbr->E_prev[ch][k]; else E_prev = sbr->E[ch][k][l - 1]; sbr->E[ch][k][l] = E_prev + sbr->E[ch][k][l]; } } else if ((g == 1) && (sbr->f[ch][l] == 0)) { uint8_t i; for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++) { for (i = 0; i < sbr->N_high; i++) { if (sbr->f_table_res[HI_RES][i] == sbr->f_table_res[LO_RES][k]) { if (l == 0) E_prev = sbr->E_prev[ch][i]; else E_prev = sbr->E[ch][i][l - 1]; sbr->E[ch][k][l] = E_prev + sbr->E[ch][k][l]; } } } } else if ((g == 0) && (sbr->f[ch][l] == 1)) { uint8_t i; for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++) { for (i = 0; i < sbr->N_low; i++) { if ((sbr->f_table_res[LO_RES][i] <= sbr->f_table_res[HI_RES][k]) && (sbr->f_table_res[HI_RES][k] < sbr->f_table_res[LO_RES][i + 1])) { if (l == 0) E_prev = sbr->E_prev[ch][i]; else E_prev = sbr->E[ch][i][l - 1]; sbr->E[ch][k][l] = E_prev + sbr->E[ch][k][l]; } } } } } } } void extract_noise_floor_data(sbr_info *sbr, uint8_t ch) { uint8_t l, k; for (l = 0; l < sbr->L_Q[ch]; l++) { if (sbr->bs_df_noise[ch][l] == 0) { for (k = 1; k < sbr->N_Q; k++) { sbr->Q[ch][k][l] = sbr->Q[ch][k][l] + sbr->Q[ch][k-1][l]; } } else { if (l == 0) { for (k = 0; k < sbr->N_Q; k++) { sbr->Q[ch][k][l] = sbr->Q_prev[ch][k] + sbr->Q[ch][k][0]; } } else { for (k = 0; k < sbr->N_Q; k++) { sbr->Q[ch][k][l] = sbr->Q[ch][k][l - 1] + sbr->Q[ch][k][l]; } } } } } #ifndef FIXED_POINT /* table for Q_div values when no coupling */ static const real_t Q_div_tab[31] = { FRAC_CONST(0.0153846), FRAC_CONST(0.030303), FRAC_CONST(0.0588235), FRAC_CONST(0.111111), FRAC_CONST(0.2), FRAC_CONST(0.333333), FRAC_CONST(0.5), FRAC_CONST(0.666667), FRAC_CONST(0.8), FRAC_CONST(0.888889), FRAC_CONST(0.941176), FRAC_CONST(0.969697), FRAC_CONST(0.984615), FRAC_CONST(0.992248), FRAC_CONST(0.996109), FRAC_CONST(0.998051), FRAC_CONST(0.999024), FRAC_CONST(0.999512), FRAC_CONST(0.999756), FRAC_CONST(0.999878), FRAC_CONST(0.999939), FRAC_CONST(0.999969), FRAC_CONST(0.999985), FRAC_CONST(0.999992), FRAC_CONST(0.999996), FRAC_CONST(0.999998), FRAC_CONST(0.999999), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }; static const real_t Q_div_tab_left[31][13] = { { FRAC_CONST(0.969704), FRAC_CONST(0.888985), FRAC_CONST(0.667532), FRAC_CONST(0.336788), FRAC_CONST(0.117241), FRAC_CONST(0.037594), FRAC_CONST(0.0153846), FRAC_CONST(0.00967118), FRAC_CONST(0.00823245), FRAC_CONST(0.00787211), FRAC_CONST(0.00778198), FRAC_CONST(0.00775945), FRAC_CONST(0.00775382) }, { FRAC_CONST(0.984619), FRAC_CONST(0.94123), FRAC_CONST(0.800623), FRAC_CONST(0.503876), FRAC_CONST(0.209877), FRAC_CONST(0.0724638), FRAC_CONST(0.030303), FRAC_CONST(0.0191571), FRAC_CONST(0.0163305), FRAC_CONST(0.0156212), FRAC_CONST(0.0154438), FRAC_CONST(0.0153994), FRAC_CONST(0.0153883) }, { FRAC_CONST(0.99225), FRAC_CONST(0.969726), FRAC_CONST(0.889273), FRAC_CONST(0.670103), FRAC_CONST(0.346939), FRAC_CONST(0.135135), FRAC_CONST(0.0588235), FRAC_CONST(0.037594), FRAC_CONST(0.0321361), FRAC_CONST(0.0307619), FRAC_CONST(0.0304178), FRAC_CONST(0.0303317), FRAC_CONST(0.0303102) }, { FRAC_CONST(0.99611), FRAC_CONST(0.98463), FRAC_CONST(0.941392), FRAC_CONST(0.802469), FRAC_CONST(0.515152), FRAC_CONST(0.238095), FRAC_CONST(0.111111), FRAC_CONST(0.0724638), FRAC_CONST(0.0622711), FRAC_CONST(0.0596878), FRAC_CONST(0.0590397), FRAC_CONST(0.0588776), FRAC_CONST(0.058837) }, { FRAC_CONST(0.998051), FRAC_CONST(0.992256), FRAC_CONST(0.969811), FRAC_CONST(0.890411), FRAC_CONST(0.68), FRAC_CONST(0.384615), FRAC_CONST(0.2), FRAC_CONST(0.135135), FRAC_CONST(0.117241), FRAC_CONST(0.112652), FRAC_CONST(0.111497), FRAC_CONST(0.111208), FRAC_CONST(0.111135) }, { FRAC_CONST(0.999025), FRAC_CONST(0.996113), FRAC_CONST(0.984674), FRAC_CONST(0.942029), FRAC_CONST(0.809524), FRAC_CONST(0.555556), FRAC_CONST(0.333333), FRAC_CONST(0.238095), FRAC_CONST(0.209877), FRAC_CONST(0.202492), FRAC_CONST(0.200625), FRAC_CONST(0.200156), FRAC_CONST(0.200039) }, { FRAC_CONST(0.999512), FRAC_CONST(0.998053), FRAC_CONST(0.992278), FRAC_CONST(0.970149), FRAC_CONST(0.894737), FRAC_CONST(0.714286), FRAC_CONST(0.5), FRAC_CONST(0.384615), FRAC_CONST(0.346939), FRAC_CONST(0.336788), FRAC_CONST(0.3342), FRAC_CONST(0.33355), FRAC_CONST(0.333388) }, { FRAC_CONST(0.999756), FRAC_CONST(0.999025), FRAC_CONST(0.996124), FRAC_CONST(0.984848), FRAC_CONST(0.944444), FRAC_CONST(0.833333), FRAC_CONST(0.666667), FRAC_CONST(0.555556), FRAC_CONST(0.515152), FRAC_CONST(0.503876), FRAC_CONST(0.500975), FRAC_CONST(0.500244), FRAC_CONST(0.500061) }, { FRAC_CONST(0.999878), FRAC_CONST(0.999512), FRAC_CONST(0.998058), FRAC_CONST(0.992366), FRAC_CONST(0.971429), FRAC_CONST(0.909091), FRAC_CONST(0.8), FRAC_CONST(0.714286), FRAC_CONST(0.68), FRAC_CONST(0.670103), FRAC_CONST(0.667532), FRAC_CONST(0.666884), FRAC_CONST(0.666721) }, { FRAC_CONST(0.999939), FRAC_CONST(0.999756), FRAC_CONST(0.999028), FRAC_CONST(0.996169), FRAC_CONST(0.985507), FRAC_CONST(0.952381), FRAC_CONST(0.888889), FRAC_CONST(0.833333), FRAC_CONST(0.809524), FRAC_CONST(0.802469), FRAC_CONST(0.800623), FRAC_CONST(0.800156), FRAC_CONST(0.800039) }, { FRAC_CONST(0.999969), FRAC_CONST(0.999878), FRAC_CONST(0.999514), FRAC_CONST(0.998081), FRAC_CONST(0.992701), FRAC_CONST(0.97561), FRAC_CONST(0.941176), FRAC_CONST(0.909091), FRAC_CONST(0.894737), FRAC_CONST(0.890411), FRAC_CONST(0.889273), FRAC_CONST(0.888985), FRAC_CONST(0.888913) }, { FRAC_CONST(0.999985), FRAC_CONST(0.999939), FRAC_CONST(0.999757), FRAC_CONST(0.999039), FRAC_CONST(0.996337), FRAC_CONST(0.987654), FRAC_CONST(0.969697), FRAC_CONST(0.952381), FRAC_CONST(0.944444), FRAC_CONST(0.942029), FRAC_CONST(0.941392), FRAC_CONST(0.94123), FRAC_CONST(0.94119) }, { FRAC_CONST(0.999992), FRAC_CONST(0.99997), FRAC_CONST(0.999878), FRAC_CONST(0.999519), FRAC_CONST(0.998165), FRAC_CONST(0.993789), FRAC_CONST(0.984615), FRAC_CONST(0.97561), FRAC_CONST(0.971429), FRAC_CONST(0.970149), FRAC_CONST(0.969811), FRAC_CONST(0.969726), FRAC_CONST(0.969704) }, { FRAC_CONST(0.999996), FRAC_CONST(0.999985), FRAC_CONST(0.999939), FRAC_CONST(0.99976), FRAC_CONST(0.999082), FRAC_CONST(0.996885), FRAC_CONST(0.992248), FRAC_CONST(0.987654), FRAC_CONST(0.985507), FRAC_CONST(0.984848), FRAC_CONST(0.984674), FRAC_CONST(0.98463), FRAC_CONST(0.984619) }, { FRAC_CONST(0.999998), FRAC_CONST(0.999992), FRAC_CONST(0.99997), FRAC_CONST(0.99988), FRAC_CONST(0.999541), FRAC_CONST(0.99844), FRAC_CONST(0.996109), FRAC_CONST(0.993789), FRAC_CONST(0.992701), FRAC_CONST(0.992366), FRAC_CONST(0.992278), FRAC_CONST(0.992256), FRAC_CONST(0.99225) }, { FRAC_CONST(0.999999), FRAC_CONST(0.999996), FRAC_CONST(0.999985), FRAC_CONST(0.99994), FRAC_CONST(0.99977), FRAC_CONST(0.999219), FRAC_CONST(0.998051), FRAC_CONST(0.996885), FRAC_CONST(0.996337), FRAC_CONST(0.996169), FRAC_CONST(0.996124), FRAC_CONST(0.996113), FRAC_CONST(0.99611) }, { FRAC_CONST(1), FRAC_CONST(0.999998), FRAC_CONST(0.999992), FRAC_CONST(0.99997), FRAC_CONST(0.999885), FRAC_CONST(0.99961), FRAC_CONST(0.999024), FRAC_CONST(0.99844), FRAC_CONST(0.998165), FRAC_CONST(0.998081), FRAC_CONST(0.998058), FRAC_CONST(0.998053), FRAC_CONST(0.998051) }, { FRAC_CONST(1), FRAC_CONST(0.999999), FRAC_CONST(0.999996), FRAC_CONST(0.999985), FRAC_CONST(0.999943), FRAC_CONST(0.999805), FRAC_CONST(0.999512), FRAC_CONST(0.999219), FRAC_CONST(0.999082), FRAC_CONST(0.999039), FRAC_CONST(0.999028), FRAC_CONST(0.999025), FRAC_CONST(0.999025) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999998), FRAC_CONST(0.999992), FRAC_CONST(0.999971), FRAC_CONST(0.999902), FRAC_CONST(0.999756), FRAC_CONST(0.99961), FRAC_CONST(0.999541), FRAC_CONST(0.999519), FRAC_CONST(0.999514), FRAC_CONST(0.999512), FRAC_CONST(0.999512) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999999), FRAC_CONST(0.999996), FRAC_CONST(0.999986), FRAC_CONST(0.999951), FRAC_CONST(0.999878), FRAC_CONST(0.999805), FRAC_CONST(0.99977), FRAC_CONST(0.99976), FRAC_CONST(0.999757), FRAC_CONST(0.999756), FRAC_CONST(0.999756) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999998), FRAC_CONST(0.999993), FRAC_CONST(0.999976), FRAC_CONST(0.999939), FRAC_CONST(0.999902), FRAC_CONST(0.999885), FRAC_CONST(0.99988), FRAC_CONST(0.999878), FRAC_CONST(0.999878), FRAC_CONST(0.999878) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999999), FRAC_CONST(0.999996), FRAC_CONST(0.999988), FRAC_CONST(0.999969), FRAC_CONST(0.999951), FRAC_CONST(0.999943), FRAC_CONST(0.99994), FRAC_CONST(0.999939), FRAC_CONST(0.999939), FRAC_CONST(0.999939) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999998), FRAC_CONST(0.999994), FRAC_CONST(0.999985), FRAC_CONST(0.999976), FRAC_CONST(0.999971), FRAC_CONST(0.99997), FRAC_CONST(0.99997), FRAC_CONST(0.99997), FRAC_CONST(0.999969) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999999), FRAC_CONST(0.999997), FRAC_CONST(0.999992), FRAC_CONST(0.999988), FRAC_CONST(0.999986), FRAC_CONST(0.999985), FRAC_CONST(0.999985), FRAC_CONST(0.999985), FRAC_CONST(0.999985) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999998), FRAC_CONST(0.999996), FRAC_CONST(0.999994), FRAC_CONST(0.999993), FRAC_CONST(0.999992), FRAC_CONST(0.999992), FRAC_CONST(0.999992), FRAC_CONST(0.999992) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999999), FRAC_CONST(0.999998), FRAC_CONST(0.999997), FRAC_CONST(0.999996), FRAC_CONST(0.999996), FRAC_CONST(0.999996), FRAC_CONST(0.999996), FRAC_CONST(0.999996) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999999), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) } }; static const real_t Q_div_tab_right[31][13] = { { FRAC_CONST(0.00775382), FRAC_CONST(0.00775945), FRAC_CONST(0.00778198), FRAC_CONST(0.00787211), FRAC_CONST(0.00823245), FRAC_CONST(0.00967118), FRAC_CONST(0.0153846), FRAC_CONST(0.037594), FRAC_CONST(0.117241), FRAC_CONST(0.336788), FRAC_CONST(0.667532), FRAC_CONST(0.888985), FRAC_CONST(0.969704) }, { FRAC_CONST(0.0153883), FRAC_CONST(0.0153994), FRAC_CONST(0.0154438), FRAC_CONST(0.0156212), FRAC_CONST(0.0163305), FRAC_CONST(0.0191571), FRAC_CONST(0.030303), FRAC_CONST(0.0724638), FRAC_CONST(0.209877), FRAC_CONST(0.503876), FRAC_CONST(0.800623), FRAC_CONST(0.94123), FRAC_CONST(0.984619) }, { FRAC_CONST(0.0303102), FRAC_CONST(0.0303317), FRAC_CONST(0.0304178), FRAC_CONST(0.0307619), FRAC_CONST(0.0321361), FRAC_CONST(0.037594), FRAC_CONST(0.0588235), FRAC_CONST(0.135135), FRAC_CONST(0.346939), FRAC_CONST(0.670103), FRAC_CONST(0.889273), FRAC_CONST(0.969726), FRAC_CONST(0.99225) }, { FRAC_CONST(0.058837), FRAC_CONST(0.0588776), FRAC_CONST(0.0590397), FRAC_CONST(0.0596878), FRAC_CONST(0.0622711), FRAC_CONST(0.0724638), FRAC_CONST(0.111111), FRAC_CONST(0.238095), FRAC_CONST(0.515152), FRAC_CONST(0.802469), FRAC_CONST(0.941392), FRAC_CONST(0.98463), FRAC_CONST(0.99611) }, { FRAC_CONST(0.111135), FRAC_CONST(0.111208), FRAC_CONST(0.111497), FRAC_CONST(0.112652), FRAC_CONST(0.117241), FRAC_CONST(0.135135), FRAC_CONST(0.2), FRAC_CONST(0.384615), FRAC_CONST(0.68), FRAC_CONST(0.890411), FRAC_CONST(0.969811), FRAC_CONST(0.992256), FRAC_CONST(0.998051) }, { FRAC_CONST(0.200039), FRAC_CONST(0.200156), FRAC_CONST(0.200625), FRAC_CONST(0.202492), FRAC_CONST(0.209877), FRAC_CONST(0.238095), FRAC_CONST(0.333333), FRAC_CONST(0.555556), FRAC_CONST(0.809524), FRAC_CONST(0.942029), FRAC_CONST(0.984674), FRAC_CONST(0.996113), FRAC_CONST(0.999025) }, { FRAC_CONST(0.333388), FRAC_CONST(0.33355), FRAC_CONST(0.3342), FRAC_CONST(0.336788), FRAC_CONST(0.346939), FRAC_CONST(0.384615), FRAC_CONST(0.5), FRAC_CONST(0.714286), FRAC_CONST(0.894737), FRAC_CONST(0.970149), FRAC_CONST(0.992278), FRAC_CONST(0.998053), FRAC_CONST(0.999512) }, { FRAC_CONST(0.500061), FRAC_CONST(0.500244), FRAC_CONST(0.500975), FRAC_CONST(0.503876), FRAC_CONST(0.515152), FRAC_CONST(0.555556), FRAC_CONST(0.666667), FRAC_CONST(0.833333), FRAC_CONST(0.944444), FRAC_CONST(0.984848), FRAC_CONST(0.996124), FRAC_CONST(0.999025), FRAC_CONST(0.999756) }, { FRAC_CONST(0.666721), FRAC_CONST(0.666884), FRAC_CONST(0.667532), FRAC_CONST(0.670103), FRAC_CONST(0.68), FRAC_CONST(0.714286), FRAC_CONST(0.8), FRAC_CONST(0.909091), FRAC_CONST(0.971429), FRAC_CONST(0.992366), FRAC_CONST(0.998058), FRAC_CONST(0.999512), FRAC_CONST(0.999878) }, { FRAC_CONST(0.800039), FRAC_CONST(0.800156), FRAC_CONST(0.800623), FRAC_CONST(0.802469), FRAC_CONST(0.809524), FRAC_CONST(0.833333), FRAC_CONST(0.888889), FRAC_CONST(0.952381), FRAC_CONST(0.985507), FRAC_CONST(0.996169), FRAC_CONST(0.999028), FRAC_CONST(0.999756), FRAC_CONST(0.999939) }, { FRAC_CONST(0.888913), FRAC_CONST(0.888985), FRAC_CONST(0.889273), FRAC_CONST(0.890411), FRAC_CONST(0.894737), FRAC_CONST(0.909091), FRAC_CONST(0.941176), FRAC_CONST(0.97561), FRAC_CONST(0.992701), FRAC_CONST(0.998081), FRAC_CONST(0.999514), FRAC_CONST(0.999878), FRAC_CONST(0.999969) }, { FRAC_CONST(0.94119), FRAC_CONST(0.94123), FRAC_CONST(0.941392), FRAC_CONST(0.942029), FRAC_CONST(0.944444), FRAC_CONST(0.952381), FRAC_CONST(0.969697), FRAC_CONST(0.987654), FRAC_CONST(0.996337), FRAC_CONST(0.999039), FRAC_CONST(0.999757), FRAC_CONST(0.999939), FRAC_CONST(0.999985) }, { FRAC_CONST(0.969704), FRAC_CONST(0.969726), FRAC_CONST(0.969811), FRAC_CONST(0.970149), FRAC_CONST(0.971429), FRAC_CONST(0.97561), FRAC_CONST(0.984615), FRAC_CONST(0.993789), FRAC_CONST(0.998165), FRAC_CONST(0.999519), FRAC_CONST(0.999878), FRAC_CONST(0.99997), FRAC_CONST(0.999992) }, { FRAC_CONST(0.984619), FRAC_CONST(0.98463), FRAC_CONST(0.984674), FRAC_CONST(0.984848), FRAC_CONST(0.985507), FRAC_CONST(0.987654), FRAC_CONST(0.992248), FRAC_CONST(0.996885), FRAC_CONST(0.999082), FRAC_CONST(0.99976), FRAC_CONST(0.999939), FRAC_CONST(0.999985), FRAC_CONST(0.999996) }, { FRAC_CONST(0.99225), FRAC_CONST(0.992256), FRAC_CONST(0.992278), FRAC_CONST(0.992366), FRAC_CONST(0.992701), FRAC_CONST(0.993789), FRAC_CONST(0.996109), FRAC_CONST(0.99844), FRAC_CONST(0.999541), FRAC_CONST(0.99988), FRAC_CONST(0.99997), FRAC_CONST(0.999992), FRAC_CONST(0.999998) }, { FRAC_CONST(0.99611), FRAC_CONST(0.996113), FRAC_CONST(0.996124), FRAC_CONST(0.996169), FRAC_CONST(0.996337), FRAC_CONST(0.996885), FRAC_CONST(0.998051), FRAC_CONST(0.999219), FRAC_CONST(0.99977), FRAC_CONST(0.99994), FRAC_CONST(0.999985), FRAC_CONST(0.999996), FRAC_CONST(0.999999) }, { FRAC_CONST(0.998051), FRAC_CONST(0.998053), FRAC_CONST(0.998058), FRAC_CONST(0.998081), FRAC_CONST(0.998165), FRAC_CONST(0.99844), FRAC_CONST(0.999024), FRAC_CONST(0.99961), FRAC_CONST(0.999885), FRAC_CONST(0.99997), FRAC_CONST(0.999992), FRAC_CONST(0.999998), FRAC_CONST(1) }, { FRAC_CONST(0.999025), FRAC_CONST(0.999025), FRAC_CONST(0.999028), FRAC_CONST(0.999039), FRAC_CONST(0.999082), FRAC_CONST(0.999219), FRAC_CONST(0.999512), FRAC_CONST(0.999805), FRAC_CONST(0.999943), FRAC_CONST(0.999985), FRAC_CONST(0.999996), FRAC_CONST(0.999999), FRAC_CONST(1) }, { FRAC_CONST(0.999512), FRAC_CONST(0.999512), FRAC_CONST(0.999514), FRAC_CONST(0.999519), FRAC_CONST(0.999541), FRAC_CONST(0.99961), FRAC_CONST(0.999756), FRAC_CONST(0.999902), FRAC_CONST(0.999971), FRAC_CONST(0.999992), FRAC_CONST(0.999998), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999756), FRAC_CONST(0.999756), FRAC_CONST(0.999757), FRAC_CONST(0.99976), FRAC_CONST(0.99977), FRAC_CONST(0.999805), FRAC_CONST(0.999878), FRAC_CONST(0.999951), FRAC_CONST(0.999986), FRAC_CONST(0.999996), FRAC_CONST(0.999999), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999878), FRAC_CONST(0.999878), FRAC_CONST(0.999878), FRAC_CONST(0.99988), FRAC_CONST(0.999885), FRAC_CONST(0.999902), FRAC_CONST(0.999939), FRAC_CONST(0.999976), FRAC_CONST(0.999993), FRAC_CONST(0.999998), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999939), FRAC_CONST(0.999939), FRAC_CONST(0.999939), FRAC_CONST(0.99994), FRAC_CONST(0.999943), FRAC_CONST(0.999951), FRAC_CONST(0.999969), FRAC_CONST(0.999988), FRAC_CONST(0.999996), FRAC_CONST(0.999999), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999969), FRAC_CONST(0.99997), FRAC_CONST(0.99997), FRAC_CONST(0.99997), FRAC_CONST(0.999971), FRAC_CONST(0.999976), FRAC_CONST(0.999985), FRAC_CONST(0.999994), FRAC_CONST(0.999998), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999985), FRAC_CONST(0.999985), FRAC_CONST(0.999985), FRAC_CONST(0.999985), FRAC_CONST(0.999986), FRAC_CONST(0.999988), FRAC_CONST(0.999992), FRAC_CONST(0.999997), FRAC_CONST(0.999999), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999992), FRAC_CONST(0.999992), FRAC_CONST(0.999992), FRAC_CONST(0.999992), FRAC_CONST(0.999993), FRAC_CONST(0.999994), FRAC_CONST(0.999996), FRAC_CONST(0.999998), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999996), FRAC_CONST(0.999996), FRAC_CONST(0.999996), FRAC_CONST(0.999996), FRAC_CONST(0.999996), FRAC_CONST(0.999997), FRAC_CONST(0.999998), FRAC_CONST(0.999999), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999998), FRAC_CONST(0.999999), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(0.999999), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1) } }; /* calculates 1/(1+Q) */ /* [0..1] */ static real_t calc_Q_div(sbr_info *sbr, uint8_t ch, uint8_t m, uint8_t l) { if (sbr->bs_coupling) { /* left channel */ if ((sbr->Q[0][m][l] < 0 || sbr->Q[0][m][l] > 30) || (sbr->Q[1][m][l] < 0 || sbr->Q[1][m][l] > 24 /* 2*panOffset(1) */)) { return 0; } else { /* the pan parameter is always even */ if (ch == 0) { return Q_div_tab_left[sbr->Q[0][m][l]][sbr->Q[1][m][l] >> 1]; } else { return Q_div_tab_right[sbr->Q[0][m][l]][sbr->Q[1][m][l] >> 1]; } } } else { /* no coupling */ if (sbr->Q[ch][m][l] < 0 || sbr->Q[ch][m][l] > 30) { return 0; } else { return Q_div_tab[sbr->Q[ch][m][l]]; } } } /* table for Q_div2 values when no coupling */ static const real_t Q_div2_tab[31] = { FRAC_CONST(0.984615), FRAC_CONST(0.969697), FRAC_CONST(0.941176), FRAC_CONST(0.888889), FRAC_CONST(0.8), FRAC_CONST(0.666667), FRAC_CONST(0.5), FRAC_CONST(0.333333), FRAC_CONST(0.2), FRAC_CONST(0.111111), FRAC_CONST(0.0588235), FRAC_CONST(0.030303), FRAC_CONST(0.0153846), FRAC_CONST(0.00775194), FRAC_CONST(0.00389105), FRAC_CONST(0.00194932), FRAC_CONST(0.00097561), FRAC_CONST(0.000488043), FRAC_CONST(0.000244081), FRAC_CONST(0.000122055), FRAC_CONST(6.10314E-005), FRAC_CONST(3.05166E-005), FRAC_CONST(1.52586E-005), FRAC_CONST(7.62934E-006), FRAC_CONST(3.81468E-006), FRAC_CONST(1.90734E-006), FRAC_CONST(9.53673E-007), FRAC_CONST(4.76837E-007), FRAC_CONST(2.38419E-007), FRAC_CONST(1.19209E-007), FRAC_CONST(5.96046E-008) }; static const real_t Q_div2_tab_left[31][13] = { { FRAC_CONST(0.0302959), FRAC_CONST(0.111015), FRAC_CONST(0.332468), FRAC_CONST(0.663212), FRAC_CONST(0.882759), FRAC_CONST(0.962406), FRAC_CONST(0.984615), FRAC_CONST(0.990329), FRAC_CONST(0.991768), FRAC_CONST(0.992128), FRAC_CONST(0.992218), FRAC_CONST(0.992241), FRAC_CONST(0.992246) }, { FRAC_CONST(0.0153809), FRAC_CONST(0.0587695), FRAC_CONST(0.199377), FRAC_CONST(0.496124), FRAC_CONST(0.790123), FRAC_CONST(0.927536), FRAC_CONST(0.969697), FRAC_CONST(0.980843), FRAC_CONST(0.98367), FRAC_CONST(0.984379), FRAC_CONST(0.984556), FRAC_CONST(0.984601), FRAC_CONST(0.984612) }, { FRAC_CONST(0.00775006), FRAC_CONST(0.0302744), FRAC_CONST(0.110727), FRAC_CONST(0.329897), FRAC_CONST(0.653061), FRAC_CONST(0.864865), FRAC_CONST(0.941176), FRAC_CONST(0.962406), FRAC_CONST(0.967864), FRAC_CONST(0.969238), FRAC_CONST(0.969582), FRAC_CONST(0.969668), FRAC_CONST(0.96969) }, { FRAC_CONST(0.0038901), FRAC_CONST(0.0153698), FRAC_CONST(0.0586081), FRAC_CONST(0.197531), FRAC_CONST(0.484848), FRAC_CONST(0.761905), FRAC_CONST(0.888889), FRAC_CONST(0.927536), FRAC_CONST(0.937729), FRAC_CONST(0.940312), FRAC_CONST(0.94096), FRAC_CONST(0.941122), FRAC_CONST(0.941163) }, { FRAC_CONST(0.00194884), FRAC_CONST(0.00774443), FRAC_CONST(0.0301887), FRAC_CONST(0.109589), FRAC_CONST(0.32), FRAC_CONST(0.615385), FRAC_CONST(0.8), FRAC_CONST(0.864865), FRAC_CONST(0.882759), FRAC_CONST(0.887348), FRAC_CONST(0.888503), FRAC_CONST(0.888792), FRAC_CONST(0.888865) }, { FRAC_CONST(0.000975372), FRAC_CONST(0.00388727), FRAC_CONST(0.0153257), FRAC_CONST(0.057971), FRAC_CONST(0.190476), FRAC_CONST(0.444444), FRAC_CONST(0.666667), FRAC_CONST(0.761905), FRAC_CONST(0.790123), FRAC_CONST(0.797508), FRAC_CONST(0.799375), FRAC_CONST(0.799844), FRAC_CONST(0.799961) }, { FRAC_CONST(0.000487924), FRAC_CONST(0.00194742), FRAC_CONST(0.00772201), FRAC_CONST(0.0298507), FRAC_CONST(0.105263), FRAC_CONST(0.285714), FRAC_CONST(0.5), FRAC_CONST(0.615385), FRAC_CONST(0.653061), FRAC_CONST(0.663212), FRAC_CONST(0.6658), FRAC_CONST(0.66645), FRAC_CONST(0.666612) }, { FRAC_CONST(0.000244021), FRAC_CONST(0.000974659), FRAC_CONST(0.00387597), FRAC_CONST(0.0151515), FRAC_CONST(0.0555556), FRAC_CONST(0.166667), FRAC_CONST(0.333333), FRAC_CONST(0.444444), FRAC_CONST(0.484848), FRAC_CONST(0.496124), FRAC_CONST(0.499025), FRAC_CONST(0.499756), FRAC_CONST(0.499939) }, { FRAC_CONST(0.000122026), FRAC_CONST(0.000487567), FRAC_CONST(0.00194175), FRAC_CONST(0.00763359), FRAC_CONST(0.0285714), FRAC_CONST(0.0909091), FRAC_CONST(0.2), FRAC_CONST(0.285714), FRAC_CONST(0.32), FRAC_CONST(0.329897), FRAC_CONST(0.332468), FRAC_CONST(0.333116), FRAC_CONST(0.333279) }, { FRAC_CONST(6.10165E-005), FRAC_CONST(0.000243843), FRAC_CONST(0.000971817), FRAC_CONST(0.00383142), FRAC_CONST(0.0144928), FRAC_CONST(0.047619), FRAC_CONST(0.111111), FRAC_CONST(0.166667), FRAC_CONST(0.190476), FRAC_CONST(0.197531), FRAC_CONST(0.199377), FRAC_CONST(0.199844), FRAC_CONST(0.199961) }, { FRAC_CONST(3.05092E-005), FRAC_CONST(0.000121936), FRAC_CONST(0.000486145), FRAC_CONST(0.00191939), FRAC_CONST(0.00729927), FRAC_CONST(0.0243902), FRAC_CONST(0.0588235), FRAC_CONST(0.0909091), FRAC_CONST(0.105263), FRAC_CONST(0.109589), FRAC_CONST(0.110727), FRAC_CONST(0.111015), FRAC_CONST(0.111087) }, { FRAC_CONST(1.52548E-005), FRAC_CONST(6.09719E-005), FRAC_CONST(0.000243132), FRAC_CONST(0.000960615), FRAC_CONST(0.003663), FRAC_CONST(0.0123457), FRAC_CONST(0.030303), FRAC_CONST(0.047619), FRAC_CONST(0.0555556), FRAC_CONST(0.057971), FRAC_CONST(0.0586081), FRAC_CONST(0.0587695), FRAC_CONST(0.05881) }, { FRAC_CONST(7.62747E-006), FRAC_CONST(3.04869E-005), FRAC_CONST(0.000121581), FRAC_CONST(0.000480538), FRAC_CONST(0.00183486), FRAC_CONST(0.00621118), FRAC_CONST(0.0153846), FRAC_CONST(0.0243902), FRAC_CONST(0.0285714), FRAC_CONST(0.0298507), FRAC_CONST(0.0301887), FRAC_CONST(0.0302744), FRAC_CONST(0.0302959) }, { FRAC_CONST(3.81375E-006), FRAC_CONST(1.52437E-005), FRAC_CONST(6.0794E-005), FRAC_CONST(0.000240327), FRAC_CONST(0.000918274), FRAC_CONST(0.00311526), FRAC_CONST(0.00775194), FRAC_CONST(0.0123457), FRAC_CONST(0.0144928), FRAC_CONST(0.0151515), FRAC_CONST(0.0153257), FRAC_CONST(0.0153698), FRAC_CONST(0.0153809) }, { FRAC_CONST(1.90688E-006), FRAC_CONST(7.62189E-006), FRAC_CONST(3.03979E-005), FRAC_CONST(0.000120178), FRAC_CONST(0.000459348), FRAC_CONST(0.00156006), FRAC_CONST(0.00389105), FRAC_CONST(0.00621118), FRAC_CONST(0.00729927), FRAC_CONST(0.00763359), FRAC_CONST(0.00772201), FRAC_CONST(0.00774443), FRAC_CONST(0.00775006) }, { FRAC_CONST(9.53441E-007), FRAC_CONST(3.81096E-006), FRAC_CONST(1.51992E-005), FRAC_CONST(6.00925E-005), FRAC_CONST(0.000229727), FRAC_CONST(0.00078064), FRAC_CONST(0.00194932), FRAC_CONST(0.00311526), FRAC_CONST(0.003663), FRAC_CONST(0.00383142), FRAC_CONST(0.00387597), FRAC_CONST(0.00388727), FRAC_CONST(0.0038901) }, { FRAC_CONST(4.76721E-007), FRAC_CONST(1.90548E-006), FRAC_CONST(7.59965E-006), FRAC_CONST(3.00472E-005), FRAC_CONST(0.000114877), FRAC_CONST(0.000390472), FRAC_CONST(0.00097561), FRAC_CONST(0.00156006), FRAC_CONST(0.00183486), FRAC_CONST(0.00191939), FRAC_CONST(0.00194175), FRAC_CONST(0.00194742), FRAC_CONST(0.00194884) }, { FRAC_CONST(2.3836E-007), FRAC_CONST(9.52743E-007), FRAC_CONST(3.79984E-006), FRAC_CONST(1.50238E-005), FRAC_CONST(5.74416E-005), FRAC_CONST(0.000195274), FRAC_CONST(0.000488043), FRAC_CONST(0.00078064), FRAC_CONST(0.000918274), FRAC_CONST(0.000960615), FRAC_CONST(0.000971817), FRAC_CONST(0.000974659), FRAC_CONST(0.000975372) }, { FRAC_CONST(1.1918E-007), FRAC_CONST(4.76372E-007), FRAC_CONST(1.89992E-006), FRAC_CONST(7.51196E-006), FRAC_CONST(2.87216E-005), FRAC_CONST(9.76467E-005), FRAC_CONST(0.000244081), FRAC_CONST(0.000390472), FRAC_CONST(0.000459348), FRAC_CONST(0.000480538), FRAC_CONST(0.000486145), FRAC_CONST(0.000487567), FRAC_CONST(0.000487924) }, { FRAC_CONST(5.95901E-008), FRAC_CONST(2.38186E-007), FRAC_CONST(9.49963E-007), FRAC_CONST(3.756E-006), FRAC_CONST(1.4361E-005), FRAC_CONST(4.88257E-005), FRAC_CONST(0.000122055), FRAC_CONST(0.000195274), FRAC_CONST(0.000229727), FRAC_CONST(0.000240327), FRAC_CONST(0.000243132), FRAC_CONST(0.000243843), FRAC_CONST(0.000244021) }, { FRAC_CONST(2.9795E-008), FRAC_CONST(1.19093E-007), FRAC_CONST(4.74982E-007), FRAC_CONST(1.878E-006), FRAC_CONST(7.18056E-006), FRAC_CONST(2.44135E-005), FRAC_CONST(6.10314E-005), FRAC_CONST(9.76467E-005), FRAC_CONST(0.000114877), FRAC_CONST(0.000120178), FRAC_CONST(0.000121581), FRAC_CONST(0.000121936), FRAC_CONST(0.000122026) }, { FRAC_CONST(1.48975E-008), FRAC_CONST(5.95465E-008), FRAC_CONST(2.37491E-007), FRAC_CONST(9.39002E-007), FRAC_CONST(3.59029E-006), FRAC_CONST(1.22069E-005), FRAC_CONST(3.05166E-005), FRAC_CONST(4.88257E-005), FRAC_CONST(5.74416E-005), FRAC_CONST(6.00925E-005), FRAC_CONST(6.0794E-005), FRAC_CONST(6.09719E-005), FRAC_CONST(6.10165E-005) }, { FRAC_CONST(7.44876E-009), FRAC_CONST(2.97732E-008), FRAC_CONST(1.18745E-007), FRAC_CONST(4.69501E-007), FRAC_CONST(1.79515E-006), FRAC_CONST(6.10348E-006), FRAC_CONST(1.52586E-005), FRAC_CONST(2.44135E-005), FRAC_CONST(2.87216E-005), FRAC_CONST(3.00472E-005), FRAC_CONST(3.03979E-005), FRAC_CONST(3.04869E-005), FRAC_CONST(3.05092E-005) }, { FRAC_CONST(3.72438E-009), FRAC_CONST(1.48866E-008), FRAC_CONST(5.93727E-008), FRAC_CONST(2.34751E-007), FRAC_CONST(8.97575E-007), FRAC_CONST(3.05175E-006), FRAC_CONST(7.62934E-006), FRAC_CONST(1.22069E-005), FRAC_CONST(1.4361E-005), FRAC_CONST(1.50238E-005), FRAC_CONST(1.51992E-005), FRAC_CONST(1.52437E-005), FRAC_CONST(1.52548E-005) }, { FRAC_CONST(1.86219E-009), FRAC_CONST(7.44331E-009), FRAC_CONST(2.96864E-008), FRAC_CONST(1.17375E-007), FRAC_CONST(4.48788E-007), FRAC_CONST(1.52588E-006), FRAC_CONST(3.81468E-006), FRAC_CONST(6.10348E-006), FRAC_CONST(7.18056E-006), FRAC_CONST(7.51196E-006), FRAC_CONST(7.59965E-006), FRAC_CONST(7.62189E-006), FRAC_CONST(7.62747E-006) }, { FRAC_CONST(9.31095E-010), FRAC_CONST(3.72166E-009), FRAC_CONST(1.48432E-008), FRAC_CONST(5.86876E-008), FRAC_CONST(2.24394E-007), FRAC_CONST(7.62939E-007), FRAC_CONST(1.90734E-006), FRAC_CONST(3.05175E-006), FRAC_CONST(3.59029E-006), FRAC_CONST(3.756E-006), FRAC_CONST(3.79984E-006), FRAC_CONST(3.81096E-006), FRAC_CONST(3.81375E-006) }, { FRAC_CONST(4.65548E-010), FRAC_CONST(1.86083E-009), FRAC_CONST(7.42159E-009), FRAC_CONST(2.93438E-008), FRAC_CONST(1.12197E-007), FRAC_CONST(3.8147E-007), FRAC_CONST(9.53673E-007), FRAC_CONST(1.52588E-006), FRAC_CONST(1.79515E-006), FRAC_CONST(1.878E-006), FRAC_CONST(1.89992E-006), FRAC_CONST(1.90548E-006), FRAC_CONST(1.90688E-006) }, { FRAC_CONST(2.32774E-010), FRAC_CONST(9.30414E-010), FRAC_CONST(3.71079E-009), FRAC_CONST(1.46719E-008), FRAC_CONST(5.60985E-008), FRAC_CONST(1.90735E-007), FRAC_CONST(4.76837E-007), FRAC_CONST(7.62939E-007), FRAC_CONST(8.97575E-007), FRAC_CONST(9.39002E-007), FRAC_CONST(9.49963E-007), FRAC_CONST(9.52743E-007), FRAC_CONST(9.53441E-007) }, { FRAC_CONST(1.16387E-010), FRAC_CONST(4.65207E-010), FRAC_CONST(1.8554E-009), FRAC_CONST(7.33596E-009), FRAC_CONST(2.80492E-008), FRAC_CONST(9.53674E-008), FRAC_CONST(2.38419E-007), FRAC_CONST(3.8147E-007), FRAC_CONST(4.48788E-007), FRAC_CONST(4.69501E-007), FRAC_CONST(4.74982E-007), FRAC_CONST(4.76372E-007), FRAC_CONST(4.76721E-007) }, { FRAC_CONST(5.81935E-011), FRAC_CONST(2.32603E-010), FRAC_CONST(9.27699E-010), FRAC_CONST(3.66798E-009), FRAC_CONST(1.40246E-008), FRAC_CONST(4.76837E-008), FRAC_CONST(1.19209E-007), FRAC_CONST(1.90735E-007), FRAC_CONST(2.24394E-007), FRAC_CONST(2.34751E-007), FRAC_CONST(2.37491E-007), FRAC_CONST(2.38186E-007), FRAC_CONST(2.3836E-007) }, { FRAC_CONST(2.90967E-011), FRAC_CONST(1.16302E-010), FRAC_CONST(4.63849E-010), FRAC_CONST(1.83399E-009), FRAC_CONST(7.01231E-009), FRAC_CONST(2.38419E-008), FRAC_CONST(5.96046E-008), FRAC_CONST(9.53674E-008), FRAC_CONST(1.12197E-007), FRAC_CONST(1.17375E-007), FRAC_CONST(1.18745E-007), FRAC_CONST(1.19093E-007), FRAC_CONST(1.1918E-007) } }; static const real_t Q_div2_tab_right[31][13] = { { FRAC_CONST(0.992246), FRAC_CONST(0.992241), FRAC_CONST(0.992218), FRAC_CONST(0.992128), FRAC_CONST(0.991768), FRAC_CONST(0.990329), FRAC_CONST(0.984615), FRAC_CONST(0.962406), FRAC_CONST(0.882759), FRAC_CONST(0.663212), FRAC_CONST(0.332468), FRAC_CONST(0.111015), FRAC_CONST(0.0302959) }, { FRAC_CONST(0.984612), FRAC_CONST(0.984601), FRAC_CONST(0.984556), FRAC_CONST(0.984379), FRAC_CONST(0.98367), FRAC_CONST(0.980843), FRAC_CONST(0.969697), FRAC_CONST(0.927536), FRAC_CONST(0.790123), FRAC_CONST(0.496124), FRAC_CONST(0.199377), FRAC_CONST(0.0587695), FRAC_CONST(0.0153809) }, { FRAC_CONST(0.96969), FRAC_CONST(0.969668), FRAC_CONST(0.969582), FRAC_CONST(0.969238), FRAC_CONST(0.967864), FRAC_CONST(0.962406), FRAC_CONST(0.941176), FRAC_CONST(0.864865), FRAC_CONST(0.653061), FRAC_CONST(0.329897), FRAC_CONST(0.110727), FRAC_CONST(0.0302744), FRAC_CONST(0.00775006) }, { FRAC_CONST(0.941163), FRAC_CONST(0.941122), FRAC_CONST(0.94096), FRAC_CONST(0.940312), FRAC_CONST(0.937729), FRAC_CONST(0.927536), FRAC_CONST(0.888889), FRAC_CONST(0.761905), FRAC_CONST(0.484848), FRAC_CONST(0.197531), FRAC_CONST(0.0586081), FRAC_CONST(0.0153698), FRAC_CONST(0.0038901) }, { FRAC_CONST(0.888865), FRAC_CONST(0.888792), FRAC_CONST(0.888503), FRAC_CONST(0.887348), FRAC_CONST(0.882759), FRAC_CONST(0.864865), FRAC_CONST(0.8), FRAC_CONST(0.615385), FRAC_CONST(0.32), FRAC_CONST(0.109589), FRAC_CONST(0.0301887), FRAC_CONST(0.00774443), FRAC_CONST(0.00194884) }, { FRAC_CONST(0.799961), FRAC_CONST(0.799844), FRAC_CONST(0.799375), FRAC_CONST(0.797508), FRAC_CONST(0.790123), FRAC_CONST(0.761905), FRAC_CONST(0.666667), FRAC_CONST(0.444444), FRAC_CONST(0.190476), FRAC_CONST(0.057971), FRAC_CONST(0.0153257), FRAC_CONST(0.00388727), FRAC_CONST(0.000975372) }, { FRAC_CONST(0.666612), FRAC_CONST(0.66645), FRAC_CONST(0.6658), FRAC_CONST(0.663212), FRAC_CONST(0.653061), FRAC_CONST(0.615385), FRAC_CONST(0.5), FRAC_CONST(0.285714), FRAC_CONST(0.105263), FRAC_CONST(0.0298507), FRAC_CONST(0.00772201), FRAC_CONST(0.00194742), FRAC_CONST(0.000487924) }, { FRAC_CONST(0.499939), FRAC_CONST(0.499756), FRAC_CONST(0.499025), FRAC_CONST(0.496124), FRAC_CONST(0.484848), FRAC_CONST(0.444444), FRAC_CONST(0.333333), FRAC_CONST(0.166667), FRAC_CONST(0.0555556), FRAC_CONST(0.0151515), FRAC_CONST(0.00387597), FRAC_CONST(0.000974659), FRAC_CONST(0.000244021) }, { FRAC_CONST(0.333279), FRAC_CONST(0.333116), FRAC_CONST(0.332468), FRAC_CONST(0.329897), FRAC_CONST(0.32), FRAC_CONST(0.285714), FRAC_CONST(0.2), FRAC_CONST(0.0909091), FRAC_CONST(0.0285714), FRAC_CONST(0.00763359), FRAC_CONST(0.00194175), FRAC_CONST(0.000487567), FRAC_CONST(0.000122026) }, { FRAC_CONST(0.199961), FRAC_CONST(0.199844), FRAC_CONST(0.199377), FRAC_CONST(0.197531), FRAC_CONST(0.190476), FRAC_CONST(0.166667), FRAC_CONST(0.111111), FRAC_CONST(0.047619), FRAC_CONST(0.0144928), FRAC_CONST(0.00383142), FRAC_CONST(0.000971817), FRAC_CONST(0.000243843), FRAC_CONST(6.10165E-005) }, { FRAC_CONST(0.111087), FRAC_CONST(0.111015), FRAC_CONST(0.110727), FRAC_CONST(0.109589), FRAC_CONST(0.105263), FRAC_CONST(0.0909091), FRAC_CONST(0.0588235), FRAC_CONST(0.0243902), FRAC_CONST(0.00729927), FRAC_CONST(0.00191939), FRAC_CONST(0.000486145), FRAC_CONST(0.000121936), FRAC_CONST(3.05092E-005) }, { FRAC_CONST(0.05881), FRAC_CONST(0.0587695), FRAC_CONST(0.0586081), FRAC_CONST(0.057971), FRAC_CONST(0.0555556), FRAC_CONST(0.047619), FRAC_CONST(0.030303), FRAC_CONST(0.0123457), FRAC_CONST(0.003663), FRAC_CONST(0.000960615), FRAC_CONST(0.000243132), FRAC_CONST(6.09719E-005), FRAC_CONST(1.52548E-005) }, { FRAC_CONST(0.0302959), FRAC_CONST(0.0302744), FRAC_CONST(0.0301887), FRAC_CONST(0.0298507), FRAC_CONST(0.0285714), FRAC_CONST(0.0243902), FRAC_CONST(0.0153846), FRAC_CONST(0.00621118), FRAC_CONST(0.00183486), FRAC_CONST(0.000480538), FRAC_CONST(0.000121581), FRAC_CONST(3.04869E-005), FRAC_CONST(7.62747E-006) }, { FRAC_CONST(0.0153809), FRAC_CONST(0.0153698), FRAC_CONST(0.0153257), FRAC_CONST(0.0151515), FRAC_CONST(0.0144928), FRAC_CONST(0.0123457), FRAC_CONST(0.00775194), FRAC_CONST(0.00311526), FRAC_CONST(0.000918274), FRAC_CONST(0.000240327), FRAC_CONST(6.0794E-005), FRAC_CONST(1.52437E-005), FRAC_CONST(3.81375E-006) }, { FRAC_CONST(0.00775006), FRAC_CONST(0.00774443), FRAC_CONST(0.00772201), FRAC_CONST(0.00763359), FRAC_CONST(0.00729927), FRAC_CONST(0.00621118), FRAC_CONST(0.00389105), FRAC_CONST(0.00156006), FRAC_CONST(0.000459348), FRAC_CONST(0.000120178), FRAC_CONST(3.03979E-005), FRAC_CONST(7.62189E-006), FRAC_CONST(1.90688E-006) }, { FRAC_CONST(0.0038901), FRAC_CONST(0.00388727), FRAC_CONST(0.00387597), FRAC_CONST(0.00383142), FRAC_CONST(0.003663), FRAC_CONST(0.00311526), FRAC_CONST(0.00194932), FRAC_CONST(0.00078064), FRAC_CONST(0.000229727), FRAC_CONST(6.00925E-005), FRAC_CONST(1.51992E-005), FRAC_CONST(3.81096E-006), FRAC_CONST(9.53441E-007) }, { FRAC_CONST(0.00194884), FRAC_CONST(0.00194742), FRAC_CONST(0.00194175), FRAC_CONST(0.00191939), FRAC_CONST(0.00183486), FRAC_CONST(0.00156006), FRAC_CONST(0.00097561), FRAC_CONST(0.000390472), FRAC_CONST(0.000114877), FRAC_CONST(3.00472E-005), FRAC_CONST(7.59965E-006), FRAC_CONST(1.90548E-006), FRAC_CONST(4.76721E-007) }, { FRAC_CONST(0.000975372), FRAC_CONST(0.000974659), FRAC_CONST(0.000971817), FRAC_CONST(0.000960615), FRAC_CONST(0.000918274), FRAC_CONST(0.00078064), FRAC_CONST(0.000488043), FRAC_CONST(0.000195274), FRAC_CONST(5.74416E-005), FRAC_CONST(1.50238E-005), FRAC_CONST(3.79984E-006), FRAC_CONST(9.52743E-007), FRAC_CONST(2.3836E-007) }, { FRAC_CONST(0.000487924), FRAC_CONST(0.000487567), FRAC_CONST(0.000486145), FRAC_CONST(0.000480538), FRAC_CONST(0.000459348), FRAC_CONST(0.000390472), FRAC_CONST(0.000244081), FRAC_CONST(9.76467E-005), FRAC_CONST(2.87216E-005), FRAC_CONST(7.51196E-006), FRAC_CONST(1.89992E-006), FRAC_CONST(4.76372E-007), FRAC_CONST(1.1918E-007) }, { FRAC_CONST(0.000244021), FRAC_CONST(0.000243843), FRAC_CONST(0.000243132), FRAC_CONST(0.000240327), FRAC_CONST(0.000229727), FRAC_CONST(0.000195274), FRAC_CONST(0.000122055), FRAC_CONST(4.88257E-005), FRAC_CONST(1.4361E-005), FRAC_CONST(3.756E-006), FRAC_CONST(9.49963E-007), FRAC_CONST(2.38186E-007), FRAC_CONST(5.95901E-008) }, { FRAC_CONST(0.000122026), FRAC_CONST(0.000121936), FRAC_CONST(0.000121581), FRAC_CONST(0.000120178), FRAC_CONST(0.000114877), FRAC_CONST(9.76467E-005), FRAC_CONST(6.10314E-005), FRAC_CONST(2.44135E-005), FRAC_CONST(7.18056E-006), FRAC_CONST(1.878E-006), FRAC_CONST(4.74982E-007), FRAC_CONST(1.19093E-007), FRAC_CONST(2.9795E-008) }, { FRAC_CONST(6.10165E-005), FRAC_CONST(6.09719E-005), FRAC_CONST(6.0794E-005), FRAC_CONST(6.00925E-005), FRAC_CONST(5.74416E-005), FRAC_CONST(4.88257E-005), FRAC_CONST(3.05166E-005), FRAC_CONST(1.22069E-005), FRAC_CONST(3.59029E-006), FRAC_CONST(9.39002E-007), FRAC_CONST(2.37491E-007), FRAC_CONST(5.95465E-008), FRAC_CONST(1.48975E-008) }, { FRAC_CONST(3.05092E-005), FRAC_CONST(3.04869E-005), FRAC_CONST(3.03979E-005), FRAC_CONST(3.00472E-005), FRAC_CONST(2.87216E-005), FRAC_CONST(2.44135E-005), FRAC_CONST(1.52586E-005), FRAC_CONST(6.10348E-006), FRAC_CONST(1.79515E-006), FRAC_CONST(4.69501E-007), FRAC_CONST(1.18745E-007), FRAC_CONST(2.97732E-008), FRAC_CONST(7.44876E-009) }, { FRAC_CONST(1.52548E-005), FRAC_CONST(1.52437E-005), FRAC_CONST(1.51992E-005), FRAC_CONST(1.50238E-005), FRAC_CONST(1.4361E-005), FRAC_CONST(1.22069E-005), FRAC_CONST(7.62934E-006), FRAC_CONST(3.05175E-006), FRAC_CONST(8.97575E-007), FRAC_CONST(2.34751E-007), FRAC_CONST(5.93727E-008), FRAC_CONST(1.48866E-008), FRAC_CONST(3.72438E-009) }, { FRAC_CONST(7.62747E-006), FRAC_CONST(7.62189E-006), FRAC_CONST(7.59965E-006), FRAC_CONST(7.51196E-006), FRAC_CONST(7.18056E-006), FRAC_CONST(6.10348E-006), FRAC_CONST(3.81468E-006), FRAC_CONST(1.52588E-006), FRAC_CONST(4.48788E-007), FRAC_CONST(1.17375E-007), FRAC_CONST(2.96864E-008), FRAC_CONST(7.44331E-009), FRAC_CONST(1.86219E-009) }, { FRAC_CONST(3.81375E-006), FRAC_CONST(3.81096E-006), FRAC_CONST(3.79984E-006), FRAC_CONST(3.756E-006), FRAC_CONST(3.59029E-006), FRAC_CONST(3.05175E-006), FRAC_CONST(1.90734E-006), FRAC_CONST(7.62939E-007), FRAC_CONST(2.24394E-007), FRAC_CONST(5.86876E-008), FRAC_CONST(1.48432E-008), FRAC_CONST(3.72166E-009), FRAC_CONST(9.31095E-010) }, { FRAC_CONST(1.90688E-006), FRAC_CONST(1.90548E-006), FRAC_CONST(1.89992E-006), FRAC_CONST(1.878E-006), FRAC_CONST(1.79515E-006), FRAC_CONST(1.52588E-006), FRAC_CONST(9.53673E-007), FRAC_CONST(3.8147E-007), FRAC_CONST(1.12197E-007), FRAC_CONST(2.93438E-008), FRAC_CONST(7.42159E-009), FRAC_CONST(1.86083E-009), FRAC_CONST(4.65548E-010) }, { FRAC_CONST(9.53441E-007), FRAC_CONST(9.52743E-007), FRAC_CONST(9.49963E-007), FRAC_CONST(9.39002E-007), FRAC_CONST(8.97575E-007), FRAC_CONST(7.62939E-007), FRAC_CONST(4.76837E-007), FRAC_CONST(1.90735E-007), FRAC_CONST(5.60985E-008), FRAC_CONST(1.46719E-008), FRAC_CONST(3.71079E-009), FRAC_CONST(9.30414E-010), FRAC_CONST(2.32774E-010) }, { FRAC_CONST(4.76721E-007), FRAC_CONST(4.76372E-007), FRAC_CONST(4.74982E-007), FRAC_CONST(4.69501E-007), FRAC_CONST(4.48788E-007), FRAC_CONST(3.8147E-007), FRAC_CONST(2.38419E-007), FRAC_CONST(9.53674E-008), FRAC_CONST(2.80492E-008), FRAC_CONST(7.33596E-009), FRAC_CONST(1.8554E-009), FRAC_CONST(4.65207E-010), FRAC_CONST(1.16387E-010) }, { FRAC_CONST(2.3836E-007), FRAC_CONST(2.38186E-007), FRAC_CONST(2.37491E-007), FRAC_CONST(2.34751E-007), FRAC_CONST(2.24394E-007), FRAC_CONST(1.90735E-007), FRAC_CONST(1.19209E-007), FRAC_CONST(4.76837E-008), FRAC_CONST(1.40246E-008), FRAC_CONST(3.66798E-009), FRAC_CONST(9.27699E-010), FRAC_CONST(2.32603E-010), FRAC_CONST(5.81935E-011) }, { FRAC_CONST(1.1918E-007), FRAC_CONST(1.19093E-007), FRAC_CONST(1.18745E-007), FRAC_CONST(1.17375E-007), FRAC_CONST(1.12197E-007), FRAC_CONST(9.53674E-008), FRAC_CONST(5.96046E-008), FRAC_CONST(2.38419E-008), FRAC_CONST(7.01231E-009), FRAC_CONST(1.83399E-009), FRAC_CONST(4.63849E-010), FRAC_CONST(1.16302E-010), FRAC_CONST(2.90967E-011) } }; /* calculates Q/(1+Q) */ /* [0..1] */ static real_t calc_Q_div2(sbr_info *sbr, uint8_t ch, uint8_t m, uint8_t l) { if (sbr->bs_coupling) { if ((sbr->Q[0][m][l] < 0 || sbr->Q[0][m][l] > 30) || (sbr->Q[1][m][l] < 0 || sbr->Q[1][m][l] > 24 /* 2*panOffset(1) */)) { return 0; } else { /* the pan parameter is always even */ if (ch == 0) { return Q_div2_tab_left[sbr->Q[0][m][l]][sbr->Q[1][m][l] >> 1]; } else { return Q_div2_tab_right[sbr->Q[0][m][l]][sbr->Q[1][m][l] >> 1]; } } } else { /* no coupling */ if (sbr->Q[ch][m][l] < 0 || sbr->Q[ch][m][l] > 30) { return 0; } else { return Q_div2_tab[sbr->Q[ch][m][l]]; } } } static const real_t E_deq_tab[64] = { 64.0f, 128.0f, 256.0f, 512.0f, 1024.0f, 2048.0f, 4096.0f, 8192.0f, 16384.0f, 32768.0f, 65536.0f, 131072.0f, 262144.0f, 524288.0f, 1.04858E+006f, 2.09715E+006f, 4.1943E+006f, 8.38861E+006f, 1.67772E+007f, 3.35544E+007f, 6.71089E+007f, 1.34218E+008f, 2.68435E+008f, 5.36871E+008f, 1.07374E+009f, 2.14748E+009f, 4.29497E+009f, 8.58993E+009f, 1.71799E+010f, 3.43597E+010f, 6.87195E+010f, 1.37439E+011f, 2.74878E+011f, 5.49756E+011f, 1.09951E+012f, 2.19902E+012f, 4.39805E+012f, 8.79609E+012f, 1.75922E+013f, 3.51844E+013f, 7.03687E+013f, 1.40737E+014f, 2.81475E+014f, 5.6295E+014f, 1.1259E+015f, 2.2518E+015f, 4.5036E+015f, 9.0072E+015f, 1.80144E+016f, 3.60288E+016f, 7.20576E+016f, 1.44115E+017f, 2.8823E+017f, 5.76461E+017f, 1.15292E+018f, 2.30584E+018f, 4.61169E+018f, 9.22337E+018f, 1.84467E+019f, 3.68935E+019f, 7.3787E+019f, 1.47574E+020f, 2.95148E+020f, 5.90296E+020f }; void envelope_noise_dequantisation(sbr_info *sbr, uint8_t ch) { if (sbr->bs_coupling == 0) { int16_t exp; uint8_t l, k; uint8_t amp = (sbr->amp_res[ch]) ? 0 : 1; for (l = 0; l < sbr->L_E[ch]; l++) { for (k = 0; k < sbr->n[sbr->f[ch][l]]; k++) { /* +6 for the *64 and -10 for the /32 in the synthesis QMF (fixed) * since this is a energy value: (x/32)^2 = (x^2)/1024 */ /* exp = (sbr->E[ch][k][l] >> amp) + 6; */ exp = (sbr->E[ch][k][l] >> amp); if ((exp < 0) || (exp >= 64)) { sbr->E_orig[ch][k][l] = 0; } else { sbr->E_orig[ch][k][l] = E_deq_tab[exp]; /* save half the table size at the cost of 1 multiply */ if (amp && (sbr->E[ch][k][l] & 1)) { sbr->E_orig[ch][k][l] = MUL_C(sbr->E_orig[ch][k][l], COEF_CONST(1.414213562)); } } } } for (l = 0; l < sbr->L_Q[ch]; l++) { for (k = 0; k < sbr->N_Q; k++) { sbr->Q_div[ch][k][l] = calc_Q_div(sbr, ch, k, l); sbr->Q_div2[ch][k][l] = calc_Q_div2(sbr, ch, k, l); } } } } static const real_t E_pan_tab[25] = { FRAC_CONST(0.000244081), FRAC_CONST(0.000488043), FRAC_CONST(0.00097561), FRAC_CONST(0.00194932), FRAC_CONST(0.00389105), FRAC_CONST(0.00775194), FRAC_CONST(0.0153846), FRAC_CONST(0.030303), FRAC_CONST(0.0588235), FRAC_CONST(0.111111), FRAC_CONST(0.2), FRAC_CONST(0.333333), FRAC_CONST(0.5), FRAC_CONST(0.666667), FRAC_CONST(0.8), FRAC_CONST(0.888889), FRAC_CONST(0.941176), FRAC_CONST(0.969697), FRAC_CONST(0.984615), FRAC_CONST(0.992248), FRAC_CONST(0.996109), FRAC_CONST(0.998051), FRAC_CONST(0.999024), FRAC_CONST(0.999512), FRAC_CONST(0.999756) }; void unmap_envelope_noise(sbr_info *sbr) { real_t tmp; int16_t exp0, exp1; uint8_t l, k; uint8_t amp0 = (sbr->amp_res[0]) ? 0 : 1; uint8_t amp1 = (sbr->amp_res[1]) ? 0 : 1; for (l = 0; l < sbr->L_E[0]; l++) { for (k = 0; k < sbr->n[sbr->f[0][l]]; k++) { /* +6: * 64 ; +1: * 2 ; */ exp0 = (sbr->E[0][k][l] >> amp0) + 1; /* UN_MAP removed: (x / 4096) same as (x >> 12) */ /* E[1] is always even so no need for compensating the divide by 2 with * an extra multiplication */ /* exp1 = (sbr->E[1][k][l] >> amp1) - 12; */ exp1 = (sbr->E[1][k][l] >> amp1); if ((exp0 < 0) || (exp0 >= 64) || (exp1 < 0) || (exp1 > 24)) { sbr->E_orig[1][k][l] = 0; sbr->E_orig[0][k][l] = 0; } else { tmp = E_deq_tab[exp0]; if (amp0 && (sbr->E[0][k][l] & 1)) { tmp = MUL_C(tmp, COEF_CONST(1.414213562)); } /* panning */ sbr->E_orig[0][k][l] = MUL_F(tmp, E_pan_tab[exp1]); sbr->E_orig[1][k][l] = MUL_F(tmp, E_pan_tab[24 - exp1]); } } } for (l = 0; l < sbr->L_Q[0]; l++) { for (k = 0; k < sbr->N_Q; k++) { sbr->Q_div[0][k][l] = calc_Q_div(sbr, 0, k, l); sbr->Q_div[1][k][l] = calc_Q_div(sbr, 1, k, l); sbr->Q_div2[0][k][l] = calc_Q_div2(sbr, 0, k, l); sbr->Q_div2[1][k][l] = calc_Q_div2(sbr, 1, k, l); } } } #endif #endif xine-lib-1.2/contrib/libfaad/drm_dec.h0000644000175000017500000000572214647725152015462 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: drm_dec.h,v 1.8 2007/11/01 12:33:30 menno Exp $ **/ #ifndef __DRM_DEC_H__ #define __DRM_DEC_H__ #ifdef __cplusplus extern "C" { #endif #include "bits.h" #define DRM_PARAMETRIC_STEREO 0 #define DRM_NUM_SA_BANDS 8 #define DRM_NUM_PAN_BANDS 20 #define NUM_OF_LINKS 3 #define NUM_OF_QMF_CHANNELS 64 #define NUM_OF_SUBSAMPLES 30 #define MAX_SA_BAND 46 #define MAX_PAN_BAND 64 #define MAX_DELAY 5 typedef struct { uint8_t drm_ps_data_available; uint8_t bs_enable_sa; uint8_t bs_enable_pan; uint8_t bs_sa_dt_flag; uint8_t bs_pan_dt_flag; uint8_t g_last_had_sa; uint8_t g_last_had_pan; int8_t bs_sa_data[DRM_NUM_SA_BANDS]; int8_t bs_pan_data[DRM_NUM_PAN_BANDS]; int8_t g_sa_index[DRM_NUM_SA_BANDS]; int8_t g_pan_index[DRM_NUM_PAN_BANDS]; int8_t g_prev_sa_index[DRM_NUM_SA_BANDS]; int8_t g_prev_pan_index[DRM_NUM_PAN_BANDS]; int8_t sa_decode_error; int8_t pan_decode_error; int8_t g_last_good_sa_index[DRM_NUM_SA_BANDS]; int8_t g_last_good_pan_index[DRM_NUM_PAN_BANDS]; qmf_t SA[NUM_OF_SUBSAMPLES][MAX_SA_BAND]; complex_t d_buff[2][MAX_SA_BAND]; complex_t d2_buff[NUM_OF_LINKS][MAX_DELAY][MAX_SA_BAND]; uint8_t delay_buf_index_ser[NUM_OF_LINKS]; real_t prev_nrg[MAX_SA_BAND]; real_t prev_peakdiff[MAX_SA_BAND]; real_t peakdecay_fast[MAX_SA_BAND]; } drm_ps_info; uint16_t drm_ps_data(drm_ps_info *ps, bitfile *ld); drm_ps_info *drm_ps_init(void); void drm_ps_free(drm_ps_info *ps); uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, qmf_t X_left[38][64], qmf_t X_right[38][64]); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_dec.h0000644000175000017500000001441514647725152015465 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_dec.h,v 1.39 2007/11/01 12:33:34 menno Exp $ **/ #ifndef __SBR_DEC_H__ #define __SBR_DEC_H__ #ifdef __cplusplus extern "C" { #endif #ifdef PS_DEC #include "ps_dec.h" #endif #ifdef DRM_PS #include "drm_dec.h" #endif /* MAX_NTSRHFG: maximum of number_time_slots * rate + HFGen. 16*2+8 */ #define MAX_NTSRHFG 40 #define MAX_NTSR 32 /* max number_time_slots * rate, ok for DRM and not DRM mode */ /* MAX_M: maximum value for M */ #define MAX_M 49 /* MAX_L_E: maximum value for L_E */ #define MAX_L_E 5 typedef struct { real_t *x; int16_t x_index; uint8_t channels; } qmfa_info; typedef struct { real_t *v; int16_t v_index; uint8_t channels; } qmfs_info; typedef struct { uint32_t sample_rate; uint32_t maxAACLine; uint8_t rate; uint8_t just_seeked; uint8_t ret; uint8_t amp_res[2]; uint8_t k0; uint8_t kx; uint8_t M; uint8_t N_master; uint8_t N_high; uint8_t N_low; uint8_t N_Q; uint8_t N_L[4]; uint8_t n[2]; uint8_t f_master[64]; uint8_t f_table_res[2][64]; uint8_t f_table_noise[64]; uint8_t f_table_lim[4][64]; #ifdef SBR_LOW_POWER uint8_t f_group[5][64]; uint8_t N_G[5]; #endif uint8_t table_map_k_to_g[64]; uint8_t abs_bord_lead[2]; uint8_t abs_bord_trail[2]; uint8_t n_rel_lead[2]; uint8_t n_rel_trail[2]; uint8_t L_E[2]; uint8_t L_E_prev[2]; uint8_t L_Q[2]; uint8_t t_E[2][MAX_L_E+1]; uint8_t t_Q[2][3]; uint8_t f[2][MAX_L_E+1]; uint8_t f_prev[2]; real_t *G_temp_prev[2][5]; real_t *Q_temp_prev[2][5]; int8_t GQ_ringbuf_index[2]; int16_t E[2][64][MAX_L_E]; int16_t E_prev[2][64]; #ifndef FIXED_POINT real_t E_orig[2][64][MAX_L_E]; #endif real_t E_curr[2][64][MAX_L_E]; int32_t Q[2][64][2]; #ifndef FIXED_POINT real_t Q_div[2][64][2]; real_t Q_div2[2][64][2]; #endif int32_t Q_prev[2][64]; int8_t l_A[2]; int8_t l_A_prev[2]; uint8_t bs_invf_mode[2][MAX_L_E]; uint8_t bs_invf_mode_prev[2][MAX_L_E]; real_t bwArray[2][64]; real_t bwArray_prev[2][64]; uint8_t noPatches; uint8_t patchNoSubbands[64]; uint8_t patchStartSubband[64]; uint8_t bs_add_harmonic[2][64]; uint8_t bs_add_harmonic_prev[2][64]; uint16_t index_noise_prev[2]; uint8_t psi_is_prev[2]; uint8_t bs_start_freq_prev; uint8_t bs_stop_freq_prev; uint8_t bs_xover_band_prev; uint8_t bs_freq_scale_prev; uint8_t bs_alter_scale_prev; uint8_t bs_noise_bands_prev; int8_t prevEnvIsShort[2]; int8_t kx_prev; uint8_t bsco; uint8_t bsco_prev; uint8_t M_prev; uint16_t frame_len; uint8_t Reset; uint32_t frame; uint32_t header_count; uint8_t id_aac; qmfa_info *qmfa[2]; qmfs_info *qmfs[2]; qmf_t Xsbr[2][MAX_NTSRHFG][64]; #ifdef DRM uint8_t Is_DRM_SBR; #ifdef DRM_PS drm_ps_info *drm_ps; #endif #endif uint8_t numTimeSlotsRate; uint8_t numTimeSlots; uint8_t tHFGen; uint8_t tHFAdj; #ifdef PS_DEC ps_info *ps; #endif #if (defined(PS_DEC) || defined(DRM_PS)) uint8_t ps_used; uint8_t psResetFlag; #endif /* to get it compiling */ /* we'll see during the coding of all the tools, whether these are all used or not. */ uint8_t bs_header_flag; uint8_t bs_crc_flag; uint16_t bs_sbr_crc_bits; uint8_t bs_protocol_version; uint8_t bs_amp_res; uint8_t bs_start_freq; uint8_t bs_stop_freq; uint8_t bs_xover_band; uint8_t bs_freq_scale; uint8_t bs_alter_scale; uint8_t bs_noise_bands; uint8_t bs_limiter_bands; uint8_t bs_limiter_gains; uint8_t bs_interpol_freq; uint8_t bs_smoothing_mode; uint8_t bs_samplerate_mode; uint8_t bs_add_harmonic_flag[2]; uint8_t bs_add_harmonic_flag_prev[2]; uint8_t bs_extended_data; uint8_t bs_extension_id; uint8_t bs_extension_data; uint8_t bs_coupling; uint8_t bs_frame_class[2]; uint8_t bs_rel_bord[2][9]; uint8_t bs_rel_bord_0[2][9]; uint8_t bs_rel_bord_1[2][9]; uint8_t bs_pointer[2]; uint8_t bs_abs_bord_0[2]; uint8_t bs_abs_bord_1[2]; uint8_t bs_num_rel_0[2]; uint8_t bs_num_rel_1[2]; uint8_t bs_df_env[2][9]; uint8_t bs_df_noise[2][3]; } sbr_info; sbr_info *sbrDecodeInit(uint16_t framelength, uint8_t id_aac, uint32_t sample_rate, uint8_t downSampledSBR #ifdef DRM , uint8_t IsDRM #endif ); void sbrDecodeEnd(sbr_info *sbr); void sbrReset(sbr_info *sbr); uint8_t sbrDecodeCoupleFrame(sbr_info *sbr, real_t *left_chan, real_t *right_chan, const uint8_t just_seeked, const uint8_t downSampledSBR); uint8_t sbrDecodeSingleFrame(sbr_info *sbr, real_t *channel, const uint8_t just_seeked, const uint8_t downSampledSBR); #if (defined(PS_DEC) || defined(DRM_PS)) uint8_t sbrDecodeSingleFramePS(sbr_info *sbr, real_t *left_channel, real_t *right_channel, const uint8_t just_seeked, const uint8_t downSampledSBR); #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_noise.h0000644000175000017500000011006114647725152016041 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_noise.h,v 1.17 2007/11/01 12:33:35 menno Exp $ **/ #ifndef __SBR_NOISE_H__ #define __SBR_NOISE_H__ #ifdef __cplusplus extern "C" { #endif #ifdef _MSC_VER #pragma warning(disable:4305) #pragma warning(disable:4244) #endif /* Table 1.A.13 Noise table V */ ALIGN static const complex_t V[] = { { FRAC_CONST(-0.99948155879974), FRAC_CONST(-0.59483414888382) }, { FRAC_CONST(0.97113454341888), FRAC_CONST(-0.67528516054153) }, { FRAC_CONST(0.14130051434040), FRAC_CONST(-0.95090985298157) }, { FRAC_CONST(-0.47005495429039), FRAC_CONST(-0.37340548634529) }, { FRAC_CONST(0.80705064535141), FRAC_CONST(0.29653668403625) }, { FRAC_CONST(-0.38981479406357), FRAC_CONST(0.89572608470917) }, { FRAC_CONST(-0.01053049881011), FRAC_CONST(-0.66959059238434) }, { FRAC_CONST(-0.91266369819641), FRAC_CONST(-0.11522938311100) }, { FRAC_CONST(0.54840421676636), FRAC_CONST(0.75221365690231) }, { FRAC_CONST(0.40009254217148), FRAC_CONST(-0.98929399251938) }, { FRAC_CONST(-0.99867975711823), FRAC_CONST(-0.88147068023682) }, { FRAC_CONST(-0.95531076192856), FRAC_CONST(0.90908759832382) }, { FRAC_CONST(-0.45725932717323), FRAC_CONST(-0.56716322898865) }, { FRAC_CONST(-0.72929674386978), FRAC_CONST(-0.98008275032043) }, { FRAC_CONST(0.75622802972794), FRAC_CONST(0.20950329303741) }, { FRAC_CONST(0.07069442421198), FRAC_CONST(-0.78247898817062) }, { FRAC_CONST(0.74496251344681), FRAC_CONST(-0.91169005632401) }, { FRAC_CONST(-0.96440184116364), FRAC_CONST(-0.94739919900894) }, { FRAC_CONST(0.30424630641937), FRAC_CONST(-0.49438267946243) }, { FRAC_CONST(0.66565030813217), FRAC_CONST(0.64652937650681) }, { FRAC_CONST(0.91697007417679), FRAC_CONST(0.17514097690582) }, { FRAC_CONST(-0.70774918794632), FRAC_CONST(0.52548652887344) }, { FRAC_CONST(-0.70051413774490), FRAC_CONST(-0.45340028405190) }, { FRAC_CONST(-0.99496513605118), FRAC_CONST(-0.90071910619736) }, { FRAC_CONST(0.98164492845535), FRAC_CONST(-0.77463155984879) }, { FRAC_CONST(-0.54671579599380), FRAC_CONST(-0.02570928446949) }, { FRAC_CONST(-0.01689629070461), FRAC_CONST(0.00287506449968) }, { FRAC_CONST(-0.86110347509384), FRAC_CONST(0.42548584938049) }, { FRAC_CONST(-0.98892980813980), FRAC_CONST(-0.87881129980087) }, { FRAC_CONST(0.51756626367569), FRAC_CONST(0.66926783323288) }, { FRAC_CONST(-0.99635028839111), FRAC_CONST(-0.58107727766037) }, { FRAC_CONST(-0.99969369173050), FRAC_CONST(0.98369991779327) }, { FRAC_CONST(0.55266261100769), FRAC_CONST(0.59449058771133) }, { FRAC_CONST(0.34581178426743), FRAC_CONST(0.94879418611526) }, { FRAC_CONST(0.62664210796356), FRAC_CONST(-0.74402970075607) }, { FRAC_CONST(-0.77149701118469), FRAC_CONST(-0.33883658051491) }, { FRAC_CONST(-0.91592246294022), FRAC_CONST(0.03687901422381) }, { FRAC_CONST(-0.76285493373871), FRAC_CONST(-0.91371870040894) }, { FRAC_CONST(0.79788339138031), FRAC_CONST(-0.93180972337723) }, { FRAC_CONST(0.54473078250885), FRAC_CONST(-0.11919206380844) }, { FRAC_CONST(-0.85639280080795), FRAC_CONST(0.42429855465889) }, { FRAC_CONST(-0.92882400751114), FRAC_CONST(0.27871808409691) }, { FRAC_CONST(-0.11708371341228), FRAC_CONST(-0.99800843000412) }, { FRAC_CONST(0.21356749534607), FRAC_CONST(-0.90716296434402) }, { FRAC_CONST(-0.76191693544388), FRAC_CONST(0.99768120050430) }, { FRAC_CONST(0.98111045360565), FRAC_CONST(-0.95854461193085) }, { FRAC_CONST(-0.85913270711899), FRAC_CONST(0.95766568183899) }, { FRAC_CONST(-0.93307244777679), FRAC_CONST(0.49431759119034) }, { FRAC_CONST(0.30485755205154), FRAC_CONST(-0.70540034770966) }, { FRAC_CONST(0.85289651155472), FRAC_CONST(0.46766132116318) }, { FRAC_CONST(0.91328084468842), FRAC_CONST(-0.99839597940445) }, { FRAC_CONST(-0.05890199914575), FRAC_CONST(0.70741826295853) }, { FRAC_CONST(0.28398686647415), FRAC_CONST(0.34633556008339) }, { FRAC_CONST(0.95258164405823), FRAC_CONST(-0.54893416166306) }, { FRAC_CONST(-0.78566324710846), FRAC_CONST(-0.75568538904190) }, { FRAC_CONST(-0.95789498090744), FRAC_CONST(-0.20423194766045) }, { FRAC_CONST(0.82411158084869), FRAC_CONST(0.96654617786407) }, { FRAC_CONST(-0.65185445547104), FRAC_CONST(-0.88734990358353) }, { FRAC_CONST(-0.93643605709076), FRAC_CONST(0.99870789051056) }, { FRAC_CONST(0.91427159309387), FRAC_CONST(-0.98290503025055) }, { FRAC_CONST(-0.70395684242249), FRAC_CONST(0.58796799182892) }, { FRAC_CONST(0.00563771976158), FRAC_CONST(0.61768198013306) }, { FRAC_CONST(0.89065051078796), FRAC_CONST(0.52783352136612) }, { FRAC_CONST(-0.68683707714081), FRAC_CONST(0.80806946754456) }, { FRAC_CONST(0.72165340185165), FRAC_CONST(-0.69259858131409) }, { FRAC_CONST(-0.62928247451782), FRAC_CONST(0.13627037405968) }, { FRAC_CONST(0.29938435554504), FRAC_CONST(-0.46051329374313) }, { FRAC_CONST(-0.91781955957413), FRAC_CONST(-0.74012714624405) }, { FRAC_CONST(0.99298715591431), FRAC_CONST(0.40816611051559) }, { FRAC_CONST(0.82368296384811), FRAC_CONST(-0.74036049842834) }, { FRAC_CONST(-0.98512834310532), FRAC_CONST(-0.99972331523895) }, { FRAC_CONST(-0.95915371179581), FRAC_CONST(-0.99237799644470) }, { FRAC_CONST(-0.21411126852036), FRAC_CONST(-0.93424820899963) }, { FRAC_CONST(-0.68821477890015), FRAC_CONST(-0.26892307400703) }, { FRAC_CONST(0.91851997375488), FRAC_CONST(0.09358228743076) }, { FRAC_CONST(-0.96062767505646), FRAC_CONST(0.36099094152451) }, { FRAC_CONST(0.51646184921265), FRAC_CONST(-0.71373331546783) }, { FRAC_CONST(0.61130720376968), FRAC_CONST(0.46950140595436) }, { FRAC_CONST(0.47336128354073), FRAC_CONST(-0.27333179116249) }, { FRAC_CONST(0.90998309850693), FRAC_CONST(0.96715664863586) }, { FRAC_CONST(0.44844800233841), FRAC_CONST(0.99211573600769) }, { FRAC_CONST(0.66614890098572), FRAC_CONST(0.96590173244476) }, { FRAC_CONST(0.74922239780426), FRAC_CONST(-0.89879858493805) }, { FRAC_CONST(-0.99571585655212), FRAC_CONST(0.52785521745682) }, { FRAC_CONST(0.97401082515717), FRAC_CONST(-0.16855870187283) }, { FRAC_CONST(0.72683745622635), FRAC_CONST(-0.48060774803162) }, { FRAC_CONST(0.95432192087173), FRAC_CONST(0.68849605321884) }, { FRAC_CONST(-0.72962206602097), FRAC_CONST(-0.76608443260193) }, { FRAC_CONST(-0.85359477996826), FRAC_CONST(0.88738125562668) }, { FRAC_CONST(-0.81412428617477), FRAC_CONST(-0.97480767965317) }, { FRAC_CONST(-0.87930774688721), FRAC_CONST(0.74748307466507) }, { FRAC_CONST(-0.71573328971863), FRAC_CONST(-0.98570609092712) }, { FRAC_CONST(0.83524298667908), FRAC_CONST(0.83702534437180) }, { FRAC_CONST(-0.48086065053940), FRAC_CONST(-0.98848503828049) }, { FRAC_CONST(0.97139126062393), FRAC_CONST(0.80093622207642) }, { FRAC_CONST(0.51992827653885), FRAC_CONST(0.80247628688812) }, { FRAC_CONST(-0.00848591234535), FRAC_CONST(-0.76670128107071) }, { FRAC_CONST(-0.70294374227524), FRAC_CONST(0.55359911918640) }, { FRAC_CONST(-0.95894426107407), FRAC_CONST(-0.43265503644943) }, { FRAC_CONST(0.97079253196716), FRAC_CONST(0.09325857460499) }, { FRAC_CONST(-0.92404294013977), FRAC_CONST(0.85507702827454) }, { FRAC_CONST(-0.69506472349167), FRAC_CONST(0.98633414506912) }, { FRAC_CONST(0.26559203863144), FRAC_CONST(0.73314309120178) }, { FRAC_CONST(0.28038442134857), FRAC_CONST(0.14537914097309) }, { FRAC_CONST(-0.74138122797012), FRAC_CONST(0.99310338497162) }, { FRAC_CONST(-0.01752796024084), FRAC_CONST(-0.82616633176804) }, { FRAC_CONST(-0.55126774311066), FRAC_CONST(-0.98898541927338) }, { FRAC_CONST(0.97960901260376), FRAC_CONST(-0.94021445512772) }, { FRAC_CONST(-0.99196308851242), FRAC_CONST(0.67019015550613) }, { FRAC_CONST(-0.67684930562973), FRAC_CONST(0.12631492316723) }, { FRAC_CONST(0.09140039235353), FRAC_CONST(-0.20537731051445) }, { FRAC_CONST(-0.71658962965012), FRAC_CONST(-0.97788202762604) }, { FRAC_CONST(0.81014639139175), FRAC_CONST(0.53722649812698) }, { FRAC_CONST(0.40616992115974), FRAC_CONST(-0.26469007134438) }, { FRAC_CONST(-0.67680186033249), FRAC_CONST(0.94502049684525) }, { FRAC_CONST(0.86849772930145), FRAC_CONST(-0.18333598971367) }, { FRAC_CONST(-0.99500381946564), FRAC_CONST(-0.02634122036397) }, { FRAC_CONST(0.84329187870026), FRAC_CONST(0.10406957566738) }, { FRAC_CONST(-0.09215968847275), FRAC_CONST(0.69540011882782) }, { FRAC_CONST(0.99956172704697), FRAC_CONST(-0.12358541786671) }, { FRAC_CONST(-0.79732781648636), FRAC_CONST(-0.91582524776459) }, { FRAC_CONST(0.96349972486496), FRAC_CONST(0.96640455722809) }, { FRAC_CONST(-0.79942780733109), FRAC_CONST(0.64323902130127) }, { FRAC_CONST(-0.11566039919853), FRAC_CONST(0.28587844967842) }, { FRAC_CONST(-0.39922955632210), FRAC_CONST(0.94129604101181) }, { FRAC_CONST(0.99089199304581), FRAC_CONST(-0.92062628269196) }, { FRAC_CONST(0.28631284832954), FRAC_CONST(-0.91035044193268) }, { FRAC_CONST(-0.83302724361420), FRAC_CONST(-0.67330408096313) }, { FRAC_CONST(0.95404446125031), FRAC_CONST(0.49162766337395) }, { FRAC_CONST(-0.06449863314629), FRAC_CONST(0.03250560909510) }, { FRAC_CONST(-0.99575054645538), FRAC_CONST(0.42389783263206) }, { FRAC_CONST(-0.65501141548157), FRAC_CONST(0.82546114921570) }, { FRAC_CONST(-0.81254440546036), FRAC_CONST(-0.51627236604691) }, { FRAC_CONST(-0.99646371603012), FRAC_CONST(0.84490531682968) }, { FRAC_CONST(0.00287840608507), FRAC_CONST(0.64768260717392) }, { FRAC_CONST(0.70176988840103), FRAC_CONST(-0.20453028380871) }, { FRAC_CONST(0.96361881494522), FRAC_CONST(0.40706968307495) }, { FRAC_CONST(-0.68883758783340), FRAC_CONST(0.91338956356049) }, { FRAC_CONST(-0.34875586628914), FRAC_CONST(0.71472293138504) }, { FRAC_CONST(0.91980081796646), FRAC_CONST(0.66507452726364) }, { FRAC_CONST(-0.99009048938751), FRAC_CONST(0.85868018865585) }, { FRAC_CONST(0.68865793943405), FRAC_CONST(0.55660319328308) }, { FRAC_CONST(-0.99484401941299), FRAC_CONST(-0.20052559673786) }, { FRAC_CONST(0.94214510917664), FRAC_CONST(-0.99696427583694) }, { FRAC_CONST(-0.67414629459381), FRAC_CONST(0.49548220634460) }, { FRAC_CONST(-0.47339352965355), FRAC_CONST(-0.85904330015182) }, { FRAC_CONST(0.14323651790619), FRAC_CONST(-0.94145596027374) }, { FRAC_CONST(-0.29268294572830), FRAC_CONST(0.05759225040674) }, { FRAC_CONST(0.43793860077858), FRAC_CONST(-0.78904968500137) }, { FRAC_CONST(-0.36345127224922), FRAC_CONST(0.64874434471130) }, { FRAC_CONST(-0.08750604838133), FRAC_CONST(0.97686946392059) }, { FRAC_CONST(-0.96495270729065), FRAC_CONST(-0.53960305452347) }, { FRAC_CONST(0.55526942014694), FRAC_CONST(0.78891521692276) }, { FRAC_CONST(0.73538213968277), FRAC_CONST(0.96452075242996) }, { FRAC_CONST(-0.30889773368835), FRAC_CONST(-0.80664390325546) }, { FRAC_CONST(0.03574995696545), FRAC_CONST(-0.97325617074966) }, { FRAC_CONST(0.98720687627792), FRAC_CONST(0.48409134149551) }, { FRAC_CONST(-0.81689298152924), FRAC_CONST(-0.90827703475952) }, { FRAC_CONST(0.67866861820221), FRAC_CONST(0.81284505128860) }, { FRAC_CONST(-0.15808570384979), FRAC_CONST(0.85279554128647) }, { FRAC_CONST(0.80723392963409), FRAC_CONST(-0.24717418849468) }, { FRAC_CONST(0.47788757085800), FRAC_CONST(-0.46333149075508) }, { FRAC_CONST(0.96367555856705), FRAC_CONST(0.38486748933792) }, { FRAC_CONST(-0.99143874645233), FRAC_CONST(-0.24945276975632) }, { FRAC_CONST(0.83081877231598), FRAC_CONST(-0.94780850410461) }, { FRAC_CONST(-0.58753192424774), FRAC_CONST(0.01290772389621) }, { FRAC_CONST(0.95538109540939), FRAC_CONST(-0.85557049512863) }, { FRAC_CONST(-0.96490919589996), FRAC_CONST(-0.64020973443985) }, { FRAC_CONST(-0.97327101230621), FRAC_CONST(0.12378127872944) }, { FRAC_CONST(0.91400367021561), FRAC_CONST(0.57972472906113) }, { FRAC_CONST(-0.99925839900970), FRAC_CONST(0.71084845066071) }, { FRAC_CONST(-0.86875903606415), FRAC_CONST(-0.20291699469090) }, { FRAC_CONST(-0.26240035891533), FRAC_CONST(-0.68264555931091) }, { FRAC_CONST(-0.24664412438869), FRAC_CONST(-0.87642270326614) }, { FRAC_CONST(0.02416275814176), FRAC_CONST(0.27192914485931) }, { FRAC_CONST(0.82068622112274), FRAC_CONST(-0.85087788105011) }, { FRAC_CONST(0.88547372817993), FRAC_CONST(-0.89636802673340) }, { FRAC_CONST(-0.18173077702522), FRAC_CONST(-0.26152145862579) }, { FRAC_CONST(0.09355476498604), FRAC_CONST(0.54845124483109) }, { FRAC_CONST(-0.54668414592743), FRAC_CONST(0.95980775356293) }, { FRAC_CONST(0.37050989270210), FRAC_CONST(-0.59910142421722) }, { FRAC_CONST(-0.70373594760895), FRAC_CONST(0.91227668523788) }, { FRAC_CONST(-0.34600785374641), FRAC_CONST(-0.99441426992416) }, { FRAC_CONST(-0.68774479627609), FRAC_CONST(-0.30238837003708) }, { FRAC_CONST(-0.26843291521072), FRAC_CONST(0.83115667104721) }, { FRAC_CONST(0.49072334170341), FRAC_CONST(-0.45359709858894) }, { FRAC_CONST(0.38975992798805), FRAC_CONST(0.95515358448029) }, { FRAC_CONST(-0.97757124900818), FRAC_CONST(0.05305894464254) }, { FRAC_CONST(-0.17325553297997), FRAC_CONST(-0.92770671844482) }, { FRAC_CONST(0.99948036670685), FRAC_CONST(0.58285546302795) }, { FRAC_CONST(-0.64946246147156), FRAC_CONST(0.68645507097244) }, { FRAC_CONST(-0.12016920745373), FRAC_CONST(-0.57147324085236) }, { FRAC_CONST(-0.58947455883026), FRAC_CONST(-0.34847131371498) }, { FRAC_CONST(-0.41815140843391), FRAC_CONST(0.16276422142982) }, { FRAC_CONST(0.99885648488998), FRAC_CONST(0.11136095225811) }, { FRAC_CONST(-0.56649613380432), FRAC_CONST(-0.90494865179062) }, { FRAC_CONST(0.94138020277023), FRAC_CONST(0.35281917452812) }, { FRAC_CONST(-0.75725078582764), FRAC_CONST(0.53650552034378) }, { FRAC_CONST(0.20541973412037), FRAC_CONST(-0.94435143470764) }, { FRAC_CONST(0.99980372190475), FRAC_CONST(0.79835915565491) }, { FRAC_CONST(0.29078277945518), FRAC_CONST(0.35393777489662) }, { FRAC_CONST(-0.62858772277832), FRAC_CONST(0.38765692710876) }, { FRAC_CONST(0.43440905213356), FRAC_CONST(-0.98546332120895) }, { FRAC_CONST(-0.98298585414886), FRAC_CONST(0.21021524071693) }, { FRAC_CONST(0.19513028860092), FRAC_CONST(-0.94239830970764) }, { FRAC_CONST(-0.95476663112640), FRAC_CONST(0.98364555835724) }, { FRAC_CONST(0.93379634618759), FRAC_CONST(-0.70881992578506) }, { FRAC_CONST(-0.85235410928726), FRAC_CONST(-0.08342348039150) }, { FRAC_CONST(-0.86425095796585), FRAC_CONST(-0.45795026421547) }, { FRAC_CONST(0.38879778981209), FRAC_CONST(0.97274428606033) }, { FRAC_CONST(0.92045122385025), FRAC_CONST(-0.62433654069901) }, { FRAC_CONST(0.89162534475327), FRAC_CONST(0.54950958490372) }, { FRAC_CONST(-0.36834338307381), FRAC_CONST(0.96458297967911) }, { FRAC_CONST(0.93891763687134), FRAC_CONST(-0.89968353509903) }, { FRAC_CONST(0.99267655611038), FRAC_CONST(-0.03757034242153) }, { FRAC_CONST(-0.94063472747803), FRAC_CONST(0.41332337260246) }, { FRAC_CONST(0.99740225076675), FRAC_CONST(-0.16830494999886) }, { FRAC_CONST(-0.35899412631989), FRAC_CONST(-0.46633225679398) }, { FRAC_CONST(0.05237237364054), FRAC_CONST(-0.25640362501144) }, { FRAC_CONST(0.36703583598137), FRAC_CONST(-0.38653266429901) }, { FRAC_CONST(0.91653180122375), FRAC_CONST(-0.30587628483772) }, { FRAC_CONST(0.69000804424286), FRAC_CONST(0.90952169895172) }, { FRAC_CONST(-0.38658750057220), FRAC_CONST(0.99501574039459) }, { FRAC_CONST(-0.29250815510750), FRAC_CONST(0.37444993853569) }, { FRAC_CONST(-0.60182201862335), FRAC_CONST(0.86779648065567) }, { FRAC_CONST(-0.97418588399887), FRAC_CONST(0.96468526124954) }, { FRAC_CONST(0.88461571931839), FRAC_CONST(0.57508403062820) }, { FRAC_CONST(0.05198933184147), FRAC_CONST(0.21269661188126) }, { FRAC_CONST(-0.53499621152878), FRAC_CONST(0.97241556644440) }, { FRAC_CONST(-0.49429559707642), FRAC_CONST(0.98183864355087) }, { FRAC_CONST(-0.98935145139694), FRAC_CONST(-0.40249159932137) }, { FRAC_CONST(-0.98081380128860), FRAC_CONST(-0.72856897115707) }, { FRAC_CONST(-0.27338150143623), FRAC_CONST(0.99950921535492) }, { FRAC_CONST(0.06310802698135), FRAC_CONST(-0.54539585113525) }, { FRAC_CONST(-0.20461677014828), FRAC_CONST(-0.14209978282452) }, { FRAC_CONST(0.66223841905594), FRAC_CONST(0.72528582811356) }, { FRAC_CONST(-0.84764343500137), FRAC_CONST(0.02372316829860) }, { FRAC_CONST(-0.89039862155914), FRAC_CONST(0.88866579532623) }, { FRAC_CONST(0.95903307199478), FRAC_CONST(0.76744925975800) }, { FRAC_CONST(0.73504126071930), FRAC_CONST(-0.03747203201056) }, { FRAC_CONST(-0.31744435429573), FRAC_CONST(-0.36834111809731) }, { FRAC_CONST(-0.34110826253891), FRAC_CONST(0.40211221575737) }, { FRAC_CONST(0.47803884744644), FRAC_CONST(-0.39423218369484) }, { FRAC_CONST(0.98299193382263), FRAC_CONST(0.01989791356027) }, { FRAC_CONST(-0.30963072180748), FRAC_CONST(-0.18076720833778) }, { FRAC_CONST(0.99992591142654), FRAC_CONST(-0.26281872391701) }, { FRAC_CONST(-0.93149733543396), FRAC_CONST(-0.98313164710999) }, { FRAC_CONST(0.99923473596573), FRAC_CONST(-0.80142992734909) }, { FRAC_CONST(-0.26024168729782), FRAC_CONST(-0.75999760627747) }, { FRAC_CONST(-0.35712513327599), FRAC_CONST(0.19298963248730) }, { FRAC_CONST(-0.99899083375931), FRAC_CONST(0.74645155668259) }, { FRAC_CONST(0.86557173728943), FRAC_CONST(0.55593866109848) }, { FRAC_CONST(0.33408042788506), FRAC_CONST(0.86185956001282) }, { FRAC_CONST(0.99010735750198), FRAC_CONST(0.04602397605777) }, { FRAC_CONST(-0.66694271564484), FRAC_CONST(-0.91643613576889) }, { FRAC_CONST(0.64016789197922), FRAC_CONST(0.15649530291557) }, { FRAC_CONST(0.99570536613464), FRAC_CONST(0.45844584703445) }, { FRAC_CONST(-0.63431465625763), FRAC_CONST(0.21079117059708) }, { FRAC_CONST(-0.07706847041845), FRAC_CONST(-0.89581435918808) }, { FRAC_CONST(0.98590087890625), FRAC_CONST(0.88241720199585) }, { FRAC_CONST(0.80099332332611), FRAC_CONST(-0.36851897835732) }, { FRAC_CONST(0.78368133306503), FRAC_CONST(0.45506998896599) }, { FRAC_CONST(0.08707806468010), FRAC_CONST(0.80938994884491) }, { FRAC_CONST(-0.86811882257462), FRAC_CONST(0.39347308874130) }, { FRAC_CONST(-0.39466530084610), FRAC_CONST(-0.66809433698654) }, { FRAC_CONST(0.97875326871872), FRAC_CONST(-0.72467839717865) }, { FRAC_CONST(-0.95038563013077), FRAC_CONST(0.89563220739365) }, { FRAC_CONST(0.17005239427090), FRAC_CONST(0.54683053493500) }, { FRAC_CONST(-0.76910793781281), FRAC_CONST(-0.96226614713669) }, { FRAC_CONST(0.99743282794952), FRAC_CONST(0.42697158455849) }, { FRAC_CONST(0.95437383651733), FRAC_CONST(0.97002321481705) }, { FRAC_CONST(0.99578905105591), FRAC_CONST(-0.54106825590134) }, { FRAC_CONST(0.28058260679245), FRAC_CONST(-0.85361421108246) }, { FRAC_CONST(0.85256522893906), FRAC_CONST(-0.64567607641220) }, { FRAC_CONST(-0.50608539581299), FRAC_CONST(-0.65846014022827) }, { FRAC_CONST(-0.97210735082626), FRAC_CONST(-0.23095212876797) }, { FRAC_CONST(0.95424050092697), FRAC_CONST(-0.99240148067474) }, { FRAC_CONST(-0.96926569938660), FRAC_CONST(0.73775655031204) }, { FRAC_CONST(0.30872163176537), FRAC_CONST(0.41514959931374) }, { FRAC_CONST(-0.24523839354515), FRAC_CONST(0.63206630945206) }, { FRAC_CONST(-0.33813264966011), FRAC_CONST(-0.38661777973175) }, { FRAC_CONST(-0.05826828256249), FRAC_CONST(-0.06940773874521) }, { FRAC_CONST(-0.22898460924625), FRAC_CONST(0.97054851055145) }, { FRAC_CONST(-0.18509915471077), FRAC_CONST(0.47565764188766) }, { FRAC_CONST(-0.10488238185644), FRAC_CONST(-0.87769949436188) }, { FRAC_CONST(-0.71886587142944), FRAC_CONST(0.78030979633331) }, { FRAC_CONST(0.99793875217438), FRAC_CONST(0.90041309595108) }, { FRAC_CONST(0.57563304901123), FRAC_CONST(-0.91034334897995) }, { FRAC_CONST(0.28909647464752), FRAC_CONST(0.96307784318924) }, { FRAC_CONST(0.42188999056816), FRAC_CONST(0.48148649930954) }, { FRAC_CONST(0.93335050344467), FRAC_CONST(-0.43537023663521) }, { FRAC_CONST(-0.97087377309799), FRAC_CONST(0.86636447906494) }, { FRAC_CONST(0.36722871661186), FRAC_CONST(0.65291655063629) }, { FRAC_CONST(-0.81093025207520), FRAC_CONST(0.08778370171785) }, { FRAC_CONST(-0.26240602135658), FRAC_CONST(-0.92774093151093) }, { FRAC_CONST(0.83996498584747), FRAC_CONST(0.55839848518372) }, { FRAC_CONST(-0.99909615516663), FRAC_CONST(-0.96024608612061) }, { FRAC_CONST(0.74649465084076), FRAC_CONST(0.12144893407822) }, { FRAC_CONST(-0.74774593114853), FRAC_CONST(-0.26898062229156) }, { FRAC_CONST(0.95781666040421), FRAC_CONST(-0.79047924280167) }, { FRAC_CONST(0.95472306013107), FRAC_CONST(-0.08588775992393) }, { FRAC_CONST(0.48708331584930), FRAC_CONST(0.99999040365219) }, { FRAC_CONST(0.46332037448883), FRAC_CONST(0.10964126139879) }, { FRAC_CONST(-0.76497006416321), FRAC_CONST(0.89210927486420) }, { FRAC_CONST(0.57397389411926), FRAC_CONST(0.35289704799652) }, { FRAC_CONST(0.75374317169189), FRAC_CONST(0.96705216169357) }, { FRAC_CONST(-0.59174400568008), FRAC_CONST(-0.89405369758606) }, { FRAC_CONST(0.75087904930115), FRAC_CONST(-0.29612672328949) }, { FRAC_CONST(-0.98607856035233), FRAC_CONST(0.25034910440445) }, { FRAC_CONST(-0.40761056542397), FRAC_CONST(-0.90045571327209) }, { FRAC_CONST(0.66929268836975), FRAC_CONST(0.98629492521286) }, { FRAC_CONST(-0.97463697195053), FRAC_CONST(-0.00190223299433) }, { FRAC_CONST(0.90145510435104), FRAC_CONST(0.99781388044357) }, { FRAC_CONST(-0.87259286642075), FRAC_CONST(0.99233585596085) }, { FRAC_CONST(-0.91529458761215), FRAC_CONST(-0.15698707103729) }, { FRAC_CONST(-0.03305738791823), FRAC_CONST(-0.37205263972282) }, { FRAC_CONST(0.07223051041365), FRAC_CONST(-0.88805001974106) }, { FRAC_CONST(0.99498009681702), FRAC_CONST(0.97094357013702) }, { FRAC_CONST(-0.74904936552048), FRAC_CONST(0.99985486268997) }, { FRAC_CONST(0.04585228487849), FRAC_CONST(0.99812334775925) }, { FRAC_CONST(-0.89054954051971), FRAC_CONST(-0.31791913509369) }, { FRAC_CONST(-0.83782142400742), FRAC_CONST(0.97637635469437) }, { FRAC_CONST(0.33454805612564), FRAC_CONST(-0.86231517791748) }, { FRAC_CONST(-0.99707579612732), FRAC_CONST(0.93237990140915) }, { FRAC_CONST(-0.22827528417110), FRAC_CONST(0.18874759972095) }, { FRAC_CONST(0.67248046398163), FRAC_CONST(-0.03646211326122) }, { FRAC_CONST(-0.05146538093686), FRAC_CONST(-0.92599701881409) }, { FRAC_CONST(0.99947297573090), FRAC_CONST(0.93625229597092) }, { FRAC_CONST(0.66951125860214), FRAC_CONST(0.98905825614929) }, { FRAC_CONST(-0.99602955579758), FRAC_CONST(-0.44654715061188) }, { FRAC_CONST(0.82104903459549), FRAC_CONST(0.99540740251541) }, { FRAC_CONST(0.99186509847641), FRAC_CONST(0.72022998332977) }, { FRAC_CONST(-0.65284591913223), FRAC_CONST(0.52186721563339) }, { FRAC_CONST(0.93885445594788), FRAC_CONST(-0.74895310401917) }, { FRAC_CONST(0.96735250949860), FRAC_CONST(0.90891814231873) }, { FRAC_CONST(-0.22225968539715), FRAC_CONST(0.57124030590057) }, { FRAC_CONST(-0.44132784008980), FRAC_CONST(-0.92688840627670) }, { FRAC_CONST(-0.85694974660873), FRAC_CONST(0.88844531774521) }, { FRAC_CONST(0.91783040761948), FRAC_CONST(-0.46356892585754) }, { FRAC_CONST(0.72556972503662), FRAC_CONST(-0.99899554252625) }, { FRAC_CONST(-0.99711579084396), FRAC_CONST(0.58211559057236) }, { FRAC_CONST(0.77638977766037), FRAC_CONST(0.94321835041046) }, { FRAC_CONST(0.07717324048281), FRAC_CONST(0.58638399839401) }, { FRAC_CONST(-0.56049829721451), FRAC_CONST(0.82522302865982) }, { FRAC_CONST(0.98398894071579), FRAC_CONST(0.39467439055443) }, { FRAC_CONST(0.47546947002411), FRAC_CONST(0.68613046407700) }, { FRAC_CONST(0.65675091743469), FRAC_CONST(0.18331636488438) }, { FRAC_CONST(0.03273375332355), FRAC_CONST(-0.74933111667633) }, { FRAC_CONST(-0.38684144616127), FRAC_CONST(0.51337349414825) }, { FRAC_CONST(-0.97346270084381), FRAC_CONST(-0.96549361944199) }, { FRAC_CONST(-0.53282153606415), FRAC_CONST(-0.91423267126083) }, { FRAC_CONST(0.99817311763763), FRAC_CONST(0.61133575439453) }, { FRAC_CONST(-0.50254499912262), FRAC_CONST(-0.88829338550568) }, { FRAC_CONST(0.01995873264968), FRAC_CONST(0.85223513841629) }, { FRAC_CONST(0.99930381774902), FRAC_CONST(0.94578897953033) }, { FRAC_CONST(0.82907766103745), FRAC_CONST(-0.06323442608118) }, { FRAC_CONST(-0.58660709857941), FRAC_CONST(0.96840775012970) }, { FRAC_CONST(-0.17573736608028), FRAC_CONST(-0.48166921734810) }, { FRAC_CONST(0.83434289693832), FRAC_CONST(-0.13023450970650) }, { FRAC_CONST(0.05946491286159), FRAC_CONST(0.20511047542095) }, { FRAC_CONST(0.81505483388901), FRAC_CONST(-0.94685947895050) }, { FRAC_CONST(-0.44976380467415), FRAC_CONST(0.40894573926926) }, { FRAC_CONST(-0.89746475219727), FRAC_CONST(0.99846577644348) }, { FRAC_CONST(0.39677256345749), FRAC_CONST(-0.74854665994644) }, { FRAC_CONST(-0.07588948309422), FRAC_CONST(0.74096214771271) }, { FRAC_CONST(0.76343196630478), FRAC_CONST(0.41746628284454) }, { FRAC_CONST(-0.74490106105804), FRAC_CONST(0.94725912809372) }, { FRAC_CONST(0.64880120754242), FRAC_CONST(0.41336661577225) }, { FRAC_CONST(0.62319535017014), FRAC_CONST(-0.93098312616348) }, { FRAC_CONST(0.42215818166733), FRAC_CONST(-0.07712787389755) }, { FRAC_CONST(0.02704554051161), FRAC_CONST(-0.05417517945170) }, { FRAC_CONST(0.80001771450043), FRAC_CONST(0.91542196273804) }, { FRAC_CONST(-0.79351830482483), FRAC_CONST(-0.36208897829056) }, { FRAC_CONST(0.63872361183167), FRAC_CONST(0.08128252625465) }, { FRAC_CONST(0.52890521287918), FRAC_CONST(0.60048872232437) }, { FRAC_CONST(0.74238550662994), FRAC_CONST(0.04491915181279) }, { FRAC_CONST(0.99096131324768), FRAC_CONST(-0.19451183080673) }, { FRAC_CONST(-0.80412328243256), FRAC_CONST(-0.88513815402985) }, { FRAC_CONST(-0.64612615108490), FRAC_CONST(0.72198677062988) }, { FRAC_CONST(0.11657770723104), FRAC_CONST(-0.83662831783295) }, { FRAC_CONST(-0.95053184032440), FRAC_CONST(-0.96939903497696) }, { FRAC_CONST(-0.62228870391846), FRAC_CONST(0.82767260074615) }, { FRAC_CONST(0.03004475869238), FRAC_CONST(-0.99738895893097) }, { FRAC_CONST(-0.97987216711044), FRAC_CONST(0.36526128649712) }, { FRAC_CONST(-0.99986982345581), FRAC_CONST(-0.36021611094475) }, { FRAC_CONST(0.89110648632050), FRAC_CONST(-0.97894251346588) }, { FRAC_CONST(0.10407960414886), FRAC_CONST(0.77357792854309) }, { FRAC_CONST(0.95964735746384), FRAC_CONST(-0.35435819625854) }, { FRAC_CONST(0.50843232870102), FRAC_CONST(0.96107691526413) }, { FRAC_CONST(0.17006334662437), FRAC_CONST(-0.76854026317596) }, { FRAC_CONST(0.25872674584389), FRAC_CONST(0.99893301725388) }, { FRAC_CONST(-0.01115998718888), FRAC_CONST(0.98496019840240) }, { FRAC_CONST(-0.79598701000214), FRAC_CONST(0.97138410806656) }, { FRAC_CONST(-0.99264711141586), FRAC_CONST(-0.99542820453644) }, { FRAC_CONST(-0.99829661846161), FRAC_CONST(0.01877138763666) }, { FRAC_CONST(-0.70801013708115), FRAC_CONST(0.33680686354637) }, { FRAC_CONST(-0.70467054843903), FRAC_CONST(0.93272775411606) }, { FRAC_CONST(0.99846023321152), FRAC_CONST(-0.98725748062134) }, { FRAC_CONST(-0.63364970684052), FRAC_CONST(-0.16473594307899) }, { FRAC_CONST(-0.16258217394352), FRAC_CONST(-0.95939123630524) }, { FRAC_CONST(-0.43645593523979), FRAC_CONST(-0.94805032014847) }, { FRAC_CONST(-0.99848473072052), FRAC_CONST(0.96245169639587) }, { FRAC_CONST(-0.16796459257603), FRAC_CONST(-0.98987513780594) }, { FRAC_CONST(-0.87979227304459), FRAC_CONST(-0.71725726127625) }, { FRAC_CONST(0.44183099269867), FRAC_CONST(-0.93568974733353) }, { FRAC_CONST(0.93310177326202), FRAC_CONST(-0.99913311004639) }, { FRAC_CONST(-0.93941932916641), FRAC_CONST(-0.56409376859665) }, { FRAC_CONST(-0.88590002059937), FRAC_CONST(0.47624599933624) }, { FRAC_CONST(0.99971461296082), FRAC_CONST(-0.83889955282211) }, { FRAC_CONST(-0.75376385450363), FRAC_CONST(0.00814643409103) }, { FRAC_CONST(0.93887686729431), FRAC_CONST(-0.11284527927637) }, { FRAC_CONST(0.85126435756683), FRAC_CONST(0.52349251508713) }, { FRAC_CONST(0.39701420068741), FRAC_CONST(0.81779634952545) }, { FRAC_CONST(-0.37024465203285), FRAC_CONST(-0.87071657180786) }, { FRAC_CONST(-0.36024826765060), FRAC_CONST(0.34655734896660) }, { FRAC_CONST(-0.93388813734055), FRAC_CONST(-0.84476542472839) }, { FRAC_CONST(-0.65298801660538), FRAC_CONST(-0.18439576029778) }, { FRAC_CONST(0.11960318684578), FRAC_CONST(0.99899345636368) }, { FRAC_CONST(0.94292563199997), FRAC_CONST(0.83163905143738) }, { FRAC_CONST(0.75081145763397), FRAC_CONST(-0.35533222556114) }, { FRAC_CONST(0.56721979379654), FRAC_CONST(-0.24076835811138) }, { FRAC_CONST(0.46857765316963), FRAC_CONST(-0.30140233039856) }, { FRAC_CONST(0.97312313318253), FRAC_CONST(-0.99548190832138) }, { FRAC_CONST(-0.38299977779388), FRAC_CONST(0.98516911268234) }, { FRAC_CONST(0.41025799512863), FRAC_CONST(0.02116736955941) }, { FRAC_CONST(0.09638062119484), FRAC_CONST(0.04411984235048) }, { FRAC_CONST(-0.85283249616623), FRAC_CONST(0.91475564241409) }, { FRAC_CONST(0.88866806030273), FRAC_CONST(-0.99735265970230) }, { FRAC_CONST(-0.48202428221703), FRAC_CONST(-0.96805608272552) }, { FRAC_CONST(0.27572581171989), FRAC_CONST(0.58634752035141) }, { FRAC_CONST(-0.65889132022858), FRAC_CONST(0.58835631608963) }, { FRAC_CONST(0.98838084936142), FRAC_CONST(0.99994349479675) }, { FRAC_CONST(-0.20651349425316), FRAC_CONST(0.54593044519424) }, { FRAC_CONST(-0.62126415967941), FRAC_CONST(-0.59893679618835) }, { FRAC_CONST(0.20320105552673), FRAC_CONST(-0.86879181861877) }, { FRAC_CONST(-0.97790551185608), FRAC_CONST(0.96290808916092) }, { FRAC_CONST(0.11112534999847), FRAC_CONST(0.21484763920307) }, { FRAC_CONST(-0.41368338465691), FRAC_CONST(0.28216838836670) }, { FRAC_CONST(0.24133038520813), FRAC_CONST(0.51294362545013) }, { FRAC_CONST(-0.66393411159515), FRAC_CONST(-0.08249679952860) }, { FRAC_CONST(-0.53697830438614), FRAC_CONST(-0.97649902105331) }, { FRAC_CONST(-0.97224736213684), FRAC_CONST(0.22081333398819) }, { FRAC_CONST(0.87392479181290), FRAC_CONST(-0.12796173989773) }, { FRAC_CONST(0.19050361216068), FRAC_CONST(0.01602615416050) }, { FRAC_CONST(-0.46353441476822), FRAC_CONST(-0.95249038934708) }, { FRAC_CONST(-0.07064096629620), FRAC_CONST(-0.94479805231094) }, { FRAC_CONST(-0.92444086074829), FRAC_CONST(-0.10457590222359) }, { FRAC_CONST(-0.83822596073151), FRAC_CONST(-0.01695043221116) }, { FRAC_CONST(0.75214684009552), FRAC_CONST(-0.99955683946609) }, { FRAC_CONST(-0.42102998495102), FRAC_CONST(0.99720942974091) }, { FRAC_CONST(-0.72094786167145), FRAC_CONST(-0.35008960962296) }, { FRAC_CONST(0.78843313455582), FRAC_CONST(0.52851396799088) }, { FRAC_CONST(0.97394025325775), FRAC_CONST(-0.26695942878723) }, { FRAC_CONST(0.99206465482712), FRAC_CONST(-0.57010120153427) }, { FRAC_CONST(0.76789611577988), FRAC_CONST(-0.76519358158112) }, { FRAC_CONST(-0.82002419233322), FRAC_CONST(-0.73530179262161) }, { FRAC_CONST(0.81924992799759), FRAC_CONST(0.99698424339294) }, { FRAC_CONST(-0.26719850301743), FRAC_CONST(0.68903368711472) }, { FRAC_CONST(-0.43311259150505), FRAC_CONST(0.85321813821793) }, { FRAC_CONST(0.99194979667664), FRAC_CONST(0.91876250505447) }, { FRAC_CONST(-0.80691999197006), FRAC_CONST(-0.32627540826797) }, { FRAC_CONST(0.43080005049706), FRAC_CONST(-0.21919095516205) }, { FRAC_CONST(0.67709493637085), FRAC_CONST(-0.95478075742722) }, { FRAC_CONST(0.56151771545410), FRAC_CONST(-0.70693808794022) }, { FRAC_CONST(0.10831862688065), FRAC_CONST(-0.08628837019205) }, { FRAC_CONST(0.91229414939880), FRAC_CONST(-0.65987348556519) }, { FRAC_CONST(-0.48972892761230), FRAC_CONST(0.56289243698120) }, { FRAC_CONST(-0.89033657312393), FRAC_CONST(-0.71656566858292) }, { FRAC_CONST(0.65269446372986), FRAC_CONST(0.65916007757187) }, { FRAC_CONST(0.67439478635788), FRAC_CONST(-0.81684380769730) }, { FRAC_CONST(-0.47770830988884), FRAC_CONST(-0.16789555549622) }, { FRAC_CONST(-0.99715977907181), FRAC_CONST(-0.93565785884857) }, { FRAC_CONST(-0.90889590978622), FRAC_CONST(0.62034398317337) }, { FRAC_CONST(-0.06618622690439), FRAC_CONST(-0.23812216520309) }, { FRAC_CONST(0.99430269002914), FRAC_CONST(0.18812555074692) }, { FRAC_CONST(0.97686403989792), FRAC_CONST(-0.28664535284042) }, { FRAC_CONST(0.94813650846481), FRAC_CONST(-0.97506642341614) }, { FRAC_CONST(-0.95434498786926), FRAC_CONST(-0.79607981443405) }, { FRAC_CONST(-0.49104782938957), FRAC_CONST(0.32895213365555) }, { FRAC_CONST(0.99881172180176), FRAC_CONST(0.88993984460831) }, { FRAC_CONST(0.50449168682098), FRAC_CONST(-0.85995072126389) }, { FRAC_CONST(0.47162890434265), FRAC_CONST(-0.18680204451084) }, { FRAC_CONST(-0.62081581354141), FRAC_CONST(0.75000673532486) }, { FRAC_CONST(-0.43867015838623), FRAC_CONST(0.99998068809509) }, { FRAC_CONST(0.98630565404892), FRAC_CONST(-0.53578901290894) }, { FRAC_CONST(-0.61510360240936), FRAC_CONST(-0.89515018463135) }, { FRAC_CONST(-0.03841517493129), FRAC_CONST(-0.69888818264008) }, { FRAC_CONST(-0.30102157592773), FRAC_CONST(-0.07667808979750) }, { FRAC_CONST(0.41881284117699), FRAC_CONST(0.02188098989427) }, { FRAC_CONST(-0.86135452985764), FRAC_CONST(0.98947483301163) }, { FRAC_CONST(0.67226862907410), FRAC_CONST(-0.13494388759136) }, { FRAC_CONST(-0.70737397670746), FRAC_CONST(-0.76547348499298) }, { FRAC_CONST(0.94044947624207), FRAC_CONST(0.09026201069355) }, { FRAC_CONST(-0.82386350631714), FRAC_CONST(0.08924768865108) }, { FRAC_CONST(-0.32070666551590), FRAC_CONST(0.50143420696259) }, { FRAC_CONST(0.57593160867691), FRAC_CONST(-0.98966425657272) }, { FRAC_CONST(-0.36326017975807), FRAC_CONST(0.07440242916346) }, { FRAC_CONST(0.99979043006897), FRAC_CONST(-0.14130286872387) }, { FRAC_CONST(-0.92366021871567), FRAC_CONST(-0.97979295253754) }, { FRAC_CONST(-0.44607177376747), FRAC_CONST(-0.54233253002167) }, { FRAC_CONST(0.44226801395416), FRAC_CONST(0.71326756477356) }, { FRAC_CONST(0.03671907261014), FRAC_CONST(0.63606387376785) }, { FRAC_CONST(0.52175426483154), FRAC_CONST(-0.85396826267242) }, { FRAC_CONST(-0.94701141119003), FRAC_CONST(-0.01826348155737) }, { FRAC_CONST(-0.98759609460831), FRAC_CONST(0.82288712263107) }, { FRAC_CONST(0.87434792518616), FRAC_CONST(0.89399492740631) }, { FRAC_CONST(-0.93412041664124), FRAC_CONST(0.41374051570892) }, { FRAC_CONST(0.96063941717148), FRAC_CONST(0.93116706609726) }, { FRAC_CONST(0.97534251213074), FRAC_CONST(0.86150932312012) }, { FRAC_CONST(0.99642467498779), FRAC_CONST(0.70190042257309) }, { FRAC_CONST(-0.94705086946487), FRAC_CONST(-0.29580041766167) }, { FRAC_CONST(0.91599804162979), FRAC_CONST(-0.98147833347321) } }; #ifdef __cplusplus #endif #endif xine-lib-1.2/contrib/libfaad/specrec.h0000644000175000017500000000346514647725152015513 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: specrec.h,v 1.33 2009/01/26 23:51:15 menno Exp $ **/ #ifndef __SPECREC_H__ #define __SPECREC_H__ #ifdef __cplusplus extern "C" { #endif #include "syntax.h" uint8_t window_grouping_info(NeAACDecStruct *hDecoder, ic_stream *ics); uint8_t reconstruct_channel_pair(NeAACDecStruct *hDecoder, ic_stream *ics1, ic_stream *ics2, element *cpe, int16_t *spec_data1, int16_t *spec_data2); uint8_t reconstruct_single_channel(NeAACDecStruct *hDecoder, ic_stream *ics, element *sce, int16_t *spec_data); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/neaacdec.h0000755000175000017500000002042514647725152015610 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: neaacdec.h,v 1.13 2009/01/26 23:51:15 menno Exp $ **/ #ifndef __NEAACDEC_H__ #define __NEAACDEC_H__ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #if 1 /* MACROS FOR BACKWARDS COMPATIBILITY */ /* structs */ #define faacDecHandle NeAACDecHandle #define faacDecConfiguration NeAACDecConfiguration #define faacDecConfigurationPtr NeAACDecConfigurationPtr #define faacDecFrameInfo NeAACDecFrameInfo /* functions */ #define faacDecGetErrorMessage NeAACDecGetErrorMessage #define faacDecSetConfiguration NeAACDecSetConfiguration #define faacDecGetCurrentConfiguration NeAACDecGetCurrentConfiguration #define faacDecInit NeAACDecInit #define faacDecInit2 NeAACDecInit2 #define faacDecInitDRM NeAACDecInitDRM #define faacDecPostSeekReset NeAACDecPostSeekReset #define faacDecOpen NeAACDecOpen #define faacDecClose NeAACDecClose #define faacDecDecode NeAACDecDecode #define AudioSpecificConfig NeAACDecAudioSpecificConfig #endif #ifdef _WIN32 #pragma pack(push, 8) #ifndef NEAACDECAPI #define NEAACDECAPI __cdecl #endif #else #ifndef NEAACDECAPI #define NEAACDECAPI #endif #endif #define FAAD2_VERSION "2.7" /* object types for AAC */ #define MAIN 1 #define LC 2 #define SSR 3 #define LTP 4 #define HE_AAC 5 #define ER_LC 17 #define ER_LTP 19 #define LD 23 #define DRM_ER_LC 27 /* special object type for DRM */ /* header types */ #define RAW 0 #define ADIF 1 #define ADTS 2 #define LATM 3 /* SBR signalling */ #define NO_SBR 0 #define SBR_UPSAMPLED 1 #define SBR_DOWNSAMPLED 2 #define NO_SBR_UPSAMPLED 3 /* library output formats */ #define FAAD_FMT_16BIT 1 #define FAAD_FMT_24BIT 2 #define FAAD_FMT_32BIT 3 #define FAAD_FMT_FLOAT 4 #define FAAD_FMT_FIXED FAAD_FMT_FLOAT #define FAAD_FMT_DOUBLE 5 /* Capabilities */ #define LC_DEC_CAP (1<<0) /* Can decode LC */ #define MAIN_DEC_CAP (1<<1) /* Can decode MAIN */ #define LTP_DEC_CAP (1<<2) /* Can decode LTP */ #define LD_DEC_CAP (1<<3) /* Can decode LD */ #define ERROR_RESILIENCE_CAP (1<<4) /* Can decode ER */ #define FIXED_POINT_CAP (1<<5) /* Fixed point */ /* Channel definitions */ #define FRONT_CHANNEL_CENTER (1) #define FRONT_CHANNEL_LEFT (2) #define FRONT_CHANNEL_RIGHT (3) #define SIDE_CHANNEL_LEFT (4) #define SIDE_CHANNEL_RIGHT (5) #define BACK_CHANNEL_LEFT (6) #define BACK_CHANNEL_RIGHT (7) #define BACK_CHANNEL_CENTER (8) #define LFE_CHANNEL (9) #define UNKNOWN_CHANNEL (0) /* DRM channel definitions */ #define DRMCH_MONO 1 #define DRMCH_STEREO 2 #define DRMCH_SBR_MONO 3 #define DRMCH_SBR_STEREO 4 #define DRMCH_SBR_PS_STEREO 5 /* A decode call can eat up to FAAD_MIN_STREAMSIZE bytes per decoded channel, so at least so much bytes per channel should be available in this stream */ #define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */ typedef void *NeAACDecHandle; typedef struct mp4AudioSpecificConfig { /* Audio Specific Info */ unsigned char objectTypeIndex; unsigned char samplingFrequencyIndex; unsigned long samplingFrequency; unsigned char channelsConfiguration; /* GA Specific Info */ unsigned char frameLengthFlag; unsigned char dependsOnCoreCoder; unsigned short coreCoderDelay; unsigned char extensionFlag; unsigned char aacSectionDataResilienceFlag; unsigned char aacScalefactorDataResilienceFlag; unsigned char aacSpectralDataResilienceFlag; unsigned char epConfig; char sbr_present_flag; char forceUpSampling; char downSampledSBR; } mp4AudioSpecificConfig; typedef struct NeAACDecConfiguration { unsigned char defObjectType; unsigned long defSampleRate; unsigned char outputFormat; unsigned char downMatrix; unsigned char useOldADTSFormat; unsigned char dontUpSampleImplicitSBR; } NeAACDecConfiguration, *NeAACDecConfigurationPtr; typedef struct NeAACDecFrameInfo { unsigned long bytesconsumed; unsigned long samples; unsigned char channels; unsigned char error; unsigned long samplerate; /* SBR: 0: off, 1: on; upsample, 2: on; downsampled, 3: off; upsampled */ unsigned char sbr; /* MPEG-4 ObjectType */ unsigned char object_type; /* AAC header type; MP4 will be signalled as RAW also */ unsigned char header_type; /* multichannel configuration */ unsigned char num_front_channels; unsigned char num_side_channels; unsigned char num_back_channels; unsigned char num_lfe_channels; unsigned char channel_position[64]; /* PS: 0: off, 1: on */ unsigned char ps; } NeAACDecFrameInfo; const char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode); unsigned long NEAACDECAPI NeAACDecGetCapabilities(void); NeAACDecHandle NEAACDECAPI NeAACDecOpen(void); NeAACDecConfigurationPtr NEAACDECAPI NeAACDecGetCurrentConfiguration(NeAACDecHandle hDecoder); unsigned char NEAACDECAPI NeAACDecSetConfiguration(NeAACDecHandle hDecoder, NeAACDecConfigurationPtr config); /* Init the library based on info from the AAC file (ADTS/ADIF) */ long NEAACDECAPI NeAACDecInit(NeAACDecHandle hDecoder, unsigned char *buffer, unsigned long buffer_size, unsigned long *samplerate, unsigned char *channels); /* Init the library using a DecoderSpecificInfo */ char NEAACDECAPI NeAACDecInit2(NeAACDecHandle hDecoder, unsigned char *pBuffer, unsigned long SizeOfDecoderSpecificInfo, unsigned long *samplerate, unsigned char *channels); /* Init the library for DRM */ char NEAACDECAPI NeAACDecInitDRM(NeAACDecHandle *hDecoder, unsigned long samplerate, unsigned char channels); void NEAACDECAPI NeAACDecPostSeekReset(NeAACDecHandle hDecoder, long frame); void NEAACDECAPI NeAACDecClose(NeAACDecHandle hDecoder); void* NEAACDECAPI NeAACDecDecode(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo, unsigned char *buffer, unsigned long buffer_size); void* NEAACDECAPI NeAACDecDecode2(NeAACDecHandle hDecoder, NeAACDecFrameInfo *hInfo, unsigned char *buffer, unsigned long buffer_size, void **sample_buffer, unsigned long sample_buffer_size); char NEAACDECAPI NeAACDecAudioSpecificConfig(unsigned char *pBuffer, unsigned long buffer_size, mp4AudioSpecificConfig *mp4ASC); #ifdef _WIN32 #pragma pack(pop) #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif xine-lib-1.2/contrib/libfaad/drm_dec.c0000644000175000017500000013673614647725152015467 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: drm_dec.c,v 1.9 2007/11/01 12:33:30 menno Exp $ **/ #include #include #include #include #include "common.h" #ifdef DRM #include "sbr_dec.h" #include "drm_dec.h" #include "bits.h" /* constants */ #define DECAY_CUTOFF 3 #define DECAY_SLOPE 0.05f /* type definitaions */ typedef const int8_t (*drm_ps_huff_tab)[2]; /* binary search huffman tables */ static const int8_t f_huffman_sa[][2] = { { /*0*/ -15, 1 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 1x */ { /*7*/ -8, 4 }, /* index 2: 3 bits: 10x */ { 5, 6 }, /* index 3: 3 bits: 11x */ { /*1*/ -14, /*-1*/ -16 }, /* index 4: 4 bits: 101x */ { /*-2*/ -17, 7 }, /* index 5: 4 bits: 110x */ { 8, 9 }, /* index 6: 4 bits: 111x */ { /*2*/ -13, /*-3*/ -18 }, /* index 7: 5 bits: 1101x */ { /*3*/ -12, 10 }, /* index 8: 5 bits: 1110x */ { 11, 12 }, /* index 9: 5 bits: 1111x */ { /*4*/ -11, /*5*/ -10 }, /* index 10: 6 bits: 11101x */ { /*-4*/ -19, /*-5*/ -20 }, /* index 11: 6 bits: 11110x */ { /*6*/ -9, 13 }, /* index 12: 6 bits: 11111x */ { /*-7*/ -22, /*-6*/ -21 } /* index 13: 7 bits: 111111x */ }; static const int8_t t_huffman_sa[][2] = { { /*0*/ -15, 1 }, /* index 0: 1 bits: x */ { 2, 3 }, /* index 1: 2 bits: 1x */ { /*-1*/ -16, /*1*/ -14 }, /* index 2: 3 bits: 10x */ { 4, 5 }, /* index 3: 3 bits: 11x */ { /*-2*/ -17, /*2*/ -13 }, /* index 4: 4 bits: 110x */ { 6, 7 }, /* index 5: 4 bits: 111x */ { /*-3*/ -18, /*3*/ -12 }, /* index 6: 5 bits: 1110x */ { 8, 9 }, /* index 7: 5 bits: 1111x */ { /*-4*/ -19, /*4*/ -11 }, /* index 8: 6 bits: 11110x */ { 10, 11 }, /* index 9: 6 bits: 11111x */ { /*-5*/ -20, /*5*/ -10 }, /* index 10: 7 bits: 111110x */ { /*-6*/ -21, 12 }, /* index 11: 7 bits: 111111x */ { /*-7*/ -22, 13 }, /* index 12: 8 bits: 1111111x */ { /*6*/ -9, /*7*/ -8 } /* index 13: 9 bits: 11111111x */ }; static const int8_t f_huffman_pan[][2] = { { /*0*/ -15, 1 }, /* index 0: 1 bits: x */ { /*-1*/ -16, 2 }, /* index 1: 2 bits: 1x */ { /*1*/ -14, 3 }, /* index 2: 3 bits: 11x */ { 4, 5 }, /* index 3: 4 bits: 111x */ { /*-2*/ -17, /*2*/ -13 }, /* index 4: 5 bits: 1110x */ { 6, 7 }, /* index 5: 5 bits: 1111x */ { /*-3*/ -18, /*3*/ -12 }, /* index 6: 6 bits: 11110x */ { 8, 9 }, /* index 7: 6 bits: 11111x */ { /*-4*/ -19, /*4*/ -11 }, /* index 8: 7 bits: 111110x */ { 10, 11 }, /* index 9: 7 bits: 111111x */ { /*-5*/ -20, /*5*/ -10 }, /* index 10: 8 bits: 1111110x */ { 12, 13 }, /* index 11: 8 bits: 1111111x */ { /*-6*/ -21, /*6*/ -9 }, /* index 12: 9 bits: 11111110x */ { /*-7*/ -22, 14 }, /* index 13: 9 bits: 11111111x */ { /*7*/ -8, 15 }, /* index 14: 10 bits: 111111111x */ { 16, 17 }, /* index 15: 11 bits: 1111111111x */ { /*-8*/ -23, /*8*/ -7 }, /* index 16: 12 bits: 11111111110x */ { 18, 19 }, /* index 17: 12 bits: 11111111111x */ { /*-10*/ -25, 20 }, /* index 18: 13 bits: 111111111110x */ { 21, 22 }, /* index 19: 13 bits: 111111111111x */ { /*-9*/ -24, /*9*/ -6 }, /* index 20: 14 bits: 1111111111101x */ { /*10*/ -5, 23 }, /* index 21: 14 bits: 1111111111110x */ { 24, 25 }, /* index 22: 14 bits: 1111111111111x */ { /*-13*/ -28, /*-11*/ -26 }, /* index 23: 15 bits: 11111111111101x */ { /*11*/ -4, /*13*/ -2 }, /* index 24: 15 bits: 11111111111110x */ { 26, 27 }, /* index 25: 15 bits: 11111111111111x */ { /*-14*/ -29, /*-12*/ -27 }, /* index 26: 16 bits: 111111111111110x */ { /*12*/ -3, /*14*/ -1 } /* index 27: 16 bits: 111111111111111x */ }; static const int8_t t_huffman_pan[][2] = { { /*0*/ -15, 1 }, /* index 0: 1 bits: x */ { /*-1*/ -16, 2 }, /* index 1: 2 bits: 1x */ { /*1*/ -14, 3 }, /* index 2: 3 bits: 11x */ { /*-2*/ -17, 4 }, /* index 3: 4 bits: 111x */ { /*2*/ -13, 5 }, /* index 4: 5 bits: 1111x */ { /*-3*/ -18, 6 }, /* index 5: 6 bits: 11111x */ { /*3*/ -12, 7 }, /* index 6: 7 bits: 111111x */ { /*-4*/ -19, 8 }, /* index 7: 8 bits: 1111111x */ { /*4*/ -11, 9 }, /* index 8: 9 bits: 11111111x */ { 10, 11 }, /* index 9: 10 bits: 111111111x */ { /*-5*/ -20, /*5*/ -10 }, /* index 10: 11 bits: 1111111110x */ { 12, 13 }, /* index 11: 11 bits: 1111111111x */ { /*-6*/ -21, /*6*/ -9 }, /* index 12: 12 bits: 11111111110x */ { 14, 15 }, /* index 13: 12 bits: 11111111111x */ { /*-7*/ -22, /*7*/ -8 }, /* index 14: 13 bits: 111111111110x */ { 16, 17 }, /* index 15: 13 bits: 111111111111x */ { /*-8*/ -23, /*8*/ -7 }, /* index 16: 14 bits: 1111111111110x */ { 18, 19 }, /* index 17: 14 bits: 1111111111111x */ { /*-10*/ -25, /*10*/ -5 }, /* index 18: 15 bits: 11111111111110x */ { 20, 21 }, /* index 19: 15 bits: 11111111111111x */ { /*-9*/ -24, /*9*/ -6 }, /* index 20: 16 bits: 111111111111110x */ { 22, 23 }, /* index 21: 16 bits: 111111111111111x */ { 24, 25 }, /* index 22: 17 bits: 1111111111111110x */ { 26, 27 }, /* index 23: 17 bits: 1111111111111111x */ { /*-14*/ -29, /*-13*/ -28 }, /* index 24: 18 bits: 11111111111111100x */ { /*-12*/ -27, /*-11*/ -26 }, /* index 25: 18 bits: 11111111111111101x */ { /*11*/ -4, /*12*/ -3 }, /* index 26: 18 bits: 11111111111111110x */ { /*13*/ -2, /*14*/ -1 } /* index 27: 18 bits: 11111111111111111x */ }; /* There are 3 classes in the standard but the last 2 are identical */ static const real_t sa_quant[8][2] = { { FRAC_CONST(0.0000), FRAC_CONST(0.0000) }, { FRAC_CONST(0.0501), FRAC_CONST(0.1778) }, { FRAC_CONST(0.0706), FRAC_CONST(0.2818) }, { FRAC_CONST(0.0995), FRAC_CONST(0.4467) }, { FRAC_CONST(0.1399), FRAC_CONST(0.5623) }, { FRAC_CONST(0.1957), FRAC_CONST(0.7079) }, { FRAC_CONST(0.2713), FRAC_CONST(0.8913) }, { FRAC_CONST(0.3699), FRAC_CONST(1.0000) }, }; /* We don't need the actual quantizer values */ #if 0 static const real_t pan_quant[8][5] = { { COEF_CONST(0.0000), COEF_CONST(0.0000), COEF_CONST(0.0000), COEF_CONST(0.0000), COEF_CONST(0.0000) }, { COEF_CONST(0.1661), COEF_CONST(0.1661), COEF_CONST(0.3322), COEF_CONST(0.3322), COEF_CONST(0.3322) }, { COEF_CONST(0.3322), COEF_CONST(0.3322), COEF_CONST(0.6644), COEF_CONST(0.8305), COEF_CONST(0.8305) }, { COEF_CONST(0.4983), COEF_CONST(0.6644), COEF_CONST(0.9966), COEF_CONST(1.4949), COEF_CONST(1.6610) }, { COEF_CONST(0.6644), COEF_CONST(0.9966), COEF_CONST(1.4949), COEF_CONST(2.1593), COEF_CONST(2.4914) }, { COEF_CONST(0.8305), COEF_CONST(1.3288), COEF_CONST(2.1593), COEF_CONST(2.9897), COEF_CONST(3.4880) }, { COEF_CONST(0.9966), COEF_CONST(1.8271), COEF_CONST(2.8236), COEF_CONST(3.8202), COEF_CONST(4.6507) }, { COEF_CONST(1.3288), COEF_CONST(2.3253), COEF_CONST(3.4880), COEF_CONST(4.6507), COEF_CONST(5.8134) }, }; #endif /* 2^(pan_quant[x][y] */ static const real_t pan_pow_2_pos[8][5] = { { REAL_CONST(1.0000000), REAL_CONST(1.0000000), REAL_CONST(1.0000000), REAL_CONST(1.0000000), REAL_CONST(1.0000000) }, { REAL_CONST(1.1220021), REAL_CONST(1.1220021), REAL_CONST(1.2589312), REAL_CONST(1.2589312), REAL_CONST(1.2589312) }, { REAL_CONST(1.2589312), REAL_CONST(1.2589312), REAL_CONST(1.5849090), REAL_CONST(1.7783016), REAL_CONST(1.7783016) }, { REAL_CONST(1.4125481), REAL_CONST(1.5849090), REAL_CONST(1.9952921), REAL_CONST(2.8184461), REAL_CONST(3.1623565) }, { REAL_CONST(1.5849090), REAL_CONST(1.9952922), REAL_CONST(2.8184461), REAL_CONST(4.4669806), REAL_CONST(5.6232337) }, { REAL_CONST(1.7783016), REAL_CONST(2.5119365), REAL_CONST(4.4669806), REAL_CONST(7.9430881), REAL_CONST(11.219994) }, { REAL_CONST(1.9952921), REAL_CONST(3.5482312), REAL_CONST(7.0792671), REAL_CONST(14.125206), REAL_CONST(25.118876) }, { REAL_CONST(2.5119365), REAL_CONST(5.0116998), REAL_CONST(11.219994), REAL_CONST(25.118876), REAL_CONST(56.235140) } }; /* 2^(-pan_quant[x][y] */ static const real_t pan_pow_2_neg[8][5] = { { REAL_CONST(1), REAL_CONST(1), REAL_CONST(1), REAL_CONST(1), REAL_CONST(1) }, { REAL_CONST(0.8912487), REAL_CONST(0.8912487), REAL_CONST(0.7943242), REAL_CONST(0.7943242), REAL_CONST(0.7943242) }, { REAL_CONST(0.7943242), REAL_CONST(0.7943242), REAL_CONST(0.6309511), REAL_CONST(0.5623344), REAL_CONST(0.5623344) }, { REAL_CONST(0.7079405), REAL_CONST(0.6309511), REAL_CONST(0.5011797), REAL_CONST(0.3548054), REAL_CONST(0.3162199) }, { REAL_CONST(0.6309511), REAL_CONST(0.5011797), REAL_CONST(0.3548054), REAL_CONST(0.2238649), REAL_CONST(0.1778336) }, { REAL_CONST(0.5623343), REAL_CONST(0.3980992), REAL_CONST(0.2238649), REAL_CONST(0.1258956), REAL_CONST(0.0891266) }, { REAL_CONST(0.5011797), REAL_CONST(0.2818306), REAL_CONST(0.1412576), REAL_CONST(0.0707954), REAL_CONST(0.0398107) }, { REAL_CONST(0.3980992), REAL_CONST(0.1995331), REAL_CONST(0.0891267), REAL_CONST(0.0398107), REAL_CONST(0.0177825) } }; /* 2^(pan_quant[x][y]/30) */ static const real_t pan_pow_2_30_pos[8][5] = { { COEF_CONST(1), COEF_CONST(1), COEF_CONST(1), COEF_CONST(1), COEF_CONST(1) }, { COEF_CONST(1.003845098), COEF_CONST(1.003845098), COEF_CONST(1.007704982), COEF_CONST(1.007704982), COEF_CONST(1.007704982) }, { COEF_CONST(1.007704982), COEF_CONST(1.007704982), COEF_CONST(1.01546933), COEF_CONST(1.019373909), COEF_CONST(1.019373909) }, { COEF_CONST(1.011579706), COEF_CONST(1.01546933), COEF_CONST(1.023293502), COEF_CONST(1.035142941), COEF_CONST(1.039123167) }, { COEF_CONST(1.01546933), COEF_CONST(1.023293502), COEF_CONST(1.035142941), COEF_CONST(1.051155908), COEF_CONST(1.059252598) }, { COEF_CONST(1.019373909), COEF_CONST(1.03117796), COEF_CONST(1.051155908), COEF_CONST(1.071518432), COEF_CONST(1.0839263) }, { COEF_CONST(1.023293502), COEF_CONST(1.043118698), COEF_CONST(1.067414119), COEF_CONST(1.092277933), COEF_CONST(1.113439626) }, { COEF_CONST(1.03117796), COEF_CONST(1.055195268), COEF_CONST(1.0839263), COEF_CONST(1.113439626), COEF_CONST(1.143756546) } }; /* 2^(-pan_quant[x][y]/30) */ static const real_t pan_pow_2_30_neg[8][5] = { { COEF_CONST(1), COEF_CONST(1), COEF_CONST(1), COEF_CONST(1), COEF_CONST(1) }, { COEF_CONST(0.99616963), COEF_CONST(0.99616963), COEF_CONST(0.992353931), COEF_CONST(0.992353931), COEF_CONST(0.99235393) }, { COEF_CONST(0.992353931), COEF_CONST(0.992353931), COEF_CONST(0.984766325), COEF_CONST(0.980994305), COEF_CONST(0.980994305) }, { COEF_CONST(0.988552848), COEF_CONST(0.984766325), COEF_CONST(0.977236734), COEF_CONST(0.966050157), COEF_CONST(0.962349827) }, { COEF_CONST(0.984766325), COEF_CONST(0.977236734), COEF_CONST(0.966050157), COEF_CONST(0.951333663), COEF_CONST(0.944061881) }, { COEF_CONST(0.980994305), COEF_CONST(0.969764715), COEF_CONST(0.951333663), COEF_CONST(0.933255062), COEF_CONST(0.922571949) }, { COEF_CONST(0.977236734), COEF_CONST(0.958663671), COEF_CONST(0.936843519), COEF_CONST(0.915517901), COEF_CONST(0.898117847) }, { COEF_CONST(0.969764715), COEF_CONST(0.947691892), COEF_CONST(0.922571949), COEF_CONST(0.898117847), COEF_CONST(0.874311936) } }; static const real_t g_decayslope[MAX_SA_BAND] = { FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(1), FRAC_CONST(0.95),FRAC_CONST(0.9), FRAC_CONST(0.85), FRAC_CONST(0.8), FRAC_CONST(0.75),FRAC_CONST(0.7), FRAC_CONST(0.65),FRAC_CONST(0.6), FRAC_CONST(0.55),FRAC_CONST(0.5), FRAC_CONST(0.45), FRAC_CONST(0.4), FRAC_CONST(0.35),FRAC_CONST(0.3), FRAC_CONST(0.25),FRAC_CONST(0.2), FRAC_CONST(0.15), FRAC_CONST(0.1), FRAC_CONST(0.05),FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0), FRAC_CONST(0) }; static const real_t sa_sqrt_1_minus[8][2] = { { FRAC_CONST(1), FRAC_CONST(1) }, { FRAC_CONST(0.998744206), FRAC_CONST(0.984066644) }, { FRAC_CONST(0.997504707), FRAC_CONST(0.959473168) }, { FRAC_CONST(0.995037562), FRAC_CONST(0.894683804) }, { FRAC_CONST(0.990165638), FRAC_CONST(0.826933317) }, { FRAC_CONST(0.980663811), FRAC_CONST(0.706312672) }, { FRAC_CONST(0.962494836), FRAC_CONST(0.45341406) }, { FRAC_CONST(0.929071574), FRAC_CONST(0) } }; static const uint8_t sa_freq_scale[9] = { 0, 1, 2, 3, 5, 7, 10, 13, 23 }; static const uint8_t pan_freq_scale[21] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 18, 22, 26, 32, 64 }; static const uint8_t pan_quant_class[20] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4 }; /* Inverse mapping lookup */ static const uint8_t pan_inv_freq[64] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 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, 19, 19, 19 }; static const uint8_t sa_inv_freq[MAX_SA_BAND] = { 0, 1, 2, 3, 3, 4, 4, 5, 5, 5, 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 }; static const real_t filter_coeff[] = { FRAC_CONST(0.65143905754106), FRAC_CONST(0.56471812200776), FRAC_CONST(0.48954165955695) }; static const uint8_t delay_length[3] = { 3, 4, 5 }; static const real_t delay_fraction[] = { FRAC_CONST(0.43), FRAC_CONST(0.75), FRAC_CONST(0.347) }; static const real_t peak_decay = FRAC_CONST(0.76592833836465); static const real_t smooth_coeff = FRAC_CONST(0.25); /* Please note that these are the same tables as in plain PS */ static const complex_t Q_Fract_allpass_Qmf[][3] = { { { FRAC_CONST(0.7804303765), FRAC_CONST(0.6252426505) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.8550928831), FRAC_CONST(0.5184748173) } }, { { FRAC_CONST(-0.4399392009), FRAC_CONST(0.8980275393) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.0643581524), FRAC_CONST(0.9979268909) } }, { { FRAC_CONST(-0.9723699093), FRAC_CONST(-0.2334454209) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.9146071672), FRAC_CONST(0.4043435752) } }, { { FRAC_CONST(0.0157073960), FRAC_CONST(-0.9998766184) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7814115286), FRAC_CONST(-0.6240159869) } }, { { FRAC_CONST(0.9792228341), FRAC_CONST(-0.2027871907) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.1920081824), FRAC_CONST(-0.9813933372) } }, { { FRAC_CONST(0.4115142524), FRAC_CONST(0.9114032984) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.9589683414), FRAC_CONST(-0.2835132182) } }, { { FRAC_CONST(-0.7996847630), FRAC_CONST(0.6004201174) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.6947838664), FRAC_CONST(0.7192186117) } }, { { FRAC_CONST(-0.7604058385), FRAC_CONST(-0.6494481564) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.3164770305), FRAC_CONST(0.9486001730) } }, { { FRAC_CONST(0.4679299891), FRAC_CONST(-0.8837655187) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9874414206), FRAC_CONST(0.1579856575) } }, { { FRAC_CONST(0.9645573497), FRAC_CONST(0.2638732493) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.5966450572), FRAC_CONST(-0.8025052547) } }, { { FRAC_CONST(-0.0471066870), FRAC_CONST(0.9988898635) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.4357025325), FRAC_CONST(-0.9000906944) } }, { { FRAC_CONST(-0.9851093888), FRAC_CONST(0.1719288528) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9995546937), FRAC_CONST(-0.0298405960) } }, { { FRAC_CONST(-0.3826831877), FRAC_CONST(-0.9238796234) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.4886211455), FRAC_CONST(0.8724960685) } }, { { FRAC_CONST(0.8181498647), FRAC_CONST(-0.5750049949) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.5477093458), FRAC_CONST(0.8366686702) } }, { { FRAC_CONST(0.7396308780), FRAC_CONST(0.6730127335) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9951074123), FRAC_CONST(-0.0987988561) } }, { { FRAC_CONST(-0.4954589605), FRAC_CONST(0.8686313629) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.3725017905), FRAC_CONST(-0.9280315042) } }, { { FRAC_CONST(-0.9557929039), FRAC_CONST(-0.2940406799) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.6506417990), FRAC_CONST(-0.7593847513) } }, { { FRAC_CONST(0.0784594864), FRAC_CONST(-0.9969173074) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9741733670), FRAC_CONST(0.2258014232) } }, { { FRAC_CONST(0.9900237322), FRAC_CONST(-0.1409008205) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.2502108514), FRAC_CONST(0.9681913853) } }, { { FRAC_CONST(0.3534744382), FRAC_CONST(0.9354441762) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7427945137), FRAC_CONST(0.6695194840) } }, { { FRAC_CONST(-0.8358076215), FRAC_CONST(0.5490224361) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9370992780), FRAC_CONST(-0.3490629196) } }, { { FRAC_CONST(-0.7181259394), FRAC_CONST(-0.6959131360) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.1237744763), FRAC_CONST(-0.9923103452) } }, { { FRAC_CONST(0.5224990249), FRAC_CONST(-0.8526399136) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.8226406574), FRAC_CONST(-0.5685616732) } }, { { FRAC_CONST(0.9460852146), FRAC_CONST(0.3239179254) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.8844994903), FRAC_CONST(0.4665412009) } }, { { FRAC_CONST(-0.1097348556), FRAC_CONST(0.9939609170) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.0047125919), FRAC_CONST(0.9999889135) } }, { { FRAC_CONST(-0.9939610362), FRAC_CONST(0.1097337380) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8888573647), FRAC_CONST(0.4581840038) } }, { { FRAC_CONST(-0.3239168525), FRAC_CONST(-0.9460855722) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8172453642), FRAC_CONST(-0.5762898922) } }, { { FRAC_CONST(0.8526405096), FRAC_CONST(-0.5224980116) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.1331215799), FRAC_CONST(-0.9910997152) } }, { { FRAC_CONST(0.6959123611), FRAC_CONST(0.7181267142) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.9403476119), FRAC_CONST(-0.3402152061) } }, { { FRAC_CONST(-0.5490233898), FRAC_CONST(0.8358070254) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.7364512086), FRAC_CONST(0.6764906645) } }, { { FRAC_CONST(-0.9354437590), FRAC_CONST(-0.3534754813) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.2593250275), FRAC_CONST(0.9657900929) } }, { { FRAC_CONST(0.1409019381), FRAC_CONST(-0.9900235534) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9762582779), FRAC_CONST(0.2166097313) } }, { { FRAC_CONST(0.9969173670), FRAC_CONST(-0.0784583688) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.6434556246), FRAC_CONST(-0.7654833794) } }, { { FRAC_CONST(0.2940396070), FRAC_CONST(0.9557932615) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.3812320232), FRAC_CONST(-0.9244794250) } }, { { FRAC_CONST(-0.8686318994), FRAC_CONST(0.4954580069) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9959943891), FRAC_CONST(-0.0894154981) } }, { { FRAC_CONST(-0.6730118990), FRAC_CONST(-0.7396316528) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.5397993922), FRAC_CONST(0.8417937160) } }, { { FRAC_CONST(0.5750059485), FRAC_CONST(-0.8181492686) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.4968227744), FRAC_CONST(0.8678520322) } }, { { FRAC_CONST(0.9238792062), FRAC_CONST(0.3826842010) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9992290139), FRAC_CONST(-0.0392601527) } }, { { FRAC_CONST(-0.1719299555), FRAC_CONST(0.9851091504) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.4271997511), FRAC_CONST(-0.9041572809) } }, { { FRAC_CONST(-0.9988899231), FRAC_CONST(0.0471055657) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.6041822433), FRAC_CONST(-0.7968461514) } }, { { FRAC_CONST(-0.2638721764), FRAC_CONST(-0.9645576477) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9859085083), FRAC_CONST(0.1672853529) } }, { { FRAC_CONST(0.8837660551), FRAC_CONST(-0.4679289758) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.3075223565), FRAC_CONST(0.9515408874) } }, { { FRAC_CONST(0.6494473219), FRAC_CONST(0.7604066133) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.7015317082), FRAC_CONST(0.7126382589) } }, { { FRAC_CONST(-0.6004210114), FRAC_CONST(0.7996840477) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9562535882), FRAC_CONST(-0.2925389707) } }, { { FRAC_CONST(-0.9114028811), FRAC_CONST(-0.4115152657) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.1827499419), FRAC_CONST(-0.9831594229) } }, { { FRAC_CONST(0.2027882934), FRAC_CONST(-0.9792225957) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.7872582674), FRAC_CONST(-0.6166234016) } }, { { FRAC_CONST(0.9998766780), FRAC_CONST(-0.0157062728) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.9107555747), FRAC_CONST(0.4129458666) } }, { { FRAC_CONST(0.2334443331), FRAC_CONST(0.9723701477) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.0549497530), FRAC_CONST(0.9984891415) } }, { { FRAC_CONST(-0.8980280757), FRAC_CONST(0.4399381876) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.8599416018), FRAC_CONST(0.5103924870) } }, { { FRAC_CONST(-0.6252418160), FRAC_CONST(-0.7804310918) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(-0.8501682281), FRAC_CONST(-0.5265110731) } }, { { FRAC_CONST(0.6252435446), FRAC_CONST(-0.7804297209) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.0737608299), FRAC_CONST(-0.9972759485) } }, { { FRAC_CONST(0.8980270624), FRAC_CONST(0.4399402142) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.9183775187), FRAC_CONST(-0.3957053721) } }, { { FRAC_CONST(-0.2334465086), FRAC_CONST(0.9723696709) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.7754954696), FRAC_CONST(0.6313531399) } }, { { FRAC_CONST(-0.9998766184), FRAC_CONST(-0.0157085191) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.2012493610), FRAC_CONST(0.9795400500) } }, { { FRAC_CONST(-0.2027861029), FRAC_CONST(-0.9792230725) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.9615978599), FRAC_CONST(0.2744622827) } }, { { FRAC_CONST(0.9114037752), FRAC_CONST(-0.4115132093) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.6879743338), FRAC_CONST(-0.7257350087) } }, { { FRAC_CONST(0.6004192233), FRAC_CONST(0.7996854186) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(0.3254036009), FRAC_CONST(-0.9455752373) } }, { { FRAC_CONST(-0.6494490504), FRAC_CONST(0.7604051232) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.9888865948), FRAC_CONST(-0.1486719251) } }, { { FRAC_CONST(-0.8837650418), FRAC_CONST(-0.4679309726) }, { FRAC_CONST(0.9238795042), FRAC_CONST(-0.3826834261) }, { FRAC_CONST(0.5890548825), FRAC_CONST(0.8080930114) } }, { { FRAC_CONST(0.2638743520), FRAC_CONST(-0.9645570517) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.4441666007), FRAC_CONST(0.8959442377) } }, { { FRAC_CONST(0.9988898039), FRAC_CONST(0.0471078083) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(-0.9997915030), FRAC_CONST(0.0204183888) } }, { { FRAC_CONST(0.1719277352), FRAC_CONST(0.9851095676) }, { FRAC_CONST(0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.4803760946), FRAC_CONST(-0.8770626187) } }, { { FRAC_CONST(-0.9238800406), FRAC_CONST(0.3826821446) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(0.5555707216), FRAC_CONST(-0.8314692974) } }, { { FRAC_CONST(-0.5750041008), FRAC_CONST(-0.8181505203) }, { FRAC_CONST(0.3826834261), FRAC_CONST(-0.9238795042) }, { FRAC_CONST(0.9941320419), FRAC_CONST(0.1081734300) } } }; static const complex_t Phi_Fract_Qmf[] = { { FRAC_CONST(0.8181497455), FRAC_CONST(0.5750052333) }, { FRAC_CONST(-0.2638730407), FRAC_CONST(0.9645574093) }, { FRAC_CONST(-0.9969173074), FRAC_CONST(0.0784590989) }, { FRAC_CONST(-0.4115143716), FRAC_CONST(-0.9114032984) }, { FRAC_CONST(0.7181262970), FRAC_CONST(-0.6959127784) }, { FRAC_CONST(0.8980275989), FRAC_CONST(0.4399391711) }, { FRAC_CONST(-0.1097343117), FRAC_CONST(0.9939609766) }, { FRAC_CONST(-0.9723699093), FRAC_CONST(0.2334453613) }, { FRAC_CONST(-0.5490227938), FRAC_CONST(-0.8358073831) }, { FRAC_CONST(0.6004202366), FRAC_CONST(-0.7996846437) }, { FRAC_CONST(0.9557930231), FRAC_CONST(0.2940403223) }, { FRAC_CONST(0.0471064523), FRAC_CONST(0.9988898635) }, { FRAC_CONST(-0.9238795042), FRAC_CONST(0.3826834261) }, { FRAC_CONST(-0.6730124950), FRAC_CONST(-0.7396311164) }, { FRAC_CONST(0.4679298103), FRAC_CONST(-0.8837656379) }, { FRAC_CONST(0.9900236726), FRAC_CONST(0.1409012377) }, { FRAC_CONST(0.2027872950), FRAC_CONST(0.9792228341) }, { FRAC_CONST(-0.8526401520), FRAC_CONST(0.5224985480) }, { FRAC_CONST(-0.7804304361), FRAC_CONST(-0.6252426505) }, { FRAC_CONST(0.3239174187), FRAC_CONST(-0.9460853338) }, { FRAC_CONST(0.9998766184), FRAC_CONST(-0.0157073177) }, { FRAC_CONST(0.3534748554), FRAC_CONST(0.9354440570) }, { FRAC_CONST(-0.7604059577), FRAC_CONST(0.6494480371) }, { FRAC_CONST(-0.8686315417), FRAC_CONST(-0.4954586625) }, { FRAC_CONST(0.1719291061), FRAC_CONST(-0.9851093292) }, { FRAC_CONST(0.9851093292), FRAC_CONST(-0.1719291061) }, { FRAC_CONST(0.4954586625), FRAC_CONST(0.8686315417) }, { FRAC_CONST(-0.6494480371), FRAC_CONST(0.7604059577) }, { FRAC_CONST(-0.9354440570), FRAC_CONST(-0.3534748554) }, { FRAC_CONST(0.0157073177), FRAC_CONST(-0.9998766184) }, { FRAC_CONST(0.9460853338), FRAC_CONST(-0.3239174187) }, { FRAC_CONST(0.6252426505), FRAC_CONST(0.7804304361) }, { FRAC_CONST(-0.5224985480), FRAC_CONST(0.8526401520) }, { FRAC_CONST(-0.9792228341), FRAC_CONST(-0.2027872950) }, { FRAC_CONST(-0.1409012377), FRAC_CONST(-0.9900236726) }, { FRAC_CONST(0.8837656379), FRAC_CONST(-0.4679298103) }, { FRAC_CONST(0.7396311164), FRAC_CONST(0.6730124950) }, { FRAC_CONST(-0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.9988898635), FRAC_CONST(-0.0471064523) }, { FRAC_CONST(-0.2940403223), FRAC_CONST(-0.9557930231) }, { FRAC_CONST(0.7996846437), FRAC_CONST(-0.6004202366) }, { FRAC_CONST(0.8358073831), FRAC_CONST(0.5490227938) }, { FRAC_CONST(-0.2334453613), FRAC_CONST(0.9723699093) }, { FRAC_CONST(-0.9939609766), FRAC_CONST(0.1097343117) }, { FRAC_CONST(-0.4399391711), FRAC_CONST(-0.8980275989) }, { FRAC_CONST(0.6959127784), FRAC_CONST(-0.7181262970) }, { FRAC_CONST(0.9114032984), FRAC_CONST(0.4115143716) }, { FRAC_CONST(-0.0784590989), FRAC_CONST(0.9969173074) }, { FRAC_CONST(-0.9645574093), FRAC_CONST(0.2638730407) }, { FRAC_CONST(-0.5750052333), FRAC_CONST(-0.8181497455) }, { FRAC_CONST(0.5750052333), FRAC_CONST(-0.8181497455) }, { FRAC_CONST(0.9645574093), FRAC_CONST(0.2638730407) }, { FRAC_CONST(0.0784590989), FRAC_CONST(0.9969173074) }, { FRAC_CONST(-0.9114032984), FRAC_CONST(0.4115143716) }, { FRAC_CONST(-0.6959127784), FRAC_CONST(-0.7181262970) }, { FRAC_CONST(0.4399391711), FRAC_CONST(-0.8980275989) }, { FRAC_CONST(0.9939609766), FRAC_CONST(0.1097343117) }, { FRAC_CONST(0.2334453613), FRAC_CONST(0.9723699093) }, { FRAC_CONST(-0.8358073831), FRAC_CONST(0.5490227938) }, { FRAC_CONST(-0.7996846437), FRAC_CONST(-0.6004202366) }, { FRAC_CONST(0.2940403223), FRAC_CONST(-0.9557930231) }, { FRAC_CONST(0.9988898635), FRAC_CONST(-0.0471064523) }, { FRAC_CONST(0.3826834261), FRAC_CONST(0.9238795042) }, { FRAC_CONST(-0.7396311164), FRAC_CONST(0.6730124950) } }; /* static function declarations */ static void drm_ps_sa_element(drm_ps_info *ps, bitfile *ld); static void drm_ps_pan_element(drm_ps_info *ps, bitfile *ld); static int8_t huff_dec(bitfile *ld, drm_ps_huff_tab huff); uint16_t drm_ps_data(drm_ps_info *ps, bitfile *ld) { uint16_t bits = (uint16_t)faad_get_processed_bits(ld); ps->drm_ps_data_available = 1; ps->bs_enable_sa = faad_get1bit(ld); ps->bs_enable_pan = faad_get1bit(ld); if (ps->bs_enable_sa) { drm_ps_sa_element(ps, ld); } if (ps->bs_enable_pan) { drm_ps_pan_element(ps, ld); } bits = (uint16_t)faad_get_processed_bits(ld) - bits; return bits; } static void drm_ps_sa_element(drm_ps_info *ps, bitfile *ld) { drm_ps_huff_tab huff; uint8_t band; ps->bs_sa_dt_flag = faad_get1bit(ld); if (ps->bs_sa_dt_flag) { huff = t_huffman_sa; } else { huff = f_huffman_sa; } for (band = 0; band < DRM_NUM_SA_BANDS; band++) { ps->bs_sa_data[band] = huff_dec(ld, huff); } } static void drm_ps_pan_element(drm_ps_info *ps, bitfile *ld) { drm_ps_huff_tab huff; uint8_t band; ps->bs_pan_dt_flag = faad_get1bit(ld); if (ps->bs_pan_dt_flag) { huff = t_huffman_pan; } else { huff = f_huffman_pan; } for (band = 0; band < DRM_NUM_PAN_BANDS; band++) { ps->bs_pan_data[band] = huff_dec(ld, huff); } } /* binary search huffman decoding */ static int8_t huff_dec(bitfile *ld, drm_ps_huff_tab huff) { uint8_t bit; int16_t index = 0; while (index >= 0) { bit = (uint8_t)faad_get1bit(ld); index = huff[index][bit]; } return index + 15; } static int8_t sa_delta_clip(drm_ps_info *ps, int8_t i) { if (i < 0) { /* printf(" SAminclip %d", i); */ ps->sa_decode_error = 1; return 0; } else if (i > 7) { /* printf(" SAmaxclip %d", i); */ ps->sa_decode_error = 1; return 7; } else return i; } static int8_t pan_delta_clip(drm_ps_info *ps, int8_t i) { if (i < -7) { /* printf(" PANminclip %d", i); */ ps->pan_decode_error = 1; return -7; } else if (i > 7) { /* printf(" PANmaxclip %d", i); */ ps->pan_decode_error = 1; return 7; } else return i; } static void drm_ps_delta_decode(drm_ps_info *ps) { uint8_t band; if (ps->bs_enable_sa) { if (ps->bs_sa_dt_flag && !ps->g_last_had_sa) { /* wait until we get a DT frame */ ps->bs_enable_sa = 0; } else if (ps->bs_sa_dt_flag) { /* DT frame, we have a last frame, so we can decode */ ps->g_sa_index[0] = sa_delta_clip(ps, ps->g_prev_sa_index[0]+ps->bs_sa_data[0]); } else { /* DF always decodable */ ps->g_sa_index[0] = sa_delta_clip(ps,ps->bs_sa_data[0]); } for (band = 1; band < DRM_NUM_SA_BANDS; band++) { if (ps->bs_sa_dt_flag && ps->g_last_had_sa) { ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_prev_sa_index[band] + ps->bs_sa_data[band]); } else if (!ps->bs_sa_dt_flag) { ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_sa_index[band-1] + ps->bs_sa_data[band]); } } } /* An error during SA decoding implies PAN data will be undecodable, too */ /* Also, we don't like on/off switching in PS, so we force to last settings */ if (ps->sa_decode_error) { ps->pan_decode_error = 1; ps->bs_enable_pan = ps->g_last_had_pan; ps->bs_enable_sa = ps->g_last_had_sa; } if (ps->bs_enable_sa) { if (ps->sa_decode_error) { for (band = 0; band < DRM_NUM_SA_BANDS; band++) { ps->g_sa_index[band] = ps->g_last_good_sa_index[band]; } } else { for (band = 0; band < DRM_NUM_SA_BANDS; band++) { ps->g_last_good_sa_index[band] = ps->g_sa_index[band]; } } } if (ps->bs_enable_pan) { if (ps->bs_pan_dt_flag && !ps->g_last_had_pan) { ps->bs_enable_pan = 0; } else if (ps->bs_pan_dt_flag) { ps->g_pan_index[0] = pan_delta_clip(ps, ps->g_prev_pan_index[0]+ps->bs_pan_data[0]); } else { ps->g_pan_index[0] = pan_delta_clip(ps, ps->bs_pan_data[0]); } for (band = 1; band < DRM_NUM_PAN_BANDS; band++) { if (ps->bs_pan_dt_flag && ps->g_last_had_pan) { ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_prev_pan_index[band] + ps->bs_pan_data[band]); } else if (!ps->bs_pan_dt_flag) { ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_pan_index[band-1] + ps->bs_pan_data[band]); } } if (ps->pan_decode_error) { for (band = 0; band < DRM_NUM_PAN_BANDS; band++) { ps->g_pan_index[band] = ps->g_last_good_pan_index[band]; } } else { for (band = 0; band < DRM_NUM_PAN_BANDS; band++) { ps->g_last_good_pan_index[band] = ps->g_pan_index[band]; } } } } static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64]) { uint8_t s, b, k; complex_t qfrac, tmp0, tmp, in, R0; real_t peakdiff; real_t nrg; real_t power; real_t transratio; real_t new_delay_slopes[NUM_OF_LINKS]; uint8_t temp_delay_ser[NUM_OF_LINKS]; complex_t Phi_Fract; #ifdef FIXED_POINT uint32_t in_re, in_im; #endif for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++) { /* set delay indices */ for (k = 0; k < NUM_OF_LINKS; k++) temp_delay_ser[k] = ps->delay_buf_index_ser[k]; RE(Phi_Fract) = RE(Phi_Fract_Qmf[b]); IM(Phi_Fract) = IM(Phi_Fract_Qmf[b]); for (s = 0; s < NUM_OF_SUBSAMPLES; s++) { const real_t gamma = REAL_CONST(1.5); const real_t sigma = REAL_CONST(1.5625); RE(in) = QMF_RE(X[s][b]); IM(in) = QMF_IM(X[s][b]); #ifdef FIXED_POINT /* NOTE: all input is scaled by 2^(-5) because of fixed point QMF * meaning that P will be scaled by 2^(-10) compared to floating point version */ in_re = ((abs(RE(in))+(1<<(REAL_BITS-1)))>>REAL_BITS); in_im = ((abs(IM(in))+(1<<(REAL_BITS-1)))>>REAL_BITS); power = in_re*in_re + in_im*in_im; #else power = MUL_R(RE(in),RE(in)) + MUL_R(IM(in),IM(in)); #endif ps->peakdecay_fast[b] = MUL_F(ps->peakdecay_fast[b], peak_decay); if (ps->peakdecay_fast[b] < power) ps->peakdecay_fast[b] = power; peakdiff = ps->prev_peakdiff[b]; peakdiff += MUL_F((ps->peakdecay_fast[b] - power - ps->prev_peakdiff[b]), smooth_coeff); ps->prev_peakdiff[b] = peakdiff; nrg = ps->prev_nrg[b]; nrg += MUL_F((power - ps->prev_nrg[b]), smooth_coeff); ps->prev_nrg[b] = nrg; if (MUL_R(peakdiff, gamma) <= nrg) { transratio = sigma; } else { transratio = MUL_R(DIV_R(nrg, MUL_R(peakdiff, gamma)), sigma); } for (k = 0; k < NUM_OF_LINKS; k++) { new_delay_slopes[k] = MUL_F(g_decayslope[b], filter_coeff[k]); } RE(tmp0) = RE(ps->d_buff[0][b]); IM(tmp0) = IM(ps->d_buff[0][b]); RE(ps->d_buff[0][b]) = RE(ps->d_buff[1][b]); IM(ps->d_buff[0][b]) = IM(ps->d_buff[1][b]); RE(ps->d_buff[1][b]) = RE(in); IM(ps->d_buff[1][b]) = IM(in); ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Phi_Fract), IM(Phi_Fract)); RE(R0) = RE(tmp); IM(R0) = IM(tmp); for (k = 0; k < NUM_OF_LINKS; k++) { RE(qfrac) = RE(Q_Fract_allpass_Qmf[b][k]); IM(qfrac) = IM(Q_Fract_allpass_Qmf[b][k]); RE(tmp0) = RE(ps->d2_buff[k][temp_delay_ser[k]][b]); IM(tmp0) = IM(ps->d2_buff[k][temp_delay_ser[k]][b]); ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(qfrac), IM(qfrac)); RE(tmp) += -MUL_F(new_delay_slopes[k], RE(R0)); IM(tmp) += -MUL_F(new_delay_slopes[k], IM(R0)); RE(ps->d2_buff[k][temp_delay_ser[k]][b]) = RE(R0) + MUL_F(new_delay_slopes[k], RE(tmp)); IM(ps->d2_buff[k][temp_delay_ser[k]][b]) = IM(R0) + MUL_F(new_delay_slopes[k], IM(tmp)); RE(R0) = RE(tmp); IM(R0) = IM(tmp); } QMF_RE(ps->SA[s][b]) = MUL_R(RE(R0), transratio); QMF_IM(ps->SA[s][b]) = MUL_R(IM(R0), transratio); for (k = 0; k < NUM_OF_LINKS; k++) { if (++temp_delay_ser[k] >= delay_length[k]) temp_delay_ser[k] = 0; } } } for (k = 0; k < NUM_OF_LINKS; k++) ps->delay_buf_index_ser[k] = temp_delay_ser[k]; } static void drm_add_ambiance(drm_ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]) { uint8_t s, b, ifreq, qclass; real_t sa_map[MAX_SA_BAND], sa_dir_map[MAX_SA_BAND], k_sa_map[MAX_SA_BAND], k_sa_dir_map[MAX_SA_BAND]; real_t new_dir_map, new_sa_map; if (ps->bs_enable_sa) { /* Instead of dequantization and mapping, we use an inverse mapping to look up all the values we need */ for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++) { const real_t inv_f_num_of_subsamples = FRAC_CONST(0.03333333333); ifreq = sa_inv_freq[b]; qclass = (b != 0); sa_map[b] = sa_quant[ps->g_prev_sa_index[ifreq]][qclass]; new_sa_map = sa_quant[ps->g_sa_index[ifreq]][qclass]; k_sa_map[b] = MUL_F(inv_f_num_of_subsamples, (new_sa_map - sa_map[b])); sa_dir_map[b] = sa_sqrt_1_minus[ps->g_prev_sa_index[ifreq]][qclass]; new_dir_map = sa_sqrt_1_minus[ps->g_sa_index[ifreq]][qclass]; k_sa_dir_map[b] = MUL_F(inv_f_num_of_subsamples, (new_dir_map - sa_dir_map[b])); } for (s = 0; s < NUM_OF_SUBSAMPLES; s++) { for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++) { QMF_RE(X_right[s][b]) = MUL_F(QMF_RE(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_RE(ps->SA[s][b]), sa_map[b]); QMF_IM(X_right[s][b]) = MUL_F(QMF_IM(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_IM(ps->SA[s][b]), sa_map[b]); QMF_RE(X_left[s][b]) = MUL_F(QMF_RE(X_left[s][b]), sa_dir_map[b]) + MUL_F(QMF_RE(ps->SA[s][b]), sa_map[b]); QMF_IM(X_left[s][b]) = MUL_F(QMF_IM(X_left[s][b]), sa_dir_map[b]) + MUL_F(QMF_IM(ps->SA[s][b]), sa_map[b]); sa_map[b] += k_sa_map[b]; sa_dir_map[b] += k_sa_dir_map[b]; } for (b = sa_freq_scale[DRM_NUM_SA_BANDS]; b < NUM_OF_QMF_CHANNELS; b++) { QMF_RE(X_right[s][b]) = QMF_RE(X_left[s][b]); QMF_IM(X_right[s][b]) = QMF_IM(X_left[s][b]); } } } else { for (s = 0; s < NUM_OF_SUBSAMPLES; s++) { for (b = 0; b < NUM_OF_QMF_CHANNELS; b++) { QMF_RE(X_right[s][b]) = QMF_RE(X_left[s][b]); QMF_IM(X_right[s][b]) = QMF_IM(X_left[s][b]); } } } } static void drm_add_pan(drm_ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]) { uint8_t s, b, qclass, ifreq; real_t tmp, coeff1, coeff2; real_t pan_base[MAX_PAN_BAND]; real_t pan_delta[MAX_PAN_BAND]; qmf_t temp_l, temp_r; if (ps->bs_enable_pan) { for (b = 0; b < NUM_OF_QMF_CHANNELS; b++) { /* Instead of dequantization, 20->64 mapping and 2^G(x,y) we do an inverse mapping 64->20 and look up the 2^G(x,y) values directly */ ifreq = pan_inv_freq[b]; qclass = pan_quant_class[ifreq]; if (ps->g_prev_pan_index[ifreq] >= 0) { pan_base[b] = pan_pow_2_pos[ps->g_prev_pan_index[ifreq]][qclass]; } else { pan_base[b] = pan_pow_2_neg[-ps->g_prev_pan_index[ifreq]][qclass]; } /* 2^((a-b)/30) = 2^(a/30) * 1/(2^(b/30)) */ /* a en b can be negative so we may need to inverse parts */ if (ps->g_pan_index[ifreq] >= 0) { if (ps->g_prev_pan_index[ifreq] >= 0) { pan_delta[b] = MUL_C(pan_pow_2_30_pos[ps->g_pan_index[ifreq]][qclass], pan_pow_2_30_neg[ps->g_prev_pan_index[ifreq]][qclass]); } else { pan_delta[b] = MUL_C(pan_pow_2_30_pos[ps->g_pan_index[ifreq]][qclass], pan_pow_2_30_pos[-ps->g_prev_pan_index[ifreq]][qclass]); } } else { if (ps->g_prev_pan_index[ifreq] >= 0) { pan_delta[b] = MUL_C(pan_pow_2_30_neg[-ps->g_pan_index[ifreq]][qclass], pan_pow_2_30_neg[ps->g_prev_pan_index[ifreq]][qclass]); } else { pan_delta[b] = MUL_C(pan_pow_2_30_neg[-ps->g_pan_index[ifreq]][qclass], pan_pow_2_30_pos[-ps->g_prev_pan_index[ifreq]][qclass]); } } } for (s = 0; s < NUM_OF_SUBSAMPLES; s++) { /* PAN always uses all 64 channels */ for (b = 0; b < NUM_OF_QMF_CHANNELS; b++) { tmp = pan_base[b]; coeff2 = DIV_R(REAL_CONST(2.0), (REAL_CONST(1.0) + tmp)); coeff1 = MUL_R(coeff2, tmp); QMF_RE(temp_l) = QMF_RE(X_left[s][b]); QMF_IM(temp_l) = QMF_IM(X_left[s][b]); QMF_RE(temp_r) = QMF_RE(X_right[s][b]); QMF_IM(temp_r) = QMF_IM(X_right[s][b]); QMF_RE(X_left[s][b]) = MUL_R(QMF_RE(temp_l), coeff1); QMF_IM(X_left[s][b]) = MUL_R(QMF_IM(temp_l), coeff1); QMF_RE(X_right[s][b]) = MUL_R(QMF_RE(temp_r), coeff2); QMF_IM(X_right[s][b]) = MUL_R(QMF_IM(temp_r), coeff2); /* 2^(a+k*b) = 2^a * 2^b * ... * 2^b */ /* ^^^^^^^^^^^^^^^ k times */ pan_base[b] = MUL_C(pan_base[b], pan_delta[b]); } } } } drm_ps_info *drm_ps_init(void) { drm_ps_info *ps = (drm_ps_info*)faad_malloc(sizeof(drm_ps_info)); memset(ps, 0, sizeof(drm_ps_info)); return ps; } void drm_ps_free(drm_ps_info *ps) { faad_free(ps); } /* main DRM PS decoding function */ uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, qmf_t X_left[38][64], qmf_t X_right[38][64]) { if (ps == NULL) { memcpy(X_right, X_left, sizeof(qmf_t)*30*64); return 0; } if (!ps->drm_ps_data_available && !guess) { memcpy(X_right, X_left, sizeof(qmf_t)*30*64); memset(ps->g_prev_sa_index, 0, sizeof(ps->g_prev_sa_index)); memset(ps->g_prev_pan_index, 0, sizeof(ps->g_prev_pan_index)); return 0; } /* if SBR CRC doesn't match out, we can assume decode errors to start with, and we'll guess what the parameters should be */ if (!guess) { ps->sa_decode_error = 0; ps->pan_decode_error = 0; drm_ps_delta_decode(ps); } else { ps->sa_decode_error = 1; ps->pan_decode_error = 1; /* don't even bother decoding */ } ps->drm_ps_data_available = 0; drm_calc_sa_side_signal(ps, X_left); drm_add_ambiance(ps, X_left, X_right); if (ps->bs_enable_sa) { ps->g_last_had_sa = 1; memcpy(ps->g_prev_sa_index, ps->g_sa_index, sizeof(int8_t) * DRM_NUM_SA_BANDS); } else { ps->g_last_had_sa = 0; } if (ps->bs_enable_pan) { drm_add_pan(ps, X_left, X_right); ps->g_last_had_pan = 1; memcpy(ps->g_prev_pan_index, ps->g_pan_index, sizeof(int8_t) * DRM_NUM_PAN_BANDS); } else { ps->g_last_had_pan = 0; } return 0; } #endif xine-lib-1.2/contrib/libfaad/syntax.c0000644000175000017500000024200314647725151015400 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: syntax.c,v 1.93 2009/01/26 23:51:15 menno Exp $ **/ /* Reads the AAC bitstream as defined in 14496-3 (MPEG-4 Audio) */ #include "common.h" #include "structs.h" #include #include #include #include "syntax.h" #include "specrec.h" #include "huffman.h" #include "bits.h" #include "pulse.h" #include "analysis.h" #include "drc.h" #ifdef ERROR_RESILIENCE #include "rvlc.h" #endif #ifdef SBR_DEC #include "sbr_syntax.h" #endif #include "mp4.h" /* static function declarations */ static void decode_sce_lfe(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, uint8_t id_syn_ele); static void decode_cpe(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, uint8_t id_syn_ele); static uint8_t single_lfe_channel_element(NeAACDecStruct *hDecoder, bitfile *ld, uint8_t channel, uint8_t *tag); static uint8_t channel_pair_element(NeAACDecStruct *hDecoder, bitfile *ld, uint8_t channel, uint8_t *tag); #ifdef COUPLING_DEC static uint8_t coupling_channel_element(NeAACDecStruct *hDecoder, bitfile *ld); #endif static uint16_t data_stream_element(NeAACDecStruct *hDecoder, bitfile *ld); static uint8_t program_config_element(program_config *pce, bitfile *ld); static uint8_t fill_element(NeAACDecStruct *hDecoder, bitfile *ld, drc_info *drc #ifdef SBR_DEC ,uint8_t sbr_ele #endif ); static uint8_t individual_channel_stream(NeAACDecStruct *hDecoder, element *ele, bitfile *ld, ic_stream *ics, uint8_t scal_flag, int16_t *spec_data); static uint8_t ics_info(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld, uint8_t common_window); static uint8_t section_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld); static uint8_t scale_factor_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld); #ifdef SSR_DEC static void gain_control_data(bitfile *ld, ic_stream *ics); #endif static uint8_t spectral_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld, int16_t *spectral_data); static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count); static uint8_t pulse_data(ic_stream *ics, pulse_info *pul, bitfile *ld); static void tns_data(ic_stream *ics, tns_info *tns, bitfile *ld); #ifdef LTP_DEC static uint8_t ltp_data(NeAACDecStruct *hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld); #endif static uint8_t adts_fixed_header(adts_header *adts, bitfile *ld); static void adts_variable_header(adts_header *adts, bitfile *ld); static void adts_error_check(adts_header *adts, bitfile *ld); static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc); static uint8_t excluded_channels(bitfile *ld, drc_info *drc); static uint8_t side_info(NeAACDecStruct *hDecoder, element *ele, bitfile *ld, ic_stream *ics, uint8_t scal_flag); #ifdef DRM static int8_t DRM_aac_scalable_main_header(NeAACDecStruct *hDecoder, ic_stream *ics1, ic_stream *ics2, bitfile *ld, uint8_t this_layer_stereo); #endif /* Table 4.4.1 */ int8_t GASpecificConfig(bitfile *ld, mp4AudioSpecificConfig *mp4ASC, program_config *pce_out) { program_config pce; /* 1024 or 960 */ mp4ASC->frameLengthFlag = faad_get1bit(ld DEBUGVAR(1,138,"GASpecificConfig(): FrameLengthFlag")); #ifndef ALLOW_SMALL_FRAMELENGTH if (mp4ASC->frameLengthFlag == 1) return -3; #endif mp4ASC->dependsOnCoreCoder = faad_get1bit(ld DEBUGVAR(1,139,"GASpecificConfig(): DependsOnCoreCoder")); if (mp4ASC->dependsOnCoreCoder == 1) { mp4ASC->coreCoderDelay = (uint16_t)faad_getbits(ld, 14 DEBUGVAR(1,140,"GASpecificConfig(): CoreCoderDelay")); } mp4ASC->extensionFlag = faad_get1bit(ld DEBUGVAR(1,141,"GASpecificConfig(): ExtensionFlag")); if (mp4ASC->channelsConfiguration == 0) { if (program_config_element(&pce, ld)) return -3; //mp4ASC->channelsConfiguration = pce.channels; if (pce_out != NULL) memcpy(pce_out, &pce, sizeof(program_config)); /* if (pce.num_valid_cc_elements) return -3; */ } #ifdef ERROR_RESILIENCE if (mp4ASC->extensionFlag == 1) { /* Error resilience not supported yet */ if (mp4ASC->objectTypeIndex >= ER_OBJECT_START) { mp4ASC->aacSectionDataResilienceFlag = faad_get1bit(ld DEBUGVAR(1,144,"GASpecificConfig(): aacSectionDataResilienceFlag")); mp4ASC->aacScalefactorDataResilienceFlag = faad_get1bit(ld DEBUGVAR(1,145,"GASpecificConfig(): aacScalefactorDataResilienceFlag")); mp4ASC->aacSpectralDataResilienceFlag = faad_get1bit(ld DEBUGVAR(1,146,"GASpecificConfig(): aacSpectralDataResilienceFlag")); } /* 1 bit: extensionFlag3 */ faad_getbits(ld, 1); } #endif return 0; } /* Table 4.4.2 */ /* An MPEG-4 Audio decoder is only required to follow the Program Configuration Element in GASpecificConfig(). The decoder shall ignore any Program Configuration Elements that may occur in raw data blocks. PCEs transmitted in raw data blocks cannot be used to convey decoder configuration information. */ static uint8_t program_config_element(program_config *pce, bitfile *ld) { uint8_t i; memset(pce, 0, sizeof(program_config)); pce->channels = 0; pce->element_instance_tag = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,10,"program_config_element(): element_instance_tag")); pce->object_type = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,11,"program_config_element(): object_type")); pce->sf_index = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,12,"program_config_element(): sf_index")); pce->num_front_channel_elements = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,13,"program_config_element(): num_front_channel_elements")); pce->num_side_channel_elements = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,14,"program_config_element(): num_side_channel_elements")); pce->num_back_channel_elements = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,15,"program_config_element(): num_back_channel_elements")); pce->num_lfe_channel_elements = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,16,"program_config_element(): num_lfe_channel_elements")); pce->num_assoc_data_elements = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,17,"program_config_element(): num_assoc_data_elements")); pce->num_valid_cc_elements = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,18,"program_config_element(): num_valid_cc_elements")); pce->mono_mixdown_present = faad_get1bit(ld DEBUGVAR(1,19,"program_config_element(): mono_mixdown_present")); if (pce->mono_mixdown_present == 1) { pce->mono_mixdown_element_number = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,20,"program_config_element(): mono_mixdown_element_number")); } pce->stereo_mixdown_present = faad_get1bit(ld DEBUGVAR(1,21,"program_config_element(): stereo_mixdown_present")); if (pce->stereo_mixdown_present == 1) { pce->stereo_mixdown_element_number = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,22,"program_config_element(): stereo_mixdown_element_number")); } pce->matrix_mixdown_idx_present = faad_get1bit(ld DEBUGVAR(1,23,"program_config_element(): matrix_mixdown_idx_present")); if (pce->matrix_mixdown_idx_present == 1) { pce->matrix_mixdown_idx = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,24,"program_config_element(): matrix_mixdown_idx")); pce->pseudo_surround_enable = faad_get1bit(ld DEBUGVAR(1,25,"program_config_element(): pseudo_surround_enable")); } for (i = 0; i < pce->num_front_channel_elements; i++) { pce->front_element_is_cpe[i] = faad_get1bit(ld DEBUGVAR(1,26,"program_config_element(): front_element_is_cpe")); pce->front_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,27,"program_config_element(): front_element_tag_select")); if (pce->front_element_is_cpe[i] & 1) { pce->cpe_channel[pce->front_element_tag_select[i]] = pce->channels; pce->num_front_channels += 2; pce->channels += 2; } else { pce->sce_channel[pce->front_element_tag_select[i]] = pce->channels; pce->num_front_channels++; pce->channels++; } } for (i = 0; i < pce->num_side_channel_elements; i++) { pce->side_element_is_cpe[i] = faad_get1bit(ld DEBUGVAR(1,28,"program_config_element(): side_element_is_cpe")); pce->side_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,29,"program_config_element(): side_element_tag_select")); if (pce->side_element_is_cpe[i] & 1) { pce->cpe_channel[pce->side_element_tag_select[i]] = pce->channels; pce->num_side_channels += 2; pce->channels += 2; } else { pce->sce_channel[pce->side_element_tag_select[i]] = pce->channels; pce->num_side_channels++; pce->channels++; } } for (i = 0; i < pce->num_back_channel_elements; i++) { pce->back_element_is_cpe[i] = faad_get1bit(ld DEBUGVAR(1,30,"program_config_element(): back_element_is_cpe")); pce->back_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,31,"program_config_element(): back_element_tag_select")); if (pce->back_element_is_cpe[i] & 1) { pce->cpe_channel[pce->back_element_tag_select[i]] = pce->channels; pce->channels += 2; pce->num_back_channels += 2; } else { pce->sce_channel[pce->back_element_tag_select[i]] = pce->channels; pce->num_back_channels++; pce->channels++; } } for (i = 0; i < pce->num_lfe_channel_elements; i++) { pce->lfe_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,32,"program_config_element(): lfe_element_tag_select")); pce->sce_channel[pce->lfe_element_tag_select[i]] = pce->channels; pce->num_lfe_channels++; pce->channels++; } for (i = 0; i < pce->num_assoc_data_elements; i++) pce->assoc_data_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,33,"program_config_element(): assoc_data_element_tag_select")); for (i = 0; i < pce->num_valid_cc_elements; i++) { pce->cc_element_is_ind_sw[i] = faad_get1bit(ld DEBUGVAR(1,34,"program_config_element(): cc_element_is_ind_sw")); pce->valid_cc_element_tag_select[i] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,35,"program_config_element(): valid_cc_element_tag_select")); } faad_byte_align(ld); pce->comment_field_bytes = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(1,36,"program_config_element(): comment_field_bytes")); for (i = 0; i < pce->comment_field_bytes; i++) { pce->comment_field_data[i] = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(1,37,"program_config_element(): comment_field_data")); } pce->comment_field_data[i] = 0; if (pce->channels > MAX_CHANNELS) return 22; return 0; } static void decode_sce_lfe(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, uint8_t id_syn_ele) { uint8_t channels = hDecoder->fr_channels; uint8_t tag = 0; if (channels+1 > MAX_CHANNELS) { hInfo->error = 12; return; } if (hDecoder->fr_ch_ele+1 > MAX_SYNTAX_ELEMENTS) { hInfo->error = 13; return; } /* for SCE hDecoder->element_output_channels[] is not set here because this can become 2 when some form of Parametric Stereo coding is used */ /* save the syntax element id */ hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele; /* decode the element */ hInfo->error = single_lfe_channel_element(hDecoder, ld, channels, &tag); /* map output channels position to internal data channels */ if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2) { /* this might be faulty when pce_set is true */ hDecoder->internal_channel[channels] = channels; hDecoder->internal_channel[channels+1] = channels+1; } else { if (hDecoder->pce_set) hDecoder->internal_channel[hDecoder->pce.sce_channel[tag]] = channels; else hDecoder->internal_channel[channels] = channels; } hDecoder->fr_channels += hDecoder->element_output_channels[hDecoder->fr_ch_ele]; hDecoder->fr_ch_ele++; } static void decode_cpe(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, uint8_t id_syn_ele) { uint8_t channels = hDecoder->fr_channels; uint8_t tag = 0; if (channels+2 > MAX_CHANNELS) { hInfo->error = 12; return; } if (hDecoder->fr_ch_ele+1 > MAX_SYNTAX_ELEMENTS) { hInfo->error = 13; return; } /* for CPE the number of output channels is always 2 */ if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 0) { /* element_output_channels not set yet */ hDecoder->element_output_channels[hDecoder->fr_ch_ele] = 2; } else if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] != 2) { /* element inconsistency */ hInfo->error = 21; return; } /* save the syntax element id */ hDecoder->element_id[hDecoder->fr_ch_ele] = id_syn_ele; /* decode the element */ hInfo->error = channel_pair_element(hDecoder, ld, channels, &tag); /* map output channel position to internal data channels */ if (hDecoder->pce_set) { hDecoder->internal_channel[hDecoder->pce.cpe_channel[tag]] = channels; hDecoder->internal_channel[hDecoder->pce.cpe_channel[tag]+1] = channels+1; } else { hDecoder->internal_channel[channels] = channels; hDecoder->internal_channel[channels+1] = channels+1; } hDecoder->fr_channels += 2; hDecoder->fr_ch_ele++; } void raw_data_block(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, program_config *pce, drc_info *drc) { uint8_t id_syn_ele; uint8_t ele_this_frame = 0; hDecoder->fr_channels = 0; hDecoder->fr_ch_ele = 0; hDecoder->first_syn_ele = 25; hDecoder->has_lfe = 0; #ifdef ERROR_RESILIENCE if (hDecoder->object_type < ER_OBJECT_START) #endif { /* Table 4.4.3: raw_data_block() */ while ((id_syn_ele = (uint8_t)faad_getbits(ld, LEN_SE_ID DEBUGVAR(1,4,"NeAACDecDecode(): id_syn_ele"))) != ID_END) { switch (id_syn_ele) { case ID_SCE: ele_this_frame++; if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele; decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele); if (hInfo->error > 0) return; break; case ID_CPE: ele_this_frame++; if (hDecoder->first_syn_ele == 25) hDecoder->first_syn_ele = id_syn_ele; decode_cpe(hDecoder, hInfo, ld, id_syn_ele); if (hInfo->error > 0) return; break; case ID_LFE: #ifdef DRM hInfo->error = 32; #else ele_this_frame++; hDecoder->has_lfe++; decode_sce_lfe(hDecoder, hInfo, ld, id_syn_ele); #endif if (hInfo->error > 0) return; break; case ID_CCE: /* not implemented yet, but skip the bits */ #ifdef DRM hInfo->error = 32; #else ele_this_frame++; #ifdef COUPLING_DEC hInfo->error = coupling_channel_element(hDecoder, ld); #else hInfo->error = 6; #endif #endif if (hInfo->error > 0) return; break; case ID_DSE: ele_this_frame++; data_stream_element(hDecoder, ld); break; case ID_PCE: if (ele_this_frame != 0) { hInfo->error = 31; return; } ele_this_frame++; /* 14496-4: 5.6.4.1.2.1.3: */ /* program_configuration_element()'s in access units shall be ignored */ program_config_element(pce, ld); //if ((hInfo->error = program_config_element(pce, ld)) > 0) // return; //hDecoder->pce_set = 1; break; case ID_FIL: ele_this_frame++; /* one sbr_info describes a channel_element not a channel! */ /* if we encounter SBR data here: error */ /* SBR data will be read directly in the SCE/LFE/CPE element */ if ((hInfo->error = fill_element(hDecoder, ld, drc #ifdef SBR_DEC , INVALID_SBR_ELEMENT #endif )) > 0) return; break; } } } #ifdef ERROR_RESILIENCE else { /* Table 262: er_raw_data_block() */ switch (hDecoder->channelConfiguration) { case 1: decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE); if (hInfo->error > 0) return; break; case 2: decode_cpe(hDecoder, hInfo, ld, ID_CPE); if (hInfo->error > 0) return; break; case 3: decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); if (hInfo->error > 0) return; break; case 4: decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE); if (hInfo->error > 0) return; break; case 5: decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); if (hInfo->error > 0) return; break; case 6: decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); decode_sce_lfe(hDecoder, hInfo, ld, ID_LFE); if (hInfo->error > 0) return; break; case 7: /* 8 channels */ decode_sce_lfe(hDecoder, hInfo, ld, ID_SCE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); decode_cpe(hDecoder, hInfo, ld, ID_CPE); decode_sce_lfe(hDecoder, hInfo, ld, ID_LFE); if (hInfo->error > 0) return; break; default: hInfo->error = 7; return; } #if 0 cnt = bits_to_decode() / 8; while (cnt >= 1) { cnt -= extension_payload(cnt); } #endif } #endif /* new in corrigendum 14496-3:2002 */ #ifdef DRM if (hDecoder->object_type != DRM_ER_LC #if 0 && !hDecoder->latm_header_present #endif ) #endif { faad_byte_align(ld); } return; } /* Table 4.4.4 and */ /* Table 4.4.9 */ static uint8_t single_lfe_channel_element(NeAACDecStruct *hDecoder, bitfile *ld, uint8_t channel, uint8_t *tag) { uint8_t retval = 0; element sce = ELEMENT_INIT; ic_stream *ics = &(sce.ics1); ALIGN int16_t spec_data[1024] = {0}; sce.element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG DEBUGVAR(1,38,"single_lfe_channel_element(): element_instance_tag")); *tag = sce.element_instance_tag; sce.channel = channel; sce.paired_channel = -1; retval = individual_channel_stream(hDecoder, &sce, ld, ics, 0, spec_data); if (retval > 0) return retval; /* IS not allowed in single channel */ if (ics->is_used) return 32; #ifdef SBR_DEC /* check if next bitstream element is a fill element */ /* if so, read it now so SBR decoding can be done in case of a file with SBR */ if (faad_showbits(ld, LEN_SE_ID) == ID_FIL) { faad_flushbits(ld, LEN_SE_ID); /* one sbr_info describes a channel_element not a channel! */ if ((retval = fill_element(hDecoder, ld, hDecoder->drc, hDecoder->fr_ch_ele)) > 0) { return retval; } } #endif /* noiseless coding is done, spectral reconstruction is done now */ retval = reconstruct_single_channel(hDecoder, ics, &sce, spec_data); if (retval > 0) return retval; return 0; } /* Table 4.4.5 */ static uint8_t channel_pair_element(NeAACDecStruct *hDecoder, bitfile *ld, uint8_t channels, uint8_t *tag) { ALIGN int16_t spec_data1[1024] = {0}; ALIGN int16_t spec_data2[1024] = {0}; element cpe = ELEMENT_INIT; ic_stream *ics1 = &(cpe.ics1); ic_stream *ics2 = &(cpe.ics2); uint8_t result; cpe.channel = channels; cpe.paired_channel = channels+1; cpe.element_instance_tag = (uint8_t)faad_getbits(ld, LEN_TAG DEBUGVAR(1,39,"channel_pair_element(): element_instance_tag")); *tag = cpe.element_instance_tag; if ((cpe.common_window = faad_get1bit(ld DEBUGVAR(1,40,"channel_pair_element(): common_window"))) & 1) { /* both channels have common ics information */ if ((result = ics_info(hDecoder, ics1, ld, cpe.common_window)) > 0) return result; ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,41,"channel_pair_element(): ms_mask_present")); if (ics1->ms_mask_present == 3) { /* bitstream error */ return 32; } if (ics1->ms_mask_present == 1) { uint8_t g, sfb; for (g = 0; g < ics1->num_window_groups; g++) { for (sfb = 0; sfb < ics1->max_sfb; sfb++) { ics1->ms_used[g][sfb] = faad_get1bit(ld DEBUGVAR(1,42,"channel_pair_element(): faad_get1bit")); } } } #ifdef ERROR_RESILIENCE if ((hDecoder->object_type >= ER_OBJECT_START) && (ics1->predictor_data_present)) { if (( #ifdef LTP_DEC ics1->ltp.data_present = #endif faad_get1bit(ld DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1) { #ifdef LTP_DEC if ((result = ltp_data(hDecoder, ics1, &(ics1->ltp), ld)) > 0) { return result; } #else return 26; #endif } } #endif memcpy(ics2, ics1, sizeof(ic_stream)); } else { ics1->ms_mask_present = 0; } if ((result = individual_channel_stream(hDecoder, &cpe, ld, ics1, 0, spec_data1)) > 0) { return result; } #ifdef ERROR_RESILIENCE if (cpe.common_window && (hDecoder->object_type >= ER_OBJECT_START) && (ics1->predictor_data_present)) { if (( #ifdef LTP_DEC ics1->ltp2.data_present = #endif faad_get1bit(ld DEBUGVAR(1,50,"channel_pair_element(): ltp.data_present"))) & 1) { #ifdef LTP_DEC if ((result = ltp_data(hDecoder, ics1, &(ics1->ltp2), ld)) > 0) { return result; } #else return 26; #endif } } #endif if ((result = individual_channel_stream(hDecoder, &cpe, ld, ics2, 0, spec_data2)) > 0) { return result; } #ifdef SBR_DEC /* check if next bitstream element is a fill element */ /* if so, read it now so SBR decoding can be done in case of a file with SBR */ if (faad_showbits(ld, LEN_SE_ID) == ID_FIL) { faad_flushbits(ld, LEN_SE_ID); /* one sbr_info describes a channel_element not a channel! */ if ((result = fill_element(hDecoder, ld, hDecoder->drc, hDecoder->fr_ch_ele)) > 0) { return result; } } #endif /* noiseless coding is done, spectral reconstruction is done now */ if ((result = reconstruct_channel_pair(hDecoder, ics1, ics2, &cpe, spec_data1, spec_data2)) > 0) { return result; } return 0; } /* Table 4.4.6 */ static uint8_t ics_info(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld, uint8_t common_window) { uint8_t retval = 0; uint8_t ics_reserved_bit; ics_reserved_bit = faad_get1bit(ld DEBUGVAR(1,43,"ics_info(): ics_reserved_bit")); if (ics_reserved_bit != 0) return 32; ics->window_sequence = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,44,"ics_info(): window_sequence")); ics->window_shape = faad_get1bit(ld DEBUGVAR(1,45,"ics_info(): window_shape")); #ifdef LD_DEC /* No block switching in LD */ if ((hDecoder->object_type == LD) && (ics->window_sequence != ONLY_LONG_SEQUENCE)) return 32; #endif if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) { ics->max_sfb = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,46,"ics_info(): max_sfb (short)")); ics->scale_factor_grouping = (uint8_t)faad_getbits(ld, 7 DEBUGVAR(1,47,"ics_info(): scale_factor_grouping")); } else { ics->max_sfb = (uint8_t)faad_getbits(ld, 6 DEBUGVAR(1,48,"ics_info(): max_sfb (long)")); } /* get the grouping information */ if ((retval = window_grouping_info(hDecoder, ics)) > 0) return retval; /* should be an error */ /* check the range of max_sfb */ if (ics->max_sfb > ics->num_swb) return 16; if (ics->window_sequence != EIGHT_SHORT_SEQUENCE) { if ((ics->predictor_data_present = faad_get1bit(ld DEBUGVAR(1,49,"ics_info(): predictor_data_present"))) & 1) { if (hDecoder->object_type == MAIN) /* MPEG2 style AAC predictor */ { uint8_t sfb; uint8_t limit = min(ics->max_sfb, max_pred_sfb(hDecoder->sf_index)); #ifdef MAIN_DEC ics->pred.limit = limit; #endif if (( #ifdef MAIN_DEC ics->pred.predictor_reset = #endif faad_get1bit(ld DEBUGVAR(1,53,"ics_info(): pred.predictor_reset"))) & 1) { #ifdef MAIN_DEC ics->pred.predictor_reset_group_number = #endif (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,54,"ics_info(): pred.predictor_reset_group_number")); } for (sfb = 0; sfb < limit; sfb++) { #ifdef MAIN_DEC ics->pred.prediction_used[sfb] = #endif faad_get1bit(ld DEBUGVAR(1,55,"ics_info(): pred.prediction_used")); } } #ifdef LTP_DEC else { /* Long Term Prediction */ if (hDecoder->object_type < ER_OBJECT_START) { if ((ics->ltp.data_present = faad_get1bit(ld DEBUGVAR(1,50,"ics_info(): ltp.data_present"))) & 1) { if ((retval = ltp_data(hDecoder, ics, &(ics->ltp), ld)) > 0) { return retval; } } if (common_window) { if ((ics->ltp2.data_present = faad_get1bit(ld DEBUGVAR(1,51,"ics_info(): ltp2.data_present"))) & 1) { if ((retval = ltp_data(hDecoder, ics, &(ics->ltp2), ld)) > 0) { return retval; } } } } #ifdef ERROR_RESILIENCE if (!common_window && (hDecoder->object_type >= ER_OBJECT_START)) { if ((ics->ltp.data_present = faad_get1bit(ld DEBUGVAR(1,50,"ics_info(): ltp.data_present"))) & 1) { ltp_data(hDecoder, ics, &(ics->ltp), ld); } } #endif } #endif } } return retval; } /* Table 4.4.7 */ static uint8_t pulse_data(ic_stream *ics, pulse_info *pul, bitfile *ld) { uint8_t i; pul->number_pulse = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,56,"pulse_data(): number_pulse")); pul->pulse_start_sfb = (uint8_t)faad_getbits(ld, 6 DEBUGVAR(1,57,"pulse_data(): pulse_start_sfb")); /* check the range of pulse_start_sfb */ if (pul->pulse_start_sfb > ics->num_swb) return 16; for (i = 0; i < pul->number_pulse+1; i++) { pul->pulse_offset[i] = (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,58,"pulse_data(): pulse_offset")); #if 0 printf("%d\n", pul->pulse_offset[i]); #endif pul->pulse_amp[i] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,59,"pulse_data(): pulse_amp")); #if 0 printf("%d\n", pul->pulse_amp[i]); #endif } return 0; } #ifdef COUPLING_DEC /* Table 4.4.8: Currently just for skipping the bits... */ static uint8_t coupling_channel_element(NeAACDecStruct *hDecoder, bitfile *ld) { uint8_t c, result = 0; uint8_t ind_sw_cce_flag = 0; uint8_t num_gain_element_lists = 0; uint8_t num_coupled_elements = 0; element el_empty = ELEMENT_INIT; ic_stream ics_empty = {0}; int16_t sh_data[1024]; c = faad_getbits(ld, LEN_TAG DEBUGVAR(1,900,"coupling_channel_element(): element_instance_tag")); ind_sw_cce_flag = faad_get1bit(ld DEBUGVAR(1,901,"coupling_channel_element(): ind_sw_cce_flag")); num_coupled_elements = faad_getbits(ld, 3 DEBUGVAR(1,902,"coupling_channel_element(): num_coupled_elements")); for (c = 0; c < num_coupled_elements + 1; c++) { uint8_t cc_target_is_cpe, cc_target_tag_select; num_gain_element_lists++; cc_target_is_cpe = faad_get1bit(ld DEBUGVAR(1,903,"coupling_channel_element(): cc_target_is_cpe")); cc_target_tag_select = faad_getbits(ld, 4 DEBUGVAR(1,904,"coupling_channel_element(): cc_target_tag_select")); if (cc_target_is_cpe) { uint8_t cc_l = faad_get1bit(ld DEBUGVAR(1,905,"coupling_channel_element(): cc_l")); uint8_t cc_r = faad_get1bit(ld DEBUGVAR(1,906,"coupling_channel_element(): cc_r")); if (cc_l && cc_r) num_gain_element_lists++; } } faad_get1bit(ld DEBUGVAR(1,907,"coupling_channel_element(): cc_domain")); faad_get1bit(ld DEBUGVAR(1,908,"coupling_channel_element(): gain_element_sign")); faad_getbits(ld, 2 DEBUGVAR(1,909,"coupling_channel_element(): gain_element_scale")); if ((result = individual_channel_stream(hDecoder, &el_empty, ld, &ics_empty, 0, sh_data)) > 0) { return result; } /* IS not allowed in single channel */ if (ics->is_used) return 32; for (c = 1; c < num_gain_element_lists; c++) { uint8_t cge; if (ind_sw_cce_flag) { cge = 1; } else { cge = faad_get1bit(ld DEBUGVAR(1,910,"coupling_channel_element(): common_gain_element_present")); } if (cge) { huffman_scale_factor(ld); } else { uint8_t g, sfb; for (g = 0; g < ics_empty.num_window_groups; g++) { for (sfb = 0; sfb < ics_empty.max_sfb; sfb++) { if (ics_empty.sfb_cb[g][sfb] != ZERO_HCB) huffman_scale_factor(ld); } } } } return 0; } #endif /* Table 4.4.10 */ static uint16_t data_stream_element(NeAACDecStruct *hDecoder, bitfile *ld) { uint8_t byte_aligned; uint16_t i, count; (void)hDecoder; /* element_instance_tag = */ faad_getbits(ld, LEN_TAG DEBUGVAR(1,60,"data_stream_element(): element_instance_tag")); byte_aligned = faad_get1bit(ld DEBUGVAR(1,61,"data_stream_element(): byte_aligned")); count = (uint16_t)faad_getbits(ld, 8 DEBUGVAR(1,62,"data_stream_element(): count")); if (count == 255) { count += (uint16_t)faad_getbits(ld, 8 DEBUGVAR(1,63,"data_stream_element(): extra count")); } if (byte_aligned) faad_byte_align(ld); for (i = 0; i < count; i++) { faad_getbits(ld, LEN_BYTE DEBUGVAR(1,64,"data_stream_element(): data_stream_byte")); } return count; } /* Table 4.4.11 */ static uint8_t fill_element(NeAACDecStruct *hDecoder, bitfile *ld, drc_info *drc #ifdef SBR_DEC ,uint8_t sbr_ele #endif ) { uint16_t count; #ifdef SBR_DEC uint8_t bs_extension_type; #endif count = (uint16_t)faad_getbits(ld, 4 DEBUGVAR(1,65,"fill_element(): count")); if (count == 15) { count += (uint16_t)faad_getbits(ld, 8 DEBUGVAR(1,66,"fill_element(): extra count")) - 1; } if (count > 0) { #ifdef SBR_DEC bs_extension_type = (uint8_t)faad_showbits(ld, 4); if ((bs_extension_type == EXT_SBR_DATA) || (bs_extension_type == EXT_SBR_DATA_CRC)) { if (sbr_ele == INVALID_SBR_ELEMENT) return 24; if (!hDecoder->sbr[sbr_ele]) { hDecoder->sbr[sbr_ele] = sbrDecodeInit(hDecoder->frameLength, hDecoder->element_id[sbr_ele], 2*get_sample_rate(hDecoder->sf_index), hDecoder->downSampledSBR #ifdef DRM , 0 #endif ); } hDecoder->sbr_present_flag = 1; /* parse the SBR data */ hDecoder->sbr[sbr_ele]->ret = sbr_extension_data(ld, hDecoder->sbr[sbr_ele], count, hDecoder->postSeekResetFlag); #if 0 if (hDecoder->sbr[sbr_ele]->ret > 0) { printf("%s\n", NeAACDecGetErrorMessage(hDecoder->sbr[sbr_ele]->ret)); } #endif #if (defined(PS_DEC) || defined(DRM_PS)) if (hDecoder->sbr[sbr_ele]->ps_used) { hDecoder->ps_used[sbr_ele] = 1; /* set element independent flag to 1 as well */ hDecoder->ps_used_global = 1; } #endif } else #endif { #ifndef DRM while (count > 0) { count -= extension_payload(ld, drc, count); } #else return 30; #endif } } return 0; } /* Table 4.4.12 */ #ifdef SSR_DEC static void gain_control_data(bitfile *ld, ic_stream *ics) { uint8_t bd, wd, ad; ssr_info *ssr = &(ics->ssr); ssr->max_band = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,1000,"gain_control_data(): max_band")); if (ics->window_sequence == ONLY_LONG_SEQUENCE) { for (bd = 1; bd <= ssr->max_band; bd++) { for (wd = 0; wd < 1; wd++) { ssr->adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,1001,"gain_control_data(): adjust_num")); for (ad = 0; ad < ssr->adjust_num[bd][wd]; ad++) { ssr->alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,1002,"gain_control_data(): alevcode")); ssr->aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,1003,"gain_control_data(): aloccode")); } } } } else if (ics->window_sequence == LONG_START_SEQUENCE) { for (bd = 1; bd <= ssr->max_band; bd++) { for (wd = 0; wd < 2; wd++) { ssr->adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,1001,"gain_control_data(): adjust_num")); for (ad = 0; ad < ssr->adjust_num[bd][wd]; ad++) { ssr->alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,1002,"gain_control_data(): alevcode")); if (wd == 0) { ssr->aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,1003,"gain_control_data(): aloccode")); } else { ssr->aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,1003,"gain_control_data(): aloccode")); } } } } } else if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) { for (bd = 1; bd <= ssr->max_band; bd++) { for (wd = 0; wd < 8; wd++) { ssr->adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,1001,"gain_control_data(): adjust_num")); for (ad = 0; ad < ssr->adjust_num[bd][wd]; ad++) { ssr->alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,1002,"gain_control_data(): alevcode")); ssr->aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,1003,"gain_control_data(): aloccode")); } } } } else if (ics->window_sequence == LONG_STOP_SEQUENCE) { for (bd = 1; bd <= ssr->max_band; bd++) { for (wd = 0; wd < 2; wd++) { ssr->adjust_num[bd][wd] = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,1001,"gain_control_data(): adjust_num")); for (ad = 0; ad < ssr->adjust_num[bd][wd]; ad++) { ssr->alevcode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,1002,"gain_control_data(): alevcode")); if (wd == 0) { ssr->aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,1003,"gain_control_data(): aloccode")); } else { ssr->aloccode[bd][wd][ad] = (uint8_t)faad_getbits(ld, 5 DEBUGVAR(1,1003,"gain_control_data(): aloccode")); } } } } } } #endif #ifdef DRM /* Table 4.4.13 ASME */ void DRM_aac_scalable_main_element(NeAACDecStruct *hDecoder, NeAACDecFrameInfo *hInfo, bitfile *ld, program_config *pce, drc_info *drc) { uint8_t retval = 0; uint8_t channels = hDecoder->fr_channels = 0; uint8_t ch; uint8_t this_layer_stereo = (hDecoder->channelConfiguration > 1) ? 1 : 0; element cpe = ELEMENT_INIT; ic_stream *ics1 = &(cpe.ics1); ic_stream *ics2 = &(cpe.ics2); int16_t *spec_data; ALIGN int16_t spec_data1[1024] = {0}; ALIGN int16_t spec_data2[1024] = {0}; hDecoder->fr_ch_ele = 0; hInfo->error = DRM_aac_scalable_main_header(hDecoder, ics1, ics2, ld, this_layer_stereo); if (hInfo->error > 0) return; cpe.common_window = 1; if (this_layer_stereo) { hDecoder->element_id[0] = ID_CPE; if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 0) hDecoder->element_output_channels[hDecoder->fr_ch_ele] = 2; } else { hDecoder->element_id[0] = ID_SCE; } if (this_layer_stereo) { cpe.channel = 0; cpe.paired_channel = 1; } /* Stereo2 / Mono1 */ ics1->tns_data_present = faad_get1bit(ld); #if defined(LTP_DEC) ics1->ltp.data_present = faad_get1bit(ld); #elif defined (DRM) if(faad_get1bit(ld)) { hInfo->error = 26; return; } #else faad_get1bit(ld); #endif hInfo->error = side_info(hDecoder, &cpe, ld, ics1, 1); if (hInfo->error > 0) return; if (this_layer_stereo) { /* Stereo3 */ ics2->tns_data_present = faad_get1bit(ld); #ifdef LTP_DEC ics1->ltp.data_present = #endif faad_get1bit(ld); hInfo->error = side_info(hDecoder, &cpe, ld, ics2, 1); if (hInfo->error > 0) return; } /* Stereo4 / Mono2 */ if (ics1->tns_data_present) tns_data(ics1, &(ics1->tns), ld); if (this_layer_stereo) { /* Stereo5 */ if (ics2->tns_data_present) tns_data(ics2, &(ics2->tns), ld); } #ifdef DRM /* CRC check */ if (hDecoder->object_type == DRM_ER_LC) { if ((hInfo->error = (uint8_t)faad_check_CRC(ld, (uint16_t)faad_get_processed_bits(ld) - 8)) > 0) return; } #endif /* Stereo6 / Mono3 */ /* error resilient spectral data decoding */ if ((hInfo->error = reordered_spectral_data(hDecoder, ics1, ld, spec_data1)) > 0) { return; } if (this_layer_stereo) { /* Stereo7 */ /* error resilient spectral data decoding */ if ((hInfo->error = reordered_spectral_data(hDecoder, ics2, ld, spec_data2)) > 0) { return; } } #ifdef DRM #ifdef SBR_DEC /* In case of DRM we need to read the SBR info before channel reconstruction */ if ((hDecoder->sbr_present_flag == 1) && (hDecoder->object_type == DRM_ER_LC)) { bitfile ld_sbr = {0}; uint32_t i; uint16_t count = 0; uint8_t *revbuffer; uint8_t *prevbufstart; uint8_t *pbufend; /* all forward bitreading should be finished at this point */ uint32_t bitsconsumed = faad_get_processed_bits(ld); uint32_t buffer_size = faad_origbitbuffer_size(ld); uint8_t *buffer = (uint8_t*)faad_origbitbuffer(ld); if (bitsconsumed + 8 > buffer_size*8) { hInfo->error = 14; return; } if (!hDecoder->sbr[0]) { hDecoder->sbr[0] = sbrDecodeInit(hDecoder->frameLength, hDecoder->element_id[0], 2*get_sample_rate(hDecoder->sf_index), 0 /* ds SBR */, 1); } /* Reverse bit reading of SBR data in DRM audio frame */ revbuffer = (uint8_t*)faad_malloc(buffer_size*sizeof(uint8_t)); prevbufstart = revbuffer; pbufend = &buffer[buffer_size - 1]; for (i = 0; i < buffer_size; i++) *prevbufstart++ = tabFlipbits[*pbufend--]; /* Set SBR data */ /* consider 8 bits from AAC-CRC */ /* SBR buffer size is original buffer size minus AAC buffer size */ count = (uint16_t)bit2byte(buffer_size*8 - bitsconsumed); faad_initbits(&ld_sbr, revbuffer, count); hDecoder->sbr[0]->sample_rate = get_sample_rate(hDecoder->sf_index); hDecoder->sbr[0]->sample_rate *= 2; faad_getbits(&ld_sbr, 8); /* Skip 8-bit CRC */ hDecoder->sbr[0]->ret = sbr_extension_data(&ld_sbr, hDecoder->sbr[0], count, hDecoder->postSeekResetFlag); #if (defined(PS_DEC) || defined(DRM_PS)) if (hDecoder->sbr[0]->ps_used) { hDecoder->ps_used[0] = 1; hDecoder->ps_used_global = 1; } #endif if (ld_sbr.error) { hDecoder->sbr[0]->ret = 1; } /* check CRC */ /* no need to check it if there was already an error */ if (hDecoder->sbr[0]->ret == 0) hDecoder->sbr[0]->ret = (uint8_t)faad_check_CRC(&ld_sbr, (uint16_t)faad_get_processed_bits(&ld_sbr) - 8); /* SBR data was corrupted, disable it until the next header */ if (hDecoder->sbr[0]->ret != 0) { hDecoder->sbr[0]->header_count = 0; } faad_endbits(&ld_sbr); if (revbuffer) faad_free(revbuffer); } #endif #endif if (this_layer_stereo) { hInfo->error = reconstruct_channel_pair(hDecoder, ics1, ics2, &cpe, spec_data1, spec_data2); if (hInfo->error > 0) return; } else { hInfo->error = reconstruct_single_channel(hDecoder, ics1, &cpe, spec_data1); if (hInfo->error > 0) return; } /* map output channels position to internal data channels */ if (hDecoder->element_output_channels[hDecoder->fr_ch_ele] == 2) { /* this might be faulty when pce_set is true */ hDecoder->internal_channel[channels] = channels; hDecoder->internal_channel[channels+1] = channels+1; } else { hDecoder->internal_channel[channels] = channels; } hDecoder->fr_channels += hDecoder->element_output_channels[hDecoder->fr_ch_ele]; hDecoder->fr_ch_ele++; return; } /* Table 4.4.15 */ static int8_t DRM_aac_scalable_main_header(NeAACDecStruct *hDecoder, ic_stream *ics1, ic_stream *ics2, bitfile *ld, uint8_t this_layer_stereo) { uint8_t retval = 0; uint8_t ch; ic_stream *ics; uint8_t ics_reserved_bit; ics_reserved_bit = faad_get1bit(ld DEBUGVAR(1,300,"aac_scalable_main_header(): ics_reserved_bits")); if (ics_reserved_bit != 0) return 32; ics1->window_sequence = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,301,"aac_scalable_main_header(): window_sequence")); ics1->window_shape = faad_get1bit(ld DEBUGVAR(1,302,"aac_scalable_main_header(): window_shape")); if (ics1->window_sequence == EIGHT_SHORT_SEQUENCE) { ics1->max_sfb = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,303,"aac_scalable_main_header(): max_sfb (short)")); ics1->scale_factor_grouping = (uint8_t)faad_getbits(ld, 7 DEBUGVAR(1,304,"aac_scalable_main_header(): scale_factor_grouping")); } else { ics1->max_sfb = (uint8_t)faad_getbits(ld, 6 DEBUGVAR(1,305,"aac_scalable_main_header(): max_sfb (long)")); } /* get the grouping information */ if ((retval = window_grouping_info(hDecoder, ics1)) > 0) return retval; /* should be an error */ /* check the range of max_sfb */ if (ics1->max_sfb > ics1->num_swb) return 16; if (this_layer_stereo) { ics1->ms_mask_present = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,306,"aac_scalable_main_header(): ms_mask_present")); if (ics1->ms_mask_present == 3) { /* bitstream error */ return 32; } if (ics1->ms_mask_present == 1) { uint8_t g, sfb; for (g = 0; g < ics1->num_window_groups; g++) { for (sfb = 0; sfb < ics1->max_sfb; sfb++) { ics1->ms_used[g][sfb] = faad_get1bit(ld DEBUGVAR(1,307,"aac_scalable_main_header(): faad_get1bit")); } } } memcpy(ics2, ics1, sizeof(ic_stream)); } else { ics1->ms_mask_present = 0; } return 0; } #endif static uint8_t side_info(NeAACDecStruct *hDecoder, element *ele, bitfile *ld, ic_stream *ics, uint8_t scal_flag) { uint8_t result; ics->global_gain = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(1,67,"individual_channel_stream(): global_gain")); if (!ele->common_window && !scal_flag) { if ((result = ics_info(hDecoder, ics, ld, ele->common_window)) > 0) return result; } if ((result = section_data(hDecoder, ics, ld)) > 0) return result; if ((result = scale_factor_data(hDecoder, ics, ld)) > 0) return result; if (!scal_flag) { /** ** NOTE: It could be that pulse data is available in scalable AAC too, ** as said in Amendment 1, this could be only the case for ER AAC, ** though. (have to check this out later) **/ /* get pulse data */ if ((ics->pulse_data_present = faad_get1bit(ld DEBUGVAR(1,68,"individual_channel_stream(): pulse_data_present"))) & 1) { if ((result = pulse_data(ics, &(ics->pul), ld)) > 0) return result; } /* get tns data */ if ((ics->tns_data_present = faad_get1bit(ld DEBUGVAR(1,69,"individual_channel_stream(): tns_data_present"))) & 1) { #ifdef ERROR_RESILIENCE if (hDecoder->object_type < ER_OBJECT_START) #endif tns_data(ics, &(ics->tns), ld); } /* get gain control data */ if ((ics->gain_control_data_present = faad_get1bit(ld DEBUGVAR(1,70,"individual_channel_stream(): gain_control_data_present"))) & 1) { #ifdef SSR_DEC if (hDecoder->object_type != SSR) return 1; else gain_control_data(ld, ics); #else return 1; #endif } } #ifdef ERROR_RESILIENCE if (hDecoder->aacSpectralDataResilienceFlag) { ics->length_of_reordered_spectral_data = (uint16_t)faad_getbits(ld, 14 DEBUGVAR(1,147,"individual_channel_stream(): length_of_reordered_spectral_data")); if (hDecoder->channelConfiguration == 2) { if (ics->length_of_reordered_spectral_data > 6144) ics->length_of_reordered_spectral_data = 6144; } else { if (ics->length_of_reordered_spectral_data > 12288) ics->length_of_reordered_spectral_data = 12288; } ics->length_of_longest_codeword = (uint8_t)faad_getbits(ld, 6 DEBUGVAR(1,148,"individual_channel_stream(): length_of_longest_codeword")); if (ics->length_of_longest_codeword >= 49) ics->length_of_longest_codeword = 49; } /* RVLC spectral data is put here */ if (hDecoder->aacScalefactorDataResilienceFlag) { if ((result = rvlc_decode_scale_factors(ics, ld)) > 0) return result; } #endif return 0; } /* Table 4.4.24 */ static uint8_t individual_channel_stream(NeAACDecStruct *hDecoder, element *ele, bitfile *ld, ic_stream *ics, uint8_t scal_flag, int16_t *spec_data) { uint8_t result; result = side_info(hDecoder, ele, ld, ics, scal_flag); if (result > 0) return result; if (hDecoder->object_type >= ER_OBJECT_START) { if (ics->tns_data_present) tns_data(ics, &(ics->tns), ld); } #ifdef DRM /* CRC check */ if (hDecoder->object_type == DRM_ER_LC) { if ((result = (uint8_t)faad_check_CRC(ld, (uint16_t)faad_get_processed_bits(ld) - 8)) > 0) return result; } #endif #ifdef ERROR_RESILIENCE if (hDecoder->aacSpectralDataResilienceFlag) { /* error resilient spectral data decoding */ if ((result = reordered_spectral_data(hDecoder, ics, ld, spec_data)) > 0) { return result; } } else #endif { /* decode the spectral data */ if ((result = spectral_data(hDecoder, ics, ld, spec_data)) > 0) { return result; } } /* pulse coding reconstruction */ if (ics->pulse_data_present) { if (ics->window_sequence != EIGHT_SHORT_SEQUENCE) { if ((result = pulse_decode(ics, spec_data, hDecoder->frameLength)) > 0) return result; } else { return 2; /* pulse coding not allowed for short blocks */ } } return 0; } /* Table 4.4.25 */ static uint8_t section_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld) { uint8_t g; uint8_t sect_esc_val, sect_bits; if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) sect_bits = 3; else sect_bits = 5; sect_esc_val = (1<max_sfb); printf(" sect top cb\n"); #endif for (g = 0; g < ics->num_window_groups; g++) { uint8_t k = 0; uint8_t i = 0; while (k < ics->max_sfb) { #ifdef ERROR_RESILIENCE uint8_t vcb11 = 0; #endif uint8_t sfb; uint8_t sect_len_incr; uint16_t sect_len = 0; uint8_t sect_cb_bits = 4; /* if "faad_getbits" detects error and returns "0", "k" is never incremented and we cannot leave the while loop */ if (ld->error != 0) return 14; #ifdef ERROR_RESILIENCE if (hDecoder->aacSectionDataResilienceFlag) sect_cb_bits = 5; #endif ics->sect_cb[g][i] = (uint8_t)faad_getbits(ld, sect_cb_bits DEBUGVAR(1,71,"section_data(): sect_cb")); if (ics->sect_cb[g][i] == 12) return 32; #if 0 printf("%d\n", ics->sect_cb[g][i]); #endif #ifndef DRM if (ics->sect_cb[g][i] == NOISE_HCB) ics->noise_used = 1; #else /* PNS not allowed in DRM */ if (ics->sect_cb[g][i] == NOISE_HCB) return 29; #endif if (ics->sect_cb[g][i] == INTENSITY_HCB2 || ics->sect_cb[g][i] == INTENSITY_HCB) ics->is_used = 1; #ifdef ERROR_RESILIENCE if (hDecoder->aacSectionDataResilienceFlag) { if ((ics->sect_cb[g][i] == 11) || ((ics->sect_cb[g][i] >= 16) && (ics->sect_cb[g][i] <= 32))) { vcb11 = 1; } } if (vcb11) { sect_len_incr = 1; } else #endif { sect_len_incr = (uint8_t)faad_getbits(ld, sect_bits DEBUGVAR(1,72,"section_data(): sect_len_incr")); } while ((sect_len_incr == sect_esc_val) /* && (k+sect_len < ics->max_sfb)*/) { sect_len += sect_len_incr; sect_len_incr = (uint8_t)faad_getbits(ld, sect_bits DEBUGVAR(1,72,"section_data(): sect_len_incr")); } sect_len += sect_len_incr; ics->sect_start[g][i] = k; ics->sect_end[g][i] = k + sect_len; #if 0 printf("%d\n", ics->sect_start[g][i]); #endif #if 0 printf("%d\n", ics->sect_end[g][i]); #endif if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) { if (k + sect_len > 8*15) return 15; if (i >= 8*15) return 15; } else { if (k + sect_len > MAX_SFB) return 15; if (i >= MAX_SFB) return 15; } for (sfb = k; sfb < k + sect_len; sfb++) { ics->sfb_cb[g][sfb] = ics->sect_cb[g][i]; #if 0 printf("%d\n", ics->sfb_cb[g][sfb]); #endif } #if 0 printf(" %6d %6d %6d\n", i, ics->sect_end[g][i], ics->sect_cb[g][i]); #endif k += sect_len; i++; } ics->num_sec[g] = i; /* the sum of all sect_len_incr elements for a given window * group shall equal max_sfb */ if (k != ics->max_sfb) { return 32; } #if 0 printf("%d\n", ics->num_sec[g]); #endif } #if 0 printf("\n"); #endif return 0; } /* * decode_scale_factors() * decodes the scalefactors from the bitstream */ /* * All scalefactors (and also the stereo positions and pns energies) are * transmitted using Huffman coded DPCM relative to the previous active * scalefactor (respectively previous stereo position or previous pns energy, * see subclause 4.6.2 and 4.6.3). The first active scalefactor is * differentially coded relative to the global gain. */ static uint8_t decode_scale_factors(ic_stream *ics, bitfile *ld) { uint8_t g, sfb; int16_t t; int8_t noise_pcm_flag = 1; int16_t scale_factor = ics->global_gain; int16_t is_position = 0; int16_t noise_energy = ics->global_gain - 90; for (g = 0; g < ics->num_window_groups; g++) { for (sfb = 0; sfb < ics->max_sfb; sfb++) { switch (ics->sfb_cb[g][sfb]) { case ZERO_HCB: /* zero book */ ics->scale_factors[g][sfb] = 0; //#define SF_PRINT #ifdef SF_PRINT printf("%d\n", ics->scale_factors[g][sfb]); #endif break; case INTENSITY_HCB: /* intensity books */ case INTENSITY_HCB2: /* decode intensity position */ t = huffman_scale_factor(ld); is_position += (t - 60); ics->scale_factors[g][sfb] = is_position; #ifdef SF_PRINT printf("%d\n", ics->scale_factors[g][sfb]); #endif break; case NOISE_HCB: /* noise books */ #ifndef DRM /* decode noise energy */ if (noise_pcm_flag) { noise_pcm_flag = 0; t = (int16_t)faad_getbits(ld, 9 DEBUGVAR(1,73,"scale_factor_data(): first noise")) - 256; } else { t = huffman_scale_factor(ld); t -= 60; } noise_energy += t; ics->scale_factors[g][sfb] = noise_energy; #ifdef SF_PRINT printf("%d\n", ics->scale_factors[g][sfb]); #endif #else /* PNS not allowed in DRM */ return 29; #endif break; default: /* spectral books */ /* ics->scale_factors[g][sfb] must be between 0 and 255 */ ics->scale_factors[g][sfb] = 0; /* decode scale factor */ t = huffman_scale_factor(ld); scale_factor += (t - 60); if (scale_factor < 0 || scale_factor > 255) return 4; ics->scale_factors[g][sfb] = scale_factor; #ifdef SF_PRINT printf("%d\n", ics->scale_factors[g][sfb]); #endif break; } } } return 0; } /* Table 4.4.26 */ static uint8_t scale_factor_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld) { uint8_t ret = 0; #ifdef PROFILE int64_t count = faad_get_ts(); #endif #ifdef ERROR_RESILIENCE if (!hDecoder->aacScalefactorDataResilienceFlag) #endif { ret = decode_scale_factors(ics, ld); } #ifdef ERROR_RESILIENCE else { /* In ER AAC the parameters for RVLC are seperated from the actual data that holds the scale_factors. Strangely enough, 2 parameters for HCR are put inbetween them. */ ret = rvlc_scale_factor_data(ics, ld); } #endif #ifdef PROFILE count = faad_get_ts() - count; hDecoder->scalefac_cycles += count; #endif return ret; } /* Table 4.4.27 */ static void tns_data(ic_stream *ics, tns_info *tns, bitfile *ld) { uint8_t w, filt, i, start_coef_bits, coef_bits; uint8_t n_filt_bits = 2; uint8_t length_bits = 6; uint8_t order_bits = 5; if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) { n_filt_bits = 1; length_bits = 4; order_bits = 3; } for (w = 0; w < ics->num_windows; w++) { tns->n_filt[w] = (uint8_t)faad_getbits(ld, n_filt_bits DEBUGVAR(1,74,"tns_data(): n_filt")); #if 0 printf("%d\n", tns->n_filt[w]); #endif if (tns->n_filt[w]) { if ((tns->coef_res[w] = faad_get1bit(ld DEBUGVAR(1,75,"tns_data(): coef_res"))) & 1) { start_coef_bits = 4; } else { start_coef_bits = 3; } #if 0 printf("%d\n", tns->coef_res[w]); #endif } for (filt = 0; filt < tns->n_filt[w]; filt++) { tns->length[w][filt] = (uint8_t)faad_getbits(ld, length_bits DEBUGVAR(1,76,"tns_data(): length")); #if 0 printf("%d\n", tns->length[w][filt]); #endif tns->order[w][filt] = (uint8_t)faad_getbits(ld, order_bits DEBUGVAR(1,77,"tns_data(): order")); #if 0 printf("%d\n", tns->order[w][filt]); #endif if (tns->order[w][filt]) { tns->direction[w][filt] = faad_get1bit(ld DEBUGVAR(1,78,"tns_data(): direction")); #if 0 printf("%d\n", tns->direction[w][filt]); #endif tns->coef_compress[w][filt] = faad_get1bit(ld DEBUGVAR(1,79,"tns_data(): coef_compress")); #if 0 printf("%d\n", tns->coef_compress[w][filt]); #endif coef_bits = start_coef_bits - tns->coef_compress[w][filt]; for (i = 0; i < tns->order[w][filt]; i++) { tns->coef[w][filt][i] = (uint8_t)faad_getbits(ld, coef_bits DEBUGVAR(1,80,"tns_data(): coef")); #if 0 printf("%d\n", tns->coef[w][filt][i]); #endif } } } } } #ifdef LTP_DEC /* Table 4.4.28 */ static uint8_t ltp_data(NeAACDecStruct *hDecoder, ic_stream *ics, ltp_info *ltp, bitfile *ld) { uint8_t sfb, w; ltp->lag = 0; #ifdef LD_DEC if (hDecoder->object_type == LD) { ltp->lag_update = (uint8_t)faad_getbits(ld, 1 DEBUGVAR(1,142,"ltp_data(): lag_update")); if (ltp->lag_update) { ltp->lag = (uint16_t)faad_getbits(ld, 10 DEBUGVAR(1,81,"ltp_data(): lag")); } } else #endif { ltp->lag = (uint16_t)faad_getbits(ld, 11 DEBUGVAR(1,81,"ltp_data(): lag")); } /* Check length of lag */ if (ltp->lag > (hDecoder->frameLength << 1)) return 18; ltp->coef = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,82,"ltp_data(): coef")); if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) { for (w = 0; w < ics->num_windows; w++) { if ((ltp->short_used[w] = faad_get1bit(ld DEBUGVAR(1,83,"ltp_data(): short_used"))) & 1) { ltp->short_lag_present[w] = faad_get1bit(ld DEBUGVAR(1,84,"ltp_data(): short_lag_present")); if (ltp->short_lag_present[w]) { ltp->short_lag[w] = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,85,"ltp_data(): short_lag")); } } } } else { ltp->last_band = (ics->max_sfb < MAX_LTP_SFB ? ics->max_sfb : MAX_LTP_SFB); for (sfb = 0; sfb < ltp->last_band; sfb++) { ltp->long_used[sfb] = faad_get1bit(ld DEBUGVAR(1,86,"ltp_data(): long_used")); } } return 0; } #endif /* Table 4.4.29 */ static uint8_t spectral_data(NeAACDecStruct *hDecoder, ic_stream *ics, bitfile *ld, int16_t *spectral_data) { int8_t i; uint8_t g; uint16_t inc, k, p = 0; uint8_t groups = 0; uint8_t sect_cb; uint8_t result; uint16_t nshort = hDecoder->frameLength/8; #ifdef PROFILE int64_t count = faad_get_ts(); #endif for(g = 0; g < ics->num_window_groups; g++) { p = groups*nshort; for (i = 0; i < ics->num_sec[g]; i++) { sect_cb = ics->sect_cb[g][i]; inc = (sect_cb >= FIRST_PAIR_HCB) ? 2 : 4; switch (sect_cb) { case ZERO_HCB: case NOISE_HCB: case INTENSITY_HCB: case INTENSITY_HCB2: //#define SD_PRINT #ifdef SD_PRINT { int j; for (j = ics->sect_sfb_offset[g][ics->sect_start[g][i]]; j < ics->sect_sfb_offset[g][ics->sect_end[g][i]]; j++) { printf("%d\n", 0); } } #endif //#define SFBO_PRINT #ifdef SFBO_PRINT printf("%d\n", ics->sect_sfb_offset[g][ics->sect_start[g][i]]); #endif p += (ics->sect_sfb_offset[g][ics->sect_end[g][i]] - ics->sect_sfb_offset[g][ics->sect_start[g][i]]); break; default: #ifdef SFBO_PRINT printf("%d\n", ics->sect_sfb_offset[g][ics->sect_start[g][i]]); #endif for (k = ics->sect_sfb_offset[g][ics->sect_start[g][i]]; k < ics->sect_sfb_offset[g][ics->sect_end[g][i]]; k += inc) { if ((result = huffman_spectral_data(sect_cb, ld, &spectral_data[p])) > 0) return result; #ifdef SD_PRINT { int j; for (j = p; j < p+inc; j++) { printf("%d\n", spectral_data[j]); } } #endif p += inc; } break; } } groups += ics->window_group_length[g]; } #ifdef PROFILE count = faad_get_ts() - count; hDecoder->spectral_cycles += count; #endif return 0; } /* Table 4.4.30 */ static uint16_t extension_payload(bitfile *ld, drc_info *drc, uint16_t count) { uint16_t i, n, dataElementLength; uint8_t dataElementLengthPart; uint8_t align = 4, data_element_version, loopCounter; uint8_t extension_type = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,87,"extension_payload(): extension_type")); switch (extension_type) { case EXT_DYNAMIC_RANGE: drc->present = 1; n = dynamic_range_info(ld, drc); return n; case EXT_FILL_DATA: /* fill_nibble = */ faad_getbits(ld, 4 DEBUGVAR(1,136,"extension_payload(): fill_nibble")); /* must be 0000 */ for (i = 0; i < count-1; i++) { /* fill_byte[i] = */ faad_getbits(ld, 8 DEBUGVAR(1,88,"extension_payload(): fill_byte")); /* must be 10100101 */ } return count; case EXT_DATA_ELEMENT: data_element_version = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,400,"extension_payload(): data_element_version")); switch (data_element_version) { case ANC_DATA: loopCounter = 0; dataElementLength = 0; do { dataElementLengthPart = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(1,401,"extension_payload(): dataElementLengthPart")); dataElementLength += dataElementLengthPart; loopCounter++; } while (dataElementLengthPart == 255); for (i = 0; i < dataElementLength; i++) { /* data_element_byte[i] = */ faad_getbits(ld, 8 DEBUGVAR(1,402,"extension_payload(): data_element_byte")); } return (dataElementLength+loopCounter+1); default: align = 0; } /* FIXME */ /* fall through */ case EXT_FIL: default: faad_getbits(ld, align DEBUGVAR(1,88,"extension_payload(): fill_nibble")); for (i = 0; i < count-1; i++) { /* other_bits[i] = */ faad_getbits(ld, 8 DEBUGVAR(1,89,"extension_payload(): fill_bit")); } return count; } } /* Table 4.4.31 */ static uint8_t dynamic_range_info(bitfile *ld, drc_info *drc) { uint8_t i, n = 1; uint8_t band_incr; drc->num_bands = 1; if (faad_get1bit(ld DEBUGVAR(1,90,"dynamic_range_info(): has instance_tag")) & 1) { drc->pce_instance_tag = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,91,"dynamic_range_info(): pce_instance_tag")); /* drc->drc_tag_reserved_bits = */ faad_getbits(ld, 4 DEBUGVAR(1,92,"dynamic_range_info(): drc_tag_reserved_bits")); n++; } drc->excluded_chns_present = faad_get1bit(ld DEBUGVAR(1,93,"dynamic_range_info(): excluded_chns_present")); if (drc->excluded_chns_present == 1) { n += excluded_channels(ld, drc); } if (faad_get1bit(ld DEBUGVAR(1,94,"dynamic_range_info(): has bands data")) & 1) { band_incr = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,95,"dynamic_range_info(): band_incr")); /* drc->drc_bands_reserved_bits = */ faad_getbits(ld, 4 DEBUGVAR(1,96,"dynamic_range_info(): drc_bands_reserved_bits")); n++; drc->num_bands += band_incr; for (i = 0; i < drc->num_bands; i++) { drc->band_top[i] = (uint8_t)faad_getbits(ld, 8 DEBUGVAR(1,97,"dynamic_range_info(): band_top")); n++; } } if (faad_get1bit(ld DEBUGVAR(1,98,"dynamic_range_info(): has prog_ref_level")) & 1) { drc->prog_ref_level = (uint8_t)faad_getbits(ld, 7 DEBUGVAR(1,99,"dynamic_range_info(): prog_ref_level")); /* drc->prog_ref_level_reserved_bits = */ faad_get1bit(ld DEBUGVAR(1,100,"dynamic_range_info(): prog_ref_level_reserved_bits")); n++; } for (i = 0; i < drc->num_bands; i++) { drc->dyn_rng_sgn[i] = faad_get1bit(ld DEBUGVAR(1,101,"dynamic_range_info(): dyn_rng_sgn")); drc->dyn_rng_ctl[i] = (uint8_t)faad_getbits(ld, 7 DEBUGVAR(1,102,"dynamic_range_info(): dyn_rng_ctl")); n++; } return n; } /* Table 4.4.32 */ static uint8_t excluded_channels(bitfile *ld, drc_info *drc) { uint8_t i, n = 0; uint8_t num_excl_chan = 7; for (i = 0; i < 7; i++) { drc->exclude_mask[i] = faad_get1bit(ld DEBUGVAR(1,103,"excluded_channels(): exclude_mask")); } n++; while ((drc->additional_excluded_chns[n-1] = faad_get1bit(ld DEBUGVAR(1,104,"excluded_channels(): additional_excluded_chns"))) == 1) { for (i = num_excl_chan; i < num_excl_chan+7; i++) { drc->exclude_mask[i] = faad_get1bit(ld DEBUGVAR(1,105,"excluded_channels(): exclude_mask")); } n++; num_excl_chan += 7; } return n; } /* Annex A: Audio Interchange Formats */ /* Table 1.A.2 */ void get_adif_header(adif_header *adif, bitfile *ld) { uint8_t i; /* adif_id[0] = */ faad_getbits(ld, 8 DEBUGVAR(1,106,"get_adif_header(): adif_id[0]")); /* adif_id[1] = */ faad_getbits(ld, 8 DEBUGVAR(1,107,"get_adif_header(): adif_id[1]")); /* adif_id[2] = */ faad_getbits(ld, 8 DEBUGVAR(1,108,"get_adif_header(): adif_id[2]")); /* adif_id[3] = */ faad_getbits(ld, 8 DEBUGVAR(1,109,"get_adif_header(): adif_id[3]")); adif->copyright_id_present = faad_get1bit(ld DEBUGVAR(1,110,"get_adif_header(): copyright_id_present")); if(adif->copyright_id_present) { for (i = 0; i < 72/8; i++) { adif->copyright_id[i] = (int8_t)faad_getbits(ld, 8 DEBUGVAR(1,111,"get_adif_header(): copyright_id")); } adif->copyright_id[i] = 0; } adif->original_copy = faad_get1bit(ld DEBUGVAR(1,112,"get_adif_header(): original_copy")); adif->home = faad_get1bit(ld DEBUGVAR(1,113,"get_adif_header(): home")); adif->bitstream_type = faad_get1bit(ld DEBUGVAR(1,114,"get_adif_header(): bitstream_type")); adif->bitrate = faad_getbits(ld, 23 DEBUGVAR(1,115,"get_adif_header(): bitrate")); adif->num_program_config_elements = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,116,"get_adif_header(): num_program_config_elements")); for (i = 0; i < adif->num_program_config_elements + 1; i++) { if(adif->bitstream_type == 0) { adif->adif_buffer_fullness = faad_getbits(ld, 20 DEBUGVAR(1,117,"get_adif_header(): adif_buffer_fullness")); } else { adif->adif_buffer_fullness = 0; } program_config_element(&adif->pce[i], ld); } } /* Table 1.A.5 */ uint8_t adts_frame(adts_header *adts, bitfile *ld) { /* faad_byte_align(ld); */ if (adts_fixed_header(adts, ld)) return 5; adts_variable_header(adts, ld); adts_error_check(adts, ld); return 0; } /* Table 1.A.6 */ static uint8_t adts_fixed_header(adts_header *adts, bitfile *ld) { uint16_t i; uint8_t sync_err = 1; /* try to recover from sync errors */ for (i = 0; i < 768; i++) { adts->syncword = (uint16_t)faad_showbits(ld, 12); if (adts->syncword != 0xFFF) { faad_getbits(ld, 8 DEBUGVAR(0,0,"")); } else { sync_err = 0; faad_getbits(ld, 12 DEBUGVAR(1,118,"adts_fixed_header(): syncword")); break; } } if (sync_err) return 5; adts->id = faad_get1bit(ld DEBUGVAR(1,119,"adts_fixed_header(): id")); adts->layer = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,120,"adts_fixed_header(): layer")); adts->protection_absent = faad_get1bit(ld DEBUGVAR(1,121,"adts_fixed_header(): protection_absent")); adts->profile = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,122,"adts_fixed_header(): profile")); adts->sf_index = (uint8_t)faad_getbits(ld, 4 DEBUGVAR(1,123,"adts_fixed_header(): sf_index")); adts->private_bit = faad_get1bit(ld DEBUGVAR(1,124,"adts_fixed_header(): private_bit")); adts->channel_configuration = (uint8_t)faad_getbits(ld, 3 DEBUGVAR(1,125,"adts_fixed_header(): channel_configuration")); adts->original = faad_get1bit(ld DEBUGVAR(1,126,"adts_fixed_header(): original")); adts->home = faad_get1bit(ld DEBUGVAR(1,127,"adts_fixed_header(): home")); if (adts->old_format == 1) { /* Removed in corrigendum 14496-3:2002 */ if (adts->id == 0) { adts->emphasis = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,128,"adts_fixed_header(): emphasis")); } } return 0; } /* Table 1.A.7 */ static void adts_variable_header(adts_header *adts, bitfile *ld) { adts->copyright_identification_bit = faad_get1bit(ld DEBUGVAR(1,129,"adts_variable_header(): copyright_identification_bit")); adts->copyright_identification_start = faad_get1bit(ld DEBUGVAR(1,130,"adts_variable_header(): copyright_identification_start")); adts->aac_frame_length = (uint16_t)faad_getbits(ld, 13 DEBUGVAR(1,131,"adts_variable_header(): aac_frame_length")); adts->adts_buffer_fullness = (uint16_t)faad_getbits(ld, 11 DEBUGVAR(1,132,"adts_variable_header(): adts_buffer_fullness")); adts->no_raw_data_blocks_in_frame = (uint8_t)faad_getbits(ld, 2 DEBUGVAR(1,133,"adts_variable_header(): no_raw_data_blocks_in_frame")); } /* Table 1.A.8 */ static void adts_error_check(adts_header *adts, bitfile *ld) { if (adts->protection_absent == 0) { adts->crc_check = (uint16_t)faad_getbits(ld, 16 DEBUGVAR(1,134,"adts_error_check(): crc_check")); } } /* LATM parsing functions */ static uint32_t latm_get_value(bitfile *ld) { uint32_t l, value; uint8_t bytesForValue; bytesForValue = (uint8_t)faad_getbits(ld, 2); value = 0; for(l=0; lframelen_type==0) { do { tmp = (uint8_t)faad_getbits(ld, 8); framelen += tmp; } while(tmp==0xff); } else if(latm->framelen_type==1) framelen=latm->frameLength; return framelen; } static uint32_t latmAudioMuxElement(latm_header *latm, bitfile *ld) { uint32_t ascLen, asc_bits=0; uint32_t x1, y1, m, n, i; program_config pce; mp4AudioSpecificConfig mp4ASC; latm->useSameStreamMux = (uint8_t)faad_getbits(ld, 1); if(!latm->useSameStreamMux) { //parseSameStreamMuxConfig latm->version = (uint8_t) faad_getbits(ld, 1); if(latm->version) latm->versionA = (uint8_t) faad_getbits(ld, 1); if(latm->versionA) { //dunno the payload format for versionA fprintf(stderr, "versionA not supported\n"); return 0; } if(latm->version) //read taraBufferFullness latm_get_value(ld); latm->allStreamsSameTimeFraming = (uint8_t)faad_getbits(ld, 1); latm->numSubFrames = (uint8_t)faad_getbits(ld, 6) + 1; latm->numPrograms = (uint8_t)faad_getbits(ld, 4) + 1; latm->numLayers = faad_getbits(ld, 3) + 1; if(latm->numPrograms>1 || !latm->allStreamsSameTimeFraming || latm->numSubFrames>1 || latm->numLayers>1) { fprintf(stderr, "\r\nUnsupported LATM configuration: %d programs/ %d subframes, %d layers, allstreams: %d\n", latm->numPrograms, latm->numSubFrames, latm->numLayers, latm->allStreamsSameTimeFraming); return 0; } ascLen = 0; if(latm->version) ascLen = latm_get_value(ld); x1 = faad_get_processed_bits(ld); if(AudioSpecificConfigFromBitfile(ld, &mp4ASC, &pce, 0, 1) < 0) return 0; //horrid hack to unread the ASC bits and store them in latm->ASC //the correct code would rely on an ideal faad_ungetbits() y1 = faad_get_processed_bits(ld); if((y1-x1) <= MAX_ASC_BYTES*8) { faad_rewindbits(ld); m = x1; while(m>0) { n = min(m, 32); faad_getbits(ld, n); m -= n; } i = 0; m = latm->ASCbits = y1 - x1; while(m > 0) { n = min(m, 8); latm->ASC[i++] = (uint8_t) faad_getbits(ld, n); m -= n; } } asc_bits = y1-x1; if(ascLen>asc_bits) faad_getbits(ld, ascLen-asc_bits); latm->framelen_type = (uint8_t) faad_getbits(ld, 3); if(latm->framelen_type == 0) { latm->frameLength = 0; faad_getbits(ld, 8); //buffer fullness for frame_len_type==0, useless } else if(latm->framelen_type == 1) { latm->frameLength = faad_getbits(ld, 9); if(latm->frameLength==0) { fprintf(stderr, "Invalid frameLength: 0\r\n"); return 0; } latm->frameLength = (latm->frameLength+20)*8; } else { //hellish CELP or HCVX stuff, discard fprintf(stderr, "Unsupported CELP/HCVX framelentype: %d\n", latm->framelen_type); return 0; } latm->otherDataLenBits = 0; if(faad_getbits(ld, 1)) { //other data present int esc, tmp; if(latm->version) latm->otherDataLenBits = latm_get_value(ld); else do { esc = faad_getbits(ld, 1); tmp = faad_getbits(ld, 8); latm->otherDataLenBits = (latm->otherDataLenBits << 8) + tmp; } while(esc); } if(faad_getbits(ld, 1)) //crc faad_getbits(ld, 8); latm->inited = 1; } //read payload if(latm->inited) return latmParsePayload(latm, ld); else return 0; } uint32_t faad_latm_frame(latm_header *latm, bitfile *ld) { uint16_t len; uint32_t initpos, endpos, /* firstpos, */ ret; /* firstpos = faad_get_processed_bits(ld); */ while (ld->bytes_left) { faad_byte_align(ld); if(faad_showbits(ld, 11) != 0x2B7) { faad_getbits(ld, 8); continue; } faad_getbits(ld, 11); len = faad_getbits(ld, 13); if(!len) continue; initpos = faad_get_processed_bits(ld); ret = latmAudioMuxElement(latm, ld); endpos = faad_get_processed_bits(ld); if(ret>0) return (len*8)-(endpos-initpos); //faad_getbits(ld, initpos-endpos); //go back to initpos, but is valid a getbits(-N) ? } return -1U; } xine-lib-1.2/contrib/libfaad/mdct.c0000644000175000017500000002010414647725152014776 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: mdct.c,v 1.47 2007/11/01 12:33:31 menno Exp $ **/ /* * Fast (I)MDCT Implementation using (I)FFT ((Inverse) Fast Fourier Transform) * and consists of three steps: pre-(I)FFT complex multiplication, complex * (I)FFT, post-(I)FFT complex multiplication, * * As described in: * P. Duhamel, Y. Mahieux, and J.P. Petit, "A Fast Algorithm for the * Implementation of Filter Banks Based on 'Time Domain Aliasing * Cancellation," IEEE Proc. on ICASSP91, 1991, pp. 2209-2212. * * * As of April 6th 2002 completely rewritten. * This (I)MDCT can now be used for any data size n, where n is divisible by 8. * */ #include "common.h" #include "structs.h" #include #ifdef _WIN32_WCE #define assert(x) #else #include #endif #include "cfft.h" #include "mdct.h" #include "mdct_tab.h" mdct_info *faad_mdct_init(uint16_t N) { mdct_info *mdct = (mdct_info*)faad_malloc(sizeof(mdct_info)); assert(N % 8 == 0); mdct->N = N; /* NOTE: For "small framelengths" in FIXED_POINT the coefficients need to be * scaled by sqrt("(nearest power of 2) > N" / N) */ /* RE(mdct->sincos[k]) = scale*(real_t)(cos(2.0*M_PI*(k+1./8.) / (real_t)N)); * IM(mdct->sincos[k]) = scale*(real_t)(sin(2.0*M_PI*(k+1./8.) / (real_t)N)); */ /* scale is 1 for fixed point, sqrt(N) for floating point */ switch (N) { case 2048: mdct->sincos = (complex_t*)mdct_tab_2048; break; case 256: mdct->sincos = (complex_t*)mdct_tab_256; break; #ifdef LD_DEC case 1024: mdct->sincos = (complex_t*)mdct_tab_1024; break; #endif #ifdef ALLOW_SMALL_FRAMELENGTH case 1920: mdct->sincos = (complex_t*)mdct_tab_1920; break; case 240: mdct->sincos = (complex_t*)mdct_tab_240; break; #ifdef LD_DEC case 960: mdct->sincos = (complex_t*)mdct_tab_960; break; #endif #endif #ifdef SSR_DEC case 512: mdct->sincos = (complex_t*)mdct_tab_512; break; case 64: mdct->sincos = (complex_t*)mdct_tab_64; break; #endif } /* initialise fft */ mdct->cfft = cffti(N/4); #ifdef PROFILE mdct->cycles = 0; mdct->fft_cycles = 0; #endif return mdct; } void faad_mdct_end(mdct_info *mdct) { if (mdct != NULL) { #ifdef PROFILE printf("MDCT[%.4d]: %I64d cycles\n", mdct->N, mdct->cycles); printf("CFFT[%.4d]: %I64d cycles\n", mdct->N/4, mdct->fft_cycles); #endif cfftu(mdct->cfft); faad_free(mdct); } } void faad_imdct(mdct_info *mdct, real_t *X_in, real_t *X_out) { uint16_t k; complex_t x; #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT real_t scale, b_scale = 0; #endif #endif ALIGN complex_t Z1[512]; complex_t *sincos = mdct->sincos; uint16_t N = mdct->N; uint16_t N2 = N >> 1; uint16_t N4 = N >> 2; uint16_t N8 = N >> 3; #ifdef PROFILE int64_t count1, count2 = faad_get_ts(); #endif #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT /* detect non-power of 2 */ if (N & (N-1)) { /* adjust scale for non-power of 2 MDCT */ /* 2048/1920 */ b_scale = 1; scale = COEF_CONST(1.0666666666666667); } #endif #endif /* pre-IFFT complex multiplication */ for (k = 0; k < N4; k++) { ComplexMult(&IM(Z1[k]), &RE(Z1[k]), X_in[2*k], X_in[N2 - 1 - 2*k], RE(sincos[k]), IM(sincos[k])); } #ifdef PROFILE count1 = faad_get_ts(); #endif /* complex IFFT, any non-scaling FFT can be used here */ cfftb(mdct->cfft, Z1); #ifdef PROFILE count1 = faad_get_ts() - count1; #endif /* post-IFFT complex multiplication */ for (k = 0; k < N4; k++) { RE(x) = RE(Z1[k]); IM(x) = IM(Z1[k]); ComplexMult(&IM(Z1[k]), &RE(Z1[k]), IM(x), RE(x), RE(sincos[k]), IM(sincos[k])); #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT /* non-power of 2 MDCT scaling */ if (b_scale) { RE(Z1[k]) = MUL_C(RE(Z1[k]), scale); IM(Z1[k]) = MUL_C(IM(Z1[k]), scale); } #endif #endif } /* reordering */ for (k = 0; k < N8; k+=2) { X_out[ 2*k] = IM(Z1[N8 + k]); X_out[ 2 + 2*k] = IM(Z1[N8 + 1 + k]); X_out[ 1 + 2*k] = -RE(Z1[N8 - 1 - k]); X_out[ 3 + 2*k] = -RE(Z1[N8 - 2 - k]); X_out[N4 + 2*k] = RE(Z1[ k]); X_out[N4 + + 2 + 2*k] = RE(Z1[ 1 + k]); X_out[N4 + 1 + 2*k] = -IM(Z1[N4 - 1 - k]); X_out[N4 + 3 + 2*k] = -IM(Z1[N4 - 2 - k]); X_out[N2 + 2*k] = RE(Z1[N8 + k]); X_out[N2 + + 2 + 2*k] = RE(Z1[N8 + 1 + k]); X_out[N2 + 1 + 2*k] = -IM(Z1[N8 - 1 - k]); X_out[N2 + 3 + 2*k] = -IM(Z1[N8 - 2 - k]); X_out[N2 + N4 + 2*k] = -IM(Z1[ k]); X_out[N2 + N4 + 2 + 2*k] = -IM(Z1[ 1 + k]); X_out[N2 + N4 + 1 + 2*k] = RE(Z1[N4 - 1 - k]); X_out[N2 + N4 + 3 + 2*k] = RE(Z1[N4 - 2 - k]); } #ifdef PROFILE count2 = faad_get_ts() - count2; mdct->fft_cycles += count1; mdct->cycles += (count2 - count1); #endif } #ifdef LTP_DEC void faad_mdct(mdct_info *mdct, real_t *X_in, real_t *X_out) { uint16_t k; complex_t x; ALIGN complex_t Z1[512]; complex_t *sincos = mdct->sincos; uint16_t N = mdct->N; uint16_t N2 = N >> 1; uint16_t N4 = N >> 2; uint16_t N8 = N >> 3; #ifndef FIXED_POINT real_t scale = REAL_CONST(N); #else real_t scale = REAL_CONST(4.0/N); #endif #ifdef ALLOW_SMALL_FRAMELENGTH #ifdef FIXED_POINT /* detect non-power of 2 */ if (N & (N-1)) { /* adjust scale for non-power of 2 MDCT */ /* *= sqrt(2048/1920) */ scale = MUL_C(scale, COEF_CONST(1.0327955589886444)); } #endif #endif /* pre-FFT complex multiplication */ for (k = 0; k < N8; k++) { uint16_t n = k << 1; RE(x) = X_in[N - N4 - 1 - n] + X_in[N - N4 + n]; IM(x) = X_in[ N4 + n] - X_in[ N4 - 1 - n]; ComplexMult(&RE(Z1[k]), &IM(Z1[k]), RE(x), IM(x), RE(sincos[k]), IM(sincos[k])); RE(Z1[k]) = MUL_R(RE(Z1[k]), scale); IM(Z1[k]) = MUL_R(IM(Z1[k]), scale); RE(x) = X_in[N2 - 1 - n] - X_in[ n]; IM(x) = X_in[N2 + n] + X_in[N - 1 - n]; ComplexMult(&RE(Z1[k + N8]), &IM(Z1[k + N8]), RE(x), IM(x), RE(sincos[k + N8]), IM(sincos[k + N8])); RE(Z1[k + N8]) = MUL_R(RE(Z1[k + N8]), scale); IM(Z1[k + N8]) = MUL_R(IM(Z1[k + N8]), scale); } /* complex FFT, any non-scaling FFT can be used here */ cfftf(mdct->cfft, Z1); /* post-FFT complex multiplication */ for (k = 0; k < N4; k++) { uint16_t n = k << 1; ComplexMult(&RE(x), &IM(x), RE(Z1[k]), IM(Z1[k]), RE(sincos[k]), IM(sincos[k])); X_out[ n] = -RE(x); X_out[N2 - 1 - n] = IM(x); X_out[N2 + n] = -IM(x); X_out[N - 1 - n] = RE(x); } } #endif xine-lib-1.2/contrib/libfaad/ic_predict.c0000644000175000017500000001532314647725152016163 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: ic_predict.c,v 1.28 2007/11/01 12:33:31 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef MAIN_DEC #include "syntax.h" #include "ic_predict.h" #include "pns.h" static void flt_round(float32_t *pf) { int32_t flg; union {float32_t f; uint32_t i;} tmp, tmp1, tmp2; tmp.f = *pf; flg = tmp.i & (uint32_t)0x00008000; tmp.i &= (uint32_t)0xffff0000; /* round 1/2 lsb toward infinity */ if (flg) { tmp1 = tmp; tmp.i &= (uint32_t)0xff800000; /* extract exponent and sign */ tmp.i |= (uint32_t)0x00010000; /* insert 1 lsb */ tmp2 = tmp; /* add 1 lsb and elided one */ tmp.i &= (uint32_t)0xff800000; /* extract exponent and sign */ *pf = tmp1.f + tmp2.f - tmp.f; } else { *pf = tmp.f; } } static int16_t quant_pred(float32_t x) { int16_t q; union {float32_t f; uint32_t i;} tmp; tmp.f = x; q = (int16_t)(tmp.i>>16); return q; } static float32_t inv_quant_pred(int16_t q) { union {float32_t f; uint32_t i;} tmp; tmp.i = ((uint32_t)q)<<16; return tmp.f; } static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t pred) { uint16_t tmp; int16_t i, j; real_t dr1; float32_t predictedvalue; real_t e0, e1; real_t k1, k2; real_t r[2]; real_t COR[2]; real_t VAR[2]; r[0] = inv_quant_pred(state->r[0]); r[1] = inv_quant_pred(state->r[1]); COR[0] = inv_quant_pred(state->COR[0]); COR[1] = inv_quant_pred(state->COR[1]); VAR[0] = inv_quant_pred(state->VAR[0]); VAR[1] = inv_quant_pred(state->VAR[1]); #if 1 tmp = state->VAR[0]; j = (tmp >> 7); i = tmp & 0x7f; if (j >= 128) { j -= 128; k1 = COR[0] * exp_table[j] * mnt_table[i]; } else { k1 = REAL_CONST(0); } #else { #define B 0.953125 real_t c = COR[0]; real_t v = VAR[0]; float32_t tmp; if (c == 0 || v <= 1) { k1 = 0; } else { tmp = B / v; flt_round(&tmp); k1 = c * tmp; } } #endif if (pred) { #if 1 tmp = state->VAR[1]; j = (tmp >> 7); i = tmp & 0x7f; if (j >= 128) { j -= 128; k2 = COR[1] * exp_table[j] * mnt_table[i]; } else { k2 = REAL_CONST(0); } #else #define B 0.953125 real_t c = COR[1]; real_t v = VAR[1]; float32_t tmp; if (c == 0 || v <= 1) { k2 = 0; } else { tmp = B / v; flt_round(&tmp); k2 = c * tmp; } #endif predictedvalue = k1*r[0] + k2*r[1]; flt_round(&predictedvalue); *output = input + predictedvalue; } /* calculate new state data */ e0 = *output; e1 = e0 - k1*r[0]; dr1 = k1*e0; VAR[0] = ALPHA*VAR[0] + 0.5f * (r[0]*r[0] + e0*e0); COR[0] = ALPHA*COR[0] + r[0]*e0; VAR[1] = ALPHA*VAR[1] + 0.5f * (r[1]*r[1] + e1*e1); COR[1] = ALPHA*COR[1] + r[1]*e1; r[1] = A * (r[0]-dr1); r[0] = A * e0; state->r[0] = quant_pred(r[0]); state->r[1] = quant_pred(r[1]); state->COR[0] = quant_pred(COR[0]); state->COR[1] = quant_pred(COR[1]); state->VAR[0] = quant_pred(VAR[0]); state->VAR[1] = quant_pred(VAR[1]); } static void reset_pred_state(pred_state *state) { state->r[0] = 0; state->r[1] = 0; state->COR[0] = 0; state->COR[1] = 0; state->VAR[0] = 0x3F80; state->VAR[1] = 0x3F80; } void pns_reset_pred_state(ic_stream *ics, pred_state *state) { uint8_t sfb, g, b; uint16_t i, offs, offs2; /* prediction only for long blocks */ if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) return; for (g = 0; g < ics->num_window_groups; g++) { for (b = 0; b < ics->window_group_length[g]; b++) { for (sfb = 0; sfb < ics->max_sfb; sfb++) { if (is_noise(ics, g, sfb)) { offs = ics->swb_offset[sfb]; offs2 = min(ics->swb_offset[sfb+1], ics->swb_offset_max); for (i = offs; i < offs2; i++) reset_pred_state(&state[i]); } } } } } void reset_all_predictors(pred_state *state, uint16_t frame_len) { uint16_t i; for (i = 0; i < frame_len; i++) reset_pred_state(&state[i]); } /* intra channel prediction */ void ic_prediction(ic_stream *ics, real_t *spec, pred_state *state, uint16_t frame_len, uint8_t sf_index) { uint8_t sfb; uint16_t bin; if (ics->window_sequence == EIGHT_SHORT_SEQUENCE) { reset_all_predictors(state, frame_len); } else { for (sfb = 0; sfb < max_pred_sfb(sf_index); sfb++) { uint16_t low = ics->swb_offset[sfb]; uint16_t high = min(ics->swb_offset[sfb+1], ics->swb_offset_max); for (bin = low; bin < high; bin++) { ic_predict(&state[bin], spec[bin], &spec[bin], (ics->predictor_data_present && ics->pred.prediction_used[sfb])); } } if (ics->predictor_data_present) { if (ics->pred.predictor_reset) { for (bin = ics->pred.predictor_reset_group_number - 1; bin < frame_len; bin += 30) { reset_pred_state(&state[bin]); } } } } } #endif xine-lib-1.2/contrib/libfaad/sbr_syntax.h0000644000175000017500000000356514647725152016264 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_syntax.h,v 1.23 2007/11/01 12:33:36 menno Exp $ **/ #ifndef __SBR_SYNTAX_H__ #define __SBR_SYNTAX_H__ #ifdef __cplusplus extern "C" { #endif #include "bits.h" #define T_HFGEN 8 #define T_HFADJ 2 #define EXT_SBR_DATA 13 #define EXT_SBR_DATA_CRC 14 #define FIXFIX 0 #define FIXVAR 1 #define VARFIX 2 #define VARVAR 3 #define LO_RES 0 #define HI_RES 1 #define NO_TIME_SLOTS_960 15 #define NO_TIME_SLOTS 16 #define RATE 2 #define NOISE_FLOOR_OFFSET 6 uint8_t sbr_extension_data(bitfile *ld, sbr_info *sbr, uint16_t cnt, uint8_t resetFlag); #ifdef __cplusplus } #endif #endif /* __SBR_SYNTAX_H__ */ xine-lib-1.2/contrib/libfaad/sbr_qmf.c0000644000175000017500000005526214647725152015515 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_qmf.c,v 1.32 2007/11/01 12:33:36 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include #include #include "sbr_dct.h" #include "sbr_qmf.h" #include "sbr_qmf_c.h" #include "sbr_syntax.h" qmfa_info *qmfa_init(uint8_t channels) { qmfa_info *qmfa = (qmfa_info*)faad_malloc(sizeof(qmfa_info)); /* x is implemented as double ringbuffer */ qmfa->x = (real_t*)faad_malloc(2 * channels * 10 * sizeof(real_t)); memset(qmfa->x, 0, 2 * channels * 10 * sizeof(real_t)); /* ringbuffer index */ qmfa->x_index = 0; qmfa->channels = channels; return qmfa; } void qmfa_end(qmfa_info *qmfa) { if (qmfa) { if (qmfa->x) faad_free(qmfa->x); faad_free(qmfa); } } void sbr_qmf_analysis_32 (sbr_info *sbr, qmfa_info *qmfa, const real_t *input, qmf_t X[][64], uint8_t offset, uint8_t kx) { ALIGN real_t u[64]; #ifndef SBR_LOW_POWER ALIGN real_t in_real[32], in_imag[32], out_real[32], out_imag[32]; #else ALIGN real_t y[32]; #endif uint32_t in = 0; uint8_t l; /* qmf subsample l */ for (l = 0; l < sbr->numTimeSlotsRate; l++) { int16_t n; /* shift input buffer x */ /* input buffer is not shifted anymore, x is implemented as double ringbuffer */ //memmove(qmfa->x + 32, qmfa->x, (320-32)*sizeof(real_t)); /* add new samples to input buffer x */ for (n = 32 - 1; n >= 0; n--) { #ifdef FIXED_POINT qmfa->x[qmfa->x_index + n] = qmfa->x[qmfa->x_index + n + 320] = (input[in++]) >> 4; #else qmfa->x[qmfa->x_index + n] = qmfa->x[qmfa->x_index + n + 320] = input[in++]; #endif } /* window and summation to create array u */ for (n = 0; n < 64; n++) { u[n] = MUL_F(qmfa->x[qmfa->x_index + n], qmf_c[2*n]) + MUL_F(qmfa->x[qmfa->x_index + n + 64], qmf_c[2*(n + 64)]) + MUL_F(qmfa->x[qmfa->x_index + n + 128], qmf_c[2*(n + 128)]) + MUL_F(qmfa->x[qmfa->x_index + n + 192], qmf_c[2*(n + 192)]) + MUL_F(qmfa->x[qmfa->x_index + n + 256], qmf_c[2*(n + 256)]); } /* update ringbuffer index */ qmfa->x_index -= 32; if (qmfa->x_index < 0) qmfa->x_index = (320-32); /* calculate 32 subband samples by introducing X */ #ifdef SBR_LOW_POWER y[0] = u[48]; for (n = 1; n < 16; n++) y[n] = u[n+48] + u[48-n]; for (n = 16; n < 32; n++) y[n] = -u[n-16] + u[48-n]; DCT3_32_unscaled(u, y); for (n = 0; n < 32; n++) { if (n < kx) { #ifdef FIXED_POINT QMF_RE(X[l + offset][n]) = u[n] /*<< 1*/; #else QMF_RE(X[l + offset][n]) = 2. * u[n]; #endif } else { QMF_RE(X[l + offset][n]) = 0; } } #else // Reordering of data moved from DCT_IV to here in_imag[31] = u[1]; in_real[0] = u[0]; for (n = 1; n < 31; n++) { in_imag[31 - n] = u[n+1]; in_real[n] = -u[64-n]; } in_imag[0] = u[32]; in_real[31] = -u[33]; // dct4_kernel is DCT_IV without reordering which is done before and after FFT dct4_kernel(in_real, in_imag, out_real, out_imag); // Reordering of data moved from DCT_IV to here for (n = 0; n < 16; n++) { if (2*n+1 < kx) { #ifdef FIXED_POINT QMF_RE(X[l + offset][2*n]) = out_real[n]; QMF_IM(X[l + offset][2*n]) = out_imag[n]; QMF_RE(X[l + offset][2*n+1]) = -out_imag[31-n]; QMF_IM(X[l + offset][2*n+1]) = -out_real[31-n]; #else QMF_RE(X[l + offset][2*n]) = 2. * out_real[n]; QMF_IM(X[l + offset][2*n]) = 2. * out_imag[n]; QMF_RE(X[l + offset][2*n+1]) = -2. * out_imag[31-n]; QMF_IM(X[l + offset][2*n+1]) = -2. * out_real[31-n]; #endif } else { if (2*n < kx) { #ifdef FIXED_POINT QMF_RE(X[l + offset][2*n]) = out_real[n]; QMF_IM(X[l + offset][2*n]) = out_imag[n]; #else QMF_RE(X[l + offset][2*n]) = 2. * out_real[n]; QMF_IM(X[l + offset][2*n]) = 2. * out_imag[n]; #endif } else { QMF_RE(X[l + offset][2*n]) = 0; QMF_IM(X[l + offset][2*n]) = 0; } QMF_RE(X[l + offset][2*n+1]) = 0; QMF_IM(X[l + offset][2*n+1]) = 0; } } #endif } } static const complex_t qmf32_pre_twiddle[] = { { FRAC_CONST(0.999924701839145), FRAC_CONST(-0.012271538285720) }, { FRAC_CONST(0.999322384588350), FRAC_CONST(-0.036807222941359) }, { FRAC_CONST(0.998118112900149), FRAC_CONST(-0.061320736302209) }, { FRAC_CONST(0.996312612182778), FRAC_CONST(-0.085797312344440) }, { FRAC_CONST(0.993906970002356), FRAC_CONST(-0.110222207293883) }, { FRAC_CONST(0.990902635427780), FRAC_CONST(-0.134580708507126) }, { FRAC_CONST(0.987301418157858), FRAC_CONST(-0.158858143333861) }, { FRAC_CONST(0.983105487431216), FRAC_CONST(-0.183039887955141) }, { FRAC_CONST(0.978317370719628), FRAC_CONST(-0.207111376192219) }, { FRAC_CONST(0.972939952205560), FRAC_CONST(-0.231058108280671) }, { FRAC_CONST(0.966976471044852), FRAC_CONST(-0.254865659604515) }, { FRAC_CONST(0.960430519415566), FRAC_CONST(-0.278519689385053) }, { FRAC_CONST(0.953306040354194), FRAC_CONST(-0.302005949319228) }, { FRAC_CONST(0.945607325380521), FRAC_CONST(-0.325310292162263) }, { FRAC_CONST(0.937339011912575), FRAC_CONST(-0.348418680249435) }, { FRAC_CONST(0.928506080473216), FRAC_CONST(-0.371317193951838) }, { FRAC_CONST(0.919113851690058), FRAC_CONST(-0.393992040061048) }, { FRAC_CONST(0.909167983090522), FRAC_CONST(-0.416429560097637) }, { FRAC_CONST(0.898674465693954), FRAC_CONST(-0.438616238538528) }, { FRAC_CONST(0.887639620402854), FRAC_CONST(-0.460538710958240) }, { FRAC_CONST(0.876070094195407), FRAC_CONST(-0.482183772079123) }, { FRAC_CONST(0.863972856121587), FRAC_CONST(-0.503538383725718) }, { FRAC_CONST(0.851355193105265), FRAC_CONST(-0.524589682678469) }, { FRAC_CONST(0.838224705554838), FRAC_CONST(-0.545324988422046) }, { FRAC_CONST(0.824589302785025), FRAC_CONST(-0.565731810783613) }, { FRAC_CONST(0.810457198252595), FRAC_CONST(-0.585797857456439) }, { FRAC_CONST(0.795836904608884), FRAC_CONST(-0.605511041404326) }, { FRAC_CONST(0.780737228572094), FRAC_CONST(-0.624859488142386) }, { FRAC_CONST(0.765167265622459), FRAC_CONST(-0.643831542889791) }, { FRAC_CONST(0.749136394523459), FRAC_CONST(-0.662415777590172) }, { FRAC_CONST(0.732654271672413), FRAC_CONST(-0.680600997795453) }, { FRAC_CONST(0.715730825283819), FRAC_CONST(-0.698376249408973) } }; qmfs_info *qmfs_init(uint8_t channels) { qmfs_info *qmfs = (qmfs_info*)faad_malloc(sizeof(qmfs_info)); /* v is a double ringbuffer */ qmfs->v = (real_t*)faad_malloc(2 * channels * 20 * sizeof(real_t)); memset(qmfs->v, 0, 2 * channels * 20 * sizeof(real_t)); qmfs->v_index = 0; qmfs->channels = channels; return qmfs; } void qmfs_end(qmfs_info *qmfs) { if (qmfs) { if (qmfs->v) faad_free(qmfs->v); faad_free(qmfs); } } #ifdef SBR_LOW_POWER void sbr_qmf_synthesis_32 (sbr_info *sbr, qmfs_info *qmfs, qmf_t X[][64], real_t *output) { ALIGN real_t x[16]; ALIGN real_t y[16]; int32_t n, k, out = 0; uint8_t l; /* qmf subsample l */ for (l = 0; l < sbr->numTimeSlotsRate; l++) { /* shift buffers */ /* we are not shifting v, it is a double ringbuffer */ //memmove(qmfs->v + 64, qmfs->v, (640-64)*sizeof(real_t)); /* calculate 64 samples */ for (k = 0; k < 16; k++) { #ifdef FIXED_POINT y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][31 - k])); x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][31 - k])); #else y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][31 - k])) / 32.0; x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][31 - k])) / 32.0; #endif } /* even n samples */ DCT2_16_unscaled(x, x); /* odd n samples */ DCT4_16(y, y); for (n = 8; n < 24; n++) { qmfs->v[qmfs->v_index + n*2] = qmfs->v[qmfs->v_index + 640 + n*2] = x[n-8]; qmfs->v[qmfs->v_index + n*2+1] = qmfs->v[qmfs->v_index + 640 + n*2+1] = y[n-8]; } for (n = 0; n < 16; n++) { qmfs->v[qmfs->v_index + n] = qmfs->v[qmfs->v_index + 640 + n] = qmfs->v[qmfs->v_index + 32-n]; } qmfs->v[qmfs->v_index + 48] = qmfs->v[qmfs->v_index + 640 + 48] = 0; for (n = 1; n < 16; n++) { qmfs->v[qmfs->v_index + 48+n] = qmfs->v[qmfs->v_index + 640 + 48+n] = -qmfs->v[qmfs->v_index + 48-n]; } /* calculate 32 output samples and window */ for (k = 0; k < 32; k++) { output[out++] = MUL_F(qmfs->v[qmfs->v_index + k], qmf_c[2*k]) + MUL_F(qmfs->v[qmfs->v_index + 96 + k], qmf_c[64 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 128 + k], qmf_c[128 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 224 + k], qmf_c[192 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 256 + k], qmf_c[256 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 352 + k], qmf_c[320 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 384 + k], qmf_c[384 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 480 + k], qmf_c[448 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 512 + k], qmf_c[512 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 608 + k], qmf_c[576 + 2*k]); } /* update the ringbuffer index */ qmfs->v_index -= 64; if (qmfs->v_index < 0) qmfs->v_index = (640-64); } } void sbr_qmf_synthesis_64 (sbr_info *sbr, qmfs_info *qmfs, qmf_t X[][64], real_t *output) { ALIGN real_t x[64]; ALIGN real_t y[64]; int32_t n, k, out = 0; uint8_t l; /* qmf subsample l */ for (l = 0; l < sbr->numTimeSlotsRate; l++) { /* shift buffers */ /* we are not shifting v, it is a double ringbuffer */ //memmove(qmfs->v + 128, qmfs->v, (1280-128)*sizeof(real_t)); /* calculate 128 samples */ for (k = 0; k < 32; k++) { #ifdef FIXED_POINT y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][63 - k])); x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][63 - k])); #else y[k] = (QMF_RE(X[l][k]) - QMF_RE(X[l][63 - k])) / 32.0; x[k] = (QMF_RE(X[l][k]) + QMF_RE(X[l][63 - k])) / 32.0; #endif } /* even n samples */ DCT2_32_unscaled(x, x); /* odd n samples */ DCT4_32(y, y); for (n = 16; n < 48; n++) { qmfs->v[qmfs->v_index + n*2] = qmfs->v[qmfs->v_index + 1280 + n*2] = x[n-16]; qmfs->v[qmfs->v_index + n*2+1] = qmfs->v[qmfs->v_index + 1280 + n*2+1] = y[n-16]; } for (n = 0; n < 32; n++) { qmfs->v[qmfs->v_index + n] = qmfs->v[qmfs->v_index + 1280 + n] = qmfs->v[qmfs->v_index + 64-n]; } qmfs->v[qmfs->v_index + 96] = qmfs->v[qmfs->v_index + 1280 + 96] = 0; for (n = 1; n < 32; n++) { qmfs->v[qmfs->v_index + 96+n] = qmfs->v[qmfs->v_index + 1280 + 96+n] = -qmfs->v[qmfs->v_index + 96-n]; } /* calculate 64 output samples and window */ for (k = 0; k < 64; k++) { output[out++] = MUL_F(qmfs->v[qmfs->v_index + k], qmf_c[k]) + MUL_F(qmfs->v[qmfs->v_index + 192 + k], qmf_c[64 + k]) + MUL_F(qmfs->v[qmfs->v_index + 256 + k], qmf_c[128 + k]) + MUL_F(qmfs->v[qmfs->v_index + 256 + 192 + k], qmf_c[128 + 64 + k]) + MUL_F(qmfs->v[qmfs->v_index + 512 + k], qmf_c[256 + k]) + MUL_F(qmfs->v[qmfs->v_index + 512 + 192 + k], qmf_c[256 + 64 + k]) + MUL_F(qmfs->v[qmfs->v_index + 768 + k], qmf_c[384 + k]) + MUL_F(qmfs->v[qmfs->v_index + 768 + 192 + k], qmf_c[384 + 64 + k]) + MUL_F(qmfs->v[qmfs->v_index + 1024 + k], qmf_c[512 + k]) + MUL_F(qmfs->v[qmfs->v_index + 1024 + 192 + k], qmf_c[512 + 64 + k]); } /* update the ringbuffer index */ qmfs->v_index -= 128; if (qmfs->v_index < 0) qmfs->v_index = (1280-128); } } #else void sbr_qmf_synthesis_32 (sbr_info *sbr, qmfs_info *qmfs, qmf_t X[][64], real_t *output) { ALIGN real_t x1[32], x2[32]; #ifndef FIXED_POINT real_t scale = 1.f/64.f; #endif int32_t n, k, out = 0; uint8_t l; /* qmf subsample l */ for (l = 0; l < sbr->numTimeSlotsRate; l++) { /* shift buffer v */ /* buffer is not shifted, we are using a ringbuffer */ //memmove(qmfs->v + 64, qmfs->v, (640-64)*sizeof(real_t)); /* calculate 64 samples */ /* complex pre-twiddle */ for (k = 0; k < 32; k++) { x1[k] = MUL_F(QMF_RE(X[l][k]), RE(qmf32_pre_twiddle[k])) - MUL_F(QMF_IM(X[l][k]), IM(qmf32_pre_twiddle[k])); x2[k] = MUL_F(QMF_IM(X[l][k]), RE(qmf32_pre_twiddle[k])) + MUL_F(QMF_RE(X[l][k]), IM(qmf32_pre_twiddle[k])); #ifndef FIXED_POINT x1[k] *= scale; x2[k] *= scale; #else x1[k] >>= 1; x2[k] >>= 1; #endif } /* transform */ DCT4_32(x1, x1); DST4_32(x2, x2); for (n = 0; n < 32; n++) { qmfs->v[qmfs->v_index + n] = qmfs->v[qmfs->v_index + 640 + n] = -x1[n] + x2[n]; qmfs->v[qmfs->v_index + 63 - n] = qmfs->v[qmfs->v_index + 640 + 63 - n] = x1[n] + x2[n]; } /* calculate 32 output samples and window */ for (k = 0; k < 32; k++) { output[out++] = MUL_F(qmfs->v[qmfs->v_index + k], qmf_c[2*k]) + MUL_F(qmfs->v[qmfs->v_index + 96 + k], qmf_c[64 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 128 + k], qmf_c[128 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 224 + k], qmf_c[192 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 256 + k], qmf_c[256 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 352 + k], qmf_c[320 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 384 + k], qmf_c[384 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 480 + k], qmf_c[448 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 512 + k], qmf_c[512 + 2*k]) + MUL_F(qmfs->v[qmfs->v_index + 608 + k], qmf_c[576 + 2*k]); } /* update ringbuffer index */ qmfs->v_index -= 64; if (qmfs->v_index < 0) qmfs->v_index = (640 - 64); } } void sbr_qmf_synthesis_64 (sbr_info *sbr, qmfs_info *qmfs, qmf_t X[][64], real_t *output) { // ALIGN real_t x1[64], x2[64]; #ifndef SBR_LOW_POWER ALIGN real_t in_real1[32], in_imag1[32], out_real1[32], out_imag1[32]; ALIGN real_t in_real2[32], in_imag2[32], out_real2[32], out_imag2[32]; #endif qmf_t * pX; real_t * pring_buffer_1, * pring_buffer_3; // real_t * ptemp_1, * ptemp_2; #ifdef PREFER_POINTERS // These pointers are used if target platform has autoinc address generators real_t * pring_buffer_2, * pring_buffer_4; real_t * pring_buffer_5, * pring_buffer_6; real_t * pring_buffer_7, * pring_buffer_8; real_t * pring_buffer_9, * pring_buffer_10; const real_t * pqmf_c_1, * pqmf_c_2, * pqmf_c_3, * pqmf_c_4; const real_t * pqmf_c_5, * pqmf_c_6, * pqmf_c_7, * pqmf_c_8; const real_t * pqmf_c_9, * pqmf_c_10; #endif // #ifdef PREFER_POINTERS #ifndef FIXED_POINT real_t scale = 1.f/64.f; #endif int32_t n, k, out = 0; uint8_t l; /* qmf subsample l */ for (l = 0; l < sbr->numTimeSlotsRate; l++) { /* shift buffer v */ /* buffer is not shifted, we use double ringbuffer */ //memmove(qmfs->v + 128, qmfs->v, (1280-128)*sizeof(real_t)); /* calculate 128 samples */ #ifndef FIXED_POINT pX = X[l]; in_imag1[31] = scale*QMF_RE(pX[1]); in_real1[0] = scale*QMF_RE(pX[0]); in_imag2[31] = scale*QMF_IM(pX[63-1]); in_real2[0] = scale*QMF_IM(pX[63-0]); for (k = 1; k < 31; k++) { in_imag1[31 - k] = scale*QMF_RE(pX[2*k + 1]); in_real1[ k] = scale*QMF_RE(pX[2*k ]); in_imag2[31 - k] = scale*QMF_IM(pX[63 - (2*k + 1)]); in_real2[ k] = scale*QMF_IM(pX[63 - (2*k )]); } in_imag1[0] = scale*QMF_RE(pX[63]); in_real1[31] = scale*QMF_RE(pX[62]); in_imag2[0] = scale*QMF_IM(pX[63-63]); in_real2[31] = scale*QMF_IM(pX[63-62]); #else pX = X[l]; in_imag1[31] = QMF_RE(pX[1]) >> 1; in_real1[0] = QMF_RE(pX[0]) >> 1; in_imag2[31] = QMF_IM(pX[62]) >> 1; in_real2[0] = QMF_IM(pX[63]) >> 1; for (k = 1; k < 31; k++) { in_imag1[31 - k] = QMF_RE(pX[2*k + 1]) >> 1; in_real1[ k] = QMF_RE(pX[2*k ]) >> 1; in_imag2[31 - k] = QMF_IM(pX[63 - (2*k + 1)]) >> 1; in_real2[ k] = QMF_IM(pX[63 - (2*k )]) >> 1; } in_imag1[0] = QMF_RE(pX[63]) >> 1; in_real1[31] = QMF_RE(pX[62]) >> 1; in_imag2[0] = QMF_IM(pX[0]) >> 1; in_real2[31] = QMF_IM(pX[1]) >> 1; #endif // dct4_kernel is DCT_IV without reordering which is done before and after FFT dct4_kernel(in_real1, in_imag1, out_real1, out_imag1); dct4_kernel(in_real2, in_imag2, out_real2, out_imag2); pring_buffer_1 = qmfs->v + qmfs->v_index; pring_buffer_3 = pring_buffer_1 + 1280; #ifdef PREFER_POINTERS pring_buffer_2 = pring_buffer_1 + 127; pring_buffer_4 = pring_buffer_1 + (1280 + 127); #endif // #ifdef PREFER_POINTERS // ptemp_1 = x1; // ptemp_2 = x2; #ifdef PREFER_POINTERS for (n = 0; n < 32; n ++) { //real_t x1 = *ptemp_1++; //real_t x2 = *ptemp_2++; // pring_buffer_3 and pring_buffer_4 are needed only for double ring buffer *pring_buffer_1++ = *pring_buffer_3++ = out_real2[n] - out_real1[n]; *pring_buffer_2-- = *pring_buffer_4-- = out_real2[n] + out_real1[n]; //x1 = *ptemp_1++; //x2 = *ptemp_2++; *pring_buffer_1++ = *pring_buffer_3++ = out_imag2[31-n] + out_imag1[31-n]; *pring_buffer_2-- = *pring_buffer_4-- = out_imag2[31-n] - out_imag1[31-n]; } #else // #ifdef PREFER_POINTERS for (n = 0; n < 32; n++) { // pring_buffer_3 and pring_buffer_4 are needed only for double ring buffer pring_buffer_1[2*n] = pring_buffer_3[2*n] = out_real2[n] - out_real1[n]; pring_buffer_1[127-2*n] = pring_buffer_3[127-2*n] = out_real2[n] + out_real1[n]; pring_buffer_1[2*n+1] = pring_buffer_3[2*n+1] = out_imag2[31-n] + out_imag1[31-n]; pring_buffer_1[127-(2*n+1)] = pring_buffer_3[127-(2*n+1)] = out_imag2[31-n] - out_imag1[31-n]; } #endif // #ifdef PREFER_POINTERS pring_buffer_1 = qmfs->v + qmfs->v_index; #ifdef PREFER_POINTERS pring_buffer_2 = pring_buffer_1 + 192; pring_buffer_3 = pring_buffer_1 + 256; pring_buffer_4 = pring_buffer_1 + (256 + 192); pring_buffer_5 = pring_buffer_1 + 512; pring_buffer_6 = pring_buffer_1 + (512 + 192); pring_buffer_7 = pring_buffer_1 + 768; pring_buffer_8 = pring_buffer_1 + (768 + 192); pring_buffer_9 = pring_buffer_1 + 1024; pring_buffer_10 = pring_buffer_1 + (1024 + 192); pqmf_c_1 = qmf_c; pqmf_c_2 = qmf_c + 64; pqmf_c_3 = qmf_c + 128; pqmf_c_4 = qmf_c + 192; pqmf_c_5 = qmf_c + 256; pqmf_c_6 = qmf_c + 320; pqmf_c_7 = qmf_c + 384; pqmf_c_8 = qmf_c + 448; pqmf_c_9 = qmf_c + 512; pqmf_c_10 = qmf_c + 576; #endif // #ifdef PREFER_POINTERS /* calculate 64 output samples and window */ for (k = 0; k < 64; k++) { #ifdef PREFER_POINTERS output[out++] = MUL_F(*pring_buffer_1++, *pqmf_c_1++) + MUL_F(*pring_buffer_2++, *pqmf_c_2++) + MUL_F(*pring_buffer_3++, *pqmf_c_3++) + MUL_F(*pring_buffer_4++, *pqmf_c_4++) + MUL_F(*pring_buffer_5++, *pqmf_c_5++) + MUL_F(*pring_buffer_6++, *pqmf_c_6++) + MUL_F(*pring_buffer_7++, *pqmf_c_7++) + MUL_F(*pring_buffer_8++, *pqmf_c_8++) + MUL_F(*pring_buffer_9++, *pqmf_c_9++) + MUL_F(*pring_buffer_10++, *pqmf_c_10++); #else // #ifdef PREFER_POINTERS output[out++] = MUL_F(pring_buffer_1[k+0], qmf_c[k+0]) + MUL_F(pring_buffer_1[k+192], qmf_c[k+64]) + MUL_F(pring_buffer_1[k+256], qmf_c[k+128]) + MUL_F(pring_buffer_1[k+(256+192)], qmf_c[k+192]) + MUL_F(pring_buffer_1[k+512], qmf_c[k+256]) + MUL_F(pring_buffer_1[k+(512+192)], qmf_c[k+320]) + MUL_F(pring_buffer_1[k+768], qmf_c[k+384]) + MUL_F(pring_buffer_1[k+(768+192)], qmf_c[k+448]) + MUL_F(pring_buffer_1[k+1024], qmf_c[k+512]) + MUL_F(pring_buffer_1[k+(1024+192)], qmf_c[k+576]); #endif // #ifdef PREFER_POINTERS } /* update ringbuffer index */ qmfs->v_index -= 128; if (qmfs->v_index < 0) qmfs->v_index = (1280 - 128); } } #endif #endif xine-lib-1.2/contrib/libfaad/ssr_ipqf.h0000644000175000017500000000310614647725152015705 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. ** ** $Id: ssr_ipqf.h,v 1.17 2007/11/01 12:33:39 menno Exp $ **/ #ifndef __SSR_IPQF_H__ #define __SSR_IPQF_H__ #ifdef __cplusplus extern "C" { #endif void ssr_ipqf(ssr_info *ssr, real_t *in_data, real_t *out_data, real_t buffer[SSR_BANDS][96/4], uint16_t frame_len, uint8_t bands); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/libfaad/sbr_huff.c0000644000175000017500000003751614647725152015664 0ustar meme/* ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ** ** Any non-GPL usage of this software or parts of this software is strictly ** forbidden. ** ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" ** ** Commercial non-GPL licensing of this software is possible. ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. ** ** $Id: sbr_huff.c,v 1.21 2007/11/01 12:33:35 menno Exp $ **/ #include "common.h" #include "structs.h" #ifdef SBR_DEC #include "sbr_syntax.h" #include "bits.h" #include "sbr_huff.h" #include "sbr_e_nf.h" typedef const int8_t (*sbr_huff_tab)[2]; static const int8_t t_huffman_env_1_5dB[120][2] = { { 1, 2 }, { -64, -65 }, { 3, 4 }, { -63, -66 }, { 5, 6 }, { -62, -67 }, { 7, 8 }, { -61, -68 }, { 9, 10 }, { -60, -69 }, { 11, 12 }, { -59, -70 }, { 13, 14 }, { -58, -71 }, { 15, 16 }, { -57, -72 }, { 17, 18 }, { -73, -56 }, { 19, 21 }, { -74, 20 }, { -55, -75 }, { 22, 26 }, { 23, 24 }, { -54, -76 }, { -77, 25 }, { -53, -78 }, { 27, 34 }, { 28, 29 }, { -52, -79 }, { 30, 31 }, { -80, -51 }, { 32, 33 }, { -83, -82 }, { -81, -50 }, { 35, 57 }, { 36, 40 }, { 37, 38 }, { -88, -84 }, { -48, 39 }, { -90, -85 }, { 41, 46 }, { 42, 43 }, { -49, -87 }, { 44, 45 }, { -89, -86 }, {-124,-123 }, { 47, 50 }, { 48, 49 }, {-122,-121 }, {-120,-119 }, { 51, 54 }, { 52, 53 }, {-118,-117 }, {-116,-115 }, { 55, 56 }, {-114,-113 }, {-112,-111 }, { 58, 89 }, { 59, 74 }, { 60, 67 }, { 61, 64 }, { 62, 63 }, {-110,-109 }, {-108,-107 }, { 65, 66 }, {-106,-105 }, {-104,-103 }, { 68, 71 }, { 69, 70 }, {-102,-101 }, {-100, -99 }, { 72, 73 }, { -98, -97 }, { -96, -95 }, { 75, 82 }, { 76, 79 }, { 77, 78 }, { -94, -93 }, { -92, -91 }, { 80, 81 }, { -47, -46 }, { -45, -44 }, { 83, 86 }, { 84, 85 }, { -43, -42 }, { -41, -40 }, { 87, 88 }, { -39, -38 }, { -37, -36 }, { 90, 105 }, { 91, 98 }, { 92, 95 }, { 93, 94 }, { -35, -34 }, { -33, -32 }, { 96, 97 }, { -31, -30 }, { -29, -28 }, { 99, 102 }, { 100, 101 }, { -27, -26 }, { -25, -24 }, { 103, 104 }, { -23, -22 }, { -21, -20 }, { 106, 113 }, { 107, 110 }, { 108, 109 }, { -19, -18 }, { -17, -16 }, { 111, 112 }, { -15, -14 }, { -13, -12 }, { 114, 117 }, { 115, 116 }, { -11, -10 }, { -9, -8 }, { 118, 119 }, { -7, -6 }, { -5, -4 } }; static const int8_t f_huffman_env_1_5dB[120][2] = { { 1, 2 }, { -64, -65 }, { 3, 4 }, { -63, -66 }, { 5, 6 }, { -67, -62 }, { 7, 8 }, { -68, -61 }, { 9, 10 }, { -69, -60 }, { 11, 13 }, { -70, 12 }, { -59, -71 }, { 14, 16 }, { -58, 15 }, { -72, -57 }, { 17, 19 }, { -73, 18 }, { -56, -74 }, { 20, 23 }, { 21, 22 }, { -55, -75 }, { -54, -53 }, { 24, 27 }, { 25, 26 }, { -76, -52 }, { -77, -51 }, { 28, 31 }, { 29, 30 }, { -50, -78 }, { -79, -49 }, { 32, 36 }, { 33, 34 }, { -48, -47 }, { -80, 35 }, { -81, -82 }, { 37, 47 }, { 38, 41 }, { 39, 40 }, { -83, -46 }, { -45, -84 }, { 42, 44 }, { -85, 43 }, { -44, -43 }, { 45, 46 }, { -88, -87 }, { -86, -90 }, { 48, 66 }, { 49, 56 }, { 50, 53 }, { 51, 52 }, { -92, -42 }, { -41, -39 }, { 54, 55 }, {-105, -89 }, { -38, -37 }, { 57, 60 }, { 58, 59 }, { -94, -91 }, { -40, -36 }, { 61, 63 }, { -20, 62 }, {-115,-110 }, { 64, 65 }, {-108,-107 }, {-101, -97 }, { 67, 89 }, { 68, 75 }, { 69, 72 }, { 70, 71 }, { -95, -93 }, { -34, -27 }, { 73, 74 }, { -22, -17 }, { -16,-124 }, { 76, 82 }, { 77, 79 }, {-123, 78 }, {-122,-121 }, { 80, 81 }, {-120,-119 }, {-118,-117 }, { 83, 86 }, { 84, 85 }, {-116,-114 }, {-113,-112 }, { 87, 88 }, {-111,-109 }, {-106,-104 }, { 90, 105 }, { 91, 98 }, { 92, 95 }, { 93, 94 }, {-103,-102 }, {-100, -99 }, { 96, 97 }, { -98, -96 }, { -35, -33 }, { 99, 102 }, { 100, 101 }, { -32, -31 }, { -30, -29 }, { 103, 104 }, { -28, -26 }, { -25, -24 }, { 106, 113 }, { 107, 110 }, { 108, 109 }, { -23, -21 }, { -19, -18 }, { 111, 112 }, { -15, -14 }, { -13, -12 }, { 114, 117 }, { 115, 116 }, { -11, -10 }, { -9, -8 }, { 118, 119 }, { -7, -6 }, { -5, -4 } }; static const int8_t t_huffman_env_bal_1_5dB[48][2] = { { -64, 1 }, { -63, 2 }, { -65, 3 }, { -62, 4 }, { -66, 5 }, { -61, 6 }, { -67, 7 }, { -60, 8 }, { -68, 9 }, { 10, 11 }, { -69, -59 }, { 12, 13 }, { -70, -58 }, { 14, 28 }, { 15, 21 }, { 16, 18 }, { -57, 17 }, { -71, -56 }, { 19, 20 }, { -88, -87 }, { -86, -85 }, { 22, 25 }, { 23, 24 }, { -84, -83 }, { -82, -81 }, { 26, 27 }, { -80, -79 }, { -78, -77 }, { 29, 36 }, { 30, 33 }, { 31, 32 }, { -76, -75 }, { -74, -73 }, { 34, 35 }, { -72, -55 }, { -54, -53 }, { 37, 41 }, { 38, 39 }, { -52, -51 }, { -50, 40 }, { -49, -48 }, { 42, 45 }, { 43, 44 }, { -47, -46 }, { -45, -44 }, { 46, 47 }, { -43, -42 }, { -41, -40 } }; static const int8_t f_huffman_env_bal_1_5dB[48][2] = { { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, { -60, 9 }, { 10, 11 }, { -69, -59 }, { -70, 12 }, { -58, 13 }, { 14, 17 }, { -71, 15 }, { -57, 16 }, { -56, -73 }, { 18, 32 }, { 19, 25 }, { 20, 22 }, { -72, 21 }, { -88, -87 }, { 23, 24 }, { -86, -85 }, { -84, -83 }, { 26, 29 }, { 27, 28 }, { -82, -81 }, { -80, -79 }, { 30, 31 }, { -78, -77 }, { -76, -75 }, { 33, 40 }, { 34, 37 }, { 35, 36 }, { -74, -55 }, { -54, -53 }, { 38, 39 }, { -52, -51 }, { -50, -49 }, { 41, 44 }, { 42, 43 }, { -48, -47 }, { -46, -45 }, { 45, 46 }, { -44, -43 }, { -42, 47 }, { -41, -40 } }; static const int8_t t_huffman_env_3_0dB[62][2] = { { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, { -62, 5 }, { -67, 6 }, { -61, 7 }, { -68, 8 }, { -60, 9 }, { 10, 11 }, { -69, -59 }, { 12, 14 }, { -70, 13 }, { -71, -58 }, { 15, 18 }, { 16, 17 }, { -72, -57 }, { -73, -74 }, { 19, 22 }, { -56, 20 }, { -55, 21 }, { -54, -77 }, { 23, 31 }, { 24, 25 }, { -75, -76 }, { 26, 27 }, { -78, -53 }, { 28, 29 }, { -52, -95 }, { -94, 30 }, { -93, -92 }, { 32, 47 }, { 33, 40 }, { 34, 37 }, { 35, 36 }, { -91, -90 }, { -89, -88 }, { 38, 39 }, { -87, -86 }, { -85, -84 }, { 41, 44 }, { 42, 43 }, { -83, -82 }, { -81, -80 }, { 45, 46 }, { -79, -51 }, { -50, -49 }, { 48, 55 }, { 49, 52 }, { 50, 51 }, { -48, -47 }, { -46, -45 }, { 53, 54 }, { -44, -43 }, { -42, -41 }, { 56, 59 }, { 57, 58 }, { -40, -39 }, { -38, -37 }, { 60, 61 }, { -36, -35 }, { -34, -33 } }; static const int8_t f_huffman_env_3_0dB[62][2] = { { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, { -62, 5 }, { -67, 6 }, { 7, 8 }, { -61, -68 }, { 9, 10 }, { -60, -69 }, { 11, 12 }, { -59, -70 }, { 13, 14 }, { -58, -71 }, { 15, 16 }, { -57, -72 }, { 17, 19 }, { -56, 18 }, { -55, -73 }, { 20, 24 }, { 21, 22 }, { -74, -54 }, { -53, 23 }, { -75, -76 }, { 25, 30 }, { 26, 27 }, { -52, -51 }, { 28, 29 }, { -77, -79 }, { -50, -49 }, { 31, 39 }, { 32, 35 }, { 33, 34 }, { -78, -46 }, { -82, -88 }, { 36, 37 }, { -83, -48 }, { -47, 38 }, { -86, -85 }, { 40, 47 }, { 41, 44 }, { 42, 43 }, { -80, -44 }, { -43, -42 }, { 45, 46 }, { -39, -87 }, { -84, -40 }, { 48, 55 }, { 49, 52 }, { 50, 51 }, { -95, -94 }, { -93, -92 }, { 53, 54 }, { -91, -90 }, { -89, -81 }, { 56, 59 }, { 57, 58 }, { -45, -41 }, { -38, -37 }, { 60, 61 }, { -36, -35 }, { -34, -33 } }; static const int8_t t_huffman_env_bal_3_0dB[24][2] = { { -64, 1 }, { -63, 2 }, { -65, 3 }, { -66, 4 }, { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, { -60, 9 }, { 10, 16 }, { 11, 13 }, { -69, 12 }, { -76, -75 }, { 14, 15 }, { -74, -73 }, { -72, -71 }, { 17, 20 }, { 18, 19 }, { -70, -59 }, { -58, -57 }, { 21, 22 }, { -56, -55 }, { -54, 23 }, { -53, -52 } }; static const int8_t f_huffman_env_bal_3_0dB[24][2] = { { -64, 1 }, { -65, 2 }, { -63, 3 }, { -66, 4 }, { -62, 5 }, { -61, 6 }, { -67, 7 }, { -68, 8 }, { -60, 9 }, { 10, 13 }, { -69, 11 }, { -59, 12 }, { -58, -76 }, { 14, 17 }, { 15, 16 }, { -75, -74 }, { -73, -72 }, { 18, 21 }, { 19, 20 }, { -71, -70 }, { -57, -56 }, { 22, 23 }, { -55, -54 }, { -53, -52 } }; static const int8_t t_huffman_noise_3_0dB[62][2] = { { -64, 1 }, { -63, 2 }, { -65, 3 }, { -66, 4 }, { -62, 5 }, { -67, 6 }, { 7, 8 }, { -61, -68 }, { 9, 30 }, { 10, 15 }, { -60, 11 }, { -69, 12 }, { 13, 14 }, { -59, -53 }, { -95, -94 }, { 16, 23 }, { 17, 20 }, { 18, 19 }, { -93, -92 }, { -91, -90 }, { 21, 22 }, { -89, -88 }, { -87, -86 }, { 24, 27 }, { 25, 26 }, { -85, -84 }, { -83, -82 }, { 28, 29 }, { -81, -80 }, { -79, -78 }, { 31, 46 }, { 32, 39 }, { 33, 36 }, { 34, 35 }, { -77, -76 }, { -75, -74 }, { 37, 38 }, { -73, -72 }, { -71, -70 }, { 40, 43 }, { 41, 42 }, { -58, -57 }, { -56, -55 }, { 44, 45 }, { -54, -52 }, { -51, -50 }, { 47, 54 }, { 48, 51 }, { 49, 50 }, { -49, -48 }, { -47, -46 }, { 52, 53 }, { -45, -44 }, { -43, -42 }, { 55, 58 }, { 56, 57 }, { -41, -40 }, { -39, -38 }, { 59, 60 }, { -37, -36 }, { -35, 61 }, { -34, -33 } }; static const int8_t t_huffman_noise_bal_3_0dB[24][2] = { { -64, 1 }, { -65, 2 }, { -63, 3 }, { 4, 9 }, { -66, 5 }, { -62, 6 }, { 7, 8 }, { -76, -75 }, { -74, -73 }, { 10, 17 }, { 11, 14 }, { 12, 13 }, { -72, -71 }, { -70, -69 }, { 15, 16 }, { -68, -67 }, { -61, -60 }, { 18, 21 }, { 19, 20 }, { -59, -58 }, { -57, -56 }, { 22, 23 }, { -55, -54 }, { -53, -52 } }; static INLINE int16_t sbr_huff_dec(bitfile *ld, sbr_huff_tab t_huff) { uint8_t bit; int16_t index = 0; while (index >= 0) { bit = (uint8_t)faad_get1bit(ld); index = t_huff[index][bit]; } return index + 64; } /* table 10 */ void sbr_envelope(bitfile *ld, sbr_info *sbr, uint8_t ch) { uint8_t env, band; int8_t delta = 0; sbr_huff_tab t_huff, f_huff; if ((sbr->L_E[ch] == 1) && (sbr->bs_frame_class[ch] == FIXFIX)) sbr->amp_res[ch] = 0; else sbr->amp_res[ch] = sbr->bs_amp_res; if ((sbr->bs_coupling) && (ch == 1)) { delta = 1; if (sbr->amp_res[ch]) { t_huff = t_huffman_env_bal_3_0dB; f_huff = f_huffman_env_bal_3_0dB; } else { t_huff = t_huffman_env_bal_1_5dB; f_huff = f_huffman_env_bal_1_5dB; } } else { delta = 0; if (sbr->amp_res[ch]) { t_huff = t_huffman_env_3_0dB; f_huff = f_huffman_env_3_0dB; } else { t_huff = t_huffman_env_1_5dB; f_huff = f_huffman_env_1_5dB; } } for (env = 0; env < sbr->L_E[ch]; env++) { if (sbr->bs_df_env[ch][env] == 0) { if ((sbr->bs_coupling == 1) && (ch == 1)) { if (sbr->amp_res[ch]) { sbr->E[ch][0][env] = (uint16_t)(faad_getbits(ld, 5 DEBUGVAR(1,272,"sbr_envelope(): bs_data_env")) << delta); } else { sbr->E[ch][0][env] = (uint16_t)(faad_getbits(ld, 6 DEBUGVAR(1,273,"sbr_envelope(): bs_data_env")) << delta); } } else { if (sbr->amp_res[ch]) { sbr->E[ch][0][env] = (uint16_t)(faad_getbits(ld, 6 DEBUGVAR(1,274,"sbr_envelope(): bs_data_env")) << delta); } else { sbr->E[ch][0][env] = (uint16_t)(faad_getbits(ld, 7 DEBUGVAR(1,275,"sbr_envelope(): bs_data_env")) << delta); } } for (band = 1; band < sbr->n[sbr->f[ch][env]]; band++) { sbr->E[ch][band][env] = (sbr_huff_dec(ld, f_huff) << delta); } } else { for (band = 0; band < sbr->n[sbr->f[ch][env]]; band++) { sbr->E[ch][band][env] = (sbr_huff_dec(ld, t_huff) << delta); } } } extract_envelope_data(sbr, ch); } /* table 11 */ void sbr_noise(bitfile *ld, sbr_info *sbr, uint8_t ch) { uint8_t noise, band; int8_t delta = 0; sbr_huff_tab t_huff, f_huff; if ((sbr->bs_coupling == 1) && (ch == 1)) { delta = 1; t_huff = t_huffman_noise_bal_3_0dB; f_huff = f_huffman_env_bal_3_0dB; } else { delta = 0; t_huff = t_huffman_noise_3_0dB; f_huff = f_huffman_env_3_0dB; } for (noise = 0; noise < sbr->L_Q[ch]; noise++) { if(sbr->bs_df_noise[ch][noise] == 0) { if ((sbr->bs_coupling == 1) && (ch == 1)) { sbr->Q[ch][0][noise] = (faad_getbits(ld, 5 DEBUGVAR(1,276,"sbr_noise(): bs_data_noise")) << delta); } else { sbr->Q[ch][0][noise] = (faad_getbits(ld, 5 DEBUGVAR(1,277,"sbr_noise(): bs_data_noise")) << delta); } for (band = 1; band < sbr->N_Q; band++) { sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, f_huff) << delta); } } else { for (band = 0; band < sbr->N_Q; band++) { sbr->Q[ch][band][noise] = (sbr_huff_dec(ld, t_huff) << delta); } } } extract_noise_floor_data(sbr, ch); } #endif xine-lib-1.2/contrib/libfaad/diff_from_faad2-2.7.patch0000644000175000017500000002613614647725152020233 0ustar memediff -r 5336b582f060 contrib/libfaad/bits.h --- a/contrib/libfaad/bits.h Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/bits.h Fri Feb 10 12:36:28 2017 +0200 @@ -35,6 +35,8 @@ extern "C" { #endif +#include "xine/attributes.h" + #include "analysis.h" #ifdef ANALYSIS #include @@ -108,7 +110,7 @@ } /* reads only n bytes from the stream instead of the standard 4 */ -static /*INLINE*/ uint32_t getdword_n(void *mem, int n) +static /*INLINE*/ __attr_unused uint32_t getdword_n(void *mem, int n) { uint32_t tmp = 0; #ifndef ARCH_IS_BIG_ENDIAN @@ -266,7 +268,7 @@ } } -static /*INLINE*/ uint32_t faad_getbits_rev(bitfile *ld, uint32_t n +static /*INLINE*/ __attr_unused uint32_t faad_getbits_rev(bitfile *ld, uint32_t n DEBUGDEC) { uint32_t ret; diff -r 5336b582f060 contrib/libfaad/cfft.c --- a/contrib/libfaad/cfft.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/cfft.c Fri Feb 10 12:36:28 2017 +0200 @@ -698,7 +698,7 @@ { uint16_t i; uint16_t k1, l1, l2; - uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido, idl1; + uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido /*, idl1 */; nf = ifac[1]; na = 0; @@ -710,7 +710,7 @@ ip = ifac[k1]; l2 = ip*l1; ido = n / l2; - idl1 = ido*l1; + /* idl1 = ido*l1; */ switch (ip) { @@ -777,7 +777,7 @@ { uint16_t i; uint16_t k1, l1, l2; - uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido, idl1; + uint16_t na, nf, ip, iw, ix2, ix3, ix4, ido /*, idl1 */; nf = ifac[1]; na = 0; @@ -789,7 +789,7 @@ ip = ifac[k1]; l2 = ip*l1; ido = n / l2; - idl1 = ido*l1; + /* idl1 = ido*l1; */ switch (ip) { diff -r 5336b582f060 contrib/libfaad/common.c --- a/contrib/libfaad/common.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/common.c Fri Feb 10 12:36:28 2017 +0200 @@ -202,9 +202,10 @@ 1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1,0,1,1,0,1,0,0,1,1,0,0,1,0,1,1,0 }; +/* TJ. these are now part of NeAACDecHandle static uint32_t __r1 = 1; static uint32_t __r2 = 1; - +*/ /* * This is a simple random number generator with good quality for audio purposes. diff -r 5336b582f060 contrib/libfaad/common.h --- a/contrib/libfaad/common.h Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/common.h Fri Feb 10 12:36:28 2017 +0200 @@ -36,7 +36,7 @@ #endif #ifdef HAVE_CONFIG_H -# include "../config.h" +# include "config.h" #endif #include "neaacdec.h" diff -r 5336b582f060 contrib/libfaad/decoder.c --- a/contrib/libfaad/decoder.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/decoder.c Fri Feb 10 12:36:28 2017 +0200 @@ -64,7 +64,7 @@ NeAACDecFrameInfo *hInfo); -char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode) +const char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode) { if (errcode >= NUM_ERROR_MESSAGES) return NULL; diff -r 5336b582f060 contrib/libfaad/drc.c --- a/contrib/libfaad/drc.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/drc.c Fri Feb 10 12:36:28 2017 +0200 @@ -132,7 +132,7 @@ if (drc->dyn_rng_sgn[bd]) /* compress */ exp = -drc->ctrl1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/REAL_CONST(24.0); else /* boost */ - exp = drc->ctrl2 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/REAL_CONST(24.0); + exp = drc->ctrl2 * (drc->dyn_rng_ctl[bd] + (DRC_REF_LEVEL - drc->prog_ref_level))/REAL_CONST(24.0); factor = (real_t)pow(2.0, exp); /* Apply gain factor */ @@ -145,8 +145,8 @@ exp = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/ 24; frac = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24; } else { /* boost */ - exp = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/ 24; - frac = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24; + exp = (drc->dyn_rng_ctl[bd] + (DRC_REF_LEVEL - drc->prog_ref_level))/ 24; + frac = (drc->dyn_rng_ctl[bd] + (DRC_REF_LEVEL - drc->prog_ref_level)) % 24; } /* Apply gain factor */ diff -r 5336b582f060 contrib/libfaad/error.c --- a/contrib/libfaad/error.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/error.c Fri Feb 10 12:36:28 2017 +0200 @@ -31,7 +31,7 @@ #include "common.h" #include "error.h" -char *err_msg[] = { +const char *err_msg[] = { "No error", "Gain control not yet implemented", "Pulse coding not allowed in short blocks", diff -r 5336b582f060 contrib/libfaad/error.h --- a/contrib/libfaad/error.h Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/error.h Fri Feb 10 12:36:28 2017 +0200 @@ -36,7 +36,7 @@ #endif #define NUM_ERROR_MESSAGES 34 -extern char *err_msg[]; +extern const char *err_msg[]; #ifdef __cplusplus } diff -r 5336b582f060 contrib/libfaad/hcr.c --- a/contrib/libfaad/hcr.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/hcr.c Fri Feb 10 12:36:28 2017 +0200 @@ -225,7 +225,9 @@ uint16_t sp_offset[8]; uint16_t g, i, sortloop, set, bitsread; +#ifdef HCR_CWCOUNT uint16_t bitsleft, codewordsleft; +#endif uint8_t w_idx, sfb, this_CB, last_CB, this_sec_CB; const uint16_t nshort = hDecoder->frameLength/8; @@ -408,7 +410,7 @@ rewrev_bits(&segment[i]); } -#if 0 // Seems to give false errors +#ifdef HCR_CWCOUNT // Seems to give false errors bitsleft = 0; for (i = 0; i < numberOfSegments && !bitsleft; i++) diff -r 5336b582f060 contrib/libfaad/ic_predict.c --- a/contrib/libfaad/ic_predict.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/ic_predict.c Fri Feb 10 12:36:28 2017 +0200 @@ -41,43 +41,43 @@ static void flt_round(float32_t *pf) { int32_t flg; - uint32_t tmp, tmp1, tmp2; + union {float32_t f; uint32_t i;} tmp, tmp1, tmp2; - tmp = *(uint32_t*)pf; - flg = tmp & (uint32_t)0x00008000; - tmp &= (uint32_t)0xffff0000; - tmp1 = tmp; + tmp.f = *pf; + flg = tmp.i & (uint32_t)0x00008000; + tmp.i &= (uint32_t)0xffff0000; /* round 1/2 lsb toward infinity */ if (flg) { - tmp &= (uint32_t)0xff800000; /* extract exponent and sign */ - tmp |= (uint32_t)0x00010000; /* insert 1 lsb */ - tmp2 = tmp; /* add 1 lsb and elided one */ - tmp &= (uint32_t)0xff800000; /* extract exponent and sign */ + tmp1 = tmp; + tmp.i &= (uint32_t)0xff800000; /* extract exponent and sign */ + tmp.i |= (uint32_t)0x00010000; /* insert 1 lsb */ + tmp2 = tmp; /* add 1 lsb and elided one */ + tmp.i &= (uint32_t)0xff800000; /* extract exponent and sign */ - *pf = *(float32_t*)&tmp1 + *(float32_t*)&tmp2 - *(float32_t*)&tmp; + *pf = tmp1.f + tmp2.f - tmp.f; } else { - *pf = *(float32_t*)&tmp; + *pf = tmp.f; } } static int16_t quant_pred(float32_t x) { int16_t q; - uint32_t *tmp = (uint32_t*)&x; + union {float32_t f; uint32_t i;} tmp; + tmp.f = x; - q = (int16_t)(*tmp>>16); + q = (int16_t)(tmp.i>>16); return q; } static float32_t inv_quant_pred(int16_t q) { - float32_t x; - uint32_t *tmp = (uint32_t*)&x; - *tmp = ((uint32_t)q)<<16; + union {float32_t f; uint32_t i;} tmp; + tmp.i = ((uint32_t)q)<<16; - return x; + return tmp.f; } static void ic_predict(pred_state *state, real_t input, real_t *output, uint8_t pred) diff -r 5336b582f060 contrib/libfaad/neaacdec.h --- a/contrib/libfaad/neaacdec.h Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/neaacdec.h Fri Feb 10 12:36:28 2017 +0200 @@ -198,7 +198,7 @@ unsigned char ps; } NeAACDecFrameInfo; -char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode); +const char* NEAACDECAPI NeAACDecGetErrorMessage(unsigned char errcode); unsigned long NEAACDECAPI NeAACDecGetCapabilities(void); diff -r 5336b582f060 contrib/libfaad/ps_dec.c --- a/contrib/libfaad/ps_dec.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/ps_dec.c Fri Feb 10 12:36:28 2017 +0200 @@ -1034,7 +1034,7 @@ qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32]) { uint8_t gr, n, m, bk; - uint8_t temp_delay; + uint8_t temp_delay = 0; uint8_t sb, maxsb; const complex_t *Phi_Fract_SubQmf; uint8_t temp_delay_ser[NO_ALLPASS_LINKS]; @@ -1043,6 +1043,8 @@ real_t G_TransientRatio[32][34] = {{0}}; complex_t inputLeft; + /* calm down gcc */ + memset (temp_delay_ser, 0, sizeof (temp_delay_ser)); /* chose hybrid filterbank: 20 or 34 band case */ if (ps->use34hybrid_bands) @@ -1454,9 +1456,10 @@ uint8_t sb, maxsb; uint8_t env; uint8_t nr_ipdopd_par; - complex_t h11, h12, h21, h22; - complex_t H11, H12, H21, H22; - complex_t deltaH11, deltaH12, deltaH21, deltaH22; + /* calm down gcc */ + complex_t h11 = {0, 0}, h12 = {0, 0}, h21 = {0, 0}, h22 = {0, 0}; + complex_t H11 = {0, 0}, H12 = {0, 0}, H21 = {0, 0}, H22 = {0, 0}; + complex_t deltaH11 = {0, 0}, deltaH12 = {0, 0}, deltaH21 = {0, 0}, deltaH22 = {0, 0}; complex_t tempLeft; complex_t tempRight; complex_t phaseLeft; @@ -1963,8 +1966,13 @@ /* main Parametric Stereo decoding function */ uint8_t ps_decode(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]) { - qmf_t X_hybrid_left[32][32] = {{0}}; - qmf_t X_hybrid_right[32][32] = {{0}}; +#ifndef SBR_LOW_POWER +# define QMF_ZERO {0,0} +#else +# define QMF_ZERO 0 +#endif + qmf_t X_hybrid_left[32][32] = {{QMF_ZERO}}; + qmf_t X_hybrid_right[32][32] = {{QMF_ZERO}}; /* delta decoding of the bitstream data */ ps_data_decode(ps); diff -r 5336b582f060 contrib/libfaad/sbr_dec.c --- a/contrib/libfaad/sbr_dec.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/sbr_dec.c Fri Feb 10 12:36:28 2017 +0200 @@ -602,8 +602,13 @@ uint8_t l, k; uint8_t dont_process = 0; uint8_t ret = 0; - ALIGN qmf_t X_left[38][64] = {{0}}; - ALIGN qmf_t X_right[38][64] = {{0}}; /* must set this to 0 */ +#ifndef SBR_LOW_POWER +# define QMF_ZERO {0,0} +#else +# define QMF_ZERO 0 +#endif + ALIGN qmf_t X_left[38][64] = {{QMF_ZERO}}; + ALIGN qmf_t X_right[38][64] = {{QMF_ZERO}}; /* must set this to 0 */ if (sbr == NULL) return 20; diff -r 5336b582f060 contrib/libfaad/sbr_hfadj.c --- a/contrib/libfaad/sbr_hfadj.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/sbr_hfadj.c Fri Feb 10 12:36:28 2017 +0200 @@ -1186,8 +1186,9 @@ real_t den = 0; real_t acc1 = 0; real_t acc2 = 0; +#if 0 uint8_t current_res_band_size = 0; - +#endif uint8_t ml1, ml2; ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; diff -r 5336b582f060 contrib/libfaad/specrec.c --- a/contrib/libfaad/specrec.c Fri Feb 10 12:12:52 2017 +0200 +++ b/contrib/libfaad/specrec.c Fri Feb 10 12:36:28 2017 +0200 @@ -425,7 +425,7 @@ } } -/* iquant() * +/* iquant() */ /* output = sign(input)*abs(input)^(4/3) */ /**/ static INLINE real_t iquant(int16_t q, const real_t *tab, uint8_t *error) xine-lib-1.2/contrib/vidix/0000755000175000017500000000000014647725152013447 5ustar memexine-lib-1.2/contrib/vidix/vidix.txt0000644000175000017500000002243314647725152015337 0ustar meme VIDIX - VIDeo Interface for *niX ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This interface was designed and introduced as interface to userspace drivers to provide DGA everywhere where it's possible (unline X11). I hope that these drivers will be portable same as X11 (not only on *nix). What is it: - It's portable successor of mga_vid technology which is located in user-space. - Unlikely X11 it's provides DGA everywhere where it's possible. - Unlikely v4l it provides interface for video playback - Unlikely linux's drivers it uses mathematics library. Why it was developed: As said Vladimir Dergachev (http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/gatos/km/km.rfc.txt): "0) Motivation v4l, v4l2 and Xv are all suffering from the same problem: attempt to fit existing multimedia devices into a fixed scheme." Well - I tried to implement something similar by motivation. How it works: ~~~~~~~~~~~~~ This interface is almost finished. But I guess it can be expanded by developer's requests. So any suggestions, reports, criticism are gladly accepted. 1) APP calls vixGetVersion to check age of driver ;) 2) APP calls vixProbe. Driver should return 0 if it can handle something in PC. 3) APP calls vixGetCapability. Driver should return filled vidix_capability_t.type field at least. 4) If above calls were succesful then APP calls vixInit function (Driver can have not exported this function in this case call will be skiped). 5) After initializing of driver APP calls vixGetCapability again (In this case driver must fill every field of struct) 6) APP calls vixQueryFourcc. Driver should answer - can it configure video memory for given fourcc or not. 7) APP calls vixConfigPlayback. Driver should prepare BES on this call. APP pass to driver following info: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vidix_playback_t.fourcc - contains fourcc of movie vidix_playback_t.capability - currently contsinas copy of vidix_capability_t.flags vidix_playback_t.blend_factor- currently unused vidix_playback_t.src - x,y,w,h fields contain original movie size (in pixels) x and y often are nulls. vidix_playback_t.src.pitch.y These fields contain source pitches vidix_playback_t.src.pitch.u - for each Y,U,V plane in bytes. vidix_playback_t.src.pitch.v (For packed fourcc only Y value is used) They are hints for driver to use same destinition pitches as in source memory (to speed up memcpy process). Note: when source pitches are unknown or variable these field will be filled into 0. vidix_playback_t.dest - x,y,w,h fields contains destinition rectange on the screen in pixels. vidix_playback_t.num_frames - maximal # of frames which can be used by APP. (Currently 10). Driver should fill following fields: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vidix_playback_t.num_frames - real # of frames which will be used by driver. (Should be less or equal to app's num_frames). vidix_playback_t.dest.pitch.y These fields should contain alignment vidix_playback_t.dest.pitch.u - for each Y,U,V plane in bytes. vidix_playback_t.dest.pitch.v (For packed fourcc only Y value is used) vidix_playback_t.frame_size - Driver should tell to app which size of source frame (src.w and src.h) should use APP (according to pitches and offsets) vidix_playback_t.offsets - offsets from begin of BES memory for each frame vidix_playback_t.offset.y These field should contain offset vidix_playback_t.offset.u - for each Y,U,V plane within frame. vidix_playback_t.offset.v (For packed fourcc only Y value is used) vidix_playback_t.dga_addr - Address of BES memory. Also see this picture: VIDEO MEMORY layout: +----------- It's begin of video memory End of video memory--------------+ | | v v [ RGB memory | YUV memory | UNDEF ] ^ | +---- begin of BES memory BES MEMORY layout: +-------- begin of BES memory | v [ | | | | | ^ ^ ^ ^ ^ | | | | + BEGIN of second frame | | | + BEGIN of V plane | | + BEGIN of U plane | +------- BEGIN of Y plane | +--------- BEGIN of first frame This means that in general case: offset of frame != offset of BES offset of Y plane != offset of first frame But often: vidix_playback_t.offsets[0] = vidix_playback_t.offset.y = 0; Formula: (For Y plane) copy source to: vidix_playback_t.dga_addr + vidix_playback_t.offsets[i] + vidix_playback_t.offset.y 8) APP calls vixPlaybackOn. Driver should activate BES on this call. 9) PLAYBACK. Driver should sleep here ;) But during playback can be called: vixFrameSelect (if this function is exported) Driver should prepare and activate corresponded frame. This function is used only for double and trilpe buffering and never used for single buffering playback. vixGet(Set)GrKeys (if this function is exported) This interface should be tuned but intriduced for overlapped playback and video effects (TYPE_FX) vixPlaybackGet(Set)Eq (if this function is exported) For color correction. 10) APP calls vixPlaybackOff. Driver should deactivate BES on this call. 11) If vixDestroy is defined APP calls this function before unloading driver from memory. What functions are mandatory: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ vixGetVersion vixProbe vixGetCapability vixQueryFourcc vixConfigPlayback vixPlaybackOn vixPlaybackOff All other functions are optionaly. BUSMASTERING ************ Busmastering is technique to implement data transfer through DMA. This technique is intended to free CPU for other useful work to speedup movie playback. The speedup will be different on different CPUs OSes and videocards. Only thing which SHOULD be implemented it's the fact that frame should be transfered faster than 1/fps. (I.e. faster than 33ms for 30 fps or faster than 40ms for 25 fps) VIDIX implementation of BM (busmastering) is slightly specific. During driver development you should keep in mind the next rules: 1. BM is implemented as parallel process which should work simultaneously with frame decoding. 2. To have possibility to use busmastering by non-ROOT users driver should rather call functions from libdha than from libc. (Example: driver should call bm_lock_mem instead of mlock) 3. To speedup data transfer player will pass pointer to the DMA buffer which will have the same structure (planes and strides) as video memory (In this connexion driver should allocate frames in video memory same as if BM would not be implemented). Interface: ~~~~~~~~~~ The interface of BM is implemented through 2 functions: vixPlaybackCopyFrame vixQueryDMAStatus vixPlaybackCopyFrame should prepare engine to copy frame from system memory into video framebuffer. After that driver should send command into engine to start data transfer and return control immediatedly. The structure vidix_dma_s in details: typedef struct vidix_dma_s { /* app -> driver. Virtual address of source. Note: source buffer is allocated by using malloc or memalign(); */ void * src; /* app -> driver. Destinition offset within of video memory. It will point offset within of YUV memory where destinition data should be stored. */ unsigned dest_offset; /* app -> driver. Size of data to be transfered in bytes. */ unsigned size; /* can accept ORed values of BM_DMA* definitions BM_DMA_ASYNC - default value which indicates that transactiion should work asynchronously. BM_DMA_SYNC - may be ignored due speedup reasons BM_DMA_FIXED_BUFFS - indicates that player was started by ROOT and source DMA buffers were already locked in memory through mlock(). /* app -> driver: idx of src buffer. if BM_DMA_FIXED_BUFFS flags is set then this field indicates which from buffers currently is passed into driver. This field maybe ignored by driver but it would be better to use that for minor speedup of engine preparing. */ unsigned idx; /* for internal use by driver. Driver may use them on its opinion */ void * internal[VID_PLAY_MAXFRAMES]; }vidix_dma_t; vixQueryDMAStatus should check out DMA status and return 1 if BM is busy and 0 otherwise. Note: this function shouldn't wait any changes in DMA state. A few words about of non-linux systems ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Well, there is only one problem which stops us to use BM on nono-linux systems: it's lacking of possibility to perform convertion from virtual to physical address in user-space. This problem is sloved by so-called dhahelper driver for linux. What about of other OSes then this driver requires to be ported first. (Of course, except of DOS and DOS32 where these convertions are unnecessary). Useful links: ~~~~~~~~~~~~~ Guide to DTV http://www.digitaltelevision.com/dtvbook/toc.shtml Fourcc http://www.webartz.com/fourcc/ MPEG http://www.mpeg.org/MPEG/index.html Analog colors http://www.miranda.com/en/app_notes/TN/TN-05/TN-05.htm Please send your suggestions, reports, feedback to mplayerxp-general@lists.sourceforge.net Best regards! Nick Kurshev. xine-lib-1.2/contrib/vidix/vidixlib.c0000644000175000017500000003427014647725152015433 0ustar meme/* * vidixlib.c * VIDIXLib - Library for VIDeo Interface for *niX * This interface is introduced as universal one to MPEG decoder, * BES == Back End Scaler and YUV2RGB hw accelerators. * In the future it may be expanded up to capturing and audio things. * Main goal of this this interface imlpementation is providing DGA * everywhere where it's possible (unlike X11 and other). * Copyright 2002 Nick Kurshev * Licence: GPL * This interface is based on v4l2, fbvid.h, mga_vid.h projects * and personally my ideas. * NOTE: This interface is introduces as APP interface. * Don't use it for driver. * It provides multistreaming. This mean that APP can handle * several streams simultaneously. (Example: Video capturing and video * playback or capturing, video playback, audio encoding and so on). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include /* GLIBC specific. Exists under cygwin too! */ #include #include "vidixlib.h" #include "bswap.h" #define t_vdl(p) (((vdl_stream_t *)p)) typedef struct vdl_stream_s { void * handle; int (*get_caps)(vidix_capability_t *); int (*query_fourcc)(vidix_fourcc_t *); int (*config_playback)(vidix_playback_t *); int (*playback_on)( void ); int (*playback_off)( void ); /* Functions below can be missed in driver ;) */ int (*init)(const char *); void (*destroy)(void); int (*frame_sel)( unsigned frame_idx ); int (*get_eq)( vidix_video_eq_t * ); int (*set_eq)( const vidix_video_eq_t * ); int (*get_deint)( vidix_deinterlace_t * ); int (*set_deint)( const vidix_deinterlace_t * ); int (*copy_frame)( const vidix_dma_t * ); int (*query_dma)( void ); int (*get_gkey)( vidix_grkey_t * ); int (*set_gkey)( const vidix_grkey_t * ); int (*get_num_fx)( unsigned * ); int (*get_fx)( vidix_oem_fx_t * ); int (*set_fx)( const vidix_oem_fx_t * ); }vdl_stream_t; static char drv_name[FILENAME_MAX]; static int dl_idx = -1; /* currently available driver for static linking */ static const char* const drv_snames[] = { #ifdef VIDIX_BUILD_STATIC "genfb_", "mach64_", "mga_crtc2_", "mga_", "nvidia_", "pm2_", "pm3_", "radeo_", "rage128_", #endif NULL }; extern unsigned vdlGetVersion( void ) { return VIDIX_VERSION; } static void* dlsymm(void* handle, const char* fce) { char b[100]; #if defined(__OpenBSD__) && !defined(__ELF__) b[0] = '_'; b[1] = 0; #else b[0] = 0; #endif if (dl_idx >= 0) strcat(b, drv_snames[dl_idx]); strcat(b, fce); //printf("Handle %p %s\n", handle, b); return dlsym(handle, b); } static int vdl_fill_driver(VDL_HANDLE stream) { t_vdl(stream)->init = dlsymm(t_vdl(stream)->handle,"vixInit"); t_vdl(stream)->destroy = dlsymm(t_vdl(stream)->handle,"vixDestroy"); t_vdl(stream)->get_caps = dlsymm(t_vdl(stream)->handle,"vixGetCapability"); t_vdl(stream)->query_fourcc = dlsymm(t_vdl(stream)->handle,"vixQueryFourcc"); t_vdl(stream)->config_playback= dlsymm(t_vdl(stream)->handle,"vixConfigPlayback"); t_vdl(stream)->playback_on = dlsymm(t_vdl(stream)->handle,"vixPlaybackOn"); t_vdl(stream)->playback_off = dlsymm(t_vdl(stream)->handle,"vixPlaybackOff"); t_vdl(stream)->frame_sel = dlsymm(t_vdl(stream)->handle,"vixPlaybackFrameSelect"); t_vdl(stream)->get_eq = dlsymm(t_vdl(stream)->handle,"vixPlaybackGetEq"); t_vdl(stream)->set_eq = dlsymm(t_vdl(stream)->handle,"vixPlaybackSetEq"); t_vdl(stream)->get_gkey = dlsymm(t_vdl(stream)->handle,"vixGetGrKeys"); t_vdl(stream)->set_gkey = dlsymm(t_vdl(stream)->handle,"vixSetGrKeys"); t_vdl(stream)->get_deint = dlsymm(t_vdl(stream)->handle,"vixPlaybackGetDeint"); t_vdl(stream)->set_deint = dlsymm(t_vdl(stream)->handle,"vixPlaybackSetDeint"); t_vdl(stream)->copy_frame = dlsymm(t_vdl(stream)->handle,"vixPlaybackCopyFrame"); t_vdl(stream)->query_dma = dlsymm(t_vdl(stream)->handle,"vixQueryDMAStatus"); t_vdl(stream)->get_num_fx = dlsymm(t_vdl(stream)->handle,"vixQueryNumOemEffects"); t_vdl(stream)->get_fx = dlsymm(t_vdl(stream)->handle,"vixGetOemEffect"); t_vdl(stream)->set_fx = dlsymm(t_vdl(stream)->handle,"vixSetOemEffect"); /* check driver viability */ if(!( t_vdl(stream)->get_caps && t_vdl(stream)->query_fourcc && t_vdl(stream)->config_playback && t_vdl(stream)->playback_on && t_vdl(stream)->playback_off)) { printf("vidixlib: Incomplete driver: some of essential features are missed in it.\n"); return 0; } return 1; } #ifndef RTLD_GLOBAL #define RTLD_GLOBAL RTLD_LAZY #endif #ifndef RTLD_NOW #define RTLD_NOW RTLD_LAZY #endif static int vdl_probe_driver(VDL_HANDLE stream,const char *path,const char *name,unsigned cap,int verbose) { vidix_capability_t vid_cap; unsigned (*_ver)(void); int (*_probe)(int,int); int (*_cap)(vidix_capability_t*); strncpy(drv_name,path,sizeof(drv_name)); drv_name[sizeof(drv_name) - 1] = '\0'; strncat(drv_name,name,sizeof(drv_name) - strlen(drv_name) - 1); if(verbose) printf("vidixlib: PROBING: %s\n",drv_name); { const char* slash = strrchr(drv_name, '/'); if (slash) { for (dl_idx = 0; drv_snames[dl_idx]; dl_idx++) { if (!strncmp(slash + 1, drv_snames[dl_idx], strlen(drv_snames[dl_idx]))) break; // locate the name } if (!drv_snames[dl_idx]) dl_idx = -1; } } if (dl_idx < 0) if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_LAZY|RTLD_GLOBAL))) { if(verbose) printf("vidixlib: %s not driver: %s\n",drv_name,dlerror()); return 0; } _ver = dlsymm(t_vdl(stream)->handle,"vixGetVersion"); _probe = dlsymm(t_vdl(stream)->handle,"vixProbe"); _cap = dlsymm(t_vdl(stream)->handle,"vixGetCapability"); if(_ver) { if((*_ver)() != VIDIX_VERSION) { if(verbose) printf("vidixlib: %s has wrong version\n",drv_name); err: dlclose(t_vdl(stream)->handle); t_vdl(stream)->handle = 0; dl_idx = -1; return 0; } } else { fatal_err: if(verbose) printf("vidixlib: %s has no function definition\n",drv_name); goto err; } if(_probe) { if((*_probe)(verbose,PROBE_NORMAL) != 0) goto err; } else goto fatal_err; if(_cap) { if((*_cap)(&vid_cap) != 0) goto err; } else goto fatal_err; if((vid_cap.type & cap) != cap) { if(verbose) printf("vidixlib: Found %s but has no required capability\n",drv_name); goto err; } if(verbose) printf("vidixlib: %s probed o'k\n",drv_name); return 1; } static int vdl_find_driver(VDL_HANDLE stream,const char *path,unsigned cap,int verbose) { DIR *dstream; struct dirent *name; int done = 0; if(!(dstream = opendir(path))) return 0; while(!done) { name = readdir(dstream); if(name) { if(name->d_name[0] != '.' && strstr(name->d_name, ".so")) if(vdl_probe_driver(stream,path,name->d_name,cap,verbose)) break; } else done = 1; } closedir(dstream); return done?0:1; } VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose) { vdl_stream_t *stream; const char *drv_args=NULL; int errcode; if(!(stream = malloc(sizeof(vdl_stream_t)))) return NULL; memset(stream,0,sizeof(vdl_stream_t)); if(name) { unsigned (*ver)(void); int (*probe)(int,int); unsigned version = 0; unsigned char *arg_sep; arg_sep = strchr(name,':'); if(arg_sep) { *arg_sep='\0'; drv_args = &arg_sep[1]; } strncpy(drv_name,path,sizeof(drv_name)); drv_name[sizeof(drv_name) - 1] = '\0'; strncat(drv_name,name,sizeof(drv_name) - strlen(drv_name) - 1); { const char* slash = strrchr(drv_name, '/'); if (slash) { for (dl_idx = 0; drv_snames[dl_idx]; dl_idx++) { if (!strncmp(slash + 1, drv_snames[dl_idx], strlen(drv_snames[dl_idx]))) break; // locate the name } if (!drv_snames[dl_idx]) dl_idx = -1; } } if (dl_idx < 0) if(!(t_vdl(stream)->handle = dlopen(drv_name,RTLD_NOW|RTLD_GLOBAL))) { if (verbose) printf("vidixlib: dlopen error: %s\n", dlerror()); err: vdlClose(stream); return NULL; } ver = dlsymm(t_vdl(stream)->handle,"vixGetVersion"); if(ver) version = (*ver)(); if(version != VIDIX_VERSION) goto err; probe = dlsymm(t_vdl(stream)->handle,"vixProbe"); if(probe) { if((*probe)(verbose,PROBE_FORCE)!=0) goto err; } else goto err; fill: if(!vdl_fill_driver(stream)) goto err; goto ok; } else if(vdl_find_driver(stream,path,cap,verbose)) { if(verbose) printf("vidixlib: will use %s driver\n",drv_name); goto fill; } else goto err; ok: if(t_vdl(stream)->init) { if(verbose) printf("vidixlib: Attempt to initialize driver at: %p\n",t_vdl(stream)->init); if((errcode=t_vdl(stream)->init(drv_args))!=0) { if(verbose) printf("vidixlib: Can't init driver: %s\n",strerror(errcode)); goto err; } } if(verbose) printf("vidixlib: '%s'successfully loaded\n",drv_name); return stream; } void vdlClose(VDL_HANDLE stream) { if(t_vdl(stream)->destroy) t_vdl(stream)->destroy(); if(t_vdl(stream)->handle) dlclose(t_vdl(stream)->handle); memset(stream,0,sizeof(vdl_stream_t)); /* <- it's not stupid */ free(stream); dl_idx = -1; } int vdlGetCapability(VDL_HANDLE handle, vidix_capability_t *cap) { return t_vdl(handle)->get_caps(cap); } #define MPLAYER_IMGFMT_RGB (('R'<<24)|('G'<<16)|('B'<<8)) #define MPLAYER_IMGFMT_BGR (('B'<<24)|('G'<<16)|('R'<<8)) #define MPLAYER_IMGFMT_RGB_MASK 0xFFFFFF00 static uint32_t normalize_fourcc(uint32_t fourcc) { if((fourcc & MPLAYER_IMGFMT_RGB_MASK) == (MPLAYER_IMGFMT_RGB|0) || (fourcc & MPLAYER_IMGFMT_RGB_MASK) == (MPLAYER_IMGFMT_BGR|0)) return bswap_32(fourcc); else return fourcc; } int vdlQueryFourcc(VDL_HANDLE handle,vidix_fourcc_t *f) { f->fourcc = normalize_fourcc(f->fourcc); return t_vdl(handle)->query_fourcc(f); } int vdlConfigPlayback(VDL_HANDLE handle,vidix_playback_t *p) { p->fourcc = normalize_fourcc(p->fourcc); return t_vdl(handle)->config_playback(p); } int vdlPlaybackOn(VDL_HANDLE handle) { return t_vdl(handle)->playback_on(); } int vdlPlaybackOff(VDL_HANDLE handle) { return t_vdl(handle)->playback_off(); } int vdlPlaybackFrameSelect(VDL_HANDLE handle, unsigned frame_idx ) { return t_vdl(handle)->frame_sel ? t_vdl(handle)->frame_sel(frame_idx) : ENOSYS; } int vdlPlaybackGetEq(VDL_HANDLE handle, vidix_video_eq_t * e) { return t_vdl(handle)->get_eq ? t_vdl(handle)->get_eq(e) : ENOSYS; } int vdlPlaybackSetEq(VDL_HANDLE handle, const vidix_video_eq_t * e) { return t_vdl(handle)->set_eq ? t_vdl(handle)->set_eq(e) : ENOSYS; } int vdlPlaybackCopyFrame(VDL_HANDLE handle, vidix_dma_t * f) { return t_vdl(handle)->copy_frame ? t_vdl(handle)->copy_frame(f) : ENOSYS; } int vdlQueryDMAStatus(VDL_HANDLE handle ) { return t_vdl(handle)->query_dma ? t_vdl(handle)->query_dma() : ENOSYS; } int vdlGetGrKeys(VDL_HANDLE handle, vidix_grkey_t * k) { return t_vdl(handle)->get_gkey ? t_vdl(handle)->get_gkey(k) : ENOSYS; } int vdlSetGrKeys(VDL_HANDLE handle, const vidix_grkey_t * k) { return t_vdl(handle)->set_gkey ? t_vdl(handle)->set_gkey(k) : ENOSYS; } int vdlPlaybackGetDeint(VDL_HANDLE handle, vidix_deinterlace_t * d) { return t_vdl(handle)->get_deint ? t_vdl(handle)->get_deint(d) : ENOSYS; } int vdlPlaybackSetDeint(VDL_HANDLE handle, const vidix_deinterlace_t * d) { return t_vdl(handle)->set_deint ? t_vdl(handle)->set_deint(d) : ENOSYS; } int vdlQueryNumOemEffects(VDL_HANDLE handle, unsigned * number ) { return t_vdl(handle)->get_num_fx ? t_vdl(handle)->get_num_fx(number) : ENOSYS; } int vdlGetOemEffect(VDL_HANDLE handle, vidix_oem_fx_t * f) { return t_vdl(handle)->get_fx ? t_vdl(handle)->get_fx(f) : ENOSYS; } int vdlSetOemEffect(VDL_HANDLE handle, const vidix_oem_fx_t * f) { return t_vdl(handle)->set_fx ? t_vdl(handle)->set_fx(f) : ENOSYS; } /* ABI related extensions */ vidix_capability_t * vdlAllocCapabilityS( void ) { vidix_capability_t *retval; retval=malloc(sizeof(vidix_capability_t)); if(retval) memset(retval,0,sizeof(vidix_capability_t)); return retval; } vidix_fourcc_t * vdlAllocFourccS( void ) { vidix_fourcc_t *retval; retval=malloc(sizeof(vidix_fourcc_t)); if(retval) memset(retval,0,sizeof(vidix_fourcc_t)); return retval; } vidix_yuv_t * vdlAllocYUVS( void ) { vidix_yuv_t *retval; retval=malloc(sizeof(vidix_yuv_t)); if(retval) memset(retval,0,sizeof(vidix_yuv_t)); return retval; } vidix_rect_t * vdlAllocRectS( void ) { vidix_rect_t *retval; retval=malloc(sizeof(vidix_rect_t)); if(retval) memset(retval,0,sizeof(vidix_rect_t)); return retval; } vidix_playback_t * vdlAllocPlaybackS( void ) { vidix_playback_t *retval; retval=malloc(sizeof(vidix_playback_t)); if(retval) memset(retval,0,sizeof(vidix_playback_t)); return retval; } vidix_grkey_t * vdlAllocGrKeyS( void ) { vidix_grkey_t *retval; retval=malloc(sizeof(vidix_grkey_t)); if(retval) memset(retval,0,sizeof(vidix_grkey_t)); return retval; } vidix_video_eq_t * vdlAllocVideoEqS( void ) { vidix_video_eq_t *retval; retval=malloc(sizeof(vidix_video_eq_t)); if(retval) memset(retval,0,sizeof(vidix_video_eq_t)); return retval; } vidix_deinterlace_t * vdlAllocDeinterlaceS( void ) { vidix_deinterlace_t *retval; retval=malloc(sizeof(vidix_deinterlace_t)); if(retval) memset(retval,0,sizeof(vidix_deinterlace_t)); return retval; } vidix_dma_t * vdlAllocDmaS( void ) { vidix_dma_t *retval; retval=malloc(sizeof(vidix_dma_t)); if(retval) memset(retval,0,sizeof(vidix_dma_t)); return retval; } vidix_oem_fx_t * vdlAllocOemFxS( void ) { vidix_oem_fx_t *retval; retval=malloc(sizeof(vidix_oem_fx_t)); if(retval) memset(retval,0,sizeof(vidix_oem_fx_t)); return retval; } void vdlFreeCapabilityS(vidix_capability_t * _this) { free(_this); } void vdlFreeFourccS( vidix_fourcc_t * _this ) { free(_this); } void vdlFreePlaybackS( vidix_playback_t * _this ) { free(_this); } void vdlFreeYUVS( vidix_yuv_t * _this) { free(_this); } void vdlFreeRectS( vidix_rect_t * _this) { free(_this); } void vdlFreeGrKeyS( vidix_grkey_t * _this) { free(_this); } void vdlFreeVideoEqS( vidix_video_eq_t * _this) { free(_this); } void vdlFreeDeinterlaceS( vidix_deinterlace_t * _this) { free(_this); } void vdlFreeDmaS( vidix_dma_t * _this) { free(_this); } void vdlFreeOemFxS( vidix_oem_fx_t * _this) { free(_this); } xine-lib-1.2/contrib/vidix/Makefile.am0000644000175000017500000000102014647725152015474 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_LDFLAGS = $(xineplug_ldflags) SUBDIRS = drivers AM_CFLAGS = $(DEFAULT_OCFLAGS) AM_CPPFLAGS += -I$(top_srcdir)/contrib/vidix -I$(top_builddir)/contrib/libdha EXTRA_DIST = README vidix.txt noinst_LTLIBRARIES = libvidix.la $(top_builddir)/contrib/libdha/libdha.la: $(MAKE) -C $(top_builddir)/contrib/libdha libdha.la libvidix_la_SOURCES = \ fourcc.h \ vidix.h \ vidixlib.h \ vidixlib.c libvidix_la_LIBADD = $(DYNAMIC_LD_LIBS) $(top_builddir)/contrib/libdha/libdha.la -lm xine-lib-1.2/contrib/vidix/vidix.h0000644000175000017500000002557614647725152014762 0ustar meme/* * vidix.h * VIDIX - VIDeo Interface for *niX * This interface is introduced as universal one to MPEG decoder, * BES == Back End Scaler and YUV2RGB hw accelerators. * In the future it may be expanded up to capturing and audio things. * Main goal of this this interface imlpementation is providing DGA * everywhere where it's possible (unlike X11 and other). * Copyright 2002 Nick Kurshev * Licence: GPL * This interface is based on v4l2, fbvid.h, mga_vid.h projects * and personally my ideas. * NOTE: This interface is introduces as driver interface. * Don't use it for APP. */ #ifndef VIDIX_H #define VIDIX_H #ifdef __cplusplus extern "C" { #endif #define VIDIX_VERSION 100 /* returns driver version */ extern unsigned vixGetVersion( void ); #define PROBE_NORMAL 0 /* normal probing */ #define PROBE_FORCE 1 /* ignore device_id but recognize device if it's known */ /* Probes video hw. verbose - specifies verbose level. force - specifies force mode - driver should ignore device_id (danger but useful for new devices) Returns 0 if ok else errno */ extern int vixProbe( int verbose, int force ); /* Initializes driver. args - specifies driver specific parameters Returns 0 if ok else errno */ extern int vixInit( const char *args ); /* Destroys driver */ extern void vixDestroy( void ); typedef struct vidix_capability_s { char name[64]; /* Driver name */ char author[64]; /* Author name */ #define TYPE_OUTPUT 0x00000000 /* Is a video playback device */ #define TYPE_CAPTURE 0x00000001 /* Is a capture device */ #define TYPE_CODEC 0x00000002 /* Device supports hw (de)coding */ #define TYPE_FX 0x00000004 /* Is a video effects device */ int type; /* Device type, see below */ unsigned reserved0[4]; int maxwidth; int maxheight; int minwidth; int minheight; int maxframerate; /* -1 if unlimited */ #define FLAG_NONE 0x00000000 /* No flags defined */ #define FLAG_DMA 0x00000001 /* Card can use DMA */ #define FLAG_EQ_DMA 0x00000002 /* Card can use DMA only if src pitch == dest pitch */ #define FLAG_SYNC_DMA 0x00000004 /* Possible to wait for DMA * to finish. See * BM_DMA_SYNC and * BM_DMA_BLOCK below */ #define FLAG_UPSCALER 0x00000010 /* Card supports hw upscaling */ #define FLAG_DOWNSCALER 0x00000020 /* Card supports hw downscaling */ #define FLAG_SUBPIC 0x00001000 /* Card supports DVD subpictures */ #define FLAG_EQUALIZER 0x00002000 /* Card supports equalizer */ unsigned flags; /* Feature flags, see above */ unsigned short vendor_id; unsigned short device_id; unsigned reserved1[4]; }vidix_capability_t; /* Should fill at least type before init. Returns 0 if ok else errno */ extern int vixGetCapability(vidix_capability_t *); typedef struct vidix_fourcc_s { unsigned fourcc; /* input: requested fourcc */ unsigned srcw; /* input: hint: width of source */ unsigned srch; /* input: hint: height of source */ #define VID_DEPTH_NONE 0x0000 #define VID_DEPTH_1BPP 0x0001 #define VID_DEPTH_2BPP 0x0002 #define VID_DEPTH_4BPP 0x0004 #define VID_DEPTH_8BPP 0x0008 #define VID_DEPTH_12BPP 0x0010 #define VID_DEPTH_15BPP 0x0020 #define VID_DEPTH_16BPP 0x0040 #define VID_DEPTH_24BPP 0x0080 #define VID_DEPTH_32BPP 0x0100 unsigned depth; /* output: screen depth for given fourcc */ #define VID_CAP_NONE 0x0000 #define VID_CAP_EXPAND 0x0001 /* if overlay can be bigger than source */ #define VID_CAP_SHRINK 0x0002 /* if overlay can be smaller than source */ #define VID_CAP_BLEND 0x0004 /* if overlay can be blended with framebuffer */ #define VID_CAP_COLORKEY 0x0008 /* if overlay can be restricted to a colorkey */ #define VID_CAP_ALPHAKEY 0x0010 /* if overlay can be restricted to an alpha channel */ #define VID_CAP_COLORKEY_ISRANGE 0x0020 /* if the colorkey can be a range */ #define VID_CAP_ALPHAKEY_ISRANGE 0x0040 /* if the alphakey can be a range */ #define VID_CAP_COLORKEY_ISMAIN 0x0080 /* colorkey is checked against framebuffer */ #define VID_CAP_COLORKEY_ISOVERLAY 0x0100 /* colorkey is checked against overlay */ #define VID_CAP_ALPHAKEY_ISMAIN 0x0200 /* alphakey is checked against framebuffer */ #define VID_CAP_ALPHAKEY_ISOVERLAY 0x0400 /* alphakey is checked against overlay */ unsigned flags; /* output: capability */ }vidix_fourcc_t; /* Returns 0 if ok else errno */ extern int vixQueryFourcc(vidix_fourcc_t *); typedef struct vidix_yuv_s { unsigned y,u,v,a; }vidix_yuv_t; typedef struct vidix_rect_s { unsigned x,y,w,h; /* in pixels */ vidix_yuv_t pitch; /* line-align in bytes */ }vidix_rect_t; typedef struct vidix_color_key_s { #define CKEY_FALSE 0 #define CKEY_TRUE 1 #define CKEY_EQ 2 #define CKEY_NEQ 3 unsigned op; /* defines logical operation */ unsigned char red; unsigned char green; unsigned char blue; unsigned char reserved; }vidix_ckey_t; typedef struct vidix_video_key_s { #define VKEY_FALSE 0 #define VKEY_TRUE 1 #define VKEY_EQ 2 #define VKEY_NEQ 3 unsigned op; /* defines logical operation */ unsigned char key[8]; }vidix_vkey_t; typedef struct vidix_playback_s { unsigned fourcc; /* app -> driver: movies's fourcc */ unsigned capability; /* app -> driver: what capability to use */ unsigned blend_factor; /* app -> driver: blending factor */ vidix_rect_t src; /* app -> driver: original movie size */ vidix_rect_t dest; /* app -> driver: destinition movie size. driver->app dest_pitch */ #define VID_PLAY_INTERLEAVED_UV 0x00000001 /* driver -> app: interleaved UV planes */ #define INTERLEAVING_UV 0x00001000 /* UVUVUVUVUV used by Matrox G200 */ #define INTERLEAVING_VU 0x00001001 /* VUVUVUVUVU */ int flags; /* memory model */ unsigned frame_size; /* driver -> app: destinition frame size */ unsigned num_frames; /* app -> driver: after call: driver -> app */ #define VID_PLAY_MAXFRAMES 1024 /* unreal limitation */ unsigned offsets[VID_PLAY_MAXFRAMES]; /* driver -> app */ vidix_yuv_t offset; /* driver -> app: relative offsets within frame for yuv planes */ void* dga_addr; /* driver -> app: linear address */ }vidix_playback_t; /* Returns 0 if ok else errno */ extern int vixConfigPlayback(vidix_playback_t *); /* Returns 0 if ok else errno */ extern int vixPlaybackOn( void ); /* Returns 0 if ok else errno */ extern int vixPlaybackOff( void ); /* Returns 0 if ok else errno */ extern int vixPlaybackFrameSelect( unsigned frame_idx ); typedef struct vidix_grkey_s { vidix_ckey_t ckey; /* app -> driver: color key */ vidix_vkey_t vkey; /* app -> driver: video key */ #define KEYS_PUT 0 #define KEYS_AND 1 #define KEYS_OR 2 #define KEYS_XOR 3 unsigned key_op; /* app -> driver: keys operations */ }vidix_grkey_t; /* Returns 0 if ok else errno */ extern int vixGetGrKeys( vidix_grkey_t * ); /* Returns 0 if ok else errno */ extern int vixSetGrKeys( const vidix_grkey_t * ); typedef struct vidix_video_eq_s { #define VEQ_CAP_NONE 0x00000000UL #define VEQ_CAP_BRIGHTNESS 0x00000001UL #define VEQ_CAP_CONTRAST 0x00000002UL #define VEQ_CAP_SATURATION 0x00000004UL #define VEQ_CAP_HUE 0x00000008UL #define VEQ_CAP_RGB_INTENSITY 0x00000010UL int cap; /* on get_eq should contain capability of equalizer on set_eq should contain using fields */ /* end-user app can have presets like: cold-normal-hot picture and so on */ int brightness; /* -1000 : +1000 */ int contrast; /* -1000 : +1000 */ int saturation; /* -1000 : +1000 */ int hue; /* -1000 : +1000 */ int red_intensity; /* -1000 : +1000 */ int green_intensity;/* -1000 : +1000 */ int blue_intensity; /* -1000 : +1000 */ #define VEQ_FLG_ITU_R_BT_601 0x00000000 /* ITU-R BT.601 colour space (default) */ #define VEQ_FLG_ITU_R_BT_709 0x00000001 /* ITU-R BT.709 colour space */ #define VEQ_FLG_ITU_MASK 0x0000000f int flags; /* currently specifies ITU YCrCb color space to use */ }vidix_video_eq_t; /* Returns 0 if ok else errno */ extern int vixPlaybackGetEq( vidix_video_eq_t * ); /* Returns 0 if ok else errno */ extern int vixPlaybackSetEq( const vidix_video_eq_t * ); typedef struct vidix_deinterlace_s { #define CFG_NON_INTERLACED 0x00000000 /* stream is not interlaced */ #define CFG_INTERLACED 0x00000001 /* stream is interlaced */ #define CFG_EVEN_ODD_INTERLACING 0x00000002 /* first frame contains even fields but second - odd */ #define CFG_ODD_EVEN_INTERLACING 0x00000004 /* first frame contains odd fields but second - even */ #define CFG_UNIQUE_INTERLACING 0x00000008 /* field deinterlace_pattern is valid */ #define CFG_UNKNOWN_INTERLACING 0x0000000f /* unknown deinterlacing - use adaptive if it's possible */ unsigned flags; unsigned deinterlace_pattern; /* app -> driver: deinterlace pattern if flag CFG_UNIQUE_INTERLACING is set */ }vidix_deinterlace_t; /* Returns 0 if ok else errno */ extern int vixPlaybackGetDeint( vidix_deinterlace_t * ); /* Returns 0 if ok else errno */ extern int vixPlaybackSetDeint( const vidix_deinterlace_t * ); typedef struct vidix_slice_s { void* address; /* app -> driver */ unsigned size; /* app -> driver */ vidix_rect_t slice; /* app -> driver */ }vidix_slice_t; typedef struct vidix_dma_s { void * src; /* app -> driver. Virtual address of source */ unsigned dest_offset; /* app -> driver. Destinition offset within of video memory */ unsigned size; /* app -> driver. Size of transaction */ #define BM_DMA_ASYNC 0 #define BM_DMA_SYNC 1 /* await previous dma transfer completion */ #define BM_DMA_FIXED_BUFFS 2 /* app -> driver: app uses buffers which are fixed in memory */ #define BM_DMA_BLOCK 4 /* block until the transfer is complete */ unsigned flags; /* app -> driver */ unsigned idx; /* app -> driver: idx of src buffer */ void * internal[VID_PLAY_MAXFRAMES]; /* for internal use by driver */ }vidix_dma_t; /* Returns 0 if ok else errno */ extern int vixPlaybackCopyFrame( vidix_dma_t * ); /* Returns 0 if DMA is available else errno (EBUSY) */ extern int vixQueryDMAStatus( void ); /* This structure is introdused to support OEM effects like: - sharpness - exposure - (auto)gain - H(V)flip - black level - white balance and many other */ typedef struct vidix_oem_fx_s { #define FX_TYPE_BOOLEAN 0x00000000 #define FX_TYPE_INTEGER 0x00000001 int type; /* type of effects */ int num; /* app -> driver: effect number. From 0 to max number of effects */ int minvalue; /* min value of effect. 0 - for boolean */ int maxvalue; /* max value of effect. 1 - for boolean */ int value; /* current value of effect on 'get'; required on set */ char * name[80]; /* effect name to display */ }vidix_oem_fx_t; /* Returns 0 if ok else errno */ extern int vixQueryNumOemEffects( unsigned * number ); /* Returns 0 if ok else errno */ extern int vixGetOemEffect( vidix_oem_fx_t * ); /* Returns 0 if ok else errno */ extern int vixSetOemEffect( const vidix_oem_fx_t * ); #ifdef VIDIX_BUILD_STATIC #define VIDIX_NAME(name) VIDIX_STATIC##name #else #define VIDIX_NAME(name) name #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/vidix/README0000644000175000017500000000051514647725152014330 0ustar memeVIDIX - Video Interface for *niX. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This library was designed and introduced as interface to userspace drivers to provide DGA everywhere where it's possible (unline X11). I hope that these drivers will be portable same as X11 (not only on *nix). For detail on how to develop new driver see vidix.txt xine-lib-1.2/contrib/vidix/drivers/0000755000175000017500000000000014647725152015125 5ustar memexine-lib-1.2/contrib/vidix/drivers/mach64_vid.c0000644000175000017500000011603314647725152017221 0ustar meme/* mach64_vid - VIDIX based video driver for Mach64 and 3DRage chips Copyrights 2002 Nick Kurshev. This file is based on sources from GATOS (gatos.sf.net) and X11 (www.xfree86.org) Licence: GPL WARNING: THIS DRIVER IS IN BETTA STAGE */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include /* for m(un)lock */ #include #ifdef HAVE_MALLOC_H #include #ifdef HAVE_MEMALIGN #define MACH64_ENABLE_BM 1 #endif #endif #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "bswap.h" #include "mach64.h" #define UNUSED(x) ((void)(x)) /**< Removes warning about unused arguments */ #define VIDIX_STATIC mach64_ #ifdef MACH64_ENABLE_BM #define cpu_to_le32(a) (a) #define VIRT_TO_CARD(a,b,c) bm_virt_to_bus(a,b,c) #pragma pack(1) typedef struct { uint32_t framebuf_offset; uint32_t sys_addr; uint32_t command; uint32_t reserved; } bm_list_descriptor; #pragma pack() static void *mach64_dma_desc_base[64]; static unsigned long bus_addr_dma_desc = 0; static unsigned long *dma_phys_addrs; #endif static void *mach64_mmio_base = 0; static void *mach64_mem_base = 0; static int32_t mach64_overlay_offset = 0; static uint32_t mach64_ram_size = 0; static uint32_t mach64_buffer_base[64][3]; static int num_mach64_buffers=-1; static int supports_planar=0; static int supports_colour_adj=0; static int supports_idct=0; static int supports_subpic=0; static int supports_lcd_v_stretch=0; pciinfo_t pci_info; static int probed = 0; static int __verbose = 0; #define VERBOSE_LEVEL 2 typedef struct bes_registers_s { /* base address of yuv framebuffer */ uint32_t yuv_base; uint32_t fourcc; /* YUV BES registers */ uint32_t reg_load_cntl; uint32_t scale_inc; uint32_t y_x_start; uint32_t y_x_end; uint32_t vid_buf_pitch; uint32_t height_width; uint32_t scale_cntl; uint32_t exclusive_horz; uint32_t auto_flip_cntl; uint32_t filter_cntl; uint32_t key_cntl; uint32_t test; /* Configurable stuff */ int brightness; int saturation; int ckey_on; uint32_t graphics_key_clr; uint32_t graphics_key_msk; int deinterlace_on; uint32_t deinterlace_pattern; } bes_registers_t; static bes_registers_t besr; typedef struct video_registers_s { const char * sname; uint32_t name; uint32_t value; }video_registers_t; static bes_registers_t besr; /* Graphic keys */ static vidix_grkey_t mach64_grkey; #define DECLARE_VREG(name) { #name, name, 0 } static video_registers_t vregs[] = { DECLARE_VREG(OVERLAY_SCALE_INC), DECLARE_VREG(OVERLAY_Y_X_START), DECLARE_VREG(OVERLAY_Y_X_END), DECLARE_VREG(OVERLAY_SCALE_CNTL), DECLARE_VREG(OVERLAY_EXCLUSIVE_HORZ), DECLARE_VREG(OVERLAY_EXCLUSIVE_VERT), DECLARE_VREG(OVERLAY_TEST), DECLARE_VREG(SCALER_BUF_PITCH), DECLARE_VREG(SCALER_HEIGHT_WIDTH), DECLARE_VREG(SCALER_BUF0_OFFSET), DECLARE_VREG(SCALER_BUF0_OFFSET_U), DECLARE_VREG(SCALER_BUF0_OFFSET_V), DECLARE_VREG(SCALER_BUF1_OFFSET), DECLARE_VREG(SCALER_BUF1_OFFSET_U), DECLARE_VREG(SCALER_BUF1_OFFSET_V), DECLARE_VREG(SCALER_H_COEFF0), DECLARE_VREG(SCALER_H_COEFF1), DECLARE_VREG(SCALER_H_COEFF2), DECLARE_VREG(SCALER_H_COEFF3), DECLARE_VREG(SCALER_H_COEFF4), DECLARE_VREG(SCALER_COLOUR_CNTL), DECLARE_VREG(SCALER_THRESHOLD), DECLARE_VREG(VIDEO_FORMAT), DECLARE_VREG(VIDEO_CONFIG), DECLARE_VREG(VIDEO_SYNC_TEST), DECLARE_VREG(VIDEO_SYNC_TEST_B), DECLARE_VREG(BUS_CNTL), DECLARE_VREG(SRC_CNTL), DECLARE_VREG(GUI_STAT), DECLARE_VREG(BM_ADDR), DECLARE_VREG(BM_DATA), DECLARE_VREG(BM_HOSTDATA), DECLARE_VREG(BM_GUI_TABLE_CMD), DECLARE_VREG(BM_FRAME_BUF_OFFSET), DECLARE_VREG(BM_SYSTEM_MEM_ADDR), DECLARE_VREG(BM_COMMAND), DECLARE_VREG(BM_STATUS), DECLARE_VREG(BM_GUI_TABLE), DECLARE_VREG(BM_SYSTEM_TABLE), DECLARE_VREG(AGP_BASE), DECLARE_VREG(AGP_CNTL), DECLARE_VREG(CRTC_INT_CNTL) }; /* VIDIX exports */ /* MMIO space*/ #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ)))) #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL #define INREG8(addr) GETREG(uint8_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2) #define OUTREG8(addr,val) SETREG(uint8_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2,val) static inline uint32_t INREG (uint32_t addr) { uint32_t tmp = GETREG(uint32_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2); return le2me_32(tmp); } #define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)mach64_mmio_base,((addr)^0x100)<<2,le2me_32(val)) #define OUTREGP(addr,val,mask) \ do { \ unsigned int _tmp = INREG(addr); \ _tmp &= (mask); \ _tmp |= (val); \ OUTREG(addr, _tmp); \ } while (0) static __inline__ int ATIGetMach64LCDReg(int _Index) { OUTREG8(LCD_INDEX, _Index); return INREG(LCD_DATA); } static __inline__ uint32_t INPLL(uint32_t addr) { uint32_t res; uint32_t in; in= INREG(CLOCK_CNTL); in &= ~((PLL_WR_EN | PLL_ADDR)); //clean some stuff OUTREG(CLOCK_CNTL, in | (addr<<10)); /* read the register value */ res = (INREG(CLOCK_CNTL)>>16)&0xFF; return res; } static __inline__ void OUTPLL(uint32_t addr,uint32_t val) { //FIXME buggy but its not used /* write addr byte */ OUTREG8(CLOCK_CNTL + 1, (addr << 2) | PLL_WR_EN); /* write the register value */ OUTREG(CLOCK_CNTL + 2, val); OUTREG8(CLOCK_CNTL + 1, (addr << 2) & ~PLL_WR_EN); } #define OUTPLLP(addr,val,mask) \ do { \ unsigned int _tmp = INPLL(addr); \ _tmp &= (mask); \ _tmp |= (val); \ OUTPLL(addr, _tmp); \ } while (0) static void mach64_engine_reset( void ) { /* Kill off bus mastering with extreme predjudice... */ OUTREG(BUS_CNTL, INREG(BUS_CNTL) | BUS_MASTER_DIS); OUTREG(CRTC_INT_CNTL,INREG(CRTC_INT_CNTL)&~(CRTC_BUSMASTER_EOL_INT|CRTC_BUSMASTER_EOL_INT_EN)); /* Reset engine -- This is accomplished by setting bit 8 of the GEN_TEST_CNTL register high, then low (per the documentation, it's on high to low transition that the GUI engine gets reset...) */ OUTREG( GEN_TEST_CNTL, INREG( GEN_TEST_CNTL ) | GEN_GUI_EN ); OUTREG( GEN_TEST_CNTL, INREG( GEN_TEST_CNTL ) & ~GEN_GUI_EN ); } static void mach64_fifo_wait(unsigned n) { while ((INREG(FIFO_STAT) & 0xffff) > ((uint32_t)(0x8000 >> n))); } static void mach64_wait_for_idle( void ) { unsigned i; mach64_fifo_wait(16); for (i=0; i<2000000; i++) if((INREG(GUI_STAT) & GUI_ACTIVE) == 0) break; if((INREG(GUI_STAT) & 1) != 0) mach64_engine_reset(); /* due card lookup */ } static void mach64_wait_vsync( void ) { int i; for(i=0; i<2000000; i++) if( (INREG(CRTC_INT_CNTL)&CRTC_VBLANK)==0 ) break; for(i=0; i<2000000; i++) if( (INREG(CRTC_INT_CNTL)&CRTC_VBLANK) ) break; } static vidix_capability_t mach64_cap = { "BES driver for Mach64/3DRage cards", "Nick Kurshev and Michael Niedermayer", TYPE_OUTPUT, { 0, 0, 0, 0 }, 2048, 2048, 4, 4, -1, FLAG_UPSCALER|FLAG_DOWNSCALER, VENDOR_ATI, -1, { 0, 0, 0, 0 } }; static uint32_t mach64_vid_get_dbpp( void ) { uint32_t dbpp,retval; dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0x7; switch(dbpp) { case 1: retval = 4; break; case 2: retval = 8; break; case 3: retval = 15; break; case 4: retval = 16; break; case 5: retval = 24; break; default: retval=32; break; } return retval; } static int mach64_is_dbl_scan( void ) { return INREG(CRTC_GEN_CNTL) & CRTC_DBL_SCAN_EN; } static int mach64_is_interlace( void ) { return INREG(CRTC_GEN_CNTL) & CRTC_INTERLACE_EN; } static uint32_t mach64_get_xres( void ) { /* FIXME: currently we extract that from CRTC!!!*/ uint32_t xres,h_total; h_total = INREG(CRTC_H_TOTAL_DISP); xres = (h_total >> 16) & 0xffff; return (xres + 1)*8; } static uint32_t mach64_get_yres( void ) { /* FIXME: currently we extract that from CRTC!!!*/ uint32_t yres,v_total; v_total = INREG(CRTC_V_TOTAL_DISP); yres = (v_total >> 16) & 0xffff; return yres + 1; } // returns the verical stretch factor in 16.16 static int mach64_get_vert_stretch(void) { int lcd_index; int vert_stretching; int ext_vert_stretch; int ret; int yres= mach64_get_yres(); if(!supports_lcd_v_stretch){ if(__verbose>0) printf("[mach64] vertical stretching not supported\n"); return 1<<16; } lcd_index= INREG(LCD_INDEX); vert_stretching= ATIGetMach64LCDReg(LCD_VERT_STRETCHING); if(!(vert_stretching&VERT_STRETCH_EN)) ret= 1<<16; else { int panel_size; ext_vert_stretch= ATIGetMach64LCDReg(LCD_EXT_VERT_STRETCH); panel_size= (ext_vert_stretch&VERT_PANEL_SIZE)>>11; panel_size++; ret= ((yres<<16) + (panel_size>>1))/panel_size; } // lcd_gen_ctrl = ATIGetMach64LCDReg(LCD_GEN_CNTL); OUTREG(LCD_INDEX, lcd_index); if(__verbose>0) printf("[mach64] vertical stretching factor= %d\n", ret); return ret; } static void mach64_vid_make_default() { mach64_fifo_wait(5); OUTREG(SCALER_COLOUR_CNTL,0x00101000); besr.ckey_on=0; besr.graphics_key_msk=0; besr.graphics_key_clr=0; OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND); } static void mach64_vid_dump_regs( void ) { size_t i; printf("[mach64] *** Begin of DRIVER variables dump ***\n"); printf("[mach64] mach64_mmio_base=%p\n",mach64_mmio_base); printf("[mach64] mach64_mem_base=%p\n",mach64_mem_base); printf("[mach64] mach64_overlay_off=%08X\n",mach64_overlay_offset); printf("[mach64] mach64_ram_size=%08X\n",mach64_ram_size); printf("[mach64] video mode: %ux%u@%u\n",mach64_get_xres(),mach64_get_yres(),mach64_vid_get_dbpp()); printf("[mach64] *** Begin of OV0 registers dump ***\n"); for(i=0;i PROBE_NORMAL) { printf("[mach64] Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : ""); if(idx == -1) printf("[mach64] Assuming it as Mach64\n"); } if(idx != -1) is_agp = ati_card_ids[idx].is_agp; mach64_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info,&lst[i],sizeof(pciinfo_t)); probed=1; break; } } } if(err && verbose) printf("[mach64] Can't find chip\n"); return err; } static void reset_regs( void ) { size_t i; for(i=0;i0) printf("[mach64] version %d args='%s'\n", VIDIX_VERSION,args); if(args) if(strncmp(args,"irq=",4) == 0) { forced_irq=atoi(&args[4]); if(__verbose>0) printf("[mach64] forcing IRQ to %u\n",forced_irq); } if((mach64_mmio_base = map_phys_mem(pci_info.base2,0x4000))==(void *)-1) return ENOMEM; mach64_wait_for_idle(); mach64_ram_size = INREG(MEM_CNTL) & CTL_MEM_SIZEB; if (mach64_ram_size < 8) mach64_ram_size = (mach64_ram_size + 1) * 512; else if (mach64_ram_size < 12) mach64_ram_size = (mach64_ram_size - 3) * 1024; else mach64_ram_size = (mach64_ram_size - 7) * 2048; mach64_ram_size *= 0x400; /* KB -> bytes */ if((mach64_mem_base = map_phys_mem(pci_info.base0,mach64_ram_size))==(void *)-1) return ENOMEM; memset(&besr,0,sizeof(bes_registers_t)); printf("[mach64] Video memory = %uMb\n",mach64_ram_size/0x100000); err = mtrr_set_type(pci_info.base0,mach64_ram_size,MTRR_TYPE_WRCOMB); if(!err) printf("[mach64] Set write-combining type of video memory\n"); save_regs(); /* check if planar formats are supported */ supports_planar=0; mach64_wait_for_idle(); mach64_fifo_wait(2); if(INREG(SCALER_BUF0_OFFSET_U)) supports_planar=1; else { OUTREG(SCALER_BUF0_OFFSET_U, -1); mach64_wait_vsync(); mach64_wait_for_idle(); mach64_fifo_wait(2); if(INREG(SCALER_BUF0_OFFSET_U)) supports_planar=1; } printf("[mach64] Planar YUV formats are %s supported\n",supports_planar?"":"not"); supports_colour_adj=0; OUTREG(SCALER_COLOUR_CNTL,-1); if(INREG(SCALER_COLOUR_CNTL)) supports_colour_adj=1; supports_idct=0; OUTREG(IDCT_CONTROL,-1); if(INREG(IDCT_CONTROL)) supports_idct=1; OUTREG(IDCT_CONTROL,0); printf("[mach64] IDCT is %s supported\n",supports_idct?"":"not"); supports_subpic=0; OUTREG(SUBPIC_CNTL,-1); if(INREG(SUBPIC_CNTL)) supports_subpic=1; OUTREG(SUBPIC_CNTL,0); printf("[mach64] subpictures are %s supported\n",supports_subpic?"":"not"); if( mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_P_M2 || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_L || mach64_cap.device_id==DEVICE_ATI_RAGE_MOBILITY_L2) supports_lcd_v_stretch=1; else supports_lcd_v_stretch=0; reset_regs(); mach64_vid_make_default(); if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); #ifdef MACH64_ENABLE_BM if(!(INREG(BUS_CNTL) & BUS_MASTER_DIS)) OUTREG(BUS_CNTL,INREG(BUS_CNTL)|BUS_MSTR_RESET); if(bm_open() == 0) { mach64_cap.flags |= FLAG_DMA | FLAG_EQ_DMA; if((dma_phys_addrs = malloc(mach64_ram_size*sizeof(unsigned long)/4096)) == 0) { out_mem: printf("[mach64] Can't allocate temporary buffer for DMA\n"); mach64_cap.flags &= ~FLAG_DMA & ~FLAG_EQ_DMA; return 0; } /* WARNING: We MUST have continigous descriptors!!! But: (720*720*2(YUV422)*16(sizeof(bm_descriptor)))/4096=4050 Thus one 4K page is far enough to describe max movie size. */ for(i=0;i<64;i++) if((mach64_dma_desc_base[i] = memalign(4096,mach64_ram_size*sizeof(bm_list_descriptor)/4096)) == 0) goto out_mem; #if 0 if(!is_agp) { long tst; if(pci_config_read(pci_info.bus,pci_info.card,pci_info.func,4,4,&pci_command) == 0) pci_config_write(pci_info.bus,pci_info.card,pci_info.func,4,4,pci_command|0x14); pci_config_read(pci_info.bus,pci_info.card,pci_info.func,4,4,&tst); } #endif } else if(__verbose) printf("[mach64] Can't initialize busmastering: %s\n",strerror(errno)); #endif return 0; } void VIDIX_NAME(vixDestroy)(void) { #ifdef MACH64_ENABLE_BM unsigned i; #endif restore_regs(); #ifdef MACH64_ENABLE_BM mach64_engine_reset(); #endif unmap_phys_mem(mach64_mem_base,mach64_ram_size); unmap_phys_mem(mach64_mmio_base,0x4000); #ifdef MACH64_ENABLE_BM bm_close(); if(can_use_irq && irq_installed) hwirq_uninstall(pci_info.bus,pci_info.card,pci_info.func); if(dma_phys_addrs) free(dma_phys_addrs); for(i=0;i<64;i++) { if(mach64_dma_desc_base[i]) free(mach64_dma_desc_base[i]); } #endif } int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &mach64_cap, sizeof(vidix_capability_t)); return 0; } static unsigned mach64_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) { unsigned pitch,spy,spv,spu; spy = spv = spu = 0; switch(spitch->y) { case 16: case 32: case 64: case 128: case 256: spy = spitch->y; break; default: break; } switch(spitch->u) { case 16: case 32: case 64: case 128: case 256: spu = spitch->u; break; default: break; } switch(spitch->v) { case 16: case 32: case 64: case 128: case 256: spv = spitch->v; break; default: break; } switch(fourcc) { /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_YV12: case IMGFMT_I420: if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy; else pitch = 32; break; case IMGFMT_YVU9: if(spy > 32 && spu == spy/4 && spv == spy/4) pitch = spy; else pitch = 64; break; default: if(spy >= 16) pitch = spy; else pitch = 16; break; } return pitch; } static void mach64_compute_framesize(vidix_playback_t *info) { unsigned pitch,awidth; pitch = mach64_query_pitch(info->fourcc,&info->src.pitch); switch(info->fourcc) { case IMGFMT_I420: case IMGFMT_YV12: case IMGFMT_IYUV: awidth = (info->src.w + (pitch-1)) & ~(pitch-1); info->frame_size = awidth*(info->src.h+info->src.h/2); break; case IMGFMT_YVU9: awidth = (info->src.w + (pitch-1)) & ~(pitch-1); info->frame_size = awidth*(info->src.h+info->src.h/8); break; // case IMGFMT_RGB32: case IMGFMT_BGR32: awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1); info->frame_size = (awidth*info->src.h); break; /* YUY2 YVYU, RGB15, RGB16 */ default: awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1); info->frame_size = (awidth*info->src.h); break; } info->frame_size+=256; // so we have some space for alignment & such info->frame_size&=~16; } static void mach64_vid_stop_video( void ) { mach64_fifo_wait(14); OUTREG(OVERLAY_SCALE_CNTL, 0x80000000); OUTREG(OVERLAY_EXCLUSIVE_HORZ, 0); OUTREG(OVERLAY_EXCLUSIVE_VERT, 0); OUTREG(SCALER_H_COEFF0, 0x00002000); OUTREG(SCALER_H_COEFF1, 0x0D06200D); OUTREG(SCALER_H_COEFF2, 0x0D0A1C0D); OUTREG(SCALER_H_COEFF3, 0x0C0E1A0C); OUTREG(SCALER_H_COEFF4, 0x0C14140C); OUTREG(VIDEO_FORMAT, 0xB000B); OUTREG(OVERLAY_TEST, 0x0); } static void mach64_vid_display_video( void ) { uint32_t vf,sc,width; mach64_fifo_wait(14); OUTREG(OVERLAY_Y_X_START, besr.y_x_start); OUTREG(OVERLAY_Y_X_END, besr.y_x_end); OUTREG(OVERLAY_SCALE_INC, besr.scale_inc); OUTREG(SCALER_BUF_PITCH, besr.vid_buf_pitch); OUTREG(SCALER_HEIGHT_WIDTH, besr.height_width); OUTREG(SCALER_BUF0_OFFSET, mach64_buffer_base[0][0]); OUTREG(SCALER_BUF0_OFFSET_U, mach64_buffer_base[0][1]); OUTREG(SCALER_BUF0_OFFSET_V, mach64_buffer_base[0][2]); OUTREG(SCALER_BUF1_OFFSET, mach64_buffer_base[0][0]); OUTREG(SCALER_BUF1_OFFSET_U, mach64_buffer_base[0][1]); OUTREG(SCALER_BUF1_OFFSET_V, mach64_buffer_base[0][2]); mach64_wait_vsync(); width = (besr.height_width >> 16 & 0x03FF); sc = SCALE_EN | OVERLAY_EN | SCALE_BANDWIDTH | /* reset bandwidth status */ SCALE_PIX_EXPAND | /* dynamic range correct */ SCALE_Y2R_TEMP; /* use the equal temparature for every component of RGB */ /* Force clocks of scaler. */ if(width > 360 && !supports_planar && !mach64_is_interlace()) sc |= SCALE_CLK_FORCE_ON; /* Do we need that? And how we can improve the quality of 3dRageII scaler ? 3dRageII+ (non pro) is really crapped HW :( ^^^^^^^^^^^^^^^^^^^ !!SCALER_WIDTH <= 360 provides full scaling functionality !!!!!!!!!!!!! !!360 < SCALER_WIDTH <= 720 provides scaling with vertical replication (crap) !!SCALER_WIDTH > 720 is illegal. (no comments) As for me - I would prefer to limit movie's width with 360 but it provides only half of picture but with perfect quality. (NK) */ mach64_fifo_wait(10); OUTREG(OVERLAY_SCALE_CNTL, sc); mach64_wait_for_idle(); switch(besr.fourcc) { /* BGR formats */ case IMGFMT_BGR15: vf = SCALER_IN_RGB15; break; case IMGFMT_BGR16: vf = SCALER_IN_RGB16; break; case IMGFMT_BGR32: vf = SCALER_IN_RGB32; break; /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_I420: case IMGFMT_YV12: vf = SCALER_IN_YUV12; break; /* 4:1:0 */ case IMGFMT_YVU9: vf = SCALER_IN_YUV9; break; /* 4:2:2 */ case IMGFMT_YVYU: case IMGFMT_UYVY: vf = SCALER_IN_YVYU422; break; case IMGFMT_YUY2: default: vf = SCALER_IN_VYUY422; break; } OUTREG(VIDEO_FORMAT,vf); if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); } /* Goal of this function: hide RGB background and provide black screen around movie. Useful in '-vo fbdev:vidix -fs -zoom' mode. Reverse effect to colorkey */ static void mach64_vid_exclusive( void ) { unsigned screenw,screenh; screenw = mach64_get_xres(); screenh = mach64_get_yres(); OUTREG(OVERLAY_EXCLUSIVE_VERT,(((screenh-1)<<16)&EXCLUSIVE_VERT_END)); OUTREG(OVERLAY_EXCLUSIVE_HORZ,(((screenw/8+1)<<8)&EXCLUSIVE_HORZ_END)|EXCLUSIVE_EN); } static void mach64_vid_non_exclusive( void ) { OUTREG(OVERLAY_EXCLUSIVE_HORZ,0); } static int mach64_vid_init_video( vidix_playback_t *config ) { uint32_t src_w,src_h,dest_w,dest_h,pitch,h_inc,v_inc,left,leftUV,top,ecp,y_pos; int is_420,best_pitch,mpitch; int src_offset_y, src_offset_u, src_offset_v; unsigned int i; mach64_vid_stop_video(); /* warning, if left or top are != 0 this will fail, as the framesize is too small then */ left = config->src.x; top = config->src.y; src_h = config->src.h; src_w = config->src.w; is_420 = 0; if(config->fourcc == IMGFMT_YV12 || config->fourcc == IMGFMT_I420 || config->fourcc == IMGFMT_IYUV) is_420 = 1; best_pitch = mach64_query_pitch(config->fourcc,&config->src.pitch); mpitch = best_pitch-1; switch(config->fourcc) { case IMGFMT_YVU9: /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_YV12: case IMGFMT_I420: pitch = (src_w + mpitch) & ~mpitch; config->dest.pitch.y = config->dest.pitch.u = config->dest.pitch.v = best_pitch; besr.vid_buf_pitch= pitch; break; /* RGB 4:4:4:4 */ case IMGFMT_RGB32: case IMGFMT_BGR32: pitch = (src_w*4 + mpitch) & ~mpitch; config->dest.pitch.y = config->dest.pitch.u = config->dest.pitch.v = best_pitch; besr.vid_buf_pitch= pitch>>2; break; /* 4:2:2 */ default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */ pitch = ((src_w*2) + mpitch) & ~mpitch; config->dest.pitch.y = config->dest.pitch.u = config->dest.pitch.v = best_pitch; besr.vid_buf_pitch= pitch>>1; break; } dest_w = config->dest.w; dest_h = config->dest.h; besr.fourcc = config->fourcc; ecp = (INPLL(PLL_VCLK_CNTL) & PLL_ECP_DIV) >> 4; #if 0 { int i; for(i=0; i<32; i++){ printf("%X ", INPLL(i)); } } #endif if(__verbose>0) printf("[mach64] ecp: %d\n", ecp); v_inc = src_h * mach64_get_vert_stretch(); if(mach64_is_interlace()) v_inc<<=1; if(mach64_is_dbl_scan() ) v_inc>>=1; v_inc/= dest_h; v_inc>>=4; // convert 16.16 -> 4.12 h_inc = (src_w << (12+ecp)) / dest_w; /* keep everything in 4.12 */ config->offsets[0] = 0; for(i=1; inum_frames; i++) config->offsets[i] = config->offsets[i-1] + config->frame_size; /*FIXME the left / top stuff is broken (= zoom a src rectangle from a larger one) 1. the framesize isnt known as the outer src rectangle dimensions arent known 2. the mach64 needs aligned addresses so it cant work anyway -> so we could shift the outer buffer to compensate that but that would mean alignment problems for the code which writes into it */ if(is_420) { config->offset.y= 0; config->offset.u= (pitch*src_h + 15)&~15; config->offset.v= (config->offset.u + (pitch*src_h>>2) + 15)&~15; src_offset_y= config->offset.y + top*pitch + left; src_offset_u= config->offset.u + (top*pitch>>2) + (left>>1); src_offset_v= config->offset.v + (top*pitch>>2) + (left>>1); if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) { uint32_t tmp; tmp = config->offset.u; config->offset.u = config->offset.v; config->offset.v = tmp; src_offset_u=config->offset.u; src_offset_v=config->offset.v; } } else if(besr.fourcc == IMGFMT_YVU9) { config->offset.y= 0; config->offset.u= (pitch*src_h + 15)&~15; config->offset.v= (config->offset.u + (pitch*src_h>>4) + 15)&~15; src_offset_y= config->offset.y + top*pitch + left; src_offset_u= config->offset.u + (top*pitch>>4) + (left>>1); src_offset_v= config->offset.v + (top*pitch>>4) + (left>>1); } else if(besr.fourcc == IMGFMT_BGR32) { config->offset.y = config->offset.u = config->offset.v = 0; src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 2); } else { config->offset.y = config->offset.u = config->offset.v = 0; src_offset_y= src_offset_u= src_offset_v= top*pitch + (left << 1); } num_mach64_buffers= config->num_frames; for(i=0; inum_frames; i++) { mach64_buffer_base[i][0]= (mach64_overlay_offset + config->offsets[i] + src_offset_y)&~15; mach64_buffer_base[i][1]= (mach64_overlay_offset + config->offsets[i] + src_offset_u)&~15; mach64_buffer_base[i][2]= (mach64_overlay_offset + config->offsets[i] + src_offset_v)&~15; } leftUV = (left >> 17) & 15; left = (left >> 16) & 15; besr.scale_inc = ( h_inc << 16 ) | v_inc; y_pos = config->dest.y; if(mach64_is_dbl_scan()) y_pos*=2; else if(mach64_is_interlace()) y_pos/=2; besr.y_x_start = y_pos | (config->dest.x << 16); y_pos =config->dest.y + dest_h; if(mach64_is_dbl_scan()) y_pos*=2; else if(mach64_is_interlace()) y_pos/=2; besr.y_x_end = y_pos | ((config->dest.x + dest_w) << 16); besr.height_width = ((src_w - left)<<16) | (src_h - top); return 0; } static int is_supported_fourcc(uint32_t fourcc) { switch(fourcc) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_YVU9: case IMGFMT_IYUV: return supports_planar; case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_BGR15: case IMGFMT_BGR16: case IMGFMT_BGR32: return 1; default: return 0; } } int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { if(is_supported_fourcc(to->fourcc)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { unsigned rgb_size,nfr; uint32_t mach64_video_size; if(!is_supported_fourcc(info->fourcc)) return ENOSYS; if(info->src.h > 720 || info->src.w > 720) { printf("[mach64] Can't apply width or height > 720\n"); return EINVAL; } if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES; mach64_compute_framesize(info); rgb_size = mach64_get_xres()*mach64_get_yres()*((mach64_vid_get_dbpp()+7)/8); nfr = info->num_frames; mach64_video_size = mach64_ram_size; for(;nfr>0;nfr--) { mach64_overlay_offset = mach64_video_size - info->frame_size*nfr; mach64_overlay_offset &= 0xffff0000; if(mach64_overlay_offset >= (int)rgb_size ) break; } if(nfr <= 3) { nfr = info->num_frames; for(;nfr>0;nfr--) { mach64_overlay_offset = mach64_video_size - info->frame_size*nfr; mach64_overlay_offset &= 0xffff0000; if(mach64_overlay_offset>=0) break; } } if(nfr <= 0) return EINVAL; info->num_frames=nfr; num_mach64_buffers = info->num_frames; info->dga_addr = (char *)mach64_mem_base + mach64_overlay_offset; mach64_vid_init_video(info); return 0; } int VIDIX_NAME(vixPlaybackOn)(void) { int err; unsigned dw,dh; dw = (besr.y_x_end >> 16) - (besr.y_x_start >> 16); dh = (besr.y_x_end & 0xFFFF) - (besr.y_x_start & 0xFFFF); if(dw == mach64_get_xres() || dh == mach64_get_yres()) mach64_vid_exclusive(); else mach64_vid_non_exclusive(); mach64_vid_display_video(); err = INREG(SCALER_BUF_PITCH) == besr.vid_buf_pitch ? 0 : EINTR; if(err) { printf("[mach64] *** Internal fatal error ***: Detected pitch corruption\n" "[mach64] Try decrease number of buffers\n"); } return err; } int VIDIX_NAME(vixPlaybackOff)(void) { mach64_vid_stop_video(); return 0; } int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { uint32_t off[6]; int i; int last_frame= (frame-1+num_mach64_buffers) % num_mach64_buffers; /* buf3-5 always should point onto second buffer for better deinterlacing and TV-in */ if(num_mach64_buffers==1) return 0; for(i=0; i<3; i++) { off[i] = mach64_buffer_base[frame][i]; off[i+3]= mach64_buffer_base[last_frame][i]; } if(__verbose > VERBOSE_LEVEL) printf("mach64_vid: flip_page = %u\n",frame); #if 0 // delay routine so the individual frames can be ssen better { volatile int i=0; for(i=0; i<10000000; i++); } #endif mach64_wait_for_idle(); mach64_fifo_wait(7); OUTREG(SCALER_BUF0_OFFSET, off[0]); OUTREG(SCALER_BUF0_OFFSET_U, off[1]); OUTREG(SCALER_BUF0_OFFSET_V, off[2]); OUTREG(SCALER_BUF1_OFFSET, off[3]); OUTREG(SCALER_BUF1_OFFSET_U, off[4]); OUTREG(SCALER_BUF1_OFFSET_V, off[5]); if(num_mach64_buffers==2) mach64_wait_vsync(); //only wait for vsync if we do double buffering if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); return 0; } vidix_video_eq_t equal = { VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION , 0, 0, 0, 0, 0, 0, 0, 0 }; int VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq) { memcpy(eq,&equal,sizeof(vidix_video_eq_t)); if(!supports_colour_adj) eq->cap = VEQ_CAP_BRIGHTNESS; return 0; } int VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq) { int br,sat; if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness; if(eq->cap & VEQ_CAP_CONTRAST) equal.contrast = eq->contrast; if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation; if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue; if(eq->cap & VEQ_CAP_RGB_INTENSITY) { equal.red_intensity = eq->red_intensity; equal.green_intensity = eq->green_intensity; equal.blue_intensity = eq->blue_intensity; } if(supports_colour_adj) { equal.flags = eq->flags; br = equal.brightness * 64 / 1000; if(br < -64) br = -64; if(br > 63) br = 63; sat = (equal.saturation + 1000) * 16 / 1000; if(sat < 0) sat = 0; if(sat > 31) sat = 31; OUTREG(SCALER_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16)); } else { unsigned gamma; br = equal.brightness * 3 / 1000; if(br < 0) br = 0; switch(br) { default:gamma = SCALE_GAMMA_SEL_BRIGHT; break; case 1: gamma = SCALE_GAMMA_SEL_G14; break; case 2: gamma = SCALE_GAMMA_SEL_G18; break; case 3: gamma = SCALE_GAMMA_SEL_G22; break; } OUTREG(OVERLAY_SCALE_CNTL,(INREG(OVERLAY_SCALE_CNTL) & ~SCALE_GAMMA_SEL_MSK) | gamma); } return 0; } int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *grkey) { memcpy(grkey, &mach64_grkey, sizeof(vidix_grkey_t)); return(0); } int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *grkey) { memcpy(&mach64_grkey, grkey, sizeof(vidix_grkey_t)); if(mach64_grkey.ckey.op == CKEY_TRUE) { besr.ckey_on=1; switch(mach64_vid_get_dbpp()) { case 15: besr.graphics_key_msk=0x7FFF; besr.graphics_key_clr= ((mach64_grkey.ckey.blue &0xF8)>>3) | ((mach64_grkey.ckey.green&0xF8)<<2) | ((mach64_grkey.ckey.red &0xF8)<<7); break; case 16: besr.graphics_key_msk=0xFFFF; besr.graphics_key_clr= ((mach64_grkey.ckey.blue &0xF8)>>3) | ((mach64_grkey.ckey.green&0xFC)<<3) | ((mach64_grkey.ckey.red &0xF8)<<8); break; case 24: besr.graphics_key_msk=0xFFFFFF; besr.graphics_key_clr= ((mach64_grkey.ckey.blue &0xFF)) | ((mach64_grkey.ckey.green&0xFF)<<8) | ((mach64_grkey.ckey.red &0xFF)<<16); break; case 32: besr.graphics_key_msk=0xFFFFFF; besr.graphics_key_clr= ((mach64_grkey.ckey.blue &0xFF)) | ((mach64_grkey.ckey.green&0xFF)<<8) | ((mach64_grkey.ckey.red &0xFF)<<16); break; default: besr.ckey_on=0; besr.graphics_key_msk=0; besr.graphics_key_clr=0; } } else { besr.ckey_on=0; besr.graphics_key_msk=0; besr.graphics_key_clr=0; } mach64_fifo_wait(4); OUTREG(OVERLAY_GRAPHICS_KEY_MSK, besr.graphics_key_msk); OUTREG(OVERLAY_GRAPHICS_KEY_CLR, besr.graphics_key_clr); // OUTREG(OVERLAY_VIDEO_KEY_MSK, 0); // OUTREG(OVERLAY_VIDEO_KEY_CLR, 0); if(besr.ckey_on) OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_EQ|CMP_MIX_AND); else OUTREG(OVERLAY_KEY_CNTL,VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND); return(0); } #ifdef MACH64_ENABLE_BM static int mach64_setup_frame( vidix_dma_t * dmai ) { if(mach64_overlay_offset + dmai->dest_offset + dmai->size > mach64_ram_size) return E2BIG; if(dmai->idx > VID_PLAY_MAXFRAMES-1) dmai->idx=0; if(!(dmai->internal[dmai->idx] && (dmai->flags & BM_DMA_FIXED_BUFFS))) { bm_list_descriptor * list = (bm_list_descriptor *)mach64_dma_desc_base[dmai->idx]; unsigned long dest_ptr; unsigned i,n,count; int retval; n = dmai->size / 4096; if(dmai->size % 4096) n++; if((retval = VIRT_TO_CARD(dmai->src,dmai->size,dma_phys_addrs)) != 0) return retval; dmai->internal[dmai->idx] = mach64_dma_desc_base[dmai->idx]; dest_ptr = dmai->dest_offset; count = dmai->size; #if 0 printf("MACH64_DMA_REQUEST va=%X size=%X\n",dmai->src,dmai->size); #endif for(i=0;i 4096 ? 4096 : (count | DMA_GUI_COMMAND__EOL)); list[i].reserved = 0; #if 0 printf("MACH64_DMA_TABLE[%i] fboff=%X pa=%X cmd=%X rsrvd=%X\n",i,list[i].framebuf_offset,list[i].sys_addr,list[i].command,list[i].reserved); #endif dest_ptr += 4096; count -= 4096; } cpu_flush(list,4096); } return 0; } static int mach64_transfer_frame( unsigned long ba_dma_desc,int sync_mode ) { uint32_t crtc_int; mach64_wait_for_idle(); mach64_fifo_wait(4); OUTREG(BUS_CNTL,(INREG(BUS_CNTL)|BUS_EXT_REG_EN)&(~BUS_MASTER_DIS)); crtc_int = INREG(CRTC_INT_CNTL); if(sync_mode && can_use_irq) OUTREG(CRTC_INT_CNTL,crtc_int|CRTC_BUSMASTER_EOL_INT|CRTC_BUSMASTER_EOL_INT_EN); else OUTREG(CRTC_INT_CNTL,crtc_int|CRTC_BUSMASTER_EOL_INT); OUTREG(BM_SYSTEM_TABLE,ba_dma_desc|SYSTEM_TRIGGER_SYSTEM_TO_VIDEO); if(__verbose > VERBOSE_LEVEL) mach64_vid_dump_regs(); #if 0 mach64_fifo_wait(4); mach64_fifo_wait(16); printf("MACH64_DMA_DBG: bm_fb_off=%08X bm_sysmem_addr=%08X bm_cmd=%08X bm_status=%08X bm_agp_base=%08X bm_agp_cntl=%08X\n", INREG(BM_FRAME_BUF_OFFSET), INREG(BM_SYSTEM_MEM_ADDR), INREG(BM_COMMAND), INREG(BM_STATUS), INREG(AGP_BASE), INREG(AGP_CNTL)); #endif return 0; } int VIDIX_NAME(vixQueryDMAStatus)( void ) { int bm_off; unsigned crtc_int_cntl; mach64_wait_for_idle(); mach64_fifo_wait(2); crtc_int_cntl = INREG(CRTC_INT_CNTL); bm_off = crtc_int_cntl & CRTC_BUSMASTER_EOL_INT; // if(bm_off) OUTREG(CRTC_INT_CNTL,crtc_int_cntl | CRTC_BUSMASTER_EOL_INT); return bm_off?0:1; } int VIDIX_NAME(vixPlaybackCopyFrame)( vidix_dma_t * dmai ) { int retval,sync_mode; if(!(dmai->flags & BM_DMA_FIXED_BUFFS)) if(bm_lock_mem(dmai->src,dmai->size) != 0) return errno; sync_mode = (dmai->flags & BM_DMA_SYNC) == BM_DMA_SYNC; if(sync_mode) { if(!irq_installed) init_irq(); /* burn CPU instead of PCI bus here */ while(vixQueryDMAStatus()!=0){ if(can_use_irq) hwirq_wait(pci_info.irq); else sched_yield (); /* usleep(0); */ /* ugly but may help */ } } mach64_engine_reset(); retval = mach64_setup_frame(dmai); VIRT_TO_CARD(mach64_dma_desc_base[dmai->idx],1,&bus_addr_dma_desc); if(retval == 0) retval = mach64_transfer_frame(bus_addr_dma_desc,sync_mode); if(!(dmai->flags & BM_DMA_FIXED_BUFFS)) bm_unlock_mem(dmai->src,dmai->size); return retval; } #endif xine-lib-1.2/contrib/vidix/drivers/radeon.h0000644000175000017500000022733214647725152016557 0ustar meme/* * radeon.h * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. * * This collection of definition was written by Nick Kurshev * It's based on radeonfb, X11, GATOS sources * and partly compatible with Rage128 set (in OV0, CAP0, CAP1 parts) */ #ifndef _RADEON_H #define _RADEON_H #define RADEON_REGSIZE 0x4000 #define MM_INDEX 0x0000 /* MM_INDEX bit constants */ # define MM_APER 0x80000000 #define MM_DATA 0x0004 #define BUS_CNTL 0x0030 /* BUS_CNTL bit constants */ # define BUS_DBL_RESYNC 0x00000001 # define BUS_MSTR_RESET 0x00000002 # define BUS_FLUSH_BUF 0x00000004 # define BUS_STOP_REQ_DIS 0x00000008 # define BUS_ROTATION_DIS 0x00000010 # define BUS_MASTER_DIS 0x00000040 # define BUS_ROM_WRT_EN 0x00000080 # define BUS_DIS_ROM 0x00001000 # define BUS_PCI_READ_RETRY_EN 0x00002000 # define BUS_AGP_AD_STEPPING_EN 0x00004000 # define BUS_PCI_WRT_RETRY_EN 0x00008000 # define BUS_MSTR_RD_MULT 0x00100000 # define BUS_MSTR_RD_LINE 0x00200000 # define BUS_SUSPEND 0x00400000 # define LAT_16X 0x00800000 # define BUS_RD_DISCARD_EN 0x01000000 # define BUS_RD_ABORT_EN 0x02000000 # define BUS_MSTR_WS 0x04000000 # define BUS_PARKING_DIS 0x08000000 # define BUS_MSTR_DISCONNECT_EN 0x10000000 # define BUS_WRT_BURST 0x20000000 # define BUS_READ_BURST 0x40000000 # define BUS_RDY_READ_DLY 0x80000000 #define HI_STAT 0x004C #define BUS_CNTL1 0x0034 # define BUS_WAIT_ON_LOCK_EN (1 << 4) #define I2C_CNTL_0 0x0090 # define I2C_DONE (1<<0) # define I2C_NACK (1<<1) # define I2C_HALT (1<<2) # define I2C_SOFT_RST (1<<5) # define I2C_DRIVE_EN (1<<6) # define I2C_DRIVE_SEL (1<<7) # define I2C_START (1<<8) # define I2C_STOP (1<<9) # define I2C_RECEIVE (1<<10) # define I2C_ABORT (1<<11) # define I2C_GO (1<<12) # define I2C_SEL (1<<16) # define I2C_EN (1<<17) #define I2C_CNTL_1 0x0094 #define I2C_DATA 0x0098 #define CONFIG_CNTL 0x00E0 /* CONFIG_CNTL bit constants */ # define CFG_VGA_RAM_EN 0x00000100 #ifdef RAGE128 #define GEN_RESET_CNTL 0x00f0 # define SOFT_RESET_GUI 0x00000001 # define SOFT_RESET_VCLK 0x00000100 # define SOFT_RESET_PCLK 0x00000200 # define SOFT_RESET_ECP 0x00000400 # define SOFT_RESET_DISPENG_XCLK 0x00000800 # define SOFT_RESET_MEMCTLR_XCLK 0x00001000 #endif #define CONFIG_MEMSIZE 0x00F8 #define CONFIG_APER_0_BASE 0x0100 #define CONFIG_APER_1_BASE 0x0104 #define CONFIG_APER_SIZE 0x0108 #define CONFIG_REG_1_BASE 0x010C #define CONFIG_REG_APER_SIZE 0x0110 #define PAD_AGPINPUT_DELAY 0x0164 #define PAD_CTLR_STRENGTH 0x0168 #define PAD_CTLR_UPDATE 0x016C #define AGP_CNTL 0x0174 # define AGP_APER_SIZE_256MB (0x00 << 0) # define AGP_APER_SIZE_128MB (0x20 << 0) # define AGP_APER_SIZE_64MB (0x30 << 0) # define AGP_APER_SIZE_32MB (0x38 << 0) # define AGP_APER_SIZE_16MB (0x3c << 0) # define AGP_APER_SIZE_8MB (0x3e << 0) # define AGP_APER_SIZE_4MB (0x3f << 0) # define AGP_APER_SIZE_MASK (0x3f << 0) #define AMCGPIO_A_REG 0x01a0 #define AMCGPIO_EN_REG 0x01a8 #define AMCGPIO_MASK 0x0194 #define AMCGPIO_Y_REG 0x01a4 /*#define BM_STATUS 0x0160*/ #define MPP_TB_CONFIG 0x01c0 /* ? */ #define MPP_GP_CONFIG 0x01c8 /* ? */ #define VENDOR_ID 0x0F00 #define DEVICE_ID 0x0F02 #define COMMAND 0x0F04 #define STATUS 0x0F06 #define REVISION_ID 0x0F08 #define REGPROG_INF 0x0F09 #define SUB_CLASS 0x0F0A #define CACHE_LINE 0x0F0C #define LATENCY 0x0F0D #define HEADER 0x0F0E #define BIST 0x0F0F #define REG_MEM_BASE 0x0F10 #define REG_IO_BASE 0x0F14 #define REG_REG_BASE 0x0F18 #define ADAPTER_ID 0x0F2C #define BIOS_ROM 0x0F30 #define CAPABILITIES_PTR 0x0F34 #define INTERRUPT_LINE 0x0F3C #define INTERRUPT_PIN 0x0F3D #define MIN_GRANT 0x0F3E #define MAX_LATENCY 0x0F3F #define ADAPTER_ID_W 0x0F4C #define PMI_CAP_ID 0x0F50 #define PMI_NXT_CAP_PTR 0x0F51 #define PMI_PMC_REG 0x0F52 #define PM_STATUS 0x0F54 #define PMI_DATA 0x0F57 #define AGP_CAP_ID 0x0F58 #define AGP_STATUS 0x0F5C # define AGP_1X_MODE 0x01 # define AGP_2X_MODE 0x02 # define AGP_4X_MODE 0x04 # define AGP_MODE_MASK 0x07 #define AGP_COMMAND 0x0F60 /* Video muxer unit */ #define VIDEOMUX_CNTL 0x0190 #define VIPPAD_MASK 0x0198 #define VIPPAD1_A 0x01AC #define VIPPAD1_EN 0x01B0 #define VIPPAD1_Y 0x01B4 #define AIC_CTRL 0x01D0 #define AIC_STAT 0x01D4 #define AIC_PT_BASE 0x01D8 #define AIC_LO_ADDR 0x01DC #define AIC_HI_ADDR 0x01E0 #define AIC_TLB_ADDR 0x01E4 #define AIC_TLB_DATA 0x01E8 #define DAC_CNTL 0x0058 /* DAC_CNTL bit constants */ # define DAC_RANGE_CNTL_MSK 0x00000003 # define DAC_RANGE_PAL 0x00000000 # define DAC_RANGE_NTSC 0x00000001 # define DAC_RANGE_PS2 0x00000002 # define DAC_BLANKING 0x00000004 # define DAC_CMP_EN 0x00000008 # define DAC_CMP_OUTPUT 0x00000080 # define DAC_8BIT_EN 0x00000100 # define DAC_4BPP_PIX_ORDER 0x00000200 # define DAC_TVO_EN 0x00000400 # define DAC_TVO_OVR_EXCL 0x00000800 # define DAC_TVO_16BPP_DITH_EN 0x00001000 # define DAC_VGA_ADR_EN (1 << 13) # define DAC_PWDN (1 << 15) # define DAC_CRC_EN 0x00080000 # define DAC_MASK_ALL (0xff << 24) # define DAC_RANGE_CNTL (3 << 0) #define DAC_CNTL2 0x007c /* DAC_CNTL2 bit constants */ # define DAC2_DAC_CLK_SEL (1 << 0) # define DAC2_DAC2_CLK_SEL (1 << 1) # define DAC2_PALETTE_ACC_CTL (1 << 5) #define TV_DAC_CNTL 0x088c /* TV_DAC_CNTL bit constants */ # define TV_DAC_STD_MASK 0x0300 # define TV_DAC_RDACPD (1 << 24) # define TV_DAC_GDACPD (1 << 25) # define TV_DAC_BDACPD (1 << 26) #define CRTC_GEN_CNTL 0x0050 /* CRTC_GEN_CNTL bit constants */ # define CRTC_DBL_SCAN_EN 0x00000001 # define CRTC_INTERLACE_EN (1 << 1) # define CRTC_CSYNC_EN (1 << 4) # define CRTC_CUR_EN 0x00010000 # define CRTC_CUR_MODE_MASK (7 << 17) # define CRTC_ICON_EN (1 << 20) # define CRTC_EXT_DISP_EN (1 << 24) # define CRTC_EN (1 << 25) # define CRTC_DISP_REQ_EN_B (1 << 26) #define CRTC2_GEN_CNTL 0x03f8 /* CRTC2_GEN_CNTL bit constants */ # define CRTC2_DBL_SCAN_EN (1 << 0) # define CRTC2_INTERLACE_EN (1 << 1) # define CRTC2_SYNC_TRISTAT (1 << 4) # define CRTC2_HSYNC_TRISTAT (1 << 5) # define CRTC2_VSYNC_TRISTAT (1 << 6) # define CRTC2_CRT2_ON (1 << 7) # define CRTC2_ICON_EN (1 << 15) # define CRTC2_CUR_EN (1 << 16) # define CRTC2_CUR_MODE_MASK (7 << 20) # define CRTC2_DISP_DIS (1 << 23) # define CRTC2_EN (1 << 25) # define CRTC2_DISP_REQ_EN_B (1 << 26) # define CRTC2_HSYNC_DIS (1 << 28) # define CRTC2_VSYNC_DIS (1 << 29) #define MEM_CNTL 0x0140 /* MEM_CNTL bit constants */ # define MEM_CTLR_STATUS_IDLE 0x00000000 # define MEM_CTLR_STATUS_BUSY 0x00100000 # define MEM_SEQNCR_STATUS_IDLE 0x00000000 # define MEM_SEQNCR_STATUS_BUSY 0x00200000 # define MEM_ARBITER_STATUS_IDLE 0x00000000 # define MEM_ARBITER_STATUS_BUSY 0x00400000 # define MEM_REQ_UNLOCK 0x00000000 # define MEM_REQ_LOCK 0x00800000 #define EXT_MEM_CNTL 0x0144 #define MC_AGP_LOCATION 0x014C #define MEM_IO_CNTL_A0 0x0178 #define MEM_INIT_LATENCY_TIMER 0x0154 #define MEM_SDRAM_MODE_REG 0x0158 #define AGP_BASE 0x0170 #ifdef RAGE128 #define PCI_GART_PAGE 0x017c #define PC_NGUI_MODE 0x0180 #define PC_NGUI_CTLSTAT 0x0184 # define PC_FLUSH_GUI (3 << 0) # define PC_RI_GUI (1 << 2) # define PC_FLUSH_ALL 0x00ff # define PC_BUSY (1 << 31) #define PC_MISC_CNTL 0x0188 #else #define MEM_IO_CNTL_A1 0x017C #define MEM_IO_CNTL_B0 0x0180 #define MEM_IO_CNTL_B1 0x0184 #define MC_DEBUG 0x0188 #endif #define MC_STATUS 0x0150 #define MEM_IO_OE_CNTL 0x018C #define MC_FB_LOCATION 0x0148 #define HOST_PATH_CNTL 0x0130 #define MEM_VGA_WP_SEL 0x0038 #define MEM_VGA_RP_SEL 0x003C #define HDP_DEBUG 0x0138 #define SW_SEMAPHORE 0x013C #define SURFACE_CNTL 0x0B00 /* SURFACE_CNTL bit constants */ # define SURF_TRANSLATION_DIS (1 << 8) # define NONSURF_AP0_SWP_16BPP (1 << 20) # define NONSURF_AP0_SWP_32BPP (2 << 20) #define SURFACE0_LOWER_BOUND 0x0B04 #define SURFACE1_LOWER_BOUND 0x0B14 #define SURFACE2_LOWER_BOUND 0x0B24 #define SURFACE3_LOWER_BOUND 0x0B34 #define SURFACE4_LOWER_BOUND 0x0B44 #define SURFACE5_LOWER_BOUND 0x0B54 #define SURFACE6_LOWER_BOUND 0x0B64 #define SURFACE7_LOWER_BOUND 0x0B74 #define SURFACE0_UPPER_BOUND 0x0B08 #define SURFACE1_UPPER_BOUND 0x0B18 #define SURFACE2_UPPER_BOUND 0x0B28 #define SURFACE3_UPPER_BOUND 0x0B38 #define SURFACE4_UPPER_BOUND 0x0B48 #define SURFACE5_UPPER_BOUND 0x0B58 #define SURFACE6_UPPER_BOUND 0x0B68 #define SURFACE7_UPPER_BOUND 0x0B78 #define SURFACE0_INFO 0x0B0C #define SURFACE1_INFO 0x0B1C #define SURFACE2_INFO 0x0B2C #define SURFACE3_INFO 0x0B3C #define SURFACE4_INFO 0x0B4C #define SURFACE5_INFO 0x0B5C #define SURFACE6_INFO 0x0B6C #define SURFACE7_INFO 0x0B7C #define SURFACE_ACCESS_FLAGS 0x0BF8 #define SURFACE_ACCESS_CLR 0x0BFC #define GEN_INT_CNTL 0x0040 #define GEN_INT_STATUS 0x0044 # define VSYNC_INT_AK (1 << 2) # define VSYNC_INT (1 << 2) #define CRTC_EXT_CNTL 0x0054 /* CRTC_EXT_CNTL bit constants */ # define CRTC_VGA_XOVERSCAN (1 << 0) # define VGA_ATI_LINEAR 0x00000008 # define VGA_128KAP_PAGING 0x00000010 # define XCRT_CNT_EN (1 << 6) # define CRTC_HSYNC_DIS (1 << 8) # define CRTC_VSYNC_DIS (1 << 9) # define CRTC_DISPLAY_DIS (1 << 10) # define CRTC_SYNC_TRISTAT (1 << 11) # define CRTC_CRT_ON (1 << 15) #define CRTC_EXT_CNTL_DPMS_BYTE 0x0055 # define CRTC_HSYNC_DIS_BYTE (1 << 0) # define CRTC_VSYNC_DIS_BYTE (1 << 1) # define CRTC_DISPLAY_DIS_BYTE (1 << 2) #define RB3D_CNTL 0x1C3C #define WAIT_UNTIL 0x1720 # define EVENT_CRTC_OFFSET 0x00000001 # define EVENT_RE_CRTC_VLINE 0x00000002 # define EVENT_FE_CRTC_VLINE 0x00000004 # define EVENT_CRTC_VLINE 0x00000008 # define EVENT_BM_VIP0_IDLE 0x00000010 # define EVENT_BM_VIP1_IDLE 0x00000020 # define EVENT_BM_VIP2_IDLE 0x00000040 # define EVENT_BM_VIP3_IDLE 0x00000080 # define EVENT_BM_VIDCAP_IDLE 0x00000100 # define EVENT_BM_GUI_IDLE 0x00000200 # define EVENT_CMDFIFO 0x00000400 # define EVENT_OV0_FLIP 0x00000800 # define EVENT_CMDFIFO_ENTRIES 0x07F00000 #define ISYNC_CNTL 0x1724 #define RBBM_GUICNTL 0x172C #define RBBM_STATUS 0x0E40 # define RBBM_FIFOCNT_MASK 0x007f # define RBBM_ACTIVE (1 << 31) #define RBBM_STATUS_alt_1 0x1740 #define RBBM_CNTL 0x00EC #define RBBM_CNTL_alt_1 0x0E44 #define RBBM_SOFT_RESET 0x00F0 /* RBBM_SOFT_RESET bit constants */ # define SOFT_RESET_CP (1 << 0) # define SOFT_RESET_HI (1 << 1) # define SOFT_RESET_SE (1 << 2) # define SOFT_RESET_RE (1 << 3) # define SOFT_RESET_PP (1 << 4) # define SOFT_RESET_E2 (1 << 5) # define SOFT_RESET_RB (1 << 6) # define SOFT_RESET_HDP (1 << 7) #define RBBM_SOFT_RESET_alt_1 0x0E48 #define NQWAIT_UNTIL 0x0E50 #define RBBM_DEBUG 0x0E6C #define RBBM_CMDFIFO_ADDR 0x0E70 #define RBBM_CMDFIFO_DATAL 0x0E74 #define RBBM_CMDFIFO_DATAH 0x0E78 #define RBBM_CMDFIFO_STAT 0x0E7C #define CRTC_STATUS 0x005C /* CRTC_STATUS bit constants */ # define CRTC_VBLANK 0x00000001 # define CRTC_VBLANK_SAVE ( 1 << 1) #define GPIO_VGA_DDC 0x0060 #define GPIO_DVI_DDC 0x0064 #define GPIO_MONID 0x0068 #define PALETTE_INDEX 0x00B0 #define PALETTE_DATA 0x00B4 #define PALETTE_30_DATA 0x00B8 #define CRTC_H_TOTAL_DISP 0x0200 # define CRTC_H_TOTAL (0x03ff << 0) # define CRTC_H_TOTAL_SHIFT 0 # define CRTC_H_DISP (0x01ff << 16) # define CRTC_H_DISP_SHIFT 16 #define CRTC2_H_TOTAL_DISP 0x0300 # define CRTC2_H_TOTAL (0x03ff << 0) # define CRTC2_H_TOTAL_SHIFT 0 # define CRTC2_H_DISP (0x01ff << 16) # define CRTC2_H_DISP_SHIFT 16 #define CRTC_H_SYNC_STRT_WID 0x0204 # define CRTC_H_SYNC_STRT_PIX (0x07 << 0) # define CRTC_H_SYNC_STRT_CHAR (0x3ff << 3) # define CRTC_H_SYNC_STRT_CHAR_SHIFT 3 # define CRTC_H_SYNC_WID (0x3f << 16) # define CRTC_H_SYNC_WID_SHIFT 16 # define CRTC_H_SYNC_POL (1 << 23) #define CRTC2_H_SYNC_STRT_WID 0x0304 # define CRTC2_H_SYNC_STRT_PIX (0x07 << 0) # define CRTC2_H_SYNC_STRT_CHAR (0x3ff << 3) # define CRTC2_H_SYNC_STRT_CHAR_SHIFT 3 # define CRTC2_H_SYNC_WID (0x3f << 16) # define CRTC2_H_SYNC_WID_SHIFT 16 # define CRTC2_H_SYNC_POL (1 << 23) #define CRTC_V_TOTAL_DISP 0x0208 # define CRTC_V_TOTAL (0x07ff << 0) # define CRTC_V_TOTAL_SHIFT 0 # define CRTC_V_DISP (0x07ff << 16) # define CRTC_V_DISP_SHIFT 16 #define CRTC2_V_TOTAL_DISP 0x0308 # define CRTC2_V_TOTAL (0x07ff << 0) # define CRTC2_V_TOTAL_SHIFT 0 # define CRTC2_V_DISP (0x07ff << 16) # define CRTC2_V_DISP_SHIFT 16 #define CRTC_V_SYNC_STRT_WID 0x020C # define CRTC_V_SYNC_STRT (0x7ff << 0) # define CRTC_V_SYNC_STRT_SHIFT 0 # define CRTC_V_SYNC_WID (0x1f << 16) # define CRTC_V_SYNC_WID_SHIFT 16 # define CRTC_V_SYNC_POL (1 << 23) #define CRTC2_V_SYNC_STRT_WID 0x030C # define CRTC2_V_SYNC_STRT (0x7ff << 0) # define CRTC2_V_SYNC_STRT_SHIFT 0 # define CRTC2_V_SYNC_WID (0x1f << 16) # define CRTC2_V_SYNC_WID_SHIFT 16 # define CRTC2_V_SYNC_POL (1 << 23) #define CRTC_VLINE_CRNT_VLINE 0x0210 # define CRTC_CRNT_VLINE_MASK (0x7ff << 16) #define CRTC2_VLINE_CRNT_VLINE 0x0310 #define CRTC_CRNT_FRAME 0x0214 #define CRTC2_CRNT_FRAME 0x0314 #define CRTC_GUI_TRIG_VLINE 0x0218 #define CRTC2_GUI_TRIG_VLINE 0x0318 #define CRTC_DEBUG 0x021C #define CRTC2_DEBUG 0x031C #define CRTC_OFFSET_RIGHT 0x0220 #define CRTC_OFFSET 0x0224 #define CRTC2_OFFSET 0x0324 #define CRTC_OFFSET_CNTL 0x0228 # define CRTC_TILE_EN (1 << 15) #define CRTC2_OFFSET_CNTL 0x0328 # define CRTC2_TILE_EN (1 << 15) #define CRTC_PITCH 0x022C #define CRTC2_PITCH 0x032C #define TMDS_CRC 0x02a0 #define OVR_CLR 0x0230 #define OVR_WID_LEFT_RIGHT 0x0234 #define OVR_WID_TOP_BOTTOM 0x0238 #define DISPLAY_BASE_ADDR 0x023C #define SNAPSHOT_VH_COUNTS 0x0240 #define SNAPSHOT_F_COUNT 0x0244 #define N_VIF_COUNT 0x0248 #define SNAPSHOT_VIF_COUNT 0x024C #define FP_CRTC_H_TOTAL_DISP 0x0250 #define FP_CRTC2_H_TOTAL_DISP 0x0350 #define FP_CRTC_V_TOTAL_DISP 0x0254 #define FP_CRTC2_V_TOTAL_DISP 0x0354 # define FP_CRTC_H_TOTAL_MASK 0x000003ff # define FP_CRTC_H_DISP_MASK 0x01ff0000 # define FP_CRTC_V_TOTAL_MASK 0x00000fff # define FP_CRTC_V_DISP_MASK 0x0fff0000 # define FP_H_SYNC_STRT_CHAR_MASK 0x00001ff8 # define FP_H_SYNC_WID_MASK 0x003f0000 # define FP_V_SYNC_STRT_MASK 0x00000fff # define FP_V_SYNC_WID_MASK 0x001f0000 # define FP_CRTC_H_TOTAL_SHIFT 0x00000000 # define FP_CRTC_H_DISP_SHIFT 0x00000010 # define FP_CRTC_V_TOTAL_SHIFT 0x00000000 # define FP_CRTC_V_DISP_SHIFT 0x00000010 # define FP_H_SYNC_STRT_CHAR_SHIFT 0x00000003 # define FP_H_SYNC_WID_SHIFT 0x00000010 # define FP_V_SYNC_STRT_SHIFT 0x00000000 # define FP_V_SYNC_WID_SHIFT 0x00000010 #define CRT_CRTC_H_SYNC_STRT_WID 0x0258 #define CRT_CRTC_V_SYNC_STRT_WID 0x025C #define CUR_OFFSET 0x0260 #define CUR_HORZ_VERT_POSN 0x0264 #define CUR_HORZ_VERT_OFF 0x0268 /* CUR_OFFSET, CUR_HORZ_VERT_POSN, CUR_HORZ_VERT_OFF bit constants */ # define CUR_LOCK 0x80000000 #define CUR_CLR0 0x026C #define CUR_CLR1 0x0270 #define CUR2_OFFSET 0x0360 #define CUR2_HORZ_VERT_POSN 0x0364 #define CUR2_HORZ_VERT_OFF 0x0368 # define CUR2_LOCK (1 << 31) #define CUR2_CLR0 0x036c #define CUR2_CLR1 0x0370 #define FP_HORZ_VERT_ACTIVE 0x0278 #define CRTC_MORE_CNTL 0x027C #define DAC_EXT_CNTL 0x0280 #define FP_GEN_CNTL 0x0284 /* FP_GEN_CNTL bit constants */ # define FP_FPON (1 << 0) # define FP_TMDS_EN (1 << 2) # define FP_EN_TMDS (1 << 7) # define FP_DETECT_SENSE (1 << 8) # define FP_SEL_CRTC2 (1 << 13) # define FP_CRTC_DONT_SHADOW_HPAR (1 << 15) # define FP_CRTC_DONT_SHADOW_VPAR (1 << 16) # define FP_CRTC_DONT_SHADOW_HEND (1 << 17) # define FP_CRTC_USE_SHADOW_VEND (1 << 18) # define FP_RMX_HVSYNC_CONTROL_EN (1 << 20) # define FP_DFP_SYNC_SEL (1 << 21) # define FP_CRTC_LOCK_8DOT (1 << 22) # define FP_CRT_SYNC_SEL (1 << 23) # define FP_USE_SHADOW_EN (1 << 24) # define FP_CRT_SYNC_ALT (1 << 26) #define FP2_GEN_CNTL 0x0288 /* FP2_GEN_CNTL bit constants */ # define FP2_FPON (1 << 0) # define FP2_TMDS_EN (1 << 2) # define FP2_EN_TMDS (1 << 7) # define FP2_DETECT_SENSE (1 << 8) # define FP2_SEL_CRTC2 (1 << 13) # define FP2_FP_POL (1 << 16) # define FP2_LP_POL (1 << 17) # define FP2_SCK_POL (1 << 18) # define FP2_LCD_CNTL_MASK (7 << 19) # define FP2_PAD_FLOP_EN (1 << 22) # define FP2_CRC_EN (1 << 23) # define FP2_CRC_READ_EN (1 << 24) #define FP_HORZ_STRETCH 0x028C #define FP_HORZ2_STRETCH 0x038C # define HORZ_STRETCH_RATIO_MASK 0xffff # define HORZ_STRETCH_RATIO_MAX 4096 # define HORZ_PANEL_SIZE (0x1ff << 16) # define HORZ_PANEL_SHIFT 16 # define HORZ_STRETCH_PIXREP (0 << 25) # define HORZ_STRETCH_BLEND (1 << 26) # define HORZ_STRETCH_ENABLE (1 << 25) # define HORZ_AUTO_RATIO (1 << 27) # define HORZ_FP_LOOP_STRETCH (0x7 << 28) # define HORZ_AUTO_RATIO_INC (1 << 31) #define FP_VERT_STRETCH 0x0290 #define FP_VERT2_STRETCH 0x0390 # define VERT_PANEL_SIZE (0xfff << 12) # define VERT_PANEL_SHIFT 12 # define VERT_STRETCH_RATIO_MASK 0xfff # define VERT_STRETCH_RATIO_SHIFT 0 # define VERT_STRETCH_RATIO_MAX 4096 # define VERT_STRETCH_ENABLE (1 << 25) # define VERT_STRETCH_LINEREP (0 << 26) # define VERT_STRETCH_BLEND (1 << 26) # define VERT_AUTO_RATIO_EN (1 << 27) # define VERT_STRETCH_RESERVED 0xf1000000 #define FP_H_SYNC_STRT_WID 0x02C4 #define FP_H2_SYNC_STRT_WID 0x03C4 #define FP_V_SYNC_STRT_WID 0x02C8 #define FP_V2_SYNC_STRT_WID 0x03C8 #define LVDS_GEN_CNTL 0x02d0 # define LVDS_ON (1 << 0) # define LVDS_DISPLAY_DIS (1 << 1) # define LVDS_PANEL_TYPE (1 << 2) # define LVDS_PANEL_FORMAT (1 << 3) # define LVDS_EN (1 << 7) # define LVDS_DIGON (1 << 18) # define LVDS_BLON (1 << 19) # define LVDS_SEL_CRTC2 (1 << 23) #define LVDS_PLL_CNTL 0x02d4 # define HSYNC_DELAY_SHIFT 28 # define HSYNC_DELAY_MASK (0xf << 28) #define AUX_WINDOW_HORZ_CNTL 0x02D8 #define AUX_WINDOW_VERT_CNTL 0x02DC #define DDA_CONFIG 0x02e0 #define DDA_ON_OFF 0x02e4 #define GRPH_BUFFER_CNTL 0x02F0 #define VGA_BUFFER_CNTL 0x02F4 /* first overlay unit (there is only one) */ #define OV0_Y_X_START 0x0400 #define OV0_Y_X_END 0x0404 #define OV0_PIPELINE_CNTL 0x0408 #define OV0_EXCLUSIVE_HORZ 0x0408 # define EXCL_HORZ_START_MASK 0x000000ff # define EXCL_HORZ_END_MASK 0x0000ff00 # define EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 # define EXCL_HORZ_EXCLUSIVE_EN 0x80000000 #define OV0_EXCLUSIVE_VERT 0x040C # define EXCL_VERT_START_MASK 0x000003ff # define EXCL_VERT_END_MASK 0x03ff0000 #define OV0_REG_LOAD_CNTL 0x0410 # define REG_LD_CTL_LOCK 0x00000001L # define REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L # define REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L # define REG_LD_CTL_LOCK_READBACK 0x00000008L #define OV0_SCALE_CNTL 0x0420 # define SCALER_PIX_EXPAND 0x00000001L # define SCALER_Y2R_TEMP 0x00000002L #ifdef RAGE128 # define SCALER_HORZ_PICK_NEAREST 0x00000003L # define SCALER_VERT_PICK_NEAREST 0x00000004L #else # define SCALER_HORZ_PICK_NEAREST 0x00000004L # define SCALER_VERT_PICK_NEAREST 0x00000008L #endif # define SCALER_SIGNED_UV 0x00000010L # define SCALER_GAMMA_SEL_MASK 0x00000060L # define SCALER_GAMMA_SEL_BRIGHT 0x00000000L # define SCALER_GAMMA_SEL_G22 0x00000020L # define SCALER_GAMMA_SEL_G18 0x00000040L # define SCALER_GAMMA_SEL_G14 0x00000060L # define SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L # define SCALER_SURFAC_FORMAT 0x00000f00L # define SCALER_SOURCE_UNK0 0x00000000L /* 2 bpp ??? */ # define SCALER_SOURCE_UNK1 0x00000100L /* 4 bpp ??? */ # define SCALER_SOURCE_UNK2 0x00000200L /* 8 bpp ??? */ # define SCALER_SOURCE_15BPP 0x00000300L # define SCALER_SOURCE_16BPP 0x00000400L /*# define SCALER_SOURCE_24BPP 0x00000500L*/ # define SCALER_SOURCE_32BPP 0x00000600L # define SCALER_SOURCE_UNK3 0x00000700L /* 8BPP_RGB332 ??? */ # define SCALER_SOURCE_UNK4 0x00000800L /* 8BPP_Y8 ??? */ # define SCALER_SOURCE_YUV9 0x00000900L /* 8BPP_RGB8 */ # define SCALER_SOURCE_YUV12 0x00000A00L # define SCALER_SOURCE_VYUY422 0x00000B00L # define SCALER_SOURCE_YVYU422 0x00000C00L # define SCALER_SOURCE_UNK5 0x00000D00L /* ??? */ # define SCALER_SOURCE_UNK6 0x00000E00L /* 32BPP_AYUV444 */ # define SCALER_SOURCE_UNK7 0x00000F00L /* 16BPP_ARGB4444 */ # define SCALER_ADAPTIVE_DEINT 0x00001000L # define R200_SCALER_TEMPORAL_DEINT 0x00002000L # define SCALER_UNKNOWN_FLAG1 0x00004000L /* ??? */ # define SCALER_SMART_SWITCH 0x00008000L #ifdef RAGE128 # define SCALER_BURST_PER_PLANE 0x00ff0000L #else # define SCALER_BURST_PER_PLANE 0x007f0000L #endif # define SCALER_DOUBLE_BUFFER 0x01000000L # define SCALER_UNKNOWN_FLAG3 0x02000000L /* ??? */ # define SCALER_UNKNOWN_FLAG4 0x04000000L /* ??? */ # define SCALER_DIS_LIMIT 0x08000000L # define SCALER_PRG_LOAD_START 0x10000000L # define SCALER_INT_EMU 0x20000000L # define SCALER_ENABLE 0x40000000L # define SCALER_SOFT_RESET 0x80000000L #define OV0_V_INC 0x0424 #define OV0_P1_V_ACCUM_INIT 0x0428 # define OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L # define OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L #define OV0_P23_V_ACCUM_INIT 0x042C # define OV0_P23_MAX_LN_IN_PER_LN_OUT 0x00000003L # define OV0_P23_V_ACCUM_INIT_MASK 0x01ff8000L #define OV0_P1_BLANK_LINES_AT_TOP 0x0430 # define P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL # define P1_ACTIVE_LINES_M1 0x0fff0000L #define OV0_P23_BLANK_LINES_AT_TOP 0x0434 # define P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL # define P23_ACTIVE_LINES_M1 0x07ff0000L #ifndef RAGE128 #define OV0_BASE_ADDR 0x043C #endif #define OV0_VID_BUF0_BASE_ADRS 0x0440 # define VIF_BUF0_PITCH_SEL 0x00000001L # define VIF_BUF0_TILE_ADRS 0x00000002L # define VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L # define VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF1_BASE_ADRS 0x0444 # define VIF_BUF1_PITCH_SEL 0x00000001L # define VIF_BUF1_TILE_ADRS 0x00000002L # define VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L # define VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF2_BASE_ADRS 0x0448 # define VIF_BUF2_PITCH_SEL 0x00000001L # define VIF_BUF2_TILE_ADRS 0x00000002L # define VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L # define VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF3_BASE_ADRS 0x044C # define VIF_BUF3_PITCH_SEL 0x00000001L # define VIF_BUF3_TILE_ADRS 0x00000002L # define VIF_BUF3_BASE_ADRS_MASK 0x03fffff0L # define VIF_BUF3_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF4_BASE_ADRS 0x0450 # define VIF_BUF4_PITCH_SEL 0x00000001L # define VIF_BUF4_TILE_ADRS 0x00000002L # define VIF_BUF4_BASE_ADRS_MASK 0x03fffff0L # define VIF_BUF4_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF5_BASE_ADRS 0x0454 # define VIF_BUF5_PITCH_SEL 0x00000001L # define VIF_BUF5_TILE_ADRS 0x00000002L # define VIF_BUF5_BASE_ADRS_MASK 0x03fffff0L # define VIF_BUF5_1ST_LINE_LSBS_MASK 0x48000000L #define OV0_VID_BUF_PITCH0_VALUE 0x0460 #define OV0_VID_BUF_PITCH1_VALUE 0x0464 #define OV0_AUTO_FLIP_CNTL 0x0470 # define OV0_AUTO_FLIP_CNTL_SOFT_BUF_NUM 0x00000007 # define OV0_AUTO_FLIP_CNTL_SOFT_REPEAT_FIELD 0x00000008 # define OV0_AUTO_FLIP_CNTL_SOFT_BUF_ODD 0x00000010 # define OV0_AUTO_FLIP_CNTL_IGNORE_REPEAT_FIELD 0x00000020 # define OV0_AUTO_FLIP_CNTL_SOFT_EOF_TOGGLE 0x00000040 # define OV0_AUTO_FLIP_CNTL_VID_PORT_SELECT 0x00000300 # define OV0_AUTO_FLIP_CNTL_P1_FIRST_LINE_EVEN 0x00010000 # define OV0_AUTO_FLIP_CNTL_SHIFT_EVEN_DOWN 0x00040000 # define OV0_AUTO_FLIP_CNTL_SHIFT_ODD_DOWN 0x00080000 # define OV0_AUTO_FLIP_CNTL_FIELD_POL_SOURCE 0x00800000 #define OV0_DEINTERLACE_PATTERN 0x0474 #define OV0_SUBMIT_HISTORY 0x0478 #define OV0_H_INC 0x0480 #define OV0_STEP_BY 0x0484 #define OV0_P1_H_ACCUM_INIT 0x0488 #define OV0_P23_H_ACCUM_INIT 0x048C #define OV0_P1_X_START_END 0x0494 #define OV0_P2_X_START_END 0x0498 #define OV0_P3_X_START_END 0x049C #define OV0_FILTER_CNTL 0x04A0 # define FILTER_PROGRAMMABLE_COEF 0x00000000 # define FILTER_HARD_SCALE_HORZ_Y 0x00000001 # define FILTER_HARD_SCALE_HORZ_UV 0x00000002 # define FILTER_HARD_SCALE_VERT_Y 0x00000004 # define FILTER_HARD_SCALE_VERT_UV 0x00000008 # define FILTER_HARDCODED_COEF 0x0000000F # define FILTER_COEF_MASK 0x0000000F /* When bit is set hard coded coefficients are used. */ /* Top quality 4x4-tap filtered vertical and horizontal scaler. It allows up to 64:1 upscaling and downscaling without performance or quality degradation. */ #define OV0_FOUR_TAP_COEF_0 0x04B0 # define OV0_FOUR_TAP_PHASE_0_TAP_0 0x0000000F # define OV0_FOUR_TAP_PHASE_0_TAP_1 0x00007F00 # define OV0_FOUR_TAP_PHASE_0_TAP_2 0x007F0000 # define OV0_FOUR_TAP_PHASE_0_TAP_3 0x0F000000 #define OV0_FOUR_TAP_COEF_1 0x04B4 # define OV0_FOUR_TAP_PHASE_1_5_TAP_0 0x0000000F # define OV0_FOUR_TAP_PHASE_1_5_TAP_1 0x00007F00 # define OV0_FOUR_TAP_PHASE_1_5_TAP_2 0x007F0000 # define OV0_FOUR_TAP_PHASE_1_5_TAP_3 0x0F000000 #define OV0_FOUR_TAP_COEF_2 0x04B8 # define OV0_FOUR_TAP_PHASE_2_6_TAP_0 0x0000000F # define OV0_FOUR_TAP_PHASE_2_6_TAP_1 0x00007F00 # define OV0_FOUR_TAP_PHASE_2_6_TAP_2 0x007F0000 # define OV0_FOUR_TAP_PHASE_2_6_TAP_3 0x0F000000 #define OV0_FOUR_TAP_COEF_3 0x04BC # define OV0_FOUR_TAP_PHASE_3_7_TAP_0 0x0000000F # define OV0_FOUR_TAP_PHASE_3_7_TAP_1 0x00007F00 # define OV0_FOUR_TAP_PHASE_3_7_TAP_2 0x007F0000 # define OV0_FOUR_TAP_PHASE_3_7_TAP_3 0x0F000000 #define OV0_FOUR_TAP_COEF_4 0x04C0 # define OV0_FOUR_TAP_PHASE_4_TAP_0 0x0000000F # define OV0_FOUR_TAP_PHASE_4_TAP_1 0x00007F00 # define OV0_FOUR_TAP_PHASE_4_TAP_2 0x007F0000 # define OV0_FOUR_TAP_PHASE_4_TAP_3 0x0F000000 /* 0th_tap means that the left most of top most pixel in a set of four will be multiplied by this coefficient. */ #define OV0_FLAG_CNTL 0x04DC #ifdef RAGE128 #define OV0_COLOUR_CNTL 0x04E0 # define COLOUR_CNTL_BRIGHTNESS 0x0000007F # define COLOUR_CNTL_SATURATION 0x001F1F00 #else /* NB: radeons have no COLOUR_CNTL register */ #define OV0_SLICE_CNTL 0x04E0 # define SLICE_CNTL_DISABLE 0x40000000 #endif /* Video and graphics keys allow alpha blending, color correction and many other video effects */ #define OV0_VID_KEY_CLR 0x04E4 #define OV0_VID_KEY_MSK 0x04E8 #define OV0_GRAPHICS_KEY_CLR 0x04EC #define OV0_GRAPHICS_KEY_MSK 0x04F0 #define OV0_KEY_CNTL 0x04F4 #ifdef RAGE128 # define VIDEO_KEY_FN_MASK 0x00000007L # define VIDEO_KEY_FN_FALSE 0x00000000L # define VIDEO_KEY_FN_TRUE 0x00000001L # define VIDEO_KEY_FN_EQ 0x00000004L # define VIDEO_KEY_FN_NE 0x00000005L # define GRAPHIC_KEY_FN_MASK 0x00000070L # define GRAPHIC_KEY_FN_FALSE 0x00000000L # define GRAPHIC_KEY_FN_TRUE 0x00000010L # define GRAPHIC_KEY_FN_EQ 0x00000040L # define GRAPHIC_KEY_FN_NE 0x00000050L #else # define VIDEO_KEY_FN_MASK 0x00000003L # define VIDEO_KEY_FN_FALSE 0x00000000L # define VIDEO_KEY_FN_TRUE 0x00000001L # define VIDEO_KEY_FN_EQ 0x00000002L # define VIDEO_KEY_FN_NE 0x00000003L # define GRAPHIC_KEY_FN_MASK 0x00000030L # define GRAPHIC_KEY_FN_FALSE 0x00000000L # define GRAPHIC_KEY_FN_TRUE 0x00000010L # define GRAPHIC_KEY_FN_EQ 0x00000020L # define GRAPHIC_KEY_FN_NE 0x00000030L #endif # define CMP_MIX_MASK 0x00000100L # define CMP_MIX_OR 0x00000000L # define CMP_MIX_AND 0x00000100L #define OV0_TEST 0x04F8 # define OV0_SCALER_Y2R_DISABLE 0x00000001L # define OV0_SUBPIC_ONLY 0x00000008L # define OV0_EXTENSE 0x00000010L # define OV0_SWAP_UV 0x00000020L #define OV0_COL_CONV 0x04FC # define OV0_CB_TO_B 0x0000007FL # define OV0_CB_TO_G 0x0000FF00L # define OV0_CR_TO_G 0x00FF0000L # define OV0_CR_TO_R 0x7F000000L # define OV0_NEW_COL_CONV 0x80000000L #define OV0_LIN_TRANS_A 0x0D20 #define OV0_LIN_TRANS_B 0x0D24 #define OV0_LIN_TRANS_C 0x0D28 #define OV0_LIN_TRANS_D 0x0D2C #define OV0_LIN_TRANS_E 0x0D30 #define OV0_LIN_TRANS_F 0x0D34 #define OV0_GAMMA_0_F 0x0D40 #define OV0_GAMMA_10_1F 0x0D44 #define OV0_GAMMA_20_3F 0x0D48 #define OV0_GAMMA_40_7F 0x0D4C /* These registers exist on R200 only */ #define OV0_GAMMA_80_BF 0x0E00 #define OV0_GAMMA_C0_FF 0x0E04 #define OV0_GAMMA_100_13F 0x0E08 #define OV0_GAMMA_140_17F 0x0E0C #define OV0_GAMMA_180_1BF 0x0E10 #define OV0_GAMMA_1C0_1FF 0x0E14 #define OV0_GAMMA_200_23F 0x0E18 #define OV0_GAMMA_240_27F 0x0E1C #define OV0_GAMMA_280_2BF 0x0E20 #define OV0_GAMMA_2C0_2FF 0x0E24 #define OV0_GAMMA_300_33F 0x0E28 #define OV0_GAMMA_340_37F 0x0E2C /* End of R200 specific definitions */ #define OV0_GAMMA_380_3BF 0x0D50 #define OV0_GAMMA_3C0_3FF 0x0D54 /* IDCT ENGINE: It's MPEG-2 hardware decoder which incorporates run-level decode, de-zigzag and IDCT into an IDCT engine to complement the motion compensation engine. */ #define IDCT_RUNS 0x1F80 #define IDCT_LEVELS 0x1F84 #define IDCT_AUTH_CONTROL 0x1F88 #define IDCT_AUTH 0x1F8C #define IDCT_CONTROL 0x1FBC #define SE_MC_SRC2_CNTL 0x19D4 # define SECONDARY_SCALE_HACC 0x00001FFFL # define SECONDARY_SCALE_VACC 0x0FFF0000L # define SECONDARY_SCALE_PICTH_ADJ 0xC0000000L #define SE_MC_SRC1_CNTL 0x19D8 # define SCALE_HACC 0x00001FFFL # define SCALE_VACC 0x0FFF0000L # define IDCT_EN 0x10000000L # define SECONDARY_TEX_EN 0x20000000L # define SCALE_PICTH_ADJ 0xC0000000L #define SE_MC_DST_CNTL 0x19DC # define DST_Y 0x00003FFFL # define DST_X 0x3FFF0000L # define DST_PITCH_ADJ 0xC0000000L #define SE_MC_CNTL_START 0x19E0 # define SCALE_OFFSET_PTR 0x0000000FL # define DST_OFFSET 0x00FFFFF0L # define ALPHA_EN 0x01000000L # define SECONDARY_OFFSET_PTR 0x1E000000L # define MC_DST_HEIGHT_WIDTH 0xE0000000L #ifndef RAGE128 #define SE_MC_BUF_BASE 0x19E4 #define PP_MC_CONTEXT 0x19E8 #define PP_MISC 0x1C14 #endif /* SUBPICTURE UNIT: Decompressing, scaling and alpha blending the compressed bitmap on the fly. Provide optimal DVD subpicture qualtity. */ #define SUBPIC_CNTL 0x0540 #define SUBPIC_DEFCOLCON 0x0544 #define SUBPIC_Y_X_START 0x054C #define SUBPIC_Y_X_END 0x0550 #define SUBPIC_V_INC 0x0554 #define SUBPIC_H_INC 0x0558 #define SUBPIC_BUF0_OFFSET 0x055C #define SUBPIC_BUF1_OFFSET 0x0560 #define SUBPIC_LC0_OFFSET 0x0564 #define SUBPIC_LC1_OFFSET 0x0568 #define SUBPIC_PITCH 0x056C #define SUBPIC_BTN_HLI_COLCON 0x0570 #define SUBPIC_BTN_HLI_Y_X_START 0x0574 #define SUBPIC_BTN_HLI_Y_X_END 0x0578 #define SUBPIC_PALETTE_INDEX 0x057C #define SUBPIC_PALETTE_DATA 0x0580 #define SUBPIC_H_ACCUM_INIT 0x0584 #define SUBPIC_V_ACCUM_INIT 0x0588 #define CP_RB_BASE 0x0700 #define CP_RB_CNTL 0x0704 #define CP_RB_RPTR_ADDR 0x070C #define CP_RB_RPTR 0x0710 #define CP_RB_WPTR 0x0714 #define CP_RB_WPTR_DELAY 0x0718 #define CP_IB_BASE 0x0738 #define CP_IB_BUFSZ 0x073C #define CP_CSQ_CNTL 0x0740 #define SCRATCH_UMSK 0x0770 #define SCRATCH_ADDR 0x0774 #ifndef RAGE128 #define DMA_GUI_TABLE_ADDR 0x0780 # define DMA_GUI_COMMAND__BYTE_COUNT_MASK 0x001fffff # define DMA_GUI_COMMAND__INTDIS 0x40000000 # define DMA_GUI_COMMAND__EOL 0x80000000 #define DMA_GUI_SRC_ADDR 0x0784 #define DMA_GUI_DST_ADDR 0x0788 #define DMA_GUI_COMMAND 0x078C #define DMA_GUI_STATUS 0x0790 #define DMA_GUI_ACT_DSCRPTR 0x0794 #define DMA_VID_TABLE_ADDR 0x07A0 #define DMA_VID_SRC_ADDR 0x07A4 #define DMA_VID_DST_ADDR 0x07A8 #define DMA_VID_COMMAND 0x07AC #define DMA_VID_STATUS 0x07B0 #define DMA_VID_ACT_DSCRPTR 0x07B4 #endif #define CP_ME_CNTL 0x07D0 #define CP_ME_RAM_ADDR 0x07D4 #define CP_ME_RAM_RADDR 0x07D8 #define CP_ME_RAM_DATAH 0x07DC #define CP_ME_RAM_DATAL 0x07E0 #define CP_CSQ_ADDR 0x07F0 #define CP_CSQ_DATA 0x07F4 #define CP_CSQ_STAT 0x07F8 #define DISP_MISC_CNTL 0x0D00 # define SOFT_RESET_GRPH_PP (1 << 0) #define DAC_MACRO_CNTL 0x0D04 #define DISP_PWR_MAN 0x0D08 #define DISP_TEST_DEBUG_CNTL 0x0D10 #define DISP_HW_DEBUG 0x0D14 #define DAC_CRC_SIG1 0x0D18 #define DAC_CRC_SIG2 0x0D1C /* first capture unit */ #define VID_BUFFER_CONTROL 0x0900 #define CAP_INT_CNTL 0x0908 #define CAP_INT_STATUS 0x090C #define FCP_CNTL 0x0910 # define FCP_CNTL__PCICLK 0 # define FCP_CNTL__PCLK 1 # define FCP_CNTL__PCLKb 2 # define FCP_CNTL__HREF 3 # define FCP_CNTL__GND 4 # define FCP_CNTL__HREFb 5 #define CAP0_BUF0_OFFSET 0x0920 #define CAP0_BUF1_OFFSET 0x0924 #define CAP0_BUF0_EVEN_OFFSET 0x0928 #define CAP0_BUF1_EVEN_OFFSET 0x092C #define CAP0_BUF_PITCH 0x0930 #define CAP0_V_WINDOW 0x0934 #define CAP0_H_WINDOW 0x0938 #define CAP0_VBI0_OFFSET 0x093C #define CAP0_VBI1_OFFSET 0x0940 #define CAP0_VBI_V_WINDOW 0x0944 #define CAP0_VBI_H_WINDOW 0x0948 #define CAP0_PORT_MODE_CNTL 0x094C #define CAP0_TRIG_CNTL 0x0950 #define CAP0_DEBUG 0x0954 #define CAP0_CONFIG 0x0958 # define CAP0_CONFIG_CONTINUOS 0x00000001 # define CAP0_CONFIG_START_FIELD_EVEN 0x00000002 # define CAP0_CONFIG_START_BUF_GET 0x00000004 # define CAP0_CONFIG_START_BUF_SET 0x00000008 # define CAP0_CONFIG_BUF_TYPE_ALT 0x00000010 # define CAP0_CONFIG_BUF_TYPE_FRAME 0x00000020 # define CAP0_CONFIG_ONESHOT_MODE_FRAME 0x00000040 # define CAP0_CONFIG_BUF_MODE_DOUBLE 0x00000080 # define CAP0_CONFIG_BUF_MODE_TRIPLE 0x00000100 # define CAP0_CONFIG_MIRROR_EN 0x00000200 # define CAP0_CONFIG_ONESHOT_MIRROR_EN 0x00000400 # define CAP0_CONFIG_VIDEO_SIGNED_UV 0x00000800 # define CAP0_CONFIG_ANC_DECODE_EN 0x00001000 # define CAP0_CONFIG_VBI_EN 0x00002000 # define CAP0_CONFIG_SOFT_PULL_DOWN_EN 0x00004000 # define CAP0_CONFIG_VIP_EXTEND_FLAG_EN 0x00008000 # define CAP0_CONFIG_FAKE_FIELD_EN 0x00010000 # define CAP0_CONFIG_ODD_ONE_MORE_LINE 0x00020000 # define CAP0_CONFIG_EVEN_ONE_MORE_LINE 0x00040000 # define CAP0_CONFIG_HORZ_DIVIDE_2 0x00080000 # define CAP0_CONFIG_HORZ_DIVIDE_4 0x00100000 # define CAP0_CONFIG_VERT_DIVIDE_2 0x00200000 # define CAP0_CONFIG_VERT_DIVIDE_4 0x00400000 # define CAP0_CONFIG_FORMAT_BROOKTREE 0x00000000 # define CAP0_CONFIG_FORMAT_CCIR656 0x00800000 # define CAP0_CONFIG_FORMAT_ZV 0x01000000 # define CAP0_CONFIG_FORMAT_VIP 0x01800000 # define CAP0_CONFIG_FORMAT_TRANSPORT 0x02000000 # define CAP0_CONFIG_HORZ_DECIMATOR 0x04000000 # define CAP0_CONFIG_VIDEO_IN_YVYU422 0x00000000 # define CAP0_CONFIG_VIDEO_IN_VYUY422 0x20000000 # define CAP0_CONFIG_VBI_DIVIDE_2 0x40000000 # define CAP0_CONFIG_VBI_DIVIDE_4 0x80000000 #define CAP0_ANC_ODD_OFFSET 0x095C #define CAP0_ANC_EVEN_OFFSET 0x0960 #define CAP0_ANC_H_WINDOW 0x0964 #define CAP0_VIDEO_SYNC_TEST 0x0968 #define CAP0_ONESHOT_BUF_OFFSET 0x096C #define CAP0_BUF_STATUS 0x0970 #ifdef RAGE128 #define CAP0_DWNSC_XRATIO 0x0978 #define CAP0_XSHARPNESS 0x097C #else /* #define CAP0_DWNSC_XRATIO 0x0978 */ /* #define CAP0_XSHARPNESS 0x097C */ #endif #define CAP0_VBI2_OFFSET 0x0980 #define CAP0_VBI3_OFFSET 0x0984 #define CAP0_ANC2_OFFSET 0x0988 #define CAP0_ANC3_OFFSET 0x098C /* second capture unit */ #define CAP1_BUF0_OFFSET 0x0990 #define CAP1_BUF1_OFFSET 0x0994 #define CAP1_BUF0_EVEN_OFFSET 0x0998 #define CAP1_BUF1_EVEN_OFFSET 0x099C #define CAP1_BUF_PITCH 0x09A0 #define CAP1_V_WINDOW 0x09A4 #define CAP1_H_WINDOW 0x09A8 #define CAP1_VBI_ODD_OFFSET 0x09AC #define CAP1_VBI_EVEN_OFFSET 0x09B0 #define CAP1_VBI_V_WINDOW 0x09B4 #define CAP1_VBI_H_WINDOW 0x09B8 #define CAP1_PORT_MODE_CNTL 0x09BC #define CAP1_TRIG_CNTL 0x09C0 #define CAP1_DEBUG 0x09C4 #define CAP1_CONFIG 0x09C8 #define CAP1_ANC_ODD_OFFSET 0x09CC #define CAP1_ANC_EVEN_OFFSET 0x09D0 #define CAP1_ANC_H_WINDOW 0x09D4 #define CAP1_VIDEO_SYNC_TEST 0x09D8 #define CAP1_ONESHOT_BUF_OFFSET 0x09DC #define CAP1_BUF_STATUS 0x09E0 #define CAP1_DWNSC_XRATIO 0x09E8 #define CAP1_XSHARPNESS 0x09EC #define DISP_MERGE_CNTL 0x0D60 #define DISP_OUTPUT_CNTL 0x0D64 # define DISP_DAC_SOURCE_MASK 0x03 # define DISP_DAC_SOURCE_CRTC2 0x01 #define DISP_LIN_TRANS_GRPH_A 0x0D80 #define DISP_LIN_TRANS_GRPH_B 0x0D84 #define DISP_LIN_TRANS_GRPH_C 0x0D88 #define DISP_LIN_TRANS_GRPH_D 0x0D8C #define DISP_LIN_TRANS_GRPH_E 0x0D90 #define DISP_LIN_TRANS_GRPH_F 0x0D94 #define DISP_LIN_TRANS_VID_A 0x0D98 #define DISP_LIN_TRANS_VID_B 0x0D9C #define DISP_LIN_TRANS_VID_C 0x0DA0 #define DISP_LIN_TRANS_VID_D 0x0DA4 #define DISP_LIN_TRANS_VID_E 0x0DA8 #define DISP_LIN_TRANS_VID_F 0x0DAC #define RMX_HORZ_FILTER_0TAP_COEF 0x0DB0 #define RMX_HORZ_FILTER_1TAP_COEF 0x0DB4 #define RMX_HORZ_FILTER_2TAP_COEF 0x0DB8 #define RMX_HORZ_PHASE 0x0DBC #define DAC_EMBEDDED_SYNC_CNTL 0x0DC0 #define DAC_BROAD_PULSE 0x0DC4 #define DAC_SKEW_CLKS 0x0DC8 #define DAC_INCR 0x0DCC #define DAC_NEG_SYNC_LEVEL 0x0DD0 #define DAC_POS_SYNC_LEVEL 0x0DD4 #define DAC_BLANK_LEVEL 0x0DD8 #define CLOCK_CNTL_INDEX 0x0008 /* CLOCK_CNTL_INDEX bit constants */ # define PLL_WR_EN 0x00000080 # define PLL_DIV_SEL (3 << 8) # define PLL2_DIV_SEL_MASK ~(3 << 8) #define CLOCK_CNTL_DATA 0x000C #define CP_RB_CNTL 0x0704 #define CP_RB_BASE 0x0700 #define CP_RB_RPTR_ADDR 0x070C #define CP_RB_RPTR 0x0710 #define CP_RB_WPTR 0x0714 #define CP_RB_WPTR_DELAY 0x0718 #define CP_IB_BASE 0x0738 #define CP_IB_BUFSZ 0x073C #define SCRATCH_REG0 0x15E0 #define GUI_SCRATCH_REG0 0x15E0 #define SCRATCH_REG1 0x15E4 #define GUI_SCRATCH_REG1 0x15E4 #define SCRATCH_REG2 0x15E8 #define GUI_SCRATCH_REG2 0x15E8 #define SCRATCH_REG3 0x15EC #define GUI_SCRATCH_REG3 0x15EC #define SCRATCH_REG4 0x15F0 #define GUI_SCRATCH_REG4 0x15F0 #define SCRATCH_REG5 0x15F4 #define GUI_SCRATCH_REG5 0x15F4 #define SCRATCH_UMSK 0x0770 #define SCRATCH_ADDR 0x0774 #define DP_BRUSH_FRGD_CLR 0x147C #define DP_BRUSH_BKGD_CLR 0x1478 #define DST_LINE_START 0x1600 #define DST_LINE_END 0x1604 #define SRC_OFFSET 0x15AC #define SRC_PITCH 0x15B0 #define SRC_TILE 0x1704 #define SRC_PITCH_OFFSET 0x1428 #define SRC_X 0x1414 #define SRC_Y 0x1418 #define DST_WIDTH_X 0x1588 #define DST_HEIGHT_WIDTH_8 0x158C #define SRC_X_Y 0x1590 #define SRC_Y_X 0x1434 #define DST_Y_X 0x1438 #define DST_WIDTH_HEIGHT 0x1598 #define DST_HEIGHT_WIDTH 0x143c #ifdef RAGE128 #define GUI_STAT 0x1740 # define GUI_FIFOCNT_MASK 0x0fff # define PM4_BUSY (1 << 16) # define MICRO_BUSY (1 << 17) # define FPU_BUSY (1 << 18) # define VC_BUSY (1 << 19) # define IDCT_BUSY (1 << 20) # define ENG_EV_BUSY (1 << 21) # define SETUP_BUSY (1 << 22) # define EDGE_WALK_BUSY (1 << 23) # define ADDRESSING_BUSY (1 << 24) # define ENG_3D_BUSY (1 << 25) # define ENG_2D_SM_BUSY (1 << 26) # define ENG_2D_BUSY (1 << 27) # define GUI_WB_BUSY (1 << 28) # define CACHE_BUSY (1 << 29) # define GUI_ACTIVE (1 << 31) #endif #define SRC_CLUT_ADDRESS 0x1780 #define SRC_CLUT_DATA 0x1784 #define SRC_CLUT_DATA_RD 0x1788 #define HOST_DATA0 0x17C0 #define HOST_DATA1 0x17C4 #define HOST_DATA2 0x17C8 #define HOST_DATA3 0x17CC #define HOST_DATA4 0x17D0 #define HOST_DATA5 0x17D4 #define HOST_DATA6 0x17D8 #define HOST_DATA7 0x17DC #define HOST_DATA_LAST 0x17E0 #define DP_SRC_ENDIAN 0x15D4 #define DP_SRC_FRGD_CLR 0x15D8 #define DP_SRC_BKGD_CLR 0x15DC #define DP_WRITE_MASK 0x16cc #define SC_LEFT 0x1640 #define SC_RIGHT 0x1644 #define SC_TOP 0x1648 #define SC_BOTTOM 0x164C #define SRC_SC_RIGHT 0x1654 #define SRC_SC_BOTTOM 0x165C #define DP_CNTL 0x16C0 /* DP_CNTL bit constants */ # define DST_X_RIGHT_TO_LEFT 0x00000000 # define DST_X_LEFT_TO_RIGHT 0x00000001 # define DST_Y_BOTTOM_TO_TOP 0x00000000 # define DST_Y_TOP_TO_BOTTOM 0x00000002 # define DST_X_MAJOR 0x00000000 # define DST_Y_MAJOR 0x00000004 # define DST_X_TILE 0x00000008 # define DST_Y_TILE 0x00000010 # define DST_LAST_PEL 0x00000020 # define DST_TRAIL_X_RIGHT_TO_LEFT 0x00000000 # define DST_TRAIL_X_LEFT_TO_RIGHT 0x00000040 # define DST_TRAP_FILL_RIGHT_TO_LEFT 0x00000000 # define DST_TRAP_FILL_LEFT_TO_RIGHT 0x00000080 # define DST_BRES_SIGN 0x00000100 # define DST_HOST_BIG_ENDIAN_EN 0x00000200 # define DST_POLYLINE_NONLAST 0x00008000 # define DST_RASTER_STALL 0x00010000 # define DST_POLY_EDGE 0x00040000 #define DP_CNTL_XDIR_YDIR_YMAJOR 0x16D0 /* DP_CNTL_XDIR_YDIR_YMAJOR bit constants (short version of DP_CNTL) */ # define DST_X_MAJOR_S 0x00000000 # define DST_Y_MAJOR_S 0x00000001 # define DST_Y_BOTTOM_TO_TOP_S 0x00000000 # define DST_Y_TOP_TO_BOTTOM_S 0x00008000 # define DST_X_RIGHT_TO_LEFT_S 0x00000000 # define DST_X_LEFT_TO_RIGHT_S 0x80000000 #define DP_DATATYPE 0x16C4 /* DP_DATATYPE bit constants */ # define DST_8BPP 0x00000002 # define DST_15BPP 0x00000003 # define DST_16BPP 0x00000004 # define DST_24BPP 0x00000005 # define DST_32BPP 0x00000006 # define DST_8BPP_RGB332 0x00000007 # define DST_8BPP_Y8 0x00000008 # define DST_8BPP_RGB8 0x00000009 # define DST_16BPP_VYUY422 0x0000000b # define DST_16BPP_YVYU422 0x0000000c # define DST_32BPP_AYUV444 0x0000000e # define DST_16BPP_ARGB4444 0x0000000f # define BRUSH_SOLIDCOLOR 0x00000d00 # define SRC_MONO 0x00000000 # define SRC_MONO_LBKGD 0x00010000 # define SRC_DSTCOLOR 0x00030000 # define BYTE_ORDER_MSB_TO_LSB 0x00000000 # define BYTE_ORDER_LSB_TO_MSB 0x40000000 # define DP_CONVERSION_TEMP 0x80000000 # define HOST_BIG_ENDIAN_EN (1 << 29) #define DP_MIX 0x16C8 /* DP_MIX bit constants */ # define DP_SRC_RECT 0x00000200 # define DP_SRC_HOST 0x00000300 # define DP_SRC_HOST_BYTEALIGN 0x00000400 #define DP_WRITE_MSK 0x16CC #define DP_XOP 0x17F8 #define CLR_CMP_CLR_SRC 0x15C4 #define CLR_CMP_CLR_DST 0x15C8 #define CLR_CMP_CNTL 0x15C0 /* CLR_CMP_CNTL bit constants */ # define COMPARE_SRC_FALSE 0x00000000 # define COMPARE_SRC_TRUE 0x00000001 # define COMPARE_SRC_NOT_EQUAL 0x00000004 # define COMPARE_SRC_EQUAL 0x00000005 # define COMPARE_SRC_EQUAL_FLIP 0x00000007 # define COMPARE_DST_FALSE 0x00000000 # define COMPARE_DST_TRUE 0x00000100 # define COMPARE_DST_NOT_EQUAL 0x00000400 # define COMPARE_DST_EQUAL 0x00000500 # define COMPARE_DESTINATION 0x00000000 # define COMPARE_SOURCE 0x01000000 # define COMPARE_SRC_AND_DST 0x02000000 #define CLR_CMP_MSK 0x15CC #define DSTCACHE_MODE 0x1710 #define DSTCACHE_CTLSTAT 0x1714 /* DSTCACHE_CTLSTAT bit constants */ # define RB2D_DC_FLUSH (3 << 0) # define RB2D_DC_FLUSH_ALL 0xf # define RB2D_DC_BUSY (1 << 31) #define DEFAULT_OFFSET 0x16e0 #define DEFAULT_PITCH_OFFSET 0x16E0 #define DEFAULT_SC_BOTTOM_RIGHT 0x16E8 /* DEFAULT_SC_BOTTOM_RIGHT bit constants */ # define DEFAULT_SC_RIGHT_MAX (0x1fff << 0) # define DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) #define DP_GUI_MASTER_CNTL 0x146C /* DP_GUI_MASTER_CNTL bit constants */ # define GMC_SRC_PITCH_OFFSET_DEFAULT 0x00000000 # define GMC_SRC_PITCH_OFFSET_LEAVE 0x00000001 # define GMC_DST_PITCH_OFFSET_DEFAULT 0x00000000 # define GMC_DST_PITCH_OFFSET_LEAVE 0x00000002 # define GMC_SRC_CLIP_DEFAULT 0x00000000 # define GMC_SRC_CLIP_LEAVE 0x00000004 # define GMC_DST_CLIP_DEFAULT 0x00000000 # define GMC_DST_CLIP_LEAVE 0x00000008 # define GMC_BRUSH_8x8MONO 0x00000000 # define GMC_BRUSH_8x8MONO_LBKGD 0x00000010 # define GMC_BRUSH_8x1MONO 0x00000020 # define GMC_BRUSH_8x1MONO_LBKGD 0x00000030 # define GMC_BRUSH_1x8MONO 0x00000040 # define GMC_BRUSH_1x8MONO_LBKGD 0x00000050 # define GMC_BRUSH_32x1MONO 0x00000060 # define GMC_BRUSH_32x1MONO_LBKGD 0x00000070 # define GMC_BRUSH_32x32MONO 0x00000080 # define GMC_BRUSH_32x32MONO_LBKGD 0x00000090 # define GMC_BRUSH_8x8COLOR 0x000000a0 # define GMC_BRUSH_8x1COLOR 0x000000b0 # define GMC_BRUSH_1x8COLOR 0x000000c0 # define GMC_BRUSH_SOLID_COLOR 0x000000d0 # define GMC_DST_8BPP 0x00000200 # define GMC_DST_15BPP 0x00000300 # define GMC_DST_16BPP 0x00000400 # define GMC_DST_24BPP 0x00000500 # define GMC_DST_32BPP 0x00000600 # define GMC_DST_8BPP_RGB332 0x00000700 # define GMC_DST_8BPP_Y8 0x00000800 # define GMC_DST_8BPP_RGB8 0x00000900 # define GMC_DST_16BPP_VYUY422 0x00000b00 # define GMC_DST_16BPP_YVYU422 0x00000c00 # define GMC_DST_32BPP_AYUV444 0x00000e00 # define GMC_DST_16BPP_ARGB4444 0x00000f00 # define GMC_SRC_MONO 0x00000000 # define GMC_SRC_MONO_LBKGD 0x00001000 # define GMC_SRC_DSTCOLOR 0x00003000 # define GMC_BYTE_ORDER_MSB_TO_LSB 0x00000000 # define GMC_BYTE_ORDER_LSB_TO_MSB 0x00004000 # define GMC_DP_CONVERSION_TEMP_9300 0x00008000 # define GMC_DP_CONVERSION_TEMP_6500 0x00000000 # define GMC_DP_SRC_RECT 0x02000000 # define GMC_DP_SRC_HOST 0x03000000 # define GMC_DP_SRC_HOST_BYTEALIGN 0x04000000 # define GMC_3D_FCN_EN_CLR 0x00000000 # define GMC_3D_FCN_EN_SET 0x08000000 # define GMC_DST_CLR_CMP_FCN_LEAVE 0x00000000 # define GMC_DST_CLR_CMP_FCN_CLEAR 0x10000000 # define GMC_AUX_CLIP_LEAVE 0x00000000 # define GMC_AUX_CLIP_CLEAR 0x20000000 # define GMC_WRITE_MASK_LEAVE 0x00000000 # define GMC_WRITE_MASK_SET 0x40000000 # define GMC_CLR_CMP_CNTL_DIS (1 << 28) # define GMC_SRC_DATATYPE_COLOR (3 << 12) # define ROP3_S 0x00cc0000 # define ROP3_SRCCOPY 0x00cc0000 # define ROP3_P 0x00f00000 # define ROP3_PATCOPY 0x00f00000 # define DP_SRC_SOURCE_MASK (7 << 24) # define GMC_BRUSH_NONE (15 << 4) # define DP_SRC_SOURCE_MEMORY (2 << 24) # define GMC_BRUSH_SOLIDCOLOR 0x000000d0 #define SC_TOP_LEFT 0x16EC #define SC_BOTTOM_RIGHT 0x16F0 #define SRC_SC_BOTTOM_RIGHT 0x16F4 #define RB2D_DSTCACHE_CTLSTAT 0x342C #define RB2D_DSTCACHE_MODE 0x3428 #define BASE_CODE 0x0f0b/*0x0f08*/ #define RADEON_BIOS_0_SCRATCH 0x0010 #define RADEON_BIOS_1_SCRATCH 0x0014 #define RADEON_BIOS_2_SCRATCH 0x0018 #define RADEON_BIOS_3_SCRATCH 0x001c #define RADEON_BIOS_4_SCRATCH 0x0020 #define RADEON_BIOS_5_SCRATCH 0x0024 #define RADEON_BIOS_6_SCRATCH 0x0028 #define RADEON_BIOS_7_SCRATCH 0x002c #define CLK_PIN_CNTL 0x0001 #define PPLL_CNTL 0x0002 # define PPLL_RESET (1 << 0) # define PPLL_SLEEP (1 << 1) # define PPLL_ATOMIC_UPDATE_EN (1 << 16) # define PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) # define PPLL_ATOMIC_UPDATE_VSYNC (1 << 18) #define PPLL_REF_DIV 0x0003 # define PPLL_REF_DIV_MASK 0x03ff # define PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ # define PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ #define PPLL_DIV_0 0x0004 #define PPLL_DIV_1 0x0005 #define PPLL_DIV_2 0x0006 #define PPLL_DIV_3 0x0007 #define VCLK_ECP_CNTL 0x0008 # define VCLK_SRC_SEL_MASK 0x03 # define VCLK_SRC_SEL_CPUCLK 0x00 # define VCLK_SRC_SEL_PSCANCLK 0x01 # define VCLK_SRC_SEL_BYTECLK 0x02 # define VCLK_SRC_SEL_PPLLCLK 0x03 #define HTOTAL_CNTL 0x0009 #define HTOTAL2_CNTL 0x002e /* PLL */ #define M_SPLL_REF_FB_DIV 0x000a #define AGP_PLL_CNTL 0x000b #define SPLL_CNTL 0x000c #define SCLK_CNTL 0x000d # define DYN_STOP_LAT_MASK 0x00007ff8 # define CP_MAX_DYN_STOP_LAT 0x0008 # define SCLK_FORCEON_MASK 0xffff8000 #define SCLK_MORE_CNTL 0x0035 /* PLL */ # define SCLK_MORE_FORCEON 0x0700 #define MPLL_CNTL 0x000e #ifdef RAGE128 #define MCLK_CNTL 0x000f /* PLL */ # define FORCE_GCP (1 << 16) # define FORCE_PIPE3D_CP (1 << 17) # define FORCE_RCP (1 << 18) #else #define MCLK_CNTL 0x0012 /* MCLK_CNTL bit constants */ # define FORCEON_MCLKA (1 << 16) # define FORCEON_MCLKB (1 << 17) # define FORCEON_YCLKA (1 << 18) # define FORCEON_YCLKB (1 << 19) # define FORCEON_MC (1 << 20) # define FORCEON_AIC (1 << 21) #endif #define PLL_TEST_CNTL 0x0013 #define P2PLL_CNTL 0x002a /* P2PLL */ # define P2PLL_RESET (1 << 0) # define P2PLL_SLEEP (1 << 1) # define P2PLL_ATOMIC_UPDATE_EN (1 << 16) # define P2PLL_VGA_ATOMIC_UPDATE_EN (1 << 17) # define P2PLL_ATOMIC_UPDATE_VSYNC (1 << 18) #define P2PLL_DIV_0 0x002c # define P2PLL_FB0_DIV_MASK 0x07ff # define P2PLL_POST0_DIV_MASK 0x00070000 #define P2PLL_REF_DIV 0x002B /* PLL */ # define P2PLL_REF_DIV_MASK 0x03ff # define P2PLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ # define P2PLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ #define PIXCLKS_CNTL 0x002d # define PIX2CLK_SRC_SEL_MASK 0x03 # define PIX2CLK_SRC_SEL_CPUCLK 0x00 # define PIX2CLK_SRC_SEL_PSCANCLK 0x01 # define PIX2CLK_SRC_SEL_BYTECLK 0x02 # define PIX2CLK_SRC_SEL_P2PLLCLK 0x03 /* masks */ #define CONFIG_MEMSIZE_MASK 0x1f000000 #define MEM_CFG_TYPE 0x40000000 #define DST_OFFSET_MASK 0x003fffff #define DST_PITCH_MASK 0x3fc00000 #define DEFAULT_TILE_MASK 0xc0000000 #define PPLL_DIV_SEL_MASK 0x00000300 #define PPLL_FB3_DIV_MASK 0x000007ff #define PPLL_POST3_DIV_MASK 0x00070000 /* BUS MASTERING */ #ifdef RAGE128 #define BM_FRAME_BUF_OFFSET 0xA00 #define BM_SYSTEM_MEM_ADDR 0xA04 #define BM_COMMAND 0xA08 # define BM_INTERRUPT_DIS 0x08000000 # define BM_TRANSFER_DEST_REG 0x10000000 # define BM_FORCE_TO_PCI 0x20000000 # define BM_FRAME_OFFSET_HOLD 0x40000000 # define BM_END_OF_LIST 0x80000000 #define BM_STATUS 0xA0c #define BM_QUEUE_STATUS 0xA10 #define BM_QUEUE_FREE_STATUS 0xA14 #define BM_CHUNK_0_VAL 0xA18 # define BM_PTR_FORCE_TO_PCI 0x00200000 # define BM_PM4_RD_FORCE_TO_PCI 0x00400000 # define BM_GLOBAL_FORCE_TO_PCI 0x00800000 # define BM_VIP3_NOCHUNK 0x10000000 # define BM_VIP2_NOCHUNK 0x20000000 # define BM_VIP1_NOCHUNK 0x40000000 # define BM_VIP0_NOCHUNK 0x80000000 #define BM_CHUNK_1_VAL 0xA1C #define BM_VIP0_BUF 0xA20 # define SYSTEM_TRIGGER_SYSTEM_TO_VIDEO 0x0 # define SYSTEM_TRIGGER_VIDEO_TO_SYSTEM 0x1 #define BM_VIP0_ACTIVE 0xA24 #define BM_VIP1_BUF 0xA30 #define BM_VIP1_ACTIVE 0xA34 #define BM_VIP2_BUF 0xA40 #define BM_VIP2_ACTIVE 0xA44 #define BM_VIP3_BUF 0xA50 #define BM_VIP3_ACTIVE 0xA54 #define BM_VIDCAP_BUF0 0xA60 #define BM_VIDCAP_BUF1 0xA64 #define BM_VIDCAP_BUF2 0xA68 #define BM_VIDCAP_ACTIVE 0xA6c #define BM_GUI 0xA80 #define BM_ABORT 0xA88 #endif /* RAGE THEATER REGISTERS */ #define DMA_VIPH0_COMMAND 0x0A00 #define DMA_VIPH1_COMMAND 0x0A04 #define DMA_VIPH2_COMMAND 0x0A08 #define DMA_VIPH3_COMMAND 0x0A0C #define DMA_VIPH_STATUS 0x0A10 #define DMA_VIPH_CHUNK_0 0x0A18 #define DMA_VIPH_CHUNK_1_VAL 0x0A1C #define DMA_VIP0_TABLE_ADDR 0x0A20 #define DMA_VIPH0_ACTIVE 0x0A24 #define DMA_VIP1_TABLE_ADDR 0x0A30 #define DMA_VIPH1_ACTIVE 0x0A34 #define DMA_VIP2_TABLE_ADDR 0x0A40 #define DMA_VIPH2_ACTIVE 0x0A44 #define DMA_VIP3_TABLE_ADDR 0x0A50 #define DMA_VIPH3_ACTIVE 0x0A54 #define DMA_VIPH_ABORT 0x0A88 #define VIPH_CH0_DATA 0x0c00 #define VIPH_CH1_DATA 0x0c04 #define VIPH_CH2_DATA 0x0c08 #define VIPH_CH3_DATA 0x0c0c #define VIPH_CH0_ADDR 0x0c10 #define VIPH_CH1_ADDR 0x0c14 #define VIPH_CH2_ADDR 0x0c18 #define VIPH_CH3_ADDR 0x0c1c #define VIPH_CH0_SBCNT 0x0c20 #define VIPH_CH1_SBCNT 0x0c24 #define VIPH_CH2_SBCNT 0x0c28 #define VIPH_CH3_SBCNT 0x0c2c #define VIPH_CH0_ABCNT 0x0c30 #define VIPH_CH1_ABCNT 0x0c34 #define VIPH_CH2_ABCNT 0x0c38 #define VIPH_CH3_ABCNT 0x0c3c #define VIPH_CONTROL 0x0c40 #define VIPH_DV_LAT 0x0c44 #define VIPH_BM_CHUNK 0x0c48 #define VIPH_DV_INT 0x0c4c #define VIPH_TIMEOUT_STAT 0x0c50 #define VIPH_REG_DATA 0x0084 #define VIPH_REG_ADDR 0x0080 /* Address Space Rage Theatre Registers (VIP Access) */ #define VIP_VIP_VENDOR_DEVICE_ID 0x0000 #define VIP_VIP_SUB_VENDOR_DEVICE_ID 0x0004 #define VIP_VIP_COMMAND_STATUS 0x0008 #define VIP_VIP_REVISION_ID 0x000c #define VIP_HW_DEBUG 0x0010 #define VIP_SW_SCRATCH 0x0014 #define VIP_I2C_CNTL_0 0x0020 #define VIP_I2C_CNTL_1 0x0024 #define VIP_I2C_DATA 0x0028 #define VIP_INT_CNTL 0x002c #define VIP_GPIO_INOUT 0x0030 #define VIP_GPIO_CNTL 0x0034 #define VIP_CLKOUT_GPIO_CNTL 0x0038 #define VIP_RIPINTF_PORT_CNTL 0x003c #define VIP_ADC_CNTL 0x0400 #define VIP_ADC_DEBUG 0x0404 #define VIP_STANDARD_SELECT 0x0408 #define VIP_THERMO2BIN_STATUS 0x040c #define VIP_COMB_CNTL0 0x0440 #define VIP_COMB_CNTL1 0x0444 #define VIP_COMB_CNTL2 0x0448 #define VIP_COMB_LINE_LENGTH 0x044c #define VIP_NOISE_CNTL0 0x0450 #define VIP_HS_PLINE 0x0480 #define VIP_HS_DTOINC 0x0484 #define VIP_HS_PLLGAIN 0x0488 #define VIP_HS_MINMAXWIDTH 0x048c #define VIP_HS_GENLOCKDELAY 0x0490 #define VIP_HS_WINDOW_LIMIT 0x0494 #define VIP_HS_WINDOW_OC_SPEED 0x0498 #define VIP_HS_PULSE_WIDTH 0x049c #define VIP_HS_PLL_ERROR 0x04a0 #define VIP_HS_PLL_FS_PATH 0x04a4 #define VIP_SG_BLACK_GATE 0x04c0 #define VIP_SG_SYNCTIP_GATE 0x04c4 #define VIP_SG_UVGATE_GATE 0x04c8 #define VIP_LP_AGC_CLAMP_CNTL0 0x0500 #define VIP_LP_AGC_CLAMP_CNTL1 0x0504 #define VIP_LP_BRIGHTNESS 0x0508 #define VIP_LP_CONTRAST 0x050c #define VIP_LP_SLICE_LIMIT 0x0510 #define VIP_LP_WPA_CNTL0 0x0514 #define VIP_LP_WPA_CNTL1 0x0518 #define VIP_LP_BLACK_LEVEL 0x051c #define VIP_LP_SLICE_LEVEL 0x0520 #define VIP_LP_SYNCTIP_LEVEL 0x0524 #define VIP_LP_VERT_LOCKOUT 0x0528 #define VIP_VS_DETECTOR_CNTL 0x0540 #define VIP_VS_BLANKING_CNTL 0x0544 #define VIP_VS_FIELD_ID_CNTL 0x0548 #define VIP_VS_COUNTER_CNTL 0x054c #define VIP_VS_FRAME_TOTAL 0x0550 #define VIP_VS_LINE_COUNT 0x0554 #define VIP_CP_PLL_CNTL0 0x0580 #define VIP_CP_PLL_CNTL1 0x0584 #define VIP_CP_HUE_CNTL 0x0588 #define VIP_CP_BURST_GAIN 0x058c #define VIP_CP_AGC_CNTL 0x0590 #define VIP_CP_ACTIVE_GAIN 0x0594 #define VIP_CP_PLL_STATUS0 0x0598 #define VIP_CP_PLL_STATUS1 0x059c #define VIP_CP_PLL_STATUS2 0x05a0 #define VIP_CP_PLL_STATUS3 0x05a4 #define VIP_CP_PLL_STATUS4 0x05a8 #define VIP_CP_PLL_STATUS5 0x05ac #define VIP_CP_PLL_STATUS6 0x05b0 #define VIP_CP_PLL_STATUS7 0x05b4 #define VIP_CP_DEBUG_FORCE 0x05b8 #define VIP_CP_VERT_LOCKOUT 0x05bc #define VIP_H_ACTIVE_WINDOW 0x05c0 #define VIP_V_ACTIVE_WINDOW 0x05c4 #define VIP_H_VBI_WINDOW 0x05c8 #define VIP_V_VBI_WINDOW 0x05cc #define VIP_VBI_CONTROL 0x05d0 #define VIP_DECODER_DEBUG_CNTL 0x05d4 #define VIP_SINGLE_STEP_DATA 0x05d8 #define VIP_MASTER_CNTL 0x0040 #define VIP_RGB_CNTL 0x0048 #define VIP_CLKOUT_CNTL 0x004c #define VIP_SYNC_CNTL 0x0050 #define VIP_I2C_CNTL 0x0054 #define VIP_HTOTAL 0x0080 #define VIP_HDISP 0x0084 #define VIP_HSIZE 0x0088 #define VIP_HSTART 0x008c #define VIP_HCOUNT 0x0090 #define VIP_VTOTAL 0x0094 #define VIP_VDISP 0x0098 #define VIP_VCOUNT 0x009c #define VIP_VFTOTAL 0x00a0 #define VIP_DFCOUNT 0x00a4 #define VIP_DFRESTART 0x00a8 #define VIP_DHRESTART 0x00ac #define VIP_DVRESTART 0x00b0 #define VIP_SYNC_SIZE 0x00b4 #define VIP_TV_PLL_FINE_CNTL 0x00b8 #define VIP_CRT_PLL_FINE_CNTL 0x00bc #define VIP_TV_PLL_CNTL 0x00c0 #define VIP_CRT_PLL_CNTL 0x00c4 #define VIP_PLL_CNTL0 0x00c8 #define VIP_PLL_TEST_CNTL 0x00cc #define VIP_CLOCK_SEL_CNTL 0x00d0 #define VIP_VIN_PLL_CNTL 0x00d4 #define VIP_VIN_PLL_FINE_CNTL 0x00d8 #define VIP_AUD_PLL_CNTL 0x00e0 #define VIP_AUD_PLL_FINE_CNTL 0x00e4 #define VIP_AUD_CLK_DIVIDERS 0x00e8 #define VIP_AUD_DTO_INCREMENTS 0x00ec #define VIP_L54_PLL_CNTL 0x00f0 #define VIP_L54_PLL_FINE_CNTL 0x00f4 #define VIP_L54_DTO_INCREMENTS 0x00f8 #define VIP_PLL_CNTL1 0x00fc #define VIP_FRAME_LOCK_CNTL 0x0100 #define VIP_SYNC_LOCK_CNTL 0x0104 #define VIP_TVO_SYNC_PAT_ACCUM 0x0108 #define VIP_TVO_SYNC_THRESHOLD 0x010c #define VIP_TVO_SYNC_PAT_EXPECT 0x0110 #define VIP_DELAY_ONE_MAP_A 0x0114 #define VIP_DELAY_ONE_MAP_B 0x0118 #define VIP_DELAY_ZERO_MAP_A 0x011c #define VIP_DELAY_ZERO_MAP_B 0x0120 #define VIP_TVO_DATA_DELAY_A 0x0140 #define VIP_TVO_DATA_DELAY_B 0x0144 #define VIP_HOST_READ_DATA 0x0180 #define VIP_HOST_WRITE_DATA 0x0184 #define VIP_HOST_RD_WT_CNTL 0x0188 #define VIP_VSCALER_CNTL1 0x01c0 #define VIP_TIMING_CNTL 0x01c4 #define VIP_VSCALER_CNTL2 0x01c8 #define VIP_Y_FALL_CNTL 0x01cc #define VIP_Y_RISE_CNTL 0x01d0 #define VIP_Y_SAW_TOOTH_CNTL 0x01d4 #define VIP_UPSAMP_AND_GAIN_CNTL 0x01e0 #define VIP_GAIN_LIMIT_SETTINGS 0x01e4 #define VIP_LINEAR_GAIN_SETTINGS 0x01e8 #define VIP_MODULATOR_CNTL1 0x0200 #define VIP_MODULATOR_CNTL2 0x0204 #define VIP_MV_MODE_CNTL 0x0208 #define VIP_MV_STRIPE_CNTL 0x020c #define VIP_MV_LEVEL_CNTL1 0x0210 #define VIP_MV_LEVEL_CNTL2 0x0214 #define VIP_PRE_DAC_MUX_CNTL 0x0240 #define VIP_TV_DAC_CNTL 0x0280 #define VIP_CRC_CNTL 0x02c0 #define VIP_VIDEO_PORT_SIG 0x02c4 #define VIP_VBI_CC_CNTL 0x02c8 #define VIP_VBI_EDS_CNTL 0x02cc #define VIP_VBI_20BIT_CNTL 0x02d0 #define VIP_VBI_DTO_CNTL 0x02d4 #define VIP_VBI_LEVEL_CNTL 0x02d8 #define VIP_UV_ADR 0x0300 #define VIP_MV_STATUS 0x0330 #define VIP_UPSAMP_COEFF0_0 0x0340 #define VIP_UPSAMP_COEFF0_1 0x0344 #define VIP_UPSAMP_COEFF0_2 0x0348 #define VIP_UPSAMP_COEFF1_0 0x034c #define VIP_UPSAMP_COEFF1_1 0x0350 #define VIP_UPSAMP_COEFF1_2 0x0354 #define VIP_UPSAMP_COEFF2_0 0x0358 #define VIP_UPSAMP_COEFF2_1 0x035c #define VIP_UPSAMP_COEFF2_2 0x0360 #define VIP_UPSAMP_COEFF3_0 0x0364 #define VIP_UPSAMP_COEFF3_1 0x0368 #define VIP_UPSAMP_COEFF3_2 0x036c #define VIP_UPSAMP_COEFF4_0 0x0370 #define VIP_UPSAMP_COEFF4_1 0x0374 #define VIP_UPSAMP_COEFF4_2 0x0378 #define VIP_TV_DTO_INCREMENTS 0x0390 #define VIP_CRT_DTO_INCREMENTS 0x0394 #define VIP_VSYNC_DIFF_CNTL 0x03a0 #define VIP_VSYNC_DIFF_LIMITS 0x03a4 #define VIP_VSYNC_DIFF_RD_DATA 0x03a8 #define VIP_SCALER_IN_WINDOW 0x0618 #define VIP_SCALER_OUT_WINDOW 0x061c #define VIP_H_SCALER_CONTROL 0x0600 #define VIP_V_SCALER_CONTROL 0x0604 #define VIP_V_DEINTERLACE_CONTROL 0x0608 #define VIP_VBI_SCALER_CONTROL 0x060c #define VIP_DVS_PORT_CTRL 0x0610 #define VIP_DVS_PORT_READBACK 0x0614 #define VIP_FIFOA_CONFIG 0x0800 #define VIP_FIFOB_CONFIG 0x0804 #define VIP_FIFOC_CONFIG 0x0808 #define VIP_SPDIF_PORT_CNTL 0x080c #define VIP_SPDIF_CHANNEL_STAT 0x0810 #define VIP_SPDIF_AC3_PREAMBLE 0x0814 #define VIP_I2S_TRANSMIT_CNTL 0x0818 #define VIP_I2S_RECEIVE_CNTL 0x081c #define VIP_SPDIF_TX_CNT_REG 0x0820 #define VIP_IIS_TX_CNT_REG 0x0824 /* Status defines */ #define VIP_BUSY 0 #define VIP_IDLE 1 #define VIP_RESET 2 #define VIPH_TIMEOUT_STAT__VIPH_REG_STAT 0x00000010 #define VIPH_TIMEOUT_STAT__VIPH_REG_AK 0x00000010 #define VIPH_TIMEOUT_STAT__VIPH_REGR_DIS 0x01000000 #define TEST_DEBUG_CNTL__TEST_DEBUG_OUT_EN 0x00000001 #define RT_ATI_ID 0x4D541002 /* Register/Field values: */ #define RT_COMP0 0x0 #define RT_COMP1 0x1 #define RT_COMP2 0x2 #define RT_YF_COMP3 0x3 #define RT_YR_COMP3 0x4 #define RT_YCF_COMP4 0x5 #define RT_YCR_COMP4 0x6 /* Video standard defines */ #define RT_NTSC 0x0 #define RT_PAL 0x1 #define RT_SECAM 0x2 #define extNONE 0x0000 #define extNTSC 0x0100 #define extRsvd 0x0200 #define extPAL 0x0300 #define extPAL_M 0x0400 #define extPAL_N 0x0500 #define extSECAM 0x0600 #define extPAL_NCOMB 0x0700 #define extNTSC_J 0x0800 #define extNTSC_443 0x0900 #define extPAL_BGHI 0x0A00 #define extPAL_60 0x0B00 /* these are used in MSP3430 */ #define extPAL_DK1 0x0C00 #define extPAL_AUTO 0x0D00 #define RT_FREF_2700 6 #define RT_FREF_2950 5 #define RT_COMPOSITE 0x0 #define RT_SVIDEO 0x1 #define RT_NORM_SHARPNESS 0x03 #define RT_HIGH_SHARPNESS 0x0F #define RT_HUE_PAL_DEF 0x00 #define RT_DECINTERLACED 0x1 #define RT_DECNONINTERLACED 0x0 #define NTSC_LINES 525 #define PAL_SECAM_LINES 625 #define RT_ASYNC_ENABLE 0x0 #define RT_ASYNC_DISABLE 0x1 #define RT_ASYNC_RESET 0x1 #define RT_VINRST_ACTIVE 0x0 #define RT_VINRST_RESET 0x1 #define RT_L54RST_RESET 0x1 #define RT_REF_CLK 0x0 #define RT_PLL_VIN_CLK 0x1 #define RT_VIN_ASYNC_RST 0x20 #define RT_DVS_ASYNC_RST 0x80 #define RT_ADC_ENABLE 0x0 #define RT_ADC_DISABLE 0x1 #define RT_DVSDIR_IN 0x0 #define RT_DVSDIR_OUT 0x1 #define RT_DVSCLK_HIGH 0x0 #define RT_DVSCLK_LOW 0x1 #define RT_DVSCLK_SEL_8FS 0x0 #define RT_DVSCLK_SEL_27MHZ 0x1 #define RT_DVS_CONTSTREAM 0x1 #define RT_DVS_NONCONTSTREAM 0x0 #define RT_DVSDAT_HIGH 0x0 #define RT_DVSDAT_LOW 0x1 #define RT_ADC_CNTL_DEFAULT 0x03252338 /* COMB_CNTL0 FILTER SETTINGS FOR DIFFERENT STANDARDS: */ #define RT_NTSCM_COMB_CNTL0_COMPOSITE 0x09438090 #define RT_NTSCM_COMB_CNTL0_SVIDEO 0x48540000 #define RT_PAL_COMB_CNTL0_COMPOSITE 0x09438090 #define RT_PAL_COMB_CNTL0_SVIDEO 0x40348090 #define RT_SECAM_COMB_CNTL0_COMPOSITE 0xD0108090 /* instead of orig 0xD0088090 - eric*/ #define RT_SECAM_COMB_CNTL0_SVIDEO 0x50148090 #define RT_PALN_COMB_CNTL0_COMPOSITE 0x09438090 #define RT_PALN_COMB_CNTL0_SVIDEO 0x40348090 #define RT_PALM_COMB_CNTL0_COMPOSITE 0x09438090 #define RT_PALM_COMB_CNTL0_SVIDEO 0x40348090 /* End of filter settings. */ /* COMB_CNTL1 FILTER SETTINGS FOR DIFFERENT STANDARDS: */ #define RT_NTSCM_COMB_CNTL1_COMPOSITE 0x00000010 #define RT_NTSCM_COMB_CNTL1_SVIDEO 0x00000081 #define RT_PAL_COMB_CNTL1_COMPOSITE 0x00000010 #define RT_PAL_COMB_CNTL1_SVIDEO 0x000000A1 #define RT_SECAM_COMB_CNTL1_COMPOSITE 0x00000091 #define RT_SECAM_COMB_CNTL1_SVIDEO 0x00000081 #define RT_PALN_COMB_CNTL1_COMPOSITE 0x00000010 #define RT_PALN_COMB_CNTL1_SVIDEO 0x000000A1 #define RT_PALM_COMB_CNTL1_COMPOSITE 0x00000010 #define RT_PALM_COMB_CNTL1_SVIDEO 0x000000A1 /* End of filter settings. */ /* COMB_CNTL2 FILTER SETTINGS FOR DIFFERENT STANDARDS: */ #define RT_NTSCM_COMB_CNTL2_COMPOSITE 0x16161010 #define RT_NTSCM_COMB_CNTL2_SVIDEO 0xFFFFFFFF #define RT_PAL_COMB_CNTL2_COMPOSITE 0x06080102 /* instead of 0x16161010 - Ivo */ #define RT_PAL_COMB_CNTL2_SVIDEO 0x06080102 #define RT_SECAM_COMB_CNTL2_COMPOSITE 0xffffffff /* instead of 0x06080102 - eric */ #define RT_SECAM_COMB_CNTL2_SVIDEO 0x06080102 #define RT_PALN_COMB_CNTL2_COMPOSITE 0x06080102 #define RT_PALN_COMB_CNTL2_SVIDEO 0x06080102 #define RT_PALM_COMB_CNTL2_COMPOSITE 0x06080102 #define RT_PALM_COMB_CNTL2_SVIDEO 0x06080102 /* End of filter settings. */ /* COMB_LINE_LENGTH FILTER SETTINGS FOR DIFFERENT STANDARDS: */ #define RT_NTSCM_COMB_LENGTH_COMPOSITE 0x0718038A #define RT_NTSCM_COMB_LENGTH_SVIDEO 0x0718038A #define RT_PAL_COMB_LENGTH_COMPOSITE 0x08DA046B #define RT_PAL_COMB_LENGTH_SVIDEO 0x08DA046B #define RT_SECAM_COMB_LENGTH_COMPOSITE 0x08DA046A #define RT_SECAM_COMB_LENGTH_SVIDEO 0x08DA046A #define RT_PALN_COMB_LENGTH_COMPOSITE 0x07260391 #define RT_PALN_COMB_LENGTH_SVIDEO 0x07260391 #define RT_PALM_COMB_LENGTH_COMPOSITE 0x07160389 #define RT_PALM_COMB_LENGTH_SVIDEO 0x07160389 /* End of filter settings. */ /* LP_AGC_CLAMP_CNTL0 */ #define RT_NTSCM_SYNCTIP_REF0 0x00000037 #define RT_NTSCM_SYNCTIP_REF1 0x00000029 #define RT_NTSCM_CLAMP_REF 0x0000003B #define RT_NTSCM_PEAKWHITE 0x000000FF #define RT_NTSCM_VBI_PEAKWHITE 0x000000C2 #define RT_NTSCM_WPA_THRESHOLD 0x00000406 #define RT_NTSCM_WPA_TRIGGER_LO 0x000000B3 #define RT_NTSCM_WPA_TRIGGER_HIGH 0x0000021B #define RT_NTSCM_LP_LOCKOUT_START 0x00000206 #define RT_NTSCM_LP_LOCKOUT_END 0x00000021 #define RT_NTSCM_CH_DTO_INC 0x00400000 #define RT_NTSCM_CH_PLL_SGAIN 0x00000001 #define RT_NTSCM_CH_PLL_FGAIN 0x00000002 #define RT_NTSCM_CR_BURST_GAIN 0x0000007A #define RT_NTSCM_CB_BURST_GAIN 0x000000AC #define RT_NTSCM_CH_HEIGHT 0x000000CD #define RT_NTSCM_CH_KILL_LEVEL 0x000000C0 #define RT_NTSCM_CH_AGC_ERROR_LIM 0x00000002 #define RT_NTSCM_CH_AGC_FILTER_EN 0x00000000 #define RT_NTSCM_CH_AGC_LOOP_SPEED 0x00000000 #define RT_NTSCM_CRDR_ACTIVE_GAIN 0x0000007A #define RT_NTSCM_CBDB_ACTIVE_GAIN 0x000000AC #define RT_NTSCM_VERT_LOCKOUT_START 0x00000207 #define RT_NTSCM_VERT_LOCKOUT_END 0x0000000E #define RT_NTSCJ_SYNCTIP_REF0 0x00000004 #define RT_NTSCJ_SYNCTIP_REF1 0x00000012 #define RT_NTSCJ_CLAMP_REF 0x0000003B #define RT_NTSCJ_PEAKWHITE 0x000000CB #define RT_NTSCJ_VBI_PEAKWHITE 0x000000C2 #define RT_NTSCJ_WPA_THRESHOLD 0x000004B0 #define RT_NTSCJ_WPA_TRIGGER_LO 0x000000B4 #define RT_NTSCJ_WPA_TRIGGER_HIGH 0x0000021C #define RT_NTSCJ_LP_LOCKOUT_START 0x00000206 #define RT_NTSCJ_LP_LOCKOUT_END 0x00000021 #define RT_NTSCJ_CR_BURST_GAIN 0x00000071 #define RT_NTSCJ_CB_BURST_GAIN 0x0000009F #define RT_NTSCJ_CH_HEIGHT 0x000000CD #define RT_NTSCJ_CH_KILL_LEVEL 0x000000C0 #define RT_NTSCJ_CH_AGC_ERROR_LIM 0x00000002 #define RT_NTSCJ_CH_AGC_FILTER_EN 0x00000000 #define RT_NTSCJ_CH_AGC_LOOP_SPEED 0x00000000 #define RT_NTSCJ_CRDR_ACTIVE_GAIN 0x00000071 #define RT_NTSCJ_CBDB_ACTIVE_GAIN 0x0000009F #define RT_NTSCJ_VERT_LOCKOUT_START 0x00000207 #define RT_NTSCJ_VERT_LOCKOUT_END 0x0000000E #define RT_PAL_SYNCTIP_REF0 0x37 /* instead of 0x00000004 - Ivo */ #define RT_PAL_SYNCTIP_REF1 0x26 /* instead of 0x0000000F - Ivo */ #define RT_PAL_CLAMP_REF 0x0000003B #define RT_PAL_PEAKWHITE 0xFF /* instead of 0x000000C1 - Ivo */ #define RT_PAL_VBI_PEAKWHITE 0xC6 /* instead of 0x000000C7 - Ivo */ #define RT_PAL_WPA_THRESHOLD 0x59C /* instead of 0x000006A4 - Ivo */ #define RT_PAL_WPA_TRIGGER_LO 0x00000096 #define RT_PAL_WPA_TRIGGER_HIGH 0x000001C2 #define RT_PAL_LP_LOCKOUT_START 0x00000263 #define RT_PAL_LP_LOCKOUT_END 0x0000002C #define RT_PAL_CH_DTO_INC 0x00400000 #define RT_PAL_CH_PLL_SGAIN 1 /* instead of 0x00000002 - Ivo */ #define RT_PAL_CH_PLL_FGAIN 2 /* instead of 0x00000001 - Ivo */ #define RT_PAL_CR_BURST_GAIN 0x0000007A #define RT_PAL_CB_BURST_GAIN 0x000000AB #define RT_PAL_CH_HEIGHT 0x0000009C #define RT_PAL_CH_KILL_LEVEL 4 /* instead of 0x00000090 - Ivo */ #define RT_PAL_CH_AGC_ERROR_LIM 1 /* instead of 0x00000002 - Ivo */ #define RT_PAL_CH_AGC_FILTER_EN 1 /* instead of 0x00000000 - Ivo */ #define RT_PAL_CH_AGC_LOOP_SPEED 0x00000000 #define RT_PAL_CRDR_ACTIVE_GAIN 0x9E /* instead of 0x0000007A - Ivo */ #define RT_PAL_CBDB_ACTIVE_GAIN 0xDF /* instead of 0x000000AB - Ivo */ #define RT_PAL_VERT_LOCKOUT_START 0x00000269 #define RT_PAL_VERT_LOCKOUT_END 0x00000012 #define RT_SECAM_SYNCTIP_REF0 0x37 /* instead of 0x00000004 - Ivo */ #define RT_SECAM_SYNCTIP_REF1 0x26 /* instead of 0x0000000F - Ivo */ #define RT_SECAM_CLAMP_REF 0x0000003B #define RT_SECAM_PEAKWHITE 0xFF /* instead of 0x000000C1 - Ivo */ #define RT_SECAM_VBI_PEAKWHITE 0xC6 /* instead of 0x000000C7 - Ivo */ #define RT_SECAM_WPA_THRESHOLD 0x57A /* instead of 0x6A4, instead of 0x0000059C is Ivo's value , -eric*/ #define RT_SECAM_WPA_TRIGGER_LO 0x96 /* instead of 0x0000026B - eric */ #define RT_SECAM_WPA_TRIGGER_HIGH 0x000001C2 #define RT_SECAM_LP_LOCKOUT_START 0x263 /* instead of 0x0000026B - eric */ #define RT_SECAM_LP_LOCKOUT_END 0x2b /* instead of 0x0000002C -eric */ #define RT_SECAM_CH_DTO_INC 0x003E7A28 #define RT_SECAM_CH_PLL_SGAIN 0x4 /* instead of 0x00000006 -Volodya */ #define RT_SECAM_CH_PLL_FGAIN 0x7 /* instead of 0x00000006 -Volodya */ #define RT_SECAM_CR_BURST_GAIN 0x1FF /* instead of 0x00000200 -Volodya */ #define RT_SECAM_CB_BURST_GAIN 0x1FF /* instead of 0x00000200 -Volodya */ #define RT_SECAM_CH_HEIGHT 0x00000066 #define RT_SECAM_CH_KILL_LEVEL 0x00000060 #define RT_SECAM_CH_AGC_ERROR_LIM 0x00000003 #define RT_SECAM_CH_AGC_FILTER_EN 0x00000000 #define RT_SECAM_CH_AGC_LOOP_SPEED 0x00000000 #define RT_SECAM_CRDR_ACTIVE_GAIN 0x11B /* instead of 0x00000200 - eric */ #define RT_SECAM_CBDB_ACTIVE_GAIN 0x15A /* instead of 0x00000200 - eric */ #define RT_SECAM_VERT_LOCKOUT_START 0x00000269 #define RT_SECAM_VERT_LOCKOUT_END 0x00000012 #define RT_PAL_VS_FIELD_BLANK_END 0x2A /* instead of 0x0000002C - Ivo*/ #define RT_NTSCM_VS_FIELD_BLANK_END 0x0000000A #define RT_NTSCM_FIELD_IDLOCATION 0x00000105 #define RT_PAL_FIELD_IDLOCATION 0x00000137 #define RT_NTSCM_H_ACTIVE_START 0x00000070 #define RT_NTSCM_H_ACTIVE_END 0x00000363 #define RT_PAL_H_ACTIVE_START 0x0000009A #define RT_PAL_H_ACTIVE_END 0x00000439 #define RT_NTSCM_V_ACTIVE_START ((22-4)*2+1) #define RT_NTSCM_V_ACTIVE_END ((22+240-4)*2+1) #define RT_PAL_V_ACTIVE_START 0x2E /* instead of 0x00000023 (Same as SECAM) - Ivo */ #define RT_PAL_V_ACTIVE_END 0x269 /* instead of 0x00000262 - Ivo */ /* VBI */ #define RT_NTSCM_H_VBI_WIND_START 0x00000049 #define RT_NTSCM_H_VBI_WIND_END 0x00000366 #define RT_PAL_H_VBI_WIND_START 0x00000084 #define RT_PAL_H_VBI_WIND_END 0x0000041F #define RT_NTSCM_V_VBI_WIND_START fld_V_VBI_WIND_START_def #define RT_NTSCM_V_VBI_WIND_END fld_V_VBI_WIND_END_def #define RT_PAL_V_VBI_WIND_START 0x8 /* instead of 0x0000000B - Ivo */ #define RT_PAL_V_VBI_WIND_END 0x2D /* instead of 0x00000022 - Ivo */ #define RT_VBI_CAPTURE_EN 0x00000001 /* Enable */ #define RT_VBI_CAPTURE_DIS 0x00000000 /* Disable */ #define RT_RAW_CAPTURE 0x00000002 /* Use raw Video Capture. */ #define RT_NTSCM_VSYNC_INT_TRIGGER 0x2AA #define RT_PALSEM_VSYNC_INT_TRIGGER 0x353 #define RT_NTSCM_VSYNC_INT_HOLD 0x17 #define RT_PALSEM_VSYNC_INT_HOLD 0x1C #define RT_NTSCM_VS_FIELD_BLANK_START 0x206 #define RT_PALSEM_VS_FIELD_BLANK_START 0x26D /* instead of 0x26C - Ivo */ #define RT_FIELD_FLIP_EN 0x4 #define RT_V_FIELD_FLIP_INVERTED 0x2000 #define RT_NTSCM_H_IN_START 0x70 #define RT_PAL_H_IN_START 154 /* instead of 144 - Ivo */ #define RT_SECAM_H_IN_START 0x91 /* instead of 0x9A, Ivo value is 154, instead of 144 - Volodya, - eric */ #define RT_NTSC_H_ACTIVE_SIZE 744 #define RT_PAL_H_ACTIVE_SIZE 928 /* instead of 927 - Ivo */ #define RT_SECAM_H_ACTIVE_SIZE 932 /* instead of 928, instead of 927 - Ivo, - eric */ #define RT_NTSCM_V_IN_START (0x23) #define RT_PAL_V_IN_START 44 /* instead of (45-6) - Ivo */ #define RT_SECAM_V_IN_START 0x2C /* instead of (45-6) - Volodya */ #define RT_NTSCM_V_ACTIVE_SIZE 480 #define RT_PAL_V_ACTIVE_SIZE 572 /* instead of 575 - Ivo */ #define RT_SECAM_V_ACTIVE_SIZE 570 /* instead of 572, instead of 575 - Ivo, - eric */ #define RT_NTSCM_WIN_CLOSE_LIMIT 0x4D #define RT_NTSCJ_WIN_CLOSE_LIMIT 0x4D #define RT_NTSC443_WIN_CLOSE_LIMIT 0x5F #define RT_PALM_WIN_CLOSE_LIMIT 0x4D #define RT_PALN_WIN_CLOSE_LIMIT 0x5F #define RT_SECAM_WIN_CLOSE_LIMIT 0xC7 /* instead of 0x5F - eric */ #define RT_NTSCM_VS_FIELD_BLANK_START 0x206 #define RT_NTSCM_HS_PLL_SGAIN 0x5 #define RT_NTSCM_HS_PLL_FGAIN 0x7 #define RT_NTSCM_H_OUT_WIND_WIDTH 0x2F4 #define RT_NTSCM_V_OUT_WIND_HEIGHT 0xF0 #define TV 0x1 #define LINEIN 0x2 #define MUTE 0x3 #define DEC_COMPOSITE 0 #define DEC_SVIDEO 1 #define DEC_TUNER 2 #define DEC_NTSC 0 #define DEC_PAL 1 #define DEC_SECAM 2 #define DEC_NTSC_J 8 #define DEC_SMOOTH 0 #define DEC_SHARP 1 /* RT Register Field Defaults: */ #define fld_tmpReg1_def 0x00000000 #define fld_tmpReg2_def 0x00000001 #define fld_tmpReg3_def 0x00000002 #define fld_LP_CONTRAST_def 0x0000006e #define fld_LP_BRIGHTNESS_def 0x00003ff0 #define fld_CP_HUE_CNTL_def 0x00000000 #define fld_LUMA_FILTER_def 0x00000001 #define fld_H_SCALE_RATIO_def 0x00010000 #define fld_H_SHARPNESS_def 0x00000000 #define fld_V_SCALE_RATIO_def 0x00000800 #define fld_V_DEINTERLACE_ON_def 0x00000001 #define fld_V_BYPSS_def 0x00000000 #define fld_V_DITHER_ON_def 0x00000001 #define fld_EVENF_OFFSET_def 0x00000000 #define fld_ODDF_OFFSET_def 0x00000000 #define fld_INTERLACE_DETECTED_def 0x00000000 #define fld_VS_LINE_COUNT_def 0x00000000 #define fld_VS_DETECTED_LINES_def 0x00000000 #define fld_VS_ITU656_VB_def 0x00000000 #define fld_VBI_CC_DATA_def 0x00000000 #define fld_VBI_CC_WT_def 0x00000000 #define fld_VBI_CC_WT_ACK_def 0x00000000 #define fld_VBI_CC_HOLD_def 0x00000000 #define fld_VBI_DECODE_EN_def 0x00000000 #define fld_VBI_CC_DTO_P_def 0x00001802 #define fld_VBI_20BIT_DTO_P_def 0x0000155c #define fld_VBI_CC_LEVEL_def 0x0000003f #define fld_VBI_20BIT_LEVEL_def 0x00000059 #define fld_VBI_CLK_RUNIN_GAIN_def 0x0000010f #define fld_H_VBI_WIND_START_def 0x00000041 #define fld_H_VBI_WIND_END_def 0x00000366 #define fld_V_VBI_WIND_START_def 0x0D #define fld_V_VBI_WIND_END_def 0x24 #define fld_VBI_20BIT_DATA0_def 0x00000000 #define fld_VBI_20BIT_DATA1_def 0x00000000 #define fld_VBI_20BIT_WT_def 0x00000000 #define fld_VBI_20BIT_WT_ACK_def 0x00000000 #define fld_VBI_20BIT_HOLD_def 0x00000000 #define fld_VBI_CAPTURE_ENABLE_def 0x00000000 #define fld_VBI_EDS_DATA_def 0x00000000 #define fld_VBI_EDS_WT_def 0x00000000 #define fld_VBI_EDS_WT_ACK_def 0x00000000 #define fld_VBI_EDS_HOLD_def 0x00000000 #define fld_VBI_SCALING_RATIO_def 0x00010000 #define fld_VBI_ALIGNER_ENABLE_def 0x00000000 #define fld_H_ACTIVE_START_def 0x00000070 #define fld_H_ACTIVE_END_def 0x000002f0 #define fld_V_ACTIVE_START_def ((22-4)*2+1) #define fld_V_ACTIVE_END_def ((22+240-4)*2+2) #define fld_CH_HEIGHT_def 0x000000CD #define fld_CH_KILL_LEVEL_def 0x000000C0 #define fld_CH_AGC_ERROR_LIM_def 0x00000002 #define fld_CH_AGC_FILTER_EN_def 0x00000000 #define fld_CH_AGC_LOOP_SPEED_def 0x00000000 #define fld_HUE_ADJ_def 0x00000000 #define fld_STANDARD_SEL_def 0x00000000 #define fld_STANDARD_YC_def 0x00000000 #define fld_ADC_PDWN_def 0x00000001 #define fld_INPUT_SELECT_def 0x00000000 #define fld_ADC_PREFLO_def 0x00000003 #define fld_H_SYNC_PULSE_WIDTH_def 0x00000000 #define fld_HS_GENLOCKED_def 0x00000000 #define fld_HS_SYNC_IN_WIN_def 0x00000000 #define fld_VIN_ASYNC_RST_def 0x00000001 #define fld_DVS_ASYNC_RST_def 0x00000001 /* Vendor IDs: */ #define fld_VIP_VENDOR_ID_def 0x00001002 #define fld_VIP_DEVICE_ID_def 0x00004d54 #define fld_VIP_REVISION_ID_def 0x00000001 /* AGC Delay Register */ #define fld_BLACK_INT_START_def 0x00000031 #define fld_BLACK_INT_LENGTH_def 0x0000000f #define fld_UV_INT_START_def 0x0000003b #define fld_U_INT_LENGTH_def 0x0000000f #define fld_V_INT_LENGTH_def 0x0000000f #define fld_CRDR_ACTIVE_GAIN_def 0x0000007a #define fld_CBDB_ACTIVE_GAIN_def 0x000000ac #define fld_DVS_DIRECTION_def 0x00000000 #define fld_DVS_VBI_CARD8_SWAP_def 0x00000000 #define fld_DVS_CLK_SELECT_def 0x00000000 #define fld_CONTINUOUS_STREAM_def 0x00000000 #define fld_DVSOUT_CLK_DRV_def 0x00000001 #define fld_DVSOUT_DATA_DRV_def 0x00000001 #define fld_COMB_CNTL0_def 0x09438090 #define fld_COMB_CNTL1_def 0x00000010 #define fld_COMB_CNTL2_def 0x16161010 #define fld_COMB_LENGTH_def 0x0718038A #define fld_SYNCTIP_REF0_def 0x00000037 #define fld_SYNCTIP_REF1_def 0x00000029 #define fld_CLAMP_REF_def 0x0000003B #define fld_AGC_PEAKWHITE_def 0x000000FF #define fld_VBI_PEAKWHITE_def 0x000000D2 #define fld_WPA_THRESHOLD_def 0x000003B0 #define fld_WPA_TRIGGER_LO_def 0x000000B4 #define fld_WPA_TRIGGER_HIGH_def 0x0000021C #define fld_LOCKOUT_START_def 0x00000206 #define fld_LOCKOUT_END_def 0x00000021 #define fld_CH_DTO_INC_def 0x00400000 #define fld_PLL_SGAIN_def 0x00000001 #define fld_PLL_FGAIN_def 0x00000002 #define fld_CR_BURST_GAIN_def 0x0000007a #define fld_CB_BURST_GAIN_def 0x000000ac #define fld_VERT_LOCKOUT_START_def 0x00000207 #define fld_VERT_LOCKOUT_END_def 0x0000000E #define fld_H_IN_WIND_START_def 0x00000070 #define fld_V_IN_WIND_START_def 0x00000027 #define fld_H_OUT_WIND_WIDTH_def 0x000002f4 #define fld_V_OUT_WIND_WIDTH_def 0x000000f0 #define fld_HS_LINE_TOTAL_def 0x0000038E #define fld_MIN_PULSE_WIDTH_def 0x0000002F #define fld_MAX_PULSE_WIDTH_def 0x00000046 #define fld_WIN_CLOSE_LIMIT_def 0x0000004D #define fld_WIN_OPEN_LIMIT_def 0x000001B7 #define fld_VSYNC_INT_TRIGGER_def 0x000002AA #define fld_VSYNC_INT_HOLD_def 0x0000001D #define fld_VIN_M0_def 0x00000039 #define fld_VIN_N0_def 0x0000014c #define fld_MNFLIP_EN_def 0x00000000 #define fld_VIN_P_def 0x00000006 #define fld_REG_CLK_SEL_def 0x00000000 #define fld_VIN_M1_def 0x00000000 #define fld_VIN_N1_def 0x00000000 #define fld_VIN_DRIVER_SEL_def 0x00000000 #define fld_VIN_MNFLIP_REQ_def 0x00000000 #define fld_VIN_MNFLIP_DONE_def 0x00000000 #define fld_TV_LOCK_TO_VIN_def 0x00000000 #define fld_TV_P_FOR_WINCLK_def 0x00000004 #define fld_VINRST_def 0x00000001 #define fld_VIN_CLK_SEL_def 0x00000000 #define fld_VS_FIELD_BLANK_START_def 0x00000206 #define fld_VS_FIELD_BLANK_END_def 0x0000000A /*#define fld_VS_FIELD_IDLOCATION_def 0x00000105 */ #define fld_VS_FIELD_IDLOCATION_def 0x00000001 #define fld_VS_FRAME_TOTAL_def 0x00000217 #define fld_SYNC_TIP_START_def 0x00000372 #define fld_SYNC_TIP_LENGTH_def 0x0000000F #define fld_GAIN_FORCE_DATA_def 0x00000000 #define fld_GAIN_FORCE_EN_def 0x00000000 #define fld_I_CLAMP_SEL_def 0x00000003 #define fld_I_AGC_SEL_def 0x00000001 #define fld_EXT_CLAMP_CAP_def 0x00000001 #define fld_EXT_AGC_CAP_def 0x00000001 #define fld_DECI_DITHER_EN_def 0x00000001 #define fld_ADC_PREFHI_def 0x00000000 #define fld_ADC_CH_GAIN_SEL_def 0x00000001 #define fld_HS_PLL_SGAIN_def 0x00000003 #define fld_NREn_def 0x00000000 #define fld_NRGainCntl_def 0x00000000 #define fld_NRBWTresh_def 0x00000000 #define fld_NRGCTresh_def 0x00000000 #define fld_NRCoefDespeclMode_def 0x00000000 #define fld_GPIO_5_OE_def 0x00000000 #define fld_GPIO_6_OE_def 0x00000000 #define fld_GPIO_5_OUT_def 0x00000000 #define fld_GPIO_6_OUT_def 0x00000000 /* End of field default values. */ #endif /* RADEON_H */ xine-lib-1.2/contrib/vidix/drivers/genfb_vid.c0000644000175000017500000000672614647725152017227 0ustar meme#include #include #include #include #include #include #include #include "../vidix.h" #include "../fourcc.h" #include "../../libdha/libdha.h" #include "../../libdha/pci_ids.h" #include "../../libdha/pci_names.h" #define DEMO_DRIVER 1 #define VIDIX_STATIC genfb_ #define GENFB_MSG "[genfb-demo-driver] " #if 0 /* these are unused. remove? */ static int fd; static void *mmio_base = 0; static void *mem_base = 0; static int32_t overlay_offset = 0; static uint32_t ram_size = 0; #endif static int probed = 0; /* VIDIX exports */ static vidix_capability_t genfb_cap = { "General Framebuffer", "alex", TYPE_OUTPUT, { 0, 0, 0, 0 }, 2048, 2048, 4, 4, -1, FLAG_UPSCALER|FLAG_DOWNSCALER, -1, -1, { 0, 0, 0, 0 } }; unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } int VIDIX_NAME(vixProbe)(int verbose,int force) { #if 0 int err = 0; #ifdef DEMO_DRIVER err = ENOSYS; #endif printf(GENFB_MSG"probe\n"); fd = open("/dev/fb0", O_RDWR); if (fd < 0) { printf(GENFB_MSG"Error occured durint open: %s\n", strerror(errno)); err = errno; } probed = 1; return(err); #else pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; err = pci_scan(lst,&num_pci); if(err) { printf(GENFB_MSG"Error occured during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0;ifourcc); to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP | VID_DEPTH_15BPP | VID_DEPTH_16BPP | VID_DEPTH_24BPP | VID_DEPTH_32BPP; to->flags = 0; return(0); } int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { printf(GENFB_MSG"config playback\n"); info->num_frames = 2; info->frame_size = info->src.w*info->src.h+(info->src.w*info->src.h)/2; info->dest.pitch.y = 32; info->dest.pitch.u = info->dest.pitch.v = 16; info->offsets[0] = 0; info->offsets[1] = info->frame_size; info->offset.y = 0; info->offset.v = ((info->src.w+31) & ~31) * info->src.h; info->offset.u = info->offset.v+((info->src.w+31) & ~31) * info->src.h/4; info->dga_addr = malloc(info->num_frames*info->frame_size); printf(GENFB_MSG"frame_size: %d, dga_addr: %p\n", info->frame_size, info->dga_addr); return(0); } int VIDIX_NAME(vixPlaybackOn)(void) { printf(GENFB_MSG"playback on\n"); return(0); } int VIDIX_NAME(vixPlaybackOff)(void) { printf(GENFB_MSG"playback off\n"); return(0); } int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { printf(GENFB_MSG"frameselect: %d\n", frame); return(0); } xine-lib-1.2/contrib/vidix/drivers/Makefile.am0000644000175000017500000000273014647725152017163 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) AM_CPPFLAGS += -I$(top_srcdir)/contrib/vidix \ -I$(top_srcdir)/contrib/libdha -I$(top_builddir)/contrib/libdha AM_LDFLAGS = -avoid-version -module EXTRA_DIST = genfb_vid.c noinst_HEADERS = mach64.h glint_regs.h pm3_regs.h radeon.h savage_regs.h \ cyberblade_regs.h unichrome_regs.h sis_defs.h sis_regs.h BUILT_SOURCES = $(top_builddir)/contrib/libdha/pci_ids.h \ $(top_builddir)/contrib/libdha/pci_names.h $(BUILT_SOURCES): $(MAKE) -C $(dir $@) $(notdir $@) vidix_LTLIBRARIES = \ mach64_vid.la \ mga_crtc2_vid.la \ mga_vid.la \ pm2_vid.la \ pm3_vid.la \ radeon_vid.la \ rage128_vid.la \ cyberblade_vid.la \ unichrome_vid.la \ nvidia_vid.la \ sis_vid.la \ savage_vid.la cyberblade_vid_la_SOURCES = cyberblade_vid.c mach64_vid_la_SOURCES = mach64_vid.c mga_crtc2_vid_la_SOURCES = mga_vid.c mga_crtc2_vid_la_LIBADD = -lm mga_crtc2_vid_la_CPPFLAGS = $(AM_CPPFLAGS) -DCRTC2 mga_vid_la_SOURCES = mga_vid.c mga_vid_la_LIBADD = -lm nvidia_vid_la_SOURCES = nvidia_vid.c pm2_vid_la_SOURCES = pm2_vid.c pm3_vid_la_SOURCES = pm3_vid.c radeon_vid_la_SOURCES = radeon_vid.c radeon_vid_la_LIBADD = -lm rage128_vid_la_SOURCES = radeon_vid.c rage128_vid_la_LIBADD = -lm rage128_vid_la_CPPFLAGS = $(AM_CPPFLAGS) -DRAGE128 savage_vid_la_SOURCES = savage_vid.c savage_vid_la_LIBADD = -lm sis_vid_la_SOURCES = sis_vid.c sis_bridge.c unichrome_vid_la_SOURCES = unichrome_vid.c xine-lib-1.2/contrib/vidix/drivers/pm3_vid.c0000644000175000017500000003501514647725152016636 0ustar meme/** Driver for 3DLabs GLINT R3 and Permedia3 chips. Copyright (C) 2002, 2003 Måns Rullgård This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **/ #include #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "pm3_regs.h" #define VIDIX_STATIC pm3_ /* MBytes of video memory to use */ #define PM3_VIDMEM 24 #if 0 #define TRACE_ENTER() fprintf(stderr, "%s: enter\n", __FUNCTION__) #define TRACE_EXIT() fprintf(stderr, "%s: exit\n", __FUNCTION__) #else #define TRACE_ENTER() #define TRACE_EXIT() #endif static pciinfo_t pci_info; void *pm3_reg_base; static uint8_t *pm3_mem; static int pm3_vidmem = PM3_VIDMEM; static int pm3_blank = 0; static int pm3_dma = 0; static int pm3_ckey_red, pm3_ckey_green, pm3_ckey_blue; static u_int page_size; static vidix_capability_t pm3_cap = { "3DLabs GLINT R3/Permedia3 driver", "Måns Rullgård ", TYPE_OUTPUT, { 0, 0, 0, 0 }, 2048, 2048, 4, 4, -1, FLAG_UPSCALER | FLAG_DOWNSCALER, VENDOR_3DLABS, -1, { 0, 0, 0, 0 } }; unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } static unsigned short pm3_card_ids[] = { DEVICE_3DLABS_GLINT_R3 }; static int find_chip(unsigned chip_id) { unsigned i; for(i = 0;i < sizeof(pm3_card_ids)/sizeof(unsigned short);i++) { if(chip_id == pm3_card_ids[i]) return i; } return -1; } int VIDIX_NAME(vixProbe)(int verbose, int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; (void)force; err = pci_scan(lst,&num_pci); if(err) { printf("[pm3] Error occured during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0; i < num_pci; i++) { if(lst[i].vendor == VENDOR_3DLABS) { int idx; const char *dname; idx = find_chip(lst[i].device); if(idx == -1) continue; dname = pci_device_name(VENDOR_3DLABS, lst[i].device); dname = dname ? dname : "Unknown chip"; printf("[pm3] Found chip: %s with IRQ %i\n", dname, lst[i].irq); pm3_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); break; } } } if(err && verbose) printf("[pm3] Can't find chip\n"); return err; } #define PRINT_REG(reg) \ { \ long _foo = READ_REG(reg); \ printf("[pm3] " #reg " (%x) = %#lx (%li)\n", reg, _foo, _foo); \ } int VIDIX_NAME(vixInit)(const char *args) { if(args != NULL){ char *ac = strdup(args), *s = NULL, *opt; opt = strtok_r(ac, ",", &s); while(opt){ char *a = strchr(opt, '='); if(a) *a++ = 0; if(!strcmp(opt, "mem")){ if(a) pm3_vidmem = strtol(a, NULL, 0); } else if(!strcmp(opt, "blank")){ pm3_blank = a? strtol(a, NULL, 0): 1; } opt = strtok_r(NULL, ",", &s); } free(ac); } pm3_reg_base = map_phys_mem(pci_info.base0, 0x20000); pm3_mem = map_phys_mem(pci_info.base1, 0x2000000); if(bm_open() == 0){ fprintf(stderr, "[pm3] DMA available.\n"); pm3_cap.flags |= FLAG_DMA | FLAG_SYNC_DMA; page_size = sysconf(_SC_PAGESIZE); hwirq_install(pci_info.bus, pci_info.card, pci_info.func, 0, PM3IntFlags, -1); WRITE_REG(PM3IntEnable, (1 << 7)); pm3_dma = 1; } RAMDAC_GET_REG(PM3RD_VideoOverlayKeyR, pm3_ckey_red); RAMDAC_GET_REG(PM3RD_VideoOverlayKeyG, pm3_ckey_green); RAMDAC_GET_REG(PM3RD_VideoOverlayKeyB, pm3_ckey_blue); return 0; } void VIDIX_NAME(vixDestroy)(void) { if(pm3_dma) WRITE_REG(PM3IntEnable, 0); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyR, pm3_ckey_red); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyG, pm3_ckey_green); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyB, pm3_ckey_blue); unmap_phys_mem(pm3_reg_base, 0x20000); unmap_phys_mem(pm3_mem, 0x2000000); hwirq_uninstall(pci_info.bus, pci_info.card, pci_info.func); bm_close(); } int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &pm3_cap, sizeof(vidix_capability_t)); return 0; } static int is_supported_fourcc(uint32_t fourcc) { switch(fourcc){ case IMGFMT_YUY2: case IMGFMT_UYVY: return 1; default: return 0; } } int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { if(is_supported_fourcc(to->fourcc)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } static int frames[VID_PLAY_MAXFRAMES], vid_base; static int overlay_mode, overlay_control, video_control, int_enable; static int rdoverlay_mode; static int src_w, drw_w; static int src_h, drw_h; static int drw_x, drw_y; #define FORMAT_RGB8888 PM3VideoOverlayMode_COLORFORMAT_RGB8888 #define FORMAT_RGB4444 PM3VideoOverlayMode_COLORFORMAT_RGB4444 #define FORMAT_RGB5551 PM3VideoOverlayMode_COLORFORMAT_RGB5551 #define FORMAT_RGB565 PM3VideoOverlayMode_COLORFORMAT_RGB565 #define FORMAT_RGB332 PM3VideoOverlayMode_COLORFORMAT_RGB332 #define FORMAT_BGR8888 PM3VideoOverlayMode_COLORFORMAT_BGR8888 #define FORMAT_BGR4444 PM3VideoOverlayMode_COLORFORMAT_BGR4444 #define FORMAT_BGR5551 PM3VideoOverlayMode_COLORFORMAT_BGR5551 #define FORMAT_BGR565 PM3VideoOverlayMode_COLORFORMAT_BGR565 #define FORMAT_BGR332 PM3VideoOverlayMode_COLORFORMAT_BGR332 #define FORMAT_CI8 PM3VideoOverlayMode_COLORFORMAT_CI8 #define FORMAT_VUY444 PM3VideoOverlayMode_COLORFORMAT_VUY444 #define FORMAT_YUV444 PM3VideoOverlayMode_COLORFORMAT_YUV444 #define FORMAT_VUY422 PM3VideoOverlayMode_COLORFORMAT_VUY422 #define FORMAT_YUV422 PM3VideoOverlayMode_COLORFORMAT_YUV422 /* Notice, have to check that we dont overflow the deltas here ... */ static void compute_scale_factor(int* src_w, int* dst_w, u_int* shrink_delta, u_int* zoom_delta) { /* NOTE: If we don't return reasonable values here then the video * unit can potential shut off and won't display an image until re-enabled. * Seems as though the zoom_delta is o.k, and I've not had the problem. * The 'shrink_delta' is prone to this the most - FIXME ! */ if (*src_w >= *dst_w) { *src_w &= ~0x3; *dst_w &= ~0x3; *shrink_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0ffffff0; *zoom_delta = 1<<16; if ( ((*shrink_delta * *dst_w) >> 16) & 0x03 ) *shrink_delta += 0x10; } else { *src_w &= ~0x3; *dst_w &= ~0x3; *zoom_delta = (((*src_w << 16) / *dst_w) + 0x0f) & 0x0001fff0; *shrink_delta = 1<<16; if ( ((*zoom_delta * *dst_w) >> 16) & 0x03 ) *zoom_delta += 0x10; } } static void pm3_setup_overlay(vidix_playback_t *info) { u_int shrink, zoom; int format = 0; int filter = 0; int sw = src_w; switch(info->fourcc){ case IMGFMT_YUY2: format = FORMAT_YUV422; break; case IMGFMT_UYVY: format = FORMAT_VUY422; break; } compute_scale_factor(&sw, &drw_w, &shrink, &zoom); WAIT_FIFO(9); WRITE_REG(PM3VideoOverlayBase0, vid_base >> 1); WRITE_REG(PM3VideoOverlayStride, PM3VideoOverlayStride_STRIDE(src_w)); WRITE_REG(PM3VideoOverlayWidth, PM3VideoOverlayWidth_WIDTH(sw)); WRITE_REG(PM3VideoOverlayHeight, PM3VideoOverlayHeight_HEIGHT(src_h)); WRITE_REG(PM3VideoOverlayOrigin, 0); /* Scale the source to the destinationsize */ if (src_w == drw_w) { WRITE_REG(PM3VideoOverlayShrinkXDelta, 1<<16); WRITE_REG(PM3VideoOverlayZoomXDelta, 1<<16); } else { WRITE_REG(PM3VideoOverlayShrinkXDelta, shrink); WRITE_REG(PM3VideoOverlayZoomXDelta, zoom); filter = PM3VideoOverlayMode_FILTER_PARTIAL; } if (src_h == drw_h) { WRITE_REG(PM3VideoOverlayYDelta, PM3VideoOverlayYDelta_NONE); } else { WRITE_REG(PM3VideoOverlayYDelta, PM3VideoOverlayYDelta_DELTA(src_h, drw_h)); filter = PM3VideoOverlayMode_FILTER_FULL; } WRITE_REG(PM3VideoOverlayIndex, 0); /* Now set the ramdac video overlay region and mode */ RAMDAC_SET_REG(PM3RD_VideoOverlayXStartLow, (drw_x & 0xff)); RAMDAC_SET_REG(PM3RD_VideoOverlayXStartHigh, (drw_x & 0xf00)>>8); RAMDAC_SET_REG(PM3RD_VideoOverlayXEndLow, (drw_x+drw_w) & 0xff); RAMDAC_SET_REG(PM3RD_VideoOverlayXEndHigh, ((drw_x+drw_w) & 0xf00)>>8); RAMDAC_SET_REG(PM3RD_VideoOverlayYStartLow, (drw_y & 0xff)); RAMDAC_SET_REG(PM3RD_VideoOverlayYStartHigh, (drw_y & 0xf00)>>8); RAMDAC_SET_REG(PM3RD_VideoOverlayYEndLow, (drw_y+drw_h) & 0xff); RAMDAC_SET_REG(PM3RD_VideoOverlayYEndHigh, ((drw_y+drw_h) & 0xf00)>>8); overlay_mode = 1 << 5 | format | filter | PM3VideoOverlayMode_BUFFERSYNC_MANUAL | PM3VideoOverlayMode_FLIP_VIDEO; overlay_control = PM3RD_VideoOverlayControl_KEY_COLOR | PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED; } extern int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *key) { if(key->ckey.op == CKEY_TRUE){ RAMDAC_SET_REG(PM3RD_VideoOverlayKeyR, key->ckey.red); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyG, key->ckey.green); RAMDAC_SET_REG(PM3RD_VideoOverlayKeyB, key->ckey.blue); rdoverlay_mode = PM3RD_VideoOverlayControl_MODE_MAINKEY; } else { rdoverlay_mode = PM3RD_VideoOverlayControl_MODE_ALWAYS; } RAMDAC_SET_REG(PM3RD_VideoOverlayControl, overlay_control | rdoverlay_mode); return 0; } extern int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *key) { RAMDAC_GET_REG(PM3RD_VideoOverlayKeyR, key->ckey.red); RAMDAC_GET_REG(PM3RD_VideoOverlayKeyG, key->ckey.green); RAMDAC_GET_REG(PM3RD_VideoOverlayKeyB, key->ckey.blue); return 0; } extern int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { unsigned int i; u_int frame_size; u_int vidmem_size; u_int max_frames; TRACE_ENTER(); src_w = info->src.w; src_h = info->src.h; drw_w = info->dest.w; drw_h = info->dest.h; drw_x = info->dest.x; drw_y = info->dest.y; frame_size = src_w * src_h * 2; vidmem_size = pm3_vidmem*1024*1024; max_frames = vidmem_size / frame_size; if(max_frames > VID_PLAY_MAXFRAMES) max_frames = VID_PLAY_MAXFRAMES; src_h--; /* ugh */ if(info->num_frames > max_frames) info->num_frames = max_frames; vidmem_size = info->num_frames * frame_size; /* Use end of video memory. Assume the card has 32 MB */ vid_base = 32*1024*1024 - vidmem_size; info->dga_addr = pm3_mem + vid_base; info->dest.pitch.y = 2; info->dest.pitch.u = 0; info->dest.pitch.v = 0; info->offset.y = 0; info->offset.v = 0; info->offset.u = 0; info->frame_size = frame_size; for(i = 0; i < info->num_frames; i++){ info->offsets[i] = frame_size * i; frames[i] = (vid_base + info->offsets[i]) >> 1; } pm3_setup_overlay(info); video_control = READ_REG(PM3VideoControl); int_enable = READ_REG(PM3IntEnable); TRACE_EXIT(); return 0; } int VIDIX_NAME(vixPlaybackOn)(void) { TRACE_ENTER(); WRITE_REG(PM3VideoOverlayMode, overlay_mode | PM3VideoOverlayMode_ENABLE); overlay_control |= PM3RD_VideoOverlayControl_ENABLE; RAMDAC_SET_REG(PM3RD_VideoOverlayControl, overlay_control | rdoverlay_mode); WRITE_REG(PM3VideoOverlayUpdate, PM3VideoOverlayUpdate_ENABLE); if(pm3_blank) WRITE_REG(PM3VideoControl, video_control | PM3VideoControl_DISPLAY_ENABLE); TRACE_EXIT(); return 0; } int VIDIX_NAME(vixPlaybackOff)(void) { overlay_control &= ~PM3RD_VideoOverlayControl_ENABLE; RAMDAC_SET_REG(PM3RD_VideoOverlayControl, PM3RD_VideoOverlayControl_DISABLE); WRITE_REG(PM3VideoOverlayMode, PM3VideoOverlayMode_DISABLE); if(video_control) WRITE_REG(PM3VideoControl, video_control & ~PM3VideoControl_DISPLAY_ENABLE); return 0; } int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { WRITE_REG(PM3VideoOverlayBase0, frames[frame]); return 0; } struct pm3_bydma_cmd { uint32_t bus_addr; uint32_t fb_addr; uint32_t mask; uint32_t count; }; struct pm3_bydma_frame { struct pm3_bydma_cmd *cmds; u_long bus_addr; uint32_t count; }; static struct pm3_bydma_frame * pm3_setup_bydma(vidix_dma_t *dma, struct pm3_bydma_frame *bdf) { u_int size = dma->size; u_int pages = (size + page_size-1) / page_size; unsigned long baddr[pages]; u_int i; uint32_t dest; if(bm_virt_to_bus(dma->src, dma->size, baddr)) return NULL; if(!bdf){ bdf = malloc(sizeof(*bdf)); bdf->cmds = valloc(pages * sizeof(struct pm3_bydma_cmd)); if(dma->flags & BM_DMA_FIXED_BUFFS){ mlock(bdf->cmds, page_size); } } dest = vid_base + dma->dest_offset; for(i = 0; i < pages; i++, dest += page_size, size -= page_size){ bdf->cmds[i].bus_addr = baddr[i]; bdf->cmds[i].fb_addr = dest; bdf->cmds[i].mask = ~0; bdf->cmds[i].count = ((size > page_size)? page_size: size) / 16; } bdf->count = pages; if(bm_virt_to_bus(bdf->cmds, page_size, &bdf->bus_addr) != 0){ free(bdf->cmds); free(bdf); return NULL; } return bdf; } extern int VIDIX_NAME(vixPlaybackCopyFrame)(vidix_dma_t *dma) { u_int frame = dma->idx; struct pm3_bydma_frame *bdf; bdf = dma->internal[frame]; if(!bdf || !(dma->flags & BM_DMA_FIXED_BUFFS)) bdf = pm3_setup_bydma(dma, bdf); if(!bdf) return -1; if(!dma->internal[frame]) dma->internal[frame] = bdf; if(dma->flags & BM_DMA_SYNC){ hwirq_wait(pci_info.irq); } WAIT_FIFO(3); WRITE_REG(PM3ByDMAReadCommandBase, bdf->bus_addr); WRITE_REG(PM3ByDMAReadCommandCount, bdf->count); WRITE_REG(PM3ByDMAReadMode, PM3ByDMAReadMode_ByteSwap_NONE | PM3ByDMAReadMode_Format_RAW | PM3ByDMAReadMode_PixelSize(16) | PM3ByDMAReadMode_Active | PM3ByDMAReadMode_Burst(7) | PM3ByDMAReadMode_Align); if(dma->flags & BM_DMA_BLOCK){ hwirq_wait(pci_info.irq); } return 0; } extern int VIDIX_NAME(vixQueryDMAStatus)(void) { uint32_t bdm = READ_REG(PM3ByDMAReadMode); return (bdm & PM3ByDMAReadMode_Active)? 1: 0; } xine-lib-1.2/contrib/vidix/drivers/mga_vid.c0000644000175000017500000012564714647725152016716 0ustar meme/* * Matrox MGA driver * * ported to VIDIX by Alex Beregszaszi * * YUY2 support (see config.format) added by A'rpi/ESP-team * double buffering added by A'rpi/ESP-team * * Brightness/contrast support by Nick Kurshev/Dariush Pietrzak (eyck) and me * * Fixed Brightness/Contrast * Rewrite or read/write kabi@users.sf.net * * TODO: * * fix memory size detection (current reading pci userconfig isn't * working as requested - returns the max avail. ram on arch?) * * translate all non-english comments to english */ /* * Original copyright: * * mga_vid.c * * Copyright (C) 1999 Aaron Holtzman * * Module skeleton based on gutted agpgart module by Jeff Hartmann * * * Matrox MGA G200/G400 YUV Video Interface module Version 0.1.0 * * BES == Back End Scaler * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. */ //#define CRTC2 // Set this value, if autodetection fails! (video ram size in megabytes) //#define MGA_MEMORY_SIZE 16 /* No irq support in userspace implemented yet, do not enable this! */ /* disable irq */ #undef MGA_ALLOW_IRQ #define MGA_VSYNC_POS 2 #undef MGA_PCICONFIG_MEMDETECT #define MGA_DEFAULT_FRAMES 64 #define BES #ifdef MGA_TV #undef BES #define CRTC2 #endif #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #if !defined(ENOTSUP) && defined(EOPNOTSUPP) #define ENOTSUP EOPNOTSUPP #endif #ifdef CRTC2 #define VIDIX_STATIC mga_crtc2_ #define MGA_MSG "[mga_crtc2]" #else #define VIDIX_STATIC mga_ #define MGA_MSG "[mga]" #endif /* from radeon_vid */ #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ)))) #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL #define readb(addr) GETREG(uint8_t,(uint32_t)(mga_mmio_base + addr),0) #define writeb(addr, val) SETREG(uint8_t,(uint32_t)(mga_mmio_base + addr),0,val) #define readl(addr) GETREG(uint32_t,(uint32_t)(mga_mmio_base + addr),0) #define writel(addr, val) SETREG(uint32_t,(uint32_t)(mga_mmio_base + addr),0,val) static int mga_verbose = 0; /* for device detection */ static int probed = 0; static pciinfo_t pci_info; /* internal booleans */ static int mga_vid_in_use = 0; static int is_g400 = 0; static int vid_src_ready = 0; static int vid_overlay_on = 0; /* mapped physical addresses */ static uint8_t *mga_mmio_base = 0; static uint8_t* mga_mem_base = 0; static int mga_src_base = 0; /* YUV buffer position in video memory */ static uint32_t mga_ram_size = 0; /* how much megabytes videoram we have */ /* Graphic keys */ static vidix_grkey_t mga_grkey; static int colkey_saved = 0; static int colkey_on = 0; static unsigned char colkey_color[4]; static unsigned char colkey_mask[4]; /* for IRQ */ static int mga_irq = -1; static int mga_next_frame = 0; static vidix_capability_t mga_cap = { #ifdef CRTC2 "Matrox MGA G200/G4x0/G5x0 YUV Video - with second-head support", #else "Matrox MGA G200/G4x0/G5x0 YUV Video", #endif "Aaron Holtzman, Arpad Gereoffy, Alex Beregszaszi, Nick Kurshev", TYPE_OUTPUT, { 0, 0, 0, 0 }, 2048, 2048, 4, 4, -1, FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER, VENDOR_MATROX, -1, /* will be set in VIDIX_NAME(vixProbe) */ { 0, 0, 0, 0} }; /* MATROX BES registers */ typedef struct bes_registers_s { //BES Control uint32_t besctl; //BES Global control uint32_t besglobctl; //Luma control (brightness and contrast) uint32_t beslumactl; //Line pitch uint32_t bespitch; //Buffer A-1 Chroma 3 plane org uint32_t besa1c3org; //Buffer A-1 Chroma org uint32_t besa1corg; //Buffer A-1 Luma org uint32_t besa1org; //Buffer A-2 Chroma 3 plane org uint32_t besa2c3org; //Buffer A-2 Chroma org uint32_t besa2corg; //Buffer A-2 Luma org uint32_t besa2org; //Buffer B-1 Chroma 3 plane org uint32_t besb1c3org; //Buffer B-1 Chroma org uint32_t besb1corg; //Buffer B-1 Luma org uint32_t besb1org; //Buffer B-2 Chroma 3 plane org uint32_t besb2c3org; //Buffer B-2 Chroma org uint32_t besb2corg; //Buffer B-2 Luma org uint32_t besb2org; //BES Horizontal coord uint32_t beshcoord; //BES Horizontal inverse scaling [5.14] uint32_t beshiscal; //BES Horizontal source start [10.14] (for scaling) uint32_t beshsrcst; //BES Horizontal source ending [10.14] (for scaling) uint32_t beshsrcend; //BES Horizontal source last uint32_t beshsrclst; //BES Vertical coord uint32_t besvcoord; //BES Vertical inverse scaling [5.14] uint32_t besviscal; //BES Field 1 vertical source last position uint32_t besv1srclst; //BES Field 1 weight start uint32_t besv1wght; //BES Field 2 vertical source last position uint32_t besv2srclst; //BES Field 2 weight start uint32_t besv2wght; } bes_registers_t; static bes_registers_t regs; #ifdef CRTC2 typedef struct crtc2_registers_s { uint32_t c2ctl; uint32_t c2datactl; uint32_t c2misc; uint32_t c2hparam; uint32_t c2hsync; uint32_t c2offset; uint32_t c2pl2startadd0; uint32_t c2pl2startadd1; uint32_t c2pl3startadd0; uint32_t c2pl3startadd1; uint32_t c2preload; uint32_t c2spicstartadd0; uint32_t c2spicstartadd1; uint32_t c2startadd0; uint32_t c2startadd1; uint32_t c2subpiclut; uint32_t c2vcount; uint32_t c2vparam; uint32_t c2vsync; } crtc2_registers_t; static crtc2_registers_t cregs; static crtc2_registers_t cregs_save; #endif //All register offsets are converted to word aligned offsets (32 bit) //because we want all our register accesses to be 32 bits #define VCOUNT 0x1e20 #define PALWTADD 0x3c00 // Index register for X_DATAREG port #define X_DATAREG 0x3c0a #define XMULCTRL 0x19 #define BPP_8 0x00 #define BPP_15 0x01 #define BPP_16 0x02 #define BPP_24 0x03 #define BPP_32_DIR 0x04 #define BPP_32_PAL 0x07 #define XCOLMSK 0x40 #define X_COLKEY 0x42 #define XKEYOPMODE 0x51 #define XCOLMSK0RED 0x52 #define XCOLMSK0GREEN 0x53 #define XCOLMSK0BLUE 0x54 #define XCOLKEY0RED 0x55 #define XCOLKEY0GREEN 0x56 #define XCOLKEY0BLUE 0x57 #ifdef CRTC2 /*CRTC2 registers*/ #define XMISCCTRL 0x1e #define C2CTL 0x3c10 #define C2DATACTL 0x3c4c #define C2MISC 0x3c44 #define C2HPARAM 0x3c14 #define C2HSYNC 0x3c18 #define C2OFFSET 0x3c40 #define C2PL2STARTADD0 0x3c30 // like BESA1CORG #define C2PL2STARTADD1 0x3c34 // like BESA2CORG #define C2PL3STARTADD0 0x3c38 // like BESA1C3ORG #define C2PL3STARTADD1 0x3c3c // like BESA2C3ORG #define C2PRELOAD 0x3c24 #define C2SPICSTARTADD0 0x3c54 #define C2SPICSTARTADD1 0x3c58 #define C2STARTADD0 0x3c28 // like BESA1ORG #define C2STARTADD1 0x3c2c // like BESA2ORG #define C2SUBPICLUT 0x3c50 #define C2VCOUNT 0x3c48 #define C2VPARAM 0x3c1c #define C2VSYNC 0x3c20 #endif /* CRTC2 */ // Backend Scaler registers #define BESCTL 0x3d20 #define BESGLOBCTL 0x3dc0 #define BESLUMACTL 0x3d40 #define BESPITCH 0x3d24 #define BESA1C3ORG 0x3d60 #define BESA1CORG 0x3d10 #define BESA1ORG 0x3d00 #define BESA2C3ORG 0x3d64 #define BESA2CORG 0x3d14 #define BESA2ORG 0x3d04 #define BESB1C3ORG 0x3d68 #define BESB1CORG 0x3d18 #define BESB1ORG 0x3d08 #define BESB2C3ORG 0x3d6C #define BESB2CORG 0x3d1C #define BESB2ORG 0x3d0C #define BESHCOORD 0x3d28 #define BESHISCAL 0x3d30 #define BESHSRCEND 0x3d3C #define BESHSRCLST 0x3d50 #define BESHSRCST 0x3d38 #define BESV1WGHT 0x3d48 #define BESV2WGHT 0x3d4c #define BESV1SRCLST 0x3d54 #define BESV2SRCLST 0x3d58 #define BESVISCAL 0x3d34 #define BESVCOORD 0x3d2c #define BESSTATUS 0x3dc4 #define CRTCX 0x1fd4 #define CRTCD 0x1fd5 #define IEN 0x1e1c #define ICLEAR 0x1e18 #define STATUS 0x1e14 #define CRTCEXTX 0x1fde #define CRTCEXTD 0x1fdf #ifdef CRTC2 static void crtc2_frame_sel(int frame) { switch(frame) { case 0: cregs.c2pl2startadd0=regs.besa1corg; cregs.c2pl3startadd0=regs.besa1c3org; cregs.c2startadd0=regs.besa1org; break; case 1: cregs.c2pl2startadd0=regs.besa2corg; cregs.c2pl3startadd0=regs.besa2c3org; cregs.c2startadd0=regs.besa2org; break; case 2: cregs.c2pl2startadd0=regs.besb1corg; cregs.c2pl3startadd0=regs.besb1c3org; cregs.c2startadd0=regs.besb1org; break; case 3: cregs.c2pl2startadd0=regs.besb2corg; cregs.c2pl3startadd0=regs.besb2c3org; cregs.c2startadd0=regs.besb2org; break; } writel(C2STARTADD0, cregs.c2startadd0); writel(C2PL2STARTADD0, cregs.c2pl2startadd0); writel(C2PL3STARTADD0, cregs.c2pl3startadd0); } #endif int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { mga_next_frame = frame; if (mga_verbose>1) printf(MGA_MSG" frameselect: %d\n", mga_next_frame); #if MGA_ALLOW_IRQ if (mga_irq == -1) #endif { #ifdef BES //we don't need the vcount protection as we're only hitting //one register (and it doesn't seem to be double buffered) regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25); writel(BESCTL, regs.besctl); // writel( regs.besglobctl + ((readl(VCOUNT)+2)<<16), writel(BESGLOBCTL, regs.besglobctl + (MGA_VSYNC_POS<<16)); #endif #ifdef CRTC2 crtc2_frame_sel(mga_next_frame); #endif } return(0); } static void mga_vid_write_regs(int restore) { #ifdef BES //Make sure internal registers don't get updated until we're done writel(BESGLOBCTL, (readl(VCOUNT)-1)<<16); // color or coordinate keying if (restore && colkey_saved) { // restore it colkey_saved = 0; // Set color key registers: writeb(PALWTADD, XKEYOPMODE); writeb(X_DATAREG, colkey_on); writeb(PALWTADD, XCOLKEY0RED); writeb(X_DATAREG, colkey_color[0]); writeb(PALWTADD, XCOLKEY0GREEN); writeb(X_DATAREG, colkey_color[1]); writeb(PALWTADD, XCOLKEY0BLUE); writeb(X_DATAREG, colkey_color[2]); writeb(PALWTADD, X_COLKEY); writeb(X_DATAREG, colkey_color[3]); writeb(PALWTADD, XCOLMSK0RED); writeb(X_DATAREG, colkey_mask[0]); writeb(PALWTADD, XCOLMSK0GREEN); writeb(X_DATAREG, colkey_mask[1]); writeb(PALWTADD, XCOLMSK0BLUE); writeb(X_DATAREG, colkey_mask[2]); writeb(PALWTADD, XCOLMSK); writeb(X_DATAREG, colkey_mask[3]); printf(MGA_MSG" Restored colour key (ON: %d %02X:%02X:%02X)\n", colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); } else if (!colkey_saved) { // save it colkey_saved=1; // Get color key registers: writeb(PALWTADD, XKEYOPMODE); colkey_on = readb(X_DATAREG) & 1; writeb(PALWTADD, XCOLKEY0RED); colkey_color[0]=(unsigned char)readb(X_DATAREG); writeb(PALWTADD, XCOLKEY0GREEN); colkey_color[1]=(unsigned char)readb(X_DATAREG); writeb(PALWTADD, XCOLKEY0BLUE); colkey_color[2]=(unsigned char)readb(X_DATAREG); writeb(PALWTADD, X_COLKEY); colkey_color[3]=(unsigned char)readb(X_DATAREG); writeb(PALWTADD, XCOLMSK0RED); colkey_mask[0]=(unsigned char)readb(X_DATAREG); writeb(PALWTADD, XCOLMSK0GREEN); colkey_mask[1]=(unsigned char)readb(X_DATAREG); writeb(PALWTADD, XCOLMSK0BLUE); colkey_mask[2]=(unsigned char)readb(X_DATAREG); writeb(PALWTADD, XCOLMSK); colkey_mask[3]=(unsigned char)readb(X_DATAREG); printf(MGA_MSG" Saved colour key (ON: %d %02X:%02X:%02X)\n", colkey_on,colkey_color[0],colkey_color[1],colkey_color[2]); } if (!restore) { writeb(PALWTADD, XKEYOPMODE); writeb(X_DATAREG, (mga_grkey.ckey.op == CKEY_TRUE)); if ( mga_grkey.ckey.op == CKEY_TRUE ) { uint32_t r=0, g=0, b=0; writeb(PALWTADD, XMULCTRL); switch (readb(X_DATAREG)) { case BPP_8: /* Need to look up the color index, just using color 0 for now. */ break; case BPP_15: r = mga_grkey.ckey.red >> 3; g = mga_grkey.ckey.green >> 3; b = mga_grkey.ckey.blue >> 3; break; case BPP_16: r = mga_grkey.ckey.red >> 3; g = mga_grkey.ckey.green >> 2; b = mga_grkey.ckey.blue >> 3; break; case BPP_24: case BPP_32_DIR: case BPP_32_PAL: r = mga_grkey.ckey.red; g = mga_grkey.ckey.green; b = mga_grkey.ckey.blue; break; } // Disable color keying on alpha channel writeb(PALWTADD, XCOLMSK); writeb(X_DATAREG, 0x00); writeb(PALWTADD, X_COLKEY); writeb(X_DATAREG, 0x00); // Set up color key registers writeb(PALWTADD, XCOLKEY0RED); writeb(X_DATAREG, r); writeb(PALWTADD, XCOLKEY0GREEN); writeb(X_DATAREG, g); writeb(PALWTADD, XCOLKEY0BLUE); writeb(X_DATAREG, b); // Set up color key mask registers writeb(PALWTADD, XCOLMSK0RED); writeb(X_DATAREG, 0xff); writeb(PALWTADD, XCOLMSK0GREEN); writeb(X_DATAREG, 0xff); writeb(PALWTADD, XCOLMSK0BLUE); writeb(X_DATAREG, 0xff); } } // Backend Scaler writel(BESCTL, regs.besctl); if (is_g400) writel(BESLUMACTL, regs.beslumactl); writel(BESPITCH, regs.bespitch); writel(BESA1ORG, regs.besa1org); writel(BESA1CORG, regs.besa1corg); writel(BESA2ORG, regs.besa2org); writel(BESA2CORG, regs.besa2corg); writel(BESB1ORG, regs.besb1org); writel(BESB1CORG, regs.besb1corg); writel(BESB2ORG, regs.besb2org); writel(BESB2CORG, regs.besb2corg); if(is_g400) { writel(BESA1C3ORG, regs.besa1c3org); writel(BESA2C3ORG, regs.besa2c3org); writel(BESB1C3ORG, regs.besb1c3org); writel(BESB2C3ORG, regs.besb2c3org); } writel(BESHCOORD, regs.beshcoord); writel(BESHISCAL, regs.beshiscal); writel(BESHSRCST, regs.beshsrcst); writel(BESHSRCEND, regs.beshsrcend); writel(BESHSRCLST, regs.beshsrclst); writel(BESVCOORD, regs.besvcoord); writel(BESVISCAL, regs.besviscal); writel(BESV1SRCLST, regs.besv1srclst); writel(BESV1WGHT, regs.besv1wght); writel(BESV2SRCLST, regs.besv2srclst); writel(BESV2WGHT, regs.besv2wght); //update the registers somewhere between 1 and 2 frames from now. writel(BESGLOBCTL, regs.besglobctl + ((readl(VCOUNT)+2)<<16)); if (mga_verbose > 1) { printf(MGA_MSG" wrote BES registers\n"); printf(MGA_MSG" BESCTL = 0x%08x\n", readl(BESCTL)); printf(MGA_MSG" BESGLOBCTL = 0x%08x\n", readl(BESGLOBCTL)); printf(MGA_MSG" BESSTATUS= 0x%08x\n", readl(BESSTATUS)); } #endif #ifdef CRTC2 #if 0 if (cregs_save.c2ctl == 0) { //int i; cregs_save.c2ctl = readl(C2CTL); cregs_save.c2datactl = readl(C2DATACTL); cregs_save.c2misc = readl(C2MISC); //for (i = 0; i <= 8; i++) { writeb(CRTCEXTX, i); printf("CRTCEXT%d %x\n", i, readb(CRTCEXTD)); } //printf("c2ctl:0x%08x c2datactl:0x%08x\n", cregs_save.c2ctl, cregs_save.c2datactl); //printf("c2misc:0x%08x\n", readl(C2MISC)); //printf("c2ctl:0x%08x c2datactl:0x%08x\n", cregs.c2ctl, cregs.c2datactl); } if (restore) { writel(C2CTL, cregs_save.c2ctl); writel(C2DATACTL, cregs_save.c2datactl); writel(C2MISC, cregs_save.c2misc); return; } #endif // writel(C2CTL, cregs.c2ctl); writel(C2CTL, ((readl(C2CTL) & ~0x03e00000) + (cregs.c2ctl & 0x03e00000))); writel(C2DATACTL, ((readl(C2DATACTL) & ~0x000000ff) + (cregs.c2datactl & 0x000000ff))); // ctrc2 // disable CRTC2 acording to specs // writel(C2CTL, cregs.c2ctl & 0xfffffff0); // je to treba ??? // writeb(XMISCCTRL, (readb(XMISCCTRL) & 0x19) | 0xa2); // MAFC - mfcsel & vdoutsel // writeb(XMISCCTRL, (readb(XMISCCTRL) & 0x19) | 0x92); // writeb(XMISCCTRL, (readb(XMISCCTRL) & ~0xe9) + 0xa2); writel(C2DATACTL, cregs.c2datactl); // writel(C2HPARAM, cregs.c2hparam); writel(C2HSYNC, cregs.c2hsync); // writel(C2VPARAM, cregs.c2vparam); writel(C2VSYNC, cregs.c2vsync); //xx //writel(C2MISC, cregs.c2misc); if (mga_verbose > 1) printf(MGA_MSG" c2offset = %d\n", cregs.c2offset); writel(C2OFFSET, cregs.c2offset); writel(C2STARTADD0, cregs.c2startadd0); // writel(C2STARTADD1, cregs.c2startadd1); writel(C2PL2STARTADD0, cregs.c2pl2startadd0); // writel(C2PL2STARTADD1, cregs.c2pl2startadd1); writel(C2PL3STARTADD0, cregs.c2pl3startadd0); // writel(C2PL3STARTADD1, cregs.c2pl3startadd1); writel(C2SPICSTARTADD0, cregs.c2spicstartadd0); //xx //writel(C2SPICSTARTADD1, cregs.c2spicstartadd1); //set Color Lookup Table for Subpicture Layer { unsigned char r, g, b, y, cb, cr; int i; for (i = 0; i < 16; i++) { r = (i & 0x8) ? 0xff : 0x00; g = (i & 0x4) ? ((i & 0x2) ? 0xff : 0xaa) : ((i & 0x2) ? 0x55 : 0x00); b = (i & 0x1) ? 0xff : 0x00; y = ((r * 16829 + g * 33039 + b * 6416 + 0x8000) >> 16) + 16; cb = ((r * -9714 + g * -19071 + b * 28784 + 0x8000) >> 16) + 128; cr = ((r * 28784 + g * -24103 + b * -4681 + 0x8000) >> 16) + 128; cregs.c2subpiclut = (cr << 24) | (cb << 16) | (y << 8) | i; writel(C2SUBPICLUT, cregs.c2subpiclut); } } //writel(C2PRELOAD, cregs.c2preload); // finaly enable everything // writel(C2CTL, cregs.c2ctl); // printf("c2ctl:0x%08x c2datactl:0x%08x\n",readl(C2CTL), readl(C2DATACTL)); // printf("c2misc:0x%08x\n", readl(C2MISC)); #endif } #ifdef MGA_ALLOW_IRQ static void enable_irq() { long int cc; cc = readl(IEN); // printf("*** !!! IRQREG = %d\n", (int)(cc&0xff)); writeb(CRTCX, 0x11); writeb(CRTCD, 0x20); /* clear 0, enable off */ writeb(CRTCD, 0x00); /* enable on */ writeb(CRTCD, 0x10); /* clear = 1 */ writel(BESGLOBCTL, regs.besglobctl); return; } static void disable_irq() { writeb(CRTCX, 0x11); writeb(CRTCD, 0x20); /* clear 0, enable off */ return; } void mga_handle_irq(int irq, void *dev_id/*, struct pt_regs *pregs*/) { // static int frame=0; // static int counter=0; long int cc; // if ( ! mga_enabled_flag ) return; // printf("vcount = %d\n",readl(VCOUNT)); //printf("mga_interrupt #%d\n", irq); if ( irq != -1 ) { cc = readl(STATUS); if ( ! (cc & 0x10) ) return; /* vsyncpen */ // debug_irqcnt++; } // if ( debug_irqignore ) { // debug_irqignore = 0; /* if ( mga_conf_deinterlace ) { if ( mga_first_field ) { // printf("mga_interrupt first field\n"); if ( syncfb_interrupt() ) mga_first_field = 0; } else { // printf("mga_interrupt second field\n"); mga_select_buffer( mga_current_field | 2 ); mga_first_field = 1; } } else { syncfb_interrupt(); } */ // frame=(frame+1)&1; regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25); writel(BESCTL, regs.besctl); #ifdef CRTC2 crtc2_frame_sel(mga_next_frame); #endif #if 0 ++counter; if(!(counter&63)){ printf("mga irq counter = %d\n",counter); } #endif // } else { // debug_irqignore = 1; // } if ( irq != -1 ) { writeb(CRTCX, 0x11); writeb(CRTCD, 0); writeb(CRTCD, 0x10); } //writel(BESGLOBCTL, regs.besglobctl); } #endif /* MGA_ALLOW_IRQ */ int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *config) { unsigned int i; int x, y, sw, sh, dw, dh; int besleft, bestop, ifactor, ofsleft, ofstop, baseadrofs, weight, weights; #ifdef CRTC2 #define right_margin 0 #define left_margin 18 #define hsync_len 46 #define lower_margin 10 #define vsync_len 4 #define upper_margin 39 unsigned int hdispend = (config->src.w + 31) & ~31; unsigned int hsyncstart = hdispend + (right_margin & ~7); unsigned int hsyncend = hsyncstart + (hsync_len & ~7); unsigned int htotal = hsyncend + (left_margin & ~7); unsigned int vdispend = config->src.h; unsigned int vsyncstart = vdispend + lower_margin; unsigned int vsyncend = vsyncstart + vsync_len; unsigned int vtotal = vsyncend + upper_margin; #endif if ((config->num_frames < 1) || (config->num_frames > MGA_DEFAULT_FRAMES)) { printf(MGA_MSG" illegal num_frames: %d, setting to %d\n", config->num_frames, MGA_DEFAULT_FRAMES); config->num_frames = MGA_DEFAULT_FRAMES; } for(;config->num_frames>0;config->num_frames--) { /*FIXME: this driver can use more frames but we need to apply some tricks to avoid RGB-memory hits*/ mga_src_base = ((mga_ram_size/2)*0x100000-(config->num_frames+1)*config->frame_size); mga_src_base &= (~0xFFFF); /* 64k boundary */ if(mga_src_base>=0) break; } if (mga_verbose > 1) printf(MGA_MSG" YUV buffer base: 0x%x\n", mga_src_base); config->dga_addr = mga_mem_base + mga_src_base; x = config->dest.x; y = config->dest.y; sw = config->src.w; sh = config->src.h; dw = config->dest.w; dh = config->dest.h; if (mga_verbose) printf(MGA_MSG" Setting up a %dx%d-%dx%d video window (src %dx%d) format %X\n", dw, dh, x, y, sw, sh, config->fourcc); if ((sw < 4) || (sh < 4) || (dw < 4) || (dh < 4)) { printf(MGA_MSG" Invalid src/dest dimensions\n"); return(EINVAL); } //FIXME check that window is valid and inside desktop // printf(MGA_MSG" vcount = %d\n", readl(VCOUNT)); sw += sw & 1; switch(config->fourcc) { case IMGFMT_I420: case IMGFMT_IYUV: case IMGFMT_YV12: sh+=sh&1; config->dest.pitch.y=config->dest.pitch.u=config->dest.pitch.v=32; config->frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; break; case IMGFMT_YUY2: case IMGFMT_UYVY: config->dest.pitch.y=16; config->dest.pitch.u=config->dest.pitch.v=0; config->frame_size = ((sw + 8) & ~8) * sh * 2; break; default: printf(MGA_MSG" Unsupported pixel format: %x\n", config->fourcc); return(ENOTSUP); } config->offsets[0] = 0; // config->offsets[1] = config->frame_size; // config->offsets[2] = 2*config->frame_size; // config->offsets[3] = 3*config->frame_size; for (i = 1; i < config->num_frames+2; i++) config->offsets[i] = i*config->frame_size; config->offset.y=0; config->offset.v=((sw + 31) & ~31) * sh; config->offset.u=config->offset.v+((sw + 31) & ~31) * sh /4; //FIXME figure out a better way to allocate memory on card //allocate 2 megs //mga_src_base = mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000; //mga_src_base = (MGA_VIDMEM_SIZE-3) * 0x100000; /* for G200 set Interleaved UV planes */ if (!is_g400) config->flags = VID_PLAY_INTERLEAVED_UV | INTERLEAVING_UV; //Setup the BES registers for a three plane 4:2:0 video source regs.besglobctl = 0; switch(config->fourcc) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: regs.besctl = 1 // BES enabled + (0<<6) // even start polarity + (1<<10) // x filtering enabled + (1<<11) // y filtering enabled + (1<<16) // chroma upsampling + (1<<17) // 4:2:0 mode + (1<<18); // dither enabled #if 0 if(is_g400) { //zoom disabled, zoom filter disabled, 420 3 plane format, proc amp //disabled, rgb mode disabled regs.besglobctl = (1<<5); } else { //zoom disabled, zoom filter disabled, Cb samples in 0246, Cr //in 1357, BES register update on besvcnt regs.besglobctl = 0; } #endif break; case IMGFMT_YUY2: regs.besctl = 1 // BES enabled + (0<<6) // even start polarity + (1<<10) // x filtering enabled + (1<<11) // y filtering enabled + (1<<16) // chroma upsampling + (0<<17) // 4:2:2 mode + (1<<18); // dither enabled regs.besglobctl = 0; // YUY2 format selected break; case IMGFMT_UYVY: regs.besctl = 1 // BES enabled + (0<<6) // even start polarity + (1<<10) // x filtering enabled + (1<<11) // y filtering enabled + (1<<16) // chroma upsampling + (0<<17) // 4:2:2 mode + (1<<18); // dither enabled regs.besglobctl = 1<<6; // UYVY format selected break; } //Disable contrast and brightness control regs.besglobctl |= (1<<5) + (1<<7); // we want to preserver these across restarts //regs.beslumactl = (0x0 << 16) + 0x80; //Setup destination window boundaries besleft = x > 0 ? x : 0; bestop = y > 0 ? y : 0; regs.beshcoord = (besleft<<16) + (x + dw-1); regs.besvcoord = (bestop<<16) + (y + dh-1); //Setup source dimensions regs.beshsrclst = (sw - 1) << 16; switch(config->fourcc) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: regs.bespitch = (sw + 31) & ~31; break; case IMGFMT_YUY2: case IMGFMT_UYVY: regs.bespitch = (sw + 8) & ~8; break; } //Setup horizontal scaling ifactor = ((sw-1)<<14)/(dw-1); ofsleft = besleft - x; regs.beshiscal = ifactor<<2; regs.beshsrcst = (ofsleft*ifactor)<<2; regs.beshsrcend = regs.beshsrcst + (((dw - ofsleft - 1) * ifactor) << 2); //Setup vertical scaling ifactor = ((sh-1)<<14)/(dh-1); ofstop = bestop - y; regs.besviscal = ifactor<<2; baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch; //frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; regs.besa1org = (uint32_t) mga_src_base + baseadrofs; regs.besa2org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size; regs.besb1org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size; regs.besb2org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size; if (config->fourcc == IMGFMT_YV12 || config->fourcc == IMGFMT_IYUV || config->fourcc == IMGFMT_I420) { // planar YUV frames: if (is_g400) baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch; else baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch; if (config->fourcc == IMGFMT_YV12){ regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; regs.besa2corg = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh; regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh; regs.besb2corg = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh; regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4); regs.besa2c3org = regs.besa2corg + ((regs.bespitch * sh) / 4); regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4); regs.besb2c3org = regs.besb2corg + ((regs.bespitch * sh) / 4); } else { regs.besa1c3org = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; regs.besa2c3org = (uint32_t) mga_src_base + baseadrofs + 1*config->frame_size + regs.bespitch * sh; regs.besb1c3org = (uint32_t) mga_src_base + baseadrofs + 2*config->frame_size + regs.bespitch * sh; regs.besb2c3org = (uint32_t) mga_src_base + baseadrofs + 3*config->frame_size + regs.bespitch * sh; regs.besa1corg = regs.besa1c3org + ((regs.bespitch * sh) / 4); regs.besa2corg = regs.besa2c3org + ((regs.bespitch * sh) / 4); regs.besb1corg = regs.besb1c3org + ((regs.bespitch * sh) / 4); regs.besb2corg = regs.besb2c3org + ((regs.bespitch * sh) / 4); } } weight = ofstop * (regs.besviscal >> 2); weights = weight < 0 ? 1 : 0; regs.besv2wght = regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2); regs.besv2srclst = regs.besv1srclst = sh - 1 - (((ofstop * regs.besviscal) >> 16) & 0x03FF); #ifdef CRTC2 // pridat hlavni registry - tj. casovani ... switch(config->fourcc){ case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_IYUV: cregs.c2ctl = 1 // CRTC2 enabled + (1<<1) // external clock + (0<<2) // external clock + (1<<3) // pixel clock enable - not needed ??? + (0<<4) // high priority req + (1<<5) // high priority req + (0<<6) // high priority req + (1<<8) // high priority req max + (0<<9) // high priority req max + (0<<10) // high priority req max + (0<<20) // CRTC1 to DAC + (1<<21) // 420 mode + (1<<22) // 420 mode + (1<<23) // 420 mode + (0<<24) // single chroma line for 420 mode - need to be corrected + (0<<25) /*/ interlace mode - need to be corrected*/ + (0<<26) // field legth polariry + (0<<27) // field identification polariry + (1<<28) // VIDRST detection mode + (0<<29) // VIDRST detection mode + (1<<30) // Horizontal counter preload + (1<<31) // Vertical counter preload ; cregs.c2datactl = 1 // disable dither - propably not needed, we are already in YUV mode + (1<<1) // Y filter enable + (1<<2) // CbCr filter enable + (1<<3) // subpicture enable (enabled) + (0<<4) // NTSC enable (disabled - PAL) + (0<<5) // C2 static subpicture enable (disabled) + (0<<6) // C2 subpicture offset division (disabled) + (0<<7) // 422 subformat selection ! /* + (0<<8) // 15 bpp high alpha + (0<<9) // 15 bpp high alpha + (0<<10) // 15 bpp high alpha + (0<<11) // 15 bpp high alpha + (0<<12) // 15 bpp high alpha + (0<<13) // 15 bpp high alpha + (0<<14) // 15 bpp high alpha + (0<<15) // 15 bpp high alpha + (0<<16) // 15 bpp low alpha + (0<<17) // 15 bpp low alpha + (0<<18) // 15 bpp low alpha + (0<<19) // 15 bpp low alpha + (0<<20) // 15 bpp low alpha + (0<<21) // 15 bpp low alpha + (0<<22) // 15 bpp low alpha + (0<<23) // 15 bpp low alpha + (0<<24) // static subpicture key + (0<<25) // static subpicture key + (0<<26) // static subpicture key + (0<<27) // static subpicture key + (0<<28) // static subpicture key */ ; break; case IMGFMT_YUY2: cregs.c2ctl = 1 // CRTC2 enabled + (1<<1) // external clock + (0<<2) // external clock + (1<<3) // pixel clock enable - not needed ??? + (0<<4) // high priority req - acc to spec + (1<<5) // high priority req + (0<<6) // high priority req // 7 reserved + (1<<8) // high priority req max + (0<<9) // high priority req max + (0<<10) // high priority req max // 11-19 reserved + (0<<20) // CRTC1 to DAC + (1<<21) // 422 mode + (0<<22) // 422 mode + (1<<23) // 422 mode + (0<<24) // single chroma line for 420 mode - need to be corrected + (0<<25) /*/ interlace mode - need to be corrected*/ + (0<<26) // field legth polariry + (0<<27) // field identification polariry + (1<<28) // VIDRST detection mode + (0<<29) // VIDRST detection mode + (1<<30) // Horizontal counter preload + (1<<31) // Vertical counter preload ; cregs.c2datactl = 1 // disable dither - propably not needed, we are already in YUV mode + (1<<1) // Y filter enable + (1<<2) // CbCr filter enable + (1<<3) // subpicture enable (enabled) + (0<<4) // NTSC enable (disabled - PAL) + (0<<5) // C2 static subpicture enable (disabled) + (0<<6) // C2 subpicture offset division (disabled) + (0<<7) // 422 subformat selection ! /* + (0<<8) // 15 bpp high alpha + (0<<9) // 15 bpp high alpha + (0<<10) // 15 bpp high alpha + (0<<11) // 15 bpp high alpha + (0<<12) // 15 bpp high alpha + (0<<13) // 15 bpp high alpha + (0<<14) // 15 bpp high alpha + (0<<15) // 15 bpp high alpha + (0<<16) // 15 bpp low alpha + (0<<17) // 15 bpp low alpha + (0<<18) // 15 bpp low alpha + (0<<19) // 15 bpp low alpha + (0<<20) // 15 bpp low alpha + (0<<21) // 15 bpp low alpha + (0<<22) // 15 bpp low alpha + (0<<23) // 15 bpp low alpha + (0<<24) // static subpicture key + (0<<25) // static subpicture key + (0<<26) // static subpicture key + (0<<27) // static subpicture key + (0<<28) // static subpicture key */ ; break; case IMGFMT_UYVY: cregs.c2ctl = 1 // CRTC2 enabled + (1<<1) // external clock + (0<<2) // external clock + (1<<3) // pixel clock enable - not needed ??? + (0<<4) // high priority req + (1<<5) // high priority req + (0<<6) // high priority req + (1<<8) // high priority req max + (0<<9) // high priority req max + (0<<10) // high priority req max + (0<<20) // CRTC1 to DAC + (1<<21) // 422 mode + (0<<22) // 422 mode + (1<<23) // 422 mode + (1<<24) // single chroma line for 420 mode - need to be corrected + (1<<25) /*/ interlace mode - need to be corrected*/ + (0<<26) // field legth polariry + (0<<27) // field identification polariry + (1<<28) // VIDRST detection mode + (0<<29) // VIDRST detection mode + (1<<30) // Horizontal counter preload + (1<<31) // Vertical counter preload ; cregs.c2datactl = 0 // enable dither - propably not needed, we are already in YUV mode + (1<<1) // Y filter enable + (1<<2) // CbCr filter enable + (1<<3) // subpicture enable (enabled) + (0<<4) // NTSC enable (disabled - PAL) + (0<<5) // C2 static subpicture enable (disabled) + (0<<6) // C2 subpicture offset division (disabled) + (1<<7) // 422 subformat selection ! /* + (0<<8) // 15 bpp high alpha + (0<<9) // 15 bpp high alpha + (0<<10) // 15 bpp high alpha + (0<<11) // 15 bpp high alpha + (0<<12) // 15 bpp high alpha + (0<<13) // 15 bpp high alpha + (0<<14) // 15 bpp high alpha + (0<<15) // 15 bpp high alpha + (0<<16) // 15 bpp low alpha + (0<<17) // 15 bpp low alpha + (0<<18) // 15 bpp low alpha + (0<<19) // 15 bpp low alpha + (0<<20) // 15 bpp low alpha + (0<<21) // 15 bpp low alpha + (0<<22) // 15 bpp low alpha + (0<<23) // 15 bpp low alpha + (0<<24) // static subpicture key + (0<<25) // static subpicture key + (0<<26) // static subpicture key + (0<<27) // static subpicture key + (0<<28) // static subpicture key */ ; break; } cregs.c2hparam=((hdispend - 8) << 16) | (htotal - 8); cregs.c2hsync=((hsyncend - 8) << 16) | (hsyncstart - 8); cregs.c2misc=0 // CRTCV2 656 togg f0 +(0<<1) // CRTCV2 656 togg f0 +(0<<2) // CRTCV2 656 togg f0 +(0<<4) // CRTCV2 656 togg f1 +(0<<5) // CRTCV2 656 togg f1 +(0<<6) // CRTCV2 656 togg f1 +(0<<8) // Hsync active high +(0<<9) // Vsync active high // 16-27 c2vlinecomp - nevim co tam dat ; cregs.c2offset=(regs.bespitch << 1); cregs.c2pl2startadd0=regs.besa1corg; //cregs.c2pl2startadd1=regs.besa2corg; cregs.c2pl3startadd0=regs.besa1c3org; //cregs.c2pl3startadd1=regs.besa2c3org; cregs.c2preload=(vsyncstart << 16) | (hsyncstart); // from memset((uint8_t *)(config->dga_addr) + config->offsets[config->num_frames], 0, config->frame_size); // clean spic area cregs.c2spicstartadd0=(uint32_t) mga_src_base + baseadrofs + config->num_frames*config->frame_size; //cregs.c2spicstartadd1=0; // not used cregs.c2startadd0=regs.besa1org; //cregs.c2startadd1=regs.besa2org; cregs.c2subpiclut=0; //not used cregs.c2vparam=((vdispend - 1) << 16) | (vtotal - 1); cregs.c2vsync=((vsyncend - 1) << 16) | (vsyncstart - 1); #endif /* CRTC2 */ mga_vid_write_regs(0); return(0); } int VIDIX_NAME(vixPlaybackOn)(void) { if (mga_verbose) printf(MGA_MSG" playback on\n"); vid_src_ready = 1; if(vid_overlay_on) { regs.besctl |= 1; mga_vid_write_regs(0); } #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) enable_irq(); #endif mga_next_frame=0; return(0); } int VIDIX_NAME(vixPlaybackOff)(void) { if (mga_verbose) printf(MGA_MSG" playback off\n"); vid_src_ready = 0; #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) disable_irq(); #endif regs.besctl &= ~1; regs.besglobctl &= ~(1<<6); /* UYVY format selected */ mga_vid_write_regs(0); return(0); } int VIDIX_NAME(vixProbe)(int verbose,int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned int i, num_pci; int err; if (verbose) printf(MGA_MSG" probe\n"); (void)force; mga_verbose = verbose; is_g400 = -1; err = pci_scan(lst, &num_pci); if (err) { printf(MGA_MSG" Error occured during pci scan: %s\n", strerror(err)); return(err); } if (mga_verbose) printf(MGA_MSG" found %d pci devices\n", num_pci); for (i = 0; i < num_pci; i++) { if (mga_verbose > 1) printf(MGA_MSG" pci[%d] vendor: %d device: %d\n", i, lst[i].vendor, lst[i].device); if (lst[i].vendor == VENDOR_MATROX) { switch(lst[i].device) { case DEVICE_MATROX_MGA_G550_AGP: printf(MGA_MSG" Found MGA G550\n"); is_g400 = 1; goto card_found; case DEVICE_MATROX_MGA_G400_AGP: printf(MGA_MSG" Found MGA G400/G450\n"); is_g400 = 1; goto card_found; #ifndef CRTC2 case DEVICE_MATROX_MGA_G200_AGP: printf(MGA_MSG" Found MGA G200 AGP\n"); is_g400 = 0; goto card_found; case DEVICE_MATROX_MGA_G200: printf(MGA_MSG" Found MGA G200 PCI\n"); is_g400 = 0; goto card_found; #endif } } } if (is_g400 == -1) { if(verbose) printf(MGA_MSG" Can't find chip\n\n"); return(ENXIO); } card_found: probed = 1; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); mga_cap.device_id = pci_info.device; /* set device id in capabilites */ return(0); } int VIDIX_NAME(vixInit)(const char *args) { unsigned int card_option = 0; int err; (void)args; /* reset Brightness & Constrast here */ regs.beslumactl = (0x0 << 16) + 0x80; if (mga_verbose) printf(MGA_MSG" init\n"); mga_vid_in_use = 0; if (!probed) { printf(MGA_MSG" driver was not probed but is being initializing\n"); return(EINTR); } #ifdef MGA_PCICONFIG_MEMDETECT pci_config_read(pci_info.bus, pci_info.card, pci_info.func, 0x40, 4, &card_option); if (mga_verbose > 1) printf(MGA_MSG" OPTION word: 0x%08X mem: 0x%02X %s\n", card_option, (card_option>>10)&0x17, ((card_option>>14)&1)?"SGRAM":"SDRAM"); #endif if (mga_ram_size) { printf(MGA_MSG" RAMSIZE forced to %d MB\n", mga_ram_size); } else { #ifdef MGA_MEMORY_SIZE mga_ram_size = MGA_MEMORY_SIZE; printf(MGA_MSG" hard-coded RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); #else if (is_g400) { switch((card_option>>10)&0x17) { // SDRAM: case 0x00: case 0x04: mga_ram_size = 16; break; case 0x03: mga_ram_size = 32; break; // SGRAM: case 0x10: case 0x14: mga_ram_size = 32; break; case 0x11: case 0x12: mga_ram_size = 16; break; default: mga_ram_size = 16; printf(MGA_MSG" Couldn't detect RAMSIZE, assuming 16MB!\n"); } } else { switch((card_option>>10)&0x17) { // case 0x10: // case 0x13: mga_ram_size = 8; break; default: mga_ram_size = 8; } } #if 0 // printf("List resources -----------\n"); for(temp=0;tempresource[temp]; if(res->flags){ int size=(1+res->end-res->start)>>20; printf("res %d: start: 0x%X end: 0x%X (%d MB) flags=0x%X\n",temp,res->start,res->end,size,res->flags); if(res->flags&(IORESOURCE_MEM|IORESOURCE_PREFETCH)){ if(size>mga_ram_size && size<=64) mga_ram_size=size; } } } #endif printf(MGA_MSG" detected RAMSIZE is %d MB\n", (unsigned int) mga_ram_size); #endif } if (mga_ram_size) { if ((mga_ram_size < 4) || (mga_ram_size > 64)) { printf(MGA_MSG" invalid RAMSIZE: %d MB\n", mga_ram_size); return(EINVAL); } } if (mga_verbose > 1) printf(MGA_MSG" hardware addresses: mmio: 0x%lx, framebuffer: 0x%lx\n", pci_info.base1, pci_info.base0); mga_mmio_base = map_phys_mem(pci_info.base1,0x4000); mga_mem_base = map_phys_mem(pci_info.base0,mga_ram_size*1024*1024); if (mga_verbose > 1) printf(MGA_MSG" MMIO at %p, IRQ: %d, framebuffer: %p\n", mga_mmio_base, mga_irq, mga_mem_base); err = mtrr_set_type(pci_info.base0,mga_ram_size*1024*1024,MTRR_TYPE_WRCOMB); if(!err) printf(MGA_MSG" Set write-combining type of video memory\n"); #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) { int tmp = request_irq(mga_irq, mga_handle_irq, SA_INTERRUPT | SA_SHIRQ, "Syncfb Time Base", &mga_irq); if (tmp) { printf("syncfb (mga): cannot register irq %d (Err: %d)\n", mga_irq, tmp); mga_irq=-1; } else { printf("syncfb (mga): registered irq %d\n", mga_irq); } } else { printf("syncfb (mga): No valid irq was found\n"); mga_irq=-1; } #else printf(MGA_MSG" IRQ support disabled\n"); mga_irq=-1; #endif #ifdef CRTC2 memset(&cregs_save, 0, sizeof(cregs_save)); #endif return(0); } void VIDIX_NAME(vixDestroy)(void) { if (mga_verbose) printf(MGA_MSG" destroy\n"); /* FIXME turn off BES */ vid_src_ready = 0; regs.besctl &= ~1; regs.besglobctl &= ~(1<<6); // UYVY format selected // mga_config.colkey_on=0; //!!! mga_vid_write_regs(1); mga_vid_in_use = 0; #ifdef MGA_ALLOW_IRQ if (mga_irq != -1) free_irq(mga_irq, &mga_irq); #endif if (mga_mmio_base) unmap_phys_mem(mga_mmio_base, 0x4000); if (mga_mem_base) unmap_phys_mem(mga_mem_base, mga_ram_size); return; } int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { int supports=0; if (mga_verbose) printf(MGA_MSG" query fourcc (%x)\n", to->fourcc); switch(to->fourcc) { case IMGFMT_YV12: case IMGFMT_IYUV: case IMGFMT_I420: supports = is_g400 ? 1 : 0; case IMGFMT_NV12: supports = is_g400 ? 0 : 1; case IMGFMT_YUY2: case IMGFMT_UYVY: supports = 1; break; default: supports = 0; } if(!supports) { to->depth = to->flags = 0; return(ENOTSUP); } to->depth = VID_DEPTH_12BPP | VID_DEPTH_15BPP | VID_DEPTH_16BPP | VID_DEPTH_24BPP | VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return(0); } unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &mga_cap, sizeof(vidix_capability_t)); return(0); } int VIDIX_NAME(vixGetGrKeys)(vidix_grkey_t *grkey) { memcpy(grkey, &mga_grkey, sizeof(vidix_grkey_t)); return(0); } int VIDIX_NAME(vixSetGrKeys)(const vidix_grkey_t *grkey) { memcpy(&mga_grkey, grkey, sizeof(vidix_grkey_t)); return(0); } int VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq) { uint32_t luma; float factor = 255.0 / 2000; /* contrast and brightness control isn't supported on G200 - alex */ if (!is_g400) { if (mga_verbose) printf(MGA_MSG" equalizer isn't supported with G200\n"); return(ENOTSUP); } luma = regs.beslumactl; if (eq->cap & VEQ_CAP_BRIGHTNESS) { luma &= 0xffff; luma |= (((int)(eq->brightness * factor) & 0xff) << 16); } if (eq->cap & VEQ_CAP_CONTRAST) { luma &= 0xffff << 16; luma |= ((int)((eq->contrast + 1000) * factor) & 0xff); } regs.beslumactl = luma; #ifdef BES writel(BESLUMACTL, regs.beslumactl); #endif return(0); } int VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq) { float factor = 2000.0 / 255; /* contrast and brightness control isn't supported on G200 - alex */ if (!is_g400) { if (mga_verbose) printf(MGA_MSG" equalizer isn't supported with G200\n"); return(ENOTSUP); } // BESLUMACTL is WO only registr! // this will not work: regs.beslumactl = readl(BESLUMACTL); eq->brightness = ((signed char)((regs.beslumactl >> 16) & 0xff)) * factor; eq->contrast = (regs.beslumactl & 0xFF) * factor - 1000; eq->cap = VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST; return(0); } xine-lib-1.2/contrib/vidix/drivers/cyberblade_regs.h0000644000175000017500000000763214647725152020422 0ustar meme/* * Copyright 1992-2000 by Alan Hourihane, Wigan, England. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of Alan Hourihane not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Alan Hourihane makes no representations * about the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, 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. * * Author: Alan Hourihane, alanh@fairlite.demon.co.uk */ /* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/trident/trident_regs.h,v 1.22 2002/01/11 13:06:30 alanh Exp $ */ #define DEBUG 1 #define NTSC 14.31818 #define PAL 17.73448 /* General Registers */ #define SPR 0x1F /* Software Programming Register (videoram) */ /* 3C4 */ #define RevisionID 0x09 #define ConfPort1 0x0C #define ConfPort2 0x0C #define NewMode2 0x0D #define OldMode2 0x00 /* Should be 0x0D - dealt with in trident_dac.c */ #define OldMode1 0x0E #define NewMode1 0x0E #define Protection 0x11 #define MCLKLow 0x16 #define MCLKHigh 0x17 #define ClockLow 0x18 #define ClockHigh 0x19 #define SSetup 0x20 #define SKey 0x37 #define SPKey 0x57 /* 3x4 */ #define Offset 0x13 #define Underline 0x14 #define CRTCMode 0x17 #define CRTCModuleTest 0x1E #define FIFOControl 0x20 #define LinearAddReg 0x21 #define DRAMTiming 0x23 #define New32 0x23 #define RAMDACTiming 0x25 #define CRTHiOrd 0x27 #define AddColReg 0x29 #define InterfaceSel 0x2A #define HorizOverflow 0x2B #define GETest 0x2D #define Performance 0x2F #define GraphEngReg 0x36 #define I2C 0x37 #define PixelBusReg 0x38 #define PCIReg 0x39 #define DRAMControl 0x3A #define MiscContReg 0x3C #define CursorXLow 0x40 #define CursorXHigh 0x41 #define CursorYLow 0x42 #define CursorYHigh 0x43 #define CursorLocLow 0x44 #define CursorLocHigh 0x45 #define CursorXOffset 0x46 #define CursorYOffset 0x47 #define CursorFG1 0x48 #define CursorFG2 0x49 #define CursorFG3 0x4A #define CursorFG4 0x4B #define CursorBG1 0x4C #define CursorBG2 0x4D #define CursorBG3 0x4E #define CursorBG4 0x4F #define CursorControl 0x50 #define PCIRetry 0x55 #define PreEndControl 0x56 #define PreEndFetch 0x57 #define PCIMaster 0x60 #define Enhancement0 0x62 #define NewEDO 0x64 /* --- Additions by AMR for Vidix support --- */ #define VideoWin1_HScale 0x80 #define VideoWin1_VScale 0x82 #define VideoWin1_Start 0x86 #define VideoWin1_Stop 0x8a #define Video_Flags 0x8e #define VideoWin1_Y_BPR 0x90 #define VideoWin1_Y_Offset 0x92 #define Video_LineBufferThreshold 0x95 #define Video_LineBufferLevel 0x96 #define Video_Flags2 0x97 /* --- */ #define TVinterface 0xC0 #define TVMode 0xC1 #define ClockControl 0xCF /* 3CE */ #define MiscExtFunc 0x0F #define MiscIntContReg 0x2F #define CyberControl 0x30 #define CyberEnhance 0x31 #define FPConfig 0x33 #define VertStretch 0x52 #define HorStretch 0x53 #define BiosMode 0x5c #define BiosNewMode1 0x5a #define BiosNewMode2 0x5c #define BiosReg 0x5d /* --- IO Macros by AMR --- */ #define CRINB(reg) (OUTPORT8(0x3d4,reg), INPORT8(0x3d5)) #define SRINB(reg) (OUTPORT8(0x3c4,reg), INPORT8(0x3c5)) #define CROUTB(reg,val) (OUTPORT8(0x3d4,reg), OUTPORT8(0x3d5,val)) #define SROUTB(reg,val) (OUTPORT8(0x3c4,reg), OUTPORT8(0x3c5,val)) /* --- */ xine-lib-1.2/contrib/vidix/drivers/glint_regs.h0000644000175000017500000012644114647725152017443 0ustar meme/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/glint_regs.h,v 1.31 2001/12/08 16:01:52 alanh Exp $ */ /* * glint register file * * Copyright by Stefan Dirsch, Dirk Hohndel, Alan Hourihane * Authors: Alan Hourihane, * Dirk Hohndel, * Stefan Dirsch, * Simon P., * * this work is sponsored by S.u.S.E. GmbH, Fuerth, Elsa GmbH, Aachen and * Siemens Nixdorf Informationssysteme * */ #ifndef _GLINTREG_H_ #define _GLINTREG_H_ /********************************************** * GLINT 500TX Configuration Region Registers * ***********************************************/ /* Device Identification */ #define CFGVendorId 0x0000 #define PCI_VENDOR_3DLABS 0x3D3D #define PCI_VENDOR_TI 0x104C #define CFGDeviceId 0x0002 #define CFGRevisionId 0x08 #define CFGClassCode 0x09 #define CFGHeaderType 0x0E /* Device Control/Status */ #define CFGCommand 0x04 #define CFGStatus 0x06 /* Miscellaneous Functions */ #define CFGBist 0x0f #define CFGLatTimer 0x0d #define CFGCacheLine 0x0c #define CFGMaxLat 0x3f #define CFGMinGrant 0x3e #define CFGIntPin 0x3d #define CFGIntLine 0x3c /* Base Adresses */ #define CFGBaseAddr0 0x10 #define CFGBaseAddr1 0x14 #define CFGBaseAddr2 0x18 #define CFGBaseAddr3 0x1C #define CFGBaseAddr4 0x20 #define CFGRomAddr 0x30 /********************************** * GLINT 500TX Region 0 Registers * **********************************/ /* Control Status Registers */ #define ResetStatus 0x0000 #define IntEnable 0x0008 #define IntFlags 0x0010 #define InFIFOSpace 0x0018 #define OutFIFOWords 0x0020 #define DMAAddress 0x0028 #define DMACount 0x0030 #define ErrorFlags 0x0038 #define VClkCtl 0x0040 #define TestRegister 0x0048 #define Aperture0 0x0050 #define Aperture1 0x0058 #define DMAControl 0x0060 #define FIFODis 0x0068 /* GLINT PerMedia Region 0 additional Registers */ #define ChipConfig 0x0070 #define SCLK_SEL_MASK (3 << 10) #define SCLK_SEL_MCLK_HALF (3 << 10) #define ByDMAControl 0x00D8 /* GLINT 500TX LocalBuffer Registers */ #define LBMemoryCtl 0x1000 #define LBNumBanksMask 0x00000001 #define LBNumBanks1 (0) #define LBNumBanks2 (1) #define LBPageSizeMask 0x00000006 #define LBPageSize256 (0<<1) #define LBPageSize512 (1<<1) #define LBPageSize1024 (2<<1) #define LBPageSize2048 (3<<1) #define LBRASCASLowMask 0x00000018 #define LBRASCASLow2 (0<<3) #define LBRASCASLow3 (1<<3) #define LBRASCASLow4 (2<<3) #define LBRASCASLow5 (3<<3) #define LBRASPrechargeMask 0x00000060 #define LBRASPrecharge2 (0<<5) #define LBRASPrecharge3 (1<<5) #define LBRASPrecharge4 (2<<5) #define LBRASPrecharge5 (3<<5) #define LBCASLowMask 0x00000180 #define LBCASLow1 (0<<7) #define LBCASLow2 (1<<7) #define LBCASLow3 (2<<7) #define LBCASLow4 (3<<7) #define LBPageModeMask 0x00000200 #define LBPageModeEnabled (0<<9) #define LBPageModeDisabled (1<<9) #define LBRefreshCountMask 0x0003fc00 #define LBRefreshCountShift 10 #define LBMemoryEDO 0x1008 #define LBEDOMask 0x00000001 #define LBEDODisabled (0) #define LBEDOEnabled (1) #define LBEDOBankSizeMask 0x0000000e #define LBEDOBankSizeDiabled (0<<1) #define LBEDOBankSize256K (1<<1) #define LBEDOBankSize512K (2<<1) #define LBEDOBankSize1M (3<<1) #define LBEDOBankSize2M (4<<1) #define LBEDOBankSize4M (5<<1) #define LBEDOBankSize8M (6<<1) #define LBEDOBankSize16M (7<<1) #define LBTwoPageDetectorMask 0x00000010 #define LBSinglePageDetector (0<<4) #define LBTwoPageDetector (1<<4) /* GLINT PerMedia Memory Control Registers */ #define PMReboot 0x1000 #define PMRomControl 0x1040 #define PMBootAddress 0x1080 #define PMMemConfig 0x10C0 #define RowCharge8 1 << 10 #define TimeRCD8 1 << 7 #define TimeRC8 0x6 << 3 #define TimeRP8 1 #define CAS3Latency8 0 << 16 #define BootAdress8 0x10 #define NumberBanks8 0x3 << 29 #define RefreshCount8 0x41 << 21 #define TimeRASMin8 1 << 13 #define DeadCycle8 1 << 17 #define BankDelay8 0 << 18 #define Burst1Cycle8 1 << 31 #define SDRAM8 0 << 4 #define RowCharge6 1 << 10 #define TimeRCD6 1 << 7 #define TimeRC6 0x6 << 3 #define TimeRP6 0x2 #define CAS3Latency6 1 << 16 #define BootAdress6 0x60 #define NumberBanks6 0x2 << 29 #define RefreshCount6 0x41 << 21 #define TimeRASMin6 1 << 13 #define DeadCycle6 1 << 17 #define BankDelay6 0 << 18 #define Burst1Cycle6 1 << 31 #define SDRAM6 0 << 4 #define RowCharge4 0 << 10 #define TimeRCD4 0 << 7 #define TimeRC4 0x4 << 3 #define TimeRP4 1 #define CAS3Latency4 0 << 16 #define BootAdress4 0x10 #define NumberBanks4 1 << 29 #define RefreshCount4 0x30 << 21 #define TimeRASMin4 1 << 13 #define DeadCycle4 0 << 17 #define BankDelay4 0 << 18 #define Burst1Cycle4 1 << 31 #define SDRAM4 0 << 4 /* Permedia 2 Control */ #define MemControl 0x1040 #define PMBypassWriteMask 0x1100 #define PMFramebufferWriteMask 0x1140 #define PMCount 0x1180 /* Framebuffer Registers */ #define FBMemoryCtl 0x1800 #define FBModeSel 0x1808 #define FBGCWrMask 0x1810 #define FBGCColorLower 0x1818 #define FBTXMemCtl 0x1820 #define FBWrMaskk 0x1830 #define FBGCColorUpper 0x1838 /* Core FIFO */ #define OutputFIFO 0x2000 /* 500TX Internal Video Registers */ #define VTGHLimit 0x3000 #define VTGHSyncStart 0x3008 #define VTGHSyncEnd 0x3010 #define VTGHBlankEnd 0x3018 #define VTGVLimit 0x3020 #define VTGVSyncStart 0x3028 #define VTGVSyncEnd 0x3030 #define VTGVBlankEnd 0x3038 #define VTGHGateStart 0x3040 #define VTGHGateEnd 0x3048 #define VTGVGateStart 0x3050 #define VTGVGateEnd 0x3058 #define VTGPolarity 0x3060 #define VTGFrameRowAddr 0x3068 #define VTGVLineNumber 0x3070 #define VTGSerialClk 0x3078 #define VTGModeCtl 0x3080 /* Permedia Video Control Registers */ #define PMScreenBase 0x3000 #define PMScreenStride 0x3008 #define PMHTotal 0x3010 #define PMHgEnd 0x3018 #define PMHbEnd 0x3020 #define PMHsStart 0x3028 #define PMHsEnd 0x3030 #define PMVTotal 0x3038 #define PMVbEnd 0x3040 #define PMVsStart 0x3048 #define PMVsEnd 0x3050 #define PMVideoControl 0x3058 #define PMInterruptLine 0x3060 #define PMDDCData 0x3068 #define DataIn (1<<0) #define ClkIn (1<<1) #define DataOut (1<<2) #define ClkOut (1<<3) #define PMLineCount 0x3070 #define PMFifoControl 0x3078 /* Permedia 2 RAMDAC Registers */ #define PM2DACWriteAddress 0x4000 #define PM2DACIndexReg 0x4000 #define PM2DACData 0x4008 #define PM2DACReadMask 0x4010 #define PM2DACReadAddress 0x4018 #define PM2DACCursorColorAddress 0x4020 #define PM2DACCursorColorData 0x4028 #define PM2DACIndexData 0x4050 #define PM2DACCursorData 0x4058 #define PM2DACCursorXLsb 0x4060 #define PM2DACCursorXMsb 0x4068 #define PM2DACCursorYLsb 0x4070 #define PM2DACCursorYMsb 0x4078 #define PM2DACCursorControl 0x06 #define PM2DACIndexCMR 0x18 #define PM2DAC_TRUECOLOR 0x80 #define PM2DAC_RGB 0x20 #define PM2DAC_GRAPHICS 0x10 #define PM2DAC_PACKED 0x09 #define PM2DAC_8888 0x08 #define PM2DAC_565 0x06 #define PM2DAC_4444 0x05 #define PM2DAC_5551 0x04 #define PM2DAC_2321 0x03 #define PM2DAC_2320 0x02 #define PM2DAC_332 0x01 #define PM2DAC_CI8 0x00 #define PM2DACIndexMDCR 0x19 #define PM2DACIndexPalettePage 0x1c #define PM2DACIndexMCR 0x1e #define PM2DACIndexClockAM 0x20 #define PM2DACIndexClockAN 0x21 #define PM2DACIndexClockAP 0x22 #define PM2DACIndexClockBM 0x23 #define PM2DACIndexClockBN 0x24 #define PM2DACIndexClockBP 0x25 #define PM2DACIndexClockCM 0x26 #define PM2DACIndexClockCN 0x27 #define PM2DACIndexClockCP 0x28 #define PM2DACIndexClockStatus 0x29 #define PM2DACIndexMemClockM 0x30 #define PM2DACIndexMemClockN 0x31 #define PM2DACIndexMemClockP 0x32 #define PM2DACIndexMemClockStatus 0x33 #define PM2DACIndexColorKeyControl 0x40 #define PM2DACIndexColorKeyOverlay 0x41 #define PM2DACIndexColorKeyRed 0x42 #define PM2DACIndexColorKeyGreen 0x43 #define PM2DACIndexColorKeyBlue 0x44 /* Permedia 2V extensions */ #define PM2VDACRDMiscControl 0x000 #define PM2VDACRDSyncControl 0x001 #define PM2VDACRDDACControl 0x002 #define PM2VDACRDPixelSize 0x003 #define PM2VDACRDColorFormat 0x004 #define PM2VDACRDCursorMode 0x005 #define PM2VDACRDCursorXLow 0x007 #define PM2VDACRDCursorXHigh 0x008 #define PM2VDACRDCursorYLow 0x009 #define PM2VDACRDCursorYHigh 0x00A #define PM2VDACRDCursorHotSpotX 0x00B #define PM2VDACRDCursorHotSpotY 0x00C #define PM2VDACRDOverlayKey 0x00D #define PM2VDACRDPan 0x00E #define PM2VDACRDSense 0x00F #define PM2VDACRDCheckControl 0x018 #define PM2VDACIndexClockControl 0x200 #define PM2VDACRDDClk0PreScale 0x201 #define PM2VDACRDDClk0FeedbackScale 0x202 #define PM2VDACRDDClk0PostScale 0x203 #define PM2VDACRDDClk1PreScale 0x204 #define PM2VDACRDDClk1FeedbackScale 0x205 #define PM2VDACRDDClk1PostScale 0x206 #define PM2VDACRDMClkControl 0x20D #define PM2VDACRDMClkPreScale 0x20E #define PM2VDACRDMClkFeedbackScale 0x20F #define PM2VDACRDMClkPostScale 0x210 #define PM2VDACRDCursorPalette 0x303 #define PM2VDACRDCursorPattern 0x400 #define PM2VDACIndexRegLow 0x4020 #define PM2VDACIndexRegHigh 0x4028 #define PM2VDACIndexData 0x4030 #define PM2VDACRDIndexControl 0x4038 /* Permedia 2 Video Streams Unit Registers */ #define VSBIntFlag (1<<8) #define VSAIntFlag (1<<9) #define VSConfiguration 0x5800 #define VS_UnitMode_ROM 0 #define VS_UnitMode_AB8 3 #define VS_UnitMode_Mask 7 #define VS_GPBusMode_A (1<<3) #define VS_HRefPolarityA (1<<9) #define VS_VRefPolarityA (1<<10) #define VS_VActivePolarityA (1<<11) #define VS_UseFieldA (1<<12) #define VS_FieldPolarityA (1<<13) #define VS_FieldEdgeA (1<<14) #define VS_VActiveVBIA (1<<15) #define VS_InterlaceA (1<<16) #define VS_ReverseDataA (1<<17) #define VS_HRefPolarityB (1<<18) #define VS_VRefPolarityB (1<<19) #define VS_VActivePolarityB (1<<20) #define VS_UseFieldB (1<<21) #define VS_FieldPolarityB (1<<22) #define VS_FieldEdgeB (1<<23) #define VS_VActiveVBIB (1<<24) #define VS_InterlaceB (1<<25) #define VS_ColorSpaceB_RGB (1<<26) #define VS_ReverseDataB (1<<27) #define VS_DoubleEdgeB (1<<28) #define VSStatus 0x5808 #define VS_FieldOne0A (1<<9) #define VS_FieldOne1A (1<<10) #define VS_FieldOne2A (1<<11) #define VS_InvalidInterlaceA (1<<12) #define VS_FieldOne0B (1<<17) #define VS_FieldOne1B (1<<18) #define VS_FieldOne2B (1<<19) #define VS_InvalidInterlaceB (1<<20) #define VSSerialBusControl 0x5810 #define VSABase 0x5900 #define VSA_Video (1<<0) #define VSA_VBI (1<<1) #define VSA_BufferCtl (1<<2) #define VSA_MirrorX (1<<7) #define VSA_MirrorY (1<<8) #define VSA_Discard_None (0<<9) #define VSA_Discard_FieldOne (1<<9) #define VSA_Discard_FieldTwo (2<<9) #define VSA_CombineFields (1<<11) #define VSA_LockToStreamB (1<<12) #define VSBBase 0x5A00 #define VSB_Video (1<<0) #define VSB_VBI (1<<1) #define VSB_BufferCtl (1<<2) #define VSB_CombineFields (1<<3) #define VSB_RGBOrder (1<<11) #define VSB_GammaCorrect (1<<12) #define VSB_LockToStreamA (1<<13) #define VSControl 0x0000 #define VSInterrupt 0x0008 #define VSCurrentLine 0x0010 #define VSVideoAddressHost 0x0018 #define VSVideoAddressIndex 0x0020 #define VSVideoAddress0 0x0028 #define VSVideoAddress1 0x0030 #define VSVideoAddress2 0x0038 #define VSVideoStride 0x0040 #define VSVideoStartLine 0x0048 #define VSVideoEndLine 0x0050 #define VSVideoStartData 0x0058 #define VSVideoEndData 0x0060 #define VSVBIAddressHost 0x0068 #define VSVBIAddressIndex 0x0070 #define VSVBIAddress0 0x0078 #define VSVBIAddress1 0x0080 #define VSVBIAddress2 0x0088 #define VSVBIStride 0x0090 #define VSVBIStartLine 0x0098 #define VSVBIEndLine 0x00A0 #define VSVBIStartData 0x00A8 #define VSVBIEndData 0x00B0 #define VSFifoControl 0x00B8 /********************************** * GLINT Delta Region 0 Registers * **********************************/ /* Control Status Registers */ #define DResetStatus 0x0800 #define DIntEnable 0x0808 #define DIntFlags 0x0810 #define DErrorFlags 0x0838 #define DTestRegister 0x0848 #define DFIFODis 0x0868 /********************************** * GLINT Gamma Region 0 Registers * **********************************/ /* Control Status Registers */ #define GInFIFOSpace 0x0018 #define GDMAAddress 0x0028 #define GDMACount 0x0030 #define GDMAControl 0x0060 #define GOutDMA 0x0080 #define GOutDMACount 0x0088 #define GResetStatus 0x0800 #define GIntEnable 0x0808 #define GIntFlags 0x0810 #define GErrorFlags 0x0838 #define GTestRegister 0x0848 #define GFIFODis 0x0868 #define GChipConfig 0x0870 #define GChipAGPCapable 1 << 0 #define GChipAGPSideband 1 << 1 #define GChipMultiGLINTApMask 3 << 19 #define GChipMultiGLINTAp_0M 0 << 19 #define GChipMultiGLINTAp_16M 1 << 19 #define GChipMultiGLINTAp_32M 2 << 19 #define GChipMultiGLINTAp_64M 3 << 19 #define GCSRAperture 0x0878 #define GCSRSecondaryGLINTMapEn 1 << 0 #define GPageTableAddr 0x0c00 #define GPageTableLength 0x0c08 #define GDelayTimer 0x0c38 #define GCommandMode 0x0c40 #define GCommandIntEnable 0x0c48 #define GCommandIntFlags 0x0c50 #define GCommandErrorFlags 0x0c58 #define GCommandStatus 0x0c60 #define GCommandFaultingAddr 0x0c68 #define GVertexFaultingAddr 0x0c70 #define GWriteFaultingAddr 0x0c88 #define GFeedbackSelectCount 0x0c98 #define GGammaProcessorMode 0x0cb8 #define GVGAShadow 0x0d00 #define GMultGLINTAperture 0x0d08 #define GMultGLINT1 0x0d10 #define GMultGLINT2 0x0d18 /************************ * GLINT Core Registers * ************************/ #define GLINT_TAG(major,offset) (((major) << 7) | ((offset) << 3)) #define GLINT_TAG_ADDR(major,offset) (0x8000 | GLINT_TAG((major),(offset))) #define UNIT_DISABLE 0 #define UNIT_ENABLE 1 #define StartXDom GLINT_TAG_ADDR(0x00,0x00) #define dXDom GLINT_TAG_ADDR(0x00,0x01) #define StartXSub GLINT_TAG_ADDR(0x00,0x02) #define dXSub GLINT_TAG_ADDR(0x00,0x03) #define StartY GLINT_TAG_ADDR(0x00,0x04) #define dY GLINT_TAG_ADDR(0x00,0x05) #define GLINTCount GLINT_TAG_ADDR(0x00,0x06) #define Render GLINT_TAG_ADDR(0x00,0x07) #define AreaStippleEnable 0x00001 #define LineStippleEnable 0x00002 #define ResetLineStipple 0x00004 #define FastFillEnable 0x00008 #define PrimitiveLine 0 #define PrimitiveTrapezoid 0x00040 #define PrimitivePoint 0x00080 #define PrimitiveRectangle 0x000C0 #define AntialiasEnable 0x00100 #define AntialiasingQuality 0x00200 #define UsePointTable 0x00400 #define SyncOnBitMask 0x00800 #define SyncOnHostData 0x01000 #define TextureEnable 0x02000 #define FogEnable 0x04000 #define CoverageEnable 0x08000 #define SubPixelCorrectionEnable 0x10000 #define SpanOperation 0x40000 #define XPositive 1<<21 #define YPositive 1<<22 #define ContinueNewLine GLINT_TAG_ADDR(0x00,0x08) #define ContinueNewDom GLINT_TAG_ADDR(0x00,0x09) #define ContinueNewSub GLINT_TAG_ADDR(0x00,0x0a) #define Continue GLINT_TAG_ADDR(0x00,0x0b) #define FlushSpan GLINT_TAG_ADDR(0x00,0x0c) #define BitMaskPattern GLINT_TAG_ADDR(0x00,0x0d) #define PointTable0 GLINT_TAG_ADDR(0x01,0x00) #define PointTable1 GLINT_TAG_ADDR(0x01,0x01) #define PointTable2 GLINT_TAG_ADDR(0x01,0x02) #define PointTable3 GLINT_TAG_ADDR(0x01,0x03) #define RasterizerMode GLINT_TAG_ADDR(0x01,0x04) #define RMMultiGLINT 1<<17 #define BitMaskPackingEachScanline 1<<9 #define ForceBackgroundColor 1<<6 #define InvertBitMask 1<<1 #define YLimits GLINT_TAG_ADDR(0x01,0x05) #define ScanLineOwnership GLINT_TAG_ADDR(0x01,0x06) #define WaitForCompletion GLINT_TAG_ADDR(0x01,0x07) #define PixelSize GLINT_TAG_ADDR(0x01,0x08) #define XLimits GLINT_TAG_ADDR(0x01,0x09) /* PM only */ #define RectangleOrigin GLINT_TAG_ADDR(0x01,0x0A) /* PM2 only */ #define RectangleSize GLINT_TAG_ADDR(0x01,0x0B) /* PM2 only */ #define PackedDataLimits GLINT_TAG_ADDR(0x02,0x0a) /* PM only */ #define ScissorMode GLINT_TAG_ADDR(0x03,0x00) #define SCI_USER 0x01 #define SCI_SCREEN 0x02 #define SCI_USERANDSCREEN 0x03 #define ScissorMinXY GLINT_TAG_ADDR(0x03,0x01) #define ScissorMaxXY GLINT_TAG_ADDR(0x03,0x02) #define ScreenSize GLINT_TAG_ADDR(0x03,0x03) #define AreaStippleMode GLINT_TAG_ADDR(0x03,0x04) /* 0: */ /* NoMirrorY */ /* NoMirrorX */ /* NoInvertPattern */ /* YAddress_1bit */ /* XAddress_1bit */ /* UNIT_DISABLE */ #define ASM_XAddress_2bit 1 << 1 #define ASM_XAddress_3bit 2 << 1 #define ASM_XAddress_4bit 3 << 1 #define ASM_XAddress_5bit 4 << 1 #define ASM_YAddress_2bit 1 << 4 #define ASM_YAddress_3bit 2 << 4 #define ASM_YAddress_4bit 3 << 4 #define ASM_YAddress_5bit 4 << 4 #define ASM_InvertPattern 1 << 17 #define ASM_MirrorX 1 << 18 #define ASM_MirrorY 1 << 19 #define LineStippleMode GLINT_TAG_ADDR(0x03,0x05) #define LoadLineStippleCounters GLINT_TAG_ADDR(0x03,0x06) #define UpdateLineStippleCounters GLINT_TAG_ADDR(0x03,0x07) #define SaveLineStippleState GLINT_TAG_ADDR(0x03,0x08) #define WindowOrigin GLINT_TAG_ADDR(0x03,0x09) #define AreaStipplePattern0 GLINT_TAG_ADDR(0x04,0x00) #define AreaStipplePattern1 GLINT_TAG_ADDR(0x04,0x01) #define AreaStipplePattern2 GLINT_TAG_ADDR(0x04,0x02) #define AreaStipplePattern3 GLINT_TAG_ADDR(0x04,0x03) #define AreaStipplePattern4 GLINT_TAG_ADDR(0x04,0x04) #define AreaStipplePattern5 GLINT_TAG_ADDR(0x04,0x05) #define AreaStipplePattern6 GLINT_TAG_ADDR(0x04,0x06) #define AreaStipplePattern7 GLINT_TAG_ADDR(0x04,0x07) #define TextureAddressMode GLINT_TAG_ADDR(0x07,0x00) #define SStart GLINT_TAG_ADDR(0x07,0x01) #define dSdx GLINT_TAG_ADDR(0x07,0x02) #define dSdyDom GLINT_TAG_ADDR(0x07,0x03) #define TStart GLINT_TAG_ADDR(0x07,0x04) #define dTdx GLINT_TAG_ADDR(0x07,0x05) #define dTdyDom GLINT_TAG_ADDR(0x07,0x06) #define QStart GLINT_TAG_ADDR(0x07,0x07) #define dQdx GLINT_TAG_ADDR(0x07,0x08) #define dQdyDom GLINT_TAG_ADDR(0x07,0x09) #define LOD GLINT_TAG_ADDR(0x07,0x0A) #define dSdy GLINT_TAG_ADDR(0x07,0x0B) #define dTdy GLINT_TAG_ADDR(0x07,0x0C) #define dQdy GLINT_TAG_ADDR(0x07,0x0D) #define TextureReadMode GLINT_TAG_ADDR(0x09,0x00) #define TextureFormat GLINT_TAG_ADDR(0x09,0x01) #define Texture_4_Components 3 << 3 #define Texture_Texel 0 #define TextureCacheControl GLINT_TAG_ADDR(0x09,0x02) #define TextureCacheControlEnable 2 #define TextureCacheControlInvalidate 1 #define GLINTBorderColor GLINT_TAG_ADDR(0x09,0x05) #define TexelLUTIndex GLINT_TAG_ADDR(0x09,0x08) #define TexelLUTData GLINT_TAG_ADDR(0x09,0x09) #define TexelLUTAddress GLINT_TAG_ADDR(0x09,0x0A) #define TexelLUTTransfer GLINT_TAG_ADDR(0x09,0x0B) #define TextureFilterMode GLINT_TAG_ADDR(0x09,0x0C) #define TextureChromaUpper GLINT_TAG_ADDR(0x09,0x0D) #define TextureChromaLower GLINT_TAG_ADDR(0x09,0x0E) #define TxBaseAddr0 GLINT_TAG_ADDR(0x0A,0x00) #define TxBaseAddr1 GLINT_TAG_ADDR(0x0A,0x01) #define TxBaseAddr2 GLINT_TAG_ADDR(0x0A,0x02) #define TxBaseAddr3 GLINT_TAG_ADDR(0x0A,0x03) #define TxBaseAddr4 GLINT_TAG_ADDR(0x0A,0x04) #define TxBaseAddr5 GLINT_TAG_ADDR(0x0A,0x05) #define TxBaseAddr6 GLINT_TAG_ADDR(0x0A,0x06) #define TxBaseAddr7 GLINT_TAG_ADDR(0x0A,0x07) #define TxBaseAddr8 GLINT_TAG_ADDR(0x0A,0x08) #define TxBaseAddr9 GLINT_TAG_ADDR(0x0A,0x09) #define TxBaseAddr10 GLINT_TAG_ADDR(0x0A,0x0A) #define TxBaseAddr11 GLINT_TAG_ADDR(0x0A,0x0B) #define PMTextureBaseAddress GLINT_TAG_ADDR(0x0b,0x00) #define PMTextureMapFormat GLINT_TAG_ADDR(0x0b,0x01) #define PMTextureDataFormat GLINT_TAG_ADDR(0x0b,0x02) #define Texel0 GLINT_TAG_ADDR(0x0c,0x00) #define Texel1 GLINT_TAG_ADDR(0x0c,0x01) #define Texel2 GLINT_TAG_ADDR(0x0c,0x02) #define Texel3 GLINT_TAG_ADDR(0x0c,0x03) #define Texel4 GLINT_TAG_ADDR(0x0c,0x04) #define Texel5 GLINT_TAG_ADDR(0x0c,0x05) #define Texel6 GLINT_TAG_ADDR(0x0c,0x06) #define Texel7 GLINT_TAG_ADDR(0x0c,0x07) #define Interp0 GLINT_TAG_ADDR(0x0c,0x08) #define Interp1 GLINT_TAG_ADDR(0x0c,0x09) #define Interp2 GLINT_TAG_ADDR(0x0c,0x0a) #define Interp3 GLINT_TAG_ADDR(0x0c,0x0b) #define Interp4 GLINT_TAG_ADDR(0x0c,0x0c) #define TextureFilter GLINT_TAG_ADDR(0x0c,0x0d) #define PMTextureReadMode GLINT_TAG_ADDR(0x0c,0x0e) #define TexelLUTMode GLINT_TAG_ADDR(0x0c,0x0f) #define TextureColorMode GLINT_TAG_ADDR(0x0d,0x00) #define TextureTypeOpenGL 0 #define TextureTypeApple 1 << 4 #define TextureKsDDA 1 << 5 /* only Apple-Mode */ #define TextureKdDDA 1 << 6 /* only Apple-Mode */ #define TextureEnvColor GLINT_TAG_ADDR(0x0d,0x01) #define FogMode GLINT_TAG_ADDR(0x0d,0x02) /* 0: */ /* FOG RGBA */ /* UNIT_DISABLE */ #define FOG_CI 0x0002 #define FogColor GLINT_TAG_ADDR(0x0d,0x03) #define FStart GLINT_TAG_ADDR(0x0d,0x04) #define dFdx GLINT_TAG_ADDR(0x0d,0x05) #define dFdyDom GLINT_TAG_ADDR(0x0d,0x06) #define KsStart GLINT_TAG_ADDR(0x0d,0x09) #define dKsdx GLINT_TAG_ADDR(0x0d,0x0a) #define dKsdyDom GLINT_TAG_ADDR(0x0d,0x0b) #define KdStart GLINT_TAG_ADDR(0x0d,0x0c) #define dKdStart GLINT_TAG_ADDR(0x0d,0x0d) #define dKddyDom GLINT_TAG_ADDR(0x0d,0x0e) #define RStart GLINT_TAG_ADDR(0x0f,0x00) #define dRdx GLINT_TAG_ADDR(0x0f,0x01) #define dRdyDom GLINT_TAG_ADDR(0x0f,0x02) #define GStart GLINT_TAG_ADDR(0x0f,0x03) #define dGdx GLINT_TAG_ADDR(0x0f,0x04) #define dGdyDom GLINT_TAG_ADDR(0x0f,0x05) #define BStart GLINT_TAG_ADDR(0x0f,0x06) #define dBdx GLINT_TAG_ADDR(0x0f,0x07) #define dBdyDom GLINT_TAG_ADDR(0x0f,0x08) #define AStart GLINT_TAG_ADDR(0x0f,0x09) #define dAdx GLINT_TAG_ADDR(0x0f,0x0a) #define dAdyDom GLINT_TAG_ADDR(0x0f,0x0b) #define ColorDDAMode GLINT_TAG_ADDR(0x0f,0x0c) /* 0: */ #define CDDA_FlatShading 0 /* UNIT_DISABLE */ #define CDDA_GouraudShading 0x0002 #define ConstantColor GLINT_TAG_ADDR(0x0f,0x0d) #define GLINTColor GLINT_TAG_ADDR(0x0f,0x0e) #define AlphaTestMode GLINT_TAG_ADDR(0x10,0x00) #define AntialiasMode GLINT_TAG_ADDR(0x10,0x01) #define AlphaBlendMode GLINT_TAG_ADDR(0x10,0x02) /* 0: */ /* SrcZERO */ /* DstZERO */ /* ColorFormat8888 */ /* AlphaBuffer present */ /* ColorOrderBGR */ /* TypeOpenGL */ /* DstFBData */ /* UNIT_DISABLE */ #define ABM_SrcONE 1 << 1 #define ABM_SrcDST_COLOR 2 << 1 #define ABM_SrcONE_MINUS_DST_COLOR 3 << 1 #define ABM_SrcSRC_ALPHA 4 << 1 #define ABM_SrcONE_MINUS_SRC_ALPHA 5 << 1 #define ABM_SrcDST_ALPHA 6 << 1 #define ABM_SrcONE_MINUS_DST_ALPHA 7 << 1 #define ABM_SrcSRC_ALPHA_SATURATE 8 << 1 #define ABM_DstONE 1 << 5 #define ABM_DstSRC_COLOR 2 << 5 #define ABM_DstONE_MINUS_SRC_COLOR 3 << 5 #define ABM_DstSRC_ALPHA 4 << 5 #define ABM_DstONE_MINUS_SRC_ALPHA 5 << 5 #define ABM_DstDST_ALPHA 6 << 5 #define ABM_DstONE_MINUS_DST_ALPHA 7 << 5 #define ABM_ColorFormat5555 1 << 8 #define ABM_ColorFormat4444 2 << 8 #define ABM_ColorFormat4444_Front 3 << 8 #define ABM_ColorFormat4444_Back 4 << 8 #define ABM_ColorFormat332_Front 5 << 8 #define ABM_ColorFormat332_Back 6 << 8 #define ABM_ColorFormat121_Front 7 << 8 #define ABM_ColorFormat121_Back 8 << 8 #define ABM_ColorFormat555_Back 13 << 8 #define ABM_ColorFormat_CI8 14 << 8 #define ABM_ColorFormat_CI4 15 << 8 #define ABM_NoAlphaBuffer 0x1000 #define ABM_ColorOrderRGB 0x2000 #define ABM_TypeQuickDraw3D 0x4000 #define ABM_DstFBSourceData 0x8000 #define DitherMode GLINT_TAG_ADDR(0x10,0x03) /* 0: */ /* ColorOrder BGR */ /* AlphaDitherDefault */ /* ColorFormat8888 */ /* TruncateMode */ /* DitherDisable */ /* UNIT_DISABLE */ #define DTM_DitherEnable 1 << 1 #define DTM_ColorFormat5555 1 << 2 #define DTM_ColorFormat4444 2 << 2 #define DTM_ColorFormat4444_Front 3 << 2 #define DTM_ColorFormat4444_Back 4 << 2 #define DTM_ColorFormat332_Front 5 << 2 #define DTM_ColorFormat332_Back 6 << 2 #define DTM_ColorFormat121_Front 7 << 2 #define DTM_ColorFormat121_Back 8 << 2 #define DTM_ColorFormat555_Back 13 << 2 #define DTM_ColorFormat_CI8 14 << 2 #define DTM_ColorFormat_CI4 15 << 2 #define DTM_ColorOrderRGB 1 << 10 #define DTM_NoAlphaDither 1 << 14 #define DTM_RoundMode 1 << 15 #define FBSoftwareWriteMask GLINT_TAG_ADDR(0x10,0x04) #define LogicalOpMode GLINT_TAG_ADDR(0x10,0x05) #define Use_ConstantFBWriteData 0x40 #define FBWriteData GLINT_TAG_ADDR(0x10,0x06) #define RouterMode GLINT_TAG_ADDR(0x10,0x08) #define ROUTER_Depth_Texture 1 #define ROUTER_Texture_Depth 0 #define LBReadMode GLINT_TAG_ADDR(0x11,0x00) /* 0: */ /* SrcNoRead */ /* DstNoRead */ /* DataLBDefault */ /* WinTopLeft */ /* NoPatch */ /* ScanlineInterval1 */ #define LBRM_SrcEnable 1 << 9 #define LBRM_DstEnable 1 << 10 #define LBRM_DataLBStencil 1 << 16 #define LBRM_DataLBDepth 2 << 16 #define LBRM_WinBottomLeft 1 << 18 #define LBRM_DoPatch 1 << 19 #define LBRM_ScanlineInt2 1 << 20 #define LBRM_ScanlineInt4 2 << 20 #define LBRM_ScanlineInt8 3 << 20 #define LBReadFormat GLINT_TAG_ADDR(0x11,0x01) #define LBRF_DepthWidth15 0x03 /* only permedia */ #define LBRF_DepthWidth16 0x00 #define LBRF_DepthWidth24 0x01 #define LBRF_DepthWidth32 0x02 #define LBRF_StencilWidth0 (0 << 2) #define LBRF_StencilWidth4 (1 << 2) #define LBRF_StencilWidth8 (2 << 2) #define LBRF_StencilPos16 (0 << 4) #define LBRF_StencilPos20 (1 << 4) #define LBRF_StencilPos24 (2 << 4) #define LBRF_StencilPos28 (3 << 4) #define LBRF_StencilPos32 (4 << 4) #define LBRF_FrameCount0 (0 << 7) #define LBRF_FrameCount4 (1 << 7) #define LBRF_FrameCount8 (2 << 7) #define LBRF_FrameCountPos16 (0 << 9) #define LBRF_FrameCountPos20 (1 << 9) #define LBRF_FrameCountPos24 (2 << 9) #define LBRF_FrameCountPos28 (3 << 9) #define LBRF_FrameCountPos32 (4 << 9) #define LBRF_FrameCountPos36 (5 << 9) #define LBRF_FrameCountPos40 (6 << 9) #define LBRF_GIDWidth0 (0 << 12) #define LBRF_GIDWidth4 (1 << 12) #define LBRF_GIDPos16 (0 << 13) #define LBRF_GIDPos20 (1 << 13) #define LBRF_GIDPos24 (2 << 13) #define LBRF_GIDPos28 (3 << 13) #define LBRF_GIDPos32 (4 << 13) #define LBRF_GIDPos36 (5 << 13) #define LBRF_GIDPos40 (6 << 13) #define LBRF_GIDPos44 (7 << 13) #define LBRF_GIDPos48 (8 << 13) #define LBRF_Compact32 (1 << 17) #define LBSourceOffset GLINT_TAG_ADDR(0x11,0x02) #define LBStencil GLINT_TAG_ADDR(0x11,0x05) #define LBDepth GLINT_TAG_ADDR(0x11,0x06) #define LBWindowBase GLINT_TAG_ADDR(0x11,0x07) #define LBWriteMode GLINT_TAG_ADDR(0x11,0x08) #define LBWM_WriteEnable 0x1 #define LBWM_UpLoad_LBDepth 0x2 #define LBWM_UpLoad_LBStencil 0x4 #define LBWriteFormat GLINT_TAG_ADDR(0x11,0x09) #define TextureData GLINT_TAG_ADDR(0x11,0x0d) #define TextureDownloadOffset GLINT_TAG_ADDR(0x11,0x0e) #define LBWindowOffset GLINT_TAG_ADDR(0x11,0x0f) #define GLINTWindow GLINT_TAG_ADDR(0x13,0x00) #define GWIN_UnitEnable (1 << 0) #define GWIN_ForceLBUpdate (1 << 3) #define GWIN_LBUpdateSourceREG (1 << 4) #define GWIN_LBUpdateSourceLB (0 << 4) #define GWIN_StencilFCP (1 << 17) #define GWIN_DepthFCP (1 << 18) #define GWIN_OverrideWriteFilter (1 << 19) /* ??? is this needed, set by permedia (2) modules */ #define GWIN_DisableLBUpdate 0x40000 #define StencilMode GLINT_TAG_ADDR(0x13,0x01) #define StencilData GLINT_TAG_ADDR(0x13,0x02) #define GLINTStencil GLINT_TAG_ADDR(0x13,0x03) #define DepthMode GLINT_TAG_ADDR(0x13,0x04) /* 0: */ /* WriteDisable */ /* SrcCompFragment */ /* CompFuncNEVER */ /* UNIT_DISABLE */ #define DPM_WriteEnable 1 << 1 #define DPM_SrcCompLBData 1 << 2 #define DPM_SrcCompDregister 2 << 2 #define DPM_SrcCompLBSourceData 3 << 2 #define DPM_CompFuncLESS 1 << 4 #define DPM_CompFuncEQUAL 2 << 4 #define DPM_CompFuncLESS_OR_EQ 3 << 4 #define DPM_CompFuncGREATER 4 << 4 #define DPM_CompFuncNOT_EQ 5 << 4 #define DPM_CompFuncGREATER_OR_EQ 6 << 4 #define DPM_CompFuncALWAYS 7 << 4 #define GLINTDepth GLINT_TAG_ADDR(0x13,0x05) #define ZStartU GLINT_TAG_ADDR(0x13,0x06) #define ZStartL GLINT_TAG_ADDR(0x13,0x07) #define dZdxU GLINT_TAG_ADDR(0x13,0x08) #define dZdxL GLINT_TAG_ADDR(0x13,0x09) #define dZdyDomU GLINT_TAG_ADDR(0x13,0x0a) #define dZdyDomL GLINT_TAG_ADDR(0x13,0x0b) #define FastClearDepth GLINT_TAG_ADDR(0x13,0x0c) #define FBReadMode GLINT_TAG_ADDR(0x15,0x00) /* 0: */ /* SrcNoRead */ /* DstNoRead */ /* DataFBDefault */ /* WinTopLeft */ /* ScanlineInterval1 */ #define FBRM_SrcEnable 1 << 9 #define FBRM_DstEnable 1 << 10 #define FBRM_DataFBColor 1 << 15 #define FBRM_WinBottomLeft 1 << 16 #define FBRM_Packed 1 << 19 #define FBRM_ScanlineInt2 1 << 23 #define FBRM_ScanlineInt4 2 << 23 #define FBRM_ScanlineInt8 3 << 23 #define FBSourceOffset GLINT_TAG_ADDR(0x15,0x01) #define FBPixelOffset GLINT_TAG_ADDR(0x15,0x02) #define FBColor GLINT_TAG_ADDR(0x15,0x03) #define FBData GLINT_TAG_ADDR(0x15,0x04) #define FBSourceData GLINT_TAG_ADDR(0x15,0x05) #define FBWindowBase GLINT_TAG_ADDR(0x15,0x06) #define FBWriteMode GLINT_TAG_ADDR(0x15,0x07) /* 0: */ /* FBWM_NoColorUpload */ /* FBWM_WriteDisable */ #define FBWM_WriteEnable 1 #define FBWM_UploadColor 1 << 3 /* Permedia3 extensions */ #define FBWM_Enable0 1 << 12 #define FBHardwareWriteMask GLINT_TAG_ADDR(0x15,0x08) #define FBBlockColor GLINT_TAG_ADDR(0x15,0x09) #define FBReadPixel GLINT_TAG_ADDR(0x15,0x0a) /* PM */ #define PatternRamMode GLINT_TAG_ADDR(0x15,0x0f) #define PatternRamData0 GLINT_TAG_ADDR(0x16,0x00) #define PatternRamData1 GLINT_TAG_ADDR(0x16,0x01) #define PatternRamData2 GLINT_TAG_ADDR(0x16,0x02) #define PatternRamData3 GLINT_TAG_ADDR(0x16,0x03) #define PatternRamData4 GLINT_TAG_ADDR(0x16,0x04) #define PatternRamData5 GLINT_TAG_ADDR(0x16,0x05) #define PatternRamData6 GLINT_TAG_ADDR(0x16,0x06) #define PatternRamData7 GLINT_TAG_ADDR(0x16,0x07) #define FilterMode GLINT_TAG_ADDR(0x18,0x00) /* 0: */ /* CullDepthTags */ /* CullDepthData */ /* CullStencilTags */ /* CullStencilData */ /* CullColorTag */ /* CullColorData */ /* CullSyncTag */ /* CullSyncData */ /* CullStatisticTag */ /* CullStatisticData */ #define FM_PassDepthTags 0x0010 #define FM_PassDepthData 0x0020 #define FM_PassStencilTags 0x0040 #define FM_PassStencilData 0x0080 #define FM_PassColorTag 0x0100 #define FM_PassColorData 0x0200 #define FM_PassSyncTag 0x0400 #define FM_PassSyncData 0x0800 #define FM_PassStatisticTag 0x1000 #define FM_PassStatisticData 0x2000 #define Sync_tag 0x0188 #define StatisticMode GLINT_TAG_ADDR(0x18,0x01) #define MinRegion GLINT_TAG_ADDR(0x18,0x02) #define MaxRegion GLINT_TAG_ADDR(0x18,0x03) #define ResetPickResult GLINT_TAG_ADDR(0x18,0x04) #define MitHitRegion GLINT_TAG_ADDR(0x18,0x05) #define MaxHitRegion GLINT_TAG_ADDR(0x18,0x06) #define PickResult GLINT_TAG_ADDR(0x18,0x07) #define GlintSync GLINT_TAG_ADDR(0x18,0x08) #define FBBlockColorU GLINT_TAG_ADDR(0x18,0x0d) #define FBBlockColorL GLINT_TAG_ADDR(0x18,0x0e) #define SuspendUntilFrameBlank GLINT_TAG_ADDR(0x18,0x0f) #define KsRStart GLINT_TAG_ADDR(0x19,0x00) #define dKsRdx GLINT_TAG_ADDR(0x19,0x01) #define dKsRdyDom GLINT_TAG_ADDR(0x19,0x02) #define KsGStart GLINT_TAG_ADDR(0x19,0x03) #define dKsGdx GLINT_TAG_ADDR(0x19,0x04) #define dKsGdyDom GLINT_TAG_ADDR(0x19,0x05) #define KsBStart GLINT_TAG_ADDR(0x19,0x06) #define dKsBdx GLINT_TAG_ADDR(0x19,0x07) #define dKsBdyDom GLINT_TAG_ADDR(0x19,0x08) #define KdRStart GLINT_TAG_ADDR(0x1A,0x00) #define dKdRdx GLINT_TAG_ADDR(0x1A,0x01) #define dKdRdyDom GLINT_TAG_ADDR(0x1A,0x02) #define KdGStart GLINT_TAG_ADDR(0x1A,0x03) #define dKdGdx GLINT_TAG_ADDR(0x1A,0x04) #define dKdGdyDom GLINT_TAG_ADDR(0x1A,0x05) #define KdBStart GLINT_TAG_ADDR(0x1A,0x06) #define dKdBdx GLINT_TAG_ADDR(0x1A,0x07) #define dKdBdyDom GLINT_TAG_ADDR(0x1A,0x08) #define FBSourceBase GLINT_TAG_ADDR(0x1B,0x00) #define FBSourceDelta GLINT_TAG_ADDR(0x1B,0x01) #define Config GLINT_TAG_ADDR(0x1B,0x02) #define CFBRM_SrcEnable 1<<0 #define CFBRM_DstEnable 1<<1 #define CFBRM_Packed 1<<2 #define CWM_Enable 1<<3 #define CCDDA_Enable 1<<4 #define CLogOp_Enable 1<<5 #define ContextDump GLINT_TAG_ADDR(0x1B,0x08) #define ContextRestore GLINT_TAG_ADDR(0x1B,0x09) #define ContextData GLINT_TAG_ADDR(0x1B,0x0a) #define TexelLUT0 GLINT_TAG_ADDR(0x1D,0x00) #define TexelLUT1 GLINT_TAG_ADDR(0x1D,0x01) #define TexelLUT2 GLINT_TAG_ADDR(0x1D,0x02) #define TexelLUT3 GLINT_TAG_ADDR(0x1D,0x03) #define TexelLUT4 GLINT_TAG_ADDR(0x1D,0x04) #define TexelLUT5 GLINT_TAG_ADDR(0x1D,0x05) #define TexelLUT6 GLINT_TAG_ADDR(0x1D,0x06) #define TexelLUT7 GLINT_TAG_ADDR(0x1D,0x07) #define TexelLUT8 GLINT_TAG_ADDR(0x1D,0x08) #define TexelLUT9 GLINT_TAG_ADDR(0x1D,0x09) #define TexelLUT10 GLINT_TAG_ADDR(0x1D,0x0A) #define TexelLUT11 GLINT_TAG_ADDR(0x1D,0x0B) #define TexelLUT12 GLINT_TAG_ADDR(0x1D,0x0C) #define TexelLUT13 GLINT_TAG_ADDR(0x1D,0x0D) #define TexelLUT14 GLINT_TAG_ADDR(0x1D,0x0E) #define TexelLUT15 GLINT_TAG_ADDR(0x1D,0x0F) #define YUVMode GLINT_TAG_ADDR(0x1E,0x00) #define ChromaUpper GLINT_TAG_ADDR(0x1E,0x01) #define ChromaLower GLINT_TAG_ADDR(0x1E,0x02) #define ChromaTestMode GLINT_TAG_ADDR(0x1E,0x03) #define AlphaMapUpperBound GLINT_TAG_ADDR(0x1E,0x03) /* PM2 */ #define AlphaMapLowerBound GLINT_TAG_ADDR(0x1E,0x04) /* PM2 */ /****************************** * GLINT Delta Core Registers * ******************************/ #define V0FixedTag GLINT_TAG_ADDR(0x20,0x00) #define V1FixedTag GLINT_TAG_ADDR(0x21,0x00) #define V2FixedTag GLINT_TAG_ADDR(0x22,0x00) #define V0FloatTag GLINT_TAG_ADDR(0x23,0x00) #define V1FloatTag GLINT_TAG_ADDR(0x24,0x00) #define V2FloatTag GLINT_TAG_ADDR(0x25,0x00) #define VPAR_s 0x00 #define VPAR_t 0x08 #define VPAR_q 0x10 #define VPAR_Ks 0x18 #define VPAR_Kd 0x20 /* have changed colors in ramdac ! #define VPAR_R 0x28 #define VPAR_G 0x30 #define VPAR_B 0x38 #define VPAR_A 0x40 */ #define VPAR_B 0x28 #define VPAR_G 0x30 #define VPAR_R 0x38 #define VPAR_A 0x40 #define VPAR_f 0x48 #define VPAR_x 0x50 #define VPAR_y 0x58 #define VPAR_z 0x60 #define DeltaModeTag GLINT_TAG_ADDR(0x26,0x00) /* 0: */ /* GLINT_300SX */ /* DeltaMode Register Bit Field Assignments */ #define DM_GLINT_300SX 0x0000 #define DM_GLINT_500TX 0x0001 #define DM_PERMEDIA 0x0002 #define DM_Depth_16BPP (1 << 2) #define DM_Depth_24BPP (2 << 2) #define DM_Depth_32BPP (3 << 2) #define DM_FogEnable 0x0010 #define DM_TextureEnable 0x0020 #define DM_SmoothShadingEnable 0x0040 #define DM_DepthEnable 0x0080 #define DM_SpecularTextureEnable 0x0100 #define DM_DiffuseTextureEnable 0x0200 #define DM_SubPixelCorrectionEnable 0x0400 #define DM_DiamondExit 0x0800 #define DM_NoDraw 0x1000 #define DM_ClampEnable 0x2000 #define DM_ClampedTexParMode 0x4000 #define DM_NormalizedTexParMode 0xC000 #define DDCMD_AreaStrippleEnable 0x0001 #define DDCMD_LineStrippleEnable 0x0002 #define DDCMD_ResetLineStripple 1 << 2 #define DDCMD_FastFillEnable 1 << 3 /* 2 Bits reserved */ #define DDCMD_PrimitiveType_Point 2 << 6 #define DDCMD_PrimitiveType_Line 0 << 6 #define DDCMD_PrimitiveType_Trapezoid 1 << 6 #define DDCMD_AntialiasEnable 1 << 8 #define DDCMD_AntialiasingQuality 1 << 9 #define DDCMD_UsePointTable 1 << 10 #define DDCMD_SyncOnBitMask 1 << 11 #define DDCMD_SyncOnHostDate 1 << 12 #define DDCMD_TextureEnable 1 << 13 #define DDCMD_FogEnable 1 << 14 #define DDCMD_CoverageEnable 1 << 15 #define DDCMD_SubPixelCorrectionEnable 1 << 16 #define DrawTriangle GLINT_TAG_ADDR(0x26,0x01) #define RepeatTriangle GLINT_TAG_ADDR(0x26,0x02) #define DrawLine01 GLINT_TAG_ADDR(0x26,0x03) #define DrawLine10 GLINT_TAG_ADDR(0x26,0x04) #define RepeatLine GLINT_TAG_ADDR(0x26,0x05) #define BroadcastMask GLINT_TAG_ADDR(0x26,0x0F) /* Permedia 3 - Accelerator Extensions */ #define FillRectanglePosition 0x8348 #define FillRender2D 0x8350 #define FBDstReadBufAddr0 0xAE80 #define FBDstReadBufOffset0 0xAEA0 #define FBDstReadBufWidth0 0xAEC0 #define FBDstReadMode 0xAEE0 #define FBDRM_Enable0 1<<8 #define FBDRM_Blocking 1<<24 #define FBDstReadEnables 0xAEE8 #define FBSrcReadMode 0xAF00 #define FBSRM_Blocking 1<<11 #define FBSrcReadBufAddr 0xAF08 #define FBSrcReadBufOffset0 0xAF10 #define FBSrcReadBufWidth 0xAF18 #define FBWriteBufAddr0 0xB000 #define FBWriteBufOffset0 0xB020 #define FBWriteBufWidth0 0xB040 #define FBBlockColorBack 0xB0A0 #define ForegroundColor 0xB0C0 #define BackgroundColor 0xB0C8 #define RectanglePosition 0xB600 #define Render2D 0xB640 /* Colorformats */ #define BGR555 1 #define BGR565 16 #define CI8 14 #define CI4 15 #ifdef DEBUG #define GLINT_WRITE_REG(v,r) \ GLINT_VERB_WRITE_REG(pGlint,v,r,__FILE__,__LINE__) #define GLINT_READ_REG(r) \ GLINT_VERB_READ_REG(pGlint,r,__FILE__,__LINE__) #else #define GLINT_WRITE_REG(v,r) \ MMIO_OUT32(pGlint->IOBase + pGlint->IOOffset,(unsigned long)(r), (v)) #define GLINT_READ_REG(r) \ MMIO_IN32(pGlint->IOBase + pGlint->IOOffset,(unsigned long)(r)) #endif /* DEBUG */ #define GLINT_WAIT(n) \ do{ \ if (pGlint->InFifoSpace>=(n)) \ pGlint->InFifoSpace -= (n); \ else { \ int tmp; \ while((tmp=GLINT_READ_REG(InFIFOSpace))<(n)); \ /* Clamp value due to bugs in PM3 */ \ if (tmp > pGlint->FIFOSize) \ tmp = pGlint->FIFOSize; \ pGlint->InFifoSpace = tmp - (n); \ } \ }while(0) #define GLINTDACDelay(x) do { \ int delay = x; \ unsigned char tmp; \ while(delay--){tmp = GLINT_READ_REG(InFIFOSpace);}; \ } while(0) #define GLINT_MASK_WRITE_REG(v,m,r) \ GLINT_WRITE_REG((GLINT_READ_REG(r)&(m))|(v),r) #define GLINT_SLOW_WRITE_REG(v,r) \ do{ \ mem_barrier(); \ GLINT_WAIT(pGlint->FIFOSize); \ mem_barrier(); \ GLINT_WRITE_REG(v,r); \ }while(0) #define GLINT_SET_INDEX(index) \ do{ \ GLINT_SLOW_WRITE_REG(((index)>>8)&0xff,PM2VDACIndexRegHigh); \ GLINT_SLOW_WRITE_REG((index)&0xff,PM2VDACIndexRegLow); \ } while(0) #define REPLICATE(r) \ { \ if (pScrn->bitsPerPixel == 16) { \ r &= 0xFFFF; \ r |= (r<<16); \ } else \ if (pScrn->bitsPerPixel == 8) { \ r &= 0xFF; \ r |= (r<<8); \ r |= (r<<16); \ } \ } #ifndef XF86DRI #define LOADROP(rop) \ { \ if (pGlint->ROP != rop) { \ GLINT_WRITE_REG(rop<<1|UNIT_ENABLE, LogicalOpMode); \ pGlint->ROP = rop; \ } \ } #else #define LOADROP(rop) \ { \ GLINT_WRITE_REG(rop<<1|UNIT_ENABLE, LogicalOpMode); \ pGlint->ROP = rop; \ } #endif #define CHECKCLIPPING \ { \ if (pGlint->ClippingOn) { \ pGlint->ClippingOn = FALSE; \ GLINT_WAIT(1); \ GLINT_WRITE_REG(0, ScissorMode); \ } \ } #ifndef XF86DRI #define DO_PLANEMASK(planemask) \ { \ if (planemask != pGlint->planemask) { \ pGlint->planemask = planemask; \ REPLICATE(planemask); \ GLINT_WRITE_REG(planemask, FBHardwareWriteMask);\ } \ } #else #define DO_PLANEMASK(planemask) \ { \ pGlint->planemask = planemask; \ REPLICATE(planemask); \ GLINT_WRITE_REG(planemask, FBHardwareWriteMask);\ } #endif /* Permedia Save/Restore functions */ #define STOREREG(address,value) \ pReg->glintRegs[address >> 3] = value; #define SAVEREG(address) \ pReg->glintRegs[address >> 3] = GLINT_READ_REG(address); #define RESTOREREG(address) \ GLINT_SLOW_WRITE_REG(pReg->glintRegs[address >> 3], address); #define STOREDAC(address,value) \ pReg->DacRegs[address] = value; #define P2VOUT(address) \ Permedia2vOutIndReg(pScrn, address, 0x00, pReg->DacRegs[address]); #define P2VIN(address) \ pReg->DacRegs[address] = Permedia2vInIndReg(pScrn, address); /* RamDac Save/Restore functions, used by external DAC's */ #define STORERAMDAC(address,value) \ ramdacReg->DacRegs[address] = value; /* Multi Chip access */ #define ACCESSCHIP1() \ pGlint->IOOffset = 0; #define ACCESSCHIP2() \ pGlint->IOOffset = 0x10000; #endif xine-lib-1.2/contrib/vidix/drivers/sis_vid.c0000644000175000017500000012242714647725152016741 0ustar meme/** VIDIX driver for SiS 300 and 310/325 series chips. Copyright 2003 Jake Page, Sugar Media. Based on SiS Xv driver: Copyright 2002-2003 by Thomas Winischhofer, Vienna, Austria. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 2003/10/08 integrated into mplayer/vidix architecture -- Alex Beregszaszi **/ #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "sis_regs.h" #include "sis_defs.h" /** Random defines **/ #define WATCHDOG_DELAY 500000 /* Watchdog counter for retrace waiting */ #define IMAGE_MIN_WIDTH 32 /* Min and max source image sizes */ #define IMAGE_MIN_HEIGHT 24 #define IMAGE_MAX_WIDTH 720 #define IMAGE_MAX_HEIGHT 576 #define IMAGE_MAX_WIDTH_M650 1920 #define IMAGE_MAX_HEIGHT_M650 1080 #define OVERLAY_MIN_WIDTH 32 /* Minimum overlay sizes */ #define OVERLAY_MIN_HEIGHT 24 #define DISPMODE_SINGLE1 0x1 /* TW: CRT1 only */ #define DISPMODE_SINGLE2 0x2 /* TW: CRT2 only */ #define DISPMODE_MIRROR 0x4 /* TW: CRT1 + CRT2 MIRROR */ #define VMODE_INTERLACED 0x1 #define VMODE_DOUBLESCAN 0x2 typedef struct { short x1, y1, x2, y2; } BoxRec; typedef struct { int pixelFormat; uint16_t pitch; uint16_t origPitch; uint8_t keyOP; uint16_t HUSF; uint16_t VUSF; uint8_t IntBit; uint8_t wHPre; uint16_t srcW; uint16_t srcH; BoxRec dstBox; uint32_t PSY; uint32_t PSV; uint32_t PSU; uint8_t bobEnable; uint8_t contrastCtrl; uint8_t contrastFactor; uint8_t lineBufSize; uint8_t(*VBlankActiveFunc) (); uint16_t SCREENheight; } SISOverlayRec, *SISOverlayPtr; /** static variable definitions **/ static int sis_probed = 0; static pciinfo_t pci_info; unsigned int sis_verbose = 0; static uint8_t *sis_mem_base; /* static void *sis_reg_base; */ unsigned short sis_iobase; unsigned int sis_vga_engine = UNKNOWN_VGA; static unsigned int sis_displaymode = DISPMODE_SINGLE1; static unsigned int sis_has_two_overlays = 0; static unsigned int sis_bridge_is_slave = 0; static unsigned int sis_shift_value = 1; static unsigned int sis_vmode = 0; unsigned int sis_vbflags = DISPTYPE_DISP1; unsigned int sis_overlay_on_crt1 = 1; unsigned int sis_crt1_off = -1; unsigned int sis_detected_crt2_devices; unsigned int sis_force_crt2_type = CRT2_DEFAULT; unsigned int sis_device_id = -1; static int sis_format; static int sis_Yoff = 0; static int sis_Voff = 0; static int sis_Uoff = 0; static int sis_screen_width = 640; static int sis_screen_height = 480; static int sis_frames[VID_PLAY_MAXFRAMES]; static vidix_grkey_t sis_grkey; static vidix_capability_t sis_cap = { "SiS 300/310/325 Video Driver", "Jake Page", TYPE_OUTPUT, {0, 0, 0, 0}, 2048, 2048, 4, 4, -1, FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER, VENDOR_SIS, -1, {0, 0, 0, 0} }; vidix_video_eq_t sis_equal = { VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST, 200, 0, 0, 0, 0, 0, 0, 0 }; static unsigned short sis_card_ids[] = { DEVICE_SIS_300, DEVICE_SIS_315H, DEVICE_SIS_315, DEVICE_SIS_315PRO, DEVICE_SIS_330, DEVICE_SIS_540_VGA, DEVICE_SIS_550_VGA, DEVICE_SIS_630_VGA, DEVICE_SIS_650_VGA }; /** function declarations **/ extern void sis_init_video_bridge(); static void set_overlay(SISOverlayPtr pOverlay, int index); static void close_overlay(void); static void calc_scale_factor(SISOverlayPtr pOverlay, int index, int iscrt2); static void set_line_buf_size(SISOverlayPtr pOverlay); static void merge_line_buf(int enable); static void set_format(SISOverlayPtr pOverlay); static void set_colorkey(void); static void set_brightness(uint8_t brightness); static void set_contrast(uint8_t contrast); static void set_saturation(char saturation); static void set_hue(uint8_t hue); #if 0 static void set_alpha(uint8_t alpha); #endif /* IO Port access functions */ static uint8_t getvideoreg(uint8_t reg) { uint8_t ret; inSISIDXREG(SISVID, reg, ret); return (ret); } static void setvideoreg(uint8_t reg, uint8_t data) { outSISIDXREG(SISVID, reg, data); } static void setvideoregmask(uint8_t reg, uint8_t data, uint8_t mask) { uint8_t old; inSISIDXREG(SISVID, reg, old); data = (data & mask) | (old & (~mask)); outSISIDXREG(SISVID, reg, data); } static void setsrregmask(uint8_t reg, uint8_t data, uint8_t mask) { uint8_t old; inSISIDXREG(SISSR, reg, old); data = (data & mask) | (old & (~mask)); outSISIDXREG(SISSR, reg, data); } /* vblank checking*/ static uint8_t vblank_active_CRT1() { /* this may be too simplistic? */ return (inSISREG(SISINPSTAT) & 0x08); } static uint8_t vblank_active_CRT2() { uint8_t ret; if (sis_vga_engine == SIS_315_VGA) { inSISIDXREG(SISPART1, Index_310_CRT2_FC_VR, ret); } else { inSISIDXREG(SISPART1, Index_CRT2_FC_VR, ret); } return ((ret & 0x02) ^ 0x02); } unsigned int vixGetVersion(void) { return (VIDIX_VERSION); } static int find_chip(unsigned chip_id) { unsigned i; for (i = 0; i < sizeof(sis_card_ids) / sizeof(unsigned short); i++) { if (chip_id == sis_card_ids[i]) return i; } return -1; } int vixProbe(int verbose, int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i, num_pci; int err; sis_verbose = verbose; force = force; err = pci_scan(lst, &num_pci); if (err) { printf("[SiS] Error occurred during pci scan: %s\n", strerror(err)); return err; } else if(!enable_app_io()){ err = ENXIO; for (i = 0; i < num_pci; i++) { if (lst[i].vendor == VENDOR_SIS) { int idx; const char *dname; idx = find_chip(lst[i].device); if (idx == -1) continue; dname = pci_device_name(VENDOR_SIS, lst[i].device); dname = dname ? dname : "Unknown chip"; if (sis_verbose > 0) printf("[SiS] Found chip: %s (0x%X)\n", dname, lst[i].device); sis_device_id = sis_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); sis_has_two_overlays = 0; switch (sis_cap.device_id) { case DEVICE_SIS_300: case DEVICE_SIS_630_VGA: sis_has_two_overlays = 1; case DEVICE_SIS_540_VGA: sis_vga_engine = SIS_300_VGA; break; case DEVICE_SIS_330: case DEVICE_SIS_550_VGA: sis_has_two_overlays = 1; case DEVICE_SIS_315H: case DEVICE_SIS_315: case DEVICE_SIS_315PRO: case DEVICE_SIS_650_VGA: /* M650 & 651 have 2 overlays */ /* JCP: I think this works, but not really tested yet */ { unsigned char CR5F; unsigned char tempreg1, tempreg2; inSISIDXREG(SISCR, 0x5F, CR5F); CR5F &= 0xf0; andSISIDXREG(SISCR, 0x5c, 0x07); inSISIDXREG(SISCR, 0x5c, tempreg1); tempreg1 &= 0xf8; setSISIDXREG(SISCR, 0x5c, 0x07, 0xf8); inSISIDXREG(SISCR, 0x5c, tempreg2); tempreg2 &= 0xf8; if ((!tempreg1) || (tempreg2)) { if (CR5F & 0x80) { sis_has_two_overlays = 1; } } else { sis_has_two_overlays = 1; /* ? */ } if (sis_has_two_overlays) { if (sis_verbose > 0) printf ("[SiS] detected M650/651 with 2 overlays\n"); } } sis_vga_engine = SIS_315_VGA; break; default: /* should never get here */ sis_vga_engine = UNKNOWN_VGA; break; } } } } else { err = EPERM; } if (err && sis_verbose) { printf("[SiS] Can't find chip\n"); } else { sis_probed = 1; } return err; } int vixInit(const char *args) { uint8_t sr_data, cr_data, cr_data2; char *env_overlay_crt; (void)args; if (!sis_probed) { printf("[SiS] driver was not probed but is being initialized\n"); return (EINTR); } /* JCP: this is WRONG. Need to coordinate w/ sisfb to use correct mem */ /* map 16MB scary hack for now. */ sis_mem_base = map_phys_mem(pci_info.base0, 0x1000000); /* sis_reg_base = map_phys_mem(pci_info.base1, 0x20000); */ sis_iobase = pci_info.base2 & 0xFFFC; /* would like to use fb ioctl - or some other method - here to get current resolution. */ inSISIDXREG(SISCR, 0x12, cr_data); inSISIDXREG(SISCR, 0x07, cr_data2); sis_screen_height = ((cr_data & 0xff) | ((uint16_t) (cr_data2 & 0x02) << 7) | ((uint16_t) (cr_data2 & 0x40) << 3) | ((uint16_t) (cr_data & 0x02) << 9)) + 1; inSISIDXREG(SISSR, 0x0b, sr_data); inSISIDXREG(SISCR, 0x01, cr_data); sis_screen_width = (((cr_data & 0xff) | ((uint16_t) (sr_data & 0x0C) << 6)) + 1) * 8; inSISIDXREG(SISSR, Index_SR_Graphic_Mode, sr_data); if (sr_data & 0x20) /* interlaced mode */ sis_vmode |= VMODE_INTERLACED; #if 0 /* getting back false data here... */ /* CR9 bit 7 set = double scan active */ inSISIDXREG(SISCR, 0x09, cr_data); if (cr_data & 0x40) { sis_vmode |= VMODE_DOUBLESCAN; } #endif /* JCP: eventually I'd like to replace this with a call to sisfb SISFB_GET_INFO ioctl to get video bridge info. Not for now, since it requires a very new and not widely distributed version. */ sis_init_video_bridge(); env_overlay_crt = getenv("VIDIX_CRT"); if (env_overlay_crt) { int crt = atoi(env_overlay_crt); if (crt == 1 || crt == 2) { sis_overlay_on_crt1 = (crt == 1); if (sis_verbose > 0) { printf ("[SiS] override: using overlay on CRT%d from VIDIX_CRT\n", crt); } } } return 0; } void vixDestroy(void) { /* unmap_phys_mem(sis_reg_base, 0x20000); */ /* JCP: see above, hence also a hack. */ unmap_phys_mem(sis_mem_base, 0x1000000); } int vixGetCapability(vidix_capability_t * to) { memcpy(to, &sis_cap, sizeof(vidix_capability_t)); return 0; } static int is_supported_fourcc(uint32_t fourcc) { switch (fourcc) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_UYVY: case IMGFMT_YUY2: case IMGFMT_RGB15: case IMGFMT_RGB16: return 1; default: return 0; } } int vixQueryFourcc(vidix_fourcc_t * to) { if (is_supported_fourcc(to->fourcc)) { to->depth = VID_DEPTH_8BPP | VID_DEPTH_16BPP | VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } static int bridge_in_slave_mode() { unsigned char usScratchP1_00; if (!(sis_vbflags & VB_VIDEOBRIDGE)) return 0; inSISIDXREG(SISPART1, 0x00, usScratchP1_00); if (((sis_vga_engine == SIS_300_VGA) && (usScratchP1_00 & 0xa0) == 0x20) || ((sis_vga_engine == SIS_315_VGA) && (usScratchP1_00 & 0x50) == 0x10)) { return 1; } else { return 0; } } /* This does not handle X dual head mode, since 1) vidix doesn't support it and 2) it doesn't make sense for other gfx drivers */ static void set_dispmode() { sis_bridge_is_slave = 0; if (bridge_in_slave_mode()) sis_bridge_is_slave = 1; if ((sis_vbflags & VB_DISPMODE_MIRROR) || (sis_bridge_is_slave && (sis_vbflags & DISPTYPE_DISP2))) { if (sis_has_two_overlays) sis_displaymode = DISPMODE_MIRROR; /* TW: CRT1+CRT2 (2 overlays) */ else if (!sis_overlay_on_crt1) sis_displaymode = DISPMODE_SINGLE2; else sis_displaymode = DISPMODE_SINGLE1; } else { if (sis_vbflags & DISPTYPE_DISP1) { sis_displaymode = DISPMODE_SINGLE1; /* TW: CRT1 only */ } else { sis_displaymode = DISPMODE_SINGLE2; /* TW: CRT2 only */ } } } static void set_disptype_regs() { switch (sis_displaymode) { case DISPMODE_SINGLE1: /* TW: CRT1 only */ if (sis_verbose > 2) { printf("[SiS] Setting up overlay on CRT1\n"); } if (sis_has_two_overlays) { setsrregmask(0x06, 0x00, 0xc0); setsrregmask(0x32, 0x00, 0xc0); } else { setsrregmask(0x06, 0x00, 0xc0); setsrregmask(0x32, 0x00, 0xc0); } break; case DISPMODE_SINGLE2: /* TW: CRT2 only */ if (sis_verbose > 2) { printf("[SiS] Setting up overlay on CRT2\n"); } if (sis_has_two_overlays) { setsrregmask(0x06, 0x80, 0xc0); setsrregmask(0x32, 0x80, 0xc0); } else { setsrregmask(0x06, 0x40, 0xc0); setsrregmask(0x32, 0x40, 0xc0); } break; case DISPMODE_MIRROR: /* TW: CRT1 + CRT2 */ default: if (sis_verbose > 2) { printf("[SiS] Setting up overlay on CRT1 AND CRT2!\n"); } setsrregmask(0x06, 0x80, 0xc0); setsrregmask(0x32, 0x80, 0xc0); break; } } static void init_overlay() { /* Initialize first overlay (CRT1) */ /* Write-enable video registers */ setvideoregmask(Index_VI_Control_Misc2, 0x80, 0x81); /* Disable overlay */ setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); /* Disable bobEnable */ setvideoregmask(Index_VI_Control_Misc1, 0x02, 0x02); /* Reset scale control and contrast */ setvideoregmask(Index_VI_Scale_Control, 0x60, 0x60); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); setvideoreg(Index_VI_Play_Threshold_Low, 0x00); setvideoreg(Index_VI_Play_Threshold_High, 0x00); /* may not want to init these here, could already be set to other values by app? */ setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); setvideoreg(Index_VI_Brightness, 0x20); if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Hue, 0x00); setvideoreg(Index_VI_Saturation, 0x00); } /* Initialize second overlay (CRT2) */ if (sis_has_two_overlays) { /* Write-enable video registers */ setvideoregmask(Index_VI_Control_Misc2, 0x81, 0x81); /* Disable overlay */ setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); /* Disable bobEnable */ setvideoregmask(Index_VI_Control_Misc1, 0x02, 0x02); /* Reset scale control and contrast */ setvideoregmask(Index_VI_Scale_Control, 0x60, 0x60); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x1F); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_Disp_Y_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Low, 0x00); setvideoreg(Index_VI_UV_Buf_Preset_Middle, 0x00); setvideoreg(Index_VI_Disp_Y_UV_Buf_Preset_High, 0x00); setvideoreg(Index_VI_Play_Threshold_Low, 0x00); setvideoreg(Index_VI_Play_Threshold_High, 0x00); setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x01); setvideoregmask(Index_VI_Contrast_Enh_Ctrl, 0x04, 0x07); setvideoreg(Index_VI_Brightness, 0x20); if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Hue, 0x00); setvideoreg(Index_VI_Saturation, 0x00); } } } int vixConfigPlayback(vidix_playback_t * info) { SISOverlayRec overlay; int srcOffsetX = 0, srcOffsetY = 0; int sx, sy; int index = 0, iscrt2 = 0; int total_size; short src_w, drw_w; short src_h, drw_h; short src_x, drw_x; short src_y, drw_y; long dga_offset; int pitch; unsigned int i; if (!is_supported_fourcc(info->fourcc)) return -1; /* set chipset/engine.dependent config info */ /* which CRT to use, etc.? */ switch (sis_vga_engine) { case SIS_315_VGA: sis_shift_value = 1; sis_equal.cap |= VEQ_CAP_SATURATION | VEQ_CAP_HUE; break; case SIS_300_VGA: default: sis_shift_value = 2; break; } sis_displaymode = DISPMODE_SINGLE1; /* xV driver code in set_dispmode() */ set_dispmode(); set_disptype_regs(); init_overlay(); /* get basic dimension info */ src_x = info->src.x; src_y = info->src.y; src_w = info->src.w; src_h = info->src.h; drw_x = info->dest.x; drw_y = info->dest.y; drw_w = info->dest.w; drw_h = info->dest.h; switch (info->fourcc) { case IMGFMT_YV12: case IMGFMT_I420: pitch = (src_w + 7) & ~7; total_size = (pitch * src_h * 3) >> 1; break; case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_RGB15: case IMGFMT_RGB16: pitch = ((src_w << 1) + 3) & ~3; total_size = pitch * src_h; break; default: return -1; } /* "allocate" memory for overlay! */ /* start at 8MB = sisfb's "dri reserved space" - really shouldn't hardcode though */ /* XXX: JCP - this can use the sisfb FBIO_ALLOC ioctl to safely allocate "video heap" memory... */ dga_offset = 0x800000; /* use 7MB for now. need to calc/get real info from sisfb? */ /* this can result in a LOT of frames - probably not necessary */ info->num_frames = 0x700000 / (total_size * 2); if (info->num_frames > VID_PLAY_MAXFRAMES) info->num_frames = VID_PLAY_MAXFRAMES; info->dga_addr = sis_mem_base + dga_offset; info->dest.pitch.y = 16; info->dest.pitch.u = 16; info->dest.pitch.v = 16; info->offset.y = 0; info->offset.u = 0; info->offset.v = 0; info->frame_size = (total_size * 2); /* why times 2 ? */ for (i = 0; i < info->num_frames; i++) { info->offsets[i] = info->frame_size * i; /* save ptrs to mem buffers */ sis_frames[i] = (dga_offset + info->offsets[i]); } memset(&overlay, 0, sizeof(overlay)); overlay.pixelFormat = sis_format = info->fourcc; overlay.pitch = overlay.origPitch = pitch; overlay.keyOP = (sis_grkey.ckey.op == CKEY_TRUE ? VI_ROP_DestKey : VI_ROP_Always); overlay.bobEnable = 0x00; overlay.SCREENheight = sis_screen_height; /* probably will not support X virtual screen > phys very well? */ overlay.dstBox.x1 = drw_x; /* - pScrn->frameX0; */ overlay.dstBox.x2 = drw_x + drw_w; /* - pScrn->frameX0; ??? */ overlay.dstBox.y1 = drw_y; /* - pScrn->frameY0; */ overlay.dstBox.y2 = drw_y + drw_h; /* - pScrn->frameY0; ??? */ if ((overlay.dstBox.x1 > overlay.dstBox.x2) || (overlay.dstBox.y1 > overlay.dstBox.y2)) return -1; if ((overlay.dstBox.x2 < 0) || (overlay.dstBox.y2 < 0)) return -1; if (overlay.dstBox.x1 < 0) { srcOffsetX = src_w * (-overlay.dstBox.x1) / drw_w; overlay.dstBox.x1 = 0; } if (overlay.dstBox.y1 < 0) { srcOffsetY = src_h * (-overlay.dstBox.y1) / drw_h; overlay.dstBox.y1 = 0; } switch (info->fourcc) { case IMGFMT_YV12: info->dest.pitch.y = 16; sx = (src_x + srcOffsetX) & ~7; sy = (src_y + srcOffsetY) & ~1; info->offset.y = sis_Yoff = sx + sy * pitch; /* JCP: NOTE reversed u & v here! Not sure why this is needed. maybe mplayer & sis define U & V differently?? */ info->offset.u = sis_Voff = src_h * pitch + ((sx + sy * pitch / 2) >> 1); info->offset.v = sis_Uoff = src_h * pitch * 5 / 4 + ((sx + sy * pitch / 2) >> 1); overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; overlay.PSV = (sis_frames[0] + sis_Voff) >> sis_shift_value; overlay.PSU = (sis_frames[0] + sis_Uoff) >> sis_shift_value; break; case IMGFMT_I420: sx = (src_x + srcOffsetX) & ~7; sy = (src_y + srcOffsetY) & ~1; info->offset.y = sis_Yoff = sx + sy * pitch; /* JCP: see above... */ info->offset.u = sis_Voff = src_h * pitch * 5 / 4 + ((sx + sy * pitch / 2) >> 1); info->offset.v = sis_Uoff = src_h * pitch + ((sx + sy * pitch / 2) >> 1); overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; overlay.PSV = (sis_frames[0] + sis_Voff) >> sis_shift_value; overlay.PSU = (sis_frames[0] + sis_Uoff) >> sis_shift_value; break; case IMGFMT_YUY2: case IMGFMT_UYVY: case IMGFMT_RGB16: case IMGFMT_RGB15: default: sx = (src_x + srcOffsetX) & ~1; sy = (src_y + srcOffsetY); info->offset.y = sis_Yoff = sx * 2 + sy * pitch; overlay.PSY = (sis_frames[0] + sis_Yoff) >> sis_shift_value; break; } /* FIXME: is it possible that srcW < 0? */ overlay.srcW = src_w - (sx - src_x); overlay.srcH = src_h - (sy - src_y); /* JCP: what to do about this? */ #if 0 if ((pPriv->oldx1 != overlay.dstBox.x1) || (pPriv->oldx2 != overlay.dstBox.x2) || (pPriv->oldy1 != overlay.dstBox.y1) || (pPriv->oldy2 != overlay.dstBox.y2)) { pPriv->mustwait = 1; pPriv->oldx1 = overlay.dstBox.x1; pPriv->oldx2 = overlay.dstBox.x2; pPriv->oldy1 = overlay.dstBox.y1; pPriv->oldy2 = overlay.dstBox.y2; } #endif /* set merge line buffer */ merge_line_buf(overlay.srcW > 384); /* calculate line buffer length */ set_line_buf_size(&overlay); if (sis_displaymode == DISPMODE_SINGLE2) { if (sis_has_two_overlays) { /* TW: On chips with two overlays we use * overlay 2 for CRT2 */ index = 1; iscrt2 = 1; } else { /* TW: On chips with only one overlay we * use that only overlay for CRT2 */ index = 0; iscrt2 = 1; } overlay.VBlankActiveFunc = vblank_active_CRT2; /* overlay.GetScanLineFunc = get_scanline_CRT2; */ } else { index = 0; iscrt2 = 0; overlay.VBlankActiveFunc = vblank_active_CRT1; /* overlay.GetScanLineFunc = get_scanline_CRT1; */ } /* calc scale factor (to use below) */ calc_scale_factor(&overlay, index, iscrt2); /* Select video1 (used for CRT1) or video2 (used for CRT2) */ setvideoregmask(Index_VI_Control_Misc2, index, 0x01); set_format(&overlay); set_colorkey(); vixPlaybackSetEq(&sis_equal); /* set up video overlay registers */ set_overlay(&overlay, index); /* prevent badness if bits are not at default setting */ setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x01); setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x04); /* JCP: Xv driver implementation loops back over above code to setup mirror CRT2 */ return 0; } int vixPlaybackOn(void) { setvideoregmask(Index_VI_Control_Misc0, 0x02, 0x02); return 0; } int vixPlaybackOff(void) { unsigned char sridx, cridx; sridx = inSISREG(SISSR); cridx = inSISREG(SISCR); close_overlay(); outSISREG(SISSR, sridx); outSISREG(SISCR, cridx); return 0; } int vixPlaybackFrameSelect(unsigned int frame) { uint8_t data; int index = 0; uint32_t PSY; if (sis_displaymode == DISPMODE_SINGLE2 && sis_has_two_overlays) { index = 1; } PSY = (sis_frames[frame] + sis_Yoff) >> sis_shift_value; /* Unlock address registers */ data = getvideoreg(Index_VI_Control_Misc1); setvideoreg(Index_VI_Control_Misc1, data | 0x20); /* TEST: Is this required? */ setvideoreg(Index_VI_Control_Misc1, data | 0x20); /* TEST end */ /* TEST: Is this required? */ if (sis_vga_engine == SIS_315_VGA) setvideoreg(Index_VI_Control_Misc3, 0x00); /* TEST end */ /* set Y start address */ setvideoreg(Index_VI_Disp_Y_Buf_Start_Low, (uint8_t) (PSY)); setvideoreg(Index_VI_Disp_Y_Buf_Start_Middle, (uint8_t) ((PSY) >> 8)); setvideoreg(Index_VI_Disp_Y_Buf_Start_High, (uint8_t) ((PSY) >> 16)); /* set 310/325 series overflow bits for Y plane */ if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Y_Buf_Start_Over, ((uint8_t) ((PSY) >> 24) & 0x01)); } /* Set U/V data if using plane formats */ if ((sis_format == IMGFMT_YV12) || (sis_format == IMGFMT_I420)) { uint32_t PSU, PSV; PSU = (sis_frames[frame] + sis_Uoff) >> sis_shift_value; PSV = (sis_frames[frame] + sis_Voff) >> sis_shift_value; /* set U/V start address */ setvideoreg(Index_VI_U_Buf_Start_Low, (uint8_t) PSU); setvideoreg(Index_VI_U_Buf_Start_Middle, (uint8_t) (PSU >> 8)); setvideoreg(Index_VI_U_Buf_Start_High, (uint8_t) (PSU >> 16)); setvideoreg(Index_VI_V_Buf_Start_Low, (uint8_t) PSV); setvideoreg(Index_VI_V_Buf_Start_Middle, (uint8_t) (PSV >> 8)); setvideoreg(Index_VI_V_Buf_Start_High, (uint8_t) (PSV >> 16)); /* 310/325 series overflow bits */ if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_U_Buf_Start_Over, ((uint8_t) (PSU >> 24) & 0x01)); setvideoreg(Index_VI_V_Buf_Start_Over, ((uint8_t) (PSV >> 24) & 0x01)); } } if (sis_vga_engine == SIS_315_VGA) { /* Trigger register copy for 310 series */ setvideoreg(Index_VI_Control_Misc3, 1 << index); } /* Lock the address registers */ setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x20); return 0; } int vixGetGrKeys(vidix_grkey_t * grkey) { memcpy(grkey, &sis_grkey, sizeof(vidix_grkey_t)); return 0; } int vixSetGrKeys(const vidix_grkey_t * grkey) { memcpy(&sis_grkey, grkey, sizeof(vidix_grkey_t)); set_colorkey(); return 0; } int vixPlaybackGetEq(vidix_video_eq_t * eq) { memcpy(eq, &sis_equal, sizeof(vidix_video_eq_t)); return 0; } int vixPlaybackSetEq(const vidix_video_eq_t * eq) { int br, sat, cr, hue; if (eq->cap & VEQ_CAP_BRIGHTNESS) sis_equal.brightness = eq->brightness; if (eq->cap & VEQ_CAP_CONTRAST) sis_equal.contrast = eq->contrast; if (eq->cap & VEQ_CAP_SATURATION) sis_equal.saturation = eq->saturation; if (eq->cap & VEQ_CAP_HUE) sis_equal.hue = eq->hue; if (eq->cap & VEQ_CAP_RGB_INTENSITY) { sis_equal.red_intensity = eq->red_intensity; sis_equal.green_intensity = eq->green_intensity; sis_equal.blue_intensity = eq->blue_intensity; } sis_equal.flags = eq->flags; cr = (sis_equal.contrast + 1000) * 7 / 2000; if (cr < 0) cr = 0; if (cr > 7) cr = 7; br = sis_equal.brightness * 127 / 1000; if (br < -128) br = -128; if (br > 127) br = 127; sat = (sis_equal.saturation * 7) / 1000; if (sat < -7) sat = -7; if (sat > 7) sat = 7; hue = sis_equal.hue * 7 / 1000; if (hue < -8) hue = -8; if (hue > 7) hue = 7; set_brightness(br); set_contrast(cr); if (sis_vga_engine == SIS_315_VGA) { set_saturation(sat); set_hue(hue); } return 0; } static void set_overlay(SISOverlayPtr pOverlay, int index) { uint16_t pitch = 0; uint8_t h_over = 0, v_over = 0; uint16_t top, bottom, left, right; uint16_t screenX = sis_screen_width; uint16_t screenY = sis_screen_height; uint8_t data; uint32_t watchdog; top = pOverlay->dstBox.y1; bottom = pOverlay->dstBox.y2; if (bottom > screenY) { bottom = screenY; } left = pOverlay->dstBox.x1; right = pOverlay->dstBox.x2; if (right > screenX) { right = screenX; } /* JCP: these aren't really tested... */ /* TW: DoubleScan modes require Y coordinates * 2 */ if (sis_vmode & VMODE_DOUBLESCAN) { top <<= 1; bottom <<= 1; } /* TW: Interlace modes require Y coordinates / 2 */ if (sis_vmode & VMODE_INTERLACED) { top >>= 1; bottom >>= 1; } h_over = (((left >> 8) & 0x0f) | ((right >> 4) & 0xf0)); v_over = (((top >> 8) & 0x0f) | ((bottom >> 4) & 0xf0)); pitch = pOverlay->pitch >> sis_shift_value; /* set line buffer size */ setvideoreg(Index_VI_Line_Buffer_Size, pOverlay->lineBufSize); /* set color key mode */ setvideoregmask(Index_VI_Key_Overlay_OP, pOverlay->keyOP, 0x0F); /* TW: We don't have to wait for vertical retrace in all cases */ /* JCP: be safe for now. */ if (1 /*pPriv->mustwait */ ) { watchdog = WATCHDOG_DELAY; while (pOverlay->VBlankActiveFunc() && --watchdog); watchdog = WATCHDOG_DELAY; while ((!pOverlay->VBlankActiveFunc()) && --watchdog); if (!watchdog && sis_verbose > 0) { printf("[SiS]: timed out waiting for vertical retrace\n"); } } /* Unlock address registers */ data = getvideoreg(Index_VI_Control_Misc1); setvideoreg(Index_VI_Control_Misc1, data | 0x20); /* TEST: Is this required? */ setvideoreg(Index_VI_Control_Misc1, data | 0x20); /* TEST end */ /* TEST: Is this required? */ if (sis_vga_engine == SIS_315_VGA) setvideoreg(Index_VI_Control_Misc3, 0x00); /* TEST end */ /* Set Y buf pitch */ setvideoreg(Index_VI_Disp_Y_Buf_Pitch_Low, (uint8_t) (pitch)); setvideoregmask(Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (uint8_t) (pitch >> 8), 0x0f); /* Set Y start address */ setvideoreg(Index_VI_Disp_Y_Buf_Start_Low, (uint8_t) (pOverlay->PSY)); setvideoreg(Index_VI_Disp_Y_Buf_Start_Middle, (uint8_t) ((pOverlay->PSY) >> 8)); setvideoreg(Index_VI_Disp_Y_Buf_Start_High, (uint8_t) ((pOverlay->PSY) >> 16)); /* set 310/325 series overflow bits for Y plane */ if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Disp_Y_Buf_Pitch_High, (uint8_t) (pitch >> 12)); setvideoreg(Index_VI_Y_Buf_Start_Over, ((uint8_t) ((pOverlay->PSY) >> 24) & 0x01)); } /* Set U/V data if using plane formats */ if ((pOverlay->pixelFormat == IMGFMT_YV12) || (pOverlay->pixelFormat == IMGFMT_I420)) { uint32_t PSU, PSV; PSU = pOverlay->PSU; PSV = pOverlay->PSV; /* Set U/V pitch */ setvideoreg(Index_VI_Disp_UV_Buf_Pitch_Low, (uint8_t) (pitch >> 1)); setvideoregmask(Index_VI_Disp_Y_UV_Buf_Pitch_Middle, (uint8_t) (pitch >> 5), 0xf0); /* set U/V start address */ setvideoreg(Index_VI_U_Buf_Start_Low, (uint8_t) PSU); setvideoreg(Index_VI_U_Buf_Start_Middle, (uint8_t) (PSU >> 8)); setvideoreg(Index_VI_U_Buf_Start_High, (uint8_t) (PSU >> 16)); setvideoreg(Index_VI_V_Buf_Start_Low, (uint8_t) PSV); setvideoreg(Index_VI_V_Buf_Start_Middle, (uint8_t) (PSV >> 8)); setvideoreg(Index_VI_V_Buf_Start_High, (uint8_t) (PSV >> 16)); /* 310/325 series overflow bits */ if (sis_vga_engine == SIS_315_VGA) { setvideoreg(Index_VI_Disp_UV_Buf_Pitch_High, (uint8_t) (pitch >> 13)); setvideoreg(Index_VI_U_Buf_Start_Over, ((uint8_t) (PSU >> 24) & 0x01)); setvideoreg(Index_VI_V_Buf_Start_Over, ((uint8_t) (PSV >> 24) & 0x01)); } } if (sis_vga_engine == SIS_315_VGA) { /* Trigger register copy for 310 series */ setvideoreg(Index_VI_Control_Misc3, 1 << index); } /* set scale factor */ setvideoreg(Index_VI_Hor_Post_Up_Scale_Low, (uint8_t) (pOverlay->HUSF)); setvideoreg(Index_VI_Hor_Post_Up_Scale_High, (uint8_t) ((pOverlay->HUSF) >> 8)); setvideoreg(Index_VI_Ver_Up_Scale_Low, (uint8_t) (pOverlay->VUSF)); setvideoreg(Index_VI_Ver_Up_Scale_High, (uint8_t) ((pOverlay->VUSF) >> 8)); setvideoregmask(Index_VI_Scale_Control, (pOverlay->IntBit << 3) | (pOverlay->wHPre), 0x7f); /* set destination window position */ setvideoreg(Index_VI_Win_Hor_Disp_Start_Low, (uint8_t) left); setvideoreg(Index_VI_Win_Hor_Disp_End_Low, (uint8_t) right); setvideoreg(Index_VI_Win_Hor_Over, (uint8_t) h_over); setvideoreg(Index_VI_Win_Ver_Disp_Start_Low, (uint8_t) top); setvideoreg(Index_VI_Win_Ver_Disp_End_Low, (uint8_t) bottom); setvideoreg(Index_VI_Win_Ver_Over, (uint8_t) v_over); setvideoregmask(Index_VI_Control_Misc1, pOverlay->bobEnable, 0x1a); /* Lock the address registers */ setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x20); } /* TW: Overlay MUST NOT be switched off while beam is over it */ static void close_overlay() { uint32_t watchdog; if ((sis_displaymode == DISPMODE_SINGLE2) || (sis_displaymode == DISPMODE_MIRROR)) { if (sis_has_two_overlays) { setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x01); watchdog = WATCHDOG_DELAY; while (vblank_active_CRT2() && --watchdog); watchdog = WATCHDOG_DELAY; while ((!vblank_active_CRT2()) && --watchdog); setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); watchdog = WATCHDOG_DELAY; while (vblank_active_CRT2() && --watchdog); watchdog = WATCHDOG_DELAY; while ((!vblank_active_CRT2()) && --watchdog); } else if (sis_displaymode == DISPMODE_SINGLE2) { setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01); watchdog = WATCHDOG_DELAY; while (vblank_active_CRT1() && --watchdog); watchdog = WATCHDOG_DELAY; while ((!vblank_active_CRT1()) && --watchdog); setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); watchdog = WATCHDOG_DELAY; while (vblank_active_CRT1() && --watchdog); watchdog = WATCHDOG_DELAY; while ((!vblank_active_CRT1()) && --watchdog); } } if ((sis_displaymode == DISPMODE_SINGLE1) || (sis_displaymode == DISPMODE_MIRROR)) { setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x01); watchdog = WATCHDOG_DELAY; while (vblank_active_CRT1() && --watchdog); watchdog = WATCHDOG_DELAY; while ((!vblank_active_CRT1()) && --watchdog); setvideoregmask(Index_VI_Control_Misc0, 0x00, 0x02); watchdog = WATCHDOG_DELAY; while (vblank_active_CRT1() && --watchdog); watchdog = WATCHDOG_DELAY; while ((!vblank_active_CRT1()) && --watchdog); } } static void calc_scale_factor(SISOverlayPtr pOverlay, int index, int iscrt2) { uint32_t i = 0, mult = 0; int flag = 0; int dstW = pOverlay->dstBox.x2 - pOverlay->dstBox.x1; int dstH = pOverlay->dstBox.y2 - pOverlay->dstBox.y1; int srcW = pOverlay->srcW; int srcH = pOverlay->srcH; /* uint16_t LCDheight = pSiS->LCDheight; */ int srcPitch = pOverlay->origPitch; int origdstH = dstH; /* get rid of warnings for now */ index = index; iscrt2 = iscrt2; #if 0 /* JCP: don't bother with this for now. */ /* TW: Stretch image due to idiotic LCD "auto"-scaling on LVDS (and 630+301B) */ if (pSiS->VBFlags & CRT2_LCD) { if (sis_bridge_is_slave) { if (pSiS->VBFlags & VB_LVDS) { dstH = (dstH * LCDheight) / pOverlay->SCREENheight; } else if ((sis_vga_engine == SIS_300_VGA) && (pSiS-> VBFlags & (VB_301B | VB_302B | VB_301LV | VB_302LV))) { dstH = (dstH * LCDheight) / pOverlay->SCREENheight; } } else if (iscrt2) { if (pSiS->VBFlags & VB_LVDS) { dstH = (dstH * LCDheight) / pOverlay->SCREENheight; if (sis_displaymode == DISPMODE_MIRROR) flag = 1; } else if ((sis_vga_engine == SIS_300_VGA) && (pSiS-> VBFlags & (VB_301B | VB_302B | VB_301LV | VB_302LV))) { dstH = (dstH * LCDheight) / pOverlay->SCREENheight; if (sis_displaymode == DISPMODE_MIRROR) flag = 1; } } } #endif /* TW: For double scan modes, we need to double the height * (Perhaps we also need to scale LVDS, but I'm not sure.) * On 310/325 series, we need to double the width as well. * Interlace mode vice versa. */ if (sis_vmode & VMODE_DOUBLESCAN) { dstH = origdstH << 1; flag = 0; if (sis_vga_engine == SIS_315_VGA) { dstW <<= 1; } } if (sis_vmode & VMODE_INTERLACED) { dstH = origdstH >> 1; flag = 0; } if (dstW < OVERLAY_MIN_WIDTH) dstW = OVERLAY_MIN_WIDTH; if (dstW == srcW) { pOverlay->HUSF = 0x00; pOverlay->IntBit = 0x05; pOverlay->wHPre = 0; } else if (dstW > srcW) { dstW += 2; pOverlay->HUSF = (srcW << 16) / dstW; pOverlay->IntBit = 0x04; pOverlay->wHPre = 0; } else { int tmpW = dstW; /* TW: It seems, the hardware can't scale below factor .125 (=1/8) if the pitch isn't a multiple of 256. TODO: Test this on the 310/325 series! */ if ((srcPitch % 256) || (srcPitch < 256)) { if (((dstW * 1000) / srcW) < 125) dstW = tmpW = ((srcW * 125) / 1000) + 1; } i = 0; pOverlay->IntBit = 0x01; while (srcW >= tmpW) { tmpW <<= 1; i++; } pOverlay->wHPre = (uint8_t) (i - 1); dstW <<= (i - 1); if ((srcW % dstW)) pOverlay->HUSF = ((srcW - dstW) << 16) / dstW; else pOverlay->HUSF = 0x00; } if (dstH < OVERLAY_MIN_HEIGHT) dstH = OVERLAY_MIN_HEIGHT; if (dstH == srcH) { pOverlay->VUSF = 0x00; pOverlay->IntBit |= 0x0A; } else if (dstH > srcH) { dstH += 0x02; pOverlay->VUSF = (srcH << 16) / dstH; pOverlay->IntBit |= 0x08; } else { uint32_t realI; i = realI = srcH / dstH; pOverlay->IntBit |= 0x02; if (i < 2) { pOverlay->VUSF = ((srcH - dstH) << 16) / dstH; /* TW: Needed for LCD-scaling modes */ if ((flag) && (mult = (srcH / origdstH)) >= 2) pOverlay->pitch /= mult; } else { #if 0 if (((pOverlay->bobEnable & 0x08) == 0x00) && (((srcPitch * i) >> 2) > 0xFFF)) { pOverlay->bobEnable |= 0x08; srcPitch >>= 1; } #endif if (((srcPitch * i) >> 2) > 0xFFF) { i = (0xFFF * 2 / srcPitch); pOverlay->VUSF = 0xFFFF; } else { dstH = i * dstH; if (srcH % dstH) pOverlay->VUSF = ((srcH - dstH) << 16) / dstH; else pOverlay->VUSF = 0x00; } /* set video frame buffer offset */ pOverlay->pitch = (uint16_t) (srcPitch * i); } } } static void set_line_buf_size(SISOverlayPtr pOverlay) { uint8_t preHIDF; uint32_t i; uint32_t line = pOverlay->srcW; if ((pOverlay->pixelFormat == IMGFMT_YV12) || (pOverlay->pixelFormat == IMGFMT_I420)) { preHIDF = pOverlay->wHPre & 0x07; switch (preHIDF) { case 3: if ((line & 0xffffff00) == line) i = (line >> 8); else i = (line >> 8) + 1; pOverlay->lineBufSize = (uint8_t) (i * 32 - 1); break; case 4: if ((line & 0xfffffe00) == line) i = (line >> 9); else i = (line >> 9) + 1; pOverlay->lineBufSize = (uint8_t) (i * 64 - 1); break; case 5: if ((line & 0xfffffc00) == line) i = (line >> 10); else i = (line >> 10) + 1; pOverlay->lineBufSize = (uint8_t) (i * 128 - 1); break; case 6: if ((line & 0xfffff800) == line) i = (line >> 11); else i = (line >> 11) + 1; pOverlay->lineBufSize = (uint8_t) (i * 256 - 1); break; default: if ((line & 0xffffff80) == line) i = (line >> 7); else i = (line >> 7) + 1; pOverlay->lineBufSize = (uint8_t) (i * 16 - 1); break; } } else { /* YUV2, UYVY */ if ((line & 0xffffff8) == line) i = (line >> 3); else i = (line >> 3) + 1; pOverlay->lineBufSize = (uint8_t) (i - 1); } } static void merge_line_buf(int enable) { if (enable) { switch (sis_displaymode) { case DISPMODE_SINGLE1: if (sis_has_two_overlays) { /* dual line merge */ setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); } else { setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); } break; case DISPMODE_SINGLE2: if (sis_has_two_overlays) { /* line merge */ setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04); } else { setvideoregmask(Index_VI_Control_Misc2, 0x10, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); } break; case DISPMODE_MIRROR: default: /* line merge */ setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04); if (sis_has_two_overlays) { /* line merge */ setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x04, 0x04); } break; } } else { switch (sis_displaymode) { case DISPMODE_SINGLE1: setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); break; case DISPMODE_SINGLE2: if (sis_has_two_overlays) { setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); } else { setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); } break; case DISPMODE_MIRROR: default: setvideoregmask(Index_VI_Control_Misc2, 0x00, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); if (sis_has_two_overlays) { setvideoregmask(Index_VI_Control_Misc2, 0x01, 0x11); setvideoregmask(Index_VI_Control_Misc1, 0x00, 0x04); } break; } } } static void set_format(SISOverlayPtr pOverlay) { uint8_t fmt; switch (pOverlay->pixelFormat) { case IMGFMT_YV12: case IMGFMT_I420: fmt = 0x0c; break; case IMGFMT_YUY2: fmt = 0x28; break; case IMGFMT_UYVY: fmt = 0x08; break; case IMGFMT_RGB15: /* D[5:4] : 00 RGB555, 01 RGB 565 */ fmt = 0x00; break; case IMGFMT_RGB16: fmt = 0x10; break; default: fmt = 0x00; break; } setvideoregmask(Index_VI_Control_Misc0, fmt, 0x7c); } static void set_colorkey() { uint8_t r, g, b; b = (uint8_t) sis_grkey.ckey.blue; g = (uint8_t) sis_grkey.ckey.green; r = (uint8_t) sis_grkey.ckey.red; /* set color key mode */ setvideoregmask(Index_VI_Key_Overlay_OP, sis_grkey.ckey.op == CKEY_TRUE ? VI_ROP_DestKey : VI_ROP_Always, 0x0F); /* set colorkey values */ setvideoreg(Index_VI_Overlay_ColorKey_Blue_Min, (uint8_t) b); setvideoreg(Index_VI_Overlay_ColorKey_Green_Min, (uint8_t) g); setvideoreg(Index_VI_Overlay_ColorKey_Red_Min, (uint8_t) r); setvideoreg(Index_VI_Overlay_ColorKey_Blue_Max, (uint8_t) b); setvideoreg(Index_VI_Overlay_ColorKey_Green_Max, (uint8_t) g); setvideoreg(Index_VI_Overlay_ColorKey_Red_Max, (uint8_t) r); } static void set_brightness(uint8_t brightness) { setvideoreg(Index_VI_Brightness, brightness); } static void set_contrast(uint8_t contrast) { setvideoregmask(Index_VI_Contrast_Enh_Ctrl, contrast, 0x07); } /* Next 3 functions are 310/325 series only */ static void set_saturation(char saturation) { uint8_t temp = 0; if (saturation < 0) { temp |= 0x88; saturation = -saturation; } temp |= (saturation & 0x07); temp |= ((saturation & 0x07) << 4); setvideoreg(Index_VI_Saturation, temp); } static void set_hue(uint8_t hue) { setvideoreg(Index_VI_Hue, (hue & 0x08) ? (hue ^ 0x07) : hue); } #if 0 /* JCP: not used (I don't think it's correct anyway) */ static void set_alpha(uint8_t alpha) { uint8_t data; data = getvideoreg(Index_VI_Key_Overlay_OP); data &= 0x0F; setvideoreg(Index_VI_Key_Overlay_OP, data | (alpha << 4)); } #endif xine-lib-1.2/contrib/vidix/drivers/savage_regs.h0000644000175000017500000002271014647725152017566 0ustar meme/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v 1.10 2001/11/04 22:17:48 alanh Exp $ */ #ifndef _SAVAGE_REGS_H #define _SAVAGE_REGS_H /* These are here until xf86PciInfo.h is updated. */ #ifndef PCI_CHIP_S3TWISTER_P #define PCI_CHIP_S3TWISTER_P 0x8d01 #endif #ifndef PCI_CHIP_S3TWISTER_K #define PCI_CHIP_S3TWISTER_K 0x8d02 #endif #ifndef PCI_CHIP_SUPSAV_MX128 #define PCI_CHIP_SUPSAV_MX128 0x8c22 #define PCI_CHIP_SUPSAV_MX64 0x8c24 #define PCI_CHIP_SUPSAV_MX64C 0x8c26 #define PCI_CHIP_SUPSAV_IX128SDR 0x8c2a #define PCI_CHIP_SUPSAV_IX128DDR 0x8c2b #define PCI_CHIP_SUPSAV_IX64SDR 0x8c2c #define PCI_CHIP_SUPSAV_IX64DDR 0x8c2d #define PCI_CHIP_SUPSAV_IXCSDR 0x8c2e #define PCI_CHIP_SUPSAV_IXCDDR 0x8c2f #endif #ifndef PCI_CHIP_PROSAVAGE_DDR #define PCI_CHIP_PROSAVAGE_DDR 0x8d03 #define PCI_CHIP_PROSAVAGE_DDRK 0x8d04 #endif #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) #define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) || (chip==S3_PROSAVAGE)) #define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE)) #define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000)) /* Chip tags. These are used to group the adapters into * related families. */ enum S3CHIPTAGS { S3_UNKNOWN = 0, S3_SAVAGE3D, S3_SAVAGE_MX, S3_SAVAGE4, S3_PROSAVAGE, S3_SUPERSAVAGE, S3_SAVAGE2000, S3_LAST }; typedef struct { unsigned int mode, refresh; unsigned char SR08, SR0E, SR0F; unsigned char SR10, SR11, SR12, SR13, SR15, SR18, SR1B, SR29, SR30; unsigned char SR54[8]; unsigned char Clock; unsigned char CR31, CR32, CR33, CR34, CR36, CR3A, CR3B, CR3C; unsigned char CR40, CR41, CR42, CR43, CR45; unsigned char CR50, CR51, CR53, CR55, CR58, CR5B, CR5D, CR5E; unsigned char CR60, CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F; unsigned char CR86, CR88; unsigned char CR90, CR91, CRB0; unsigned int STREAMS[22]; /* yuck, streams regs */ unsigned int MMPR0, MMPR1, MMPR2, MMPR3; } SavageRegRec, *SavageRegPtr; #define BIOS_BSIZE 1024 #define BIOS_BASE 0xc0000 #define SAVAGE_NEWMMIO_REGBASE_S3 0x1000000 /* 16MB */ #define SAVAGE_NEWMMIO_REGBASE_S4 0x0000000 #define SAVAGE_NEWMMIO_REGSIZE 0x0080000 /* 512kb */ #define SAVAGE_NEWMMIO_VGABASE 0x8000 #define BASE_FREQ 14.31818 #define FIFO_CONTROL_REG 0x8200 #define MIU_CONTROL_REG 0x8204 #define STREAMS_TIMEOUT_REG 0x8208 #define MISC_TIMEOUT_REG 0x820c /* Stream Processor 1 */ /* Primary Stream 1 Frame Buffer Address 0 */ #define PRI_STREAM_FBUF_ADDR0 0x81c0 /* Primary Stream 1 Frame Buffer Address 0 */ #define PRI_STREAM_FBUF_ADDR1 0x81c4 /* Primary Stream 1 Stride */ #define PRI_STREAM_STRIDE 0x81c8 /* Primary Stream 1 Frame Buffer Size */ #define PRI_STREAM_BUFFERSIZE 0x8214 /* Secondary stream 1 Color/Chroma Key Control */ #define SEC_STREAM_CKEY_LOW 0x8184 /* Secondary stream 1 Chroma Key Upper Bound */ #define SEC_STREAM_CKEY_UPPER 0x8194 /* Blend Control of Secondary Stream 1 & 2 */ #define BLEND_CONTROL 0x8190 /* Secondary Stream 1 Color conversion/Adjustment 1 */ #define SEC_STREAM_COLOR_CONVERT1 0x8198 /* Secondary Stream 1 Color conversion/Adjustment 2 */ #define SEC_STREAM_COLOR_CONVERT2 0x819c /* Secondary Stream 1 Color conversion/Adjustment 3 */ #define SEC_STREAM_COLOR_CONVERT3 0x81e4 /* Secondary Stream 1 Horizontal Scaling */ #define SEC_STREAM_HSCALING 0x81a0 /* Secondary Stream 1 Frame Buffer Size */ #define SEC_STREAM_BUFFERSIZE 0x81a8 /* Secondary Stream 1 Horizontal Scaling Normalization (2K only) */ #define SEC_STREAM_HSCALE_NORMALIZE 0x81ac /* Secondary Stream 1 Horizontal Scaling */ #define SEC_STREAM_VSCALING 0x81e8 /* Secondary Stream 1 Frame Buffer Address 0 */ #define SEC_STREAM_FBUF_ADDR0 0x81d0 /* Secondary Stream 1 Frame Buffer Address 1 */ #define SEC_STREAM_FBUF_ADDR1 0x81d4 /* Secondary Stream 1 Frame Buffer Address 2 */ #define SEC_STREAM_FBUF_ADDR2 0x81ec /* Secondary Stream 1 Stride */ #define SEC_STREAM_STRIDE 0x81d8 /* Secondary Stream 1 Window Start Coordinates */ #define SEC_STREAM_WINDOW_START 0x81f8 /* Secondary Stream 1 Window Size */ #define SEC_STREAM_WINDOW_SZ 0x81fc /* Secondary Streams Tile Offset */ #define SEC_STREAM_TILE_OFF 0x821c /* Secondary Stream 1 Opaque Overlay Control */ #define SEC_STREAM_OPAQUE_OVERLAY 0x81dc /* Stream Processor 2 */ /* Primary Stream 2 Frame Buffer Address 0 */ #define PRI_STREAM2_FBUF_ADDR0 0x81b0 /* Primary Stream 2 Frame Buffer Address 1 */ #define PRI_STREAM2_FBUF_ADDR1 0x81b4 /* Primary Stream 2 Stride */ #define PRI_STREAM2_STRIDE 0x81b8 /* Primary Stream 2 Frame Buffer Size */ #define PRI_STREAM2_BUFFERSIZE 0x8218 /* Secondary Stream 2 Color/Chroma Key Control */ #define SEC_STREAM2_CKEY_LOW 0x8188 /* Secondary Stream 2 Chroma Key Upper Bound */ #define SEC_STREAM2_CKEY_UPPER 0x818c /* Secondary Stream 2 Horizontal Scaling */ #define SEC_STREAM2_HSCALING 0x81a4 /* Secondary Stream 2 Horizontal Scaling */ #define SEC_STREAM2_VSCALING 0x8204 /* Secondary Stream 2 Frame Buffer Size */ #define SEC_STREAM2_BUFFERSIZE 0x81ac /* Secondary Stream 2 Frame Buffer Address 0 */ #define SEC_STREAM2_FBUF_ADDR0 0x81bc /* Secondary Stream 2 Frame Buffer Address 1 */ #define SEC_STREAM2_FBUF_ADDR1 0x81e0 /* Secondary Stream 2 Frame Buffer Address 2 */ #define SEC_STREAM2_FBUF_ADDR2 0x8208 /* Multiple Buffer/LPB and Secondary Stream 2 Stride */ #define SEC_STREAM2_STRIDE_LPB 0x81cc /* Secondary Stream 2 Color conversion/Adjustment 1 */ #define SEC_STREAM2_COLOR_CONVERT1 0x81f0 /* Secondary Stream 2 Color conversion/Adjustment 2 */ #define SEC_STREAM2_COLOR_CONVERT2 0x81f4 /* Secondary Stream 2 Color conversion/Adjustment 3 */ #define SEC_STREAM2_COLOR_CONVERT3 0x8200 /* Secondary Stream 2 Window Start Coordinates */ #define SEC_STREAM2_WINDOW_START 0x820c /* Secondary Stream 2 Window Size */ #define SEC_STREAM2_WINDOW_SZ 0x8210 /* Secondary Stream 2 Opaque Overlay Control */ #define SEC_STREAM2_OPAQUE_OVERLAY 0x8180 /* savage 2000 */ #define SEC_STREAM_COLOR_CONVERT0_2000 0x8198 #define SEC_STREAM_COLOR_CONVERT1_2000 0x819c #define SEC_STREAM_COLOR_CONVERT2_2000 0x81e0 #define SEC_STREAM_COLOR_CONVERT3_2000 0x81e4 #define SUBSYS_STAT_REG 0x8504 #define SRC_BASE 0xa4d4 #define DEST_BASE 0xa4d8 #define CLIP_L_R 0xa4dc #define CLIP_T_B 0xa4e0 #define DEST_SRC_STR 0xa4e4 #define MONO_PAT_0 0xa4e8 #define MONO_PAT_1 0xa4ec /* Constants for CR69. */ #define CRT_ACTIVE 0x01 #define LCD_ACTIVE 0x02 #define TV_ACTIVE 0x04 #define CRT_ATTACHED 0x10 #define LCD_ATTACHED 0x20 #define TV_ATTACHED 0x40 /* * reads from SUBSYS_STAT */ #define STATUS_WORD0 (INREG(0x48C00)) #define ALT_STATUS_WORD0 (INREG(0x48C60)) #define MAXLOOP 0xffffff #define IN_SUBSYS_STAT() (INREG(SUBSYS_STAT_REG)) #define MAXFIFO 0x7f00 /* * NOTE: don't remove 'VGAIN8(vgaCRIndex);'. * If not present it will cause lockups on Savage4. * Ask S3, why. */ /*#define VerticalRetraceWait() \ { \ VGAIN8(0x3d0+4); \ VGAOUT8(0x3d0+4, 0x17); \ if (VGAIN8(0x3d0+5) & 0x80) { \ while ((VGAIN8(0x3d0 + 0x0a) & 0x08) == 0x08) ; \ while ((VGAIN8(0x3d0 + 0x0a) & 0x08) == 0x00) ; \ } \ } */ #define VerticalRetraceWait() \ do { \ VGAIN8(0x3d4); \ VGAOUT8(0x3d4, 0x17); \ if (VGAIN8(0x3d5) & 0x80) { \ int i = 0x10000; \ while ((VGAIN8(0x3da) & 0x08) == 0x08 && i--) ; \ i = 0x10000; \ while ((VGAIN8(0x3da) & 0x08) == 0x00 && i--) ; \ } \ } while (0) #define I2C_REG 0xa0 #define InI2CREG(a) \ { \ VGAOUT8(0x3d0 + 4, I2C_REG); \ a = VGAIN8(0x3d0 + 5); \ } #define OutI2CREG(a) \ { \ VGAOUT8(0x3d0 + 4, I2C_REG); \ VGAOUT8(0x3d0 + 5, a); \ } #define HZEXP_COMP_1 0x54 #define HZEXP_BORDER 0x58 #define HZEXP_FACTOR_IGA1 0x59 #define VTEXP_COMP_1 0x56 #define VTEXP_BORDER 0x5a #define VTEXP_FACTOR_IGA1 0x5b #define EC1_CENTER_ON 0x10 #define EC1_EXPAND_ON 0x0c #define MODE_24 24 #if (MODE_24 == 32) # define BYTES_PP24 4 #else # define BYTES_PP24 3 #endif #define OVERLAY_DEPTH 16 #define STREAMS_MODE32 0x7 #define STREAMS_MODE24 0x6 #define STREAMS_MODE16 0x5 /* @@@ */ #define DEPTH_BPP(depth) (depth == 24 ? (BYTES_PP24 << 3) : (depth + 7) & ~0x7) #define DEPTH_2ND(depth) (depth > 8 ? depth\ : OVERLAY_DEPTH) #define SSTREAMS_MODE(bpp) (bpp > 16 ? (bpp > 24 ? STREAMS_MODE32 :\ STREAMS_MODE24) : STREAMS_MODE16) #define HSCALING_Shift 0 #define HSCALING_Mask (((1L << 16)-1) << HSCALING_Shift) #define HSCALING(w0,w1) ((((unsigned int)(((double)w0/(double)w1) * (1 << 15))) \ << HSCALING_Shift) \ & HSCALING_Mask) #define VSCALING_Shift 0 #define VSCALING_Mask (((1L << 20)-1) << VSCALING_Shift) #define VSCALING(h0,h1) ((((unsigned int) (((double)h0/(double)h1) * (1 << 15))) \ << VSCALING_Shift) \ & VSCALING_Mask) #endif /* _SAVAGE_REGS_H */ xine-lib-1.2/contrib/vidix/drivers/unichrome_vid.c0000644000175000017500000004130414647725152020126 0ustar meme/* Driver for VIA CLE266 Unichrome - Version 0.1.0 Copyright (C) 2004 by Timothy Lee Based on Cyberblade/i driver by Alastair M. Robison. Thanks to Gilles Frattini for bugfixes This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Changes: 2004-03-10 Initial version To Do: */ #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "unichrome_regs.h" pciinfo_t pci_info; uint8_t *uc_mem; static vidix_grkey_t uc_grkey; static int frames[VID_PLAY_MAXFRAMES]; uint8_t *vio; uint8_t mclk_save[3]; #define VIA_OUT(hwregs, reg, val) *(volatile uint32_t *)((hwregs) + (reg)) = (val) #define VIA_IN(hwregs, reg) *(volatile uint32_t *)((hwregs) + (reg)) #define VGA_OUT8(hwregs, reg, val) *(volatile uint8_t *)((hwregs) + (reg) + 0x8000) = (val) #define VGA_IN8(hwregs, reg) *(volatile uint8_t *)((hwregs) + (reg) + 0x8000) #define VIDEO_OUT(hwregs, reg, val) VIA_OUT((hwregs)+0x200, reg, val) #define VIDEO_IN(hwregs, reg) VIA_IN((hwregs)+0x200, reg) #define outb(val,reg) OUTPORT8(reg,val) #define inb(reg) INPORT8(reg) #define ALIGN_TO(v, n) (((v) + (n-1)) & ~(n-1)) #define UC_MAP_V1_FIFO_CONTROL(depth, pre_thr, thr) \ (((depth)-1) | ((thr) << 8) | ((pre_thr) << 24)) #define FRAMEBUFFER_START 0x600000 #define FRAMEBUFFER_SIZE 0x200000 #ifdef DEBUG_LOGFILE FILE *logfile=0; #define LOGWRITE(x) {if(logfile) fprintf(logfile,x);} #else #define LOGWRITE(x) #endif static vidix_capability_t uc_cap = { "VIA CLE266 Unichrome driver", "Timothy Lee ", TYPE_OUTPUT, { 0, 0, 0, 0 }, 4096, 4096, 4, 4, -1, FLAG_UPSCALER|FLAG_DOWNSCALER, VENDOR_VIA2, -1, { 0, 0, 0, 0 } }; unsigned int vixGetVersion(void) { return(VIDIX_VERSION); } static unsigned short uc_card_ids[] = { DEVICE_VIA2_VT8623_APOLLO_CLE266 }; static int find_chip(unsigned chip_id) { unsigned i; for(i = 0;i < sizeof(uc_card_ids)/sizeof(unsigned short);i++) { if(chip_id == uc_card_ids[i]) return i; } return -1; } /** * Map hw settings for vertical scaling. * * @param sh source height * @param dh destination height * @param zoom will hold vertical setting of zoom register. * @param mini will hold vertical setting of mini register. * * @returns 1 if successful. * 0 if the zooming factor is too large or small. * * @note Derived from VIA's V4L driver. * See ddover.c, DDOVER_HQVCalcZoomHeight() */ static int uc_ovl_map_vzoom(int sh, int dh, uint32_t* zoom, uint32_t* mini) { uint32_t sh1, tmp, d; int zoom_ok = 1; if (sh == dh) { // No zoom // Do nothing } else if (sh < dh) { // Zoom in tmp = (sh * 0x0400) / dh; zoom_ok = !(tmp > 0x3ff); *zoom |= (tmp & 0x3ff) | V1_Y_ZOOM_ENABLE; *mini |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY; } else { // sw > dh - Zoom out // Find a suitable divider (1 << d) = {2, 4, 8 or 16} sh1 = sh; for (d = 1; d < 5; d++) { sh1 >>= 1; if ((int)sh1 <= dh) break; } if (d == 5) { // Too small. d = 4; zoom_ok = 0; } *mini |= ((d<<1)-1) << 16; // <= {1,3,5,7} << 16 // Add scaling if ((int)sh1 < dh) { tmp = (sh1 * 0x400) / dh; *zoom |= ((tmp & 0x3ff) | V1_Y_ZOOM_ENABLE); *mini |= V1_Y_INTERPOLY | V1_YCBCR_INTERPOLY; } } return zoom_ok; } /** * Map hw settings for horizontal scaling. * * @param sw source width * @param dw destination width * * @param zoom will hold horizontal setting of zoom register. * @param mini will hold horizontal setting of mini register. * @param falign will hold fetch aligment * @param dcount will hold display count * * @returns 1 if successful. * 0 if the zooming factor is too large or small. * * @note Derived from VIA's V4L driver. * See ddover.c, DDOVER_HQVCalcZoomWidth() and DDOver_GetDisplayCount() */ static int uc_ovl_map_hzoom(int sw, int dw, uint32_t* zoom, uint32_t* mini, int* falign, int* dcount) { uint32_t tmp, sw1, d; int md; // Minify-divider int zoom_ok = 1; md = 1; *falign = 0; if (sw == dw) { // No zoom // Do nothing } else if (sw < dw) { // Zoom in tmp = (sw * 0x0800) / dw; zoom_ok = !(tmp > 0x7ff); *zoom |= ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; *mini |= V1_X_INTERPOLY; } else { // sw > dw - Zoom out // Find a suitable divider (1 << d) = {2, 4, 8 or 16} sw1 = sw; for (d = 1; d < 5; d++) { sw1 >>= 1; if ((int)sw1 <= dw) break; } if (d == 5) { // Too small. d = 4; zoom_ok = 0; } md = 1 << d; // <= {2,4,8,16} *falign = ((md<<1)-1) & 0xf; // <= {3,7,15,15} *mini |= V1_X_INTERPOLY; *mini |= ((d<<1)-1) << 24; // <= {1,3,5,7} << 24 // Add scaling if ((int)sw1 < dw) { //CLE bug //tmp = sw1*0x0800 / dw; tmp = (sw1 - 2) * 0x0800 / dw; *zoom |= ((tmp & 0x7ff) << 16) | V1_X_ZOOM_ENABLE; } } *dcount = sw - md; return zoom_ok; } /** * @param format overlay pixel format * @param sw source width * * @returns qword fetch register setting * * @note Derived from VIA's V4L driver. See ddover.c, DDOver_GetFetch() * @note Only call after uc_ovl_map_hzoom() */ static uint32_t uc_ovl_map_qwfetch(uint32_t format, int sw) { uint32_t fetch = 0; switch (format) { case IMGFMT_YV12: case IMGFMT_I420: fetch = ALIGN_TO(sw, 32) >> 4; break; case IMGFMT_UYVY: case IMGFMT_YVYU: case IMGFMT_YUY2: fetch = (ALIGN_TO(sw << 1, 16) >> 4) + 1; break; case IMGFMT_BGR15: case IMGFMT_BGR16: fetch = (ALIGN_TO(sw << 1, 16) >> 4) + 1; break; case IMGFMT_BGR32: fetch = (ALIGN_TO(sw << 2, 16) >> 4) + 1; break; default: printf("[unichrome] Unexpected pixelformat!"); break; } if (fetch < 4) fetch = 4; return fetch; } /** * Map pixel format. * * @note Derived from VIA's V4L driver. See ddover.c, DDOver_GetV1Format() */ static uint32_t uc_ovl_map_format(uint32_t format) { switch (format) { case IMGFMT_UYVY: case IMGFMT_YVYU: case IMGFMT_YUY2: return V1_COLORSPACE_SIGN | V1_YUV422; case IMGFMT_IYUV: return V1_COLORSPACE_SIGN | V1_YCbCr420 | V1_SWAP_SW; case IMGFMT_YV12: case IMGFMT_I420: return V1_COLORSPACE_SIGN | V1_YCbCr420; case IMGFMT_BGR15: return V1_RGB15; case IMGFMT_BGR16: return V1_RGB16; case IMGFMT_BGR32: return V1_RGB32; default : printf("[unichrome] Unexpected pixelformat!"); return V1_YUV422; } } /** * Calculate V1 control and fifo-control register values * @param format pixel format * @param sw source width * @param hwrev CLE266 hardware revision * @param extfifo_on set this 1 if the extended FIFO is enabled * @param control will hold value for V1_CONTROL * @param fifo will hold value for V1_FIFO_CONTROL */ static void uc_ovl_map_v1_control(uint32_t format, int sw, int hwrev, int extfifo_on, uint32_t* control, uint32_t* fifo) { *control = V1_BOB_ENABLE | uc_ovl_map_format(format); if (hwrev == 0x10) { *control |= V1_EXPIRE_NUM_F; } else { if (extfifo_on) { *control |= V1_EXPIRE_NUM_A | V1_FIFO_EXTENDED; } else { *control |= V1_EXPIRE_NUM; } } if ((format == IMGFMT_YV12) || (format == IMGFMT_I420)) { //Minified video will be skewed without this workaround. if (sw <= 80) { //Fetch count <= 5 *fifo = UC_MAP_V1_FIFO_CONTROL(16,0,0); } else { if (hwrev == 0x10) *fifo = UC_MAP_V1_FIFO_CONTROL(64,56,56); else *fifo = UC_MAP_V1_FIFO_CONTROL(16,12,8); } } else { if (hwrev == 0x10) { *fifo = UC_MAP_V1_FIFO_CONTROL(64,56,56); // Default rev 0x10 } else { if (extfifo_on) *fifo = UC_MAP_V1_FIFO_CONTROL(48,40,40); else *fifo = UC_MAP_V1_FIFO_CONTROL(32,29,16); // Default } } } static void uc_ovl_setup_fifo(int *extfifo_on, int dst_w) { if (dst_w <= 1024) { // Disable extended FIFO outb(0x16, 0x3c4); outb(mclk_save[0], 0x3c5); outb(0x17, 0x3c4); outb(mclk_save[1], 0x3c5); outb(0x18, 0x3c4); outb(mclk_save[2], 0x3c5); *extfifo_on = 0; } else { // Enable extended FIFO outb(0x17, 0x3c4); outb(0x2f, 0x3c5); outb(0x16, 0x3c4); outb((mclk_save[0] & 0xf0) | 0x14, 0x3c5); outb(0x18, 0x3c4); outb(0x56, 0x3c5); *extfifo_on = 1; } } static void uc_ovl_vcmd_wait(volatile uint8_t* vio) { while ((VIDEO_IN(vio, V_COMPOSE_MODE) & (V1_COMMAND_FIRE | V3_COMMAND_FIRE))); } int vixProbe(int verbose, int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; (void)force; err = pci_scan(lst,&num_pci); if(err) { printf("[unichrome] Error occurred during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0; i < num_pci; i++) { if(lst[i].vendor == VENDOR_VIA2) { int idx; const char *dname; idx = find_chip(lst[i].device); if(idx == -1) continue; dname = pci_device_name(VENDOR_VIA2, lst[i].device); dname = dname ? dname : "Unknown chip"; printf("[unichrome] Found chip: %s\n", dname); uc_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); break; } } } if(err && verbose) printf("[unichrome] Can't find chip\n"); return err; } int vixInit(const char *args) { long tmp; (void)args; uc_mem = map_phys_mem(pci_info.base0, 0x800000); enable_app_io(); outb(0x2f, 0x3c4); tmp = inb(0x3c5) << 0x18; vio = map_phys_mem(tmp,0x1000); outb(0x16, 0x3c4); mclk_save[0] = inb(0x3c5); outb(0x17, 0x3c4); mclk_save[1] = inb(0x3c5); outb(0x18, 0x3c4); mclk_save[2] = inb(0x3c5); uc_grkey.ckey.blue = 0x00; uc_grkey.ckey.green = 0x00; uc_grkey.ckey.red = 0x00; #ifdef DEBUG_LOGFILE logfile=fopen("/tmp/uc_vidix.log","w"); #endif return 0; } void vixDestroy(void) { #ifdef DEBUG_LOGFILE if(logfile) fclose(logfile); #endif outb(0x16, 0x3c4); outb(mclk_save[0], 0x3c5); outb(0x17, 0x3c4); outb(mclk_save[1], 0x3c5); outb(0x18, 0x3c4); outb(mclk_save[2], 0x3c5); disable_app_io(); unmap_phys_mem(uc_mem, 0x800000); unmap_phys_mem(vio, 0x1000); } int vixGetCapability(vidix_capability_t *to) { memcpy(to, &uc_cap, sizeof(vidix_capability_t)); return 0; } static int is_supported_fourcc(uint32_t fourcc) { switch(fourcc) { case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_UYVY: case IMGFMT_YVYU: case IMGFMT_YUY2: case IMGFMT_BGR15: case IMGFMT_BGR16: case IMGFMT_BGR32: return 1; default: return 0; } } int vixQueryFourcc(vidix_fourcc_t *to) { if(is_supported_fourcc(to->fourcc)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } int vixGetGrKeys(vidix_grkey_t *grkey) { memcpy(grkey, &uc_grkey, sizeof(vidix_grkey_t)); return(0); } int vixSetGrKeys(const vidix_grkey_t *grkey) { unsigned long dwCompose = VIDEO_IN(vio, V_COMPOSE_MODE) & ~0x0f; memcpy(&uc_grkey, grkey, sizeof(vidix_grkey_t)); if (uc_grkey.ckey.op != CKEY_FALSE) { // Set colorkey // (how do I detect BPP in hardware??) unsigned long ckey; if (1) // Assume 16-bit graphics { ckey = (grkey->ckey.blue & 0x1f) | ((grkey->ckey.green & 0x3f) << 5) | ((grkey->ckey.red & 0x1f) << 11); } else { ckey = (grkey->ckey.blue) | (grkey->ckey.green << 8) | (grkey->ckey.red << 16); } VIDEO_OUT(vio, V_COLOR_KEY, ckey); dwCompose |= SELECT_VIDEO_IF_COLOR_KEY; } // Execute the changes VIDEO_OUT(vio, V_COMPOSE_MODE, dwCompose | V1_COMMAND_FIRE); return(0); } vidix_video_eq_t equal = { VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION | VEQ_CAP_HUE, 300, 100, 0, 0, 0, 0, 0, 0 }; int vixPlaybackGetEq( vidix_video_eq_t * eq) { memcpy(eq,&equal,sizeof(vidix_video_eq_t)); return 0; } int vixPlaybackSetEq( const vidix_video_eq_t * eq) { (void)eq; return 0; } static int YOffs,UOffs,VOffs; int vixConfigPlayback(vidix_playback_t *info) { int src_w, drw_w; int src_h, drw_h; long base0, pitch; int uv_size, swap_uv; unsigned int i; int extfifo_on; // Overlay register settings uint32_t win_start, win_end; uint32_t zoom, mini; uint32_t dcount, falign, qwfetch; uint32_t v_ctrl, fifo_ctrl; if(!is_supported_fourcc(info->fourcc)) return -1; src_w = info->src.w; src_h = info->src.h; drw_w = info->dest.w; drw_h = info->dest.h; // Setup FIFO uc_ovl_setup_fifo(&extfifo_on, src_w); // Get image format, FIFO size, etc. uc_ovl_map_v1_control(info->fourcc, src_w, 3, extfifo_on, &v_ctrl, &fifo_ctrl); // Setup layer window win_start = (info->dest.x << 16) | info->dest.y; win_end = ((info->dest.x + drw_w - 1) << 16) | (info->dest.y + drw_h - 1); // Get scaling and data-fetch parameters zoom = 0; mini = 0; uc_ovl_map_vzoom(src_h, drw_h, &zoom, &mini); uc_ovl_map_hzoom(src_w, drw_w, &zoom, &mini, &falign, &dcount); qwfetch = uc_ovl_map_qwfetch(info->fourcc, src_w); // Calculate buffer sizes swap_uv = 0; switch(info->fourcc) { default: case IMGFMT_YV12: swap_uv = 1; case IMGFMT_I420: case IMGFMT_UYVY: case IMGFMT_YVYU: pitch = ALIGN_TO (src_w, 32); uv_size = (pitch >> 1) * (src_h >> 1); break; case IMGFMT_YUY2: case IMGFMT_BGR15: case IMGFMT_BGR16: pitch = ALIGN_TO (src_w << 1, 32); uv_size = 0; break; case IMGFMT_BGR32: pitch = ALIGN_TO (src_w << 2, 32); uv_size = 0; break; } if ((src_w > 4096) || (src_h > 4096) || (src_w < 32) || (src_h < 1) || (pitch > 0x1fff)) { printf("[unichrome] Layer size out of bounds\n"); } // Calculate offsets info->offset.y = 0; info->offset.v = info->offset.y + pitch * src_h; info->offset.u = info->offset.v + uv_size; info->frame_size = info->offset.u + uv_size; YOffs = info->offset.y; UOffs = (swap_uv ? info->offset.v : info->offset.u); VOffs = (swap_uv ? info->offset.u : info->offset.v); /* Assume we have 2 MB to play with */ info->num_frames = FRAMEBUFFER_SIZE / info->frame_size; if(info->num_frames > VID_PLAY_MAXFRAMES) info->num_frames = VID_PLAY_MAXFRAMES; /* Start at 6 MB. Let's hope it's not in use. */ base0 = FRAMEBUFFER_START; info->dga_addr = uc_mem + base0; info->dest.pitch.y = 32; info->dest.pitch.u = 32; info->dest.pitch.v = 32; for(i = 0; i < info->num_frames; i++) { info->offsets[i] = info->frame_size * i; frames[i] = base0+info->offsets[i]; } // Write to the hardware uc_ovl_vcmd_wait(vio); // Configure diy_pitchlay parameters now if (v_ctrl & V1_COLORSPACE_SIGN) { VIDEO_OUT (vio, V1_ColorSpaceReg_2, ColorSpaceValue_2); VIDEO_OUT (vio, V1_ColorSpaceReg_1, ColorSpaceValue_1); } VIDEO_OUT(vio, V1_CONTROL, v_ctrl); VIDEO_OUT(vio, V_FIFO_CONTROL, fifo_ctrl); VIDEO_OUT(vio, V1_WIN_START_Y, win_start); VIDEO_OUT(vio, V1_WIN_END_Y, win_end); VIDEO_OUT(vio, V1_SOURCE_HEIGHT, (src_h << 16) | dcount); VIDEO_OUT(vio, V12_QWORD_PER_LINE, qwfetch << 20); VIDEO_OUT(vio, V1_STRIDE, pitch | ((pitch >> 1) << 16)); VIDEO_OUT(vio, V1_MINI_CONTROL, mini); VIDEO_OUT(vio, V1_ZOOM_CONTROL, zoom); // Configure buffer address and execute the changes now! vixPlaybackFrameSelect(0); return 0; } int vixPlaybackOn(void) { LOGWRITE("Enable overlay\n"); // Turn on overlay VIDEO_OUT(vio, V1_CONTROL, VIDEO_IN(vio, V1_CONTROL) | V1_ENABLE); // Execute the changes VIDEO_OUT(vio, V_COMPOSE_MODE, VIDEO_IN(vio, V_COMPOSE_MODE) | V1_COMMAND_FIRE); return 0; } int vixPlaybackOff(void) { LOGWRITE("Disable overlay\n"); uc_ovl_vcmd_wait(vio); // Restore FIFO VIDEO_OUT(vio, V_FIFO_CONTROL, UC_MAP_V1_FIFO_CONTROL(16,12,8)); // Turn off overlay VIDEO_OUT(vio, V1_CONTROL, VIDEO_IN(vio, V1_CONTROL) & ~V1_ENABLE); // Execute the changes VIDEO_OUT(vio, V_COMPOSE_MODE, VIDEO_IN(vio, V_COMPOSE_MODE) | V1_COMMAND_FIRE); return 0; } int vixPlaybackFrameSelect(unsigned int frame) { LOGWRITE("Frame select\n"); uc_ovl_vcmd_wait(vio); // Configure buffer address VIDEO_OUT(vio, V1_STARTADDR_Y0, frames[frame]+YOffs); VIDEO_OUT(vio, V1_STARTADDR_CB0, frames[frame]+UOffs); VIDEO_OUT(vio, V1_STARTADDR_CR0, frames[frame]+VOffs); // Execute the changes VIDEO_OUT(vio, V_COMPOSE_MODE, VIDEO_IN(vio, V_COMPOSE_MODE) | V1_COMMAND_FIRE); return 0; } xine-lib-1.2/contrib/vidix/drivers/cyberblade_vid.c0000644000175000017500000003705114647725152020235 0ustar meme/* Driver for CyberBlade/i1 - Version 0.1.4 Copyright (C) 2002 by Alastair M. Robinson. Official homepage: http://www.blackfiveservices.co.uk/EPIAVidix.shtml Based on Permedia 3 driver by Måns Rullgård Thanks to Gilles Frattini for bugfixes This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Changes: 18/01/03 MMIO is no longer used, sidestepping cache issues on EPIA-800 TV-Out modes are now better supported - this should be the end of the magenta stripes :) Brightness/Contrast controls disabled for the time being - they were seriously degrading picture quality, especially with TV-Out. To Do: Implement Hue/Saturation controls Support / Test multiple frames Test colour-key code more extensively */ #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "cyberblade_regs.h" pciinfo_t pci_info; char save_colourkey[6]; char *cyberblade_mem; #ifdef DEBUG_LOGFILE FILE *logfile=0; #define LOGWRITE(x) {if(logfile) fprintf(logfile,x);} #else #define LOGWRITE(x) #endif /* Helper functions for reading registers. */ #if 0 /* unused */ static int CRINW(int reg) { int result; result=CRINB(reg); result|=CRINB(reg+1)<<8; return(result); } #endif static void CROUTW(int reg,int val) { CROUTB(reg,val&255); CROUTB(reg+1,(val>>8)&255); } #if 0 /* unused */ static int SRINW(int reg) { int result; result=SRINB(reg); result|=SRINB(reg+1)<<8; return(result); } #endif static void SROUTW(int reg,int val) { SROUTB(reg,val&255); SROUTB(reg+1,(val>>8)&255); } #if 0 /* unused */ static void DumpRegisters(void) { #ifdef DEBUG_LOGFILE int reg,val; if(logfile) { LOGWRITE("CRTC Register Dump:\n") for(reg=0;reg<256;++reg) { val=CRINB(reg); fprintf(logfile,"CR0x%2x: 0x%2x\n",reg,val); } LOGWRITE("SR Register Dump:\n") for(reg=0;reg<256;++reg) { val=SRINB(reg); fprintf(logfile,"SR0x%2x: 0x%2x\n",reg,val); } } #endif } #endif /* --- */ static vidix_capability_t cyberblade_cap = { "Trident CyberBlade i1 driver", "Alastair M. Robinson ", TYPE_OUTPUT, { 0, 0, 0, 0 }, 1024, 1024, 4, 4, -1, FLAG_UPSCALER|FLAG_DOWNSCALER, VENDOR_TRIDENT, -1, { 0, 0, 0, 0 } }; unsigned int vixGetVersion(void) { return(VIDIX_VERSION); } static unsigned short cyberblade_card_ids[] = { DEVICE_TRIDENT_CYBERBLADE_I7, DEVICE_TRIDENT_CYBERBLADE_I7D, DEVICE_TRIDENT_CYBERBLADE_I1, DEVICE_TRIDENT_CYBERBLADE_I12, DEVICE_TRIDENT_CYBERBLADE_I13, DEVICE_TRIDENT_CYBERBLADE_XPAI1 }; static int find_chip(unsigned chip_id) { unsigned i; for(i = 0;i < sizeof(cyberblade_card_ids)/sizeof(unsigned short);i++) { if(chip_id == cyberblade_card_ids[i]) return i; } return -1; } int vixProbe(int verbose, int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; (void)force; err = pci_scan(lst,&num_pci); if(err) { printf("[cyberblade] Error occurred during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0; i < num_pci; i++) { if(lst[i].vendor == VENDOR_TRIDENT) { int idx; const char *dname; idx = find_chip(lst[i].device); if(idx == -1) continue; dname = pci_device_name(VENDOR_TRIDENT, lst[i].device); dname = dname ? dname : "Unknown chip"; printf("[cyberblade] Found chip: %s\n", dname); cyberblade_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); break; } } } if(err && verbose) printf("[cyberblade] Can't find chip\n"); return err; } int vixInit(const char *args) { (void)args; cyberblade_mem = map_phys_mem(pci_info.base0, 0x800000); enable_app_io(); save_colourkey[0]=SRINB(0x50); save_colourkey[1]=SRINB(0x51); save_colourkey[2]=SRINB(0x52); save_colourkey[3]=SRINB(0x54); save_colourkey[4]=SRINB(0x55); save_colourkey[5]=SRINB(0x56); #ifdef DEBUG_LOGFILE logfile=fopen("/tmp/cyberblade_vidix.log","w"); #endif return 0; } void vixDestroy(void) { int protect; #ifdef DEBUG_LOGFILE if(logfile) fclose(logfile); #endif protect=SRINB(0x11); SROUTB(0x11, 0x92); CROUTB(0x8E, 0xc4); /* Disable overlay */ SROUTB(0x50,save_colourkey[0]); SROUTB(0x51,save_colourkey[1]); SROUTB(0x52,save_colourkey[2]); SROUTB(0x54,save_colourkey[3]); SROUTB(0x55,save_colourkey[4]); SROUTB(0x56,save_colourkey[5]); SROUTB(0x11, protect); disable_app_io(); unmap_phys_mem(cyberblade_mem, 0x800000); } int vixGetCapability(vidix_capability_t *to) { memcpy(to, &cyberblade_cap, sizeof(vidix_capability_t)); return 0; } static int is_supported_fourcc(uint32_t fourcc) { switch(fourcc) { case IMGFMT_YUY2: case IMGFMT_YV12: case IMGFMT_I420: case IMGFMT_YVU9: case IMGFMT_BGR16: return 1; default: return 0; } } int vixQueryFourcc(vidix_fourcc_t *to) { if(is_supported_fourcc(to->fourcc)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } static int frames[VID_PLAY_MAXFRAMES]; static vidix_grkey_t cyberblade_grkey; int vixGetGrKeys(vidix_grkey_t *grkey) { memcpy(grkey, &cyberblade_grkey, sizeof(vidix_grkey_t)); return(0); } int vixSetGrKeys(const vidix_grkey_t *grkey) { int pixfmt=CRINB(0x38); int protect; memcpy(&cyberblade_grkey, grkey, sizeof(vidix_grkey_t)); protect=SRINB(0x11); SROUTB(0x11, 0x92); if(pixfmt&0x28) /* 32 or 24 bpp */ { SROUTB(0x50, cyberblade_grkey.ckey.blue); /* Colour Key */ SROUTB(0x51, cyberblade_grkey.ckey.green); /* Colour Key */ SROUTB(0x52, cyberblade_grkey.ckey.red); /* Colour Key */ SROUTB(0x54, 0xff); /* Colour Key Mask */ SROUTB(0x55, 0xff); /* Colour Key Mask */ SROUTB(0x56, 0xff); /* Colour Key Mask */ } else { int tmp=((cyberblade_grkey.ckey.blue & 0xF8)>>3) | ((cyberblade_grkey.ckey.green & 0xfc)<<3) | ((cyberblade_grkey.ckey.red & 0xf8)<<8); SROUTB(0x50, tmp&0xff); /* Colour Key */ SROUTB(0x51, (tmp>>8)&0xff); /* Colour Key */ SROUTB(0x52, 0); /* Colour Key */ SROUTB(0x54, 0xff); /* Colour Key Mask */ SROUTB(0x55, 0xff); /* Colour Key Mask */ SROUTB(0x56, 0x00); /* Colour Key Mask */ } SROUTB(0x11,protect); return(0); } vidix_video_eq_t equal = { VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION | VEQ_CAP_HUE, 300, 100, 0, 0, 0, 0, 0, 0 }; int vixPlaybackGetEq( vidix_video_eq_t * eq) { memcpy(eq,&equal,sizeof(vidix_video_eq_t)); return 0; } int vixPlaybackSetEq( const vidix_video_eq_t * eq) { int br,sat,cr,protect; if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness; if(eq->cap & VEQ_CAP_CONTRAST) equal.contrast = eq->contrast; if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation; if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue; if(eq->cap & VEQ_CAP_RGB_INTENSITY) { equal.red_intensity = eq->red_intensity; equal.green_intensity = eq->green_intensity; equal.blue_intensity = eq->blue_intensity; } equal.flags = eq->flags; cr = (equal.contrast) * 31 / 2000; cr+=16; if (cr < 0) cr = 0; if(cr > 7) cr = 7; cr=cr<<4 | cr; br = (equal.brightness+1000) * 63 / 2000; if (br < 0) br = 0; if(br > 63) br = 63; if(br>32) br-=32; else br+=32; sat = (equal.saturation + 1000) * 16 / 2000; if (sat < 0) sat = 0; if(sat > 31) sat = 31; protect=SRINB(0x11); SROUTB(0x11, 0x92); SROUTB(0xBC,cr); SROUTW(0xB0,(br<<10)|4); SROUTB(0x11, protect); return 0; } static int YOffs,UOffs,VOffs; int vixConfigPlayback(vidix_playback_t *info) { int src_w, drw_w; int src_h, drw_h; int hscale,vscale; long base0; int y_pitch = 0, uv_pitch = 0; int protect=0; int layout=0; unsigned int i; if(!is_supported_fourcc(info->fourcc)) return -1; src_w = info->src.w; src_h = info->src.h; drw_w = info->dest.w; drw_h = info->dest.h; switch(info->fourcc) { case IMGFMT_YUY2: case IMGFMT_BGR16: y_pitch = (src_w*2 + 15) & ~15; uv_pitch = 0; YOffs=VOffs=UOffs=info->offset.y = info->offset.v = info->offset.u = 0; info->frame_size = y_pitch*src_h; layout=0x0; /* packed */ break; case IMGFMT_YV12: case IMGFMT_I420: y_pitch = (src_w+15) & ~15; uv_pitch = ((src_w/2)+7) & ~7; YOffs=info->offset.y = 0; VOffs=info->offset.v = y_pitch*src_h; UOffs=info->offset.u = info->offset.v+(uv_pitch)*(src_h/2); info->frame_size = y_pitch*src_h + 2*uv_pitch*(src_h/2); layout=0x1; /* planar, 4:1:1 */ break; case IMGFMT_YVU9: y_pitch = (src_w+15) & ~15; uv_pitch = ((src_w/4)+3) & ~3; YOffs=info->offset.y = 0; VOffs=info->offset.v = y_pitch*src_h; UOffs=info->offset.u = info->offset.v+(uv_pitch)*(src_h/4); info->frame_size = y_pitch*src_h + 2*uv_pitch*(src_h/4); layout=0x51; /* planar, 16:1:1 */ break; } /* Assume we have 2 MB to play with */ info->num_frames = 0x200000 / info->frame_size; if(info->num_frames > VID_PLAY_MAXFRAMES) info->num_frames = VID_PLAY_MAXFRAMES; /* Start at 6 MB. Let's hope it's not in use. */ base0 = 0x600000; info->dga_addr = cyberblade_mem + base0; info->dest.pitch.y = 16; info->dest.pitch.u = 16; info->dest.pitch.v = 16; for(i = 0; i < info->num_frames; i++) { info->offsets[i] = info->frame_size * i; frames[i] = base0+info->offsets[i]; } OUTPORT8(0x3d4,0x39); OUTPORT8(0x3d5,INPORT(0x3d5)|1); SRINB(0x0b); /* Select new mode */ /* Unprotect hardware registers... */ protect=SRINB(0x11); SROUTB(0x11, 0x92); SROUTB(0x57, 0xc0); /* Playback key function */ SROUTB(0x21, 0x34); /* Signature control */ SROUTB(0x37, 0x30); /* Video key mode */ vixSetGrKeys(&cyberblade_grkey); /* compute_scale_factor(&src_w, &drw_w, &shrink, &zoom); */ { int HTotal,VTotal,HSync,VSync,Overflow,HDisp,VDisp; int HWinStart,VWinStart; int tx1,ty1,tx2,ty2; HTotal=CRINB(0x00); HSync=CRINB(0x04); VTotal=CRINB(0x06); VSync=CRINB(0x10); Overflow=CRINB(0x07); HTotal <<=3; HSync <<=3; VTotal |= (Overflow & 1) <<8; VTotal |= (Overflow & 0x20) <<4; VTotal +=4; VSync |= (Overflow & 4) <<6; VSync |= (Overflow & 0x80) <<2; if(CRINB(0xd1)&0x80) { int TVHTotal,TVVTotal,TVHSyncStart,TVVSyncStart,TVOverflow; LOGWRITE("[cyberblade] Using TV-CRTC\n"); HDisp=(1+CRINB(0x01))*8; VDisp=1+CRINB(0x12); Overflow=CRINB(0x07); VDisp |= (Overflow & 2) <<7; VDisp |= (Overflow & 0x40) << 3; TVHTotal=CRINB(0xe0)*8; TVVTotal=CRINB(0xe6); TVOverflow=CRINB(0xe7); if(TVOverflow&0x20) TVVTotal|=512; if(TVOverflow&0x01) TVVTotal|=256; TVHTotal+=40; TVVTotal+=2; TVHSyncStart=CRINB(0xe4)*8; TVVSyncStart=CRINB(0xf0); if(TVOverflow&0x80) TVVSyncStart|=512; if(TVOverflow&0x04) TVVSyncStart|=256; HWinStart=(TVHTotal-HDisp)&15; HWinStart|=(HTotal-HDisp)&15; HWinStart+=(TVHTotal-TVHSyncStart)-49; } else { LOGWRITE("[cyberblade] Using Standard CRTC\n"); HWinStart=(HTotal-HSync)+15; } VWinStart=(VTotal-VSync)-8; printf("[cyberblade] HTotal: 0x%x, HSStart: 0x%x\n",HTotal,HSync); printf(" VTotal: 0x%x, VStart: 0x%x\n",VTotal,VSync); tx1=HWinStart+info->dest.x; ty1=VWinStart+info->dest.y; tx2=tx1+info->dest.w; ty2=ty1+info->dest.h; CROUTW(0x86,tx1); CROUTW(0x88,ty1); CROUTW(0x8a,tx2); CROUTW(0x8c,ty2+3); } if(src_w==drw_w) hscale=0; else if(src_w> 2; CROUTB(0x95, ((lb & 0x100)>>1) | 0x08 ); /* Linebuffer level bit 8 & threshold */ CROUTB(0x96, (lb & 0xFF)); /* Linebuffer level */ CROUTB(0x97, 0x00); /* VDE Flags */ CROUTB(0xBA, 0x00); /* Chroma key */ CROUTB(0xBB, 0x00); /* Chroma key */ CROUTB(0xBC, 0xFF); /* Chroma key */ CROUTB(0xBD, 0xFF); /* Chroma key */ CROUTB(0xBE, 0x04); /* Capture control */ if(src_w > 384) layout|=4; /* 2x line buffers */ SROUTB(0x97, layout); CROUTW(0x90,y_pitch); /* Y Bytes per row */ SROUTW(0x9A,uv_pitch); /* UV Bytes per row */ switch(info->fourcc) { case IMGFMT_BGR16: CROUTB(0x8F, 0x24); /* VDE Flags - Edge Recovery & CSC Bypass */ CROUTB(0xBF, 0x02); /* Video format - RGB16 */ SROUTB(0xBE, 0x0); /* HSCB disabled */ break; default: CROUTB(0x8F, 0x20); /* VDE Flags - Edge Recovery */ CROUTB(0xBF, 0x00); /* Video format - YUV */ SROUTB(0xBE, 0x00); /* HSCB disable - was 0x03*/ break; } CROUTB(0x92, ((base0+info->offset.y) >> 3) &0xff); /* Lower 8 bits of start address */ CROUTB(0x93, ((base0+info->offset.y) >> 11) &0xff); /* Mid 8 bits of start address */ CROUTB(0x94, ((base0+info->offset.y) >> 19) &0xf); /* Upper 4 bits of start address */ SROUTB(0x80, ((base0+info->offset.v) >> 3) &0xff); /* Lower 8 bits of start address */ SROUTB(0x81, ((base0+info->offset.v) >> 11) &0xff); /* Mid 8 bits of start address */ SROUTB(0x82, ((base0+info->offset.v) >> 19) &0xf); /* Upper 4 bits of start address */ SROUTB(0x83, ((base0+info->offset.u) >> 3) &0xff); /* Lower 8 bits of start address */ SROUTB(0x84, ((base0+info->offset.u) >> 11) &0xff); /* Mid 8 bits of start address */ SROUTB(0x85, ((base0+info->offset.u) >> 19) &0xf); /* Upper 4 bits of start address */ } vixPlaybackSetEq(&equal); /* Protect hardware registers again */ SROUTB(0x11, protect); return 0; } int vixPlaybackOn(void) { LOGWRITE("Enable overlay\n"); CROUTB(0x8E, 0xd4); /* VDE Flags*/ return 0; } int vixPlaybackOff(void) { LOGWRITE("Disable overlay\n"); CROUTB(0x8E, 0xc4); /* VDE Flags*/ return 0; } int vixPlaybackFrameSelect(unsigned int frame) { int protect; LOGWRITE("Frame select\n"); protect=SRINB(0x11); SROUTB(0x11, 0x92); /* Set overlay address to that of selected frame */ CROUTB(0x92, ((frames[frame]+YOffs) >> 3) &0xff); /* Lower 8 bits of start address */ CROUTB(0x93, ((frames[frame]+YOffs) >> 11) &0xff); /* Mid 8 bits of start address */ CROUTB(0x94, ((frames[frame]+YOffs) >> 19) &0xf); /* Upper 4 bits of start address */ SROUTB(0x80, ((frames[frame]+VOffs) >> 3) &0xff); /* Lower 8 bits of start address */ SROUTB(0x81, ((frames[frame]+VOffs) >> 11) &0xff); /* Mid 8 bits of start address */ SROUTB(0x82, ((frames[frame]+VOffs) >> 19) &0xf); /* Upper 4 bits of start address */ SROUTB(0x83, ((frames[frame]+UOffs) >> 3) &0xff); /* Lower 8 bits of start address */ SROUTB(0x84, ((frames[frame]+UOffs) >> 11) &0xff); /* Mid 8 bits of start address */ SROUTB(0x85, ((frames[frame]+UOffs) >> 19) &0xf); /* Upper 4 bits of start address */ SROUTB(0x11, protect); return 0; } xine-lib-1.2/contrib/vidix/drivers/nvidia_vid.c0000644000175000017500000007673014647725152017422 0ustar meme/* nvidia_vid - VIDIX based video driver for NVIDIA chips Copyrights 2003 - 2004 Sascha Sommer. This file is based on sources from RIVATV (rivatv.sf.net) Licence: GPL WARNING: THIS DRIVER IS IN BETA STAGE multi buffer support and TNT2 fixes by Dmitry Baryshkov */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "bswap.h" pciinfo_t pci_info; #define MAX_FRAMES 3 #define NV04_BES_SIZE 1024*2000*4 static vidix_capability_t nvidia_cap = { "NVIDIA RIVA OVERLAY DRIVER", "Sascha Sommer ", TYPE_OUTPUT, { 0, 0, 0, 0 }, 2046, 2046, 4, 4, -1, FLAG_UPSCALER|FLAG_DOWNSCALER, VENDOR_NVIDIA2, -1, { 0, 0, 0, 0 } }; unsigned int vixGetVersion(void){ return(VIDIX_VERSION); } #define NV_ARCH_03 0x03 #define NV_ARCH_04 0x04 #define NV_ARCH_10 0x10 #define NV_ARCH_20 0x20 #define NV_ARCH_30 0x30 struct nvidia_cards { unsigned short chip_id; unsigned short arch; }; static struct nvidia_cards nvidia_card_ids[] = { /*NV03*/ {DEVICE_NVIDIA2_RIVA128, NV_ARCH_03}, {DEVICE_NVIDIA2_RIVA128ZX,NV_ARCH_03}, /*NV04*/ {DEVICE_NVIDIA_NV4_RIVA_TNT,NV_ARCH_04}, {DEVICE_NVIDIA_NV5_RIVA_TNT2,NV_ARCH_04}, {DEVICE_NVIDIA_NV5_RIVA_TNT22,NV_ARCH_04}, {DEVICE_NVIDIA_NV5_RIVA_TNT23,NV_ARCH_04}, {DEVICE_NVIDIA_NV6_VANTA,NV_ARCH_04}, {DEVICE_NVIDIA_NV6_VANTA2,NV_ARCH_04}, {DEVICE_NVIDIA2_TNT,NV_ARCH_04}, {DEVICE_NVIDIA2_TNT2,NV_ARCH_04}, {DEVICE_NVIDIA2_VTNT2,NV_ARCH_04}, {DEVICE_NVIDIA2_UTNT2 ,NV_ARCH_04}, {DEVICE_NVIDIA2_ITNT2,NV_ARCH_04}, {DEVICE_NVIDIA_NV5_ALADDIN_TNT2,NV_ARCH_30}, /*NV10*/ {DEVICE_NVIDIA_NV18_GEFORCE_PCX,NV_ARCH_10}, {DEVICE_NVIDIA_NV10_GEFORCE_256,NV_ARCH_10}, {DEVICE_NVIDIA_NV10DDR_GEFORCE_256,NV_ARCH_10}, {DEVICE_NVIDIA_NV10GL_QUADRO,NV_ARCH_10}, {DEVICE_NVIDIA_NV11_GEFORCE2_MX_MX,NV_ARCH_10}, {DEVICE_NVIDIA_NV11DDR_GEFORCE2_MX,NV_ARCH_10}, {DEVICE_NVIDIA_NV11_GEFORCE2_GO,NV_ARCH_10}, {DEVICE_NVIDIA_NV11GL_QUADRO2_MXR_EX,NV_ARCH_10}, {DEVICE_NVIDIA_NV15_GEFORCE2_GTS_PRO,NV_ARCH_10}, {DEVICE_NVIDIA_NV15DDR_GEFORCE2_TI,NV_ARCH_10}, {DEVICE_NVIDIA_NV15BR_GEFORCE2_ULTRA,NV_ARCH_10}, {DEVICE_NVIDIA_NV15GL_QUADRO2_PRO,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_MX,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_MX2,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_MX3,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_MX4,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_440,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_420,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_4202,NV_ARCH_10}, {DEVICE_NVIDIA_NV17GL_QUADRO4_550,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_4402,NV_ARCH_10}, {DEVICE_NVIDIA_NV17GL_QUADRO4_200_400,NV_ARCH_10}, {DEVICE_NVIDIA_NV17GL_QUADRO4_5502,NV_ARCH_10}, {DEVICE_NVIDIA_NV17GL_QUADRO4_5503,NV_ARCH_10}, {DEVICE_NVIDIA_NV17_GEFORCE4_410,NV_ARCH_10}, {DEVICE_NVIDIA_NV18_GEFORCE4_MX,NV_ARCH_10}, {DEVICE_NVIDIA_NV18_GEFORCE4_MX2,NV_ARCH_10}, {DEVICE_NVIDIA_NV18_GEFORCE4_MX3,NV_ARCH_10}, {DEVICE_NVIDIA_NV18_GEFORCE4_MX4,NV_ARCH_10}, {DEVICE_NVIDIA_NV18M_GEFORCE4_448,NV_ARCH_10}, {DEVICE_NVIDIA_NV18M_GEFORCE4_488,NV_ARCH_10}, {DEVICE_NVIDIA_NV18GL_QUADRO4_580,NV_ARCH_10}, {DEVICE_NVIDIA_NV18GL_QUADRO4_NVS,NV_ARCH_10}, {DEVICE_NVIDIA_NV18GL_QUADRO4_380,NV_ARCH_10}, {DEVICE_NVIDIA_NV18M_GEFORCE4_4482,NV_ARCH_10}, {DEVICE_NVIDIA_NVCRUSH11_GEFORCE2_MX,NV_ARCH_10}, {DEVICE_NVIDIA_NFORCE2_AGP_DIFFERENT,NV_ARCH_10}, {DEVICE_NVIDIA_NFORCE2_AGP,NV_ARCH_10}, {DEVICE_NVIDIA_NV18_GEFORCE4_MX5,NV_ARCH_10}, /*NV20*/ {DEVICE_NVIDIA_NV20_GEFORCE3,NV_ARCH_20}, {DEVICE_NVIDIA_NV20_GEFORCE3_TI,NV_ARCH_20}, {DEVICE_NVIDIA_NV20_GEFORCE3_TI2,NV_ARCH_20}, {DEVICE_NVIDIA_NV20DCC_QUADRO_DCC,NV_ARCH_20}, {DEVICE_NVIDIA_NV25_GEFORCE4_TI,NV_ARCH_20}, {DEVICE_NVIDIA_NV25_GEFORCE4_TI2,NV_ARCH_20}, {DEVICE_NVIDIA_NV25_GEFORCE4_TI3,NV_ARCH_20}, {DEVICE_NVIDIA_NV25_GEFORCE4_TI4,NV_ARCH_20}, {DEVICE_NVIDIA_NV25GL_QUADRO4_900,NV_ARCH_20}, {DEVICE_NVIDIA_NV25GL_QUADRO4_750,NV_ARCH_20}, {DEVICE_NVIDIA_NV25GL_QUADRO4_700,NV_ARCH_20}, {DEVICE_NVIDIA_NV28_GEFORCE4_TI,NV_ARCH_20}, {DEVICE_NVIDIA_NV28_GEFORCE4_TI2,NV_ARCH_20}, {DEVICE_NVIDIA_NV28_GEFORCE4_TI3,NV_ARCH_20}, {DEVICE_NVIDIA_NV28_GEFORCE4_TI4,NV_ARCH_20}, {DEVICE_NVIDIA_NV28GL_QUADRO4_980,NV_ARCH_20}, {DEVICE_NVIDIA_NV28GL_QUADRO4_780,NV_ARCH_20}, {DEVICE_NVIDIA_NV28GLM_QUADRO4_700,NV_ARCH_20}, /*NV30*/ {DEVICE_NVIDIA_NV30_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV30_GEFORCE_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV30_GEFORCE_FX3,NV_ARCH_30}, {DEVICE_NVIDIA_NV30GL_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV30GL_QUADRO_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV31_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV31_GEFORCE_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV31,NV_ARCH_30}, {DEVICE_NVIDIA_NV31_GEFORCE_FX3,NV_ARCH_30}, {DEVICE_NVIDIA_NV312,NV_ARCH_30}, {DEVICE_NVIDIA_NV313,NV_ARCH_30}, {DEVICE_NVIDIA_NV31M_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV31M_GEFORCE_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NVIDIA_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV314,NV_ARCH_30}, {DEVICE_NVIDIA_NV315,NV_ARCH_30}, {DEVICE_NVIDIA_NV316,NV_ARCH_30}, {DEVICE_NVIDIA_NV34_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV34_GEFORCE_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV34_GEFORCE_FX3,NV_ARCH_30}, {DEVICE_NVIDIA_NV34_GEFORCE_FX4,NV_ARCH_30}, {DEVICE_NVIDIA_NV34M_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV34M_GEFORCE_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV34_GEFORCE_FX5,NV_ARCH_30}, {DEVICE_NVIDIA_NV34_GEFORCE_FX6,NV_ARCH_30}, {DEVICE_NVIDIA_NV34M_GEFORCE_FX3,NV_ARCH_30}, {DEVICE_NVIDIA_NV34M_GEFORCE_FX4,NV_ARCH_30}, {DEVICE_NVIDIA_NV34GL_QUADRO_NVS,NV_ARCH_30}, {DEVICE_NVIDIA_NV34GL_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV34GLM_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV34_GEFORCE_FX7,NV_ARCH_30}, {DEVICE_NVIDIA_NV34,NV_ARCH_30}, {DEVICE_NVIDIA_NV35_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV35_GEFORCE_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV35_GEFORCE_FX3,NV_ARCH_30}, {DEVICE_NVIDIA_NV38_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV35_GEFORCE_FX4,NV_ARCH_30}, {DEVICE_NVIDIA_NV35GL_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV35GL_QUADRO_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_1_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_2_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_4_GEFORCE_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_5,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_GEFORCE_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_GEFORCE_FX3,NV_ARCH_30}, {DEVICE_NVIDIA_NV36,NV_ARCH_30}, {DEVICE_NVIDIA_NV362,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV36GL_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV36GL,NV_ARCH_30}, {DEVICE_NVIDIA_NV36_GEFORCE_PCX,NV_ARCH_30}, {DEVICE_NVIDIA_NV35_GEFORCE_PCX,NV_ARCH_30}, {DEVICE_NVIDIA_NV37GL_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV37GL_QUADRO_FX2,NV_ARCH_30}, {DEVICE_NVIDIA_NV38GL_QUADRO_FX,NV_ARCH_30}, /* FIXME are they different? */ {DEVICE_NVIDIA_NV40_GEFORCE_6800,NV_ARCH_30}, {DEVICE_NVIDIA_NV40_GEFORCE_68002,NV_ARCH_30}, {DEVICE_NVIDIA_NV40_2,NV_ARCH_30}, {DEVICE_NVIDIA_NV40_3,NV_ARCH_30}, {DEVICE_NVIDIA_NV40_GEFORCE_68003,NV_ARCH_30}, {DEVICE_NVIDIA_NV40GL,NV_ARCH_30}, {DEVICE_NVIDIA_NV40GL_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV41_0,NV_ARCH_30}, {DEVICE_NVIDIA_NV41_1,NV_ARCH_30}, {DEVICE_NVIDIA_NV41_2,NV_ARCH_30}, {DEVICE_NVIDIA_NV41_8,NV_ARCH_30}, {DEVICE_NVIDIA_NV41GL,NV_ARCH_30}, {DEVICE_NVIDIA_NV40_GEFORCE_6800_GEFORCE,NV_ARCH_30}, {DEVICE_NVIDIA_NV43_GEFORCE_6600_GEFORCE,NV_ARCH_30}, {DEVICE_NVIDIA_NV43_GEFORCE_6600,NV_ARCH_30}, {DEVICE_NVIDIA_NV45GL_QUADRO_FX,NV_ARCH_30}, {DEVICE_NVIDIA_NV40_GEFORCE_68004,NV_ARCH_30} }; static int find_chip(unsigned chip_id){ unsigned i; for(i = 0;i < sizeof(nvidia_card_ids)/sizeof(struct nvidia_cards);i++) { if(chip_id == nvidia_card_ids[i].chip_id)return i; } return -1; } int vixProbe(int verbose, int force){ pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; if (force) printf("[nvidia_vid]: warning: forcing not supported yet!\n"); err = pci_scan(lst,&num_pci); if(err){ printf("[nvidia_vid] Error occurred during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0; i < num_pci; i++){ if(lst[i].vendor == VENDOR_NVIDIA2 || lst[i].vendor == VENDOR_NVIDIA){ int idx; const char *dname; idx = find_chip(lst[i].device); if(idx == -1) continue; dname = pci_device_name(lst[i].vendor, lst[i].device); dname = dname ? dname : "Unknown chip"; printf("[nvidia_vid] Found chip: %s\n", dname); nvidia_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); break; } } } if(err && verbose) printf("[nvidia_vid] Can't find chip\n"); return err; } /* * PCI-Memory IO access macros. */ #define VID_WR08(p,i,val) (((uint8_t *)(p))[(i)]=(val)) #define VID_RD08(p,i) (((uint8_t *)(p))[(i)]) #define VID_WR32(p,i,val) (((uint32_t *)(p))[(i)/4]=(val)) #define VID_RD32(p,i) (((uint32_t *)(p))[(i)/4]) #ifndef USE_RMW_CYCLES /* * Can be used to inhibit READ-MODIFY-WRITE cycles. On by default. */ #define MEM_BARRIER() __asm__ __volatile__ ("" : : : "memory") #undef VID_WR08 #define VID_WR08(p,i,val) ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]=(val); }) #undef VID_RD08 #define VID_RD08(p,i) ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]; }) #undef VID_WR32 #define VID_WR32(p,i,val) ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]=(val); }) #undef VID_RD32 #define VID_RD32(p,i) ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]; }) #endif /* USE_RMW_CYCLES */ #define VID_AND32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)&(val)) #define VID_OR32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)|(val)) #define VID_XOR32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)^(val)) struct rivatv_chip { volatile uint32_t *PMC; /* general control */ volatile uint32_t *PME; /* multimedia port */ volatile uint32_t *PFB; /* framebuffer control */ volatile uint32_t *PVIDEO; /* overlay control */ volatile uint8_t *PCIO; /* SVGA (CRTC, ATTR) registers */ volatile uint8_t *PVIO; /* SVGA (MISC, GRAPH, SEQ) registers */ volatile uint32_t *PRAMIN; /* instance memory */ volatile uint32_t *PRAMHT; /* hash table */ volatile uint32_t *PRAMFC; /* fifo context table */ volatile uint32_t *PRAMRO; /* fifo runout table */ volatile uint32_t *PFIFO; /* fifo control region */ volatile uint32_t *FIFO; /* fifo channels (USER) */ volatile uint32_t *PGRAPH; /* graphics engine */ unsigned long fbsize; /* framebuffer size */ int arch; /* compatible NV_ARCH_XX define */ int realarch; /* real architecture */ void (* lock) (struct rivatv_chip *, int); }; typedef struct rivatv_chip rivatv_chip; struct rivatv_info { unsigned int use_colorkey; unsigned int colorkey; /* saved xv colorkey*/ unsigned int vidixcolorkey; /*currently used colorkey*/ unsigned int depth; unsigned int format; unsigned int pitch; unsigned int width,height; unsigned int d_width,d_height; /*scaled width && height*/ unsigned int wx,wy; /*window x && y*/ unsigned int screen_x; /*screen width*/ unsigned int screen_y; /*screen height*/ unsigned long buffer_size; /* size of the image buffer */ struct rivatv_chip chip; /* NV architecture structure */ uint8_t* video_base; /* virtual address of control region */ uint8_t* control_base; /* virtual address of fb region */ unsigned long picture_base; /* direct pointer to video picture */ unsigned long picture_offset; /* offset of video picture in frame buffer */ // struct rivatv_dma dma; /* DMA structure */ unsigned int cur_frame; unsigned int num_frames; /* number of buffers */ int bps; /* bytes per line */ }; typedef struct rivatv_info rivatv_info; //framebuffer size funcs static unsigned long rivatv_fbsize_nv03 (struct rivatv_chip *chip){ if (VID_RD32 (chip->PFB, 0) & 0x00000020) { if (((VID_RD32 (chip->PMC, 0) & 0xF0) == 0x20) && ((VID_RD32 (chip->PMC, 0) & 0x0F) >= 0x02)) { /* SDRAM 128 ZX. */ return ((1 << (VID_RD32 (chip->PFB, 0) & 0x03)) * 1024 * 1024); } else { return 1024 * 1024 * 8; } } else { /* SGRAM 128. */ switch (chip->PFB[0x00000000] & 0x00000003) { case 0: return 1024 * 1024 * 8; break; case 2: return 1024 * 1024 * 4; break; default: return 1024 * 1024 * 2; break; } } } static unsigned long rivatv_fbsize_nv04 (struct rivatv_chip *chip){ if (VID_RD32 (chip->PFB, 0) & 0x00000100) { return ((VID_RD32 (chip->PFB, 0) >> 12) & 0x0F) * 1024 * 1024 * 2 + 1024 * 1024 * 2; } else { switch (VID_RD32 (chip->PFB, 0) & 0x00000003) { case 0: return 1024 * 1024 * 32; break; case 1: return 1024 * 1024 * 4; break; case 2: return 1024 * 1024 * 8; break; case 3: default: return 1024 * 1024 * 16; break; } } } static unsigned long rivatv_fbsize_nv10 (struct rivatv_chip *chip){ return ((VID_RD32 (chip->PFB, 0x20C) >> 20) & 0x000000FF) * 1024 * 1024; } //lock funcs static void rivatv_lock_nv03 (struct rivatv_chip *chip, int LockUnlock){ VID_WR08 (chip->PVIO, 0x3C4, 0x06); VID_WR08 (chip->PVIO, 0x3C5, LockUnlock ? 0x99 : 0x57); } static void rivatv_lock_nv04 (struct rivatv_chip *chip, int LockUnlock){ VID_WR08 (chip->PCIO, 0x3C4, 0x06); VID_WR08 (chip->PCIO, 0x3C5, LockUnlock ? 0x99 : 0x57); VID_WR08 (chip->PCIO, 0x3D4, 0x1F); VID_WR08 (chip->PCIO, 0x3D5, LockUnlock ? 0x99 : 0x57); } /* Enable PFB (Framebuffer), PVIDEO (Overlay unit) and PME (Mediaport) if neccessary. */ static void rivatv_enable_PMEDIA (struct rivatv_info *info){ uint32_t reg; /* switch off interrupts once for a while */ // VID_WR32 (info->chip.PME, 0x200140, 0x00); // VID_WR32 (info->chip.PMC, 0x000140, 0x00); reg = VID_RD32 (info->chip.PMC, 0x000200); /* NV3 (0x10100010): NV03_PMC_ENABLE_PMEDIA, NV03_PMC_ENABLE_PFB, NV03_PMC_ENABLE_PVIDEO */ if ((reg & 0x10100010) != 0x10100010) { printf("PVIDEO and PFB disabled, enabling...\n"); VID_OR32 (info->chip.PMC, 0x000200, 0x10100010); } /* save the current colorkey */ switch (info->chip.arch ) { case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: /* NV_PVIDEO_COLOR_KEY */ info->colorkey = VID_RD32 (info->chip.PVIDEO, 0xB00); break; case NV_ARCH_03: case NV_ARCH_04: /* NV_PVIDEO_KEY */ info->colorkey = VID_RD32 (info->chip.PVIDEO, 0x240); break; } /* re-enable interrupts again */ // VID_WR32 (info->chip.PMC, 0x000140, 0x01); // VID_WR32 (info->chip.PME, 0x200140, 0x01); } /* Stop overlay video. */ static void rivatv_overlay_stop (struct rivatv_info *info) { switch (info->chip.arch ) { case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: /* NV_PVIDEO_COLOR_KEY */ /* Xv-Extension-Hack: Restore previously saved value. */ VID_WR32 (info->chip.PVIDEO, 0xB00, info->colorkey); /* NV_PVIDEO_STOP */ VID_OR32 (info->chip.PVIDEO, 0x704, 0x11); /* NV_PVIDEO_BUFFER */ VID_AND32 (info->chip.PVIDEO, 0x700, ~0x11); /* NV_PVIDEO_INTR_EN_BUFFER */ // VID_AND32 (info->chip.PVIDEO, 0x140, ~0x11); break; case NV_ARCH_03: case NV_ARCH_04: /* NV_PVIDEO_KEY */ VID_WR32 (info->chip.PVIDEO, 0x240, info->colorkey); /* NV_PVIDEO_OVERLAY_VIDEO_OFF */ VID_AND32 (info->chip.PVIDEO, 0x244, ~0x01); /* NV_PVIDEO_INTR_EN_0_NOTIFY */ // VID_AND32 (info->chip.PVIDEO, 0x140, ~0x01); /* NV_PVIDEO_OE_STATE */ VID_WR32 (info->chip.PVIDEO, 0x224, 0); /* NV_PVIDEO_SU_STATE */ VID_WR32 (info->chip.PVIDEO, 0x228, 0); /* NV_PVIDEO_RM_STATE */ VID_WR32 (info->chip.PVIDEO, 0x22C, 0); break; } } /* Get pan offset of the physical screen. */ static uint32_t rivatv_overlay_pan (struct rivatv_info *info){ uint32_t pan; info->chip.lock (&info->chip, 0); VID_WR08 (info->chip.PCIO, 0x3D4, 0x0D); pan = VID_RD08 (info->chip.PCIO, 0x3D5); VID_WR08 (info->chip.PCIO, 0x3D4, 0x0C); pan |= VID_RD08 (info->chip.PCIO, 0x3D5) << 8; VID_WR08 (info->chip.PCIO, 0x3D4, 0x19); pan |= (VID_RD08 (info->chip.PCIO, 0x3D5) & 0x1F) << 16; VID_WR08 (info->chip.PCIO, 0x3D4, 0x2D); pan |= (VID_RD08 (info->chip.PCIO, 0x3D5) & 0x60) << 16; return pan << 2; } /* Compute and set colorkey depending on the colour depth. */ static void rivatv_overlay_colorkey (rivatv_info* info, unsigned int chromakey){ uint32_t r, g, b, key = 0; r = (chromakey & 0x00FF0000) >> 16; g = (chromakey & 0x0000FF00) >> 8; b = chromakey & 0x000000FF; switch (info->depth) { case 15: key = ((r >> 3) << 10) | ((g >> 3) << 5) | ((b >> 3)); #ifndef WIN32 key = key | 0x00008000; #endif break; case 16: // XXX unchecked key = ((r >> 3) << 11) | ((g >> 2) << 5) | ((b >> 3)); #ifndef WIN32 key = key | 0x00008000; #endif break; case 24: // XXX unchecked, maybe swap order of masking - FIXME Can the card be in 24 bit mode anyway? key = (chromakey & 0x00FFFFFF) | 0x00800000; break; case 32: key = chromakey; #ifndef WIN32 key = key | 0x80000000; #endif break; } //printf("[nvidia_vid] depth=%d %08X \n", info->depth, chromakey); switch (info->chip.arch) { case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: VID_WR32 (info->chip.PVIDEO, 0xB00, key); break; case NV_ARCH_03: case NV_ARCH_04: VID_WR32 (info->chip.PVIDEO, 0x240, key); break; } } static void nv_getscreenproperties(struct rivatv_info *info){ uint32_t bpp=0; info->chip.lock(&info->chip, 0); /*get screen depth*/ VID_WR08(info->chip.PCIO, 0x03D4,0x28); bpp = VID_RD08(info->chip.PCIO,0x03D5)&0x3; if(bpp==3)bpp=4; if((bpp == 2) && (info->chip.PVIDEO[0x00000600/4] & 0x00001000) == 0x0)info->depth=15; else info->depth = bpp*8; /*get screen width*/ VID_WR08(info->chip.PCIO, 0x03D4, 0x1); info->screen_x = (1 + VID_RD08(info->chip.PCIO, 0x3D5)) * 8; /*get screen height*/ /* get first 8 bits in VT_DISPLAY_END*/ VID_WR08(info->chip.PCIO, 0x03D4, 0x12); info->screen_y = VID_RD08(info->chip.PCIO,0x03D5); VID_WR08(info->chip.PCIO,0x03D4,0x07); /* get 9th bit in CRTC_OVERFLOW*/ info->screen_y |= (VID_RD08(info->chip.PCIO,0x03D5) &0x02)<<7; /* and the 10th in CRTC_OVERFLOW*/ info->screen_y |=(VID_RD08(info->chip.PCIO,0x03D5) &0x40)<<3; ++info->screen_y; } /* Start overlay video. */ static void rivatv_overlay_start (struct rivatv_info *info,int bufno){ uint32_t base, size, offset, xscale, yscale, pan; uint32_t value; int x=info->wx?info->wx:8, y=info->wy?info->wy:8; int lwidth=info->d_width, lheight=info->d_height; int bps; int i; size = info->buffer_size; base = info->picture_offset; offset = bufno*size; /*update depth & dimensions here because it may change with vo vesa or vo fbdev*/ nv_getscreenproperties(info); if(info->depth){ // bps = info->screen_x * ((info->depth+1)/8); /* get pan offset of the physical screen */ pan = rivatv_overlay_pan (info); /* adjust window position depending on the pan offset */ bps = 0; info->chip.lock (&info->chip, 0); for (i = 0; (i < 1024) && (bps == 0); i++) { if (info->chip.arch != NV_ARCH_03) bps = info->chip.PGRAPH[0x00000670/4]; else bps = info->chip.PGRAPH[0x00000650/4]; } if (bps == 0) { fprintf(stderr, "[nvidia_vid] reading bps returned 0!!!\n"); if (info->bps != 0) bps = info->bps; } else { info->bps = bps; } if (bps != 0) { x = info->wx - (pan % bps) * 8 / info->depth; y = info->wy - (pan / bps); } } /* adjust negative output window variables */ if (x < 0) { lwidth = info->d_width + x; offset += (-x * info->width / info->d_width) << 1; // offset += (-window->x * port->vld_width / window->width) << 1; x = 0; } if (y < 0) { lheight = info->d_height + y; offset += (-y * info->height / info->d_height * info->width) << 1; // offset += (-window->y * port->vld_height / window->height * port->org_width) << 1; y = 0; } switch (info->chip.arch) { case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: /* NV_PVIDEO_BASE */ VID_WR32 (info->chip.PVIDEO, 0x900 + 0, base + offset); //VID_WR32 (info->chip.PVIDEO, 0x900 + 4, base); /* NV_PVIDEO_LIMIT */ VID_WR32 (info->chip.PVIDEO, 0x908 + 0, base + offset + size - 1); //VID_WR32 (info->chip.PVIDEO, 0x908 + 4, base + size - 1); /* extra code for NV20 && NV30 architectures */ if (info->chip.arch == NV_ARCH_20 || info->chip.arch == NV_ARCH_30) { VID_WR32 (info->chip.PVIDEO, 0x800 + 0, base + offset); //VID_WR32 (info->chip.PVIDEO, 0x800 + 4, base); VID_WR32 (info->chip.PVIDEO, 0x808 + 0, base + offset + size - 1); //VID_WR32 (info->chip.PVIDEO, 0x808 + 4, base + size - 1); } /* NV_PVIDEO_LUMINANCE */ VID_WR32 (info->chip.PVIDEO, 0x910 + 0, 0x00001000); //VID_WR32 (info->chip.PVIDEO, 0x910 + 4, 0x00001000); /* NV_PVIDEO_CHROMINANCE */ VID_WR32 (info->chip.PVIDEO, 0x918 + 0, 0x00001000); //VID_WR32 (info->chip.PVIDEO, 0x918 + 4, 0x00001000); /* NV_PVIDEO_OFFSET */ VID_WR32 (info->chip.PVIDEO, 0x920 + 0, 0x0); //VID_WR32 (info->chip.PVIDEO, 0x920 + 4, offset + pitch); /* NV_PVIDEO_SIZE_IN */ VID_WR32 (info->chip.PVIDEO, 0x928 + 0, ((info->height) << 16) | info->width); //VID_WR32 (info->chip.PVIDEO, 0x928 + 4, ((port->org_height/2) << 16) | port->org_width); /* NV_PVIDEO_POINT_IN */ VID_WR32 (info->chip.PVIDEO, 0x930 + 0, 0x00000000); //VID_WR32 (info->chip.PVIDEO, 0x930 + 4, 0x00000000); /* NV_PVIDEO_DS_DX_RATIO */ VID_WR32 (info->chip.PVIDEO, 0x938 + 0, (info->width << 20) / info->d_width); //VID_WR32 (info->chip.PVIDEO, 0x938 + 4, (port->org_width << 20) / window->width); /* NV_PVIDEO_DT_DY_RATIO */ VID_WR32 (info->chip.PVIDEO, 0x940 + 0, ((info->height) << 20) / info->d_height); //VID_WR32 (info->chip.PVIDEO, 0x940 + 4, ((port->org_height/2) << 20) / window->height); /* NV_PVIDEO_POINT_OUT */ VID_WR32 (info->chip.PVIDEO, 0x948 + 0, ((y + 0) << 16) | x); //VID_WR32 (info->chip.PVIDEO, 0x948 + 4, ((y + 0) << 16) | x); /* NV_PVIDEO_SIZE_OUT */ VID_WR32 (info->chip.PVIDEO, 0x950 + 0, (lheight << 16) | lwidth); //VID_WR32 (info->chip.PVIDEO, 0x950 + 4, (height << 16) | width); /* NV_PVIDEO_FORMAT */ value = info->pitch; if(info->use_colorkey)value |= 1 << 20; if(info->format == IMGFMT_YUY2)value |= 1 << 16; VID_WR32 (info->chip.PVIDEO, 0x958 + 0, value); //VID_WR32 (info->chip.PVIDEO, 0x958 + 4, (pitch << 1) | 0x00100000); /* NV_PVIDEO_INTR_EN_BUFFER */ // VID_OR32 (info->chip.PVIDEO, 0x140, 0x01/*0x11*/); /* NV_PVIDEO_STOP */ VID_WR32 (info->chip.PVIDEO, 0x704,0x0); /* NV_PVIDEO_BUFFER */ VID_WR32 (info->chip.PVIDEO, 0x700, 0x01/*0x11*/); break; case NV_ARCH_03: case NV_ARCH_04: /* NV_PVIDEO_OE_STATE */ VID_WR32 (info->chip.PVIDEO, 0x224, 0); /* NV_PVIDEO_SU_STATE */ VID_WR32 (info->chip.PVIDEO, 0x228, 0); /* NV_PVIDEO_RM_STATE */ VID_WR32 (info->chip.PVIDEO, 0x22C, 0); /* NV_PVIDEO_BUFF0_START_ADDRESS */ VID_WR32 (info->chip.PVIDEO, 0x20C + 0, base + offset + 0); VID_WR32 (info->chip.PVIDEO, 0x20C + 4, base + offset + 0); /* NV_PVIDEO_BUFF0_PITCH_LENGTH */ VID_WR32 (info->chip.PVIDEO, 0x214 + 0, info->pitch); VID_WR32 (info->chip.PVIDEO, 0x214 + 4, info->pitch); /* NV_PVIDEO_WINDOW_START */ VID_WR32 (info->chip.PVIDEO, 0x230, (y << 16) | x); /* NV_PVIDEO_WINDOW_SIZE */ VID_WR32 (info->chip.PVIDEO, 0x234, (lheight << 16) | lwidth); /* NV_PVIDEO_STEP_SIZE */ yscale = ((info->height - 1) << 11) / (info->d_height - 1); xscale = ((info->width - 1) << 11) / (info->d_width - 1); VID_WR32 (info->chip.PVIDEO, 0x200, (yscale << 16) | xscale); /* NV_PVIDEO_RED_CSC_OFFSET */ VID_WR32 (info->chip.PVIDEO, 0x280, 0x69); /* NV_PVIDEO_GREEN_CSC_OFFSET */ VID_WR32 (info->chip.PVIDEO, 0x284, 0x3e); /* NV_PVIDEO_BLUE_CSC_OFFSET */ VID_WR32 (info->chip.PVIDEO, 0x288, 0x89); /* NV_PVIDEO_CSC_ADJUST */ VID_WR32 (info->chip.PVIDEO, 0x28C, 0x00000); /* No colour correction! */ /* NV_PVIDEO_CONTROL_Y (BLUR_ON, LINE_HALF) */ VID_WR32 (info->chip.PVIDEO, 0x204, 0x001); /* NV_PVIDEO_CONTROL_X (WEIGHT_HEAVY, SHARPENING_ON, SMOOTHING_ON) */ VID_WR32 (info->chip.PVIDEO, 0x208, 0x111); /*directx overlay 0x110 */ /* NV_PVIDEO_FIFO_BURST_LENGTH */ VID_WR32 (info->chip.PVIDEO, 0x23C, 0x03); /* NV_PVIDEO_FIFO_THRES_SIZE */ VID_WR32 (info->chip.PVIDEO, 0x238, 0x38); /*windows uses 0x40*/ /* NV_PVIDEO_BUFF0_OFFSET */ VID_WR32 (info->chip.PVIDEO, 0x21C + 0, 0); VID_WR32 (info->chip.PVIDEO, 0x21C + 4, 0); /* NV_PVIDEO_INTR_EN_0_NOTIFY_ENABLED */ // VID_OR32 (info->chip.PVIDEO, 0x140, 0x01); /* NV_PVIDEO_OVERLAY (KEY_ON, VIDEO_ON, FORMAT_CCIR) */ value = 0x1; /*video on*/ if(info->format==IMGFMT_YUY2)value |= 0x100; if(info->use_colorkey)value |=0x10; VID_WR32 (info->chip.PVIDEO, 0x244, value); /* NV_PVIDEO_SU_STATE */ VID_XOR32 (info->chip.PVIDEO, 0x228, 1 << 16); break; } /*set colorkey*/ rivatv_overlay_colorkey(info,info->vidixcolorkey); } static rivatv_info* info; int vixInit(const char *args){ int mtrr; (void)args; info = (rivatv_info*)calloc(1,sizeof(rivatv_info)); info->control_base = map_phys_mem(pci_info.base0, 0x00C00000 + 0x00008000); info->chip.arch = nvidia_card_ids[find_chip(pci_info.device)].arch; printf("[nvidia_vid] arch %x register base %x\n",info->chip.arch,(unsigned int)info->control_base); info->chip.PFIFO = (uint32_t *) (info->control_base + 0x00002000); info->chip.FIFO = (uint32_t *) (info->control_base + 0x00800000); info->chip.PMC = (uint32_t *) (info->control_base + 0x00000000); info->chip.PFB = (uint32_t *) (info->control_base + 0x00100000); info->chip.PME = (uint32_t *) (info->control_base + 0x00000000); info->chip.PCIO = (uint8_t *) (info->control_base + 0x00601000); info->chip.PVIO = (uint8_t *) (info->control_base + 0x000C0000); info->chip.PGRAPH = (uint32_t *) (info->control_base + 0x00400000); /* setup chip specific functions */ switch (info->chip.arch) { case NV_ARCH_03: info->chip.lock = rivatv_lock_nv03; info->chip.fbsize = rivatv_fbsize_nv03 (&info->chip); info->chip.PVIDEO = (uint32_t *) (info->control_base + 0x00680000); break; case NV_ARCH_04: info->chip.lock = rivatv_lock_nv04; info->chip.fbsize = rivatv_fbsize_nv04 (&info->chip); info->chip.PRAMIN = (uint32_t *) (info->control_base + 0x00700000); info->chip.PVIDEO = (uint32_t *) (info->control_base + 0x00680000); break; case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: info->chip.lock = rivatv_lock_nv04; info->chip.fbsize = rivatv_fbsize_nv10 (&info->chip); info->chip.PRAMIN = (uint32_t *) (info->control_base + 0x00700000); info->chip.PVIDEO = (uint32_t *) (info->control_base + 0x00008000); break; } switch (info->chip.arch) { case NV_ARCH_03: { /* This maps framebuffer @6MB, thus 2MB are left for video. */ info->video_base = map_phys_mem(pci_info.base1, info->chip.fbsize); /* This may trash your screen for resolutions greater than 1024x768, sorry. */ info->picture_offset = 1024*768* 4 * ((info->chip.fbsize > 4194304)?2:1); info->picture_base = (uint32_t) info->video_base + info->picture_offset; info->chip.PRAMIN = (uint32_t *) (info->video_base + 0x00C00000); break; } case NV_ARCH_04: case NV_ARCH_10: case NV_ARCH_20: case NV_ARCH_30: { info->video_base = map_phys_mem(pci_info.base1, info->chip.fbsize); info->picture_offset = info->chip.fbsize - NV04_BES_SIZE; // info->picture_base = (unsigned long)map_phys_mem(pci_info.base1+info->picture_offset,NV04_BES_SIZE); info->picture_base = (uint32_t) info->video_base + info->picture_offset; break; } } printf("[nvidia_vid] detected memory size %u MB\n",(uint32_t)(info->chip.fbsize /1024/1024)); if ((mtrr = mtrr_set_type(pci_info.base1, info->chip.fbsize, MTRR_TYPE_WRCOMB))!= 0) printf("[nvidia_vid] unable to setup MTRR: %s\n", strerror(mtrr)); else printf("[nvidia_vid] MTRR set up\n"); nv_getscreenproperties(info); if(!info->depth)printf("[nvidia_vid] text mode: %ux%u\n",info->screen_x,info->screen_y); else printf("[nvidia_vid] video mode: %ux%u@%u\n",info->screen_x,info->screen_y, info->depth); rivatv_enable_PMEDIA(info); info->cur_frame = 0; info->use_colorkey = 0; return 0; } void vixDestroy(void){ unmap_phys_mem(info->control_base ,0x00C00000 + 0x00008000); unmap_phys_mem(info->video_base, info->chip.fbsize); free(info); } int vixGetCapability(vidix_capability_t *to){ memcpy(to, &nvidia_cap, sizeof(vidix_capability_t)); return 0; } inline static int is_supported_fourcc(uint32_t fourcc) { if (fourcc == IMGFMT_UYVY || fourcc == IMGFMT_YUY2) return 1; else return 0; } int vixQueryFourcc(vidix_fourcc_t *to){ if(is_supported_fourcc(to->fourcc)){ to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } int vixConfigPlayback(vidix_playback_t *vinfo){ uint32_t i; printf("called %s\n", __FUNCTION__); if (! is_supported_fourcc(vinfo->fourcc)) return ENOSYS; info->width = vinfo->src.w; info->height = vinfo->src.h; info->d_width = vinfo->dest.w; info->d_height = vinfo->dest.h; info->wx = vinfo->dest.x; info->wy = vinfo->dest.y; info->format = vinfo->fourcc; printf("[nvidia_vid] setting up a %dx%d-%dx%d video window (src %dx%d), format 0x%X\n", info->d_width, info->d_height, info->wx, info->wy, info->width, info->height, vinfo->fourcc); vinfo->dga_addr=(void*)(info->picture_base); switch (vinfo->fourcc) { case IMGFMT_YUY2: case IMGFMT_UYVY: vinfo->dest.pitch.y = 16; vinfo->dest.pitch.u = 0; vinfo->dest.pitch.v = 0; vinfo->offset.y = 0; vinfo->offset.v = 0; vinfo->offset.u = 0; info->pitch = ((info->width << 1) + (vinfo->dest.pitch.y-1)) & ~(vinfo->dest.pitch.y-1); vinfo->frame_size = info->pitch * info->height; break; } info->buffer_size = vinfo->frame_size; info->num_frames = vinfo->num_frames= (info->chip.fbsize - info->picture_offset)/vinfo->frame_size; if(vinfo->num_frames > MAX_FRAMES)vinfo->num_frames = MAX_FRAMES; // vinfo->num_frames = 1; // printf("[nvidia_vid] Number of frames %i\n",vinfo->num_frames); for(i=0;i num_frames;i++)vinfo->offsets[i] = vinfo->frame_size*i; return 0; } int vixPlaybackOn(void){ rivatv_overlay_start(info,info->cur_frame); return 0; } int vixPlaybackOff(void){ rivatv_overlay_stop(info); return 0; } int vixSetGrKeys( const vidix_grkey_t * grkey){ if (grkey->ckey.op == CKEY_FALSE) { info->use_colorkey = 0; printf("[nvidia_vid] colour keying disabled\n"); } else { info->use_colorkey = 1; info->vidixcolorkey = ((grkey->ckey.red<<16)|(grkey->ckey.green<<8)|grkey->ckey.blue); printf("[nvidia_vid] set colour key 0x%x\n",info->vidixcolorkey); } if(info->d_width && info->d_height)rivatv_overlay_start(info,0); return 0; } int vixPlaybackFrameSelect(unsigned int frame){ // printf("selecting buffer %d\n", frame); rivatv_overlay_start(info, frame); if (info->num_frames >= 1) info->cur_frame = frame/*(frame+1)%info->num_frames*/; return 0; } xine-lib-1.2/contrib/vidix/drivers/sis_bridge.c0000644000175000017500000005174014647725152017412 0ustar meme/** Video bridge detection for SiS 300 and 310/325 series chips. Copyright 2003 Jake Page, Sugar Media. Based on SiS Xv driver: Copyright 2002-2003 by Thomas Winischhofer, Vienna, Austria. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **/ #include #include #include #include "libdha.h" #include "sis_regs.h" #include "sis_defs.h" void sis_init_video_bridge(void); static void sis_ddc2_delay(unsigned short delaytime) { unsigned short i; int temp; for (i = 0; i < delaytime; i++) { inSISIDXREG(SISSR, 0x05, temp); } } static int sis_do_sense(int tempbl, int tempbh, int tempcl, int tempch) { int temp; outSISIDXREG(SISPART4, 0x11, tempbl); temp = tempbh | tempcl; setSISIDXREG(SISPART4, 0x10, 0xe0, temp); //usleep(200000); sis_ddc2_delay(0x1000); tempch &= 0x7f; inSISIDXREG(SISPART4, 0x03, temp); temp ^= 0x0e; temp &= tempch; return (temp == tempch); } /* sense connected devices on 30x bridge */ static void sis_sense_30x() { unsigned char backupP4_0d, backupP2_00, biosflag; unsigned char testsvhs_tempbl, testsvhs_tempbh; unsigned char testsvhs_tempcl, testsvhs_tempch; unsigned char testcvbs_tempbl, testcvbs_tempbh; unsigned char testcvbs_tempcl, testcvbs_tempch; unsigned char testvga2_tempbl, testvga2_tempbh; unsigned char testvga2_tempcl, testvga2_tempch; int myflag, result = 0, i, j, haveresult; #if 0 unsigned short temp; #endif inSISIDXREG(SISPART4, 0x0d, backupP4_0d); outSISIDXREG(SISPART4, 0x0d, (backupP4_0d | 0x04)); inSISIDXREG(SISPART2, 0x00, backupP2_00); outSISIDXREG(SISPART2, 0x00, (backupP2_00 | 0x1c)); sis_do_sense(0, 0, 0, 0); if ((sis_vga_engine == SIS_315_VGA) || (sis_device_id == DEVICE_SIS_300)) { #if 0 if (0 /*pSiS->sishw_ext.UseROM */ ) { if (sis_vga_engine == SIS_300_VGA) temp = 0xfe; else { temp = 0xf3; if (sis_device_id == DEVICE_SIS_330) temp = 0x11b; } if (pSiS->BIOS[temp] & 0x08) { if (sis_verbose > 1) { printf ("[SiS] SiS30x: Video bridge has DVI-I TMDS/VGA combo connector\n"); } orSISIDXREG(SISCR, 0x32, 0x80); } else { andSISIDXREG(SISCR, 0x32, 0x7f); } } #endif } if (sis_vga_engine == SIS_300_VGA) { if (0 /*pSiS->sishw_ext.UseROM */ ) { #if 0 testvga2_tempbh = pSiS->BIOS[0xf9]; testvga2_tempbl = pSiS->BIOS[0xf8]; testsvhs_tempbh = pSiS->BIOS[0xfb]; testsvhs_tempbl = pSiS->BIOS[0xfa]; testcvbs_tempbh = pSiS->BIOS[0xfd]; testcvbs_tempbl = pSiS->BIOS[0xfc]; biosflag = pSiS->BIOS[0xfe]; #endif } else { testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1; testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9; testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3; biosflag = 0; } if (sis_vbflags & (VB_301B | VB_302B | VB_301LV | VB_302LV)) { testvga2_tempbh = 0x01; testvga2_tempbl = 0x90; testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b; testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74; } inSISIDXREG(SISPART4, 0x01, myflag); if (myflag & 0x04) { testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd; testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd; testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee; } testvga2_tempch = 0x0e; testvga2_tempcl = 0x08; testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04; testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04; if (sis_device_id == DEVICE_SIS_300) { inSISIDXREG(SISSR, 0x3b, myflag); if (!(myflag & 0x01)) { testvga2_tempbh = 0x00; testvga2_tempbl = 0x00; testvga2_tempch = 0x00; testvga2_tempcl = 0x00; } } } else { if (0 /*pSiS->sishw_ext.UseROM */ ) { #if 0 if (sis_device_id == DEVICE_SIS_330) { testvga2_tempbh = pSiS->BIOS[0xe6]; testvga2_tempbl = pSiS->BIOS[0xe5]; testsvhs_tempbh = pSiS->BIOS[0xe8]; testsvhs_tempbl = pSiS->BIOS[0xe7]; testcvbs_tempbh = pSiS->BIOS[0xea]; testcvbs_tempbl = pSiS->BIOS[0xe9]; biosflag = pSiS->BIOS[0x11b]; } else { testvga2_tempbh = pSiS->BIOS[0xbe]; testvga2_tempbl = pSiS->BIOS[0xbd]; testsvhs_tempbh = pSiS->BIOS[0xc0]; testsvhs_tempbl = pSiS->BIOS[0xbf]; testcvbs_tempbh = pSiS->BIOS[0xc2]; testcvbs_tempbl = pSiS->BIOS[0xc1]; biosflag = pSiS->BIOS[0xf3]; } #endif } else { testvga2_tempbh = 0x00; testvga2_tempbl = 0xd1; testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xb9; testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xb3; biosflag = 0; } if (sis_vbflags & (VB_301B | VB_302B | VB_301LV | VB_302LV)) { if (0 /*pSiS->sishw_ext.UseROM */ ) { #if 0 if (sis_device_id == DEVICE_SIS_330) { testvga2_tempbh = pSiS->BIOS[0xec]; testvga2_tempbl = pSiS->BIOS[0xeb]; testsvhs_tempbh = pSiS->BIOS[0xee]; testsvhs_tempbl = pSiS->BIOS[0xed]; testcvbs_tempbh = pSiS->BIOS[0xf0]; testcvbs_tempbl = pSiS->BIOS[0xef]; } else { testvga2_tempbh = pSiS->BIOS[0xc4]; testvga2_tempbl = pSiS->BIOS[0xc3]; testsvhs_tempbh = pSiS->BIOS[0xc6]; testsvhs_tempbl = pSiS->BIOS[0xc5]; testcvbs_tempbh = pSiS->BIOS[0xc8]; testcvbs_tempbl = pSiS->BIOS[0xc7]; } #endif } else { if (sis_vbflags & (VB_301B | VB_302B)) { testvga2_tempbh = 0x01; testvga2_tempbl = 0x90; testsvhs_tempbh = 0x01; testsvhs_tempbl = 0x6b; testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x74; } else { testvga2_tempbh = 0x00; testvga2_tempbl = 0x00; testsvhs_tempbh = 0x02; testsvhs_tempbl = 0x00; testcvbs_tempbh = 0x01; testcvbs_tempbl = 0x00; } } } if (sis_vbflags & (VB_301 | VB_301B | VB_302B)) { inSISIDXREG(SISPART4, 0x01, myflag); if (myflag & 0x04) { testvga2_tempbh = 0x00; testvga2_tempbl = 0xfd; testsvhs_tempbh = 0x00; testsvhs_tempbl = 0xdd; testcvbs_tempbh = 0x00; testcvbs_tempbl = 0xee; } } if (sis_vbflags & (VB_301LV | VB_302LV)) { /* TW: No VGA2 or SCART on LV bridges */ testvga2_tempbh = 0x00; testvga2_tempbl = 0x00; testvga2_tempch = 0x00; testvga2_tempcl = 0x00; testsvhs_tempch = 0x04; testsvhs_tempcl = 0x08; testcvbs_tempch = 0x08; testcvbs_tempcl = 0x08; } else { testvga2_tempch = 0x0e; testvga2_tempcl = 0x08; testsvhs_tempch = 0x06; testsvhs_tempcl = 0x04; testcvbs_tempch = 0x08; testcvbs_tempcl = 0x04; } } /* XXX: ?? andSISIDXREG(SISCR, 0x32, ~0x14); */ /* pSiS->postVBCR32 &= ~0x14; */ /* scan for VGA2/SCART */ if (testvga2_tempch || testvga2_tempcl || testvga2_tempbh || testvga2_tempbl) { haveresult = 0; for (j = 0; j < 10; j++) { result = 0; for (i = 0; i < 3; i++) { if (sis_do_sense(testvga2_tempbl, testvga2_tempbh, testvga2_tempcl, testvga2_tempch)) result++; } if ((result == 0) || (result >= 2)) break; } if (result) { if (biosflag & 0x01) { if (sis_verbose > 1) { printf ("[SiS] SiS30x: Detected TV connected to SCART output\n"); } sis_vbflags |= TV_SCART; orSISIDXREG(SISCR, 0x32, 0x04); /*pSiS->postVBCR32 |= 0x04; */ } else { if (sis_verbose > 1) { printf ("[SiS] SiS30x: Detected secondary VGA connection\n"); } sis_vbflags |= VGA2_CONNECTED; orSISIDXREG(SISCR, 0x32, 0x10); /*pSiS->postVBCR32 |= 0x10; */ } } } /* scanning for TV */ /* XXX: ?? andSISIDXREG(SISCR, 0x32, ~0x03); */ /* pSiS->postVBCR32 &= ~0x03; */ result = sis_do_sense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl, testsvhs_tempch); haveresult = 0; for (j = 0; j < 10; j++) { result = 0; for (i = 0; i < 3; i++) { if (sis_do_sense(testsvhs_tempbl, testsvhs_tempbh, testsvhs_tempcl, testsvhs_tempch)) result++; } if ((result == 0) || (result >= 2)) break; } if (result) { if (sis_verbose > 1) { printf ("[SiS] SiS30x: Detected TV connected to SVIDEO output\n"); } /* TW: So we can be sure that there IS a SVIDEO output */ sis_vbflags |= TV_SVIDEO; orSISIDXREG(SISCR, 0x32, 0x02); //pSiS->postVBCR32 |= 0x02; } if ((biosflag & 0x02) || (!(result))) { haveresult = 0; for (j = 0; j < 10; j++) { result = 0; for (i = 0; i < 3; i++) { if (sis_do_sense(testcvbs_tempbl, testcvbs_tempbh, testcvbs_tempcl, testcvbs_tempch)) result++; } if ((result == 0) || (result >= 2)) break; } if (result) { if (sis_verbose > 1) { printf ("[SiS] SiS30x: Detected TV connected to COMPOSITE output\n"); } sis_vbflags |= TV_AVIDEO; orSISIDXREG(SISCR, 0x32, 0x01); //pSiS->postVBCR32 |= 0x01; } } sis_do_sense(0, 0, 0, 0); outSISIDXREG(SISPART2, 0x00, backupP2_00); outSISIDXREG(SISPART4, 0x0d, backupP4_0d); } static void sis_detect_crt1() { unsigned char CR32; unsigned char CRT1Detected = 0; unsigned char OtherDevices = 0; if (!(sis_vbflags & VB_VIDEOBRIDGE)) { sis_crt1_off = 0; return; } inSISIDXREG(SISCR, 0x32, CR32); if (CR32 & 0x20) CRT1Detected = 1; if (CR32 & 0x5F) OtherDevices = 1; if (sis_crt1_off == (unsigned int)-1) { if (!CRT1Detected) { /* BIOS detected no CRT1. */ /* If other devices exist, switch it off */ if (OtherDevices) sis_crt1_off = 1; else sis_crt1_off = 0; } else { /* BIOS detected CRT1, leave/switch it on */ sis_crt1_off = 0; } } if (sis_verbose > 0) { printf("[SiS] %sCRT1 connection detected\n", sis_crt1_off ? "No " : ""); } } #if 0 /* not used yet */ static void sis_detect_lcd() { unsigned char CR32; #if 0 /* not supported yet? */ unsigned char CR36, CR37; #endif if (!(sis_vbflags & VB_VIDEOBRIDGE)) { return; } inSISIDXREG(SISCR, 0x32, CR32); if (CR32 & 0x08) sis_vbflags |= CRT2_LCD; /* DDC detection of LCD - not supported yet */ /* Get other misc info about LCD - not supported */ } #endif static void sis_detect_tv() { unsigned char SR16, SR38, CR32, CR38 = 0, CR79; int temp = 0; if (!(sis_vbflags & VB_VIDEOBRIDGE)) return; inSISIDXREG(SISCR, 0x32, CR32); inSISIDXREG(SISSR, 0x16, SR16); inSISIDXREG(SISSR, 0x38, SR38); switch (sis_vga_engine) { case SIS_300_VGA: if (sis_device_id == DEVICE_SIS_630_VGA) temp = 0x35; break; case SIS_315_VGA: temp = 0x38; break; } if (temp) { inSISIDXREG(SISCR, temp, CR38); } if (CR32 & 0x47) sis_vbflags |= CRT2_TV; if (CR32 & 0x04) sis_vbflags |= TV_SCART; else if (CR32 & 0x02) sis_vbflags |= TV_SVIDEO; else if (CR32 & 0x01) sis_vbflags |= TV_AVIDEO; else if (CR32 & 0x40) sis_vbflags |= (TV_SVIDEO | TV_HIVISION); else if ((CR38 & 0x04) && (sis_vbflags & (VB_301LV | VB_302LV))) sis_vbflags |= TV_HIVISION_LV; else if ((CR38 & 0x04) && (sis_vbflags & VB_CHRONTEL)) sis_vbflags |= (TV_CHSCART | TV_PAL); else if ((CR38 & 0x08) && (sis_vbflags & VB_CHRONTEL)) sis_vbflags |= (TV_CHHDTV | TV_NTSC); if (sis_vbflags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION)) { if (sis_vga_engine == SIS_300_VGA) { /* TW: Should be SR38 here as well, but this * does not work. Looks like a BIOS bug (2.04.5c). */ if (SR16 & 0x20) sis_vbflags |= TV_PAL; else sis_vbflags |= TV_NTSC; } else if ((sis_device_id == DEVICE_SIS_550_VGA)) { inSISIDXREG(SISCR, 0x79, CR79); if (CR79 & 0x08) { inSISIDXREG(SISCR, 0x79, CR79); CR79 >>= 5; } if (CR79 & 0x01) { sis_vbflags |= TV_PAL; if (CR38 & 0x40) sis_vbflags |= TV_PALM; else if (CR38 & 0x80) sis_vbflags |= TV_PALN; } else sis_vbflags |= TV_NTSC; } else if ((sis_device_id == DEVICE_SIS_650_VGA)) { inSISIDXREG(SISCR, 0x79, CR79); if (CR79 & 0x20) { sis_vbflags |= TV_PAL; if (CR38 & 0x40) sis_vbflags |= TV_PALM; else if (CR38 & 0x80) sis_vbflags |= TV_PALN; } else sis_vbflags |= TV_NTSC; } else { /* 315, 330 */ if (SR38 & 0x01) { sis_vbflags |= TV_PAL; if (CR38 & 0x40) sis_vbflags |= TV_PALM; else if (CR38 & 0x80) sis_vbflags |= TV_PALN; } else sis_vbflags |= TV_NTSC; } } if (sis_vbflags & (TV_SCART | TV_SVIDEO | TV_AVIDEO | TV_HIVISION | TV_CHSCART | TV_CHHDTV)) { if (sis_verbose > 0) { printf("[SiS] %sTV standard %s\n", (sis_vbflags & (TV_CHSCART | TV_CHHDTV)) ? "Using " : "Detected default ", (sis_vbflags & TV_NTSC) ? ((sis_vbflags & TV_CHHDTV) ? "480i HDTV" : "NTSC") : ((sis_vbflags & TV_PALM) ? "PALM" : ((sis_vbflags & TV_PALN) ? "PALN" : "PAL"))); } } } static void sis_detect_crt2() { unsigned char CR32; if (!(sis_vbflags & VB_VIDEOBRIDGE)) return; /* CRT2-VGA not supported on LVDS and 30xLV */ if (sis_vbflags & (VB_LVDS | VB_301LV | VB_302LV)) return; inSISIDXREG(SISCR, 0x32, CR32); if (CR32 & 0x10) sis_vbflags |= CRT2_VGA; #if 0 if (!(pSiS->nocrt2ddcdetection)) { if (sis_vbflags & (VB_301B | VB_302B)) { if (!(sis_vbflags & (CRT2_VGA | CRT2_LCD))) { printf ("[SiS] BIOS detected no secondary VGA, sensing via DDC\n"); if (SiS_SenseVGA2DDC(pSiS->SiS_Pr, pSiS)) { printf ("[SiS] DDC error during secondary VGA detection\n"); } else { inSISIDXREG(SISCR, 0x32, CR32); if (CR32 & 0x10) { sis_vbflags |= CRT2_VGA; /*pSiS->postVBCR32 |= 0x10; */ printf ("[SiS] Detected secondary VGA connection\n"); } else { printf ("[SiS] No secondary VGA connection detected\n"); } } } } } #endif } /* Preinit: detect video bridge and sense connected devs */ static void sis_detect_video_bridge() { int temp, temp1, temp2; sis_vbflags = 0; if (sis_vga_engine != SIS_300_VGA && sis_vga_engine != SIS_315_VGA) return; inSISIDXREG(SISPART4, 0x00, temp); temp &= 0x0F; if (temp == 1) { inSISIDXREG(SISPART4, 0x01, temp1); temp1 &= 0xff; if (temp1 >= 0xE0) { sis_vbflags |= VB_302LV; //pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; if (sis_verbose > 1) { printf ("[SiS] Detected SiS302LV video bridge (ID 1; Revision 0x%x)\n", temp1); } } else if (temp1 >= 0xD0) { sis_vbflags |= VB_301LV; //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; if (sis_verbose > 1) { printf ("[SiS] Detected SiS301LV video bridge (ID 1; Revision 0x%x)\n", temp1); } } else if (temp1 >= 0xB0) { sis_vbflags |= VB_301B; //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301B; inSISIDXREG(SISPART4, 0x23, temp2); if (!(temp2 & 0x02)) sis_vbflags |= VB_30xBDH; if (sis_verbose > 1) { printf ("[SiS] Detected SiS301B%s video bridge (Revision 0x%x)\n", (temp2 & 0x02) ? "" : " (DH)", temp1); } } else { sis_vbflags |= VB_301; //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301; if (sis_verbose > 1) { printf ("[SiS] Detected SiS301 video bridge (Revision 0x%x)\n", temp1); } } sis_sense_30x(); } else if (temp == 2) { inSISIDXREG(SISPART4, 0x01, temp1); temp1 &= 0xff; if (temp1 >= 0xE0) { sis_vbflags |= VB_302LV; //pSiS->sishw_ext.ujVBChipID = VB_CHIP_302LV; if (sis_verbose > 1) { printf ("[SiS] Detected SiS302LV video bridge (ID 2; Revision 0x%x)\n", temp1); } } else if (temp1 >= 0xD0) { sis_vbflags |= VB_301LV; //pSiS->sishw_ext.ujVBChipID = VB_CHIP_301LV; if (sis_verbose > 1) { printf ("[SiS] Detected SiS301LV video bridge (ID 2; Revision 0x%x)\n", temp1); } } else { sis_vbflags |= VB_302B; //pSiS->sishw_ext.ujVBChipID = VB_CHIP_302B; inSISIDXREG(SISPART4, 0x23, temp2); if (!(temp & 0x02)) sis_vbflags |= VB_30xBDH; if (sis_verbose > 1) { printf ("[SiS] Detected SiS302B%s video bridge (Revision 0x%x)\n", (temp2 & 0x02) ? "" : " (DH)", temp1); } } sis_sense_30x(); } else if (temp == 3) { if (sis_verbose > 1) { printf("[SiS] Detected SiS303 video bridge - not supported\n"); } } else { /* big scary mess of code to handle unknown or Chrontel LVDS */ /* skipping it for now */ if (sis_verbose > 1) { printf ("[SiS] Detected Chrontel video bridge - not supported\n"); } } /* this is probably not relevant to video overlay driver... */ /* detects if brdige uses LCDA for low res text modes */ if (sis_vga_engine == SIS_315_VGA) { if (sis_vbflags & (VB_302B | VB_301LV | VB_302LV)) { #if 0 if (pSiS->sisfblcda != 0xff) { if ((pSiS->sisfblcda & 0x03) == 0x03) { //pSiS->SiS_Pr->SiS_UseLCDA = TRUE; sis_vbflags |= VB_USELCDA; } } else #endif { inSISIDXREG(SISCR, 0x34, temp); if (temp <= 0x13) { inSISIDXREG(SISCR, 0x38, temp); if ((temp & 0x03) == 0x03) { //pSiS->SiS_Pr->SiS_UseLCDA = TRUE; sis_vbflags |= VB_USELCDA; } else { inSISIDXREG(SISCR, 0x30, temp); if (temp & 0x20) { inSISIDXREG(SISPART1, 0x13, temp); if (temp & 0x40) { //pSiS->SiS_Pr->SiS_UseLCDA = TRUE; sis_vbflags |= VB_USELCDA; } } } } } if (sis_vbflags & VB_USELCDA) { /* printf("Bridge uses LCDA for low resolution and text modes\n"); */ } } } } /* detect video bridge type and sense connected devices */ void sis_init_video_bridge() { sis_detect_video_bridge(); sis_detect_crt1(); //sis_detect_lcd(); /* not fully ready probably */ sis_detect_tv(); sis_detect_crt2(); sis_detected_crt2_devices = sis_vbflags & (CRT2_LCD | CRT2_TV | CRT2_VGA); // force crt2 type if (sis_force_crt2_type == CRT2_DEFAULT) { if (sis_vbflags & CRT2_VGA) sis_force_crt2_type = CRT2_VGA; else if (sis_vbflags & CRT2_LCD) sis_force_crt2_type = CRT2_LCD; else if (sis_vbflags & CRT2_TV) sis_force_crt2_type = CRT2_TV; } switch (sis_force_crt2_type) { case CRT2_TV: sis_vbflags = sis_vbflags & ~(CRT2_LCD | CRT2_VGA); if (sis_vbflags & VB_VIDEOBRIDGE) sis_vbflags = sis_vbflags | CRT2_TV; else sis_vbflags = sis_vbflags & ~(CRT2_TV); break; case CRT2_LCD: sis_vbflags = sis_vbflags & ~(CRT2_TV | CRT2_VGA); if ((sis_vbflags & VB_VIDEOBRIDGE) /* XXX: && (pSiS->VBLCDFlags) */ ) sis_vbflags = sis_vbflags | CRT2_LCD; else { sis_vbflags = sis_vbflags & ~(CRT2_LCD); if (sis_verbose > 0) { printf ("[SiS] Can't force CRT2 to LCD, no panel detected\n"); } } break; case CRT2_VGA: if (sis_vbflags & VB_LVDS) { if (sis_verbose > 0) { printf("[SiS] LVDS does not support secondary VGA\n"); } break; } if (sis_vbflags & (VB_301LV | VB_302LV)) { if (sis_verbose > 0) { printf ("[SiS] SiS30xLV bridge does not support secondary VGA\n"); } break; } sis_vbflags = sis_vbflags & ~(CRT2_TV | CRT2_LCD); if (sis_vbflags & VB_VIDEOBRIDGE) sis_vbflags = sis_vbflags | CRT2_VGA; else sis_vbflags = sis_vbflags & ~(CRT2_VGA); break; default: sis_vbflags &= ~(CRT2_TV | CRT2_LCD | CRT2_VGA); } /* CRT2 gamma correction?? */ /* other force modes: */ /* have a 'force tv type' (svideo, composite, scart) option? */ /* have a 'force crt1 type' (to turn it off, etc??) */ /* TW: Check if CRT1 used (or needed; this eg. if no CRT2 detected) */ if (sis_vbflags & VB_VIDEOBRIDGE) { /* TW: No CRT2 output? Then we NEED CRT1! * We also need CRT1 if depth = 8 and bridge=LVDS|630+301B */ if ((!(sis_vbflags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) || ( /*(pScrn->bitsPerPixel == 8) && */ ((sis_vbflags & (VB_LVDS | VB_CHRONTEL)) || ((sis_vga_engine == SIS_300_VGA) && (sis_vbflags & VB_301B))))) { sis_crt1_off = 0; } /* TW: No CRT2 output? Then we can't use hw overlay on CRT2 */ if (!(sis_vbflags & (CRT2_VGA | CRT2_LCD | CRT2_TV))) sis_overlay_on_crt1 = 1; } else { /* TW: no video bridge? */ /* Then we NEED CRT1... */ sis_crt1_off = 0; /* ... and can't use CRT2 for overlay output */ sis_overlay_on_crt1 = 1; } /* tvstandard options ? */ // determine using CRT1 or CRT2? /* -> NO dualhead right now... */ if (sis_vbflags & DISPTYPE_DISP2) { if (sis_crt1_off) { sis_vbflags |= VB_DISPMODE_SINGLE; /* TW: No CRT1? Then we use the video overlay on CRT2 */ sis_overlay_on_crt1 = 0; } else /* TW: CRT1 and CRT2 - mirror or dual head ----- */ sis_vbflags |= (VB_DISPMODE_MIRROR | DISPTYPE_CRT1); } else { /* TW: CRT1 only ------------------------------- */ sis_vbflags |= (VB_DISPMODE_SINGLE | DISPTYPE_CRT1); } if (sis_verbose > 0) { printf("[SiS] Using hardware overlay on CRT%d\n", sis_overlay_on_crt1 ? 1 : 2); } } xine-lib-1.2/contrib/vidix/drivers/mach64.h0000644000175000017500000030233714647725152016370 0ustar meme/* * mach64.h * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. * * It's based on radeonfb, X11, GATOS sources */ #ifndef __MACH64_INCLUDED #define __MACH64_INCLUDED 1 /* Note: this model of accessing to IO space is based on MMIO technology. This means that this sources don't support ISA and VLB cards */ #define BlockIOTag(val) (val) #define IOPortTag(sparce,val) (val) /* MDA/[M]CGA/EGA/VGA I/O ports */ #define GENVS 0x0102u /* Write (and Read on uC only) */ #define R_GENLPS 0x03b9u /* Read */ #define GENHP 0x03bfu #define ATTRX 0x03c0u #define ATTRD 0x03c1u #define GENS0 0x03c2u /* Read */ #define GENMO 0x03c2u /* Write */ #define GENENB 0x03c3u /* Read */ #define SEQX 0x03c4u #define SEQD 0x03c5u #define VGA_DAC_MASK 0x03c6u #define VGA_DAC_READ 0x03c7u #define VGA_DAC_WRITE 0x03c8u #define VGA_DAC_DATA 0x03c9u #define R_GENFC 0x03cau /* Read */ /* ? 0x03cbu */ #define R_GENMO 0x03ccu /* Read */ /* ? 0x03cdu */ #define GRAX 0x03ceu #define GRAD 0x03cfu #define GENB 0x03d9u #define GENLPS 0x03dcu /* Write */ #define KCX 0x03ddu #define KCD 0x03deu #define GENENA 0x46e8u /* Write */ /* I/O port base numbers */ #define MonochromeIOBase 0x03b0u #define ColourIOBase 0x03d0u /* Other MDA/[M]CGA/EGA/VGA I/O ports */ /* ?(_IOBase) ((_IOBase) + 0x00u) */ /* CRTX synonym */ /* ?(_IOBase) ((_IOBase) + 0x01u) */ /* CRTD synonym */ /* ?(_IOBase) ((_IOBase) + 0x02u) */ /* CRTX synonym */ /* ?(_IOBase) ((_IOBase) + 0x03u) */ /* CRTD synonym */ #define CRTX(_IOBase) ((_IOBase) + 0x04u) #define CRTD(_IOBase) ((_IOBase) + 0x05u) /* ?(_IOBase) ((_IOBase) + 0x06u) */ /* ?(_IOBase) ((_IOBase) + 0x07u) */ #define GENMC(_IOBase) ((_IOBase) + 0x08u) /* ?(_IOBase) ((_IOBase) + 0x09u) */ /* R_GENLPS/GENB */ #define GENS1(_IOBase) ((_IOBase) + 0x0au) /* Read */ #define GENFC(_IOBase) ((_IOBase) + 0x0au) /* Write */ #define GENLPC(_IOBase) ((_IOBase) + 0x0bu) /* ?(_IOBase) ((_IOBase) + 0x0cu) */ /* /GENLPS */ /* ?(_IOBase) ((_IOBase) + 0x0du) */ /* /KCX */ /* ?(_IOBase) ((_IOBase) + 0x0eu) */ /* /KCD */ /* ?(_IOBase) ((_IOBase) + 0x0fu) */ /* GENHP/ */ /* 8514/A VESA approved register definitions */ #define DISP_STAT 0x02e8u /* Read */ #define SENSE 0x0001u /* Presumably belong here */ #define VBLANK 0x0002u #define HORTOG 0x0004u #define H_TOTAL 0x02e8u /* Write */ #define IBM_DAC_MASK 0x02eau #define IBM_DAC_READ 0x02ebu #define IBM_DAC_WRITE 0x02ecu #define IBM_DAC_DATA 0x02edu #define H_DISP 0x06e8u /* Write */ #define H_SYNC_STRT 0x0ae8u /* Write */ #define H_SYNC_WID 0x0ee8u /* Write */ #define HSYNCPOL_POS 0x0000u #define HSYNCPOL_NEG 0x0020u #define H_POLARITY_POS HSYNCPOL_POS /* Sigh */ #define H_POLARITY_NEG HSYNCPOL_NEG /* Sigh */ #define V_TOTAL 0x12e8u /* Write */ #define V_DISP 0x16e8u /* Write */ #define V_SYNC_STRT 0x1ae8u /* Write */ #define V_SYNC_WID 0x1ee8u /* Write */ #define VSYNCPOL_POS 0x0000u #define VSYNCPOL_NEG 0x0020u #define V_POLARITY_POS VSYNCPOL_POS /* Sigh */ #define V_POLARITY_NEG VSYNCPOL_NEG /* Sigh */ #define DISP_CNTL 0x22e8u /* Write */ #define ODDBNKENAB 0x0001u #define MEMCFG_2 0x0000u #define MEMCFG_4 0x0002u #define MEMCFG_6 0x0004u #define MEMCFG_8 0x0006u #define DBLSCAN 0x0008u #define INTERLACE 0x0010u #define DISPEN_NC 0x0000u #define DISPEN_ENAB 0x0020u #define DISPEN_DISAB 0x0040u #define R_H_TOTAL 0x26e8u /* Read */ /* ? 0x2ae8u */ /* ? 0x2ee8u */ /* ? 0x32e8u */ /* ? 0x36e8u */ /* ? 0x3ae8u */ /* ? 0x3ee8u */ #define SUBSYS_STAT 0x42e8u /* Read */ #define VBLNKFLG 0x0001u #define PICKFLAG 0x0002u #define INVALIDIO 0x0004u #define GPIDLE 0x0008u #define MONITORID_MASK 0x0070u /* MONITORID_? 0x0000u */ #define MONITORID_8507 0x0010u #define MONITORID_8514 0x0020u /* MONITORID_? 0x0030u */ /* MONITORID_? 0x0040u */ #define MONITORID_8503 0x0050u #define MONITORID_8512 0x0060u #define MONITORID_8513 0x0060u #define MONITORID_NONE 0x0070u #define _8PLANE 0x0080u #define SUBSYS_CNTL 0x42e8u /* Write */ #define RVBLNKFLG 0x0001u #define RPICKFLAG 0x0002u #define RINVALIDIO 0x0004u #define RGPIDLE 0x0008u #define IVBLNKFLG 0x0100u #define IPICKFLAG 0x0200u #define IINVALIDIO 0x0400u #define IGPIDLE 0x0800u #define CHPTEST_NC 0x0000u #define CHPTEST_NORMAL 0x1000u #define CHPTEST_ENAB 0x2000u #define GPCTRL_NC 0x0000u #define GPCTRL_ENAB 0x4000u #define GPCTRL_RESET 0x8000u #define ROM_PAGE_SEL 0x46e8u /* Write */ #define ADVFUNC_CNTL 0x4ae8u /* Write */ #define DISABPASSTHRU 0x0001u #define CLOKSEL 0x0004u /* ? 0x4ee8u */ #define EXT_CONFIG_0 0x52e8u /* C & T 82C480 */ #define EXT_CONFIG_1 0x56e8u /* C & T 82C480 */ #define EXT_CONFIG_2 0x5ae8u /* C & T 82C480 */ #define EXT_CONFIG_3 0x5ee8u /* C & T 82C480 */ /* ? 0x62e8u */ /* ? 0x66e8u */ /* ? 0x6ae8u */ /* ? 0x6ee8u */ /* ? 0x72e8u */ /* ? 0x76e8u */ /* ? 0x7ae8u */ /* ? 0x7ee8u */ #define CUR_Y 0x82e8u #define CUR_X 0x86e8u #define DESTY_AXSTP 0x8ae8u /* Write */ #define DESTX_DIASTP 0x8ee8u /* Write */ #define ERR_TERM 0x92e8u #define MAJ_AXIS_PCNT 0x96e8u /* Write */ #define GP_STAT 0x9ae8u /* Read */ #define GE_STAT 0x9ae8u /* Alias */ #define DATARDY 0x0100u #define DATA_READY DATARDY /* Alias */ #define GPBUSY 0x0200u #define CMD 0x9ae8u /* Write */ #define WRTDATA 0x0001u #define PLANAR 0x0002u #define LASTPIX 0x0004u #define LINETYPE 0x0008u #define DRAW 0x0010u #define INC_X 0x0020u #define YMAJAXIS 0x0040u #define INC_Y 0x0080u #define PCDATA 0x0100u #define _16BIT 0x0200u #define CMD_NOP 0x0000u #define CMD_OP_MSK 0xf000u #define BYTSEQ 0x1000u #define CMD_LINE 0x2000u #define CMD_RECT 0x4000u #define CMD_RECTV1 0x6000u #define CMD_RECTV2 0x8000u #define CMD_LINEAF 0xa000u #define CMD_BITBLT 0xc000u #define SHORT_STROKE 0x9ee8u /* Write */ #define SSVDRAW 0x0010u #define VECDIR_000 0x0000u #define VECDIR_045 0x0020u #define VECDIR_090 0x0040u #define VECDIR_135 0x0060u #define VECDIR_180 0x0080u #define VECDIR_225 0x00a0u #define VECDIR_270 0x00c0u #define VECDIR_315 0x00e0u #define BKGD_COLOR 0xa2e8u /* Write */ #define FRGD_COLOR 0xa6e8u /* Write */ #define WRT_MASK 0xaae8u /* Write */ #define RD_MASK 0xaee8u /* Write */ #define COLOR_CMP 0xb2e8u /* Write */ #define BKGD_MIX 0xb6e8u /* Write */ /* 0x001fu See MIX_* definitions below */ #define BSS_BKGDCOL 0x0000u #define BSS_FRGDCOL 0x0020u #define BSS_PCDATA 0x0040u #define BSS_BITBLT 0x0060u #define FRGD_MIX 0xbae8u /* Write */ /* 0x001fu See MIX_* definitions below */ #define FSS_BKGDCOL 0x0000u #define FSS_FRGDCOL 0x0020u #define FSS_PCDATA 0x0040u #define FSS_BITBLT 0x0060u #define MULTIFUNC_CNTL 0xbee8u /* Write */ #define MIN_AXIS_PCNT 0x0000u #define SCISSORS_T 0x1000u #define SCISSORS_L 0x2000u #define SCISSORS_B 0x3000u #define SCISSORS_R 0x4000u #define M32_MEM_CNTL 0x5000u #define HORCFG_4 0x0000u #define HORCFG_5 0x0001u #define HORCFG_8 0x0002u #define HORCFG_10 0x0003u #define VRTCFG_2 0x0000u #define VRTCFG_4 0x0004u #define VRTCFG_6 0x0008u #define VRTCFG_8 0x000cu #define BUFSWP 0x0010u #define PATTERN_L 0x8000u #define PATTERN_H 0x9000u #define PIX_CNTL 0xa000u #define PLANEMODE 0x0004u #define COLCMPOP_F 0x0000u #define COLCMPOP_T 0x0008u #define COLCMPOP_GE 0x0010u #define COLCMPOP_LT 0x0018u #define COLCMPOP_NE 0x0020u #define COLCMPOP_EQ 0x0028u #define COLCMPOP_LE 0x0030u #define COLCMPOP_GT 0x0038u #define MIXSEL_FRGDMIX 0x0000u #define MIXSEL_PATT 0x0040u #define MIXSEL_EXPPC 0x0080u #define MIXSEL_EXPBLT 0x00c0u /* ? 0xc2e8u */ /* ? 0xc6e8u */ /* ? 0xcae8u */ /* ? 0xcee8u */ /* ? 0xd2e8u */ /* ? 0xd6e8u */ /* ? 0xdae8u */ /* ? 0xdee8u */ #define PIX_TRANS 0xe2e8u /* ? 0xe6e8u */ /* ? 0xeae8u */ /* ? 0xeee8u */ /* ? 0xf2e8u */ /* ? 0xf6e8u */ /* ? 0xfae8u */ /* ? 0xfee8u */ /* ATI Mach8 & Mach32 register definitions */ #define OVERSCAN_COLOR_8 0x02eeu /* Write */ /* Mach32 */ #define OVERSCAN_BLUE_24 0x02efu /* Write */ /* Mach32 */ #define OVERSCAN_GREEN_24 0x06eeu /* Write */ /* Mach32 */ #define OVERSCAN_RED_24 0x06efu /* Write */ /* Mach32 */ #define CURSOR_OFFSET_LO 0x0aeeu /* Write */ /* Mach32 */ #define CURSOR_OFFSET_HI 0x0eeeu /* Write */ /* Mach32 */ #define CONFIG_STATUS_1 0x12eeu /* Read */ #define CLK_MODE 0x0001u /* Mach8 */ #define BUS_16 0x0002u /* Mach8 */ #define MC_BUS 0x0004u /* Mach8 */ #define EEPROM_ENA 0x0008u /* Mach8 */ #define DRAM_ENA 0x0010u /* Mach8 */ #define MEM_INSTALLED 0x0060u /* Mach8 */ #define ROM_ENA 0x0080u /* Mach8 */ #define ROM_PAGE_ENA 0x0100u /* Mach8 */ #define ROM_LOCATION 0xfe00u /* Mach8 */ #define _8514_ONLY 0x0001u /* Mach32 */ #define BUS_TYPE 0x000eu /* Mach32 */ #define ISA_16_BIT 0x0000u /* Mach32 */ #define EISA 0x0002u /* Mach32 */ #define MICRO_C_16_BIT 0x0004u /* Mach32 */ #define MICRO_C_8_BIT 0x0006u /* Mach32 */ #define LOCAL_386SX 0x0008u /* Mach32 */ #define LOCAL_386DX 0x000au /* Mach32 */ #define LOCAL_486 0x000cu /* Mach32 */ #define PCI 0x000eu /* Mach32 */ #define MEM_TYPE 0x0070u /* Mach32 */ #define CHIP_DIS 0x0080u /* Mach32 */ #define TST_VCTR_ENA 0x0100u /* Mach32 */ #define DACTYPE 0x0e00u /* Mach32 */ #define MC_ADR_DECODE 0x1000u /* Mach32 */ #define CARD_ID 0xe000u /* Mach32 */ #define HORZ_CURSOR_POSN 0x12eeu /* Write */ /* Mach32 */ #define CONFIG_STATUS_2 0x16eeu /* Read */ #define SHARE_CLOCK 0x0001u /* Mach8 */ #define HIRES_BOOT 0x0002u /* Mach8 */ #define EPROM_16_ENA 0x0004u /* Mach8 */ #define WRITE_PER_BIT 0x0008u /* Mach8 */ #define FLASH_ENA 0x0010u /* Mach8 */ #define SLOW_SEQ_EN 0x0001u /* Mach32 */ #define MEM_ADDR_DIS 0x0002u /* Mach32 */ #define ISA_16_ENA 0x0004u /* Mach32 */ #define KOR_TXT_MODE_ENA 0x0008u /* Mach32 */ #define LOCAL_BUS_SUPPORT 0x0030u /* Mach32 */ #define LOCAL_BUS_CONFIG_2 0x0040u /* Mach32 */ #define LOCAL_BUS_RD_DLY_ENA 0x0080u /* Mach32 */ #define LOCAL_DAC_EN 0x0100u /* Mach32 */ #define LOCAL_RDY_EN 0x0200u /* Mach32 */ #define EEPROM_ADR_SEL 0x0400u /* Mach32 */ #define GE_STRAP_SEL 0x0800u /* Mach32 */ #define VESA_RDY 0x1000u /* Mach32 */ #define Z4GB 0x2000u /* Mach32 */ #define LOC2_MDRAM 0x4000u /* Mach32 */ #define VERT_CURSOR_POSN 0x16eeu /* Write */ /* Mach32 */ #define FIFO_TEST_DATA 0x1aeeu /* Read */ /* Mach32 */ #define CURSOR_COLOR_0 0x1aeeu /* Write */ /* Mach32 */ #define CURSOR_COLOR_1 0x1aefu /* Write */ /* Mach32 */ #define HORZ_CURSOR_OFFSET 0x1eeeu /* Write */ /* Mach32 */ #define VERT_CURSOR_OFFSET 0x1eefu /* Write */ /* Mach32 */ #define PCI_CNTL 0x22eeu /* Mach32-PCI */ #define CRT_PITCH 0x26eeu /* Write */ #define CRT_OFFSET_LO 0x2aeeu /* Write */ #define CRT_OFFSET_HI 0x2eeeu /* Write */ #define LOCAL_CNTL 0x32eeu /* Mach32 */ #define FIFO_OPT 0x36eeu /* Write */ /* Mach8 */ #define MISC_OPTIONS 0x36eeu /* Mach32 */ #define W_STATE_ENA 0x0000u /* Mach32 */ #define HOST_8_ENA 0x0001u /* Mach32 */ #define MEM_SIZE_ALIAS 0x000cu /* Mach32 */ #define MEM_SIZE_512K 0x0000u /* Mach32 */ #define MEM_SIZE_1M 0x0004u /* Mach32 */ #define MEM_SIZE_2M 0x0008u /* Mach32 */ #define MEM_SIZE_4M 0x000cu /* Mach32 */ #define DISABLE_VGA 0x0010u /* Mach32 */ #define _16_BIT_IO 0x0020u /* Mach32 */ #define DISABLE_DAC 0x0040u /* Mach32 */ #define DLY_LATCH_ENA 0x0080u /* Mach32 */ #define TEST_MODE 0x0100u /* Mach32 */ #define BLK_WR_ENA 0x0400u /* Mach32 */ #define _64_DRAW_ENA 0x0800u /* Mach32 */ #define FIFO_TEST_TAG 0x3aeeu /* Read */ /* Mach32 */ #define EXT_CURSOR_COLOR_0 0x3aeeu /* Write */ /* Mach32 */ #define EXT_CURSOR_COLOR_1 0x3eeeu /* Write */ /* Mach32 */ #define MEM_BNDRY 0x42eeu /* Mach32 */ #define MEM_PAGE_BNDRY 0x000fu /* Mach32 */ #define MEM_BNDRY_ENA 0x0010u /* Mach32 */ #define SHADOW_CTL 0x46eeu /* Write */ #define CLOCK_SEL 0x4aeeu /* DISABPASSTHRU 0x0001u See ADVFUNC_CNTL */ #define VFIFO_DEPTH_1 0x0100u /* Mach32 */ #define VFIFO_DEPTH_2 0x0200u /* Mach32 */ #define VFIFO_DEPTH_3 0x0300u /* Mach32 */ #define VFIFO_DEPTH_4 0x0400u /* Mach32 */ #define VFIFO_DEPTH_5 0x0500u /* Mach32 */ #define VFIFO_DEPTH_6 0x0600u /* Mach32 */ #define VFIFO_DEPTH_7 0x0700u /* Mach32 */ #define VFIFO_DEPTH_8 0x0800u /* Mach32 */ #define VFIFO_DEPTH_9 0x0900u /* Mach32 */ #define VFIFO_DEPTH_A 0x0a00u /* Mach32 */ #define VFIFO_DEPTH_B 0x0b00u /* Mach32 */ #define VFIFO_DEPTH_C 0x0c00u /* Mach32 */ #define VFIFO_DEPTH_D 0x0d00u /* Mach32 */ #define VFIFO_DEPTH_E 0x0e00u /* Mach32 */ #define VFIFO_DEPTH_F 0x0f00u /* Mach32 */ #define COMPOSITE_SYNC 0x1000u /* ? 0x4eeeu */ #define ROM_ADDR_1 0x52eeu #define BIOS_BASE_SEGMENT 0x007fu /* Mach32 */ /* ? 0xff80u */ /* Mach32 */ #define ROM_ADDR_2 0x56eeu /* Sick ... */ #define SHADOW_SET 0x5aeeu /* Write */ #define MEM_CFG 0x5eeeu /* Mach32 */ #define MEM_APERT_SEL 0x0003u /* Mach32 */ #define MEM_APERT_PAGE 0x000cu /* Mach32 */ #define MEM_APERT_LOC 0xfff0u /* Mach32 */ #define EXT_GE_STATUS 0x62eeu /* Read */ /* Mach32 */ #define HORZ_OVERSCAN 0x62eeu /* Write */ /* Mach32 */ #define VERT_OVERSCAN 0x66eeu /* Write */ /* Mach32 */ #define MAX_WAITSTATES 0x6aeeu #define GE_OFFSET_LO 0x6eeeu /* Write */ #define BOUNDS_LEFT 0x72eeu /* Read */ #define GE_OFFSET_HI 0x72eeu /* Write */ #define BOUNDS_TOP 0x76eeu /* Read */ #define GE_PITCH 0x76eeu /* Write */ #define BOUNDS_RIGHT 0x7aeeu /* Read */ #define EXT_GE_CONFIG 0x7aeeu /* Write */ /* Mach32 */ #define MONITOR_ALIAS 0x0007u /* Mach32 */ /* MONITOR_? 0x0000u */ /* Mach32 */ #define MONITOR_8507 0x0001u /* Mach32 */ #define MONITOR_8514 0x0002u /* Mach32 */ /* MONITOR_? 0x0003u */ /* Mach32 */ /* MONITOR_? 0x0004u */ /* Mach32 */ #define MONITOR_8503 0x0005u /* Mach32 */ #define MONITOR_8512 0x0006u /* Mach32 */ #define MONITOR_8513 0x0006u /* Mach32 */ #define MONITOR_NONE 0x0007u /* Mach32 */ #define ALIAS_ENA 0x0008u /* Mach32 */ #define PIXEL_WIDTH_4 0x0000u /* Mach32 */ #define PIXEL_WIDTH_8 0x0010u /* Mach32 */ #define PIXEL_WIDTH_16 0x0020u /* Mach32 */ #define PIXEL_WIDTH_24 0x0030u /* Mach32 */ #define RGB16_555 0x0000u /* Mach32 */ #define RGB16_565 0x0040u /* Mach32 */ #define RGB16_655 0x0080u /* Mach32 */ #define RGB16_664 0x00c0u /* Mach32 */ #define MULTIPLEX_PIXELS 0x0100u /* Mach32 */ #define RGB24 0x0000u /* Mach32 */ #define RGBx24 0x0200u /* Mach32 */ #define BGR24 0x0400u /* Mach32 */ #define xBGR24 0x0600u /* Mach32 */ #define DAC_8_BIT_EN 0x4000u /* Mach32 */ #define ORDER_16BPP_565 RGB16_565 /* Mach32 */ #define BOUNDS_BOTTOM 0x7eeeu /* Read */ #define MISC_CNTL 0x7eeeu /* Write */ /* Mach32 */ #define PATT_DATA_INDEX 0x82eeu /* ? 0x86eeu */ /* ? 0x8aeeu */ #define R_EXT_GE_CONFIG 0x8eeeu /* Read */ /* Mach32 */ #define PATT_DATA 0x8eeeu /* Write */ #define R_MISC_CNTL 0x92eeu /* Read */ /* Mach32 */ #define BRES_COUNT 0x96eeu #define EXT_FIFO_STATUS 0x9aeeu /* Read */ #define LINEDRAW_INDEX 0x9aeeu /* Write */ /* ? 0x9eeeu */ #define LINEDRAW_OPT 0xa2eeu #define BOUNDS_RESET 0x0100u #define CLIP_MODE_0 0x0000u /* Clip exception disabled */ #define CLIP_MODE_1 0x0200u /* Line segments */ #define CLIP_MODE_2 0x0400u /* Polygon boundary lines */ #define CLIP_MODE_3 0x0600u /* Patterned lines */ #define DEST_X_START 0xa6eeu /* Write */ #define DEST_X_END 0xaaeeu /* Write */ #define DEST_Y_END 0xaeeeu /* Write */ #define R_H_TOTAL_DISP 0xb2eeu /* Read */ /* Mach32 */ #define SRC_X_STRT 0xb2eeu /* Write */ #define R_H_SYNC_STRT 0xb6eeu /* Read */ /* Mach32 */ #define ALU_BG_FN 0xb6eeu /* Write */ #define R_H_SYNC_WID 0xbaeeu /* Read */ /* Mach32 */ #define ALU_FG_FN 0xbaeeu /* Write */ #define SRC_X_END 0xbeeeu /* Write */ #define R_V_TOTAL 0xc2eeu /* Read */ #define SRC_Y_DIR 0xc2eeu /* Write */ #define R_V_DISP 0xc6eeu /* Read */ /* Mach32 */ #define EXT_SHORT_STROKE 0xc6eeu /* Write */ #define R_V_SYNC_STRT 0xcaeeu /* Read */ /* Mach32 */ #define SCAN_X 0xcaeeu /* Write */ #define VERT_LINE_CNTR 0xceeeu /* Read */ /* Mach32 */ #define DP_CONFIG 0xceeeu /* Write */ #define READ_WRITE 0x0001u #define DATA_WIDTH 0x0200u #define DATA_ORDER 0x1000u #define FG_COLOR_SRC_FG 0x2000u #define FG_COLOR_SRC_BLIT 0x6000u #define R_V_SYNC_WID 0xd2eeu /* Read */ #define PATT_LENGTH 0xd2eeu /* Write */ #define PATT_INDEX 0xd6eeu /* Write */ #define READ_SRC_X 0xdaeeu /* Read */ /* Mach32 */ #define EXT_SCISSOR_L 0xdaeeu /* Write */ #define READ_SRC_Y 0xdeeeu /* Read */ /* Mach32 */ #define EXT_SCISSOR_T 0xdeeeu /* Write */ #define EXT_SCISSOR_R 0xe2eeu /* Write */ #define EXT_SCISSOR_B 0xe6eeu /* Write */ /* ? 0xeaeeu */ #define DEST_COMP_FN 0xeeeeu /* Write */ #define DEST_COLOR_CMP_MASK 0xf2eeu /* Write */ /* Mach32 */ /* ? 0xf6eeu */ #define CHIP_ID 0xfaeeu /* Read */ /* Mach32 */ #define CHIP_CODE_0 0x001fu /* Mach32 */ #define CHIP_CODE_1 0x03e0u /* Mach32 */ #define CHIP_CLASS 0x0c00u /* Mach32 */ #define CHIP_REV 0xf000u /* Mach32 */ #define LINEDRAW 0xfeeeu /* Write */ /* ATI Mach64 register definitions */ #define CRTC_H_TOTAL_DISP IOPortTag(0x00u, 0x00u) # define CRTC_H_TOTAL 0x000001fful /* ? 0x0000fe00ul */ # define CRTC_H_DISP 0x01ff0000ul /* ? 0xfe000000ul */ #define CRTC_H_SYNC_STRT_WID IOPortTag(0x01u, 0x01u) # define CRTC_H_SYNC_STRT 0x000000fful # define CRTC_H_SYNC_DLY 0x00000700ul /* ? 0x00000800ul */ # define CRTC_H_SYNC_STRT_HI 0x00001000ul /* ? 0x0000e000ul */ # define CRTC_H_SYNC_WID 0x001f0000ul # define CRTC_H_SYNC_POL 0x00200000ul /* ? 0xffc00000ul */ #define CRTC_V_TOTAL_DISP IOPortTag(0x02u, 0x02u) # define CRTC_V_TOTAL 0x000007fful /* ? 0x0000f800ul */ # define CRTC_V_DISP 0x07ff0000ul /* ? 0xf8000000ul */ #define CRTC_V_SYNC_STRT_WID IOPortTag(0x03u, 0x03u) # define CRTC_V_SYNC_STRT 0x000007fful /* ? 0x0000f800ul */ # define CRTC_V_SYNC_WID 0x001f0000ul # define CRTC_V_SYNC_POL 0x00200000ul /* ? 0xffc00000ul */ #define CRTC_VLINE_CRNT_VLINE IOPortTag(0x04u, 0x04u) #define CRTC_VLINE 0x000007fful /* ? 0x0000f800ul */ #define CRTC_CRNT_VLINE 0x07ff0000ul /* ? 0xf8000000ul */ #define CRTC_OFF_PITCH IOPortTag(0x05u, 0x05u) # define CRTC_OFFSET 0x000ffffful # define CRTC_OFFSET_VGA 0x0003fffful # define CRTC_OFFSET_LOCK 0x00100000ul /* XC/XL */ /* ? 0x00200000ul */ # define CRTC_PITCH 0xffc00000ul #define CRTC_INT_CNTL IOPortTag(0x06u, 0x06u) # define CRTC_VBLANK 0x00000001ul # define CRTC_VBLANK_INT_EN 0x00000002ul # define CRTC_VBLANK_INT 0x00000004ul # define CRTC_VLINE_INT_EN 0x00000008ul # define CRTC_VLINE_INT 0x00000010ul # define CRTC_VLINE_SYNC 0x00000020ul # define CRTC_FRAME 0x00000040ul # define CRTC_SNAPSHOT_INT_EN 0x00000080ul /* GTPro */ # define CRTC_SNAPSHOT_INT 0x00000100ul /* GTPro */ # define CRTC_I2C_INT_EN 0x00000200ul /* GTPro */ # define CRTC_I2C_INT 0x00000400ul /* GTPro */ # define CRTC2_VBLANK 0x00000800ul /* LTPro */ # define CRTC2_VBLANK_INT_EN 0x00001000ul /* LTPro */ # define CRTC2_VBLANK_INT 0x00002000ul /* LTPro */ # define CRTC2_VLINE_INT_EN 0x00004000ul /* LTPro */ # define CRTC2_VLINE_INT 0x00008000ul /* LTPro */ # define CRTC_CAPBUF0_INT_EN 0x00010000ul /* VT/GT */ # define CRTC_CAPBUF0_INT 0x00020000ul /* VT/GT */ # define CRTC_CAPBUF1_INT_EN 0x00040000ul /* VT/GT */ # define CRTC_CAPBUF1_INT 0x00080000ul /* VT/GT */ # define CRTC_OVERLAY_EOF_INT_EN 0x00100000ul /* VT/GT */ # define CRTC_OVERLAY_EOF_INT 0x00200000ul /* VT/GT */ # define CRTC_ONESHOT_CAP_INT_EN 0x00400000ul /* VT/GT */ # define CRTC_ONESHOT_CAP_INT 0x00800000ul /* VT/GT */ # define CRTC_BUSMASTER_EOL_INT_EN 0x01000000ul /* VTB/GTB/LT */ # define CRTC_BUSMASTER_EOL_INT 0x02000000ul /* VTB/GTB/LT */ # define CRTC_GP_INT_EN 0x04000000ul /* VTB/GTB/LT */ # define CRTC_GP_INT 0x08000000ul /* VTB/GTB/LT */ # define CRTC2_VLINE_SYNC 0x10000000ul /* LTPro */ # define CRTC_SNAPSHOT2_INT_EN 0x20000000ul /* LTPro */ # define CRTC_SNAPSHOT2_INT 0x40000000ul /* LTPro */ # define CRTC_VBLANK_BIT2_INT 0x80000000ul /* GTPro */ # define CRTC_INT_ENS /* *** UPDATE ME *** */ \ ( \ CRTC_VBLANK_INT_EN | \ CRTC_VLINE_INT_EN | \ CRTC_SNAPSHOT_INT_EN | \ CRTC_I2C_INT_EN | \ CRTC2_VBLANK_INT_EN | \ CRTC2_VLINE_INT_EN | \ CRTC_CAPBUF0_INT_EN | \ CRTC_CAPBUF1_INT_EN | \ CRTC_OVERLAY_EOF_INT_EN | \ CRTC_ONESHOT_CAP_INT_EN | \ CRTC_BUSMASTER_EOL_INT_EN | \ CRTC_GP_INT_EN | \ CRTC_SNAPSHOT2_INT_EN | \ 0 \ ) # define CRTC_INT_ACKS /* *** UPDATE ME *** */ \ ( \ CRTC_VBLANK_INT | \ CRTC_VLINE_INT | \ CRTC_SNAPSHOT_INT | \ CRTC_I2C_INT | \ CRTC2_VBLANK_INT | \ CRTC2_VLINE_INT | \ CRTC_CAPBUF0_INT | \ CRTC_CAPBUF1_INT | \ CRTC_OVERLAY_EOF_INT | \ CRTC_ONESHOT_CAP_INT | \ CRTC_BUSMASTER_EOL_INT | \ CRTC_GP_INT | \ CRTC_SNAPSHOT2_INT | \ CRTC_VBLANK_BIT2_INT | \ 0 \ ) #define CRTC_GEN_CNTL IOPortTag(0x07u, 0x07u) # define CRTC_DBL_SCAN_EN 0x00000001ul # define CRTC_INTERLACE_EN 0x00000002ul # define CRTC_HSYNC_DIS 0x00000004ul # define CRTC_VSYNC_DIS 0x00000008ul # define CRTC_CSYNC_EN 0x00000010ul # define CRTC_PIX_BY_2_EN 0x00000020ul # define CRTC2_DBL_SCAN_EN 0x00000020ul /* LTPro */ # define CRTC_DISPLAY_DIS 0x00000040ul # define CRTC_VGA_XOVERSCAN 0x00000080ul # define CRTC_PIX_WIDTH 0x00000700ul # define CRTC_BYTE_PIX_ORDER 0x00000800ul # define CRTC_VSYNC_INT_EN 0x00001000ul /* XC/XL */ # define CRTC_VSYNC_INT 0x00002000ul /* XC/XL */ # define CRTC_FIFO_OVERFILL 0x0000c000ul /* VT/GT */ # define CRTC2_VSYNC_INT_EN 0x00004000ul /* XC/XL */ # define CRTC2_VSYNC_INT 0x00008000ul /* XC/XL */ # define CRTC_FIFO_LWM 0x000f0000ul # define CRTC_HVSYNC_IO_DRIVE 0x00010000ul /* XC/XL */ # define CRTC2_PIX_WIDTH 0x000e0000ul /* LTPro */ # define CRTC_VGA_128KAP_PAGING 0x00100000ul /* VT/GT */ # define CRTC_DISPREQ_ONLY 0x00200000ul /* VT/GT */ # define CRTC_VFC_SYNC_TRISTATE 0x00200000ul /* VTB/GTB/LT */ # define CRTC2_EN 0x00200000ul /* LTPro */ # define CRTC_LOCK_REGS 0x00400000ul /* VT/GT */ # define CRTC_SYNC_TRISTATE 0x00800000ul /* VT/GT */ # define CRTC_EXT_DISP_EN 0x01000000ul # define CRTC_EN 0x02000000ul # define CRTC_DISP_REQ_EN 0x04000000ul # define CRTC_VGA_LINEAR 0x08000000ul # define CRTC_VSYNC_FALL_EDGE 0x10000000ul # define CRTC_VGA_TEXT_132 0x20000000ul # define CRTC_CNT_EN 0x40000000ul # define CRTC_CUR_B_TEST 0x80000000ul # define CRTC_INT_ENS_X /* *** UPDATE ME *** */ \ ( \ CRTC_VSYNC_INT_EN | \ CRTC2_VSYNC_INT_EN | \ 0 \ ) # define CRTC_INT_ACKS_X /* *** UPDATE ME *** */ \ ( \ CRTC_VSYNC_INT | \ CRTC2_VSYNC_INT | \ 0 \ ) #define DSP_CONFIG BlockIOTag(0x08u) /* VTB/GTB/LT */ # define DSP_XCLKS_PER_QW 0x00003ffful /* ? 0x00004000ul */ # define DSP_FLUSH_WB 0x00008000ul # define DSP_LOOP_LATENCY 0x000f0000ul # define DSP_PRECISION 0x00700000ul /* ? 0xff800000ul */ #define DSP_ON_OFF BlockIOTag(0x09u) /* VTB/GTB/LT */ # define DSP_OFF 0x000007fful /* ? 0x0000f800ul */ # define DSP_ON 0x07ff0000ul /* ? 0xf8000000ul */ #define TIMER_CONFIG BlockIOTag(0x0au) /* VTB/GTB/LT */ #define MEM_BUF_CNTL BlockIOTag(0x0bu) /* VTB/GTB/LT */ #define SHARED_CNTL BlockIOTag(0x0cu) /* VTB/GTB/LT */ #define SHARED_MEM_CONFIG BlockIOTag(0x0du) /* VTB/GTB/LT */ #define MEM_ADDR_CONFIG BlockIOTag(0x0du) /* GTPro */ #define SHARED_CNTL_CTD BlockIOTag(0x0eu) /* CTD */ /* ? 0x00fffffful */ #define CTD_FIFO5 0x01000000ul /* ? 0xfe000000ul */ #define CRT_TRAP BlockIOTag(0x0eu) /* VTB/GTB/LT */ #define DSTN_CONTROL BlockIOTag(0x0fu) /* LT */ #define I2C_CNTL_0 BlockIOTag(0x0fu) /* GTPro */ #define OVR_CLR IOPortTag(0x08u, 0x10u) # define OVR_CLR_8 0x000000fful # define OVR_CLR_B 0x0000ff00ul # define OVR_CLR_G 0x00ff0000ul # define OVR_CLR_R 0xff000000ul #define OVR_WID_LEFT_RIGHT IOPortTag(0x09u, 0x11u) # define OVR_WID_LEFT 0x0000003ful /* 0x0f on VidMapBase + (port))) #define VIDInW(port) *((volatile CARD16 *)(pVia->VidMapBase + (port))) #define VIDInD(port) *((volatile CARD32 *)(pVia->VidMapBase + (port))) #define VIDOutB(port, data) *((volatile CARD8 *)(pVia->VidMapBase + (port))) = (data) #define VIDOutW(port, data) *((volatile CARD16 *)(pVia->VidMapBase + (port))) = (data) #define VIDOutD(port, data) *((volatile CARD32 *)(pVia->VidMapBase + (port))) = (data) #define MPGOutD(port, data) *((volatile CARD32 *)(lpMPEGMMIO +(port))) = (data) #define MPGInD(port) *((volatile CARD32 *)(lpMPEGMMIO +(port))) #endif /* * Macros for GE MMIO */ #define GEInW(port) *((volatile CARD16 *)(lpGEMMIO + (port))) #define GEInD(port) *((volatile CARD32 *)(lpGEMMIO + (port))) #define GEOutW(port, data) *((volatile CARD16 *)(lpGEMMIO + (port))) = (data) #define GEOutD(port, data) *((volatile CARD32 *)(lpGEMMIO + (port))) = (data) /* * MPEG 1/2 Slice Engine (at 0xC00 relative to base) */ #define MPG_CONTROL 0x00 #define MPG_CONTROL_STRUCT 0x03 #define MPG_CONTROL_STRUCT_TOP 0x01 #define MPG_CONTROL_STRUCT_BOTTOM 0x02 #define MPG_CONTROL_STRUCT_FRAME 0x03 /* Use TOP if interlaced */ #define MPG_CONTROL_TYPE 0x3C #define MPG_CONTROL_TYPE_I (0x01 << 2) #define MPG_CONTROL_TYPE_B (0x02 << 2) #define MPG_CONTROL_TYPE_P (0x03 << 3) #define MPG_CONTROL_ALTSCAN 0x40 #define MPG_BLOCK 0x08 /* Unsure */ #define MPG_COMMAND 0x0C #define MPG_DATA1 0x10 #define MPG_DATA2 0x14 #define MPG_DATA3 0x18 #define MPG_DATA4 0x1C #define MPG_YPHYSICAL(x) (0x20 + 12*(x)) #define MPG_CbPHYSICAL(x) (0x24 + 12*(x)) #define MPG_CrPHYSICAL(x) (0x28 + 12*(x)) #define MPG_PITCH 0x50 #define MPG_STATUS 0x54 #define MPG_MATRIX_IDX 0x5C #define MPG_MATRIX_IDX_INTRA 0x00 #define MPG_MATRIX_IDX_NON 0x01 #define MPG_MATRIX_DATA 0x60 #define MPG_SLICE_CTRL_1 0x90 #define MPG_SLICE_MBAMAX 0x2FFF #define MPG_SLICE_PREDICTIVE_DCT 0x4000 #define MPG_SLICE_TOP_FIRST 0x8000 #define MPG_SLICE_MACROBLOCK_WIDTH(x) ((x)<<18) /* in 64's */ #define MPG_SLICE_CTRL_2 0x94 #define MPG_SLICE_CONCEAL_MVEC 0x0000001 #define MPG_SLICE_QSCALE_TYPE 0x0000002 #define MPG_SLICE_DCPRECISION 0x000000C #define MPG_SLICE_MACROBQUOT 0x0FFFFF0 #define MPG_SLICE_INTRAVLC 0x1000000 #define MPG_SLICE_CTRL_3 0x98 #define MPG_SLICE_FHMVR 0x0000003 #define MPG_SLICE_FVMVR 0x000000C #define MPG_SLICE_BHMVR 0x0000030 #define MPG_SLICE_BVMVR 0x00000C0 #define MPG_SLICE_SECOND_FIELD 0x0100000 #define MPG_SLICE_RESET 0x0400000 #define MPG_SLICE_LENGTH 0x9C #define MPG_SLICE_DATA 0xA0 #endif /* _VIA_H_ */ xine-lib-1.2/contrib/vidix/drivers/pm3_regs.h0000644000175000017500000015055214647725152017025 0ustar meme/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/glint/pm3_regs.h,v 1.9 2001/11/20 00:09:15 alanh Exp $ */ /* * glint register file * * Copyright by Sven Luther * Authors: Sven Luther, * Thomas Witzel, * * this work is sponsored by Appian Graphics. * */ #ifndef _PM3_REG_H_ #define _PM3_REG_H_ #define PM3FIFOSize 120 #define PM3Tag(r) ((r>>3)&0x7ff) #define PM3OutputFIFO 0x2000 /********************************************** * GLINT Permedia3 Control Status registers * ***********************************************/ /* Control Status Registers */ #define PM3ResetStatus 0x0000 #define PM3IntEnable 0x0008 #define PM3IntFlags 0x0010 #define PM3InFIFOSpace 0x0018 #define PM3OutFIFOWords 0x0020 #define PM3DMAAddress 0x0028 #define PM3DMACount 0x0030 #define PM3ErrorFlags 0x0038 #define PM3VClkCtl 0x0040 #define PM3TestRegister 0x0048 #define PM3Aperture0 0x0050 #define PM3Aperture1 0x0058 #define PM3DMAControl 0x0060 #define PM3FIFODis 0x0068 #define PM3ChipConfig 0x0070 #define PM3AGPControl 0x0078 #define PM3GPOutDMAAddress 0x0080 #define PM3PCIFeedbackCount 0x0088 #define PM3PCIAbortStatus 0x0090 #define PM3PCIAbortAddress 0x0098 #define PM3PCIPLLStatus 0x00f0 #define PM3HostTextureAddress 0x0100 #define PM3TextureDownloadControl 0x0108 #define PM3TextureOperation 0x0110 #define PM3LogicalTexturePage 0x0118 #define PM3TexDMAAddress 0x0120 #define PM3TexFIFOSpace 0x0128 /********************************************** * GLINT Permedia3 Region 0 Bypass Controls * ***********************************************/ #define PM3ByAperture1Mode 0x0300 #define PM3ByApertureMode_BYTESWAP_ABCD (0<<0) #define PM3ByApertureMode_BYTESWAP_BADC (1<<0) #define PM3ByApertureMode_BYTESWAP_CDAB (2<<0) #define PM3ByApertureMode_BYTESWAP_DCBA (3<<0) #define PM3ByApertureMode_PATCH_DISABLE (0<<2) #define PM3ByApertureMode_PATCH_ENABLE (1<<2) #define PM3ByApertureMode_FORMAT_RAW (0<<3) #define PM3ByApertureMode_FORMAT_YUYV (1<<3) #define PM3ByApertureMode_FORMAT_UYVY (2<<3) #define PM3ByApertureMode_PIXELSIZE_8BIT (0<<5) #define PM3ByApertureMode_PIXELSIZE_16BIT (1<<5) #define PM3ByApertureMode_PIXELSIZE_32BIT (2<<5) #define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0<<7) #define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1<<7) #define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2<<7) #define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3<<7) #define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off)&7f)<<9) #define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off)&7f)<<16) #define PM3ByApertureMode_FRAMEBUFFER (0<<21) #define PM3ByApertureMode_LOCALBUFFER (1<<21) #define PM3ByApertureMode_DOUBLE_WRITE_OFF (0<<22) #define PM3ByApertureMode_DOUBLE_WRITE_1MB (1<<22) #define PM3ByApertureMode_DOUBLE_WRITE_2MB (2<<22) #define PM3ByApertureMode_DOUBLE_WRITE_4MB (3<<22) #define PM3ByApertureMode_DOUBLE_WRITE_8MB (4<<22) #define PM3ByApertureMode_DOUBLE_WRITE_16MB (5<<22) #define PM3ByApertureMode_DOUBLE_WRITE_32MB (6<<22) #define PM3Aperture1Stride 0x0308 #define PM3Aperture1YStart 0x0310 #define PM3Aperture1UStart 0x0318 #define PM3Aperture1VStart 0x0320 #define PM3ByAperture2Mode 0x0328 #define PM3Aperture2Stride 0x0330 #define PM3Aperture2YStart 0x0338 #define PM3Aperture2UStart 0x0340 #define PM3Aperture2VStart 0x0348 #define PM3ByDMAReadCommandBase 0x0378 #define PM3ByDMAReadCommandCount 0x0380 #define PM3ByDMAReadMode 0x0350 #define PM3ByDMAReadMode_ByteSwap_NONE (0<<0) #define PM3ByDMAReadMode_ByteSwap_BYTE (1<<0) #define PM3ByDMAReadMode_ByteSwap_HWORD (2<<0) #define PM3ByDMAReadMode_ByteSwap_FULL (3<<0) #define PM3ByDMAReadMode_PatchEnable (1<<2) #define PM3ByDMAReadMode_Format_RAW (0<<3) #define PM3ByDMAReadMode_Format_YUYV (1<<3) #define PM3ByDMAReadMode_Format_UYVY (2<<3) #define PM3ByDMAReadMode_PixelSize(s) (((s>>4)&3)<<5) #define PM3ByDMAReadMode_EffectiveStride(s) ((s&3)<<7) #define PM3ByDMAReadMode_PatchOffsetX(x) ((x&0x3f)<<9) #define PM3ByDMAReadMode_PatchOffsetY(y) ((y&0x3f)<<16) #define PM3ByDMAReadMode_Buffer_FB (0<<21) #define PM3ByDMAReadMode_Buffer_LB (1<<21) #define PM3ByDMAReadMode_Active (1<<22) #define PM3ByDMAReadMode_MemType_PCI (0<<23) #define PM3ByDMAReadMode_MemType_AGP (1<<23) #define PM3ByDMAReadMode_Burst(b) ((b&7)<<24) #define PM3ByDMAReadMode_Align (1<<27) #define PM3ByDMAReadStride 0x0358 #define PM3ByDMAReadUStart 0x0368 #define PM3ByDMAReadVStart 0x0370 #define PM3ByDMAReadYStart 0x0360 /********************************************** * GLINT Permedia3 Memory Control (0x1000) * ***********************************************/ #define PM3MemCounter 0x1000 #define PM3MemBypassWriteMask 0x1008 #define PM3MemScratch 0x1010 #define PM3LocalMemCaps 0x1018 #define PM3LocalMemCaps_NoWriteMask (1<<28) #define PM3LocalMemTimings 0x1020 #define PM3LocalMemControl 0x1028 #define PM3LocalMemRefresh 0x1030 #define PM3LocalMemPowerDown 0x1038 #define PM3RemoteMemControl 0x1100 /********************************************** * GLINT Permedia3 Video Control (0x3000) * ***********************************************/ #define PM3ScreenBase 0x3000 #define PM3ScreenStride 0x3008 #define PM3HTotal 0x3010 #define PM3HgEnd 0x3018 #define PM3HbEnd 0x3020 #define PM3HsStart 0x3028 #define PM3HsEnd 0x3030 #define PM3VTotal 0x3038 #define PM3VbEnd 0x3040 #define PM3VsStart 0x3048 #define PM3VsEnd 0x3050 #define PM3VideoControl 0x3058 #define PM3VideoControl_DISABLE (0<<0) #define PM3VideoControl_ENABLE (1<<0) #define PM3VideoControl_BLANK_ACTIVE_HIGH (0<<1) #define PM3VideoControl_BLANK_ACTIVE_LOW (1<<1) #define PM3VideoControl_LINE_DOUBLE_OFF (0<<2) #define PM3VideoControl_LINE_DOUBLE_ON (1<<2) #define PM3VideoControl_HSYNC_FORCE_HIGH (0<<3) #define PM3VideoControl_HSYNC_ACTIVE_HIGH (1<<3) #define PM3VideoControl_HSYNC_FORCE_LOW (2<<3) #define PM3VideoControl_HSYNC_ACTIVE_LOW (3<<3) #define PM3VideoControl_VSYNC_FORCE_HIGH (0<<5) #define PM3VideoControl_VSYNC_ACTIVE_HIGH (1<<5) #define PM3VideoControl_VSYNC_FORCE_LOW (2<<5) #define PM3VideoControl_VSYNC_ACTIVE_LOW (3<<5) #define PM3VideoControl_BYTE_DOUBLE_OFF (0<<7) #define PM3VideoControl_BYTE_DOUBLE_ON (1<<7) #define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0<<9) #define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1<<9) #define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2<<9) #define PM3VideoControl_STEREO_DISABLE (0<<11) #define PM3VideoControl_STEREO_ENABLE (1<<11) #define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0<<12) #define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1<<12) #define PM3VideoControl_VIDEO_EXT_LOW (0<<14) #define PM3VideoControl_VIDEO_EXT_HIGH (1<<14) #define PM3VideoControl_SYNC_MODE_INDEPENDENT (0<<16) #define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1<<16) #define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2<<16) #define PM3VideoControl_PATCH_DISABLE (0<<18) #define PM3VideoControl_PATCH_ENABLE (1<<18) #define PM3VideoControl_PIXELSIZE_8BIT (0<<19) #define PM3VideoControl_PIXELSIZE_16BIT (1<<19) #define PM3VideoControl_PIXELSIZE_32BIT (2<<19) #define PM3VideoControl_DISPLAY_DISABLE (0<<21) #define PM3VideoControl_DISPLAY_ENABLE (1<<21) #define PM3VideoControl_PATCH_OFFSET_X(off) (((off)&0x3f)<<22) #define PM3VideoControl_PATCH_OFFSET_Y(off) (((off)&0x3f)<<28) #define PM3InterruptLine 0x3060 #define PM3DisplayData 0x3068 #define PM3VerticalLineCount 0x3070 #define PM3FifoControl 0x3078 #define PM3ScreenBaseRight 0x3080 #define PM3MiscControl 0x3088 #define PM3VideoOverlayUpdate 0x3100 #define PM3VideoOverlayUpdate_DISABLE (0<<0) #define PM3VideoOverlayUpdate_ENABLE (1<<0) #define PM3VideoOverlayMode 0x3108 #define PM3VideoOverlayMode_DISABLE (0<<0) #define PM3VideoOverlayMode_ENABLE (1<<0) #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0<<1) #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1<<1) #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2<<1) #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0<<4) #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1<<4) #define PM3VideoOverlayMode_PIXELSIZE_8BIT (0<<5) #define PM3VideoOverlayMode_PIXELSIZE_16BIT (1<<5) #define PM3VideoOverlayMode_PIXELSIZE_32BIT (2<<5) #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5)) #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5)) #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5)) #define PM3VideoOverlayMode_COLORFORMAT_RGB565 ((3<<7)|(1<<12)|(1<<5)) #define PM3VideoOverlayMode_COLORFORMAT_RGB332 ((4<<7)|(1<<12)|(0<<5)) #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5)) #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5)) #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5)) #define PM3VideoOverlayMode_COLORFORMAT_BGR565 ((3<<7)|(1<<5)) #define PM3VideoOverlayMode_COLORFORMAT_BGR332 ((4<<7)|(0<<5)) #define PM3VideoOverlayMode_COLORFORMAT_CI8 ((5<<7)|(1<<12)|(0<<5)) #define PM3VideoOverlayMode_COLORFORMAT_VUY444 ((2<<10)|(1<<12)|(2<<5)) #define PM3VideoOverlayMode_COLORFORMAT_YUV444 ((2<<10)|(2<<5)) #define PM3VideoOverlayMode_COLORFORMAT_VUY422 ((1<<10)|(1<<12)|(1<<5)) #define PM3VideoOverlayMode_COLORFORMAT_YUV422 ((1<<10)|(1<<5)) #define PM3VideoOverlayMode_COLORORDER_BGR (0<<12) #define PM3VideoOverlayMode_COLORORDER_RGB (1<<12) #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0<<13) #define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1<<13) #define PM3VideoOverlayMode_FILTER_MASK (3<<14) #define PM3VideoOverlayMode_FILTER_OFF (0<<14) #define PM3VideoOverlayMode_FILTER_FULL (1<<14) #define PM3VideoOverlayMode_FILTER_PARTIAL (2<<14) #define PM3VideoOverlayMode_DEINTERLACE_OFF (0<<16) #define PM3VideoOverlayMode_DEINTERLACE_BOB (1<<16) #define PM3VideoOverlayMode_PATCHMODE_OFF (0<<18) #define PM3VideoOverlayMode_PATCHMODE_ON (1<<18) #define PM3VideoOverlayMode_FLIP_VIDEO (0<<20) #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1<<20) #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2<<20) #define PM3VideoOverlayMode_MIRROR_MASK (3<<23) #define PM3VideoOverlayMode_MIRRORX_OFF (0<<23) #define PM3VideoOverlayMode_MIRRORX_ON (1<<23) #define PM3VideoOverlayMode_MIRRORY_OFF (0<<24) #define PM3VideoOverlayMode_MIRRORY_ON (1<<24) #define PM3VideoOverlayFifoControl 0x3110 #define PM3VideoOverlayIndex 0x3118 #define PM3VideoOverlayBase 0x3120 #define PM3VideoOverlayBase0 0x3120 #define PM3VideoOverlayBase1 0x3128 #define PM3VideoOverlayBase2 0x3130 #define PM3VideoOverlayStride 0x3138 #define PM3VideoOverlayStride_STRIDE(s) (((s)&0xfff)<<0) #define PM3VideoOverlayWidth 0x3140 #define PM3VideoOverlayWidth_WIDTH(w) (((w)&0xfff)<<0) #define PM3VideoOverlayHeight 0x3148 #define PM3VideoOverlayHeight_HEIGHT(h) (((h)&0xfff)<<0) #define PM3VideoOverlayOrigin 0x3150 #define PM3VideoOverlayOrigin_XORIGIN(x) (((x)&0xfff)<<0) #define PM3VideoOverlayOrigin_YORIGIN(y) (((y)&0xfff)<<16) #define PM3VideoOverlayShrinkXDelta 0x3158 #define PM3VideoOverlayShrinkXDelta_NONE (1<<16) #define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \ ((((s)<<16)/(d))&0x0ffffff0) #define PM3VideoOverlayZoomXDelta 0x3160 #define PM3VideoOverlayZoomXDelta_NONE (1<<16) #define PM3VideoOverlayZoomXDelta_DELTA(s,d) \ ((((s)<<16)/(d))&0x0001fff0) #define PM3VideoOverlayYDelta 0x3168 #define PM3VideoOverlayYDelta_NONE (1<<16) #define PM3VideoOverlayYDelta_DELTA(s,d) \ ((((s)<<16)/(d))&0x0ffffff0) #define PM3VideoOverlayFieldOffset 0x3170 #define PM3VideoOverlayStatus 0x3178 /********************************************** * GLINT Permedia3 RAMDAC Registers (0x4000) * ***********************************************/ /* Direct Registers */ #define PM3RD_PaletteWriteAddress 0x4000 #define PM3RD_PaletteData 0x4008 #define PM3RD_PixelMask 0x4010 #define PM3RD_PaletteReadAddress 0x4018 #define PM3RD_IndexLow 0x4020 #define PM3RD_IndexHigh 0x4028 #define PM3RD_IndexedData 0x4030 #define PM3RD_IndexControl 0x4038 #define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1<<0) #define PM3RD_IndexControl_AUTOINCREMENT_DISABLE (0<<0) /* Indirect Registers */ #define PM3RD_MiscControl 0x000 #define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE (0<<0) #define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1<<0) #define PM3RD_MiscControl_PIXELDOUBLE_DISABLE (0<<1) #define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1<<1) #define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE (0<<2) #define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1<<2) #define PM3RD_MiscControl_DIRECTCOLOR_DISABLE (0<<3) #define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1<<3) #define PM3RD_MiscControl_OVERLAY_DISABLE (0<<4) #define PM3RD_MiscControl_OVERLAY_ENABLE (1<<4) #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE (0<<5) #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1<<5) #define PM3RD_MiscControl_VSB_OUTPUT_DISABLE (0<<6) #define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1<<6) #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE (0<<7) #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1<<7) #define PM3RD_SyncControl 0x001 #define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0<<0) #define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1<<0) #define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3<<0) #define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4<<0) #define PM3RD_SyncControl_HSYNC_TRI_STATE (2<<0) #define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0<<3) #define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1<<3) #define PM3RD_SyncControl_VSYNC_TRI_STATE (2<<3) #define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3<<3) #define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4<<3) #define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0<<6) #define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1<<6) #define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0<<7) #define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1<<7) #define PM3RD_DACControl 0x002 #define PM3RD_DACControl_DAC_POWER_ON (0<<0) #define PM3RD_DACControl_DAC_POWER_OFF (1<<0) #define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE (0<<3) #define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1<<3) #define PM3RD_DACControl_BLANK_RED_DAC_DISABLE (0<<4) #define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1<<4) #define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE (0<<5) #define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1<<5) #define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE (0<<6) #define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1<<6) #define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE (0<<7) #define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1<<7) #define PM3RD_PixelSize 0x003 #define PM3RD_PixelSize_24_BIT_PIXELS (4<<0) #define PM3RD_PixelSize_32_BIT_PIXELS (2<<0) #define PM3RD_PixelSize_16_BIT_PIXELS (1<<0) #define PM3RD_PixelSize_8_BIT_PIXELS (0<<0) #define PM3RD_ColorFormat 0x004 #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1<<6) #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE (0<<6) #define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1<<5) #define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0<<5) #define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f<<0) #define PM3RD_ColorFormat_8888_COLOR (0<<0) #define PM3RD_ColorFormat_5551_FRONT_COLOR (1<<0) #define PM3RD_ColorFormat_4444_COLOR (2<<0) #define PM3RD_ColorFormat_332_FRONT_COLOR (5<<0) #define PM3RD_ColorFormat_332_BACK_COLOR (6<<0) #define PM3RD_ColorFormat_2321_FRONT_COLOR (9<<0) #define PM3RD_ColorFormat_2321_BACK_COLOR (10<<0) #define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11<<0) #define PM3RD_ColorFormat_232_BACKOFF_COLOR (12<<0) #define PM3RD_ColorFormat_5551_BACK_COLOR (13<<0) #define PM3RD_ColorFormat_CI8_COLOR (14<<0) #define PM3RD_ColorFormat_565_FRONT_COLOR (16<<0) #define PM3RD_ColorFormat_565_BACK_COLOR (17<<0) #define PM3RD_CursorMode 0x005 #define PM3RD_CursorMode_CURSOR_DISABLE (0<<0) #define PM3RD_CursorMode_CURSOR_ENABLE (1<<0) #define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0<<2) #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1<<2) #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2<<2) #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3<<2) #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4<<2) #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5<<2) #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6<<2) #define PM3RD_CursorMode_TYPE_MS (0<<4) #define PM3RD_CursorMode_TYPE_X (1<<4) #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE (0<<6) #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1<<6) #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2<<6) #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3<<6) #define PM3RD_CursorControl 0x006 #define PM3RD_CursorControl_DOUBLE_X_DISABLED (0<<0) #define PM3RD_CursorControl_DOUBLE_X_ENABLED (1<<0) #define PM3RD_CursorControl_DOUBLE_Y_DISABLED (0<<1) #define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1<<1) #define PM3RD_CursorControl_READBACK_POS_DISABLED (0<<2) #define PM3RD_CursorControl_READBACK_POS_ENABLED (1<<2) #define PM3RD_CursorXLow 0x007 #define PM3RD_CursorXHigh 0x008 #define PM3RD_CursorYLow 0x009 #define PM3RD_CursorYHigh 0x00a #define PM3RD_CursorHotSpotX 0x00b #define PM3RD_CursorHotSpotY 0x00c #define PM3RD_OverlayKey 0x00d #define PM3RD_Pan 0x00e #define PM3RD_Pan_DISABLE (0<<0) #define PM3RD_Pan_ENABLE (1<<0) #define PM3RD_Pan_GATE_DISABLE (0<<1) #define PM3RD_Pan_GATE_ENABLE (1<<1) #define PM3RD_Sense 0x00f #define PM3RD_CheckControl 0x018 #define PM3RD_CheckControl_PIXEL_DISABLED (0<<0) #define PM3RD_CheckControl_PIXEL_ENABLED (1<<0) #define PM3RD_CheckControl_LUT_DISABLED (0<<1) #define PM3RD_CheckControl_LUT_ENABLED (1<<1) #define PM3RD_CheckPixelRed 0x019 #define PM3RD_CheckPixelGreen 0x01a #define PM3RD_CheckPixelBlue 0x01b #define PM3RD_CheckLUTRed 0x01c #define PM3RD_CheckLUTGreen 0x01d #define PM3RD_CheckLUTBlue 0x01e #define PM3RD_Scratch 0x01f #define PM3RD_VideoOverlayControl 0x020 #define PM3RD_VideoOverlayControl_DISABLE (0<<0) #define PM3RD_VideoOverlayControl_ENABLE (1<<0) #define PM3RD_VideoOverlayControl_MODE_MASK (3<<1) #define PM3RD_VideoOverlayControl_MODE_MAINKEY (0<<1) #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1<<1) #define PM3RD_VideoOverlayControl_MODE_ALWAYS (2<<1) #define PM3RD_VideoOverlayControl_MODE_BLEND (3<<1) #define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED (0<<3) #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1<<3) #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0<<4) #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1<<4) #define PM3RD_VideoOverlayControl_KEY_COLOR (0<<5) #define PM3RD_VideoOverlayControl_KEY_ALPHA (1<<5) #define PM3RD_VideoOverlayXStartLow 0x021 #define PM3RD_VideoOverlayXStartHigh 0x022 #define PM3RD_VideoOverlayYStartLow 0x023 #define PM3RD_VideoOverlayYStartHigh 0x024 #define PM3RD_VideoOverlayXEndLow 0x025 #define PM3RD_VideoOverlayXEndHigh 0x026 #define PM3RD_VideoOverlayYEndLow 0x027 #define PM3RD_VideoOverlayYEndHigh 0x028 #define PM3RD_VideoOverlayKeyR 0x029 #define PM3RD_VideoOverlayKeyG 0x02a #define PM3RD_VideoOverlayKeyB 0x02b #define PM3RD_VideoOverlayBlend 0x02c #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0<<6) #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1<<6) #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2<<6) #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3<<6) #define PM3RD_DClkSetup1 0x1f0 #define PM3RD_DClkSetup2 0x1f1 #define PM3RD_KClkSetup1 0x1f2 #define PM3RD_KClkSetup2 0x1f3 #define PM3RD_DClkControl 0x200 #define PM3RD_DClkControl_SOURCE_PLL (0<<4) #define PM3RD_DClkControl_SOURCE_VSA (1<<4) #define PM3RD_DClkControl_SOURCE_VSB (2<<4) #define PM3RD_DClkControl_SOURCE_EXT (3<<4) #define PM3RD_DClkControl_STATE_RUN (2<<2) #define PM3RD_DClkControl_STATE_HIGH (1<<2) #define PM3RD_DClkControl_STATE_LOW (0<<2) #define PM3RD_DClkControl_LOCKED (1<<1) #define PM3RD_DClkControl_NOT_LOCKED (0<<1) #define PM3RD_DClkControl_ENABLE (1<<0) #define PM3RD_DClkControl_DISABLE (0<<0) #define PM3RD_DClk0PreScale 0x201 #define PM3RD_DClk0FeedbackScale 0x202 #define PM3RD_DClk0PostScale 0x203 #define PM3RD_DClk1PreScale 0x204 #define PM3RD_DClk1FeedbackScale 0x205 #define PM3RD_DClk1PostScale 0x206 #define PM3RD_DClk2PreScale 0x207 #define PM3RD_DClk2FeedbackScale 0x208 #define PM3RD_DClk2PostScale 0x209 #define PM3RD_DClk3PreScale 0x20a #define PM3RD_DClk3FeedbackScale 0x20b #define PM3RD_DClk3PostScale 0x20c #define PM3RD_KClkControl 0x20d #define PM3RD_KClkControl_DISABLE (0<<0) #define PM3RD_KClkControl_ENABLE (1<<0) #define PM3RD_KClkControl_NOT_LOCKED (0<<1) #define PM3RD_KClkControl_LOCKED (1<<1) #define PM3RD_KClkControl_STATE_LOW (0<<2) #define PM3RD_KClkControl_STATE_HIGH (1<<2) #define PM3RD_KClkControl_STATE_RUN (2<<2) #define PM3RD_KClkControl_STATE_LOW_POWER (3<<2) #define PM3RD_KClkControl_SOURCE_PCLK (0<<4) #define PM3RD_KClkControl_SOURCE_HALF_PCLK (1<<4) #define PM3RD_KClkControl_SOURCE_PLL (2<<4) #define PM3RD_KClkPreScale 0x20e #define PM3RD_KClkFeedbackScale 0x20f #define PM3RD_KClkPostScale 0x210 #define PM3RD_MClkControl 0x211 #define PM3RD_MClkControl_DISABLE (0<<0) #define PM3RD_MClkControl_ENABLE (1<<0) #define PM3RD_MClkControl_NOT_LOCKED (0<<1) #define PM3RD_MClkControl_LOCKED (1<<1) #define PM3RD_MClkControl_STATE_LOW (0<<2) #define PM3RD_MClkControl_STATE_HIGH (1<<2) #define PM3RD_MClkControl_STATE_RUN (2<<2) #define PM3RD_MClkControl_STATE_LOW_POWER (3<<2) #define PM3RD_MClkControl_SOURCE_PCLK (0<<4) #define PM3RD_MClkControl_SOURCE_HALF_PCLK (1<<4) #define PM3RD_MClkControl_SOURCE_HALF_EXT (3<<4) #define PM3RD_MClkControl_SOURCE_EXT (4<<4) #define PM3RD_MClkControl_SOURCE_HALF_KCLK (5<<4) #define PM3RD_MClkControl_SOURCE_KCLK (6<<4) #define PM3RD_MClkPreScale 0x212 #define PM3RD_MClkFeedbackScale 0x213 #define PM3RD_MClkPostScale 0x214 #define PM3RD_SClkControl 0x215 #define PM3RD_SClkControl_DISABLE (0<<0) #define PM3RD_SClkControl_ENABLE (1<<0) #define PM3RD_SClkControl_NOT_LOCKED (0<<1) #define PM3RD_SClkControl_LOCKED (1<<1) #define PM3RD_SClkControl_STATE_LOW (0<<2) #define PM3RD_SClkControl_STATE_HIGH (1<<2) #define PM3RD_SClkControl_STATE_RUN (2<<2) #define PM3RD_SClkControl_STATE_LOW_POWER (3<<2) #define PM3RD_SClkControl_SOURCE_PCLK (0<<4) #define PM3RD_SClkControl_SOURCE_HALF_PCLK (1<<4) #define PM3RD_SClkControl_SOURCE_HALF_EXT (3<<4) #define PM3RD_SClkControl_SOURCE_EXT (4<<4) #define PM3RD_SClkControl_SOURCE_HALF_KCLK (5<<4) #define PM3RD_SClkControl_SOURCE_KCLK (6<<4) #define PM3RD_SClkPreScale 0x216 #define PM3RD_SClkFeedbackScale 0x217 #define PM3RD_SClkPostScale 0x218 #define PM3RD_CursorPalette(p) (0x303+(p)) #define PM3RD_CursorPattern(p) (0x400+(p)) /****************************************************** * GLINT Permedia3 Video Streaming Registers (0x5000) * *******************************************************/ #define PM3VSConfiguration 0x5800 /********************************************** * GLINT Permedia3 Core Registers (0x8000+) * ***********************************************/ #define PM3AALineWidth 0x94c0 #define PM3AAPointsize 0x94a0 #define PM3AlphaBlendAlphaMode 0xafa8 #define PM3AlphaBlendAlphaModeAnd 0xad30 #define PM3AlphaBlendAlphaModeOr 0xad38 #define PM3AlphaBlendColorMode 0xafa0 #define PM3AlphaBlendColorModeAnd 0xacb0 #define PM3AlphaBlendColorModeOr 0xacb8 #define PM3AlphaDestColor 0xaf88 #define PM3AlphaSourceColor 0xaf80 #define PM3AlphaTestMode 0x8800 #define PM3AlphaTestModeAnd 0xabf0 #define PM3AlphaTestModeOr 0xabf8 #define PM3AntialiasMode 0x8808 #define PM3AntialiasModeAnd 0xac00 #define PM3AntialiasModeOr 0xac08 #define PM3AreaStippleMode 0x81a0 /* ... */ #define PM3BackgroundColor 0xb0c8 #define PM3BasePageOfWorkingSet 0xb4c8 /* ... */ #define PM3ChromaTestMode 0x8f18 /* ... */ #define PM3ColorDDAMode 0x87e0 #define PM3ColorDDAModeAnd 0xabe0 #define PM3ColorDDAModeOr 0xabe8 #define PM3CommandInterrupt 0xa990 #define PM3ConstantColorDDA 0xafb0 #define PM3ConstantColorDDA_R(r) ((r)&0xff) #define PM3ConstantColorDDA_G(g) (((g)&0xff)<<8) #define PM3ConstantColorDDA_B(b) (((b)&0xff)<<16) #define PM3ConstantColorDDA_A(a) (((a)&0xff)<<24) #define PM3ContextData 0x8dd0 #define PM3ContextDump 0x8dc0 #define PM3ContextRestore 0x8dc8 #define PM3Continue 0x8058 #define PM3ContinueNewDom 0x8048 #define PM3ContinueNewLine 0x8040 #define PM3ContinueNewSub 0x8050 #define PM3Count 0x8030 /* ... */ #define PM3DeltaControl 0x9350 #define PM3DeltaControlAnd 0xab20 #define PM3DeltaControlOr 0xab28 #define PM3DeltaMode 0x9300 #define PM3DeltaModeAnd 0xaad0 #define PM3DeltaModeOr 0xaad8 #define PM3DepthMode 0x89a0 /* ... */ #define PM3DitherMode 0x8818 #define PM3DitherModeAnd 0xacd0 #define PM3DitherModeOr 0xacd8 /* ... */ #define PM3DMARectangleRead 0xa9a8 #define PM3DMARectangleRead_Width(w) (w&0xfff) #define PM3DMARectangleRead_Height(h) ((h&0xfff)<<12) #define PM3DMARectangleRead_PixelSize(s) ((s&0x3)<<24) #define PM3DMARectangleRead_Pack (1<<26) #define PM3DMARectangleRead_ByteSwap(b) ((b&0x3)<<27) #define PM3DMARectangleRead_Alignment (1<<30) #define PM3DMARectangleReadAddress 0xa9b0 #define PM3DMARectangleReadLinePitch 0xa9b8 #define PM3DMARectangleReadTarget 0xa9c0 /* ... */ #define PM3DownloadAddress 0xb0d0 #define PM3DownloadData 0xb0d8 /* ... */ #define PM3dBdx 0x87b8 #define PM3dBdyDom 0x87c0 #define PM3dGdx 0x87a0 #define PM3dGdyDom 0x87a8 #define PM3dQdx 0x83c0 #define PM3dQdyDom 0x83c8 #define PM3dRdx 0x8788 #define PM3dRdyDom 0x8790 #define PM3dSdx 0x8390 #define PM3dSdy 0x83d8 #define PM3dSdyDom 0x8398 #define PM3dTdx 0x83a8 #define PM3dTdy 0x83e0 #define PM3dTdyDom 0x83b0 #define PM3dXDom 0x8008 #define PM3dXSub 0x8018 #define PM3dY 0x8028 /* ... */ #define PM3FBBlockColor 0x8ac8 #define PM3FBBlockColor0 0xb060 #define PM3FBBlockColor1 0xb068 #define PM3FBBlockColor2 0xb070 #define PM3FBBlockColor3 0xb078 #define PM3FBBlockColorBack 0xb0a0 #define PM3FBBlockColorBack0 0xb080 #define PM3FBBlockColorBack1 0xb088 #define PM3FBBlockColorBack2 0xb090 #define PM3FBBlockColorBack3 0xb098 #define PM3FBColor 0x8a98 #define PM3FBDestReadBufferAddr0 0xae80 #define PM3FBDestReadBufferAddr1 0xae88 #define PM3FBDestReadBufferAddr2 0xae90 #define PM3FBDestReadBufferAddr3 0xae98 #define PM3FBDestReadBufferOffset0 0xaea0 #define PM3FBDestReadBufferOffset1 0xaea8 #define PM3FBDestReadBufferOffset2 0xaeb0 #define PM3FBDestReadBufferOffset3 0xaeb8 #define PM3FBDestReadBufferOffset_XOffset(x) ((x)&0xffff) #define PM3FBDestReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FBDestReadBufferWidth0 0xaec0 #define PM3FBDestReadBufferWidth1 0xaec8 #define PM3FBDestReadBufferWidth2 0xaed0 #define PM3FBDestReadBufferWidth3 0xaed8 #define PM3FBDestReadBufferWidth_Width(w) ((w)&0x0fff) #define PM3FBDestReadEnables 0xaee8 #define PM3FBDestReadEnablesAnd 0xad20 #define PM3FBDestReadEnablesOr 0xad28 #define PM3FBDestReadEnables_E(e) ((e)&0xff) #define PM3FBDestReadEnables_E0 (1<<0) #define PM3FBDestReadEnables_E1 (1<<1) #define PM3FBDestReadEnables_E2 (1<<2) #define PM3FBDestReadEnables_E3 (1<<3) #define PM3FBDestReadEnables_E4 (1<<4) #define PM3FBDestReadEnables_E5 (1<<5) #define PM3FBDestReadEnables_E6 (1<<6) #define PM3FBDestReadEnables_E7 (1<<7) #define PM3FBDestReadEnables_R(r) (((r)&0xff)<<8) #define PM3FBDestReadEnables_R0 (1<<8) #define PM3FBDestReadEnables_R1 (1<<9) #define PM3FBDestReadEnables_R2 (1<<10) #define PM3FBDestReadEnables_R3 (1<<11) #define PM3FBDestReadEnables_R4 (1<<12) #define PM3FBDestReadEnables_R5 (1<<13) #define PM3FBDestReadEnables_R6 (1<<14) #define PM3FBDestReadEnables_R7 (1<<15) #define PM3FBDestReadEnables_ReferenceAlpha(a) (((a)&0xff)<<24) #define PM3FBDestReadMode 0xaee0 #define PM3FBDestReadModeAnd 0xac90 #define PM3FBDestReadModeOr 0xac98 #define PM3FBDestReadMode_ReadDisable (0<<0) #define PM3FBDestReadMode_ReadEnable (1<<0) #define PM3FBDestReadMode_StripePitch(sp) (((sp)&0x7)<<2) #define PM3FBDestReadMode_StripeHeight(sh) (((sh)&0x7)<<7) #define PM3FBDestReadMode_Enable0 (1<<8) #define PM3FBDestReadMode_Enable1 (1<<9) #define PM3FBDestReadMode_Enable2 (1<<10) #define PM3FBDestReadMode_Enable3 (1<<11) #define PM3FBDestReadMode_Layout0(l) (((l)&0x3)<<12) #define PM3FBDestReadMode_Layout1(l) (((l)&0x3)<<14) #define PM3FBDestReadMode_Layout2(l) (((l)&0x3)<<16) #define PM3FBDestReadMode_Layout3(l) (((l)&0x3)<<18) #define PM3FBDestReadMode_Origin0 (1<<20) #define PM3FBDestReadMode_Origin1 (1<<21) #define PM3FBDestReadMode_Origin2 (1<<22) #define PM3FBDestReadMode_Origin3 (1<<23) #define PM3FBDestReadMode_Blocking (1<<24) #define PM3FBDestReadMode_UseReadEnabled (1<<26) #define PM3FBDestReadMode_AlphaFiltering (1<<27) #define PM3FBHardwareWriteMask 0x8ac0 #define PM3FBSoftwareWriteMask 0x8820 #define PM3FBData 0x8aa0 #define PM3FBSourceData 0x8aa8 #define PM3FBSourceReadBufferAddr 0xaf08 #define PM3FBSourceReadBufferOffset 0xaf10 #define PM3FBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) #define PM3FBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FBSourceReadBufferWidth 0xaf18 #define PM3FBSourceReadBufferWidth_Width(w) ((w)&0x0fff) #define PM3FBSourceReadMode 0xaf00 #define PM3FBSourceReadModeAnd 0xaca0 #define PM3FBSourceReadModeOr 0xaca8 #define PM3FBSourceReadMode_ReadDisable (0<<0) #define PM3FBSourceReadMode_ReadEnable (1<<0) #define PM3FBSourceReadMode_StripePitch(sp) (((sp)&0x7)<<2) #define PM3FBSourceReadMode_StripeHeight(sh) (((sh)&0x7)<<7) #define PM3FBSourceReadMode_Layout(l) (((l)&0x3)<<8) #define PM3FBSourceReadMode_Origin (1<<10) #define PM3FBSourceReadMode_Blocking (1<<11) #define PM3FBSourceReadMode_UseTexelCoord (1<<13) #define PM3FBSourceReadMode_WrapXEnable (1<<14) #define PM3FBSourceReadMode_WrapYEnable (1<<15) #define PM3FBSourceReadMode_WrapX(w) (((w)&0xf)<<16) #define PM3FBSourceReadMode_WrapY(w) (((w)&0xf)<<20) #define PM3FBSourceReadMode_ExternalSourceData (1<<24) #define PM3FBWriteBufferAddr0 0xb000 #define PM3FBWriteBufferAddr1 0xb008 #define PM3FBWriteBufferAddr2 0xb010 #define PM3FBWriteBufferAddr3 0xb018 #define PM3FBWriteBufferOffset0 0xb020 #define PM3FBWriteBufferOffset1 0xb028 #define PM3FBWriteBufferOffset2 0xb030 #define PM3FBWriteBufferOffset3 0xb038 #define PM3FBWriteBufferOffset_XOffset(x) ((x)&0xffff) #define PM3FBWriteBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FBWriteBufferWidth0 0xb040 #define PM3FBWriteBufferWidth1 0xb048 #define PM3FBWriteBufferWidth2 0xb050 #define PM3FBWriteBufferWidth3 0xb058 #define PM3FBWriteBufferWidth_Width(w) ((w)&0x0fff) #define PM3FBWriteMode 0x8ab8 #define PM3FBWriteModeAnd 0xacf0 #define PM3FBWriteModeOr 0xacf8 #define PM3FBWriteMode_WriteDisable 0<<0 #define PM3FBWriteMode_WriteEnable 1<<0 #define PM3FBWriteMode_Replicate 1<<4 #define PM3FBWriteMode_OpaqueSpan 1<<5 #define PM3FBWriteMode_StripePitch(p) (((p)&0x7)<<6) #define PM3FBWriteMode_StripeHeight(h) (((h)&0x7)<<9) #define PM3FBWriteMode_Enable0 1<<12 #define PM3FBWriteMode_Enable1 1<<13 #define PM3FBWriteMode_Enable2 1<<14 #define PM3FBWriteMode_Enable3 1<<15 #define PM3FBWriteMode_Layout0(l) (((l)&0x3)<<16) #define PM3FBWriteMode_Layout1(l) (((l)&0x3)<<18) #define PM3FBWriteMode_Layout2(l) (((l)&0x3)<<20) #define PM3FBWriteMode_Layout3(l) (((l)&0x3)<<22) #define PM3FBWriteMode_Origin0 1<<24 #define PM3FBWriteMode_Origin1 1<<25 #define PM3FBWriteMode_Origin2 1<<26 #define PM3FBWriteMode_Origin3 1<<27 #define PM3FogMode 0x8690 #define PM3ForegroundColor 0xb0c0 /* ... */ #define PM3GIDMode 0xb538 #define PM3GIDModeAnd 0xb5b0 #define PM3GIDModeOr 0xb5b8 /* ... */ #define PM3HeadPhysicalPageAllocation0 0xb480 #define PM3HeadPhysicalPageAllocation1 0xb488 #define PM3HeadPhysicalPageAllocation2 0xb490 #define PM3HeadPhysicalPageAllocation3 0xb498 /* ... */ #define PM3LBDestReadBufferAddr 0xb510 #define PM3LBDestReadBufferOffset 0xb518 #define PM3LBDestReadEnables 0xb508 #define PM3LBDestReadEnablesAnd 0xb590 #define PM3LBDestReadEnablesOr 0xb598 #define PM3LBDestReadMode 0xb500 #define PM3LBDestReadModeAnd 0xb580 #define PM3LBDestReadModeOr 0xb588 #define PM3LBDestReadMode_Disable (0<<0) #define PM3LBDestReadMode_Enable (1<<0) #define PM3LBDestReadMode_StripePitch(p) (((p)&0x7)<<2) #define PM3LBDestReadMode_StripeHeight(h) (((h)&0x7)<<5) #define PM3LBDestReadMode_Layout (1<<8) #define PM3LBDestReadMode_Origin (1<<9) #define PM3LBDestReadMode_UserReadEnables (1<<10) #define PM3LBDestReadMode_Packed16 (1<<11) #define PM3LBDestReadMode_Width(w) (((w)&0xfff)<<12) #define PM3LBReadFormat 0x8888 #define PM3LBReadFormat_DepthWidth(w) (((w)&0x3)<<0) #define PM3LBReadFormat_StencilWidth(w) (((w)&0xf)<<2) #define PM3LBReadFormat_StencilPosition(p) (((p)&0x1f)<<6) #define PM3LBReadFormat_FCPWidth(w) (((w)&0xf)<<11) #define PM3LBReadFormat_FCPPosition(p) (((p)&0x1f)<<15) #define PM3LBReadFormat_GIDWidth(w) (((w)&0x7)<<20) #define PM3LBReadFormat_GIDPosition(p) (((p)&0x1f)<<23) #define PM3LBSourceReadBufferAddr 0xb528 #define PM3LBSourceReadBufferOffset 0xb530 #define PM3LBSourceReadMode 0xb520 #define PM3LBSourceReadModeAnd 0xb5a0 #define PM3LBSourceReadModeOr 0xb5a8 #define PM3LBSourceReadMode_Enable (1<<0) #define PM3LBSourceReadMode_StripePitch(p) (((p)&0x7)<<2) #define PM3LBSourceReadMode_StripeHeight(h) (((h)&0x7)<<5) #define PM3LBSourceReadMode_Layout (1<<8) #define PM3LBSourceReadMode_Origin (1<<9) #define PM3LBSourceReadMode_Packed16 (1<<10) #define PM3LBSourceReadMode_Width(w) (((w)&0xfff)<<11) #define PM3LBStencil 0x88a8 #define PM3LBWriteBufferAddr 0xb540 #define PM3LBWriteBufferOffset 0xb548 #define PM3LBWriteFormat 0x88c8 #define PM3LBWriteFormat_DepthWidth(w) (((w)&0x3)<<0) #define PM3LBWriteFormat_StencilWidth(w) (((w)&0xf)<<2) #define PM3LBWriteFormat_StencilPosition(p) (((p)&0x1f)<<6) #define PM3LBWriteFormat_GIDWidth(w) (((w)&0x7)<<20) #define PM3LBWriteFormat_GIDPosition(p) (((p)&0x1f)<<23) #define PM3LBWriteMode 0x88c0 #define PM3LBWriteModeAnd 0xac80 #define PM3LBWriteModeOr 0xac88 #define PM3LBWriteMode_WriteDisable (0<<0) #define PM3LBWriteMode_WriteEnable (1<<0) #define PM3LBWriteMode_StripePitch(p) (((p)&0x7)<<3) #define PM3LBWriteMode_StripeHeight(h) (((h)&0x7)<<6) #define PM3LBWriteMode_Layout (1<<9) #define PM3LBWriteMode_Origin (1<<10) #define PM3LBWriteMode_Packed16 (1<<11) #define PM3LBWriteMode_Width(w) (((w)&0xfff)<<12) /* ... */ #define PM3LineStippleMode 0x81a8 #define PM3LineStippleModeAnd 0xabc0 #define PM3LineStippleModeOr 0xabc8 #define PM3LoadLineStippleCounters 0x81b0 /* ... */ #define PM3LogicalOpMode 0x8828 #define PM3LogicalOpModeAnd 0xace0 #define PM3LogicalOpModeOr 0xace8 #define PM3LogicalOpMode_Disable (0<<0) #define PM3LogicalOpMode_Enable (1<<0) #define PM3LogicalOpMode_LogicOp(op) (((op)&0xf)<<1) #define PM3LogicalOpMode_UseConstantWriteData_Disable (0<<5) #define PM3LogicalOpMode_UseConstantWriteData_Enable (1<<5) #define PM3LogicalOpMode_Background_Disable (0<<6) #define PM3LogicalOpMode_Background_Enable (1<<6) #define PM3LogicalOpMode_Background_LogicOp(op) (((op)&0xf)<<7) #define PM3LogicalOpMode_UseConstantSource_Disable (0<<11) #define PM3LogicalOpMode_UseConstantSource_Enable (1<<11) #define PM3LogicalTexturePageAddr 0xb4d0 #define PM3LogicalTexturePageTableLength 0xb4d8 /* ... */ #define PM3LUT 0x8e80 /* ... */ #define PM3LUT 0x8e80 #define PM3LUTAddress 0x84d0 #define PM3LUTData 0x84c8 #define PM3LUTIndex 0x84c0 #define PM3LUTMode 0xb378 #define PM3LUTModeAnd 0xad70 #define PM3LUTModeOr 0xad78 #define PM3LUTTransfer 0x84d8 /* ... */ #define PM3PhysicalPageAllocationTableAddr 0xb4c0 /* ... */ #define PM3PixelSize 0x80c0 #define PM3PixelSize_GLOBAL_32BIT (0<<0) #define PM3PixelSize_GLOBAL_16BIT (1<<0) #define PM3PixelSize_GLOBAL_8BIT (2<<0) #define PM3PixelSize_RASTERIZER_32BIT (0<<2) #define PM3PixelSize_RASTERIZER_16BIT (1<<2) #define PM3PixelSize_RASTERIZER_8BIT (2<<2) #define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0<<4) #define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1<<4) #define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2<<4) #define PM3PixelSize_TEXTURE_32BIT (0<<6) #define PM3PixelSize_TEXTURE_16BIT (1<<6) #define PM3PixelSize_TEXTURE_8BIT (2<<6) #define PM3PixelSize_LUT_32BIT (0<<8) #define PM3PixelSize_LUT_16BIT (1<<8) #define PM3PixelSize_LUT_8BIT (2<<8) #define PM3PixelSize_FRAMEBUFFER_32BIT (0<<10) #define PM3PixelSize_FRAMEBUFFER_16BIT (1<<10) #define PM3PixelSize_FRAMEBUFFER_8BIT (2<<10) #define PM3PixelSize_LOGICAL_OP_32BIT (0<<12) #define PM3PixelSize_LOGICAL_OP_16BIT (1<<12) #define PM3PixelSize_LOGICAL_OP_8BIT (2<<12) #define PM3PixelSize_LOCALBUFFER_32BIT (0<<14) #define PM3PixelSize_LOCALBUFFER_16BIT (1<<14) #define PM3PixelSize_LOCALBUFFER_8BIT (2<<14) #define PM3PixelSize_SETUP_32BIT (0<<16) #define PM3PixelSize_SETUP_16BIT (1<<16) #define PM3PixelSize_SETUP_8BIT (2<<16) #define PM3PixelSize_GLOBAL (0<<31) #define PM3PixelSize_INDIVIDUAL (1<<31) /* ... */ #define PM3QStart 0x83b8 #define PM3Render 0x8038 #define PM3Render_AreaStipple_Disable (0<<0) #define PM3Render_AreaStipple_Enable (1<<0) #define PM3Render_LineStipple_Disable (0<<1) #define PM3Render_LineStipple_Enable (1<<1) #define PM3Render_ResetLine_Disable (0<<2) #define PM3Render_ResetLine_Enable (1<<2) #define PM3Render_FastFill_Disable (0<<3) #define PM3Render_FastFill_Enable (1<<3) #define PM3Render_Primitive_Line (0<<6) #define PM3Render_Primitive_Trapezoid (1<<6) #define PM3Render_Primitive_Point (2<<6) #define PM3Render_Antialias_Disable (0<<8) #define PM3Render_Antialias_Enable (1<<8) #define PM3Render_Antialias_SubPixelRes_4x4 (0<<9) #define PM3Render_Antialias_SubPixelRes_8x8 (1<<9) #define PM3Render_UsePointTable_Disable (0<<10) #define PM3Render_UsePointTable_Enable (1<<10) #define PM3Render_SyncOnbitMask_Disable (0<<11) #define PM3Render_SyncOnBitMask_Enable (1<<11) #define PM3Render_SyncOnHostData_Disable (0<<12) #define PM3Render_SyncOnHostData_Enable (1<<12) #define PM3Render_Texture_Disable (0<<13) #define PM3Render_Texture_Enable (1<<13) #define PM3Render_Fog_Disable (0<<14) #define PM3Render_Fog_Enable (1<<14) #define PM3Render_Coverage_Disable (0<<15) #define PM3Render_Coverage_Enable (1<<15) #define PM3Render_SubPixelCorrection_Disable (0<<16) #define PM3Render_SubPixelCorrection_Enable (1<<16) #define PM3Render_SpanOperation_Disable (0<<18) #define PM3Render_SpanOperation_Enable (1<<18) #define PM3Render_FBSourceRead_Disable (0<<27) #define PM3Render_FBSourceRead_Enable (1<<27) #define PM3RasterizerMode 0x80a0 #define PM3RasterizerModeAnd 0xaba0 #define PM3RasterizerModeOr 0xabb8 #define PM3RectangleHeight 0x94e0 #define PM3RepeatLine 0x9328 #define PM3ResetPickResult 0x8c20 #define PM3RLEMask 0x8c48 #define PM3RouterMode 0x8840 #define PM3RStart 0x8780 #define PM3S1Start 0x8400 #define PM3aveLineStippleCounters 0x81c0 #define PM3ScissorMaxXY 0x8190 #define PM3ScissorMinXY 0x8188 #define PM3ScissorMode 0x8180 #define PM3ScissorModeAnd 0xabb0 #define PM3ScissorModeOr 0xabb8 #define PM3ScreenSize 0x8198 #define PM3Security 0x8908 #define PM3SetLogicalTexturePage 0xb360 #define PM3SizeOfFramebuffer 0xb0a8 #define PM3SStart 0x8388 #define PM3StartXDom 0x8000 #define PM3StartXSub 0x8010 #define PM3StartY 0x8020 /* ... */ #define PM3SpanColorMask 0x8168 #define PM3StencilMode 0x8988 /* ... */ #define PM3TailPhysicalPageAllocation0 0xb4a0 #define PM3TailPhysicalPageAllocation1 0xb4a8 #define PM3TailPhysicalPageAllocation2 0xb4b0 #define PM3TailPhysicalPageAllocation3 0xb4b8 /* ... */ #define PM3TextureApplicationMode 0x8680 #define PM3TextureApplicationModeAnd 0xac50 #define PM3TextureApplicationModeOr 0xac58 #define PM3TextureBaseAddr0 0x8500 #define PM3TextureBaseAddr1 0x8508 #define PM3TextureBaseAddr2 0x8510 #define PM3TextureBaseAddr3 0x8518 #define PM3TextureBaseAddr4 0x8520 #define PM3TextureBaseAddr5 0x8528 #define PM3TextureBaseAddr6 0x8530 #define PM3TextureBaseAddr7 0x8538 #define PM3TextureBaseAddr8 0x8540 #define PM3TextureBaseAddr9 0x8548 #define PM3TextureBaseAddr10 0x8550 #define PM3TextureBaseAddr11 0x8558 #define PM3TextureBaseAddr12 0x8560 #define PM3TextureBaseAddr13 0x8568 #define PM3TextureBaseAddr14 0x8570 #define PM3TextureBaseAddr15 0x8578 #define PM3TextureCacheControl 0x8490 #define PM3TextureChromaLower0 0x84f0 #define PM3TextureChromaLower1 0x8608 #define PM3TextureChromaUpper0 0x84e8 #define PM3TextureChromaUpper1 0x8600 #define PM3TextureCompositeAlphaMode0 0xb310 #define PM3TextureCompositeAlphaMode0And 0xb390 #define PM3TextureCompositeAlphaMode0Or 0xb398 #define PM3TextureCompositeAlphaMode1 0xb320 #define PM3TextureCompositeAlphaMode1And 0xb3b0 #define PM3TextureCompositeAlphaMode1Or 0xb3b8 #define PM3TextureCompositeColorMode0 0xb308 #define PM3TextureCompositeColorMode0And 0xb380 #define PM3TextureCompositeColorMode0Or 0xb388 #define PM3TextureCompositeColorMode1 0xb318 #define PM3TextureCompositeColorMode1And 0xb3a0 #define PM3TextureCompositeColorMode1Or 0xb3a8 #define PM3TextureCompositeFactor0 0xb328 #define PM3TextureCompositeFactor1 0xb330 #define PM3TextureCompositeMode 0xb300 #define PM3TextureCoordMode 0x8380 #define PM3TextureCoordModeAnd 0xac20 #define PM3TextureCoordModeOr 0xac28 #define PM3TextureData 0x88e8 /* #define PM3TextureDownloadControl 0x0108 */ #define PM3TextureDownloadOffset 0x88f0 #define PM3TextureEnvColor 0x8688 #define PM3TextureFilterMode 0x84e0 #define PM3TextureFilterModeAnd 0xad50 #define PM3TextureFilterModeOr 0xad58 #define PM3TextureIndexMode0 0xb338 #define PM3TextureIndexMode0And 0xb3c0 #define PM3TextureIndexMode0Or 0xb3c8 #define PM3TextureIndexMode1 0xb340 #define PM3TextureIndexMode1And 0xb3d0 #define PM3TextureIndexMode1Or 0xb3d8 #define PM3TextureLODBiasS 0x8450 #define PM3TextureLODBiasT 0x8458 /* ... */ #define PM3TextureMapSize 0xb428 #define PM3TextureMapWidth0 0x8580 #define PM3TextureMapWidth1 0x8588 #define PM3TextureMapWidth_Width(w) ((w&0xfff)<<0) #define PM3TextureMapWidth_BorderLayout (1<<12) #define PM3TextureMapWidth_Layout_Linear (0<<13) #define PM3TextureMapWidth_Layout_Patch64 (1<<13) #define PM3TextureMapWidth_Layout_Patch32_2 (2<<13) #define PM3TextureMapWidth_Layout_Patch2 (3<<13) #define PM3TextureMapWidth_HostTexture (1<<15) #define PM3TextureReadMode0 0xb400 #define PM3TextureReadMode0And 0xac30 #define PM3TextureReadMode0Or 0xac38 #define PM3TextureReadMode1 0xb408 #define PM3TextureReadMode1And 0xad40 #define PM3TextureReadMode1Or 0xad48 #define PM3TouchLogicalPage 0xb370 #define PM3TouchLogicalPage_Page(p) (p&0xffff) #define PM3TouchLogicalPage_Count(c) ((c&0x3fff)<<16) #define PM3TouchLogicalPage_Mode(m) ((m&0x3)<<30) #define PM3TStart 0x83a0 #define PM3UpdateLogicalTextureInfo 0xb368 #define PM3UpdateLogicalTextureInfo_Length(l) ((l)&0x1ff) #define PM3UpdateLogicalTextureInfo_MemoryPool(m) (((m)&0x3)<<9) #define PM3UpdateLogicalTextureInfo_VirtualHostPage (1<<11) #define PM3UpdateLogicalTextureInfo_HostPage(p) (((p)&0xfffff)<<12) /* ... */ #define PM3WaitForCompletion 0x80b8 #define PM3Window 0x8980 #define PM3Window_ForceLBUpdate (1<<3) #define PM3Window_LBUpdateSource (1<<4) #define PM3Window_FrameCount(c) (((c)&0xff)<<9) #define PM3Window_StencilFCP (1<<17) #define PM3Window_DepthFCP (1<<18) #define PM3Window_OverrideWriteFiltering (1<<19) #define PM3WindowAnd 0xab80 #define PM3WindowOr 0xab88 #define PM3WindowOrigin 0x81c8 #define PM3XBias 0x9480 #define PM3YBias 0x9488 #define PM3YLimits 0x80a8 #define PM3YUVMode 0x8f00 #define PM3ZFogBias 0x86b8 #define PM3ZStart 0xadd8 #define PM3ZStartL 0x89b8 #define PM3ZStartU 0x89b0 /********************************************** * GLINT Permedia3 2D setup Unit * ***********************************************/ #define PM3Config2D 0xb618 #define PM3Config2D_OpaqueSpan (1<<0) #define PM3Config2D_MultiRXBlit (1<<1) #define PM3Config2D_UserScissorEnable (1<<2) #define PM3Config2D_FBDestReadEnable (1<<3) #define PM3Config2D_AlphaBlendEnable (1<<4) #define PM3Config2D_DitherEnable (1<<5) #define PM3Config2D_ForegroundROPEnable (1<<6) #define PM3Config2D_ForegroundROP(rop) (((rop)&0xf)<<7) #define PM3Config2D_BackgroundROPEnable (1<<11) #define PM3Config2D_BackgroundROP(rop) (((rop)&0xf)<<12) #define PM3Config2D_UseConstantSource (1<<16) #define PM3Config2D_FBWriteEnable (1<<17) #define PM3Config2D_Blocking (1<<18) #define PM3Config2D_ExternalSourceData (1<<19) #define PM3Config2D_LUTModeEnable (1<<20) #define PM3DownloadGlyphwidth 0xb658 #define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw)&0xffff) #define PM3DownloadTarget 0xb650 #define PM3DownloadTarget_TagName(tag) ((tag)&0x1fff) #define PM3GlyphData 0xb660 #define PM3GlyphPosition 0xb608 #define PM3GlyphPosition_XOffset(x) ((x)&0xffff) #define PM3GlyphPosition_YOffset(y) (((y)&0xffff)<<16) #define PM3Packed4Pixels 0xb668 #define PM3Packed8Pixels 0xb630 #define PM3Packed16Pixels 0xb638 #define PM3RectanglePosition 0xb600 #define PM3RectanglePosition_XOffset(x) ((x)&0xffff) #define PM3RectanglePosition_YOffset(y) (((y)&0xffff)<<16) #define PM3Render2D 0xb640 #define PM3Render2D_Width(w) ((w)&0x0fff) #define PM3Render2D_Operation_Normal (0<<12) #define PM3Render2D_Operation_SyncOnHostData (1<<12) #define PM3Render2D_Operation_SyncOnBitMask (2<<12) #define PM3Render2D_Operation_PatchOrderRendering (3<<12) #define PM3Render2D_FBSourceReadEnable (1<<14) #define PM3Render2D_SpanOperation (1<<15) #define PM3Render2D_Height(h) (((h)&0x0fff)<<16) #define PM3Render2D_XPositive (1<<28) #define PM3Render2D_YPositive (1<<29) #define PM3Render2D_AreaStippleEnable (1<<30) #define PM3Render2D_TextureEnable (1<<31) #define PM3Render2DGlyph 0xb648 #define PM3Render2DGlyph_Width(w) ((w)&0x7f) #define PM3Render2DGlyph_Height(h) (((h)&0x7f)<<7) #define PM3Render2DGlyph_XOffset(x) (((x)&0x1ff)<<14) #define PM3Render2DGlyph_YOffset(y) (((y)&0x1ff)<<23) #define PM3RenderPatchOffset 0xb610 #define PM3RenderPatchOffset_XOffset(x) ((x)&0xffff) #define PM3RenderPatchOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3RLCount 0xb678 #define PM3RLCount_Count(c) ((c)&0x0fff) #define PM3RLData 0xb670 /********************************************** * GLINT Permedia3 Alias Register * ***********************************************/ #define PM3FillBackgroundColor 0x8330 #define PM3FillConfig2D0 0x8338 #define PM3FillConfig2D1 0x8360 #define PM3FillConfig2D_OpaqueSpan 1<<0 #define PM3FillConfig2D_MultiRXBlit 1<<1 #define PM3FillConfig2D_UserScissorEnable 1<<2 #define PM3FillConfig2D_FBDestReadEnable 1<<3 #define PM3FillConfig2D_AlphaBlendEnable 1<<4 #define PM3FillConfig2D_DitherEnable 1<<5 #define PM3FillConfig2D_ForegroundROPEnable 1<<6 #define PM3FillConfig2D_ForegroundROP(rop) (((rop)&0xf)<<7) #define PM3FillConfig2D_BackgroundROPEnable 1<<11 #define PM3FillConfig2D_BackgroundROP(rop) (((rop)&0xf)<<12) #define PM3FillConfig2D_UseConstantSource 1<<16 #define PM3FillConfig2D_FBWriteEnable 1<<17 #define PM3FillConfig2D_Blocking 1<<18 #define PM3FillConfig2D_ExternalSourceData 1<<19 #define PM3FillConfig2D_LUTModeEnable 1<<20 #define PM3FillFBDestReadBufferAddr 0x8310 #define PM3FillFBSourceReadBufferAddr 0x8308 #define PM3FillFBSourceReadBufferOffset 0x8340 #define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) #define PM3FillFBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) #define PM3FillFBWriteBufferAddr 0x8300 #define PM3FillForegroundColor0 0x8328 #define PM3FillForegroundColor1 0x8358 #define PM3FillGlyphPosition 0x8368 #define PM3FillGlyphPosition_XOffset(x) ((x)&0xffff) #define PM3FillGlyphPosition_YOffset(y) (((y)&0xffff)<<16) #define PM3FillRectanglePosition 0x8348 #define PM3FillRectanglePosition_XOffset(x) ((x)&0xffff) #define PM3FillRectanglePosition_YOffset(y) (((y)&0xffff)<<16) /********************************************** * GLINT Permedia3 Macros * ***********************************************/ #ifdef __alpha__ #define mem_barrier() asm volatile ("mb" : : : "memory") #define write_mem_barrier() asm volatile ("wmb" : : : "memory") #else #define mem_barrier() #define write_mem_barrier() #endif extern void *pm3_reg_base; #define WRITE_REG(offset,val) \ do { \ write_mem_barrier(); \ *(volatile uint32_t *) \ (((unsigned char *)(pm3_reg_base)) + offset) = (val); \ } while(0) static inline uint32_t READ_REG(uint32_t offset) { mem_barrier(); return *(volatile uint32_t *)(((unsigned char *)(pm3_reg_base)) + offset); } #define UPDATE_SET_REG(offset,val) \ { \ unsigned long temp; \ temp = READ_REG(offset); \ WRITE_REG(offset,temp|(val)); \ } #define UPDATE_CLEAR_REG(offset,val) \ { \ unsigned long temp; \ temp = READ_REG(offset); \ WRITE_REG(offset,temp&(~(val))); \ } #define WAIT_FIFO(n) while(READ_REG(PM3InFIFOSpace) < (n)) #define RAMDAC_DELAY(x) do { \ int delay = x; \ unsigned char tmp; \ while(delay--){tmp = READ_REG(PM3InFIFOSpace);}; \ } while(0) #define SLOW_WRITE_REG(v,r) \ do{ \ RAMDAC_DELAY(5); \ WRITE_REG(v,r); \ RAMDAC_DELAY(5); \ }while(0) #define RAMDAC_SET_INDEX(index) \ { \ SLOW_WRITE_REG (PM3RD_IndexHigh,(index>>8)&0xff); \ SLOW_WRITE_REG (PM3RD_IndexLow,index&0xff); \ } #define RAMDAC_SET_REG(index, data) \ { \ RAMDAC_SET_INDEX(index); \ SLOW_WRITE_REG(PM3RD_IndexedData, data); \ } #define RAMDAC_GET_REG(index, temp) \ { \ RAMDAC_SET_INDEX(index); \ temp = READ_REG(PM3RD_IndexedData); \ } #endif /* _PM3_REG_H_ */ xine-lib-1.2/contrib/vidix/drivers/sis_regs.h0000644000175000017500000003755414647725152017132 0ustar meme/** SiS register definitions and access macros. From SiS X11 driver. Copyright 2001-2003 by Thomas Winischhofer, Vienna, Austria. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **/ #ifndef VIDIX_SIS_REGS_H #define VIDIX_SIS_REGS_H #define inSISREG(base) INPORT8(base) #define outSISREG(base,val) OUTPORT8(base, val) #define orSISREG(base,val) do { \ unsigned char __Temp = INPORT8(base); \ outSISREG(base, __Temp | (val)); \ } while (0) #define andSISREG(base,val) do { \ unsigned char __Temp = INPORT8(base); \ outSISREG(base, __Temp & (val)); \ } while (0) #define inSISIDXREG(base,idx,var) do { \ OUTPORT8(base, idx); var=INPORT8((base)+1); \ } while (0) #define outSISIDXREG(base,idx,val) do { \ OUTPORT8(base, idx); OUTPORT8((base)+1, val); \ } while (0) #define orSISIDXREG(base,idx,val) do { \ unsigned char __Temp; \ OUTPORT8(base, idx); \ __Temp = INPORT8((base)+1)|(val); \ outSISIDXREG(base,idx,__Temp); \ } while (0) #define andSISIDXREG(base,idx,and) do { \ unsigned char __Temp; \ OUTPORT8(base, idx); \ __Temp = INPORT8((base)+1)&(and); \ outSISIDXREG(base,idx,__Temp); \ } while (0) #define setSISIDXREG(base,idx,and,or) do { \ unsigned char __Temp; \ OUTPORT8(base, idx); \ __Temp = (INPORT8((base)+1)&(and))|(or); \ outSISIDXREG(base,idx,__Temp); \ } while (0) #define BITMASK(h,l) (((unsigned)(1U << ((h)-(l)+1))-1)<<(l)) #define GENMASK(mask) BITMASK(1?mask,0?mask) #define GETBITS(var,mask) (((var) & GENMASK(mask)) >> (0?mask)) #define SETBITS(val,mask) ((val) << (0?mask)) #define SETBIT(n) (1<<(n)) #define GETBITSTR(val,from,to) ((GETBITS(val,from)) << (0?to)) #define SETVARBITS(var,val,from,to) (((var)&(~(GENMASK(to)))) | \ GETBITSTR(val,from,to)) #define GETVAR8(var) ((var)&0xFF) #define SETVAR8(var,val) (var) = GETVAR8(val) /* #define VGA_RELIO_BASE 0x380 */ #define AROFFSET 0x40 /* VGA_ATTR_INDEX - VGA_RELIO_BASE */ #define ARROFFSET 0x41 /* VGA_ATTR_DATA_R - VGA_RELIO_BASE */ #define GROFFSET 0x4e /* VGA_GRAPH_INDEX - VGA_RELIO_BASE */ #define SROFFSET 0x44 /* VGA_SEQ_INDEX - VGA_RELIO_BASE */ #define CROFFSET 0x54 /* VGA_CRTC_INDEX_OFFSET + VGA_IOBASE_COLOR - VGA_RELIO_BASE */ #define MISCROFFSET 0x4c /* VGA_MISC_OUT_R - VGA_RELIO_BASE */ #define MISCWOFFSET 0x42 /* VGA_MISC_OUT_W - VGA_RELIO_BASE */ #define INPUTSTATOFFSET 0x5A #define PART1OFFSET 0x04 #define PART2OFFSET 0x10 #define PART3OFFSET 0x12 #define PART4OFFSET 0x14 #define PART5OFFSET 0x16 #define VIDEOOFFSET 0x02 #define COLREGOFFSET 0x48 #define SIS_IOBASE sis_iobase /* var defined in sis_vid.c */ #define SISAR SIS_IOBASE + AROFFSET #define SISARR SIS_IOBASE + ARROFFSET #define SISGR SIS_IOBASE + GROFFSET #define SISSR SIS_IOBASE + SROFFSET #define SISCR SIS_IOBASE + CROFFSET #define SISMISCR SIS_IOBASE + MISCROFFSET #define SISMISCW SIS_IOBASE + MISCWOFFSET #define SISINPSTAT SIS_IOBASE + INPUTSTATOFFSET #define SISPART1 SIS_IOBASE + PART1OFFSET #define SISPART2 SIS_IOBASE + PART2OFFSET #define SISPART3 SIS_IOBASE + PART3OFFSET #define SISPART4 SIS_IOBASE + PART4OFFSET #define SISPART5 SIS_IOBASE + PART5OFFSET #define SISVID SIS_IOBASE + VIDEOOFFSET #define SISCOLIDX SIS_IOBASE + COLREGOFFSET #define SISCOLDATA SIS_IOBASE + COLREGOFFSET + 1 #define SISCOL2IDX SISPART5 #define SISCOL2DATA SISPART5 + 1 #define vc_index_offset 0x00 /* Video capture - unused */ #define vc_data_offset 0x01 #define vi_index_offset VIDEOOFFSET #define vi_data_offset (VIDEOOFFSET + 1) #define crt2_index_offset PART1OFFSET #define crt2_port_offset (PART1OFFSET + 1) #define sr_index_offset SROFFSET #define sr_data_offset (SROFFSET + 1) #define cr_index_offset CROFFSET #define cr_data_offset (CROFFSET + 1) #define input_stat INPUTSTATOFFSET /* For old chipsets (5597/5598, 6326, 530/620) ------------ */ /* SR (3C4) */ #define BankReg 0x06 #define ClockReg 0x07 #define CPUThreshold 0x08 #define CRTThreshold 0x09 #define CRTCOff 0x0A #define DualBanks 0x0B #define MMIOEnable 0x0B #define RAMSize 0x0C #define Mode64 0x0C #define ExtConfStatus1 0x0E #define ClockBase 0x13 #define LinearAdd0 0x20 #define LinearAdd1 0x21 #define GraphEng 0x27 #define MemClock0 0x28 #define MemClock1 0x29 #define XR2A 0x2A #define XR2B 0x2B #define TurboQueueBase 0x2C #define FBSize 0x2F #define ExtMiscCont5 0x34 #define ExtMiscCont9 0x3C /* 3x4 */ #define Offset 0x13 /* SiS Registers for 300, 540, 630, 730, 315, 550, 650, 740 */ /* VGA standard register */ #define Index_SR_Graphic_Mode 0x06 #define Index_SR_RAMDAC_Ctrl 0x07 #define Index_SR_Threshold_Ctrl1 0x08 #define Index_SR_Threshold_Ctrl2 0x09 #define Index_SR_Misc_Ctrl 0x0F #define Index_SR_DDC 0x11 #define Index_SR_Feature_Connector_Ctrl 0x12 #define Index_SR_DRAM_Sizing 0x14 #define Index_SR_DRAM_State_Machine_Ctrl 0x15 #define Index_SR_AGP_PCI_State_Machine 0x21 #define Index_SR_Internal_MCLK0 0x28 #define Index_SR_Internal_MCLK1 0x29 #define Index_SR_Internal_DCLK1 0x2B #define Index_SR_Internal_DCLK2 0x2C #define Index_SR_Internal_DCLK3 0x2D #define Index_SR_Ext_Clock_Sel 0x32 #define Index_SR_Int_Status 0x34 #define Index_SR_Int_Enable 0x35 #define Index_SR_Int_Reset 0x36 #define Index_SR_Power_On_Trap 0x38 #define Index_SR_Power_On_Trap2 0x39 #define Index_SR_Power_On_Trap3 0x3A /* video registers (300/630/730/315/550/650/740 only) */ #define Index_VI_Passwd 0x00 /* Video overlay horizontal start/end, unit=screen pixels */ #define Index_VI_Win_Hor_Disp_Start_Low 0x01 #define Index_VI_Win_Hor_Disp_End_Low 0x02 #define Index_VI_Win_Hor_Over 0x03 /* Overflow */ /* Video overlay vertical start/end, unit=screen pixels */ #define Index_VI_Win_Ver_Disp_Start_Low 0x04 #define Index_VI_Win_Ver_Disp_End_Low 0x05 #define Index_VI_Win_Ver_Over 0x06 /* Overflow */ /* Y Plane (4:2:0) or YUV (4:2:2) buffer start address, unit=word */ #define Index_VI_Disp_Y_Buf_Start_Low 0x07 #define Index_VI_Disp_Y_Buf_Start_Middle 0x08 #define Index_VI_Disp_Y_Buf_Start_High 0x09 /* U Plane (4:2:0) buffer start address, unit=word */ #define Index_VI_U_Buf_Start_Low 0x0A #define Index_VI_U_Buf_Start_Middle 0x0B #define Index_VI_U_Buf_Start_High 0x0C /* V Plane (4:2:0) buffer start address, unit=word */ #define Index_VI_V_Buf_Start_Low 0x0D #define Index_VI_V_Buf_Start_Middle 0x0E #define Index_VI_V_Buf_Start_High 0x0F /* Pitch for Y, UV Planes, unit=word */ #define Index_VI_Disp_Y_Buf_Pitch_Low 0x10 #define Index_VI_Disp_UV_Buf_Pitch_Low 0x11 #define Index_VI_Disp_Y_UV_Buf_Pitch_Middle 0x12 /* What is this ? */ #define Index_VI_Disp_Y_Buf_Preset_Low 0x13 #define Index_VI_Disp_Y_Buf_Preset_Middle 0x14 #define Index_VI_UV_Buf_Preset_Low 0x15 #define Index_VI_UV_Buf_Preset_Middle 0x16 #define Index_VI_Disp_Y_UV_Buf_Preset_High 0x17 /* Scaling control registers */ #define Index_VI_Hor_Post_Up_Scale_Low 0x18 #define Index_VI_Hor_Post_Up_Scale_High 0x19 #define Index_VI_Ver_Up_Scale_Low 0x1A #define Index_VI_Ver_Up_Scale_High 0x1B #define Index_VI_Scale_Control 0x1C /* Playback line buffer control */ #define Index_VI_Play_Threshold_Low 0x1D #define Index_VI_Play_Threshold_High 0x1E #define Index_VI_Line_Buffer_Size 0x1F /* Destination color key */ #define Index_VI_Overlay_ColorKey_Red_Min 0x20 #define Index_VI_Overlay_ColorKey_Green_Min 0x21 #define Index_VI_Overlay_ColorKey_Blue_Min 0x22 #define Index_VI_Overlay_ColorKey_Red_Max 0x23 #define Index_VI_Overlay_ColorKey_Green_Max 0x24 #define Index_VI_Overlay_ColorKey_Blue_Max 0x25 /* Source color key, YUV color space */ #define Index_VI_Overlay_ChromaKey_Red_Y_Min 0x26 #define Index_VI_Overlay_ChromaKey_Green_U_Min 0x27 #define Index_VI_Overlay_ChromaKey_Blue_V_Min 0x28 #define Index_VI_Overlay_ChromaKey_Red_Y_Max 0x29 #define Index_VI_Overlay_ChromaKey_Green_U_Max 0x2A #define Index_VI_Overlay_ChromaKey_Blue_V_Max 0x2B /* Contrast enhancement and brightness control */ #define Index_VI_Contrast_Factor 0x2C /* obviously unused/undefined */ #define Index_VI_Brightness 0x2D #define Index_VI_Contrast_Enh_Ctrl 0x2E #define Index_VI_Key_Overlay_OP 0x2F #define Index_VI_Control_Misc0 0x30 #define Index_VI_Control_Misc1 0x31 #define Index_VI_Control_Misc2 0x32 /* TW: Subpicture registers */ #define Index_VI_SubPict_Buf_Start_Low 0x33 #define Index_VI_SubPict_Buf_Start_Middle 0x34 #define Index_VI_SubPict_Buf_Start_High 0x35 /* TW: What is this ? */ #define Index_VI_SubPict_Buf_Preset_Low 0x36 #define Index_VI_SubPict_Buf_Preset_Middle 0x37 /* TW: Subpicture pitch, unit=16 bytes */ #define Index_VI_SubPict_Buf_Pitch 0x38 /* TW: Subpicture scaling control */ #define Index_VI_SubPict_Hor_Scale_Low 0x39 #define Index_VI_SubPict_Hor_Scale_High 0x3A #define Index_VI_SubPict_Vert_Scale_Low 0x3B #define Index_VI_SubPict_Vert_Scale_High 0x3C #define Index_VI_SubPict_Scale_Control 0x3D /* (0x40 = enable/disable subpicture) */ /* TW: Subpicture line buffer control */ #define Index_VI_SubPict_Threshold 0x3E /* TW: What is this? */ #define Index_VI_FIFO_Max 0x3F /* TW: Subpicture palette; 16 colors, total 32 bytes address space */ #define Index_VI_SubPict_Pal_Base_Low 0x40 #define Index_VI_SubPict_Pal_Base_High 0x41 /* I wish I knew how to use these ... */ #define Index_MPEG_Read_Ctrl0 0x60 /* MPEG auto flip */ #define Index_MPEG_Read_Ctrl1 0x61 /* MPEG auto flip */ #define Index_MPEG_Read_Ctrl2 0x62 /* MPEG auto flip */ #define Index_MPEG_Read_Ctrl3 0x63 /* MPEG auto flip */ /* TW: MPEG AutoFlip scale */ #define Index_MPEG_Ver_Up_Scale_Low 0x64 #define Index_MPEG_Ver_Up_Scale_High 0x65 #define Index_MPEG_Y_Buf_Preset_Low 0x66 #define Index_MPEG_Y_Buf_Preset_Middle 0x67 #define Index_MPEG_UV_Buf_Preset_Low 0x68 #define Index_MPEG_UV_Buf_Preset_Middle 0x69 #define Index_MPEG_Y_UV_Buf_Preset_High 0x6A /* TW: The following registers only exist on the 310/325 series */ /* TW: Bit 16:24 of Y_U_V buf start address (?) */ #define Index_VI_Y_Buf_Start_Over 0x6B #define Index_VI_U_Buf_Start_Over 0x6C #define Index_VI_V_Buf_Start_Over 0x6D #define Index_VI_Disp_Y_Buf_Pitch_High 0x6E #define Index_VI_Disp_UV_Buf_Pitch_High 0x6F /* Hue and saturation */ #define Index_VI_Hue 0x70 #define Index_VI_Saturation 0x71 #define Index_VI_SubPict_Start_Over 0x72 #define Index_VI_SubPict_Buf_Pitch_High 0x73 #define Index_VI_Control_Misc3 0x74 /* TW: Bits (and helpers) for Index_VI_Control_Misc0 */ #define VI_Misc0_Enable_Overlay 0x02 #define VI_Misc0_420_Plane_Enable 0x04 /* Select Plane or Packed mode */ #define VI_Misc0_422_Enable 0x20 /* Select 422 or 411 mode */ #define VI_Misc0_Fmt_YVU420P 0x0C /* YUV420 Planar (I420, YV12) */ #define VI_Misc0_Fmt_YUYV 0x28 /* YUYV Packed (YUY2) */ #define VI_Misc0_Fmt_UYVY 0x08 /* (UYVY) */ /* TW: Bits for Index_VI_Control_Misc1 */ /* #define VI_Misc1_? 0x01 */ #define VI_Misc1_BOB_Enable 0x02 #define VI_Misc1_Line_Merge 0x04 #define VI_Misc1_Field_Mode 0x08 /* #define VI_Misc1_? 0x10 */ #define VI_Misc1_Non_Interleave 0x20 /* 300 series only? */ #define VI_Misc1_Buf_Addr_Lock 0x20 /* 310 series only? */ /* #define VI_Misc1_? 0x40 */ /* #define VI_Misc1_? 0x80 */ /* TW: Bits for Index_VI_Control_Misc2 */ #define VI_Misc2_Select_Video2 0x01 #define VI_Misc2_Video2_On_Top 0x02 /* #define VI_Misc2_? 0x04 */ #define VI_Misc2_Vertical_Interpol 0x08 #define VI_Misc2_Dual_Line_Merge 0x10 #define VI_Misc2_All_Line_Merge 0x20 /* 310 series only? */ #define VI_Misc2_Auto_Flip_Enable 0x40 /* 300 series only? */ #define VI_Misc2_Video_Reg_Write_Enable 0x80 /* 310 series only? */ /* TW: Bits for Index_VI_Control_Misc3 */ #define VI_Misc3_Submit_Video_1 0x01 /* AKA "address ready" */ #define VI_Misc3_Submit_Video_2 0x02 /* AKA "address ready" */ #define VI_Misc3_Submit_SubPict 0x04 /* AKA "address ready" */ /* TW: Values for Index_VI_Key_Overlay_OP (0x2F) */ #define VI_ROP_Never 0x00 #define VI_ROP_DestKey 0x03 #define VI_ROP_Always 0x0F /* * CRT_2 function control register --------------------------------- */ #define Index_CRT2_FC_CONTROL 0x00 #define Index_CRT2_FC_SCREEN_HIGH 0x04 #define Index_CRT2_FC_SCREEN_MID 0x05 #define Index_CRT2_FC_SCREEN_LOW 0x06 #define Index_CRT2_FC_ENABLE_WRITE 0x24 #define Index_CRT2_FC_VR 0x25 #define Index_CRT2_FC_VCount 0x27 #define Index_CRT2_FC_VCount1 0x28 #define Index_310_CRT2_FC_VR 0x30 /* d[1] = vertical retrace */ #define Index_310_CRT2_FC_RT 0x33 /* d[7] = retrace in progress */ /* video attributes - these should probably be configurable on the fly * so users with different desktop sizes can keep * captured data off the desktop */ #define _VINWID 704 #define _VINHGT _VINHGT_NTSC #define _VINHGT_NTSC 240 #define _VINHGT_PAL 290 #define _VIN_WINDOW (704 * 291 * 2) #define _VBI_WINDOW (704 * 64 * 2) #define _VIN_FIELD_EVEN 1 #define _VIN_FIELD_ODD 2 #define _VIN_FIELD_BOTH 4 /* i2c registers (TW; not on 300/310/325 series) */ #define X_INDEXREG 0x14 #define X_PORTREG 0x15 #define X_DATA 0x0f #define I2C_SCL 0x00 #define I2C_SDA 0x01 #define I2C_DELAY 10 /* mmio registers for video */ #define REG_PRIM_CRT_COUNTER 0x8514 /* TW: MPEG MMIO registers (630 and later) ----------------------------*/ /* Not public (yet?) */ #endif /* VIDIX_SIS_REGS_H */ xine-lib-1.2/contrib/vidix/drivers/pm2_vid.c0000644000175000017500000002073714647725152016642 0ustar meme/** Driver for 3DLabs Permedia 2. Copyright (C) 2002 Måns Rullgård This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA **/ #include #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "glint_regs.h" #define VIDIX_STATIC pm2_ /* MBytes of video memory to use */ #define PM2_VIDMEM 6 #if 0 #define TRACE_ENTER() fprintf(stderr, "%s: enter\n", __FUNCTION__) #define TRACE_EXIT() fprintf(stderr, "%s: exit\n", __FUNCTION__) #else #define TRACE_ENTER() #define TRACE_EXIT() #endif #define WRITE_REG(offset,val) \ *(volatile u_long *)(((u_char *)(pm2_reg_base)) + offset) = (val) #define READ_REG(offset) \ *(volatile unsigned long *)(((unsigned char *)(pm2_reg_base)) + offset) pciinfo_t pci_info; uint8_t *pm2_reg_base; uint8_t *pm2_mem; int pm2_vidmem = PM2_VIDMEM; static vidix_capability_t pm2_cap = { "3DLabs Permedia2 driver", "Måns Rullgård ", TYPE_OUTPUT, { 0, 0, 0, 0 }, 2048, 2048, 4, 4, -1, FLAG_UPSCALER|FLAG_DOWNSCALER, VENDOR_3DLABS, -1, { 0, 0, 0, 0 } }; unsigned int VIDIX_NAME(vixGetVersion)(void) { return(VIDIX_VERSION); } static u_int pm2_card_ids[] = { (VENDOR_3DLABS << 16) | DEVICE_3DLABS_PERMEDIA2, (VENDOR_TEXAS << 16) | DEVICE_TEXAS_TVP4020_PERMEDIA_2 }; static int find_chip(u_int vendor, u_int chip_id) { u_int vci = (vendor << 16) | chip_id; unsigned i; for(i = 0; i < sizeof(pm2_card_ids)/sizeof(u_int); i++){ if(vci == pm2_card_ids[i]) return i; } return -1; } int VIDIX_NAME(vixProbe)(int verbose, int force) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; (void)force; err = pci_scan(lst,&num_pci); if(err) { printf("[pm2] Error occured during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0; i < num_pci; i++) { int idx; const char *dname; idx = find_chip(lst[i].vendor, lst[i].device); if(idx == -1) continue; dname = pci_device_name(lst[i].vendor, lst[i].device); dname = dname ? dname : "Unknown chip"; printf("[pm2] Found chip: %s\n", dname); pm2_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); break; } } if(err && verbose) printf("[pm2] Can't find chip.\n"); return err; } #define PRINT_REG(reg) \ { \ long _foo = READ_REG(reg); \ printf("[pm2] " #reg " (%x) = %#lx (%li)\n", reg, _foo, _foo); \ } int VIDIX_NAME(vixInit)(const char *args) { char *vm; (void)args; pm2_reg_base = map_phys_mem(pci_info.base0, 0x10000); pm2_mem = map_phys_mem(pci_info.base1, 1 << 23); if((vm = getenv("PM2_VIDMEM"))){ pm2_vidmem = strtol(vm, NULL, 0); } return 0; } void VIDIX_NAME(vixDestroy)(void) { unmap_phys_mem(pm2_reg_base, 0x10000); unmap_phys_mem(pm2_mem, 1 << 23); } int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to, &pm2_cap, sizeof(vidix_capability_t)); return 0; } static int is_supported_fourcc(uint32_t fourcc) { switch(fourcc){ case IMGFMT_YUY2: return 1; default: return 0; } } int VIDIX_NAME(vixQueryFourcc)(vidix_fourcc_t *to) { if(is_supported_fourcc(to->fourcc)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } #define FORMAT_YUV422 ((1 << 6) | 3 | (1 << 4)) #define PPROD(a,b,c) (a | (b << 3) | (c << 6)) static u_int ppcodes[][2] = { {0, 0}, {32, PPROD(1, 0, 0)}, {64, PPROD(1, 1, 0)}, {96, PPROD(1, 1, 1)}, {128, PPROD(2, 1, 1)}, {160, PPROD(2, 2, 1)}, {192, PPROD(2, 2, 2)}, {224, PPROD(3, 2, 1)}, {256, PPROD(3, 2, 2)}, {288, PPROD(3, 3, 1)}, {320, PPROD(3, 3, 2)}, {384, PPROD(3, 3, 3)}, {416, PPROD(4, 3, 1)}, {448, PPROD(4, 3, 2)}, {512, PPROD(4, 3, 3)}, {544, PPROD(4, 4, 1)}, {576, PPROD(4, 4, 2)}, {640, PPROD(4, 4, 3)}, {768, PPROD(4, 4, 4)}, {800, PPROD(5, 4, 1)}, {832, PPROD(5, 4, 2)}, {896, PPROD(5, 4, 3)}, {1024, PPROD(5, 4, 4)}, {1056, PPROD(5, 5, 1)}, {1088, PPROD(5, 5, 2)}, {1152, PPROD(5, 5, 3)}, {1280, PPROD(5, 5, 4)}, {1536, PPROD(5, 5, 5)}, {1568, PPROD(6, 5, 1)}, {1600, PPROD(6, 5, 2)}, {1664, PPROD(6, 5, 3)}, {1792, PPROD(6, 5, 4)}, {2048, PPROD(6, 5, 5)} }; static int frames[VID_PLAY_MAXFRAMES]; int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { u_int src_w, drw_w; u_int src_h, drw_h; long base0; u_int stride, sstr; u_int format; unsigned int i; u_int ppcode = 0, sppc = 0; u_int pitch = 0; TRACE_ENTER(); switch(info->fourcc){ case IMGFMT_YUY2: format = FORMAT_YUV422; break; default: return -1; } src_w = info->src.w; src_h = info->src.h; drw_w = info->dest.w; drw_h = info->dest.h; sstr = READ_REG(PMScreenStride) * 2; stride = 0; for(i = 1; i < sizeof(ppcodes) / sizeof(ppcodes[0]); i++){ if((!stride) && (ppcodes[i][0] >= src_w)){ stride = ppcodes[i][0]; ppcode = ppcodes[i][1]; pitch = ppcodes[i][0] - ppcodes[i-1][0]; } if(ppcodes[i][0] == sstr) sppc = ppcodes[i][1]; } if(!stride) return -1; info->num_frames = pm2_vidmem*1024*1024 / (stride * src_h * 2); if(info->num_frames > VID_PLAY_MAXFRAMES) info->num_frames = VID_PLAY_MAXFRAMES; /* Use end of video memory. Assume the card has 8 MB */ base0 = (8 - pm2_vidmem)*1024*1024; info->dga_addr = pm2_mem + base0; info->dest.pitch.y = pitch*2; info->dest.pitch.u = 0; info->dest.pitch.v = 0; info->offset.y = 0; info->offset.v = 0; info->offset.u = 0; info->frame_size = stride * src_h * 2; for(i = 0; i < info->num_frames; i++){ info->offsets[i] = info->frame_size * i; frames[i] = (base0 + info->offsets[i]) >> 1; } WRITE_REG(WindowOrigin, 0); WRITE_REG(dY, 1 << 16); WRITE_REG(RasterizerMode, 0); WRITE_REG(ScissorMode, 0); WRITE_REG(AreaStippleMode, 0); WRITE_REG(StencilMode, 0); WRITE_REG(TextureAddressMode, 1); WRITE_REG(dSdyDom, 0); WRITE_REG(dTdx, 0); WRITE_REG(PMTextureMapFormat, (1 << 19) | ppcode); WRITE_REG(PMTextureDataFormat, format); WRITE_REG(PMTextureReadMode, (1 << 17) | /* FilterMode */ (11 << 13) | (11 << 9) /* TextureSize log2 */ | 1); WRITE_REG(ColorDDAMode, 0); WRITE_REG(TextureColorMode, (0 << 4) /* RGB */ | (3 << 1) /* Copy */ | 1); WRITE_REG(AlphaBlendMode, 0); WRITE_REG(DitherMode, (1 << 10) | 1); WRITE_REG(LogicalOpMode, 0); WRITE_REG(FBReadMode, sppc); WRITE_REG(FBHardwareWriteMask, 0xFFFFFFFF); WRITE_REG(FBWriteMode, 1); WRITE_REG(YUVMode, 1); WRITE_REG(SStart, 0); WRITE_REG(TStart, 0); WRITE_REG(dSdx, (src_w << 20) / drw_w); WRITE_REG(dTdyDom, (src_h << 20) / drw_h); WRITE_REG(RectangleOrigin, info->dest.x | (info->dest.y << 16)); WRITE_REG(RectangleSize, (drw_h << 16) | drw_w); TRACE_EXIT(); return 0; } int VIDIX_NAME(vixPlaybackOn)(void) { TRACE_ENTER(); TRACE_EXIT(); return 0; } int VIDIX_NAME(vixPlaybackOff)(void) { WRITE_REG(YUVMode, 0); WRITE_REG(TextureColorMode, 0); WRITE_REG(TextureAddressMode, 0); WRITE_REG(TextureReadMode, 0); return 0; } int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned int frame) { WRITE_REG(PMTextureBaseAddress, frames[frame]); WRITE_REG(Render, PrimitiveRectangle | XPositive | YPositive | TextureEnable); return 0; } xine-lib-1.2/contrib/vidix/drivers/radeon_vid.c0000644000175000017500000033565714647725152017426 0ustar meme/* radeon_vid - VIDIX based video driver for Radeon and Rage128 chips Copyrights 2002 Nick Kurshev. This file is based on sources from GATOS (gatos.sf.net) and X11 (www.xfree86.org) Licence: GPL */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include "bswap.h" #include "pci_ids.h" #include "pci_names.h" #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "radeon.h" #ifdef RAGE128 #define RADEON_MSG "[rage128]" #define X_ADJUST 0 #else #define RADEON_MSG "[radeon]" #define X_ADJUST (((besr.chip_flags&R_OVL_SHIFT)==R_OVL_SHIFT)?8:0) #ifndef RADEON #define RADEON #endif #endif #define RADEON_ASSERT(msg) printf(RADEON_MSG"################# FATAL:"msg); #ifdef RAGE128 #define VIDIX_STATIC rage128_ #else #define VIDIX_STATIC radeo_ #endif //#undef RADEON_ENABLE_BM /* unfinished stuff. May corrupt your filesystem ever */ #define RADEON_ENABLE_BM 1 #ifdef RADEON_ENABLE_BM static void * radeon_dma_desc_base = 0; static unsigned long bus_addr_dma_desc = 0; static unsigned long *dma_phys_addrs = 0; #pragma pack(1) typedef struct { uint32_t framebuf_offset; uint32_t sys_addr; uint32_t command; uint32_t reserved; } bm_list_descriptor; #pragma pack() #endif #define VERBOSE_LEVEL 0 static int __verbose = 0; typedef struct bes_registers_s { /* base address of yuv framebuffer */ uint32_t yuv_base; uint32_t fourcc; uint32_t surf_id; int load_prg_start; int horz_pick_nearest; int vert_pick_nearest; int swap_uv; /* for direct support of bgr fourccs */ uint32_t dest_bpp; /* YUV BES registers */ uint32_t reg_load_cntl; uint32_t h_inc; uint32_t step_by; uint32_t y_x_start; uint32_t y_x_end; uint32_t v_inc; uint32_t p1_blank_lines_at_top; uint32_t p23_blank_lines_at_top; uint32_t vid_buf_pitch0_value; uint32_t vid_buf_pitch1_value; uint32_t p1_x_start_end; uint32_t p2_x_start_end; uint32_t p3_x_start_end; uint32_t base_addr; uint32_t vid_buf_base_adrs_y[VID_PLAY_MAXFRAMES]; uint32_t vid_buf_base_adrs_u[VID_PLAY_MAXFRAMES]; uint32_t vid_buf_base_adrs_v[VID_PLAY_MAXFRAMES]; uint32_t vid_nbufs; uint32_t p1_v_accum_init; uint32_t p1_h_accum_init; uint32_t p23_v_accum_init; uint32_t p23_h_accum_init; uint32_t scale_cntl; uint32_t exclusive_horz; uint32_t auto_flip_cntl; uint32_t filter_cntl; uint32_t four_tap_coeff[5]; uint32_t key_cntl; uint32_t test; /* Configurable stuff */ int double_buff; int brightness; int saturation; uint32_t graphics_key_clr; uint32_t graphics_key_msk; uint32_t ckey_cntl; int deinterlace_on; uint32_t deinterlace_pattern; unsigned chip_flags; } bes_registers_t; typedef struct video_registers_s { const char * sname; uint32_t name; uint32_t value; }video_registers_t; static bes_registers_t besr; #define DECLARE_VREG(name) { #name, name, 0 } static video_registers_t vregs[] = { DECLARE_VREG(VIDEOMUX_CNTL), DECLARE_VREG(VIPPAD_MASK), DECLARE_VREG(VIPPAD1_A), DECLARE_VREG(VIPPAD1_EN), DECLARE_VREG(VIPPAD1_Y), DECLARE_VREG(OV0_Y_X_START), DECLARE_VREG(OV0_Y_X_END), DECLARE_VREG(OV0_PIPELINE_CNTL), DECLARE_VREG(OV0_EXCLUSIVE_HORZ), DECLARE_VREG(OV0_EXCLUSIVE_VERT), DECLARE_VREG(OV0_REG_LOAD_CNTL), DECLARE_VREG(OV0_SCALE_CNTL), DECLARE_VREG(OV0_V_INC), DECLARE_VREG(OV0_P1_V_ACCUM_INIT), DECLARE_VREG(OV0_P23_V_ACCUM_INIT), DECLARE_VREG(OV0_P1_BLANK_LINES_AT_TOP), DECLARE_VREG(OV0_P23_BLANK_LINES_AT_TOP), #ifdef RADEON DECLARE_VREG(OV0_BASE_ADDR), #endif DECLARE_VREG(OV0_VID_BUF0_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF1_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF2_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF3_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF4_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF5_BASE_ADRS), DECLARE_VREG(OV0_VID_BUF_PITCH0_VALUE), DECLARE_VREG(OV0_VID_BUF_PITCH1_VALUE), DECLARE_VREG(OV0_AUTO_FLIP_CNTL), DECLARE_VREG(OV0_DEINTERLACE_PATTERN), DECLARE_VREG(OV0_SUBMIT_HISTORY), DECLARE_VREG(OV0_H_INC), DECLARE_VREG(OV0_STEP_BY), DECLARE_VREG(OV0_P1_H_ACCUM_INIT), DECLARE_VREG(OV0_P23_H_ACCUM_INIT), DECLARE_VREG(OV0_P1_X_START_END), DECLARE_VREG(OV0_P2_X_START_END), DECLARE_VREG(OV0_P3_X_START_END), DECLARE_VREG(OV0_FILTER_CNTL), DECLARE_VREG(OV0_FOUR_TAP_COEF_0), DECLARE_VREG(OV0_FOUR_TAP_COEF_1), DECLARE_VREG(OV0_FOUR_TAP_COEF_2), DECLARE_VREG(OV0_FOUR_TAP_COEF_3), DECLARE_VREG(OV0_FOUR_TAP_COEF_4), DECLARE_VREG(OV0_FLAG_CNTL), #ifdef RAGE128 DECLARE_VREG(OV0_COLOUR_CNTL), #else DECLARE_VREG(OV0_SLICE_CNTL), #endif DECLARE_VREG(OV0_VID_KEY_CLR), DECLARE_VREG(OV0_VID_KEY_MSK), DECLARE_VREG(OV0_GRAPHICS_KEY_CLR), DECLARE_VREG(OV0_GRAPHICS_KEY_MSK), DECLARE_VREG(OV0_KEY_CNTL), DECLARE_VREG(OV0_TEST), DECLARE_VREG(OV0_LIN_TRANS_A), DECLARE_VREG(OV0_LIN_TRANS_B), DECLARE_VREG(OV0_LIN_TRANS_C), DECLARE_VREG(OV0_LIN_TRANS_D), DECLARE_VREG(OV0_LIN_TRANS_E), DECLARE_VREG(OV0_LIN_TRANS_F), DECLARE_VREG(OV0_GAMMA_0_F), DECLARE_VREG(OV0_GAMMA_10_1F), DECLARE_VREG(OV0_GAMMA_20_3F), DECLARE_VREG(OV0_GAMMA_40_7F), DECLARE_VREG(OV0_GAMMA_380_3BF), DECLARE_VREG(OV0_GAMMA_3C0_3FF), DECLARE_VREG(SUBPIC_CNTL), DECLARE_VREG(SUBPIC_DEFCOLCON), DECLARE_VREG(SUBPIC_Y_X_START), DECLARE_VREG(SUBPIC_Y_X_END), DECLARE_VREG(SUBPIC_V_INC), DECLARE_VREG(SUBPIC_H_INC), DECLARE_VREG(SUBPIC_BUF0_OFFSET), DECLARE_VREG(SUBPIC_BUF1_OFFSET), DECLARE_VREG(SUBPIC_LC0_OFFSET), DECLARE_VREG(SUBPIC_LC1_OFFSET), DECLARE_VREG(SUBPIC_PITCH), DECLARE_VREG(SUBPIC_BTN_HLI_COLCON), DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_START), DECLARE_VREG(SUBPIC_BTN_HLI_Y_X_END), DECLARE_VREG(SUBPIC_PALETTE_INDEX), DECLARE_VREG(SUBPIC_PALETTE_DATA), DECLARE_VREG(SUBPIC_H_ACCUM_INIT), DECLARE_VREG(SUBPIC_V_ACCUM_INIT), DECLARE_VREG(IDCT_RUNS), DECLARE_VREG(IDCT_LEVELS), DECLARE_VREG(IDCT_AUTH_CONTROL), DECLARE_VREG(IDCT_AUTH), DECLARE_VREG(IDCT_CONTROL), #ifdef RAGE128 DECLARE_VREG(BM_FRAME_BUF_OFFSET), DECLARE_VREG(BM_SYSTEM_MEM_ADDR), DECLARE_VREG(BM_COMMAND), DECLARE_VREG(BM_STATUS), DECLARE_VREG(BM_QUEUE_STATUS), DECLARE_VREG(BM_QUEUE_FREE_STATUS), DECLARE_VREG(BM_CHUNK_0_VAL), DECLARE_VREG(BM_CHUNK_1_VAL), DECLARE_VREG(BM_VIP0_BUF), DECLARE_VREG(BM_VIP0_ACTIVE), DECLARE_VREG(BM_VIP1_BUF), DECLARE_VREG(BM_VIP1_ACTIVE), DECLARE_VREG(BM_VIP2_BUF), DECLARE_VREG(BM_VIP2_ACTIVE), DECLARE_VREG(BM_VIP3_BUF), DECLARE_VREG(BM_VIP3_ACTIVE), DECLARE_VREG(BM_VIDCAP_BUF0), DECLARE_VREG(BM_VIDCAP_BUF1), DECLARE_VREG(BM_VIDCAP_BUF2), DECLARE_VREG(BM_VIDCAP_ACTIVE), DECLARE_VREG(BM_GUI), DECLARE_VREG(BM_ABORT) #else DECLARE_VREG(DMA_GUI_TABLE_ADDR), DECLARE_VREG(DMA_GUI_SRC_ADDR), DECLARE_VREG(DMA_GUI_DST_ADDR), DECLARE_VREG(DMA_GUI_COMMAND), DECLARE_VREG(DMA_GUI_STATUS), DECLARE_VREG(DMA_GUI_ACT_DSCRPTR), DECLARE_VREG(DMA_VID_SRC_ADDR), DECLARE_VREG(DMA_VID_DST_ADDR), DECLARE_VREG(DMA_VID_COMMAND), DECLARE_VREG(DMA_VID_STATUS), DECLARE_VREG(DMA_VID_ACT_DSCRPTR), #endif }; #define R_FAMILY 0x000000FF #define R_100 0x00000001 #define R_120 0x00000002 #define R_150 0x00000003 #define R_200 0x00000004 #define R_250 0x00000005 #define R_280 0x00000006 #define R_300 0x00000007 #define R_350 0x00000008 #define R_370 0x00000010 #define R_380 0x00000020 #define R_420 0x00000040 #define R_OVL_SHIFT 0x00000100 #define R_INTEGRATED 0x00000200 #define R_PCIE 0x00000400 typedef struct ati_card_ids_s { unsigned short id; unsigned flags; }ati_card_ids_t; static const ati_card_ids_t ati_card_ids[] = { #ifdef RAGE128 /* This driver should be compatible with Rage128 (pro) chips. (include adaptive deinterlacing!!!). Moreover: the same logic can be used with Mach64 chips. (I mean: mach64xx, 3d rage, 3d rage IIc, 3D rage pro, 3d rage mobility). but they are incompatible by i/o ports. So if enthusiasts will want then they can redefine OUTREG and INREG macros and redefine OV0_* constants. Also it seems that mach64 chips supports only: YUY2, YV12, UYVY fourccs (422 and 420 formats only). */ /* Rage128 Pro GL */ { DEVICE_ATI_RAGE_128_PA_PRO, 0 }, { DEVICE_ATI_RAGE_128_PB_PRO, 0 }, { DEVICE_ATI_RAGE_128_PC_PRO, 0 }, { DEVICE_ATI_RAGE_128_PD_PRO, 0 }, { DEVICE_ATI_RAGE_128_PE_PRO, 0 }, { DEVICE_ATI_RAGE_128_PF_PRO, 0 }, /* Rage128 Pro VR */ { DEVICE_ATI_RAGE_128_PG_PRO, 0 }, { DEVICE_ATI_RAGE_128_PH_PRO, 0 }, { DEVICE_ATI_RAGE_128_PI_PRO, 0 }, { DEVICE_ATI_RAGE_128_PJ_PRO, 0 }, { DEVICE_ATI_RAGE_128_PK_PRO, 0 }, { DEVICE_ATI_RAGE_128_PL_PRO, 0 }, { DEVICE_ATI_RAGE_128_PM_PRO, 0 }, { DEVICE_ATI_RAGE_128_PN_PRO, 0 }, { DEVICE_ATI_RAGE_128_PO_PRO, 0 }, { DEVICE_ATI_RAGE_128_PP_PRO, 0 }, { DEVICE_ATI_RAGE_128_PQ_PRO, 0 }, { DEVICE_ATI_RAGE_128_PR_PRO, 0 }, { DEVICE_ATI_RAGE_128_PS_PRO, 0 }, { DEVICE_ATI_RAGE_128_PT_PRO, 0 }, { DEVICE_ATI_RAGE_128_PU_PRO, 0 }, { DEVICE_ATI_RAGE_128_PV_PRO, 0 }, { DEVICE_ATI_RAGE_128_PW_PRO, 0 }, { DEVICE_ATI_RAGE_128_PX_PRO, 0 }, /* Rage128 GL */ { DEVICE_ATI_RAGE_128_RE_SG, 0 }, { DEVICE_ATI_RAGE_128_RF_SG, 0 }, { DEVICE_ATI_RAGE_128_RG, 0 }, { DEVICE_ATI_RAGE_128_RK_VR, 0 }, { DEVICE_ATI_RAGE_128_RL_VR, 0 }, { DEVICE_ATI_RAGE_128_SE_4X, 0 }, { DEVICE_ATI_RAGE_128_SF_4X, 0 }, { DEVICE_ATI_RAGE_128_SG_4X, 0 }, { DEVICE_ATI_RAGE_128_SH, 0 }, { DEVICE_ATI_RAGE_128_SK_4X, 0 }, { DEVICE_ATI_RAGE_128_SL_4X, 0 }, { DEVICE_ATI_RAGE_128_SM_4X, 0 }, { DEVICE_ATI_RAGE_128_4X, 0 }, { DEVICE_ATI_RAGE_128_PRO, 0 }, { DEVICE_ATI_RAGE_128_PRO2, 0 }, { DEVICE_ATI_RAGE_128_PRO3, 0 }, /* these seem to be based on rage 128 instead of mach64 */ { DEVICE_ATI_RAGE_MOBILITY_M3, 0 }, { DEVICE_ATI_RAGE_MOBILITY_M32, 0 }, #else /* Radeon1 (indeed: Rage 256 Pro ;) */ { DEVICE_ATI_RADEON_R100_QD, R_100|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_R100_QE, R_100|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_R100_QF, R_100|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_R100_QG, R_100|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_IGP_320, R_150|R_OVL_SHIFT|R_INTEGRATED }, { DEVICE_ATI_RADEON_MOBILITY_U1, R_150|R_OVL_SHIFT|R_INTEGRATED }, { DEVICE_ATI_RADEON_RV100_QY, R_120|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_RV100_QZ, R_120|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_MOBILITY_M7, R_150|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_RV200_LX, R_150|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_MOBILITY_M6, R_120|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_MOBILITY_M62, R_120|R_OVL_SHIFT }, /* Radeon2 (indeed: Rage 512 Pro ;) */ { DEVICE_ATI_R200_BB_RADEON, R_200 }, { DEVICE_ATI_R200_BC_RADEON, R_200 }, { DEVICE_ATI_RADEON_R200_QH, R_200 }, { DEVICE_ATI_RADEON_R200_QI, R_200 }, { DEVICE_ATI_RADEON_R200_QJ, R_200 }, { DEVICE_ATI_RADEON_R200_QK, R_200 }, { DEVICE_ATI_RADEON_R200_QL, R_200 }, { DEVICE_ATI_RADEON_R200_QM, R_200 }, { DEVICE_ATI_RADEON_R200_QN, R_200 }, { DEVICE_ATI_RADEON_R200_QO, R_200 }, { DEVICE_ATI_RADEON_R200_QH2, R_200 }, { DEVICE_ATI_RADEON_R200_QI2, R_200 }, { DEVICE_ATI_RADEON_R200_QJ2, R_200 }, { DEVICE_ATI_RADEON_R200_QK2, R_200 }, { DEVICE_ATI_RADEON_R200_QL2, R_200 }, { DEVICE_ATI_RADEON_RV200_QW, R_150|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_RV200_QX, R_150|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_IGP330_340_350,R_200|R_INTEGRATED }, { DEVICE_ATI_RADEON_IGP_330M_340M_350M,R_200|R_INTEGRATED }, { DEVICE_ATI_RADEON_RV250_IG, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_7000_IGP, R_250|R_OVL_SHIFT|R_INTEGRATED }, { DEVICE_ATI_RADEON_MOBILITY_7000, R_250|R_OVL_SHIFT|R_INTEGRATED }, { DEVICE_ATI_RADEON_RV250_ID, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_RV250_IE, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_RV250_IF, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_RV250_IG, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_R250_LD, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_R250_LE, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_R250_LF, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RADEON_R250_LG, R_250|R_OVL_SHIFT }, { DEVICE_ATI_RV280_RADEON_92003, R_280 }, { DEVICE_ATI_RV280_RADEON_92004, R_280 }, { DEVICE_ATI_RV280_RADEON_92005, R_280 }, /* Radeon3 (indeed: Rage 1024 Pro ;) */ { DEVICE_ATI_R300_AG_FIREGL, R_300 }, { DEVICE_ATI_RADEON_R300_ND, R_300 }, { DEVICE_ATI_RADEON_R300_NE, R_300 }, { DEVICE_ATI_RADEON_R300_NG, R_300 }, { DEVICE_ATI_R300_AD_RADEON, R_300 }, { DEVICE_ATI_R300_AE_RADEON, R_300 }, { DEVICE_ATI_R300_AF_RADEON, R_300 }, { DEVICE_ATI_RADEON_9100_IGP2, R_300|R_OVL_SHIFT|R_INTEGRATED }, { DEVICE_ATI_RS300M_AGP_RADEON, R_300|R_INTEGRATED }, { DEVICE_ATI_R350_AH_RADEON, R_350 }, { DEVICE_ATI_R350_AI_RADEON, R_350 }, { DEVICE_ATI_R350_AJ_RADEON, R_350 }, { DEVICE_ATI_R350_AK_FIRE, R_350 }, { DEVICE_ATI_RADEON_R350_RADEON2, R_350 }, { DEVICE_ATI_RADEON_R350_RADEON3, R_350 }, { DEVICE_ATI_RV350_NJ_RADEON, R_350 }, { DEVICE_ATI_R350_NK_FIRE, R_350 }, { DEVICE_ATI_RV350_AP_RADEON, R_350 }, { DEVICE_ATI_RV350_AQ_RADEON, R_350 }, { DEVICE_ATI_RV350_AR_RADEON, R_350 }, { DEVICE_ATI_RV350_AS_RADEON, R_350 }, { DEVICE_ATI_RV350_AT_FIRE, R_350 }, { DEVICE_ATI_RV350_AU_FIRE, R_350 }, { DEVICE_ATI_RV350_AV_FIRE, R_350 }, { DEVICE_ATI_RV350_AW_FIRE, R_350 }, { DEVICE_ATI_RV350_MOBILITY_RADEON, R_350 }, { DEVICE_ATI_RV350_NF_RADEON, R_300 }, { DEVICE_ATI_RV350_NJ_RADEON, R_300 }, { DEVICE_ATI_M10_NQ_RADEON, R_350 }, { DEVICE_ATI_RV350_MOBILITY_RADEON2, R_350 }, { DEVICE_ATI_M10_NS_RADEON, R_350 }, { DEVICE_ATI_M10_NT_FIREGL, R_350 }, { DEVICE_ATI_M11_NV_FIREGL, R_350 }, { DEVICE_ATI_RV370_5B60_RADEON, R_370|R_PCIE }, { DEVICE_ATI_RV370_5B62_RADEON, R_370|R_PCIE }, { DEVICE_ATI_RV370_5B64_FIREGL, R_370|R_PCIE }, { DEVICE_ATI_RV370_5B65_FIREGL, R_370|R_PCIE }, { DEVICE_ATI_RV380_0X3E50_RADEON, R_380|R_PCIE }, { DEVICE_ATI_RV380_0X3E54_FIREGL, R_380|R_PCIE }, { DEVICE_ATI_RV380_RADEON_X600, R_380|R_PCIE }, { DEVICE_ATI_R420_JH_RADEON, R_420|R_PCIE }, { DEVICE_ATI_R420_JI_RADEON, R_420|R_PCIE }, { DEVICE_ATI_R420_JJ_RADEON, R_420|R_PCIE }, { DEVICE_ATI_R420_JK_RADEON, R_420|R_PCIE }, { DEVICE_ATI_R420_JL_RADEON, R_420|R_PCIE }, { DEVICE_ATI_R420_JM_FIREGL, R_420|R_PCIE }, { DEVICE_ATI_M18_JN_RADEON, R_420|R_PCIE }, { DEVICE_ATI_R420_JP_RADEON, R_420|R_PCIE }, { DEVICE_ATI_R420_JM_FIREGL, R_420|R_PCIE }, { DEVICE_ATI_R423_5F57_RADEON, R_420|R_PCIE } #endif }; static void * radeon_mmio_base = 0; static void * radeon_mem_base = 0; static int32_t radeon_overlay_off = 0; static uint32_t radeon_ram_size = 0; #define GETREG(TYPE,PTR,OFFZ) (*((volatile TYPE*)((PTR)+(OFFZ)))) #define SETREG(TYPE,PTR,OFFZ,VAL) (*((volatile TYPE*)((PTR)+(OFFZ))))=VAL #define INREG8(addr) GETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr) #define OUTREG8(addr,val) SETREG(uint8_t,(uint32_t)(radeon_mmio_base),addr,val) static inline uint32_t INREG (uint32_t addr) { uint32_t tmp = GETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr); return le2me_32(tmp); } #define OUTREG(addr,val) SETREG(uint32_t,(uint32_t)(radeon_mmio_base),addr,le2me_32(val)) #define OUTREGP(addr,val,mask) \ do { \ unsigned int _tmp = INREG(addr); \ _tmp &= (mask); \ _tmp |= (val); \ OUTREG(addr, _tmp); \ } while (0) static __inline__ uint32_t INPLL(uint32_t addr) { OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000001f); return (INREG(CLOCK_CNTL_DATA)); } #define OUTPLL(addr,val) OUTREG8(CLOCK_CNTL_INDEX, (addr & 0x0000001f) | 0x00000080); \ OUTREG(CLOCK_CNTL_DATA, val) #define OUTPLLP(addr,val,mask) \ do { \ unsigned int _tmp = INPLL(addr); \ _tmp &= (mask); \ _tmp |= (val); \ OUTPLL(addr, _tmp); \ } while (0) static uint32_t radeon_vid_get_dbpp( void ) { uint32_t dbpp,retval; dbpp = (INREG(CRTC_GEN_CNTL)>>8)& 0xF; switch(dbpp) { case DST_8BPP: retval = 8; break; case DST_15BPP: retval = 15; break; case DST_16BPP: retval = 16; break; case DST_24BPP: retval = 24; break; default: retval=32; break; } return retval; } static int radeon_is_dbl_scan( void ) { return (INREG(CRTC_GEN_CNTL))&CRTC_DBL_SCAN_EN; } static int radeon_is_interlace( void ) { return (INREG(CRTC_GEN_CNTL))&CRTC_INTERLACE_EN; } static uint32_t radeon_get_xres( void ) { /* FIXME: currently we extract that from CRTC!!!*/ uint32_t xres,h_total; h_total = INREG(CRTC_H_TOTAL_DISP); xres = (h_total >> 16) & 0xffff; return (xres + 1)*8; } static uint32_t radeon_get_yres( void ) { /* FIXME: currently we extract that from CRTC!!!*/ uint32_t yres,v_total; v_total = INREG(CRTC_V_TOTAL_DISP); yres = (v_total >> 16) & 0xffff; return yres + 1; } static void radeon_wait_vsync(void) { int i; OUTREG(GEN_INT_STATUS, VSYNC_INT_AK); for (i = 0; i < 2000000; i++) { if (INREG(GEN_INT_STATUS) & VSYNC_INT) break; } } #ifdef RAGE128 static void _radeon_engine_idle(void); static void _radeon_fifo_wait(unsigned); #define radeon_engine_idle() _radeon_engine_idle() #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries) /* Flush all dirty data in the Pixel Cache to memory. */ static __inline__ void radeon_engine_flush ( void ) { unsigned i; OUTREGP(PC_NGUI_CTLSTAT, PC_FLUSH_ALL, ~PC_FLUSH_ALL); for (i = 0; i < 2000000; i++) { if (!(INREG(PC_NGUI_CTLSTAT) & PC_BUSY)) break; } } /* Reset graphics card to known state. */ static void radeon_engine_reset( void ) { uint32_t clock_cntl_index; uint32_t mclk_cntl; uint32_t gen_reset_cntl; radeon_engine_flush(); clock_cntl_index = INREG(CLOCK_CNTL_INDEX); mclk_cntl = INPLL(MCLK_CNTL); OUTPLL(MCLK_CNTL, mclk_cntl | FORCE_GCP | FORCE_PIPE3D_CP); gen_reset_cntl = INREG(GEN_RESET_CNTL); OUTREG(GEN_RESET_CNTL, gen_reset_cntl | SOFT_RESET_GUI); INREG(GEN_RESET_CNTL); OUTREG(GEN_RESET_CNTL, gen_reset_cntl & (uint32_t)(~SOFT_RESET_GUI)); INREG(GEN_RESET_CNTL); OUTPLL(MCLK_CNTL, mclk_cntl); OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); OUTREG(GEN_RESET_CNTL, gen_reset_cntl); } #else static __inline__ void radeon_engine_flush ( void ) { int i; /* initiate flush */ OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, ~RB2D_DC_FLUSH_ALL); for (i=0; i < 2000000; i++) { if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) break; } } static void _radeon_engine_idle(void); static void _radeon_fifo_wait(unsigned); #define radeon_engine_idle() _radeon_engine_idle() #define radeon_fifo_wait(entries) _radeon_fifo_wait(entries) static void radeon_engine_reset( void ) { uint32_t clock_cntl_index, mclk_cntl, rbbm_soft_reset; radeon_engine_flush (); clock_cntl_index = INREG(CLOCK_CNTL_INDEX); mclk_cntl = INPLL(MCLK_CNTL); OUTPLL(MCLK_CNTL, (mclk_cntl | FORCEON_MCLKA | FORCEON_MCLKB | FORCEON_YCLKA | FORCEON_YCLKB | FORCEON_MC | FORCEON_AIC)); rbbm_soft_reset = INREG(RBBM_SOFT_RESET); OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset | SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE | SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB | SOFT_RESET_HDP); INREG(RBBM_SOFT_RESET); OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset & (uint32_t) ~(SOFT_RESET_CP | SOFT_RESET_HI | SOFT_RESET_SE | SOFT_RESET_RE | SOFT_RESET_PP | SOFT_RESET_E2 | SOFT_RESET_RB | SOFT_RESET_HDP)); INREG(RBBM_SOFT_RESET); OUTPLL(MCLK_CNTL, mclk_cntl); OUTREG(CLOCK_CNTL_INDEX, clock_cntl_index); OUTREG(RBBM_SOFT_RESET, rbbm_soft_reset); return; } #endif static void radeon_engine_restore( void ) { #ifndef RAGE128 int pitch64; uint32_t xres,yres,bpp; radeon_fifo_wait(1); xres = radeon_get_xres(); yres = radeon_get_yres(); bpp = radeon_vid_get_dbpp(); /* turn of all automatic flushing - we'll do it all */ OUTREG(RB2D_DSTCACHE_MODE, 0); pitch64 = ((xres * (bpp / 8) + 0x3f)) >> 6; radeon_fifo_wait(1); OUTREG(DEFAULT_OFFSET, (INREG(DEFAULT_OFFSET) & 0xC0000000) | (pitch64 << 22)); radeon_fifo_wait(1); #if defined(WORDS_BIGENDIAN) OUTREGP(DP_DATATYPE, HOST_BIG_ENDIAN_EN, ~HOST_BIG_ENDIAN_EN); #else OUTREGP(DP_DATATYPE, 0, ~HOST_BIG_ENDIAN_EN); #endif radeon_fifo_wait(1); OUTREG(DEFAULT_SC_BOTTOM_RIGHT, (DEFAULT_SC_RIGHT_MAX | DEFAULT_SC_BOTTOM_MAX)); radeon_fifo_wait(1); OUTREG(DP_GUI_MASTER_CNTL, (INREG(DP_GUI_MASTER_CNTL) | GMC_BRUSH_SOLID_COLOR | GMC_SRC_DATATYPE_COLOR)); radeon_fifo_wait(7); OUTREG(DST_LINE_START, 0); OUTREG(DST_LINE_END, 0); OUTREG(DP_BRUSH_FRGD_CLR, 0xffffffff); OUTREG(DP_BRUSH_BKGD_CLR, 0x00000000); OUTREG(DP_SRC_FRGD_CLR, 0xffffffff); OUTREG(DP_SRC_BKGD_CLR, 0x00000000); OUTREG(DP_WRITE_MASK, 0xffffffff); radeon_engine_idle(); #endif } #ifdef RAGE128 static void _radeon_fifo_wait (unsigned entries) { unsigned i; for(;;) { for (i=0; i<2000000; i++) if ((INREG(GUI_STAT) & GUI_FIFOCNT_MASK) >= entries) return; radeon_engine_reset(); radeon_engine_restore(); } } static void _radeon_engine_idle ( void ) { unsigned i; /* ensure FIFO is empty before waiting for idle */ radeon_fifo_wait (64); for(;;) { for (i=0; i<2000000; i++) { if ((INREG(GUI_STAT) & GUI_ACTIVE) == 0) { radeon_engine_flush (); return; } } radeon_engine_reset(); radeon_engine_restore(); } } #else static void _radeon_fifo_wait (unsigned entries) { unsigned i; for(;;) { for (i=0; i<2000000; i++) if ((INREG(RBBM_STATUS) & RBBM_FIFOCNT_MASK) >= entries) return; radeon_engine_reset(); radeon_engine_restore(); } } static void _radeon_engine_idle ( void ) { int i; /* ensure FIFO is empty before waiting for idle */ radeon_fifo_wait (64); for(;;) { for (i=0; i<2000000; i++) { if (((INREG(RBBM_STATUS) & RBBM_ACTIVE)) == 0) { radeon_engine_flush (); return; } } radeon_engine_reset(); radeon_engine_restore(); } } #endif #ifndef RAGE128 /* Reference color space transform data */ typedef struct tagREF_TRANSFORM { float RefLuma; float RefRCb; float RefRCr; float RefGCb; float RefGCr; float RefBCb; float RefBCr; } REF_TRANSFORM; /* Parameters for ITU-R BT.601 and ITU-R BT.709 colour spaces */ REF_TRANSFORM trans[2] = { {1.1678, 0.0, 1.6007, -0.3929, -0.8154, 2.0232, 0.0}, /* BT.601 */ {1.1678, 0.0, 1.7980, -0.2139, -0.5345, 2.1186, 0.0} /* BT.709 */ }; /**************************************************************************** * SetTransform * * Function: Calculates and sets color space transform from supplied * * reference transform, gamma, brightness, contrast, hue and * * saturation. * * Inputs: bright - brightness * * cont - contrast * * sat - saturation * * hue - hue * * red_intensity - intense of red component * * green_intensity - intense of green component * * blue_intensity - intense of blue component * * ref - index to the table of refernce transforms * * Outputs: NONE * ****************************************************************************/ static void radeon_set_transform(float bright, float cont, float sat, float hue, float red_intensity, float green_intensity,float blue_intensity, unsigned ref) { float OvHueSin, OvHueCos; float CAdjLuma, CAdjOff; float RedAdj,GreenAdj,BlueAdj; float CAdjRCb, CAdjRCr; float CAdjGCb, CAdjGCr; float CAdjBCb, CAdjBCr; float OvLuma, OvROff, OvGOff, OvBOff; float OvRCb, OvRCr; float OvGCb, OvGCr; float OvBCb, OvBCr; float Loff = 64.0; float Coff = 512.0f; uint32_t dwOvLuma, dwOvROff, dwOvGOff, dwOvBOff; uint32_t dwOvRCb, dwOvRCr; uint32_t dwOvGCb, dwOvGCr; uint32_t dwOvBCb, dwOvBCr; if (ref >= 2) return; OvHueSin = sin((double)hue); OvHueCos = cos((double)hue); CAdjLuma = cont * trans[ref].RefLuma; CAdjOff = cont * trans[ref].RefLuma * bright * 1023.0; RedAdj = cont * trans[ref].RefLuma * red_intensity * 1023.0; GreenAdj = cont * trans[ref].RefLuma * green_intensity * 1023.0; BlueAdj = cont * trans[ref].RefLuma * blue_intensity * 1023.0; CAdjRCb = sat * -OvHueSin * trans[ref].RefRCr; CAdjRCr = sat * OvHueCos * trans[ref].RefRCr; CAdjGCb = sat * (OvHueCos * trans[ref].RefGCb - OvHueSin * trans[ref].RefGCr); CAdjGCr = sat * (OvHueSin * trans[ref].RefGCb + OvHueCos * trans[ref].RefGCr); CAdjBCb = sat * OvHueCos * trans[ref].RefBCb; CAdjBCr = sat * OvHueSin * trans[ref].RefBCb; #if 0 /* default constants */ CAdjLuma = 1.16455078125; CAdjRCb = 0.0; CAdjRCr = 1.59619140625; CAdjGCb = -0.39111328125; CAdjGCr = -0.8125; CAdjBCb = 2.01708984375; CAdjBCr = 0; #endif OvLuma = CAdjLuma; OvRCb = CAdjRCb; OvRCr = CAdjRCr; OvGCb = CAdjGCb; OvGCr = CAdjGCr; OvBCb = CAdjBCb; OvBCr = CAdjBCr; OvROff = RedAdj + CAdjOff - OvLuma * Loff - (OvRCb + OvRCr) * Coff; OvGOff = GreenAdj + CAdjOff - OvLuma * Loff - (OvGCb + OvGCr) * Coff; OvBOff = BlueAdj + CAdjOff - OvLuma * Loff - (OvBCb + OvBCr) * Coff; #if 0 /* default constants */ OvROff = -888.5; OvGOff = 545; OvBOff = -1104; #endif dwOvROff = ((int)(OvROff * 2.0)) & 0x1fff; dwOvGOff = (int)(OvGOff * 2.0) & 0x1fff; dwOvBOff = (int)(OvBOff * 2.0) & 0x1fff; /* Whatever docs say about R200 having 3.8 format instead of 3.11 as in Radeon is a lie */ #if 0 if(!IsR200) { #endif dwOvLuma =(((int)(OvLuma * 2048.0))&0x7fff)<<17; dwOvRCb = (((int)(OvRCb * 2048.0))&0x7fff)<<1; dwOvRCr = (((int)(OvRCr * 2048.0))&0x7fff)<<17; dwOvGCb = (((int)(OvGCb * 2048.0))&0x7fff)<<1; dwOvGCr = (((int)(OvGCr * 2048.0))&0x7fff)<<17; dwOvBCb = (((int)(OvBCb * 2048.0))&0x7fff)<<1; dwOvBCr = (((int)(OvBCr * 2048.0))&0x7fff)<<17; #if 0 } else { dwOvLuma = (((int)(OvLuma * 256.0))&0x7ff)<<20; dwOvRCb = (((int)(OvRCb * 256.0))&0x7ff)<<4; dwOvRCr = (((int)(OvRCr * 256.0))&0x7ff)<<20; dwOvGCb = (((int)(OvGCb * 256.0))&0x7ff)<<4; dwOvGCr = (((int)(OvGCr * 256.0))&0x7ff)<<20; dwOvBCb = (((int)(OvBCb * 256.0))&0x7ff)<<4; dwOvBCr = (((int)(OvBCr * 256.0))&0x7ff)<<20; } #endif OUTREG(OV0_LIN_TRANS_A, dwOvRCb | dwOvLuma); OUTREG(OV0_LIN_TRANS_B, dwOvROff | dwOvRCr); OUTREG(OV0_LIN_TRANS_C, dwOvGCb | dwOvLuma); OUTREG(OV0_LIN_TRANS_D, dwOvGOff | dwOvGCr); OUTREG(OV0_LIN_TRANS_E, dwOvBCb | dwOvLuma); OUTREG(OV0_LIN_TRANS_F, dwOvBOff | dwOvBCr); } /* Gamma curve definition */ typedef struct { unsigned int gammaReg; unsigned int gammaSlope; unsigned int gammaOffset; }GAMMA_SETTINGS; /* Recommended gamma curve parameters */ GAMMA_SETTINGS r200_def_gamma[18] = { {OV0_GAMMA_0_F, 0x100, 0x0000}, {OV0_GAMMA_10_1F, 0x100, 0x0020}, {OV0_GAMMA_20_3F, 0x100, 0x0040}, {OV0_GAMMA_40_7F, 0x100, 0x0080}, {OV0_GAMMA_80_BF, 0x100, 0x0100}, {OV0_GAMMA_C0_FF, 0x100, 0x0100}, {OV0_GAMMA_100_13F, 0x100, 0x0200}, {OV0_GAMMA_140_17F, 0x100, 0x0200}, {OV0_GAMMA_180_1BF, 0x100, 0x0300}, {OV0_GAMMA_1C0_1FF, 0x100, 0x0300}, {OV0_GAMMA_200_23F, 0x100, 0x0400}, {OV0_GAMMA_240_27F, 0x100, 0x0400}, {OV0_GAMMA_280_2BF, 0x100, 0x0500}, {OV0_GAMMA_2C0_2FF, 0x100, 0x0500}, {OV0_GAMMA_300_33F, 0x100, 0x0600}, {OV0_GAMMA_340_37F, 0x100, 0x0600}, {OV0_GAMMA_380_3BF, 0x100, 0x0700}, {OV0_GAMMA_3C0_3FF, 0x100, 0x0700} }; GAMMA_SETTINGS r100_def_gamma[6] = { {OV0_GAMMA_0_F, 0x100, 0x0000}, {OV0_GAMMA_10_1F, 0x100, 0x0020}, {OV0_GAMMA_20_3F, 0x100, 0x0040}, {OV0_GAMMA_40_7F, 0x100, 0x0080}, {OV0_GAMMA_380_3BF, 0x100, 0x0100}, {OV0_GAMMA_3C0_3FF, 0x100, 0x0100} }; static void make_default_gamma_correction( void ) { size_t i; if((besr.chip_flags & R_100)==R_100|| (besr.chip_flags & R_120)==R_120|| (besr.chip_flags & R_150)==R_150){ OUTREG(OV0_LIN_TRANS_A, 0x12A00000); OUTREG(OV0_LIN_TRANS_B, 0x199018FE); OUTREG(OV0_LIN_TRANS_C, 0x12A0F9B0); OUTREG(OV0_LIN_TRANS_D, 0xF2F0043B); OUTREG(OV0_LIN_TRANS_E, 0x12A02050); OUTREG(OV0_LIN_TRANS_F, 0x0000174E); for(i=0; i<6; i++){ OUTREG(r100_def_gamma[i].gammaReg, (r100_def_gamma[i].gammaSlope<<16) | r100_def_gamma[i].gammaOffset); } } else{ OUTREG(OV0_LIN_TRANS_A, 0x12a20000); OUTREG(OV0_LIN_TRANS_B, 0x198a190e); OUTREG(OV0_LIN_TRANS_C, 0x12a2f9da); OUTREG(OV0_LIN_TRANS_D, 0xf2fe0442); OUTREG(OV0_LIN_TRANS_E, 0x12a22046); OUTREG(OV0_LIN_TRANS_F, 0x175f); /* Default Gamma, Of 18 segments for gamma cure, all segments in R200 are programmable, while only lower 4 and upper 2 segments are programmable in Radeon*/ for(i=0; i<18; i++){ OUTREG(r200_def_gamma[i].gammaReg, (r200_def_gamma[i].gammaSlope<<16) | r200_def_gamma[i].gammaOffset); } } } #endif static void radeon_vid_make_default(void) { #ifdef RAGE128 besr.saturation = 0x0F; besr.brightness = 0; OUTREG(OV0_COLOUR_CNTL,0x000F0F00UL); /* Default brihgtness and saturation for Rage128 */ #else make_default_gamma_correction(); #endif besr.deinterlace_pattern = 0x900AAAAA; OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern); besr.deinterlace_on=1; besr.double_buff=1; besr.graphics_key_msk=0; besr.graphics_key_clr=0; besr.ckey_cntl = VIDEO_KEY_FN_TRUE|GRAPHIC_KEY_FN_TRUE|CMP_MIX_AND; } unsigned VIDIX_NAME(vixGetVersion)( void ) { return VIDIX_VERSION; } static int find_chip(unsigned chip_id) { unsigned i; for(i = 0;i < sizeof(ati_card_ids)/sizeof(ati_card_ids_t);i++) { if(chip_id == ati_card_ids[i].id) return i; } return -1; } static pciinfo_t pci_info; static int probed=0; vidix_capability_t def_cap = { #ifdef RAGE128 "BES driver for rage128 cards", #else "BES driver for radeon cards", #endif "Nick Kurshev", TYPE_OUTPUT | TYPE_FX, { 0, 0, 0, 0 }, 2048, 2048, 4, 4, -1, FLAG_UPSCALER | FLAG_DOWNSCALER | FLAG_EQUALIZER, VENDOR_ATI, 0, { 0, 0, 0, 0} }; int VIDIX_NAME(vixProbe)( int verbose,int force ) { pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; __verbose = verbose; err = pci_scan(lst,&num_pci); if(err) { printf(RADEON_MSG" Error occured during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0;i PROBE_NORMAL) { printf(RADEON_MSG" Driver was forced. Was found %sknown chip\n",idx == -1 ? "un" : ""); if(idx == -1) #ifdef RAGE128 printf(RADEON_MSG" Assuming it as Rage128\n"); #else printf(RADEON_MSG" Assuming it as Radeon1\n"); #endif besr.chip_flags=R_100|R_OVL_SHIFT; } if(idx != -1) besr.chip_flags=ati_card_ids[idx].flags; def_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info,&lst[i],sizeof(pciinfo_t)); probed=1; break; } } } if(err && verbose) printf(RADEON_MSG" Can't find chip\n"); return err; } #ifndef RAGE128 enum radeon_montype { MT_NONE, MT_CRT, /* CRT-(cathode ray tube) analog monitor. (15-pin VGA connector) */ MT_LCD, /* Liquid Crystal Display */ MT_DFP, /* DFP-digital flat panel monitor. (24-pin DVI-I connector) */ MT_CTV, /* Composite TV out (not in VE) */ MT_STV /* S-Video TV out (probably in VE only) */ }; typedef struct radeon_info_s { int hasCRTC2; int crtDispType; int dviDispType; }rinfo_t; static rinfo_t rinfo; static const char * GET_MON_NAME(int type) { const char *pret; switch(type) { case MT_NONE: pret = "no"; break; case MT_CRT: pret = "CRT"; break; case MT_DFP: pret = "DFP"; break; case MT_LCD: pret = "LCD"; break; case MT_CTV: pret = "CTV"; break; case MT_STV: pret = "STV"; break; default: pret = "Unknown"; } return pret; } static void radeon_get_moninfo (rinfo_t *rinfo) { unsigned int tmp; tmp = INREG(RADEON_BIOS_4_SCRATCH); if (rinfo->hasCRTC2) { /* primary DVI port */ if (tmp & 0x08) rinfo->dviDispType = MT_DFP; else if (tmp & 0x4) rinfo->dviDispType = MT_LCD; else if (tmp & 0x200) rinfo->dviDispType = MT_CRT; else if (tmp & 0x10) rinfo->dviDispType = MT_CTV; else if (tmp & 0x20) rinfo->dviDispType = MT_STV; /* secondary CRT port */ if (tmp & 0x2) rinfo->crtDispType = MT_CRT; else if (tmp & 0x800) rinfo->crtDispType = MT_DFP; else if (tmp & 0x400) rinfo->crtDispType = MT_LCD; else if (tmp & 0x1000) rinfo->crtDispType = MT_CTV; else if (tmp & 0x2000) rinfo->crtDispType = MT_STV; } else { rinfo->dviDispType = MT_NONE; tmp = INREG(FP_GEN_CNTL); if (tmp & FP_EN_TMDS) rinfo->crtDispType = MT_DFP; else rinfo->crtDispType = MT_CRT; } } #endif typedef struct saved_regs_s { uint32_t ov0_vid_key_clr; uint32_t ov0_vid_key_msk; uint32_t ov0_graphics_key_clr; uint32_t ov0_graphics_key_msk; uint32_t ov0_key_cntl; }saved_regs_t; static saved_regs_t savreg; static void save_regs( void ) { radeon_fifo_wait(6); savreg.ov0_vid_key_clr = INREG(OV0_VID_KEY_CLR); savreg.ov0_vid_key_msk = INREG(OV0_VID_KEY_MSK); savreg.ov0_graphics_key_clr = INREG(OV0_GRAPHICS_KEY_CLR); savreg.ov0_graphics_key_msk = INREG(OV0_GRAPHICS_KEY_MSK); savreg.ov0_key_cntl = INREG(OV0_KEY_CNTL); } static void restore_regs( void ) { radeon_fifo_wait(6); OUTREG(OV0_VID_KEY_CLR,savreg.ov0_vid_key_clr); OUTREG(OV0_VID_KEY_MSK,savreg.ov0_vid_key_msk); OUTREG(OV0_GRAPHICS_KEY_CLR,savreg.ov0_graphics_key_clr); OUTREG(OV0_GRAPHICS_KEY_MSK,savreg.ov0_graphics_key_msk); OUTREG(OV0_KEY_CNTL,savreg.ov0_key_cntl); } int VIDIX_NAME(vixInit)( const char *args ) { int err; (void)args; if(!probed) { printf(RADEON_MSG" Driver was not probed but is being initializing\n"); return EINTR; } if((radeon_mmio_base = map_phys_mem(pci_info.base2,0xFFFF))==(void *)-1) return ENOMEM; radeon_ram_size = INREG(CONFIG_MEMSIZE); /* mem size is bits [28:0], mask off the rest. Range: from 1Mb up to 512 Mb */ radeon_ram_size &= CONFIG_MEMSIZE_MASK; #ifdef RADEON /* according to XFree86 4.2.0, some production M6's return 0 for 8MB */ if (radeon_ram_size == 0 && (def_cap.device_id == DEVICE_ATI_RADEON_MOBILITY_M6 || def_cap.device_id == DEVICE_ATI_RADEON_MOBILITY_M62)) { printf(RADEON_MSG" Workarounding buggy Radeon Mobility M6 (0 vs. 8MB ram)\n"); radeon_ram_size = 8192*1024; } #else /* Rage Mobility (rage128) also has memsize bug */ if (radeon_ram_size == 0 && (def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M3 || def_cap.device_id == DEVICE_ATI_RAGE_MOBILITY_M32)) { printf(RADEON_MSG" Workarounding buggy Rage Mobility M3 (0 vs. 8MB ram)\n"); radeon_ram_size = 8192*1024; } #endif if((radeon_mem_base = map_phys_mem(pci_info.base0,radeon_ram_size))==(void *)-1) return ENOMEM; radeon_vid_make_default(); printf(RADEON_MSG" Video memory = %uMb\n",radeon_ram_size/0x100000); err = mtrr_set_type(pci_info.base0,radeon_ram_size,MTRR_TYPE_WRCOMB); if(!err) printf(RADEON_MSG" Set write-combining type of video memory\n"); #ifndef RAGE128 { memset(&rinfo,0,sizeof(rinfo_t)); if((besr.chip_flags&R_100) != R_100) rinfo.hasCRTC2 = 1; radeon_get_moninfo(&rinfo); if(rinfo.hasCRTC2) { printf(RADEON_MSG" DVI port has %s monitor connected\n",GET_MON_NAME(rinfo.dviDispType)); printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType)); } else printf(RADEON_MSG" CRT port has %s monitor connected\n",GET_MON_NAME(rinfo.crtDispType)); } #endif #ifdef RADEON_ENABLE_BM if(bm_open() == 0) { if((dma_phys_addrs = malloc(radeon_ram_size*sizeof(unsigned long)/4096)) != 0) def_cap.flags |= FLAG_DMA | FLAG_EQ_DMA; else printf(RADEON_MSG" Can't allocate temopary buffer for DMA\n"); } else if(__verbose) printf(RADEON_MSG" Can't initialize busmastering: %s\n",strerror(errno)); #endif save_regs(); return 0; } void VIDIX_NAME(vixDestroy)( void ) { restore_regs(); unmap_phys_mem(radeon_mem_base,radeon_ram_size); unmap_phys_mem(radeon_mmio_base,0xFFFF); bm_close(); } int VIDIX_NAME(vixGetCapability)(vidix_capability_t *to) { memcpy(to,&def_cap,sizeof(vidix_capability_t)); return 0; } /* Full list of fourcc which are supported by Win2K radeon driver: YUY2, UYVY, DDES, OGLT, OGL2, OGLS, OGLB, OGNT, OGNZ, OGNS, IF09, YVU9, IMC4, M2IA, IYUV, VBID, DXT1, DXT2, DXT3, DXT4, DXT5 */ typedef struct fourcc_desc_s { uint32_t fourcc; unsigned max_srcw; }fourcc_desc_t; fourcc_desc_t supported_fourcc[] = { { IMGFMT_Y800, 1567 }, { IMGFMT_YVU9, 1567 }, { IMGFMT_IF09, 1567 }, { IMGFMT_YV12, 1567 }, { IMGFMT_I420, 1567 }, { IMGFMT_IYUV, 1567 }, { IMGFMT_UYVY, 1551 }, { IMGFMT_YUY2, 1551 }, { IMGFMT_YVYU, 1551 }, { IMGFMT_RGB15, 1551 }, { IMGFMT_BGR15, 1551 }, { IMGFMT_RGB16, 1551 }, { IMGFMT_BGR16, 1551 }, { IMGFMT_RGB32, 775 }, { IMGFMT_BGR32, 775 } }; __inline__ static int is_supported_fourcc(uint32_t fourcc,unsigned srcw) { unsigned i; for(i=0;ifourcc,to->srcw)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP| VID_DEPTH_15BPP| VID_DEPTH_16BPP| VID_DEPTH_24BPP| VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } static double H_scale_ratio; static void radeon_vid_dump_regs( void ) { size_t i; printf(RADEON_MSG"*** Begin of DRIVER variables dump ***\n"); printf(RADEON_MSG"radeon_mmio_base=%p\n",radeon_mmio_base); printf(RADEON_MSG"radeon_mem_base=%p\n",radeon_mem_base); printf(RADEON_MSG"radeon_overlay_off=%08X\n",radeon_overlay_off); printf(RADEON_MSG"radeon_ram_size=%08X\n",radeon_ram_size); printf(RADEON_MSG"video mode: %ux%u@%u\n",radeon_get_xres(),radeon_get_yres(),radeon_vid_get_dbpp()); printf(RADEON_MSG"H_scale_ratio=%8.2f\n",H_scale_ratio); printf(RADEON_MSG"*** Begin of OV0 registers dump ***\n"); for(i=0;i VERBOSE_LEVEL) printf(RADEON_MSG"we wanted: scaler=%08X\n",bes_flags); if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs(); } /* Goal of this function: hide RGB background and provide black screen around movie. Useful in '-vo fbdev:vidix -fs -zoom' mode. Reverse effect to colorkey */ #ifdef RAGE128 static void radeon_vid_exclusive( void ) { /* this function works only with Rage128. Radeon should has something the same */ unsigned screenw,screenh; screenw = radeon_get_xres(); screenh = radeon_get_yres(); radeon_fifo_wait(2); OUTREG(OV0_EXCLUSIVE_VERT,(((screenh-1)<<16)&EXCL_VERT_END_MASK)); OUTREG(OV0_EXCLUSIVE_HORZ,(((screenw/8+1)<<8)&EXCL_HORZ_END_MASK)|EXCL_HORZ_EXCLUSIVE_EN); } static void radeon_vid_non_exclusive( void ) { OUTREG(OV0_EXCLUSIVE_HORZ,0); } #endif static unsigned radeon_query_pitch(unsigned fourcc,const vidix_yuv_t *spitch) { unsigned pitch,spy,spv,spu; spy = spv = spu = 0; switch(spitch->y) { case 16: case 32: case 64: case 128: case 256: spy = spitch->y; break; default: break; } switch(spitch->u) { case 16: case 32: case 64: case 128: case 256: spu = spitch->u; break; default: break; } switch(spitch->v) { case 16: case 32: case 64: case 128: case 256: spv = spitch->v; break; default: break; } switch(fourcc) { /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_YV12: case IMGFMT_I420: if(spy > 16 && spu == spy/2 && spv == spy/2) pitch = spy; else pitch = 32; break; case IMGFMT_IF09: case IMGFMT_YVU9: if(spy >= 64 && spu == spy/4 && spv == spy/4) pitch = spy; else pitch = 64; break; default: if(spy >= 16) pitch = spy; else pitch = 16; break; } return pitch; } static void Calc_H_INC_STEP_BY ( int fieldvalue_OV0_SURFACE_FORMAT, double H_scale_ratio, int DisallowFourTapVertFiltering, int DisallowFourTapUVVertFiltering, uint32_t *val_OV0_P1_H_INC, uint32_t *val_OV0_P1_H_STEP_BY, uint32_t *val_OV0_P23_H_INC, uint32_t *val_OV0_P23_H_STEP_BY, int *P1GroupSize, int *P1StepSize, int *P23StepSize ) { double ClocksNeededFor16Pixels; switch (fieldvalue_OV0_SURFACE_FORMAT) { case 3: case 4: /*16BPP (ARGB1555 and RGB565) */ /* All colour components are fetched in pairs */ *P1GroupSize = 2; /* We don't support four tap in this mode because G's are split between two bytes. In theory we could support it if */ /* we saved part of the G when fetching the R, and then filter the G, followed by the B in the following cycles. */ if (H_scale_ratio>=.5) { /* We are actually generating two pixels (but 3 colour components) per tick. Thus we don't have to skip */ /* until we reach .5. P1 and P23 are the same. */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 1; *P1StepSize = 1; *P23StepSize = 1; } else if (H_scale_ratio>=.25) { /* Step by two */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 2; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 2; *P1StepSize = 2; *P23StepSize = 2; } else if (H_scale_ratio>=.125) { /* Step by four */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 3; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 3; *P1StepSize = 4; *P23StepSize = 4; } else if (H_scale_ratio>=.0625) { /* Step by eight */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 4; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 4; *P1StepSize = 8; *P23StepSize = 8; } else if (H_scale_ratio>=0.03125) { /* Step by sixteen */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } else { H_scale_ratio=0.03125; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } break; case 6: /*32BPP RGB */ if (H_scale_ratio>=1.5 && !DisallowFourTapVertFiltering) { /* All colour components are fetched in pairs */ *P1GroupSize = 2; /* With four tap filtering, we can generate two colour components every clock, or two pixels every three */ /* clocks. This means that we will have four tap filtering when scaling 1.5 or more. */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 0; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 0; *P1StepSize = 1; *P23StepSize = 1; } else if (H_scale_ratio>=0.75) { /* Four G colour components are fetched at once */ *P1GroupSize = 4; /* R and B colour components are fetched in pairs */ /* With two tap filtering, we can generate four colour components every clock. */ /* This means that we will have two tap filtering when scaling 1.0 or more. */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 1; *P1StepSize = 1; *P23StepSize = 1; } else if (H_scale_ratio>=0.375) { /* Step by two. */ /* Four G colour components are fetched at once */ *P1GroupSize = 4; /* R and B colour components are fetched in pairs */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 2; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 2; *P1StepSize = 2; *P23StepSize = 2; } else if (H_scale_ratio>=0.25) { /* Step by two. */ /* Four G colour components are fetched at once */ *P1GroupSize = 4; /* R and B colour components are fetched in pairs */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 2; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 3; *P1StepSize = 2; *P23StepSize = 4; } else if (H_scale_ratio>=0.1875) { /* Step by four */ /* Four G colour components are fetched at once */ *P1GroupSize = 4; /* R and B colour components are fetched in pairs */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 3; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 3; *P1StepSize = 4; *P23StepSize = 4; } else if (H_scale_ratio>=0.125) { /* Step by four */ /* Four G colour components are fetched at once */ *P1GroupSize = 4; /* R and B colour components are fetched in pairs */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 3; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 4; *P1StepSize = 4; *P23StepSize = 8; } else if (H_scale_ratio>=0.09375) { /* Step by eight */ /* Four G colour components are fetched at once */ *P1GroupSize = 4; /* R and B colour components are fetched in pairs */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 4; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 4; *P1StepSize = 8; *P23StepSize = 8; } else if (H_scale_ratio>=0.0625) { /* Step by eight */ /* Four G colour components are fetched at once */ *P1GroupSize = 4; /* R and B colour components are fetched in pairs */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } else { H_scale_ratio=0.0625; *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } break; case 9: /*ToDo_Active: In mode 9 there is a possibility that HScale ratio may be set to an illegal value, so we have extra conditions in the if statement. For consistancy, these conditions be added to the other modes as well. */ /* four tap on both (unless Y is too wide) */ if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+2+2) / 16.0) && ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) && !DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering) { /*0.75 */ /* Colour components are fetched in pairs */ *P1GroupSize = 2; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 0; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 0; *P1StepSize = 1; *P23StepSize = 1; } /* two tap on Y (because it is too big for four tap), four tap on UV */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+2+2) / 16.0) && ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) && DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering) { /*0.75 */ *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 0; *P1StepSize = 1; *P23StepSize = 1; } /* We scale the Y with the four tap filters, but UV's are generated with dual two tap configuration. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+1+1) / 16.0) && ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000) && !DisallowFourTapVertFiltering) { /*0.625 */ *P1GroupSize = 2; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 0; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 1; *P1StepSize = 1; *P23StepSize = 1; } /* We scale the Y, U, and V with the two tap filters */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+1+1) / 16.0) && ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x2000)) { /*0.375 */ *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 1; *P1StepSize = 1; *P23StepSize = 1; } /* We scale step the U and V by two to allow more bandwidth for fetching Y's, thus we won't drop Y's yet. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+.5+.5) / 16.0) && ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5)<=0x2000)) { /*>=0.3125 and >.333333~ */ *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 2; *P1StepSize = 1; *P23StepSize = 2; } /* We step the Y, U, and V by two. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=2+.5+.5) / 16.0) && ((uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5)<=0x2000)) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 2; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 2; *P1StepSize = 2; *P23StepSize = 2; } /* We step the Y by two and the U and V by four. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=2+.25+.25) / 16.0) && ((uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5)<=0x2000)) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 2; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 3; *P1StepSize = 2; *P23StepSize = 4; } /* We step the Y, U, and V by four. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=1+.25+.25) / 16.0) && ((uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5)<=0x2000)) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 3; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 3; *P1StepSize = 4; *P23StepSize = 4; } /* We would like to step the Y by four and the U and V by eight, but we can't mix step by 3 and step by 4 for packed modes */ /* We step the Y, U, and V by eight. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.125+.125) / 16.0) && ((uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4*8)) * (1<<0xc) + 0.5)<=0x2000)) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 4; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*8)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 4; *P1StepSize = 8; *P23StepSize = 8; } /* We step the Y by eight and the U and V by sixteen. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.0625+.0625) / 16.0) && ((uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5)<=0x2000)) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 4; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 8; *P23StepSize = 16; } /* We step the Y, U, and V by sixteen. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.25+.0625+.0625) / 16.0) && ((uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5)<=0x3000) && ((uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5)<=0x2000)) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } else { H_scale_ratio=(ClocksNeededFor16Pixels=.25+.0625+.0625) / 16; *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*4*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } break; case 10: case 11: case 12: case 13: case 14: /* YUV12, VYUY422, YUYV422, YOverPkCRCB12, YWovenWithPkCRCB12 */ /* We scale the Y, U, and V with the four tap filters */ /* four tap on both (unless Y is too wide) */ if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+4+4) / 16.0) && !DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering) { /*0.75 */ *P1GroupSize = 2; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 0; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 0; *P1StepSize = 1; *P23StepSize = 1; } /* two tap on Y (because it is too big for four tap), four tap on UV */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=4+4+4) / 16.0) && DisallowFourTapVertFiltering && !DisallowFourTapUVVertFiltering) { /*0.75 */ *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 0; *P1StepSize = 1; *P23StepSize = 1; } /* We scale the Y with the four tap filters, but UV's are generated with dual two tap configuration. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=8+2+2) / 16.0) && !DisallowFourTapVertFiltering) { /*0.625 */ *P1GroupSize = 2; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 0; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 1; *P1StepSize = 1; *P23StepSize = 1; } /* We scale the Y, U, and V with the two tap filters */ else if (H_scale_ratio>=(ClocksNeededFor16Pixels=4+2+2) / 16.0) { /*0.375 */ *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 1; *P1StepSize = 1; *P23StepSize = 1; } /* We scale step the U and V by two to allow more bandwidth for fetching Y's, thus we won't drop Y's yet. */ else if (H_scale_ratio>=(ClocksNeededFor16Pixels=4+1+1) / 16.0) { /*0.312 */ *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 1; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 2; *P1StepSize = 1; *P23StepSize = 2; } /* We step the Y, U, and V by two. */ else if (H_scale_ratio>=(ClocksNeededFor16Pixels=2+1+1) / 16.0) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 2; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*2)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 2; *P1StepSize = 2; *P23StepSize = 2; } /* We step the Y by two and the U and V by four. */ else if (H_scale_ratio>=(ClocksNeededFor16Pixels=2+.5+.5) / 16.0) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*2)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 2; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 3; *P1StepSize = 2; *P23StepSize = 4; } /* We step the Y, U, and V by four. */ else if (H_scale_ratio>=(ClocksNeededFor16Pixels=1+.5+.5) / 16.0) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 3; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*4)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 3; *P1StepSize = 4; *P23StepSize = 4; } /* We step the Y by four and the U and V by eight. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=1+.25+.25) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT==10)) { *P1GroupSize = 4; /* Can't mix step by 3 and step by 4 for packed modes */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*4)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 3; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*8)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 4; *P1StepSize = 4; *P23StepSize = 8; } /* We step the Y, U, and V by eight. */ else if (H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.25+.25) / 16.0) { *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 4; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*8)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 4; *P1StepSize = 8; *P23StepSize = 8; } /* We step the Y by eight and the U and V by sixteen. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.5+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT==10)) { *P1GroupSize = 4; /* Step by 5 not supported for packed modes */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 4; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 8; *P23StepSize = 16; } /* We step the Y, U, and V by sixteen. */ else if ((H_scale_ratio>=(ClocksNeededFor16Pixels=.25+.125+.125) / 16.0) && (fieldvalue_OV0_SURFACE_FORMAT==10)) { *P1GroupSize = 4; /* Step by 5 not supported for packed modes */ *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } else { if (fieldvalue_OV0_SURFACE_FORMAT==10) { H_scale_ratio=(ClocksNeededFor16Pixels=.25+.125+.125) / 16; *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*16)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 5; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*16)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 5; *P1StepSize = 16; *P23StepSize = 16; } else { H_scale_ratio=(ClocksNeededFor16Pixels=.5+.25+.25) / 16; *P1GroupSize = 4; *val_OV0_P1_H_INC = (uint16_t)((1/(H_scale_ratio*8)) * (1<<0xc) + 0.5); *val_OV0_P1_H_STEP_BY = 4; *val_OV0_P23_H_INC = (uint16_t)((1/(H_scale_ratio*2*8)) * (1<<0xc) + 0.5); *val_OV0_P23_H_STEP_BY = 4; *P1StepSize = 8; *P23StepSize = 8; } } break; default: break; } besr.h_inc = (*(val_OV0_P1_H_INC)&0x3fff) | ((*(val_OV0_P23_H_INC)&0x3fff)<<16); besr.step_by = (*(val_OV0_P1_H_STEP_BY)&0x7) | ((*(val_OV0_P23_H_STEP_BY)&0x7)<<8); } /* ********************************************************* */ /* ** Setup Black Bordering */ /* ********************************************************* */ static void ComputeBorders( vidix_playback_t *config, int VertUVSubSample ) { double tempBLANK_LINES_AT_TOP; unsigned TopLine,BottomLine,SourceLinesUsed,TopUVLine,BottomUVLine,SourceUVLinesUsed; uint32_t val_OV0_P1_ACTIVE_LINES_M1,val_OV0_P1_BLNK_LN_AT_TOP_M1; uint32_t val_OV0_P23_ACTIVE_LINES_M1,val_OV0_P23_BLNK_LN_AT_TOP_M1; if (floor(config->src.y)<0) { tempBLANK_LINES_AT_TOP = -floor(config->src.y); TopLine = 0; } else { tempBLANK_LINES_AT_TOP = 0; TopLine = (int)floor(config->src.y); } /* Round rSrcBottom up and subtract one */ if (ceil(config->src.y+config->src.h) > config->src.h) { BottomLine = config->src.h - 1; } else { BottomLine = (int)ceil(config->src.y+config->src.h) - 1; } if (BottomLine >= TopLine) { SourceLinesUsed = BottomLine - TopLine + 1; } else { /*CYCACC_ASSERT(0, "SourceLinesUsed less than or equal to zero.") */ SourceLinesUsed = 1; } { int SourceHeightInPixels; SourceHeightInPixels = BottomLine - TopLine + 1; } val_OV0_P1_ACTIVE_LINES_M1 = SourceLinesUsed - 1; val_OV0_P1_BLNK_LN_AT_TOP_M1 = ((int)tempBLANK_LINES_AT_TOP-1) & 0xfff; TopUVLine = ((int)(config->src.y/VertUVSubSample) < 0) ? 0: (int)(config->src.y/VertUVSubSample); /* Round rSrcTop down */ BottomUVLine = (ceil(((config->src.y+config->src.h)/VertUVSubSample)) > (config->src.h/VertUVSubSample)) ? (config->src.h/VertUVSubSample)-1 : (u_int)ceil(((config->src.y+config->src.h)/VertUVSubSample))-1; if (BottomUVLine >= TopUVLine) { SourceUVLinesUsed = BottomUVLine - TopUVLine + 1; } else { /*CYCACC_ASSERT(0, "SourceUVLinesUsed less than or equal to zero.") */ SourceUVLinesUsed = 1; } val_OV0_P23_ACTIVE_LINES_M1 = SourceUVLinesUsed - 1; val_OV0_P23_BLNK_LN_AT_TOP_M1 = ((int)(tempBLANK_LINES_AT_TOP/VertUVSubSample)-1) & 0x7ff; besr.p1_blank_lines_at_top = (val_OV0_P1_BLNK_LN_AT_TOP_M1 & 0xfff) | ((val_OV0_P1_ACTIVE_LINES_M1 & 0xfff) << 16); besr.p23_blank_lines_at_top = (val_OV0_P23_BLNK_LN_AT_TOP_M1 & 0x7ff) | ((val_OV0_P23_ACTIVE_LINES_M1 & 0x7ff) << 16); } static void ComputeXStartEnd( int is_400, uint32_t LeftPixel,uint32_t LeftUVPixel, uint32_t MemWordsInBytes,uint32_t BytesPerPixel, uint32_t SourceWidthInPixels, uint32_t P1StepSize, uint32_t BytesPerUVPixel,uint32_t SourceUVWidthInPixels, uint32_t P23StepSize, uint32_t *p1_x_start, uint32_t *p2_x_start ) { uint32_t val_OV0_P1_X_START,val_OV0_P2_X_START,val_OV0_P3_X_START; uint32_t val_OV0_P1_X_END,val_OV0_P2_X_END,val_OV0_P3_X_END; /* ToDo_Active: At the moment we are not using iOV0_VID_BUF?_START_PIX, but instead // are using iOV0_P?_X_START and iOV0_P?_X_END. We should use "start pix" and // "width" to derive the start and end. */ val_OV0_P1_X_START = (int)LeftPixel % (MemWordsInBytes/BytesPerPixel); val_OV0_P1_X_END = (int)((val_OV0_P1_X_START + SourceWidthInPixels - 1) / P1StepSize) * P1StepSize; val_OV0_P2_X_START = val_OV0_P2_X_END = 0; switch (besr.surf_id) { case 9: case 10: case 13: case 14: /* ToDo_Active: The driver must insure that the initial value is */ /* a multiple of a power of two when decimating */ val_OV0_P2_X_START = (int)LeftUVPixel % (MemWordsInBytes/BytesPerUVPixel); val_OV0_P2_X_END = (int)((val_OV0_P2_X_START + SourceUVWidthInPixels - 1) / P23StepSize) * P23StepSize; break; case 11: case 12: val_OV0_P2_X_START = (int)LeftUVPixel % (MemWordsInBytes/(BytesPerPixel*2)); val_OV0_P2_X_END = (int)((val_OV0_P2_X_START + SourceUVWidthInPixels - 1) / P23StepSize) * P23StepSize; break; case 3: case 4: val_OV0_P2_X_START = val_OV0_P1_X_START; /* This value is needed only to allow proper setting of */ /* val_OV0_PRESHIFT_P23_TO */ /* val_OV0_P2_X_END = 0; */ break; case 6: val_OV0_P2_X_START = (int)LeftPixel % (MemWordsInBytes/BytesPerPixel); val_OV0_P2_X_END = (int)((val_OV0_P1_X_START + SourceWidthInPixels - 1) / P23StepSize) * P23StepSize; break; default: /* insert debug statement here. */ RADEON_ASSERT("unknown fourcc\n"); break; } val_OV0_P3_X_START = val_OV0_P2_X_START; val_OV0_P3_X_END = val_OV0_P2_X_END; besr.p1_x_start_end = (val_OV0_P1_X_END&0x7ff) | ((val_OV0_P1_X_START&0x7ff)<<16); besr.p2_x_start_end = (val_OV0_P2_X_END&0x7ff) | ((val_OV0_P2_X_START&0x7ff)<<16); besr.p3_x_start_end = (val_OV0_P3_X_END&0x7ff) | ((val_OV0_P3_X_START&0x7ff)<<16); if(is_400) { besr.p2_x_start_end = 0; besr.p3_x_start_end = 0; } *p1_x_start = val_OV0_P1_X_START; *p2_x_start = val_OV0_P2_X_START; } static void ComputeAccumInit( uint32_t val_OV0_P1_X_START,uint32_t val_OV0_P2_X_START, uint32_t val_OV0_P1_H_INC,uint32_t val_OV0_P23_H_INC, uint32_t val_OV0_P1_H_STEP_BY,uint32_t val_OV0_P23_H_STEP_BY, uint32_t CRT_V_INC, uint32_t P1GroupSize, uint32_t P23GroupSize, uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT, uint32_t val_OV0_P23_MAX_LN_IN_PER_LN_OUT) { uint32_t val_OV0_P1_H_ACCUM_INIT,val_OV0_PRESHIFT_P1_TO; uint32_t val_OV0_P23_H_ACCUM_INIT,val_OV0_PRESHIFT_P23_TO; uint32_t val_OV0_P1_V_ACCUM_INIT,val_OV0_P23_V_ACCUM_INIT; /* 2.5 puts the kernal 50% of the way between the source pixel that is off screen */ /* and the first on-screen source pixel. "(float)valOV0_P?_H_INC / (1<<0xc)" is */ /* the distance (in source pixel coordinates) to the center of the first */ /* destination pixel. Need to add additional pixels depending on how many pixels */ /* are fetched at a time and how many pixels in a set are masked. */ /* P23 values are always fetched in groups of two or four. If the start */ /* pixel does not fall on the boundary, then we need to shift preshift for */ /* some additional pixels */ { double ExtraHalfPixel; double tempAdditionalShift; double tempP1HStartPoint; double tempP23HStartPoint; double tempP1Init; double tempP23Init; if (besr.horz_pick_nearest) ExtraHalfPixel = 0.5; else ExtraHalfPixel = 0.0; tempAdditionalShift = val_OV0_P1_X_START % P1GroupSize + ExtraHalfPixel; tempP1HStartPoint = tempAdditionalShift + 2.5 + ((float)val_OV0_P1_H_INC / (1<<0xd)); tempP1Init = (double)((int)(tempP1HStartPoint * (1<<0x5) + 0.5)) / (1<<0x5); /* P23 values are always fetched in pairs. If the start pixel is odd, then we */ /* need to shift an additional pixel */ /* Note that if the pitch is a multiple of two, and if we store fields using */ /* the traditional planer format where the V plane and the U plane share the */ /* same pitch, then OverlayRegFields->val_OV0_P2_X_START % P23Group */ /* OverlayRegFields->val_OV0_P3_X_START % P23GroupSize. Either way */ /* it is a requirement that the U and V start on the same polarity byte */ /* (even or odd). */ tempAdditionalShift = val_OV0_P2_X_START % P23GroupSize + ExtraHalfPixel; tempP23HStartPoint = tempAdditionalShift + 2.5 + ((float)val_OV0_P23_H_INC / (1<<0xd)); tempP23Init = (double)((int)(tempP23HStartPoint * (1<<0x5) + 0.5)) / (1 << 0x5); val_OV0_P1_H_ACCUM_INIT = (int)((tempP1Init - (int)tempP1Init) * (1<<0x5)); val_OV0_PRESHIFT_P1_TO = (int)tempP1Init; val_OV0_P23_H_ACCUM_INIT = (int)((tempP23Init - (int)tempP23Init) * (1<<0x5)); val_OV0_PRESHIFT_P23_TO = (int)tempP23Init; } /* ************************************************************** */ /* ** Calculate values for initializing the vertical accumulators */ /* ************************************************************** */ { double ExtraHalfLine; double ExtraFullLine; double tempP1VStartPoint; double tempP23VStartPoint; if (besr.vert_pick_nearest) ExtraHalfLine = 0.5; else ExtraHalfLine = 0.0; if (val_OV0_P1_H_STEP_BY==0)ExtraFullLine = 1.0; else ExtraFullLine = 0.0; tempP1VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine + ((float)CRT_V_INC / (1<<0xd)); if (tempP1VStartPoint>2.5 + 2*ExtraFullLine) { tempP1VStartPoint = 2.5 + 2*ExtraFullLine; } val_OV0_P1_V_ACCUM_INIT = (int)(tempP1VStartPoint * (1<<0x5) + 0.5); if (val_OV0_P23_H_STEP_BY==0)ExtraFullLine = 1.0; else ExtraFullLine = 0.0; switch (besr.surf_id) { case 10: case 13: case 14: tempP23VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine + ((float)CRT_V_INC / (1<<0xe)); break; case 9: tempP23VStartPoint = 1.5 + ExtraFullLine + ExtraHalfLine + ((float)CRT_V_INC / (1<<0xf)); break; case 3: case 4: case 6: case 11: case 12: tempP23VStartPoint = 0; break; default: tempP23VStartPoint = 0xFFFF;/* insert debug statement here */ break; } if (tempP23VStartPoint>2.5 + 2*ExtraFullLine) { tempP23VStartPoint = 2.5 + 2*ExtraFullLine; } val_OV0_P23_V_ACCUM_INIT = (int)(tempP23VStartPoint * (1<<0x5) + 0.5); } besr.p1_h_accum_init = ((val_OV0_P1_H_ACCUM_INIT&0x1f)<<15) |((val_OV0_PRESHIFT_P1_TO&0xf)<<28); besr.p1_v_accum_init = (val_OV0_P1_MAX_LN_IN_PER_LN_OUT&0x3) |((val_OV0_P1_V_ACCUM_INIT&0x7ff)<<15); besr.p23_h_accum_init= ((val_OV0_P23_H_ACCUM_INIT&0x1f)<<15) |((val_OV0_PRESHIFT_P23_TO&0xf)<<28); besr.p23_v_accum_init= (val_OV0_P23_MAX_LN_IN_PER_LN_OUT&0x3)|((val_OV0_P23_V_ACCUM_INIT&0x3ff)<<15); } typedef struct RangeAndCoefSet { double Range; signed char CoefSet[5][4]; } RANGEANDCOEFSET; /* Filter Setup Routine */ static void FilterSetup ( uint32_t val_OV0_P1_H_INC ) { static RANGEANDCOEFSET ArrayOfSets[] = { {0.25, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.26, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.27, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.28, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.29, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.30, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.31, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.32, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.33, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.34, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.35, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.36, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.37, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.38, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.39, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.40, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.41, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.42, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.43, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.44, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.45, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.46, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.47, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.48, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.49, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.50, {{ 7, 16, 9, 0}, { 7, 16, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 3, 13, 13, 3}, }}, {0.51, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 15, 11, 1}, { 4, 15, 12, 1}, { 2, 14, 14, 2}, }}, {0.52, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, {0.53, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 5, 16, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, {0.54, {{ 7, 17, 8, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 2, 14, 14, 2}, }}, {0.55, {{ 7, 18, 7, 0}, { 6, 17, 9, 0}, { 4, 17, 11, 0}, { 3, 15, 13, 1}, { 1, 15, 15, 1}, }}, {0.56, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.57, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.58, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.59, {{ 7, 18, 7, 0}, { 5, 18, 9, 0}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.60, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.61, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.62, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.63, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 11, 0}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.64, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 1, 15, 15, 1}, }}, {0.65, {{ 7, 18, 8, -1}, { 6, 17, 10, -1}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, {0.66, {{ 7, 18, 8, -1}, { 6, 18, 10, -2}, { 4, 17, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, {0.67, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 18, 12, -1}, { 2, 17, 13, 0}, { 0, 16, 16, 0}, }}, {0.68, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, {0.69, {{ 7, 20, 7, -2}, { 5, 19, 10, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, {0.70, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, {0.71, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 3, 19, 12, -2}, { 1, 18, 14, -1}, { 0, 16, 16, 0}, }}, {0.72, {{ 7, 20, 7, -2}, { 5, 20, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, {0.73, {{ 7, 20, 7, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, {0.74, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 2, 20, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, {0.75, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, {0.76, {{ 6, 22, 6, -2}, { 4, 21, 9, -2}, { 1, 21, 12, -2}, { 0, 19, 15, -2}, {-1, 17, 17, -1}, }}, {0.77, {{ 6, 22, 6, -2}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, {0.78, {{ 6, 21, 6, -1}, { 3, 22, 9, -2}, { 1, 22, 12, -3}, { 0, 19, 15, -2}, {-2, 18, 18, -2}, }}, {0.79, {{ 5, 23, 5, -1}, { 3, 22, 9, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, {0.80, {{ 5, 23, 5, -1}, { 3, 23, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, {0.81, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-2, 18, 18, -2}, }}, {0.82, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 12, -3}, {-1, 21, 15, -3}, {-3, 19, 19, -3}, }}, {0.83, {{ 5, 23, 5, -1}, { 2, 24, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, {0.84, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, {0.85, {{ 4, 25, 4, -1}, { 1, 25, 8, -2}, { 0, 23, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, {0.86, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, {0.87, {{ 4, 24, 4, 0}, { 1, 25, 7, -1}, {-1, 24, 11, -2}, {-2, 22, 15, -3}, {-3, 19, 19, -3}, }}, {0.88, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, {0.89, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-1, 24, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, {0.90, {{ 3, 26, 3, 0}, { 0, 26, 7, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, {0.91, {{ 3, 26, 3, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, {0.92, {{ 2, 28, 2, 0}, { 0, 27, 6, -1}, {-2, 25, 11, -2}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, {0.93, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, {0.94, {{ 2, 28, 2, 0}, { 0, 26, 6, 0}, {-2, 25, 10, -1}, {-3, 23, 15, -3}, {-3, 19, 19, -3}, }}, {0.95, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, {0.96, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, {0.97, {{ 1, 30, 1, 0}, {-1, 28, 5, 0}, {-3, 26, 10, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, {0.98, {{ 1, 30, 1, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-3, 23, 14, -2}, {-3, 19, 19, -3}, }}, {0.99, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }}, {1.00, {{ 0, 32, 0, 0}, {-2, 29, 5, 0}, {-3, 27, 9, -1}, {-4, 24, 14, -2}, {-3, 19, 19, -3}, }} }; double DSR; unsigned ArrayElement; DSR = (double)(1<<0xc)/val_OV0_P1_H_INC; if (DSR<.25) DSR=.25; if (DSR>1) DSR=1; ArrayElement = (int)((DSR-0.25) * 100); besr.four_tap_coeff[0] = (ArrayOfSets[ArrayElement].CoefSet[0][0] & 0xf) | ((ArrayOfSets[ArrayElement].CoefSet[0][1] & 0x7f)<<8) | ((ArrayOfSets[ArrayElement].CoefSet[0][2] & 0x7f)<<16) | ((ArrayOfSets[ArrayElement].CoefSet[0][3] & 0xf)<<24); besr.four_tap_coeff[1] = (ArrayOfSets[ArrayElement].CoefSet[1][0] & 0xf) | ((ArrayOfSets[ArrayElement].CoefSet[1][1] & 0x7f)<<8) | ((ArrayOfSets[ArrayElement].CoefSet[1][2] & 0x7f)<<16) | ((ArrayOfSets[ArrayElement].CoefSet[1][3] & 0xf)<<24); besr.four_tap_coeff[2] = (ArrayOfSets[ArrayElement].CoefSet[2][0] & 0xf) | ((ArrayOfSets[ArrayElement].CoefSet[2][1] & 0x7f)<<8) | ((ArrayOfSets[ArrayElement].CoefSet[2][2] & 0x7f)<<16) | ((ArrayOfSets[ArrayElement].CoefSet[2][3] & 0xf)<<24); besr.four_tap_coeff[3] = (ArrayOfSets[ArrayElement].CoefSet[3][0] & 0xf) | ((ArrayOfSets[ArrayElement].CoefSet[3][1] & 0x7f)<<8) | ((ArrayOfSets[ArrayElement].CoefSet[3][2] & 0x7f)<<16) | ((ArrayOfSets[ArrayElement].CoefSet[3][3] & 0xf)<<24); besr.four_tap_coeff[4] = (ArrayOfSets[ArrayElement].CoefSet[4][0] & 0xf) | ((ArrayOfSets[ArrayElement].CoefSet[4][1] & 0x7f)<<8) | ((ArrayOfSets[ArrayElement].CoefSet[4][2] & 0x7f)<<16) | ((ArrayOfSets[ArrayElement].CoefSet[4][3] & 0xf)<<24); /* For more details, refer to Microsoft's draft of PC99. */ } /* The minimal value of horizontal scale ratio when hard coded coefficients are suitable for the best quality. */ /* FIXME: Should it be 0.9 for Rage128 ??? */ const double MinHScaleHard=0.75; static int radeon_vid_init_video( vidix_playback_t *config ) { double V_scale_ratio; uint32_t i,src_w,src_h,dest_w,dest_h,pitch,left,leftUV,top,h_inc; uint32_t val_OV0_P1_H_INC=0,val_OV0_P1_H_STEP_BY=0,val_OV0_P23_H_INC=0,val_OV0_P23_H_STEP_BY=0; uint32_t val_OV0_P1_X_START,val_OV0_P2_X_START; uint32_t val_OV0_P1_MAX_LN_IN_PER_LN_OUT,val_OV0_P23_MAX_LN_IN_PER_LN_OUT; uint32_t CRT_V_INC; uint32_t BytesPerOctWord,LogMemWordsInBytes,MemWordsInBytes,LogTileWidthInMemWords; uint32_t TileWidthInMemWords,TileWidthInBytes,LogTileHeight,TileHeight; uint32_t PageSizeInBytes,OV0LB_Rows; uint32_t SourceWidthInMemWords,SourceUVWidthInMemWords; uint32_t SourceWidthInPixels,SourceUVWidthInPixels; uint32_t RightPixel,RightUVPixel,LeftPixel,LeftUVPixel; int is_400,is_410,is_420,best_pitch,mpitch; int horz_repl_factor,interlace_factor; int BytesPerPixel,BytesPerUVPixel,HorzUVSubSample,VertUVSubSample; int DisallowFourTapVertFiltering,DisallowFourTapUVVertFiltering; radeon_vid_stop_video(); left = config->src.x << 16; top = config->src.y << 16; src_h = config->src.h; src_w = config->src.w; is_400 = is_410 = is_420 = 0; if(config->fourcc == IMGFMT_YV12 || config->fourcc == IMGFMT_I420 || config->fourcc == IMGFMT_IYUV) is_420 = 1; if(config->fourcc == IMGFMT_YVU9 || config->fourcc == IMGFMT_IF09) is_410 = 1; if(config->fourcc == IMGFMT_Y800) is_400 = 1; best_pitch = radeon_query_pitch(config->fourcc,&config->src.pitch); mpitch = best_pitch-1; BytesPerOctWord = 16; LogMemWordsInBytes = 4; MemWordsInBytes = 1<fourcc) { /* 4:0:0*/ case IMGFMT_Y800: /* 4:1:0*/ case IMGFMT_YVU9: case IMGFMT_IF09: /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_YV12: case IMGFMT_I420: pitch = (src_w + mpitch) & ~mpitch; config->dest.pitch.y = config->dest.pitch.u = config->dest.pitch.v = best_pitch; break; /* RGB 4:4:4:4 */ case IMGFMT_RGB32: case IMGFMT_BGR32: pitch = (src_w*4 + mpitch) & ~mpitch; config->dest.pitch.y = config->dest.pitch.u = config->dest.pitch.v = best_pitch; break; /* 4:2:2 */ default: /* RGB15, RGB16, YVYU, UYVY, YUY2 */ pitch = ((src_w*2) + mpitch) & ~mpitch; config->dest.pitch.y = config->dest.pitch.u = config->dest.pitch.v = best_pitch; break; } besr.load_prg_start=0; besr.swap_uv=0; switch(config->fourcc) { case IMGFMT_RGB15: besr.swap_uv=1; case IMGFMT_BGR15: besr.surf_id = SCALER_SOURCE_15BPP>>8; besr.load_prg_start = 1; break; case IMGFMT_RGB16: besr.swap_uv=1; case IMGFMT_BGR16: besr.surf_id = SCALER_SOURCE_16BPP>>8; besr.load_prg_start = 1; break; case IMGFMT_RGB32: besr.swap_uv=1; case IMGFMT_BGR32: besr.surf_id = SCALER_SOURCE_32BPP>>8; besr.load_prg_start = 1; break; /* 4:1:0*/ case IMGFMT_IF09: case IMGFMT_YVU9: besr.surf_id = SCALER_SOURCE_YUV9>>8; break; /* 4:0:0*/ case IMGFMT_Y800: /* 4:2:0 */ case IMGFMT_IYUV: case IMGFMT_I420: case IMGFMT_YV12: besr.surf_id = SCALER_SOURCE_YUV12>>8; break; /* 4:2:2 */ case IMGFMT_YVYU: case IMGFMT_UYVY: besr.surf_id = SCALER_SOURCE_YVYU422>>8; break; case IMGFMT_YUY2: default: besr.surf_id = SCALER_SOURCE_VYUY422>>8; break; } switch (besr.surf_id) { case 3: case 4: case 11: case 12: BytesPerPixel = 2; break; case 6: BytesPerPixel = 4; break; case 9: case 10: case 13: case 14: BytesPerPixel = 1; break; default: BytesPerPixel = 0;/*insert a debug statement here. */ break; } switch (besr.surf_id) { case 3: case 4: BytesPerUVPixel = 0; break;/* In RGB modes, the BytesPerUVPixel is don't care */ case 11: case 12: BytesPerUVPixel = 2; break; case 6: BytesPerUVPixel = 0; break; /* In RGB modes, the BytesPerUVPixel is don't care */ case 9: case 10: BytesPerUVPixel = 1; break; case 13: case 14: BytesPerUVPixel = 2; break; default: BytesPerUVPixel = 0;/* insert a debug statement here. */ break; } switch (besr.surf_id) { case 3: case 4: case 6: HorzUVSubSample = 1; break; case 9: HorzUVSubSample = 4; break; case 10: case 11: case 12: case 13: case 14: HorzUVSubSample = 2; break; default: HorzUVSubSample = 0;/* insert debug statement here. */ break; } switch (besr.surf_id) { case 3: case 4: case 6: case 11: case 12: VertUVSubSample = 1; break; case 9: VertUVSubSample = 4; break; case 10: case 13: case 14: VertUVSubSample = 2; break; default: VertUVSubSample = 0;/* insert debug statment here. */ break; } DisallowFourTapVertFiltering = 0; /* Allow it by default */ DisallowFourTapUVVertFiltering = 0; /* Allow it by default */ LeftPixel = config->src.x; RightPixel = config->src.w-1; if(floor(config->src.x/HorzUVSubSample)<0) LeftUVPixel = 0; else LeftUVPixel = (int)floor(config->src.x/HorzUVSubSample); if(ceil((config->src.x+config->src.w)/HorzUVSubSample) > config->src.w/HorzUVSubSample) RightUVPixel = config->src.w/HorzUVSubSample - 1; else RightUVPixel = (int)ceil((config->src.x+config->src.w)/HorzUVSubSample) - 1; /* Top, Bottom and Right Crops can be out of range. The driver will program the hardware // to create a black border at the top and bottom. This is useful for DVD letterboxing. */ SourceWidthInPixels = (int)(config->src.w + 1); SourceUVWidthInPixels = (int)(RightUVPixel - LeftUVPixel + 1); SourceWidthInMemWords = (int)(ceil(RightPixel*BytesPerPixel / MemWordsInBytes) - floor(LeftPixel*BytesPerPixel / MemWordsInBytes) + 1); /* SourceUVWidthInMemWords means Source_U_or_V_or_UV_WidthInMemWords depending on whether the UV is packed together of not. */ SourceUVWidthInMemWords = (int)(ceil(RightUVPixel*BytesPerUVPixel / MemWordsInBytes) - floor(LeftUVPixel*BytesPerUVPixel / MemWordsInBytes) + 1); switch (besr.surf_id) { case 9: case 10: if ((ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1) { RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n"); } else if ((SourceWidthInMemWords-1) * 2 > OV0LB_Rows-1) { DisallowFourTapVertFiltering = 1; } if ((ceil(SourceUVWidthInMemWords/2)-1) * 4 + 1 > OV0LB_Rows-1) { /*CYCACC_ASSERT(0, "Image U plane width spans more octwords than supported by hardware.") */ } else if ((SourceUVWidthInMemWords-1) * 4 + 1 > OV0LB_Rows-1) { DisallowFourTapUVVertFiltering = 1; } if ((ceil(SourceUVWidthInMemWords/2)-1) * 4 + 3 > OV0LB_Rows-1) { /*CYCACC_ASSERT(0, "Image V plane width spans more octwords than supported by hardware.") */ } else if ((SourceUVWidthInMemWords-1) * 4 + 3 > OV0LB_Rows-1) { DisallowFourTapUVVertFiltering = 1; } break; case 13: case 14: if ((ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1) { RADEON_ASSERT("ceil(SourceWidthInMemWords/2)-1) * 2 > OV0LB_Rows-1\n"); } else if ((SourceWidthInMemWords-1) * 2 > OV0LB_Rows-1) { DisallowFourTapVertFiltering = 1; } if ((ceil(SourceUVWidthInMemWords/2)-1) * 2 + 1 > OV0LB_Rows-1) { /*CYCACC_ASSERT(0, "Image UV plane width spans more octwords than supported by hardware.") */ } else if ((SourceUVWidthInMemWords-1) * 2 + 1 > OV0LB_Rows-1) { DisallowFourTapUVVertFiltering = 1; } break; case 3: case 4: case 6: case 11: case 12: if ((ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1) { RADEON_ASSERT("(ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\n") } else if ((SourceWidthInMemWords-1) > OV0LB_Rows-1) { DisallowFourTapVertFiltering = 1; } break; default: /* insert debug statement here. */ break; } dest_w = config->dest.w; dest_h = config->dest.h; if(radeon_is_dbl_scan()) dest_h *= 2; besr.dest_bpp = radeon_vid_get_dbpp(); besr.fourcc = config->fourcc; if(radeon_is_interlace()) interlace_factor = 2; else interlace_factor = 1; /* TODO: must be checked in doublescan mode!!! */ if((besr.chip_flags&R_INTEGRATED)==R_INTEGRATED) { /* Force the overlay clock on for integrated chips */ OUTPLL(VCLK_ECP_CNTL, (INPLL(VCLK_ECP_CNTL) | (1<<18))); } horz_repl_factor = 1 << (uint32_t)((INPLL(VCLK_ECP_CNTL) & 0x300) >> 8); H_scale_ratio = (double)ceil(((double)dest_w+1)/horz_repl_factor)/src_w; V_scale_ratio = (double)(dest_h+1)/src_h; if(H_scale_ratio < 0.5 && V_scale_ratio < 0.5) { val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 3; val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 2; } else if(H_scale_ratio < 1 && V_scale_ratio < 1) { val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 2; val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 1; } else { val_OV0_P1_MAX_LN_IN_PER_LN_OUT = 1; val_OV0_P23_MAX_LN_IN_PER_LN_OUT = 1; } /* N.B.: Indeed it has 6.12 format but shifted on 8 to the left!!! */ besr.v_inc = (uint16_t)((1./V_scale_ratio)*(1<<12)*interlace_factor+0.5); CRT_V_INC = besr.v_inc/interlace_factor; besr.v_inc <<= 8; { int ThereIsTwoTapVerticalFiltering,DoNotUseMostRecentlyFetchedLine; int P1GroupSize = 0; int P23GroupSize; int P1StepSize = 0; int P23StepSize = 0; Calc_H_INC_STEP_BY( besr.surf_id, H_scale_ratio, DisallowFourTapVertFiltering, DisallowFourTapUVVertFiltering, &val_OV0_P1_H_INC, &val_OV0_P1_H_STEP_BY, &val_OV0_P23_H_INC, &val_OV0_P23_H_STEP_BY, &P1GroupSize, &P1StepSize, &P23StepSize); if(H_scale_ratio > MinHScaleHard) { h_inc = (src_w << 12) / dest_w; besr.step_by = 0x0101; switch (besr.surf_id) { case 3: case 4: case 6: besr.h_inc = (h_inc)|(h_inc<<16); break; case 9: besr.h_inc = h_inc | ((h_inc >> 2) << 16); break; default: besr.h_inc = h_inc | ((h_inc >> 1) << 16); break; } } P23GroupSize = 2; /* Current vaue for all modes */ besr.horz_pick_nearest=0; DoNotUseMostRecentlyFetchedLine=0; ThereIsTwoTapVerticalFiltering = (val_OV0_P1_H_STEP_BY!=0) || (val_OV0_P23_H_STEP_BY!=0); if (ThereIsTwoTapVerticalFiltering && DoNotUseMostRecentlyFetchedLine) besr.vert_pick_nearest = 1; else besr.vert_pick_nearest = 0; ComputeXStartEnd(is_400,LeftPixel,LeftUVPixel,MemWordsInBytes,BytesPerPixel, SourceWidthInPixels,P1StepSize,BytesPerUVPixel, SourceUVWidthInPixels,P23StepSize,&val_OV0_P1_X_START,&val_OV0_P2_X_START); if(H_scale_ratio > MinHScaleHard) { unsigned tmp; tmp = (left & 0x0003ffff) + 0x00028000 + (h_inc << 3); besr.p1_h_accum_init = ((tmp << 4) & 0x000f8000) | ((tmp << 12) & 0xf0000000); tmp = (top & 0x0000ffff) + 0x00018000; besr.p1_v_accum_init = ((tmp << 4) & OV0_P1_V_ACCUM_INIT_MASK) |(OV0_P1_MAX_LN_IN_PER_LN_OUT & 1); tmp = ((left >> 1) & 0x0001ffff) + 0x00028000 + (h_inc << 2); besr.p23_h_accum_init = ((tmp << 4) & 0x000f8000) | ((tmp << 12) & 0x70000000); tmp = ((top >> 1) & 0x0000ffff) + 0x00018000; besr.p23_v_accum_init = (is_420||is_410) ? ((tmp << 4) & OV0_P23_V_ACCUM_INIT_MASK) |(OV0_P23_MAX_LN_IN_PER_LN_OUT & 1) : 0; } else ComputeAccumInit( val_OV0_P1_X_START,val_OV0_P2_X_START, val_OV0_P1_H_INC,val_OV0_P23_H_INC, val_OV0_P1_H_STEP_BY,val_OV0_P23_H_STEP_BY, CRT_V_INC,P1GroupSize,P23GroupSize, val_OV0_P1_MAX_LN_IN_PER_LN_OUT, val_OV0_P23_MAX_LN_IN_PER_LN_OUT); } /* keep everything in 16.16 */ besr.base_addr = INREG(DISPLAY_BASE_ADDR); config->offsets[0] = 0; for(i=1;ioffsets[i] = config->offsets[i-1]+config->frame_size; if(is_420 || is_410 || is_400) { uint32_t d1line,d2line,d3line; d1line = top*pitch; if(is_420) { d2line = src_h*pitch+(d1line>>2); d3line = d2line+((src_h*pitch)>>2); } else if(is_410) { d2line = src_h*pitch+(d1line>>4); d3line = d2line+((src_h*pitch)>>4); } else { d2line = 0; d3line = 0; } d1line += (left >> 16) & ~15; if(is_420) { d2line += (left >> 17) & ~15; d3line += (left >> 17) & ~15; } else /* is_410 */ { d2line += (left >> 18) & ~15; d3line += (left >> 18) & ~15; } config->offset.y = d1line & VIF_BUF0_BASE_ADRS_MASK; if(is_400) { config->offset.v = 0; config->offset.u = 0; } else { config->offset.v = d2line & VIF_BUF1_BASE_ADRS_MASK; config->offset.u = d3line & VIF_BUF2_BASE_ADRS_MASK; } for(i=0;ioffsets[i]+config->offset.y)&VIF_BUF0_BASE_ADRS_MASK); if(is_400) { besr.vid_buf_base_adrs_v[i]=0; besr.vid_buf_base_adrs_u[i]=0; } else { besr.vid_buf_base_adrs_v[i]=((radeon_overlay_off+config->offsets[i]+config->offset.v)&VIF_BUF1_BASE_ADRS_MASK)|VIF_BUF1_PITCH_SEL; besr.vid_buf_base_adrs_u[i]=((radeon_overlay_off+config->offsets[i]+config->offset.u)&VIF_BUF2_BASE_ADRS_MASK)|VIF_BUF2_PITCH_SEL; } } config->offset.y = ((besr.vid_buf_base_adrs_y[0])&VIF_BUF0_BASE_ADRS_MASK) - radeon_overlay_off; if(is_400) { config->offset.v = 0; config->offset.u = 0; } else { config->offset.v = ((besr.vid_buf_base_adrs_v[0])&VIF_BUF1_BASE_ADRS_MASK) - radeon_overlay_off; config->offset.u = ((besr.vid_buf_base_adrs_u[0])&VIF_BUF2_BASE_ADRS_MASK) - radeon_overlay_off; } if(besr.fourcc == IMGFMT_I420 || besr.fourcc == IMGFMT_IYUV) { uint32_t tmp; tmp = config->offset.u; config->offset.u = config->offset.v; config->offset.v = tmp; } } else { config->offset.y = config->offset.u = config->offset.v = ((left & ~7) << 1)&VIF_BUF0_BASE_ADRS_MASK; for(i=0;ioffsets[i] + config->offset.y; } } leftUV = (left >> (is_410?18:17)) & 15; left = (left >> 16) & 15; besr.y_x_start = (config->dest.x+X_ADJUST) | (config->dest.y << 16); besr.y_x_end = (config->dest.x + dest_w+X_ADJUST) | ((config->dest.y + dest_h) << 16); ComputeBorders(config,VertUVSubSample); besr.vid_buf_pitch0_value = pitch; besr.vid_buf_pitch1_value = is_410 ? pitch>>2 : is_420 ? pitch>>1 : pitch; /* ********************************************************* */ /* ** Calculate programmable coefficients as needed */ /* ********************************************************* */ /* ToDo_Active: When in pick nearest mode, we need to program the filter tap zero */ /* coefficients to 0, 32, 0, 0. Or use hard coded coefficients. */ if(H_scale_ratio > MinHScaleHard) besr.filter_cntl |= FILTER_HARDCODED_COEF; else { FilterSetup (val_OV0_P1_H_INC); /* ToDo_Active: Must add the smarts into the driver to decide what type of filtering it */ /* would like to do. For now, we let the test application decide. */ besr.filter_cntl = FILTER_PROGRAMMABLE_COEF; if(DisallowFourTapVertFiltering) besr.filter_cntl |= FILTER_HARD_SCALE_VERT_Y; if(DisallowFourTapUVVertFiltering) besr.filter_cntl |= FILTER_HARD_SCALE_VERT_UV; } return 0; } static void radeon_compute_framesize(vidix_playback_t *info) { unsigned pitch,awidth,dbpp; pitch = radeon_query_pitch(info->fourcc,&info->src.pitch); dbpp = radeon_vid_get_dbpp(); switch(info->fourcc) { case IMGFMT_Y800: awidth = (info->src.w + (pitch-1)) & ~(pitch-1); info->frame_size = awidth*info->src.h; break; case IMGFMT_YVU9: case IMGFMT_IF09: awidth = (info->src.w + (pitch-1)) & ~(pitch-1); info->frame_size = awidth*(info->src.h+info->src.h/8); break; case IMGFMT_I420: case IMGFMT_YV12: case IMGFMT_IYUV: awidth = (info->src.w + (pitch-1)) & ~(pitch-1); info->frame_size = awidth*(info->src.h+info->src.h/2); break; case IMGFMT_RGB32: case IMGFMT_BGR32: awidth = (info->src.w*4 + (pitch-1)) & ~(pitch-1); info->frame_size = awidth*info->src.h; break; /* YUY2 YVYU, RGB15, RGB16 */ default: awidth = (info->src.w*2 + (pitch-1)) & ~(pitch-1); info->frame_size = awidth*info->src.h; break; } info->frame_size = (info->frame_size+4095)&~4095; } int VIDIX_NAME(vixConfigPlayback)(vidix_playback_t *info) { unsigned rgb_size,nfr; uint32_t radeon_video_size; if(!is_supported_fourcc(info->fourcc,info->src.w)) return ENOSYS; if(info->num_frames>VID_PLAY_MAXFRAMES) info->num_frames=VID_PLAY_MAXFRAMES; if(info->num_frames==1) besr.double_buff=0; else besr.double_buff=1; radeon_compute_framesize(info); rgb_size = radeon_get_xres()*radeon_get_yres()*((radeon_vid_get_dbpp()+7)/8); nfr = info->num_frames; radeon_video_size = radeon_ram_size; #ifdef RADEON_ENABLE_BM if(def_cap.flags & FLAG_DMA) { /* every descriptor describes one 4K page and takes 16 bytes in memory Note: probably it's ont good idea to locate them in video memory but as initial release it's OK */ radeon_video_size -= radeon_ram_size * sizeof(bm_list_descriptor) / 4096; radeon_dma_desc_base = (uint8_t *) pci_info.base0 + radeon_video_size; } #endif for(;nfr>0; nfr--) { radeon_overlay_off = radeon_video_size - info->frame_size*nfr; radeon_overlay_off &= 0xffff0000; if(radeon_overlay_off >= (int)rgb_size ) break; } if(nfr <= 3) { nfr = info->num_frames; for(;nfr>0; nfr--) { radeon_overlay_off = radeon_video_size - info->frame_size*nfr; radeon_overlay_off &= 0xffff0000; if(radeon_overlay_off > 0) break; } } if(nfr <= 0) return EINVAL; info->num_frames = nfr; besr.vid_nbufs = info->num_frames; info->dga_addr = (char *)radeon_mem_base + radeon_overlay_off; radeon_vid_init_video(info); return 0; } int VIDIX_NAME(vixPlaybackOn)( void ) { #ifdef RAGE128 unsigned dw,dh; #endif radeon_vid_display_video(); #ifdef RAGE128 dh = (besr.y_x_end >> 16) - (besr.y_x_start >> 16); dw = (besr.y_x_end & 0xFFFF) - (besr.y_x_start & 0xFFFF); if(dw == radeon_get_xres() || dh == radeon_get_yres()) radeon_vid_exclusive(); else radeon_vid_non_exclusive(); #endif return 0; } int VIDIX_NAME(vixPlaybackOff)( void ) { radeon_vid_stop_video(); return 0; } int VIDIX_NAME(vixPlaybackFrameSelect)(unsigned frame) { uint32_t off[6]; int prev_frame= (frame-1+besr.vid_nbufs) % besr.vid_nbufs; /* buf3-5 always should point onto second buffer for better deinterlacing and TV-in */ if(!besr.double_buff) return 0; if(frame > besr.vid_nbufs) frame = besr.vid_nbufs-1; if(prev_frame > (int)besr.vid_nbufs) prev_frame = besr.vid_nbufs-1; off[0] = besr.vid_buf_base_adrs_y[frame]; off[1] = besr.vid_buf_base_adrs_v[frame]; off[2] = besr.vid_buf_base_adrs_u[frame]; off[3] = besr.vid_buf_base_adrs_y[prev_frame]; off[4] = besr.vid_buf_base_adrs_v[prev_frame]; off[5] = besr.vid_buf_base_adrs_u[prev_frame]; radeon_fifo_wait(8); OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); radeon_engine_idle(); while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); OUTREG(OV0_VID_BUF0_BASE_ADRS, off[0]); OUTREG(OV0_VID_BUF1_BASE_ADRS, off[1]); OUTREG(OV0_VID_BUF2_BASE_ADRS, off[2]); OUTREG(OV0_VID_BUF3_BASE_ADRS, off[3]); OUTREG(OV0_VID_BUF4_BASE_ADRS, off[4]); OUTREG(OV0_VID_BUF5_BASE_ADRS, off[5]); OUTREG(OV0_REG_LOAD_CNTL, 0); if(besr.vid_nbufs == 2) radeon_wait_vsync(); if(__verbose > VERBOSE_LEVEL) radeon_vid_dump_regs(); return 0; } vidix_video_eq_t equal = { VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION #ifndef RAGE128 | VEQ_CAP_CONTRAST | VEQ_CAP_HUE | VEQ_CAP_RGB_INTENSITY #endif , 0, 0, 0, 0, 0, 0, 0, 0 }; int VIDIX_NAME(vixPlaybackGetEq)( vidix_video_eq_t * eq) { memcpy(eq,&equal,sizeof(vidix_video_eq_t)); return 0; } #ifndef RAGE128 #define RTFSaturation(a) (1.0 + ((a)*1.0)/1000.0) #define RTFBrightness(a) (((a)*1.0)/2000.0) #define RTFIntensity(a) (((a)*1.0)/2000.0) #define RTFContrast(a) (1.0 + ((a)*1.0)/1000.0) #define RTFHue(a) (((a)*3.1416)/1000.0) #define RTFCheckParam(a) {if((a)<-1000) (a)=-1000; if((a)>1000) (a)=1000;} #endif int VIDIX_NAME(vixPlaybackSetEq)( const vidix_video_eq_t * eq) { #ifdef RAGE128 int br,sat; #else int itu_space; #endif if(eq->cap & VEQ_CAP_BRIGHTNESS) equal.brightness = eq->brightness; if(eq->cap & VEQ_CAP_CONTRAST) equal.contrast = eq->contrast; if(eq->cap & VEQ_CAP_SATURATION) equal.saturation = eq->saturation; if(eq->cap & VEQ_CAP_HUE) equal.hue = eq->hue; if(eq->cap & VEQ_CAP_RGB_INTENSITY) { equal.red_intensity = eq->red_intensity; equal.green_intensity = eq->green_intensity; equal.blue_intensity = eq->blue_intensity; } equal.flags = eq->flags; #ifdef RAGE128 br = equal.brightness * 64 / 1000; if(br < -64) br = -64; if(br > 63) br = 63; sat = (equal.saturation*31 + 31000) / 2000; if(sat < 0) sat = 0; if(sat > 31) sat = 31; OUTREG(OV0_COLOUR_CNTL, (br & 0x7f) | (sat << 8) | (sat << 16)); #else itu_space = equal.flags == VEQ_FLG_ITU_R_BT_709 ? 1 : 0; RTFCheckParam(equal.brightness); RTFCheckParam(equal.saturation); RTFCheckParam(equal.contrast); RTFCheckParam(equal.hue); RTFCheckParam(equal.red_intensity); RTFCheckParam(equal.green_intensity); RTFCheckParam(equal.blue_intensity); radeon_set_transform(RTFBrightness(equal.brightness), RTFContrast(equal.contrast), RTFSaturation(equal.saturation), RTFHue(equal.hue), RTFIntensity(equal.red_intensity), RTFIntensity(equal.green_intensity), RTFIntensity(equal.blue_intensity), itu_space); #endif return 0; } int VIDIX_NAME(vixPlaybackSetDeint)( const vidix_deinterlace_t * info) { unsigned sflg; switch(info->flags) { default: case CFG_NON_INTERLACED: besr.deinterlace_on = 0; break; case CFG_EVEN_ODD_INTERLACING: case CFG_INTERLACED: besr.deinterlace_on = 1; besr.deinterlace_pattern = 0x900AAAAA; break; case CFG_ODD_EVEN_INTERLACING: besr.deinterlace_on = 1; besr.deinterlace_pattern = 0x00055555; break; case CFG_UNIQUE_INTERLACING: besr.deinterlace_on = 1; besr.deinterlace_pattern = info->deinterlace_pattern; break; } OUTREG(OV0_REG_LOAD_CNTL, REG_LD_CTL_LOCK); radeon_engine_idle(); while(!(INREG(OV0_REG_LOAD_CNTL)®_LD_CTL_LOCK_READBACK)); radeon_fifo_wait(15); sflg = INREG(OV0_SCALE_CNTL); if(besr.deinterlace_on) { OUTREG(OV0_SCALE_CNTL,sflg | SCALER_ADAPTIVE_DEINT); OUTREG(OV0_DEINTERLACE_PATTERN,besr.deinterlace_pattern); } else OUTREG(OV0_SCALE_CNTL,sflg & (~SCALER_ADAPTIVE_DEINT)); OUTREG(OV0_REG_LOAD_CNTL, 0); return 0; } int VIDIX_NAME(vixPlaybackGetDeint)( vidix_deinterlace_t * info) { if(!besr.deinterlace_on) info->flags = CFG_NON_INTERLACED; else { info->flags = CFG_UNIQUE_INTERLACING; info->deinterlace_pattern = besr.deinterlace_pattern; } return 0; } /* Graphic keys */ static vidix_grkey_t radeon_grkey; static void set_gr_key( void ) { if(radeon_grkey.ckey.op == CKEY_TRUE) { int dbpp=radeon_vid_get_dbpp(); switch(dbpp) { case 15: #ifndef RAGE128 besr.graphics_key_clr= ((radeon_grkey.ckey.blue &0xF8)) | ((radeon_grkey.ckey.green&0xF8)<<8) | ((radeon_grkey.ckey.red &0xF8)<<16); #else besr.graphics_key_clr= ((radeon_grkey.ckey.blue &0xF8)>>3) | ((radeon_grkey.ckey.green&0xF8)<<2) | ((radeon_grkey.ckey.red &0xF8)<<7); #endif break; case 16: #ifndef RAGE128 besr.graphics_key_clr= ((radeon_grkey.ckey.blue &0xF8)) | ((radeon_grkey.ckey.green&0xFC)<<8) | ((radeon_grkey.ckey.red &0xF8)<<16); #else besr.graphics_key_clr= ((radeon_grkey.ckey.blue &0xF8)>>3) | ((radeon_grkey.ckey.green&0xFC)<<3) | ((radeon_grkey.ckey.red &0xF8)<<8); #endif break; case 24: case 32: besr.graphics_key_clr= ((radeon_grkey.ckey.blue &0xFF)) | ((radeon_grkey.ckey.green&0xFF)<<8) | ((radeon_grkey.ckey.red &0xFF)<<16); break; default: besr.graphics_key_msk=0; besr.graphics_key_clr=0; } #ifdef RAGE128 besr.graphics_key_msk=(1<dest_offset + dmai->size > radeon_ram_size) return E2BIG; n = dmai->size / 4096; if(dmai->size % 4096) n++; if((retval = bm_virt_to_bus(dmai->src,dmai->size,dma_phys_addrs)) != 0) return retval; dest_ptr = dmai->dest_offset; count = dmai->size; for(i=0;i 4096 ? 4096 : count | BM_END_OF_LIST)|BM_FORCE_TO_PCI; #else list[i].command = (count > 4096 ? 4096 : count | DMA_GUI_COMMAND__EOL); #endif list[i].reserved = 0; printf("RADEON_DMA_TABLE[%i] %X %X %X %X\n",i,list[i].framebuf_offset,list[i].sys_addr,list[i].command,list[i].reserved); dest_ptr += 4096; count -= 4096; } return 0; } static int radeon_transfer_frame( void ) { unsigned i; radeon_engine_idle(); for(i=0;i<1000;i++) INREG(BUS_CNTL); /* FlushWriteCombining */ OUTREG(BUS_CNTL,(INREG(BUS_CNTL) | BUS_STOP_REQ_DIS)&(~BUS_MASTER_DIS)); #ifdef RAGE128 OUTREG(BM_CHUNK_0_VAL,0x000000FF | BM_GLOBAL_FORCE_TO_PCI); OUTREG(BM_CHUNK_1_VAL,0x0F0F0F0F); OUTREG(BM_VIP0_BUF,bus_addr_dma_desc|SYSTEM_TRIGGER_SYSTEM_TO_VIDEO); // OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|0x00010000); #else OUTREG(MC_FB_LOCATION, ((pci_info.base0>>16)&0xffff)| ((pci_info.base0+INREG(CONFIG_APER_SIZE)-1)&0xffff0000)); if((INREG(MC_AGP_LOCATION)&0xffff)!= (((pci_info.base0+INREG(CONFIG_APER_SIZE))>>16)&0xffff)) /*Radeon memory controller is misconfigured*/ return EINVAL; OUTREG(DMA_VID_ACT_DSCRPTR,bus_addr_dma_desc); // OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|(1<<30)); #endif OUTREG(GEN_INT_STATUS,INREG(GEN_INT_STATUS)|0x00010000); return 0; } int VIDIX_NAME(vixPlaybackCopyFrame)( vidix_dma_t * dmai ) { int retval; if(mlock(dmai->src,dmai->size) != 0) return errno; retval = radeon_setup_frame(dmai); if(retval == 0) retval = radeon_transfer_frame(); munlock(dmai->src,dmai->size); return retval; } int VIDIX_NAME(vixQueryDMAStatus)( void ) { int bm_active; #if 1 //def RAGE128 bm_active=(INREG(GEN_INT_STATUS)&0x00010000)==0?1:0; #else bm_active=(INREG(GEN_INT_STATUS)&(1<<30))==0?1:0; #endif return bm_active?1:0; } #endif xine-lib-1.2/contrib/vidix/drivers/savage_vid.c0000644000175000017500000011121614647725152017403 0ustar meme/* Driver for S3 Savage Series Copyright (C) 2004 by Reza Jelveh Based on the X11 driver and nvidia vid Thanks to Alex Deucher for Support This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Changes: 2004-11-09 Initial version To Do: */ #include #include #include #include #include #include #include #include "vidix.h" #include "fourcc.h" #include "libdha.h" #include "pci_ids.h" #include "pci_names.h" #include "savage_regs.h" #define VF_STREAMS_ON 0x0001 #define BASE_PAD 0xf #define FRAMEBUFFER_SIZE 1024*2000*4 /************************************** S3 streams processor **************************************/ #define EXT_MISC_CTRL2 0x67 /* New streams */ /* CR67[2] = 1 : enable stream 1 */ #define ENABLE_STREAM1 0x04 /* CR67[1] = 1 : enable stream 2 */ #define ENABLE_STREAM2 0x02 /* mask to clear CR67[2,1] */ #define NO_STREAMS 0xF9 /* CR67[3] = 1 : Mem-mapped regs */ #define USE_MM_FOR_PRI_STREAM 0x08 #define HDM_SHIFT 16 #define HDSCALE_4 (2 << HDM_SHIFT) #define HDSCALE_8 (3 << HDM_SHIFT) #define HDSCALE_16 (4 << HDM_SHIFT) #define HDSCALE_32 (5 << HDM_SHIFT) #define HDSCALE_64 (6 << HDM_SHIFT) /* Old Streams */ #define ENABLE_STREAMS_OLD 0x0c #define NO_STREAMS_OLD 0xf3 /* CR69[0] = 1 : Mem-mapped regs */ #define USE_MM_FOR_PRI_STREAM_OLD 0x01 static void SavageStreamsOn(void); /* * There are two different streams engines used in the Savage line. * The old engine is in the 3D, 4, Pro, and Twister. * The new engine is in the 2000, MX, IX, and Super. */ /* streams registers for old engine */ #define PSTREAM_CONTROL_REG 0x8180 #define COL_CHROMA_KEY_CONTROL_REG 0x8184 #define SSTREAM_CONTROL_REG 0x8190 #define CHROMA_KEY_UPPER_BOUND_REG 0x8194 #define SSTREAM_STRETCH_REG 0x8198 #define COLOR_ADJUSTMENT_REG 0x819C #define BLEND_CONTROL_REG 0x81A0 #define PSTREAM_FBADDR0_REG 0x81C0 #define PSTREAM_FBADDR1_REG 0x81C4 #define PSTREAM_STRIDE_REG 0x81C8 #define DOUBLE_BUFFER_REG 0x81CC #define SSTREAM_FBADDR0_REG 0x81D0 #define SSTREAM_FBADDR1_REG 0x81D4 #define SSTREAM_STRIDE_REG 0x81D8 #define SSTREAM_VSCALE_REG 0x81E0 #define SSTREAM_VINITIAL_REG 0x81E4 #define SSTREAM_LINES_REG 0x81E8 #define STREAMS_FIFO_REG 0x81EC #define PSTREAM_WINDOW_START_REG 0x81F0 #define PSTREAM_WINDOW_SIZE_REG 0x81F4 #define SSTREAM_WINDOW_START_REG 0x81F8 #define SSTREAM_WINDOW_SIZE_REG 0x81FC #define FIFO_CONTROL 0x8200 #define PSTREAM_FBSIZE_REG 0x8300 #define SSTREAM_FBSIZE_REG 0x8304 #define SSTREAM_FBADDR2_REG 0x8308 #define OS_XY(x,y) (((x+1)<<16)|(y+1)) #define OS_WH(x,y) (((x-1)<<16)|(y)) #define PCI_COMMAND_MEM 0x2 #define MAX_FRAMES 3 /** * @brief Information on PCI device. */ pciinfo_t pci_info; /** * @brief Unichrome driver colorkey settings. */ /* static vidix_grkey_t savage_grkey; */ /* static int frames[VID_PLAY_MAXFRAMES]; */ uint8_t *vio; uint8_t mclk_save[3]; #define outb(reg,val) OUTPORT8(reg,val) #define inb(reg) INPORT8(reg) #define outw(reg,val) OUTPORT16(reg,val) #define inw(reg) INPORT16(reg) #define outl(reg,val) OUTPORT32(reg,val) #define inl(reg) INPORT32(reg) /* * PCI-Memory IO access macros. */ #define VID_WR08(p,i,val) (((uint8_t *)(p))[(i)]=(val)) #define VID_RD08(p,i) (((uint8_t *)(p))[(i)]) #define VID_WR32(p,i,val) (((uint32_t *)(p))[(i)/4]=(val)) #define VID_RD32(p,i) (((uint32_t *)(p))[(i)/4]) #ifndef USE_RMW_CYCLES /* * Can be used to inhibit READ-MODIFY-WRITE cycles. On by default. */ #define MEM_BARRIER() __asm__ __volatile__ ("" : : : "memory") #undef VID_WR08 #define VID_WR08(p,i,val) ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]=(val); }) #undef VID_RD08 #define VID_RD08(p,i) ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]; }) #undef VID_WR16 #define VID_WR16(p,i,val) ({ MEM_BARRIER(); ((uint16_t *)(p))[(i)/2]=(val); }) #undef VID_RD16 #define VID_RD16(p,i) ({ MEM_BARRIER(); ((uint16_t *)(p))[(i)/2]; }) #undef VID_WR32 #define VID_WR32(p,i,val) ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]=(val); }) #undef VID_RD32 #define VID_RD32(p,i) ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]; }) #endif /* USE_RMW_CYCLES */ #define VID_AND32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)&(val)) #define VID_OR32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)|(val)) #define VID_XOR32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)^(val)) /* from x driver */ #define VGAIN8(addr) VID_RD08(info->control_base+0x8000, addr) #define VGAIN16(addr) VID_RD16(info->control_base+0x8000, addr) #define VGAIN(addr) VID_RD32(info->control_base+0x8000, addr) #define VGAOUT8(addr,val) VID_WR08(info->control_base+0x8000, addr, val) #define VGAOUT16(addr,val) VID_WR16(info->control_base+0x8000, addr, val) #define VGAOUT(addr,val) VID_WR32(info->control_base+0x8000, addr, val) #define INREG(addr) VID_RD32(info->control_base, addr) #define OUTREG(addr,val) VID_WR32(info->control_base, addr, val) #define INREG8(addr) VID_RD08(info->control_base, addr) #define OUTREG8(addr,val) VID_WR08(info->control_base, addr, val) #define INREG16(addr) VID_RD16(info->control_base, addr) #define OUTREG16(addr,val) VID_WR16(info->control_base, addr, val) #define ALIGN_TO(v, n) (((v) + (n-1)) & ~(n-1)) void debugout(unsigned int addr, unsigned int val); struct savage_chip { volatile uint32_t *PMC; /* general control */ volatile uint32_t *PME; /* multimedia port */ volatile uint32_t *PFB; /* framebuffer control */ volatile uint32_t *PVIDEO; /* overlay control */ volatile uint8_t *PCIO; /* SVGA (CRTC, ATTR) registers */ volatile uint8_t *PVIO; /* SVGA (MISC, GRAPH, SEQ) registers */ volatile uint32_t *PRAMIN; /* instance memory */ volatile uint32_t *PRAMHT; /* hash table */ volatile uint32_t *PRAMFC; /* fifo context table */ volatile uint32_t *PRAMRO; /* fifo runout table */ volatile uint32_t *PFIFO; /* fifo control region */ volatile uint32_t *FIFO; /* fifo channels (USER) */ volatile uint32_t *PGRAPH; /* graphics engine */ int arch; /* compatible NV_ARCH_XX define */ unsigned long fbsize; /* framebuffer size */ void (* lock) (struct savage_chip *, int); }; typedef struct savage_chip savage_chip; struct savage_info { unsigned int use_colorkey; unsigned int colorkey; /* saved xv colorkey*/ unsigned int vidixcolorkey; /*currently used colorkey*/ unsigned int depth; unsigned int bpp; unsigned int videoFlags; unsigned int format; unsigned int pitch; unsigned int blendBase; unsigned int lastKnownPitch; unsigned int displayWidth, displayHeight; unsigned int brightness,hue,saturation,contrast; unsigned int src_w,src_h; unsigned int drw_w,drw_h; /*scaled width && height*/ unsigned int wx,wy; /*window x && y*/ unsigned int screen_x; /*screen width*/ unsigned int screen_y; /*screen height*/ unsigned long buffer_size; /* size of the image buffer */ struct savage_chip chip; /* NV architecture structure */ uint8_t* video_base; /* virtual address of control region */ uint8_t* control_base; /* virtual address of fb region */ unsigned long picture_base; /* direct pointer to video picture */ unsigned long picture_offset; /* offset of video picture in frame buffer */ // struct savage_dma dma; /* DMA structure */ unsigned int cur_frame; unsigned int num_frames; /* number of buffers */ int bps; /* bytes per line */ void (*SavageWaitIdle) (); void (*SavageWaitFifo) (int space); }; typedef struct savage_info savage_info; static savage_info* info; /** * @brief Unichrome driver vidix capabilities. */ static vidix_capability_t savage_cap = { "Savage/ProSavage/Twister vidix", "Reza Jelveh ", TYPE_OUTPUT, {0, 0, 0, 0}, 4096, 4096, 4, 4, -1, FLAG_UPSCALER | FLAG_DOWNSCALER, VENDOR_S3_INC, -1, {0, 0, 0, 0} }; struct savage_cards { unsigned short chip_id; unsigned short arch; }; static unsigned int GetBlendForFourCC( int id ) { switch( id ) { case IMGFMT_YUY2: case IMGFMT_YV12: case IMGFMT_I420: return 1; case IMGFMT_Y211: return 4; case IMGFMT_RGB15: return 3; case IMGFMT_RGB16: return 5; default: return 0; } } /** * @brief list of card IDs compliant with the Unichrome driver . */ static struct savage_cards savage_card_ids[] = { /*[ProSavage PN133] AGP4X VGA Controller (Twister)*/ { PCI_CHIP_S3TWISTER_P, S3_PROSAVAGE }, /*[ProSavage KN133] AGP4X VGA Controller (TwisterK)*/ { PCI_CHIP_S3TWISTER_K, S3_PROSAVAGE }, /*ProSavage DDR*/ { PCI_CHIP_PROSAVAGE_DDR , S3_PROSAVAGE }, /*[ProSavageDDR P4M266 K] */ { PCI_CHIP_PROSAVAGE_DDRK , S3_PROSAVAGE }, }; static void SavageSetColorOld(void) { if( (info->format == IMGFMT_RGB15) || (info->format == IMGFMT_RGB16) ) { OUTREG( COLOR_ADJUSTMENT_REG, 0 ); } else { /* Change 0..255 into 0..15 */ long sat = info->saturation * 16 / 256; double hue = info->hue * 0.017453292; unsigned long hs1 = ((long)(sat * cos(hue))) & 0x1f; unsigned long hs2 = ((long)(sat * sin(hue))) & 0x1f; OUTREG( COLOR_ADJUSTMENT_REG, 0x80008000 | (info->brightness + 128) | ((info->contrast & 0xf8) << (12-7)) | (hs1 << 16) | (hs2 << 24) ); debugout( COLOR_ADJUSTMENT_REG, 0x80008000 | (info->brightness + 128) | ((info->contrast & 0xf8) << (12-7)) | (hs1 << 16) | (hs2 << 24) ); } } static void SavageSetColorKeyOld(void) { int red, green, blue; /* Here, we reset the colorkey and all the controls. */ red = (info->vidixcolorkey & 0x00FF0000) >> 16; green = (info->vidixcolorkey & 0x0000FF00) >> 8; blue = info->vidixcolorkey & 0x000000FF; if( !info->vidixcolorkey ) { printf("SavageSetColorKey disabling colour key\n"); OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0 ); OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0 ); OUTREG( BLEND_CONTROL_REG, 0 ); } else { switch (info->depth) { // FIXME: isnt fixed yet case 8: OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0x37000000 | (info->vidixcolorkey & 0xFF) ); OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (info->vidixcolorkey & 0xFF) ); break; case 15: /* 15 bpp 555 */ red&=0x1f; green&=0x1f; blue&=0x1f; OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0x05000000 | (red<<19) | (green<<11) | (blue<<3) ); OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (red<<19) | (green<<11) | (blue<<3) ); break; case 16: /* 16 bpp 565 */ red&=0x1f; green&=0x3f; blue&=0x1f; OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0x16000000 | (red<<19) | (green<<10) | (blue<<3) ); OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0x00020002 | (red<<19) | (green<<10) | (blue<<3) ); break; case 24: /* 24 bpp 888 */ OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0x17000000 | (red<<16) | (green<<8) | (blue) ); OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (red<<16) | (green<<8) | (blue) ); break; } /* We use destination colorkey */ OUTREG( BLEND_CONTROL_REG, 0x05000000 ); } } static void SavageDisplayVideoOld(void) { int vgaCRIndex, vgaCRReg, vgaIOBase; unsigned int ssControl; int cr92; vgaIOBase = 0x3d0; vgaCRIndex = vgaIOBase + 4; vgaCRReg = vgaIOBase + 5; // if( psav->videoFourCC != id ) // SavageStreamsOff(pScrn); if( !info->videoFlags & VF_STREAMS_ON ) { SavageStreamsOn(); // SavageResetVideo(); SavageSetColorOld(); SavageSetColorKeyOld(); } /* Set surface format. */ OUTREG(SSTREAM_CONTROL_REG,GetBlendForFourCC(info->format) << 24 | info->src_w); debugout(SSTREAM_CONTROL_REG,GetBlendForFourCC(info->format) << 24 | info->src_w); /* Calculate horizontal scale factor. */ //FIXME: enable scaling OUTREG(SSTREAM_STRETCH_REG, (info->src_w << 15) / info->drw_w ); // debugout(SSTREAM_STRETCH_REG, 1 << 15); OUTREG(SSTREAM_LINES_REG, info->src_h ); debugout(SSTREAM_LINES_REG, info->src_h ); OUTREG(SSTREAM_VINITIAL_REG, 0 ); debugout(SSTREAM_VINITIAL_REG, 0 ); /* Calculate vertical scale factor. */ // OUTREG(SSTREAM_VSCALE_REG, 1 << 15); OUTREG(SSTREAM_VSCALE_REG, VSCALING(info->src_h,info->drw_h) ); debugout(SSTREAM_VSCALE_REG, VSCALING(info->src_h,info->drw_h) ); // OUTREG(SSTREAM_VSCALE_REG, (info->src_h << 15) / info->drw_h ); /* Set surface location and stride. */ OUTREG(SSTREAM_FBADDR0_REG, info->picture_offset ); debugout(SSTREAM_FBADDR0_REG, info->picture_offset ); OUTREG(SSTREAM_FBADDR1_REG, 0 ); debugout(SSTREAM_FBADDR1_REG, 0 ); OUTREG(SSTREAM_STRIDE_REG, info->pitch ); debugout(SSTREAM_STRIDE_REG, info->pitch ); OUTREG(SSTREAM_WINDOW_START_REG, OS_XY(info->wx, info->wy) ); debugout(SSTREAM_WINDOW_START_REG, OS_XY(info->wx, info->wy) ); OUTREG(SSTREAM_WINDOW_SIZE_REG, OS_WH(info->drw_w, info->drw_h) ); debugout(SSTREAM_WINDOW_SIZE_REG, OS_WH(info->drw_w, info->drw_h) ); ssControl = 0; if( info->src_w > (info->drw_w << 1) ) { /* BUGBUG shouldn't this be >=? */ if( info->src_w <= (info->drw_w << 2) ) ssControl |= HDSCALE_4; else if( info->src_w > (info->drw_w << 3) ) ssControl |= HDSCALE_8; else if( info->src_w > (info->drw_w << 4) ) ssControl |= HDSCALE_16; else if( info->src_w > (info->drw_w << 5) ) ssControl |= HDSCALE_32; else if( info->src_w > (info->drw_w << 6) ) ssControl |= HDSCALE_64; } ssControl |= info->src_w; ssControl |= (1 << 24); //FIXME: enable scaling OUTREG(SSTREAM_CONTROL_REG, ssControl); debugout(SSTREAM_CONTROL_REG, ssControl); // FIXME: this should actually be enabled info->pitch = (info->pitch + 7) / 8; VGAOUT8(vgaCRIndex, 0x92); cr92 = VGAIN8(vgaCRReg); VGAOUT8(vgaCRReg, (cr92 & 0x40) | (info->pitch >> 8) | 0x80); VGAOUT8(vgaCRIndex, 0x93); VGAOUT8(vgaCRReg, info->pitch); OUTREG(STREAMS_FIFO_REG, 2 | 25 << 5 | 32 << 11); } static void SavageInitStreamsOld() { /*unsigned long jDelta;*/ unsigned long format = 0; /* * For the OLD streams engine, several of these registers * cannot be touched unless streams are on. Seems backwards to me; * I'd want to set 'em up, then cut 'em loose. */ /*jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8;*/ switch( info->depth ) { case 8: format = 0 << 24; break; case 15: format = 3 << 24; break; case 16: format = 5 << 24; break; case 24: format = 7 << 24; break; } #warning enable this again OUTREG(PSTREAM_FBSIZE_REG, info->screen_y * info->screen_x * (info->bpp >> 3)); OUTREG( PSTREAM_WINDOW_START_REG, OS_XY(0,0) ); OUTREG( PSTREAM_WINDOW_SIZE_REG, OS_WH(info->screen_x, info->screen_y) ); OUTREG( PSTREAM_FBADDR1_REG, 0 ); /*OUTREG( PSTREAM_STRIDE_REG, jDelta );*/ OUTREG( PSTREAM_CONTROL_REG, format ); OUTREG( PSTREAM_FBADDR0_REG, 0 ); /*OUTREG( PSTREAM_FBSIZE_REG, jDelta * pScrn->virtualY >> 3 );*/ OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0 ); OUTREG( SSTREAM_CONTROL_REG, 0 ); OUTREG( CHROMA_KEY_UPPER_BOUND_REG, 0 ); OUTREG( SSTREAM_STRETCH_REG, 0 ); OUTREG( COLOR_ADJUSTMENT_REG, 0 ); OUTREG( BLEND_CONTROL_REG, 1 << 24 ); OUTREG( DOUBLE_BUFFER_REG, 0 ); OUTREG( SSTREAM_FBADDR0_REG, 0 ); OUTREG( SSTREAM_FBADDR1_REG, 0 ); OUTREG( SSTREAM_FBADDR2_REG, 0 ); OUTREG( SSTREAM_FBSIZE_REG, 0 ); OUTREG( SSTREAM_STRIDE_REG, 0 ); OUTREG( SSTREAM_VSCALE_REG, 0 ); OUTREG( SSTREAM_LINES_REG, 0 ); OUTREG( SSTREAM_VINITIAL_REG, 0 ); #warning is this needed? OUTREG( SSTREAM_WINDOW_START_REG, OS_XY(0xfffe, 0xfffe) ); OUTREG( SSTREAM_WINDOW_SIZE_REG, OS_WH(10,2) ); } static void SavageStreamsOn() { unsigned char jStreamsControl; unsigned short vgaCRIndex = 0x3d0 + 4; unsigned short vgaCRReg = 0x3d0 + 5; // xf86ErrorFVerb(STREAMS_TRACE, "SavageStreamsOn\n" ); /* Sequence stolen from streams.c in M7 NT driver */ enable_app_io (); /* Unlock extended registers. */ /* FIXME: it looks like mmaped io is broken with vgaout16 */ VGAOUT16(vgaCRIndex, 0x4838 ); VGAOUT16(vgaCRIndex, 0xa039); VGAOUT16(0x3c4, 0x0608); VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 ); if( S3_SAVAGE_MOBILE_SERIES(info->chip.arch) ) { // SavageInitStreamsNew( pScrn ); jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAM1; /* Wait for VBLANK. */ VerticalRetraceWait(); /* Fire up streams! */ VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); /* These values specify brightness, contrast, saturation and hue. */ OUTREG( SEC_STREAM_COLOR_CONVERT1, 0x0000C892 ); OUTREG( SEC_STREAM_COLOR_CONVERT2, 0x00039F9A ); OUTREG( SEC_STREAM_COLOR_CONVERT3, 0x01F1547E ); } else if (info->chip.arch == S3_SAVAGE2000) { // SavageInitStreams2000( pScrn ); jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAM1; /* Wait for VBLANK. */ VerticalRetraceWait(); /* Fire up streams! */ VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); /* These values specify brightness, contrast, saturation and hue. */ OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, 0x0000C892 ); OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, 0x00033400 ); OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, 0x000001CF ); OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, 0x01F1547E ); } else { jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD; /* Wait for VBLANK. */ VerticalRetraceWait(); /* Fire up streams! */ VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); SavageInitStreamsOld( ); } /* Wait for VBLANK. */ VerticalRetraceWait(); /* Turn on secondary stream TV flicker filter, once we support TV. */ /* SR70 |= 0x10 */ info->videoFlags |= VF_STREAMS_ON; } static void savage_getscreenproperties(struct savage_info *info){ unsigned char bpp=0; /* uint32_t width=0; unused */ uint32_t vgaIOBase, vgaCRIndex, vgaCRReg; vgaIOBase = 0x3d0; vgaCRIndex = vgaIOBase + 4; vgaCRReg = vgaIOBase + 5; /* a little reversed from x driver source code */ VGAOUT8(vgaCRIndex, 0x67); bpp = VGAIN8(vgaCRReg); switch (bpp&0xf0) { case 0x00: case 0x10: info->depth=8; info->bpp=8; break; case 0x20: case 0x30: info->depth=15; info->bpp=16; break; case 0x40: case 0x50: info->depth=16; info->bpp=16; break; case 0x70: case 0xd0: info->depth=24; info->bpp=32; break; } VGAOUT8(vgaCRIndex, 0x1); info->screen_x = (1 + VGAIN8(vgaCRReg)) <<3; /*get screen height*/ /* get first 8 bits in VT_DISPLAY_END*/ VGAOUT8(0x03D4, 0x12); info->screen_y = VGAIN8(0x03D5); VGAOUT8(0x03D4,0x07); /* get 9th bit in CRTC_OVERFLOW*/ info->screen_y |= (VGAIN8(0x03D5) &0x02)<<7; /* and the 10th in CRTC_OVERFLOW*/ info->screen_y |=(VGAIN8(0x03D5) &0x40)<<3; ++info->screen_y; printf("screen_x = %d, screen_y = %d, bpp = %d\n",info->screen_x,info->screen_y,info->bpp); } static void SavageStreamsOff() { unsigned char jStreamsControl; unsigned short vgaCRIndex = 0x3d0 + 4; unsigned short vgaCRReg = 0x3d0 + 5; /* Unlock extended registers. */ VGAOUT16(vgaCRIndex, 0x4838); VGAOUT16(vgaCRIndex, 0xa039); VGAOUT16(0x3c4, 0x0608); VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 ); if( S3_SAVAGE_MOBILE_SERIES(info->chip.arch) || (info->chip.arch == S3_SUPERSAVAGE) || (info->chip.arch == S3_SAVAGE2000) ) jStreamsControl = VGAIN8( vgaCRReg ) & NO_STREAMS; else jStreamsControl = VGAIN8( vgaCRReg ) & NO_STREAMS_OLD; /* Wait for VBLANK. */ VerticalRetraceWait(); /* Kill streams. */ VGAOUT16(vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 ); VGAOUT16(vgaCRIndex, 0x0093 ); VGAOUT8( vgaCRIndex, 0x92 ); VGAOUT8( vgaCRReg, VGAIN8(vgaCRReg) & 0x40 ); info->videoFlags &= ~VF_STREAMS_ON; } /** * @brief Check age of driver. * * @return vidix version number. */ unsigned int vixGetVersion (void) { return (VIDIX_VERSION); } /** * @brief Find chip index in Unichrome compliant devices list. * * @param chip_id PCI device ID. * * @returns index position in savage_card_ids if successful. * -1 if chip_id is not a compliant chipset ID. */ static int find_chip(unsigned chip_id){ unsigned i; for(i = 0;i < sizeof(savage_card_ids)/sizeof(struct savage_cards);i++) { if(chip_id == savage_card_ids[i].chip_id)return i; } return -1; } /** * @brief Probe hardware to find some useable chipset. * * @param verbose specifies verbose level. * @param force specifies force mode : driver should ignore * device_id (danger but useful for new devices) * * @returns 0 if it can handle something in PC. * a negative error code otherwise. */ int vixProbe(int verbose, int force){ pciinfo_t lst[MAX_PCI_DEVICES]; unsigned i,num_pci; int err; if (force) printf("[savage_vid]: warning: forcing not supported yet!\n"); err = pci_scan(lst,&num_pci); if(err){ printf("[savage_vid] Error occurred during pci scan: %s\n",strerror(err)); return err; } else { err = ENXIO; for(i=0; i < num_pci; i++){ if(lst[i].vendor == VENDOR_S3_INC) { int idx; const char *dname; idx = find_chip(lst[i].device); if(idx == -1) continue; dname = pci_device_name(lst[i].vendor, lst[i].device); dname = dname ? dname : "Unknown chip"; printf("[savage_vid] Found chip: %s\n", dname); savage_cap.device_id = lst[i].device; err = 0; memcpy(&pci_info, &lst[i], sizeof(pciinfo_t)); break; } } } if(err && verbose) printf("[savage_vid] Can't find chip\n"); return err; } /** * @brief Initializes driver. * * @returns 0 if ok. * a negative error code otherwise. */ int vixInit (const char *args) { int mtrr; unsigned char config1, /* m, n, n1, n2, sr8, cr3f, cr66 = 0, */ tmp; static unsigned char RamSavage3D[] = { 8, 4, 4, 2 }; static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 }; static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 }; static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 16, 2 }; int videoRam /*, videoRambytes */; uint32_t vgaIOBase, vgaCRIndex, vgaCRReg ; unsigned char val; (void)args; vgaIOBase = 0x3d0; vgaCRIndex = vgaIOBase + 4; vgaCRReg = vgaIOBase + 5; fprintf(stderr, "vixInit enter \n"); // //getc(stdin); info = (savage_info*)calloc(1,sizeof(savage_info)); /* need this if we want direct outb and inb access? */ enable_app_io (); /* 12mb + 32kb ? */ /* allocate some space for control registers */ info->chip.arch = savage_card_ids[find_chip(pci_info.device)].arch; if (info->chip.arch == S3_SAVAGE3D) { info->control_base = map_phys_mem(pci_info.base0+SAVAGE_NEWMMIO_REGBASE_S3, SAVAGE_NEWMMIO_REGSIZE); } else { info->control_base = map_phys_mem(pci_info.base0+SAVAGE_NEWMMIO_REGBASE_S4, SAVAGE_NEWMMIO_REGSIZE); } // info->chip.PCIO = (uint8_t *) (info->control_base + SAVAGE_NEWMMIO_VGABASE); // FIXME: enable mmio? val = VGAIN8 (0x3c3); VGAOUT8 (0x3c3, val | 0x01); val = VGAIN8 (0x3cc); VGAOUT8 (0x3c2, val | 0x01); if (info->chip.arch >= S3_SAVAGE4) { VGAOUT8 (0x3d4, 0x40); val = VGAIN8 (0x3d5); VGAOUT8 (0x3d5, val | 1); } /* unprotect CRTC[0-7] */ VGAOUT8(vgaCRIndex, 0x11); tmp = VGAIN8(vgaCRReg); // printf("$########## tmp = %d\n",tmp); VGAOUT8(vgaCRReg, tmp & 0x7f); /* unlock extended regs */ VGAOUT16(vgaCRIndex, 0x4838); VGAOUT16(vgaCRIndex, 0xa039); VGAOUT16(0x3c4, 0x0608); VGAOUT8(vgaCRIndex, 0x40); tmp = VGAIN8(vgaCRReg); VGAOUT8(vgaCRReg, tmp & ~0x01); /* unlock sys regs */ VGAOUT8(vgaCRIndex, 0x38); VGAOUT8(vgaCRReg, 0x48); /* Unlock system registers. */ VGAOUT16(vgaCRIndex, 0x4838); /* Next go on to detect amount of installed ram */ VGAOUT8(vgaCRIndex, 0x36); /* for register CR36 (CONFG_REG1), */ config1 = VGAIN8(vgaCRReg); /* get amount of vram installed */ switch( info->chip.arch ) { case S3_SAVAGE3D: videoRam = RamSavage3D[ (config1 & 0xC0) >> 6 ] * 1024; break; case S3_SAVAGE4: /* * The Savage4 has one ugly special case to consider. On * systems with 4 banks of 2Mx32 SDRAM, the BIOS says 4MB * when it really means 8MB. Why do it the same when you * can do it different... */ VGAOUT8(0x3d4, 0x68); /* memory control 1 */ if( (VGAIN8(0x3d5) & 0xC0) == (0x01 << 6) ) RamSavage4[1] = 8; /*FALLTHROUGH*/ case S3_SAVAGE2000: videoRam = RamSavage4[ (config1 & 0xE0) >> 5 ] * 1024; break; case S3_SAVAGE_MX: videoRam = RamSavageMX[ (config1 & 0x0E) >> 1 ] * 1024; break; case S3_PROSAVAGE: videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ] * 1024; break; default: /* How did we get here? */ videoRam = 0; break; } printf("###### videoRam = %d\n",videoRam); info->chip.fbsize = videoRam * 1024; /* reset graphics engine to avoid memory corruption */ #if 0 VGAOUT8 (0x3d4, 0x66); cr66 = VGAIN8 (0x3d5); VGAOUT8 (0x3d5, cr66 | 0x02); udelay (10000); VGAOUT8 (0x3d4, 0x66); VGAOUT8 (0x3d5, cr66 & ~0x02); /* clear reset flag */ #endif /* udelay (10000); */ /* This maps framebuffer @6MB, thus 2MB are left for video. */ if (info->chip.arch == S3_SAVAGE3D) { info->video_base = map_phys_mem(pci_info.base0, info->chip.fbsize); info->picture_offset = 1024*768* 4 * ((info->chip.fbsize > 4194304)?2:1); } else { info->video_base = map_phys_mem(pci_info.base1, info->chip.fbsize); info->picture_offset = info->chip.fbsize - FRAMEBUFFER_SIZE; // info->picture_offset = 1024*1024* 4 * 2; } if ((intptr_t)info->video_base < 0) { printf("errno = %s\n", strerror(errno)); return -1; } info->picture_base = (uint32_t) info->video_base + info->picture_offset; if ( info->chip.arch == S3_SAVAGE3D ){ mtrr = mtrr_set_type(pci_info.base0, info->chip.fbsize, MTRR_TYPE_WRCOMB); } else{ mtrr = mtrr_set_type(pci_info.base1, info->chip.fbsize, MTRR_TYPE_WRCOMB); } if (mtrr!= 0) printf("[savage_vid] unable to setup MTRR: %s\n", strerror(mtrr)); else printf("[savage_vid] MTRR set up\n"); /* This may trash your screen for resolutions greater than 1024x768, sorry. */ savage_getscreenproperties(info); // return -1; info->videoFlags = 0; SavageStreamsOn(); //getc(stdin); //FIXME ADD return 0; } /** * @brief Destroys driver. */ void vixDestroy (void) { unmap_phys_mem(info->video_base, info->chip.fbsize); unmap_phys_mem(info->control_base, SAVAGE_NEWMMIO_REGSIZE); //FIXME ADD } /** * @brief Get chipset's hardware capabilities. * * @param to Pointer to the vidix_capability_t structure to be filled. * * @returns 0. */ int vixGetCapability (vidix_capability_t * to) { memcpy (to, &savage_cap, sizeof (vidix_capability_t)); return 0; } /** * @brief Report if the video FourCC is supported by hardware. * * @param fourcc input image format. * * @returns 1 if the fourcc is supported. * 0 otherwise. */ static int is_supported_fourcc (uint32_t fourcc) { switch (fourcc) { //FIXME: YV12 isnt working properly yet // case IMGFMT_YV12: // case IMGFMT_I420: case IMGFMT_UYVY: case IMGFMT_YVYU: case IMGFMT_YUY2: case IMGFMT_RGB15: case IMGFMT_RGB16: // case IMGFMT_BGR32: return 1; default: return 0; } } /** * @brief Try to configure video memory for given fourcc. * * @param to Pointer to the vidix_fourcc_t structure to be filled. * * @returns 0 if ok. * errno otherwise. */ int vixQueryFourcc (vidix_fourcc_t * to) { if (is_supported_fourcc (to->fourcc)) { to->depth = VID_DEPTH_1BPP | VID_DEPTH_2BPP | VID_DEPTH_4BPP | VID_DEPTH_8BPP | VID_DEPTH_12BPP | VID_DEPTH_15BPP | VID_DEPTH_16BPP | VID_DEPTH_24BPP | VID_DEPTH_32BPP; to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY; return 0; } else to->depth = to->flags = 0; return ENOSYS; } /** * @brief Get the GrKeys * * @param grkey Pointer to the vidix_grkey_t structure to be filled by driver. * * @return 0. */ /*int vixGetGrKeys (vidix_grkey_t * grkey) { // if(info->d_width && info->d_height)savage_overlay_start(info,0); return (0); } * */ /** * @brief Set the GrKeys * * @param grkey Colorkey to be set. * * @return 0. */ int vixSetGrKeys (const vidix_grkey_t * grkey) { if (grkey->ckey.op == CKEY_FALSE) { info->use_colorkey = 0; info->vidixcolorkey=0; printf("[savage_vid] colour keying disabled\n"); } else { info->use_colorkey = 1; info->vidixcolorkey = ((grkey->ckey.red<<16)|(grkey->ckey.green<<8)|grkey->ckey.blue); printf("[savage_vid] set colour key 0x%x\n",info->vidixcolorkey); } //FIXME: freezes if streams arent enabled SavageSetColorKeyOld(); return (0); } /** * @brief Unichrome driver equalizer capabilities. */ vidix_video_eq_t equal = { VEQ_CAP_BRIGHTNESS | VEQ_CAP_SATURATION | VEQ_CAP_HUE, 300, 100, 0, 0, 0, 0, 0, 0 }; /** * @brief Get the equalizer capabilities. * * @param eq Pointer to the vidix_video_eq_t structure to be filled by driver. * * @return 0. */ int vixPlaybackGetEq (vidix_video_eq_t * eq) { memcpy (eq, &equal, sizeof (vidix_video_eq_t)); return 0; } /** * @brief Set the equalizer capabilities for color correction * * @param eq equalizer capabilities to be set. * * @return 0. */ int vixPlaybackSetEq (const vidix_video_eq_t * eq) { (void)eq; return 0; } /** * @brief Y, U, V offsets. */ /* static int YOffs, UOffs, VOffs; */ /** * @brief Configure driver for playback. Driver should prepare BES. * * @param info configuration description for playback. * * @returns 0 in case of success. * -1 otherwise. */ int vixConfigPlayback (vidix_playback_t * vinfo) { int uv_size, swap_uv; unsigned int i; #if 0 int extfifo_on; int srcPitch,srcPitch2; /* Overlay register settings */ uint32_t win_start, win_end; uint32_t zoom, mini; uint32_t dcount, falign, qwfetch; uint32_t y_start, u_start, v_start; uint32_t v_ctrl, fifo_ctrl; #endif if (!is_supported_fourcc (vinfo->fourcc)) return -1; info->src_w = vinfo->src.w; info->src_h = vinfo->src.h; info->drw_w = vinfo->dest.w; info->drw_h = vinfo->dest.h; info->wx = vinfo->dest.x; info->wy = vinfo->dest.y; info->format = vinfo->fourcc; info->lastKnownPitch = 0; info->brightness = 0; info->contrast = 128; info->saturation = 128; info->hue = 0; vinfo->dga_addr=(void*)(info->picture_base); vinfo->offset.y = 0; vinfo->offset.v = 0; vinfo->offset.u = 0; vinfo->dest.pitch.y = 32; vinfo->dest.pitch.u = 32; vinfo->dest.pitch.v = 32; // vinfo->dest.pitch.u = 0; // vinfo->dest.pitch.v = 0; info->pitch = ((info->src_w << 1) + 15) & ~15; swap_uv = 0; switch (vinfo->fourcc) { case IMGFMT_YUY2: case IMGFMT_UYVY: info->pitch = ((info->src_w << 1) + (vinfo->dest.pitch.y-1)) & ~(vinfo->dest.pitch.y-1); info->pitch = info->src_w << 1; info->pitch = ALIGN_TO (info->src_w << 1, 32); uv_size = 0; break; case IMGFMT_YV12: swap_uv = 1; /* srcPitch = (info->src_w + 3) & ~3; vinfo->offset.u = srcPitch * info->src_h; srcPitch2 = ((info->src_w >> 1) + 3) & ~3; vinfo->offset.v = (srcPitch2 * (info->src_h >> 1)) + vinfo->offset.v; vinfo->dest.pitch.y=srcPitch ; vinfo->dest.pitch.v=srcPitch2 ; vinfo->dest.pitch.u=srcPitch2 ; */ info->pitch = ALIGN_TO (info->src_w, 32); uv_size = (info->pitch >> 1) * (info->src_h >> 1); vinfo->offset.y = 0; vinfo->offset.v = vinfo->offset.y + info->pitch * info->src_h; vinfo->offset.u = vinfo->offset.v + uv_size; vinfo->frame_size = vinfo->offset.u + uv_size; /* YOffs = info->offset.y; UOffs = (swap_uv ? vinfo->offset.v : vinfo->offset.u); VOffs = (swap_uv ? vinfo->offset.u : vinfo->offset.v); */ // vinfo->offset.y = info->src_w; // vinfo->offset.v = vinfo->offset.y + info->src_w /2 * info->src_h; // vinfo->offset.u = vinfo->offset.v + (info->src_w >> 1) * (info->src_h >> 1) ; break; } info->pitch |= ((info->pitch >> 1) << 16); vinfo->frame_size = info->pitch * info->src_h; printf("$#### destination pitch = %u\n", info->pitch&0xffff); info->buffer_size = vinfo->frame_size; info->num_frames = vinfo->num_frames= (info->chip.fbsize - info->picture_offset)/vinfo->frame_size; if(vinfo->num_frames > MAX_FRAMES)vinfo->num_frames = MAX_FRAMES; // vinfo->num_frames = 1; // printf("[nvidia_vid] Number of frames %i\n",vinfo->num_frames); for(i=0;i num_frames;i++)vinfo->offsets[i] = vinfo->frame_size*i; return 0; } /** * @brief Set playback on : driver should activate BES on this call. * * @return 0. */ int vixPlaybackOn (void) { // FIXME: enable SavageDisplayVideoOld(); //FIXME ADD return 0; } /** * @brief Set playback off : driver should deactivate BES on this call. * * @return 0. */ int vixPlaybackOff (void) { // otherwise we wont disable streams properly in new xorg // FIXME: shouldnt this be enabled? // SavageStreamsOn(); SavageStreamsOff(); // info->vidixcolorkey=0x0; // OUTREG( SSTREAM_WINDOW_START_REG, OS_XY(0xfffe, 0xfffe) ); // SavageSetColorKeyOld(); //FIXME ADD return 0; } /** * @brief Driver should prepare and activate corresponded frame. * * @param frame the frame index. * * @return 0. * * @note This function is used only for double and triple buffering * and never used for single buffering playback. */ #if 0 int vixPlaybackFrameSelect (unsigned int frame) { ////FIXME ADD // savage_overlay_start(info, frame); //if (info->num_frames >= 1) // info->cur_frame = frame//(frame+1)%info->num_frames; // // savage4_waitidle(info); printf("vixPlaybackFrameSelect Leave\n" ); // FIXME: does this work to avoid tearing? // VerticalRetraceWait(); return 0; } #endif void debugout(unsigned int addr, unsigned int val){ return ; switch ( addr ){ case PSTREAM_CONTROL_REG: fprintf(stderr,"PSTREAM_CONTROL_REG"); break; case COL_CHROMA_KEY_CONTROL_REG: fprintf(stderr,"COL_CHROMA_KEY_CONTROL_REG"); break; case SSTREAM_CONTROL_REG: fprintf(stderr,"SSTREAM_CONTROL_REG"); break; case CHROMA_KEY_UPPER_BOUND_REG: fprintf(stderr,"CHROMA_KEY_UPPER_BOUND_REG"); break; case SSTREAM_STRETCH_REG: fprintf(stderr,"SSTREAM_STRETCH_REG"); break; case COLOR_ADJUSTMENT_REG: fprintf(stderr,"COLOR_ADJUSTMENT_REG"); break; case BLEND_CONTROL_REG: fprintf(stderr,"BLEND_CONTROL_REG"); break; case PSTREAM_FBADDR0_REG: fprintf(stderr,"PSTREAM_FBADDR0_REG"); break; case PSTREAM_FBADDR1_REG: fprintf(stderr,"PSTREAM_FBADDR1_REG"); break; case PSTREAM_STRIDE_REG: fprintf(stderr,"PSTREAM_STRIDE_REG"); break; case DOUBLE_BUFFER_REG: fprintf(stderr,"DOUBLE_BUFFER_REG"); break; case SSTREAM_FBADDR0_REG: fprintf(stderr,"SSTREAM_FBADDR0_REG"); break; case SSTREAM_FBADDR1_REG: fprintf(stderr,"SSTREAM_FBADDR1_REG"); break; case SSTREAM_STRIDE_REG: fprintf(stderr,"SSTREAM_STRIDE_REG"); break; case SSTREAM_VSCALE_REG: fprintf(stderr,"SSTREAM_VSCALE_REG"); break; case SSTREAM_VINITIAL_REG: fprintf(stderr,"SSTREAM_VINITIAL_REG"); break; case SSTREAM_LINES_REG: fprintf(stderr,"SSTREAM_LINES_REG"); break; case STREAMS_FIFO_REG: fprintf(stderr,"STREAMS_FIFO_REG"); break; case PSTREAM_WINDOW_START_REG: fprintf(stderr,"PSTREAM_WINDOW_START_REG"); break; case PSTREAM_WINDOW_SIZE_REG: fprintf(stderr,"PSTREAM_WINDOW_SIZE_REG"); break; case SSTREAM_WINDOW_START_REG: fprintf(stderr,"SSTREAM_WINDOW_START_REG"); break; case SSTREAM_WINDOW_SIZE_REG: fprintf(stderr,"SSTREAM_WINDOW_SIZE_REG"); break; case FIFO_CONTROL: fprintf(stderr,"FIFO_CONTROL"); break; case PSTREAM_FBSIZE_REG: fprintf(stderr,"PSTREAM_FBSIZE_REG"); break; case SSTREAM_FBSIZE_REG: fprintf(stderr,"SSTREAM_FBSIZE_REG"); break; case SSTREAM_FBADDR2_REG: fprintf(stderr,"SSTREAM_FBADDR2_REG"); break; } fprintf(stderr,":\t\t 0x%08X = %u\n",val,val); } xine-lib-1.2/contrib/vidix/vidixlib.h0000644000175000017500000001053514647725152015436 0ustar meme/* * vidixlib.h * VIDIXLib - Library for VIDeo Interface for *niX * This interface is introduced as universal one to MPEG decoder, * BES == Back End Scaler and YUV2RGB hw accelerators. * In the future it may be expanded up to capturing and audio things. * Main goal of this this interface imlpementation is providing DGA * everywhere where it's possible (unlike X11 and other). * Copyright 2002 Nick Kurshev * Licence: GPL * This interface is based on v4l2, fbvid.h, mga_vid.h projects * and personally my ideas. * NOTE: This interface is introduces as APP interface. * Don't use it for driver. * It provides multistreaming. This mean that APP can handle * several streams simultaneously. (Example: Video capturing and video * playback or capturing, video playback, audio encoding and so on). */ #ifndef VIDIXLIB_H #define VIDIXLIB_H #ifdef __cplusplus extern "C" { #endif #include "vidix.h" typedef void * VDL_HANDLE; /* returns library version */ extern unsigned vdlGetVersion( void ); /* Opens corresponded video driver and returns handle of associated stream. path - specifies path where drivers are located. name - specifies prefered driver name (can be NULL). cap - specifies driver capability (TYPE_* constants). verbose - specifies verbose level returns !0 if ok else NULL. */ extern VDL_HANDLE vdlOpen(const char *path,const char *name,unsigned cap,int verbose); /* Closes stream and corresponded driver. */ extern void vdlClose(VDL_HANDLE stream); /* Queries driver capabilities. Return 0 if ok else errno */ extern int vdlGetCapability(VDL_HANDLE, vidix_capability_t *); /* Queries support for given fourcc. Returns 0 if ok else errno */ extern int vdlQueryFourcc(VDL_HANDLE,vidix_fourcc_t *); /* Returns 0 if ok else errno */ extern int vdlConfigPlayback(VDL_HANDLE, vidix_playback_t *); /* Returns 0 if ok else errno */ extern int vdlPlaybackOn(VDL_HANDLE); /* Returns 0 if ok else errno */ extern int vdlPlaybackOff(VDL_HANDLE); /* Returns 0 if ok else errno */ extern int vdlPlaybackFrameSelect(VDL_HANDLE, unsigned frame_idx ); /* Returns 0 if ok else errno */ extern int vdlGetGrKeys(VDL_HANDLE, vidix_grkey_t * ); /* Returns 0 if ok else errno */ extern int vdlSetGrKeys(VDL_HANDLE, const vidix_grkey_t * ); /* Returns 0 if ok else errno */ extern int vdlPlaybackGetEq(VDL_HANDLE, vidix_video_eq_t * ); /* Returns 0 if ok else errno */ extern int vdlPlaybackSetEq(VDL_HANDLE, const vidix_video_eq_t * ); /* Returns 0 if ok else errno */ extern int vdlPlaybackGetDeint(VDL_HANDLE, vidix_deinterlace_t * ); /* Returns 0 if ok else errno */ extern int vdlPlaybackSetDeint(VDL_HANDLE, const vidix_deinterlace_t * ); /* Returns 0 if ok else errno */ extern int vdlQueryNumOemEffects(VDL_HANDLE, unsigned * number ); /* Returns 0 if ok else errno */ extern int vdlGetOemEffect(VDL_HANDLE, vidix_oem_fx_t * ); /* Returns 0 if ok else errno */ extern int vdlSetOemEffect(VDL_HANDLE, const vidix_oem_fx_t * ); /* Returns 0 if ok else errno */ extern int vdlPlaybackCopyFrame(VDL_HANDLE, vidix_dma_t * ); /* Returns 0 if DMA is available else errno (EBUSY) */ extern int vdlQueryDMAStatus( VDL_HANDLE ); /* ABI related extensions. Note: you should use this functions if you are using shared version of vidix. */ extern vidix_capability_t * vdlAllocCapabilityS( void ); extern vidix_fourcc_t * vdlAllocFourccS( void ); extern vidix_playback_t * vdlAllocPlaybackS( void ); extern vidix_yuv_t * vdlAllocYUVS( void ); extern vidix_rect_t * vdlAllocRectS( void ); extern vidix_grkey_t * vdlAllocGrKeyS( void ); extern vidix_video_eq_t * vdlAllocVideoEqS( void ); extern vidix_deinterlace_t * vdlAllocDeinterlaceS( void ); extern vidix_dma_t * vdlAllocDmaS( void ); extern vidix_oem_fx_t * vdlAllocOemFxS( void ); extern void vdlFreeCapabilityS(vidix_capability_t * ); extern void vdlFreeFourccS( vidix_fourcc_t * ); extern void vdlFreePlaybackS( vidix_playback_t * ); extern void vdlFreeYUVS( vidix_yuv_t * ); extern void vdlFreeRectS( vidix_rect_t * ); extern void vdlFreeGrKeyS( vidix_grkey_t * ); extern void vdlFreeVideoEqS( vidix_video_eq_t * ); extern void vdlFreeDeinterlaceS( vidix_deinterlace_t * ); extern void vdlFreeDmaS( vidix_dma_t * ); extern void vdlFreeOemFxS( vidix_oem_fx_t * ); #ifdef __cplusplus } #endif #endif xine-lib-1.2/contrib/vidix/fourcc.h0000644000175000017500000000744314647725152015111 0ustar meme/* * fourcc.h * This file is part of VIDIX * Copyright 2002 Nick Kurshev * Licence: GPL * This interface is based on v4l2, fbvid.h, mga_vid.h projects * and personally my ideas. */ #ifndef FOURCC_H #define FOURCC_H /* Four-character-code (FOURCC) */ #define vid_fourcc(a,b,c,d)\ (((unsigned)(a)<<0)|((unsigned)(b)<<8)|((unsigned)(c)<<16)|((unsigned)(d)<<24)) /* RGB fourcc */ #define IMGFMT_RGB332 vid_fourcc('R','G','B','1') /* 8 RGB-3-3-2 */ #define IMGFMT_RGB555 vid_fourcc('R','G','B','O') /* 16 RGB-5-5-5 */ #define IMGFMT_RGB565 vid_fourcc('R','G','B','P') /* 16 RGB-5-6-5 */ #define IMGFMT_RGB555X vid_fourcc('R','G','B','Q') /* 16 RGB-5-5-5 BE */ #define IMGFMT_RGB565X vid_fourcc('R','G','B','R') /* 16 RGB-5-6-5 BE */ #define IMGFMT_BGR15 vid_fourcc('B','G','R',15) /* 15 BGR-5-5-5 */ #define IMGFMT_RGB15 vid_fourcc('R','G','B',15) /* 15 RGB-5-5-5 */ #define IMGFMT_BGR16 vid_fourcc('B','G','R',16) /* 32 BGR-5-6-5 */ #define IMGFMT_RGB16 vid_fourcc('R','G','B',16) /* 32 RGB-5-6-5 */ #define IMGFMT_BGR24 vid_fourcc('B','G','R',24) /* 24 BGR-8-8-8 */ #define IMGFMT_RGB24 vid_fourcc('R','G','B',24) /* 24 RGB-8-8-8 */ #define IMGFMT_BGR32 vid_fourcc('B','G','R',32) /* 32 BGR-8-8-8-8 */ #define IMGFMT_RGB32 vid_fourcc('R','G','B',32) /* 32 RGB-8-8-8-8 */ /* Planar YUV Formats */ #define IMGFMT_YVU9 vid_fourcc('Y','V','U','9') /* 9 YVU 4:1:0 */ #define IMGFMT_IF09 vid_fourcc('I','F','0','9') /* 9.5 YUV 4:1:0 */ #define IMGFMT_YV12 vid_fourcc('Y','V','1','2') /* 12 YVU 4:2:0 */ #define IMGFMT_I420 vid_fourcc('I','4','2','0') /* 12 YUV 4:2:0 */ #define IMGFMT_IYUV vid_fourcc('I','Y','U','V') /* 12 YUV 4:2:0 */ #define IMGFMT_CLPL vid_fourcc('C','L','P','L') /* 12 */ #define IMGFMT_Y800 vid_fourcc('Y','8','0','0') /* 8 Y Grayscale */ #define IMGFMT_NV12 vid_fourcc('N','V','1','2') /* 8 Y Grayscale */ #define IMGFMT_Y8 vid_fourcc('Y','8',' ',' ') /* 8 Y Grayscale */ /* Packed YUV Formats */ #define IMGFMT_IUYV vid_fourcc('I','U','Y','V') /* 16 line order {0,2,4,...1,3,5} */ #define IMGFMT_IY41 vid_fourcc('I','Y','4','1') /* 12 line order {0,2,4,...1,3,5} */ #define IMGFMT_IYU1 vid_fourcc('I','Y','U','1') /* 12 IEEE 1394 Digital Camera */ #define IMGFMT_IYU2 vid_fourcc('I','Y','U','2') /* 24 IEEE 1394 Digital Camera */ #define IMGFMT_UYVY vid_fourcc('U','Y','V','Y') /* 16 UYVY 4:2:2 */ #define IMGFMT_UYNV vid_fourcc('U','Y','N','V') /* 16 UYVY 4:2:2 */ #define IMGFMT_cyuv vid_fourcc('c','y','u','v') /* 16 */ #define IMGFMT_Y422 vid_fourcc('Y','4','2','2') /* 16 UYVY 4:2:2 */ #define IMGFMT_YUY2 vid_fourcc('Y','U','Y','2') /* 16 YUYV 4:2:2 */ #define IMGFMT_YUNV vid_fourcc('Y','U','N','V') /* 16 YUYV 4:2:2 */ #define IMGFMT_YVYU vid_fourcc('Y','V','Y','U') /* 16 YVYU 4:2:2 */ #define IMGFMT_Y41P vid_fourcc('Y','4','1','P') /* 12 YUV 4:1:1 */ #define IMGFMT_Y211 vid_fourcc('Y','2','1','1') /* 8.5 YUV 2:1:1 */ #define IMGFMT_Y41T vid_fourcc('Y','4','1','T') /* 12 YUV 4:1:1 */ #define IMGFMT_Y42T vid_fourcc('Y','4','2','T') /* 16 UYVU 4:2:2 */ #define IMGFMT_V422 vid_fourcc('V','4','2','2') /* 16 YUY2 4:2:2 */ #define IMGFMT_V655 vid_fourcc('V','6','5','5') /* 16 YUV 4:2:2 */ #define IMGFMT_CLJR vid_fourcc('C','L','J','R') /* 7.9 YUV 4:1:1 */ #define IMGFMT_YUVP vid_fourcc('Y','U','V','P') /* 24 Y0U0Y1V0 */ #define IMGFMT_UYVP vid_fourcc('U','Y','V','P') /* 24 U0Y0V0Y1 */ #define IMGFMT_411P vid_fourcc('4','1','1','P') /* 12 alias of Y41B */ #define IMGFMT_422P vid_fourcc('4','2','2','P') /* 16 alias of Y42B */ #define IMGFMT_444P vid_fourcc('4','4','4','P') /* 24 alias of Y44B */ /* Vendor-specific formats */ #define IMGFMT_WNVA vid_fourcc('W','N','V','A') /* Winnov hw compress */ #endif xine-lib-1.2/contrib/nosefart/0000755000175000017500000000000014647725152014145 5ustar memexine-lib-1.2/contrib/nosefart/vrc7_snd.h0000644000175000017500000000356514647725152016054 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** vrc7_snd.h ** ** VRCVII (Konami MMC) sound hardware emulation header ** Thanks to Charles MacDonald (cgfm2@hooked.net) for donating code. ** ** $Id: vrc7_snd.h,v 1.1 2003/01/08 07:04:36 tmmm Exp $ */ #ifndef _VRC7_SND_H_ #define _VRC7_SND_H_ #include "fmopl.h" /* VRC7 context */ typedef struct vrc7_s { uint8 reg[0x40]; /* 64 registers */ uint8 latch; /* Register latch */ uint8 user[0x10]; /* User instrument settings */ struct { uint16 frequency; /* Channel frequency */ uint8 volume; /* Channel volume */ uint8 instrument; /* Channel instrument */ } channel[9]; FM_OPL *ym3812; } vrc7_t; #include "nes_apu.h" extern apuext_t vrc7_ext; #endif /* !_VRC7_SND_H_ */ /* ** $Log: vrc7_snd.h,v $ ** Revision 1.1 2003/01/08 07:04:36 tmmm ** initial import of Nosefart sources ** ** Revision 1.3 2000/07/04 04:51:02 matt ** made data types stricter ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.1 2000/06/20 00:06:47 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/fmopl.c0000644000175000017500000010265014647725152015432 0ustar meme/* ** ** File: fmopl.c -- software implementation of FM sound generator ** ** Copyright (C) 1999 Tatsuyuki Satoh , MultiArcadeMachineEmurator development ** ** Version 0.36f ** */ /* preliminary : Problem : note: */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include //#include "driver.h" /* use M.A.M.E. */ #include "fmopl.h" /* MPC - hacks */ #include "types.h" #include "log.h" #ifndef PI #define PI 3.14159265358979323846 #endif /* -------------------- preliminary define section --------------------- */ /* attack/decay rate time rate */ #define OPL_ARRATE 141280 /* RATE 4 = 2826.24ms @ 3.6MHz */ #define OPL_DRRATE 1956000 /* RATE 4 = 39280.64ms @ 3.6MHz */ #define DELTAT_MIXING_LEVEL (1) /* DELTA-T ADPCM MIXING LEVEL */ #define FREQ_BITS 24 /* frequency turn */ /* counter bits = 20 , octerve 7 */ #define FREQ_RATE (1<<(FREQ_BITS-20)) #define TL_BITS (FREQ_BITS+2) /* final output shift , limit minimum and maximum */ #define OPL_OUTSB (TL_BITS+3-16) /* OPL output final shift 16bit */ #define OPL_MAXOUT (0x7fff<=LOG_LEVEL ) logerror x #define LOG(n,x) if( (n)>=LOG_LEVEL ) log_printf x /* --------------------- subroutines --------------------- */ INLINE int Limit( int val, int max, int min ) { if ( val > max ) val = max; else if ( val < min ) val = min; return val; } /* status set and IRQ handling */ INLINE void OPL_STATUS_SET(FM_OPL *OPL,int flag) { /* set status flag */ OPL->status |= flag; if(!(OPL->status & 0x80)) { if(OPL->status & OPL->statusmask) { /* IRQ on */ OPL->status |= 0x80; /* callback user interrupt handler (IRQ is OFF to ON) */ if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,1); } } } /* status reset and IRQ handling */ INLINE void OPL_STATUS_RESET(FM_OPL *OPL,int flag) { /* reset status flag */ OPL->status &=~flag; if((OPL->status & 0x80)) { if (!(OPL->status & OPL->statusmask) ) { OPL->status &= 0x7f; /* callback user interrupt handler (IRQ is ON to OFF) */ if(OPL->IRQHandler) (OPL->IRQHandler)(OPL->IRQParam,0); } } } /* IRQ mask set */ INLINE void OPL_STATUSMASK_SET(FM_OPL *OPL,int flag) { OPL->statusmask = flag; /* IRQ handling check */ OPL_STATUS_SET(OPL,0); OPL_STATUS_RESET(OPL,0); } /* ----- key on ----- */ INLINE void OPL_KEYON(OPL_SLOT *SLOT) { /* sin wave restart */ SLOT->Cnt = 0; /* set attack */ SLOT->evm = ENV_MOD_AR; SLOT->evs = SLOT->evsa; SLOT->evc = EG_AST; SLOT->eve = EG_AED; } /* ----- key off ----- */ INLINE void OPL_KEYOFF(OPL_SLOT *SLOT) { if( SLOT->evm > ENV_MOD_RR) { /* set envelope counter from envleope output */ SLOT->evm = ENV_MOD_RR; if( !(SLOT->evc&EG_DST) ) //SLOT->evc = (ENV_CURVE[SLOT->evc>>ENV_BITS]<evc = EG_DST; SLOT->eve = EG_DED; SLOT->evs = SLOT->evsr; } } /* ---------- calcrate Envelope Generator & Phase Generator ---------- */ /* return : envelope output */ INLINE UINT32 OPL_CALC_SLOT( OPL_SLOT *SLOT ) { /* calcrate envelope generator */ if( (SLOT->evc+=SLOT->evs) >= SLOT->eve ) { switch( SLOT->evm ){ case ENV_MOD_AR: /* ATTACK -> DECAY1 */ /* next DR */ SLOT->evm = ENV_MOD_DR; SLOT->evc = EG_DST; SLOT->eve = SLOT->SL; SLOT->evs = SLOT->evsd; break; case ENV_MOD_DR: /* DECAY -> SL or RR */ SLOT->evc = SLOT->SL; SLOT->eve = EG_DED; if(SLOT->eg_typ) { SLOT->evs = 0; } else { SLOT->evm = ENV_MOD_RR; SLOT->evs = SLOT->evsr; } break; case ENV_MOD_RR: /* RR -> OFF */ SLOT->evc = EG_OFF; SLOT->eve = EG_OFF+1; SLOT->evs = 0; break; } } /* calcrate envelope */ return SLOT->TLL+ENV_CURVE[SLOT->evc>>ENV_BITS]+(SLOT->ams ? ams : 0); } /* set algorythm connection */ static void set_algorythm( OPL_CH *CH) { INT32 *carrier = &outd[0]; CH->connect1 = CH->CON ? carrier : &feedback2; CH->connect2 = carrier; } /* ---------- frequency counter for operater update ---------- */ INLINE void CALC_FCSLOT(OPL_CH *CH,OPL_SLOT *SLOT) { int ksr; /* frequency step counter */ SLOT->Incr = CH->fc * SLOT->mul; ksr = CH->kcode >> SLOT->KSR; if( SLOT->ksr != ksr ) { SLOT->ksr = ksr; /* attack , decay rate recalcration */ SLOT->evsa = SLOT->AR[ksr]; SLOT->evsd = SLOT->DR[ksr]; SLOT->evsr = SLOT->RR[ksr]; } SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); } /* set multi,am,vib,EG-TYP,KSR,mul */ INLINE void set_mul(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; SLOT->mul = MUL_TABLE[v&0x0f]; SLOT->KSR = (v&0x10) ? 0 : 2; SLOT->eg_typ = (v&0x20)>>5; SLOT->vib = (v&0x40); SLOT->ams = (v&0x80); CALC_FCSLOT(CH,SLOT); } /* set ksl & tl */ INLINE void set_ksl_tl(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; int ksl = v>>6; /* 0 / 1.5 / 3 / 6 db/OCT */ SLOT->ksl = ksl ? 3-ksl : 31; SLOT->TL = (INT32) (((v&0x3f)*(0.75/EG_STEP))); /* 0.75db step */ if( !(OPL->mode&0x80) ) { /* not CSM latch total level */ SLOT->TLL = SLOT->TL + (CH->ksl_base>>SLOT->ksl); } } /* set attack rate & decay rate */ INLINE void set_ar_dr(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; int ar = v>>4; int dr = v&0x0f; SLOT->AR = ar ? &OPL->AR_TABLE[ar<<2] : RATE_0; SLOT->evsa = SLOT->AR[SLOT->ksr]; if( SLOT->evm == ENV_MOD_AR ) SLOT->evs = SLOT->evsa; SLOT->DR = dr ? &OPL->DR_TABLE[dr<<2] : RATE_0; SLOT->evsd = SLOT->DR[SLOT->ksr]; if( SLOT->evm == ENV_MOD_DR ) SLOT->evs = SLOT->evsd; } /* set sustain level & release rate */ INLINE void set_sl_rr(FM_OPL *OPL,int slot,int v) { OPL_CH *CH = &OPL->P_CH[slot/2]; OPL_SLOT *SLOT = &CH->SLOT[slot&1]; int sl = v>>4; int rr = v & 0x0f; SLOT->SL = SL_TABLE[sl]; if( SLOT->evm == ENV_MOD_DR ) SLOT->eve = SLOT->SL; SLOT->RR = &OPL->DR_TABLE[rr<<2]; SLOT->evsr = SLOT->RR[SLOT->ksr]; if( SLOT->evm == ENV_MOD_RR ) SLOT->evs = SLOT->evsr; } /* operator output calcrator */ #define OP_OUT(slot,env,con) slot->wavetable[((slot->Cnt+con)/(0x1000000/SIN_ENT))&(SIN_ENT-1)][env] /* ---------- calcrate one of channel ---------- */ INLINE void OPL_CALC_CH( OPL_CH *CH ) { UINT32 env_out; OPL_SLOT *SLOT; feedback2 = 0; /* SLOT 1 */ SLOT = &CH->SLOT[SLOT1]; env_out=OPL_CALC_SLOT(SLOT); if( env_out < EG_ENT-1 ) { /* PG */ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); else SLOT->Cnt += SLOT->Incr; /* connectoion */ if(CH->FB) { int feedback1 = (CH->op1_out[0]+CH->op1_out[1])>>CH->FB; CH->op1_out[1] = CH->op1_out[0]; *CH->connect1 += CH->op1_out[0] = OP_OUT(SLOT,env_out,feedback1); } else { *CH->connect1 += OP_OUT(SLOT,env_out,0); } }else { CH->op1_out[1] = CH->op1_out[0]; CH->op1_out[0] = 0; } /* SLOT 2 */ SLOT = &CH->SLOT[SLOT2]; env_out=OPL_CALC_SLOT(SLOT); if( env_out < EG_ENT-1 ) { /* PG */ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); else SLOT->Cnt += SLOT->Incr; /* connectoion */ outd[0] += OP_OUT(SLOT,env_out, feedback2); } } /* ---------- calcrate rythm block ---------- */ #define WHITE_NOISE_db 6.0 INLINE void OPL_CALC_RH( OPL_CH *CH ) { UINT32 env_tam,env_sd,env_top,env_hh; int whitenoise = (rand()&1)*((int)(WHITE_NOISE_db/EG_STEP)); INT32 tone8; OPL_SLOT *SLOT; int env_out; /* BD : same as FM serial mode and output level is large */ feedback2 = 0; /* SLOT 1 */ SLOT = &CH[6].SLOT[SLOT1]; env_out=OPL_CALC_SLOT(SLOT); if( env_out < EG_ENT-1 ) { /* PG */ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); else SLOT->Cnt += SLOT->Incr; /* connectoion */ if(CH[6].FB) { int feedback1 = (CH[6].op1_out[0]+CH[6].op1_out[1])>>CH[6].FB; CH[6].op1_out[1] = CH[6].op1_out[0]; feedback2 = CH[6].op1_out[0] = OP_OUT(SLOT,env_out,feedback1); } else { feedback2 = OP_OUT(SLOT,env_out,0); } }else { feedback2 = 0; CH[6].op1_out[1] = CH[6].op1_out[0]; CH[6].op1_out[0] = 0; } /* SLOT 2 */ SLOT = &CH[6].SLOT[SLOT2]; env_out=OPL_CALC_SLOT(SLOT); if( env_out < EG_ENT-1 ) { /* PG */ if(SLOT->vib) SLOT->Cnt += (SLOT->Incr*vib/VIB_RATE); else SLOT->Cnt += SLOT->Incr; /* connectoion */ outd[0] += OP_OUT(SLOT,env_out, feedback2)*2; } // SD (17) = mul14[fnum7] + white noise // TAM (15) = mul15[fnum8] // TOP (18) = fnum6(mul18[fnum8]+whitenoise) // HH (14) = fnum7(mul18[fnum8]+whitenoise) + white noise env_sd =OPL_CALC_SLOT(SLOT7_2) + whitenoise; env_tam=OPL_CALC_SLOT(SLOT8_1); env_top=OPL_CALC_SLOT(SLOT8_2); env_hh =OPL_CALC_SLOT(SLOT7_1) + whitenoise; /* PG */ if(SLOT7_1->vib) SLOT7_1->Cnt += (2*SLOT7_1->Incr*vib/VIB_RATE); else SLOT7_1->Cnt += 2*SLOT7_1->Incr; if(SLOT7_2->vib) SLOT7_2->Cnt += ((CH[7].fc*8)*vib/VIB_RATE); else SLOT7_2->Cnt += (CH[7].fc*8); if(SLOT8_1->vib) SLOT8_1->Cnt += (SLOT8_1->Incr*vib/VIB_RATE); else SLOT8_1->Cnt += SLOT8_1->Incr; if(SLOT8_2->vib) SLOT8_2->Cnt += ((CH[8].fc*48)*vib/VIB_RATE); else SLOT8_2->Cnt += (CH[8].fc*48); tone8 = OP_OUT(SLOT8_2,whitenoise,0 ); /* SD */ if( env_sd < EG_ENT-1 ) outd[0] += OP_OUT(SLOT7_1,env_sd, 0)*8; /* TAM */ if( env_tam < EG_ENT-1 ) outd[0] += OP_OUT(SLOT8_1,env_tam, 0)*2; /* TOP-CY */ if( env_top < EG_ENT-1 ) outd[0] += OP_OUT(SLOT7_2,env_top,tone8)*2; /* HH */ if( env_hh < EG_ENT-1 ) outd[0] += OP_OUT(SLOT7_2,env_hh,tone8)*2; } /* ----------- initialize time tabls ----------- */ static void init_timetables( FM_OPL *OPL , int ARRATE , int DRRATE ) { int i; double rate; /* make attack rate & decay rate tables */ for (i = 0;i < 4;i++) OPL->AR_TABLE[i] = OPL->DR_TABLE[i] = 0; for (i = 4;i <= 60;i++){ rate = OPL->freqbase; /* frequency rate */ if( i < 60 ) rate *= 1.0+(i&3)*0.25; /* b0-1 : x1 , x1.25 , x1.5 , x1.75 */ rate *= 1<<((i>>2)-1); /* b2-5 : shift bit */ rate *= (double)(EG_ENT<AR_TABLE[i] = (INT32) (rate / ARRATE); OPL->DR_TABLE[i] = (INT32) (rate / DRRATE); } for (i = 60;i < 76;i++) { OPL->AR_TABLE[i] = EG_AED-1; OPL->DR_TABLE[i] = OPL->DR_TABLE[60]; } #if 0 for (i = 0;i < 64 ;i++){ /* make for overflow area */ LOG(LOG_WAR,("rate %2d , ar %f ms , dr %f ms \n",i, ((double)(EG_ENT<AR_TABLE[i]) * (1000.0 / OPL->rate), ((double)(EG_ENT<DR_TABLE[i]) * (1000.0 / OPL->rate) )); } #endif } /* ---------- generic table initialize ---------- */ static int OPLOpenTable( void ) { int s,t; double rate; int i,j; double pom; /* allocate dynamic tables */ if( (TL_TABLE = malloc(TL_MAX*2*sizeof(INT32))) == NULL) return 0; if( (SIN_TABLE = malloc(SIN_ENT*4 *sizeof(INT32 *))) == NULL) { free(TL_TABLE); return 0; } if( (AMS_TABLE = malloc(AMS_ENT*2 *sizeof(INT32))) == NULL) { free(TL_TABLE); free(SIN_TABLE); return 0; } if( (VIB_TABLE = malloc(VIB_ENT*2 *sizeof(INT32))) == NULL) { free(TL_TABLE); free(SIN_TABLE); free(AMS_TABLE); return 0; } /* make total level table */ for (t = 0;t < EG_ENT-1 ;t++){ rate = ((1< voltage */ TL_TABLE[ t] = (int)rate; TL_TABLE[TL_MAX+t] = -TL_TABLE[t]; /* LOG(LOG_INF,("TotalLevel(%3d) = %x\n",t,TL_TABLE[t]));*/ } /* fill volume off area */ for ( t = EG_ENT-1; t < TL_MAX ;t++){ TL_TABLE[t] = TL_TABLE[TL_MAX+t] = 0; } /* make sinwave table (total level offet) */ /* degree 0 = degree 180 = off */ SIN_TABLE[0] = SIN_TABLE[SIN_ENT/2] = &TL_TABLE[EG_ENT-1]; for (s = 1;s <= SIN_ENT/4;s++){ pom = sin(2*PI*s/SIN_ENT); /* sin */ pom = 20*log10(1/pom); /* decibel */ j = (int) (pom / EG_STEP); /* TL_TABLE steps */ /* degree 0 - 90 , degree 180 - 90 : plus section */ SIN_TABLE[ s] = SIN_TABLE[SIN_ENT/2-s] = &TL_TABLE[j]; /* degree 180 - 270 , degree 360 - 270 : minus section */ SIN_TABLE[SIN_ENT/2+s] = SIN_TABLE[SIN_ENT -s] = &TL_TABLE[TL_MAX+j]; /* LOG(LOG_INF,("sin(%3d) = %f:%f db\n",s,pom,(double)j * EG_STEP));*/ } for (s = 0;s < SIN_ENT;s++) { SIN_TABLE[SIN_ENT*1+s] = s<(SIN_ENT/2) ? SIN_TABLE[s] : &TL_TABLE[EG_ENT]; SIN_TABLE[SIN_ENT*2+s] = SIN_TABLE[s % (SIN_ENT/2)]; SIN_TABLE[SIN_ENT*3+s] = (s/(SIN_ENT/4))&1 ? &TL_TABLE[EG_ENT] : SIN_TABLE[SIN_ENT*2+s]; } /* envelope counter -> envelope output table */ for (i=0; i= EG_ENT ) pom = EG_ENT-1; */ ENV_CURVE[i] = (int)pom; /* DECAY ,RELEASE curve */ ENV_CURVE[(EG_DST>>ENV_BITS)+i]= i; } /* off */ ENV_CURVE[EG_OFF>>ENV_BITS]= EG_ENT-1; /* make LFO ams table */ for (i=0; iSLOT[SLOT1]; OPL_SLOT *slot2 = &CH->SLOT[SLOT2]; /* all key off */ OPL_KEYOFF(slot1); OPL_KEYOFF(slot2); /* total level latch */ slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); slot1->TLL = slot1->TL + (CH->ksl_base>>slot1->ksl); /* key on */ CH->op1_out[0] = CH->op1_out[1] = 0; OPL_KEYON(slot1); OPL_KEYON(slot2); } /* ---------- opl initialize ---------- */ static void OPL_initalize(FM_OPL *OPL) { int fn; /* frequency base */ OPL->freqbase = (OPL->rate) ? ((double)OPL->clock / OPL->rate) / 72 : 0; /* Timer base time */ OPL->TimerBase = 1.0/((double)OPL->clock / 72.0 ); /* make time tables */ init_timetables( OPL , OPL_ARRATE , OPL_DRRATE ); /* make fnumber -> increment counter table */ for( fn=0 ; fn < 1024 ; fn++ ) { OPL->FN_TABLE[fn] = (UINT32) (OPL->freqbase * fn * FREQ_RATE * (1<<7) / 2); } /* LFO freq.table */ OPL->amsIncr = (INT32) (OPL->rate ? (double)AMS_ENT*(1<rate * 3.7 * ((double)OPL->clock/3600000) : 0); OPL->vibIncr = (INT32) (OPL->rate ? (double)VIB_ENT*(1<rate * 6.4 * ((double)OPL->clock/3600000) : 0); } /* ---------- write a OPL registers ---------- */ static void OPLWriteReg(FM_OPL *OPL, int r, int v) { OPL_CH *CH; int slot; unsigned int block_fnum; switch(r&0xe0) { case 0x00: /* 00-1f:controll */ switch(r&0x1f) { case 0x01: /* wave selector enable */ if(OPL->type&OPL_TYPE_WAVESEL) { OPL->wavesel = v&0x20; if(!OPL->wavesel) { /* preset compatible mode */ int c; for(c=0;cmax_ch;c++) { OPL->P_CH[c].SLOT[SLOT1].wavetable = &SIN_TABLE[0]; OPL->P_CH[c].SLOT[SLOT2].wavetable = &SIN_TABLE[0]; } } } return; case 0x02: /* Timer 1 */ OPL->T[0] = (256-v)*4; break; case 0x03: /* Timer 2 */ OPL->T[1] = (256-v)*16; return; case 0x04: /* IRQ clear / mask and Timer enable */ if(v&0x80) { /* IRQ flag clear */ OPL_STATUS_RESET(OPL,0x7f); } else { /* set IRQ mask ,timer enable*/ UINT8 st1 = v&1; UINT8 st2 = (v>>1)&1; /* IRQRST,T1MSK,t2MSK,EOSMSK,BRMSK,x,ST2,ST1 */ OPL_STATUS_RESET(OPL,v&0x78); OPL_STATUSMASK_SET(OPL,((~v)&0x78)|0x01); /* timer 2 */ if(OPL->st[1] != st2) { double interval = st2 ? (double)OPL->T[1]*OPL->TimerBase : 0.0; OPL->st[1] = st2; if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+1,interval); } /* timer 1 */ if(OPL->st[0] != st1) { double interval = st1 ? (double)OPL->T[0]*OPL->TimerBase : 0.0; OPL->st[0] = st1; if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+0,interval); } } return; #if BUILD_Y8950 case 0x06: /* Key Board OUT */ if(OPL->type&OPL_TYPE_KEYBOARD) { if(OPL->keyboardhandler_w) OPL->keyboardhandler_w(OPL->keyboard_param,v); else LOG(LOG_WAR,("OPL:write unmapped KEYBOARD port\n")); } return; case 0x07: /* DELTA-T controll : START,REC,MEMDATA,REPT,SPOFF,x,x,RST */ if(OPL->type&OPL_TYPE_ADPCM) YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); return; case 0x08: /* MODE,DELTA-T : CSM,NOTESEL,x,x,smpl,da/ad,64k,rom */ OPL->mode = v; v&=0x1f; /* for DELTA-T unit */ case 0x09: /* START ADD */ case 0x0a: case 0x0b: /* STOP ADD */ case 0x0c: case 0x0d: /* PRESCALE */ case 0x0e: case 0x0f: /* ADPCM data */ case 0x10: /* DELTA-N */ case 0x11: /* DELTA-N */ case 0x12: /* EG-CTRL */ if(OPL->type&OPL_TYPE_ADPCM) YM_DELTAT_ADPCM_Write(OPL->deltat,r-0x07,v); return; #if 0 case 0x15: /* DAC data */ case 0x16: case 0x17: /* SHIFT */ return; case 0x18: /* I/O CTRL (Direction) */ if(OPL->type&OPL_TYPE_IO) OPL->portDirection = v&0x0f; return; case 0x19: /* I/O DATA */ if(OPL->type&OPL_TYPE_IO) { OPL->portLatch = v; if(OPL->porthandler_w) OPL->porthandler_w(OPL->port_param,v&OPL->portDirection); } return; case 0x1a: /* PCM data */ return; #endif #endif } break; case 0x20: /* am,vib,ksr,eg type,mul */ slot = slot_array[r&0x1f]; if(slot == -1) return; set_mul(OPL,slot,v); return; case 0x40: slot = slot_array[r&0x1f]; if(slot == -1) return; set_ksl_tl(OPL,slot,v); return; case 0x60: slot = slot_array[r&0x1f]; if(slot == -1) return; set_ar_dr(OPL,slot,v); return; case 0x80: slot = slot_array[r&0x1f]; if(slot == -1) return; set_sl_rr(OPL,slot,v); return; case 0xa0: switch(r) { case 0xbd: /* amsep,vibdep,r,bd,sd,tom,tc,hh */ { UINT8 rkey = OPL->rythm^v; OPL->ams_table = &AMS_TABLE[v&0x80 ? AMS_ENT : 0]; OPL->vib_table = &VIB_TABLE[v&0x40 ? VIB_ENT : 0]; OPL->rythm = v&0x3f; if(OPL->rythm&0x20) { #if 0 usrintf_showmessage("OPL Rythm mode select"); #endif /* BD key on/off */ if(rkey&0x10) { if(v&0x10) { OPL->P_CH[6].op1_out[0] = OPL->P_CH[6].op1_out[1] = 0; OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT1]); OPL_KEYON(&OPL->P_CH[6].SLOT[SLOT2]); } else { OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT1]); OPL_KEYOFF(&OPL->P_CH[6].SLOT[SLOT2]); } } /* SD key on/off */ if(rkey&0x08) { if(v&0x08) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT2]); else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT2]); }/* TAM key on/off */ if(rkey&0x04) { if(v&0x04) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT1]); else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT1]); } /* TOP-CY key on/off */ if(rkey&0x02) { if(v&0x02) OPL_KEYON(&OPL->P_CH[8].SLOT[SLOT2]); else OPL_KEYOFF(&OPL->P_CH[8].SLOT[SLOT2]); } /* HH key on/off */ if(rkey&0x01) { if(v&0x01) OPL_KEYON(&OPL->P_CH[7].SLOT[SLOT1]); else OPL_KEYOFF(&OPL->P_CH[7].SLOT[SLOT1]); } } } return; } /* keyon,block,fnum */ if( (r&0x0f) > 8) return; CH = &OPL->P_CH[r&0x0f]; if(!(r&0x10)) { /* a0-a8 */ block_fnum = (CH->block_fnum&0x1f00) | v; } else { /* b0-b8 */ int keyon = (v>>5)&1; block_fnum = ((v&0x1f)<<8) | (CH->block_fnum&0xff); if(CH->keyon != keyon) { if( (CH->keyon=keyon) ) { CH->op1_out[0] = CH->op1_out[1] = 0; OPL_KEYON(&CH->SLOT[SLOT1]); OPL_KEYON(&CH->SLOT[SLOT2]); } else { OPL_KEYOFF(&CH->SLOT[SLOT1]); OPL_KEYOFF(&CH->SLOT[SLOT2]); } } } /* update */ if(CH->block_fnum != block_fnum) { int blockRv = 7-(block_fnum>>10); int fnum = block_fnum&0x3ff; CH->block_fnum = block_fnum; CH->ksl_base = KSL_TABLE[block_fnum>>6]; CH->fc = OPL->FN_TABLE[fnum]>>blockRv; CH->kcode = CH->block_fnum>>9; if( (OPL->mode&0x40) && CH->block_fnum&0x100) CH->kcode |=1; CALC_FCSLOT(CH,&CH->SLOT[SLOT1]); CALC_FCSLOT(CH,&CH->SLOT[SLOT2]); } return; case 0xc0: /* FB,C */ if( (r&0x0f) > 8) return; CH = &OPL->P_CH[r&0x0f]; { int feedback = (v>>1)&7; CH->FB = feedback ? (8+1) - feedback : 0; CH->CON = v&1; set_algorythm(CH); } return; case 0xe0: /* wave type */ slot = slot_array[r&0x1f]; if(slot == -1) return; CH = &OPL->P_CH[slot/2]; if(OPL->wavesel) { /* LOG(LOG_INF,("OPL SLOT %d wave select %d\n",slot,v&3)); */ CH->SLOT[slot&1].wavetable = &SIN_TABLE[(v&0x03)*SIN_ENT]; } return; } } /* lock/unlock for common table */ static int OPL_LockTable(void) { num_lock++; if(num_lock>1) return 0; /* first time */ cur_chip = NULL; /* allocate total level table (128kb space) */ if( !OPLOpenTable() ) { num_lock--; return -1; } return 0; } static void OPL_UnLockTable(void) { if(num_lock) num_lock--; if(num_lock) return; /* last time */ cur_chip = NULL; OPLCloseTable(); } #if (BUILD_YM3812 || BUILD_YM3526) /*******************************************************************************/ /* YM3812 local section */ /*******************************************************************************/ /* ---------- update one of chip ----------- */ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) { int i; int data; FMSAMPLE *buf = buffer; UINT32 amsCnt = OPL->amsCnt; UINT32 vibCnt = OPL->vibCnt; UINT8 rythm = OPL->rythm&0x20; OPL_CH *CH,*R_CH; if( (void *)OPL != cur_chip ){ cur_chip = (void *)OPL; /* channel pointers */ S_CH = OPL->P_CH; E_CH = &S_CH[9]; /* rythm slot */ SLOT7_1 = &S_CH[7].SLOT[SLOT1]; SLOT7_2 = &S_CH[7].SLOT[SLOT2]; SLOT8_1 = &S_CH[8].SLOT[SLOT1]; SLOT8_2 = &S_CH[8].SLOT[SLOT2]; /* LFO state */ amsIncr = OPL->amsIncr; vibIncr = OPL->vibIncr; ams_table = OPL->ams_table; vib_table = OPL->vib_table; } R_CH = rythm ? &S_CH[6] : E_CH; for( i=0; i < length ; i++ ) { /* channel A channel B channel C */ /* LFO */ ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT]; vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT]; outd[0] = 0; /* FM part */ for(CH=S_CH ; CH < R_CH ; CH++) OPL_CALC_CH(CH); /* Rythn part */ if(rythm) OPL_CALC_RH(S_CH); /* limit check */ data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT ); /* store to sound buffer */ buf[i] = data >> OPL_OUTSB; } OPL->amsCnt = amsCnt; OPL->vibCnt = vibCnt; } #endif /* (BUILD_YM3812 || BUILD_YM3526) */ #if BUILD_Y8950 void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length) { int i; int data; FMSAMPLE *buf = buffer; UINT32 amsCnt = OPL->amsCnt; UINT32 vibCnt = OPL->vibCnt; UINT8 rythm = OPL->rythm&0x20; OPL_CH *CH,*R_CH; YM_DELTAT *DELTAT = OPL->deltat; /* setup DELTA-T unit */ YM_DELTAT_DECODE_PRESET(DELTAT); if( (void *)OPL != cur_chip ){ cur_chip = (void *)OPL; /* channel pointers */ S_CH = OPL->P_CH; E_CH = &S_CH[9]; /* rythm slot */ SLOT7_1 = &S_CH[7].SLOT[SLOT1]; SLOT7_2 = &S_CH[7].SLOT[SLOT2]; SLOT8_1 = &S_CH[8].SLOT[SLOT1]; SLOT8_2 = &S_CH[8].SLOT[SLOT2]; /* LFO state */ amsIncr = OPL->amsIncr; vibIncr = OPL->vibIncr; ams_table = OPL->ams_table; vib_table = OPL->vib_table; } R_CH = rythm ? &S_CH[6] : E_CH; for( i=0; i < length ; i++ ) { /* channel A channel B channel C */ /* LFO */ ams = ams_table[(amsCnt+=amsIncr)>>AMS_SHIFT]; vib = vib_table[(vibCnt+=vibIncr)>>VIB_SHIFT]; outd[0] = 0; /* deltaT ADPCM */ if( DELTAT->flag ) YM_DELTAT_ADPCM_CALC(DELTAT); /* FM part */ for(CH=S_CH ; CH < R_CH ; CH++) OPL_CALC_CH(CH); /* Rythn part */ if(rythm) OPL_CALC_RH(S_CH); /* limit check */ data = Limit( outd[0] , OPL_MAXOUT, OPL_MINOUT ); /* store to sound buffer */ buf[i] = data >> OPL_OUTSB; } OPL->amsCnt = amsCnt; OPL->vibCnt = vibCnt; /* deltaT START flag */ if( !DELTAT->flag ) OPL->status &= 0xfe; } #endif /* ---------- reset one of chip ---------- */ void OPLResetChip(FM_OPL *OPL) { int c,s; int i; /* reset chip */ OPL->mode = 0; /* normal mode */ OPL_STATUS_RESET(OPL,0x7f); /* reset with register write */ OPLWriteReg(OPL,0x01,0); /* wabesel disable */ OPLWriteReg(OPL,0x02,0); /* Timer1 */ OPLWriteReg(OPL,0x03,0); /* Timer2 */ OPLWriteReg(OPL,0x04,0); /* IRQ mask clear */ for(i = 0xff ; i >= 0x20 ; i-- ) OPLWriteReg(OPL,i,0); /* reset OPerator paramater */ for( c = 0 ; c < OPL->max_ch ; c++ ) { OPL_CH *CH = &OPL->P_CH[c]; /* OPL->P_CH[c].PAN = OPN_CENTER; */ for(s = 0 ; s < 2 ; s++ ) { /* wave table */ CH->SLOT[s].wavetable = &SIN_TABLE[0]; /* CH->SLOT[s].evm = ENV_MOD_RR; */ CH->SLOT[s].evc = EG_OFF; CH->SLOT[s].eve = EG_OFF+1; CH->SLOT[s].evs = 0; } } #if BUILD_Y8950 if(OPL->type&OPL_TYPE_ADPCM) { YM_DELTAT *DELTAT = OPL->deltat; DELTAT->freqbase = OPL->freqbase; DELTAT->output_pointer = outd; DELTAT->portshift = 5; DELTAT->output_range = DELTAT_MIXING_LEVEL<P_CH = (OPL_CH *)ptr; ptr+=sizeof(OPL_CH)*max_ch; #if BUILD_Y8950 if(type&OPL_TYPE_ADPCM) OPL->deltat = (YM_DELTAT *)ptr; ptr+=sizeof(YM_DELTAT); #endif /* set channel state pointer */ OPL->type = type; OPL->clock = clock; OPL->rate = rate; OPL->max_ch = max_ch; /* init grobal tables */ OPL_initalize(OPL); /* reset chip */ OPLResetChip(OPL); return OPL; } /* ---------- Destroy one of vietual YM3812 ---------- */ void OPLDestroy(FM_OPL *OPL) { OPL_UnLockTable(); free(OPL); } /* ---------- Option handlers ---------- */ void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset) { OPL->TimerHandler = TimerHandler; OPL->TimerParam = channelOffset; } void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param) { OPL->IRQHandler = IRQHandler; OPL->IRQParam = param; } void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param) { OPL->UpdateHandler = UpdateHandler; OPL->UpdateParam = param; } #if BUILD_Y8950 void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param) { OPL->porthandler_w = PortHandler_w; OPL->porthandler_r = PortHandler_r; OPL->port_param = param; } void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param) { OPL->keyboardhandler_w = KeyboardHandler_w; OPL->keyboardhandler_r = KeyboardHandler_r; OPL->keyboard_param = param; } #endif /* ---------- YM3812 I/O interface ---------- */ int OPLWrite(FM_OPL *OPL,int a,int v) { if( !(a&1) ) { /* address port */ OPL->address = v & 0xff; } else { /* data port */ if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); OPLWriteReg(OPL,OPL->address,v); } return OPL->status>>7; } unsigned char OPLRead(FM_OPL *OPL,int a) { if( !(a&1) ) { /* status port */ return OPL->status & (OPL->statusmask|0x80); } /* data port */ switch(OPL->address) { case 0x05: /* KeyBoard IN */ if(OPL->type&OPL_TYPE_KEYBOARD) { if(OPL->keyboardhandler_r) return OPL->keyboardhandler_r(OPL->keyboard_param); else LOG(LOG_WAR,("OPL:read unmapped KEYBOARD port\n")); } return 0; #if 0 case 0x0f: /* ADPCM-DATA */ return 0; #endif case 0x19: /* I/O DATA */ if(OPL->type&OPL_TYPE_IO) { if(OPL->porthandler_r) return OPL->porthandler_r(OPL->port_param); else LOG(LOG_WAR,("OPL:read unmapped I/O port\n")); } return 0; case 0x1a: /* PCM-DATA */ return 0; } return 0; } int OPLTimerOver(FM_OPL *OPL,int c) { if( c ) { /* Timer B */ OPL_STATUS_SET(OPL,0x20); } else { /* Timer A */ OPL_STATUS_SET(OPL,0x40); /* CSM mode key,TL controll */ if( OPL->mode & 0x80 ) { /* CSM mode total level latch and auto key on */ int ch; if(OPL->UpdateHandler) OPL->UpdateHandler(OPL->UpdateParam,0); for(ch=0;ch<9;ch++) CSMKeyControll( &OPL->P_CH[ch] ); } } /* reload timer */ if (OPL->TimerHandler) (OPL->TimerHandler)(OPL->TimerParam+c,(double)OPL->T[c]*OPL->TimerBase); return OPL->status>>7; } xine-lib-1.2/contrib/nosefart/memguard.h0000644000175000017500000000366214647725152016126 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** memguard.h ** ** memory allocation wrapper routines ** $Id: memguard.h,v 1.2 2003/03/01 02:23:01 storri Exp $ */ #ifndef _MEMGUARD_H_ #define _MEMGUARD_H_ #ifdef NOFRENDO_DEBUG #define malloc(s) _my_malloc((s), __FILE__, __LINE__) #define free(d) _my_free((void **) &(d), __FILE__, __LINE__) extern void *_my_malloc(int size, char *file, int line); extern void _my_free(void **data, char *file, int line); #else /* Non-debugging versions of calls */ #define malloc(s) _my_malloc((s)) #define free(d) do { _my_free(d); (d) = NULL; } while (0) extern void *_my_malloc(int size); extern void _my_free(void *data); #endif /* NOFRENDO_DEBUG */ extern void mem_checkblocks(void); extern void mem_checkleaks(void); extern boolean mem_debug; #endif /* _MEMGUARD_H_ */ /* ** $Log: memguard.h,v $ ** Revision 1.2 2003/03/01 02:23:01 storri ** Added new line at end of file to remove compiler warning. ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.5 2000/06/26 04:54:48 matt ** simplified and made more robust ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/types.h0000644000175000017500000001037414647725152015467 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** types.h ** ** Data type definitions ** $Id: types.h,v 1.4 2004/08/27 19:33:37 valtri Exp $ */ #ifndef _NOSEFART_TYPES_H_ #define _NOSEFART_TYPES_H_ #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included #endif /* Define this if running on little-endian (x86) systems */ #ifndef DCPLAYA # define HOST_LITTLE_ENDIAN #endif #ifdef __GNUC__ #define INLINE static inline #elif defined(WIN32) #define INLINE static __inline #else /* crapintosh? */ #define INLINE static #endif /* These should be changed depending on the platform */ #ifdef __BEOS__ /* added by Eli Dayan (for compiling under BeOS) */ /* use types in the BeOS Support Kit instead */ #include #elif defined (DCPLAYA) /* $$$ added by ben (for compiling with dcplaya) */ # include #else typedef char int8; typedef short int16; typedef int int32; typedef unsigned char uint8; typedef unsigned short uint16; typedef unsigned int uint32; #endif typedef uint8 boolean; #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef NULL #define NULL ((void *) 0) #endif #ifdef NOFRENDO_DEBUG #include #include "memguard.h" #include "log.h" #define ASSERT(expr) if (FALSE == (expr))\ {\ log_printf("ASSERT: line %d of %s\n", __LINE__, __FILE__);\ log_shutdown();\ exit(1);\ } #define ASSERT_MSG(msg) {\ log_printf("ASSERT: %s\n", msg);\ log_shutdown();\ exit(1);\ } #else /* Not debugging */ #include "memguard.h" #define ASSERT(expr) #define ASSERT_MSG(msg) #endif #endif /* _NOSEFART_TYPES_H_ */ /* ** $Log: types.h,v $ ** Revision 1.4 2004/08/27 19:33:37 valtri ** MINGW32 port. Engine library and most of plugins compiles now. ** ** List of some changes: ** - replaced some _MSC_VER by more common WIN32 ** - define INTLDIR, remove -static flag for included intl ** - shared more common CFLAGS with DEBUG_CFLAGS ** - use WIN32_CFLAGS for all building ** - separate some flags into THREAD_CFLAGS_CONFIG, ** THREAD_CFLAGS_CONFIG and ZLIB_LIB_CONFIG for public xine-config, ** automatically use internal libs if necessary ** - don't warn about missing X for mingw and cygwin ** - libw32dll disabled for WIN32 (making native loader would be ** interesting, or porting wine code to Windows? :->) ** - DVB and RTP disabled for WIN32, not ported yet ** - fix build and fix a warning in cdda ** - fix build for nosefart and libfaad ** - implement configure option --disable-freetype ** - sync libxine.pc and xine-config.in ** - add -liberty to goom under WIN32 ** - move original build files from included phread and zlib into archives ** and replace them by autotools ** ** Revision 1.3 2003/01/11 15:53:53 tmmm ** make the Nosefart engine aware of the config's WORDS_BIGENDIAN #define ** ** Revision 1.2 2003/01/09 19:50:04 jkeil ** NSF audio files were crashing on SPARC. ** ** - Define the correct HOST_ENDIAN for SPARC ** - remove unaligned memory accesses ** ** Revision 1.1 2003/01/08 07:04:36 tmmm ** initial import of Nosefart sources ** ** Revision 1.7 2000/07/04 04:46:44 matt ** moved INLINE define from osd.h ** ** Revision 1.6 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/dis6502.h0000644000175000017500000000334514647725152015417 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** dis6502.h ** ** 6502 disassembler header ** $Id: dis6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifndef _DIS6502_H_ #define _DIS6502_H_ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ extern void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 S); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* !_DIS6502_H_ */ /* ** $Log: dis6502.h,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/log.h0000644000175000017500000000350114647725152015076 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** log.h ** ** Error logging header file ** $Id: log.h,v 1.3 2006/04/21 23:15:45 dsalt Exp $ */ #ifndef _LOG_H_ #define _LOG_H_ #include #include extern int log_init(void); extern void log_shutdown(void); extern void log_print(const char *string); extern void log_printf(const char *format, ...) XINE_FORMAT_PRINTF(1, 2); #endif /* _LOG_H_ */ /* ** $Log: log.h,v $ ** Revision 1.3 2006/04/21 23:15:45 dsalt ** Add printf format attributes. ** ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/mmc5_snd.c0000644000175000017500000002046214647725152016022 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** mmc5_snd.c ** ** Nintendo MMC5 sound emulation ** $Id: mmc5_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "types.h" #include "mmc5_snd.h" #include "nes_apu.h" /* TODO: encapsulate apu/mmc5 rectangle */ #define APU_OVERSAMPLE #define APU_VOLUME_DECAY(x) ((x) -= ((x) >> 7)) typedef struct mmc5dac_s { int32 output; boolean enabled; } mmc5dac_t; /* look up table madness */ static int32 decay_lut[16]; static int vbl_lut[32]; /* various sound constants for sound emulation */ /* vblank length table used for rectangles, triangle, noise */ static const uint8 vbl_length[32] = { 5, 127, 10, 1, 19, 2, 40, 3, 80, 4, 30, 5, 7, 6, 13, 7, 6, 8, 12, 9, 24, 10, 48, 11, 96, 12, 36, 13, 8, 14, 16, 15 }; /* ratios of pos/neg pulse for rectangle waves ** 2/16 = 12.5%, 4/16 = 25%, 8/16 = 50%, 12/16 = 75% ** (4-bit adder in rectangles, hence the 16) */ static const int duty_lut[4] = { 2, 4, 8, 12 }; static int32 mmc5_incsize; static uint8 mul[2]; static mmc5rectangle_t mmc5rect[2]; static mmc5dac_t mmc5dac; #define MMC5_RECTANGLE_OUTPUT chan->output_vol static int32 mmc5_rectangle(mmc5rectangle_t *chan) { int32 output; #ifdef APU_OVERSAMPLE int num_times; int32 total; #endif /* APU_OVERSAMPLE */ /* reg0: 0-3=volume, 4=envelope, 5=hold, 6-7=duty cycle ** reg1: 0-2=sweep shifts, 3=sweep inc/dec, 4-6=sweep length, 7=sweep on ** reg2: 8 bits of freq ** reg3: 0-2=high freq, 7-4=vbl length counter */ APU_VOLUME_DECAY(chan->output_vol); if (FALSE == chan->enabled || 0 == chan->vbl_length) return MMC5_RECTANGLE_OUTPUT; /* vbl length counter */ if (FALSE == chan->holdnote) chan->vbl_length--; /* envelope decay at a rate of (env_delay + 1) / 240 secs */ chan->env_phase -= 4; /* 240/60 */ while (chan->env_phase < 0) { chan->env_phase += chan->env_delay; if (chan->holdnote) chan->env_vol = (chan->env_vol + 1) & 0x0F; else if (chan->env_vol < 0x0F) chan->env_vol++; } if (chan->freq < APU_TO_FIXED(4)) return MMC5_RECTANGLE_OUTPUT; chan->phaseacc -= mmc5_incsize; /* # of cycles per sample */ if (chan->phaseacc >= 0) return MMC5_RECTANGLE_OUTPUT; #ifdef APU_OVERSAMPLE num_times = total = 0; if (chan->fixed_envelope) output = chan->volume << 8; /* fixed volume */ else output = (chan->env_vol ^ 0x0F) << 8; #endif while (chan->phaseacc < 0) { chan->phaseacc += chan->freq; chan->adder = (chan->adder + 1) & 0x0F; #ifdef APU_OVERSAMPLE if (chan->adder < chan->duty_flip) total += output; else total -= output; num_times++; #endif } #ifdef APU_OVERSAMPLE chan->output_vol = total / num_times; #else if (chan->fixed_envelope) output = chan->volume << 8; /* fixed volume */ else output = (chan->env_vol ^ 0x0F) << 8; if (0 == chan->adder) chan->output_vol = output; else if (chan->adder == chan->duty_flip) chan->output_vol = -output; #endif return MMC5_RECTANGLE_OUTPUT; } static uint8 mmc5_read(uint32 address) { uint32 retval; retval = (uint32) (mul[0] * mul[1]); switch (address) { case 0x5205: return (uint8) retval; case 0x5206: return (uint8) (retval >> 8); default: return 0xFF; } } /* mix vrcvi sound channels together */ static int32 mmc5_process(void) { int32 accum; accum = mmc5_rectangle(&mmc5rect[0]); accum += mmc5_rectangle(&mmc5rect[1]); if (mmc5dac.enabled) accum += mmc5dac.output; return accum; } /* write to registers */ static void mmc5_write(uint32 address, uint8 value) { int chan; switch (address) { /* rectangles */ case MMC5_WRA0: case MMC5_WRB0: chan = (address & 4) ? 1 : 0; mmc5rect[chan].regs[0] = value; mmc5rect[chan].volume = value & 0x0F; mmc5rect[chan].env_delay = decay_lut[value & 0x0F]; mmc5rect[chan].holdnote = (value & 0x20) ? TRUE : FALSE; mmc5rect[chan].fixed_envelope = (value & 0x10) ? TRUE : FALSE; mmc5rect[chan].duty_flip = duty_lut[value >> 6]; break; case MMC5_WRA1: case MMC5_WRB1: break; case MMC5_WRA2: case MMC5_WRB2: chan = (address & 4) ? 1 : 0; mmc5rect[chan].regs[2] = value; if (mmc5rect[chan].enabled) mmc5rect[chan].freq = APU_TO_FIXED((((mmc5rect[chan].regs[3] & 7) << 8) + value) + 1); break; case MMC5_WRA3: case MMC5_WRB3: chan = (address & 4) ? 1 : 0; mmc5rect[chan].regs[3] = value; if (mmc5rect[chan].enabled) { mmc5rect[chan].vbl_length = vbl_lut[value >> 3]; mmc5rect[chan].env_vol = 0; mmc5rect[chan].freq = APU_TO_FIXED((((value & 7) << 8) + mmc5rect[chan].regs[2]) + 1); mmc5rect[chan].adder = 0; } break; case MMC5_SMASK: if (value & 0x01) mmc5rect[0].enabled = TRUE; else { mmc5rect[0].enabled = FALSE; mmc5rect[0].vbl_length = 0; } if (value & 0x02) mmc5rect[1].enabled = TRUE; else { mmc5rect[1].enabled = FALSE; mmc5rect[1].vbl_length = 0; } break; case 0x5010: if (value & 0x01) mmc5dac.enabled = TRUE; else mmc5dac.enabled = FALSE; break; case 0x5011: mmc5dac.output = (value ^ 0x80) << 8; break; case 0x5205: mul[0] = value; break; case 0x5206: mul[1] = value; break; default: break; } } /* reset state of vrcvi sound channels */ static void mmc5_reset(void) { int i; /* get the phase period from the apu */ mmc5_incsize = apu_getcyclerate(); for (i = 0x5000; i < 0x5008; i++) mmc5_write(i, 0); mmc5_write(0x5010, 0); mmc5_write(0x5011, 0); } static void mmc5_init(void) { int i; int num_samples = apu_getcontext()->num_samples; /* lut used for enveloping and frequency sweeps */ for (i = 0; i < 16; i++) decay_lut[i] = num_samples * (i + 1); /* used for note length, based on vblanks and size of audio buffer */ for (i = 0; i < 32; i++) vbl_lut[i] = vbl_length[i] * num_samples; } /* TODO: bleh */ static void mmc5_shutdown(void) { } static apu_memread mmc5_memread[] = { { 0x5205, 0x5206, mmc5_read }, { -1, -1, NULL } }; static apu_memwrite mmc5_memwrite[] = { { 0x5000, 0x5015, mmc5_write }, { 0x5205, 0x5206, mmc5_write }, { -1, -1, NULL } }; apuext_t mmc5_ext = { mmc5_init, mmc5_shutdown, mmc5_reset, mmc5_process, mmc5_memread, mmc5_memwrite }; /* ** $Log: mmc5_snd.c,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.6 2000/07/04 04:51:41 matt ** cleanups ** ** Revision 1.5 2000/07/03 02:18:53 matt ** much better external module exporting ** ** Revision 1.4 2000/06/28 22:03:51 matt ** fixed stupid oversight ** ** Revision 1.3 2000/06/20 20:46:58 matt ** minor cleanups ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.1 2000/06/20 00:06:47 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/osd.h0000644000175000017500000000514114647725152015104 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** osd.h ** ** O/S dependent routine defintions (must be customized) ** $Id: osd.h,v 1.2 2003/07/12 12:31:14 mroi Exp $ */ #ifndef _OSD_H_ #define _OSD_H_ #if defined(__GNUC__) || defined(__ICC) #define PATH_SEP '/' #ifdef __DJGPP__ #include #include "dos_ints.h" #endif #elif defined(WIN32) #define PATH_SEP '\\' #else /* crapintosh? */ #define PATH_SEP ':' #endif extern void osd_loginit(void); extern void osd_logshutdown(void); extern void osd_logprint(const char *string); extern int osd_startsound(void (*playfunc)(void *buffer, int size)); extern int osd_getsoundbps(void); extern int osd_getsamplerate(void); #ifndef NSF_PLAYER #include "rgb.h" #include "bitmap.h" extern bitmap_t *osd_getvidbuf(void); typedef void (*blitproc_t)(bitmap_t *bmp, int x_pos, int y_pos, int width, int height); extern blitproc_t osd_blit; extern void osd_copytoscreen(void); extern void osd_showusage(char *filename); extern void osd_fullname(char *fullname, const char *shortname); extern char *osd_newextension(char *string, char *ext); extern void osd_setpalette(rgb_t *pal); extern void osd_restorepalette(void); extern void osd_getinput(void); extern int osd_gethostinput(void); extern void osd_getmouse(int *x, int *y, int *button); extern int osd_init(void); extern void osd_shutdown(void); #endif /* !NSF_PLAYER */ #endif /* _OSD_H_ */ /* ** $Log: osd.h,v $ ** Revision 1.2 2003/07/12 12:31:14 mroi ** - adding support for the Intel compiler icc ** - general multipass compilation make targets ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.7 2000/07/04 04:45:33 matt ** moved INLINE define into types.h ** ** Revision 1.6 2000/06/29 16:06:18 neil ** Wrapped DOS-specific headers in an ifdef ** ** Revision 1.5 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/Makefile.am0000644000175000017500000000122614647725152016202 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) if ENABLE_NOSEFART noinst_LTLIBRARIES = libnosefart.la endif libnosefart_la_SOURCES = \ dis6502.c \ dis6502.h \ fds_snd.c \ fds_snd.h \ fmopl.c \ fmopl.h \ log.c \ log.h \ memguard.c \ memguard.h \ mmc5_snd.c \ mmc5_snd.h \ nsf.c \ nsf.h \ nes_apu.c \ nes_apu.h \ nes6502.c \ nes6502.h \ osd.h \ types.h \ version.h \ vrc7_snd.c \ vrc7_snd.h \ vrcvisnd.c \ vrcvisnd.h libnosefart_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing libnosefart_la_CPPFLAGS = $(AM_CPPFLAGS) -DNSF_PLAYER libnosefart_la_LIBADD = -lm xine-lib-1.2/contrib/nosefart/nes_apu.c0000644000175000017500000007476014647725152015761 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** nes_apu.c ** ** NES APU emulation ** $Id: nes_apu.c,v 1.4 2005/05/07 09:11:39 valtri Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "types.h" #include "log.h" #include "nes_apu.h" #include "nes6502.h" #ifdef NSF_PLAYER #include "nsf.h" #else #include "nes.h" #include "nes_ppu.h" #include "nes_mmc.h" #include "nesinput.h" #endif /* !NSF_PLAYER */ #define APU_OVERSAMPLE #define APU_VOLUME_DECAY(x) ((x) -= ((x) >> 7)) /* pointer to active APU */ static apu_t *apu; /* look up table madness */ static int32 decay_lut[16]; static int vbl_lut[32]; static int trilength_lut[128]; /* noise lookups for both modes */ #ifndef REALTIME_NOISE static int8 noise_long_lut[APU_NOISE_32K]; static int8 noise_short_lut[APU_NOISE_93]; #endif /* !REALTIME_NOISE */ /* $$$ ben : last error */ #define SET_APU_ERROR(APU,X) \ do {if (APU) (APU)->errstr = "apu: " X;} while (0) #define APU_MIX_ENABLE(BIT) (apu->mix_enable&(1<<(BIT))) /* vblank length table used for rectangles, triangle, noise */ static const uint8 vbl_length[32] = { 5, 127, 10, 1, 19, 2, 40, 3, 80, 4, 30, 5, 7, 6, 13, 7, 6, 8, 12, 9, 24, 10, 48, 11, 96, 12, 36, 13, 8, 14, 16, 15 }; /* frequency limit of rectangle channels */ static const int freq_limit[8] = { 0x3FF, 0x555, 0x666, 0x71C, 0x787, 0x7C1, 0x7E0, 0x7F0 }; /* noise frequency lookup table */ static const int noise_freq[16] = { 4, 8, 16, 32, 64, 96, 128, 160, 202, 254, 380, 508, 762, 1016, 2034, 4068 }; /* DMC transfer freqs */ const int dmc_clocks[16] = { 428, 380, 340, 320, 286, 254, 226, 214, 190, 160, 142, 128, 106, 85, 72, 54 }; /* ratios of pos/neg pulse for rectangle waves */ static const int duty_lut[4] = { 2, 4, 8, 12 }; void apu_setcontext(apu_t *src_apu) { apu = src_apu; /* $$$ ben reset eoor string here. */ SET_APU_ERROR(apu,"no error"); } /* ** Simple queue routines */ #define APU_QEMPTY() (apu->q_head == apu->q_tail) static int apu_enqueue(apudata_t *d) { ASSERT(apu); apu->queue[apu->q_head] = *d; apu->q_head = (apu->q_head + 1) & APUQUEUE_MASK; if (APU_QEMPTY()) { log_printf("apu: queue overflow\n"); SET_APU_ERROR(apu,"queue overflow"); return -1; } return 0; } static apudata_t *apu_dequeue(void) { int loc; ASSERT(apu); if (APU_QEMPTY()) { log_printf("apu: queue empty\n"); SET_APU_ERROR(apu,"queue empty"); /* $$$ ben : should return 0 ??? */ } loc = apu->q_tail; apu->q_tail = (apu->q_tail + 1) & APUQUEUE_MASK; return &apu->queue[loc]; } int apu_setchan(int chan, boolean enabled) { const unsigned int max = 6; int old; ASSERT(apu); if ((unsigned int)chan >= max) { SET_APU_ERROR(apu,"channel out of range"); return -1; } old = (apu->mix_enable>>chan) & 1; if (enabled != (boolean)-1) { apu->mix_enable = (apu->mix_enable & ~(1<>= 1; sreg |= (bit14 << 14); return (bit0 ^ 1); } #else static void shift_register15(int8 *buf, int count) { static int sreg = 0x4000; int bit0, bit1, bit6, bit14; if (count == APU_NOISE_93) { while (count--) { bit0 = sreg & 1; bit6 = (sreg & 0x40) >> 6; bit14 = (bit0 ^ bit6); sreg >>= 1; sreg |= (bit14 << 14); *buf++ = bit0 ^ 1; } } else /* 32K noise */ { while (count--) { bit0 = sreg & 1; bit1 = (sreg & 2) >> 1; bit14 = (bit0 ^ bit1); sreg >>= 1; sreg |= (bit14 << 14); *buf++ = bit0 ^ 1; } } } #endif /* RECTANGLE WAVE ** ============== ** reg0: 0-3=volume, 4=envelope, 5=hold, 6-7=duty cycle ** reg1: 0-2=sweep shifts, 3=sweep inc/dec, 4-6=sweep length, 7=sweep on ** reg2: 8 bits of freq ** reg3: 0-2=high freq, 7-4=vbl length counter */ #define APU_RECTANGLE_OUTPUT chan->output_vol static int32 apu_rectangle(rectangle_t *chan) { int32 output; #ifdef APU_OVERSAMPLE int num_times; int32 total; #endif APU_VOLUME_DECAY(chan->output_vol); if (FALSE == chan->enabled || 0 == chan->vbl_length) return APU_RECTANGLE_OUTPUT; /* vbl length counter */ if (FALSE == chan->holdnote) chan->vbl_length--; /* envelope decay at a rate of (env_delay + 1) / 240 secs */ chan->env_phase -= 4; /* 240/60 */ while (chan->env_phase < 0) { chan->env_phase += chan->env_delay; if (chan->holdnote) chan->env_vol = (chan->env_vol + 1) & 0x0F; else if (chan->env_vol < 0x0F) chan->env_vol++; } if ((FALSE == chan->sweep_inc && chan->freq > chan->freq_limit) || chan->freq < APU_TO_FIXED(4)) return APU_RECTANGLE_OUTPUT; /* frequency sweeping at a rate of (sweep_delay + 1) / 120 secs */ if (chan->sweep_on && chan->sweep_shifts) { chan->sweep_phase -= 2; /* 120/60 */ while (chan->sweep_phase < 0) { chan->sweep_phase += chan->sweep_delay; if (chan->sweep_inc) /* ramp up */ chan->freq -= chan->freq >> (chan->sweep_shifts); else /* ramp down */ chan->freq += chan->freq >> (chan->sweep_shifts); } } chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ if (chan->phaseacc >= 0) return APU_RECTANGLE_OUTPUT; #ifdef APU_OVERSAMPLE num_times = total = 0; if (chan->fixed_envelope) output = chan->volume << 8; /* fixed volume */ else output = (chan->env_vol ^ 0x0F) << 8; #endif while (chan->phaseacc < 0) { chan->phaseacc += chan->freq; chan->adder = (chan->adder + 1) & 0x0F; #ifdef APU_OVERSAMPLE if (chan->adder < chan->duty_flip) total += output; else total -= output; num_times++; #endif } #ifdef APU_OVERSAMPLE chan->output_vol = total / num_times; #else if (chan->fixed_envelope) output = chan->volume << 8; /* fixed volume */ else output = (chan->env_vol ^ 0x0F) << 8; if (0 == chan->adder) chan->output_vol = output; else if (chan->adder == chan->duty_flip) chan->output_vol = -output; #endif return APU_RECTANGLE_OUTPUT; } /* TRIANGLE WAVE ** ============= ** reg0: 7=holdnote, 6-0=linear length counter ** reg2: low 8 bits of frequency ** reg3: 7-3=length counter, 2-0=high 3 bits of frequency */ #define APU_TRIANGLE_OUTPUT (chan->output_vol + (chan->output_vol >> 2)) static int32 apu_triangle(triangle_t *chan) { APU_VOLUME_DECAY(chan->output_vol); if (FALSE == chan->enabled || 0 == chan->vbl_length) return APU_TRIANGLE_OUTPUT; if (chan->counter_started) { if (chan->linear_length > 0) chan->linear_length--; if (chan->vbl_length && FALSE == chan->holdnote) chan->vbl_length--; } else if (FALSE == chan->holdnote && chan->write_latency) { if (--chan->write_latency == 0) chan->counter_started = TRUE; } /* if (chan->countmode == COUNTMODE_COUNT) { if (chan->linear_length > 0) chan->linear_length--; if (chan->vbl_length) chan->vbl_length--; } */ if (0 == chan->linear_length || chan->freq < APU_TO_FIXED(4)) /* inaudible */ return APU_TRIANGLE_OUTPUT; chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ while (chan->phaseacc < 0) { chan->phaseacc += chan->freq; chan->adder = (chan->adder + 1) & 0x1F; if (chan->adder & 0x10) chan->output_vol -= (2 << 8); else chan->output_vol += (2 << 8); } return APU_TRIANGLE_OUTPUT; } /* WHITE NOISE CHANNEL ** =================== ** reg0: 0-3=volume, 4=envelope, 5=hold ** reg2: 7=small(93 byte) sample,3-0=freq lookup ** reg3: 7-4=vbl length counter */ #define APU_NOISE_OUTPUT ((chan->output_vol + chan->output_vol + chan->output_vol) >> 2) static int32 apu_noise(noise_t *chan) { int32 outvol; #if defined(APU_OVERSAMPLE) && defined(REALTIME_NOISE) #else int32 noise_bit; #endif #ifdef APU_OVERSAMPLE int num_times; int32 total; #endif APU_VOLUME_DECAY(chan->output_vol); if (FALSE == chan->enabled || 0 == chan->vbl_length) return APU_NOISE_OUTPUT; /* vbl length counter */ if (FALSE == chan->holdnote) chan->vbl_length--; /* envelope decay at a rate of (env_delay + 1) / 240 secs */ chan->env_phase -= 4; /* 240/60 */ while (chan->env_phase < 0) { chan->env_phase += chan->env_delay; if (chan->holdnote) chan->env_vol = (chan->env_vol + 1) & 0x0F; else if (chan->env_vol < 0x0F) chan->env_vol++; } chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ if (chan->phaseacc >= 0) return APU_NOISE_OUTPUT; #ifdef APU_OVERSAMPLE num_times = total = 0; if (chan->fixed_envelope) outvol = chan->volume << 8; /* fixed volume */ else outvol = (chan->env_vol ^ 0x0F) << 8; #endif while (chan->phaseacc < 0) { chan->phaseacc += chan->freq; #ifdef REALTIME_NOISE #ifdef APU_OVERSAMPLE if (shift_register15(chan->xor_tap)) total += outvol; else total -= outvol; num_times++; #else noise_bit = shift_register15(chan->xor_tap); #endif #else chan->cur_pos++; if (chan->short_sample) { if (APU_NOISE_93 == chan->cur_pos) chan->cur_pos = 0; } else { if (APU_NOISE_32K == chan->cur_pos) chan->cur_pos = 0; } #ifdef APU_OVERSAMPLE if (chan->short_sample) noise_bit = noise_short_lut[chan->cur_pos]; else noise_bit = noise_long_lut[chan->cur_pos]; if (noise_bit) total += outvol; else total -= outvol; num_times++; #endif #endif /* REALTIME_NOISE */ } #ifdef APU_OVERSAMPLE chan->output_vol = total / num_times; #else if (chan->fixed_envelope) outvol = chan->volume << 8; /* fixed volume */ else outvol = (chan->env_vol ^ 0x0F) << 8; #ifndef REALTIME_NOISE if (chan->short_sample) noise_bit = noise_short_lut[chan->cur_pos]; else noise_bit = noise_long_lut[chan->cur_pos]; #endif /* !REALTIME_NOISE */ if (noise_bit) chan->output_vol = outvol; else chan->output_vol = -outvol; #endif return APU_NOISE_OUTPUT; } INLINE void apu_dmcreload(dmc_t *chan) { chan->address = chan->cached_addr; chan->dma_length = chan->cached_dmalength; chan->irq_occurred = FALSE; } /* DELTA MODULATION CHANNEL ** ========================= ** reg0: 7=irq gen, 6=looping, 3-0=pointer to clock table ** reg1: output dc level, 6 bits unsigned ** reg2: 8 bits of 64-byte aligned address offset : $C000 + (value * 64) ** reg3: length, (value * 16) + 1 */ #define APU_DMC_OUTPUT ((chan->output_vol + chan->output_vol + chan->output_vol) >> 2) static int32 apu_dmc(dmc_t *chan) { int delta_bit; APU_VOLUME_DECAY(chan->output_vol); /* only process when channel is alive */ if (chan->dma_length) { chan->phaseacc -= apu->cycle_rate; /* # of cycles per sample */ while (chan->phaseacc < 0) { chan->phaseacc += chan->freq; delta_bit = (chan->dma_length & 7) ^ 7; if (7 == delta_bit) { chan->cur_byte = nes6502_getbyte(chan->address); /* steal a cycle from CPU*/ nes6502_setdma(1); if (0xFFFF == chan->address) chan->address = 0x8000; else chan->address++; } if (--chan->dma_length == 0) { /* if loop bit set, we're cool to retrigger sample */ if (chan->looping) apu_dmcreload(chan); else { /* check to see if we should generate an irq */ if (chan->irq_gen) { chan->irq_occurred = TRUE; nes6502_irq(); } /* bodge for timestamp queue */ chan->enabled = FALSE; break; } } /* positive delta */ if (chan->cur_byte & (1 << delta_bit)) { if (chan->regs[1] < 0x7D) { chan->regs[1] += 2; chan->output_vol += (2 << 8); } /* if (chan->regs[1] < 0x3F) chan->regs[1]++; chan->output_vol &= ~(0x7E << 8); chan->output_vol |= ((chan->regs[1] << 1) << 8); */ } /* negative delta */ else { if (chan->regs[1] > 1) { chan->regs[1] -= 2; chan->output_vol -= (2 << 8); } /* if (chan->regs[1] > 0) chan->regs[1]--; chan->output_vol &= ~(0x7E << 8); chan->output_vol |= ((chan->regs[1] << 1) << 8); */ } } } return APU_DMC_OUTPUT; } static void apu_regwrite(uint32 address, uint8 value) { int chan; ASSERT(apu); switch (address) { /* rectangles */ case APU_WRA0: case APU_WRB0: chan = (address & 4) ? 1 : 0; apu->rectangle[chan].regs[0] = value; apu->rectangle[chan].volume = value & 0x0F; apu->rectangle[chan].env_delay = decay_lut[value & 0x0F]; apu->rectangle[chan].holdnote = (value & 0x20) ? TRUE : FALSE; apu->rectangle[chan].fixed_envelope = (value & 0x10) ? TRUE : FALSE; apu->rectangle[chan].duty_flip = duty_lut[value >> 6]; break; case APU_WRA1: case APU_WRB1: chan = (address & 4) ? 1 : 0; apu->rectangle[chan].regs[1] = value; apu->rectangle[chan].sweep_on = (value & 0x80) ? TRUE : FALSE; apu->rectangle[chan].sweep_shifts = value & 7; apu->rectangle[chan].sweep_delay = decay_lut[(value >> 4) & 7]; apu->rectangle[chan].sweep_inc = (value & 0x08) ? TRUE : FALSE; apu->rectangle[chan].freq_limit = APU_TO_FIXED(freq_limit[value & 7]); break; case APU_WRA2: case APU_WRB2: chan = (address & 4) ? 1 : 0; apu->rectangle[chan].regs[2] = value; // if (apu->rectangle[chan].enabled) apu->rectangle[chan].freq = APU_TO_FIXED((((apu->rectangle[chan].regs[3] & 7) << 8) + value) + 1); break; case APU_WRA3: case APU_WRB3: chan = (address & 4) ? 1 : 0; apu->rectangle[chan].regs[3] = value; // if (apu->rectangle[chan].enabled) { apu->rectangle[chan].vbl_length = vbl_lut[value >> 3]; apu->rectangle[chan].env_vol = 0; apu->rectangle[chan].freq = APU_TO_FIXED((((value & 7) << 8) + apu->rectangle[chan].regs[2]) + 1); apu->rectangle[chan].adder = 0; } break; /* triangle */ case APU_WRC0: /* if (0 == (apu->triangle.regs[0] & 0x80)) apu->triangle.countmode = COUNTMODE_COUNT; else { if (apu->triangle.countmode == COUNTMODE_LOAD && apu->triangle.vbl_length) apu->triangle.linear_length = trilength_lut[value & 0x7F]; if (0 == (value & 0x80)) apu->triangle.countmode = COUNTMODE_COUNT; } */ apu->triangle.regs[0] = value; apu->triangle.holdnote = (value & 0x80) ? TRUE : FALSE; // if (apu->triangle.enabled) { if (FALSE == apu->triangle.counter_started && apu->triangle.vbl_length) apu->triangle.linear_length = trilength_lut[value & 0x7F]; } break; case APU_WRC2: apu->triangle.regs[1] = value; // if (apu->triangle.enabled) apu->triangle.freq = APU_TO_FIXED((((apu->triangle.regs[2] & 7) << 8) + value) + 1); break; case APU_WRC3: apu->triangle.regs[2] = value; /* this is somewhat of a hack. there appears to be some latency on ** the Real Thing between when trireg0 is written to and when the ** linear length counter actually begins its countdown. we want to ** prevent the case where the program writes to the freq regs first, ** then to reg 0, and the counter accidentally starts running because ** of the sound queue's timestamp processing. ** ** set latency to a couple scanlines -- should be plenty of time for ** the 6502 code to do a couple of table dereferences and load up the ** other triregs */ /* 06/13/00 MPC -- seems to work OK */ apu->triangle.write_latency = (int) (2 * NES_SCANLINE_CYCLES / APU_FROM_FIXED(apu->cycle_rate)); /* apu->triangle.linear_length = trilength_lut[apu->triangle.regs[0] & 0x7F]; if (0 == (apu->triangle.regs[0] & 0x80)) apu->triangle.countmode = COUNTMODE_COUNT; else apu->triangle.countmode = COUNTMODE_LOAD; */ // if (apu->triangle.enabled) { apu->triangle.freq = APU_TO_FIXED((((value & 7) << 8) + apu->triangle.regs[1]) + 1); apu->triangle.vbl_length = vbl_lut[value >> 3]; apu->triangle.counter_started = FALSE; apu->triangle.linear_length = trilength_lut[apu->triangle.regs[0] & 0x7F]; } break; /* noise */ case APU_WRD0: apu->noise.regs[0] = value; apu->noise.env_delay = decay_lut[value & 0x0F]; apu->noise.holdnote = (value & 0x20) ? TRUE : FALSE; apu->noise.fixed_envelope = (value & 0x10) ? TRUE : FALSE; apu->noise.volume = value & 0x0F; break; case APU_WRD2: apu->noise.regs[1] = value; apu->noise.freq = APU_TO_FIXED(noise_freq[value & 0x0F]); #ifdef REALTIME_NOISE apu->noise.xor_tap = (value & 0x80) ? 0x40: 0x02; #else /* detect transition from long->short sample */ if ((value & 0x80) && FALSE == apu->noise.short_sample) { /* recalculate short noise buffer */ shift_register15(noise_short_lut, APU_NOISE_93); apu->noise.cur_pos = 0; } apu->noise.short_sample = (value & 0x80) ? TRUE : FALSE; #endif break; case APU_WRD3: apu->noise.regs[2] = value; // if (apu->noise.enabled) { apu->noise.vbl_length = vbl_lut[value >> 3]; apu->noise.env_vol = 0; /* reset envelope */ } break; /* DMC */ case APU_WRE0: apu->dmc.regs[0] = value; apu->dmc.freq = APU_TO_FIXED(dmc_clocks[value & 0x0F]); apu->dmc.looping = (value & 0x40) ? TRUE : FALSE; if (value & 0x80) apu->dmc.irq_gen = TRUE; else { apu->dmc.irq_gen = FALSE; apu->dmc.irq_occurred = FALSE; } break; case APU_WRE1: /* 7-bit DAC */ /* add the _delta_ between written value and ** current output level of the volume reg */ value &= 0x7F; /* bit 7 ignored */ apu->dmc.output_vol += ((value - apu->dmc.regs[1]) << 8); apu->dmc.regs[1] = value; /* apu->dmc.output_vol = (value & 0x7F) << 8; apu->dmc.regs[1] = (value & 0x7E) >> 1; */ break; case APU_WRE2: apu->dmc.regs[2] = value; apu->dmc.cached_addr = 0xC000 + (uint16) (value << 6); break; case APU_WRE3: apu->dmc.regs[3] = value; apu->dmc.cached_dmalength = ((value << 4) + 1) << 3; break; case APU_SMASK: /* bodge for timestamp queue */ apu->dmc.enabled = (value & 0x10) ? TRUE : FALSE; apu->enable_reg = value; for (chan = 0; chan < 2; chan++) { if (value & (1 << chan)) apu->rectangle[chan].enabled = TRUE; else { apu->rectangle[chan].enabled = FALSE; apu->rectangle[chan].vbl_length = 0; } } if (value & 0x04) apu->triangle.enabled = TRUE; else { apu->triangle.enabled = FALSE; apu->triangle.vbl_length = 0; apu->triangle.linear_length = 0; apu->triangle.counter_started = FALSE; apu->triangle.write_latency = 0; } if (value & 0x08) apu->noise.enabled = TRUE; else { apu->noise.enabled = FALSE; apu->noise.vbl_length = 0; } if (value & 0x10) { if (0 == apu->dmc.dma_length) apu_dmcreload(&apu->dmc); } else apu->dmc.dma_length = 0; apu->dmc.irq_occurred = FALSE; break; /* unused, but they get hit in some mem-clear loops */ case 0x4009: case 0x400D: break; default: break; } } /* Read from $4000-$4017 */ uint8 apu_read(uint32 address) { uint8 value; ASSERT(apu); switch (address) { case APU_SMASK: /* seems that bit 6 denotes vblank -- return 1 for now */ value = 0x40; /* Return 1 in 0-5 bit pos if a channel is playing */ if (apu->rectangle[0].enabled && apu->rectangle[0].vbl_length) value |= 0x01; if (apu->rectangle[1].enabled && apu->rectangle[1].vbl_length) value |= 0x02; if (apu->triangle.enabled && apu->triangle.vbl_length) value |= 0x04; if (apu->noise.enabled && apu->noise.vbl_length) value |= 0x08; //if (apu->dmc.dma_length) /* bodge for timestamp queue */ if (apu->dmc.enabled) value |= 0x10; if (apu->dmc.irq_occurred) value |= 0x80; break; #ifndef NSF_PLAYER case APU_JOY0: value = input_get(INP_JOYPAD0); break; case APU_JOY1: value = input_get(INP_ZAPPER | INP_JOYPAD1 /*| INP_ARKANOID*/ /*| INP_POWERPAD*/); break; #endif /* !NSF_PLAYER */ default: value = (address >> 8); /* heavy capacitance on data bus */ break; } return value; } void apu_write(uint32 address, uint8 value) { #ifndef NSF_PLAYER static uint8 last_write; #endif /* !NSF_PLAYER */ apudata_t d; switch (address) { case 0x4015: /* bodge for timestamp queue */ apu->dmc.enabled = (value & 0x10) ? TRUE : FALSE; /* fall through */ case 0x4000: case 0x4001: case 0x4002: case 0x4003: case 0x4004: case 0x4005: case 0x4006: case 0x4007: case 0x4008: case 0x4009: case 0x400A: case 0x400B: case 0x400C: case 0x400D: case 0x400E: case 0x400F: case 0x4010: case 0x4011: case 0x4012: case 0x4013: d.timestamp = nes6502_getcycles(FALSE); d.address = address; d.value = value; apu_enqueue(&d); break; #ifndef NSF_PLAYER case APU_OAMDMA: ppu_oamdma(address, value); break; case APU_JOY0: /* VS system VROM switching */ mmc_vsvrom(value & 4); /* see if we need to strobe them joypads */ value &= 1; if ((0 == value) && last_write) input_strobe(); last_write = value; break; case APU_JOY1: /* Some kind of IRQ control business */ break; #endif /* !NSF_PLAYER */ default: break; } } void apu_getpcmdata(void **data, int *num_samples, int *sample_bits) { ASSERT(apu); *data = apu->buffer; *num_samples = apu->num_samples; *sample_bits = apu->sample_bits; } void apu_process(void *buffer, int num_samples) { apudata_t *d; uint32 elapsed_cycles; static int32 prev_sample = 0; int32 next_sample, accum; ASSERT(apu); /* grab it, keep it local for speed */ elapsed_cycles = (uint32) apu->elapsed_cycles; /* BLEH */ apu->buffer = buffer; while (num_samples--) { while ((FALSE == APU_QEMPTY()) && (apu->queue[apu->q_tail].timestamp <= elapsed_cycles)) { d = apu_dequeue(); apu_regwrite(d->address, d->value); } elapsed_cycles += APU_FROM_FIXED(apu->cycle_rate); accum = 0; if (APU_MIX_ENABLE(0)) accum += apu_rectangle(&apu->rectangle[0]); if (APU_MIX_ENABLE(1)) accum += apu_rectangle(&apu->rectangle[1]); if (APU_MIX_ENABLE(2)) accum += apu_triangle(&apu->triangle); if (APU_MIX_ENABLE(3)) accum += apu_noise(&apu->noise); if (APU_MIX_ENABLE(4)) accum += apu_dmc(&apu->dmc); if (apu->ext && APU_MIX_ENABLE(5)) accum += apu->ext->process(); /* do any filtering */ if (APU_FILTER_NONE != apu->filter_type) { next_sample = accum; if (APU_FILTER_LOWPASS == apu->filter_type) { accum += prev_sample; accum >>= 1; } else accum = (accum + accum + accum + prev_sample) >> 2; prev_sample = next_sample; } /* little extra kick for the kids */ accum <<= 1; /* prevent clipping */ if (accum > 0x7FFF) accum = 0x7FFF; else if (accum < -0x8000) accum = -0x8000; /* signed 16-bit output, unsigned 8-bit */ if (16 == apu->sample_bits) { int16 *q = buffer; *q++ = accum; buffer = q; } else { uint8 *q = buffer; *q++ = (accum >> 8) ^ 0x80; buffer = q; } } /* resync cycle counter */ apu->elapsed_cycles = nes6502_getcycles(FALSE); } /* set the filter type */ /* $$$ ben : * Add a get feature (filter_type == -1) and returns old filter type */ int apu_setfilter(int filter_type) { int old; ASSERT(apu); old = apu->filter_type; if (filter_type != -1) { apu->filter_type = filter_type; } return old; } void apu_reset(void) { uint32 address; ASSERT(apu); apu->elapsed_cycles = 0; memset(&apu->queue, 0, APUQUEUE_SIZE * sizeof(apudata_t)); apu->q_head = 0; apu->q_tail = 0; /* use to avoid bugs =) */ for (address = 0x4000; address <= 0x4013; address++) apu_regwrite(address, 0); #ifdef NSF_PLAYER apu_regwrite(0x400C, 0x10); /* silence noise channel on NSF start */ apu_regwrite(0x4015, 0x0F); #else apu_regwrite(0x4015, 0); #endif /* NSF_PLAYER */ if (apu->ext) apu->ext->reset(); } void apu_build_luts(int num_samples); void apu_build_luts(int num_samples) { int i; /* lut used for enveloping and frequency sweeps */ for (i = 0; i < 16; i++) decay_lut[i] = num_samples * (i + 1); /* used for note length, based on vblanks and size of audio buffer */ for (i = 0; i < 32; i++) vbl_lut[i] = vbl_length[i] * num_samples; /* triangle wave channel's linear length table */ for (i = 0; i < 128; i++) trilength_lut[i] = (i * num_samples) / 4; #ifndef REALTIME_NOISE /* generate noise samples */ shift_register15(noise_long_lut, APU_NOISE_32K); shift_register15(noise_short_lut, APU_NOISE_93); #endif /* !REALTIME_NOISE */ } static void apu_setactive(apu_t *active) { ASSERT(active); apu = active; } /* Initializes emulated sound hardware, creates waveforms/voices */ apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo) { apu_t *temp_apu; /* int channel; */ (void)stereo; temp_apu = malloc(sizeof(apu_t)); if (NULL == temp_apu) return NULL; /* $$$ ben : safety net, in case we forgot to init something */ memset(temp_apu,0,sizeof(apu_t)); SET_APU_ERROR(temp_apu,"no error"); temp_apu->sample_rate = sample_rate; temp_apu->refresh_rate = refresh_rate; temp_apu->sample_bits = sample_bits; temp_apu->num_samples = sample_rate / refresh_rate; /* turn into fixed point! */ temp_apu->cycle_rate = (int32) (APU_BASEFREQ * 65536.0 / (float) sample_rate); /* build various lookup tables for apu */ apu_build_luts(temp_apu->num_samples); /* set the update routine */ temp_apu->process = apu_process; temp_apu->ext = NULL; apu_setactive(temp_apu); apu_reset(); temp_apu->mix_enable = 0x3F; /* for (channel = 0; channel < 6; channel++) */ /* apu_setchan(channel, TRUE); */ apu_setfilter(APU_FILTER_LOWPASS); return temp_apu; } apu_t *apu_getcontext(void) { return apu; } void apu_destroy(apu_t *src_apu) { if (src_apu) { if (src_apu->ext) src_apu->ext->shutdown(); free(src_apu); } } int apu_setext(apu_t *src_apu, apuext_t *ext) { ASSERT(src_apu); /* $$$ ben : seem cleaner like this */ if (src_apu->ext) { src_apu->ext->shutdown(); } src_apu->ext = ext; /* initialize it */ if (src_apu->ext) src_apu->ext->init(); /* $$$ ben : May be one day extension int () will return error code */ return 0; } /* this exists for external mixing routines */ int32 apu_getcyclerate(void) { ASSERT(apu); return apu->cycle_rate; } /* ** $Log: nes_apu.c,v $ ** Revision 1.4 2005/05/07 09:11:39 valtri ** *BUGFIX* ** gcc4 patches from Dams Nadé (livna.org) and Keenan Pepper. ** ** Revision 1.3 2004/12/12 06:55:59 athp ** Code cleanups and elimination of some compiler warnings; patch courtesy of AL13N ** ** Revision 1.2 2003/08/25 21:51:43 f1rmb ** Reduce GCC verbosity (various prototype declaration fixes). ffmpeg, wine and fft*post are untouched (fft: for now). ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.19 2000/07/04 04:53:26 matt ** minor changes, sound amplification ** ** Revision 1.18 2000/07/03 02:18:53 matt ** much better external module exporting ** ** Revision 1.17 2000/06/26 11:01:55 matt ** made triangle a tad quieter ** ** Revision 1.16 2000/06/26 05:10:33 matt ** fixed cycle rate generation accuracy ** ** Revision 1.15 2000/06/26 05:00:37 matt ** cleanups ** ** Revision 1.14 2000/06/23 11:06:24 matt ** more faithful mixing of channels ** ** Revision 1.13 2000/06/23 03:29:27 matt ** cleaned up external sound inteface ** ** Revision 1.12 2000/06/20 00:08:39 matt ** bugfix to rectangle wave ** ** Revision 1.11 2000/06/13 13:48:58 matt ** fixed triangle write latency for fixed point apu cycle rate ** ** Revision 1.10 2000/06/12 01:14:36 matt ** minor change to clipping extents ** ** Revision 1.9 2000/06/09 20:00:56 matt ** fixed noise hiccup in NSF player mode ** ** Revision 1.8 2000/06/09 16:49:02 matt ** removed all floating point from sound generation ** ** Revision 1.7 2000/06/09 15:12:28 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/fds_snd.c0000644000175000017500000000473114647725152015736 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** fds_snd.c ** ** Famicom Disk System sound emulation ** $Id: fds_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "types.h" #include "nes_apu.h" #include "fds_snd.h" static int32 fds_incsize = 0; /* mix sound channels together */ static int32 fds_process(void) { int32 output; output = 0; return output; } /* write to registers */ static void fds_write(uint32 address, uint8 value) { /* ?? - */ (void)address; (void)value; } /* reset state of vrcvi sound channels */ static void fds_reset(void) { fds_incsize = apu_getcyclerate(); } static void fds_init(void) { } /* TODO: bleh */ static void fds_shutdown(void) { } static apu_memwrite fds_memwrite[] = { { 0x4040, 0x4092, fds_write }, { -1, -1, NULL } }; apuext_t fds_ext = { fds_init, fds_shutdown, fds_reset, fds_process, NULL, /* no reads */ fds_memwrite }; /* ** $Log: fds_snd.c,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.3 2000/07/03 02:18:53 matt ** much better external module exporting ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.1 2000/06/20 00:06:47 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/dis6502.c0000644000175000017500000004214014647725152015406 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** dis6502.c ** ** 6502 disassembler based on code from John Saeger ** $Id: dis6502.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "types.h" #include "log.h" #include "nes6502.h" #include "dis6502.h" #ifdef NES6502_DEBUG /* addressing modes */ enum { _imp, _acc, _rel, _imm, _abs, _abs_x, _abs_y, _zero, _zero_x, _zero_y, _ind, _ind_x, _ind_y }; /* keep a filthy local copy of PC to ** reduce the amount of parameter passing */ static uint32 pc_reg; static uint8 dis_op8(void) { return (nes6502_getbyte(pc_reg + 1)); } static uint16 dis_op16(void) { return (nes6502_getbyte(pc_reg + 1) + (nes6502_getbyte(pc_reg + 2) << 8)); } static void dis_show_ind(void) { log_printf("(%04X) ", dis_op16()); } static void dis_show_ind_x(void) { log_printf("(%02X,x) ", dis_op8()); } static void dis_show_ind_y(void) { log_printf("(%02X),y ", dis_op8()); } static void dis_show_zero_x(void) { log_printf(" %02X,x ", dis_op8()); } static void dis_show_zero_y(void) { log_printf(" %02X,y ", dis_op8()); } static void dis_show_abs_y(void) { log_printf(" %04X,y ", dis_op16()); } static void dis_show_abs_x(void) { log_printf(" %04X,x ", dis_op16()); } static void dis_show_zero(void) { log_printf(" %02X ", dis_op8()); } static void dis_show_abs(void) { log_printf(" %04X ", dis_op16()); } static void dis_show_immediate(void) { log_printf("#%02X ", dis_op8()); } static void dis_show_acc(void) { log_printf(" a "); } static void dis_show_relative(void) { int target; target = (int8) dis_op8(); target += (pc_reg + 2); log_printf(" %04X ", target); } static void dis_show_code(int optype) { log_printf("%02X ", nes6502_getbyte(pc_reg)); switch (optype) { case _imp: case _acc: log_printf(" "); break; case _rel: case _imm: case _zero: case _zero_x: log_printf("%02X ", nes6502_getbyte(pc_reg + 1)); break; case _abs: case _abs_x: case _abs_y: case _ind: case _ind_x: case _ind_y: log_printf("%02X %02X ", nes6502_getbyte(pc_reg + 1), nes6502_getbyte(pc_reg + 2)); break; } } static void dis_show_op(char *opstr, int optype) { dis_show_code(optype); log_printf("%s ", opstr); switch(optype) { case _imp: log_printf(" "); break; case _acc: dis_show_acc(); break; case _rel: dis_show_relative(); break; case _imm: dis_show_immediate(); break; case _abs: dis_show_abs(); break; case _abs_x: dis_show_abs_x(); break; case _abs_y: dis_show_abs_y(); break; case _zero: dis_show_zero(); break; case _zero_x: dis_show_zero_x(); break; case _ind: dis_show_ind(); break; case _ind_x: dis_show_ind_x(); break; case _ind_y: dis_show_ind_y(); break; } } void nes6502_disasm(uint32 PC, uint8 P, uint8 A, uint8 X, uint8 Y, uint8 S) { pc_reg = PC; log_printf("%04X: ", pc_reg); switch(nes6502_getbyte(pc_reg)) { case 0x00: dis_show_op("brk",_imp); break; case 0x01: dis_show_op("ora",_ind_x); break; case 0x02: dis_show_op("jam",_imp); break; case 0x03: dis_show_op("slo",_ind_x); break; case 0x04: dis_show_op("nop",_zero); break; case 0x05: dis_show_op("ora",_zero); break; case 0x06: dis_show_op("asl",_zero); break; case 0x07: dis_show_op("slo",_zero); break; case 0x08: dis_show_op("php",_imp); break; case 0x09: dis_show_op("ora",_imm); break; case 0x0a: dis_show_op("asl",_acc); break; case 0x0b: dis_show_op("anc",_imm); break; case 0x0c: dis_show_op("nop",_abs); break; case 0x0d: dis_show_op("ora",_abs); break; case 0x0e: dis_show_op("asl",_abs); break; case 0x0f: dis_show_op("slo",_abs); break; case 0x10: dis_show_op("bpl",_rel); break; case 0x11: dis_show_op("ora",_ind_y); break; case 0x12: dis_show_op("jam",_imp); break; case 0x13: dis_show_op("slo",_ind_y); break; case 0x14: dis_show_op("nop",_zero_x); break; case 0x15: dis_show_op("ora",_zero_x); break; case 0x16: dis_show_op("asl",_zero_x); break; case 0x17: dis_show_op("slo",_zero_x); break; case 0x18: dis_show_op("clc",_imp); break; case 0x19: dis_show_op("ora",_abs_y); break; case 0x1a: dis_show_op("nop",_imp); break; case 0x1b: dis_show_op("slo",_abs_y); break; case 0x1c: dis_show_op("nop",_abs_x); break; case 0x1d: dis_show_op("ora",_abs_x); break; case 0x1e: dis_show_op("asl",_abs_x); break; case 0x1f: dis_show_op("slo",_abs_x); break; case 0x20: dis_show_op("jsr",_abs); break; case 0x21: dis_show_op("and",_ind_x); break; case 0x22: dis_show_op("jam",_imp); break; case 0x23: dis_show_op("rla",_ind_x); break; case 0x24: dis_show_op("bit",_zero); break; case 0x25: dis_show_op("and",_zero); break; case 0x26: dis_show_op("rol",_zero); break; case 0x27: dis_show_op("rla",_zero); break; case 0x28: dis_show_op("plp",_imp); break; case 0x29: dis_show_op("and",_imm); break; case 0x2a: dis_show_op("rol",_acc); break; case 0x2b: dis_show_op("anc",_imm); break; case 0x2c: dis_show_op("bit",_abs); break; case 0x2d: dis_show_op("and",_abs); break; case 0x2e: dis_show_op("rol",_abs); break; case 0x2f: dis_show_op("rla",_abs); break; case 0x30: dis_show_op("bmi",_rel); break; case 0x31: dis_show_op("and",_ind_y); break; case 0x32: dis_show_op("jam",_imp); break; case 0x33: dis_show_op("rla",_ind_y); break; /* case 0x34: dis_show_op("nop",_zero); break;*/ case 0x34: dis_show_op("nop",_imp); break; case 0x35: dis_show_op("and",_zero_x); break; case 0x36: dis_show_op("rol",_zero_x); break; case 0x37: dis_show_op("rla",_zero_x); break; case 0x38: dis_show_op("sec",_imp); break; case 0x39: dis_show_op("and",_abs_y); break; case 0x3a: dis_show_op("nop",_imp); break; case 0x3b: dis_show_op("rla",_abs_y); break; /* case 0x3c: dis_show_op("nop",_imp); break;*/ case 0x3c: dis_show_op("nop",_abs_x); break; case 0x3d: dis_show_op("and",_abs_x); break; case 0x3e: dis_show_op("rol",_abs_x); break; case 0x3f: dis_show_op("rla",_abs_x); break; case 0x40: dis_show_op("rti",_imp); break; case 0x41: dis_show_op("eor",_ind_x); break; case 0x42: dis_show_op("jam",_imp); break; case 0x43: dis_show_op("sre",_ind_x); break; case 0x44: dis_show_op("nop",_zero); break; case 0x45: dis_show_op("eor",_zero); break; case 0x46: dis_show_op("lsr",_zero); break; case 0x47: dis_show_op("sre",_zero); break; case 0x48: dis_show_op("pha",_imp); break; case 0x49: dis_show_op("eor",_imm); break; case 0x4a: dis_show_op("lsr",_acc); break; case 0x4b: dis_show_op("asr",_imm); break; case 0x4c: dis_show_op("jmp",_abs); break; case 0x4d: dis_show_op("eor",_abs); break; case 0x4e: dis_show_op("lsr",_abs); break; case 0x4f: dis_show_op("sre",_abs); break; case 0x50: dis_show_op("bvc",_rel); break; case 0x51: dis_show_op("eor",_ind_y); break; case 0x52: dis_show_op("jam",_imp); break; case 0x53: dis_show_op("sre",_ind_y); break; case 0x54: dis_show_op("nop",_zero_x); break; case 0x55: dis_show_op("eor",_zero_x); break; case 0x56: dis_show_op("lsr",_zero_x); break; case 0x57: dis_show_op("sre",_zero_x); break; case 0x58: dis_show_op("cli",_imp); break; case 0x59: dis_show_op("eor",_abs_y); break; case 0x5a: dis_show_op("nop",_imp); break; case 0x5b: dis_show_op("sre",_abs_y); break; case 0x5c: dis_show_op("nop",_abs_x); break; case 0x5d: dis_show_op("eor",_abs_x); break; case 0x5e: dis_show_op("lsr",_abs_x); break; case 0x5f: dis_show_op("sre",_abs_x); break; case 0x60: dis_show_op("rts",_imp); break; case 0x61: dis_show_op("adc",_ind_x); break; case 0x62: dis_show_op("jam",_imp); break; case 0x63: dis_show_op("rra",_ind_x); break; case 0x64: dis_show_op("nop",_zero); break; case 0x65: dis_show_op("adc",_zero); break; case 0x66: dis_show_op("ror",_zero); break; case 0x67: dis_show_op("rra",_zero); break; case 0x68: dis_show_op("pla",_imp); break; case 0x69: dis_show_op("adc",_imm); break; case 0x6a: dis_show_op("ror",_acc); break; case 0x6b: dis_show_op("arr",_imm); break; case 0x6c: dis_show_op("jmp",_ind); break; case 0x6d: dis_show_op("adc",_abs); break; case 0x6e: dis_show_op("ror",_abs); break; case 0x6f: dis_show_op("rra",_abs); break; case 0x70: dis_show_op("bvs",_rel); break; case 0x71: dis_show_op("adc",_ind_y); break; case 0x72: dis_show_op("jam",_imp); break; case 0x73: dis_show_op("rra",_ind_y); break; case 0x74: dis_show_op("nop",_zero_x); break; case 0x75: dis_show_op("adc",_zero_x); break; case 0x76: dis_show_op("ror",_zero_x); break; case 0x77: dis_show_op("rra",_zero_x); break; case 0x78: dis_show_op("sei",_imp); break; case 0x79: dis_show_op("adc",_abs_y); break; case 0x7a: dis_show_op("nop",_imp); break; case 0x7b: dis_show_op("rra",_abs_y); break; case 0x7c: dis_show_op("nop",_abs_x); break; case 0x7d: dis_show_op("adc",_abs_x); break; case 0x7e: dis_show_op("ror",_abs_x); break; case 0x7f: dis_show_op("rra",_abs_x); break; case 0x80: dis_show_op("nop",_imm); break; case 0x81: dis_show_op("sta",_ind_x); break; case 0x82: dis_show_op("nop",_imm); break; case 0x83: dis_show_op("sax",_ind_x); break; case 0x84: dis_show_op("sty",_zero); break; case 0x85: dis_show_op("sta",_zero); break; case 0x86: dis_show_op("stx",_zero); break; case 0x87: dis_show_op("sax",_zero); break; case 0x88: dis_show_op("dey",_imp); break; case 0x89: dis_show_op("nop",_imm); break; case 0x8a: dis_show_op("txa",_imp); break; case 0x8b: dis_show_op("ane",_imm); break; case 0x8c: dis_show_op("sty",_abs); break; case 0x8d: dis_show_op("sta",_abs); break; case 0x8e: dis_show_op("stx",_abs); break; case 0x8f: dis_show_op("sax",_abs); break; case 0x90: dis_show_op("bcc",_rel); break; case 0x91: dis_show_op("sta",_ind_y); break; case 0x92: dis_show_op("jam",_imp); break; case 0x93: dis_show_op("sha",_ind_y); break; case 0x94: dis_show_op("sty",_zero_x); break; case 0x95: dis_show_op("sta",_zero_x); break; case 0x96: dis_show_op("stx",_zero_y); break; case 0x97: dis_show_op("sax",_zero_y); break; case 0x98: dis_show_op("tya",_imp); break; case 0x99: dis_show_op("sta",_abs_y); break; case 0x9a: dis_show_op("txs",_imp); break; case 0x9b: dis_show_op("shs",_abs_y); break; case 0x9c: dis_show_op("shy",_abs_x); break; case 0x9d: dis_show_op("sta",_abs_x); break; case 0x9e: dis_show_op("shx",_abs_y); break; case 0x9f: dis_show_op("sha",_abs_y); break; case 0xa0: dis_show_op("ldy",_imm); break; case 0xa1: dis_show_op("lda",_ind_x); break; case 0xa2: dis_show_op("ldx",_imm); break; case 0xa3: dis_show_op("lax",_ind_x); break; case 0xa4: dis_show_op("ldy",_zero); break; case 0xa5: dis_show_op("lda",_zero); break; case 0xa6: dis_show_op("ldx",_zero); break; case 0xa7: dis_show_op("lax",_zero); break; case 0xa8: dis_show_op("tay",_imp); break; case 0xa9: dis_show_op("lda",_imm); break; case 0xaa: dis_show_op("tax",_imp); break; case 0xab: dis_show_op("lxa",_imm); break; case 0xac: dis_show_op("ldy",_abs); break; case 0xad: dis_show_op("lda",_abs); break; case 0xae: dis_show_op("ldx",_abs); break; case 0xaf: dis_show_op("lax",_abs); break; case 0xb0: dis_show_op("bcs",_rel); break; case 0xb1: dis_show_op("lda",_ind_y); break; case 0xb2: dis_show_op("jam",_imp); break; case 0xb3: dis_show_op("lax",_ind_y); break; case 0xb4: dis_show_op("ldy",_zero_x); break; case 0xb5: dis_show_op("lda",_zero_x); break; case 0xb6: dis_show_op("ldx",_zero_y); break; case 0xb7: dis_show_op("lax",_zero_y); break; case 0xb8: dis_show_op("clv",_imp); break; case 0xb9: dis_show_op("lda",_abs_y); break; case 0xba: dis_show_op("tsx",_imp); break; case 0xbb: dis_show_op("las",_abs_y); break; case 0xbc: dis_show_op("ldy",_abs_x); break; case 0xbd: dis_show_op("lda",_abs_x); break; case 0xbe: dis_show_op("ldx",_abs_y); break; case 0xbf: dis_show_op("lax",_abs_y); break; case 0xc0: dis_show_op("cpy",_imm); break; case 0xc1: dis_show_op("cmp",_ind_x); break; case 0xc2: dis_show_op("nop",_imm); break; case 0xc3: dis_show_op("dcp",_ind_x); break; case 0xc4: dis_show_op("cpy",_zero); break; case 0xc5: dis_show_op("cmp",_zero); break; case 0xc6: dis_show_op("dec",_zero); break; case 0xc7: dis_show_op("dcp",_zero); break; case 0xc8: dis_show_op("iny",_imp); break; case 0xc9: dis_show_op("cmp",_imm); break; case 0xca: dis_show_op("dex",_imp); break; case 0xcb: dis_show_op("sbx",_imm); break; case 0xcc: dis_show_op("cpy",_abs); break; case 0xcd: dis_show_op("cmp",_abs); break; case 0xce: dis_show_op("dec",_abs); break; case 0xcf: dis_show_op("dcp",_abs); break; case 0xd0: dis_show_op("bne",_rel); break; case 0xd1: dis_show_op("cmp",_ind_y); break; case 0xd2: dis_show_op("jam",_imp); break; case 0xd3: dis_show_op("dcp",_ind_y); break; case 0xd4: dis_show_op("nop",_zero_x); break; case 0xd5: dis_show_op("cmp",_zero_x); break; case 0xd6: dis_show_op("dec",_zero_x); break; case 0xd7: dis_show_op("dcp",_zero_x); break; case 0xd8: dis_show_op("cld",_imp); break; case 0xd9: dis_show_op("cmp",_abs_y); break; case 0xda: dis_show_op("nop",_imp); break; case 0xdb: dis_show_op("dcp",_abs_y); break; case 0xdc: dis_show_op("nop",_abs_x); break; case 0xdd: dis_show_op("cmp",_abs_x); break; case 0xde: dis_show_op("dec",_abs_x); break; case 0xdf: dis_show_op("dcp",_abs_x); break; case 0xe0: dis_show_op("cpx",_imm); break; case 0xe1: dis_show_op("sbc",_ind_x); break; case 0xe2: dis_show_op("nop",_imm); break; case 0xe3: dis_show_op("isb",_ind_x); break; case 0xe4: dis_show_op("cpx",_zero); break; case 0xe5: dis_show_op("sbc",_zero); break; case 0xe6: dis_show_op("inc",_zero); break; case 0xe7: dis_show_op("isb",_zero); break; case 0xe8: dis_show_op("inx",_imp); break; case 0xe9: dis_show_op("sbc",_imm); break; case 0xea: dis_show_op("nop",_imp); break; case 0xeb: dis_show_op("sbc",_imm); break; case 0xec: dis_show_op("cpx",_abs); break; case 0xed: dis_show_op("sbc",_abs); break; case 0xee: dis_show_op("inc",_abs); break; case 0xef: dis_show_op("isb",_abs); break; case 0xf0: dis_show_op("beq",_rel); break; case 0xf1: dis_show_op("sbc",_ind_y); break; case 0xf2: dis_show_op("jam",_imp); break; case 0xf3: dis_show_op("isb",_ind_y); break; case 0xf4: dis_show_op("nop",_zero_x); break; case 0xf5: dis_show_op("sbc",_zero_x); break; case 0xf6: dis_show_op("inc",_zero_x); break; case 0xf7: dis_show_op("isb",_zero_x); break; case 0xf8: dis_show_op("sed",_imp); break; case 0xf9: dis_show_op("sbc",_abs_y); break; case 0xfa: dis_show_op("nop",_imp); break; case 0xfb: dis_show_op("isb",_abs_y); break; case 0xfc: dis_show_op("nop",_abs_x); break; case 0xfd: dis_show_op("sbc",_abs_x); break; case 0xfe: dis_show_op("inc",_abs_x); break; case 0xff: dis_show_op("isb",_abs_x); break; } log_printf("%c%c1%c%c%c%c%c %02X %02X %02X %02X\n", (P & N_FLAG) ? 'N' : 'n', (P & V_FLAG) ? 'V' : 'v', (P & V_FLAG) ? 'B' : 'b', (P & V_FLAG) ? 'D' : 'd', (P & V_FLAG) ? 'I' : 'i', (P & V_FLAG) ? 'Z' : 'z', (P & V_FLAG) ? 'C' : 'c', A, X, Y, S); } #endif /* NES6502_DEBUG */ /* ** $Log: dis6502.c,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/fds_snd.h0000644000175000017500000000330514647725152015737 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** fds_snd.h ** ** Famicom Disk System sound emulation ** $Id: fds_snd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifndef _FDS_SND_H_ #define _FDS_SND_H_ #include "nes_apu.h" extern apuext_t fds_ext; #endif /* _VRCVISND_H_ */ /* ** $Log: fds_snd.h,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.1 2000/06/20 00:06:47 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/version.h0000644000175000017500000000276414647725152016014 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** version.h ** ** Program name / version definitions ** $Id: version.h,v 1.1 2003/04/08 20:46:46 ben Exp $ */ #ifndef _VERSION_H_ #define _VERSION_H_ #ifdef NSF_PLAYER #define APP_STRING "Nosefart" #else #define APP_STRING "Nofrendo" #endif /* NSF_PLAYER */ #define APP_VERSION "2.3-mls" #endif /* _VERSION_H_ */ /* ** $Log: version.h,v $ ** Revision 1.1 2003/04/08 20:46:46 ben ** add new input for NES music file. ** ** Revision 1.7 2000/07/04 04:46:55 matt ** updated version number ** ** Revision 1.6 2000/06/20 00:03:39 matt ** updated for 1.91 ** ** Revision 1.5 2000/06/09 17:01:56 matt ** changed version to 1.90 ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/vrcvisnd.c0000644000175000017500000001314614647725152016154 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** vrcvisnd.c ** ** VRCVI sound hardware emulation ** $Id: vrcvisnd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "types.h" #include "vrcvisnd.h" #include "nes_apu.h" static vrcvisnd_t vrcvi; static int32 vrcvi_incsize; /* VRCVI rectangle wave generation */ static int32 vrcvi_rectangle(vrcvirectangle_t *chan) { /* reg0: 0-3=volume, 4-6=duty cycle ** reg1: 8 bits of freq ** reg2: 0-3=high freq, 7=enable */ chan->phaseacc -= vrcvi_incsize; /* # of clocks per wave cycle */ while (chan->phaseacc < 0) { chan->phaseacc += chan->freq; chan->adder = (chan->adder + 1) & 0x0F; } /* return if not enabled */ if (FALSE == chan->enabled) return 0; if (chan->adder < chan->duty_flip) return -(chan->volume); else return chan->volume; } /* VRCVI sawtooth wave generation */ static int32 vrcvi_sawtooth(vrcvisawtooth_t *chan) { /* reg0: 0-5=phase accumulator bits ** reg1: 8 bits of freq ** reg2: 0-3=high freq, 7=enable */ chan->phaseacc -= vrcvi_incsize; /* # of clocks per wav cycle */ while (chan->phaseacc < 0) { chan->phaseacc += chan->freq; chan->output_acc += chan->volume; if (7 == ++chan->adder) { chan->adder = 0; chan->output_acc = 0; } } /* return if not enabled */ if (FALSE == chan->enabled) return 0; else return (chan->output_acc >> 3) << 9; } /* mix vrcvi sound channels together */ static int32 vrcvi_process(void) { int32 output; output = vrcvi_rectangle(&vrcvi.rectangle[0]); output += vrcvi_rectangle(&vrcvi.rectangle[1]); output += vrcvi_sawtooth(&vrcvi.saw); return output; } /* write to registers */ static void vrcvi_write(uint32 address, uint8 value) { int chan; switch (address & 0xB003) { case 0x9000: case 0xA000: chan = (address >> 12) - 9; vrcvi.rectangle[chan].reg[0] = value; vrcvi.rectangle[chan].volume = (value & 0x0F) << 8; vrcvi.rectangle[chan].duty_flip = (value >> 4) + 1; break; case 0x9001: case 0xA001: chan = (address >> 12) - 9; vrcvi.rectangle[chan].reg[1] = value; vrcvi.rectangle[chan].freq = APU_TO_FIXED(((vrcvi.rectangle[chan].reg[2] & 0x0F) << 8) + value + 1); break; case 0x9002: case 0xA002: chan = (address >> 12) - 9; vrcvi.rectangle[chan].reg[2] = value; vrcvi.rectangle[chan].freq = APU_TO_FIXED(((value & 0x0F) << 8) + vrcvi.rectangle[chan].reg[1] + 1); vrcvi.rectangle[chan].enabled = (value & 0x80) ? TRUE : FALSE; break; case 0xB000: vrcvi.saw.reg[0] = value; vrcvi.saw.volume = value & 0x3F; break; case 0xB001: vrcvi.saw.reg[1] = value; vrcvi.saw.freq = APU_TO_FIXED((((vrcvi.saw.reg[2] & 0x0F) << 8) + value + 1) << 1); break; case 0xB002: vrcvi.saw.reg[2] = value; vrcvi.saw.freq = APU_TO_FIXED((((value & 0x0F) << 8) + vrcvi.saw.reg[1] + 1) << 1); vrcvi.saw.enabled = (value & 0x80) ? TRUE : FALSE; break; default: break; } } /* reset state of vrcvi sound channels */ static void vrcvi_reset(void) { int i; /* preload regs */ for (i = 0; i < 3; i++) { vrcvi_write(0x9000 + i, 0); vrcvi_write(0xA000 + i, 0); vrcvi_write(0xB000 + i, 0); } /* get the phase period from the apu */ vrcvi_incsize = apu_getcyclerate(); } static void vrcvi_dummy(void) { } static apu_memwrite vrcvi_memwrite[] = { // { 0x4040, 0x4092, ext_write }, /* FDS sound regs */ { 0x9000, 0x9002, vrcvi_write }, /* vrc6 */ { 0xA000, 0xA002, vrcvi_write }, { 0xB000, 0xB002, vrcvi_write }, { -1, -1, NULL } }; apuext_t vrcvi_ext = { vrcvi_dummy, /* no init */ vrcvi_dummy, /* no shutdown */ vrcvi_reset, vrcvi_process, NULL, /* no reads */ vrcvi_memwrite }; /* ** $Log: vrcvisnd.c,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:36 tmmm ** initial import of Nosefart sources ** ** Revision 1.9 2000/07/04 04:51:41 matt ** cleanups ** ** Revision 1.8 2000/07/03 02:18:53 matt ** much better external module exporting ** ** Revision 1.7 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.6 2000/06/20 00:08:58 matt ** changed to driver based API ** ** Revision 1.5 2000/06/09 16:49:02 matt ** removed all floating point from sound generation ** ** Revision 1.4 2000/06/09 15:12:28 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/nes_apu.h0000644000175000017500000001547714647725152015766 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** nes_apu.h ** ** NES APU emulation header file ** $Id: nes_apu.h,v 1.2 2003/01/09 19:50:03 jkeil Exp $ */ #ifndef _NES_APU_H_ #define _NES_APU_H_ #ifdef __GNUC__ #define INLINE static inline #elif defined(WIN32) #define INLINE static __inline #else #define INLINE static #endif /* define this for realtime generated noise */ #define REALTIME_NOISE #define APU_WRA0 0x4000 #define APU_WRA1 0x4001 #define APU_WRA2 0x4002 #define APU_WRA3 0x4003 #define APU_WRB0 0x4004 #define APU_WRB1 0x4005 #define APU_WRB2 0x4006 #define APU_WRB3 0x4007 #define APU_WRC0 0x4008 #define APU_WRC2 0x400A #define APU_WRC3 0x400B #define APU_WRD0 0x400C #define APU_WRD2 0x400E #define APU_WRD3 0x400F #define APU_WRE0 0x4010 #define APU_WRE1 0x4011 #define APU_WRE2 0x4012 #define APU_WRE3 0x4013 #define APU_OAMDMA 0x4014 #define APU_SMASK 0x4015 #define APU_JOY0 0x4016 #define APU_JOY1 0x4017 /* length of generated noise */ #define APU_NOISE_32K 0x7FFF #define APU_NOISE_93 93 #define APU_BASEFREQ (NES_MASTER_CLOCK / 12) /* to/from 16.16 fixed point */ #define APU_TO_FIXED(x) ((x) << 16) #define APU_FROM_FIXED(x) ((x) >> 16) /* channel structures */ /* As much data as possible is precalculated, ** to keep the sample processing as lean as possible */ typedef struct rectangle_s { uint8 regs[4]; boolean enabled; int32 phaseacc; int32 freq; int32 output_vol; boolean fixed_envelope; boolean holdnote; uint8 volume; int32 sweep_phase; int32 sweep_delay; boolean sweep_on; uint8 sweep_shifts; uint8 sweep_length; boolean sweep_inc; int32 freq_limit; int32 env_phase; int32 env_delay; uint8 env_vol; int vbl_length; uint8 adder; int duty_flip; } rectangle_t; /* enum { COUNTMODE_LOAD, COUNTMODE_COUNT }; */ typedef struct triangle_s { uint8 regs[3]; boolean enabled; int32 freq; int32 phaseacc; int32 output_vol; uint8 adder; boolean holdnote; boolean counter_started; /* quasi-hack */ int write_latency; // boolean countmode; int vbl_length; int linear_length; } triangle_t; typedef struct noise_s { uint8 regs[3]; boolean enabled; int32 freq; int32 phaseacc; int32 output_vol; int32 env_phase; int32 env_delay; uint8 env_vol; boolean fixed_envelope; boolean holdnote; uint8 volume; int vbl_length; #ifdef REALTIME_NOISE uint8 xor_tap; #else boolean short_sample; int cur_pos; #endif /* REALTIME_NOISE */ } noise_t; typedef struct dmc_s { uint8 regs[4]; /* bodge for timestamp queue */ boolean enabled; int32 freq; int32 phaseacc; int32 output_vol; uint32 address; uint32 cached_addr; int dma_length; int cached_dmalength; uint8 cur_byte; boolean looping; boolean irq_gen; boolean irq_occurred; } dmc_t; enum { APU_FILTER_NONE, APU_FILTER_LOWPASS, APU_FILTER_WEIGHTED }; typedef struct { uint32 min_range, max_range; uint8 (*read_func)(uint32 address); } apu_memread; typedef struct { uint32 min_range, max_range; void (*write_func)(uint32 address, uint8 value); } apu_memwrite; /* external sound chip stuff */ typedef struct apuext_s { void (*init)(void); void (*shutdown)(void); void (*reset)(void); int32 (*process)(void); apu_memread *mem_read; apu_memwrite *mem_write; } apuext_t; /* APU queue structure */ #define APUQUEUE_SIZE 4096 #define APUQUEUE_MASK (APUQUEUE_SIZE - 1) /* apu ring buffer member */ typedef struct apudata_s { uint32 timestamp, address; uint8 value; } apudata_t; typedef struct apu_s { rectangle_t rectangle[2]; triangle_t triangle; noise_t noise; dmc_t dmc; uint8 enable_reg; apudata_t queue[APUQUEUE_SIZE]; int q_head, q_tail; uint32 elapsed_cycles; void *buffer; /* pointer to output buffer */ int num_samples; int mix_enable; /* $$$ben : should improve emulation */ int filter_type; int32 cycle_rate; int sample_rate; int sample_bits; int refresh_rate; void (*process)(void *buffer, int num_samples); /* $$$ ben : last error string */ const char * errstr; /* external sound chip */ apuext_t *ext; } apu_t; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Function prototypes */ extern apu_t *apu_create(int sample_rate, int refresh_rate, int sample_bits, boolean stereo); extern void apu_destroy(apu_t *apu); extern int apu_setext(apu_t *apu, apuext_t *ext); extern int apu_setfilter(int filter_type); extern void apu_process(void *buffer, int num_samples); extern void apu_reset(void); extern int apu_setchan(int chan, boolean enabled); extern int32 apu_getcyclerate(void); extern apu_t *apu_getcontext(void); extern uint8 apu_read(uint32 address); extern void apu_write(uint32 address, uint8 value); /* for visualization */ extern void apu_getpcmdata(void **data, int *num_samples, int *sample_bits); extern void apu_setcontext(apu_t *src_apu); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _NES_APU_H_ */ /* ** $Log: nes_apu.h,v $ ** Revision 1.2 2003/01/09 19:50:03 jkeil ** NSF audio files were crashing on SPARC. ** ** - Define the correct HOST_ENDIAN for SPARC ** - remove unaligned memory accesses ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.12 2000/07/04 04:54:48 matt ** minor changes that helped with MAME ** ** Revision 1.11 2000/07/03 02:18:53 matt ** much better external module exporting ** ** Revision 1.10 2000/06/26 05:00:37 matt ** cleanups ** ** Revision 1.9 2000/06/23 03:29:28 matt ** cleaned up external sound inteface ** ** Revision 1.8 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.7 2000/06/20 00:07:35 matt ** added convenience members to apu_t struct ** ** Revision 1.6 2000/06/09 16:49:02 matt ** removed all floating point from sound generation ** ** Revision 1.5 2000/06/09 15:12:28 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/nsf.h0000644000175000017500000001320614647725152015106 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** nsf.h ** ** NSF loading/saving related defines / prototypes ** $Id: nsf.h,v 1.3 2007/01/18 21:34:10 dgp85 Exp $ */ #ifndef _NSF_H_ #define _NSF_H_ #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included #endif #include "osd.h" #include "nes6502.h" #include "nes_apu.h" #define NSF_MAGIC "NESM\x1A" #define NSF_DEDICATED_PAL 0x01 #define NSF_DUAL_PAL_NTSC 0x02 #define EXT_SOUND_NONE 0x00 #define EXT_SOUND_VRCVI 0x01 #define EXT_SOUND_VRCVII 0x02 #define EXT_SOUND_FDS 0x04 #define EXT_SOUND_MMC5 0x08 #define EXT_SOUND_NAMCO106 0x10 #define EXT_SOUND_SUNSOFT_FME07 0x20 /* bits 6,7: future expansion */ #define NSF_HEADER_SIZE 0x80 /* 60 Hertz refresh (NTSC) */ #define NES_MASTER_CLOCK 21477272.7272 #define NTSC_REFRESH 60 #define NTSC_SUBCARRIER_DIV 12 #define NTSC_SCANLINES 262 #define NES_FRAME_CYCLES ((NES_MASTER_CLOCK / NTSC_SUBCARRIER_DIV) / NTSC_REFRESH) #define NES_SCANLINE_CYCLES (NES_FRAME_CYCLES / NTSC_SCANLINES) /* filter levels */ enum { NSF_FILTER_NONE, NSF_FILTER_LOWPASS, NSF_FILTER_WEIGHTED, NSF_FILTER_MAX, /* $$$ ben : add this one for range chacking */ }; typedef struct nsf_s { /* NESM header */ uint8 id[5]; /* NESM\x1A */ uint8 version; /* spec version */ uint8 num_songs; /* total num songs */ uint8 start_song; /* first song */ uint16 load_addr; /* loc to load code */ uint16 init_addr; /* init call address */ uint16 play_addr; /* play call address */ uint8 song_name[32]; /* name of song */ uint8 artist_name[32]; /* artist name */ uint8 copyright[32]; /* copyright info */ uint16 ntsc_speed; /* playback speed (if NTSC) */ uint8 bankswitch_info[8]; /* initial code banking */ uint16 pal_speed; /* playback speed (if PAL) */ uint8 pal_ntsc_bits; /* NTSC/PAL determination bits */ uint8 ext_sound_type; /* type of external sound gen. */ uint8 reserved[4]; /* reserved */ /* things that the NSF player needs */ uint8 *data; /* actual NSF data */ uint32 length; /* length of data */ uint32 playback_rate; /* current playback rate */ uint8 current_song; /* current song */ boolean bankswitched; /* is bankswitched? */ /* $$$ ben : Playing time ... */ uint32 cur_frame; uint32 cur_frame_end; uint32 * song_frames; /* $$$ ben : Last error string */ const char * errstr; /* CPU and APU contexts */ nes6502_context *cpu; apu_t *apu; /* our main processing routine, calls all external mixing routines */ void (*process)(void *buffer, int num_samples); } XINE_PACKED nsf_t; /* $$$ ben : Generic loader struct */ struct nsf_loader_t { /* Init and open. */ int (*open)(struct nsf_loader_t * loader); /* Close and shutdown. */ void (*close) (struct nsf_loader_t * loader); /* This function should return <0 on error, else the number of byte NOT read. * that way a simple 0 test tell us if read was complete. */ int (*read) (struct nsf_loader_t * loader, void *data, int n); /* Get file length. */ int (*length) (struct nsf_loader_t * loader); /* Skip n bytes. */ int (*skip) (struct nsf_loader_t * loader,int n); /* Get filename (for debug). */ const char * (*fname) (struct nsf_loader_t * loader); }; /* Function prototypes */ extern int nsf_init(void); extern nsf_t * nsf_load_extended(struct nsf_loader_t * loader); extern nsf_t *nsf_load(const char *filename, void *source, int length); extern void nsf_free(nsf_t **nsf_info); extern int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, boolean stereo); extern void nsf_frame(nsf_t *nsf); extern int nsf_setchan(nsf_t *nsf, int chan, boolean enabled); extern int nsf_setfilter(nsf_t *nsf, int filter_type); #endif /* _NSF_H_ */ /* ** $Log: nsf.h,v $ ** Revision 1.3 2003/05/01 22:34:20 benjihan ** New NSF plugin ** ** Revision 1.2 2003/04/09 14:50:32 ben ** Clean NSF api. ** ** Revision 1.1 2003/04/08 20:53:00 ben ** Adding more files... ** ** Revision 1.11 2000/07/04 04:59:24 matt ** removed DOS-specific stuff ** ** Revision 1.10 2000/07/03 02:19:36 matt ** dynamic address range handlers, cleaner and faster ** ** Revision 1.9 2000/06/23 03:27:58 matt ** cleaned up external sound inteface ** ** Revision 1.8 2000/06/20 04:04:37 matt ** moved external soundchip struct to apu module ** ** Revision 1.7 2000/06/20 00:05:45 matt ** changed to driver-based external sound generation ** ** Revision 1.6 2000/06/13 03:51:54 matt ** update API to take freq/sample data on nsf_playtrack ** ** Revision 1.5 2000/06/12 01:13:00 matt ** added CPU/APU as members of the nsf struct ** ** Revision 1.4 2000/06/09 15:12:26 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/nes6502.c0000644000175000017500000015200714647725152015420 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** nes6502.c ** ** NES custom 6502 (2A03) CPU implementation ** $Id: nes6502.c,v 1.2 2003/01/09 19:50:03 jkeil Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "types.h" #include "nes6502.h" #include "dis6502.h" #include #define ADD_CYCLES(x) instruction_cycles += (x) #define INC_CYCLES() instruction_cycles++ //#define ADD_CYCLES(x) remaining_cycles -= (x) //#define INC_CYCLES() remaining_cycles-- /* ** Check to see if an index reg addition overflowed to next page */ #define CHECK_INDEX_OVERFLOW(addr, reg) \ { \ if ((uint8) (addr) < (reg)) \ INC_CYCLES(); \ } /* ** Addressing mode macros */ #define NO_READ(value) /* empty */ #define IMMEDIATE_BYTE(value) \ { \ value = bank_readbyte(PC++); \ } #define ABSOLUTE_ADDR(address) \ { \ address = bank_readaddress(PC); \ PC += 2; \ } #define ABSOLUTE(address, value) \ { \ ABSOLUTE_ADDR(address); \ value = mem_read(address); \ } #define ABSOLUTE_BYTE(value) \ { \ ABSOLUTE(temp, value); \ } #define ABS_IND_X_ADDR(address) \ { \ address = (bank_readaddress(PC) + X) & 0xFFFF; \ PC += 2; \ CHECK_INDEX_OVERFLOW(address, X); \ } #define ABS_IND_X(address, value) \ { \ ABS_IND_X_ADDR(address); \ value = mem_read(address); \ } #define ABS_IND_X_BYTE(value) \ { \ ABS_IND_X(temp, value); \ } #define ABS_IND_Y_ADDR(address) \ { \ address = (bank_readaddress(PC) + Y) & 0xFFFF; \ PC += 2; \ CHECK_INDEX_OVERFLOW(address, Y); \ } #define ABS_IND_Y(address, value) \ { \ ABS_IND_Y_ADDR(address); \ value = mem_read(address); \ } #define ABS_IND_Y_BYTE(value) \ { \ ABS_IND_Y(temp, value); \ } #define ZERO_PAGE_ADDR(address) \ { \ IMMEDIATE_BYTE(address); \ } #define ZERO_PAGE(address, value) \ { \ ZERO_PAGE_ADDR(address); \ value = ZP_READ(address); \ } #define ZERO_PAGE_BYTE(value) \ { \ ZERO_PAGE(btemp, value); \ } /* Zero-page indexed Y doesn't really exist, just for LDX / STX */ #define ZP_IND_X_ADDR(address) \ { \ address = bank_readbyte(PC++) + X; \ } #define ZP_IND_X(bAddr, value) \ { \ ZP_IND_X_ADDR(bAddr); \ value = ZP_READ(bAddr); \ } #define ZP_IND_X_BYTE(value) \ { \ ZP_IND_X(btemp, value); \ } #define ZP_IND_Y_ADDR(address) \ { \ address = bank_readbyte(PC++) + Y; \ } #define ZP_IND_Y(address, value) \ { \ ZP_IND_Y_ADDR(address); \ value = ZP_READ(address); \ } #define ZP_IND_Y_BYTE(value) \ { \ ZP_IND_Y(btemp, value); \ } /* ** For conditional jump relative instructions ** (BCC, BCS, BEQ, BMI, BNE, BPL, BVC, BVS) */ #define RELATIVE_JUMP(cond) \ { \ if (cond) \ { \ IMMEDIATE_BYTE(btemp); \ if (((int8) btemp + (uint8) PC) & 0xFF00) \ ADD_CYCLES(4); \ else \ ADD_CYCLES(3); \ PC += ((int8) btemp); \ } \ else \ { \ PC++; \ ADD_CYCLES(2); \ } \ } /* ** This is actually indexed indirect, but I call it ** indirect X to avoid confusion */ #define INDIR_X_ADDR(address) \ { \ btemp = bank_readbyte(PC++) + X; \ address = zp_address(btemp); \ } #define INDIR_X(address, value) \ { \ INDIR_X_ADDR(address); \ value = mem_read(address); \ } #define INDIR_X_BYTE(value) \ { \ INDIR_X(temp, value); \ } /* ** This is actually indirect indexed, but I call it ** indirect y to avoid confusion */ #define INDIR_Y_ADDR(address) \ { \ IMMEDIATE_BYTE(btemp); \ address = (zp_address(btemp) + Y) & 0xFFFF; \ /* ???? */ \ CHECK_INDEX_OVERFLOW(address, Y); \ } #define INDIR_Y(address, value) \ { \ INDIR_Y_ADDR(address); \ value = mem_read(address); \ } #define INDIR_Y_BYTE(value) \ { \ /*IMMEDIATE_BYTE(btemp); \ temp = zp_address(btemp) + Y; \ CHECK_INDEX_OVERFLOW(temp, Y); \ value = mem_read(temp);*/ \ INDIR_Y(temp, value); \ } #define JUMP(address) PC = bank_readaddress((address)) /* ** Interrupt macros */ #define NMI() \ { \ PUSH(PC >> 8); \ PUSH(PC & 0xFF); \ CLEAR_FLAG(B_FLAG); \ PUSH(P); \ SET_FLAG(I_FLAG); \ JUMP(NMI_VECTOR); \ int_pending &= ~NMI_MASK; \ ADD_CYCLES(INT_CYCLES); \ } #define IRQ() \ { \ PUSH(PC >> 8); \ PUSH(PC & 0xFF); \ CLEAR_FLAG(B_FLAG); \ PUSH(P); \ SET_FLAG(I_FLAG); \ JUMP(IRQ_VECTOR); \ int_pending &= ~IRQ_MASK; \ ADD_CYCLES(INT_CYCLES); \ } /* ** Instruction macros */ /* Warning! NES CPU has no decimal mode, so by default this does no BCD! */ #ifdef NES6502_DECIMAL #define ADC(cycles, read_func) \ { \ read_func(data); \ if (P & D_FLAG) \ { \ temp = (A & 0x0F) + (data & 0x0F) + (P & C_FLAG); \ if (temp >= 10) \ temp = (temp - 10) | 0x10; \ temp += (A & 0xF0) + (data & 0xF0); \ TEST_AND_FLAG(0 == ((A + data + (P & C_FLAG)) & 0xFF), Z_FLAG); \ TEST_AND_FLAG(temp & 0x80, N_FLAG); \ TEST_AND_FLAG(((~(A ^ data)) & (A ^ temp) & 0x80), V_FLAG); \ if (temp > 0x9F) \ temp += 0x60; \ TEST_AND_FLAG(temp > 0xFF, C_FLAG); \ A = (uint8) temp; \ } \ else \ { \ temp = A + data + (P & C_FLAG); \ /* Set C on carry */ \ TEST_AND_FLAG(temp > 0xFF, C_FLAG); \ /* Set V on overflow */ \ TEST_AND_FLAG(((~(A ^ data)) & (A ^ temp) & 0x80), V_FLAG); \ A = (uint8) temp; \ SET_NZ_FLAGS(A); \ }\ ADD_CYCLES(cycles); \ } #else #define ADC(cycles, read_func) \ { \ read_func(data); \ temp = A + data + (P & C_FLAG); \ /* Set C on carry */ \ TEST_AND_FLAG(temp > 0xFF, C_FLAG); \ /* Set V on overflow */ \ TEST_AND_FLAG(((~(A ^ data)) & (A ^ temp) & 0x80), V_FLAG); \ A = (uint8) temp; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #endif /* NES6502_DECIMAL */ /* undocumented */ #define ANC(cycles, read_func) \ { \ read_func(data); \ A &= data; \ SET_NZ_FLAGS(A); \ TEST_AND_FLAG(P & N_FLAG, C_FLAG); \ ADD_CYCLES(cycles); \ } #define AND(cycles, read_func) \ { \ read_func(data); \ A &= data; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } /* undocumented */ #define ANE(cycles, read_func) \ { \ read_func(data); \ A = (A | 0xEE) & X & data; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } /* undocumented */ #ifdef NES6502_DECIMAL #define ARR(cycles, read_func) \ { \ read_func(data); \ data &= A; \ if (P & D_FLAG) \ { \ temp = (data >> 1) | ((P & C_FLAG) << 7); \ SET_NZ_FLAGS(temp); \ TEST_AND_FLAG((temp ^ data) & 0x40, V_FLAG); \ if (((data & 0x0F) + (data & 0x01)) > 5) \ temp = (temp & 0xF0) | ((temp + 0x6) & 0x0F); \ if (((data & 0xF0) + (data & 0x10)) > 0x50) \ { \ temp = (temp & 0x0F) | ((temp + 0x60) & 0xF0); \ SET_FLAG(C_FLAG); \ } \ else \ CLEAR_FLAG(C_FLAG); \ A = (uint8) temp; \ } \ else \ { \ A = (data >> 1) | ((P & C_FLAG) << 7); \ SET_NZ_FLAGS(A); \ TEST_AND_FLAG(A & 0x40, C_FLAG); \ TEST_AND_FLAG(((A >> 6) ^ (A >> 5)) & 1, V_FLAG); \ }\ ADD_CYCLES(cycles); \ } #else #define ARR(cycles, read_func) \ { \ read_func(data); \ data &= A; \ A = (data >> 1) | ((P & C_FLAG) << 7); \ SET_NZ_FLAGS(A); \ TEST_AND_FLAG(A & 0x40, C_FLAG); \ TEST_AND_FLAG((A >> 6) ^ (A >> 5), V_FLAG); \ ADD_CYCLES(cycles); \ } #endif /* NES6502_DECIMAL */ #define ASL(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ TEST_AND_FLAG(data & 0x80, C_FLAG); \ data <<= 1; \ write_func(addr, data); \ SET_NZ_FLAGS(data); \ ADD_CYCLES(cycles); \ } #define ASL_A() \ { \ TEST_AND_FLAG(A & 0x80, C_FLAG); \ A <<= 1; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(2); \ } /* undocumented */ #define ASR(cycles, read_func) \ { \ read_func(data); \ data &= A; \ TEST_AND_FLAG(data & 0x01, C_FLAG); \ A = data >> 1; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #define BCC() \ { \ RELATIVE_JUMP((IS_FLAG_CLEAR(C_FLAG))); \ } #define BCS() \ { \ RELATIVE_JUMP((IS_FLAG_SET(C_FLAG))); \ } #define BEQ() \ { \ RELATIVE_JUMP((IS_FLAG_SET(Z_FLAG))); \ } #define BIT(cycles, read_func) \ { \ read_func(data); \ TEST_AND_FLAG(0 == (data & A), Z_FLAG);\ CLEAR_FLAG(N_FLAG | V_FLAG); \ /* move bit 7/6 of data into N/V flags */ \ SET_FLAG(data & (N_FLAG | V_FLAG)); \ ADD_CYCLES(cycles); \ } #define BMI() \ { \ RELATIVE_JUMP((IS_FLAG_SET(N_FLAG))); \ } #define BNE() \ { \ RELATIVE_JUMP((IS_FLAG_CLEAR(Z_FLAG))); \ } #define BPL() \ { \ RELATIVE_JUMP((IS_FLAG_CLEAR(N_FLAG))); \ } /* Software interrupt type thang */ #define BRK() \ { \ PC++; \ PUSH(PC >> 8); \ PUSH(PC & 0xFF); \ SET_FLAG(B_FLAG); \ PUSH(P); \ SET_FLAG(I_FLAG); \ JUMP(IRQ_VECTOR); \ ADD_CYCLES(7); \ } #define BVC() \ { \ RELATIVE_JUMP((IS_FLAG_CLEAR(V_FLAG))); \ } #define BVS() \ { \ RELATIVE_JUMP((IS_FLAG_SET(V_FLAG))); \ } #define CLC() \ { \ CLEAR_FLAG(C_FLAG); \ ADD_CYCLES(2); \ } #define CLD() \ { \ CLEAR_FLAG(D_FLAG); \ ADD_CYCLES(2); \ } #define CLI() \ { \ CLEAR_FLAG(I_FLAG); \ ADD_CYCLES(2); \ } #define CLV() \ { \ CLEAR_FLAG(V_FLAG); \ ADD_CYCLES(2); \ } /* TODO: ick! */ #define _COMPARE(reg, value) \ { \ temp = (reg) - (value); \ /* C is clear when data > A */ \ TEST_AND_FLAG(0 == (temp & 0x8000), C_FLAG); \ SET_NZ_FLAGS((uint8) temp); /* handles Z flag */ \ } #define CMP(cycles, read_func) \ { \ read_func(data); \ _COMPARE(A, data); \ ADD_CYCLES(cycles); \ } #define CPX(cycles, read_func) \ { \ read_func(data); \ _COMPARE(X, data); \ ADD_CYCLES(cycles); \ } #define CPY(cycles, read_func) \ { \ read_func(data); \ _COMPARE(Y, data); \ ADD_CYCLES(cycles); \ } /* undocumented */ #define DCP(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ data--; \ write_func(addr, data); \ CMP(cycles, NO_READ); \ } #define DEC(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ data--; \ write_func(addr, data); \ SET_NZ_FLAGS(data); \ ADD_CYCLES(cycles); \ } #define DEX() \ { \ X--; \ SET_NZ_FLAGS(X); \ ADD_CYCLES(2); \ } #define DEY() \ { \ Y--; \ SET_NZ_FLAGS(Y); \ ADD_CYCLES(2); \ } /* undocumented (double-NOP) */ #define DOP(cycles) \ { \ PC++; \ ADD_CYCLES(cycles); \ } #define EOR(cycles, read_func) \ { \ read_func(data); \ A ^= data; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #define INC(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ data++; \ write_func(addr, data); \ SET_NZ_FLAGS(data); \ ADD_CYCLES(cycles); \ } #define INX() \ { \ X++; \ SET_NZ_FLAGS(X); \ ADD_CYCLES(2); \ } #define INY() \ { \ Y++; \ SET_NZ_FLAGS(Y); \ ADD_CYCLES(2); \ } /* undocumented */ #define ISB(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ data++; \ write_func(addr, data); \ SBC(cycles, NO_READ); \ } #ifdef NES6502_TESTOPS #define JAM() \ { \ cpu_Jam(); \ } #elif defined(NSF_PLAYER) #define JAM() \ { \ } #else #define JAM() \ { \ char jambuf[20]; \ sprintf(jambuf, "JAM: PC=$%04X", PC); \ ASSERT_MSG(jambuf); \ ADD_CYCLES(2); \ } #endif /* NES6502_TESTOPS */ #define JMP_INDIRECT() \ { \ temp = bank_readaddress(PC); \ /* bug in crossing page boundaries */ \ if (0xFF == (uint8) temp) \ PC = (bank_readbyte(temp & ~0xFF) << 8) | bank_readbyte(temp); \ else \ JUMP(temp); \ ADD_CYCLES(5); \ } #define JMP_ABSOLUTE() \ { \ JUMP(PC); \ ADD_CYCLES(3); \ } #define JSR() \ { \ PC++; \ PUSH(PC >> 8); \ PUSH(PC & 0xFF); \ JUMP(PC - 1); \ ADD_CYCLES(6); \ } /* undocumented */ #define LAS(cycles, read_func) \ { \ read_func(data); \ A = X = S = (S & data); \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } /* undocumented */ #define LAX(cycles, read_func) \ { \ read_func(A); \ X = A; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #define LDA(cycles, read_func) \ { \ read_func(A); \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #define LDX(cycles, read_func) \ { \ read_func(X); \ SET_NZ_FLAGS(X);\ ADD_CYCLES(cycles); \ } #define LDY(cycles, read_func) \ { \ read_func(Y); \ SET_NZ_FLAGS(Y);\ ADD_CYCLES(cycles); \ } #define LSR(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ TEST_AND_FLAG(data & 0x01, C_FLAG); \ data >>= 1; \ write_func(addr, data); \ SET_NZ_FLAGS(data); \ ADD_CYCLES(cycles); \ } #define LSR_A() \ { \ TEST_AND_FLAG(A & 0x01, C_FLAG); \ A >>= 1; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(2); \ } /* undocumented */ #define LXA(cycles, read_func) \ { \ read_func(data); \ A = X = ((A | 0xEE) & data); \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #define NOP() \ { \ ADD_CYCLES(2); \ } #define ORA(cycles, read_func) \ { \ read_func(data); \ A |= data; \ SET_NZ_FLAGS(A);\ ADD_CYCLES(cycles); \ } #define PHA() \ { \ PUSH(A); \ ADD_CYCLES(3); \ } #define PHP() \ { \ /* B flag is pushed on stack as well */ \ PUSH((P | B_FLAG)); \ ADD_CYCLES(3); \ } #define PLA() \ { \ A = PULL(); \ SET_NZ_FLAGS(A); \ ADD_CYCLES(4); \ } #define PLP() \ { \ P = PULL(); \ SET_FLAG(R_FLAG); /* ensure reserved flag is set */ \ ADD_CYCLES(4); \ } /* undocumented */ #define RLA(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ if (P & C_FLAG) \ { \ TEST_AND_FLAG(data & 0x80, C_FLAG); \ data = (data << 1) | 1; \ } \ else \ { \ TEST_AND_FLAG(data & 0x80, C_FLAG); \ data <<= 1; \ } \ write_func(addr, data); \ A &= data; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } /* 9-bit rotation (carry flag used for rollover) */ #define ROL(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ if (P & C_FLAG) \ { \ TEST_AND_FLAG(data & 0x80, C_FLAG); \ data = (data << 1) | 1; \ } \ else \ { \ TEST_AND_FLAG(data & 0x80, C_FLAG); \ data <<= 1; \ } \ write_func(addr, data); \ SET_NZ_FLAGS(data); \ ADD_CYCLES(cycles); \ } #define ROL_A() \ { \ if (P & C_FLAG) \ { \ TEST_AND_FLAG(A & 0x80, C_FLAG); \ A = (A << 1) | 1; \ } \ else \ { \ TEST_AND_FLAG(A & 0x80, C_FLAG); \ A <<= 1; \ } \ SET_NZ_FLAGS(A); \ ADD_CYCLES(2); \ } #define ROR(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ if (P & C_FLAG) \ { \ TEST_AND_FLAG(data & 1, C_FLAG); \ data = (data >> 1) | 0x80; \ } \ else \ { \ TEST_AND_FLAG(data & 1, C_FLAG); \ data >>= 1; \ } \ write_func(addr, data); \ SET_NZ_FLAGS(data); \ ADD_CYCLES(cycles); \ } #define ROR_A() \ { \ if (P & C_FLAG) \ { \ TEST_AND_FLAG(A & 1, C_FLAG); \ A = (A >> 1) | 0x80; \ } \ else \ { \ TEST_AND_FLAG(A & 1, C_FLAG); \ A >>= 1; \ } \ SET_NZ_FLAGS(A); \ ADD_CYCLES(2); \ } /* undocumented */ #define RRA(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ if (P & C_FLAG) \ { \ TEST_AND_FLAG(data & 1, C_FLAG); \ data = (data >> 1) | 0x80; \ } \ else \ { \ TEST_AND_FLAG(data & 1, C_FLAG); \ data >>= 1; \ } \ write_func(addr, data); \ ADC(cycles, NO_READ); \ } #define RTI() \ { \ P = PULL(); \ SET_FLAG(R_FLAG); /* ensure reserved flag is set */ \ PC = PULL(); \ PC |= PULL() << 8; \ ADD_CYCLES(6); \ } #define RTS() \ { \ PC = PULL(); \ PC = (PC | (PULL() << 8)) + 1; \ ADD_CYCLES(6); \ } /* undocumented */ #define SAX(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ data = A & X; \ write_func(addr, data); \ ADD_CYCLES(cycles); \ } /* Warning! NES CPU has no decimal mode, so by default this does no BCD! */ #ifdef NES6502_DECIMAL #define SBC(cycles, read_func) \ { \ read_func(data); \ /* NOT(C) is considered borrow */ \ temp = A - data - ((P & C_FLAG) ^ C_FLAG); \ if (P & D_FLAG) \ { \ uint8 al, ah; \ al = (A & 0x0F) - (data & 0x0F) - ((P & C_FLAG) ^ C_FLAG); \ ah = (A >> 4) - (data >> 4); \ if (al & 0x10) \ { \ al -= 6; \ ah--; \ } \ if (ah & 0x10) \ ah -= 6; \ TEST_AND_FLAG(temp < 0x100, C_FLAG); \ TEST_AND_FLAG(((A ^ temp) & 0x80) && ((A ^ data) & 0x80), V_FLAG); \ SET_NZ_FLAGS(temp & 0xFF); \ A = (ah << 4) | (al & 0x0F); \ } \ else \ { \ TEST_AND_FLAG(((A ^ temp) & 0x80) && ((A ^ data) & 0x80), V_FLAG); \ TEST_AND_FLAG(temp < 0x100, C_FLAG); \ A = (uint8) temp; \ SET_NZ_FLAGS(A & 0xFF); \ } \ ADD_CYCLES(cycles); \ } #else #define SBC(cycles, read_func) \ { \ read_func(data); \ temp = A - data - ((P & C_FLAG) ^ C_FLAG); \ TEST_AND_FLAG(((A ^ data) & (A ^ temp) & 0x80), V_FLAG); \ TEST_AND_FLAG(temp < 0x100, C_FLAG); \ A = (uint8) temp; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #endif /* NES6502_DECIMAL */ /* undocumented */ #define SBX(cycles, read_func) \ { \ read_func(data); \ temp = (A & X) - data; \ TEST_AND_FLAG(temp < 0x100, C_FLAG); \ X = temp & 0xFF; \ SET_NZ_FLAGS(X); \ ADD_CYCLES(cycles); \ } #define SEC() \ { \ SET_FLAG(C_FLAG); \ ADD_CYCLES(2); \ } #define SED() \ { \ SET_FLAG(D_FLAG); \ ADD_CYCLES(2); \ } #define SEI() \ { \ SET_FLAG(I_FLAG); \ ADD_CYCLES(2); \ } /* undocumented */ #define SHA(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ data = A & X & ((uint8) ((addr >> 8) + 1)); \ write_func(addr, data); \ ADD_CYCLES(cycles); \ } /* undocumented */ #define SHS(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ S = A & X; \ data = S & ((uint8) ((addr >> 8) + 1)); \ write_func(addr, data); \ ADD_CYCLES(cycles); \ } /* undocumented */ #define SHX(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ data = X & ((uint8) ((addr >> 8) + 1)); \ write_func(addr, data); \ ADD_CYCLES(cycles); \ } /* undocumented */ #define SHY(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ data = Y & ((uint8) ((addr >> 8 ) + 1)); \ write_func(addr, data); \ ADD_CYCLES(cycles); \ } /* undocumented */ #define SLO(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ TEST_AND_FLAG(data & 0x80, C_FLAG); \ data <<= 1; \ write_func(addr, data); \ A |= data; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } /* unoffical */ #define SRE(cycles, read_func, write_func, addr) \ { \ read_func(addr, data); \ TEST_AND_FLAG(data & 1, C_FLAG); \ data >>= 1; \ write_func(addr, data); \ A ^= data; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(cycles); \ } #define STA(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ write_func(addr, A); \ ADD_CYCLES(cycles); \ } #define STX(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ write_func(addr, X); \ ADD_CYCLES(cycles); \ } #define STY(cycles, read_func, write_func, addr) \ { \ read_func(addr); \ write_func(addr, Y); \ ADD_CYCLES(cycles); \ } #define TAX() \ { \ X = A; \ SET_NZ_FLAGS(X);\ ADD_CYCLES(2); \ } #define TAY() \ { \ Y = A; \ SET_NZ_FLAGS(Y);\ ADD_CYCLES(2); \ } /* undocumented (triple-NOP) */ #define TOP() \ { \ PC += 2; \ ADD_CYCLES(4); \ } #define TSX() \ { \ X = S; \ SET_NZ_FLAGS(X);\ ADD_CYCLES(2); \ } #define TXA() \ { \ A = X; \ SET_NZ_FLAGS(A);\ ADD_CYCLES(2); \ } #define TXS() \ { \ S = X; \ ADD_CYCLES(2); \ } #define TYA() \ { \ A = Y; \ SET_NZ_FLAGS(A); \ ADD_CYCLES(2); \ } /* ** Stack and data fetching macros */ /* Set/clear/test bits in the flags register */ #define SET_FLAG(mask) P |= (mask) #define CLEAR_FLAG(mask) P &= ~(mask) #define IS_FLAG_SET(mask) (P & (mask)) #define IS_FLAG_CLEAR(mask) (0 == IS_FLAG_SET((mask))) #define TEST_AND_FLAG(test, mask) \ { \ if ((test)) \ SET_FLAG((mask)); \ else \ CLEAR_FLAG((mask)); \ } /* ** flag register helper macros */ /* register push/pull */ #ifdef NES6502_MEM_ACCESS_CTRL # define PUSH(value) stack_push((S--),(value)) # define PULL() stack_pull((++S)) #else # define PUSH(value) stack_page[S--] = (uint8) (value) # define PULL() stack_page[++S] #endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ /* Sets the Z and N flags based on given data, taken from precomputed table */ #define SET_NZ_FLAGS(value) P &= ~(N_FLAG | Z_FLAG); \ P |= flag_table[(value)] #define GET_GLOBAL_REGS() \ { \ PC = reg_PC; \ A = reg_A; \ X = reg_X; \ Y = reg_Y; \ P = reg_P; \ S = reg_S; \ } #define SET_LOCAL_REGS() \ { \ reg_PC = PC; \ reg_A = A; \ reg_X = X; \ reg_Y = Y; \ reg_P = P; \ reg_S = S; \ } /* static data */ static nes6502_memread *pmem_read, *pmr; static nes6502_memwrite *pmem_write, *pmw; /* lookup table for N/Z flags */ static uint8 flag_table[256]; /* internal critical CPU vars */ static uint32 reg_PC; static uint8 reg_A, reg_P, reg_X, reg_Y, reg_S; static uint8 int_pending; static int dma_cycles; /* execution cycle count (can be reset by user) */ static uint32 total_cycles = 0; /* memory region pointers */ static uint8 *nes6502_banks[NES6502_NUMBANKS]; static uint8 *ram = NULL; static uint8 *stack_page = NULL; /* access flag for memory * $$$ ben : I add this for the playing time calculation. * Only if compiled with NES6502_MEM_ACCESS. */ #ifdef NES6502_MEM_ACCESS_CTRL uint8 *acc_nes6502_banks[NES6502_NUMBANKS]; static uint8 *acc_ram = NULL; static uint8 *acc_stack_page = NULL; uint8 nes6502_mem_access = 0; /* $$$ ben : * Set memory access check flags, and store ORed frame global check * for music time calculation. */ static void chk_mem_access(uint8 * access, int flags) { uint8 oldchk = * access; if ((oldchk&flags) != flags) { nes6502_mem_access |= flags; *access = oldchk|flags; } } INLINE void stack_push(uint8 s, uint8 v) { chk_mem_access(acc_stack_page+s, NES6502_WRITE_ACCESS); stack_page[s] = v; } INLINE uint8 stack_pull(uint8 s) { chk_mem_access(acc_stack_page+s, NES6502_READ_ACCESS); return stack_page[s]; } INLINE uint8 zp_read(register uint32 addr) { chk_mem_access(acc_ram+addr, NES6502_READ_ACCESS); return ram[addr]; } INLINE void zp_write(register uint32 addr, uint8 v) { chk_mem_access(acc_ram+addr, NES6502_WRITE_ACCESS); ram[addr] = v; } #define ZP_READ(addr) zp_read((addr)) #define ZP_WRITE(addr, value) zp_write((addr),(value)) #define bank_readbyte(address) _bank_readbyte((address), NES6502_READ_ACCESS) #define bank_readbyte_pc(address) _bank_readbyte((address), NES6502_EXE_ACCESS) #else # define chk_mem_access(access, flags) /* ** Zero-page helper macros */ #define ZP_READ(addr) ram[(addr)] #define ZP_WRITE(addr, value) ram[(addr)] = (uint8) (value) #define bank_readbyte(address) _bank_readbyte((address)) #define bank_readbyte_pc(address) _bank_readbyte((address)) #endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ #ifdef NES6502_MEM_ACCESS_CTRL int max_access[NES6502_NUMBANKS] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; INLINE uint8 _bank_readbyte(register uint32 address, const uint8 flags) #else INLINE uint8 _bank_readbyte(register uint32 address) #endif { ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); #ifdef NES6502_MEM_ACCESS_CTRL //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, flags); if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) { max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); } #endif chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] + (address & NES6502_BANKMASK), flags); return nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK]; } INLINE void bank_writebyte(register uint32 address, register uint8 value) { ASSERT(nes6502_banks[address >> NES6502_BANKSHIFT]); #ifdef NES6502_MEM_ACCESS_CTRL //printf("chk_mem_access(acc_nes6502_banks[%d] + %d, %d)\n", address>>NES6502_BANKSHIFT, address & NES6502_BANKMASK, NES6502_WRITE_ACCESS); if((address & NES6502_BANKMASK) > max_access[address>>NES6502_BANKSHIFT]) { max_access[address>>NES6502_BANKSHIFT] = address & NES6502_BANKMASK; //printf("max_access[%d] increased to %d\n", address>>NES6502_BANKSHIFT, max_access[address>>NES6502_BANKSHIFT]); } #endif chk_mem_access(acc_nes6502_banks[address>>NES6502_BANKSHIFT] + (address & NES6502_BANKMASK), NES6502_WRITE_ACCESS); nes6502_banks[address >> NES6502_BANKSHIFT][address & NES6502_BANKMASK] = value; } /* Read a 16bit word */ #define READ_SNES_16(bank,offset) \ (\ (offset) [ (uint8 *) (bank) ] |\ ((unsigned int)( ((offset)+1) [ (uint8 *) (bank) ] ) << 8)\ ) INLINE uint32 zp_address(register uint8 address) { chk_mem_access(acc_ram+address, NES6502_READ_ACCESS); chk_mem_access(acc_ram+address+1, NES6502_READ_ACCESS); #if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) /* TODO: this fails if src address is $xFFF */ /* TODO: this fails if host architecture doesn't support byte alignment */ /* $$$ ben : DONE */ return (uint32) (*(uint16 *)(ram + address)); #elif defined(TARGET_CPU_PPC) return __lhbrx(ram, address); #else return READ_SNES_16(ram,address); /* uint32 x = (uint32) *(uint16 *)(ram + address); */ /* return (x << 8) | (x >> 8); */ //#endif /* TARGET_CPU_PPC */ #endif /* HOST_LITTLE_ENDIAN */ } INLINE uint32 bank_readaddress(register uint32 address) { #ifdef NES6502_MEM_ACCESS_CTRL { const unsigned int offset = address & NES6502_BANKMASK; uint8 * addr = acc_nes6502_banks[address >> NES6502_BANKSHIFT]; chk_mem_access(addr+offset+0, NES6502_READ_ACCESS); chk_mem_access(addr+offset+1, NES6502_READ_ACCESS); } #endif #if defined (HOST_LITTLE_ENDIAN) && defined(HOST_UNALIGN_WORD) /* TODO: this fails if src address is $xFFF */ /* TODO: this fails if host architecture doesn't support byte alignment */ /* $$$ ben : DONE */ return (uint32) (*(uint16 *)(nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK))); #elif defined(TARGET_CPU_PPC) return __lhbrx(nes6502_banks[address >> NES6502_BANKSHIFT], address & NES6502_BANKMASK); #else { const unsigned int offset = address & NES6502_BANKMASK; return READ_SNES_16(nes6502_banks[address >> NES6502_BANKSHIFT], offset); } /* uint32 x = (uint32) *(uint16 *)(nes6502_banks[address >> NES6502_BANKSHIFT] + (address & NES6502_BANKMASK)); */ /* return (x << 8) | (x >> 8); */ //#endif /* TARGET_CPU_PPC */ #endif /* HOST_LITTLE_ENDIAN */ } /* read a byte of 6502 memory */ static uint8 mem_read(uint32 address) { /* TODO: following cases are N2A03-specific */ /* RAM */ if (address < 0x800) { chk_mem_access(acc_ram + address, NES6502_READ_ACCESS); return ram[address]; } /* always paged memory */ // else if (address >= 0x6000) else if (address >= 0x8000) { return bank_readbyte(address); } /* check memory range handlers */ else { for (pmr = pmem_read; pmr->min_range != 0xFFFFFFFF; pmr++) { if ((address >= pmr->min_range) && (address <= pmr->max_range)) return pmr->read_func(address); } } /* return paged memory */ return bank_readbyte(address); } /* write a byte of data to 6502 memory */ static void mem_write(uint32 address, uint8 value) { /* RAM */ if (address < 0x800) { chk_mem_access(acc_ram + address, NES6502_WRITE_ACCESS); ram[address] = value; return; } /* check memory range handlers */ else { for (pmw = pmem_write; pmw->min_range != 0xFFFFFFFF; pmw++) { if ((address >= pmw->min_range) && (address <= pmw->max_range)) { pmw->write_func(address, value); return; } } } /* write to paged memory */ bank_writebyte(address, value); } /* set the current context */ void nes6502_setcontext(nes6502_context *cpu) { int loop; ASSERT(cpu); /* Set the page pointers */ for (loop = 0; loop < NES6502_NUMBANKS; loop++) { nes6502_banks[loop] = cpu->mem_page[loop]; #ifdef NES6502_MEM_ACCESS_CTRL acc_nes6502_banks[loop] = cpu->acc_mem_page[loop]; #endif } ram = nes6502_banks[0]; /* quicker zero-page/RAM references */ stack_page = ram + STACK_OFFSET; #ifdef NES6502_MEM_ACCESS_CTRL acc_ram = acc_nes6502_banks[0]; /* quicker zero-page/RAM references */ acc_stack_page = acc_ram + STACK_OFFSET; #endif pmem_read = cpu->read_handler; pmem_write = cpu->write_handler; reg_PC = cpu->pc_reg; reg_A = cpu->a_reg; reg_P = cpu->p_reg; reg_X = cpu->x_reg; reg_Y = cpu->y_reg; reg_S = cpu->s_reg; int_pending = cpu->int_pending; dma_cycles = cpu->dma_cycles; } /* get the current context */ void nes6502_getcontext(nes6502_context *cpu) { int loop; /* Set the page pointers */ for (loop = 0; loop < NES6502_NUMBANKS; loop++) { cpu->mem_page[loop] = nes6502_banks[loop]; #ifdef NES6502_MEM_ACCESS_CTRL cpu->acc_mem_page[loop] = acc_nes6502_banks[loop]; #endif } cpu->read_handler = pmem_read; cpu->write_handler = pmem_write; cpu->pc_reg = reg_PC; cpu->a_reg = reg_A; cpu->p_reg = reg_P; cpu->x_reg = reg_X; cpu->y_reg = reg_Y; cpu->s_reg = reg_S; cpu->int_pending = int_pending; cpu->dma_cycles = dma_cycles; } /* DMA a byte of data from ROM */ uint8 nes6502_getbyte(uint32 address) { return bank_readbyte(address); } /* get number of elapsed cycles */ uint32 nes6502_getcycles(boolean reset_flag) { uint32 cycles = total_cycles; if (reset_flag) total_cycles = 0; return cycles; } /* Execute instructions until count expires ** ** Returns the number of cycles *actually* executed ** (note that this can be from 0-6 cycles more than you wanted) */ int nes6502_execute(int remaining_cycles) { int instruction_cycles, old_cycles = total_cycles; uint32 temp, addr; /* for macros */ uint32 PC; uint8 A, X, Y, P, S; uint8 opcode, data; uint8 btemp, baddr; /* for macros */ GET_GLOBAL_REGS(); #ifdef NES6502_MEM_ACCESS_CTRL /* reset global memory access for this execute loop. */ nes6502_mem_access = 0; #endif /* Continue until we run out of cycles */ while (remaining_cycles > 0) { instruction_cycles = 0; /* check for DMA cycle burning */ if (dma_cycles) { if (remaining_cycles <= dma_cycles) { dma_cycles -= remaining_cycles; total_cycles += remaining_cycles; goto _execute_done; } else { remaining_cycles -= dma_cycles; total_cycles += dma_cycles; dma_cycles = 0; } } if (int_pending) { /* NMI has highest priority */ if (int_pending & NMI_MASK) { NMI(); } /* IRQ has lowest priority */ else /* if (int_pending & IRQ_MASK) */ { if (IS_FLAG_CLEAR(I_FLAG)) IRQ(); } } /* Fetch instruction */ //nes6502_disasm(PC, P, A, X, Y, S); opcode = bank_readbyte_pc(PC++); /* Execute instruction */ switch (opcode) { case 0x00: /* BRK */ BRK(); break; case 0x01: /* ORA ($nn,X) */ ORA(6, INDIR_X_BYTE); break; /* JAM */ case 0x02: /* JAM */ case 0x12: /* JAM */ case 0x22: /* JAM */ case 0x32: /* JAM */ case 0x42: /* JAM */ case 0x52: /* JAM */ case 0x62: /* JAM */ case 0x72: /* JAM */ case 0x92: /* JAM */ case 0xB2: /* JAM */ case 0xD2: /* JAM */ case 0xF2: /* JAM */ JAM(); /* kill switch for CPU emulation */ goto _execute_done; case 0x03: /* SLO ($nn,X) */ SLO(8, INDIR_X, mem_write, addr); break; case 0x04: /* NOP $nn */ case 0x44: /* NOP $nn */ case 0x64: /* NOP $nn */ DOP(3); break; case 0x05: /* ORA $nn */ ORA(3, ZERO_PAGE_BYTE); break; case 0x06: /* ASL $nn */ ASL(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x07: /* SLO $nn */ SLO(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x08: /* PHP */ PHP(); break; case 0x09: /* ORA #$nn */ ORA(2, IMMEDIATE_BYTE); break; case 0x0A: /* ASL A */ ASL_A(); break; case 0x0B: /* ANC #$nn */ ANC(2, IMMEDIATE_BYTE); break; case 0x0C: /* NOP $nnnn */ TOP(); break; case 0x0D: /* ORA $nnnn */ ORA(4, ABSOLUTE_BYTE); break; case 0x0E: /* ASL $nnnn */ ASL(6, ABSOLUTE, mem_write, addr); break; case 0x0F: /* SLO $nnnn */ SLO(6, ABSOLUTE, mem_write, addr); break; case 0x10: /* BPL $nnnn */ BPL(); break; case 0x11: /* ORA ($nn),Y */ ORA(5, INDIR_Y_BYTE); break; case 0x13: /* SLO ($nn),Y */ SLO(8, INDIR_Y, mem_write, addr); break; case 0x14: /* NOP $nn,X */ case 0x34: /* NOP */ case 0x54: /* NOP $nn,X */ case 0x74: /* NOP $nn,X */ case 0xD4: /* NOP $nn,X */ case 0xF4: /* NOP ($nn,X) */ DOP(4); break; case 0x15: /* ORA $nn,X */ ORA(4, ZP_IND_X_BYTE); break; case 0x16: /* ASL $nn,X */ ASL(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x17: /* SLO $nn,X */ SLO(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x18: /* CLC */ CLC(); break; case 0x19: /* ORA $nnnn,Y */ ORA(4, ABS_IND_Y_BYTE); break; case 0x1A: /* NOP */ case 0x3A: /* NOP */ case 0x5A: /* NOP */ case 0x7A: /* NOP */ case 0xDA: /* NOP */ case 0xFA: /* NOP */ NOP(); break; case 0x1B: /* SLO $nnnn,Y */ SLO(7, ABS_IND_Y, mem_write, addr); break; case 0x1C: /* NOP $nnnn,X */ case 0x3C: /* NOP $nnnn,X */ case 0x5C: /* NOP $nnnn,X */ case 0x7C: /* NOP $nnnn,X */ case 0xDC: /* NOP $nnnn,X */ case 0xFC: /* NOP $nnnn,X */ TOP(); break; case 0x1D: /* ORA $nnnn,X */ ORA(4, ABS_IND_X_BYTE); break; case 0x1E: /* ASL $nnnn,X */ ASL(7, ABS_IND_X, mem_write, addr); break; case 0x1F: /* SLO $nnnn,X */ SLO(7, ABS_IND_X, mem_write, addr); break; case 0x20: /* JSR $nnnn */ JSR(); break; case 0x21: /* AND ($nn,X) */ AND(6, INDIR_X_BYTE); break; case 0x23: /* RLA ($nn,X) */ RLA(8, INDIR_X, mem_write, addr); break; case 0x24: /* BIT $nn */ BIT(3, ZERO_PAGE_BYTE); break; case 0x25: /* AND $nn */ AND(3, ZERO_PAGE_BYTE); break; case 0x26: /* ROL $nn */ ROL(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x27: /* RLA $nn */ RLA(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x28: /* PLP */ PLP(); break; case 0x29: /* AND #$nn */ AND(2, IMMEDIATE_BYTE); break; case 0x2A: /* ROL A */ ROL_A(); break; case 0x2B: /* ANC #$nn */ ANC(2, IMMEDIATE_BYTE); break; case 0x2C: /* BIT $nnnn */ BIT(4, ABSOLUTE_BYTE); break; case 0x2D: /* AND $nnnn */ AND(4, ABSOLUTE_BYTE); break; case 0x2E: /* ROL $nnnn */ ROL(6, ABSOLUTE, mem_write, addr); break; case 0x2F: /* RLA $nnnn */ RLA(6, ABSOLUTE, mem_write, addr); break; case 0x30: /* BMI $nnnn */ BMI(); break; case 0x31: /* AND ($nn),Y */ AND(5, INDIR_Y_BYTE); break; case 0x33: /* RLA ($nn),Y */ RLA(8, INDIR_Y, mem_write, addr); break; case 0x35: /* AND $nn,X */ AND(4, ZP_IND_X_BYTE); break; case 0x36: /* ROL $nn,X */ ROL(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x37: /* RLA $nn,X */ RLA(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x38: /* SEC */ SEC(); break; case 0x39: /* AND $nnnn,Y */ AND(4, ABS_IND_Y_BYTE); break; case 0x3B: /* RLA $nnnn,Y */ RLA(7, ABS_IND_Y, mem_write, addr); break; case 0x3D: /* AND $nnnn,X */ AND(4, ABS_IND_X_BYTE); break; case 0x3E: /* ROL $nnnn,X */ ROL(7, ABS_IND_X, mem_write, addr); break; case 0x3F: /* RLA $nnnn,X */ RLA(7, ABS_IND_X, mem_write, addr); break; case 0x40: /* RTI */ RTI(); break; case 0x41: /* EOR ($nn,X) */ EOR(6, INDIR_X_BYTE); break; case 0x43: /* SRE ($nn,X) */ SRE(8, INDIR_X, mem_write, addr); break; case 0x45: /* EOR $nn */ EOR(3, ZERO_PAGE_BYTE); break; case 0x46: /* LSR $nn */ LSR(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x47: /* SRE $nn */ SRE(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x48: /* PHA */ PHA(); break; case 0x49: /* EOR #$nn */ EOR(2, IMMEDIATE_BYTE); break; case 0x4A: /* LSR A */ LSR_A(); break; case 0x4B: /* ASR #$nn */ ASR(2, IMMEDIATE_BYTE); break; case 0x4C: /* JMP $nnnn */ JMP_ABSOLUTE(); break; case 0x4D: /* EOR $nnnn */ EOR(4, ABSOLUTE_BYTE); break; case 0x4E: /* LSR $nnnn */ LSR(6, ABSOLUTE, mem_write, addr); break; case 0x4F: /* SRE $nnnn */ SRE(6, ABSOLUTE, mem_write, addr); break; case 0x50: /* BVC $nnnn */ BVC(); break; case 0x51: /* EOR ($nn),Y */ EOR(5, INDIR_Y_BYTE); break; case 0x53: /* SRE ($nn),Y */ SRE(8, INDIR_Y, mem_write, addr); break; case 0x55: /* EOR $nn,X */ EOR(4, ZP_IND_X_BYTE); break; case 0x56: /* LSR $nn,X */ LSR(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x57: /* SRE $nn,X */ SRE(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x58: /* CLI */ CLI(); break; case 0x59: /* EOR $nnnn,Y */ EOR(4, ABS_IND_Y_BYTE); break; case 0x5B: /* SRE $nnnn,Y */ SRE(7, ABS_IND_Y, mem_write, addr); break; case 0x5D: /* EOR $nnnn,X */ EOR(4, ABS_IND_X_BYTE); break; case 0x5E: /* LSR $nnnn,X */ LSR(7, ABS_IND_X, mem_write, addr); break; case 0x5F: /* SRE $nnnn,X */ SRE(7, ABS_IND_X, mem_write, addr); break; case 0x60: /* RTS */ RTS(); break; case 0x61: /* ADC ($nn,X) */ ADC(6, INDIR_X_BYTE); break; case 0x63: /* RRA ($nn,X) */ RRA(8, INDIR_X, mem_write, addr); break; case 0x65: /* ADC $nn */ ADC(3, ZERO_PAGE_BYTE); break; case 0x66: /* ROR $nn */ ROR(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x67: /* RRA $nn */ RRA(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0x68: /* PLA */ PLA(); break; case 0x69: /* ADC #$nn */ ADC(2, IMMEDIATE_BYTE); break; case 0x6A: /* ROR A */ ROR_A(); break; case 0x6B: /* ARR #$nn */ ARR(2, IMMEDIATE_BYTE); break; case 0x6C: /* JMP ($nnnn) */ JMP_INDIRECT(); break; case 0x6D: /* ADC $nnnn */ ADC(4, ABSOLUTE_BYTE); break; case 0x6E: /* ROR $nnnn */ ROR(6, ABSOLUTE, mem_write, addr); break; case 0x6F: /* RRA $nnnn */ RRA(6, ABSOLUTE, mem_write, addr); break; case 0x70: /* BVS $nnnn */ BVS(); break; case 0x71: /* ADC ($nn),Y */ ADC(5, INDIR_Y_BYTE); break; case 0x73: /* RRA ($nn),Y */ RRA(8, INDIR_Y, mem_write, addr); break; case 0x75: /* ADC $nn,X */ ADC(4, ZP_IND_X_BYTE); break; case 0x76: /* ROR $nn,X */ ROR(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x77: /* RRA $nn,X */ RRA(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0x78: /* SEI */ SEI(); break; case 0x79: /* ADC $nnnn,Y */ ADC(4, ABS_IND_Y_BYTE); break; case 0x7B: /* RRA $nnnn,Y */ RRA(7, ABS_IND_Y, mem_write, addr); break; case 0x7D: /* ADC $nnnn,X */ ADC(4, ABS_IND_X_BYTE); break; case 0x7E: /* ROR $nnnn,X */ ROR(7, ABS_IND_X, mem_write, addr); break; case 0x7F: /* RRA $nnnn,X */ RRA(7, ABS_IND_X, mem_write, addr); break; case 0x80: /* NOP #$nn */ case 0x82: /* NOP #$nn */ case 0x89: /* NOP #$nn */ case 0xC2: /* NOP #$nn */ case 0xE2: /* NOP #$nn */ DOP(2); break; case 0x81: /* STA ($nn,X) */ STA(6, INDIR_X_ADDR, mem_write, addr); break; case 0x83: /* SAX ($nn,X) */ SAX(6, INDIR_X_ADDR, mem_write, addr); break; case 0x84: /* STY $nn */ STY(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); break; case 0x85: /* STA $nn */ STA(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); break; case 0x86: /* STX $nn */ STX(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); break; case 0x87: /* SAX $nn */ SAX(3, ZERO_PAGE_ADDR, ZP_WRITE, baddr); break; case 0x88: /* DEY */ DEY(); break; case 0x8A: /* TXA */ TXA(); break; case 0x8B: /* ANE #$nn */ ANE(2, IMMEDIATE_BYTE); break; case 0x8C: /* STY $nnnn */ STY(4, ABSOLUTE_ADDR, mem_write, addr); break; case 0x8D: /* STA $nnnn */ STA(4, ABSOLUTE_ADDR, mem_write, addr); break; case 0x8E: /* STX $nnnn */ STX(4, ABSOLUTE_ADDR, mem_write, addr); break; case 0x8F: /* SAX $nnnn */ SAX(4, ABSOLUTE_ADDR, mem_write, addr); break; case 0x90: /* BCC $nnnn */ BCC(); break; case 0x91: /* STA ($nn),Y */ STA(6, INDIR_Y_ADDR, mem_write, addr); break; case 0x93: /* SHA ($nn),Y */ SHA(6, INDIR_Y_ADDR, mem_write, addr); break; case 0x94: /* STY $nn,X */ STY(4, ZP_IND_X_ADDR, ZP_WRITE, baddr); break; case 0x95: /* STA $nn,X */ STA(4, ZP_IND_X_ADDR, ZP_WRITE, baddr); break; case 0x96: /* STX $nn,Y */ STX(4, ZP_IND_Y_ADDR, ZP_WRITE, baddr); break; case 0x97: /* SAX $nn,Y */ SAX(4, ZP_IND_Y_ADDR, ZP_WRITE, baddr); break; case 0x98: /* TYA */ TYA(); break; case 0x99: /* STA $nnnn,Y */ STA(5, ABS_IND_Y_ADDR, mem_write, addr); break; case 0x9A: /* TXS */ TXS(); break; case 0x9B: /* SHS $nnnn,Y */ SHS(5, ABS_IND_Y_ADDR, mem_write, addr); break; case 0x9C: /* SHY $nnnn,X */ SHY(5, ABS_IND_X_ADDR, mem_write, addr); break; case 0x9D: /* STA $nnnn,X */ STA(5, ABS_IND_X_ADDR, mem_write, addr); break; case 0x9E: /* SHX $nnnn,Y */ SHX(5, ABS_IND_Y_ADDR, mem_write, addr); break; case 0x9F: /* SHA $nnnn,Y */ SHA(5, ABS_IND_Y_ADDR, mem_write, addr); break; case 0xA0: /* LDY #$nn */ LDY(2, IMMEDIATE_BYTE); break; case 0xA1: /* LDA ($nn,X) */ LDA(6, INDIR_X_BYTE); break; case 0xA2: /* LDX #$nn */ LDX(2, IMMEDIATE_BYTE); break; case 0xA3: /* LAX ($nn,X) */ LAX(6, INDIR_X_BYTE); break; case 0xA4: /* LDY $nn */ LDY(3, ZERO_PAGE_BYTE); break; case 0xA5: /* LDA $nn */ LDA(3, ZERO_PAGE_BYTE); break; case 0xA6: /* LDX $nn */ LDX(3, ZERO_PAGE_BYTE); break; case 0xA7: /* LAX $nn */ LAX(3, ZERO_PAGE_BYTE); break; case 0xA8: /* TAY */ TAY(); break; case 0xA9: /* LDA #$nn */ LDA(2, IMMEDIATE_BYTE); break; case 0xAA: /* TAX */ TAX(); break; case 0xAB: /* LXA #$nn */ LXA(2, IMMEDIATE_BYTE); break; case 0xAC: /* LDY $nnnn */ LDY(4, ABSOLUTE_BYTE); break; case 0xAD: /* LDA $nnnn */ LDA(4, ABSOLUTE_BYTE); break; case 0xAE: /* LDX $nnnn */ LDX(4, ABSOLUTE_BYTE); break; case 0xAF: /* LAX $nnnn */ LAX(4, ABSOLUTE_BYTE); break; case 0xB0: /* BCS $nnnn */ BCS(); break; case 0xB1: /* LDA ($nn),Y */ LDA(5, INDIR_Y_BYTE); break; case 0xB3: /* LAX ($nn),Y */ LAX(5, INDIR_Y_BYTE); break; case 0xB4: /* LDY $nn,X */ LDY(4, ZP_IND_X_BYTE); break; case 0xB5: /* LDA $nn,X */ LDA(4, ZP_IND_X_BYTE); break; case 0xB6: /* LDX $nn,Y */ LDX(4, ZP_IND_Y_BYTE); break; case 0xB7: /* LAX $nn,Y */ LAX(4, ZP_IND_Y_BYTE); break; case 0xB8: /* CLV */ CLV(); break; case 0xB9: /* LDA $nnnn,Y */ LDA(4, ABS_IND_Y_BYTE); break; case 0xBA: /* TSX */ TSX(); break; case 0xBB: /* LAS $nnnn,Y */ LAS(4, ABS_IND_Y_BYTE); break; case 0xBC: /* LDY $nnnn,X */ LDY(4, ABS_IND_X_BYTE); break; case 0xBD: /* LDA $nnnn,X */ LDA(4, ABS_IND_X_BYTE); break; case 0xBE: /* LDX $nnnn,Y */ LDX(4, ABS_IND_Y_BYTE); break; case 0xBF: /* LAX $nnnn,Y */ LAX(4, ABS_IND_Y_BYTE); break; case 0xC0: /* CPY #$nn */ CPY(2, IMMEDIATE_BYTE); break; case 0xC1: /* CMP ($nn,X) */ CMP(6, INDIR_X_BYTE); break; case 0xC3: /* DCP ($nn,X) */ DCP(8, INDIR_X, mem_write, addr); break; case 0xC4: /* CPY $nn */ CPY(3, ZERO_PAGE_BYTE); break; case 0xC5: /* CMP $nn */ CMP(3, ZERO_PAGE_BYTE); break; case 0xC6: /* DEC $nn */ DEC(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0xC7: /* DCP $nn */ DCP(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0xC8: /* INY */ INY(); break; case 0xC9: /* CMP #$nn */ CMP(2, IMMEDIATE_BYTE); break; case 0xCA: /* DEX */ DEX(); break; case 0xCB: /* SBX #$nn */ SBX(2, IMMEDIATE_BYTE); break; case 0xCC: /* CPY $nnnn */ CPY(4, ABSOLUTE_BYTE); break; case 0xCD: /* CMP $nnnn */ CMP(4, ABSOLUTE_BYTE); break; case 0xCE: /* DEC $nnnn */ DEC(6, ABSOLUTE, mem_write, addr); break; case 0xCF: /* DCP $nnnn */ DCP(6, ABSOLUTE, mem_write, addr); break; case 0xD0: /* BNE $nnnn */ BNE(); break; case 0xD1: /* CMP ($nn),Y */ CMP(5, INDIR_Y_BYTE); break; case 0xD3: /* DCP ($nn),Y */ DCP(8, INDIR_Y, mem_write, addr); break; case 0xD5: /* CMP $nn,X */ CMP(4, ZP_IND_X_BYTE); break; case 0xD6: /* DEC $nn,X */ DEC(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0xD7: /* DCP $nn,X */ DCP(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0xD8: /* CLD */ CLD(); break; case 0xD9: /* CMP $nnnn,Y */ CMP(4, ABS_IND_Y_BYTE); break; case 0xDB: /* DCP $nnnn,Y */ DCP(7, ABS_IND_Y, mem_write, addr); break; case 0xDD: /* CMP $nnnn,X */ CMP(4, ABS_IND_X_BYTE); break; case 0xDE: /* DEC $nnnn,X */ DEC(7, ABS_IND_X, mem_write, addr); break; case 0xDF: /* DCP $nnnn,X */ DCP(7, ABS_IND_X, mem_write, addr); break; case 0xE0: /* CPX #$nn */ CPX(2, IMMEDIATE_BYTE); break; case 0xE1: /* SBC ($nn,X) */ SBC(6, INDIR_X_BYTE); break; case 0xE3: /* ISB ($nn,X) */ ISB(8, INDIR_X, mem_write, addr); break; case 0xE4: /* CPX $nn */ CPX(3, ZERO_PAGE_BYTE); break; case 0xE5: /* SBC $nn */ SBC(3, ZERO_PAGE_BYTE); break; case 0xE6: /* INC $nn */ INC(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0xE7: /* ISB $nn */ ISB(5, ZERO_PAGE, ZP_WRITE, baddr); break; case 0xE8: /* INX */ INX(); break; case 0xE9: /* SBC #$nn */ case 0xEB: /* USBC #$nn */ SBC(2, IMMEDIATE_BYTE); break; case 0xEA: /* NOP */ NOP(); break; case 0xEC: /* CPX $nnnn */ CPX(4, ABSOLUTE_BYTE); break; case 0xED: /* SBC $nnnn */ SBC(4, ABSOLUTE_BYTE); break; case 0xEE: /* INC $nnnn */ INC(6, ABSOLUTE, mem_write, addr); break; case 0xEF: /* ISB $nnnn */ ISB(6, ABSOLUTE, mem_write, addr); break; case 0xF0: /* BEQ $nnnn */ BEQ(); break; case 0xF1: /* SBC ($nn),Y */ SBC(5, INDIR_Y_BYTE); break; case 0xF3: /* ISB ($nn),Y */ ISB(8, INDIR_Y, mem_write, addr); break; case 0xF5: /* SBC $nn,X */ SBC(4, ZP_IND_X_BYTE); break; case 0xF6: /* INC $nn,X */ INC(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0xF7: /* ISB $nn,X */ ISB(6, ZP_IND_X, ZP_WRITE, baddr); break; case 0xF8: /* SED */ SED(); break; case 0xF9: /* SBC $nnnn,Y */ SBC(4, ABS_IND_Y_BYTE); break; case 0xFB: /* ISB $nnnn,Y */ ISB(7, ABS_IND_Y, mem_write, addr); break; case 0xFD: /* SBC $nnnn,X */ SBC(4, ABS_IND_X_BYTE); break; case 0xFE: /* INC $nnnn,X */ INC(7, ABS_IND_X, mem_write, addr); break; case 0xFF: /* ISB $nnnn,X */ ISB(7, ABS_IND_X, mem_write, addr); break; } /* Calculate remaining/elapsed clock cycles */ remaining_cycles -= instruction_cycles; total_cycles += instruction_cycles; } _execute_done: /* restore local copy of regs */ SET_LOCAL_REGS(); /* Return our actual amount of executed cycles */ return (total_cycles - old_cycles); } /* Initialize tables, etc. */ void nes6502_init(void) { int index; /* Build the N / Z flag lookup table */ flag_table[0] = Z_FLAG; for (index = 1; index < 256; index++) flag_table[index] = (index & 0x80) ? N_FLAG : 0; reg_A = reg_X = reg_Y = 0; reg_S = 0xFF; /* Stack grows down */ } /* Issue a CPU Reset */ void nes6502_reset(void) { reg_P = Z_FLAG | R_FLAG | I_FLAG; /* Reserved bit always 1 */ int_pending = dma_cycles = 0; /* No pending interrupts */ reg_PC = bank_readaddress(RESET_VECTOR); /* Fetch reset vector */ /* TODO: 6 cycles for RESET? */ } /* Non-maskable interrupt */ void nes6502_nmi(void) { int_pending |= NMI_MASK; } /* Interrupt request */ void nes6502_irq(void) { int_pending |= IRQ_MASK; } /* Set dma period (in cycles) */ void nes6502_setdma(int cycles) { dma_cycles += cycles; } #ifdef NES6502_MEM_ACCESS_CTRL void nes6502_chk_mem_access(uint8 * access, int flags) { chk_mem_access(access, flags); } #endif /* ** $Log: nes6502.c,v $ ** Revision 1.2 2003/05/01 22:34:19 benjihan ** New NSF plugin ** ** Revision 1.1 2003/04/08 20:53:00 ben ** Adding more files... ** ** Revision 1.6 2000/07/04 04:50:07 matt ** minor change to includes ** ** Revision 1.5 2000/07/03 02:18:16 matt ** added a few notes about potential failure cases ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/log.c0000644000175000017500000000603214647725152015073 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** log.c ** ** Error logging functions ** $Id: log.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "types.h" #include "log.h" #ifdef OSD_LOG #include "osd.h" #endif #if defined(OSD_LOG) && !defined(NOFRENDO_DEBUG) #error NOFRENDO_DEBUG must be defined as well as OSD_LOG #endif /* Note that all of these functions will be empty if ** debugging is not enabled. */ #ifdef NOFRENDO_DEBUG static FILE *errorlog; #endif int log_init(void) { #ifdef NOFRENDO_DEBUG #ifdef OSD_LOG /* Initialize an OSD logging system */ osd_loginit(); #endif /* OSD_LOG */ errorlog = fopen("errorlog.txt", "wt"); if (NULL == errorlog) return (-1); #endif /* NOFRENDO_DEBUG */ return 0; } void log_shutdown(void) { #ifdef NOFRENDO_DEBUG /* Snoop around for unallocated blocks */ mem_checkblocks(); mem_checkleaks(); #ifdef OSD_LOG osd_logshutdown(); #endif /* OSD_LOG */ fclose(errorlog); #endif /* NOFRENDO_DEBUG */ } void log_print(const char *string) { #ifdef NOFRENDO_DEBUG #ifdef OSD_LOG osd_logprint(string); #endif /* OSD_LOG */ /* Log it to disk, as well */ fputs(string, errorlog); #else (void)string; #endif /* NOFRENDO_DEBUG */ } void log_printf(const char *format, ... ) { #ifdef NOFRENDO_DEBUG #ifdef OSD_LOG char buffer[1024 + 1]; #endif /* OSD_LOG */ va_list arg; va_start(arg, format); #ifdef OSD_LOG vsprintf(buffer, format, arg); osd_logprint(buffer); #endif /* OSD_LOG */ vfprintf(errorlog, format, arg); va_end(arg); #else (void)format; #endif /* NOFRENDO_DEBUG */ } /* ** $Log: log.c,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.5 2000/06/26 04:55:33 matt ** minor change ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/nes6502.h0000644000175000017500000001110214647725152015413 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** nes6502.h ** ** NES custom 6502 CPU definitions / prototypes ** $Id: nes6502.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ /* straitm */ #include "types.h" /* NOTE: 16-bit addresses avoided like the plague: use 32-bit values ** wherever humanly possible */ #ifndef _NES6502_H_ #define _NES6502_H_ /* Define this to enable decimal mode in ADC / SBC (not needed in NES) */ /*#define NES6502_DECIMAL*/ /* number of bank pointers the CPU emulation core handles */ #ifdef NSF_PLAYER #define NES6502_4KBANKS #endif #ifdef NES6502_4KBANKS #define NES6502_NUMBANKS 16 #define NES6502_BANKSHIFT 12 #else #define NES6502_NUMBANKS 8 #define NES6502_BANKSHIFT 13 #endif #define NES6502_BANKMASK ((0x10000 / NES6502_NUMBANKS) - 1) /* Add memory access control flags. This is a ram shadow memory that holds * for each memory bytes access flags for read, write and execute access. * The nes6502_mem_access holds all new access (all mode all location). It is * used to determine if the player has loop in playing time calculation. */ #ifdef NES6502_MEM_ACCESS_CTRL extern uint8 nes6502_mem_access; # define NES6502_READ_ACCESS 1 # define NES6502_WRITE_ACCESS 2 # define NES6502_EXE_ACCESS 4 #endif /* #ifdef NES6502_MEM_ACCESS_CTRL */ /* P (flag) register bitmasks */ #define N_FLAG 0x80 #define V_FLAG 0x40 #define R_FLAG 0x20 /* Reserved, always 1 */ #define B_FLAG 0x10 #define D_FLAG 0x08 #define I_FLAG 0x04 #define Z_FLAG 0x02 #define C_FLAG 0x01 /* Vector addresses */ #define NMI_VECTOR 0xFFFA #define RESET_VECTOR 0xFFFC #define IRQ_VECTOR 0xFFFE /* cycle counts for interrupts */ #define INT_CYCLES 7 #define RESET_CYCLES 6 #define NMI_MASK 0x01 #define IRQ_MASK 0x02 /* Stack is located on 6502 page 1 */ #define STACK_OFFSET 0x0100 typedef struct { uint32 min_range, max_range; uint8 (*read_func)(uint32 address); } nes6502_memread; typedef struct { uint32 min_range, max_range; void (*write_func)(uint32 address, uint8 value); } nes6502_memwrite; typedef struct { uint8 * mem_page[NES6502_NUMBANKS]; /* memory page pointers */ #ifdef NES6502_MEM_ACCESS_CTRL uint8 * acc_mem_page[NES6502_NUMBANKS]; /* memory access page pointer */ #endif nes6502_memread *read_handler; nes6502_memwrite *write_handler; int dma_cycles; uint32 pc_reg; uint8 a_reg, p_reg, x_reg, y_reg, s_reg; uint8 int_pending; } nes6502_context; #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* Functions which govern the 6502's execution */ extern void nes6502_init(void); extern void nes6502_reset(void); extern int nes6502_execute(int total_cycles); extern void nes6502_nmi(void); extern void nes6502_irq(void); extern uint8 nes6502_getbyte(uint32 address); extern uint32 nes6502_getcycles(boolean reset_flag); extern void nes6502_setdma(int cycles); #ifdef NES6502_MEM_ACCESS_CTRL extern void nes6502_chk_mem_access(uint8 * access, int flags); #else #define nes6502_chk_mem_access(access,flags) #endif /* Context get/set */ extern void nes6502_setcontext(nes6502_context *cpu); extern void nes6502_getcontext(nes6502_context *cpu); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _NES6502_H_ */ /* ** $Log: nes6502.h,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.4 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/nsf.c0000644000175000017500000006476214647725152015116 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** nsf.c ** ** NSF loading/saving related functions ** $Id: nsf.c,v 1.4 2006/09/26 00:52:17 dgp85 Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "types.h" #include "nsf.h" #include "log.h" #include "nes6502.h" #include "nes_apu.h" #include "vrcvisnd.h" #include "vrc7_snd.h" #include "mmc5_snd.h" #include "fds_snd.h" /* TODO: bleh! should encapsulate in NSF */ #define MAX_ADDRESS_HANDLERS 32 static nes6502_memread nsf_readhandler[MAX_ADDRESS_HANDLERS]; static nes6502_memwrite nsf_writehandler[MAX_ADDRESS_HANDLERS]; static nsf_t *cur_nsf = NULL; static void nsf_setcontext(nsf_t *nsf) { ASSERT(nsf); cur_nsf = nsf; } static uint8 read_mirrored_ram(uint32 address) { nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], NES6502_READ_ACCESS); return cur_nsf->cpu->mem_page[0][address & 0x7FF]; } static void write_mirrored_ram(uint32 address, uint8 value) { nes6502_chk_mem_access(&cur_nsf->cpu->acc_mem_page[0][address & 0x7FF], NES6502_WRITE_ACCESS); cur_nsf->cpu->mem_page[0][address & 0x7FF] = value; } /* can be used for both banked and non-bankswitched NSFs */ static void nsf_bankswitch(uint32 address, uint8 value) { int cpu_page; int roffset; uint8 *offset; cpu_page = address & 0x0F; roffset = -(cur_nsf->load_addr & 0x0FFF) + ((int)value << 12); offset = cur_nsf->data + roffset; nes6502_getcontext(cur_nsf->cpu); cur_nsf->cpu->mem_page[cpu_page] = offset; #ifdef NES6502_MEM_ACCESS_CTRL cur_nsf->cpu->acc_mem_page[cpu_page] = offset + cur_nsf->length; #endif nes6502_setcontext(cur_nsf->cpu); } static nes6502_memread default_readhandler[] = { { 0x0800, 0x1FFF, read_mirrored_ram }, { 0x4000, 0x4017, apu_read }, { -1, -1, NULL } }; static nes6502_memwrite default_writehandler[] = { { 0x0800, 0x1FFF, write_mirrored_ram }, { 0x4000, 0x4017, apu_write }, { 0x5FF6, 0x5FFF, nsf_bankswitch }, { -1, -1, NULL} }; static uint8 invalid_read(uint32 address) { #ifdef NOFRENDO_DEBUG log_printf("filthy NSF read from $%04X\n", address); #else (void)address; #endif /* NOFRENDO_DEBUG */ return 0xFF; } static void invalid_write(uint32 address, uint8 value) { #ifdef NOFRENDO_DEBUG log_printf("filthy NSF tried to write $%02X to $%04X\n", value, address); #else (void)address; (void)value; #endif /* NOFRENDO_DEBUG */ } /* set up the address handlers that the CPU uses */ static void build_address_handlers(nsf_t *nsf) { int count, num_handlers; memset(nsf_readhandler, 0, sizeof(nsf_readhandler)); memset(nsf_writehandler, 0, sizeof(nsf_writehandler)); num_handlers = 0; for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) { if (NULL == default_readhandler[count].read_func) break; memcpy(&nsf_readhandler[num_handlers], &default_readhandler[count], sizeof(nes6502_memread)); } if (nsf->apu->ext) { if (NULL != nsf->apu->ext->mem_read) { for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) { if (NULL == nsf->apu->ext->mem_read[count].read_func) break; memcpy(&nsf_readhandler[num_handlers], &nsf->apu->ext->mem_read[count], sizeof(nes6502_memread)); } } } /* catch-all for bad reads */ nsf_readhandler[num_handlers].min_range = 0x2000; /* min address */ nsf_readhandler[num_handlers].max_range = 0x5BFF; /* max address */ nsf_readhandler[num_handlers].read_func = invalid_read; /* handler */ num_handlers++; nsf_readhandler[num_handlers].min_range = -1; nsf_readhandler[num_handlers].max_range = -1; nsf_readhandler[num_handlers].read_func = NULL; num_handlers++; ASSERT(num_handlers <= MAX_ADDRESS_HANDLERS); num_handlers = 0; for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) { if (NULL == default_writehandler[count].write_func) break; memcpy(&nsf_writehandler[num_handlers], &default_writehandler[count], sizeof(nes6502_memwrite)); } if (nsf->apu->ext) { if (NULL != nsf->apu->ext->mem_write) { for (count = 0; num_handlers < MAX_ADDRESS_HANDLERS; count++, num_handlers++) { if (NULL == nsf->apu->ext->mem_write[count].write_func) break; memcpy(&nsf_writehandler[num_handlers], &nsf->apu->ext->mem_write[count], sizeof(nes6502_memwrite)); } } } /* catch-all for bad writes */ nsf_writehandler[num_handlers].min_range = 0x2000; /* min address */ nsf_writehandler[num_handlers].max_range = 0x5BFF; /* max address */ nsf_writehandler[num_handlers].write_func = invalid_write; /* handler */ num_handlers++; /* protect region at $8000-$FFFF */ nsf_writehandler[num_handlers].min_range = 0x8000; /* min address */ nsf_writehandler[num_handlers].max_range = 0xFFFF; /* max address */ nsf_writehandler[num_handlers].write_func = invalid_write; /* handler */ num_handlers++; nsf_writehandler[num_handlers].min_range = -1; nsf_writehandler[num_handlers].max_range = -1; nsf_writehandler[num_handlers].write_func = NULL; num_handlers++; ASSERT(num_handlers <= MAX_ADDRESS_HANDLERS); } #define NSF_ROUTINE_LOC 0x5000 /* sets up a simple loop that calls the desired routine and spins */ static void nsf_setup_routine(uint32 address, uint8 a_reg, uint8 x_reg) { uint8 *mem; nes6502_getcontext(cur_nsf->cpu); mem = cur_nsf->cpu->mem_page[NSF_ROUTINE_LOC >> 12] + (NSF_ROUTINE_LOC & 0x0FFF); /* our lovely 4-byte 6502 NSF player */ mem[0] = 0x20; /* JSR address */ mem[1] = address & 0xFF; mem[2] = address >> 8; mem[3] = 0xF2; /* JAM (cpu kill op) */ cur_nsf->cpu->pc_reg = NSF_ROUTINE_LOC; cur_nsf->cpu->a_reg = a_reg; cur_nsf->cpu->x_reg = x_reg; cur_nsf->cpu->y_reg = 0; cur_nsf->cpu->s_reg = 0xFF; nes6502_setcontext(cur_nsf->cpu); } /* retrieve any external soundchip driver */ static apuext_t *nsf_getext(nsf_t *nsf) { switch (nsf->ext_sound_type) { case EXT_SOUND_VRCVI: return &vrcvi_ext; case EXT_SOUND_VRCVII: return &vrc7_ext; case EXT_SOUND_FDS: return &fds_ext; case EXT_SOUND_MMC5: return &mmc5_ext; case EXT_SOUND_NAMCO106: case EXT_SOUND_SUNSOFT_FME07: case EXT_SOUND_NONE: default: return NULL; } } static void nsf_inittune(nsf_t *nsf) { uint8 bank, x_reg; uint8 start_bank, num_banks; memset(nsf->cpu->mem_page[0], 0, 0x800); memset(nsf->cpu->mem_page[6], 0, 0x1000); memset(nsf->cpu->mem_page[7], 0, 0x1000); #ifdef NES6502_MEM_ACCESS_CTRL memset(nsf->cpu->acc_mem_page[0], 0, 0x800); memset(nsf->cpu->acc_mem_page[6], 0, 0x1000); memset(nsf->cpu->acc_mem_page[7], 0, 0x1000); memset(nsf->data+nsf->length, 0, nsf->length); #endif nsf->cur_frame = 0; /* nsf->last_access_frame = 0; */ nsf->cur_frame_end = !nsf->song_frames ? 0 : nsf->song_frames[nsf->current_song]; if (nsf->bankswitched) { /* the first hack of the NSF spec! */ if (EXT_SOUND_FDS == nsf->ext_sound_type) { nsf_bankswitch(0x5FF6, nsf->bankswitch_info[6]); nsf_bankswitch(0x5FF7, nsf->bankswitch_info[7]); } for (bank = 0; bank < 8; bank++) nsf_bankswitch(0x5FF8 + bank, nsf->bankswitch_info[bank]); } else { /* not bankswitched, just page in our standard stuff */ ASSERT(nsf->load_addr + nsf->length <= 0x10000); /* avoid ripper filth */ for (bank = 0; bank < 8; bank++) nsf_bankswitch(0x5FF8 + bank, bank); start_bank = nsf->load_addr >> 12; num_banks = ((nsf->load_addr + nsf->length - 1) >> 12) - start_bank + 1; for (bank = 0; bank < num_banks; bank++) nsf_bankswitch(0x5FF0 + start_bank + bank, bank); } /* determine PAL/NTSC compatibility shite */ if (nsf->pal_ntsc_bits & NSF_DEDICATED_PAL) x_reg = 1; else x_reg = 0; /* execute 1 frame or so; let init routine run free */ nsf_setup_routine(nsf->init_addr, (uint8) (nsf->current_song - 1), x_reg); nes6502_execute((int) NES_FRAME_CYCLES); } void nsf_frame(nsf_t *nsf) { // This is how Matthew Conte left it //nsf_setcontext(nsf); /* future expansion =) */ // This was suggested by Arne Morten Kvarving, who says: /* Also, I fixed a bug that prevented Nosefart to play multiple tunes at one time (actually it was just a few missing setcontext calls in the playback routine, it had a nice TODO commented beside it. You had to set the cpu and apu contexts not just the nsf context). it will affect any player that tries to use nosefart to play more than one tune at a time. */ nsf_setcontext(nsf); apu_setcontext(nsf->apu); nes6502_setcontext(nsf->cpu); /* one frame of NES processing */ nsf_setup_routine(nsf->play_addr, 0, 0); nes6502_execute((int) NES_FRAME_CYCLES); ++nsf->cur_frame; #if defined(NES6502_MEM_ACCESS_CTRL) && 0 if (nes6502_mem_access) { uint32 sec = (nsf->last_access_frame + nsf->playback_rate - 1) / nsf->playback_rate; nsf->last_access_frame = nsf->cur_frame; fprintf(stderr,"nsf : memory access [%x] at frame #%u [%u:%02u]\n", nes6502_mem_access, nsf->last_access_frame, sec/60, sec%60); } #endif } /* Deallocate memory */ void nes_shutdown(nsf_t *nsf); void nes_shutdown(nsf_t *nsf) { int i; ASSERT(nsf); if (nsf->cpu) { if (nsf->cpu->mem_page[0]) { free(nsf->cpu->mem_page[0]);/*tracks 1 and 2 of lifeforce hang here.*/ } for (i = 5; i <= 7; i++) { if (nsf->cpu->mem_page[i]) { free(nsf->cpu->mem_page[i]); } } #ifdef NES6502_MEM_ACCESS_CTRL if (nsf->cpu->acc_mem_page[0]) { free(nsf->cpu->acc_mem_page[0]); } for (i = 5; i <= 7; i++) { if (nsf->cpu->acc_mem_page[i]) { free(nsf->cpu->acc_mem_page[i]); } } #endif { void *tmp = nsf->cpu; free(tmp); nsf->cpu = NULL; } } } int nsf_init(void) { nes6502_init(); return 0; } /* Initialize NES CPU, hardware, etc. */ static int nsf_cpuinit(nsf_t *nsf) { int i; nsf->cpu = malloc(sizeof(nes6502_context)); if (NULL == nsf->cpu) return -1; memset(nsf->cpu, 0, sizeof(nes6502_context)); nsf->cpu->mem_page[0] = malloc(0x800); if (NULL == nsf->cpu->mem_page[0]) return -1; /* allocate some space for the NSF "player" MMC5 EXRAM, and WRAM */ for (i = 5; i <= 7; i++) { nsf->cpu->mem_page[i] = malloc(0x1000); if (NULL == nsf->cpu->mem_page[i]) return -1; } #ifdef NES6502_MEM_ACCESS_CTRL nsf->cpu->acc_mem_page[0] = malloc(0x800); if (NULL == nsf->cpu->acc_mem_page[0]) return -1; /* allocate some space for the NSF "player" MMC5 EXRAM, and WRAM */ for (i = 5; i <= 7; i++) { nsf->cpu->acc_mem_page[i] = malloc(0x1000); if (NULL == nsf->cpu->acc_mem_page[i]) return -1; } #endif nsf->cpu->read_handler = nsf_readhandler; nsf->cpu->write_handler = nsf_writehandler; return 0; } static unsigned int nsf_playback_rate(nsf_t *nsf) { if (nsf->pal_ntsc_bits & NSF_DEDICATED_PAL) { if (nsf->pal_speed) nsf->playback_rate = 1000000 / nsf->pal_speed; else nsf->playback_rate = 50; /* 50 Hz */ } else { if (nsf->ntsc_speed) nsf->playback_rate = 1000000 / nsf->ntsc_speed; else nsf->playback_rate = 60; /* 60 Hz */ } return 0; } static void nsf_setup(nsf_t *nsf) { int i; nsf->current_song = nsf->start_song; nsf_playback_rate(nsf); nsf->bankswitched = FALSE; for (i = 0; i < 8; i++) { if (nsf->bankswitch_info[i]) { nsf->bankswitched = TRUE; break; } } } #ifdef HOST_LITTLE_ENDIAN #define SWAP_16(x) (x) #else /* !HOST_LITTLE_ENDIAN */ #define SWAP_16(x) (((uint16) x >> 8) | (((uint16) x & 0xFF) << 8)) #endif /* !HOST_LITTLE_ENDIAN */ /* $$$ ben : find extension. Should be OK with DOS, but not with some * OS like RiscOS ... */ static char * find_ext(char *fn) { char * a, * b, * c; a = strrchr(fn,'.'); b = strrchr(fn,'/'); c = strrchr(fn,'\\'); if (a <= b || a <= c) { a = 0; } return a; } /* $$$ ben : FILE loader */ struct nsf_file_loader_t { struct nsf_loader_t loader; FILE *fp; char * fname; int name_allocated; }; static int nfs_open_file(struct nsf_loader_t *loader) { struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; floader->name_allocated = 0; floader->fp = 0; if (!floader->fname) { return -1; } floader->fp = fopen(floader->fname,"rb"); if (!floader->fp) { char * fname, * ext; ext = find_ext(floader->fname); if (ext) { /* There was an extension, so we do not change it */ return -1; } fname = malloc(strlen(floader->fname) + 5); if (!fname) { return -1; } /* try with .nsf extension. */ strcpy(fname, floader->fname); strcat(fname, ".nsf"); floader->fp = fopen(fname,"rb"); if (!floader->fp) { free(fname); return -1; } floader->fname = fname; floader->name_allocated = 1; } return 0; } static void nfs_close_file(struct nsf_loader_t *loader) { struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; if (floader->fp) { fclose(floader->fp); floader->fp = 0; } if (floader->fname && floader->name_allocated) { free(floader->fname); floader->fname = 0; floader->name_allocated = 0; } } static int nfs_read_file(struct nsf_loader_t *loader, void *data, int n) { struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; int r = fread(data, 1, n, floader->fp); if (r >= 0) { r = n-r; } return r; } static int nfs_length_file(struct nsf_loader_t *loader) { struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; long save, pos; save = ftell(floader->fp); if (save < 0) return 0; if (fseek(floader->fp, 0, SEEK_END) < 0) return 0; pos = ftell(floader->fp); if (fseek(floader->fp, save, SEEK_SET) < 0) return 0; return pos; } static int nfs_skip_file(struct nsf_loader_t *loader, int n) { struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; int r; r = fseek(floader->fp, n, SEEK_CUR); return r; } static const char * nfs_fname_file(struct nsf_loader_t *loader) { struct nsf_file_loader_t * floader = (struct nsf_file_loader_t *)loader; return floader->fname ? floader->fname : ""; } static struct nsf_file_loader_t nsf_file_loader = { { nfs_open_file, nfs_close_file, nfs_read_file, nfs_length_file, nfs_skip_file, nfs_fname_file }, 0,0,0 }; struct nsf_mem_loader_t { struct nsf_loader_t loader; uint8 *data; unsigned long cur; unsigned long len; char fname[32]; }; static int nfs_open_mem(struct nsf_loader_t *loader) { struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; if (!mloader->data) { return -1; } mloader->cur = 0; sprintf(mloader->fname,"", mloader->data, (unsigned int)mloader->len); return 0; } static void nfs_close_mem(struct nsf_loader_t *loader) { struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; mloader->data = 0; mloader->cur = 0; mloader->len = 0; } static int nfs_read_mem(struct nsf_loader_t *loader, void *data, int n) { struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; int rem; if (n <= 0) { return n; } if (!mloader->data) { return -1; } rem = mloader->len - mloader->cur; if (rem > n) { rem = n; } memcpy(data, mloader->data + mloader->cur, rem); mloader->cur += rem; return n - rem; } static int nfs_length_mem(struct nsf_loader_t *loader) { struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; return mloader->len; } static int nfs_skip_mem(struct nsf_loader_t *loader, int n) { struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; unsigned long goal = mloader->cur + n; mloader->cur = (goal > mloader->len) ? mloader->len : goal; return goal - mloader->cur; } /* static const char * nfs_fname_mem(struct nsf_loader_t *loader) { struct nsf_mem_loader_t * mloader = (struct nsf_mem_loader_t *)loader; return mloader->fname; } */ static struct nsf_mem_loader_t nsf_mem_loader = { .loader = { nfs_open_mem, nfs_close_mem, nfs_read_mem, nfs_length_mem, nfs_skip_mem, 0 } }; nsf_t * nsf_load_extended(struct nsf_loader_t * loader) { nsf_t *temp_nsf = 0; int length; char id[6]; struct { uint8 magic[4]; /* always "NESM" */ uint8 type[4]; /* defines extension type */ uint8 size[4]; /* extension data size (this struct include) */ } nsf_file_ext; /* no loader ! */ if (!loader) { return NULL; } /* Open the "file" */ if (loader->open(loader) < 0) { return NULL; } /* Get file size, and exit if there is not enough data for NSF header * and more since it does not make sens to have header without data. */ length = loader->length(loader); /* For version 2, we do not need file length. just check error later. */ #if 0 if (length <= NSF_HEADER_SIZE) { log_printf("nsf : [%s] not an NSF format file\n", loader->fname(loader)); goto error; } #endif /* Read magic */ if (loader->read(loader, id, 5)) { log_printf("nsf : [%s] error reading magic number\n", loader->fname(loader)); goto error; } /* Check magic */ if (memcmp(id, NSF_MAGIC, 5)) { log_printf("nsf : [%s] is not an NSF format file\n", loader->fname(loader)); goto error; } /* $$$ ben : Now the file should be an NSF, we can start allocating. * first : the nsf struct */ temp_nsf = malloc(sizeof(nsf_t)); if (NULL == temp_nsf) { log_printf("nsf : [%s] error allocating nsf header\n", loader->fname(loader)); goto error; } /* $$$ ben : safety net */ memset(temp_nsf,0,sizeof(nsf_t)); /* Copy magic ID */ memcpy(temp_nsf,id,5); /* Read header (without MAGIC) */ if (loader->read(loader, (int8 *)temp_nsf+5, NSF_HEADER_SIZE - 5)) { log_printf("nsf : [%s] error reading nsf header\n", loader->fname(loader)); goto error; } /* fixup endianness */ temp_nsf->load_addr = SWAP_16(temp_nsf->load_addr); temp_nsf->init_addr = SWAP_16(temp_nsf->init_addr); temp_nsf->play_addr = SWAP_16(temp_nsf->play_addr); temp_nsf->ntsc_speed = SWAP_16(temp_nsf->ntsc_speed); temp_nsf->pal_speed = SWAP_16(temp_nsf->pal_speed); /* we're now at position 80h */ /* Here comes the specific codes for spec version 2 */ temp_nsf->length = 0; if (temp_nsf->version > 1) { /* Get specified data size in reserved field (3 bytes). */ temp_nsf->length = 0 + temp_nsf->reserved[0] + (temp_nsf->reserved[1]<<8) + (temp_nsf->reserved[2]<<16); } /* no specified size : try to guess with file length. */ if (!temp_nsf->length) { temp_nsf->length = length - NSF_HEADER_SIZE; } if (temp_nsf->length <= 0) { log_printf("nsf : [%s] not an NSF format file (missing data)\n", loader->fname(loader)); goto error; } /* Allocate NSF space, and load it up! */ { int len = temp_nsf->length; #ifdef NES6502_MEM_ACCESS_CTRL /* $$$ twice memory for access control shadow mem. */ len <<= 1; #endif temp_nsf->data = malloc(len); } if (NULL == temp_nsf->data) { log_printf("nsf : [%s] error allocating nsf data\n", loader->fname(loader)); goto error; } /* Read data */ if (loader->read(loader, temp_nsf->data, temp_nsf->length)) { log_printf("nsf : [%s] error reading NSF data\n", loader->fname(loader)); goto error; } /* Here comes the second part of spec > 1 : get extension */ while (!loader->read(loader, &nsf_file_ext, sizeof(nsf_file_ext)) && !memcmp(nsf_file_ext.magic,id,4)) { /* Got a NESM extension here. Checks for known extension type : * right now, the only extension is "TIME" which give songs length. * in frames. */ int size; size = 0 + nsf_file_ext.size[0] + (nsf_file_ext.size[1] << 8) + (nsf_file_ext.size[2] << 16) + (nsf_file_ext.size[3] << 24); if (size < (int)sizeof(nsf_file_ext)) { log_printf("nsf : [%s] corrupt extension size (%d)\n", loader->fname(loader), size); /* Not a fatal error here. Just skip extension loading. */ break; } size -= sizeof(nsf_file_ext); if (!temp_nsf->song_frames && !memcmp(nsf_file_ext.type,"TIME", 4) && !(size & 3) && (size >= 2*4) && (size <= 256*4)) { uint8 tmp_time[256][4]; int tsongs = size >> 2; int i; int songs = temp_nsf->num_songs; /* Add 1 for 0 which contains total time for all songs. */ ++songs; if (loader->read(loader, tmp_time, size)) { log_printf("nsf : [%s] missing extension data\n", loader->fname(loader)); /* Not a fatal error here. Just skip extension loading. */ break; } /* Alloc song_frames for songs (not tsongs). */ temp_nsf->song_frames = malloc(sizeof(*temp_nsf->song_frames) * songs); if (!temp_nsf->song_frames) { log_printf("nsf : [%s] extension alloc failed\n", loader->fname(loader)); /* Not a fatal error here. Just skip extension loading. */ break; } if (tsongs > songs) { tsongs = songs; } /* Copy time info. */ for (i=0; isong_frames[i] = 0 | tmp_time[i][0] | (tmp_time[i][1] << 8) | (tmp_time[i][2] << 16) | (tmp_time[i][2] << 24); } /* Clear missing (safety net). */ for (; isong_frames[i] = 0; } } else if (loader->skip(loader, size)) { log_printf("nsf : [%s] extension skip failed\n", loader->fname(loader)); /* Not a fatal error here. Just skip extension loading. */ break; } } /* Close "file" */ loader->close(loader); loader = 0; /* Set up some variables */ nsf_setup(temp_nsf); temp_nsf->apu = NULL; /* just make sure */ if (nsf_cpuinit(temp_nsf)) { log_printf("nsf : error cpu init\n"); goto error; } return temp_nsf; /* $$$ ben : some people tell that goto are not clean. I am not agree with * them. In most case, it allow to avoid code duplications, which are as * most people know a source of error... Here we are sure of being clean */ error: if (loader) { loader->close(loader); } if (temp_nsf) { nsf_free(&temp_nsf); } return 0; } /* Load a ROM image into memory */ nsf_t *nsf_load(const char *filename, void *source, int length) { struct nsf_loader_t * loader = 0; /* $$$ ben : new loader */ if (filename) { nsf_file_loader.fname = (char *)filename; loader = &nsf_file_loader.loader; } else { nsf_mem_loader.data = source; nsf_mem_loader.len = length; nsf_mem_loader.fname[0] = 0; loader = &nsf_mem_loader.loader; } return nsf_load_extended(loader); } /* Free an NSF */ void nsf_free(nsf_t **pnsf) { nsf_t *nsf; if (!pnsf) { return; } nsf = *pnsf; /* $$$ ben : Don't see why passing a pointer to pointer * is not to clear it :) */ *pnsf = 0; if (nsf) { if (nsf->apu) apu_destroy(nsf->apu); nes_shutdown(nsf); if (nsf->data) { void *tmp = nsf->data; free(tmp); nsf->data = NULL; } if (nsf->song_frames) { void *tmp = nsf->song_frames; free (tmp); nsf->song_frames = NULL; } free(nsf); } } int nsf_setchan(nsf_t *nsf, int chan, boolean enabled) { if (!nsf) return -1; nsf_setcontext(nsf); return apu_setchan(chan, enabled); } int nsf_playtrack(nsf_t *nsf, int track, int sample_rate, int sample_bits, boolean stereo) { if (!nsf) { return -1; } /* make this NSF the current context */ nsf_setcontext(nsf); /* create the APU */ if (nsf->apu) { apu_destroy(nsf->apu); } nsf->apu = apu_create(sample_rate, nsf->playback_rate, sample_bits, stereo); if (NULL == nsf->apu) { /* $$$ ben : from my point of view this is not clean. Function should * never destroy object it has not created... */ /* nsf_free(&nsf); */ return -1; } apu_setext(nsf->apu, nsf_getext(nsf)); /* go ahead and init all the read/write handlers */ build_address_handlers(nsf); /* convenience? */ nsf->process = nsf->apu->process; nes6502_setcontext(nsf->cpu); if (track > nsf->num_songs) track = nsf->num_songs; else if (track < 1) track = 1; nsf->current_song = track; apu_reset(); nsf_inittune(nsf); return nsf->current_song; } int nsf_setfilter(nsf_t *nsf, int filter_type) { if (!nsf) { return -1; } nsf_setcontext(nsf); return apu_setfilter(filter_type); } /* ** $Log: nsf.c,v $ ** Revision 1.3 2003/05/01 22:34:20 benjihan ** New NSF plugin ** ** Revision 1.2 2003/04/09 14:50:32 ben ** Clean NSF api. ** ** Revision 1.1 2003/04/08 20:53:00 ben ** Adding more files... ** ** Revision 1.14 2000/07/05 14:54:45 matt ** fix for naughty Crystalis rip ** ** Revision 1.13 2000/07/04 04:59:38 matt ** removed DOS-specific stuff, fixed bug in address handlers ** ** Revision 1.12 2000/07/03 02:19:36 matt ** dynamic address range handlers, cleaner and faster ** ** Revision 1.11 2000/06/23 03:27:58 matt ** cleaned up external sound inteface ** ** Revision 1.10 2000/06/20 20:42:47 matt ** accuracy changes ** ** Revision 1.9 2000/06/20 00:05:58 matt ** changed to driver-based external sound generation ** ** Revision 1.8 2000/06/13 03:51:54 matt ** update API to take freq/sample data on nsf_playtrack ** ** Revision 1.7 2000/06/12 03:57:14 matt ** more robust checking for winamp plugin ** ** Revision 1.6 2000/06/12 01:13:00 matt ** added CPU/APU as members of the nsf struct ** ** Revision 1.5 2000/06/11 16:09:21 matt ** nsf_free is more robust ** ** Revision 1.4 2000/06/09 15:12:26 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/memguard.c0000644000175000017500000002533114647725152016116 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** memguard.c ** ** memory allocation wrapper routines ** ** NOTE: based on code (c) 1998 the Retrocade group ** $Id: memguard.c,v 1.4 2004/02/20 19:53:39 komadori Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "types.h" /* undefine macro definitions, so we get real calls */ #undef malloc #undef free #include #include #if HAVE_INTTYPES_H # include #else # if HAVE_STDINT_H # include # endif #endif #include "memguard.h" #include "log.h" /* Maximum number of allocated blocks at any one time */ #define MAX_BLOCKS 16384 /* Memory block structure */ typedef struct memblock_s { void *block_addr; int block_size; char *file_name; int line_num; } memblock_t; boolean mem_debug = TRUE; /* debugging flag */ #ifdef NOFRENDO_DEBUG static int mem_blockcount = 0; /* allocated block count */ static memblock_t *mem_record = NULL; #define GUARD_STRING "GgUuAaRrDdSsTtRrIiNnGgBbLlOoCcKk" #define GUARD_LENGTH 64 /* before and after allocated block */ /* ** Check the memory guard to make sure out of bounds writes have not ** occurred. */ static boolean mem_checkguardblock(void *data, int guard_size) { uint8 *orig, *chk, *blk; int i, alloc_size; /* get the original pointer */ orig = (((uint8 *) data) - guard_size); /* get the size */ alloc_size = *((uint32 *) orig); /* now skip past the size */ blk = orig + sizeof(uint32); /* check leading guard string */ chk = GUARD_STRING; for (i = sizeof(uint32); i < guard_size; i++) { if (0 == *chk) chk = GUARD_STRING; if (*blk != *chk) return FALSE; chk++; blk++; } /* check end of block */ chk = GUARD_STRING; blk = ((uint8 *) data) + alloc_size; for (i = 0; i < guard_size; i++) { if (0 == *chk) chk = GUARD_STRING; if (*blk != *chk) return FALSE; chk++; blk++; } /* we're okay! */ return TRUE; } /* free a guard block */ static void mem_freeguardblock(void *data, int guard_size) { uint8 *orig = (((uint8 *) data) - guard_size); free(orig); } /* fill in the memory guard, advance the pointer to the 'real' memory */ static void *mem_guardblock(int alloc_size, int guard_size) { void *orig; uint8 *blk, *chk; int i; /* allocate memory */ orig = calloc(alloc_size + (guard_size * 2), 1); if (NULL == orig) return NULL; blk = ((uint8 *) orig); /* store the size of the newly allocated block*/ *((uint32 *) blk) = alloc_size; /* skip past the size */ blk += sizeof(uint32); /* put guard string at beginning of block */ chk = GUARD_STRING; for (i = sizeof(uint32); i < guard_size; i++) { if (0 == *chk) chk = GUARD_STRING; *blk++ = *chk++; } /* check end of block */ chk = GUARD_STRING; blk = guard_size + (uint8 *) orig + alloc_size; for (i = 0; i < guard_size; i++) { if (0 == *chk) chk = GUARD_STRING; *blk++ = *chk++; } return (void *) (guard_size + (uint8 *) orig); } /* Allocate a bunch of memory to keep track of all memory blocks */ static void mem_init(void) { if (mem_record) { free(mem_record); mem_record = NULL; } mem_record = calloc(MAX_BLOCKS * sizeof(memblock_t), 1); ASSERT(mem_record); } /* add a block of memory to the master record */ static void mem_addblock(void *data, int block_size, char *file, int line) { int i; for (i = 0; i < MAX_BLOCKS; i++) { if (NULL == mem_record[i].block_addr) { mem_record[i].block_addr = data; mem_record[i].block_size = block_size; mem_record[i].file_name = file; mem_record[i].line_num = line; return; } } ASSERT_MSG("out of memory blocks."); } /* find an entry in the block record and delete it */ static void mem_deleteblock(void *data, char *file, int line) { int i; char fail[256]; for (i = 0; i < MAX_BLOCKS; i++) { if (data == mem_record[i].block_addr) { if (FALSE == mem_checkguardblock(mem_record[i].block_addr, GUARD_LENGTH)) { sprintf(fail, "mem_deleteblock 0x%08X at line %d of %s -- block corrupt", (uint32) data, line, file); ASSERT_MSG(fail); } memset(&mem_record[i], 0, sizeof(memblock_t)); return; } } sprintf(fail, "mem_deleteblock 0x%08X at line %d of %s -- block not found", (uint32) data, line, file); ASSERT_MSG(fail); } #endif /* NOFRENDO_DEBUG */ /* allocates memory and clears it */ #ifdef NOFRENDO_DEBUG void *_my_malloc(int size, char *file, int line) #else void *_my_malloc(int size) #endif { void *temp; char fail[256]; #ifdef NOFRENDO_DEBUG if (NULL == mem_record && FALSE != mem_debug) mem_init(); if (FALSE != mem_debug) temp = mem_guardblock(size, GUARD_LENGTH); else #endif /* NOFRENDO_DEBUG */ temp = calloc(sizeof(uint8), size); if (NULL == temp) { #ifdef NOFRENDO_DEBUG sprintf(fail, "malloc: out of memory at line %d of %s. block size: %d\n", line, file, size); #else sprintf(fail, "malloc: out of memory. block size: %d\n", size); #endif ASSERT_MSG(fail); } #ifdef NOFRENDO_DEBUG if (FALSE != mem_debug) mem_addblock(temp, size, file, line); mem_blockcount++; #endif return temp; } /* free a pointer allocated with my_malloc */ #ifdef NOFRENDO_DEBUG void _my_free(void **data, char *file, int line) { char fail[256]; if (NULL == data || NULL == *data || ((uintptr_t)-1) == (uintptr_t) *data || ((uintptr_t)-1) == (uintptr_t) data) { #ifdef NOFRENDO_DEBUG sprintf(fail, "free: attempted to free NULL pointer at line %d of %s\n", line, file); #else sprintf(fail, "free: attempted to free NULL pointer.\n"); #endif ASSERT_MSG(fail); } #ifdef NOFRENDO_DEBUG /* if this is true, we are in REAL trouble */ if (0 == mem_blockcount) { ASSERT_MSG("free: attempted to free memory when no blocks available"); } if (FALSE != mem_debug) mem_deleteblock(*data, file, line); mem_blockcount--; /* dec our block count */ if (FALSE != mem_debug) mem_freeguardblock(*data, GUARD_LENGTH); else #endif /* NOFRENDO_DEBUG */ free(*data); *data = NULL; /* NULL our source */ } #else void _my_free(void *data) { if (NULL == data || ((uintptr_t)-1) == (uintptr_t) data) { ASSERT_MSG("free: attempted to free NULL pointer.\n"); } free(data); } #endif /* check for orphaned memory handles */ void mem_checkleaks(void) { #ifdef NOFRENDO_DEBUG int i; if (FALSE == mem_debug) return; if (mem_blockcount) { log_printf("memory leak - %d unfreed block%s\n\n", mem_blockcount, mem_blockcount == 1 ? "" : "s"); for (i = 0; i < MAX_BLOCKS; i++) { if (mem_record[i].block_addr) { log_printf("addr: 0x%08X, size: %d, line %d of %s%s\n", (uint32) mem_record[i].block_addr, mem_record[i].block_size, mem_record[i].line_num, mem_record[i].file_name, (FALSE == mem_checkguardblock(mem_record[i].block_addr, GUARD_LENGTH)) ? " -- block corrupt" : ""); } } } else log_printf("no memory leaks\n"); #endif } void mem_checkblocks(void) { #ifdef NOFRENDO_DEBUG int i; if (FALSE == mem_debug) return; for (i = 0; i < MAX_BLOCKS; i++) { if (mem_record[i].block_addr) { if (FALSE == mem_checkguardblock(mem_record[i].block_addr, GUARD_LENGTH)) { log_printf("addr: 0x%08X, size: %d, line %d of %s -- block corrupt\n", (uint32) mem_record[i].block_addr, mem_record[i].block_size, mem_record[i].line_num, mem_record[i].file_name); } } } #endif /* NOFRENDO_DEBUG */ } /* ** $Log: memguard.c,v $ ** Revision 1.4 2004/02/20 19:53:39 komadori ** Fixed detection of linux framebuffer support. Included xineutils.h in dsputil_mlib.c and added to diff_to_ffmpeg_cvs.txt. Fixed function prototype in dsputil_mlib.c (should be sent back to ffmpeg-dev at some point). Fixed includes in nosefart. Fixed nested comments and includes in goom. ** ** Revision 1.3 2004/02/19 02:50:25 rockyb ** Mandrake patches from ** http://cvs.mandrakesoft.com/cgi-bin/cvsweb.cgi/SPECS/xine-lib/ ** via Goetz Waschk who reports: ** ** The amd64 patch (xine-lib-1-rc0a-amd64.patch) sets some conservative ** CFLAGS for amd64, ** ** the lib64 patch (xine-lib-1-rc0a-lib64.patch) replaces hardcoded ** /lib to support the lib64 library dir on amd64, ** ** the directfb patch (xine-lib-1-rc2-no-directfb.patch) adds a ** configure option to disable directfb, ** ** the linuxfb patch (xine-lib-1-rc3a-no-linuxfb.patch) does the same ** for linux framebuffer and ** ** the 64bit fixes patch (xine-lib-1-rc3-64bit-fixes.patch) doesn't ** apply at the moment against the CVS -- demux_ogg.c was not applied. ** it includes some 64 bit pointer and other fixes for 64bit architectures. ** from Gwenole Beauchesne ** ** I haven't tested other than apply and compile. ** ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.8 2000/06/26 04:54:48 matt ** simplified and made more robust ** ** Revision 1.7 2000/06/12 01:11:41 matt ** cleaned up some error output for win32 ** ** Revision 1.6 2000/06/09 15:12:25 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/fmopl.h0000644000175000017500000001424614647725152015442 0ustar meme#ifndef __FMOPL_H_ #define __FMOPL_H_ #define HAS_YM3812 1 typedef signed short int FMSAMPLE; #define BUILD_YM3812 (HAS_YM3812) #define BUILD_YM3526 (HAS_YM3526) #define BUILD_Y8950 (HAS_Y8950) /* compiler dependence */ #ifndef OSD_CPU_H #define OSD_CPU_H typedef unsigned char UINT8; /* unsigned 8bit */ typedef unsigned short UINT16; /* unsigned 16bit */ typedef unsigned int UINT32; /* unsigned 32bit */ typedef signed char INT8; /* signed 8bit */ typedef signed short INT16; /* signed 16bit */ typedef signed int INT32; /* signed 32bit */ #endif #if BUILD_Y8950 #include "ymdeltat.h" #endif typedef void (*OPL_TIMERHANDLER)(int channel,double interval_Sec); typedef void (*OPL_IRQHANDLER)(int param,int irq); typedef void (*OPL_UPDATEHANDLER)(int param,int min_interval_us); typedef void (*OPL_PORTHANDLER_W)(int param,unsigned char data); typedef unsigned char (*OPL_PORTHANDLER_R)(int param); /* !!!!! here is private section , do not access there member direct !!!!! */ #define OPL_TYPE_WAVESEL 0x01 /* waveform select */ #define OPL_TYPE_ADPCM 0x02 /* DELTA-T ADPCM unit */ #define OPL_TYPE_KEYBOARD 0x04 /* keyboard interface */ #define OPL_TYPE_IO 0x08 /* I/O port */ /* ---------- OPL one of slot ---------- */ typedef struct fm_opl_slot { INT32 TL; /* total level :TL << 8 */ INT32 TLL; /* adjusted now TL */ UINT8 KSR; /* key scale rate :(shift down bit) */ INT32 *AR; /* attack rate :&AR_TABLE[AR<<2] */ INT32 *DR; /* decay rate :&DR_TALBE[DR<<2] */ INT32 SL; /* sustin level :SL_TALBE[SL] */ INT32 *RR; /* release rate :&DR_TABLE[RR<<2] */ UINT8 ksl; /* keyscale level :(shift down bits) */ UINT8 ksr; /* key scale rate :kcode>>KSR */ UINT32 mul; /* multiple :ML_TABLE[ML] */ UINT32 Cnt; /* frequency count : */ UINT32 Incr; /* frequency step : */ /* envelope generator state */ UINT8 eg_typ; /* envelope type flag */ UINT8 evm; /* envelope phase */ INT32 evc; /* envelope counter */ INT32 eve; /* envelope counter end point */ INT32 evs; /* envelope counter step */ INT32 evsa; /* envelope step for AR :AR[ksr] */ INT32 evsd; /* envelope step for DR :DR[ksr] */ INT32 evsr; /* envelope step for RR :RR[ksr] */ /* LFO */ UINT8 ams; /* ams flag */ UINT8 vib; /* vibrate flag */ /* wave selector */ INT32 **wavetable; }OPL_SLOT; /* ---------- OPL one of channel ---------- */ typedef struct fm_opl_channel { OPL_SLOT SLOT[2]; UINT8 CON; /* connection type */ UINT8 FB; /* feed back :(shift down bit) */ INT32 *connect1; /* slot1 output pointer */ INT32 *connect2; /* slot2 output pointer */ INT32 op1_out[2]; /* slot1 output for selfeedback */ /* phase generator state */ UINT32 block_fnum; /* block+fnum : */ UINT8 kcode; /* key code : KeyScaleCode */ UINT32 fc; /* Freq. Increment base */ UINT32 ksl_base; /* KeyScaleLevel Base step */ UINT8 keyon; /* key on/off flag */ } OPL_CH; /* OPL state */ typedef struct fm_opl_f { UINT8 type; /* chip type */ int clock; /* master clock (Hz) */ int rate; /* sampling rate (Hz) */ double freqbase; /* frequency base */ double TimerBase; /* Timer base time (==sampling time) */ UINT8 address; /* address register */ UINT8 status; /* status flag */ UINT8 statusmask; /* status mask */ UINT32 mode; /* Reg.08 : CSM , notesel,etc. */ /* Timer */ int T[2]; /* timer counter */ UINT8 st[2]; /* timer enable */ /* FM channel slots */ OPL_CH *P_CH; /* pointer of CH */ int max_ch; /* maximum channel */ /* Rythm sention */ UINT8 rythm; /* Rythm mode , key flag */ #if BUILD_Y8950 /* Delta-T ADPCM unit (Y8950) */ YM_DELTAT *deltat; /* DELTA-T ADPCM */ #endif /* Keyboard / I/O interface unit (Y8950) */ UINT8 portDirection; UINT8 portLatch; OPL_PORTHANDLER_R porthandler_r; OPL_PORTHANDLER_W porthandler_w; int port_param; OPL_PORTHANDLER_R keyboardhandler_r; OPL_PORTHANDLER_W keyboardhandler_w; int keyboard_param; /* time tables */ INT32 AR_TABLE[76]; /* atttack rate tables */ INT32 DR_TABLE[76]; /* decay rate tables */ UINT32 FN_TABLE[1024]; /* fnumber -> increment counter */ /* LFO */ INT32 *ams_table; INT32 *vib_table; INT32 amsCnt; INT32 amsIncr; INT32 vibCnt; INT32 vibIncr; /* wave selector enable flag */ UINT8 wavesel; /* external event callback handler */ OPL_TIMERHANDLER TimerHandler; /* TIMER handler */ int TimerParam; /* TIMER parameter */ OPL_IRQHANDLER IRQHandler; /* IRQ handler */ int IRQParam; /* IRQ parameter */ OPL_UPDATEHANDLER UpdateHandler; /* stream update handler */ int UpdateParam; /* stream update parameter */ } FM_OPL; /* ---------- Generic interface section ---------- */ #define OPL_TYPE_YM3526 (0) #define OPL_TYPE_YM3812 (OPL_TYPE_WAVESEL) #define OPL_TYPE_Y8950 (OPL_TYPE_ADPCM|OPL_TYPE_KEYBOARD|OPL_TYPE_IO) FM_OPL *OPLCreate(int type, int clock, int rate); void OPLDestroy(FM_OPL *OPL); void OPLSetTimerHandler(FM_OPL *OPL,OPL_TIMERHANDLER TimerHandler,int channelOffset); void OPLSetIRQHandler(FM_OPL *OPL,OPL_IRQHANDLER IRQHandler,int param); void OPLSetUpdateHandler(FM_OPL *OPL,OPL_UPDATEHANDLER UpdateHandler,int param); /* Y8950 port handlers */ void OPLSetPortHandler(FM_OPL *OPL,OPL_PORTHANDLER_W PortHandler_w,OPL_PORTHANDLER_R PortHandler_r,int param); void OPLSetKeyboardHandler(FM_OPL *OPL,OPL_PORTHANDLER_W KeyboardHandler_w,OPL_PORTHANDLER_R KeyboardHandler_r,int param); void OPLResetChip(FM_OPL *OPL); int OPLWrite(FM_OPL *OPL,int a,int v); unsigned char OPLRead(FM_OPL *OPL,int a); int OPLTimerOver(FM_OPL *OPL,int c); /* YM3626/YM3812 local section */ void YM3812UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); void Y8950UpdateOne(FM_OPL *OPL, INT16 *buffer, int length); #endif xine-lib-1.2/contrib/nosefart/vrc7_snd.c0000644000175000017500000003003414647725152016036 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** vrc7_snd.c ** ** VRCVII sound hardware emulation ** Thanks to Charles MacDonald (cgfm2@hooked.net) for donating code. ** $Id: vrc7_snd.c,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "types.h" #include "vrc7_snd.h" #include "fmopl.h" static int buflen; static int16 *buffer; #define OPL_WRITE(opl, r, d) \ { \ OPLWrite((opl)->ym3812, 0, (r)); \ OPLWrite((opl)->ym3812, 1, (d)); \ } static vrc7_t vrc7; /* Fixed instrument settings, from MAME's YM2413 emulation */ /* This might need some tweaking... */ unsigned char table[16][11] = { /* 20 23 40 43 60 63 80 83 E0 E3 C0 */ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* MAME */ { 0x01, 0x22, 0x23, 0x07, 0xF0, 0xF0, 0x07, 0x18, 0x00, 0x00, 0x00 }, /* Violin */ { 0x23, 0x01, 0x68, 0x05, 0xF2, 0x74, 0x6C, 0x89, 0x00, 0x00, 0x00 }, /* Acoustic Guitar(steel) */ { 0x13, 0x11, 0x25, 0x00, 0xD2, 0xB2, 0xF4, 0xF4, 0x00, 0x00, 0x00 }, /* Acoustic Grand */ { 0x22, 0x21, 0x1B, 0x05, 0xC0, 0xA1, 0x18, 0x08, 0x00, 0x00, 0x00 }, /* Flute */ { 0x22, 0x21, 0x2C, 0x03, 0xD2, 0xA1, 0x18, 0x57, 0x00, 0x00, 0x00 }, /* Clarinet */ { 0x01, 0x22, 0xBA, 0x01, 0xF1, 0xF1, 0x1E, 0x04, 0x00, 0x00, 0x00 }, /* Oboe */ { 0x21, 0x21, 0x28, 0x06, 0xF1, 0xF1, 0x6B, 0x3E, 0x00, 0x00, 0x00 }, /* Trumpet */ { 0x27, 0x21, 0x60, 0x00, 0xF0, 0xF0, 0x0D, 0x0F, 0x00, 0x00, 0x00 }, /* Church Organ */ { 0x20, 0x21, 0x2B, 0x06, 0x85, 0xF1, 0x6D, 0x89, 0x00, 0x00, 0x00 }, /* French Horn */ { 0x01, 0x21, 0xBF, 0x02, 0x53, 0x62, 0x5F, 0xAE, 0x01, 0x00, 0x00 }, /* Synth Voice */ { 0x23, 0x21, 0x70, 0x07, 0xD4, 0xA3, 0x4E, 0x64, 0x01, 0x00, 0x00 }, /* Harpsichord */ { 0x2B, 0x21, 0xA4, 0x07, 0xF6, 0x93, 0x5C, 0x4D, 0x00, 0x00, 0x00 }, /* Vibraphone */ { 0x21, 0x23, 0xAD, 0x07, 0x77, 0xF1, 0x18, 0x37, 0x00, 0x00, 0x00 }, /* Synth Bass 1 */ { 0x21, 0x21, 0x2A, 0x03, 0xF3, 0xE2, 0x29, 0x46, 0x00, 0x00, 0x00 }, /* Acoustic Bass */ { 0x21, 0x23, 0x37, 0x03, 0xF3, 0xE2, 0x29, 0x46, 0x00, 0x00, 0x00 }, /* Electric Guitar(clean) */ #if 0 /* Horton, try 1 */ { 0x05, 0x03, 0x10, 0x06, 0x74, 0xA1, 0x13, 0xF4, 0x00, 0x00, 0x00 }, { 0x05, 0x01, 0x16, 0x00, 0xF9, 0xA2, 0x15, 0xF5, 0x00, 0x00, 0x00 }, { 0x01, 0x41, 0x11, 0x00, 0xA0, 0xA0, 0x83, 0x95, 0x00, 0x00, 0x00 }, { 0x01, 0x41, 0x17, 0x00, 0x60, 0xF0, 0x83, 0x95, 0x00, 0x00, 0x00 }, { 0x24, 0x41, 0x1F, 0x00, 0x50, 0xB0, 0x94, 0x94, 0x00, 0x00, 0x00 }, { 0x05, 0x01, 0x0B, 0x04, 0x65, 0xA0, 0x54, 0x95, 0x00, 0x00, 0x00 }, { 0x11, 0x41, 0x0E, 0x04, 0x70, 0xC7, 0x13, 0x10, 0x00, 0x00, 0x00 }, { 0x02, 0x44, 0x16, 0x06, 0xE0, 0xE0, 0x31, 0x35, 0x00, 0x00, 0x00 }, { 0x48, 0x22, 0x22, 0x07, 0x50, 0xA1, 0xA5, 0xF4, 0x00, 0x00, 0x00 }, { 0x05, 0xA1, 0x18, 0x00, 0xA2, 0xA2, 0xF5, 0xF5, 0x00, 0x00, 0x00 }, { 0x07, 0x81, 0x2B, 0x05, 0xA5, 0xA5, 0x03, 0x03, 0x00, 0x00, 0x00 }, { 0x01, 0x41, 0x08, 0x08, 0xA0, 0xA0, 0x83, 0x95, 0x00, 0x00, 0x00 }, { 0x21, 0x61, 0x12, 0x00, 0x93, 0x92, 0x74, 0x75, 0x00, 0x00, 0x00 }, { 0x21, 0x62, 0x21, 0x00, 0x84, 0x85, 0x34, 0x15, 0x00, 0x00, 0x00 }, { 0x21, 0x62, 0x0E, 0x00, 0xA1, 0xA0, 0x34, 0x15, 0x00, 0x00, 0x00 }, #endif #if 0 /* Horton try 2 */ { 0x31, 0x22, 0x23, 0x07, 0xF0, 0xF0, 0xE8, 0xF7, 0x00, 0x00, 0x00 }, { 0x03, 0x31, 0x68, 0x05, 0xF2, 0x74, 0x79, 0x9C, 0x00, 0x00, 0x00 }, { 0x01, 0x51, 0x72, 0x04, 0xF1, 0xD3, 0x9D, 0x8B, 0x00, 0x00, 0x00 }, { 0x22, 0x61, 0x1B, 0x05, 0xC0, 0xA1, 0xF8, 0xE8, 0x00, 0x00, 0x00 }, { 0x22, 0x61, 0x2C, 0x03, 0xD2, 0xA1, 0xA7, 0xE8, 0x00, 0x00, 0x00 }, { 0x31, 0x22, 0xFA, 0x01, 0xF1, 0xF1, 0xF4, 0xEE, 0x00, 0x00, 0x00 }, { 0x21, 0x61, 0x28, 0x06, 0xF1, 0xF1, 0xCE, 0x9B, 0x00, 0x00, 0x00 }, { 0x27, 0x61, 0x60, 0x00, 0xF0, 0xF0, 0xFF, 0xFD, 0x00, 0x00, 0x00 }, { 0x60, 0x21, 0x2B, 0x06, 0x85, 0xF1, 0x79, 0x9D, 0x00, 0x00, 0x00 }, { 0x31, 0xA1, 0xFF, 0x0A, 0x53, 0x62, 0x5E, 0xAF, 0x00, 0x00, 0x00 }, { 0x03, 0xA1, 0x70, 0x0F, 0xD4, 0xA3, 0x94, 0xBE, 0x00, 0x00, 0x00 }, { 0x2B, 0x61, 0xE4, 0x07, 0xF6, 0x93, 0xBD, 0xAC, 0x00, 0x00, 0x00 }, { 0x21, 0x63, 0xED, 0x07, 0x77, 0xF1, 0xC7, 0xE8, 0x00, 0x00, 0x00 }, { 0x21, 0x61, 0x2A, 0x03, 0xF3, 0xE2, 0xB6, 0xD9, 0x00, 0x00, 0x00 }, { 0x21, 0x63, 0x37, 0x03, 0xF3, 0xE2, 0xB6, 0xD9, 0x00, 0x00, 0x00 }, #endif }; static void vrc7_reset(void) { int n; /* Point to current VRC7 context */ vrc7_t *opll = &vrc7; /* Clear all YM3812 registers */ for (n = 0; n < 0x100; n++) OPL_WRITE(opll, n, 0x00); /* Turn off rhythm mode and key-on bits */ OPL_WRITE(opll, 0xBD, 0xC0); /* Enable waveform select */ OPL_WRITE(opll, 0x01, 0x20); } static void vrc7_init(void) { vrc7.ym3812 = OPLCreate(OPL_TYPE_YM3812, 3579545, apu_getcontext()->sample_rate); ASSERT(vrc7.ym3812); buflen = apu_getcontext()->num_samples; buffer = malloc(buflen * 2); ASSERT(buffer); vrc7_reset(); } static void vrc7_shutdown(void) { vrc7_reset(); OPLDestroy(vrc7.ym3812); free(buffer); } /* channel (0-9), instrument (0-F), volume (0-3F, YM3812 format) */ static void load_instrument(uint8 ch, uint8 inst, uint8 vol) { /* Point to current VRC7 context */ vrc7_t *opll = &vrc7; /* Point to fixed instrument or user table */ uint8 *param = (inst == 0) ? &opll->user[0] : &table[inst][0]; /* Maps channels to operator registers */ uint8 ch2op[] = {0, 1, 2, 8, 9, 10, 16, 17, 18}; /* Make operator offset from requested channel */ uint8 op = ch2op[ch]; /* Store volume level */ opll->channel[ch].volume = (vol & 0x3F); /* Store instrument number */ opll->channel[ch].instrument = (inst & 0x0F); /* Update instrument settings, except frequency registers */ OPL_WRITE(opll, 0x20 + op, param[0]); OPL_WRITE(opll, 0x23 + op, param[1]); OPL_WRITE(opll, 0x40 + op, param[2]); OPL_WRITE(opll, 0x43 + op, (param[3] & 0xC0) | opll->channel[ch].volume); OPL_WRITE(opll, 0x60 + op, param[4]); OPL_WRITE(opll, 0x63 + op, param[5]); OPL_WRITE(opll, 0x80 + op, param[6]); OPL_WRITE(opll, 0x83 + op, param[7]); OPL_WRITE(opll, 0xE0 + op, param[8]); OPL_WRITE(opll, 0xE3 + op, param[9]); OPL_WRITE(opll, 0xC0 + ch, param[10]); } static void vrc7_write(uint32 address, uint8 data) { /* Point to current VRC7 context */ vrc7_t *opll = &vrc7; if (address & 0x0020) /* data port */ { /* Store register data */ opll->reg[opll->latch] = data; switch (opll->latch & 0x30) { case 0x00: /* User instrument registers */ switch (opll->latch & 0x0F) { case 0x00: /* Misc. ctrl. (modulator) */ case 0x01: /* Misc. ctrl. (carrier) */ case 0x02: /* Key scale level and total level (modulator) */ case 0x04: /* Attack / Decay (modulator) */ case 0x05: /* Attack / Decay (carrier) */ case 0x06: /* Sustain / Release (modulator) */ case 0x07: /* Sustain / Release (carrier) */ opll->user[(opll->latch & 0x07)] = data; break; case 0x03: /* Key scale level, carrier/modulator waveform, feedback */ /* Key scale level (carrier) */ /* Don't touch the total level (channel volume) */ opll->user[3] = (opll->user[3] & 0x3F) | (data & 0xC0); /* Waveform select for the modulator */ opll->user[8] = (data >> 3) & 1; /* Waveform select for the carrier */ opll->user[9] = (data >> 4) & 1; /* Store feedback level in YM3812 format */ opll->user[10] = ((data & 0x07) << 1) & 0x0E; break; } /* If the user instrument registers were accessed, then go through each channel and update the ones that were currently using the user instrument. We can skip the last three channels in rhythm mode since they can only use percussion sounds anyways. */ if (opll->latch <= 0x05) { uint8 x; for (x = 0; x < 6; x++) if (opll->channel[x].instrument == 0x00) load_instrument(x, 0x00, opll->channel[x].volume); } break; case 0x10: /* Channel Frequency (LSB) */ case 0x20: /* Channel Frequency (MSB) + key-on and sustain control */ { uint8 block; uint16 frequency; uint8 ch = (opll->latch & 0x0F); /* Ensure proper channel range */ if (ch > 0x05) break; /* Get VRC7 channel frequency */ frequency = ((opll->reg[0x10 + ch] & 0xFF) | ((opll->reg[0x20 + ch] & 0x01) << 8)); /* Scale 9 bit frequency to 10 bits */ frequency = (frequency << 1) & 0x1FFF; /* Get VRC7 block */ block = (opll->reg[0x20 + ch] >> 1) & 7; /* Add in block */ frequency |= (block << 10); /* Add key-on flag */ if (opll->reg[0x20 + ch] & 0x10) frequency |= 0x2000; /* Save current frequency/block/key-on setting */ opll->channel[ch].frequency = (frequency & 0x3FFF); /* Write changes to YM3812 */ OPL_WRITE(opll, 0xA0 + ch, (opll->channel[ch].frequency >> 0) & 0xFF); OPL_WRITE(opll, 0xB0 + ch, (opll->channel[ch].frequency >> 8) & 0xFF); } break; case 0x30: /* Channel Volume Level and Instrument Select */ /* Ensure proper channel range */ if (opll->latch > 0x35) break; { uint8 ch = (opll->latch & 0x0F); uint8 inst = (data >> 4) & 0x0F; uint8 vol = (data & 0x0F) << 2; load_instrument(ch, inst, vol); } break; } } else /* Register latch */ { opll->latch = (data & 0x3F); } } static int32 vrc7_process(void) { static int sample = 0; /* update a large chunk at once */ if (sample >= buflen) { sample -= buflen; YM3812UpdateOne(vrc7.ym3812, buffer, buflen); } return (int32) ((int16 *) buffer)[sample++]; } static apu_memwrite vrc7_memwrite[] = { { 0x9010, 0x9010, vrc7_write }, { 0x9030, 0x9030, vrc7_write }, { -1, -1, NULL } }; apuext_t vrc7_ext = { vrc7_init, vrc7_shutdown, vrc7_reset, vrc7_process, NULL, /* no reads */ vrc7_memwrite }; /* ** $Log: vrc7_snd.c,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:36 tmmm ** initial import of Nosefart sources ** ** Revision 1.5 2000/07/04 04:51:02 matt ** made data types stricter ** ** Revision 1.4 2000/07/03 02:18:53 matt ** much better external module exporting ** ** Revision 1.3 2000/06/20 20:45:09 matt ** minor cleanups ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.1 2000/06/20 00:06:47 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/vrcvisnd.h0000644000175000017500000000452514647725152016162 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** vrcvisnd.h ** ** VRCVI (Konami MMC) sound hardware emulation header ** $Id: vrcvisnd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifndef _VRCVISND_H_ #define _VRCVISND_H_ typedef struct vrcvirectangle_s { uint8 reg[3]; int32 phaseacc; uint8 adder; int32 freq; int32 volume; uint8 duty_flip; boolean enabled; } vrcvirectangle_t; typedef struct vrcvisawtooth_s { uint8 reg[3]; int32 phaseacc; uint8 adder; uint8 output_acc; int32 freq; uint8 volume; boolean enabled; } vrcvisawtooth_t; typedef struct vrcvisnd_s { vrcvirectangle_t rectangle[2]; vrcvisawtooth_t saw; } vrcvisnd_t; #include "nes_apu.h" extern apuext_t vrcvi_ext; #endif /* _VRCVISND_H_ */ /* ** $Log: vrcvisnd.h,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:36 tmmm ** initial import of Nosefart sources ** ** Revision 1.7 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.6 2000/06/20 00:08:58 matt ** changed to driver based API ** ** Revision 1.5 2000/06/09 16:49:02 matt ** removed all floating point from sound generation ** ** Revision 1.4 2000/06/09 15:12:28 matt ** initial revision ** */ xine-lib-1.2/contrib/nosefart/diff_to_nosefart_cvs.patch0000644000175000017500000000720714647725152021362 0ustar memediff -u -p -r1.1.1.1 types.h --- types.h 26 Jul 2004 15:27:59 -0000 1.1.1.1 +++ types.h 26 Aug 2004 16:00:07 -0000 @@ -23,8 +23,8 @@ ** $Id: diff_to_nosefart_cvs.patch,v 1.2 2005/05/07 09:11:39 valtri Exp $ */ -#ifndef _TYPES_H_ -#define _TYPES_H_ +#ifndef _NOSEFART_TYPES_H_ +#define _NOSEFART_TYPES_H_ #ifdef HAVE_CONFIG_H #include "config.h" @@ -88,7 +88,7 @@ typedef uint8 boolean; #define ASSERT_MSG(msg) #endif -#endif /* _TYPES_H_ */ +#endif /* _NOSEFART_TYPES_H_ */ /* ** $Log: diff_to_nosefart_cvs.patch,v $ ** Revision 1.2 2005/05/07 09:11:39 valtri ** *BUGFIX* ** gcc4 patches from Dams Nadé (livna.org) and Keenan Pepper. ** ** Revision 1.1 2004/08/27 19:33:37 valtri ** MINGW32 port. Engine library and most of plugins compiles now. ** ** List of some changes: ** - replaced some _MSC_VER by more common WIN32 ** - define INTLDIR, remove -static flag for included intl ** - shared more common CFLAGS with DEBUG_CFLAGS ** - use WIN32_CFLAGS for all building ** - separate some flags into THREAD_CFLAGS_CONFIG, ** THREAD_CFLAGS_CONFIG and ZLIB_LIB_CONFIG for public xine-config, ** automatically use internal libs if necessary ** - don't warn about missing X for mingw and cygwin ** - libw32dll disabled for WIN32 (making native loader would be ** interesting, or porting wine code to Windows? :->) ** - DVB and RTP disabled for WIN32, not ported yet ** - fix build and fix a warning in cdda ** - fix build for nosefart and libfaad ** - implement configure option --disable-freetype ** - sync libxine.pc and xine-config.in ** - add -liberty to goom under WIN32 ** - move original build files from included phread and zlib into archives ** and replace them by autotools ** Index: nes_apu.c =================================================================== RCS file: /home/valtri/CVS/xine-lib/src/libxineadec/nosefart/nes_apu.c,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 nes_apu.c --- nes_apu.c 12 Dec 2004 13:57:16 -0000 1.1.1.1 +++ nes_apu.c 7 May 2005 08:23:36 -0000 @@ -1011,10 +1011,13 @@ void apu_process(void *buffer, int num_s accum = -0x8000; /* signed 16-bit output, unsigned 8-bit */ - if (16 == apu->sample_bits) - *((int16 *) buffer)++ = (int16) accum; - else - *((uint8 *) buffer)++ = (accum >> 8) ^ 0x80; + if (16 == apu->sample_bits) { + *((int16 *) buffer) = (int16) accum; + buffer = (int16 *) buffer + 1; + } else { + *((uint8 *) buffer) = (accum >> 8) ^ 0x80; + buffer = (int8 *) buffer + 1; + } } /* resync cycle counter */ --- a/src/libxineadec/nosefart/nsf.h Tue Apr 10 13:42:00 2007 +0200 +++ b/src/libxineadec/nosefart/nsf.h Tue Apr 10 13:48:50 2007 +0200 @@ -29,6 +29,8 @@ #include "osd.h" #include "nes6502.h" #include "nes_apu.h" + +#include "config.h" #define NSF_MAGIC "NESM\x1A" @@ -96,7 +98,7 @@ typedef struct nsf_s /* our main processing routine, calls all external mixing routines */ void (*process)(void *buffer, int num_samples); -} __PACKED__ nsf_t; +} XINE_PACKED nsf_t; /* Function prototypes */ extern void nsf_init(void); --- a/src/libxineadec/nosefart/osd.h Tue Apr 10 13:42:00 2007 +0200 +++ b/src/libxineadec/nosefart/osd.h Tue Apr 10 13:19:34 2007 +0200 @@ -26,19 +26,15 @@ #ifndef _OSD_H_ #define _OSD_H_ - #if defined(__GNUC__) || defined(__ICC) -#define __PACKED__ __attribute__ ((packed)) #define PATH_SEP '/' #ifdef __DJGPP__ #include #include "dos_ints.h" #endif #elif defined(WIN32) -#define __PACKED__ #define PATH_SEP '\\' #else /* crapintosh? */ -#define __PACKED__ #define PATH_SEP ':' #endif xine-lib-1.2/contrib/nosefart/mmc5_snd.h0000644000175000017500000000443414647725152016030 0ustar meme/* ** Nofrendo (c) 1998-2000 Matthew Conte (matt@conte.com) ** ** ** This program is free software; you can redistribute it and/or ** modify it under the terms of version 2 of the GNU Library General ** Public License as published by the Free Software Foundation. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ** Library General Public License for more details. To obtain a ** copy of the GNU Library General Public License, write to the Free ** Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, ** MA 02110-1301, USA. ** ** Any permitted reproduction of these routines, in whole or in part, ** must bear this legend. ** ** ** mmc5_snd.h ** ** Nintendo MMC5 sound emulation header ** $Id: mmc5_snd.h,v 1.2 2003/12/05 15:55:01 f1rmb Exp $ */ #ifndef _MMC5_SND_H_ #define _MMC5_SND_H_ #define MMC5_WRA0 0x5000 #define MMC5_WRA1 0x5001 #define MMC5_WRA2 0x5002 #define MMC5_WRA3 0x5003 #define MMC5_WRB0 0x5004 #define MMC5_WRB1 0x5005 #define MMC5_WRB2 0x5006 #define MMC5_WRB3 0x5007 #define MMC5_SMASK 0x5015 typedef struct mmc5rectangle_s { uint8 regs[4]; boolean enabled; int32 phaseacc; int32 freq; int32 output_vol; boolean fixed_envelope; boolean holdnote; uint8 volume; int32 env_phase; int32 env_delay; uint8 env_vol; int vbl_length; uint8 adder; int duty_flip; } mmc5rectangle_t; #include "nes_apu.h" extern apuext_t mmc5_ext; #endif /* !_MMC5_SND_H_ */ /* ** $Log: mmc5_snd.h,v $ ** Revision 1.2 2003/12/05 15:55:01 f1rmb ** cleanup phase II. use xprintf when it's relevant, use xine_xmalloc when it's relevant too. Small other little fix (can't remember). Change few internal function prototype because it xine_t pointer need to be used if some xine's internal sections. NOTE: libdvd{nav,read} is still too noisy, i will take a look to made it quit, without invasive changes. To be continued... ** ** Revision 1.1 2003/01/08 07:04:35 tmmm ** initial import of Nosefart sources ** ** Revision 1.2 2000/06/20 04:06:16 matt ** migrated external sound definition to apu module ** ** Revision 1.1 2000/06/20 00:06:47 matt ** initial revision ** */ xine-lib-1.2/contrib/libxdg-basedir/0000755000175000017500000000000014647725152015204 5ustar memexine-lib-1.2/contrib/libxdg-basedir/basedir.h0000644000175000017500000001246614647725152016777 0ustar meme/* Copyright (c) 2007 Mark Nevill * * 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. */ /** @mainpage * *
* Various specifications specify files and file formats. The * XDG Base Directory specification defines where these files should * be looked for by defining one or more base directories relative to * which files should be located. *
* * This library implements functions to list the directories according * to the specification and provides a few higher-level functions for * use with the specification. */ /** @file basedir.h * Functions for using the XDG Base Directory specification. */ #ifndef XDG_BASEDIR_H #define XDG_BASEDIR_H #ifdef __cplusplus extern "C" { #endif /** Version of XDG Base Directory specification implemented in this library. */ #define XDG_BASEDIR_SPEC 0.6 /** @name XDG data cache management */ /*@{*/ /** Handle to XDG data cache. * Handles are initialized with xdgInitHandle() and * freed with xdgWipeHandle(). */ typedef struct /*_xdgHandle*/ { /** Reserved for internal use, do not modify. */ void *reserved; } xdgHandle; /** Initialize a handle to an XDG data cache and initialize the cache. * Use xdgWipeHandle() to free the handle. * @return a pointer to the handle if initialization was successful, else 0 */ xdgHandle * xdgInitHandle(xdgHandle *handle); /** Wipe handle of XDG data cache. * Wipe handle initialized using xdgInitHandle(). */ void xdgWipeHandle(xdgHandle *handle); /** Update the data cache. * This should not be done frequently as it reallocates the cache. * Even if updating the cache fails the handle remains valid and can * be used to access XDG data as it was before xdgUpdateData() was called. * @return 0 if update failed, non-0 if successful.*/ int xdgUpdateData(xdgHandle *handle); /*@}*/ /** @name Basic XDG Base Directory Queries */ /*@{*/ /** Base directory for user specific data files. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return a path as described by the standards. */ const char * xdgDataHome(xdgHandle *handle); /** Base directory for user specific configuration files. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return a path as described by the standards. */ const char * xdgConfigHome(xdgHandle *handle); /** Preference-ordered set of base directories to search for data files * in addition to the $XDG_DATA_HOME base directory. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ const char * const * xdgDataDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for data files * with $XDG_DATA_HOME prepended. * The base directory defined by $XDG_DATA_HOME is considered more * important than any of the base directories defined by $XDG_DATA_DIRS. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ const char * const * xdgSearchableDataDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for configuration * files in addition to the $XDG_CONFIG_HOME base directory. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ const char * const * xdgConfigDirectories(xdgHandle *handle); /** Preference-ordered set of base directories to search for configuration * files with $XDG_CONFIG_HOME prepended. * The base directory defined by $XDG_CONFIG_HOME is considered more * important than any of the base directories defined by $XDG_CONFIG_DIRS. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A null-terminated list of directory strings. */ const char * const * xdgSearchableConfigDirectories(xdgHandle *handle); /** Base directory for user specific non-essential data files. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return a path as described by the standards. */ const char * xdgCacheHome(xdgHandle *handle); /*@}*/ #ifdef __cplusplus } // extern "C" #endif #endif /*XDG_BASEDIR_H*/ xine-lib-1.2/contrib/libxdg-basedir/Makefile.am0000644000175000017500000000042114647725152017235 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_LDFLAGS = $(xineplug_ldflags) if !EXTERNAL_LIBXDG_BASEDIR noinst_LTLIBRARIES = libxdg-basedir.la endif AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) libxdg_basedir_la_SOURCES = \ basedir.c \ basedir.h \ basedir_fs.h xine-lib-1.2/contrib/libxdg-basedir/basedir.c0000644000175000017500000003762014647725152016771 0ustar meme/* Copyright (c) 2007 Mark Nevill * * 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. */ /** @file basedir.c * @brief Implementation of the XDG Base Directory specification. */ #if defined(HAVE_CONFIG_H) || defined(_DOXYGEN) #include #endif #include #if HAVE_MEMORY_H || !defined(HAVE_CONFIG_H) # include #endif #include #if HAVE_STRINGS_H # include #endif #include #include #include #ifdef FALSE #undef FALSE #endif #ifdef TRUE #undef TRUE #endif #define FALSE 0 #define TRUE 1 #if HAVE_MEMSET || !defined(HAVE_CONFIG_H) # define xdgZeroMemory(p, n) memset(p, 0, n) #elif HAVE_BZERO # define xdgZeroMemory(p, n) bzero(p, n) #else static void xdgZeroMemory(void* p, size_t n) { while (n > 0) { ((char*)p)[n] = 0; ++n; } } #endif #if defined _WIN32 && !defined __CYGWIN__ /* Use Windows separators on all _WIN32 defining environments, except Cygwin. */ # define DIR_SEPARATOR_CHAR '\\' # define DIR_SEPARATOR_STR "\\" # define PATH_SEPARATOR_CHAR ';' # define PATH_SEPARATOR_STR ";" # define NO_ESCAPES_IN_PATHS #else # define DIR_SEPARATOR_CHAR '/' # define DIR_SEPARATOR_STR "/" # define PATH_SEPARATOR_CHAR ':' # define PATH_SEPARATOR_STR ":" # define NO_ESCAPES_IN_PATHS #endif #include #include #ifndef MAX #define MAX(a, b) ((b) > (a) ? (b) : (a)) #endif static const char DefaultRelativeDataHome[] = DIR_SEPARATOR_STR ".local" DIR_SEPARATOR_STR "share", DefaultRelativeConfigHome[] = DIR_SEPARATOR_STR ".config", DefaultDataDirectories1[] = DIR_SEPARATOR_STR "usr" DIR_SEPARATOR_STR "local" DIR_SEPARATOR_STR "share", DefaultDataDirectories2[] = DIR_SEPARATOR_STR "usr" DIR_SEPARATOR_STR "share", DefaultConfigDirectories[] = DIR_SEPARATOR_STR "etc" DIR_SEPARATOR_STR "xdg", DefaultRelativeCacheHome[] = DIR_SEPARATOR_STR ".cache"; static const char *DefaultDataDirectoriesList[] = { DefaultDataDirectories1, DefaultDataDirectories2, NULL }, *DefaultConfigDirectoriesList[] = { DefaultConfigDirectories, NULL }; typedef struct _xdgCachedData { char * dataHome; char * configHome; char * cacheHome; /* Note: string lists are null-terminated and all items */ /* except the first are assumed to be allocated using malloc. */ /* The first item is assumed to be allocated by malloc only if */ /* it is not equal to the appropriate home directory string above. */ char ** searchableDataDirectories; char ** searchableConfigDirectories; } xdgCachedData; /** Get cache object associated with a handle */ static xdgCachedData* xdgGetCache(xdgHandle *handle) { return ((xdgCachedData*)(handle->reserved)); } xdgHandle * xdgInitHandle(xdgHandle *handle) { if (!handle) return 0; handle->reserved = 0; /* So xdgUpdateData() doesn't free it */ if (xdgUpdateData(handle)) return handle; return 0; } /** Free all memory used by a NULL-terminated string list */ static void xdgFreeStringList(char** list) { char** ptr = list; if (!list) return; for (; *ptr; ptr++) free(*ptr); free(list); } /** Free all data in the cache and set pointers to null. */ static void xdgFreeData(xdgCachedData *cache) { /* if (cache->dataHome) */ { /* the first element of the directory lists is usually the home directory */ if (cache->searchableDataDirectories[0] != cache->dataHome) free(cache->dataHome); cache->dataHome = NULL; } /* if (cache->configHome) */ { if (cache->searchableConfigDirectories[0] != cache->configHome) free(cache->configHome); cache->configHome = NULL; } if (cache->cacheHome) { free(cache->cacheHome); cache->cacheHome = NULL; } xdgFreeStringList(cache->searchableDataDirectories); cache->searchableDataDirectories = NULL; xdgFreeStringList(cache->searchableConfigDirectories); cache->searchableConfigDirectories = NULL; } void xdgWipeHandle(xdgHandle *handle) { xdgCachedData* cache = xdgGetCache(handle); xdgFreeData(cache); free(cache); } /** Get value for environment variable $name, defaulting to "defaultValue". * @param name Name of environment variable. * @param defaultValue Value to assume for environment variable if it is * unset or empty. */ static char* xdgGetEnv(const char* name, const char* defaultValue) { const char* env; char* value; env = getenv(name); if (env && env[0]) { if (!(value = (char*)malloc(strlen(env)+1))) return NULL; strcpy(value, env); } else { if (!(value = (char*)malloc(strlen(defaultValue)+1))) return NULL; strcpy(value, defaultValue); } return value; } /** Split string at ':', return null-terminated list of resulting strings. * @param string String to be split */ static char** xdgSplitPath(const char* string) { unsigned int size, i, j, k; char** itemlist; /* Get the number of paths */ size=2; /* One item more than seperators + terminating null item */ for (i = 0; string[i]; ++i) { #ifndef NO_ESCAPES_IN_PATHS if (string[i] == '\\' && string[i+1]) { /* skip escaped characters including seperators */ ++i; continue; } #endif if (string[i] == PATH_SEPARATOR_CHAR) ++size; } if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return NULL; xdgZeroMemory(itemlist, sizeof(char*)*size); for (i = 0; *string; ++i) { /* get length of current string */ for (j = 0; string[j] && string[j] != PATH_SEPARATOR_CHAR; ++j) #ifndef NO_ESCAPES_IN_PATHS if (string[j] == '\\' && string[j+1]) ++j #endif ; if (!(itemlist[i] = (char*)malloc(j+1))) { xdgFreeStringList(itemlist); return NULL; } /* transfer string, unescaping any escaped seperators */ for (k = j = 0; string[j] && string[j] != PATH_SEPARATOR_CHAR; ++j, ++k) { #ifndef NO_ESCAPES_IN_PATHS if (string[j] == '\\' && string[j+1] == PATH_SEPARATOR_CHAR) ++j; /* replace escaped ':' with just ':' */ else if (string[j] == '\\' && string[j+1]) /* skip escaped characters so escaping remains aligned to pairs. */ { itemlist[i][k]=string[j]; ++j, ++k; } #endif itemlist[i][k] = string[j]; } itemlist[i][k] = 0; /* Bugfix provided by Diego 'Flameeyes' Pettenò */ /* move to next string */ string += j; if (*string == PATH_SEPARATOR_CHAR) string++; /* skip seperator */ } return itemlist; } /** Get $PATH-style environment variable as list of strings. * If $name is unset or empty, use default strings specified by variable arguments. * @param name Name of environment variable * @param strings NULL-terminated list of strings to be copied and used as defaults */ static char** xdgGetPathListEnv(const char* name, const char ** strings) { const char* env; char* item; char** itemlist; int i, size; env = getenv(name); if (env && env[0]) { if (!(item = (char*)malloc(strlen(env)+1))) return NULL; strcpy(item, env); itemlist = xdgSplitPath(item); free(item); } else { if (!strings) return NULL; for (size = 0; strings[size]; ++size) ; ++size; if (!(itemlist = (char**)malloc(sizeof(char*)*size))) return NULL; xdgZeroMemory(itemlist, sizeof(char*)*(size)); /* Copy defaults into itemlist. */ /* Why all this funky stuff? So the result can be handled uniformly by xdgFreeStringList. */ for (i = 0; strings[i]; ++i) { if (!(item = (char*)malloc(strlen(strings[i])+1))) { xdgFreeStringList(itemlist); return NULL; } strcpy(item, strings[i]); itemlist[i] = item; } } return itemlist; } /** Update all *Home variables of cache. * This includes xdgCachedData::dataHome, xdgCachedData::configHome and xdgCachedData::cacheHome. * @param cache Data cache to be updated */ static int xdgUpdateHomeDirectories(xdgCachedData* cache) { const char* env; char* home, *defVal = NULL; int result = FALSE; env = getenv("HOME"); if (!env || !env[0]) return FALSE; if (!(home = (char*)malloc(strlen(env)+1))) goto out; strcpy(home, env); /* Allocate maximum needed for any of the 3 default values */ defVal = (char*)malloc(strlen(home)+ MAX(MAX(sizeof(DefaultRelativeDataHome), sizeof(DefaultRelativeConfigHome)), sizeof(DefaultRelativeCacheHome))); if (!defVal) goto out; strcpy(defVal, home); strcat(defVal, DefaultRelativeDataHome); if (!(cache->dataHome = xdgGetEnv("XDG_DATA_HOME", defVal))) goto out; defVal[strlen(home)] = 0; strcat(defVal, DefaultRelativeConfigHome); if (!(cache->configHome = xdgGetEnv("XDG_CONFIG_HOME", defVal))) goto out; defVal[strlen(home)] = 0; strcat(defVal, DefaultRelativeCacheHome); if (!(cache->cacheHome = xdgGetEnv("XDG_CACHE_HOME", defVal))) goto out; result = TRUE; out: free(defVal); free(home); return result; } /** Update all *Directories variables of cache. * This includes xdgCachedData::searchableDataDirectories and xdgCachedData::searchableConfigDirectories. * @param cache Data cache to be updated. */ static int xdgUpdateDirectoryLists(xdgCachedData* cache) { char** itemlist; int size; itemlist = xdgGetPathListEnv("XDG_DATA_DIRS", DefaultDataDirectoriesList); if (!itemlist) return FALSE; for (size = 0; itemlist[size]; size++) ; /* Get list size */ if (!(cache->searchableDataDirectories = (char**)malloc(sizeof(char*)*(size+2)))) { xdgFreeStringList(itemlist); return FALSE; } /* "home" directory has highest priority according to spec */ cache->searchableDataDirectories[0] = cache->dataHome; memcpy(&(cache->searchableDataDirectories[1]), itemlist, sizeof(char*)*(size+1)); free(itemlist); itemlist = xdgGetPathListEnv("XDG_CONFIG_DIRS", DefaultConfigDirectoriesList); if (!itemlist) return FALSE; for (size = 0; itemlist[size]; size++) ; /* Get list size */ if (!(cache->searchableConfigDirectories = (char**)malloc(sizeof(char*)*(size+2)))) { xdgFreeStringList(itemlist); return FALSE; } cache->searchableConfigDirectories[0] = cache->configHome; memcpy(&(cache->searchableConfigDirectories[1]), itemlist, sizeof(char*)*(size+1)); free(itemlist); return TRUE; } int xdgUpdateData(xdgHandle *handle) { xdgCachedData* cache = (xdgCachedData*)malloc(sizeof(xdgCachedData)); xdgCachedData* oldCache; if (!cache) return FALSE; xdgZeroMemory(cache, sizeof(xdgCachedData)); if (xdgUpdateHomeDirectories(cache) && xdgUpdateDirectoryLists(cache)) { /* Update successful, replace pointer to old cache with pointer to new cache */ oldCache = xdgGetCache(handle); handle->reserved = cache; if (oldCache) { xdgFreeData(oldCache); free(oldCache); } return TRUE; } else { /* Update failed, discard new cache and leave old cache unmodified */ xdgFreeData(cache); free(cache); return FALSE; } } /** Find all existing files corresponding to relativePath relative to each item in dirList. * @param relativePath Relative path to search for. * @param dirList NULL-terminated list of directory paths. * @return A sequence of null-terminated strings terminated by a * double-NULL (empty string) and allocated using malloc(). */ static char * xdgFindExisting(const char * relativePath, const char * const * dirList) { char * fullPath; char * returnString = 0; char * tmpString; int strLen = 0; FILE * testFile; const char * const * item; for (item = dirList; *item; item++) { if (!(fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2))) { if (returnString) free(returnString); return NULL; } strcpy(fullPath, *item); if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) strcat(fullPath, DIR_SEPARATOR_STR); strcat(fullPath, relativePath); testFile = fopen(fullPath, "r"); if (testFile) { fclose(testFile); if (!(tmpString = (char*)realloc(returnString, strLen+strlen(fullPath)+2))) { free(returnString); free(fullPath); return NULL; } returnString = tmpString; strcpy(&returnString[strLen], fullPath); strLen = strLen+strlen(fullPath)+1; } free(fullPath); } if (returnString) returnString[strLen] = 0; else { if ((returnString = (char*)malloc(2))) strcpy(returnString, "\0"); } return returnString; } /** Open first possible config file corresponding to relativePath. * @param relativePath Path to scan for. * @param mode Mode with which to attempt to open files (see fopen modes). * @param dirList NULL-terminated list of paths in which to search for relativePath. * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. */ static FILE * xdgFileOpen(const char * relativePath, const char * mode, const char * const * dirList) { char * fullPath; FILE * testFile; const char * const * item; for (item = dirList; *item; item++) { if (!(fullPath = (char*)malloc(strlen(*item)+strlen(relativePath)+2))) return NULL; strcpy(fullPath, *item); if (fullPath[strlen(fullPath)-1] != DIR_SEPARATOR_CHAR) strcat(fullPath, DIR_SEPARATOR_STR); strcat(fullPath, relativePath); testFile = fopen(fullPath, mode); free(fullPath); if (testFile) return testFile; } return NULL; } int xdgMakePath(const char * path, mode_t mode) { int length = strlen(path); char * tmpPath; char * tmpPtr; int ret; if (length == 0 || (length == 1 && path[0] == DIR_SEPARATOR_CHAR)) return 0; if (!(tmpPath = (char*)malloc(length+1))) { errno = ENOMEM; return -1; } strcpy(tmpPath, path); if (tmpPath[length-1] == DIR_SEPARATOR_CHAR) tmpPath[length-1] = '\0'; /* skip tmpPath[0] since if it's a seperator we have an absolute path */ for (tmpPtr = tmpPath+1; *tmpPtr; ++tmpPtr) { if (*tmpPtr == DIR_SEPARATOR_CHAR) { *tmpPtr = '\0'; if (mkdir(tmpPath, mode) == -1) { if (errno != EEXIST) { free(tmpPath); return -1; } } *tmpPtr = DIR_SEPARATOR_CHAR; } } ret = mkdir(tmpPath, mode); free(tmpPath); return ret; } const char * xdgDataHome(xdgHandle *handle) { return xdgGetCache(handle)->dataHome; } const char * xdgConfigHome(xdgHandle *handle) { return xdgGetCache(handle)->configHome; } const char * const * xdgDataDirectories(xdgHandle *handle) { return (const char * const *)&(xdgGetCache(handle)->searchableDataDirectories[1]); } const char * const * xdgSearchableDataDirectories(xdgHandle *handle) { return (const char * const *)xdgGetCache(handle)->searchableDataDirectories; } const char * const * xdgConfigDirectories(xdgHandle *handle) { return (const char * const *)&(xdgGetCache(handle)->searchableConfigDirectories[1]); } const char * const * xdgSearchableConfigDirectories(xdgHandle *handle) { return (const char * const *)xdgGetCache(handle)->searchableConfigDirectories; } const char * xdgCacheHome(xdgHandle *handle) { return xdgGetCache(handle)->cacheHome; } char * xdgDataFind(const char * relativePath, xdgHandle *handle) { return xdgFindExisting(relativePath, xdgSearchableDataDirectories(handle)); } char * xdgConfigFind(const char * relativePath, xdgHandle *handle) { return xdgFindExisting(relativePath, xdgSearchableConfigDirectories(handle)); } FILE * xdgDataOpen(const char * relativePath, const char * mode, xdgHandle *handle) { return xdgFileOpen(relativePath, mode, xdgSearchableDataDirectories(handle)); } FILE * xdgConfigOpen(const char * relativePath, const char * mode, xdgHandle *handle) { return xdgFileOpen(relativePath, mode, xdgSearchableConfigDirectories(handle)); } xine-lib-1.2/contrib/libxdg-basedir/basedir_fs.h0000644000175000017500000001053514647725152017462 0ustar meme/* Copyright (c) 2007 Mark Nevill * * 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. */ /** @file basedir_fs.h * Filesystem functions related to the XDG Base Directory specification. */ #ifndef XDG_BASEDIR_FS_H #define XDG_BASEDIR_FS_H #include #include #include #ifdef __cplusplus extern "C" { #endif /** @name Filesystem-related XDG Base Directory Queries */ /*@{*/ /** Find all existing data files corresponding to relativePath. * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename * and returning the successful filenames. * @param relativePath Path to scan for. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A sequence of null-terminated strings terminated by a double-null (empty string) * and allocated using malloc(), e.g.: @code "/etc/share\0/home/jdoe/.local\0" @endcode */ char * xdgDataFind(const char* relativePath, xdgHandle *handle); /** Find all existing config files corresponding to relativePath. * Consider as performing @code fopen(filename, "r") @endcode on every possible @c filename * and returning the successful filenames. * @param relativePath Path to scan for. * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return A sequence of null-terminated strings terminated by a double-null (empty string) * and allocated using malloc(), e.g.: @code "/etc/xdg\0/home/jdoe/.config\0" @endcode */ char * xdgConfigFind(const char* relativePath, xdgHandle *handle); /** Open first possible data file corresponding to relativePath. * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename * and returning the first successful @c filename or @c NULL. * @param relativePath Path to scan for. * @param mode Mode with which to attempt to open files (see fopen modes). * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. */ FILE * xdgDataOpen(const char* relativePath, const char* mode, xdgHandle *handle); /** Open first possible config file corresponding to relativePath. * Consider as performing @code fopen(filename, mode) @endcode on every possible @c filename * and returning the first successful @c filename or @c NULL. * @param relativePath Path to scan for. * @param mode Mode with which to attempt to open files (see fopen modes). * @param handle Handle to data cache, initialized with xdgInitHandle(). * @return File pointer if successful else @c NULL. Client must use @c fclose to close file. */ FILE * xdgConfigOpen(const char* relativePath, const char* mode, xdgHandle *handle); /** Create path by recursively creating directories. * This utility function is not part of the XDG specification, but * nevertheless useful in context of directory manipulation. * @param path The path to be created. * @param mode The permissions to use for created directories. This parameter * is modified by the process's umask. For details, see mkdir(2)'s mode * parameter. * @return Zero on success, -1 if an error occured (in which case errno will * be set appropriately) */ int xdgMakePath(const char * path, mode_t mode); /*@}*/ #ifdef __cplusplus } // extern "C" #endif #endif /*XDG_BASEDIR_FS_H*/ xine-lib-1.2/contrib/a52dec/0000755000175000017500000000000014647725151013366 5ustar memexine-lib-1.2/contrib/a52dec/a52_internal.h0000644000175000017500000001476714647725151016041 0ustar meme/* * a52_internal.h * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ typedef struct complex_s { sample_t real; sample_t imag; } complex_t; typedef struct { uint8_t bai; /* fine SNR offset, fast gain */ uint8_t deltbae; /* delta bit allocation exists */ int8_t deltba[50]; /* per-band delta bit allocation */ } ba_t; typedef struct { uint8_t exp[256]; /* decoded channel exponents */ int8_t bap[256]; /* derived channel bit allocation */ } expbap_t; struct a52_state_s { uint8_t fscod; /* sample rate */ uint8_t halfrate; /* halfrate factor */ uint8_t acmod; /* coded channels */ uint8_t lfeon; /* coded lfe channel */ sample_t clev; /* centre channel mix level */ sample_t slev; /* surround channels mix level */ int output; /* type of output */ sample_t level; /* output level */ sample_t bias; /* output bias */ int dynrnge; /* apply dynamic range */ sample_t dynrng; /* dynamic range */ void * dynrngdata; /* dynamic range callback funtion and data */ sample_t (* dynrngcall) (sample_t range, void * dynrngdata); uint8_t chincpl; /* channel coupled */ uint8_t phsflginu; /* phase flags in use (stereo only) */ uint8_t cplstrtmant; /* coupling channel start mantissa */ uint8_t cplendmant; /* coupling channel end mantissa */ uint32_t cplbndstrc; /* coupling band structure */ sample_t cplco[5][18]; /* coupling coordinates */ /* derived information */ uint8_t cplstrtbnd; /* coupling start band (for bit allocation) */ uint8_t ncplbnd; /* number of coupling bands */ uint8_t rematflg; /* stereo rematrixing */ uint8_t endmant[5]; /* channel end mantissa */ uint16_t bai; /* bit allocation information */ uint32_t * buffer_start; uint16_t lfsr_state; /* dither state */ uint32_t bits_left; uint32_t current_word; uint8_t csnroffst; /* coarse SNR offset */ ba_t cplba; /* coupling bit allocation parameters */ ba_t ba[5]; /* channel bit allocation parameters */ ba_t lfeba; /* lfe bit allocation parameters */ uint8_t cplfleak; /* coupling fast leak init */ uint8_t cplsleak; /* coupling slow leak init */ expbap_t cpl_expbap; expbap_t fbw_expbap[5]; expbap_t lfe_expbap; sample_t * samples; void * samples_base; int downmixed; /* these used to be writable static data in imdct.c. */ /* Root values for IFFT */ sample_t roots16[3]; sample_t roots32[7]; sample_t roots64[15]; sample_t roots128[31]; /* Twiddle factors for IMDCT */ complex_t pre1[128]; complex_t post1[64]; complex_t pre2[64]; complex_t post2[32]; /* */ sample_t a52_imdct_window[256]; /* */ void (* ifft128) (a52_state_t *a52, complex_t * buf); void (* ifft64) (a52_state_t *a52, complex_t * buf); }; #define LEVEL_PLUS6DB 2.0 #define LEVEL_PLUS3DB 1.4142135623730951 #define LEVEL_3DB 0.7071067811865476 #define LEVEL_45DB 0.5946035575013605 #define LEVEL_6DB 0.5 #define EXP_REUSE (0) #define EXP_D15 (1) #define EXP_D25 (2) #define EXP_D45 (3) #define DELTA_BIT_REUSE (0) #define DELTA_BIT_NEW (1) #define DELTA_BIT_NONE (2) #define DELTA_BIT_RESERVED (3) void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart, int start, int end, int fastleak, int slowleak, expbap_t * expbap); int a52_downmix_init (int input, int flags, sample_t * level, sample_t clev, sample_t slev); int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level, sample_t clev, sample_t slev); void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, sample_t clev, sample_t slev); void a52_upmix (sample_t * samples, int acmod, int output); void a52_imdct_init (a52_state_t *a52, uint32_t mm_accel); void a52_imdct_256 (a52_state_t *a52, sample_t * data, sample_t * delay, sample_t bias); void a52_imdct_512 (a52_state_t *a52, sample_t * data, sample_t * delay, sample_t bias); #define ROUND(x) ((int)((x) + ((x) > 0 ? 0.5 : -0.5))) #ifndef LIBA52_FIXED typedef sample_t quantizer_t; # define SAMPLE(x) (x) # define LEVEL(x) (x) # define MUL(a,b) ((a) * (b)) # define MUL_L(a,b) ((a) * (b)) # define MUL_C(a,b) ((a) * (b)) # define DIV(a,b) ((a) / (b)) static inline sample_t minus3db (sample_t v) { return LEVEL_3DB * v; } static inline sample_t minus6db (sample_t v) { return LEVEL_6DB * v; } static inline sample_t plus6db (sample_t v) { return LEVEL_PLUS6DB * v; } #else /* LIBA52_FIXED */ typedef int16_t quantizer_t; # define SAMPLE(x) (sample_t)((x) * (1 << 30)) # define LEVEL(x) (sample_t)((x) * (1 << 26)) # if 0 # define MUL(a,b) ((int)(((int64_t)(a) * (b) + (1 << 29)) >> 30)) # define MUL_L(a,b) ((int)(((int64_t)(a) * (b) + (1 << 25)) >> 26)) # elif 1 # define MUL(a,b) ({ \ int32_t _ta=(a), _tb=(b), _tc; \ _tc = (_ta & 0xffff) * (_tb >> 16) + (_ta >> 16) * (_tb & 0xffff); \ (int32_t)(((_tc >> 14)) + (((_ta >> 16) * (_tb >> 16)) << 2 )); \ }) # define MUL_L(a,b) ({ \ int32_t _ta=(a), _tb=(b), _tc; \ _tc = (_ta & 0xffff) * (_tb >> 16) + (_ta >> 16) * (_tb & 0xffff); \ (int32_t)((_tc >> 10) + (((_ta >> 16) * (_tb >> 16)) << 6)); \ }) # else # define MUL(a,b) (((a) >> 15) * ((b) >> 15)) # define MUL_L(a,b) (((a) >> 13) * ((b) >> 13)) # endif # define MUL_C(a,b) MUL_L (a, LEVEL (b)) # define DIV(a,b) ((((int64_t)LEVEL (a)) << 26) / (b)) static inline sample_t minus3db (sample_t v) { return v - (v >> 8) * 0x4b; } static inline sample_t minus6db (sample_t v) { return v >> 1; } static inline sample_t plus6db (sample_t v) { return v << 1; } #endif xine-lib-1.2/contrib/a52dec/Makefile.am0000644000175000017500000000066714647725151015433 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) if ENABLE_A52DEC if !WITH_EXTERNAL_A52DEC noinst_LTLIBRARIES = liba52.la endif endif liba52_la_SOURCES = \ a52.h \ a52_internal.h \ bitstream.c \ bitstream.h \ bit_allocate.c \ crc.c \ downmix.c \ imdct.c \ parse.c \ tables.h liba52_la_LIBADD = -lm liba52_la_CPPFLAGS = $(AM_CPPFLAGS) $(A52DEC_MATH) xine-lib-1.2/contrib/a52dec/bitstream.h0000644000175000017500000000416114647725151015533 0ustar meme/* * bitstream.h * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef WIN32 #include #endif #ifdef WORDS_BIGENDIAN # define swab32(x) (x) #else /* TJ. gcc 4+ will recognize this as __builtin_bswap32 (). */ # define swab32(x) (((x) << 24) | (((x) & 0xff00) << 8) | (((x) & 0xff0000) >> 8) | ((x) >> 24)) #endif void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf); uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits); int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits); static inline uint32_t bitstream_get (a52_state_t * state, uint32_t num_bits) { uint32_t result; if (num_bits < state->bits_left) { result = state->current_word >> (32 - num_bits); state->current_word <<= num_bits; state->bits_left -= num_bits; return result; } return a52_bitstream_get_bh (state, num_bits); } static inline int32_t bitstream_get_2 (a52_state_t * state, uint32_t num_bits) { int32_t result; if (num_bits < state->bits_left) { result = ((int32_t)state->current_word) >> (32 - num_bits); state->current_word <<= num_bits; state->bits_left -= num_bits; return result; } return a52_bitstream_get_bh_2 (state, num_bits); } xine-lib-1.2/contrib/a52dec/crc.c0000644000175000017500000000567114647725151014312 0ustar meme/* * crc.c * * Copyright (C) Aaron Holtzman - May 1999 * * This file is part of ac3dec, a free Dolby AC-3 stream decoder. * * ac3dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * ac3dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include #include #include static const uint16_t crc_lut[256] = { 0x0000,0x8005,0x800f,0x000a,0x801b,0x001e,0x0014,0x8011, 0x8033,0x0036,0x003c,0x8039,0x0028,0x802d,0x8027,0x0022, 0x8063,0x0066,0x006c,0x8069,0x0078,0x807d,0x8077,0x0072, 0x0050,0x8055,0x805f,0x005a,0x804b,0x004e,0x0044,0x8041, 0x80c3,0x00c6,0x00cc,0x80c9,0x00d8,0x80dd,0x80d7,0x00d2, 0x00f0,0x80f5,0x80ff,0x00fa,0x80eb,0x00ee,0x00e4,0x80e1, 0x00a0,0x80a5,0x80af,0x00aa,0x80bb,0x00be,0x00b4,0x80b1, 0x8093,0x0096,0x009c,0x8099,0x0088,0x808d,0x8087,0x0082, 0x8183,0x0186,0x018c,0x8189,0x0198,0x819d,0x8197,0x0192, 0x01b0,0x81b5,0x81bf,0x01ba,0x81ab,0x01ae,0x01a4,0x81a1, 0x01e0,0x81e5,0x81ef,0x01ea,0x81fb,0x01fe,0x01f4,0x81f1, 0x81d3,0x01d6,0x01dc,0x81d9,0x01c8,0x81cd,0x81c7,0x01c2, 0x0140,0x8145,0x814f,0x014a,0x815b,0x015e,0x0154,0x8151, 0x8173,0x0176,0x017c,0x8179,0x0168,0x816d,0x8167,0x0162, 0x8123,0x0126,0x012c,0x8129,0x0138,0x813d,0x8137,0x0132, 0x0110,0x8115,0x811f,0x011a,0x810b,0x010e,0x0104,0x8101, 0x8303,0x0306,0x030c,0x8309,0x0318,0x831d,0x8317,0x0312, 0x0330,0x8335,0x833f,0x033a,0x832b,0x032e,0x0324,0x8321, 0x0360,0x8365,0x836f,0x036a,0x837b,0x037e,0x0374,0x8371, 0x8353,0x0356,0x035c,0x8359,0x0348,0x834d,0x8347,0x0342, 0x03c0,0x83c5,0x83cf,0x03ca,0x83db,0x03de,0x03d4,0x83d1, 0x83f3,0x03f6,0x03fc,0x83f9,0x03e8,0x83ed,0x83e7,0x03e2, 0x83a3,0x03a6,0x03ac,0x83a9,0x03b8,0x83bd,0x83b7,0x03b2, 0x0390,0x8395,0x839f,0x039a,0x838b,0x038e,0x0384,0x8381, 0x0280,0x8285,0x828f,0x028a,0x829b,0x029e,0x0294,0x8291, 0x82b3,0x02b6,0x02bc,0x82b9,0x02a8,0x82ad,0x82a7,0x02a2, 0x82e3,0x02e6,0x02ec,0x82e9,0x02f8,0x82fd,0x82f7,0x02f2, 0x02d0,0x82d5,0x82df,0x02da,0x82cb,0x02ce,0x02c4,0x82c1, 0x8243,0x0246,0x024c,0x8249,0x0258,0x825d,0x8257,0x0252, 0x0270,0x8275,0x827f,0x027a,0x826b,0x026e,0x0264,0x8261, 0x0220,0x8225,0x822f,0x022a,0x823b,0x023e,0x0234,0x8231, 0x8213,0x0216,0x021c,0x8219,0x0208,0x820d,0x8207,0x0202 }; static uint16_t crc16_block(uint8_t *data,uint32_t num_bytes) { uint32_t i; uint16_t state=0; for(i=0;i>8)] ^ (state<<8); return state; } xine-lib-1.2/contrib/a52dec/parse.c0000644000175000017500000005576414647725151014665 0ustar meme/* * parse.c * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include "a52.h" #include "a52_internal.h" #include "bitstream.h" #include "tables.h" #include typedef struct { quantizer_t q1[2]; quantizer_t q2[2]; quantizer_t q4; int q1_ptr; int q2_ptr; int q4_ptr; } quantizer_set_t; static const uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3}; a52_state_t * a52_init (uint32_t mm_accel) { a52_state_t * state; state = calloc(1, sizeof (a52_state_t)); if (state == NULL) return NULL; state->samples_base = state->samples = xine_mallocz_aligned (256 * 12 * sizeof (sample_t)); if (state->samples == NULL) { free (state); return NULL; } state->downmixed = 1; state->lfsr_state = 1; a52_imdct_init (state, mm_accel); return state; } sample_t * a52_samples (a52_state_t * state) { return state->samples; } int a52_syncinfo (uint8_t * buf, int * flags, int * sample_rate, int * bit_rate) { static const uint16_t rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640}; static const uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01}; int frmsizecod; int bitrate; int half; int acmod; if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */ return 0; if (buf[5] >= 0x60) /* bsid >= 12 */ return 0; half = halfrate[buf[5] >> 3]; /* acmod, dsurmod and lfeon */ acmod = buf[6] >> 5; *flags = ((((buf[6] & 0xf8) == 0x50) ? A52_DOLBY : acmod) | ((buf[6] & lfeon[acmod]) ? A52_LFE : 0)); frmsizecod = buf[4] & 63; if (frmsizecod >= 38) return 0; bitrate = rate [frmsizecod >> 1]; *bit_rate = (bitrate * 1000) >> half; switch (buf[4] & 0xc0) { case 0: *sample_rate = 48000 >> half; return 4 * bitrate; case 0x40: *sample_rate = 44100 >> half; return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); case 0x80: *sample_rate = 32000 >> half; return 6 * bitrate; default: return 0; } } int a52_frame (a52_state_t * state, uint8_t * buf, int * flags, sample_t * level, sample_t bias) { static const sample_t clev[4] = {LEVEL_3DB, LEVEL_45DB, LEVEL_6DB, LEVEL_45DB}; static const sample_t slev[4] = {LEVEL_3DB, LEVEL_6DB, 0, LEVEL_6DB}; int chaninfo; int acmod; state->fscod = buf[4] >> 6; state->halfrate = halfrate[buf[5] >> 3]; state->acmod = acmod = buf[6] >> 5; a52_bitstream_set_ptr (state, buf + 6); bitstream_get (state, 3); /* skip acmod we already parsed */ if ((acmod == 2) && (bitstream_get (state, 2) == 2)) /* dsurmod */ acmod = A52_DOLBY; state->clev = state->slev = 0; if ((acmod & 1) && (acmod != 1)) state->clev = clev[bitstream_get (state, 2)]; /* cmixlev */ if (acmod & 4) state->slev = slev[bitstream_get (state, 2)]; /* surmixlev */ state->lfeon = bitstream_get (state, 1); state->output = a52_downmix_init (acmod, *flags, level, state->clev, state->slev); if (state->output < 0) return 1; if (state->lfeon && (*flags & A52_LFE)) state->output |= A52_LFE; *flags = state->output; /* the 2* compensates for differences in imdct */ state->dynrng = state->level = 2 * *level; state->bias = bias; state->dynrnge = 1; state->dynrngcall = NULL; state->cplba.deltbae = DELTA_BIT_NONE; state->ba[0].deltbae = state->ba[1].deltbae = state->ba[2].deltbae = state->ba[3].deltbae = state->ba[4].deltbae = DELTA_BIT_NONE; chaninfo = !acmod; do { bitstream_get (state, 5); /* dialnorm */ if (bitstream_get (state, 1)) /* compre */ bitstream_get (state, 8); /* compr */ if (bitstream_get (state, 1)) /* langcode */ bitstream_get (state, 8); /* langcod */ if (bitstream_get (state, 1)) /* audprodie */ bitstream_get (state, 7); /* mixlevel + roomtyp */ } while (chaninfo--); bitstream_get (state, 2); /* copyrightb + origbs */ if (bitstream_get (state, 1)) /* timecod1e */ bitstream_get (state, 14); /* timecod1 */ if (bitstream_get (state, 1)) /* timecod2e */ bitstream_get (state, 14); /* timecod2 */ if (bitstream_get (state, 1)) { /* addbsie */ int addbsil; addbsil = bitstream_get (state, 6); do { bitstream_get (state, 8); /* addbsi */ } while (addbsil--); } return 0; } void a52_dynrng (a52_state_t * state, sample_t (* call) (sample_t, void *), void * data) { state->dynrnge = 0; if (call) { state->dynrnge = 1; state->dynrngcall = call; state->dynrngdata = data; } } static int parse_exponents (a52_state_t * state, int expstr, int ngrps, uint8_t exponent, uint8_t * dest) { int exps; while (ngrps--) { exps = bitstream_get (state, 7); exponent += exp_1[exps]; if (exponent > 24) return 1; switch (expstr) { case EXP_D45: *(dest++) = exponent; *(dest++) = exponent; /* fall through */ case EXP_D25: *(dest++) = exponent; /* fall through */ case EXP_D15: *(dest++) = exponent; } exponent += exp_2[exps]; if (exponent > 24) return 1; switch (expstr) { case EXP_D45: *(dest++) = exponent; *(dest++) = exponent; /* fall through */ case EXP_D25: *(dest++) = exponent; /* fall through */ case EXP_D15: *(dest++) = exponent; } exponent += exp_3[exps]; if (exponent > 24) return 1; switch (expstr) { case EXP_D45: *(dest++) = exponent; *(dest++) = exponent; /* fall through */ case EXP_D25: *(dest++) = exponent; /* fall through */ case EXP_D15: *(dest++) = exponent; } } return 0; } static int parse_deltba (a52_state_t * state, int8_t * deltba) { int deltnseg, deltlen, delta, j; memset (deltba, 0, 50); deltnseg = bitstream_get (state, 3); j = 0; do { j += bitstream_get (state, 5); deltlen = bitstream_get (state, 4); delta = bitstream_get (state, 3); delta -= (delta >= 4) ? 3 : 4; if (!deltlen) continue; if (j + deltlen >= 50) return 1; while (deltlen--) deltba[j++] = delta; } while (deltnseg--); return 0; } static inline int zero_snr_offsets (int nfchans, a52_state_t * state) { int i; if ((state->csnroffst) || (state->chincpl && state->cplba.bai >> 3) || /* cplinu, fsnroffst */ (state->lfeon && state->lfeba.bai >> 3)) /* fsnroffst */ return 0; for (i = 0; i < nfchans; i++) if (state->ba[i].bai >> 3) /* fsnroffst */ return 0; return 1; } static inline int16_t dither_gen (a52_state_t * state) { int16_t nstate; nstate = dither_lut[state->lfsr_state >> 8] ^ (state->lfsr_state << 8); state->lfsr_state = (uint16_t) nstate; return nstate; } #ifndef LIBA52_FIXED #define COEFF(c,t,l,s,e) (c) = (t) * (s)[e] #else #define COEFF(c,_t,_l,s,e) do { \ quantizer_t t = (_t); \ sample_t l = (_l); \ int shift = e - 5; \ sample_t tmp = t * (l >> 16) + ((t * (l & 0xffff)) >> 16); \ if (shift >= 0) \ (c) = tmp >> shift; \ else \ (c) = tmp << -shift; \ } while (0) #endif static void coeff_get (a52_state_t * state, sample_t * coeff, expbap_t * expbap, quantizer_set_t * quant, sample_t level, int dither, int end) { int i; uint8_t * exp; int8_t * bap; #ifndef LIBA52_FIXED sample_t factor[25]; for (i = 0; i <= 24; i++) factor[i] = scale_factor[i] * level; #endif exp = expbap->exp; bap = expbap->bap; for (i = 0; i < end; i++) { int bapi; bapi = bap[i]; switch (bapi) { case 0: if (dither) { COEFF (coeff[i], dither_gen (state), minus3db (level), factor, exp[i]); continue; } else { coeff[i] = 0; continue; } case -1: if (quant->q1_ptr >= 0) { COEFF (coeff[i], quant->q1[quant->q1_ptr--], level, factor, exp[i]); continue; } else { int code; code = bitstream_get (state, 5); quant->q1_ptr = 1; quant->q1[0] = q_1_2[code]; quant->q1[1] = q_1_1[code]; COEFF (coeff[i], q_1_0[code], level, factor, exp[i]); continue; } case -2: if (quant->q2_ptr >= 0) { COEFF (coeff[i], quant->q2[quant->q2_ptr--], level, factor, exp[i]); continue; } else { int code; code = bitstream_get (state, 7); quant->q2_ptr = 1; quant->q2[0] = q_2_2[code]; quant->q2[1] = q_2_1[code]; COEFF (coeff[i], q_2_0[code], level, factor, exp[i]); continue; } case 3: COEFF (coeff[i], q_3[bitstream_get (state, 3)], level, factor, exp[i]); continue; case -3: if (quant->q4_ptr == 0) { quant->q4_ptr = -1; COEFF (coeff[i], quant->q4, level, factor, exp[i]); continue; } else { int code; code = bitstream_get (state, 7); quant->q4_ptr = 0; quant->q4 = q_4_1[code]; COEFF (coeff[i], q_4_0[code], level, factor, exp[i]); continue; } case 4: COEFF (coeff[i], q_5[bitstream_get (state, 4)], level, factor, exp[i]); continue; default: COEFF (coeff[i], bitstream_get_2 (state, bapi) << (16 - bapi), level, factor, exp[i]); } } } static void coeff_get_coupling (a52_state_t * state, int nfchans, sample_t * coeff, sample_t (* samples)[256], quantizer_set_t * quantizer, uint8_t dithflag[5]) { int cplbndstrc, bnd, i, i_end, ch; uint8_t * exp; int8_t * bap; sample_t cplco[5]; exp = state->cpl_expbap.exp; bap = state->cpl_expbap.bap; bnd = 0; cplbndstrc = state->cplbndstrc; i = state->cplstrtmant; while (i < state->cplendmant) { i_end = i + 12; while (cplbndstrc & 1) { cplbndstrc >>= 1; i_end += 12; } cplbndstrc >>= 1; for (ch = 0; ch < nfchans; ch++) cplco[ch] = state->cplco[ch][bnd] * coeff[ch]; /* calm down gcc7 */ for (; ch < 5; ch++) cplco[ch] = 0; bnd++; while (i < i_end) { quantizer_t cplcoeff; int bapi; bapi = bap[i]; switch (bapi) { case 0: #ifndef LIBA52_FIXED cplcoeff = LEVEL_3DB * scale_factor[exp[i]]; #endif for (ch = 0; ch < nfchans; ch++) if ((state->chincpl >> ch) & 1) { if (dithflag[ch]) #ifndef LIBA52_FIXED samples[ch][i] = (cplcoeff * cplco[ch] * dither_gen (state)); #else COEFF (samples[ch][i], dither_gen (state), minus3db (cplco[ch]), scale_factor, exp[i]); #endif else samples[ch][i] = 0; } i++; continue; case -1: if (quantizer->q1_ptr >= 0) { cplcoeff = quantizer->q1[quantizer->q1_ptr--]; break; } else { int code; code = bitstream_get (state, 5); quantizer->q1_ptr = 1; quantizer->q1[0] = q_1_2[code]; quantizer->q1[1] = q_1_1[code]; cplcoeff = q_1_0[code]; break; } case -2: if (quantizer->q2_ptr >= 0) { cplcoeff = quantizer->q2[quantizer->q2_ptr--]; break; } else { int code; code = bitstream_get (state, 7); quantizer->q2_ptr = 1; quantizer->q2[0] = q_2_2[code]; quantizer->q2[1] = q_2_1[code]; cplcoeff = q_2_0[code]; break; } case 3: cplcoeff = q_3[bitstream_get (state, 3)]; break; case -3: if (quantizer->q4_ptr == 0) { quantizer->q4_ptr = -1; cplcoeff = quantizer->q4; break; } else { int code; code = bitstream_get (state, 7); quantizer->q4_ptr = 0; quantizer->q4 = q_4_1[code]; cplcoeff = q_4_0[code]; break; } case 4: cplcoeff = q_5[bitstream_get (state, 4)]; break; default: cplcoeff = bitstream_get_2 (state, bapi) << (16 - bapi); } #ifndef LIBA52_FIXED cplcoeff *= scale_factor[exp[i]]; #endif for (ch = 0; ch < nfchans; ch++) if ((state->chincpl >> ch) & 1) #ifndef LIBA52_FIXED samples[ch][i] = cplcoeff * cplco[ch]; #else COEFF (samples[ch][i], cplcoeff, cplco[ch], scale_factor, exp[i]); #endif i++; } } } int a52_block (a52_state_t * state) { static const uint8_t nfchans_tbl[] = {2, 1, 2, 3, 3, 4, 4, 5, 1, 1, 2}; static const uint8_t rematrix_band[4] = {25, 37, 61, 253}; int i, nfchans, chaninfo; uint8_t cplexpstr, chexpstr[5], lfeexpstr, do_bit_alloc, done_cpl; uint8_t blksw[5], dithflag[5]; sample_t coeff[5]; int chanbias; quantizer_set_t quantizer; sample_t * samples; nfchans = nfchans_tbl[state->acmod]; for (i = 0; i < nfchans; i++) blksw[i] = bitstream_get (state, 1); for (i = 0; i < nfchans; i++) dithflag[i] = bitstream_get (state, 1); chaninfo = !state->acmod; do { if (bitstream_get (state, 1)) { /* dynrnge */ int dynrng; dynrng = bitstream_get_2 (state, 8); if (state->dynrnge) { sample_t range; #ifndef LIBA52_FIXED range = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factor[3 - (dynrng >> 5)]); #else range = ((dynrng & 0x1f) | 0x20) << (21 + (dynrng >> 5)); #endif if (state->dynrngcall) range = state->dynrngcall (range, state->dynrngdata); state->dynrng = state->level * range; } } } while (chaninfo--); if (bitstream_get (state, 1)) { /* cplstre */ state->chincpl = 0; if (bitstream_get (state, 1)) { /* cplinu */ static const uint8_t bndtab[16] = {31, 35, 37, 39, 41, 42, 43, 44, 45, 45, 46, 46, 47, 47, 48, 48}; int cplbegf; int cplendf; int ncplsubnd; for (i = 0; i < nfchans; i++) state->chincpl |= bitstream_get (state, 1) << i; switch (state->acmod) { case 0: case 1: return 1; case 2: state->phsflginu = bitstream_get (state, 1); } cplbegf = bitstream_get (state, 4); cplendf = bitstream_get (state, 4); if (cplendf + 3 - cplbegf < 0) return 1; state->ncplbnd = ncplsubnd = cplendf + 3 - cplbegf; state->cplstrtbnd = bndtab[cplbegf]; state->cplstrtmant = cplbegf * 12 + 37; state->cplendmant = cplendf * 12 + 73; state->cplbndstrc = 0; for (i = 0; i < ncplsubnd - 1; i++) if (bitstream_get (state, 1)) { state->cplbndstrc |= 1 << i; state->ncplbnd--; } } } if (state->chincpl) { /* cplinu */ int j, cplcoe; cplcoe = 0; for (i = 0; i < nfchans; i++) if ((state->chincpl) >> i & 1) if (bitstream_get (state, 1)) { /* cplcoe */ int mstrcplco, cplcoexp, cplcomant; cplcoe = 1; mstrcplco = 3 * bitstream_get (state, 2); for (j = 0; j < state->ncplbnd; j++) { cplcoexp = bitstream_get (state, 4); cplcomant = bitstream_get (state, 4); if (cplcoexp == 15) cplcomant <<= 14; else cplcomant = (cplcomant | 0x10) << 13; #ifndef LIBA52_FIXED state->cplco[i][j] = cplcomant * scale_factor[cplcoexp + mstrcplco]; #else state->cplco[i][j] = (cplcomant << 11) >> (cplcoexp + mstrcplco); #endif } } if ((state->acmod == 2) && state->phsflginu && cplcoe) for (j = 0; j < state->ncplbnd; j++) if (bitstream_get (state, 1)) /* phsflg */ state->cplco[1][j] = -state->cplco[1][j]; } if ((state->acmod == 2) && (bitstream_get (state, 1))) { /* rematstr */ int end; state->rematflg = 0; end = (state->chincpl) ? state->cplstrtmant : 253; /* cplinu */ i = 0; do state->rematflg |= bitstream_get (state, 1) << i; while (rematrix_band[i++] < end); } cplexpstr = EXP_REUSE; lfeexpstr = EXP_REUSE; if (state->chincpl) /* cplinu */ cplexpstr = bitstream_get (state, 2); for (i = 0; i < nfchans; i++) chexpstr[i] = bitstream_get (state, 2); if (state->lfeon) lfeexpstr = bitstream_get (state, 1); for (i = 0; i < nfchans; i++) if (chexpstr[i] != EXP_REUSE) { if ((state->chincpl >> i) & 1) state->endmant[i] = state->cplstrtmant; else { int chbwcod; chbwcod = bitstream_get (state, 6); if (chbwcod > 60) return 1; state->endmant[i] = chbwcod * 3 + 73; } } do_bit_alloc = 0; if (cplexpstr != EXP_REUSE) { int cplabsexp, ncplgrps; do_bit_alloc = 64; ncplgrps = ((state->cplendmant - state->cplstrtmant) / (3 << (cplexpstr - 1))); cplabsexp = bitstream_get (state, 4) << 1; if (parse_exponents (state, cplexpstr, ncplgrps, cplabsexp, state->cpl_expbap.exp + state->cplstrtmant)) return 1; } for (i = 0; i < nfchans; i++) if (chexpstr[i] != EXP_REUSE) { int grp_size, nchgrps; do_bit_alloc |= 1 << i; grp_size = 3 << (chexpstr[i] - 1); nchgrps = (state->endmant[i] + grp_size - 4) / grp_size; state->fbw_expbap[i].exp[0] = bitstream_get (state, 4); if (parse_exponents (state, chexpstr[i], nchgrps, state->fbw_expbap[i].exp[0], state->fbw_expbap[i].exp + 1)) return 1; bitstream_get (state, 2); /* gainrng */ } if (lfeexpstr != EXP_REUSE) { do_bit_alloc |= 32; state->lfe_expbap.exp[0] = bitstream_get (state, 4); if (parse_exponents (state, lfeexpstr, 2, state->lfe_expbap.exp[0], state->lfe_expbap.exp + 1)) return 1; } if (bitstream_get (state, 1)) { /* baie */ do_bit_alloc = -1; state->bai = bitstream_get (state, 11); } if (bitstream_get (state, 1)) { /* snroffste */ do_bit_alloc = -1; state->csnroffst = bitstream_get (state, 6); if (state->chincpl) /* cplinu */ state->cplba.bai = bitstream_get (state, 7); for (i = 0; i < nfchans; i++) state->ba[i].bai = bitstream_get (state, 7); if (state->lfeon) state->lfeba.bai = bitstream_get (state, 7); } if ((state->chincpl) && (bitstream_get (state, 1))) { /* cplleake */ do_bit_alloc |= 64; state->cplfleak = 9 - bitstream_get (state, 3); state->cplsleak = 9 - bitstream_get (state, 3); } if (bitstream_get (state, 1)) { /* deltbaie */ do_bit_alloc = -1; if (state->chincpl) /* cplinu */ state->cplba.deltbae = bitstream_get (state, 2); for (i = 0; i < nfchans; i++) state->ba[i].deltbae = bitstream_get (state, 2); if (state->chincpl && /* cplinu */ (state->cplba.deltbae == DELTA_BIT_NEW) && parse_deltba (state, state->cplba.deltba)) return 1; for (i = 0; i < nfchans; i++) if ((state->ba[i].deltbae == DELTA_BIT_NEW) && parse_deltba (state, state->ba[i].deltba)) return 1; } if (do_bit_alloc) { if (zero_snr_offsets (nfchans, state)) { memset (state->cpl_expbap.bap, 0, sizeof (state->cpl_expbap.bap)); for (i = 0; i < nfchans; i++) memset (state->fbw_expbap[i].bap, 0, sizeof (state->fbw_expbap[i].bap)); memset (state->lfe_expbap.bap, 0, sizeof (state->lfe_expbap.bap)); } else { if (state->chincpl && (do_bit_alloc & 64)) /* cplinu */ a52_bit_allocate (state, &state->cplba, state->cplstrtbnd, state->cplstrtmant, state->cplendmant, state->cplfleak << 8, state->cplsleak << 8, &state->cpl_expbap); for (i = 0; i < nfchans; i++) if (do_bit_alloc & (1 << i)) a52_bit_allocate (state, state->ba + i, 0, 0, state->endmant[i], 0, 0, state->fbw_expbap +i); if (state->lfeon && (do_bit_alloc & 32)) { state->lfeba.deltbae = DELTA_BIT_NONE; a52_bit_allocate (state, &state->lfeba, 0, 0, 7, 0, 0, &state->lfe_expbap); } } } if (bitstream_get (state, 1)) { /* skiple */ i = bitstream_get (state, 9); /* skipl */ while (i--) bitstream_get (state, 8); } samples = state->samples; if (state->output & A52_LFE) samples += 256; /* shift for LFE channel */ chanbias = a52_downmix_coeff (coeff, state->acmod, state->output, state->dynrng, state->clev, state->slev); quantizer.q1_ptr = quantizer.q2_ptr = quantizer.q4_ptr = -1; done_cpl = 0; for (i = 0; i < nfchans; i++) { int j; coeff_get (state, samples + 256 * i, state->fbw_expbap +i, &quantizer, coeff[i], dithflag[i], state->endmant[i]); if ((state->chincpl >> i) & 1) { if (!done_cpl) { done_cpl = 1; coeff_get_coupling (state, nfchans, coeff, (sample_t (*)[256])samples, &quantizer, dithflag); } j = state->cplendmant; } else j = state->endmant[i]; do (samples + 256 * i)[j] = 0; while (++j < 256); } if (state->acmod == 2) { int j, end, band, rematflg; end = ((state->endmant[0] < state->endmant[1]) ? state->endmant[0] : state->endmant[1]); i = 0; j = 13; rematflg = state->rematflg; do { if (! (rematflg & 1)) { rematflg >>= 1; j = rematrix_band[i++]; continue; } rematflg >>= 1; band = rematrix_band[i++]; if (band > end) band = end; do { sample_t tmp0, tmp1; tmp0 = samples[j]; tmp1 = (samples+256)[j]; samples[j] = tmp0 + tmp1; (samples+256)[j] = tmp0 - tmp1; } while (++j < band); } while (j < end); } if (state->lfeon) { if (state->output & A52_LFE) { coeff_get (state, samples - 256, &state->lfe_expbap, &quantizer, state->dynrng, 0, 7); for (i = 7; i < 256; i++) (samples-256)[i] = 0; a52_imdct_512 (state, samples - 256, samples + 1536 - 256, state->bias); } else { /* just skip the LFE coefficients */ coeff_get (state, samples + 1280, &state->lfe_expbap, &quantizer, 0, 0, 7); } } i = 0; if (nfchans_tbl[state->output & A52_CHANNEL_MASK] < nfchans) for (i = 1; i < nfchans; i++) if (blksw[i] != blksw[0]) break; if (i < nfchans) { if (state->downmixed) { state->downmixed = 0; a52_upmix (samples + 1536, state->acmod, state->output); } for (i = 0; i < nfchans; i++) { sample_t bias; bias = 0; if (!(chanbias & (1 << i))) bias = state->bias; if (coeff[i]) { if (blksw[i]) a52_imdct_256 (state, samples + 256 * i, samples + 1536 + 256 * i, bias); else a52_imdct_512 (state, samples + 256 * i, samples + 1536 + 256 * i, bias); } else { int j; for (j = 0; j < 256; j++) (samples + 256 * i)[j] = bias; } } a52_downmix (samples, state->acmod, state->output, state->bias, state->clev, state->slev); } else { nfchans = nfchans_tbl[state->output & A52_CHANNEL_MASK]; a52_downmix (samples, state->acmod, state->output, 0, state->clev, state->slev); if (!state->downmixed) { state->downmixed = 1; a52_downmix (samples + 1536, state->acmod, state->output, 0, state->clev, state->slev); } if (blksw[0]) for (i = 0; i < nfchans; i++) a52_imdct_256 (state, samples + 256 * i, samples + 1536 + 256 * i, state->bias); else for (i = 0; i < nfchans; i++) a52_imdct_512 (state, samples + 256 * i, samples + 1536 + 256 * i, state->bias); } return 0; } void a52_free (a52_state_t * state) { xine_free_aligned (state->samples_base); free (state); } xine-lib-1.2/contrib/a52dec/downmix.c0000644000175000017500000004350614647725151015227 0ustar meme/* * downmix.c * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include "a52.h" #include "a52_internal.h" #ifdef LIBA52_FIXED # define PLUS_BIAS # define VOID_BIAS (void)bias #else # define PLUS_BIAS + bias # define VOID_BIAS #endif #define CONVERT(acmod,output) (((output) << 3) + (acmod)) int a52_downmix_init (int input, int flags, sample_t * level, sample_t clev, sample_t slev) { static const uint8_t table[11][8] = { {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO}, {A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO, A52_STEREO}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, A52_STEREO, A52_3F, A52_STEREO, A52_3F}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_2F1R, A52_2F1R, A52_2F1R, A52_2F1R}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_STEREO, A52_2F1R, A52_3F1R, A52_2F1R, A52_3F1R}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, A52_2F2R, A52_2F2R, A52_2F2R, A52_2F2R}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_3F, A52_2F2R, A52_3F2R, A52_2F2R, A52_3F2R}, {A52_CHANNEL1, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO}, {A52_CHANNEL2, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO, A52_MONO}, {A52_CHANNEL, A52_DOLBY, A52_STEREO, A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY, A52_DOLBY} }; int output; output = flags & A52_CHANNEL_MASK; if (output > A52_DOLBY) return -1; output = table[output][input & 7]; if ((output == A52_STEREO) && ((input == A52_DOLBY) || ((input == A52_3F) && (clev == LEVEL_3DB)))) output = A52_DOLBY; if (flags & A52_ADJUST_LEVEL) { sample_t adjust; switch (CONVERT (input & 7, output)) { case CONVERT (A52_3F, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev); break; case CONVERT (A52_STEREO, A52_MONO): case CONVERT (A52_2F2R, A52_2F1R): case CONVERT (A52_3F2R, A52_3F1R): level_3db: adjust = LEVEL (LEVEL_3DB); break; case CONVERT (A52_3F2R, A52_2F1R): if (clev < LEVEL_PLUS3DB - 1) goto level_3db; /* fall through */ case CONVERT (A52_3F, A52_STEREO): case CONVERT (A52_3F1R, A52_2F1R): case CONVERT (A52_3F1R, A52_2F2R): case CONVERT (A52_3F2R, A52_2F2R): adjust = DIV (1, LEVEL (1) + clev); break; case CONVERT (A52_2F1R, A52_MONO): adjust = DIV (LEVEL_PLUS3DB, LEVEL (2) + slev); break; case CONVERT (A52_2F1R, A52_STEREO): case CONVERT (A52_3F1R, A52_3F): adjust = DIV (1, LEVEL (1) + MUL_C (slev, LEVEL_3DB)); break; case CONVERT (A52_3F1R, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + MUL_C (slev, 0.5)); break; case CONVERT (A52_3F1R, A52_STEREO): adjust = DIV (1, LEVEL (1) + clev + MUL_C (slev, LEVEL_3DB)); break; case CONVERT (A52_2F2R, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + slev); break; case CONVERT (A52_2F2R, A52_STEREO): case CONVERT (A52_3F2R, A52_3F): adjust = DIV (1, LEVEL (1) + slev); break; case CONVERT (A52_3F2R, A52_MONO): adjust = DIV (LEVEL_3DB, LEVEL (1) + clev + slev); break; case CONVERT (A52_3F2R, A52_STEREO): adjust = DIV (1, LEVEL (1) + clev + slev); break; case CONVERT (A52_MONO, A52_DOLBY): adjust = LEVEL (LEVEL_PLUS3DB); break; case CONVERT (A52_3F, A52_DOLBY): case CONVERT (A52_2F1R, A52_DOLBY): adjust = LEVEL (1 / (1 + LEVEL_3DB)); break; case CONVERT (A52_3F1R, A52_DOLBY): case CONVERT (A52_2F2R, A52_DOLBY): adjust = LEVEL (1 / (1 + 2 * LEVEL_3DB)); break; case CONVERT (A52_3F2R, A52_DOLBY): adjust = LEVEL (1 / (1 + 3 * LEVEL_3DB)); break; default: adjust = LEVEL (1); } *level = MUL_L (*level, adjust); } return output; } int a52_downmix_coeff (sample_t * coeff, int acmod, int output, sample_t level, sample_t clev, sample_t slev) { sample_t level_3db = minus3db (level); switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) { case CONVERT (A52_CHANNEL, A52_CHANNEL): case CONVERT (A52_MONO, A52_MONO): case CONVERT (A52_STEREO, A52_STEREO): case CONVERT (A52_3F, A52_3F): case CONVERT (A52_2F1R, A52_2F1R): case CONVERT (A52_3F1R, A52_3F1R): case CONVERT (A52_2F2R, A52_2F2R): case CONVERT (A52_3F2R, A52_3F2R): case CONVERT (A52_STEREO, A52_DOLBY): coeff[0] = coeff[1] = coeff[2] = coeff[3] = coeff[4] = level; return 0; case CONVERT (A52_CHANNEL, A52_MONO): coeff[0] = coeff[1] = minus6db (level); return 3; case CONVERT (A52_STEREO, A52_MONO): coeff[0] = coeff[1] = level_3db; return 3; case CONVERT (A52_3F, A52_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = plus6db (MUL_L (level_3db, clev)); return 7; case CONVERT (A52_2F1R, A52_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (A52_2F2R, A52_MONO): coeff[0] = coeff[1] = level_3db; coeff[2] = coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (A52_3F1R, A52_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = plus6db (MUL_L (level_3db, clev)); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (A52_3F2R, A52_MONO): coeff[0] = coeff[2] = level_3db; coeff[1] = plus6db (MUL_L (level_3db, clev)); coeff[3] = coeff[4] = MUL_L (level_3db, slev); return 31; case CONVERT (A52_MONO, A52_DOLBY): coeff[0] = level_3db; return 0; case CONVERT (A52_3F, A52_DOLBY): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = level_3db; return 7; case CONVERT (A52_3F, A52_STEREO): case CONVERT (A52_3F1R, A52_2F1R): case CONVERT (A52_3F2R, A52_2F2R): coeff[0] = coeff[2] = coeff[3] = coeff[4] = level; coeff[1] = MUL_L (level, clev); return 7; case CONVERT (A52_2F1R, A52_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 7; case CONVERT (A52_2F1R, A52_STEREO): coeff[0] = coeff[1] = level; coeff[2] = MUL_L (level_3db, slev); return 7; case CONVERT (A52_3F1R, A52_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = level_3db; return 15; case CONVERT (A52_3F1R, A52_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = MUL_L (level_3db, slev); return 15; case CONVERT (A52_2F2R, A52_DOLBY): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 15; case CONVERT (A52_2F2R, A52_STEREO): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = MUL_L (level, slev); return 15; case CONVERT (A52_3F2R, A52_DOLBY): coeff[0] = coeff[2] = level; coeff[1] = coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (A52_3F2R, A52_2F1R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = level_3db; return 31; case CONVERT (A52_3F2R, A52_STEREO): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = coeff[4] = MUL_L (level, slev); return 31; case CONVERT (A52_3F1R, A52_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = MUL_L (level_3db, slev); return 13; case CONVERT (A52_3F2R, A52_3F): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = MUL_L (level, slev); return 29; case CONVERT (A52_2F2R, A52_2F1R): coeff[0] = coeff[1] = level; coeff[2] = coeff[3] = level_3db; return 12; case CONVERT (A52_3F2R, A52_3F1R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = coeff[4] = level_3db; return 24; case CONVERT (A52_2F1R, A52_2F2R): coeff[0] = coeff[1] = level; coeff[2] = level_3db; return 0; case CONVERT (A52_3F1R, A52_2F2R): coeff[0] = coeff[2] = level; coeff[1] = MUL_L (level, clev); coeff[3] = level_3db; return 7; case CONVERT (A52_3F1R, A52_3F2R): coeff[0] = coeff[1] = coeff[2] = level; coeff[3] = level_3db; return 0; case CONVERT (A52_CHANNEL, A52_CHANNEL1): coeff[0] = level; coeff[1] = 0; return 0; case CONVERT (A52_CHANNEL, A52_CHANNEL2): coeff[0] = 0; coeff[1] = level; return 0; } return -1; /* NOTREACHED */ } static void mix2to1 (sample_t * dest, sample_t * src, sample_t bias) { int i; VOID_BIAS; for (i = 0; i < 256; i++) dest[i] += src[i] PLUS_BIAS; } static void mix3to1 (sample_t * samples, sample_t bias) { int i; VOID_BIAS; for (i = 0; i < 256; i++) samples[i] += samples[i + 256] + samples[i + 512] PLUS_BIAS; } static void mix4to1 (sample_t * samples, sample_t bias) { int i; VOID_BIAS; for (i = 0; i < 256; i++) samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768] PLUS_BIAS); } static void mix5to1 (sample_t * samples, sample_t bias) { int i; VOID_BIAS; for (i = 0; i < 256; i++) samples[i] += (samples[i + 256] + samples[i + 512] + samples[i + 768] + samples[i + 1024] PLUS_BIAS); } static void mix3to2 (sample_t * samples, sample_t bias) { int i; sample_t common; VOID_BIAS; for (i = 0; i < 256; i++) { common = samples[i + 256] PLUS_BIAS; samples[i] += common; samples[i + 256] = samples[i + 512] + common; } } static void mix21to2 (sample_t * left, sample_t * right, sample_t bias) { int i; sample_t common; VOID_BIAS; for (i = 0; i < 256; i++) { common = right[i + 256] PLUS_BIAS; left[i] += common; right[i] += common; } } static void mix21toS (sample_t * samples, sample_t bias) { int i; sample_t surround; VOID_BIAS; for (i = 0; i < 256; i++) { surround = samples[i + 512]; samples[i] += -surround PLUS_BIAS; samples[i + 256] += surround PLUS_BIAS; } } static void mix31to2 (sample_t * samples, sample_t bias) { int i; sample_t common; VOID_BIAS; for (i = 0; i < 256; i++) { common = samples[i + 256] + samples[i + 768] PLUS_BIAS; samples[i] += common; samples[i + 256] = samples[i + 512] + common; } } static void mix31toS (sample_t * samples, sample_t bias) { int i; sample_t common, surround; VOID_BIAS; for (i = 0; i < 256; i++) { common = samples[i + 256] PLUS_BIAS; surround = samples[i + 768]; samples[i] += common - surround; samples[i + 256] = samples[i + 512] + common + surround; } } static void mix22toS (sample_t * samples, sample_t bias) { int i; sample_t surround; VOID_BIAS; for (i = 0; i < 256; i++) { surround = samples[i + 512] + samples[i + 768]; samples[i] += -surround PLUS_BIAS; samples[i + 256] += surround PLUS_BIAS; } } static void mix32to2 (sample_t * samples, sample_t bias) { int i; sample_t common; VOID_BIAS; for (i = 0; i < 256; i++) { common = samples[i + 256] PLUS_BIAS; samples[i] += common + samples[i + 768]; samples[i + 256] = common + samples[i + 512] + samples[i + 1024]; } } static void mix32toS (sample_t * samples, sample_t bias) { int i; sample_t common, surround; VOID_BIAS; for (i = 0; i < 256; i++) { common = samples[i + 256] PLUS_BIAS; surround = samples[i + 768] + samples[i + 1024]; samples[i] += common - surround; samples[i + 256] = samples[i + 512] + common + surround; } } static void move2to1 (sample_t * src, sample_t * dest, sample_t bias) { int i; VOID_BIAS; for (i = 0; i < 256; i++) dest[i] = src[i] + src[i + 256] PLUS_BIAS; } static void zero (sample_t * samples) { int i; for (i = 0; i < 256; i++) samples[i] = 0; } void a52_downmix (sample_t * samples, int acmod, int output, sample_t bias, sample_t clev, sample_t slev) { /* ?? */ (void)clev; switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) { case CONVERT (A52_CHANNEL, A52_CHANNEL2): memcpy (samples, samples + 256, 256 * sizeof (sample_t)); break; case CONVERT (A52_CHANNEL, A52_MONO): case CONVERT (A52_STEREO, A52_MONO): mix_2to1: mix2to1 (samples, samples + 256, bias); break; case CONVERT (A52_2F1R, A52_MONO): if (slev == 0) goto mix_2to1; /* fall through */ case CONVERT (A52_3F, A52_MONO): mix_3to1: mix3to1 (samples, bias); break; case CONVERT (A52_3F1R, A52_MONO): if (slev == 0) goto mix_3to1; /* fall through */ case CONVERT (A52_2F2R, A52_MONO): if (slev == 0) goto mix_2to1; /* fall through */ mix4to1 (samples, bias); break; case CONVERT (A52_3F2R, A52_MONO): if (slev == 0) goto mix_3to1; /* fall through */ mix5to1 (samples, bias); break; case CONVERT (A52_MONO, A52_DOLBY): memcpy (samples + 256, samples, 256 * sizeof (sample_t)); break; case CONVERT (A52_3F, A52_STEREO): case CONVERT (A52_3F, A52_DOLBY): mix_3to2: mix3to2 (samples, bias); break; case CONVERT (A52_2F1R, A52_STEREO): if (slev == 0) break; mix21to2 (samples, samples + 256, bias); break; case CONVERT (A52_2F1R, A52_DOLBY): mix21toS (samples, bias); break; case CONVERT (A52_3F1R, A52_STEREO): if (slev == 0) goto mix_3to2; /* fall through */ mix31to2 (samples, bias); break; case CONVERT (A52_3F1R, A52_DOLBY): mix31toS (samples, bias); break; case CONVERT (A52_2F2R, A52_STEREO): if (slev == 0) break; mix2to1 (samples, samples + 512, bias); mix2to1 (samples + 256, samples + 768, bias); break; case CONVERT (A52_2F2R, A52_DOLBY): mix22toS (samples, bias); break; case CONVERT (A52_3F2R, A52_STEREO): if (slev == 0) goto mix_3to2; mix32to2 (samples, bias); break; case CONVERT (A52_3F2R, A52_DOLBY): mix32toS (samples, bias); break; case CONVERT (A52_3F1R, A52_3F): if (slev == 0) break; mix21to2 (samples, samples + 512, bias); break; case CONVERT (A52_3F2R, A52_3F): if (slev == 0) break; mix2to1 (samples, samples + 768, bias); mix2to1 (samples + 512, samples + 1024, bias); break; case CONVERT (A52_3F1R, A52_2F1R): mix3to2 (samples, bias); memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); break; case CONVERT (A52_2F2R, A52_2F1R): mix2to1 (samples + 512, samples + 768, bias); break; case CONVERT (A52_3F2R, A52_2F1R): mix3to2 (samples, bias); move2to1 (samples + 768, samples + 512, bias); break; case CONVERT (A52_3F2R, A52_3F1R): mix2to1 (samples + 768, samples + 1024, bias); break; case CONVERT (A52_2F1R, A52_2F2R): memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t)); break; case CONVERT (A52_3F1R, A52_2F2R): mix3to2 (samples, bias); memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); break; case CONVERT (A52_3F2R, A52_2F2R): mix3to2 (samples, bias); memcpy (samples + 512, samples + 768, 256 * sizeof (sample_t)); memcpy (samples + 768, samples + 1024, 256 * sizeof (sample_t)); break; case CONVERT (A52_3F1R, A52_3F2R): memcpy (samples + 1027, samples + 768, 256 * sizeof (sample_t)); break; } } void a52_upmix (sample_t * samples, int acmod, int output) { switch (CONVERT (acmod, output & A52_CHANNEL_MASK)) { case CONVERT (A52_CHANNEL, A52_CHANNEL2): memcpy (samples + 256, samples, 256 * sizeof (sample_t)); break; case CONVERT (A52_3F2R, A52_MONO): zero (samples + 1024); /* fall through */ case CONVERT (A52_3F1R, A52_MONO): case CONVERT (A52_2F2R, A52_MONO): zero (samples + 768); /* fall through */ case CONVERT (A52_3F, A52_MONO): case CONVERT (A52_2F1R, A52_MONO): zero (samples + 512); /* fall through */ case CONVERT (A52_CHANNEL, A52_MONO): case CONVERT (A52_STEREO, A52_MONO): zero (samples + 256); break; case CONVERT (A52_3F2R, A52_STEREO): case CONVERT (A52_3F2R, A52_DOLBY): zero (samples + 1024); /* fall through */ case CONVERT (A52_3F1R, A52_STEREO): case CONVERT (A52_3F1R, A52_DOLBY): zero (samples + 768); /* fall through */ case CONVERT (A52_3F, A52_STEREO): case CONVERT (A52_3F, A52_DOLBY): mix_3to2: memcpy (samples + 512, samples + 256, 256 * sizeof (sample_t)); zero (samples + 256); break; case CONVERT (A52_2F2R, A52_STEREO): case CONVERT (A52_2F2R, A52_DOLBY): zero (samples + 768); /* fall through */ case CONVERT (A52_2F1R, A52_STEREO): case CONVERT (A52_2F1R, A52_DOLBY): zero (samples + 512); break; case CONVERT (A52_3F2R, A52_3F): zero (samples + 1024); /* fall through */ case CONVERT (A52_3F1R, A52_3F): case CONVERT (A52_2F2R, A52_2F1R): zero (samples + 768); break; case CONVERT (A52_3F2R, A52_3F1R): zero (samples + 1024); break; case CONVERT (A52_3F2R, A52_2F1R): zero (samples + 1024); /* fall through */ case CONVERT (A52_3F1R, A52_2F1R): mix_31to21: memcpy (samples + 768, samples + 512, 256 * sizeof (sample_t)); goto mix_3to2; case CONVERT (A52_3F2R, A52_2F2R): memcpy (samples + 1024, samples + 768, 256 * sizeof (sample_t)); goto mix_31to21; } } xine-lib-1.2/contrib/a52dec/diff_against_release.patch0000644000175000017500000000346314647725151020533 0ustar meme--- src/liba52/a52_internal.h Sun Jul 28 03:52:06 2002 +++ src/liba52/a52_internal.h Wed Aug 28 19:01:05 2002 @@ -84,6 +84,7 @@ expbap_t lfe_expbap; sample_t * samples; + void * samples_base; int downmixed; }; --- src/liba52/imdct.c Sun Jul 28 03:52:07 2002 +++ src/liba52/imdct.c Wed Aug 28 18:55:38 2002 @@ -38,7 +38,7 @@ #include "a52.h" #include "a52_internal.h" -#include "mm_accel.h" +#include "xineutils.h" typedef struct complex_s { sample_t real; @@ -425,7 +425,6 @@ } else #endif { - fprintf (stderr, "liba52:No accelerated IMDCT transform found\n"); ifft128 = ifft128_c; ifft64 = ifft64_c; } --- src/liba52/parse.c Sun Jul 28 03:52:07 2002 +++ src/liba52/parse.c Wed Aug 28 19:02:21 2002 @@ -31,14 +31,7 @@ #include "a52_internal.h" #include "bitstream.h" #include "tables.h" - -#ifdef HAVE_MEMALIGN -/* some systems have memalign() but no declaration for it */ -void * memalign (size_t align, size_t size); -#else -/* assume malloc alignment is sufficient */ -#define memalign(align,size) malloc (size) -#endif +#include "xineutils.h" typedef struct { sample_t q1[2]; @@ -60,7 +53,7 @@ if (state == NULL) return NULL; - state->samples = memalign (16, 256 * 12 * sizeof (sample_t)); + state->samples = xine_xmalloc_aligned (16, 256 * 12 * sizeof (sample_t), &state->samples_base); if (state->samples == NULL) { free (state); return NULL; @@ -896,6 +889,6 @@ void a52_free (a52_state_t * state) { - free (state->samples); + free (state->samples_base); free (state); } --- src/liba52/bitstream.h +++ src/liba52/bitstream.h @@ -21,6 +21,10 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifdef WIN32 +#include +#endif + /* (stolen from the kernel) */ #ifdef WORDS_BIGENDIAN xine-lib-1.2/contrib/a52dec/bit_allocate.c0000644000175000017500000002254714647725151016166 0ustar meme/* * bit_allocate.c * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include "a52.h" #include "a52_internal.h" static const uint16_t hthtab[3][50] = { {0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0, 0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0}, {0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820, 0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0}, {0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850, 0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720} }; static const int8_t baptab[305] = { 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, 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, /* 93 padding elems */ 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14, 14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5, 5, 4, 4, -3, -3, 3, 3, 3, -2, -2, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 148 padding elems */ }; static const uint8_t bndtab[30] = { 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 }; static const int8_t latab[256] = { -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53, -52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44, -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35, -35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28, -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22, -22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18, -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14, -13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11, -10, -10, -10, -10, -10, -9, -9, -9, -9, -9, -8, -8, -8, -8, -8, -8, -7, -7, -7, -7, -7, -7, -6, -6, -6, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5, -5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define UPDATE_LEAK() \ do { \ fastleak += fdecay; \ if (fastleak > psd + fgain) \ fastleak = psd + fgain; \ slowleak += sdecay; \ if (slowleak > psd + sgain) \ slowleak = psd + sgain; \ } while (0) #define COMPUTE_MASK() \ do { \ if (psd > dbknee) \ mask -= (psd - dbknee) >> 2; \ if (mask > hth [i >> halfrate]) \ mask = hth [i >> halfrate]; \ mask -= snroffset + 128 * deltba[i]; \ mask = (mask > 0) ? 0 : ((-mask) >> 5); \ mask -= floor; \ } while (0) void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart, int start, int end, int fastleak, int slowleak, expbap_t * expbap) { static const uint16_t slowgain[4] = {0x540, 0x4d8, 0x478, 0x410}; static const uint16_t dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100}; static const uint16_t floortab[8] = {0x910, 0x950, 0x990, 0x9d0, 0xa10, 0xa90, 0xb10, 0x1400}; int i, j; uint8_t * exp; int8_t * bap; int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset; int psd, mask; const int8_t * deltba; const uint16_t * hth; int halfrate; halfrate = state->halfrate; fdecay = (63 + 20 * ((state->bai >> 7) & 3)) >> halfrate; /* fdcycod */ fgain = 128 + 128 * (ba->bai & 7); /* fgaincod */ sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate; /* sdcycod */ sgain = slowgain[(state->bai >> 5) & 3]; /* sgaincod */ dbknee = dbpbtab[(state->bai >> 3) & 3]; /* dbpbcod */ hth = hthtab[state->fscod]; /* * if there is no delta bit allocation, make deltba point to an area * known to contain zeroes. baptab+156 here. */ deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba; floor = floortab[state->bai & 7]; /* floorcod */ snroffset = 960 - 64 * state->csnroffst - 4 * (ba->bai >> 3) + floor; floor >>= 5; exp = expbap->exp; bap = expbap->bap; i = bndstart; j = start; if (start == 0) { /* not the coupling channel */ int lowcomp; lowcomp = 0; j = end - 1; do { if (i < j) { if (exp[i+1] == exp[i] - 2) lowcomp = 384; else if (lowcomp && (exp[i+1] > exp[i])) lowcomp -= 64; } psd = 128 * exp[i]; mask = psd + fgain + lowcomp; COMPUTE_MASK (); bap[i] = (baptab+156)[mask + 4 * exp[i]]; i++; } while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1]))); fastleak = psd + fgain; slowleak = psd + sgain; while (i < 7) { if (i < j) { if (exp[i+1] == exp[i] - 2) lowcomp = 384; else if (lowcomp && (exp[i+1] > exp[i])) lowcomp -= 64; } psd = 128 * exp[i]; UPDATE_LEAK (); mask = ((fastleak + lowcomp < slowleak) ? fastleak + lowcomp : slowleak); COMPUTE_MASK (); bap[i] = (baptab+156)[mask + 4 * exp[i]]; i++; } if (end == 7) /* lfe channel */ return; do { if (exp[i+1] == exp[i] - 2) lowcomp = 320; else if (lowcomp && (exp[i+1] > exp[i])) lowcomp -= 64; psd = 128 * exp[i]; UPDATE_LEAK (); mask = ((fastleak + lowcomp < slowleak) ? fastleak + lowcomp : slowleak); COMPUTE_MASK (); bap[i] = (baptab+156)[mask + 4 * exp[i]]; i++; } while (i < 20); while (lowcomp > 128) { /* two iterations maximum */ lowcomp -= 128; psd = 128 * exp[i]; UPDATE_LEAK (); mask = ((fastleak + lowcomp < slowleak) ? fastleak + lowcomp : slowleak); COMPUTE_MASK (); bap[i] = (baptab+156)[mask + 4 * exp[i]]; i++; } j = i; } do { int startband, endband; startband = j; endband = ((bndtab-20)[i] < end) ? (bndtab-20)[i] : end; psd = 128 * exp[j++]; while (j < endband) { int next, delta; next = 128 * exp[j++]; delta = next - psd; switch (delta >> 9) { case -6: case -5: case -4: case -3: case -2: psd = next; break; case -1: psd = next + latab[(-delta) >> 1]; break; case 0: psd += latab[delta >> 1]; break; } } /* minpsd = -289 */ UPDATE_LEAK (); mask = (fastleak < slowleak) ? fastleak : slowleak; COMPUTE_MASK (); i++; j = startband; do { /* max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp */ /* min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 */ bap[j] = (baptab+156)[mask + 4 * exp[j]]; } while (++j < endband); } while (j < end); } xine-lib-1.2/contrib/a52dec/tables.h0000644000175000017500000002273614647725151015023 0ustar meme/* * tables.h * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ static const int8_t exp_1[128] = { -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, -1,-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, 1, 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, 25,25,25 }; static const int8_t exp_2[128] = { -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, -2,-2,-2,-2,-2,-1,-1,-1,-1,-1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 25,25,25 }; static const int8_t exp_3[128] = { -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, -2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2,-2,-1, 0, 1, 2, 25,25,25 }; #define Q0 (-(2 << 15) / 3.0) #define Q1 (0) #define Q2 ((2 << 15) / 3.0) static const sample_t q_1_0[32] = { Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, 0,0,0,0,0 }; static const sample_t q_1_1[32] = { Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, Q0,Q0,Q0,Q1,Q1,Q1,Q2,Q2,Q2, 0,0,0,0,0 }; static const sample_t q_1_2[32] = { Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, Q0,Q1,Q2,Q0,Q1,Q2,Q0,Q1,Q2, 0,0,0,0,0 }; #undef Q0 #undef Q1 #undef Q2 #define Q0 (-(4 << 15) / 5.0) #define Q1 (-(2 << 15) / 5.0) #define Q2 (0) #define Q3 ((2 << 15) / 5.0) #define Q4 ((4 << 15) / 5.0) static const sample_t q_2_0[128] = { Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0,Q0, Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1,Q1, Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2,Q2, Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3,Q3, Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4,Q4, 0,0,0 }; static const sample_t q_2_1[128] = { Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, Q0,Q0,Q0,Q0,Q0,Q1,Q1,Q1,Q1,Q1,Q2,Q2,Q2,Q2,Q2,Q3,Q3,Q3,Q3,Q3,Q4,Q4,Q4,Q4,Q4, 0,0,0 }; static const sample_t q_2_2[128] = { Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4,Q0,Q1,Q2,Q3,Q4, 0,0,0 }; #undef Q0 #undef Q1 #undef Q2 #undef Q3 #undef Q4 static const sample_t q_3[8] = { -(6 << 15)/7.0, -(4 << 15)/7.0, -(2 << 15)/7.0, 0, (2 << 15)/7.0, (4 << 15)/7.0, (6 << 15)/7.0, 0 }; #define Q0 (-(10 << 15) / 11.0) #define Q1 (-(8 << 15) / 11.0) #define Q2 (-(6 << 15) / 11.0) #define Q3 (-(4 << 15) / 11.0) #define Q4 (-(2 << 15) / 11.0) #define Q5 (0) #define Q6 ((2 << 15) / 11.0) #define Q7 ((4 << 15) / 11.0) #define Q8 ((6 << 15) / 11.0) #define Q9 ((8 << 15) / 11.0) #define QA ((10 << 15) / 11.0) static const sample_t q_4_0[128] = { Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q0, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q1, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q2, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q3, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q4, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q5, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q6, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q7, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q8, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, Q9, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, QA, 0, 0, 0, 0, 0, 0, 0 }; static const sample_t q_4_1[128] = { Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, Q0, Q1, Q2, Q3, Q4, Q5, Q6, Q7, Q8, Q9, QA, 0, 0, 0, 0, 0, 0, 0 }; #undef Q0 #undef Q1 #undef Q2 #undef Q3 #undef Q4 #undef Q5 #undef Q6 #undef Q7 #undef Q8 #undef Q9 #undef QA static const sample_t q_5[16] = { -(14 << 15)/15.0,-(12 << 15)/15.0,-(10 << 15)/15.0, -( 8 << 15)/15.0,-( 6 << 15)/15.0,-( 4 << 15)/15.0, -( 2 << 15)/15.0, 0 , ( 2 << 15)/15.0, ( 4 << 15)/15.0, ( 6 << 15)/15.0, ( 8 << 15)/15.0, (10 << 15)/15.0, (12 << 15)/15.0, (14 << 15)/15.0, 0 }; #ifndef LIBA52_FIXED static const sample_t scale_factor[25] = { 0.000030517578125, 0.0000152587890625, 0.00000762939453125, 0.000003814697265625, 0.0000019073486328125, 0.00000095367431640625, 0.000000476837158203125, 0.0000002384185791015625, 0.00000011920928955078125, 0.000000059604644775390625, 0.0000000298023223876953125, 0.00000001490116119384765625, 0.000000007450580596923828125, 0.0000000037252902984619140625, 0.00000000186264514923095703125, 0.000000000931322574615478515625, 0.0000000004656612873077392578125, 0.00000000023283064365386962890625, 0.000000000116415321826934814453125, 0.0000000000582076609134674072265625, 0.00000000002910383045673370361328125, 0.000000000014551915228366851806640625, 0.0000000000072759576141834259033203125, 0.00000000000363797880709171295166015625, 0.000000000001818989403545856475830078125 }; #endif static const uint16_t dither_lut[256] = { 0x0000, 0xa011, 0xe033, 0x4022, 0x6077, 0xc066, 0x8044, 0x2055, 0xc0ee, 0x60ff, 0x20dd, 0x80cc, 0xa099, 0x0088, 0x40aa, 0xe0bb, 0x21cd, 0x81dc, 0xc1fe, 0x61ef, 0x41ba, 0xe1ab, 0xa189, 0x0198, 0xe123, 0x4132, 0x0110, 0xa101, 0x8154, 0x2145, 0x6167, 0xc176, 0x439a, 0xe38b, 0xa3a9, 0x03b8, 0x23ed, 0x83fc, 0xc3de, 0x63cf, 0x8374, 0x2365, 0x6347, 0xc356, 0xe303, 0x4312, 0x0330, 0xa321, 0x6257, 0xc246, 0x8264, 0x2275, 0x0220, 0xa231, 0xe213, 0x4202, 0xa2b9, 0x02a8, 0x428a, 0xe29b, 0xc2ce, 0x62df, 0x22fd, 0x82ec, 0x8734, 0x2725, 0x6707, 0xc716, 0xe743, 0x4752, 0x0770, 0xa761, 0x47da, 0xe7cb, 0xa7e9, 0x07f8, 0x27ad, 0x87bc, 0xc79e, 0x678f, 0xa6f9, 0x06e8, 0x46ca, 0xe6db, 0xc68e, 0x669f, 0x26bd, 0x86ac, 0x6617, 0xc606, 0x8624, 0x2635, 0x0660, 0xa671, 0xe653, 0x4642, 0xc4ae, 0x64bf, 0x249d, 0x848c, 0xa4d9, 0x04c8, 0x44ea, 0xe4fb, 0x0440, 0xa451, 0xe473, 0x4462, 0x6437, 0xc426, 0x8404, 0x2415, 0xe563, 0x4572, 0x0550, 0xa541, 0x8514, 0x2505, 0x6527, 0xc536, 0x258d, 0x859c, 0xc5be, 0x65af, 0x45fa, 0xe5eb, 0xa5c9, 0x05d8, 0xae79, 0x0e68, 0x4e4a, 0xee5b, 0xce0e, 0x6e1f, 0x2e3d, 0x8e2c, 0x6e97, 0xce86, 0x8ea4, 0x2eb5, 0x0ee0, 0xaef1, 0xeed3, 0x4ec2, 0x8fb4, 0x2fa5, 0x6f87, 0xcf96, 0xefc3, 0x4fd2, 0x0ff0, 0xafe1, 0x4f5a, 0xef4b, 0xaf69, 0x0f78, 0x2f2d, 0x8f3c, 0xcf1e, 0x6f0f, 0xede3, 0x4df2, 0x0dd0, 0xadc1, 0x8d94, 0x2d85, 0x6da7, 0xcdb6, 0x2d0d, 0x8d1c, 0xcd3e, 0x6d2f, 0x4d7a, 0xed6b, 0xad49, 0x0d58, 0xcc2e, 0x6c3f, 0x2c1d, 0x8c0c, 0xac59, 0x0c48, 0x4c6a, 0xec7b, 0x0cc0, 0xacd1, 0xecf3, 0x4ce2, 0x6cb7, 0xcca6, 0x8c84, 0x2c95, 0x294d, 0x895c, 0xc97e, 0x696f, 0x493a, 0xe92b, 0xa909, 0x0918, 0xe9a3, 0x49b2, 0x0990, 0xa981, 0x89d4, 0x29c5, 0x69e7, 0xc9f6, 0x0880, 0xa891, 0xe8b3, 0x48a2, 0x68f7, 0xc8e6, 0x88c4, 0x28d5, 0xc86e, 0x687f, 0x285d, 0x884c, 0xa819, 0x0808, 0x482a, 0xe83b, 0x6ad7, 0xcac6, 0x8ae4, 0x2af5, 0x0aa0, 0xaab1, 0xea93, 0x4a82, 0xaa39, 0x0a28, 0x4a0a, 0xea1b, 0xca4e, 0x6a5f, 0x2a7d, 0x8a6c, 0x4b1a, 0xeb0b, 0xab29, 0x0b38, 0x2b6d, 0x8b7c, 0xcb5e, 0x6b4f, 0x8bf4, 0x2be5, 0x6bc7, 0xcbd6, 0xeb83, 0x4b92, 0x0bb0, 0xaba1 }; xine-lib-1.2/contrib/a52dec/a52.h0000644000175000017500000000364214647725151014133 0ustar meme/* * a52.h * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef A52_H #define A52_H #if defined(LIBA52_FIXED) typedef int32_t sample_t; #elif defined(LIBA52_DOUBLE) typedef double sample_t; #else typedef float sample_t; #endif typedef struct a52_state_s a52_state_t; #define A52_CHANNEL 0 #define A52_MONO 1 #define A52_STEREO 2 #define A52_3F 3 #define A52_2F1R 4 #define A52_3F1R 5 #define A52_2F2R 6 #define A52_3F2R 7 #define A52_CHANNEL1 8 #define A52_CHANNEL2 9 #define A52_DOLBY 10 #define A52_CHANNEL_MASK 15 #define A52_LFE 16 #define A52_ADJUST_LEVEL 32 a52_state_t * a52_init (uint32_t mm_accel); sample_t * a52_samples (a52_state_t * state); int a52_syncinfo (uint8_t * buf, int * flags, int * sample_rate, int * bit_rate); int a52_frame (a52_state_t * state, uint8_t * buf, int * flags, sample_t * level, sample_t bias); void a52_dynrng (a52_state_t * state, sample_t (* call) (sample_t, void *), void * data); int a52_block (a52_state_t * state); void a52_free (a52_state_t * state); #endif /* A52_H */ xine-lib-1.2/contrib/a52dec/imdct.c0000644000175000017500000003024514647725151014636 0ustar meme/* * imdct.c * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * The ifft algorithms in this file have been largely inspired by Dan * Bernstein's work, djbfft, available at http://cr.yp.to/djbfft.html * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #ifdef LIBA52_DJBFFT #include #endif #ifndef M_PI #define M_PI 3.1415926535897932384626433832795029 #endif #include #include "a52.h" #include "a52_internal.h" #include static const uint8_t fftorder[] = { 0,128, 64,192, 32,160,224, 96, 16,144, 80,208,240,112, 48,176, 8,136, 72,200, 40,168,232,104,248,120, 56,184, 24,152,216, 88, 4,132, 68,196, 36,164,228,100, 20,148, 84,212,244,116, 52,180, 252,124, 60,188, 28,156,220, 92, 12,140, 76,204,236,108, 44,172, 2,130, 66,194, 34,162,226, 98, 18,146, 82,210,242,114, 50,178, 10,138, 74,202, 42,170,234,106,250,122, 58,186, 26,154,218, 90, 254,126, 62,190, 30,158,222, 94, 14,142, 78,206,238,110, 46,174, 6,134, 70,198, 38,166,230,102,246,118, 54,182, 22,150,214, 86 }; static inline void ifft2 (complex_t * buf) { sample_t r, i; r = buf[0].real; i = buf[0].imag; buf[0].real += buf[1].real; buf[0].imag += buf[1].imag; buf[1].real = r - buf[1].real; buf[1].imag = i - buf[1].imag; } static inline void ifft4 (complex_t * buf) { sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; tmp1 = buf[0].real + buf[1].real; tmp2 = buf[3].real + buf[2].real; tmp3 = buf[0].imag + buf[1].imag; tmp4 = buf[2].imag + buf[3].imag; tmp5 = buf[0].real - buf[1].real; tmp6 = buf[0].imag - buf[1].imag; tmp7 = buf[2].imag - buf[3].imag; tmp8 = buf[3].real - buf[2].real; buf[0].real = tmp1 + tmp2; buf[0].imag = tmp3 + tmp4; buf[2].real = tmp1 - tmp2; buf[2].imag = tmp3 - tmp4; buf[1].real = tmp5 + tmp7; buf[1].imag = tmp6 + tmp8; buf[3].real = tmp5 - tmp7; buf[3].imag = tmp6 - tmp8; } /* basic radix-2 ifft butterfly */ #define BUTTERFLY_0(t0,t1,W0,W1,d0,d1) do { \ t0 = MUL (W1, d1) + MUL (W0, d0); \ t1 = MUL (W0, d1) - MUL (W1, d0); \ } while (0) #ifdef LIBA52_FIXED # define BUTTERFLY_BIAS(t0,t1,W0,W1,d0,d1,bias) do { \ t0 = MUL (d1, W1) + MUL (d0, W0); \ t1 = MUL (d1, W0) - MUL (d0, W1); \ (void)bias; \ } while (0) #else # define BUTTERFLY_BIAS(t0,t1,W0,W1,d0,d1,bias) do { \ t0 = MUL (d1, W1) + MUL (d0, W0) + bias; \ t1 = MUL (d1, W0) - MUL (d0, W1) + bias; \ } while (0) #endif /* the basic split-radix ifft butterfly */ #define BUTTERFLY(a0,a1,a2,a3,wr,wi) do { \ BUTTERFLY_0 (tmp5, tmp6, wr, wi, a2.real, a2.imag); \ BUTTERFLY_0 (tmp8, tmp7, wr, wi, a3.imag, a3.real); \ tmp1 = tmp5 + tmp7; \ tmp2 = tmp6 + tmp8; \ tmp3 = tmp6 - tmp8; \ tmp4 = tmp7 - tmp5; \ a2.real = a0.real - tmp1; \ a2.imag = a0.imag - tmp2; \ a3.real = a1.real - tmp3; \ a3.imag = a1.imag - tmp4; \ a0.real += tmp1; \ a0.imag += tmp2; \ a1.real += tmp3; \ a1.imag += tmp4; \ } while (0) /* split-radix ifft butterfly, specialized for wr=1 wi=0 */ #define BUTTERFLY_ZERO(a0,a1,a2,a3) do { \ tmp1 = a2.real + a3.real; \ tmp2 = a2.imag + a3.imag; \ tmp3 = a2.imag - a3.imag; \ tmp4 = a3.real - a2.real; \ a2.real = a0.real - tmp1; \ a2.imag = a0.imag - tmp2; \ a3.real = a1.real - tmp3; \ a3.imag = a1.imag - tmp4; \ a0.real += tmp1; \ a0.imag += tmp2; \ a1.real += tmp3; \ a1.imag += tmp4; \ } while (0) /* split-radix ifft butterfly, specialized for wr=wi */ #define BUTTERFLY_HALF(a0,a1,a2,a3,w) do { \ tmp5 = MUL (a2.real + a2.imag, w); \ tmp6 = MUL (a2.imag - a2.real, w); \ tmp7 = MUL (a3.real - a3.imag, w); \ tmp8 = MUL (a3.imag + a3.real, w); \ tmp1 = tmp5 + tmp7; \ tmp2 = tmp6 + tmp8; \ tmp3 = tmp6 - tmp8; \ tmp4 = tmp7 - tmp5; \ a2.real = a0.real - tmp1; \ a2.imag = a0.imag - tmp2; \ a3.real = a1.real - tmp3; \ a3.imag = a1.imag - tmp4; \ a0.real += tmp1; \ a0.imag += tmp2; \ a1.real += tmp3; \ a1.imag += tmp4; \ } while (0) static inline void ifft8 (a52_state_t *a52, complex_t * buf) { sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; ifft4 (buf); ifft2 (buf + 4); ifft2 (buf + 6); BUTTERFLY_ZERO (buf[0], buf[2], buf[4], buf[6]); BUTTERFLY_HALF (buf[1], buf[3], buf[5], buf[7], a52->roots16[1]); } static void ifft_pass (complex_t * buf, sample_t * weight, int n) { complex_t * buf1; complex_t * buf2; complex_t * buf3; sample_t * wi; sample_t tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; int i; buf++; buf1 = buf + n; buf2 = buf + 2 * n; buf3 = buf + 3 * n; BUTTERFLY_ZERO (buf[-1], buf1[-1], buf2[-1], buf3[-1]); i = n - 1; wi = weight + n - 2; do { BUTTERFLY (buf[0], buf1[0], buf2[0], buf3[0], weight[0], wi[0]); buf++; buf1++; buf2++; buf3++; weight++; wi--; } while (--i); } static void ifft16 (a52_state_t *a52, complex_t * buf) { ifft8 (a52, buf); ifft4 (buf + 8); ifft4 (buf + 12); ifft_pass (buf, a52->roots16, 4); } static void ifft32 (a52_state_t *a52, complex_t * buf) { ifft16 (a52, buf); ifft8 (a52, buf + 16); ifft8 (a52, buf + 24); ifft_pass (buf, a52->roots32, 8); } #ifdef LIBA52_DJBFFT static void ifft64_djbfft (a52_state_t *a52, complex_t * buf) { (void)a52; # ifndef LIBA52_DOUBLE fftc4_un64 (buf); # else fftc8_un64 (buf); # endif } static void ifft128_djbfft (a52_state_t *a52, complex_t * buf) { (void)a52; # ifndef LIBA52_DOUBLE fftc4_un128 (buf); # else fftc8_un128 (buf); # endif } #endif static void ifft64_c (a52_state_t *a52, complex_t * buf) { ifft32 (a52, buf); ifft16 (a52, buf + 32); ifft16 (a52, buf + 48); ifft_pass (buf, a52->roots64, 16); } static void ifft128_c (a52_state_t *a52, complex_t * buf) { ifft32 (a52, buf); ifft16 (a52, buf + 32); ifft16 (a52, buf + 48); ifft_pass (buf, a52->roots64, 16); ifft32 (a52, buf + 64); ifft32 (a52, buf + 96); ifft_pass (buf, a52->roots128, 32); } void a52_imdct_512 (a52_state_t *a52, sample_t * data, sample_t * delay, sample_t bias) { int i, k; sample_t t_r, t_i, a_r, a_i, b_r, b_i, w_1, w_2; const sample_t * window = a52->a52_imdct_window; complex_t buf[128]; for (i = 0; i < 128; i++) { k = fftorder[i]; t_r = a52->pre1[i].real; t_i = a52->pre1[i].imag; BUTTERFLY_0 (buf[i].real, buf[i].imag, t_r, t_i, data[k], data[255-k]); } a52->ifft128 (a52, buf); /* Post IFFT complex multiply plus IFFT complex conjugate*/ /* Window and convert to real valued signal */ for (i = 0; i < 64; i++) { /* y[n] = z[n] * (xcos1[n] + j * xsin1[n]) ; */ t_r = a52->post1[i].real; t_i = a52->post1[i].imag; BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf[i].imag, buf[i].real); BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf[127-i].imag, buf[127-i].real); w_1 = window[2*i]; w_2 = window[255-2*i]; BUTTERFLY_BIAS (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i], bias); delay[2*i] = a_i; w_1 = window[2*i+1]; w_2 = window[254-2*i]; BUTTERFLY_BIAS (data[2*i+1], data[254-2*i], w_1, w_2, b_r, delay[2*i+1], bias); delay[2*i+1] = b_i; } } void a52_imdct_256 (a52_state_t *a52, sample_t * data, sample_t * delay, sample_t bias) { int i, k; sample_t t_r, t_i, a_r, a_i, b_r, b_i, c_r, c_i, d_r, d_i, w_1, w_2; const sample_t * window = a52->a52_imdct_window; complex_t buf1[64], buf2[64]; /* Pre IFFT complex multiply plus IFFT cmplx conjugate */ for (i = 0; i < 64; i++) { k = fftorder[i]; t_r = a52->pre2[i].real; t_i = a52->pre2[i].imag; BUTTERFLY_0 (buf1[i].real, buf1[i].imag, t_r, t_i, data[k], data[254-k]); BUTTERFLY_0 (buf2[i].real, buf2[i].imag, t_r, t_i, data[k+1], data[255-k]); } a52->ifft64 (a52, buf1); a52->ifft64 (a52, buf2); /* Post IFFT complex multiply */ /* Window and convert to real valued signal */ for (i = 0; i < 32; i++) { /* y1[n] = z1[n] * (xcos2[n] + j * xs in2[n]) ; */ t_r = a52->post2[i].real; t_i = a52->post2[i].imag; BUTTERFLY_0 (a_r, a_i, t_i, t_r, buf1[i].imag, buf1[i].real); BUTTERFLY_0 (b_r, b_i, t_r, t_i, buf1[63-i].imag, buf1[63-i].real); BUTTERFLY_0 (c_r, c_i, t_i, t_r, buf2[i].imag, buf2[i].real); BUTTERFLY_0 (d_r, d_i, t_r, t_i, buf2[63-i].imag, buf2[63-i].real); w_1 = window[2*i]; w_2 = window[255-2*i]; BUTTERFLY_BIAS (data[255-2*i], data[2*i], w_2, w_1, a_r, delay[2*i], bias); delay[2*i] = c_i; w_1 = window[128+2*i]; w_2 = window[127-2*i]; BUTTERFLY_BIAS (data[128+2*i], data[127-2*i], w_1, w_2, a_i, delay[127-2*i], bias); delay[127-2*i] = c_r; w_1 = window[2*i+1]; w_2 = window[254-2*i]; BUTTERFLY_BIAS (data[254-2*i], data[2*i+1], w_2, w_1, b_i, delay[2*i+1], bias); delay[2*i+1] = d_r; w_1 = window[129+2*i]; w_2 = window[126-2*i]; BUTTERFLY_BIAS (data[129+2*i], data[126-2*i], w_1, w_2, b_r, delay[126-2*i], bias); delay[126-2*i] = d_i; } } static double besselI0 (double x) { double bessel = 1; int i = 100; do bessel = bessel * x / (i * i) + 1; while (--i); return bessel; } void a52_imdct_init (a52_state_t *a52, uint32_t mm_accel) { int i, k; double sum; /* compute imdct window - kaiser-bessel derived window, alpha = 5.0 */ sum = 0; for (i = 0; i < 256; i++) { sum += besselI0 (i * (256 - i) * (5 * M_PI / 256) * (5 * M_PI / 256)); a52->a52_imdct_window[i] = sum; } sum++; for (i = 0; i < 256; i++) a52->a52_imdct_window[i] = SAMPLE (sqrt (a52->a52_imdct_window[i] / sum)); for (i = 0; i < 3; i++) a52->roots16[i] = SAMPLE (cos ((M_PI / 8) * (i + 1))); for (i = 0; i < 7; i++) a52->roots32[i] = SAMPLE (cos ((M_PI / 16) * (i + 1))); for (i = 0; i < 15; i++) a52->roots64[i] = SAMPLE (cos ((M_PI / 32) * (i + 1))); for (i = 0; i < 31; i++) a52->roots128[i] = SAMPLE (cos ((M_PI / 64) * (i + 1))); for (i = 0; i < 64; i++) { k = fftorder[i] / 2 + 64; a52->pre1[i].real = SAMPLE (cos ((M_PI / 256) * (k - 0.25))); a52->pre1[i].imag = SAMPLE (sin ((M_PI / 256) * (k - 0.25))); } for (i = 64; i < 128; i++) { k = fftorder[i] / 2 + 64; a52->pre1[i].real = SAMPLE (-cos ((M_PI / 256) * (k - 0.25))); a52->pre1[i].imag = SAMPLE (-sin ((M_PI / 256) * (k - 0.25))); } for (i = 0; i < 64; i++) { a52->post1[i].real = SAMPLE (cos ((M_PI / 256) * (i + 0.5))); a52->post1[i].imag = SAMPLE (sin ((M_PI / 256) * (i + 0.5))); } for (i = 0; i < 64; i++) { k = fftorder[i] / 4; a52->pre2[i].real = SAMPLE (cos ((M_PI / 128) * (k - 0.25))); a52->pre2[i].imag = SAMPLE (sin ((M_PI / 128) * (k - 0.25))); } for (i = 0; i < 32; i++) { a52->post2[i].real = SAMPLE (cos ((M_PI / 128) * (i + 0.5))); a52->post2[i].imag = SAMPLE (sin ((M_PI / 128) * (i + 0.5))); } #ifndef LIBA52_DJBFFT (void)mm_accel; #else if (mm_accel & MM_ACCEL_DJBFFT) { fprintf (stderr, "liba52:Using djbfft for IMDCT transform\n"); a52->ifft128 = ifft128_djbfft; a52->ifft64 = ifft64_djbfft; } else #endif { a52->ifft128 = ifft128_c; a52->ifft64 = ifft64_c; } } xine-lib-1.2/contrib/a52dec/bitstream.c0000644000175000017500000000465214647725151015533 0ustar meme/* * bitstream.c * Copyright (C) 2000-2002 Michel Lespinasse * Copyright (C) 1999-2000 Aaron Holtzman * * This file is part of a52dec, a free ATSC A-52 stream decoder. * See http://liba52.sourceforge.net/ for updates. * * a52dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * a52dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include "a52.h" #include "a52_internal.h" #include "bitstream.h" #define BUFFER_SIZE 4096 void a52_bitstream_set_ptr (a52_state_t * state, uint8_t * buf) { int align; align = (long)buf & 3; state->buffer_start = (uint32_t *) (buf - align); state->bits_left = 0; bitstream_get (state, align * 8); } /* * The fast paths for _get is in the * bitstream.h header file so it can be inlined. * * The "bottom half" of this routine is suffixed _bh * * -ah */ uint32_t a52_bitstream_get_bh (a52_state_t * state, uint32_t num_bits) { uint32_t result, next; result = state->current_word >> (32 - state->bits_left); next = *(state->buffer_start++); next = swab32 (next); num_bits -= state->bits_left; if (num_bits != 0) { result = (result << num_bits) | (next >> (32 - num_bits)); next <<= num_bits; } state->current_word = next; state->bits_left = 32 - num_bits; return result; } int32_t a52_bitstream_get_bh_2 (a52_state_t * state, uint32_t num_bits) { int32_t result; uint32_t next; result = ((int32_t)state->current_word) >> (32 - state->bits_left); next = *(state->buffer_start++); next = swab32 (next); num_bits -= state->bits_left; if (num_bits != 0) { result = (result << num_bits) | (next >> (32 - num_bits)); next <<= num_bits; } state->current_word = next; state->bits_left = 32 - num_bits; return result; } xine-lib-1.2/contrib/libmad/0000755000175000017500000000000014647725152013554 5ustar memexine-lib-1.2/contrib/libmad/layer12.c0000644000175000017500000003246714647725152015213 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer12.c,v 1.17 2004/02/05 09:02:39 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # ifdef HAVE_LIMITS_H # include # else # define CHAR_BIT 8 # endif # include "fixed.h" # include "bit.h" # include "stream.h" # include "frame.h" # include "layer12.h" /* * scalefactor table * used in both Layer I and Layer II decoding */ static mad_fixed_t const sf_table[64] = { # include "sf_table.dat" }; /* --- Layer I ------------------------------------------------------------- */ /* linear scaling table */ static mad_fixed_t const linear_table[14] = { MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */ MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */ MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */ MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */ MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */ MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */ MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */ MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */ MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */ MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */ MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */ MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */ MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */ MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */ }; /* * NAME: I_sample() * DESCRIPTION: decode one requantized Layer I sample from a bitstream */ static mad_fixed_t I_sample(struct mad_bitptr *ptr, unsigned int nb) { mad_fixed_t sample; sample = mad_bit_read(ptr, nb); /* invert most significant bit, extend sign, then scale to fixed format */ sample ^= 1 << (nb - 1); sample |= -(sample & (1 << (nb - 1))); sample <<= MAD_F_FRACBITS - (nb - 1); /* requantize the sample */ /* s'' = (2^nb / (2^nb - 1)) * (s''' + 2^(-nb + 1)) */ sample += MAD_F_ONE >> (nb - 1); return mad_f_mul(sample, linear_table[nb - 2]); /* s' = factor * s'' */ /* (to be performed by caller) */ } /* * NAME: layer->I() * DESCRIPTION: decode a single Layer I frame */ int mad_layer_I(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; unsigned int nch, bound, ch, s, sb, nb; unsigned char allocation[2][32], scalefactor[2][32]; nch = MAD_NCHANNELS(header); bound = 32; if (header->mode == MAD_MODE_JOINT_STEREO) { header->flags |= MAD_FLAG_I_STEREO; bound = 4 + header->mode_extension * 4; } /* check CRC word */ if (header->flags & MAD_FLAG_PROTECTION) { header->crc_check = mad_bit_crc(stream->ptr, 4 * (bound * nch + (32 - bound)), header->crc_check); if (header->crc_check != header->crc_target && !(frame->options & MAD_OPTION_IGNORECRC)) { stream->error = MAD_ERROR_BADCRC; return -1; } } /* decode bit allocations */ for (sb = 0; sb < bound; ++sb) { for (ch = 0; ch < nch; ++ch) { nb = mad_bit_read(&stream->ptr, 4); if (nb == 15) { stream->error = MAD_ERROR_BADBITALLOC; return -1; } allocation[ch][sb] = nb ? nb + 1 : 0; } } for (sb = bound; sb < 32; ++sb) { nb = mad_bit_read(&stream->ptr, 4); if (nb == 15) { stream->error = MAD_ERROR_BADBITALLOC; return -1; } allocation[0][sb] = allocation[1][sb] = nb ? nb + 1 : 0; } /* decode scalefactors */ for (sb = 0; sb < 32; ++sb) { for (ch = 0; ch < nch; ++ch) { if (allocation[ch][sb]) { scalefactor[ch][sb] = mad_bit_read(&stream->ptr, 6); # if defined(OPT_STRICT) /* * Scalefactor index 63 does not appear in Table B.1 of * ISO/IEC 11172-3. Nonetheless, other implementations accept it, * so we only reject it if OPT_STRICT is defined. */ if (scalefactor[ch][sb] == 63) { stream->error = MAD_ERROR_BADSCALEFACTOR; return -1; } # endif } } } /* decode samples */ for (s = 0; s < 12; ++s) { for (sb = 0; sb < bound; ++sb) { for (ch = 0; ch < nch; ++ch) { nb = allocation[ch][sb]; frame->sbsample[ch][s][sb] = nb ? mad_f_mul(I_sample(&stream->ptr, nb), sf_table[scalefactor[ch][sb]]) : 0; } } for (sb = bound; sb < 32; ++sb) { if ((nb = allocation[0][sb])) { mad_fixed_t sample; sample = I_sample(&stream->ptr, nb); for (ch = 0; ch < nch; ++ch) { frame->sbsample[ch][s][sb] = mad_f_mul(sample, sf_table[scalefactor[ch][sb]]); } } else { for (ch = 0; ch < nch; ++ch) frame->sbsample[ch][s][sb] = 0; } } } return 0; } /* --- Layer II ------------------------------------------------------------ */ /* possible quantization per subband table */ static struct { unsigned int sblimit; unsigned char const offsets[30]; } const sbquant_table[5] = { /* ISO/IEC 11172-3 Table B.2a */ { 27, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 0 */ 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 } }, /* ISO/IEC 11172-3 Table B.2b */ { 30, { 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, /* 1 */ 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0 } }, /* ISO/IEC 11172-3 Table B.2c */ { 8, { 5, 5, 2, 2, 2, 2, 2, 2 } }, /* 2 */ /* ISO/IEC 11172-3 Table B.2d */ { 12, { 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 } }, /* 3 */ /* ISO/IEC 13818-3 Table B.1 */ { 30, { 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, /* 4 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } } }; /* bit allocation table */ static struct { unsigned short nbal; unsigned short offset; } const bitalloc_table[8] = { { 2, 0 }, /* 0 */ { 2, 3 }, /* 1 */ { 3, 3 }, /* 2 */ { 3, 1 }, /* 3 */ { 4, 2 }, /* 4 */ { 4, 3 }, /* 5 */ { 4, 4 }, /* 6 */ { 4, 5 } /* 7 */ }; /* offsets into quantization class table */ static unsigned char const offset_table[6][15] = { { 0, 1, 16 }, /* 0 */ { 0, 1, 2, 3, 4, 5, 16 }, /* 1 */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }, /* 2 */ { 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, /* 3 */ { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 }, /* 4 */ { 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 } /* 5 */ }; /* quantization class table */ static struct quantclass { unsigned short nlevels; unsigned char group; unsigned char bits; mad_fixed_t C; mad_fixed_t D; } const qc_table[17] = { # include "qc_table.dat" }; /* * NAME: II_samples() * DESCRIPTION: decode three requantized Layer II samples from a bitstream */ static void II_samples(struct mad_bitptr *ptr, struct quantclass const *quantclass, mad_fixed_t output[3]) { unsigned int nb, s, sample[3]; if ((nb = quantclass->group)) { unsigned int c, nlevels; /* degrouping */ c = mad_bit_read(ptr, quantclass->bits); nlevels = quantclass->nlevels; for (s = 0; s < 3; ++s) { sample[s] = c % nlevels; c /= nlevels; } } else { nb = quantclass->bits; for (s = 0; s < 3; ++s) sample[s] = mad_bit_read(ptr, nb); } for (s = 0; s < 3; ++s) { mad_fixed_t requantized; /* invert most significant bit, extend sign, then scale to fixed format */ requantized = sample[s] ^ (1 << (nb - 1)); requantized |= -(requantized & (1 << (nb - 1))); requantized <<= MAD_F_FRACBITS - (nb - 1); /* requantize the sample */ /* s'' = C * (s''' + D) */ output[s] = mad_f_mul(requantized + quantclass->D, quantclass->C); /* s' = factor * s'' */ /* (to be performed by caller) */ } } /* * NAME: layer->II() * DESCRIPTION: decode a single Layer II frame */ int mad_layer_II(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; struct mad_bitptr start; unsigned int index, sblimit, nbal, nch, bound, gr, ch, s, sb; unsigned char const *offsets; unsigned char allocation[2][32], scfsi[2][32], scalefactor[2][32][3]; mad_fixed_t samples[3]; nch = MAD_NCHANNELS(header); if (header->flags & MAD_FLAG_LSF_EXT) index = 4; else if (header->flags & MAD_FLAG_FREEFORMAT) goto freeformat; else { unsigned long bitrate_per_channel; bitrate_per_channel = header->bitrate; if (nch == 2) { bitrate_per_channel /= 2; # if defined(OPT_STRICT) /* * ISO/IEC 11172-3 allows only single channel mode for 32, 48, 56, and * 80 kbps bitrates in Layer II, but some encoders ignore this * restriction. We enforce it if OPT_STRICT is defined. */ if (bitrate_per_channel <= 28000 || bitrate_per_channel == 40000) { stream->error = MAD_ERROR_BADMODE; return -1; } # endif } else { /* nch == 1 */ if (bitrate_per_channel > 192000) { /* * ISO/IEC 11172-3 does not allow single channel mode for 224, 256, * 320, or 384 kbps bitrates in Layer II. */ stream->error = MAD_ERROR_BADMODE; return -1; } } if (bitrate_per_channel <= 48000) index = (header->samplerate == 32000) ? 3 : 2; else if (bitrate_per_channel <= 80000) index = 0; else { freeformat: index = (header->samplerate == 48000) ? 0 : 1; } } sblimit = sbquant_table[index].sblimit; offsets = sbquant_table[index].offsets; bound = 32; if (header->mode == MAD_MODE_JOINT_STEREO) { header->flags |= MAD_FLAG_I_STEREO; bound = 4 + header->mode_extension * 4; } if (bound > sblimit) bound = sblimit; start = stream->ptr; /* decode bit allocations */ for (sb = 0; sb < bound; ++sb) { nbal = bitalloc_table[offsets[sb]].nbal; for (ch = 0; ch < nch; ++ch) allocation[ch][sb] = mad_bit_read(&stream->ptr, nbal); } for (sb = bound; sb < sblimit; ++sb) { nbal = bitalloc_table[offsets[sb]].nbal; allocation[0][sb] = allocation[1][sb] = mad_bit_read(&stream->ptr, nbal); } /* decode scalefactor selection info */ for (sb = 0; sb < sblimit; ++sb) { for (ch = 0; ch < nch; ++ch) { if (allocation[ch][sb]) scfsi[ch][sb] = mad_bit_read(&stream->ptr, 2); } } /* check CRC word */ if (header->flags & MAD_FLAG_PROTECTION) { header->crc_check = mad_bit_crc(start, mad_bit_length(&start, &stream->ptr), header->crc_check); if (header->crc_check != header->crc_target && !(frame->options & MAD_OPTION_IGNORECRC)) { stream->error = MAD_ERROR_BADCRC; return -1; } } /* decode scalefactors */ for (sb = 0; sb < sblimit; ++sb) { for (ch = 0; ch < nch; ++ch) { if (allocation[ch][sb]) { scalefactor[ch][sb][0] = mad_bit_read(&stream->ptr, 6); switch (scfsi[ch][sb]) { case 2: scalefactor[ch][sb][2] = scalefactor[ch][sb][1] = scalefactor[ch][sb][0]; break; case 0: scalefactor[ch][sb][1] = mad_bit_read(&stream->ptr, 6); /* fall through */ case 1: case 3: scalefactor[ch][sb][2] = mad_bit_read(&stream->ptr, 6); } if (scfsi[ch][sb] & 1) scalefactor[ch][sb][1] = scalefactor[ch][sb][scfsi[ch][sb] - 1]; # if defined(OPT_STRICT) /* * Scalefactor index 63 does not appear in Table B.1 of * ISO/IEC 11172-3. Nonetheless, other implementations accept it, * so we only reject it if OPT_STRICT is defined. */ if (scalefactor[ch][sb][0] == 63 || scalefactor[ch][sb][1] == 63 || scalefactor[ch][sb][2] == 63) { stream->error = MAD_ERROR_BADSCALEFACTOR; return -1; } # endif } } } /* decode samples */ for (gr = 0; gr < 12; ++gr) { for (sb = 0; sb < bound; ++sb) { for (ch = 0; ch < nch; ++ch) { if ((index = allocation[ch][sb])) { index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1]; II_samples(&stream->ptr, &qc_table[index], samples); for (s = 0; s < 3; ++s) { frame->sbsample[ch][3 * gr + s][sb] = mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]); } } else { for (s = 0; s < 3; ++s) frame->sbsample[ch][3 * gr + s][sb] = 0; } } } for (sb = bound; sb < sblimit; ++sb) { if ((index = allocation[0][sb])) { index = offset_table[bitalloc_table[offsets[sb]].offset][index - 1]; II_samples(&stream->ptr, &qc_table[index], samples); for (ch = 0; ch < nch; ++ch) { for (s = 0; s < 3; ++s) { frame->sbsample[ch][3 * gr + s][sb] = mad_f_mul(samples[s], sf_table[scalefactor[ch][sb][gr / 4]]); } } } else { for (ch = 0; ch < nch; ++ch) { for (s = 0; s < 3; ++s) frame->sbsample[ch][3 * gr + s][sb] = 0; } } } for (ch = 0; ch < nch; ++ch) { for (s = 0; s < 3; ++s) { for (sb = sblimit; sb < 32; ++sb) frame->sbsample[ch][3 * gr + s][sb] = 0; } } } return 0; } xine-lib-1.2/contrib/libmad/synth.h0000644000175000017500000000363614647725152015102 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: synth.h,v 1.15 2004/01/23 09:41:33 rob Exp $ */ # ifndef LIBMAD_SYNTH_H # define LIBMAD_SYNTH_H # include "fixed.h" # include "frame.h" struct mad_pcm { unsigned int samplerate; /* sampling frequency (Hz) */ unsigned short channels; /* number of channels */ unsigned short length; /* number of samples per channel */ mad_fixed_t samples[2][1152]; /* PCM output samples [ch][sample] */ }; struct mad_synth { mad_fixed_t filter[2][2][2][16][8]; /* polyphase filterbank outputs */ /* [ch][eo][peo][s][v] */ unsigned int phase; /* current processing phase */ struct mad_pcm pcm; /* PCM output */ }; /* single channel PCM selector */ enum { MAD_PCM_CHANNEL_SINGLE = 0 }; /* dual channel PCM selector */ enum { MAD_PCM_CHANNEL_DUAL_1 = 0, MAD_PCM_CHANNEL_DUAL_2 = 1 }; /* stereo PCM selector */ enum { MAD_PCM_CHANNEL_STEREO_LEFT = 0, MAD_PCM_CHANNEL_STEREO_RIGHT = 1 }; void mad_synth_init(struct mad_synth *); # define mad_synth_finish(synth) /* nothing */ void mad_synth_mute(struct mad_synth *); void mad_synth_frame(struct mad_synth *, struct mad_frame const *); # endif xine-lib-1.2/contrib/libmad/fixed.h0000644000175000017500000003237014647725151015030 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: fixed.h,v 1.38 2004/02/17 02:02:03 rob Exp $ */ # ifndef LIBMAD_FIXED_H # define LIBMAD_FIXED_H # if SIZEOF_INT >= 4 typedef signed int mad_fixed_t; typedef signed int mad_fixed64hi_t; typedef unsigned int mad_fixed64lo_t; # else typedef signed long mad_fixed_t; typedef signed long mad_fixed64hi_t; typedef unsigned long mad_fixed64lo_t; # endif # if defined(_MSC_VER) # define mad_fixed64_t signed __int64 # elif 1 || defined(__GNUC__) # define mad_fixed64_t signed long long # endif # if defined(FPM_FLOAT) typedef double mad_sample_t; # else typedef mad_fixed_t mad_sample_t; # endif /* * Fixed-point format: 0xABBBBBBB * A == whole part (sign + 3 bits) * B == fractional part (28 bits) * * Values are signed two's complement, so the effective range is: * 0x80000000 to 0x7fffffff * -8.0 to +7.9999999962747097015380859375 * * The smallest representable value is: * 0x00000001 == 0.0000000037252902984619140625 (i.e. about 3.725e-9) * * 28 bits of fractional accuracy represent about * 8.6 digits of decimal accuracy. * * Fixed-point numbers can be added or subtracted as normal * integers, but multiplication requires shifting the 64-bit result * from 56 fractional bits back to 28 (and rounding.) * * Changing the definition of MAD_F_FRACBITS is only partially * supported, and must be done with care. */ # define MAD_F_FRACBITS 28 # if MAD_F_FRACBITS == 28 # define MAD_F(x) ((mad_fixed_t) (x##L)) # else # if MAD_F_FRACBITS < 28 # warning "MAD_F_FRACBITS < 28" # define MAD_F(x) ((mad_fixed_t) \ (((x##L) + \ (1L << (28 - MAD_F_FRACBITS - 1))) >> \ (28 - MAD_F_FRACBITS))) # elif MAD_F_FRACBITS > 28 # error "MAD_F_FRACBITS > 28 not currently supported" # define MAD_F(x) ((mad_fixed_t) \ ((x##L) << (MAD_F_FRACBITS - 28))) # endif # endif # define MAD_F_MIN ((mad_fixed_t) -0x80000000L) # define MAD_F_MAX ((mad_fixed_t) +0x7fffffffL) # define MAD_F_ONE MAD_F(0x10000000) # define mad_f_tofixed(x) ((mad_fixed_t) \ ((x) * (double) (1L << MAD_F_FRACBITS) + 0.5)) # define mad_f_todouble(x) ((double) \ ((x) / (double) (1L << MAD_F_FRACBITS))) # define mad_f_intpart(x) ((x) >> MAD_F_FRACBITS) # define mad_f_fracpart(x) ((x) & ((1L << MAD_F_FRACBITS) - 1)) /* (x should be positive) */ # define mad_f_fromint(x) ((x) << MAD_F_FRACBITS) # define mad_f_add(x, y) ((x) + (y)) # define mad_f_sub(x, y) ((x) - (y)) # if defined(FPM_FLOAT) # error "FPM_FLOAT not yet supported" # undef MAD_F # define MAD_F(x) mad_f_todouble(x) # define mad_f_mul(x, y) ((x) * (y)) # define mad_f_scale64 # undef ASO_ZEROCHECK # elif defined(FPM_64BIT) /* * This version should be the most accurate if 64-bit types are supported by * the compiler, although it may not be the most efficient. */ # if defined(OPT_ACCURACY) # define mad_f_mul(x, y) \ ((mad_fixed_t) \ ((((mad_fixed64_t) (x) * (y)) + \ (1L << (MAD_F_SCALEBITS - 1))) >> MAD_F_SCALEBITS)) # else # define mad_f_mul(x, y) \ ((mad_fixed_t) (((mad_fixed64_t) (x) * (y)) >> MAD_F_SCALEBITS)) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- Intel --------------------------------------------------------------- */ # elif defined(FPM_INTEL) # if defined(_MSC_VER) # pragma warning(push) # pragma warning(disable: 4035) /* no return value */ static __forceinline mad_fixed_t mad_f_mul_inline(mad_fixed_t x, mad_fixed_t y) { enum { fracbits = MAD_F_FRACBITS }; __asm { mov eax, x imul y shrd eax, edx, fracbits } /* implicit return of eax */ } # pragma warning(pop) # define mad_f_mul mad_f_mul_inline # define mad_f_scale64 # else /* * This Intel version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ asm ("imull %3" \ : "=a" (lo), "=d" (hi) \ : "%a" (x), "rm" (y) \ : "cc") # if defined(OPT_ACCURACY) /* * This gives best accuracy but is not very fast. */ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ asm ("addl %2,%0\n\t" \ "adcl %3,%1" \ : "=rm" (lo), "=rm" (hi) \ : "r" (__lo), "r" (__hi), "0" (lo), "1" (hi) \ : "cc"); \ }) # endif /* OPT_ACCURACY */ # if defined(OPT_ACCURACY) /* * Surprisingly, this is faster than SHRD followed by ADC. */ # define mad_f_scale64(hi, lo) \ ({ mad_fixed64hi_t __hi_; \ mad_fixed64lo_t __lo_; \ mad_fixed_t __result; \ asm ("addl %4,%2\n\t" \ "adcl %5,%3" \ : "=rm" (__lo_), "=rm" (__hi_) \ : "0" (lo), "1" (hi), \ "ir" (1L << (MAD_F_SCALEBITS - 1)), "ir" (0) \ : "cc"); \ asm ("shrdl %3,%2,%1" \ : "=rm" (__result) \ : "0" (__lo_), "r" (__hi_), "I" (MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # elif defined(OPT_INTEL) /* * Alternate Intel scaling that may or may not perform better. */ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrl %3,%1\n\t" \ "shll %4,%2\n\t" \ "orl %2,%1" \ : "=rm" (__result) \ : "0" (lo), "r" (hi), \ "I" (MAD_F_SCALEBITS), "I" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # else # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("shrdl %3,%2,%1" \ : "=rm" (__result) \ : "0" (lo), "r" (hi), "I" (MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # endif /* OPT_ACCURACY */ # define MAD_F_SCALEBITS MAD_F_FRACBITS # endif /* --- ARM ----------------------------------------------------------------- */ # elif defined(FPM_ARM) /* * This ARM V4 version is as accurate as FPM_64BIT but much faster. The * least significant bit is properly rounded at no CPU cycle cost! */ # if 1 /* * This is faster than the default implementation via MAD_F_MLX() and * mad_f_scale64(). */ # define mad_f_mul(x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ mad_fixed_t __result; \ asm ("smull %0, %1, %3, %4\n\t" \ "movs %0, %0, lsr %5\n\t" \ "adc %2, %0, %1, lsl %6" \ : "=&r" (__lo), "=&r" (__hi), "=r" (__result) \ : "%r" (x), "r" (y), \ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # endif # define MAD_F_MLX(hi, lo, x, y) \ asm ("smull %0, %1, %2, %3" \ : "=&r" (lo), "=&r" (hi) \ : "%r" (x), "r" (y)) # define MAD_F_MLA(hi, lo, x, y) \ asm ("smlal %0, %1, %2, %3" \ : "+r" (lo), "+r" (hi) \ : "%r" (x), "r" (y)) # define MAD_F_MLN(hi, lo) \ asm ("rsbs %0, %2, #0\n\t" \ "rsc %1, %3, #0" \ : "=r" (lo), "=r" (hi) \ : "0" (lo), "1" (hi) \ : "cc") # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("movs %0, %1, lsr %3\n\t" \ "adc %0, %0, %2, lsl %4" \ : "=&r" (__result) \ : "r" (lo), "r" (hi), \ "M" (MAD_F_SCALEBITS), "M" (32 - MAD_F_SCALEBITS) \ : "cc"); \ __result; \ }) # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- MIPS ---------------------------------------------------------------- */ # elif defined(FPM_MIPS) /* * This MIPS version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ : "%r" (x), "r" (y)) # if defined(HAVE_MADD_ASM) # define MAD_F_MLA(hi, lo, x, y) \ asm ("madd %2,%3" \ : "+l" (lo), "+h" (hi) \ : "%r" (x), "r" (y)) # elif defined(HAVE_MADD16_ASM) /* * This loses significant accuracy due to the 16-bit integer limit in the * multiply/accumulate instruction. */ # define MAD_F_ML0(hi, lo, x, y) \ asm ("mult %2,%3" \ : "=l" (lo), "=h" (hi) \ : "%r" ((x) >> 12), "r" ((y) >> 16)) # define MAD_F_MLA(hi, lo, x, y) \ asm ("madd16 %2,%3" \ : "+l" (lo), "+h" (hi) \ : "%r" ((x) >> 12), "r" ((y) >> 16)) # define MAD_F_MLZ(hi, lo) ((mad_fixed_t) (lo)) # endif # if defined(OPT_SPEED) # define mad_f_scale64(hi, lo) \ ((mad_fixed_t) ((hi) << (32 - MAD_F_SCALEBITS))) # define MAD_F_SCALEBITS MAD_F_FRACBITS # endif /* --- SPARC --------------------------------------------------------------- */ # elif defined(FPM_SPARC) /* * This SPARC V8 version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ asm ("smul %2, %3, %0\n\t" \ "rd %%y, %1" \ : "=r" (lo), "=r" (hi) \ : "%r" (x), "rI" (y)) /* --- PowerPC ------------------------------------------------------------- */ # elif defined(FPM_PPC) /* * This PowerPC version is fast and accurate; the disposition of the least * significant bit depends on OPT_ACCURACY via mad_f_scale64(). */ # define MAD_F_MLX(hi, lo, x, y) \ do { \ asm ("mullw %0,%1,%2" \ : "=r" (lo) \ : "%r" (x), "r" (y)); \ asm ("mulhw %0,%1,%2" \ : "=r" (hi) \ : "%r" (x), "r" (y)); \ } \ while (0) # if defined(OPT_ACCURACY) /* * This gives best accuracy but is not very fast. */ # define MAD_F_MLA(hi, lo, x, y) \ ({ mad_fixed64hi_t __hi; \ mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ asm ("addc %0,%2,%3\n\t" \ "adde %1,%4,%5" \ : "=r" (lo), "=r" (hi) \ : "%r" (lo), "r" (__lo), \ "%r" (hi), "r" (__hi) \ : "xer"); \ }) # endif # if defined(OPT_ACCURACY) /* * This is slower than the truncating version below it. */ # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result, __round; \ asm ("rotrwi %0,%1,%2" \ : "=r" (__result) \ : "r" (lo), "i" (MAD_F_SCALEBITS)); \ asm ("extrwi %0,%1,1,0" \ : "=r" (__round) \ : "r" (__result)); \ asm ("insrwi %0,%1,%2,0" \ : "+r" (__result) \ : "r" (hi), "i" (MAD_F_SCALEBITS)); \ asm ("add %0,%1,%2" \ : "=r" (__result) \ : "%r" (__result), "r" (__round)); \ __result; \ }) # else # define mad_f_scale64(hi, lo) \ ({ mad_fixed_t __result; \ asm ("rotrwi %0,%1,%2" \ : "=r" (__result) \ : "r" (lo), "i" (MAD_F_SCALEBITS)); \ asm ("insrwi %0,%1,%2,0" \ : "+r" (__result) \ : "r" (hi), "i" (MAD_F_SCALEBITS)); \ __result; \ }) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS /* --- Default ------------------------------------------------------------- */ # elif defined(FPM_DEFAULT) /* * This version is the most portable but it loses significant accuracy. * Furthermore, accuracy is biased against the second argument, so care * should be taken when ordering operands. * * The scale factors are constant as this is not used with SSO. * * Pre-rounding is required to stay within the limits of compliance. */ # if defined(OPT_SPEED) # define mad_f_mul(x, y) (((x) >> 12) * ((y) >> 16)) # else # define mad_f_mul(x, y) ((((x) + (1L << 11)) >> 12) * \ (((y) + (1L << 15)) >> 16)) # endif /* ------------------------------------------------------------------------- */ # else # error "no FPM selected" # endif /* default implementations */ # if !defined(mad_f_mul) # define mad_f_mul(x, y) \ ({ register mad_fixed64hi_t __hi; \ register mad_fixed64lo_t __lo; \ MAD_F_MLX(__hi, __lo, (x), (y)); \ mad_f_scale64(__hi, __lo); \ }) # endif # if !defined(MAD_F_MLA) # define MAD_F_ML0(hi, lo, x, y) ((lo) = mad_f_mul((x), (y))) # define MAD_F_MLA(hi, lo, x, y) ((lo) += mad_f_mul((x), (y))) # define MAD_F_MLN(hi, lo) ((lo) = -(lo)) # define MAD_F_MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # endif # if !defined(MAD_F_ML0) # define MAD_F_ML0(hi, lo, x, y) MAD_F_MLX((hi), (lo), (x), (y)) # endif # if !defined(MAD_F_MLN) # define MAD_F_MLN(hi, lo) ((hi) = ((lo) = -(lo)) ? ~(hi) : -(hi)) # endif # if !defined(MAD_F_MLZ) # define MAD_F_MLZ(hi, lo) mad_f_scale64((hi), (lo)) # endif # if !defined(mad_f_scale64) # if defined(OPT_ACCURACY) # define mad_f_scale64(hi, lo) \ ((((mad_fixed_t) \ (((hi) << (32 - (MAD_F_SCALEBITS - 1))) | \ ((lo) >> (MAD_F_SCALEBITS - 1)))) + 1) >> 1) # else # define mad_f_scale64(hi, lo) \ ((mad_fixed_t) \ (((hi) << (32 - MAD_F_SCALEBITS)) | \ ((lo) >> MAD_F_SCALEBITS))) # endif # define MAD_F_SCALEBITS MAD_F_FRACBITS # endif /* C routines */ mad_fixed_t mad_f_abs(mad_fixed_t); mad_fixed_t mad_f_div(mad_fixed_t, mad_fixed_t); # endif xine-lib-1.2/contrib/libmad/decoder.c0000644000175000017500000002657014647725152015337 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: decoder.c,v 1.22 2004/01/23 09:41:32 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # ifdef HAVE_SYS_TYPES_H # include # endif # ifdef HAVE_SYS_WAIT_H # include # endif # ifdef HAVE_UNISTD_H # include # endif # ifdef HAVE_FCNTL_H # include # endif # include # ifdef HAVE_ERRNO_H # include # endif # include "stream.h" # include "frame.h" # include "synth.h" # include "decoder.h" /* * NAME: decoder->init() * DESCRIPTION: initialize a decoder object with callback routines */ void mad_decoder_init(struct mad_decoder *decoder, void *data, enum mad_flow (*input_func)(void *, struct mad_stream *), enum mad_flow (*header_func)(void *, struct mad_header const *), enum mad_flow (*filter_func)(void *, struct mad_stream const *, struct mad_frame *), enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *), enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *), enum mad_flow (*message_func)(void *, void *, unsigned int *)) { decoder->mode = -1; decoder->options = 0; decoder->async.pid = 0; decoder->async.in = -1; decoder->async.out = -1; decoder->sync = 0; decoder->cb_data = data; decoder->input_func = input_func; decoder->header_func = header_func; decoder->filter_func = filter_func; decoder->output_func = output_func; decoder->error_func = error_func; decoder->message_func = message_func; } int mad_decoder_finish(struct mad_decoder *decoder) { # if defined(USE_ASYNC) if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) { pid_t pid; int status; close(decoder->async.in); do pid = waitpid(decoder->async.pid, &status, 0); while (pid == -1 && errno == EINTR); decoder->mode = -1; close(decoder->async.out); decoder->async.pid = 0; decoder->async.in = -1; decoder->async.out = -1; if (pid == -1) return -1; return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0; } #else (void)decoder; # endif return 0; } # if defined(USE_ASYNC) static enum mad_flow send_io(int fd, void const *data, size_t len) { char const *ptr = data; ssize_t count; while (len) { do count = write(fd, ptr, len); while (count == -1 && errno == EINTR); if (count == -1) return MAD_FLOW_BREAK; len -= count; ptr += count; } return MAD_FLOW_CONTINUE; } static enum mad_flow receive_io(int fd, void *buffer, size_t len) { char *ptr = buffer; ssize_t count; while (len) { do count = read(fd, ptr, len); while (count == -1 && errno == EINTR); if (count == -1) return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK; else if (count == 0) return MAD_FLOW_STOP; len -= count; ptr += count; } return MAD_FLOW_CONTINUE; } static enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len) { int flags, blocking; enum mad_flow result; flags = fcntl(fd, F_GETFL); if (flags == -1) return MAD_FLOW_BREAK; blocking = flags & ~O_NONBLOCK; if (blocking != flags && fcntl(fd, F_SETFL, blocking) == -1) return MAD_FLOW_BREAK; result = receive_io(fd, buffer, len); if (flags != blocking && fcntl(fd, F_SETFL, flags) == -1) return MAD_FLOW_BREAK; return result; } static enum mad_flow send(int fd, void const *message, unsigned int size) { enum mad_flow result; /* send size */ result = send_io(fd, &size, sizeof(size)); /* send message */ if (result == MAD_FLOW_CONTINUE) result = send_io(fd, message, size); return result; } static enum mad_flow receive(int fd, void **message, unsigned int *size) { enum mad_flow result; unsigned int actual; if (*message == 0) *size = 0; /* receive size */ result = receive_io(fd, &actual, sizeof(actual)); /* receive message */ if (result == MAD_FLOW_CONTINUE) { if (actual > *size) actual -= *size; else { *size = actual; actual = 0; } if (*size > 0) { if (*message == 0) { *message = malloc(*size); if (*message == 0) return MAD_FLOW_BREAK; } result = receive_io_blocking(fd, *message, *size); } /* throw away remainder of message */ while (actual && result == MAD_FLOW_CONTINUE) { char sink[256]; unsigned int len; len = actual > sizeof(sink) ? sizeof(sink) : actual; result = receive_io_blocking(fd, sink, len); actual -= len; } } return result; } static enum mad_flow check_message(struct mad_decoder *decoder) { enum mad_flow result; void *message = 0; unsigned int size; result = receive(decoder->async.in, &message, &size); if (result == MAD_FLOW_CONTINUE) { if (decoder->message_func == 0) size = 0; else { result = decoder->message_func(decoder->cb_data, message, &size); if (result == MAD_FLOW_IGNORE || result == MAD_FLOW_BREAK) size = 0; } if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE) result = MAD_FLOW_BREAK; } if (message) free(message); return result; } # endif static enum mad_flow error_default(void *data, struct mad_stream *stream, struct mad_frame *frame) { int *bad_last_frame = data; switch (stream->error) { case MAD_ERROR_BADCRC: if (*bad_last_frame) mad_frame_mute(frame); else *bad_last_frame = 1; return MAD_FLOW_IGNORE; default: return MAD_FLOW_CONTINUE; } } static int run_sync(struct mad_decoder *decoder) { enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); void *error_data; int bad_last_frame = 0; struct mad_stream *stream; struct mad_frame *frame; struct mad_synth *synth; int result = 0; if (decoder->input_func == 0) return 0; if (decoder->error_func) { error_func = decoder->error_func; error_data = decoder->cb_data; } else { error_func = error_default; error_data = &bad_last_frame; } stream = &decoder->sync->stream; frame = &decoder->sync->frame; synth = &decoder->sync->synth; mad_stream_init(stream); mad_frame_init(frame); mad_synth_init(synth); mad_stream_options(stream, decoder->options); do { switch (decoder->input_func(decoder->cb_data, stream)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } while (1) { # if defined(USE_ASYNC) if (decoder->mode == MAD_DECODER_MODE_ASYNC) { switch (check_message(decoder)) { case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: break; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_STOP: goto done; } } # endif if (decoder->header_func) { if (mad_header_decode(&frame->header, stream) == -1) { if (!MAD_RECOVERABLE(stream->error)) break; switch (error_func(error_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: default: continue; } } switch (decoder->header_func(decoder->cb_data, &frame->header)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } } if (mad_frame_decode(frame, stream) == -1) { if (!MAD_RECOVERABLE(stream->error)) break; switch (error_func(error_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: break; case MAD_FLOW_CONTINUE: default: continue; } } else bad_last_frame = 0; if (decoder->filter_func) { switch (decoder->filter_func(decoder->cb_data, stream, frame)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: continue; case MAD_FLOW_CONTINUE: break; } } mad_synth_frame(synth, frame); if (decoder->output_func) { switch (decoder->output_func(decoder->cb_data, &frame->header, &synth->pcm)) { case MAD_FLOW_STOP: goto done; case MAD_FLOW_BREAK: goto fail; case MAD_FLOW_IGNORE: case MAD_FLOW_CONTINUE: break; } } } } while (stream->error == MAD_ERROR_BUFLEN); fail: result = -1; done: mad_synth_finish(synth); mad_frame_finish(frame); mad_stream_finish(stream); return result; } # if defined(USE_ASYNC) static int run_async(struct mad_decoder *decoder) { pid_t pid; int ptoc[2], ctop[2], flags; if (pipe(ptoc) == -1) return -1; if (pipe(ctop) == -1) { close(ptoc[0]); close(ptoc[1]); return -1; } flags = fcntl(ptoc[0], F_GETFL); if (flags == -1 || fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) { close(ctop[0]); close(ctop[1]); close(ptoc[0]); close(ptoc[1]); return -1; } pid = fork(); if (pid == -1) { close(ctop[0]); close(ctop[1]); close(ptoc[0]); close(ptoc[1]); return -1; } decoder->async.pid = pid; if (pid) { /* parent */ close(ptoc[0]); close(ctop[1]); decoder->async.in = ctop[0]; decoder->async.out = ptoc[1]; return 0; } /* child */ close(ptoc[1]); close(ctop[0]); decoder->async.in = ptoc[0]; decoder->async.out = ctop[1]; _exit(run_sync(decoder)); /* not reached */ return -1; } # endif /* * NAME: decoder->run() * DESCRIPTION: run the decoder thread either synchronously or asynchronously */ int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode) { int result; int (*run)(struct mad_decoder *) = 0; switch (decoder->mode = mode) { case MAD_DECODER_MODE_SYNC: run = run_sync; break; case MAD_DECODER_MODE_ASYNC: # if defined(USE_ASYNC) run = run_async; # endif break; } if (run == 0) return -1; decoder->sync = malloc(sizeof(*decoder->sync)); if (decoder->sync == 0) return -1; result = run(decoder); free(decoder->sync); decoder->sync = 0; return result; } /* * NAME: decoder->message() * DESCRIPTION: send a message to and receive a reply from the decoder process */ int mad_decoder_message(struct mad_decoder *decoder, void *message, unsigned int *len) { # if defined(USE_ASYNC) if (decoder->mode != MAD_DECODER_MODE_ASYNC || send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE || receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE) return -1; return 0; # else (void)decoder; (void)message; (void)len; return -1; # endif } xine-lib-1.2/contrib/libmad/layer3.h0000644000175000017500000000201514647725152015122 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer3.h,v 1.10 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_LAYER3_H # define LIBMAD_LAYER3_H # include "stream.h" # include "frame.h" int mad_layer_III(struct mad_stream *, struct mad_frame *); # endif xine-lib-1.2/contrib/libmad/Makefile.am0000644000175000017500000000300614647725152015607 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) AM_CPPFLAGS += -DOPT_SPEED EXTRA_DIST = COPYING if ENABLE_MAD if !WITH_EXTERNAL_MAD noinst_LTLIBRARIES = libmad.la endif endif ## ## libmad - MPEG audio decoder library ## Copyright (C) 2000-2004 Underbit Technologies, Inc. ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ## ## $Id: Makefile.am,v 1.23 2004/02/17 02:02:03 rob Exp $ ## exported_headers = version.h fixed.h bit.h timer.h stream.h frame.h \ synth.h decoder.h headers = $(exported_headers) \ global.h layer12.h layer3.h huffman.h data_includes = D.dat imdct_s.dat qc_table.dat rq_table.dat \ sf_table.dat libmad_la_SOURCES = version.c fixed.c bit.c timer.c stream.c frame.c \ synth.c decoder.c layer12.c layer3.c huffman.c \ $(headers) $(data_includes) xine-lib-1.2/contrib/libmad/fixed.c0000644000175000017500000000340314647725152015017 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: fixed.c,v 1.13 2004/01/23 09:41:32 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include "fixed.h" /* * NAME: fixed->abs() * DESCRIPTION: return absolute value of a fixed-point number */ mad_fixed_t mad_f_abs(mad_fixed_t x) { return x < 0 ? -x : x; } /* * NAME: fixed->div() * DESCRIPTION: perform division using fixed-point math */ mad_fixed_t mad_f_div(mad_fixed_t x, mad_fixed_t y) { mad_fixed_t q, r; unsigned int bits; q = mad_f_abs(x / y); if (x < 0) { x = -x; y = -y; } r = x % y; if (y < 0) { x = -x; y = -y; } if (q > mad_f_intpart(MAD_F_MAX) && !(q == -mad_f_intpart(MAD_F_MIN) && r == 0 && (x < 0) != (y < 0))) return 0; for (bits = MAD_F_FRACBITS; bits && r; --bits) { q <<= 1, r <<= 1; if (r >= y) r -= y, ++q; } /* round */ if (2 * r >= y) ++q; /* fix sign */ if ((x < 0) != (y < 0)) q = -q; return q << bits; } xine-lib-1.2/contrib/libmad/huffman.c0000644000175000017500000021676414647725151015363 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: huffman.c,v 1.10 2004/01/23 09:41:32 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include "huffman.h" /* * These are the Huffman code words for Layer III. * The data for these tables are derived from Table B.7 of ISO/IEC 11172-3. * * These tables support decoding up to 4 Huffman code bits at a time. */ # if defined(__GNUC__) || \ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901) # define PTR(offs, bits) { .ptr = { 0, bits, offs } } # define V(v, w, x, y, hlen) { .value = { 1, hlen, v, w, x, y } } # else # define PTR(offs, bits) { { 0, bits, offs } } # if defined(WORDS_BIGENDIAN) # define V(v, w, x, y, hlen) { { 1, hlen, (v << 11) | (w << 10) | \ (x << 9) | (y << 8) } } # else # define V(v, w, x, y, hlen) { { 1, hlen, (v << 0) | (w << 1) | \ (x << 2) | (y << 3) } } # endif # endif static union huffquad const hufftabA[] = { /* 0000 */ PTR(16, 2), /* 0001 */ PTR(20, 2), /* 0010 */ PTR(24, 1), /* 0011 */ PTR(26, 1), /* 0100 */ V(0, 0, 1, 0, 4), /* 0101 */ V(0, 0, 0, 1, 4), /* 0110 */ V(0, 1, 0, 0, 4), /* 0111 */ V(1, 0, 0, 0, 4), /* 1000 */ V(0, 0, 0, 0, 1), /* 1001 */ V(0, 0, 0, 0, 1), /* 1010 */ V(0, 0, 0, 0, 1), /* 1011 */ V(0, 0, 0, 0, 1), /* 1100 */ V(0, 0, 0, 0, 1), /* 1101 */ V(0, 0, 0, 0, 1), /* 1110 */ V(0, 0, 0, 0, 1), /* 1111 */ V(0, 0, 0, 0, 1), /* 0000 ... */ /* 00 */ V(1, 0, 1, 1, 2), /* 16 */ /* 01 */ V(1, 1, 1, 1, 2), /* 10 */ V(1, 1, 0, 1, 2), /* 11 */ V(1, 1, 1, 0, 2), /* 0001 ... */ /* 00 */ V(0, 1, 1, 1, 2), /* 20 */ /* 01 */ V(0, 1, 0, 1, 2), /* 10 */ V(1, 0, 0, 1, 1), /* 11 */ V(1, 0, 0, 1, 1), /* 0010 ... */ /* 0 */ V(0, 1, 1, 0, 1), /* 24 */ /* 1 */ V(0, 0, 1, 1, 1), /* 0011 ... */ /* 0 */ V(1, 0, 1, 0, 1), /* 26 */ /* 1 */ V(1, 1, 0, 0, 1) }; static union huffquad const hufftabB[] = { /* 0000 */ V(1, 1, 1, 1, 4), /* 0001 */ V(1, 1, 1, 0, 4), /* 0010 */ V(1, 1, 0, 1, 4), /* 0011 */ V(1, 1, 0, 0, 4), /* 0100 */ V(1, 0, 1, 1, 4), /* 0101 */ V(1, 0, 1, 0, 4), /* 0110 */ V(1, 0, 0, 1, 4), /* 0111 */ V(1, 0, 0, 0, 4), /* 1000 */ V(0, 1, 1, 1, 4), /* 1001 */ V(0, 1, 1, 0, 4), /* 1010 */ V(0, 1, 0, 1, 4), /* 1011 */ V(0, 1, 0, 0, 4), /* 1100 */ V(0, 0, 1, 1, 4), /* 1101 */ V(0, 0, 1, 0, 4), /* 1110 */ V(0, 0, 0, 1, 4), /* 1111 */ V(0, 0, 0, 0, 4) }; # undef V # undef PTR # if defined(__GNUC__) || \ (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901) # define PTR(offs, bits) { .ptr = { 0, bits, offs } } # define V(x, y, hlen) { .value = { 1, hlen, x, y } } # else # define PTR(offs, bits) { { 0, bits, offs } } # if defined(WORDS_BIGENDIAN) # define V(x, y, hlen) { { 1, hlen, (x << 8) | (y << 4) } } # else # define V(x, y, hlen) { { 1, hlen, (x << 0) | (y << 4) } } # endif # endif static union huffpair const hufftab0[] = { /* */ V(0, 0, 0) }; static union huffpair const hufftab1[] = { /* 000 */ V(1, 1, 3), /* 001 */ V(0, 1, 3), /* 010 */ V(1, 0, 2), /* 011 */ V(1, 0, 2), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1) }; static union huffpair const hufftab2[] = { /* 000 */ PTR(8, 3), /* 001 */ V(1, 1, 3), /* 010 */ V(0, 1, 3), /* 011 */ V(1, 0, 3), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1), /* 000 ... */ /* 000 */ V(2, 2, 3), /* 8 */ /* 001 */ V(0, 2, 3), /* 010 */ V(1, 2, 2), /* 011 */ V(1, 2, 2), /* 100 */ V(2, 1, 2), /* 101 */ V(2, 1, 2), /* 110 */ V(2, 0, 2), /* 111 */ V(2, 0, 2) }; static union huffpair const hufftab3[] = { /* 000 */ PTR(8, 3), /* 001 */ V(1, 0, 3), /* 010 */ V(1, 1, 2), /* 011 */ V(1, 1, 2), /* 100 */ V(0, 1, 2), /* 101 */ V(0, 1, 2), /* 110 */ V(0, 0, 2), /* 111 */ V(0, 0, 2), /* 000 ... */ /* 000 */ V(2, 2, 3), /* 8 */ /* 001 */ V(0, 2, 3), /* 010 */ V(1, 2, 2), /* 011 */ V(1, 2, 2), /* 100 */ V(2, 1, 2), /* 101 */ V(2, 1, 2), /* 110 */ V(2, 0, 2), /* 111 */ V(2, 0, 2) }; static union huffpair const hufftab5[] = { /* 000 */ PTR(8, 4), /* 001 */ V(1, 1, 3), /* 010 */ V(0, 1, 3), /* 011 */ V(1, 0, 3), /* 100 */ V(0, 0, 1), /* 101 */ V(0, 0, 1), /* 110 */ V(0, 0, 1), /* 111 */ V(0, 0, 1), /* 000 ... */ /* 0000 */ PTR(24, 1), /* 8 */ /* 0001 */ V(3, 2, 4), /* 0010 */ V(3, 1, 3), /* 0011 */ V(3, 1, 3), /* 0100 */ V(1, 3, 4), /* 0101 */ V(0, 3, 4), /* 0110 */ V(3, 0, 4), /* 0111 */ V(2, 2, 4), /* 1000 */ V(1, 2, 3), /* 1001 */ V(1, 2, 3), /* 1010 */ V(2, 1, 3), /* 1011 */ V(2, 1, 3), /* 1100 */ V(0, 2, 3), /* 1101 */ V(0, 2, 3), /* 1110 */ V(2, 0, 3), /* 1111 */ V(2, 0, 3), /* 000 0000 ... */ /* 0 */ V(3, 3, 1), /* 24 */ /* 1 */ V(2, 3, 1) }; static union huffpair const hufftab6[] = { /* 0000 */ PTR(16, 3), /* 0001 */ PTR(24, 1), /* 0010 */ PTR(26, 1), /* 0011 */ V(1, 2, 4), /* 0100 */ V(2, 1, 4), /* 0101 */ V(2, 0, 4), /* 0110 */ V(0, 1, 3), /* 0111 */ V(0, 1, 3), /* 1000 */ V(1, 1, 2), /* 1001 */ V(1, 1, 2), /* 1010 */ V(1, 1, 2), /* 1011 */ V(1, 1, 2), /* 1100 */ V(1, 0, 3), /* 1101 */ V(1, 0, 3), /* 1110 */ V(0, 0, 3), /* 1111 */ V(0, 0, 3), /* 0000 ... */ /* 000 */ V(3, 3, 3), /* 16 */ /* 001 */ V(0, 3, 3), /* 010 */ V(2, 3, 2), /* 011 */ V(2, 3, 2), /* 100 */ V(3, 2, 2), /* 101 */ V(3, 2, 2), /* 110 */ V(3, 0, 2), /* 111 */ V(3, 0, 2), /* 0001 ... */ /* 0 */ V(1, 3, 1), /* 24 */ /* 1 */ V(3, 1, 1), /* 0010 ... */ /* 0 */ V(2, 2, 1), /* 26 */ /* 1 */ V(0, 2, 1) }; static union huffpair const hufftab7[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 2), /* 0011 */ V(1, 1, 4), /* 0100 */ V(0, 1, 3), /* 0101 */ V(0, 1, 3), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(52, 2), /* 16 */ /* 0001 */ PTR(56, 1), /* 0010 */ PTR(58, 1), /* 0011 */ V(1, 5, 4), /* 0100 */ V(5, 1, 4), /* 0101 */ PTR(60, 1), /* 0110 */ V(5, 0, 4), /* 0111 */ PTR(62, 1), /* 1000 */ V(2, 4, 4), /* 1001 */ V(4, 2, 4), /* 1010 */ V(1, 4, 3), /* 1011 */ V(1, 4, 3), /* 1100 */ V(4, 1, 3), /* 1101 */ V(4, 1, 3), /* 1110 */ V(4, 0, 3), /* 1111 */ V(4, 0, 3), /* 0001 ... */ /* 0000 */ V(0, 4, 4), /* 32 */ /* 0001 */ V(2, 3, 4), /* 0010 */ V(3, 2, 4), /* 0011 */ V(0, 3, 4), /* 0100 */ V(1, 3, 3), /* 0101 */ V(1, 3, 3), /* 0110 */ V(3, 1, 3), /* 0111 */ V(3, 1, 3), /* 1000 */ V(3, 0, 3), /* 1001 */ V(3, 0, 3), /* 1010 */ V(2, 2, 3), /* 1011 */ V(2, 2, 3), /* 1100 */ V(1, 2, 2), /* 1101 */ V(1, 2, 2), /* 1110 */ V(1, 2, 2), /* 1111 */ V(1, 2, 2), /* 0010 ... */ /* 00 */ V(2, 1, 1), /* 48 */ /* 01 */ V(2, 1, 1), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 00 */ V(5, 5, 2), /* 52 */ /* 01 */ V(4, 5, 2), /* 10 */ V(5, 4, 2), /* 11 */ V(5, 3, 2), /* 0000 0001 ... */ /* 0 */ V(3, 5, 1), /* 56 */ /* 1 */ V(4, 4, 1), /* 0000 0010 ... */ /* 0 */ V(2, 5, 1), /* 58 */ /* 1 */ V(5, 2, 1), /* 0000 0101 ... */ /* 0 */ V(0, 5, 1), /* 60 */ /* 1 */ V(3, 4, 1), /* 0000 0111 ... */ /* 0 */ V(4, 3, 1), /* 62 */ /* 1 */ V(3, 3, 1) }; # if 0 /* this version saves 8 entries (16 bytes) at the expense of an extra lookup in 4 out of 36 cases */ static union huffpair const hufftab8[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 2), /* 0010 */ V(1, 2, 4), /* 0011 */ V(2, 1, 4), /* 0100 */ V(1, 1, 2), /* 0101 */ V(1, 1, 2), /* 0110 */ V(1, 1, 2), /* 0111 */ V(1, 1, 2), /* 1000 */ V(0, 1, 3), /* 1001 */ V(0, 1, 3), /* 1010 */ V(1, 0, 3), /* 1011 */ V(1, 0, 3), /* 1100 */ V(0, 0, 2), /* 1101 */ V(0, 0, 2), /* 1110 */ V(0, 0, 2), /* 1111 */ V(0, 0, 2), /* 0000 ... */ /* 0000 */ PTR(36, 3), /* 16 */ /* 0001 */ PTR(44, 2), /* 0010 */ PTR(48, 1), /* 0011 */ V(1, 5, 4), /* 0100 */ V(5, 1, 4), /* 0101 */ PTR(50, 1), /* 0110 */ PTR(52, 1), /* 0111 */ V(2, 4, 4), /* 1000 */ V(4, 2, 4), /* 1001 */ V(1, 4, 4), /* 1010 */ V(4, 1, 3), /* 1011 */ V(4, 1, 3), /* 1100 */ V(0, 4, 4), /* 1101 */ V(4, 0, 4), /* 1110 */ V(2, 3, 4), /* 1111 */ V(3, 2, 4), /* 0001 ... */ /* 00 */ PTR(54, 2), /* 32 */ /* 01 */ V(2, 2, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(5, 5, 3), /* 36 */ /* 001 */ V(5, 4, 3), /* 010 */ V(4, 5, 2), /* 011 */ V(4, 5, 2), /* 100 */ V(5, 3, 1), /* 101 */ V(5, 3, 1), /* 110 */ V(5, 3, 1), /* 111 */ V(5, 3, 1), /* 0000 0001 ... */ /* 00 */ V(3, 5, 2), /* 44 */ /* 01 */ V(4, 4, 2), /* 10 */ V(2, 5, 1), /* 11 */ V(2, 5, 1), /* 0000 0010 ... */ /* 0 */ V(5, 2, 1), /* 48 */ /* 1 */ V(0, 5, 1), /* 0000 0101 ... */ /* 0 */ V(3, 4, 1), /* 50 */ /* 1 */ V(4, 3, 1), /* 0000 0110 ... */ /* 0 */ V(5, 0, 1), /* 52 */ /* 1 */ V(3, 3, 1), /* 0001 00 ... */ /* 00 */ V(1, 3, 2), /* 54 */ /* 01 */ V(3, 1, 2), /* 10 */ V(0, 3, 2), /* 11 */ V(3, 0, 2), }; # else static union huffpair const hufftab8[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ V(1, 2, 4), /* 0011 */ V(2, 1, 4), /* 0100 */ V(1, 1, 2), /* 0101 */ V(1, 1, 2), /* 0110 */ V(1, 1, 2), /* 0111 */ V(1, 1, 2), /* 1000 */ V(0, 1, 3), /* 1001 */ V(0, 1, 3), /* 1010 */ V(1, 0, 3), /* 1011 */ V(1, 0, 3), /* 1100 */ V(0, 0, 2), /* 1101 */ V(0, 0, 2), /* 1110 */ V(0, 0, 2), /* 1111 */ V(0, 0, 2), /* 0000 ... */ /* 0000 */ PTR(48, 3), /* 16 */ /* 0001 */ PTR(56, 2), /* 0010 */ PTR(60, 1), /* 0011 */ V(1, 5, 4), /* 0100 */ V(5, 1, 4), /* 0101 */ PTR(62, 1), /* 0110 */ PTR(64, 1), /* 0111 */ V(2, 4, 4), /* 1000 */ V(4, 2, 4), /* 1001 */ V(1, 4, 4), /* 1010 */ V(4, 1, 3), /* 1011 */ V(4, 1, 3), /* 1100 */ V(0, 4, 4), /* 1101 */ V(4, 0, 4), /* 1110 */ V(2, 3, 4), /* 1111 */ V(3, 2, 4), /* 0001 ... */ /* 0000 */ V(1, 3, 4), /* 32 */ /* 0001 */ V(3, 1, 4), /* 0010 */ V(0, 3, 4), /* 0011 */ V(3, 0, 4), /* 0100 */ V(2, 2, 2), /* 0101 */ V(2, 2, 2), /* 0110 */ V(2, 2, 2), /* 0111 */ V(2, 2, 2), /* 1000 */ V(0, 2, 2), /* 1001 */ V(0, 2, 2), /* 1010 */ V(0, 2, 2), /* 1011 */ V(0, 2, 2), /* 1100 */ V(2, 0, 2), /* 1101 */ V(2, 0, 2), /* 1110 */ V(2, 0, 2), /* 1111 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(5, 5, 3), /* 48 */ /* 001 */ V(5, 4, 3), /* 010 */ V(4, 5, 2), /* 011 */ V(4, 5, 2), /* 100 */ V(5, 3, 1), /* 101 */ V(5, 3, 1), /* 110 */ V(5, 3, 1), /* 111 */ V(5, 3, 1), /* 0000 0001 ... */ /* 00 */ V(3, 5, 2), /* 56 */ /* 01 */ V(4, 4, 2), /* 10 */ V(2, 5, 1), /* 11 */ V(2, 5, 1), /* 0000 0010 ... */ /* 0 */ V(5, 2, 1), /* 60 */ /* 1 */ V(0, 5, 1), /* 0000 0101 ... */ /* 0 */ V(3, 4, 1), /* 62 */ /* 1 */ V(4, 3, 1), /* 0000 0110 ... */ /* 0 */ V(5, 0, 1), /* 64 */ /* 1 */ V(3, 3, 1) }; # endif static union huffpair const hufftab9[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 3), /* 0010 */ PTR(40, 2), /* 0011 */ PTR(44, 2), /* 0100 */ PTR(48, 1), /* 0101 */ V(1, 2, 4), /* 0110 */ V(2, 1, 4), /* 0111 */ V(2, 0, 4), /* 1000 */ V(1, 1, 3), /* 1001 */ V(1, 1, 3), /* 1010 */ V(0, 1, 3), /* 1011 */ V(0, 1, 3), /* 1100 */ V(1, 0, 3), /* 1101 */ V(1, 0, 3), /* 1110 */ V(0, 0, 3), /* 1111 */ V(0, 0, 3), /* 0000 ... */ /* 0000 */ PTR(50, 1), /* 16 */ /* 0001 */ V(3, 5, 4), /* 0010 */ V(5, 3, 4), /* 0011 */ PTR(52, 1), /* 0100 */ V(4, 4, 4), /* 0101 */ V(2, 5, 4), /* 0110 */ V(5, 2, 4), /* 0111 */ V(1, 5, 4), /* 1000 */ V(5, 1, 3), /* 1001 */ V(5, 1, 3), /* 1010 */ V(3, 4, 3), /* 1011 */ V(3, 4, 3), /* 1100 */ V(4, 3, 3), /* 1101 */ V(4, 3, 3), /* 1110 */ V(5, 0, 4), /* 1111 */ V(0, 4, 4), /* 0001 ... */ /* 000 */ V(2, 4, 3), /* 32 */ /* 001 */ V(4, 2, 3), /* 010 */ V(3, 3, 3), /* 011 */ V(4, 0, 3), /* 100 */ V(1, 4, 2), /* 101 */ V(1, 4, 2), /* 110 */ V(4, 1, 2), /* 111 */ V(4, 1, 2), /* 0010 ... */ /* 00 */ V(2, 3, 2), /* 40 */ /* 01 */ V(3, 2, 2), /* 10 */ V(1, 3, 1), /* 11 */ V(1, 3, 1), /* 0011 ... */ /* 00 */ V(3, 1, 1), /* 44 */ /* 01 */ V(3, 1, 1), /* 10 */ V(0, 3, 2), /* 11 */ V(3, 0, 2), /* 0100 ... */ /* 0 */ V(2, 2, 1), /* 48 */ /* 1 */ V(0, 2, 1), /* 0000 0000 ... */ /* 0 */ V(5, 5, 1), /* 50 */ /* 1 */ V(4, 5, 1), /* 0000 0011 ... */ /* 0 */ V(5, 4, 1), /* 52 */ /* 1 */ V(0, 5, 1) }; static union huffpair const hufftab10[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 2), /* 0011 */ V(1, 1, 4), /* 0100 */ V(0, 1, 3), /* 0101 */ V(0, 1, 3), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(52, 3), /* 16 */ /* 0001 */ PTR(60, 2), /* 0010 */ PTR(64, 3), /* 0011 */ PTR(72, 1), /* 0100 */ PTR(74, 2), /* 0101 */ PTR(78, 2), /* 0110 */ PTR(82, 2), /* 0111 */ V(1, 7, 4), /* 1000 */ V(7, 1, 4), /* 1001 */ PTR(86, 1), /* 1010 */ PTR(88, 2), /* 1011 */ PTR(92, 2), /* 1100 */ V(1, 6, 4), /* 1101 */ V(6, 1, 4), /* 1110 */ V(6, 0, 4), /* 1111 */ PTR(96, 1), /* 0001 ... */ /* 0000 */ PTR(98, 1), /* 32 */ /* 0001 */ PTR(100, 1), /* 0010 */ V(1, 4, 4), /* 0011 */ V(4, 1, 4), /* 0100 */ V(4, 0, 4), /* 0101 */ V(2, 3, 4), /* 0110 */ V(3, 2, 4), /* 0111 */ V(0, 3, 4), /* 1000 */ V(1, 3, 3), /* 1001 */ V(1, 3, 3), /* 1010 */ V(3, 1, 3), /* 1011 */ V(3, 1, 3), /* 1100 */ V(3, 0, 3), /* 1101 */ V(3, 0, 3), /* 1110 */ V(2, 2, 3), /* 1111 */ V(2, 2, 3), /* 0010 ... */ /* 00 */ V(1, 2, 2), /* 48 */ /* 01 */ V(2, 1, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(7, 7, 3), /* 52 */ /* 001 */ V(6, 7, 3), /* 010 */ V(7, 6, 3), /* 011 */ V(5, 7, 3), /* 100 */ V(7, 5, 3), /* 101 */ V(6, 6, 3), /* 110 */ V(4, 7, 2), /* 111 */ V(4, 7, 2), /* 0000 0001 ... */ /* 00 */ V(7, 4, 2), /* 60 */ /* 01 */ V(5, 6, 2), /* 10 */ V(6, 5, 2), /* 11 */ V(3, 7, 2), /* 0000 0010 ... */ /* 000 */ V(7, 3, 2), /* 64 */ /* 001 */ V(7, 3, 2), /* 010 */ V(4, 6, 2), /* 011 */ V(4, 6, 2), /* 100 */ V(5, 5, 3), /* 101 */ V(5, 4, 3), /* 110 */ V(6, 3, 2), /* 111 */ V(6, 3, 2), /* 0000 0011 ... */ /* 0 */ V(2, 7, 1), /* 72 */ /* 1 */ V(7, 2, 1), /* 0000 0100 ... */ /* 00 */ V(6, 4, 2), /* 74 */ /* 01 */ V(0, 7, 2), /* 10 */ V(7, 0, 1), /* 11 */ V(7, 0, 1), /* 0000 0101 ... */ /* 00 */ V(6, 2, 1), /* 78 */ /* 01 */ V(6, 2, 1), /* 10 */ V(4, 5, 2), /* 11 */ V(3, 5, 2), /* 0000 0110 ... */ /* 00 */ V(0, 6, 1), /* 82 */ /* 01 */ V(0, 6, 1), /* 10 */ V(5, 3, 2), /* 11 */ V(4, 4, 2), /* 0000 1001 ... */ /* 0 */ V(3, 6, 1), /* 86 */ /* 1 */ V(2, 6, 1), /* 0000 1010 ... */ /* 00 */ V(2, 5, 2), /* 88 */ /* 01 */ V(5, 2, 2), /* 10 */ V(1, 5, 1), /* 11 */ V(1, 5, 1), /* 0000 1011 ... */ /* 00 */ V(5, 1, 1), /* 92 */ /* 01 */ V(5, 1, 1), /* 10 */ V(3, 4, 2), /* 11 */ V(4, 3, 2), /* 0000 1111 ... */ /* 0 */ V(0, 5, 1), /* 96 */ /* 1 */ V(5, 0, 1), /* 0001 0000 ... */ /* 0 */ V(2, 4, 1), /* 98 */ /* 1 */ V(4, 2, 1), /* 0001 0001 ... */ /* 0 */ V(3, 3, 1), /* 100 */ /* 1 */ V(0, 4, 1) }; static union huffpair const hufftab11[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 3), /* 0100 */ V(1, 2, 4), /* 0101 */ PTR(72, 1), /* 0110 */ V(1, 1, 3), /* 0111 */ V(1, 1, 3), /* 1000 */ V(0, 1, 3), /* 1001 */ V(0, 1, 3), /* 1010 */ V(1, 0, 3), /* 1011 */ V(1, 0, 3), /* 1100 */ V(0, 0, 2), /* 1101 */ V(0, 0, 2), /* 1110 */ V(0, 0, 2), /* 1111 */ V(0, 0, 2), /* 0000 ... */ /* 0000 */ PTR(74, 2), /* 16 */ /* 0001 */ PTR(78, 3), /* 0010 */ PTR(86, 2), /* 0011 */ PTR(90, 1), /* 0100 */ PTR(92, 2), /* 0101 */ V(2, 7, 4), /* 0110 */ V(7, 2, 4), /* 0111 */ PTR(96, 1), /* 1000 */ V(7, 1, 3), /* 1001 */ V(7, 1, 3), /* 1010 */ V(1, 7, 4), /* 1011 */ V(7, 0, 4), /* 1100 */ V(3, 6, 4), /* 1101 */ V(6, 3, 4), /* 1110 */ V(6, 0, 4), /* 1111 */ PTR(98, 1), /* 0001 ... */ /* 0000 */ PTR(100, 1), /* 32 */ /* 0001 */ V(1, 5, 4), /* 0010 */ V(6, 2, 3), /* 0011 */ V(6, 2, 3), /* 0100 */ V(2, 6, 4), /* 0101 */ V(0, 6, 4), /* 0110 */ V(1, 6, 3), /* 0111 */ V(1, 6, 3), /* 1000 */ V(6, 1, 3), /* 1001 */ V(6, 1, 3), /* 1010 */ V(5, 1, 4), /* 1011 */ V(3, 4, 4), /* 1100 */ V(5, 0, 4), /* 1101 */ PTR(102, 1), /* 1110 */ V(2, 4, 4), /* 1111 */ V(4, 2, 4), /* 0010 ... */ /* 0000 */ V(1, 4, 4), /* 48 */ /* 0001 */ V(4, 1, 4), /* 0010 */ V(0, 4, 4), /* 0011 */ V(4, 0, 4), /* 0100 */ V(2, 3, 3), /* 0101 */ V(2, 3, 3), /* 0110 */ V(3, 2, 3), /* 0111 */ V(3, 2, 3), /* 1000 */ V(1, 3, 2), /* 1001 */ V(1, 3, 2), /* 1010 */ V(1, 3, 2), /* 1011 */ V(1, 3, 2), /* 1100 */ V(3, 1, 2), /* 1101 */ V(3, 1, 2), /* 1110 */ V(3, 1, 2), /* 1111 */ V(3, 1, 2), /* 0011 ... */ /* 000 */ V(0, 3, 3), /* 64 */ /* 001 */ V(3, 0, 3), /* 010 */ V(2, 2, 2), /* 011 */ V(2, 2, 2), /* 100 */ V(2, 1, 1), /* 101 */ V(2, 1, 1), /* 110 */ V(2, 1, 1), /* 111 */ V(2, 1, 1), /* 0101 ... */ /* 0 */ V(0, 2, 1), /* 72 */ /* 1 */ V(2, 0, 1), /* 0000 0000 ... */ /* 00 */ V(7, 7, 2), /* 74 */ /* 01 */ V(6, 7, 2), /* 10 */ V(7, 6, 2), /* 11 */ V(7, 5, 2), /* 0000 0001 ... */ /* 000 */ V(6, 6, 2), /* 78 */ /* 001 */ V(6, 6, 2), /* 010 */ V(4, 7, 2), /* 011 */ V(4, 7, 2), /* 100 */ V(7, 4, 2), /* 101 */ V(7, 4, 2), /* 110 */ V(5, 7, 3), /* 111 */ V(5, 5, 3), /* 0000 0010 ... */ /* 00 */ V(5, 6, 2), /* 86 */ /* 01 */ V(6, 5, 2), /* 10 */ V(3, 7, 1), /* 11 */ V(3, 7, 1), /* 0000 0011 ... */ /* 0 */ V(7, 3, 1), /* 90 */ /* 1 */ V(4, 6, 1), /* 0000 0100 ... */ /* 00 */ V(4, 5, 2), /* 92 */ /* 01 */ V(5, 4, 2), /* 10 */ V(3, 5, 2), /* 11 */ V(5, 3, 2), /* 0000 0111 ... */ /* 0 */ V(6, 4, 1), /* 96 */ /* 1 */ V(0, 7, 1), /* 0000 1111 ... */ /* 0 */ V(4, 4, 1), /* 98 */ /* 1 */ V(2, 5, 1), /* 0001 0000 ... */ /* 0 */ V(5, 2, 1), /* 100 */ /* 1 */ V(0, 5, 1), /* 0001 1101 ... */ /* 0 */ V(4, 3, 1), /* 102 */ /* 1 */ V(3, 3, 1) }; static union huffpair const hufftab12[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 2), /* 0100 */ PTR(68, 3), /* 0101 */ PTR(76, 1), /* 0110 */ V(1, 2, 4), /* 0111 */ V(2, 1, 4), /* 1000 */ PTR(78, 1), /* 1001 */ V(0, 0, 4), /* 1010 */ V(1, 1, 3), /* 1011 */ V(1, 1, 3), /* 1100 */ V(0, 1, 3), /* 1101 */ V(0, 1, 3), /* 1110 */ V(1, 0, 3), /* 1111 */ V(1, 0, 3), /* 0000 ... */ /* 0000 */ PTR(80, 2), /* 16 */ /* 0001 */ PTR(84, 1), /* 0010 */ PTR(86, 1), /* 0011 */ PTR(88, 1), /* 0100 */ V(5, 6, 4), /* 0101 */ V(3, 7, 4), /* 0110 */ PTR(90, 1), /* 0111 */ V(2, 7, 4), /* 1000 */ V(7, 2, 4), /* 1001 */ V(4, 6, 4), /* 1010 */ V(6, 4, 4), /* 1011 */ V(1, 7, 4), /* 1100 */ V(7, 1, 4), /* 1101 */ PTR(92, 1), /* 1110 */ V(3, 6, 4), /* 1111 */ V(6, 3, 4), /* 0001 ... */ /* 0000 */ V(4, 5, 4), /* 32 */ /* 0001 */ V(5, 4, 4), /* 0010 */ V(4, 4, 4), /* 0011 */ PTR(94, 1), /* 0100 */ V(2, 6, 3), /* 0101 */ V(2, 6, 3), /* 0110 */ V(6, 2, 3), /* 0111 */ V(6, 2, 3), /* 1000 */ V(6, 1, 3), /* 1001 */ V(6, 1, 3), /* 1010 */ V(1, 6, 4), /* 1011 */ V(6, 0, 4), /* 1100 */ V(3, 5, 4), /* 1101 */ V(5, 3, 4), /* 1110 */ V(2, 5, 4), /* 1111 */ V(5, 2, 4), /* 0010 ... */ /* 0000 */ V(1, 5, 3), /* 48 */ /* 0001 */ V(1, 5, 3), /* 0010 */ V(5, 1, 3), /* 0011 */ V(5, 1, 3), /* 0100 */ V(3, 4, 3), /* 0101 */ V(3, 4, 3), /* 0110 */ V(4, 3, 3), /* 0111 */ V(4, 3, 3), /* 1000 */ V(5, 0, 4), /* 1001 */ V(0, 4, 4), /* 1010 */ V(2, 4, 3), /* 1011 */ V(2, 4, 3), /* 1100 */ V(4, 2, 3), /* 1101 */ V(4, 2, 3), /* 1110 */ V(1, 4, 3), /* 1111 */ V(1, 4, 3), /* 0011 ... */ /* 00 */ V(3, 3, 2), /* 64 */ /* 01 */ V(4, 1, 2), /* 10 */ V(2, 3, 2), /* 11 */ V(3, 2, 2), /* 0100 ... */ /* 000 */ V(4, 0, 3), /* 68 */ /* 001 */ V(0, 3, 3), /* 010 */ V(3, 0, 2), /* 011 */ V(3, 0, 2), /* 100 */ V(1, 3, 1), /* 101 */ V(1, 3, 1), /* 110 */ V(1, 3, 1), /* 111 */ V(1, 3, 1), /* 0101 ... */ /* 0 */ V(3, 1, 1), /* 76 */ /* 1 */ V(2, 2, 1), /* 1000 ... */ /* 0 */ V(0, 2, 1), /* 78 */ /* 1 */ V(2, 0, 1), /* 0000 0000 ... */ /* 00 */ V(7, 7, 2), /* 80 */ /* 01 */ V(6, 7, 2), /* 10 */ V(7, 6, 1), /* 11 */ V(7, 6, 1), /* 0000 0001 ... */ /* 0 */ V(5, 7, 1), /* 84 */ /* 1 */ V(7, 5, 1), /* 0000 0010 ... */ /* 0 */ V(6, 6, 1), /* 86 */ /* 1 */ V(4, 7, 1), /* 0000 0011 ... */ /* 0 */ V(7, 4, 1), /* 88 */ /* 1 */ V(6, 5, 1), /* 0000 0110 ... */ /* 0 */ V(7, 3, 1), /* 90 */ /* 1 */ V(5, 5, 1), /* 0000 1101 ... */ /* 0 */ V(0, 7, 1), /* 92 */ /* 1 */ V(7, 0, 1), /* 0001 0011 ... */ /* 0 */ V(0, 6, 1), /* 94 */ /* 1 */ V(0, 5, 1) }; static union huffpair const hufftab13[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 2), /* 0100 */ V(1, 1, 4), /* 0101 */ V(0, 1, 4), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(68, 4), /* 16 */ /* 0001 */ PTR(84, 4), /* 0010 */ PTR(100, 4), /* 0011 */ PTR(116, 4), /* 0100 */ PTR(132, 4), /* 0101 */ PTR(148, 4), /* 0110 */ PTR(164, 3), /* 0111 */ PTR(172, 3), /* 1000 */ PTR(180, 3), /* 1001 */ PTR(188, 3), /* 1010 */ PTR(196, 3), /* 1011 */ PTR(204, 3), /* 1100 */ PTR(212, 1), /* 1101 */ PTR(214, 2), /* 1110 */ PTR(218, 3), /* 1111 */ PTR(226, 1), /* 0001 ... */ /* 0000 */ PTR(228, 2), /* 32 */ /* 0001 */ PTR(232, 2), /* 0010 */ PTR(236, 2), /* 0011 */ PTR(240, 2), /* 0100 */ V(8, 1, 4), /* 0101 */ PTR(244, 1), /* 0110 */ PTR(246, 1), /* 0111 */ PTR(248, 1), /* 1000 */ PTR(250, 2), /* 1001 */ PTR(254, 1), /* 1010 */ V(1, 5, 4), /* 1011 */ V(5, 1, 4), /* 1100 */ PTR(256, 1), /* 1101 */ PTR(258, 1), /* 1110 */ PTR(260, 1), /* 1111 */ V(1, 4, 4), /* 0010 ... */ /* 0000 */ V(4, 1, 3), /* 48 */ /* 0001 */ V(4, 1, 3), /* 0010 */ V(0, 4, 4), /* 0011 */ V(4, 0, 4), /* 0100 */ V(2, 3, 4), /* 0101 */ V(3, 2, 4), /* 0110 */ V(1, 3, 3), /* 0111 */ V(1, 3, 3), /* 1000 */ V(3, 1, 3), /* 1001 */ V(3, 1, 3), /* 1010 */ V(0, 3, 3), /* 1011 */ V(0, 3, 3), /* 1100 */ V(3, 0, 3), /* 1101 */ V(3, 0, 3), /* 1110 */ V(2, 2, 3), /* 1111 */ V(2, 2, 3), /* 0011 ... */ /* 00 */ V(1, 2, 2), /* 64 */ /* 01 */ V(2, 1, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 0000 */ PTR(262, 4), /* 68 */ /* 0001 */ PTR(278, 4), /* 0010 */ PTR(294, 4), /* 0011 */ PTR(310, 3), /* 0100 */ PTR(318, 2), /* 0101 */ PTR(322, 2), /* 0110 */ PTR(326, 3), /* 0111 */ PTR(334, 2), /* 1000 */ PTR(338, 1), /* 1001 */ PTR(340, 2), /* 1010 */ PTR(344, 2), /* 1011 */ PTR(348, 2), /* 1100 */ PTR(352, 2), /* 1101 */ PTR(356, 2), /* 1110 */ V(1, 15, 4), /* 1111 */ V(15, 1, 4), /* 0000 0001 ... */ /* 0000 */ V(15, 0, 4), /* 84 */ /* 0001 */ PTR(360, 1), /* 0010 */ PTR(362, 1), /* 0011 */ PTR(364, 1), /* 0100 */ V(14, 2, 4), /* 0101 */ PTR(366, 1), /* 0110 */ V(1, 14, 4), /* 0111 */ V(14, 1, 4), /* 1000 */ PTR(368, 1), /* 1001 */ PTR(370, 1), /* 1010 */ PTR(372, 1), /* 1011 */ PTR(374, 1), /* 1100 */ PTR(376, 1), /* 1101 */ PTR(378, 1), /* 1110 */ V(12, 6, 4), /* 1111 */ V(3, 13, 4), /* 0000 0010 ... */ /* 0000 */ PTR(380, 1), /* 100 */ /* 0001 */ V(2, 13, 4), /* 0010 */ V(13, 2, 4), /* 0011 */ V(1, 13, 4), /* 0100 */ V(11, 7, 4), /* 0101 */ PTR(382, 1), /* 0110 */ PTR(384, 1), /* 0111 */ V(12, 3, 4), /* 1000 */ PTR(386, 1), /* 1001 */ V(4, 11, 4), /* 1010 */ V(13, 1, 3), /* 1011 */ V(13, 1, 3), /* 1100 */ V(0, 13, 4), /* 1101 */ V(13, 0, 4), /* 1110 */ V(8, 10, 4), /* 1111 */ V(10, 8, 4), /* 0000 0011 ... */ /* 0000 */ V(4, 12, 4), /* 116 */ /* 0001 */ V(12, 4, 4), /* 0010 */ V(6, 11, 4), /* 0011 */ V(11, 6, 4), /* 0100 */ V(3, 12, 3), /* 0101 */ V(3, 12, 3), /* 0110 */ V(2, 12, 3), /* 0111 */ V(2, 12, 3), /* 1000 */ V(12, 2, 3), /* 1001 */ V(12, 2, 3), /* 1010 */ V(5, 11, 3), /* 1011 */ V(5, 11, 3), /* 1100 */ V(11, 5, 4), /* 1101 */ V(8, 9, 4), /* 1110 */ V(1, 12, 3), /* 1111 */ V(1, 12, 3), /* 0000 0100 ... */ /* 0000 */ V(12, 1, 3), /* 132 */ /* 0001 */ V(12, 1, 3), /* 0010 */ V(9, 8, 4), /* 0011 */ V(0, 12, 4), /* 0100 */ V(12, 0, 3), /* 0101 */ V(12, 0, 3), /* 0110 */ V(11, 4, 4), /* 0111 */ V(6, 10, 4), /* 1000 */ V(10, 6, 4), /* 1001 */ V(7, 9, 4), /* 1010 */ V(3, 11, 3), /* 1011 */ V(3, 11, 3), /* 1100 */ V(11, 3, 3), /* 1101 */ V(11, 3, 3), /* 1110 */ V(8, 8, 4), /* 1111 */ V(5, 10, 4), /* 0000 0101 ... */ /* 0000 */ V(2, 11, 3), /* 148 */ /* 0001 */ V(2, 11, 3), /* 0010 */ V(10, 5, 4), /* 0011 */ V(6, 9, 4), /* 0100 */ V(10, 4, 3), /* 0101 */ V(10, 4, 3), /* 0110 */ V(7, 8, 4), /* 0111 */ V(8, 7, 4), /* 1000 */ V(9, 4, 3), /* 1001 */ V(9, 4, 3), /* 1010 */ V(7, 7, 4), /* 1011 */ V(7, 6, 4), /* 1100 */ V(11, 2, 2), /* 1101 */ V(11, 2, 2), /* 1110 */ V(11, 2, 2), /* 1111 */ V(11, 2, 2), /* 0000 0110 ... */ /* 000 */ V(1, 11, 2), /* 164 */ /* 001 */ V(1, 11, 2), /* 010 */ V(11, 1, 2), /* 011 */ V(11, 1, 2), /* 100 */ V(0, 11, 3), /* 101 */ V(11, 0, 3), /* 110 */ V(9, 6, 3), /* 111 */ V(4, 10, 3), /* 0000 0111 ... */ /* 000 */ V(3, 10, 3), /* 172 */ /* 001 */ V(10, 3, 3), /* 010 */ V(5, 9, 3), /* 011 */ V(9, 5, 3), /* 100 */ V(2, 10, 2), /* 101 */ V(2, 10, 2), /* 110 */ V(10, 2, 2), /* 111 */ V(10, 2, 2), /* 0000 1000 ... */ /* 000 */ V(1, 10, 2), /* 180 */ /* 001 */ V(1, 10, 2), /* 010 */ V(10, 1, 2), /* 011 */ V(10, 1, 2), /* 100 */ V(0, 10, 3), /* 101 */ V(6, 8, 3), /* 110 */ V(10, 0, 2), /* 111 */ V(10, 0, 2), /* 0000 1001 ... */ /* 000 */ V(8, 6, 3), /* 188 */ /* 001 */ V(4, 9, 3), /* 010 */ V(9, 3, 2), /* 011 */ V(9, 3, 2), /* 100 */ V(3, 9, 3), /* 101 */ V(5, 8, 3), /* 110 */ V(8, 5, 3), /* 111 */ V(6, 7, 3), /* 0000 1010 ... */ /* 000 */ V(2, 9, 2), /* 196 */ /* 001 */ V(2, 9, 2), /* 010 */ V(9, 2, 2), /* 011 */ V(9, 2, 2), /* 100 */ V(5, 7, 3), /* 101 */ V(7, 5, 3), /* 110 */ V(3, 8, 2), /* 111 */ V(3, 8, 2), /* 0000 1011 ... */ /* 000 */ V(8, 3, 2), /* 204 */ /* 001 */ V(8, 3, 2), /* 010 */ V(6, 6, 3), /* 011 */ V(4, 7, 3), /* 100 */ V(7, 4, 3), /* 101 */ V(5, 6, 3), /* 110 */ V(6, 5, 3), /* 111 */ V(7, 3, 3), /* 0000 1100 ... */ /* 0 */ V(1, 9, 1), /* 212 */ /* 1 */ V(9, 1, 1), /* 0000 1101 ... */ /* 00 */ V(0, 9, 2), /* 214 */ /* 01 */ V(9, 0, 2), /* 10 */ V(4, 8, 2), /* 11 */ V(8, 4, 2), /* 0000 1110 ... */ /* 000 */ V(7, 2, 2), /* 218 */ /* 001 */ V(7, 2, 2), /* 010 */ V(4, 6, 3), /* 011 */ V(6, 4, 3), /* 100 */ V(2, 8, 1), /* 101 */ V(2, 8, 1), /* 110 */ V(2, 8, 1), /* 111 */ V(2, 8, 1), /* 0000 1111 ... */ /* 0 */ V(8, 2, 1), /* 226 */ /* 1 */ V(1, 8, 1), /* 0001 0000 ... */ /* 00 */ V(3, 7, 2), /* 228 */ /* 01 */ V(2, 7, 2), /* 10 */ V(1, 7, 1), /* 11 */ V(1, 7, 1), /* 0001 0001 ... */ /* 00 */ V(7, 1, 1), /* 232 */ /* 01 */ V(7, 1, 1), /* 10 */ V(5, 5, 2), /* 11 */ V(0, 7, 2), /* 0001 0010 ... */ /* 00 */ V(7, 0, 2), /* 236 */ /* 01 */ V(3, 6, 2), /* 10 */ V(6, 3, 2), /* 11 */ V(4, 5, 2), /* 0001 0011 ... */ /* 00 */ V(5, 4, 2), /* 240 */ /* 01 */ V(2, 6, 2), /* 10 */ V(6, 2, 2), /* 11 */ V(3, 5, 2), /* 0001 0101 ... */ /* 0 */ V(0, 8, 1), /* 244 */ /* 1 */ V(8, 0, 1), /* 0001 0110 ... */ /* 0 */ V(1, 6, 1), /* 246 */ /* 1 */ V(6, 1, 1), /* 0001 0111 ... */ /* 0 */ V(0, 6, 1), /* 248 */ /* 1 */ V(6, 0, 1), /* 0001 1000 ... */ /* 00 */ V(5, 3, 2), /* 250 */ /* 01 */ V(4, 4, 2), /* 10 */ V(2, 5, 1), /* 11 */ V(2, 5, 1), /* 0001 1001 ... */ /* 0 */ V(5, 2, 1), /* 254 */ /* 1 */ V(0, 5, 1), /* 0001 1100 ... */ /* 0 */ V(3, 4, 1), /* 256 */ /* 1 */ V(4, 3, 1), /* 0001 1101 ... */ /* 0 */ V(5, 0, 1), /* 258 */ /* 1 */ V(2, 4, 1), /* 0001 1110 ... */ /* 0 */ V(4, 2, 1), /* 260 */ /* 1 */ V(3, 3, 1), /* 0000 0000 0000 ... */ /* 0000 */ PTR(388, 3), /* 262 */ /* 0001 */ V(15, 15, 4), /* 0010 */ V(14, 15, 4), /* 0011 */ V(13, 15, 4), /* 0100 */ V(14, 14, 4), /* 0101 */ V(12, 15, 4), /* 0110 */ V(13, 14, 4), /* 0111 */ V(11, 15, 4), /* 1000 */ V(15, 11, 4), /* 1001 */ V(12, 14, 4), /* 1010 */ V(13, 12, 4), /* 1011 */ PTR(396, 1), /* 1100 */ V(14, 12, 3), /* 1101 */ V(14, 12, 3), /* 1110 */ V(13, 13, 3), /* 1111 */ V(13, 13, 3), /* 0000 0000 0001 ... */ /* 0000 */ V(15, 10, 4), /* 278 */ /* 0001 */ V(12, 13, 4), /* 0010 */ V(11, 14, 3), /* 0011 */ V(11, 14, 3), /* 0100 */ V(14, 11, 3), /* 0101 */ V(14, 11, 3), /* 0110 */ V(9, 15, 3), /* 0111 */ V(9, 15, 3), /* 1000 */ V(15, 9, 3), /* 1001 */ V(15, 9, 3), /* 1010 */ V(14, 10, 3), /* 1011 */ V(14, 10, 3), /* 1100 */ V(11, 13, 3), /* 1101 */ V(11, 13, 3), /* 1110 */ V(13, 11, 3), /* 1111 */ V(13, 11, 3), /* 0000 0000 0010 ... */ /* 0000 */ V(8, 15, 3), /* 294 */ /* 0001 */ V(8, 15, 3), /* 0010 */ V(15, 8, 3), /* 0011 */ V(15, 8, 3), /* 0100 */ V(12, 12, 3), /* 0101 */ V(12, 12, 3), /* 0110 */ V(10, 14, 4), /* 0111 */ V(9, 14, 4), /* 1000 */ V(8, 14, 3), /* 1001 */ V(8, 14, 3), /* 1010 */ V(7, 15, 4), /* 1011 */ V(7, 14, 4), /* 1100 */ V(15, 7, 2), /* 1101 */ V(15, 7, 2), /* 1110 */ V(15, 7, 2), /* 1111 */ V(15, 7, 2), /* 0000 0000 0011 ... */ /* 000 */ V(13, 10, 2), /* 310 */ /* 001 */ V(13, 10, 2), /* 010 */ V(10, 13, 3), /* 011 */ V(11, 12, 3), /* 100 */ V(12, 11, 3), /* 101 */ V(15, 6, 3), /* 110 */ V(6, 15, 2), /* 111 */ V(6, 15, 2), /* 0000 0000 0100 ... */ /* 00 */ V(14, 8, 2), /* 318 */ /* 01 */ V(5, 15, 2), /* 10 */ V(9, 13, 2), /* 11 */ V(13, 9, 2), /* 0000 0000 0101 ... */ /* 00 */ V(15, 5, 2), /* 322 */ /* 01 */ V(14, 7, 2), /* 10 */ V(10, 12, 2), /* 11 */ V(11, 11, 2), /* 0000 0000 0110 ... */ /* 000 */ V(4, 15, 2), /* 326 */ /* 001 */ V(4, 15, 2), /* 010 */ V(15, 4, 2), /* 011 */ V(15, 4, 2), /* 100 */ V(12, 10, 3), /* 101 */ V(14, 6, 3), /* 110 */ V(15, 3, 2), /* 111 */ V(15, 3, 2), /* 0000 0000 0111 ... */ /* 00 */ V(3, 15, 1), /* 334 */ /* 01 */ V(3, 15, 1), /* 10 */ V(8, 13, 2), /* 11 */ V(13, 8, 2), /* 0000 0000 1000 ... */ /* 0 */ V(2, 15, 1), /* 338 */ /* 1 */ V(15, 2, 1), /* 0000 0000 1001 ... */ /* 00 */ V(6, 14, 2), /* 340 */ /* 01 */ V(9, 12, 2), /* 10 */ V(0, 15, 1), /* 11 */ V(0, 15, 1), /* 0000 0000 1010 ... */ /* 00 */ V(12, 9, 2), /* 344 */ /* 01 */ V(5, 14, 2), /* 10 */ V(10, 11, 1), /* 11 */ V(10, 11, 1), /* 0000 0000 1011 ... */ /* 00 */ V(7, 13, 2), /* 348 */ /* 01 */ V(13, 7, 2), /* 10 */ V(4, 14, 1), /* 11 */ V(4, 14, 1), /* 0000 0000 1100 ... */ /* 00 */ V(12, 8, 2), /* 352 */ /* 01 */ V(13, 6, 2), /* 10 */ V(3, 14, 1), /* 11 */ V(3, 14, 1), /* 0000 0000 1101 ... */ /* 00 */ V(11, 9, 1), /* 356 */ /* 01 */ V(11, 9, 1), /* 10 */ V(9, 11, 2), /* 11 */ V(10, 10, 2), /* 0000 0001 0001 ... */ /* 0 */ V(11, 10, 1), /* 360 */ /* 1 */ V(14, 5, 1), /* 0000 0001 0010 ... */ /* 0 */ V(14, 4, 1), /* 362 */ /* 1 */ V(8, 12, 1), /* 0000 0001 0011 ... */ /* 0 */ V(6, 13, 1), /* 364 */ /* 1 */ V(14, 3, 1), /* 0000 0001 0101 ... */ /* 0 */ V(2, 14, 1), /* 366 */ /* 1 */ V(0, 14, 1), /* 0000 0001 1000 ... */ /* 0 */ V(14, 0, 1), /* 368 */ /* 1 */ V(5, 13, 1), /* 0000 0001 1001 ... */ /* 0 */ V(13, 5, 1), /* 370 */ /* 1 */ V(7, 12, 1), /* 0000 0001 1010 ... */ /* 0 */ V(12, 7, 1), /* 372 */ /* 1 */ V(4, 13, 1), /* 0000 0001 1011 ... */ /* 0 */ V(8, 11, 1), /* 374 */ /* 1 */ V(11, 8, 1), /* 0000 0001 1100 ... */ /* 0 */ V(13, 4, 1), /* 376 */ /* 1 */ V(9, 10, 1), /* 0000 0001 1101 ... */ /* 0 */ V(10, 9, 1), /* 378 */ /* 1 */ V(6, 12, 1), /* 0000 0010 0000 ... */ /* 0 */ V(13, 3, 1), /* 380 */ /* 1 */ V(7, 11, 1), /* 0000 0010 0101 ... */ /* 0 */ V(5, 12, 1), /* 382 */ /* 1 */ V(12, 5, 1), /* 0000 0010 0110 ... */ /* 0 */ V(9, 9, 1), /* 384 */ /* 1 */ V(7, 10, 1), /* 0000 0010 1000 ... */ /* 0 */ V(10, 7, 1), /* 386 */ /* 1 */ V(9, 7, 1), /* 0000 0000 0000 0000 ... */ /* 000 */ V(15, 14, 3), /* 388 */ /* 001 */ V(15, 12, 3), /* 010 */ V(15, 13, 2), /* 011 */ V(15, 13, 2), /* 100 */ V(14, 13, 1), /* 101 */ V(14, 13, 1), /* 110 */ V(14, 13, 1), /* 111 */ V(14, 13, 1), /* 0000 0000 0000 1011 ... */ /* 0 */ V(10, 15, 1), /* 396 */ /* 1 */ V(14, 9, 1) }; static union huffpair const hufftab15[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 4), /* 0100 */ PTR(80, 4), /* 0101 */ PTR(96, 3), /* 0110 */ PTR(104, 3), /* 0111 */ PTR(112, 2), /* 1000 */ PTR(116, 1), /* 1001 */ PTR(118, 1), /* 1010 */ V(1, 1, 3), /* 1011 */ V(1, 1, 3), /* 1100 */ V(0, 1, 4), /* 1101 */ V(1, 0, 4), /* 1110 */ V(0, 0, 3), /* 1111 */ V(0, 0, 3), /* 0000 ... */ /* 0000 */ PTR(120, 4), /* 16 */ /* 0001 */ PTR(136, 4), /* 0010 */ PTR(152, 4), /* 0011 */ PTR(168, 4), /* 0100 */ PTR(184, 4), /* 0101 */ PTR(200, 3), /* 0110 */ PTR(208, 3), /* 0111 */ PTR(216, 4), /* 1000 */ PTR(232, 3), /* 1001 */ PTR(240, 3), /* 1010 */ PTR(248, 3), /* 1011 */ PTR(256, 3), /* 1100 */ PTR(264, 2), /* 1101 */ PTR(268, 3), /* 1110 */ PTR(276, 3), /* 1111 */ PTR(284, 2), /* 0001 ... */ /* 0000 */ PTR(288, 2), /* 32 */ /* 0001 */ PTR(292, 2), /* 0010 */ PTR(296, 2), /* 0011 */ PTR(300, 2), /* 0100 */ PTR(304, 2), /* 0101 */ PTR(308, 2), /* 0110 */ PTR(312, 2), /* 0111 */ PTR(316, 2), /* 1000 */ PTR(320, 1), /* 1001 */ PTR(322, 1), /* 1010 */ PTR(324, 1), /* 1011 */ PTR(326, 2), /* 1100 */ PTR(330, 1), /* 1101 */ PTR(332, 1), /* 1110 */ PTR(334, 2), /* 1111 */ PTR(338, 1), /* 0010 ... */ /* 0000 */ PTR(340, 1), /* 48 */ /* 0001 */ PTR(342, 1), /* 0010 */ V(9, 1, 4), /* 0011 */ PTR(344, 1), /* 0100 */ PTR(346, 1), /* 0101 */ PTR(348, 1), /* 0110 */ PTR(350, 1), /* 0111 */ PTR(352, 1), /* 1000 */ V(2, 8, 4), /* 1001 */ V(8, 2, 4), /* 1010 */ V(1, 8, 4), /* 1011 */ V(8, 1, 4), /* 1100 */ PTR(354, 1), /* 1101 */ PTR(356, 1), /* 1110 */ PTR(358, 1), /* 1111 */ PTR(360, 1), /* 0011 ... */ /* 0000 */ V(2, 7, 4), /* 64 */ /* 0001 */ V(7, 2, 4), /* 0010 */ V(6, 4, 4), /* 0011 */ V(1, 7, 4), /* 0100 */ V(5, 5, 4), /* 0101 */ V(7, 1, 4), /* 0110 */ PTR(362, 1), /* 0111 */ V(3, 6, 4), /* 1000 */ V(6, 3, 4), /* 1001 */ V(4, 5, 4), /* 1010 */ V(5, 4, 4), /* 1011 */ V(2, 6, 4), /* 1100 */ V(6, 2, 4), /* 1101 */ V(1, 6, 4), /* 1110 */ PTR(364, 1), /* 1111 */ V(3, 5, 4), /* 0100 ... */ /* 0000 */ V(6, 1, 3), /* 80 */ /* 0001 */ V(6, 1, 3), /* 0010 */ V(5, 3, 4), /* 0011 */ V(4, 4, 4), /* 0100 */ V(2, 5, 3), /* 0101 */ V(2, 5, 3), /* 0110 */ V(5, 2, 3), /* 0111 */ V(5, 2, 3), /* 1000 */ V(1, 5, 3), /* 1001 */ V(1, 5, 3), /* 1010 */ V(5, 1, 3), /* 1011 */ V(5, 1, 3), /* 1100 */ V(0, 5, 4), /* 1101 */ V(5, 0, 4), /* 1110 */ V(3, 4, 3), /* 1111 */ V(3, 4, 3), /* 0101 ... */ /* 000 */ V(4, 3, 3), /* 96 */ /* 001 */ V(2, 4, 3), /* 010 */ V(4, 2, 3), /* 011 */ V(3, 3, 3), /* 100 */ V(4, 1, 2), /* 101 */ V(4, 1, 2), /* 110 */ V(1, 4, 3), /* 111 */ V(0, 4, 3), /* 0110 ... */ /* 000 */ V(2, 3, 2), /* 104 */ /* 001 */ V(2, 3, 2), /* 010 */ V(3, 2, 2), /* 011 */ V(3, 2, 2), /* 100 */ V(4, 0, 3), /* 101 */ V(0, 3, 3), /* 110 */ V(1, 3, 2), /* 111 */ V(1, 3, 2), /* 0111 ... */ /* 00 */ V(3, 1, 2), /* 112 */ /* 01 */ V(3, 0, 2), /* 10 */ V(2, 2, 1), /* 11 */ V(2, 2, 1), /* 1000 ... */ /* 0 */ V(1, 2, 1), /* 116 */ /* 1 */ V(2, 1, 1), /* 1001 ... */ /* 0 */ V(0, 2, 1), /* 118 */ /* 1 */ V(2, 0, 1), /* 0000 0000 ... */ /* 0000 */ PTR(366, 1), /* 120 */ /* 0001 */ PTR(368, 1), /* 0010 */ V(14, 14, 4), /* 0011 */ PTR(370, 1), /* 0100 */ PTR(372, 1), /* 0101 */ PTR(374, 1), /* 0110 */ V(15, 11, 4), /* 0111 */ PTR(376, 1), /* 1000 */ V(13, 13, 4), /* 1001 */ V(10, 15, 4), /* 1010 */ V(15, 10, 4), /* 1011 */ V(11, 14, 4), /* 1100 */ V(14, 11, 4), /* 1101 */ V(12, 13, 4), /* 1110 */ V(13, 12, 4), /* 1111 */ V(9, 15, 4), /* 0000 0001 ... */ /* 0000 */ V(15, 9, 4), /* 136 */ /* 0001 */ V(14, 10, 4), /* 0010 */ V(11, 13, 4), /* 0011 */ V(13, 11, 4), /* 0100 */ V(8, 15, 4), /* 0101 */ V(15, 8, 4), /* 0110 */ V(12, 12, 4), /* 0111 */ V(9, 14, 4), /* 1000 */ V(14, 9, 4), /* 1001 */ V(7, 15, 4), /* 1010 */ V(15, 7, 4), /* 1011 */ V(10, 13, 4), /* 1100 */ V(13, 10, 4), /* 1101 */ V(11, 12, 4), /* 1110 */ V(6, 15, 4), /* 1111 */ PTR(378, 1), /* 0000 0010 ... */ /* 0000 */ V(12, 11, 3), /* 152 */ /* 0001 */ V(12, 11, 3), /* 0010 */ V(15, 6, 3), /* 0011 */ V(15, 6, 3), /* 0100 */ V(8, 14, 4), /* 0101 */ V(14, 8, 4), /* 0110 */ V(5, 15, 4), /* 0111 */ V(9, 13, 4), /* 1000 */ V(15, 5, 3), /* 1001 */ V(15, 5, 3), /* 1010 */ V(7, 14, 3), /* 1011 */ V(7, 14, 3), /* 1100 */ V(14, 7, 3), /* 1101 */ V(14, 7, 3), /* 1110 */ V(10, 12, 3), /* 1111 */ V(10, 12, 3), /* 0000 0011 ... */ /* 0000 */ V(12, 10, 3), /* 168 */ /* 0001 */ V(12, 10, 3), /* 0010 */ V(11, 11, 3), /* 0011 */ V(11, 11, 3), /* 0100 */ V(13, 9, 4), /* 0101 */ V(8, 13, 4), /* 0110 */ V(4, 15, 3), /* 0111 */ V(4, 15, 3), /* 1000 */ V(15, 4, 3), /* 1001 */ V(15, 4, 3), /* 1010 */ V(3, 15, 3), /* 1011 */ V(3, 15, 3), /* 1100 */ V(15, 3, 3), /* 1101 */ V(15, 3, 3), /* 1110 */ V(13, 8, 3), /* 1111 */ V(13, 8, 3), /* 0000 0100 ... */ /* 0000 */ V(14, 6, 3), /* 184 */ /* 0001 */ V(14, 6, 3), /* 0010 */ V(2, 15, 3), /* 0011 */ V(2, 15, 3), /* 0100 */ V(15, 2, 3), /* 0101 */ V(15, 2, 3), /* 0110 */ V(6, 14, 4), /* 0111 */ V(15, 0, 4), /* 1000 */ V(1, 15, 3), /* 1001 */ V(1, 15, 3), /* 1010 */ V(15, 1, 3), /* 1011 */ V(15, 1, 3), /* 1100 */ V(9, 12, 3), /* 1101 */ V(9, 12, 3), /* 1110 */ V(12, 9, 3), /* 1111 */ V(12, 9, 3), /* 0000 0101 ... */ /* 000 */ V(5, 14, 3), /* 200 */ /* 001 */ V(10, 11, 3), /* 010 */ V(11, 10, 3), /* 011 */ V(14, 5, 3), /* 100 */ V(7, 13, 3), /* 101 */ V(13, 7, 3), /* 110 */ V(4, 14, 3), /* 111 */ V(14, 4, 3), /* 0000 0110 ... */ /* 000 */ V(8, 12, 3), /* 208 */ /* 001 */ V(12, 8, 3), /* 010 */ V(3, 14, 3), /* 011 */ V(6, 13, 3), /* 100 */ V(13, 6, 3), /* 101 */ V(14, 3, 3), /* 110 */ V(9, 11, 3), /* 111 */ V(11, 9, 3), /* 0000 0111 ... */ /* 0000 */ V(2, 14, 3), /* 216 */ /* 0001 */ V(2, 14, 3), /* 0010 */ V(10, 10, 3), /* 0011 */ V(10, 10, 3), /* 0100 */ V(14, 2, 3), /* 0101 */ V(14, 2, 3), /* 0110 */ V(1, 14, 3), /* 0111 */ V(1, 14, 3), /* 1000 */ V(14, 1, 3), /* 1001 */ V(14, 1, 3), /* 1010 */ V(0, 14, 4), /* 1011 */ V(14, 0, 4), /* 1100 */ V(5, 13, 3), /* 1101 */ V(5, 13, 3), /* 1110 */ V(13, 5, 3), /* 1111 */ V(13, 5, 3), /* 0000 1000 ... */ /* 000 */ V(7, 12, 3), /* 232 */ /* 001 */ V(12, 7, 3), /* 010 */ V(4, 13, 3), /* 011 */ V(8, 11, 3), /* 100 */ V(13, 4, 2), /* 101 */ V(13, 4, 2), /* 110 */ V(11, 8, 3), /* 111 */ V(9, 10, 3), /* 0000 1001 ... */ /* 000 */ V(10, 9, 3), /* 240 */ /* 001 */ V(6, 12, 3), /* 010 */ V(12, 6, 3), /* 011 */ V(3, 13, 3), /* 100 */ V(13, 3, 2), /* 101 */ V(13, 3, 2), /* 110 */ V(13, 2, 2), /* 111 */ V(13, 2, 2), /* 0000 1010 ... */ /* 000 */ V(2, 13, 3), /* 248 */ /* 001 */ V(0, 13, 3), /* 010 */ V(1, 13, 2), /* 011 */ V(1, 13, 2), /* 100 */ V(7, 11, 2), /* 101 */ V(7, 11, 2), /* 110 */ V(11, 7, 2), /* 111 */ V(11, 7, 2), /* 0000 1011 ... */ /* 000 */ V(13, 1, 2), /* 256 */ /* 001 */ V(13, 1, 2), /* 010 */ V(5, 12, 3), /* 011 */ V(13, 0, 3), /* 100 */ V(12, 5, 2), /* 101 */ V(12, 5, 2), /* 110 */ V(8, 10, 2), /* 111 */ V(8, 10, 2), /* 0000 1100 ... */ /* 00 */ V(10, 8, 2), /* 264 */ /* 01 */ V(4, 12, 2), /* 10 */ V(12, 4, 2), /* 11 */ V(6, 11, 2), /* 0000 1101 ... */ /* 000 */ V(11, 6, 2), /* 268 */ /* 001 */ V(11, 6, 2), /* 010 */ V(9, 9, 3), /* 011 */ V(0, 12, 3), /* 100 */ V(3, 12, 2), /* 101 */ V(3, 12, 2), /* 110 */ V(12, 3, 2), /* 111 */ V(12, 3, 2), /* 0000 1110 ... */ /* 000 */ V(7, 10, 2), /* 276 */ /* 001 */ V(7, 10, 2), /* 010 */ V(10, 7, 2), /* 011 */ V(10, 7, 2), /* 100 */ V(10, 6, 2), /* 101 */ V(10, 6, 2), /* 110 */ V(12, 0, 3), /* 111 */ V(0, 11, 3), /* 0000 1111 ... */ /* 00 */ V(12, 2, 1), /* 284 */ /* 01 */ V(12, 2, 1), /* 10 */ V(2, 12, 2), /* 11 */ V(5, 11, 2), /* 0001 0000 ... */ /* 00 */ V(11, 5, 2), /* 288 */ /* 01 */ V(1, 12, 2), /* 10 */ V(8, 9, 2), /* 11 */ V(9, 8, 2), /* 0001 0001 ... */ /* 00 */ V(12, 1, 2), /* 292 */ /* 01 */ V(4, 11, 2), /* 10 */ V(11, 4, 2), /* 11 */ V(6, 10, 2), /* 0001 0010 ... */ /* 00 */ V(3, 11, 2), /* 296 */ /* 01 */ V(7, 9, 2), /* 10 */ V(11, 3, 1), /* 11 */ V(11, 3, 1), /* 0001 0011 ... */ /* 00 */ V(9, 7, 2), /* 300 */ /* 01 */ V(8, 8, 2), /* 10 */ V(2, 11, 2), /* 11 */ V(5, 10, 2), /* 0001 0100 ... */ /* 00 */ V(11, 2, 1), /* 304 */ /* 01 */ V(11, 2, 1), /* 10 */ V(10, 5, 2), /* 11 */ V(1, 11, 2), /* 0001 0101 ... */ /* 00 */ V(11, 1, 1), /* 308 */ /* 01 */ V(11, 1, 1), /* 10 */ V(11, 0, 2), /* 11 */ V(6, 9, 2), /* 0001 0110 ... */ /* 00 */ V(9, 6, 2), /* 312 */ /* 01 */ V(4, 10, 2), /* 10 */ V(10, 4, 2), /* 11 */ V(7, 8, 2), /* 0001 0111 ... */ /* 00 */ V(8, 7, 2), /* 316 */ /* 01 */ V(3, 10, 2), /* 10 */ V(10, 3, 1), /* 11 */ V(10, 3, 1), /* 0001 1000 ... */ /* 0 */ V(5, 9, 1), /* 320 */ /* 1 */ V(9, 5, 1), /* 0001 1001 ... */ /* 0 */ V(2, 10, 1), /* 322 */ /* 1 */ V(10, 2, 1), /* 0001 1010 ... */ /* 0 */ V(1, 10, 1), /* 324 */ /* 1 */ V(10, 1, 1), /* 0001 1011 ... */ /* 00 */ V(0, 10, 2), /* 326 */ /* 01 */ V(10, 0, 2), /* 10 */ V(6, 8, 1), /* 11 */ V(6, 8, 1), /* 0001 1100 ... */ /* 0 */ V(8, 6, 1), /* 330 */ /* 1 */ V(4, 9, 1), /* 0001 1101 ... */ /* 0 */ V(9, 4, 1), /* 332 */ /* 1 */ V(3, 9, 1), /* 0001 1110 ... */ /* 00 */ V(9, 3, 1), /* 334 */ /* 01 */ V(9, 3, 1), /* 10 */ V(7, 7, 2), /* 11 */ V(0, 9, 2), /* 0001 1111 ... */ /* 0 */ V(5, 8, 1), /* 338 */ /* 1 */ V(8, 5, 1), /* 0010 0000 ... */ /* 0 */ V(2, 9, 1), /* 340 */ /* 1 */ V(6, 7, 1), /* 0010 0001 ... */ /* 0 */ V(7, 6, 1), /* 342 */ /* 1 */ V(9, 2, 1), /* 0010 0011 ... */ /* 0 */ V(1, 9, 1), /* 344 */ /* 1 */ V(9, 0, 1), /* 0010 0100 ... */ /* 0 */ V(4, 8, 1), /* 346 */ /* 1 */ V(8, 4, 1), /* 0010 0101 ... */ /* 0 */ V(5, 7, 1), /* 348 */ /* 1 */ V(7, 5, 1), /* 0010 0110 ... */ /* 0 */ V(3, 8, 1), /* 350 */ /* 1 */ V(8, 3, 1), /* 0010 0111 ... */ /* 0 */ V(6, 6, 1), /* 352 */ /* 1 */ V(4, 7, 1), /* 0010 1100 ... */ /* 0 */ V(7, 4, 1), /* 354 */ /* 1 */ V(0, 8, 1), /* 0010 1101 ... */ /* 0 */ V(8, 0, 1), /* 356 */ /* 1 */ V(5, 6, 1), /* 0010 1110 ... */ /* 0 */ V(6, 5, 1), /* 358 */ /* 1 */ V(3, 7, 1), /* 0010 1111 ... */ /* 0 */ V(7, 3, 1), /* 360 */ /* 1 */ V(4, 6, 1), /* 0011 0110 ... */ /* 0 */ V(0, 7, 1), /* 362 */ /* 1 */ V(7, 0, 1), /* 0011 1110 ... */ /* 0 */ V(0, 6, 1), /* 364 */ /* 1 */ V(6, 0, 1), /* 0000 0000 0000 ... */ /* 0 */ V(15, 15, 1), /* 366 */ /* 1 */ V(14, 15, 1), /* 0000 0000 0001 ... */ /* 0 */ V(15, 14, 1), /* 368 */ /* 1 */ V(13, 15, 1), /* 0000 0000 0011 ... */ /* 0 */ V(15, 13, 1), /* 370 */ /* 1 */ V(12, 15, 1), /* 0000 0000 0100 ... */ /* 0 */ V(15, 12, 1), /* 372 */ /* 1 */ V(13, 14, 1), /* 0000 0000 0101 ... */ /* 0 */ V(14, 13, 1), /* 374 */ /* 1 */ V(11, 15, 1), /* 0000 0000 0111 ... */ /* 0 */ V(12, 14, 1), /* 376 */ /* 1 */ V(14, 12, 1), /* 0000 0001 1111 ... */ /* 0 */ V(10, 14, 1), /* 378 */ /* 1 */ V(0, 15, 1) }; static union huffpair const hufftab16[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ PTR(64, 2), /* 0100 */ V(1, 1, 4), /* 0101 */ V(0, 1, 4), /* 0110 */ V(1, 0, 3), /* 0111 */ V(1, 0, 3), /* 1000 */ V(0, 0, 1), /* 1001 */ V(0, 0, 1), /* 1010 */ V(0, 0, 1), /* 1011 */ V(0, 0, 1), /* 1100 */ V(0, 0, 1), /* 1101 */ V(0, 0, 1), /* 1110 */ V(0, 0, 1), /* 1111 */ V(0, 0, 1), /* 0000 ... */ /* 0000 */ PTR(68, 3), /* 16 */ /* 0001 */ PTR(76, 3), /* 0010 */ PTR(84, 2), /* 0011 */ V(15, 15, 4), /* 0100 */ PTR(88, 2), /* 0101 */ PTR(92, 1), /* 0110 */ PTR(94, 4), /* 0111 */ V(15, 2, 4), /* 1000 */ PTR(110, 1), /* 1001 */ V(1, 15, 4), /* 1010 */ V(15, 1, 4), /* 1011 */ PTR(112, 4), /* 1100 */ PTR(128, 4), /* 1101 */ PTR(144, 4), /* 1110 */ PTR(160, 4), /* 1111 */ PTR(176, 4), /* 0001 ... */ /* 0000 */ PTR(192, 4), /* 32 */ /* 0001 */ PTR(208, 3), /* 0010 */ PTR(216, 3), /* 0011 */ PTR(224, 3), /* 0100 */ PTR(232, 3), /* 0101 */ PTR(240, 3), /* 0110 */ PTR(248, 3), /* 0111 */ PTR(256, 3), /* 1000 */ PTR(264, 2), /* 1001 */ PTR(268, 2), /* 1010 */ PTR(272, 1), /* 1011 */ PTR(274, 2), /* 1100 */ PTR(278, 2), /* 1101 */ PTR(282, 1), /* 1110 */ V(5, 1, 4), /* 1111 */ PTR(284, 1), /* 0010 ... */ /* 0000 */ PTR(286, 1), /* 48 */ /* 0001 */ PTR(288, 1), /* 0010 */ PTR(290, 1), /* 0011 */ V(1, 4, 4), /* 0100 */ V(4, 1, 4), /* 0101 */ PTR(292, 1), /* 0110 */ V(2, 3, 4), /* 0111 */ V(3, 2, 4), /* 1000 */ V(1, 3, 3), /* 1001 */ V(1, 3, 3), /* 1010 */ V(3, 1, 3), /* 1011 */ V(3, 1, 3), /* 1100 */ V(0, 3, 4), /* 1101 */ V(3, 0, 4), /* 1110 */ V(2, 2, 3), /* 1111 */ V(2, 2, 3), /* 0011 ... */ /* 00 */ V(1, 2, 2), /* 64 */ /* 01 */ V(2, 1, 2), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0000 0000 ... */ /* 000 */ V(14, 15, 3), /* 68 */ /* 001 */ V(15, 14, 3), /* 010 */ V(13, 15, 3), /* 011 */ V(15, 13, 3), /* 100 */ V(12, 15, 3), /* 101 */ V(15, 12, 3), /* 110 */ V(11, 15, 3), /* 111 */ V(15, 11, 3), /* 0000 0001 ... */ /* 000 */ V(10, 15, 2), /* 76 */ /* 001 */ V(10, 15, 2), /* 010 */ V(15, 10, 3), /* 011 */ V(9, 15, 3), /* 100 */ V(15, 9, 3), /* 101 */ V(15, 8, 3), /* 110 */ V(8, 15, 2), /* 111 */ V(8, 15, 2), /* 0000 0010 ... */ /* 00 */ V(7, 15, 2), /* 84 */ /* 01 */ V(15, 7, 2), /* 10 */ V(6, 15, 2), /* 11 */ V(15, 6, 2), /* 0000 0100 ... */ /* 00 */ V(5, 15, 2), /* 88 */ /* 01 */ V(15, 5, 2), /* 10 */ V(4, 15, 1), /* 11 */ V(4, 15, 1), /* 0000 0101 ... */ /* 0 */ V(15, 4, 1), /* 92 */ /* 1 */ V(15, 3, 1), /* 0000 0110 ... */ /* 0000 */ V(15, 0, 1), /* 94 */ /* 0001 */ V(15, 0, 1), /* 0010 */ V(15, 0, 1), /* 0011 */ V(15, 0, 1), /* 0100 */ V(15, 0, 1), /* 0101 */ V(15, 0, 1), /* 0110 */ V(15, 0, 1), /* 0111 */ V(15, 0, 1), /* 1000 */ V(3, 15, 2), /* 1001 */ V(3, 15, 2), /* 1010 */ V(3, 15, 2), /* 1011 */ V(3, 15, 2), /* 1100 */ PTR(294, 4), /* 1101 */ PTR(310, 3), /* 1110 */ PTR(318, 3), /* 1111 */ PTR(326, 3), /* 0000 1000 ... */ /* 0 */ V(2, 15, 1), /* 110 */ /* 1 */ V(0, 15, 1), /* 0000 1011 ... */ /* 0000 */ PTR(334, 2), /* 112 */ /* 0001 */ PTR(338, 2), /* 0010 */ PTR(342, 2), /* 0011 */ PTR(346, 1), /* 0100 */ PTR(348, 2), /* 0101 */ PTR(352, 2), /* 0110 */ PTR(356, 1), /* 0111 */ PTR(358, 2), /* 1000 */ PTR(362, 2), /* 1001 */ PTR(366, 2), /* 1010 */ PTR(370, 2), /* 1011 */ V(14, 3, 4), /* 1100 */ PTR(374, 1), /* 1101 */ PTR(376, 1), /* 1110 */ PTR(378, 1), /* 1111 */ PTR(380, 1), /* 0000 1100 ... */ /* 0000 */ PTR(382, 1), /* 128 */ /* 0001 */ PTR(384, 1), /* 0010 */ PTR(386, 1), /* 0011 */ V(0, 13, 4), /* 0100 */ PTR(388, 1), /* 0101 */ PTR(390, 1), /* 0110 */ PTR(392, 1), /* 0111 */ V(3, 12, 4), /* 1000 */ PTR(394, 1), /* 1001 */ V(1, 12, 4), /* 1010 */ V(12, 0, 4), /* 1011 */ PTR(396, 1), /* 1100 */ V(14, 2, 3), /* 1101 */ V(14, 2, 3), /* 1110 */ V(2, 14, 4), /* 1111 */ V(1, 14, 4), /* 0000 1101 ... */ /* 0000 */ V(13, 3, 4), /* 144 */ /* 0001 */ V(2, 13, 4), /* 0010 */ V(13, 2, 4), /* 0011 */ V(13, 1, 4), /* 0100 */ V(3, 11, 4), /* 0101 */ PTR(398, 1), /* 0110 */ V(1, 13, 3), /* 0111 */ V(1, 13, 3), /* 1000 */ V(12, 4, 4), /* 1001 */ V(6, 11, 4), /* 1010 */ V(12, 3, 4), /* 1011 */ V(10, 7, 4), /* 1100 */ V(2, 12, 3), /* 1101 */ V(2, 12, 3), /* 1110 */ V(12, 2, 4), /* 1111 */ V(11, 5, 4), /* 0000 1110 ... */ /* 0000 */ V(12, 1, 4), /* 160 */ /* 0001 */ V(0, 12, 4), /* 0010 */ V(4, 11, 4), /* 0011 */ V(11, 4, 4), /* 0100 */ V(6, 10, 4), /* 0101 */ V(10, 6, 4), /* 0110 */ V(11, 3, 3), /* 0111 */ V(11, 3, 3), /* 1000 */ V(5, 10, 4), /* 1001 */ V(10, 5, 4), /* 1010 */ V(2, 11, 3), /* 1011 */ V(2, 11, 3), /* 1100 */ V(11, 2, 3), /* 1101 */ V(11, 2, 3), /* 1110 */ V(1, 11, 3), /* 1111 */ V(1, 11, 3), /* 0000 1111 ... */ /* 0000 */ V(11, 1, 3), /* 176 */ /* 0001 */ V(11, 1, 3), /* 0010 */ V(0, 11, 4), /* 0011 */ V(11, 0, 4), /* 0100 */ V(6, 9, 4), /* 0101 */ V(9, 6, 4), /* 0110 */ V(4, 10, 4), /* 0111 */ V(10, 4, 4), /* 1000 */ V(7, 8, 4), /* 1001 */ V(8, 7, 4), /* 1010 */ V(10, 3, 3), /* 1011 */ V(10, 3, 3), /* 1100 */ V(3, 10, 4), /* 1101 */ V(5, 9, 4), /* 1110 */ V(2, 10, 3), /* 1111 */ V(2, 10, 3), /* 0001 0000 ... */ /* 0000 */ V(9, 5, 4), /* 192 */ /* 0001 */ V(6, 8, 4), /* 0010 */ V(10, 1, 3), /* 0011 */ V(10, 1, 3), /* 0100 */ V(8, 6, 4), /* 0101 */ V(7, 7, 4), /* 0110 */ V(9, 4, 3), /* 0111 */ V(9, 4, 3), /* 1000 */ V(4, 9, 4), /* 1001 */ V(5, 7, 4), /* 1010 */ V(6, 7, 3), /* 1011 */ V(6, 7, 3), /* 1100 */ V(10, 2, 2), /* 1101 */ V(10, 2, 2), /* 1110 */ V(10, 2, 2), /* 1111 */ V(10, 2, 2), /* 0001 0001 ... */ /* 000 */ V(1, 10, 2), /* 208 */ /* 001 */ V(1, 10, 2), /* 010 */ V(0, 10, 3), /* 011 */ V(10, 0, 3), /* 100 */ V(3, 9, 3), /* 101 */ V(9, 3, 3), /* 110 */ V(5, 8, 3), /* 111 */ V(8, 5, 3), /* 0001 0010 ... */ /* 000 */ V(2, 9, 2), /* 216 */ /* 001 */ V(2, 9, 2), /* 010 */ V(9, 2, 2), /* 011 */ V(9, 2, 2), /* 100 */ V(7, 6, 3), /* 101 */ V(0, 9, 3), /* 110 */ V(1, 9, 2), /* 111 */ V(1, 9, 2), /* 0001 0011 ... */ /* 000 */ V(9, 1, 2), /* 224 */ /* 001 */ V(9, 1, 2), /* 010 */ V(9, 0, 3), /* 011 */ V(4, 8, 3), /* 100 */ V(8, 4, 3), /* 101 */ V(7, 5, 3), /* 110 */ V(3, 8, 3), /* 111 */ V(8, 3, 3), /* 0001 0100 ... */ /* 000 */ V(6, 6, 3), /* 232 */ /* 001 */ V(2, 8, 3), /* 010 */ V(8, 2, 2), /* 011 */ V(8, 2, 2), /* 100 */ V(4, 7, 3), /* 101 */ V(7, 4, 3), /* 110 */ V(1, 8, 2), /* 111 */ V(1, 8, 2), /* 0001 0101 ... */ /* 000 */ V(8, 1, 2), /* 240 */ /* 001 */ V(8, 1, 2), /* 010 */ V(8, 0, 2), /* 011 */ V(8, 0, 2), /* 100 */ V(0, 8, 3), /* 101 */ V(5, 6, 3), /* 110 */ V(3, 7, 2), /* 111 */ V(3, 7, 2), /* 0001 0110 ... */ /* 000 */ V(7, 3, 2), /* 248 */ /* 001 */ V(7, 3, 2), /* 010 */ V(6, 5, 3), /* 011 */ V(4, 6, 3), /* 100 */ V(2, 7, 2), /* 101 */ V(2, 7, 2), /* 110 */ V(7, 2, 2), /* 111 */ V(7, 2, 2), /* 0001 0111 ... */ /* 000 */ V(6, 4, 3), /* 256 */ /* 001 */ V(5, 5, 3), /* 010 */ V(0, 7, 2), /* 011 */ V(0, 7, 2), /* 100 */ V(1, 7, 1), /* 101 */ V(1, 7, 1), /* 110 */ V(1, 7, 1), /* 111 */ V(1, 7, 1), /* 0001 1000 ... */ /* 00 */ V(7, 1, 1), /* 264 */ /* 01 */ V(7, 1, 1), /* 10 */ V(7, 0, 2), /* 11 */ V(3, 6, 2), /* 0001 1001 ... */ /* 00 */ V(6, 3, 2), /* 268 */ /* 01 */ V(4, 5, 2), /* 10 */ V(5, 4, 2), /* 11 */ V(2, 6, 2), /* 0001 1010 ... */ /* 0 */ V(6, 2, 1), /* 272 */ /* 1 */ V(1, 6, 1), /* 0001 1011 ... */ /* 00 */ V(6, 1, 1), /* 274 */ /* 01 */ V(6, 1, 1), /* 10 */ V(0, 6, 2), /* 11 */ V(6, 0, 2), /* 0001 1100 ... */ /* 00 */ V(5, 3, 1), /* 278 */ /* 01 */ V(5, 3, 1), /* 10 */ V(3, 5, 2), /* 11 */ V(4, 4, 2), /* 0001 1101 ... */ /* 0 */ V(2, 5, 1), /* 282 */ /* 1 */ V(5, 2, 1), /* 0001 1111 ... */ /* 0 */ V(1, 5, 1), /* 284 */ /* 1 */ V(0, 5, 1), /* 0010 0000 ... */ /* 0 */ V(3, 4, 1), /* 286 */ /* 1 */ V(4, 3, 1), /* 0010 0001 ... */ /* 0 */ V(5, 0, 1), /* 288 */ /* 1 */ V(2, 4, 1), /* 0010 0010 ... */ /* 0 */ V(4, 2, 1), /* 290 */ /* 1 */ V(3, 3, 1), /* 0010 0101 ... */ /* 0 */ V(0, 4, 1), /* 292 */ /* 1 */ V(4, 0, 1), /* 0000 0110 1100 ... */ /* 0000 */ V(12, 14, 4), /* 294 */ /* 0001 */ PTR(400, 1), /* 0010 */ V(13, 14, 3), /* 0011 */ V(13, 14, 3), /* 0100 */ V(14, 9, 3), /* 0101 */ V(14, 9, 3), /* 0110 */ V(14, 10, 4), /* 0111 */ V(13, 9, 4), /* 1000 */ V(14, 14, 2), /* 1001 */ V(14, 14, 2), /* 1010 */ V(14, 14, 2), /* 1011 */ V(14, 14, 2), /* 1100 */ V(14, 13, 3), /* 1101 */ V(14, 13, 3), /* 1110 */ V(14, 11, 3), /* 1111 */ V(14, 11, 3), /* 0000 0110 1101 ... */ /* 000 */ V(11, 14, 2), /* 310 */ /* 001 */ V(11, 14, 2), /* 010 */ V(12, 13, 2), /* 011 */ V(12, 13, 2), /* 100 */ V(13, 12, 3), /* 101 */ V(13, 11, 3), /* 110 */ V(10, 14, 2), /* 111 */ V(10, 14, 2), /* 0000 0110 1110 ... */ /* 000 */ V(12, 12, 2), /* 318 */ /* 001 */ V(12, 12, 2), /* 010 */ V(10, 13, 3), /* 011 */ V(13, 10, 3), /* 100 */ V(7, 14, 3), /* 101 */ V(10, 12, 3), /* 110 */ V(12, 10, 2), /* 111 */ V(12, 10, 2), /* 0000 0110 1111 ... */ /* 000 */ V(12, 9, 3), /* 326 */ /* 001 */ V(7, 13, 3), /* 010 */ V(5, 14, 2), /* 011 */ V(5, 14, 2), /* 100 */ V(11, 13, 1), /* 101 */ V(11, 13, 1), /* 110 */ V(11, 13, 1), /* 111 */ V(11, 13, 1), /* 0000 1011 0000 ... */ /* 00 */ V(9, 14, 1), /* 334 */ /* 01 */ V(9, 14, 1), /* 10 */ V(11, 12, 2), /* 11 */ V(12, 11, 2), /* 0000 1011 0001 ... */ /* 00 */ V(8, 14, 2), /* 338 */ /* 01 */ V(14, 8, 2), /* 10 */ V(9, 13, 2), /* 11 */ V(14, 7, 2), /* 0000 1011 0010 ... */ /* 00 */ V(11, 11, 2), /* 342 */ /* 01 */ V(8, 13, 2), /* 10 */ V(13, 8, 2), /* 11 */ V(6, 14, 2), /* 0000 1011 0011 ... */ /* 0 */ V(14, 6, 1), /* 346 */ /* 1 */ V(9, 12, 1), /* 0000 1011 0100 ... */ /* 00 */ V(10, 11, 2), /* 348 */ /* 01 */ V(11, 10, 2), /* 10 */ V(14, 5, 2), /* 11 */ V(13, 7, 2), /* 0000 1011 0101 ... */ /* 00 */ V(4, 14, 1), /* 352 */ /* 01 */ V(4, 14, 1), /* 10 */ V(14, 4, 2), /* 11 */ V(8, 12, 2), /* 0000 1011 0110 ... */ /* 0 */ V(12, 8, 1), /* 356 */ /* 1 */ V(3, 14, 1), /* 0000 1011 0111 ... */ /* 00 */ V(6, 13, 1), /* 358 */ /* 01 */ V(6, 13, 1), /* 10 */ V(13, 6, 2), /* 11 */ V(9, 11, 2), /* 0000 1011 1000 ... */ /* 00 */ V(11, 9, 2), /* 362 */ /* 01 */ V(10, 10, 2), /* 10 */ V(14, 1, 1), /* 11 */ V(14, 1, 1), /* 0000 1011 1001 ... */ /* 00 */ V(13, 4, 1), /* 366 */ /* 01 */ V(13, 4, 1), /* 10 */ V(11, 8, 2), /* 11 */ V(10, 9, 2), /* 0000 1011 1010 ... */ /* 00 */ V(7, 11, 1), /* 370 */ /* 01 */ V(7, 11, 1), /* 10 */ V(11, 7, 2), /* 11 */ V(13, 0, 2), /* 0000 1011 1100 ... */ /* 0 */ V(0, 14, 1), /* 374 */ /* 1 */ V(14, 0, 1), /* 0000 1011 1101 ... */ /* 0 */ V(5, 13, 1), /* 376 */ /* 1 */ V(13, 5, 1), /* 0000 1011 1110 ... */ /* 0 */ V(7, 12, 1), /* 378 */ /* 1 */ V(12, 7, 1), /* 0000 1011 1111 ... */ /* 0 */ V(4, 13, 1), /* 380 */ /* 1 */ V(8, 11, 1), /* 0000 1100 0000 ... */ /* 0 */ V(9, 10, 1), /* 382 */ /* 1 */ V(6, 12, 1), /* 0000 1100 0001 ... */ /* 0 */ V(12, 6, 1), /* 384 */ /* 1 */ V(3, 13, 1), /* 0000 1100 0010 ... */ /* 0 */ V(5, 12, 1), /* 386 */ /* 1 */ V(12, 5, 1), /* 0000 1100 0100 ... */ /* 0 */ V(8, 10, 1), /* 388 */ /* 1 */ V(10, 8, 1), /* 0000 1100 0101 ... */ /* 0 */ V(9, 9, 1), /* 390 */ /* 1 */ V(4, 12, 1), /* 0000 1100 0110 ... */ /* 0 */ V(11, 6, 1), /* 392 */ /* 1 */ V(7, 10, 1), /* 0000 1100 1000 ... */ /* 0 */ V(5, 11, 1), /* 394 */ /* 1 */ V(8, 9, 1), /* 0000 1100 1011 ... */ /* 0 */ V(9, 8, 1), /* 396 */ /* 1 */ V(7, 9, 1), /* 0000 1101 0101 ... */ /* 0 */ V(9, 7, 1), /* 398 */ /* 1 */ V(8, 8, 1), /* 0000 0110 1100 0001 ... */ /* 0 */ V(14, 12, 1), /* 400 */ /* 1 */ V(13, 13, 1) }; static union huffpair const hufftab24[] = { /* 0000 */ PTR(16, 4), /* 0001 */ PTR(32, 4), /* 0010 */ PTR(48, 4), /* 0011 */ V(15, 15, 4), /* 0100 */ PTR(64, 4), /* 0101 */ PTR(80, 4), /* 0110 */ PTR(96, 4), /* 0111 */ PTR(112, 4), /* 1000 */ PTR(128, 4), /* 1001 */ PTR(144, 4), /* 1010 */ PTR(160, 3), /* 1011 */ PTR(168, 2), /* 1100 */ V(1, 1, 4), /* 1101 */ V(0, 1, 4), /* 1110 */ V(1, 0, 4), /* 1111 */ V(0, 0, 4), /* 0000 ... */ /* 0000 */ V(14, 15, 4), /* 16 */ /* 0001 */ V(15, 14, 4), /* 0010 */ V(13, 15, 4), /* 0011 */ V(15, 13, 4), /* 0100 */ V(12, 15, 4), /* 0101 */ V(15, 12, 4), /* 0110 */ V(11, 15, 4), /* 0111 */ V(15, 11, 4), /* 1000 */ V(15, 10, 3), /* 1001 */ V(15, 10, 3), /* 1010 */ V(10, 15, 4), /* 1011 */ V(9, 15, 4), /* 1100 */ V(15, 9, 3), /* 1101 */ V(15, 9, 3), /* 1110 */ V(15, 8, 3), /* 1111 */ V(15, 8, 3), /* 0001 ... */ /* 0000 */ V(8, 15, 4), /* 32 */ /* 0001 */ V(7, 15, 4), /* 0010 */ V(15, 7, 3), /* 0011 */ V(15, 7, 3), /* 0100 */ V(6, 15, 3), /* 0101 */ V(6, 15, 3), /* 0110 */ V(15, 6, 3), /* 0111 */ V(15, 6, 3), /* 1000 */ V(5, 15, 3), /* 1001 */ V(5, 15, 3), /* 1010 */ V(15, 5, 3), /* 1011 */ V(15, 5, 3), /* 1100 */ V(4, 15, 3), /* 1101 */ V(4, 15, 3), /* 1110 */ V(15, 4, 3), /* 1111 */ V(15, 4, 3), /* 0010 ... */ /* 0000 */ V(3, 15, 3), /* 48 */ /* 0001 */ V(3, 15, 3), /* 0010 */ V(15, 3, 3), /* 0011 */ V(15, 3, 3), /* 0100 */ V(2, 15, 3), /* 0101 */ V(2, 15, 3), /* 0110 */ V(15, 2, 3), /* 0111 */ V(15, 2, 3), /* 1000 */ V(15, 1, 3), /* 1001 */ V(15, 1, 3), /* 1010 */ V(1, 15, 4), /* 1011 */ V(15, 0, 4), /* 1100 */ PTR(172, 3), /* 1101 */ PTR(180, 3), /* 1110 */ PTR(188, 3), /* 1111 */ PTR(196, 3), /* 0100 ... */ /* 0000 */ PTR(204, 4), /* 64 */ /* 0001 */ PTR(220, 3), /* 0010 */ PTR(228, 3), /* 0011 */ PTR(236, 3), /* 0100 */ PTR(244, 2), /* 0101 */ PTR(248, 2), /* 0110 */ PTR(252, 2), /* 0111 */ PTR(256, 2), /* 1000 */ PTR(260, 2), /* 1001 */ PTR(264, 2), /* 1010 */ PTR(268, 2), /* 1011 */ PTR(272, 2), /* 1100 */ PTR(276, 2), /* 1101 */ PTR(280, 3), /* 1110 */ PTR(288, 2), /* 1111 */ PTR(292, 2), /* 0101 ... */ /* 0000 */ PTR(296, 2), /* 80 */ /* 0001 */ PTR(300, 3), /* 0010 */ PTR(308, 2), /* 0011 */ PTR(312, 3), /* 0100 */ PTR(320, 1), /* 0101 */ PTR(322, 2), /* 0110 */ PTR(326, 2), /* 0111 */ PTR(330, 1), /* 1000 */ PTR(332, 2), /* 1001 */ PTR(336, 1), /* 1010 */ PTR(338, 1), /* 1011 */ PTR(340, 1), /* 1100 */ PTR(342, 1), /* 1101 */ PTR(344, 1), /* 1110 */ PTR(346, 1), /* 1111 */ PTR(348, 1), /* 0110 ... */ /* 0000 */ PTR(350, 1), /* 96 */ /* 0001 */ PTR(352, 1), /* 0010 */ PTR(354, 1), /* 0011 */ PTR(356, 1), /* 0100 */ PTR(358, 1), /* 0101 */ PTR(360, 1), /* 0110 */ PTR(362, 1), /* 0111 */ PTR(364, 1), /* 1000 */ PTR(366, 1), /* 1001 */ PTR(368, 1), /* 1010 */ PTR(370, 2), /* 1011 */ PTR(374, 1), /* 1100 */ PTR(376, 2), /* 1101 */ V(7, 3, 4), /* 1110 */ PTR(380, 1), /* 1111 */ V(7, 2, 4), /* 0111 ... */ /* 0000 */ V(4, 6, 4), /* 112 */ /* 0001 */ V(6, 4, 4), /* 0010 */ V(5, 5, 4), /* 0011 */ V(7, 1, 4), /* 0100 */ V(3, 6, 4), /* 0101 */ V(6, 3, 4), /* 0110 */ V(4, 5, 4), /* 0111 */ V(5, 4, 4), /* 1000 */ V(2, 6, 4), /* 1001 */ V(6, 2, 4), /* 1010 */ V(1, 6, 4), /* 1011 */ V(6, 1, 4), /* 1100 */ PTR(382, 1), /* 1101 */ V(3, 5, 4), /* 1110 */ V(5, 3, 4), /* 1111 */ V(4, 4, 4), /* 1000 ... */ /* 0000 */ V(2, 5, 4), /* 128 */ /* 0001 */ V(5, 2, 4), /* 0010 */ V(1, 5, 4), /* 0011 */ PTR(384, 1), /* 0100 */ V(5, 1, 3), /* 0101 */ V(5, 1, 3), /* 0110 */ V(3, 4, 4), /* 0111 */ V(4, 3, 4), /* 1000 */ V(2, 4, 3), /* 1001 */ V(2, 4, 3), /* 1010 */ V(4, 2, 3), /* 1011 */ V(4, 2, 3), /* 1100 */ V(3, 3, 3), /* 1101 */ V(3, 3, 3), /* 1110 */ V(1, 4, 3), /* 1111 */ V(1, 4, 3), /* 1001 ... */ /* 0000 */ V(4, 1, 3), /* 144 */ /* 0001 */ V(4, 1, 3), /* 0010 */ V(0, 4, 4), /* 0011 */ V(4, 0, 4), /* 0100 */ V(2, 3, 3), /* 0101 */ V(2, 3, 3), /* 0110 */ V(3, 2, 3), /* 0111 */ V(3, 2, 3), /* 1000 */ V(1, 3, 2), /* 1001 */ V(1, 3, 2), /* 1010 */ V(1, 3, 2), /* 1011 */ V(1, 3, 2), /* 1100 */ V(3, 1, 2), /* 1101 */ V(3, 1, 2), /* 1110 */ V(3, 1, 2), /* 1111 */ V(3, 1, 2), /* 1010 ... */ /* 000 */ V(0, 3, 3), /* 160 */ /* 001 */ V(3, 0, 3), /* 010 */ V(2, 2, 2), /* 011 */ V(2, 2, 2), /* 100 */ V(1, 2, 1), /* 101 */ V(1, 2, 1), /* 110 */ V(1, 2, 1), /* 111 */ V(1, 2, 1), /* 1011 ... */ /* 00 */ V(2, 1, 1), /* 168 */ /* 01 */ V(2, 1, 1), /* 10 */ V(0, 2, 2), /* 11 */ V(2, 0, 2), /* 0010 1100 ... */ /* 000 */ V(0, 15, 1), /* 172 */ /* 001 */ V(0, 15, 1), /* 010 */ V(0, 15, 1), /* 011 */ V(0, 15, 1), /* 100 */ V(14, 14, 3), /* 101 */ V(13, 14, 3), /* 110 */ V(14, 13, 3), /* 111 */ V(12, 14, 3), /* 0010 1101 ... */ /* 000 */ V(14, 12, 3), /* 180 */ /* 001 */ V(13, 13, 3), /* 010 */ V(11, 14, 3), /* 011 */ V(14, 11, 3), /* 100 */ V(12, 13, 3), /* 101 */ V(13, 12, 3), /* 110 */ V(10, 14, 3), /* 111 */ V(14, 10, 3), /* 0010 1110 ... */ /* 000 */ V(11, 13, 3), /* 188 */ /* 001 */ V(13, 11, 3), /* 010 */ V(12, 12, 3), /* 011 */ V(9, 14, 3), /* 100 */ V(14, 9, 3), /* 101 */ V(10, 13, 3), /* 110 */ V(13, 10, 3), /* 111 */ V(11, 12, 3), /* 0010 1111 ... */ /* 000 */ V(12, 11, 3), /* 196 */ /* 001 */ V(8, 14, 3), /* 010 */ V(14, 8, 3), /* 011 */ V(9, 13, 3), /* 100 */ V(13, 9, 3), /* 101 */ V(7, 14, 3), /* 110 */ V(14, 7, 3), /* 111 */ V(10, 12, 3), /* 0100 0000 ... */ /* 0000 */ V(12, 10, 3), /* 204 */ /* 0001 */ V(12, 10, 3), /* 0010 */ V(11, 11, 3), /* 0011 */ V(11, 11, 3), /* 0100 */ V(8, 13, 3), /* 0101 */ V(8, 13, 3), /* 0110 */ V(13, 8, 3), /* 0111 */ V(13, 8, 3), /* 1000 */ V(0, 14, 4), /* 1001 */ V(14, 0, 4), /* 1010 */ V(0, 13, 3), /* 1011 */ V(0, 13, 3), /* 1100 */ V(14, 6, 2), /* 1101 */ V(14, 6, 2), /* 1110 */ V(14, 6, 2), /* 1111 */ V(14, 6, 2), /* 0100 0001 ... */ /* 000 */ V(6, 14, 3), /* 220 */ /* 001 */ V(9, 12, 3), /* 010 */ V(12, 9, 2), /* 011 */ V(12, 9, 2), /* 100 */ V(5, 14, 2), /* 101 */ V(5, 14, 2), /* 110 */ V(11, 10, 2), /* 111 */ V(11, 10, 2), /* 0100 0010 ... */ /* 000 */ V(14, 5, 2), /* 228 */ /* 001 */ V(14, 5, 2), /* 010 */ V(10, 11, 3), /* 011 */ V(7, 13, 3), /* 100 */ V(13, 7, 2), /* 101 */ V(13, 7, 2), /* 110 */ V(14, 4, 2), /* 111 */ V(14, 4, 2), /* 0100 0011 ... */ /* 000 */ V(8, 12, 2), /* 236 */ /* 001 */ V(8, 12, 2), /* 010 */ V(12, 8, 2), /* 011 */ V(12, 8, 2), /* 100 */ V(4, 14, 3), /* 101 */ V(2, 14, 3), /* 110 */ V(3, 14, 2), /* 111 */ V(3, 14, 2), /* 0100 0100 ... */ /* 00 */ V(6, 13, 2), /* 244 */ /* 01 */ V(13, 6, 2), /* 10 */ V(14, 3, 2), /* 11 */ V(9, 11, 2), /* 0100 0101 ... */ /* 00 */ V(11, 9, 2), /* 248 */ /* 01 */ V(10, 10, 2), /* 10 */ V(14, 2, 2), /* 11 */ V(1, 14, 2), /* 0100 0110 ... */ /* 00 */ V(14, 1, 2), /* 252 */ /* 01 */ V(5, 13, 2), /* 10 */ V(13, 5, 2), /* 11 */ V(7, 12, 2), /* 0100 0111 ... */ /* 00 */ V(12, 7, 2), /* 256 */ /* 01 */ V(4, 13, 2), /* 10 */ V(8, 11, 2), /* 11 */ V(11, 8, 2), /* 0100 1000 ... */ /* 00 */ V(13, 4, 2), /* 260 */ /* 01 */ V(9, 10, 2), /* 10 */ V(10, 9, 2), /* 11 */ V(6, 12, 2), /* 0100 1001 ... */ /* 00 */ V(12, 6, 2), /* 264 */ /* 01 */ V(3, 13, 2), /* 10 */ V(13, 3, 2), /* 11 */ V(2, 13, 2), /* 0100 1010 ... */ /* 00 */ V(13, 2, 2), /* 268 */ /* 01 */ V(1, 13, 2), /* 10 */ V(7, 11, 2), /* 11 */ V(11, 7, 2), /* 0100 1011 ... */ /* 00 */ V(13, 1, 2), /* 272 */ /* 01 */ V(5, 12, 2), /* 10 */ V(12, 5, 2), /* 11 */ V(8, 10, 2), /* 0100 1100 ... */ /* 00 */ V(10, 8, 2), /* 276 */ /* 01 */ V(9, 9, 2), /* 10 */ V(4, 12, 2), /* 11 */ V(12, 4, 2), /* 0100 1101 ... */ /* 000 */ V(6, 11, 2), /* 280 */ /* 001 */ V(6, 11, 2), /* 010 */ V(11, 6, 2), /* 011 */ V(11, 6, 2), /* 100 */ V(13, 0, 3), /* 101 */ V(0, 12, 3), /* 110 */ V(3, 12, 2), /* 111 */ V(3, 12, 2), /* 0100 1110 ... */ /* 00 */ V(12, 3, 2), /* 288 */ /* 01 */ V(7, 10, 2), /* 10 */ V(10, 7, 2), /* 11 */ V(2, 12, 2), /* 0100 1111 ... */ /* 00 */ V(12, 2, 2), /* 292 */ /* 01 */ V(5, 11, 2), /* 10 */ V(11, 5, 2), /* 11 */ V(1, 12, 2), /* 0101 0000 ... */ /* 00 */ V(8, 9, 2), /* 296 */ /* 01 */ V(9, 8, 2), /* 10 */ V(12, 1, 2), /* 11 */ V(4, 11, 2), /* 0101 0001 ... */ /* 000 */ V(12, 0, 3), /* 300 */ /* 001 */ V(0, 11, 3), /* 010 */ V(3, 11, 2), /* 011 */ V(3, 11, 2), /* 100 */ V(11, 0, 3), /* 101 */ V(0, 10, 3), /* 110 */ V(1, 10, 2), /* 111 */ V(1, 10, 2), /* 0101 0010 ... */ /* 00 */ V(11, 4, 1), /* 308 */ /* 01 */ V(11, 4, 1), /* 10 */ V(6, 10, 2), /* 11 */ V(10, 6, 2), /* 0101 0011 ... */ /* 000 */ V(7, 9, 2), /* 312 */ /* 001 */ V(7, 9, 2), /* 010 */ V(9, 7, 2), /* 011 */ V(9, 7, 2), /* 100 */ V(10, 0, 3), /* 101 */ V(0, 9, 3), /* 110 */ V(9, 0, 2), /* 111 */ V(9, 0, 2), /* 0101 0100 ... */ /* 0 */ V(11, 3, 1), /* 320 */ /* 1 */ V(8, 8, 1), /* 0101 0101 ... */ /* 00 */ V(2, 11, 2), /* 322 */ /* 01 */ V(5, 10, 2), /* 10 */ V(11, 2, 1), /* 11 */ V(11, 2, 1), /* 0101 0110 ... */ /* 00 */ V(10, 5, 2), /* 326 */ /* 01 */ V(1, 11, 2), /* 10 */ V(11, 1, 2), /* 11 */ V(6, 9, 2), /* 0101 0111 ... */ /* 0 */ V(9, 6, 1), /* 330 */ /* 1 */ V(10, 4, 1), /* 0101 1000 ... */ /* 00 */ V(4, 10, 2), /* 332 */ /* 01 */ V(7, 8, 2), /* 10 */ V(8, 7, 1), /* 11 */ V(8, 7, 1), /* 0101 1001 ... */ /* 0 */ V(3, 10, 1), /* 336 */ /* 1 */ V(10, 3, 1), /* 0101 1010 ... */ /* 0 */ V(5, 9, 1), /* 338 */ /* 1 */ V(9, 5, 1), /* 0101 1011 ... */ /* 0 */ V(2, 10, 1), /* 340 */ /* 1 */ V(10, 2, 1), /* 0101 1100 ... */ /* 0 */ V(10, 1, 1), /* 342 */ /* 1 */ V(6, 8, 1), /* 0101 1101 ... */ /* 0 */ V(8, 6, 1), /* 344 */ /* 1 */ V(7, 7, 1), /* 0101 1110 ... */ /* 0 */ V(4, 9, 1), /* 346 */ /* 1 */ V(9, 4, 1), /* 0101 1111 ... */ /* 0 */ V(3, 9, 1), /* 348 */ /* 1 */ V(9, 3, 1), /* 0110 0000 ... */ /* 0 */ V(5, 8, 1), /* 350 */ /* 1 */ V(8, 5, 1), /* 0110 0001 ... */ /* 0 */ V(2, 9, 1), /* 352 */ /* 1 */ V(6, 7, 1), /* 0110 0010 ... */ /* 0 */ V(7, 6, 1), /* 354 */ /* 1 */ V(9, 2, 1), /* 0110 0011 ... */ /* 0 */ V(1, 9, 1), /* 356 */ /* 1 */ V(9, 1, 1), /* 0110 0100 ... */ /* 0 */ V(4, 8, 1), /* 358 */ /* 1 */ V(8, 4, 1), /* 0110 0101 ... */ /* 0 */ V(5, 7, 1), /* 360 */ /* 1 */ V(7, 5, 1), /* 0110 0110 ... */ /* 0 */ V(3, 8, 1), /* 362 */ /* 1 */ V(8, 3, 1), /* 0110 0111 ... */ /* 0 */ V(6, 6, 1), /* 364 */ /* 1 */ V(2, 8, 1), /* 0110 1000 ... */ /* 0 */ V(8, 2, 1), /* 366 */ /* 1 */ V(1, 8, 1), /* 0110 1001 ... */ /* 0 */ V(4, 7, 1), /* 368 */ /* 1 */ V(7, 4, 1), /* 0110 1010 ... */ /* 00 */ V(8, 1, 1), /* 370 */ /* 01 */ V(8, 1, 1), /* 10 */ V(0, 8, 2), /* 11 */ V(8, 0, 2), /* 0110 1011 ... */ /* 0 */ V(5, 6, 1), /* 374 */ /* 1 */ V(6, 5, 1), /* 0110 1100 ... */ /* 00 */ V(1, 7, 1), /* 376 */ /* 01 */ V(1, 7, 1), /* 10 */ V(0, 7, 2), /* 11 */ V(7, 0, 2), /* 0110 1110 ... */ /* 0 */ V(3, 7, 1), /* 380 */ /* 1 */ V(2, 7, 1), /* 0111 1100 ... */ /* 0 */ V(0, 6, 1), /* 382 */ /* 1 */ V(6, 0, 1), /* 1000 0011 ... */ /* 0 */ V(0, 5, 1), /* 384 */ /* 1 */ V(5, 0, 1) }; # undef V # undef PTR /* external tables */ union huffquad const *const mad_huff_quad_table[2] = { hufftabA, hufftabB }; struct hufftable const mad_huff_pair_table[32] = { /* 0 */ { hufftab0, 0, 0 }, /* 1 */ { hufftab1, 0, 3 }, /* 2 */ { hufftab2, 0, 3 }, /* 3 */ { hufftab3, 0, 3 }, /* 4 */ { NULL, 0, 0 }, /* not used */ /* 5 */ { hufftab5, 0, 3 }, /* 6 */ { hufftab6, 0, 4 }, /* 7 */ { hufftab7, 0, 4 }, /* 8 */ { hufftab8, 0, 4 }, /* 9 */ { hufftab9, 0, 4 }, /* 10 */ { hufftab10, 0, 4 }, /* 11 */ { hufftab11, 0, 4 }, /* 12 */ { hufftab12, 0, 4 }, /* 13 */ { hufftab13, 0, 4 }, /* 14 */ { NULL, 0, 0 }, /* not used */ /* 15 */ { hufftab15, 0, 4 }, /* 16 */ { hufftab16, 1, 4 }, /* 17 */ { hufftab16, 2, 4 }, /* 18 */ { hufftab16, 3, 4 }, /* 19 */ { hufftab16, 4, 4 }, /* 20 */ { hufftab16, 6, 4 }, /* 21 */ { hufftab16, 8, 4 }, /* 22 */ { hufftab16, 10, 4 }, /* 23 */ { hufftab16, 13, 4 }, /* 24 */ { hufftab24, 4, 4 }, /* 25 */ { hufftab24, 5, 4 }, /* 26 */ { hufftab24, 6, 4 }, /* 27 */ { hufftab24, 7, 4 }, /* 28 */ { hufftab24, 8, 4 }, /* 29 */ { hufftab24, 9, 4 }, /* 30 */ { hufftab24, 11, 4 }, /* 31 */ { hufftab24, 13, 4 } }; xine-lib-1.2/contrib/libmad/layer3.c0000644000175000017500000021076414647725152015131 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer3.c,v 1.43 2004/01/23 09:41:32 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include # include # ifdef HAVE_ASSERT_H # include # endif # ifdef HAVE_LIMITS_H # include # else # define CHAR_BIT 8 # endif # include "fixed.h" # include "bit.h" # include "stream.h" # include "frame.h" # include "huffman.h" # include "layer3.h" /* --- Layer III ----------------------------------------------------------- */ enum { count1table_select = 0x01, scalefac_scale = 0x02, preflag = 0x04, mixed_block_flag = 0x08 }; enum { I_STEREO = 0x1, MS_STEREO = 0x2 }; struct sideinfo { unsigned int main_data_begin; unsigned int private_bits; unsigned char scfsi[2]; struct granule { struct channel { /* from side info */ unsigned short part2_3_length; unsigned short big_values; unsigned short global_gain; unsigned short scalefac_compress; unsigned char flags; unsigned char block_type; unsigned char table_select[3]; unsigned char subblock_gain[3]; unsigned char region0_count; unsigned char region1_count; /* from main_data */ unsigned char scalefac[39]; /* scalefac_l and/or scalefac_s */ } ch[2]; } gr[2]; }; /* * scalefactor bit lengths * derived from section 2.4.2.7 of ISO/IEC 11172-3 */ static struct { unsigned char slen1; unsigned char slen2; } const sflen_table[16] = { { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 3, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }, { 2, 1 }, { 2, 2 }, { 2, 3 }, { 3, 1 }, { 3, 2 }, { 3, 3 }, { 4, 2 }, { 4, 3 } }; /* * number of LSF scalefactor band values * derived from section 2.4.3.2 of ISO/IEC 13818-3 */ static unsigned char const nsfb_table[6][3][4] = { { { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } }, { { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } }, { { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } }, { { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } }, { { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } }, { { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } } }; /* * MPEG-1 scalefactor band widths * derived from Table B.8 of ISO/IEC 11172-3 */ static unsigned char const sfb_48000_long[] = { 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10, 12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192 }; static unsigned char const sfb_44100_long[] = { 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10, 12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158 }; static unsigned char const sfb_32000_long[] = { 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12, 16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26 }; static unsigned char const sfb_48000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14, 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 }; static unsigned char const sfb_44100_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 }; static unsigned char const sfb_32000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 }; static unsigned char const sfb_48000_mixed[] = { /* long */ 4, 4, 4, 4, 4, 4, 6, 6, /* short */ 4, 4, 4, 6, 6, 6, 6, 6, 6, 10, 10, 10, 12, 12, 12, 14, 14, 14, 16, 16, 16, 20, 20, 20, 26, 26, 26, 66, 66, 66 }; static unsigned char const sfb_44100_mixed[] = { /* long */ 4, 4, 4, 4, 4, 4, 6, 6, /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 22, 22, 22, 30, 30, 30, 56, 56, 56 }; static unsigned char const sfb_32000_mixed[] = { /* long */ 4, 4, 4, 4, 4, 4, 6, 6, /* short */ 4, 4, 4, 6, 6, 6, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 26, 26, 26, 34, 34, 34, 42, 42, 42, 12, 12, 12 }; /* * MPEG-2 scalefactor band widths * derived from Table B.2 of ISO/IEC 13818-3 */ static unsigned char const sfb_24000_long[] = { 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 18, 22, 26, 32, 38, 46, 54, 62, 70, 76, 36 }; static unsigned char const sfb_22050_long[] = { 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54 }; # define sfb_16000_long sfb_22050_long static unsigned char const sfb_24000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 }; static unsigned char const sfb_22050_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18, 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 }; static unsigned char const sfb_16000_short[] = { 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 }; static unsigned char const sfb_24000_mixed[] = { /* long */ 6, 6, 6, 6, 6, 6, /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 32, 32, 32, 44, 44, 44, 12, 12, 12 }; static unsigned char const sfb_22050_mixed[] = { /* long */ 6, 6, 6, 6, 6, 6, /* short */ 6, 6, 6, 6, 6, 6, 8, 8, 8, 10, 10, 10, 14, 14, 14, 18, 18, 18, 26, 26, 26, 32, 32, 32, 42, 42, 42, 18, 18, 18 }; static unsigned char const sfb_16000_mixed[] = { /* long */ 6, 6, 6, 6, 6, 6, /* short */ 6, 6, 6, 8, 8, 8, 10, 10, 10, 12, 12, 12, 14, 14, 14, 18, 18, 18, 24, 24, 24, 30, 30, 30, 40, 40, 40, 18, 18, 18 }; /* * MPEG 2.5 scalefactor band widths * derived from public sources */ # define sfb_12000_long sfb_16000_long # define sfb_11025_long sfb_12000_long static unsigned char const sfb_8000_long[] = { 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2 }; # define sfb_12000_short sfb_16000_short # define sfb_11025_short sfb_12000_short static unsigned char const sfb_8000_short[] = { 8, 8, 8, 8, 8, 8, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 }; # define sfb_12000_mixed sfb_16000_mixed # define sfb_11025_mixed sfb_12000_mixed /* the 8000 Hz short block scalefactor bands do not break after the first 36 frequency lines, so this is probably wrong */ static unsigned char const sfb_8000_mixed[] = { /* long */ 12, 12, 12, /* short */ 4, 4, 4, 8, 8, 8, 12, 12, 12, 16, 16, 16, 20, 20, 20, 24, 24, 24, 28, 28, 28, 36, 36, 36, 2, 2, 2, 2, 2, 2, 2, 2, 2, 26, 26, 26 }; static struct { unsigned char const *l; unsigned char const *s; unsigned char const *m; } const sfbwidth_table[9] = { { sfb_48000_long, sfb_48000_short, sfb_48000_mixed }, { sfb_44100_long, sfb_44100_short, sfb_44100_mixed }, { sfb_32000_long, sfb_32000_short, sfb_32000_mixed }, { sfb_24000_long, sfb_24000_short, sfb_24000_mixed }, { sfb_22050_long, sfb_22050_short, sfb_22050_mixed }, { sfb_16000_long, sfb_16000_short, sfb_16000_mixed }, { sfb_12000_long, sfb_12000_short, sfb_12000_mixed }, { sfb_11025_long, sfb_11025_short, sfb_11025_mixed }, { sfb_8000_long, sfb_8000_short, sfb_8000_mixed } }; /* * scalefactor band preemphasis (used only when preflag is set) * derived from Table B.6 of ISO/IEC 11172-3 */ static unsigned char const pretab[22] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 }; /* * table for requantization * * rq_table[x].mantissa * 2^(rq_table[x].exponent) = x^(4/3) */ static struct fixedfloat { unsigned long mantissa : 27; unsigned short exponent : 5; } const rq_table[8207] = { # include "rq_table.dat" }; /* * fractional powers of two * used for requantization and joint stereo decoding * * root_table[3 + x] = 2^(x/4) */ static mad_fixed_t const root_table[7] = { MAD_F(0x09837f05) /* 2^(-3/4) == 0.59460355750136 */, MAD_F(0x0b504f33) /* 2^(-2/4) == 0.70710678118655 */, MAD_F(0x0d744fcd) /* 2^(-1/4) == 0.84089641525371 */, MAD_F(0x10000000) /* 2^( 0/4) == 1.00000000000000 */, MAD_F(0x1306fe0a) /* 2^(+1/4) == 1.18920711500272 */, MAD_F(0x16a09e66) /* 2^(+2/4) == 1.41421356237310 */, MAD_F(0x1ae89f99) /* 2^(+3/4) == 1.68179283050743 */ }; /* * coefficients for aliasing reduction * derived from Table B.9 of ISO/IEC 11172-3 * * c[] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 } * cs[i] = 1 / sqrt(1 + c[i]^2) * ca[i] = c[i] / sqrt(1 + c[i]^2) */ static mad_fixed_t const cs[8] = { +MAD_F(0x0db84a81) /* +0.857492926 */, +MAD_F(0x0e1b9d7f) /* +0.881741997 */, +MAD_F(0x0f31adcf) /* +0.949628649 */, +MAD_F(0x0fbba815) /* +0.983314592 */, +MAD_F(0x0feda417) /* +0.995517816 */, +MAD_F(0x0ffc8fc8) /* +0.999160558 */, +MAD_F(0x0fff964c) /* +0.999899195 */, +MAD_F(0x0ffff8d3) /* +0.999993155 */ }; static mad_fixed_t const ca[8] = { -MAD_F(0x083b5fe7) /* -0.514495755 */, -MAD_F(0x078c36d2) /* -0.471731969 */, -MAD_F(0x05039814) /* -0.313377454 */, -MAD_F(0x02e91dd1) /* -0.181913200 */, -MAD_F(0x0183603a) /* -0.094574193 */, -MAD_F(0x00a7cb87) /* -0.040965583 */, -MAD_F(0x003a2847) /* -0.014198569 */, -MAD_F(0x000f27b4) /* -0.003699975 */ }; /* * IMDCT coefficients for short blocks * derived from section 2.4.3.4.10.2 of ISO/IEC 11172-3 * * imdct_s[i/even][k] = cos((PI / 24) * (2 * (i / 2) + 7) * (2 * k + 1)) * imdct_s[i /odd][k] = cos((PI / 24) * (2 * (6 + (i-1)/2) + 7) * (2 * k + 1)) */ static mad_fixed_t const imdct_s[6][6] = { # include "imdct_s.dat" }; # if !defined(ASO_IMDCT) /* * windowing coefficients for long blocks * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 * * window_l[i] = sin((PI / 36) * (i + 1/2)) */ static mad_fixed_t const window_l[36] = { MAD_F(0x00b2aa3e) /* 0.043619387 */, MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0ffc19fd) /* 0.999048222 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0f9ee890) /* 0.976296007 */, MAD_F(0x0f426cb5) /* 0.953716951 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0e313245) /* 0.887010833 */, MAD_F(0x0d7e8807) /* 0.843391446 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0bcbe352) /* 0.737277337 */, MAD_F(0x0acf37ad) /* 0.675590208 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0898c779) /* 0.537299608 */, MAD_F(0x07635284) /* 0.461748613 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x04cfb0e2) /* 0.300705800 */, MAD_F(0x03768962) /* 0.216439614 */, MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x00b2aa3e) /* 0.043619387 */, }; # endif /* ASO_IMDCT */ /* * windowing coefficients for short blocks * derived from section 2.4.3.4.10.3 of ISO/IEC 11172-3 * * window_s[i] = sin((PI / 12) * (i + 1/2)) */ static mad_fixed_t const window_s[12] = { MAD_F(0x0216a2a2) /* 0.130526192 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0cb19346) /* 0.793353340 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0216a2a2) /* 0.130526192 */, }; /* * coefficients for intensity stereo processing * derived from section 2.4.3.4.9.3 of ISO/IEC 11172-3 * * is_ratio[i] = tan(i * (PI / 12)) * is_table[i] = is_ratio[i] / (1 + is_ratio[i]) */ static mad_fixed_t const is_table[7] = { MAD_F(0x00000000) /* 0.000000000 */, MAD_F(0x0361962f) /* 0.211324865 */, MAD_F(0x05db3d74) /* 0.366025404 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x0a24c28c) /* 0.633974596 */, MAD_F(0x0c9e69d1) /* 0.788675135 */, MAD_F(0x10000000) /* 1.000000000 */ }; /* * coefficients for LSF intensity stereo processing * derived from section 2.4.3.2 of ISO/IEC 13818-3 * * is_lsf_table[0][i] = (1 / sqrt(sqrt(2)))^(i + 1) * is_lsf_table[1][i] = (1 / sqrt(2)) ^(i + 1) */ static mad_fixed_t const is_lsf_table[2][15] = { { MAD_F(0x0d744fcd) /* 0.840896415 */, MAD_F(0x0b504f33) /* 0.707106781 */, MAD_F(0x09837f05) /* 0.594603558 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x06ba27e6) /* 0.420448208 */, MAD_F(0x05a8279a) /* 0.353553391 */, MAD_F(0x04c1bf83) /* 0.297301779 */, MAD_F(0x04000000) /* 0.250000000 */, MAD_F(0x035d13f3) /* 0.210224104 */, MAD_F(0x02d413cd) /* 0.176776695 */, MAD_F(0x0260dfc1) /* 0.148650889 */, MAD_F(0x02000000) /* 0.125000000 */, MAD_F(0x01ae89fa) /* 0.105112052 */, MAD_F(0x016a09e6) /* 0.088388348 */, MAD_F(0x01306fe1) /* 0.074325445 */ }, { MAD_F(0x0b504f33) /* 0.707106781 */, MAD_F(0x08000000) /* 0.500000000 */, MAD_F(0x05a8279a) /* 0.353553391 */, MAD_F(0x04000000) /* 0.250000000 */, MAD_F(0x02d413cd) /* 0.176776695 */, MAD_F(0x02000000) /* 0.125000000 */, MAD_F(0x016a09e6) /* 0.088388348 */, MAD_F(0x01000000) /* 0.062500000 */, MAD_F(0x00b504f3) /* 0.044194174 */, MAD_F(0x00800000) /* 0.031250000 */, MAD_F(0x005a827a) /* 0.022097087 */, MAD_F(0x00400000) /* 0.015625000 */, MAD_F(0x002d413d) /* 0.011048543 */, MAD_F(0x00200000) /* 0.007812500 */, MAD_F(0x0016a09e) /* 0.005524272 */ } }; /* * NAME: III_sideinfo() * DESCRIPTION: decode frame side information from a bitstream */ static enum mad_error III_sideinfo(struct mad_bitptr *ptr, unsigned int nch, int lsf, struct sideinfo *si, unsigned int *data_bitlen, unsigned int *priv_bitlen) { unsigned int ngr, gr, ch, i; enum mad_error result = MAD_ERROR_NONE; *data_bitlen = 0; *priv_bitlen = lsf ? ((nch == 1) ? 1 : 2) : ((nch == 1) ? 5 : 3); si->main_data_begin = mad_bit_read(ptr, lsf ? 8 : 9); si->private_bits = mad_bit_read(ptr, *priv_bitlen); ngr = 1; if (!lsf) { ngr = 2; for (ch = 0; ch < nch; ++ch) si->scfsi[ch] = mad_bit_read(ptr, 4); } for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; channel->part2_3_length = mad_bit_read(ptr, 12); channel->big_values = mad_bit_read(ptr, 9); channel->global_gain = mad_bit_read(ptr, 8); channel->scalefac_compress = mad_bit_read(ptr, lsf ? 9 : 4); *data_bitlen += channel->part2_3_length; if (channel->big_values > 288 && result == 0) result = MAD_ERROR_BADBIGVALUES; channel->flags = 0; /* window_switching_flag */ if (mad_bit_read(ptr, 1)) { channel->block_type = mad_bit_read(ptr, 2); if (channel->block_type == 0 && result == 0) result = MAD_ERROR_BADBLOCKTYPE; if (!lsf && channel->block_type == 2 && si->scfsi[ch] && result == 0) result = MAD_ERROR_BADSCFSI; channel->region0_count = 7; channel->region1_count = 36; if (mad_bit_read(ptr, 1)) channel->flags |= mixed_block_flag; else if (channel->block_type == 2) channel->region0_count = 8; for (i = 0; i < 2; ++i) channel->table_select[i] = mad_bit_read(ptr, 5); # if defined(DEBUG) channel->table_select[2] = 4; /* not used */ # endif for (i = 0; i < 3; ++i) channel->subblock_gain[i] = mad_bit_read(ptr, 3); } else { channel->block_type = 0; for (i = 0; i < 3; ++i) channel->table_select[i] = mad_bit_read(ptr, 5); channel->region0_count = mad_bit_read(ptr, 4); channel->region1_count = mad_bit_read(ptr, 3); } /* [preflag,] scalefac_scale, count1table_select */ channel->flags |= mad_bit_read(ptr, lsf ? 2 : 3); } } return result; } /* * NAME: III_scalefactors_lsf() * DESCRIPTION: decode channel scalefactors for LSF from a bitstream */ static unsigned int III_scalefactors_lsf(struct mad_bitptr *ptr, struct channel *channel, struct channel *gr1ch, int mode_extension) { struct mad_bitptr start; unsigned int scalefac_compress, index, slen[4], part, n, i; unsigned char const *nsfb; start = *ptr; scalefac_compress = channel->scalefac_compress; index = (channel->block_type == 2) ? ((channel->flags & mixed_block_flag) ? 2 : 1) : 0; if (!((mode_extension & I_STEREO) && gr1ch)) { if (scalefac_compress < 400) { slen[0] = (scalefac_compress >> 4) / 5; slen[1] = (scalefac_compress >> 4) % 5; slen[2] = (scalefac_compress % 16) >> 2; slen[3] = scalefac_compress % 4; nsfb = nsfb_table[0][index]; } else if (scalefac_compress < 500) { scalefac_compress -= 400; slen[0] = (scalefac_compress >> 2) / 5; slen[1] = (scalefac_compress >> 2) % 5; slen[2] = scalefac_compress % 4; slen[3] = 0; nsfb = nsfb_table[1][index]; } else { scalefac_compress -= 500; slen[0] = scalefac_compress / 3; slen[1] = scalefac_compress % 3; slen[2] = 0; slen[3] = 0; channel->flags |= preflag; nsfb = nsfb_table[2][index]; } n = 0; for (part = 0; part < 4; ++part) { for (i = 0; i < nsfb[part]; ++i) channel->scalefac[n++] = mad_bit_read(ptr, slen[part]); } while (n < 39) channel->scalefac[n++] = 0; } else { /* (mode_extension & I_STEREO) && gr1ch (i.e. ch == 1) */ scalefac_compress >>= 1; if (scalefac_compress < 180) { slen[0] = scalefac_compress / 36; slen[1] = (scalefac_compress % 36) / 6; slen[2] = (scalefac_compress % 36) % 6; slen[3] = 0; nsfb = nsfb_table[3][index]; } else if (scalefac_compress < 244) { scalefac_compress -= 180; slen[0] = (scalefac_compress % 64) >> 4; slen[1] = (scalefac_compress % 16) >> 2; slen[2] = scalefac_compress % 4; slen[3] = 0; nsfb = nsfb_table[4][index]; } else { scalefac_compress -= 244; slen[0] = scalefac_compress / 3; slen[1] = scalefac_compress % 3; slen[2] = 0; slen[3] = 0; nsfb = nsfb_table[5][index]; } n = 0; for (part = 0; part < 4; ++part) { unsigned int max, is_pos; max = (1 << slen[part]) - 1; for (i = 0; i < nsfb[part]; ++i) { is_pos = mad_bit_read(ptr, slen[part]); channel->scalefac[n] = is_pos; gr1ch->scalefac[n++] = (is_pos == max); } } while (n < 39) { channel->scalefac[n] = 0; gr1ch->scalefac[n++] = 0; /* apparently not illegal */ } } return mad_bit_length(&start, ptr); } /* * NAME: III_scalefactors() * DESCRIPTION: decode channel scalefactors of one granule from a bitstream */ static unsigned int III_scalefactors(struct mad_bitptr *ptr, struct channel *channel, struct channel const *gr0ch, unsigned int scfsi) { struct mad_bitptr start; unsigned int slen1, slen2, sfbi; start = *ptr; slen1 = sflen_table[channel->scalefac_compress].slen1; slen2 = sflen_table[channel->scalefac_compress].slen2; if (channel->block_type == 2) { unsigned int nsfb; sfbi = 0; nsfb = (channel->flags & mixed_block_flag) ? 8 + 3 * 3 : 6 * 3; while (nsfb--) channel->scalefac[sfbi++] = mad_bit_read(ptr, slen1); nsfb = 6 * 3; while (nsfb--) channel->scalefac[sfbi++] = mad_bit_read(ptr, slen2); nsfb = 1 * 3; while (nsfb--) channel->scalefac[sfbi++] = 0; } else { /* channel->block_type != 2 */ if (scfsi & 0x8) { for (sfbi = 0; sfbi < 6; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 0; sfbi < 6; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); } if (scfsi & 0x4) { for (sfbi = 6; sfbi < 11; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 6; sfbi < 11; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen1); } if (scfsi & 0x2) { for (sfbi = 11; sfbi < 16; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 11; sfbi < 16; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); } if (scfsi & 0x1) { for (sfbi = 16; sfbi < 21; ++sfbi) channel->scalefac[sfbi] = gr0ch->scalefac[sfbi]; } else { for (sfbi = 16; sfbi < 21; ++sfbi) channel->scalefac[sfbi] = mad_bit_read(ptr, slen2); } channel->scalefac[21] = 0; } return mad_bit_length(&start, ptr); } /* * The Layer III formula for requantization and scaling is defined by * section 2.4.3.4.7.1 of ISO/IEC 11172-3, as follows: * * long blocks: * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * * 2^((1/4) * (global_gain - 210)) * * 2^-(scalefac_multiplier * * (scalefac_l[sfb] + preflag * pretab[sfb])) * * short blocks: * xr[i] = sign(is[i]) * abs(is[i])^(4/3) * * 2^((1/4) * (global_gain - 210 - 8 * subblock_gain[w])) * * 2^-(scalefac_multiplier * scalefac_s[sfb][w]) * * where: * scalefac_multiplier = (scalefac_scale + 1) / 2 * * The routines III_exponents() and III_requantize() facilitate this * calculation. */ /* * NAME: III_exponents() * DESCRIPTION: calculate scalefactor exponents */ static void III_exponents(struct channel const *channel, unsigned char const *sfbwidth, signed int exponents[39]) { signed int gain; unsigned int scalefac_multiplier, sfbi; gain = (signed int) channel->global_gain - 210; scalefac_multiplier = (channel->flags & scalefac_scale) ? 2 : 1; if (channel->block_type == 2) { unsigned int l; signed int gain0, gain1, gain2; sfbi = l = 0; if (channel->flags & mixed_block_flag) { unsigned int premask; premask = (channel->flags & preflag) ? ~0 : 0; /* long block subbands 0-1 */ while (l < 36) { exponents[sfbi] = gain - (signed int) ((channel->scalefac[sfbi] + (pretab[sfbi] & premask)) << scalefac_multiplier); l += sfbwidth[sfbi++]; } } /* this is probably wrong for 8000 Hz short/mixed blocks */ gain0 = gain - 8 * (signed int) channel->subblock_gain[0]; gain1 = gain - 8 * (signed int) channel->subblock_gain[1]; gain2 = gain - 8 * (signed int) channel->subblock_gain[2]; while (l < 576) { exponents[sfbi + 0] = gain0 - (signed int) (channel->scalefac[sfbi + 0] << scalefac_multiplier); exponents[sfbi + 1] = gain1 - (signed int) (channel->scalefac[sfbi + 1] << scalefac_multiplier); exponents[sfbi + 2] = gain2 - (signed int) (channel->scalefac[sfbi + 2] << scalefac_multiplier); l += 3 * sfbwidth[sfbi]; sfbi += 3; } } else { /* channel->block_type != 2 */ if (channel->flags & preflag) { for (sfbi = 0; sfbi < 22; ++sfbi) { exponents[sfbi] = gain - (signed int) ((channel->scalefac[sfbi] + pretab[sfbi]) << scalefac_multiplier); } } else { for (sfbi = 0; sfbi < 22; ++sfbi) { exponents[sfbi] = gain - (signed int) (channel->scalefac[sfbi] << scalefac_multiplier); } } } } /* * NAME: III_requantize() * DESCRIPTION: requantize one (positive) value */ static mad_fixed_t III_requantize(unsigned int value, signed int exp) { mad_fixed_t requantized; signed int frac; struct fixedfloat const *power; frac = exp % 4; /* assumes sign(frac) == sign(exp) */ exp /= 4; power = &rq_table[value]; requantized = power->mantissa; exp += power->exponent; if (exp < 0) { if (-exp >= (int)sizeof(mad_fixed_t) * CHAR_BIT) { /* underflow */ requantized = 0; } else { requantized += 1L << (-exp - 1); requantized >>= -exp; } } else { if (exp >= 5) { /* overflow */ # if defined(DEBUG) fprintf(stderr, "requantize overflow (%f * 2^%d)\n", mad_f_todouble(requantized), exp); # endif requantized = MAD_F_MAX; } else requantized <<= exp; } return frac ? mad_f_mul(requantized, root_table[3 + frac]) : requantized; } /* we must take care that sz >= bits and sz < sizeof(long) lest bits == 0 */ # define MASK(cache, sz, bits) \ (((cache) >> ((sz) - (bits))) & ((1 << (bits)) - 1)) # define MASK1BIT(cache, sz) \ ((cache) & (1 << ((sz) - 1))) /* * NAME: III_huffdecode() * DESCRIPTION: decode Huffman code words of one channel of one granule */ static enum mad_error III_huffdecode(struct mad_bitptr *ptr, mad_fixed_t xr[576], struct channel *channel, unsigned char const *sfbwidth, unsigned int part2_length) { signed int exponents[39], exp; signed int const *expptr; struct mad_bitptr peek; signed int bits_left, cachesz; register mad_fixed_t *xrptr; mad_fixed_t const *sfbound; register unsigned long bitcache; bits_left = (signed) channel->part2_3_length - (signed) part2_length; if (bits_left < 0) return MAD_ERROR_BADPART3LEN; III_exponents(channel, sfbwidth, exponents); peek = *ptr; mad_bit_skip(ptr, bits_left); /* align bit reads to byte boundaries */ cachesz = mad_bit_bitsleft(&peek); cachesz += ((32 - 1 - 24) + (24 - cachesz)) & ~7; bitcache = mad_bit_read(&peek, cachesz); bits_left -= cachesz; xrptr = &xr[0]; /* big_values */ { unsigned int region, rcount; struct hufftable const *entry; union huffpair const *table; unsigned int linbits, startbits, big_values, reqhits; mad_fixed_t reqcache[16]; sfbound = xrptr + *sfbwidth++; rcount = channel->region0_count + 1; entry = &mad_huff_pair_table[channel->table_select[region = 0]]; table = entry->table; linbits = entry->linbits; startbits = entry->startbits; if (table == 0) return MAD_ERROR_BADHUFFTABLE; expptr = &exponents[0]; exp = *expptr++; reqhits = 0; big_values = channel->big_values; while (big_values-- && cachesz + bits_left > 0) { union huffpair const *pair; unsigned int clumpsz, value; register mad_fixed_t requantized; if (xrptr == sfbound) { sfbound += *sfbwidth++; /* change table if region boundary */ if (--rcount == 0) { if (region == 0) rcount = channel->region1_count + 1; else rcount = 0; /* all remaining */ entry = &mad_huff_pair_table[channel->table_select[++region]]; table = entry->table; linbits = entry->linbits; startbits = entry->startbits; if (table == 0) return MAD_ERROR_BADHUFFTABLE; } if (exp != *expptr) { exp = *expptr; reqhits = 0; } ++expptr; } if (cachesz < 21) { unsigned int bits; bits = ((32 - 1 - 21) + (21 - cachesz)) & ~7; bitcache = (bitcache << bits) | mad_bit_read(&peek, bits); cachesz += bits; bits_left -= bits; } /* hcod (0..19) */ clumpsz = startbits; pair = &table[MASK(bitcache, cachesz, clumpsz)]; while (!pair->final) { cachesz -= clumpsz; clumpsz = pair->ptr.bits; pair = &table[pair->ptr.offset + MASK(bitcache, cachesz, clumpsz)]; } cachesz -= pair->value.hlen; if (linbits) { /* x (0..14) */ value = pair->value.x; switch (value) { case 0: xrptr[0] = 0; break; case 15: if (cachesz < (int)linbits + 2) { bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); cachesz += 16; bits_left -= 16; } value += MASK(bitcache, cachesz, linbits); cachesz -= linbits; requantized = III_requantize(value, exp); goto x_final; default: if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } x_final: xrptr[0] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } /* y (0..14) */ value = pair->value.y; switch (value) { case 0: xrptr[1] = 0; break; case 15: if (cachesz < (int)linbits + 1) { bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); cachesz += 16; bits_left -= 16; } value += MASK(bitcache, cachesz, linbits); cachesz -= linbits; requantized = III_requantize(value, exp); goto y_final; default: if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } y_final: xrptr[1] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } } else { /* x (0..1) */ value = pair->value.x; if (value == 0) xrptr[0] = 0; else { if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } xrptr[0] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } /* y (0..1) */ value = pair->value.y; if (value == 0) xrptr[1] = 0; else { if (reqhits & (1 << value)) requantized = reqcache[value]; else { reqhits |= (1 << value); requantized = reqcache[value] = III_requantize(value, exp); } xrptr[1] = MASK1BIT(bitcache, cachesz--) ? -requantized : requantized; } } xrptr += 2; } } if (cachesz + bits_left < 0) return MAD_ERROR_BADHUFFDATA; /* big_values overrun */ /* count1 */ { union huffquad const *table; register mad_fixed_t requantized; table = mad_huff_quad_table[channel->flags & count1table_select]; requantized = III_requantize(1, exp); while (cachesz + bits_left > 0 && xrptr <= &xr[572]) { union huffquad const *quad; /* hcod (1..6) */ if (cachesz < 10) { bitcache = (bitcache << 16) | mad_bit_read(&peek, 16); cachesz += 16; bits_left -= 16; } quad = &table[MASK(bitcache, cachesz, 4)]; /* quad tables guaranteed to have at most one extra lookup */ if (!quad->final) { cachesz -= 4; quad = &table[quad->ptr.offset + MASK(bitcache, cachesz, quad->ptr.bits)]; } cachesz -= quad->value.hlen; if (xrptr == sfbound) { sfbound += *sfbwidth++; if (exp != *expptr) { exp = *expptr; requantized = III_requantize(1, exp); } ++expptr; } /* v (0..1) */ xrptr[0] = quad->value.v ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; /* w (0..1) */ xrptr[1] = quad->value.w ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; xrptr += 2; if (xrptr == sfbound) { sfbound += *sfbwidth++; if (exp != *expptr) { exp = *expptr; requantized = III_requantize(1, exp); } ++expptr; } /* x (0..1) */ xrptr[0] = quad->value.x ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; /* y (0..1) */ xrptr[1] = quad->value.y ? (MASK1BIT(bitcache, cachesz--) ? -requantized : requantized) : 0; xrptr += 2; } if (cachesz + bits_left < 0) { # if 0 && defined(DEBUG) fprintf(stderr, "huffman count1 overrun (%d bits)\n", -(cachesz + bits_left)); # endif /* technically the bitstream is misformatted, but apparently some encoders are just a bit sloppy with stuffing bits */ xrptr -= 4; } } assert(-bits_left <= MAD_BUFFER_GUARD * CHAR_BIT); # if 0 && defined(DEBUG) if (bits_left < 0) fprintf(stderr, "read %d bits too many\n", -bits_left); else if (cachesz + bits_left > 0) fprintf(stderr, "%d stuffing bits\n", cachesz + bits_left); # endif /* rzero */ while (xrptr < &xr[576]) { xrptr[0] = 0; xrptr[1] = 0; xrptr += 2; } return MAD_ERROR_NONE; } # undef MASK # undef MASK1BIT /* * NAME: III_reorder() * DESCRIPTION: reorder frequency lines of a short block into subband order */ static void III_reorder(mad_fixed_t xr[576], struct channel const *channel, unsigned char const sfbwidth[39]) { mad_fixed_t tmp[32][3][6]; unsigned int sb, l, f, w, sbw[3], sw[3]; /* this is probably wrong for 8000 Hz mixed blocks */ sb = 0; if (channel->flags & mixed_block_flag) { sb = 2; l = 0; while (l < 36) l += *sfbwidth++; } for (w = 0; w < 3; ++w) { sbw[w] = sb; sw[w] = 0; } f = *sfbwidth++; w = 0; for (l = 18 * sb; l < 576; ++l) { if (f-- == 0) { f = *sfbwidth++ - 1; w = (w + 1) % 3; } tmp[sbw[w]][w][sw[w]++] = xr[l]; if (sw[w] == 6) { sw[w] = 0; ++sbw[w]; } } memcpy(&xr[18 * sb], &tmp[sb], (576 - 18 * sb) * sizeof(mad_fixed_t)); } /* * NAME: III_stereo() * DESCRIPTION: perform joint stereo processing on a granule */ static enum mad_error III_stereo(mad_fixed_t xr[2][576], struct granule const *granule, struct mad_header *header, unsigned char const *sfbwidth) { short modes[39]; unsigned int sfbi, l, n, i; if (granule->ch[0].block_type != granule->ch[1].block_type || (granule->ch[0].flags & mixed_block_flag) != (granule->ch[1].flags & mixed_block_flag)) return MAD_ERROR_BADSTEREO; for (i = 0; i < 39; ++i) modes[i] = header->mode_extension; /* intensity stereo */ if (header->mode_extension & I_STEREO) { struct channel const *right_ch = &granule->ch[1]; mad_fixed_t const *right_xr = xr[1]; unsigned int is_pos; header->flags |= MAD_FLAG_I_STEREO; /* first determine which scalefactor bands are to be processed */ if (right_ch->block_type == 2) { unsigned int lower, start, max, bound[3], w; lower = start = max = bound[0] = bound[1] = bound[2] = 0; sfbi = l = 0; if (right_ch->flags & mixed_block_flag) { while (l < 36) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { lower = sfbi; break; } } right_xr += n; l += n; } start = sfbi; } w = 0; while (l < 576) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { max = bound[w] = sfbi; break; } } right_xr += n; l += n; w = (w + 1) % 3; } if (max) lower = start; /* long blocks */ for (i = 0; i < lower; ++i) modes[i] = header->mode_extension & ~I_STEREO; /* short blocks */ w = 0; for (i = start; i < max; ++i) { if (i < bound[w]) modes[i] = header->mode_extension & ~I_STEREO; w = (w + 1) % 3; } } else { /* right_ch->block_type != 2 */ unsigned int bound; bound = 0; for (sfbi = l = 0; l < 576; l += n) { n = sfbwidth[sfbi++]; for (i = 0; i < n; ++i) { if (right_xr[i]) { bound = sfbi; break; } } right_xr += n; } for (i = 0; i < bound; ++i) modes[i] = header->mode_extension & ~I_STEREO; } /* now do the actual processing */ if (header->flags & MAD_FLAG_LSF_EXT) { unsigned char const *illegal_pos = granule[1].ch[1].scalefac; mad_fixed_t const *lsf_scale; /* intensity_scale */ lsf_scale = is_lsf_table[right_ch->scalefac_compress & 0x1]; for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; if (!(modes[sfbi] & I_STEREO)) continue; if (illegal_pos[sfbi]) { modes[sfbi] &= ~I_STEREO; continue; } is_pos = right_ch->scalefac[sfbi]; for (i = 0; i < n; ++i) { register mad_fixed_t left; left = xr[0][l + i]; if (is_pos == 0) xr[1][l + i] = left; else { register mad_fixed_t opposite; opposite = mad_f_mul(left, lsf_scale[(is_pos - 1) / 2]); if (is_pos & 1) { xr[0][l + i] = opposite; xr[1][l + i] = left; } else xr[1][l + i] = opposite; } } } } else { /* !(header->flags & MAD_FLAG_LSF_EXT) */ for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; if (!(modes[sfbi] & I_STEREO)) continue; is_pos = right_ch->scalefac[sfbi]; if (is_pos >= 7) { /* illegal intensity position */ modes[sfbi] &= ~I_STEREO; continue; } for (i = 0; i < n; ++i) { register mad_fixed_t left; left = xr[0][l + i]; xr[0][l + i] = mad_f_mul(left, is_table[ is_pos]); xr[1][l + i] = mad_f_mul(left, is_table[6 - is_pos]); } } } } /* middle/side stereo */ if (header->mode_extension & MS_STEREO) { register mad_fixed_t invsqrt2; header->flags |= MAD_FLAG_MS_STEREO; invsqrt2 = root_table[3 + -2]; for (sfbi = l = 0; l < 576; ++sfbi, l += n) { n = sfbwidth[sfbi]; if (modes[sfbi] != MS_STEREO) continue; for (i = 0; i < n; ++i) { register mad_fixed_t m, s; m = xr[0][l + i]; s = xr[1][l + i]; xr[0][l + i] = mad_f_mul(m + s, invsqrt2); /* l = (m + s) / sqrt(2) */ xr[1][l + i] = mad_f_mul(m - s, invsqrt2); /* r = (m - s) / sqrt(2) */ } } } return MAD_ERROR_NONE; } /* * NAME: III_aliasreduce() * DESCRIPTION: perform frequency line alias reduction */ static void III_aliasreduce(mad_fixed_t xr[576], int lines) { mad_fixed_t const *bound; int i; bound = &xr[lines]; for (xr += 18; xr < bound; xr += 18) { for (i = 0; i < 8; ++i) { register mad_fixed_t a, b; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; a = xr[-1 - i]; b = xr[ i]; # if defined(ASO_ZEROCHECK) if (a | b) # endif { MAD_F_ML0(hi, lo, a, cs[i]); MAD_F_MLA(hi, lo, -b, ca[i]); xr[-1 - i] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, b, cs[i]); MAD_F_MLA(hi, lo, a, ca[i]); xr[ i] = MAD_F_MLZ(hi, lo); } } } } # if defined(ASO_IMDCT) void III_imdct_l(mad_fixed_t const [18], mad_fixed_t [36], unsigned int); # else # if 1 static void fastsdct(mad_fixed_t const x[9], mad_fixed_t y[18]) { mad_fixed_t a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12; mad_fixed_t a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25; mad_fixed_t m0, m1, m2, m3, m4, m5, m6, m7; enum { c0 = MAD_F(0x1f838b8d), /* 2 * cos( 1 * PI / 18) */ c1 = MAD_F(0x1bb67ae8), /* 2 * cos( 3 * PI / 18) */ c2 = MAD_F(0x18836fa3), /* 2 * cos( 4 * PI / 18) */ c3 = MAD_F(0x1491b752), /* 2 * cos( 5 * PI / 18) */ c4 = MAD_F(0x0af1d43a), /* 2 * cos( 7 * PI / 18) */ c5 = MAD_F(0x058e86a0), /* 2 * cos( 8 * PI / 18) */ c6 = -MAD_F(0x1e11f642) /* 2 * cos(16 * PI / 18) */ }; a0 = x[3] + x[5]; a1 = x[3] - x[5]; a2 = x[6] + x[2]; a3 = x[6] - x[2]; a4 = x[1] + x[7]; a5 = x[1] - x[7]; a6 = x[8] + x[0]; a7 = x[8] - x[0]; a8 = a0 + a2; a9 = a0 - a2; a10 = a0 - a6; a11 = a2 - a6; a12 = a8 + a6; a13 = a1 - a3; a14 = a13 + a7; a15 = a3 + a7; a16 = a1 - a7; a17 = a1 + a3; m0 = mad_f_mul(a17, -c3); m1 = mad_f_mul(a16, -c0); m2 = mad_f_mul(a15, -c4); m3 = mad_f_mul(a14, -c1); m4 = mad_f_mul(a5, -c1); m5 = mad_f_mul(a11, -c6); m6 = mad_f_mul(a10, -c5); m7 = mad_f_mul(a9, -c2); a18 = x[4] + a4; a19 = 2 * x[4] - a4; a20 = a19 + m5; a21 = a19 - m5; a22 = a19 + m6; a23 = m4 + m2; a24 = m4 - m2; a25 = m4 + m1; /* output to every other slot for convenience */ y[ 0] = a18 + a12; y[ 2] = m0 - a25; y[ 4] = m7 - a20; y[ 6] = m3; y[ 8] = a21 - m6; y[10] = a24 - m1; y[12] = a12 - 2 * a18; y[14] = a23 + m0; y[16] = a22 + m7; } static inline void sdctII(mad_fixed_t const x[18], mad_fixed_t X[18]) { mad_fixed_t tmp[9]; int i; /* scale[i] = 2 * cos(PI * (2 * i + 1) / (2 * 18)) */ static mad_fixed_t const scale[9] = { MAD_F(0x1fe0d3b4), MAD_F(0x1ee8dd47), MAD_F(0x1d007930), MAD_F(0x1a367e59), MAD_F(0x16a09e66), MAD_F(0x125abcf8), MAD_F(0x0d8616bc), MAD_F(0x08483ee1), MAD_F(0x02c9fad7) }; /* divide the 18-point SDCT-II into two 9-point SDCT-IIs */ /* even input butterfly */ for (i = 0; i < 9; i += 3) { tmp[i + 0] = x[i + 0] + x[18 - (i + 0) - 1]; tmp[i + 1] = x[i + 1] + x[18 - (i + 1) - 1]; tmp[i + 2] = x[i + 2] + x[18 - (i + 2) - 1]; } fastsdct(tmp, &X[0]); /* odd input butterfly and scaling */ for (i = 0; i < 9; i += 3) { tmp[i + 0] = mad_f_mul(x[i + 0] - x[18 - (i + 0) - 1], scale[i + 0]); tmp[i + 1] = mad_f_mul(x[i + 1] - x[18 - (i + 1) - 1], scale[i + 1]); tmp[i + 2] = mad_f_mul(x[i + 2] - x[18 - (i + 2) - 1], scale[i + 2]); } fastsdct(tmp, &X[1]); /* output accumulation */ for (i = 3; i < 18; i += 8) { X[i + 0] -= X[(i + 0) - 2]; X[i + 2] -= X[(i + 2) - 2]; X[i + 4] -= X[(i + 4) - 2]; X[i + 6] -= X[(i + 6) - 2]; } } static inline void dctIV(mad_fixed_t const y[18], mad_fixed_t X[18]) { mad_fixed_t tmp[18]; int i; /* scale[i] = 2 * cos(PI * (2 * i + 1) / (4 * 18)) */ static mad_fixed_t const scale[18] = { MAD_F(0x1ff833fa), MAD_F(0x1fb9ea93), MAD_F(0x1f3dd120), MAD_F(0x1e84d969), MAD_F(0x1d906bcf), MAD_F(0x1c62648b), MAD_F(0x1afd100f), MAD_F(0x1963268b), MAD_F(0x1797c6a4), MAD_F(0x159e6f5b), MAD_F(0x137af940), MAD_F(0x11318ef3), MAD_F(0x0ec6a507), MAD_F(0x0c3ef153), MAD_F(0x099f61c5), MAD_F(0x06ed12c5), MAD_F(0x042d4544), MAD_F(0x0165547c) }; /* scaling */ for (i = 0; i < 18; i += 3) { tmp[i + 0] = mad_f_mul(y[i + 0], scale[i + 0]); tmp[i + 1] = mad_f_mul(y[i + 1], scale[i + 1]); tmp[i + 2] = mad_f_mul(y[i + 2], scale[i + 2]); } /* SDCT-II */ sdctII(tmp, X); /* scale reduction and output accumulation */ X[0] /= 2; for (i = 1; i < 17; i += 4) { X[i + 0] = X[i + 0] / 2 - X[(i + 0) - 1]; X[i + 1] = X[i + 1] / 2 - X[(i + 1) - 1]; X[i + 2] = X[i + 2] / 2 - X[(i + 2) - 1]; X[i + 3] = X[i + 3] / 2 - X[(i + 3) - 1]; } X[17] = X[17] / 2 - X[16]; } /* * NAME: imdct36 * DESCRIPTION: perform X[18]->x[36] IMDCT using Szu-Wei Lee's fast algorithm */ static inline void imdct36(mad_fixed_t const x[18], mad_fixed_t y[36]) { mad_fixed_t tmp[18]; int i; /* DCT-IV */ dctIV(x, tmp); /* convert 18-point DCT-IV to 36-point IMDCT */ for (i = 0; i < 9; i += 3) { y[i + 0] = tmp[9 + (i + 0)]; y[i + 1] = tmp[9 + (i + 1)]; y[i + 2] = tmp[9 + (i + 2)]; } for (i = 9; i < 27; i += 3) { y[i + 0] = -tmp[36 - (9 + (i + 0)) - 1]; y[i + 1] = -tmp[36 - (9 + (i + 1)) - 1]; y[i + 2] = -tmp[36 - (9 + (i + 2)) - 1]; } for (i = 27; i < 36; i += 3) { y[i + 0] = -tmp[(i + 0) - 27]; y[i + 1] = -tmp[(i + 1) - 27]; y[i + 2] = -tmp[(i + 2) - 27]; } } # else /* * NAME: imdct36 * DESCRIPTION: perform X[18]->x[36] IMDCT */ static inline void imdct36(mad_fixed_t const X[18], mad_fixed_t x[36]) { mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; MAD_F_ML0(hi, lo, X[4], MAD_F(0x0ec835e8)); MAD_F_MLA(hi, lo, X[13], MAD_F(0x061f78aa)); t6 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, (t14 = X[1] - X[10]), -MAD_F(0x061f78aa)); MAD_F_MLA(hi, lo, (t15 = X[7] + X[16]), -MAD_F(0x0ec835e8)); t0 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, (t8 = X[0] - X[11] - X[12]), MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, (t9 = X[2] - X[9] - X[14]), MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, (t10 = X[3] - X[8] - X[15]), -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, (t11 = X[5] - X[6] - X[17]), -MAD_F(0x0fdcf549)); x[7] = MAD_F_MLZ(hi, lo); x[10] = -x[7]; MAD_F_ML0(hi, lo, t8, -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, t9, MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, t10, MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, t11, -MAD_F(0x09bd7ca0)); x[19] = x[34] = MAD_F_MLZ(hi, lo) - t0; t12 = X[0] - X[3] + X[8] - X[11] - X[12] + X[15]; t13 = X[2] + X[5] - X[6] - X[9] - X[14] - X[17]; MAD_F_ML0(hi, lo, t12, -MAD_F(0x0ec835e8)); MAD_F_MLA(hi, lo, t13, MAD_F(0x061f78aa)); x[22] = x[31] = MAD_F_MLZ(hi, lo) + t0; MAD_F_ML0(hi, lo, X[1], -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, X[7], MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, X[10], -MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, X[16], MAD_F(0x0cb19346)); t1 = MAD_F_MLZ(hi, lo) + t6; MAD_F_ML0(hi, lo, X[0], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0f9ee890)); x[6] = MAD_F_MLZ(hi, lo) + t1; x[11] = -x[6]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x04cfb0e2)); x[23] = x[30] = MAD_F_MLZ(hi, lo) + t1; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0acf37ad)); x[18] = x[35] = MAD_F_MLZ(hi, lo) - t1; MAD_F_ML0(hi, lo, X[4], MAD_F(0x061f78aa)); MAD_F_MLA(hi, lo, X[13], -MAD_F(0x0ec835e8)); t7 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, X[1], -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, X[7], MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, X[10], MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, X[16], -MAD_F(0x09bd7ca0)); t2 = MAD_F_MLZ(hi, lo); MAD_F_MLA(hi, lo, X[0], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x0f426cb5)); x[5] = MAD_F_MLZ(hi, lo); x[12] = -x[5]; MAD_F_ML0(hi, lo, X[0], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0bcbe352)); x[0] = MAD_F_MLZ(hi, lo) + t2; x[17] = -x[0]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x03768962)); x[24] = x[29] = MAD_F_MLZ(hi, lo) + t2; MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, X[7], -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, X[10], MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, X[16], MAD_F(0x0fdcf549)); t3 = MAD_F_MLZ(hi, lo) + t7; MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd)); x[8] = MAD_F_MLZ(hi, lo) + t3; x[9] = -x[8]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284)); x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779)); x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3; MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8)); MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa)); t4 = MAD_F_MLZ(hi, lo) - t7; MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa)); MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8)); x[4] = MAD_F_MLZ(hi, lo) + t4; x[13] = -x[4]; MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2)); MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346)); x[1] = MAD_F_MLZ(hi, lo) + t4; x[16] = -x[1]; MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2)); x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4; MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549)); MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346)); MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0)); MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2)); t5 = MAD_F_MLZ(hi, lo) - t6; MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807)); x[2] = MAD_F_MLZ(hi, lo) + t5; x[15] = -x[2]; MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e)); MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245)); x[3] = MAD_F_MLZ(hi, lo) + t5; x[14] = -x[3]; MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd)); MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890)); MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5)); MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245)); MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807)); MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352)); MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad)); MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779)); MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284)); MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2)); MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962)); MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e)); x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5; } # endif /* * NAME: III_imdct_l() * DESCRIPTION: perform IMDCT and windowing for long blocks */ static void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36], unsigned int block_type) { unsigned int i; /* IMDCT */ imdct36(X, z); /* windowing */ switch (block_type) { case 0: /* normal window */ # if defined(ASO_INTERLEAVE1) { register mad_fixed_t tmp1, tmp2; tmp1 = window_l[0]; tmp2 = window_l[1]; for (i = 0; i < 34; i += 2) { z[i + 0] = mad_f_mul(z[i + 0], tmp1); tmp1 = window_l[i + 2]; z[i + 1] = mad_f_mul(z[i + 1], tmp2); tmp2 = window_l[i + 3]; } z[34] = mad_f_mul(z[34], tmp1); z[35] = mad_f_mul(z[35], tmp2); } # elif defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = z[0]; tmp2 = window_l[0]; for (i = 0; i < 35; ++i) { z[i] = mad_f_mul(tmp1, tmp2); tmp1 = z[i + 1]; tmp2 = window_l[i + 1]; } z[35] = mad_f_mul(tmp1, tmp2); } # elif 1 for (i = 0; i < 36; i += 4) { z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]); z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]); z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]); z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]); } # else for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]); # endif break; case 1: /* start block */ for (i = 0; i < 18; i += 3) { z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]); z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]); z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]); } /* (i = 18; i < 24; ++i) z[i] unchanged */ for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]); for (i = 30; i < 36; ++i) z[i] = 0; break; case 3: /* stop block */ for (i = 0; i < 6; ++i) z[i] = 0; for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]); /* (i = 12; i < 18; ++i) z[i] unchanged */ for (i = 18; i < 36; i += 3) { z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]); z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]); z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]); } break; } } # endif /* ASO_IMDCT */ /* * NAME: III_imdct_s() * DESCRIPTION: perform IMDCT and windowing for short blocks */ static void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36]) { mad_fixed_t y[36], *yptr; mad_fixed_t const *wptr; int w, i; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; /* IMDCT */ yptr = &y[0]; for (w = 0; w < 3; ++w) { register mad_fixed_t const (*s)[6]; s = imdct_s; for (i = 0; i < 3; ++i) { MAD_F_ML0(hi, lo, X[0], (*s)[0]); MAD_F_MLA(hi, lo, X[1], (*s)[1]); MAD_F_MLA(hi, lo, X[2], (*s)[2]); MAD_F_MLA(hi, lo, X[3], (*s)[3]); MAD_F_MLA(hi, lo, X[4], (*s)[4]); MAD_F_MLA(hi, lo, X[5], (*s)[5]); yptr[i + 0] = MAD_F_MLZ(hi, lo); yptr[5 - i] = -yptr[i + 0]; ++s; MAD_F_ML0(hi, lo, X[0], (*s)[0]); MAD_F_MLA(hi, lo, X[1], (*s)[1]); MAD_F_MLA(hi, lo, X[2], (*s)[2]); MAD_F_MLA(hi, lo, X[3], (*s)[3]); MAD_F_MLA(hi, lo, X[4], (*s)[4]); MAD_F_MLA(hi, lo, X[5], (*s)[5]); yptr[ i + 6] = MAD_F_MLZ(hi, lo); yptr[11 - i] = yptr[i + 6]; ++s; } yptr += 12; X += 6; } /* windowing, overlapping and concatenation */ yptr = &y[0]; wptr = &window_s[0]; for (i = 0; i < 6; ++i) { z[i + 0] = 0; z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]); MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]); MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]); z[i + 12] = MAD_F_MLZ(hi, lo); MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]); MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]); z[i + 18] = MAD_F_MLZ(hi, lo); z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]); z[i + 30] = 0; ++yptr; ++wptr; } } /* * NAME: III_overlap() * DESCRIPTION: perform overlap-add of windowed IMDCT outputs */ static void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18], mad_fixed_t sample[18][32], unsigned int sb) { unsigned int i; # if defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = overlap[0]; tmp2 = overlap[1]; for (i = 0; i < 16; i += 2) { sample[i + 0][sb] = output[i + 0 + 0] + tmp1; overlap[i + 0] = output[i + 0 + 18]; tmp1 = overlap[i + 2]; sample[i + 1][sb] = output[i + 1 + 0] + tmp2; overlap[i + 1] = output[i + 1 + 18]; tmp2 = overlap[i + 3]; } sample[16][sb] = output[16 + 0] + tmp1; overlap[16] = output[16 + 18]; sample[17][sb] = output[17 + 0] + tmp2; overlap[17] = output[17 + 18]; } # elif 0 for (i = 0; i < 18; i += 2) { sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0]; overlap[i + 0] = output[i + 0 + 18]; sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1]; overlap[i + 1] = output[i + 1 + 18]; } # else for (i = 0; i < 18; ++i) { sample[i][sb] = output[i + 0] + overlap[i]; overlap[i] = output[i + 18]; } # endif } /* * NAME: III_overlap_z() * DESCRIPTION: perform "overlap-add" of zero IMDCT outputs */ static inline void III_overlap_z(mad_fixed_t overlap[18], mad_fixed_t sample[18][32], unsigned int sb) { unsigned int i; # if defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = overlap[0]; tmp2 = overlap[1]; for (i = 0; i < 16; i += 2) { sample[i + 0][sb] = tmp1; overlap[i + 0] = 0; tmp1 = overlap[i + 2]; sample[i + 1][sb] = tmp2; overlap[i + 1] = 0; tmp2 = overlap[i + 3]; } sample[16][sb] = tmp1; overlap[16] = 0; sample[17][sb] = tmp2; overlap[17] = 0; } # else for (i = 0; i < 18; ++i) { sample[i][sb] = overlap[i]; overlap[i] = 0; } # endif } /* * NAME: III_freqinver() * DESCRIPTION: perform subband frequency inversion for odd sample lines */ static void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb) { unsigned int i; # if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2) { register mad_fixed_t tmp1, tmp2; tmp1 = sample[1][sb]; tmp2 = sample[3][sb]; for (i = 1; i < 13; i += 4) { sample[i + 0][sb] = -tmp1; tmp1 = sample[i + 4][sb]; sample[i + 2][sb] = -tmp2; tmp2 = sample[i + 6][sb]; } sample[13][sb] = -tmp1; tmp1 = sample[17][sb]; sample[15][sb] = -tmp2; sample[17][sb] = -tmp1; } # else for (i = 1; i < 18; i += 2) sample[i][sb] = -sample[i][sb]; # endif } /* * NAME: III_decode() * DESCRIPTION: decode frame main_data */ static enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame, struct sideinfo *si, unsigned int nch) { struct mad_header *header = &frame->header; unsigned int sfreqi, ngr, gr; { unsigned int sfreq; sfreq = header->samplerate; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreq *= 2; /* 48000 => 0, 44100 => 1, 32000 => 2, 24000 => 3, 22050 => 4, 16000 => 5 */ sfreqi = ((sfreq >> 7) & 0x000f) + ((sfreq >> 15) & 0x0001) - 8; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) sfreqi += 3; } /* scalefactors, Huffman decoding, requantization */ ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2; for (gr = 0; gr < ngr; ++gr) { struct granule *granule = &si->gr[gr]; unsigned char const *sfbwidth[2]; mad_fixed_t xr[2][576]; unsigned int ch; enum mad_error error; for (ch = 0; ch < nch; ++ch) { struct channel *channel = &granule->ch[ch]; unsigned int part2_length; sfbwidth[ch] = sfbwidth_table[sfreqi].l; if (channel->block_type == 2) { sfbwidth[ch] = (channel->flags & mixed_block_flag) ? sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s; } if (header->flags & MAD_FLAG_LSF_EXT) { part2_length = III_scalefactors_lsf(ptr, channel, ch == 0 ? 0 : &si->gr[1].ch[1], header->mode_extension); } else { part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch], gr == 0 ? 0 : si->scfsi[ch]); } error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length); if (error) return error; } /* joint stereo processing */ if (header->mode == MAD_MODE_JOINT_STEREO && header->mode_extension) { error = III_stereo(xr, granule, header, sfbwidth[0]); if (error) return error; } /* reordering, alias reduction, IMDCT, overlap-add, frequency inversion */ for (ch = 0; ch < nch; ++ch) { struct channel const *channel = &granule->ch[ch]; mad_fixed_t (*sample)[32] = &frame->sbsample[ch][18 * gr]; unsigned int sb, l, i, sblimit; mad_fixed_t output[36]; if (channel->block_type == 2) { III_reorder(xr[ch], channel, sfbwidth[ch]); # if !defined(OPT_STRICT) /* * According to ISO/IEC 11172-3, "Alias reduction is not applied for * granules with block_type == 2 (short block)." However, other * sources suggest alias reduction should indeed be performed on the * lower two subbands of mixed blocks. Most other implementations do * this, so by default we will too. */ if (channel->flags & mixed_block_flag) III_aliasreduce(xr[ch], 36); # endif } else III_aliasreduce(xr[ch], 576); l = 0; /* subbands 0-1 */ if (channel->block_type != 2 || (channel->flags & mixed_block_flag)) { unsigned int block_type; block_type = channel->block_type; if (channel->flags & mixed_block_flag) block_type = 0; /* long blocks */ for (sb = 0; sb < 2; ++sb, l += 18) { III_imdct_l(&xr[ch][l], output, block_type); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); } } else { /* short blocks */ for (sb = 0; sb < 2; ++sb, l += 18) { III_imdct_s(&xr[ch][l], output); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); } } III_freqinver(sample, 1); /* (nonzero) subbands 2-31 */ i = 576; while (i > 36 && xr[ch][i - 1] == 0) --i; sblimit = 32 - (576 - i) / 18; if (channel->block_type != 2) { /* long blocks */ for (sb = 2; sb < sblimit; ++sb, l += 18) { III_imdct_l(&xr[ch][l], output, channel->block_type); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } else { /* short blocks */ for (sb = 2; sb < sblimit; ++sb, l += 18) { III_imdct_s(&xr[ch][l], output); III_overlap(output, (*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } /* remaining (zero) subbands */ for (sb = sblimit; sb < 32; ++sb) { III_overlap_z((*frame->overlap)[ch][sb], sample, sb); if (sb & 1) III_freqinver(sample, sb); } } } return MAD_ERROR_NONE; } /* * NAME: layer->III() * DESCRIPTION: decode a single Layer III frame */ int mad_layer_III(struct mad_stream *stream, struct mad_frame *frame) { struct mad_header *header = &frame->header; unsigned int nch, priv_bitlen, next_md_begin = 0; unsigned int si_len, data_bitlen, md_len; unsigned int frame_space, frame_used, frame_free; struct mad_bitptr ptr; struct sideinfo si; enum mad_error error; int result = 0; /* allocate Layer III dynamic structures */ if (stream->main_data == 0) { stream->main_data = malloc(MAD_BUFFER_MDLEN); if (stream->main_data == 0) { stream->error = MAD_ERROR_NOMEM; return -1; } } if (frame->overlap == 0) { frame->overlap = calloc(2 * 32 * 18, sizeof(mad_fixed_t)); if (frame->overlap == 0) { stream->error = MAD_ERROR_NOMEM; return -1; } } nch = MAD_NCHANNELS(header); si_len = (header->flags & MAD_FLAG_LSF_EXT) ? (nch == 1 ? 9 : 17) : (nch == 1 ? 17 : 32); /* check frame sanity */ if (stream->next_frame - mad_bit_nextbyte(&stream->ptr) < (signed int) si_len) { stream->error = MAD_ERROR_BADFRAMELEN; stream->md_len = 0; return -1; } /* check CRC word */ if (header->flags & MAD_FLAG_PROTECTION) { header->crc_check = mad_bit_crc(stream->ptr, si_len * CHAR_BIT, header->crc_check); if (header->crc_check != header->crc_target && !(frame->options & MAD_OPTION_IGNORECRC)) { stream->error = MAD_ERROR_BADCRC; result = -1; } } /* decode frame side information */ error = III_sideinfo(&stream->ptr, nch, header->flags & MAD_FLAG_LSF_EXT, &si, &data_bitlen, &priv_bitlen); if (error && result == 0) { stream->error = error; result = -1; } header->flags |= priv_bitlen; header->private_bits |= si.private_bits; /* find main_data of next frame */ { struct mad_bitptr peek; unsigned long header; mad_bit_init(&peek, stream->next_frame); header = mad_bit_read(&peek, 32); if ((header & 0xffe60000L) /* syncword | layer */ == 0xffe20000L) { if (!(header & 0x00010000L)) /* protection_bit */ mad_bit_skip(&peek, 16); /* crc_check */ next_md_begin = mad_bit_read(&peek, (header & 0x00080000L) /* ID */ ? 9 : 8); } mad_bit_finish(&peek); } /* find main_data of this frame */ frame_space = stream->next_frame - mad_bit_nextbyte(&stream->ptr); if (next_md_begin > si.main_data_begin + frame_space) next_md_begin = 0; md_len = si.main_data_begin + frame_space - next_md_begin; frame_used = 0; if (si.main_data_begin == 0) { ptr = stream->ptr; stream->md_len = 0; frame_used = md_len; } else { if (si.main_data_begin > stream->md_len) { if (result == 0) { stream->error = MAD_ERROR_BADDATAPTR; result = -1; } } else { mad_bit_init(&ptr, *stream->main_data + stream->md_len - si.main_data_begin); if (md_len > si.main_data_begin) { assert(stream->md_len + md_len - si.main_data_begin <= MAD_BUFFER_MDLEN); memcpy(*stream->main_data + stream->md_len, mad_bit_nextbyte(&stream->ptr), frame_used = md_len - si.main_data_begin); stream->md_len += frame_used; } } } frame_free = frame_space - frame_used; /* decode main_data */ if (result == 0) { error = III_decode(&ptr, frame, &si, nch); if (error) { stream->error = error; result = -1; } /* designate ancillary bits */ stream->anc_ptr = ptr; stream->anc_bitlen = md_len * CHAR_BIT - data_bitlen; } # if 0 && defined(DEBUG) fprintf(stderr, "main_data_begin:%u, md_len:%u, frame_free:%u, " "data_bitlen:%u, anc_bitlen: %u\n", si.main_data_begin, md_len, frame_free, data_bitlen, stream->anc_bitlen); # endif /* preload main_data buffer with up to 511 bytes for next frame(s) */ if (frame_free >= next_md_begin) { memcpy(*stream->main_data, stream->next_frame - next_md_begin, next_md_begin); stream->md_len = next_md_begin; } else { if (md_len < si.main_data_begin) { unsigned int extra; extra = si.main_data_begin - md_len; if (extra + frame_free > next_md_begin) extra = next_md_begin - frame_free; if (extra < stream->md_len) { memmove(*stream->main_data, *stream->main_data + stream->md_len - extra, extra); stream->md_len = extra; } } else stream->md_len = 0; memcpy(*stream->main_data + stream->md_len, stream->next_frame - frame_free, frame_free); stream->md_len += frame_free; } return result; } xine-lib-1.2/contrib/libmad/huffman.h0000644000175000017500000000350614647725152015355 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: huffman.h,v 1.11 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_HUFFMAN_H # define LIBMAD_HUFFMAN_H union huffquad { struct { unsigned short final : 1; unsigned short bits : 3; unsigned short offset : 12; } ptr; struct { unsigned short final : 1; unsigned short hlen : 3; unsigned short v : 1; unsigned short w : 1; unsigned short x : 1; unsigned short y : 1; } value; unsigned short final : 1; }; union huffpair { struct { unsigned short final : 1; unsigned short bits : 3; unsigned short offset : 12; } ptr; struct { unsigned short final : 1; unsigned short hlen : 3; unsigned short x : 4; unsigned short y : 4; } value; unsigned short final : 1; }; struct hufftable { union huffpair const *table; unsigned short linbits; unsigned short startbits; }; extern union huffquad const *const mad_huff_quad_table[2]; extern struct hufftable const mad_huff_pair_table[32]; # endif xine-lib-1.2/contrib/libmad/frame.h0000644000175000017500000000772314647725152015030 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frame.h,v 1.20 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_FRAME_H # define LIBMAD_FRAME_H # include "fixed.h" # include "timer.h" # include "stream.h" enum mad_layer { MAD_LAYER_I = 1, /* Layer I */ MAD_LAYER_II = 2, /* Layer II */ MAD_LAYER_III = 3 /* Layer III */ }; enum mad_mode { MAD_MODE_SINGLE_CHANNEL = 0, /* single channel */ MAD_MODE_DUAL_CHANNEL = 1, /* dual channel */ MAD_MODE_JOINT_STEREO = 2, /* joint (MS/intensity) stereo */ MAD_MODE_STEREO = 3 /* normal LR stereo */ }; enum mad_emphasis { MAD_EMPHASIS_NONE = 0, /* no emphasis */ MAD_EMPHASIS_50_15_US = 1, /* 50/15 microseconds emphasis */ MAD_EMPHASIS_CCITT_J_17 = 3, /* CCITT J.17 emphasis */ MAD_EMPHASIS_RESERVED = 2 /* unknown emphasis */ }; struct mad_header { enum mad_layer layer; /* audio layer (1, 2, or 3) */ enum mad_mode mode; /* channel mode (see above) */ int mode_extension; /* additional mode info */ enum mad_emphasis emphasis; /* de-emphasis to use (see above) */ unsigned long bitrate; /* stream bitrate (bps) */ unsigned int samplerate; /* sampling frequency (Hz) */ unsigned short crc_check; /* frame CRC accumulator */ unsigned short crc_target; /* final target CRC checksum */ int flags; /* flags (see below) */ int private_bits; /* private bits (see below) */ mad_timer_t duration; /* audio playing time of frame */ }; struct mad_frame { struct mad_header header; /* MPEG audio header */ int options; /* decoding options (from stream) */ mad_fixed_t sbsample[2][36][32]; /* synthesis subband filter samples */ mad_fixed_t (*overlap)[2][32][18]; /* Layer III block overlap data */ }; # define MAD_NCHANNELS(header) ((header)->mode ? 2 : 1) # define MAD_NSBSAMPLES(header) \ ((header)->layer == MAD_LAYER_I ? 12 : \ (((header)->layer == MAD_LAYER_III && \ ((header)->flags & MAD_FLAG_LSF_EXT)) ? 18 : 36)) enum { MAD_FLAG_NPRIVATE_III = 0x0007, /* number of Layer III private bits */ MAD_FLAG_INCOMPLETE = 0x0008, /* header but not data is decoded */ MAD_FLAG_PROTECTION = 0x0010, /* frame has CRC protection */ MAD_FLAG_COPYRIGHT = 0x0020, /* frame is copyright */ MAD_FLAG_ORIGINAL = 0x0040, /* frame is original (else copy) */ MAD_FLAG_PADDING = 0x0080, /* frame has additional slot */ MAD_FLAG_I_STEREO = 0x0100, /* uses intensity joint stereo */ MAD_FLAG_MS_STEREO = 0x0200, /* uses middle/side joint stereo */ MAD_FLAG_FREEFORMAT = 0x0400, /* uses free format bitrate */ MAD_FLAG_LSF_EXT = 0x1000, /* lower sampling freq. extension */ MAD_FLAG_MC_EXT = 0x2000, /* multichannel audio extension */ MAD_FLAG_MPEG_2_5_EXT = 0x4000 /* MPEG 2.5 (unofficial) extension */ }; enum { MAD_PRIVATE_HEADER = 0x0100, /* header private bit */ MAD_PRIVATE_III = 0x001f /* Layer III private bits (up to 5) */ }; void mad_header_init(struct mad_header *); # define mad_header_finish(header) /* nothing */ int mad_header_decode(struct mad_header *, struct mad_stream *); void mad_frame_init(struct mad_frame *); void mad_frame_finish(struct mad_frame *); int mad_frame_decode(struct mad_frame *, struct mad_stream *); void mad_frame_mute(struct mad_frame *); # endif xine-lib-1.2/contrib/libmad/timer.c0000644000175000017500000002452114647725152015044 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include # ifdef HAVE_ASSERT_H # include # endif # include "timer.h" mad_timer_t const mad_timer_zero = { 0, 0 }; /* * NAME: timer->compare() * DESCRIPTION: indicate relative order of two timers */ int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2) { signed long diff; diff = timer1.seconds - timer2.seconds; if (diff < 0) return -1; else if (diff > 0) return +1; diff = timer1.fraction - timer2.fraction; if (diff < 0) return -1; else if (diff > 0) return +1; return 0; } /* * NAME: timer->negate() * DESCRIPTION: invert the sign of a timer */ void mad_timer_negate(mad_timer_t *timer) { timer->seconds = -timer->seconds; if (timer->fraction) { timer->seconds -= 1; timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction; } } /* * NAME: timer->abs() * DESCRIPTION: return the absolute value of a timer */ mad_timer_t mad_timer_abs(mad_timer_t timer) { if (timer.seconds < 0) mad_timer_negate(&timer); return timer; } /* * NAME: reduce_timer() * DESCRIPTION: carry timer fraction into seconds */ static void reduce_timer(mad_timer_t *timer) { timer->seconds += timer->fraction / MAD_TIMER_RESOLUTION; timer->fraction %= MAD_TIMER_RESOLUTION; } /* * NAME: gcd() * DESCRIPTION: compute greatest common denominator */ static unsigned long gcd(unsigned long num1, unsigned long num2) { unsigned long tmp; while (num2) { tmp = num2; num2 = num1 % num2; num1 = tmp; } return num1; } /* * NAME: reduce_rational() * DESCRIPTION: convert rational expression to lowest terms */ static void reduce_rational(unsigned long *numer, unsigned long *denom) { unsigned long factor; factor = gcd(*numer, *denom); assert(factor != 0); *numer /= factor; *denom /= factor; } /* * NAME: scale_rational() * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing */ static unsigned long scale_rational(unsigned long numer, unsigned long denom, unsigned long scale) { reduce_rational(&numer, &denom); reduce_rational(&scale, &denom); assert(denom != 0); if (denom < scale) return numer * (scale / denom) + numer * (scale % denom) / denom; if (denom < numer) return scale * (numer / denom) + scale * (numer % denom) / denom; return numer * scale / denom; } /* * NAME: timer->set() * DESCRIPTION: set timer to specific (positive) value */ void mad_timer_set(mad_timer_t *timer, unsigned long seconds, unsigned long numer, unsigned long denom) { timer->seconds = seconds; if (numer >= denom && denom > 0) { timer->seconds += numer / denom; numer %= denom; } switch (denom) { case 0: case 1: timer->fraction = 0; break; case MAD_TIMER_RESOLUTION: timer->fraction = numer; break; case 1000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 1000); break; case 8000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 8000); break; case 11025: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025); break; case 12000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000); break; case 16000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000); break; case 22050: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050); break; case 24000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000); break; case 32000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000); break; case 44100: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100); break; case 48000: timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000); break; default: timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION); break; } if (timer->fraction >= MAD_TIMER_RESOLUTION) reduce_timer(timer); } /* * NAME: timer->add() * DESCRIPTION: add one timer to another */ void mad_timer_add(mad_timer_t *timer, mad_timer_t incr) { timer->seconds += incr.seconds; timer->fraction += incr.fraction; if (timer->fraction >= MAD_TIMER_RESOLUTION) reduce_timer(timer); } /* * NAME: timer->multiply() * DESCRIPTION: multiply a timer by a scalar value */ void mad_timer_multiply(mad_timer_t *timer, signed long scalar) { mad_timer_t addend; unsigned long factor; factor = scalar; if (scalar < 0) { factor = -scalar; mad_timer_negate(timer); } addend = *timer; *timer = mad_timer_zero; while (factor) { if (factor & 1) mad_timer_add(timer, addend); mad_timer_add(&addend, addend); factor >>= 1; } } /* * NAME: timer->count() * DESCRIPTION: return timer value in selected units */ signed long mad_timer_count(mad_timer_t timer, enum mad_units units) { switch (units) { case MAD_UNITS_HOURS: return timer.seconds / 60 / 60; case MAD_UNITS_MINUTES: return timer.seconds / 60; case MAD_UNITS_SECONDS: return timer.seconds; case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: return timer.seconds * (signed long) units + (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, units); case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: return (mad_timer_count(timer, -units) + 1) * 1000 / 1001; } /* unsupported units */ return 0; } /* * NAME: timer->fraction() * DESCRIPTION: return fractional part of timer in arbitrary terms */ unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom) { timer = mad_timer_abs(timer); switch (denom) { case 0: return timer.fraction ? MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1; case MAD_TIMER_RESOLUTION: return timer.fraction; default: return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom); } } /* * NAME: timer->string() * DESCRIPTION: write a string representation of a timer using a template */ void mad_timer_string(mad_timer_t timer, char *dest, char const *format, enum mad_units units, enum mad_units fracunits, unsigned long subparts) { unsigned long hours, minutes, seconds, sub; unsigned int frac; timer = mad_timer_abs(timer); seconds = timer.seconds; frac = sub = 0; switch (fracunits) { case MAD_UNITS_HOURS: case MAD_UNITS_MINUTES: case MAD_UNITS_SECONDS: break; case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: { unsigned long denom; denom = MAD_TIMER_RESOLUTION / fracunits; frac = timer.fraction / denom; sub = scale_rational(timer.fraction % denom, denom, subparts); } break; case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: /* drop-frame encoding */ /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */ { unsigned long frame, cycle, d, m; frame = mad_timer_count(timer, fracunits); cycle = -fracunits * 60 * 10 - (10 - 1) * 2; d = frame / cycle; m = frame % cycle; frame += (10 - 1) * 2 * d; if (m > 2) frame += 2 * ((m - 2) / (cycle / 10)); frac = frame % -fracunits; seconds = frame / -fracunits; } break; } switch (units) { case MAD_UNITS_HOURS: minutes = seconds / 60; hours = minutes / 60; sprintf(dest, format, hours, (unsigned int) (minutes % 60), (unsigned int) (seconds % 60), frac, sub); break; case MAD_UNITS_MINUTES: minutes = seconds / 60; sprintf(dest, format, minutes, (unsigned int) (seconds % 60), frac, sub); break; case MAD_UNITS_SECONDS: sprintf(dest, format, seconds, frac, sub); break; case MAD_UNITS_23_976_FPS: case MAD_UNITS_24_975_FPS: case MAD_UNITS_29_97_FPS: case MAD_UNITS_47_952_FPS: case MAD_UNITS_49_95_FPS: case MAD_UNITS_59_94_FPS: if (fracunits < 0) { /* not yet implemented */ sub = 0; } /* fall through */ case MAD_UNITS_DECISECONDS: case MAD_UNITS_CENTISECONDS: case MAD_UNITS_MILLISECONDS: case MAD_UNITS_8000_HZ: case MAD_UNITS_11025_HZ: case MAD_UNITS_12000_HZ: case MAD_UNITS_16000_HZ: case MAD_UNITS_22050_HZ: case MAD_UNITS_24000_HZ: case MAD_UNITS_32000_HZ: case MAD_UNITS_44100_HZ: case MAD_UNITS_48000_HZ: case MAD_UNITS_24_FPS: case MAD_UNITS_25_FPS: case MAD_UNITS_30_FPS: case MAD_UNITS_48_FPS: case MAD_UNITS_50_FPS: case MAD_UNITS_60_FPS: case MAD_UNITS_75_FPS: sprintf(dest, format, mad_timer_count(timer, units), sub); break; } } xine-lib-1.2/contrib/libmad/version.h0000644000175000017500000000311214647725152015407 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: version.h,v 1.26 2004/01/23 09:41:33 rob Exp $ */ # ifndef LIBMAD_VERSION_H # define LIBMAD_VERSION_H # define MAD_VERSION_MAJOR 0 # define MAD_VERSION_MINOR 15 # define MAD_VERSION_PATCH 1 # define MAD_VERSION_EXTRA " (beta)" # define MAD_VERSION_STRINGIZE(str) #str # define MAD_VERSION_STRING(num) MAD_VERSION_STRINGIZE(num) # define MAD_VERSION MAD_VERSION_STRING(MAD_VERSION_MAJOR) "." \ MAD_VERSION_STRING(MAD_VERSION_MINOR) "." \ MAD_VERSION_STRING(MAD_VERSION_PATCH) \ MAD_VERSION_EXTRA # define MAD_PUBLISHYEAR "2000-2004" # define MAD_AUTHOR "Underbit Technologies, Inc." # define MAD_EMAIL "info@underbit.com" extern char const mad_version[]; extern char const mad_copyright[]; extern char const mad_author[]; extern char const mad_build[]; # endif xine-lib-1.2/contrib/libmad/version.c0000644000175000017500000000407114647725152015407 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: version.c,v 1.15 2004/01/23 09:41:33 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include "version.h" char const mad_version[] = "MPEG Audio Decoder " MAD_VERSION; char const mad_copyright[] = "Copyright (C) " MAD_PUBLISHYEAR " " MAD_AUTHOR; char const mad_author[] = MAD_AUTHOR " <" MAD_EMAIL ">"; char const mad_build[] = "" # if defined(DEBUG) "DEBUG " # elif defined(NDEBUG) "NDEBUG " # endif # if defined(EXPERIMENTAL) "EXPERIMENTAL " # endif # if defined(FPM_64BIT) "FPM_64BIT " # elif defined(FPM_INTEL) "FPM_INTEL " # elif defined(FPM_ARM) "FPM_ARM " # elif defined(FPM_MIPS) "FPM_MIPS " # elif defined(FPM_SPARC) "FPM_SPARC " # elif defined(FPM_PPC) "FPM_PPC " # elif defined(FPM_DEFAULT) "FPM_DEFAULT " # endif # if defined(ASO_IMDCT) "ASO_IMDCT " # endif # if defined(ASO_INTERLEAVE1) "ASO_INTERLEAVE1 " # endif # if defined(ASO_INTERLEAVE2) "ASO_INTERLEAVE2 " # endif # if defined(ASO_ZEROCHECK) "ASO_ZEROCHECK " # endif # if defined(OPT_SPEED) "OPT_SPEED " # elif defined(OPT_ACCURACY) "OPT_ACCURACY " # endif # if defined(OPT_SSO) "OPT_SSO " # endif # if defined(OPT_DCTO) /* never defined here */ "OPT_DCTO " # endif # if defined(OPT_STRICT) "OPT_STRICT " # endif ; xine-lib-1.2/contrib/libmad/global.h0000644000175000017500000000315614647725152015172 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: global.h,v 1.11 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_GLOBAL_H # define LIBMAD_GLOBAL_H /* conditional debugging */ # if defined(DEBUG) && defined(NDEBUG) # error "cannot define both DEBUG and NDEBUG" # endif # if defined(DEBUG) # include # endif /* conditional features */ # if defined(OPT_SPEED) && defined(OPT_ACCURACY) # error "cannot optimize for both speed and accuracy" # endif # if defined(OPT_SPEED) && !defined(OPT_SSO) # define OPT_SSO # endif # if defined(HAVE_UNISTD_H) && defined(HAVE_WAITPID) && \ defined(HAVE_FCNTL) && defined(HAVE_PIPE) && defined(HAVE_FORK) # define USE_ASYNC # endif # if !defined(HAVE_ASSERT_H) # if defined(NDEBUG) # define assert(x) /* nothing */ # else # define assert(x) do { if (!(x)) abort(); } while (0) # endif # endif # endif xine-lib-1.2/contrib/libmad/decoder.h0000644000175000017500000000543414647725152015340 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: decoder.h,v 1.17 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_DECODER_H # define LIBMAD_DECODER_H # include "stream.h" # include "frame.h" # include "synth.h" enum mad_decoder_mode { MAD_DECODER_MODE_SYNC = 0, MAD_DECODER_MODE_ASYNC }; enum mad_flow { MAD_FLOW_CONTINUE = 0x0000, /* continue normally */ MAD_FLOW_STOP = 0x0010, /* stop decoding normally */ MAD_FLOW_BREAK = 0x0011, /* stop decoding and signal an error */ MAD_FLOW_IGNORE = 0x0020 /* ignore the current frame */ }; struct mad_decoder { enum mad_decoder_mode mode; int options; struct { long pid; int in; int out; } async; struct { struct mad_stream stream; struct mad_frame frame; struct mad_synth synth; } *sync; void *cb_data; enum mad_flow (*input_func)(void *, struct mad_stream *); enum mad_flow (*header_func)(void *, struct mad_header const *); enum mad_flow (*filter_func)(void *, struct mad_stream const *, struct mad_frame *); enum mad_flow (*output_func)(void *, struct mad_header const *, struct mad_pcm *); enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *); enum mad_flow (*message_func)(void *, void *, unsigned int *); }; void mad_decoder_init(struct mad_decoder *, void *, enum mad_flow (*)(void *, struct mad_stream *), enum mad_flow (*)(void *, struct mad_header const *), enum mad_flow (*)(void *, struct mad_stream const *, struct mad_frame *), enum mad_flow (*)(void *, struct mad_header const *, struct mad_pcm *), enum mad_flow (*)(void *, struct mad_stream *, struct mad_frame *), enum mad_flow (*)(void *, void *, unsigned int *)); int mad_decoder_finish(struct mad_decoder *); # define mad_decoder_options(decoder, opts) \ ((void) ((decoder)->options = (opts))) int mad_decoder_run(struct mad_decoder *, enum mad_decoder_mode); int mad_decoder_message(struct mad_decoder *, void *, unsigned int *); # endif xine-lib-1.2/contrib/libmad/stream.h0000644000175000017500000001017314647725152015222 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: stream.h,v 1.20 2004/02/05 09:02:39 rob Exp $ */ # ifndef LIBMAD_STREAM_H # define LIBMAD_STREAM_H # include "bit.h" # define MAD_BUFFER_GUARD 8 # define MAD_BUFFER_MDLEN (511 + 2048 + MAD_BUFFER_GUARD) enum mad_error { MAD_ERROR_NONE = 0x0000, /* no error */ MAD_ERROR_BUFLEN = 0x0001, /* input buffer too small (or EOF) */ MAD_ERROR_BUFPTR = 0x0002, /* invalid (null) buffer pointer */ MAD_ERROR_NOMEM = 0x0031, /* not enough memory */ MAD_ERROR_LOSTSYNC = 0x0101, /* lost synchronization */ MAD_ERROR_BADLAYER = 0x0102, /* reserved header layer value */ MAD_ERROR_BADBITRATE = 0x0103, /* forbidden bitrate value */ MAD_ERROR_BADSAMPLERATE = 0x0104, /* reserved sample frequency value */ MAD_ERROR_BADEMPHASIS = 0x0105, /* reserved emphasis value */ MAD_ERROR_BADCRC = 0x0201, /* CRC check failed */ MAD_ERROR_BADBITALLOC = 0x0211, /* forbidden bit allocation value */ MAD_ERROR_BADSCALEFACTOR = 0x0221, /* bad scalefactor index */ MAD_ERROR_BADMODE = 0x0222, /* bad bitrate/mode combination */ MAD_ERROR_BADFRAMELEN = 0x0231, /* bad frame length */ MAD_ERROR_BADBIGVALUES = 0x0232, /* bad big_values count */ MAD_ERROR_BADBLOCKTYPE = 0x0233, /* reserved block_type */ MAD_ERROR_BADSCFSI = 0x0234, /* bad scalefactor selection info */ MAD_ERROR_BADDATAPTR = 0x0235, /* bad main_data_begin pointer */ MAD_ERROR_BADPART3LEN = 0x0236, /* bad audio data length */ MAD_ERROR_BADHUFFTABLE = 0x0237, /* bad Huffman table select */ MAD_ERROR_BADHUFFDATA = 0x0238, /* Huffman data overrun */ MAD_ERROR_BADSTEREO = 0x0239 /* incompatible block_type for JS */ }; # define MAD_RECOVERABLE(error) ((error) & 0xff00) struct mad_stream { unsigned char const *buffer; /* input bitstream buffer */ unsigned char const *bufend; /* end of buffer */ unsigned long skiplen; /* bytes to skip before next frame */ int sync; /* stream sync found */ unsigned long freerate; /* free bitrate (fixed) */ unsigned char const *this_frame; /* start of current frame */ unsigned char const *next_frame; /* start of next frame */ struct mad_bitptr ptr; /* current processing bit pointer */ struct mad_bitptr anc_ptr; /* ancillary bits pointer */ unsigned int anc_bitlen; /* number of ancillary bits */ unsigned char (*main_data)[MAD_BUFFER_MDLEN]; /* Layer III main_data() */ unsigned int md_len; /* bytes in main_data */ int options; /* decoding options (see below) */ enum mad_error error; /* error code (see above) */ }; enum { MAD_OPTION_IGNORECRC = 0x0001, /* ignore CRC errors */ MAD_OPTION_HALFSAMPLERATE = 0x0002 /* generate PCM at 1/2 sample rate */ # if 0 /* not yet implemented */ MAD_OPTION_LEFTCHANNEL = 0x0010, /* decode left channel only */ MAD_OPTION_RIGHTCHANNEL = 0x0020, /* decode right channel only */ MAD_OPTION_SINGLECHANNEL = 0x0030 /* combine channels */ # endif }; void mad_stream_init(struct mad_stream *); void mad_stream_finish(struct mad_stream *); # define mad_stream_options(stream, opts) \ ((void) ((stream)->options = (opts))) void mad_stream_buffer(struct mad_stream *, unsigned char const *, unsigned long); void mad_stream_skip(struct mad_stream *, unsigned long); int mad_stream_sync(struct mad_stream *); char const *mad_stream_errorstr(struct mad_stream const *); # endif xine-lib-1.2/contrib/libmad/layer12.h0000644000175000017500000000211114647725151015176 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: layer12.h,v 1.10 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_LAYER12_H # define LIBMAD_LAYER12_H # include "stream.h" # include "frame.h" int mad_layer_I(struct mad_stream *, struct mad_frame *); int mad_layer_II(struct mad_stream *, struct mad_frame *); # endif xine-lib-1.2/contrib/libmad/D.dat0000644000175000017500000006355114647725152014443 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: D.dat,v 1.9 2004/01/23 09:41:32 rob Exp $ */ /* * These are the coefficients for the subband synthesis window. This is a * reordered version of Table B.3 from ISO/IEC 11172-3. * * Every value is parameterized so that shift optimizations can be made at * compile-time. For example, every value can be right-shifted 12 bits to * minimize multiply instruction times without any loss of accuracy. */ { PRESHIFT(0x00000000) /* 0.000000000 */, /* 0 */ -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x000d5000) /* 0.003250122 */, -PRESHIFT(0x001cb000) /* -0.007003784 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x01421000) /* -0.078628540 */, PRESHIFT(0x019ae000) /* 0.100311279 */, -PRESHIFT(0x09271000) /* -0.572036743 */, PRESHIFT(0x1251e000) /* 1.144989014 */, PRESHIFT(0x09271000) /* 0.572036743 */, PRESHIFT(0x019ae000) /* 0.100311279 */, PRESHIFT(0x01421000) /* 0.078628540 */, PRESHIFT(0x007f5000) /* 0.031082153 */, PRESHIFT(0x001cb000) /* 0.007003784 */, PRESHIFT(0x000d5000) /* 0.003250122 */, PRESHIFT(0x0001d000) /* 0.000442505 */, PRESHIFT(0x00000000) /* 0.000000000 */, -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x000d5000) /* 0.003250122 */, -PRESHIFT(0x001cb000) /* -0.007003784 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x01421000) /* -0.078628540 */, PRESHIFT(0x019ae000) /* 0.100311279 */, -PRESHIFT(0x09271000) /* -0.572036743 */, PRESHIFT(0x1251e000) /* 1.144989014 */, PRESHIFT(0x09271000) /* 0.572036743 */, PRESHIFT(0x019ae000) /* 0.100311279 */, PRESHIFT(0x01421000) /* 0.078628540 */, PRESHIFT(0x007f5000) /* 0.031082153 */, PRESHIFT(0x001cb000) /* 0.007003784 */, PRESHIFT(0x000d5000) /* 0.003250122 */, PRESHIFT(0x0001d000) /* 0.000442505 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 1 */ -PRESHIFT(0x0001f000) /* -0.000473022 */, PRESHIFT(0x000da000) /* 0.003326416 */, -PRESHIFT(0x00207000) /* -0.007919312 */, PRESHIFT(0x007d0000) /* 0.030517578 */, -PRESHIFT(0x0158d000) /* -0.084182739 */, PRESHIFT(0x01747000) /* 0.090927124 */, -PRESHIFT(0x099a8000) /* -0.600219727 */, PRESHIFT(0x124f0000) /* 1.144287109 */, PRESHIFT(0x08b38000) /* 0.543823242 */, PRESHIFT(0x01bde000) /* 0.108856201 */, PRESHIFT(0x012b4000) /* 0.073059082 */, PRESHIFT(0x0080f000) /* 0.031478882 */, PRESHIFT(0x00191000) /* 0.006118774 */, PRESHIFT(0x000d0000) /* 0.003173828 */, PRESHIFT(0x0001a000) /* 0.000396729 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x0001f000) /* -0.000473022 */, PRESHIFT(0x000da000) /* 0.003326416 */, -PRESHIFT(0x00207000) /* -0.007919312 */, PRESHIFT(0x007d0000) /* 0.030517578 */, -PRESHIFT(0x0158d000) /* -0.084182739 */, PRESHIFT(0x01747000) /* 0.090927124 */, -PRESHIFT(0x099a8000) /* -0.600219727 */, PRESHIFT(0x124f0000) /* 1.144287109 */, PRESHIFT(0x08b38000) /* 0.543823242 */, PRESHIFT(0x01bde000) /* 0.108856201 */, PRESHIFT(0x012b4000) /* 0.073059082 */, PRESHIFT(0x0080f000) /* 0.031478882 */, PRESHIFT(0x00191000) /* 0.006118774 */, PRESHIFT(0x000d0000) /* 0.003173828 */, PRESHIFT(0x0001a000) /* 0.000396729 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 2 */ -PRESHIFT(0x00023000) /* -0.000534058 */, PRESHIFT(0x000de000) /* 0.003387451 */, -PRESHIFT(0x00245000) /* -0.008865356 */, PRESHIFT(0x007a0000) /* 0.029785156 */, -PRESHIFT(0x016f7000) /* -0.089706421 */, PRESHIFT(0x014a8000) /* 0.080688477 */, -PRESHIFT(0x0a0d8000) /* -0.628295898 */, PRESHIFT(0x12468000) /* 1.142211914 */, PRESHIFT(0x083ff000) /* 0.515609741 */, PRESHIFT(0x01dd8000) /* 0.116577148 */, PRESHIFT(0x01149000) /* 0.067520142 */, PRESHIFT(0x00820000) /* 0.031738281 */, PRESHIFT(0x0015b000) /* 0.005294800 */, PRESHIFT(0x000ca000) /* 0.003082275 */, PRESHIFT(0x00018000) /* 0.000366211 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00023000) /* -0.000534058 */, PRESHIFT(0x000de000) /* 0.003387451 */, -PRESHIFT(0x00245000) /* -0.008865356 */, PRESHIFT(0x007a0000) /* 0.029785156 */, -PRESHIFT(0x016f7000) /* -0.089706421 */, PRESHIFT(0x014a8000) /* 0.080688477 */, -PRESHIFT(0x0a0d8000) /* -0.628295898 */, PRESHIFT(0x12468000) /* 1.142211914 */, PRESHIFT(0x083ff000) /* 0.515609741 */, PRESHIFT(0x01dd8000) /* 0.116577148 */, PRESHIFT(0x01149000) /* 0.067520142 */, PRESHIFT(0x00820000) /* 0.031738281 */, PRESHIFT(0x0015b000) /* 0.005294800 */, PRESHIFT(0x000ca000) /* 0.003082275 */, PRESHIFT(0x00018000) /* 0.000366211 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 3 */ -PRESHIFT(0x00026000) /* -0.000579834 */, PRESHIFT(0x000e1000) /* 0.003433228 */, -PRESHIFT(0x00285000) /* -0.009841919 */, PRESHIFT(0x00765000) /* 0.028884888 */, -PRESHIFT(0x0185d000) /* -0.095169067 */, PRESHIFT(0x011d1000) /* 0.069595337 */, -PRESHIFT(0x0a7fe000) /* -0.656219482 */, PRESHIFT(0x12386000) /* 1.138763428 */, PRESHIFT(0x07ccb000) /* 0.487472534 */, PRESHIFT(0x01f9c000) /* 0.123474121 */, PRESHIFT(0x00fdf000) /* 0.061996460 */, PRESHIFT(0x00827000) /* 0.031845093 */, PRESHIFT(0x00126000) /* 0.004486084 */, PRESHIFT(0x000c4000) /* 0.002990723 */, PRESHIFT(0x00015000) /* 0.000320435 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00026000) /* -0.000579834 */, PRESHIFT(0x000e1000) /* 0.003433228 */, -PRESHIFT(0x00285000) /* -0.009841919 */, PRESHIFT(0x00765000) /* 0.028884888 */, -PRESHIFT(0x0185d000) /* -0.095169067 */, PRESHIFT(0x011d1000) /* 0.069595337 */, -PRESHIFT(0x0a7fe000) /* -0.656219482 */, PRESHIFT(0x12386000) /* 1.138763428 */, PRESHIFT(0x07ccb000) /* 0.487472534 */, PRESHIFT(0x01f9c000) /* 0.123474121 */, PRESHIFT(0x00fdf000) /* 0.061996460 */, PRESHIFT(0x00827000) /* 0.031845093 */, PRESHIFT(0x00126000) /* 0.004486084 */, PRESHIFT(0x000c4000) /* 0.002990723 */, PRESHIFT(0x00015000) /* 0.000320435 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 4 */ -PRESHIFT(0x00029000) /* -0.000625610 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x002c7000) /* -0.010848999 */, PRESHIFT(0x0071e000) /* 0.027801514 */, -PRESHIFT(0x019bd000) /* -0.100540161 */, PRESHIFT(0x00ec0000) /* 0.057617187 */, -PRESHIFT(0x0af15000) /* -0.683914185 */, PRESHIFT(0x12249000) /* 1.133926392 */, PRESHIFT(0x075a0000) /* 0.459472656 */, PRESHIFT(0x0212c000) /* 0.129577637 */, PRESHIFT(0x00e79000) /* 0.056533813 */, PRESHIFT(0x00825000) /* 0.031814575 */, PRESHIFT(0x000f4000) /* 0.003723145 */, PRESHIFT(0x000be000) /* 0.002899170 */, PRESHIFT(0x00013000) /* 0.000289917 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00029000) /* -0.000625610 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x002c7000) /* -0.010848999 */, PRESHIFT(0x0071e000) /* 0.027801514 */, -PRESHIFT(0x019bd000) /* -0.100540161 */, PRESHIFT(0x00ec0000) /* 0.057617187 */, -PRESHIFT(0x0af15000) /* -0.683914185 */, PRESHIFT(0x12249000) /* 1.133926392 */, PRESHIFT(0x075a0000) /* 0.459472656 */, PRESHIFT(0x0212c000) /* 0.129577637 */, PRESHIFT(0x00e79000) /* 0.056533813 */, PRESHIFT(0x00825000) /* 0.031814575 */, PRESHIFT(0x000f4000) /* 0.003723145 */, PRESHIFT(0x000be000) /* 0.002899170 */, PRESHIFT(0x00013000) /* 0.000289917 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 5 */ -PRESHIFT(0x0002d000) /* -0.000686646 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x0030b000) /* -0.011886597 */, PRESHIFT(0x006cb000) /* 0.026535034 */, -PRESHIFT(0x01b17000) /* -0.105819702 */, PRESHIFT(0x00b77000) /* 0.044784546 */, -PRESHIFT(0x0b619000) /* -0.711318970 */, PRESHIFT(0x120b4000) /* 1.127746582 */, PRESHIFT(0x06e81000) /* 0.431655884 */, PRESHIFT(0x02288000) /* 0.134887695 */, PRESHIFT(0x00d17000) /* 0.051132202 */, PRESHIFT(0x0081b000) /* 0.031661987 */, PRESHIFT(0x000c5000) /* 0.003005981 */, PRESHIFT(0x000b7000) /* 0.002792358 */, PRESHIFT(0x00011000) /* 0.000259399 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x0002d000) /* -0.000686646 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x0030b000) /* -0.011886597 */, PRESHIFT(0x006cb000) /* 0.026535034 */, -PRESHIFT(0x01b17000) /* -0.105819702 */, PRESHIFT(0x00b77000) /* 0.044784546 */, -PRESHIFT(0x0b619000) /* -0.711318970 */, PRESHIFT(0x120b4000) /* 1.127746582 */, PRESHIFT(0x06e81000) /* 0.431655884 */, PRESHIFT(0x02288000) /* 0.134887695 */, PRESHIFT(0x00d17000) /* 0.051132202 */, PRESHIFT(0x0081b000) /* 0.031661987 */, PRESHIFT(0x000c5000) /* 0.003005981 */, PRESHIFT(0x000b7000) /* 0.002792358 */, PRESHIFT(0x00011000) /* 0.000259399 */ }, { -PRESHIFT(0x00001000) /* -0.000015259 */, /* 6 */ -PRESHIFT(0x00031000) /* -0.000747681 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x00350000) /* -0.012939453 */, PRESHIFT(0x0066c000) /* 0.025085449 */, -PRESHIFT(0x01c67000) /* -0.110946655 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x0bd06000) /* -0.738372803 */, PRESHIFT(0x11ec7000) /* 1.120223999 */, PRESHIFT(0x06772000) /* 0.404083252 */, PRESHIFT(0x023b3000) /* 0.139450073 */, PRESHIFT(0x00bbc000) /* 0.045837402 */, PRESHIFT(0x00809000) /* 0.031387329 */, PRESHIFT(0x00099000) /* 0.002334595 */, PRESHIFT(0x000b0000) /* 0.002685547 */, PRESHIFT(0x00010000) /* 0.000244141 */, -PRESHIFT(0x00001000) /* -0.000015259 */, -PRESHIFT(0x00031000) /* -0.000747681 */, PRESHIFT(0x000e4000) /* 0.003479004 */, -PRESHIFT(0x00350000) /* -0.012939453 */, PRESHIFT(0x0066c000) /* 0.025085449 */, -PRESHIFT(0x01c67000) /* -0.110946655 */, PRESHIFT(0x007f5000) /* 0.031082153 */, -PRESHIFT(0x0bd06000) /* -0.738372803 */, PRESHIFT(0x11ec7000) /* 1.120223999 */, PRESHIFT(0x06772000) /* 0.404083252 */, PRESHIFT(0x023b3000) /* 0.139450073 */, PRESHIFT(0x00bbc000) /* 0.045837402 */, PRESHIFT(0x00809000) /* 0.031387329 */, PRESHIFT(0x00099000) /* 0.002334595 */, PRESHIFT(0x000b0000) /* 0.002685547 */, PRESHIFT(0x00010000) /* 0.000244141 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 7 */ -PRESHIFT(0x00035000) /* -0.000808716 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x00397000) /* -0.014022827 */, PRESHIFT(0x005ff000) /* 0.023422241 */, -PRESHIFT(0x01dad000) /* -0.115921021 */, PRESHIFT(0x0043a000) /* 0.016510010 */, -PRESHIFT(0x0c3d9000) /* -0.765029907 */, PRESHIFT(0x11c83000) /* 1.111373901 */, PRESHIFT(0x06076000) /* 0.376800537 */, PRESHIFT(0x024ad000) /* 0.143264771 */, PRESHIFT(0x00a67000) /* 0.040634155 */, PRESHIFT(0x007f0000) /* 0.031005859 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x000a9000) /* 0.002578735 */, PRESHIFT(0x0000e000) /* 0.000213623 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x00035000) /* -0.000808716 */, PRESHIFT(0x000e3000) /* 0.003463745 */, -PRESHIFT(0x00397000) /* -0.014022827 */, PRESHIFT(0x005ff000) /* 0.023422241 */, -PRESHIFT(0x01dad000) /* -0.115921021 */, PRESHIFT(0x0043a000) /* 0.016510010 */, -PRESHIFT(0x0c3d9000) /* -0.765029907 */, PRESHIFT(0x11c83000) /* 1.111373901 */, PRESHIFT(0x06076000) /* 0.376800537 */, PRESHIFT(0x024ad000) /* 0.143264771 */, PRESHIFT(0x00a67000) /* 0.040634155 */, PRESHIFT(0x007f0000) /* 0.031005859 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x000a9000) /* 0.002578735 */, PRESHIFT(0x0000e000) /* 0.000213623 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 8 */ -PRESHIFT(0x0003a000) /* -0.000885010 */, PRESHIFT(0x000e0000) /* 0.003417969 */, -PRESHIFT(0x003df000) /* -0.015121460 */, PRESHIFT(0x00586000) /* 0.021575928 */, -PRESHIFT(0x01ee6000) /* -0.120697021 */, PRESHIFT(0x00046000) /* 0.001068115 */, -PRESHIFT(0x0ca8d000) /* -0.791213989 */, PRESHIFT(0x119e9000) /* 1.101211548 */, PRESHIFT(0x05991000) /* 0.349868774 */, PRESHIFT(0x02578000) /* 0.146362305 */, PRESHIFT(0x0091a000) /* 0.035552979 */, PRESHIFT(0x007d1000) /* 0.030532837 */, PRESHIFT(0x00048000) /* 0.001098633 */, PRESHIFT(0x000a1000) /* 0.002456665 */, PRESHIFT(0x0000d000) /* 0.000198364 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x0003a000) /* -0.000885010 */, PRESHIFT(0x000e0000) /* 0.003417969 */, -PRESHIFT(0x003df000) /* -0.015121460 */, PRESHIFT(0x00586000) /* 0.021575928 */, -PRESHIFT(0x01ee6000) /* -0.120697021 */, PRESHIFT(0x00046000) /* 0.001068115 */, -PRESHIFT(0x0ca8d000) /* -0.791213989 */, PRESHIFT(0x119e9000) /* 1.101211548 */, PRESHIFT(0x05991000) /* 0.349868774 */, PRESHIFT(0x02578000) /* 0.146362305 */, PRESHIFT(0x0091a000) /* 0.035552979 */, PRESHIFT(0x007d1000) /* 0.030532837 */, PRESHIFT(0x00048000) /* 0.001098633 */, PRESHIFT(0x000a1000) /* 0.002456665 */, PRESHIFT(0x0000d000) /* 0.000198364 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 9 */ -PRESHIFT(0x0003f000) /* -0.000961304 */, PRESHIFT(0x000dd000) /* 0.003372192 */, -PRESHIFT(0x00428000) /* -0.016235352 */, PRESHIFT(0x00500000) /* 0.019531250 */, -PRESHIFT(0x02011000) /* -0.125259399 */, -PRESHIFT(0x003e6000) /* -0.015228271 */, -PRESHIFT(0x0d11e000) /* -0.816864014 */, PRESHIFT(0x116fc000) /* 1.089782715 */, PRESHIFT(0x052c5000) /* 0.323318481 */, PRESHIFT(0x02616000) /* 0.148773193 */, PRESHIFT(0x007d6000) /* 0.030609131 */, PRESHIFT(0x007aa000) /* 0.029937744 */, PRESHIFT(0x00024000) /* 0.000549316 */, PRESHIFT(0x0009a000) /* 0.002349854 */, PRESHIFT(0x0000b000) /* 0.000167847 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x0003f000) /* -0.000961304 */, PRESHIFT(0x000dd000) /* 0.003372192 */, -PRESHIFT(0x00428000) /* -0.016235352 */, PRESHIFT(0x00500000) /* 0.019531250 */, -PRESHIFT(0x02011000) /* -0.125259399 */, -PRESHIFT(0x003e6000) /* -0.015228271 */, -PRESHIFT(0x0d11e000) /* -0.816864014 */, PRESHIFT(0x116fc000) /* 1.089782715 */, PRESHIFT(0x052c5000) /* 0.323318481 */, PRESHIFT(0x02616000) /* 0.148773193 */, PRESHIFT(0x007d6000) /* 0.030609131 */, PRESHIFT(0x007aa000) /* 0.029937744 */, PRESHIFT(0x00024000) /* 0.000549316 */, PRESHIFT(0x0009a000) /* 0.002349854 */, PRESHIFT(0x0000b000) /* 0.000167847 */ }, { -PRESHIFT(0x00002000) /* -0.000030518 */, /* 10 */ -PRESHIFT(0x00044000) /* -0.001037598 */, PRESHIFT(0x000d7000) /* 0.003280640 */, -PRESHIFT(0x00471000) /* -0.017349243 */, PRESHIFT(0x0046b000) /* 0.017257690 */, -PRESHIFT(0x0212b000) /* -0.129562378 */, -PRESHIFT(0x0084a000) /* -0.032379150 */, -PRESHIFT(0x0d78a000) /* -0.841949463 */, PRESHIFT(0x113be000) /* 1.077117920 */, PRESHIFT(0x04c16000) /* 0.297210693 */, PRESHIFT(0x02687000) /* 0.150497437 */, PRESHIFT(0x0069c000) /* 0.025817871 */, PRESHIFT(0x0077f000) /* 0.029281616 */, PRESHIFT(0x00002000) /* 0.000030518 */, PRESHIFT(0x00093000) /* 0.002243042 */, PRESHIFT(0x0000a000) /* 0.000152588 */, -PRESHIFT(0x00002000) /* -0.000030518 */, -PRESHIFT(0x00044000) /* -0.001037598 */, PRESHIFT(0x000d7000) /* 0.003280640 */, -PRESHIFT(0x00471000) /* -0.017349243 */, PRESHIFT(0x0046b000) /* 0.017257690 */, -PRESHIFT(0x0212b000) /* -0.129562378 */, -PRESHIFT(0x0084a000) /* -0.032379150 */, -PRESHIFT(0x0d78a000) /* -0.841949463 */, PRESHIFT(0x113be000) /* 1.077117920 */, PRESHIFT(0x04c16000) /* 0.297210693 */, PRESHIFT(0x02687000) /* 0.150497437 */, PRESHIFT(0x0069c000) /* 0.025817871 */, PRESHIFT(0x0077f000) /* 0.029281616 */, PRESHIFT(0x00002000) /* 0.000030518 */, PRESHIFT(0x00093000) /* 0.002243042 */, PRESHIFT(0x0000a000) /* 0.000152588 */ }, { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 11 */ -PRESHIFT(0x00049000) /* -0.001113892 */, PRESHIFT(0x000d0000) /* 0.003173828 */, -PRESHIFT(0x004ba000) /* -0.018463135 */, PRESHIFT(0x003ca000) /* 0.014801025 */, -PRESHIFT(0x02233000) /* -0.133590698 */, -PRESHIFT(0x00ce4000) /* -0.050354004 */, -PRESHIFT(0x0ddca000) /* -0.866363525 */, PRESHIFT(0x1102f000) /* 1.063217163 */, PRESHIFT(0x04587000) /* 0.271591187 */, PRESHIFT(0x026cf000) /* 0.151596069 */, PRESHIFT(0x0056c000) /* 0.021179199 */, PRESHIFT(0x0074e000) /* 0.028533936 */, -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x0008b000) /* 0.002120972 */, PRESHIFT(0x00009000) /* 0.000137329 */, -PRESHIFT(0x00003000) /* -0.000045776 */, -PRESHIFT(0x00049000) /* -0.001113892 */, PRESHIFT(0x000d0000) /* 0.003173828 */, -PRESHIFT(0x004ba000) /* -0.018463135 */, PRESHIFT(0x003ca000) /* 0.014801025 */, -PRESHIFT(0x02233000) /* -0.133590698 */, -PRESHIFT(0x00ce4000) /* -0.050354004 */, -PRESHIFT(0x0ddca000) /* -0.866363525 */, PRESHIFT(0x1102f000) /* 1.063217163 */, PRESHIFT(0x04587000) /* 0.271591187 */, PRESHIFT(0x026cf000) /* 0.151596069 */, PRESHIFT(0x0056c000) /* 0.021179199 */, PRESHIFT(0x0074e000) /* 0.028533936 */, -PRESHIFT(0x0001d000) /* -0.000442505 */, PRESHIFT(0x0008b000) /* 0.002120972 */, PRESHIFT(0x00009000) /* 0.000137329 */ }, { -PRESHIFT(0x00003000) /* -0.000045776 */, /* 12 */ -PRESHIFT(0x0004f000) /* -0.001205444 */, PRESHIFT(0x000c8000) /* 0.003051758 */, -PRESHIFT(0x00503000) /* -0.019577026 */, PRESHIFT(0x0031a000) /* 0.012115479 */, -PRESHIFT(0x02326000) /* -0.137298584 */, -PRESHIFT(0x011b5000) /* -0.069168091 */, -PRESHIFT(0x0e3dd000) /* -0.890090942 */, PRESHIFT(0x10c54000) /* 1.048156738 */, PRESHIFT(0x03f1b000) /* 0.246505737 */, PRESHIFT(0x026ee000) /* 0.152069092 */, PRESHIFT(0x00447000) /* 0.016708374 */, PRESHIFT(0x00719000) /* 0.027725220 */, -PRESHIFT(0x00039000) /* -0.000869751 */, PRESHIFT(0x00084000) /* 0.002014160 */, PRESHIFT(0x00008000) /* 0.000122070 */, -PRESHIFT(0x00003000) /* -0.000045776 */, -PRESHIFT(0x0004f000) /* -0.001205444 */, PRESHIFT(0x000c8000) /* 0.003051758 */, -PRESHIFT(0x00503000) /* -0.019577026 */, PRESHIFT(0x0031a000) /* 0.012115479 */, -PRESHIFT(0x02326000) /* -0.137298584 */, -PRESHIFT(0x011b5000) /* -0.069168091 */, -PRESHIFT(0x0e3dd000) /* -0.890090942 */, PRESHIFT(0x10c54000) /* 1.048156738 */, PRESHIFT(0x03f1b000) /* 0.246505737 */, PRESHIFT(0x026ee000) /* 0.152069092 */, PRESHIFT(0x00447000) /* 0.016708374 */, PRESHIFT(0x00719000) /* 0.027725220 */, -PRESHIFT(0x00039000) /* -0.000869751 */, PRESHIFT(0x00084000) /* 0.002014160 */, PRESHIFT(0x00008000) /* 0.000122070 */ }, { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 13 */ -PRESHIFT(0x00055000) /* -0.001296997 */, PRESHIFT(0x000bd000) /* 0.002883911 */, -PRESHIFT(0x0054c000) /* -0.020690918 */, PRESHIFT(0x0025d000) /* 0.009231567 */, -PRESHIFT(0x02403000) /* -0.140670776 */, -PRESHIFT(0x016ba000) /* -0.088775635 */, -PRESHIFT(0x0e9be000) /* -0.913055420 */, PRESHIFT(0x1082d000) /* 1.031936646 */, PRESHIFT(0x038d4000) /* 0.221984863 */, PRESHIFT(0x026e7000) /* 0.151962280 */, PRESHIFT(0x0032e000) /* 0.012420654 */, PRESHIFT(0x006df000) /* 0.026840210 */, -PRESHIFT(0x00053000) /* -0.001266479 */, PRESHIFT(0x0007d000) /* 0.001907349 */, PRESHIFT(0x00007000) /* 0.000106812 */, -PRESHIFT(0x00004000) /* -0.000061035 */, -PRESHIFT(0x00055000) /* -0.001296997 */, PRESHIFT(0x000bd000) /* 0.002883911 */, -PRESHIFT(0x0054c000) /* -0.020690918 */, PRESHIFT(0x0025d000) /* 0.009231567 */, -PRESHIFT(0x02403000) /* -0.140670776 */, -PRESHIFT(0x016ba000) /* -0.088775635 */, -PRESHIFT(0x0e9be000) /* -0.913055420 */, PRESHIFT(0x1082d000) /* 1.031936646 */, PRESHIFT(0x038d4000) /* 0.221984863 */, PRESHIFT(0x026e7000) /* 0.151962280 */, PRESHIFT(0x0032e000) /* 0.012420654 */, PRESHIFT(0x006df000) /* 0.026840210 */, -PRESHIFT(0x00053000) /* -0.001266479 */, PRESHIFT(0x0007d000) /* 0.001907349 */, PRESHIFT(0x00007000) /* 0.000106812 */ }, { -PRESHIFT(0x00004000) /* -0.000061035 */, /* 14 */ -PRESHIFT(0x0005b000) /* -0.001388550 */, PRESHIFT(0x000b1000) /* 0.002700806 */, -PRESHIFT(0x00594000) /* -0.021789551 */, PRESHIFT(0x00192000) /* 0.006134033 */, -PRESHIFT(0x024c8000) /* -0.143676758 */, -PRESHIFT(0x01bf2000) /* -0.109161377 */, -PRESHIFT(0x0ef69000) /* -0.935195923 */, PRESHIFT(0x103be000) /* 1.014617920 */, PRESHIFT(0x032b4000) /* 0.198059082 */, PRESHIFT(0x026bc000) /* 0.151306152 */, PRESHIFT(0x00221000) /* 0.008316040 */, PRESHIFT(0x006a2000) /* 0.025909424 */, -PRESHIFT(0x0006a000) /* -0.001617432 */, PRESHIFT(0x00075000) /* 0.001785278 */, PRESHIFT(0x00007000) /* 0.000106812 */, -PRESHIFT(0x00004000) /* -0.000061035 */, -PRESHIFT(0x0005b000) /* -0.001388550 */, PRESHIFT(0x000b1000) /* 0.002700806 */, -PRESHIFT(0x00594000) /* -0.021789551 */, PRESHIFT(0x00192000) /* 0.006134033 */, -PRESHIFT(0x024c8000) /* -0.143676758 */, -PRESHIFT(0x01bf2000) /* -0.109161377 */, -PRESHIFT(0x0ef69000) /* -0.935195923 */, PRESHIFT(0x103be000) /* 1.014617920 */, PRESHIFT(0x032b4000) /* 0.198059082 */, PRESHIFT(0x026bc000) /* 0.151306152 */, PRESHIFT(0x00221000) /* 0.008316040 */, PRESHIFT(0x006a2000) /* 0.025909424 */, -PRESHIFT(0x0006a000) /* -0.001617432 */, PRESHIFT(0x00075000) /* 0.001785278 */, PRESHIFT(0x00007000) /* 0.000106812 */ }, { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 15 */ -PRESHIFT(0x00061000) /* -0.001480103 */, PRESHIFT(0x000a3000) /* 0.002487183 */, -PRESHIFT(0x005da000) /* -0.022857666 */, PRESHIFT(0x000b9000) /* 0.002822876 */, -PRESHIFT(0x02571000) /* -0.146255493 */, -PRESHIFT(0x0215c000) /* -0.130310059 */, -PRESHIFT(0x0f4dc000) /* -0.956481934 */, PRESHIFT(0x0ff0a000) /* 0.996246338 */, PRESHIFT(0x02cbf000) /* 0.174789429 */, PRESHIFT(0x0266e000) /* 0.150115967 */, PRESHIFT(0x00120000) /* 0.004394531 */, PRESHIFT(0x00662000) /* 0.024932861 */, -PRESHIFT(0x0007f000) /* -0.001937866 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x00006000) /* 0.000091553 */, -PRESHIFT(0x00005000) /* -0.000076294 */, -PRESHIFT(0x00061000) /* -0.001480103 */, PRESHIFT(0x000a3000) /* 0.002487183 */, -PRESHIFT(0x005da000) /* -0.022857666 */, PRESHIFT(0x000b9000) /* 0.002822876 */, -PRESHIFT(0x02571000) /* -0.146255493 */, -PRESHIFT(0x0215c000) /* -0.130310059 */, -PRESHIFT(0x0f4dc000) /* -0.956481934 */, PRESHIFT(0x0ff0a000) /* 0.996246338 */, PRESHIFT(0x02cbf000) /* 0.174789429 */, PRESHIFT(0x0266e000) /* 0.150115967 */, PRESHIFT(0x00120000) /* 0.004394531 */, PRESHIFT(0x00662000) /* 0.024932861 */, -PRESHIFT(0x0007f000) /* -0.001937866 */, PRESHIFT(0x0006f000) /* 0.001693726 */, PRESHIFT(0x00006000) /* 0.000091553 */ }, { -PRESHIFT(0x00005000) /* -0.000076294 */, /* 16 */ -PRESHIFT(0x00068000) /* -0.001586914 */, PRESHIFT(0x00092000) /* 0.002227783 */, -PRESHIFT(0x0061f000) /* -0.023910522 */, -PRESHIFT(0x0002d000) /* -0.000686646 */, -PRESHIFT(0x025ff000) /* -0.148422241 */, -PRESHIFT(0x026f7000) /* -0.152206421 */, -PRESHIFT(0x0fa13000) /* -0.976852417 */, PRESHIFT(0x0fa13000) /* 0.976852417 */, PRESHIFT(0x026f7000) /* 0.152206421 */, PRESHIFT(0x025ff000) /* 0.148422241 */, PRESHIFT(0x0002d000) /* 0.000686646 */, PRESHIFT(0x0061f000) /* 0.023910522 */, -PRESHIFT(0x00092000) /* -0.002227783 */, PRESHIFT(0x00068000) /* 0.001586914 */, PRESHIFT(0x00005000) /* 0.000076294 */, -PRESHIFT(0x00005000) /* -0.000076294 */, -PRESHIFT(0x00068000) /* -0.001586914 */, PRESHIFT(0x00092000) /* 0.002227783 */, -PRESHIFT(0x0061f000) /* -0.023910522 */, -PRESHIFT(0x0002d000) /* -0.000686646 */, -PRESHIFT(0x025ff000) /* -0.148422241 */, -PRESHIFT(0x026f7000) /* -0.152206421 */, -PRESHIFT(0x0fa13000) /* -0.976852417 */, PRESHIFT(0x0fa13000) /* 0.976852417 */, PRESHIFT(0x026f7000) /* 0.152206421 */, PRESHIFT(0x025ff000) /* 0.148422241 */, PRESHIFT(0x0002d000) /* 0.000686646 */, PRESHIFT(0x0061f000) /* 0.023910522 */, -PRESHIFT(0x00092000) /* -0.002227783 */, PRESHIFT(0x00068000) /* 0.001586914 */, PRESHIFT(0x00005000) /* 0.000076294 */ } xine-lib-1.2/contrib/libmad/sf_table.dat0000644000175000017500000001464114647725152016033 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: sf_table.dat,v 1.7 2004/01/23 09:41:33 rob Exp $ */ /* * These are the scalefactor values for Layer I and Layer II. * The values are from Table B.1 of ISO/IEC 11172-3. * * There is some error introduced by the 32-bit fixed-point representation; * the amount of error is shown. For 16-bit PCM output, this shouldn't be * too much of a problem. * * Strictly speaking, Table B.1 has only 63 entries (0-62), thus a strict * interpretation of ISO/IEC 11172-3 would suggest that a scalefactor index of * 63 is invalid. However, for better compatibility with current practices, we * add a 64th entry. */ MAD_F(0x20000000), /* 2.000000000000 => 2.000000000000, e 0.000000000000 */ MAD_F(0x1965fea5), /* 1.587401051968 => 1.587401051074, e 0.000000000894 */ MAD_F(0x1428a2fa), /* 1.259921049895 => 1.259921051562, e -0.000000001667 */ MAD_F(0x10000000), /* 1.000000000000 => 1.000000000000, e 0.000000000000 */ MAD_F(0x0cb2ff53), /* 0.793700525984 => 0.793700527400, e -0.000000001416 */ MAD_F(0x0a14517d), /* 0.629960524947 => 0.629960525781, e -0.000000000833 */ MAD_F(0x08000000), /* 0.500000000000 => 0.500000000000, e 0.000000000000 */ MAD_F(0x06597fa9), /* 0.396850262992 => 0.396850261837, e 0.000000001155 */ MAD_F(0x050a28be), /* 0.314980262474 => 0.314980261028, e 0.000000001446 */ MAD_F(0x04000000), /* 0.250000000000 => 0.250000000000, e 0.000000000000 */ MAD_F(0x032cbfd5), /* 0.198425131496 => 0.198425132781, e -0.000000001285 */ MAD_F(0x0285145f), /* 0.157490131237 => 0.157490130514, e 0.000000000723 */ MAD_F(0x02000000), /* 0.125000000000 => 0.125000000000, e 0.000000000000 */ MAD_F(0x01965fea), /* 0.099212565748 => 0.099212564528, e 0.000000001220 */ MAD_F(0x01428a30), /* 0.078745065618 => 0.078745067120, e -0.000000001501 */ MAD_F(0x01000000), /* 0.062500000000 => 0.062500000000, e 0.000000000000 */ MAD_F(0x00cb2ff5), /* 0.049606282874 => 0.049606282264, e 0.000000000610 */ MAD_F(0x00a14518), /* 0.039372532809 => 0.039372533560, e -0.000000000751 */ MAD_F(0x00800000), /* 0.031250000000 => 0.031250000000, e 0.000000000000 */ MAD_F(0x006597fb), /* 0.024803141437 => 0.024803142995, e -0.000000001558 */ MAD_F(0x0050a28c), /* 0.019686266405 => 0.019686266780, e -0.000000000375 */ MAD_F(0x00400000), /* 0.015625000000 => 0.015625000000, e 0.000000000000 */ MAD_F(0x0032cbfd), /* 0.012401570719 => 0.012401569635, e 0.000000001084 */ MAD_F(0x00285146), /* 0.009843133202 => 0.009843133390, e -0.000000000188 */ MAD_F(0x00200000), /* 0.007812500000 => 0.007812500000, e 0.000000000000 */ MAD_F(0x001965ff), /* 0.006200785359 => 0.006200786680, e -0.000000001321 */ MAD_F(0x001428a3), /* 0.004921566601 => 0.004921566695, e -0.000000000094 */ MAD_F(0x00100000), /* 0.003906250000 => 0.003906250000, e 0.000000000000 */ MAD_F(0x000cb2ff), /* 0.003100392680 => 0.003100391477, e 0.000000001202 */ MAD_F(0x000a1451), /* 0.002460783301 => 0.002460781485, e 0.000000001816 */ MAD_F(0x00080000), /* 0.001953125000 => 0.001953125000, e 0.000000000000 */ MAD_F(0x00065980), /* 0.001550196340 => 0.001550197601, e -0.000000001262 */ MAD_F(0x00050a29), /* 0.001230391650 => 0.001230392605, e -0.000000000955 */ MAD_F(0x00040000), /* 0.000976562500 => 0.000976562500, e 0.000000000000 */ MAD_F(0x00032cc0), /* 0.000775098170 => 0.000775098801, e -0.000000000631 */ MAD_F(0x00028514), /* 0.000615195825 => 0.000615194440, e 0.000000001385 */ MAD_F(0x00020000), /* 0.000488281250 => 0.000488281250, e 0.000000000000 */ MAD_F(0x00019660), /* 0.000387549085 => 0.000387549400, e -0.000000000315 */ MAD_F(0x0001428a), /* 0.000307597913 => 0.000307597220, e 0.000000000693 */ MAD_F(0x00010000), /* 0.000244140625 => 0.000244140625, e 0.000000000000 */ MAD_F(0x0000cb30), /* 0.000193774542 => 0.000193774700, e -0.000000000158 */ MAD_F(0x0000a145), /* 0.000153798956 => 0.000153798610, e 0.000000000346 */ MAD_F(0x00008000), /* 0.000122070313 => 0.000122070313, e 0.000000000000 */ MAD_F(0x00006598), /* 0.000096887271 => 0.000096887350, e -0.000000000079 */ MAD_F(0x000050a3), /* 0.000076899478 => 0.000076901168, e -0.000000001689 */ MAD_F(0x00004000), /* 0.000061035156 => 0.000061035156, e 0.000000000000 */ MAD_F(0x000032cc), /* 0.000048443636 => 0.000048443675, e -0.000000000039 */ MAD_F(0x00002851), /* 0.000038449739 => 0.000038448721, e 0.000000001018 */ MAD_F(0x00002000), /* 0.000030517578 => 0.000030517578, e 0.000000000000 */ MAD_F(0x00001966), /* 0.000024221818 => 0.000024221838, e -0.000000000020 */ MAD_F(0x00001429), /* 0.000019224870 => 0.000019226223, e -0.000000001354 */ MAD_F(0x00001000), /* 0.000015258789 => 0.000015258789, e -0.000000000000 */ MAD_F(0x00000cb3), /* 0.000012110909 => 0.000012110919, e -0.000000000010 */ MAD_F(0x00000a14), /* 0.000009612435 => 0.000009611249, e 0.000000001186 */ MAD_F(0x00000800), /* 0.000007629395 => 0.000007629395, e -0.000000000000 */ MAD_F(0x00000659), /* 0.000006055454 => 0.000006053597, e 0.000000001858 */ MAD_F(0x0000050a), /* 0.000004806217 => 0.000004805624, e 0.000000000593 */ MAD_F(0x00000400), /* 0.000003814697 => 0.000003814697, e 0.000000000000 */ MAD_F(0x0000032d), /* 0.000003027727 => 0.000003028661, e -0.000000000934 */ MAD_F(0x00000285), /* 0.000002403109 => 0.000002402812, e 0.000000000296 */ MAD_F(0x00000200), /* 0.000001907349 => 0.000001907349, e -0.000000000000 */ MAD_F(0x00000196), /* 0.000001513864 => 0.000001512468, e 0.000000001396 */ MAD_F(0x00000143), /* 0.000001201554 => 0.000001203269, e -0.000000001714 */ MAD_F(0x00000000) /* this compatibility entry is not part of Table B.1 */ xine-lib-1.2/contrib/libmad/COPYING0000644000175000017500000004311014647725151014605 0ustar meme GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. xine-lib-1.2/contrib/libmad/bit.c0000644000175000017500000001542414647725152014504 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: bit.c,v 1.12 2004/01/23 09:41:32 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # ifdef HAVE_LIMITS_H # include # else # define CHAR_BIT 8 # endif # include "bit.h" /* * This is the lookup table for computing the CRC-check word. * As described in section 2.4.3.1 and depicted in Figure A.9 * of ISO/IEC 11172-3, the generator polynomial is: * * G(X) = X^16 + X^15 + X^2 + 1 */ static unsigned short const crc_table[256] = { 0x0000, 0x8005, 0x800f, 0x000a, 0x801b, 0x001e, 0x0014, 0x8011, 0x8033, 0x0036, 0x003c, 0x8039, 0x0028, 0x802d, 0x8027, 0x0022, 0x8063, 0x0066, 0x006c, 0x8069, 0x0078, 0x807d, 0x8077, 0x0072, 0x0050, 0x8055, 0x805f, 0x005a, 0x804b, 0x004e, 0x0044, 0x8041, 0x80c3, 0x00c6, 0x00cc, 0x80c9, 0x00d8, 0x80dd, 0x80d7, 0x00d2, 0x00f0, 0x80f5, 0x80ff, 0x00fa, 0x80eb, 0x00ee, 0x00e4, 0x80e1, 0x00a0, 0x80a5, 0x80af, 0x00aa, 0x80bb, 0x00be, 0x00b4, 0x80b1, 0x8093, 0x0096, 0x009c, 0x8099, 0x0088, 0x808d, 0x8087, 0x0082, 0x8183, 0x0186, 0x018c, 0x8189, 0x0198, 0x819d, 0x8197, 0x0192, 0x01b0, 0x81b5, 0x81bf, 0x01ba, 0x81ab, 0x01ae, 0x01a4, 0x81a1, 0x01e0, 0x81e5, 0x81ef, 0x01ea, 0x81fb, 0x01fe, 0x01f4, 0x81f1, 0x81d3, 0x01d6, 0x01dc, 0x81d9, 0x01c8, 0x81cd, 0x81c7, 0x01c2, 0x0140, 0x8145, 0x814f, 0x014a, 0x815b, 0x015e, 0x0154, 0x8151, 0x8173, 0x0176, 0x017c, 0x8179, 0x0168, 0x816d, 0x8167, 0x0162, 0x8123, 0x0126, 0x012c, 0x8129, 0x0138, 0x813d, 0x8137, 0x0132, 0x0110, 0x8115, 0x811f, 0x011a, 0x810b, 0x010e, 0x0104, 0x8101, 0x8303, 0x0306, 0x030c, 0x8309, 0x0318, 0x831d, 0x8317, 0x0312, 0x0330, 0x8335, 0x833f, 0x033a, 0x832b, 0x032e, 0x0324, 0x8321, 0x0360, 0x8365, 0x836f, 0x036a, 0x837b, 0x037e, 0x0374, 0x8371, 0x8353, 0x0356, 0x035c, 0x8359, 0x0348, 0x834d, 0x8347, 0x0342, 0x03c0, 0x83c5, 0x83cf, 0x03ca, 0x83db, 0x03de, 0x03d4, 0x83d1, 0x83f3, 0x03f6, 0x03fc, 0x83f9, 0x03e8, 0x83ed, 0x83e7, 0x03e2, 0x83a3, 0x03a6, 0x03ac, 0x83a9, 0x03b8, 0x83bd, 0x83b7, 0x03b2, 0x0390, 0x8395, 0x839f, 0x039a, 0x838b, 0x038e, 0x0384, 0x8381, 0x0280, 0x8285, 0x828f, 0x028a, 0x829b, 0x029e, 0x0294, 0x8291, 0x82b3, 0x02b6, 0x02bc, 0x82b9, 0x02a8, 0x82ad, 0x82a7, 0x02a2, 0x82e3, 0x02e6, 0x02ec, 0x82e9, 0x02f8, 0x82fd, 0x82f7, 0x02f2, 0x02d0, 0x82d5, 0x82df, 0x02da, 0x82cb, 0x02ce, 0x02c4, 0x82c1, 0x8243, 0x0246, 0x024c, 0x8249, 0x0258, 0x825d, 0x8257, 0x0252, 0x0270, 0x8275, 0x827f, 0x027a, 0x826b, 0x026e, 0x0264, 0x8261, 0x0220, 0x8225, 0x822f, 0x022a, 0x823b, 0x023e, 0x0234, 0x8231, 0x8213, 0x0216, 0x021c, 0x8219, 0x0208, 0x820d, 0x8207, 0x0202 }; # define CRC_POLY 0x8005 /* * NAME: bit->init() * DESCRIPTION: initialize bit pointer struct */ void mad_bit_init(struct mad_bitptr *bitptr, unsigned char const *byte) { bitptr->byte = byte; bitptr->cache = 0; bitptr->left = CHAR_BIT; } /* * NAME: bit->length() * DESCRIPTION: return number of bits between start and end points */ unsigned int mad_bit_length(struct mad_bitptr const *begin, struct mad_bitptr const *end) { return begin->left + CHAR_BIT * (end->byte - (begin->byte + 1)) + (CHAR_BIT - end->left); } /* * NAME: bit->nextbyte() * DESCRIPTION: return pointer to next unprocessed byte */ unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *bitptr) { return bitptr->left == CHAR_BIT ? bitptr->byte : bitptr->byte + 1; } /* * NAME: bit->skip() * DESCRIPTION: advance bit pointer */ void mad_bit_skip(struct mad_bitptr *bitptr, unsigned int len) { bitptr->byte += len / CHAR_BIT; bitptr->left -= len % CHAR_BIT; if (bitptr->left > CHAR_BIT) { bitptr->byte++; bitptr->left += CHAR_BIT; } if (bitptr->left < CHAR_BIT) bitptr->cache = *bitptr->byte; } /* * NAME: bit->read() * DESCRIPTION: read an arbitrary number of bits and return their UIMSBF value */ unsigned long mad_bit_read(struct mad_bitptr *bitptr, unsigned int len) { register unsigned long value; if (bitptr->left == CHAR_BIT) bitptr->cache = *bitptr->byte; if (len < bitptr->left) { value = (bitptr->cache & ((1 << bitptr->left) - 1)) >> (bitptr->left - len); bitptr->left -= len; return value; } /* remaining bits in current byte */ value = bitptr->cache & ((1 << bitptr->left) - 1); len -= bitptr->left; bitptr->byte++; bitptr->left = CHAR_BIT; /* more bytes */ while (len >= CHAR_BIT) { value = (value << CHAR_BIT) | *bitptr->byte++; len -= CHAR_BIT; } if (len > 0) { bitptr->cache = *bitptr->byte; value = (value << len) | (bitptr->cache >> (CHAR_BIT - len)); bitptr->left -= len; } return value; } # if 0 /* * NAME: bit->write() * DESCRIPTION: write an arbitrary number of bits */ void mad_bit_write(struct mad_bitptr *bitptr, unsigned int len, unsigned long value) { unsigned char *ptr; ptr = (unsigned char *) bitptr->byte; /* ... */ } # endif /* * NAME: bit->crc() * DESCRIPTION: compute CRC-check word */ unsigned short mad_bit_crc(struct mad_bitptr bitptr, unsigned int len, unsigned short init) { register unsigned int crc; for (crc = init; len >= 32; len -= 32) { register unsigned long data; data = mad_bit_read(&bitptr, 32); crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 24)) & 0xff]; crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 16)) & 0xff]; crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 8)) & 0xff]; crc = (crc << 8) ^ crc_table[((crc >> 8) ^ (data >> 0)) & 0xff]; } switch (len / 8) { case 3: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; /* fall through */ case 2: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; /* fall through */ case 1: crc = (crc << 8) ^ crc_table[((crc >> 8) ^ mad_bit_read(&bitptr, 8)) & 0xff]; len %= 8; /* fall through */ case 0: break; } while (len--) { register unsigned int msb; msb = mad_bit_read(&bitptr, 1) ^ (crc >> 15); crc <<= 1; if (msb & 1) crc ^= CRC_POLY; } return crc & 0xffff; } xine-lib-1.2/contrib/libmad/qc_table.dat0000644000175000017500000000762314647725152016030 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: qc_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ */ /* * These are the Layer II classes of quantization. * The table is derived from Table B.4 of ISO/IEC 11172-3. */ { 3, 2, 5, MAD_F(0x15555555) /* 1.33333333333 => 1.33333333209, e 0.00000000124 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 5, 3, 7, MAD_F(0x1999999a) /* 1.60000000000 => 1.60000000149, e -0.00000000149 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 7, 0, 3, MAD_F(0x12492492) /* 1.14285714286 => 1.14285714179, e 0.00000000107 */, MAD_F(0x04000000) /* 0.25000000000 => 0.25000000000, e 0.00000000000 */ }, { 9, 4, 10, MAD_F(0x1c71c71c) /* 1.77777777777 => 1.77777777612, e 0.00000000165 */, MAD_F(0x08000000) /* 0.50000000000 => 0.50000000000, e 0.00000000000 */ }, { 15, 0, 4, MAD_F(0x11111111) /* 1.06666666666 => 1.06666666642, e 0.00000000024 */, MAD_F(0x02000000) /* 0.12500000000 => 0.12500000000, e 0.00000000000 */ }, { 31, 0, 5, MAD_F(0x10842108) /* 1.03225806452 => 1.03225806355, e 0.00000000097 */, MAD_F(0x01000000) /* 0.06250000000 => 0.06250000000, e 0.00000000000 */ }, { 63, 0, 6, MAD_F(0x10410410) /* 1.01587301587 => 1.01587301493, e 0.00000000094 */, MAD_F(0x00800000) /* 0.03125000000 => 0.03125000000, e 0.00000000000 */ }, { 127, 0, 7, MAD_F(0x10204081) /* 1.00787401575 => 1.00787401572, e 0.00000000003 */, MAD_F(0x00400000) /* 0.01562500000 => 0.01562500000, e 0.00000000000 */ }, { 255, 0, 8, MAD_F(0x10101010) /* 1.00392156863 => 1.00392156839, e 0.00000000024 */, MAD_F(0x00200000) /* 0.00781250000 => 0.00781250000, e 0.00000000000 */ }, { 511, 0, 9, MAD_F(0x10080402) /* 1.00195694716 => 1.00195694715, e 0.00000000001 */, MAD_F(0x00100000) /* 0.00390625000 => 0.00390625000, e 0.00000000000 */ }, { 1023, 0, 10, MAD_F(0x10040100) /* 1.00097751711 => 1.00097751617, e 0.00000000094 */, MAD_F(0x00080000) /* 0.00195312500 => 0.00195312500, e 0.00000000000 */ }, { 2047, 0, 11, MAD_F(0x10020040) /* 1.00048851979 => 1.00048851967, e 0.00000000012 */, MAD_F(0x00040000) /* 0.00097656250 => 0.00097656250, e 0.00000000000 */ }, { 4095, 0, 12, MAD_F(0x10010010) /* 1.00024420024 => 1.00024420023, e 0.00000000001 */, MAD_F(0x00020000) /* 0.00048828125 => 0.00048828125, e 0.00000000000 */ }, { 8191, 0, 13, MAD_F(0x10008004) /* 1.00012208522 => 1.00012208521, e 0.00000000001 */, MAD_F(0x00010000) /* 0.00024414063 => 0.00024414062, e 0.00000000000 */ }, { 16383, 0, 14, MAD_F(0x10004001) /* 1.00006103888 => 1.00006103888, e -0.00000000000 */, MAD_F(0x00008000) /* 0.00012207031 => 0.00012207031, e -0.00000000000 */ }, { 32767, 0, 15, MAD_F(0x10002000) /* 1.00003051851 => 1.00003051758, e 0.00000000093 */, MAD_F(0x00004000) /* 0.00006103516 => 0.00006103516, e 0.00000000000 */ }, { 65535, 0, 16, MAD_F(0x10001000) /* 1.00001525902 => 1.00001525879, e 0.00000000023 */, MAD_F(0x00002000) /* 0.00003051758 => 0.00003051758, e 0.00000000000 */ } xine-lib-1.2/contrib/libmad/frame.c0000644000175000017500000002751614647725152015025 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: frame.c,v 1.29 2004/02/04 22:59:19 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include # include "bit.h" # include "stream.h" # include "frame.h" # include "timer.h" # include "layer12.h" # include "layer3.h" static unsigned long const bitrate_table[5][15] = { /* MPEG-1 */ { 0, 32000, 64000, 96000, 128000, 160000, 192000, 224000, /* Layer I */ 256000, 288000, 320000, 352000, 384000, 416000, 448000 }, { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer II */ 128000, 160000, 192000, 224000, 256000, 320000, 384000 }, { 0, 32000, 40000, 48000, 56000, 64000, 80000, 96000, /* Layer III */ 112000, 128000, 160000, 192000, 224000, 256000, 320000 }, /* MPEG-2 LSF */ { 0, 32000, 48000, 56000, 64000, 80000, 96000, 112000, /* Layer I */ 128000, 144000, 160000, 176000, 192000, 224000, 256000 }, { 0, 8000, 16000, 24000, 32000, 40000, 48000, 56000, /* Layers */ 64000, 80000, 96000, 112000, 128000, 144000, 160000 } /* II & III */ }; static unsigned int const samplerate_table[3] = { 44100, 48000, 32000 }; static int (*const decoder_table[3])(struct mad_stream *, struct mad_frame *) = { mad_layer_I, mad_layer_II, mad_layer_III }; /* * NAME: header->init() * DESCRIPTION: initialize header struct */ void mad_header_init(struct mad_header *header) { header->layer = 0; header->mode = 0; header->mode_extension = 0; header->emphasis = 0; header->bitrate = 0; header->samplerate = 0; header->crc_check = 0; header->crc_target = 0; header->flags = 0; header->private_bits = 0; header->duration = mad_timer_zero; } /* * NAME: frame->init() * DESCRIPTION: initialize frame struct */ void mad_frame_init(struct mad_frame *frame) { mad_header_init(&frame->header); frame->options = 0; frame->overlap = 0; mad_frame_mute(frame); } /* * NAME: frame->finish() * DESCRIPTION: deallocate any dynamic memory associated with frame */ void mad_frame_finish(struct mad_frame *frame) { mad_header_finish(&frame->header); if (frame->overlap) { free(frame->overlap); frame->overlap = 0; } } /* * NAME: decode_header() * DESCRIPTION: read header data and following CRC word */ static int decode_header(struct mad_header *header, struct mad_stream *stream) { unsigned int index; header->flags = 0; header->private_bits = 0; /* header() */ /* syncword */ mad_bit_skip(&stream->ptr, 11); /* MPEG 2.5 indicator (really part of syncword) */ if (mad_bit_read(&stream->ptr, 1) == 0) header->flags |= MAD_FLAG_MPEG_2_5_EXT; /* ID */ if (mad_bit_read(&stream->ptr, 1) == 0) header->flags |= MAD_FLAG_LSF_EXT; else if (header->flags & MAD_FLAG_MPEG_2_5_EXT) { stream->error = MAD_ERROR_LOSTSYNC; return -1; } /* layer */ header->layer = 4 - mad_bit_read(&stream->ptr, 2); if (header->layer == 4) { stream->error = MAD_ERROR_BADLAYER; return -1; } /* protection_bit */ if (mad_bit_read(&stream->ptr, 1) == 0) { header->flags |= MAD_FLAG_PROTECTION; header->crc_check = mad_bit_crc(stream->ptr, 16, 0xffff); } /* bitrate_index */ index = mad_bit_read(&stream->ptr, 4); if (index == 15) { stream->error = MAD_ERROR_BADBITRATE; return -1; } if (header->flags & MAD_FLAG_LSF_EXT) header->bitrate = bitrate_table[3 + (header->layer >> 1)][index]; else header->bitrate = bitrate_table[header->layer - 1][index]; /* sampling_frequency */ index = mad_bit_read(&stream->ptr, 2); if (index == 3) { stream->error = MAD_ERROR_BADSAMPLERATE; return -1; } header->samplerate = samplerate_table[index]; if (header->flags & MAD_FLAG_LSF_EXT) { header->samplerate /= 2; if (header->flags & MAD_FLAG_MPEG_2_5_EXT) header->samplerate /= 2; } /* padding_bit */ if (mad_bit_read(&stream->ptr, 1)) header->flags |= MAD_FLAG_PADDING; /* private_bit */ if (mad_bit_read(&stream->ptr, 1)) header->private_bits |= MAD_PRIVATE_HEADER; /* mode */ header->mode = 3 - mad_bit_read(&stream->ptr, 2); /* mode_extension */ header->mode_extension = mad_bit_read(&stream->ptr, 2); /* copyright */ if (mad_bit_read(&stream->ptr, 1)) header->flags |= MAD_FLAG_COPYRIGHT; /* original/copy */ if (mad_bit_read(&stream->ptr, 1)) header->flags |= MAD_FLAG_ORIGINAL; /* emphasis */ header->emphasis = mad_bit_read(&stream->ptr, 2); # if defined(OPT_STRICT) /* * ISO/IEC 11172-3 says this is a reserved emphasis value, but * streams exist which use it anyway. Since the value is not important * to the decoder proper, we allow it unless OPT_STRICT is defined. */ if (header->emphasis == MAD_EMPHASIS_RESERVED) { stream->error = MAD_ERROR_BADEMPHASIS; return -1; } # endif /* error_check() */ /* crc_check */ if (header->flags & MAD_FLAG_PROTECTION) header->crc_target = mad_bit_read(&stream->ptr, 16); return 0; } /* * NAME: free_bitrate() * DESCRIPTION: attempt to discover the bitstream's free bitrate */ static int free_bitrate(struct mad_stream *stream, struct mad_header const *header) { struct mad_bitptr keep_ptr; unsigned long rate = 0; unsigned int pad_slot, slots_per_frame; unsigned char const *ptr = 0; keep_ptr = stream->ptr; pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; slots_per_frame = (header->layer == MAD_LAYER_III && (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; while (mad_stream_sync(stream) == 0) { struct mad_stream peek_stream; struct mad_header peek_header; peek_stream = *stream; peek_header = *header; if (decode_header(&peek_header, &peek_stream) == 0 && peek_header.layer == header->layer && peek_header.samplerate == header->samplerate) { unsigned int N; ptr = mad_bit_nextbyte(&stream->ptr); N = ptr - stream->this_frame; if (header->layer == MAD_LAYER_I) { rate = (unsigned long) header->samplerate * (N - 4 * pad_slot + 4) / 48 / 1000; } else { rate = (unsigned long) header->samplerate * (N - pad_slot + 1) / slots_per_frame / 1000; } if (rate >= 8) break; } mad_bit_skip(&stream->ptr, 8); } stream->ptr = keep_ptr; if (rate < 8 || (header->layer == MAD_LAYER_III && rate > 640)) { stream->error = MAD_ERROR_LOSTSYNC; return -1; } stream->freerate = rate * 1000; return 0; } /* * NAME: header->decode() * DESCRIPTION: read the next frame header from the stream */ int mad_header_decode(struct mad_header *header, struct mad_stream *stream) { register unsigned char const *ptr, *end; unsigned int pad_slot, N; ptr = stream->next_frame; end = stream->bufend; if (ptr == 0) { stream->error = MAD_ERROR_BUFPTR; goto fail; } /* stream skip */ if (stream->skiplen) { if (!stream->sync) ptr = stream->this_frame; if (end - ptr < (int)stream->skiplen) { stream->skiplen -= end - ptr; stream->next_frame = end; stream->error = MAD_ERROR_BUFLEN; goto fail; } ptr += stream->skiplen; stream->skiplen = 0; stream->sync = 1; } sync: /* synchronize */ if (stream->sync) { if (end - ptr < MAD_BUFFER_GUARD) { stream->next_frame = ptr; stream->error = MAD_ERROR_BUFLEN; goto fail; } else if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { /* mark point where frame sync word was expected */ stream->this_frame = ptr; stream->next_frame = ptr + 1; stream->error = MAD_ERROR_LOSTSYNC; goto fail; } } else { mad_bit_init(&stream->ptr, ptr); if (mad_stream_sync(stream) == -1) { if (end - stream->next_frame >= MAD_BUFFER_GUARD) stream->next_frame = end - MAD_BUFFER_GUARD; stream->error = MAD_ERROR_BUFLEN; goto fail; } ptr = mad_bit_nextbyte(&stream->ptr); } /* begin processing */ stream->this_frame = ptr; stream->next_frame = ptr + 1; /* possibly bogus sync word */ mad_bit_init(&stream->ptr, stream->this_frame); if (decode_header(header, stream) == -1) goto fail; /* calculate frame duration */ mad_timer_set(&header->duration, 0, 32 * MAD_NSBSAMPLES(header), header->samplerate); /* calculate free bit rate */ if (header->bitrate == 0) { if ((stream->freerate == 0 || !stream->sync || (header->layer == MAD_LAYER_III && stream->freerate > 640000)) && free_bitrate(stream, header) == -1) goto fail; header->bitrate = stream->freerate; header->flags |= MAD_FLAG_FREEFORMAT; } /* calculate beginning of next frame */ pad_slot = (header->flags & MAD_FLAG_PADDING) ? 1 : 0; if (header->layer == MAD_LAYER_I) N = ((12 * header->bitrate / header->samplerate) + pad_slot) * 4; else { unsigned int slots_per_frame; slots_per_frame = (header->layer == MAD_LAYER_III && (header->flags & MAD_FLAG_LSF_EXT)) ? 72 : 144; N = (slots_per_frame * header->bitrate / header->samplerate) + pad_slot; } /* verify there is enough data left in buffer to decode this frame */ if ((int)(N + MAD_BUFFER_GUARD) > end - stream->this_frame) { stream->next_frame = stream->this_frame; stream->error = MAD_ERROR_BUFLEN; goto fail; } stream->next_frame = stream->this_frame + N; if (!stream->sync) { /* check that a valid frame header follows this frame */ ptr = stream->next_frame; if (!(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) { ptr = stream->next_frame = stream->this_frame + 1; goto sync; } stream->sync = 1; } header->flags |= MAD_FLAG_INCOMPLETE; return 0; fail: stream->sync = 0; return -1; } /* * NAME: frame->decode() * DESCRIPTION: decode a single frame from a bitstream */ int mad_frame_decode(struct mad_frame *frame, struct mad_stream *stream) { frame->options = stream->options; /* header() */ /* error_check() */ if (!(frame->header.flags & MAD_FLAG_INCOMPLETE) && mad_header_decode(&frame->header, stream) == -1) goto fail; /* audio_data() */ frame->header.flags &= ~MAD_FLAG_INCOMPLETE; if (decoder_table[frame->header.layer - 1](stream, frame) == -1) { if (!MAD_RECOVERABLE(stream->error)) stream->next_frame = stream->this_frame; goto fail; } /* ancillary_data() */ if (frame->header.layer != MAD_LAYER_III) { struct mad_bitptr next_frame; mad_bit_init(&next_frame, stream->next_frame); stream->anc_ptr = stream->ptr; stream->anc_bitlen = mad_bit_length(&stream->ptr, &next_frame); mad_bit_finish(&next_frame); } return 0; fail: stream->anc_bitlen = 0; return -1; } /* * NAME: frame->mute() * DESCRIPTION: zero all subband values so the frame becomes silent */ void mad_frame_mute(struct mad_frame *frame) { unsigned int s, sb; for (s = 0; s < 36; ++s) { for (sb = 0; sb < 32; ++sb) { frame->sbsample[0][s][sb] = frame->sbsample[1][s][sb] = 0; } } if (frame->overlap) { for (s = 0; s < 18; ++s) { for (sb = 0; sb < 32; ++sb) { (*frame->overlap)[0][sb][s] = (*frame->overlap)[1][sb][s] = 0; } } } } xine-lib-1.2/contrib/libmad/synth.c0000644000175000017500000005745614647725152015106 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: synth.c,v 1.25 2004/01/23 09:41:33 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include "fixed.h" # include "frame.h" # include "synth.h" /* * NAME: synth->init() * DESCRIPTION: initialize synth struct */ void mad_synth_init(struct mad_synth *synth) { mad_synth_mute(synth); synth->phase = 0; synth->pcm.samplerate = 0; synth->pcm.channels = 0; synth->pcm.length = 0; } /* * NAME: synth->mute() * DESCRIPTION: zero all polyphase filterbank values, resetting synthesis */ void mad_synth_mute(struct mad_synth *synth) { unsigned int ch, s, v; for (ch = 0; ch < 2; ++ch) { for (s = 0; s < 16; ++s) { for (v = 0; v < 8; ++v) { synth->filter[ch][0][0][s][v] = synth->filter[ch][0][1][s][v] = synth->filter[ch][1][0][s][v] = synth->filter[ch][1][1][s][v] = 0; } } } } /* * An optional optimization called here the Subband Synthesis Optimization * (SSO) improves the performance of subband synthesis at the expense of * accuracy. * * The idea is to simplify 32x32->64-bit multiplication to 32x32->32 such * that extra scaling and rounding are not necessary. This often allows the * compiler to use faster 32-bit multiply-accumulate instructions instead of * explicit 64-bit multiply, shift, and add instructions. * * SSO works like this: a full 32x32->64-bit multiply of two mad_fixed_t * values requires the result to be right-shifted 28 bits to be properly * scaled to the same fixed-point format. Right shifts can be applied at any * time to either operand or to the result, so the optimization involves * careful placement of these shifts to minimize the loss of accuracy. * * First, a 14-bit shift is applied with rounding at compile-time to the D[] * table of coefficients for the subband synthesis window. This only loses 2 * bits of accuracy because the lower 12 bits are always zero. A second * 12-bit shift occurs after the DCT calculation. This loses 12 bits of * accuracy. Finally, a third 2-bit shift occurs just before the sample is * saved in the PCM buffer. 14 + 12 + 2 == 28 bits. */ /* FPM_DEFAULT without OPT_SSO will actually lose accuracy and performance */ # if defined(FPM_DEFAULT) && !defined(OPT_SSO) # define OPT_SSO # endif /* second SSO shift, with rounding */ # if defined(OPT_SSO) # define SHIFT(x) (((x) + (1L << 11)) >> 12) # else # define SHIFT(x) (x) # endif /* possible DCT speed optimization */ # if defined(OPT_SPEED) && defined(MAD_F_MLX) # define OPT_DCTO # define MUL(x, y) \ ({ mad_fixed64hi_t hi; \ mad_fixed64lo_t lo; \ MAD_F_MLX(hi, lo, (x), (y)); \ hi << (32 - MAD_F_SCALEBITS - 3); \ }) # else # undef OPT_DCTO # define MUL(x, y) mad_f_mul((x), (y)) # endif /* * NAME: dct32() * DESCRIPTION: perform fast in[32]->out[32] DCT */ static void dct32(mad_fixed_t const in[32], unsigned int slot, mad_fixed_t lo[16][8], mad_fixed_t hi[16][8]) { mad_fixed_t t0, t1, t2, t3, t4, t5, t6, t7; mad_fixed_t t8, t9, t10, t11, t12, t13, t14, t15; mad_fixed_t t16, t17, t18, t19, t20, t21, t22, t23; mad_fixed_t t24, t25, t26, t27, t28, t29, t30, t31; mad_fixed_t t32, t33, t34, t35, t36, t37, t38, t39; mad_fixed_t t40, t41, t42, t43, t44, t45, t46, t47; mad_fixed_t t48, t49, t50, t51, t52, t53, t54, t55; mad_fixed_t t56, t57, t58, t59, t60, t61, t62, t63; mad_fixed_t t64, t65, t66, t67, t68, t69, t70, t71; mad_fixed_t t72, t73, t74, t75, t76, t77, t78, t79; mad_fixed_t t80, t81, t82, t83, t84, t85, t86, t87; mad_fixed_t t88, t89, t90, t91, t92, t93, t94, t95; mad_fixed_t t96, t97, t98, t99, t100, t101, t102, t103; mad_fixed_t t104, t105, t106, t107, t108, t109, t110, t111; mad_fixed_t t112, t113, t114, t115, t116, t117, t118, t119; mad_fixed_t t120, t121, t122, t123, t124, t125, t126, t127; mad_fixed_t t128, t129, t130, t131, t132, t133, t134, t135; mad_fixed_t t136, t137, t138, t139, t140, t141, t142, t143; mad_fixed_t t144, t145, t146, t147, t148, t149, t150, t151; mad_fixed_t t152, t153, t154, t155, t156, t157, t158, t159; mad_fixed_t t160, t161, t162, t163, t164, t165, t166, t167; mad_fixed_t t168, t169, t170, t171, t172, t173, t174, t175; mad_fixed_t t176; /* costab[i] = cos(PI / (2 * 32) * i) */ # if defined(OPT_DCTO) # define costab1 MAD_F(0x7fd8878e) # define costab2 MAD_F(0x7f62368f) # define costab3 MAD_F(0x7e9d55fc) # define costab4 MAD_F(0x7d8a5f40) # define costab5 MAD_F(0x7c29fbee) # define costab6 MAD_F(0x7a7d055b) # define costab7 MAD_F(0x78848414) # define costab8 MAD_F(0x7641af3d) # define costab9 MAD_F(0x73b5ebd1) # define costab10 MAD_F(0x70e2cbc6) # define costab11 MAD_F(0x6dca0d14) # define costab12 MAD_F(0x6a6d98a4) # define costab13 MAD_F(0x66cf8120) # define costab14 MAD_F(0x62f201ac) # define costab15 MAD_F(0x5ed77c8a) # define costab16 MAD_F(0x5a82799a) # define costab17 MAD_F(0x55f5a4d2) # define costab18 MAD_F(0x5133cc94) # define costab19 MAD_F(0x4c3fdff4) # define costab20 MAD_F(0x471cece7) # define costab21 MAD_F(0x41ce1e65) # define costab22 MAD_F(0x3c56ba70) # define costab23 MAD_F(0x36ba2014) # define costab24 MAD_F(0x30fbc54d) # define costab25 MAD_F(0x2b1f34eb) # define costab26 MAD_F(0x25280c5e) # define costab27 MAD_F(0x1f19f97b) # define costab28 MAD_F(0x18f8b83c) # define costab29 MAD_F(0x12c8106f) # define costab30 MAD_F(0x0c8bd35e) # define costab31 MAD_F(0x0647d97c) # else # define costab1 MAD_F(0x0ffb10f2) /* 0.998795456 */ # define costab2 MAD_F(0x0fec46d2) /* 0.995184727 */ # define costab3 MAD_F(0x0fd3aac0) /* 0.989176510 */ # define costab4 MAD_F(0x0fb14be8) /* 0.980785280 */ # define costab5 MAD_F(0x0f853f7e) /* 0.970031253 */ # define costab6 MAD_F(0x0f4fa0ab) /* 0.956940336 */ # define costab7 MAD_F(0x0f109082) /* 0.941544065 */ # define costab8 MAD_F(0x0ec835e8) /* 0.923879533 */ # define costab9 MAD_F(0x0e76bd7a) /* 0.903989293 */ # define costab10 MAD_F(0x0e1c5979) /* 0.881921264 */ # define costab11 MAD_F(0x0db941a3) /* 0.857728610 */ # define costab12 MAD_F(0x0d4db315) /* 0.831469612 */ # define costab13 MAD_F(0x0cd9f024) /* 0.803207531 */ # define costab14 MAD_F(0x0c5e4036) /* 0.773010453 */ # define costab15 MAD_F(0x0bdaef91) /* 0.740951125 */ # define costab16 MAD_F(0x0b504f33) /* 0.707106781 */ # define costab17 MAD_F(0x0abeb49a) /* 0.671558955 */ # define costab18 MAD_F(0x0a267993) /* 0.634393284 */ # define costab19 MAD_F(0x0987fbfe) /* 0.595699304 */ # define costab20 MAD_F(0x08e39d9d) /* 0.555570233 */ # define costab21 MAD_F(0x0839c3cd) /* 0.514102744 */ # define costab22 MAD_F(0x078ad74e) /* 0.471396737 */ # define costab23 MAD_F(0x06d74402) /* 0.427555093 */ # define costab24 MAD_F(0x061f78aa) /* 0.382683432 */ # define costab25 MAD_F(0x0563e69d) /* 0.336889853 */ # define costab26 MAD_F(0x04a5018c) /* 0.290284677 */ # define costab27 MAD_F(0x03e33f2f) /* 0.242980180 */ # define costab28 MAD_F(0x031f1708) /* 0.195090322 */ # define costab29 MAD_F(0x0259020e) /* 0.146730474 */ # define costab30 MAD_F(0x01917a6c) /* 0.098017140 */ # define costab31 MAD_F(0x00c8fb30) /* 0.049067674 */ # endif t0 = in[0] + in[31]; t16 = MUL(in[0] - in[31], costab1); t1 = in[15] + in[16]; t17 = MUL(in[15] - in[16], costab31); t41 = t16 + t17; t59 = MUL(t16 - t17, costab2); t33 = t0 + t1; t50 = MUL(t0 - t1, costab2); t2 = in[7] + in[24]; t18 = MUL(in[7] - in[24], costab15); t3 = in[8] + in[23]; t19 = MUL(in[8] - in[23], costab17); t42 = t18 + t19; t60 = MUL(t18 - t19, costab30); t34 = t2 + t3; t51 = MUL(t2 - t3, costab30); t4 = in[3] + in[28]; t20 = MUL(in[3] - in[28], costab7); t5 = in[12] + in[19]; t21 = MUL(in[12] - in[19], costab25); t43 = t20 + t21; t61 = MUL(t20 - t21, costab14); t35 = t4 + t5; t52 = MUL(t4 - t5, costab14); t6 = in[4] + in[27]; t22 = MUL(in[4] - in[27], costab9); t7 = in[11] + in[20]; t23 = MUL(in[11] - in[20], costab23); t44 = t22 + t23; t62 = MUL(t22 - t23, costab18); t36 = t6 + t7; t53 = MUL(t6 - t7, costab18); t8 = in[1] + in[30]; t24 = MUL(in[1] - in[30], costab3); t9 = in[14] + in[17]; t25 = MUL(in[14] - in[17], costab29); t45 = t24 + t25; t63 = MUL(t24 - t25, costab6); t37 = t8 + t9; t54 = MUL(t8 - t9, costab6); t10 = in[6] + in[25]; t26 = MUL(in[6] - in[25], costab13); t11 = in[9] + in[22]; t27 = MUL(in[9] - in[22], costab19); t46 = t26 + t27; t64 = MUL(t26 - t27, costab26); t38 = t10 + t11; t55 = MUL(t10 - t11, costab26); t12 = in[2] + in[29]; t28 = MUL(in[2] - in[29], costab5); t13 = in[13] + in[18]; t29 = MUL(in[13] - in[18], costab27); t47 = t28 + t29; t65 = MUL(t28 - t29, costab10); t39 = t12 + t13; t56 = MUL(t12 - t13, costab10); t14 = in[5] + in[26]; t30 = MUL(in[5] - in[26], costab11); t15 = in[10] + in[21]; t31 = MUL(in[10] - in[21], costab21); t48 = t30 + t31; t66 = MUL(t30 - t31, costab22); t40 = t14 + t15; t57 = MUL(t14 - t15, costab22); t69 = t33 + t34; t89 = MUL(t33 - t34, costab4); t70 = t35 + t36; t90 = MUL(t35 - t36, costab28); t71 = t37 + t38; t91 = MUL(t37 - t38, costab12); t72 = t39 + t40; t92 = MUL(t39 - t40, costab20); t73 = t41 + t42; t94 = MUL(t41 - t42, costab4); t74 = t43 + t44; t95 = MUL(t43 - t44, costab28); t75 = t45 + t46; t96 = MUL(t45 - t46, costab12); t76 = t47 + t48; t97 = MUL(t47 - t48, costab20); t78 = t50 + t51; t100 = MUL(t50 - t51, costab4); t79 = t52 + t53; t101 = MUL(t52 - t53, costab28); t80 = t54 + t55; t102 = MUL(t54 - t55, costab12); t81 = t56 + t57; t103 = MUL(t56 - t57, costab20); t83 = t59 + t60; t106 = MUL(t59 - t60, costab4); t84 = t61 + t62; t107 = MUL(t61 - t62, costab28); t85 = t63 + t64; t108 = MUL(t63 - t64, costab12); t86 = t65 + t66; t109 = MUL(t65 - t66, costab20); t113 = t69 + t70; t114 = t71 + t72; /* 0 */ hi[15][slot] = SHIFT(t113 + t114); /* 16 */ lo[ 0][slot] = SHIFT(MUL(t113 - t114, costab16)); t115 = t73 + t74; t116 = t75 + t76; t32 = t115 + t116; /* 1 */ hi[14][slot] = SHIFT(t32); t118 = t78 + t79; t119 = t80 + t81; t58 = t118 + t119; /* 2 */ hi[13][slot] = SHIFT(t58); t121 = t83 + t84; t122 = t85 + t86; t67 = t121 + t122; t49 = (t67 * 2) - t32; /* 3 */ hi[12][slot] = SHIFT(t49); t125 = t89 + t90; t126 = t91 + t92; t93 = t125 + t126; /* 4 */ hi[11][slot] = SHIFT(t93); t128 = t94 + t95; t129 = t96 + t97; t98 = t128 + t129; t68 = (t98 * 2) - t49; /* 5 */ hi[10][slot] = SHIFT(t68); t132 = t100 + t101; t133 = t102 + t103; t104 = t132 + t133; t82 = (t104 * 2) - t58; /* 6 */ hi[ 9][slot] = SHIFT(t82); t136 = t106 + t107; t137 = t108 + t109; t110 = t136 + t137; t87 = (t110 * 2) - t67; t77 = (t87 * 2) - t68; /* 7 */ hi[ 8][slot] = SHIFT(t77); t141 = MUL(t69 - t70, costab8); t142 = MUL(t71 - t72, costab24); t143 = t141 + t142; /* 8 */ hi[ 7][slot] = SHIFT(t143); /* 24 */ lo[ 8][slot] = SHIFT((MUL(t141 - t142, costab16) * 2) - t143); t144 = MUL(t73 - t74, costab8); t145 = MUL(t75 - t76, costab24); t146 = t144 + t145; t88 = (t146 * 2) - t77; /* 9 */ hi[ 6][slot] = SHIFT(t88); t148 = MUL(t78 - t79, costab8); t149 = MUL(t80 - t81, costab24); t150 = t148 + t149; t105 = (t150 * 2) - t82; /* 10 */ hi[ 5][slot] = SHIFT(t105); t152 = MUL(t83 - t84, costab8); t153 = MUL(t85 - t86, costab24); t154 = t152 + t153; t111 = (t154 * 2) - t87; t99 = (t111 * 2) - t88; /* 11 */ hi[ 4][slot] = SHIFT(t99); t157 = MUL(t89 - t90, costab8); t158 = MUL(t91 - t92, costab24); t159 = t157 + t158; t127 = (t159 * 2) - t93; /* 12 */ hi[ 3][slot] = SHIFT(t127); t160 = (MUL(t125 - t126, costab16) * 2) - t127; /* 20 */ lo[ 4][slot] = SHIFT(t160); /* 28 */ lo[12][slot] = SHIFT((((MUL(t157 - t158, costab16) * 2) - t159) * 2) - t160); t161 = MUL(t94 - t95, costab8); t162 = MUL(t96 - t97, costab24); t163 = t161 + t162; t130 = (t163 * 2) - t98; t112 = (t130 * 2) - t99; /* 13 */ hi[ 2][slot] = SHIFT(t112); t164 = (MUL(t128 - t129, costab16) * 2) - t130; t166 = MUL(t100 - t101, costab8); t167 = MUL(t102 - t103, costab24); t168 = t166 + t167; t134 = (t168 * 2) - t104; t120 = (t134 * 2) - t105; /* 14 */ hi[ 1][slot] = SHIFT(t120); t135 = (MUL(t118 - t119, costab16) * 2) - t120; /* 18 */ lo[ 2][slot] = SHIFT(t135); t169 = (MUL(t132 - t133, costab16) * 2) - t134; t151 = (t169 * 2) - t135; /* 22 */ lo[ 6][slot] = SHIFT(t151); t170 = (((MUL(t148 - t149, costab16) * 2) - t150) * 2) - t151; /* 26 */ lo[10][slot] = SHIFT(t170); /* 30 */ lo[14][slot] = SHIFT((((((MUL(t166 - t167, costab16) * 2) - t168) * 2) - t169) * 2) - t170); t171 = MUL(t106 - t107, costab8); t172 = MUL(t108 - t109, costab24); t173 = t171 + t172; t138 = (t173 * 2) - t110; t123 = (t138 * 2) - t111; t139 = (MUL(t121 - t122, costab16) * 2) - t123; t117 = (t123 * 2) - t112; /* 15 */ hi[ 0][slot] = SHIFT(t117); t124 = (MUL(t115 - t116, costab16) * 2) - t117; /* 17 */ lo[ 1][slot] = SHIFT(t124); t131 = (t139 * 2) - t124; /* 19 */ lo[ 3][slot] = SHIFT(t131); t140 = (t164 * 2) - t131; /* 21 */ lo[ 5][slot] = SHIFT(t140); t174 = (MUL(t136 - t137, costab16) * 2) - t138; t155 = (t174 * 2) - t139; t147 = (t155 * 2) - t140; /* 23 */ lo[ 7][slot] = SHIFT(t147); t156 = (((MUL(t144 - t145, costab16) * 2) - t146) * 2) - t147; /* 25 */ lo[ 9][slot] = SHIFT(t156); t175 = (((MUL(t152 - t153, costab16) * 2) - t154) * 2) - t155; t165 = (t175 * 2) - t156; /* 27 */ lo[11][slot] = SHIFT(t165); t176 = (((((MUL(t161 - t162, costab16) * 2) - t163) * 2) - t164) * 2) - t165; /* 29 */ lo[13][slot] = SHIFT(t176); /* 31 */ lo[15][slot] = SHIFT((((((((MUL(t171 - t172, costab16) * 2) - t173) * 2) - t174) * 2) - t175) * 2) - t176); /* * Totals: * 80 multiplies * 80 additions * 119 subtractions * 49 shifts (not counting SSO) */ } # undef MUL # undef SHIFT /* third SSO shift and/or D[] optimization preshift */ # if defined(OPT_SSO) # if MAD_F_FRACBITS != 28 # error "MAD_F_FRACBITS must be 28 to use OPT_SSO" # endif # define ML0(hi, lo, x, y) ((lo) = (x) * (y)) # define MLA(hi, lo, x, y) ((lo) += (x) * (y)) # define MLN(hi, lo) ((lo) = -(lo)) # define MLZ(hi, lo) ((void) (hi), (mad_fixed_t) (lo)) # define SHIFT(x) ((x) >> 2) # define PRESHIFT(x) ((MAD_F(x) + (1L << 13)) >> 14) # else # define ML0(hi, lo, x, y) MAD_F_ML0((hi), (lo), (x), (y)) # define MLA(hi, lo, x, y) MAD_F_MLA((hi), (lo), (x), (y)) # define MLN(hi, lo) MAD_F_MLN((hi), (lo)) # define MLZ(hi, lo) MAD_F_MLZ((hi), (lo)) # define SHIFT(x) (x) # if defined(MAD_F_SCALEBITS) # undef MAD_F_SCALEBITS # define MAD_F_SCALEBITS (MAD_F_FRACBITS - 12) # define PRESHIFT(x) (MAD_F(x) >> 12) # else # define PRESHIFT(x) MAD_F(x) # endif # endif static mad_fixed_t const D[17][32] = { # include "D.dat" }; # if defined(ASO_SYNTH) void synth_full(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int); # else /* * NAME: synth->full() * DESCRIPTION: perform full frequency PCM synthesis */ static void synth_full(struct mad_synth *synth, struct mad_frame const *frame, unsigned int nch, unsigned int ns) { unsigned int phase, ch, s, sb, pe, po; mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; mad_fixed_t const (*sbsample)[36][32]; register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; register mad_fixed_t const (*Dptr)[32], *ptr; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; for (ch = 0; ch < nch; ++ch) { sbsample = &frame->sbsample[ch]; filter = &synth->filter[ch]; phase = synth->phase; pcm1 = synth->pcm.samples[ch]; for (s = 0; s < ns; ++s) { dct32((*sbsample)[s], phase >> 1, (*filter)[0][phase & 1], (*filter)[1][phase & 1]); pe = phase & ~1; po = ((phase - 1) & 0xf) | 1; /* calculate 32 samples */ fe = &(*filter)[0][ phase & 1][0]; fx = &(*filter)[0][~phase & 1][0]; fo = &(*filter)[1][~phase & 1][0]; Dptr = &D[0]; ptr = *Dptr + po; ML0(hi, lo, (*fx)[0], ptr[ 0]); MLA(hi, lo, (*fx)[1], ptr[14]); MLA(hi, lo, (*fx)[2], ptr[12]); MLA(hi, lo, (*fx)[3], ptr[10]); MLA(hi, lo, (*fx)[4], ptr[ 8]); MLA(hi, lo, (*fx)[5], ptr[ 6]); MLA(hi, lo, (*fx)[6], ptr[ 4]); MLA(hi, lo, (*fx)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 30; for (sb = 1; sb < 16; ++sb) { ++fe; ++Dptr; /* D[32 - sb][i] == -D[sb][31 - i] */ ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); *pcm1++ = SHIFT(MLZ(hi, lo)); ptr = *Dptr - pe; ML0(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); MLA(hi, lo, (*fe)[4], ptr[31 - 8]); MLA(hi, lo, (*fe)[5], ptr[31 - 6]); MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); ptr = *Dptr - po; MLA(hi, lo, (*fo)[7], ptr[31 - 2]); MLA(hi, lo, (*fo)[6], ptr[31 - 4]); MLA(hi, lo, (*fo)[5], ptr[31 - 6]); MLA(hi, lo, (*fo)[4], ptr[31 - 8]); MLA(hi, lo, (*fo)[3], ptr[31 - 10]); MLA(hi, lo, (*fo)[2], ptr[31 - 12]); MLA(hi, lo, (*fo)[1], ptr[31 - 14]); MLA(hi, lo, (*fo)[0], ptr[31 - 16]); *pcm2-- = SHIFT(MLZ(hi, lo)); ++fo; } ++Dptr; ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); *pcm1 = SHIFT(-MLZ(hi, lo)); pcm1 += 16; phase = (phase + 1) % 16; } } } # endif /* * NAME: synth->half() * DESCRIPTION: perform half frequency PCM synthesis */ static void synth_half(struct mad_synth *synth, struct mad_frame const *frame, unsigned int nch, unsigned int ns) { unsigned int phase, ch, s, sb, pe, po; mad_fixed_t *pcm1, *pcm2, (*filter)[2][2][16][8]; mad_fixed_t const (*sbsample)[36][32]; register mad_fixed_t (*fe)[8], (*fx)[8], (*fo)[8]; register mad_fixed_t const (*Dptr)[32], *ptr; register mad_fixed64hi_t hi; register mad_fixed64lo_t lo; for (ch = 0; ch < nch; ++ch) { sbsample = &frame->sbsample[ch]; filter = &synth->filter[ch]; phase = synth->phase; pcm1 = synth->pcm.samples[ch]; for (s = 0; s < ns; ++s) { dct32((*sbsample)[s], phase >> 1, (*filter)[0][phase & 1], (*filter)[1][phase & 1]); pe = phase & ~1; po = ((phase - 1) & 0xf) | 1; /* calculate 16 samples */ fe = &(*filter)[0][ phase & 1][0]; fx = &(*filter)[0][~phase & 1][0]; fo = &(*filter)[1][~phase & 1][0]; Dptr = &D[0]; ptr = *Dptr + po; ML0(hi, lo, (*fx)[0], ptr[ 0]); MLA(hi, lo, (*fx)[1], ptr[14]); MLA(hi, lo, (*fx)[2], ptr[12]); MLA(hi, lo, (*fx)[3], ptr[10]); MLA(hi, lo, (*fx)[4], ptr[ 8]); MLA(hi, lo, (*fx)[5], ptr[ 6]); MLA(hi, lo, (*fx)[6], ptr[ 4]); MLA(hi, lo, (*fx)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[0], ptr[ 0]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[7], ptr[ 2]); *pcm1++ = SHIFT(MLZ(hi, lo)); pcm2 = pcm1 + 14; for (sb = 1; sb < 16; ++sb) { ++fe; ++Dptr; /* D[32 - sb][i] == -D[sb][31 - i] */ if (!(sb & 1)) { ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); MLN(hi, lo); ptr = *Dptr + pe; MLA(hi, lo, (*fe)[7], ptr[ 2]); MLA(hi, lo, (*fe)[6], ptr[ 4]); MLA(hi, lo, (*fe)[5], ptr[ 6]); MLA(hi, lo, (*fe)[4], ptr[ 8]); MLA(hi, lo, (*fe)[3], ptr[10]); MLA(hi, lo, (*fe)[2], ptr[12]); MLA(hi, lo, (*fe)[1], ptr[14]); MLA(hi, lo, (*fe)[0], ptr[ 0]); *pcm1++ = SHIFT(MLZ(hi, lo)); ptr = *Dptr - po; ML0(hi, lo, (*fo)[7], ptr[31 - 2]); MLA(hi, lo, (*fo)[6], ptr[31 - 4]); MLA(hi, lo, (*fo)[5], ptr[31 - 6]); MLA(hi, lo, (*fo)[4], ptr[31 - 8]); MLA(hi, lo, (*fo)[3], ptr[31 - 10]); MLA(hi, lo, (*fo)[2], ptr[31 - 12]); MLA(hi, lo, (*fo)[1], ptr[31 - 14]); MLA(hi, lo, (*fo)[0], ptr[31 - 16]); ptr = *Dptr - pe; MLA(hi, lo, (*fe)[0], ptr[31 - 16]); MLA(hi, lo, (*fe)[1], ptr[31 - 14]); MLA(hi, lo, (*fe)[2], ptr[31 - 12]); MLA(hi, lo, (*fe)[3], ptr[31 - 10]); MLA(hi, lo, (*fe)[4], ptr[31 - 8]); MLA(hi, lo, (*fe)[5], ptr[31 - 6]); MLA(hi, lo, (*fe)[6], ptr[31 - 4]); MLA(hi, lo, (*fe)[7], ptr[31 - 2]); *pcm2-- = SHIFT(MLZ(hi, lo)); } ++fo; } ++Dptr; ptr = *Dptr + po; ML0(hi, lo, (*fo)[0], ptr[ 0]); MLA(hi, lo, (*fo)[1], ptr[14]); MLA(hi, lo, (*fo)[2], ptr[12]); MLA(hi, lo, (*fo)[3], ptr[10]); MLA(hi, lo, (*fo)[4], ptr[ 8]); MLA(hi, lo, (*fo)[5], ptr[ 6]); MLA(hi, lo, (*fo)[6], ptr[ 4]); MLA(hi, lo, (*fo)[7], ptr[ 2]); *pcm1 = SHIFT(-MLZ(hi, lo)); pcm1 += 8; phase = (phase + 1) % 16; } } } /* * NAME: synth->frame() * DESCRIPTION: perform PCM synthesis of frame subband samples */ void mad_synth_frame(struct mad_synth *synth, struct mad_frame const *frame) { unsigned int nch, ns; void (*synth_frame)(struct mad_synth *, struct mad_frame const *, unsigned int, unsigned int); nch = MAD_NCHANNELS(&frame->header); ns = MAD_NSBSAMPLES(&frame->header); synth->pcm.samplerate = frame->header.samplerate; synth->pcm.channels = nch; synth->pcm.length = 32 * ns; synth_frame = synth_full; if (frame->options & MAD_OPTION_HALFSAMPLERATE) { synth->pcm.samplerate /= 2; synth->pcm.length /= 2; synth_frame = synth_half; } synth_frame(synth, frame, nch, ns); synth->phase = (synth->phase + ns) % 16; } xine-lib-1.2/contrib/libmad/imdct_s.dat0000644000175000017500000000503714647725152015675 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: imdct_s.dat,v 1.8 2004/01/23 09:41:32 rob Exp $ */ /* 0 */ { MAD_F(0x09bd7ca0) /* 0.608761429 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x0216a2a2) /* -0.130526192 */, MAD_F(0x0fdcf549) /* 0.991444861 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x0cb19346) /* -0.793353340 */ }, /* 6 */ { -MAD_F(0x0cb19346) /* -0.793353340 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0fdcf549) /* 0.991444861 */, MAD_F(0x0216a2a2) /* 0.130526192 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x09bd7ca0) /* -0.608761429 */ }, /* 1 */ { MAD_F(0x061f78aa) /* 0.382683432 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, MAD_F(0x0ec835e8) /* 0.923879533 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x0ec835e8) /* 0.923879533 */ }, /* 7 */ { -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x061f78aa) /* 0.382683432 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x0ec835e8) /* 0.923879533 */, MAD_F(0x061f78aa) /* 0.382683432 */ }, /* 2 */ { MAD_F(0x0216a2a2) /* 0.130526192 */, -MAD_F(0x061f78aa) /* -0.382683432 */, MAD_F(0x09bd7ca0) /* 0.608761429 */, -MAD_F(0x0cb19346) /* -0.793353340 */, MAD_F(0x0ec835e8) /* 0.923879533 */, -MAD_F(0x0fdcf549) /* -0.991444861 */ }, /* 8 */ { -MAD_F(0x0fdcf549) /* -0.991444861 */, -MAD_F(0x0ec835e8) /* -0.923879533 */, -MAD_F(0x0cb19346) /* -0.793353340 */, -MAD_F(0x09bd7ca0) /* -0.608761429 */, -MAD_F(0x061f78aa) /* -0.382683432 */, -MAD_F(0x0216a2a2) /* -0.130526192 */ } xine-lib-1.2/contrib/libmad/rq_table.dat0000644000175000017500000166476714647725152016072 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: rq_table.dat,v 1.7 2004/01/23 09:41:32 rob Exp $ */ /* * This is the lookup table used to compute x^(4/3) for Layer III * requantization. To maintain the best possible accuracy, the value is * stored as a normalized mantissa with exponent. The requantization * algorithm recombines these parts with appropriate scaling. */ /* 0 */ { MAD_F(0x00000000) /* 0.000000000 */, 0 }, /* 1 */ { MAD_F(0x04000000) /* 0.250000000 */, 2 }, /* 2 */ { MAD_F(0x050a28be) /* 0.314980262 */, 3 }, /* 3 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 4 }, /* 4 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 4 }, /* 5 */ { MAD_F(0x04466275) /* 0.267183742 */, 5 }, /* 6 */ { MAD_F(0x05738c72) /* 0.340710111 */, 5 }, /* 7 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 5 }, /* 8 */ { MAD_F(0x04000000) /* 0.250000000 */, 6 }, /* 9 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 6 }, /* 10 */ { MAD_F(0x0562d694) /* 0.336630420 */, 6 }, /* 11 */ { MAD_F(0x061dae96) /* 0.382246578 */, 6 }, /* 12 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 6 }, /* 13 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 6 }, /* 14 */ { MAD_F(0x0437be65) /* 0.263609310 */, 7 }, /* 15 */ { MAD_F(0x049fc824) /* 0.289009227 */, 7 }, /* 16 */ { MAD_F(0x050a28be) /* 0.314980262 */, 7 }, /* 17 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 7 }, /* 18 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 7 }, /* 19 */ { MAD_F(0x06566361) /* 0.396090870 */, 7 }, /* 20 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 7 }, /* 21 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 7 }, /* 22 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 7 }, /* 23 */ { MAD_F(0x04168b05) /* 0.255503674 */, 8 }, /* 24 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 8 }, /* 25 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 8 }, /* 26 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 8 }, /* 27 */ { MAD_F(0x05100000) /* 0.316406250 */, 8 }, /* 28 */ { MAD_F(0x05506451) /* 0.332126919 */, 8 }, /* 29 */ { MAD_F(0x05918e15) /* 0.348035890 */, 8 }, /* 30 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 8 }, /* 31 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 8 }, /* 32 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 8 }, /* 33 */ { MAD_F(0x069d9400) /* 0.413471222 */, 8 }, /* 34 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 8 }, /* 35 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 8 }, /* 36 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 8 }, /* 37 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 8 }, /* 38 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 8 }, /* 39 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 9 }, /* 40 */ { MAD_F(0x04466275) /* 0.267183742 */, 9 }, /* 41 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 9 }, /* 42 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 9 }, /* 43 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 9 }, /* 44 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 9 }, /* 45 */ { MAD_F(0x05007b49) /* 0.312617576 */, 9 }, /* 46 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 9 }, /* 47 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 9 }, /* 48 */ { MAD_F(0x05738c72) /* 0.340710111 */, 9 }, /* 49 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 9 }, /* 50 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 9 }, /* 51 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 9 }, /* 52 */ { MAD_F(0x0610b982) /* 0.379083164 */, 9 }, /* 53 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 9 }, /* 54 */ { MAD_F(0x0660db91) /* 0.398646895 */, 9 }, /* 55 */ { MAD_F(0x06894c90) /* 0.408520284 */, 9 }, /* 56 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 9 }, /* 57 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 9 }, /* 58 */ { MAD_F(0x07041636) /* 0.438497744 */, 9 }, /* 59 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 9 }, /* 60 */ { MAD_F(0x075722ef) /* 0.458773552 */, 9 }, /* 61 */ { MAD_F(0x078102b8) /* 0.468996735 */, 9 }, /* 62 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 9 }, /* 63 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 9 }, /* 64 */ { MAD_F(0x04000000) /* 0.250000000 */, 10 }, /* 65 */ { MAD_F(0x04156381) /* 0.255221850 */, 10 }, /* 66 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 10 }, /* 67 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 10 }, /* 68 */ { MAD_F(0x045635cf) /* 0.271047409 */, 10 }, /* 69 */ { MAD_F(0x046c083e) /* 0.276375048 */, 10 }, /* 70 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 10 }, /* 71 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 10 }, /* 72 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 10 }, /* 73 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 10 }, /* 74 */ { MAD_F(0x04dab524) /* 0.303395408 */, 10 }, /* 75 */ { MAD_F(0x04f12624) /* 0.308874267 */, 10 }, /* 76 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 10 }, /* 77 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 10 }, /* 78 */ { MAD_F(0x053511cb) /* 0.325456423 */, 10 }, /* 79 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 10 }, /* 80 */ { MAD_F(0x0562d694) /* 0.336630420 */, 10 }, /* 81 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 10 }, /* 82 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 10 }, /* 83 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 10 }, /* 84 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 10 }, /* 85 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 10 }, /* 86 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 10 }, /* 87 */ { MAD_F(0x0606012b) /* 0.376465960 */, 10 }, /* 88 */ { MAD_F(0x061dae96) /* 0.382246578 */, 10 }, /* 89 */ { MAD_F(0x06357302) /* 0.388049134 */, 10 }, /* 90 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 10 }, /* 91 */ { MAD_F(0x0665402d) /* 0.399719406 */, 10 }, /* 92 */ { MAD_F(0x067d4896) /* 0.405586801 */, 10 }, /* 93 */ { MAD_F(0x06956753) /* 0.411475493 */, 10 }, /* 94 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 10 }, /* 95 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 10 }, /* 96 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 10 }, /* 97 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 10 }, /* 98 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 10 }, /* 99 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 10 }, /* 100 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 10 }, /* 101 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 10 }, /* 102 */ { MAD_F(0x07724f64) /* 0.465407744 */, 10 }, /* 103 */ { MAD_F(0x078b4514) /* 0.471501425 */, 10 }, /* 104 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 10 }, /* 105 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 10 }, /* 106 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 10 }, /* 107 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 10 }, /* 108 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 11 }, /* 109 */ { MAD_F(0x04115aca) /* 0.254236974 */, 11 }, /* 110 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 11 }, /* 111 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 11 }, /* 112 */ { MAD_F(0x0437be65) /* 0.263609310 */, 11 }, /* 113 */ { MAD_F(0x04449dee) /* 0.266752177 */, 11 }, /* 114 */ { MAD_F(0x04518733) /* 0.269904329 */, 11 }, /* 115 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 11 }, /* 116 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 11 }, /* 117 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 11 }, /* 118 */ { MAD_F(0x04858c83) /* 0.282604707 */, 11 }, /* 119 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 11 }, /* 120 */ { MAD_F(0x049fc824) /* 0.289009227 */, 11 }, /* 121 */ { MAD_F(0x04acf402) /* 0.292224893 */, 11 }, /* 122 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 11 }, /* 123 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 11 }, /* 124 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 11 }, /* 125 */ { MAD_F(0x04e20000) /* 0.305175781 */, 11 }, /* 126 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 11 }, /* 127 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 11 }, /* 128 */ { MAD_F(0x050a28be) /* 0.314980262 */, 11 }, /* 129 */ { MAD_F(0x05179da4) /* 0.318265572 */, 11 }, /* 130 */ { MAD_F(0x05251b73) /* 0.321559381 */, 11 }, /* 131 */ { MAD_F(0x0532a220) /* 0.324861647 */, 11 }, /* 132 */ { MAD_F(0x054031a0) /* 0.328172327 */, 11 }, /* 133 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 11 }, /* 134 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 11 }, /* 135 */ { MAD_F(0x0569149c) /* 0.338154423 */, 11 }, /* 136 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 11 }, /* 137 */ { MAD_F(0x058481e9) /* 0.344850455 */, 11 }, /* 138 */ { MAD_F(0x0592456d) /* 0.348210741 */, 11 }, /* 139 */ { MAD_F(0x05a01176) /* 0.351579152 */, 11 }, /* 140 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 11 }, /* 141 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 11 }, /* 142 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 11 }, /* 143 */ { MAD_F(0x05d79601) /* 0.365133291 */, 11 }, /* 144 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 11 }, /* 145 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 11 }, /* 146 */ { MAD_F(0x060190ee) /* 0.375382356 */, 11 }, /* 147 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 11 }, /* 148 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 11 }, /* 149 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 11 }, /* 150 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 11 }, /* 151 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 11 }, /* 152 */ { MAD_F(0x06566361) /* 0.396090870 */, 11 }, /* 153 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 11 }, /* 154 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 11 }, /* 155 */ { MAD_F(0x068138f3) /* 0.406548452 */, 11 }, /* 156 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 11 }, /* 157 */ { MAD_F(0x069deed1) /* 0.413557833 */, 11 }, /* 158 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 11 }, /* 159 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 11 }, /* 160 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 11 }, /* 161 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 11 }, /* 162 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 11 }, /* 163 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 11 }, /* 164 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 11 }, /* 165 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 11 }, /* 166 */ { MAD_F(0x0720a087) /* 0.445465593 */, 11 }, /* 167 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 11 }, /* 168 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 11 }, /* 169 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 11 }, /* 170 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 11 }, /* 171 */ { MAD_F(0x076a454c) /* 0.463444993 */, 11 }, /* 172 */ { MAD_F(0x07791620) /* 0.467062117 */, 11 }, /* 173 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 11 }, /* 174 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 11 }, /* 175 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 11 }, /* 176 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 11 }, /* 177 */ { MAD_F(0x07c39812) /* 0.485252449 */, 11 }, /* 178 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 11 }, /* 179 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 11 }, /* 180 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 11 }, /* 181 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 11 }, /* 182 */ { MAD_F(0x0407673f) /* 0.251807447 */, 12 }, /* 183 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 12 }, /* 184 */ { MAD_F(0x04168b05) /* 0.255503674 */, 12 }, /* 185 */ { MAD_F(0x041e2230) /* 0.257356825 */, 12 }, /* 186 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 12 }, /* 187 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 12 }, /* 188 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 12 }, /* 189 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 12 }, /* 190 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 12 }, /* 191 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 12 }, /* 192 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 12 }, /* 193 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 12 }, /* 194 */ { MAD_F(0x04630eed) /* 0.274184158 */, 12 }, /* 195 */ { MAD_F(0x046ac896) /* 0.276070203 */, 12 }, /* 196 */ { MAD_F(0x047285a2) /* 0.277959474 */, 12 }, /* 197 */ { MAD_F(0x047a460c) /* 0.279851960 */, 12 }, /* 198 */ { MAD_F(0x048209d3) /* 0.281747652 */, 12 }, /* 199 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 12 }, /* 200 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 12 }, /* 201 */ { MAD_F(0x04996935) /* 0.287453849 */, 12 }, /* 202 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 12 }, /* 203 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 12 }, /* 204 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 12 }, /* 205 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 12 }, /* 206 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 12 }, /* 207 */ { MAD_F(0x04c88135) /* 0.298951346 */, 12 }, /* 208 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 12 }, /* 209 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 12 }, /* 210 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 12 }, /* 211 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 12 }, /* 212 */ { MAD_F(0x04f01963) /* 0.308617963 */, 12 }, /* 213 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 12 }, /* 214 */ { MAD_F(0x05000655) /* 0.312506041 */, 12 }, /* 215 */ { MAD_F(0x05080195) /* 0.314454634 */, 12 }, /* 216 */ { MAD_F(0x05100000) /* 0.316406250 */, 12 }, /* 217 */ { MAD_F(0x05180194) /* 0.318360880 */, 12 }, /* 218 */ { MAD_F(0x0520064f) /* 0.320318516 */, 12 }, /* 219 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 12 }, /* 220 */ { MAD_F(0x0530192e) /* 0.324242764 */, 12 }, /* 221 */ { MAD_F(0x0538274e) /* 0.326209359 */, 12 }, /* 222 */ { MAD_F(0x0540388a) /* 0.328178922 */, 12 }, /* 223 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 12 }, /* 224 */ { MAD_F(0x05506451) /* 0.332126919 */, 12 }, /* 225 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 12 }, /* 226 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 12 }, /* 227 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 12 }, /* 228 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 12 }, /* 229 */ { MAD_F(0x05790793) /* 0.342048241 */, 12 }, /* 230 */ { MAD_F(0x05813162) /* 0.344041237 */, 12 }, /* 231 */ { MAD_F(0x05895e39) /* 0.346037122 */, 12 }, /* 232 */ { MAD_F(0x05918e15) /* 0.348035890 */, 12 }, /* 233 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 12 }, /* 234 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 12 }, /* 235 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 12 }, /* 236 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 12 }, /* 237 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 12 }, /* 238 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 12 }, /* 239 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 12 }, /* 240 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 12 }, /* 241 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 12 }, /* 242 */ { MAD_F(0x05e41105) /* 0.368180294 */, 12 }, /* 243 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 12 }, /* 244 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 12 }, /* 245 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 12 }, /* 246 */ { MAD_F(0x060564b1) /* 0.376316732 */, 12 }, /* 247 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 12 }, /* 248 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 12 }, /* 249 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 12 }, /* 250 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 12 }, /* 251 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 12 }, /* 252 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 12 }, /* 253 */ { MAD_F(0x06402666) /* 0.390661620 */, 12 }, /* 254 */ { MAD_F(0x064896a7) /* 0.392721798 */, 12 }, /* 255 */ { MAD_F(0x065109be) /* 0.394784681 */, 12 }, /* 256 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 12 }, /* 257 */ { MAD_F(0x0661f867) /* 0.398918536 */, 12 }, /* 258 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 12 }, /* 259 */ { MAD_F(0x0672f252) /* 0.403063128 */, 12 }, /* 260 */ { MAD_F(0x067b737c) /* 0.405139433 */, 12 }, /* 261 */ { MAD_F(0x0683f771) /* 0.407218402 */, 12 }, /* 262 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 12 }, /* 263 */ { MAD_F(0x069507b5) /* 0.411384303 */, 12 }, /* 264 */ { MAD_F(0x069d9400) /* 0.413471222 */, 12 }, /* 265 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 12 }, /* 266 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 12 }, /* 267 */ { MAD_F(0x06b74971) /* 0.419747773 */, 12 }, /* 268 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 12 }, /* 269 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 12 }, /* 270 */ { MAD_F(0x06d11794) /* 0.426047876 */, 12 }, /* 271 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 12 }, /* 272 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 12 }, /* 273 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 12 }, /* 274 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 12 }, /* 275 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 12 }, /* 276 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 12 }, /* 277 */ { MAD_F(0x070dacea) /* 0.440838732 */, 12 }, /* 278 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 12 }, /* 279 */ { MAD_F(0x071f1459) /* 0.445087765 */, 12 }, /* 280 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 12 }, /* 281 */ { MAD_F(0x07308671) /* 0.449346964 */, 12 }, /* 282 */ { MAD_F(0x07394378) /* 0.451480360 */, 12 }, /* 283 */ { MAD_F(0x07420325) /* 0.453616280 */, 12 }, /* 284 */ { MAD_F(0x074ac575) /* 0.455754717 */, 12 }, /* 285 */ { MAD_F(0x07538a67) /* 0.457895665 */, 12 }, /* 286 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 12 }, /* 287 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 12 }, /* 288 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 12 }, /* 289 */ { MAD_F(0x0776b867) /* 0.466484455 */, 12 }, /* 290 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 12 }, /* 291 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 12 }, /* 292 */ { MAD_F(0x07913641) /* 0.472952132 */, 12 }, /* 293 */ { MAD_F(0x079a100c) /* 0.475112962 */, 12 }, /* 294 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 12 }, /* 295 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 12 }, /* 296 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 12 }, /* 297 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 12 }, /* 298 */ { MAD_F(0x07c67798) /* 0.485953899 */, 12 }, /* 299 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 12 }, /* 300 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 12 }, /* 301 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 12 }, /* 302 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 12 }, /* 303 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 12 }, /* 304 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 12 }, /* 305 */ { MAD_F(0x0402868e) /* 0.250616605 */, 13 }, /* 306 */ { MAD_F(0x040703ff) /* 0.251712795 */, 13 }, /* 307 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 13 }, /* 308 */ { MAD_F(0x041002a1) /* 0.253908756 */, 13 }, /* 309 */ { MAD_F(0x041483d1) /* 0.255008523 */, 13 }, /* 310 */ { MAD_F(0x04190640) /* 0.256109476 */, 13 }, /* 311 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 13 }, /* 312 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 13 }, /* 313 */ { MAD_F(0x042694fe) /* 0.259419433 */, 13 }, /* 314 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 13 }, /* 315 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 13 }, /* 316 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 13 }, /* 317 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 13 }, /* 318 */ { MAD_F(0x043d4635) /* 0.264959533 */, 13 }, /* 319 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 13 }, /* 320 */ { MAD_F(0x04466275) /* 0.267183742 */, 13 }, /* 321 */ { MAD_F(0x044af269) /* 0.268297587 */, 13 }, /* 322 */ { MAD_F(0x044f8393) /* 0.269412589 */, 13 }, /* 323 */ { MAD_F(0x045415f3) /* 0.270528746 */, 13 }, /* 324 */ { MAD_F(0x0458a989) /* 0.271646056 */, 13 }, /* 325 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 13 }, /* 326 */ { MAD_F(0x0461d451) /* 0.273884123 */, 13 }, /* 327 */ { MAD_F(0x04666b83) /* 0.275004875 */, 13 }, /* 328 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 13 }, /* 329 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 13 }, /* 330 */ { MAD_F(0x04743847) /* 0.278373983 */, 13 }, /* 331 */ { MAD_F(0x0478d440) /* 0.279499294 */, 13 }, /* 332 */ { MAD_F(0x047d716a) /* 0.280625739 */, 13 }, /* 333 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 13 }, /* 334 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 13 }, /* 335 */ { MAD_F(0x048b5003) /* 0.284011853 */, 13 }, /* 336 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 13 }, /* 337 */ { MAD_F(0x049494fb) /* 0.286274891 */, 13 }, /* 338 */ { MAD_F(0x0499393a) /* 0.287408091 */, 13 }, /* 339 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 13 }, /* 340 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 13 }, /* 341 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 13 }, /* 342 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 13 }, /* 343 */ { MAD_F(0x04b08000) /* 0.293090820 */, 13 }, /* 344 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 13 }, /* 345 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 13 }, /* 346 */ { MAD_F(0x04be8537) /* 0.296513762 */, 13 }, /* 347 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 13 }, /* 348 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 13 }, /* 349 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 13 }, /* 350 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 13 }, /* 351 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 13 }, /* 352 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 13 }, /* 353 */ { MAD_F(0x04df6458) /* 0.304539056 */, 13 }, /* 354 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 13 }, /* 355 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 13 }, /* 356 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 13 }, /* 357 */ { MAD_F(0x04f24618) /* 0.309148880 */, 13 }, /* 358 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 13 }, /* 359 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 13 }, /* 360 */ { MAD_F(0x05007b49) /* 0.312617576 */, 13 }, /* 361 */ { MAD_F(0x050539ef) /* 0.313775954 */, 13 }, /* 362 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 13 }, /* 363 */ { MAD_F(0x050eba98) /* 0.316095920 */, 13 }, /* 364 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 13 }, /* 365 */ { MAD_F(0x05183fba) /* 0.318420150 */, 13 }, /* 366 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 13 }, /* 367 */ { MAD_F(0x0521c950) /* 0.320748629 */, 13 }, /* 368 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 13 }, /* 369 */ { MAD_F(0x052b5757) /* 0.323081342 */, 13 }, /* 370 */ { MAD_F(0x05302003) /* 0.324249281 */, 13 }, /* 371 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 13 }, /* 372 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 13 }, /* 373 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 13 }, /* 374 */ { MAD_F(0x05434db9) /* 0.328931546 */, 13 }, /* 375 */ { MAD_F(0x05481be5) /* 0.330104730 */, 13 }, /* 376 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 13 }, /* 377 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 13 }, /* 378 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 13 }, /* 379 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 13 }, /* 380 */ { MAD_F(0x05603321) /* 0.335986261 */, 13 }, /* 381 */ { MAD_F(0x056507d6) /* 0.337165677 */, 13 }, /* 382 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 13 }, /* 383 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 13 }, /* 384 */ { MAD_F(0x05738c72) /* 0.340710111 */, 13 }, /* 385 */ { MAD_F(0x05786578) /* 0.341893646 */, 13 }, /* 386 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 13 }, /* 387 */ { MAD_F(0x05821abf) /* 0.344263788 */, 13 }, /* 388 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 13 }, /* 389 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 13 }, /* 390 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 13 }, /* 391 */ { MAD_F(0x05959222) /* 0.349016318 */, 13 }, /* 392 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 13 }, /* 393 */ { MAD_F(0x059f5438) /* 0.351398678 */, 13 }, /* 394 */ { MAD_F(0x05a436da) /* 0.352591376 */, 13 }, /* 395 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 13 }, /* 396 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 13 }, /* 397 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 13 }, /* 398 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 13 }, /* 399 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 13 }, /* 400 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 13 }, /* 401 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 13 }, /* 402 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 13 }, /* 403 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 13 }, /* 404 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 13 }, /* 405 */ { MAD_F(0x05da394d) /* 0.365777304 */, 13 }, /* 406 */ { MAD_F(0x05df2885) /* 0.366982004 */, 13 }, /* 407 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 13 }, /* 408 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 13 }, /* 409 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 13 }, /* 410 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 13 }, /* 411 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 13 }, /* 412 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 13 }, /* 413 */ { MAD_F(0x0601d004) /* 0.375442522 */, 13 }, /* 414 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 13 }, /* 415 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 13 }, /* 416 */ { MAD_F(0x0610b982) /* 0.379083164 */, 13 }, /* 417 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 13 }, /* 418 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 13 }, /* 419 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 13 }, /* 420 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 13 }, /* 421 */ { MAD_F(0x0629a863) /* 0.385170352 */, 13 }, /* 422 */ { MAD_F(0x062ea802) /* 0.386390694 */, 13 }, /* 423 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 13 }, /* 424 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 13 }, /* 425 */ { MAD_F(0x063dacee) /* 0.390057497 */, 13 }, /* 426 */ { MAD_F(0x0642b096) /* 0.391281687 */, 13 }, /* 427 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 13 }, /* 428 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 13 }, /* 429 */ { MAD_F(0x0651c193) /* 0.394959999 */, 13 }, /* 430 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 13 }, /* 431 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 13 }, /* 432 */ { MAD_F(0x0660db91) /* 0.398646895 */, 13 }, /* 433 */ { MAD_F(0x0665e639) /* 0.399877761 */, 13 }, /* 434 */ { MAD_F(0x066af1df) /* 0.401109575 */, 13 }, /* 435 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 13 }, /* 436 */ { MAD_F(0x06750c26) /* 0.403576041 */, 13 }, /* 437 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 13 }, /* 438 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 13 }, /* 439 */ { MAD_F(0x06843afb) /* 0.407282813 */, 13 }, /* 440 */ { MAD_F(0x06894c90) /* 0.408520284 */, 13 }, /* 441 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 13 }, /* 442 */ { MAD_F(0x069372ae) /* 0.410998038 */, 13 }, /* 443 */ { MAD_F(0x06988735) /* 0.412238319 */, 13 }, /* 444 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 13 }, /* 445 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 13 }, /* 446 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 13 }, /* 447 */ { MAD_F(0x06ace318) /* 0.417208762 */, 13 }, /* 448 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 13 }, /* 449 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 13 }, /* 450 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 13 }, /* 451 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 13 }, /* 452 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 13 }, /* 453 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 13 }, /* 454 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 13 }, /* 455 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 13 }, /* 456 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 13 }, /* 457 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 13 }, /* 458 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 13 }, /* 459 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 13 }, /* 460 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 13 }, /* 461 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 13 }, /* 462 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 13 }, /* 463 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 13 }, /* 464 */ { MAD_F(0x07041636) /* 0.438497744 */, 13 }, /* 465 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 13 }, /* 466 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 13 }, /* 467 */ { MAD_F(0x07139641) /* 0.442281965 */, 13 }, /* 468 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 13 }, /* 469 */ { MAD_F(0x071df058) /* 0.444809288 */, 13 }, /* 470 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 13 }, /* 471 */ { MAD_F(0x07284e34) /* 0.447340205 */, 13 }, /* 472 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 13 }, /* 473 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 13 }, /* 474 */ { MAD_F(0x0737e209) /* 0.451143300 */, 13 }, /* 475 */ { MAD_F(0x073d1530) /* 0.452412785 */, 13 }, /* 476 */ { MAD_F(0x07424946) /* 0.453683161 */, 13 }, /* 477 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 13 }, /* 478 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 13 }, /* 479 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 13 }, /* 480 */ { MAD_F(0x075722ef) /* 0.458773552 */, 13 }, /* 481 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 13 }, /* 482 */ { MAD_F(0x07619557) /* 0.461324062 */, 13 }, /* 483 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 13 }, /* 484 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 13 }, /* 485 */ { MAD_F(0x077147e2) /* 0.465156443 */, 13 }, /* 486 */ { MAD_F(0x0776853e) /* 0.466435663 */, 13 }, /* 487 */ { MAD_F(0x077bc385) /* 0.467715761 */, 13 }, /* 488 */ { MAD_F(0x078102b8) /* 0.468996735 */, 13 }, /* 489 */ { MAD_F(0x078642d6) /* 0.470278584 */, 13 }, /* 490 */ { MAD_F(0x078b83de) /* 0.471561307 */, 13 }, /* 491 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 13 }, /* 492 */ { MAD_F(0x079608ae) /* 0.474129372 */, 13 }, /* 493 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 13 }, /* 494 */ { MAD_F(0x07a09124) /* 0.476700918 */, 13 }, /* 495 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 13 }, /* 496 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 13 }, /* 497 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 13 }, /* 498 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 13 }, /* 499 */ { MAD_F(0x07baf635) /* 0.483144957 */, 13 }, /* 500 */ { MAD_F(0x07c04056) /* 0.484436356 */, 13 }, /* 501 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 13 }, /* 502 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 13 }, /* 503 */ { MAD_F(0x07d02424) /* 0.488315717 */, 13 }, /* 504 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 13 }, /* 505 */ { MAD_F(0x07dac083) /* 0.490906249 */, 13 }, /* 506 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 13 }, /* 507 */ { MAD_F(0x07e56078) /* 0.493500203 */, 13 }, /* 508 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 13 }, /* 509 */ { MAD_F(0x07f00401) /* 0.496097570 */, 13 }, /* 510 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 13 }, /* 511 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 13 }, /* 512 */ { MAD_F(0x04000000) /* 0.250000000 */, 14 }, /* 513 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 14 }, /* 514 */ { MAD_F(0x04055638) /* 0.251302930 */, 14 }, /* 515 */ { MAD_F(0x040801ff) /* 0.251955030 */, 14 }, /* 516 */ { MAD_F(0x040aae37) /* 0.252607552 */, 14 }, /* 517 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 14 }, /* 518 */ { MAD_F(0x041007fa) /* 0.253913860 */, 14 }, /* 519 */ { MAD_F(0x0412b586) /* 0.254567645 */, 14 }, /* 520 */ { MAD_F(0x04156381) /* 0.255221850 */, 14 }, /* 521 */ { MAD_F(0x041811ee) /* 0.255876475 */, 14 }, /* 522 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 14 }, /* 523 */ { MAD_F(0x041d7018) /* 0.257186980 */, 14 }, /* 524 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 14 }, /* 525 */ { MAD_F(0x0422d003) /* 0.258499157 */, 14 }, /* 526 */ { MAD_F(0x042580a0) /* 0.259155872 */, 14 }, /* 527 */ { MAD_F(0x042831ad) /* 0.259813002 */, 14 }, /* 528 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 14 }, /* 529 */ { MAD_F(0x042d9516) /* 0.261128510 */, 14 }, /* 530 */ { MAD_F(0x04304772) /* 0.261786886 */, 14 }, /* 531 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 14 }, /* 532 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 14 }, /* 533 */ { MAD_F(0x0438611f) /* 0.263764497 */, 14 }, /* 534 */ { MAD_F(0x043b1536) /* 0.264424527 */, 14 }, /* 535 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 14 }, /* 536 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 14 }, /* 537 */ { MAD_F(0x04433414) /* 0.266407088 */, 14 }, /* 538 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 14 }, /* 539 */ { MAD_F(0x0448a024) /* 0.267730848 */, 14 }, /* 540 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 14 }, /* 541 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 14 }, /* 542 */ { MAD_F(0x0450c575) /* 0.269719560 */, 14 }, /* 543 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 14 }, /* 544 */ { MAD_F(0x045635cf) /* 0.271047409 */, 14 }, /* 545 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 14 }, /* 546 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 14 }, /* 547 */ { MAD_F(0x045e6188) /* 0.273042234 */, 14 }, /* 548 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 14 }, /* 549 */ { MAD_F(0x0463d625) /* 0.274374147 */, 14 }, /* 550 */ { MAD_F(0x04669116) /* 0.275040710 */, 14 }, /* 551 */ { MAD_F(0x04694c74) /* 0.275707677 */, 14 }, /* 552 */ { MAD_F(0x046c083e) /* 0.276375048 */, 14 }, /* 553 */ { MAD_F(0x046ec474) /* 0.277042822 */, 14 }, /* 554 */ { MAD_F(0x04718116) /* 0.277710999 */, 14 }, /* 555 */ { MAD_F(0x04743e25) /* 0.278379578 */, 14 }, /* 556 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 14 }, /* 557 */ { MAD_F(0x0479b984) /* 0.279717940 */, 14 }, /* 558 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 14 }, /* 559 */ { MAD_F(0x047f3693) /* 0.281057905 */, 14 }, /* 560 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 14 }, /* 561 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 14 }, /* 562 */ { MAD_F(0x0487754c) /* 0.283070849 */, 14 }, /* 563 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 14 }, /* 564 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 14 }, /* 565 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 14 }, /* 566 */ { MAD_F(0x04927972) /* 0.285760350 */, 14 }, /* 567 */ { MAD_F(0x04953b85) /* 0.286433717 */, 14 }, /* 568 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 14 }, /* 569 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 14 }, /* 570 */ { MAD_F(0x049d843e) /* 0.288456194 */, 14 }, /* 571 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 14 }, /* 572 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 14 }, /* 573 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 14 }, /* 574 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 14 }, /* 575 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 14 }, /* 576 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 14 }, /* 577 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 14 }, /* 578 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 14 }, /* 579 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 14 }, /* 580 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 14 }, /* 581 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 14 }, /* 582 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 14 }, /* 583 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 14 }, /* 584 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 14 }, /* 585 */ { MAD_F(0x04c72771) /* 0.298621598 */, 14 }, /* 586 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 14 }, /* 587 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 14 }, /* 588 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 14 }, /* 589 */ { MAD_F(0x04d25169) /* 0.301347172 */, 14 }, /* 590 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 14 }, /* 591 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 14 }, /* 592 */ { MAD_F(0x04dab524) /* 0.303395408 */, 14 }, /* 593 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 14 }, /* 594 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 14 }, /* 595 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 14 }, /* 596 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 14 }, /* 597 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 14 }, /* 598 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 14 }, /* 599 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 14 }, /* 600 */ { MAD_F(0x04f12624) /* 0.308874267 */, 14 }, /* 601 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 14 }, /* 602 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 14 }, /* 603 */ { MAD_F(0x04f99721) /* 0.310935143 */, 14 }, /* 604 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 14 }, /* 605 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 14 }, /* 606 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 14 }, /* 607 */ { MAD_F(0x0504de05) /* 0.313688296 */, 14 }, /* 608 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 14 }, /* 609 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 14 }, /* 610 */ { MAD_F(0x050d575b) /* 0.315757136 */, 14 }, /* 611 */ { MAD_F(0x05102b42) /* 0.316447504 */, 14 }, /* 612 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 14 }, /* 613 */ { MAD_F(0x0515d440) /* 0.317829370 */, 14 }, /* 614 */ { MAD_F(0x0518a956) /* 0.318520867 */, 14 }, /* 615 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 14 }, /* 616 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 14 }, /* 617 */ { MAD_F(0x05212af5) /* 0.320597609 */, 14 }, /* 618 */ { MAD_F(0x0524019e) /* 0.321290606 */, 14 }, /* 619 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 14 }, /* 620 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 14 }, /* 621 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 14 }, /* 622 */ { MAD_F(0x052f602c) /* 0.324066327 */, 14 }, /* 623 */ { MAD_F(0x053238ca) /* 0.324761189 */, 14 }, /* 624 */ { MAD_F(0x053511cb) /* 0.325456423 */, 14 }, /* 625 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 14 }, /* 626 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 14 }, /* 627 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 14 }, /* 628 */ { MAD_F(0x054079b5) /* 0.328241070 */, 14 }, /* 629 */ { MAD_F(0x054354a8) /* 0.328938157 */, 14 }, /* 630 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 14 }, /* 631 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 14 }, /* 632 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 14 }, /* 633 */ { MAD_F(0x054ec453) /* 0.331730198 */, 14 }, /* 634 */ { MAD_F(0x0551a134) /* 0.332429129 */, 14 }, /* 635 */ { MAD_F(0x05547e79) /* 0.333128427 */, 14 }, /* 636 */ { MAD_F(0x05575c20) /* 0.333828093 */, 14 }, /* 637 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 14 }, /* 638 */ { MAD_F(0x055d1896) /* 0.335228525 */, 14 }, /* 639 */ { MAD_F(0x055ff764) /* 0.335929290 */, 14 }, /* 640 */ { MAD_F(0x0562d694) /* 0.336630420 */, 14 }, /* 641 */ { MAD_F(0x0565b627) /* 0.337331916 */, 14 }, /* 642 */ { MAD_F(0x0568961b) /* 0.338033777 */, 14 }, /* 643 */ { MAD_F(0x056b7671) /* 0.338736002 */, 14 }, /* 644 */ { MAD_F(0x056e5729) /* 0.339438592 */, 14 }, /* 645 */ { MAD_F(0x05713843) /* 0.340141545 */, 14 }, /* 646 */ { MAD_F(0x057419be) /* 0.340844862 */, 14 }, /* 647 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 14 }, /* 648 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 14 }, /* 649 */ { MAD_F(0x057cc077) /* 0.342956988 */, 14 }, /* 650 */ { MAD_F(0x057fa378) /* 0.343661754 */, 14 }, /* 651 */ { MAD_F(0x058286d9) /* 0.344366882 */, 14 }, /* 652 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 14 }, /* 653 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 14 }, /* 654 */ { MAD_F(0x058b3342) /* 0.346484431 */, 14 }, /* 655 */ { MAD_F(0x058e1827) /* 0.347191002 */, 14 }, /* 656 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 14 }, /* 657 */ { MAD_F(0x0593e311) /* 0.348605221 */, 14 }, /* 658 */ { MAD_F(0x0596c917) /* 0.349312869 */, 14 }, /* 659 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 14 }, /* 660 */ { MAD_F(0x059c9643) /* 0.350729240 */, 14 }, /* 661 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 14 }, /* 662 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 14 }, /* 663 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 14 }, /* 664 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 14 }, /* 665 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 14 }, /* 666 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 14 }, /* 667 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 14 }, /* 668 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 14 }, /* 669 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 14 }, /* 670 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 14 }, /* 671 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 14 }, /* 672 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 14 }, /* 673 */ { MAD_F(0x05c27057) /* 0.359970419 */, 14 }, /* 674 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 14 }, /* 675 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 14 }, /* 676 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 14 }, /* 677 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 14 }, /* 678 */ { MAD_F(0x05d11001) /* 0.363540655 */, 14 }, /* 679 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 14 }, /* 680 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 14 }, /* 681 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 14 }, /* 682 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 14 }, /* 683 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 14 }, /* 684 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 14 }, /* 685 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 14 }, /* 686 */ { MAD_F(0x05e88904) /* 0.369271294 */, 14 }, /* 687 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 14 }, /* 688 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 14 }, /* 689 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 14 }, /* 690 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 14 }, /* 691 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 14 }, /* 692 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 14 }, /* 693 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 14 }, /* 694 */ { MAD_F(0x0600196e) /* 0.375024253 */, 14 }, /* 695 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 14 }, /* 696 */ { MAD_F(0x0606012b) /* 0.376465960 */, 14 }, /* 697 */ { MAD_F(0x0608f595) /* 0.377187332 */, 14 }, /* 698 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 14 }, /* 699 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 14 }, /* 700 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 14 }, /* 701 */ { MAD_F(0x0614cada) /* 0.380076266 */, 14 }, /* 702 */ { MAD_F(0x0617c112) /* 0.380799360 */, 14 }, /* 703 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 14 }, /* 704 */ { MAD_F(0x061dae96) /* 0.382246578 */, 14 }, /* 705 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 14 }, /* 706 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 14 }, /* 707 */ { MAD_F(0x0626958f) /* 0.384419975 */, 14 }, /* 708 */ { MAD_F(0x06298def) /* 0.385145124 */, 14 }, /* 709 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 14 }, /* 710 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 14 }, /* 711 */ { MAD_F(0x06327934) /* 0.387322621 */, 14 }, /* 712 */ { MAD_F(0x06357302) /* 0.388049134 */, 14 }, /* 713 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 14 }, /* 714 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 14 }, /* 715 */ { MAD_F(0x063e6290) /* 0.390230715 */, 14 }, /* 716 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 14 }, /* 717 */ { MAD_F(0x06445960) /* 0.391686799 */, 14 }, /* 718 */ { MAD_F(0x06475551) /* 0.392415349 */, 14 }, /* 719 */ { MAD_F(0x064a519c) /* 0.393144238 */, 14 }, /* 720 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 14 }, /* 721 */ { MAD_F(0x06504b44) /* 0.394603028 */, 14 }, /* 722 */ { MAD_F(0x0653489f) /* 0.395332930 */, 14 }, /* 723 */ { MAD_F(0x06564655) /* 0.396063168 */, 14 }, /* 724 */ { MAD_F(0x06594465) /* 0.396793743 */, 14 }, /* 725 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 14 }, /* 726 */ { MAD_F(0x065f4195) /* 0.398255903 */, 14 }, /* 727 */ { MAD_F(0x066240b4) /* 0.398987487 */, 14 }, /* 728 */ { MAD_F(0x0665402d) /* 0.399719406 */, 14 }, /* 729 */ { MAD_F(0x06684000) /* 0.400451660 */, 14 }, /* 730 */ { MAD_F(0x066b402d) /* 0.401184249 */, 14 }, /* 731 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 14 }, /* 732 */ { MAD_F(0x06714194) /* 0.402650431 */, 14 }, /* 733 */ { MAD_F(0x067442ce) /* 0.403384024 */, 14 }, /* 734 */ { MAD_F(0x06774462) /* 0.404117949 */, 14 }, /* 735 */ { MAD_F(0x067a464f) /* 0.404852209 */, 14 }, /* 736 */ { MAD_F(0x067d4896) /* 0.405586801 */, 14 }, /* 737 */ { MAD_F(0x06804b36) /* 0.406321726 */, 14 }, /* 738 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 14 }, /* 739 */ { MAD_F(0x06865181) /* 0.407792573 */, 14 }, /* 740 */ { MAD_F(0x0689552c) /* 0.408528495 */, 14 }, /* 741 */ { MAD_F(0x068c5931) /* 0.409264748 */, 14 }, /* 742 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 14 }, /* 743 */ { MAD_F(0x06926245) /* 0.410738247 */, 14 }, /* 744 */ { MAD_F(0x06956753) /* 0.411475493 */, 14 }, /* 745 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 14 }, /* 746 */ { MAD_F(0x069b727b) /* 0.412950976 */, 14 }, /* 747 */ { MAD_F(0x069e7894) /* 0.413689213 */, 14 }, /* 748 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 14 }, /* 749 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 14 }, /* 750 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 14 }, /* 751 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 14 }, /* 752 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 14 }, /* 753 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 14 }, /* 754 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 14 }, /* 755 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 14 }, /* 756 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 14 }, /* 757 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 14 }, /* 758 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 14 }, /* 759 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 14 }, /* 760 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 14 }, /* 761 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 14 }, /* 762 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 14 }, /* 763 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 14 }, /* 764 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 14 }, /* 765 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 14 }, /* 766 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 14 }, /* 767 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 14 }, /* 768 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 14 }, /* 769 */ { MAD_F(0x06e15595) /* 0.430013259 */, 14 }, /* 770 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 14 }, /* 771 */ { MAD_F(0x06e771db) /* 0.431505065 */, 14 }, /* 772 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 14 }, /* 773 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 14 }, /* 774 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 14 }, /* 775 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 14 }, /* 776 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 14 }, /* 777 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 14 }, /* 778 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 14 }, /* 779 */ { MAD_F(0x06fff073) /* 0.437485172 */, 14 }, /* 780 */ { MAD_F(0x070301ca) /* 0.438234130 */, 14 }, /* 781 */ { MAD_F(0x07061377) /* 0.438983408 */, 14 }, /* 782 */ { MAD_F(0x0709257a) /* 0.439733006 */, 14 }, /* 783 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 14 }, /* 784 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 14 }, /* 785 */ { MAD_F(0x07125d84) /* 0.441983717 */, 14 }, /* 786 */ { MAD_F(0x071570de) /* 0.442734592 */, 14 }, /* 787 */ { MAD_F(0x0718848d) /* 0.443485785 */, 14 }, /* 788 */ { MAD_F(0x071b9891) /* 0.444237296 */, 14 }, /* 789 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 14 }, /* 790 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 14 }, /* 791 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 14 }, /* 792 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 14 }, /* 793 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 14 }, /* 794 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 14 }, /* 795 */ { MAD_F(0x07312e01) /* 0.449506765 */, 14 }, /* 796 */ { MAD_F(0x073444ae) /* 0.450260813 */, 14 }, /* 797 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 14 }, /* 798 */ { MAD_F(0x073a7307) /* 0.451769856 */, 14 }, /* 799 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 14 }, /* 800 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 14 }, /* 801 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 14 }, /* 802 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 14 }, /* 803 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 14 }, /* 804 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 14 }, /* 805 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 14 }, /* 806 */ { MAD_F(0x0753399d) /* 0.457818618 */, 14 }, /* 807 */ { MAD_F(0x075653eb) /* 0.458576125 */, 14 }, /* 808 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 14 }, /* 809 */ { MAD_F(0x075c8983) /* 0.460092079 */, 14 }, /* 810 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 14 }, /* 811 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 14 }, /* 812 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 14 }, /* 813 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 14 }, /* 814 */ { MAD_F(0x076c1538) /* 0.463887426 */, 14 }, /* 815 */ { MAD_F(0x076f3224) /* 0.464647430 */, 14 }, /* 816 */ { MAD_F(0x07724f64) /* 0.465407744 */, 14 }, /* 817 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 14 }, /* 818 */ { MAD_F(0x07788add) /* 0.466929306 */, 14 }, /* 819 */ { MAD_F(0x077ba916) /* 0.467690552 */, 14 }, /* 820 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 14 }, /* 821 */ { MAD_F(0x0781e683) /* 0.469213973 */, 14 }, /* 822 */ { MAD_F(0x078505b5) /* 0.469976148 */, 14 }, /* 823 */ { MAD_F(0x0788253b) /* 0.470738632 */, 14 }, /* 824 */ { MAD_F(0x078b4514) /* 0.471501425 */, 14 }, /* 825 */ { MAD_F(0x078e653f) /* 0.472264527 */, 14 }, /* 826 */ { MAD_F(0x079185be) /* 0.473027937 */, 14 }, /* 827 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 14 }, /* 828 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 14 }, /* 829 */ { MAD_F(0x079ae929) /* 0.475320014 */, 14 }, /* 830 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 14 }, /* 831 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 14 }, /* 832 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 14 }, /* 833 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 14 }, /* 834 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 14 }, /* 835 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 14 }, /* 836 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 14 }, /* 837 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 14 }, /* 838 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 14 }, /* 839 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 14 }, /* 840 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 14 }, /* 841 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 14 }, /* 842 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 14 }, /* 843 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 14 }, /* 844 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 14 }, /* 845 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 14 }, /* 846 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 14 }, /* 847 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 14 }, /* 848 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 14 }, /* 849 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 14 }, /* 850 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 14 }, /* 851 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 14 }, /* 852 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 14 }, /* 853 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 14 }, /* 854 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 14 }, /* 855 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 14 }, /* 856 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 14 }, /* 857 */ { MAD_F(0x07f31405) /* 0.496845266 */, 14 }, /* 858 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 14 }, /* 859 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 14 }, /* 860 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 14 }, /* 861 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 14 }, /* 862 */ { MAD_F(0x04017659) /* 0.250357008 */, 15 }, /* 863 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 15 }, /* 864 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 15 }, /* 865 */ { MAD_F(0x0406393d) /* 0.251519431 */, 15 }, /* 866 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 15 }, /* 867 */ { MAD_F(0x0409669d) /* 0.252295127 */, 15 }, /* 868 */ { MAD_F(0x040afd89) /* 0.252683198 */, 15 }, /* 869 */ { MAD_F(0x040c949e) /* 0.253071419 */, 15 }, /* 870 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 15 }, /* 871 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 15 }, /* 872 */ { MAD_F(0x04115aca) /* 0.254236974 */, 15 }, /* 873 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 15 }, /* 874 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 15 }, /* 875 */ { MAD_F(0x0416225d) /* 0.255403867 */, 15 }, /* 876 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 15 }, /* 877 */ { MAD_F(0x041952dc) /* 0.256182537 */, 15 }, /* 878 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 15 }, /* 879 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 15 }, /* 880 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 15 }, /* 881 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 15 }, /* 882 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 15 }, /* 883 */ { MAD_F(0x0422e811) /* 0.258522097 */, 15 }, /* 884 */ { MAD_F(0x04248179) /* 0.258912540 */, 15 }, /* 885 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 15 }, /* 886 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 15 }, /* 887 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 15 }, /* 888 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 15 }, /* 889 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 15 }, /* 890 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 15 }, /* 891 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 15 }, /* 892 */ { MAD_F(0x0431524c) /* 0.262041376 */, 15 }, /* 893 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 15 }, /* 894 */ { MAD_F(0x0434880a) /* 0.262825051 */, 15 }, /* 895 */ { MAD_F(0x04362324) /* 0.263217107 */, 15 }, /* 896 */ { MAD_F(0x0437be65) /* 0.263609310 */, 15 }, /* 897 */ { MAD_F(0x043959cd) /* 0.264001659 */, 15 }, /* 898 */ { MAD_F(0x043af55d) /* 0.264394153 */, 15 }, /* 899 */ { MAD_F(0x043c9113) /* 0.264786794 */, 15 }, /* 900 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 15 }, /* 901 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 15 }, /* 902 */ { MAD_F(0x04416522) /* 0.265965588 */, 15 }, /* 903 */ { MAD_F(0x04430174) /* 0.266358810 */, 15 }, /* 904 */ { MAD_F(0x04449dee) /* 0.266752177 */, 15 }, /* 905 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 15 }, /* 906 */ { MAD_F(0x0447d756) /* 0.267539347 */, 15 }, /* 907 */ { MAD_F(0x04497445) /* 0.267933149 */, 15 }, /* 908 */ { MAD_F(0x044b115a) /* 0.268327096 */, 15 }, /* 909 */ { MAD_F(0x044cae96) /* 0.268721187 */, 15 }, /* 910 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 15 }, /* 911 */ { MAD_F(0x044fe983) /* 0.269509804 */, 15 }, /* 912 */ { MAD_F(0x04518733) /* 0.269904329 */, 15 }, /* 913 */ { MAD_F(0x0453250a) /* 0.270298998 */, 15 }, /* 914 */ { MAD_F(0x0454c308) /* 0.270693811 */, 15 }, /* 915 */ { MAD_F(0x0456612d) /* 0.271088768 */, 15 }, /* 916 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 15 }, /* 917 */ { MAD_F(0x04599dea) /* 0.271879114 */, 15 }, /* 918 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 15 }, /* 919 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 15 }, /* 920 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 15 }, /* 921 */ { MAD_F(0x04601932) /* 0.273461530 */, 15 }, /* 922 */ { MAD_F(0x0461b864) /* 0.273857492 */, 15 }, /* 923 */ { MAD_F(0x046357bd) /* 0.274253597 */, 15 }, /* 924 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 15 }, /* 925 */ { MAD_F(0x046696e2) /* 0.275046238 */, 15 }, /* 926 */ { MAD_F(0x046836ae) /* 0.275442772 */, 15 }, /* 927 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 15 }, /* 928 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 15 }, /* 929 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 15 }, /* 930 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 15 }, /* 931 */ { MAD_F(0x047057e8) /* 0.277427584 */, 15 }, /* 932 */ { MAD_F(0x0471f899) /* 0.277824973 */, 15 }, /* 933 */ { MAD_F(0x04739971) /* 0.278222505 */, 15 }, /* 934 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 15 }, /* 935 */ { MAD_F(0x0476db92) /* 0.279017995 */, 15 }, /* 936 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 15 }, /* 937 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 15 }, /* 938 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 15 }, /* 939 */ { MAD_F(0x047d619e) /* 0.280610675 */, 15 }, /* 940 */ { MAD_F(0x047f0380) /* 0.281009199 */, 15 }, /* 941 */ { MAD_F(0x0480a588) /* 0.281407864 */, 15 }, /* 942 */ { MAD_F(0x048247b6) /* 0.281806670 */, 15 }, /* 943 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 15 }, /* 944 */ { MAD_F(0x04858c83) /* 0.282604707 */, 15 }, /* 945 */ { MAD_F(0x04872f22) /* 0.283003936 */, 15 }, /* 946 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 15 }, /* 947 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 15 }, /* 948 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 15 }, /* 949 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 15 }, /* 950 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 15 }, /* 951 */ { MAD_F(0x049101f8) /* 0.285402269 */, 15 }, /* 952 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 15 }, /* 953 */ { MAD_F(0x0494496c) /* 0.286202836 */, 15 }, /* 954 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 15 }, /* 955 */ { MAD_F(0x04979177) /* 0.287003963 */, 15 }, /* 956 */ { MAD_F(0x049935b5) /* 0.287404737 */, 15 }, /* 957 */ { MAD_F(0x049ada19) /* 0.287805650 */, 15 }, /* 958 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 15 }, /* 959 */ { MAD_F(0x049e2350) /* 0.288607895 */, 15 }, /* 960 */ { MAD_F(0x049fc824) /* 0.289009227 */, 15 }, /* 961 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 15 }, /* 962 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 15 }, /* 963 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 15 }, /* 964 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 15 }, /* 965 */ { MAD_F(0x04a80277) /* 0.291017976 */, 15 }, /* 966 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 15 }, /* 967 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 15 }, /* 968 */ { MAD_F(0x04acf402) /* 0.292224893 */, 15 }, /* 969 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 15 }, /* 970 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 15 }, /* 971 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 15 }, /* 972 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 15 }, /* 973 */ { MAD_F(0x04b53427) /* 0.294239192 */, 15 }, /* 974 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 15 }, /* 975 */ { MAD_F(0x04b88207) /* 0.295045879 */, 15 }, /* 976 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 15 }, /* 977 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 15 }, /* 978 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 15 }, /* 979 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 15 }, /* 980 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 15 }, /* 981 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 15 }, /* 982 */ { MAD_F(0x04c41722) /* 0.297873624 */, 15 }, /* 983 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 15 }, /* 984 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 15 }, /* 985 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 15 }, /* 986 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 15 }, /* 987 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 15 }, /* 988 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 15 }, /* 989 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 15 }, /* 990 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 15 }, /* 991 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 15 }, /* 992 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 15 }, /* 993 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 15 }, /* 994 */ { MAD_F(0x04d80290) /* 0.302736820 */, 15 }, /* 995 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 15 }, /* 996 */ { MAD_F(0x04db5679) /* 0.303549263 */, 15 }, /* 997 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 15 }, /* 998 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 15 }, /* 999 */ { MAD_F(0x04e05567) /* 0.304768948 */, 15 }, /* 1000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 15 }, /* 1001 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 15 }, /* 1002 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 15 }, /* 1003 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 15 }, /* 1004 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 15 }, /* 1005 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 15 }, /* 1006 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 15 }, /* 1007 */ { MAD_F(0x04edae25) /* 0.308027406 */, 15 }, /* 1008 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 15 }, /* 1009 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 15 }, /* 1010 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 15 }, /* 1011 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 15 }, /* 1012 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 15 }, /* 1013 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 15 }, /* 1014 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 15 }, /* 1015 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 15 }, /* 1016 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 15 }, /* 1017 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 15 }, /* 1018 */ { MAD_F(0x050016f3) /* 0.312521885 */, 15 }, /* 1019 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 15 }, /* 1020 */ { MAD_F(0x050371a7) /* 0.313340809 */, 15 }, /* 1021 */ { MAD_F(0x05051f37) /* 0.313750472 */, 15 }, /* 1022 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 15 }, /* 1023 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 15 }, /* 1024 */ { MAD_F(0x050a28be) /* 0.314980262 */, 15 }, /* 1025 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 15 }, /* 1026 */ { MAD_F(0x050d8521) /* 0.315800790 */, 15 }, /* 1027 */ { MAD_F(0x050f3388) /* 0.316211255 */, 15 }, /* 1028 */ { MAD_F(0x0510e213) /* 0.316621852 */, 15 }, /* 1029 */ { MAD_F(0x051290c2) /* 0.317032582 */, 15 }, /* 1030 */ { MAD_F(0x05143f94) /* 0.317443446 */, 15 }, /* 1031 */ { MAD_F(0x0515ee8a) /* 0.317854442 */, 15 }, /* 1032 */ { MAD_F(0x05179da4) /* 0.318265572 */, 15 }, /* 1033 */ { MAD_F(0x05194ce1) /* 0.318676834 */, 15 }, /* 1034 */ { MAD_F(0x051afc42) /* 0.319088229 */, 15 }, /* 1035 */ { MAD_F(0x051cabc7) /* 0.319499756 */, 15 }, /* 1036 */ { MAD_F(0x051e5b6f) /* 0.319911417 */, 15 }, /* 1037 */ { MAD_F(0x05200b3a) /* 0.320323209 */, 15 }, /* 1038 */ { MAD_F(0x0521bb2a) /* 0.320735134 */, 15 }, /* 1039 */ { MAD_F(0x05236b3d) /* 0.321147192 */, 15 }, /* 1040 */ { MAD_F(0x05251b73) /* 0.321559381 */, 15 }, /* 1041 */ { MAD_F(0x0526cbcd) /* 0.321971703 */, 15 }, /* 1042 */ { MAD_F(0x05287c4a) /* 0.322384156 */, 15 }, /* 1043 */ { MAD_F(0x052a2cea) /* 0.322796742 */, 15 }, /* 1044 */ { MAD_F(0x052bddae) /* 0.323209460 */, 15 }, /* 1045 */ { MAD_F(0x052d8e96) /* 0.323622309 */, 15 }, /* 1046 */ { MAD_F(0x052f3fa1) /* 0.324035290 */, 15 }, /* 1047 */ { MAD_F(0x0530f0cf) /* 0.324448403 */, 15 }, /* 1048 */ { MAD_F(0x0532a220) /* 0.324861647 */, 15 }, /* 1049 */ { MAD_F(0x05345395) /* 0.325275023 */, 15 }, /* 1050 */ { MAD_F(0x0536052d) /* 0.325688530 */, 15 }, /* 1051 */ { MAD_F(0x0537b6e8) /* 0.326102168 */, 15 }, /* 1052 */ { MAD_F(0x053968c6) /* 0.326515938 */, 15 }, /* 1053 */ { MAD_F(0x053b1ac8) /* 0.326929839 */, 15 }, /* 1054 */ { MAD_F(0x053ccced) /* 0.327343870 */, 15 }, /* 1055 */ { MAD_F(0x053e7f35) /* 0.327758033 */, 15 }, /* 1056 */ { MAD_F(0x054031a0) /* 0.328172327 */, 15 }, /* 1057 */ { MAD_F(0x0541e42e) /* 0.328586751 */, 15 }, /* 1058 */ { MAD_F(0x054396df) /* 0.329001306 */, 15 }, /* 1059 */ { MAD_F(0x054549b4) /* 0.329415992 */, 15 }, /* 1060 */ { MAD_F(0x0546fcab) /* 0.329830808 */, 15 }, /* 1061 */ { MAD_F(0x0548afc6) /* 0.330245755 */, 15 }, /* 1062 */ { MAD_F(0x054a6303) /* 0.330660832 */, 15 }, /* 1063 */ { MAD_F(0x054c1663) /* 0.331076039 */, 15 }, /* 1064 */ { MAD_F(0x054dc9e7) /* 0.331491377 */, 15 }, /* 1065 */ { MAD_F(0x054f7d8d) /* 0.331906845 */, 15 }, /* 1066 */ { MAD_F(0x05513156) /* 0.332322443 */, 15 }, /* 1067 */ { MAD_F(0x0552e542) /* 0.332738170 */, 15 }, /* 1068 */ { MAD_F(0x05549951) /* 0.333154028 */, 15 }, /* 1069 */ { MAD_F(0x05564d83) /* 0.333570016 */, 15 }, /* 1070 */ { MAD_F(0x055801d8) /* 0.333986133 */, 15 }, /* 1071 */ { MAD_F(0x0559b64f) /* 0.334402380 */, 15 }, /* 1072 */ { MAD_F(0x055b6ae9) /* 0.334818756 */, 15 }, /* 1073 */ { MAD_F(0x055d1fa6) /* 0.335235262 */, 15 }, /* 1074 */ { MAD_F(0x055ed486) /* 0.335651898 */, 15 }, /* 1075 */ { MAD_F(0x05608988) /* 0.336068662 */, 15 }, /* 1076 */ { MAD_F(0x05623ead) /* 0.336485556 */, 15 }, /* 1077 */ { MAD_F(0x0563f3f5) /* 0.336902579 */, 15 }, /* 1078 */ { MAD_F(0x0565a960) /* 0.337319732 */, 15 }, /* 1079 */ { MAD_F(0x05675eed) /* 0.337737013 */, 15 }, /* 1080 */ { MAD_F(0x0569149c) /* 0.338154423 */, 15 }, /* 1081 */ { MAD_F(0x056aca6f) /* 0.338571962 */, 15 }, /* 1082 */ { MAD_F(0x056c8064) /* 0.338989630 */, 15 }, /* 1083 */ { MAD_F(0x056e367b) /* 0.339407426 */, 15 }, /* 1084 */ { MAD_F(0x056fecb5) /* 0.339825351 */, 15 }, /* 1085 */ { MAD_F(0x0571a311) /* 0.340243405 */, 15 }, /* 1086 */ { MAD_F(0x05735990) /* 0.340661587 */, 15 }, /* 1087 */ { MAD_F(0x05751032) /* 0.341079898 */, 15 }, /* 1088 */ { MAD_F(0x0576c6f5) /* 0.341498336 */, 15 }, /* 1089 */ { MAD_F(0x05787ddc) /* 0.341916903 */, 15 }, /* 1090 */ { MAD_F(0x057a34e4) /* 0.342335598 */, 15 }, /* 1091 */ { MAD_F(0x057bec0f) /* 0.342754421 */, 15 }, /* 1092 */ { MAD_F(0x057da35d) /* 0.343173373 */, 15 }, /* 1093 */ { MAD_F(0x057f5acc) /* 0.343592452 */, 15 }, /* 1094 */ { MAD_F(0x0581125e) /* 0.344011659 */, 15 }, /* 1095 */ { MAD_F(0x0582ca12) /* 0.344430993 */, 15 }, /* 1096 */ { MAD_F(0x058481e9) /* 0.344850455 */, 15 }, /* 1097 */ { MAD_F(0x058639e2) /* 0.345270045 */, 15 }, /* 1098 */ { MAD_F(0x0587f1fd) /* 0.345689763 */, 15 }, /* 1099 */ { MAD_F(0x0589aa3a) /* 0.346109608 */, 15 }, /* 1100 */ { MAD_F(0x058b629a) /* 0.346529580 */, 15 }, /* 1101 */ { MAD_F(0x058d1b1b) /* 0.346949679 */, 15 }, /* 1102 */ { MAD_F(0x058ed3bf) /* 0.347369906 */, 15 }, /* 1103 */ { MAD_F(0x05908c85) /* 0.347790260 */, 15 }, /* 1104 */ { MAD_F(0x0592456d) /* 0.348210741 */, 15 }, /* 1105 */ { MAD_F(0x0593fe77) /* 0.348631348 */, 15 }, /* 1106 */ { MAD_F(0x0595b7a3) /* 0.349052083 */, 15 }, /* 1107 */ { MAD_F(0x059770f1) /* 0.349472945 */, 15 }, /* 1108 */ { MAD_F(0x05992a61) /* 0.349893933 */, 15 }, /* 1109 */ { MAD_F(0x059ae3f3) /* 0.350315048 */, 15 }, /* 1110 */ { MAD_F(0x059c9da8) /* 0.350736290 */, 15 }, /* 1111 */ { MAD_F(0x059e577e) /* 0.351157658 */, 15 }, /* 1112 */ { MAD_F(0x05a01176) /* 0.351579152 */, 15 }, /* 1113 */ { MAD_F(0x05a1cb90) /* 0.352000773 */, 15 }, /* 1114 */ { MAD_F(0x05a385cc) /* 0.352422520 */, 15 }, /* 1115 */ { MAD_F(0x05a5402a) /* 0.352844394 */, 15 }, /* 1116 */ { MAD_F(0x05a6faa9) /* 0.353266393 */, 15 }, /* 1117 */ { MAD_F(0x05a8b54b) /* 0.353688519 */, 15 }, /* 1118 */ { MAD_F(0x05aa700e) /* 0.354110771 */, 15 }, /* 1119 */ { MAD_F(0x05ac2af3) /* 0.354533148 */, 15 }, /* 1120 */ { MAD_F(0x05ade5fa) /* 0.354955651 */, 15 }, /* 1121 */ { MAD_F(0x05afa123) /* 0.355378281 */, 15 }, /* 1122 */ { MAD_F(0x05b15c6d) /* 0.355801035 */, 15 }, /* 1123 */ { MAD_F(0x05b317d9) /* 0.356223916 */, 15 }, /* 1124 */ { MAD_F(0x05b4d367) /* 0.356646922 */, 15 }, /* 1125 */ { MAD_F(0x05b68f16) /* 0.357070053 */, 15 }, /* 1126 */ { MAD_F(0x05b84ae7) /* 0.357493310 */, 15 }, /* 1127 */ { MAD_F(0x05ba06da) /* 0.357916692 */, 15 }, /* 1128 */ { MAD_F(0x05bbc2ef) /* 0.358340200 */, 15 }, /* 1129 */ { MAD_F(0x05bd7f25) /* 0.358763832 */, 15 }, /* 1130 */ { MAD_F(0x05bf3b7c) /* 0.359187590 */, 15 }, /* 1131 */ { MAD_F(0x05c0f7f5) /* 0.359611472 */, 15 }, /* 1132 */ { MAD_F(0x05c2b490) /* 0.360035480 */, 15 }, /* 1133 */ { MAD_F(0x05c4714c) /* 0.360459613 */, 15 }, /* 1134 */ { MAD_F(0x05c62e2a) /* 0.360883870 */, 15 }, /* 1135 */ { MAD_F(0x05c7eb29) /* 0.361308252 */, 15 }, /* 1136 */ { MAD_F(0x05c9a84a) /* 0.361732758 */, 15 }, /* 1137 */ { MAD_F(0x05cb658c) /* 0.362157390 */, 15 }, /* 1138 */ { MAD_F(0x05cd22ef) /* 0.362582145 */, 15 }, /* 1139 */ { MAD_F(0x05cee074) /* 0.363007026 */, 15 }, /* 1140 */ { MAD_F(0x05d09e1b) /* 0.363432030 */, 15 }, /* 1141 */ { MAD_F(0x05d25be2) /* 0.363857159 */, 15 }, /* 1142 */ { MAD_F(0x05d419cb) /* 0.364282412 */, 15 }, /* 1143 */ { MAD_F(0x05d5d7d5) /* 0.364707789 */, 15 }, /* 1144 */ { MAD_F(0x05d79601) /* 0.365133291 */, 15 }, /* 1145 */ { MAD_F(0x05d9544e) /* 0.365558916 */, 15 }, /* 1146 */ { MAD_F(0x05db12bc) /* 0.365984665 */, 15 }, /* 1147 */ { MAD_F(0x05dcd14c) /* 0.366410538 */, 15 }, /* 1148 */ { MAD_F(0x05de8ffc) /* 0.366836535 */, 15 }, /* 1149 */ { MAD_F(0x05e04ece) /* 0.367262655 */, 15 }, /* 1150 */ { MAD_F(0x05e20dc1) /* 0.367688900 */, 15 }, /* 1151 */ { MAD_F(0x05e3ccd5) /* 0.368115267 */, 15 }, /* 1152 */ { MAD_F(0x05e58c0b) /* 0.368541759 */, 15 }, /* 1153 */ { MAD_F(0x05e74b61) /* 0.368968373 */, 15 }, /* 1154 */ { MAD_F(0x05e90ad9) /* 0.369395111 */, 15 }, /* 1155 */ { MAD_F(0x05eaca72) /* 0.369821973 */, 15 }, /* 1156 */ { MAD_F(0x05ec8a2b) /* 0.370248957 */, 15 }, /* 1157 */ { MAD_F(0x05ee4a06) /* 0.370676065 */, 15 }, /* 1158 */ { MAD_F(0x05f00a02) /* 0.371103295 */, 15 }, /* 1159 */ { MAD_F(0x05f1ca1f) /* 0.371530649 */, 15 }, /* 1160 */ { MAD_F(0x05f38a5d) /* 0.371958126 */, 15 }, /* 1161 */ { MAD_F(0x05f54abc) /* 0.372385725 */, 15 }, /* 1162 */ { MAD_F(0x05f70b3c) /* 0.372813448 */, 15 }, /* 1163 */ { MAD_F(0x05f8cbdc) /* 0.373241292 */, 15 }, /* 1164 */ { MAD_F(0x05fa8c9e) /* 0.373669260 */, 15 }, /* 1165 */ { MAD_F(0x05fc4d81) /* 0.374097350 */, 15 }, /* 1166 */ { MAD_F(0x05fe0e84) /* 0.374525563 */, 15 }, /* 1167 */ { MAD_F(0x05ffcfa8) /* 0.374953898 */, 15 }, /* 1168 */ { MAD_F(0x060190ee) /* 0.375382356 */, 15 }, /* 1169 */ { MAD_F(0x06035254) /* 0.375810936 */, 15 }, /* 1170 */ { MAD_F(0x060513da) /* 0.376239638 */, 15 }, /* 1171 */ { MAD_F(0x0606d582) /* 0.376668462 */, 15 }, /* 1172 */ { MAD_F(0x0608974a) /* 0.377097408 */, 15 }, /* 1173 */ { MAD_F(0x060a5934) /* 0.377526476 */, 15 }, /* 1174 */ { MAD_F(0x060c1b3d) /* 0.377955667 */, 15 }, /* 1175 */ { MAD_F(0x060ddd68) /* 0.378384979 */, 15 }, /* 1176 */ { MAD_F(0x060f9fb3) /* 0.378814413 */, 15 }, /* 1177 */ { MAD_F(0x0611621f) /* 0.379243968 */, 15 }, /* 1178 */ { MAD_F(0x061324ac) /* 0.379673646 */, 15 }, /* 1179 */ { MAD_F(0x0614e759) /* 0.380103444 */, 15 }, /* 1180 */ { MAD_F(0x0616aa27) /* 0.380533365 */, 15 }, /* 1181 */ { MAD_F(0x06186d16) /* 0.380963407 */, 15 }, /* 1182 */ { MAD_F(0x061a3025) /* 0.381393570 */, 15 }, /* 1183 */ { MAD_F(0x061bf354) /* 0.381823855 */, 15 }, /* 1184 */ { MAD_F(0x061db6a5) /* 0.382254261 */, 15 }, /* 1185 */ { MAD_F(0x061f7a15) /* 0.382684788 */, 15 }, /* 1186 */ { MAD_F(0x06213da7) /* 0.383115436 */, 15 }, /* 1187 */ { MAD_F(0x06230158) /* 0.383546205 */, 15 }, /* 1188 */ { MAD_F(0x0624c52a) /* 0.383977096 */, 15 }, /* 1189 */ { MAD_F(0x0626891d) /* 0.384408107 */, 15 }, /* 1190 */ { MAD_F(0x06284d30) /* 0.384839239 */, 15 }, /* 1191 */ { MAD_F(0x062a1164) /* 0.385270492 */, 15 }, /* 1192 */ { MAD_F(0x062bd5b8) /* 0.385701865 */, 15 }, /* 1193 */ { MAD_F(0x062d9a2c) /* 0.386133359 */, 15 }, /* 1194 */ { MAD_F(0x062f5ec1) /* 0.386564974 */, 15 }, /* 1195 */ { MAD_F(0x06312376) /* 0.386996709 */, 15 }, /* 1196 */ { MAD_F(0x0632e84b) /* 0.387428565 */, 15 }, /* 1197 */ { MAD_F(0x0634ad41) /* 0.387860541 */, 15 }, /* 1198 */ { MAD_F(0x06367257) /* 0.388292637 */, 15 }, /* 1199 */ { MAD_F(0x0638378d) /* 0.388724854 */, 15 }, /* 1200 */ { MAD_F(0x0639fce4) /* 0.389157191 */, 15 }, /* 1201 */ { MAD_F(0x063bc25b) /* 0.389589648 */, 15 }, /* 1202 */ { MAD_F(0x063d87f2) /* 0.390022225 */, 15 }, /* 1203 */ { MAD_F(0x063f4da9) /* 0.390454922 */, 15 }, /* 1204 */ { MAD_F(0x06411380) /* 0.390887739 */, 15 }, /* 1205 */ { MAD_F(0x0642d978) /* 0.391320675 */, 15 }, /* 1206 */ { MAD_F(0x06449f8f) /* 0.391753732 */, 15 }, /* 1207 */ { MAD_F(0x064665c7) /* 0.392186908 */, 15 }, /* 1208 */ { MAD_F(0x06482c1f) /* 0.392620204 */, 15 }, /* 1209 */ { MAD_F(0x0649f297) /* 0.393053619 */, 15 }, /* 1210 */ { MAD_F(0x064bb92f) /* 0.393487154 */, 15 }, /* 1211 */ { MAD_F(0x064d7fe8) /* 0.393920808 */, 15 }, /* 1212 */ { MAD_F(0x064f46c0) /* 0.394354582 */, 15 }, /* 1213 */ { MAD_F(0x06510db8) /* 0.394788475 */, 15 }, /* 1214 */ { MAD_F(0x0652d4d0) /* 0.395222488 */, 15 }, /* 1215 */ { MAD_F(0x06549c09) /* 0.395656619 */, 15 }, /* 1216 */ { MAD_F(0x06566361) /* 0.396090870 */, 15 }, /* 1217 */ { MAD_F(0x06582ad9) /* 0.396525239 */, 15 }, /* 1218 */ { MAD_F(0x0659f271) /* 0.396959728 */, 15 }, /* 1219 */ { MAD_F(0x065bba29) /* 0.397394336 */, 15 }, /* 1220 */ { MAD_F(0x065d8201) /* 0.397829062 */, 15 }, /* 1221 */ { MAD_F(0x065f49f9) /* 0.398263907 */, 15 }, /* 1222 */ { MAD_F(0x06611211) /* 0.398698871 */, 15 }, /* 1223 */ { MAD_F(0x0662da49) /* 0.399133954 */, 15 }, /* 1224 */ { MAD_F(0x0664a2a0) /* 0.399569155 */, 15 }, /* 1225 */ { MAD_F(0x06666b17) /* 0.400004475 */, 15 }, /* 1226 */ { MAD_F(0x066833ae) /* 0.400439913 */, 15 }, /* 1227 */ { MAD_F(0x0669fc65) /* 0.400875470 */, 15 }, /* 1228 */ { MAD_F(0x066bc53c) /* 0.401311145 */, 15 }, /* 1229 */ { MAD_F(0x066d8e32) /* 0.401746938 */, 15 }, /* 1230 */ { MAD_F(0x066f5748) /* 0.402182850 */, 15 }, /* 1231 */ { MAD_F(0x0671207e) /* 0.402618879 */, 15 }, /* 1232 */ { MAD_F(0x0672e9d4) /* 0.403055027 */, 15 }, /* 1233 */ { MAD_F(0x0674b349) /* 0.403491293 */, 15 }, /* 1234 */ { MAD_F(0x06767cde) /* 0.403927676 */, 15 }, /* 1235 */ { MAD_F(0x06784692) /* 0.404364178 */, 15 }, /* 1236 */ { MAD_F(0x067a1066) /* 0.404800797 */, 15 }, /* 1237 */ { MAD_F(0x067bda5a) /* 0.405237535 */, 15 }, /* 1238 */ { MAD_F(0x067da46d) /* 0.405674390 */, 15 }, /* 1239 */ { MAD_F(0x067f6ea0) /* 0.406111362 */, 15 }, /* 1240 */ { MAD_F(0x068138f3) /* 0.406548452 */, 15 }, /* 1241 */ { MAD_F(0x06830365) /* 0.406985660 */, 15 }, /* 1242 */ { MAD_F(0x0684cdf6) /* 0.407422985 */, 15 }, /* 1243 */ { MAD_F(0x068698a8) /* 0.407860427 */, 15 }, /* 1244 */ { MAD_F(0x06886378) /* 0.408297987 */, 15 }, /* 1245 */ { MAD_F(0x068a2e68) /* 0.408735664 */, 15 }, /* 1246 */ { MAD_F(0x068bf978) /* 0.409173458 */, 15 }, /* 1247 */ { MAD_F(0x068dc4a7) /* 0.409611370 */, 15 }, /* 1248 */ { MAD_F(0x068f8ff5) /* 0.410049398 */, 15 }, /* 1249 */ { MAD_F(0x06915b63) /* 0.410487544 */, 15 }, /* 1250 */ { MAD_F(0x069326f0) /* 0.410925806 */, 15 }, /* 1251 */ { MAD_F(0x0694f29c) /* 0.411364185 */, 15 }, /* 1252 */ { MAD_F(0x0696be68) /* 0.411802681 */, 15 }, /* 1253 */ { MAD_F(0x06988a54) /* 0.412241294 */, 15 }, /* 1254 */ { MAD_F(0x069a565e) /* 0.412680024 */, 15 }, /* 1255 */ { MAD_F(0x069c2288) /* 0.413118870 */, 15 }, /* 1256 */ { MAD_F(0x069deed1) /* 0.413557833 */, 15 }, /* 1257 */ { MAD_F(0x069fbb3a) /* 0.413996912 */, 15 }, /* 1258 */ { MAD_F(0x06a187c1) /* 0.414436108 */, 15 }, /* 1259 */ { MAD_F(0x06a35468) /* 0.414875420 */, 15 }, /* 1260 */ { MAD_F(0x06a5212f) /* 0.415314849 */, 15 }, /* 1261 */ { MAD_F(0x06a6ee14) /* 0.415754393 */, 15 }, /* 1262 */ { MAD_F(0x06a8bb18) /* 0.416194054 */, 15 }, /* 1263 */ { MAD_F(0x06aa883c) /* 0.416633831 */, 15 }, /* 1264 */ { MAD_F(0x06ac557f) /* 0.417073724 */, 15 }, /* 1265 */ { MAD_F(0x06ae22e1) /* 0.417513734 */, 15 }, /* 1266 */ { MAD_F(0x06aff062) /* 0.417953859 */, 15 }, /* 1267 */ { MAD_F(0x06b1be03) /* 0.418394100 */, 15 }, /* 1268 */ { MAD_F(0x06b38bc2) /* 0.418834457 */, 15 }, /* 1269 */ { MAD_F(0x06b559a1) /* 0.419274929 */, 15 }, /* 1270 */ { MAD_F(0x06b7279e) /* 0.419715518 */, 15 }, /* 1271 */ { MAD_F(0x06b8f5bb) /* 0.420156222 */, 15 }, /* 1272 */ { MAD_F(0x06bac3f6) /* 0.420597041 */, 15 }, /* 1273 */ { MAD_F(0x06bc9251) /* 0.421037977 */, 15 }, /* 1274 */ { MAD_F(0x06be60cb) /* 0.421479027 */, 15 }, /* 1275 */ { MAD_F(0x06c02f63) /* 0.421920193 */, 15 }, /* 1276 */ { MAD_F(0x06c1fe1b) /* 0.422361475 */, 15 }, /* 1277 */ { MAD_F(0x06c3ccf1) /* 0.422802871 */, 15 }, /* 1278 */ { MAD_F(0x06c59be7) /* 0.423244383 */, 15 }, /* 1279 */ { MAD_F(0x06c76afb) /* 0.423686010 */, 15 }, /* 1280 */ { MAD_F(0x06c93a2e) /* 0.424127753 */, 15 }, /* 1281 */ { MAD_F(0x06cb0981) /* 0.424569610 */, 15 }, /* 1282 */ { MAD_F(0x06ccd8f2) /* 0.425011582 */, 15 }, /* 1283 */ { MAD_F(0x06cea881) /* 0.425453669 */, 15 }, /* 1284 */ { MAD_F(0x06d07830) /* 0.425895871 */, 15 }, /* 1285 */ { MAD_F(0x06d247fe) /* 0.426338188 */, 15 }, /* 1286 */ { MAD_F(0x06d417ea) /* 0.426780620 */, 15 }, /* 1287 */ { MAD_F(0x06d5e7f5) /* 0.427223166 */, 15 }, /* 1288 */ { MAD_F(0x06d7b81f) /* 0.427665827 */, 15 }, /* 1289 */ { MAD_F(0x06d98868) /* 0.428108603 */, 15 }, /* 1290 */ { MAD_F(0x06db58cf) /* 0.428551493 */, 15 }, /* 1291 */ { MAD_F(0x06dd2955) /* 0.428994497 */, 15 }, /* 1292 */ { MAD_F(0x06def9fa) /* 0.429437616 */, 15 }, /* 1293 */ { MAD_F(0x06e0cabe) /* 0.429880849 */, 15 }, /* 1294 */ { MAD_F(0x06e29ba0) /* 0.430324197 */, 15 }, /* 1295 */ { MAD_F(0x06e46ca1) /* 0.430767659 */, 15 }, /* 1296 */ { MAD_F(0x06e63dc0) /* 0.431211234 */, 15 }, /* 1297 */ { MAD_F(0x06e80efe) /* 0.431654924 */, 15 }, /* 1298 */ { MAD_F(0x06e9e05b) /* 0.432098728 */, 15 }, /* 1299 */ { MAD_F(0x06ebb1d6) /* 0.432542647 */, 15 }, /* 1300 */ { MAD_F(0x06ed8370) /* 0.432986678 */, 15 }, /* 1301 */ { MAD_F(0x06ef5529) /* 0.433430824 */, 15 }, /* 1302 */ { MAD_F(0x06f12700) /* 0.433875084 */, 15 }, /* 1303 */ { MAD_F(0x06f2f8f5) /* 0.434319457 */, 15 }, /* 1304 */ { MAD_F(0x06f4cb09) /* 0.434763944 */, 15 }, /* 1305 */ { MAD_F(0x06f69d3c) /* 0.435208545 */, 15 }, /* 1306 */ { MAD_F(0x06f86f8d) /* 0.435653259 */, 15 }, /* 1307 */ { MAD_F(0x06fa41fd) /* 0.436098087 */, 15 }, /* 1308 */ { MAD_F(0x06fc148b) /* 0.436543029 */, 15 }, /* 1309 */ { MAD_F(0x06fde737) /* 0.436988083 */, 15 }, /* 1310 */ { MAD_F(0x06ffba02) /* 0.437433251 */, 15 }, /* 1311 */ { MAD_F(0x07018ceb) /* 0.437878533 */, 15 }, /* 1312 */ { MAD_F(0x07035ff3) /* 0.438323927 */, 15 }, /* 1313 */ { MAD_F(0x07053319) /* 0.438769435 */, 15 }, /* 1314 */ { MAD_F(0x0707065d) /* 0.439215056 */, 15 }, /* 1315 */ { MAD_F(0x0708d9c0) /* 0.439660790 */, 15 }, /* 1316 */ { MAD_F(0x070aad41) /* 0.440106636 */, 15 }, /* 1317 */ { MAD_F(0x070c80e1) /* 0.440552596 */, 15 }, /* 1318 */ { MAD_F(0x070e549f) /* 0.440998669 */, 15 }, /* 1319 */ { MAD_F(0x0710287b) /* 0.441444855 */, 15 }, /* 1320 */ { MAD_F(0x0711fc75) /* 0.441891153 */, 15 }, /* 1321 */ { MAD_F(0x0713d08d) /* 0.442337564 */, 15 }, /* 1322 */ { MAD_F(0x0715a4c4) /* 0.442784088 */, 15 }, /* 1323 */ { MAD_F(0x07177919) /* 0.443230724 */, 15 }, /* 1324 */ { MAD_F(0x07194d8c) /* 0.443677473 */, 15 }, /* 1325 */ { MAD_F(0x071b221e) /* 0.444124334 */, 15 }, /* 1326 */ { MAD_F(0x071cf6ce) /* 0.444571308 */, 15 }, /* 1327 */ { MAD_F(0x071ecb9b) /* 0.445018394 */, 15 }, /* 1328 */ { MAD_F(0x0720a087) /* 0.445465593 */, 15 }, /* 1329 */ { MAD_F(0x07227591) /* 0.445912903 */, 15 }, /* 1330 */ { MAD_F(0x07244ab9) /* 0.446360326 */, 15 }, /* 1331 */ { MAD_F(0x07262000) /* 0.446807861 */, 15 }, /* 1332 */ { MAD_F(0x0727f564) /* 0.447255509 */, 15 }, /* 1333 */ { MAD_F(0x0729cae7) /* 0.447703268 */, 15 }, /* 1334 */ { MAD_F(0x072ba087) /* 0.448151139 */, 15 }, /* 1335 */ { MAD_F(0x072d7646) /* 0.448599122 */, 15 }, /* 1336 */ { MAD_F(0x072f4c22) /* 0.449047217 */, 15 }, /* 1337 */ { MAD_F(0x0731221d) /* 0.449495424 */, 15 }, /* 1338 */ { MAD_F(0x0732f835) /* 0.449943742 */, 15 }, /* 1339 */ { MAD_F(0x0734ce6c) /* 0.450392173 */, 15 }, /* 1340 */ { MAD_F(0x0736a4c1) /* 0.450840715 */, 15 }, /* 1341 */ { MAD_F(0x07387b33) /* 0.451289368 */, 15 }, /* 1342 */ { MAD_F(0x073a51c4) /* 0.451738133 */, 15 }, /* 1343 */ { MAD_F(0x073c2872) /* 0.452187010 */, 15 }, /* 1344 */ { MAD_F(0x073dff3e) /* 0.452635998 */, 15 }, /* 1345 */ { MAD_F(0x073fd628) /* 0.453085097 */, 15 }, /* 1346 */ { MAD_F(0x0741ad30) /* 0.453534308 */, 15 }, /* 1347 */ { MAD_F(0x07438456) /* 0.453983630 */, 15 }, /* 1348 */ { MAD_F(0x07455b9a) /* 0.454433063 */, 15 }, /* 1349 */ { MAD_F(0x074732fc) /* 0.454882607 */, 15 }, /* 1350 */ { MAD_F(0x07490a7b) /* 0.455332262 */, 15 }, /* 1351 */ { MAD_F(0x074ae218) /* 0.455782029 */, 15 }, /* 1352 */ { MAD_F(0x074cb9d3) /* 0.456231906 */, 15 }, /* 1353 */ { MAD_F(0x074e91ac) /* 0.456681894 */, 15 }, /* 1354 */ { MAD_F(0x075069a3) /* 0.457131993 */, 15 }, /* 1355 */ { MAD_F(0x075241b7) /* 0.457582203 */, 15 }, /* 1356 */ { MAD_F(0x075419e9) /* 0.458032524 */, 15 }, /* 1357 */ { MAD_F(0x0755f239) /* 0.458482956 */, 15 }, /* 1358 */ { MAD_F(0x0757caa7) /* 0.458933498 */, 15 }, /* 1359 */ { MAD_F(0x0759a332) /* 0.459384151 */, 15 }, /* 1360 */ { MAD_F(0x075b7bdb) /* 0.459834914 */, 15 }, /* 1361 */ { MAD_F(0x075d54a1) /* 0.460285788 */, 15 }, /* 1362 */ { MAD_F(0x075f2d85) /* 0.460736772 */, 15 }, /* 1363 */ { MAD_F(0x07610687) /* 0.461187867 */, 15 }, /* 1364 */ { MAD_F(0x0762dfa6) /* 0.461639071 */, 15 }, /* 1365 */ { MAD_F(0x0764b8e3) /* 0.462090387 */, 15 }, /* 1366 */ { MAD_F(0x0766923e) /* 0.462541812 */, 15 }, /* 1367 */ { MAD_F(0x07686bb6) /* 0.462993348 */, 15 }, /* 1368 */ { MAD_F(0x076a454c) /* 0.463444993 */, 15 }, /* 1369 */ { MAD_F(0x076c1eff) /* 0.463896749 */, 15 }, /* 1370 */ { MAD_F(0x076df8d0) /* 0.464348615 */, 15 }, /* 1371 */ { MAD_F(0x076fd2be) /* 0.464800591 */, 15 }, /* 1372 */ { MAD_F(0x0771acca) /* 0.465252676 */, 15 }, /* 1373 */ { MAD_F(0x077386f3) /* 0.465704872 */, 15 }, /* 1374 */ { MAD_F(0x0775613a) /* 0.466157177 */, 15 }, /* 1375 */ { MAD_F(0x07773b9e) /* 0.466609592 */, 15 }, /* 1376 */ { MAD_F(0x07791620) /* 0.467062117 */, 15 }, /* 1377 */ { MAD_F(0x077af0bf) /* 0.467514751 */, 15 }, /* 1378 */ { MAD_F(0x077ccb7c) /* 0.467967495 */, 15 }, /* 1379 */ { MAD_F(0x077ea656) /* 0.468420349 */, 15 }, /* 1380 */ { MAD_F(0x0780814d) /* 0.468873312 */, 15 }, /* 1381 */ { MAD_F(0x07825c62) /* 0.469326384 */, 15 }, /* 1382 */ { MAD_F(0x07843794) /* 0.469779566 */, 15 }, /* 1383 */ { MAD_F(0x078612e3) /* 0.470232857 */, 15 }, /* 1384 */ { MAD_F(0x0787ee50) /* 0.470686258 */, 15 }, /* 1385 */ { MAD_F(0x0789c9da) /* 0.471139767 */, 15 }, /* 1386 */ { MAD_F(0x078ba581) /* 0.471593386 */, 15 }, /* 1387 */ { MAD_F(0x078d8146) /* 0.472047114 */, 15 }, /* 1388 */ { MAD_F(0x078f5d28) /* 0.472500951 */, 15 }, /* 1389 */ { MAD_F(0x07913927) /* 0.472954896 */, 15 }, /* 1390 */ { MAD_F(0x07931543) /* 0.473408951 */, 15 }, /* 1391 */ { MAD_F(0x0794f17d) /* 0.473863115 */, 15 }, /* 1392 */ { MAD_F(0x0796cdd4) /* 0.474317388 */, 15 }, /* 1393 */ { MAD_F(0x0798aa48) /* 0.474771769 */, 15 }, /* 1394 */ { MAD_F(0x079a86d9) /* 0.475226259 */, 15 }, /* 1395 */ { MAD_F(0x079c6388) /* 0.475680858 */, 15 }, /* 1396 */ { MAD_F(0x079e4053) /* 0.476135565 */, 15 }, /* 1397 */ { MAD_F(0x07a01d3c) /* 0.476590381 */, 15 }, /* 1398 */ { MAD_F(0x07a1fa42) /* 0.477045306 */, 15 }, /* 1399 */ { MAD_F(0x07a3d765) /* 0.477500339 */, 15 }, /* 1400 */ { MAD_F(0x07a5b4a5) /* 0.477955481 */, 15 }, /* 1401 */ { MAD_F(0x07a79202) /* 0.478410731 */, 15 }, /* 1402 */ { MAD_F(0x07a96f7d) /* 0.478866089 */, 15 }, /* 1403 */ { MAD_F(0x07ab4d14) /* 0.479321555 */, 15 }, /* 1404 */ { MAD_F(0x07ad2ac8) /* 0.479777130 */, 15 }, /* 1405 */ { MAD_F(0x07af089a) /* 0.480232813 */, 15 }, /* 1406 */ { MAD_F(0x07b0e688) /* 0.480688604 */, 15 }, /* 1407 */ { MAD_F(0x07b2c494) /* 0.481144503 */, 15 }, /* 1408 */ { MAD_F(0x07b4a2bc) /* 0.481600510 */, 15 }, /* 1409 */ { MAD_F(0x07b68102) /* 0.482056625 */, 15 }, /* 1410 */ { MAD_F(0x07b85f64) /* 0.482512848 */, 15 }, /* 1411 */ { MAD_F(0x07ba3de4) /* 0.482969179 */, 15 }, /* 1412 */ { MAD_F(0x07bc1c80) /* 0.483425618 */, 15 }, /* 1413 */ { MAD_F(0x07bdfb39) /* 0.483882164 */, 15 }, /* 1414 */ { MAD_F(0x07bfda0f) /* 0.484338818 */, 15 }, /* 1415 */ { MAD_F(0x07c1b902) /* 0.484795580 */, 15 }, /* 1416 */ { MAD_F(0x07c39812) /* 0.485252449 */, 15 }, /* 1417 */ { MAD_F(0x07c5773f) /* 0.485709426 */, 15 }, /* 1418 */ { MAD_F(0x07c75689) /* 0.486166511 */, 15 }, /* 1419 */ { MAD_F(0x07c935ef) /* 0.486623703 */, 15 }, /* 1420 */ { MAD_F(0x07cb1573) /* 0.487081002 */, 15 }, /* 1421 */ { MAD_F(0x07ccf513) /* 0.487538409 */, 15 }, /* 1422 */ { MAD_F(0x07ced4d0) /* 0.487995923 */, 15 }, /* 1423 */ { MAD_F(0x07d0b4aa) /* 0.488453544 */, 15 }, /* 1424 */ { MAD_F(0x07d294a0) /* 0.488911273 */, 15 }, /* 1425 */ { MAD_F(0x07d474b3) /* 0.489369108 */, 15 }, /* 1426 */ { MAD_F(0x07d654e4) /* 0.489827051 */, 15 }, /* 1427 */ { MAD_F(0x07d83530) /* 0.490285101 */, 15 }, /* 1428 */ { MAD_F(0x07da159a) /* 0.490743258 */, 15 }, /* 1429 */ { MAD_F(0x07dbf620) /* 0.491201522 */, 15 }, /* 1430 */ { MAD_F(0x07ddd6c3) /* 0.491659892 */, 15 }, /* 1431 */ { MAD_F(0x07dfb783) /* 0.492118370 */, 15 }, /* 1432 */ { MAD_F(0x07e1985f) /* 0.492576954 */, 15 }, /* 1433 */ { MAD_F(0x07e37958) /* 0.493035645 */, 15 }, /* 1434 */ { MAD_F(0x07e55a6e) /* 0.493494443 */, 15 }, /* 1435 */ { MAD_F(0x07e73ba0) /* 0.493953348 */, 15 }, /* 1436 */ { MAD_F(0x07e91cef) /* 0.494412359 */, 15 }, /* 1437 */ { MAD_F(0x07eafe5a) /* 0.494871476 */, 15 }, /* 1438 */ { MAD_F(0x07ecdfe2) /* 0.495330701 */, 15 }, /* 1439 */ { MAD_F(0x07eec187) /* 0.495790031 */, 15 }, /* 1440 */ { MAD_F(0x07f0a348) /* 0.496249468 */, 15 }, /* 1441 */ { MAD_F(0x07f28526) /* 0.496709012 */, 15 }, /* 1442 */ { MAD_F(0x07f46720) /* 0.497168662 */, 15 }, /* 1443 */ { MAD_F(0x07f64937) /* 0.497628418 */, 15 }, /* 1444 */ { MAD_F(0x07f82b6a) /* 0.498088280 */, 15 }, /* 1445 */ { MAD_F(0x07fa0dba) /* 0.498548248 */, 15 }, /* 1446 */ { MAD_F(0x07fbf026) /* 0.499008323 */, 15 }, /* 1447 */ { MAD_F(0x07fdd2af) /* 0.499468503 */, 15 }, /* 1448 */ { MAD_F(0x07ffb554) /* 0.499928790 */, 15 }, /* 1449 */ { MAD_F(0x0400cc0b) /* 0.250194591 */, 16 }, /* 1450 */ { MAD_F(0x0401bd7a) /* 0.250424840 */, 16 }, /* 1451 */ { MAD_F(0x0402aef7) /* 0.250655143 */, 16 }, /* 1452 */ { MAD_F(0x0403a083) /* 0.250885498 */, 16 }, /* 1453 */ { MAD_F(0x0404921c) /* 0.251115906 */, 16 }, /* 1454 */ { MAD_F(0x040583c4) /* 0.251346367 */, 16 }, /* 1455 */ { MAD_F(0x0406757a) /* 0.251576880 */, 16 }, /* 1456 */ { MAD_F(0x0407673f) /* 0.251807447 */, 16 }, /* 1457 */ { MAD_F(0x04085911) /* 0.252038066 */, 16 }, /* 1458 */ { MAD_F(0x04094af1) /* 0.252268738 */, 16 }, /* 1459 */ { MAD_F(0x040a3ce0) /* 0.252499463 */, 16 }, /* 1460 */ { MAD_F(0x040b2edd) /* 0.252730240 */, 16 }, /* 1461 */ { MAD_F(0x040c20e8) /* 0.252961071 */, 16 }, /* 1462 */ { MAD_F(0x040d1301) /* 0.253191953 */, 16 }, /* 1463 */ { MAD_F(0x040e0529) /* 0.253422889 */, 16 }, /* 1464 */ { MAD_F(0x040ef75e) /* 0.253653877 */, 16 }, /* 1465 */ { MAD_F(0x040fe9a1) /* 0.253884918 */, 16 }, /* 1466 */ { MAD_F(0x0410dbf3) /* 0.254116011 */, 16 }, /* 1467 */ { MAD_F(0x0411ce53) /* 0.254347157 */, 16 }, /* 1468 */ { MAD_F(0x0412c0c1) /* 0.254578356 */, 16 }, /* 1469 */ { MAD_F(0x0413b33d) /* 0.254809606 */, 16 }, /* 1470 */ { MAD_F(0x0414a5c7) /* 0.255040910 */, 16 }, /* 1471 */ { MAD_F(0x0415985f) /* 0.255272266 */, 16 }, /* 1472 */ { MAD_F(0x04168b05) /* 0.255503674 */, 16 }, /* 1473 */ { MAD_F(0x04177db9) /* 0.255735135 */, 16 }, /* 1474 */ { MAD_F(0x0418707c) /* 0.255966648 */, 16 }, /* 1475 */ { MAD_F(0x0419634c) /* 0.256198213 */, 16 }, /* 1476 */ { MAD_F(0x041a562a) /* 0.256429831 */, 16 }, /* 1477 */ { MAD_F(0x041b4917) /* 0.256661501 */, 16 }, /* 1478 */ { MAD_F(0x041c3c11) /* 0.256893223 */, 16 }, /* 1479 */ { MAD_F(0x041d2f1a) /* 0.257124998 */, 16 }, /* 1480 */ { MAD_F(0x041e2230) /* 0.257356825 */, 16 }, /* 1481 */ { MAD_F(0x041f1555) /* 0.257588704 */, 16 }, /* 1482 */ { MAD_F(0x04200888) /* 0.257820635 */, 16 }, /* 1483 */ { MAD_F(0x0420fbc8) /* 0.258052619 */, 16 }, /* 1484 */ { MAD_F(0x0421ef17) /* 0.258284654 */, 16 }, /* 1485 */ { MAD_F(0x0422e273) /* 0.258516742 */, 16 }, /* 1486 */ { MAD_F(0x0423d5de) /* 0.258748882 */, 16 }, /* 1487 */ { MAD_F(0x0424c956) /* 0.258981074 */, 16 }, /* 1488 */ { MAD_F(0x0425bcdd) /* 0.259213318 */, 16 }, /* 1489 */ { MAD_F(0x0426b071) /* 0.259445614 */, 16 }, /* 1490 */ { MAD_F(0x0427a414) /* 0.259677962 */, 16 }, /* 1491 */ { MAD_F(0x042897c4) /* 0.259910362 */, 16 }, /* 1492 */ { MAD_F(0x04298b83) /* 0.260142814 */, 16 }, /* 1493 */ { MAD_F(0x042a7f4f) /* 0.260375318 */, 16 }, /* 1494 */ { MAD_F(0x042b7329) /* 0.260607874 */, 16 }, /* 1495 */ { MAD_F(0x042c6711) /* 0.260840481 */, 16 }, /* 1496 */ { MAD_F(0x042d5b07) /* 0.261073141 */, 16 }, /* 1497 */ { MAD_F(0x042e4f0b) /* 0.261305852 */, 16 }, /* 1498 */ { MAD_F(0x042f431d) /* 0.261538616 */, 16 }, /* 1499 */ { MAD_F(0x0430373d) /* 0.261771431 */, 16 }, /* 1500 */ { MAD_F(0x04312b6b) /* 0.262004297 */, 16 }, /* 1501 */ { MAD_F(0x04321fa6) /* 0.262237216 */, 16 }, /* 1502 */ { MAD_F(0x043313f0) /* 0.262470186 */, 16 }, /* 1503 */ { MAD_F(0x04340847) /* 0.262703208 */, 16 }, /* 1504 */ { MAD_F(0x0434fcad) /* 0.262936282 */, 16 }, /* 1505 */ { MAD_F(0x0435f120) /* 0.263169407 */, 16 }, /* 1506 */ { MAD_F(0x0436e5a1) /* 0.263402584 */, 16 }, /* 1507 */ { MAD_F(0x0437da2f) /* 0.263635813 */, 16 }, /* 1508 */ { MAD_F(0x0438cecc) /* 0.263869093 */, 16 }, /* 1509 */ { MAD_F(0x0439c377) /* 0.264102425 */, 16 }, /* 1510 */ { MAD_F(0x043ab82f) /* 0.264335808 */, 16 }, /* 1511 */ { MAD_F(0x043bacf5) /* 0.264569243 */, 16 }, /* 1512 */ { MAD_F(0x043ca1c9) /* 0.264802730 */, 16 }, /* 1513 */ { MAD_F(0x043d96ab) /* 0.265036267 */, 16 }, /* 1514 */ { MAD_F(0x043e8b9b) /* 0.265269857 */, 16 }, /* 1515 */ { MAD_F(0x043f8098) /* 0.265503498 */, 16 }, /* 1516 */ { MAD_F(0x044075a3) /* 0.265737190 */, 16 }, /* 1517 */ { MAD_F(0x04416abc) /* 0.265970933 */, 16 }, /* 1518 */ { MAD_F(0x04425fe3) /* 0.266204728 */, 16 }, /* 1519 */ { MAD_F(0x04435518) /* 0.266438574 */, 16 }, /* 1520 */ { MAD_F(0x04444a5a) /* 0.266672472 */, 16 }, /* 1521 */ { MAD_F(0x04453fab) /* 0.266906421 */, 16 }, /* 1522 */ { MAD_F(0x04463508) /* 0.267140421 */, 16 }, /* 1523 */ { MAD_F(0x04472a74) /* 0.267374472 */, 16 }, /* 1524 */ { MAD_F(0x04481fee) /* 0.267608575 */, 16 }, /* 1525 */ { MAD_F(0x04491575) /* 0.267842729 */, 16 }, /* 1526 */ { MAD_F(0x044a0b0a) /* 0.268076934 */, 16 }, /* 1527 */ { MAD_F(0x044b00ac) /* 0.268311190 */, 16 }, /* 1528 */ { MAD_F(0x044bf65d) /* 0.268545497 */, 16 }, /* 1529 */ { MAD_F(0x044cec1b) /* 0.268779856 */, 16 }, /* 1530 */ { MAD_F(0x044de1e7) /* 0.269014265 */, 16 }, /* 1531 */ { MAD_F(0x044ed7c0) /* 0.269248726 */, 16 }, /* 1532 */ { MAD_F(0x044fcda8) /* 0.269483238 */, 16 }, /* 1533 */ { MAD_F(0x0450c39c) /* 0.269717800 */, 16 }, /* 1534 */ { MAD_F(0x0451b99f) /* 0.269952414 */, 16 }, /* 1535 */ { MAD_F(0x0452afaf) /* 0.270187079 */, 16 }, /* 1536 */ { MAD_F(0x0453a5cd) /* 0.270421794 */, 16 }, /* 1537 */ { MAD_F(0x04549bf9) /* 0.270656561 */, 16 }, /* 1538 */ { MAD_F(0x04559232) /* 0.270891379 */, 16 }, /* 1539 */ { MAD_F(0x04568879) /* 0.271126247 */, 16 }, /* 1540 */ { MAD_F(0x04577ece) /* 0.271361166 */, 16 }, /* 1541 */ { MAD_F(0x04587530) /* 0.271596136 */, 16 }, /* 1542 */ { MAD_F(0x04596ba0) /* 0.271831157 */, 16 }, /* 1543 */ { MAD_F(0x045a621e) /* 0.272066229 */, 16 }, /* 1544 */ { MAD_F(0x045b58a9) /* 0.272301352 */, 16 }, /* 1545 */ { MAD_F(0x045c4f42) /* 0.272536525 */, 16 }, /* 1546 */ { MAD_F(0x045d45e9) /* 0.272771749 */, 16 }, /* 1547 */ { MAD_F(0x045e3c9d) /* 0.273007024 */, 16 }, /* 1548 */ { MAD_F(0x045f335e) /* 0.273242350 */, 16 }, /* 1549 */ { MAD_F(0x04602a2e) /* 0.273477726 */, 16 }, /* 1550 */ { MAD_F(0x0461210b) /* 0.273713153 */, 16 }, /* 1551 */ { MAD_F(0x046217f5) /* 0.273948630 */, 16 }, /* 1552 */ { MAD_F(0x04630eed) /* 0.274184158 */, 16 }, /* 1553 */ { MAD_F(0x046405f3) /* 0.274419737 */, 16 }, /* 1554 */ { MAD_F(0x0464fd06) /* 0.274655366 */, 16 }, /* 1555 */ { MAD_F(0x0465f427) /* 0.274891046 */, 16 }, /* 1556 */ { MAD_F(0x0466eb55) /* 0.275126776 */, 16 }, /* 1557 */ { MAD_F(0x0467e291) /* 0.275362557 */, 16 }, /* 1558 */ { MAD_F(0x0468d9db) /* 0.275598389 */, 16 }, /* 1559 */ { MAD_F(0x0469d132) /* 0.275834270 */, 16 }, /* 1560 */ { MAD_F(0x046ac896) /* 0.276070203 */, 16 }, /* 1561 */ { MAD_F(0x046bc009) /* 0.276306185 */, 16 }, /* 1562 */ { MAD_F(0x046cb788) /* 0.276542218 */, 16 }, /* 1563 */ { MAD_F(0x046daf15) /* 0.276778302 */, 16 }, /* 1564 */ { MAD_F(0x046ea6b0) /* 0.277014435 */, 16 }, /* 1565 */ { MAD_F(0x046f9e58) /* 0.277250619 */, 16 }, /* 1566 */ { MAD_F(0x0470960e) /* 0.277486854 */, 16 }, /* 1567 */ { MAD_F(0x04718dd1) /* 0.277723139 */, 16 }, /* 1568 */ { MAD_F(0x047285a2) /* 0.277959474 */, 16 }, /* 1569 */ { MAD_F(0x04737d80) /* 0.278195859 */, 16 }, /* 1570 */ { MAD_F(0x0474756c) /* 0.278432294 */, 16 }, /* 1571 */ { MAD_F(0x04756d65) /* 0.278668780 */, 16 }, /* 1572 */ { MAD_F(0x0476656b) /* 0.278905316 */, 16 }, /* 1573 */ { MAD_F(0x04775d7f) /* 0.279141902 */, 16 }, /* 1574 */ { MAD_F(0x047855a1) /* 0.279378538 */, 16 }, /* 1575 */ { MAD_F(0x04794dd0) /* 0.279615224 */, 16 }, /* 1576 */ { MAD_F(0x047a460c) /* 0.279851960 */, 16 }, /* 1577 */ { MAD_F(0x047b3e56) /* 0.280088747 */, 16 }, /* 1578 */ { MAD_F(0x047c36ae) /* 0.280325583 */, 16 }, /* 1579 */ { MAD_F(0x047d2f12) /* 0.280562470 */, 16 }, /* 1580 */ { MAD_F(0x047e2784) /* 0.280799406 */, 16 }, /* 1581 */ { MAD_F(0x047f2004) /* 0.281036393 */, 16 }, /* 1582 */ { MAD_F(0x04801891) /* 0.281273429 */, 16 }, /* 1583 */ { MAD_F(0x0481112b) /* 0.281510516 */, 16 }, /* 1584 */ { MAD_F(0x048209d3) /* 0.281747652 */, 16 }, /* 1585 */ { MAD_F(0x04830288) /* 0.281984838 */, 16 }, /* 1586 */ { MAD_F(0x0483fb4b) /* 0.282222075 */, 16 }, /* 1587 */ { MAD_F(0x0484f41b) /* 0.282459361 */, 16 }, /* 1588 */ { MAD_F(0x0485ecf8) /* 0.282696697 */, 16 }, /* 1589 */ { MAD_F(0x0486e5e3) /* 0.282934082 */, 16 }, /* 1590 */ { MAD_F(0x0487dedb) /* 0.283171518 */, 16 }, /* 1591 */ { MAD_F(0x0488d7e1) /* 0.283409003 */, 16 }, /* 1592 */ { MAD_F(0x0489d0f4) /* 0.283646538 */, 16 }, /* 1593 */ { MAD_F(0x048aca14) /* 0.283884123 */, 16 }, /* 1594 */ { MAD_F(0x048bc341) /* 0.284121757 */, 16 }, /* 1595 */ { MAD_F(0x048cbc7c) /* 0.284359441 */, 16 }, /* 1596 */ { MAD_F(0x048db5c4) /* 0.284597175 */, 16 }, /* 1597 */ { MAD_F(0x048eaf1a) /* 0.284834959 */, 16 }, /* 1598 */ { MAD_F(0x048fa87d) /* 0.285072792 */, 16 }, /* 1599 */ { MAD_F(0x0490a1ed) /* 0.285310675 */, 16 }, /* 1600 */ { MAD_F(0x04919b6a) /* 0.285548607 */, 16 }, /* 1601 */ { MAD_F(0x049294f5) /* 0.285786589 */, 16 }, /* 1602 */ { MAD_F(0x04938e8d) /* 0.286024621 */, 16 }, /* 1603 */ { MAD_F(0x04948833) /* 0.286262702 */, 16 }, /* 1604 */ { MAD_F(0x049581e5) /* 0.286500832 */, 16 }, /* 1605 */ { MAD_F(0x04967ba5) /* 0.286739012 */, 16 }, /* 1606 */ { MAD_F(0x04977573) /* 0.286977242 */, 16 }, /* 1607 */ { MAD_F(0x04986f4d) /* 0.287215521 */, 16 }, /* 1608 */ { MAD_F(0x04996935) /* 0.287453849 */, 16 }, /* 1609 */ { MAD_F(0x049a632a) /* 0.287692227 */, 16 }, /* 1610 */ { MAD_F(0x049b5d2c) /* 0.287930654 */, 16 }, /* 1611 */ { MAD_F(0x049c573c) /* 0.288169131 */, 16 }, /* 1612 */ { MAD_F(0x049d5159) /* 0.288407657 */, 16 }, /* 1613 */ { MAD_F(0x049e4b83) /* 0.288646232 */, 16 }, /* 1614 */ { MAD_F(0x049f45ba) /* 0.288884857 */, 16 }, /* 1615 */ { MAD_F(0x04a03ffe) /* 0.289123530 */, 16 }, /* 1616 */ { MAD_F(0x04a13a50) /* 0.289362253 */, 16 }, /* 1617 */ { MAD_F(0x04a234af) /* 0.289601026 */, 16 }, /* 1618 */ { MAD_F(0x04a32f1b) /* 0.289839847 */, 16 }, /* 1619 */ { MAD_F(0x04a42995) /* 0.290078718 */, 16 }, /* 1620 */ { MAD_F(0x04a5241b) /* 0.290317638 */, 16 }, /* 1621 */ { MAD_F(0x04a61eaf) /* 0.290556607 */, 16 }, /* 1622 */ { MAD_F(0x04a71950) /* 0.290795626 */, 16 }, /* 1623 */ { MAD_F(0x04a813fe) /* 0.291034693 */, 16 }, /* 1624 */ { MAD_F(0x04a90eba) /* 0.291273810 */, 16 }, /* 1625 */ { MAD_F(0x04aa0982) /* 0.291512975 */, 16 }, /* 1626 */ { MAD_F(0x04ab0458) /* 0.291752190 */, 16 }, /* 1627 */ { MAD_F(0x04abff3b) /* 0.291991453 */, 16 }, /* 1628 */ { MAD_F(0x04acfa2b) /* 0.292230766 */, 16 }, /* 1629 */ { MAD_F(0x04adf528) /* 0.292470128 */, 16 }, /* 1630 */ { MAD_F(0x04aef032) /* 0.292709539 */, 16 }, /* 1631 */ { MAD_F(0x04afeb4a) /* 0.292948998 */, 16 }, /* 1632 */ { MAD_F(0x04b0e66e) /* 0.293188507 */, 16 }, /* 1633 */ { MAD_F(0x04b1e1a0) /* 0.293428065 */, 16 }, /* 1634 */ { MAD_F(0x04b2dcdf) /* 0.293667671 */, 16 }, /* 1635 */ { MAD_F(0x04b3d82b) /* 0.293907326 */, 16 }, /* 1636 */ { MAD_F(0x04b4d384) /* 0.294147031 */, 16 }, /* 1637 */ { MAD_F(0x04b5ceea) /* 0.294386784 */, 16 }, /* 1638 */ { MAD_F(0x04b6ca5e) /* 0.294626585 */, 16 }, /* 1639 */ { MAD_F(0x04b7c5de) /* 0.294866436 */, 16 }, /* 1640 */ { MAD_F(0x04b8c16c) /* 0.295106336 */, 16 }, /* 1641 */ { MAD_F(0x04b9bd06) /* 0.295346284 */, 16 }, /* 1642 */ { MAD_F(0x04bab8ae) /* 0.295586281 */, 16 }, /* 1643 */ { MAD_F(0x04bbb463) /* 0.295826327 */, 16 }, /* 1644 */ { MAD_F(0x04bcb024) /* 0.296066421 */, 16 }, /* 1645 */ { MAD_F(0x04bdabf3) /* 0.296306564 */, 16 }, /* 1646 */ { MAD_F(0x04bea7cf) /* 0.296546756 */, 16 }, /* 1647 */ { MAD_F(0x04bfa3b8) /* 0.296786996 */, 16 }, /* 1648 */ { MAD_F(0x04c09faf) /* 0.297027285 */, 16 }, /* 1649 */ { MAD_F(0x04c19bb2) /* 0.297267623 */, 16 }, /* 1650 */ { MAD_F(0x04c297c2) /* 0.297508009 */, 16 }, /* 1651 */ { MAD_F(0x04c393df) /* 0.297748444 */, 16 }, /* 1652 */ { MAD_F(0x04c49009) /* 0.297988927 */, 16 }, /* 1653 */ { MAD_F(0x04c58c41) /* 0.298229459 */, 16 }, /* 1654 */ { MAD_F(0x04c68885) /* 0.298470039 */, 16 }, /* 1655 */ { MAD_F(0x04c784d6) /* 0.298710668 */, 16 }, /* 1656 */ { MAD_F(0x04c88135) /* 0.298951346 */, 16 }, /* 1657 */ { MAD_F(0x04c97da0) /* 0.299192071 */, 16 }, /* 1658 */ { MAD_F(0x04ca7a18) /* 0.299432846 */, 16 }, /* 1659 */ { MAD_F(0x04cb769e) /* 0.299673668 */, 16 }, /* 1660 */ { MAD_F(0x04cc7330) /* 0.299914539 */, 16 }, /* 1661 */ { MAD_F(0x04cd6fcf) /* 0.300155459 */, 16 }, /* 1662 */ { MAD_F(0x04ce6c7b) /* 0.300396426 */, 16 }, /* 1663 */ { MAD_F(0x04cf6935) /* 0.300637443 */, 16 }, /* 1664 */ { MAD_F(0x04d065fb) /* 0.300878507 */, 16 }, /* 1665 */ { MAD_F(0x04d162ce) /* 0.301119620 */, 16 }, /* 1666 */ { MAD_F(0x04d25fae) /* 0.301360781 */, 16 }, /* 1667 */ { MAD_F(0x04d35c9b) /* 0.301601990 */, 16 }, /* 1668 */ { MAD_F(0x04d45995) /* 0.301843247 */, 16 }, /* 1669 */ { MAD_F(0x04d5569c) /* 0.302084553 */, 16 }, /* 1670 */ { MAD_F(0x04d653b0) /* 0.302325907 */, 16 }, /* 1671 */ { MAD_F(0x04d750d1) /* 0.302567309 */, 16 }, /* 1672 */ { MAD_F(0x04d84dff) /* 0.302808759 */, 16 }, /* 1673 */ { MAD_F(0x04d94b3a) /* 0.303050257 */, 16 }, /* 1674 */ { MAD_F(0x04da4881) /* 0.303291804 */, 16 }, /* 1675 */ { MAD_F(0x04db45d6) /* 0.303533399 */, 16 }, /* 1676 */ { MAD_F(0x04dc4337) /* 0.303775041 */, 16 }, /* 1677 */ { MAD_F(0x04dd40a6) /* 0.304016732 */, 16 }, /* 1678 */ { MAD_F(0x04de3e21) /* 0.304258471 */, 16 }, /* 1679 */ { MAD_F(0x04df3ba9) /* 0.304500257 */, 16 }, /* 1680 */ { MAD_F(0x04e0393e) /* 0.304742092 */, 16 }, /* 1681 */ { MAD_F(0x04e136e0) /* 0.304983975 */, 16 }, /* 1682 */ { MAD_F(0x04e2348f) /* 0.305225906 */, 16 }, /* 1683 */ { MAD_F(0x04e3324b) /* 0.305467885 */, 16 }, /* 1684 */ { MAD_F(0x04e43013) /* 0.305709911 */, 16 }, /* 1685 */ { MAD_F(0x04e52de9) /* 0.305951986 */, 16 }, /* 1686 */ { MAD_F(0x04e62bcb) /* 0.306194108 */, 16 }, /* 1687 */ { MAD_F(0x04e729ba) /* 0.306436279 */, 16 }, /* 1688 */ { MAD_F(0x04e827b6) /* 0.306678497 */, 16 }, /* 1689 */ { MAD_F(0x04e925bf) /* 0.306920763 */, 16 }, /* 1690 */ { MAD_F(0x04ea23d4) /* 0.307163077 */, 16 }, /* 1691 */ { MAD_F(0x04eb21f7) /* 0.307405438 */, 16 }, /* 1692 */ { MAD_F(0x04ec2026) /* 0.307647848 */, 16 }, /* 1693 */ { MAD_F(0x04ed1e62) /* 0.307890305 */, 16 }, /* 1694 */ { MAD_F(0x04ee1cab) /* 0.308132810 */, 16 }, /* 1695 */ { MAD_F(0x04ef1b01) /* 0.308375362 */, 16 }, /* 1696 */ { MAD_F(0x04f01963) /* 0.308617963 */, 16 }, /* 1697 */ { MAD_F(0x04f117d3) /* 0.308860611 */, 16 }, /* 1698 */ { MAD_F(0x04f2164f) /* 0.309103306 */, 16 }, /* 1699 */ { MAD_F(0x04f314d8) /* 0.309346050 */, 16 }, /* 1700 */ { MAD_F(0x04f4136d) /* 0.309588841 */, 16 }, /* 1701 */ { MAD_F(0x04f51210) /* 0.309831679 */, 16 }, /* 1702 */ { MAD_F(0x04f610bf) /* 0.310074565 */, 16 }, /* 1703 */ { MAD_F(0x04f70f7b) /* 0.310317499 */, 16 }, /* 1704 */ { MAD_F(0x04f80e44) /* 0.310560480 */, 16 }, /* 1705 */ { MAD_F(0x04f90d19) /* 0.310803509 */, 16 }, /* 1706 */ { MAD_F(0x04fa0bfc) /* 0.311046586 */, 16 }, /* 1707 */ { MAD_F(0x04fb0aeb) /* 0.311289710 */, 16 }, /* 1708 */ { MAD_F(0x04fc09e7) /* 0.311532881 */, 16 }, /* 1709 */ { MAD_F(0x04fd08ef) /* 0.311776100 */, 16 }, /* 1710 */ { MAD_F(0x04fe0805) /* 0.312019366 */, 16 }, /* 1711 */ { MAD_F(0x04ff0727) /* 0.312262680 */, 16 }, /* 1712 */ { MAD_F(0x05000655) /* 0.312506041 */, 16 }, /* 1713 */ { MAD_F(0x05010591) /* 0.312749449 */, 16 }, /* 1714 */ { MAD_F(0x050204d9) /* 0.312992905 */, 16 }, /* 1715 */ { MAD_F(0x0503042e) /* 0.313236408 */, 16 }, /* 1716 */ { MAD_F(0x0504038f) /* 0.313479959 */, 16 }, /* 1717 */ { MAD_F(0x050502fe) /* 0.313723556 */, 16 }, /* 1718 */ { MAD_F(0x05060279) /* 0.313967202 */, 16 }, /* 1719 */ { MAD_F(0x05070200) /* 0.314210894 */, 16 }, /* 1720 */ { MAD_F(0x05080195) /* 0.314454634 */, 16 }, /* 1721 */ { MAD_F(0x05090136) /* 0.314698420 */, 16 }, /* 1722 */ { MAD_F(0x050a00e3) /* 0.314942255 */, 16 }, /* 1723 */ { MAD_F(0x050b009e) /* 0.315186136 */, 16 }, /* 1724 */ { MAD_F(0x050c0065) /* 0.315430064 */, 16 }, /* 1725 */ { MAD_F(0x050d0039) /* 0.315674040 */, 16 }, /* 1726 */ { MAD_F(0x050e0019) /* 0.315918063 */, 16 }, /* 1727 */ { MAD_F(0x050f0006) /* 0.316162133 */, 16 }, /* 1728 */ { MAD_F(0x05100000) /* 0.316406250 */, 16 }, /* 1729 */ { MAD_F(0x05110006) /* 0.316650414 */, 16 }, /* 1730 */ { MAD_F(0x05120019) /* 0.316894625 */, 16 }, /* 1731 */ { MAD_F(0x05130039) /* 0.317138884 */, 16 }, /* 1732 */ { MAD_F(0x05140065) /* 0.317383189 */, 16 }, /* 1733 */ { MAD_F(0x0515009e) /* 0.317627541 */, 16 }, /* 1734 */ { MAD_F(0x051600e3) /* 0.317871941 */, 16 }, /* 1735 */ { MAD_F(0x05170135) /* 0.318116387 */, 16 }, /* 1736 */ { MAD_F(0x05180194) /* 0.318360880 */, 16 }, /* 1737 */ { MAD_F(0x051901ff) /* 0.318605421 */, 16 }, /* 1738 */ { MAD_F(0x051a0277) /* 0.318850008 */, 16 }, /* 1739 */ { MAD_F(0x051b02fc) /* 0.319094642 */, 16 }, /* 1740 */ { MAD_F(0x051c038d) /* 0.319339323 */, 16 }, /* 1741 */ { MAD_F(0x051d042a) /* 0.319584051 */, 16 }, /* 1742 */ { MAD_F(0x051e04d4) /* 0.319828826 */, 16 }, /* 1743 */ { MAD_F(0x051f058b) /* 0.320073647 */, 16 }, /* 1744 */ { MAD_F(0x0520064f) /* 0.320318516 */, 16 }, /* 1745 */ { MAD_F(0x0521071f) /* 0.320563431 */, 16 }, /* 1746 */ { MAD_F(0x052207fb) /* 0.320808393 */, 16 }, /* 1747 */ { MAD_F(0x052308e4) /* 0.321053402 */, 16 }, /* 1748 */ { MAD_F(0x052409da) /* 0.321298457 */, 16 }, /* 1749 */ { MAD_F(0x05250adc) /* 0.321543560 */, 16 }, /* 1750 */ { MAD_F(0x05260bea) /* 0.321788709 */, 16 }, /* 1751 */ { MAD_F(0x05270d06) /* 0.322033904 */, 16 }, /* 1752 */ { MAD_F(0x05280e2d) /* 0.322279147 */, 16 }, /* 1753 */ { MAD_F(0x05290f62) /* 0.322524436 */, 16 }, /* 1754 */ { MAD_F(0x052a10a3) /* 0.322769771 */, 16 }, /* 1755 */ { MAD_F(0x052b11f0) /* 0.323015154 */, 16 }, /* 1756 */ { MAD_F(0x052c134a) /* 0.323260583 */, 16 }, /* 1757 */ { MAD_F(0x052d14b0) /* 0.323506058 */, 16 }, /* 1758 */ { MAD_F(0x052e1623) /* 0.323751580 */, 16 }, /* 1759 */ { MAD_F(0x052f17a2) /* 0.323997149 */, 16 }, /* 1760 */ { MAD_F(0x0530192e) /* 0.324242764 */, 16 }, /* 1761 */ { MAD_F(0x05311ac6) /* 0.324488426 */, 16 }, /* 1762 */ { MAD_F(0x05321c6b) /* 0.324734134 */, 16 }, /* 1763 */ { MAD_F(0x05331e1c) /* 0.324979889 */, 16 }, /* 1764 */ { MAD_F(0x05341fda) /* 0.325225690 */, 16 }, /* 1765 */ { MAD_F(0x053521a4) /* 0.325471538 */, 16 }, /* 1766 */ { MAD_F(0x0536237b) /* 0.325717432 */, 16 }, /* 1767 */ { MAD_F(0x0537255e) /* 0.325963372 */, 16 }, /* 1768 */ { MAD_F(0x0538274e) /* 0.326209359 */, 16 }, /* 1769 */ { MAD_F(0x0539294a) /* 0.326455392 */, 16 }, /* 1770 */ { MAD_F(0x053a2b52) /* 0.326701472 */, 16 }, /* 1771 */ { MAD_F(0x053b2d67) /* 0.326947598 */, 16 }, /* 1772 */ { MAD_F(0x053c2f89) /* 0.327193770 */, 16 }, /* 1773 */ { MAD_F(0x053d31b6) /* 0.327439989 */, 16 }, /* 1774 */ { MAD_F(0x053e33f1) /* 0.327686254 */, 16 }, /* 1775 */ { MAD_F(0x053f3637) /* 0.327932565 */, 16 }, /* 1776 */ { MAD_F(0x0540388a) /* 0.328178922 */, 16 }, /* 1777 */ { MAD_F(0x05413aea) /* 0.328425326 */, 16 }, /* 1778 */ { MAD_F(0x05423d56) /* 0.328671776 */, 16 }, /* 1779 */ { MAD_F(0x05433fce) /* 0.328918272 */, 16 }, /* 1780 */ { MAD_F(0x05444253) /* 0.329164814 */, 16 }, /* 1781 */ { MAD_F(0x054544e4) /* 0.329411403 */, 16 }, /* 1782 */ { MAD_F(0x05464781) /* 0.329658038 */, 16 }, /* 1783 */ { MAD_F(0x05474a2b) /* 0.329904718 */, 16 }, /* 1784 */ { MAD_F(0x05484ce2) /* 0.330151445 */, 16 }, /* 1785 */ { MAD_F(0x05494fa4) /* 0.330398218 */, 16 }, /* 1786 */ { MAD_F(0x054a5273) /* 0.330645037 */, 16 }, /* 1787 */ { MAD_F(0x054b554e) /* 0.330891903 */, 16 }, /* 1788 */ { MAD_F(0x054c5836) /* 0.331138814 */, 16 }, /* 1789 */ { MAD_F(0x054d5b2a) /* 0.331385771 */, 16 }, /* 1790 */ { MAD_F(0x054e5e2b) /* 0.331632774 */, 16 }, /* 1791 */ { MAD_F(0x054f6138) /* 0.331879824 */, 16 }, /* 1792 */ { MAD_F(0x05506451) /* 0.332126919 */, 16 }, /* 1793 */ { MAD_F(0x05516776) /* 0.332374060 */, 16 }, /* 1794 */ { MAD_F(0x05526aa8) /* 0.332621247 */, 16 }, /* 1795 */ { MAD_F(0x05536de6) /* 0.332868480 */, 16 }, /* 1796 */ { MAD_F(0x05547131) /* 0.333115759 */, 16 }, /* 1797 */ { MAD_F(0x05557487) /* 0.333363084 */, 16 }, /* 1798 */ { MAD_F(0x055677ea) /* 0.333610455 */, 16 }, /* 1799 */ { MAD_F(0x05577b5a) /* 0.333857872 */, 16 }, /* 1800 */ { MAD_F(0x05587ed5) /* 0.334105334 */, 16 }, /* 1801 */ { MAD_F(0x0559825e) /* 0.334352843 */, 16 }, /* 1802 */ { MAD_F(0x055a85f2) /* 0.334600397 */, 16 }, /* 1803 */ { MAD_F(0x055b8992) /* 0.334847997 */, 16 }, /* 1804 */ { MAD_F(0x055c8d3f) /* 0.335095642 */, 16 }, /* 1805 */ { MAD_F(0x055d90f9) /* 0.335343334 */, 16 }, /* 1806 */ { MAD_F(0x055e94be) /* 0.335591071 */, 16 }, /* 1807 */ { MAD_F(0x055f9890) /* 0.335838854 */, 16 }, /* 1808 */ { MAD_F(0x05609c6e) /* 0.336086683 */, 16 }, /* 1809 */ { MAD_F(0x0561a058) /* 0.336334557 */, 16 }, /* 1810 */ { MAD_F(0x0562a44f) /* 0.336582477 */, 16 }, /* 1811 */ { MAD_F(0x0563a851) /* 0.336830443 */, 16 }, /* 1812 */ { MAD_F(0x0564ac60) /* 0.337078454 */, 16 }, /* 1813 */ { MAD_F(0x0565b07c) /* 0.337326511 */, 16 }, /* 1814 */ { MAD_F(0x0566b4a3) /* 0.337574614 */, 16 }, /* 1815 */ { MAD_F(0x0567b8d7) /* 0.337822762 */, 16 }, /* 1816 */ { MAD_F(0x0568bd17) /* 0.338070956 */, 16 }, /* 1817 */ { MAD_F(0x0569c163) /* 0.338319195 */, 16 }, /* 1818 */ { MAD_F(0x056ac5bc) /* 0.338567480 */, 16 }, /* 1819 */ { MAD_F(0x056bca20) /* 0.338815811 */, 16 }, /* 1820 */ { MAD_F(0x056cce91) /* 0.339064186 */, 16 }, /* 1821 */ { MAD_F(0x056dd30e) /* 0.339312608 */, 16 }, /* 1822 */ { MAD_F(0x056ed798) /* 0.339561075 */, 16 }, /* 1823 */ { MAD_F(0x056fdc2d) /* 0.339809587 */, 16 }, /* 1824 */ { MAD_F(0x0570e0cf) /* 0.340058145 */, 16 }, /* 1825 */ { MAD_F(0x0571e57d) /* 0.340306748 */, 16 }, /* 1826 */ { MAD_F(0x0572ea37) /* 0.340555397 */, 16 }, /* 1827 */ { MAD_F(0x0573eefd) /* 0.340804091 */, 16 }, /* 1828 */ { MAD_F(0x0574f3d0) /* 0.341052830 */, 16 }, /* 1829 */ { MAD_F(0x0575f8ae) /* 0.341301615 */, 16 }, /* 1830 */ { MAD_F(0x0576fd99) /* 0.341550445 */, 16 }, /* 1831 */ { MAD_F(0x05780290) /* 0.341799321 */, 16 }, /* 1832 */ { MAD_F(0x05790793) /* 0.342048241 */, 16 }, /* 1833 */ { MAD_F(0x057a0ca3) /* 0.342297207 */, 16 }, /* 1834 */ { MAD_F(0x057b11be) /* 0.342546219 */, 16 }, /* 1835 */ { MAD_F(0x057c16e6) /* 0.342795275 */, 16 }, /* 1836 */ { MAD_F(0x057d1c1a) /* 0.343044377 */, 16 }, /* 1837 */ { MAD_F(0x057e2159) /* 0.343293524 */, 16 }, /* 1838 */ { MAD_F(0x057f26a6) /* 0.343542717 */, 16 }, /* 1839 */ { MAD_F(0x05802bfe) /* 0.343791954 */, 16 }, /* 1840 */ { MAD_F(0x05813162) /* 0.344041237 */, 16 }, /* 1841 */ { MAD_F(0x058236d2) /* 0.344290564 */, 16 }, /* 1842 */ { MAD_F(0x05833c4f) /* 0.344539937 */, 16 }, /* 1843 */ { MAD_F(0x058441d8) /* 0.344789356 */, 16 }, /* 1844 */ { MAD_F(0x0585476c) /* 0.345038819 */, 16 }, /* 1845 */ { MAD_F(0x05864d0d) /* 0.345288327 */, 16 }, /* 1846 */ { MAD_F(0x058752ba) /* 0.345537880 */, 16 }, /* 1847 */ { MAD_F(0x05885873) /* 0.345787479 */, 16 }, /* 1848 */ { MAD_F(0x05895e39) /* 0.346037122 */, 16 }, /* 1849 */ { MAD_F(0x058a640a) /* 0.346286811 */, 16 }, /* 1850 */ { MAD_F(0x058b69e7) /* 0.346536545 */, 16 }, /* 1851 */ { MAD_F(0x058c6fd1) /* 0.346786323 */, 16 }, /* 1852 */ { MAD_F(0x058d75c6) /* 0.347036147 */, 16 }, /* 1853 */ { MAD_F(0x058e7bc8) /* 0.347286015 */, 16 }, /* 1854 */ { MAD_F(0x058f81d5) /* 0.347535929 */, 16 }, /* 1855 */ { MAD_F(0x059087ef) /* 0.347785887 */, 16 }, /* 1856 */ { MAD_F(0x05918e15) /* 0.348035890 */, 16 }, /* 1857 */ { MAD_F(0x05929447) /* 0.348285939 */, 16 }, /* 1858 */ { MAD_F(0x05939a84) /* 0.348536032 */, 16 }, /* 1859 */ { MAD_F(0x0594a0ce) /* 0.348786170 */, 16 }, /* 1860 */ { MAD_F(0x0595a724) /* 0.349036353 */, 16 }, /* 1861 */ { MAD_F(0x0596ad86) /* 0.349286580 */, 16 }, /* 1862 */ { MAD_F(0x0597b3f4) /* 0.349536853 */, 16 }, /* 1863 */ { MAD_F(0x0598ba6e) /* 0.349787170 */, 16 }, /* 1864 */ { MAD_F(0x0599c0f4) /* 0.350037532 */, 16 }, /* 1865 */ { MAD_F(0x059ac786) /* 0.350287939 */, 16 }, /* 1866 */ { MAD_F(0x059bce25) /* 0.350538391 */, 16 }, /* 1867 */ { MAD_F(0x059cd4cf) /* 0.350788887 */, 16 }, /* 1868 */ { MAD_F(0x059ddb85) /* 0.351039428 */, 16 }, /* 1869 */ { MAD_F(0x059ee247) /* 0.351290014 */, 16 }, /* 1870 */ { MAD_F(0x059fe915) /* 0.351540645 */, 16 }, /* 1871 */ { MAD_F(0x05a0efef) /* 0.351791320 */, 16 }, /* 1872 */ { MAD_F(0x05a1f6d5) /* 0.352042040 */, 16 }, /* 1873 */ { MAD_F(0x05a2fdc7) /* 0.352292804 */, 16 }, /* 1874 */ { MAD_F(0x05a404c5) /* 0.352543613 */, 16 }, /* 1875 */ { MAD_F(0x05a50bcf) /* 0.352794467 */, 16 }, /* 1876 */ { MAD_F(0x05a612e5) /* 0.353045365 */, 16 }, /* 1877 */ { MAD_F(0x05a71a07) /* 0.353296308 */, 16 }, /* 1878 */ { MAD_F(0x05a82135) /* 0.353547296 */, 16 }, /* 1879 */ { MAD_F(0x05a9286f) /* 0.353798328 */, 16 }, /* 1880 */ { MAD_F(0x05aa2fb5) /* 0.354049405 */, 16 }, /* 1881 */ { MAD_F(0x05ab3707) /* 0.354300526 */, 16 }, /* 1882 */ { MAD_F(0x05ac3e65) /* 0.354551691 */, 16 }, /* 1883 */ { MAD_F(0x05ad45ce) /* 0.354802901 */, 16 }, /* 1884 */ { MAD_F(0x05ae4d44) /* 0.355054156 */, 16 }, /* 1885 */ { MAD_F(0x05af54c6) /* 0.355305455 */, 16 }, /* 1886 */ { MAD_F(0x05b05c53) /* 0.355556799 */, 16 }, /* 1887 */ { MAD_F(0x05b163ed) /* 0.355808187 */, 16 }, /* 1888 */ { MAD_F(0x05b26b92) /* 0.356059619 */, 16 }, /* 1889 */ { MAD_F(0x05b37343) /* 0.356311096 */, 16 }, /* 1890 */ { MAD_F(0x05b47b00) /* 0.356562617 */, 16 }, /* 1891 */ { MAD_F(0x05b582c9) /* 0.356814182 */, 16 }, /* 1892 */ { MAD_F(0x05b68a9e) /* 0.357065792 */, 16 }, /* 1893 */ { MAD_F(0x05b7927f) /* 0.357317446 */, 16 }, /* 1894 */ { MAD_F(0x05b89a6c) /* 0.357569145 */, 16 }, /* 1895 */ { MAD_F(0x05b9a265) /* 0.357820887 */, 16 }, /* 1896 */ { MAD_F(0x05baaa69) /* 0.358072674 */, 16 }, /* 1897 */ { MAD_F(0x05bbb27a) /* 0.358324506 */, 16 }, /* 1898 */ { MAD_F(0x05bcba96) /* 0.358576381 */, 16 }, /* 1899 */ { MAD_F(0x05bdc2be) /* 0.358828301 */, 16 }, /* 1900 */ { MAD_F(0x05becaf2) /* 0.359080265 */, 16 }, /* 1901 */ { MAD_F(0x05bfd332) /* 0.359332273 */, 16 }, /* 1902 */ { MAD_F(0x05c0db7e) /* 0.359584326 */, 16 }, /* 1903 */ { MAD_F(0x05c1e3d6) /* 0.359836423 */, 16 }, /* 1904 */ { MAD_F(0x05c2ec39) /* 0.360088563 */, 16 }, /* 1905 */ { MAD_F(0x05c3f4a9) /* 0.360340748 */, 16 }, /* 1906 */ { MAD_F(0x05c4fd24) /* 0.360592977 */, 16 }, /* 1907 */ { MAD_F(0x05c605ab) /* 0.360845251 */, 16 }, /* 1908 */ { MAD_F(0x05c70e3e) /* 0.361097568 */, 16 }, /* 1909 */ { MAD_F(0x05c816dd) /* 0.361349929 */, 16 }, /* 1910 */ { MAD_F(0x05c91f87) /* 0.361602335 */, 16 }, /* 1911 */ { MAD_F(0x05ca283e) /* 0.361854784 */, 16 }, /* 1912 */ { MAD_F(0x05cb3100) /* 0.362107278 */, 16 }, /* 1913 */ { MAD_F(0x05cc39ce) /* 0.362359815 */, 16 }, /* 1914 */ { MAD_F(0x05cd42a8) /* 0.362612397 */, 16 }, /* 1915 */ { MAD_F(0x05ce4b8d) /* 0.362865022 */, 16 }, /* 1916 */ { MAD_F(0x05cf547f) /* 0.363117692 */, 16 }, /* 1917 */ { MAD_F(0x05d05d7c) /* 0.363370405 */, 16 }, /* 1918 */ { MAD_F(0x05d16685) /* 0.363623163 */, 16 }, /* 1919 */ { MAD_F(0x05d26f9a) /* 0.363875964 */, 16 }, /* 1920 */ { MAD_F(0x05d378bb) /* 0.364128809 */, 16 }, /* 1921 */ { MAD_F(0x05d481e7) /* 0.364381698 */, 16 }, /* 1922 */ { MAD_F(0x05d58b1f) /* 0.364634632 */, 16 }, /* 1923 */ { MAD_F(0x05d69463) /* 0.364887608 */, 16 }, /* 1924 */ { MAD_F(0x05d79db3) /* 0.365140629 */, 16 }, /* 1925 */ { MAD_F(0x05d8a70f) /* 0.365393694 */, 16 }, /* 1926 */ { MAD_F(0x05d9b076) /* 0.365646802 */, 16 }, /* 1927 */ { MAD_F(0x05dab9e9) /* 0.365899955 */, 16 }, /* 1928 */ { MAD_F(0x05dbc368) /* 0.366153151 */, 16 }, /* 1929 */ { MAD_F(0x05dcccf2) /* 0.366406390 */, 16 }, /* 1930 */ { MAD_F(0x05ddd689) /* 0.366659674 */, 16 }, /* 1931 */ { MAD_F(0x05dee02b) /* 0.366913001 */, 16 }, /* 1932 */ { MAD_F(0x05dfe9d8) /* 0.367166372 */, 16 }, /* 1933 */ { MAD_F(0x05e0f392) /* 0.367419787 */, 16 }, /* 1934 */ { MAD_F(0x05e1fd57) /* 0.367673246 */, 16 }, /* 1935 */ { MAD_F(0x05e30728) /* 0.367926748 */, 16 }, /* 1936 */ { MAD_F(0x05e41105) /* 0.368180294 */, 16 }, /* 1937 */ { MAD_F(0x05e51aed) /* 0.368433883 */, 16 }, /* 1938 */ { MAD_F(0x05e624e1) /* 0.368687517 */, 16 }, /* 1939 */ { MAD_F(0x05e72ee1) /* 0.368941193 */, 16 }, /* 1940 */ { MAD_F(0x05e838ed) /* 0.369194914 */, 16 }, /* 1941 */ { MAD_F(0x05e94304) /* 0.369448678 */, 16 }, /* 1942 */ { MAD_F(0x05ea4d27) /* 0.369702485 */, 16 }, /* 1943 */ { MAD_F(0x05eb5756) /* 0.369956336 */, 16 }, /* 1944 */ { MAD_F(0x05ec6190) /* 0.370210231 */, 16 }, /* 1945 */ { MAD_F(0x05ed6bd6) /* 0.370464169 */, 16 }, /* 1946 */ { MAD_F(0x05ee7628) /* 0.370718151 */, 16 }, /* 1947 */ { MAD_F(0x05ef8085) /* 0.370972177 */, 16 }, /* 1948 */ { MAD_F(0x05f08aee) /* 0.371226245 */, 16 }, /* 1949 */ { MAD_F(0x05f19563) /* 0.371480358 */, 16 }, /* 1950 */ { MAD_F(0x05f29fe3) /* 0.371734513 */, 16 }, /* 1951 */ { MAD_F(0x05f3aa6f) /* 0.371988712 */, 16 }, /* 1952 */ { MAD_F(0x05f4b507) /* 0.372242955 */, 16 }, /* 1953 */ { MAD_F(0x05f5bfab) /* 0.372497241 */, 16 }, /* 1954 */ { MAD_F(0x05f6ca5a) /* 0.372751570 */, 16 }, /* 1955 */ { MAD_F(0x05f7d514) /* 0.373005943 */, 16 }, /* 1956 */ { MAD_F(0x05f8dfdb) /* 0.373260359 */, 16 }, /* 1957 */ { MAD_F(0x05f9eaad) /* 0.373514819 */, 16 }, /* 1958 */ { MAD_F(0x05faf58a) /* 0.373769322 */, 16 }, /* 1959 */ { MAD_F(0x05fc0073) /* 0.374023868 */, 16 }, /* 1960 */ { MAD_F(0x05fd0b68) /* 0.374278458 */, 16 }, /* 1961 */ { MAD_F(0x05fe1669) /* 0.374533091 */, 16 }, /* 1962 */ { MAD_F(0x05ff2175) /* 0.374787767 */, 16 }, /* 1963 */ { MAD_F(0x06002c8d) /* 0.375042486 */, 16 }, /* 1964 */ { MAD_F(0x060137b0) /* 0.375297249 */, 16 }, /* 1965 */ { MAD_F(0x060242df) /* 0.375552055 */, 16 }, /* 1966 */ { MAD_F(0x06034e19) /* 0.375806904 */, 16 }, /* 1967 */ { MAD_F(0x0604595f) /* 0.376061796 */, 16 }, /* 1968 */ { MAD_F(0x060564b1) /* 0.376316732 */, 16 }, /* 1969 */ { MAD_F(0x0606700f) /* 0.376571710 */, 16 }, /* 1970 */ { MAD_F(0x06077b77) /* 0.376826732 */, 16 }, /* 1971 */ { MAD_F(0x060886ec) /* 0.377081797 */, 16 }, /* 1972 */ { MAD_F(0x0609926c) /* 0.377336905 */, 16 }, /* 1973 */ { MAD_F(0x060a9df8) /* 0.377592057 */, 16 }, /* 1974 */ { MAD_F(0x060ba98f) /* 0.377847251 */, 16 }, /* 1975 */ { MAD_F(0x060cb532) /* 0.378102489 */, 16 }, /* 1976 */ { MAD_F(0x060dc0e0) /* 0.378357769 */, 16 }, /* 1977 */ { MAD_F(0x060ecc9a) /* 0.378613093 */, 16 }, /* 1978 */ { MAD_F(0x060fd860) /* 0.378868460 */, 16 }, /* 1979 */ { MAD_F(0x0610e431) /* 0.379123870 */, 16 }, /* 1980 */ { MAD_F(0x0611f00d) /* 0.379379322 */, 16 }, /* 1981 */ { MAD_F(0x0612fbf5) /* 0.379634818 */, 16 }, /* 1982 */ { MAD_F(0x061407e9) /* 0.379890357 */, 16 }, /* 1983 */ { MAD_F(0x061513e8) /* 0.380145939 */, 16 }, /* 1984 */ { MAD_F(0x06161ff3) /* 0.380401563 */, 16 }, /* 1985 */ { MAD_F(0x06172c09) /* 0.380657231 */, 16 }, /* 1986 */ { MAD_F(0x0618382b) /* 0.380912942 */, 16 }, /* 1987 */ { MAD_F(0x06194458) /* 0.381168695 */, 16 }, /* 1988 */ { MAD_F(0x061a5091) /* 0.381424492 */, 16 }, /* 1989 */ { MAD_F(0x061b5cd5) /* 0.381680331 */, 16 }, /* 1990 */ { MAD_F(0x061c6925) /* 0.381936213 */, 16 }, /* 1991 */ { MAD_F(0x061d7581) /* 0.382192138 */, 16 }, /* 1992 */ { MAD_F(0x061e81e8) /* 0.382448106 */, 16 }, /* 1993 */ { MAD_F(0x061f8e5a) /* 0.382704117 */, 16 }, /* 1994 */ { MAD_F(0x06209ad8) /* 0.382960171 */, 16 }, /* 1995 */ { MAD_F(0x0621a761) /* 0.383216267 */, 16 }, /* 1996 */ { MAD_F(0x0622b3f6) /* 0.383472406 */, 16 }, /* 1997 */ { MAD_F(0x0623c096) /* 0.383728588 */, 16 }, /* 1998 */ { MAD_F(0x0624cd42) /* 0.383984813 */, 16 }, /* 1999 */ { MAD_F(0x0625d9f9) /* 0.384241080 */, 16 }, /* 2000 */ { MAD_F(0x0626e6bc) /* 0.384497391 */, 16 }, /* 2001 */ { MAD_F(0x0627f38a) /* 0.384753744 */, 16 }, /* 2002 */ { MAD_F(0x06290064) /* 0.385010139 */, 16 }, /* 2003 */ { MAD_F(0x062a0d49) /* 0.385266578 */, 16 }, /* 2004 */ { MAD_F(0x062b1a3a) /* 0.385523059 */, 16 }, /* 2005 */ { MAD_F(0x062c2736) /* 0.385779582 */, 16 }, /* 2006 */ { MAD_F(0x062d343d) /* 0.386036149 */, 16 }, /* 2007 */ { MAD_F(0x062e4150) /* 0.386292758 */, 16 }, /* 2008 */ { MAD_F(0x062f4e6f) /* 0.386549409 */, 16 }, /* 2009 */ { MAD_F(0x06305b99) /* 0.386806104 */, 16 }, /* 2010 */ { MAD_F(0x063168ce) /* 0.387062840 */, 16 }, /* 2011 */ { MAD_F(0x0632760f) /* 0.387319620 */, 16 }, /* 2012 */ { MAD_F(0x0633835b) /* 0.387576442 */, 16 }, /* 2013 */ { MAD_F(0x063490b2) /* 0.387833306 */, 16 }, /* 2014 */ { MAD_F(0x06359e15) /* 0.388090213 */, 16 }, /* 2015 */ { MAD_F(0x0636ab83) /* 0.388347163 */, 16 }, /* 2016 */ { MAD_F(0x0637b8fd) /* 0.388604155 */, 16 }, /* 2017 */ { MAD_F(0x0638c682) /* 0.388861190 */, 16 }, /* 2018 */ { MAD_F(0x0639d413) /* 0.389118267 */, 16 }, /* 2019 */ { MAD_F(0x063ae1af) /* 0.389375386 */, 16 }, /* 2020 */ { MAD_F(0x063bef56) /* 0.389632548 */, 16 }, /* 2021 */ { MAD_F(0x063cfd09) /* 0.389889752 */, 16 }, /* 2022 */ { MAD_F(0x063e0ac7) /* 0.390146999 */, 16 }, /* 2023 */ { MAD_F(0x063f1891) /* 0.390404289 */, 16 }, /* 2024 */ { MAD_F(0x06402666) /* 0.390661620 */, 16 }, /* 2025 */ { MAD_F(0x06413446) /* 0.390918994 */, 16 }, /* 2026 */ { MAD_F(0x06424232) /* 0.391176411 */, 16 }, /* 2027 */ { MAD_F(0x06435029) /* 0.391433869 */, 16 }, /* 2028 */ { MAD_F(0x06445e2b) /* 0.391691371 */, 16 }, /* 2029 */ { MAD_F(0x06456c39) /* 0.391948914 */, 16 }, /* 2030 */ { MAD_F(0x06467a52) /* 0.392206500 */, 16 }, /* 2031 */ { MAD_F(0x06478877) /* 0.392464128 */, 16 }, /* 2032 */ { MAD_F(0x064896a7) /* 0.392721798 */, 16 }, /* 2033 */ { MAD_F(0x0649a4e2) /* 0.392979511 */, 16 }, /* 2034 */ { MAD_F(0x064ab328) /* 0.393237266 */, 16 }, /* 2035 */ { MAD_F(0x064bc17a) /* 0.393495063 */, 16 }, /* 2036 */ { MAD_F(0x064ccfd8) /* 0.393752902 */, 16 }, /* 2037 */ { MAD_F(0x064dde40) /* 0.394010784 */, 16 }, /* 2038 */ { MAD_F(0x064eecb4) /* 0.394268707 */, 16 }, /* 2039 */ { MAD_F(0x064ffb33) /* 0.394526673 */, 16 }, /* 2040 */ { MAD_F(0x065109be) /* 0.394784681 */, 16 }, /* 2041 */ { MAD_F(0x06521854) /* 0.395042732 */, 16 }, /* 2042 */ { MAD_F(0x065326f5) /* 0.395300824 */, 16 }, /* 2043 */ { MAD_F(0x065435a1) /* 0.395558959 */, 16 }, /* 2044 */ { MAD_F(0x06554459) /* 0.395817135 */, 16 }, /* 2045 */ { MAD_F(0x0656531c) /* 0.396075354 */, 16 }, /* 2046 */ { MAD_F(0x065761ea) /* 0.396333615 */, 16 }, /* 2047 */ { MAD_F(0x065870c4) /* 0.396591918 */, 16 }, /* 2048 */ { MAD_F(0x06597fa9) /* 0.396850263 */, 16 }, /* 2049 */ { MAD_F(0x065a8e99) /* 0.397108650 */, 16 }, /* 2050 */ { MAD_F(0x065b9d95) /* 0.397367079 */, 16 }, /* 2051 */ { MAD_F(0x065cac9c) /* 0.397625550 */, 16 }, /* 2052 */ { MAD_F(0x065dbbae) /* 0.397884063 */, 16 }, /* 2053 */ { MAD_F(0x065ecacb) /* 0.398142619 */, 16 }, /* 2054 */ { MAD_F(0x065fd9f4) /* 0.398401216 */, 16 }, /* 2055 */ { MAD_F(0x0660e928) /* 0.398659855 */, 16 }, /* 2056 */ { MAD_F(0x0661f867) /* 0.398918536 */, 16 }, /* 2057 */ { MAD_F(0x066307b1) /* 0.399177259 */, 16 }, /* 2058 */ { MAD_F(0x06641707) /* 0.399436024 */, 16 }, /* 2059 */ { MAD_F(0x06652668) /* 0.399694831 */, 16 }, /* 2060 */ { MAD_F(0x066635d4) /* 0.399953679 */, 16 }, /* 2061 */ { MAD_F(0x0667454c) /* 0.400212570 */, 16 }, /* 2062 */ { MAD_F(0x066854ce) /* 0.400471503 */, 16 }, /* 2063 */ { MAD_F(0x0669645c) /* 0.400730477 */, 16 }, /* 2064 */ { MAD_F(0x066a73f5) /* 0.400989493 */, 16 }, /* 2065 */ { MAD_F(0x066b839a) /* 0.401248551 */, 16 }, /* 2066 */ { MAD_F(0x066c9349) /* 0.401507651 */, 16 }, /* 2067 */ { MAD_F(0x066da304) /* 0.401766793 */, 16 }, /* 2068 */ { MAD_F(0x066eb2ca) /* 0.402025976 */, 16 }, /* 2069 */ { MAD_F(0x066fc29b) /* 0.402285202 */, 16 }, /* 2070 */ { MAD_F(0x0670d278) /* 0.402544469 */, 16 }, /* 2071 */ { MAD_F(0x0671e25f) /* 0.402803777 */, 16 }, /* 2072 */ { MAD_F(0x0672f252) /* 0.403063128 */, 16 }, /* 2073 */ { MAD_F(0x06740250) /* 0.403322520 */, 16 }, /* 2074 */ { MAD_F(0x0675125a) /* 0.403581954 */, 16 }, /* 2075 */ { MAD_F(0x0676226e) /* 0.403841430 */, 16 }, /* 2076 */ { MAD_F(0x0677328e) /* 0.404100947 */, 16 }, /* 2077 */ { MAD_F(0x067842b9) /* 0.404360506 */, 16 }, /* 2078 */ { MAD_F(0x067952ef) /* 0.404620107 */, 16 }, /* 2079 */ { MAD_F(0x067a6330) /* 0.404879749 */, 16 }, /* 2080 */ { MAD_F(0x067b737c) /* 0.405139433 */, 16 }, /* 2081 */ { MAD_F(0x067c83d4) /* 0.405399159 */, 16 }, /* 2082 */ { MAD_F(0x067d9436) /* 0.405658926 */, 16 }, /* 2083 */ { MAD_F(0x067ea4a4) /* 0.405918735 */, 16 }, /* 2084 */ { MAD_F(0x067fb51d) /* 0.406178585 */, 16 }, /* 2085 */ { MAD_F(0x0680c5a2) /* 0.406438477 */, 16 }, /* 2086 */ { MAD_F(0x0681d631) /* 0.406698410 */, 16 }, /* 2087 */ { MAD_F(0x0682e6cb) /* 0.406958385 */, 16 }, /* 2088 */ { MAD_F(0x0683f771) /* 0.407218402 */, 16 }, /* 2089 */ { MAD_F(0x06850822) /* 0.407478460 */, 16 }, /* 2090 */ { MAD_F(0x068618de) /* 0.407738559 */, 16 }, /* 2091 */ { MAD_F(0x068729a5) /* 0.407998700 */, 16 }, /* 2092 */ { MAD_F(0x06883a77) /* 0.408258883 */, 16 }, /* 2093 */ { MAD_F(0x06894b55) /* 0.408519107 */, 16 }, /* 2094 */ { MAD_F(0x068a5c3d) /* 0.408779372 */, 16 }, /* 2095 */ { MAD_F(0x068b6d31) /* 0.409039679 */, 16 }, /* 2096 */ { MAD_F(0x068c7e2f) /* 0.409300027 */, 16 }, /* 2097 */ { MAD_F(0x068d8f39) /* 0.409560417 */, 16 }, /* 2098 */ { MAD_F(0x068ea04e) /* 0.409820848 */, 16 }, /* 2099 */ { MAD_F(0x068fb16e) /* 0.410081321 */, 16 }, /* 2100 */ { MAD_F(0x0690c299) /* 0.410341834 */, 16 }, /* 2101 */ { MAD_F(0x0691d3cf) /* 0.410602390 */, 16 }, /* 2102 */ { MAD_F(0x0692e511) /* 0.410862986 */, 16 }, /* 2103 */ { MAD_F(0x0693f65d) /* 0.411123624 */, 16 }, /* 2104 */ { MAD_F(0x069507b5) /* 0.411384303 */, 16 }, /* 2105 */ { MAD_F(0x06961917) /* 0.411645024 */, 16 }, /* 2106 */ { MAD_F(0x06972a85) /* 0.411905785 */, 16 }, /* 2107 */ { MAD_F(0x06983bfe) /* 0.412166588 */, 16 }, /* 2108 */ { MAD_F(0x06994d82) /* 0.412427433 */, 16 }, /* 2109 */ { MAD_F(0x069a5f11) /* 0.412688318 */, 16 }, /* 2110 */ { MAD_F(0x069b70ab) /* 0.412949245 */, 16 }, /* 2111 */ { MAD_F(0x069c8250) /* 0.413210213 */, 16 }, /* 2112 */ { MAD_F(0x069d9400) /* 0.413471222 */, 16 }, /* 2113 */ { MAD_F(0x069ea5bb) /* 0.413732273 */, 16 }, /* 2114 */ { MAD_F(0x069fb781) /* 0.413993364 */, 16 }, /* 2115 */ { MAD_F(0x06a0c953) /* 0.414254497 */, 16 }, /* 2116 */ { MAD_F(0x06a1db2f) /* 0.414515671 */, 16 }, /* 2117 */ { MAD_F(0x06a2ed16) /* 0.414776886 */, 16 }, /* 2118 */ { MAD_F(0x06a3ff09) /* 0.415038142 */, 16 }, /* 2119 */ { MAD_F(0x06a51106) /* 0.415299440 */, 16 }, /* 2120 */ { MAD_F(0x06a6230f) /* 0.415560778 */, 16 }, /* 2121 */ { MAD_F(0x06a73522) /* 0.415822157 */, 16 }, /* 2122 */ { MAD_F(0x06a84741) /* 0.416083578 */, 16 }, /* 2123 */ { MAD_F(0x06a9596a) /* 0.416345040 */, 16 }, /* 2124 */ { MAD_F(0x06aa6b9f) /* 0.416606542 */, 16 }, /* 2125 */ { MAD_F(0x06ab7ddf) /* 0.416868086 */, 16 }, /* 2126 */ { MAD_F(0x06ac9029) /* 0.417129671 */, 16 }, /* 2127 */ { MAD_F(0x06ada27f) /* 0.417391297 */, 16 }, /* 2128 */ { MAD_F(0x06aeb4e0) /* 0.417652964 */, 16 }, /* 2129 */ { MAD_F(0x06afc74b) /* 0.417914672 */, 16 }, /* 2130 */ { MAD_F(0x06b0d9c2) /* 0.418176420 */, 16 }, /* 2131 */ { MAD_F(0x06b1ec43) /* 0.418438210 */, 16 }, /* 2132 */ { MAD_F(0x06b2fed0) /* 0.418700041 */, 16 }, /* 2133 */ { MAD_F(0x06b41168) /* 0.418961912 */, 16 }, /* 2134 */ { MAD_F(0x06b5240a) /* 0.419223825 */, 16 }, /* 2135 */ { MAD_F(0x06b636b8) /* 0.419485778 */, 16 }, /* 2136 */ { MAD_F(0x06b74971) /* 0.419747773 */, 16 }, /* 2137 */ { MAD_F(0x06b85c34) /* 0.420009808 */, 16 }, /* 2138 */ { MAD_F(0x06b96f03) /* 0.420271884 */, 16 }, /* 2139 */ { MAD_F(0x06ba81dc) /* 0.420534001 */, 16 }, /* 2140 */ { MAD_F(0x06bb94c1) /* 0.420796159 */, 16 }, /* 2141 */ { MAD_F(0x06bca7b0) /* 0.421058358 */, 16 }, /* 2142 */ { MAD_F(0x06bdbaaa) /* 0.421320597 */, 16 }, /* 2143 */ { MAD_F(0x06becdb0) /* 0.421582878 */, 16 }, /* 2144 */ { MAD_F(0x06bfe0c0) /* 0.421845199 */, 16 }, /* 2145 */ { MAD_F(0x06c0f3db) /* 0.422107561 */, 16 }, /* 2146 */ { MAD_F(0x06c20702) /* 0.422369964 */, 16 }, /* 2147 */ { MAD_F(0x06c31a33) /* 0.422632407 */, 16 }, /* 2148 */ { MAD_F(0x06c42d6f) /* 0.422894891 */, 16 }, /* 2149 */ { MAD_F(0x06c540b6) /* 0.423157416 */, 16 }, /* 2150 */ { MAD_F(0x06c65408) /* 0.423419982 */, 16 }, /* 2151 */ { MAD_F(0x06c76765) /* 0.423682588 */, 16 }, /* 2152 */ { MAD_F(0x06c87acc) /* 0.423945235 */, 16 }, /* 2153 */ { MAD_F(0x06c98e3f) /* 0.424207923 */, 16 }, /* 2154 */ { MAD_F(0x06caa1bd) /* 0.424470652 */, 16 }, /* 2155 */ { MAD_F(0x06cbb545) /* 0.424733421 */, 16 }, /* 2156 */ { MAD_F(0x06ccc8d9) /* 0.424996230 */, 16 }, /* 2157 */ { MAD_F(0x06cddc77) /* 0.425259081 */, 16 }, /* 2158 */ { MAD_F(0x06cef020) /* 0.425521972 */, 16 }, /* 2159 */ { MAD_F(0x06d003d4) /* 0.425784903 */, 16 }, /* 2160 */ { MAD_F(0x06d11794) /* 0.426047876 */, 16 }, /* 2161 */ { MAD_F(0x06d22b5e) /* 0.426310889 */, 16 }, /* 2162 */ { MAD_F(0x06d33f32) /* 0.426573942 */, 16 }, /* 2163 */ { MAD_F(0x06d45312) /* 0.426837036 */, 16 }, /* 2164 */ { MAD_F(0x06d566fd) /* 0.427100170 */, 16 }, /* 2165 */ { MAD_F(0x06d67af2) /* 0.427363345 */, 16 }, /* 2166 */ { MAD_F(0x06d78ef3) /* 0.427626561 */, 16 }, /* 2167 */ { MAD_F(0x06d8a2fe) /* 0.427889817 */, 16 }, /* 2168 */ { MAD_F(0x06d9b714) /* 0.428153114 */, 16 }, /* 2169 */ { MAD_F(0x06dacb35) /* 0.428416451 */, 16 }, /* 2170 */ { MAD_F(0x06dbdf61) /* 0.428679828 */, 16 }, /* 2171 */ { MAD_F(0x06dcf398) /* 0.428943246 */, 16 }, /* 2172 */ { MAD_F(0x06de07d9) /* 0.429206704 */, 16 }, /* 2173 */ { MAD_F(0x06df1c26) /* 0.429470203 */, 16 }, /* 2174 */ { MAD_F(0x06e0307d) /* 0.429733743 */, 16 }, /* 2175 */ { MAD_F(0x06e144df) /* 0.429997322 */, 16 }, /* 2176 */ { MAD_F(0x06e2594c) /* 0.430260942 */, 16 }, /* 2177 */ { MAD_F(0x06e36dc4) /* 0.430524603 */, 16 }, /* 2178 */ { MAD_F(0x06e48246) /* 0.430788304 */, 16 }, /* 2179 */ { MAD_F(0x06e596d4) /* 0.431052045 */, 16 }, /* 2180 */ { MAD_F(0x06e6ab6c) /* 0.431315826 */, 16 }, /* 2181 */ { MAD_F(0x06e7c00f) /* 0.431579648 */, 16 }, /* 2182 */ { MAD_F(0x06e8d4bd) /* 0.431843511 */, 16 }, /* 2183 */ { MAD_F(0x06e9e976) /* 0.432107413 */, 16 }, /* 2184 */ { MAD_F(0x06eafe3a) /* 0.432371356 */, 16 }, /* 2185 */ { MAD_F(0x06ec1308) /* 0.432635339 */, 16 }, /* 2186 */ { MAD_F(0x06ed27e2) /* 0.432899362 */, 16 }, /* 2187 */ { MAD_F(0x06ee3cc6) /* 0.433163426 */, 16 }, /* 2188 */ { MAD_F(0x06ef51b4) /* 0.433427530 */, 16 }, /* 2189 */ { MAD_F(0x06f066ae) /* 0.433691674 */, 16 }, /* 2190 */ { MAD_F(0x06f17bb3) /* 0.433955859 */, 16 }, /* 2191 */ { MAD_F(0x06f290c2) /* 0.434220083 */, 16 }, /* 2192 */ { MAD_F(0x06f3a5dc) /* 0.434484348 */, 16 }, /* 2193 */ { MAD_F(0x06f4bb01) /* 0.434748653 */, 16 }, /* 2194 */ { MAD_F(0x06f5d030) /* 0.435012998 */, 16 }, /* 2195 */ { MAD_F(0x06f6e56b) /* 0.435277383 */, 16 }, /* 2196 */ { MAD_F(0x06f7fab0) /* 0.435541809 */, 16 }, /* 2197 */ { MAD_F(0x06f91000) /* 0.435806274 */, 16 }, /* 2198 */ { MAD_F(0x06fa255a) /* 0.436070780 */, 16 }, /* 2199 */ { MAD_F(0x06fb3ac0) /* 0.436335326 */, 16 }, /* 2200 */ { MAD_F(0x06fc5030) /* 0.436599912 */, 16 }, /* 2201 */ { MAD_F(0x06fd65ab) /* 0.436864538 */, 16 }, /* 2202 */ { MAD_F(0x06fe7b31) /* 0.437129204 */, 16 }, /* 2203 */ { MAD_F(0x06ff90c2) /* 0.437393910 */, 16 }, /* 2204 */ { MAD_F(0x0700a65d) /* 0.437658657 */, 16 }, /* 2205 */ { MAD_F(0x0701bc03) /* 0.437923443 */, 16 }, /* 2206 */ { MAD_F(0x0702d1b4) /* 0.438188269 */, 16 }, /* 2207 */ { MAD_F(0x0703e76f) /* 0.438453136 */, 16 }, /* 2208 */ { MAD_F(0x0704fd35) /* 0.438718042 */, 16 }, /* 2209 */ { MAD_F(0x07061306) /* 0.438982988 */, 16 }, /* 2210 */ { MAD_F(0x070728e2) /* 0.439247975 */, 16 }, /* 2211 */ { MAD_F(0x07083ec9) /* 0.439513001 */, 16 }, /* 2212 */ { MAD_F(0x070954ba) /* 0.439778067 */, 16 }, /* 2213 */ { MAD_F(0x070a6ab6) /* 0.440043173 */, 16 }, /* 2214 */ { MAD_F(0x070b80bc) /* 0.440308320 */, 16 }, /* 2215 */ { MAD_F(0x070c96ce) /* 0.440573506 */, 16 }, /* 2216 */ { MAD_F(0x070dacea) /* 0.440838732 */, 16 }, /* 2217 */ { MAD_F(0x070ec310) /* 0.441103997 */, 16 }, /* 2218 */ { MAD_F(0x070fd942) /* 0.441369303 */, 16 }, /* 2219 */ { MAD_F(0x0710ef7e) /* 0.441634649 */, 16 }, /* 2220 */ { MAD_F(0x071205c5) /* 0.441900034 */, 16 }, /* 2221 */ { MAD_F(0x07131c17) /* 0.442165460 */, 16 }, /* 2222 */ { MAD_F(0x07143273) /* 0.442430925 */, 16 }, /* 2223 */ { MAD_F(0x071548da) /* 0.442696430 */, 16 }, /* 2224 */ { MAD_F(0x07165f4b) /* 0.442961975 */, 16 }, /* 2225 */ { MAD_F(0x071775c8) /* 0.443227559 */, 16 }, /* 2226 */ { MAD_F(0x07188c4f) /* 0.443493184 */, 16 }, /* 2227 */ { MAD_F(0x0719a2e0) /* 0.443758848 */, 16 }, /* 2228 */ { MAD_F(0x071ab97d) /* 0.444024552 */, 16 }, /* 2229 */ { MAD_F(0x071bd024) /* 0.444290296 */, 16 }, /* 2230 */ { MAD_F(0x071ce6d6) /* 0.444556079 */, 16 }, /* 2231 */ { MAD_F(0x071dfd92) /* 0.444821902 */, 16 }, /* 2232 */ { MAD_F(0x071f1459) /* 0.445087765 */, 16 }, /* 2233 */ { MAD_F(0x07202b2b) /* 0.445353668 */, 16 }, /* 2234 */ { MAD_F(0x07214207) /* 0.445619610 */, 16 }, /* 2235 */ { MAD_F(0x072258ee) /* 0.445885592 */, 16 }, /* 2236 */ { MAD_F(0x07236fe0) /* 0.446151614 */, 16 }, /* 2237 */ { MAD_F(0x072486dc) /* 0.446417675 */, 16 }, /* 2238 */ { MAD_F(0x07259de3) /* 0.446683776 */, 16 }, /* 2239 */ { MAD_F(0x0726b4f4) /* 0.446949917 */, 16 }, /* 2240 */ { MAD_F(0x0727cc11) /* 0.447216097 */, 16 }, /* 2241 */ { MAD_F(0x0728e338) /* 0.447482317 */, 16 }, /* 2242 */ { MAD_F(0x0729fa69) /* 0.447748576 */, 16 }, /* 2243 */ { MAD_F(0x072b11a5) /* 0.448014875 */, 16 }, /* 2244 */ { MAD_F(0x072c28ec) /* 0.448281214 */, 16 }, /* 2245 */ { MAD_F(0x072d403d) /* 0.448547592 */, 16 }, /* 2246 */ { MAD_F(0x072e5799) /* 0.448814010 */, 16 }, /* 2247 */ { MAD_F(0x072f6f00) /* 0.449080467 */, 16 }, /* 2248 */ { MAD_F(0x07308671) /* 0.449346964 */, 16 }, /* 2249 */ { MAD_F(0x07319ded) /* 0.449613501 */, 16 }, /* 2250 */ { MAD_F(0x0732b573) /* 0.449880076 */, 16 }, /* 2251 */ { MAD_F(0x0733cd04) /* 0.450146692 */, 16 }, /* 2252 */ { MAD_F(0x0734e4a0) /* 0.450413347 */, 16 }, /* 2253 */ { MAD_F(0x0735fc46) /* 0.450680041 */, 16 }, /* 2254 */ { MAD_F(0x073713f7) /* 0.450946775 */, 16 }, /* 2255 */ { MAD_F(0x07382bb2) /* 0.451213548 */, 16 }, /* 2256 */ { MAD_F(0x07394378) /* 0.451480360 */, 16 }, /* 2257 */ { MAD_F(0x073a5b49) /* 0.451747213 */, 16 }, /* 2258 */ { MAD_F(0x073b7324) /* 0.452014104 */, 16 }, /* 2259 */ { MAD_F(0x073c8b0a) /* 0.452281035 */, 16 }, /* 2260 */ { MAD_F(0x073da2fa) /* 0.452548005 */, 16 }, /* 2261 */ { MAD_F(0x073ebaf5) /* 0.452815015 */, 16 }, /* 2262 */ { MAD_F(0x073fd2fa) /* 0.453082064 */, 16 }, /* 2263 */ { MAD_F(0x0740eb0a) /* 0.453349152 */, 16 }, /* 2264 */ { MAD_F(0x07420325) /* 0.453616280 */, 16 }, /* 2265 */ { MAD_F(0x07431b4a) /* 0.453883447 */, 16 }, /* 2266 */ { MAD_F(0x0744337a) /* 0.454150653 */, 16 }, /* 2267 */ { MAD_F(0x07454bb4) /* 0.454417899 */, 16 }, /* 2268 */ { MAD_F(0x074663f8) /* 0.454685184 */, 16 }, /* 2269 */ { MAD_F(0x07477c48) /* 0.454952508 */, 16 }, /* 2270 */ { MAD_F(0x074894a2) /* 0.455219872 */, 16 }, /* 2271 */ { MAD_F(0x0749ad06) /* 0.455487275 */, 16 }, /* 2272 */ { MAD_F(0x074ac575) /* 0.455754717 */, 16 }, /* 2273 */ { MAD_F(0x074bddee) /* 0.456022198 */, 16 }, /* 2274 */ { MAD_F(0x074cf672) /* 0.456289719 */, 16 }, /* 2275 */ { MAD_F(0x074e0f01) /* 0.456557278 */, 16 }, /* 2276 */ { MAD_F(0x074f279a) /* 0.456824877 */, 16 }, /* 2277 */ { MAD_F(0x0750403e) /* 0.457092516 */, 16 }, /* 2278 */ { MAD_F(0x075158ec) /* 0.457360193 */, 16 }, /* 2279 */ { MAD_F(0x075271a4) /* 0.457627909 */, 16 }, /* 2280 */ { MAD_F(0x07538a67) /* 0.457895665 */, 16 }, /* 2281 */ { MAD_F(0x0754a335) /* 0.458163460 */, 16 }, /* 2282 */ { MAD_F(0x0755bc0d) /* 0.458431294 */, 16 }, /* 2283 */ { MAD_F(0x0756d4f0) /* 0.458699167 */, 16 }, /* 2284 */ { MAD_F(0x0757eddd) /* 0.458967079 */, 16 }, /* 2285 */ { MAD_F(0x075906d5) /* 0.459235030 */, 16 }, /* 2286 */ { MAD_F(0x075a1fd7) /* 0.459503021 */, 16 }, /* 2287 */ { MAD_F(0x075b38e3) /* 0.459771050 */, 16 }, /* 2288 */ { MAD_F(0x075c51fa) /* 0.460039119 */, 16 }, /* 2289 */ { MAD_F(0x075d6b1c) /* 0.460307226 */, 16 }, /* 2290 */ { MAD_F(0x075e8448) /* 0.460575373 */, 16 }, /* 2291 */ { MAD_F(0x075f9d7f) /* 0.460843559 */, 16 }, /* 2292 */ { MAD_F(0x0760b6c0) /* 0.461111783 */, 16 }, /* 2293 */ { MAD_F(0x0761d00b) /* 0.461380047 */, 16 }, /* 2294 */ { MAD_F(0x0762e961) /* 0.461648350 */, 16 }, /* 2295 */ { MAD_F(0x076402c1) /* 0.461916691 */, 16 }, /* 2296 */ { MAD_F(0x07651c2c) /* 0.462185072 */, 16 }, /* 2297 */ { MAD_F(0x076635a2) /* 0.462453492 */, 16 }, /* 2298 */ { MAD_F(0x07674f22) /* 0.462721950 */, 16 }, /* 2299 */ { MAD_F(0x076868ac) /* 0.462990448 */, 16 }, /* 2300 */ { MAD_F(0x07698240) /* 0.463258984 */, 16 }, /* 2301 */ { MAD_F(0x076a9be0) /* 0.463527560 */, 16 }, /* 2302 */ { MAD_F(0x076bb589) /* 0.463796174 */, 16 }, /* 2303 */ { MAD_F(0x076ccf3d) /* 0.464064827 */, 16 }, /* 2304 */ { MAD_F(0x076de8fc) /* 0.464333519 */, 16 }, /* 2305 */ { MAD_F(0x076f02c5) /* 0.464602250 */, 16 }, /* 2306 */ { MAD_F(0x07701c98) /* 0.464871020 */, 16 }, /* 2307 */ { MAD_F(0x07713676) /* 0.465139829 */, 16 }, /* 2308 */ { MAD_F(0x0772505e) /* 0.465408676 */, 16 }, /* 2309 */ { MAD_F(0x07736a51) /* 0.465677563 */, 16 }, /* 2310 */ { MAD_F(0x0774844e) /* 0.465946488 */, 16 }, /* 2311 */ { MAD_F(0x07759e55) /* 0.466215452 */, 16 }, /* 2312 */ { MAD_F(0x0776b867) /* 0.466484455 */, 16 }, /* 2313 */ { MAD_F(0x0777d283) /* 0.466753496 */, 16 }, /* 2314 */ { MAD_F(0x0778ecaa) /* 0.467022577 */, 16 }, /* 2315 */ { MAD_F(0x077a06db) /* 0.467291696 */, 16 }, /* 2316 */ { MAD_F(0x077b2117) /* 0.467560854 */, 16 }, /* 2317 */ { MAD_F(0x077c3b5d) /* 0.467830050 */, 16 }, /* 2318 */ { MAD_F(0x077d55ad) /* 0.468099285 */, 16 }, /* 2319 */ { MAD_F(0x077e7008) /* 0.468368560 */, 16 }, /* 2320 */ { MAD_F(0x077f8a6d) /* 0.468637872 */, 16 }, /* 2321 */ { MAD_F(0x0780a4dc) /* 0.468907224 */, 16 }, /* 2322 */ { MAD_F(0x0781bf56) /* 0.469176614 */, 16 }, /* 2323 */ { MAD_F(0x0782d9da) /* 0.469446043 */, 16 }, /* 2324 */ { MAD_F(0x0783f469) /* 0.469715510 */, 16 }, /* 2325 */ { MAD_F(0x07850f02) /* 0.469985016 */, 16 }, /* 2326 */ { MAD_F(0x078629a5) /* 0.470254561 */, 16 }, /* 2327 */ { MAD_F(0x07874453) /* 0.470524145 */, 16 }, /* 2328 */ { MAD_F(0x07885f0b) /* 0.470793767 */, 16 }, /* 2329 */ { MAD_F(0x078979ce) /* 0.471063427 */, 16 }, /* 2330 */ { MAD_F(0x078a949a) /* 0.471333126 */, 16 }, /* 2331 */ { MAD_F(0x078baf72) /* 0.471602864 */, 16 }, /* 2332 */ { MAD_F(0x078cca53) /* 0.471872641 */, 16 }, /* 2333 */ { MAD_F(0x078de53f) /* 0.472142456 */, 16 }, /* 2334 */ { MAD_F(0x078f0035) /* 0.472412309 */, 16 }, /* 2335 */ { MAD_F(0x07901b36) /* 0.472682201 */, 16 }, /* 2336 */ { MAD_F(0x07913641) /* 0.472952132 */, 16 }, /* 2337 */ { MAD_F(0x07925156) /* 0.473222101 */, 16 }, /* 2338 */ { MAD_F(0x07936c76) /* 0.473492108 */, 16 }, /* 2339 */ { MAD_F(0x079487a0) /* 0.473762155 */, 16 }, /* 2340 */ { MAD_F(0x0795a2d4) /* 0.474032239 */, 16 }, /* 2341 */ { MAD_F(0x0796be13) /* 0.474302362 */, 16 }, /* 2342 */ { MAD_F(0x0797d95c) /* 0.474572524 */, 16 }, /* 2343 */ { MAD_F(0x0798f4af) /* 0.474842724 */, 16 }, /* 2344 */ { MAD_F(0x079a100c) /* 0.475112962 */, 16 }, /* 2345 */ { MAD_F(0x079b2b74) /* 0.475383239 */, 16 }, /* 2346 */ { MAD_F(0x079c46e7) /* 0.475653554 */, 16 }, /* 2347 */ { MAD_F(0x079d6263) /* 0.475923908 */, 16 }, /* 2348 */ { MAD_F(0x079e7dea) /* 0.476194300 */, 16 }, /* 2349 */ { MAD_F(0x079f997b) /* 0.476464731 */, 16 }, /* 2350 */ { MAD_F(0x07a0b516) /* 0.476735200 */, 16 }, /* 2351 */ { MAD_F(0x07a1d0bc) /* 0.477005707 */, 16 }, /* 2352 */ { MAD_F(0x07a2ec6c) /* 0.477276252 */, 16 }, /* 2353 */ { MAD_F(0x07a40827) /* 0.477546836 */, 16 }, /* 2354 */ { MAD_F(0x07a523eb) /* 0.477817459 */, 16 }, /* 2355 */ { MAD_F(0x07a63fba) /* 0.478088119 */, 16 }, /* 2356 */ { MAD_F(0x07a75b93) /* 0.478358818 */, 16 }, /* 2357 */ { MAD_F(0x07a87777) /* 0.478629555 */, 16 }, /* 2358 */ { MAD_F(0x07a99364) /* 0.478900331 */, 16 }, /* 2359 */ { MAD_F(0x07aaaf5c) /* 0.479171145 */, 16 }, /* 2360 */ { MAD_F(0x07abcb5f) /* 0.479441997 */, 16 }, /* 2361 */ { MAD_F(0x07ace76b) /* 0.479712887 */, 16 }, /* 2362 */ { MAD_F(0x07ae0382) /* 0.479983816 */, 16 }, /* 2363 */ { MAD_F(0x07af1fa3) /* 0.480254782 */, 16 }, /* 2364 */ { MAD_F(0x07b03bcf) /* 0.480525787 */, 16 }, /* 2365 */ { MAD_F(0x07b15804) /* 0.480796831 */, 16 }, /* 2366 */ { MAD_F(0x07b27444) /* 0.481067912 */, 16 }, /* 2367 */ { MAD_F(0x07b3908e) /* 0.481339032 */, 16 }, /* 2368 */ { MAD_F(0x07b4ace3) /* 0.481610189 */, 16 }, /* 2369 */ { MAD_F(0x07b5c941) /* 0.481881385 */, 16 }, /* 2370 */ { MAD_F(0x07b6e5aa) /* 0.482152620 */, 16 }, /* 2371 */ { MAD_F(0x07b8021d) /* 0.482423892 */, 16 }, /* 2372 */ { MAD_F(0x07b91e9b) /* 0.482695202 */, 16 }, /* 2373 */ { MAD_F(0x07ba3b22) /* 0.482966551 */, 16 }, /* 2374 */ { MAD_F(0x07bb57b4) /* 0.483237938 */, 16 }, /* 2375 */ { MAD_F(0x07bc7450) /* 0.483509362 */, 16 }, /* 2376 */ { MAD_F(0x07bd90f6) /* 0.483780825 */, 16 }, /* 2377 */ { MAD_F(0x07beada7) /* 0.484052326 */, 16 }, /* 2378 */ { MAD_F(0x07bfca61) /* 0.484323865 */, 16 }, /* 2379 */ { MAD_F(0x07c0e726) /* 0.484595443 */, 16 }, /* 2380 */ { MAD_F(0x07c203f5) /* 0.484867058 */, 16 }, /* 2381 */ { MAD_F(0x07c320cf) /* 0.485138711 */, 16 }, /* 2382 */ { MAD_F(0x07c43db2) /* 0.485410402 */, 16 }, /* 2383 */ { MAD_F(0x07c55aa0) /* 0.485682131 */, 16 }, /* 2384 */ { MAD_F(0x07c67798) /* 0.485953899 */, 16 }, /* 2385 */ { MAD_F(0x07c7949a) /* 0.486225704 */, 16 }, /* 2386 */ { MAD_F(0x07c8b1a7) /* 0.486497547 */, 16 }, /* 2387 */ { MAD_F(0x07c9cebd) /* 0.486769429 */, 16 }, /* 2388 */ { MAD_F(0x07caebde) /* 0.487041348 */, 16 }, /* 2389 */ { MAD_F(0x07cc0909) /* 0.487313305 */, 16 }, /* 2390 */ { MAD_F(0x07cd263e) /* 0.487585300 */, 16 }, /* 2391 */ { MAD_F(0x07ce437d) /* 0.487857333 */, 16 }, /* 2392 */ { MAD_F(0x07cf60c7) /* 0.488129404 */, 16 }, /* 2393 */ { MAD_F(0x07d07e1b) /* 0.488401513 */, 16 }, /* 2394 */ { MAD_F(0x07d19b79) /* 0.488673660 */, 16 }, /* 2395 */ { MAD_F(0x07d2b8e1) /* 0.488945845 */, 16 }, /* 2396 */ { MAD_F(0x07d3d653) /* 0.489218067 */, 16 }, /* 2397 */ { MAD_F(0x07d4f3cf) /* 0.489490328 */, 16 }, /* 2398 */ { MAD_F(0x07d61156) /* 0.489762626 */, 16 }, /* 2399 */ { MAD_F(0x07d72ee6) /* 0.490034962 */, 16 }, /* 2400 */ { MAD_F(0x07d84c81) /* 0.490307336 */, 16 }, /* 2401 */ { MAD_F(0x07d96a26) /* 0.490579748 */, 16 }, /* 2402 */ { MAD_F(0x07da87d5) /* 0.490852198 */, 16 }, /* 2403 */ { MAD_F(0x07dba58f) /* 0.491124686 */, 16 }, /* 2404 */ { MAD_F(0x07dcc352) /* 0.491397211 */, 16 }, /* 2405 */ { MAD_F(0x07dde120) /* 0.491669774 */, 16 }, /* 2406 */ { MAD_F(0x07defef7) /* 0.491942375 */, 16 }, /* 2407 */ { MAD_F(0x07e01cd9) /* 0.492215014 */, 16 }, /* 2408 */ { MAD_F(0x07e13ac5) /* 0.492487690 */, 16 }, /* 2409 */ { MAD_F(0x07e258bc) /* 0.492760404 */, 16 }, /* 2410 */ { MAD_F(0x07e376bc) /* 0.493033156 */, 16 }, /* 2411 */ { MAD_F(0x07e494c6) /* 0.493305946 */, 16 }, /* 2412 */ { MAD_F(0x07e5b2db) /* 0.493578773 */, 16 }, /* 2413 */ { MAD_F(0x07e6d0f9) /* 0.493851638 */, 16 }, /* 2414 */ { MAD_F(0x07e7ef22) /* 0.494124541 */, 16 }, /* 2415 */ { MAD_F(0x07e90d55) /* 0.494397481 */, 16 }, /* 2416 */ { MAD_F(0x07ea2b92) /* 0.494670459 */, 16 }, /* 2417 */ { MAD_F(0x07eb49d9) /* 0.494943475 */, 16 }, /* 2418 */ { MAD_F(0x07ec682a) /* 0.495216529 */, 16 }, /* 2419 */ { MAD_F(0x07ed8686) /* 0.495489620 */, 16 }, /* 2420 */ { MAD_F(0x07eea4eb) /* 0.495762748 */, 16 }, /* 2421 */ { MAD_F(0x07efc35b) /* 0.496035915 */, 16 }, /* 2422 */ { MAD_F(0x07f0e1d4) /* 0.496309119 */, 16 }, /* 2423 */ { MAD_F(0x07f20058) /* 0.496582360 */, 16 }, /* 2424 */ { MAD_F(0x07f31ee6) /* 0.496855639 */, 16 }, /* 2425 */ { MAD_F(0x07f43d7e) /* 0.497128956 */, 16 }, /* 2426 */ { MAD_F(0x07f55c20) /* 0.497402310 */, 16 }, /* 2427 */ { MAD_F(0x07f67acc) /* 0.497675702 */, 16 }, /* 2428 */ { MAD_F(0x07f79982) /* 0.497949132 */, 16 }, /* 2429 */ { MAD_F(0x07f8b842) /* 0.498222598 */, 16 }, /* 2430 */ { MAD_F(0x07f9d70c) /* 0.498496103 */, 16 }, /* 2431 */ { MAD_F(0x07faf5e1) /* 0.498769645 */, 16 }, /* 2432 */ { MAD_F(0x07fc14bf) /* 0.499043224 */, 16 }, /* 2433 */ { MAD_F(0x07fd33a8) /* 0.499316841 */, 16 }, /* 2434 */ { MAD_F(0x07fe529a) /* 0.499590496 */, 16 }, /* 2435 */ { MAD_F(0x07ff7197) /* 0.499864188 */, 16 }, /* 2436 */ { MAD_F(0x0400484f) /* 0.250068959 */, 17 }, /* 2437 */ { MAD_F(0x0400d7d7) /* 0.250205842 */, 17 }, /* 2438 */ { MAD_F(0x04016764) /* 0.250342744 */, 17 }, /* 2439 */ { MAD_F(0x0401f6f7) /* 0.250479665 */, 17 }, /* 2440 */ { MAD_F(0x0402868e) /* 0.250616605 */, 17 }, /* 2441 */ { MAD_F(0x0403162b) /* 0.250753563 */, 17 }, /* 2442 */ { MAD_F(0x0403a5cc) /* 0.250890540 */, 17 }, /* 2443 */ { MAD_F(0x04043573) /* 0.251027536 */, 17 }, /* 2444 */ { MAD_F(0x0404c51e) /* 0.251164550 */, 17 }, /* 2445 */ { MAD_F(0x040554cf) /* 0.251301583 */, 17 }, /* 2446 */ { MAD_F(0x0405e484) /* 0.251438635 */, 17 }, /* 2447 */ { MAD_F(0x0406743f) /* 0.251575706 */, 17 }, /* 2448 */ { MAD_F(0x040703ff) /* 0.251712795 */, 17 }, /* 2449 */ { MAD_F(0x040793c3) /* 0.251849903 */, 17 }, /* 2450 */ { MAD_F(0x0408238d) /* 0.251987029 */, 17 }, /* 2451 */ { MAD_F(0x0408b35b) /* 0.252124174 */, 17 }, /* 2452 */ { MAD_F(0x0409432f) /* 0.252261338 */, 17 }, /* 2453 */ { MAD_F(0x0409d308) /* 0.252398520 */, 17 }, /* 2454 */ { MAD_F(0x040a62e5) /* 0.252535721 */, 17 }, /* 2455 */ { MAD_F(0x040af2c8) /* 0.252672941 */, 17 }, /* 2456 */ { MAD_F(0x040b82b0) /* 0.252810180 */, 17 }, /* 2457 */ { MAD_F(0x040c129c) /* 0.252947436 */, 17 }, /* 2458 */ { MAD_F(0x040ca28e) /* 0.253084712 */, 17 }, /* 2459 */ { MAD_F(0x040d3284) /* 0.253222006 */, 17 }, /* 2460 */ { MAD_F(0x040dc280) /* 0.253359319 */, 17 }, /* 2461 */ { MAD_F(0x040e5281) /* 0.253496651 */, 17 }, /* 2462 */ { MAD_F(0x040ee286) /* 0.253634001 */, 17 }, /* 2463 */ { MAD_F(0x040f7291) /* 0.253771369 */, 17 }, /* 2464 */ { MAD_F(0x041002a1) /* 0.253908756 */, 17 }, /* 2465 */ { MAD_F(0x041092b5) /* 0.254046162 */, 17 }, /* 2466 */ { MAD_F(0x041122cf) /* 0.254183587 */, 17 }, /* 2467 */ { MAD_F(0x0411b2ed) /* 0.254321030 */, 17 }, /* 2468 */ { MAD_F(0x04124311) /* 0.254458491 */, 17 }, /* 2469 */ { MAD_F(0x0412d339) /* 0.254595971 */, 17 }, /* 2470 */ { MAD_F(0x04136367) /* 0.254733470 */, 17 }, /* 2471 */ { MAD_F(0x0413f399) /* 0.254870987 */, 17 }, /* 2472 */ { MAD_F(0x041483d1) /* 0.255008523 */, 17 }, /* 2473 */ { MAD_F(0x0415140d) /* 0.255146077 */, 17 }, /* 2474 */ { MAD_F(0x0415a44f) /* 0.255283650 */, 17 }, /* 2475 */ { MAD_F(0x04163495) /* 0.255421241 */, 17 }, /* 2476 */ { MAD_F(0x0416c4e1) /* 0.255558851 */, 17 }, /* 2477 */ { MAD_F(0x04175531) /* 0.255696480 */, 17 }, /* 2478 */ { MAD_F(0x0417e586) /* 0.255834127 */, 17 }, /* 2479 */ { MAD_F(0x041875e1) /* 0.255971792 */, 17 }, /* 2480 */ { MAD_F(0x04190640) /* 0.256109476 */, 17 }, /* 2481 */ { MAD_F(0x041996a4) /* 0.256247179 */, 17 }, /* 2482 */ { MAD_F(0x041a270d) /* 0.256384900 */, 17 }, /* 2483 */ { MAD_F(0x041ab77b) /* 0.256522639 */, 17 }, /* 2484 */ { MAD_F(0x041b47ef) /* 0.256660397 */, 17 }, /* 2485 */ { MAD_F(0x041bd867) /* 0.256798174 */, 17 }, /* 2486 */ { MAD_F(0x041c68e4) /* 0.256935969 */, 17 }, /* 2487 */ { MAD_F(0x041cf966) /* 0.257073782 */, 17 }, /* 2488 */ { MAD_F(0x041d89ed) /* 0.257211614 */, 17 }, /* 2489 */ { MAD_F(0x041e1a79) /* 0.257349465 */, 17 }, /* 2490 */ { MAD_F(0x041eab0a) /* 0.257487334 */, 17 }, /* 2491 */ { MAD_F(0x041f3b9f) /* 0.257625221 */, 17 }, /* 2492 */ { MAD_F(0x041fcc3a) /* 0.257763127 */, 17 }, /* 2493 */ { MAD_F(0x04205cda) /* 0.257901051 */, 17 }, /* 2494 */ { MAD_F(0x0420ed7f) /* 0.258038994 */, 17 }, /* 2495 */ { MAD_F(0x04217e28) /* 0.258176955 */, 17 }, /* 2496 */ { MAD_F(0x04220ed7) /* 0.258314934 */, 17 }, /* 2497 */ { MAD_F(0x04229f8a) /* 0.258452932 */, 17 }, /* 2498 */ { MAD_F(0x04233043) /* 0.258590948 */, 17 }, /* 2499 */ { MAD_F(0x0423c100) /* 0.258728983 */, 17 }, /* 2500 */ { MAD_F(0x042451c3) /* 0.258867036 */, 17 }, /* 2501 */ { MAD_F(0x0424e28a) /* 0.259005108 */, 17 }, /* 2502 */ { MAD_F(0x04257356) /* 0.259143198 */, 17 }, /* 2503 */ { MAD_F(0x04260428) /* 0.259281307 */, 17 }, /* 2504 */ { MAD_F(0x042694fe) /* 0.259419433 */, 17 }, /* 2505 */ { MAD_F(0x042725d9) /* 0.259557579 */, 17 }, /* 2506 */ { MAD_F(0x0427b6b9) /* 0.259695742 */, 17 }, /* 2507 */ { MAD_F(0x0428479e) /* 0.259833924 */, 17 }, /* 2508 */ { MAD_F(0x0428d888) /* 0.259972124 */, 17 }, /* 2509 */ { MAD_F(0x04296976) /* 0.260110343 */, 17 }, /* 2510 */ { MAD_F(0x0429fa6a) /* 0.260248580 */, 17 }, /* 2511 */ { MAD_F(0x042a8b63) /* 0.260386836 */, 17 }, /* 2512 */ { MAD_F(0x042b1c60) /* 0.260525110 */, 17 }, /* 2513 */ { MAD_F(0x042bad63) /* 0.260663402 */, 17 }, /* 2514 */ { MAD_F(0x042c3e6a) /* 0.260801712 */, 17 }, /* 2515 */ { MAD_F(0x042ccf77) /* 0.260940041 */, 17 }, /* 2516 */ { MAD_F(0x042d6088) /* 0.261078388 */, 17 }, /* 2517 */ { MAD_F(0x042df19e) /* 0.261216754 */, 17 }, /* 2518 */ { MAD_F(0x042e82b9) /* 0.261355137 */, 17 }, /* 2519 */ { MAD_F(0x042f13d9) /* 0.261493540 */, 17 }, /* 2520 */ { MAD_F(0x042fa4fe) /* 0.261631960 */, 17 }, /* 2521 */ { MAD_F(0x04303628) /* 0.261770399 */, 17 }, /* 2522 */ { MAD_F(0x0430c757) /* 0.261908856 */, 17 }, /* 2523 */ { MAD_F(0x0431588b) /* 0.262047331 */, 17 }, /* 2524 */ { MAD_F(0x0431e9c3) /* 0.262185825 */, 17 }, /* 2525 */ { MAD_F(0x04327b01) /* 0.262324337 */, 17 }, /* 2526 */ { MAD_F(0x04330c43) /* 0.262462867 */, 17 }, /* 2527 */ { MAD_F(0x04339d8a) /* 0.262601416 */, 17 }, /* 2528 */ { MAD_F(0x04342ed7) /* 0.262739982 */, 17 }, /* 2529 */ { MAD_F(0x0434c028) /* 0.262878568 */, 17 }, /* 2530 */ { MAD_F(0x0435517e) /* 0.263017171 */, 17 }, /* 2531 */ { MAD_F(0x0435e2d9) /* 0.263155792 */, 17 }, /* 2532 */ { MAD_F(0x04367439) /* 0.263294432 */, 17 }, /* 2533 */ { MAD_F(0x0437059e) /* 0.263433090 */, 17 }, /* 2534 */ { MAD_F(0x04379707) /* 0.263571767 */, 17 }, /* 2535 */ { MAD_F(0x04382876) /* 0.263710461 */, 17 }, /* 2536 */ { MAD_F(0x0438b9e9) /* 0.263849174 */, 17 }, /* 2537 */ { MAD_F(0x04394b61) /* 0.263987905 */, 17 }, /* 2538 */ { MAD_F(0x0439dcdf) /* 0.264126655 */, 17 }, /* 2539 */ { MAD_F(0x043a6e61) /* 0.264265422 */, 17 }, /* 2540 */ { MAD_F(0x043affe8) /* 0.264404208 */, 17 }, /* 2541 */ { MAD_F(0x043b9174) /* 0.264543012 */, 17 }, /* 2542 */ { MAD_F(0x043c2305) /* 0.264681834 */, 17 }, /* 2543 */ { MAD_F(0x043cb49a) /* 0.264820674 */, 17 }, /* 2544 */ { MAD_F(0x043d4635) /* 0.264959533 */, 17 }, /* 2545 */ { MAD_F(0x043dd7d4) /* 0.265098410 */, 17 }, /* 2546 */ { MAD_F(0x043e6979) /* 0.265237305 */, 17 }, /* 2547 */ { MAD_F(0x043efb22) /* 0.265376218 */, 17 }, /* 2548 */ { MAD_F(0x043f8cd0) /* 0.265515149 */, 17 }, /* 2549 */ { MAD_F(0x04401e83) /* 0.265654099 */, 17 }, /* 2550 */ { MAD_F(0x0440b03b) /* 0.265793066 */, 17 }, /* 2551 */ { MAD_F(0x044141f7) /* 0.265932052 */, 17 }, /* 2552 */ { MAD_F(0x0441d3b9) /* 0.266071056 */, 17 }, /* 2553 */ { MAD_F(0x04426580) /* 0.266210078 */, 17 }, /* 2554 */ { MAD_F(0x0442f74b) /* 0.266349119 */, 17 }, /* 2555 */ { MAD_F(0x0443891b) /* 0.266488177 */, 17 }, /* 2556 */ { MAD_F(0x04441af0) /* 0.266627254 */, 17 }, /* 2557 */ { MAD_F(0x0444acca) /* 0.266766349 */, 17 }, /* 2558 */ { MAD_F(0x04453ea9) /* 0.266905462 */, 17 }, /* 2559 */ { MAD_F(0x0445d08d) /* 0.267044593 */, 17 }, /* 2560 */ { MAD_F(0x04466275) /* 0.267183742 */, 17 }, /* 2561 */ { MAD_F(0x0446f463) /* 0.267322909 */, 17 }, /* 2562 */ { MAD_F(0x04478655) /* 0.267462094 */, 17 }, /* 2563 */ { MAD_F(0x0448184c) /* 0.267601298 */, 17 }, /* 2564 */ { MAD_F(0x0448aa48) /* 0.267740519 */, 17 }, /* 2565 */ { MAD_F(0x04493c49) /* 0.267879759 */, 17 }, /* 2566 */ { MAD_F(0x0449ce4f) /* 0.268019017 */, 17 }, /* 2567 */ { MAD_F(0x044a6059) /* 0.268158293 */, 17 }, /* 2568 */ { MAD_F(0x044af269) /* 0.268297587 */, 17 }, /* 2569 */ { MAD_F(0x044b847d) /* 0.268436899 */, 17 }, /* 2570 */ { MAD_F(0x044c1696) /* 0.268576229 */, 17 }, /* 2571 */ { MAD_F(0x044ca8b4) /* 0.268715577 */, 17 }, /* 2572 */ { MAD_F(0x044d3ad7) /* 0.268854943 */, 17 }, /* 2573 */ { MAD_F(0x044dccff) /* 0.268994328 */, 17 }, /* 2574 */ { MAD_F(0x044e5f2b) /* 0.269133730 */, 17 }, /* 2575 */ { MAD_F(0x044ef15d) /* 0.269273150 */, 17 }, /* 2576 */ { MAD_F(0x044f8393) /* 0.269412589 */, 17 }, /* 2577 */ { MAD_F(0x045015ce) /* 0.269552045 */, 17 }, /* 2578 */ { MAD_F(0x0450a80e) /* 0.269691520 */, 17 }, /* 2579 */ { MAD_F(0x04513a53) /* 0.269831013 */, 17 }, /* 2580 */ { MAD_F(0x0451cc9c) /* 0.269970523 */, 17 }, /* 2581 */ { MAD_F(0x04525eeb) /* 0.270110052 */, 17 }, /* 2582 */ { MAD_F(0x0452f13e) /* 0.270249599 */, 17 }, /* 2583 */ { MAD_F(0x04538396) /* 0.270389163 */, 17 }, /* 2584 */ { MAD_F(0x045415f3) /* 0.270528746 */, 17 }, /* 2585 */ { MAD_F(0x0454a855) /* 0.270668347 */, 17 }, /* 2586 */ { MAD_F(0x04553abb) /* 0.270807965 */, 17 }, /* 2587 */ { MAD_F(0x0455cd27) /* 0.270947602 */, 17 }, /* 2588 */ { MAD_F(0x04565f97) /* 0.271087257 */, 17 }, /* 2589 */ { MAD_F(0x0456f20c) /* 0.271226930 */, 17 }, /* 2590 */ { MAD_F(0x04578486) /* 0.271366620 */, 17 }, /* 2591 */ { MAD_F(0x04581705) /* 0.271506329 */, 17 }, /* 2592 */ { MAD_F(0x0458a989) /* 0.271646056 */, 17 }, /* 2593 */ { MAD_F(0x04593c11) /* 0.271785800 */, 17 }, /* 2594 */ { MAD_F(0x0459ce9e) /* 0.271925563 */, 17 }, /* 2595 */ { MAD_F(0x045a6130) /* 0.272065343 */, 17 }, /* 2596 */ { MAD_F(0x045af3c7) /* 0.272205142 */, 17 }, /* 2597 */ { MAD_F(0x045b8663) /* 0.272344958 */, 17 }, /* 2598 */ { MAD_F(0x045c1903) /* 0.272484793 */, 17 }, /* 2599 */ { MAD_F(0x045caba9) /* 0.272624645 */, 17 }, /* 2600 */ { MAD_F(0x045d3e53) /* 0.272764515 */, 17 }, /* 2601 */ { MAD_F(0x045dd102) /* 0.272904403 */, 17 }, /* 2602 */ { MAD_F(0x045e63b6) /* 0.273044310 */, 17 }, /* 2603 */ { MAD_F(0x045ef66e) /* 0.273184234 */, 17 }, /* 2604 */ { MAD_F(0x045f892b) /* 0.273324176 */, 17 }, /* 2605 */ { MAD_F(0x04601bee) /* 0.273464136 */, 17 }, /* 2606 */ { MAD_F(0x0460aeb5) /* 0.273604113 */, 17 }, /* 2607 */ { MAD_F(0x04614180) /* 0.273744109 */, 17 }, /* 2608 */ { MAD_F(0x0461d451) /* 0.273884123 */, 17 }, /* 2609 */ { MAD_F(0x04626727) /* 0.274024154 */, 17 }, /* 2610 */ { MAD_F(0x0462fa01) /* 0.274164204 */, 17 }, /* 2611 */ { MAD_F(0x04638ce0) /* 0.274304271 */, 17 }, /* 2612 */ { MAD_F(0x04641fc4) /* 0.274444356 */, 17 }, /* 2613 */ { MAD_F(0x0464b2ac) /* 0.274584459 */, 17 }, /* 2614 */ { MAD_F(0x0465459a) /* 0.274724580 */, 17 }, /* 2615 */ { MAD_F(0x0465d88c) /* 0.274864719 */, 17 }, /* 2616 */ { MAD_F(0x04666b83) /* 0.275004875 */, 17 }, /* 2617 */ { MAD_F(0x0466fe7f) /* 0.275145050 */, 17 }, /* 2618 */ { MAD_F(0x0467917f) /* 0.275285242 */, 17 }, /* 2619 */ { MAD_F(0x04682485) /* 0.275425452 */, 17 }, /* 2620 */ { MAD_F(0x0468b78f) /* 0.275565681 */, 17 }, /* 2621 */ { MAD_F(0x04694a9e) /* 0.275705926 */, 17 }, /* 2622 */ { MAD_F(0x0469ddb2) /* 0.275846190 */, 17 }, /* 2623 */ { MAD_F(0x046a70ca) /* 0.275986472 */, 17 }, /* 2624 */ { MAD_F(0x046b03e7) /* 0.276126771 */, 17 }, /* 2625 */ { MAD_F(0x046b970a) /* 0.276267088 */, 17 }, /* 2626 */ { MAD_F(0x046c2a31) /* 0.276407423 */, 17 }, /* 2627 */ { MAD_F(0x046cbd5c) /* 0.276547776 */, 17 }, /* 2628 */ { MAD_F(0x046d508d) /* 0.276688147 */, 17 }, /* 2629 */ { MAD_F(0x046de3c2) /* 0.276828535 */, 17 }, /* 2630 */ { MAD_F(0x046e76fc) /* 0.276968942 */, 17 }, /* 2631 */ { MAD_F(0x046f0a3b) /* 0.277109366 */, 17 }, /* 2632 */ { MAD_F(0x046f9d7e) /* 0.277249808 */, 17 }, /* 2633 */ { MAD_F(0x047030c7) /* 0.277390267 */, 17 }, /* 2634 */ { MAD_F(0x0470c414) /* 0.277530745 */, 17 }, /* 2635 */ { MAD_F(0x04715766) /* 0.277671240 */, 17 }, /* 2636 */ { MAD_F(0x0471eabc) /* 0.277811753 */, 17 }, /* 2637 */ { MAD_F(0x04727e18) /* 0.277952284 */, 17 }, /* 2638 */ { MAD_F(0x04731178) /* 0.278092832 */, 17 }, /* 2639 */ { MAD_F(0x0473a4dd) /* 0.278233399 */, 17 }, /* 2640 */ { MAD_F(0x04743847) /* 0.278373983 */, 17 }, /* 2641 */ { MAD_F(0x0474cbb5) /* 0.278514584 */, 17 }, /* 2642 */ { MAD_F(0x04755f29) /* 0.278655204 */, 17 }, /* 2643 */ { MAD_F(0x0475f2a1) /* 0.278795841 */, 17 }, /* 2644 */ { MAD_F(0x0476861d) /* 0.278936496 */, 17 }, /* 2645 */ { MAD_F(0x0477199f) /* 0.279077169 */, 17 }, /* 2646 */ { MAD_F(0x0477ad25) /* 0.279217860 */, 17 }, /* 2647 */ { MAD_F(0x047840b0) /* 0.279358568 */, 17 }, /* 2648 */ { MAD_F(0x0478d440) /* 0.279499294 */, 17 }, /* 2649 */ { MAD_F(0x047967d5) /* 0.279640037 */, 17 }, /* 2650 */ { MAD_F(0x0479fb6e) /* 0.279780799 */, 17 }, /* 2651 */ { MAD_F(0x047a8f0c) /* 0.279921578 */, 17 }, /* 2652 */ { MAD_F(0x047b22af) /* 0.280062375 */, 17 }, /* 2653 */ { MAD_F(0x047bb657) /* 0.280203189 */, 17 }, /* 2654 */ { MAD_F(0x047c4a03) /* 0.280344021 */, 17 }, /* 2655 */ { MAD_F(0x047cddb4) /* 0.280484871 */, 17 }, /* 2656 */ { MAD_F(0x047d716a) /* 0.280625739 */, 17 }, /* 2657 */ { MAD_F(0x047e0524) /* 0.280766624 */, 17 }, /* 2658 */ { MAD_F(0x047e98e4) /* 0.280907527 */, 17 }, /* 2659 */ { MAD_F(0x047f2ca8) /* 0.281048447 */, 17 }, /* 2660 */ { MAD_F(0x047fc071) /* 0.281189385 */, 17 }, /* 2661 */ { MAD_F(0x0480543e) /* 0.281330341 */, 17 }, /* 2662 */ { MAD_F(0x0480e811) /* 0.281471315 */, 17 }, /* 2663 */ { MAD_F(0x04817be8) /* 0.281612306 */, 17 }, /* 2664 */ { MAD_F(0x04820fc3) /* 0.281753315 */, 17 }, /* 2665 */ { MAD_F(0x0482a3a4) /* 0.281894341 */, 17 }, /* 2666 */ { MAD_F(0x04833789) /* 0.282035386 */, 17 }, /* 2667 */ { MAD_F(0x0483cb73) /* 0.282176447 */, 17 }, /* 2668 */ { MAD_F(0x04845f62) /* 0.282317527 */, 17 }, /* 2669 */ { MAD_F(0x0484f355) /* 0.282458624 */, 17 }, /* 2670 */ { MAD_F(0x0485874d) /* 0.282599738 */, 17 }, /* 2671 */ { MAD_F(0x04861b4a) /* 0.282740871 */, 17 }, /* 2672 */ { MAD_F(0x0486af4c) /* 0.282882021 */, 17 }, /* 2673 */ { MAD_F(0x04874352) /* 0.283023188 */, 17 }, /* 2674 */ { MAD_F(0x0487d75d) /* 0.283164373 */, 17 }, /* 2675 */ { MAD_F(0x04886b6d) /* 0.283305576 */, 17 }, /* 2676 */ { MAD_F(0x0488ff82) /* 0.283446796 */, 17 }, /* 2677 */ { MAD_F(0x0489939b) /* 0.283588034 */, 17 }, /* 2678 */ { MAD_F(0x048a27b9) /* 0.283729290 */, 17 }, /* 2679 */ { MAD_F(0x048abbdc) /* 0.283870563 */, 17 }, /* 2680 */ { MAD_F(0x048b5003) /* 0.284011853 */, 17 }, /* 2681 */ { MAD_F(0x048be42f) /* 0.284153161 */, 17 }, /* 2682 */ { MAD_F(0x048c7860) /* 0.284294487 */, 17 }, /* 2683 */ { MAD_F(0x048d0c96) /* 0.284435831 */, 17 }, /* 2684 */ { MAD_F(0x048da0d0) /* 0.284577192 */, 17 }, /* 2685 */ { MAD_F(0x048e350f) /* 0.284718570 */, 17 }, /* 2686 */ { MAD_F(0x048ec953) /* 0.284859966 */, 17 }, /* 2687 */ { MAD_F(0x048f5d9b) /* 0.285001380 */, 17 }, /* 2688 */ { MAD_F(0x048ff1e8) /* 0.285142811 */, 17 }, /* 2689 */ { MAD_F(0x0490863a) /* 0.285284259 */, 17 }, /* 2690 */ { MAD_F(0x04911a91) /* 0.285425726 */, 17 }, /* 2691 */ { MAD_F(0x0491aeec) /* 0.285567209 */, 17 }, /* 2692 */ { MAD_F(0x0492434c) /* 0.285708711 */, 17 }, /* 2693 */ { MAD_F(0x0492d7b0) /* 0.285850229 */, 17 }, /* 2694 */ { MAD_F(0x04936c1a) /* 0.285991766 */, 17 }, /* 2695 */ { MAD_F(0x04940088) /* 0.286133319 */, 17 }, /* 2696 */ { MAD_F(0x049494fb) /* 0.286274891 */, 17 }, /* 2697 */ { MAD_F(0x04952972) /* 0.286416480 */, 17 }, /* 2698 */ { MAD_F(0x0495bdee) /* 0.286558086 */, 17 }, /* 2699 */ { MAD_F(0x0496526f) /* 0.286699710 */, 17 }, /* 2700 */ { MAD_F(0x0496e6f5) /* 0.286841351 */, 17 }, /* 2701 */ { MAD_F(0x04977b7f) /* 0.286983010 */, 17 }, /* 2702 */ { MAD_F(0x0498100e) /* 0.287124686 */, 17 }, /* 2703 */ { MAD_F(0x0498a4a1) /* 0.287266380 */, 17 }, /* 2704 */ { MAD_F(0x0499393a) /* 0.287408091 */, 17 }, /* 2705 */ { MAD_F(0x0499cdd7) /* 0.287549820 */, 17 }, /* 2706 */ { MAD_F(0x049a6278) /* 0.287691566 */, 17 }, /* 2707 */ { MAD_F(0x049af71f) /* 0.287833330 */, 17 }, /* 2708 */ { MAD_F(0x049b8bca) /* 0.287975111 */, 17 }, /* 2709 */ { MAD_F(0x049c207a) /* 0.288116909 */, 17 }, /* 2710 */ { MAD_F(0x049cb52e) /* 0.288258725 */, 17 }, /* 2711 */ { MAD_F(0x049d49e7) /* 0.288400559 */, 17 }, /* 2712 */ { MAD_F(0x049ddea5) /* 0.288542409 */, 17 }, /* 2713 */ { MAD_F(0x049e7367) /* 0.288684278 */, 17 }, /* 2714 */ { MAD_F(0x049f082f) /* 0.288826163 */, 17 }, /* 2715 */ { MAD_F(0x049f9cfa) /* 0.288968067 */, 17 }, /* 2716 */ { MAD_F(0x04a031cb) /* 0.289109987 */, 17 }, /* 2717 */ { MAD_F(0x04a0c6a0) /* 0.289251925 */, 17 }, /* 2718 */ { MAD_F(0x04a15b7a) /* 0.289393881 */, 17 }, /* 2719 */ { MAD_F(0x04a1f059) /* 0.289535854 */, 17 }, /* 2720 */ { MAD_F(0x04a2853c) /* 0.289677844 */, 17 }, /* 2721 */ { MAD_F(0x04a31a24) /* 0.289819851 */, 17 }, /* 2722 */ { MAD_F(0x04a3af10) /* 0.289961876 */, 17 }, /* 2723 */ { MAD_F(0x04a44401) /* 0.290103919 */, 17 }, /* 2724 */ { MAD_F(0x04a4d8f7) /* 0.290245979 */, 17 }, /* 2725 */ { MAD_F(0x04a56df2) /* 0.290388056 */, 17 }, /* 2726 */ { MAD_F(0x04a602f1) /* 0.290530150 */, 17 }, /* 2727 */ { MAD_F(0x04a697f5) /* 0.290672262 */, 17 }, /* 2728 */ { MAD_F(0x04a72cfe) /* 0.290814392 */, 17 }, /* 2729 */ { MAD_F(0x04a7c20b) /* 0.290956538 */, 17 }, /* 2730 */ { MAD_F(0x04a8571d) /* 0.291098703 */, 17 }, /* 2731 */ { MAD_F(0x04a8ec33) /* 0.291240884 */, 17 }, /* 2732 */ { MAD_F(0x04a9814e) /* 0.291383083 */, 17 }, /* 2733 */ { MAD_F(0x04aa166e) /* 0.291525299 */, 17 }, /* 2734 */ { MAD_F(0x04aaab93) /* 0.291667532 */, 17 }, /* 2735 */ { MAD_F(0x04ab40bc) /* 0.291809783 */, 17 }, /* 2736 */ { MAD_F(0x04abd5ea) /* 0.291952051 */, 17 }, /* 2737 */ { MAD_F(0x04ac6b1c) /* 0.292094337 */, 17 }, /* 2738 */ { MAD_F(0x04ad0053) /* 0.292236640 */, 17 }, /* 2739 */ { MAD_F(0x04ad958f) /* 0.292378960 */, 17 }, /* 2740 */ { MAD_F(0x04ae2ad0) /* 0.292521297 */, 17 }, /* 2741 */ { MAD_F(0x04aec015) /* 0.292663652 */, 17 }, /* 2742 */ { MAD_F(0x04af555e) /* 0.292806024 */, 17 }, /* 2743 */ { MAD_F(0x04afeaad) /* 0.292948414 */, 17 }, /* 2744 */ { MAD_F(0x04b08000) /* 0.293090820 */, 17 }, /* 2745 */ { MAD_F(0x04b11557) /* 0.293233244 */, 17 }, /* 2746 */ { MAD_F(0x04b1aab4) /* 0.293375686 */, 17 }, /* 2747 */ { MAD_F(0x04b24015) /* 0.293518144 */, 17 }, /* 2748 */ { MAD_F(0x04b2d57a) /* 0.293660620 */, 17 }, /* 2749 */ { MAD_F(0x04b36ae4) /* 0.293803113 */, 17 }, /* 2750 */ { MAD_F(0x04b40053) /* 0.293945624 */, 17 }, /* 2751 */ { MAD_F(0x04b495c7) /* 0.294088151 */, 17 }, /* 2752 */ { MAD_F(0x04b52b3f) /* 0.294230696 */, 17 }, /* 2753 */ { MAD_F(0x04b5c0bc) /* 0.294373259 */, 17 }, /* 2754 */ { MAD_F(0x04b6563d) /* 0.294515838 */, 17 }, /* 2755 */ { MAD_F(0x04b6ebc3) /* 0.294658435 */, 17 }, /* 2756 */ { MAD_F(0x04b7814e) /* 0.294801049 */, 17 }, /* 2757 */ { MAD_F(0x04b816dd) /* 0.294943680 */, 17 }, /* 2758 */ { MAD_F(0x04b8ac71) /* 0.295086329 */, 17 }, /* 2759 */ { MAD_F(0x04b9420a) /* 0.295228995 */, 17 }, /* 2760 */ { MAD_F(0x04b9d7a7) /* 0.295371678 */, 17 }, /* 2761 */ { MAD_F(0x04ba6d49) /* 0.295514378 */, 17 }, /* 2762 */ { MAD_F(0x04bb02ef) /* 0.295657095 */, 17 }, /* 2763 */ { MAD_F(0x04bb989a) /* 0.295799830 */, 17 }, /* 2764 */ { MAD_F(0x04bc2e4a) /* 0.295942582 */, 17 }, /* 2765 */ { MAD_F(0x04bcc3fe) /* 0.296085351 */, 17 }, /* 2766 */ { MAD_F(0x04bd59b7) /* 0.296228138 */, 17 }, /* 2767 */ { MAD_F(0x04bdef74) /* 0.296370941 */, 17 }, /* 2768 */ { MAD_F(0x04be8537) /* 0.296513762 */, 17 }, /* 2769 */ { MAD_F(0x04bf1afd) /* 0.296656600 */, 17 }, /* 2770 */ { MAD_F(0x04bfb0c9) /* 0.296799455 */, 17 }, /* 2771 */ { MAD_F(0x04c04699) /* 0.296942327 */, 17 }, /* 2772 */ { MAD_F(0x04c0dc6d) /* 0.297085217 */, 17 }, /* 2773 */ { MAD_F(0x04c17247) /* 0.297228124 */, 17 }, /* 2774 */ { MAD_F(0x04c20824) /* 0.297371048 */, 17 }, /* 2775 */ { MAD_F(0x04c29e07) /* 0.297513989 */, 17 }, /* 2776 */ { MAD_F(0x04c333ee) /* 0.297656947 */, 17 }, /* 2777 */ { MAD_F(0x04c3c9da) /* 0.297799922 */, 17 }, /* 2778 */ { MAD_F(0x04c45fca) /* 0.297942915 */, 17 }, /* 2779 */ { MAD_F(0x04c4f5bf) /* 0.298085925 */, 17 }, /* 2780 */ { MAD_F(0x04c58bb8) /* 0.298228951 */, 17 }, /* 2781 */ { MAD_F(0x04c621b6) /* 0.298371996 */, 17 }, /* 2782 */ { MAD_F(0x04c6b7b9) /* 0.298515057 */, 17 }, /* 2783 */ { MAD_F(0x04c74dc0) /* 0.298658135 */, 17 }, /* 2784 */ { MAD_F(0x04c7e3cc) /* 0.298801231 */, 17 }, /* 2785 */ { MAD_F(0x04c879dd) /* 0.298944343 */, 17 }, /* 2786 */ { MAD_F(0x04c90ff2) /* 0.299087473 */, 17 }, /* 2787 */ { MAD_F(0x04c9a60c) /* 0.299230620 */, 17 }, /* 2788 */ { MAD_F(0x04ca3c2a) /* 0.299373784 */, 17 }, /* 2789 */ { MAD_F(0x04cad24d) /* 0.299516965 */, 17 }, /* 2790 */ { MAD_F(0x04cb6874) /* 0.299660163 */, 17 }, /* 2791 */ { MAD_F(0x04cbfea0) /* 0.299803378 */, 17 }, /* 2792 */ { MAD_F(0x04cc94d1) /* 0.299946611 */, 17 }, /* 2793 */ { MAD_F(0x04cd2b06) /* 0.300089860 */, 17 }, /* 2794 */ { MAD_F(0x04cdc140) /* 0.300233127 */, 17 }, /* 2795 */ { MAD_F(0x04ce577f) /* 0.300376411 */, 17 }, /* 2796 */ { MAD_F(0x04ceedc2) /* 0.300519711 */, 17 }, /* 2797 */ { MAD_F(0x04cf8409) /* 0.300663029 */, 17 }, /* 2798 */ { MAD_F(0x04d01a55) /* 0.300806364 */, 17 }, /* 2799 */ { MAD_F(0x04d0b0a6) /* 0.300949716 */, 17 }, /* 2800 */ { MAD_F(0x04d146fb) /* 0.301093085 */, 17 }, /* 2801 */ { MAD_F(0x04d1dd55) /* 0.301236472 */, 17 }, /* 2802 */ { MAD_F(0x04d273b4) /* 0.301379875 */, 17 }, /* 2803 */ { MAD_F(0x04d30a17) /* 0.301523295 */, 17 }, /* 2804 */ { MAD_F(0x04d3a07f) /* 0.301666733 */, 17 }, /* 2805 */ { MAD_F(0x04d436eb) /* 0.301810187 */, 17 }, /* 2806 */ { MAD_F(0x04d4cd5c) /* 0.301953659 */, 17 }, /* 2807 */ { MAD_F(0x04d563d1) /* 0.302097147 */, 17 }, /* 2808 */ { MAD_F(0x04d5fa4b) /* 0.302240653 */, 17 }, /* 2809 */ { MAD_F(0x04d690ca) /* 0.302384175 */, 17 }, /* 2810 */ { MAD_F(0x04d7274d) /* 0.302527715 */, 17 }, /* 2811 */ { MAD_F(0x04d7bdd5) /* 0.302671271 */, 17 }, /* 2812 */ { MAD_F(0x04d85461) /* 0.302814845 */, 17 }, /* 2813 */ { MAD_F(0x04d8eaf2) /* 0.302958436 */, 17 }, /* 2814 */ { MAD_F(0x04d98187) /* 0.303102044 */, 17 }, /* 2815 */ { MAD_F(0x04da1821) /* 0.303245668 */, 17 }, /* 2816 */ { MAD_F(0x04daaec0) /* 0.303389310 */, 17 }, /* 2817 */ { MAD_F(0x04db4563) /* 0.303532969 */, 17 }, /* 2818 */ { MAD_F(0x04dbdc0a) /* 0.303676645 */, 17 }, /* 2819 */ { MAD_F(0x04dc72b7) /* 0.303820337 */, 17 }, /* 2820 */ { MAD_F(0x04dd0967) /* 0.303964047 */, 17 }, /* 2821 */ { MAD_F(0x04dda01d) /* 0.304107774 */, 17 }, /* 2822 */ { MAD_F(0x04de36d7) /* 0.304251517 */, 17 }, /* 2823 */ { MAD_F(0x04decd95) /* 0.304395278 */, 17 }, /* 2824 */ { MAD_F(0x04df6458) /* 0.304539056 */, 17 }, /* 2825 */ { MAD_F(0x04dffb20) /* 0.304682850 */, 17 }, /* 2826 */ { MAD_F(0x04e091ec) /* 0.304826662 */, 17 }, /* 2827 */ { MAD_F(0x04e128bc) /* 0.304970491 */, 17 }, /* 2828 */ { MAD_F(0x04e1bf92) /* 0.305114336 */, 17 }, /* 2829 */ { MAD_F(0x04e2566b) /* 0.305258199 */, 17 }, /* 2830 */ { MAD_F(0x04e2ed4a) /* 0.305402078 */, 17 }, /* 2831 */ { MAD_F(0x04e3842d) /* 0.305545974 */, 17 }, /* 2832 */ { MAD_F(0x04e41b14) /* 0.305689888 */, 17 }, /* 2833 */ { MAD_F(0x04e4b200) /* 0.305833818 */, 17 }, /* 2834 */ { MAD_F(0x04e548f1) /* 0.305977765 */, 17 }, /* 2835 */ { MAD_F(0x04e5dfe6) /* 0.306121729 */, 17 }, /* 2836 */ { MAD_F(0x04e676df) /* 0.306265710 */, 17 }, /* 2837 */ { MAD_F(0x04e70dde) /* 0.306409708 */, 17 }, /* 2838 */ { MAD_F(0x04e7a4e0) /* 0.306553723 */, 17 }, /* 2839 */ { MAD_F(0x04e83be7) /* 0.306697755 */, 17 }, /* 2840 */ { MAD_F(0x04e8d2f3) /* 0.306841804 */, 17 }, /* 2841 */ { MAD_F(0x04e96a04) /* 0.306985869 */, 17 }, /* 2842 */ { MAD_F(0x04ea0118) /* 0.307129952 */, 17 }, /* 2843 */ { MAD_F(0x04ea9832) /* 0.307274051 */, 17 }, /* 2844 */ { MAD_F(0x04eb2f50) /* 0.307418168 */, 17 }, /* 2845 */ { MAD_F(0x04ebc672) /* 0.307562301 */, 17 }, /* 2846 */ { MAD_F(0x04ec5d99) /* 0.307706451 */, 17 }, /* 2847 */ { MAD_F(0x04ecf4c5) /* 0.307850618 */, 17 }, /* 2848 */ { MAD_F(0x04ed8bf5) /* 0.307994802 */, 17 }, /* 2849 */ { MAD_F(0x04ee2329) /* 0.308139003 */, 17 }, /* 2850 */ { MAD_F(0x04eeba63) /* 0.308283220 */, 17 }, /* 2851 */ { MAD_F(0x04ef51a0) /* 0.308427455 */, 17 }, /* 2852 */ { MAD_F(0x04efe8e2) /* 0.308571706 */, 17 }, /* 2853 */ { MAD_F(0x04f08029) /* 0.308715974 */, 17 }, /* 2854 */ { MAD_F(0x04f11774) /* 0.308860260 */, 17 }, /* 2855 */ { MAD_F(0x04f1aec4) /* 0.309004561 */, 17 }, /* 2856 */ { MAD_F(0x04f24618) /* 0.309148880 */, 17 }, /* 2857 */ { MAD_F(0x04f2dd71) /* 0.309293216 */, 17 }, /* 2858 */ { MAD_F(0x04f374cf) /* 0.309437568 */, 17 }, /* 2859 */ { MAD_F(0x04f40c30) /* 0.309581938 */, 17 }, /* 2860 */ { MAD_F(0x04f4a397) /* 0.309726324 */, 17 }, /* 2861 */ { MAD_F(0x04f53b02) /* 0.309870727 */, 17 }, /* 2862 */ { MAD_F(0x04f5d271) /* 0.310015147 */, 17 }, /* 2863 */ { MAD_F(0x04f669e5) /* 0.310159583 */, 17 }, /* 2864 */ { MAD_F(0x04f7015d) /* 0.310304037 */, 17 }, /* 2865 */ { MAD_F(0x04f798da) /* 0.310448507 */, 17 }, /* 2866 */ { MAD_F(0x04f8305c) /* 0.310592994 */, 17 }, /* 2867 */ { MAD_F(0x04f8c7e2) /* 0.310737498 */, 17 }, /* 2868 */ { MAD_F(0x04f95f6c) /* 0.310882018 */, 17 }, /* 2869 */ { MAD_F(0x04f9f6fb) /* 0.311026556 */, 17 }, /* 2870 */ { MAD_F(0x04fa8e8f) /* 0.311171110 */, 17 }, /* 2871 */ { MAD_F(0x04fb2627) /* 0.311315681 */, 17 }, /* 2872 */ { MAD_F(0x04fbbdc3) /* 0.311460269 */, 17 }, /* 2873 */ { MAD_F(0x04fc5564) /* 0.311604874 */, 17 }, /* 2874 */ { MAD_F(0x04fced0a) /* 0.311749495 */, 17 }, /* 2875 */ { MAD_F(0x04fd84b4) /* 0.311894133 */, 17 }, /* 2876 */ { MAD_F(0x04fe1c62) /* 0.312038788 */, 17 }, /* 2877 */ { MAD_F(0x04feb415) /* 0.312183460 */, 17 }, /* 2878 */ { MAD_F(0x04ff4bcd) /* 0.312328148 */, 17 }, /* 2879 */ { MAD_F(0x04ffe389) /* 0.312472854 */, 17 }, /* 2880 */ { MAD_F(0x05007b49) /* 0.312617576 */, 17 }, /* 2881 */ { MAD_F(0x0501130e) /* 0.312762314 */, 17 }, /* 2882 */ { MAD_F(0x0501aad8) /* 0.312907070 */, 17 }, /* 2883 */ { MAD_F(0x050242a6) /* 0.313051842 */, 17 }, /* 2884 */ { MAD_F(0x0502da78) /* 0.313196631 */, 17 }, /* 2885 */ { MAD_F(0x0503724f) /* 0.313341437 */, 17 }, /* 2886 */ { MAD_F(0x05040a2b) /* 0.313486259 */, 17 }, /* 2887 */ { MAD_F(0x0504a20b) /* 0.313631098 */, 17 }, /* 2888 */ { MAD_F(0x050539ef) /* 0.313775954 */, 17 }, /* 2889 */ { MAD_F(0x0505d1d8) /* 0.313920827 */, 17 }, /* 2890 */ { MAD_F(0x050669c5) /* 0.314065716 */, 17 }, /* 2891 */ { MAD_F(0x050701b7) /* 0.314210622 */, 17 }, /* 2892 */ { MAD_F(0x050799ae) /* 0.314355545 */, 17 }, /* 2893 */ { MAD_F(0x050831a9) /* 0.314500484 */, 17 }, /* 2894 */ { MAD_F(0x0508c9a8) /* 0.314645440 */, 17 }, /* 2895 */ { MAD_F(0x050961ac) /* 0.314790413 */, 17 }, /* 2896 */ { MAD_F(0x0509f9b4) /* 0.314935403 */, 17 }, /* 2897 */ { MAD_F(0x050a91c1) /* 0.315080409 */, 17 }, /* 2898 */ { MAD_F(0x050b29d2) /* 0.315225432 */, 17 }, /* 2899 */ { MAD_F(0x050bc1e8) /* 0.315370472 */, 17 }, /* 2900 */ { MAD_F(0x050c5a02) /* 0.315515528 */, 17 }, /* 2901 */ { MAD_F(0x050cf221) /* 0.315660601 */, 17 }, /* 2902 */ { MAD_F(0x050d8a44) /* 0.315805690 */, 17 }, /* 2903 */ { MAD_F(0x050e226c) /* 0.315950797 */, 17 }, /* 2904 */ { MAD_F(0x050eba98) /* 0.316095920 */, 17 }, /* 2905 */ { MAD_F(0x050f52c9) /* 0.316241059 */, 17 }, /* 2906 */ { MAD_F(0x050feafe) /* 0.316386216 */, 17 }, /* 2907 */ { MAD_F(0x05108337) /* 0.316531388 */, 17 }, /* 2908 */ { MAD_F(0x05111b75) /* 0.316676578 */, 17 }, /* 2909 */ { MAD_F(0x0511b3b8) /* 0.316821784 */, 17 }, /* 2910 */ { MAD_F(0x05124bff) /* 0.316967007 */, 17 }, /* 2911 */ { MAD_F(0x0512e44a) /* 0.317112247 */, 17 }, /* 2912 */ { MAD_F(0x05137c9a) /* 0.317257503 */, 17 }, /* 2913 */ { MAD_F(0x051414ee) /* 0.317402775 */, 17 }, /* 2914 */ { MAD_F(0x0514ad47) /* 0.317548065 */, 17 }, /* 2915 */ { MAD_F(0x051545a5) /* 0.317693371 */, 17 }, /* 2916 */ { MAD_F(0x0515de06) /* 0.317838693 */, 17 }, /* 2917 */ { MAD_F(0x0516766d) /* 0.317984033 */, 17 }, /* 2918 */ { MAD_F(0x05170ed7) /* 0.318129388 */, 17 }, /* 2919 */ { MAD_F(0x0517a746) /* 0.318274761 */, 17 }, /* 2920 */ { MAD_F(0x05183fba) /* 0.318420150 */, 17 }, /* 2921 */ { MAD_F(0x0518d832) /* 0.318565555 */, 17 }, /* 2922 */ { MAD_F(0x051970ae) /* 0.318710978 */, 17 }, /* 2923 */ { MAD_F(0x051a092f) /* 0.318856416 */, 17 }, /* 2924 */ { MAD_F(0x051aa1b5) /* 0.319001872 */, 17 }, /* 2925 */ { MAD_F(0x051b3a3f) /* 0.319147344 */, 17 }, /* 2926 */ { MAD_F(0x051bd2cd) /* 0.319292832 */, 17 }, /* 2927 */ { MAD_F(0x051c6b60) /* 0.319438338 */, 17 }, /* 2928 */ { MAD_F(0x051d03f7) /* 0.319583859 */, 17 }, /* 2929 */ { MAD_F(0x051d9c92) /* 0.319729398 */, 17 }, /* 2930 */ { MAD_F(0x051e3532) /* 0.319874952 */, 17 }, /* 2931 */ { MAD_F(0x051ecdd7) /* 0.320020524 */, 17 }, /* 2932 */ { MAD_F(0x051f6680) /* 0.320166112 */, 17 }, /* 2933 */ { MAD_F(0x051fff2d) /* 0.320311716 */, 17 }, /* 2934 */ { MAD_F(0x052097df) /* 0.320457337 */, 17 }, /* 2935 */ { MAD_F(0x05213095) /* 0.320602975 */, 17 }, /* 2936 */ { MAD_F(0x0521c950) /* 0.320748629 */, 17 }, /* 2937 */ { MAD_F(0x0522620f) /* 0.320894300 */, 17 }, /* 2938 */ { MAD_F(0x0522fad3) /* 0.321039987 */, 17 }, /* 2939 */ { MAD_F(0x0523939b) /* 0.321185691 */, 17 }, /* 2940 */ { MAD_F(0x05242c68) /* 0.321331411 */, 17 }, /* 2941 */ { MAD_F(0x0524c538) /* 0.321477148 */, 17 }, /* 2942 */ { MAD_F(0x05255e0e) /* 0.321622901 */, 17 }, /* 2943 */ { MAD_F(0x0525f6e8) /* 0.321768671 */, 17 }, /* 2944 */ { MAD_F(0x05268fc6) /* 0.321914457 */, 17 }, /* 2945 */ { MAD_F(0x052728a9) /* 0.322060260 */, 17 }, /* 2946 */ { MAD_F(0x0527c190) /* 0.322206079 */, 17 }, /* 2947 */ { MAD_F(0x05285a7b) /* 0.322351915 */, 17 }, /* 2948 */ { MAD_F(0x0528f36b) /* 0.322497768 */, 17 }, /* 2949 */ { MAD_F(0x05298c5f) /* 0.322643636 */, 17 }, /* 2950 */ { MAD_F(0x052a2558) /* 0.322789522 */, 17 }, /* 2951 */ { MAD_F(0x052abe55) /* 0.322935424 */, 17 }, /* 2952 */ { MAD_F(0x052b5757) /* 0.323081342 */, 17 }, /* 2953 */ { MAD_F(0x052bf05d) /* 0.323227277 */, 17 }, /* 2954 */ { MAD_F(0x052c8968) /* 0.323373228 */, 17 }, /* 2955 */ { MAD_F(0x052d2277) /* 0.323519196 */, 17 }, /* 2956 */ { MAD_F(0x052dbb8a) /* 0.323665180 */, 17 }, /* 2957 */ { MAD_F(0x052e54a2) /* 0.323811180 */, 17 }, /* 2958 */ { MAD_F(0x052eedbe) /* 0.323957197 */, 17 }, /* 2959 */ { MAD_F(0x052f86de) /* 0.324103231 */, 17 }, /* 2960 */ { MAD_F(0x05302003) /* 0.324249281 */, 17 }, /* 2961 */ { MAD_F(0x0530b92d) /* 0.324395347 */, 17 }, /* 2962 */ { MAD_F(0x0531525b) /* 0.324541430 */, 17 }, /* 2963 */ { MAD_F(0x0531eb8d) /* 0.324687530 */, 17 }, /* 2964 */ { MAD_F(0x053284c4) /* 0.324833646 */, 17 }, /* 2965 */ { MAD_F(0x05331dff) /* 0.324979778 */, 17 }, /* 2966 */ { MAD_F(0x0533b73e) /* 0.325125926 */, 17 }, /* 2967 */ { MAD_F(0x05345082) /* 0.325272091 */, 17 }, /* 2968 */ { MAD_F(0x0534e9ca) /* 0.325418273 */, 17 }, /* 2969 */ { MAD_F(0x05358317) /* 0.325564471 */, 17 }, /* 2970 */ { MAD_F(0x05361c68) /* 0.325710685 */, 17 }, /* 2971 */ { MAD_F(0x0536b5be) /* 0.325856916 */, 17 }, /* 2972 */ { MAD_F(0x05374f17) /* 0.326003163 */, 17 }, /* 2973 */ { MAD_F(0x0537e876) /* 0.326149427 */, 17 }, /* 2974 */ { MAD_F(0x053881d9) /* 0.326295707 */, 17 }, /* 2975 */ { MAD_F(0x05391b40) /* 0.326442003 */, 17 }, /* 2976 */ { MAD_F(0x0539b4ab) /* 0.326588316 */, 17 }, /* 2977 */ { MAD_F(0x053a4e1b) /* 0.326734645 */, 17 }, /* 2978 */ { MAD_F(0x053ae78f) /* 0.326880990 */, 17 }, /* 2979 */ { MAD_F(0x053b8108) /* 0.327027352 */, 17 }, /* 2980 */ { MAD_F(0x053c1a85) /* 0.327173730 */, 17 }, /* 2981 */ { MAD_F(0x053cb407) /* 0.327320125 */, 17 }, /* 2982 */ { MAD_F(0x053d4d8d) /* 0.327466536 */, 17 }, /* 2983 */ { MAD_F(0x053de717) /* 0.327612963 */, 17 }, /* 2984 */ { MAD_F(0x053e80a6) /* 0.327759407 */, 17 }, /* 2985 */ { MAD_F(0x053f1a39) /* 0.327905867 */, 17 }, /* 2986 */ { MAD_F(0x053fb3d0) /* 0.328052344 */, 17 }, /* 2987 */ { MAD_F(0x05404d6c) /* 0.328198837 */, 17 }, /* 2988 */ { MAD_F(0x0540e70c) /* 0.328345346 */, 17 }, /* 2989 */ { MAD_F(0x054180b1) /* 0.328491871 */, 17 }, /* 2990 */ { MAD_F(0x05421a5a) /* 0.328638413 */, 17 }, /* 2991 */ { MAD_F(0x0542b407) /* 0.328784971 */, 17 }, /* 2992 */ { MAD_F(0x05434db9) /* 0.328931546 */, 17 }, /* 2993 */ { MAD_F(0x0543e76f) /* 0.329078137 */, 17 }, /* 2994 */ { MAD_F(0x0544812a) /* 0.329224744 */, 17 }, /* 2995 */ { MAD_F(0x05451ae9) /* 0.329371367 */, 17 }, /* 2996 */ { MAD_F(0x0545b4ac) /* 0.329518007 */, 17 }, /* 2997 */ { MAD_F(0x05464e74) /* 0.329664663 */, 17 }, /* 2998 */ { MAD_F(0x0546e840) /* 0.329811336 */, 17 }, /* 2999 */ { MAD_F(0x05478211) /* 0.329958024 */, 17 }, /* 3000 */ { MAD_F(0x05481be5) /* 0.330104730 */, 17 }, /* 3001 */ { MAD_F(0x0548b5bf) /* 0.330251451 */, 17 }, /* 3002 */ { MAD_F(0x05494f9c) /* 0.330398189 */, 17 }, /* 3003 */ { MAD_F(0x0549e97e) /* 0.330544943 */, 17 }, /* 3004 */ { MAD_F(0x054a8364) /* 0.330691713 */, 17 }, /* 3005 */ { MAD_F(0x054b1d4f) /* 0.330838499 */, 17 }, /* 3006 */ { MAD_F(0x054bb73e) /* 0.330985302 */, 17 }, /* 3007 */ { MAD_F(0x054c5132) /* 0.331132121 */, 17 }, /* 3008 */ { MAD_F(0x054ceb2a) /* 0.331278957 */, 17 }, /* 3009 */ { MAD_F(0x054d8526) /* 0.331425808 */, 17 }, /* 3010 */ { MAD_F(0x054e1f26) /* 0.331572676 */, 17 }, /* 3011 */ { MAD_F(0x054eb92b) /* 0.331719560 */, 17 }, /* 3012 */ { MAD_F(0x054f5334) /* 0.331866461 */, 17 }, /* 3013 */ { MAD_F(0x054fed42) /* 0.332013377 */, 17 }, /* 3014 */ { MAD_F(0x05508754) /* 0.332160310 */, 17 }, /* 3015 */ { MAD_F(0x0551216b) /* 0.332307260 */, 17 }, /* 3016 */ { MAD_F(0x0551bb85) /* 0.332454225 */, 17 }, /* 3017 */ { MAD_F(0x055255a4) /* 0.332601207 */, 17 }, /* 3018 */ { MAD_F(0x0552efc8) /* 0.332748205 */, 17 }, /* 3019 */ { MAD_F(0x055389f0) /* 0.332895219 */, 17 }, /* 3020 */ { MAD_F(0x0554241c) /* 0.333042249 */, 17 }, /* 3021 */ { MAD_F(0x0554be4c) /* 0.333189296 */, 17 }, /* 3022 */ { MAD_F(0x05555881) /* 0.333336359 */, 17 }, /* 3023 */ { MAD_F(0x0555f2ba) /* 0.333483438 */, 17 }, /* 3024 */ { MAD_F(0x05568cf8) /* 0.333630533 */, 17 }, /* 3025 */ { MAD_F(0x0557273a) /* 0.333777645 */, 17 }, /* 3026 */ { MAD_F(0x0557c180) /* 0.333924772 */, 17 }, /* 3027 */ { MAD_F(0x05585bcb) /* 0.334071916 */, 17 }, /* 3028 */ { MAD_F(0x0558f61a) /* 0.334219076 */, 17 }, /* 3029 */ { MAD_F(0x0559906d) /* 0.334366253 */, 17 }, /* 3030 */ { MAD_F(0x055a2ac5) /* 0.334513445 */, 17 }, /* 3031 */ { MAD_F(0x055ac521) /* 0.334660654 */, 17 }, /* 3032 */ { MAD_F(0x055b5f81) /* 0.334807879 */, 17 }, /* 3033 */ { MAD_F(0x055bf9e6) /* 0.334955120 */, 17 }, /* 3034 */ { MAD_F(0x055c944f) /* 0.335102377 */, 17 }, /* 3035 */ { MAD_F(0x055d2ebd) /* 0.335249651 */, 17 }, /* 3036 */ { MAD_F(0x055dc92e) /* 0.335396941 */, 17 }, /* 3037 */ { MAD_F(0x055e63a5) /* 0.335544246 */, 17 }, /* 3038 */ { MAD_F(0x055efe1f) /* 0.335691568 */, 17 }, /* 3039 */ { MAD_F(0x055f989e) /* 0.335838906 */, 17 }, /* 3040 */ { MAD_F(0x05603321) /* 0.335986261 */, 17 }, /* 3041 */ { MAD_F(0x0560cda8) /* 0.336133631 */, 17 }, /* 3042 */ { MAD_F(0x05616834) /* 0.336281018 */, 17 }, /* 3043 */ { MAD_F(0x056202c4) /* 0.336428421 */, 17 }, /* 3044 */ { MAD_F(0x05629d59) /* 0.336575840 */, 17 }, /* 3045 */ { MAD_F(0x056337f2) /* 0.336723275 */, 17 }, /* 3046 */ { MAD_F(0x0563d28f) /* 0.336870726 */, 17 }, /* 3047 */ { MAD_F(0x05646d30) /* 0.337018193 */, 17 }, /* 3048 */ { MAD_F(0x056507d6) /* 0.337165677 */, 17 }, /* 3049 */ { MAD_F(0x0565a280) /* 0.337313176 */, 17 }, /* 3050 */ { MAD_F(0x05663d2f) /* 0.337460692 */, 17 }, /* 3051 */ { MAD_F(0x0566d7e1) /* 0.337608224 */, 17 }, /* 3052 */ { MAD_F(0x05677298) /* 0.337755772 */, 17 }, /* 3053 */ { MAD_F(0x05680d54) /* 0.337903336 */, 17 }, /* 3054 */ { MAD_F(0x0568a814) /* 0.338050916 */, 17 }, /* 3055 */ { MAD_F(0x056942d8) /* 0.338198513 */, 17 }, /* 3056 */ { MAD_F(0x0569dda0) /* 0.338346125 */, 17 }, /* 3057 */ { MAD_F(0x056a786d) /* 0.338493753 */, 17 }, /* 3058 */ { MAD_F(0x056b133e) /* 0.338641398 */, 17 }, /* 3059 */ { MAD_F(0x056bae13) /* 0.338789059 */, 17 }, /* 3060 */ { MAD_F(0x056c48ed) /* 0.338936736 */, 17 }, /* 3061 */ { MAD_F(0x056ce3cb) /* 0.339084429 */, 17 }, /* 3062 */ { MAD_F(0x056d7ead) /* 0.339232138 */, 17 }, /* 3063 */ { MAD_F(0x056e1994) /* 0.339379863 */, 17 }, /* 3064 */ { MAD_F(0x056eb47f) /* 0.339527604 */, 17 }, /* 3065 */ { MAD_F(0x056f4f6e) /* 0.339675361 */, 17 }, /* 3066 */ { MAD_F(0x056fea62) /* 0.339823134 */, 17 }, /* 3067 */ { MAD_F(0x0570855a) /* 0.339970924 */, 17 }, /* 3068 */ { MAD_F(0x05712056) /* 0.340118729 */, 17 }, /* 3069 */ { MAD_F(0x0571bb56) /* 0.340266550 */, 17 }, /* 3070 */ { MAD_F(0x0572565b) /* 0.340414388 */, 17 }, /* 3071 */ { MAD_F(0x0572f164) /* 0.340562242 */, 17 }, /* 3072 */ { MAD_F(0x05738c72) /* 0.340710111 */, 17 }, /* 3073 */ { MAD_F(0x05742784) /* 0.340857997 */, 17 }, /* 3074 */ { MAD_F(0x0574c29a) /* 0.341005899 */, 17 }, /* 3075 */ { MAD_F(0x05755db4) /* 0.341153816 */, 17 }, /* 3076 */ { MAD_F(0x0575f8d3) /* 0.341301750 */, 17 }, /* 3077 */ { MAD_F(0x057693f6) /* 0.341449700 */, 17 }, /* 3078 */ { MAD_F(0x05772f1d) /* 0.341597666 */, 17 }, /* 3079 */ { MAD_F(0x0577ca49) /* 0.341745648 */, 17 }, /* 3080 */ { MAD_F(0x05786578) /* 0.341893646 */, 17 }, /* 3081 */ { MAD_F(0x057900ad) /* 0.342041659 */, 17 }, /* 3082 */ { MAD_F(0x05799be5) /* 0.342189689 */, 17 }, /* 3083 */ { MAD_F(0x057a3722) /* 0.342337735 */, 17 }, /* 3084 */ { MAD_F(0x057ad263) /* 0.342485797 */, 17 }, /* 3085 */ { MAD_F(0x057b6da8) /* 0.342633875 */, 17 }, /* 3086 */ { MAD_F(0x057c08f2) /* 0.342781969 */, 17 }, /* 3087 */ { MAD_F(0x057ca440) /* 0.342930079 */, 17 }, /* 3088 */ { MAD_F(0x057d3f92) /* 0.343078205 */, 17 }, /* 3089 */ { MAD_F(0x057ddae9) /* 0.343226347 */, 17 }, /* 3090 */ { MAD_F(0x057e7644) /* 0.343374505 */, 17 }, /* 3091 */ { MAD_F(0x057f11a3) /* 0.343522679 */, 17 }, /* 3092 */ { MAD_F(0x057fad06) /* 0.343670869 */, 17 }, /* 3093 */ { MAD_F(0x0580486e) /* 0.343819075 */, 17 }, /* 3094 */ { MAD_F(0x0580e3da) /* 0.343967296 */, 17 }, /* 3095 */ { MAD_F(0x05817f4a) /* 0.344115534 */, 17 }, /* 3096 */ { MAD_F(0x05821abf) /* 0.344263788 */, 17 }, /* 3097 */ { MAD_F(0x0582b638) /* 0.344412058 */, 17 }, /* 3098 */ { MAD_F(0x058351b5) /* 0.344560343 */, 17 }, /* 3099 */ { MAD_F(0x0583ed36) /* 0.344708645 */, 17 }, /* 3100 */ { MAD_F(0x058488bc) /* 0.344856963 */, 17 }, /* 3101 */ { MAD_F(0x05852446) /* 0.345005296 */, 17 }, /* 3102 */ { MAD_F(0x0585bfd4) /* 0.345153646 */, 17 }, /* 3103 */ { MAD_F(0x05865b67) /* 0.345302011 */, 17 }, /* 3104 */ { MAD_F(0x0586f6fd) /* 0.345450393 */, 17 }, /* 3105 */ { MAD_F(0x05879298) /* 0.345598790 */, 17 }, /* 3106 */ { MAD_F(0x05882e38) /* 0.345747203 */, 17 }, /* 3107 */ { MAD_F(0x0588c9dc) /* 0.345895632 */, 17 }, /* 3108 */ { MAD_F(0x05896583) /* 0.346044077 */, 17 }, /* 3109 */ { MAD_F(0x058a0130) /* 0.346192538 */, 17 }, /* 3110 */ { MAD_F(0x058a9ce0) /* 0.346341015 */, 17 }, /* 3111 */ { MAD_F(0x058b3895) /* 0.346489508 */, 17 }, /* 3112 */ { MAD_F(0x058bd44e) /* 0.346638017 */, 17 }, /* 3113 */ { MAD_F(0x058c700b) /* 0.346786542 */, 17 }, /* 3114 */ { MAD_F(0x058d0bcd) /* 0.346935082 */, 17 }, /* 3115 */ { MAD_F(0x058da793) /* 0.347083639 */, 17 }, /* 3116 */ { MAD_F(0x058e435d) /* 0.347232211 */, 17 }, /* 3117 */ { MAD_F(0x058edf2b) /* 0.347380799 */, 17 }, /* 3118 */ { MAD_F(0x058f7afe) /* 0.347529403 */, 17 }, /* 3119 */ { MAD_F(0x059016d5) /* 0.347678023 */, 17 }, /* 3120 */ { MAD_F(0x0590b2b0) /* 0.347826659 */, 17 }, /* 3121 */ { MAD_F(0x05914e8f) /* 0.347975311 */, 17 }, /* 3122 */ { MAD_F(0x0591ea73) /* 0.348123979 */, 17 }, /* 3123 */ { MAD_F(0x0592865b) /* 0.348272662 */, 17 }, /* 3124 */ { MAD_F(0x05932247) /* 0.348421362 */, 17 }, /* 3125 */ { MAD_F(0x0593be37) /* 0.348570077 */, 17 }, /* 3126 */ { MAD_F(0x05945a2c) /* 0.348718808 */, 17 }, /* 3127 */ { MAD_F(0x0594f625) /* 0.348867555 */, 17 }, /* 3128 */ { MAD_F(0x05959222) /* 0.349016318 */, 17 }, /* 3129 */ { MAD_F(0x05962e24) /* 0.349165097 */, 17 }, /* 3130 */ { MAD_F(0x0596ca2a) /* 0.349313892 */, 17 }, /* 3131 */ { MAD_F(0x05976634) /* 0.349462702 */, 17 }, /* 3132 */ { MAD_F(0x05980242) /* 0.349611528 */, 17 }, /* 3133 */ { MAD_F(0x05989e54) /* 0.349760370 */, 17 }, /* 3134 */ { MAD_F(0x05993a6b) /* 0.349909228 */, 17 }, /* 3135 */ { MAD_F(0x0599d686) /* 0.350058102 */, 17 }, /* 3136 */ { MAD_F(0x059a72a5) /* 0.350206992 */, 17 }, /* 3137 */ { MAD_F(0x059b0ec9) /* 0.350355897 */, 17 }, /* 3138 */ { MAD_F(0x059baaf1) /* 0.350504818 */, 17 }, /* 3139 */ { MAD_F(0x059c471d) /* 0.350653756 */, 17 }, /* 3140 */ { MAD_F(0x059ce34d) /* 0.350802708 */, 17 }, /* 3141 */ { MAD_F(0x059d7f81) /* 0.350951677 */, 17 }, /* 3142 */ { MAD_F(0x059e1bba) /* 0.351100662 */, 17 }, /* 3143 */ { MAD_F(0x059eb7f7) /* 0.351249662 */, 17 }, /* 3144 */ { MAD_F(0x059f5438) /* 0.351398678 */, 17 }, /* 3145 */ { MAD_F(0x059ff07e) /* 0.351547710 */, 17 }, /* 3146 */ { MAD_F(0x05a08cc7) /* 0.351696758 */, 17 }, /* 3147 */ { MAD_F(0x05a12915) /* 0.351845821 */, 17 }, /* 3148 */ { MAD_F(0x05a1c567) /* 0.351994901 */, 17 }, /* 3149 */ { MAD_F(0x05a261be) /* 0.352143996 */, 17 }, /* 3150 */ { MAD_F(0x05a2fe18) /* 0.352293107 */, 17 }, /* 3151 */ { MAD_F(0x05a39a77) /* 0.352442233 */, 17 }, /* 3152 */ { MAD_F(0x05a436da) /* 0.352591376 */, 17 }, /* 3153 */ { MAD_F(0x05a4d342) /* 0.352740534 */, 17 }, /* 3154 */ { MAD_F(0x05a56fad) /* 0.352889708 */, 17 }, /* 3155 */ { MAD_F(0x05a60c1d) /* 0.353038898 */, 17 }, /* 3156 */ { MAD_F(0x05a6a891) /* 0.353188103 */, 17 }, /* 3157 */ { MAD_F(0x05a7450a) /* 0.353337325 */, 17 }, /* 3158 */ { MAD_F(0x05a7e186) /* 0.353486562 */, 17 }, /* 3159 */ { MAD_F(0x05a87e07) /* 0.353635814 */, 17 }, /* 3160 */ { MAD_F(0x05a91a8c) /* 0.353785083 */, 17 }, /* 3161 */ { MAD_F(0x05a9b715) /* 0.353934367 */, 17 }, /* 3162 */ { MAD_F(0x05aa53a2) /* 0.354083667 */, 17 }, /* 3163 */ { MAD_F(0x05aaf034) /* 0.354232983 */, 17 }, /* 3164 */ { MAD_F(0x05ab8cca) /* 0.354382314 */, 17 }, /* 3165 */ { MAD_F(0x05ac2964) /* 0.354531662 */, 17 }, /* 3166 */ { MAD_F(0x05acc602) /* 0.354681025 */, 17 }, /* 3167 */ { MAD_F(0x05ad62a5) /* 0.354830403 */, 17 }, /* 3168 */ { MAD_F(0x05adff4c) /* 0.354979798 */, 17 }, /* 3169 */ { MAD_F(0x05ae9bf7) /* 0.355129208 */, 17 }, /* 3170 */ { MAD_F(0x05af38a6) /* 0.355278634 */, 17 }, /* 3171 */ { MAD_F(0x05afd559) /* 0.355428075 */, 17 }, /* 3172 */ { MAD_F(0x05b07211) /* 0.355577533 */, 17 }, /* 3173 */ { MAD_F(0x05b10ecd) /* 0.355727006 */, 17 }, /* 3174 */ { MAD_F(0x05b1ab8d) /* 0.355876494 */, 17 }, /* 3175 */ { MAD_F(0x05b24851) /* 0.356025999 */, 17 }, /* 3176 */ { MAD_F(0x05b2e51a) /* 0.356175519 */, 17 }, /* 3177 */ { MAD_F(0x05b381e6) /* 0.356325054 */, 17 }, /* 3178 */ { MAD_F(0x05b41eb7) /* 0.356474606 */, 17 }, /* 3179 */ { MAD_F(0x05b4bb8c) /* 0.356624173 */, 17 }, /* 3180 */ { MAD_F(0x05b55866) /* 0.356773756 */, 17 }, /* 3181 */ { MAD_F(0x05b5f543) /* 0.356923354 */, 17 }, /* 3182 */ { MAD_F(0x05b69225) /* 0.357072969 */, 17 }, /* 3183 */ { MAD_F(0x05b72f0b) /* 0.357222598 */, 17 }, /* 3184 */ { MAD_F(0x05b7cbf5) /* 0.357372244 */, 17 }, /* 3185 */ { MAD_F(0x05b868e3) /* 0.357521905 */, 17 }, /* 3186 */ { MAD_F(0x05b905d6) /* 0.357671582 */, 17 }, /* 3187 */ { MAD_F(0x05b9a2cd) /* 0.357821275 */, 17 }, /* 3188 */ { MAD_F(0x05ba3fc8) /* 0.357970983 */, 17 }, /* 3189 */ { MAD_F(0x05badcc7) /* 0.358120707 */, 17 }, /* 3190 */ { MAD_F(0x05bb79ca) /* 0.358270446 */, 17 }, /* 3191 */ { MAD_F(0x05bc16d2) /* 0.358420201 */, 17 }, /* 3192 */ { MAD_F(0x05bcb3de) /* 0.358569972 */, 17 }, /* 3193 */ { MAD_F(0x05bd50ee) /* 0.358719758 */, 17 }, /* 3194 */ { MAD_F(0x05bdee02) /* 0.358869560 */, 17 }, /* 3195 */ { MAD_F(0x05be8b1a) /* 0.359019378 */, 17 }, /* 3196 */ { MAD_F(0x05bf2837) /* 0.359169211 */, 17 }, /* 3197 */ { MAD_F(0x05bfc558) /* 0.359319060 */, 17 }, /* 3198 */ { MAD_F(0x05c0627d) /* 0.359468925 */, 17 }, /* 3199 */ { MAD_F(0x05c0ffa6) /* 0.359618805 */, 17 }, /* 3200 */ { MAD_F(0x05c19cd3) /* 0.359768701 */, 17 }, /* 3201 */ { MAD_F(0x05c23a05) /* 0.359918612 */, 17 }, /* 3202 */ { MAD_F(0x05c2d73a) /* 0.360068540 */, 17 }, /* 3203 */ { MAD_F(0x05c37474) /* 0.360218482 */, 17 }, /* 3204 */ { MAD_F(0x05c411b2) /* 0.360368440 */, 17 }, /* 3205 */ { MAD_F(0x05c4aef5) /* 0.360518414 */, 17 }, /* 3206 */ { MAD_F(0x05c54c3b) /* 0.360668404 */, 17 }, /* 3207 */ { MAD_F(0x05c5e986) /* 0.360818409 */, 17 }, /* 3208 */ { MAD_F(0x05c686d5) /* 0.360968429 */, 17 }, /* 3209 */ { MAD_F(0x05c72428) /* 0.361118466 */, 17 }, /* 3210 */ { MAD_F(0x05c7c17f) /* 0.361268517 */, 17 }, /* 3211 */ { MAD_F(0x05c85eda) /* 0.361418585 */, 17 }, /* 3212 */ { MAD_F(0x05c8fc3a) /* 0.361568668 */, 17 }, /* 3213 */ { MAD_F(0x05c9999e) /* 0.361718766 */, 17 }, /* 3214 */ { MAD_F(0x05ca3706) /* 0.361868881 */, 17 }, /* 3215 */ { MAD_F(0x05cad472) /* 0.362019010 */, 17 }, /* 3216 */ { MAD_F(0x05cb71e2) /* 0.362169156 */, 17 }, /* 3217 */ { MAD_F(0x05cc0f57) /* 0.362319316 */, 17 }, /* 3218 */ { MAD_F(0x05ccaccf) /* 0.362469493 */, 17 }, /* 3219 */ { MAD_F(0x05cd4a4c) /* 0.362619685 */, 17 }, /* 3220 */ { MAD_F(0x05cde7cd) /* 0.362769892 */, 17 }, /* 3221 */ { MAD_F(0x05ce8552) /* 0.362920115 */, 17 }, /* 3222 */ { MAD_F(0x05cf22dc) /* 0.363070354 */, 17 }, /* 3223 */ { MAD_F(0x05cfc069) /* 0.363220608 */, 17 }, /* 3224 */ { MAD_F(0x05d05dfb) /* 0.363370878 */, 17 }, /* 3225 */ { MAD_F(0x05d0fb91) /* 0.363521163 */, 17 }, /* 3226 */ { MAD_F(0x05d1992b) /* 0.363671464 */, 17 }, /* 3227 */ { MAD_F(0x05d236c9) /* 0.363821780 */, 17 }, /* 3228 */ { MAD_F(0x05d2d46c) /* 0.363972112 */, 17 }, /* 3229 */ { MAD_F(0x05d37212) /* 0.364122459 */, 17 }, /* 3230 */ { MAD_F(0x05d40fbd) /* 0.364272822 */, 17 }, /* 3231 */ { MAD_F(0x05d4ad6c) /* 0.364423200 */, 17 }, /* 3232 */ { MAD_F(0x05d54b1f) /* 0.364573594 */, 17 }, /* 3233 */ { MAD_F(0x05d5e8d6) /* 0.364724004 */, 17 }, /* 3234 */ { MAD_F(0x05d68691) /* 0.364874429 */, 17 }, /* 3235 */ { MAD_F(0x05d72451) /* 0.365024869 */, 17 }, /* 3236 */ { MAD_F(0x05d7c215) /* 0.365175325 */, 17 }, /* 3237 */ { MAD_F(0x05d85fdc) /* 0.365325796 */, 17 }, /* 3238 */ { MAD_F(0x05d8fda8) /* 0.365476283 */, 17 }, /* 3239 */ { MAD_F(0x05d99b79) /* 0.365626786 */, 17 }, /* 3240 */ { MAD_F(0x05da394d) /* 0.365777304 */, 17 }, /* 3241 */ { MAD_F(0x05dad726) /* 0.365927837 */, 17 }, /* 3242 */ { MAD_F(0x05db7502) /* 0.366078386 */, 17 }, /* 3243 */ { MAD_F(0x05dc12e3) /* 0.366228950 */, 17 }, /* 3244 */ { MAD_F(0x05dcb0c8) /* 0.366379530 */, 17 }, /* 3245 */ { MAD_F(0x05dd4eb1) /* 0.366530125 */, 17 }, /* 3246 */ { MAD_F(0x05ddec9e) /* 0.366680736 */, 17 }, /* 3247 */ { MAD_F(0x05de8a90) /* 0.366831362 */, 17 }, /* 3248 */ { MAD_F(0x05df2885) /* 0.366982004 */, 17 }, /* 3249 */ { MAD_F(0x05dfc67f) /* 0.367132661 */, 17 }, /* 3250 */ { MAD_F(0x05e0647d) /* 0.367283334 */, 17 }, /* 3251 */ { MAD_F(0x05e1027f) /* 0.367434022 */, 17 }, /* 3252 */ { MAD_F(0x05e1a085) /* 0.367584725 */, 17 }, /* 3253 */ { MAD_F(0x05e23e8f) /* 0.367735444 */, 17 }, /* 3254 */ { MAD_F(0x05e2dc9e) /* 0.367886179 */, 17 }, /* 3255 */ { MAD_F(0x05e37ab0) /* 0.368036929 */, 17 }, /* 3256 */ { MAD_F(0x05e418c7) /* 0.368187694 */, 17 }, /* 3257 */ { MAD_F(0x05e4b6e2) /* 0.368338475 */, 17 }, /* 3258 */ { MAD_F(0x05e55501) /* 0.368489271 */, 17 }, /* 3259 */ { MAD_F(0x05e5f324) /* 0.368640082 */, 17 }, /* 3260 */ { MAD_F(0x05e6914c) /* 0.368790909 */, 17 }, /* 3261 */ { MAD_F(0x05e72f77) /* 0.368941752 */, 17 }, /* 3262 */ { MAD_F(0x05e7cda7) /* 0.369092610 */, 17 }, /* 3263 */ { MAD_F(0x05e86bda) /* 0.369243483 */, 17 }, /* 3264 */ { MAD_F(0x05e90a12) /* 0.369394372 */, 17 }, /* 3265 */ { MAD_F(0x05e9a84e) /* 0.369545276 */, 17 }, /* 3266 */ { MAD_F(0x05ea468e) /* 0.369696195 */, 17 }, /* 3267 */ { MAD_F(0x05eae4d3) /* 0.369847130 */, 17 }, /* 3268 */ { MAD_F(0x05eb831b) /* 0.369998080 */, 17 }, /* 3269 */ { MAD_F(0x05ec2168) /* 0.370149046 */, 17 }, /* 3270 */ { MAD_F(0x05ecbfb8) /* 0.370300027 */, 17 }, /* 3271 */ { MAD_F(0x05ed5e0d) /* 0.370451024 */, 17 }, /* 3272 */ { MAD_F(0x05edfc66) /* 0.370602036 */, 17 }, /* 3273 */ { MAD_F(0x05ee9ac3) /* 0.370753063 */, 17 }, /* 3274 */ { MAD_F(0x05ef3924) /* 0.370904105 */, 17 }, /* 3275 */ { MAD_F(0x05efd78a) /* 0.371055163 */, 17 }, /* 3276 */ { MAD_F(0x05f075f3) /* 0.371206237 */, 17 }, /* 3277 */ { MAD_F(0x05f11461) /* 0.371357326 */, 17 }, /* 3278 */ { MAD_F(0x05f1b2d3) /* 0.371508430 */, 17 }, /* 3279 */ { MAD_F(0x05f25148) /* 0.371659549 */, 17 }, /* 3280 */ { MAD_F(0x05f2efc2) /* 0.371810684 */, 17 }, /* 3281 */ { MAD_F(0x05f38e40) /* 0.371961834 */, 17 }, /* 3282 */ { MAD_F(0x05f42cc3) /* 0.372113000 */, 17 }, /* 3283 */ { MAD_F(0x05f4cb49) /* 0.372264181 */, 17 }, /* 3284 */ { MAD_F(0x05f569d3) /* 0.372415377 */, 17 }, /* 3285 */ { MAD_F(0x05f60862) /* 0.372566589 */, 17 }, /* 3286 */ { MAD_F(0x05f6a6f5) /* 0.372717816 */, 17 }, /* 3287 */ { MAD_F(0x05f7458b) /* 0.372869058 */, 17 }, /* 3288 */ { MAD_F(0x05f7e426) /* 0.373020316 */, 17 }, /* 3289 */ { MAD_F(0x05f882c5) /* 0.373171589 */, 17 }, /* 3290 */ { MAD_F(0x05f92169) /* 0.373322877 */, 17 }, /* 3291 */ { MAD_F(0x05f9c010) /* 0.373474181 */, 17 }, /* 3292 */ { MAD_F(0x05fa5ebb) /* 0.373625500 */, 17 }, /* 3293 */ { MAD_F(0x05fafd6b) /* 0.373776834 */, 17 }, /* 3294 */ { MAD_F(0x05fb9c1e) /* 0.373928184 */, 17 }, /* 3295 */ { MAD_F(0x05fc3ad6) /* 0.374079549 */, 17 }, /* 3296 */ { MAD_F(0x05fcd992) /* 0.374230929 */, 17 }, /* 3297 */ { MAD_F(0x05fd7852) /* 0.374382325 */, 17 }, /* 3298 */ { MAD_F(0x05fe1716) /* 0.374533735 */, 17 }, /* 3299 */ { MAD_F(0x05feb5de) /* 0.374685162 */, 17 }, /* 3300 */ { MAD_F(0x05ff54aa) /* 0.374836603 */, 17 }, /* 3301 */ { MAD_F(0x05fff37b) /* 0.374988060 */, 17 }, /* 3302 */ { MAD_F(0x0600924f) /* 0.375139532 */, 17 }, /* 3303 */ { MAD_F(0x06013128) /* 0.375291019 */, 17 }, /* 3304 */ { MAD_F(0x0601d004) /* 0.375442522 */, 17 }, /* 3305 */ { MAD_F(0x06026ee5) /* 0.375594040 */, 17 }, /* 3306 */ { MAD_F(0x06030dca) /* 0.375745573 */, 17 }, /* 3307 */ { MAD_F(0x0603acb3) /* 0.375897122 */, 17 }, /* 3308 */ { MAD_F(0x06044ba0) /* 0.376048685 */, 17 }, /* 3309 */ { MAD_F(0x0604ea91) /* 0.376200265 */, 17 }, /* 3310 */ { MAD_F(0x06058987) /* 0.376351859 */, 17 }, /* 3311 */ { MAD_F(0x06062880) /* 0.376503468 */, 17 }, /* 3312 */ { MAD_F(0x0606c77d) /* 0.376655093 */, 17 }, /* 3313 */ { MAD_F(0x0607667f) /* 0.376806733 */, 17 }, /* 3314 */ { MAD_F(0x06080585) /* 0.376958389 */, 17 }, /* 3315 */ { MAD_F(0x0608a48f) /* 0.377110059 */, 17 }, /* 3316 */ { MAD_F(0x0609439c) /* 0.377261745 */, 17 }, /* 3317 */ { MAD_F(0x0609e2ae) /* 0.377413446 */, 17 }, /* 3318 */ { MAD_F(0x060a81c4) /* 0.377565163 */, 17 }, /* 3319 */ { MAD_F(0x060b20df) /* 0.377716894 */, 17 }, /* 3320 */ { MAD_F(0x060bbffd) /* 0.377868641 */, 17 }, /* 3321 */ { MAD_F(0x060c5f1f) /* 0.378020403 */, 17 }, /* 3322 */ { MAD_F(0x060cfe46) /* 0.378172181 */, 17 }, /* 3323 */ { MAD_F(0x060d9d70) /* 0.378323973 */, 17 }, /* 3324 */ { MAD_F(0x060e3c9f) /* 0.378475781 */, 17 }, /* 3325 */ { MAD_F(0x060edbd1) /* 0.378627604 */, 17 }, /* 3326 */ { MAD_F(0x060f7b08) /* 0.378779442 */, 17 }, /* 3327 */ { MAD_F(0x06101a43) /* 0.378931296 */, 17 }, /* 3328 */ { MAD_F(0x0610b982) /* 0.379083164 */, 17 }, /* 3329 */ { MAD_F(0x061158c5) /* 0.379235048 */, 17 }, /* 3330 */ { MAD_F(0x0611f80c) /* 0.379386947 */, 17 }, /* 3331 */ { MAD_F(0x06129757) /* 0.379538862 */, 17 }, /* 3332 */ { MAD_F(0x061336a6) /* 0.379690791 */, 17 }, /* 3333 */ { MAD_F(0x0613d5fa) /* 0.379842736 */, 17 }, /* 3334 */ { MAD_F(0x06147551) /* 0.379994696 */, 17 }, /* 3335 */ { MAD_F(0x061514ad) /* 0.380146671 */, 17 }, /* 3336 */ { MAD_F(0x0615b40c) /* 0.380298661 */, 17 }, /* 3337 */ { MAD_F(0x06165370) /* 0.380450666 */, 17 }, /* 3338 */ { MAD_F(0x0616f2d8) /* 0.380602687 */, 17 }, /* 3339 */ { MAD_F(0x06179243) /* 0.380754723 */, 17 }, /* 3340 */ { MAD_F(0x061831b3) /* 0.380906774 */, 17 }, /* 3341 */ { MAD_F(0x0618d127) /* 0.381058840 */, 17 }, /* 3342 */ { MAD_F(0x0619709f) /* 0.381210921 */, 17 }, /* 3343 */ { MAD_F(0x061a101b) /* 0.381363018 */, 17 }, /* 3344 */ { MAD_F(0x061aaf9c) /* 0.381515130 */, 17 }, /* 3345 */ { MAD_F(0x061b4f20) /* 0.381667257 */, 17 }, /* 3346 */ { MAD_F(0x061beea8) /* 0.381819399 */, 17 }, /* 3347 */ { MAD_F(0x061c8e34) /* 0.381971556 */, 17 }, /* 3348 */ { MAD_F(0x061d2dc5) /* 0.382123728 */, 17 }, /* 3349 */ { MAD_F(0x061dcd59) /* 0.382275916 */, 17 }, /* 3350 */ { MAD_F(0x061e6cf2) /* 0.382428118 */, 17 }, /* 3351 */ { MAD_F(0x061f0c8f) /* 0.382580336 */, 17 }, /* 3352 */ { MAD_F(0x061fac2f) /* 0.382732569 */, 17 }, /* 3353 */ { MAD_F(0x06204bd4) /* 0.382884817 */, 17 }, /* 3354 */ { MAD_F(0x0620eb7d) /* 0.383037080 */, 17 }, /* 3355 */ { MAD_F(0x06218b2a) /* 0.383189358 */, 17 }, /* 3356 */ { MAD_F(0x06222adb) /* 0.383341652 */, 17 }, /* 3357 */ { MAD_F(0x0622ca90) /* 0.383493960 */, 17 }, /* 3358 */ { MAD_F(0x06236a49) /* 0.383646284 */, 17 }, /* 3359 */ { MAD_F(0x06240a06) /* 0.383798623 */, 17 }, /* 3360 */ { MAD_F(0x0624a9c7) /* 0.383950977 */, 17 }, /* 3361 */ { MAD_F(0x0625498d) /* 0.384103346 */, 17 }, /* 3362 */ { MAD_F(0x0625e956) /* 0.384255730 */, 17 }, /* 3363 */ { MAD_F(0x06268923) /* 0.384408129 */, 17 }, /* 3364 */ { MAD_F(0x062728f5) /* 0.384560544 */, 17 }, /* 3365 */ { MAD_F(0x0627c8ca) /* 0.384712973 */, 17 }, /* 3366 */ { MAD_F(0x062868a4) /* 0.384865418 */, 17 }, /* 3367 */ { MAD_F(0x06290881) /* 0.385017878 */, 17 }, /* 3368 */ { MAD_F(0x0629a863) /* 0.385170352 */, 17 }, /* 3369 */ { MAD_F(0x062a4849) /* 0.385322842 */, 17 }, /* 3370 */ { MAD_F(0x062ae832) /* 0.385475347 */, 17 }, /* 3371 */ { MAD_F(0x062b8820) /* 0.385627867 */, 17 }, /* 3372 */ { MAD_F(0x062c2812) /* 0.385780402 */, 17 }, /* 3373 */ { MAD_F(0x062cc808) /* 0.385932953 */, 17 }, /* 3374 */ { MAD_F(0x062d6802) /* 0.386085518 */, 17 }, /* 3375 */ { MAD_F(0x062e0800) /* 0.386238098 */, 17 }, /* 3376 */ { MAD_F(0x062ea802) /* 0.386390694 */, 17 }, /* 3377 */ { MAD_F(0x062f4808) /* 0.386543304 */, 17 }, /* 3378 */ { MAD_F(0x062fe812) /* 0.386695930 */, 17 }, /* 3379 */ { MAD_F(0x06308820) /* 0.386848570 */, 17 }, /* 3380 */ { MAD_F(0x06312832) /* 0.387001226 */, 17 }, /* 3381 */ { MAD_F(0x0631c849) /* 0.387153897 */, 17 }, /* 3382 */ { MAD_F(0x06326863) /* 0.387306582 */, 17 }, /* 3383 */ { MAD_F(0x06330881) /* 0.387459283 */, 17 }, /* 3384 */ { MAD_F(0x0633a8a3) /* 0.387611999 */, 17 }, /* 3385 */ { MAD_F(0x063448ca) /* 0.387764730 */, 17 }, /* 3386 */ { MAD_F(0x0634e8f4) /* 0.387917476 */, 17 }, /* 3387 */ { MAD_F(0x06358923) /* 0.388070237 */, 17 }, /* 3388 */ { MAD_F(0x06362955) /* 0.388223013 */, 17 }, /* 3389 */ { MAD_F(0x0636c98c) /* 0.388375804 */, 17 }, /* 3390 */ { MAD_F(0x063769c6) /* 0.388528610 */, 17 }, /* 3391 */ { MAD_F(0x06380a05) /* 0.388681431 */, 17 }, /* 3392 */ { MAD_F(0x0638aa48) /* 0.388834268 */, 17 }, /* 3393 */ { MAD_F(0x06394a8e) /* 0.388987119 */, 17 }, /* 3394 */ { MAD_F(0x0639ead9) /* 0.389139985 */, 17 }, /* 3395 */ { MAD_F(0x063a8b28) /* 0.389292866 */, 17 }, /* 3396 */ { MAD_F(0x063b2b7b) /* 0.389445762 */, 17 }, /* 3397 */ { MAD_F(0x063bcbd1) /* 0.389598674 */, 17 }, /* 3398 */ { MAD_F(0x063c6c2c) /* 0.389751600 */, 17 }, /* 3399 */ { MAD_F(0x063d0c8b) /* 0.389904541 */, 17 }, /* 3400 */ { MAD_F(0x063dacee) /* 0.390057497 */, 17 }, /* 3401 */ { MAD_F(0x063e4d55) /* 0.390210468 */, 17 }, /* 3402 */ { MAD_F(0x063eedc0) /* 0.390363455 */, 17 }, /* 3403 */ { MAD_F(0x063f8e2f) /* 0.390516456 */, 17 }, /* 3404 */ { MAD_F(0x06402ea2) /* 0.390669472 */, 17 }, /* 3405 */ { MAD_F(0x0640cf19) /* 0.390822503 */, 17 }, /* 3406 */ { MAD_F(0x06416f94) /* 0.390975549 */, 17 }, /* 3407 */ { MAD_F(0x06421013) /* 0.391128611 */, 17 }, /* 3408 */ { MAD_F(0x0642b096) /* 0.391281687 */, 17 }, /* 3409 */ { MAD_F(0x0643511d) /* 0.391434778 */, 17 }, /* 3410 */ { MAD_F(0x0643f1a8) /* 0.391587884 */, 17 }, /* 3411 */ { MAD_F(0x06449237) /* 0.391741005 */, 17 }, /* 3412 */ { MAD_F(0x064532ca) /* 0.391894141 */, 17 }, /* 3413 */ { MAD_F(0x0645d361) /* 0.392047292 */, 17 }, /* 3414 */ { MAD_F(0x064673fc) /* 0.392200458 */, 17 }, /* 3415 */ { MAD_F(0x0647149c) /* 0.392353638 */, 17 }, /* 3416 */ { MAD_F(0x0647b53f) /* 0.392506834 */, 17 }, /* 3417 */ { MAD_F(0x064855e6) /* 0.392660045 */, 17 }, /* 3418 */ { MAD_F(0x0648f691) /* 0.392813271 */, 17 }, /* 3419 */ { MAD_F(0x06499740) /* 0.392966511 */, 17 }, /* 3420 */ { MAD_F(0x064a37f4) /* 0.393119767 */, 17 }, /* 3421 */ { MAD_F(0x064ad8ab) /* 0.393273038 */, 17 }, /* 3422 */ { MAD_F(0x064b7966) /* 0.393426323 */, 17 }, /* 3423 */ { MAD_F(0x064c1a25) /* 0.393579623 */, 17 }, /* 3424 */ { MAD_F(0x064cbae9) /* 0.393732939 */, 17 }, /* 3425 */ { MAD_F(0x064d5bb0) /* 0.393886269 */, 17 }, /* 3426 */ { MAD_F(0x064dfc7b) /* 0.394039614 */, 17 }, /* 3427 */ { MAD_F(0x064e9d4b) /* 0.394192974 */, 17 }, /* 3428 */ { MAD_F(0x064f3e1e) /* 0.394346349 */, 17 }, /* 3429 */ { MAD_F(0x064fdef5) /* 0.394499739 */, 17 }, /* 3430 */ { MAD_F(0x06507fd0) /* 0.394653144 */, 17 }, /* 3431 */ { MAD_F(0x065120b0) /* 0.394806564 */, 17 }, /* 3432 */ { MAD_F(0x0651c193) /* 0.394959999 */, 17 }, /* 3433 */ { MAD_F(0x0652627a) /* 0.395113448 */, 17 }, /* 3434 */ { MAD_F(0x06530366) /* 0.395266913 */, 17 }, /* 3435 */ { MAD_F(0x0653a455) /* 0.395420392 */, 17 }, /* 3436 */ { MAD_F(0x06544548) /* 0.395573886 */, 17 }, /* 3437 */ { MAD_F(0x0654e640) /* 0.395727395 */, 17 }, /* 3438 */ { MAD_F(0x0655873b) /* 0.395880919 */, 17 }, /* 3439 */ { MAD_F(0x0656283a) /* 0.396034458 */, 17 }, /* 3440 */ { MAD_F(0x0656c93d) /* 0.396188012 */, 17 }, /* 3441 */ { MAD_F(0x06576a45) /* 0.396341581 */, 17 }, /* 3442 */ { MAD_F(0x06580b50) /* 0.396495164 */, 17 }, /* 3443 */ { MAD_F(0x0658ac5f) /* 0.396648763 */, 17 }, /* 3444 */ { MAD_F(0x06594d73) /* 0.396802376 */, 17 }, /* 3445 */ { MAD_F(0x0659ee8a) /* 0.396956004 */, 17 }, /* 3446 */ { MAD_F(0x065a8fa5) /* 0.397109647 */, 17 }, /* 3447 */ { MAD_F(0x065b30c4) /* 0.397263305 */, 17 }, /* 3448 */ { MAD_F(0x065bd1e7) /* 0.397416978 */, 17 }, /* 3449 */ { MAD_F(0x065c730f) /* 0.397570666 */, 17 }, /* 3450 */ { MAD_F(0x065d143a) /* 0.397724368 */, 17 }, /* 3451 */ { MAD_F(0x065db569) /* 0.397878085 */, 17 }, /* 3452 */ { MAD_F(0x065e569c) /* 0.398031818 */, 17 }, /* 3453 */ { MAD_F(0x065ef7d3) /* 0.398185565 */, 17 }, /* 3454 */ { MAD_F(0x065f990e) /* 0.398339326 */, 17 }, /* 3455 */ { MAD_F(0x06603a4e) /* 0.398493103 */, 17 }, /* 3456 */ { MAD_F(0x0660db91) /* 0.398646895 */, 17 }, /* 3457 */ { MAD_F(0x06617cd8) /* 0.398800701 */, 17 }, /* 3458 */ { MAD_F(0x06621e23) /* 0.398954522 */, 17 }, /* 3459 */ { MAD_F(0x0662bf72) /* 0.399108358 */, 17 }, /* 3460 */ { MAD_F(0x066360c5) /* 0.399262209 */, 17 }, /* 3461 */ { MAD_F(0x0664021c) /* 0.399416075 */, 17 }, /* 3462 */ { MAD_F(0x0664a377) /* 0.399569955 */, 17 }, /* 3463 */ { MAD_F(0x066544d6) /* 0.399723851 */, 17 }, /* 3464 */ { MAD_F(0x0665e639) /* 0.399877761 */, 17 }, /* 3465 */ { MAD_F(0x066687a0) /* 0.400031686 */, 17 }, /* 3466 */ { MAD_F(0x0667290b) /* 0.400185625 */, 17 }, /* 3467 */ { MAD_F(0x0667ca79) /* 0.400339580 */, 17 }, /* 3468 */ { MAD_F(0x06686bec) /* 0.400493549 */, 17 }, /* 3469 */ { MAD_F(0x06690d63) /* 0.400647534 */, 17 }, /* 3470 */ { MAD_F(0x0669aede) /* 0.400801533 */, 17 }, /* 3471 */ { MAD_F(0x066a505d) /* 0.400955546 */, 17 }, /* 3472 */ { MAD_F(0x066af1df) /* 0.401109575 */, 17 }, /* 3473 */ { MAD_F(0x066b9366) /* 0.401263618 */, 17 }, /* 3474 */ { MAD_F(0x066c34f1) /* 0.401417676 */, 17 }, /* 3475 */ { MAD_F(0x066cd67f) /* 0.401571749 */, 17 }, /* 3476 */ { MAD_F(0x066d7812) /* 0.401725837 */, 17 }, /* 3477 */ { MAD_F(0x066e19a9) /* 0.401879939 */, 17 }, /* 3478 */ { MAD_F(0x066ebb43) /* 0.402034056 */, 17 }, /* 3479 */ { MAD_F(0x066f5ce2) /* 0.402188188 */, 17 }, /* 3480 */ { MAD_F(0x066ffe84) /* 0.402342335 */, 17 }, /* 3481 */ { MAD_F(0x0670a02a) /* 0.402496497 */, 17 }, /* 3482 */ { MAD_F(0x067141d5) /* 0.402650673 */, 17 }, /* 3483 */ { MAD_F(0x0671e383) /* 0.402804864 */, 17 }, /* 3484 */ { MAD_F(0x06728535) /* 0.402959070 */, 17 }, /* 3485 */ { MAD_F(0x067326ec) /* 0.403113291 */, 17 }, /* 3486 */ { MAD_F(0x0673c8a6) /* 0.403267526 */, 17 }, /* 3487 */ { MAD_F(0x06746a64) /* 0.403421776 */, 17 }, /* 3488 */ { MAD_F(0x06750c26) /* 0.403576041 */, 17 }, /* 3489 */ { MAD_F(0x0675adec) /* 0.403730320 */, 17 }, /* 3490 */ { MAD_F(0x06764fb6) /* 0.403884615 */, 17 }, /* 3491 */ { MAD_F(0x0676f184) /* 0.404038924 */, 17 }, /* 3492 */ { MAD_F(0x06779356) /* 0.404193247 */, 17 }, /* 3493 */ { MAD_F(0x0678352c) /* 0.404347586 */, 17 }, /* 3494 */ { MAD_F(0x0678d706) /* 0.404501939 */, 17 }, /* 3495 */ { MAD_F(0x067978e4) /* 0.404656307 */, 17 }, /* 3496 */ { MAD_F(0x067a1ac6) /* 0.404810690 */, 17 }, /* 3497 */ { MAD_F(0x067abcac) /* 0.404965087 */, 17 }, /* 3498 */ { MAD_F(0x067b5e95) /* 0.405119499 */, 17 }, /* 3499 */ { MAD_F(0x067c0083) /* 0.405273926 */, 17 }, /* 3500 */ { MAD_F(0x067ca275) /* 0.405428368 */, 17 }, /* 3501 */ { MAD_F(0x067d446a) /* 0.405582824 */, 17 }, /* 3502 */ { MAD_F(0x067de664) /* 0.405737295 */, 17 }, /* 3503 */ { MAD_F(0x067e8861) /* 0.405891781 */, 17 }, /* 3504 */ { MAD_F(0x067f2a62) /* 0.406046281 */, 17 }, /* 3505 */ { MAD_F(0x067fcc68) /* 0.406200796 */, 17 }, /* 3506 */ { MAD_F(0x06806e71) /* 0.406355326 */, 17 }, /* 3507 */ { MAD_F(0x0681107e) /* 0.406509870 */, 17 }, /* 3508 */ { MAD_F(0x0681b28f) /* 0.406664429 */, 17 }, /* 3509 */ { MAD_F(0x068254a4) /* 0.406819003 */, 17 }, /* 3510 */ { MAD_F(0x0682f6bd) /* 0.406973592 */, 17 }, /* 3511 */ { MAD_F(0x068398da) /* 0.407128195 */, 17 }, /* 3512 */ { MAD_F(0x06843afb) /* 0.407282813 */, 17 }, /* 3513 */ { MAD_F(0x0684dd20) /* 0.407437445 */, 17 }, /* 3514 */ { MAD_F(0x06857f49) /* 0.407592093 */, 17 }, /* 3515 */ { MAD_F(0x06862176) /* 0.407746754 */, 17 }, /* 3516 */ { MAD_F(0x0686c3a6) /* 0.407901431 */, 17 }, /* 3517 */ { MAD_F(0x068765db) /* 0.408056122 */, 17 }, /* 3518 */ { MAD_F(0x06880814) /* 0.408210828 */, 17 }, /* 3519 */ { MAD_F(0x0688aa50) /* 0.408365549 */, 17 }, /* 3520 */ { MAD_F(0x06894c90) /* 0.408520284 */, 17 }, /* 3521 */ { MAD_F(0x0689eed5) /* 0.408675034 */, 17 }, /* 3522 */ { MAD_F(0x068a911d) /* 0.408829798 */, 17 }, /* 3523 */ { MAD_F(0x068b3369) /* 0.408984577 */, 17 }, /* 3524 */ { MAD_F(0x068bd5b9) /* 0.409139371 */, 17 }, /* 3525 */ { MAD_F(0x068c780e) /* 0.409294180 */, 17 }, /* 3526 */ { MAD_F(0x068d1a66) /* 0.409449003 */, 17 }, /* 3527 */ { MAD_F(0x068dbcc1) /* 0.409603840 */, 17 }, /* 3528 */ { MAD_F(0x068e5f21) /* 0.409758693 */, 17 }, /* 3529 */ { MAD_F(0x068f0185) /* 0.409913560 */, 17 }, /* 3530 */ { MAD_F(0x068fa3ed) /* 0.410068441 */, 17 }, /* 3531 */ { MAD_F(0x06904658) /* 0.410223338 */, 17 }, /* 3532 */ { MAD_F(0x0690e8c8) /* 0.410378249 */, 17 }, /* 3533 */ { MAD_F(0x06918b3c) /* 0.410533174 */, 17 }, /* 3534 */ { MAD_F(0x06922db3) /* 0.410688114 */, 17 }, /* 3535 */ { MAD_F(0x0692d02e) /* 0.410843069 */, 17 }, /* 3536 */ { MAD_F(0x069372ae) /* 0.410998038 */, 17 }, /* 3537 */ { MAD_F(0x06941531) /* 0.411153022 */, 17 }, /* 3538 */ { MAD_F(0x0694b7b8) /* 0.411308021 */, 17 }, /* 3539 */ { MAD_F(0x06955a43) /* 0.411463034 */, 17 }, /* 3540 */ { MAD_F(0x0695fcd2) /* 0.411618062 */, 17 }, /* 3541 */ { MAD_F(0x06969f65) /* 0.411773104 */, 17 }, /* 3542 */ { MAD_F(0x069741fb) /* 0.411928161 */, 17 }, /* 3543 */ { MAD_F(0x0697e496) /* 0.412083232 */, 17 }, /* 3544 */ { MAD_F(0x06988735) /* 0.412238319 */, 17 }, /* 3545 */ { MAD_F(0x069929d7) /* 0.412393419 */, 17 }, /* 3546 */ { MAD_F(0x0699cc7e) /* 0.412548535 */, 17 }, /* 3547 */ { MAD_F(0x069a6f28) /* 0.412703664 */, 17 }, /* 3548 */ { MAD_F(0x069b11d6) /* 0.412858809 */, 17 }, /* 3549 */ { MAD_F(0x069bb489) /* 0.413013968 */, 17 }, /* 3550 */ { MAD_F(0x069c573f) /* 0.413169142 */, 17 }, /* 3551 */ { MAD_F(0x069cf9f9) /* 0.413324330 */, 17 }, /* 3552 */ { MAD_F(0x069d9cb7) /* 0.413479532 */, 17 }, /* 3553 */ { MAD_F(0x069e3f78) /* 0.413634750 */, 17 }, /* 3554 */ { MAD_F(0x069ee23e) /* 0.413789982 */, 17 }, /* 3555 */ { MAD_F(0x069f8508) /* 0.413945228 */, 17 }, /* 3556 */ { MAD_F(0x06a027d5) /* 0.414100489 */, 17 }, /* 3557 */ { MAD_F(0x06a0caa7) /* 0.414255765 */, 17 }, /* 3558 */ { MAD_F(0x06a16d7c) /* 0.414411055 */, 17 }, /* 3559 */ { MAD_F(0x06a21055) /* 0.414566359 */, 17 }, /* 3560 */ { MAD_F(0x06a2b333) /* 0.414721679 */, 17 }, /* 3561 */ { MAD_F(0x06a35614) /* 0.414877012 */, 17 }, /* 3562 */ { MAD_F(0x06a3f8f9) /* 0.415032361 */, 17 }, /* 3563 */ { MAD_F(0x06a49be2) /* 0.415187723 */, 17 }, /* 3564 */ { MAD_F(0x06a53ece) /* 0.415343101 */, 17 }, /* 3565 */ { MAD_F(0x06a5e1bf) /* 0.415498493 */, 17 }, /* 3566 */ { MAD_F(0x06a684b4) /* 0.415653899 */, 17 }, /* 3567 */ { MAD_F(0x06a727ac) /* 0.415809320 */, 17 }, /* 3568 */ { MAD_F(0x06a7caa9) /* 0.415964756 */, 17 }, /* 3569 */ { MAD_F(0x06a86da9) /* 0.416120206 */, 17 }, /* 3570 */ { MAD_F(0x06a910ad) /* 0.416275670 */, 17 }, /* 3571 */ { MAD_F(0x06a9b3b5) /* 0.416431149 */, 17 }, /* 3572 */ { MAD_F(0x06aa56c1) /* 0.416586643 */, 17 }, /* 3573 */ { MAD_F(0x06aaf9d1) /* 0.416742151 */, 17 }, /* 3574 */ { MAD_F(0x06ab9ce5) /* 0.416897673 */, 17 }, /* 3575 */ { MAD_F(0x06ac3ffc) /* 0.417053210 */, 17 }, /* 3576 */ { MAD_F(0x06ace318) /* 0.417208762 */, 17 }, /* 3577 */ { MAD_F(0x06ad8637) /* 0.417364328 */, 17 }, /* 3578 */ { MAD_F(0x06ae295b) /* 0.417519909 */, 17 }, /* 3579 */ { MAD_F(0x06aecc82) /* 0.417675504 */, 17 }, /* 3580 */ { MAD_F(0x06af6fad) /* 0.417831113 */, 17 }, /* 3581 */ { MAD_F(0x06b012dc) /* 0.417986737 */, 17 }, /* 3582 */ { MAD_F(0x06b0b60f) /* 0.418142376 */, 17 }, /* 3583 */ { MAD_F(0x06b15946) /* 0.418298029 */, 17 }, /* 3584 */ { MAD_F(0x06b1fc81) /* 0.418453696 */, 17 }, /* 3585 */ { MAD_F(0x06b29fbf) /* 0.418609378 */, 17 }, /* 3586 */ { MAD_F(0x06b34302) /* 0.418765075 */, 17 }, /* 3587 */ { MAD_F(0x06b3e648) /* 0.418920786 */, 17 }, /* 3588 */ { MAD_F(0x06b48992) /* 0.419076511 */, 17 }, /* 3589 */ { MAD_F(0x06b52ce0) /* 0.419232251 */, 17 }, /* 3590 */ { MAD_F(0x06b5d032) /* 0.419388005 */, 17 }, /* 3591 */ { MAD_F(0x06b67388) /* 0.419543774 */, 17 }, /* 3592 */ { MAD_F(0x06b716e2) /* 0.419699557 */, 17 }, /* 3593 */ { MAD_F(0x06b7ba3f) /* 0.419855355 */, 17 }, /* 3594 */ { MAD_F(0x06b85da1) /* 0.420011167 */, 17 }, /* 3595 */ { MAD_F(0x06b90106) /* 0.420166994 */, 17 }, /* 3596 */ { MAD_F(0x06b9a470) /* 0.420322835 */, 17 }, /* 3597 */ { MAD_F(0x06ba47dd) /* 0.420478690 */, 17 }, /* 3598 */ { MAD_F(0x06baeb4e) /* 0.420634560 */, 17 }, /* 3599 */ { MAD_F(0x06bb8ec3) /* 0.420790445 */, 17 }, /* 3600 */ { MAD_F(0x06bc323b) /* 0.420946343 */, 17 }, /* 3601 */ { MAD_F(0x06bcd5b8) /* 0.421102257 */, 17 }, /* 3602 */ { MAD_F(0x06bd7939) /* 0.421258184 */, 17 }, /* 3603 */ { MAD_F(0x06be1cbd) /* 0.421414127 */, 17 }, /* 3604 */ { MAD_F(0x06bec045) /* 0.421570083 */, 17 }, /* 3605 */ { MAD_F(0x06bf63d1) /* 0.421726054 */, 17 }, /* 3606 */ { MAD_F(0x06c00761) /* 0.421882040 */, 17 }, /* 3607 */ { MAD_F(0x06c0aaf5) /* 0.422038039 */, 17 }, /* 3608 */ { MAD_F(0x06c14e8d) /* 0.422194054 */, 17 }, /* 3609 */ { MAD_F(0x06c1f229) /* 0.422350082 */, 17 }, /* 3610 */ { MAD_F(0x06c295c8) /* 0.422506125 */, 17 }, /* 3611 */ { MAD_F(0x06c3396c) /* 0.422662183 */, 17 }, /* 3612 */ { MAD_F(0x06c3dd13) /* 0.422818255 */, 17 }, /* 3613 */ { MAD_F(0x06c480be) /* 0.422974341 */, 17 }, /* 3614 */ { MAD_F(0x06c5246d) /* 0.423130442 */, 17 }, /* 3615 */ { MAD_F(0x06c5c820) /* 0.423286557 */, 17 }, /* 3616 */ { MAD_F(0x06c66bd6) /* 0.423442686 */, 17 }, /* 3617 */ { MAD_F(0x06c70f91) /* 0.423598830 */, 17 }, /* 3618 */ { MAD_F(0x06c7b34f) /* 0.423754988 */, 17 }, /* 3619 */ { MAD_F(0x06c85712) /* 0.423911161 */, 17 }, /* 3620 */ { MAD_F(0x06c8fad8) /* 0.424067348 */, 17 }, /* 3621 */ { MAD_F(0x06c99ea2) /* 0.424223550 */, 17 }, /* 3622 */ { MAD_F(0x06ca4270) /* 0.424379765 */, 17 }, /* 3623 */ { MAD_F(0x06cae641) /* 0.424535996 */, 17 }, /* 3624 */ { MAD_F(0x06cb8a17) /* 0.424692240 */, 17 }, /* 3625 */ { MAD_F(0x06cc2df0) /* 0.424848499 */, 17 }, /* 3626 */ { MAD_F(0x06ccd1ce) /* 0.425004772 */, 17 }, /* 3627 */ { MAD_F(0x06cd75af) /* 0.425161060 */, 17 }, /* 3628 */ { MAD_F(0x06ce1994) /* 0.425317362 */, 17 }, /* 3629 */ { MAD_F(0x06cebd7d) /* 0.425473678 */, 17 }, /* 3630 */ { MAD_F(0x06cf6169) /* 0.425630009 */, 17 }, /* 3631 */ { MAD_F(0x06d0055a) /* 0.425786354 */, 17 }, /* 3632 */ { MAD_F(0x06d0a94e) /* 0.425942714 */, 17 }, /* 3633 */ { MAD_F(0x06d14d47) /* 0.426099088 */, 17 }, /* 3634 */ { MAD_F(0x06d1f143) /* 0.426255476 */, 17 }, /* 3635 */ { MAD_F(0x06d29543) /* 0.426411878 */, 17 }, /* 3636 */ { MAD_F(0x06d33947) /* 0.426568295 */, 17 }, /* 3637 */ { MAD_F(0x06d3dd4e) /* 0.426724726 */, 17 }, /* 3638 */ { MAD_F(0x06d4815a) /* 0.426881172 */, 17 }, /* 3639 */ { MAD_F(0x06d52569) /* 0.427037632 */, 17 }, /* 3640 */ { MAD_F(0x06d5c97c) /* 0.427194106 */, 17 }, /* 3641 */ { MAD_F(0x06d66d93) /* 0.427350594 */, 17 }, /* 3642 */ { MAD_F(0x06d711ae) /* 0.427507097 */, 17 }, /* 3643 */ { MAD_F(0x06d7b5cd) /* 0.427663614 */, 17 }, /* 3644 */ { MAD_F(0x06d859f0) /* 0.427820146 */, 17 }, /* 3645 */ { MAD_F(0x06d8fe16) /* 0.427976692 */, 17 }, /* 3646 */ { MAD_F(0x06d9a240) /* 0.428133252 */, 17 }, /* 3647 */ { MAD_F(0x06da466f) /* 0.428289826 */, 17 }, /* 3648 */ { MAD_F(0x06daeaa1) /* 0.428446415 */, 17 }, /* 3649 */ { MAD_F(0x06db8ed6) /* 0.428603018 */, 17 }, /* 3650 */ { MAD_F(0x06dc3310) /* 0.428759635 */, 17 }, /* 3651 */ { MAD_F(0x06dcd74d) /* 0.428916267 */, 17 }, /* 3652 */ { MAD_F(0x06dd7b8f) /* 0.429072913 */, 17 }, /* 3653 */ { MAD_F(0x06de1fd4) /* 0.429229573 */, 17 }, /* 3654 */ { MAD_F(0x06dec41d) /* 0.429386248 */, 17 }, /* 3655 */ { MAD_F(0x06df686a) /* 0.429542937 */, 17 }, /* 3656 */ { MAD_F(0x06e00cbb) /* 0.429699640 */, 17 }, /* 3657 */ { MAD_F(0x06e0b10f) /* 0.429856357 */, 17 }, /* 3658 */ { MAD_F(0x06e15567) /* 0.430013089 */, 17 }, /* 3659 */ { MAD_F(0x06e1f9c4) /* 0.430169835 */, 17 }, /* 3660 */ { MAD_F(0x06e29e24) /* 0.430326595 */, 17 }, /* 3661 */ { MAD_F(0x06e34287) /* 0.430483370 */, 17 }, /* 3662 */ { MAD_F(0x06e3e6ef) /* 0.430640159 */, 17 }, /* 3663 */ { MAD_F(0x06e48b5b) /* 0.430796962 */, 17 }, /* 3664 */ { MAD_F(0x06e52fca) /* 0.430953779 */, 17 }, /* 3665 */ { MAD_F(0x06e5d43d) /* 0.431110611 */, 17 }, /* 3666 */ { MAD_F(0x06e678b4) /* 0.431267457 */, 17 }, /* 3667 */ { MAD_F(0x06e71d2f) /* 0.431424317 */, 17 }, /* 3668 */ { MAD_F(0x06e7c1ae) /* 0.431581192 */, 17 }, /* 3669 */ { MAD_F(0x06e86630) /* 0.431738080 */, 17 }, /* 3670 */ { MAD_F(0x06e90ab7) /* 0.431894983 */, 17 }, /* 3671 */ { MAD_F(0x06e9af41) /* 0.432051900 */, 17 }, /* 3672 */ { MAD_F(0x06ea53cf) /* 0.432208832 */, 17 }, /* 3673 */ { MAD_F(0x06eaf860) /* 0.432365778 */, 17 }, /* 3674 */ { MAD_F(0x06eb9cf6) /* 0.432522737 */, 17 }, /* 3675 */ { MAD_F(0x06ec418f) /* 0.432679712 */, 17 }, /* 3676 */ { MAD_F(0x06ece62d) /* 0.432836700 */, 17 }, /* 3677 */ { MAD_F(0x06ed8ace) /* 0.432993703 */, 17 }, /* 3678 */ { MAD_F(0x06ee2f73) /* 0.433150720 */, 17 }, /* 3679 */ { MAD_F(0x06eed41b) /* 0.433307751 */, 17 }, /* 3680 */ { MAD_F(0x06ef78c8) /* 0.433464796 */, 17 }, /* 3681 */ { MAD_F(0x06f01d78) /* 0.433621856 */, 17 }, /* 3682 */ { MAD_F(0x06f0c22c) /* 0.433778929 */, 17 }, /* 3683 */ { MAD_F(0x06f166e4) /* 0.433936017 */, 17 }, /* 3684 */ { MAD_F(0x06f20ba0) /* 0.434093120 */, 17 }, /* 3685 */ { MAD_F(0x06f2b060) /* 0.434250236 */, 17 }, /* 3686 */ { MAD_F(0x06f35523) /* 0.434407367 */, 17 }, /* 3687 */ { MAD_F(0x06f3f9eb) /* 0.434564512 */, 17 }, /* 3688 */ { MAD_F(0x06f49eb6) /* 0.434721671 */, 17 }, /* 3689 */ { MAD_F(0x06f54385) /* 0.434878844 */, 17 }, /* 3690 */ { MAD_F(0x06f5e857) /* 0.435036032 */, 17 }, /* 3691 */ { MAD_F(0x06f68d2e) /* 0.435193233 */, 17 }, /* 3692 */ { MAD_F(0x06f73208) /* 0.435350449 */, 17 }, /* 3693 */ { MAD_F(0x06f7d6e6) /* 0.435507679 */, 17 }, /* 3694 */ { MAD_F(0x06f87bc8) /* 0.435664924 */, 17 }, /* 3695 */ { MAD_F(0x06f920ae) /* 0.435822182 */, 17 }, /* 3696 */ { MAD_F(0x06f9c597) /* 0.435979455 */, 17 }, /* 3697 */ { MAD_F(0x06fa6a85) /* 0.436136741 */, 17 }, /* 3698 */ { MAD_F(0x06fb0f76) /* 0.436294042 */, 17 }, /* 3699 */ { MAD_F(0x06fbb46b) /* 0.436451358 */, 17 }, /* 3700 */ { MAD_F(0x06fc5964) /* 0.436608687 */, 17 }, /* 3701 */ { MAD_F(0x06fcfe60) /* 0.436766031 */, 17 }, /* 3702 */ { MAD_F(0x06fda361) /* 0.436923388 */, 17 }, /* 3703 */ { MAD_F(0x06fe4865) /* 0.437080760 */, 17 }, /* 3704 */ { MAD_F(0x06feed6d) /* 0.437238146 */, 17 }, /* 3705 */ { MAD_F(0x06ff9279) /* 0.437395547 */, 17 }, /* 3706 */ { MAD_F(0x07003788) /* 0.437552961 */, 17 }, /* 3707 */ { MAD_F(0x0700dc9c) /* 0.437710389 */, 17 }, /* 3708 */ { MAD_F(0x070181b3) /* 0.437867832 */, 17 }, /* 3709 */ { MAD_F(0x070226ce) /* 0.438025289 */, 17 }, /* 3710 */ { MAD_F(0x0702cbed) /* 0.438182760 */, 17 }, /* 3711 */ { MAD_F(0x0703710f) /* 0.438340245 */, 17 }, /* 3712 */ { MAD_F(0x07041636) /* 0.438497744 */, 17 }, /* 3713 */ { MAD_F(0x0704bb60) /* 0.438655258 */, 17 }, /* 3714 */ { MAD_F(0x0705608e) /* 0.438812785 */, 17 }, /* 3715 */ { MAD_F(0x070605c0) /* 0.438970327 */, 17 }, /* 3716 */ { MAD_F(0x0706aaf5) /* 0.439127883 */, 17 }, /* 3717 */ { MAD_F(0x0707502f) /* 0.439285453 */, 17 }, /* 3718 */ { MAD_F(0x0707f56c) /* 0.439443037 */, 17 }, /* 3719 */ { MAD_F(0x07089aad) /* 0.439600635 */, 17 }, /* 3720 */ { MAD_F(0x07093ff2) /* 0.439758248 */, 17 }, /* 3721 */ { MAD_F(0x0709e53a) /* 0.439915874 */, 17 }, /* 3722 */ { MAD_F(0x070a8a86) /* 0.440073515 */, 17 }, /* 3723 */ { MAD_F(0x070b2fd7) /* 0.440231170 */, 17 }, /* 3724 */ { MAD_F(0x070bd52a) /* 0.440388839 */, 17 }, /* 3725 */ { MAD_F(0x070c7a82) /* 0.440546522 */, 17 }, /* 3726 */ { MAD_F(0x070d1fde) /* 0.440704219 */, 17 }, /* 3727 */ { MAD_F(0x070dc53d) /* 0.440861930 */, 17 }, /* 3728 */ { MAD_F(0x070e6aa0) /* 0.441019655 */, 17 }, /* 3729 */ { MAD_F(0x070f1007) /* 0.441177395 */, 17 }, /* 3730 */ { MAD_F(0x070fb571) /* 0.441335148 */, 17 }, /* 3731 */ { MAD_F(0x07105ae0) /* 0.441492916 */, 17 }, /* 3732 */ { MAD_F(0x07110052) /* 0.441650697 */, 17 }, /* 3733 */ { MAD_F(0x0711a5c8) /* 0.441808493 */, 17 }, /* 3734 */ { MAD_F(0x07124b42) /* 0.441966303 */, 17 }, /* 3735 */ { MAD_F(0x0712f0bf) /* 0.442124127 */, 17 }, /* 3736 */ { MAD_F(0x07139641) /* 0.442281965 */, 17 }, /* 3737 */ { MAD_F(0x07143bc6) /* 0.442439817 */, 17 }, /* 3738 */ { MAD_F(0x0714e14f) /* 0.442597683 */, 17 }, /* 3739 */ { MAD_F(0x071586db) /* 0.442755564 */, 17 }, /* 3740 */ { MAD_F(0x07162c6c) /* 0.442913458 */, 17 }, /* 3741 */ { MAD_F(0x0716d200) /* 0.443071366 */, 17 }, /* 3742 */ { MAD_F(0x07177798) /* 0.443229289 */, 17 }, /* 3743 */ { MAD_F(0x07181d34) /* 0.443387226 */, 17 }, /* 3744 */ { MAD_F(0x0718c2d3) /* 0.443545176 */, 17 }, /* 3745 */ { MAD_F(0x07196877) /* 0.443703141 */, 17 }, /* 3746 */ { MAD_F(0x071a0e1e) /* 0.443861120 */, 17 }, /* 3747 */ { MAD_F(0x071ab3c9) /* 0.444019113 */, 17 }, /* 3748 */ { MAD_F(0x071b5977) /* 0.444177119 */, 17 }, /* 3749 */ { MAD_F(0x071bff2a) /* 0.444335140 */, 17 }, /* 3750 */ { MAD_F(0x071ca4e0) /* 0.444493175 */, 17 }, /* 3751 */ { MAD_F(0x071d4a9a) /* 0.444651224 */, 17 }, /* 3752 */ { MAD_F(0x071df058) /* 0.444809288 */, 17 }, /* 3753 */ { MAD_F(0x071e9619) /* 0.444967365 */, 17 }, /* 3754 */ { MAD_F(0x071f3bde) /* 0.445125456 */, 17 }, /* 3755 */ { MAD_F(0x071fe1a8) /* 0.445283561 */, 17 }, /* 3756 */ { MAD_F(0x07208774) /* 0.445441680 */, 17 }, /* 3757 */ { MAD_F(0x07212d45) /* 0.445599814 */, 17 }, /* 3758 */ { MAD_F(0x0721d319) /* 0.445757961 */, 17 }, /* 3759 */ { MAD_F(0x072278f1) /* 0.445916122 */, 17 }, /* 3760 */ { MAD_F(0x07231ecd) /* 0.446074298 */, 17 }, /* 3761 */ { MAD_F(0x0723c4ad) /* 0.446232487 */, 17 }, /* 3762 */ { MAD_F(0x07246a90) /* 0.446390690 */, 17 }, /* 3763 */ { MAD_F(0x07251077) /* 0.446548908 */, 17 }, /* 3764 */ { MAD_F(0x0725b662) /* 0.446707139 */, 17 }, /* 3765 */ { MAD_F(0x07265c51) /* 0.446865385 */, 17 }, /* 3766 */ { MAD_F(0x07270244) /* 0.447023644 */, 17 }, /* 3767 */ { MAD_F(0x0727a83a) /* 0.447181918 */, 17 }, /* 3768 */ { MAD_F(0x07284e34) /* 0.447340205 */, 17 }, /* 3769 */ { MAD_F(0x0728f431) /* 0.447498507 */, 17 }, /* 3770 */ { MAD_F(0x07299a33) /* 0.447656822 */, 17 }, /* 3771 */ { MAD_F(0x072a4038) /* 0.447815152 */, 17 }, /* 3772 */ { MAD_F(0x072ae641) /* 0.447973495 */, 17 }, /* 3773 */ { MAD_F(0x072b8c4e) /* 0.448131853 */, 17 }, /* 3774 */ { MAD_F(0x072c325e) /* 0.448290224 */, 17 }, /* 3775 */ { MAD_F(0x072cd873) /* 0.448448609 */, 17 }, /* 3776 */ { MAD_F(0x072d7e8b) /* 0.448607009 */, 17 }, /* 3777 */ { MAD_F(0x072e24a7) /* 0.448765422 */, 17 }, /* 3778 */ { MAD_F(0x072ecac6) /* 0.448923850 */, 17 }, /* 3779 */ { MAD_F(0x072f70e9) /* 0.449082291 */, 17 }, /* 3780 */ { MAD_F(0x07301710) /* 0.449240746 */, 17 }, /* 3781 */ { MAD_F(0x0730bd3b) /* 0.449399216 */, 17 }, /* 3782 */ { MAD_F(0x0731636a) /* 0.449557699 */, 17 }, /* 3783 */ { MAD_F(0x0732099c) /* 0.449716196 */, 17 }, /* 3784 */ { MAD_F(0x0732afd2) /* 0.449874708 */, 17 }, /* 3785 */ { MAD_F(0x0733560c) /* 0.450033233 */, 17 }, /* 3786 */ { MAD_F(0x0733fc49) /* 0.450191772 */, 17 }, /* 3787 */ { MAD_F(0x0734a28b) /* 0.450350325 */, 17 }, /* 3788 */ { MAD_F(0x073548d0) /* 0.450508892 */, 17 }, /* 3789 */ { MAD_F(0x0735ef18) /* 0.450667473 */, 17 }, /* 3790 */ { MAD_F(0x07369565) /* 0.450826068 */, 17 }, /* 3791 */ { MAD_F(0x07373bb5) /* 0.450984677 */, 17 }, /* 3792 */ { MAD_F(0x0737e209) /* 0.451143300 */, 17 }, /* 3793 */ { MAD_F(0x07388861) /* 0.451301937 */, 17 }, /* 3794 */ { MAD_F(0x07392ebc) /* 0.451460588 */, 17 }, /* 3795 */ { MAD_F(0x0739d51c) /* 0.451619252 */, 17 }, /* 3796 */ { MAD_F(0x073a7b7f) /* 0.451777931 */, 17 }, /* 3797 */ { MAD_F(0x073b21e5) /* 0.451936623 */, 17 }, /* 3798 */ { MAD_F(0x073bc850) /* 0.452095330 */, 17 }, /* 3799 */ { MAD_F(0x073c6ebe) /* 0.452254050 */, 17 }, /* 3800 */ { MAD_F(0x073d1530) /* 0.452412785 */, 17 }, /* 3801 */ { MAD_F(0x073dbba6) /* 0.452571533 */, 17 }, /* 3802 */ { MAD_F(0x073e621f) /* 0.452730295 */, 17 }, /* 3803 */ { MAD_F(0x073f089c) /* 0.452889071 */, 17 }, /* 3804 */ { MAD_F(0x073faf1d) /* 0.453047861 */, 17 }, /* 3805 */ { MAD_F(0x074055a2) /* 0.453206665 */, 17 }, /* 3806 */ { MAD_F(0x0740fc2a) /* 0.453365483 */, 17 }, /* 3807 */ { MAD_F(0x0741a2b6) /* 0.453524315 */, 17 }, /* 3808 */ { MAD_F(0x07424946) /* 0.453683161 */, 17 }, /* 3809 */ { MAD_F(0x0742efd9) /* 0.453842020 */, 17 }, /* 3810 */ { MAD_F(0x07439671) /* 0.454000894 */, 17 }, /* 3811 */ { MAD_F(0x07443d0c) /* 0.454159781 */, 17 }, /* 3812 */ { MAD_F(0x0744e3aa) /* 0.454318683 */, 17 }, /* 3813 */ { MAD_F(0x07458a4d) /* 0.454477598 */, 17 }, /* 3814 */ { MAD_F(0x074630f3) /* 0.454636527 */, 17 }, /* 3815 */ { MAD_F(0x0746d79d) /* 0.454795470 */, 17 }, /* 3816 */ { MAD_F(0x07477e4b) /* 0.454954427 */, 17 }, /* 3817 */ { MAD_F(0x074824fc) /* 0.455113397 */, 17 }, /* 3818 */ { MAD_F(0x0748cbb1) /* 0.455272382 */, 17 }, /* 3819 */ { MAD_F(0x0749726a) /* 0.455431381 */, 17 }, /* 3820 */ { MAD_F(0x074a1927) /* 0.455590393 */, 17 }, /* 3821 */ { MAD_F(0x074abfe7) /* 0.455749419 */, 17 }, /* 3822 */ { MAD_F(0x074b66ab) /* 0.455908459 */, 17 }, /* 3823 */ { MAD_F(0x074c0d73) /* 0.456067513 */, 17 }, /* 3824 */ { MAD_F(0x074cb43e) /* 0.456226581 */, 17 }, /* 3825 */ { MAD_F(0x074d5b0d) /* 0.456385663 */, 17 }, /* 3826 */ { MAD_F(0x074e01e0) /* 0.456544759 */, 17 }, /* 3827 */ { MAD_F(0x074ea8b7) /* 0.456703868 */, 17 }, /* 3828 */ { MAD_F(0x074f4f91) /* 0.456862992 */, 17 }, /* 3829 */ { MAD_F(0x074ff66f) /* 0.457022129 */, 17 }, /* 3830 */ { MAD_F(0x07509d51) /* 0.457181280 */, 17 }, /* 3831 */ { MAD_F(0x07514437) /* 0.457340445 */, 17 }, /* 3832 */ { MAD_F(0x0751eb20) /* 0.457499623 */, 17 }, /* 3833 */ { MAD_F(0x0752920d) /* 0.457658816 */, 17 }, /* 3834 */ { MAD_F(0x075338fd) /* 0.457818022 */, 17 }, /* 3835 */ { MAD_F(0x0753dff2) /* 0.457977243 */, 17 }, /* 3836 */ { MAD_F(0x075486ea) /* 0.458136477 */, 17 }, /* 3837 */ { MAD_F(0x07552de6) /* 0.458295725 */, 17 }, /* 3838 */ { MAD_F(0x0755d4e5) /* 0.458454987 */, 17 }, /* 3839 */ { MAD_F(0x07567be8) /* 0.458614262 */, 17 }, /* 3840 */ { MAD_F(0x075722ef) /* 0.458773552 */, 17 }, /* 3841 */ { MAD_F(0x0757c9fa) /* 0.458932855 */, 17 }, /* 3842 */ { MAD_F(0x07587108) /* 0.459092172 */, 17 }, /* 3843 */ { MAD_F(0x0759181a) /* 0.459251503 */, 17 }, /* 3844 */ { MAD_F(0x0759bf30) /* 0.459410848 */, 17 }, /* 3845 */ { MAD_F(0x075a664a) /* 0.459570206 */, 17 }, /* 3846 */ { MAD_F(0x075b0d67) /* 0.459729579 */, 17 }, /* 3847 */ { MAD_F(0x075bb488) /* 0.459888965 */, 17 }, /* 3848 */ { MAD_F(0x075c5bac) /* 0.460048365 */, 17 }, /* 3849 */ { MAD_F(0x075d02d5) /* 0.460207779 */, 17 }, /* 3850 */ { MAD_F(0x075daa01) /* 0.460367206 */, 17 }, /* 3851 */ { MAD_F(0x075e5130) /* 0.460526648 */, 17 }, /* 3852 */ { MAD_F(0x075ef864) /* 0.460686103 */, 17 }, /* 3853 */ { MAD_F(0x075f9f9b) /* 0.460845572 */, 17 }, /* 3854 */ { MAD_F(0x076046d6) /* 0.461005055 */, 17 }, /* 3855 */ { MAD_F(0x0760ee14) /* 0.461164552 */, 17 }, /* 3856 */ { MAD_F(0x07619557) /* 0.461324062 */, 17 }, /* 3857 */ { MAD_F(0x07623c9d) /* 0.461483586 */, 17 }, /* 3858 */ { MAD_F(0x0762e3e6) /* 0.461643124 */, 17 }, /* 3859 */ { MAD_F(0x07638b34) /* 0.461802676 */, 17 }, /* 3860 */ { MAD_F(0x07643285) /* 0.461962242 */, 17 }, /* 3861 */ { MAD_F(0x0764d9d9) /* 0.462121821 */, 17 }, /* 3862 */ { MAD_F(0x07658132) /* 0.462281414 */, 17 }, /* 3863 */ { MAD_F(0x0766288e) /* 0.462441021 */, 17 }, /* 3864 */ { MAD_F(0x0766cfee) /* 0.462600642 */, 17 }, /* 3865 */ { MAD_F(0x07677751) /* 0.462760276 */, 17 }, /* 3866 */ { MAD_F(0x07681eb9) /* 0.462919924 */, 17 }, /* 3867 */ { MAD_F(0x0768c624) /* 0.463079586 */, 17 }, /* 3868 */ { MAD_F(0x07696d92) /* 0.463239262 */, 17 }, /* 3869 */ { MAD_F(0x076a1505) /* 0.463398951 */, 17 }, /* 3870 */ { MAD_F(0x076abc7b) /* 0.463558655 */, 17 }, /* 3871 */ { MAD_F(0x076b63f4) /* 0.463718372 */, 17 }, /* 3872 */ { MAD_F(0x076c0b72) /* 0.463878102 */, 17 }, /* 3873 */ { MAD_F(0x076cb2f3) /* 0.464037847 */, 17 }, /* 3874 */ { MAD_F(0x076d5a78) /* 0.464197605 */, 17 }, /* 3875 */ { MAD_F(0x076e0200) /* 0.464357377 */, 17 }, /* 3876 */ { MAD_F(0x076ea98c) /* 0.464517163 */, 17 }, /* 3877 */ { MAD_F(0x076f511c) /* 0.464676962 */, 17 }, /* 3878 */ { MAD_F(0x076ff8b0) /* 0.464836776 */, 17 }, /* 3879 */ { MAD_F(0x0770a047) /* 0.464996603 */, 17 }, /* 3880 */ { MAD_F(0x077147e2) /* 0.465156443 */, 17 }, /* 3881 */ { MAD_F(0x0771ef80) /* 0.465316298 */, 17 }, /* 3882 */ { MAD_F(0x07729723) /* 0.465476166 */, 17 }, /* 3883 */ { MAD_F(0x07733ec9) /* 0.465636048 */, 17 }, /* 3884 */ { MAD_F(0x0773e672) /* 0.465795943 */, 17 }, /* 3885 */ { MAD_F(0x07748e20) /* 0.465955853 */, 17 }, /* 3886 */ { MAD_F(0x077535d1) /* 0.466115776 */, 17 }, /* 3887 */ { MAD_F(0x0775dd85) /* 0.466275713 */, 17 }, /* 3888 */ { MAD_F(0x0776853e) /* 0.466435663 */, 17 }, /* 3889 */ { MAD_F(0x07772cfa) /* 0.466595627 */, 17 }, /* 3890 */ { MAD_F(0x0777d4ba) /* 0.466755605 */, 17 }, /* 3891 */ { MAD_F(0x07787c7d) /* 0.466915597 */, 17 }, /* 3892 */ { MAD_F(0x07792444) /* 0.467075602 */, 17 }, /* 3893 */ { MAD_F(0x0779cc0f) /* 0.467235621 */, 17 }, /* 3894 */ { MAD_F(0x077a73dd) /* 0.467395654 */, 17 }, /* 3895 */ { MAD_F(0x077b1baf) /* 0.467555701 */, 17 }, /* 3896 */ { MAD_F(0x077bc385) /* 0.467715761 */, 17 }, /* 3897 */ { MAD_F(0x077c6b5f) /* 0.467875835 */, 17 }, /* 3898 */ { MAD_F(0x077d133c) /* 0.468035922 */, 17 }, /* 3899 */ { MAD_F(0x077dbb1d) /* 0.468196023 */, 17 }, /* 3900 */ { MAD_F(0x077e6301) /* 0.468356138 */, 17 }, /* 3901 */ { MAD_F(0x077f0ae9) /* 0.468516267 */, 17 }, /* 3902 */ { MAD_F(0x077fb2d5) /* 0.468676409 */, 17 }, /* 3903 */ { MAD_F(0x07805ac5) /* 0.468836565 */, 17 }, /* 3904 */ { MAD_F(0x078102b8) /* 0.468996735 */, 17 }, /* 3905 */ { MAD_F(0x0781aaaf) /* 0.469156918 */, 17 }, /* 3906 */ { MAD_F(0x078252aa) /* 0.469317115 */, 17 }, /* 3907 */ { MAD_F(0x0782faa8) /* 0.469477326 */, 17 }, /* 3908 */ { MAD_F(0x0783a2aa) /* 0.469637550 */, 17 }, /* 3909 */ { MAD_F(0x07844aaf) /* 0.469797788 */, 17 }, /* 3910 */ { MAD_F(0x0784f2b8) /* 0.469958040 */, 17 }, /* 3911 */ { MAD_F(0x07859ac5) /* 0.470118305 */, 17 }, /* 3912 */ { MAD_F(0x078642d6) /* 0.470278584 */, 17 }, /* 3913 */ { MAD_F(0x0786eaea) /* 0.470438877 */, 17 }, /* 3914 */ { MAD_F(0x07879302) /* 0.470599183 */, 17 }, /* 3915 */ { MAD_F(0x07883b1e) /* 0.470759503 */, 17 }, /* 3916 */ { MAD_F(0x0788e33d) /* 0.470919836 */, 17 }, /* 3917 */ { MAD_F(0x07898b60) /* 0.471080184 */, 17 }, /* 3918 */ { MAD_F(0x078a3386) /* 0.471240545 */, 17 }, /* 3919 */ { MAD_F(0x078adbb0) /* 0.471400919 */, 17 }, /* 3920 */ { MAD_F(0x078b83de) /* 0.471561307 */, 17 }, /* 3921 */ { MAD_F(0x078c2c10) /* 0.471721709 */, 17 }, /* 3922 */ { MAD_F(0x078cd445) /* 0.471882125 */, 17 }, /* 3923 */ { MAD_F(0x078d7c7e) /* 0.472042554 */, 17 }, /* 3924 */ { MAD_F(0x078e24ba) /* 0.472202996 */, 17 }, /* 3925 */ { MAD_F(0x078eccfb) /* 0.472363453 */, 17 }, /* 3926 */ { MAD_F(0x078f753e) /* 0.472523923 */, 17 }, /* 3927 */ { MAD_F(0x07901d86) /* 0.472684406 */, 17 }, /* 3928 */ { MAD_F(0x0790c5d1) /* 0.472844904 */, 17 }, /* 3929 */ { MAD_F(0x07916e20) /* 0.473005414 */, 17 }, /* 3930 */ { MAD_F(0x07921672) /* 0.473165939 */, 17 }, /* 3931 */ { MAD_F(0x0792bec8) /* 0.473326477 */, 17 }, /* 3932 */ { MAD_F(0x07936722) /* 0.473487029 */, 17 }, /* 3933 */ { MAD_F(0x07940f80) /* 0.473647594 */, 17 }, /* 3934 */ { MAD_F(0x0794b7e1) /* 0.473808173 */, 17 }, /* 3935 */ { MAD_F(0x07956045) /* 0.473968765 */, 17 }, /* 3936 */ { MAD_F(0x079608ae) /* 0.474129372 */, 17 }, /* 3937 */ { MAD_F(0x0796b11a) /* 0.474289991 */, 17 }, /* 3938 */ { MAD_F(0x0797598a) /* 0.474450625 */, 17 }, /* 3939 */ { MAD_F(0x079801fd) /* 0.474611272 */, 17 }, /* 3940 */ { MAD_F(0x0798aa74) /* 0.474771932 */, 17 }, /* 3941 */ { MAD_F(0x079952ee) /* 0.474932606 */, 17 }, /* 3942 */ { MAD_F(0x0799fb6d) /* 0.475093294 */, 17 }, /* 3943 */ { MAD_F(0x079aa3ef) /* 0.475253995 */, 17 }, /* 3944 */ { MAD_F(0x079b4c74) /* 0.475414710 */, 17 }, /* 3945 */ { MAD_F(0x079bf4fd) /* 0.475575439 */, 17 }, /* 3946 */ { MAD_F(0x079c9d8a) /* 0.475736181 */, 17 }, /* 3947 */ { MAD_F(0x079d461b) /* 0.475896936 */, 17 }, /* 3948 */ { MAD_F(0x079deeaf) /* 0.476057705 */, 17 }, /* 3949 */ { MAD_F(0x079e9747) /* 0.476218488 */, 17 }, /* 3950 */ { MAD_F(0x079f3fe2) /* 0.476379285 */, 17 }, /* 3951 */ { MAD_F(0x079fe881) /* 0.476540095 */, 17 }, /* 3952 */ { MAD_F(0x07a09124) /* 0.476700918 */, 17 }, /* 3953 */ { MAD_F(0x07a139ca) /* 0.476861755 */, 17 }, /* 3954 */ { MAD_F(0x07a1e274) /* 0.477022606 */, 17 }, /* 3955 */ { MAD_F(0x07a28b22) /* 0.477183470 */, 17 }, /* 3956 */ { MAD_F(0x07a333d3) /* 0.477344348 */, 17 }, /* 3957 */ { MAD_F(0x07a3dc88) /* 0.477505239 */, 17 }, /* 3958 */ { MAD_F(0x07a48541) /* 0.477666144 */, 17 }, /* 3959 */ { MAD_F(0x07a52dfd) /* 0.477827062 */, 17 }, /* 3960 */ { MAD_F(0x07a5d6bd) /* 0.477987994 */, 17 }, /* 3961 */ { MAD_F(0x07a67f80) /* 0.478148940 */, 17 }, /* 3962 */ { MAD_F(0x07a72847) /* 0.478309899 */, 17 }, /* 3963 */ { MAD_F(0x07a7d112) /* 0.478470871 */, 17 }, /* 3964 */ { MAD_F(0x07a879e1) /* 0.478631857 */, 17 }, /* 3965 */ { MAD_F(0x07a922b3) /* 0.478792857 */, 17 }, /* 3966 */ { MAD_F(0x07a9cb88) /* 0.478953870 */, 17 }, /* 3967 */ { MAD_F(0x07aa7462) /* 0.479114897 */, 17 }, /* 3968 */ { MAD_F(0x07ab1d3e) /* 0.479275937 */, 17 }, /* 3969 */ { MAD_F(0x07abc61f) /* 0.479436991 */, 17 }, /* 3970 */ { MAD_F(0x07ac6f03) /* 0.479598058 */, 17 }, /* 3971 */ { MAD_F(0x07ad17eb) /* 0.479759139 */, 17 }, /* 3972 */ { MAD_F(0x07adc0d6) /* 0.479920233 */, 17 }, /* 3973 */ { MAD_F(0x07ae69c6) /* 0.480081341 */, 17 }, /* 3974 */ { MAD_F(0x07af12b8) /* 0.480242463 */, 17 }, /* 3975 */ { MAD_F(0x07afbbaf) /* 0.480403598 */, 17 }, /* 3976 */ { MAD_F(0x07b064a8) /* 0.480564746 */, 17 }, /* 3977 */ { MAD_F(0x07b10da6) /* 0.480725908 */, 17 }, /* 3978 */ { MAD_F(0x07b1b6a7) /* 0.480887083 */, 17 }, /* 3979 */ { MAD_F(0x07b25fac) /* 0.481048272 */, 17 }, /* 3980 */ { MAD_F(0x07b308b5) /* 0.481209475 */, 17 }, /* 3981 */ { MAD_F(0x07b3b1c1) /* 0.481370691 */, 17 }, /* 3982 */ { MAD_F(0x07b45ad0) /* 0.481531920 */, 17 }, /* 3983 */ { MAD_F(0x07b503e4) /* 0.481693163 */, 17 }, /* 3984 */ { MAD_F(0x07b5acfb) /* 0.481854420 */, 17 }, /* 3985 */ { MAD_F(0x07b65615) /* 0.482015690 */, 17 }, /* 3986 */ { MAD_F(0x07b6ff33) /* 0.482176973 */, 17 }, /* 3987 */ { MAD_F(0x07b7a855) /* 0.482338270 */, 17 }, /* 3988 */ { MAD_F(0x07b8517b) /* 0.482499580 */, 17 }, /* 3989 */ { MAD_F(0x07b8faa4) /* 0.482660904 */, 17 }, /* 3990 */ { MAD_F(0x07b9a3d0) /* 0.482822242 */, 17 }, /* 3991 */ { MAD_F(0x07ba4d01) /* 0.482983592 */, 17 }, /* 3992 */ { MAD_F(0x07baf635) /* 0.483144957 */, 17 }, /* 3993 */ { MAD_F(0x07bb9f6c) /* 0.483306335 */, 17 }, /* 3994 */ { MAD_F(0x07bc48a7) /* 0.483467726 */, 17 }, /* 3995 */ { MAD_F(0x07bcf1e6) /* 0.483629131 */, 17 }, /* 3996 */ { MAD_F(0x07bd9b28) /* 0.483790549 */, 17 }, /* 3997 */ { MAD_F(0x07be446e) /* 0.483951980 */, 17 }, /* 3998 */ { MAD_F(0x07beedb8) /* 0.484113426 */, 17 }, /* 3999 */ { MAD_F(0x07bf9705) /* 0.484274884 */, 17 }, /* 4000 */ { MAD_F(0x07c04056) /* 0.484436356 */, 17 }, /* 4001 */ { MAD_F(0x07c0e9aa) /* 0.484597842 */, 17 }, /* 4002 */ { MAD_F(0x07c19302) /* 0.484759341 */, 17 }, /* 4003 */ { MAD_F(0x07c23c5e) /* 0.484920853 */, 17 }, /* 4004 */ { MAD_F(0x07c2e5bd) /* 0.485082379 */, 17 }, /* 4005 */ { MAD_F(0x07c38f20) /* 0.485243918 */, 17 }, /* 4006 */ { MAD_F(0x07c43887) /* 0.485405471 */, 17 }, /* 4007 */ { MAD_F(0x07c4e1f1) /* 0.485567037 */, 17 }, /* 4008 */ { MAD_F(0x07c58b5f) /* 0.485728617 */, 17 }, /* 4009 */ { MAD_F(0x07c634d0) /* 0.485890210 */, 17 }, /* 4010 */ { MAD_F(0x07c6de45) /* 0.486051817 */, 17 }, /* 4011 */ { MAD_F(0x07c787bd) /* 0.486213436 */, 17 }, /* 4012 */ { MAD_F(0x07c83139) /* 0.486375070 */, 17 }, /* 4013 */ { MAD_F(0x07c8dab9) /* 0.486536717 */, 17 }, /* 4014 */ { MAD_F(0x07c9843c) /* 0.486698377 */, 17 }, /* 4015 */ { MAD_F(0x07ca2dc3) /* 0.486860051 */, 17 }, /* 4016 */ { MAD_F(0x07cad74e) /* 0.487021738 */, 17 }, /* 4017 */ { MAD_F(0x07cb80dc) /* 0.487183438 */, 17 }, /* 4018 */ { MAD_F(0x07cc2a6e) /* 0.487345152 */, 17 }, /* 4019 */ { MAD_F(0x07ccd403) /* 0.487506879 */, 17 }, /* 4020 */ { MAD_F(0x07cd7d9c) /* 0.487668620 */, 17 }, /* 4021 */ { MAD_F(0x07ce2739) /* 0.487830374 */, 17 }, /* 4022 */ { MAD_F(0x07ced0d9) /* 0.487992142 */, 17 }, /* 4023 */ { MAD_F(0x07cf7a7d) /* 0.488153923 */, 17 }, /* 4024 */ { MAD_F(0x07d02424) /* 0.488315717 */, 17 }, /* 4025 */ { MAD_F(0x07d0cdcf) /* 0.488477525 */, 17 }, /* 4026 */ { MAD_F(0x07d1777e) /* 0.488639346 */, 17 }, /* 4027 */ { MAD_F(0x07d22130) /* 0.488801181 */, 17 }, /* 4028 */ { MAD_F(0x07d2cae5) /* 0.488963029 */, 17 }, /* 4029 */ { MAD_F(0x07d3749f) /* 0.489124890 */, 17 }, /* 4030 */ { MAD_F(0x07d41e5c) /* 0.489286765 */, 17 }, /* 4031 */ { MAD_F(0x07d4c81c) /* 0.489448653 */, 17 }, /* 4032 */ { MAD_F(0x07d571e0) /* 0.489610555 */, 17 }, /* 4033 */ { MAD_F(0x07d61ba8) /* 0.489772470 */, 17 }, /* 4034 */ { MAD_F(0x07d6c573) /* 0.489934398 */, 17 }, /* 4035 */ { MAD_F(0x07d76f42) /* 0.490096340 */, 17 }, /* 4036 */ { MAD_F(0x07d81915) /* 0.490258295 */, 17 }, /* 4037 */ { MAD_F(0x07d8c2eb) /* 0.490420263 */, 17 }, /* 4038 */ { MAD_F(0x07d96cc4) /* 0.490582245 */, 17 }, /* 4039 */ { MAD_F(0x07da16a2) /* 0.490744240 */, 17 }, /* 4040 */ { MAD_F(0x07dac083) /* 0.490906249 */, 17 }, /* 4041 */ { MAD_F(0x07db6a67) /* 0.491068271 */, 17 }, /* 4042 */ { MAD_F(0x07dc144f) /* 0.491230306 */, 17 }, /* 4043 */ { MAD_F(0x07dcbe3b) /* 0.491392355 */, 17 }, /* 4044 */ { MAD_F(0x07dd682a) /* 0.491554417 */, 17 }, /* 4045 */ { MAD_F(0x07de121d) /* 0.491716492 */, 17 }, /* 4046 */ { MAD_F(0x07debc13) /* 0.491878581 */, 17 }, /* 4047 */ { MAD_F(0x07df660d) /* 0.492040683 */, 17 }, /* 4048 */ { MAD_F(0x07e0100a) /* 0.492202799 */, 17 }, /* 4049 */ { MAD_F(0x07e0ba0c) /* 0.492364928 */, 17 }, /* 4050 */ { MAD_F(0x07e16410) /* 0.492527070 */, 17 }, /* 4051 */ { MAD_F(0x07e20e19) /* 0.492689225 */, 17 }, /* 4052 */ { MAD_F(0x07e2b824) /* 0.492851394 */, 17 }, /* 4053 */ { MAD_F(0x07e36234) /* 0.493013576 */, 17 }, /* 4054 */ { MAD_F(0x07e40c47) /* 0.493175772 */, 17 }, /* 4055 */ { MAD_F(0x07e4b65e) /* 0.493337981 */, 17 }, /* 4056 */ { MAD_F(0x07e56078) /* 0.493500203 */, 17 }, /* 4057 */ { MAD_F(0x07e60a95) /* 0.493662438 */, 17 }, /* 4058 */ { MAD_F(0x07e6b4b7) /* 0.493824687 */, 17 }, /* 4059 */ { MAD_F(0x07e75edc) /* 0.493986949 */, 17 }, /* 4060 */ { MAD_F(0x07e80904) /* 0.494149225 */, 17 }, /* 4061 */ { MAD_F(0x07e8b330) /* 0.494311514 */, 17 }, /* 4062 */ { MAD_F(0x07e95d60) /* 0.494473816 */, 17 }, /* 4063 */ { MAD_F(0x07ea0793) /* 0.494636131 */, 17 }, /* 4064 */ { MAD_F(0x07eab1ca) /* 0.494798460 */, 17 }, /* 4065 */ { MAD_F(0x07eb5c04) /* 0.494960802 */, 17 }, /* 4066 */ { MAD_F(0x07ec0642) /* 0.495123158 */, 17 }, /* 4067 */ { MAD_F(0x07ecb084) /* 0.495285526 */, 17 }, /* 4068 */ { MAD_F(0x07ed5ac9) /* 0.495447908 */, 17 }, /* 4069 */ { MAD_F(0x07ee0512) /* 0.495610304 */, 17 }, /* 4070 */ { MAD_F(0x07eeaf5e) /* 0.495772712 */, 17 }, /* 4071 */ { MAD_F(0x07ef59ae) /* 0.495935134 */, 17 }, /* 4072 */ { MAD_F(0x07f00401) /* 0.496097570 */, 17 }, /* 4073 */ { MAD_F(0x07f0ae58) /* 0.496260018 */, 17 }, /* 4074 */ { MAD_F(0x07f158b3) /* 0.496422480 */, 17 }, /* 4075 */ { MAD_F(0x07f20311) /* 0.496584955 */, 17 }, /* 4076 */ { MAD_F(0x07f2ad72) /* 0.496747444 */, 17 }, /* 4077 */ { MAD_F(0x07f357d8) /* 0.496909945 */, 17 }, /* 4078 */ { MAD_F(0x07f40240) /* 0.497072460 */, 17 }, /* 4079 */ { MAD_F(0x07f4acad) /* 0.497234989 */, 17 }, /* 4080 */ { MAD_F(0x07f5571d) /* 0.497397530 */, 17 }, /* 4081 */ { MAD_F(0x07f60190) /* 0.497560085 */, 17 }, /* 4082 */ { MAD_F(0x07f6ac07) /* 0.497722653 */, 17 }, /* 4083 */ { MAD_F(0x07f75682) /* 0.497885235 */, 17 }, /* 4084 */ { MAD_F(0x07f80100) /* 0.498047829 */, 17 }, /* 4085 */ { MAD_F(0x07f8ab82) /* 0.498210437 */, 17 }, /* 4086 */ { MAD_F(0x07f95607) /* 0.498373058 */, 17 }, /* 4087 */ { MAD_F(0x07fa0090) /* 0.498535693 */, 17 }, /* 4088 */ { MAD_F(0x07faab1c) /* 0.498698341 */, 17 }, /* 4089 */ { MAD_F(0x07fb55ac) /* 0.498861002 */, 17 }, /* 4090 */ { MAD_F(0x07fc0040) /* 0.499023676 */, 17 }, /* 4091 */ { MAD_F(0x07fcaad7) /* 0.499186364 */, 17 }, /* 4092 */ { MAD_F(0x07fd5572) /* 0.499349064 */, 17 }, /* 4093 */ { MAD_F(0x07fe0010) /* 0.499511778 */, 17 }, /* 4094 */ { MAD_F(0x07feaab2) /* 0.499674506 */, 17 }, /* 4095 */ { MAD_F(0x07ff5557) /* 0.499837246 */, 17 }, /* 4096 */ { MAD_F(0x04000000) /* 0.250000000 */, 18 }, /* 4097 */ { MAD_F(0x04005556) /* 0.250081384 */, 18 }, /* 4098 */ { MAD_F(0x0400aaae) /* 0.250162774 */, 18 }, /* 4099 */ { MAD_F(0x04010008) /* 0.250244170 */, 18 }, /* 4100 */ { MAD_F(0x04015563) /* 0.250325574 */, 18 }, /* 4101 */ { MAD_F(0x0401aac1) /* 0.250406984 */, 18 }, /* 4102 */ { MAD_F(0x04020020) /* 0.250488400 */, 18 }, /* 4103 */ { MAD_F(0x04025581) /* 0.250569824 */, 18 }, /* 4104 */ { MAD_F(0x0402aae3) /* 0.250651254 */, 18 }, /* 4105 */ { MAD_F(0x04030048) /* 0.250732690 */, 18 }, /* 4106 */ { MAD_F(0x040355ae) /* 0.250814133 */, 18 }, /* 4107 */ { MAD_F(0x0403ab16) /* 0.250895583 */, 18 }, /* 4108 */ { MAD_F(0x04040080) /* 0.250977039 */, 18 }, /* 4109 */ { MAD_F(0x040455eb) /* 0.251058502 */, 18 }, /* 4110 */ { MAD_F(0x0404ab59) /* 0.251139971 */, 18 }, /* 4111 */ { MAD_F(0x040500c8) /* 0.251221448 */, 18 }, /* 4112 */ { MAD_F(0x04055638) /* 0.251302930 */, 18 }, /* 4113 */ { MAD_F(0x0405abab) /* 0.251384420 */, 18 }, /* 4114 */ { MAD_F(0x0406011f) /* 0.251465916 */, 18 }, /* 4115 */ { MAD_F(0x04065696) /* 0.251547418 */, 18 }, /* 4116 */ { MAD_F(0x0406ac0e) /* 0.251628927 */, 18 }, /* 4117 */ { MAD_F(0x04070187) /* 0.251710443 */, 18 }, /* 4118 */ { MAD_F(0x04075703) /* 0.251791965 */, 18 }, /* 4119 */ { MAD_F(0x0407ac80) /* 0.251873494 */, 18 }, /* 4120 */ { MAD_F(0x040801ff) /* 0.251955030 */, 18 }, /* 4121 */ { MAD_F(0x04085780) /* 0.252036572 */, 18 }, /* 4122 */ { MAD_F(0x0408ad02) /* 0.252118121 */, 18 }, /* 4123 */ { MAD_F(0x04090287) /* 0.252199676 */, 18 }, /* 4124 */ { MAD_F(0x0409580d) /* 0.252281238 */, 18 }, /* 4125 */ { MAD_F(0x0409ad95) /* 0.252362807 */, 18 }, /* 4126 */ { MAD_F(0x040a031e) /* 0.252444382 */, 18 }, /* 4127 */ { MAD_F(0x040a58aa) /* 0.252525963 */, 18 }, /* 4128 */ { MAD_F(0x040aae37) /* 0.252607552 */, 18 }, /* 4129 */ { MAD_F(0x040b03c6) /* 0.252689147 */, 18 }, /* 4130 */ { MAD_F(0x040b5957) /* 0.252770748 */, 18 }, /* 4131 */ { MAD_F(0x040baee9) /* 0.252852356 */, 18 }, /* 4132 */ { MAD_F(0x040c047e) /* 0.252933971 */, 18 }, /* 4133 */ { MAD_F(0x040c5a14) /* 0.253015592 */, 18 }, /* 4134 */ { MAD_F(0x040cafab) /* 0.253097220 */, 18 }, /* 4135 */ { MAD_F(0x040d0545) /* 0.253178854 */, 18 }, /* 4136 */ { MAD_F(0x040d5ae0) /* 0.253260495 */, 18 }, /* 4137 */ { MAD_F(0x040db07d) /* 0.253342143 */, 18 }, /* 4138 */ { MAD_F(0x040e061c) /* 0.253423797 */, 18 }, /* 4139 */ { MAD_F(0x040e5bbd) /* 0.253505457 */, 18 }, /* 4140 */ { MAD_F(0x040eb15f) /* 0.253587125 */, 18 }, /* 4141 */ { MAD_F(0x040f0703) /* 0.253668799 */, 18 }, /* 4142 */ { MAD_F(0x040f5ca9) /* 0.253750479 */, 18 }, /* 4143 */ { MAD_F(0x040fb251) /* 0.253832166 */, 18 }, /* 4144 */ { MAD_F(0x041007fa) /* 0.253913860 */, 18 }, /* 4145 */ { MAD_F(0x04105da6) /* 0.253995560 */, 18 }, /* 4146 */ { MAD_F(0x0410b353) /* 0.254077266 */, 18 }, /* 4147 */ { MAD_F(0x04110901) /* 0.254158980 */, 18 }, /* 4148 */ { MAD_F(0x04115eb2) /* 0.254240700 */, 18 }, /* 4149 */ { MAD_F(0x0411b464) /* 0.254322426 */, 18 }, /* 4150 */ { MAD_F(0x04120a18) /* 0.254404159 */, 18 }, /* 4151 */ { MAD_F(0x04125fce) /* 0.254485899 */, 18 }, /* 4152 */ { MAD_F(0x0412b586) /* 0.254567645 */, 18 }, /* 4153 */ { MAD_F(0x04130b3f) /* 0.254649397 */, 18 }, /* 4154 */ { MAD_F(0x041360fa) /* 0.254731157 */, 18 }, /* 4155 */ { MAD_F(0x0413b6b7) /* 0.254812922 */, 18 }, /* 4156 */ { MAD_F(0x04140c75) /* 0.254894695 */, 18 }, /* 4157 */ { MAD_F(0x04146236) /* 0.254976474 */, 18 }, /* 4158 */ { MAD_F(0x0414b7f8) /* 0.255058259 */, 18 }, /* 4159 */ { MAD_F(0x04150dbc) /* 0.255140051 */, 18 }, /* 4160 */ { MAD_F(0x04156381) /* 0.255221850 */, 18 }, /* 4161 */ { MAD_F(0x0415b949) /* 0.255303655 */, 18 }, /* 4162 */ { MAD_F(0x04160f12) /* 0.255385467 */, 18 }, /* 4163 */ { MAD_F(0x041664dd) /* 0.255467285 */, 18 }, /* 4164 */ { MAD_F(0x0416baaa) /* 0.255549110 */, 18 }, /* 4165 */ { MAD_F(0x04171078) /* 0.255630941 */, 18 }, /* 4166 */ { MAD_F(0x04176648) /* 0.255712779 */, 18 }, /* 4167 */ { MAD_F(0x0417bc1a) /* 0.255794624 */, 18 }, /* 4168 */ { MAD_F(0x041811ee) /* 0.255876475 */, 18 }, /* 4169 */ { MAD_F(0x041867c3) /* 0.255958332 */, 18 }, /* 4170 */ { MAD_F(0x0418bd9b) /* 0.256040196 */, 18 }, /* 4171 */ { MAD_F(0x04191374) /* 0.256122067 */, 18 }, /* 4172 */ { MAD_F(0x0419694e) /* 0.256203944 */, 18 }, /* 4173 */ { MAD_F(0x0419bf2b) /* 0.256285828 */, 18 }, /* 4174 */ { MAD_F(0x041a1509) /* 0.256367718 */, 18 }, /* 4175 */ { MAD_F(0x041a6ae9) /* 0.256449615 */, 18 }, /* 4176 */ { MAD_F(0x041ac0cb) /* 0.256531518 */, 18 }, /* 4177 */ { MAD_F(0x041b16ae) /* 0.256613428 */, 18 }, /* 4178 */ { MAD_F(0x041b6c94) /* 0.256695344 */, 18 }, /* 4179 */ { MAD_F(0x041bc27b) /* 0.256777267 */, 18 }, /* 4180 */ { MAD_F(0x041c1863) /* 0.256859197 */, 18 }, /* 4181 */ { MAD_F(0x041c6e4e) /* 0.256941133 */, 18 }, /* 4182 */ { MAD_F(0x041cc43a) /* 0.257023076 */, 18 }, /* 4183 */ { MAD_F(0x041d1a28) /* 0.257105025 */, 18 }, /* 4184 */ { MAD_F(0x041d7018) /* 0.257186980 */, 18 }, /* 4185 */ { MAD_F(0x041dc60a) /* 0.257268942 */, 18 }, /* 4186 */ { MAD_F(0x041e1bfd) /* 0.257350911 */, 18 }, /* 4187 */ { MAD_F(0x041e71f2) /* 0.257432886 */, 18 }, /* 4188 */ { MAD_F(0x041ec7e9) /* 0.257514868 */, 18 }, /* 4189 */ { MAD_F(0x041f1de1) /* 0.257596856 */, 18 }, /* 4190 */ { MAD_F(0x041f73dc) /* 0.257678851 */, 18 }, /* 4191 */ { MAD_F(0x041fc9d8) /* 0.257760852 */, 18 }, /* 4192 */ { MAD_F(0x04201fd5) /* 0.257842860 */, 18 }, /* 4193 */ { MAD_F(0x042075d5) /* 0.257924875 */, 18 }, /* 4194 */ { MAD_F(0x0420cbd6) /* 0.258006895 */, 18 }, /* 4195 */ { MAD_F(0x042121d9) /* 0.258088923 */, 18 }, /* 4196 */ { MAD_F(0x042177de) /* 0.258170957 */, 18 }, /* 4197 */ { MAD_F(0x0421cde5) /* 0.258252997 */, 18 }, /* 4198 */ { MAD_F(0x042223ed) /* 0.258335044 */, 18 }, /* 4199 */ { MAD_F(0x042279f7) /* 0.258417097 */, 18 }, /* 4200 */ { MAD_F(0x0422d003) /* 0.258499157 */, 18 }, /* 4201 */ { MAD_F(0x04232611) /* 0.258581224 */, 18 }, /* 4202 */ { MAD_F(0x04237c20) /* 0.258663297 */, 18 }, /* 4203 */ { MAD_F(0x0423d231) /* 0.258745376 */, 18 }, /* 4204 */ { MAD_F(0x04242844) /* 0.258827462 */, 18 }, /* 4205 */ { MAD_F(0x04247e58) /* 0.258909555 */, 18 }, /* 4206 */ { MAD_F(0x0424d46e) /* 0.258991654 */, 18 }, /* 4207 */ { MAD_F(0x04252a87) /* 0.259073760 */, 18 }, /* 4208 */ { MAD_F(0x042580a0) /* 0.259155872 */, 18 }, /* 4209 */ { MAD_F(0x0425d6bc) /* 0.259237990 */, 18 }, /* 4210 */ { MAD_F(0x04262cd9) /* 0.259320115 */, 18 }, /* 4211 */ { MAD_F(0x042682f8) /* 0.259402247 */, 18 }, /* 4212 */ { MAD_F(0x0426d919) /* 0.259484385 */, 18 }, /* 4213 */ { MAD_F(0x04272f3b) /* 0.259566529 */, 18 }, /* 4214 */ { MAD_F(0x04278560) /* 0.259648680 */, 18 }, /* 4215 */ { MAD_F(0x0427db86) /* 0.259730838 */, 18 }, /* 4216 */ { MAD_F(0x042831ad) /* 0.259813002 */, 18 }, /* 4217 */ { MAD_F(0x042887d7) /* 0.259895173 */, 18 }, /* 4218 */ { MAD_F(0x0428de02) /* 0.259977350 */, 18 }, /* 4219 */ { MAD_F(0x0429342f) /* 0.260059533 */, 18 }, /* 4220 */ { MAD_F(0x04298a5e) /* 0.260141723 */, 18 }, /* 4221 */ { MAD_F(0x0429e08e) /* 0.260223920 */, 18 }, /* 4222 */ { MAD_F(0x042a36c0) /* 0.260306123 */, 18 }, /* 4223 */ { MAD_F(0x042a8cf4) /* 0.260388332 */, 18 }, /* 4224 */ { MAD_F(0x042ae32a) /* 0.260470548 */, 18 }, /* 4225 */ { MAD_F(0x042b3962) /* 0.260552771 */, 18 }, /* 4226 */ { MAD_F(0x042b8f9b) /* 0.260635000 */, 18 }, /* 4227 */ { MAD_F(0x042be5d6) /* 0.260717235 */, 18 }, /* 4228 */ { MAD_F(0x042c3c12) /* 0.260799477 */, 18 }, /* 4229 */ { MAD_F(0x042c9251) /* 0.260881725 */, 18 }, /* 4230 */ { MAD_F(0x042ce891) /* 0.260963980 */, 18 }, /* 4231 */ { MAD_F(0x042d3ed3) /* 0.261046242 */, 18 }, /* 4232 */ { MAD_F(0x042d9516) /* 0.261128510 */, 18 }, /* 4233 */ { MAD_F(0x042deb5c) /* 0.261210784 */, 18 }, /* 4234 */ { MAD_F(0x042e41a3) /* 0.261293065 */, 18 }, /* 4235 */ { MAD_F(0x042e97ec) /* 0.261375352 */, 18 }, /* 4236 */ { MAD_F(0x042eee36) /* 0.261457646 */, 18 }, /* 4237 */ { MAD_F(0x042f4482) /* 0.261539946 */, 18 }, /* 4238 */ { MAD_F(0x042f9ad1) /* 0.261622253 */, 18 }, /* 4239 */ { MAD_F(0x042ff120) /* 0.261704566 */, 18 }, /* 4240 */ { MAD_F(0x04304772) /* 0.261786886 */, 18 }, /* 4241 */ { MAD_F(0x04309dc5) /* 0.261869212 */, 18 }, /* 4242 */ { MAD_F(0x0430f41a) /* 0.261951545 */, 18 }, /* 4243 */ { MAD_F(0x04314a71) /* 0.262033884 */, 18 }, /* 4244 */ { MAD_F(0x0431a0c9) /* 0.262116229 */, 18 }, /* 4245 */ { MAD_F(0x0431f723) /* 0.262198581 */, 18 }, /* 4246 */ { MAD_F(0x04324d7f) /* 0.262280940 */, 18 }, /* 4247 */ { MAD_F(0x0432a3dd) /* 0.262363305 */, 18 }, /* 4248 */ { MAD_F(0x0432fa3d) /* 0.262445676 */, 18 }, /* 4249 */ { MAD_F(0x0433509e) /* 0.262528054 */, 18 }, /* 4250 */ { MAD_F(0x0433a701) /* 0.262610438 */, 18 }, /* 4251 */ { MAD_F(0x0433fd65) /* 0.262692829 */, 18 }, /* 4252 */ { MAD_F(0x043453cc) /* 0.262775227 */, 18 }, /* 4253 */ { MAD_F(0x0434aa34) /* 0.262857630 */, 18 }, /* 4254 */ { MAD_F(0x0435009d) /* 0.262940040 */, 18 }, /* 4255 */ { MAD_F(0x04355709) /* 0.263022457 */, 18 }, /* 4256 */ { MAD_F(0x0435ad76) /* 0.263104880 */, 18 }, /* 4257 */ { MAD_F(0x043603e5) /* 0.263187310 */, 18 }, /* 4258 */ { MAD_F(0x04365a56) /* 0.263269746 */, 18 }, /* 4259 */ { MAD_F(0x0436b0c9) /* 0.263352188 */, 18 }, /* 4260 */ { MAD_F(0x0437073d) /* 0.263434637 */, 18 }, /* 4261 */ { MAD_F(0x04375db3) /* 0.263517093 */, 18 }, /* 4262 */ { MAD_F(0x0437b42a) /* 0.263599554 */, 18 }, /* 4263 */ { MAD_F(0x04380aa4) /* 0.263682023 */, 18 }, /* 4264 */ { MAD_F(0x0438611f) /* 0.263764497 */, 18 }, /* 4265 */ { MAD_F(0x0438b79c) /* 0.263846979 */, 18 }, /* 4266 */ { MAD_F(0x04390e1a) /* 0.263929466 */, 18 }, /* 4267 */ { MAD_F(0x0439649b) /* 0.264011960 */, 18 }, /* 4268 */ { MAD_F(0x0439bb1d) /* 0.264094461 */, 18 }, /* 4269 */ { MAD_F(0x043a11a1) /* 0.264176968 */, 18 }, /* 4270 */ { MAD_F(0x043a6826) /* 0.264259481 */, 18 }, /* 4271 */ { MAD_F(0x043abead) /* 0.264342001 */, 18 }, /* 4272 */ { MAD_F(0x043b1536) /* 0.264424527 */, 18 }, /* 4273 */ { MAD_F(0x043b6bc1) /* 0.264507060 */, 18 }, /* 4274 */ { MAD_F(0x043bc24d) /* 0.264589599 */, 18 }, /* 4275 */ { MAD_F(0x043c18dc) /* 0.264672145 */, 18 }, /* 4276 */ { MAD_F(0x043c6f6c) /* 0.264754697 */, 18 }, /* 4277 */ { MAD_F(0x043cc5fd) /* 0.264837255 */, 18 }, /* 4278 */ { MAD_F(0x043d1c91) /* 0.264919820 */, 18 }, /* 4279 */ { MAD_F(0x043d7326) /* 0.265002392 */, 18 }, /* 4280 */ { MAD_F(0x043dc9bc) /* 0.265084969 */, 18 }, /* 4281 */ { MAD_F(0x043e2055) /* 0.265167554 */, 18 }, /* 4282 */ { MAD_F(0x043e76ef) /* 0.265250144 */, 18 }, /* 4283 */ { MAD_F(0x043ecd8b) /* 0.265332741 */, 18 }, /* 4284 */ { MAD_F(0x043f2429) /* 0.265415345 */, 18 }, /* 4285 */ { MAD_F(0x043f7ac8) /* 0.265497955 */, 18 }, /* 4286 */ { MAD_F(0x043fd169) /* 0.265580571 */, 18 }, /* 4287 */ { MAD_F(0x0440280c) /* 0.265663194 */, 18 }, /* 4288 */ { MAD_F(0x04407eb1) /* 0.265745823 */, 18 }, /* 4289 */ { MAD_F(0x0440d557) /* 0.265828459 */, 18 }, /* 4290 */ { MAD_F(0x04412bff) /* 0.265911101 */, 18 }, /* 4291 */ { MAD_F(0x044182a9) /* 0.265993749 */, 18 }, /* 4292 */ { MAD_F(0x0441d955) /* 0.266076404 */, 18 }, /* 4293 */ { MAD_F(0x04423002) /* 0.266159065 */, 18 }, /* 4294 */ { MAD_F(0x044286b1) /* 0.266241733 */, 18 }, /* 4295 */ { MAD_F(0x0442dd61) /* 0.266324407 */, 18 }, /* 4296 */ { MAD_F(0x04433414) /* 0.266407088 */, 18 }, /* 4297 */ { MAD_F(0x04438ac8) /* 0.266489775 */, 18 }, /* 4298 */ { MAD_F(0x0443e17e) /* 0.266572468 */, 18 }, /* 4299 */ { MAD_F(0x04443835) /* 0.266655168 */, 18 }, /* 4300 */ { MAD_F(0x04448eef) /* 0.266737874 */, 18 }, /* 4301 */ { MAD_F(0x0444e5aa) /* 0.266820587 */, 18 }, /* 4302 */ { MAD_F(0x04453c66) /* 0.266903306 */, 18 }, /* 4303 */ { MAD_F(0x04459325) /* 0.266986031 */, 18 }, /* 4304 */ { MAD_F(0x0445e9e5) /* 0.267068763 */, 18 }, /* 4305 */ { MAD_F(0x044640a7) /* 0.267151501 */, 18 }, /* 4306 */ { MAD_F(0x0446976a) /* 0.267234246 */, 18 }, /* 4307 */ { MAD_F(0x0446ee30) /* 0.267316997 */, 18 }, /* 4308 */ { MAD_F(0x044744f7) /* 0.267399755 */, 18 }, /* 4309 */ { MAD_F(0x04479bc0) /* 0.267482518 */, 18 }, /* 4310 */ { MAD_F(0x0447f28a) /* 0.267565289 */, 18 }, /* 4311 */ { MAD_F(0x04484956) /* 0.267648065 */, 18 }, /* 4312 */ { MAD_F(0x0448a024) /* 0.267730848 */, 18 }, /* 4313 */ { MAD_F(0x0448f6f4) /* 0.267813638 */, 18 }, /* 4314 */ { MAD_F(0x04494dc5) /* 0.267896434 */, 18 }, /* 4315 */ { MAD_F(0x0449a498) /* 0.267979236 */, 18 }, /* 4316 */ { MAD_F(0x0449fb6d) /* 0.268062045 */, 18 }, /* 4317 */ { MAD_F(0x044a5243) /* 0.268144860 */, 18 }, /* 4318 */ { MAD_F(0x044aa91c) /* 0.268227681 */, 18 }, /* 4319 */ { MAD_F(0x044afff6) /* 0.268310509 */, 18 }, /* 4320 */ { MAD_F(0x044b56d1) /* 0.268393343 */, 18 }, /* 4321 */ { MAD_F(0x044badaf) /* 0.268476184 */, 18 }, /* 4322 */ { MAD_F(0x044c048e) /* 0.268559031 */, 18 }, /* 4323 */ { MAD_F(0x044c5b6f) /* 0.268641885 */, 18 }, /* 4324 */ { MAD_F(0x044cb251) /* 0.268724744 */, 18 }, /* 4325 */ { MAD_F(0x044d0935) /* 0.268807611 */, 18 }, /* 4326 */ { MAD_F(0x044d601b) /* 0.268890483 */, 18 }, /* 4327 */ { MAD_F(0x044db703) /* 0.268973362 */, 18 }, /* 4328 */ { MAD_F(0x044e0dec) /* 0.269056248 */, 18 }, /* 4329 */ { MAD_F(0x044e64d7) /* 0.269139139 */, 18 }, /* 4330 */ { MAD_F(0x044ebbc4) /* 0.269222037 */, 18 }, /* 4331 */ { MAD_F(0x044f12b3) /* 0.269304942 */, 18 }, /* 4332 */ { MAD_F(0x044f69a3) /* 0.269387853 */, 18 }, /* 4333 */ { MAD_F(0x044fc095) /* 0.269470770 */, 18 }, /* 4334 */ { MAD_F(0x04501788) /* 0.269553694 */, 18 }, /* 4335 */ { MAD_F(0x04506e7e) /* 0.269636624 */, 18 }, /* 4336 */ { MAD_F(0x0450c575) /* 0.269719560 */, 18 }, /* 4337 */ { MAD_F(0x04511c6e) /* 0.269802503 */, 18 }, /* 4338 */ { MAD_F(0x04517368) /* 0.269885452 */, 18 }, /* 4339 */ { MAD_F(0x0451ca64) /* 0.269968408 */, 18 }, /* 4340 */ { MAD_F(0x04522162) /* 0.270051370 */, 18 }, /* 4341 */ { MAD_F(0x04527862) /* 0.270134338 */, 18 }, /* 4342 */ { MAD_F(0x0452cf63) /* 0.270217312 */, 18 }, /* 4343 */ { MAD_F(0x04532666) /* 0.270300293 */, 18 }, /* 4344 */ { MAD_F(0x04537d6b) /* 0.270383281 */, 18 }, /* 4345 */ { MAD_F(0x0453d472) /* 0.270466275 */, 18 }, /* 4346 */ { MAD_F(0x04542b7a) /* 0.270549275 */, 18 }, /* 4347 */ { MAD_F(0x04548284) /* 0.270632281 */, 18 }, /* 4348 */ { MAD_F(0x0454d98f) /* 0.270715294 */, 18 }, /* 4349 */ { MAD_F(0x0455309c) /* 0.270798313 */, 18 }, /* 4350 */ { MAD_F(0x045587ab) /* 0.270881339 */, 18 }, /* 4351 */ { MAD_F(0x0455debc) /* 0.270964371 */, 18 }, /* 4352 */ { MAD_F(0x045635cf) /* 0.271047409 */, 18 }, /* 4353 */ { MAD_F(0x04568ce3) /* 0.271130454 */, 18 }, /* 4354 */ { MAD_F(0x0456e3f9) /* 0.271213505 */, 18 }, /* 4355 */ { MAD_F(0x04573b10) /* 0.271296562 */, 18 }, /* 4356 */ { MAD_F(0x04579229) /* 0.271379626 */, 18 }, /* 4357 */ { MAD_F(0x0457e944) /* 0.271462696 */, 18 }, /* 4358 */ { MAD_F(0x04584061) /* 0.271545772 */, 18 }, /* 4359 */ { MAD_F(0x0458977f) /* 0.271628855 */, 18 }, /* 4360 */ { MAD_F(0x0458ee9f) /* 0.271711944 */, 18 }, /* 4361 */ { MAD_F(0x045945c1) /* 0.271795040 */, 18 }, /* 4362 */ { MAD_F(0x04599ce5) /* 0.271878142 */, 18 }, /* 4363 */ { MAD_F(0x0459f40a) /* 0.271961250 */, 18 }, /* 4364 */ { MAD_F(0x045a4b31) /* 0.272044365 */, 18 }, /* 4365 */ { MAD_F(0x045aa259) /* 0.272127486 */, 18 }, /* 4366 */ { MAD_F(0x045af984) /* 0.272210613 */, 18 }, /* 4367 */ { MAD_F(0x045b50b0) /* 0.272293746 */, 18 }, /* 4368 */ { MAD_F(0x045ba7dd) /* 0.272376886 */, 18 }, /* 4369 */ { MAD_F(0x045bff0d) /* 0.272460033 */, 18 }, /* 4370 */ { MAD_F(0x045c563e) /* 0.272543185 */, 18 }, /* 4371 */ { MAD_F(0x045cad71) /* 0.272626344 */, 18 }, /* 4372 */ { MAD_F(0x045d04a5) /* 0.272709510 */, 18 }, /* 4373 */ { MAD_F(0x045d5bdc) /* 0.272792681 */, 18 }, /* 4374 */ { MAD_F(0x045db313) /* 0.272875859 */, 18 }, /* 4375 */ { MAD_F(0x045e0a4d) /* 0.272959044 */, 18 }, /* 4376 */ { MAD_F(0x045e6188) /* 0.273042234 */, 18 }, /* 4377 */ { MAD_F(0x045eb8c5) /* 0.273125431 */, 18 }, /* 4378 */ { MAD_F(0x045f1004) /* 0.273208635 */, 18 }, /* 4379 */ { MAD_F(0x045f6745) /* 0.273291844 */, 18 }, /* 4380 */ { MAD_F(0x045fbe87) /* 0.273375060 */, 18 }, /* 4381 */ { MAD_F(0x046015cb) /* 0.273458283 */, 18 }, /* 4382 */ { MAD_F(0x04606d10) /* 0.273541511 */, 18 }, /* 4383 */ { MAD_F(0x0460c457) /* 0.273624747 */, 18 }, /* 4384 */ { MAD_F(0x04611ba0) /* 0.273707988 */, 18 }, /* 4385 */ { MAD_F(0x046172eb) /* 0.273791236 */, 18 }, /* 4386 */ { MAD_F(0x0461ca37) /* 0.273874490 */, 18 }, /* 4387 */ { MAD_F(0x04622185) /* 0.273957750 */, 18 }, /* 4388 */ { MAD_F(0x046278d5) /* 0.274041017 */, 18 }, /* 4389 */ { MAD_F(0x0462d026) /* 0.274124290 */, 18 }, /* 4390 */ { MAD_F(0x0463277a) /* 0.274207569 */, 18 }, /* 4391 */ { MAD_F(0x04637ece) /* 0.274290855 */, 18 }, /* 4392 */ { MAD_F(0x0463d625) /* 0.274374147 */, 18 }, /* 4393 */ { MAD_F(0x04642d7d) /* 0.274457445 */, 18 }, /* 4394 */ { MAD_F(0x046484d7) /* 0.274540749 */, 18 }, /* 4395 */ { MAD_F(0x0464dc33) /* 0.274624060 */, 18 }, /* 4396 */ { MAD_F(0x04653390) /* 0.274707378 */, 18 }, /* 4397 */ { MAD_F(0x04658aef) /* 0.274790701 */, 18 }, /* 4398 */ { MAD_F(0x0465e250) /* 0.274874031 */, 18 }, /* 4399 */ { MAD_F(0x046639b2) /* 0.274957367 */, 18 }, /* 4400 */ { MAD_F(0x04669116) /* 0.275040710 */, 18 }, /* 4401 */ { MAD_F(0x0466e87c) /* 0.275124059 */, 18 }, /* 4402 */ { MAD_F(0x04673fe3) /* 0.275207414 */, 18 }, /* 4403 */ { MAD_F(0x0467974d) /* 0.275290775 */, 18 }, /* 4404 */ { MAD_F(0x0467eeb7) /* 0.275374143 */, 18 }, /* 4405 */ { MAD_F(0x04684624) /* 0.275457517 */, 18 }, /* 4406 */ { MAD_F(0x04689d92) /* 0.275540897 */, 18 }, /* 4407 */ { MAD_F(0x0468f502) /* 0.275624284 */, 18 }, /* 4408 */ { MAD_F(0x04694c74) /* 0.275707677 */, 18 }, /* 4409 */ { MAD_F(0x0469a3e7) /* 0.275791076 */, 18 }, /* 4410 */ { MAD_F(0x0469fb5c) /* 0.275874482 */, 18 }, /* 4411 */ { MAD_F(0x046a52d3) /* 0.275957894 */, 18 }, /* 4412 */ { MAD_F(0x046aaa4b) /* 0.276041312 */, 18 }, /* 4413 */ { MAD_F(0x046b01c5) /* 0.276124737 */, 18 }, /* 4414 */ { MAD_F(0x046b5941) /* 0.276208167 */, 18 }, /* 4415 */ { MAD_F(0x046bb0bf) /* 0.276291605 */, 18 }, /* 4416 */ { MAD_F(0x046c083e) /* 0.276375048 */, 18 }, /* 4417 */ { MAD_F(0x046c5fbf) /* 0.276458498 */, 18 }, /* 4418 */ { MAD_F(0x046cb741) /* 0.276541954 */, 18 }, /* 4419 */ { MAD_F(0x046d0ec5) /* 0.276625416 */, 18 }, /* 4420 */ { MAD_F(0x046d664b) /* 0.276708885 */, 18 }, /* 4421 */ { MAD_F(0x046dbdd3) /* 0.276792360 */, 18 }, /* 4422 */ { MAD_F(0x046e155c) /* 0.276875841 */, 18 }, /* 4423 */ { MAD_F(0x046e6ce7) /* 0.276959328 */, 18 }, /* 4424 */ { MAD_F(0x046ec474) /* 0.277042822 */, 18 }, /* 4425 */ { MAD_F(0x046f1c02) /* 0.277126322 */, 18 }, /* 4426 */ { MAD_F(0x046f7392) /* 0.277209829 */, 18 }, /* 4427 */ { MAD_F(0x046fcb24) /* 0.277293341 */, 18 }, /* 4428 */ { MAD_F(0x047022b8) /* 0.277376860 */, 18 }, /* 4429 */ { MAD_F(0x04707a4d) /* 0.277460385 */, 18 }, /* 4430 */ { MAD_F(0x0470d1e4) /* 0.277543917 */, 18 }, /* 4431 */ { MAD_F(0x0471297c) /* 0.277627455 */, 18 }, /* 4432 */ { MAD_F(0x04718116) /* 0.277710999 */, 18 }, /* 4433 */ { MAD_F(0x0471d8b2) /* 0.277794549 */, 18 }, /* 4434 */ { MAD_F(0x04723050) /* 0.277878106 */, 18 }, /* 4435 */ { MAD_F(0x047287ef) /* 0.277961669 */, 18 }, /* 4436 */ { MAD_F(0x0472df90) /* 0.278045238 */, 18 }, /* 4437 */ { MAD_F(0x04733733) /* 0.278128813 */, 18 }, /* 4438 */ { MAD_F(0x04738ed7) /* 0.278212395 */, 18 }, /* 4439 */ { MAD_F(0x0473e67d) /* 0.278295983 */, 18 }, /* 4440 */ { MAD_F(0x04743e25) /* 0.278379578 */, 18 }, /* 4441 */ { MAD_F(0x047495ce) /* 0.278463178 */, 18 }, /* 4442 */ { MAD_F(0x0474ed79) /* 0.278546785 */, 18 }, /* 4443 */ { MAD_F(0x04754526) /* 0.278630398 */, 18 }, /* 4444 */ { MAD_F(0x04759cd4) /* 0.278714018 */, 18 }, /* 4445 */ { MAD_F(0x0475f484) /* 0.278797643 */, 18 }, /* 4446 */ { MAD_F(0x04764c36) /* 0.278881275 */, 18 }, /* 4447 */ { MAD_F(0x0476a3ea) /* 0.278964914 */, 18 }, /* 4448 */ { MAD_F(0x0476fb9f) /* 0.279048558 */, 18 }, /* 4449 */ { MAD_F(0x04775356) /* 0.279132209 */, 18 }, /* 4450 */ { MAD_F(0x0477ab0e) /* 0.279215866 */, 18 }, /* 4451 */ { MAD_F(0x047802c8) /* 0.279299529 */, 18 }, /* 4452 */ { MAD_F(0x04785a84) /* 0.279383199 */, 18 }, /* 4453 */ { MAD_F(0x0478b242) /* 0.279466875 */, 18 }, /* 4454 */ { MAD_F(0x04790a01) /* 0.279550557 */, 18 }, /* 4455 */ { MAD_F(0x047961c2) /* 0.279634245 */, 18 }, /* 4456 */ { MAD_F(0x0479b984) /* 0.279717940 */, 18 }, /* 4457 */ { MAD_F(0x047a1149) /* 0.279801641 */, 18 }, /* 4458 */ { MAD_F(0x047a690f) /* 0.279885348 */, 18 }, /* 4459 */ { MAD_F(0x047ac0d6) /* 0.279969061 */, 18 }, /* 4460 */ { MAD_F(0x047b18a0) /* 0.280052781 */, 18 }, /* 4461 */ { MAD_F(0x047b706b) /* 0.280136507 */, 18 }, /* 4462 */ { MAD_F(0x047bc837) /* 0.280220239 */, 18 }, /* 4463 */ { MAD_F(0x047c2006) /* 0.280303978 */, 18 }, /* 4464 */ { MAD_F(0x047c77d6) /* 0.280387722 */, 18 }, /* 4465 */ { MAD_F(0x047ccfa8) /* 0.280471473 */, 18 }, /* 4466 */ { MAD_F(0x047d277b) /* 0.280555230 */, 18 }, /* 4467 */ { MAD_F(0x047d7f50) /* 0.280638994 */, 18 }, /* 4468 */ { MAD_F(0x047dd727) /* 0.280722764 */, 18 }, /* 4469 */ { MAD_F(0x047e2eff) /* 0.280806540 */, 18 }, /* 4470 */ { MAD_F(0x047e86d9) /* 0.280890322 */, 18 }, /* 4471 */ { MAD_F(0x047edeb5) /* 0.280974110 */, 18 }, /* 4472 */ { MAD_F(0x047f3693) /* 0.281057905 */, 18 }, /* 4473 */ { MAD_F(0x047f8e72) /* 0.281141706 */, 18 }, /* 4474 */ { MAD_F(0x047fe653) /* 0.281225513 */, 18 }, /* 4475 */ { MAD_F(0x04803e35) /* 0.281309326 */, 18 }, /* 4476 */ { MAD_F(0x04809619) /* 0.281393146 */, 18 }, /* 4477 */ { MAD_F(0x0480edff) /* 0.281476972 */, 18 }, /* 4478 */ { MAD_F(0x048145e7) /* 0.281560804 */, 18 }, /* 4479 */ { MAD_F(0x04819dd0) /* 0.281644643 */, 18 }, /* 4480 */ { MAD_F(0x0481f5bb) /* 0.281728487 */, 18 }, /* 4481 */ { MAD_F(0x04824da7) /* 0.281812338 */, 18 }, /* 4482 */ { MAD_F(0x0482a595) /* 0.281896195 */, 18 }, /* 4483 */ { MAD_F(0x0482fd85) /* 0.281980059 */, 18 }, /* 4484 */ { MAD_F(0x04835577) /* 0.282063928 */, 18 }, /* 4485 */ { MAD_F(0x0483ad6a) /* 0.282147804 */, 18 }, /* 4486 */ { MAD_F(0x0484055f) /* 0.282231686 */, 18 }, /* 4487 */ { MAD_F(0x04845d56) /* 0.282315574 */, 18 }, /* 4488 */ { MAD_F(0x0484b54e) /* 0.282399469 */, 18 }, /* 4489 */ { MAD_F(0x04850d48) /* 0.282483370 */, 18 }, /* 4490 */ { MAD_F(0x04856544) /* 0.282567277 */, 18 }, /* 4491 */ { MAD_F(0x0485bd41) /* 0.282651190 */, 18 }, /* 4492 */ { MAD_F(0x04861540) /* 0.282735109 */, 18 }, /* 4493 */ { MAD_F(0x04866d40) /* 0.282819035 */, 18 }, /* 4494 */ { MAD_F(0x0486c543) /* 0.282902967 */, 18 }, /* 4495 */ { MAD_F(0x04871d47) /* 0.282986905 */, 18 }, /* 4496 */ { MAD_F(0x0487754c) /* 0.283070849 */, 18 }, /* 4497 */ { MAD_F(0x0487cd54) /* 0.283154800 */, 18 }, /* 4498 */ { MAD_F(0x0488255d) /* 0.283238757 */, 18 }, /* 4499 */ { MAD_F(0x04887d67) /* 0.283322720 */, 18 }, /* 4500 */ { MAD_F(0x0488d574) /* 0.283406689 */, 18 }, /* 4501 */ { MAD_F(0x04892d82) /* 0.283490665 */, 18 }, /* 4502 */ { MAD_F(0x04898591) /* 0.283574646 */, 18 }, /* 4503 */ { MAD_F(0x0489dda3) /* 0.283658634 */, 18 }, /* 4504 */ { MAD_F(0x048a35b6) /* 0.283742628 */, 18 }, /* 4505 */ { MAD_F(0x048a8dca) /* 0.283826629 */, 18 }, /* 4506 */ { MAD_F(0x048ae5e1) /* 0.283910635 */, 18 }, /* 4507 */ { MAD_F(0x048b3df9) /* 0.283994648 */, 18 }, /* 4508 */ { MAD_F(0x048b9612) /* 0.284078667 */, 18 }, /* 4509 */ { MAD_F(0x048bee2e) /* 0.284162692 */, 18 }, /* 4510 */ { MAD_F(0x048c464b) /* 0.284246723 */, 18 }, /* 4511 */ { MAD_F(0x048c9e69) /* 0.284330761 */, 18 }, /* 4512 */ { MAD_F(0x048cf68a) /* 0.284414805 */, 18 }, /* 4513 */ { MAD_F(0x048d4eac) /* 0.284498855 */, 18 }, /* 4514 */ { MAD_F(0x048da6cf) /* 0.284582911 */, 18 }, /* 4515 */ { MAD_F(0x048dfef5) /* 0.284666974 */, 18 }, /* 4516 */ { MAD_F(0x048e571c) /* 0.284751042 */, 18 }, /* 4517 */ { MAD_F(0x048eaf44) /* 0.284835117 */, 18 }, /* 4518 */ { MAD_F(0x048f076f) /* 0.284919198 */, 18 }, /* 4519 */ { MAD_F(0x048f5f9b) /* 0.285003285 */, 18 }, /* 4520 */ { MAD_F(0x048fb7c8) /* 0.285087379 */, 18 }, /* 4521 */ { MAD_F(0x04900ff8) /* 0.285171479 */, 18 }, /* 4522 */ { MAD_F(0x04906829) /* 0.285255584 */, 18 }, /* 4523 */ { MAD_F(0x0490c05b) /* 0.285339697 */, 18 }, /* 4524 */ { MAD_F(0x04911890) /* 0.285423815 */, 18 }, /* 4525 */ { MAD_F(0x049170c6) /* 0.285507939 */, 18 }, /* 4526 */ { MAD_F(0x0491c8fd) /* 0.285592070 */, 18 }, /* 4527 */ { MAD_F(0x04922137) /* 0.285676207 */, 18 }, /* 4528 */ { MAD_F(0x04927972) /* 0.285760350 */, 18 }, /* 4529 */ { MAD_F(0x0492d1ae) /* 0.285844499 */, 18 }, /* 4530 */ { MAD_F(0x049329ed) /* 0.285928655 */, 18 }, /* 4531 */ { MAD_F(0x0493822c) /* 0.286012816 */, 18 }, /* 4532 */ { MAD_F(0x0493da6e) /* 0.286096984 */, 18 }, /* 4533 */ { MAD_F(0x049432b1) /* 0.286181158 */, 18 }, /* 4534 */ { MAD_F(0x04948af6) /* 0.286265338 */, 18 }, /* 4535 */ { MAD_F(0x0494e33d) /* 0.286349525 */, 18 }, /* 4536 */ { MAD_F(0x04953b85) /* 0.286433717 */, 18 }, /* 4537 */ { MAD_F(0x049593cf) /* 0.286517916 */, 18 }, /* 4538 */ { MAD_F(0x0495ec1b) /* 0.286602121 */, 18 }, /* 4539 */ { MAD_F(0x04964468) /* 0.286686332 */, 18 }, /* 4540 */ { MAD_F(0x04969cb7) /* 0.286770550 */, 18 }, /* 4541 */ { MAD_F(0x0496f508) /* 0.286854773 */, 18 }, /* 4542 */ { MAD_F(0x04974d5a) /* 0.286939003 */, 18 }, /* 4543 */ { MAD_F(0x0497a5ae) /* 0.287023239 */, 18 }, /* 4544 */ { MAD_F(0x0497fe03) /* 0.287107481 */, 18 }, /* 4545 */ { MAD_F(0x0498565a) /* 0.287191729 */, 18 }, /* 4546 */ { MAD_F(0x0498aeb3) /* 0.287275983 */, 18 }, /* 4547 */ { MAD_F(0x0499070e) /* 0.287360244 */, 18 }, /* 4548 */ { MAD_F(0x04995f6a) /* 0.287444511 */, 18 }, /* 4549 */ { MAD_F(0x0499b7c8) /* 0.287528784 */, 18 }, /* 4550 */ { MAD_F(0x049a1027) /* 0.287613063 */, 18 }, /* 4551 */ { MAD_F(0x049a6889) /* 0.287697348 */, 18 }, /* 4552 */ { MAD_F(0x049ac0eb) /* 0.287781640 */, 18 }, /* 4553 */ { MAD_F(0x049b1950) /* 0.287865937 */, 18 }, /* 4554 */ { MAD_F(0x049b71b6) /* 0.287950241 */, 18 }, /* 4555 */ { MAD_F(0x049bca1e) /* 0.288034551 */, 18 }, /* 4556 */ { MAD_F(0x049c2287) /* 0.288118867 */, 18 }, /* 4557 */ { MAD_F(0x049c7af2) /* 0.288203190 */, 18 }, /* 4558 */ { MAD_F(0x049cd35f) /* 0.288287518 */, 18 }, /* 4559 */ { MAD_F(0x049d2bce) /* 0.288371853 */, 18 }, /* 4560 */ { MAD_F(0x049d843e) /* 0.288456194 */, 18 }, /* 4561 */ { MAD_F(0x049ddcaf) /* 0.288540541 */, 18 }, /* 4562 */ { MAD_F(0x049e3523) /* 0.288624894 */, 18 }, /* 4563 */ { MAD_F(0x049e8d98) /* 0.288709253 */, 18 }, /* 4564 */ { MAD_F(0x049ee60e) /* 0.288793619 */, 18 }, /* 4565 */ { MAD_F(0x049f3e87) /* 0.288877990 */, 18 }, /* 4566 */ { MAD_F(0x049f9701) /* 0.288962368 */, 18 }, /* 4567 */ { MAD_F(0x049fef7c) /* 0.289046752 */, 18 }, /* 4568 */ { MAD_F(0x04a047fa) /* 0.289131142 */, 18 }, /* 4569 */ { MAD_F(0x04a0a079) /* 0.289215538 */, 18 }, /* 4570 */ { MAD_F(0x04a0f8f9) /* 0.289299941 */, 18 }, /* 4571 */ { MAD_F(0x04a1517c) /* 0.289384349 */, 18 }, /* 4572 */ { MAD_F(0x04a1a9ff) /* 0.289468764 */, 18 }, /* 4573 */ { MAD_F(0x04a20285) /* 0.289553185 */, 18 }, /* 4574 */ { MAD_F(0x04a25b0c) /* 0.289637612 */, 18 }, /* 4575 */ { MAD_F(0x04a2b395) /* 0.289722045 */, 18 }, /* 4576 */ { MAD_F(0x04a30c20) /* 0.289806485 */, 18 }, /* 4577 */ { MAD_F(0x04a364ac) /* 0.289890930 */, 18 }, /* 4578 */ { MAD_F(0x04a3bd3a) /* 0.289975382 */, 18 }, /* 4579 */ { MAD_F(0x04a415c9) /* 0.290059840 */, 18 }, /* 4580 */ { MAD_F(0x04a46e5a) /* 0.290144304 */, 18 }, /* 4581 */ { MAD_F(0x04a4c6ed) /* 0.290228774 */, 18 }, /* 4582 */ { MAD_F(0x04a51f81) /* 0.290313250 */, 18 }, /* 4583 */ { MAD_F(0x04a57818) /* 0.290397733 */, 18 }, /* 4584 */ { MAD_F(0x04a5d0af) /* 0.290482221 */, 18 }, /* 4585 */ { MAD_F(0x04a62949) /* 0.290566716 */, 18 }, /* 4586 */ { MAD_F(0x04a681e4) /* 0.290651217 */, 18 }, /* 4587 */ { MAD_F(0x04a6da80) /* 0.290735724 */, 18 }, /* 4588 */ { MAD_F(0x04a7331f) /* 0.290820237 */, 18 }, /* 4589 */ { MAD_F(0x04a78bbf) /* 0.290904756 */, 18 }, /* 4590 */ { MAD_F(0x04a7e460) /* 0.290989281 */, 18 }, /* 4591 */ { MAD_F(0x04a83d03) /* 0.291073813 */, 18 }, /* 4592 */ { MAD_F(0x04a895a8) /* 0.291158351 */, 18 }, /* 4593 */ { MAD_F(0x04a8ee4f) /* 0.291242894 */, 18 }, /* 4594 */ { MAD_F(0x04a946f7) /* 0.291327444 */, 18 }, /* 4595 */ { MAD_F(0x04a99fa1) /* 0.291412001 */, 18 }, /* 4596 */ { MAD_F(0x04a9f84c) /* 0.291496563 */, 18 }, /* 4597 */ { MAD_F(0x04aa50fa) /* 0.291581131 */, 18 }, /* 4598 */ { MAD_F(0x04aaa9a8) /* 0.291665706 */, 18 }, /* 4599 */ { MAD_F(0x04ab0259) /* 0.291750286 */, 18 }, /* 4600 */ { MAD_F(0x04ab5b0b) /* 0.291834873 */, 18 }, /* 4601 */ { MAD_F(0x04abb3bf) /* 0.291919466 */, 18 }, /* 4602 */ { MAD_F(0x04ac0c74) /* 0.292004065 */, 18 }, /* 4603 */ { MAD_F(0x04ac652b) /* 0.292088670 */, 18 }, /* 4604 */ { MAD_F(0x04acbde4) /* 0.292173281 */, 18 }, /* 4605 */ { MAD_F(0x04ad169e) /* 0.292257899 */, 18 }, /* 4606 */ { MAD_F(0x04ad6f5a) /* 0.292342522 */, 18 }, /* 4607 */ { MAD_F(0x04adc818) /* 0.292427152 */, 18 }, /* 4608 */ { MAD_F(0x04ae20d7) /* 0.292511788 */, 18 }, /* 4609 */ { MAD_F(0x04ae7998) /* 0.292596430 */, 18 }, /* 4610 */ { MAD_F(0x04aed25a) /* 0.292681078 */, 18 }, /* 4611 */ { MAD_F(0x04af2b1e) /* 0.292765732 */, 18 }, /* 4612 */ { MAD_F(0x04af83e4) /* 0.292850392 */, 18 }, /* 4613 */ { MAD_F(0x04afdcac) /* 0.292935058 */, 18 }, /* 4614 */ { MAD_F(0x04b03575) /* 0.293019731 */, 18 }, /* 4615 */ { MAD_F(0x04b08e40) /* 0.293104409 */, 18 }, /* 4616 */ { MAD_F(0x04b0e70c) /* 0.293189094 */, 18 }, /* 4617 */ { MAD_F(0x04b13fda) /* 0.293273785 */, 18 }, /* 4618 */ { MAD_F(0x04b198aa) /* 0.293358482 */, 18 }, /* 4619 */ { MAD_F(0x04b1f17b) /* 0.293443185 */, 18 }, /* 4620 */ { MAD_F(0x04b24a4e) /* 0.293527894 */, 18 }, /* 4621 */ { MAD_F(0x04b2a322) /* 0.293612609 */, 18 }, /* 4622 */ { MAD_F(0x04b2fbf9) /* 0.293697331 */, 18 }, /* 4623 */ { MAD_F(0x04b354d1) /* 0.293782058 */, 18 }, /* 4624 */ { MAD_F(0x04b3adaa) /* 0.293866792 */, 18 }, /* 4625 */ { MAD_F(0x04b40685) /* 0.293951532 */, 18 }, /* 4626 */ { MAD_F(0x04b45f62) /* 0.294036278 */, 18 }, /* 4627 */ { MAD_F(0x04b4b840) /* 0.294121029 */, 18 }, /* 4628 */ { MAD_F(0x04b51120) /* 0.294205788 */, 18 }, /* 4629 */ { MAD_F(0x04b56a02) /* 0.294290552 */, 18 }, /* 4630 */ { MAD_F(0x04b5c2e6) /* 0.294375322 */, 18 }, /* 4631 */ { MAD_F(0x04b61bcb) /* 0.294460098 */, 18 }, /* 4632 */ { MAD_F(0x04b674b1) /* 0.294544881 */, 18 }, /* 4633 */ { MAD_F(0x04b6cd99) /* 0.294629669 */, 18 }, /* 4634 */ { MAD_F(0x04b72683) /* 0.294714464 */, 18 }, /* 4635 */ { MAD_F(0x04b77f6f) /* 0.294799265 */, 18 }, /* 4636 */ { MAD_F(0x04b7d85c) /* 0.294884072 */, 18 }, /* 4637 */ { MAD_F(0x04b8314b) /* 0.294968885 */, 18 }, /* 4638 */ { MAD_F(0x04b88a3b) /* 0.295053704 */, 18 }, /* 4639 */ { MAD_F(0x04b8e32d) /* 0.295138529 */, 18 }, /* 4640 */ { MAD_F(0x04b93c21) /* 0.295223360 */, 18 }, /* 4641 */ { MAD_F(0x04b99516) /* 0.295308197 */, 18 }, /* 4642 */ { MAD_F(0x04b9ee0d) /* 0.295393041 */, 18 }, /* 4643 */ { MAD_F(0x04ba4706) /* 0.295477890 */, 18 }, /* 4644 */ { MAD_F(0x04baa000) /* 0.295562746 */, 18 }, /* 4645 */ { MAD_F(0x04baf8fc) /* 0.295647608 */, 18 }, /* 4646 */ { MAD_F(0x04bb51fa) /* 0.295732476 */, 18 }, /* 4647 */ { MAD_F(0x04bbaaf9) /* 0.295817349 */, 18 }, /* 4648 */ { MAD_F(0x04bc03fa) /* 0.295902229 */, 18 }, /* 4649 */ { MAD_F(0x04bc5cfc) /* 0.295987115 */, 18 }, /* 4650 */ { MAD_F(0x04bcb600) /* 0.296072008 */, 18 }, /* 4651 */ { MAD_F(0x04bd0f06) /* 0.296156906 */, 18 }, /* 4652 */ { MAD_F(0x04bd680d) /* 0.296241810 */, 18 }, /* 4653 */ { MAD_F(0x04bdc116) /* 0.296326721 */, 18 }, /* 4654 */ { MAD_F(0x04be1a21) /* 0.296411637 */, 18 }, /* 4655 */ { MAD_F(0x04be732d) /* 0.296496560 */, 18 }, /* 4656 */ { MAD_F(0x04becc3b) /* 0.296581488 */, 18 }, /* 4657 */ { MAD_F(0x04bf254a) /* 0.296666423 */, 18 }, /* 4658 */ { MAD_F(0x04bf7e5b) /* 0.296751364 */, 18 }, /* 4659 */ { MAD_F(0x04bfd76e) /* 0.296836311 */, 18 }, /* 4660 */ { MAD_F(0x04c03083) /* 0.296921264 */, 18 }, /* 4661 */ { MAD_F(0x04c08999) /* 0.297006223 */, 18 }, /* 4662 */ { MAD_F(0x04c0e2b0) /* 0.297091188 */, 18 }, /* 4663 */ { MAD_F(0x04c13bca) /* 0.297176159 */, 18 }, /* 4664 */ { MAD_F(0x04c194e4) /* 0.297261136 */, 18 }, /* 4665 */ { MAD_F(0x04c1ee01) /* 0.297346120 */, 18 }, /* 4666 */ { MAD_F(0x04c2471f) /* 0.297431109 */, 18 }, /* 4667 */ { MAD_F(0x04c2a03f) /* 0.297516105 */, 18 }, /* 4668 */ { MAD_F(0x04c2f960) /* 0.297601106 */, 18 }, /* 4669 */ { MAD_F(0x04c35283) /* 0.297686114 */, 18 }, /* 4670 */ { MAD_F(0x04c3aba8) /* 0.297771128 */, 18 }, /* 4671 */ { MAD_F(0x04c404ce) /* 0.297856147 */, 18 }, /* 4672 */ { MAD_F(0x04c45df6) /* 0.297941173 */, 18 }, /* 4673 */ { MAD_F(0x04c4b720) /* 0.298026205 */, 18 }, /* 4674 */ { MAD_F(0x04c5104b) /* 0.298111243 */, 18 }, /* 4675 */ { MAD_F(0x04c56978) /* 0.298196287 */, 18 }, /* 4676 */ { MAD_F(0x04c5c2a7) /* 0.298281337 */, 18 }, /* 4677 */ { MAD_F(0x04c61bd7) /* 0.298366393 */, 18 }, /* 4678 */ { MAD_F(0x04c67508) /* 0.298451456 */, 18 }, /* 4679 */ { MAD_F(0x04c6ce3c) /* 0.298536524 */, 18 }, /* 4680 */ { MAD_F(0x04c72771) /* 0.298621598 */, 18 }, /* 4681 */ { MAD_F(0x04c780a7) /* 0.298706679 */, 18 }, /* 4682 */ { MAD_F(0x04c7d9df) /* 0.298791765 */, 18 }, /* 4683 */ { MAD_F(0x04c83319) /* 0.298876858 */, 18 }, /* 4684 */ { MAD_F(0x04c88c55) /* 0.298961956 */, 18 }, /* 4685 */ { MAD_F(0x04c8e592) /* 0.299047061 */, 18 }, /* 4686 */ { MAD_F(0x04c93ed1) /* 0.299132172 */, 18 }, /* 4687 */ { MAD_F(0x04c99811) /* 0.299217288 */, 18 }, /* 4688 */ { MAD_F(0x04c9f153) /* 0.299302411 */, 18 }, /* 4689 */ { MAD_F(0x04ca4a97) /* 0.299387540 */, 18 }, /* 4690 */ { MAD_F(0x04caa3dc) /* 0.299472675 */, 18 }, /* 4691 */ { MAD_F(0x04cafd23) /* 0.299557816 */, 18 }, /* 4692 */ { MAD_F(0x04cb566b) /* 0.299642963 */, 18 }, /* 4693 */ { MAD_F(0x04cbafb5) /* 0.299728116 */, 18 }, /* 4694 */ { MAD_F(0x04cc0901) /* 0.299813275 */, 18 }, /* 4695 */ { MAD_F(0x04cc624e) /* 0.299898440 */, 18 }, /* 4696 */ { MAD_F(0x04ccbb9d) /* 0.299983611 */, 18 }, /* 4697 */ { MAD_F(0x04cd14ee) /* 0.300068789 */, 18 }, /* 4698 */ { MAD_F(0x04cd6e40) /* 0.300153972 */, 18 }, /* 4699 */ { MAD_F(0x04cdc794) /* 0.300239161 */, 18 }, /* 4700 */ { MAD_F(0x04ce20e9) /* 0.300324357 */, 18 }, /* 4701 */ { MAD_F(0x04ce7a40) /* 0.300409558 */, 18 }, /* 4702 */ { MAD_F(0x04ced399) /* 0.300494765 */, 18 }, /* 4703 */ { MAD_F(0x04cf2cf3) /* 0.300579979 */, 18 }, /* 4704 */ { MAD_F(0x04cf864f) /* 0.300665198 */, 18 }, /* 4705 */ { MAD_F(0x04cfdfad) /* 0.300750424 */, 18 }, /* 4706 */ { MAD_F(0x04d0390c) /* 0.300835656 */, 18 }, /* 4707 */ { MAD_F(0x04d0926d) /* 0.300920893 */, 18 }, /* 4708 */ { MAD_F(0x04d0ebcf) /* 0.301006137 */, 18 }, /* 4709 */ { MAD_F(0x04d14533) /* 0.301091387 */, 18 }, /* 4710 */ { MAD_F(0x04d19e99) /* 0.301176643 */, 18 }, /* 4711 */ { MAD_F(0x04d1f800) /* 0.301261904 */, 18 }, /* 4712 */ { MAD_F(0x04d25169) /* 0.301347172 */, 18 }, /* 4713 */ { MAD_F(0x04d2aad4) /* 0.301432446 */, 18 }, /* 4714 */ { MAD_F(0x04d30440) /* 0.301517726 */, 18 }, /* 4715 */ { MAD_F(0x04d35dae) /* 0.301603012 */, 18 }, /* 4716 */ { MAD_F(0x04d3b71d) /* 0.301688304 */, 18 }, /* 4717 */ { MAD_F(0x04d4108e) /* 0.301773602 */, 18 }, /* 4718 */ { MAD_F(0x04d46a01) /* 0.301858906 */, 18 }, /* 4719 */ { MAD_F(0x04d4c375) /* 0.301944216 */, 18 }, /* 4720 */ { MAD_F(0x04d51ceb) /* 0.302029532 */, 18 }, /* 4721 */ { MAD_F(0x04d57662) /* 0.302114854 */, 18 }, /* 4722 */ { MAD_F(0x04d5cfdb) /* 0.302200182 */, 18 }, /* 4723 */ { MAD_F(0x04d62956) /* 0.302285516 */, 18 }, /* 4724 */ { MAD_F(0x04d682d2) /* 0.302370856 */, 18 }, /* 4725 */ { MAD_F(0x04d6dc50) /* 0.302456203 */, 18 }, /* 4726 */ { MAD_F(0x04d735d0) /* 0.302541555 */, 18 }, /* 4727 */ { MAD_F(0x04d78f51) /* 0.302626913 */, 18 }, /* 4728 */ { MAD_F(0x04d7e8d4) /* 0.302712277 */, 18 }, /* 4729 */ { MAD_F(0x04d84258) /* 0.302797648 */, 18 }, /* 4730 */ { MAD_F(0x04d89bde) /* 0.302883024 */, 18 }, /* 4731 */ { MAD_F(0x04d8f566) /* 0.302968406 */, 18 }, /* 4732 */ { MAD_F(0x04d94eef) /* 0.303053794 */, 18 }, /* 4733 */ { MAD_F(0x04d9a87a) /* 0.303139189 */, 18 }, /* 4734 */ { MAD_F(0x04da0207) /* 0.303224589 */, 18 }, /* 4735 */ { MAD_F(0x04da5b95) /* 0.303309995 */, 18 }, /* 4736 */ { MAD_F(0x04dab524) /* 0.303395408 */, 18 }, /* 4737 */ { MAD_F(0x04db0eb6) /* 0.303480826 */, 18 }, /* 4738 */ { MAD_F(0x04db6849) /* 0.303566251 */, 18 }, /* 4739 */ { MAD_F(0x04dbc1dd) /* 0.303651681 */, 18 }, /* 4740 */ { MAD_F(0x04dc1b73) /* 0.303737117 */, 18 }, /* 4741 */ { MAD_F(0x04dc750b) /* 0.303822560 */, 18 }, /* 4742 */ { MAD_F(0x04dccea5) /* 0.303908008 */, 18 }, /* 4743 */ { MAD_F(0x04dd2840) /* 0.303993463 */, 18 }, /* 4744 */ { MAD_F(0x04dd81dc) /* 0.304078923 */, 18 }, /* 4745 */ { MAD_F(0x04dddb7a) /* 0.304164390 */, 18 }, /* 4746 */ { MAD_F(0x04de351a) /* 0.304249862 */, 18 }, /* 4747 */ { MAD_F(0x04de8ebc) /* 0.304335340 */, 18 }, /* 4748 */ { MAD_F(0x04dee85f) /* 0.304420825 */, 18 }, /* 4749 */ { MAD_F(0x04df4203) /* 0.304506315 */, 18 }, /* 4750 */ { MAD_F(0x04df9baa) /* 0.304591812 */, 18 }, /* 4751 */ { MAD_F(0x04dff552) /* 0.304677314 */, 18 }, /* 4752 */ { MAD_F(0x04e04efb) /* 0.304762823 */, 18 }, /* 4753 */ { MAD_F(0x04e0a8a6) /* 0.304848337 */, 18 }, /* 4754 */ { MAD_F(0x04e10253) /* 0.304933858 */, 18 }, /* 4755 */ { MAD_F(0x04e15c01) /* 0.305019384 */, 18 }, /* 4756 */ { MAD_F(0x04e1b5b1) /* 0.305104917 */, 18 }, /* 4757 */ { MAD_F(0x04e20f63) /* 0.305190455 */, 18 }, /* 4758 */ { MAD_F(0x04e26916) /* 0.305275999 */, 18 }, /* 4759 */ { MAD_F(0x04e2c2cb) /* 0.305361550 */, 18 }, /* 4760 */ { MAD_F(0x04e31c81) /* 0.305447106 */, 18 }, /* 4761 */ { MAD_F(0x04e37639) /* 0.305532669 */, 18 }, /* 4762 */ { MAD_F(0x04e3cff3) /* 0.305618237 */, 18 }, /* 4763 */ { MAD_F(0x04e429ae) /* 0.305703811 */, 18 }, /* 4764 */ { MAD_F(0x04e4836b) /* 0.305789392 */, 18 }, /* 4765 */ { MAD_F(0x04e4dd29) /* 0.305874978 */, 18 }, /* 4766 */ { MAD_F(0x04e536e9) /* 0.305960571 */, 18 }, /* 4767 */ { MAD_F(0x04e590ab) /* 0.306046169 */, 18 }, /* 4768 */ { MAD_F(0x04e5ea6e) /* 0.306131773 */, 18 }, /* 4769 */ { MAD_F(0x04e64433) /* 0.306217383 */, 18 }, /* 4770 */ { MAD_F(0x04e69df9) /* 0.306303000 */, 18 }, /* 4771 */ { MAD_F(0x04e6f7c1) /* 0.306388622 */, 18 }, /* 4772 */ { MAD_F(0x04e7518b) /* 0.306474250 */, 18 }, /* 4773 */ { MAD_F(0x04e7ab56) /* 0.306559885 */, 18 }, /* 4774 */ { MAD_F(0x04e80523) /* 0.306645525 */, 18 }, /* 4775 */ { MAD_F(0x04e85ef2) /* 0.306731171 */, 18 }, /* 4776 */ { MAD_F(0x04e8b8c2) /* 0.306816823 */, 18 }, /* 4777 */ { MAD_F(0x04e91293) /* 0.306902481 */, 18 }, /* 4778 */ { MAD_F(0x04e96c67) /* 0.306988145 */, 18 }, /* 4779 */ { MAD_F(0x04e9c63b) /* 0.307073816 */, 18 }, /* 4780 */ { MAD_F(0x04ea2012) /* 0.307159492 */, 18 }, /* 4781 */ { MAD_F(0x04ea79ea) /* 0.307245174 */, 18 }, /* 4782 */ { MAD_F(0x04ead3c4) /* 0.307330862 */, 18 }, /* 4783 */ { MAD_F(0x04eb2d9f) /* 0.307416556 */, 18 }, /* 4784 */ { MAD_F(0x04eb877c) /* 0.307502256 */, 18 }, /* 4785 */ { MAD_F(0x04ebe15b) /* 0.307587962 */, 18 }, /* 4786 */ { MAD_F(0x04ec3b3b) /* 0.307673674 */, 18 }, /* 4787 */ { MAD_F(0x04ec951c) /* 0.307759392 */, 18 }, /* 4788 */ { MAD_F(0x04ecef00) /* 0.307845115 */, 18 }, /* 4789 */ { MAD_F(0x04ed48e5) /* 0.307930845 */, 18 }, /* 4790 */ { MAD_F(0x04eda2cb) /* 0.308016581 */, 18 }, /* 4791 */ { MAD_F(0x04edfcb3) /* 0.308102323 */, 18 }, /* 4792 */ { MAD_F(0x04ee569d) /* 0.308188071 */, 18 }, /* 4793 */ { MAD_F(0x04eeb088) /* 0.308273824 */, 18 }, /* 4794 */ { MAD_F(0x04ef0a75) /* 0.308359584 */, 18 }, /* 4795 */ { MAD_F(0x04ef6464) /* 0.308445350 */, 18 }, /* 4796 */ { MAD_F(0x04efbe54) /* 0.308531121 */, 18 }, /* 4797 */ { MAD_F(0x04f01846) /* 0.308616899 */, 18 }, /* 4798 */ { MAD_F(0x04f07239) /* 0.308702682 */, 18 }, /* 4799 */ { MAD_F(0x04f0cc2e) /* 0.308788472 */, 18 }, /* 4800 */ { MAD_F(0x04f12624) /* 0.308874267 */, 18 }, /* 4801 */ { MAD_F(0x04f1801d) /* 0.308960068 */, 18 }, /* 4802 */ { MAD_F(0x04f1da16) /* 0.309045876 */, 18 }, /* 4803 */ { MAD_F(0x04f23412) /* 0.309131689 */, 18 }, /* 4804 */ { MAD_F(0x04f28e0f) /* 0.309217508 */, 18 }, /* 4805 */ { MAD_F(0x04f2e80d) /* 0.309303334 */, 18 }, /* 4806 */ { MAD_F(0x04f3420d) /* 0.309389165 */, 18 }, /* 4807 */ { MAD_F(0x04f39c0f) /* 0.309475002 */, 18 }, /* 4808 */ { MAD_F(0x04f3f612) /* 0.309560845 */, 18 }, /* 4809 */ { MAD_F(0x04f45017) /* 0.309646694 */, 18 }, /* 4810 */ { MAD_F(0x04f4aa1e) /* 0.309732549 */, 18 }, /* 4811 */ { MAD_F(0x04f50426) /* 0.309818410 */, 18 }, /* 4812 */ { MAD_F(0x04f55e30) /* 0.309904277 */, 18 }, /* 4813 */ { MAD_F(0x04f5b83b) /* 0.309990150 */, 18 }, /* 4814 */ { MAD_F(0x04f61248) /* 0.310076028 */, 18 }, /* 4815 */ { MAD_F(0x04f66c56) /* 0.310161913 */, 18 }, /* 4816 */ { MAD_F(0x04f6c666) /* 0.310247804 */, 18 }, /* 4817 */ { MAD_F(0x04f72078) /* 0.310333700 */, 18 }, /* 4818 */ { MAD_F(0x04f77a8b) /* 0.310419603 */, 18 }, /* 4819 */ { MAD_F(0x04f7d4a0) /* 0.310505511 */, 18 }, /* 4820 */ { MAD_F(0x04f82eb7) /* 0.310591426 */, 18 }, /* 4821 */ { MAD_F(0x04f888cf) /* 0.310677346 */, 18 }, /* 4822 */ { MAD_F(0x04f8e2e9) /* 0.310763272 */, 18 }, /* 4823 */ { MAD_F(0x04f93d04) /* 0.310849205 */, 18 }, /* 4824 */ { MAD_F(0x04f99721) /* 0.310935143 */, 18 }, /* 4825 */ { MAD_F(0x04f9f13f) /* 0.311021087 */, 18 }, /* 4826 */ { MAD_F(0x04fa4b5f) /* 0.311107037 */, 18 }, /* 4827 */ { MAD_F(0x04faa581) /* 0.311192993 */, 18 }, /* 4828 */ { MAD_F(0x04faffa4) /* 0.311278955 */, 18 }, /* 4829 */ { MAD_F(0x04fb59c9) /* 0.311364923 */, 18 }, /* 4830 */ { MAD_F(0x04fbb3ef) /* 0.311450897 */, 18 }, /* 4831 */ { MAD_F(0x04fc0e17) /* 0.311536877 */, 18 }, /* 4832 */ { MAD_F(0x04fc6841) /* 0.311622862 */, 18 }, /* 4833 */ { MAD_F(0x04fcc26c) /* 0.311708854 */, 18 }, /* 4834 */ { MAD_F(0x04fd1c99) /* 0.311794851 */, 18 }, /* 4835 */ { MAD_F(0x04fd76c7) /* 0.311880855 */, 18 }, /* 4836 */ { MAD_F(0x04fdd0f7) /* 0.311966864 */, 18 }, /* 4837 */ { MAD_F(0x04fe2b29) /* 0.312052880 */, 18 }, /* 4838 */ { MAD_F(0x04fe855c) /* 0.312138901 */, 18 }, /* 4839 */ { MAD_F(0x04fedf91) /* 0.312224928 */, 18 }, /* 4840 */ { MAD_F(0x04ff39c7) /* 0.312310961 */, 18 }, /* 4841 */ { MAD_F(0x04ff93ff) /* 0.312397000 */, 18 }, /* 4842 */ { MAD_F(0x04ffee38) /* 0.312483045 */, 18 }, /* 4843 */ { MAD_F(0x05004874) /* 0.312569096 */, 18 }, /* 4844 */ { MAD_F(0x0500a2b0) /* 0.312655153 */, 18 }, /* 4845 */ { MAD_F(0x0500fcef) /* 0.312741216 */, 18 }, /* 4846 */ { MAD_F(0x0501572e) /* 0.312827284 */, 18 }, /* 4847 */ { MAD_F(0x0501b170) /* 0.312913359 */, 18 }, /* 4848 */ { MAD_F(0x05020bb3) /* 0.312999439 */, 18 }, /* 4849 */ { MAD_F(0x050265f8) /* 0.313085526 */, 18 }, /* 4850 */ { MAD_F(0x0502c03e) /* 0.313171618 */, 18 }, /* 4851 */ { MAD_F(0x05031a86) /* 0.313257716 */, 18 }, /* 4852 */ { MAD_F(0x050374cf) /* 0.313343820 */, 18 }, /* 4853 */ { MAD_F(0x0503cf1a) /* 0.313429931 */, 18 }, /* 4854 */ { MAD_F(0x05042967) /* 0.313516047 */, 18 }, /* 4855 */ { MAD_F(0x050483b5) /* 0.313602168 */, 18 }, /* 4856 */ { MAD_F(0x0504de05) /* 0.313688296 */, 18 }, /* 4857 */ { MAD_F(0x05053856) /* 0.313774430 */, 18 }, /* 4858 */ { MAD_F(0x050592a9) /* 0.313860570 */, 18 }, /* 4859 */ { MAD_F(0x0505ecfd) /* 0.313946715 */, 18 }, /* 4860 */ { MAD_F(0x05064754) /* 0.314032867 */, 18 }, /* 4861 */ { MAD_F(0x0506a1ab) /* 0.314119024 */, 18 }, /* 4862 */ { MAD_F(0x0506fc04) /* 0.314205187 */, 18 }, /* 4863 */ { MAD_F(0x0507565f) /* 0.314291357 */, 18 }, /* 4864 */ { MAD_F(0x0507b0bc) /* 0.314377532 */, 18 }, /* 4865 */ { MAD_F(0x05080b1a) /* 0.314463713 */, 18 }, /* 4866 */ { MAD_F(0x05086579) /* 0.314549900 */, 18 }, /* 4867 */ { MAD_F(0x0508bfdb) /* 0.314636092 */, 18 }, /* 4868 */ { MAD_F(0x05091a3d) /* 0.314722291 */, 18 }, /* 4869 */ { MAD_F(0x050974a2) /* 0.314808496 */, 18 }, /* 4870 */ { MAD_F(0x0509cf08) /* 0.314894706 */, 18 }, /* 4871 */ { MAD_F(0x050a296f) /* 0.314980923 */, 18 }, /* 4872 */ { MAD_F(0x050a83d8) /* 0.315067145 */, 18 }, /* 4873 */ { MAD_F(0x050ade43) /* 0.315153373 */, 18 }, /* 4874 */ { MAD_F(0x050b38af) /* 0.315239607 */, 18 }, /* 4875 */ { MAD_F(0x050b931d) /* 0.315325847 */, 18 }, /* 4876 */ { MAD_F(0x050bed8d) /* 0.315412093 */, 18 }, /* 4877 */ { MAD_F(0x050c47fe) /* 0.315498345 */, 18 }, /* 4878 */ { MAD_F(0x050ca271) /* 0.315584603 */, 18 }, /* 4879 */ { MAD_F(0x050cfce5) /* 0.315670866 */, 18 }, /* 4880 */ { MAD_F(0x050d575b) /* 0.315757136 */, 18 }, /* 4881 */ { MAD_F(0x050db1d2) /* 0.315843411 */, 18 }, /* 4882 */ { MAD_F(0x050e0c4b) /* 0.315929693 */, 18 }, /* 4883 */ { MAD_F(0x050e66c5) /* 0.316015980 */, 18 }, /* 4884 */ { MAD_F(0x050ec141) /* 0.316102273 */, 18 }, /* 4885 */ { MAD_F(0x050f1bbf) /* 0.316188572 */, 18 }, /* 4886 */ { MAD_F(0x050f763e) /* 0.316274877 */, 18 }, /* 4887 */ { MAD_F(0x050fd0bf) /* 0.316361187 */, 18 }, /* 4888 */ { MAD_F(0x05102b42) /* 0.316447504 */, 18 }, /* 4889 */ { MAD_F(0x051085c6) /* 0.316533826 */, 18 }, /* 4890 */ { MAD_F(0x0510e04b) /* 0.316620155 */, 18 }, /* 4891 */ { MAD_F(0x05113ad3) /* 0.316706489 */, 18 }, /* 4892 */ { MAD_F(0x0511955b) /* 0.316792829 */, 18 }, /* 4893 */ { MAD_F(0x0511efe6) /* 0.316879175 */, 18 }, /* 4894 */ { MAD_F(0x05124a72) /* 0.316965527 */, 18 }, /* 4895 */ { MAD_F(0x0512a4ff) /* 0.317051885 */, 18 }, /* 4896 */ { MAD_F(0x0512ff8e) /* 0.317138249 */, 18 }, /* 4897 */ { MAD_F(0x05135a1f) /* 0.317224618 */, 18 }, /* 4898 */ { MAD_F(0x0513b4b1) /* 0.317310994 */, 18 }, /* 4899 */ { MAD_F(0x05140f45) /* 0.317397375 */, 18 }, /* 4900 */ { MAD_F(0x051469da) /* 0.317483762 */, 18 }, /* 4901 */ { MAD_F(0x0514c471) /* 0.317570155 */, 18 }, /* 4902 */ { MAD_F(0x05151f0a) /* 0.317656554 */, 18 }, /* 4903 */ { MAD_F(0x051579a4) /* 0.317742959 */, 18 }, /* 4904 */ { MAD_F(0x0515d440) /* 0.317829370 */, 18 }, /* 4905 */ { MAD_F(0x05162edd) /* 0.317915786 */, 18 }, /* 4906 */ { MAD_F(0x0516897c) /* 0.318002209 */, 18 }, /* 4907 */ { MAD_F(0x0516e41c) /* 0.318088637 */, 18 }, /* 4908 */ { MAD_F(0x05173ebe) /* 0.318175071 */, 18 }, /* 4909 */ { MAD_F(0x05179962) /* 0.318261511 */, 18 }, /* 4910 */ { MAD_F(0x0517f407) /* 0.318347957 */, 18 }, /* 4911 */ { MAD_F(0x05184eae) /* 0.318434409 */, 18 }, /* 4912 */ { MAD_F(0x0518a956) /* 0.318520867 */, 18 }, /* 4913 */ { MAD_F(0x05190400) /* 0.318607330 */, 18 }, /* 4914 */ { MAD_F(0x05195eab) /* 0.318693800 */, 18 }, /* 4915 */ { MAD_F(0x0519b958) /* 0.318780275 */, 18 }, /* 4916 */ { MAD_F(0x051a1407) /* 0.318866756 */, 18 }, /* 4917 */ { MAD_F(0x051a6eb7) /* 0.318953243 */, 18 }, /* 4918 */ { MAD_F(0x051ac969) /* 0.319039736 */, 18 }, /* 4919 */ { MAD_F(0x051b241c) /* 0.319126235 */, 18 }, /* 4920 */ { MAD_F(0x051b7ed1) /* 0.319212739 */, 18 }, /* 4921 */ { MAD_F(0x051bd987) /* 0.319299250 */, 18 }, /* 4922 */ { MAD_F(0x051c3440) /* 0.319385766 */, 18 }, /* 4923 */ { MAD_F(0x051c8ef9) /* 0.319472288 */, 18 }, /* 4924 */ { MAD_F(0x051ce9b4) /* 0.319558816 */, 18 }, /* 4925 */ { MAD_F(0x051d4471) /* 0.319645350 */, 18 }, /* 4926 */ { MAD_F(0x051d9f2f) /* 0.319731890 */, 18 }, /* 4927 */ { MAD_F(0x051df9ef) /* 0.319818435 */, 18 }, /* 4928 */ { MAD_F(0x051e54b1) /* 0.319904987 */, 18 }, /* 4929 */ { MAD_F(0x051eaf74) /* 0.319991544 */, 18 }, /* 4930 */ { MAD_F(0x051f0a38) /* 0.320078107 */, 18 }, /* 4931 */ { MAD_F(0x051f64ff) /* 0.320164676 */, 18 }, /* 4932 */ { MAD_F(0x051fbfc6) /* 0.320251251 */, 18 }, /* 4933 */ { MAD_F(0x05201a90) /* 0.320337832 */, 18 }, /* 4934 */ { MAD_F(0x0520755b) /* 0.320424419 */, 18 }, /* 4935 */ { MAD_F(0x0520d027) /* 0.320511011 */, 18 }, /* 4936 */ { MAD_F(0x05212af5) /* 0.320597609 */, 18 }, /* 4937 */ { MAD_F(0x052185c5) /* 0.320684213 */, 18 }, /* 4938 */ { MAD_F(0x0521e096) /* 0.320770823 */, 18 }, /* 4939 */ { MAD_F(0x05223b69) /* 0.320857439 */, 18 }, /* 4940 */ { MAD_F(0x0522963d) /* 0.320944061 */, 18 }, /* 4941 */ { MAD_F(0x0522f113) /* 0.321030688 */, 18 }, /* 4942 */ { MAD_F(0x05234bea) /* 0.321117322 */, 18 }, /* 4943 */ { MAD_F(0x0523a6c3) /* 0.321203961 */, 18 }, /* 4944 */ { MAD_F(0x0524019e) /* 0.321290606 */, 18 }, /* 4945 */ { MAD_F(0x05245c7a) /* 0.321377257 */, 18 }, /* 4946 */ { MAD_F(0x0524b758) /* 0.321463913 */, 18 }, /* 4947 */ { MAD_F(0x05251237) /* 0.321550576 */, 18 }, /* 4948 */ { MAD_F(0x05256d18) /* 0.321637244 */, 18 }, /* 4949 */ { MAD_F(0x0525c7fb) /* 0.321723919 */, 18 }, /* 4950 */ { MAD_F(0x052622df) /* 0.321810599 */, 18 }, /* 4951 */ { MAD_F(0x05267dc4) /* 0.321897285 */, 18 }, /* 4952 */ { MAD_F(0x0526d8ab) /* 0.321983976 */, 18 }, /* 4953 */ { MAD_F(0x05273394) /* 0.322070674 */, 18 }, /* 4954 */ { MAD_F(0x05278e7e) /* 0.322157377 */, 18 }, /* 4955 */ { MAD_F(0x0527e96a) /* 0.322244087 */, 18 }, /* 4956 */ { MAD_F(0x05284457) /* 0.322330802 */, 18 }, /* 4957 */ { MAD_F(0x05289f46) /* 0.322417523 */, 18 }, /* 4958 */ { MAD_F(0x0528fa37) /* 0.322504249 */, 18 }, /* 4959 */ { MAD_F(0x05295529) /* 0.322590982 */, 18 }, /* 4960 */ { MAD_F(0x0529b01d) /* 0.322677720 */, 18 }, /* 4961 */ { MAD_F(0x052a0b12) /* 0.322764465 */, 18 }, /* 4962 */ { MAD_F(0x052a6609) /* 0.322851215 */, 18 }, /* 4963 */ { MAD_F(0x052ac101) /* 0.322937971 */, 18 }, /* 4964 */ { MAD_F(0x052b1bfb) /* 0.323024732 */, 18 }, /* 4965 */ { MAD_F(0x052b76f7) /* 0.323111500 */, 18 }, /* 4966 */ { MAD_F(0x052bd1f4) /* 0.323198273 */, 18 }, /* 4967 */ { MAD_F(0x052c2cf2) /* 0.323285052 */, 18 }, /* 4968 */ { MAD_F(0x052c87f2) /* 0.323371837 */, 18 }, /* 4969 */ { MAD_F(0x052ce2f4) /* 0.323458628 */, 18 }, /* 4970 */ { MAD_F(0x052d3df7) /* 0.323545425 */, 18 }, /* 4971 */ { MAD_F(0x052d98fc) /* 0.323632227 */, 18 }, /* 4972 */ { MAD_F(0x052df403) /* 0.323719036 */, 18 }, /* 4973 */ { MAD_F(0x052e4f0b) /* 0.323805850 */, 18 }, /* 4974 */ { MAD_F(0x052eaa14) /* 0.323892670 */, 18 }, /* 4975 */ { MAD_F(0x052f051f) /* 0.323979496 */, 18 }, /* 4976 */ { MAD_F(0x052f602c) /* 0.324066327 */, 18 }, /* 4977 */ { MAD_F(0x052fbb3a) /* 0.324153165 */, 18 }, /* 4978 */ { MAD_F(0x0530164a) /* 0.324240008 */, 18 }, /* 4979 */ { MAD_F(0x0530715b) /* 0.324326857 */, 18 }, /* 4980 */ { MAD_F(0x0530cc6e) /* 0.324413712 */, 18 }, /* 4981 */ { MAD_F(0x05312783) /* 0.324500572 */, 18 }, /* 4982 */ { MAD_F(0x05318299) /* 0.324587439 */, 18 }, /* 4983 */ { MAD_F(0x0531ddb0) /* 0.324674311 */, 18 }, /* 4984 */ { MAD_F(0x053238ca) /* 0.324761189 */, 18 }, /* 4985 */ { MAD_F(0x053293e4) /* 0.324848073 */, 18 }, /* 4986 */ { MAD_F(0x0532ef01) /* 0.324934963 */, 18 }, /* 4987 */ { MAD_F(0x05334a1e) /* 0.325021858 */, 18 }, /* 4988 */ { MAD_F(0x0533a53e) /* 0.325108760 */, 18 }, /* 4989 */ { MAD_F(0x0534005f) /* 0.325195667 */, 18 }, /* 4990 */ { MAD_F(0x05345b81) /* 0.325282580 */, 18 }, /* 4991 */ { MAD_F(0x0534b6a5) /* 0.325369498 */, 18 }, /* 4992 */ { MAD_F(0x053511cb) /* 0.325456423 */, 18 }, /* 4993 */ { MAD_F(0x05356cf2) /* 0.325543353 */, 18 }, /* 4994 */ { MAD_F(0x0535c81b) /* 0.325630290 */, 18 }, /* 4995 */ { MAD_F(0x05362345) /* 0.325717232 */, 18 }, /* 4996 */ { MAD_F(0x05367e71) /* 0.325804179 */, 18 }, /* 4997 */ { MAD_F(0x0536d99f) /* 0.325891133 */, 18 }, /* 4998 */ { MAD_F(0x053734ce) /* 0.325978092 */, 18 }, /* 4999 */ { MAD_F(0x05378ffe) /* 0.326065057 */, 18 }, /* 5000 */ { MAD_F(0x0537eb30) /* 0.326152028 */, 18 }, /* 5001 */ { MAD_F(0x05384664) /* 0.326239005 */, 18 }, /* 5002 */ { MAD_F(0x0538a199) /* 0.326325988 */, 18 }, /* 5003 */ { MAD_F(0x0538fcd0) /* 0.326412976 */, 18 }, /* 5004 */ { MAD_F(0x05395808) /* 0.326499970 */, 18 }, /* 5005 */ { MAD_F(0x0539b342) /* 0.326586970 */, 18 }, /* 5006 */ { MAD_F(0x053a0e7d) /* 0.326673976 */, 18 }, /* 5007 */ { MAD_F(0x053a69ba) /* 0.326760988 */, 18 }, /* 5008 */ { MAD_F(0x053ac4f9) /* 0.326848005 */, 18 }, /* 5009 */ { MAD_F(0x053b2039) /* 0.326935028 */, 18 }, /* 5010 */ { MAD_F(0x053b7b7b) /* 0.327022057 */, 18 }, /* 5011 */ { MAD_F(0x053bd6be) /* 0.327109092 */, 18 }, /* 5012 */ { MAD_F(0x053c3203) /* 0.327196132 */, 18 }, /* 5013 */ { MAD_F(0x053c8d49) /* 0.327283178 */, 18 }, /* 5014 */ { MAD_F(0x053ce891) /* 0.327370231 */, 18 }, /* 5015 */ { MAD_F(0x053d43da) /* 0.327457288 */, 18 }, /* 5016 */ { MAD_F(0x053d9f25) /* 0.327544352 */, 18 }, /* 5017 */ { MAD_F(0x053dfa72) /* 0.327631421 */, 18 }, /* 5018 */ { MAD_F(0x053e55c0) /* 0.327718497 */, 18 }, /* 5019 */ { MAD_F(0x053eb10f) /* 0.327805578 */, 18 }, /* 5020 */ { MAD_F(0x053f0c61) /* 0.327892665 */, 18 }, /* 5021 */ { MAD_F(0x053f67b3) /* 0.327979757 */, 18 }, /* 5022 */ { MAD_F(0x053fc308) /* 0.328066855 */, 18 }, /* 5023 */ { MAD_F(0x05401e5e) /* 0.328153960 */, 18 }, /* 5024 */ { MAD_F(0x054079b5) /* 0.328241070 */, 18 }, /* 5025 */ { MAD_F(0x0540d50e) /* 0.328328185 */, 18 }, /* 5026 */ { MAD_F(0x05413068) /* 0.328415307 */, 18 }, /* 5027 */ { MAD_F(0x05418bc4) /* 0.328502434 */, 18 }, /* 5028 */ { MAD_F(0x0541e722) /* 0.328589567 */, 18 }, /* 5029 */ { MAD_F(0x05424281) /* 0.328676706 */, 18 }, /* 5030 */ { MAD_F(0x05429de2) /* 0.328763850 */, 18 }, /* 5031 */ { MAD_F(0x0542f944) /* 0.328851001 */, 18 }, /* 5032 */ { MAD_F(0x054354a8) /* 0.328938157 */, 18 }, /* 5033 */ { MAD_F(0x0543b00d) /* 0.329025319 */, 18 }, /* 5034 */ { MAD_F(0x05440b74) /* 0.329112486 */, 18 }, /* 5035 */ { MAD_F(0x054466dd) /* 0.329199660 */, 18 }, /* 5036 */ { MAD_F(0x0544c247) /* 0.329286839 */, 18 }, /* 5037 */ { MAD_F(0x05451db2) /* 0.329374024 */, 18 }, /* 5038 */ { MAD_F(0x0545791f) /* 0.329461215 */, 18 }, /* 5039 */ { MAD_F(0x0545d48e) /* 0.329548411 */, 18 }, /* 5040 */ { MAD_F(0x05462ffe) /* 0.329635614 */, 18 }, /* 5041 */ { MAD_F(0x05468b70) /* 0.329722822 */, 18 }, /* 5042 */ { MAD_F(0x0546e6e3) /* 0.329810036 */, 18 }, /* 5043 */ { MAD_F(0x05474258) /* 0.329897255 */, 18 }, /* 5044 */ { MAD_F(0x05479dce) /* 0.329984481 */, 18 }, /* 5045 */ { MAD_F(0x0547f946) /* 0.330071712 */, 18 }, /* 5046 */ { MAD_F(0x054854c0) /* 0.330158949 */, 18 }, /* 5047 */ { MAD_F(0x0548b03b) /* 0.330246191 */, 18 }, /* 5048 */ { MAD_F(0x05490bb7) /* 0.330333440 */, 18 }, /* 5049 */ { MAD_F(0x05496735) /* 0.330420694 */, 18 }, /* 5050 */ { MAD_F(0x0549c2b5) /* 0.330507954 */, 18 }, /* 5051 */ { MAD_F(0x054a1e36) /* 0.330595220 */, 18 }, /* 5052 */ { MAD_F(0x054a79b9) /* 0.330682491 */, 18 }, /* 5053 */ { MAD_F(0x054ad53d) /* 0.330769768 */, 18 }, /* 5054 */ { MAD_F(0x054b30c3) /* 0.330857051 */, 18 }, /* 5055 */ { MAD_F(0x054b8c4b) /* 0.330944340 */, 18 }, /* 5056 */ { MAD_F(0x054be7d4) /* 0.331031635 */, 18 }, /* 5057 */ { MAD_F(0x054c435e) /* 0.331118935 */, 18 }, /* 5058 */ { MAD_F(0x054c9eea) /* 0.331206241 */, 18 }, /* 5059 */ { MAD_F(0x054cfa78) /* 0.331293553 */, 18 }, /* 5060 */ { MAD_F(0x054d5607) /* 0.331380870 */, 18 }, /* 5061 */ { MAD_F(0x054db197) /* 0.331468193 */, 18 }, /* 5062 */ { MAD_F(0x054e0d2a) /* 0.331555522 */, 18 }, /* 5063 */ { MAD_F(0x054e68bd) /* 0.331642857 */, 18 }, /* 5064 */ { MAD_F(0x054ec453) /* 0.331730198 */, 18 }, /* 5065 */ { MAD_F(0x054f1fe9) /* 0.331817544 */, 18 }, /* 5066 */ { MAD_F(0x054f7b82) /* 0.331904896 */, 18 }, /* 5067 */ { MAD_F(0x054fd71c) /* 0.331992254 */, 18 }, /* 5068 */ { MAD_F(0x055032b7) /* 0.332079617 */, 18 }, /* 5069 */ { MAD_F(0x05508e54) /* 0.332166986 */, 18 }, /* 5070 */ { MAD_F(0x0550e9f3) /* 0.332254361 */, 18 }, /* 5071 */ { MAD_F(0x05514593) /* 0.332341742 */, 18 }, /* 5072 */ { MAD_F(0x0551a134) /* 0.332429129 */, 18 }, /* 5073 */ { MAD_F(0x0551fcd8) /* 0.332516521 */, 18 }, /* 5074 */ { MAD_F(0x0552587c) /* 0.332603919 */, 18 }, /* 5075 */ { MAD_F(0x0552b423) /* 0.332691323 */, 18 }, /* 5076 */ { MAD_F(0x05530fca) /* 0.332778732 */, 18 }, /* 5077 */ { MAD_F(0x05536b74) /* 0.332866147 */, 18 }, /* 5078 */ { MAD_F(0x0553c71f) /* 0.332953568 */, 18 }, /* 5079 */ { MAD_F(0x055422cb) /* 0.333040995 */, 18 }, /* 5080 */ { MAD_F(0x05547e79) /* 0.333128427 */, 18 }, /* 5081 */ { MAD_F(0x0554da29) /* 0.333215865 */, 18 }, /* 5082 */ { MAD_F(0x055535da) /* 0.333303309 */, 18 }, /* 5083 */ { MAD_F(0x0555918c) /* 0.333390759 */, 18 }, /* 5084 */ { MAD_F(0x0555ed40) /* 0.333478214 */, 18 }, /* 5085 */ { MAD_F(0x055648f6) /* 0.333565675 */, 18 }, /* 5086 */ { MAD_F(0x0556a4ad) /* 0.333653142 */, 18 }, /* 5087 */ { MAD_F(0x05570066) /* 0.333740615 */, 18 }, /* 5088 */ { MAD_F(0x05575c20) /* 0.333828093 */, 18 }, /* 5089 */ { MAD_F(0x0557b7dc) /* 0.333915577 */, 18 }, /* 5090 */ { MAD_F(0x05581399) /* 0.334003067 */, 18 }, /* 5091 */ { MAD_F(0x05586f58) /* 0.334090562 */, 18 }, /* 5092 */ { MAD_F(0x0558cb19) /* 0.334178063 */, 18 }, /* 5093 */ { MAD_F(0x055926db) /* 0.334265570 */, 18 }, /* 5094 */ { MAD_F(0x0559829e) /* 0.334353083 */, 18 }, /* 5095 */ { MAD_F(0x0559de63) /* 0.334440601 */, 18 }, /* 5096 */ { MAD_F(0x055a3a2a) /* 0.334528126 */, 18 }, /* 5097 */ { MAD_F(0x055a95f2) /* 0.334615655 */, 18 }, /* 5098 */ { MAD_F(0x055af1bb) /* 0.334703191 */, 18 }, /* 5099 */ { MAD_F(0x055b4d87) /* 0.334790732 */, 18 }, /* 5100 */ { MAD_F(0x055ba953) /* 0.334878279 */, 18 }, /* 5101 */ { MAD_F(0x055c0522) /* 0.334965832 */, 18 }, /* 5102 */ { MAD_F(0x055c60f1) /* 0.335053391 */, 18 }, /* 5103 */ { MAD_F(0x055cbcc3) /* 0.335140955 */, 18 }, /* 5104 */ { MAD_F(0x055d1896) /* 0.335228525 */, 18 }, /* 5105 */ { MAD_F(0x055d746a) /* 0.335316100 */, 18 }, /* 5106 */ { MAD_F(0x055dd040) /* 0.335403682 */, 18 }, /* 5107 */ { MAD_F(0x055e2c17) /* 0.335491269 */, 18 }, /* 5108 */ { MAD_F(0x055e87f0) /* 0.335578861 */, 18 }, /* 5109 */ { MAD_F(0x055ee3cb) /* 0.335666460 */, 18 }, /* 5110 */ { MAD_F(0x055f3fa7) /* 0.335754064 */, 18 }, /* 5111 */ { MAD_F(0x055f9b85) /* 0.335841674 */, 18 }, /* 5112 */ { MAD_F(0x055ff764) /* 0.335929290 */, 18 }, /* 5113 */ { MAD_F(0x05605344) /* 0.336016911 */, 18 }, /* 5114 */ { MAD_F(0x0560af27) /* 0.336104538 */, 18 }, /* 5115 */ { MAD_F(0x05610b0a) /* 0.336192171 */, 18 }, /* 5116 */ { MAD_F(0x056166f0) /* 0.336279809 */, 18 }, /* 5117 */ { MAD_F(0x0561c2d7) /* 0.336367453 */, 18 }, /* 5118 */ { MAD_F(0x05621ebf) /* 0.336455103 */, 18 }, /* 5119 */ { MAD_F(0x05627aa9) /* 0.336542759 */, 18 }, /* 5120 */ { MAD_F(0x0562d694) /* 0.336630420 */, 18 }, /* 5121 */ { MAD_F(0x05633281) /* 0.336718087 */, 18 }, /* 5122 */ { MAD_F(0x05638e70) /* 0.336805760 */, 18 }, /* 5123 */ { MAD_F(0x0563ea60) /* 0.336893439 */, 18 }, /* 5124 */ { MAD_F(0x05644651) /* 0.336981123 */, 18 }, /* 5125 */ { MAD_F(0x0564a244) /* 0.337068813 */, 18 }, /* 5126 */ { MAD_F(0x0564fe39) /* 0.337156508 */, 18 }, /* 5127 */ { MAD_F(0x05655a2f) /* 0.337244209 */, 18 }, /* 5128 */ { MAD_F(0x0565b627) /* 0.337331916 */, 18 }, /* 5129 */ { MAD_F(0x05661220) /* 0.337419629 */, 18 }, /* 5130 */ { MAD_F(0x05666e1a) /* 0.337507347 */, 18 }, /* 5131 */ { MAD_F(0x0566ca17) /* 0.337595071 */, 18 }, /* 5132 */ { MAD_F(0x05672614) /* 0.337682801 */, 18 }, /* 5133 */ { MAD_F(0x05678214) /* 0.337770537 */, 18 }, /* 5134 */ { MAD_F(0x0567de15) /* 0.337858278 */, 18 }, /* 5135 */ { MAD_F(0x05683a17) /* 0.337946025 */, 18 }, /* 5136 */ { MAD_F(0x0568961b) /* 0.338033777 */, 18 }, /* 5137 */ { MAD_F(0x0568f220) /* 0.338121535 */, 18 }, /* 5138 */ { MAD_F(0x05694e27) /* 0.338209299 */, 18 }, /* 5139 */ { MAD_F(0x0569aa30) /* 0.338297069 */, 18 }, /* 5140 */ { MAD_F(0x056a063a) /* 0.338384844 */, 18 }, /* 5141 */ { MAD_F(0x056a6245) /* 0.338472625 */, 18 }, /* 5142 */ { MAD_F(0x056abe52) /* 0.338560412 */, 18 }, /* 5143 */ { MAD_F(0x056b1a61) /* 0.338648204 */, 18 }, /* 5144 */ { MAD_F(0x056b7671) /* 0.338736002 */, 18 }, /* 5145 */ { MAD_F(0x056bd283) /* 0.338823806 */, 18 }, /* 5146 */ { MAD_F(0x056c2e96) /* 0.338911616 */, 18 }, /* 5147 */ { MAD_F(0x056c8aab) /* 0.338999431 */, 18 }, /* 5148 */ { MAD_F(0x056ce6c1) /* 0.339087252 */, 18 }, /* 5149 */ { MAD_F(0x056d42d9) /* 0.339175078 */, 18 }, /* 5150 */ { MAD_F(0x056d9ef2) /* 0.339262910 */, 18 }, /* 5151 */ { MAD_F(0x056dfb0d) /* 0.339350748 */, 18 }, /* 5152 */ { MAD_F(0x056e5729) /* 0.339438592 */, 18 }, /* 5153 */ { MAD_F(0x056eb347) /* 0.339526441 */, 18 }, /* 5154 */ { MAD_F(0x056f0f66) /* 0.339614296 */, 18 }, /* 5155 */ { MAD_F(0x056f6b87) /* 0.339702157 */, 18 }, /* 5156 */ { MAD_F(0x056fc7aa) /* 0.339790023 */, 18 }, /* 5157 */ { MAD_F(0x057023cd) /* 0.339877895 */, 18 }, /* 5158 */ { MAD_F(0x05707ff3) /* 0.339965773 */, 18 }, /* 5159 */ { MAD_F(0x0570dc1a) /* 0.340053656 */, 18 }, /* 5160 */ { MAD_F(0x05713843) /* 0.340141545 */, 18 }, /* 5161 */ { MAD_F(0x0571946d) /* 0.340229440 */, 18 }, /* 5162 */ { MAD_F(0x0571f098) /* 0.340317340 */, 18 }, /* 5163 */ { MAD_F(0x05724cc5) /* 0.340405246 */, 18 }, /* 5164 */ { MAD_F(0x0572a8f4) /* 0.340493158 */, 18 }, /* 5165 */ { MAD_F(0x05730524) /* 0.340581075 */, 18 }, /* 5166 */ { MAD_F(0x05736156) /* 0.340668999 */, 18 }, /* 5167 */ { MAD_F(0x0573bd89) /* 0.340756927 */, 18 }, /* 5168 */ { MAD_F(0x057419be) /* 0.340844862 */, 18 }, /* 5169 */ { MAD_F(0x057475f4) /* 0.340932802 */, 18 }, /* 5170 */ { MAD_F(0x0574d22c) /* 0.341020748 */, 18 }, /* 5171 */ { MAD_F(0x05752e65) /* 0.341108699 */, 18 }, /* 5172 */ { MAD_F(0x05758aa0) /* 0.341196656 */, 18 }, /* 5173 */ { MAD_F(0x0575e6dc) /* 0.341284619 */, 18 }, /* 5174 */ { MAD_F(0x0576431a) /* 0.341372587 */, 18 }, /* 5175 */ { MAD_F(0x05769f59) /* 0.341460562 */, 18 }, /* 5176 */ { MAD_F(0x0576fb9a) /* 0.341548541 */, 18 }, /* 5177 */ { MAD_F(0x057757dd) /* 0.341636527 */, 18 }, /* 5178 */ { MAD_F(0x0577b421) /* 0.341724518 */, 18 }, /* 5179 */ { MAD_F(0x05781066) /* 0.341812515 */, 18 }, /* 5180 */ { MAD_F(0x05786cad) /* 0.341900517 */, 18 }, /* 5181 */ { MAD_F(0x0578c8f5) /* 0.341988525 */, 18 }, /* 5182 */ { MAD_F(0x0579253f) /* 0.342076539 */, 18 }, /* 5183 */ { MAD_F(0x0579818b) /* 0.342164558 */, 18 }, /* 5184 */ { MAD_F(0x0579ddd8) /* 0.342252584 */, 18 }, /* 5185 */ { MAD_F(0x057a3a27) /* 0.342340614 */, 18 }, /* 5186 */ { MAD_F(0x057a9677) /* 0.342428651 */, 18 }, /* 5187 */ { MAD_F(0x057af2c8) /* 0.342516693 */, 18 }, /* 5188 */ { MAD_F(0x057b4f1c) /* 0.342604741 */, 18 }, /* 5189 */ { MAD_F(0x057bab70) /* 0.342692794 */, 18 }, /* 5190 */ { MAD_F(0x057c07c6) /* 0.342780853 */, 18 }, /* 5191 */ { MAD_F(0x057c641e) /* 0.342868918 */, 18 }, /* 5192 */ { MAD_F(0x057cc077) /* 0.342956988 */, 18 }, /* 5193 */ { MAD_F(0x057d1cd2) /* 0.343045064 */, 18 }, /* 5194 */ { MAD_F(0x057d792e) /* 0.343133146 */, 18 }, /* 5195 */ { MAD_F(0x057dd58c) /* 0.343221233 */, 18 }, /* 5196 */ { MAD_F(0x057e31eb) /* 0.343309326 */, 18 }, /* 5197 */ { MAD_F(0x057e8e4c) /* 0.343397425 */, 18 }, /* 5198 */ { MAD_F(0x057eeaae) /* 0.343485529 */, 18 }, /* 5199 */ { MAD_F(0x057f4712) /* 0.343573639 */, 18 }, /* 5200 */ { MAD_F(0x057fa378) /* 0.343661754 */, 18 }, /* 5201 */ { MAD_F(0x057fffde) /* 0.343749876 */, 18 }, /* 5202 */ { MAD_F(0x05805c47) /* 0.343838003 */, 18 }, /* 5203 */ { MAD_F(0x0580b8b1) /* 0.343926135 */, 18 }, /* 5204 */ { MAD_F(0x0581151c) /* 0.344014273 */, 18 }, /* 5205 */ { MAD_F(0x05817189) /* 0.344102417 */, 18 }, /* 5206 */ { MAD_F(0x0581cdf7) /* 0.344190566 */, 18 }, /* 5207 */ { MAD_F(0x05822a67) /* 0.344278722 */, 18 }, /* 5208 */ { MAD_F(0x058286d9) /* 0.344366882 */, 18 }, /* 5209 */ { MAD_F(0x0582e34c) /* 0.344455049 */, 18 }, /* 5210 */ { MAD_F(0x05833fc0) /* 0.344543221 */, 18 }, /* 5211 */ { MAD_F(0x05839c36) /* 0.344631398 */, 18 }, /* 5212 */ { MAD_F(0x0583f8ae) /* 0.344719582 */, 18 }, /* 5213 */ { MAD_F(0x05845527) /* 0.344807771 */, 18 }, /* 5214 */ { MAD_F(0x0584b1a1) /* 0.344895965 */, 18 }, /* 5215 */ { MAD_F(0x05850e1e) /* 0.344984165 */, 18 }, /* 5216 */ { MAD_F(0x05856a9b) /* 0.345072371 */, 18 }, /* 5217 */ { MAD_F(0x0585c71a) /* 0.345160583 */, 18 }, /* 5218 */ { MAD_F(0x0586239b) /* 0.345248800 */, 18 }, /* 5219 */ { MAD_F(0x0586801d) /* 0.345337023 */, 18 }, /* 5220 */ { MAD_F(0x0586dca1) /* 0.345425251 */, 18 }, /* 5221 */ { MAD_F(0x05873926) /* 0.345513485 */, 18 }, /* 5222 */ { MAD_F(0x058795ac) /* 0.345601725 */, 18 }, /* 5223 */ { MAD_F(0x0587f235) /* 0.345689970 */, 18 }, /* 5224 */ { MAD_F(0x05884ebe) /* 0.345778221 */, 18 }, /* 5225 */ { MAD_F(0x0588ab49) /* 0.345866478 */, 18 }, /* 5226 */ { MAD_F(0x058907d6) /* 0.345954740 */, 18 }, /* 5227 */ { MAD_F(0x05896464) /* 0.346043008 */, 18 }, /* 5228 */ { MAD_F(0x0589c0f4) /* 0.346131281 */, 18 }, /* 5229 */ { MAD_F(0x058a1d85) /* 0.346219560 */, 18 }, /* 5230 */ { MAD_F(0x058a7a18) /* 0.346307845 */, 18 }, /* 5231 */ { MAD_F(0x058ad6ac) /* 0.346396135 */, 18 }, /* 5232 */ { MAD_F(0x058b3342) /* 0.346484431 */, 18 }, /* 5233 */ { MAD_F(0x058b8fd9) /* 0.346572733 */, 18 }, /* 5234 */ { MAD_F(0x058bec72) /* 0.346661040 */, 18 }, /* 5235 */ { MAD_F(0x058c490c) /* 0.346749353 */, 18 }, /* 5236 */ { MAD_F(0x058ca5a8) /* 0.346837671 */, 18 }, /* 5237 */ { MAD_F(0x058d0246) /* 0.346925996 */, 18 }, /* 5238 */ { MAD_F(0x058d5ee4) /* 0.347014325 */, 18 }, /* 5239 */ { MAD_F(0x058dbb85) /* 0.347102661 */, 18 }, /* 5240 */ { MAD_F(0x058e1827) /* 0.347191002 */, 18 }, /* 5241 */ { MAD_F(0x058e74ca) /* 0.347279348 */, 18 }, /* 5242 */ { MAD_F(0x058ed16f) /* 0.347367700 */, 18 }, /* 5243 */ { MAD_F(0x058f2e15) /* 0.347456058 */, 18 }, /* 5244 */ { MAD_F(0x058f8abd) /* 0.347544422 */, 18 }, /* 5245 */ { MAD_F(0x058fe766) /* 0.347632791 */, 18 }, /* 5246 */ { MAD_F(0x05904411) /* 0.347721165 */, 18 }, /* 5247 */ { MAD_F(0x0590a0be) /* 0.347809546 */, 18 }, /* 5248 */ { MAD_F(0x0590fd6c) /* 0.347897931 */, 18 }, /* 5249 */ { MAD_F(0x05915a1b) /* 0.347986323 */, 18 }, /* 5250 */ { MAD_F(0x0591b6cc) /* 0.348074720 */, 18 }, /* 5251 */ { MAD_F(0x0592137e) /* 0.348163123 */, 18 }, /* 5252 */ { MAD_F(0x05927032) /* 0.348251531 */, 18 }, /* 5253 */ { MAD_F(0x0592cce8) /* 0.348339945 */, 18 }, /* 5254 */ { MAD_F(0x0593299f) /* 0.348428365 */, 18 }, /* 5255 */ { MAD_F(0x05938657) /* 0.348516790 */, 18 }, /* 5256 */ { MAD_F(0x0593e311) /* 0.348605221 */, 18 }, /* 5257 */ { MAD_F(0x05943fcd) /* 0.348693657 */, 18 }, /* 5258 */ { MAD_F(0x05949c8a) /* 0.348782099 */, 18 }, /* 5259 */ { MAD_F(0x0594f948) /* 0.348870547 */, 18 }, /* 5260 */ { MAD_F(0x05955608) /* 0.348959000 */, 18 }, /* 5261 */ { MAD_F(0x0595b2ca) /* 0.349047459 */, 18 }, /* 5262 */ { MAD_F(0x05960f8c) /* 0.349135923 */, 18 }, /* 5263 */ { MAD_F(0x05966c51) /* 0.349224393 */, 18 }, /* 5264 */ { MAD_F(0x0596c917) /* 0.349312869 */, 18 }, /* 5265 */ { MAD_F(0x059725de) /* 0.349401350 */, 18 }, /* 5266 */ { MAD_F(0x059782a7) /* 0.349489837 */, 18 }, /* 5267 */ { MAD_F(0x0597df72) /* 0.349578329 */, 18 }, /* 5268 */ { MAD_F(0x05983c3e) /* 0.349666827 */, 18 }, /* 5269 */ { MAD_F(0x0598990c) /* 0.349755331 */, 18 }, /* 5270 */ { MAD_F(0x0598f5db) /* 0.349843840 */, 18 }, /* 5271 */ { MAD_F(0x059952ab) /* 0.349932355 */, 18 }, /* 5272 */ { MAD_F(0x0599af7d) /* 0.350020876 */, 18 }, /* 5273 */ { MAD_F(0x059a0c51) /* 0.350109402 */, 18 }, /* 5274 */ { MAD_F(0x059a6926) /* 0.350197933 */, 18 }, /* 5275 */ { MAD_F(0x059ac5fc) /* 0.350286470 */, 18 }, /* 5276 */ { MAD_F(0x059b22d4) /* 0.350375013 */, 18 }, /* 5277 */ { MAD_F(0x059b7fae) /* 0.350463562 */, 18 }, /* 5278 */ { MAD_F(0x059bdc89) /* 0.350552116 */, 18 }, /* 5279 */ { MAD_F(0x059c3965) /* 0.350640675 */, 18 }, /* 5280 */ { MAD_F(0x059c9643) /* 0.350729240 */, 18 }, /* 5281 */ { MAD_F(0x059cf323) /* 0.350817811 */, 18 }, /* 5282 */ { MAD_F(0x059d5004) /* 0.350906388 */, 18 }, /* 5283 */ { MAD_F(0x059dace6) /* 0.350994970 */, 18 }, /* 5284 */ { MAD_F(0x059e09cb) /* 0.351083557 */, 18 }, /* 5285 */ { MAD_F(0x059e66b0) /* 0.351172150 */, 18 }, /* 5286 */ { MAD_F(0x059ec397) /* 0.351260749 */, 18 }, /* 5287 */ { MAD_F(0x059f2080) /* 0.351349353 */, 18 }, /* 5288 */ { MAD_F(0x059f7d6a) /* 0.351437963 */, 18 }, /* 5289 */ { MAD_F(0x059fda55) /* 0.351526579 */, 18 }, /* 5290 */ { MAD_F(0x05a03742) /* 0.351615200 */, 18 }, /* 5291 */ { MAD_F(0x05a09431) /* 0.351703827 */, 18 }, /* 5292 */ { MAD_F(0x05a0f121) /* 0.351792459 */, 18 }, /* 5293 */ { MAD_F(0x05a14e12) /* 0.351881097 */, 18 }, /* 5294 */ { MAD_F(0x05a1ab05) /* 0.351969740 */, 18 }, /* 5295 */ { MAD_F(0x05a207fa) /* 0.352058389 */, 18 }, /* 5296 */ { MAD_F(0x05a264f0) /* 0.352147044 */, 18 }, /* 5297 */ { MAD_F(0x05a2c1e7) /* 0.352235704 */, 18 }, /* 5298 */ { MAD_F(0x05a31ee1) /* 0.352324369 */, 18 }, /* 5299 */ { MAD_F(0x05a37bdb) /* 0.352413041 */, 18 }, /* 5300 */ { MAD_F(0x05a3d8d7) /* 0.352501718 */, 18 }, /* 5301 */ { MAD_F(0x05a435d5) /* 0.352590400 */, 18 }, /* 5302 */ { MAD_F(0x05a492d4) /* 0.352679088 */, 18 }, /* 5303 */ { MAD_F(0x05a4efd4) /* 0.352767782 */, 18 }, /* 5304 */ { MAD_F(0x05a54cd6) /* 0.352856481 */, 18 }, /* 5305 */ { MAD_F(0x05a5a9da) /* 0.352945186 */, 18 }, /* 5306 */ { MAD_F(0x05a606df) /* 0.353033896 */, 18 }, /* 5307 */ { MAD_F(0x05a663e5) /* 0.353122612 */, 18 }, /* 5308 */ { MAD_F(0x05a6c0ed) /* 0.353211333 */, 18 }, /* 5309 */ { MAD_F(0x05a71df7) /* 0.353300061 */, 18 }, /* 5310 */ { MAD_F(0x05a77b02) /* 0.353388793 */, 18 }, /* 5311 */ { MAD_F(0x05a7d80e) /* 0.353477531 */, 18 }, /* 5312 */ { MAD_F(0x05a8351c) /* 0.353566275 */, 18 }, /* 5313 */ { MAD_F(0x05a8922c) /* 0.353655024 */, 18 }, /* 5314 */ { MAD_F(0x05a8ef3c) /* 0.353743779 */, 18 }, /* 5315 */ { MAD_F(0x05a94c4f) /* 0.353832540 */, 18 }, /* 5316 */ { MAD_F(0x05a9a963) /* 0.353921306 */, 18 }, /* 5317 */ { MAD_F(0x05aa0678) /* 0.354010077 */, 18 }, /* 5318 */ { MAD_F(0x05aa638f) /* 0.354098855 */, 18 }, /* 5319 */ { MAD_F(0x05aac0a8) /* 0.354187637 */, 18 }, /* 5320 */ { MAD_F(0x05ab1dc2) /* 0.354276426 */, 18 }, /* 5321 */ { MAD_F(0x05ab7add) /* 0.354365220 */, 18 }, /* 5322 */ { MAD_F(0x05abd7fa) /* 0.354454019 */, 18 }, /* 5323 */ { MAD_F(0x05ac3518) /* 0.354542824 */, 18 }, /* 5324 */ { MAD_F(0x05ac9238) /* 0.354631635 */, 18 }, /* 5325 */ { MAD_F(0x05acef5a) /* 0.354720451 */, 18 }, /* 5326 */ { MAD_F(0x05ad4c7d) /* 0.354809272 */, 18 }, /* 5327 */ { MAD_F(0x05ada9a1) /* 0.354898100 */, 18 }, /* 5328 */ { MAD_F(0x05ae06c7) /* 0.354986932 */, 18 }, /* 5329 */ { MAD_F(0x05ae63ee) /* 0.355075771 */, 18 }, /* 5330 */ { MAD_F(0x05aec117) /* 0.355164615 */, 18 }, /* 5331 */ { MAD_F(0x05af1e41) /* 0.355253464 */, 18 }, /* 5332 */ { MAD_F(0x05af7b6d) /* 0.355342319 */, 18 }, /* 5333 */ { MAD_F(0x05afd89b) /* 0.355431180 */, 18 }, /* 5334 */ { MAD_F(0x05b035c9) /* 0.355520046 */, 18 }, /* 5335 */ { MAD_F(0x05b092fa) /* 0.355608917 */, 18 }, /* 5336 */ { MAD_F(0x05b0f02b) /* 0.355697795 */, 18 }, /* 5337 */ { MAD_F(0x05b14d5f) /* 0.355786677 */, 18 }, /* 5338 */ { MAD_F(0x05b1aa94) /* 0.355875566 */, 18 }, /* 5339 */ { MAD_F(0x05b207ca) /* 0.355964460 */, 18 }, /* 5340 */ { MAD_F(0x05b26502) /* 0.356053359 */, 18 }, /* 5341 */ { MAD_F(0x05b2c23b) /* 0.356142264 */, 18 }, /* 5342 */ { MAD_F(0x05b31f76) /* 0.356231175 */, 18 }, /* 5343 */ { MAD_F(0x05b37cb2) /* 0.356320091 */, 18 }, /* 5344 */ { MAD_F(0x05b3d9f0) /* 0.356409012 */, 18 }, /* 5345 */ { MAD_F(0x05b4372f) /* 0.356497940 */, 18 }, /* 5346 */ { MAD_F(0x05b4946f) /* 0.356586872 */, 18 }, /* 5347 */ { MAD_F(0x05b4f1b2) /* 0.356675811 */, 18 }, /* 5348 */ { MAD_F(0x05b54ef5) /* 0.356764754 */, 18 }, /* 5349 */ { MAD_F(0x05b5ac3a) /* 0.356853704 */, 18 }, /* 5350 */ { MAD_F(0x05b60981) /* 0.356942659 */, 18 }, /* 5351 */ { MAD_F(0x05b666c9) /* 0.357031619 */, 18 }, /* 5352 */ { MAD_F(0x05b6c413) /* 0.357120585 */, 18 }, /* 5353 */ { MAD_F(0x05b7215e) /* 0.357209557 */, 18 }, /* 5354 */ { MAD_F(0x05b77eab) /* 0.357298534 */, 18 }, /* 5355 */ { MAD_F(0x05b7dbf9) /* 0.357387516 */, 18 }, /* 5356 */ { MAD_F(0x05b83948) /* 0.357476504 */, 18 }, /* 5357 */ { MAD_F(0x05b89699) /* 0.357565498 */, 18 }, /* 5358 */ { MAD_F(0x05b8f3ec) /* 0.357654497 */, 18 }, /* 5359 */ { MAD_F(0x05b95140) /* 0.357743502 */, 18 }, /* 5360 */ { MAD_F(0x05b9ae95) /* 0.357832512 */, 18 }, /* 5361 */ { MAD_F(0x05ba0bec) /* 0.357921528 */, 18 }, /* 5362 */ { MAD_F(0x05ba6945) /* 0.358010550 */, 18 }, /* 5363 */ { MAD_F(0x05bac69f) /* 0.358099576 */, 18 }, /* 5364 */ { MAD_F(0x05bb23fa) /* 0.358188609 */, 18 }, /* 5365 */ { MAD_F(0x05bb8157) /* 0.358277647 */, 18 }, /* 5366 */ { MAD_F(0x05bbdeb6) /* 0.358366690 */, 18 }, /* 5367 */ { MAD_F(0x05bc3c16) /* 0.358455739 */, 18 }, /* 5368 */ { MAD_F(0x05bc9977) /* 0.358544794 */, 18 }, /* 5369 */ { MAD_F(0x05bcf6da) /* 0.358633854 */, 18 }, /* 5370 */ { MAD_F(0x05bd543e) /* 0.358722920 */, 18 }, /* 5371 */ { MAD_F(0x05bdb1a4) /* 0.358811991 */, 18 }, /* 5372 */ { MAD_F(0x05be0f0b) /* 0.358901067 */, 18 }, /* 5373 */ { MAD_F(0x05be6c74) /* 0.358990150 */, 18 }, /* 5374 */ { MAD_F(0x05bec9df) /* 0.359079237 */, 18 }, /* 5375 */ { MAD_F(0x05bf274a) /* 0.359168331 */, 18 }, /* 5376 */ { MAD_F(0x05bf84b8) /* 0.359257429 */, 18 }, /* 5377 */ { MAD_F(0x05bfe226) /* 0.359346534 */, 18 }, /* 5378 */ { MAD_F(0x05c03f97) /* 0.359435644 */, 18 }, /* 5379 */ { MAD_F(0x05c09d08) /* 0.359524759 */, 18 }, /* 5380 */ { MAD_F(0x05c0fa7c) /* 0.359613880 */, 18 }, /* 5381 */ { MAD_F(0x05c157f0) /* 0.359703006 */, 18 }, /* 5382 */ { MAD_F(0x05c1b566) /* 0.359792138 */, 18 }, /* 5383 */ { MAD_F(0x05c212de) /* 0.359881276 */, 18 }, /* 5384 */ { MAD_F(0x05c27057) /* 0.359970419 */, 18 }, /* 5385 */ { MAD_F(0x05c2cdd2) /* 0.360059567 */, 18 }, /* 5386 */ { MAD_F(0x05c32b4e) /* 0.360148721 */, 18 }, /* 5387 */ { MAD_F(0x05c388cb) /* 0.360237881 */, 18 }, /* 5388 */ { MAD_F(0x05c3e64b) /* 0.360327046 */, 18 }, /* 5389 */ { MAD_F(0x05c443cb) /* 0.360416216 */, 18 }, /* 5390 */ { MAD_F(0x05c4a14d) /* 0.360505392 */, 18 }, /* 5391 */ { MAD_F(0x05c4fed1) /* 0.360594574 */, 18 }, /* 5392 */ { MAD_F(0x05c55c56) /* 0.360683761 */, 18 }, /* 5393 */ { MAD_F(0x05c5b9dc) /* 0.360772953 */, 18 }, /* 5394 */ { MAD_F(0x05c61764) /* 0.360862152 */, 18 }, /* 5395 */ { MAD_F(0x05c674ed) /* 0.360951355 */, 18 }, /* 5396 */ { MAD_F(0x05c6d278) /* 0.361040564 */, 18 }, /* 5397 */ { MAD_F(0x05c73005) /* 0.361129779 */, 18 }, /* 5398 */ { MAD_F(0x05c78d93) /* 0.361218999 */, 18 }, /* 5399 */ { MAD_F(0x05c7eb22) /* 0.361308225 */, 18 }, /* 5400 */ { MAD_F(0x05c848b3) /* 0.361397456 */, 18 }, /* 5401 */ { MAD_F(0x05c8a645) /* 0.361486693 */, 18 }, /* 5402 */ { MAD_F(0x05c903d9) /* 0.361575935 */, 18 }, /* 5403 */ { MAD_F(0x05c9616e) /* 0.361665183 */, 18 }, /* 5404 */ { MAD_F(0x05c9bf05) /* 0.361754436 */, 18 }, /* 5405 */ { MAD_F(0x05ca1c9d) /* 0.361843695 */, 18 }, /* 5406 */ { MAD_F(0x05ca7a37) /* 0.361932959 */, 18 }, /* 5407 */ { MAD_F(0x05cad7d2) /* 0.362022229 */, 18 }, /* 5408 */ { MAD_F(0x05cb356e) /* 0.362111504 */, 18 }, /* 5409 */ { MAD_F(0x05cb930d) /* 0.362200785 */, 18 }, /* 5410 */ { MAD_F(0x05cbf0ac) /* 0.362290071 */, 18 }, /* 5411 */ { MAD_F(0x05cc4e4d) /* 0.362379362 */, 18 }, /* 5412 */ { MAD_F(0x05ccabf0) /* 0.362468660 */, 18 }, /* 5413 */ { MAD_F(0x05cd0994) /* 0.362557962 */, 18 }, /* 5414 */ { MAD_F(0x05cd6739) /* 0.362647271 */, 18 }, /* 5415 */ { MAD_F(0x05cdc4e0) /* 0.362736584 */, 18 }, /* 5416 */ { MAD_F(0x05ce2289) /* 0.362825904 */, 18 }, /* 5417 */ { MAD_F(0x05ce8033) /* 0.362915228 */, 18 }, /* 5418 */ { MAD_F(0x05ceddde) /* 0.363004559 */, 18 }, /* 5419 */ { MAD_F(0x05cf3b8b) /* 0.363093894 */, 18 }, /* 5420 */ { MAD_F(0x05cf9939) /* 0.363183236 */, 18 }, /* 5421 */ { MAD_F(0x05cff6e9) /* 0.363272582 */, 18 }, /* 5422 */ { MAD_F(0x05d0549a) /* 0.363361935 */, 18 }, /* 5423 */ { MAD_F(0x05d0b24d) /* 0.363451292 */, 18 }, /* 5424 */ { MAD_F(0x05d11001) /* 0.363540655 */, 18 }, /* 5425 */ { MAD_F(0x05d16db7) /* 0.363630024 */, 18 }, /* 5426 */ { MAD_F(0x05d1cb6e) /* 0.363719398 */, 18 }, /* 5427 */ { MAD_F(0x05d22927) /* 0.363808778 */, 18 }, /* 5428 */ { MAD_F(0x05d286e1) /* 0.363898163 */, 18 }, /* 5429 */ { MAD_F(0x05d2e49d) /* 0.363987554 */, 18 }, /* 5430 */ { MAD_F(0x05d3425a) /* 0.364076950 */, 18 }, /* 5431 */ { MAD_F(0x05d3a018) /* 0.364166352 */, 18 }, /* 5432 */ { MAD_F(0x05d3fdd8) /* 0.364255759 */, 18 }, /* 5433 */ { MAD_F(0x05d45b9a) /* 0.364345171 */, 18 }, /* 5434 */ { MAD_F(0x05d4b95d) /* 0.364434589 */, 18 }, /* 5435 */ { MAD_F(0x05d51721) /* 0.364524013 */, 18 }, /* 5436 */ { MAD_F(0x05d574e7) /* 0.364613442 */, 18 }, /* 5437 */ { MAD_F(0x05d5d2af) /* 0.364702877 */, 18 }, /* 5438 */ { MAD_F(0x05d63078) /* 0.364792317 */, 18 }, /* 5439 */ { MAD_F(0x05d68e42) /* 0.364881762 */, 18 }, /* 5440 */ { MAD_F(0x05d6ec0e) /* 0.364971213 */, 18 }, /* 5441 */ { MAD_F(0x05d749db) /* 0.365060669 */, 18 }, /* 5442 */ { MAD_F(0x05d7a7aa) /* 0.365150131 */, 18 }, /* 5443 */ { MAD_F(0x05d8057a) /* 0.365239599 */, 18 }, /* 5444 */ { MAD_F(0x05d8634c) /* 0.365329072 */, 18 }, /* 5445 */ { MAD_F(0x05d8c11f) /* 0.365418550 */, 18 }, /* 5446 */ { MAD_F(0x05d91ef4) /* 0.365508034 */, 18 }, /* 5447 */ { MAD_F(0x05d97cca) /* 0.365597523 */, 18 }, /* 5448 */ { MAD_F(0x05d9daa1) /* 0.365687018 */, 18 }, /* 5449 */ { MAD_F(0x05da387a) /* 0.365776518 */, 18 }, /* 5450 */ { MAD_F(0x05da9655) /* 0.365866024 */, 18 }, /* 5451 */ { MAD_F(0x05daf431) /* 0.365955536 */, 18 }, /* 5452 */ { MAD_F(0x05db520e) /* 0.366045052 */, 18 }, /* 5453 */ { MAD_F(0x05dbafed) /* 0.366134574 */, 18 }, /* 5454 */ { MAD_F(0x05dc0dce) /* 0.366224102 */, 18 }, /* 5455 */ { MAD_F(0x05dc6baf) /* 0.366313635 */, 18 }, /* 5456 */ { MAD_F(0x05dcc993) /* 0.366403174 */, 18 }, /* 5457 */ { MAD_F(0x05dd2778) /* 0.366492718 */, 18 }, /* 5458 */ { MAD_F(0x05dd855e) /* 0.366582267 */, 18 }, /* 5459 */ { MAD_F(0x05dde346) /* 0.366671822 */, 18 }, /* 5460 */ { MAD_F(0x05de412f) /* 0.366761383 */, 18 }, /* 5461 */ { MAD_F(0x05de9f1a) /* 0.366850949 */, 18 }, /* 5462 */ { MAD_F(0x05defd06) /* 0.366940520 */, 18 }, /* 5463 */ { MAD_F(0x05df5af3) /* 0.367030097 */, 18 }, /* 5464 */ { MAD_F(0x05dfb8e2) /* 0.367119680 */, 18 }, /* 5465 */ { MAD_F(0x05e016d3) /* 0.367209267 */, 18 }, /* 5466 */ { MAD_F(0x05e074c5) /* 0.367298861 */, 18 }, /* 5467 */ { MAD_F(0x05e0d2b8) /* 0.367388459 */, 18 }, /* 5468 */ { MAD_F(0x05e130ad) /* 0.367478064 */, 18 }, /* 5469 */ { MAD_F(0x05e18ea4) /* 0.367567673 */, 18 }, /* 5470 */ { MAD_F(0x05e1ec9c) /* 0.367657288 */, 18 }, /* 5471 */ { MAD_F(0x05e24a95) /* 0.367746909 */, 18 }, /* 5472 */ { MAD_F(0x05e2a890) /* 0.367836535 */, 18 }, /* 5473 */ { MAD_F(0x05e3068c) /* 0.367926167 */, 18 }, /* 5474 */ { MAD_F(0x05e3648a) /* 0.368015804 */, 18 }, /* 5475 */ { MAD_F(0x05e3c289) /* 0.368105446 */, 18 }, /* 5476 */ { MAD_F(0x05e4208a) /* 0.368195094 */, 18 }, /* 5477 */ { MAD_F(0x05e47e8c) /* 0.368284747 */, 18 }, /* 5478 */ { MAD_F(0x05e4dc8f) /* 0.368374406 */, 18 }, /* 5479 */ { MAD_F(0x05e53a94) /* 0.368464070 */, 18 }, /* 5480 */ { MAD_F(0x05e5989b) /* 0.368553740 */, 18 }, /* 5481 */ { MAD_F(0x05e5f6a3) /* 0.368643415 */, 18 }, /* 5482 */ { MAD_F(0x05e654ac) /* 0.368733096 */, 18 }, /* 5483 */ { MAD_F(0x05e6b2b7) /* 0.368822782 */, 18 }, /* 5484 */ { MAD_F(0x05e710c4) /* 0.368912473 */, 18 }, /* 5485 */ { MAD_F(0x05e76ed2) /* 0.369002170 */, 18 }, /* 5486 */ { MAD_F(0x05e7cce1) /* 0.369091873 */, 18 }, /* 5487 */ { MAD_F(0x05e82af2) /* 0.369181581 */, 18 }, /* 5488 */ { MAD_F(0x05e88904) /* 0.369271294 */, 18 }, /* 5489 */ { MAD_F(0x05e8e718) /* 0.369361013 */, 18 }, /* 5490 */ { MAD_F(0x05e9452d) /* 0.369450737 */, 18 }, /* 5491 */ { MAD_F(0x05e9a343) /* 0.369540467 */, 18 }, /* 5492 */ { MAD_F(0x05ea015c) /* 0.369630202 */, 18 }, /* 5493 */ { MAD_F(0x05ea5f75) /* 0.369719942 */, 18 }, /* 5494 */ { MAD_F(0x05eabd90) /* 0.369809688 */, 18 }, /* 5495 */ { MAD_F(0x05eb1bad) /* 0.369899440 */, 18 }, /* 5496 */ { MAD_F(0x05eb79cb) /* 0.369989197 */, 18 }, /* 5497 */ { MAD_F(0x05ebd7ea) /* 0.370078959 */, 18 }, /* 5498 */ { MAD_F(0x05ec360b) /* 0.370168727 */, 18 }, /* 5499 */ { MAD_F(0x05ec942d) /* 0.370258500 */, 18 }, /* 5500 */ { MAD_F(0x05ecf251) /* 0.370348279 */, 18 }, /* 5501 */ { MAD_F(0x05ed5076) /* 0.370438063 */, 18 }, /* 5502 */ { MAD_F(0x05edae9d) /* 0.370527853 */, 18 }, /* 5503 */ { MAD_F(0x05ee0cc5) /* 0.370617648 */, 18 }, /* 5504 */ { MAD_F(0x05ee6aef) /* 0.370707448 */, 18 }, /* 5505 */ { MAD_F(0x05eec91a) /* 0.370797254 */, 18 }, /* 5506 */ { MAD_F(0x05ef2746) /* 0.370887065 */, 18 }, /* 5507 */ { MAD_F(0x05ef8574) /* 0.370976882 */, 18 }, /* 5508 */ { MAD_F(0x05efe3a4) /* 0.371066704 */, 18 }, /* 5509 */ { MAD_F(0x05f041d5) /* 0.371156532 */, 18 }, /* 5510 */ { MAD_F(0x05f0a007) /* 0.371246365 */, 18 }, /* 5511 */ { MAD_F(0x05f0fe3b) /* 0.371336203 */, 18 }, /* 5512 */ { MAD_F(0x05f15c70) /* 0.371426047 */, 18 }, /* 5513 */ { MAD_F(0x05f1baa7) /* 0.371515897 */, 18 }, /* 5514 */ { MAD_F(0x05f218df) /* 0.371605751 */, 18 }, /* 5515 */ { MAD_F(0x05f27719) /* 0.371695612 */, 18 }, /* 5516 */ { MAD_F(0x05f2d554) /* 0.371785477 */, 18 }, /* 5517 */ { MAD_F(0x05f33390) /* 0.371875348 */, 18 }, /* 5518 */ { MAD_F(0x05f391cf) /* 0.371965225 */, 18 }, /* 5519 */ { MAD_F(0x05f3f00e) /* 0.372055107 */, 18 }, /* 5520 */ { MAD_F(0x05f44e4f) /* 0.372144994 */, 18 }, /* 5521 */ { MAD_F(0x05f4ac91) /* 0.372234887 */, 18 }, /* 5522 */ { MAD_F(0x05f50ad5) /* 0.372324785 */, 18 }, /* 5523 */ { MAD_F(0x05f5691b) /* 0.372414689 */, 18 }, /* 5524 */ { MAD_F(0x05f5c761) /* 0.372504598 */, 18 }, /* 5525 */ { MAD_F(0x05f625aa) /* 0.372594513 */, 18 }, /* 5526 */ { MAD_F(0x05f683f3) /* 0.372684433 */, 18 }, /* 5527 */ { MAD_F(0x05f6e23f) /* 0.372774358 */, 18 }, /* 5528 */ { MAD_F(0x05f7408b) /* 0.372864289 */, 18 }, /* 5529 */ { MAD_F(0x05f79ed9) /* 0.372954225 */, 18 }, /* 5530 */ { MAD_F(0x05f7fd29) /* 0.373044167 */, 18 }, /* 5531 */ { MAD_F(0x05f85b7a) /* 0.373134114 */, 18 }, /* 5532 */ { MAD_F(0x05f8b9cc) /* 0.373224066 */, 18 }, /* 5533 */ { MAD_F(0x05f91820) /* 0.373314024 */, 18 }, /* 5534 */ { MAD_F(0x05f97675) /* 0.373403987 */, 18 }, /* 5535 */ { MAD_F(0x05f9d4cc) /* 0.373493956 */, 18 }, /* 5536 */ { MAD_F(0x05fa3324) /* 0.373583930 */, 18 }, /* 5537 */ { MAD_F(0x05fa917e) /* 0.373673910 */, 18 }, /* 5538 */ { MAD_F(0x05faefd9) /* 0.373763895 */, 18 }, /* 5539 */ { MAD_F(0x05fb4e36) /* 0.373853885 */, 18 }, /* 5540 */ { MAD_F(0x05fbac94) /* 0.373943881 */, 18 }, /* 5541 */ { MAD_F(0x05fc0af3) /* 0.374033882 */, 18 }, /* 5542 */ { MAD_F(0x05fc6954) /* 0.374123889 */, 18 }, /* 5543 */ { MAD_F(0x05fcc7b7) /* 0.374213901 */, 18 }, /* 5544 */ { MAD_F(0x05fd261b) /* 0.374303918 */, 18 }, /* 5545 */ { MAD_F(0x05fd8480) /* 0.374393941 */, 18 }, /* 5546 */ { MAD_F(0x05fde2e7) /* 0.374483970 */, 18 }, /* 5547 */ { MAD_F(0x05fe414f) /* 0.374574003 */, 18 }, /* 5548 */ { MAD_F(0x05fe9fb9) /* 0.374664042 */, 18 }, /* 5549 */ { MAD_F(0x05fefe24) /* 0.374754087 */, 18 }, /* 5550 */ { MAD_F(0x05ff5c91) /* 0.374844137 */, 18 }, /* 5551 */ { MAD_F(0x05ffbaff) /* 0.374934192 */, 18 }, /* 5552 */ { MAD_F(0x0600196e) /* 0.375024253 */, 18 }, /* 5553 */ { MAD_F(0x060077df) /* 0.375114319 */, 18 }, /* 5554 */ { MAD_F(0x0600d651) /* 0.375204391 */, 18 }, /* 5555 */ { MAD_F(0x060134c5) /* 0.375294468 */, 18 }, /* 5556 */ { MAD_F(0x0601933b) /* 0.375384550 */, 18 }, /* 5557 */ { MAD_F(0x0601f1b1) /* 0.375474638 */, 18 }, /* 5558 */ { MAD_F(0x0602502a) /* 0.375564731 */, 18 }, /* 5559 */ { MAD_F(0x0602aea3) /* 0.375654830 */, 18 }, /* 5560 */ { MAD_F(0x06030d1e) /* 0.375744934 */, 18 }, /* 5561 */ { MAD_F(0x06036b9b) /* 0.375835043 */, 18 }, /* 5562 */ { MAD_F(0x0603ca19) /* 0.375925158 */, 18 }, /* 5563 */ { MAD_F(0x06042898) /* 0.376015278 */, 18 }, /* 5564 */ { MAD_F(0x06048719) /* 0.376105404 */, 18 }, /* 5565 */ { MAD_F(0x0604e59c) /* 0.376195535 */, 18 }, /* 5566 */ { MAD_F(0x0605441f) /* 0.376285671 */, 18 }, /* 5567 */ { MAD_F(0x0605a2a5) /* 0.376375813 */, 18 }, /* 5568 */ { MAD_F(0x0606012b) /* 0.376465960 */, 18 }, /* 5569 */ { MAD_F(0x06065fb4) /* 0.376556113 */, 18 }, /* 5570 */ { MAD_F(0x0606be3d) /* 0.376646271 */, 18 }, /* 5571 */ { MAD_F(0x06071cc8) /* 0.376736434 */, 18 }, /* 5572 */ { MAD_F(0x06077b55) /* 0.376826603 */, 18 }, /* 5573 */ { MAD_F(0x0607d9e3) /* 0.376916777 */, 18 }, /* 5574 */ { MAD_F(0x06083872) /* 0.377006957 */, 18 }, /* 5575 */ { MAD_F(0x06089703) /* 0.377097141 */, 18 }, /* 5576 */ { MAD_F(0x0608f595) /* 0.377187332 */, 18 }, /* 5577 */ { MAD_F(0x06095429) /* 0.377277528 */, 18 }, /* 5578 */ { MAD_F(0x0609b2be) /* 0.377367729 */, 18 }, /* 5579 */ { MAD_F(0x060a1155) /* 0.377457935 */, 18 }, /* 5580 */ { MAD_F(0x060a6fed) /* 0.377548147 */, 18 }, /* 5581 */ { MAD_F(0x060ace86) /* 0.377638364 */, 18 }, /* 5582 */ { MAD_F(0x060b2d21) /* 0.377728587 */, 18 }, /* 5583 */ { MAD_F(0x060b8bbe) /* 0.377818815 */, 18 }, /* 5584 */ { MAD_F(0x060bea5c) /* 0.377909049 */, 18 }, /* 5585 */ { MAD_F(0x060c48fb) /* 0.377999288 */, 18 }, /* 5586 */ { MAD_F(0x060ca79c) /* 0.378089532 */, 18 }, /* 5587 */ { MAD_F(0x060d063e) /* 0.378179781 */, 18 }, /* 5588 */ { MAD_F(0x060d64e1) /* 0.378270036 */, 18 }, /* 5589 */ { MAD_F(0x060dc387) /* 0.378360297 */, 18 }, /* 5590 */ { MAD_F(0x060e222d) /* 0.378450563 */, 18 }, /* 5591 */ { MAD_F(0x060e80d5) /* 0.378540834 */, 18 }, /* 5592 */ { MAD_F(0x060edf7f) /* 0.378631110 */, 18 }, /* 5593 */ { MAD_F(0x060f3e29) /* 0.378721392 */, 18 }, /* 5594 */ { MAD_F(0x060f9cd6) /* 0.378811680 */, 18 }, /* 5595 */ { MAD_F(0x060ffb83) /* 0.378901972 */, 18 }, /* 5596 */ { MAD_F(0x06105a33) /* 0.378992270 */, 18 }, /* 5597 */ { MAD_F(0x0610b8e3) /* 0.379082574 */, 18 }, /* 5598 */ { MAD_F(0x06111795) /* 0.379172883 */, 18 }, /* 5599 */ { MAD_F(0x06117649) /* 0.379263197 */, 18 }, /* 5600 */ { MAD_F(0x0611d4fe) /* 0.379353516 */, 18 }, /* 5601 */ { MAD_F(0x061233b4) /* 0.379443841 */, 18 }, /* 5602 */ { MAD_F(0x0612926c) /* 0.379534172 */, 18 }, /* 5603 */ { MAD_F(0x0612f125) /* 0.379624507 */, 18 }, /* 5604 */ { MAD_F(0x06134fe0) /* 0.379714848 */, 18 }, /* 5605 */ { MAD_F(0x0613ae9c) /* 0.379805195 */, 18 }, /* 5606 */ { MAD_F(0x06140d5a) /* 0.379895547 */, 18 }, /* 5607 */ { MAD_F(0x06146c19) /* 0.379985904 */, 18 }, /* 5608 */ { MAD_F(0x0614cada) /* 0.380076266 */, 18 }, /* 5609 */ { MAD_F(0x0615299c) /* 0.380166634 */, 18 }, /* 5610 */ { MAD_F(0x0615885f) /* 0.380257008 */, 18 }, /* 5611 */ { MAD_F(0x0615e724) /* 0.380347386 */, 18 }, /* 5612 */ { MAD_F(0x061645ea) /* 0.380437770 */, 18 }, /* 5613 */ { MAD_F(0x0616a4b2) /* 0.380528160 */, 18 }, /* 5614 */ { MAD_F(0x0617037b) /* 0.380618555 */, 18 }, /* 5615 */ { MAD_F(0x06176246) /* 0.380708955 */, 18 }, /* 5616 */ { MAD_F(0x0617c112) /* 0.380799360 */, 18 }, /* 5617 */ { MAD_F(0x06181fdf) /* 0.380889771 */, 18 }, /* 5618 */ { MAD_F(0x06187eae) /* 0.380980187 */, 18 }, /* 5619 */ { MAD_F(0x0618dd7e) /* 0.381070609 */, 18 }, /* 5620 */ { MAD_F(0x06193c50) /* 0.381161036 */, 18 }, /* 5621 */ { MAD_F(0x06199b24) /* 0.381251468 */, 18 }, /* 5622 */ { MAD_F(0x0619f9f8) /* 0.381341906 */, 18 }, /* 5623 */ { MAD_F(0x061a58ce) /* 0.381432349 */, 18 }, /* 5624 */ { MAD_F(0x061ab7a6) /* 0.381522798 */, 18 }, /* 5625 */ { MAD_F(0x061b167f) /* 0.381613251 */, 18 }, /* 5626 */ { MAD_F(0x061b7559) /* 0.381703711 */, 18 }, /* 5627 */ { MAD_F(0x061bd435) /* 0.381794175 */, 18 }, /* 5628 */ { MAD_F(0x061c3313) /* 0.381884645 */, 18 }, /* 5629 */ { MAD_F(0x061c91f1) /* 0.381975120 */, 18 }, /* 5630 */ { MAD_F(0x061cf0d2) /* 0.382065601 */, 18 }, /* 5631 */ { MAD_F(0x061d4fb3) /* 0.382156087 */, 18 }, /* 5632 */ { MAD_F(0x061dae96) /* 0.382246578 */, 18 }, /* 5633 */ { MAD_F(0x061e0d7b) /* 0.382337075 */, 18 }, /* 5634 */ { MAD_F(0x061e6c61) /* 0.382427577 */, 18 }, /* 5635 */ { MAD_F(0x061ecb48) /* 0.382518084 */, 18 }, /* 5636 */ { MAD_F(0x061f2a31) /* 0.382608597 */, 18 }, /* 5637 */ { MAD_F(0x061f891b) /* 0.382699115 */, 18 }, /* 5638 */ { MAD_F(0x061fe807) /* 0.382789638 */, 18 }, /* 5639 */ { MAD_F(0x062046f4) /* 0.382880167 */, 18 }, /* 5640 */ { MAD_F(0x0620a5e3) /* 0.382970701 */, 18 }, /* 5641 */ { MAD_F(0x062104d3) /* 0.383061241 */, 18 }, /* 5642 */ { MAD_F(0x062163c4) /* 0.383151786 */, 18 }, /* 5643 */ { MAD_F(0x0621c2b7) /* 0.383242336 */, 18 }, /* 5644 */ { MAD_F(0x062221ab) /* 0.383332891 */, 18 }, /* 5645 */ { MAD_F(0x062280a1) /* 0.383423452 */, 18 }, /* 5646 */ { MAD_F(0x0622df98) /* 0.383514018 */, 18 }, /* 5647 */ { MAD_F(0x06233e91) /* 0.383604590 */, 18 }, /* 5648 */ { MAD_F(0x06239d8b) /* 0.383695167 */, 18 }, /* 5649 */ { MAD_F(0x0623fc86) /* 0.383785749 */, 18 }, /* 5650 */ { MAD_F(0x06245b83) /* 0.383876337 */, 18 }, /* 5651 */ { MAD_F(0x0624ba82) /* 0.383966930 */, 18 }, /* 5652 */ { MAD_F(0x06251981) /* 0.384057528 */, 18 }, /* 5653 */ { MAD_F(0x06257883) /* 0.384148132 */, 18 }, /* 5654 */ { MAD_F(0x0625d785) /* 0.384238741 */, 18 }, /* 5655 */ { MAD_F(0x06263689) /* 0.384329355 */, 18 }, /* 5656 */ { MAD_F(0x0626958f) /* 0.384419975 */, 18 }, /* 5657 */ { MAD_F(0x0626f496) /* 0.384510600 */, 18 }, /* 5658 */ { MAD_F(0x0627539e) /* 0.384601230 */, 18 }, /* 5659 */ { MAD_F(0x0627b2a8) /* 0.384691866 */, 18 }, /* 5660 */ { MAD_F(0x062811b3) /* 0.384782507 */, 18 }, /* 5661 */ { MAD_F(0x062870c0) /* 0.384873153 */, 18 }, /* 5662 */ { MAD_F(0x0628cfce) /* 0.384963805 */, 18 }, /* 5663 */ { MAD_F(0x06292ede) /* 0.385054462 */, 18 }, /* 5664 */ { MAD_F(0x06298def) /* 0.385145124 */, 18 }, /* 5665 */ { MAD_F(0x0629ed01) /* 0.385235792 */, 18 }, /* 5666 */ { MAD_F(0x062a4c15) /* 0.385326465 */, 18 }, /* 5667 */ { MAD_F(0x062aab2a) /* 0.385417143 */, 18 }, /* 5668 */ { MAD_F(0x062b0a41) /* 0.385507827 */, 18 }, /* 5669 */ { MAD_F(0x062b6959) /* 0.385598516 */, 18 }, /* 5670 */ { MAD_F(0x062bc873) /* 0.385689211 */, 18 }, /* 5671 */ { MAD_F(0x062c278e) /* 0.385779910 */, 18 }, /* 5672 */ { MAD_F(0x062c86aa) /* 0.385870615 */, 18 }, /* 5673 */ { MAD_F(0x062ce5c8) /* 0.385961326 */, 18 }, /* 5674 */ { MAD_F(0x062d44e8) /* 0.386052041 */, 18 }, /* 5675 */ { MAD_F(0x062da408) /* 0.386142762 */, 18 }, /* 5676 */ { MAD_F(0x062e032a) /* 0.386233489 */, 18 }, /* 5677 */ { MAD_F(0x062e624e) /* 0.386324221 */, 18 }, /* 5678 */ { MAD_F(0x062ec173) /* 0.386414958 */, 18 }, /* 5679 */ { MAD_F(0x062f209a) /* 0.386505700 */, 18 }, /* 5680 */ { MAD_F(0x062f7fc1) /* 0.386596448 */, 18 }, /* 5681 */ { MAD_F(0x062fdeeb) /* 0.386687201 */, 18 }, /* 5682 */ { MAD_F(0x06303e16) /* 0.386777959 */, 18 }, /* 5683 */ { MAD_F(0x06309d42) /* 0.386868723 */, 18 }, /* 5684 */ { MAD_F(0x0630fc6f) /* 0.386959492 */, 18 }, /* 5685 */ { MAD_F(0x06315b9e) /* 0.387050266 */, 18 }, /* 5686 */ { MAD_F(0x0631bacf) /* 0.387141045 */, 18 }, /* 5687 */ { MAD_F(0x06321a01) /* 0.387231830 */, 18 }, /* 5688 */ { MAD_F(0x06327934) /* 0.387322621 */, 18 }, /* 5689 */ { MAD_F(0x0632d869) /* 0.387413416 */, 18 }, /* 5690 */ { MAD_F(0x0633379f) /* 0.387504217 */, 18 }, /* 5691 */ { MAD_F(0x063396d7) /* 0.387595023 */, 18 }, /* 5692 */ { MAD_F(0x0633f610) /* 0.387685835 */, 18 }, /* 5693 */ { MAD_F(0x0634554a) /* 0.387776652 */, 18 }, /* 5694 */ { MAD_F(0x0634b486) /* 0.387867474 */, 18 }, /* 5695 */ { MAD_F(0x063513c3) /* 0.387958301 */, 18 }, /* 5696 */ { MAD_F(0x06357302) /* 0.388049134 */, 18 }, /* 5697 */ { MAD_F(0x0635d242) /* 0.388139972 */, 18 }, /* 5698 */ { MAD_F(0x06363184) /* 0.388230816 */, 18 }, /* 5699 */ { MAD_F(0x063690c7) /* 0.388321665 */, 18 }, /* 5700 */ { MAD_F(0x0636f00b) /* 0.388412519 */, 18 }, /* 5701 */ { MAD_F(0x06374f51) /* 0.388503378 */, 18 }, /* 5702 */ { MAD_F(0x0637ae99) /* 0.388594243 */, 18 }, /* 5703 */ { MAD_F(0x06380de1) /* 0.388685113 */, 18 }, /* 5704 */ { MAD_F(0x06386d2b) /* 0.388775988 */, 18 }, /* 5705 */ { MAD_F(0x0638cc77) /* 0.388866869 */, 18 }, /* 5706 */ { MAD_F(0x06392bc4) /* 0.388957755 */, 18 }, /* 5707 */ { MAD_F(0x06398b12) /* 0.389048646 */, 18 }, /* 5708 */ { MAD_F(0x0639ea62) /* 0.389139542 */, 18 }, /* 5709 */ { MAD_F(0x063a49b4) /* 0.389230444 */, 18 }, /* 5710 */ { MAD_F(0x063aa906) /* 0.389321352 */, 18 }, /* 5711 */ { MAD_F(0x063b085a) /* 0.389412264 */, 18 }, /* 5712 */ { MAD_F(0x063b67b0) /* 0.389503182 */, 18 }, /* 5713 */ { MAD_F(0x063bc707) /* 0.389594105 */, 18 }, /* 5714 */ { MAD_F(0x063c265f) /* 0.389685033 */, 18 }, /* 5715 */ { MAD_F(0x063c85b9) /* 0.389775967 */, 18 }, /* 5716 */ { MAD_F(0x063ce514) /* 0.389866906 */, 18 }, /* 5717 */ { MAD_F(0x063d4471) /* 0.389957850 */, 18 }, /* 5718 */ { MAD_F(0x063da3cf) /* 0.390048800 */, 18 }, /* 5719 */ { MAD_F(0x063e032f) /* 0.390139755 */, 18 }, /* 5720 */ { MAD_F(0x063e6290) /* 0.390230715 */, 18 }, /* 5721 */ { MAD_F(0x063ec1f2) /* 0.390321681 */, 18 }, /* 5722 */ { MAD_F(0x063f2156) /* 0.390412651 */, 18 }, /* 5723 */ { MAD_F(0x063f80bb) /* 0.390503628 */, 18 }, /* 5724 */ { MAD_F(0x063fe022) /* 0.390594609 */, 18 }, /* 5725 */ { MAD_F(0x06403f8a) /* 0.390685596 */, 18 }, /* 5726 */ { MAD_F(0x06409ef3) /* 0.390776588 */, 18 }, /* 5727 */ { MAD_F(0x0640fe5e) /* 0.390867585 */, 18 }, /* 5728 */ { MAD_F(0x06415dcb) /* 0.390958588 */, 18 }, /* 5729 */ { MAD_F(0x0641bd38) /* 0.391049596 */, 18 }, /* 5730 */ { MAD_F(0x06421ca7) /* 0.391140609 */, 18 }, /* 5731 */ { MAD_F(0x06427c18) /* 0.391231627 */, 18 }, /* 5732 */ { MAD_F(0x0642db8a) /* 0.391322651 */, 18 }, /* 5733 */ { MAD_F(0x06433afd) /* 0.391413680 */, 18 }, /* 5734 */ { MAD_F(0x06439a72) /* 0.391504714 */, 18 }, /* 5735 */ { MAD_F(0x0643f9e9) /* 0.391595754 */, 18 }, /* 5736 */ { MAD_F(0x06445960) /* 0.391686799 */, 18 }, /* 5737 */ { MAD_F(0x0644b8d9) /* 0.391777849 */, 18 }, /* 5738 */ { MAD_F(0x06451854) /* 0.391868905 */, 18 }, /* 5739 */ { MAD_F(0x064577d0) /* 0.391959966 */, 18 }, /* 5740 */ { MAD_F(0x0645d74d) /* 0.392051032 */, 18 }, /* 5741 */ { MAD_F(0x064636cc) /* 0.392142103 */, 18 }, /* 5742 */ { MAD_F(0x0646964c) /* 0.392233180 */, 18 }, /* 5743 */ { MAD_F(0x0646f5ce) /* 0.392324262 */, 18 }, /* 5744 */ { MAD_F(0x06475551) /* 0.392415349 */, 18 }, /* 5745 */ { MAD_F(0x0647b4d5) /* 0.392506442 */, 18 }, /* 5746 */ { MAD_F(0x0648145b) /* 0.392597540 */, 18 }, /* 5747 */ { MAD_F(0x064873e3) /* 0.392688643 */, 18 }, /* 5748 */ { MAD_F(0x0648d36b) /* 0.392779751 */, 18 }, /* 5749 */ { MAD_F(0x064932f6) /* 0.392870865 */, 18 }, /* 5750 */ { MAD_F(0x06499281) /* 0.392961984 */, 18 }, /* 5751 */ { MAD_F(0x0649f20e) /* 0.393053108 */, 18 }, /* 5752 */ { MAD_F(0x064a519c) /* 0.393144238 */, 18 }, /* 5753 */ { MAD_F(0x064ab12c) /* 0.393235372 */, 18 }, /* 5754 */ { MAD_F(0x064b10be) /* 0.393326513 */, 18 }, /* 5755 */ { MAD_F(0x064b7050) /* 0.393417658 */, 18 }, /* 5756 */ { MAD_F(0x064bcfe4) /* 0.393508809 */, 18 }, /* 5757 */ { MAD_F(0x064c2f7a) /* 0.393599965 */, 18 }, /* 5758 */ { MAD_F(0x064c8f11) /* 0.393691126 */, 18 }, /* 5759 */ { MAD_F(0x064ceea9) /* 0.393782292 */, 18 }, /* 5760 */ { MAD_F(0x064d4e43) /* 0.393873464 */, 18 }, /* 5761 */ { MAD_F(0x064dadde) /* 0.393964641 */, 18 }, /* 5762 */ { MAD_F(0x064e0d7a) /* 0.394055823 */, 18 }, /* 5763 */ { MAD_F(0x064e6d18) /* 0.394147011 */, 18 }, /* 5764 */ { MAD_F(0x064eccb8) /* 0.394238204 */, 18 }, /* 5765 */ { MAD_F(0x064f2c59) /* 0.394329402 */, 18 }, /* 5766 */ { MAD_F(0x064f8bfb) /* 0.394420605 */, 18 }, /* 5767 */ { MAD_F(0x064feb9e) /* 0.394511814 */, 18 }, /* 5768 */ { MAD_F(0x06504b44) /* 0.394603028 */, 18 }, /* 5769 */ { MAD_F(0x0650aaea) /* 0.394694247 */, 18 }, /* 5770 */ { MAD_F(0x06510a92) /* 0.394785472 */, 18 }, /* 5771 */ { MAD_F(0x06516a3b) /* 0.394876702 */, 18 }, /* 5772 */ { MAD_F(0x0651c9e6) /* 0.394967937 */, 18 }, /* 5773 */ { MAD_F(0x06522992) /* 0.395059177 */, 18 }, /* 5774 */ { MAD_F(0x06528940) /* 0.395150423 */, 18 }, /* 5775 */ { MAD_F(0x0652e8ef) /* 0.395241673 */, 18 }, /* 5776 */ { MAD_F(0x0653489f) /* 0.395332930 */, 18 }, /* 5777 */ { MAD_F(0x0653a851) /* 0.395424191 */, 18 }, /* 5778 */ { MAD_F(0x06540804) /* 0.395515458 */, 18 }, /* 5779 */ { MAD_F(0x065467b9) /* 0.395606730 */, 18 }, /* 5780 */ { MAD_F(0x0654c76f) /* 0.395698007 */, 18 }, /* 5781 */ { MAD_F(0x06552726) /* 0.395789289 */, 18 }, /* 5782 */ { MAD_F(0x065586df) /* 0.395880577 */, 18 }, /* 5783 */ { MAD_F(0x0655e699) /* 0.395971870 */, 18 }, /* 5784 */ { MAD_F(0x06564655) /* 0.396063168 */, 18 }, /* 5785 */ { MAD_F(0x0656a612) /* 0.396154472 */, 18 }, /* 5786 */ { MAD_F(0x065705d0) /* 0.396245780 */, 18 }, /* 5787 */ { MAD_F(0x06576590) /* 0.396337094 */, 18 }, /* 5788 */ { MAD_F(0x0657c552) /* 0.396428414 */, 18 }, /* 5789 */ { MAD_F(0x06582514) /* 0.396519738 */, 18 }, /* 5790 */ { MAD_F(0x065884d9) /* 0.396611068 */, 18 }, /* 5791 */ { MAD_F(0x0658e49e) /* 0.396702403 */, 18 }, /* 5792 */ { MAD_F(0x06594465) /* 0.396793743 */, 18 }, /* 5793 */ { MAD_F(0x0659a42e) /* 0.396885089 */, 18 }, /* 5794 */ { MAD_F(0x065a03f7) /* 0.396976440 */, 18 }, /* 5795 */ { MAD_F(0x065a63c3) /* 0.397067796 */, 18 }, /* 5796 */ { MAD_F(0x065ac38f) /* 0.397159157 */, 18 }, /* 5797 */ { MAD_F(0x065b235d) /* 0.397250524 */, 18 }, /* 5798 */ { MAD_F(0x065b832d) /* 0.397341896 */, 18 }, /* 5799 */ { MAD_F(0x065be2fe) /* 0.397433273 */, 18 }, /* 5800 */ { MAD_F(0x065c42d0) /* 0.397524655 */, 18 }, /* 5801 */ { MAD_F(0x065ca2a3) /* 0.397616043 */, 18 }, /* 5802 */ { MAD_F(0x065d0279) /* 0.397707436 */, 18 }, /* 5803 */ { MAD_F(0x065d624f) /* 0.397798834 */, 18 }, /* 5804 */ { MAD_F(0x065dc227) /* 0.397890237 */, 18 }, /* 5805 */ { MAD_F(0x065e2200) /* 0.397981646 */, 18 }, /* 5806 */ { MAD_F(0x065e81db) /* 0.398073059 */, 18 }, /* 5807 */ { MAD_F(0x065ee1b7) /* 0.398164479 */, 18 }, /* 5808 */ { MAD_F(0x065f4195) /* 0.398255903 */, 18 }, /* 5809 */ { MAD_F(0x065fa174) /* 0.398347333 */, 18 }, /* 5810 */ { MAD_F(0x06600154) /* 0.398438767 */, 18 }, /* 5811 */ { MAD_F(0x06606136) /* 0.398530207 */, 18 }, /* 5812 */ { MAD_F(0x0660c119) /* 0.398621653 */, 18 }, /* 5813 */ { MAD_F(0x066120fd) /* 0.398713103 */, 18 }, /* 5814 */ { MAD_F(0x066180e3) /* 0.398804559 */, 18 }, /* 5815 */ { MAD_F(0x0661e0cb) /* 0.398896020 */, 18 }, /* 5816 */ { MAD_F(0x066240b4) /* 0.398987487 */, 18 }, /* 5817 */ { MAD_F(0x0662a09e) /* 0.399078958 */, 18 }, /* 5818 */ { MAD_F(0x06630089) /* 0.399170435 */, 18 }, /* 5819 */ { MAD_F(0x06636077) /* 0.399261917 */, 18 }, /* 5820 */ { MAD_F(0x0663c065) /* 0.399353404 */, 18 }, /* 5821 */ { MAD_F(0x06642055) /* 0.399444897 */, 18 }, /* 5822 */ { MAD_F(0x06648046) /* 0.399536395 */, 18 }, /* 5823 */ { MAD_F(0x0664e039) /* 0.399627898 */, 18 }, /* 5824 */ { MAD_F(0x0665402d) /* 0.399719406 */, 18 }, /* 5825 */ { MAD_F(0x0665a022) /* 0.399810919 */, 18 }, /* 5826 */ { MAD_F(0x06660019) /* 0.399902438 */, 18 }, /* 5827 */ { MAD_F(0x06666011) /* 0.399993962 */, 18 }, /* 5828 */ { MAD_F(0x0666c00b) /* 0.400085491 */, 18 }, /* 5829 */ { MAD_F(0x06672006) /* 0.400177026 */, 18 }, /* 5830 */ { MAD_F(0x06678003) /* 0.400268565 */, 18 }, /* 5831 */ { MAD_F(0x0667e000) /* 0.400360110 */, 18 }, /* 5832 */ { MAD_F(0x06684000) /* 0.400451660 */, 18 }, /* 5833 */ { MAD_F(0x0668a000) /* 0.400543216 */, 18 }, /* 5834 */ { MAD_F(0x06690003) /* 0.400634776 */, 18 }, /* 5835 */ { MAD_F(0x06696006) /* 0.400726342 */, 18 }, /* 5836 */ { MAD_F(0x0669c00b) /* 0.400817913 */, 18 }, /* 5837 */ { MAD_F(0x066a2011) /* 0.400909489 */, 18 }, /* 5838 */ { MAD_F(0x066a8019) /* 0.401001071 */, 18 }, /* 5839 */ { MAD_F(0x066ae022) /* 0.401092657 */, 18 }, /* 5840 */ { MAD_F(0x066b402d) /* 0.401184249 */, 18 }, /* 5841 */ { MAD_F(0x066ba039) /* 0.401275847 */, 18 }, /* 5842 */ { MAD_F(0x066c0046) /* 0.401367449 */, 18 }, /* 5843 */ { MAD_F(0x066c6055) /* 0.401459057 */, 18 }, /* 5844 */ { MAD_F(0x066cc065) /* 0.401550670 */, 18 }, /* 5845 */ { MAD_F(0x066d2076) /* 0.401642288 */, 18 }, /* 5846 */ { MAD_F(0x066d8089) /* 0.401733911 */, 18 }, /* 5847 */ { MAD_F(0x066de09e) /* 0.401825540 */, 18 }, /* 5848 */ { MAD_F(0x066e40b3) /* 0.401917173 */, 18 }, /* 5849 */ { MAD_F(0x066ea0cb) /* 0.402008812 */, 18 }, /* 5850 */ { MAD_F(0x066f00e3) /* 0.402100457 */, 18 }, /* 5851 */ { MAD_F(0x066f60fd) /* 0.402192106 */, 18 }, /* 5852 */ { MAD_F(0x066fc118) /* 0.402283761 */, 18 }, /* 5853 */ { MAD_F(0x06702135) /* 0.402375420 */, 18 }, /* 5854 */ { MAD_F(0x06708153) /* 0.402467086 */, 18 }, /* 5855 */ { MAD_F(0x0670e173) /* 0.402558756 */, 18 }, /* 5856 */ { MAD_F(0x06714194) /* 0.402650431 */, 18 }, /* 5857 */ { MAD_F(0x0671a1b6) /* 0.402742112 */, 18 }, /* 5858 */ { MAD_F(0x067201da) /* 0.402833798 */, 18 }, /* 5859 */ { MAD_F(0x067261ff) /* 0.402925489 */, 18 }, /* 5860 */ { MAD_F(0x0672c226) /* 0.403017186 */, 18 }, /* 5861 */ { MAD_F(0x0673224e) /* 0.403108887 */, 18 }, /* 5862 */ { MAD_F(0x06738277) /* 0.403200594 */, 18 }, /* 5863 */ { MAD_F(0x0673e2a2) /* 0.403292306 */, 18 }, /* 5864 */ { MAD_F(0x067442ce) /* 0.403384024 */, 18 }, /* 5865 */ { MAD_F(0x0674a2fc) /* 0.403475746 */, 18 }, /* 5866 */ { MAD_F(0x0675032b) /* 0.403567474 */, 18 }, /* 5867 */ { MAD_F(0x0675635b) /* 0.403659207 */, 18 }, /* 5868 */ { MAD_F(0x0675c38d) /* 0.403750945 */, 18 }, /* 5869 */ { MAD_F(0x067623c0) /* 0.403842688 */, 18 }, /* 5870 */ { MAD_F(0x067683f4) /* 0.403934437 */, 18 }, /* 5871 */ { MAD_F(0x0676e42a) /* 0.404026190 */, 18 }, /* 5872 */ { MAD_F(0x06774462) /* 0.404117949 */, 18 }, /* 5873 */ { MAD_F(0x0677a49b) /* 0.404209714 */, 18 }, /* 5874 */ { MAD_F(0x067804d5) /* 0.404301483 */, 18 }, /* 5875 */ { MAD_F(0x06786510) /* 0.404393258 */, 18 }, /* 5876 */ { MAD_F(0x0678c54d) /* 0.404485037 */, 18 }, /* 5877 */ { MAD_F(0x0679258c) /* 0.404576822 */, 18 }, /* 5878 */ { MAD_F(0x067985cb) /* 0.404668613 */, 18 }, /* 5879 */ { MAD_F(0x0679e60c) /* 0.404760408 */, 18 }, /* 5880 */ { MAD_F(0x067a464f) /* 0.404852209 */, 18 }, /* 5881 */ { MAD_F(0x067aa693) /* 0.404944014 */, 18 }, /* 5882 */ { MAD_F(0x067b06d8) /* 0.405035825 */, 18 }, /* 5883 */ { MAD_F(0x067b671f) /* 0.405127642 */, 18 }, /* 5884 */ { MAD_F(0x067bc767) /* 0.405219463 */, 18 }, /* 5885 */ { MAD_F(0x067c27b1) /* 0.405311290 */, 18 }, /* 5886 */ { MAD_F(0x067c87fc) /* 0.405403122 */, 18 }, /* 5887 */ { MAD_F(0x067ce848) /* 0.405494959 */, 18 }, /* 5888 */ { MAD_F(0x067d4896) /* 0.405586801 */, 18 }, /* 5889 */ { MAD_F(0x067da8e5) /* 0.405678648 */, 18 }, /* 5890 */ { MAD_F(0x067e0935) /* 0.405770501 */, 18 }, /* 5891 */ { MAD_F(0x067e6987) /* 0.405862359 */, 18 }, /* 5892 */ { MAD_F(0x067ec9da) /* 0.405954222 */, 18 }, /* 5893 */ { MAD_F(0x067f2a2f) /* 0.406046090 */, 18 }, /* 5894 */ { MAD_F(0x067f8a85) /* 0.406137963 */, 18 }, /* 5895 */ { MAD_F(0x067feadd) /* 0.406229842 */, 18 }, /* 5896 */ { MAD_F(0x06804b36) /* 0.406321726 */, 18 }, /* 5897 */ { MAD_F(0x0680ab90) /* 0.406413615 */, 18 }, /* 5898 */ { MAD_F(0x06810beb) /* 0.406505509 */, 18 }, /* 5899 */ { MAD_F(0x06816c49) /* 0.406597408 */, 18 }, /* 5900 */ { MAD_F(0x0681cca7) /* 0.406689313 */, 18 }, /* 5901 */ { MAD_F(0x06822d07) /* 0.406781223 */, 18 }, /* 5902 */ { MAD_F(0x06828d68) /* 0.406873138 */, 18 }, /* 5903 */ { MAD_F(0x0682edcb) /* 0.406965058 */, 18 }, /* 5904 */ { MAD_F(0x06834e2f) /* 0.407056983 */, 18 }, /* 5905 */ { MAD_F(0x0683ae94) /* 0.407148914 */, 18 }, /* 5906 */ { MAD_F(0x06840efb) /* 0.407240850 */, 18 }, /* 5907 */ { MAD_F(0x06846f63) /* 0.407332791 */, 18 }, /* 5908 */ { MAD_F(0x0684cfcd) /* 0.407424737 */, 18 }, /* 5909 */ { MAD_F(0x06853038) /* 0.407516688 */, 18 }, /* 5910 */ { MAD_F(0x068590a4) /* 0.407608645 */, 18 }, /* 5911 */ { MAD_F(0x0685f112) /* 0.407700606 */, 18 }, /* 5912 */ { MAD_F(0x06865181) /* 0.407792573 */, 18 }, /* 5913 */ { MAD_F(0x0686b1f2) /* 0.407884545 */, 18 }, /* 5914 */ { MAD_F(0x06871264) /* 0.407976522 */, 18 }, /* 5915 */ { MAD_F(0x068772d7) /* 0.408068505 */, 18 }, /* 5916 */ { MAD_F(0x0687d34c) /* 0.408160492 */, 18 }, /* 5917 */ { MAD_F(0x068833c2) /* 0.408252485 */, 18 }, /* 5918 */ { MAD_F(0x06889439) /* 0.408344483 */, 18 }, /* 5919 */ { MAD_F(0x0688f4b2) /* 0.408436486 */, 18 }, /* 5920 */ { MAD_F(0x0689552c) /* 0.408528495 */, 18 }, /* 5921 */ { MAD_F(0x0689b5a8) /* 0.408620508 */, 18 }, /* 5922 */ { MAD_F(0x068a1625) /* 0.408712527 */, 18 }, /* 5923 */ { MAD_F(0x068a76a4) /* 0.408804551 */, 18 }, /* 5924 */ { MAD_F(0x068ad724) /* 0.408896580 */, 18 }, /* 5925 */ { MAD_F(0x068b37a5) /* 0.408988614 */, 18 }, /* 5926 */ { MAD_F(0x068b9827) /* 0.409080653 */, 18 }, /* 5927 */ { MAD_F(0x068bf8ac) /* 0.409172698 */, 18 }, /* 5928 */ { MAD_F(0x068c5931) /* 0.409264748 */, 18 }, /* 5929 */ { MAD_F(0x068cb9b8) /* 0.409356803 */, 18 }, /* 5930 */ { MAD_F(0x068d1a40) /* 0.409448863 */, 18 }, /* 5931 */ { MAD_F(0x068d7aca) /* 0.409540928 */, 18 }, /* 5932 */ { MAD_F(0x068ddb54) /* 0.409632999 */, 18 }, /* 5933 */ { MAD_F(0x068e3be1) /* 0.409725074 */, 18 }, /* 5934 */ { MAD_F(0x068e9c6f) /* 0.409817155 */, 18 }, /* 5935 */ { MAD_F(0x068efcfe) /* 0.409909241 */, 18 }, /* 5936 */ { MAD_F(0x068f5d8e) /* 0.410001332 */, 18 }, /* 5937 */ { MAD_F(0x068fbe20) /* 0.410093428 */, 18 }, /* 5938 */ { MAD_F(0x06901eb4) /* 0.410185530 */, 18 }, /* 5939 */ { MAD_F(0x06907f48) /* 0.410277637 */, 18 }, /* 5940 */ { MAD_F(0x0690dfde) /* 0.410369748 */, 18 }, /* 5941 */ { MAD_F(0x06914076) /* 0.410461865 */, 18 }, /* 5942 */ { MAD_F(0x0691a10f) /* 0.410553988 */, 18 }, /* 5943 */ { MAD_F(0x069201a9) /* 0.410646115 */, 18 }, /* 5944 */ { MAD_F(0x06926245) /* 0.410738247 */, 18 }, /* 5945 */ { MAD_F(0x0692c2e2) /* 0.410830385 */, 18 }, /* 5946 */ { MAD_F(0x06932380) /* 0.410922528 */, 18 }, /* 5947 */ { MAD_F(0x06938420) /* 0.411014676 */, 18 }, /* 5948 */ { MAD_F(0x0693e4c1) /* 0.411106829 */, 18 }, /* 5949 */ { MAD_F(0x06944563) /* 0.411198987 */, 18 }, /* 5950 */ { MAD_F(0x0694a607) /* 0.411291151 */, 18 }, /* 5951 */ { MAD_F(0x069506ad) /* 0.411383320 */, 18 }, /* 5952 */ { MAD_F(0x06956753) /* 0.411475493 */, 18 }, /* 5953 */ { MAD_F(0x0695c7fc) /* 0.411567672 */, 18 }, /* 5954 */ { MAD_F(0x069628a5) /* 0.411659857 */, 18 }, /* 5955 */ { MAD_F(0x06968950) /* 0.411752046 */, 18 }, /* 5956 */ { MAD_F(0x0696e9fc) /* 0.411844240 */, 18 }, /* 5957 */ { MAD_F(0x06974aaa) /* 0.411936440 */, 18 }, /* 5958 */ { MAD_F(0x0697ab59) /* 0.412028645 */, 18 }, /* 5959 */ { MAD_F(0x06980c09) /* 0.412120855 */, 18 }, /* 5960 */ { MAD_F(0x06986cbb) /* 0.412213070 */, 18 }, /* 5961 */ { MAD_F(0x0698cd6e) /* 0.412305290 */, 18 }, /* 5962 */ { MAD_F(0x06992e23) /* 0.412397516 */, 18 }, /* 5963 */ { MAD_F(0x06998ed9) /* 0.412489746 */, 18 }, /* 5964 */ { MAD_F(0x0699ef90) /* 0.412581982 */, 18 }, /* 5965 */ { MAD_F(0x069a5049) /* 0.412674223 */, 18 }, /* 5966 */ { MAD_F(0x069ab103) /* 0.412766469 */, 18 }, /* 5967 */ { MAD_F(0x069b11bf) /* 0.412858720 */, 18 }, /* 5968 */ { MAD_F(0x069b727b) /* 0.412950976 */, 18 }, /* 5969 */ { MAD_F(0x069bd33a) /* 0.413043238 */, 18 }, /* 5970 */ { MAD_F(0x069c33f9) /* 0.413135505 */, 18 }, /* 5971 */ { MAD_F(0x069c94ba) /* 0.413227776 */, 18 }, /* 5972 */ { MAD_F(0x069cf57d) /* 0.413320053 */, 18 }, /* 5973 */ { MAD_F(0x069d5641) /* 0.413412335 */, 18 }, /* 5974 */ { MAD_F(0x069db706) /* 0.413504623 */, 18 }, /* 5975 */ { MAD_F(0x069e17cc) /* 0.413596915 */, 18 }, /* 5976 */ { MAD_F(0x069e7894) /* 0.413689213 */, 18 }, /* 5977 */ { MAD_F(0x069ed95e) /* 0.413781515 */, 18 }, /* 5978 */ { MAD_F(0x069f3a28) /* 0.413873823 */, 18 }, /* 5979 */ { MAD_F(0x069f9af4) /* 0.413966136 */, 18 }, /* 5980 */ { MAD_F(0x069ffbc2) /* 0.414058454 */, 18 }, /* 5981 */ { MAD_F(0x06a05c91) /* 0.414150778 */, 18 }, /* 5982 */ { MAD_F(0x06a0bd61) /* 0.414243106 */, 18 }, /* 5983 */ { MAD_F(0x06a11e32) /* 0.414335440 */, 18 }, /* 5984 */ { MAD_F(0x06a17f05) /* 0.414427779 */, 18 }, /* 5985 */ { MAD_F(0x06a1dfda) /* 0.414520122 */, 18 }, /* 5986 */ { MAD_F(0x06a240b0) /* 0.414612471 */, 18 }, /* 5987 */ { MAD_F(0x06a2a187) /* 0.414704826 */, 18 }, /* 5988 */ { MAD_F(0x06a3025f) /* 0.414797185 */, 18 }, /* 5989 */ { MAD_F(0x06a36339) /* 0.414889549 */, 18 }, /* 5990 */ { MAD_F(0x06a3c414) /* 0.414981919 */, 18 }, /* 5991 */ { MAD_F(0x06a424f1) /* 0.415074294 */, 18 }, /* 5992 */ { MAD_F(0x06a485cf) /* 0.415166674 */, 18 }, /* 5993 */ { MAD_F(0x06a4e6ae) /* 0.415259059 */, 18 }, /* 5994 */ { MAD_F(0x06a5478f) /* 0.415351449 */, 18 }, /* 5995 */ { MAD_F(0x06a5a871) /* 0.415443844 */, 18 }, /* 5996 */ { MAD_F(0x06a60955) /* 0.415536244 */, 18 }, /* 5997 */ { MAD_F(0x06a66a3a) /* 0.415628650 */, 18 }, /* 5998 */ { MAD_F(0x06a6cb20) /* 0.415721061 */, 18 }, /* 5999 */ { MAD_F(0x06a72c08) /* 0.415813476 */, 18 }, /* 6000 */ { MAD_F(0x06a78cf1) /* 0.415905897 */, 18 }, /* 6001 */ { MAD_F(0x06a7eddb) /* 0.415998324 */, 18 }, /* 6002 */ { MAD_F(0x06a84ec7) /* 0.416090755 */, 18 }, /* 6003 */ { MAD_F(0x06a8afb4) /* 0.416183191 */, 18 }, /* 6004 */ { MAD_F(0x06a910a3) /* 0.416275633 */, 18 }, /* 6005 */ { MAD_F(0x06a97193) /* 0.416368079 */, 18 }, /* 6006 */ { MAD_F(0x06a9d284) /* 0.416460531 */, 18 }, /* 6007 */ { MAD_F(0x06aa3377) /* 0.416552988 */, 18 }, /* 6008 */ { MAD_F(0x06aa946b) /* 0.416645450 */, 18 }, /* 6009 */ { MAD_F(0x06aaf561) /* 0.416737917 */, 18 }, /* 6010 */ { MAD_F(0x06ab5657) /* 0.416830389 */, 18 }, /* 6011 */ { MAD_F(0x06abb750) /* 0.416922867 */, 18 }, /* 6012 */ { MAD_F(0x06ac1849) /* 0.417015349 */, 18 }, /* 6013 */ { MAD_F(0x06ac7944) /* 0.417107837 */, 18 }, /* 6014 */ { MAD_F(0x06acda41) /* 0.417200330 */, 18 }, /* 6015 */ { MAD_F(0x06ad3b3e) /* 0.417292828 */, 18 }, /* 6016 */ { MAD_F(0x06ad9c3d) /* 0.417385331 */, 18 }, /* 6017 */ { MAD_F(0x06adfd3e) /* 0.417477839 */, 18 }, /* 6018 */ { MAD_F(0x06ae5e40) /* 0.417570352 */, 18 }, /* 6019 */ { MAD_F(0x06aebf43) /* 0.417662871 */, 18 }, /* 6020 */ { MAD_F(0x06af2047) /* 0.417755394 */, 18 }, /* 6021 */ { MAD_F(0x06af814d) /* 0.417847923 */, 18 }, /* 6022 */ { MAD_F(0x06afe255) /* 0.417940457 */, 18 }, /* 6023 */ { MAD_F(0x06b0435e) /* 0.418032996 */, 18 }, /* 6024 */ { MAD_F(0x06b0a468) /* 0.418125540 */, 18 }, /* 6025 */ { MAD_F(0x06b10573) /* 0.418218089 */, 18 }, /* 6026 */ { MAD_F(0x06b16680) /* 0.418310643 */, 18 }, /* 6027 */ { MAD_F(0x06b1c78e) /* 0.418403203 */, 18 }, /* 6028 */ { MAD_F(0x06b2289e) /* 0.418495767 */, 18 }, /* 6029 */ { MAD_F(0x06b289af) /* 0.418588337 */, 18 }, /* 6030 */ { MAD_F(0x06b2eac1) /* 0.418680911 */, 18 }, /* 6031 */ { MAD_F(0x06b34bd5) /* 0.418773491 */, 18 }, /* 6032 */ { MAD_F(0x06b3acea) /* 0.418866076 */, 18 }, /* 6033 */ { MAD_F(0x06b40e00) /* 0.418958666 */, 18 }, /* 6034 */ { MAD_F(0x06b46f18) /* 0.419051262 */, 18 }, /* 6035 */ { MAD_F(0x06b4d031) /* 0.419143862 */, 18 }, /* 6036 */ { MAD_F(0x06b5314c) /* 0.419236467 */, 18 }, /* 6037 */ { MAD_F(0x06b59268) /* 0.419329078 */, 18 }, /* 6038 */ { MAD_F(0x06b5f385) /* 0.419421694 */, 18 }, /* 6039 */ { MAD_F(0x06b654a4) /* 0.419514314 */, 18 }, /* 6040 */ { MAD_F(0x06b6b5c4) /* 0.419606940 */, 18 }, /* 6041 */ { MAD_F(0x06b716e6) /* 0.419699571 */, 18 }, /* 6042 */ { MAD_F(0x06b77808) /* 0.419792208 */, 18 }, /* 6043 */ { MAD_F(0x06b7d92d) /* 0.419884849 */, 18 }, /* 6044 */ { MAD_F(0x06b83a52) /* 0.419977495 */, 18 }, /* 6045 */ { MAD_F(0x06b89b79) /* 0.420070147 */, 18 }, /* 6046 */ { MAD_F(0x06b8fca1) /* 0.420162803 */, 18 }, /* 6047 */ { MAD_F(0x06b95dcb) /* 0.420255465 */, 18 }, /* 6048 */ { MAD_F(0x06b9bef6) /* 0.420348132 */, 18 }, /* 6049 */ { MAD_F(0x06ba2023) /* 0.420440803 */, 18 }, /* 6050 */ { MAD_F(0x06ba8150) /* 0.420533481 */, 18 }, /* 6051 */ { MAD_F(0x06bae280) /* 0.420626163 */, 18 }, /* 6052 */ { MAD_F(0x06bb43b0) /* 0.420718850 */, 18 }, /* 6053 */ { MAD_F(0x06bba4e2) /* 0.420811542 */, 18 }, /* 6054 */ { MAD_F(0x06bc0615) /* 0.420904240 */, 18 }, /* 6055 */ { MAD_F(0x06bc674a) /* 0.420996942 */, 18 }, /* 6056 */ { MAD_F(0x06bcc880) /* 0.421089650 */, 18 }, /* 6057 */ { MAD_F(0x06bd29b7) /* 0.421182362 */, 18 }, /* 6058 */ { MAD_F(0x06bd8af0) /* 0.421275080 */, 18 }, /* 6059 */ { MAD_F(0x06bdec2a) /* 0.421367803 */, 18 }, /* 6060 */ { MAD_F(0x06be4d66) /* 0.421460531 */, 18 }, /* 6061 */ { MAD_F(0x06beaea3) /* 0.421553264 */, 18 }, /* 6062 */ { MAD_F(0x06bf0fe1) /* 0.421646003 */, 18 }, /* 6063 */ { MAD_F(0x06bf7120) /* 0.421738746 */, 18 }, /* 6064 */ { MAD_F(0x06bfd261) /* 0.421831494 */, 18 }, /* 6065 */ { MAD_F(0x06c033a4) /* 0.421924248 */, 18 }, /* 6066 */ { MAD_F(0x06c094e7) /* 0.422017007 */, 18 }, /* 6067 */ { MAD_F(0x06c0f62c) /* 0.422109770 */, 18 }, /* 6068 */ { MAD_F(0x06c15773) /* 0.422202539 */, 18 }, /* 6069 */ { MAD_F(0x06c1b8bb) /* 0.422295313 */, 18 }, /* 6070 */ { MAD_F(0x06c21a04) /* 0.422388092 */, 18 }, /* 6071 */ { MAD_F(0x06c27b4e) /* 0.422480876 */, 18 }, /* 6072 */ { MAD_F(0x06c2dc9a) /* 0.422573665 */, 18 }, /* 6073 */ { MAD_F(0x06c33de8) /* 0.422666460 */, 18 }, /* 6074 */ { MAD_F(0x06c39f36) /* 0.422759259 */, 18 }, /* 6075 */ { MAD_F(0x06c40086) /* 0.422852064 */, 18 }, /* 6076 */ { MAD_F(0x06c461d8) /* 0.422944873 */, 18 }, /* 6077 */ { MAD_F(0x06c4c32a) /* 0.423037688 */, 18 }, /* 6078 */ { MAD_F(0x06c5247f) /* 0.423130508 */, 18 }, /* 6079 */ { MAD_F(0x06c585d4) /* 0.423223333 */, 18 }, /* 6080 */ { MAD_F(0x06c5e72b) /* 0.423316162 */, 18 }, /* 6081 */ { MAD_F(0x06c64883) /* 0.423408997 */, 18 }, /* 6082 */ { MAD_F(0x06c6a9dd) /* 0.423501838 */, 18 }, /* 6083 */ { MAD_F(0x06c70b38) /* 0.423594683 */, 18 }, /* 6084 */ { MAD_F(0x06c76c94) /* 0.423687533 */, 18 }, /* 6085 */ { MAD_F(0x06c7cdf2) /* 0.423780389 */, 18 }, /* 6086 */ { MAD_F(0x06c82f51) /* 0.423873249 */, 18 }, /* 6087 */ { MAD_F(0x06c890b1) /* 0.423966115 */, 18 }, /* 6088 */ { MAD_F(0x06c8f213) /* 0.424058985 */, 18 }, /* 6089 */ { MAD_F(0x06c95376) /* 0.424151861 */, 18 }, /* 6090 */ { MAD_F(0x06c9b4da) /* 0.424244742 */, 18 }, /* 6091 */ { MAD_F(0x06ca1640) /* 0.424337628 */, 18 }, /* 6092 */ { MAD_F(0x06ca77a8) /* 0.424430519 */, 18 }, /* 6093 */ { MAD_F(0x06cad910) /* 0.424523415 */, 18 }, /* 6094 */ { MAD_F(0x06cb3a7a) /* 0.424616316 */, 18 }, /* 6095 */ { MAD_F(0x06cb9be5) /* 0.424709222 */, 18 }, /* 6096 */ { MAD_F(0x06cbfd52) /* 0.424802133 */, 18 }, /* 6097 */ { MAD_F(0x06cc5ec0) /* 0.424895050 */, 18 }, /* 6098 */ { MAD_F(0x06ccc030) /* 0.424987971 */, 18 }, /* 6099 */ { MAD_F(0x06cd21a0) /* 0.425080898 */, 18 }, /* 6100 */ { MAD_F(0x06cd8313) /* 0.425173829 */, 18 }, /* 6101 */ { MAD_F(0x06cde486) /* 0.425266766 */, 18 }, /* 6102 */ { MAD_F(0x06ce45fb) /* 0.425359708 */, 18 }, /* 6103 */ { MAD_F(0x06cea771) /* 0.425452655 */, 18 }, /* 6104 */ { MAD_F(0x06cf08e9) /* 0.425545607 */, 18 }, /* 6105 */ { MAD_F(0x06cf6a62) /* 0.425638564 */, 18 }, /* 6106 */ { MAD_F(0x06cfcbdc) /* 0.425731526 */, 18 }, /* 6107 */ { MAD_F(0x06d02d58) /* 0.425824493 */, 18 }, /* 6108 */ { MAD_F(0x06d08ed5) /* 0.425917465 */, 18 }, /* 6109 */ { MAD_F(0x06d0f053) /* 0.426010443 */, 18 }, /* 6110 */ { MAD_F(0x06d151d3) /* 0.426103425 */, 18 }, /* 6111 */ { MAD_F(0x06d1b354) /* 0.426196412 */, 18 }, /* 6112 */ { MAD_F(0x06d214d7) /* 0.426289405 */, 18 }, /* 6113 */ { MAD_F(0x06d2765a) /* 0.426382403 */, 18 }, /* 6114 */ { MAD_F(0x06d2d7e0) /* 0.426475405 */, 18 }, /* 6115 */ { MAD_F(0x06d33966) /* 0.426568413 */, 18 }, /* 6116 */ { MAD_F(0x06d39aee) /* 0.426661426 */, 18 }, /* 6117 */ { MAD_F(0x06d3fc77) /* 0.426754444 */, 18 }, /* 6118 */ { MAD_F(0x06d45e02) /* 0.426847467 */, 18 }, /* 6119 */ { MAD_F(0x06d4bf8e) /* 0.426940495 */, 18 }, /* 6120 */ { MAD_F(0x06d5211c) /* 0.427033528 */, 18 }, /* 6121 */ { MAD_F(0x06d582aa) /* 0.427126566 */, 18 }, /* 6122 */ { MAD_F(0x06d5e43a) /* 0.427219609 */, 18 }, /* 6123 */ { MAD_F(0x06d645cc) /* 0.427312657 */, 18 }, /* 6124 */ { MAD_F(0x06d6a75f) /* 0.427405711 */, 18 }, /* 6125 */ { MAD_F(0x06d708f3) /* 0.427498769 */, 18 }, /* 6126 */ { MAD_F(0x06d76a88) /* 0.427591833 */, 18 }, /* 6127 */ { MAD_F(0x06d7cc1f) /* 0.427684901 */, 18 }, /* 6128 */ { MAD_F(0x06d82db8) /* 0.427777975 */, 18 }, /* 6129 */ { MAD_F(0x06d88f51) /* 0.427871054 */, 18 }, /* 6130 */ { MAD_F(0x06d8f0ec) /* 0.427964137 */, 18 }, /* 6131 */ { MAD_F(0x06d95288) /* 0.428057226 */, 18 }, /* 6132 */ { MAD_F(0x06d9b426) /* 0.428150320 */, 18 }, /* 6133 */ { MAD_F(0x06da15c5) /* 0.428243419 */, 18 }, /* 6134 */ { MAD_F(0x06da7766) /* 0.428336523 */, 18 }, /* 6135 */ { MAD_F(0x06dad907) /* 0.428429632 */, 18 }, /* 6136 */ { MAD_F(0x06db3aaa) /* 0.428522746 */, 18 }, /* 6137 */ { MAD_F(0x06db9c4f) /* 0.428615865 */, 18 }, /* 6138 */ { MAD_F(0x06dbfdf5) /* 0.428708989 */, 18 }, /* 6139 */ { MAD_F(0x06dc5f9c) /* 0.428802119 */, 18 }, /* 6140 */ { MAD_F(0x06dcc145) /* 0.428895253 */, 18 }, /* 6141 */ { MAD_F(0x06dd22ee) /* 0.428988392 */, 18 }, /* 6142 */ { MAD_F(0x06dd849a) /* 0.429081537 */, 18 }, /* 6143 */ { MAD_F(0x06dde646) /* 0.429174686 */, 18 }, /* 6144 */ { MAD_F(0x06de47f4) /* 0.429267841 */, 18 }, /* 6145 */ { MAD_F(0x06dea9a4) /* 0.429361001 */, 18 }, /* 6146 */ { MAD_F(0x06df0b54) /* 0.429454165 */, 18 }, /* 6147 */ { MAD_F(0x06df6d06) /* 0.429547335 */, 18 }, /* 6148 */ { MAD_F(0x06dfceba) /* 0.429640510 */, 18 }, /* 6149 */ { MAD_F(0x06e0306f) /* 0.429733690 */, 18 }, /* 6150 */ { MAD_F(0x06e09225) /* 0.429826874 */, 18 }, /* 6151 */ { MAD_F(0x06e0f3dc) /* 0.429920064 */, 18 }, /* 6152 */ { MAD_F(0x06e15595) /* 0.430013259 */, 18 }, /* 6153 */ { MAD_F(0x06e1b74f) /* 0.430106459 */, 18 }, /* 6154 */ { MAD_F(0x06e2190b) /* 0.430199664 */, 18 }, /* 6155 */ { MAD_F(0x06e27ac8) /* 0.430292875 */, 18 }, /* 6156 */ { MAD_F(0x06e2dc86) /* 0.430386090 */, 18 }, /* 6157 */ { MAD_F(0x06e33e46) /* 0.430479310 */, 18 }, /* 6158 */ { MAD_F(0x06e3a007) /* 0.430572535 */, 18 }, /* 6159 */ { MAD_F(0x06e401c9) /* 0.430665765 */, 18 }, /* 6160 */ { MAD_F(0x06e4638d) /* 0.430759001 */, 18 }, /* 6161 */ { MAD_F(0x06e4c552) /* 0.430852241 */, 18 }, /* 6162 */ { MAD_F(0x06e52718) /* 0.430945487 */, 18 }, /* 6163 */ { MAD_F(0x06e588e0) /* 0.431038737 */, 18 }, /* 6164 */ { MAD_F(0x06e5eaa9) /* 0.431131993 */, 18 }, /* 6165 */ { MAD_F(0x06e64c73) /* 0.431225253 */, 18 }, /* 6166 */ { MAD_F(0x06e6ae3f) /* 0.431318519 */, 18 }, /* 6167 */ { MAD_F(0x06e7100c) /* 0.431411790 */, 18 }, /* 6168 */ { MAD_F(0x06e771db) /* 0.431505065 */, 18 }, /* 6169 */ { MAD_F(0x06e7d3ab) /* 0.431598346 */, 18 }, /* 6170 */ { MAD_F(0x06e8357c) /* 0.431691632 */, 18 }, /* 6171 */ { MAD_F(0x06e8974e) /* 0.431784923 */, 18 }, /* 6172 */ { MAD_F(0x06e8f922) /* 0.431878218 */, 18 }, /* 6173 */ { MAD_F(0x06e95af8) /* 0.431971519 */, 18 }, /* 6174 */ { MAD_F(0x06e9bcce) /* 0.432064825 */, 18 }, /* 6175 */ { MAD_F(0x06ea1ea6) /* 0.432158136 */, 18 }, /* 6176 */ { MAD_F(0x06ea807f) /* 0.432251452 */, 18 }, /* 6177 */ { MAD_F(0x06eae25a) /* 0.432344773 */, 18 }, /* 6178 */ { MAD_F(0x06eb4436) /* 0.432438099 */, 18 }, /* 6179 */ { MAD_F(0x06eba614) /* 0.432531431 */, 18 }, /* 6180 */ { MAD_F(0x06ec07f2) /* 0.432624767 */, 18 }, /* 6181 */ { MAD_F(0x06ec69d2) /* 0.432718108 */, 18 }, /* 6182 */ { MAD_F(0x06eccbb4) /* 0.432811454 */, 18 }, /* 6183 */ { MAD_F(0x06ed2d97) /* 0.432904805 */, 18 }, /* 6184 */ { MAD_F(0x06ed8f7b) /* 0.432998162 */, 18 }, /* 6185 */ { MAD_F(0x06edf160) /* 0.433091523 */, 18 }, /* 6186 */ { MAD_F(0x06ee5347) /* 0.433184889 */, 18 }, /* 6187 */ { MAD_F(0x06eeb52f) /* 0.433278261 */, 18 }, /* 6188 */ { MAD_F(0x06ef1719) /* 0.433371637 */, 18 }, /* 6189 */ { MAD_F(0x06ef7904) /* 0.433465019 */, 18 }, /* 6190 */ { MAD_F(0x06efdaf0) /* 0.433558405 */, 18 }, /* 6191 */ { MAD_F(0x06f03cde) /* 0.433651797 */, 18 }, /* 6192 */ { MAD_F(0x06f09ecc) /* 0.433745193 */, 18 }, /* 6193 */ { MAD_F(0x06f100bd) /* 0.433838595 */, 18 }, /* 6194 */ { MAD_F(0x06f162ae) /* 0.433932001 */, 18 }, /* 6195 */ { MAD_F(0x06f1c4a1) /* 0.434025413 */, 18 }, /* 6196 */ { MAD_F(0x06f22696) /* 0.434118830 */, 18 }, /* 6197 */ { MAD_F(0x06f2888b) /* 0.434212251 */, 18 }, /* 6198 */ { MAD_F(0x06f2ea82) /* 0.434305678 */, 18 }, /* 6199 */ { MAD_F(0x06f34c7b) /* 0.434399110 */, 18 }, /* 6200 */ { MAD_F(0x06f3ae75) /* 0.434492546 */, 18 }, /* 6201 */ { MAD_F(0x06f41070) /* 0.434585988 */, 18 }, /* 6202 */ { MAD_F(0x06f4726c) /* 0.434679435 */, 18 }, /* 6203 */ { MAD_F(0x06f4d46a) /* 0.434772887 */, 18 }, /* 6204 */ { MAD_F(0x06f53669) /* 0.434866344 */, 18 }, /* 6205 */ { MAD_F(0x06f59869) /* 0.434959806 */, 18 }, /* 6206 */ { MAD_F(0x06f5fa6b) /* 0.435053272 */, 18 }, /* 6207 */ { MAD_F(0x06f65c6e) /* 0.435146744 */, 18 }, /* 6208 */ { MAD_F(0x06f6be73) /* 0.435240221 */, 18 }, /* 6209 */ { MAD_F(0x06f72079) /* 0.435333703 */, 18 }, /* 6210 */ { MAD_F(0x06f78280) /* 0.435427190 */, 18 }, /* 6211 */ { MAD_F(0x06f7e489) /* 0.435520682 */, 18 }, /* 6212 */ { MAD_F(0x06f84693) /* 0.435614179 */, 18 }, /* 6213 */ { MAD_F(0x06f8a89e) /* 0.435707681 */, 18 }, /* 6214 */ { MAD_F(0x06f90aaa) /* 0.435801188 */, 18 }, /* 6215 */ { MAD_F(0x06f96cb8) /* 0.435894700 */, 18 }, /* 6216 */ { MAD_F(0x06f9cec8) /* 0.435988217 */, 18 }, /* 6217 */ { MAD_F(0x06fa30d8) /* 0.436081739 */, 18 }, /* 6218 */ { MAD_F(0x06fa92ea) /* 0.436175266 */, 18 }, /* 6219 */ { MAD_F(0x06faf4fe) /* 0.436268799 */, 18 }, /* 6220 */ { MAD_F(0x06fb5712) /* 0.436362336 */, 18 }, /* 6221 */ { MAD_F(0x06fbb928) /* 0.436455878 */, 18 }, /* 6222 */ { MAD_F(0x06fc1b40) /* 0.436549425 */, 18 }, /* 6223 */ { MAD_F(0x06fc7d58) /* 0.436642977 */, 18 }, /* 6224 */ { MAD_F(0x06fcdf72) /* 0.436736534 */, 18 }, /* 6225 */ { MAD_F(0x06fd418e) /* 0.436830096 */, 18 }, /* 6226 */ { MAD_F(0x06fda3ab) /* 0.436923664 */, 18 }, /* 6227 */ { MAD_F(0x06fe05c9) /* 0.437017236 */, 18 }, /* 6228 */ { MAD_F(0x06fe67e8) /* 0.437110813 */, 18 }, /* 6229 */ { MAD_F(0x06feca09) /* 0.437204395 */, 18 }, /* 6230 */ { MAD_F(0x06ff2c2b) /* 0.437297982 */, 18 }, /* 6231 */ { MAD_F(0x06ff8e4f) /* 0.437391575 */, 18 }, /* 6232 */ { MAD_F(0x06fff073) /* 0.437485172 */, 18 }, /* 6233 */ { MAD_F(0x0700529a) /* 0.437578774 */, 18 }, /* 6234 */ { MAD_F(0x0700b4c1) /* 0.437672381 */, 18 }, /* 6235 */ { MAD_F(0x070116ea) /* 0.437765994 */, 18 }, /* 6236 */ { MAD_F(0x07017914) /* 0.437859611 */, 18 }, /* 6237 */ { MAD_F(0x0701db40) /* 0.437953233 */, 18 }, /* 6238 */ { MAD_F(0x07023d6c) /* 0.438046860 */, 18 }, /* 6239 */ { MAD_F(0x07029f9b) /* 0.438140493 */, 18 }, /* 6240 */ { MAD_F(0x070301ca) /* 0.438234130 */, 18 }, /* 6241 */ { MAD_F(0x070363fb) /* 0.438327772 */, 18 }, /* 6242 */ { MAD_F(0x0703c62d) /* 0.438421419 */, 18 }, /* 6243 */ { MAD_F(0x07042861) /* 0.438515072 */, 18 }, /* 6244 */ { MAD_F(0x07048a96) /* 0.438608729 */, 18 }, /* 6245 */ { MAD_F(0x0704eccc) /* 0.438702391 */, 18 }, /* 6246 */ { MAD_F(0x07054f04) /* 0.438796059 */, 18 }, /* 6247 */ { MAD_F(0x0705b13d) /* 0.438889731 */, 18 }, /* 6248 */ { MAD_F(0x07061377) /* 0.438983408 */, 18 }, /* 6249 */ { MAD_F(0x070675b3) /* 0.439077090 */, 18 }, /* 6250 */ { MAD_F(0x0706d7f0) /* 0.439170778 */, 18 }, /* 6251 */ { MAD_F(0x07073a2e) /* 0.439264470 */, 18 }, /* 6252 */ { MAD_F(0x07079c6e) /* 0.439358167 */, 18 }, /* 6253 */ { MAD_F(0x0707feaf) /* 0.439451869 */, 18 }, /* 6254 */ { MAD_F(0x070860f1) /* 0.439545577 */, 18 }, /* 6255 */ { MAD_F(0x0708c335) /* 0.439639289 */, 18 }, /* 6256 */ { MAD_F(0x0709257a) /* 0.439733006 */, 18 }, /* 6257 */ { MAD_F(0x070987c0) /* 0.439826728 */, 18 }, /* 6258 */ { MAD_F(0x0709ea08) /* 0.439920456 */, 18 }, /* 6259 */ { MAD_F(0x070a4c51) /* 0.440014188 */, 18 }, /* 6260 */ { MAD_F(0x070aae9b) /* 0.440107925 */, 18 }, /* 6261 */ { MAD_F(0x070b10e7) /* 0.440201667 */, 18 }, /* 6262 */ { MAD_F(0x070b7334) /* 0.440295414 */, 18 }, /* 6263 */ { MAD_F(0x070bd583) /* 0.440389167 */, 18 }, /* 6264 */ { MAD_F(0x070c37d2) /* 0.440482924 */, 18 }, /* 6265 */ { MAD_F(0x070c9a23) /* 0.440576686 */, 18 }, /* 6266 */ { MAD_F(0x070cfc76) /* 0.440670453 */, 18 }, /* 6267 */ { MAD_F(0x070d5eca) /* 0.440764225 */, 18 }, /* 6268 */ { MAD_F(0x070dc11f) /* 0.440858002 */, 18 }, /* 6269 */ { MAD_F(0x070e2375) /* 0.440951784 */, 18 }, /* 6270 */ { MAD_F(0x070e85cd) /* 0.441045572 */, 18 }, /* 6271 */ { MAD_F(0x070ee826) /* 0.441139364 */, 18 }, /* 6272 */ { MAD_F(0x070f4a80) /* 0.441233161 */, 18 }, /* 6273 */ { MAD_F(0x070facdc) /* 0.441326963 */, 18 }, /* 6274 */ { MAD_F(0x07100f39) /* 0.441420770 */, 18 }, /* 6275 */ { MAD_F(0x07107198) /* 0.441514582 */, 18 }, /* 6276 */ { MAD_F(0x0710d3f8) /* 0.441608399 */, 18 }, /* 6277 */ { MAD_F(0x07113659) /* 0.441702221 */, 18 }, /* 6278 */ { MAD_F(0x071198bb) /* 0.441796048 */, 18 }, /* 6279 */ { MAD_F(0x0711fb1f) /* 0.441889880 */, 18 }, /* 6280 */ { MAD_F(0x07125d84) /* 0.441983717 */, 18 }, /* 6281 */ { MAD_F(0x0712bfeb) /* 0.442077559 */, 18 }, /* 6282 */ { MAD_F(0x07132253) /* 0.442171406 */, 18 }, /* 6283 */ { MAD_F(0x071384bc) /* 0.442265257 */, 18 }, /* 6284 */ { MAD_F(0x0713e726) /* 0.442359114 */, 18 }, /* 6285 */ { MAD_F(0x07144992) /* 0.442452976 */, 18 }, /* 6286 */ { MAD_F(0x0714abff) /* 0.442546843 */, 18 }, /* 6287 */ { MAD_F(0x07150e6e) /* 0.442640715 */, 18 }, /* 6288 */ { MAD_F(0x071570de) /* 0.442734592 */, 18 }, /* 6289 */ { MAD_F(0x0715d34f) /* 0.442828473 */, 18 }, /* 6290 */ { MAD_F(0x071635c1) /* 0.442922360 */, 18 }, /* 6291 */ { MAD_F(0x07169835) /* 0.443016252 */, 18 }, /* 6292 */ { MAD_F(0x0716faaa) /* 0.443110148 */, 18 }, /* 6293 */ { MAD_F(0x07175d21) /* 0.443204050 */, 18 }, /* 6294 */ { MAD_F(0x0717bf99) /* 0.443297957 */, 18 }, /* 6295 */ { MAD_F(0x07182212) /* 0.443391868 */, 18 }, /* 6296 */ { MAD_F(0x0718848d) /* 0.443485785 */, 18 }, /* 6297 */ { MAD_F(0x0718e709) /* 0.443579706 */, 18 }, /* 6298 */ { MAD_F(0x07194986) /* 0.443673633 */, 18 }, /* 6299 */ { MAD_F(0x0719ac04) /* 0.443767564 */, 18 }, /* 6300 */ { MAD_F(0x071a0e84) /* 0.443861501 */, 18 }, /* 6301 */ { MAD_F(0x071a7105) /* 0.443955442 */, 18 }, /* 6302 */ { MAD_F(0x071ad388) /* 0.444049389 */, 18 }, /* 6303 */ { MAD_F(0x071b360c) /* 0.444143340 */, 18 }, /* 6304 */ { MAD_F(0x071b9891) /* 0.444237296 */, 18 }, /* 6305 */ { MAD_F(0x071bfb18) /* 0.444331258 */, 18 }, /* 6306 */ { MAD_F(0x071c5d9f) /* 0.444425224 */, 18 }, /* 6307 */ { MAD_F(0x071cc029) /* 0.444519195 */, 18 }, /* 6308 */ { MAD_F(0x071d22b3) /* 0.444613171 */, 18 }, /* 6309 */ { MAD_F(0x071d853f) /* 0.444707153 */, 18 }, /* 6310 */ { MAD_F(0x071de7cc) /* 0.444801139 */, 18 }, /* 6311 */ { MAD_F(0x071e4a5b) /* 0.444895130 */, 18 }, /* 6312 */ { MAD_F(0x071eaceb) /* 0.444989126 */, 18 }, /* 6313 */ { MAD_F(0x071f0f7c) /* 0.445083127 */, 18 }, /* 6314 */ { MAD_F(0x071f720e) /* 0.445177133 */, 18 }, /* 6315 */ { MAD_F(0x071fd4a2) /* 0.445271144 */, 18 }, /* 6316 */ { MAD_F(0x07203737) /* 0.445365160 */, 18 }, /* 6317 */ { MAD_F(0x072099ce) /* 0.445459181 */, 18 }, /* 6318 */ { MAD_F(0x0720fc66) /* 0.445553206 */, 18 }, /* 6319 */ { MAD_F(0x07215eff) /* 0.445647237 */, 18 }, /* 6320 */ { MAD_F(0x0721c19a) /* 0.445741273 */, 18 }, /* 6321 */ { MAD_F(0x07222436) /* 0.445835314 */, 18 }, /* 6322 */ { MAD_F(0x072286d3) /* 0.445929359 */, 18 }, /* 6323 */ { MAD_F(0x0722e971) /* 0.446023410 */, 18 }, /* 6324 */ { MAD_F(0x07234c11) /* 0.446117466 */, 18 }, /* 6325 */ { MAD_F(0x0723aeb2) /* 0.446211526 */, 18 }, /* 6326 */ { MAD_F(0x07241155) /* 0.446305592 */, 18 }, /* 6327 */ { MAD_F(0x072473f9) /* 0.446399662 */, 18 }, /* 6328 */ { MAD_F(0x0724d69e) /* 0.446493738 */, 18 }, /* 6329 */ { MAD_F(0x07253944) /* 0.446587818 */, 18 }, /* 6330 */ { MAD_F(0x07259bec) /* 0.446681903 */, 18 }, /* 6331 */ { MAD_F(0x0725fe95) /* 0.446775994 */, 18 }, /* 6332 */ { MAD_F(0x07266140) /* 0.446870089 */, 18 }, /* 6333 */ { MAD_F(0x0726c3ec) /* 0.446964189 */, 18 }, /* 6334 */ { MAD_F(0x07272699) /* 0.447058294 */, 18 }, /* 6335 */ { MAD_F(0x07278947) /* 0.447152404 */, 18 }, /* 6336 */ { MAD_F(0x0727ebf7) /* 0.447246519 */, 18 }, /* 6337 */ { MAD_F(0x07284ea8) /* 0.447340639 */, 18 }, /* 6338 */ { MAD_F(0x0728b15b) /* 0.447434764 */, 18 }, /* 6339 */ { MAD_F(0x0729140f) /* 0.447528894 */, 18 }, /* 6340 */ { MAD_F(0x072976c4) /* 0.447623029 */, 18 }, /* 6341 */ { MAD_F(0x0729d97a) /* 0.447717169 */, 18 }, /* 6342 */ { MAD_F(0x072a3c32) /* 0.447811314 */, 18 }, /* 6343 */ { MAD_F(0x072a9eeb) /* 0.447905463 */, 18 }, /* 6344 */ { MAD_F(0x072b01a6) /* 0.447999618 */, 18 }, /* 6345 */ { MAD_F(0x072b6461) /* 0.448093778 */, 18 }, /* 6346 */ { MAD_F(0x072bc71e) /* 0.448187942 */, 18 }, /* 6347 */ { MAD_F(0x072c29dd) /* 0.448282112 */, 18 }, /* 6348 */ { MAD_F(0x072c8c9d) /* 0.448376286 */, 18 }, /* 6349 */ { MAD_F(0x072cef5e) /* 0.448470466 */, 18 }, /* 6350 */ { MAD_F(0x072d5220) /* 0.448564650 */, 18 }, /* 6351 */ { MAD_F(0x072db4e4) /* 0.448658839 */, 18 }, /* 6352 */ { MAD_F(0x072e17a9) /* 0.448753033 */, 18 }, /* 6353 */ { MAD_F(0x072e7a6f) /* 0.448847233 */, 18 }, /* 6354 */ { MAD_F(0x072edd37) /* 0.448941437 */, 18 }, /* 6355 */ { MAD_F(0x072f4000) /* 0.449035646 */, 18 }, /* 6356 */ { MAD_F(0x072fa2ca) /* 0.449129860 */, 18 }, /* 6357 */ { MAD_F(0x07300596) /* 0.449224079 */, 18 }, /* 6358 */ { MAD_F(0x07306863) /* 0.449318303 */, 18 }, /* 6359 */ { MAD_F(0x0730cb32) /* 0.449412531 */, 18 }, /* 6360 */ { MAD_F(0x07312e01) /* 0.449506765 */, 18 }, /* 6361 */ { MAD_F(0x073190d2) /* 0.449601004 */, 18 }, /* 6362 */ { MAD_F(0x0731f3a5) /* 0.449695247 */, 18 }, /* 6363 */ { MAD_F(0x07325678) /* 0.449789496 */, 18 }, /* 6364 */ { MAD_F(0x0732b94d) /* 0.449883749 */, 18 }, /* 6365 */ { MAD_F(0x07331c23) /* 0.449978008 */, 18 }, /* 6366 */ { MAD_F(0x07337efb) /* 0.450072271 */, 18 }, /* 6367 */ { MAD_F(0x0733e1d4) /* 0.450166540 */, 18 }, /* 6368 */ { MAD_F(0x073444ae) /* 0.450260813 */, 18 }, /* 6369 */ { MAD_F(0x0734a78a) /* 0.450355091 */, 18 }, /* 6370 */ { MAD_F(0x07350a67) /* 0.450449374 */, 18 }, /* 6371 */ { MAD_F(0x07356d45) /* 0.450543662 */, 18 }, /* 6372 */ { MAD_F(0x0735d025) /* 0.450637955 */, 18 }, /* 6373 */ { MAD_F(0x07363306) /* 0.450732253 */, 18 }, /* 6374 */ { MAD_F(0x073695e8) /* 0.450826556 */, 18 }, /* 6375 */ { MAD_F(0x0736f8cb) /* 0.450920864 */, 18 }, /* 6376 */ { MAD_F(0x07375bb0) /* 0.451015176 */, 18 }, /* 6377 */ { MAD_F(0x0737be96) /* 0.451109494 */, 18 }, /* 6378 */ { MAD_F(0x0738217e) /* 0.451203817 */, 18 }, /* 6379 */ { MAD_F(0x07388467) /* 0.451298144 */, 18 }, /* 6380 */ { MAD_F(0x0738e751) /* 0.451392477 */, 18 }, /* 6381 */ { MAD_F(0x07394a3d) /* 0.451486814 */, 18 }, /* 6382 */ { MAD_F(0x0739ad29) /* 0.451581156 */, 18 }, /* 6383 */ { MAD_F(0x073a1017) /* 0.451675503 */, 18 }, /* 6384 */ { MAD_F(0x073a7307) /* 0.451769856 */, 18 }, /* 6385 */ { MAD_F(0x073ad5f8) /* 0.451864213 */, 18 }, /* 6386 */ { MAD_F(0x073b38ea) /* 0.451958575 */, 18 }, /* 6387 */ { MAD_F(0x073b9bdd) /* 0.452052942 */, 18 }, /* 6388 */ { MAD_F(0x073bfed2) /* 0.452147313 */, 18 }, /* 6389 */ { MAD_F(0x073c61c8) /* 0.452241690 */, 18 }, /* 6390 */ { MAD_F(0x073cc4bf) /* 0.452336072 */, 18 }, /* 6391 */ { MAD_F(0x073d27b8) /* 0.452430458 */, 18 }, /* 6392 */ { MAD_F(0x073d8ab2) /* 0.452524850 */, 18 }, /* 6393 */ { MAD_F(0x073dedae) /* 0.452619246 */, 18 }, /* 6394 */ { MAD_F(0x073e50aa) /* 0.452713648 */, 18 }, /* 6395 */ { MAD_F(0x073eb3a8) /* 0.452808054 */, 18 }, /* 6396 */ { MAD_F(0x073f16a8) /* 0.452902465 */, 18 }, /* 6397 */ { MAD_F(0x073f79a8) /* 0.452996882 */, 18 }, /* 6398 */ { MAD_F(0x073fdcaa) /* 0.453091303 */, 18 }, /* 6399 */ { MAD_F(0x07403fad) /* 0.453185729 */, 18 }, /* 6400 */ { MAD_F(0x0740a2b2) /* 0.453280160 */, 18 }, /* 6401 */ { MAD_F(0x074105b8) /* 0.453374595 */, 18 }, /* 6402 */ { MAD_F(0x074168bf) /* 0.453469036 */, 18 }, /* 6403 */ { MAD_F(0x0741cbc8) /* 0.453563482 */, 18 }, /* 6404 */ { MAD_F(0x07422ed2) /* 0.453657932 */, 18 }, /* 6405 */ { MAD_F(0x074291dd) /* 0.453752388 */, 18 }, /* 6406 */ { MAD_F(0x0742f4e9) /* 0.453846848 */, 18 }, /* 6407 */ { MAD_F(0x074357f7) /* 0.453941314 */, 18 }, /* 6408 */ { MAD_F(0x0743bb06) /* 0.454035784 */, 18 }, /* 6409 */ { MAD_F(0x07441e17) /* 0.454130259 */, 18 }, /* 6410 */ { MAD_F(0x07448129) /* 0.454224739 */, 18 }, /* 6411 */ { MAD_F(0x0744e43c) /* 0.454319224 */, 18 }, /* 6412 */ { MAD_F(0x07454750) /* 0.454413714 */, 18 }, /* 6413 */ { MAD_F(0x0745aa66) /* 0.454508209 */, 18 }, /* 6414 */ { MAD_F(0x07460d7d) /* 0.454602708 */, 18 }, /* 6415 */ { MAD_F(0x07467095) /* 0.454697213 */, 18 }, /* 6416 */ { MAD_F(0x0746d3af) /* 0.454791723 */, 18 }, /* 6417 */ { MAD_F(0x074736ca) /* 0.454886237 */, 18 }, /* 6418 */ { MAD_F(0x074799e7) /* 0.454980756 */, 18 }, /* 6419 */ { MAD_F(0x0747fd04) /* 0.455075281 */, 18 }, /* 6420 */ { MAD_F(0x07486023) /* 0.455169810 */, 18 }, /* 6421 */ { MAD_F(0x0748c344) /* 0.455264344 */, 18 }, /* 6422 */ { MAD_F(0x07492665) /* 0.455358883 */, 18 }, /* 6423 */ { MAD_F(0x07498988) /* 0.455453427 */, 18 }, /* 6424 */ { MAD_F(0x0749ecac) /* 0.455547976 */, 18 }, /* 6425 */ { MAD_F(0x074a4fd2) /* 0.455642529 */, 18 }, /* 6426 */ { MAD_F(0x074ab2f9) /* 0.455737088 */, 18 }, /* 6427 */ { MAD_F(0x074b1621) /* 0.455831652 */, 18 }, /* 6428 */ { MAD_F(0x074b794b) /* 0.455926220 */, 18 }, /* 6429 */ { MAD_F(0x074bdc75) /* 0.456020793 */, 18 }, /* 6430 */ { MAD_F(0x074c3fa1) /* 0.456115372 */, 18 }, /* 6431 */ { MAD_F(0x074ca2cf) /* 0.456209955 */, 18 }, /* 6432 */ { MAD_F(0x074d05fe) /* 0.456304543 */, 18 }, /* 6433 */ { MAD_F(0x074d692e) /* 0.456399136 */, 18 }, /* 6434 */ { MAD_F(0x074dcc5f) /* 0.456493733 */, 18 }, /* 6435 */ { MAD_F(0x074e2f92) /* 0.456588336 */, 18 }, /* 6436 */ { MAD_F(0x074e92c6) /* 0.456682944 */, 18 }, /* 6437 */ { MAD_F(0x074ef5fb) /* 0.456777556 */, 18 }, /* 6438 */ { MAD_F(0x074f5932) /* 0.456872174 */, 18 }, /* 6439 */ { MAD_F(0x074fbc6a) /* 0.456966796 */, 18 }, /* 6440 */ { MAD_F(0x07501fa3) /* 0.457061423 */, 18 }, /* 6441 */ { MAD_F(0x075082de) /* 0.457156056 */, 18 }, /* 6442 */ { MAD_F(0x0750e61a) /* 0.457250693 */, 18 }, /* 6443 */ { MAD_F(0x07514957) /* 0.457345335 */, 18 }, /* 6444 */ { MAD_F(0x0751ac96) /* 0.457439981 */, 18 }, /* 6445 */ { MAD_F(0x07520fd6) /* 0.457534633 */, 18 }, /* 6446 */ { MAD_F(0x07527317) /* 0.457629290 */, 18 }, /* 6447 */ { MAD_F(0x0752d659) /* 0.457723951 */, 18 }, /* 6448 */ { MAD_F(0x0753399d) /* 0.457818618 */, 18 }, /* 6449 */ { MAD_F(0x07539ce2) /* 0.457913289 */, 18 }, /* 6450 */ { MAD_F(0x07540029) /* 0.458007965 */, 18 }, /* 6451 */ { MAD_F(0x07546371) /* 0.458102646 */, 18 }, /* 6452 */ { MAD_F(0x0754c6ba) /* 0.458197332 */, 18 }, /* 6453 */ { MAD_F(0x07552a04) /* 0.458292023 */, 18 }, /* 6454 */ { MAD_F(0x07558d50) /* 0.458386719 */, 18 }, /* 6455 */ { MAD_F(0x0755f09d) /* 0.458481420 */, 18 }, /* 6456 */ { MAD_F(0x075653eb) /* 0.458576125 */, 18 }, /* 6457 */ { MAD_F(0x0756b73b) /* 0.458670836 */, 18 }, /* 6458 */ { MAD_F(0x07571a8c) /* 0.458765551 */, 18 }, /* 6459 */ { MAD_F(0x07577dde) /* 0.458860271 */, 18 }, /* 6460 */ { MAD_F(0x0757e131) /* 0.458954996 */, 18 }, /* 6461 */ { MAD_F(0x07584486) /* 0.459049726 */, 18 }, /* 6462 */ { MAD_F(0x0758a7dd) /* 0.459144461 */, 18 }, /* 6463 */ { MAD_F(0x07590b34) /* 0.459239201 */, 18 }, /* 6464 */ { MAD_F(0x07596e8d) /* 0.459333946 */, 18 }, /* 6465 */ { MAD_F(0x0759d1e7) /* 0.459428695 */, 18 }, /* 6466 */ { MAD_F(0x075a3542) /* 0.459523450 */, 18 }, /* 6467 */ { MAD_F(0x075a989f) /* 0.459618209 */, 18 }, /* 6468 */ { MAD_F(0x075afbfd) /* 0.459712973 */, 18 }, /* 6469 */ { MAD_F(0x075b5f5d) /* 0.459807742 */, 18 }, /* 6470 */ { MAD_F(0x075bc2bd) /* 0.459902516 */, 18 }, /* 6471 */ { MAD_F(0x075c261f) /* 0.459997295 */, 18 }, /* 6472 */ { MAD_F(0x075c8983) /* 0.460092079 */, 18 }, /* 6473 */ { MAD_F(0x075cece7) /* 0.460186867 */, 18 }, /* 6474 */ { MAD_F(0x075d504d) /* 0.460281661 */, 18 }, /* 6475 */ { MAD_F(0x075db3b5) /* 0.460376459 */, 18 }, /* 6476 */ { MAD_F(0x075e171d) /* 0.460471262 */, 18 }, /* 6477 */ { MAD_F(0x075e7a87) /* 0.460566071 */, 18 }, /* 6478 */ { MAD_F(0x075eddf2) /* 0.460660884 */, 18 }, /* 6479 */ { MAD_F(0x075f415f) /* 0.460755701 */, 18 }, /* 6480 */ { MAD_F(0x075fa4cc) /* 0.460850524 */, 18 }, /* 6481 */ { MAD_F(0x0760083b) /* 0.460945352 */, 18 }, /* 6482 */ { MAD_F(0x07606bac) /* 0.461040184 */, 18 }, /* 6483 */ { MAD_F(0x0760cf1e) /* 0.461135022 */, 18 }, /* 6484 */ { MAD_F(0x07613291) /* 0.461229864 */, 18 }, /* 6485 */ { MAD_F(0x07619605) /* 0.461324711 */, 18 }, /* 6486 */ { MAD_F(0x0761f97b) /* 0.461419563 */, 18 }, /* 6487 */ { MAD_F(0x07625cf2) /* 0.461514420 */, 18 }, /* 6488 */ { MAD_F(0x0762c06a) /* 0.461609282 */, 18 }, /* 6489 */ { MAD_F(0x076323e3) /* 0.461704149 */, 18 }, /* 6490 */ { MAD_F(0x0763875e) /* 0.461799020 */, 18 }, /* 6491 */ { MAD_F(0x0763eadb) /* 0.461893897 */, 18 }, /* 6492 */ { MAD_F(0x07644e58) /* 0.461988778 */, 18 }, /* 6493 */ { MAD_F(0x0764b1d7) /* 0.462083664 */, 18 }, /* 6494 */ { MAD_F(0x07651557) /* 0.462178555 */, 18 }, /* 6495 */ { MAD_F(0x076578d8) /* 0.462273451 */, 18 }, /* 6496 */ { MAD_F(0x0765dc5b) /* 0.462368352 */, 18 }, /* 6497 */ { MAD_F(0x07663fdf) /* 0.462463257 */, 18 }, /* 6498 */ { MAD_F(0x0766a364) /* 0.462558168 */, 18 }, /* 6499 */ { MAD_F(0x076706eb) /* 0.462653083 */, 18 }, /* 6500 */ { MAD_F(0x07676a73) /* 0.462748003 */, 18 }, /* 6501 */ { MAD_F(0x0767cdfc) /* 0.462842928 */, 18 }, /* 6502 */ { MAD_F(0x07683187) /* 0.462937858 */, 18 }, /* 6503 */ { MAD_F(0x07689513) /* 0.463032793 */, 18 }, /* 6504 */ { MAD_F(0x0768f8a0) /* 0.463127733 */, 18 }, /* 6505 */ { MAD_F(0x07695c2e) /* 0.463222678 */, 18 }, /* 6506 */ { MAD_F(0x0769bfbe) /* 0.463317627 */, 18 }, /* 6507 */ { MAD_F(0x076a234f) /* 0.463412581 */, 18 }, /* 6508 */ { MAD_F(0x076a86e2) /* 0.463507540 */, 18 }, /* 6509 */ { MAD_F(0x076aea75) /* 0.463602504 */, 18 }, /* 6510 */ { MAD_F(0x076b4e0a) /* 0.463697473 */, 18 }, /* 6511 */ { MAD_F(0x076bb1a1) /* 0.463792447 */, 18 }, /* 6512 */ { MAD_F(0x076c1538) /* 0.463887426 */, 18 }, /* 6513 */ { MAD_F(0x076c78d1) /* 0.463982409 */, 18 }, /* 6514 */ { MAD_F(0x076cdc6c) /* 0.464077398 */, 18 }, /* 6515 */ { MAD_F(0x076d4007) /* 0.464172391 */, 18 }, /* 6516 */ { MAD_F(0x076da3a4) /* 0.464267389 */, 18 }, /* 6517 */ { MAD_F(0x076e0742) /* 0.464362392 */, 18 }, /* 6518 */ { MAD_F(0x076e6ae2) /* 0.464457399 */, 18 }, /* 6519 */ { MAD_F(0x076ece82) /* 0.464552412 */, 18 }, /* 6520 */ { MAD_F(0x076f3224) /* 0.464647430 */, 18 }, /* 6521 */ { MAD_F(0x076f95c8) /* 0.464742452 */, 18 }, /* 6522 */ { MAD_F(0x076ff96c) /* 0.464837479 */, 18 }, /* 6523 */ { MAD_F(0x07705d12) /* 0.464932511 */, 18 }, /* 6524 */ { MAD_F(0x0770c0ba) /* 0.465027548 */, 18 }, /* 6525 */ { MAD_F(0x07712462) /* 0.465122590 */, 18 }, /* 6526 */ { MAD_F(0x0771880c) /* 0.465217637 */, 18 }, /* 6527 */ { MAD_F(0x0771ebb7) /* 0.465312688 */, 18 }, /* 6528 */ { MAD_F(0x07724f64) /* 0.465407744 */, 18 }, /* 6529 */ { MAD_F(0x0772b312) /* 0.465502806 */, 18 }, /* 6530 */ { MAD_F(0x077316c1) /* 0.465597872 */, 18 }, /* 6531 */ { MAD_F(0x07737a71) /* 0.465692943 */, 18 }, /* 6532 */ { MAD_F(0x0773de23) /* 0.465788018 */, 18 }, /* 6533 */ { MAD_F(0x077441d6) /* 0.465883099 */, 18 }, /* 6534 */ { MAD_F(0x0774a58a) /* 0.465978184 */, 18 }, /* 6535 */ { MAD_F(0x07750940) /* 0.466073275 */, 18 }, /* 6536 */ { MAD_F(0x07756cf7) /* 0.466168370 */, 18 }, /* 6537 */ { MAD_F(0x0775d0af) /* 0.466263470 */, 18 }, /* 6538 */ { MAD_F(0x07763468) /* 0.466358575 */, 18 }, /* 6539 */ { MAD_F(0x07769823) /* 0.466453684 */, 18 }, /* 6540 */ { MAD_F(0x0776fbdf) /* 0.466548799 */, 18 }, /* 6541 */ { MAD_F(0x07775f9d) /* 0.466643918 */, 18 }, /* 6542 */ { MAD_F(0x0777c35c) /* 0.466739043 */, 18 }, /* 6543 */ { MAD_F(0x0778271c) /* 0.466834172 */, 18 }, /* 6544 */ { MAD_F(0x07788add) /* 0.466929306 */, 18 }, /* 6545 */ { MAD_F(0x0778ee9f) /* 0.467024445 */, 18 }, /* 6546 */ { MAD_F(0x07795263) /* 0.467119588 */, 18 }, /* 6547 */ { MAD_F(0x0779b629) /* 0.467214737 */, 18 }, /* 6548 */ { MAD_F(0x077a19ef) /* 0.467309890 */, 18 }, /* 6549 */ { MAD_F(0x077a7db7) /* 0.467405048 */, 18 }, /* 6550 */ { MAD_F(0x077ae180) /* 0.467500211 */, 18 }, /* 6551 */ { MAD_F(0x077b454b) /* 0.467595379 */, 18 }, /* 6552 */ { MAD_F(0x077ba916) /* 0.467690552 */, 18 }, /* 6553 */ { MAD_F(0x077c0ce3) /* 0.467785729 */, 18 }, /* 6554 */ { MAD_F(0x077c70b2) /* 0.467880912 */, 18 }, /* 6555 */ { MAD_F(0x077cd481) /* 0.467976099 */, 18 }, /* 6556 */ { MAD_F(0x077d3852) /* 0.468071291 */, 18 }, /* 6557 */ { MAD_F(0x077d9c24) /* 0.468166488 */, 18 }, /* 6558 */ { MAD_F(0x077dfff8) /* 0.468261690 */, 18 }, /* 6559 */ { MAD_F(0x077e63cd) /* 0.468356896 */, 18 }, /* 6560 */ { MAD_F(0x077ec7a3) /* 0.468452108 */, 18 }, /* 6561 */ { MAD_F(0x077f2b7a) /* 0.468547324 */, 18 }, /* 6562 */ { MAD_F(0x077f8f53) /* 0.468642545 */, 18 }, /* 6563 */ { MAD_F(0x077ff32d) /* 0.468737771 */, 18 }, /* 6564 */ { MAD_F(0x07805708) /* 0.468833002 */, 18 }, /* 6565 */ { MAD_F(0x0780bae5) /* 0.468928237 */, 18 }, /* 6566 */ { MAD_F(0x07811ec3) /* 0.469023478 */, 18 }, /* 6567 */ { MAD_F(0x078182a2) /* 0.469118723 */, 18 }, /* 6568 */ { MAD_F(0x0781e683) /* 0.469213973 */, 18 }, /* 6569 */ { MAD_F(0x07824a64) /* 0.469309228 */, 18 }, /* 6570 */ { MAD_F(0x0782ae47) /* 0.469404488 */, 18 }, /* 6571 */ { MAD_F(0x0783122c) /* 0.469499752 */, 18 }, /* 6572 */ { MAD_F(0x07837612) /* 0.469595022 */, 18 }, /* 6573 */ { MAD_F(0x0783d9f9) /* 0.469690296 */, 18 }, /* 6574 */ { MAD_F(0x07843de1) /* 0.469785575 */, 18 }, /* 6575 */ { MAD_F(0x0784a1ca) /* 0.469880859 */, 18 }, /* 6576 */ { MAD_F(0x078505b5) /* 0.469976148 */, 18 }, /* 6577 */ { MAD_F(0x078569a2) /* 0.470071442 */, 18 }, /* 6578 */ { MAD_F(0x0785cd8f) /* 0.470166740 */, 18 }, /* 6579 */ { MAD_F(0x0786317e) /* 0.470262043 */, 18 }, /* 6580 */ { MAD_F(0x0786956e) /* 0.470357351 */, 18 }, /* 6581 */ { MAD_F(0x0786f95f) /* 0.470452664 */, 18 }, /* 6582 */ { MAD_F(0x07875d52) /* 0.470547982 */, 18 }, /* 6583 */ { MAD_F(0x0787c146) /* 0.470643305 */, 18 }, /* 6584 */ { MAD_F(0x0788253b) /* 0.470738632 */, 18 }, /* 6585 */ { MAD_F(0x07888932) /* 0.470833964 */, 18 }, /* 6586 */ { MAD_F(0x0788ed2a) /* 0.470929301 */, 18 }, /* 6587 */ { MAD_F(0x07895123) /* 0.471024643 */, 18 }, /* 6588 */ { MAD_F(0x0789b51d) /* 0.471119990 */, 18 }, /* 6589 */ { MAD_F(0x078a1919) /* 0.471215341 */, 18 }, /* 6590 */ { MAD_F(0x078a7d16) /* 0.471310698 */, 18 }, /* 6591 */ { MAD_F(0x078ae114) /* 0.471406059 */, 18 }, /* 6592 */ { MAD_F(0x078b4514) /* 0.471501425 */, 18 }, /* 6593 */ { MAD_F(0x078ba915) /* 0.471596796 */, 18 }, /* 6594 */ { MAD_F(0x078c0d17) /* 0.471692171 */, 18 }, /* 6595 */ { MAD_F(0x078c711a) /* 0.471787552 */, 18 }, /* 6596 */ { MAD_F(0x078cd51f) /* 0.471882937 */, 18 }, /* 6597 */ { MAD_F(0x078d3925) /* 0.471978327 */, 18 }, /* 6598 */ { MAD_F(0x078d9d2d) /* 0.472073722 */, 18 }, /* 6599 */ { MAD_F(0x078e0135) /* 0.472169122 */, 18 }, /* 6600 */ { MAD_F(0x078e653f) /* 0.472264527 */, 18 }, /* 6601 */ { MAD_F(0x078ec94b) /* 0.472359936 */, 18 }, /* 6602 */ { MAD_F(0x078f2d57) /* 0.472455350 */, 18 }, /* 6603 */ { MAD_F(0x078f9165) /* 0.472550769 */, 18 }, /* 6604 */ { MAD_F(0x078ff574) /* 0.472646193 */, 18 }, /* 6605 */ { MAD_F(0x07905985) /* 0.472741622 */, 18 }, /* 6606 */ { MAD_F(0x0790bd96) /* 0.472837055 */, 18 }, /* 6607 */ { MAD_F(0x079121a9) /* 0.472932493 */, 18 }, /* 6608 */ { MAD_F(0x079185be) /* 0.473027937 */, 18 }, /* 6609 */ { MAD_F(0x0791e9d3) /* 0.473123384 */, 18 }, /* 6610 */ { MAD_F(0x07924dea) /* 0.473218837 */, 18 }, /* 6611 */ { MAD_F(0x0792b202) /* 0.473314295 */, 18 }, /* 6612 */ { MAD_F(0x0793161c) /* 0.473409757 */, 18 }, /* 6613 */ { MAD_F(0x07937a37) /* 0.473505224 */, 18 }, /* 6614 */ { MAD_F(0x0793de53) /* 0.473600696 */, 18 }, /* 6615 */ { MAD_F(0x07944270) /* 0.473696173 */, 18 }, /* 6616 */ { MAD_F(0x0794a68f) /* 0.473791655 */, 18 }, /* 6617 */ { MAD_F(0x07950aaf) /* 0.473887141 */, 18 }, /* 6618 */ { MAD_F(0x07956ed0) /* 0.473982632 */, 18 }, /* 6619 */ { MAD_F(0x0795d2f2) /* 0.474078128 */, 18 }, /* 6620 */ { MAD_F(0x07963716) /* 0.474173629 */, 18 }, /* 6621 */ { MAD_F(0x07969b3b) /* 0.474269135 */, 18 }, /* 6622 */ { MAD_F(0x0796ff62) /* 0.474364645 */, 18 }, /* 6623 */ { MAD_F(0x07976389) /* 0.474460161 */, 18 }, /* 6624 */ { MAD_F(0x0797c7b2) /* 0.474555681 */, 18 }, /* 6625 */ { MAD_F(0x07982bdd) /* 0.474651205 */, 18 }, /* 6626 */ { MAD_F(0x07989008) /* 0.474746735 */, 18 }, /* 6627 */ { MAD_F(0x0798f435) /* 0.474842270 */, 18 }, /* 6628 */ { MAD_F(0x07995863) /* 0.474937809 */, 18 }, /* 6629 */ { MAD_F(0x0799bc92) /* 0.475033353 */, 18 }, /* 6630 */ { MAD_F(0x079a20c3) /* 0.475128902 */, 18 }, /* 6631 */ { MAD_F(0x079a84f5) /* 0.475224456 */, 18 }, /* 6632 */ { MAD_F(0x079ae929) /* 0.475320014 */, 18 }, /* 6633 */ { MAD_F(0x079b4d5d) /* 0.475415578 */, 18 }, /* 6634 */ { MAD_F(0x079bb193) /* 0.475511146 */, 18 }, /* 6635 */ { MAD_F(0x079c15ca) /* 0.475606719 */, 18 }, /* 6636 */ { MAD_F(0x079c7a03) /* 0.475702296 */, 18 }, /* 6637 */ { MAD_F(0x079cde3c) /* 0.475797879 */, 18 }, /* 6638 */ { MAD_F(0x079d4277) /* 0.475893466 */, 18 }, /* 6639 */ { MAD_F(0x079da6b4) /* 0.475989058 */, 18 }, /* 6640 */ { MAD_F(0x079e0af1) /* 0.476084655 */, 18 }, /* 6641 */ { MAD_F(0x079e6f30) /* 0.476180257 */, 18 }, /* 6642 */ { MAD_F(0x079ed370) /* 0.476275863 */, 18 }, /* 6643 */ { MAD_F(0x079f37b2) /* 0.476371475 */, 18 }, /* 6644 */ { MAD_F(0x079f9bf5) /* 0.476467091 */, 18 }, /* 6645 */ { MAD_F(0x07a00039) /* 0.476562712 */, 18 }, /* 6646 */ { MAD_F(0x07a0647e) /* 0.476658338 */, 18 }, /* 6647 */ { MAD_F(0x07a0c8c5) /* 0.476753968 */, 18 }, /* 6648 */ { MAD_F(0x07a12d0c) /* 0.476849603 */, 18 }, /* 6649 */ { MAD_F(0x07a19156) /* 0.476945243 */, 18 }, /* 6650 */ { MAD_F(0x07a1f5a0) /* 0.477040888 */, 18 }, /* 6651 */ { MAD_F(0x07a259ec) /* 0.477136538 */, 18 }, /* 6652 */ { MAD_F(0x07a2be39) /* 0.477232193 */, 18 }, /* 6653 */ { MAD_F(0x07a32287) /* 0.477327852 */, 18 }, /* 6654 */ { MAD_F(0x07a386d7) /* 0.477423516 */, 18 }, /* 6655 */ { MAD_F(0x07a3eb28) /* 0.477519185 */, 18 }, /* 6656 */ { MAD_F(0x07a44f7a) /* 0.477614858 */, 18 }, /* 6657 */ { MAD_F(0x07a4b3ce) /* 0.477710537 */, 18 }, /* 6658 */ { MAD_F(0x07a51822) /* 0.477806220 */, 18 }, /* 6659 */ { MAD_F(0x07a57c78) /* 0.477901908 */, 18 }, /* 6660 */ { MAD_F(0x07a5e0d0) /* 0.477997601 */, 18 }, /* 6661 */ { MAD_F(0x07a64528) /* 0.478093299 */, 18 }, /* 6662 */ { MAD_F(0x07a6a982) /* 0.478189001 */, 18 }, /* 6663 */ { MAD_F(0x07a70ddd) /* 0.478284708 */, 18 }, /* 6664 */ { MAD_F(0x07a7723a) /* 0.478380420 */, 18 }, /* 6665 */ { MAD_F(0x07a7d698) /* 0.478476137 */, 18 }, /* 6666 */ { MAD_F(0x07a83af7) /* 0.478571858 */, 18 }, /* 6667 */ { MAD_F(0x07a89f57) /* 0.478667585 */, 18 }, /* 6668 */ { MAD_F(0x07a903b9) /* 0.478763316 */, 18 }, /* 6669 */ { MAD_F(0x07a9681c) /* 0.478859052 */, 18 }, /* 6670 */ { MAD_F(0x07a9cc80) /* 0.478954793 */, 18 }, /* 6671 */ { MAD_F(0x07aa30e5) /* 0.479050538 */, 18 }, /* 6672 */ { MAD_F(0x07aa954c) /* 0.479146288 */, 18 }, /* 6673 */ { MAD_F(0x07aaf9b4) /* 0.479242043 */, 18 }, /* 6674 */ { MAD_F(0x07ab5e1e) /* 0.479337803 */, 18 }, /* 6675 */ { MAD_F(0x07abc288) /* 0.479433568 */, 18 }, /* 6676 */ { MAD_F(0x07ac26f4) /* 0.479529337 */, 18 }, /* 6677 */ { MAD_F(0x07ac8b61) /* 0.479625111 */, 18 }, /* 6678 */ { MAD_F(0x07acefd0) /* 0.479720890 */, 18 }, /* 6679 */ { MAD_F(0x07ad543f) /* 0.479816674 */, 18 }, /* 6680 */ { MAD_F(0x07adb8b0) /* 0.479912463 */, 18 }, /* 6681 */ { MAD_F(0x07ae1d23) /* 0.480008256 */, 18 }, /* 6682 */ { MAD_F(0x07ae8196) /* 0.480104054 */, 18 }, /* 6683 */ { MAD_F(0x07aee60b) /* 0.480199857 */, 18 }, /* 6684 */ { MAD_F(0x07af4a81) /* 0.480295664 */, 18 }, /* 6685 */ { MAD_F(0x07afaef9) /* 0.480391477 */, 18 }, /* 6686 */ { MAD_F(0x07b01372) /* 0.480487294 */, 18 }, /* 6687 */ { MAD_F(0x07b077ec) /* 0.480583116 */, 18 }, /* 6688 */ { MAD_F(0x07b0dc67) /* 0.480678943 */, 18 }, /* 6689 */ { MAD_F(0x07b140e4) /* 0.480774774 */, 18 }, /* 6690 */ { MAD_F(0x07b1a561) /* 0.480870611 */, 18 }, /* 6691 */ { MAD_F(0x07b209e1) /* 0.480966452 */, 18 }, /* 6692 */ { MAD_F(0x07b26e61) /* 0.481062298 */, 18 }, /* 6693 */ { MAD_F(0x07b2d2e3) /* 0.481158148 */, 18 }, /* 6694 */ { MAD_F(0x07b33766) /* 0.481254004 */, 18 }, /* 6695 */ { MAD_F(0x07b39bea) /* 0.481349864 */, 18 }, /* 6696 */ { MAD_F(0x07b4006f) /* 0.481445729 */, 18 }, /* 6697 */ { MAD_F(0x07b464f6) /* 0.481541598 */, 18 }, /* 6698 */ { MAD_F(0x07b4c97e) /* 0.481637473 */, 18 }, /* 6699 */ { MAD_F(0x07b52e08) /* 0.481733352 */, 18 }, /* 6700 */ { MAD_F(0x07b59292) /* 0.481829236 */, 18 }, /* 6701 */ { MAD_F(0x07b5f71e) /* 0.481925125 */, 18 }, /* 6702 */ { MAD_F(0x07b65bac) /* 0.482021019 */, 18 }, /* 6703 */ { MAD_F(0x07b6c03a) /* 0.482116917 */, 18 }, /* 6704 */ { MAD_F(0x07b724ca) /* 0.482212820 */, 18 }, /* 6705 */ { MAD_F(0x07b7895b) /* 0.482308728 */, 18 }, /* 6706 */ { MAD_F(0x07b7eded) /* 0.482404640 */, 18 }, /* 6707 */ { MAD_F(0x07b85281) /* 0.482500558 */, 18 }, /* 6708 */ { MAD_F(0x07b8b716) /* 0.482596480 */, 18 }, /* 6709 */ { MAD_F(0x07b91bac) /* 0.482692407 */, 18 }, /* 6710 */ { MAD_F(0x07b98044) /* 0.482788339 */, 18 }, /* 6711 */ { MAD_F(0x07b9e4dc) /* 0.482884275 */, 18 }, /* 6712 */ { MAD_F(0x07ba4976) /* 0.482980216 */, 18 }, /* 6713 */ { MAD_F(0x07baae12) /* 0.483076162 */, 18 }, /* 6714 */ { MAD_F(0x07bb12ae) /* 0.483172113 */, 18 }, /* 6715 */ { MAD_F(0x07bb774c) /* 0.483268069 */, 18 }, /* 6716 */ { MAD_F(0x07bbdbeb) /* 0.483364029 */, 18 }, /* 6717 */ { MAD_F(0x07bc408c) /* 0.483459994 */, 18 }, /* 6718 */ { MAD_F(0x07bca52d) /* 0.483555964 */, 18 }, /* 6719 */ { MAD_F(0x07bd09d0) /* 0.483651939 */, 18 }, /* 6720 */ { MAD_F(0x07bd6e75) /* 0.483747918 */, 18 }, /* 6721 */ { MAD_F(0x07bdd31a) /* 0.483843902 */, 18 }, /* 6722 */ { MAD_F(0x07be37c1) /* 0.483939891 */, 18 }, /* 6723 */ { MAD_F(0x07be9c69) /* 0.484035885 */, 18 }, /* 6724 */ { MAD_F(0x07bf0113) /* 0.484131883 */, 18 }, /* 6725 */ { MAD_F(0x07bf65bd) /* 0.484227886 */, 18 }, /* 6726 */ { MAD_F(0x07bfca69) /* 0.484323894 */, 18 }, /* 6727 */ { MAD_F(0x07c02f16) /* 0.484419907 */, 18 }, /* 6728 */ { MAD_F(0x07c093c5) /* 0.484515924 */, 18 }, /* 6729 */ { MAD_F(0x07c0f875) /* 0.484611946 */, 18 }, /* 6730 */ { MAD_F(0x07c15d26) /* 0.484707973 */, 18 }, /* 6731 */ { MAD_F(0x07c1c1d8) /* 0.484804005 */, 18 }, /* 6732 */ { MAD_F(0x07c2268b) /* 0.484900041 */, 18 }, /* 6733 */ { MAD_F(0x07c28b40) /* 0.484996083 */, 18 }, /* 6734 */ { MAD_F(0x07c2eff6) /* 0.485092128 */, 18 }, /* 6735 */ { MAD_F(0x07c354ae) /* 0.485188179 */, 18 }, /* 6736 */ { MAD_F(0x07c3b967) /* 0.485284235 */, 18 }, /* 6737 */ { MAD_F(0x07c41e21) /* 0.485380295 */, 18 }, /* 6738 */ { MAD_F(0x07c482dc) /* 0.485476360 */, 18 }, /* 6739 */ { MAD_F(0x07c4e798) /* 0.485572430 */, 18 }, /* 6740 */ { MAD_F(0x07c54c56) /* 0.485668504 */, 18 }, /* 6741 */ { MAD_F(0x07c5b115) /* 0.485764583 */, 18 }, /* 6742 */ { MAD_F(0x07c615d6) /* 0.485860667 */, 18 }, /* 6743 */ { MAD_F(0x07c67a97) /* 0.485956756 */, 18 }, /* 6744 */ { MAD_F(0x07c6df5a) /* 0.486052849 */, 18 }, /* 6745 */ { MAD_F(0x07c7441e) /* 0.486148948 */, 18 }, /* 6746 */ { MAD_F(0x07c7a8e4) /* 0.486245051 */, 18 }, /* 6747 */ { MAD_F(0x07c80daa) /* 0.486341158 */, 18 }, /* 6748 */ { MAD_F(0x07c87272) /* 0.486437271 */, 18 }, /* 6749 */ { MAD_F(0x07c8d73c) /* 0.486533388 */, 18 }, /* 6750 */ { MAD_F(0x07c93c06) /* 0.486629510 */, 18 }, /* 6751 */ { MAD_F(0x07c9a0d2) /* 0.486725637 */, 18 }, /* 6752 */ { MAD_F(0x07ca059f) /* 0.486821768 */, 18 }, /* 6753 */ { MAD_F(0x07ca6a6d) /* 0.486917905 */, 18 }, /* 6754 */ { MAD_F(0x07cacf3d) /* 0.487014045 */, 18 }, /* 6755 */ { MAD_F(0x07cb340e) /* 0.487110191 */, 18 }, /* 6756 */ { MAD_F(0x07cb98e0) /* 0.487206342 */, 18 }, /* 6757 */ { MAD_F(0x07cbfdb4) /* 0.487302497 */, 18 }, /* 6758 */ { MAD_F(0x07cc6288) /* 0.487398657 */, 18 }, /* 6759 */ { MAD_F(0x07ccc75e) /* 0.487494821 */, 18 }, /* 6760 */ { MAD_F(0x07cd2c36) /* 0.487590991 */, 18 }, /* 6761 */ { MAD_F(0x07cd910e) /* 0.487687165 */, 18 }, /* 6762 */ { MAD_F(0x07cdf5e8) /* 0.487783344 */, 18 }, /* 6763 */ { MAD_F(0x07ce5ac3) /* 0.487879528 */, 18 }, /* 6764 */ { MAD_F(0x07cebfa0) /* 0.487975716 */, 18 }, /* 6765 */ { MAD_F(0x07cf247d) /* 0.488071909 */, 18 }, /* 6766 */ { MAD_F(0x07cf895c) /* 0.488168107 */, 18 }, /* 6767 */ { MAD_F(0x07cfee3c) /* 0.488264310 */, 18 }, /* 6768 */ { MAD_F(0x07d0531e) /* 0.488360517 */, 18 }, /* 6769 */ { MAD_F(0x07d0b801) /* 0.488456729 */, 18 }, /* 6770 */ { MAD_F(0x07d11ce5) /* 0.488552946 */, 18 }, /* 6771 */ { MAD_F(0x07d181ca) /* 0.488649167 */, 18 }, /* 6772 */ { MAD_F(0x07d1e6b0) /* 0.488745394 */, 18 }, /* 6773 */ { MAD_F(0x07d24b98) /* 0.488841625 */, 18 }, /* 6774 */ { MAD_F(0x07d2b081) /* 0.488937860 */, 18 }, /* 6775 */ { MAD_F(0x07d3156c) /* 0.489034101 */, 18 }, /* 6776 */ { MAD_F(0x07d37a57) /* 0.489130346 */, 18 }, /* 6777 */ { MAD_F(0x07d3df44) /* 0.489226596 */, 18 }, /* 6778 */ { MAD_F(0x07d44432) /* 0.489322851 */, 18 }, /* 6779 */ { MAD_F(0x07d4a922) /* 0.489419110 */, 18 }, /* 6780 */ { MAD_F(0x07d50e13) /* 0.489515375 */, 18 }, /* 6781 */ { MAD_F(0x07d57305) /* 0.489611643 */, 18 }, /* 6782 */ { MAD_F(0x07d5d7f8) /* 0.489707917 */, 18 }, /* 6783 */ { MAD_F(0x07d63cec) /* 0.489804195 */, 18 }, /* 6784 */ { MAD_F(0x07d6a1e2) /* 0.489900479 */, 18 }, /* 6785 */ { MAD_F(0x07d706d9) /* 0.489996766 */, 18 }, /* 6786 */ { MAD_F(0x07d76bd2) /* 0.490093059 */, 18 }, /* 6787 */ { MAD_F(0x07d7d0cb) /* 0.490189356 */, 18 }, /* 6788 */ { MAD_F(0x07d835c6) /* 0.490285658 */, 18 }, /* 6789 */ { MAD_F(0x07d89ac2) /* 0.490381965 */, 18 }, /* 6790 */ { MAD_F(0x07d8ffc0) /* 0.490478277 */, 18 }, /* 6791 */ { MAD_F(0x07d964be) /* 0.490574593 */, 18 }, /* 6792 */ { MAD_F(0x07d9c9be) /* 0.490670914 */, 18 }, /* 6793 */ { MAD_F(0x07da2ebf) /* 0.490767239 */, 18 }, /* 6794 */ { MAD_F(0x07da93c2) /* 0.490863570 */, 18 }, /* 6795 */ { MAD_F(0x07daf8c6) /* 0.490959905 */, 18 }, /* 6796 */ { MAD_F(0x07db5dcb) /* 0.491056245 */, 18 }, /* 6797 */ { MAD_F(0x07dbc2d1) /* 0.491152589 */, 18 }, /* 6798 */ { MAD_F(0x07dc27d9) /* 0.491248939 */, 18 }, /* 6799 */ { MAD_F(0x07dc8ce1) /* 0.491345293 */, 18 }, /* 6800 */ { MAD_F(0x07dcf1ec) /* 0.491441651 */, 18 }, /* 6801 */ { MAD_F(0x07dd56f7) /* 0.491538015 */, 18 }, /* 6802 */ { MAD_F(0x07ddbc04) /* 0.491634383 */, 18 }, /* 6803 */ { MAD_F(0x07de2111) /* 0.491730756 */, 18 }, /* 6804 */ { MAD_F(0x07de8621) /* 0.491827134 */, 18 }, /* 6805 */ { MAD_F(0x07deeb31) /* 0.491923516 */, 18 }, /* 6806 */ { MAD_F(0x07df5043) /* 0.492019903 */, 18 }, /* 6807 */ { MAD_F(0x07dfb556) /* 0.492116295 */, 18 }, /* 6808 */ { MAD_F(0x07e01a6a) /* 0.492212691 */, 18 }, /* 6809 */ { MAD_F(0x07e07f80) /* 0.492309093 */, 18 }, /* 6810 */ { MAD_F(0x07e0e496) /* 0.492405499 */, 18 }, /* 6811 */ { MAD_F(0x07e149ae) /* 0.492501909 */, 18 }, /* 6812 */ { MAD_F(0x07e1aec8) /* 0.492598325 */, 18 }, /* 6813 */ { MAD_F(0x07e213e2) /* 0.492694745 */, 18 }, /* 6814 */ { MAD_F(0x07e278fe) /* 0.492791170 */, 18 }, /* 6815 */ { MAD_F(0x07e2de1b) /* 0.492887599 */, 18 }, /* 6816 */ { MAD_F(0x07e3433a) /* 0.492984033 */, 18 }, /* 6817 */ { MAD_F(0x07e3a859) /* 0.493080472 */, 18 }, /* 6818 */ { MAD_F(0x07e40d7a) /* 0.493176916 */, 18 }, /* 6819 */ { MAD_F(0x07e4729c) /* 0.493273365 */, 18 }, /* 6820 */ { MAD_F(0x07e4d7c0) /* 0.493369818 */, 18 }, /* 6821 */ { MAD_F(0x07e53ce4) /* 0.493466275 */, 18 }, /* 6822 */ { MAD_F(0x07e5a20a) /* 0.493562738 */, 18 }, /* 6823 */ { MAD_F(0x07e60732) /* 0.493659205 */, 18 }, /* 6824 */ { MAD_F(0x07e66c5a) /* 0.493755677 */, 18 }, /* 6825 */ { MAD_F(0x07e6d184) /* 0.493852154 */, 18 }, /* 6826 */ { MAD_F(0x07e736af) /* 0.493948635 */, 18 }, /* 6827 */ { MAD_F(0x07e79bdb) /* 0.494045122 */, 18 }, /* 6828 */ { MAD_F(0x07e80109) /* 0.494141612 */, 18 }, /* 6829 */ { MAD_F(0x07e86638) /* 0.494238108 */, 18 }, /* 6830 */ { MAD_F(0x07e8cb68) /* 0.494334608 */, 18 }, /* 6831 */ { MAD_F(0x07e93099) /* 0.494431113 */, 18 }, /* 6832 */ { MAD_F(0x07e995cc) /* 0.494527623 */, 18 }, /* 6833 */ { MAD_F(0x07e9fb00) /* 0.494624137 */, 18 }, /* 6834 */ { MAD_F(0x07ea6035) /* 0.494720656 */, 18 }, /* 6835 */ { MAD_F(0x07eac56b) /* 0.494817180 */, 18 }, /* 6836 */ { MAD_F(0x07eb2aa3) /* 0.494913709 */, 18 }, /* 6837 */ { MAD_F(0x07eb8fdc) /* 0.495010242 */, 18 }, /* 6838 */ { MAD_F(0x07ebf516) /* 0.495106780 */, 18 }, /* 6839 */ { MAD_F(0x07ec5a51) /* 0.495203322 */, 18 }, /* 6840 */ { MAD_F(0x07ecbf8e) /* 0.495299870 */, 18 }, /* 6841 */ { MAD_F(0x07ed24cc) /* 0.495396422 */, 18 }, /* 6842 */ { MAD_F(0x07ed8a0b) /* 0.495492978 */, 18 }, /* 6843 */ { MAD_F(0x07edef4c) /* 0.495589540 */, 18 }, /* 6844 */ { MAD_F(0x07ee548e) /* 0.495686106 */, 18 }, /* 6845 */ { MAD_F(0x07eeb9d1) /* 0.495782677 */, 18 }, /* 6846 */ { MAD_F(0x07ef1f15) /* 0.495879252 */, 18 }, /* 6847 */ { MAD_F(0x07ef845b) /* 0.495975833 */, 18 }, /* 6848 */ { MAD_F(0x07efe9a1) /* 0.496072418 */, 18 }, /* 6849 */ { MAD_F(0x07f04ee9) /* 0.496169007 */, 18 }, /* 6850 */ { MAD_F(0x07f0b433) /* 0.496265602 */, 18 }, /* 6851 */ { MAD_F(0x07f1197d) /* 0.496362201 */, 18 }, /* 6852 */ { MAD_F(0x07f17ec9) /* 0.496458804 */, 18 }, /* 6853 */ { MAD_F(0x07f1e416) /* 0.496555413 */, 18 }, /* 6854 */ { MAD_F(0x07f24965) /* 0.496652026 */, 18 }, /* 6855 */ { MAD_F(0x07f2aeb5) /* 0.496748644 */, 18 }, /* 6856 */ { MAD_F(0x07f31405) /* 0.496845266 */, 18 }, /* 6857 */ { MAD_F(0x07f37958) /* 0.496941894 */, 18 }, /* 6858 */ { MAD_F(0x07f3deab) /* 0.497038526 */, 18 }, /* 6859 */ { MAD_F(0x07f44400) /* 0.497135162 */, 18 }, /* 6860 */ { MAD_F(0x07f4a956) /* 0.497231804 */, 18 }, /* 6861 */ { MAD_F(0x07f50ead) /* 0.497328450 */, 18 }, /* 6862 */ { MAD_F(0x07f57405) /* 0.497425100 */, 18 }, /* 6863 */ { MAD_F(0x07f5d95f) /* 0.497521756 */, 18 }, /* 6864 */ { MAD_F(0x07f63eba) /* 0.497618416 */, 18 }, /* 6865 */ { MAD_F(0x07f6a416) /* 0.497715081 */, 18 }, /* 6866 */ { MAD_F(0x07f70974) /* 0.497811750 */, 18 }, /* 6867 */ { MAD_F(0x07f76ed3) /* 0.497908425 */, 18 }, /* 6868 */ { MAD_F(0x07f7d433) /* 0.498005103 */, 18 }, /* 6869 */ { MAD_F(0x07f83994) /* 0.498101787 */, 18 }, /* 6870 */ { MAD_F(0x07f89ef7) /* 0.498198475 */, 18 }, /* 6871 */ { MAD_F(0x07f9045a) /* 0.498295168 */, 18 }, /* 6872 */ { MAD_F(0x07f969c0) /* 0.498391866 */, 18 }, /* 6873 */ { MAD_F(0x07f9cf26) /* 0.498488568 */, 18 }, /* 6874 */ { MAD_F(0x07fa348e) /* 0.498585275 */, 18 }, /* 6875 */ { MAD_F(0x07fa99f6) /* 0.498681987 */, 18 }, /* 6876 */ { MAD_F(0x07faff60) /* 0.498778704 */, 18 }, /* 6877 */ { MAD_F(0x07fb64cc) /* 0.498875425 */, 18 }, /* 6878 */ { MAD_F(0x07fbca38) /* 0.498972150 */, 18 }, /* 6879 */ { MAD_F(0x07fc2fa6) /* 0.499068881 */, 18 }, /* 6880 */ { MAD_F(0x07fc9516) /* 0.499165616 */, 18 }, /* 6881 */ { MAD_F(0x07fcfa86) /* 0.499262356 */, 18 }, /* 6882 */ { MAD_F(0x07fd5ff8) /* 0.499359101 */, 18 }, /* 6883 */ { MAD_F(0x07fdc56b) /* 0.499455850 */, 18 }, /* 6884 */ { MAD_F(0x07fe2adf) /* 0.499552604 */, 18 }, /* 6885 */ { MAD_F(0x07fe9054) /* 0.499649362 */, 18 }, /* 6886 */ { MAD_F(0x07fef5cb) /* 0.499746126 */, 18 }, /* 6887 */ { MAD_F(0x07ff5b43) /* 0.499842894 */, 18 }, /* 6888 */ { MAD_F(0x07ffc0bc) /* 0.499939666 */, 18 }, /* 6889 */ { MAD_F(0x0400131b) /* 0.250018222 */, 19 }, /* 6890 */ { MAD_F(0x040045d9) /* 0.250066613 */, 19 }, /* 6891 */ { MAD_F(0x04007897) /* 0.250115006 */, 19 }, /* 6892 */ { MAD_F(0x0400ab57) /* 0.250163402 */, 19 }, /* 6893 */ { MAD_F(0x0400de16) /* 0.250211800 */, 19 }, /* 6894 */ { MAD_F(0x040110d7) /* 0.250260200 */, 19 }, /* 6895 */ { MAD_F(0x04014398) /* 0.250308603 */, 19 }, /* 6896 */ { MAD_F(0x04017659) /* 0.250357008 */, 19 }, /* 6897 */ { MAD_F(0x0401a91c) /* 0.250405415 */, 19 }, /* 6898 */ { MAD_F(0x0401dbdf) /* 0.250453825 */, 19 }, /* 6899 */ { MAD_F(0x04020ea2) /* 0.250502237 */, 19 }, /* 6900 */ { MAD_F(0x04024166) /* 0.250550652 */, 19 }, /* 6901 */ { MAD_F(0x0402742b) /* 0.250599068 */, 19 }, /* 6902 */ { MAD_F(0x0402a6f0) /* 0.250647488 */, 19 }, /* 6903 */ { MAD_F(0x0402d9b6) /* 0.250695909 */, 19 }, /* 6904 */ { MAD_F(0x04030c7d) /* 0.250744333 */, 19 }, /* 6905 */ { MAD_F(0x04033f44) /* 0.250792759 */, 19 }, /* 6906 */ { MAD_F(0x0403720c) /* 0.250841187 */, 19 }, /* 6907 */ { MAD_F(0x0403a4d5) /* 0.250889618 */, 19 }, /* 6908 */ { MAD_F(0x0403d79e) /* 0.250938051 */, 19 }, /* 6909 */ { MAD_F(0x04040a68) /* 0.250986487 */, 19 }, /* 6910 */ { MAD_F(0x04043d32) /* 0.251034924 */, 19 }, /* 6911 */ { MAD_F(0x04046ffd) /* 0.251083365 */, 19 }, /* 6912 */ { MAD_F(0x0404a2c9) /* 0.251131807 */, 19 }, /* 6913 */ { MAD_F(0x0404d595) /* 0.251180252 */, 19 }, /* 6914 */ { MAD_F(0x04050862) /* 0.251228699 */, 19 }, /* 6915 */ { MAD_F(0x04053b30) /* 0.251277148 */, 19 }, /* 6916 */ { MAD_F(0x04056dfe) /* 0.251325600 */, 19 }, /* 6917 */ { MAD_F(0x0405a0cd) /* 0.251374054 */, 19 }, /* 6918 */ { MAD_F(0x0405d39c) /* 0.251422511 */, 19 }, /* 6919 */ { MAD_F(0x0406066c) /* 0.251470970 */, 19 }, /* 6920 */ { MAD_F(0x0406393d) /* 0.251519431 */, 19 }, /* 6921 */ { MAD_F(0x04066c0e) /* 0.251567894 */, 19 }, /* 6922 */ { MAD_F(0x04069ee0) /* 0.251616360 */, 19 }, /* 6923 */ { MAD_F(0x0406d1b3) /* 0.251664828 */, 19 }, /* 6924 */ { MAD_F(0x04070486) /* 0.251713299 */, 19 }, /* 6925 */ { MAD_F(0x0407375a) /* 0.251761772 */, 19 }, /* 6926 */ { MAD_F(0x04076a2e) /* 0.251810247 */, 19 }, /* 6927 */ { MAD_F(0x04079d03) /* 0.251858724 */, 19 }, /* 6928 */ { MAD_F(0x0407cfd9) /* 0.251907204 */, 19 }, /* 6929 */ { MAD_F(0x040802af) /* 0.251955686 */, 19 }, /* 6930 */ { MAD_F(0x04083586) /* 0.252004171 */, 19 }, /* 6931 */ { MAD_F(0x0408685e) /* 0.252052658 */, 19 }, /* 6932 */ { MAD_F(0x04089b36) /* 0.252101147 */, 19 }, /* 6933 */ { MAD_F(0x0408ce0f) /* 0.252149638 */, 19 }, /* 6934 */ { MAD_F(0x040900e8) /* 0.252198132 */, 19 }, /* 6935 */ { MAD_F(0x040933c2) /* 0.252246628 */, 19 }, /* 6936 */ { MAD_F(0x0409669d) /* 0.252295127 */, 19 }, /* 6937 */ { MAD_F(0x04099978) /* 0.252343627 */, 19 }, /* 6938 */ { MAD_F(0x0409cc54) /* 0.252392131 */, 19 }, /* 6939 */ { MAD_F(0x0409ff31) /* 0.252440636 */, 19 }, /* 6940 */ { MAD_F(0x040a320e) /* 0.252489144 */, 19 }, /* 6941 */ { MAD_F(0x040a64ec) /* 0.252537654 */, 19 }, /* 6942 */ { MAD_F(0x040a97cb) /* 0.252586166 */, 19 }, /* 6943 */ { MAD_F(0x040acaaa) /* 0.252634681 */, 19 }, /* 6944 */ { MAD_F(0x040afd89) /* 0.252683198 */, 19 }, /* 6945 */ { MAD_F(0x040b306a) /* 0.252731718 */, 19 }, /* 6946 */ { MAD_F(0x040b634b) /* 0.252780240 */, 19 }, /* 6947 */ { MAD_F(0x040b962c) /* 0.252828764 */, 19 }, /* 6948 */ { MAD_F(0x040bc90e) /* 0.252877290 */, 19 }, /* 6949 */ { MAD_F(0x040bfbf1) /* 0.252925819 */, 19 }, /* 6950 */ { MAD_F(0x040c2ed5) /* 0.252974350 */, 19 }, /* 6951 */ { MAD_F(0x040c61b9) /* 0.253022883 */, 19 }, /* 6952 */ { MAD_F(0x040c949e) /* 0.253071419 */, 19 }, /* 6953 */ { MAD_F(0x040cc783) /* 0.253119957 */, 19 }, /* 6954 */ { MAD_F(0x040cfa69) /* 0.253168498 */, 19 }, /* 6955 */ { MAD_F(0x040d2d4f) /* 0.253217040 */, 19 }, /* 6956 */ { MAD_F(0x040d6037) /* 0.253265585 */, 19 }, /* 6957 */ { MAD_F(0x040d931e) /* 0.253314133 */, 19 }, /* 6958 */ { MAD_F(0x040dc607) /* 0.253362682 */, 19 }, /* 6959 */ { MAD_F(0x040df8f0) /* 0.253411234 */, 19 }, /* 6960 */ { MAD_F(0x040e2bda) /* 0.253459789 */, 19 }, /* 6961 */ { MAD_F(0x040e5ec4) /* 0.253508345 */, 19 }, /* 6962 */ { MAD_F(0x040e91af) /* 0.253556904 */, 19 }, /* 6963 */ { MAD_F(0x040ec49b) /* 0.253605466 */, 19 }, /* 6964 */ { MAD_F(0x040ef787) /* 0.253654029 */, 19 }, /* 6965 */ { MAD_F(0x040f2a74) /* 0.253702595 */, 19 }, /* 6966 */ { MAD_F(0x040f5d61) /* 0.253751164 */, 19 }, /* 6967 */ { MAD_F(0x040f904f) /* 0.253799734 */, 19 }, /* 6968 */ { MAD_F(0x040fc33e) /* 0.253848307 */, 19 }, /* 6969 */ { MAD_F(0x040ff62d) /* 0.253896883 */, 19 }, /* 6970 */ { MAD_F(0x0410291d) /* 0.253945460 */, 19 }, /* 6971 */ { MAD_F(0x04105c0e) /* 0.253994040 */, 19 }, /* 6972 */ { MAD_F(0x04108eff) /* 0.254042622 */, 19 }, /* 6973 */ { MAD_F(0x0410c1f1) /* 0.254091207 */, 19 }, /* 6974 */ { MAD_F(0x0410f4e3) /* 0.254139794 */, 19 }, /* 6975 */ { MAD_F(0x041127d6) /* 0.254188383 */, 19 }, /* 6976 */ { MAD_F(0x04115aca) /* 0.254236974 */, 19 }, /* 6977 */ { MAD_F(0x04118dbe) /* 0.254285568 */, 19 }, /* 6978 */ { MAD_F(0x0411c0b3) /* 0.254334165 */, 19 }, /* 6979 */ { MAD_F(0x0411f3a9) /* 0.254382763 */, 19 }, /* 6980 */ { MAD_F(0x0412269f) /* 0.254431364 */, 19 }, /* 6981 */ { MAD_F(0x04125996) /* 0.254479967 */, 19 }, /* 6982 */ { MAD_F(0x04128c8d) /* 0.254528572 */, 19 }, /* 6983 */ { MAD_F(0x0412bf85) /* 0.254577180 */, 19 }, /* 6984 */ { MAD_F(0x0412f27e) /* 0.254625790 */, 19 }, /* 6985 */ { MAD_F(0x04132577) /* 0.254674403 */, 19 }, /* 6986 */ { MAD_F(0x04135871) /* 0.254723017 */, 19 }, /* 6987 */ { MAD_F(0x04138b6c) /* 0.254771635 */, 19 }, /* 6988 */ { MAD_F(0x0413be67) /* 0.254820254 */, 19 }, /* 6989 */ { MAD_F(0x0413f163) /* 0.254868876 */, 19 }, /* 6990 */ { MAD_F(0x0414245f) /* 0.254917500 */, 19 }, /* 6991 */ { MAD_F(0x0414575c) /* 0.254966126 */, 19 }, /* 6992 */ { MAD_F(0x04148a5a) /* 0.255014755 */, 19 }, /* 6993 */ { MAD_F(0x0414bd58) /* 0.255063386 */, 19 }, /* 6994 */ { MAD_F(0x0414f057) /* 0.255112019 */, 19 }, /* 6995 */ { MAD_F(0x04152356) /* 0.255160655 */, 19 }, /* 6996 */ { MAD_F(0x04155657) /* 0.255209292 */, 19 }, /* 6997 */ { MAD_F(0x04158957) /* 0.255257933 */, 19 }, /* 6998 */ { MAD_F(0x0415bc59) /* 0.255306575 */, 19 }, /* 6999 */ { MAD_F(0x0415ef5b) /* 0.255355220 */, 19 }, /* 7000 */ { MAD_F(0x0416225d) /* 0.255403867 */, 19 }, /* 7001 */ { MAD_F(0x04165561) /* 0.255452517 */, 19 }, /* 7002 */ { MAD_F(0x04168864) /* 0.255501169 */, 19 }, /* 7003 */ { MAD_F(0x0416bb69) /* 0.255549823 */, 19 }, /* 7004 */ { MAD_F(0x0416ee6e) /* 0.255598479 */, 19 }, /* 7005 */ { MAD_F(0x04172174) /* 0.255647138 */, 19 }, /* 7006 */ { MAD_F(0x0417547a) /* 0.255695799 */, 19 }, /* 7007 */ { MAD_F(0x04178781) /* 0.255744463 */, 19 }, /* 7008 */ { MAD_F(0x0417ba89) /* 0.255793128 */, 19 }, /* 7009 */ { MAD_F(0x0417ed91) /* 0.255841796 */, 19 }, /* 7010 */ { MAD_F(0x0418209a) /* 0.255890467 */, 19 }, /* 7011 */ { MAD_F(0x041853a3) /* 0.255939139 */, 19 }, /* 7012 */ { MAD_F(0x041886ad) /* 0.255987814 */, 19 }, /* 7013 */ { MAD_F(0x0418b9b8) /* 0.256036492 */, 19 }, /* 7014 */ { MAD_F(0x0418ecc3) /* 0.256085171 */, 19 }, /* 7015 */ { MAD_F(0x04191fcf) /* 0.256133853 */, 19 }, /* 7016 */ { MAD_F(0x041952dc) /* 0.256182537 */, 19 }, /* 7017 */ { MAD_F(0x041985e9) /* 0.256231224 */, 19 }, /* 7018 */ { MAD_F(0x0419b8f7) /* 0.256279913 */, 19 }, /* 7019 */ { MAD_F(0x0419ec05) /* 0.256328604 */, 19 }, /* 7020 */ { MAD_F(0x041a1f15) /* 0.256377297 */, 19 }, /* 7021 */ { MAD_F(0x041a5224) /* 0.256425993 */, 19 }, /* 7022 */ { MAD_F(0x041a8534) /* 0.256474691 */, 19 }, /* 7023 */ { MAD_F(0x041ab845) /* 0.256523392 */, 19 }, /* 7024 */ { MAD_F(0x041aeb57) /* 0.256572095 */, 19 }, /* 7025 */ { MAD_F(0x041b1e69) /* 0.256620800 */, 19 }, /* 7026 */ { MAD_F(0x041b517c) /* 0.256669507 */, 19 }, /* 7027 */ { MAD_F(0x041b848f) /* 0.256718217 */, 19 }, /* 7028 */ { MAD_F(0x041bb7a3) /* 0.256766929 */, 19 }, /* 7029 */ { MAD_F(0x041beab8) /* 0.256815643 */, 19 }, /* 7030 */ { MAD_F(0x041c1dcd) /* 0.256864359 */, 19 }, /* 7031 */ { MAD_F(0x041c50e3) /* 0.256913078 */, 19 }, /* 7032 */ { MAD_F(0x041c83fa) /* 0.256961800 */, 19 }, /* 7033 */ { MAD_F(0x041cb711) /* 0.257010523 */, 19 }, /* 7034 */ { MAD_F(0x041cea28) /* 0.257059249 */, 19 }, /* 7035 */ { MAD_F(0x041d1d41) /* 0.257107977 */, 19 }, /* 7036 */ { MAD_F(0x041d505a) /* 0.257156708 */, 19 }, /* 7037 */ { MAD_F(0x041d8373) /* 0.257205440 */, 19 }, /* 7038 */ { MAD_F(0x041db68e) /* 0.257254175 */, 19 }, /* 7039 */ { MAD_F(0x041de9a8) /* 0.257302913 */, 19 }, /* 7040 */ { MAD_F(0x041e1cc4) /* 0.257351652 */, 19 }, /* 7041 */ { MAD_F(0x041e4fe0) /* 0.257400394 */, 19 }, /* 7042 */ { MAD_F(0x041e82fd) /* 0.257449139 */, 19 }, /* 7043 */ { MAD_F(0x041eb61a) /* 0.257497885 */, 19 }, /* 7044 */ { MAD_F(0x041ee938) /* 0.257546634 */, 19 }, /* 7045 */ { MAD_F(0x041f1c57) /* 0.257595386 */, 19 }, /* 7046 */ { MAD_F(0x041f4f76) /* 0.257644139 */, 19 }, /* 7047 */ { MAD_F(0x041f8296) /* 0.257692895 */, 19 }, /* 7048 */ { MAD_F(0x041fb5b6) /* 0.257741653 */, 19 }, /* 7049 */ { MAD_F(0x041fe8d7) /* 0.257790414 */, 19 }, /* 7050 */ { MAD_F(0x04201bf9) /* 0.257839176 */, 19 }, /* 7051 */ { MAD_F(0x04204f1b) /* 0.257887941 */, 19 }, /* 7052 */ { MAD_F(0x0420823e) /* 0.257936709 */, 19 }, /* 7053 */ { MAD_F(0x0420b561) /* 0.257985478 */, 19 }, /* 7054 */ { MAD_F(0x0420e885) /* 0.258034250 */, 19 }, /* 7055 */ { MAD_F(0x04211baa) /* 0.258083025 */, 19 }, /* 7056 */ { MAD_F(0x04214ed0) /* 0.258131801 */, 19 }, /* 7057 */ { MAD_F(0x042181f6) /* 0.258180580 */, 19 }, /* 7058 */ { MAD_F(0x0421b51c) /* 0.258229361 */, 19 }, /* 7059 */ { MAD_F(0x0421e843) /* 0.258278145 */, 19 }, /* 7060 */ { MAD_F(0x04221b6b) /* 0.258326931 */, 19 }, /* 7061 */ { MAD_F(0x04224e94) /* 0.258375719 */, 19 }, /* 7062 */ { MAD_F(0x042281bd) /* 0.258424509 */, 19 }, /* 7063 */ { MAD_F(0x0422b4e6) /* 0.258473302 */, 19 }, /* 7064 */ { MAD_F(0x0422e811) /* 0.258522097 */, 19 }, /* 7065 */ { MAD_F(0x04231b3c) /* 0.258570894 */, 19 }, /* 7066 */ { MAD_F(0x04234e67) /* 0.258619694 */, 19 }, /* 7067 */ { MAD_F(0x04238193) /* 0.258668496 */, 19 }, /* 7068 */ { MAD_F(0x0423b4c0) /* 0.258717300 */, 19 }, /* 7069 */ { MAD_F(0x0423e7ee) /* 0.258766106 */, 19 }, /* 7070 */ { MAD_F(0x04241b1c) /* 0.258814915 */, 19 }, /* 7071 */ { MAD_F(0x04244e4a) /* 0.258863726 */, 19 }, /* 7072 */ { MAD_F(0x04248179) /* 0.258912540 */, 19 }, /* 7073 */ { MAD_F(0x0424b4a9) /* 0.258961356 */, 19 }, /* 7074 */ { MAD_F(0x0424e7da) /* 0.259010174 */, 19 }, /* 7075 */ { MAD_F(0x04251b0b) /* 0.259058994 */, 19 }, /* 7076 */ { MAD_F(0x04254e3d) /* 0.259107817 */, 19 }, /* 7077 */ { MAD_F(0x0425816f) /* 0.259156642 */, 19 }, /* 7078 */ { MAD_F(0x0425b4a2) /* 0.259205469 */, 19 }, /* 7079 */ { MAD_F(0x0425e7d6) /* 0.259254298 */, 19 }, /* 7080 */ { MAD_F(0x04261b0a) /* 0.259303130 */, 19 }, /* 7081 */ { MAD_F(0x04264e3f) /* 0.259351964 */, 19 }, /* 7082 */ { MAD_F(0x04268174) /* 0.259400801 */, 19 }, /* 7083 */ { MAD_F(0x0426b4aa) /* 0.259449639 */, 19 }, /* 7084 */ { MAD_F(0x0426e7e1) /* 0.259498480 */, 19 }, /* 7085 */ { MAD_F(0x04271b18) /* 0.259547324 */, 19 }, /* 7086 */ { MAD_F(0x04274e50) /* 0.259596169 */, 19 }, /* 7087 */ { MAD_F(0x04278188) /* 0.259645017 */, 19 }, /* 7088 */ { MAD_F(0x0427b4c2) /* 0.259693868 */, 19 }, /* 7089 */ { MAD_F(0x0427e7fb) /* 0.259742720 */, 19 }, /* 7090 */ { MAD_F(0x04281b36) /* 0.259791575 */, 19 }, /* 7091 */ { MAD_F(0x04284e71) /* 0.259840432 */, 19 }, /* 7092 */ { MAD_F(0x042881ac) /* 0.259889291 */, 19 }, /* 7093 */ { MAD_F(0x0428b4e8) /* 0.259938153 */, 19 }, /* 7094 */ { MAD_F(0x0428e825) /* 0.259987017 */, 19 }, /* 7095 */ { MAD_F(0x04291b63) /* 0.260035883 */, 19 }, /* 7096 */ { MAD_F(0x04294ea1) /* 0.260084752 */, 19 }, /* 7097 */ { MAD_F(0x042981df) /* 0.260133623 */, 19 }, /* 7098 */ { MAD_F(0x0429b51f) /* 0.260182496 */, 19 }, /* 7099 */ { MAD_F(0x0429e85f) /* 0.260231372 */, 19 }, /* 7100 */ { MAD_F(0x042a1b9f) /* 0.260280249 */, 19 }, /* 7101 */ { MAD_F(0x042a4ee0) /* 0.260329129 */, 19 }, /* 7102 */ { MAD_F(0x042a8222) /* 0.260378012 */, 19 }, /* 7103 */ { MAD_F(0x042ab564) /* 0.260426896 */, 19 }, /* 7104 */ { MAD_F(0x042ae8a7) /* 0.260475783 */, 19 }, /* 7105 */ { MAD_F(0x042b1beb) /* 0.260524673 */, 19 }, /* 7106 */ { MAD_F(0x042b4f2f) /* 0.260573564 */, 19 }, /* 7107 */ { MAD_F(0x042b8274) /* 0.260622458 */, 19 }, /* 7108 */ { MAD_F(0x042bb5ba) /* 0.260671354 */, 19 }, /* 7109 */ { MAD_F(0x042be900) /* 0.260720252 */, 19 }, /* 7110 */ { MAD_F(0x042c1c46) /* 0.260769153 */, 19 }, /* 7111 */ { MAD_F(0x042c4f8e) /* 0.260818056 */, 19 }, /* 7112 */ { MAD_F(0x042c82d6) /* 0.260866961 */, 19 }, /* 7113 */ { MAD_F(0x042cb61e) /* 0.260915869 */, 19 }, /* 7114 */ { MAD_F(0x042ce967) /* 0.260964779 */, 19 }, /* 7115 */ { MAD_F(0x042d1cb1) /* 0.261013691 */, 19 }, /* 7116 */ { MAD_F(0x042d4ffb) /* 0.261062606 */, 19 }, /* 7117 */ { MAD_F(0x042d8346) /* 0.261111522 */, 19 }, /* 7118 */ { MAD_F(0x042db692) /* 0.261160441 */, 19 }, /* 7119 */ { MAD_F(0x042de9de) /* 0.261209363 */, 19 }, /* 7120 */ { MAD_F(0x042e1d2b) /* 0.261258286 */, 19 }, /* 7121 */ { MAD_F(0x042e5078) /* 0.261307212 */, 19 }, /* 7122 */ { MAD_F(0x042e83c6) /* 0.261356140 */, 19 }, /* 7123 */ { MAD_F(0x042eb715) /* 0.261405071 */, 19 }, /* 7124 */ { MAD_F(0x042eea64) /* 0.261454004 */, 19 }, /* 7125 */ { MAD_F(0x042f1db4) /* 0.261502939 */, 19 }, /* 7126 */ { MAD_F(0x042f5105) /* 0.261551876 */, 19 }, /* 7127 */ { MAD_F(0x042f8456) /* 0.261600816 */, 19 }, /* 7128 */ { MAD_F(0x042fb7a8) /* 0.261649758 */, 19 }, /* 7129 */ { MAD_F(0x042feafa) /* 0.261698702 */, 19 }, /* 7130 */ { MAD_F(0x04301e4d) /* 0.261747649 */, 19 }, /* 7131 */ { MAD_F(0x043051a1) /* 0.261796597 */, 19 }, /* 7132 */ { MAD_F(0x043084f5) /* 0.261845548 */, 19 }, /* 7133 */ { MAD_F(0x0430b84a) /* 0.261894502 */, 19 }, /* 7134 */ { MAD_F(0x0430eb9f) /* 0.261943458 */, 19 }, /* 7135 */ { MAD_F(0x04311ef5) /* 0.261992416 */, 19 }, /* 7136 */ { MAD_F(0x0431524c) /* 0.262041376 */, 19 }, /* 7137 */ { MAD_F(0x043185a3) /* 0.262090338 */, 19 }, /* 7138 */ { MAD_F(0x0431b8fb) /* 0.262139303 */, 19 }, /* 7139 */ { MAD_F(0x0431ec54) /* 0.262188270 */, 19 }, /* 7140 */ { MAD_F(0x04321fad) /* 0.262237240 */, 19 }, /* 7141 */ { MAD_F(0x04325306) /* 0.262286211 */, 19 }, /* 7142 */ { MAD_F(0x04328661) /* 0.262335185 */, 19 }, /* 7143 */ { MAD_F(0x0432b9bc) /* 0.262384162 */, 19 }, /* 7144 */ { MAD_F(0x0432ed17) /* 0.262433140 */, 19 }, /* 7145 */ { MAD_F(0x04332074) /* 0.262482121 */, 19 }, /* 7146 */ { MAD_F(0x043353d0) /* 0.262531104 */, 19 }, /* 7147 */ { MAD_F(0x0433872e) /* 0.262580089 */, 19 }, /* 7148 */ { MAD_F(0x0433ba8c) /* 0.262629077 */, 19 }, /* 7149 */ { MAD_F(0x0433edea) /* 0.262678067 */, 19 }, /* 7150 */ { MAD_F(0x0434214a) /* 0.262727059 */, 19 }, /* 7151 */ { MAD_F(0x043454aa) /* 0.262776054 */, 19 }, /* 7152 */ { MAD_F(0x0434880a) /* 0.262825051 */, 19 }, /* 7153 */ { MAD_F(0x0434bb6b) /* 0.262874050 */, 19 }, /* 7154 */ { MAD_F(0x0434eecd) /* 0.262923051 */, 19 }, /* 7155 */ { MAD_F(0x0435222f) /* 0.262972055 */, 19 }, /* 7156 */ { MAD_F(0x04355592) /* 0.263021061 */, 19 }, /* 7157 */ { MAD_F(0x043588f6) /* 0.263070069 */, 19 }, /* 7158 */ { MAD_F(0x0435bc5a) /* 0.263119079 */, 19 }, /* 7159 */ { MAD_F(0x0435efbf) /* 0.263168092 */, 19 }, /* 7160 */ { MAD_F(0x04362324) /* 0.263217107 */, 19 }, /* 7161 */ { MAD_F(0x0436568a) /* 0.263266125 */, 19 }, /* 7162 */ { MAD_F(0x043689f1) /* 0.263315144 */, 19 }, /* 7163 */ { MAD_F(0x0436bd58) /* 0.263364166 */, 19 }, /* 7164 */ { MAD_F(0x0436f0c0) /* 0.263413191 */, 19 }, /* 7165 */ { MAD_F(0x04372428) /* 0.263462217 */, 19 }, /* 7166 */ { MAD_F(0x04375791) /* 0.263511246 */, 19 }, /* 7167 */ { MAD_F(0x04378afb) /* 0.263560277 */, 19 }, /* 7168 */ { MAD_F(0x0437be65) /* 0.263609310 */, 19 }, /* 7169 */ { MAD_F(0x0437f1d0) /* 0.263658346 */, 19 }, /* 7170 */ { MAD_F(0x0438253c) /* 0.263707384 */, 19 }, /* 7171 */ { MAD_F(0x043858a8) /* 0.263756424 */, 19 }, /* 7172 */ { MAD_F(0x04388c14) /* 0.263805466 */, 19 }, /* 7173 */ { MAD_F(0x0438bf82) /* 0.263854511 */, 19 }, /* 7174 */ { MAD_F(0x0438f2f0) /* 0.263903558 */, 19 }, /* 7175 */ { MAD_F(0x0439265e) /* 0.263952607 */, 19 }, /* 7176 */ { MAD_F(0x043959cd) /* 0.264001659 */, 19 }, /* 7177 */ { MAD_F(0x04398d3d) /* 0.264050713 */, 19 }, /* 7178 */ { MAD_F(0x0439c0ae) /* 0.264099769 */, 19 }, /* 7179 */ { MAD_F(0x0439f41f) /* 0.264148827 */, 19 }, /* 7180 */ { MAD_F(0x043a2790) /* 0.264197888 */, 19 }, /* 7181 */ { MAD_F(0x043a5b02) /* 0.264246951 */, 19 }, /* 7182 */ { MAD_F(0x043a8e75) /* 0.264296016 */, 19 }, /* 7183 */ { MAD_F(0x043ac1e9) /* 0.264345084 */, 19 }, /* 7184 */ { MAD_F(0x043af55d) /* 0.264394153 */, 19 }, /* 7185 */ { MAD_F(0x043b28d2) /* 0.264443225 */, 19 }, /* 7186 */ { MAD_F(0x043b5c47) /* 0.264492300 */, 19 }, /* 7187 */ { MAD_F(0x043b8fbd) /* 0.264541376 */, 19 }, /* 7188 */ { MAD_F(0x043bc333) /* 0.264590455 */, 19 }, /* 7189 */ { MAD_F(0x043bf6aa) /* 0.264639536 */, 19 }, /* 7190 */ { MAD_F(0x043c2a22) /* 0.264688620 */, 19 }, /* 7191 */ { MAD_F(0x043c5d9a) /* 0.264737706 */, 19 }, /* 7192 */ { MAD_F(0x043c9113) /* 0.264786794 */, 19 }, /* 7193 */ { MAD_F(0x043cc48d) /* 0.264835884 */, 19 }, /* 7194 */ { MAD_F(0x043cf807) /* 0.264884976 */, 19 }, /* 7195 */ { MAD_F(0x043d2b82) /* 0.264934071 */, 19 }, /* 7196 */ { MAD_F(0x043d5efd) /* 0.264983168 */, 19 }, /* 7197 */ { MAD_F(0x043d9279) /* 0.265032268 */, 19 }, /* 7198 */ { MAD_F(0x043dc5f6) /* 0.265081369 */, 19 }, /* 7199 */ { MAD_F(0x043df973) /* 0.265130473 */, 19 }, /* 7200 */ { MAD_F(0x043e2cf1) /* 0.265179580 */, 19 }, /* 7201 */ { MAD_F(0x043e6070) /* 0.265228688 */, 19 }, /* 7202 */ { MAD_F(0x043e93ef) /* 0.265277799 */, 19 }, /* 7203 */ { MAD_F(0x043ec76e) /* 0.265326912 */, 19 }, /* 7204 */ { MAD_F(0x043efaef) /* 0.265376027 */, 19 }, /* 7205 */ { MAD_F(0x043f2e6f) /* 0.265425145 */, 19 }, /* 7206 */ { MAD_F(0x043f61f1) /* 0.265474264 */, 19 }, /* 7207 */ { MAD_F(0x043f9573) /* 0.265523387 */, 19 }, /* 7208 */ { MAD_F(0x043fc8f6) /* 0.265572511 */, 19 }, /* 7209 */ { MAD_F(0x043ffc79) /* 0.265621638 */, 19 }, /* 7210 */ { MAD_F(0x04402ffd) /* 0.265670766 */, 19 }, /* 7211 */ { MAD_F(0x04406382) /* 0.265719898 */, 19 }, /* 7212 */ { MAD_F(0x04409707) /* 0.265769031 */, 19 }, /* 7213 */ { MAD_F(0x0440ca8d) /* 0.265818167 */, 19 }, /* 7214 */ { MAD_F(0x0440fe13) /* 0.265867305 */, 19 }, /* 7215 */ { MAD_F(0x0441319a) /* 0.265916445 */, 19 }, /* 7216 */ { MAD_F(0x04416522) /* 0.265965588 */, 19 }, /* 7217 */ { MAD_F(0x044198aa) /* 0.266014732 */, 19 }, /* 7218 */ { MAD_F(0x0441cc33) /* 0.266063880 */, 19 }, /* 7219 */ { MAD_F(0x0441ffbc) /* 0.266113029 */, 19 }, /* 7220 */ { MAD_F(0x04423346) /* 0.266162181 */, 19 }, /* 7221 */ { MAD_F(0x044266d1) /* 0.266211334 */, 19 }, /* 7222 */ { MAD_F(0x04429a5c) /* 0.266260491 */, 19 }, /* 7223 */ { MAD_F(0x0442cde8) /* 0.266309649 */, 19 }, /* 7224 */ { MAD_F(0x04430174) /* 0.266358810 */, 19 }, /* 7225 */ { MAD_F(0x04433501) /* 0.266407973 */, 19 }, /* 7226 */ { MAD_F(0x0443688f) /* 0.266457138 */, 19 }, /* 7227 */ { MAD_F(0x04439c1d) /* 0.266506305 */, 19 }, /* 7228 */ { MAD_F(0x0443cfac) /* 0.266555475 */, 19 }, /* 7229 */ { MAD_F(0x0444033c) /* 0.266604647 */, 19 }, /* 7230 */ { MAD_F(0x044436cc) /* 0.266653822 */, 19 }, /* 7231 */ { MAD_F(0x04446a5d) /* 0.266702998 */, 19 }, /* 7232 */ { MAD_F(0x04449dee) /* 0.266752177 */, 19 }, /* 7233 */ { MAD_F(0x0444d180) /* 0.266801358 */, 19 }, /* 7234 */ { MAD_F(0x04450513) /* 0.266850541 */, 19 }, /* 7235 */ { MAD_F(0x044538a6) /* 0.266899727 */, 19 }, /* 7236 */ { MAD_F(0x04456c39) /* 0.266948915 */, 19 }, /* 7237 */ { MAD_F(0x04459fce) /* 0.266998105 */, 19 }, /* 7238 */ { MAD_F(0x0445d363) /* 0.267047298 */, 19 }, /* 7239 */ { MAD_F(0x044606f8) /* 0.267096492 */, 19 }, /* 7240 */ { MAD_F(0x04463a8f) /* 0.267145689 */, 19 }, /* 7241 */ { MAD_F(0x04466e25) /* 0.267194888 */, 19 }, /* 7242 */ { MAD_F(0x0446a1bd) /* 0.267244090 */, 19 }, /* 7243 */ { MAD_F(0x0446d555) /* 0.267293294 */, 19 }, /* 7244 */ { MAD_F(0x044708ee) /* 0.267342500 */, 19 }, /* 7245 */ { MAD_F(0x04473c87) /* 0.267391708 */, 19 }, /* 7246 */ { MAD_F(0x04477021) /* 0.267440919 */, 19 }, /* 7247 */ { MAD_F(0x0447a3bb) /* 0.267490131 */, 19 }, /* 7248 */ { MAD_F(0x0447d756) /* 0.267539347 */, 19 }, /* 7249 */ { MAD_F(0x04480af2) /* 0.267588564 */, 19 }, /* 7250 */ { MAD_F(0x04483e8e) /* 0.267637783 */, 19 }, /* 7251 */ { MAD_F(0x0448722b) /* 0.267687005 */, 19 }, /* 7252 */ { MAD_F(0x0448a5c9) /* 0.267736229 */, 19 }, /* 7253 */ { MAD_F(0x0448d967) /* 0.267785456 */, 19 }, /* 7254 */ { MAD_F(0x04490d05) /* 0.267834685 */, 19 }, /* 7255 */ { MAD_F(0x044940a5) /* 0.267883915 */, 19 }, /* 7256 */ { MAD_F(0x04497445) /* 0.267933149 */, 19 }, /* 7257 */ { MAD_F(0x0449a7e5) /* 0.267982384 */, 19 }, /* 7258 */ { MAD_F(0x0449db86) /* 0.268031622 */, 19 }, /* 7259 */ { MAD_F(0x044a0f28) /* 0.268080862 */, 19 }, /* 7260 */ { MAD_F(0x044a42ca) /* 0.268130104 */, 19 }, /* 7261 */ { MAD_F(0x044a766d) /* 0.268179349 */, 19 }, /* 7262 */ { MAD_F(0x044aaa11) /* 0.268228595 */, 19 }, /* 7263 */ { MAD_F(0x044addb5) /* 0.268277844 */, 19 }, /* 7264 */ { MAD_F(0x044b115a) /* 0.268327096 */, 19 }, /* 7265 */ { MAD_F(0x044b44ff) /* 0.268376349 */, 19 }, /* 7266 */ { MAD_F(0x044b78a5) /* 0.268425605 */, 19 }, /* 7267 */ { MAD_F(0x044bac4c) /* 0.268474863 */, 19 }, /* 7268 */ { MAD_F(0x044bdff3) /* 0.268524123 */, 19 }, /* 7269 */ { MAD_F(0x044c139b) /* 0.268573386 */, 19 }, /* 7270 */ { MAD_F(0x044c4743) /* 0.268622651 */, 19 }, /* 7271 */ { MAD_F(0x044c7aec) /* 0.268671918 */, 19 }, /* 7272 */ { MAD_F(0x044cae96) /* 0.268721187 */, 19 }, /* 7273 */ { MAD_F(0x044ce240) /* 0.268770459 */, 19 }, /* 7274 */ { MAD_F(0x044d15eb) /* 0.268819733 */, 19 }, /* 7275 */ { MAD_F(0x044d4997) /* 0.268869009 */, 19 }, /* 7276 */ { MAD_F(0x044d7d43) /* 0.268918287 */, 19 }, /* 7277 */ { MAD_F(0x044db0ef) /* 0.268967568 */, 19 }, /* 7278 */ { MAD_F(0x044de49d) /* 0.269016851 */, 19 }, /* 7279 */ { MAD_F(0x044e184b) /* 0.269066136 */, 19 }, /* 7280 */ { MAD_F(0x044e4bf9) /* 0.269115423 */, 19 }, /* 7281 */ { MAD_F(0x044e7fa8) /* 0.269164713 */, 19 }, /* 7282 */ { MAD_F(0x044eb358) /* 0.269214005 */, 19 }, /* 7283 */ { MAD_F(0x044ee708) /* 0.269263299 */, 19 }, /* 7284 */ { MAD_F(0x044f1ab9) /* 0.269312595 */, 19 }, /* 7285 */ { MAD_F(0x044f4e6b) /* 0.269361894 */, 19 }, /* 7286 */ { MAD_F(0x044f821d) /* 0.269411195 */, 19 }, /* 7287 */ { MAD_F(0x044fb5cf) /* 0.269460498 */, 19 }, /* 7288 */ { MAD_F(0x044fe983) /* 0.269509804 */, 19 }, /* 7289 */ { MAD_F(0x04501d37) /* 0.269559111 */, 19 }, /* 7290 */ { MAD_F(0x045050eb) /* 0.269608421 */, 19 }, /* 7291 */ { MAD_F(0x045084a0) /* 0.269657734 */, 19 }, /* 7292 */ { MAD_F(0x0450b856) /* 0.269707048 */, 19 }, /* 7293 */ { MAD_F(0x0450ec0d) /* 0.269756365 */, 19 }, /* 7294 */ { MAD_F(0x04511fc4) /* 0.269805684 */, 19 }, /* 7295 */ { MAD_F(0x0451537b) /* 0.269855005 */, 19 }, /* 7296 */ { MAD_F(0x04518733) /* 0.269904329 */, 19 }, /* 7297 */ { MAD_F(0x0451baec) /* 0.269953654 */, 19 }, /* 7298 */ { MAD_F(0x0451eea5) /* 0.270002982 */, 19 }, /* 7299 */ { MAD_F(0x0452225f) /* 0.270052313 */, 19 }, /* 7300 */ { MAD_F(0x0452561a) /* 0.270101645 */, 19 }, /* 7301 */ { MAD_F(0x045289d5) /* 0.270150980 */, 19 }, /* 7302 */ { MAD_F(0x0452bd91) /* 0.270200317 */, 19 }, /* 7303 */ { MAD_F(0x0452f14d) /* 0.270249656 */, 19 }, /* 7304 */ { MAD_F(0x0453250a) /* 0.270298998 */, 19 }, /* 7305 */ { MAD_F(0x045358c8) /* 0.270348341 */, 19 }, /* 7306 */ { MAD_F(0x04538c86) /* 0.270397687 */, 19 }, /* 7307 */ { MAD_F(0x0453c045) /* 0.270447036 */, 19 }, /* 7308 */ { MAD_F(0x0453f405) /* 0.270496386 */, 19 }, /* 7309 */ { MAD_F(0x045427c5) /* 0.270545739 */, 19 }, /* 7310 */ { MAD_F(0x04545b85) /* 0.270595094 */, 19 }, /* 7311 */ { MAD_F(0x04548f46) /* 0.270644451 */, 19 }, /* 7312 */ { MAD_F(0x0454c308) /* 0.270693811 */, 19 }, /* 7313 */ { MAD_F(0x0454f6cb) /* 0.270743173 */, 19 }, /* 7314 */ { MAD_F(0x04552a8e) /* 0.270792537 */, 19 }, /* 7315 */ { MAD_F(0x04555e51) /* 0.270841903 */, 19 }, /* 7316 */ { MAD_F(0x04559216) /* 0.270891271 */, 19 }, /* 7317 */ { MAD_F(0x0455c5db) /* 0.270940642 */, 19 }, /* 7318 */ { MAD_F(0x0455f9a0) /* 0.270990015 */, 19 }, /* 7319 */ { MAD_F(0x04562d66) /* 0.271039390 */, 19 }, /* 7320 */ { MAD_F(0x0456612d) /* 0.271088768 */, 19 }, /* 7321 */ { MAD_F(0x045694f4) /* 0.271138148 */, 19 }, /* 7322 */ { MAD_F(0x0456c8bc) /* 0.271187530 */, 19 }, /* 7323 */ { MAD_F(0x0456fc84) /* 0.271236914 */, 19 }, /* 7324 */ { MAD_F(0x0457304e) /* 0.271286301 */, 19 }, /* 7325 */ { MAD_F(0x04576417) /* 0.271335689 */, 19 }, /* 7326 */ { MAD_F(0x045797e2) /* 0.271385080 */, 19 }, /* 7327 */ { MAD_F(0x0457cbac) /* 0.271434474 */, 19 }, /* 7328 */ { MAD_F(0x0457ff78) /* 0.271483869 */, 19 }, /* 7329 */ { MAD_F(0x04583344) /* 0.271533267 */, 19 }, /* 7330 */ { MAD_F(0x04586711) /* 0.271582667 */, 19 }, /* 7331 */ { MAD_F(0x04589ade) /* 0.271632069 */, 19 }, /* 7332 */ { MAD_F(0x0458ceac) /* 0.271681474 */, 19 }, /* 7333 */ { MAD_F(0x0459027b) /* 0.271730880 */, 19 }, /* 7334 */ { MAD_F(0x0459364a) /* 0.271780289 */, 19 }, /* 7335 */ { MAD_F(0x04596a19) /* 0.271829701 */, 19 }, /* 7336 */ { MAD_F(0x04599dea) /* 0.271879114 */, 19 }, /* 7337 */ { MAD_F(0x0459d1bb) /* 0.271928530 */, 19 }, /* 7338 */ { MAD_F(0x045a058c) /* 0.271977948 */, 19 }, /* 7339 */ { MAD_F(0x045a395e) /* 0.272027368 */, 19 }, /* 7340 */ { MAD_F(0x045a6d31) /* 0.272076790 */, 19 }, /* 7341 */ { MAD_F(0x045aa104) /* 0.272126215 */, 19 }, /* 7342 */ { MAD_F(0x045ad4d8) /* 0.272175642 */, 19 }, /* 7343 */ { MAD_F(0x045b08ad) /* 0.272225071 */, 19 }, /* 7344 */ { MAD_F(0x045b3c82) /* 0.272274503 */, 19 }, /* 7345 */ { MAD_F(0x045b7058) /* 0.272323936 */, 19 }, /* 7346 */ { MAD_F(0x045ba42e) /* 0.272373372 */, 19 }, /* 7347 */ { MAD_F(0x045bd805) /* 0.272422810 */, 19 }, /* 7348 */ { MAD_F(0x045c0bdd) /* 0.272472251 */, 19 }, /* 7349 */ { MAD_F(0x045c3fb5) /* 0.272521693 */, 19 }, /* 7350 */ { MAD_F(0x045c738e) /* 0.272571138 */, 19 }, /* 7351 */ { MAD_F(0x045ca767) /* 0.272620585 */, 19 }, /* 7352 */ { MAD_F(0x045cdb41) /* 0.272670035 */, 19 }, /* 7353 */ { MAD_F(0x045d0f1b) /* 0.272719486 */, 19 }, /* 7354 */ { MAD_F(0x045d42f7) /* 0.272768940 */, 19 }, /* 7355 */ { MAD_F(0x045d76d2) /* 0.272818396 */, 19 }, /* 7356 */ { MAD_F(0x045daaaf) /* 0.272867855 */, 19 }, /* 7357 */ { MAD_F(0x045dde8c) /* 0.272917315 */, 19 }, /* 7358 */ { MAD_F(0x045e1269) /* 0.272966778 */, 19 }, /* 7359 */ { MAD_F(0x045e4647) /* 0.273016243 */, 19 }, /* 7360 */ { MAD_F(0x045e7a26) /* 0.273065710 */, 19 }, /* 7361 */ { MAD_F(0x045eae06) /* 0.273115180 */, 19 }, /* 7362 */ { MAD_F(0x045ee1e6) /* 0.273164652 */, 19 }, /* 7363 */ { MAD_F(0x045f15c6) /* 0.273214126 */, 19 }, /* 7364 */ { MAD_F(0x045f49a7) /* 0.273263602 */, 19 }, /* 7365 */ { MAD_F(0x045f7d89) /* 0.273313081 */, 19 }, /* 7366 */ { MAD_F(0x045fb16c) /* 0.273362561 */, 19 }, /* 7367 */ { MAD_F(0x045fe54f) /* 0.273412044 */, 19 }, /* 7368 */ { MAD_F(0x04601932) /* 0.273461530 */, 19 }, /* 7369 */ { MAD_F(0x04604d16) /* 0.273511017 */, 19 }, /* 7370 */ { MAD_F(0x046080fb) /* 0.273560507 */, 19 }, /* 7371 */ { MAD_F(0x0460b4e1) /* 0.273609999 */, 19 }, /* 7372 */ { MAD_F(0x0460e8c7) /* 0.273659493 */, 19 }, /* 7373 */ { MAD_F(0x04611cad) /* 0.273708989 */, 19 }, /* 7374 */ { MAD_F(0x04615094) /* 0.273758488 */, 19 }, /* 7375 */ { MAD_F(0x0461847c) /* 0.273807989 */, 19 }, /* 7376 */ { MAD_F(0x0461b864) /* 0.273857492 */, 19 }, /* 7377 */ { MAD_F(0x0461ec4d) /* 0.273906997 */, 19 }, /* 7378 */ { MAD_F(0x04622037) /* 0.273956505 */, 19 }, /* 7379 */ { MAD_F(0x04625421) /* 0.274006015 */, 19 }, /* 7380 */ { MAD_F(0x0462880c) /* 0.274055527 */, 19 }, /* 7381 */ { MAD_F(0x0462bbf7) /* 0.274105041 */, 19 }, /* 7382 */ { MAD_F(0x0462efe3) /* 0.274154558 */, 19 }, /* 7383 */ { MAD_F(0x046323d0) /* 0.274204076 */, 19 }, /* 7384 */ { MAD_F(0x046357bd) /* 0.274253597 */, 19 }, /* 7385 */ { MAD_F(0x04638bab) /* 0.274303121 */, 19 }, /* 7386 */ { MAD_F(0x0463bf99) /* 0.274352646 */, 19 }, /* 7387 */ { MAD_F(0x0463f388) /* 0.274402174 */, 19 }, /* 7388 */ { MAD_F(0x04642778) /* 0.274451704 */, 19 }, /* 7389 */ { MAD_F(0x04645b68) /* 0.274501236 */, 19 }, /* 7390 */ { MAD_F(0x04648f59) /* 0.274550771 */, 19 }, /* 7391 */ { MAD_F(0x0464c34a) /* 0.274600307 */, 19 }, /* 7392 */ { MAD_F(0x0464f73c) /* 0.274649846 */, 19 }, /* 7393 */ { MAD_F(0x04652b2f) /* 0.274699387 */, 19 }, /* 7394 */ { MAD_F(0x04655f22) /* 0.274748931 */, 19 }, /* 7395 */ { MAD_F(0x04659316) /* 0.274798476 */, 19 }, /* 7396 */ { MAD_F(0x0465c70a) /* 0.274848024 */, 19 }, /* 7397 */ { MAD_F(0x0465faff) /* 0.274897574 */, 19 }, /* 7398 */ { MAD_F(0x04662ef5) /* 0.274947126 */, 19 }, /* 7399 */ { MAD_F(0x046662eb) /* 0.274996681 */, 19 }, /* 7400 */ { MAD_F(0x046696e2) /* 0.275046238 */, 19 }, /* 7401 */ { MAD_F(0x0466cad9) /* 0.275095797 */, 19 }, /* 7402 */ { MAD_F(0x0466fed1) /* 0.275145358 */, 19 }, /* 7403 */ { MAD_F(0x046732ca) /* 0.275194921 */, 19 }, /* 7404 */ { MAD_F(0x046766c3) /* 0.275244487 */, 19 }, /* 7405 */ { MAD_F(0x04679abd) /* 0.275294055 */, 19 }, /* 7406 */ { MAD_F(0x0467ceb7) /* 0.275343625 */, 19 }, /* 7407 */ { MAD_F(0x046802b2) /* 0.275393198 */, 19 }, /* 7408 */ { MAD_F(0x046836ae) /* 0.275442772 */, 19 }, /* 7409 */ { MAD_F(0x04686aaa) /* 0.275492349 */, 19 }, /* 7410 */ { MAD_F(0x04689ea7) /* 0.275541928 */, 19 }, /* 7411 */ { MAD_F(0x0468d2a4) /* 0.275591509 */, 19 }, /* 7412 */ { MAD_F(0x046906a2) /* 0.275641093 */, 19 }, /* 7413 */ { MAD_F(0x04693aa1) /* 0.275690679 */, 19 }, /* 7414 */ { MAD_F(0x04696ea0) /* 0.275740267 */, 19 }, /* 7415 */ { MAD_F(0x0469a2a0) /* 0.275789857 */, 19 }, /* 7416 */ { MAD_F(0x0469d6a0) /* 0.275839449 */, 19 }, /* 7417 */ { MAD_F(0x046a0aa1) /* 0.275889044 */, 19 }, /* 7418 */ { MAD_F(0x046a3ea3) /* 0.275938641 */, 19 }, /* 7419 */ { MAD_F(0x046a72a5) /* 0.275988240 */, 19 }, /* 7420 */ { MAD_F(0x046aa6a8) /* 0.276037842 */, 19 }, /* 7421 */ { MAD_F(0x046adaab) /* 0.276087445 */, 19 }, /* 7422 */ { MAD_F(0x046b0eaf) /* 0.276137051 */, 19 }, /* 7423 */ { MAD_F(0x046b42b3) /* 0.276186659 */, 19 }, /* 7424 */ { MAD_F(0x046b76b9) /* 0.276236269 */, 19 }, /* 7425 */ { MAD_F(0x046baabe) /* 0.276285882 */, 19 }, /* 7426 */ { MAD_F(0x046bdec5) /* 0.276335497 */, 19 }, /* 7427 */ { MAD_F(0x046c12cc) /* 0.276385113 */, 19 }, /* 7428 */ { MAD_F(0x046c46d3) /* 0.276434733 */, 19 }, /* 7429 */ { MAD_F(0x046c7adb) /* 0.276484354 */, 19 }, /* 7430 */ { MAD_F(0x046caee4) /* 0.276533978 */, 19 }, /* 7431 */ { MAD_F(0x046ce2ee) /* 0.276583604 */, 19 }, /* 7432 */ { MAD_F(0x046d16f7) /* 0.276633232 */, 19 }, /* 7433 */ { MAD_F(0x046d4b02) /* 0.276682862 */, 19 }, /* 7434 */ { MAD_F(0x046d7f0d) /* 0.276732495 */, 19 }, /* 7435 */ { MAD_F(0x046db319) /* 0.276782129 */, 19 }, /* 7436 */ { MAD_F(0x046de725) /* 0.276831766 */, 19 }, /* 7437 */ { MAD_F(0x046e1b32) /* 0.276881406 */, 19 }, /* 7438 */ { MAD_F(0x046e4f40) /* 0.276931047 */, 19 }, /* 7439 */ { MAD_F(0x046e834e) /* 0.276980691 */, 19 }, /* 7440 */ { MAD_F(0x046eb75c) /* 0.277030337 */, 19 }, /* 7441 */ { MAD_F(0x046eeb6c) /* 0.277079985 */, 19 }, /* 7442 */ { MAD_F(0x046f1f7c) /* 0.277129635 */, 19 }, /* 7443 */ { MAD_F(0x046f538c) /* 0.277179288 */, 19 }, /* 7444 */ { MAD_F(0x046f879d) /* 0.277228942 */, 19 }, /* 7445 */ { MAD_F(0x046fbbaf) /* 0.277278600 */, 19 }, /* 7446 */ { MAD_F(0x046fefc1) /* 0.277328259 */, 19 }, /* 7447 */ { MAD_F(0x047023d4) /* 0.277377920 */, 19 }, /* 7448 */ { MAD_F(0x047057e8) /* 0.277427584 */, 19 }, /* 7449 */ { MAD_F(0x04708bfc) /* 0.277477250 */, 19 }, /* 7450 */ { MAD_F(0x0470c011) /* 0.277526918 */, 19 }, /* 7451 */ { MAD_F(0x0470f426) /* 0.277576588 */, 19 }, /* 7452 */ { MAD_F(0x0471283c) /* 0.277626261 */, 19 }, /* 7453 */ { MAD_F(0x04715c52) /* 0.277675936 */, 19 }, /* 7454 */ { MAD_F(0x04719069) /* 0.277725613 */, 19 }, /* 7455 */ { MAD_F(0x0471c481) /* 0.277775292 */, 19 }, /* 7456 */ { MAD_F(0x0471f899) /* 0.277824973 */, 19 }, /* 7457 */ { MAD_F(0x04722cb2) /* 0.277874657 */, 19 }, /* 7458 */ { MAD_F(0x047260cc) /* 0.277924343 */, 19 }, /* 7459 */ { MAD_F(0x047294e6) /* 0.277974031 */, 19 }, /* 7460 */ { MAD_F(0x0472c900) /* 0.278023722 */, 19 }, /* 7461 */ { MAD_F(0x0472fd1b) /* 0.278073414 */, 19 }, /* 7462 */ { MAD_F(0x04733137) /* 0.278123109 */, 19 }, /* 7463 */ { MAD_F(0x04736554) /* 0.278172806 */, 19 }, /* 7464 */ { MAD_F(0x04739971) /* 0.278222505 */, 19 }, /* 7465 */ { MAD_F(0x0473cd8e) /* 0.278272207 */, 19 }, /* 7466 */ { MAD_F(0x047401ad) /* 0.278321910 */, 19 }, /* 7467 */ { MAD_F(0x047435cb) /* 0.278371616 */, 19 }, /* 7468 */ { MAD_F(0x047469eb) /* 0.278421324 */, 19 }, /* 7469 */ { MAD_F(0x04749e0b) /* 0.278471035 */, 19 }, /* 7470 */ { MAD_F(0x0474d22c) /* 0.278520747 */, 19 }, /* 7471 */ { MAD_F(0x0475064d) /* 0.278570462 */, 19 }, /* 7472 */ { MAD_F(0x04753a6f) /* 0.278620179 */, 19 }, /* 7473 */ { MAD_F(0x04756e91) /* 0.278669898 */, 19 }, /* 7474 */ { MAD_F(0x0475a2b4) /* 0.278719619 */, 19 }, /* 7475 */ { MAD_F(0x0475d6d7) /* 0.278769343 */, 19 }, /* 7476 */ { MAD_F(0x04760afc) /* 0.278819069 */, 19 }, /* 7477 */ { MAD_F(0x04763f20) /* 0.278868797 */, 19 }, /* 7478 */ { MAD_F(0x04767346) /* 0.278918527 */, 19 }, /* 7479 */ { MAD_F(0x0476a76c) /* 0.278968260 */, 19 }, /* 7480 */ { MAD_F(0x0476db92) /* 0.279017995 */, 19 }, /* 7481 */ { MAD_F(0x04770fba) /* 0.279067731 */, 19 }, /* 7482 */ { MAD_F(0x047743e1) /* 0.279117471 */, 19 }, /* 7483 */ { MAD_F(0x0477780a) /* 0.279167212 */, 19 }, /* 7484 */ { MAD_F(0x0477ac33) /* 0.279216956 */, 19 }, /* 7485 */ { MAD_F(0x0477e05c) /* 0.279266701 */, 19 }, /* 7486 */ { MAD_F(0x04781486) /* 0.279316449 */, 19 }, /* 7487 */ { MAD_F(0x047848b1) /* 0.279366200 */, 19 }, /* 7488 */ { MAD_F(0x04787cdc) /* 0.279415952 */, 19 }, /* 7489 */ { MAD_F(0x0478b108) /* 0.279465707 */, 19 }, /* 7490 */ { MAD_F(0x0478e535) /* 0.279515464 */, 19 }, /* 7491 */ { MAD_F(0x04791962) /* 0.279565223 */, 19 }, /* 7492 */ { MAD_F(0x04794d8f) /* 0.279614984 */, 19 }, /* 7493 */ { MAD_F(0x047981be) /* 0.279664748 */, 19 }, /* 7494 */ { MAD_F(0x0479b5ed) /* 0.279714513 */, 19 }, /* 7495 */ { MAD_F(0x0479ea1c) /* 0.279764281 */, 19 }, /* 7496 */ { MAD_F(0x047a1e4c) /* 0.279814051 */, 19 }, /* 7497 */ { MAD_F(0x047a527d) /* 0.279863824 */, 19 }, /* 7498 */ { MAD_F(0x047a86ae) /* 0.279913598 */, 19 }, /* 7499 */ { MAD_F(0x047abae0) /* 0.279963375 */, 19 }, /* 7500 */ { MAD_F(0x047aef12) /* 0.280013154 */, 19 }, /* 7501 */ { MAD_F(0x047b2346) /* 0.280062935 */, 19 }, /* 7502 */ { MAD_F(0x047b5779) /* 0.280112719 */, 19 }, /* 7503 */ { MAD_F(0x047b8bad) /* 0.280162504 */, 19 }, /* 7504 */ { MAD_F(0x047bbfe2) /* 0.280212292 */, 19 }, /* 7505 */ { MAD_F(0x047bf418) /* 0.280262082 */, 19 }, /* 7506 */ { MAD_F(0x047c284e) /* 0.280311875 */, 19 }, /* 7507 */ { MAD_F(0x047c5c84) /* 0.280361669 */, 19 }, /* 7508 */ { MAD_F(0x047c90bb) /* 0.280411466 */, 19 }, /* 7509 */ { MAD_F(0x047cc4f3) /* 0.280461265 */, 19 }, /* 7510 */ { MAD_F(0x047cf92c) /* 0.280511066 */, 19 }, /* 7511 */ { MAD_F(0x047d2d65) /* 0.280560869 */, 19 }, /* 7512 */ { MAD_F(0x047d619e) /* 0.280610675 */, 19 }, /* 7513 */ { MAD_F(0x047d95d8) /* 0.280660483 */, 19 }, /* 7514 */ { MAD_F(0x047dca13) /* 0.280710292 */, 19 }, /* 7515 */ { MAD_F(0x047dfe4e) /* 0.280760105 */, 19 }, /* 7516 */ { MAD_F(0x047e328a) /* 0.280809919 */, 19 }, /* 7517 */ { MAD_F(0x047e66c7) /* 0.280859736 */, 19 }, /* 7518 */ { MAD_F(0x047e9b04) /* 0.280909554 */, 19 }, /* 7519 */ { MAD_F(0x047ecf42) /* 0.280959375 */, 19 }, /* 7520 */ { MAD_F(0x047f0380) /* 0.281009199 */, 19 }, /* 7521 */ { MAD_F(0x047f37bf) /* 0.281059024 */, 19 }, /* 7522 */ { MAD_F(0x047f6bff) /* 0.281108852 */, 19 }, /* 7523 */ { MAD_F(0x047fa03f) /* 0.281158682 */, 19 }, /* 7524 */ { MAD_F(0x047fd47f) /* 0.281208514 */, 19 }, /* 7525 */ { MAD_F(0x048008c1) /* 0.281258348 */, 19 }, /* 7526 */ { MAD_F(0x04803d02) /* 0.281308184 */, 19 }, /* 7527 */ { MAD_F(0x04807145) /* 0.281358023 */, 19 }, /* 7528 */ { MAD_F(0x0480a588) /* 0.281407864 */, 19 }, /* 7529 */ { MAD_F(0x0480d9cc) /* 0.281457707 */, 19 }, /* 7530 */ { MAD_F(0x04810e10) /* 0.281507552 */, 19 }, /* 7531 */ { MAD_F(0x04814255) /* 0.281557400 */, 19 }, /* 7532 */ { MAD_F(0x0481769a) /* 0.281607250 */, 19 }, /* 7533 */ { MAD_F(0x0481aae0) /* 0.281657101 */, 19 }, /* 7534 */ { MAD_F(0x0481df27) /* 0.281706956 */, 19 }, /* 7535 */ { MAD_F(0x0482136e) /* 0.281756812 */, 19 }, /* 7536 */ { MAD_F(0x048247b6) /* 0.281806670 */, 19 }, /* 7537 */ { MAD_F(0x04827bfe) /* 0.281856531 */, 19 }, /* 7538 */ { MAD_F(0x0482b047) /* 0.281906394 */, 19 }, /* 7539 */ { MAD_F(0x0482e491) /* 0.281956259 */, 19 }, /* 7540 */ { MAD_F(0x048318db) /* 0.282006127 */, 19 }, /* 7541 */ { MAD_F(0x04834d26) /* 0.282055996 */, 19 }, /* 7542 */ { MAD_F(0x04838171) /* 0.282105868 */, 19 }, /* 7543 */ { MAD_F(0x0483b5bd) /* 0.282155742 */, 19 }, /* 7544 */ { MAD_F(0x0483ea0a) /* 0.282205618 */, 19 }, /* 7545 */ { MAD_F(0x04841e57) /* 0.282255496 */, 19 }, /* 7546 */ { MAD_F(0x048452a4) /* 0.282305377 */, 19 }, /* 7547 */ { MAD_F(0x048486f3) /* 0.282355260 */, 19 }, /* 7548 */ { MAD_F(0x0484bb42) /* 0.282405145 */, 19 }, /* 7549 */ { MAD_F(0x0484ef91) /* 0.282455032 */, 19 }, /* 7550 */ { MAD_F(0x048523e1) /* 0.282504921 */, 19 }, /* 7551 */ { MAD_F(0x04855832) /* 0.282554813 */, 19 }, /* 7552 */ { MAD_F(0x04858c83) /* 0.282604707 */, 19 }, /* 7553 */ { MAD_F(0x0485c0d5) /* 0.282654603 */, 19 }, /* 7554 */ { MAD_F(0x0485f527) /* 0.282704501 */, 19 }, /* 7555 */ { MAD_F(0x0486297a) /* 0.282754401 */, 19 }, /* 7556 */ { MAD_F(0x04865dce) /* 0.282804304 */, 19 }, /* 7557 */ { MAD_F(0x04869222) /* 0.282854209 */, 19 }, /* 7558 */ { MAD_F(0x0486c677) /* 0.282904116 */, 19 }, /* 7559 */ { MAD_F(0x0486facc) /* 0.282954025 */, 19 }, /* 7560 */ { MAD_F(0x04872f22) /* 0.283003936 */, 19 }, /* 7561 */ { MAD_F(0x04876379) /* 0.283053850 */, 19 }, /* 7562 */ { MAD_F(0x048797d0) /* 0.283103766 */, 19 }, /* 7563 */ { MAD_F(0x0487cc28) /* 0.283153684 */, 19 }, /* 7564 */ { MAD_F(0x04880080) /* 0.283203604 */, 19 }, /* 7565 */ { MAD_F(0x048834d9) /* 0.283253527 */, 19 }, /* 7566 */ { MAD_F(0x04886933) /* 0.283303451 */, 19 }, /* 7567 */ { MAD_F(0x04889d8d) /* 0.283353378 */, 19 }, /* 7568 */ { MAD_F(0x0488d1e8) /* 0.283403307 */, 19 }, /* 7569 */ { MAD_F(0x04890643) /* 0.283453238 */, 19 }, /* 7570 */ { MAD_F(0x04893a9f) /* 0.283503172 */, 19 }, /* 7571 */ { MAD_F(0x04896efb) /* 0.283553107 */, 19 }, /* 7572 */ { MAD_F(0x0489a358) /* 0.283603045 */, 19 }, /* 7573 */ { MAD_F(0x0489d7b6) /* 0.283652985 */, 19 }, /* 7574 */ { MAD_F(0x048a0c14) /* 0.283702927 */, 19 }, /* 7575 */ { MAD_F(0x048a4073) /* 0.283752872 */, 19 }, /* 7576 */ { MAD_F(0x048a74d3) /* 0.283802818 */, 19 }, /* 7577 */ { MAD_F(0x048aa933) /* 0.283852767 */, 19 }, /* 7578 */ { MAD_F(0x048add93) /* 0.283902718 */, 19 }, /* 7579 */ { MAD_F(0x048b11f5) /* 0.283952671 */, 19 }, /* 7580 */ { MAD_F(0x048b4656) /* 0.284002627 */, 19 }, /* 7581 */ { MAD_F(0x048b7ab9) /* 0.284052584 */, 19 }, /* 7582 */ { MAD_F(0x048baf1c) /* 0.284102544 */, 19 }, /* 7583 */ { MAD_F(0x048be37f) /* 0.284152506 */, 19 }, /* 7584 */ { MAD_F(0x048c17e3) /* 0.284202470 */, 19 }, /* 7585 */ { MAD_F(0x048c4c48) /* 0.284252436 */, 19 }, /* 7586 */ { MAD_F(0x048c80ad) /* 0.284302405 */, 19 }, /* 7587 */ { MAD_F(0x048cb513) /* 0.284352376 */, 19 }, /* 7588 */ { MAD_F(0x048ce97a) /* 0.284402349 */, 19 }, /* 7589 */ { MAD_F(0x048d1de1) /* 0.284452324 */, 19 }, /* 7590 */ { MAD_F(0x048d5249) /* 0.284502301 */, 19 }, /* 7591 */ { MAD_F(0x048d86b1) /* 0.284552281 */, 19 }, /* 7592 */ { MAD_F(0x048dbb1a) /* 0.284602263 */, 19 }, /* 7593 */ { MAD_F(0x048def83) /* 0.284652246 */, 19 }, /* 7594 */ { MAD_F(0x048e23ed) /* 0.284702233 */, 19 }, /* 7595 */ { MAD_F(0x048e5858) /* 0.284752221 */, 19 }, /* 7596 */ { MAD_F(0x048e8cc3) /* 0.284802211 */, 19 }, /* 7597 */ { MAD_F(0x048ec12f) /* 0.284852204 */, 19 }, /* 7598 */ { MAD_F(0x048ef59b) /* 0.284902199 */, 19 }, /* 7599 */ { MAD_F(0x048f2a08) /* 0.284952196 */, 19 }, /* 7600 */ { MAD_F(0x048f5e76) /* 0.285002195 */, 19 }, /* 7601 */ { MAD_F(0x048f92e4) /* 0.285052197 */, 19 }, /* 7602 */ { MAD_F(0x048fc753) /* 0.285102201 */, 19 }, /* 7603 */ { MAD_F(0x048ffbc2) /* 0.285152206 */, 19 }, /* 7604 */ { MAD_F(0x04903032) /* 0.285202214 */, 19 }, /* 7605 */ { MAD_F(0x049064a3) /* 0.285252225 */, 19 }, /* 7606 */ { MAD_F(0x04909914) /* 0.285302237 */, 19 }, /* 7607 */ { MAD_F(0x0490cd86) /* 0.285352252 */, 19 }, /* 7608 */ { MAD_F(0x049101f8) /* 0.285402269 */, 19 }, /* 7609 */ { MAD_F(0x0491366b) /* 0.285452288 */, 19 }, /* 7610 */ { MAD_F(0x04916ade) /* 0.285502309 */, 19 }, /* 7611 */ { MAD_F(0x04919f52) /* 0.285552332 */, 19 }, /* 7612 */ { MAD_F(0x0491d3c7) /* 0.285602358 */, 19 }, /* 7613 */ { MAD_F(0x0492083c) /* 0.285652386 */, 19 }, /* 7614 */ { MAD_F(0x04923cb2) /* 0.285702416 */, 19 }, /* 7615 */ { MAD_F(0x04927128) /* 0.285752448 */, 19 }, /* 7616 */ { MAD_F(0x0492a59f) /* 0.285802482 */, 19 }, /* 7617 */ { MAD_F(0x0492da17) /* 0.285852519 */, 19 }, /* 7618 */ { MAD_F(0x04930e8f) /* 0.285902557 */, 19 }, /* 7619 */ { MAD_F(0x04934308) /* 0.285952598 */, 19 }, /* 7620 */ { MAD_F(0x04937781) /* 0.286002641 */, 19 }, /* 7621 */ { MAD_F(0x0493abfb) /* 0.286052687 */, 19 }, /* 7622 */ { MAD_F(0x0493e076) /* 0.286102734 */, 19 }, /* 7623 */ { MAD_F(0x049414f1) /* 0.286152784 */, 19 }, /* 7624 */ { MAD_F(0x0494496c) /* 0.286202836 */, 19 }, /* 7625 */ { MAD_F(0x04947de9) /* 0.286252890 */, 19 }, /* 7626 */ { MAD_F(0x0494b266) /* 0.286302946 */, 19 }, /* 7627 */ { MAD_F(0x0494e6e3) /* 0.286353005 */, 19 }, /* 7628 */ { MAD_F(0x04951b61) /* 0.286403065 */, 19 }, /* 7629 */ { MAD_F(0x04954fe0) /* 0.286453128 */, 19 }, /* 7630 */ { MAD_F(0x0495845f) /* 0.286503193 */, 19 }, /* 7631 */ { MAD_F(0x0495b8df) /* 0.286553260 */, 19 }, /* 7632 */ { MAD_F(0x0495ed5f) /* 0.286603329 */, 19 }, /* 7633 */ { MAD_F(0x049621e0) /* 0.286653401 */, 19 }, /* 7634 */ { MAD_F(0x04965662) /* 0.286703475 */, 19 }, /* 7635 */ { MAD_F(0x04968ae4) /* 0.286753551 */, 19 }, /* 7636 */ { MAD_F(0x0496bf67) /* 0.286803629 */, 19 }, /* 7637 */ { MAD_F(0x0496f3ea) /* 0.286853709 */, 19 }, /* 7638 */ { MAD_F(0x0497286e) /* 0.286903792 */, 19 }, /* 7639 */ { MAD_F(0x04975cf2) /* 0.286953876 */, 19 }, /* 7640 */ { MAD_F(0x04979177) /* 0.287003963 */, 19 }, /* 7641 */ { MAD_F(0x0497c5fd) /* 0.287054052 */, 19 }, /* 7642 */ { MAD_F(0x0497fa83) /* 0.287104143 */, 19 }, /* 7643 */ { MAD_F(0x04982f0a) /* 0.287154237 */, 19 }, /* 7644 */ { MAD_F(0x04986392) /* 0.287204332 */, 19 }, /* 7645 */ { MAD_F(0x0498981a) /* 0.287254430 */, 19 }, /* 7646 */ { MAD_F(0x0498cca2) /* 0.287304530 */, 19 }, /* 7647 */ { MAD_F(0x0499012c) /* 0.287354632 */, 19 }, /* 7648 */ { MAD_F(0x049935b5) /* 0.287404737 */, 19 }, /* 7649 */ { MAD_F(0x04996a40) /* 0.287454843 */, 19 }, /* 7650 */ { MAD_F(0x04999ecb) /* 0.287504952 */, 19 }, /* 7651 */ { MAD_F(0x0499d356) /* 0.287555063 */, 19 }, /* 7652 */ { MAD_F(0x049a07e2) /* 0.287605176 */, 19 }, /* 7653 */ { MAD_F(0x049a3c6f) /* 0.287655291 */, 19 }, /* 7654 */ { MAD_F(0x049a70fc) /* 0.287705409 */, 19 }, /* 7655 */ { MAD_F(0x049aa58a) /* 0.287755528 */, 19 }, /* 7656 */ { MAD_F(0x049ada19) /* 0.287805650 */, 19 }, /* 7657 */ { MAD_F(0x049b0ea8) /* 0.287855774 */, 19 }, /* 7658 */ { MAD_F(0x049b4337) /* 0.287905900 */, 19 }, /* 7659 */ { MAD_F(0x049b77c8) /* 0.287956028 */, 19 }, /* 7660 */ { MAD_F(0x049bac58) /* 0.288006159 */, 19 }, /* 7661 */ { MAD_F(0x049be0ea) /* 0.288056292 */, 19 }, /* 7662 */ { MAD_F(0x049c157c) /* 0.288106427 */, 19 }, /* 7663 */ { MAD_F(0x049c4a0e) /* 0.288156564 */, 19 }, /* 7664 */ { MAD_F(0x049c7ea1) /* 0.288206703 */, 19 }, /* 7665 */ { MAD_F(0x049cb335) /* 0.288256844 */, 19 }, /* 7666 */ { MAD_F(0x049ce7ca) /* 0.288306988 */, 19 }, /* 7667 */ { MAD_F(0x049d1c5e) /* 0.288357134 */, 19 }, /* 7668 */ { MAD_F(0x049d50f4) /* 0.288407282 */, 19 }, /* 7669 */ { MAD_F(0x049d858a) /* 0.288457432 */, 19 }, /* 7670 */ { MAD_F(0x049dba21) /* 0.288507584 */, 19 }, /* 7671 */ { MAD_F(0x049deeb8) /* 0.288557739 */, 19 }, /* 7672 */ { MAD_F(0x049e2350) /* 0.288607895 */, 19 }, /* 7673 */ { MAD_F(0x049e57e8) /* 0.288658054 */, 19 }, /* 7674 */ { MAD_F(0x049e8c81) /* 0.288708215 */, 19 }, /* 7675 */ { MAD_F(0x049ec11b) /* 0.288758379 */, 19 }, /* 7676 */ { MAD_F(0x049ef5b5) /* 0.288808544 */, 19 }, /* 7677 */ { MAD_F(0x049f2a50) /* 0.288858712 */, 19 }, /* 7678 */ { MAD_F(0x049f5eeb) /* 0.288908881 */, 19 }, /* 7679 */ { MAD_F(0x049f9387) /* 0.288959053 */, 19 }, /* 7680 */ { MAD_F(0x049fc824) /* 0.289009227 */, 19 }, /* 7681 */ { MAD_F(0x049ffcc1) /* 0.289059404 */, 19 }, /* 7682 */ { MAD_F(0x04a0315e) /* 0.289109582 */, 19 }, /* 7683 */ { MAD_F(0x04a065fd) /* 0.289159763 */, 19 }, /* 7684 */ { MAD_F(0x04a09a9b) /* 0.289209946 */, 19 }, /* 7685 */ { MAD_F(0x04a0cf3b) /* 0.289260131 */, 19 }, /* 7686 */ { MAD_F(0x04a103db) /* 0.289310318 */, 19 }, /* 7687 */ { MAD_F(0x04a1387b) /* 0.289360507 */, 19 }, /* 7688 */ { MAD_F(0x04a16d1d) /* 0.289410699 */, 19 }, /* 7689 */ { MAD_F(0x04a1a1be) /* 0.289460893 */, 19 }, /* 7690 */ { MAD_F(0x04a1d661) /* 0.289511088 */, 19 }, /* 7691 */ { MAD_F(0x04a20b04) /* 0.289561287 */, 19 }, /* 7692 */ { MAD_F(0x04a23fa7) /* 0.289611487 */, 19 }, /* 7693 */ { MAD_F(0x04a2744b) /* 0.289661689 */, 19 }, /* 7694 */ { MAD_F(0x04a2a8f0) /* 0.289711894 */, 19 }, /* 7695 */ { MAD_F(0x04a2dd95) /* 0.289762101 */, 19 }, /* 7696 */ { MAD_F(0x04a3123b) /* 0.289812309 */, 19 }, /* 7697 */ { MAD_F(0x04a346e2) /* 0.289862521 */, 19 }, /* 7698 */ { MAD_F(0x04a37b89) /* 0.289912734 */, 19 }, /* 7699 */ { MAD_F(0x04a3b030) /* 0.289962949 */, 19 }, /* 7700 */ { MAD_F(0x04a3e4d8) /* 0.290013167 */, 19 }, /* 7701 */ { MAD_F(0x04a41981) /* 0.290063387 */, 19 }, /* 7702 */ { MAD_F(0x04a44e2b) /* 0.290113609 */, 19 }, /* 7703 */ { MAD_F(0x04a482d5) /* 0.290163833 */, 19 }, /* 7704 */ { MAD_F(0x04a4b77f) /* 0.290214059 */, 19 }, /* 7705 */ { MAD_F(0x04a4ec2a) /* 0.290264288 */, 19 }, /* 7706 */ { MAD_F(0x04a520d6) /* 0.290314519 */, 19 }, /* 7707 */ { MAD_F(0x04a55582) /* 0.290364751 */, 19 }, /* 7708 */ { MAD_F(0x04a58a2f) /* 0.290414986 */, 19 }, /* 7709 */ { MAD_F(0x04a5bedd) /* 0.290465224 */, 19 }, /* 7710 */ { MAD_F(0x04a5f38b) /* 0.290515463 */, 19 }, /* 7711 */ { MAD_F(0x04a62839) /* 0.290565705 */, 19 }, /* 7712 */ { MAD_F(0x04a65ce8) /* 0.290615948 */, 19 }, /* 7713 */ { MAD_F(0x04a69198) /* 0.290666194 */, 19 }, /* 7714 */ { MAD_F(0x04a6c648) /* 0.290716442 */, 19 }, /* 7715 */ { MAD_F(0x04a6faf9) /* 0.290766692 */, 19 }, /* 7716 */ { MAD_F(0x04a72fab) /* 0.290816945 */, 19 }, /* 7717 */ { MAD_F(0x04a7645d) /* 0.290867199 */, 19 }, /* 7718 */ { MAD_F(0x04a79910) /* 0.290917456 */, 19 }, /* 7719 */ { MAD_F(0x04a7cdc3) /* 0.290967715 */, 19 }, /* 7720 */ { MAD_F(0x04a80277) /* 0.291017976 */, 19 }, /* 7721 */ { MAD_F(0x04a8372b) /* 0.291068239 */, 19 }, /* 7722 */ { MAD_F(0x04a86be0) /* 0.291118505 */, 19 }, /* 7723 */ { MAD_F(0x04a8a096) /* 0.291168772 */, 19 }, /* 7724 */ { MAD_F(0x04a8d54c) /* 0.291219042 */, 19 }, /* 7725 */ { MAD_F(0x04a90a03) /* 0.291269314 */, 19 }, /* 7726 */ { MAD_F(0x04a93eba) /* 0.291319588 */, 19 }, /* 7727 */ { MAD_F(0x04a97372) /* 0.291369865 */, 19 }, /* 7728 */ { MAD_F(0x04a9a82b) /* 0.291420143 */, 19 }, /* 7729 */ { MAD_F(0x04a9dce4) /* 0.291470424 */, 19 }, /* 7730 */ { MAD_F(0x04aa119d) /* 0.291520706 */, 19 }, /* 7731 */ { MAD_F(0x04aa4658) /* 0.291570991 */, 19 }, /* 7732 */ { MAD_F(0x04aa7b13) /* 0.291621278 */, 19 }, /* 7733 */ { MAD_F(0x04aaafce) /* 0.291671568 */, 19 }, /* 7734 */ { MAD_F(0x04aae48a) /* 0.291721859 */, 19 }, /* 7735 */ { MAD_F(0x04ab1947) /* 0.291772153 */, 19 }, /* 7736 */ { MAD_F(0x04ab4e04) /* 0.291822449 */, 19 }, /* 7737 */ { MAD_F(0x04ab82c2) /* 0.291872747 */, 19 }, /* 7738 */ { MAD_F(0x04abb780) /* 0.291923047 */, 19 }, /* 7739 */ { MAD_F(0x04abec3f) /* 0.291973349 */, 19 }, /* 7740 */ { MAD_F(0x04ac20fe) /* 0.292023653 */, 19 }, /* 7741 */ { MAD_F(0x04ac55be) /* 0.292073960 */, 19 }, /* 7742 */ { MAD_F(0x04ac8a7f) /* 0.292124269 */, 19 }, /* 7743 */ { MAD_F(0x04acbf40) /* 0.292174580 */, 19 }, /* 7744 */ { MAD_F(0x04acf402) /* 0.292224893 */, 19 }, /* 7745 */ { MAD_F(0x04ad28c5) /* 0.292275208 */, 19 }, /* 7746 */ { MAD_F(0x04ad5d88) /* 0.292325526 */, 19 }, /* 7747 */ { MAD_F(0x04ad924b) /* 0.292375845 */, 19 }, /* 7748 */ { MAD_F(0x04adc70f) /* 0.292426167 */, 19 }, /* 7749 */ { MAD_F(0x04adfbd4) /* 0.292476491 */, 19 }, /* 7750 */ { MAD_F(0x04ae3099) /* 0.292526817 */, 19 }, /* 7751 */ { MAD_F(0x04ae655f) /* 0.292577145 */, 19 }, /* 7752 */ { MAD_F(0x04ae9a26) /* 0.292627476 */, 19 }, /* 7753 */ { MAD_F(0x04aeceed) /* 0.292677808 */, 19 }, /* 7754 */ { MAD_F(0x04af03b4) /* 0.292728143 */, 19 }, /* 7755 */ { MAD_F(0x04af387d) /* 0.292778480 */, 19 }, /* 7756 */ { MAD_F(0x04af6d45) /* 0.292828819 */, 19 }, /* 7757 */ { MAD_F(0x04afa20f) /* 0.292879160 */, 19 }, /* 7758 */ { MAD_F(0x04afd6d9) /* 0.292929504 */, 19 }, /* 7759 */ { MAD_F(0x04b00ba3) /* 0.292979849 */, 19 }, /* 7760 */ { MAD_F(0x04b0406e) /* 0.293030197 */, 19 }, /* 7761 */ { MAD_F(0x04b0753a) /* 0.293080547 */, 19 }, /* 7762 */ { MAD_F(0x04b0aa06) /* 0.293130899 */, 19 }, /* 7763 */ { MAD_F(0x04b0ded3) /* 0.293181253 */, 19 }, /* 7764 */ { MAD_F(0x04b113a1) /* 0.293231610 */, 19 }, /* 7765 */ { MAD_F(0x04b1486f) /* 0.293281968 */, 19 }, /* 7766 */ { MAD_F(0x04b17d3d) /* 0.293332329 */, 19 }, /* 7767 */ { MAD_F(0x04b1b20c) /* 0.293382692 */, 19 }, /* 7768 */ { MAD_F(0x04b1e6dc) /* 0.293433057 */, 19 }, /* 7769 */ { MAD_F(0x04b21bad) /* 0.293483424 */, 19 }, /* 7770 */ { MAD_F(0x04b2507d) /* 0.293533794 */, 19 }, /* 7771 */ { MAD_F(0x04b2854f) /* 0.293584165 */, 19 }, /* 7772 */ { MAD_F(0x04b2ba21) /* 0.293634539 */, 19 }, /* 7773 */ { MAD_F(0x04b2eef4) /* 0.293684915 */, 19 }, /* 7774 */ { MAD_F(0x04b323c7) /* 0.293735293 */, 19 }, /* 7775 */ { MAD_F(0x04b3589b) /* 0.293785673 */, 19 }, /* 7776 */ { MAD_F(0x04b38d6f) /* 0.293836055 */, 19 }, /* 7777 */ { MAD_F(0x04b3c244) /* 0.293886440 */, 19 }, /* 7778 */ { MAD_F(0x04b3f71a) /* 0.293936826 */, 19 }, /* 7779 */ { MAD_F(0x04b42bf0) /* 0.293987215 */, 19 }, /* 7780 */ { MAD_F(0x04b460c7) /* 0.294037606 */, 19 }, /* 7781 */ { MAD_F(0x04b4959e) /* 0.294087999 */, 19 }, /* 7782 */ { MAD_F(0x04b4ca76) /* 0.294138395 */, 19 }, /* 7783 */ { MAD_F(0x04b4ff4e) /* 0.294188792 */, 19 }, /* 7784 */ { MAD_F(0x04b53427) /* 0.294239192 */, 19 }, /* 7785 */ { MAD_F(0x04b56901) /* 0.294289593 */, 19 }, /* 7786 */ { MAD_F(0x04b59ddb) /* 0.294339997 */, 19 }, /* 7787 */ { MAD_F(0x04b5d2b6) /* 0.294390403 */, 19 }, /* 7788 */ { MAD_F(0x04b60791) /* 0.294440812 */, 19 }, /* 7789 */ { MAD_F(0x04b63c6d) /* 0.294491222 */, 19 }, /* 7790 */ { MAD_F(0x04b6714a) /* 0.294541635 */, 19 }, /* 7791 */ { MAD_F(0x04b6a627) /* 0.294592049 */, 19 }, /* 7792 */ { MAD_F(0x04b6db05) /* 0.294642466 */, 19 }, /* 7793 */ { MAD_F(0x04b70fe3) /* 0.294692885 */, 19 }, /* 7794 */ { MAD_F(0x04b744c2) /* 0.294743306 */, 19 }, /* 7795 */ { MAD_F(0x04b779a1) /* 0.294793730 */, 19 }, /* 7796 */ { MAD_F(0x04b7ae81) /* 0.294844155 */, 19 }, /* 7797 */ { MAD_F(0x04b7e362) /* 0.294894583 */, 19 }, /* 7798 */ { MAD_F(0x04b81843) /* 0.294945013 */, 19 }, /* 7799 */ { MAD_F(0x04b84d24) /* 0.294995445 */, 19 }, /* 7800 */ { MAD_F(0x04b88207) /* 0.295045879 */, 19 }, /* 7801 */ { MAD_F(0x04b8b6ea) /* 0.295096315 */, 19 }, /* 7802 */ { MAD_F(0x04b8ebcd) /* 0.295146753 */, 19 }, /* 7803 */ { MAD_F(0x04b920b1) /* 0.295197194 */, 19 }, /* 7804 */ { MAD_F(0x04b95596) /* 0.295247637 */, 19 }, /* 7805 */ { MAD_F(0x04b98a7b) /* 0.295298082 */, 19 }, /* 7806 */ { MAD_F(0x04b9bf61) /* 0.295348529 */, 19 }, /* 7807 */ { MAD_F(0x04b9f447) /* 0.295398978 */, 19 }, /* 7808 */ { MAD_F(0x04ba292e) /* 0.295449429 */, 19 }, /* 7809 */ { MAD_F(0x04ba5e16) /* 0.295499883 */, 19 }, /* 7810 */ { MAD_F(0x04ba92fe) /* 0.295550338 */, 19 }, /* 7811 */ { MAD_F(0x04bac7e6) /* 0.295600796 */, 19 }, /* 7812 */ { MAD_F(0x04bafcd0) /* 0.295651256 */, 19 }, /* 7813 */ { MAD_F(0x04bb31b9) /* 0.295701718 */, 19 }, /* 7814 */ { MAD_F(0x04bb66a4) /* 0.295752183 */, 19 }, /* 7815 */ { MAD_F(0x04bb9b8f) /* 0.295802649 */, 19 }, /* 7816 */ { MAD_F(0x04bbd07a) /* 0.295853118 */, 19 }, /* 7817 */ { MAD_F(0x04bc0566) /* 0.295903588 */, 19 }, /* 7818 */ { MAD_F(0x04bc3a53) /* 0.295954061 */, 19 }, /* 7819 */ { MAD_F(0x04bc6f40) /* 0.296004536 */, 19 }, /* 7820 */ { MAD_F(0x04bca42e) /* 0.296055013 */, 19 }, /* 7821 */ { MAD_F(0x04bcd91d) /* 0.296105493 */, 19 }, /* 7822 */ { MAD_F(0x04bd0e0c) /* 0.296155974 */, 19 }, /* 7823 */ { MAD_F(0x04bd42fb) /* 0.296206458 */, 19 }, /* 7824 */ { MAD_F(0x04bd77ec) /* 0.296256944 */, 19 }, /* 7825 */ { MAD_F(0x04bdacdc) /* 0.296307432 */, 19 }, /* 7826 */ { MAD_F(0x04bde1ce) /* 0.296357922 */, 19 }, /* 7827 */ { MAD_F(0x04be16c0) /* 0.296408414 */, 19 }, /* 7828 */ { MAD_F(0x04be4bb2) /* 0.296458908 */, 19 }, /* 7829 */ { MAD_F(0x04be80a5) /* 0.296509405 */, 19 }, /* 7830 */ { MAD_F(0x04beb599) /* 0.296559904 */, 19 }, /* 7831 */ { MAD_F(0x04beea8d) /* 0.296610404 */, 19 }, /* 7832 */ { MAD_F(0x04bf1f82) /* 0.296660907 */, 19 }, /* 7833 */ { MAD_F(0x04bf5477) /* 0.296711413 */, 19 }, /* 7834 */ { MAD_F(0x04bf896d) /* 0.296761920 */, 19 }, /* 7835 */ { MAD_F(0x04bfbe64) /* 0.296812429 */, 19 }, /* 7836 */ { MAD_F(0x04bff35b) /* 0.296862941 */, 19 }, /* 7837 */ { MAD_F(0x04c02852) /* 0.296913455 */, 19 }, /* 7838 */ { MAD_F(0x04c05d4b) /* 0.296963971 */, 19 }, /* 7839 */ { MAD_F(0x04c09243) /* 0.297014489 */, 19 }, /* 7840 */ { MAD_F(0x04c0c73d) /* 0.297065009 */, 19 }, /* 7841 */ { MAD_F(0x04c0fc37) /* 0.297115531 */, 19 }, /* 7842 */ { MAD_F(0x04c13131) /* 0.297166056 */, 19 }, /* 7843 */ { MAD_F(0x04c1662d) /* 0.297216582 */, 19 }, /* 7844 */ { MAD_F(0x04c19b28) /* 0.297267111 */, 19 }, /* 7845 */ { MAD_F(0x04c1d025) /* 0.297317642 */, 19 }, /* 7846 */ { MAD_F(0x04c20521) /* 0.297368175 */, 19 }, /* 7847 */ { MAD_F(0x04c23a1f) /* 0.297418710 */, 19 }, /* 7848 */ { MAD_F(0x04c26f1d) /* 0.297469248 */, 19 }, /* 7849 */ { MAD_F(0x04c2a41b) /* 0.297519787 */, 19 }, /* 7850 */ { MAD_F(0x04c2d91b) /* 0.297570329 */, 19 }, /* 7851 */ { MAD_F(0x04c30e1a) /* 0.297620873 */, 19 }, /* 7852 */ { MAD_F(0x04c3431b) /* 0.297671418 */, 19 }, /* 7853 */ { MAD_F(0x04c3781c) /* 0.297721967 */, 19 }, /* 7854 */ { MAD_F(0x04c3ad1d) /* 0.297772517 */, 19 }, /* 7855 */ { MAD_F(0x04c3e21f) /* 0.297823069 */, 19 }, /* 7856 */ { MAD_F(0x04c41722) /* 0.297873624 */, 19 }, /* 7857 */ { MAD_F(0x04c44c25) /* 0.297924180 */, 19 }, /* 7858 */ { MAD_F(0x04c48129) /* 0.297974739 */, 19 }, /* 7859 */ { MAD_F(0x04c4b62d) /* 0.298025300 */, 19 }, /* 7860 */ { MAD_F(0x04c4eb32) /* 0.298075863 */, 19 }, /* 7861 */ { MAD_F(0x04c52038) /* 0.298126429 */, 19 }, /* 7862 */ { MAD_F(0x04c5553e) /* 0.298176996 */, 19 }, /* 7863 */ { MAD_F(0x04c58a44) /* 0.298227565 */, 19 }, /* 7864 */ { MAD_F(0x04c5bf4c) /* 0.298278137 */, 19 }, /* 7865 */ { MAD_F(0x04c5f453) /* 0.298328711 */, 19 }, /* 7866 */ { MAD_F(0x04c6295c) /* 0.298379287 */, 19 }, /* 7867 */ { MAD_F(0x04c65e65) /* 0.298429865 */, 19 }, /* 7868 */ { MAD_F(0x04c6936e) /* 0.298480445 */, 19 }, /* 7869 */ { MAD_F(0x04c6c878) /* 0.298531028 */, 19 }, /* 7870 */ { MAD_F(0x04c6fd83) /* 0.298581612 */, 19 }, /* 7871 */ { MAD_F(0x04c7328e) /* 0.298632199 */, 19 }, /* 7872 */ { MAD_F(0x04c7679a) /* 0.298682788 */, 19 }, /* 7873 */ { MAD_F(0x04c79ca7) /* 0.298733379 */, 19 }, /* 7874 */ { MAD_F(0x04c7d1b4) /* 0.298783972 */, 19 }, /* 7875 */ { MAD_F(0x04c806c1) /* 0.298834567 */, 19 }, /* 7876 */ { MAD_F(0x04c83bcf) /* 0.298885165 */, 19 }, /* 7877 */ { MAD_F(0x04c870de) /* 0.298935764 */, 19 }, /* 7878 */ { MAD_F(0x04c8a5ed) /* 0.298986366 */, 19 }, /* 7879 */ { MAD_F(0x04c8dafd) /* 0.299036970 */, 19 }, /* 7880 */ { MAD_F(0x04c9100d) /* 0.299087576 */, 19 }, /* 7881 */ { MAD_F(0x04c9451e) /* 0.299138184 */, 19 }, /* 7882 */ { MAD_F(0x04c97a30) /* 0.299188794 */, 19 }, /* 7883 */ { MAD_F(0x04c9af42) /* 0.299239406 */, 19 }, /* 7884 */ { MAD_F(0x04c9e455) /* 0.299290021 */, 19 }, /* 7885 */ { MAD_F(0x04ca1968) /* 0.299340638 */, 19 }, /* 7886 */ { MAD_F(0x04ca4e7c) /* 0.299391256 */, 19 }, /* 7887 */ { MAD_F(0x04ca8391) /* 0.299441877 */, 19 }, /* 7888 */ { MAD_F(0x04cab8a6) /* 0.299492500 */, 19 }, /* 7889 */ { MAD_F(0x04caedbb) /* 0.299543126 */, 19 }, /* 7890 */ { MAD_F(0x04cb22d1) /* 0.299593753 */, 19 }, /* 7891 */ { MAD_F(0x04cb57e8) /* 0.299644382 */, 19 }, /* 7892 */ { MAD_F(0x04cb8d00) /* 0.299695014 */, 19 }, /* 7893 */ { MAD_F(0x04cbc217) /* 0.299745648 */, 19 }, /* 7894 */ { MAD_F(0x04cbf730) /* 0.299796284 */, 19 }, /* 7895 */ { MAD_F(0x04cc2c49) /* 0.299846922 */, 19 }, /* 7896 */ { MAD_F(0x04cc6163) /* 0.299897562 */, 19 }, /* 7897 */ { MAD_F(0x04cc967d) /* 0.299948204 */, 19 }, /* 7898 */ { MAD_F(0x04cccb98) /* 0.299998849 */, 19 }, /* 7899 */ { MAD_F(0x04cd00b3) /* 0.300049495 */, 19 }, /* 7900 */ { MAD_F(0x04cd35cf) /* 0.300100144 */, 19 }, /* 7901 */ { MAD_F(0x04cd6aeb) /* 0.300150795 */, 19 }, /* 7902 */ { MAD_F(0x04cda008) /* 0.300201448 */, 19 }, /* 7903 */ { MAD_F(0x04cdd526) /* 0.300252103 */, 19 }, /* 7904 */ { MAD_F(0x04ce0a44) /* 0.300302761 */, 19 }, /* 7905 */ { MAD_F(0x04ce3f63) /* 0.300353420 */, 19 }, /* 7906 */ { MAD_F(0x04ce7482) /* 0.300404082 */, 19 }, /* 7907 */ { MAD_F(0x04cea9a2) /* 0.300454745 */, 19 }, /* 7908 */ { MAD_F(0x04cedec3) /* 0.300505411 */, 19 }, /* 7909 */ { MAD_F(0x04cf13e4) /* 0.300556079 */, 19 }, /* 7910 */ { MAD_F(0x04cf4906) /* 0.300606749 */, 19 }, /* 7911 */ { MAD_F(0x04cf7e28) /* 0.300657421 */, 19 }, /* 7912 */ { MAD_F(0x04cfb34b) /* 0.300708096 */, 19 }, /* 7913 */ { MAD_F(0x04cfe86e) /* 0.300758772 */, 19 }, /* 7914 */ { MAD_F(0x04d01d92) /* 0.300809451 */, 19 }, /* 7915 */ { MAD_F(0x04d052b6) /* 0.300860132 */, 19 }, /* 7916 */ { MAD_F(0x04d087db) /* 0.300910815 */, 19 }, /* 7917 */ { MAD_F(0x04d0bd01) /* 0.300961500 */, 19 }, /* 7918 */ { MAD_F(0x04d0f227) /* 0.301012187 */, 19 }, /* 7919 */ { MAD_F(0x04d1274e) /* 0.301062876 */, 19 }, /* 7920 */ { MAD_F(0x04d15c76) /* 0.301113568 */, 19 }, /* 7921 */ { MAD_F(0x04d1919e) /* 0.301164261 */, 19 }, /* 7922 */ { MAD_F(0x04d1c6c6) /* 0.301214957 */, 19 }, /* 7923 */ { MAD_F(0x04d1fbef) /* 0.301265655 */, 19 }, /* 7924 */ { MAD_F(0x04d23119) /* 0.301316355 */, 19 }, /* 7925 */ { MAD_F(0x04d26643) /* 0.301367057 */, 19 }, /* 7926 */ { MAD_F(0x04d29b6e) /* 0.301417761 */, 19 }, /* 7927 */ { MAD_F(0x04d2d099) /* 0.301468468 */, 19 }, /* 7928 */ { MAD_F(0x04d305c5) /* 0.301519176 */, 19 }, /* 7929 */ { MAD_F(0x04d33af2) /* 0.301569887 */, 19 }, /* 7930 */ { MAD_F(0x04d3701f) /* 0.301620599 */, 19 }, /* 7931 */ { MAD_F(0x04d3a54d) /* 0.301671314 */, 19 }, /* 7932 */ { MAD_F(0x04d3da7b) /* 0.301722031 */, 19 }, /* 7933 */ { MAD_F(0x04d40faa) /* 0.301772751 */, 19 }, /* 7934 */ { MAD_F(0x04d444d9) /* 0.301823472 */, 19 }, /* 7935 */ { MAD_F(0x04d47a09) /* 0.301874195 */, 19 }, /* 7936 */ { MAD_F(0x04d4af3a) /* 0.301924921 */, 19 }, /* 7937 */ { MAD_F(0x04d4e46b) /* 0.301975649 */, 19 }, /* 7938 */ { MAD_F(0x04d5199c) /* 0.302026378 */, 19 }, /* 7939 */ { MAD_F(0x04d54ecf) /* 0.302077110 */, 19 }, /* 7940 */ { MAD_F(0x04d58401) /* 0.302127845 */, 19 }, /* 7941 */ { MAD_F(0x04d5b935) /* 0.302178581 */, 19 }, /* 7942 */ { MAD_F(0x04d5ee69) /* 0.302229319 */, 19 }, /* 7943 */ { MAD_F(0x04d6239d) /* 0.302280060 */, 19 }, /* 7944 */ { MAD_F(0x04d658d2) /* 0.302330802 */, 19 }, /* 7945 */ { MAD_F(0x04d68e08) /* 0.302381547 */, 19 }, /* 7946 */ { MAD_F(0x04d6c33e) /* 0.302432294 */, 19 }, /* 7947 */ { MAD_F(0x04d6f875) /* 0.302483043 */, 19 }, /* 7948 */ { MAD_F(0x04d72dad) /* 0.302533794 */, 19 }, /* 7949 */ { MAD_F(0x04d762e5) /* 0.302584547 */, 19 }, /* 7950 */ { MAD_F(0x04d7981d) /* 0.302635303 */, 19 }, /* 7951 */ { MAD_F(0x04d7cd56) /* 0.302686060 */, 19 }, /* 7952 */ { MAD_F(0x04d80290) /* 0.302736820 */, 19 }, /* 7953 */ { MAD_F(0x04d837ca) /* 0.302787581 */, 19 }, /* 7954 */ { MAD_F(0x04d86d05) /* 0.302838345 */, 19 }, /* 7955 */ { MAD_F(0x04d8a240) /* 0.302889111 */, 19 }, /* 7956 */ { MAD_F(0x04d8d77c) /* 0.302939879 */, 19 }, /* 7957 */ { MAD_F(0x04d90cb9) /* 0.302990650 */, 19 }, /* 7958 */ { MAD_F(0x04d941f6) /* 0.303041422 */, 19 }, /* 7959 */ { MAD_F(0x04d97734) /* 0.303092197 */, 19 }, /* 7960 */ { MAD_F(0x04d9ac72) /* 0.303142973 */, 19 }, /* 7961 */ { MAD_F(0x04d9e1b1) /* 0.303193752 */, 19 }, /* 7962 */ { MAD_F(0x04da16f0) /* 0.303244533 */, 19 }, /* 7963 */ { MAD_F(0x04da4c30) /* 0.303295316 */, 19 }, /* 7964 */ { MAD_F(0x04da8171) /* 0.303346101 */, 19 }, /* 7965 */ { MAD_F(0x04dab6b2) /* 0.303396889 */, 19 }, /* 7966 */ { MAD_F(0x04daebf4) /* 0.303447678 */, 19 }, /* 7967 */ { MAD_F(0x04db2136) /* 0.303498469 */, 19 }, /* 7968 */ { MAD_F(0x04db5679) /* 0.303549263 */, 19 }, /* 7969 */ { MAD_F(0x04db8bbc) /* 0.303600059 */, 19 }, /* 7970 */ { MAD_F(0x04dbc100) /* 0.303650857 */, 19 }, /* 7971 */ { MAD_F(0x04dbf644) /* 0.303701657 */, 19 }, /* 7972 */ { MAD_F(0x04dc2b8a) /* 0.303752459 */, 19 }, /* 7973 */ { MAD_F(0x04dc60cf) /* 0.303803263 */, 19 }, /* 7974 */ { MAD_F(0x04dc9616) /* 0.303854070 */, 19 }, /* 7975 */ { MAD_F(0x04dccb5c) /* 0.303904878 */, 19 }, /* 7976 */ { MAD_F(0x04dd00a4) /* 0.303955689 */, 19 }, /* 7977 */ { MAD_F(0x04dd35ec) /* 0.304006502 */, 19 }, /* 7978 */ { MAD_F(0x04dd6b34) /* 0.304057317 */, 19 }, /* 7979 */ { MAD_F(0x04dda07d) /* 0.304108134 */, 19 }, /* 7980 */ { MAD_F(0x04ddd5c7) /* 0.304158953 */, 19 }, /* 7981 */ { MAD_F(0x04de0b11) /* 0.304209774 */, 19 }, /* 7982 */ { MAD_F(0x04de405c) /* 0.304260597 */, 19 }, /* 7983 */ { MAD_F(0x04de75a7) /* 0.304311423 */, 19 }, /* 7984 */ { MAD_F(0x04deaaf3) /* 0.304362251 */, 19 }, /* 7985 */ { MAD_F(0x04dee040) /* 0.304413080 */, 19 }, /* 7986 */ { MAD_F(0x04df158d) /* 0.304463912 */, 19 }, /* 7987 */ { MAD_F(0x04df4adb) /* 0.304514746 */, 19 }, /* 7988 */ { MAD_F(0x04df8029) /* 0.304565582 */, 19 }, /* 7989 */ { MAD_F(0x04dfb578) /* 0.304616421 */, 19 }, /* 7990 */ { MAD_F(0x04dfeac7) /* 0.304667261 */, 19 }, /* 7991 */ { MAD_F(0x04e02017) /* 0.304718103 */, 19 }, /* 7992 */ { MAD_F(0x04e05567) /* 0.304768948 */, 19 }, /* 7993 */ { MAD_F(0x04e08ab8) /* 0.304819795 */, 19 }, /* 7994 */ { MAD_F(0x04e0c00a) /* 0.304870644 */, 19 }, /* 7995 */ { MAD_F(0x04e0f55c) /* 0.304921495 */, 19 }, /* 7996 */ { MAD_F(0x04e12aaf) /* 0.304972348 */, 19 }, /* 7997 */ { MAD_F(0x04e16002) /* 0.305023203 */, 19 }, /* 7998 */ { MAD_F(0x04e19556) /* 0.305074060 */, 19 }, /* 7999 */ { MAD_F(0x04e1caab) /* 0.305124920 */, 19 }, /* 8000 */ { MAD_F(0x04e20000) /* 0.305175781 */, 19 }, /* 8001 */ { MAD_F(0x04e23555) /* 0.305226645 */, 19 }, /* 8002 */ { MAD_F(0x04e26aac) /* 0.305277511 */, 19 }, /* 8003 */ { MAD_F(0x04e2a002) /* 0.305328379 */, 19 }, /* 8004 */ { MAD_F(0x04e2d55a) /* 0.305379249 */, 19 }, /* 8005 */ { MAD_F(0x04e30ab2) /* 0.305430121 */, 19 }, /* 8006 */ { MAD_F(0x04e3400a) /* 0.305480995 */, 19 }, /* 8007 */ { MAD_F(0x04e37563) /* 0.305531872 */, 19 }, /* 8008 */ { MAD_F(0x04e3aabd) /* 0.305582750 */, 19 }, /* 8009 */ { MAD_F(0x04e3e017) /* 0.305633631 */, 19 }, /* 8010 */ { MAD_F(0x04e41572) /* 0.305684513 */, 19 }, /* 8011 */ { MAD_F(0x04e44acd) /* 0.305735398 */, 19 }, /* 8012 */ { MAD_F(0x04e48029) /* 0.305786285 */, 19 }, /* 8013 */ { MAD_F(0x04e4b585) /* 0.305837174 */, 19 }, /* 8014 */ { MAD_F(0x04e4eae2) /* 0.305888066 */, 19 }, /* 8015 */ { MAD_F(0x04e52040) /* 0.305938959 */, 19 }, /* 8016 */ { MAD_F(0x04e5559e) /* 0.305989854 */, 19 }, /* 8017 */ { MAD_F(0x04e58afd) /* 0.306040752 */, 19 }, /* 8018 */ { MAD_F(0x04e5c05c) /* 0.306091652 */, 19 }, /* 8019 */ { MAD_F(0x04e5f5bc) /* 0.306142554 */, 19 }, /* 8020 */ { MAD_F(0x04e62b1c) /* 0.306193457 */, 19 }, /* 8021 */ { MAD_F(0x04e6607d) /* 0.306244364 */, 19 }, /* 8022 */ { MAD_F(0x04e695df) /* 0.306295272 */, 19 }, /* 8023 */ { MAD_F(0x04e6cb41) /* 0.306346182 */, 19 }, /* 8024 */ { MAD_F(0x04e700a3) /* 0.306397094 */, 19 }, /* 8025 */ { MAD_F(0x04e73607) /* 0.306448009 */, 19 }, /* 8026 */ { MAD_F(0x04e76b6b) /* 0.306498925 */, 19 }, /* 8027 */ { MAD_F(0x04e7a0cf) /* 0.306549844 */, 19 }, /* 8028 */ { MAD_F(0x04e7d634) /* 0.306600765 */, 19 }, /* 8029 */ { MAD_F(0x04e80b99) /* 0.306651688 */, 19 }, /* 8030 */ { MAD_F(0x04e84100) /* 0.306702613 */, 19 }, /* 8031 */ { MAD_F(0x04e87666) /* 0.306753540 */, 19 }, /* 8032 */ { MAD_F(0x04e8abcd) /* 0.306804470 */, 19 }, /* 8033 */ { MAD_F(0x04e8e135) /* 0.306855401 */, 19 }, /* 8034 */ { MAD_F(0x04e9169e) /* 0.306906334 */, 19 }, /* 8035 */ { MAD_F(0x04e94c07) /* 0.306957270 */, 19 }, /* 8036 */ { MAD_F(0x04e98170) /* 0.307008208 */, 19 }, /* 8037 */ { MAD_F(0x04e9b6da) /* 0.307059148 */, 19 }, /* 8038 */ { MAD_F(0x04e9ec45) /* 0.307110090 */, 19 }, /* 8039 */ { MAD_F(0x04ea21b0) /* 0.307161034 */, 19 }, /* 8040 */ { MAD_F(0x04ea571c) /* 0.307211980 */, 19 }, /* 8041 */ { MAD_F(0x04ea8c88) /* 0.307262928 */, 19 }, /* 8042 */ { MAD_F(0x04eac1f5) /* 0.307313879 */, 19 }, /* 8043 */ { MAD_F(0x04eaf762) /* 0.307364831 */, 19 }, /* 8044 */ { MAD_F(0x04eb2cd0) /* 0.307415786 */, 19 }, /* 8045 */ { MAD_F(0x04eb623f) /* 0.307466743 */, 19 }, /* 8046 */ { MAD_F(0x04eb97ae) /* 0.307517702 */, 19 }, /* 8047 */ { MAD_F(0x04ebcd1e) /* 0.307568663 */, 19 }, /* 8048 */ { MAD_F(0x04ec028e) /* 0.307619626 */, 19 }, /* 8049 */ { MAD_F(0x04ec37ff) /* 0.307670591 */, 19 }, /* 8050 */ { MAD_F(0x04ec6d71) /* 0.307721558 */, 19 }, /* 8051 */ { MAD_F(0x04eca2e3) /* 0.307772528 */, 19 }, /* 8052 */ { MAD_F(0x04ecd855) /* 0.307823499 */, 19 }, /* 8053 */ { MAD_F(0x04ed0dc8) /* 0.307874473 */, 19 }, /* 8054 */ { MAD_F(0x04ed433c) /* 0.307925449 */, 19 }, /* 8055 */ { MAD_F(0x04ed78b0) /* 0.307976426 */, 19 }, /* 8056 */ { MAD_F(0x04edae25) /* 0.308027406 */, 19 }, /* 8057 */ { MAD_F(0x04ede39a) /* 0.308078389 */, 19 }, /* 8058 */ { MAD_F(0x04ee1910) /* 0.308129373 */, 19 }, /* 8059 */ { MAD_F(0x04ee4e87) /* 0.308180359 */, 19 }, /* 8060 */ { MAD_F(0x04ee83fe) /* 0.308231347 */, 19 }, /* 8061 */ { MAD_F(0x04eeb976) /* 0.308282338 */, 19 }, /* 8062 */ { MAD_F(0x04eeeeee) /* 0.308333331 */, 19 }, /* 8063 */ { MAD_F(0x04ef2467) /* 0.308384325 */, 19 }, /* 8064 */ { MAD_F(0x04ef59e0) /* 0.308435322 */, 19 }, /* 8065 */ { MAD_F(0x04ef8f5a) /* 0.308486321 */, 19 }, /* 8066 */ { MAD_F(0x04efc4d5) /* 0.308537322 */, 19 }, /* 8067 */ { MAD_F(0x04effa50) /* 0.308588325 */, 19 }, /* 8068 */ { MAD_F(0x04f02fcb) /* 0.308639331 */, 19 }, /* 8069 */ { MAD_F(0x04f06547) /* 0.308690338 */, 19 }, /* 8070 */ { MAD_F(0x04f09ac4) /* 0.308741348 */, 19 }, /* 8071 */ { MAD_F(0x04f0d041) /* 0.308792359 */, 19 }, /* 8072 */ { MAD_F(0x04f105bf) /* 0.308843373 */, 19 }, /* 8073 */ { MAD_F(0x04f13b3e) /* 0.308894389 */, 19 }, /* 8074 */ { MAD_F(0x04f170bd) /* 0.308945407 */, 19 }, /* 8075 */ { MAD_F(0x04f1a63c) /* 0.308996427 */, 19 }, /* 8076 */ { MAD_F(0x04f1dbbd) /* 0.309047449 */, 19 }, /* 8077 */ { MAD_F(0x04f2113d) /* 0.309098473 */, 19 }, /* 8078 */ { MAD_F(0x04f246bf) /* 0.309149499 */, 19 }, /* 8079 */ { MAD_F(0x04f27c40) /* 0.309200528 */, 19 }, /* 8080 */ { MAD_F(0x04f2b1c3) /* 0.309251558 */, 19 }, /* 8081 */ { MAD_F(0x04f2e746) /* 0.309302591 */, 19 }, /* 8082 */ { MAD_F(0x04f31cc9) /* 0.309353626 */, 19 }, /* 8083 */ { MAD_F(0x04f3524d) /* 0.309404663 */, 19 }, /* 8084 */ { MAD_F(0x04f387d2) /* 0.309455702 */, 19 }, /* 8085 */ { MAD_F(0x04f3bd57) /* 0.309506743 */, 19 }, /* 8086 */ { MAD_F(0x04f3f2dd) /* 0.309557786 */, 19 }, /* 8087 */ { MAD_F(0x04f42864) /* 0.309608831 */, 19 }, /* 8088 */ { MAD_F(0x04f45dea) /* 0.309659879 */, 19 }, /* 8089 */ { MAD_F(0x04f49372) /* 0.309710928 */, 19 }, /* 8090 */ { MAD_F(0x04f4c8fa) /* 0.309761980 */, 19 }, /* 8091 */ { MAD_F(0x04f4fe83) /* 0.309813033 */, 19 }, /* 8092 */ { MAD_F(0x04f5340c) /* 0.309864089 */, 19 }, /* 8093 */ { MAD_F(0x04f56996) /* 0.309915147 */, 19 }, /* 8094 */ { MAD_F(0x04f59f20) /* 0.309966207 */, 19 }, /* 8095 */ { MAD_F(0x04f5d4ab) /* 0.310017269 */, 19 }, /* 8096 */ { MAD_F(0x04f60a36) /* 0.310068333 */, 19 }, /* 8097 */ { MAD_F(0x04f63fc2) /* 0.310119400 */, 19 }, /* 8098 */ { MAD_F(0x04f6754f) /* 0.310170468 */, 19 }, /* 8099 */ { MAD_F(0x04f6aadc) /* 0.310221539 */, 19 }, /* 8100 */ { MAD_F(0x04f6e06a) /* 0.310272611 */, 19 }, /* 8101 */ { MAD_F(0x04f715f8) /* 0.310323686 */, 19 }, /* 8102 */ { MAD_F(0x04f74b87) /* 0.310374763 */, 19 }, /* 8103 */ { MAD_F(0x04f78116) /* 0.310425842 */, 19 }, /* 8104 */ { MAD_F(0x04f7b6a6) /* 0.310476923 */, 19 }, /* 8105 */ { MAD_F(0x04f7ec37) /* 0.310528006 */, 19 }, /* 8106 */ { MAD_F(0x04f821c8) /* 0.310579091 */, 19 }, /* 8107 */ { MAD_F(0x04f85759) /* 0.310630179 */, 19 }, /* 8108 */ { MAD_F(0x04f88cec) /* 0.310681268 */, 19 }, /* 8109 */ { MAD_F(0x04f8c27e) /* 0.310732360 */, 19 }, /* 8110 */ { MAD_F(0x04f8f812) /* 0.310783453 */, 19 }, /* 8111 */ { MAD_F(0x04f92da6) /* 0.310834549 */, 19 }, /* 8112 */ { MAD_F(0x04f9633a) /* 0.310885647 */, 19 }, /* 8113 */ { MAD_F(0x04f998cf) /* 0.310936747 */, 19 }, /* 8114 */ { MAD_F(0x04f9ce65) /* 0.310987849 */, 19 }, /* 8115 */ { MAD_F(0x04fa03fb) /* 0.311038953 */, 19 }, /* 8116 */ { MAD_F(0x04fa3992) /* 0.311090059 */, 19 }, /* 8117 */ { MAD_F(0x04fa6f29) /* 0.311141168 */, 19 }, /* 8118 */ { MAD_F(0x04faa4c1) /* 0.311192278 */, 19 }, /* 8119 */ { MAD_F(0x04fada59) /* 0.311243390 */, 19 }, /* 8120 */ { MAD_F(0x04fb0ff2) /* 0.311294505 */, 19 }, /* 8121 */ { MAD_F(0x04fb458c) /* 0.311345622 */, 19 }, /* 8122 */ { MAD_F(0x04fb7b26) /* 0.311396741 */, 19 }, /* 8123 */ { MAD_F(0x04fbb0c1) /* 0.311447862 */, 19 }, /* 8124 */ { MAD_F(0x04fbe65c) /* 0.311498985 */, 19 }, /* 8125 */ { MAD_F(0x04fc1bf8) /* 0.311550110 */, 19 }, /* 8126 */ { MAD_F(0x04fc5194) /* 0.311601237 */, 19 }, /* 8127 */ { MAD_F(0x04fc8731) /* 0.311652366 */, 19 }, /* 8128 */ { MAD_F(0x04fcbcce) /* 0.311703498 */, 19 }, /* 8129 */ { MAD_F(0x04fcf26c) /* 0.311754631 */, 19 }, /* 8130 */ { MAD_F(0x04fd280b) /* 0.311805767 */, 19 }, /* 8131 */ { MAD_F(0x04fd5daa) /* 0.311856905 */, 19 }, /* 8132 */ { MAD_F(0x04fd934a) /* 0.311908044 */, 19 }, /* 8133 */ { MAD_F(0x04fdc8ea) /* 0.311959186 */, 19 }, /* 8134 */ { MAD_F(0x04fdfe8b) /* 0.312010330 */, 19 }, /* 8135 */ { MAD_F(0x04fe342c) /* 0.312061476 */, 19 }, /* 8136 */ { MAD_F(0x04fe69ce) /* 0.312112625 */, 19 }, /* 8137 */ { MAD_F(0x04fe9f71) /* 0.312163775 */, 19 }, /* 8138 */ { MAD_F(0x04fed514) /* 0.312214927 */, 19 }, /* 8139 */ { MAD_F(0x04ff0ab8) /* 0.312266082 */, 19 }, /* 8140 */ { MAD_F(0x04ff405c) /* 0.312317238 */, 19 }, /* 8141 */ { MAD_F(0x04ff7601) /* 0.312368397 */, 19 }, /* 8142 */ { MAD_F(0x04ffaba6) /* 0.312419558 */, 19 }, /* 8143 */ { MAD_F(0x04ffe14c) /* 0.312470720 */, 19 }, /* 8144 */ { MAD_F(0x050016f3) /* 0.312521885 */, 19 }, /* 8145 */ { MAD_F(0x05004c9a) /* 0.312573052 */, 19 }, /* 8146 */ { MAD_F(0x05008241) /* 0.312624222 */, 19 }, /* 8147 */ { MAD_F(0x0500b7e9) /* 0.312675393 */, 19 }, /* 8148 */ { MAD_F(0x0500ed92) /* 0.312726566 */, 19 }, /* 8149 */ { MAD_F(0x0501233b) /* 0.312777742 */, 19 }, /* 8150 */ { MAD_F(0x050158e5) /* 0.312828919 */, 19 }, /* 8151 */ { MAD_F(0x05018e90) /* 0.312880099 */, 19 }, /* 8152 */ { MAD_F(0x0501c43b) /* 0.312931280 */, 19 }, /* 8153 */ { MAD_F(0x0501f9e6) /* 0.312982464 */, 19 }, /* 8154 */ { MAD_F(0x05022f92) /* 0.313033650 */, 19 }, /* 8155 */ { MAD_F(0x0502653f) /* 0.313084838 */, 19 }, /* 8156 */ { MAD_F(0x05029aec) /* 0.313136028 */, 19 }, /* 8157 */ { MAD_F(0x0502d09a) /* 0.313187220 */, 19 }, /* 8158 */ { MAD_F(0x05030648) /* 0.313238414 */, 19 }, /* 8159 */ { MAD_F(0x05033bf7) /* 0.313289611 */, 19 }, /* 8160 */ { MAD_F(0x050371a7) /* 0.313340809 */, 19 }, /* 8161 */ { MAD_F(0x0503a757) /* 0.313392010 */, 19 }, /* 8162 */ { MAD_F(0x0503dd07) /* 0.313443212 */, 19 }, /* 8163 */ { MAD_F(0x050412b9) /* 0.313494417 */, 19 }, /* 8164 */ { MAD_F(0x0504486a) /* 0.313545624 */, 19 }, /* 8165 */ { MAD_F(0x05047e1d) /* 0.313596833 */, 19 }, /* 8166 */ { MAD_F(0x0504b3cf) /* 0.313648044 */, 19 }, /* 8167 */ { MAD_F(0x0504e983) /* 0.313699257 */, 19 }, /* 8168 */ { MAD_F(0x05051f37) /* 0.313750472 */, 19 }, /* 8169 */ { MAD_F(0x050554eb) /* 0.313801689 */, 19 }, /* 8170 */ { MAD_F(0x05058aa0) /* 0.313852909 */, 19 }, /* 8171 */ { MAD_F(0x0505c056) /* 0.313904130 */, 19 }, /* 8172 */ { MAD_F(0x0505f60c) /* 0.313955354 */, 19 }, /* 8173 */ { MAD_F(0x05062bc3) /* 0.314006579 */, 19 }, /* 8174 */ { MAD_F(0x0506617a) /* 0.314057807 */, 19 }, /* 8175 */ { MAD_F(0x05069732) /* 0.314109037 */, 19 }, /* 8176 */ { MAD_F(0x0506cceb) /* 0.314160269 */, 19 }, /* 8177 */ { MAD_F(0x050702a4) /* 0.314211502 */, 19 }, /* 8178 */ { MAD_F(0x0507385d) /* 0.314262739 */, 19 }, /* 8179 */ { MAD_F(0x05076e17) /* 0.314313977 */, 19 }, /* 8180 */ { MAD_F(0x0507a3d2) /* 0.314365217 */, 19 }, /* 8181 */ { MAD_F(0x0507d98d) /* 0.314416459 */, 19 }, /* 8182 */ { MAD_F(0x05080f49) /* 0.314467704 */, 19 }, /* 8183 */ { MAD_F(0x05084506) /* 0.314518950 */, 19 }, /* 8184 */ { MAD_F(0x05087ac2) /* 0.314570199 */, 19 }, /* 8185 */ { MAD_F(0x0508b080) /* 0.314621449 */, 19 }, /* 8186 */ { MAD_F(0x0508e63e) /* 0.314672702 */, 19 }, /* 8187 */ { MAD_F(0x05091bfd) /* 0.314723957 */, 19 }, /* 8188 */ { MAD_F(0x050951bc) /* 0.314775214 */, 19 }, /* 8189 */ { MAD_F(0x0509877c) /* 0.314826473 */, 19 }, /* 8190 */ { MAD_F(0x0509bd3c) /* 0.314877734 */, 19 }, /* 8191 */ { MAD_F(0x0509f2fd) /* 0.314928997 */, 19 }, /* 8192 */ { MAD_F(0x050a28be) /* 0.314980262 */, 19 }, /* 8193 */ { MAD_F(0x050a5e80) /* 0.315031530 */, 19 }, /* 8194 */ { MAD_F(0x050a9443) /* 0.315082799 */, 19 }, /* 8195 */ { MAD_F(0x050aca06) /* 0.315134071 */, 19 }, /* 8196 */ { MAD_F(0x050affc9) /* 0.315185344 */, 19 }, /* 8197 */ { MAD_F(0x050b358e) /* 0.315236620 */, 19 }, /* 8198 */ { MAD_F(0x050b6b52) /* 0.315287898 */, 19 }, /* 8199 */ { MAD_F(0x050ba118) /* 0.315339178 */, 19 }, /* 8200 */ { MAD_F(0x050bd6de) /* 0.315390460 */, 19 }, /* 8201 */ { MAD_F(0x050c0ca4) /* 0.315441744 */, 19 }, /* 8202 */ { MAD_F(0x050c426b) /* 0.315493030 */, 19 }, /* 8203 */ { MAD_F(0x050c7833) /* 0.315544318 */, 19 }, /* 8204 */ { MAD_F(0x050cadfb) /* 0.315595608 */, 19 }, /* 8205 */ { MAD_F(0x050ce3c4) /* 0.315646901 */, 19 }, /* 8206 */ { MAD_F(0x050d198d) /* 0.315698195 */, 19 } xine-lib-1.2/contrib/libmad/bit.h0000644000175000017500000000311514647725151014502 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: bit.h,v 1.12 2004/01/23 09:41:32 rob Exp $ */ # ifndef LIBMAD_BIT_H # define LIBMAD_BIT_H struct mad_bitptr { unsigned char const *byte; unsigned short cache; unsigned short left; }; void mad_bit_init(struct mad_bitptr *, unsigned char const *); # define mad_bit_finish(bitptr) /* nothing */ unsigned int mad_bit_length(struct mad_bitptr const *, struct mad_bitptr const *); # define mad_bit_bitsleft(bitptr) ((bitptr)->left) unsigned char const *mad_bit_nextbyte(struct mad_bitptr const *); void mad_bit_skip(struct mad_bitptr *, unsigned int); unsigned long mad_bit_read(struct mad_bitptr *, unsigned int); void mad_bit_write(struct mad_bitptr *, unsigned int, unsigned long); unsigned short mad_bit_crc(struct mad_bitptr, unsigned int, unsigned short); # endif xine-lib-1.2/contrib/libmad/timer.h0000644000175000017500000000547714647725152015062 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: timer.h,v 1.16 2004/01/23 09:41:33 rob Exp $ */ # ifndef LIBMAD_TIMER_H # define LIBMAD_TIMER_H typedef struct { signed long seconds; /* whole seconds */ unsigned long fraction; /* 1/MAD_TIMER_RESOLUTION seconds */ } mad_timer_t; extern mad_timer_t const mad_timer_zero; # define MAD_TIMER_RESOLUTION 352800000UL enum mad_units { MAD_UNITS_HOURS = -2, MAD_UNITS_MINUTES = -1, MAD_UNITS_SECONDS = 0, /* metric units */ MAD_UNITS_DECISECONDS = 10, MAD_UNITS_CENTISECONDS = 100, MAD_UNITS_MILLISECONDS = 1000, /* audio sample units */ MAD_UNITS_8000_HZ = 8000, MAD_UNITS_11025_HZ = 11025, MAD_UNITS_12000_HZ = 12000, MAD_UNITS_16000_HZ = 16000, MAD_UNITS_22050_HZ = 22050, MAD_UNITS_24000_HZ = 24000, MAD_UNITS_32000_HZ = 32000, MAD_UNITS_44100_HZ = 44100, MAD_UNITS_48000_HZ = 48000, /* video frame/field units */ MAD_UNITS_24_FPS = 24, MAD_UNITS_25_FPS = 25, MAD_UNITS_30_FPS = 30, MAD_UNITS_48_FPS = 48, MAD_UNITS_50_FPS = 50, MAD_UNITS_60_FPS = 60, /* CD audio frames */ MAD_UNITS_75_FPS = 75, /* video drop-frame units */ MAD_UNITS_23_976_FPS = -24, MAD_UNITS_24_975_FPS = -25, MAD_UNITS_29_97_FPS = -30, MAD_UNITS_47_952_FPS = -48, MAD_UNITS_49_95_FPS = -50, MAD_UNITS_59_94_FPS = -60 }; # define mad_timer_reset(timer) ((void) (*(timer) = mad_timer_zero)) int mad_timer_compare(mad_timer_t, mad_timer_t); # define mad_timer_sign(timer) mad_timer_compare((timer), mad_timer_zero) void mad_timer_negate(mad_timer_t *); mad_timer_t mad_timer_abs(mad_timer_t); void mad_timer_set(mad_timer_t *, unsigned long, unsigned long, unsigned long); void mad_timer_add(mad_timer_t *, mad_timer_t); void mad_timer_multiply(mad_timer_t *, signed long); signed long mad_timer_count(mad_timer_t, enum mad_units); unsigned long mad_timer_fraction(mad_timer_t, unsigned long); void mad_timer_string(mad_timer_t, char *, char const *, enum mad_units, enum mad_units, unsigned long); # endif xine-lib-1.2/contrib/libmad/stream.c0000644000175000017500000001057314647725152015221 0ustar meme/* * libmad - MPEG audio decoder library * Copyright (C) 2000-2004 Underbit Technologies, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * $Id: stream.c,v 1.12 2004/02/05 09:02:39 rob Exp $ */ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include # include "bit.h" # include "stream.h" /* * NAME: stream->init() * DESCRIPTION: initialize stream struct */ void mad_stream_init(struct mad_stream *stream) { stream->buffer = 0; stream->bufend = 0; stream->skiplen = 0; stream->sync = 0; stream->freerate = 0; stream->this_frame = 0; stream->next_frame = 0; mad_bit_init(&stream->ptr, 0); mad_bit_init(&stream->anc_ptr, 0); stream->anc_bitlen = 0; stream->main_data = 0; stream->md_len = 0; stream->options = 0; stream->error = MAD_ERROR_NONE; } /* * NAME: stream->finish() * DESCRIPTION: deallocate any dynamic memory associated with stream */ void mad_stream_finish(struct mad_stream *stream) { if (stream->main_data) { free(stream->main_data); stream->main_data = 0; } mad_bit_finish(&stream->anc_ptr); mad_bit_finish(&stream->ptr); } /* * NAME: stream->buffer() * DESCRIPTION: set stream buffer pointers */ void mad_stream_buffer(struct mad_stream *stream, unsigned char const *buffer, unsigned long length) { stream->buffer = buffer; stream->bufend = buffer + length; stream->this_frame = buffer; stream->next_frame = buffer; stream->sync = 1; mad_bit_init(&stream->ptr, buffer); } /* * NAME: stream->skip() * DESCRIPTION: arrange to skip bytes before the next frame */ void mad_stream_skip(struct mad_stream *stream, unsigned long length) { stream->skiplen += length; } /* * NAME: stream->sync() * DESCRIPTION: locate the next stream sync word */ int mad_stream_sync(struct mad_stream *stream) { register unsigned char const *ptr, *end; ptr = mad_bit_nextbyte(&stream->ptr); end = stream->bufend; while (ptr < end - 1 && !(ptr[0] == 0xff && (ptr[1] & 0xe0) == 0xe0)) ++ptr; if (end - ptr < MAD_BUFFER_GUARD) return -1; mad_bit_init(&stream->ptr, ptr); return 0; } /* * NAME: stream->errorstr() * DESCRIPTION: return a string description of the current error condition */ char const *mad_stream_errorstr(struct mad_stream const *stream) { switch (stream->error) { case MAD_ERROR_NONE: return "no error"; case MAD_ERROR_BUFLEN: return "input buffer too small (or EOF)"; case MAD_ERROR_BUFPTR: return "invalid (null) buffer pointer"; case MAD_ERROR_NOMEM: return "not enough memory"; case MAD_ERROR_LOSTSYNC: return "lost synchronization"; case MAD_ERROR_BADLAYER: return "reserved header layer value"; case MAD_ERROR_BADBITRATE: return "forbidden bitrate value"; case MAD_ERROR_BADSAMPLERATE: return "reserved sample frequency value"; case MAD_ERROR_BADEMPHASIS: return "reserved emphasis value"; case MAD_ERROR_BADCRC: return "CRC check failed"; case MAD_ERROR_BADBITALLOC: return "forbidden bit allocation value"; case MAD_ERROR_BADSCALEFACTOR: return "bad scalefactor index"; case MAD_ERROR_BADMODE: return "bad bitrate/mode combination"; case MAD_ERROR_BADFRAMELEN: return "bad frame length"; case MAD_ERROR_BADBIGVALUES: return "bad big_values count"; case MAD_ERROR_BADBLOCKTYPE: return "reserved block_type"; case MAD_ERROR_BADSCFSI: return "bad scalefactor selection info"; case MAD_ERROR_BADDATAPTR: return "bad main_data_begin pointer"; case MAD_ERROR_BADPART3LEN: return "bad audio data length"; case MAD_ERROR_BADHUFFTABLE: return "bad Huffman table select"; case MAD_ERROR_BADHUFFDATA: return "Huffman data overrun"; case MAD_ERROR_BADSTEREO: return "incompatible block_type for JS"; } return 0; } xine-lib-1.2/contrib/gsm610/0000755000175000017500000000000014647725151013340 5ustar memexine-lib-1.2/contrib/gsm610/decode.c0000644000175000017500000000304514647725151014731 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/decode.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ #include #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER */ static void Postprocessing P2((S,s), struct gsm_state * S, register word * s) { register int k; register word msr = S->msr; register longword ltmp; /* for GSM_ADD */ register word tmp; for (k = 160; k--; s++) { tmp = GSM_MULT_R( msr, 28180 ); msr = GSM_ADD(*s, tmp); /* Deemphasis */ *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ } S->msr = msr; } void Gsm_Decoder P8((S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s), struct gsm_state * S, word * LARcr, /* [0..7] IN */ word * Ncr, /* [0..3] IN */ word * bcr, /* [0..3] IN */ word * Mcr, /* [0..3] IN */ word * xmaxcr, /* [0..3] IN */ word * xMcr, /* [0..13*4] IN */ word * s) /* [0..159] OUT */ { int j, k; word erp[40], wt[160]; word * drp = S->dp0 + 120; for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; } Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); Postprocessing(S, s); } xine-lib-1.2/contrib/gsm610/gsm_decode.c0000644000175000017500000002463114647725151015603 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_decode.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ #include "private.h" #include "gsm.h" #include "proto.h" int gsm_decode P3((s, c, target), gsm s, gsm_byte * c, gsm_signal * target) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; if (s->wav_fmt) { uword sr = 0; s->frame_index = !s->frame_index; if (s->frame_index) { sr = *c++; LARc[0] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 2; LARc[1] = sr & 0x3f; sr >>= 6; sr |= (uword)*c++ << 4; LARc[2] = sr & 0x1f; sr >>= 5; LARc[3] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 2; LARc[4] = sr & 0xf; sr >>= 4; LARc[5] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; /* 5 */ LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[0] = sr & 0x7f; sr >>= 7; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[0] = sr & 0x3f; sr >>= 6; xmc[0] = sr & 0x7; sr >>= 3; sr = *c++; xmc[1] = sr & 0x7; sr >>= 3; xmc[2] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; xmc[5] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 10 */ xmc[6] = sr & 0x7; sr >>= 3; xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; sr = *c++; xmc[9] = sr & 0x7; sr >>= 3; xmc[10] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[1] = sr & 0x7f; sr >>= 7; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[1] = sr & 0x3f; sr >>= 6; xmc[13] = sr & 0x7; sr >>= 3; sr = *c++; /* 15 */ xmc[14] = sr & 0x7; sr >>= 3; xmc[15] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; xmc[18] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[19] = sr & 0x7; sr >>= 3; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; sr = *c++; xmc[22] = sr & 0x7; sr >>= 3; xmc[23] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; /* 20 */ Nc[2] = sr & 0x7f; sr >>= 7; bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[2] = sr & 0x3f; sr >>= 6; xmc[26] = sr & 0x7; sr >>= 3; sr = *c++; xmc[27] = sr & 0x7; sr >>= 3; xmc[28] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; xmc[31] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[32] = sr & 0x7; sr >>= 3; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; sr = *c++; /* 25 */ xmc[35] = sr & 0x7; sr >>= 3; xmc[36] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 4; Nc[3] = sr & 0x7f; sr >>= 7; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 1; xmaxc[3] = sr & 0x3f; sr >>= 6; xmc[39] = sr & 0x7; sr >>= 3; sr = *c++; xmc[40] = sr & 0x7; sr >>= 3; xmc[41] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 30 */ xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; xmc[44] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[45] = sr & 0x7; sr >>= 3; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; sr = *c++; xmc[48] = sr & 0x7; sr >>= 3; xmc[49] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; s->frame_chain = sr & 0xf; } else { sr = s->frame_chain; sr |= (uword)*c++ << 4; /* 1 */ LARc[0] = sr & 0x3f; sr >>= 6; LARc[1] = sr & 0x3f; sr >>= 6; sr = *c++; LARc[2] = sr & 0x1f; sr >>= 5; sr |= (uword)*c++ << 3; LARc[3] = sr & 0x1f; sr >>= 5; LARc[4] = sr & 0xf; sr >>= 4; sr |= (uword)*c++ << 2; LARc[5] = sr & 0xf; sr >>= 4; LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr = *c++; /* 5 */ Nc[0] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[0] = sr & 0x3f; sr >>= 6; xmc[0] = sr & 0x7; sr >>= 3; xmc[1] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[2] = sr & 0x7; sr >>= 3; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; sr = *c++; xmc[5] = sr & 0x7; sr >>= 3; xmc[6] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; /* 10 */ xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; xmc[9] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[10] = sr & 0x7; sr >>= 3; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr = *c++; Nc[1] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[1] = sr & 0x3f; sr >>= 6; xmc[13] = sr & 0x7; sr >>= 3; xmc[14] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 15 */ xmc[15] = sr & 0x7; sr >>= 3; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; sr = *c++; xmc[18] = sr & 0x7; sr >>= 3; xmc[19] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; xmc[22] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[23] = sr & 0x7; sr >>= 3; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr = *c++; Nc[2] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; /* 20 */ bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[2] = sr & 0x3f; sr >>= 6; xmc[26] = sr & 0x7; sr >>= 3; xmc[27] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[28] = sr & 0x7; sr >>= 3; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; sr = *c++; xmc[31] = sr & 0x7; sr >>= 3; xmc[32] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; xmc[35] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; /* 25 */ xmc[36] = sr & 0x7; sr >>= 3; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr = *c++; Nc[3] = sr & 0x7f; sr >>= 7; sr |= (uword)*c++ << 1; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (uword)*c++ << 5; xmaxc[3] = sr & 0x3f; sr >>= 6; xmc[39] = sr & 0x7; sr >>= 3; xmc[40] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[41] = sr & 0x7; sr >>= 3; xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; sr = *c++; /* 30 */ xmc[44] = sr & 0x7; sr >>= 3; xmc[45] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 2; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; xmc[48] = sr & 0x7; sr >>= 3; sr |= (uword)*c++ << 1; xmc[49] = sr & 0x7; sr >>= 3; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; } } else { /* GSM_MAGIC = (*c >> 4) & 0xF; */ if (((*c >> 4) & 0x0F) != GSM_MAGIC) return -1; LARc[0] = (*c++ & 0xF) << 2; /* 1 */ LARc[0] |= (*c >> 6) & 0x3; LARc[1] = *c++ & 0x3F; LARc[2] = (*c >> 3) & 0x1F; LARc[3] = (*c++ & 0x7) << 2; LARc[3] |= (*c >> 6) & 0x3; LARc[4] = (*c >> 2) & 0xF; LARc[5] = (*c++ & 0x3) << 2; LARc[5] |= (*c >> 6) & 0x3; LARc[6] = (*c >> 3) & 0x7; LARc[7] = *c++ & 0x7; Nc[0] = (*c >> 1) & 0x7F; bc[0] = (*c++ & 0x1) << 1; bc[0] |= (*c >> 7) & 0x1; Mc[0] = (*c >> 5) & 0x3; xmaxc[0] = (*c++ & 0x1F) << 1; xmaxc[0] |= (*c >> 7) & 0x1; xmc[0] = (*c >> 4) & 0x7; xmc[1] = (*c >> 1) & 0x7; xmc[2] = (*c++ & 0x1) << 2; xmc[2] |= (*c >> 6) & 0x3; xmc[3] = (*c >> 3) & 0x7; xmc[4] = *c++ & 0x7; xmc[5] = (*c >> 5) & 0x7; xmc[6] = (*c >> 2) & 0x7; xmc[7] = (*c++ & 0x3) << 1; /* 10 */ xmc[7] |= (*c >> 7) & 0x1; xmc[8] = (*c >> 4) & 0x7; xmc[9] = (*c >> 1) & 0x7; xmc[10] = (*c++ & 0x1) << 2; xmc[10] |= (*c >> 6) & 0x3; xmc[11] = (*c >> 3) & 0x7; xmc[12] = *c++ & 0x7; Nc[1] = (*c >> 1) & 0x7F; bc[1] = (*c++ & 0x1) << 1; bc[1] |= (*c >> 7) & 0x1; Mc[1] = (*c >> 5) & 0x3; xmaxc[1] = (*c++ & 0x1F) << 1; xmaxc[1] |= (*c >> 7) & 0x1; xmc[13] = (*c >> 4) & 0x7; xmc[14] = (*c >> 1) & 0x7; xmc[15] = (*c++ & 0x1) << 2; xmc[15] |= (*c >> 6) & 0x3; xmc[16] = (*c >> 3) & 0x7; xmc[17] = *c++ & 0x7; xmc[18] = (*c >> 5) & 0x7; xmc[19] = (*c >> 2) & 0x7; xmc[20] = (*c++ & 0x3) << 1; xmc[20] |= (*c >> 7) & 0x1; xmc[21] = (*c >> 4) & 0x7; xmc[22] = (*c >> 1) & 0x7; xmc[23] = (*c++ & 0x1) << 2; xmc[23] |= (*c >> 6) & 0x3; xmc[24] = (*c >> 3) & 0x7; xmc[25] = *c++ & 0x7; Nc[2] = (*c >> 1) & 0x7F; bc[2] = (*c++ & 0x1) << 1; /* 20 */ bc[2] |= (*c >> 7) & 0x1; Mc[2] = (*c >> 5) & 0x3; xmaxc[2] = (*c++ & 0x1F) << 1; xmaxc[2] |= (*c >> 7) & 0x1; xmc[26] = (*c >> 4) & 0x7; xmc[27] = (*c >> 1) & 0x7; xmc[28] = (*c++ & 0x1) << 2; xmc[28] |= (*c >> 6) & 0x3; xmc[29] = (*c >> 3) & 0x7; xmc[30] = *c++ & 0x7; xmc[31] = (*c >> 5) & 0x7; xmc[32] = (*c >> 2) & 0x7; xmc[33] = (*c++ & 0x3) << 1; xmc[33] |= (*c >> 7) & 0x1; xmc[34] = (*c >> 4) & 0x7; xmc[35] = (*c >> 1) & 0x7; xmc[36] = (*c++ & 0x1) << 2; xmc[36] |= (*c >> 6) & 0x3; xmc[37] = (*c >> 3) & 0x7; xmc[38] = *c++ & 0x7; Nc[3] = (*c >> 1) & 0x7F; bc[3] = (*c++ & 0x1) << 1; bc[3] |= (*c >> 7) & 0x1; Mc[3] = (*c >> 5) & 0x3; xmaxc[3] = (*c++ & 0x1F) << 1; xmaxc[3] |= (*c >> 7) & 0x1; xmc[39] = (*c >> 4) & 0x7; xmc[40] = (*c >> 1) & 0x7; xmc[41] = (*c++ & 0x1) << 2; xmc[41] |= (*c >> 6) & 0x3; xmc[42] = (*c >> 3) & 0x7; xmc[43] = *c++ & 0x7; /* 30 */ xmc[44] = (*c >> 5) & 0x7; xmc[45] = (*c >> 2) & 0x7; xmc[46] = (*c++ & 0x3) << 1; xmc[46] |= (*c >> 7) & 0x1; xmc[47] = (*c >> 4) & 0x7; xmc[48] = (*c >> 1) & 0x7; xmc[49] = (*c++ & 0x1) << 2; xmc[49] |= (*c >> 6) & 0x3; xmc[50] = (*c >> 3) & 0x7; xmc[51] = *c & 0x7; /* 33 */ } Gsm_Decoder(s, LARc, Nc, bc, Mc, xmaxc, xmc, target); return 0; } xine-lib-1.2/contrib/gsm610/gsm_destroy.c0000644000175000017500000000110014647725151016033 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_destroy.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ #include "gsm.h" #include "gsm_config.h" #include "proto.h" #ifdef HAS_STDLIB_H # include #else # ifdef HAS_MALLOC_H # include # else extern void free(); # endif #endif void gsm_destroy P1((S), gsm S) { if (S) free((char *)S); } xine-lib-1.2/contrib/gsm610/add.c0000644000175000017500000001266714647725151014250 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/add.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ /* * See private.h for the more commonly used macro versions. */ #include #include #include "private.h" #include "gsm.h" #include "proto.h" #define saturate(x) \ ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) word gsm_add P2((a,b), word a, word b) { longword sum = (longword)a + (longword)b; return saturate(sum); } word gsm_sub P2((a,b), word a, word b) { longword diff = (longword)a - (longword)b; return saturate(diff); } word gsm_mult P2((a,b), word a, word b) { if (a == MIN_WORD && b == MIN_WORD) return MAX_WORD; else return SASR( (longword)a * (longword)b, 15 ); } word gsm_mult_r P2((a,b), word a, word b) { if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD; else { longword prod = (longword)a * (longword)b + 16384; prod >>= 15; return prod & 0xFFFF; } } word gsm_abs P1((a), word a) { return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a; } longword gsm_L_mult P2((a,b),word a, word b) { assert( a != MIN_WORD || b != MIN_WORD ); return ((longword)a * (longword)b) << 1; } longword gsm_L_add P2((a,b), longword a, longword b) { if (a < 0) { if (b >= 0) return a + b; else { ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1); return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2; } } else if (b <= 0) return a + b; else { ulongword A = (ulongword)a + (ulongword)b; return A > MAX_LONGWORD ? MAX_LONGWORD : A; } } longword gsm_L_sub P2((a,b), longword a, longword b) { if (a >= 0) { if (b >= 0) return a - b; else { /* a>=0, b<0 */ ulongword A = (ulongword)a + -(b + 1); return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1); } } else if (b <= 0) return a - b; else { /* a<0, b>0 */ ulongword A = (ulongword)-(a + 1) + b; return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1; } } static unsigned char const bitoff[ 256 ] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 }; word gsm_norm P1((a), longword a ) /* * the number of left shifts needed to normalize the 32 bit * variable L_var1 for positive values on the interval * * with minimum of * minimum of 1073741824 (01000000000000000000000000000000) and * maximum of 2147483647 (01111111111111111111111111111111) * * * and for negative values on the interval with * minimum of -2147483648 (-10000000000000000000000000000000) and * maximum of -1073741824 ( -1000000000000000000000000000000). * * in order to normalize the result, the following * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 ); * * (That's 'ffs', only from the left, not the right..) */ { assert(a != 0); if (a < 0) { if (a <= -1073741824) return 0; a = ~a; } return a & 0xffff0000 ? ( a & 0xff000000 ? -1 + bitoff[ 0xFF & (a >> 24) ] : 7 + bitoff[ 0xFF & (a >> 16) ] ) : ( a & 0xff00 ? 15 + bitoff[ 0xFF & (a >> 8) ] : 23 + bitoff[ 0xFF & a ] ); } longword gsm_L_asl P2((a,n), longword a, int n) { if (n >= 32) return 0; if (n <= -32) return -(a < 0); if (n < 0) return gsm_L_asr(a, -n); return a << n; } word gsm_asl P2((a,n), word a, int n) { if (n >= 16) return 0; if (n <= -16) return -(a < 0); if (n < 0) return gsm_asr(a, -n); return a << n; } longword gsm_L_asr P2((a,n), longword a, int n) { if (n >= 32) return -(a < 0); if (n <= -32) return 0; if (n < 0) return a << -n; # ifdef SASR return a >> n; # else if (a >= 0) return a >> n; else return -(longword)( -(ulongword)a >> n ); # endif } word gsm_asr P2((a,n), word a, int n) { if (n >= 16) return -(a < 0); if (n <= -16) return 0; if (n < 0) return a << -n; # ifdef SASR return a >> n; # else if (a >= 0) return a >> n; else return -(word)( -(uword)a >> n ); # endif } /* * (From p. 46, end of section 4.2.5) * * NOTE: The following lines gives [sic] one correct implementation * of the div(num, denum) arithmetic operation. Compute div * which is the integer division of num by denum: with denum * >= num > 0 */ word gsm_div P2((num,denum), word num, word denum) { longword L_num = num; longword L_denum = denum; word div = 0; int k = 15; /* The parameter num sometimes becomes zero. * Although this is explicitly guarded against in 4.2.5, * we assume that the result should then be zero as well. */ /* assert(num != 0); */ assert(num >= 0 && denum >= num); if (num == 0) return 0; while (k--) { div <<= 1; L_num <<= 1; if (L_num >= L_denum) { L_num -= L_denum; div++; } } return div; } xine-lib-1.2/contrib/gsm610/lpc.c0000644000175000017500000001610314647725151014263 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/lpc.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "private.h" #include "gsm.h" #include "proto.h" #undef P /* * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION */ /* 4.2.4 */ static void Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ longword * L_ACF) /* [0..8] OUT */ /* * The goal is to compute the array L_ACF[k]. The signal s[i] must * be scaled in order to avoid an overflow situation. */ { register int k, i; word temp, smax, scalauto; #ifdef USE_FLOAT_MUL float float_s[160]; #endif /* Dynamic scaling of the array s[0..159] */ /* Search for the maximum. */ smax = 0; for (k = 0; k <= 159; k++) { temp = GSM_ABS( s[k] ); if (temp > smax) smax = temp; } /* Computation of the scaling factor. */ if (smax == 0) scalauto = 0; else { _x_assert(smax > 0); scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */ } /* Scaling of the array s[0...159] */ if (scalauto > 0) { # ifdef USE_FLOAT_MUL # define SCALE(n) \ case n: for (k = 0; k <= 159; k++) \ float_s[k] = (float) \ (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ break; # else # define SCALE(n) \ case n: for (k = 0; k <= 159; k++) \ s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ break; # endif /* USE_FLOAT_MUL */ switch (scalauto) { SCALE(1) SCALE(2) SCALE(3) SCALE(4) } # undef SCALE } # ifdef USE_FLOAT_MUL else for (k = 0; k <= 159; k++) float_s[k] = (float) s[k]; # endif /* Compute the L_ACF[..]. */ { # ifdef USE_FLOAT_MUL register float * sp = float_s; register float sl = *sp; # define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); # else word * sp = s; word sl = *sp; # define STEP(k) L_ACF[k] += ((longword)sl * sp[ -(k) ]); # endif # define NEXTI sl = *++sp for (k = 9; k--; L_ACF[k] = 0) ; STEP (0); NEXTI; STEP(0); STEP(1); NEXTI; STEP(0); STEP(1); STEP(2); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); for (i = 8; i <= 159; i++) { NEXTI; STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7); STEP(8); } for (k = 9; k--; L_ACF[k] <<= 1) ; } /* Rescaling of the array s[0..159] */ if (scalauto > 0) { _x_assert(scalauto <= 4); for (k = 160; k--; *s++ <<= scalauto) ; } } #if defined(USE_FLOAT_MUL) && defined(FAST) static void Fast_Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ longword * L_ACF) /* [0..8] OUT */ { register int k, i; float f_L_ACF[9]; float scale; float s_f[160]; register float *sf = s_f; for (i = 0; i < 160; ++i) sf[i] = s[i]; for (k = 0; k <= 8; k++) { register float L_temp2 = 0; register float *sfl = sf - k; for (i = k; i < 160; ++i) L_temp2 += sf[i] * sfl[i]; f_L_ACF[k] = L_temp2; } scale = MAX_LONGWORD / f_L_ACF[0]; for (k = 0; k <= 8; k++) { L_ACF[k] = f_L_ACF[k] * scale; } } #endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ /* 4.2.5 */ static void Reflection_coefficients P2( (L_ACF, r), longword * L_ACF, /* 0...8 IN */ register word * r /* 0...7 OUT */ ) { register int i, m, n; register word temp; register longword ltmp; word ACF[9]; /* 0..8 */ word P[ 9]; /* 0..8 */ word K[ 9]; /* 2..8 */ /* Schur recursion with 16 bits arithmetic. */ if (L_ACF[0] == 0) { for (i = 8; i--; *r++ = 0) ; return; } _x_assert( L_ACF[0] != 0 ); temp = gsm_norm( L_ACF[0] ); _x_assert(temp >= 0 && temp < 32); /* ? overflow ? */ for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 ); /* Initialize array P[..] and K[..] for the recursion. */ for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ]; for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ]; /* Compute reflection coefficients */ for (n = 1; n <= 8; n++, r++) { temp = P[1]; temp = GSM_ABS(temp); if (P[0] < temp) { for (i = n; i <= 8; i++) *r++ = 0; return; } *r = gsm_div( temp, P[0] ); _x_assert(*r >= 0); if (P[1] > 0) *r = -*r; /* r[n] = sub(0, r[n]) */ _x_assert(*r != MIN_WORD); if (n == 8) return; /* Schur recursion */ temp = GSM_MULT_R( P[1], *r ); P[0] = GSM_ADD( P[0], temp ); for (m = 1; m <= 8 - n; m++) { temp = GSM_MULT_R( K[ m ], *r ); P[m] = GSM_ADD( P[ m+1 ], temp ); temp = GSM_MULT_R( P[ m+1 ], *r ); K[m] = GSM_ADD( K[ m ], temp ); } } } /* 4.2.6 */ static void Transformation_to_Log_Area_Ratios P1((r), register word * r /* 0..7 IN/OUT */ ) /* * The following scaling for r[..] and LAR[..] has been used: * * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. * LAR[..] = integer( real_LAR[..] * 16384 ); * with -1.625 <= real_LAR <= 1.625 */ { register word temp; register int i; /* Computation of the LAR[0..7] from the r[0..7] */ for (i = 1; i <= 8; i++, r++) { temp = *r; temp = GSM_ABS(temp); _x_assert(temp >= 0); if (temp < 22118) { temp >>= 1; } else if (temp < 31130) { _x_assert(temp >= 11059); temp -= 11059; } else { _x_assert(temp >= 26112); temp -= 26112; temp <<= 2; } if (*r < 0) { *r = -temp; } else { *r = temp; } _x_assert(*r != MIN_WORD); } } /* 4.2.7 */ static void Quantization_and_coding P1((LAR), register word * LAR /* [0..7] IN/OUT */ ) { register word temp; longword ltmp; /* This procedure needs four tables; the following equations * give the optimum scaling for the constants: * * A[0..7] = integer( real_A[0..7] * 1024 ) * B[0..7] = integer( real_B[0..7] * 512 ) * MAC[0..7] = maximum of the LARc[0..7] * MIC[0..7] = minimum of the LARc[0..7] */ # undef STEP # define STEP( A, B, MAC, MIC ) \ temp = GSM_MULT( A, *LAR ); \ temp = GSM_ADD( temp, B ); \ temp = GSM_ADD( temp, 256 ); \ temp = SASR( temp, 9 ); \ *LAR = temp>MAC ? MAC - MIC : (tempfast) Fast_Autocorrelation (s, L_ACF ); else #else (void)S; #endif Autocorrelation (s, L_ACF ); Reflection_coefficients (L_ACF, LARc ); Transformation_to_Log_Area_Ratios (LARc); Quantization_and_coding (LARc); } xine-lib-1.2/contrib/gsm610/proto.h0000644000175000017500000000311214647725151014651 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/proto.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ #ifndef PROTO_H #define PROTO_H #if __cplusplus # define NeedFunctionPrototypes 1 #endif #if __STDC__ # define NeedFunctionPrototypes 1 #endif #ifdef _NO_PROTO # undef NeedFunctionPrototypes #endif #undef P /* gnu stdio.h actually defines this... */ #undef P0 #undef P1 #undef P2 #undef P3 #undef P4 #undef P5 #undef P6 #undef P7 #undef P8 #if NeedFunctionPrototypes # define P( protos ) protos # define P0() (void) # define P1(x, a) (a) # define P2(x, a, b) (a, b) # define P3(x, a, b, c) (a, b, c) # define P4(x, a, b, c, d) (a, b, c, d) # define P5(x, a, b, c, d, e) (a, b, c, d, e) # define P6(x, a, b, c, d, e, f) (a, b, c, d, e, f) # define P7(x, a, b, c, d, e, f, g) (a, b, c, d, e, f, g) # define P8(x, a, b, c, d, e, f, g, h) (a, b, c, d, e, f, g, h) #else /* !NeedFunctionPrototypes */ # define P( protos ) ( /* protos */ ) # define P0() () # define P1(x, a) x a; # define P2(x, a, b) x a; b; # define P3(x, a, b, c) x a; b; c; # define P4(x, a, b, c, d) x a; b; c; d; # define P5(x, a, b, c, d, e) x a; b; c; d; e; # define P6(x, a, b, c, d, e, f) x a; b; c; d; e; f; # define P7(x, a, b, c, d, e, f, g) x a; b; c; d; e; f; g; # define P8(x, a, b, c, d, e, f, g, h) x a; b; c; d; e; f; g; h; #endif /* !NeedFunctionPrototypes */ #endif /* PROTO_H */ xine-lib-1.2/contrib/gsm610/Makefile.am0000644000175000017500000000062314647725151015375 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) if ENABLE_GSM610 noinst_LTLIBRARIES = libgsm610.la endif libgsm610_la_SOURCES = \ add.c \ decode.c \ gsm.h \ gsm_config.h \ gsm_create.c \ gsm_decode.c \ gsm_destroy.c \ long_term.c \ lpc.c \ private.h \ proto.h \ rpe.c \ short_term.c \ table.c \ unproto.h xine-lib-1.2/contrib/gsm610/unproto.h0000644000175000017500000000073314647725151015222 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/unproto.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ #ifdef PROTO_H /* sic */ #undef PROTO_H #undef P #undef P0 #undef P1 #undef P2 #undef P3 #undef P4 #undef P5 #undef P6 #undef P7 #undef P8 #endif /* PROTO_H */ xine-lib-1.2/contrib/gsm610/rpe.c0000644000175000017500000002616414647725151014303 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/rpe.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* 4.2.13 .. 4.2.17 RPE ENCODING SECTION */ /* 4.2.13 */ static void Weighting_filter P2((e, x), register word * e, /* signal [-5..0.39.44] IN */ word * x /* signal [0..39] OUT */ ) /* * The coefficients of the weighting filter are stored in a table * (see table 4.4). The following scaling is used: * * H[0..10] = integer( real_H[ 0..10] * 8192 ); */ { /* word wt[ 50 ]; */ register longword L_result; register int k /* , i */ ; /* Initialization of a temporary working array wt[0...49] */ /* for (k = 0; k <= 4; k++) wt[k] = 0; * for (k = 5; k <= 44; k++) wt[k] = *e++; * for (k = 45; k <= 49; k++) wt[k] = 0; * * (e[-5..-1] and e[40..44] are allocated by the caller, * are initially zero and are not written anywhere.) */ e -= 5; /* Compute the signal x[0..39] */ for (k = 0; k <= 39; k++) { L_result = 8192 >> 1; /* for (i = 0; i <= 10; i++) { * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); * L_result = GSM_L_ADD( L_result, L_temp ); * } */ #undef STEP #define STEP( i, H ) (e[ k + i ] * (longword)H) /* Every one of these multiplications is done twice -- * but I don't see an elegant way to optimize this. * Do you? */ #ifdef STUPID_COMPILER L_result += STEP( 0, -134 ) ; L_result += STEP( 1, -374 ) ; /* + STEP( 2, 0 ) */ L_result += STEP( 3, 2054 ) ; L_result += STEP( 4, 5741 ) ; L_result += STEP( 5, 8192 ) ; L_result += STEP( 6, 5741 ) ; L_result += STEP( 7, 2054 ) ; /* + STEP( 8, 0 ) */ L_result += STEP( 9, -374 ) ; L_result += STEP( 10, -134 ) ; #else L_result += STEP( 0, -134 ) + STEP( 1, -374 ) /* + STEP( 2, 0 ) */ + STEP( 3, 2054 ) + STEP( 4, 5741 ) + STEP( 5, 8192 ) + STEP( 6, 5741 ) + STEP( 7, 2054 ) /* + STEP( 8, 0 ) */ + STEP( 9, -374 ) + STEP(10, -134 ) ; #endif /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) * * x[k] = SASR( L_result, 16 ); */ /* 2 adds vs. >>16 => 14, minus one shift to compensate for * those we lost when replacing L_MULT by '*'. */ L_result = SASR( L_result, 13 ); x[k] = ( L_result < MIN_WORD ? MIN_WORD : (L_result > MAX_WORD ? MAX_WORD : L_result )); } } /* 4.2.14 */ static void RPE_grid_selection P3((x,xM,Mc_out), word * x, /* [0..39] IN */ word * xM, /* [0..12] OUT */ word * Mc_out /* OUT */ ) /* * The signal x[0..39] is used to select the RPE grid which is * represented by Mc. */ { /* register word temp1; */ register int /* m, */ i; register longword L_result, L_temp; longword EM; /* xxx should be L_EM? */ word Mc; longword L_common_0_3; EM = 0; Mc = 0; /* for (m = 0; m <= 3; m++) { * L_result = 0; * * * for (i = 0; i <= 12; i++) { * * temp1 = SASR( x[m + 3*i], 2 ); * * _x_assert(temp1 != MIN_WORD); * * L_temp = GSM_L_MULT( temp1, temp1 ); * L_result = GSM_L_ADD( L_temp, L_result ); * } * * if (L_result > EM) { * Mc = m; * EM = L_result; * } * } */ #undef STEP #define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ L_result += L_temp * L_temp; /* common part of 0 and 3 */ L_result = 0; STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); L_common_0_3 = L_result; /* i = 0 */ STEP( 0, 0 ); L_result <<= 1; /* implicit in L_MULT */ EM = L_result; /* i = 1 */ L_result = 0; STEP( 1, 0 ); STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); L_result <<= 1; if (L_result > EM) { Mc = 1; EM = L_result; } /* i = 2 */ L_result = 0; STEP( 2, 0 ); STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); L_result <<= 1; if (L_result > EM) { Mc = 2; EM = L_result; } /* i = 3 */ L_result = L_common_0_3; STEP( 3, 12 ); L_result <<= 1; if (L_result > EM) { Mc = 3; EM = L_result; } /**/ /* Down-sampling by a factor 3 to get the selected xM[0..12] * RPE sequence. */ for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; *Mc_out = Mc; } /* 4.12.15 */ static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), word xmaxc, /* IN */ word * exp_out, /* OUT */ word * mant_out ) /* OUT */ { word exp, mant; /* Compute exponent and mantissa of the decoded version of xmaxc */ exp = 0; if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; mant = xmaxc - (exp << 3); if (mant == 0) { exp = -4; mant = 7; } else { while (mant <= 7) { mant = mant << 1 | 1; exp--; } mant -= 8; } _x_assert( exp >= -4 && exp <= 6 ); _x_assert( mant >= 0 && mant <= 7 ); *exp_out = exp; *mant_out = mant; } static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), word * xM, /* [0..12] IN */ word * xMc, /* [0..12] OUT */ word * mant_out, /* OUT */ word * exp_out, /* OUT */ word * xmaxc_out /* OUT */ ) { int i, itest; word xmax, xmaxc, temp, temp1, temp2; word exp, mant; /* Find the maximum absolute value xmax of xM[0..12]. */ xmax = 0; for (i = 0; i <= 12; i++) { temp = xM[i]; temp = GSM_ABS(temp); if (temp > xmax) xmax = temp; } /* Qantizing and coding of xmax to get xmaxc. */ exp = 0; temp = SASR( xmax, 9 ); itest = 0; for (i = 0; i <= 5; i++) { itest |= (temp <= 0); temp = SASR( temp, 1 ); _x_assert(exp <= 5); if (itest == 0) exp++; /* exp = add (exp, 1) */ } _x_assert(exp <= 6 && exp >= 0); temp = exp + 5; _x_assert(temp <= 11 && temp >= 0); xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); /* Quantizing and coding of the xM[0..12] RPE sequence * to get the xMc[0..12] */ APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); /* This computation uses the fact that the decoded version of xmaxc * can be calculated by using the exponent and the mantissa part of * xmaxc (logarithmic table). * So, this method avoids any division and uses only a scaling * of the RPE samples by a function of the exponent. A direct * multiplication by the inverse of the mantissa (NRFAC[0..7] * found in table 4.5) gives the 3 bit coded version xMc[0..12] * of the RPE samples. */ /* Direct computation of xMc[0..12] using table 4.5 */ _x_assert((exp <= 4096) && (exp >= -4096)); _x_assert((mant >= 0) && (mant <= 7)); temp1 = 6 - exp; /* normalization by the exponent */ temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ for (i = 0; i <= 12; i++) { _x_assert(temp1 >= 0 && temp1 < 16); temp = xM[i] << temp1; temp = GSM_MULT( temp, temp2 ); temp = SASR(temp, 12); xMc[i] = temp + 4; /* see note below */ } /* NOTE: This equation is used to make all the xMc[i] positive. */ *mant_out = mant; *exp_out = exp; *xmaxc_out = xmaxc; } /* 4.2.16 */ static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), register word * xMc, /* [0..12] IN */ word mant, word exp, register word * xMp) /* [0..12] OUT */ /* * This part is for decoding the RPE sequence of coded xMc[0..12] * samples to obtain the xMp[0..12] array. Table 4.6 is used to get * the mantissa of xmaxc (FAC[0..7]). */ { int i; word temp, temp1, temp2, temp3; longword ltmp; _x_assert((mant >= 0) && (mant <= 7)); temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); for (i = 13; i--;) { _x_assert((mant >= 0) && (mant <= 7)); _x_assert((*xMc <= 7) && (*xMc >= 0)); /* 3 bit unsigned */ /* temp = gsm_sub( *xMc++ << 1, 7 ); */ temp = (*xMc++ << 1) - 7; /* restore sign */ _x_assert((temp <= 7) && (temp >= -7)); /* 4 bit signed */ temp <<= 12; /* 16 bit signed */ temp = GSM_MULT_R( temp1, temp ); temp = GSM_ADD( temp, temp3 ); *xMp++ = gsm_asr( temp, temp2 ); } } /* 4.2.17 */ static void RPE_grid_positioning P3((Mc,xMp,ep), word Mc, /* grid position IN */ register word * xMp, /* [0..12] IN */ register word * ep /* [0..39] OUT */ ) /* * This procedure computes the reconstructed long term residual signal * ep[0..39] for the LTP analysis filter. The inputs are the Mc * which is the grid position selection and the xMp[0..12] decoded * RPE samples which are upsampled by a factor of 3 by inserting zero * values. */ { int i = 13; _x_assert((0 <= Mc) && (Mc <= 3)); switch (Mc) { case 3: *ep++ = 0; /* fall through */ case 2: do { *ep++ = 0; /* fall through */ case 1: *ep++ = 0; /* fall through */ case 0: *ep++ = *xMp++; } while (--i); } while (++Mc < 4) *ep++ = 0; /* int i, k; for (k = 0; k <= 39; k++) ep[k] = 0; for (i = 0; i <= 12; i++) { ep[ Mc + (3*i) ] = xMp[i]; } */ } /* 4.2.18 */ /* This procedure adds the reconstructed long term residual signal * ep[0..39] to the estimated signal dpp[0..39] from the long term * analysis filter to compute the reconstructed short term residual * signal dp[-40..-1]; also the reconstructed short term residual * array dp[-120..-41] is updated. */ #if 0 /* Has been inlined in code.c */ void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), word * dpp, /* [0...39] IN */ word * ep, /* [0...39] IN */ word * dp) /* [-120...-1] IN/OUT */ { int k; for (k = 0; k <= 79; k++) dp[ -120 + k ] = dp[ -80 + k ]; for (k = 0; k <= 39; k++) dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); } #endif /* Has been inlined in code.c */ void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), struct gsm_state * S, word * e, /* -5..-1][0..39][40..44 IN/OUT */ word * xmaxc, /* OUT */ word * Mc, /* OUT */ word * xMc) /* [0..12] OUT */ { word x[40]; word xM[13], xMp[13]; word mant, exp; (void)S; Weighting_filter(e, x); RPE_grid_selection(x, xM, Mc); APCM_quantization( xM, xMc, &mant, &exp, xmaxc); APCM_inverse_quantization( xMc, mant, exp, xMp); RPE_grid_positioning( *Mc, xMp, e ); } void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), struct gsm_state * S, word xmaxcr, word Mcr, word * xMcr, /* [0..12], 3 bits IN */ word * erp /* [0..39] OUT */ ) { word exp, mant; word xMp[ 13 ]; (void)S; APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); APCM_inverse_quantization( xMcr, mant, exp, xMp ); RPE_grid_positioning( Mcr, xMp, erp ); } xine-lib-1.2/contrib/gsm610/long_term.c0000644000175000017500000005633214647725151015503 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/long_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION */ /* * This module computes the LTP gain (bc) and the LTP lag (Nc) * for the long term analysis filter. This is done by calculating a * maximum of the cross-correlation function between the current * sub-segment short term residual signal d[0..39] (output of * the short term analysis filter; for simplification the index * of this array begins at 0 and ends at 39 for each sub-segment of the * RPE-LTP analysis) and the previous reconstructed short term * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be * performed to avoid overflow. */ /* The next procedure exists in six versions. First two integer * version (if USE_FLOAT_MUL is not defined); then four floating * point versions, twice with proper scaling (USE_FLOAT_MUL defined), * once without (USE_FLOAT_MUL and FAST defined, and fast run-time * option used). Every pair has first a Cut version (see the -C * option to toast or the LTP_CUT option to gsm_option()), then the * uncut one. (For a detailed explanation of why this is altogether * a bad idea, see Henry Spencer and Geoff Collyer, ``#ifdef Considered * Harmful''.) a */ #ifndef USE_FLOAT_MUL #ifdef LTP_CUT static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word wt[40]; longword L_result; longword L_max, L_power; word R, S, dmax, scal, best_k; word ltp_cut; register word temp, wt_k; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) { dmax = temp; best_k = k; } } temp = 0; if (dmax == 0) scal = 0; else { _x_assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; _x_assert(scal >= 0); /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ wt_k = SASR(d[best_k], scal); for (lambda = 40; lambda <= 120; lambda++) { L_result = (longword)wt_k * dp[best_k - lambda]; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ _x_assert((scal <= 100) && (scal >= -100)); L_max = L_max >> (6 - scal); /* sub(6, scal) */ _x_assert(Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word wt[40]; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { _x_assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; _x_assert(scal >= 0); /* Initialization of a working array wt */ for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda++) { # undef STEP # define STEP(k) (longword)wt[k] * dp[k - lambda] register longword L_result; L_result = STEP(0) ; L_result += STEP(1) ; L_result += STEP(2) ; L_result += STEP(3) ; L_result += STEP(4) ; L_result += STEP(5) ; L_result += STEP(6) ; L_result += STEP(7) ; L_result += STEP(8) ; L_result += STEP(9) ; L_result += STEP(10) ; L_result += STEP(11) ; L_result += STEP(12) ; L_result += STEP(13) ; L_result += STEP(14) ; L_result += STEP(15) ; L_result += STEP(16) ; L_result += STEP(17) ; L_result += STEP(18) ; L_result += STEP(19) ; L_result += STEP(20) ; L_result += STEP(21) ; L_result += STEP(22) ; L_result += STEP(23) ; L_result += STEP(24) ; L_result += STEP(25) ; L_result += STEP(26) ; L_result += STEP(27) ; L_result += STEP(28) ; L_result += STEP(29) ; L_result += STEP(30) ; L_result += STEP(31) ; L_result += STEP(32) ; L_result += STEP(33) ; L_result += STEP(34) ; L_result += STEP(35) ; L_result += STEP(36) ; L_result += STEP(37) ; L_result += STEP(38) ; L_result += STEP(39) ; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ _x_assert( (scal <= 100) && (scal >= -100)); L_max = L_max >> (6 - scal); /* sub(6, scal) */ _x_assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #else /* USE_FLOAT_MUL */ #ifdef LTP_CUT static void Cut_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, /* IN */ register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; word ltp_cut; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { _x_assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; _x_assert(scal >= 0); ltp_cut = (longword)SASR(dmax, scal) * st->ltp_cut / 100; /* Initialization of a working array wt */ for (k = 0; k < 40; k++) { register word w = SASR( d[k], scal ); if (w < 0 ? w > -ltp_cut : w < ltp_cut) { wt_float[k] = 0.0; } else { wt_float[k] = w; } } for (k = -120; k < 0; k++) dp_float[k] = dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ if ((W = wt_float[K]) != 0.0) { \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E; } else (a = lp[K]) # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ _x_assert( (scal <= 100) && (scal >= -100)); L_max = L_max >> (6 - scal); /* sub(6, scal) */ _x_assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; longword L_max, L_power; word R, S, dmax, scal; register word temp; /* Search of the optimum scaling of d[0..39]. */ dmax = 0; for (k = 0; k <= 39; k++) { temp = d[k]; temp = GSM_ABS( temp ); if (temp > dmax) dmax = temp; } temp = 0; if (dmax == 0) scal = 0; else { _x_assert(dmax > 0); temp = gsm_norm( (longword)dmax << 16 ); } if (temp > 6) scal = 0; else scal = 6 - temp; _x_assert(scal >= 0); /* Initialization of a working array wt */ for (k = 0; k < 40; k++) wt_float[k] = SASR( d[k], scal ); for (k = -120; k < 0; k++) dp_float[k] = dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ W = wt_float[K]; \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; L_max <<= 1; /* Rescaling of L_max */ _x_assert( (scal <= 100) && (scal >= -100)); L_max = L_max >> (6 - scal); /* sub(6, scal) */ _x_assert( Nc <= 120 && Nc >= 40); /* Compute the power of the reconstructed short term residual * signal dp[..] */ L_power = 0; for (k = 0; k <= 39; k++) { register longword L_temp; L_temp = SASR( dp[k - Nc], 3 ); L_power += L_temp * L_temp; } L_power <<= 1; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0; return; } if (L_max >= L_power) { *bc_out = 3; return; } temp = gsm_norm( L_power ); R = SASR( L_max << temp, 16 ); S = SASR( L_power << temp, 16 ); /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; *bc_out = bc; } #ifdef FAST #ifdef LTP_CUT static void Cut_Fast_Calculation_of_the_LTP_parameters P5((st, d,dp,bc_out,Nc_out), struct gsm_state * st, /* IN */ register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; register float wt_float; word Nc, bc; word wt_max, best_k, ltp_cut; float dp_float_base[120], * dp_float = dp_float_base + 120; register float L_result, L_max, L_power; wt_max = 0; for (k = 0; k < 40; ++k) { if ( d[k] > wt_max) wt_max = d[best_k = k]; else if (-d[k] > wt_max) wt_max = -d[best_k = k]; } _x_assert(wt_max >= 0); wt_float = (float)wt_max; for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda++) { L_result = wt_float * dp_float[best_k - lambda]; if (L_result > L_max) { Nc = lambda; L_max = L_result; } } *Nc_out = Nc; if (L_max <= 0.) { *bc_out = 0; return; } /* Compute the power of the reconstructed short term residual * signal dp[..] */ dp_float -= Nc; L_power = 0; for (k = 0; k < 40; ++k) { register float f = dp_float[k]; L_power += f * f; } if (L_max >= L_power) { *bc_out = 3; return; } /* Coding of the LTP gain * Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ lambda = L_max / L_power * 32768.; for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; *bc_out = bc; } #endif /* LTP_CUT */ static void Fast_Calculation_of_the_LTP_parameters P4((d,dp,bc_out,Nc_out), register word * d, /* [0..39] IN */ register word * dp, /* [-120..-1] IN */ word * bc_out, /* OUT */ word * Nc_out /* OUT */ ) { register int k, lambda; word Nc, bc; float wt_float[40]; float dp_float_base[120], * dp_float = dp_float_base + 120; register float L_max, L_power; for (k = 0; k < 40; ++k) wt_float[k] = (float)d[k]; for (k = -120; k < 0; ++k) dp_float[k] = (float)dp[k]; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0; Nc = 40; /* index for the maximum cross-correlation */ for (lambda = 40; lambda <= 120; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda; register float W; register float a = lp[-8], b = lp[-7], c = lp[-6], d = lp[-5], e = lp[-4], f = lp[-3], g = lp[-2], h = lp[-1]; register float E; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ W = wt_float[K]; \ E = W * a; S8 += E; \ E = W * b; S7 += E; \ E = W * c; S6 += E; \ E = W * d; S5 += E; \ E = W * e; S4 += E; \ E = W * f; S3 += E; \ E = W * g; S2 += E; \ E = W * h; S1 += E; \ a = lp[K]; \ E = W * a; S0 += E # define STEP_A(K) STEP(K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP(K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP(K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP(K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP(K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP(K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP(K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP(K, h, a, b, c, d, e, f, g) STEP_A( 0); STEP_B( 1); STEP_C( 2); STEP_D( 3); STEP_E( 4); STEP_F( 5); STEP_G( 6); STEP_H( 7); STEP_A( 8); STEP_B( 9); STEP_C(10); STEP_D(11); STEP_E(12); STEP_F(13); STEP_G(14); STEP_H(15); STEP_A(16); STEP_B(17); STEP_C(18); STEP_D(19); STEP_E(20); STEP_F(21); STEP_G(22); STEP_H(23); STEP_A(24); STEP_B(25); STEP_C(26); STEP_D(27); STEP_E(28); STEP_F(29); STEP_G(30); STEP_H(31); STEP_A(32); STEP_B(33); STEP_C(34); STEP_D(35); STEP_E(36); STEP_F(37); STEP_G(38); STEP_H(39); if (S0 > L_max) { L_max = S0; Nc = lambda; } if (S1 > L_max) { L_max = S1; Nc = lambda + 1; } if (S2 > L_max) { L_max = S2; Nc = lambda + 2; } if (S3 > L_max) { L_max = S3; Nc = lambda + 3; } if (S4 > L_max) { L_max = S4; Nc = lambda + 4; } if (S5 > L_max) { L_max = S5; Nc = lambda + 5; } if (S6 > L_max) { L_max = S6; Nc = lambda + 6; } if (S7 > L_max) { L_max = S7; Nc = lambda + 7; } if (S8 > L_max) { L_max = S8; Nc = lambda + 8; } } *Nc_out = Nc; if (L_max <= 0.) { *bc_out = 0; return; } /* Compute the power of the reconstructed short term residual * signal dp[..] */ dp_float -= Nc; L_power = 0; for (k = 0; k < 40; ++k) { register float f = dp_float[k]; L_power += f * f; } if (L_max >= L_power) { *bc_out = 3; return; } /* Coding of the LTP gain * Table 4.3a must be used to obtain the level DLB[i] for the * quantization of the LTP gain b to get the coded version bc. */ lambda = L_max / L_power * 32768.; for (bc = 0; bc <= 2; ++bc) if (lambda <= gsm_DLB[bc]) break; *bc_out = bc; } #endif /* FAST */ #endif /* USE_FLOAT_MUL */ /* 4.2.12 */ static void Long_term_analysis_filtering P6((bc,Nc,dp,d,dpp,e), word bc, /* IN */ word Nc, /* IN */ register word * dp, /* previous d [-120..-1] IN */ register word * d, /* d [0..39] IN */ register word * dpp, /* estimate [0..39] OUT */ register word * e /* long term res. signal [0..39] OUT */ ) /* * In this part, we have to decode the bc parameter to compute * the samples of the estimate dpp[0..39]. The decoding of bc needs the * use of table 4.3b. The long term residual signal e[0..39] * is then calculated to be fed to the RPE encoding section. */ { register int k; register longword ltmp; # undef STEP # define STEP(BP) \ for (k = 0; k <= 39; k++) { \ dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ e[k] = GSM_SUB( d[k], dpp[k] ); \ } switch (bc) { case 0: STEP( 3277 ); break; case 1: STEP( 11469 ); break; case 2: STEP( 21299 ); break; case 3: STEP( 32767 ); break; } } void Gsm_Long_Term_Predictor P7((S,d,dp,e,dpp,Nc,bc), /* 4x for 160 samples */ struct gsm_state * S, word * d, /* [0..39] residual signal IN */ word * dp, /* [-120..-1] d' IN */ word * e, /* [0..39] OUT */ word * dpp, /* [0..39] OUT */ word * Nc, /* correlation lag OUT */ word * bc /* gain factor OUT */ ) { _x_assert( d ); _x_assert( dp ); _x_assert( e ); _x_assert( dpp ); _x_assert( Nc ); _x_assert( bc ); #if defined(FAST) && defined(USE_FLOAT_MUL) if (S->fast) #if defined (LTP_CUT) if (S->ltp_cut) Cut_Fast_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); else #endif /* LTP_CUT */ Fast_Calculation_of_the_LTP_parameters(d, dp, bc, Nc ); else #else (void)S; #endif /* FAST & USE_FLOAT_MUL */ #ifdef LTP_CUT if (S->ltp_cut) Cut_Calculation_of_the_LTP_parameters(S, d, dp, bc, Nc); else #endif Calculation_of_the_LTP_parameters(d, dp, bc, Nc); Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); } /* 4.3.2 */ void Gsm_Long_Term_Synthesis_Filtering P5((S,Ncr,bcr,erp,drp), struct gsm_state * S, word Ncr, word bcr, register word * erp, /* [0..39] IN */ register word * drp /* [-120..-1] IN, [-120..40] OUT */ ) /* * This procedure uses the bcr and Ncr parameter to realize the * long term synthesis filtering. The decoding of bcr needs * table 4.3b. */ { register longword ltmp; /* for ADD */ register int k; word brp, drpp, Nr; /* Check the limits of Nr. */ Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; S->nrp = Nr; _x_assert(Nr >= 40 && Nr <= 120); /* Decoding of the LTP gain bcr */ brp = gsm_QLB[ bcr ]; /* Computation of the reconstructed short term residual * signal drp[0..39] */ _x_assert(brp != MIN_WORD); for (k = 0; k <= 39; k++) { drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); drp[k] = GSM_ADD( erp[k], drpp ); } /* * Update of the reconstructed short term residual signal * drp[ -1..-120 ] */ for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; } xine-lib-1.2/contrib/gsm610/gsm.h0000644000175000017500000000322414647725151014300 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ #ifndef GSM_H #define GSM_H #ifdef __cplusplus # define NeedFunctionPrototypes 1 #endif #if __STDC__ # define NeedFunctionPrototypes 1 #endif #ifdef _NO_PROTO # undef NeedFunctionPrototypes #endif #ifdef NeedFunctionPrototypes # include /* for FILE * */ #endif #undef GSM_P #if NeedFunctionPrototypes # define GSM_P( protos ) protos #else # define GSM_P( protos ) ( /* protos */ ) #endif /* * Interface */ typedef struct gsm_state * gsm; typedef short gsm_signal; /* signed 16 bit */ typedef unsigned char gsm_byte; typedef gsm_byte gsm_frame[33]; /* 33 * 8 bits */ #define GSM_MAGIC 0xD /* 13 kbit/s RPE-LTP */ #define GSM_PATCHLEVEL 10 #define GSM_MINOR 0 #define GSM_MAJOR 1 #define GSM_OPT_VERBOSE 1 #define GSM_OPT_FAST 2 #define GSM_OPT_LTP_CUT 3 #define GSM_OPT_WAV49 4 #define GSM_OPT_FRAME_INDEX 5 #define GSM_OPT_FRAME_CHAIN 6 extern gsm gsm_create GSM_P((void)); extern void gsm_destroy GSM_P((gsm)); extern int gsm_print GSM_P((FILE *, gsm, gsm_byte *)); extern int gsm_option GSM_P((gsm, int, int *)); extern void gsm_encode GSM_P((gsm, gsm_signal *, gsm_byte *)); extern int gsm_decode GSM_P((gsm, gsm_byte *, gsm_signal *)); extern int gsm_explode GSM_P((gsm, gsm_byte *, gsm_signal *)); extern void gsm_implode GSM_P((gsm, gsm_signal *, gsm_byte *)); #undef GSM_P #endif /* GSM_H */ xine-lib-1.2/contrib/gsm610/gsm_config.h0000644000175000017500000000260214647725151015624 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_config.h,v 1.2 2004/05/12 16:21:41 mroi Exp $*/ #ifndef CONFIG_H #define CONFIG_H /*efine SIGHANDLER_T int / * signal handlers are void */ /*efine HAS_SYSV_SIGNAL 1 / * sigs not blocked/reset? */ #define HAS_STDLIB_H 1 /* /usr/include/stdlib.h */ /*efine HAS_LIMITS_H 1 / * /usr/include/limits.h */ #define HAS_FCNTL_H 1 /* /usr/include/fcntl.h */ /*efine HAS_ERRNO_DECL 1 / * errno.h declares errno */ #define HAS_FSTAT 1 /* fstat syscall */ #define HAS_FCHMOD 1 /* fchmod syscall */ #define HAS_CHMOD 1 /* chmod syscall */ #define HAS_FCHOWN 1 /* fchown syscall */ #define HAS_CHOWN 1 /* chown syscall */ /*efine HAS__FSETMODE 1 / * _fsetmode -- set file mode */ #define HAS_STRING_H 1 /* /usr/include/string.h */ /*efine HAS_STRINGS_H 1 / * /usr/include/strings.h */ #define HAS_UNISTD_H 1 /* /usr/include/unistd.h */ #define HAS_UTIME 1 /* POSIX utime(path, times) */ /*efine HAS_UTIMES 1 / * use utimes() syscall instead */ #define HAS_UTIME_H 1 /* UTIME header file */ /*efine HAS_UTIMBUF 1 / * struct utimbuf */ /*efine HAS_UTIMEUSEC 1 / * microseconds in utimbuf? */ #endif /* CONFIG_H */ xine-lib-1.2/contrib/gsm610/short_term.c0000644000175000017500000002434714647725151015704 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/short_term.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "private.h" #include "gsm.h" #include "proto.h" /* * SHORT TERM ANALYSIS FILTERING SECTION */ /* 4.2.8 */ static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc,LARpp), word * LARc, /* coded log area ratio [0..7] IN */ word * LARpp) /* out: decoded .. */ { register word temp1 /* , temp2 */; register long ltmp; /* for GSM_ADD */ /* This procedure requires for efficient implementation * two tables. * * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) * MIC[1..8] = minimum value of the LARc[1..8] */ /* Compute the LARpp[1..8] */ /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { * * temp1 = GSM_ADD( *LARc, *MIC ) << 10; * temp2 = *B << 1; * temp1 = GSM_SUB( temp1, temp2 ); * * _x_assert(*INVA != MIN_WORD); * * temp1 = GSM_MULT_R( *INVA, temp1 ); * *LARpp = GSM_ADD( temp1, temp1 ); * } */ #undef STEP #define STEP( B, MIC, INVA ) \ temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ temp1 = GSM_SUB( temp1, B * 2 ); \ temp1 = GSM_MULT_R( INVA, temp1 ); \ *LARpp++ = GSM_ADD( temp1, temp1 ); STEP( 0, -32, 13107 ); STEP( 0, -32, 13107 ); STEP( 2048, -16, 13107 ); STEP( -2560, -16, 13107 ); STEP( 94, -8, 19223 ); STEP( -1792, -8, 17476 ); STEP( -341, -4, 31454 ); STEP( -1144, -4, 29708 ); /* NOTE: the addition of *MIC is used to restore * the sign of *LARc. */ } /* 4.2.9 */ /* Computation of the quantized reflection coefficients */ /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] */ /* * Within each frame of 160 analyzed speech samples the short term * analysis and synthesis filters operate with four different sets of * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) * and the actual set of decoded LARs (LARpp(j)) * * (Initial value: LARpp(j-1)[1..8] = 0.) */ static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); } } static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); } } static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), register word * LARpp_j_1, register word * LARpp_j, register word * LARp) { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); } } static void Coefficients_40_159 P2((LARpp_j, LARp), register word * LARpp_j, register word * LARp) { register int i; for (i = 1; i <= 8; i++, LARp++, LARpp_j++) *LARp = *LARpp_j; } /* 4.2.9.2 */ static void LARp_to_rp P1((LARp), register word * LARp) /* [0..7] IN/OUT */ /* * The input of this procedure is the interpolated LARp[0..7] array. * The reflection coefficients, rp[i], are used in the analysis * filter and in the synthesis filter. */ { register int i; register word temp; register longword ltmp; for (i = 1; i <= 8; i++, LARp++) { /* temp = GSM_ABS( *LARp ); * * if (temp < 11059) temp <<= 1; * else if (temp < 20070) temp += 11059; * else temp = GSM_ADD( temp >> 2, 26112 ); * * *LARp = *LARp < 0 ? -temp : temp; */ if (*LARp < 0) { temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); *LARp = - ((temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 ))); } else { temp = *LARp; *LARp = (temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 )); } } } /* 4.2.10 */ static void Short_term_analysis_filtering P4((S,rp,k_n,s), struct gsm_state * S, register word * rp, /* [0..7] IN */ register int k_n, /* k_end - k_start */ register word * s /* [0..n-1] IN/OUT */ ) /* * This procedure computes the short term residual signal d[..] to be fed * to the RPE-LTP loop from the s[..] signal and from the local rp[..] * array (quantized reflection coefficients). As the call of this * procedure can be done in many ways (see the interpolation of the LAR * coefficient), it is assumed that the computation begins with index * k_start (for arrays d[..] and s[..]) and stops with index k_end * (k_start and k_end are defined in 4.2.9.1). This procedure also * needs to keep the array u[0..7] in memory for each call. */ { register word * u = S->u; register int i; register word di, zzz, ui, sav, rpi; register longword ltmp; for (; k_n--; s++) { di = sav = *s; for (i = 0; i < 8; i++) { /* YYY */ ui = u[i]; rpi = rp[i]; u[i] = sav; zzz = GSM_MULT_R(rpi, di); sav = GSM_ADD( ui, zzz); zzz = GSM_MULT_R(rpi, ui); di = GSM_ADD( di, zzz ); } *s = di; } } #if defined(USE_FLOAT_MUL) && defined(FAST) static void Fast_Short_term_analysis_filtering P4((S,rp,k_n,s), struct gsm_state * S, register word * rp, /* [0..7] IN */ register int k_n, /* k_end - k_start */ register word * s /* [0..n-1] IN/OUT */ ) { register word * u = S->u; register int i; float uf[8], rpf[8]; register float scalef = 3.0517578125e-5; register float sav, di, temp; for (i = 0; i < 8; ++i) { uf[i] = u[i]; rpf[i] = rp[i] * scalef; } for (; k_n--; s++) { sav = di = *s; for (i = 0; i < 8; ++i) { register float rpfi = rpf[i]; register float ufi = uf[i]; uf[i] = sav; temp = rpfi * di + ufi; di += rpfi * ufi; sav = temp; } *s = di; } for (i = 0; i < 8; ++i) u[i] = uf[i]; } #endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ static void Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), struct gsm_state * S, register word * rrp, /* [0..7] IN */ register int k, /* k_end - k_start */ register word * wt, /* [0..k-1] IN */ register word * sr /* [0..k-1] OUT */ ) { register word * v = S->v; register int i; register word sri, tmp1, tmp2; register longword ltmp; /* for GSM_ADD & GSM_SUB */ while (k--) { sri = *wt++; for (i = 8; i--;) { /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); */ tmp1 = rrp[i]; tmp2 = v[i]; tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 + 16384) >> 15)) ; sri = GSM_SUB( sri, tmp2 ); /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); */ tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)sri + 16384) >> 15)) ; v[i+1] = GSM_ADD( v[i], tmp1); } *sr++ = v[0] = sri; } } #if defined(FAST) && defined(USE_FLOAT_MUL) static void Fast_Short_term_synthesis_filtering P5((S,rrp,k,wt,sr), struct gsm_state * S, register word * rrp, /* [0..7] IN */ register int k, /* k_end - k_start */ register word * wt, /* [0..k-1] IN */ register word * sr /* [0..k-1] OUT */ ) { register word * v = S->v; register int i; float va[9], rrpa[8]; register float scalef = 3.0517578125e-5, temp; for (i = 0; i < 8; ++i) { va[i] = v[i]; rrpa[i] = (float)rrp[i] * scalef; } while (k--) { register float sri = *wt++; for (i = 8; i--;) { sri -= rrpa[i] * va[i]; if (sri < -32768.) sri = -32768.; else if (sri > 32767.) sri = 32767.; temp = va[i] + rrpa[i] * sri; if (temp < -32768.) temp = -32768.; else if (temp > 32767.) temp = 32767.; va[i+1] = temp; } *sr++ = va[0] = sri; } for (i = 0; i < 9; ++i) v[i] = va[i]; } #endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ void Gsm_Short_Term_Analysis_Filter P3((S,LARc,s), struct gsm_state * S, word * LARc, /* coded log area ratio [0..7] IN */ word * s /* signal [0..159] IN/OUT */ ) { word * LARpp_j = S->LARpp[ S->j ]; word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; word LARp[8]; #undef FILTER #if defined(FAST) && defined(USE_FLOAT_MUL) # define FILTER (* (S->fast \ ? Fast_Short_term_analysis_filtering \ : Short_term_analysis_filtering )) #else # define FILTER Short_term_analysis_filtering #endif Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER( S, LARp, 13, s); Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 14, s + 13); Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 13, s + 27); Coefficients_40_159( LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 120, s + 40); } void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), struct gsm_state * S, word * LARcr, /* received log area ratios [0..7] IN */ word * wt, /* received d [0..159] IN */ word * s /* signal s [0..159] OUT */ ) { word * LARpp_j = S->LARpp[ S->j ]; word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; word LARp[8]; #undef FILTER #if defined(FAST) && defined(USE_FLOAT_MUL) # define FILTER (* (S->fast \ ? Fast_Short_term_synthesis_filtering \ : Short_term_synthesis_filtering )) #else # define FILTER Short_term_synthesis_filtering #endif Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt, s ); Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 14, wt + 13, s + 13 ); Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt + 27, s + 27 ); Coefficients_40_159( LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER(S, LARp, 120, wt + 40, s + 40); } xine-lib-1.2/contrib/gsm610/private.h0000644000175000017500000001721614647725151015172 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /*$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/private.h,v 1.1 2002/10/12 19:12:49 tmmm Exp $*/ #ifndef PRIVATE_H #define PRIVATE_H typedef short word; /* 16 bit signed int */ typedef long longword; /* 32 bit signed int */ typedef unsigned short uword; /* unsigned word */ typedef unsigned long ulongword; /* unsigned longword */ struct gsm_state { word dp0[ 280 ]; word z1; /* preprocessing.c, Offset_com. */ longword L_z2; /* Offset_com. */ int mp; /* Preemphasis */ word u[8]; /* short_term_aly_filter.c */ word LARpp[2][8]; /* */ word j; /* */ word ltp_cut; /* long_term.c, LTP crosscorr. */ word nrp; /* 40 */ /* long_term.c, synthesis */ word v[9]; /* short_term.c, synthesis */ word msr; /* decoder.c, Postprocessing */ char verbose; /* only used if !NDEBUG */ char fast; /* only used if FAST */ char wav_fmt; /* only used if WAV49 defined */ unsigned char frame_index; /* odd/even chaining */ unsigned char frame_chain; /* half-byte to carry forward */ }; #define MIN_WORD (-32767 - 1) #define MAX_WORD 32767 #define MIN_LONGWORD (-2147483647 - 1) #define MAX_LONGWORD 2147483647 #ifdef SASR /* flag: >> is a signed arithmetic shift right */ #undef SASR #define SASR(x, by) ((x) >> (by)) #else #define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by)))) #endif /* SASR */ #include "proto.h" /* * Prototypes from add.c */ extern word gsm_mult P((word a, word b)); extern longword gsm_L_mult P((word a, word b)); extern word gsm_mult_r P((word a, word b)); extern word gsm_div P((word num, word denum)); extern word gsm_add P(( word a, word b )); extern longword gsm_L_add P(( longword a, longword b )); extern word gsm_sub P((word a, word b)); extern longword gsm_L_sub P((longword a, longword b)); extern word gsm_abs P((word a)); extern word gsm_norm P(( longword a )); extern longword gsm_L_asl P((longword a, int n)); extern word gsm_asl P((word a, int n)); extern longword gsm_L_asr P((longword a, int n)); extern word gsm_asr P((word a, int n)); /* * Inlined functions from add.h */ /* * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) */ #define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) # define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ (SASR( ((longword)(a) * (longword)(b)), 15 )) # define GSM_L_MULT(a, b) /* word a, word b */ \ (((longword)(a) * (longword)(b)) << 1) # define GSM_L_ADD(a, b) \ ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ : ((b) <= 0 ? (a) + (b) \ : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ ? MAX_LONGWORD : utmp)) /* * # define GSM_ADD(a, b) \ * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) */ /* Nonportable, but faster: */ #define GSM_ADD(a, b) \ ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) # define GSM_SUB(a, b) \ ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) # define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) /* Use these if necessary: # define GSM_MULT_R(a, b) gsm_mult_r(a, b) # define GSM_MULT(a, b) gsm_mult(a, b) # define GSM_L_MULT(a, b) gsm_L_mult(a, b) # define GSM_L_ADD(a, b) gsm_L_add(a, b) # define GSM_ADD(a, b) gsm_add(a, b) # define GSM_SUB(a, b) gsm_sub(a, b) # define GSM_ABS(a) gsm_abs(a) */ /* * More prototypes from implementations.. */ extern void Gsm_Coder P(( struct gsm_state * S, word * s, /* [0..159] samples IN */ word * LARc, /* [0..7] LAR coefficients OUT */ word * Nc, /* [0..3] LTP lag OUT */ word * bc, /* [0..3] coded LTP gain OUT */ word * Mc, /* [0..3] RPE grid selection OUT */ word * xmaxc,/* [0..3] Coded maximum amplitude OUT */ word * xMc /* [13*4] normalized RPE samples OUT */)); extern void Gsm_Long_Term_Predictor P(( /* 4x for 160 samples */ struct gsm_state * S, word * d, /* [0..39] residual signal IN */ word * dp, /* [-120..-1] d' IN */ word * e, /* [0..40] OUT */ word * dpp, /* [0..40] OUT */ word * Nc, /* correlation lag OUT */ word * bc /* gain factor OUT */)); extern void Gsm_LPC_Analysis P(( struct gsm_state * S, word * s, /* 0..159 signals IN/OUT */ word * LARc)); /* 0..7 LARc's OUT */ extern void Gsm_Preprocess P(( struct gsm_state * S, word * s, word * so)); extern void Gsm_Encoding P(( struct gsm_state * S, word * e, word * ep, word * xmaxc, word * Mc, word * xMc)); extern void Gsm_Short_Term_Analysis_Filter P(( struct gsm_state * S, word * LARc, /* coded log area ratio [0..7] IN */ word * d /* st res. signal [0..159] IN/OUT */)); extern void Gsm_Decoder P(( struct gsm_state * S, word * LARcr, /* [0..7] IN */ word * Ncr, /* [0..3] IN */ word * bcr, /* [0..3] IN */ word * Mcr, /* [0..3] IN */ word * xmaxcr, /* [0..3] IN */ word * xMcr, /* [0..13*4] IN */ word * s)); /* [0..159] OUT */ extern void Gsm_Decoding P(( struct gsm_state * S, word xmaxcr, word Mcr, word * xMcr, /* [0..12] IN */ word * erp)); /* [0..39] OUT */ extern void Gsm_Long_Term_Synthesis_Filtering P(( struct gsm_state* S, word Ncr, word bcr, word * erp, /* [0..39] IN */ word * drp)); /* [-120..-1] IN, [0..40] OUT */ void Gsm_RPE_Decoding P(( struct gsm_state *S, word xmaxcr, word Mcr, word * xMcr, /* [0..12], 3 bits IN */ word * erp)); /* [0..39] OUT */ void Gsm_RPE_Encoding P(( struct gsm_state * S, word * e, /* -5..-1][0..39][40..44 IN/OUT */ word * xmaxc, /* OUT */ word * Mc, /* OUT */ word * xMc)); /* [0..12] OUT */ extern void Gsm_Short_Term_Synthesis_Filter P(( struct gsm_state * S, word * LARcr, /* log area ratios [0..7] IN */ word * drp, /* received d [0...39] IN */ word * s)); /* signal s [0..159] OUT */ extern void Gsm_Update_of_reconstructed_short_time_residual_signal P(( word * dpp, /* [0...39] IN */ word * ep, /* [0...39] IN */ word * dp)); /* [-120...-1] IN/OUT */ /* * Tables from table.c */ #ifndef GSM_TABLE_C extern const word gsm_A[8], gsm_B[8], gsm_MIC[8], gsm_MAC[8]; extern const word gsm_INVA[8]; extern const word gsm_DLB[4], gsm_QLB[4]; extern const word gsm_H[11]; extern const word gsm_NRFAC[8]; extern const word gsm_FAC[8]; #endif /* GSM_TABLE_C */ /* * Debugging */ #ifdef NDEBUG # define gsm_debug_words(a, b, c, d) /* nil */ # define gsm_debug_longwords(a, b, c, d) /* nil */ # define gsm_debug_word(a, b) /* nil */ # define gsm_debug_longword(a, b) /* nil */ #else /* !NDEBUG => DEBUG */ extern void gsm_debug_words P((char * name, int, int, word *)); extern void gsm_debug_longwords P((char * name, int, int, longword *)); extern void gsm_debug_longword P((char * name, longword)); extern void gsm_debug_word P((char * name, word)); #endif /* !NDEBUG */ #include "unproto.h" #endif /* PRIVATE_H */ xine-lib-1.2/contrib/gsm610/table.c0000644000175000017500000000434514647725151014601 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/table.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $ */ /* Most of these tables are inlined at their point of use. */ /* 4.4 TABLES USED IN THE FIXED POINT IMPLEMENTATION OF THE RPE-LTP * CODER AND DECODER * * (Most of them inlined, so watch out.) */ #define GSM_TABLE_C #include "private.h" #include "gsm.h" /* Table 4.1 Quantization of the Log.-Area Ratios */ /* i 1 2 3 4 5 6 7 8 */ const word gsm_A[8] = {20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036}; const word gsm_B[8] = { 0, 0, 2048, -2560, 94, -1792, -341, -1144}; const word gsm_MIC[8] = { -32, -32, -16, -16, -8, -8, -4, -4}; const word gsm_MAC[8] = { 31, 31, 15, 15, 7, 7, 3, 3}; /* Table 4.2 Tabulation of 1/A[1..8] */ const word gsm_INVA[8] = { 13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 }; /* Table 4.3a Decision level of the LTP gain quantizer */ /* bc 0 1 2 3 */ const word gsm_DLB[4] = { 6554, 16384, 26214, 32767 }; /* Table 4.3b Quantization levels of the LTP gain quantizer */ /* bc 0 1 2 3 */ const word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; /* Table 4.4 Coefficients of the weighting filter */ /* i 0 1 2 3 4 5 6 7 8 9 10 */ const word gsm_H[11] = {-134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 }; /* Table 4.5 Normalized inverse mantissa used to compute xM/xmax */ /* i 0 1 2 3 4 5 6 7 */ const word gsm_NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 }; /* Table 4.6 Normalized direct mantissa used to compute xM/xmax */ /* i 0 1 2 3 4 5 6 7 */ const word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; xine-lib-1.2/contrib/gsm610/gsm_create.c0000644000175000017500000000154114647725151015616 0ustar meme/* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ //static char const ident[] = "$Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/gsm_create.c,v 1.1 2002/10/12 19:12:49 tmmm Exp $"; #include "gsm_config.h" #ifdef HAS_STRING_H #include #else # include "proto.h" extern char * memset P((char *, int, int)); #endif #ifdef HAS_STDLIB_H # include #else # ifdef HAS_MALLOC_H # include # else extern char * malloc(); # endif #endif #include #include "gsm.h" #include "private.h" #include "proto.h" gsm gsm_create P0() { gsm r; r = (gsm)malloc(sizeof(struct gsm_state)); if (!r) return r; memset((char *)r, 0, sizeof(*r)); r->nrp = 40; return r; } xine-lib-1.2/README0000644000175000017500000000166514647725151011553 0ustar meme ---------------------- xine ---------------------- free multimedia xine-lib is a free multimedia engine, released under the GNU GPL. See COPYING for details. see the doc/ directory for more information about xine-lib. You will find various README files, FAQ and developer documentation (xine hacker's guide) there. Developers will find additional documentation for xine interfaces in the form of header file comments in the xine sources (for example the xine-lib API is documented in the include/xine.h header file). Individual frontends (e.g. xine-ui, gxine, totem, ...) may provide additional documentation in their packages. For more information on xine features (supported multimedia formats etc.) see the xine homepage, located at http://www.xine-project.org/ The xine-lib XML parser (src/xine-utils/xmlparser.[ch] and src/xine-utils/xmllexer.[ch]) is released under the GNU LGPL, see COPYING.LIB for details. xine-lib-1.2/README-VDPAU0000644000175000017500000000223214647725151012417 0ustar memeFAQ: Q: Why my file plays fine with mplayer-vdpau and not with xine-vdpau? A: We are not using the nvidia's libavcodec patch. We are writing decoders from scratch. So don't expect them to be as mature as ffmpeg ones. Not yet. Q: Why mpeg2 doesn't use less cpu than software decoder? A: Because at that moment it does a lot of memcpy. This will be fixed soon, but that's not a priority. Stability is our focus. Q: Is deinterlacing working? A: Yes. It's already quite good (doing 50i->50p), but could even be better in the future. Q: How do i get it working with VDR, Kaffeine, whatever. A: Ask VDR, Kaffeine, whatever developers. (Note: for kaffeine you are lucky, i'm going to tell you the tip. Build kaffeine like that: ./configure --without-xcb && make && make install) Q: How can i contact you? A: IRC: #xine-vdpau on freenode MAIL: http://lists.kafic.ba/mailman/listinfo/xine-vdpau Eventually, nvnews. Q: What information do I need if there's a problem? A: Run 'xine --verbose /path/to/a/working/sample' (or equivalent for your chosen front end). You will probably be asked for this anyway, so it helps to have it handy. xine-lib-1.2/configure.ac0000644000175000017500000020330214647725151013151 0ustar memeAC_PREREQ([2.59]) m4_include([m4/objc.m4]) dnl Note that autoconf/autoheader/automake cache using autom4te, so version.sh dnl will only be run if configure.ac has changed. This must be done before dnl AC_INIT so that XINE_VERSION_SPEC, which is an m4 macro, is available. m4_esyscmd([./version.sh]) dnl Initialize autoconf, autoheader, and automake AC_INIT([xine-lib],[XINE_VERSION_SPEC],[xine-bugs@lists.sourceforge.net]) AM_INIT_AUTOMAKE([1.11 -Wall]) AC_CONFIG_SRCDIR([src/xine-engine/xine.c]) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_LIBOBJ_DIR([lib]) AC_CONFIG_HEADERS([include/configure.h]) AM_MAINTAINER_MODE AM_SILENT_RULES([yes]) AH_TOP([#ifndef __XINE_LIB_CONFIG_H__ #define __XINE_LIB_CONFIG_H__ 1 ]) AH_BOTTOM([#ifdef ASMALIGN_1SLN # define ASMALIGN(ZEROBITS) ".align " #ZEROBITS "\n\t" #else # define ASMALIGN(ZEROBITS) ".align 1<<" #ZEROBITS "\n\t" #endif #endif /* __XINE_LIB_CONFIG_H__ */ ]) test x"$prefix" = x"NONE" && prefix="${ac_default_prefix}" test x"$exec_prefix" = x"NONE" && exec_prefix='${prefix}' dnl Use features of autoconf 2.61, but stay compatible with older versions. if test x"$datarootdir" = x""; then datarootdir='${datadir}' AC_SUBST(datarootdir) fi if test x"$docdir" = x""; then docdir='${datarootdir}/doc/${PACKAGE}' AC_SUBST(docdir) fi if test x"$htmldir" = x""; then htmldir='${docdir}' AC_SUBST(htmldir) fi dnl ------------------------- dnl Setup version information dnl ------------------------- dnl Do not change these manually; they come from running ./version.sh when dnl autoconf runs. This must all be done after AC_INIT is done, but running dnl the version.sh script must be done before AC_INIT. XINE_MAJOR=XINE_VERSION_MAJOR AC_SUBST(XINE_MAJOR) AC_DEFINE_UNQUOTED([XINE_MAJOR], [$XINE_MAJOR], [xine major version number]) XINE_MINOR=XINE_VERSION_MINOR AC_SUBST(XINE_MINOR) AC_DEFINE_UNQUOTED([XINE_MINOR], [$XINE_MINOR], [xine minor version number]) XINE_SUB=XINE_VERSION_SUB AC_SUBST(XINE_SUB) AC_DEFINE_UNQUOTED([XINE_SUB], [$XINE_SUB], [xine sub version number]) XINE_PATCH=XINE_VERSION_PATCH AC_SUBST(XINE_PATCH) AC_DEFINE_UNQUOTED([XINE_PATCH], [$XINE_PATCH], [xine patch version number]) XINE_SERIES=XINE_VERSION_SERIES AC_SUBST(XINE_SERIES) XINE_LT_CURRENT=__XINE_LT_CURRENT AC_SUBST(XINE_LT_CURRENT) AC_DEFINE_UNQUOTED(XINE_LT_CURRENT, $XINE_LT_CURRENT, [xine interface version number]) XINE_LT_REVISION=__XINE_LT_REVISION AC_SUBST(XINE_LT_REVISION) XINE_LT_AGE=__XINE_LT_AGE AC_SUBST(XINE_LT_AGE) AC_DEFINE_UNQUOTED(XINE_LT_AGE, $XINE_LT_AGE, [xine interface version age]) LIBNAME="libxine$(($XINE_LT_CURRENT-$XINE_LT_AGE))" AC_SUBST(LIBNAME) AC_DEFINE_UNQUOTED([XINE_TEXTDOMAIN], "$LIBNAME", [catalog message text domain]) dnl Always set flags to begin with -g so that debug information will be dnl included. In release bulids, this can be stripped out later if desired. dnl More importantly, it prevents autoconf from initializing the defaults to dnl include -O2, which is not desirable in a debug build, and it messes with dnl other optimizations that we'll want to be setting ourselves later. CFLAGS="-g $CFLAGS" CPPFLAGS="-D_REENTRANT -DXINE_COMPILE $CPPFLAGS" LDFLAGS="-g $LDFLAGS" OBJCFLAGS="-g $OBJCFLAGS" dnl ------------------------------ dnl Build modes: debug and profile dnl ------------------------------ AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug], [build with debugging code enabled])], [], [enable_debug="no"]) if test x"$enable_debug" != x"no"; then CPPFLAGS="-DDEBUG $CPPFLAGS" else CPPFLAGS="-DNDEBUG $CPPFLAGS" fi AM_CONDITIONAL([DEBUG_BUILD], [test x"$enable_debug" != x"no"]) AC_ARG_ENABLE([profiling], [AS_HELP_STRING([--enable-profiling], [build with profiling code enabled])], [], [enable_profiling="no"]) if test x"$enable_profiling" != x"no"; then CFLAGS="-pg $CFLAGS" OBJCFLAGS="-pg $OBJCFLAGS" LDFLAGS="-pg $LDFLAGS" fi AM_CONDITIONAL([PROFILING_BUILD], [test x"$enable_profiling" != x"no"]) AC_ARG_ENABLE([extra-warnings], [AS_HELP_STRING([--enable-extra-warnings], [build with extra warnings enabled])], [], [enable_extra_warnings="no"]) AC_ARG_ENABLE([asan], [AS_HELP_STRING([--enable-asan], [Compile with address sanitizer])]) dnl -------------- dnl Build features dnl -------------- AC_ARG_ENABLE([antialiasing], [AS_HELP_STRING([--enable-antialiasing], [enable font antialiasing])], [if test x"$enableval" != x"no"; then AC_DEFINE([ENABLE_ANTIALIASING], 1, [Define this to 1 to enable font antialising.]) fi]) dnl ---------------------------------------------- dnl Cross compilation, Mac OS X Universal Binaries dnl ---------------------------------------------- AC_CANONICAL_BUILD AC_CANONICAL_HOST dnl check for Mac OS X universal binary support early, because certain flags dnl must be set prior to looking for cc/libtool, etc. MACOSX_UNIVERSAL_BINARIES dnl Check to see if $host is empty. If it is, try $host_alias instead. dnl If $host is empty, it's because the user has run ./configure with a host dnl parameter unknown to config.sub. This used to be set in xv handling, but dnl it's also used in a bunch of other places unrelated to Xwindows support, dnl so if X is disabled, other things could go badly. host_or_hostalias="$host" test x"$host_or_hostalias" = x"" && host_or_hostalias="$host_alias" dnl ------------------- dnl checks for programs dnl ------------------- AC_PROG_CC AM_PROG_CC_C_O AC_GNU_SOURCE AC_SEARCH_LIBS([strerror],[cposix]) AC_PROG_OBJC CC_PROG_AS m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) AC_PROG_MAKE_SET AC_PROG_EGREP AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_AWK AC_PATH_PROG([PERL], [perl], [no]) if test "$PERL" = no; then AC_MSG_ERROR([perl not found]) fi AC_SUBST([PERL]) AC_CHECK_TOOL([STRINGS], [strings], [false]) PKG_PROG_PKG_CONFIG dnl --------------------------------------------- dnl Libtool dnl --------------------------------------------- AC_DISABLE_STATIC AC_PATH_MAGIC LT_INIT([dlopen win32-dll]) AC_PROG_LIBTOOL_SANITYCHECK dnl -------------------- dnl checks for libraries dnl -------------------- AM_ICONV AC_ARG_ENABLE([iconvtest], [AS_HELP_STRING([--disable-iconvtest], [don't require iconv library])]) if test x"$enable_iconvtest" != x"no"; then if test x"$am_cv_func_iconv" != x"yes"; then AC_MSG_ERROR([ **************************************************************** * iconv library not found. It's necessary for proper * * manipulation with texts so xine requires it as default. * * * * You need to install iconv library or to specify prefix * * by option --with-libiconv-prefix. * * * * If you don't want iconv support use the option * * --disable-iconvtest. * **************************************************************** ]) fi fi AM_GNU_GETTEXT([external]) AM_GNU_GETTEXT_VERSION([0.18.3]) AC_PROG_GMSGFMT_PLURAL AC_CHECK_LIB([c], [dlopen], [DYNAMIC_LD_LIBS=""], [AC_CHECK_LIB([dl], [dlopen], [DYNAMIC_LD_LIBS="-ldl"], [AC_MSG_CHECKING(for dlopen under win32) AC_LANG_PUSH([C]) ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="-I${srcdir}/win32/include $CPPFLAGS" ac_save_LIBS="$LIBS" LIBS="$LIBS -lkernel32" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[dlopen(NULL, 0)]])], [DYNAMIC_LD_LIBS="-lkernel32" AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) CPPFLAGS="$ac_save_CPPFLAGS" LIBS="$ac_save_LIBS" AC_LANG_POP([C])], [AC_MSG_ERROR([dynamic linker needed])])]) AC_SUBST([DYNAMIC_LD_LIBS]) AC_ARG_WITH([external-libxdg-basedir], [AS_HELP_STRING([--without-external-libxdg-basedir], [use internal copy of libxdg-basedir])]) have_xdg_basedir=no if test x"$with_external_libxdg_basedir" != x"no"; then PKG_CHECK_MODULES([XDG_BASEDIR], [libxdg-basedir >= 1], [have_xdg_basedir=yes], [have_xdg_basedir=no]) if test x"$have_xdg_basedir" = x"no" -a x"$with_external_libxdg_basedir" = x"yes"; then AC_MSG_ERROR([--with-external-libxdg-basedir used but no libxdg-basedir found]) fi fi if test x"$have_xdg_basedir" = xyes; then XDG_BASEDIR_REQUIRES="libxdg-basedir" else XDG_BASEDIR_CPPFLAGS='-I$(top_srcdir)/contrib/libxdg-basedir' XDG_BASEDIR_LIBS='$(top_builddir)/contrib/libxdg-basedir/libxdg-basedir.la' XDG_BASEDIR_DEPS='$(top_builddir)/contrib/libxdg-basedir/libxdg-basedir.la' fi AC_SUBST([XDG_BASEDIR_REQUIRES]) AC_SUBST([XDG_BASEDIR_CPPFLAGS]) AC_SUBST([XDG_BASEDIR_LIBS]) AC_SUBST([XDG_BASEDIR_DEPS]) AM_CONDITIONAL([EXTERNAL_LIBXDG_BASEDIR], [test x"$have_xdg_basedir" = xyes]) dnl Test for socket and network support library AC_CHECK_LIB([socket], [socket], [NET_LIBS="-lsocket $NET_LIBS"]) AC_CHECK_LIB([nsl], [gethostbyname], [NET_LIBS="-lnsl $NET_LIBS"]) AC_CHECK_LIB([resolv], [hstrerror], [NET_LIBS="-lresolv $NET_LIBS"]) AC_SUBST(NET_LIBS) WINE_LIBS="" AC_CHECK_LIB(i386, i386_set_ldt, WINE_LIBS="-li386 $WINE_LIBS",) AC_SUBST(WINE_LIBS) AC_CHECK_LIB([rt], [clock_getres], [RT_LIBS="-lrt" AC_DEFINE(HAVE_POSIX_TIMERS, 1, [Define this if you have POSIX timers.])], [AC_MSG_RESULT([*** no POSIX timers available.])]) AC_SUBST(RT_LIBS) AC_CHECK_LIB([posix4], [sched_get_priority_min]) AC_CHECK_LIB([kstat], [kstat_open], [KSTAT_LIBS=-lkstat AC_DEFINE([HAVE_KSTAT], 1, [Define this if you have kernel statistics available via kstat interface])]) AC_SUBST(KSTAT_LIBS) AC_ARG_WITH([zlib-prefix], [AS_HELP_STRING([--with-zlib-prefix=PREFIX], [path to zlib compression library])], [if test x"$withval" != x"no"; then ZLIB_CPPFLAGS="-I$withval/include" ZLIB_LIBS="-L$withval/lib" fi]) AC_CHECK_LIB([z], [gzsetparams], [ZLIB_LIBS="$ZLIB_LIBS -lz" ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $ZLIB_CPPFLAGS" AC_CHECK_HEADER([zlib.h], [have_zlib=yes], [have_zlib=no]) CPPFLAGS="$ac_save_CPPFLAGS"], [have_zlib=no], ["$ZLIB_LIBS"]) test x"$have_zlib" != x"yes" && AC_MSG_ERROR(zlib needed) AC_SUBST(ZLIB_CPPFLAGS) AC_SUBST(ZLIB_LIBS) dnl FreeType2 (optional; disabled by default) AC_ARG_WITH([freetype], [AS_HELP_STRING([--with-freetype], [Build with FreeType2 library])], [], [with_freetype=no]) if test x"$with_freetype" != x"no"; then PKG_CHECK_MODULES([FT2], [freetype2], [have_freetype=yes], [have_freetype=no]) if test x"$have_freetype" = x"no"; then AC_MSG_ERROR([FreeType2 support requested but FreeType2 library not found]) elif test x"$have_freetype" = x"yes"; then AC_DEFINE([HAVE_FT2], 1, [Define this if you have freetype2 library]) fi fi dnl fontconfig (optional; disabled by default) AC_ARG_WITH([fontconfig], [AS_HELP_STRING([--with-fontconfig], [Build with fontconfig library])], [], [with_fontconfig=no]) if test x"$with_fontconfig" = x"yes"; then if test x"$have_freetype" != x"yes"; then AC_MSG_ERROR([fontconfig support requested, but FreeType2 not enabled.]) fi PKG_CHECK_MODULES([FONTCONFIG], [fontconfig], [have_fontconfig=yes], [have_fontconfig=no]) if test x"$have_fontconfig" = x"no"; then AC_MSG_ERROR([fontconfig support requested but fontconfig library not found]) elif test x"$have_fontconfig" = x"yes"; then AC_DEFINE([HAVE_FONTCONFIG], 1, [Define this if you have fontconfig library]) fi fi dnl ----------------------- dnl checks for header files dnl ----------------------- AC_CHECK_HEADERS([alloca.h]) AC_CHECK_HEADERS([assert.h byteswap.h dirent.h errno.h execinfo.h fcntl.h glob.h]) AC_CHECK_HEADERS([libgen.h malloc.h netdb.h pwd.h stdbool.h strings.h ucontext.h]) AC_CHECK_HEADERS([sys/ioctl.h sys/mixer.h sys/mman.h sys/param.h sys/socket.h sys/times.h sys/wait.h sys/sysmacros.h]) AC_CHECK_HEADERS([arpa/inet.h netinet/in.h]) dnl cdrom ioctls (common for dvdnav and vcd) case "$host_os" in linux*) AC_CHECK_HEADERS([linux/cdrom.h], [AC_DEFINE([HAVE_LINUX_CDROM], 1, [Define 1 if you have Linux-type CD-ROM support]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct cdrom_generic_command test; int has_timeout = sizeof(test.timeout);]])], [AC_DEFINE([HAVE_LINUX_CDROM_TIMEOUT], [1], [Define 1 if timeout is in cdrom_generic_command struct])])]) ;; esac AC_CHECK_HEADERS([sys/dvdio.h sys/cdio.h sys/scsiio.h]) dnl ---------------------------------------------- dnl Check for NetBSD DTV headers dnl ---------------------------------------------- AC_CHECK_HEADERS([dev/dtv/dtvio.h]) dnl ---------------- dnl checks for types dnl ---------------- AC_TYPE_OFF_T AC_TYPE_SIZE_T AC_CHECK_SIZEOF([int]) AC_CHECK_SIZEOF([long]) AC_CHECK_GENERATE_INTTYPES([include]) AM_CONDITIONAL([GENERATED_INTTYPES_H], [test "x$ac_cv_header_inttypes_h" != x"yes"]) AC_CHECK_TYPE([ssize_t], [], [AC_DEFINE([ssize_t], [__int64], [define ssize_t to __int64 if it's missing in default includes])]) AC_CHECK_SOCKLEN_T AC_CACHE_CHECK([type of request parameter for ioctl()], [ac_cv_ioctl_request], [ for ac_ioctl_request_type in "unsigned long" "int"; do AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include int ioctl(int fd, $ac_ioctl_request_type request, ...);]], [[]])], [ac_cv_ioctl_request=$ac_ioctl_request_type], []) done if test x"$ac_cv_ioctl_request" = x""; then AC_MSG_ERROR([Unable to determine the type for ioctl() request parameter]) fi ]) AC_DEFINE_UNQUOTED([IOCTL_REQUEST_TYPE], [$ac_cv_ioctl_request], [Type of the request parameter for ioctl()]) case "$host_os" in linux*) AC_DEFINE([HAVE_ZERO_SAFE_MEM], 1, [Define to 1 if clear mem interpretes as 0, 0f or NULL safely.]) ;; esac dnl --------------------- dnl checks for structures dnl --------------------- AC_CHECK_MEMBER([struct tm.tm_gmtoff], [AC_DEFINE([HAVE_TM_GMTOFF], 1, [Define if struct tm has the tm_gmtoff member.])], [], [#include ]) dnl ----------------------------------- dnl checks for compiler characteristics dnl ----------------------------------- if test x"$GCC" = x"yes"; then GCC_VERSION="`$CC -dumpversion`" GCC_VERSION_MAJOR="`echo "$GCC_VERSION" | cut -d '.' -f1`" GCC_VERSION_MINOR="`echo "$GCC_VERSION" | cut -d '.' -f2`" GCC_VERSION_PATCHLEVEL="`echo "$GCC_VERSION" | cut -d '.' -f3`" fi CC_CHECK_WERROR CC_PTHREAD_FLAGS([], [AC_MSG_ERROR([Pthread support is needed])]) CC_PTHREAD_RECURSIVE_MUTEX([], [AC_MSG_ERROR([recursive mutex support is needed - please report])]) dnl is implicitly included by xine-internals.h, so the include dir is needed everywhere CPPFLAGS="$CPPFLAGS $PTHREAD_CFLAGS" dnl REVISIT: AC_C_ALWAYS_INLINE removal allows ffmpeg to be more widely buildable AC_C_BIGENDIAN AC_C_CONST AC_C_INLINE AC_C_RESTRICT dnl empty_array_size - src/input/vcd AC_MSG_CHECKING([how to create empty arrays]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[struct { int foo; int bar[]; } baz]])], [empty_array_size=""], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[struct { int foo; int bar[0]; } baz]])], [empty_array_size="0"], [AC_MSG_ERROR([compiler is unable to create empty arrays])])]) AC_DEFINE_UNQUOTED([EMPTY_ARRAY_SIZE], [$empty_array_size], [what to put between the brackets for empty arrays]) AC_MSG_RESULT([[[$empty_array_size]]]) dnl ISOC99_PRAGMA - src/input/vcd/libvcd AC_MSG_CHECKING([whether $CC supports ISOC99 _Pragma()]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[_Pragma("pack(1)")]])], [ISOC99_PRAGMA=yes AC_DEFINE([HAVE_ISOC99_PRAGMA], [], [Supports ISO _Pragma() macro])], [ISOC99_PRAGMA=no]) AC_MSG_RESULT([$ISOC99_PRAGMA]) dnl ASM ALIGN is power of two ? dnl src/post/planar AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[asm(".align 3");]])], [AC_DEFINE([ASMALIGN_1SLN], [1], [define if '.align n' means alignment to (1 << n) - byte boundaries])]) dnl avx instruction set support AC_MSG_CHECKING([for AVX assembler]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[asm("vmovaps %ymm1, %ymm0");]])], [AC_DEFINE([HAVE_AVX], [1], [define if compiler supports avx inline assembler]) AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no)]) CC_ATTRIBUTE_ALIGNED CC_ATTRIBUTE_VISIBILITY([protected], [visibility_export="protected"], [CC_ATTRIBUTE_VISIBILITY([default], [visibility_export="default"])]) CC_ATTRIBUTE_VISIBILITY([internal]) if test x"$visibility_export" != x""; then CC_FLAG_VISIBILITY([VISIBILITY_FLAG="-fvisibility=hidden" EXPORTED='__attribute__((visibility("default")))']) fi AC_DEFINE_UNQUOTED([EXPORTED], [$EXPORTED], [Mark a symbol as being exported if visibility is changed]) AC_SUBST([VISIBILITY_FLAG]) CC_ATTRIBUTE_SENTINEL CC_ATTRIBUTE_FORMAT CC_ATTRIBUTE_FORMAT_ARG CC_ATTRIBUTE_DEPRECATED CC_ATTRIBUTE_UNUSED CC_ATTRIBUTE_MALLOC CC_ATTRIBUTE_WEAK CC_ATTRIBUTE_WARN_UNUSED_RESULT CC_ATTRIBUTE_PACKED([], [AC_MSG_WARN([Your compiler doesn't support __attribute__((packed)); xine might not work as expected.])]) CC_ATTRIBUTE_CONST CC_CHECK_CFLAGS([-pipe], [miscflags="$miscflags -pipe"]) dnl Set warning flags for warnings that we do not want to skip. In all cases, dnl these warnings should be enabled. Set these into CFLAGS and OBJCFLAGS dnl later after all testing is done. CC_CHECK_CFLAGS([-Wall], [warnflags="$warnflags -Wall"]) if test x"$enable_extra_warnings" = x"yes"; then CC_CHECK_CFLAGS([-Wextra], [warnflags="$warnflags -Wextra"]) fi CC_CHECK_CFLAGS([-Wformat=2], [wformat="-Wformat=2"], [CC_CHECK_CFLAGS([-Wformat], [wformat="-Wformat"])]) if test x"$wformat" != x""; then CC_CHECK_CFLAGS([-Wno-format-zero-length], [wformat="$wformat -Wno-format-zero-length"]) fi CC_CHECK_CFLAGS([-Wmissing-format-attribute], [wformat="$wformat -Wmissing-format-attribute"]) warnflags="$warnflags $wformat" dnl WARNING: This warning flag, if set into CFLAGS now, can break some autoconf tests. CC_CHECK_CFLAGS([-Werror-implicit-function-declaration], [warnflags="$warnflags -Werror-implicit-function-declaration"]) CC_CHECK_CFLAGS([-Wstrict-aliasing=2], [warnflags="$warnflags -Wstrict-aliasing=2"], [CC_CHECK_CFLAGS([-Wstrict-aliasing], [warnflags="$warnflags -Wstrict-aliasing"])]) CC_CHECK_CFLAGS([-Wchar-subscripts], [warnflags="$warnflags -Wchar-subscripts"]) CC_CHECK_CFLAGS([-Wmissing-declarations], [warnflags="$warnflags -Wmissing-declarations"]) CC_CHECK_CFLAGS([-Wmissing-prototypes], [warnflags="$warnflags -Wmissing-prototypes"]) CC_CHECK_CFLAGS([-Wwrite-strings], [warnflags="$warnflags -Wwrite-strings"]) dnl Some combinations of gcc and glibc produce useless warnings on memset when dnl compiling with -Wpointer-arith, so check for this first. AC_MSG_CHECKING([for sane -Wpointer-arith]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int a; memset(&a, 0, sizeof(int))]])], [warnflags="$warnflags -Wpointer-arith" AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) CC_CHECK_LDFLAGS([-Wl,--gc-sections], [GCSECTIONS="-Wl,--gc-sections"]) AC_SUBST([GCSECTIONS]) dnl FreeBSD (et al.) does not complete linking for shared objects when pthreads dnl are requested, as different implementations are present; to avoid problems dnl use -Wl,-z,defs only for those platforms not behaving this way. case "$host_or_hostalias" in *-freebsd*) ;; dnl check if we are using the cygwin, mingw or cygwin with mno-cygwin mode dnl in which case we are actually dealing with a mingw32 compiler dnl This cannot be done until AC_PROG_EGREP and AC_PROG_CC are both done. *-*-mingw* | *-*-cygwin*) CC_CHECK_LDFLAGS([-Wl,-z,defs], [NOUNDEF="-Wl,-z,defs"]) case "$host_or_hostalias" in *-*-mingw32*) WIN32_SYS=mingw32 ;; *-*-cygwin*) AC_EGREP_CPP([yes], [#ifdef WIN32 yes #endif], [WIN32_SYS=mingw32], [WIN32_SYS=cygwin]) ;; esac if test "$WIN32_SYS" = "mingw32"; then WIN32_INCLUDES='-I$(top_srcdir)/win32/include' LIBS="-lwinmm -lwsock32 $LIBS" LDFLAGS="-Wl,--enable-stdcall-fixup $LDFLAGS" dnl iberty has been needed only in older versions AC_CHECK_LIB(iberty, strncomp, [GOOM_LIBS="-liberty"]) AC_SUBST(GOOM_LIBS) fi ;; *) CC_CHECK_LDFLAGS([-Wl,-z,defs], [NOUNDEF="-Wl,-z,defs"]) ;; esac AC_SUBST(NOUNDEF) AM_CONDITIONAL([WIN32], [test x"$WIN32_SYS" = x"mingw32"]) AC_ARG_ENABLE([altivec], [AS_HELP_STRING([--disable-altivec], [do not use assembly codes for Motorola 74xx CPUs])], [], [enable_altivec="yes"]) dnl No optimization at all. For gcc, this is the optimization level. O0_CFLAGS="-O0" dnl Lowest level of optimization. For gcc, this enables: dnl -fdefer-pop -fdelayed-branch -fguess-branch-probability -fcprop-registers dnl -floop-optimize -fif-conversion -fif-conversion2 -ftree-ccp -ftree-dce dnl -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-ter -ftree-lrs dnl -ftree-sra -ftree-copyrename -ftree-fre -ftree-ch -fmerge-constants dnl On platforms where -fomit-frame-pointer does not interfere with debugging, dnl it is also enabled by -O1. O1_CFLAGS="-O1" dnl Middle level of optimization. For gcc, this enables -O1 and: dnl -fthread-jumps -fcrossjumping -foptimize-sibling-calls -fcse-follow-jumps dnl -fcse-skip-blocks -fgcse -fgcse-lm -fexpensive-optimizations dnl -fstrength-reduce -frerun-cse-after-loop -frerun-loop-opt -fcaller-saves dnl -fforce-mem -fpeephole2 -fschedule-insns -fschedule-insns2 dnl -fsched-interblock -fsched-spec -fregmove -fstrict-aliasing dnl -fdelete-null-pointer-checks -freorder-blocks -freorder-functions dnl -funit-at-a-time -falign-functions -falign-jumps -falign-loops dnl -falign-labels -ftree-pre dnl Note that Apple's version of gcc differs slightly, because it does not enable dnl -fstrict-aliasing -freorder-blocks -fsched-interblock O2_CFLAGS="-O2" dnl Highest level of optimization. For gcc, this enables -O2 and: dnl -finline-functions -funswitch-loops -fgcse-after-reload O3_CFLAGS="-O3" dnl gcc 3.3.5 (at least) is known to be buggy wrt optimization with dnl -finline-functions, so use -fno-inline-functions for gcc < 3.4.0 if test x"$GCC" = x"yes"; then if test "$GCC_VERSION_MAJOR" -lt 3; then O3_CFLAGS="$O3_CFLAGS -fno-inline-functions" else if test "$GCC_VERSION_MAJOR" -eq 3 -a "$GCC_VERSION_MINOR" -lt 4; then O3_CFLAGS="$O3_CFLAGS -fno-inline-functions" fi fi fi CC_CHECK_CFLAGS([-fexpensive-optimizations], [optflags="$optflags -fexpensive-optimizations"]) dnl HACK -- BETTER FIX WANTED!! dnl Static archives (lib.a) work whan building an executable, but may not work when building a dnl shared library (eg newer x86-64). Try to force a dynamic external lib at least where we have an dnl internal fallback. First, test whether the linker understands -l:FILENAME. my_shared_lib_prefix="" my_shared_lib_postfix="" AC_CHECK_LIB([:libz.so], [inflateEnd], [my_shared_lib_prefix=":lib"; my_shared_lib_postfix=".so"]) AC_DEFUN([MY_SHARED_LIB_NAME], ["$my_shared_lib_prefix""$1""$my_shared_lib_postfix"]) dnl __builtin_expect AC_MSG_CHECKING([for __builtin_expect]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include ]],[[ const char *s = "this is a test."; if (__builtin_expect ((uintptr_t)s & 3, 0)) printf ("string is unaligned.\n"); ]])], [my_builtin_expect=yes], [my_builtin_expect=no]) AC_MSG_RESULT([$my_builtin_expect]) if test x"$my_builtin_expect" = x"yes" ; then AC_DEFINE([TEST_LIKELY(_test,_likely_result)],[__builtin_expect (_test, _likely_result)],[Define to a working __builtin_expect.]) else AC_DEFINE([TEST_LIKELY(_test,_likely_result)],[(_test)],[Define to a working __builtin_expect.]) fi dnl __builtin_assume_aligned AC_MSG_CHECKING([for available __builtin_assume_aligned arguments]) my_builtin_assume_aligned_args=0 AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ const char *s = "this is a test."; int *i = __builtin_assume_aligned (s - ((uintptr_t)s & 3), 4); ]])], [my_builtin_assume_aligned_args=2], [my_builtin_assume_aligned_args=0]) if test $my_builtin_assume_aligned_args -gt 1 ; then AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ const char *s = "this is a test."; int *i = __builtin_assume_aligned (s - ((uintptr_t)s & 3), 8, 4); ]])], [my_builtin_assume_aligned_args=3], []) fi AC_MSG_RESULT([$my_builtin_assume_aligned_args]) if test $my_builtin_assume_aligned_args -gt 1 ; then AC_DEFINE([ASSUME_ALIGNED_2(_ptr,_align)],[__builtin_assume_aligned (_ptr, _align)], [Define to a __builtin_assume_aligned with 2 args.]) else AC_DEFINE([ASSUME_ALIGNED_2(_ptr,_align)],[(_ptr)], [Define to a __builtin_assume_aligned with 2 args.]) fi if test $my_builtin_assume_aligned_args -gt 2 ; then AC_DEFINE([ASSUME_ALIGNED_3(_ptr,_align,_offs)],[__builtin_assume_aligned (_ptr, _align, _offs)], [Define to a __builtin_assume_aligned with 3 args.]) else AC_DEFINE([ASSUME_ALIGNED_3(_ptr,_align,_offs)],[(_ptr)], [Define to a __builtin_assume_aligned with 3 args.]) fi dnl MY_CHECK_CPP_DEFINED - Check for a single (pre)#defined cpp macro. dnl Usage: MY_CHECK_CPP_DEFINED([name], [action-if-defined], [action-if-not-defined]) AC_DEFUN([MY_CHECK_CPP_DEFINED], [ AC_CACHE_CHECK( [whether cpp macro $1 is defined], AS_TR_SH([my_cv_cpp_defined_$1]), [AC_COMPILE_IFELSE( [AC_LANG_PROGRAM([ #ifndef $1 #error $1 is not defined! #endif ])], [eval "AS_TR_SH([my_cv_cpp_defined_$1])=yes"], [eval "AS_TR_SH([my_cv_cpp_defined_$1])=no"] )] ) if eval test [x$]AS_TR_SH([my_cv_cpp_defined_$1]) = xyes; then ifelse([$2], , [:], [$2]) else ifelse([$3], , [:], [$3]) fi ]) dnl MY_X86_DEFAULT_ARCH - Check for compler default x86 architecture. dnl Sets x86_default_arch to either "32", "x32" or "64". AC_DEFUN([MY_X86_DEFAULT_ARCH], [ MY_CHECK_CPP_DEFINED([__i386], [x86_default_arch=32], [ MY_CHECK_CPP_DEFINED([__i386__], [x86_default_arch=32], [ MY_CHECK_CPP_DEFINED([__ILP32__], [x86_default_arch=x32], [x86_default_arch=64]) ])])]) dnl initialize arch_86 as it is later tested for != "no" arch_x86=no case "$host_or_hostalias" in alphaev56-*) cpuflags="-mcpu=ev56 -mieee $cpuflags" AC_DEFINE([ARCH_ALPHA], [], [Define this if you're running Alpha architecture]) ;; alpha*) cpuflags="-mieee $cpuflags" AC_DEFINE([ARCH_ALPHA], [], [Define this if you're running Alpha architecture]) ;; armv4l-*-linux*) cpuflags="-mcpu=strongarm1100 -ffast-math -fsigned-char $cpuflags" DEFAULT_OCFLAGS="O2_CFLAGS" AC_DEFINE([ARCH_ARM], [], [Define this if you're running ARM architecture]) ;; sparc*-*-linux*) case "`uname -m`" in sparc) cpuflags="-mcpu=supersparc -mtune=supersparc" ;; sparc64) cpuflags="-mcpu=ultrasparc -mtune=ultrasparc" ;; esac test x"$enable_vis" != x"no" && has_vis=yes AC_DEFINE([ARCH_SPARC], [], [Define this if you're running SPARC architecture]) ;; sparc-*-solaris*) if test x"$GCC" = x"yes"; then case "`uname -m`" in sun4c) cpuflags="-mcpu=v7 -mtune=supersparc" ;; sun4m) cpuflags="-mcpu=v8 -mtune=supersparc" ;; sun4u) if test x"$GCC_VERSION_MAJOR" -lt 3; then # -mcpu=ultrasparc triggers a GCC 2.95.x compiler bug # when compiling video_out.c: # gcc: Internal compiler error: program cc1 got fatal signal 11 # avoid -mcpu=ultrasparc with gcc 2.* cpuflags="-mcpu=v8 -mtune=ultrasparc" else cpuflags="-mcpu=ultrasparc -mtune=ultrasparc" fi ;; esac if test "$GCC_VERSION_MAJOR" -ge 3; then test x"$enable_vis" != x"no" && has_vis=yes fi else case "`uname -m`" in sun4c) cpuflags="-xarch=v7" ;; sun4m) cpuflags="-xarch=v8" ;; sun4u) cpuflags="-xarch=v8plusa" ;; esac O1_CFLAGS="-fast -xCC" O2_CFLAGS="$O1_CFLAGS" O3_CFLAGS="$O1_CFLAGS" fi AC_DEFINE([ARCH_SPARC], [], [Define this if you're running SPARC architecture]) ;; x86_64-*gnux32*) dnl optional build with fast 64 bit code but usable by 32 bit applications directly. dnl requires x86 64bit, x32 kernel support, gcc 4.7+ and x32 system headers. should we test for these first? arch_x86=x32 cpuflags="$cpuflags -mx32" AC_DEFINE([ARCH_X86_X32], [], [Define this if you're running x86 architecture 64 bits with 32 bit ABI]) ;; x86_64-*) dnl x86_64 kernel optionally supports x32 and 32 as well. If user did not explicitly state arch, dnl use compiler default. Otherwise, override it when needed. arch_x86=64 MY_X86_DEFAULT_ARCH test x"$host_alias" = x && arch_x86=$x86_default_arch test x"$arch_x86" != x"$x86_default_arch" && cpuflags="$cpuflags -m$arch_x86" if test x"$arch_x86" = x"64" ; then AC_DEFINE([ARCH_X86_64], [], [Define this if you're running x86 architecture 64 bits]) elif test x"$arch_x86" = x"x32" ; then AC_DEFINE([ARCH_X86_X32], [], [Define this if you're running x86 architecture 64 bits with 32 bit ABI]) else AC_DEFINE([ARCH_X86_32], [], [Define this if you're running x86 architecture 32 bits]) fi ;; *-*-darwin*) case "$host_or_hostalias" in universal-*) arch_ppc=yes arch_x86=32 ;; i386-* | x86_64-*) arch_x86=32 AC_DEFINE([ARCH_X86_32], [], [Define this if you're running x86 architecture 32 bits]) ;; ppc* | powerpc*) arch_ppc=yes dnl avoid ppc compilation crash AS="$CC" AC_DEFINE([ARCH_PPC], [], [Define this if you're running PowerPC architecture]) AC_CHECK_HEADER([altivec.h], [], [enable_altivec=no]) if test x"$enable_altivec" != x"no"; then AC_DEFINE([ENABLE_ALTIVEC], [], [Define this if you want to use altivec on PowerPC CPUs]) cpuflags="$cpuflags -faltivec -maltivec" LIBMPEG2_CFLAGS="$LIBMPEG2_CFLAGS -force_cpusubtype_ALL" fi ;; esac enable_impure_text=yes HOST_OS_DARWIN=1 dnl HOST_OS_DARWIN is used by a bunch of difference stuff, including dnl libdvdnav, libmpeg2, and xine itself (xine-engine, xine-utils) AC_DEFINE([HOST_OS_DARWIN], 1, [Define this if built on Mac OS X/Darwin]) dnl CONFIG_DARWIN is used by ffmpeg, so anything that pulls ffmpeg dnl headers needs to have this set. AC_DEFINE([CONFIG_DARWIN], 1, [Define this if built on Mac OS X/Darwin]) CPPFLAGS="-D_INTL_REDIRECT_MACROS $CPPFLAGS" ;; ppc-*-linux* | powerpc-*) arch_ppc=yes dnl avoid ppc compilation crash AS="$CC" AC_DEFINE([ARCH_PPC], [], [Define this if you're running PowerPC architecture]) AC_CHECK_HEADER([altivec.h], [], [enable_altivec=no]) if test x"$enable_altivec" != x"no"; then AC_DEFINE([ENABLE_ALTIVEC], [], [Define this if you want to use altivec on PowerPC CPUs]) cpuflags="$cpuflags -maltivec" fi ;; i?86-* | k?-* | athlon-* | pentium*) arch_x86=32 enable_impure_text=yes case "$host_or_hostalias" in *-*-cygwin* | *-*-mingw32*) CC_CHECK_CFLAGS([-fno-omit-frame-pointer], [W32_NO_OPTIMIZE="$W32_NO_OPTIMIZE -fno-omit-frame-pointer"]) CC_CHECK_CFLAGS([-fno-inline-functions], [W32_NO_OPTIMIZE="$W32_NO_OPTIMIZE -fno-inline-functions"]) CC_CHECK_CFLAGS([-fno-rename-registers], [W32_NO_OPTIMIZE="$W32_NO_OPTIMIZE -fno-rename-registers"]) AC_SUBST(W32_NO_OPTIMIZE) ;; esac AC_DEFINE([ARCH_X86_32], [], [Define this if you're running x86 architecture 32 bits]) if test x"$GCC" = x"yes" -o x"${CC##*/}" = x"icc"; then if test x"$GCC" = x"yes"; then # GCC optimizations CC_CHECK_CFLAGS([-mtune=i386], [sarchopt="-mtune"], [CC_CHECK_CFLAGS([-mcpu=i386], [sarchopt="-mcpu"], [CC_CHECK_CFLAGS([-march=i386], [sarchopt="-march"], [sarchopt="no"])])]) if test "$sarchopt" != "no"; then case "$host_or_hostalias" in i386-*) archopt_val="i386" ;; i486-*) archopt_val="i486" ;; i586-*) archopt_val="pentium" ;; pentium-mmx-*) archopt_val="pentium-mmx" ;; k6-2* | k6-3-*) archopt_val="k6-2" ;; k6-*) archopt_val="k6" ;; pentium3-*) archopt_val="pentium3" ;; pentium4-*) archopt_val="pentium4" ;; athlon-4-* | athlon-xp-* | althon-mp-*) archopt_val="athlon-4" ;; k7-* | athlon-tbird-* | athlon-*) archopt_val="athlon" ;; pentiumpro-* | pentium2-* | i686-*) archopt_val="pentiumpro" if test x"$cross_compiling" != x"yes"; then if test -f /proc/cpuinfo; then modelname=`cat /proc/cpuinfo | grep "model\ name\ :" | sed -e 's/ //g' | cut -d ':' -f2` case "$modelname" in *Athlon* | *Duron* | *K7*) dnl Special check for k7 cpu CC support CC_CHECK_CFLAGS([$sarchopt=athlon], [archopt_val="athlon"], [archopt_val="i686"]) ;; VIAEzra) archopt_val="c3" ;; esac fi fi ;; esac test x"$archopt_val" != x"" && cpuflags="$cpuflags $sarchopt=$archopt_val" fi else # Intel optimizations O3_CFLAGS="$O3_CFLAGS -unroll -ipo -ipo_obj" fi fi ;; esac AC_ARG_ENABLE([vis], [AS_HELP_STRING([--disable-vis], [do not use assembly codes for Sun UltraSPARC CPUs])], [], [enable_vis="yes"]) if test "x$has_vis" = "xyes"; then AC_DEFINE([ENABLE_VIS], [], [Define this if you have Sun UltraSPARC CPU]) case "$cpuflags" in *-mcpu=*) ;; *) cpuflags="$cpuflags -mcpu=v9" ;; esac fi AM_CONDITIONAL([ENABLE_VIS], test x"$has_vis" = x"yes") O1_CFLAGS="$O1_CFLAGS $optflags $cpuflags" O2_CFLAGS="$O2_CFLAGS $optflags $cpuflags" O3_CFLAGS="$O3_CFLAGS $optflags $cpuflags" dnl Allow turning off/on of optimizations. By default, optimizations are dnl enabled if --enable-debug is not specified. Even with --enable-debug, dnl optimizations can be enabled by explicitly specifying --enable-optimizations AC_ARG_ENABLE([optimizations], [AS_HELP_STRING([--disable-optimizations], [Don't try to guess what optimization to enable])], [], [test x"$enable_debug" != x"no" && enable_optimizations="no"]) AM_CONDITIONAL([DISABLE_OPTIMIZATIONS], [test x"$enable_optimizations" = x"no"]) if test x"$enable_optimizations" = x"no"; then DEFAULT_OCFLAGS="O0_CFLAGS" else dnl For multi-pass compilation: never when cross-compiling if test x"$cross_compiling" != x"yes"; then if test x"$GCC" = x"yes"; then CC_CHECK_CFLAGS([-fprofile-arcs], [CC_CHECK_CFLAGS([-fbranch-probabilities], [PASS1_CFLAGS="-fprofile-arcs $PASS1_CFLAGS" PASS2_CFLAGS="-fbranch-probabilities $PASS2_CFLAGS"])]) else pass1flags="-prof_dir \$(PWD)/\$(top_builddir)/ -prof_genx" pass2flags="-prof_dir \$(PWD)/\$(top_builddir)/ -prof_use" CC_CHECK_CFLAGS(["$pass1flags"], [CC_CHECK_CFLAGS(["$pass2flags"], [PASS1_CFLAGS="$pass1flags $PASS1_CFLAGS" PASS2_CFLAGS="$pass2flags $PASS2_CFLAGS"])]) fi fi fi AC_SUBST(O0_CFLAGS) AC_SUBST(PASS1_CFLAGS) AC_SUBST(PASS2_CFLAGS) test x"$DEFAULT_OCFLAGS" = x"" && DEFAULT_OCFLAGS="O3_CFLAGS" dnl xineutils.h:dlist_* AC_MSG_CHECKING([for nameless struct within union support]) nameless_struct_in_union="no" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include typedef struct dnode_st { struct dnode_st *next, *prev; } dnode_t; typedef union { struct { dnode_t *head, *null, *tail; }; struct { dnode_t h; dnode_t *dummy1; }; struct { dnode_t *dummy2; dnode_t t; }; } dlist_t; ]],[[ dlist_t list; list.head = &list.t; list.null = NULL; list.tail = &list.h; printf ("head = %p, tail = %p\n", (void *)list.head, (void *)list.tail); ]])], [nameless_struct_in_union="yes"]) AC_MSG_RESULT([$nameless_struct_in_union]) test x"$nameless_struct_in_union" = x"yes" && AC_DEFINE([HAVE_NAMELESS_STRUCT_IN_UNION], [], [Define this if compiler supports nameless structs within unions.]) dnl -ffast-math fails in broken build environments due to missing stuff like _foo_pow_finite (). dnl We dont want to kill that feature generally either because stuff like faad will benefit a dnl lot from inlined fsin/fcos instructions. -Ox affects that code as well, so test it this late dnl when we know the final optimization level. ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" dnl ugly but "$$DEFAULT_OCFLAGS" wont work here I guess. test x"$DEFAULT_OCFLAGS" = x"O0_CFLAGS" && CFLAGS="$CFLAGS $O0_CFLAGS -ffast-math" test x"$DEFAULT_OCFLAGS" = x"O1_CFLAGS" && CFLAGS="$CFLAGS $O1_CFLAGS -ffast-math" test x"$DEFAULT_OCFLAGS" = x"O2_CFLAGS" && CFLAGS="$CFLAGS $O2_CFLAGS -ffast-math" test x"$DEFAULT_OCFLAGS" = x"O3_CFLAGS" && CFLAGS="$CFLAGS $O3_CFLAGS -ffast-math" dnl Test for libmvec, for unaware libm. AC_MSG_CHECKING([for libmvec]) fast_math_res="no" MVEC_LIB= LIBS="$ac_save_LIBS -lm -lmvec" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]],[[ ]])], [fast_math_res="yes"; MVEC_LIB="-lmvec"]) AC_MSG_RESULT([$fast_math_res]) AC_SUBST(MVEC_LIB) LIBS="$ac_save_LIBS -lm $MVEC_LIB" fast_math_hack= while test y = y ; do fast_math_res="no" CC_CHECK_CFLAGS([-ffast-math], [fast_math_res="yes"]) test x"$fast_math_res" = x"yes" || break AC_MSG_CHECKING([whether libm supports -ffast-math]) fast_math_res="no" dnl Make sure gcc does not optimize away all this. AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include ]],[[ double a, b; a = 0.88 * rand (); b = 0.99 * rand (); a = pow (sin (a), cos (sqrt (b))); printf ("%lf\n", a); ]])], [fast_math_res="yes"]) AC_MSG_RESULT([$fast_math_res]) test x"$fast_math_res" = x"yes" || break AC_MSG_CHECKING([whether compiler autovectorization supports -ffast-math]) fast_math_res="no" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include static void maketable (int *tab, double e) { int i; for (i = -256; i <= 255; i++) { double base = 1.0 - (i < 0 ? -i : i) / 255.0; tab[256 + i] = pow (base, e) * 65536; } } ]],[[ int tab[512], i; double e = 0.0000000005 * rand (); maketable (tab, e); for (i = 0; i < 512; i++) e += tab[i]; printf ("%lf\n", e); ]])], [fast_math_res="yes"]) AC_MSG_RESULT([$fast_math_res]) test x"$fast_math_res" = x"yes" && break fast_math_hack="__attribute__((optimize(no-fast-math)))" AC_MSG_CHECKING([whether __attribute__((optimize(no-fast-math))) works]) fast_math_res="no" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include #include static void __attribute__((optimize(no-fast-math))) maketable (int *tab, double e) { int i; for (i = -256; i <= 255; i++) { double base = 1.0 - (i < 0 ? -i : i) / 255.0; tab[256 + i] = pow (base, e) * 65536; } } ]],[[ int tab[512], i; double e = 0.0000000005 * rand (); maketable (tab, e); for (i = 0; i < 512; i++) e += tab[i]; printf ("%lf\n", e); ]])], [fast_math_res="yes"]) AC_MSG_RESULT([$fast_math_res]) test x"$fast_math_res" = x"yes" && break fast_math_hack= break done CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" if test x"$fast_math_res" = x"yes" ; then O1_CFLAGS="$O1_CFLAGS -ffast-math" O2_CFLAGS="$O2_CFLAGS -ffast-math" O3_CFLAGS="$O3_CFLAGS -ffast-math" fi AC_DEFINE_UNQUOTED([ATTR_NO_FAST_VECTOR_MATH], [$fast_math_hack], [Define to a function attribute that turns off -ffast-math when needed for autovectorized code.]) dnl end of -ffast-math stuff dnl Various atomic vars. gcc says these may yield external library calls but does not tell what lib to link... my_atomic_mode=0 AC_MSG_CHECKING([for stdatomic.h support]) my_atomic_res="no" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include ]],[[ atomic_int v = 8; int r = atomic_fetch_add_explicit (&v, -1, memory_order_acq_rel); printf ("%d\n", r); ]])], [my_atomic_mode=1; my_atomic_res="yes"]) AC_MSG_RESULT([$my_atomic_res]) if test x"$my_atomic_res" != x"yes" ; then AC_MSG_CHECKING([for __atomic_* compiler builtins]) my_atomic_res="no" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ int v = 8; int r = __atomic_fetch_add (&v, -1, __ATOMIC_ACQ_REL); printf ("%d\n", r); ]])], [my_atomic_mode=2; my_atomic_res="yes"]) AC_MSG_RESULT([$my_atomic_res]) fi if test x"$my_atomic_res" != x"yes" ; then AC_MSG_CHECKING([for __sync_* compiler builtins]) my_atomic_res="no" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include ]],[[ int v = 8; int r = __sync_fetch_and_add (&v, -1); printf ("%d\n", r); ]])], [my_atomic_mode=3; my_atomic_res="yes"]) AC_MSG_RESULT([$my_atomic_res]) fi AC_DEFINE_UNQUOTED([HAVE_ATOMIC_VARS], [$my_atomic_mode], [0 = none, 1 = stdatomic.h, 2 = __atomic_*, 3 = __sync_*]) dnl end of atomic stuff AC_SUBST(O1_CFLAGS) AC_SUBST(O2_CFLAGS) AC_SUBST(O3_CFLAGS) DEFAULT_OCFLAGS='$('$DEFAULT_OCFLAGS')' AC_SUBST(DEFAULT_OCFLAGS) if test x"$arch_x86" != x"no" && test x"$enable_macosx_universal" = x"no"; then AC_DEFINE([ARCH_X86], [], [Define this if you're running x86 architecture]) AC_DEFINE([HAVE_MMX], [], [Define this if you can compile MMX asm instructions]) fi AM_CONDITIONAL([ARCH_PPC], test x"$arch_ppc" = x"yes") AM_CONDITIONAL([ARCH_X86], test x"$arch_x86" != x"no") AM_CONDITIONAL([ARCH_X86_32], test x"$arch_x86" = x"32") AM_CONDITIONAL([ARCH_X86_X32], test x"$arch_x86" = x"x32") AM_CONDITIONAL([ARCH_X86_64], test x"$arch_x86" = x"64") AM_CONDITIONAL([HAVE_MMX], test x"$arch_x86" != x"no") AM_CONDITIONAL([HOST_OS_DARWIN], test x"$HOST_OS_DARWIN" = x"1") if test x"$enable_impure_text" = x"yes"; then case "$host_or_hostalias" in *solaris*) if test "$GCC" = yes; then IMPURE_TEXT_LDFLAGS="-mimpure-text" else IMPURE_TEXT_LDFLAGS="-z textoff" fi ;; *darwin*) IMPURE_TEXT_LDFLAGS="-Wl,-read_only_relocs,warning" ;; esac fi AC_SUBST(IMPURE_TEXT_LDFLAGS) dnl ---------------------------- dnl checks for library functions dnl ---------------------------- dnl NLS: src/input/mms.c src/input/vcd, xine-utils AC_CHECK_FUNCS([nl_langinfo]) dnl src/libfaad AC_CHECK_DECL([lrintf], [AC_DEFINE([HAVE_LRINTF], 1, [Define this if the 'lrintf' function is declared in math.h]) AC_DEFINE([_ISOC9X_SOURCE], 1, [Define this if you are ISO C9X compliant])], [], [#define _ISOC9X_SOURCE #include ]) dnl contrib/libdca, src/video_out/vidix/drivers/mach64_vid.c AC_CHECK_FUNCS([memalign]) dnl src/input/vcd/libcdio/portable.h AC_CHECK_FUNCS([bzero]) dnl src/libfaad/common.h AC_CHECK_FUNCS([memcpy]) dnl src/xine-engine/scratch.c AC_CHECK_FUNCS([localtime_r]) dnl src/input/input_file.c AC_ARG_ENABLE([mmap], AS_HELP_STRING([--enable-mmap], [Enable mmap() file loading (default: no)])) if test x"$enable_mmap" = x"yes"; then AC_CHECK_FUNCS([mmap]) fi AC_CHECK_FUNCS([vsscanf sigaction sigset getpwuid_r nanosleep lstat memset readlink strchr va_copy sched_getaffinity sysconf]) AC_CHECK_FUNCS([llabs]) AC_CHECK_FUNCS([snprintf _snprintf], [have_required_function="yes"]) test x"$have_required_function" != x"yes" && AC_MSG_ERROR([required function not found]) AC_CHECK_FUNCS([vsnprintf _vsnprintf], [have_required_function="yes"]) test x"$have_required_function" != x"yes" && AC_MSG_ERROR([required function not found]) AC_CHECK_FUNCS([strcasecmp _stricmp], [have_required_function="yes"]) test x"$have_required_function" != x"yes" && AC_MSG_ERROR([required function not found]) AC_CHECK_FUNCS([strncasecmp _strnicmp], [have_required_function="yes"]) test x"$have_required_function" != x"yes" && AC_MSG_ERROR([required function not found]) AC_FUNC_FSEEKO AC_REPLACE_FUNCS([asprintf basename gettimeofday setenv strcasestr strlcat strlcpy strndup strpbrk strsep strtok_r swab timegm unsetenv memmem]) AC_LIBSOURCE([hstrerror.c]) saveLIBS="${LIBS}" LIBS="${LIBS} ${NET_LIBS}" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[hstrerror(0)]])], [AC_DEFINE([HAVE_HSTRERROR], 1, [Define to 1 if you have 'hstrerror' in ])], [AC_LIBOBJ([hstrerror])]) LIBS="${saveLIBS}" AC_LIBSOURCE([dirent_msvc.c]) AC_CHECK_FUNC([opendir], [AC_DEFINE([HAVE_OPENDIR], 1, [Define to 1 if you have 'opendir' function])], [if test x"$WIN32_SYS" = x"mingw32"; then AC_LIBOBJ([dirent_msvc]) else AC_MSG_ERROR([dirent is needed (opendir, readdir, ...)]) fi]) XINE_CHECK_MINMAX([ AC_DEFINE(HAVE_MAX_MACRO, 1, [Define to 1 if you have 'MAX' macro in sys/param.h]) AC_DEFINE(HAVE_MIN_MACRO, 1, [Define to 1 if you have 'MIN' macro in sys/param.h]) ],[]) AC_CHECK_HEADERS([limits.h]) AC_LIBSOURCE([timedlock.c]) ac_save_LIBS="$LIBS" LIBS="$LIBS $PTHREAD_LIBS" AC_CHECK_FUNCS([pthread_mutex_timedlock], [AC_DEFINE([HAVE_PTHREAD_MUTEX_TIMEDLOCK], 1, [Define to 1 if you have 'pthread_mutex_timedlock' in ])], [AC_LIBOBJ([timedlock])]) LIBS="$ac_save_LIBS" AC_MSG_CHECKING([for pthread rwlock support]) ac_save_LIBS="$LIBS" LIBS="$LIBS $PTHREAD_LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include ]], [[ pthread_rwlock_t rwl; struct timespec ts; ts.tv_sec = 8888; ts.tv_nsec = 0; pthread_rwlock_init (&rwl, NULL); pthread_rwlock_rdlock (&rwl); pthread_rwlock_tryrdlock (&rwl); pthread_rwlock_timedrdlock (&rwl, &ts); pthread_rwlock_wrlock (&rwl); pthread_rwlock_trywrlock (&rwl); pthread_rwlock_timedwrlock (&rwl, &ts); pthread_rwlock_unlock (&rwl); pthread_rwlock_destroy (&rwl); ]])], [have_pthread_rwlock="yes"], [have_pthread_rwlock="no"]) LIBS="$ac_save_LIBS" AC_MSG_RESULT([$have_pthread_rwlock]) AC_ARG_ENABLE([pthread-rwlock], [AS_HELP_STRING([--disable-pthread-rwlock], [do not use pthread rwlock support even if present.])], [], [enable_pthread_rwlock="$have_pthread_rwlock"]) test x"$enable_pthread_rwlock" = x"yes" && AC_DEFINE([HAVE_PTHREAD_RWLOCK], [1], [Define to 1 if you have pthread rwlock support.]) AC_GETOPT_LONG dnl -------------------------- dnl checks for system services dnl -------------------------- AC_ARG_ENABLE([ipv6], [AS_HELP_STRING([--enable-ipv6], [user configurable IPv6 support, default: auto])], [], [enable_ipv6=try]) if test x"$enable_ipv6" != x"no" ; then AC_MSG_CHECKING([for IPv6]) AC_COMPILE_IFELSE([ AC_LANG_PROGRAM([[ #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETDB_H #include #endif ]], [[ struct addrinfo hints, *res; hints.ai_socktype = SOCK_STREAM; hints.ai_family = AF_INET6; getaddrinfo ("localhost", "80", &hints, &res); freeaddrinfo (res); ]])], [enable_ipv6=yes], [test x"$enable_ipv6" = x"yes" && enable_ipv6=fail]) AC_MSG_RESULT([$enable_ipv6]) test x"$enable_ipv6" = x"fail" && AC_MSG_ERROR([IPv6 requested but not supported!]) fi test x"$enable_ipv6" = x"yes" && AC_DEFINE([ENABLE_IPV6], 1, [Enable this when IPv6 support is requested]) dnl Even as of 2.61, autoconf is not smart enough to find the X include dnl and library paths on Mac OS X, so seed them automatically if they're dnl not specified on the configure command-line. case "$host_os" in darwin*) test x"$x_includes" = x"NONE" && x_includes="/usr/X11R6/include" test x"$x_libraries" = x"NONE" && x_libraries="/usr/X11R6/lib" ;; esac dnl Check for Xwindows using the autoconf AC_PATH_XTRA macro, which is an dnl extension of AC_PATH_X that sets X_CFLAGS and X_LIBS. It will also set dnl X_EXTRA_LIBS and X_PRE_LIBS. AC_PATH_XTRA if test x"$no_x" != x"yes"; then X_LIBS="$X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS" AC_CHECK_LIB([Xext], [main], [X_LIBS="$X_LIBS -lXext"], [AC_MSG_ERROR([libXext is required])], [$X_LIBS]) elif test x"$have_x" = x"no"; then PKG_CHECK_MODULES([X], [x11 xext], [have_x=yes; no_x=no], [have_x=no; no_x=yes]) fi dnl Check for XShm support (required for xine X support) if test x"$no_x" != x"yes"; then ac_save_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS $X_CFLAGS" AC_CHECK_HEADERS([X11/extensions/XShm.h], [], [AC_MSG_ERROR([XShm extension is required])], [#include ]) CPPFLAGS="$ac_save_CPPFLAGS" AC_DEFINE([HAVE_X11], 1, [Define this if you have X11R6 installed]) fi AM_CONDITIONAL([HAVE_X11], [test x"$no_x" != x"yes"]) dnl Locate libraries needed for X health check soname_script="/[[0-9]]$/! d; s%^.*/%% t q b :q q" x_lib_location="`ls -1 "${x_libraries:-/usr/local/lib}/libX11.$acl_cv_shlibext"* "${x_libraries:-/usr/lib}/libX11.$acl_cv_shlibext"* 2>/dev/null | sed -e \"${soname_script}\"`" AC_DEFINE_UNQUOTED([LIBX11_SO], "${x_lib_location:-libX11.$acl_cv_shlibext}", [The soname of libX11, needed for dlopen()]) x_lib_location="`ls -1 "${x_libraries:-/usr/local/lib}/libXv.$acl_cv_shlibext"* "${x_libraries:-/usr/lib}/libXv.$acl_cv_shlibext"* 2>/dev/null | sed -e \"${soname_script}\"`" AC_DEFINE_UNQUOTED([LIBXV_SO], "${x_lib_location:-libXv.$acl_cv_shlibext}", [The soname of libXv, needed for dlopen()]) dnl Does X11 need XLockDisplay () to prevent deadlocks? AC_MSG_CHECKING([for thread safe X11]) x_is_thread_safe=no if test -n "$PKG_CONFIG" ; then if "$PKG_CONFIG" --atleast-version 1.9 xcb && "$PKG_CONFIG" --atleast-version 1.4.99.901 x11 ; then x_is_thread_safe=yes AC_DEFINE([HAVE_THREAD_SAFE_X11], [1], [Define this if x11 does without XLockDisplay ().]) fi fi AC_MSG_RESULT([$x_is_thread_safe]) dnl _FILE_OFFSET_BITS (AC_SYS_LARGEFILE; ac_cv_sys_file_offset_bits) dnl _LARGE_FILES (AC_SYS_LARGEFILE; ac_cv_sys_large_files) dnl _LARGEFILE_SOURCE (AC_FUNC_SEEKO; ac_cv_sys_largfile_source) dnl _LARGEFILE64_SOURCE (glibc transitional; not tested or used anywhere) AC_SYS_LARGEFILE dnl Add macros to the compiler command line that are also in config.h for things dnl that do not #include config.h. dnl known: src/input/libreal, src/input/librtsp test x"$ac_cv_sys_file_offset_bits" != x"no" && CPPFLAGS="-D_FILE_OFFSET_BITS=64 $CPPFLAGS" test x"$ac_cv_sys_largefile_source" != x"no" && CPPFLAGS="-D_LARGEFILE_SOURCE $CPPFLAGS" test x"$ac_cv_sys_large_files" != x"" && test x"$ac_cv_sys_large_files" != x"no" && CPPFLAGS="-D_LARGE_FILES $CPPFLAGS" dnl --------------------------- dnl User defined linker options dnl --------------------------- dnl Bind everything possible within the current shared object, for more efficient linking. dnl For now, xine tries to give all exported symbols the "protected" visibility. dnl Plugin description catalogs are the only "default" exceptions but they are not used by dnl the plugins themselves so potential overrides have no effect there anyway. dnl However, at least with gcc 4.x, this seems to only affect the defining .o not the entire .so, dnl which looks somewhat inconsistent. CC_CHECK_LDFLAGS([-Wl,-Bsymbolic], [symbolic_ldflags="-Wl,-Bsymbolic"]) default_enable_symbolic=yes AC_ARG_ENABLE([symbolic], [AS_HELP_STRING( [--disable-symbolic], [Allow applictions to override some xine linker symbols, and break build with gcc < 5.0 / GNU ld >= 2.26 on 64 bit platforms.])]) if test x"$enable_symbolic" = x"no" ; then symbolic_ldflags="" fi LDFLAGS="$symbolic_ldflags $LDFLAGS" dnl ------- dnl Plugins dnl ------- dnl build a few basic plugins into libxine itself (optional, enabled by default) default_enable_libxine_builtins=yes AC_ARG_ENABLE([libxine-builtins], [AS_HELP_STRING([--disable-libxine-builtins], [Disable building a few basic plugins into libxine])]) if test x"$enable_libxine_builtins" != x"no" ; then AC_DEFINE([XINE_MAKE_BUILTINS], 1, [Define this if you want a few basic plugins built into libxine itself]) fi AM_CONDITIONAL([ENABLE_LIBXINE_BUILTINS], [test x"$enable_libxine_builtins" != x"no"]) XINE_AUDIO_OUT_PLUGINS XINE_VIDEO_OUT_PLUGINS XINE_INPUT_PLUGINS XINE_DECODER_PLUGINS dnl --------------------------------------------- dnl XINE_ROOTDIR does not work if architecture independent files are dnl installed to another place than architecture dependent files !!! dnl --------------------------------------------- dnl dnl installation directories and directories relative to prefix dnl dnl Note: dnl use AC_DEFINE for runtime dnl use AC_SUBST for installation dnl makeexpand () { local i local j i="$1" while test "$i" != "$j"; do j="$i"; eval i="$j"; done echo "$i" } xinelibdir='${libdir}/xine' xinedatadir='${datadir}/xine' pkgconfigdir='${libdir}/pkgconfig' AC_SUBST(xinelibdir) AC_SUBST(xinedatadir) AC_SUBST(pkgconfigdir) XINE_PLUGINROOT="\${xinelibdir}/plugins/$(($XINE_LT_CURRENT-$XINE_LT_AGE))" XINE_PLUGINDIR="$XINE_PLUGINROOT.$XINE_LT_AGE" XINE_FONTDIR="\${xinedatadir}/libxine$XINE_MAJOR/fonts" XINE_LOCALEDIR='${datadir}/locale' XINE_REL_PLUGINROOT="`makeexpand "$XINE_PLUGINROOT"`" XINE_REL_PLUGINROOT="`makeexpand "$XINE_REL_PLUGINROOT" | sed -e "s,^${prefix}/,,"`" XINE_REL_PLUGINDIR="$XINE_REL_PLUGINROOT.$XINE_LT_AGE" XINE_REL_FONTDIR="`makeexpand "$XINE_FONTDIR" | sed -e "s,^${prefix}/,,"`" XINE_REL_LOCALEDIR="`makeexpand "$XINE_LOCALEDIR" | sed -e "s,^${prefix}/,,"`" XINE_PKGCONFIG_DIR="`makeexpand "$pkgconfigdir"`" if test "x$WIN32_SYS" = "xmingw32" -o "x$WIN32_SYS" = "xcygwin"; then dnl polish paths (MinGW runtime accepts both \ and / anyway) XINE_REL_PLUGINROOT="`echo "$XINE_REL_PLUGINROOT" | sed -e 's/\\//\\\\\\\\/g'`" XINE_REL_PLUGINDIR="$XINE_REL_PLUGINROOT.$XINE_LT_AGE" XINE_REL_FONTDIR="`echo "$XINE_REL_FONTDIR" | sed -e 's/\\//\\\\\\\\/g'`" XINE_REL_LOCALEDIR="`echo "$XINE_REL_LOCALEDIR" | sed -e 's/\\//\\\\\\\\/g'`" AC_DEFINE([XINE_PLUGINROOT],[xine_get_pluginroot()],[Define this to general plugins directory location]) AC_DEFINE([XINE_PLUGINDIR], [xine_get_plugindir()], [Define this to specific plugins directory location]) AC_DEFINE([XINE_FONTDIR], [xine_get_fontdir()], [Define this to osd fonts dir location]) AC_DEFINE([XINE_LOCALEDIR], [xine_get_localedir()], [Path where catalog files will be.]) else XINE_PLUGINROOTPATH="`makeexpand "$XINE_PLUGINROOT"`" XINE_FONTPATH="`makeexpand "$XINE_FONTDIR"`" XINE_LOCALEPATH="`makeexpand "$XINE_LOCALEDIR"`" AC_DEFINE_UNQUOTED([XINE_PLUGINROOT],["$XINE_PLUGINROOTPATH"], [Define this to general plugins directory location]) AC_DEFINE_UNQUOTED([XINE_PLUGINDIR], ["$XINE_PLUGINROOTPATH.$XINE_LT_AGE"], [Define this to soecific plugins directory location]) AC_DEFINE_UNQUOTED([XINE_FONTDIR], ["$XINE_FONTPATH"], [Define this to osd fonts dir location]) AC_DEFINE_UNQUOTED([XINE_LOCALEDIR], ["$XINE_LOCALEPATH"], [Path where catalog files will be.]) fi AC_DEFINE_UNQUOTED([XINE_REL_PLUGINDIR], ["$XINE_REL_PLUGINDIR"], [Define this to specific plugin directory relative to execution prefix]) AC_DEFINE_UNQUOTED([XINE_REL_PLUGINROOT],["$XINE_REL_PLUGINROOT"],[Define this to general plugin directory relative to execution prefix]) AC_DEFINE_UNQUOTED([XINE_REL_FONTDIR], ["$XINE_REL_FONTDIR"], [Define this to font directory relative to prefix]) AC_DEFINE_UNQUOTED([XINE_REL_LOCALEDIR], ["$XINE_REL_LOCALEDIR"], [Define this to font directory relative to prefix]) AC_SUBST(XINE_PLUGINDIR) AC_SUBST(XINE_FONTDIR) AC_SUBST(XINE_LOCALEDIR) AC_SUBST(XINE_PKGCONFIG_DIR) LIBTOOL_DESTDIR_DEFAULT= if test "x$SYS" != "xmingw32" -a "x$SYS" != "xcygwin"; then LIBTOOL_DESTDIR_DEFAULT=/ fi AC_SUBST([LIBTOOL_DESTDIR_DEFAULT]) dnl Where aclocal m4 files should be installed xine_acflags='-I ${datarootdir}/aclocal' XINE_ACFLAGS="-I ${datarootdir}/aclocal" AC_DEFINE_UNQUOTED([XINE_ACFLAGS], ["$XINE_ACFLAGS"], [Path where aclocal m4 files will be.]) AC_SUBST(xine_acflags) AC_SUBST(XINE_ACFLAGS) dnl Where architecture independent data (e.g. logo) will/should be installed XINE_DATADIR="\${xinedatadir}" AC_SUBST(XINE_DATADIR) dnl Where scripts will/should be installed. XINE_SCRIPTPATH="\${xinedatadir}/scripts" AC_SUBST(XINE_SCRIPTPATH) dnl --------------------------------------------- dnl Get where .m4 should be installed. dnl --------------------------------------------- dnl if test "x${ACLOCAL_DIR+set}" != xset; then dnl case "`id`" in dnl uid=0\(* ) dnl AC_MSG_CHECKING(for aclocal directory) dnl if (aclocal --version) < /dev/null > /dev/null 2>&1; then dnl ACLOCAL_DIR="`eval $ACLOCAL --print-ac-dir`" dnl AC_MSG_RESULT($ACLOCAL_DIR) dnl else dnl ACLOCAL_DIR="${prefix}/share/aclocal" dnl AC_MSG_RESULT(none - will be installed in $ACLOCAL_DIR) dnl fi dnl escapedprefix="`echo $prefix | sed -e 's/\\//\\\\\//g'`" dnl ACLOCAL_DIR="`echo $ACLOCAL_DIR|sed -e 's/^'$escapedprefix/'\${prefix}'/`" dnl ;; dnl esac dnl fi AC_SUBST(ACLOCAL_DIR) AM_CONDITIONAL([INSTALL_M4], [test x"$ACLOCAL_DIR" != x""]) dnl this is an internal function we should not use, but dnl as long as neither autoconf nor automake offer an A[CM]_PROG_OBJC dnl check we will have to call it _AM_DEPENDENCIES([OBJC]) dnl --------------------------------------------- dnl some include paths ( !!! DO NOT REMOVE !!! ) dnl --------------------------------------------- AM_CPPFLAGS='-I$(top_srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include -I$(top_srcdir)/src -I$(top_builddir)/src/xine-engine -I$(top_srcdir)/src/xine-engine -I$(top_srcdir)/src/xine-utils $(INTLDIR) -I$(top_builddir)/src/input -I$(top_srcdir)/src/input $(WIN32_INCLUDES) -I$(top_builddir)/lib -I$(top_srcdir)/lib' AC_SUBST(AM_CPPFLAGS) dnl We check for warnings here rather than with optimisations since we dnl want them to be _always_ enabled, to make sure the code is sane dnl enough. CC_CHECK_CFLAGS_APPEND([-Wall -Wchar-subscripts dnl -Wnested-externs -Wcast-align dnl -Wmissing-declarations -Wmissing-prototypes dnl -Wmissing-format-attribute -Wno-pointer-sign]) CC_CHECK_CFLAGS_APPEND([-Wformat=2 -Wformat], [CC_CHECK_CFLAGS_APPEND([-Wno-format-zero-length]) break; ]) CC_CHECK_CFLAGS_APPEND([-Wformat-security]) dnl check for strict aliasing problem, get the highest between =2 and dnl normal. CC_CHECK_CFLAGS_APPEND([-Wstrict-aliasing=2 -Wstrict-aliasing], [break;]) dnl This *has* to stay at the end as it can break some autoconf tests. CC_CHECK_CFLAGS_APPEND([-Werror=implicit-function-declaration dnl -Werror-implicit-function-declaration], [break;]) CC_NOUNDEFINED dnl signal FreeBSD have also FreeBSD based kernel. dnl AH_BOTTOM([ #if defined (__FreeBSD__) && !defined (__FreeBSD_kernel__) #define __FreeBSD_kernel__ __FreeBSD__ #endif #if defined (__FreeBSD_kernel__) #include # if defined (__FreeBSD_version) && !defined (__FreeBSD_kernel_version) # define __FreeBSD_kernel_version __FreeBSD_version # endif #endif ]) AC_ARG_ENABLE([lto], [AS_HELP_STRING([--enable-lto], [build with link-time optimization (lto) enabled])], [], [enable_lto="no"]) if test x"$enable_lto" = x"yes"; then CC_CHECK_CFLAGS_APPEND([-flto]) fi if test "x$enable_asan" = "xyes"; then CFLAGS="$CFLAGS -fsanitize=address -no-pie -fno-omit-frame-pointer" fi dnl Common cflags for all platforms CFLAGS="$UNIVERSAL_CFLAGS \$(MULTIPASS_CFLAGS) $miscflags $warnflags $CFLAGS" LDFLAGS="$UNIVERSAL_LDFLAGS $LDFLAGS" OBJCFLAGS="$UNIVERSAL_CFLAGS $miscflags $warnflags $OBJCFLAGS" dnl Some informations about xine-lib compilation for xine-config XINE_BUILD_CC="`$CC -v 2>&1 | tail -1 2>/dev/null`" XINE_BUILD_OS="`uname -s -r -m`" XINE_BUILD_DATE="`date "+%a %d %b %Y %T"`" AC_SUBST(XINE_BUILD_CC) AC_SUBST(XINE_BUILD_OS) AC_SUBST(XINE_BUILD_DATE) dnl --------------------------------------------- dnl Check for documentation formatting tool dnl --------------------------------------------- AC_CHECK_PROG(XMLTO, xmlto, xmlto, no) AM_CONDITIONAL([HAVE_XMLTO], [test "$XMLTO" != "no"]) AC_CHECK_PROG(RSVG, rsvg-convert, rsvg-convert, no) AM_CONDITIONAL([HAVE_RSVG_CONVERT], [test "$RSVG" != "no"]) if test "$RSVG" = no; then AC_CHECK_PROG(RSVG, rsvg, rsvg, no) fi AM_CONDITIONAL([HAVE_RSVG], [test "$RSVG" != "no"]) dnl --------------------------------------------- dnl ... and for PNG optimisation tool dnl --------------------------------------------- AC_CHECK_PROG(OPTIPNG, optipng, optipng, no) AM_CONDITIONAL([HAVE_OPTIPNG], [test "$OPTIPNG" != "no"]) dnl --------------------------------------------- dnl Output configuration files dnl --------------------------------------------- AC_CONFIG_FILES([ Makefile doc/Makefile doc/man/en/Makefile doc/hackersguide/Makefile doc/faq/Makefile doc/Doxyfile contrib/Makefile contrib/a52dec/Makefile contrib/gsm610/Makefile contrib/libdca/Makefile contrib/libdha/Makefile contrib/libdha/bin/Makefile contrib/libdha/kernelhelper/Makefile contrib/libdha/oth/Makefile contrib/libdha/sysdep/Makefile contrib/libfaad/Makefile contrib/libmad/Makefile contrib/libmpcdec/Makefile contrib/libxdg-basedir/Makefile contrib/nosefart/Makefile contrib/vidix/Makefile contrib/vidix/drivers/Makefile include/xine/version.h lib/Makefile misc/Makefile misc/Makefile.plugins misc/SlackBuild misc/build_rpms.sh misc/libxine.pc misc/relchk.sh misc/xine-config misc/xine-lib.spec po/Makevars.extra po/Makefile.in src/Makefile src/audio_out/Makefile src/audio_dec/Makefile src/combined/Makefile src/combined/ffmpeg/Makefile src/demuxers/Makefile src/dxr3/Makefile src/input/Makefile src/input/libdvdnav/Makefile src/libw32dll/Makefile src/libreal/Makefile src/post/Makefile src/spu_dec/Makefile src/video_dec/Makefile src/video_out/Makefile src/video_out/macosx/Makefile src/xine-utils/Makefile src/xine-engine/Makefile src/vdr/Makefile]) AC_CONFIG_COMMANDS([default],[[chmod +x ./misc/SlackBuild ./misc/build_rpms.sh ./misc/relchk.sh]],[[]]) AC_OUTPUT dnl Guard against multiple inclusion AH_TOP([#ifndef _XINE_CONFIGURE_H_ #define _XINE_CONFIGURE_H_ ]) AH_BOTTOM([#endif ]) dnl --------------------------------------------- dnl Work around a suspected bug in libtool: dnl dnl Remove excessive trailing slash from search dir names in the libtool script. dnl It occurs in dir names obtained by 'gcc -print-search-dirs' in the created dnl configure script and causes a test on dir names in libtool to fail, dnl leading to confusing (but harmless) 'warning: seems to be moved'. dnl dnl This should be fixed in the libtool package itself as all other dir names dnl there have no trailing slash. dnl --------------------------------------------- dnl Work around problem due to LTCFLAGS: dnl dnl CFLAGS is passed to LTCFLAGS directly from configure instead of Makefiles. dnl Fixing LTCFLAGS here will help compile xine-list on some crazy platforms. dnl dnl It disables multi-pass compilation of xine-list. dnl --------------------------------------------- dnl Note: Brackets [] must be doubled as they are treated as m4 macro quotes. if test x"$enable_macosx_universal" = x"no"; then cat libtool | sed -e '/sys_lib_search_path_spec=/s/\/\([[ "]]\)/\1/g' > libtool.tmp else cat libtool | sed -e 's,sys_lib_search_path_spec=.*$,sys_lib_search_path_spec=\"/Developer/SDKs/MacOSX10.4u.sdk/usr/lib\",' > libtool.tmp fi mv -f libtool.tmp libtool dnl removing make-specific variable cat libtool | sed 's/\\$(MULTIPASS_CFLAGS)//' > libtool.tmp mv -f libtool.tmp libtool chmod +x libtool XINE_LIB_SUMMARY xine-lib-1.2/include/0000755000175000017500000000000014647725152012307 5ustar memexine-lib-1.2/include/xine/0000755000175000017500000000000014647725152013252 5ustar memexine-lib-1.2/include/xine/alphablend.h0000644000175000017500000000727714647725152015532 0ustar meme/* * * Copyright (C) 2000 Thomas Mirlacher * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. * * The author may be reached as * *------------------------------------------------------------ * */ #ifndef __ALPHABLEND_H__ #define __ALPHABLEND_H__ #include "video_out.h" typedef struct { void *buffer; unsigned int buffer_size; int disable_exact_blending; int offset_x, offset_y; } alphablend_t; void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine) XINE_PROTECTED; void _x_alphablend_free(alphablend_t *extra_data) XINE_PROTECTED; typedef struct clut_s clut_t; struct clut_s { /* CLUT == Color LookUp Table */ uint8_t cb; uint8_t cr; uint8_t y; uint8_t foo; } XINE_PACKED; void _x_clut_yuv2rgb(uint32_t *clut, int num_items, int color_matrix) XINE_PROTECTED; #define XX44_PALETTE_SIZE 32 typedef struct { unsigned size; unsigned max_used; uint32_t cluts[XX44_PALETTE_SIZE]; /* cache palette entries for both colors and hili_colors */ int lookup_cache[OVL_PALETTE_SIZE*2]; } xx44_palette_t; void _x_blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, int dst_width, int dst_height, alphablend_t *extra_data) XINE_PROTECTED; void _x_blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, int dst_width, int dst_height, alphablend_t *extra_data) XINE_PROTECTED; void _x_blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, int dst_width, int dst_height, alphablend_t *extra_data) XINE_PROTECTED; void _x_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, int dst_width, int dst_height, int dst_pitches[3], alphablend_t *extra_data) XINE_PROTECTED; void _x_blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, int dst_width, int dst_height, int dst_pitch, alphablend_t *extra_data) XINE_PROTECTED; /* * This function isn't too smart about blending. We want to avoid creating new * colors in the palette as a result from two non-zero colors needed to be * blended. Instead we choose the color with the highest alpha value to be * visible. Some parts of the code taken from the "VeXP" project. */ void _x_blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, int dst_width, int dst_height, int dst_pitch, alphablend_t *extra_data, xx44_palette_t *palette,int ia44) XINE_PROTECTED; /* * Functions to handle the xine-specific palette. */ void _x_clear_xx44_palette(xx44_palette_t *p) XINE_PROTECTED; void _x_init_xx44_palette(xx44_palette_t *p, unsigned num_entries) XINE_PROTECTED; void _x_dispose_xx44_palette(xx44_palette_t *p) XINE_PROTECTED; /* * Convert the xine-specific palette to something useful. */ void _x_xx44_to_xvmc_palette(const xx44_palette_t *p,unsigned char *xvmc_palette, unsigned first_xx44_entry, unsigned num_xx44_entries, unsigned num_xvmc_components, const char *xvmc_components) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/info_helper.h0000644000175000017500000001155614647725152015725 0ustar meme/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stream metainfo helper functions * hide some xine engine details from demuxers and reduce code duplication * * $id$ */ #ifndef INFO_HELPER_H #define INFO_HELPER_H #include #include "xine_internal.h" /* * set a stream info * * params: * *stream the xine stream * info stream info id (see xine.h, XINE_STREAM_INFO_*) * value the value to assign * */ void _x_stream_info_set(xine_stream_t *stream, int info, int value) XINE_PROTECTED; /* * reset a stream info (internal ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_STREAM_INFO_*) * */ void _x_stream_info_reset(xine_stream_t *stream, int info) XINE_PROTECTED; /* * reset a stream info (public ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_STREAM_INFO_*) * */ void _x_stream_info_public_reset(xine_stream_t *stream, int info) XINE_PROTECTED; /* * retrieve stream info (internal ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_STREAM_INFO_*) * */ uint32_t _x_stream_info_get(xine_stream_t *stream, int info) XINE_PROTECTED; /* * retrieve stream info (public ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_STREAM_INFO_*) * */ uint32_t _x_stream_info_get_public(xine_stream_t *stream, int info) XINE_PROTECTED; /* * set a stream meta info * * params: * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * *str null-terminated string (using current locale) * */ void _x_meta_info_set(xine_stream_t *stream, int info, const char *str) XINE_PROTECTED; /* * set a stream meta info * * params: * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * *str null-terminated string (using utf8) * */ void _x_meta_info_set_utf8(xine_stream_t *stream, int info, const char *str) XINE_PROTECTED; /* * set a stream meta info * * params: * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * *str null-terminated string (using encoding below) * *enc charset encoding of the string * */ void _x_meta_info_set_generic(xine_stream_t *stream, int info, const char *str, const char *enc) XINE_PROTECTED; /* * set a stream meta multiple info * * params: * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * ... one or more meta info, followed by a NULL pointer * */ void _x_meta_info_set_multi(xine_stream_t *stream, int info, ...) XINE_SENTINEL XINE_PROTECTED; /* * set a stream meta info * * params: * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * *buf char buffer (not a null-terminated string) * len length of the metainfo * */ void _x_meta_info_n_set(xine_stream_t *stream, int info, const char *buf, int len) XINE_PROTECTED; /* * reset a stream meta info (internal ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * */ void _x_meta_info_reset(xine_stream_t *stream, int info) XINE_PROTECTED; /* * reset a stream meta info (public ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * */ void _x_meta_info_public_reset(xine_stream_t *stream, int info) XINE_PROTECTED; /* * retrieve stream meta info (internal ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * */ const char *_x_meta_info_get(xine_stream_t *stream, int info) XINE_PROTECTED; /* * retrieve stream meta info (public ones only) * * params : * *stream the xine stream * info meta info id (see xine.h, XINE_META_INFO_*) * */ const char *_x_meta_info_get_public(xine_stream_t *stream, int info) XINE_PROTECTED; #endif /* INFO_HELPER_H */ xine-lib-1.2/include/xine/xineintl.h0000644000175000017500000000307214647725152015257 0ustar meme/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_XINEINTL_H #define HAVE_XINEINTL_H #ifdef __cplusplus extern "C" { #endif #include #ifdef ENABLE_NLS # include # define _(String) dgettext (XINE_TEXTDOMAIN, String) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else /* Stubs that do something close enough. */ # define textdomain(String) (String) # define gettext(String) (String) # define dgettext(Domain,Message) (Message) # define dcgettext(Domain,Message,Type) (Message) # define ngettext(Singular, Plural, IsPlural) (Singular) # define bindtextdomain(Domain,Directory) (Domain) # define _(String) (String) # define N_(String) (String) #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/metronom.h0000644000175000017500000002334014647725152015265 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * metronom: general pts => virtual calculation/assoc * * virtual pts: unit 1/90000 sec, always increasing * can be used for synchronization * video/audio frame with same pts also have same vpts * but pts is likely to differ from vpts * * the basic idea is: * video_pts + video_wrap_offset = video_vpts * audio_pts + audio_wrap_offset = audio_vpts * * - video_wrap_offset should be equal to audio_wrap_offset as to have * perfect audio and video sync. They will differ on brief periods due * discontinuity correction. * - metronom should also interpolate vpts values most of the time as * video_pts and audio_vpts are not given for every frame. * - corrections to the frame rate may be needed to cope with bad * encoded streams. */ #ifndef HAVE_METRONOM_H #define HAVE_METRONOM_H #ifdef __cplusplus extern "C" { #endif #include #include #include typedef struct metronom_s metronom_t ; typedef struct metronom_clock_s metronom_clock_t; typedef struct scr_plugin_s scr_plugin_t; /* metronom prebuffer can be adjusted with XINE_PARAM_METRONOM_PREBUFFER. * it sets how much the first video/audio frame should be delayed to * have some prebuffering at the output layers. reducing this value (about * 1/8 sec) may result in faster seeking (good to simulate play backwards, * for example). */ #define PREBUFFER_PTS_OFFSET 12000 /* see below */ #define DISC_STREAMSTART 0 #define DISC_RELATIVE 1 #define DISC_ABSOLUTE 2 #define DISC_STREAMSEEK 3 #define DISC_GAPLESS 4 struct metronom_s { /* * called by audio output driver to inform metronom about current audio * samplerate * * parameter pts_per_smpls : 1/90000 sec per 65536 samples */ void (*set_audio_rate) (metronom_t *self, int64_t pts_per_smpls); /* * called by video output driver for *every* frame * * parameter frame containing pts, scr, ... information * * will set vpts field in frame * * this function will also update video_wrap_offset if a discontinuity * is detected (read the comentaries below about discontinuities). * */ void (*got_video_frame) (metronom_t *self, vo_frame_t *frame); /* * called by audio output driver whenever audio samples are delivered to it * * parameter pts : pts for audio data if known, 0 otherwise * nsamples : number of samples delivered * * return value: virtual pts for audio data * * this function will also update audio_wrap_offset if a discontinuity * is detected (read the comentaries below about discontinuities). * */ int64_t (*got_audio_samples) (metronom_t *self, int64_t pts, int nsamples); /* * called by SPU decoder whenever a packet is delivered to it * * parameter pts : pts for SPU packet if known, 0 otherwise * * return value: virtual pts for SPU packet * (this is the only pts to vpts function that cannot update the wrap_offset * due to the lack of regularity on spu packets) */ int64_t (*got_spu_packet) (metronom_t *self, int64_t pts); /* * tell metronom about discontinuities. * * these functions are called due to a discontinuity detected at * demux stage. * * there are different types of discontinuities: * * DISC_STREAMSTART : new stream starts, expect pts values to start * from zero immediately * DISC_RELATIVE : typically a wrap-around, expect pts with * a specified offset from the former ones soon * DISC_ABSOLUTE : typically a new menu stream (nav packets) * pts will start from given value soon. * this will try a seamless transition even if decoder * reorders frames around it. * DISC_STREAMSEEK : used by video and audio decoder loop, * when a buffer with BUF_FLAG_SEEK set is encountered; * applies the necessary vpts offset for the seek in * metronom, but keeps the vpts difference between * audio and video, so that metronom doesn't cough * DISC_GAPLESS : wait until it is safe to start next gapless stream. * used internally by xine_play (). */ void (*handle_audio_discontinuity) (metronom_t *self, int type, int64_t disc_off); void (*handle_video_discontinuity) (metronom_t *self, int type, int64_t disc_off); /* * set/get options for metronom, constants see below */ void (*set_option) (metronom_t *self, int option, int64_t value); int64_t (*get_option) (metronom_t *self, int option); /* * set a master metronom * this is currently useful to sync independently generated streams * (e.g. by post plugins) to the discontinuity domain of another * metronom */ void (*set_master) (metronom_t *self, metronom_t *master); void (*exit) (metronom_t *self); }; /* * metronom options */ #define METRONOM_AV_OFFSET 2 #define METRONOM_ADJ_VPTS_OFFSET 3 #define METRONOM_FRAME_DURATION 4 #define METRONOM_SPU_OFFSET 5 #define METRONOM_VPTS_OFFSET 6 #define METRONOM_PREBUFFER 7 #define METRONOM_VPTS 8 /* METRONOM_LOCK can be used to lock metronom when multiple options needs to be fetched atomically (ex. VPTS_OFFSET and AV_OFFSET). * example: * metronom->set_option(metronom, METRONOM_LOCK, 1); * vpts_offset = metronom->get_option(metronom, METRONOM_VPTS_OFFSET|METRONOM_NO_LOCK); * av_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET|METRONOM_NO_LOCK); * metronom->set_option(metronom, METRONOM_LOCK, 0); */ #define METRONOM_LOCK 9 /* Returns 0 (not waiting), 1 (waiting for audio discontinuity), 2 (waiting for video discontinuity). */ #define METRONOM_WAITING 10 /* Nasty input_vdr helper. Inserts an immediate absolute discontinuity, * old style without pts reorder fix. */ #define METRONOM_VDR_TRICK_PTS 11 #define METRONOM_NO_LOCK 0x8000 typedef void xine_speed_change_cb_t (void *user_data, int new_speed); metronom_t *_x_metronom_init (int have_video, int have_audio, xine_t *xine) XINE_MALLOC XINE_PROTECTED; /* FIXME: reorder this structure on the next cleanup to remove the dummies */ struct metronom_clock_s { /* * set/get options for clock, constants see below */ void (*set_option) (metronom_clock_t *self, int option, int64_t value); int64_t (*get_option) (metronom_clock_t *self, int option); /* * system clock reference (SCR) functions */ #ifdef METRONOM_CLOCK_INTERNAL /* * start clock (no clock reset) * at given pts */ void (*start_clock) (metronom_clock_t *self, int64_t pts); /* * stop metronom clock */ void (*stop_clock) (metronom_clock_t *self); /* * resume clock from where it was stopped */ void (*resume_clock) (metronom_clock_t *self); #else void *dummy1; void *dummy2; void *dummy3; #endif /* * get current clock value in vpts */ int64_t (*get_current_time) (metronom_clock_t *self); /* * adjust master clock to external timer (e.g. audio hardware) */ void (*adjust_clock) (metronom_clock_t *self, int64_t desired_pts); #ifdef METRONOM_CLOCK_INTERNAL /* * set clock speed * for constants see xine_internal.h */ int (*set_fine_speed) (metronom_clock_t *self, int speed); #else void *dummy4; #endif /* * (un)register a System Clock Reference provider at the metronom */ int (*register_scr) (metronom_clock_t *self, scr_plugin_t *scr); void (*unregister_scr) (metronom_clock_t *self, scr_plugin_t *scr); #ifdef METRONOM_CLOCK_INTERNAL void (*exit) (metronom_clock_t *self); xine_t *xine; scr_plugin_t *scr_master; scr_plugin_t **scr_list; pthread_t sync_thread; int thread_running; int scr_adjustable; #else void *dummy5; void *dummy6; void *dummy7; void *dummy8; pthread_t dummy9; int dummy10; int dummy11; #endif int speed; void (*register_speed_change_callback) (metronom_clock_t *self, xine_speed_change_cb_t *callback, void *user_data); void (*unregister_speed_change_callback) (metronom_clock_t *self, xine_speed_change_cb_t *callback, void *user_data); #ifdef METRONOM_CLOCK_INTERNAL pthread_mutex_t lock; pthread_cond_t cancel; #endif }; metronom_clock_t *_x_metronom_clock_init(xine_t *xine) XINE_MALLOC XINE_PROTECTED; /* * clock options */ #define CLOCK_SCR_ADJUSTABLE 1 /* * SCR (system clock reference) plugins */ struct scr_plugin_s { int (*get_priority) (scr_plugin_t *self); /* * set/get clock speed * * for speed constants see xine_internal.h * returns actual speed */ int (*set_fine_speed) (scr_plugin_t *self, int speed); void (*adjust) (scr_plugin_t *self, int64_t vpts); void (*start) (scr_plugin_t *self, int64_t start_vpts); int64_t (*get_current) (scr_plugin_t *self); void (*exit) (scr_plugin_t *self); metronom_clock_t *clock; int interface_version; }; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/vo_scale.h0000644000175000017500000001341614647725152015223 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vo_scale.h * * keeps video scaling information */ #ifndef HAVE_VO_SCALE_H #define HAVE_VO_SCALE_H #ifdef __cplusplus extern "C" { #endif #include typedef struct { int x, y; int w, h; } vo_scale_rect_t; struct vo_scale_s { /* true if driver supports frame zooming */ int support_zoom; /* forces direct mapping between frame pixels and screen pixels */ int scaling_disabled; /* size / aspect ratio calculations */ /* * "delivered" size: * frame dimension / aspect as delivered by the decoder * used (among other things) to detect frame size changes * units: frame pixels */ int delivered_width; int delivered_height; double delivered_ratio; /* * required cropping: * units: frame pixels */ int crop_left; int crop_right; int crop_top; int crop_bottom; /* * displayed part of delivered images, * taking zoom into account * units: frame pixels */ int displayed_xoffset; int displayed_yoffset; int displayed_width; int displayed_height; double zoom_factor_x, zoom_factor_y; /* * user's aspect selection */ int user_ratio; /* * "gui" size / offset: * what gui told us about where to display the video * units: screen pixels */ int gui_x, gui_y; int gui_width, gui_height; int gui_win_x, gui_win_y; /* */ int force_redraw; /* * video + display pixel aspect * One pixel of height 1 has this width * This may be corrected by the driver in order to fit the video seamlessly */ double gui_pixel_aspect; double video_pixel_aspect; /* * "output" size: * * this is finally the ideal size "fitted" into the * gui size while maintaining the aspect ratio * units: screen pixels */ int output_width; int output_height; int output_xoffset; int output_yoffset; /* gui callbacks */ void *user_data; void (*frame_output_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y); void (*dest_size_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_width, int *dest_height, double *dest_pixel_aspect); /* borders */ vo_scale_rect_t border[4]; /* * border ratios to determine image position in the * viewport; these are set by user config */ double output_horizontal_position; double output_vertical_position; }; typedef struct vo_scale_s vo_scale_t; /* * convert delivered height/width to ideal width/height * taking into account aspect ratio and zoom factor */ void _x_vo_scale_compute_ideal_size (vo_scale_t *self) XINE_PROTECTED; /* * make ideal width/height "fit" into the gui */ void _x_vo_scale_compute_output_size (vo_scale_t *self) XINE_PROTECTED; /* * return true if a redraw is needed due resizing, zooming, * aspect ratio changing, etc. */ int _x_vo_scale_redraw_needed (vo_scale_t *self) XINE_PROTECTED; /* * */ void _x_vo_scale_translate_gui2video(vo_scale_t *self, int x, int y, int *vid_x, int *vid_y) XINE_PROTECTED; typedef struct { struct { int x0, y0, x1, y1; } in, out; } vo_scale_map_t; typedef enum { VO_SCALE_MAP_OK = 0, /** << Fine. */ VO_SCALE_MAP_OUTSIDE, /** << rect completely outside visible video. */ VO_SCALE_MAP_WRONG_ARGS, /** << NULL passed. */ VO_SCALE_MAP_ERROR /** << vo_scale yet unset. */ } vo_scale_map_res_t; /** @brief Map a rectangle to video out window. * @param self The vo_scale status to use. * @param map On call: map.in = {0, 0, width, height} of input rect. * map.out = {left, top, extent_width, extent_height} where input should go. * Extents may be 0 if same as video size. * On return: map.in = {left, top, right, bottom} to use from input rect. * map.out = {left, top, right, bottom} inside video out. * @return What went wrong. */ vo_scale_map_res_t _x_vo_scale_map (vo_scale_t *self, vo_scale_map_t *map) XINE_PROTECTED; /* * Returns description of a given ratio code */ extern const char _x_vo_scale_aspect_ratio_name_table[][8] XINE_PROTECTED; /* * initialize rescaling struct */ void _x_vo_scale_init(vo_scale_t *self, int support_zoom, int scaling_disabled, config_values_t *config ) XINE_PROTECTED; void _x_vo_scale_cleanup(vo_scale_t *self, config_values_t *config) XINE_PROTECTED; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/audio_decoder.h0000644000175000017500000000544714647725152016223 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine audio decoder plugin interface */ #ifndef HAVE_AUDIO_DECODER_H #define HAVE_AUDIO_DECODER_H #include #include struct plugin_node_s; #define AUDIO_DECODER_IFACE_VERSION 16 /* * generic xine audio decoder plugin interface */ typedef struct audio_decoder_class_s audio_decoder_class_t; typedef struct audio_decoder_s audio_decoder_t; struct audio_decoder_class_s { /* * open a new instance of this plugin class */ audio_decoder_t* (*open_plugin) (audio_decoder_class_t *this_gen, xine_stream_t *stream); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * free all class-related resources */ void (*dispose) (audio_decoder_class_t *this_gen); }; #define default_audio_decoder_class_dispose (void (*) (audio_decoder_class_t *this_gen))free struct audio_decoder_s { /* * decode data from buf and feed decoded samples to * audio output */ void (*decode_data) (audio_decoder_t *this_gen, buf_element_t *buf); /* * reset decoder after engine flush (prepare for new * audio data not related to recently decoded data) */ void (*reset) (audio_decoder_t *this_gen); /* * inform decoder that a time reference discontinuity has happened. * that is, it must forget any currently held pts value */ void (*discontinuity) (audio_decoder_t *this_gen); /* * close down, free all resources */ void (*dispose) (audio_decoder_t *this_gen); /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; }; #endif xine-lib-1.2/include/xine/xineutils.h0000644000175000017500000007424514647725152015463 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef XINEUTILS_H #define XINEUTILS_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #ifdef WIN32 #else # include #endif #include #include #include #include #include #include #include #include #include #include #include /* * Mark exported data symbols for link engine library clients with older * Win32 compilers */ #if defined(WIN32) && !defined(XINE_LIBRARY_COMPILE) # define DL_IMPORT __declspec(dllimport) # define extern DL_IMPORT extern #endif /* Amiga style doubly linked lists, taken from TJtools. * Most compilers will support the straightforward aliasing safe version. * For others, try that "volatile" hack. */ typedef struct dnode_st { struct dnode_st *next, *prev; } dnode_t; #ifdef HAVE_NAMELESS_STRUCT_IN_UNION # define DLIST_H(l) (&(l)->h) # define DLIST_T(l) (&(l)->t) typedef union { struct { dnode_t *head, *null, *tail; }; struct { dnode_t h; dnode_t *dummy1; }; struct { dnode_t *dummy2; dnode_t t; }; } dlist_t; #else # define DLIST_H(l) ((void *)(&(l)->head)) # define DLIST_T(l) ((void *)(&(l)->null)) typedef struct { dnode_t * volatile head; dnode_t *null; dnode_t * volatile tail; } dlist_t; #endif #define DLIST_IS_EMPTY(l) ((l)->head == DLIST_T(l)) #define DLIST_REMOVE(n) { \ dnode_t *dl_rm_this = n; \ dnode_t *dl_rm_prev = dl_rm_this->prev; \ dnode_t *dl_rm_next = dl_rm_this->next; \ dl_rm_next->prev = dl_rm_prev; \ dl_rm_prev->next = dl_rm_next; \ } #define DLIST_ADD_HEAD(n,l) { \ dlist_t *dl_ah_list = l; \ dnode_t *dl_ah_node = n; \ dnode_t *dl_ah_head = dl_ah_list->head; \ dl_ah_node->next = dl_ah_head; \ dl_ah_node->prev = DLIST_H(dl_ah_list); \ dl_ah_list->head = dl_ah_node; \ dl_ah_head->prev = dl_ah_node; \ } #define DLIST_ADD_TAIL(n,l) { \ dlist_t *dl_at_list = l; \ dnode_t *dl_at_node = n; \ dnode_t *dl_at_tail = dl_at_list->tail; \ dl_at_node->next = DLIST_T(dl_at_list); \ dl_at_node->prev = dl_at_tail; \ dl_at_tail->next = dl_at_node; \ dl_at_list->tail = dl_at_node; \ } #define DLIST_INSERT(n,h) { \ dnode_t *dl_i_node = n; \ dnode_t *dl_i_here = h; \ dnode_t *dl_i_prev = dl_i_here->prev; \ dl_i_prev->next = dl_i_node; \ dl_i_here->prev = dl_i_node; \ dl_i_node->next = dl_i_here; \ dl_i_node->prev = dl_i_prev; \ } #define DLIST_INIT(l) { \ dlist_t *dl_in_list = l; \ dl_in_list->head = DLIST_T(dl_in_list); \ dl_in_list->null = NULL; \ dl_in_list->tail = DLIST_H(dl_in_list); } /* * debugable mutexes */ typedef struct { pthread_mutex_t mutex; char id[80]; char *locked_by; } xine_mutex_t; int xine_mutex_init (xine_mutex_t *mutex, const pthread_mutexattr_t *mutexattr, const char *id) XINE_PROTECTED; int xine_mutex_lock (xine_mutex_t *mutex, const char *who) XINE_PROTECTED; int xine_mutex_unlock (xine_mutex_t *mutex, const char *who) XINE_PROTECTED; int xine_mutex_destroy (xine_mutex_t *mutex) XINE_PROTECTED; /* CPU Acceleration */ /* * The type of an value that fits in an MMX register (note that long * long constant values MUST be suffixed by LL and unsigned long long * values by ULL, lest they be truncated by the compiler) */ /* generic accelerations */ #define MM_ACCEL_MLIB 0x00000001 /* x86 accelerations */ #define MM_ACCEL_X86_MMX 0x80000000 #define MM_ACCEL_X86_3DNOW 0x40000000 #define MM_ACCEL_X86_MMXEXT 0x20000000 #define MM_ACCEL_X86_SSE 0x10000000 #define MM_ACCEL_X86_SSE2 0x08000000 #define MM_ACCEL_X86_SSE3 0x04000000 #define MM_ACCEL_X86_SSSE3 0x02000000 #define MM_ACCEL_X86_SSE4 0x01000000 #define MM_ACCEL_X86_SSE42 0x00800000 #define MM_ACCEL_X86_AVX 0x00400000 /* powerpc accelerations and features */ #define MM_ACCEL_PPC_ALTIVEC 0x04000000 #define MM_ACCEL_PPC_CACHE32 0x02000000 /* SPARC accelerations */ #define MM_ACCEL_SPARC_VIS 0x01000000 #define MM_ACCEL_SPARC_VIS2 0x00800000 /* x86 compat defines */ #define MM_MMX MM_ACCEL_X86_MMX #define MM_3DNOW MM_ACCEL_X86_3DNOW #define MM_MMXEXT MM_ACCEL_X86_MMXEXT #define MM_SSE MM_ACCEL_X86_SSE #define MM_SSE2 MM_ACCEL_X86_SSE2 uint32_t xine_mm_accel (void) XINE_CONST XINE_PROTECTED; int xine_cpu_count(void) XINE_CONST XINE_PROTECTED; /* Optimized/fast memcpy */ extern void *(* xine_fast_memcpy)(void *to, const void *from, size_t len) XINE_PROTECTED; /* len (usually) < 500, but not a build time constant. */ #define xine_small_memcpy(xsm_to,xsm_from,xsm_len) memcpy (xsm_to, xsm_from, xsm_len) #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) # if defined(ARCH_X86) # undef xine_small_memcpy static inline void *xine_small_memcpy (void *to, const void *from, size_t len) { void *t2 = to; size_t l2 = len; # if !defined(__clang__) && !defined(__cplusplus) __asm__ __volatile__ ( "cld\n\trep movsb" : "=S" (from), "=D" (t2), "=c" (l2), "=m" (*(struct {char foo[len];} *)to) : "0" (from), "1" (t2), "2" (l2) : "cc" ); # else /* clang dislikes virtual variable size struct */ __asm__ __volatile__ ( "cld\n\trep movsb" : "=S" (from), "=D" (t2), "=c" (l2) : "0" (from), "1" (t2), "2" (l2) : "cc", "memory" ); # endif (void)from; (void)t2; (void)l2; return to; } # endif #endif /* * Debug stuff */ /* * profiling (unworkable in non DEBUG isn't defined) */ void xine_profiler_init (void) XINE_PROTECTED; int xine_profiler_allocate_slot (const char *label) XINE_PROTECTED; void xine_profiler_start_count (int id) XINE_PROTECTED; void xine_profiler_stop_count (int id) XINE_PROTECTED; void xine_profiler_print_results (void) XINE_PROTECTED; /* * xine_container_of() * calculate struct pointer from field pointer */ #if defined(__GNUC__) # define xine_container_of(ptr, type, member) \ ({ \ const typeof(((type *)0)->member) *__mptr = (ptr); \ (type *)(void *)((char *)__mptr - offsetof(type, member)); \ }) #else # define xine_container_of(ptr, type, member) \ ((type *)(void *)((char *)(1 ? (ptr) : &((type *)0)->member) - offsetof(type, member))) #endif /* * Allocate and clean memory size_t 'size', then return the pointer * to the allocated memory. */ void *xine_xmalloc(size_t size) XINE_MALLOC XINE_DEPRECATED XINE_PROTECTED; void *xine_xcalloc(size_t nmemb, size_t size) XINE_MALLOC XINE_PROTECTED; /* * Free allocated memory and set pointer to NULL * @param ptr Pointer to the pointer to the memory block which should be freed. */ static inline void _x_freep(void *ptr) { void **p = (void **)ptr; free (*p); *p = NULL; } static inline void _x_freep_wipe_string(char **pp) { char *p = *pp; while (p && *p) *p++ = 0; _x_freep(pp); } /* * Copy blocks of memory. */ void *xine_memdup (const void *src, size_t length) XINE_PROTECTED; void *xine_memdup0 (const void *src, size_t length) XINE_PROTECTED; /** * Get/resize/free aligned memory. */ #ifndef XINE_MEM_ALIGN # define XINE_MEM_ALIGN 32 #endif void *xine_mallocz_aligned (size_t size) XINE_PROTECTED XINE_MALLOC; void *xine_malloc_aligned (size_t size) XINE_PROTECTED XINE_MALLOC; void xine_free_aligned (void *ptr) XINE_PROTECTED; void *xine_realloc_aligned (void *ptr, size_t size) XINE_PROTECTED; #define xine_freep_aligned(xinefreepptr) do {xine_free_aligned (*(xinefreepptr)); *(xinefreepptr) = NULL; } while (0) /** * Base64 encoder. * from: pointer to binary input. * to: pointer to output string buffer. * size: byte length of input. * ret: length of output string (without \0). * Note that both buffers need 4 writable padding bytes. */ size_t xine_base64_encode (uint8_t *from, char *to, size_t size) XINE_PROTECTED; /** * Base64 decoder. * from: pointer to input string or line formatted / indented, null terminated text. * to: pointer to output buffer. * ret: length of output in bytes. */ size_t xine_base64_decode (const char *from, uint8_t *to) XINE_PROTECTED; /** * Checksum calculator. */ uint32_t xine_crc32_ieee (uint32_t crc, const uint8_t *data, size_t len) XINE_PROTECTED; uint32_t xine_crc16_ansi (uint32_t crc, const uint8_t *data, size_t len) XINE_PROTECTED; /* * Get user home directory. */ const char *xine_get_homedir(void) XINE_PROTECTED; #if defined(WIN32) || defined(__CYGWIN__) /* * Get other xine directories. */ const char *xine_get_pluginroot(void) XINE_PROTECTED; const char *xine_get_plugindir(void) XINE_PROTECTED; const char *xine_get_fontdir(void) XINE_PROTECTED; const char *xine_get_localedir(void) XINE_PROTECTED; #endif /* * Clean a string (remove spaces and '=' at the begin, * and '\n', '\r' and spaces at the end. */ char *xine_chomp (char *str) XINE_PROTECTED; /* * A thread-safe usecond sleep */ void xine_usec_sleep(unsigned usec) XINE_PROTECTED; /* compatibility macros */ #define xine_strpbrk(S, ACCEPT) strpbrk((S), (ACCEPT)) #define xine_strsep(STRINGP, DELIM) strsep((STRINGP), (DELIM)) #define xine_setenv(NAME, VAL, XX) setenv((NAME), (VAL), (XX)) /** * append to a string, reallocating * normally, updates & returns *dest * on error, *dest is unchanged & NULL is returned. */ char *xine_strcat_realloc (char **dest, const char *append) XINE_PROTECTED; /** * asprintf wrapper * allocate a string large enough to hold the output, and return a pointer to * it. This pointer should be passed to free when it is no longer needed. * return NULL on error. */ char *_x_asprintf(const char *format, ...) XINE_PROTECTED XINE_MALLOC XINE_FORMAT_PRINTF(1, 2); /** * opens a file, ensuring that the descriptor will be closed * automatically after a fork/execute. */ int xine_open_cloexec(const char *name, int flags) XINE_PROTECTED; /** * creates a file, ensuring that the descriptor will be closed * automatically after a fork/execute. */ int xine_create_cloexec(const char *name, int flags, mode_t mode) XINE_PROTECTED; /** * creates a socket, ensuring that the descriptor will be closed * automatically after a fork/execute. */ int xine_socket_cloexec(int domain, int type, int protocol) XINE_PROTECTED; /* * Color Conversion Utility Functions * The following data structures and functions facilitate the conversion * of RGB images to packed YUV (YUY2) images. There are also functions to * convert from YUV9 -> YV12. All of the meaty details are written in * color.c. */ typedef struct yuv_planes_s { unsigned char *y; unsigned char *u; unsigned char *v; unsigned int row_width; /* frame width */ unsigned int row_count; /* frame height */ } yuv_planes_t; void init_yuv_conversion(void) XINE_PROTECTED; void init_yuv_planes(yuv_planes_t *yuv_planes, int width, int height) XINE_PROTECTED; void free_yuv_planes(yuv_planes_t *yuv_planes) XINE_PROTECTED; extern void (*yuv444_to_yuy2) (const yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int pitch) XINE_PROTECTED; extern void (*yuv9_to_yv12) (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, const unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, int width, int height) XINE_PROTECTED; extern void (*yuv411_to_yv12) (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, const unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, int width, int height) XINE_PROTECTED; extern void (*yv12_to_yuy2) (const unsigned char *y_src, int y_src_pitch, const unsigned char *u_src, int u_src_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, int width, int height, int progressive) XINE_PROTECTED; extern void (*yuy2_to_yv12) (const unsigned char *yuy2_map, int yuy2_pitch, unsigned char *y_dst, int y_dst_pitch, unsigned char *u_dst, int u_dst_pitch, unsigned char *v_dst, int v_dst_pitch, int width, int height) XINE_PROTECTED; /* convert full range rgb to mpeg range yuv */ #define SCALESHIFT 16 #define SCALEFACTOR (1<> SCALESHIFT) #define COMPUTE_U(r, g, b) \ (unsigned char) \ ((u_r_table[r] + u_g_table[g] + uv_br_table[b]) >> SCALESHIFT) #define COMPUTE_V(r, g, b) \ (unsigned char) \ ((uv_br_table[r] + v_g_table[g] + v_b_table[b]) >> SCALESHIFT) /* Binaries using these old ones keep working, and get the full vs mpeg range bug fixed transparently as well. #define COMPUTE_Y(r, g, b) \ (unsigned char) \ ((y_r_table[r] + y_g_table[g] + y_b_table[b]) / SCALEFACTOR) #define COMPUTE_U(r, g, b) \ (unsigned char) \ ((u_r_table[r] + u_g_table[g] + u_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) #define COMPUTE_V(r, g, b) \ (unsigned char) \ ((v_r_table[r] + v_g_table[g] + v_b_table[b]) / SCALEFACTOR + CENTERSAMPLE) */ #define UNPACK_BGR15(packed_pixel, r, g, b) \ b = (packed_pixel & 0x7C00) >> 7; \ g = (packed_pixel & 0x03E0) >> 2; \ r = (packed_pixel & 0x001F) << 3; #define UNPACK_BGR16(packed_pixel, r, g, b) \ b = (packed_pixel & 0xF800) >> 8; \ g = (packed_pixel & 0x07E0) >> 3; \ r = (packed_pixel & 0x001F) << 3; #define UNPACK_RGB15(packed_pixel, r, g, b) \ r = (packed_pixel & 0x7C00) >> 7; \ g = (packed_pixel & 0x03E0) >> 2; \ b = (packed_pixel & 0x001F) << 3; #define UNPACK_RGB16(packed_pixel, r, g, b) \ r = (packed_pixel & 0xF800) >> 8; \ g = (packed_pixel & 0x07E0) >> 3; \ b = (packed_pixel & 0x001F) << 3; extern int y_r_table[256] XINE_PROTECTED; extern int y_g_table[256] XINE_PROTECTED; extern int y_b_table[256] XINE_PROTECTED; extern int uv_br_table[256] XINE_PROTECTED; extern int u_r_table[256] XINE_PROTECTED; extern int u_g_table[256] XINE_PROTECTED; extern int u_b_table[256] XINE_PROTECTED; extern int v_r_table[256] XINE_PROTECTED; extern int v_g_table[256] XINE_PROTECTED; extern int v_b_table[256] XINE_PROTECTED; /* TJ. direct sliced rgb -> yuy2 conversion */ typedef struct rgb2yuy2_s rgb2yuy2_t; extern rgb2yuy2_t *rgb2yuy2_alloc (int color_matrix, const char *format) XINE_PROTECTED; extern void rgb2yuy2_free (rgb2yuy2_t *rgb2yuy2) XINE_PROTECTED; extern void rgb2yuy2_slice (rgb2yuy2_t *rgb2yuy2, const uint8_t *in, int ipitch, uint8_t *out, int opitch, int width, int height) XINE_PROTECTED; extern void rgb2yuy2_palette (rgb2yuy2_t *rgb2yuy2, const uint8_t *pal, int num_colors, int bits_per_pixel) XINE_PROTECTED; extern void rgb2yv12_slice (rgb2yuy2_t *rgb2yuy2, const uint8_t *src, int src_stride, uint8_t *y_dst, int y_pitch, uint8_t *u_dst, int u_pitch, uint8_t *v_dst, int v_pitch, int width, int height) XINE_PROTECTED; /* frame copying functions */ extern void yv12_to_yv12 (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dst, int y_dst_pitch, const unsigned char *u_src, int u_src_pitch, unsigned char *u_dst, int u_dst_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *v_dst, int v_dst_pitch, int width, int height) XINE_PROTECTED; extern void yuy2_to_yuy2 (const unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch, int width, int height) XINE_PROTECTED; void _x_nv12_to_yv12(const uint8_t *y_src, int y_src_pitch, const uint8_t *uv_src, int uv_src_pitch, uint8_t *y_dst, int y_dst_pitch, uint8_t *u_dst, int u_dst_pitch, uint8_t *v_dst, int v_dst_pitch, int width, int height) XINE_PROTECTED; void _x_yv12_to_nv12(const uint8_t *y_src, int y_src_pitch, const uint8_t *u_src, int u_src_pitch, const uint8_t *v_src, int v_src_pitch, uint8_t *y_dst, int y_dst_pitch, uint8_t *uv_dst, int uv_dst_pitch, int width, int height) XINE_PROTECTED; void _x_yuy2_to_nv12(const uint8_t *src_yuy2_map, int yuy2_pitch, uint8_t *y_dst, int y_dst_pitch, uint8_t *uv_dst, int uv_dst_pitch, int width, int height) XINE_PROTECTED; /* print a hexdump of the given data */ void xine_hexdump (const void *buf, int length) XINE_PROTECTED; /* * Optimization macros for conditions * Taken from the FIASCO L4 microkernel sources */ #if !defined(__GNUC__) || __GNUC__ < 3 # define EXPECT_TRUE(x) (x) # define EXPECT_FALSE(x) (x) #else # define EXPECT_TRUE(x) __builtin_expect((x),1) # define EXPECT_FALSE(x) __builtin_expect((x),0) #endif #ifdef NDEBUG #define _x_assert(exp) \ do { \ if (!(exp)) \ fprintf(stderr, "assert: %s:%d: %s: Assertion `%s' failed.\n", \ __FILE__, __LINE__, __XINE_FUNCTION__, #exp); \ } while(0) #else #define _x_assert(exp) \ do { \ if (!(exp)) { \ fprintf(stderr, "assert: %s:%d: %s: Assertion `%s' failed.\n", \ __FILE__, __LINE__, __XINE_FUNCTION__, #exp); \ abort(); \ } \ } while(0) #endif XINE_DEPRECATED static inline void _x_abort_is_deprecated(void) {} #define _x_abort() \ do { \ fprintf(stderr, "abort: %s:%d: %s: Aborting.\n", \ __FILE__, __LINE__, __XINE_FUNCTION__); \ abort(); \ _x_abort_is_deprecated(); \ } while(0) /****** logging with xine **********************************/ #ifndef LOG_MODULE #define LOG_MODULE __FILE__ #endif /* LOG_MODULE */ #define LOG_MODULE_STRING printf("%s: ", LOG_MODULE ); #ifdef LOG_VERBOSE #define LONG_LOG_MODULE_STRING \ printf("%s: (%s:%d) ", LOG_MODULE, __XINE_FUNCTION__, __LINE__ ); #else #define LONG_LOG_MODULE_STRING LOG_MODULE_STRING #endif /* LOG_VERBOSE */ #ifdef LOG #if defined(__GNUC__) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) #define lprintf(fmt, args...) \ do { \ LONG_LOG_MODULE_STRING \ printf(fmt, ##args); \ fflush(stdout); \ } while(0) #else /* __GNUC__ */ #ifdef _MSC_VER #define lprintf(fmtargs) \ do { \ LONG_LOG_MODULE_STRING \ printf("%s", fmtargs); \ fflush(stdout); \ } while(0) #else /* _MSC_VER */ #define lprintf(...) \ do { \ LONG_LOG_MODULE_STRING \ printf(__VA_ARGS__); \ fflush(stdout); \ } while(0) #endif /* _MSC_VER */ #endif /* __GNUC__ */ #else /* LOG */ #if defined(DEBUG) && defined(XINE_COMPILE) XINE_FORMAT_PRINTF(1, 2) static inline void lprintf(const char * fmt, ...) { (void)fmt; } #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define lprintf(...) do {} while(0) #elif defined(__GNUC__) #define lprintf(fmt, args...) do {} while(0) #elif defined(_MSC_VER) void __inline lprintf(const char * fmt, ...) {} #else #define lprintf(...) do {} while(0) #endif #endif /* LOG */ #if defined(__GNUC__) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) #define llprintf(cat, fmt, args...) \ do{ \ if(cat){ \ LONG_LOG_MODULE_STRING \ printf( fmt, ##args ); \ } \ }while(0) #else #ifdef _MSC_VER #define llprintf(cat, fmtargs) \ do{ \ if(cat){ \ LONG_LOG_MODULE_STRING \ printf( "%s", fmtargs ); \ } \ }while(0) #else #define llprintf(cat, ...) \ do{ \ if(cat){ \ LONG_LOG_MODULE_STRING \ printf( __VA_ARGS__ ); \ } \ }while(0) #endif /* _MSC_VER */ #endif /* __GNUC__ */ #if defined(__GNUC__) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L) #define xprintf(xine, verbose, fmt, args...) \ do { \ if((xine) && (xine)->verbosity >= verbose){ \ xine_log(xine, XINE_LOG_TRACE, fmt, ##args); \ } \ } while(0) #else #ifdef _MSC_VER void xine_xprintf(xine_t *xine, int verbose, const char *fmt, ...); #define xprintf xine_xprintf #else #define xprintf(xine, verbose, ...) \ do { \ if((xine) && (xine)->verbosity >= verbose){ \ xine_log(xine, XINE_LOG_TRACE, __VA_ARGS__); \ } \ } while(0) #endif /* _MSC_VER */ #endif /* __GNUC__ */ /* time measuring macros for profiling tasks */ #ifdef DEBUG # define XINE_PROFILE(function) \ do { \ struct timeval current_time; \ double dtime; \ gettimeofday(¤t_time, NULL); \ dtime = -(current_time.tv_sec + (current_time.tv_usec / 1000000.0)); \ function; \ gettimeofday(¤t_time, NULL); \ dtime += current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ printf("%s: (%s:%d) took %lf seconds\n", \ LOG_MODULE, __XINE_FUNCTION__, __LINE__, dtime); \ } while(0) # define XINE_PROFILE_ACCUMULATE(function) \ do { \ struct timeval current_time; \ static double dtime = 0; \ gettimeofday(¤t_time, NULL); \ dtime -= current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ function; \ gettimeofday(¤t_time, NULL); \ dtime += current_time.tv_sec + (current_time.tv_usec / 1000000.0); \ printf("%s: (%s:%d) took %lf seconds\n", \ LOG_MODULE, __XINE_FUNCTION__, __LINE__, dtime); \ } while(0) #else # define XINE_PROFILE(function) function # define XINE_PROFILE_ACCUMULATE(function) function #endif /* DEBUG */ /** * get encoding of current locale */ char *xine_get_system_encoding(void) XINE_MALLOC XINE_PROTECTED; /* * guess default encoding for the subtitles */ const char *xine_guess_spu_encoding(void) XINE_PROTECTED; /* * use the best clock reference (API compatible with gettimeofday) * note: it will be a monotonic clock, if available. */ struct timezone; int xine_monotonic_clock(struct timeval *tv, struct timezone *tz) XINE_PROTECTED; /** * Unknown FourCC reporting functions */ void _x_report_video_fourcc (xine_t *, const char *module, uint32_t) XINE_PROTECTED; void _x_report_audio_format_tag (xine_t *, const char *module, uint32_t) XINE_PROTECTED; /** fast strings are either inside an application supplied buffer, * or they are (re)allocated by xine_fast_string_set (). * the returned pointer will be at least 8 byte aligned, * and can be read like an ordinary C string. */ #define XINE_FAST_STRING 1 /** return the byte size needed for an application supplied buffer. */ size_t xine_fast_string_need (size_t max_strlen) XINE_PROTECTED; /** return the actual max strlen. */ size_t xine_fast_string_max (char *fast_string) XINE_PROTECTED; /** set up a fast string inside an application supplied buffer. */ char *xine_fast_string_init (char *buf, size_t bsize) XINE_PROTECTED; /** set or change the contents of a fast string. * fast_text may be NULL, to allocate a new one. * you can even edit the string manually, then apply the new size with text == NULL. */ char *xine_fast_string_set (char *fast_string, const char *text, size_t tsize) XINE_PROTECTED; /** fast strcmp (). * BTW: XINE_PROTECTED does not link on some systems when doing * xine_sarray_new (size, (xine_sarray_comparator_t)xine_fast_string_cmp);. */ int xine_fast_string_cmp (char *fast_string1, char *fast_string2); /** free a fast string if it is not application supplied. */ void xine_fast_string_free (char **fast_string) XINE_PROTECTED; #define XINE_REF_STRING 1 /** create or reuse a xine reference counted string, whose contents shall remain unchanged. * use len == -1 if not kown. */ char *xine_ref_string_ref (const char *s, int len) XINE_PROTECTED; /** fast if s is a xine reference counted string. */ size_t xine_ref_string_len (const char *s) XINE_PROTECTED; /** same as _x_freep if s is _not_ a xine reference counted string. */ int xine_ref_string_unref (char **s) XINE_PROTECTED; /** stream parsers do delay data, but often do not care about the frame pts * that need to be delayed as well. this may help here. */ #define XINE_PTS_QUEUE 1 typedef struct xine_pts_queue_s xine_pts_queue_t; /** create a new instance. */ xine_pts_queue_t *xine_pts_queue_new (void) XINE_PROTECTED; /** reset after a stream seek. */ void xine_pts_queue_reset (xine_pts_queue_t *queue) XINE_PROTECTED; /** tell what the parser has consumed. pts == 0 if unknown. */ void xine_pts_queue_put (xine_pts_queue_t *queue, size_t bytes, int64_t pts) XINE_PROTECTED; /** tell what the parser has delivered, and get the filtered pts or 0. */ int64_t xine_pts_queue_get (xine_pts_queue_t *queue, size_t bytes) XINE_PROTECTED; /** you no longer need the queue. */ void xine_pts_queue_delete (xine_pts_queue_t **queue) XINE_PROTECTED; /** xine timespec magic. */ #define XINE_TS 1 /** XINE_TS >= 1: Well. * libcurl.curl_getdate () fails on plain "01 January 1970 00:00:04 GMT". * shell.date fails on "2020-08-31T23:55:00.000+02:00". * here comes yet another "we can do better" attempt: * input: * ts: the fallback or relative base time. * string: the date/time in some halfway common format. * output: * ts: what we got. * return: 0 (OK) or some Exxx error code. */ int xine_ts_from_string (struct timespec *ts, const char *string) XINE_PROTECTED; /** XINE_TS >= 1: a += b. */ void xine_ts_add (struct timespec *a, const struct timespec *b) XINE_PROTECTED; /** XINE_TS >= 1: a -= b. */ void xine_ts_sub (struct timespec *a, const struct timespec *b) XINE_PROTECTED; /** XINE_TS >= 1: ts * timebase. */ int64_t xine_ts_to_timebase (const struct timespec *ts, uint32_t timebase) XINE_PROTECTED; /** xine rational numbers. */ #define XINE_RATS 1 typedef struct { int64_t num, den; } xine_rats_t; /** XINE_RATS >= 1: shorten value. */ void xine_rats_shorten (xine_rats_t *value) XINE_PROTECTED; /* don't harm following code */ #ifdef extern # undef extern #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/spu.h0000644000175000017500000000350714647725152014237 0ustar meme/* * Copyright (C) 2007-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifndef XINE_UTILS_SPU_H #define XINE_UTILS_SPU_H #include #include typedef struct xine_spu_opacity_s xine_spu_opacity_t; struct xine_spu_opacity_s { uint8_t black, colour; }; void _x_spu_misc_init (xine_t *); void _x_spu_get_opacity (xine_t *, xine_spu_opacity_t *) XINE_PROTECTED; /* in: trans = 0..255, 0=opaque * out: 0..255, 0=transparent */ int _x_spu_calculate_opacity (const clut_t *, uint8_t trans, const xine_spu_opacity_t *) XINE_PROTECTED; /** @brief (re)calculate DVB subtitle opacity table if needed. * @param xine pointer to the xine instance. * @param opacity pointer to an array of 0...15 opacity values to fill in for each color. * @param clut pointer to an array of colors, with .foo set to 0...255 transparency value. * @param gen pointer to an int that you set to 0 initially, and when colors have changed. * @param n count of colors. */ void _x_spu_dvb_opacity (xine_t *xine, uint8_t *opacity, const clut_t *clut, int *gen, uint32_t n) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/osd.h0000644000175000017500000002121414647725152014210 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * OSD stuff (text and graphic primitives) */ #ifndef HAVE_OSD_H #define HAVE_OSD_H #ifdef HAVE_ICONV # include #endif #include typedef struct osd_object_s osd_object_t; typedef struct osd_renderer_s osd_renderer_t; typedef struct osd_font_s osd_font_t; typedef struct osd_ft2context_s osd_ft2context_t; struct osd_object_s { osd_object_t *next; osd_renderer_t *renderer; int width, height; /* work area dimentions */ uint8_t *area; /* work area */ int area_touched; /* work area was used for painting */ int display_x,display_y; /* where to display it in screen */ /* video output area within osd extent */ int video_window_x, video_window_y; int video_window_width, video_window_height; /* extent of reference coordinate system */ int extent_width, extent_height; /* clipping box inside work area */ int x1, y1; int x2, y2; uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */ uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */ #ifdef HAVE_ICONV iconv_t cd; /* iconv handle of encoding */ char *encoding; /* name of encoding */ #endif osd_font_t *font; osd_ft2context_t *ft2; /* this holds an optional ARGB overlay, which * is only be used by supported video_out modules. * right now this is only vdpau */ argb_layer_t *argb_layer; int32_t handle; }; /* this one is public */ struct xine_osd_s { osd_object_t osd; }; struct osd_renderer_s { xine_stream_t *stream; /* * open a new osd object. this will allocated an empty (all zero) drawing * area where graphic primitives may be used. * It is ok to specify big width and height values. The render will keep * track of the smallest changed area to not generate too big overlays. * A default palette is initialized (i sugest keeping color 0 as transparent * for the sake of simplicity) */ osd_object_t* (*new_object) (osd_renderer_t *this_gen, int width, int height); /* * free osd object */ void (*free_object) (osd_object_t *osd_to_close); /* * send the osd to be displayed at given pts (0=now) * the object is not changed. there may be subsequent drawing on it. */ int (*show) (osd_object_t *osd, int64_t vpts ); /* * send event to hide osd at given pts (0=now) * the object is not changed. there may be subsequent drawing on it. */ int (*hide) (osd_object_t *osd, int64_t vpts ); /* * draw point. */ void (*point) (osd_object_t *osd, int x, int y, int color); /* * Bresenham line implementation on osd object */ void (*line) (osd_object_t *osd, int x1, int y1, int x2, int y2, int color ); /* * filled rectangle */ void (*filled_rect) (osd_object_t *osd, int x1, int y1, int x2, int y2, int color ); /* * set palette (color and transparency) * * NOTE: both color and trans arrays must hold OVL_PALETTE_SIZE entries ! */ void (*set_palette) (osd_object_t *osd, const uint32_t *color, const uint8_t *trans ); /* * set on existing text palette * (-1 to set used specified palette) * * color_base specifies the first color index to use for this text * palette. The OSD palette is then modified starting at this * color index, up to the size of the text palette. * * Use OSD_TEXT1, OSD_TEXT2, ... for some preasssigned color indices. */ void (*set_text_palette) (osd_object_t *osd, int palette_number, int color_base ); /* * get palette (color and transparency) */ void (*get_palette) (osd_object_t *osd, uint32_t *color, uint8_t *trans); /* * set position were overlay will be blended */ void (*set_position) (osd_object_t *osd, int x, int y); /* * set the font of osd object */ int (*set_font) (osd_object_t *osd, const char *fontname, int size); /* * set encoding of text * * NULL ... no conversion (iso-8859-1) * "" ... locale encoding */ int (*set_encoding) (osd_object_t *osd, const char *encoding); /* * render text in current encoding on x,y position * no \n yet * * The text is assigned the colors starting at the index specified by * color_base up to the size of the text palette. * * Use OSD_TEXT1, OSD_TEXT2, ... for some preasssigned color indices. */ int (*render_text) (osd_object_t *osd, int x1, int y1, const char *text, int color_base); /* * get width and height of how text will be renderized */ int (*get_text_size) (osd_object_t *osd, const char *text, int *width, int *height); /* * close osd rendering engine * loaded fonts are unloaded * osd objects are closed */ void (*close) (osd_renderer_t *this_gen); /* * clear an osd object (empty drawing area) */ void (*clear) (osd_object_t *osd ); /* * paste a bitmap with optional palette mapping */ void (*draw_bitmap) (osd_object_t *osd, const uint8_t *bitmap, int x1, int y1, int width, int height, const uint8_t *palette_map); /* * send the osd to be displayed (unscaled) at given pts (0=now) * the object is not changed. there may be subsequent drawing on it. * overlay is blended at output (screen) resolution. */ int (*show_unscaled) (osd_object_t *osd, int64_t vpts ); /* * see xine.h for defined XINE_OSD_CAP_ values. */ uint32_t (*get_capabilities) (osd_object_t *osd); /* * define extent of reference coordinate system for video * resolution independent osds. both sizes must be > 0 to * take effect. otherwise, video resolution will be used. */ void (*set_extent) (osd_object_t *osd, int extent_width, int extent_height); /* * set an argb buffer to be blended into video * the buffer must exactly match the osd dimensions * and stay valid while the osd is on screen. pass * a NULL pointer to safely remove the buffer from * the osd layer. only the dirty area will be * updated on screen. for convinience the whole * osd object will be considered dirty when setting * a different buffer pointer. * see also XINE_OSD_CAP_ARGB_LAYER */ void (*set_argb_buffer) (osd_object_t *osd, uint32_t *argb_buffer, int dirty_x, int dirty_y, int dirty_width, int dirty_height); /* * osd video window defines an area withing osd extent where the * video shall be scaled to while an osd is displayed on screen. * both width and height must be > 0 to take effect. */ void (*set_video_window) (osd_object_t *osd, int window_x, int window_y, int window_width, int window_height); /* private stuff */ pthread_mutex_t osd_mutex; video_overlay_event_t event; osd_object_t *osds; /* instances of osd */ osd_font_t *fonts; /* loaded fonts */ int textpalette; /* default textpalette */ }; /* * initialize the osd rendering engine */ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ); /* * The size of a text palette */ #define TEXT_PALETTE_SIZE 11 /* * Preassigned color indices for rendering text * (more can be added, not exceeding OVL_PALETTE_SIZE) */ #define OSD_TEXT1 (0 * TEXT_PALETTE_SIZE) #define OSD_TEXT2 (1 * TEXT_PALETTE_SIZE) #define OSD_TEXT3 (2 * TEXT_PALETTE_SIZE) #define OSD_TEXT4 (3 * TEXT_PALETTE_SIZE) #define OSD_TEXT5 (4 * TEXT_PALETTE_SIZE) #define OSD_TEXT6 (5 * TEXT_PALETTE_SIZE) #define OSD_TEXT7 (6 * TEXT_PALETTE_SIZE) #define OSD_TEXT8 (7 * TEXT_PALETTE_SIZE) #define OSD_TEXT9 (8 * TEXT_PALETTE_SIZE) #define OSD_TEXT10 (9 * TEXT_PALETTE_SIZE) /* * Defined palettes for rendering osd text * (more can be added later) */ #define NUMBER_OF_TEXT_PALETTES 4 #define TEXTPALETTE_WHITE_BLACK_TRANSPARENT 0 #define TEXTPALETTE_WHITE_NONE_TRANSPARENT 1 #define TEXTPALETTE_WHITE_NONE_TRANSLUCID 2 #define TEXTPALETTE_YELLOW_BLACK_TRANSPARENT 3 #endif xine-lib-1.2/include/xine/video_out.h0000644000175000017500000005312414647725152015425 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * xine version of video_out.h * * vo_frame : frame containing yuv data and timing info, * transferred between video_decoder and video_output * * vo_driver : lowlevel, platform-specific video output code * * vo_port : generic frame_handling code, uses * a vo_driver for output */ #ifndef HAVE_VIDEO_OUT_H #define HAVE_VIDEO_OUT_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include struct plugin_node_s; typedef struct vo_frame_s vo_frame_t; typedef struct vo_driver_s vo_driver_t; typedef struct video_driver_class_s video_driver_class_t; typedef struct vo_overlay_s vo_overlay_t; typedef struct video_overlay_manager_s video_overlay_manager_t; /* public part, video drivers may add private fields * * Remember that adding new functions to this structure requires * adaption of the post plugin decoration layer. Be sure to look into * src/xine-engine/post.[ch]. */ typedef struct { void (*lock) (vo_frame_t *frame, int lock); void *display; enum { VO_DISP_TYPE_UNKNOWN = 0, VO_DISP_TYPE_X11, VO_DISP_TYPE_WAYLAND } disp_type; } vo_accel_generic_t; struct vo_frame_s { /* * member functions */ /* Provide a copy of the frame's image in an image format already known to xine. data's member */ /* have already been intialized to frame's content on entry, so it's usually only necessary to */ /* change format and img_size. In case img is set, it will point to a memory block of suitable */ /* size (size has been determined by a previous call with img == NULL). img content and img_size */ /* must adhere to the specification of _x_get_current_frame_data(). */ /* Currently this is needed for all image formats except XINE_IMGFMT_YV12 and XINE_IMGFMT_YUY2. */ void (*proc_provide_standard_frame_data) (vo_frame_t *vo_img, xine_current_frame_data_t *data); /* Duplicate picture data and acceleration specific data of a frame. */ /* if the image format isn't already known by Xine. Currently this is needed */ /* For all image formats except XINE_IMGFMT_YV12 and XINE_IMGFMT_YUY2 */ void (*proc_duplicate_frame_data) (vo_frame_t *vo_img, vo_frame_t *src); /* tell video driver to copy/convert the whole of this frame, may be NULL */ /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */ void (*proc_frame) (vo_frame_t *vo_img); /* tell video driver to copy/convert a slice of this frame, may be NULL */ /* at least one of proc_frame() and proc_slice() MUST set the variable proc_called to 1 */ void (*proc_slice) (vo_frame_t *vo_img, uint8_t **src); /* tell video driver that the decoder starts a new field */ void (*field) (vo_frame_t *vo_img, int which_field); /* append this frame to the display queue, returns number of frames to skip if decoder is late */ /* when the frame does not originate from a stream, it is legal to pass an anonymous stream */ int (*draw) (vo_frame_t *vo_img, xine_stream_t *stream); /* lock frame as reference, must be paired with free. * most decoders/drivers do not need to call this function since * newly allocated frames are already locked once. */ void (*lock) (vo_frame_t *vo_img); /* this frame is no longer used by the decoder, video driver, etc */ void (*free) (vo_frame_t *vo_img); /* free memory/resources for this frame */ void (*dispose) (vo_frame_t *vo_img); /* * public variables to decoders and vo drivers * changing anything here will require recompiling them both */ int64_t pts; /* presentation time stamp (1/90000 sec) */ int64_t vpts; /* virtual pts, generated by metronom */ int bad_frame; /* e.g. frame skipped or based on skipped frame */ int duration; /* frame length in time, in 1/90000 sec */ /* yv12 (planar) base[0]: y, base[1]: u, base[2]: v */ /* yuy2 (interleaved) base[0]: yuyv..., base[1]: --, base[2]: -- */ uint8_t *base[3]; int pitches[3]; /* info that can be used for interlaced output (e.g. tv-out) */ int top_field_first; int repeat_first_field; /* note: progressive_frame is set wrong on many mpeg2 streams. for * that reason, this flag should be interpreted as a "hint". */ int progressive_frame; int picture_coding_type; /* cropping to be done */ int crop_left, crop_right, crop_top, crop_bottom; int lock_counter; pthread_mutex_t mutex; /* protect access to lock_count */ /* extra info coming from input or demuxers */ extra_info_t *extra_info; /* additional information to be able to duplicate frames: */ int width, height; double ratio; /* aspect ratio */ int format; /* IMGFMT_YV12 or IMGFMT_YUY2 */ int drawn; /* used by decoder, frame has already been drawn */ int flags; /* remember the frame flags */ int proc_called; /* track use of proc_*() methods */ /* Used to carry private data for accelerated plugins.*/ void *accel_data; /* "backward" references to where this frame originates from */ xine_video_port_t *port; vo_driver_t *driver; xine_stream_t *stream; /* displacement for overlays */ int overlay_offset_x, overlay_offset_y; /* pointer to the next frame in display order, used by some vo deint */ struct vo_frame_s *future_frame; /* * that part is used only by video_out.c for frame management * obs: changing anything here will require recompiling vo drivers */ struct vo_frame_s *next; int id; /* debugging - track this frame */ int is_first; }; /* * Remember that adding new functions to this structure requires * adaption of the post plugin decoration layer. Be sure to look into * src/xine-engine/post.[ch]. */ struct xine_video_port_s { uint32_t (*get_capabilities) (xine_video_port_t *self); /* for constants see below */ /* open display driver for video output */ /* when you are not a full-blown stream, but still need to open the port * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ void (*open) (xine_video_port_t *self, xine_stream_t *stream); /* * get_frame - allocate an image buffer from display driver * * params : width == width of video to display. * height == height of video to display. * ratio == aspect ration information * format == FOURCC descriptor of image format * flags == field/prediction flags */ vo_frame_t* (*get_frame) (xine_video_port_t *self, uint32_t width, uint32_t height, double ratio, int format, int flags); /* create a new grab video frame */ xine_grab_video_frame_t* (*new_grab_video_frame) (xine_video_port_t *self); /* retrieves the last displayed frame (useful for taking snapshots) */ vo_frame_t* (*get_last_frame) (xine_video_port_t *self); /* overlay stuff */ void (*enable_ovl) (xine_video_port_t *self, int ovl_enable); /* get overlay manager */ video_overlay_manager_t* (*get_overlay_manager) (xine_video_port_t *self); /* flush video_out fifo */ void (*flush) (xine_video_port_t *self); /* trigger immediate drawing */ void (*trigger_drawing) (xine_video_port_t *self); /* Get/Set video property * * See VO_PROP_* bellow */ int (*get_property) (xine_video_port_t *self, int property); int (*set_property) (xine_video_port_t *self, int property, int value); /* return true if port is opened for this stream, stream can be anonymous */ int (*status) (xine_video_port_t *self, xine_stream_t *stream, int *width, int *height, int64_t *img_duration); /* video driver is no longer used by decoder => close */ /* when you are not a full-blown stream, but still need to close the port * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ void (*close) (xine_video_port_t *self, xine_stream_t *stream); /* called on xine exit */ void (*exit) (xine_video_port_t *self); /* the driver in use */ vo_driver_t *driver; }; /* constants for the get/set property functions. * MAINTAINERS: please keep in sync with xine.h/XINE_PARAM_VO_*. */ #define VO_PROP_INTERLACED 0 #define VO_PROP_ASPECT_RATIO 1 #define VO_PROP_HUE 2 #define VO_PROP_SATURATION 3 #define VO_PROP_CONTRAST 4 #define VO_PROP_BRIGHTNESS 5 #define VO_PROP_COLORKEY 6 #define VO_PROP_AUTOPAINT_COLORKEY 7 #define VO_PROP_ZOOM_X 8 #define VO_PROP_PAN_SCAN 9 #define VO_PROP_TVMODE 10 #define VO_PROP_MAX_NUM_FRAMES 11 #define VO_PROP_GAMMA 12 #define VO_PROP_ZOOM_Y 13 /* while this is set, vo shall drop all incoming and queued frames. * when receiving a value of -1 for this, driver shall unref any held frames, * and return their count. drivers not needing this will silently return * -1 or 0. */ #define VO_PROP_DISCARD_FRAMES 14 #define VO_PROP_WINDOW_WIDTH 15 /* read-only */ #define VO_PROP_WINDOW_HEIGHT 16 /* read-only */ #define VO_PROP_BUFS_IN_FIFO 17 /* read-only */ #define VO_PROP_NUM_STREAMS 18 /* read-only */ #define VO_PROP_OUTPUT_WIDTH 19 /* read-only */ #define VO_PROP_OUTPUT_HEIGHT 20 /* read-only */ #define VO_PROP_OUTPUT_XOFFSET 21 /* read-only */ #define VO_PROP_OUTPUT_YOFFSET 22 /* read-only */ #define VO_PROP_SHARPNESS 24 #define VO_PROP_NOISE_REDUCTION 25 #define VO_PROP_BUFS_TOTAL 26 /* read-only */ #define VO_PROP_BUFS_FREE 27 /* read-only */ #define VO_PROP_MAX_VIDEO_WIDTH 28 /* read-only */ #define VO_PROP_MAX_VIDEO_HEIGHT 29 /* read-only */ #define VO_PROP_CAPS2 30 /* read-only. second capability flags, see below. */ #define VO_PROP_TRANSFORM 31 /* XINE_VO_TRANSFORM_* */ #define VO_NUM_PROPERTIES 32 /* number of colors in the overlay palette. Currently limited to 256 at most, because some alphablend functions use an 8-bit index into the palette. This should probably be classified as a bug. */ #define OVL_PALETTE_SIZE 256 #define OVL_MAX_OPACITY 0x0f /* number of recent frames to keep in memory these frames are needed by some deinterlace algorithms FIXME: we need a method to flush the recent frames (new stream) */ #define VO_NUM_RECENT_FRAMES 2 /* get_frame flags */ #define VO_TOP_FIELD 0x0001 #define VO_BOTTOM_FIELD 0x0002 #define VO_BOTH_FIELDS (VO_TOP_FIELD | VO_BOTTOM_FIELD) #define VO_PAN_SCAN_FLAG 0x0004 #define VO_INTERLACED_FLAG 0x0008 #define VO_NEW_SEQUENCE_FLAG 0x0010 /* set after MPEG2 Sequence Header Code (used by XvMC) */ #define VO_CHROMA_422 0x0020 /* used by VDPAU, default is chroma_420 */ #define VO_STILL_IMAGE 0x0040 #define VO_GET_FRAME_MAY_FAIL 0x0080 /* video out may return NULL if frame allocation failed */ /* ((mpeg_color_matrix << 1) | color_range) inside frame.flags bits 12-8 */ #define VO_FULLRANGE 0x100 #define VO_GET_FLAGS_CM(flags) ((flags >> 8) & 31) #define VO_SET_FLAGS_CM(cm,flags) flags = ((flags) & ~0x1f00) | (((cm) & 31) << 8) /* deep color bit dept inside frame.flags bits 18-16: */ #define VO_GET_FLAGS_DEPTH(flags) (16 - ((flags >> 16) & 7)) #define VO_SET_FLAGS_DEPTH(depth,flags) flags = (((flags) & ~0x70000) | (((16 - depth) & 7) << 16)) /* video driver capabilities */ #define VO_CAP_YV12 0x00000001 /* driver can handle YUV 4:2:0 pictures */ #define VO_CAP_YUY2 0x00000002 /* driver can handle YUY2 pictures */ #define VO_CAP_XVMC_MOCOMP 0x00000004 /* driver can use XvMC motion compensation */ #define VO_CAP_XVMC_IDCT 0x00000008 /* driver can use XvMC idct acceleration */ #define VO_CAP_UNSCALED_OVERLAY 0x00000010 /* driver can blend overlay at output resolution */ #define VO_CAP_CROP 0x00000020 /* driver can crop */ #define VO_CAP_XXMC 0x00000040 /* driver can use extended XvMC */ #define VO_CAP_VDPAU_H264 0x00000080 /* driver can use VDPAU for H264 */ #define VO_CAP_VDPAU_MPEG12 0x00000100 /* driver can use VDPAU for mpeg1/2 */ #define VO_CAP_VDPAU_VC1 0x00000200 /* driver can use VDPAU for VC1 */ #define VO_CAP_VDPAU_MPEG4 0x00000400 /* driver can use VDPAU for mpeg4-part2 */ #define VO_CAP_VAAPI 0x00000800 /* driver can use VAAPI */ #define VO_CAP_COLOR_MATRIX 0x00004000 /* driver can use alternative yuv->rgb matrices */ #define VO_CAP_FULLRANGE 0x00008000 /* driver handles fullrange yuv */ #define VO_CAP_HUE 0x00010000 #define VO_CAP_SATURATION 0x00020000 #define VO_CAP_CONTRAST 0x00040000 #define VO_CAP_BRIGHTNESS 0x00080000 #define VO_CAP_COLORKEY 0x00100000 #define VO_CAP_AUTOPAINT_COLORKEY 0x00200000 #define VO_CAP_ZOOM_X 0x00400000 #define VO_CAP_ZOOM_Y 0x00800000 #define VO_CAP_CUSTOM_EXTENT_OVERLAY 0x01000000 /* driver can blend custom extent overlay to output extent */ #define VO_CAP_ARGB_LAYER_OVERLAY 0x02000000 /* driver supports true color overlay */ #define VO_CAP_VIDEO_WINDOW_OVERLAY 0x04000000 /* driver can scale video to an area within overlay */ #define VO_CAP_GAMMA 0x08000000 #define VO_CAP_SHARPNESS 0x10000000 #define VO_CAP_NOISE_REDUCTION 0x20000000 #define VO_CAP_YV12_DEEP 0x40000000 /* driver can handle deep color YV12 (9...16 bits) */ /* retrieved via VO_PROP_CAPS2 if != -1 */ #define VO_CAP2_NV12 0x00000001 /* driver can handle YUV 4:2:0 pictures as 2 planes (Y plus interleaved UV) */ #define VO_CAP2_TRANSFORM 0x00000002 /* driver can flip image */ #define VO_CAP2_ACCEL_GENERIC 0x00000004 /* vo_frame_t.accel_data == vo_accel_generic_t * */ /* * vo_driver_s contains the functions every display driver * has to implement. The vo_new_port function (see below) * should then be used to construct a vo_port using this * driver. Some of the function pointers will be copied * directly into xine_video_port_s, others will be called * from generic vo functions. */ #define VIDEO_OUT_DRIVER_IFACE_VERSION 22 struct vo_driver_s { uint32_t (*get_capabilities) (vo_driver_t *self); /* for constants see above */ /* * allocate an vo_frame_t struct, * the driver must supply the copy, field and dispose functions */ vo_frame_t* (*alloc_frame) (vo_driver_t *self); /* * check if the given image fullfills the format specified * (re-)allocate memory if necessary */ void (*update_frame_format) (vo_driver_t *self, vo_frame_t *img, uint32_t width, uint32_t height, double ratio, int format, int flags); /* display a given frame */ void (*display_frame) (vo_driver_t *self, vo_frame_t *vo_img); /* overlay_begin and overlay_end are used by drivers suporting * persistent overlays. they can be optimized to update only when * overlay image has changed. * * sequence of operation (pseudo-code): * overlay_begin(this,img,true_if_something_changed_since_last_blend ); * while(visible_overlays) * overlay_blend(this,img,overlay[i]); * overlay_end(this,img); * * any function pointer from this group may be set to NULL. */ void (*overlay_begin) (vo_driver_t *self, vo_frame_t *vo_img, int changed); void (*overlay_blend) (vo_driver_t *self, vo_frame_t *vo_img, vo_overlay_t *overlay); void (*overlay_end) (vo_driver_t *self, vo_frame_t *vo_img); /* * these can be used by the gui directly: */ int (*get_property) (vo_driver_t *self, int property); int (*set_property) (vo_driver_t *self, int property, int value); void (*get_property_min_max) (vo_driver_t *self, int property, int *min, int *max); /* * general purpose communication channel between gui and driver * * this should be used to propagate events, display data, window sizes * etc. to the driver */ int (*gui_data_exchange) (vo_driver_t *self, int data_type, void *data); /* check if a redraw is needed (due to resize) * this is only used for still frames, normal video playback * must call that inside display_frame() function. */ int (*redraw_needed) (vo_driver_t *self); /* Create a new grab video frame */ xine_grab_video_frame_t* (*new_grab_video_frame)(vo_driver_t *self); /* * free all resources, close driver */ void (*dispose) (vo_driver_t *self); /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; }; struct video_driver_class_s { /* * open a new instance of this plugin class */ vo_driver_t* (*open_plugin) (video_driver_class_t *self, const void *visual); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * free all class-related resources */ void (*dispose) (video_driver_class_t *self); }; #define default_video_driver_class_dispose (void (*) (video_driver_class_t *this_gen))free typedef struct rle_elem_s { uint16_t len; uint16_t color; } rle_elem_t; typedef struct argb_layer_s { pthread_mutex_t mutex; uint32_t *buffer; /* dirty area */ int x1, y1; int x2, y2; int ref_count; } argb_layer_t; struct vo_overlay_s { rle_elem_t *rle; /* rle code buffer */ int data_size; /* useful for deciding realloc */ int num_rle; /* number of active rle codes */ int x; /* x start of subpicture area */ int y; /* y start of subpicture area */ int width; /* width of subpicture area */ int height; /* height of subpicture area */ /* area within osd extent to scale video to */ int video_window_x; int video_window_y; int video_window_width; int video_window_height; /* extent of reference coordinate system */ int extent_width; int extent_height; uint32_t color[OVL_PALETTE_SIZE]; /* color lookup table */ uint8_t trans[OVL_PALETTE_SIZE]; /* mixer key table */ int rgb_clut; /* true if clut was converted to rgb */ /* define a highlight area with different colors */ int hili_top; int hili_bottom; int hili_left; int hili_right; uint32_t hili_color[OVL_PALETTE_SIZE]; uint8_t hili_trans[OVL_PALETTE_SIZE]; int hili_rgb_clut; /* true if clut was converted to rgb */ int unscaled; /* true if it should be blended unscaled */ argb_layer_t *argb_layer; }; void set_argb_layer_ptr(argb_layer_t **dst, argb_layer_t *src); /* API to video_overlay manager * * Remember that adding new functions to this structure requires * adaption of the post plugin decoration layer. Be sure to look into * src/xine-engine/post.[ch]. */ struct video_overlay_manager_s { void (*init) (video_overlay_manager_t *this_gen); void (*dispose) (video_overlay_manager_t *this_gen); int32_t (*get_handle) (video_overlay_manager_t *this_gen, int object_type ); void (*free_handle) (video_overlay_manager_t *this_gen, int32_t handle); int32_t (*add_event) (video_overlay_manager_t *this_gen, void *event); void (*flush_events) (video_overlay_manager_t *this_gen ); int (*redraw_needed) (video_overlay_manager_t *this_gen, int64_t vpts ); void (*multiple_overlay_blend) (video_overlay_manager_t *this_gen, int64_t vpts, vo_driver_t *output, vo_frame_t *vo_img, int enabled); }; /** * @brief Build a video output port from a given video driver. * * @internal */ xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly); #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/xmlparser.h0000644000175000017500000000707714647725152015453 0ustar meme/* * Copyright (C) 2002-2018 the xine project * * This file is part of xine, a free video player. * * The xine-lib XML parser is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The xine-lib XML parser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110, USA */ #ifndef XML_PARSER_H #define XML_PARSER_H #include /* parser modes */ #define XML_PARSER_CASE_INSENSITIVE 0 #define XML_PARSER_CASE_SENSITIVE 1 /* return codes */ #define XML_PARSER_OK 0 #define XML_PARSER_ERROR 1 /* xml_parser_build_tree_with_options flag bits */ #define XML_PARSER_RELAXED 1 #define XML_PARSER_MULTI_TEXT 2 /* node name for extra text chunks */ #define CDATA_MARKER "[CDATA]" /* xml property */ typedef struct xml_property_s { char *name; char *value; struct xml_property_s *next; } xml_property_t; /* xml node */ /* .data contains any text which precedes any subtree elements; * subtree elements may also contain only text; if so, name is "[CDATA]". * e.g. bd * node1: .name="a" .data="b" .child=node2 .next=NULL * node2: .name="c" .data=NULL .child=NULL .next=node3 * node3: .name="[CDATA]" .data="d" .child=NULL .next=NULL * Adjacent text items are merged. */ typedef struct xml_node_s { char *name; char *data; struct xml_property_s *props; struct xml_node_s *child; struct xml_node_s *next; } xml_node_t; /* xml parser */ typedef struct xml_parser_s { struct lexer *lexer; int mode; } xml_parser_t; void xml_parser_init(const char * buf, int size, int mode) XINE_DEPRECATED XINE_PROTECTED; xml_parser_t *xml_parser_init_r(const char * buf, int size, int mode) XINE_PROTECTED; void xml_parser_finalize_r(xml_parser_t *xml_parser) XINE_PROTECTED; int xml_parser_build_tree(xml_node_t **root_node) XINE_DEPRECATED XINE_PROTECTED; int xml_parser_build_tree_r(xml_parser_t *xml_parser, xml_node_t **root_node) XINE_PROTECTED; int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) XINE_DEPRECATED XINE_PROTECTED; int xml_parser_build_tree_with_options_r(xml_parser_t *xml_parser, xml_node_t **root_node, int flags) XINE_PROTECTED; void xml_parser_free_tree(xml_node_t *root_node) XINE_PROTECTED; const char *xml_parser_get_property (const xml_node_t *node, const char *name) XINE_PROTECTED; int xml_parser_get_property_int (const xml_node_t *node, const char *name, int def_value) XINE_PROTECTED; int xml_parser_get_property_bool (const xml_node_t *node, const char *name, int def_value) XINE_PROTECTED; /* for output: * returns an escaped string (free() it when done) * input must be in ASCII or UTF-8 */ typedef enum { XML_ESCAPE_NO_QUOTE, XML_ESCAPE_SINGLE_QUOTE, XML_ESCAPE_DOUBLE_QUOTE } xml_escape_quote_t; char *xml_escape_string (const char *s, xml_escape_quote_t quote_type) XINE_PROTECTED; /* for debugging purposes: dump read-in xml tree in a nicely * indented fashion */ void xml_parser_dump_tree (const xml_node_t *node) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/pool.h0000644000175000017500000000362614647725152014403 0ustar meme/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Object Pool */ #include #include #include typedef struct xine_pool_s xine_pool_t; /* Creates a new pool * object_size: sizeof(your struct) * create_object: function called to create an object (can be NULL) * prepare_object: function called to prepare an object to returned to the client (can be NULL) * return_object: function called to prepare an object to returned to the pool (can be NULL) * delete_object: function called to delete an object (can be NULL) */ xine_pool_t *xine_pool_new(size_t object_size, void (create_object)(void *object), void (prepare_object)(void *object), void (return_object)(void *object), void (delete_object)(void *object)) XINE_MALLOC XINE_PROTECTED; /* Deletes a pool */ void xine_pool_delete(xine_pool_t *pool) XINE_PROTECTED; /* Get an object from the pool */ void *xine_pool_get(xine_pool_t *pool) XINE_PROTECTED; /* Returns an object to the pool */ void xine_pool_put(xine_pool_t *pool, void *object) XINE_PROTECTED; xine-lib-1.2/include/xine/mfrag.h0000644000175000017500000000625614647725152014530 0ustar meme/* * Copyright (C) 2021 the xine project * Copyright (C) 2021 Torsten Jager * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Xine media fragment list utility. */ #ifndef HAVE_XINE_MFRAG_H #define HAVE_XINE_MFRAG_H #ifdef __cplusplus extern "C" { #endif #include #include #include /** -1: error. * 0: the stream head. * dur = timebase. * len = byte offset of first media fragment or 0. * 1..n: a media fragment. * dur = duration in timebase units or -1 (no change). * len = length in bytes or -1 (unknown/no change). * n + 1: append this one (set) or the stream total (get/find). */ typedef int32_t xine_mfrag_index_t; typedef struct xine_mfrag_list_s xine_mfrag_list_t; /** *plist may be NULL. */ void xine_mfrag_list_open (xine_mfrag_list_t **plist) XINE_PROTECTED; /** returns the "n" above. */ int32_t xine_mfrag_get_frag_count (xine_mfrag_list_t *list) XINE_PROTECTED; /** find the media fragment that contains the specified timepos or offs. */ xine_mfrag_index_t xine_mfrag_find_time (xine_mfrag_list_t *list, int64_t timepos) XINE_PROTECTED; xine_mfrag_index_t xine_mfrag_find_pos (xine_mfrag_list_t *list, off_t offs) XINE_PROTECTED; /** index 0: dur = timebase or -1 (no change). * len = head size in bytes or -1 (no change). * 1..n: dur = fragment duration in timebase units or 0 (unknown), -1 (no change). * len = fragment size or 0 (unknown), -1 (no change). * n + 1: dur = set: new fragment duration in timebase units or 0/-1 (unknown). * get: 0. * len = set: new fragment size or 0/-1 (unknown). * get: 0. */ int xine_mfrag_set_index_frag (xine_mfrag_list_t *list, xine_mfrag_index_t index, int64_t dur, off_t len) XINE_PROTECTED; int xine_mfrag_get_index_frag (xine_mfrag_list_t *list, xine_mfrag_index_t index, int64_t *dur, off_t *len) XINE_PROTECTED; /** index 0: timepos = 0. * offs = 0. * these values will be estimated if some previous fragment has an "unknown" setting: * 1..n: timepos = fragment start time in timebase units. * offs = fragment start offs in bytes. * n + 1: timepos = total time in timebase units. * offs = total size in bytes. */ int xine_mfrag_get_index_start (xine_mfrag_list_t *list, xine_mfrag_index_t index, int64_t *timepos, off_t *offs) XINE_PROTECTED; void xine_mfrag_list_close (xine_mfrag_list_t **plist) XINE_PROTECTED; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/stree.h0000644000175000017500000000560014647725152014546 0ustar meme/* * Copyright (C) 2021 the xine project * Copyright (C) 2021 Torsten Jager * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Xine string tree library. */ #ifndef HAVE_XINE_STREE_H #define HAVE_XINE_STREE_H #ifdef __cplusplus extern "C" { #endif #include #include #include typedef enum { XINE_STREE_AUTO = 0, XINE_STREE_XML, /** << eXtensible Markup Language */ XINE_STREE_JSON, /** << Java script Serial Object Notation */ XINE_STREE_URL, /** << Uniform Resource Location encoding */ XINE_STREE_LAST } xine_stree_mode_t; typedef struct { uint32_t next, prev; /** << xine_stree_t index */ uint32_t first_child, last_child, parent; /** << xine_stree_t index */ uint32_t num_children, level, index; /** << int */ uint32_t key, value; /** << offset into buf */ } xine_stree_t; /** buf will be reused (modified) to hold the strings referenced by xine_stree_t. * XINE_STREE_AUTO will update mode. */ xine_stree_t *xine_stree_load (char *buf, xine_stree_mode_t *mode) XINE_PROTECTED; /** base is an index into the tree, where to start. */ void xine_stree_dump (const xine_stree_t *tree, const char *buf, uint32_t base) XINE_PROTECTED; /** path is a dot separated list of parts. * part is a key, a zero based index number in square brackets, or both. * the special key "[]" refers to xml tag content text. * "foo.[][0]" will also be available as "foo". */ uint32_t xine_stree_find (const xine_stree_t *tree, const char *buf, const char *path, uint32_t base, int case_sens) XINE_PROTECTED; void xine_stree_delete (xine_stree_t **tree) XINE_PROTECTED; /** "&" -> "&" * "<" -> "<" * ">" -> ">" * """ -> "\"" * "핵" -> "핵" * return new strlen (). */ size_t xine_string_unampersand (char *s) XINE_PROTECTED; /** "%3a" -> ":" etc. return new strlen (). */ size_t xine_string_unpercent (char *s) XINE_PROTECTED; /** "\n" -> * "\070" -> "8" * "\x37" -> "7" * "\ud575" -> "핵" * "\cG" -> (^G) * return new strlen (). */ size_t xine_string_unbackslash (char *s) XINE_PROTECTED; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/xine_internal.h0000644000175000017500000003323314647725152016266 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_XINE_INTERNAL_H #define HAVE_XINE_INTERNAL_H #ifdef __cplusplus extern "C" { #endif /* * include public part of xine header */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define XINE_MAX_EVENT_LISTENERS 50 #define XINE_MAX_EVENT_TYPES 100 #define XINE_MAX_TICKET_HOLDER_THREADS 64 /* used by plugin loader */ #define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION /* * log constants */ #define XINE_LOG_MSG 0 /* warnings, errors, ... */ #define XINE_LOG_PLUGIN 1 #define XINE_LOG_TRACE 2 #define XINE_LOG_NUM 3 /* # of log buffers defined */ #define XINE_STREAM_INFO_MAX 99 /* * the "big" xine struct, holding everything together */ #ifndef XDG_BASEDIR_H /* present here for internal convenience only */ typedef struct { void *reserved; } xdgHandle; #endif struct xine_s { config_values_t *config; plugin_catalog_t *plugin_catalog; int verbosity; int demux_strategy; const char *save_path; /* log output that may be presented to the user */ scratch_buffer_t *log_buffers[XINE_LOG_NUM]; xine_list_t *streams; pthread_mutex_t streams_lock; metronom_clock_t *clock; /** Handle for libxdg-basedir functions. */ xdgHandle basedir_handle; }; /* * xine event queue */ struct xine_event_queue_s { xine_list_t *events; pthread_mutex_t lock; pthread_cond_t new_event; pthread_cond_t events_processed; xine_stream_t *stream; pthread_t *listener_thread; void *user_data; xine_event_listener_cb_t callback; int callback_running; }; /* * xine_stream - per-stream parts of the xine engine */ struct xine_stream_s { /* reference to xine context */ xine_t *xine; /* metronom instance used by current stream */ metronom_t *metronom; /* demuxers use input_plugin to read data */ input_plugin_t *input_plugin; /* used by video decoders, may change by port rewire */ xine_video_port_t * volatile video_out; /* demuxers send data to video decoders using this fifo */ fifo_buffer_t *video_fifo; /* used by audio decoders, may change by port rewire */ xine_audio_port_t * volatile audio_out; /* demuxers send data to audio decoders using this fifo */ fifo_buffer_t *audio_fifo; /* provide access to osd api */ osd_renderer_t *osd_renderer; /* master/slave streams */ xine_stream_t *master; /* usually a pointer to itself */ xine_stream_t *slave; /* input_dvd uses this one. is it possible to add helper functions instead? */ spu_decoder_t *spu_decoder_plugin; /* dxr3 use this one, should be possible to fix to use the port instead */ vo_driver_t *video_driver; /* these definitely should be made private! */ int audio_channel_auto; int spu_decoder_streamtype; int spu_channel_user; int spu_channel_auto; int spu_channel_letterbox; int spu_channel; /* current content detection method, see METHOD_BY_xxx */ int content_detection_method; }; /* when explicitly noted, some functions accept an anonymous stream, * which is a valid stream that does not want to be addressed. */ #define XINE_ANON_STREAM ((xine_stream_t *)-1) typedef struct { int total; int ready; int avail; } xine_query_buffers_data_t; typedef struct { xine_query_buffers_data_t vi; xine_query_buffers_data_t ai; xine_query_buffers_data_t vo; xine_query_buffers_data_t ao; } xine_query_buffers_t; /* * private function prototypes: */ int _x_query_network_timeout (xine_t *xine) XINE_PROTECTED; int _x_query_buffers(xine_stream_t *stream, xine_query_buffers_t *query) XINE_PROTECTED; int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *num_audio_buffers, int *num_video_frames, int *num_audio_frames) XINE_PROTECTED; int _x_lock_port_rewiring(xine_t *xine, int ms_to_time_out) XINE_PROTECTED; void _x_unlock_port_rewiring(xine_t *xine) XINE_PROTECTED; int _x_lock_frontend(xine_stream_t *stream, int ms_to_time_out) XINE_PROTECTED; void _x_unlock_frontend(xine_stream_t *stream) XINE_PROTECTED; int _x_query_unprocessed_osd_events(xine_stream_t *stream) XINE_PROTECTED; int _x_demux_seek(xine_stream_t *stream, off_t start_pos, int start_time, int playing) XINE_PROTECTED; int _x_continue_stream_processing(xine_stream_t *stream) XINE_PROTECTED; void _x_trigger_relaxed_frame_drop_mode(xine_stream_t *stream) XINE_PROTECTED; void _x_reset_relaxed_frame_drop_mode(xine_stream_t *stream) XINE_PROTECTED; void _x_handle_stream_end (xine_stream_t *stream, int non_user) XINE_PROTECTED; /* report message to UI. usually these are async errors */ int _x_message(xine_stream_t *stream, int type, ...) XINE_SENTINEL XINE_PROTECTED; /* flush the message queues */ void _x_flush_events_queues (xine_stream_t *stream) XINE_PROTECTED; /* extra_info operations */ void _x_extra_info_reset( extra_info_t *extra_info ) XINE_PROTECTED; void _x_extra_info_merge (extra_info_t *dst, const extra_info_t *src) XINE_PROTECTED; void _x_get_current_info (xine_stream_t *stream, extra_info_t *extra_info, int size) XINE_PROTECTED; /** @brief Register a list of stream keyframes. @param stream The stream that index is for. @param list The array of entries to add. @param size The count of entries. @return 0 (OK), 1 (Fail). */ int _x_keyframes_set (xine_stream_t *stream, xine_keyframes_entry_t *list, int size) XINE_PROTECTED; /** @brief Register a stream keyframe to seek index. @note This will try not to duplicate already registered frames. @param stream The stream that index is for. @param pos The frame time AND normpos. @return The index *g* into the index where that frame has been added, or -1. */ int _x_keyframes_add (xine_stream_t *stream, xine_keyframes_entry_t *pos) XINE_PROTECTED; /* demuxer helper functions from demux.c */ /* * Flush audio and video buffers. It is called from demuxers on * seek/stop, and may be useful when user input changes a stream and * xine-lib has cached buffers that have yet to be played. * * warning: after clearing decoders fifos an absolute discontinuity * indication must be sent. relative discontinuities are likely * to cause "jumps" on metronom. */ void _x_demux_flush_engine (xine_stream_t *stream) XINE_PROTECTED; void _x_demux_control_nop (xine_stream_t *stream, uint32_t flags) XINE_PROTECTED; void _x_demux_control_newpts (xine_stream_t *stream, int64_t pts, uint32_t flags) XINE_PROTECTED; void _x_demux_control_headers_done (xine_stream_t *stream) XINE_PROTECTED; void _x_demux_control_start (xine_stream_t *stream) XINE_PROTECTED; void _x_demux_control_end (xine_stream_t *stream, uint32_t flags) XINE_PROTECTED; int _x_demux_start_thread (xine_stream_t *stream) XINE_PROTECTED; int _x_demux_called_from (xine_stream_t *stream) XINE_PROTECTED; int _x_demux_stop_thread (xine_stream_t *stream) XINE_PROTECTED; int _x_demux_read_header (input_plugin_t *input, void *buffer, off_t size) XINE_PROTECTED; int _x_demux_read_stream_header (xine_stream_t *stream, input_plugin_t *input, void *buffer, size_t size) XINE_PROTECTED; int _x_demux_check_extension (const char *mrl, const char *extensions); off_t _x_read_abort (xine_stream_t *stream, int fd, char *buf, off_t todo) XINE_PROTECTED; int _x_action_pending (xine_stream_t *stream) XINE_PROTECTED; void _x_action_raise (xine_stream_t *stream) XINE_PROTECTED; void _x_action_lower (xine_stream_t *stream) XINE_PROTECTED; void _x_demux_send_data(fifo_buffer_t *fifo, uint8_t *data, int size, int64_t pts, uint32_t type, uint32_t decoder_flags, int input_normpos, int input_time, int total_time, uint32_t frame_number) XINE_PROTECTED; int _x_demux_read_send_data(fifo_buffer_t *fifo, input_plugin_t *input, int size, int64_t pts, uint32_t type, uint32_t decoder_flags, off_t input_normpos, int input_time, int total_time, uint32_t frame_number) XINE_USED XINE_PROTECTED; void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative, const char *mrl, const char *title, int start_time, int duration) XINE_PROTECTED; /* * MRL escaped-character decoding (overwrites the source string) */ void _x_mrl_unescape(char *mrl) XINE_PROTECTED; /* * Return a copy of mrl without authentication credentials */ char *_x_mrl_remove_auth(const char *mrl) XINE_PROTECTED; /* * plugin_loader functions * */ /* allow input plugins to use other input plugins */ input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) XINE_PROTECTED; void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED; /* on-demand loading of generic modules / sub-plugins */ struct xine_module_s; /* xine_module.h */ struct xine_module_s *_x_find_module(xine_t *xine, const char *type, const char *id, unsigned sub_type, const void *params) XINE_PROTECTED; void _x_free_module(xine_t *xine, struct xine_module_s **pmodule) XINE_PROTECTED; /* on-demand loading of audio/video/spu decoder plugins */ video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; void _x_free_video_decoder (xine_stream_t *stream, video_decoder_t *decoder) XINE_PROTECTED; audio_decoder_t *_x_get_audio_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; void _x_free_audio_decoder (xine_stream_t *stream, audio_decoder_t *decoder) XINE_PROTECTED; spu_decoder_t *_x_get_spu_decoder (xine_stream_t *stream, uint8_t stream_type) XINE_PROTECTED; void _x_free_spu_decoder (xine_stream_t *stream, spu_decoder_t *decoder) XINE_PROTECTED; /* check for decoder availability - but don't try to initialize it */ int _x_decoder_available (xine_t *xine, uint32_t buftype) XINE_PROTECTED; /* on-demand loading of demux plugins */ demux_plugin_t *_x_find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED; demux_plugin_t *_x_find_demux_plugin_by_name (xine_stream_t *stream, const char *name, input_plugin_t *input) XINE_PROTECTED; void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t **demux) XINE_PROTECTED; /* * load_video_output_plugin * * load a specific video output plugin */ vo_driver_t *_x_load_video_output_plugin(xine_t *this_gen, const char *id, int visual_type, const void *visual) XINE_PROTECTED; /* * audio output plugin dynamic loading stuff */ /* * load_audio_output_plugin * * load a specific audio output plugin */ ao_driver_t *_x_load_audio_output_plugin (xine_t *self, const char *id) XINE_PROTECTED; void _x_set_speed (xine_stream_t *stream, int speed) XINE_PROTECTED; int _x_get_speed (xine_stream_t *stream) XINE_PROTECTED; /* set when pauseing with port ticket granted, for XINE_PARAM_VO_SINGLE_STEP. */ /* special values for fine speed. */ # define XINE_LIVE_PAUSE_ON 0x7ffffffd # define XINE_LIVE_PAUSE_OFF 0x7ffffffc void _x_set_fine_speed (xine_stream_t *stream, int speed) XINE_PROTECTED; int _x_get_fine_speed (xine_stream_t *stream) XINE_PROTECTED; void _x_select_spu_channel (xine_stream_t *stream, int channel) XINE_PROTECTED; int _x_get_audio_channel (xine_stream_t *stream) XINE_PROTECTED; int _x_get_spu_channel (xine_stream_t *stream) XINE_PROTECTED; int _x_get_video_streamtype (xine_stream_t *) XINE_PROTECTED; /* * internal events */ /* sent by dvb frontend to inform ts demuxer of new pids */ #define XINE_EVENT_PIDS_CHANGE 0x80000000 /* sent by BluRay input plugin to inform ts demuxer about end of clip */ #define XINE_EVENT_END_OF_CLIP 0x80000001 /* * pids change event - inform ts demuxer of new pids */ typedef struct { int vpid; /* video program id */ int apid; /* audio program id */ } xine_pids_data_t; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/version.h.in0000644000175000017500000000177514647725152015527 0ustar meme/* * Copyright (C) 2007 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* static info - which libxine release this header came from */ #define XINE_MAJOR_VERSION @XINE_MAJOR@ #define XINE_MINOR_VERSION @XINE_MINOR@ #define XINE_SUB_VERSION @XINE_SUB@ #define XINE_VERSION "@VERSION@" xine-lib-1.2/include/xine/list.h0000644000175000017500000001054014647725152014376 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Doubly-linked linked list. * * Exemples: * * Create a list: * xine_list_t *list = xine_list_new(); * * Delete a list: * xine_list_delete(list); * * Walk thru a list: * xine_list_iterator_t ite = xine_list_front(list); * while (ite) { * _useful code here_ * ite = xine_list_next(list, ite); * } * * The list elements are managed using memory chunks and a free list. The first * chunk contains 32 elements, each following chunk is two time as big as the * previous one, with a limit of 64K elements. */ #ifndef XINE_LIST_H #define XINE_LIST_H #include /* Doubly-linked list type */ typedef struct xine_list_s xine_list_t; /* List iterator */ typedef struct xine_list_elem_s *xine_list_iterator_t; /* Constructor */ xine_list_t *xine_list_new(void) XINE_MALLOC XINE_PROTECTED; /* Destructor */ void xine_list_delete(xine_list_t *list) XINE_PROTECTED; /* Returns the number of element stored in the list */ unsigned int xine_list_size(xine_list_t *list) XINE_PROTECTED; /* Returns true if the number of elements is zero, false otherwise */ unsigned int xine_list_empty(xine_list_t *list) XINE_PROTECTED; /* Adds the element at the beginning of the list */ void xine_list_push_front(xine_list_t *list, void *value) XINE_PROTECTED; /* Adds the element at the end of the list */ void xine_list_push_back(xine_list_t *list, void *value) XINE_PROTECTED; /* Remove all elements from a list */ void xine_list_clear(xine_list_t *list) XINE_PROTECTED; /* Insert the element elem into the list at the position specified by the iterator (before the element, if any, that was previously at the iterator's position). The return value is an iterator that specifies the position of the inserted element. */ xine_list_iterator_t xine_list_insert(xine_list_t *list, xine_list_iterator_t position, void *value) XINE_PROTECTED; /* Remove one element from a list.*/ void xine_list_remove(xine_list_t *list, xine_list_iterator_t position) XINE_PROTECTED; /* Returns an iterator that references the first element of the list */ xine_list_iterator_t xine_list_front(xine_list_t *list) XINE_PROTECTED; /* Returns an iterator that references the last element of the list */ xine_list_iterator_t xine_list_back(xine_list_t *list) XINE_PROTECTED; /* Perform a linear search of a given value, and returns an iterator that references this value or NULL if not found */ xine_list_iterator_t xine_list_find(xine_list_t *list, void *value) XINE_PROTECTED; /* If iterator == NULL: same as xine_list_front (). Otherwise, increments the iterator's value, so it specifies the next element in the list, or NULL at the end of the list. */ xine_list_iterator_t xine_list_next(xine_list_t *list, xine_list_iterator_t ite) XINE_PROTECTED; /* Like xine_list_next () but returns the user value or NULL. */ void *xine_list_next_value (xine_list_t *list, xine_list_iterator_t *ite) XINE_PROTECTED; /* If iterator == NULL: same as xine_list_back (). Otherwise, decrements the iterator's value, so it specifies the previous element in the list, or NULL at the beginning of the list */ xine_list_iterator_t xine_list_prev(xine_list_t *list, xine_list_iterator_t ite) XINE_PROTECTED; /* Like xine_list_prev () but returns the user value or NULL. */ void *xine_list_prev_value (xine_list_t *list, xine_list_iterator_t *ite) XINE_PROTECTED; /* Returns the value at the position specified by the iterator */ void *xine_list_get_value(xine_list_t *list, xine_list_iterator_t ite) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/video_decoder.h0000644000175000017500000000563614647725152016230 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine video decoder plugin interface */ #ifndef HAVE_VIDEO_DECODER_H #define HAVE_VIDEO_DECODER_H #include #include struct plugin_node_s; #define VIDEO_DECODER_IFACE_VERSION 19 /* * generic xine video decoder plugin interface */ typedef struct video_decoder_class_s video_decoder_class_t; typedef struct video_decoder_s video_decoder_t; struct video_decoder_class_s { /* * open a new instance of this plugin class */ video_decoder_t* (*open_plugin) (video_decoder_class_t *this_gen, xine_stream_t *stream); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * free all class-related resources */ void (*dispose) (video_decoder_class_t *this_gen); }; #define default_video_decoder_class_dispose (void (*) (video_decoder_class_t *this_gen))free struct video_decoder_s { /* * decode data from buf and feed decoded frames to * video output */ void (*decode_data) (video_decoder_t *this_gen, buf_element_t *buf); /* * reset decoder after engine flush (prepare for new * video data not related to recently decoded data) */ void (*reset) (video_decoder_t *this_gen); /* * inform decoder that a time reference discontinuity has happened. * that is, it must forget any currently held pts value */ void (*discontinuity) (video_decoder_t *this_gen); /* * flush out any frames that are still stored in the decoder */ void (*flush) (video_decoder_t *this_gen); /* * close down, free all resources */ void (*dispose) (video_decoder_t *this_gen); /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; }; #endif xine-lib-1.2/include/xine/buffer.h0000644000175000017500000006776514647725152014721 0ustar meme/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * contents: * * buffer_entry structure - serves as a transport encapsulation * of the mpeg audio/video data through xine * * free buffer pool management routines * * FIFO buffer structures/routines */ #ifndef HAVE_BUFFER_H #define HAVE_BUFFER_H #ifdef __cplusplus extern "C" { #endif #include /* memcmp */ #include /* pthread_* */ #include /* clang systems seem to need this */ #include #include #include #define BUF_MAX_CALLBACKS 5 /** * @defgroup buffer_types Buffer Types * * a buffer type ID describes the contents of a buffer * it consists of three fields: * * buf_type = 0xMMDDCCCC * * MM : major buffer type (CONTROL, VIDEO, AUDIO, SPU) * DD : decoder selection (e.g. MPEG, OPENDIVX ... for VIDEO) * CCCC : channel number or other subtype information for the decoder */ /*@{*/ #define BUF_MAJOR_MASK 0xFF000000 #define BUF_DECODER_MASK 0x00FF0000 /** * @defgroup buffer_ctrl Control buffer types */ /*@{*/ #define BUF_CONTROL_BASE 0x01000000 #define BUF_CONTROL_START 0x01000000 #define BUF_CONTROL_END 0x01010000 #define BUF_CONTROL_QUIT 0x01020000 #define BUF_CONTROL_DISCONTINUITY 0x01030000 /**< former AVSYNC_RESET */ #define BUF_CONTROL_NOP 0x01040000 #define BUF_CONTROL_AUDIO_CHANNEL 0x01050000 #define BUF_CONTROL_SPU_CHANNEL 0x01060000 #define BUF_CONTROL_NEWPTS 0x01070000 #define BUF_CONTROL_RESET_DECODER 0x01080000 #define BUF_CONTROL_HEADERS_DONE 0x01090000 #define BUF_CONTROL_FLUSH_DECODER 0x010a0000 #define BUF_CONTROL_RESET_TRACK_MAP 0x010b0000 /*@}*/ /** * @defgroup buffer_video Video buffer types * @note (please keep in sync with buffer_types.c) */ /*@{*/ #define BUF_VIDEO_BASE 0x02000000 #define BUF_VIDEO_UNKNOWN 0x02ff0000 /**< no decoder should handle this one */ #define BUF_VIDEO_MPEG 0x02000000 #define BUF_VIDEO_MPEG4 0x02010000 #define BUF_VIDEO_CINEPAK 0x02020000 #define BUF_VIDEO_SORENSON_V1 0x02030000 #define BUF_VIDEO_MSMPEG4_V2 0x02040000 #define BUF_VIDEO_MSMPEG4_V3 0x02050000 #define BUF_VIDEO_MJPEG 0x02060000 #define BUF_VIDEO_IV50 0x02070000 #define BUF_VIDEO_IV41 0x02080000 #define BUF_VIDEO_IV32 0x02090000 #define BUF_VIDEO_IV31 0x020a0000 #define BUF_VIDEO_ATIVCR1 0x020b0000 #define BUF_VIDEO_ATIVCR2 0x020c0000 #define BUF_VIDEO_I263 0x020d0000 #define BUF_VIDEO_RV10 0x020e0000 #define BUF_VIDEO_RGB 0x02100000 #define BUF_VIDEO_YUY2 0x02110000 #define BUF_VIDEO_JPEG 0x02120000 #define BUF_VIDEO_WMV7 0x02130000 #define BUF_VIDEO_WMV8 0x02140000 #define BUF_VIDEO_MSVC 0x02150000 #define BUF_VIDEO_DV 0x02160000 #define BUF_VIDEO_REAL 0x02170000 #define BUF_VIDEO_VP31 0x02180000 #define BUF_VIDEO_H263 0x02190000 #define BUF_VIDEO_3IVX 0x021A0000 #define BUF_VIDEO_CYUV 0x021B0000 #define BUF_VIDEO_DIVX5 0x021C0000 #define BUF_VIDEO_XVID 0x021D0000 #define BUF_VIDEO_SMC 0x021E0000 #define BUF_VIDEO_RPZA 0x021F0000 #define BUF_VIDEO_QTRLE 0x02200000 #define BUF_VIDEO_MSRLE 0x02210000 #define BUF_VIDEO_DUCKTM1 0x02220000 #define BUF_VIDEO_FLI 0x02230000 #define BUF_VIDEO_ROQ 0x02240000 #define BUF_VIDEO_SORENSON_V3 0x02250000 #define BUF_VIDEO_MSMPEG4_V1 0x02260000 #define BUF_VIDEO_MSS1 0x02270000 #define BUF_VIDEO_IDCIN 0x02280000 #define BUF_VIDEO_PGVV 0x02290000 #define BUF_VIDEO_ZYGO 0x022A0000 #define BUF_VIDEO_TSCC 0x022B0000 #define BUF_VIDEO_YVU9 0x022C0000 #define BUF_VIDEO_VQA 0x022D0000 #define BUF_VIDEO_GREY 0x022E0000 #define BUF_VIDEO_XXAN 0x022F0000 #define BUF_VIDEO_WC3 0x02300000 #define BUF_VIDEO_YV12 0x02310000 #define BUF_VIDEO_SEGA 0x02320000 #define BUF_VIDEO_RV20 0x02330000 #define BUF_VIDEO_RV30 0x02340000 #define BUF_VIDEO_MVI2 0x02350000 #define BUF_VIDEO_UCOD 0x02360000 #define BUF_VIDEO_WMV9 0x02370000 #define BUF_VIDEO_INTERPLAY 0x02380000 #define BUF_VIDEO_RV40 0x02390000 #define BUF_VIDEO_PSX_MDEC 0x023A0000 #define BUF_VIDEO_YUV_FRAMES 0x023B0000 /**< uncompressed YUV, delivered by v4l input plugin */ #define BUF_VIDEO_HUFFYUV 0x023C0000 #define BUF_VIDEO_IMAGE 0x023D0000 #define BUF_VIDEO_THEORA 0x023E0000 #define BUF_VIDEO_4XM 0x023F0000 #define BUF_VIDEO_I420 0x02400000 #define BUF_VIDEO_VP4 0x02410000 #define BUF_VIDEO_VP5 0x02420000 #define BUF_VIDEO_VP6 0x02430000 #define BUF_VIDEO_VMD 0x02440000 #define BUF_VIDEO_MSZH 0x02450000 #define BUF_VIDEO_ZLIB 0x02460000 #define BUF_VIDEO_8BPS 0x02470000 #define BUF_VIDEO_ASV1 0x02480000 #define BUF_VIDEO_ASV2 0x02490000 #define BUF_VIDEO_BITPLANE 0x024A0000 /**< Amiga typical picture and animation format */ #define BUF_VIDEO_BITPLANE_BR1 0x024B0000 /**< the same with Bytrun compression 1 */ #define BUF_VIDEO_FLV1 0x024C0000 #define BUF_VIDEO_H264 0x024D0000 #define BUF_VIDEO_MJPEG_B 0x024E0000 #define BUF_VIDEO_H261 0x024F0000 #define BUF_VIDEO_AASC 0x02500000 #define BUF_VIDEO_LOCO 0x02510000 #define BUF_VIDEO_QDRW 0x02520000 #define BUF_VIDEO_QPEG 0x02530000 #define BUF_VIDEO_ULTI 0x02540000 #define BUF_VIDEO_WNV1 0x02550000 #define BUF_VIDEO_XL 0x02560000 #define BUF_VIDEO_RT21 0x02570000 #define BUF_VIDEO_FPS1 0x02580000 #define BUF_VIDEO_DUCKTM2 0x02590000 #define BUF_VIDEO_CSCD 0x025A0000 #define BUF_VIDEO_ALGMM 0x025B0000 #define BUF_VIDEO_ZMBV 0x025C0000 #define BUF_VIDEO_AVS 0x025D0000 #define BUF_VIDEO_SMACKER 0x025E0000 #define BUF_VIDEO_NUV 0x025F0000 #define BUF_VIDEO_KMVC 0x02600000 #define BUF_VIDEO_FLASHSV 0x02610000 #define BUF_VIDEO_CAVS 0x02620000 #define BUF_VIDEO_VP6F 0x02630000 #define BUF_VIDEO_THEORA_RAW 0x02640000 #define BUF_VIDEO_VC1 0x02650000 #define BUF_VIDEO_VMNC 0x02660000 #define BUF_VIDEO_SNOW 0x02670000 #define BUF_VIDEO_VP8 0x02680000 #define BUF_VIDEO_VP9 0x02690000 #define BUF_VIDEO_HEVC 0x026A0000 #define BUF_VIDEO_AV1 0x026B0000 #define BUF_VIDEO_PNG 0x026C0000 /*@}*/ /** * @defgroup buffer_audio Audio buffer types * @note (please keep in sync with buffer_types.c) */ /*@{*/ #define BUF_AUDIO_BASE 0x03000000 #define BUF_AUDIO_UNKNOWN 0x03ff0000 /**< no decoder should handle this one */ #define BUF_AUDIO_A52 0x03000000 #define BUF_AUDIO_MPEG 0x03010000 #define BUF_AUDIO_LPCM_BE 0x03020000 #define BUF_AUDIO_LPCM_LE 0x03030000 #define BUF_AUDIO_WMAV1 0x03040000 #define BUF_AUDIO_DTS 0x03050000 #define BUF_AUDIO_MSADPCM 0x03060000 #define BUF_AUDIO_MSIMAADPCM 0x03070000 #define BUF_AUDIO_MSGSM 0x03080000 #define BUF_AUDIO_VORBIS 0x03090000 #define BUF_AUDIO_IMC 0x030a0000 #define BUF_AUDIO_LH 0x030b0000 #define BUF_AUDIO_VOXWARE 0x030c0000 #define BUF_AUDIO_ACELPNET 0x030d0000 #define BUF_AUDIO_AAC 0x030e0000 #define BUF_AUDIO_DNET 0x030f0000 #define BUF_AUDIO_VIVOG723 0x03100000 #define BUF_AUDIO_DK3ADPCM 0x03110000 #define BUF_AUDIO_DK4ADPCM 0x03120000 #define BUF_AUDIO_ROQ 0x03130000 #define BUF_AUDIO_QTIMAADPCM 0x03140000 #define BUF_AUDIO_MAC3 0x03150000 #define BUF_AUDIO_MAC6 0x03160000 #define BUF_AUDIO_QDESIGN1 0x03170000 #define BUF_AUDIO_QDESIGN2 0x03180000 #define BUF_AUDIO_QCLP 0x03190000 #define BUF_AUDIO_SMJPEG_IMA 0x031A0000 #define BUF_AUDIO_VQA_IMA 0x031B0000 #define BUF_AUDIO_MULAW 0x031C0000 #define BUF_AUDIO_ALAW 0x031D0000 #define BUF_AUDIO_GSM610 0x031E0000 #define BUF_AUDIO_EA_ADPCM 0x031F0000 #define BUF_AUDIO_WMAV2 0x03200000 #define BUF_AUDIO_COOK 0x03210000 #define BUF_AUDIO_ATRK 0x03220000 #define BUF_AUDIO_14_4 0x03230000 #define BUF_AUDIO_28_8 0x03240000 #define BUF_AUDIO_SIPRO 0x03250000 #define BUF_AUDIO_WMAPRO 0x03260000 #define BUF_AUDIO_WMAV3 BUF_AUDIO_WMAPRO #define BUF_AUDIO_INTERPLAY 0x03270000 #define BUF_AUDIO_XA_ADPCM 0x03280000 #define BUF_AUDIO_WESTWOOD 0x03290000 #define BUF_AUDIO_DIALOGIC_IMA 0x032A0000 #define BUF_AUDIO_NSF 0x032B0000 #define BUF_AUDIO_FLAC 0x032C0000 #define BUF_AUDIO_DV 0x032D0000 #define BUF_AUDIO_WMAV 0x032E0000 #define BUF_AUDIO_SPEEX 0x032F0000 #define BUF_AUDIO_RAWPCM 0x03300000 #define BUF_AUDIO_4X_ADPCM 0x03310000 #define BUF_AUDIO_VMD 0x03320000 #define BUF_AUDIO_XAN_DPCM 0x03330000 #define BUF_AUDIO_ALAC 0x03340000 #define BUF_AUDIO_MPC 0x03350000 #define BUF_AUDIO_SHORTEN 0x03360000 #define BUF_AUDIO_WESTWOOD_SND1 0x03370000 #define BUF_AUDIO_WMALL 0x03380000 #define BUF_AUDIO_TRUESPEECH 0x03390000 #define BUF_AUDIO_TTA 0x033A0000 #define BUF_AUDIO_SMACKER 0x033B0000 #define BUF_AUDIO_FLVADPCM 0x033C0000 #define BUF_AUDIO_WAVPACK 0x033D0000 #define BUF_AUDIO_MP3ADU 0x033E0000 #define BUF_AUDIO_AMR_NB 0x033F0000 #define BUF_AUDIO_AMR_WB 0x03400000 #define BUF_AUDIO_EAC3 0x03410000 #define BUF_AUDIO_AAC_LATM 0x03420000 #define BUF_AUDIO_ADPCM_G726 0x03430000 #define BUF_AUDIO_OPUS 0x03440000 #define BUF_AUDIO_TRUEHD 0x03450000 /*@}*/ /** * @defgroup buffer_spu SPU buffer types */ /*@{*/ #define BUF_SPU_BASE 0x04000000 #define BUF_SPU_DVD 0x04000000 #define BUF_SPU_TEXT 0x04010000 #define BUF_SPU_CC 0x04020000 #define BUF_SPU_DVB 0x04030000 #define BUF_SPU_SVCD 0x04040000 #define BUF_SPU_CVD 0x04050000 #define BUF_SPU_OGM 0x04060000 #define BUF_SPU_CMML 0x04070000 #define BUF_SPU_HDMV 0x04080000 #define BUF_SPU_HDMV_TEXT 0x04090000 /*@}*/ /** * @defgroup buffer_demux Demuxer block types */ /*@{*/ #define BUF_DEMUX_BLOCK 0x05000000 /*@}*/ /*@}*/ typedef struct extra_info_s extra_info_t; /** * @brief Structure to pass information from input or demuxer plugins * to output frames (past decoder). * * New data must be added after the existing fields to not break ABI * (backward compatibility). */ struct extra_info_s { int input_normpos; /**< remember where this buf came from in * the input source (0..65535). can be * either time or offset based. */ int input_time; /**< time offset in miliseconds from * beginning of stream */ uint32_t frame_number; /**< number of current frame if known */ int seek_count; /**< internal engine use */ int64_t vpts; /**< set on output layers only */ int invalid; /**< do not use this extra info to update anything */ int total_time; /**< duration in miliseconds of the stream */ }; #define BUF_NUM_DEC_INFO 5 typedef struct buf_element_s buf_element_t; struct buf_element_s { buf_element_t *next; unsigned char *mem; unsigned char *content; /**< start of raw content in mem (without header etc) */ int32_t size ; /**< size of _content_ */ int32_t max_size; /**< size of pre-allocated memory pointed to by "mem" */ int64_t pts; /**< presentation time stamp, used for a/v sync */ int64_t disc_off; /**< discontinuity offset */ extra_info_t *extra_info; /**< extra info will be passed to frames */ uint32_t decoder_flags; /**< stuff like keyframe, is_header ... see below */ /** additional decoder flags and other dec-spec. stuff */ uint32_t decoder_info[BUF_NUM_DEC_INFO]; /** pointers to dec-spec. stuff */ void *decoder_info_ptr[BUF_NUM_DEC_INFO]; void (*free_buffer) (buf_element_t *buf); void *source; /**< pointer to source of this buffer for * free_buffer */ uint32_t type; } ; /** keyframe should be set whenever possible (that is, when demuxer * knows about frames and keyframes). */ #define BUF_FLAG_KEYFRAME 0x0001 /** frame start/end. BUF_FLAG_FRAME_END is sent on last buf of a frame */ #define BUF_FLAG_FRAME_START 0x0002 #define BUF_FLAG_FRAME_END 0x0004 /** any out-of-band data needed to initialize decoder must have * this flag set. */ #define BUF_FLAG_HEADER 0x0008 /** preview buffers are normal data buffers that must not produce any * output in decoders (may be used to sneak details about the stream * to come). */ #define BUF_FLAG_PREVIEW 0x0010 /** set when user stop the playback */ #define BUF_FLAG_END_USER 0x0020 /** set when stream finished naturaly */ #define BUF_FLAG_END_STREAM 0x0040 /** decoder_info[0] carries the frame step (1/90000). */ #define BUF_FLAG_FRAMERATE 0x0080 /** hint to metronom that seeking has occurred */ #define BUF_FLAG_SEEK 0x0100 /** special information inside, see below. */ #define BUF_FLAG_SPECIAL 0x0200 /** header use standard xine_bmiheader or xine_waveformatex structs. * xine_waveformatex is actually optional since the most important * information for audio init is available from decoder_info[]. * note: BUF_FLAG_HEADER must also be set. */ #define BUF_FLAG_STDHEADER 0x0400 /** decoder_info[1] carries numerator for display aspect ratio * decoder_info[2] carries denominator for display aspect ratio */ #define BUF_FLAG_ASPECT 0x0800 /* represent the state of gapless_switch at the time buf was enqueued */ #define BUF_FLAG_GAPLESS_SW 0x1000 /* Amount of audio padding added by encoder (mp3, aac). These empty * audio frames are causing a gap when switching between mp3 files. * decoder_info[1] carries amount of audio frames padded at the * beginning of the buffer * decoder_info[2] carries amount of audio frames padded at the end of * the buffer */ #define BUF_FLAG_AUDIO_PADDING 0x2000 /** decoder_info[4] has (mpeg_color_matrix << 1) | fullrange. * Useful for raw YUV which cannot tell this otherwise. * Valid until revoked or next stream. */ #define BUF_FLAG_COLOR_MATRIX 0x4000 /** Optimization: try to merge this buf with previous one still in fifo. * This is for demuxers that dont know a frame's size before sending it * (mpeg-ts). Decoders will never see this. */ #define BUF_FLAG_MERGE 0x8000 /** * \defgroup buffer_special Special buffer types: * Sometimes there is a need to relay special information from a demuxer * to a video decoder. For example, some file types store palette data in * the file header independant of the video data. The special buffer type * offers a way to communicate this or any other custom, format-specific * data to the decoder. * * The interface was designed in a way that did not require an API * version bump. To send a special buffer type, set a buffer's flags field * to BUF_FLAG_SPECIAL. Set the buffer's decoder_info[1] field to a * number according to one of the special buffer subtypes defined below. * The second and third decoder_info[] fields are defined according to * your buffer type's requirements. * * Finally, remember to set the buffer's size to 0. This way, if a special * buffer is sent to a decode that does not know how to handle it, the * buffer will fall through to the case where the buffer's data content * is accumulated and no harm will be done. */ /*@{*/ /** * In a BUF_SPECIAL_PALETTE buffer: * decoder_info[1] = BUF_SPECIAL_PALETTE * decoder_info[2] = number of entries in palette table * decoder_info_ptr[2] = pointer to palette table * This buffer type is used to provide a file- and decoder-independent * facility to transport RGB color palettes from demuxers to decoders. * A palette table is an array of palette_entry_t structures. A decoder * should not count on this array to exist for the duration of the * program's execution and should copy, manipulate, and store the palette * data privately if it needs the palette information. */ #define BUF_SPECIAL_PALETTE 1 /* special buffer type 2 used to be defined but is now available for use */ /** * In a BUF_SPECIAL_ASPECT buffer: * decoder_info[1] = BUF_SPECIAL_ASPECT * decoder_info[2] = MPEG2 aspect ratio code * decoder_info[3] = stream scale prohibitions * This buffer is used to force mpeg decoders to use a certain aspect. * Currently xine-dvdnav uses this, because it has more accurate information * about the aspect from the dvd ifo-data. * The stream scale prohibitions are also delivered, with bit 0 meaning * "deny letterboxing" and bit 1 meaning "deny pan&scan" */ #define BUF_SPECIAL_ASPECT 3 /** * In a BUF_SPECIAL_DECODER_CONFIG buffer: * decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG * decoder_info[2] = data size * decoder_info_ptr[2] = pointer to data * This buffer is used to pass config information from .mp4 files * (atom esds) to decoders. both mpeg4 and aac streams use that. */ #define BUF_SPECIAL_DECODER_CONFIG 4 /** * In a BUF_SPECIAL_STSD_ATOM buffer: * decoder_info[1] = BUF_SPECIAL_STSD_ATOM * decoder_info[2] = size of the ImageDescription atom, minus the * four length bytes at the beginning * decoder_info_ptr[2] = pointer to ImageDescription atom, starting with * the codec fourcc * Some Quicktime decoders need information contained within the * ImageDescription atom inside a Quicktime file's stsd atom. This * special buffer carries the ImageDescription atom from the QT demuxer * to an A/V decoder. */ #define BUF_SPECIAL_STSD_ATOM 5 /** * In a BUF_SPECIAL_LPCM_CONFIG buffer: * decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG * decoder_info[2] = config data * lpcm data encoded into mpeg2 streams have a format configuration * byte in every frame. this is used to detect the sample rate, * number of bits and channels. */ #define BUF_SPECIAL_LPCM_CONFIG 6 /** * In a BUF_SPECIAL_CHARSET_ENCODING buffer: * decoder_info[1] = BUF_SPECIAL_CHARSET_ENCODING * decoder_info[2] = size of charset encoding string * decoder_info_ptr[2] = pointer to charset encoding string * This is used mostly with subtitle buffers when encoding is * known at demuxer level (take precedence over xine config * settings such as subtitles.separate.src_encoding) */ #define BUF_SPECIAL_CHARSET_ENCODING 7 /** * In a BUF_SPECIAL_SPU_DVD_SUBTYPE: * decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE * decoder_info[2] = subtype * decoder_info[3] = * This buffer is pass SPU subtypes from DVDs */ #define BUF_SPECIAL_SPU_DVD_SUBTYPE 8 #define SPU_DVD_SUBTYPE_CLUT 1 #define SPU_DVD_SUBTYPE_PACKAGE 2 #define SPU_DVD_SUBTYPE_VOBSUB_PACKAGE 3 #define SPU_DVD_SUBTYPE_NAV 4 /** * In a BUF_SPECIAL_SPU_DVB_DESCRIPTOR * decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR * decoder_info[2] = size of spu_dvb_descriptor_t * decoder_info_ptr[2] = pointer to spu_dvb_descriptor_t, or NULL * decoder_info[3] = * * This buffer is used to tell a DVBSUB decoder when the stream * changes. For more information on how to write a DVBSUB decoder, * see the comment at the top of src/demuxers/demux_ts.c **/ #define BUF_SPECIAL_SPU_DVB_DESCRIPTOR 9 /** * In a BUF_SPECIAL_RV_CHUNK_TABLE: * decoder_info[1] = BUF_SPECIAL_RV_CHUNK_TABLE * decoder_info[2] = number of entries in chunk table * decoder_info_ptr[2] = pointer to the chunk table * * This buffer transports the chunk table associated to each RealVideo frame. */ #define BUF_SPECIAL_RV_CHUNK_TABLE 10 /*@}*/ typedef struct spu_dvb_descriptor_s spu_dvb_descriptor_t; struct spu_dvb_descriptor_s { char lang[4]; long comp_page_id; long aux_page_id; } ; typedef struct palette_entry_s palette_entry_t; struct palette_entry_s { unsigned char r, g, b; } ; /* NOTE well: unfortunately, early libxine design made all these details public. * Please * a) use _x_[dummy_]fifo_buffer_new (), and dont assume anything about * the non function members, or * b) provide a full own implementation, which is tricky because fifo_buffer_t * has been enlarged with libxine version bumps, or * ?) at least never pass your own to engine or unaware plugins. * vdr-xineliboutput builds its own fifo_buffer_t structs from a partly copy * of a libxine one (including some functions) as pools. * We are trying hard to keep that vdr compatibility, with no guarantee. */ typedef struct fifo_buffer_s fifo_buffer_t; struct fifo_buffer_s { buf_element_t *first, *last; int fifo_size; uint32_t fifo_data_size; void *fifo_empty_cb_data; pthread_mutex_t mutex; pthread_cond_t not_empty; /* * functions to access this fifo: */ void (*put) (fifo_buffer_t *fifo, buf_element_t *buf); buf_element_t *(*get) (fifo_buffer_t *fifo); void (*clear) (fifo_buffer_t *fifo) ; int (*size) (fifo_buffer_t *fifo); int (*num_free) (fifo_buffer_t *fifo); uint32_t (*data_size) (fifo_buffer_t *fifo); void (*dispose) (fifo_buffer_t *fifo); /* * alloc buffer for this fifo from global buf pool * you don't have to use this function to allocate a buffer, * an input plugin can decide to implement it's own * buffer allocation functions */ buf_element_t *(*buffer_pool_alloc) (fifo_buffer_t *self); /* * special functions, not used by demuxers */ /* the same as buffer_pool_alloc but may fail if none is available */ buf_element_t *(*buffer_pool_try_alloc) (fifo_buffer_t *self); /* the same as put but insert at the head of the fifo */ void (*insert) (fifo_buffer_t *fifo, buf_element_t *buf); /* callbacks */ void (*register_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *), void *cb_data); void (*register_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); void (*register_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *), void *cb_data); void (*unregister_alloc_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, void *)); void (*unregister_put_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *)); void (*unregister_get_cb) (fifo_buffer_t *fifo, void (*cb)(fifo_buffer_t *fifo, buf_element_t *buf, void *)); /* * private variables for buffer pool management */ buf_element_t *buffer_pool_top; /* a heap actually */ pthread_mutex_t buffer_pool_mutex; pthread_cond_t buffer_pool_cond_not_empty; int buffer_pool_num_free; int buffer_pool_capacity; int buffer_pool_buf_size; void *buffer_pool_base; /*used to free mem chunk */ void (*alloc_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, void *data_cb); void (*put_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); void (*get_cb[BUF_MAX_CALLBACKS])(fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb); void *alloc_cb_data[BUF_MAX_CALLBACKS]; void *put_cb_data[BUF_MAX_CALLBACKS]; void *get_cb_data[BUF_MAX_CALLBACKS]; /* get a buffer large enough for given byte size. * result may still be smaller, do check buf->max_size. */ buf_element_t *(*buffer_pool_size_alloc) (fifo_buffer_t *self, size_t size); /* private */ int buffer_pool_num_waiters; int buffer_pool_large_wait; int fifo_num_waiters; /* Same as get but if ticket is not NULL * - release it while waiting for a buf, or * - renew it when revoked. */ buf_element_t *(*tget) (fifo_buffer_t *fifo, xine_ticket_t *ticket); /* Try to enlarge an allocated buf. * There are 2 possible results: * a) The buffer has been enlarged, and NULL is returned. * b) The buffer cannot be enlarged due to internal memory fragmentation, * and a new buffer for the extra data is returned. * No need for an extra buffer_pool_size_alloc (). * Any result may still be smaller, do check buf->max_size. */ buf_element_t *(*buffer_pool_realloc) (buf_element_t *buf, size_t new_size); } ; /** * @brief Allocate and initialise new (empty) FIFO buffers. * @param num_buffer Number of buffers to allocate. * @param buf_size Size of each buffer. * @internal Only used by video and audio decoder loops. */ fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED; /** * @brief Allocate and initialise new dummy FIFO buffers. * @param num_buffer Number of dummy buffers to allocate. * @param buf_size Size of each buffer. * @internal Only used by video and audio decoder loops. */ fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) XINE_PROTECTED; /** * @brief Free chained list of buffer elements. * @param head List to free. May be NULL. */ void _x_free_buf_elements (buf_element_t *head) XINE_PROTECTED; /** * @brief Returns the \ref buffer_video "BUF_VIDEO_xxx" for the given fourcc. * @param fourcc_int 32-bit FOURCC value in machine endianness * @sa _x_formattag_to_buf_audio * * example: fourcc_int = *(uint32_t *)fourcc_char; */ uint32_t _x_fourcc_to_buf_video( uint32_t fourcc_int ) XINE_PROTECTED; /** * @brief Returns video codec name given the buffer type. * @param buf_type One of the \ref buffer_video "BUF_VIDEO_xxx" values. * @sa _x_buf_audio_name */ const char * _x_buf_video_name( uint32_t buf_type ) XINE_PROTECTED; /** * @brief Returns the \ref buffer_audio "BUF_AUDIO_xxx" for the given formattag. * @param formattagg 32-bit format tag value in machine endianness * @sa _x_fourcc_to_buf_video */ uint32_t _x_formattag_to_buf_audio( uint32_t formattag ) XINE_PROTECTED; /** * @brief Returns audio codec name given the buffer type. * @param buf_type One of the \ref buffer_audio "BUF_AUDIO_xxx" values. * @sa _x_buf_video_name */ const char * _x_buf_audio_name( uint32_t buf_type ) XINE_PROTECTED; /** * @brief xine version of BITMAPINFOHEADER. * @note Should be safe to compile on 64bits machines. * @note Will always use machine endian format, so demuxers reading * stuff from win32 formats must use the function below. */ typedef struct XINE_PACKED { int32_t biSize; int32_t biWidth; int32_t biHeight; int16_t biPlanes; int16_t biBitCount; uint32_t biCompression; int32_t biSizeImage; int32_t biXPelsPerMeter; int32_t biYPelsPerMeter; int32_t biClrUsed; int32_t biClrImportant; } xine_bmiheader; /** * @brief xine version of WAVEFORMATEX. * @note The same comments from xine_bmiheader applies. */ typedef struct XINE_PACKED { int16_t wFormatTag; int16_t nChannels; int32_t nSamplesPerSec; int32_t nAvgBytesPerSec; int16_t nBlockAlign; int16_t wBitsPerSample; int16_t cbSize; } xine_waveformatex; /** Convert xine_bmiheader struct from little endian */ void _x_bmiheader_le2me( xine_bmiheader *bih ) XINE_PROTECTED; /** Convert xine_waveformatex struct from little endian */ void _x_waveformatex_le2me( xine_waveformatex *wavex ) XINE_PROTECTED; static __inline int _x_is_fourcc(const void *ptr, const void *tag) { return memcmp(ptr, tag, 4) == 0; } /** * @brief Make string from machine endian 32bit tag, eg a fourcc or a chunk ID. * @param s Pointer to string buffer of at least 20 bytes. * @param tag The 32bit tag value in native byte order. * @return The length of target string written to s, without the trailing \0. */ size_t _x_tag32_me2str (char *s, uint32_t tag) XINE_PROTECTED; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/xine_plugin.h0000644000175000017500000000771614647725152015757 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * generic plugin definitions */ #ifndef XINE_PLUGIN_H #define XINE_PLUGIN_H #include #include #define PLUGIN_NONE 0 #define PLUGIN_INPUT 1 #define PLUGIN_DEMUX 2 #define PLUGIN_AUDIO_DECODER 3 #define PLUGIN_VIDEO_DECODER 4 #define PLUGIN_SPU_DECODER 5 #define PLUGIN_AUDIO_OUT 6 #define PLUGIN_VIDEO_OUT 7 #define PLUGIN_POST 8 #define PLUGIN_TYPE_MAX PLUGIN_POST #define PLUGIN_XINE_MODULE 0x10 /* this flag may be or'ed with type in order to force preloading the plugin. * very useful to register config items on xine initialization. */ #define PLUGIN_MUST_PRELOAD (1 << 7) /* this flag may be or'ed with type to prevent the plugin loader from unloading * the plugin */ #define PLUGIN_NO_UNLOAD (1 << 6) #define PLUGIN_TYPE_MASK ((1 << 6) - 1) typedef struct { uint8_t type; /* one of the PLUGIN_* constants above */ uint8_t API; /* API version supported by this plugin */ const char *id; /* a name that identifies this plugin */ uint32_t version; /* version number, increased every release */ const void *special_info; /* plugin-type specific, see structs below */ void *(*init)(xine_t *, const void *); /* init the plugin class */ } plugin_info_t; /* special_info for a video output plugin */ typedef struct { int priority; /* priority of this plugin for auto-probing */ int visual_type; /* visual type supported by this plugin */ } vo_info_t; /* special info for a audio output plugin */ typedef struct { int priority; } ao_info_t; /* special_info for a decoder plugin */ typedef struct { const uint32_t *supported_types; /* streamtypes this decoder can handle */ int priority; } decoder_info_t; /* special info for a post plugin */ typedef struct { uint32_t type; /* type of the post plugin, use one of XINE_POST_TYPE_* */ } post_info_t; /* special info for a demuxer plugin */ typedef struct { int priority; } demuxer_info_t; /* special info for an input plugin */ typedef struct { int priority; } input_info_t; /* special info for generic loadable module * examples: * { .type = "tls_v1" }, * { .type = "gl_v1", .sub_type = XINE_VISUAL_TYPE_X11 }, */ typedef struct { int priority; char type[16]; /* plugin type (and version) */ unsigned int sub_type; } xine_module_info_t; /* register a list of statically linked plugins * info is a list of plugin_info_t terminated by PLUGIN_NONE * example: * plugin_info_t acme_plugin_info[] = { * { PLUGIN_VIDEO_OUT, 21, "acme", XINE_VERSION_CODE, &vo_info_acme, * init_class_acme }, * { PLUGIN_NONE, 0, "", 0, NULL, NULL } * }; * */ void xine_register_plugins(xine_t *self, const plugin_info_t *info) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/spu_decoder.h0000644000175000017500000001160214647725152015717 0ustar meme/* * spu_decoder_api.h * * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, * */ #ifndef HAVE_SPU_API_H #define HAVE_SPU_API_H #include #include #include struct plugin_node_s; #define SPU_DECODER_IFACE_VERSION 17 /* * generic xine spu decoder plugin interface */ typedef struct spu_decoder_class_s spu_decoder_class_t; typedef struct spu_decoder_s spu_decoder_t; struct spu_decoder_class_s { /* * open a new instance of this plugin class */ spu_decoder_t* (*open_plugin) (spu_decoder_class_t *this_gen, xine_stream_t *stream); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * free all class-related resources */ void (*dispose) (spu_decoder_class_t *this_gen); }; #define default_spu_decoder_class_dispose (void (*) (spu_decoder_class_t *this_gen))free struct spu_decoder_s { /* * decode data from buf and feed the overlay to overlay manager */ void (*decode_data) (spu_decoder_t *this_gen, buf_element_t *buf); /* * reset decoder after engine flush (prepare for new * SPU data not related to recently decoded data) */ void (*reset) (spu_decoder_t *this_gen); /* * inform decoder that a time reference discontinuity has happened. * that is, it must forget any currently held pts value */ void (*discontinuity) (spu_decoder_t *this_gen); /* * close down, free all resources */ void (*dispose) (spu_decoder_t *this_gen); /* * When the SPU decoder also handles data used in user interaction, * you can query the related information here. The typical example * for this is DVD NAV packets which are handled by the SPU decoder * and can be received readily parsed from here. * The caller and the decoder must agree on the structure which is * passed here. * This function pointer may be NULL, if the plugin does not have * such functionality. */ int (*get_interact_info) (spu_decoder_t *this_gen, void *data); /* * When the SPU decoder also handles menu overlays for user inter- * action, you can set a menu button here. The typical example for * this is DVD menus. * This function pointer may be NULL, if the plugin does not have * such functionality. */ void (*set_button) (spu_decoder_t *this_gen, int32_t button, int32_t mode); /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; }; /* SPU decoders differ from video and audio decoders in one significant * way: unlike audio and video, SPU streams are not continuous; * this results in another difference, programmers have to consider: * while both audio and video decoders are automatically blocked in * their get_buffer()/get_frame() methods when the output cannot take * any more data, this does not work for SPU, because it could take * minutes before the next free slot becomes available and we must not * block the decoder thread for that long; * therefore, we provide a convenience function for SPU decoders which * implements a wait until a timestamp sufficiently close to the VPTS * of the next SPU is reached, but the waiting will end before that, * if some outside condition requires us to release the decoder thread * to other tasks; * if this functions returns with 1, noone needs the decoder thread and * you may continue waiting; if it returns 0, finish whatever you are * doing and return; * the usual pattern for SPU decoders is this: * * do { * spu = prepare_spu(); * int thread_vacant = _x_spu_decoder_sleep(this->stream, spu->vpts); * int success = process_spu(spu); * } while (!success && thread_vacant); */ int _x_spu_decoder_sleep(xine_stream_t *, int64_t next_spu_vpts) XINE_PROTECTED; #endif /* HAVE_SPUDEC_H */ xine-lib-1.2/include/xine/xine_buffer.h0000644000175000017500000001060414647725152015720 0ustar meme/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * generic dynamic buffer functions. The goals * of these functions are (in fact many of these points * are todos): * - dynamic allocation and reallocation depending * on the size of data written to it. * - fast and transparent access to the data. * The user sees only the raw data chunk as it is * returned by the well-known malloc function. * This is necessary since not all data-accessing * functions can be wrapped here. * - some additional health checks are made during * development (eg boundary checks after direct * access to a buffer). This can be turned off in * production state for higher performance. * - A lot of convenient string and memory manipulation * functions are implemented here, where the user * do not have to care about memory chunk sizes. * - Some garbage collention could be implemented as well; * i think of a global structure containing infos * about all allocated chunks. This must be implemented * in a thread-save way... * * Here are some drawbacks (aka policies): * - The user must not pass indexed buffers to xine_buffer_* * functions. * - The pointers passed to xine_buffer_* functions may change * (eg during reallocation). The user must respect that. */ #ifndef HAVE_XINE_BUFFER_H #define HAVE_XINE_BUFFER_H #include #include /* * returns an initialized pointer to a buffer. * The buffer will be allocated in blocks of * chunk_size bytes. This will prevent permanent * reallocation on slow growing buffers. */ void *xine_buffer_init(int chunk_size) XINE_PROTECTED; /* * frees a buffer, the macro ensures, that a freed * buffer pointer is set to NULL */ #define xine_buffer_free(buf) buf=_xine_buffer_free(buf) void *_xine_buffer_free(void *buf) XINE_PROTECTED; /* * duplicates a buffer */ void *xine_buffer_dup(const void *buf) XINE_PROTECTED; /* * will copy len bytes of data into buf at position index. */ #define xine_buffer_copyin(buf,i,data,len) \ buf=_xine_buffer_copyin(buf,i,data,len) void *_xine_buffer_copyin(void *buf, int index, const void *data, int len) XINE_PROTECTED; /* * will copy len bytes out of buf+index into data. * no checks are made in data. It is treated as an ordinary * user-malloced data chunk. */ void xine_buffer_copyout(const void *buf, int index, void *data, int len) XINE_PROTECTED; /* * set len bytes in buf+index to b. */ #define xine_buffer_set(buf,i,b,len) \ buf=_xine_buffer_set(buf,i,b,len) void *_xine_buffer_set(void *buf, int index, uint8_t b, int len) XINE_PROTECTED; /* * concatenates given buf (which should contain a null terminated string) * with another string. */ #define xine_buffer_strcat(buf,data) \ buf=_xine_buffer_strcat(buf,data) void *_xine_buffer_strcat(void *buf, const char *data) XINE_PROTECTED; /* * copies given string to buf+index */ #define xine_buffer_strcpy(buf,index,data) \ buf=_xine_buffer_strcpy(buf,index,data) void *_xine_buffer_strcpy(void *buf, int index, const char *data) XINE_PROTECTED; /* * returns a pointer to the first occurence of ch. * note, that the returned pointer cannot be used * in any other xine_buffer_* functions. */ char *xine_buffer_strchr(const void *buf, int ch) XINE_PROTECTED; /* * get allocated memory size */ int xine_buffer_get_size(const void *buf) XINE_PROTECTED; /* * ensures a specified buffer size if the user want to * write directly to the buffer. Normally the special * access functions defined here should be used. */ #define xine_buffer_ensure_size(buf,data) \ buf=_xine_buffer_ensure_size(buf,data) void *_xine_buffer_ensure_size(void *buf, int size) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/array.h0000644000175000017500000000425514647725152014547 0ustar meme/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Array that can grow automatically when you add elements. * Inserting an element in the middle of the array implies memory moves. */ #ifndef XINE_ARRAY_H #define XINE_ARRAY_H #include /* size_t */ #include /* Array type */ typedef struct xine_array_s xine_array_t; /* Constructor */ xine_array_t *xine_array_new(size_t initial_size) XINE_MALLOC XINE_PROTECTED; /* Destructor */ void xine_array_delete(xine_array_t *array) XINE_PROTECTED; /* Returns the number of element stored in the array */ size_t xine_array_size(const xine_array_t *array) XINE_PROTECTED; /* Removes all elements from an array */ void xine_array_clear(xine_array_t *array) XINE_PROTECTED; /* Adds the element at the end of the array */ void xine_array_add(xine_array_t *array, void *value) XINE_PROTECTED; /* Inserts an element into an array at the position specified */ void xine_array_insert(xine_array_t *array, unsigned int position, void *value) XINE_PROTECTED; /* Removes one element from an array at the position specified */ void xine_array_remove(xine_array_t *array, unsigned int position) XINE_PROTECTED; /* Get the element at the position specified */ void *xine_array_get(const xine_array_t *array, unsigned int position) XINE_PROTECTED; /* Set the element at the position specified */ void xine_array_set(xine_array_t *array, unsigned int position, void *value) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/audio_out.h0000644000175000017500000002566114647725152015425 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_AUDIO_OUT_H #define HAVE_AUDIO_OUT_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include struct plugin_node_s; #define AUDIO_OUT_IFACE_VERSION 9 /* * ao_driver_s contains the driver every audio output * driver plugin has to implement. */ typedef struct ao_driver_s ao_driver_t; struct ao_driver_s { /* * * find out what output modes + capatilities are supported by * this plugin (constants for the bit vector to return see above) * * See AO_CAP_* bellow. */ uint32_t (*get_capabilities) (ao_driver_t *); /* * open the driver and make it ready to receive audio data * buffers may be flushed(!) * * return value: 0 : failure, >0 : output sample rate */ int (*open)(ao_driver_t *, uint32_t bits, uint32_t rate, int mode); /* return the number of audio channels */ int (*num_channels)(ao_driver_t *self_gen); /* return the number of bytes per frame. * A frame is equivalent to one sample being output on every audio channel. */ int (*bytes_per_frame)(ao_driver_t *self_gen); /* return the delay is frames measured by * looking at pending samples in the audio output device */ int (*delay)(ao_driver_t *self_gen); /* * return gap tolerance (in pts) needed for this driver */ int (*get_gap_tolerance) (ao_driver_t *self_gen); /* * write audio data to audio output device * return value: * >0 => audio samples were processed ok * 0 => audio samples were not yet processed, * call write_audio_data with the _same_ samples again */ int (*write)(ao_driver_t *, int16_t* audio_data, uint32_t num_samples); /* * this is called when the decoder no longer uses the audio * output driver - the driver should get ready to get opened() again */ void (*close)(ao_driver_t *); /* * shut down this audio output driver plugin and * free all resources allocated */ void (*exit) (ao_driver_t *); /* * Get, Set a property of audio driver. * * get_property() return 1 in success, 0 on failure. * set_property() return value on success, ~value on failure. * * See AO_PROP_* below for available properties. */ int (*get_property) (ao_driver_t *, int property); int (*set_property) (ao_driver_t *, int property, int value); /* * misc control operations on the audio device. * * See AO_CTRL_* below. */ int (*control) (ao_driver_t *, int cmd, /* arg */ ...); /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; }; typedef struct ao_format_s ao_format_t; struct ao_format_s { uint32_t bits; uint32_t rate; int mode; }; typedef struct audio_fifo_s audio_fifo_t; typedef struct audio_buffer_s audio_buffer_t; struct audio_buffer_s { audio_buffer_t *next; int16_t *mem; int mem_size; int num_frames; int64_t vpts; uint32_t frame_header_count; uint32_t first_access_unit; /* extra info coming from input or demuxers */ extra_info_t *extra_info; xine_stream_t *stream; /* stream that send that buffer */ ao_format_t format; /* let each buffer carry it's own format info */ }; /* * xine_audio_port_s contains the port every audio decoder talks to * * Remember that adding new functions to this structure requires * adaption of the post plugin decoration layer. Be sure to look into * src/xine-engine/post.[ch]. */ struct xine_audio_port_s { uint32_t (*get_capabilities) (xine_audio_port_t *); /* for constants see below */ /* * Get/Set audio property * * See AO_PROP_* bellow */ int (*get_property) (xine_audio_port_t *, int property); int (*set_property) (xine_audio_port_t *, int property, int value); /* open audio driver for audio output * return value: 0:failure, >0:output sample rate */ /* when you are not a full-blown stream, but still need to open the port * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ int (*open) (xine_audio_port_t *, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode); /* * get a piece of memory for audio data */ audio_buffer_t * (*get_buffer) (xine_audio_port_t *); /* * append a buffer filled with audio data to the audio fifo * for output */ /* when the frame does not originate from a stream, it is legal to pass an anonymous stream */ void (*put_buffer) (xine_audio_port_t *, audio_buffer_t *buf, xine_stream_t *stream); /* audio driver is no longer used by decoder => close */ /* when you are not a full-blown stream, but still need to close the port * (e.g. you are a post plugin) it is legal to pass an anonymous stream */ void (*close) (xine_audio_port_t *self, xine_stream_t *stream); /* called on xine exit */ void (*exit) (xine_audio_port_t *); /* * misc control operations on the audio device. * * See AO_CTRL_* below. */ int (*control) (xine_audio_port_t *, int cmd, /* arg */ ...); /* * Flush audio_out fifo. */ void (*flush) (xine_audio_port_t *); /* * Check if port is opened for this stream and get parameters. * The stream can be anonymous. */ int (*status) (xine_audio_port_t *, xine_stream_t *stream, uint32_t *bits, uint32_t *rate, int *mode); }; typedef struct audio_driver_class_s audio_driver_class_t; struct audio_driver_class_s { /* * open a new instance of this plugin class */ ao_driver_t* (*open_plugin) (audio_driver_class_t *, const void *data); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * free all class-related resources */ void (*dispose) (audio_driver_class_t *); }; #define default_audio_driver_class_dispose (void (*) (audio_driver_class_t *this_gen))free /** * @brief Initialise the audio_out sync routines * * @internal */ xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) XINE_MALLOC; /* * audio output modes + capabilities */ #define AO_CAP_NOCAP 0x00000000 /* driver has no capabilities */ #define AO_CAP_MODE_A52 0x00000001 /* driver supports A/52 output */ #define AO_CAP_MODE_AC5 0x00000002 /* driver supports AC5 output */ /* 1 sample == 2 bytes (C) */ #define AO_CAP_MODE_MONO 0x00000004 /* driver supports mono output */ /* 1 sample == 4 bytes (L,R) */ #define AO_CAP_MODE_STEREO 0x00000008 /* driver supports stereo output */ /* 1 sample == 8 bytes (L,R,LR,RR) */ #define AO_CAP_MODE_4CHANNEL 0x00000010 /* driver supports 4 channels */ /* * Sound cards generally support, 1,2,4,6 channels, but rarely 5. * So xine will take 4.1, 5 and 6 channel a52 streams and * down or upmix it correctly to fill the 6 output channels. * Are there any requests for 2.1 out there? */ /* 1 sample == 12 bytes (L,R,LR,RR,Null,LFE) */ #define AO_CAP_MODE_4_1CHANNEL 0x00000020 /* driver supports 4.1 channels */ /* 1 sample == 12 bytes (L,R,LR,RR,C, Null) */ #define AO_CAP_MODE_5CHANNEL 0x00000040 /* driver supports 5 channels */ /* 1 sample == 12 bytes (L,R,LR,RR,C,LFE) */ #define AO_CAP_MODE_5_1CHANNEL 0x00000080 /* driver supports 5.1 channels */ /* * converts the audio output mode into the number of channels */ int _x_ao_mode2channels( int mode ) XINE_PROTECTED; /* * converts the number of channels into the audio output mode */ int _x_ao_channels2mode( int channels ) XINE_PROTECTED; #define AO_CAP_MIXER_VOL 0x00000100 /* driver supports mixer control */ #define AO_CAP_PCM_VOL 0x00000200 /* driver supports pcm control */ #define AO_CAP_MUTE_VOL 0x00000400 /* driver can mute volume */ #define AO_CAP_8BITS 0x00000800 /* driver support 8-bit samples */ #define AO_CAP_16BITS 0x00001000 /* driver support 16-bit samples */ #define AO_CAP_24BITS 0x00002000 /* driver support 24-bit samples */ #define AO_CAP_FLOAT32 0x00004000 /* driver support 32-bit samples. i.e. Floats */ #define AO_CAP_NO_UNPAUSE 0x00008000 /* driver can not resume after pause. * please resend some frames instead. */ /* properties supported by get/set_property() */ #define AO_PROP_MIXER_VOL 0 #define AO_PROP_PCM_VOL 1 #define AO_PROP_MUTE_VOL 2 #define AO_PROP_COMPRESSOR 3 #define AO_PROP_DISCARD_BUFFERS 4 #define AO_PROP_BUFS_IN_FIFO 5 /* read-only */ #define AO_PROP_AMP 6 /* amplifier */ #define AO_PROP_EQ_30HZ 7 /* equalizer */ #define AO_PROP_EQ_60HZ 8 /* equalizer */ #define AO_PROP_EQ_125HZ 9 /* equalizer */ #define AO_PROP_EQ_250HZ 10 /* equalizer */ #define AO_PROP_EQ_500HZ 11 /* equalizer */ #define AO_PROP_EQ_1000HZ 12 /* equalizer */ #define AO_PROP_EQ_2000HZ 13 /* equalizer */ #define AO_PROP_EQ_4000HZ 14 /* equalizer */ #define AO_PROP_EQ_8000HZ 15 /* equalizer */ #define AO_PROP_EQ_16000HZ 16 /* equalizer */ #define AO_PROP_CLOSE_DEVICE 17 /* force closing audio device */ #define AO_PROP_AMP_MUTE 18 /* amplifier mute */ #define AO_PROP_NUM_STREAMS 19 /* read-only */ #define AO_PROP_CLOCK_SPEED 20 /* inform audio_out that speed has changed */ #define AO_PROP_BUFS_TOTAL 21 /* read-only */ #define AO_PROP_BUFS_FREE 22 /* read-only */ #define AO_PROP_DRIVER_DELAY 23 /* read-only */ #define AO_PROP_PTS_IN_FIFO 24 /* read only */ #define AO_NUM_PROPERTIES 25 /* audio device control ops */ #define AO_CTRL_PLAY_PAUSE 0 #define AO_CTRL_PLAY_RESUME 1 #define AO_CTRL_FLUSH_BUFFERS 2 /* above that value audio frames are discarded */ #define AO_MAX_GAP 15000 #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/input_plugin.h0000644000175000017500000004021114647725152016136 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_INPUT_PLUGIN_H #define HAVE_INPUT_PLUGIN_H #include /* off_t */ #include #include #include #include struct plugin_node_s; #define INPUT_PLUGIN_IFACE_VERSION 18 typedef struct input_class_s input_class_t ; typedef struct input_plugin_s input_plugin_t; struct input_class_s { /* * create a new instance of this plugin class * return NULL if the plugin does'nt handle the given mrl */ input_plugin_t* (*get_instance) (input_class_t *this_gen, xine_stream_t *stream, const char *mrl); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * ls function, optional: may be NULL * return value: NULL => filename is a file, **char=> filename is a dir */ xine_mrl_t ** (*get_dir) (input_class_t *this_gen, const char *filename, int *nFiles); /* * generate autoplay list, optional: may be NULL * return value: list of MRLs */ const char * const * (*get_autoplay_list) (input_class_t *this_gen, int *num_files); /* * close down, free all resources */ void (*dispose) (input_class_t *this_gen); /* * eject/load the media (if possible), optional: may be NULL * * returns 0 for temporary failures */ int (*eject_media) (input_class_t *this_gen); }; #define default_input_class_dispose (void (*) (input_class_t *this_gen))free struct input_plugin_s { /* * open the stream * return 0 if an error occured */ int (*open) (input_plugin_t *this_gen); /* * return capabilities of the current playable entity. See * get_current_pos below for a description of a "playable entity" * Capabilities a created by "OR"ing a mask of constants listed * below which start "INPUT_CAP". * * depending on the values set, some of the functions below * will or will not get called or should (not) be able to * do certain tasks. * * for example if INPUT_CAP_SEEKABLE is set, * the seek() function is expected to work fully at any time. * however, if the flag is not set, the seek() function should * make a best-effort attempt to seek, e.g. at least * relative forward seeking should work. */ uint32_t (*get_capabilities) (input_plugin_t *this_gen); /* * read nlen bytes, return number of bytes read * Should block until some bytes available for read; * a return value of 0 indicates no data available */ off_t (*read) (input_plugin_t *this_gen, void *buf, off_t nlen) XINE_USED; /* * read one block, return newly allocated block (or NULL on failure) * for blocked input sources len must be == blocksize * the fifo parameter is only used to get access to the buffer_pool_alloc function */ buf_element_t *(*read_block)(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t len); /* * seek position, return new position * * if seeking failed, -1 is returned */ off_t (*seek) (input_plugin_t *this_gen, off_t offset, int origin); /* * seek to time position, return new position * time_offset is given in miliseconds * * if seeking failed, -1 is returned * * note: only SEEK_SET (0) is currently supported as origin, * unless INPUT_CAP_TIME_SEEKABLE is set. * note: may be NULL is not supported */ off_t (*seek_time) (input_plugin_t *this_gen, int time_offset, int origin); /* * get current position in stream. * */ off_t (*get_current_pos) (input_plugin_t *this_gen); /* * get current time position in stream in miliseconds. * * note: may be NULL is not supported */ int (*get_current_time) (input_plugin_t *this_gen); /* * return number of bytes in the next playable entity or -1 if the * input is unlimited, as would be the case in a network stream. * * A "playable entity" tends to be the entities listed in a playback * list or the units on which playback control generally works on. * It might be the number of bytes in a VCD "segment" or "track" (if * the track has no "entry" subdivisions), or the number of bytes in * a PS (Program Segment or "Chapter") of a DVD. If there are no * subdivisions of the input medium and it is considered one * indivisible entity, it would be the byte count of that entity; * for example, the length in bytes of an MPEG file. * This length information is used, for example when in setting the * absolute or relative play position or possibly calculating the * bit rate. */ off_t (*get_length) (input_plugin_t *this_gen); /* * return block size in bytes of next complete playable entity (if * supported, 0 otherwise). See the description above under * get_length for a description of a "complete playable entity". * * this block size is only used for mpeg streams stored on * a block oriented storage media, e.g. DVDs and VCDs, to speed * up the demuxing process. only set this (and the INPUT_CAP_BLOCK * flag) if this is the case for your input plugin. * * make this function simply return 0 if unsure. */ uint32_t (*get_blocksize) (input_plugin_t *this_gen); /* * return current MRL */ const char * (*get_mrl) (input_plugin_t *this_gen); /* * request optional data from input plugin. */ int (*get_optional_data) (input_plugin_t *this_gen, void *data, int data_type); /* * close stream, free instance resources */ void (*dispose) (input_plugin_t *this_gen); /* * "backward" link to input plugin class struct */ input_class_t *input_class; /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; }; /* * possible capabilites an input plugin can have: */ #define INPUT_CAP_NOCAP 0x00000000 /* * INPUT_CAP_SEEKABLE: * seek () works reliably. * even for plugins that do not have this flag set * it is a good idea to implement the seek() function * in a "best effort" style anyway, so at least * throw away data for network streams when seeking forward */ #define INPUT_CAP_SEEKABLE 0x00000001 /* * INPUT_CAP_BLOCK: * means more or less that a block device sits behind * this input plugin. get_blocksize must be implemented. * will be used for fast and efficient demuxing of * mpeg streams (demux_mpeg_block). */ #define INPUT_CAP_BLOCK 0x00000002 /* * INPUT_CAP_AUDIOLANG: * INPUT_CAP_SPULANG: * input plugin knows something about audio/spu languages, * e.g. knows that audio stream #0 is english, * audio stream #1 is german, ... * *((int *)data) will provide the requested channel number * and awaits the language back in (char *)data */ #define INPUT_CAP_AUDIOLANG 0x00000008 #define INPUT_CAP_SPULANG 0x00000010 /* * INPUT_CAP_PREVIEW: * get_optional_data can handle INPUT_OPTIONAL_DATA_PREVIEW * so a non-seekable stream plugin can povide the first * few bytes for demuxers to look at them and decide wheter * they can handle the stream or not. the preview data must * be buffered and delivered again through subsequent * read() calls. * caller must provide a buffer allocated with at least * MAX_PREVIEW_SIZE bytes. */ #define INPUT_CAP_PREVIEW 0x00000040 /* * INPUT_CAP_CHAPTERS: * The media streams provided by this plugin have an internal * structure dividing it into segments usable for navigation. * For those plugins, the behaviour of the skip button in UIs * should be changed from "next MRL" to "next chapter" by * sending XINE_EVENT_INPUT_NEXT. */ #define INPUT_CAP_CHAPTERS 0x00000080 /* * INPUT_CAP_RIP_FORBIDDEN: * means that rip/disk saving must not be used. * (probably at author's request) */ #define INPUT_CAP_RIP_FORBIDDEN 0x00000100 /* * INPUT_CAP_NO_CACHE: * do not use input cache plugin */ #define INPUT_CAP_NO_CACHE 0x00000200 /* * INPUT_CAP_CLONE: * open a second input plugin instance on the same source. */ #define INPUT_CAP_CLONE 0x00000400 /* * INPUT_CAP_SLOW_SEEKABLE: * Like INPUT_CAP_SEEKABLE, but seeking may be expensive. * Short forward seeks are fast (ex. implemented by skipping data). * Seeking back or far forward is expensive. * * This type of seeking should be used only when user issues seek request * and the destination offset is known (no binary search etc. required). * Another use case could be when header is located at the end of file. * */ #define INPUT_CAP_SLOW_SEEKABLE 0x00000800 #define INPUT_IS_SEEKABLE(input) (((input)->get_capabilities(input) & INPUT_CAP_SEEKABLE) != 0) #define INPUT_IS_SLOW_SEEKABLE(input) (((input)->get_capabilities(input) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) != 0) /* * INPUT_CAP_SIZED_PREVIEW: * Like INPUT_CAP_PREVIEW, but the buffer shall contain an int telling * the count of bytes to read before the call. */ #define INPUT_CAP_SIZED_PREVIEW 0x00001000 /* * INPUT_CAP_TIME_SEEKABLE: * Time based seek works reliably and should be preferred over size based seek. */ #define INPUT_CAP_TIME_SEEKABLE 0x00002000 /* * INPUT_CAP_NEW_MRL: * Plugin can try to switch to a new mrl on the fly. * See INPUT_OPTIONAL_DATA_NEW_MRL below. */ #define INPUT_CAP_NEW_MRL 0x00004000 /* * INPUT_CAP_LIVE: * Plugin knows it has a real live stream. It runs at a fixed speed that is * _roughly_ the same as XINE_FINE_SPEED_NORMAL. */ #define INPUT_CAP_LIVE 0x00008000 #define INPUT_OPTIONAL_UNSUPPORTED 0 #define INPUT_OPTIONAL_SUCCESS 1 #define INPUT_OPTIONAL_DATA_AUDIOLANG 2 #define INPUT_OPTIONAL_DATA_SPULANG 3 #define INPUT_OPTIONAL_DATA_PREVIEW 7 /* buffer is a const char **; the string is freed by the input plugin. */ #define INPUT_OPTIONAL_DATA_MIME_TYPE 8 /* buffer is unused; true if the demuxer should be determined by the MIME type */ #define INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE 9 /* buffer is a const char **; the string is static or freed by the input plugin. */ #define INPUT_OPTIONAL_DATA_DEMUXER 10 /* buffer is a struct input_plugin_s **; release by calling ptr->dispose (ptr). */ #define INPUT_OPTIONAL_DATA_CLONE 11 /* see INPUT_CAP_SIZED_PREVIEW above. */ #define INPUT_OPTIONAL_DATA_SIZED_PREVIEW 12 /* buffer is an int32_t * where input plugin will store media duration in milliseconds. */ #define INPUT_OPTIONAL_DATA_DURATION 13 /* buffer is a const char * holding the new mrl to try. * fragment streams can avoid input_plugin->dispose () followed by input_class->get_instance (), * or _x_free_input_plugin () followed by _x_find_input_plugin () on a lot of * similar mrls. * an empty mrl (buffer[0] == 0) means close connection now, and wait for a real new mrl later. */ #define INPUT_OPTIONAL_DATA_NEW_MRL 14 /* buffer is a xine_mfrag_list_t ** where input plugin will store a pointer to its media fragment * list, if any (see ). demux may update it if fragment index is part of the * container, like with some .mp4. */ #define INPUT_OPTIONAL_DATA_FRAGLIST 15 /* after a successful open () of a main input, this may supply possible side stream inputs. * on call, buffer is an int * telling the side stream index 1..3. * on return, buffer is a struct input_plugin_s ** where a pointer to a ready side input * bound to xine_get_side_stream (main_stream, stream_index) will be stored if available. * NOTE: this shall be an alternative get_instance (), not the result of an _x_find_input_plugin (). * release by _x_free_input_plugin () or xine_dispose () of the side stream. */ #define INPUT_OPTIONAL_DATA_SIDE 16 /* returns a pts value (1/90000s) to add to all demux media pts, or INPUT_OPTIONAL_UNSUPPORTED == 0. * some fragment streams need this to provide a/v sync over multiple side streams. */ #define INPUT_OPTIONAL_DATA_PTSOFFS 17 /* data is an int * telling how many seconds to go back into a live stream. * yes this _does_ work sometimes, up to 24h ;-) */ #define INPUT_OPTIONAL_DATA_REWIND 18 /* ask plugin to generate a new preview from the current position, * eg to skip a large ID3v2 tag. data is ignored. */ #define INPUT_OPTIONAL_DATA_NEW_PREVIEW 19 #define MAX_MRL_ENTRIES 255 #define MAX_PREVIEW_SIZE 4096 /* network buffering control */ typedef struct xine_nbc_st xine_nbc_t; xine_nbc_t *xine_nbc_init (xine_stream_t *stream) XINE_PROTECTED; /* returns a combinwd demux pts position, starting with 0 at stream start. */ int64_t xine_nbc_get_pos_pts (xine_nbc_t *nbc) XINE_PROTECTED; void xine_nbc_close (xine_nbc_t *nbc) XINE_PROTECTED; /* Types of mrls returned by get_dir() */ #define mrl_unknown (0 << 0) #define mrl_dvd (1 << 0) #define mrl_vcd (1 << 1) #define mrl_net (1 << 2) #define mrl_rtp (1 << 3) #define mrl_stdin (1 << 4) #define mrl_cda (1 << 5) #define mrl_file (1 << 6) #define mrl_file_fifo (1 << 7) #define mrl_file_chardev (1 << 8) #define mrl_file_directory (1 << 9) #define mrl_file_blockdev (1 << 10) #define mrl_file_normal (1 << 11) #define mrl_file_symlink (1 << 12) #define mrl_file_sock (1 << 13) #define mrl_file_exec (1 << 14) #define mrl_file_backup (1 << 15) #define mrl_file_hidden (1 << 16) /* * Freeing/zeroing all of entries of given mrl. */ #define MRL_ZERO(m) { \ if((m)) { \ free((m)->origin); \ free((m)->mrl); \ free((m)->link); \ (m)->origin = NULL; \ (m)->mrl = NULL; \ (m)->link = NULL; \ (m)->type = 0; \ (m)->size = (off_t) 0; \ } \ } /* * Duplicate two mrls entries (s = source, d = destination). */ #define MRL_DUPLICATE(s, d) { \ _x_assert((s) != NULL); \ _x_assert((d) != NULL); \ \ free((d)->origin); \ (d)->origin = (s)->origin ? strdup((s)->origin) : NULL; \ \ free((d)->mrl); \ (d)->mrl = (s)->mrl ? strdup((s)->mrl) : NULL; \ \ free((d)->link); \ (d)->link = (s)->link ? strdup((s)->link) : NULL; \ \ (d)->type = (s)->type; \ (d)->size = (s)->size; \ } /* * Duplicate two arrays of mrls (s = source, d = destination). */ #define MRLS_DUPLICATE(s, d) { \ int i = 0; \ \ _x_assert((s) != NULL); \ _x_assert((d) != NULL); \ \ while((s) != NULL) { \ d[i] = (xine_mrl_t *) malloc(sizeof(xine_mrl_t)); \ MRL_DUPLICATE(s[i], d[i]); \ i++; \ } \ } #endif xine-lib-1.2/include/xine/resample.h0000644000175000017500000000460714647725152015242 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * utilitiy functions for audio drivers * * FIXME: not all of them are implemented yet */ #ifndef HAVE_RESAMPLE_H #define HAVE_RESAMPLE_H #include #include #define RESAMPLE_MAX_CHANNELS 6 void _x_audio_out_resample_stereo(int16_t* last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; void _x_audio_out_resample_mono(int16_t* last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; void _x_audio_out_resample_4channel(int16_t* last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; void _x_audio_out_resample_5channel(int16_t* last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; void _x_audio_out_resample_6channel(int16_t* last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) XINE_PROTECTED; void _x_audio_out_resample_8to16(int8_t* input_samples, int16_t* output_samples, uint32_t samples) XINE_PROTECTED; void _x_audio_out_resample_16to8(int16_t* input_samples, int8_t* output_samples, uint32_t samples) XINE_PROTECTED; void _x_audio_out_resample_monotostereo(int16_t* input_samples, int16_t* output_samples, uint32_t frames) XINE_PROTECTED; void _x_audio_out_resample_stereotomono(int16_t* input_samples, int16_t* output_samples, uint32_t frames) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/video_overlay.h0000644000175000017500000000607014647725152016275 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_VIDEO_OVERLAY_H #define HAVE_VIDEO_OVERLAY_H #include #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) {.y = (_y), .cr = (_cr), .cb = (_cb) } #elif defined(__GNUC__) #define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) {y: (_y), cr: (_cr), cb: (_cb)} #else #define CLUT_Y_CR_CB_INIT(_y,_cr,_cb) { (_cb), (_cr), (_y) } #endif #define MAX_OBJECTS 50 #define MAX_EVENTS 50 #define MAX_SHOWING (5 + 16) #define OVERLAY_EVENT_NULL 0 #define OVERLAY_EVENT_SHOW 1 #define OVERLAY_EVENT_HIDE 2 #define OVERLAY_EVENT_MENU_BUTTON 3 #define OVERLAY_EVENT_FREE_HANDLE 8 /* Frees a handle, previous allocated via get_handle */ typedef struct video_overlay_object_s { int32_t handle; /* Used to match Show and Hide events. */ uint32_t object_type; /* 0=Subtitle, 1=Menu */ int64_t pts; /* Needed for Menu button compares */ vo_overlay_t *overlay; /* The image data. */ uint32_t *palette; /* If NULL, no palette contained in this event. */ uint32_t palette_type; /* 1 Y'CrCB, 2 R'G'B' */ } video_overlay_object_t; /* This will hold all details of an event item, needed for event queue to function */ typedef struct video_overlay_event_s { int64_t vpts; /* Time when event will action. 0 means action now */ /* Once video_out blend_yuv etc. can take rle_elem_t with Colour, blend and length information. * we can remove clut and blend from this structure. * This will allow for many more colours for OSD. */ uint32_t event_type; /* Show SPU, Show OSD, Hide etc. */ video_overlay_object_t object; /* The image data. */ } video_overlay_event_t; video_overlay_manager_t *_x_video_overlay_new_manager(xine_t *) XINE_MALLOC XINE_PROTECTED; /* Transport color matrix setting inside those unused "foo" fields. Guard against uninitialized values. */ #define _X_SET_CLUT_CM(_clut,_color_matrix) { \ uint8_t *q = (uint8_t *)(_clut); \ q[3] = 'X'; \ q[7] = 'C'; \ q[11] = 'M'; \ q[15] = _color_matrix; \ } void _x_overlay_clut_yuv2rgb(vo_overlay_t *overlay, int video_color_matrix) XINE_PROTECTED; void _x_overlay_to_argb32(const vo_overlay_t *overlay, uint32_t *rgba, int stride, const char *format) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/attributes.h0000644000175000017500000001141214647725152015610 0ustar meme/* * attributes.h * Copyright (C) 1999-2000 Aaron Holtzman * Copyright (C) 2001-2021 xine developers * * This file was originally part of mpeg2dec, a free MPEG-2 video stream * decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* use gcc attribs to align critical data structures */ #ifndef ATTRIBUTE_H_ #define ATTRIBUTE_H_ #ifdef XINE_COMPILE # if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # warning Define XINE_COMPILE _only_ when tweaking xine-lib itself, and then include xine config.h early in your source file! # endif #else # if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95 ) # define SUPPORT_ATTRIBUTE_PACKED 1 # endif # if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3 ) # define SUPPORT_ATTRIBUTE_DEPRECATED 1 # define SUPPORT_ATTRIBUTE_FORMAT 1 # define SUPPORT_ATTRIBUTE_FORMAT_ARG 1 # define SUPPORT_ATTRIBUTE_MALLOC 1 # define SUPPORT_ATTRIBUTE_UNUSED 1 # define SUPPORT_ATTRIBUTE_CONST 1 # define SUPPORT_ATTRIBUTE_WARN_UNUSED_RESULT 1 # endif # if __GNUC__ >= 4 # define SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT 1 # if defined(__ELF__) && __ELF__ # define SUPPORT_ATTRIBUTE_VISIBILITY_PROTECTED 1 # endif # define SUPPORT_ATTRIBUTE_SENTINEL 1 # endif #endif #if defined(SUPPORT_ATTRIBUTE_WARN_UNUSED_RESULT) # define XINE_USED __attribute__((warn_unused_result)) #else # define XINE_USED #endif #ifdef ATTRIBUTE_ALIGNED_MAX #define ATTR_ALIGN(align) __attribute__ ((__aligned__ ((ATTRIBUTE_ALIGNED_MAX < align) ? ATTRIBUTE_ALIGNED_MAX : align))) #else #define ATTR_ALIGN(align) #endif /* Export protected only for libxine functions */ #if defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_PROTECTED) # define XINE_PROTECTED __attribute__((__visibility__("protected"))) #elif defined(XINE_LIBRARY_COMPILE) && defined(SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT) # define XINE_PROTECTED __attribute__((__visibility__("default"))) #else # define XINE_PROTECTED #endif #ifdef SUPPORT_ATTRIBUTE_SENTINEL # define XINE_SENTINEL __attribute__((__sentinel__)) #else # define XINE_SENTINEL #endif #if defined(SUPPORT_ATTRIBUTE_DEPRECATED) && (!defined(XINE_COMPILE) || defined(DEBUG)) # define XINE_DEPRECATED __attribute__((__deprecated__)) #else # define XINE_DEPRECATED #endif #if defined(SUPPORT_ATTRIBUTE_DEPRECATED) && (!defined(XINE_LIBRARY_COMPILE)) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 )) # define XINE_PRIVATE_FIELD __attribute__((__deprecated__("this is xine-engine private field"))) #elif defined(SUPPORT_ATTRIBUTE_DEPRECATED) && (!defined(XINE_LIBRARY_COMPILE)) # define XINE_PRIVATE_FIELD __attribute__((__deprecated__)) #else # define XINE_PRIVATE_FIELD #endif #ifdef SUPPORT_ATTRIBUTE_WEAK # define XINE_WEAK __attribute__((weak)) #else # define XINE_WEAK #endif #ifndef __attr_unused # ifdef SUPPORT_ATTRIBUTE_UNUSED # define __attr_unused __attribute__((__unused__)) # else # define __attr_unused # endif #endif /* Format attributes */ #ifdef SUPPORT_ATTRIBUTE_FORMAT # if defined(__MINGW32__) # if defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO # ifndef __MINGW_PRINTF_FORMAT # define __MINGW_PRINTF_FORMAT gnu_printf # endif # endif # ifndef __MINGW_PRINTF_FORMAT # define __MINGW_PRINTF_FORMAT __printf__ # endif # define XINE_FORMAT_PRINTF(fmt,var) __attribute__((__format__(__MINGW_PRINTF_FORMAT, fmt, var))) # else # define XINE_FORMAT_PRINTF(fmt,var) __attribute__((__format__(__printf__, fmt, var))) # endif # define XINE_FORMAT_SCANF(fmt,var) __attribute__((__format__(__scanf__, fmt, var))) #else # define XINE_FORMAT_PRINTF(fmt,var) # define XINE_FORMAT_SCANF(fmt,var) #endif #ifdef SUPPORT_ATTRIBUTE_FORMAT_ARG # define XINE_FORMAT_PRINTF_ARG(fmt) __attribute__((__format_arg__(fmt))) #else # define XINE_FORMAT_PRINTF_ARG(fmt) #endif #ifdef SUPPORT_ATTRIBUTE_MALLOC # define XINE_MALLOC __attribute__((__malloc__)) #else # define XINE_MALLOC #endif #ifdef SUPPORT_ATTRIBUTE_PACKED # define XINE_PACKED __attribute__((__packed__)) #else # define XINE_PACKED #endif #ifdef SUPPORT_ATTRIBUTE_CONST # define XINE_CONST __attribute__((__const__)) #else # define XINE_CONST #endif #endif /* ATTRIBUTE_H_ */ xine-lib-1.2/include/xine/broadcaster.h0000644000175000017500000000236214647725152015717 0ustar meme/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * broadcaster.h */ #ifndef HAVE_BROADCASTER_H #define HAVE_BROADCASTER_H #ifdef __cplusplus extern "C" { #endif #include typedef struct broadcaster_s broadcaster_t; broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) XINE_MALLOC XINE_PROTECTED; void _x_close_broadcaster(broadcaster_t *this_gen) XINE_PROTECTED; int _x_get_broadcaster_port(broadcaster_t *this_gen) XINE_PROTECTED; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/post.h0000644000175000017500000003713314647725152014417 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * post plugin definitions */ #ifndef XINE_POST_H #define XINE_POST_H #include #include #include #include #include #include #include struct plugin_node_s; #define POST_PLUGIN_IFACE_VERSION 10 typedef struct post_class_s post_class_t; typedef struct post_plugin_s post_plugin_t; typedef struct post_in_s post_in_t; typedef struct post_out_s post_out_t; struct post_class_s { /* * open a new instance of this plugin class */ post_plugin_t* (*open_plugin) (post_class_t *this_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * free all class-related resources */ void (*dispose) (post_class_t *this_gen); }; #define default_post_class_dispose (void (*) (post_class_t *this_gen))free struct post_plugin_s { /* public part of the plugin */ xine_post_t xine_post; /* * the connections announced by the plugin * the plugin must fill these with xine_post_{in,out}_t on init */ xine_list_t *input; xine_list_t *output; /* * close down, free all resources */ void (*dispose) (post_plugin_t *this_gen); /* plugins don't have to init the stuff below */ /* * the running ticket * * the plugin must assure to check for ticket revocation in * intervals of finite length; this means that you must release * the ticket before any operation that might block; * note that all port functions are safe in this respect * * the running ticket is assigned to you by the engine */ xine_ticket_t *running_ticket; /* this is needed by the engine to decrement the reference counter * on disposal of the plugin, but since this is useful, we expose it */ xine_t *xine; /* used when the user requests a list of all inputs/outputs */ const char **input_ids; const char **output_ids; /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; /* has dispose been called */ int dispose_pending; }; /* helper function to initialize a post_plugin_t */ void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) XINE_PROTECTED; struct post_in_s { /* public part of the input */ xine_post_in_t xine_in; /* backward reference so that you have access to the post plugin */ post_plugin_t *post; /* you can fill this to your liking */ void *user_data; }; struct post_out_s { /* public part of the output */ xine_post_out_t xine_out; /* backward reference so that you have access to the post plugin */ post_plugin_t *post; /* you can fill this to your liking */ void *user_data; }; /* Post plugins work by intercepting calls to video or audio ports * in the sense of the decorator design pattern. They reuse the * functions of a given target port, but add own functionality in * front of that port by creating a new port structure and filling in * the function pointers with pointers to own functions that * would do something and then call the original port function. * * Much the same is done with video frames which have their own * set of functions attached that you might need to decorate. */ /* helper structure for intercepting video port calls */ typedef struct post_video_port_s post_video_port_t; struct post_video_port_s { /* the new public port with replaced function pointers */ xine_video_port_t new_port; /* the original port to call its functions from inside yours */ xine_video_port_t *original_port; /* if you want to decide yourself, whether a given frame should * be intercepted, fill in this function; get_frame() acts as * a template method and asks your function; return a boolean; * the default is to intercept all frames */ int (*intercept_frame)(post_video_port_t *self, vo_frame_t *frame); /* the new frame function pointers */ vo_frame_t *new_frame; /* if you want to decide yourself, whether the preprocessing functions * should still be routed when draw is intercepted, fill in this * function; _x_post_intercept_video_frame() acts as a template method * and asks your function; return a boolean; the default is _not_ to * route preprocessing functions when draw is intercepted */ int (*route_preprocessing_procs)(post_video_port_t *self, vo_frame_t *frame); /* if you want to decide yourself, whether the overlay manager should * be intercepted, fill in this function; get_overlay_manager() acts as * a template method and asks your function; return a boolean; * the default is _not_ to intercept the overlay manager */ int (*intercept_ovl)(post_video_port_t *self); /* the new public overlay manager with replaced function pointers */ video_overlay_manager_t *new_manager; /* the original manager to call its functions from inside yours */ video_overlay_manager_t *original_manager; /* usage counter: how many objects are floating around that need * these pointers to exist */ int usage_count; pthread_mutex_t usage_lock; /* the stream we are being fed by; NULL means no stream is connected; * this may be an anonymous stream */ xine_stream_t *stream; /* point to a mutex here, if you need some synchronization */ pthread_mutex_t *port_lock; pthread_mutex_t *frame_lock; pthread_mutex_t *manager_lock; /* backward reference so that you have access to the post plugin * when the call only gives you the port */ post_plugin_t *post; /* you can fill this to your liking */ void *user_data; #ifdef POST_INTERNAL /* some of the above members are to be directly included here, but * adding the structures would mean that post_video_port_t becomes * depended of the sizes of these structs; solution: we add pointers * above and have them point into the memory provided here; * note that the overlay manager needs to be first so that we can * reconstruct the post_video_port_t* from overlay manager calls */ /* any change here requires a change in _x_post_ovl_manager_to_port() * below! */ video_overlay_manager_t manager_storage; vo_frame_t frame_storage; /* this is used to keep a linked list of free vo_frame_t's */ vo_frame_t *free_frame_slots; pthread_mutex_t free_frames_lock; #endif }; /* use this to create a new decorated video port in which * port functions will be replaced with own implementations; * for convenience, this can also create a related post_in_t and post_out_t */ post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_port_t *port, post_in_t **input, post_out_t **output) XINE_PROTECTED; /* use this to decorate and to undecorate a frame so that its functions * can be replaced with own implementations, decoration is usually done in * get_frame(), undecoration in frame->free() */ vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port) XINE_PROTECTED; vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port) XINE_PROTECTED; /* when you want to pass a frame call on to the original issuer of the frame, * you need to propagate potential changes up and down the pipe, so the usual * procedure for this situation would be: * * _x_post_frame_copy_down(frame, frame->next); * frame->next->function(frame->next); * _x_post_frame_copy_up(frame, frame->next); */ void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) XINE_PROTECTED; void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) XINE_PROTECTED; /* when you shortcut a frames usual draw() travel so that it will never reach * the draw() function of the original issuer, you still have to do some * housekeeping on the frame, before returning control up the pipe */ void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream) XINE_PROTECTED; /* use this to create a new, trivially decorated overlay manager in which * port functions can be replaced with own implementations */ void _x_post_intercept_overlay_manager(video_overlay_manager_t *manager, post_video_port_t *port) XINE_PROTECTED; /* pointer retrieval functions */ static inline post_video_port_t *_x_post_video_frame_to_port(vo_frame_t *frame) { return (post_video_port_t *)frame->port; } static inline post_video_port_t *_x_post_ovl_manager_to_port(video_overlay_manager_t *manager) { /* NOTE: assuming that manager really is a post_video_port->manager_storage. * Furthermore, try to avoid cast-align warnings. */ post_video_port_t *res; uint32_t n; #ifdef POST_INTERNAL post_video_port_t *dummy = (post_video_port_t *)0; n = (uintptr_t)(&dummy->manager_storage); #else n = sizeof (post_video_port_t); #endif n /= sizeof (void *); res = (post_video_port_t *)((void **)manager - n); return res->new_manager == manager ? res : NULL; } /* helper structure for intercepting audio port calls */ typedef struct post_audio_port_s post_audio_port_t; struct post_audio_port_s { /* the new public port with replaced function pointers */ xine_audio_port_t new_port; /* the original port to call its functions from inside yours */ xine_audio_port_t *original_port; /* the stream we are being fed by; NULL means no stream is connected; * this may be an anonymous stream */ xine_stream_t *stream; pthread_mutex_t usage_lock; /* usage counter: how many objects are floating around that need * these pointers to exist */ int usage_count; /* some values remembered by (port->open) () */ uint32_t bits; uint32_t rate; uint32_t mode; /* point to a mutex here, if you need some synchronization */ pthread_mutex_t *port_lock; /* backward reference so that you have access to the post plugin * when the call only gives you the port */ post_plugin_t *post; /* you can fill this to your liking */ void *user_data; }; /* use this to create a new decorated audio port in which * port functions will be replaced with own implementations */ post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_port_t *port, post_in_t **input, post_out_t **output) XINE_PROTECTED; /* If you do intercept these decoder-called functions * (that is, you do not use post defaults), please * open (): * _x_post_inc_usage (port); * _x_post_rewire (port->post); * ... * close (): * ... * _x_post_dec_usage (port); * get_buffer (): * _x_post_inc_usage (port); * ... * port->original_port->get_buffer (port->original_port); and/or * while (not_done_yet) { * _x_post_rewire (port->post); * timed_wait (done); * } * ... * _x_post_dec_usage (port); * get_frame (): * _x_post_inc_usage (port); * ... * port->original_port->get_frame (port->original_port, ...); and/or * while (not_done_yet) { * _x_post_rewire (port->post); * timed_wait (done); * } * ... * if (this_frame_is_not_intercepted) * _x_post_dec_usage (port); * frame.free (): * ... * _x_post_dec_usage (port); * this will allow pending rewire operations, while preventing your port from getting * pulled from under your feet by the possible rewire. */ static inline void _x_post_rewire(post_plugin_t *post) { if (post->running_ticket->ticket_revoked) post->running_ticket->renew(post->running_ticket, 1); } /* with these functions you can switch interruptions like rewiring or engine pausing * off for a block of code; use this only when really necessary */ static inline void _x_post_lock(post_plugin_t *post) { post->running_ticket->acquire(post->running_ticket, 1); } static inline void _x_post_unlock(post_plugin_t *post) { post->running_ticket->release(post->running_ticket, 1); _x_post_rewire(post); } /* the standard disposal operation; returns 1 if the plugin is really * disposed and you should free everything you malloc()ed yourself */ int _x_post_dispose(post_plugin_t *post) XINE_PROTECTED; /* macros to handle usage counter */ /* WARNING! * note that _x_post_dec_usage() can call dispose, so be sure to * not use any potentially already freed memory after this */ #define _x_post_inc_usage(port) \ do { \ pthread_mutex_lock(&(port)->usage_lock); \ (port)->usage_count++; \ pthread_mutex_unlock(&(port)->usage_lock); \ } while(0) #define _x_post_dec_usage(port) \ do { \ pthread_mutex_lock(&(port)->usage_lock); \ (port)->usage_count--; \ if ((port)->usage_count == 0) { \ if ((port)->post->dispose_pending) { \ pthread_mutex_unlock(&(port)->usage_lock); \ (port)->post->dispose((port)->post); \ } else \ pthread_mutex_unlock(&(port)->usage_lock); \ } else \ pthread_mutex_unlock(&(port)->usage_lock); \ } while(0) #ifdef POST_INTERNAL /* try to recognize post ports, do the above, return new use count. * otherwise, return -1. */ int _x_post_video_port_ref (xine_video_port_t *port_gen); int _x_post_video_port_unref (xine_video_port_t *port_gen); int _x_post_audio_port_ref (xine_audio_port_t *port_gen); int _x_post_audio_port_unref (xine_audio_port_t *port_gen); #endif /* macros to create parameter descriptors */ #define START_PARAM_DESCR( param_t ) \ typedef param_t temp_t; \ static xine_post_api_parameter_t temp_p[] = { #ifndef offsetof #include #endif #define PARAM_ITEM( param_type, var, enumv, min, max, readonly, descr ) \ { param_type, #var, sizeof(((temp_t*)0)->var), \ offsetof(temp_t, var), enumv, min, max, readonly, descr }, #define END_PARAM_DESCR( name ) \ { POST_PARAM_TYPE_LAST, NULL, 0, 0, NULL, 0, 0, 1, NULL } \ }; \ static xine_post_api_descr_t name = { \ sizeof( temp_t ), \ temp_p \ }; #endif xine-lib-1.2/include/xine/os_types.h0000644000175000017500000000626514647725152015301 0ustar meme/* * Copyright (C) 2004-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Platform dependent types needed by public xine.h. * Types not needed by xine.h are specified in os_internal.h. * * Heavily based on os_types.h from OggVorbis (BSD License), * not tested on all platforms with xine. */ #ifndef XINE_OS_TYPES_H #define XINE_OS_TYPES_H #if defined(_WIN32) && !defined(__GNUC__) /* MSVC/Borland */ typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; typedef __int32 intptr_t; typedef unsigned __int32 uintptr_t; #elif defined(__MACOS__) # include typedef SInt8 int8_t; typedef UInt8 uint8_t; typedef SInt16 int16_t; typedef UInt16 uint16_t; typedef SInt32 int32_t; typedef UInt32 uint32_t; typedef SInt64 int64_t; typedef UInt64 uint64_t; typedef SInt32 intptr_t; typedef UInt32 uintptr_t; #elif defined(__MACOSX__) /* MacOS X Framework build */ # include typedef u_int8_t uint8_t; typedef u_int16_t uint16_t; typedef u_int32_t uint32_t; typedef u_int64_t uint64_t; #elif defined (__EMX__) /* OS/2 GCC */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef int int32_t; typedef unsigned int uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; typedef long intptr_t; typedef unsigned long uintptr_t; #elif defined (DJGPP) /* DJGPP */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef int int32_t; typedef unsigned int uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; typedef long intptr_t; typedef unsigned long uintptr_t; #elif defined(R5900) /* PS2 EE */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short int16_t; typedef int int32_t; typedef unsigned uint32_t; typedef long int64_t; typedef unsigned long uint64_t; /* FIXME: 32bit? */ typedef long intptr_t; typedef unsigned long uintptr_t; #else /* * CygWin: _WIN32 & __GNUC__ * BeOS: __BEOS__ * Linux, Solaris, Mac and others */ # include #endif #endif /* XINE_OS_TYPES_H */ xine-lib-1.2/include/xine/xmllexer.h0000644000175000017500000000517414647725152015272 0ustar meme/* * Copyright (C) 2002-2018 the xine project * * This file is part of xine, a free video player. * * The xine-lib XML parser is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The xine-lib XML parser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110, USA */ /* xml lexer */ #ifndef XML_LEXER_H #define XML_LEXER_H #include /* public constants */ #define T_ERROR -1 /* lexer error */ #define T_EOF 0 /* end of file */ #define T_EOL 1 /* end of line */ #define T_SEPAR 2 /* separator ' ' '/t' '\n' '\r' */ #define T_M_START_1 3 /* markup start < */ #define T_M_START_2 4 /* markup start */ #define T_M_STOP_2 6 /* markup stop /> */ #define T_EQUAL 7 /* = */ #define T_QUOTE 8 /* \" or \' */ #define T_STRING 9 /* "string" */ #define T_IDENT 10 /* identifier */ #define T_DATA 11 /* data */ #define T_C_START 12 /* */ #define T_TI_START 14 /* */ #define T_DOCTYPE_START 16 /* */ #define T_CDATA_START 18 /* */ /* public structure */ struct lexer { const char * lexbuf; int lexbuf_size; int lexbuf_pos; int lex_mode; int in_comment; char *lex_malloc; }; /* public functions */ void lexer_init(const char * buf, int size) XINE_DEPRECATED XINE_PROTECTED; struct lexer *lexer_init_r(const char * buf, int size) XINE_PROTECTED; void lexer_finalize_r(struct lexer * lexer) XINE_PROTECTED; int lexer_get_token_d_r(struct lexer * lexer, char ** tok, int * tok_size, int fixed) XINE_PROTECTED; int lexer_get_token_d(char ** tok, int * tok_size, int fixed) XINE_DEPRECATED XINE_PROTECTED; int lexer_get_token(char * tok, int tok_size) XINE_DEPRECATED XINE_PROTECTED; char *lexer_decode_entities (const char *tok) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/vdr.h0000644000175000017500000002523614647725152014226 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef __VDR_H #define __VDR_H #define XINE_VDR_VERSION 901 #include enum funcs { func_unknown = -1 , func_nop , func_osd_new , func_osd_free , func_osd_show , func_osd_hide , func_osd_set_position , func_osd_draw_bitmap , func_set_color , func_clear , func_mute , func_set_volume , func_set_speed , func_set_prebuffer , func_metronom , func_start , func_wait , func_setup , func_grab_image , func_get_pts , func_flush , func_first_frame , func_still_frame , func_video_size , func_set_video_window , func_osd_flush , func_play_external , func_key , func_frame_size , func_reset_audio , func_select_audio , func_trick_speed_mode , func_get_version , func_discontinuity , func_query_capabilities }; enum keys { key_none, key_up, key_down, key_menu, key_ok, key_back, key_left, key_right, key_red, key_green, key_yellow, key_blue, key_0, key_1, key_2, key_3, key_4, key_5, key_6, key_7, key_8, key_9, key_play, key_pause, key_stop, key_record, key_fast_fwd, key_fast_rew, key_power, key_channel_plus, key_channel_minus, key_volume_plus, key_volume_minus, key_mute, key_schedule, key_channels, key_timers, key_recordings, key_setup, key_commands, key_user1, key_user2, key_user3, key_user4, key_user5, key_user6, key_user7, key_user8, key_user9, key_audio, key_info, key_channel_previous, key_next, key_previous, key_subtitles, key_user0, }; typedef struct __attribute__((packed)) data_header_s { uint32_t func:8; uint32_t len:24; } data_header_t; typedef data_header_t result_header_t; typedef data_header_t event_header_t; typedef struct __attribute__((packed)) data_nop_s { data_header_t header; } data_nop_t; typedef struct __attribute__((packed)) data_osd_new_s { data_header_t header; uint8_t window; int16_t x; int16_t y; uint16_t width; uint16_t height; uint16_t w_ref; uint16_t h_ref; } data_osd_new_t; typedef struct __attribute__((packed)) data_osd_free_s { data_header_t header; uint8_t window; } data_osd_free_t; typedef struct __attribute__((packed)) data_osd_show_s { data_header_t header; uint8_t window; } data_osd_show_t; typedef struct __attribute__((packed)) data_osd_hide_s { data_header_t header; uint8_t window; } data_osd_hide_t; typedef struct __attribute__((packed)) data_osd_flush_s { data_header_t header; } data_osd_flush_t; typedef struct __attribute__((packed)) data_play_external_s { data_header_t header; } data_play_external_t; typedef struct __attribute__((packed)) data_osd_set_position_s { data_header_t header; uint8_t window; int16_t x; int16_t y; } data_osd_set_position_t; typedef struct __attribute__((packed)) data_osd_draw_bitmap_s { data_header_t header; uint8_t window; int16_t x; int16_t y; uint16_t width; uint16_t height; uint8_t argb; } data_osd_draw_bitmap_t; typedef struct __attribute__((packed)) data_set_color_s { data_header_t header; uint8_t window; uint8_t index; uint8_t num; } data_set_color_t; typedef struct __attribute__((packed)) data_flush_s { data_header_t header; int32_t ms_timeout; uint8_t just_wait; } data_flush_t; typedef struct __attribute__((packed)) result_flush_s { result_header_t header; uint8_t timed_out; } result_flush_t; typedef struct __attribute__((packed)) data_clear_s { data_header_t header; int32_t n; int8_t s; uint8_t i; } data_clear_t; typedef struct __attribute__((packed)) data_mute_s { data_header_t header; uint8_t mute; } data_mute_t; typedef struct __attribute__((packed)) data_set_volume_s { data_header_t header; uint8_t volume; } data_set_volume_t; typedef struct __attribute__((packed)) data_set_speed_s { data_header_t header; int32_t speed; } data_set_speed_t; typedef struct __attribute__((packed)) data_set_prebuffer_s { data_header_t header; uint32_t prebuffer; } data_set_prebuffer_t; typedef struct __attribute__((packed)) data_metronom_s { data_header_t header; int64_t pts; uint32_t flags; } data_metronom_t; typedef struct __attribute__((packed)) data_start_s { data_header_t header; } data_start_t; typedef struct __attribute__((packed)) data_wait_s { data_header_t header; uint8_t id; } data_wait_t; typedef struct __attribute__((packed)) result_wait_s { result_header_t header; } result_wait_t; #define XINE_VDR_VOLUME_IGNORE 0 #define XINE_VDR_VOLUME_CHANGE_HW 1 #define XINE_VDR_VOLUME_CHANGE_SW 2 #define XINE_VDR_MUTE_IGNORE 0 #define XINE_VDR_MUTE_EXECUTE 1 #define XINE_VDR_MUTE_SIMULATE 2 typedef struct __attribute__((packed)) data_setup_s { data_header_t header; uint8_t osd_unscaled_blending; uint8_t volume_mode; uint8_t mute_mode; uint16_t image4_3_zoom_x; uint16_t image4_3_zoom_y; uint16_t image16_9_zoom_x; uint16_t image16_9_zoom_y; } data_setup_t; typedef struct __attribute__((packed)) data_first_frame_s { data_header_t header; } data_first_frame_t; typedef struct __attribute__((packed)) data_still_frame_s { data_header_t header; } data_still_frame_t; typedef struct __attribute__((packed)) data_set_video_window_s { data_header_t header; uint32_t x; uint32_t y; uint32_t w; uint32_t h; uint32_t w_ref; uint32_t h_ref; } data_set_video_window_t; typedef struct __attribute__((packed)) data_grab_image_s { data_header_t header; } data_grab_image_t; typedef struct __attribute__((packed)) result_grab_image_s { result_header_t header; int32_t width; int32_t height; int32_t ratio; int32_t format; int32_t interlaced; int32_t crop_left; int32_t crop_right; int32_t crop_top; int32_t crop_bottom; } result_grab_image_t; typedef struct __attribute__((packed)) data_get_pts_s { data_header_t header; int32_t ms_timeout; } data_get_pts_t; typedef struct __attribute__((packed)) result_get_pts_s { result_header_t header; int64_t pts; int8_t queued; } result_get_pts_t; typedef struct __attribute__((packed)) data_get_version_s { data_header_t header; } data_get_version_t; typedef struct __attribute__((packed)) result_get_version_s { result_header_t header; int32_t version; } result_get_version_t; typedef struct __attribute__((packed)) data_video_size_s { data_header_t header; } data_video_size_t; typedef struct __attribute__((packed)) result_video_size_s { result_header_t header; int32_t left; int32_t top; int32_t width; int32_t height; int32_t ratio; int32_t zoom_x; int32_t zoom_y; } result_video_size_t; typedef struct __attribute__((packed)) data_reset_audio_s { data_header_t header; } data_reset_audio_t; typedef struct __attribute__((packed)) event_key_s { event_header_t header; uint32_t key; } event_key_t; typedef struct __attribute__((packed)) event_frame_size_s { event_header_t header; int32_t left; int32_t top; int32_t width; int32_t height; int32_t zoom_x; int32_t zoom_y; } event_frame_size_t; typedef struct __attribute__((packed)) event_play_external_s { event_header_t header; uint32_t key; } event_play_external_t; typedef struct __attribute__((packed)) data_select_audio_s { data_header_t header; uint8_t channels; } data_select_audio_t; typedef struct __attribute__((packed)) data_trick_speed_mode_s { data_header_t header; uint8_t on; } data_trick_speed_mode_t; typedef struct __attribute__((packed)) event_discontinuity_s { event_header_t header; int32_t type; } event_discontinuity_t; typedef struct __attribute__((packed)) data_query_capabilities_s { data_header_t header; } data_query_capabilities_t; typedef struct __attribute__((packed)) result_query_capabilities_s { result_header_t header; uint8_t osd_max_num_windows; uint8_t osd_palette_max_depth; uint8_t osd_palette_is_shared; uint8_t osd_supports_argb_layer; uint8_t osd_supports_custom_extent; } result_query_capabilities_t; typedef union __attribute__((packed)) data_union_u { data_header_t header; data_nop_t nop; data_osd_new_t osd_new; data_osd_free_t osd_free; data_osd_show_t osd_show; data_osd_hide_t osd_hide; data_osd_set_position_t osd_set_position; data_osd_draw_bitmap_t osd_draw_bitmap; data_set_color_t set_color; data_flush_t flush; data_clear_t clear; data_mute_t mute; data_set_volume_t set_volume; data_set_speed_t set_speed; data_set_prebuffer_t set_prebuffer; data_metronom_t metronom; data_start_t start; data_wait_t wait; data_setup_t setup; data_grab_image_t grab_image; data_get_pts_t get_pts; data_first_frame_t first_frame; data_still_frame_t still_frame; data_video_size_t video_size; data_set_video_window_t set_video_window; data_osd_flush_t osd_flush; data_play_external_t play_external; data_reset_audio_t reset_audio; data_select_audio_t select_audio; data_trick_speed_mode_t trick_speed_mode; data_get_version_t get_version; data_query_capabilities_t query_capabilities; } data_union_t; typedef union __attribute__((packed)) result_union_u { result_header_t header; result_grab_image_t grab_image; result_get_pts_t get_pts; result_flush_t flush; result_video_size_t video_size; result_get_version_t get_version; result_wait_t wait; result_query_capabilities_t query_capabilities; } result_union_t; typedef union __attribute__((packed)) event_union_u { event_header_t header; event_key_t key; event_frame_size_t frame_size; event_play_external_t play_external; event_discontinuity_t discontinuity; } event_union_t; #endif /* __VDR_H */ xine-lib-1.2/include/xine/ring_buffer.h0000644000175000017500000000447114647725152015721 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Fifo + Ring Buffer */ #ifndef XINE_RING_BUFFER_H #define XINE_RING_BUFFER_H #include /* size_t */ #include typedef struct xine_ring_buffer_s xine_ring_buffer_t; /* Creates a new ring buffer */ xine_ring_buffer_t *xine_ring_buffer_new(size_t size) XINE_MALLOC XINE_PROTECTED; /* Deletes a ring buffer */ void xine_ring_buffer_delete(xine_ring_buffer_t *ring_buffer) XINE_PROTECTED; /* Returns a new chunk of the specified size */ /* Might block if the ring buffer is full */ void *xine_ring_buffer_alloc(xine_ring_buffer_t *ring_buffer, size_t size) XINE_PROTECTED; /* Put a chunk into the ring */ void xine_ring_buffer_put(xine_ring_buffer_t *ring_buffer, void *chunk) XINE_PROTECTED; /* Get a chunk of a specified size from the ring buffer * Might block if the ring buffer is empty * param size: the desired size * param rsize: the size of the chunk returned * rsize is not equal to size at the end of stream, the caller MUST check * rsize value. */ void *xine_ring_buffer_get(xine_ring_buffer_t *ring_buffer, size_t size, size_t *rsize) XINE_PROTECTED; /* Releases the chunk, makes memory available for the alloc function */ void xine_ring_buffer_release(xine_ring_buffer_t *ring_buffer, void *chunk) XINE_PROTECTED; /* Closes the ring buffer * The writer uses this function to signal the end of stream to the reader. * The reader MUST check the rsize value returned by the get function. */ void xine_ring_buffer_close(xine_ring_buffer_t *ring_buffer) XINE_PROTECTED; #endif /* XINE_RING_BUFFER_H */ xine-lib-1.2/include/xine/plugin_catalog.h0000644000175000017500000000451214647725152016415 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine-internal header: Definitions for plugin lists */ #ifndef _PLUGIN_CATALOG_H #define _PLUGIN_CATALOG_H #include #include #define DECODER_MAX 128 #define PLUGIN_MAX 256 /* the engine takes this many plugins for one stream type */ #define PLUGINS_PER_TYPE 10 typedef struct { char *filename; off_t filesize; time_t filemtime; void *lib_handle; int ref; /* count number of classes */ int no_unload; /* set if the file can't be unloaded */ } plugin_file_t ; typedef struct plugin_node_s { plugin_file_t *file; plugin_info_t *info; void *plugin_class; xine_list_t *config_entry_list; int ref; /* count intances of plugins */ int priority; } plugin_node_t ; struct plugin_catalog_s { xine_sarray_t *plugin_lists[PLUGIN_TYPE_MAX]; xine_sarray_t *cache_list; xine_list_t *file_list; plugin_node_t *audio_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; plugin_node_t *video_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; plugin_node_t *spu_decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]; const char *ids[PLUGIN_MAX]; /* memory block for the decoder priority config entry descriptions */ char *prio_desc[DECODER_MAX]; pthread_mutex_t lock; /* recursive mutex */ int plugin_count; int decoder_count; xine_sarray_t *modules_list; }; typedef struct plugin_catalog_s plugin_catalog_t; #endif xine-lib-1.2/include/xine/compat.h0000644000175000017500000000276614647725152014721 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef XINE_COMPAT_H #define XINE_COMPAT_H #include #ifdef __cplusplus extern "C" { #endif #if defined _MSC_VER #define __XINE_FUNCTION__ __FILE__ #elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L #define __XINE_FUNCTION__ __func__ #elif defined __GNUC__ #define __XINE_FUNCTION__ __FUNCTION__ #else #define __XINE_FUNCTION__ __func__ #endif #ifndef NAME_MAX #define XINE_NAME_MAX 256 #else #define XINE_NAME_MAX NAME_MAX #endif #ifndef PATH_MAX #define XINE_PATH_MAX 768 #else #define XINE_PATH_MAX PATH_MAX #endif #if !defined offsetof && defined __GNUC__ #define offsetof(type, member) __builtin_offsetof(type, member) #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/io_helper.h0000644000175000017500000001213614647725152015374 0ustar meme/* * Copyright (C) 2000-2021 the xine project, * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * abortable i/o helper functions */ #ifndef IO_HELPER_H #define IO_HELPER_H #include "xine_internal.h" /* select states */ #define XIO_READ_READY 1 #define XIO_WRITE_READY 2 /* xine select return codes */ #define XIO_READY 0 #define XIO_ERROR 1 #define XIO_ABORTED 2 #define XIO_TIMEOUT 3 /* * Waits for a file descriptor/socket to change status. * * network input plugins should use this function in order to * not freeze the engine. * * params : * stream needed for aborting and reporting errors but may be NULL * fd file/socket descriptor or -1 (just wait) * state XIO_READ_READY, XIO_WRITE_READY or 0 (just wait) * timeout_msec timeout in milliseconds * * Engine seek/stop can abort this function if stream != NULL. * * return value : * XIO_READY the file descriptor is ready for cmd * XIO_ERROR an i/o error occured * XIO_ABORTED command aborted by an other thread * XIO_TIMEOUT the file descriptor is not ready after timeout_msec milliseconds */ int _x_io_select (xine_stream_t *stream, int fd, int state, int timeout_msec) XINE_PROTECTED XINE_USED; /* * open a tcp connection * * params : * stream needed for reporting errors but may be NULL * host address of target * port port on target * * returns a socket descriptor or -1 if an error occured */ int _x_io_tcp_connect(xine_stream_t *stream, const char *host, int port) XINE_PROTECTED XINE_USED; /* connect and handshake. */ typedef enum { /* return success. */ XIO_HANDSHAKE_OK = 1, /* reopen same target, and try a different handshake (eg with/without tls). */ XIO_HANDSHAKE_TRY_SAME = 2, /* try next target, if any. */ XIO_HANDSHAKE_TRY_NEXT = 3, /* return failure (eg when handshake has hit a -1 EINTR). */ XIO_HANDSHAKE_INTR = 4 } xio_handshake_status_t; /* use _x_io_* () below. */ typedef xio_handshake_status_t (xio_handshake_cb_t)(void *userdata, int fd); /* like _x_io_tcp_connect (). */ int _x_io_tcp_handshake_connect (xine_stream_t *stream, const char *host, int port, xio_handshake_cb_t *handshake_cb, void *userdata) XINE_PROTECTED XINE_USED; /* * wait for finish connection * * params : * stream needed for aborting and reporting errors but may be NULL * fd socket descriptor * timeout_msec timeout in milliseconds * * return value: * XIO_READY host respond, the socket is ready for cmd * XIO_ERROR an i/o error occured * XIO_ABORTED command aborted by an other thread * XIO_TIMEOUT the file descriptor is not ready after timeout */ int _x_io_tcp_connect_finish(xine_stream_t *stream, int fd, int timeout_msec) XINE_PROTECTED XINE_USED; /* The next 5 read/write functions will try to transfer todo/min bytes unless * - the end of stream is reached (0), or * - no data is available for user network timeout seconds (-1 ETIMEDOUT), or * - an io error hits (-1 Exxx), or * - xine engine wants to seek/stop (-1 EINTR). * _x_io_tcp_part_read (stream, s, buf, 0, len) may also yield (-1 EAGAIN), and will never wait. * network input plugins should use these functions in order not to freeze the engine. * "off_t" is just there for historical reasons, "(s)size_t" should be enough. */ off_t _x_io_tcp_read (xine_stream_t *stream, int s, void *buf, off_t todo) XINE_PROTECTED XINE_USED; /* like _x_io_tcp_read () but: * 1. wait until we have at least min bytes, then * 2. return up to max bytes that are already there. */ ssize_t _x_io_tcp_part_read (xine_stream_t *stream, int s, void *buf, size_t min, size_t max) XINE_PROTECTED XINE_USED; off_t _x_io_tcp_write (xine_stream_t *stream, int s, const void *buf, off_t todo) XINE_PROTECTED XINE_USED; off_t _x_io_file_read (xine_stream_t *stream, int fd, void *buf, off_t todo) XINE_PROTECTED XINE_USED; off_t _x_io_file_write (xine_stream_t *stream, int fd, const void *buf, off_t todo) XINE_PROTECTED XINE_USED; /* XXX this is slow. * read a string from socket, return string length (same as strlen) * the string is always '\0' terminated but given buffer size is never exceeded * that is, _x_io_tcp_read_line(,,,X) <= (X-1) ; X > 0 */ int _x_io_tcp_read_line(xine_stream_t *stream, int sock, char *str, int size) XINE_PROTECTED XINE_USED; /* * Close socket */ int _x_io_tcp_close(xine_stream_t *stream, int fd) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/configfile.h0000644000175000017500000002014314647725152015530 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * config file management */ #ifndef HAVE_CONFIGFILE_H #define HAVE_CONFIGFILE_H #ifdef __cplusplus extern "C" { #endif #include #include #define CONFIG_FILE_VERSION 2 /** * config entries above this experience * level must never be changed from MRL */ #define XINE_CONFIG_SECURITY 30 typedef struct cfg_entry_s cfg_entry_t; typedef struct config_values_s config_values_t; struct cfg_entry_s { cfg_entry_t *next; config_values_t *config; char *key; int type; /** user experience level */ int exp_level; /** type unknown */ char *unknown_value; /** type string */ char *str_value; char *str_default; /** common to range, enum, num, bool: */ int num_value; int num_default; /** type range specific: */ int range_min; int range_max; /* also used for enum */ /** type enum specific: */ char **enum_values; /** help info for the user */ char *description; char *help; /** callback function and data for live changeable values */ xine_config_cb_t callback; void *callback_data; }; struct config_values_s { /* * register config values * * these functions return the current value of the * registered item, i.e. the default value if it was * not found in the config file or the current value * from the config file otherwise * NOTE: config entries registered during class init of * input, demux, decoder, or post plugins will _always_ * show up in the application - even if that plugin is * not currently loaded. * * NOTE on callbacks: * - callback shall be safe to run from _any_ thread. * There will be no 2 calls at the same time, though. * - callback shall be safe to call at any time between * entering register_foo (), and leaving unregister_foo (). * - There can be multiple callbacks for the same key. * They will run in no fixed order. * - if cb_data is a real pointer, make sure it points to * valid thread shared memory (malloc'ed or static). * Plain stack variables will not work, and may cause * strange malfunction. */ char* (*register_string) (config_values_t *self, const char *key, const char *def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data); char* (*register_filename) (config_values_t *self, const char *key, const char *def_value, int req_type, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data); int (*register_range) (config_values_t *self, const char *key, int def_value, int min, int max, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data); int (*register_enum) (config_values_t *self, const char *key, int def_value, char **values, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data); int (*register_num) (config_values_t *self, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data); int (*register_bool) (config_values_t *self, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data); /** not yet implemented */ void (*register_entry) (config_values_t *self, cfg_entry_t* entry); /** convenience function to update range, enum, num and bool values */ void (*update_num) (config_values_t *self, const char *key, int value); /** convenience function to update string values */ void (*update_string) (config_values_t *self, const char *key, const char *value); /** small utility function for enum handling */ int (*parse_enum) (const char *str, const char **values); /** * @brief lookup config entries * * remember to call the changed_cb if it exists * and you changed the value of this item */ cfg_entry_t* (*lookup_entry) (config_values_t *self, const char *key); /** * unregister _all_ entry callback functions for this key. * if there may be multiple callbacks on different cb_data, * consider using unregister_callbacks (self, NULL, NULL, my_data, sizeof (*my_data)) * before freeing each instance instead. this also eliminates the need * to unregister every key separately. */ void (*unregister_callback) (config_values_t *self, const char *key); /** * dispose of all config entries in memory */ void (*dispose) (config_values_t *self); /** * callback called when a new config entry is registered */ void (*set_new_entry_callback) (config_values_t *self, xine_config_cb_t new_entry_cb, void *cb_data); /** * unregister the callback */ void (*unset_new_entry_callback) (config_values_t *self); /** * serialize a config entry. * return a base64 null terminated string. */ char* (*get_serialized_entry) (config_values_t *self, const char *key); /** * deserialize a config entry. * value is a base 64 encoded string * return the key of the serialized entry */ char* (*register_serialized_entry) (config_values_t *self, const char *value); /** * config values are stored here: */ cfg_entry_t *first, *last, *cur; /** * new entry callback */ xine_config_cb_t new_entry_cb; void *new_entry_cbdata; /** * mutex for modification to the config */ pthread_mutex_t config_lock; /** * current config file's version number */ int current_version; /** * unregister multiple entry callback functions. * all 3 values need to match unless they are NULL. * if cb_data_size is not zero, data pointers within the range * (cb_data <= ptr < cb_data + cb_data_size) will match. * returns the count of unregistered functions. */ int (*unregister_callbacks) (config_values_t *self, const char *key, xine_config_cb_t changed_cb, void *cb_data, size_t cb_data_size); /** * Set this manually to enable logging. */ xine_t *xine; /** * MT-safe convenience function to lookup string values. * Returns copy of current value or NULL. * Returned string must be freed with config->free_string(). */ char * (*lookup_string)(config_values_t *, const char *key); void (*free_string)(config_values_t *, char **); /** convenience function to lookup numeric values */ int (*lookup_num)(config_values_t *, const char *key, int def_value); }; /** * @brief allocate and init a new xine config object * @internal */ config_values_t *_x_config_init (void); /** * @brief interpret stream_setup part of mrls for config value changes * @internal */ int _x_config_change_opt(config_values_t *config, const char *opt); /** deprecated in favour of config_values_t->unregister_callbacks (). */ void _x_config_unregister_cb_class_d (config_values_t *config, void *callback_data) XINE_PROTECTED; void _x_config_unregister_cb_class_p (config_values_t *config, xine_config_cb_t callback) XINE_PROTECTED; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/refcounter.h0000644000175000017500000000273714647725152015610 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_REFCOUNTER_H #define HAVE_REFCOUNTER_H #include #include typedef struct { pthread_mutex_t lock; void* object; /* referenced object */ void (*destructor)(void *); /* object destructor */ int count; } refcounter_t; typedef void (*refcounter_destructor)(void*); refcounter_t* _x_new_refcounter(void *object, refcounter_destructor destructor) XINE_PROTECTED; int _x_refcounter_inc(refcounter_t *refcounter) XINE_PROTECTED; int _x_refcounter_dec(refcounter_t *refcounter) XINE_PROTECTED; void _x_refcounter_dispose(refcounter_t *refcounter) XINE_PROTECTED; #endif /* HAVE_REFCOUNTER_H */ xine-lib-1.2/include/xine/sorted_array.h0000644000175000017500000001202514647725152016121 0ustar meme/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Sorted array which grows automatically when you add elements. * A binary search is used to find the position of a new element. * * Example: * Let's create de comparison method for integers: * * int int_comparator(void *a, void *b) { * if ((int)a < (int)b) { * return -1; * } else if ((int)a == (int)b) { * return 0; * } else { * return 1; * } * } * * Create a sorted array for integers: * xine_sarray_t *sarray = xine_sarray_new(10, int_comparator); * * Add elements: * xine_sarray_add(sarray, (void*)4); * xine_sarray_add(sarray, (void*)28); * xine_sarray_add(sarray, (void*)7); * * Find an element: * int pos = xine_sarray_binary_search(sarray, (void*)7); * if (pos >= 0) * FOUND * else * NOT FOUND * * Delete the array: * xine_sarray_delete(sarray); */ #ifndef XINE_SORTED_ARRAY_H #define XINE_SORTED_ARRAY_H #include /* size_t */ #include /* version */ #define XINE_SARRAY 4 /* Array type */ typedef struct xine_sarray_s xine_sarray_t; /* Array element comparator */ typedef int (*xine_sarray_comparator_t) (void *item1, void *item2); /* Array element hash value */ typedef unsigned int (*xine_sarray_hash_func_t) (void *item); /* Constructor */ xine_sarray_t *xine_sarray_new(size_t initial_size, xine_sarray_comparator_t comparator) XINE_MALLOC XINE_PROTECTED; /* Destructor */ void xine_sarray_delete(xine_sarray_t *sarray) XINE_PROTECTED; /* XINE_SARRAY >= 3: add optional hash function that returns 0 ... (hash_size - 1). * Items will be sorted by ascending hash value first, then by comparator within the same hash value. * NOTE: hash_size is currently limited to 4096. */ void xine_sarray_set_hash (xine_sarray_t *sarray, xine_sarray_hash_func_t hash_func, unsigned int hash_size) XINE_PROTECTED; /* XINE_SARRAY >= 4: statistics helper for adjusing the hash function. * returns 0 (no hash set) ... 1000 (perfect). */ unsigned int xine_sarray_hash_quality (xine_sarray_t *sarray) XINE_PROTECTED; /* Set mode */ /* For both add() and binary_search(): if there are multiple matching indices, * select 1 of them randomly. That is, the order of matches does not matter, just be fast. */ #define XINE_SARRAY_MODE_DEFAULT 0x00000000 /* if present, select the first match, or add brfore that. */ #define XINE_SARRAY_MODE_FIRST 0x80000000 /* if present, select the last match, or add after that. */ #define XINE_SARRAY_MODE_LAST 0x40000000 /* For add(): if there is a match already, dont add another copy, * and return ~(found_index) instead. */ #define XINE_SARRAY_MODE_UNIQUE 0x20000000 void xine_sarray_set_mode (xine_sarray_t *sarray, unsigned int mode) XINE_PROTECTED; /* Returns the number of element stored in the array */ size_t xine_sarray_size(const xine_sarray_t *sarray) XINE_PROTECTED; /* Removes all elements from an array */ void xine_sarray_clear(xine_sarray_t *sarray) XINE_PROTECTED; /* Adds the element into the array Returns the insertion position */ int xine_sarray_add(xine_sarray_t *sarray, void *value) XINE_PROTECTED; /* Removes one element from an array at the position specified. * XINE_SARRAY >= 4: return the removed data ptr. */ void *xine_sarray_remove (xine_sarray_t *sarray, unsigned int position) XINE_PROTECTED; /* Removes one element from an array by user pointer. * Return the index it was found at, or ~0. */ int xine_sarray_remove_ptr (xine_sarray_t *sarray, void *ptr) XINE_PROTECTED; /* Get the element at the position specified */ void *xine_sarray_get(xine_sarray_t *sarray, unsigned int position) XINE_PROTECTED; /* Returns the index of the search key, if it is contained in the list. Otherwise, (-(insertion point) - 1) or ~(insertion point). The insertion point is defined as the point at which the key would be inserted into the array. */ int xine_sarray_binary_search(xine_sarray_t *sarray, void *key) XINE_PROTECTED; /* XINE_SARRAY >= 2: update the location of an existing entry, * eg from a stack dummy to a neqly allocted real object. * new_ptr == NULL does the same as xine_sarray_remove (). * WARNING: this does _not_ recheck the sort order. */ void xine_sarray_move_location (xine_sarray_t *sarray, void *new_ptr, unsigned int position) XINE_PROTECTED; #endif xine-lib-1.2/include/xine/tickets.h0000644000175000017500000001262714647725152015101 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_XINE_TICKETS_H #define HAVE_XINE_TICKETS_H #ifdef __cplusplus extern "C" { #endif /* * xine thread tickets. * This is similar to a rw lock in "prefer writers" mode. * - Shared recursive read lock: acquire () / release () * - Recursive write lock: revoke () / issue () * plus there are a few special hacks. * - Low overhead temporary read unlock: renew () * (better than release () + acquire ()). * Mutex less check ticket_revoked whether it is time to do so. * Yes this may delay writers a bit due to multicore data cache * sync issues (and your check interval, of course) but since * writing is rare we accept that. * Alternatively, register a revoke notify callback that stops * waiting for something else. * - Read lock with priority over writers: "irrevocable" * (use for known quick actions only). * - Top level uninterruptible write lock: "atomic". * Note that the write side is for engine internal use. * It now also supports turning an already held read into write * temporarily. */ typedef void xine_ticket_revoke_cb_t (void *user_data, int flags); typedef struct xine_ticket_s xine_ticket_t; struct xine_ticket_s { /* the ticket owner must assure to check for ticket revocation in * intervals of finite length; this means that you must release * the ticket before any operation that might block * * you must never write to this member directly */ int ticket_revoked; /* apply for a ticket; between acquire and relese of an irrevocable * ticket (be sure to pair them properly!), it is guaranteed that you * will never be blocked by ticket revocation */ void (*acquire)(xine_ticket_t *self, int irrevocable); /* give a ticket back */ void (*release)(xine_ticket_t *self, int irrevocable); /* renew a ticket, when it has been revoked, see ticket_revoked above; * irrevocable must be set to one, if your thread might have acquired * irrevocable tickets you don't know of; set it to zero only when * you know that this is impossible. */ void (*renew)(xine_ticket_t *self, int irrevocable); #ifdef XINE_ENGINE_INTERNAL /* XXX: port rewiring in the middle of a decoder loop iteration is a bad idea. * We could make that halfway safe by (un)referencing post ports consistently. * Unfortunately, post plugins intercept our calls at will. * Even worse, we ourselves told them to inline _x_post_rewire () then * still use the previous port :-/ * KLUDGE: * - We now have 2 levels of revocation, plain and rewire. * - If there is a pending rewire, ticket_revoked has the rewire flag set. * - A pending or incoming rewire revoke repels plain renewers, so they * can advance to a code location more suitable for a rewire, then * renew again with rewire flag set. * - Output layer get funcs return an emergency buffer/frame if engine is paused. * Why the f**k didnt we allow NULL there?? * - Decoder loops let the full thing go right before next iteration. */ #define XINE_TICKET_FLAG_ATOMIC 1 #define XINE_TICKET_FLAG_REWIRE 2 /* allow handing out new tickets. atomic needs to be same as below. */ void (*issue)(xine_ticket_t *self, int flags); /* revoke all tickets and deny new ones; * a pair of atomic revoke and issue cannot be interrupted by another * revocation or by other threads acquiring tickets. * set rewire flag to also do that lock. */ void (*revoke)(xine_ticket_t *self, int flags); /* behaves like acquire() but doesn't block the calling thread; when * the thread would have been blocked, 0 is returned otherwise 1 * this function acquires a ticket even if ticket revocation is active */ int (*acquire_nonblocking)(xine_ticket_t *self, int irrevocable); /* behaves like release() but doesn't block the calling thread; should * be used in combination with acquire_nonblocking() */ void (*release_nonblocking)(xine_ticket_t *self, int irrevocable); /* forbid port rewiring for critical code sections. */ int (*lock_port_rewiring)(xine_ticket_t *self, int ms_timeout); void (*unlock_port_rewiring)(xine_ticket_t *self); void (*dispose)(xine_ticket_t *self); /* (un)register a revoke notify callback, telling the current revoke flags. * Return from it does not * imply anything about the ticket itself, * it just shall shorten wait. * Note that unregister needs the same data pointer as well to * handle multiple instances of the same object. */ void (*revoke_cb_register) (xine_ticket_t *self, xine_ticket_revoke_cb_t *cb, void *user_data); void (*revoke_cb_unregister)(xine_ticket_t *self, xine_ticket_revoke_cb_t *cb, void *user_data); #endif }; #ifdef __cplusplus } #endif #endif xine-lib-1.2/include/xine/demux.h0000644000175000017500000001511714647725152014552 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_DEMUX_H #define HAVE_DEMUX_H #include #include #include #include struct plugin_node_s; #define DEMUXER_PLUGIN_IFACE_VERSION 27 #define DEMUX_OK 0 #define DEMUX_FINISHED 1 #define DEMUX_CANNOT_HANDLE 0 #define DEMUX_CAN_HANDLE 1 #define METHOD_BY_CONTENT 1 #define METHOD_BY_MRL 2 #define METHOD_EXPLICIT 3 typedef struct demux_class_s demux_class_t ; typedef struct demux_plugin_s demux_plugin_t; struct demux_class_s { /* * open a new instance of this plugin class */ demux_plugin_t* (*open_plugin) (demux_class_t *this_gen, xine_stream_t *stream, input_plugin_t *input); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /** * @brief MIME types supported for this plugin */ const char* mimetypes; /** * @brief space separated list of file extensions this demuxer is * likely to handle * * (will be used to filter media files in file selection dialogs) */ const char* extensions; /* * close down, free all resources */ void (*dispose) (demux_class_t *this_gen); }; #define default_demux_class_dispose (void (*) (demux_class_t *this_gen))free /* * any demux plugin must implement these functions */ struct demux_plugin_s { /* * send headers, followed by BUF_CONTROL_HEADERS_DONE down the * fifos, then return. do not start demux thread (yet) */ void (*send_headers) (demux_plugin_t *this_gen); /* * ask demux to seek * * for seekable streams, a start position can be specified * * start_pos : position in input source (0..65535) * this is defined as most convenient to demuxer, can be * either time or offset based. * start_time : position measured in miliseconds from stream start * playing : true if this is a new seek within an already playing stream * false if playback of this stream has not started yet * * if both parameters are !=0 start_pos will be used * for non-seekable streams both values will be ignored * * returns the demux status (like get_status, but immediately after * starting the demuxer) */ int (*seek) (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing ); /* * send a chunk of data down to decoder fifos * * the meaning of "chunk" is specific to every demux, usually * it involves parsing one unit of data from stream. * * this function will be called from demux loop and should return * the demux current status */ int (*send_chunk) (demux_plugin_t *this_gen); /* * free resources */ void (*dispose) (demux_plugin_t *this_gen) ; /* * returns DEMUX_OK or DEMUX_FINISHED */ int (*get_status) (demux_plugin_t *this_gen) ; /* * gets stream length in miliseconds (might be estimated) * may return 0 for non-seekable streams */ int (*get_stream_length) (demux_plugin_t *this_gen); /* * return capabilities of demuxed stream */ uint32_t (*get_capabilities) (demux_plugin_t *this_gen); /* * request optional data from input plugin. */ int (*get_optional_data) (demux_plugin_t *this_gen, void *data, int data_type); /* * "backwards" link to plugin class */ demux_class_t *demux_class; /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node XINE_PRIVATE_FIELD; }; #define default_demux_plugin_dispose (void (*) (demux_plugin_t *this_gen))free /* * possible capabilites a demux plugin can have: */ #define DEMUX_CAP_NOCAP 0x00000000 /* * DEMUX_CAP_AUDIOLANG: * DEMUX_CAP_SPULANG: * demux plugin knows something about audio/spu languages, * e.g. knows that audio stream #0 is english, * audio stream #1 is german, ... Same bits as INPUT * capabilities . */ #define DEMUX_CAP_AUDIOLANG 0x00000008 #define DEMUX_CAP_SPULANG 0x00000010 /* * DEMUX_CAP_CHAPTERS: * The media streams provided by this plugin have an internal * structure dividing it into segments usable for navigation. * For those plugins, the behaviour of the skip button in UIs * should be changed from "next MRL" to "next chapter" by * sending XINE_EVENT_INPUT_NEXT. * Same bits as INPUT capabilities. */ #define DEMUX_CAP_CHAPTERS 0x00000080 /* * DEMUX_CAP_STOP: * demux plugin needs to do some cleanup work _before_ end buffers * when the stream is stopped (eg flushing a pending discontinuity). * This shall be done by calling * demux_plugin->get_optional_data (demux_plugin, NULL, DEMUX_OPTIONAL_DATA_STOP). */ #define DEMUX_CAP_STOP 0x00000100 /* * DEMUX_CAP_VIDEO_TIME: * demux plugin has video, and it can tell its current video time in milliseconds. * It can do that especially after a seek by normpos and/or to nearest keyframe. * This shall be done by calling * demux_plugin->get_optional_data (demux_plugin, (int32_t *)(&msec), DEMUX_OPTIONAL_DATA_VIDEO_TIME). */ #define DEMUX_CAP_VIDEO_TIME 0x00000200 #define DEMUX_OPTIONAL_UNSUPPORTED 0 #define DEMUX_OPTIONAL_SUCCESS 1 #define DEMUX_OPTIONAL_DATA_AUDIOLANG 2 #define DEMUX_OPTIONAL_DATA_SPULANG 3 #define DEMUX_OPTIONAL_DATA_STOP 4 #define DEMUX_OPTIONAL_DATA_VIDEO_TIME 5 #endif xine-lib-1.2/include/xine/xine_module.h0000644000175000017500000000401414647725152015732 0ustar meme/* * Copyright (C) 2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef XINE_MODULE_H #define XINE_MODULE_H #define XINE_MODULE_IFACE_VERSION 1 typedef struct xine_module_class_s xine_module_class_t; typedef struct xine_module_s xine_module_t; struct xine_module_class_s { /* * create a new instance of this plugin class * - may return NULL */ xine_module_t *(*get_instance)(xine_module_class_t *, const void *params); /** * @brief short human readable identifier for this plugin class */ const char *identifier; /** * @brief human readable (verbose = 1 line) description for this plugin class * * The description is passed to gettext() to internationalise. */ const char *description; /** * @brief Optional non-standard catalog to use with dgettext() for description. */ const char *text_domain; /* * free all class-related resources * - optional, may be NULL */ void (*dispose)(xine_module_class_t *); }; struct xine_module_s { /** * @brief Pointer to the loaded plugin node. * * Used by the plugins loader. It's an opaque type when using the * structure outside of xine's build. */ struct plugin_node_s *node; /* * close down, free all resources */ void (*dispose)(xine_module_t *); }; #endif /* XINE_MODULE_H_ */ xine-lib-1.2/include/xine/scratch.h0000644000175000017500000000301614647725152015052 0ustar meme/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * scratch buffer for log output */ #ifndef HAVE_SCRATCH_H #define HAVE_SCRATCH_H #include #include #include typedef struct scratch_buffer_s scratch_buffer_t; #define SCRATCH_LINE_LEN_MAX 1024 struct scratch_buffer_s { void XINE_FORMAT_PRINTF(2, 0) (*scratch_printf) (scratch_buffer_t *this_gen, const char *format, va_list ap); char **(*get_content) (scratch_buffer_t *this_gen); void (*dispose) (scratch_buffer_t *this_gen); char **lines; char **ordered; int num_lines; int cur; pthread_mutex_t lock; }; scratch_buffer_t *_x_new_scratch_buffer (int num_lines) XINE_MALLOC XINE_PROTECTED; #endif xine-lib-1.2/include/.hgignore0000644000175000017500000000000714647725152014107 0ustar memexine.h xine-lib-1.2/include/config.h0000644000175000017500000000305014647725152013723 0ustar meme/* * Copyright (C) 2007-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public Licence as published by the Free * Software Foundation; either version 2 of the Licence, or (at your option) * any later version. * * xine is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public Licence for more * details. * * You should have received a copy of the GNU General Public Licence along * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * */ #include "configure.h" /* Ugly build time sanity guard. * ./configure might mistake X32 mode as plain 64bit, * but compiler itself sets __ILP32__ when in x32. * Even worse: clang sets this in 32 mode as well, * so also test __i386__ here. */ #ifdef ARCH_X86 # if defined(__ILP32__) && !defined(__i386) && !defined(__i386__) && !defined(ARCH_X86_X32) # ifdef ARCH_WARN # warning "configure did not detect ARCH_X86_X32!" # endif # undef ARCH_X86_64 # define ARCH_X86_X32 # undef ARCH_X86_32 # elif defined(ARCH_X86_64) && defined(ARCH_X86_X32) # ifdef ARCH_WARN # warning "configure did set both ARCH_X86_64 and ARCH_X86_X32!" # endif # undef ARCH_X86_64 # undef ARCH_X86_32 # endif #endif #include "os_internal.h" xine-lib-1.2/include/xine.h0000644000175000017500000026401714647725152013435 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * public xine-lib (libxine) interface and documentation * * * some programming guidelines about this api: * ------------------------------------------- * * (1) libxine has (per stream instance) a fairly static memory * model * (2) as a rule of thumb, never free() or realloc() any pointers * returned by the xine engine (unless stated otherwise) * or, in other words: * do not free() stuff you have not malloc()ed * (3) xine is multi-threaded, make sure your programming environment * can handle this. * for x11-related stuff this means that you either have to properly * use xlockdisplay() or use two seperate connections to the x-server * */ /*_x_ Lines formatted like this one are xine-lib developer comments. */ /*_x_ They will be removed from the installed version of this header. */ #ifndef HAVE_XINE_H #define HAVE_XINE_H #ifdef __cplusplus extern "C" { #endif #include #include #include #if defined(WIN32) && !defined(XINE_COMPILE) #include #endif #include #include #include /* This enables some experimental features. These are not part of the * official libxine API, so use them only, if you absolutely need them. * Although we make efforts to keep even this part of the API as stable * as possible, this is not guaranteed. Incompatible changes can occur. */ /* #define XINE_ENABLE_EXPERIMENTAL_FEATURES */ /* This disables some deprecated features. These are still part of the * official libxine API and you may still use them. During the current * major release series, these will always be available and will stay * compatible. However, removal is likely to occur as soon as possible. */ /* #define XINE_DISABLE_DEPRECATED_FEATURES */ /********************************************************************* * xine opaque data types * *********************************************************************/ typedef struct xine_s xine_t; typedef struct xine_stream_s xine_stream_t; typedef struct xine_audio_port_s xine_audio_port_t; typedef struct xine_video_port_s xine_video_port_t; /********************************************************************* * global engine handling * *********************************************************************/ /* * version information */ /* dynamic info from actually linked libxine */ const char *xine_get_version_string (void) XINE_PROTECTED; void xine_get_version (int *major, int *minor, int *sub) XINE_PROTECTED; /* compare given version to libxine version, return 1 if compatible, 0 otherwise */ int xine_check_version (int major, int minor, int sub) XINE_PROTECTED; /* * pre-init the xine engine * * will first malloc and init a xine_t, create an empty config * system, then scan through all installed plugins and add them * to an internal list for later use. * * to fully init the xine engine, you have to load config values * (either using your own storage method and calling * xine_config_register_entry, or by using the xine_load_config * utility function - see below) and then call xine_init * * the only proper way to shut down the xine engine is to * call xine_exit() - do not try to free() the xine pointer * yourself and do not try to access any internal data structures */ xine_t *xine_new (void) XINE_PROTECTED; /* allow the setting of some flags before xine_init * FIXME-ABI: this is currently GLOBAL */ void xine_set_flags (xine_t *, int) XINE_PROTECTED XINE_WEAK; #define XINE_FLAG_NO_WRITE_CACHE 1 /* * post_init the xine engine */ void xine_init (xine_t *self) XINE_PROTECTED; /* * helper functions to find and init audio/video drivers * from xine's plugin collection * * id : identifier of the driver, may be NULL for auto-detection * data : special data struct for ui/driver communications, depends * on driver * visual: video driver flavor selector, constants see below * * both functions may return NULL if driver failed to load, was not * found ... * * use xine_close_audio/video_driver() to close loaded drivers * and free resources allocated by them */ xine_audio_port_t *xine_open_audio_driver (xine_t *self, const char *id, const void *data) XINE_PROTECTED; xine_video_port_t *xine_open_video_driver (xine_t *self, const char *id, int visual, const void *data) XINE_PROTECTED; void xine_close_audio_driver (xine_t *self, xine_audio_port_t *driver) XINE_PROTECTED; void xine_close_video_driver (xine_t *self, xine_video_port_t *driver) XINE_PROTECTED; /* valid visual types */ #define XINE_VISUAL_TYPE_NONE 0 #define XINE_VISUAL_TYPE_X11 1 #define XINE_VISUAL_TYPE_X11_2 10 #define XINE_VISUAL_TYPE_AA 2 #define XINE_VISUAL_TYPE_FB 3 #define XINE_VISUAL_TYPE_GTK 4 #define XINE_VISUAL_TYPE_DFB 5 #define XINE_VISUAL_TYPE_PM 6 /* used by the OS/2 port */ #define XINE_VISUAL_TYPE_DIRECTX 7 /* used by the win32/msvc port */ #define XINE_VISUAL_TYPE_CACA 8 #define XINE_VISUAL_TYPE_MACOSX 9 #define XINE_VISUAL_TYPE_XCB 11 #define XINE_VISUAL_TYPE_RAW 12 #define XINE_VISUAL_TYPE_WAYLAND 13 /* * free all resources, close all plugins, close engine. * self pointer is no longer valid after this call. */ void xine_exit (xine_t *self) XINE_PROTECTED; /********************************************************************* * stream handling * *********************************************************************/ /* * create a new stream for media playback/access * * returns xine_stream_t* if OK, * NULL on error (use xine_get_error for details) * * the only proper way to free the stream pointer returned by this * function is to call xine_dispose() on it. do not try to access any * fields in xine_stream_t, they're all private and subject to change * without further notice. */ xine_stream_t *xine_stream_new (xine_t *self, xine_audio_port_t *ao, xine_video_port_t *vo) XINE_PROTECTED; /* * A side stream is like a side car on a bike. It has its own mrl, input, and demux. * Everything else is handled by the master (play, seek, pause, close, dispose). * This is intended for streams who have separate mrls for audio, video, and subtitle. * Index 0 just returns the master itself, 1 ... 3 are free for side mrls. */ #define XINE_SIDE_STREAMS 1 xine_stream_t *xine_get_side_stream (xine_stream_t *master, int index) XINE_PROTECTED; /* * Make one stream the slave of another. * This establishes a binary master slave relation on streams, where * certain operations (specified by parameter "affection") on the master * stream are also applied to the slave stream. * If you want more than one stream to react to one master, you have to * apply the calls in a top down way: * xine_stream_master_slave(stream1, stream2, 3); * xine_stream_master_slave(stream2, stream3, 3); * This will make stream1 affect stream2 and stream2 affect stream3, so * effectively, operations on stream1 propagate to stream2 and 3. * * Please note that subsequent master_slave calls on the same streams * will overwrite their previous master/slave setting. * Be sure to not mess around. * * returns 1 on success, 0 on failure */ int xine_stream_master_slave(xine_stream_t *master, xine_stream_t *slave, int affection) XINE_PROTECTED; /* affection is some of the following ORed together: */ /* playing the master plays the slave */ #define XINE_MASTER_SLAVE_PLAY (1<<0) /* slave stops on master stop */ #define XINE_MASTER_SLAVE_STOP (1<<1) /* slave is synced to master's speed */ #define XINE_MASTER_SLAVE_SPEED (1<<2) /* * open a stream * * look for input / demux / decoder plugins, find out about the format * see if it is supported, set up internal buffers and threads * * returns 1 if OK, 0 on error (use xine_get_error for details) */ int xine_open (xine_stream_t *stream, const char *mrl) XINE_PROTECTED; /** The keyframe seek index feature. */ #define XINE_KEYFRAMES 1 /**<< Check this for feature available. */ typedef struct { int msecs; /**<< Milliseconds from beginning of stream. */ int normpos; /**<< Size based stream position (beginning == 0, end == 64k - 1). */ } xine_keyframes_entry_t; /** @brief Query stream keyframe seek index. @note We dont do an expensive file scan. We will only find keyframes listed in container or already seen while playing. @param stream The stream that index is for. @param pos On call, the start time or normpos. On return, the found time and normpos. @param offs 0 gets nearest keyframe, other values step from exact given pos. @return 0: Found. 1: Search truncated to first or last known keyframe. 2: Failure. */ int xine_keyframes_find (xine_stream_t *stream, xine_keyframes_entry_t *pos, int offs) XINE_PROTECTED; /** @brief Get a private stream keyframe seek index copy, free () it when done. @param stream The stream that index is for. @param size On return, the count of entries there are. @return The entry array or NULL. */ xine_keyframes_entry_t *xine_keyframes_get (xine_stream_t *stream, int *size) XINE_PROTECTED; /* * play a stream from a given position * * start_pos: 0..65535 * start_time: milliseconds * if both start position parameters are != 0 start_pos will be used * for non-seekable streams both values will be ignored * * returns 1 if OK, 0 on error (use xine_get_error for details) */ int xine_play (xine_stream_t *stream, int start_pos, int start_time) XINE_PROTECTED; /* * stop stream playback * xine_stream_t stays valid for new xine_open or xine_play */ void xine_stop (xine_stream_t *stream) XINE_PROTECTED; /* * stop stream playback, free all stream-related resources * xine_stream_t stays valid for new xine_open */ void xine_close (xine_stream_t *stream) XINE_PROTECTED; /* * ask current/recent input plugin to eject media - may or may not work, * depending on input plugin capabilities */ int xine_eject (xine_stream_t *stream) XINE_PROTECTED; /* * stop playback, dispose all stream-related resources * xine_stream_t no longer valid when after this */ void xine_dispose (xine_stream_t *stream) XINE_PROTECTED; /* * set/get engine parameters. */ void xine_engine_set_param(xine_t *self, int param, int value) XINE_PROTECTED; int xine_engine_get_param(xine_t *self, int param) XINE_PROTECTED; #define XINE_ENGINE_PARAM_VERBOSITY 1 /* * set/get xine stream parameters * e.g. playback speed, constants see below */ void xine_set_param (xine_stream_t *stream, int param, int value) XINE_PROTECTED; int xine_get_param (xine_stream_t *stream, int param) XINE_PROTECTED; /* * xine stream parameters */ #define XINE_PARAM_SPEED 1 /* see below */ #define XINE_PARAM_AV_OFFSET 2 /* unit: 1/90000 sec */ #define XINE_PARAM_AUDIO_CHANNEL_LOGICAL 3 /* -1 => auto, -2 => off */ #define XINE_PARAM_SPU_CHANNEL 4 #define XINE_PARAM_VIDEO_CHANNEL 5 #define XINE_PARAM_AUDIO_VOLUME 6 /* 0..100 % of current audio out mixer range (eg alsa emu10k1 master: -46dB..0dB. */ #define XINE_PARAM_AUDIO_MUTE 7 /* 1=>mute, 0=>unmute */ #define XINE_PARAM_AUDIO_COMPR_LEVEL 8 /* <100=>off, % compress otherw*/ #define XINE_PARAM_AUDIO_AMP_LEVEL 9 /* 0..200, (val - 100) / 2 dB, 100 = default */ #define XINE_PARAM_AUDIO_REPORT_LEVEL 10 /* 1=>send events, 0=> don't */ #define XINE_PARAM_VERBOSITY 11 /* control console output */ #define XINE_PARAM_SPU_OFFSET 12 /* unit: 1/90000 sec */ #define XINE_PARAM_IGNORE_VIDEO 13 /* disable video decoding */ #define XINE_PARAM_IGNORE_AUDIO 14 /* disable audio decoding */ #define XINE_PARAM_IGNORE_SPU 15 /* disable spu decoding */ #define XINE_PARAM_BROADCASTER_PORT 16 /* 0: disable, x: server port */ #define XINE_PARAM_METRONOM_PREBUFFER 17 /* unit: 1/90000 sec */ #define XINE_PARAM_EQ_30HZ 18 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_60HZ 19 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_125HZ 20 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_250HZ 21 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_500HZ 22 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_1000HZ 23 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_2000HZ 24 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_4000HZ 25 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_8000HZ 26 /* equalizer gains -100..100 */ #define XINE_PARAM_EQ_16000HZ 27 /* equalizer gains -100..100 */ #define XINE_PARAM_AUDIO_CLOSE_DEVICE 28 /* force closing audio device */ #define XINE_PARAM_AUDIO_AMP_MUTE 29 /* 1=>mute, 0=>unmute */ #define XINE_PARAM_FINE_SPEED 30 /* 1.000.000 => normal speed */ #define XINE_PARAM_EARLY_FINISHED_EVENT 31 /* send event when demux finish*/ #define XINE_PARAM_GAPLESS_SWITCH 32 /* next stream only gapless swi*/ #define XINE_PARAM_DELAY_FINISHED_EVENT 33 /* 1/10sec,0=>disable,-1=>forev*/ /* * speed values for XINE_PARAM_SPEED parameter. * * alternatively, one may use XINE_PARAM_FINE_SPEED for greater * control of the speed value, where: * XINE_PARAM_SPEED / 4 <-> XINE_PARAM_FINE_SPEED / 1000000 */ #define XINE_SPEED_PAUSE 0 #define XINE_SPEED_SLOW_4 1 #define XINE_SPEED_SLOW_2 2 #define XINE_SPEED_NORMAL 4 #define XINE_SPEED_FAST_2 8 #define XINE_SPEED_FAST_4 16 /* normal speed value for XINE_PARAM_FINE_SPEED parameter */ #define XINE_FINE_SPEED_NORMAL 1000000 /* video parameters */ #define XINE_PARAM_VO_DEINTERLACE 0x01000000 /* bool */ #define XINE_PARAM_VO_ASPECT_RATIO 0x01000001 /* see below */ #define XINE_PARAM_VO_HUE 0x01000002 /* 0..65535 */ #define XINE_PARAM_VO_SATURATION 0x01000003 /* 0..65535 */ #define XINE_PARAM_VO_CONTRAST 0x01000004 /* 0..65535 */ #define XINE_PARAM_VO_BRIGHTNESS 0x01000005 /* 0..65535 */ #define XINE_PARAM_VO_GAMMA 0x0100000c /* 0..65535 */ #define XINE_PARAM_VO_ZOOM_X 0x01000008 /* percent */ #define XINE_PARAM_VO_ZOOM_Y 0x0100000d /* percent */ #define XINE_PARAM_VO_PAN_SCAN 0x01000009 /* bool */ #define XINE_PARAM_VO_TVMODE 0x0100000a /* ??? */ #define XINE_PARAM_VO_WINDOW_WIDTH 0x0100000f /* readonly */ #define XINE_PARAM_VO_WINDOW_HEIGHT 0x01000010 /* readonly */ #define XINE_PARAM_VO_SHARPNESS 0x01000018 /* 0..65535 */ #define XINE_PARAM_VO_NOISE_REDUCTION 0x01000019 /* 0..65535 */ #define XINE_PARAM_VO_TRANSFORM 0x0100001f /* see below */ #define XINE_PARAM_VO_CROP_LEFT 0x01000020 /* crop frame pixels */ #define XINE_PARAM_VO_CROP_RIGHT 0x01000021 /* crop frame pixels */ #define XINE_PARAM_VO_CROP_TOP 0x01000022 /* crop frame pixels */ #define XINE_PARAM_VO_CROP_BOTTOM 0x01000023 /* crop frame pixels */ #define XINE_PARAM_VO_SINGLE_STEP 0x01000024 /* 1 = "advance to next frame, then pause" */ #define XINE_VO_TRANSFORM_FLIP_H 0x00000001 #define XINE_VO_TRANSFORM_FLIP_V 0x00000002 #define XINE_VO_ZOOM_STEP 100 #define XINE_VO_ZOOM_MAX 400 #define XINE_VO_ZOOM_MIN -85 /* possible ratios for XINE_PARAM_VO_ASPECT_RATIO */ #define XINE_VO_ASPECT_AUTO 0 #define XINE_VO_ASPECT_SQUARE 1 /* 1:1 */ #define XINE_VO_ASPECT_4_3 2 /* 4:3 */ #define XINE_VO_ASPECT_ANAMORPHIC 3 /* 16:9 */ #define XINE_VO_ASPECT_DVB 4 /* 2.11:1 */ #define XINE_VO_ASPECT_NUM_RATIOS 5 #ifndef XINE_DISABLE_DEPRECATED_FEATURES #define XINE_VO_ASPECT_PAN_SCAN 41 #define XINE_VO_ASPECT_DONT_TOUCH 42 #endif /* stream format detection strategies */ /* recognize stream type first by content then by extension. */ #define XINE_DEMUX_DEFAULT_STRATEGY 0 /* recognize stream type first by extension then by content. */ #define XINE_DEMUX_REVERT_STRATEGY 1 /* recognize stream type by content only. */ #define XINE_DEMUX_CONTENT_STRATEGY 2 /* recognize stream type by extension only. */ #define XINE_DEMUX_EXTENSION_STRATEGY 3 /* verbosity settings */ #define XINE_VERBOSITY_NONE 0 #define XINE_VERBOSITY_LOG 1 #define XINE_VERBOSITY_DEBUG 2 /* * snapshot function * * image format can be YUV 4:2:0 or 4:2:2 * will copy the image data into memory that points to * (interleaved for yuv 4:2:2 or planary for 4:2:0) * * xine_get_current_frame() requires that must be able * to hold the image data. Use a NULL pointer to retrieve the * necessary parameters for calculating the buffer size. Be * aware that the image can change between two successive calls * so you better pause the stream. * * xine_get_current_frame_s() requires to specify the buffer * size and it returns the needed / used size. It won't copy * image data into a too small buffer. * * xine_get_current_frame_alloc() takes care of allocating * a buffer on its own, so image data can be retrieved by * a single call without the need to pause the stream. * * xine_get_current_frame_data() passes the parameters of the * previously mentioned functions plus further information in * a structure and can work like the _s or _alloc function * respectively depending on the passed flags. * * all functions return 1 on success, 0 failure. */ int xine_get_current_frame (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, uint8_t *img) XINE_PROTECTED XINE_DEPRECATED; int xine_get_current_frame_s (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, uint8_t *img, int *img_size) XINE_PROTECTED; int xine_get_current_frame_alloc (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, uint8_t **img, int *img_size) XINE_PROTECTED; typedef struct xine_current_frame_data_s xine_current_frame_data_t; struct xine_current_frame_data_s { int width; int height; int crop_left; int crop_right; int crop_top; int crop_bottom; int ratio_code; int interlaced; int format; int img_size; uint8_t *img; }; #define XINE_FRAME_DATA_ALLOCATE_IMG (1<<0) int xine_get_current_frame_data (xine_stream_t *stream, xine_current_frame_data_t *data, int flags) XINE_PROTECTED; /* xine image formats */ #define XINE_IMGFMT_YV12 (('2'<<24)|('1'<<16)|('V'<<8)|'Y') #define XINE_IMGFMT_NV12 (('2'<<24)|('1'<<16)|('V'<<8)|'N') #define XINE_IMGFMT_YUY2 (('2'<<24)|('Y'<<16)|('U'<<8)|'Y') #define XINE_IMGFMT_XVMC (('C'<<24)|('M'<<16)|('v'<<8)|'X') #define XINE_IMGFMT_XXMC (('C'<<24)|('M'<<16)|('x'<<8)|'X') #define XINE_IMGFMT_VDPAU (('A'<<24)|('P'<<16)|('D'<<8)|'V') #define XINE_IMGFMT_VAAPI (('P'<<24)|('A'<<16)|('A'<<8)|'V') #define XINE_IMGFMT_YV12_DEEP (('6'<<24)|('1'<<16)|('V'<<8)|'Y') /* Note: actual bit depth in frame flags */ /* get current xine's virtual presentation timestamp (1/90000 sec) * note: this is mostly internal data. * one can use vpts with xine_osd_show() and xine_osd_hide(). */ int64_t xine_get_current_vpts(xine_stream_t *stream) XINE_PROTECTED; /* * Continuous video frame grabbing feature. * * In opposite to the 'xine_get_current_frame' based snapshot function this grabbing * feature allow continuous grabbing of last or next displayed video frame. * Grabbed video frames are returned in simple three byte RGB format. * * Depending on the capabilities of the used video output driver video image data is * taken as close as possible at the end of the video processing chain. Thus a returned * video image could contain the blended OSD data, is deinterlaced, cropped and scaled * and video properties like hue, sat could be applied. * If a video output driver does not have a decent grabbing implementation then there * is a generic fallback feature that grabs the video frame as they are taken from the video * display queue (like the xine_get_current_frame' function). * In this case color correct conversation to a RGB image incorporating source cropping * and scaling to the requested grab size is also supported. * * The caller must first request a new video grab frame using the public 'xine_new_grab_video_frame' * function. Then the caller should populate the frame with the wanted source cropping, grab image * size and control flags. After that grab requests could be done by calling the supplied grab() feature * of the frame. At the end a call to the supplied dispose() feature of the frame releases all needed * resources. * The caller should have acquired a port ticket while calling these features. * */ #define HAVE_XINE_GRAB_VIDEO_FRAME 1 /* * frame structure used for grabbing video frames of format RGB. */ typedef struct xine_grab_video_frame_s xine_grab_video_frame_t; struct xine_grab_video_frame_s { /* * grab last/next displayed image. * returns 0 if grab is successful, 1 on timeout and -1 on error */ int (*grab) (xine_grab_video_frame_t *self); /* * free all resources. */ void (*dispose) (xine_grab_video_frame_t *self); /* * Cropping of source image. Has to be specified by caller. */ int crop_left; int crop_right; int crop_top; int crop_bottom; /* * Parameters of returned RGB image. * Caller can specify wanted frame size giving width and/or height a value > 0. * In this case the grabbed image is scaled to the requested size. * Otherwise the grab function returns the actual size of the grabbed image * in width/height without scaling the image. */ int width, height; /* requested/returned size of image */ uint8_t *img; /* returned RGB image data taking three bytes per pixel */ int64_t vpts; /* virtual presentation timestamp (1/90000 sec) of returned frame */ int timeout; /* Max. time to wait for next displayed frame in milliseconds */ int flags; /* Controlling flags. See XINE_GRAB_VIDEO_FRAME_FLAGS_* definitions */ }; #define XINE_GRAB_VIDEO_FRAME_FLAGS_CONTINUOUS 0x01 /* optimize resource allocation for continuous frame grabbing */ #define XINE_GRAB_VIDEO_FRAME_FLAGS_WAIT_NEXT 0x02 /* wait for next display frame instead of using last displayed frame */ #define XINE_GRAB_VIDEO_FRAME_DEFAULT_TIMEOUT 500 /* * Allocate new grab video frame. Returns NULL on error. */ xine_grab_video_frame_t* xine_new_grab_video_frame (xine_stream_t *stream) XINE_PROTECTED; /********************************************************************* * media processing * *********************************************************************/ #ifdef XINE_ENABLE_EXPERIMENTAL_FEATURES /* * access to decoded audio and video frames from a stream * these functions are intended to provide the basis for * re-encoding and other video processing applications * * note that the xine playback engine will block when * rendering to a framegrab port: to unblock the stream, * you must fetch the frames manually with the * xine_get_next_* functions. this ensures that a * framegrab port is guaranteed to never miss a frame. * */ xine_video_port_t *xine_new_framegrab_video_port (xine_t *self) XINE_PROTECTED; typedef struct { int64_t vpts; /* timestamp 1/90000 sec for a/v sync */ int64_t duration; double aspect_ratio; int width, height; int colorspace; /* XINE_IMGFMT_* */ int pos_stream; /* bytes from stream start */ int pos_time; /* milliseconds */ int frame_number; /* frame number (may be unknown) */ uint8_t *data; void *xine_frame; /* used internally by xine engine */ } xine_video_frame_t; int xine_get_next_video_frame (xine_video_port_t *port, xine_video_frame_t *frame) XINE_PROTECTED; void xine_free_video_frame (xine_video_port_t *port, xine_video_frame_t *frame) XINE_PROTECTED; xine_audio_port_t *xine_new_framegrab_audio_port (xine_t *self) XINE_PROTECTED; typedef struct { int64_t vpts; /* timestamp 1/90000 sec for a/v sync */ int num_samples; int sample_rate; int num_channels; int bits_per_sample; /* per channel */ uint8_t *data; void *xine_frame; /* used internally by xine engine */ off_t pos_stream; /* bytes from stream start */ int pos_time; /* milliseconds */ } xine_audio_frame_t; int xine_get_next_audio_frame (xine_audio_port_t *port, xine_audio_frame_t *frame) XINE_PROTECTED; void xine_free_audio_frame (xine_audio_port_t *port, xine_audio_frame_t *frame) XINE_PROTECTED; #endif /********************************************************************* * post plugin handling * *********************************************************************/ /* * post effect plugin functions * * after the data leaves the decoder it can pass an arbitrary tree * of post plugins allowing for effects to be applied to the video * frames/audio buffers before they reach the output stage */ typedef struct xine_post_s xine_post_t; struct xine_post_s { /* a NULL-terminated array of audio input ports this post plugin * provides; you can hand these to other post plugin's outputs or * pass them to the initialization of streams */ xine_audio_port_t **audio_input; /* a NULL-terminated array of video input ports this post plugin * provides; you can hand these to other post plugin's outputs or * pass them to the initialization of streams */ xine_video_port_t **video_input; /* the type of the post plugin * one of XINE_POST_TYPE_* can be used here */ int type; }; /* * initialize a post plugin * * returns xine_post_t* on success, NULL on failure * * Initializes the post plugin with the given name and connects its * outputs to the NULL-terminated arrays of audio and video ports. * Some plugins also care about the number of inputs you request * (e.g. mixer plugins), others simply ignore this number. */ xine_post_t *xine_post_init(xine_t *xine, const char *name, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) XINE_PROTECTED; /* get a list of all available post plugins */ const char *const *xine_list_post_plugins(xine_t *xine) XINE_PROTECTED; /* get a list of all post plugins of one type */ const char *const *xine_list_post_plugins_typed(xine_t *xine, uint32_t type) XINE_PROTECTED; /* * post plugin input/output * * These structures encapsulate inputs/outputs for post plugins * to transfer arbitrary data. Frontends can also provide inputs * and outputs and connect them to post plugins to exchange data * with them. */ typedef struct xine_post_in_s xine_post_in_t; typedef struct xine_post_out_s xine_post_out_t; struct xine_post_in_s { /* the name identifying this input */ const char *name; /* the data pointer; input is directed to this memory location, * so you simply access the pointer to access the input data */ void *data; /* the datatype of this input, use one of XINE_POST_DATA_* here */ int type; }; struct xine_post_out_s { /* the name identifying this output */ const char *name; /* the data pointer; output should be directed to this memory location, * so in the easy case you simply write through the pointer */ void *data; /* this function is called, when the output should be redirected * to another input, you sould set the data pointer to direct * any output to this new input; * a special situation is, when this function is called with a NULL * argument: in this case you should disconnect the data pointer * from any output and if necessary to avoid writing to some stray * memory you should make it point to some dummy location, * returns 1 on success, 0 on failure; * if you do not implement rewiring, set this to NULL */ int (*rewire) (xine_post_out_t *self, void *data); /* the datatype of this output, use one of XINE_POST_DATA_* here */ int type; }; /* get a list of all inputs of a post plugin */ const char *const *xine_post_list_inputs(xine_post_t *self) XINE_PROTECTED; /* get a list of all outputs of a post plugin */ const char *const *xine_post_list_outputs(xine_post_t *self) XINE_PROTECTED; /* retrieve one specific input of a post plugin */ xine_post_in_t *xine_post_input(xine_post_t *self, const char *name) XINE_PROTECTED; /* retrieve one specific output of a post plugin */ xine_post_out_t *xine_post_output(xine_post_t *self, const char *name) XINE_PROTECTED; /* * wire an input to an output * returns 1 on success, 0 on failure */ int xine_post_wire(xine_post_out_t *source, xine_post_in_t *target) XINE_PROTECTED; /* * wire a video port to a video output * This can be used to rewire different post plugins to the video output * plugin layer. The ports you hand in at xine_post_init() will already * be wired with the post plugin, so you need this function for * _re_connecting only. * * returns 1 on success, 0 on failure */ int xine_post_wire_video_port(xine_post_out_t *source, xine_video_port_t *vo) XINE_PROTECTED; /* * wire an audio port to an audio output * This can be used to rewire different post plugins to the audio output * plugin layer. The ports you hand in at xine_post_init() will already * be wired with the post plugin, so you need this function for * _re_connecting only. * * returns 1 on success, 0 on failure */ int xine_post_wire_audio_port(xine_post_out_t *source, xine_audio_port_t *ao) XINE_PROTECTED; /* * Extracts an output for a stream. Use this to rewire the outputs of streams. */ xine_post_out_t * xine_get_video_source(xine_stream_t *stream) XINE_PROTECTED; xine_post_out_t * xine_get_audio_source(xine_stream_t *stream) XINE_PROTECTED; /* * disposes the post plugin * please make sure that no other post plugin and no stream is * connected to any of this plugin's inputs */ void xine_post_dispose(xine_t *xine, xine_post_t *self) XINE_PROTECTED; /* post plugin types */ #define XINE_POST_TYPE_VIDEO_FILTER 0x010000 #define XINE_POST_TYPE_VIDEO_VISUALIZATION 0x010001 #define XINE_POST_TYPE_VIDEO_COMPOSE 0x010002 #define XINE_POST_TYPE_AUDIO_FILTER 0x020000 #define XINE_POST_TYPE_AUDIO_VISUALIZATION 0x020001 /* post plugin data types */ /* video port data * input->data is a xine_video_port_t* * output->data usually is a xine_video_port_t** */ #define XINE_POST_DATA_VIDEO 0 /* audio port data * input->data is a xine_audio_port_t* * output->data usually is a xine_audio_port_t** */ #define XINE_POST_DATA_AUDIO 1 /* integer data * input->data is a int* * output->data usually is a int* */ #define XINE_POST_DATA_INT 3 /* double precision floating point data * input->data is a double* * output->data usually is a double* */ #define XINE_POST_DATA_DOUBLE 4 /* parameters api (used by frontends) * input->data is xine_post_api_t* (see below) */ #define XINE_POST_DATA_PARAMETERS 5 /* defines a single parameter entry. */ typedef struct { int type; /* POST_PARAM_TYPE_xxx */ const char *name; /* name of this parameter */ int size; /* sizeof(parameter) */ int offset; /* offset in bytes from struct ptr */ char **enum_values; /* enumeration (first=0) or NULL */ double range_min; /* minimum value */ double range_max; /* maximum value */ int readonly; /* 0 = read/write, 1=read-only */ const char *description; /* user-friendly description */ } xine_post_api_parameter_t; /* description of parameters struct (params). */ typedef struct { int struct_size; /* sizeof(params) */ xine_post_api_parameter_t *parameter; /* list of parameters */ } xine_post_api_descr_t; typedef struct { /* * method to set all the read/write parameters. * params is a struct * defined by xine_post_api_descr_t */ int (*set_parameters) (xine_post_t *self, const void *params); /* * method to get all parameters. */ int (*get_parameters) (xine_post_t *self, void *params); /* * method to get params struct definition */ xine_post_api_descr_t * (*get_param_descr) (void); /* * method to get plugin and parameters help (UTF-8) * the help string must be word wrapped by the frontend. * it might contain \n to mark paragraph breaks. */ char * (*get_help) (void); } xine_post_api_t; /* post parameter types */ #define POST_PARAM_TYPE_LAST 0 /* terminator of parameter list */ #define POST_PARAM_TYPE_INT 1 /* integer (or vector of integers) */ #define POST_PARAM_TYPE_DOUBLE 2 /* double (or vector of doubles) */ #define POST_PARAM_TYPE_CHAR 3 /* char (or vector of chars = string) */ #define POST_PARAM_TYPE_STRING 4 /* (char *), ASCIIZ */ #define POST_PARAM_TYPE_STRINGLIST 5 /* (char **) list, NULL terminated */ #define POST_PARAM_TYPE_BOOL 6 /* integer (0 or 1) */ /********************************************************************* * information retrieval * *********************************************************************/ /* * xine log functions * * frontends can display xine log output using these functions */ int xine_get_log_section_count(xine_t *self) XINE_PROTECTED; /* return a NULL terminated array of log sections names */ const char *const *xine_get_log_names(xine_t *self) XINE_PROTECTED; /* print some log information to section */ void xine_log (xine_t *self, int buf, const char *format, ...) XINE_FORMAT_PRINTF(3, 4) XINE_PROTECTED; void xine_vlog(xine_t *self, int buf, const char *format, va_list args) XINE_FORMAT_PRINTF(3, 0) XINE_PROTECTED; /* get log messages of specified section */ char *const *xine_get_log (xine_t *self, int buf) XINE_PROTECTED; /* log callback will be called whenever something is logged */ typedef void (*xine_log_cb_t) (void *user_data, int section); void xine_register_log_cb (xine_t *self, xine_log_cb_t cb, void *user_data) XINE_PROTECTED; /* * error handling / engine status */ /* return last error */ int xine_get_error (xine_stream_t *stream) XINE_PROTECTED; /* get current xine engine status (constants see below) */ int xine_get_status (xine_stream_t *stream) XINE_PROTECTED; /* * engine status codes */ #define XINE_STATUS_IDLE 0 /* no mrl assigned */ #define XINE_STATUS_STOP 1 #define XINE_STATUS_PLAY 2 #define XINE_STATUS_QUIT 3 /* * xine error codes */ #define XINE_ERROR_NONE 0 #define XINE_ERROR_NO_INPUT_PLUGIN 1 #define XINE_ERROR_NO_DEMUX_PLUGIN 2 #define XINE_ERROR_DEMUX_FAILED 3 #define XINE_ERROR_MALFORMED_MRL 4 #define XINE_ERROR_INPUT_FAILED 5 /* * try to find out audio/spu language of given channel * (use -1 for current channel) * * lang must point to a buffer of at least XINE_LANG_MAX bytes * * returns 1 on success, 0 on failure */ int xine_get_audio_lang (xine_stream_t *stream, int channel, char *lang) XINE_PROTECTED; int xine_get_spu_lang (xine_stream_t *stream, int channel, char *lang) XINE_PROTECTED; /*_x_ increasing this number means an incompatible ABI breakage! */ #define XINE_LANG_MAX 32 /* * get position / length information * * depending of the nature and system layer of the stream, * some or all of this information may be unavailable or incorrect * (e.g. live network streams may not have a valid length) * * return: * 2: still playing the tail of the previous stream before * a pending gapless switch, info is valid for that * (libxine 1.2.14+): * 1: success, * 0: failure (data was not updated, probably because * it's not known yet... try again later). */ int xine_get_pos_length (xine_stream_t *stream, int *pos_stream, /* 0..65535 */ int *pos_time, /* milliseconds */ int *length_time) /* milliseconds */ XINE_PROTECTED; /* * get information about the stream such as * video width/height, codecs, audio format, title, author... * strings are UTF-8 encoded. * * constants see below */ uint32_t xine_get_stream_info (xine_stream_t *stream, int info) XINE_PROTECTED; const char *xine_get_meta_info (xine_stream_t *stream, int info) XINE_PROTECTED; #define XINE_QUERY_STREAM_INFO 1 /** @brief query multiple stream props, thread safe and consistently. * @param stream the xine stream to query. * @param sbuf the buffer to write string copies to. sbuf[0] will be set to 0. * @param sblen the byte size of sbuf. * @param strings input: -1 terminated list of XINE_META_INFO_*. * output: list of offsets into sbuf or 0 for NULL strings. * @param ints input: -1 terminated list of XINE_STREAM_INFO_*. * output: list of values or 0 where not set or found. * @return the count of bytes used in sbuf. */ int xine_query_stream_info (xine_stream_t *stream, char *sbuf, size_t sblen, int *strings, int *ints) XINE_PROTECTED; /* xine_get_stream_info */ #define XINE_STREAM_INFO_BITRATE 0 #define XINE_STREAM_INFO_SEEKABLE 1 #define XINE_STREAM_INFO_VIDEO_WIDTH 2 #define XINE_STREAM_INFO_VIDEO_HEIGHT 3 #define XINE_STREAM_INFO_VIDEO_RATIO 4 /* *10000 */ #define XINE_STREAM_INFO_VIDEO_CHANNELS 5 #define XINE_STREAM_INFO_VIDEO_STREAMS 6 #define XINE_STREAM_INFO_VIDEO_BITRATE 7 #define XINE_STREAM_INFO_VIDEO_FOURCC 8 #define XINE_STREAM_INFO_VIDEO_HANDLED 9 /* codec available? */ #define XINE_STREAM_INFO_FRAME_DURATION 10 /* 1/90000 sec */ #define XINE_STREAM_INFO_AUDIO_CHANNELS 11 #define XINE_STREAM_INFO_AUDIO_BITS 12 #define XINE_STREAM_INFO_AUDIO_SAMPLERATE 13 #define XINE_STREAM_INFO_AUDIO_BITRATE 14 #define XINE_STREAM_INFO_AUDIO_FOURCC 15 #define XINE_STREAM_INFO_AUDIO_HANDLED 16 /* codec available? */ #define XINE_STREAM_INFO_HAS_CHAPTERS 17 #define XINE_STREAM_INFO_HAS_VIDEO 18 #define XINE_STREAM_INFO_HAS_AUDIO 19 #define XINE_STREAM_INFO_IGNORE_VIDEO 20 #define XINE_STREAM_INFO_IGNORE_AUDIO 21 #define XINE_STREAM_INFO_IGNORE_SPU 22 #define XINE_STREAM_INFO_VIDEO_HAS_STILL 23 #define XINE_STREAM_INFO_MAX_AUDIO_CHANNEL 24 #define XINE_STREAM_INFO_MAX_SPU_CHANNEL 25 #define XINE_STREAM_INFO_AUDIO_MODE 26 #define XINE_STREAM_INFO_SKIPPED_FRAMES 27 /* for 1000 frames delivered */ #define XINE_STREAM_INFO_DISCARDED_FRAMES 28 /* for 1000 frames delivered */ #define XINE_STREAM_INFO_VIDEO_AFD 29 #define XINE_STREAM_INFO_DVD_TITLE_NUMBER 30 #define XINE_STREAM_INFO_DVD_TITLE_COUNT 31 #define XINE_STREAM_INFO_DVD_CHAPTER_NUMBER 32 #define XINE_STREAM_INFO_DVD_CHAPTER_COUNT 33 #define XINE_STREAM_INFO_DVD_ANGLE_NUMBER 34 #define XINE_STREAM_INFO_DVD_ANGLE_COUNT 35 /* possible values for XINE_STREAM_INFO_VIDEO_AFD */ #define XINE_VIDEO_AFD_NOT_PRESENT -1 #define XINE_VIDEO_AFD_RESERVED_0 0 #define XINE_VIDEO_AFD_RESERVED_1 1 #define XINE_VIDEO_AFD_BOX_16_9_TOP 2 #define XINE_VIDEO_AFD_BOX_14_9_TOP 3 #define XINE_VIDEO_AFD_BOX_GT_16_9_CENTRE 4 #define XINE_VIDEO_AFD_RESERVED_5 5 #define XINE_VIDEO_AFD_RESERVED_6 6 #define XINE_VIDEO_AFD_RESERVED_7 7 #define XINE_VIDEO_AFD_SAME_AS_FRAME 8 #define XINE_VIDEO_AFD_4_3_CENTRE 9 #define XINE_VIDEO_AFD_16_9_CENTRE 10 #define XINE_VIDEO_AFD_14_9_CENTRE 11 #define XINE_VIDEO_AFD_RESERVED_12 12 #define XINE_VIDEO_AFD_4_3_PROTECT_14_9 13 #define XINE_VIDEO_AFD_16_9_PROTECT_14_9 14 #define XINE_VIDEO_AFD_16_9_PROTECT_4_3 15 /* xine_get_meta_info */ #define XINE_META_INFO_TITLE 0 #define XINE_META_INFO_COMMENT 1 #define XINE_META_INFO_ARTIST 2 #define XINE_META_INFO_GENRE 3 #define XINE_META_INFO_ALBUM 4 #define XINE_META_INFO_YEAR 5 /* may be full date */ #define XINE_META_INFO_VIDEOCODEC 6 #define XINE_META_INFO_AUDIOCODEC 7 #define XINE_META_INFO_SYSTEMLAYER 8 #define XINE_META_INFO_INPUT_PLUGIN 9 #define XINE_META_INFO_CDINDEX_DISCID 10 #define XINE_META_INFO_TRACK_NUMBER 11 #define XINE_META_INFO_COMPOSER 12 /* post-1.1.17; taken from the list at http://age.hobba.nl/audio/mirroredpages/ogg-tagging.html on 2009-12-11 */ #define XINE_META_INFO_PUBLISHER 13 #define XINE_META_INFO_COPYRIGHT 14 #define XINE_META_INFO_LICENSE 15 #define XINE_META_INFO_ARRANGER 16 #define XINE_META_INFO_LYRICIST 17 #define XINE_META_INFO_AUTHOR 18 #define XINE_META_INFO_CONDUCTOR 19 #define XINE_META_INFO_PERFORMER 20 #define XINE_META_INFO_ENSEMBLE 21 #define XINE_META_INFO_OPUS 22 #define XINE_META_INFO_PART 23 #define XINE_META_INFO_PARTNUMBER 24 #define XINE_META_INFO_LOCATION 25 /* post-1.1.18.1 */ #define XINE_META_INFO_DISCNUMBER 26 /********************************************************************* * plugin management / autoplay / mrl browsing * *********************************************************************/ /* * note: the pointers to strings or string arrays returned * by some of these functions are pointers to statically * alloced internal xine memory chunks. * they're only valid between xine function calls * and should never be free()d. */ typedef struct xine_mrl_s xine_mrl_t; struct xine_mrl_s { char *origin; /* file plugin: path */ char *mrl; /* :// */ char *link; off_t size; /* size of this source, may be 0 */ uint32_t type; /* see below */ }; /* mrl types */ #define XINE_MRL_TYPE_unknown (0 << 0) #define XINE_MRL_TYPE_dvd (1 << 0) #define XINE_MRL_TYPE_vcd (1 << 1) #define XINE_MRL_TYPE_net (1 << 2) #define XINE_MRL_TYPE_rtp (1 << 3) #define XINE_MRL_TYPE_stdin (1 << 4) #define XINE_MRL_TYPE_cda (1 << 5) #define XINE_MRL_TYPE_file (1 << 6) #define XINE_MRL_TYPE_file_fifo (1 << 7) #define XINE_MRL_TYPE_file_chardev (1 << 8) #define XINE_MRL_TYPE_file_directory (1 << 9) #define XINE_MRL_TYPE_file_blockdev (1 << 10) #define XINE_MRL_TYPE_file_normal (1 << 11) #define XINE_MRL_TYPE_file_symlink (1 << 12) #define XINE_MRL_TYPE_file_sock (1 << 13) #define XINE_MRL_TYPE_file_exec (1 << 14) #define XINE_MRL_TYPE_file_backup (1 << 15) #define XINE_MRL_TYPE_file_hidden (1 << 16) /* get a list of browsable input plugin ids */ const char *const *xine_get_browsable_input_plugin_ids (xine_t *self) XINE_PROTECTED; /* * ask input plugin named to return * a list of available MRLs in domain/directory . * * may be NULL indicating the toplevel domain/dir * returns if is a valid MRL, not a directory * returns NULL if is an invalid MRL, not even a directory. */ xine_mrl_t **xine_get_browse_mrls (xine_t *self, const char *plugin_id, const char *start_mrl, int *num_mrls) XINE_PROTECTED; /* get a list of plugins that support the autoplay feature */ const char *const *xine_get_autoplay_input_plugin_ids (xine_t *self) XINE_PROTECTED; /* get autoplay MRL list from input plugin named */ const char * const *xine_get_autoplay_mrls (xine_t *self, const char *plugin_id, int *num_mrls) XINE_PROTECTED; /* get a list of file extensions for file types supported by xine * the list is separated by spaces * * the pointer returned can be free()ed when no longer used */ char *xine_get_file_extensions (xine_t *self) XINE_PROTECTED; /* get a list of mime types supported by xine * * the pointer returned can be free()ed when no longer used */ char *xine_get_mime_types (xine_t *self) XINE_PROTECTED; /* get the demuxer identifier that handles a given mime type * * the pointer returned can be free()ed when no longer used * returns NULL if no demuxer is available to handle this. */ char *xine_get_demux_for_mime_type (xine_t *self, const char *mime_type) XINE_PROTECTED; /* get a description string for a plugin */ const char *xine_get_input_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; const char *xine_get_demux_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; const char *xine_get_spu_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; const char *xine_get_audio_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; const char *xine_get_video_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; const char *xine_get_audio_driver_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; const char *xine_get_video_driver_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; const char *xine_get_post_plugin_description (xine_t *self, const char *plugin_id) XINE_PROTECTED; /* get lists of available audio and video output plugins */ const char *const *xine_list_audio_output_plugins (xine_t *self) XINE_PROTECTED; const char *const *xine_list_video_output_plugins (xine_t *self) XINE_PROTECTED; /* typemask is (1ULL << XINE_VISUAL_TYPE_FOO) | ... */ const char *const *xine_list_video_output_plugins_typed (xine_t *self, uint64_t typemask) XINE_PROTECTED; /* get list of available demultiplexor plugins */ const char *const *xine_list_demuxer_plugins(xine_t *self) XINE_PROTECTED; /* get list of available input plugins */ const char *const *xine_list_input_plugins(xine_t *self) XINE_PROTECTED; /* get list of available subpicture plugins */ const char *const *xine_list_spu_plugins(xine_t *self) XINE_PROTECTED; /* get list of available audio and video decoder plugins */ const char *const *xine_list_audio_decoder_plugins(xine_t *self) XINE_PROTECTED; const char *const *xine_list_video_decoder_plugins(xine_t *self) XINE_PROTECTED; /* unload unused plugins */ void xine_plugins_garbage_collector(xine_t *self) XINE_PROTECTED; /********************************************************************* * visual specific gui <-> xine engine communication * *********************************************************************/ /* new (preferred) method to talk to video driver. */ int xine_port_send_gui_data (xine_video_port_t *vo, int type, void *data) XINE_PROTECTED; typedef struct { /* area of that drawable to be used by video */ int x,y,w,h; } x11_rectangle_t; /* * this is the visual data struct any x11 gui * must supply to the xine_open_video_driver call * ("data" parameter) */ typedef struct { /* some information about the display */ void *display; /* Display* */ int screen; /* drawable to display the video in/on */ unsigned long d; /* Drawable */ void *user_data; /* * dest size callback * * this will be called by the video driver to find out * how big the video output area size will be for a * given video size. The ui should _not_ adjust its * video out area, just do some calculations and return * the size. This will be called for every frame, ui * implementation should be fast. * dest_pixel_aspect should be set to the used display pixel aspect. * NOTE: Semantics has changed: video_width and video_height * are no longer pixel aspect corrected. Get the old semantics * in the UI with * *dest_pixel_aspect = display_pixel_aspect; * if (video_pixel_aspect >= display_pixel_aspect) * video_width = video_width * video_pixel_aspect / display_pixel_aspect + .5; * else * video_height = video_height * display_pixel_aspect / video_pixel_aspect + .5; */ void (*dest_size_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_width, int *dest_height, double *dest_pixel_aspect); /* * frame output callback * * this will be called by the video driver for every frame * it's about to draw. ui can adapt its size if necessary * here. * note: the ui doesn't have to adjust itself to this * size, this is just to be taken as a hint. * ui must return the actual size of the video output * area and the video output driver will do its best * to adjust the video frames to that size (while * preserving aspect ratio and stuff). * dest_x, dest_y: offset inside window * dest_width, dest_height: available drawing space * dest_pixel_aspect: display pixel aspect * win_x, win_y: window absolute screen position * NOTE: Semantics has changed: video_width and video_height * are no longer pixel aspect corrected. Get the old semantics * in the UI with * *dest_pixel_aspect = display_pixel_aspect; * if (video_pixel_aspect >= display_pixel_aspect) * video_width = video_width * video_pixel_aspect / display_pixel_aspect + .5; * else * video_height = video_height * display_pixel_aspect / video_pixel_aspect + .5; */ void (*frame_output_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y); /* * lock display callback * * this callback is called when the video driver * needs access to the x11 display connection * * note: to enable this you MUST use XINE_VISUAL_TYPE_X11_2 * note: if display_lock is NULL, the fallback is used * note: fallback for this function is XLockDisplay(display) */ void (*lock_display) (void *user_data); /* * unlock display callback * * this callback is called when the video driver * doesn't need access to the x11 display connection anymore * * note: to enable this you MUST use XINE_VISUAL_TYPE_X11_2 * note: if display_unlock is NULL, the fallback is used * note: fallback for this function is XUnlockDisplay(display) */ void (*unlock_display) (void *user_data); } x11_visual_t; /* * this is the visual data struct any xcb gui * must supply to the xine_open_video_driver call * ("data" parameter) */ typedef struct { /* some information about the display */ void *connection; /* xcb_connection_t */ void *screen; /* xcb_screen_t */ /* window to display the video in / on */ unsigned int window; /* xcb_window_t */ void *user_data; /* * dest size callback * * this will be called by the video driver to find out * how big the video output area size will be for a * given video size. The ui should _not_ adjust its * video out area, just do some calculations and return * the size. This will be called for every frame, ui * implementation should be fast. * dest_pixel_aspect should be set to the used display pixel aspect. * NOTE: Semantics has changed: video_width and video_height * are no longer pixel aspect corrected. Get the old semantics * in the UI with * *dest_pixel_aspect = display_pixel_aspect; * if (video_pixel_aspect >= display_pixel_aspect) * video_width = video_width * video_pixel_aspect / display_pixel_aspect + .5; * else * video_height = video_height * display_pixel_aspect / video_pixel_aspect + .5; */ void (*dest_size_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_width, int *dest_height, double *dest_pixel_aspect); /* * frame output callback * * this will be called by the video driver for every frame * it's about to draw. ui can adapt its size if necessary * here. * note: the ui doesn't have to adjust itself to this * size, this is just to be taken as a hint. * ui must return the actual size of the video output * area and the video output driver will do its best * to adjust the video frames to that size (while * preserving aspect ratio and stuff). * dest_x, dest_y: offset inside window * dest_width, dest_height: available drawing space * dest_pixel_aspect: display pixel aspect * win_x, win_y: window absolute screen position * NOTE: Semantics has changed: video_width and video_height * are no longer pixel aspect corrected. Get the old semantics * in the UI with * *dest_pixel_aspect = display_pixel_aspect; * if (video_pixel_aspect >= display_pixel_aspect) * video_width = video_width * video_pixel_aspect / display_pixel_aspect + .5; * else * video_height = video_height * display_pixel_aspect / video_pixel_aspect + .5; */ void (*frame_output_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y); } xcb_visual_t; /* * this is the visual data struct any Wayland GUI * must supply to the xine_open_video_driver call * ("data" parameter) */ struct wl_display; struct wl_surface; typedef struct { struct wl_display *display; struct wl_surface *surface; void *user_data; void (*frame_output_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y); } xine_wayland_visual_t; /************************************************** * XINE_VO_RAW struct definitions *************************************************/ /* frame_format definitions */ #define XINE_VORAW_YV12 1 #define XINE_VORAW_YUY2 2 #define XINE_VORAW_RGB 4 /* maximum number of overlays the raw driver can handle */ #define XINE_VORAW_MAX_OVL 16 /* raw_overlay_t struct used in raw_overlay_cb callback */ typedef struct { uint8_t *ovl_rgba; int ovl_w, ovl_h; /* overlay's width and height */ int ovl_x, ovl_y; /* overlay's top-left display position */ } raw_overlay_t; /* this is the visual data struct any raw gui * must supply to the xine_open_video_driver call * ("data" parameter) */ typedef struct { void *user_data; /* OR'ed frame_format * Unsupported frame formats are converted to rgb. * XINE_VORAW_RGB is always assumed by the driver, even if not set. * So a frontend must at least support rgb. * Be aware that rgb requires more cpu than yuv, * so avoid its usage for video playback. * However, it's useful for single frame capture (e.g. thumbs) */ int supported_formats; /* raw output callback * this will be called by the video driver for every frame * * If frame_format==XINE_VORAW_YV12, data0 points to frame_width*frame_height Y values * data1 points to (frame_width/2)*(frame_height/2) U values * data2 points to (frame_width/2)*(frame_height/2) V values * * If frame_format==XINE_VORAW_YUY2, data0 points to frame_width*frame_height*2 YU/Y²V values * data1 is NULL * data2 is NULL * * If frame_format==XINE_VORAW_RGB, data0 points to frame_width*frame_height*3 RGB values * data1 is NULL * data2 is NULL */ void (*raw_output_cb) (void *user_data, int frame_format, int frame_width, int frame_height, double frame_aspect, void *data0, void *data1, void *data2); /* raw overlay callback * this will be called by the video driver for every new overlay state * overlays_array points to an array of num_ovl raw_overlay_t * Note that num_ovl can be 0, meaning "end of overlay display" * num_ovl is at most XINE_VORAW_MAX_OVL */ void (*raw_overlay_cb) (void *user_data, int num_ovl, raw_overlay_t *overlays_array); } raw_visual_t; /********************************************** * end of vo_raw defs *********************************************/ /* * this is the visual data struct any fb gui * may supply to the xine_open_video_driver call * ("data" parameter) to get frame_output_cd calls */ typedef struct { void (*frame_output_cb) (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y); void *user_data; } fb_visual_t; #if defined(WIN32) && (!defined(XINE_COMPILE) || defined(XINE_NEED_WIN32_VISUAL)) /* * this is the visual data struct any win32 gui should supply * (pass this to init_video_out_plugin or the xine_load_video_output_plugin * utility function) */ typedef struct { HWND WndHnd; /* handle of window associated with primary surface */ HINSTANCE HInst; /* handle of windows application instance */ RECT WndRect; /* rect of window client points translated to screen * cooridnates */ int FullScreen; /* is window fullscreen */ HBRUSH Brush; /* window brush for background color */ COLORREF ColorKey; /* window brush color key */ } win32_visual_t; /* * constants for gui_data_exchange's data_type parameter */ #define GUI_WIN32_MOVED_OR_RESIZED 0 #endif /* WIN32 */ /* * "type" constants for xine_port_send_gui_data(...) */ #ifndef XINE_DISABLE_DEPRECATED_FEATURES /* xevent *data */ #define XINE_GUI_SEND_COMPLETION_EVENT 1 /* DEPRECATED */ #endif /* Drawable data */ #define XINE_GUI_SEND_DRAWABLE_CHANGED 2 /* xevent *data */ #define XINE_GUI_SEND_EXPOSE_EVENT 3 /* x11_rectangle_t *data */ #define XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO 4 /* int data */ #define XINE_GUI_SEND_VIDEOWIN_VISIBLE 5 /* *data contains chosen visual, select a new one or change it to NULL * to indicate the visual to use or that no visual will work */ /* XVisualInfo **data */ #define XINE_GUI_SEND_SELECT_VISUAL 8 /* Gui is about to destroy drawable */ #define XINE_GUI_SEND_WILL_DESTROY_DRAWABLE 9 /********************************************************************* * xine health check stuff * *********************************************************************/ #define XINE_HEALTH_CHECK_OK 0 #define XINE_HEALTH_CHECK_FAIL 1 #define XINE_HEALTH_CHECK_UNSUPPORTED 2 #define XINE_HEALTH_CHECK_NO_SUCH_CHECK 3 #define CHECK_KERNEL 0 #define CHECK_MTRR 1 #define CHECK_CDROM 2 #define CHECK_DVDROM 3 #define CHECK_DMA 4 #define CHECK_X 5 #define CHECK_XV 6 struct xine_health_check_s { const char* cdrom_dev; const char* dvd_dev; const char* msg; const char* title; const char* explanation; int status; }; typedef struct xine_health_check_s xine_health_check_t; xine_health_check_t* xine_health_check(xine_health_check_t*, int check_num) XINE_PROTECTED; /********************************************************************* * configuration system * *********************************************************************/ /* * config entry data types */ #define XINE_CONFIG_TYPE_UNKNOWN 0 #define XINE_CONFIG_TYPE_RANGE 1 #define XINE_CONFIG_TYPE_STRING 2 #define XINE_CONFIG_TYPE_ENUM 3 #define XINE_CONFIG_TYPE_NUM 4 #define XINE_CONFIG_TYPE_BOOL 5 /* For the string type (1.1.4 and later). These are stored in num_value. */ #define XINE_CONFIG_STRING_IS_STRING 0 #define XINE_CONFIG_STRING_IS_FILENAME 1 #define XINE_CONFIG_STRING_IS_DEVICE_NAME 2 #define XINE_CONFIG_STRING_IS_DIRECTORY_NAME 3 typedef struct xine_cfg_entry_s xine_cfg_entry_t; typedef void (*xine_config_cb_t) (void *user_data, xine_cfg_entry_t *entry); struct xine_cfg_entry_s { const char *key; /* unique id (example: gui.logo_mrl) */ int type; /* user experience level */ int exp_level; /* 0 => beginner, 10 => advanced user, 20 => expert */ /* type unknown */ char *unknown_value; /* type string */ char *str_value; char *str_default; /* common to range, enum, num, bool; * num_value is also used by string to indicate what's required: * plain string, file name, device name, directory name */ int num_value; int num_default; /* type range specific: */ int range_min; int range_max; /* type enum specific: */ char **enum_values; /* help info for the user (UTF-8) * the help string must be word wrapped by the frontend. * it might contain \n to mark paragraph breaks. */ const char *description; const char *help; /* callback function and data for live changeable values */ /* some config entries will take effect immediately, although they * do not have a callback registered; such values will have some * non-NULL dummy value in callback_data; so if you want to check, * if a config change will require restarting xine, check for * callback_data == NULL */ xine_config_cb_t callback; void *callback_data; }; const char *xine_config_register_string (xine_t *self, const char *key, const char *def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) XINE_PROTECTED; const char *xine_config_register_filename (xine_t *self, const char *key, const char *def_value, int req_type, /* XINE_CONFIG_STRING_IS_* */ const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) XINE_PROTECTED; int xine_config_register_range (xine_t *self, const char *key, int def_value, int min, int max, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) XINE_PROTECTED; int xine_config_register_enum (xine_t *self, const char *key, int def_value, char **values, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) XINE_PROTECTED; int xine_config_register_num (xine_t *self, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) XINE_PROTECTED; int xine_config_register_bool (xine_t *self, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) XINE_PROTECTED; /** * unregister multiple entry callback functions. * all 3 values need to match unless they are NULL. * if cb_data_size is not zero, data pointers within the range * (cb_data <= ptr < cb_data + cb_data_size) will match. * returns the count of unregistered functions. */ #define HAVE_XINE_CONFIG_UNREGISTER_CALLBACKS 1 int xine_config_unregister_callbacks (xine_t *self, const char *key, xine_config_cb_t changed_cb, void *cb_data, size_t cb_data_size) XINE_PROTECTED; /* * the following functions will copy data from the internal xine_config * data database to the xine_cfg_entry_t *entry you provide * * they return 1 on success, 0 on failure */ /* get first config item */ int xine_config_get_first_entry (xine_t *self, xine_cfg_entry_t *entry) XINE_PROTECTED; /* get next config item (iterate through the items) */ int xine_config_get_next_entry (xine_t *self, xine_cfg_entry_t *entry) XINE_PROTECTED; /* search for a config entry by key */ int xine_config_lookup_entry (xine_t *self, const char *key, xine_cfg_entry_t *entry) XINE_PROTECTED; /* * Helper function to get numeric value of config entry. * Return def_value if entry was not found (or is not correct type). */ int xine_config_lookup_num(xine_t *self, const char *key, int def_value) XINE_PROTECTED; /* * Thread-safe helper function to get string value of config entry. * Return copy of current value or NULL. * Returned string must be freed with xine_config_free_str(). */ char *xine_config_lookup_string(xine_t *self, const char *key) XINE_PROTECTED; void xine_config_free_string(xine_t *self, char **value) XINE_PROTECTED; /* * update a config entry (which was returned from lookup_entry() ) * * xine will make a deep copy of the data in the entry into its internal * config database. */ void xine_config_update_entry (xine_t *self, const xine_cfg_entry_t *entry) XINE_PROTECTED; /* * translation of old configuration entry names */ typedef struct { const char *old_name, *new_name; } xine_config_entry_translation_t; void xine_config_set_translation_user (const xine_config_entry_translation_t *) XINE_PROTECTED; /* * load/save config data from/to afile (e.g. $HOME/.xine/config) */ void xine_config_load (xine_t *self, const char *cfg_filename) XINE_PROTECTED; void xine_config_save (xine_t *self, const char *cfg_filename) XINE_PROTECTED; void xine_config_reset (xine_t *self) XINE_PROTECTED; /********************************************************************* * asynchroneous xine event mechanism * *********************************************************************/ /* * to receive events you have to register an event queue with * the xine engine (xine_event_new_queue, see below). * * then you can either * 1) check for incoming events regularly (xine_event_get/wait), * process them and free them using xine_event_free * 2) use xine_event_create_listener_thread and specify a callback * which will then be called for each event * * to send events to every module listening you don't need * to register an event queue but simply call xine_event_send. * * front ends should listen for one of MRL_REFERENCE and MRL_REFERENCE_EXT * since both will be sent for compatibility reasons */ /* event types */ #define XINE_EVENT_UI_PLAYBACK_FINISHED 1 /* frontend can e.g. move on to next playlist entry */ #define XINE_EVENT_UI_CHANNELS_CHANGED 2 /* inform ui that new channel info is available */ #define XINE_EVENT_UI_SET_TITLE 3 /* request title display change in ui */ #define XINE_EVENT_UI_MESSAGE 4 /* message (dialog) for the ui to display */ #define XINE_EVENT_FRAME_FORMAT_CHANGE 5 /* e.g. aspect ratio change during dvd playback */ #define XINE_EVENT_AUDIO_LEVEL 6 /* report current audio level (l/r/mute) */ #define XINE_EVENT_QUIT 7 /* last event sent when stream is disposed */ #define XINE_EVENT_PROGRESS 8 /* index creation/network connections */ #define XINE_EVENT_MRL_REFERENCE 9 /* (deprecated) demuxer->frontend: MRL reference(s) for the real stream */ #define XINE_EVENT_UI_NUM_BUTTONS 10 /* number of buttons for interactive menus */ #define XINE_EVENT_SPU_BUTTON 11 /* the mouse pointer enter/leave a button */ #define XINE_EVENT_DROPPED_FRAMES 12 /* number of dropped frames is too high */ #define XINE_EVENT_MRL_REFERENCE_EXT 13 /* demuxer->frontend: MRL reference(s) for the real stream */ #define XINE_EVENT_AUDIO_AMP_LEVEL 14 /* report current audio amp level (l/r/mute) */ #define XINE_EVENT_NBC_STATS 15 /* nbc buffer status */ /* input events coming from frontend */ #define XINE_EVENT_INPUT_MOUSE_BUTTON 101 #define XINE_EVENT_INPUT_MOUSE_MOVE 102 #define XINE_EVENT_INPUT_MENU1 103 #define XINE_EVENT_INPUT_MENU2 104 #define XINE_EVENT_INPUT_MENU3 105 #define XINE_EVENT_INPUT_MENU4 106 #define XINE_EVENT_INPUT_MENU5 107 #define XINE_EVENT_INPUT_MENU6 108 #define XINE_EVENT_INPUT_MENU7 109 #define XINE_EVENT_INPUT_UP 110 #define XINE_EVENT_INPUT_DOWN 111 #define XINE_EVENT_INPUT_LEFT 112 #define XINE_EVENT_INPUT_RIGHT 113 #define XINE_EVENT_INPUT_SELECT 114 #define XINE_EVENT_INPUT_NEXT 115 #define XINE_EVENT_INPUT_PREVIOUS 116 #define XINE_EVENT_INPUT_ANGLE_NEXT 117 #define XINE_EVENT_INPUT_ANGLE_PREVIOUS 118 #define XINE_EVENT_INPUT_BUTTON_FORCE 119 #define XINE_EVENT_INPUT_NUMBER_0 120 #define XINE_EVENT_INPUT_NUMBER_1 121 #define XINE_EVENT_INPUT_NUMBER_2 122 #define XINE_EVENT_INPUT_NUMBER_3 123 #define XINE_EVENT_INPUT_NUMBER_4 124 #define XINE_EVENT_INPUT_NUMBER_5 125 #define XINE_EVENT_INPUT_NUMBER_6 126 #define XINE_EVENT_INPUT_NUMBER_7 127 #define XINE_EVENT_INPUT_NUMBER_8 128 #define XINE_EVENT_INPUT_NUMBER_9 129 #define XINE_EVENT_INPUT_NUMBER_10_ADD 130 /* specific event types */ #define XINE_EVENT_SET_V4L2 200 #define XINE_EVENT_PVR_SAVE 201 #define XINE_EVENT_PVR_REPORT_NAME 202 #define XINE_EVENT_PVR_REALTIME 203 #define XINE_EVENT_PVR_PAUSE 204 #define XINE_EVENT_SET_MPEG_DATA 205 /* VDR specific event types */ #define XINE_EVENT_VDR_RED 300 #define XINE_EVENT_VDR_GREEN 301 #define XINE_EVENT_VDR_YELLOW 302 #define XINE_EVENT_VDR_BLUE 303 #define XINE_EVENT_VDR_PLAY 304 #define XINE_EVENT_VDR_PAUSE 305 #define XINE_EVENT_VDR_STOP 306 #define XINE_EVENT_VDR_RECORD 307 #define XINE_EVENT_VDR_FASTFWD 308 #define XINE_EVENT_VDR_FASTREW 309 #define XINE_EVENT_VDR_POWER 310 #define XINE_EVENT_VDR_CHANNELPLUS 311 #define XINE_EVENT_VDR_CHANNELMINUS 312 #define XINE_EVENT_VDR_SCHEDULE 313 #define XINE_EVENT_VDR_CHANNELS 314 #define XINE_EVENT_VDR_TIMERS 315 #define XINE_EVENT_VDR_RECORDINGS 316 #define XINE_EVENT_VDR_SETUP 317 #define XINE_EVENT_VDR_COMMANDS 318 #define XINE_EVENT_VDR_BACK 319 #define XINE_EVENT_VDR_USER1 320 #define XINE_EVENT_VDR_USER2 321 #define XINE_EVENT_VDR_USER3 322 #define XINE_EVENT_VDR_USER4 323 #define XINE_EVENT_VDR_USER5 324 #define XINE_EVENT_VDR_USER6 325 #define XINE_EVENT_VDR_USER7 326 #define XINE_EVENT_VDR_USER8 327 #define XINE_EVENT_VDR_USER9 328 #define XINE_EVENT_VDR_VOLPLUS 329 #define XINE_EVENT_VDR_VOLMINUS 330 #define XINE_EVENT_VDR_MUTE 331 #define XINE_EVENT_VDR_AUDIO 332 #define XINE_EVENT_VDR_INFO 333 #define XINE_EVENT_VDR_CHANNELPREVIOUS 334 #define XINE_EVENT_VDR_SUBTITLES 335 #define XINE_EVENT_VDR_USER0 336 /* some space for further keys */ #define XINE_EVENT_VDR_SETVIDEOWINDOW 350 #define XINE_EVENT_VDR_FRAMESIZECHANGED 351 #define XINE_EVENT_VDR_SELECTAUDIO 352 #define XINE_EVENT_VDR_TRICKSPEEDMODE 353 #define XINE_EVENT_VDR_PLUGINSTARTED 354 #define XINE_EVENT_VDR_DISCONTINUITY 355 /* events generated from post plugins */ #define XINE_EVENT_POST_TVTIME_FILMMODE_CHANGE 400 /* * xine event struct */ typedef struct { xine_stream_t *stream; /* stream this event belongs to */ void *data; /* contents depending on type */ int data_length; int type; /* event type (constants see above) */ /* you do not have to provide this, it will be filled in by xine_event_send() */ struct timeval tv; /* timestamp of event creation */ } xine_event_t; /* * input event dynamic data */ typedef struct { xine_event_t event; uint8_t button; /* Generally 1 = left, 2 = mid, 3 = right */ uint16_t x,y; /* In Image space */ } xine_input_data_t; /* * UI event dynamic data - send information to/from UI. */ typedef struct { int num_buttons; int str_len; char str[256]; /* might be longer */ } xine_ui_data_t; /* * Send messages to UI. used mostly to report errors. */ typedef struct { /* * old xine-ui versions expect xine_ui_data_t type. * this struct is added for compatibility. */ xine_ui_data_t compatibility; /* See XINE_MSG_xxx for defined types. */ int type; /* defined types are provided with a standard explanation. * note: zero means no explanation. */ int explanation; /* add to struct address to get a valid (char *) */ /* parameters are zero terminated strings */ int num_parameters; int parameters; /* add to struct address to get a valid (char *) */ /* where messages are stored, will be longer * * this field begins with the message text itself (\0-terminated), * followed by (optional) \0-terminated parameter strings * the end marker is \0 \0 */ char messages[1]; } xine_ui_message_data_t; /* * notify frame format change */ typedef struct { int width; int height; /* these are aspect codes as defined in MPEG2, because this * is only used for DVD playback, pan_scan is a boolean flag */ int aspect; int pan_scan; } xine_format_change_data_t; /* * audio level for left/right channel */ typedef struct { int left; int right; /* 0..100 % */ int mute; } xine_audio_level_data_t; /* * index generation / buffering */ typedef struct { const char *description; /* e.g. "connecting..." */ int percent; } xine_progress_data_t; /* * nbc buffer status */ typedef struct { int v_percent; /* fill of video buffer */ int64_t v_remaining; /* remaining time in ms till underrun */ int64_t v_bitrate; /* current bitrate */ int v_in_disc; /* in discontinuity */ int a_percent; /* like video, but for audio */ int64_t a_remaining; int64_t a_bitrate; int a_in_disc; int buffering; /* currently filling buffer */ int enabled; /* buffer disabled by engine */ int type; /* 0=buffer put, 1=buffer get */ } xine_nbc_stats_data_t; /* * mrl reference data is sent by demuxers when a reference stream is found. * this stream just contains pointers (urls) to the real data, which are * passed to frontend using this event type. (examples: .asx, .mov and .ram) * * ideally, frontends should add these mrls to a "hierarchical playlist". * that is, instead of the original file, the ones provided here should be * played instead. on pratice, just using a simple playlist should work. * * mrl references should be played in the same order they are received, just * after the current stream finishes. * alternative entries may be provided and should be used in case of * failure of the primary stream (the one with alternative=0). * * sample playlist: * 1) http://something/something.ram * 1a) rtsp://something/realsomething1.rm (alternative=0) * 1b) pnm://something/realsomething1.rm (alternative=1) * 2) http://another/another.avi * * 1 and 2 are the original items on this playlist. 1a and 1b were received * by events (they are the mrl references enclosed in 1). 1a is played after * receiving the finished event from 1. note: 1b is usually ignored, it should * only be used in case 1a fails to open. * * An event listener which accepts XINE_EVENT_MRL_REFERENCE_EXT events * *must* ignore XINE_EVENT_MRL_REFERENCE events. */ typedef struct { int alternative; /* alternative playlist number, usually 0 */ char mrl[1]; /* might (will) be longer */ } xine_mrl_reference_data_t XINE_DEPRECATED; typedef struct { int alternative; /* as above */ uint32_t start_time, duration; /* milliseconds */ uint32_t spare[20]; /* for future expansion */ const char mrl[1]; /* might (will) be longer */ /*const char title[]; ** immediately follows MRL's terminating NUL */ } xine_mrl_reference_data_ext_t; /* * configuration options for video4linux-like input plugins */ typedef struct { /* input selection */ int input; /* select active input from card */ int channel; /* channel number */ int radio; /* ask for a radio channel */ uint32_t frequency; /* frequency divided by 62.5KHz or 62.5 Hz */ uint32_t transmission; /* The transmission standard. */ /* video parameters */ uint32_t framerate_numerator; /* framerate as numerator/denominator */ uint32_t framerate_denominator; uint32_t framelines; /* Total lines per frame including blanking */ uint64_t standard_id; /* One of the V4L2_STD_* values */ uint32_t colorstandard; /* One of the V4L2_COLOR_STD_* values */ uint32_t colorsubcarrier; /* The color subcarrier frequency */ int frame_width; /* scaled frame width */ int frame_height; /* scaled frame height */ /* let some spare space so we can add new fields without breaking * binary api compatibility. */ uint32_t spare[20]; /* used by pvr plugin */ int32_t session_id; /* -1 stops pvr recording */ } xine_set_v4l2_data_t; /* * configuration options for plugins that can do a kind of mpeg encoding * note: highly experimental api :) */ typedef struct { /* mpeg2 parameters */ int bitrate_vbr; /* 1 = vbr, 0 = cbr */ int bitrate_mean; /* mean (target) bitrate in kbps*/ int bitrate_peak; /* peak (max) bitrate in kbps */ int gop_size; /* GOP size in frames */ int gop_closure; /* open/closed GOP */ int b_frames; /* number of B frames to use */ int aspect_ratio; /* XINE_VO_ASPECT_xxx */ /* let some spare space so we can add new fields without breaking * binary api compatibility. */ uint32_t spare[20]; } xine_set_mpeg_data_t; typedef struct { int direction; /* 0 leave, 1 enter */ int32_t button; /* button number */ } xine_spu_button_t; #ifdef XINE_ENABLE_EXPERIMENTAL_FEATURES /* * ask pvr to save (ie. do not discard) the current session * see comments on input_pvr.c to understand how it works. */ typedef struct { /* mode values: * -1 = do nothing, just set the name * 0 = truncate current session and save from now on * 1 = save from last sync point * 2 = save everything on current session */ int mode; int id; char name[256]; /* name for saving, might be longer */ } xine_pvr_save_data_t; typedef struct { /* mode values: * 0 = non realtime * 1 = realtime */ int mode; } xine_pvr_realtime_t; typedef struct { /* mode values: * 0 = playing * 1 = paused */ int mode; } xine_pvr_pause_t; #endif /* event XINE_EVENT_DROPPED_FRAMES is generated if libxine detects a * high number of dropped frames (above configured thresholds). it can * be used by the front end to warn about performance problems. */ typedef struct { /* these values are given for 1000 frames delivered */ /* (that is, divide by 10 to get percentages) */ int skipped_frames; int skipped_threshold; int discarded_frames; int discarded_threshold; } xine_dropped_frames_t; /* * Defined message types for XINE_EVENT_UI_MESSAGE * This is the mechanism to report async errors from engine. * * If frontend knows about the XINE_MSG_xxx type it may safely * ignore the 'explanation' field and provide its own custom * dialogue to the 'parameters'. * * right column specifies the usual parameters. */ #define XINE_MSG_NO_ERROR 0 /* (messages to UI) */ #define XINE_MSG_GENERAL_WARNING 1 /* (warning message) */ #define XINE_MSG_UNKNOWN_HOST 2 /* (host name) */ #define XINE_MSG_UNKNOWN_DEVICE 3 /* (device name) */ #define XINE_MSG_NETWORK_UNREACHABLE 4 /* none */ #define XINE_MSG_CONNECTION_REFUSED 5 /* (host name) */ #define XINE_MSG_FILE_NOT_FOUND 6 /* (file name or mrl) */ #define XINE_MSG_READ_ERROR 7 /* (device/file/mrl) */ #define XINE_MSG_LIBRARY_LOAD_ERROR 8 /* (library/decoder) */ #define XINE_MSG_ENCRYPTED_SOURCE 9 /* none */ #define XINE_MSG_SECURITY 10 /* (security message) */ #define XINE_MSG_AUDIO_OUT_UNAVAILABLE 11 /* none */ #define XINE_MSG_PERMISSION_ERROR 12 /* (file name or mrl) */ #define XINE_MSG_FILE_EMPTY 13 /* file is empty */ #define XINE_MSG_AUTHENTICATION_NEEDED 14 /* (mrl, likely http) */ #define XINE_MSG_RECORDING_DONE 15 /* just what it says */ /* opaque xine_event_queue_t */ typedef struct xine_event_queue_s xine_event_queue_t; /* * register a new event queue * * you have to receive messages from this queue regularly * * use xine_event_dispose_queue to unregister and free the queue */ xine_event_queue_t *xine_event_new_queue (xine_stream_t *stream) XINE_PROTECTED; void xine_event_dispose_queue (xine_event_queue_t *queue) XINE_PROTECTED; /** @brief Filter events by type. * @param queue The queue that shall receive a few types only. * @param types List of event types, termiated by XINE_EVENT_QUIT. NULL reverts to the "all types" default. */ void xine_event_select (xine_event_queue_t *queue, const int *types) XINE_PROTECTED; /* * receive events (poll) * * use xine_event_free on the events received from these calls * when they're no longer needed */ /* get first event or NULL when queue is empty. */ xine_event_t *xine_event_get (xine_event_queue_t *queue) XINE_PROTECTED; /* free prev_event if not NULL, then same as xine_event_get (). */ xine_event_t *xine_event_next (xine_event_queue_t *queue, xine_event_t *prev_event) XINE_PROTECTED; /* get first event, wait for it if needed. */ xine_event_t *xine_event_wait (xine_event_queue_t *queue) XINE_PROTECTED; /* free or reuse event. may be NULL. */ void xine_event_free (xine_event_t *event) XINE_PROTECTED; /* * receive events (callback) * * a thread is created which will receive all events from * the specified queue, call your callback on each of them * and will then free the event when your callback returns * * Note: only one listener thread / event queue ! * * @return 0 on error */ typedef void (*xine_event_listener_cb_t) (void *user_data, const xine_event_t *event); int xine_event_create_listener_thread (xine_event_queue_t *queue, xine_event_listener_cb_t callback, void *user_data) XINE_PROTECTED; /* * send an event to all queues * * the event will be copied so you can free or reuse * *event as soon as xine_event_send returns. */ void xine_event_send (xine_stream_t *stream, const xine_event_t *event) XINE_PROTECTED; /********************************************************************* * OSD (on screen display) * *********************************************************************/ #define XINE_TEXT_PALETTE_SIZE 11 #define XINE_OSD_TEXT1 (0 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT2 (1 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT3 (2 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT4 (3 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT5 (4 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT6 (5 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT7 (6 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT8 (7 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT9 (8 * XINE_TEXT_PALETTE_SIZE) #define XINE_OSD_TEXT10 (9 * XINE_TEXT_PALETTE_SIZE) /* white text, black border, transparent background */ #define XINE_TEXTPALETTE_WHITE_BLACK_TRANSPARENT 0 /* white text, noborder, transparent background */ #define XINE_TEXTPALETTE_WHITE_NONE_TRANSPARENT 1 /* white text, no border, translucid background */ #define XINE_TEXTPALETTE_WHITE_NONE_TRANSLUCID 2 /* yellow text, black border, transparent background */ #define XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT 3 #define XINE_OSD_CAP_FREETYPE2 0x0001 /* freetype2 support compiled in */ #define XINE_OSD_CAP_UNSCALED 0x0002 /* unscaled overlays supp. by vo drv */ #define XINE_OSD_CAP_CUSTOM_EXTENT 0x0004 /* hardware scaled to match video output window */ #define XINE_OSD_CAP_ARGB_LAYER 0x0008 /* supports ARGB true color pixmaps */ #define XINE_OSD_CAP_VIDEO_WINDOW 0x0010 /* can scale video to an area within osd extent */ typedef struct xine_osd_s xine_osd_t; xine_osd_t *xine_osd_new (xine_stream_t *self, int x, int y, int width, int height) XINE_PROTECTED; uint32_t xine_osd_get_capabilities (xine_osd_t *self) XINE_PROTECTED; void xine_osd_draw_point (xine_osd_t *self, int x, int y, int color) XINE_PROTECTED; void xine_osd_draw_line (xine_osd_t *self, int x1, int y1, int x2, int y2, int color) XINE_PROTECTED; void xine_osd_draw_rect (xine_osd_t *self, int x1, int y1, int x2, int y2, int color, int filled ) XINE_PROTECTED; /* x1 and y1 specifies the upper left corner of the text to be rendered */ void xine_osd_draw_text (xine_osd_t *self, int x1, int y1, const char *text, int color_base) XINE_PROTECTED; void xine_osd_draw_bitmap (xine_osd_t *self, uint8_t *bitmap, int x1, int y1, int width, int height, uint8_t *palette_map) XINE_PROTECTED; /* for freetype2 fonts the height is the maximum height for the whole font and not * only for the specified text */ void xine_osd_get_text_size (xine_osd_t *self, const char *text, int *width, int *height) XINE_PROTECTED; /* with freetype2 support compiled in, you can also specify a font file as 'fontname' here */ int xine_osd_set_font (xine_osd_t *self, const char *fontname, int size) XINE_PROTECTED; /* * specifying encoding of texts * "" ... means current locale encoding (default) * NULL ... means latin1 */ void xine_osd_set_encoding(xine_osd_t *self, const char *encoding) XINE_PROTECTED; /* set position were overlay will be blended */ void xine_osd_set_position (xine_osd_t *self, int x, int y) XINE_PROTECTED; void xine_osd_show (xine_osd_t *self, int64_t vpts) XINE_PROTECTED; void xine_osd_show_unscaled (xine_osd_t *self, int64_t vpts) XINE_PROTECTED; void xine_osd_hide (xine_osd_t *self, int64_t vpts) XINE_PROTECTED; /* empty drawing area */ void xine_osd_clear (xine_osd_t *self) XINE_PROTECTED; /* * set on existing text palette * (-1 to set used specified palette) * * color_base specifies the first color index to use for this text * palette. The OSD palette is then modified starting at this * color index, up to the size of the text palette. * * Use OSD_TEXT1, OSD_TEXT2, ... for some preassigned color indices. * * These palettes are not working well with the true type fonts. * First thing is that these fonts cannot have a border. So you get * the best results by loading a linearly blending palette from the * background (at index 0) to the forground color (at index 10). */ void xine_osd_set_text_palette (xine_osd_t *self, int palette_number, int color_base ) XINE_PROTECTED; /* get palette (color and transparency) */ void xine_osd_get_palette (xine_osd_t *self, uint32_t *color, uint8_t *trans) XINE_PROTECTED; void xine_osd_set_palette (xine_osd_t *self, const uint32_t *const color, const uint8_t *const trans ) XINE_PROTECTED; /* * Set an ARGB buffer to be blended into video. * The buffer must stay valid while the OSD is on screen. * Pass a NULL pointer to safely remove the buffer from * the OSD layer. Only the dirty area will be * updated on screen. For convenience the whole * OSD object will be considered dirty when setting * a different buffer pointer. * see also XINE_OSD_CAP_ARGB_LAYER */ void xine_osd_set_argb_buffer(xine_osd_t *self, uint32_t *argb_buffer, int dirty_x, int dirty_y, int dirty_width, int dirty_height) XINE_PROTECTED; /* * define extent of reference coordinate system * for video resolution independent osds. * see also XINE_OSD_CAP_CUSTOM_EXTENT */ void xine_osd_set_extent(xine_osd_t *self, int extent_width, int extent_height) XINE_PROTECTED; /* * define area within osd extent to output * video to while osd is on screen * see also XINE_OSD_CAP_VIDEO_WINDOW */ void xine_osd_set_video_window(xine_osd_t *self, int window_x, int window_y, int window_width, int window_height) XINE_PROTECTED; /* * close osd rendering engine * loaded fonts are unloaded * osd objects are closed */ void xine_osd_free (xine_osd_t *self) XINE_PROTECTED; #ifdef __cplusplus } #endif #endif xine-lib-1.2/src/0000755000175000017500000000000014647725152011453 5ustar memexine-lib-1.2/src/vdr/0000755000175000017500000000000014647725152012246 5ustar memexine-lib-1.2/src/vdr/combined_vdr.h0000644000175000017500000000350214647725152015052 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef __COMBINED_VDR_H #define __COMBINED_VDR_H typedef struct vdr_set_video_window_data_s { int32_t x; int32_t y; int32_t w; int32_t h; int32_t w_ref; int32_t h_ref; } vdr_set_video_window_data_t; typedef struct vdr_frame_size_changed_data_s { int32_t x; int32_t y; int32_t w; int32_t h; double r; } vdr_frame_size_changed_data_t; typedef struct vdr_select_audio_data_s { uint8_t channels; } vdr_select_audio_data_t; inline static int vdr_is_vdr_stream(xine_stream_t *stream) { if (!stream || !stream->input_plugin || !stream->input_plugin->input_class) { return 0; } if (stream->input_plugin->input_class->identifier && 0 == strcmp(stream->input_plugin->input_class->identifier, "VDR")) return 1; return 0; } /* plugin class initialization function */ void *vdr_input_init_plugin(xine_t *xine, const void *data); void *vdr_video_init_plugin(xine_t *xine, const void *data); void *vdr_audio_init_plugin(xine_t *xine, const void *data); #endif /* __COMBINED_VDR_H */ xine-lib-1.2/src/vdr/combined_vdr.c0000644000175000017500000000345014647725152015047 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * plugins for VDR */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "combined_vdr.h" static const post_info_t vdr_video_special_info = { XINE_POST_TYPE_VIDEO_FILTER }; static const post_info_t vdr_audio_special_info = { XINE_POST_TYPE_AUDIO_FILTER }; /* exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type , API, "name" , version , special_info , init_function */ { PLUGIN_INPUT, 18, "VDR" , XINE_VERSION_CODE, NULL , &vdr_input_init_plugin }, { PLUGIN_POST , 10, "vdr" , XINE_VERSION_CODE, &vdr_video_special_info, &vdr_video_init_plugin }, { PLUGIN_POST , 10, "vdr_video", XINE_VERSION_CODE, &vdr_video_special_info, &vdr_video_init_plugin }, { PLUGIN_POST , 10, "vdr_audio", XINE_VERSION_CODE, &vdr_audio_special_info, &vdr_audio_init_plugin }, { PLUGIN_NONE , 0, NULL , 0 , NULL , NULL } }; xine-lib-1.2/src/vdr/input_vdr.c0000644000175000017500000025045114647725152014433 0ustar meme/* * Copyright (C) 2003-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* NOTE: This will bend the xine engine into a certain direction (just to avoid the * term "misuse"). Demux keeps running all the time. Its the vdr server that * performs seeks, stream switches, still frames, trick play frames etc. * It then muxes the result down the line sequentially. For the demuxer, most stuff * looks like ordinary absolute discontinuities. We need to watch the control * messages coming through a side channel, and inject apropriate xine engine calls * manually. In reverse, we listen to xine events, and send back vdr keys. * "Trick play" is turned on and off by server. When on, xine shall just play all * frames as if they had perfectly consecutive time stamps. We still need to register * first discontinuity early because server will wait for it, and video decoder may * delay it -> freeze. * Issue #2: xine engine now uses a more efficient buffering scheme. Audio fifo * default now is 700*2k with soft start vs 230*8k fixed. This is needed to support * modern fragment streaming protocols. It also helps live DVB radio, and it speeds * up seeking. However, vdr seems to freeze from it sometimes. We work around it * by using fifo->buffer_pool_size_alloc (fifo, need), and by registering a dummy * alloc callback that disables file_buf_ctrl soft start. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #include #ifdef HAVE_NETDB_H #include #endif #ifdef WIN32 #include #endif #define LOG_MODULE "input_vdr" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "combined_vdr.h" #define VDR_DISC_START (('V' << 24) | ('D' << 16) | ('R' << 8) | 1) #define VDR_DISC_STOP (('V' << 24) | ('D' << 16) | ('R' << 8) | 0) #define VDR_MAX_NUM_WINDOWS 16 #define VDR_ABS_FIFO_DIR "/tmp/vdr-xine" #define BUF_SIZE 1024 #define LOG_OSD(x) /* #define LOG_OSD(x) x */ typedef struct vdr_input_plugin_s vdr_input_plugin_t; /* This is our relay metronom, built on top of the engine one. * src/xine-engine/metronom.c uses a much more complex algorithm now. * One goal is to avoid unnecessary waiting. Thus lets not wait * ourselves here, and detect complete discontinuity pairs instead. */ typedef struct { metronom_t metronom; metronom_t *stream_metronom; vdr_input_plugin_t *input; pthread_mutex_t mutex; struct { int disc_num; int seek; int on; } audio, video; /* -1 = unset, 0 = off, 1 = on, 2 = first disc sent. */ int trick_new_mode, trick_mode; } vdr_metronom_t; typedef struct vdr_osd_s { xine_osd_t *window; uint32_t *argb_buffer[ 2 ]; int width; int height; } vdr_osd_t; /* This struct shall provide: * - backwards translation current vpts -> stream pts, and * - the information whether there are jumps that are not yet reached. */ typedef struct { int64_t offset; /* vpts - pts */ int64_t vpts; /* the vpts time that offset shall take effect from */ } vdr_vpts_offset_t; struct vdr_input_plugin_s { input_plugin_t input_plugin; xine_stream_t *stream; xine_stream_t *stream_external; int is_netvdr; int fh; int fh_control; int fh_result; int fh_event; char *mrl; off_t curpos; enum funcs cur_func; off_t cur_size; off_t cur_done; vdr_osd_t osd[ VDR_MAX_NUM_WINDOWS ]; uint32_t *osd_buffer; uint32_t osd_buffer_size; /** << in bytes */ uint8_t osd_unscaled_blending; uint8_t osd_supports_custom_extent; uint8_t osd_supports_argb_layer; uint8_t audio_channels; uint8_t mute_mode; uint8_t volume_mode; int last_volume; vdr_frame_size_changed_data_t frame_size; pthread_t rpc_thread; int rpc_thread_created; int rpc_thread_shutdown; pthread_mutex_t rpc_thread_shutdown_lock; pthread_cond_t rpc_thread_shutdown_cond; int startup_phase; xine_event_queue_t *event_queue; xine_event_queue_t *event_queue_external; pthread_mutex_t adjust_zoom_lock; uint16_t image4_3_zoom_x; uint16_t image4_3_zoom_y; uint16_t image16_9_zoom_x; uint16_t image16_9_zoom_y; uint8_t find_sync_point; pthread_mutex_t find_sync_point_lock; vdr_metronom_t metronom; int last_disc_type; #define OFFS_RING_LD 7 #define OFFS_RING_NUM (1 << OFFS_RING_LD) #define OFFS_RING_MASK (OFFS_RING_NUM - 1) struct { vdr_vpts_offset_t items[OFFS_RING_NUM]; int read; int write; pthread_mutex_t lock; pthread_cond_t changed; } vpts_offs_queue; int video_window_active; vdr_set_video_window_data_t video_window_event_data; uint8_t seek_buf[BUF_SIZE]; }; static void input_vdr_dummy (fifo_buffer_t *fifo, void *data) { (void)fifo; (void)data; } static void trick_speed_send_event (vdr_input_plugin_t *this, int mode) { xine_event_t event; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: trick play mode now %d.\n", mode); _x_demux_seek (this->stream, 0, 0, 0); event.type = XINE_EVENT_VDR_TRICKSPEEDMODE; event.data = NULL; event.data_length = mode; xine_event_send (this->stream, &event); } static int vdr_write(int f, void *b, int n) { int t = 0, r; while (t < n) { /* * System calls are not a thread cancellation point in Linux * pthreads. However, the RT signal sent to cancel the thread * will cause recv() to return with EINTR, and we can manually * check cancellation. */ pthread_testcancel(); r = write(f, ((char *)b) + t, n - t); pthread_testcancel(); if (r < 0 && (errno == EINTR || errno == EAGAIN)) { continue; } if (r < 0) return r; t += r; } return t; } static int internal_write_event_play_external(vdr_input_plugin_t *this, uint32_t key); static void event_handler_external(void *user_data, const xine_event_t *event) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)user_data; uint32_t key = key_none; /* printf("event_handler_external(): event->type: %d\n", event->type); */ switch (event->type) { case XINE_EVENT_UI_PLAYBACK_FINISHED: break; default: return; } if (0 != internal_write_event_play_external(this, key)) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: input event write: %s.\n"), LOG_MODULE, strerror(errno)); } static void external_stream_stop(vdr_input_plugin_t *this) { if (this->stream_external) { xine_stop(this->stream_external); xine_close(this->stream_external); if (this->event_queue_external) { xine_event_dispose_queue(this->event_queue_external); this->event_queue_external = NULL; } _x_demux_flush_engine(this->stream_external); xine_dispose(this->stream_external); this->stream_external = NULL; } } static void external_stream_play(vdr_input_plugin_t *this, char *file_name) { external_stream_stop(this); this->stream_external = xine_stream_new(this->stream->xine, this->stream->audio_out, this->stream->video_out); this->event_queue_external = xine_event_new_queue(this->stream_external); xine_event_create_listener_thread(this->event_queue_external, event_handler_external, this); if (!xine_open(this->stream_external, file_name) || !xine_play(this->stream_external, 0, 0)) { uint32_t key = key_none; if ( 0 != internal_write_event_play_external(this, key)) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: input event write: %s.\n"), LOG_MODULE, strerror(errno)); } } static ssize_t vdr_read_abort (xine_stream_t *stream, int fd, uint8_t *buf, size_t todo) { ssize_t ret; while (1) { /* * System calls are not a thread cancellation point in Linux * pthreads. However, the RT signal sent to cancel the thread * will cause recv() to return with EINTR, and we can manually * check cancellation. */ pthread_testcancel(); ret = _x_read_abort (stream, fd, (char *)buf, todo); pthread_testcancel(); if (ret < 0 && (errno == EINTR || errno == EAGAIN)) { continue; } break; } return ret; } #define READ_DATA_OR_FAIL(kind, log) \ data_##kind##_t *data = &data_union.kind; \ { \ log; \ n = vdr_read_abort (this->stream, this->fh_control, (uint8_t *)data + sizeof (data->header), sizeof (*data) - sizeof (data->header)); \ if (n != sizeof (*data) - sizeof (data->header)) \ return -1; \ \ this->cur_size -= n; \ } static double _now() { struct timeval tv; gettimeofday(&tv, 0); return (tv.tv_sec * 1000000.0 + tv.tv_usec) / 1000.0; } static void adjust_zoom(vdr_input_plugin_t *this) { pthread_mutex_lock(&this->adjust_zoom_lock); if (this->image4_3_zoom_x && this->image4_3_zoom_y && this->image16_9_zoom_x && this->image16_9_zoom_y) { int ratio = (int)(10000 * this->frame_size.r + 0.5); int matches4_3 = abs(ratio - 13333); int matches16_9 = abs(ratio - 17778); /* fprintf(stderr, "ratio: %d\n", ratio); */ if (matches4_3 < matches16_9) { xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, this->image4_3_zoom_x); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, this->image4_3_zoom_y); } else { xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, this->image16_9_zoom_x); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, this->image16_9_zoom_y); } } pthread_mutex_unlock(&this->adjust_zoom_lock); } static void vdr_vpts_offset_queue_init (vdr_input_plugin_t *this) { pthread_mutex_init (&this->vpts_offs_queue.lock, NULL); pthread_cond_init (&this->vpts_offs_queue.changed, NULL); this->metronom.stream_metronom = this->stream->metronom; this->vpts_offs_queue.read = 0; this->vpts_offs_queue.write = 1; this->vpts_offs_queue.items[0].offset = this->metronom.stream_metronom->get_option (this->metronom.stream_metronom, METRONOM_VPTS_OFFSET); this->vpts_offs_queue.items[0].vpts = xine_get_current_vpts (this->stream); } static void vdr_vpts_offset_queue_deinit (vdr_input_plugin_t *this) { pthread_cond_destroy (&this->vpts_offs_queue.changed); pthread_mutex_destroy (&this->vpts_offs_queue.lock); } static void vdr_vpts_offset_queue_process (vdr_input_plugin_t *this, int64_t vpts) { int i = this->vpts_offs_queue.read; while (1) { int j = (i + 1) & OFFS_RING_MASK; if (j == this->vpts_offs_queue.write) break; if (this->vpts_offs_queue.items[j].vpts > vpts) break; i = j; } this->vpts_offs_queue.read = i; } static void vdr_vpts_offset_queue_add_int (vdr_input_plugin_t *this, int64_t pts) { int64_t offset = this->metronom.stream_metronom->get_option (this->metronom.stream_metronom, METRONOM_VPTS_OFFSET); int64_t vpts = pts + offset; this->vpts_offs_queue.items[this->vpts_offs_queue.write].offset = offset; this->vpts_offs_queue.items[this->vpts_offs_queue.write].vpts = vpts; this->vpts_offs_queue.write = (this->vpts_offs_queue.write + 1) & OFFS_RING_MASK; /* queue full, make some room */ if (this->vpts_offs_queue.write == this->vpts_offs_queue.read) vdr_vpts_offset_queue_process (this, xine_get_current_vpts (this->stream)); } static int vdr_vpts_offset_queue_ask (vdr_input_plugin_t *this, int64_t *pts) { int64_t vpts = xine_get_current_vpts (this->stream); vdr_vpts_offset_queue_process (this, vpts); *pts = vpts - this->vpts_offs_queue.items[this->vpts_offs_queue.read].offset; return ((this->vpts_offs_queue.write - this->vpts_offs_queue.read) & OFFS_RING_MASK) > 1; } static void vdr_vpts_offset_queue_purge (vdr_input_plugin_t *this) { this->vpts_offs_queue.read = (this->vpts_offs_queue.write - 1) & OFFS_RING_MASK; } static void vdr_start_buffers (vdr_input_plugin_t *this) { /* Make sure this sends DISC_STREAMSTART. */ int gs = xine_get_param (this->stream, XINE_PARAM_GAPLESS_SWITCH); if (gs) { xine_set_param (this->stream, XINE_PARAM_GAPLESS_SWITCH, 0); _x_demux_control_start (this->stream); xine_set_param (this->stream, XINE_PARAM_GAPLESS_SWITCH, gs); } else { _x_demux_control_start (this->stream); } } static ssize_t vdr_execute_rpc_command (vdr_input_plugin_t *this) { data_union_t data_union; ssize_t n; n = vdr_read_abort (this->stream, this->fh_control, (uint8_t *)&data_union, sizeof (data_union.header)); if (n != sizeof (data_union.header)) return -1; this->cur_func = data_union.header.func; this->cur_size = data_union.header.len - sizeof (data_union.header); this->cur_done = 0; switch (this->cur_func) { case func_nop: { READ_DATA_OR_FAIL(nop, lprintf("got NOP\n")); } break; case func_osd_new: { READ_DATA_OR_FAIL(osd_new, LOG_OSD(lprintf("got OSDNEW\n"))); /* LOG_OSD(lprintf("... (%d,%d)-(%d,%d)@(%d,%d)\n", data->x, data->y, data->width, data->height, data->w_ref, data->h_ref)); fprintf(stderr, "vdr: osdnew %d\n", data->window); */ if (data->window >= VDR_MAX_NUM_WINDOWS) return -1; if (NULL != this->osd[ data->window ].window) return -1; this->osd[ data->window ].window = xine_osd_new(this->stream , data->x , data->y , data->width , data->height); this->osd[ data->window ].width = data->width; this->osd[ data->window ].height = data->height; if (NULL == this->osd[ data->window ].window) return -1; if (this->osd_supports_custom_extent && data->w_ref > 0 && data->h_ref > 0) xine_osd_set_extent(this->osd[ data->window ].window, data->w_ref, data->h_ref); } break; case func_osd_free: { int i; READ_DATA_OR_FAIL(osd_free, LOG_OSD(lprintf("got OSDFREE\n"))); /* fprintf(stderr, "vdr: osdfree %d\n", data->window); */ if (data->window >= VDR_MAX_NUM_WINDOWS) return -1; if (NULL != this->osd[ data->window ].window) xine_osd_free(this->osd[ data->window ].window); this->osd[ data->window ].window = NULL; for (i = 0; i < 2; i++) { free(this->osd[ data->window ].argb_buffer[ i ]); this->osd[ data->window ].argb_buffer[ i ] = NULL; } } break; case func_osd_show: { READ_DATA_OR_FAIL(osd_show, LOG_OSD(lprintf("got OSDSHOW\n"))); /* fprintf(stderr, "vdr: osdshow %d\n", data->window); */ if (data->window >= VDR_MAX_NUM_WINDOWS) return -1; if (NULL != this->osd[ data->window ].window) { #ifdef XINE_OSD_CAP_VIDEO_WINDOW xine_osd_set_video_window(this->osd[ data->window ].window , this->video_window_active ? this->video_window_event_data.x : 0 , this->video_window_active ? this->video_window_event_data.y : 0 , this->video_window_active ? this->video_window_event_data.w : 0 , this->video_window_active ? this->video_window_event_data.h : 0); #endif if (this->osd_unscaled_blending) xine_osd_show_unscaled(this->osd[ data->window ].window, 0); else xine_osd_show(this->osd[ data->window ].window, 0); } } break; case func_osd_hide: { READ_DATA_OR_FAIL(osd_hide, LOG_OSD(lprintf("got OSDHIDE\n"))); /* fprintf(stderr, "vdr: osdhide %d\n", data->window); */ if (data->window >= VDR_MAX_NUM_WINDOWS) return -1; if (NULL != this->osd[ data->window ].window) xine_osd_hide(this->osd[ data->window ].window, 0); } break; case func_osd_flush: { double _t1/*, _t2*/; int _n = 0; /*int _to = 0;*/ int r = 0; READ_DATA_OR_FAIL(osd_flush, LOG_OSD(lprintf("got OSDFLUSH\n"))); /* fprintf(stderr, "vdr: osdflush +\n"); */ _t1 = _now(); while ((r = _x_query_unprocessed_osd_events(this->stream))) { break; if ((_now() - _t1) > 200) { /*_to = 1;*/ break; } /* fprintf(stderr, "redraw_needed: 1\n"); */ /* sched_yield(); */ xine_usec_sleep(5000); _n++; } /* _t2 = _now(); fprintf(stderr, "vdr: osdflush: n: %d, %.1lf, timeout: %d, result: %d\n", _n, _t2 - _t1, _to, r); */ /* fprintf(stderr, "redraw_needed: 0\n"); fprintf(stderr, "vdr: osdflush -\n"); */ } break; case func_osd_set_position: { READ_DATA_OR_FAIL(osd_set_position, LOG_OSD(lprintf("got OSDSETPOSITION\n"))); /* fprintf(stderr, "vdr: osdsetposition %d\n", data->window); */ if (data->window >= VDR_MAX_NUM_WINDOWS) return -1; if (NULL != this->osd[ data->window ].window) xine_osd_set_position(this->osd[ data->window ].window, data->x, data->y); } break; case func_osd_draw_bitmap: { READ_DATA_OR_FAIL(osd_draw_bitmap, LOG_OSD(lprintf("got OSDDRAWBITMAP\n"))); /* fprintf(stderr, "vdr: osddrawbitmap %d, %d, %d, %d, %d, %d\n", data->window, data->x, data->y, data->width, data->height, data->argb); */ if (this->osd_buffer_size < this->cur_size) { free(this->osd_buffer); this->osd_buffer_size = 0; this->osd_buffer = calloc(1, this->cur_size); if (!this->osd_buffer) return -1; this->osd_buffer_size = this->cur_size; } n = vdr_read_abort (this->stream, this->fh_control, (uint8_t *)this->osd_buffer, this->cur_size); if (n != this->cur_size) return -1; this->cur_size -= n; if (data->window >= VDR_MAX_NUM_WINDOWS) return -1; if (NULL != this->osd[ data->window ].window) { vdr_osd_t *osd = &this->osd[ data->window ]; if (data->argb) { int i; for (i = 0; i < 2; i++) { if (!osd->argb_buffer[i]) osd->argb_buffer[i] = calloc (1, osd->width * osd->height * sizeof (*osd->argb_buffer[0])); if (osd->argb_buffer[i]) { uint32_t *src = this->osd_buffer; uint32_t *dst = osd->argb_buffer[i] + data->y * osd->width + data->x; int y; if (data->width == osd->width) { xine_fast_memcpy (dst, src, data->width * data->height * sizeof (*dst)); } else { for (y = 0; y < data->height; y++) { xine_fast_memcpy (dst, src, data->width * sizeof (*dst)); dst += osd->width; src += data->width; } } if (i == 0) xine_osd_set_argb_buffer (osd->window, osd->argb_buffer[i], data->x, data->y, data->width, data->height); } } /* flip render and display buffer */ { uint32_t *argb_buffer = osd->argb_buffer[0]; osd->argb_buffer[0] = osd->argb_buffer[1]; osd->argb_buffer[1] = argb_buffer; } } else xine_osd_draw_bitmap (osd->window, (uint8_t *)this->osd_buffer, data->x, data->y, data->width, data->height, 0); } } break; case func_set_color: { uint32_t vdr_color[ 256 ]; READ_DATA_OR_FAIL(set_color, lprintf("got SETCOLOR\n")); if (((data->num + 1) * sizeof (uint32_t)) != (unsigned int)this->cur_size) return -1; n = vdr_read_abort (this->stream, this->fh_control, (uint8_t *)&vdr_color[ data->index ], this->cur_size); if (n != this->cur_size) return -1; this->cur_size -= n; if (data->window >= VDR_MAX_NUM_WINDOWS) return -1; if (NULL != this->osd[ data->window ].window) { uint32_t color[ 256 ]; uint8_t trans[ 256 ]; xine_osd_get_palette(this->osd[ data->window ].window, color, trans); { int i; for (i = data->index; i <= (data->index + data->num); i++) { int a = (vdr_color[ i ] & 0xff000000) >> 0x18; int r = (vdr_color[ i ] & 0x00ff0000) >> 0x10; int g = (vdr_color[ i ] & 0x0000ff00) >> 0x08; int b = (vdr_color[ i ] & 0x000000ff) >> 0x00; int y = (( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16; int cr = ((112 * r - 94 * g - 18 * b + 128) >> 8) + 128; int cb = ((-38 * r - 74 * g + 112 * b + 128) >> 8) + 128; uint8_t *dst = (uint8_t *)&color[ i ]; *dst++ = cb; *dst++ = cr; *dst++ = y; *dst++ = 0; trans[ i ] = a >> 4; } } xine_osd_set_palette(this->osd[ data->window ].window, color, trans); } } break; case func_play_external: { char file_name[ 1024 ]; int file_name_len = 0; READ_DATA_OR_FAIL(play_external, lprintf("got PLAYEXTERNAL\n")); file_name_len = this->cur_size; if (0 != file_name_len) { if (file_name_len <= 1 || file_name_len > (int)sizeof (file_name)) { return -1; } n = vdr_read_abort (this->stream, this->fh_control, (uint8_t *)file_name, file_name_len); if (n != file_name_len) return -1; if (file_name[ file_name_len - 1 ] != '\0') return -1; this->cur_size -= n; } lprintf((file_name_len > 0) ? "----------- play external: %s\n" : "---------- stop external\n", file_name); if (file_name_len > 0) external_stream_play(this, file_name); else external_stream_stop(this); } break; case func_clear: { READ_DATA_OR_FAIL(clear, lprintf("got CLEAR\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: clear (%d, %d, %u)\n", (int)data->n, (int)data->s, (unsigned int)data->i); { /* make sure engine is not paused. */ int orig_speed = xine_get_param(this->stream, XINE_PARAM_FINE_SPEED); if (orig_speed <= XINE_FINE_SPEED_NORMAL / 3) xine_set_param (this->stream, XINE_PARAM_FINE_SPEED, XINE_FINE_SPEED_NORMAL); /* server seems to always send this 2 times: with s == 0, then again with s == 1. * lets try and ignore the latter. */ if (!data->s) { /* let vdr_plugin_read () seek (skip) to server generated pes padding of 6 + 0xff00 + i bytes: * 00 00 01 be ff ... * this flushes the main pipe, and tells demux about this. */ pthread_mutex_lock (&this->find_sync_point_lock); this->find_sync_point = data->i; pthread_mutex_unlock (&this->find_sync_point_lock); /* if (!this->dont_change_xine_volume) xine_set_param(this->stream, XINE_PARAM_AUDIO_VOLUME, 0); */ /* start buffers are needed at least to reset audio track map. * demux_pes does pass pes audio id as track verbatim, and a * switch from a52 to mp2 or back would add a new track instead * of replacing the old one. * start bufs will force metronom DISC_STREAMSTART wait later. * we need to make sure vdr does not pause inbetween, and freeze. * workaround: send start first, then flush. flush will keep the * start bufs, and wait until both decoders have seen all this. */ /* fprintf(stderr, "=== CLEAR(%d.1)\n", data->n); */ vdr_start_buffers (this); _x_demux_flush_engine (this->stream); /* fprintf(stderr, "=== CLEAR(%d.2)\n", data->n); */ /* _x_demux_seek (this->stream, 0, 0, 0); */ /* fprintf(stderr, "=== CLEAR(%d.3)\n", data->n); */ /* XXX: why is this needed? */ pthread_mutex_lock (&this->metronom.mutex); this->metronom.audio.seek = 1; this->metronom.video.seek = 1; pthread_mutex_unlock (&this->metronom.mutex); pthread_mutex_lock (&this->vpts_offs_queue.lock); this->last_disc_type = DISC_STREAMSTART; pthread_mutex_unlock (&this->vpts_offs_queue.lock); _x_stream_info_reset(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE); /* fprintf(stderr, "=== CLEAR(%d.4)\n", data->n); */ _x_meta_info_reset (this->stream, XINE_META_INFO_AUDIOCODEC); /* fprintf(stderr, "=== CLEAR(%d.5)\n", data->n); */ _x_trigger_relaxed_frame_drop_mode(this->stream); /* _x_reset_relaxed_frame_drop_mode(this->stream); */ /* if (!this->dont_change_xine_volume) xine_set_param(this->stream, XINE_PARAM_AUDIO_VOLUME, this->last_volume); */ } /* fprintf(stderr, "--- CLEAR(%d%c)\n", data->n, data->s ? 'b' : 'a'); */ if (orig_speed <= XINE_FINE_SPEED_NORMAL / 3) { xine_set_param (this->stream, XINE_PARAM_FINE_SPEED, orig_speed); if (orig_speed == 0) /* make sure decoders are responsive. */ xine_set_param (this->stream, XINE_PARAM_FINE_SPEED, XINE_LIVE_PAUSE_ON); } } } break; case func_first_frame: { READ_DATA_OR_FAIL(first_frame, lprintf("got FIRST FRAME\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: first_frame ()\n"); _x_trigger_relaxed_frame_drop_mode(this->stream); /* _x_reset_relaxed_frame_drop_mode(this->stream); */ } break; case func_still_frame: { READ_DATA_OR_FAIL(still_frame, lprintf("got STILL FRAME\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: still_frame ()\n"); _x_reset_relaxed_frame_drop_mode(this->stream); } break; case func_set_video_window: { READ_DATA_OR_FAIL(set_video_window, lprintf("got SET VIDEO WINDOW\n")); /* fprintf(stderr, "svw: (%d, %d)x(%d, %d), (%d, %d)\n", data->x, data->y, data->w, data->h, data->wRef, data->hRef); */ { xine_event_t event; this->video_window_active = (data->x != 0 || data->y != 0 || data->w != data->w_ref || data->h != data->h_ref); this->video_window_event_data.x = data->x; this->video_window_event_data.y = data->y; this->video_window_event_data.w = data->w; this->video_window_event_data.h = data->h; this->video_window_event_data.w_ref = data->w_ref; this->video_window_event_data.h_ref = data->h_ref; event.type = XINE_EVENT_VDR_SETVIDEOWINDOW; event.data = &this->video_window_event_data; event.data_length = sizeof (this->video_window_event_data); xine_event_send(this->stream, &event); } } break; case func_select_audio: { READ_DATA_OR_FAIL(select_audio, lprintf("got SELECT AUDIO\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: select_audio (%d)\n", data->channels); this->audio_channels = data->channels; { xine_event_t event; vdr_select_audio_data_t event_data; event_data.channels = this->audio_channels; event.type = XINE_EVENT_VDR_SELECTAUDIO; event.data = &event_data; event.data_length = sizeof (event_data); xine_event_send(this->stream, &event); } } break; case func_trick_speed_mode: { READ_DATA_OR_FAIL(trick_speed_mode, lprintf("got TRICK SPEED MODE\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: trick_speed_mode (%d)\n", (int)data->on); pthread_mutex_lock (&this->metronom.mutex); if (this->metronom.audio.disc_num != this->metronom.video.disc_num) { this->metronom.trick_new_mode = data->on; pthread_mutex_unlock (&this->metronom.mutex); } else { this->metronom.trick_mode = data->on; this->metronom.trick_new_mode = -1; pthread_mutex_unlock (&this->metronom.mutex); trick_speed_send_event (this, this->metronom.trick_mode); } } break; case func_flush: { READ_DATA_OR_FAIL(flush, lprintf("got FLUSH\n")); if (!data->just_wait) { if (this->stream->video_fifo) { buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo); if (!buf) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: buffer_pool_alloc() failed!\n"), LOG_MODULE); return -1; } buf->type = BUF_CONTROL_FLUSH_DECODER; this->stream->video_fifo->put(this->stream->video_fifo, buf); } } { /*double _t1, _t2*/; int _n = 0; int vb = -1, ab = -1, vf = -1, af = -1; uint8_t timed_out = 0; struct timeval now, then; if (data->ms_timeout >= 0) { gettimeofday(&now, 0); then = now; then.tv_usec += (data->ms_timeout % 1000) * 1000; then.tv_sec += (data->ms_timeout / 1000); if (then.tv_usec >= 1000000) { then.tv_usec -= 1000000; then.tv_sec += 1; } } else { then.tv_usec = 0; then.tv_sec = 0; } /*_t1 = _now();*/ while (1) { _x_query_buffer_usage(this->stream, &vb, &ab, &vf, &af); if (vb <= 0 && ab <= 0 && vf <= 0 && af <= 0) break; if (data->ms_timeout >= 0 && timercmp(&now, &then, >=)) { timed_out++; break; } /* sched_yield(); */ xine_usec_sleep(5000); _n++; if (data->ms_timeout >= 0) gettimeofday(&now, 0); } /*_t2 = _now();*/ /* fprintf(stderr, "vdr: flush: n: %d, %.1lf\n", _n, _t2 - _t1); */ xprintf(this->stream->xine , XINE_VERBOSITY_LOG , _("%s: flush buffers (vb: %d, ab: %d, vf: %d, af: %d) %s.\n") , LOG_MODULE, vb, ab, vf, af , (timed_out ? "timed out" : "done")); { result_flush_t result_flush; result_flush.header.func = data->header.func; result_flush.header.len = sizeof (result_flush); result_flush.timed_out = timed_out; if (sizeof (result_flush) != vdr_write(this->fh_result, &result_flush, sizeof (result_flush))) return -1; } } } break; case func_mute: { READ_DATA_OR_FAIL(mute, lprintf("got MUTE\n")); { int param_mute = (this->volume_mode == XINE_VDR_VOLUME_CHANGE_SW) ? XINE_PARAM_AUDIO_AMP_MUTE : XINE_PARAM_AUDIO_MUTE; xine_set_param(this->stream, param_mute, data->mute); } } break; case func_set_volume: { /*double t3, t2, t1, t0;*/ READ_DATA_OR_FAIL(set_volume, lprintf("got SETVOLUME\n")); /*t0 = _now();*/ { int change_volume = (this->volume_mode != XINE_VDR_VOLUME_IGNORE); int do_mute = (this->last_volume != 0 && 0 == data->volume); int do_unmute = (this->last_volume <= 0 && 0 != data->volume); int report_change = 0; int param_mute = (this->volume_mode == XINE_VDR_VOLUME_CHANGE_SW) ? XINE_PARAM_AUDIO_AMP_MUTE : XINE_PARAM_AUDIO_MUTE; int param_volume = (this->volume_mode == XINE_VDR_VOLUME_CHANGE_SW) ? XINE_PARAM_AUDIO_AMP_LEVEL : XINE_PARAM_AUDIO_VOLUME; this->last_volume = data->volume; if (do_mute || do_unmute) { switch (this->mute_mode) { case XINE_VDR_MUTE_EXECUTE: report_change = 1; xine_set_param(this->stream, param_mute, do_mute); /* fall through */ case XINE_VDR_MUTE_IGNORE: if (do_mute) change_volume = 0; break; case XINE_VDR_MUTE_SIMULATE: change_volume = 1; break; default: return -1; }; } /*t1 = _now();*/ if (change_volume) { report_change = 1; xine_set_param(this->stream, param_volume, this->last_volume); } /*t2 = _now();*/ if (report_change && this->volume_mode != XINE_VDR_VOLUME_CHANGE_SW) { xine_event_t event; xine_audio_level_data_t data; data.left = data.right = xine_get_param(this->stream, param_volume); data.mute = xine_get_param(this->stream, param_mute); /*t3 = _now();*/ event.type = XINE_EVENT_AUDIO_LEVEL; event.data = &data; event.data_length = sizeof (data); xine_event_send(this->stream, &event); } } /* fprintf(stderr, "volume: %6.3lf ms, %6.3lf ms, %6.3lf ms\n", t1 - t0, t2 - t1, t3 - t2); */ } break; case func_set_speed: { READ_DATA_OR_FAIL(set_speed, lprintf("got SETSPEED\n")); lprintf("... got SETSPEED %d\n", data->speed); if (data->speed != xine_get_param (this->stream, XINE_PARAM_FINE_SPEED)) { xine_set_param (this->stream, XINE_PARAM_FINE_SPEED, data->speed); if (data->speed == 0) /* make sure decoders are responsive. */ xine_set_param (this->stream, XINE_PARAM_FINE_SPEED, XINE_LIVE_PAUSE_ON); } } break; case func_set_prebuffer: { READ_DATA_OR_FAIL(set_prebuffer, lprintf("got SETPREBUFFER\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: set_prebuffer (%d)\n", (int)data->prebuffer); xine_set_param (this->stream, XINE_PARAM_METRONOM_PREBUFFER, data->prebuffer); } break; case func_metronom: { READ_DATA_OR_FAIL(metronom, lprintf("got METRONOM\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: newpts (%"PRId64", 0x%08x)\n", data->pts, (unsigned int)data->flags); _x_demux_control_newpts(this->stream, data->pts, data->flags); } break; case func_start: { READ_DATA_OR_FAIL(start, lprintf("got START\n")); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: start ()\n"); vdr_start_buffers (this); _x_demux_seek(this->stream, 0, 0, 0); } break; case func_wait: { READ_DATA_OR_FAIL(wait, lprintf("got WAIT\n")); { result_wait_t result_wait; result_wait.header.func = data->header.func; result_wait.header.len = sizeof (result_wait); if (sizeof (result_wait) != vdr_write(this->fh_result, &result_wait, sizeof (result_wait))) return -1; if (data->id == 1) this->startup_phase = 0; } } break; case func_setup: { READ_DATA_OR_FAIL(setup, lprintf("got SETUP\n")); this->osd_unscaled_blending = data->osd_unscaled_blending; this->volume_mode = data->volume_mode; this->mute_mode = data->mute_mode; this->image4_3_zoom_x = data->image4_3_zoom_x; this->image4_3_zoom_y = data->image4_3_zoom_y; this->image16_9_zoom_x = data->image16_9_zoom_x; this->image16_9_zoom_y = data->image16_9_zoom_y; adjust_zoom(this); } break; case func_grab_image: { READ_DATA_OR_FAIL(grab_image, lprintf("got GRABIMAGE\n")); { off_t ret_val = -1; xine_current_frame_data_t frame_data; memset(&frame_data, 0, sizeof (frame_data)); if (xine_get_current_frame_data(this->stream, &frame_data, XINE_FRAME_DATA_ALLOCATE_IMG)) { if (frame_data.ratio_code == XINE_VO_ASPECT_SQUARE) frame_data.ratio_code = 10000; else if (frame_data.ratio_code == XINE_VO_ASPECT_4_3) frame_data.ratio_code = 13333; else if (frame_data.ratio_code == XINE_VO_ASPECT_ANAMORPHIC) frame_data.ratio_code = 17778; else if (frame_data.ratio_code == XINE_VO_ASPECT_DVB) frame_data.ratio_code = 21100; } if (!frame_data.img) memset(&frame_data, 0, sizeof (frame_data)); { result_grab_image_t result_grab_image; result_grab_image.header.func = data->header.func; result_grab_image.header.len = sizeof (result_grab_image) + frame_data.img_size; result_grab_image.width = frame_data.width; result_grab_image.height = frame_data.height; result_grab_image.ratio = frame_data.ratio_code; result_grab_image.format = frame_data.format; result_grab_image.interlaced = frame_data.interlaced; result_grab_image.crop_left = frame_data.crop_left; result_grab_image.crop_right = frame_data.crop_right; result_grab_image.crop_top = frame_data.crop_top; result_grab_image.crop_bottom = frame_data.crop_bottom; if (sizeof (result_grab_image) == vdr_write(this->fh_result, &result_grab_image, sizeof (result_grab_image))) { if (!frame_data.img_size || (frame_data.img_size == vdr_write(this->fh_result, frame_data.img, frame_data.img_size))) ret_val = 0; } } free(frame_data.img); if (ret_val != 0) return ret_val; } } break; case func_get_pts: { READ_DATA_OR_FAIL(get_pts, lprintf("got GETPTS\n")); { result_get_pts_t result_get_pts; result_get_pts.header.func = data->header.func; result_get_pts.header.len = sizeof (result_get_pts); pthread_mutex_lock(&this->vpts_offs_queue.lock); if (this->last_disc_type == DISC_STREAMSTART && data->ms_timeout > 0) { struct timespec abstime; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: get_pts (%d ms)\n", (int)data->ms_timeout); { struct timeval now; gettimeofday(&now, 0); abstime.tv_sec = now.tv_sec + data->ms_timeout / 1000; abstime.tv_nsec = now.tv_usec * 1000 + (data->ms_timeout % 1000) * 1e6; if (abstime.tv_nsec > 1e9) { abstime.tv_nsec -= 1e9; abstime.tv_sec++; } } while (this->last_disc_type == DISC_STREAMSTART) { if (0 != pthread_cond_timedwait (&this->vpts_offs_queue.changed, &this->vpts_offs_queue.lock, &abstime)) break; } } if (this->last_disc_type == DISC_STREAMSTART) { result_get_pts.pts = -1; result_get_pts.queued = 0; } else { int64_t pts; result_get_pts.queued = vdr_vpts_offset_queue_ask (this, &pts); result_get_pts.pts = pts & ((1ll << 33) - 1); /* fprintf(stderr, "vpts: %12ld, stc: %12ld, offset: %12ld\n", vpts, result_get_pts.pts, offset); */ } pthread_mutex_unlock(&this->vpts_offs_queue.lock); if (sizeof (result_get_pts) != vdr_write(this->fh_result, &result_get_pts, sizeof (result_get_pts))) return -1; } } break; case func_get_version: { READ_DATA_OR_FAIL(get_version, lprintf("got GETVERSION\n")); { result_get_version_t result_get_version; result_get_version.header.func = data->header.func; result_get_version.header.len = sizeof (result_get_version); result_get_version.version = XINE_VDR_VERSION; if (sizeof (result_get_version) != vdr_write(this->fh_result, &result_get_version, sizeof (result_get_version))) return -1; } } break; case func_video_size: { READ_DATA_OR_FAIL(video_size, lprintf("got VIDEO SIZE\n")); { int format, width, height, ratio; result_video_size_t result_video_size; result_video_size.header.func = data->header.func; result_video_size.header.len = sizeof (result_video_size); result_video_size.top = -1; result_video_size.left = -1; result_video_size.width = -1; result_video_size.height = -1; result_video_size.ratio = 0; xine_get_current_frame_s(this->stream, &width, &height, &ratio, &format, NULL, NULL); result_video_size.width = width; result_video_size.height = height; result_video_size.ratio = ratio; if (ratio == XINE_VO_ASPECT_SQUARE) result_video_size.ratio = 10000; else if (ratio == XINE_VO_ASPECT_4_3) result_video_size.ratio = 13333; else if (ratio == XINE_VO_ASPECT_ANAMORPHIC) result_video_size.ratio = 17778; else if (ratio == XINE_VO_ASPECT_DVB) result_video_size.ratio = 21100; if (0 != this->frame_size.x || 0 != this->frame_size.y || 0 != this->frame_size.w || 0 != this->frame_size.h) { result_video_size.left = this->frame_size.x; result_video_size.top = this->frame_size.y; result_video_size.width = this->frame_size.w; result_video_size.height = this->frame_size.h; } /* fprintf(stderr, "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\n"); */ result_video_size.zoom_x = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_X); result_video_size.zoom_y = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_Y); /* fprintf(stderr, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\n"); */ if (sizeof (result_video_size) != vdr_write(this->fh_result, &result_video_size, sizeof (result_video_size))) return -1; /* fprintf(stderr, "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\n"); */ } } break; case func_reset_audio: { /*double _t1, _t2;*/ int _n = 0; READ_DATA_OR_FAIL(reset_audio, lprintf("got RESET AUDIO\n")); if (this->stream->audio_fifo) { xine_set_param(this->stream, XINE_PARAM_IGNORE_AUDIO, 1); xine_set_param(this->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -2); /*_t1 = _now();*/ while (1) { int n = xine_get_stream_info(this->stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL); if (n <= 0) break; /* keep the decoder running */ if (this->stream->audio_fifo) { buf_element_t *buf = this->stream->audio_fifo->buffer_pool_alloc(this->stream->audio_fifo); if (!buf) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: buffer_pool_alloc() failed!\n"), LOG_MODULE); return -1; } buf->type = BUF_CONTROL_RESET_TRACK_MAP; this->stream->audio_fifo->put(this->stream->audio_fifo, buf); } /* sched_yield(); */ xine_usec_sleep(5000); _n++; } /*_t2 = _now();*/ /* fprintf(stderr, "vdr: reset_audio: n: %d, %.1lf\n", _n, _t2 - _t1); */ xine_set_param(this->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -1); _x_stream_info_reset(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE); _x_meta_info_reset(this->stream, XINE_META_INFO_AUDIOCODEC); xine_set_param(this->stream, XINE_PARAM_IGNORE_AUDIO, 0); } } break; case func_query_capabilities: { READ_DATA_OR_FAIL(query_capabilities, lprintf("got QUERYCAPABILITIES\n")); { result_query_capabilities_t result_query_capabilities; result_query_capabilities.header.func = data->header.func; result_query_capabilities.header.len = sizeof (result_query_capabilities); result_query_capabilities.osd_max_num_windows = MAX_SHOWING; result_query_capabilities.osd_palette_max_depth = 8; result_query_capabilities.osd_palette_is_shared = 0; result_query_capabilities.osd_supports_argb_layer = this->osd_supports_argb_layer; result_query_capabilities.osd_supports_custom_extent = this->osd_supports_custom_extent; if (sizeof (result_query_capabilities) != vdr_write(this->fh_result, &result_query_capabilities, sizeof (result_query_capabilities))) return -1; } } break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "input_vdr: unknown function #%d\n", (int)this->cur_func); } if (this->cur_size != this->cur_done) { off_t skip = this->cur_size - this->cur_done; lprintf("func: %d, skipping: %" PRId64 "\n", this->cur_func, (int64_t)skip); while (skip > BUF_SIZE) { n = vdr_read_abort(this->stream, this->fh_control, this->seek_buf, BUF_SIZE); if (n != BUF_SIZE) return -1; skip -= BUF_SIZE; } n = vdr_read_abort(this->stream, this->fh_control, this->seek_buf, skip); if (n != skip) return -1; this->cur_done = this->cur_size; return -1; } return 0; } static void *vdr_rpc_thread_loop(void *arg) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)arg; int frontend_lock_failures = 0; int failed = 0; int was_startup_phase = this->startup_phase; while (!failed && !this->rpc_thread_shutdown && was_startup_phase == this->startup_phase) { struct timeval timeout; fd_set rset; FD_ZERO(&rset); FD_SET(this->fh_control, &rset); timeout.tv_sec = 0; timeout.tv_usec = 50000; if (select(this->fh_control + 1, &rset, NULL, NULL, &timeout) > 0) { if (!_x_lock_frontend(this->stream, 100)) { if (++frontend_lock_failures > 50) { failed = 1; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": locking frontend for rpc command execution failed, exiting ...\n"); } } else { frontend_lock_failures = 0; if (_x_lock_port_rewiring(this->stream->xine, 100)) { if (vdr_execute_rpc_command(this) < 0) { failed = 1; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": execution of rpc command %d (%s) failed, exiting ...\n", this->cur_func, ""); } _x_unlock_port_rewiring(this->stream->xine); } _x_unlock_frontend(this->stream); } } } if (!failed && was_startup_phase) return (void *)1; /* close control and result channel here to have vdr-xine initiate a disconnect for the above error case ... */ close(this->fh_control); this->fh_control = -1; close(this->fh_result); this->fh_result = -1; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": rpc thread done.\n"); pthread_mutex_lock(&this->rpc_thread_shutdown_lock); this->rpc_thread_shutdown = -1; pthread_cond_broadcast(&this->rpc_thread_shutdown_cond); pthread_mutex_unlock(&this->rpc_thread_shutdown_lock); return 0; } static int internal_write_event_key(vdr_input_plugin_t *this, uint32_t key) { event_key_t event; event.header.func = func_key; event.header.len = sizeof (event); event.key = key; if (sizeof (event) != vdr_write(this->fh_event, &event, sizeof (event))) return -1; return 0; } static int internal_write_event_frame_size(vdr_input_plugin_t *this) { event_frame_size_t event; event.header.func = func_frame_size; event.header.len = sizeof (event); event.left = this->frame_size.x; event.top = this->frame_size.y; event.width = this->frame_size.w, event.height = this->frame_size.h; event.zoom_x = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_X); event.zoom_y = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_Y); if (sizeof (event) != vdr_write(this->fh_event, &event, sizeof (event))) return -1; return 0; } static int internal_write_event_play_external(vdr_input_plugin_t *this, uint32_t key) { event_play_external_t event; event.header.func = func_play_external; event.header.len = sizeof (event); event.key = key; if (sizeof (event) != vdr_write(this->fh_event, &event, sizeof (event))) return -1; return 0; } static int internal_write_event_discontinuity(vdr_input_plugin_t *this, int32_t type) { event_discontinuity_t event; event.header.func = func_discontinuity; event.header.len = sizeof (event); event.type = type; if (sizeof (event) != vdr_write(this->fh_event, &event, sizeof (event))) return -1; return 0; } static ssize_t vdr_main_read (vdr_input_plugin_t *this, uint8_t *buf, ssize_t len) { ssize_t have = 0, n = 0; if (this->is_netvdr) { n = _x_io_tcp_read (this->stream, this->fh, buf + have, len - have); if (n >= 0) { this->curpos += n; have += n; #ifdef LOG_READ lprintf ("got %d bytes (%d/%d bytes read)\n", (int)n, (int)have, (int)len); #endif } } else { int retries = 0; while (have < len) { n = read (this->fh, buf + have, len - have); if (n > 0) { retries = 0; this->curpos += n; have += n; #ifdef LOG_READ lprintf ("got %d bytes (%d/%d bytes read)\n", (int)n, (int)have, (int)len); #endif continue; } if (n < 0) { int e = errno; if (e == EINTR) continue; if (e != EAGAIN) break; do { fd_set rset; struct timeval timeout; if (_x_action_pending (this->stream) || this->stream_external || !_x_continue_stream_processing (this->stream)) { errno = EINTR; break; } FD_ZERO (&rset); FD_SET (this->fh, &rset); timeout.tv_sec = 0; timeout.tv_usec = 50000; e = select (this->fh + 1, &rset, NULL, NULL, &timeout); } while (e == 0); if (e < 0) break; } else { /* n == 0 (pipe not yet open for writing) */ struct timeval timeout; if (_x_action_pending (this->stream) || this->stream_external || !_x_continue_stream_processing (this->stream)) { errno = EINTR; break; } if (++retries >= 200) { /* 200 * 50ms */ errno = ETIMEDOUT; break; } lprintf ("read 0, retries: %d\n", retries); timeout.tv_sec = 0; timeout.tv_usec = 50000; select (0, NULL, NULL, NULL, &timeout); } } } if ((n < 0) && (errno != EINTR)) _x_message (this->stream, XINE_MSG_READ_ERROR, NULL); return have; } static off_t vdr_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { vdr_input_plugin_t *this = (vdr_input_plugin_t *) this_gen; uint8_t *buf = (uint8_t *)buf_gen; ssize_t have; #ifdef LOG_READ lprintf ("reading %d bytes...\n", (int)len); #endif have = vdr_main_read (this, buf, len); /* HACK: demux_pes always reads 6 byte pes heads. */ if (have == 6) { pthread_mutex_lock (&this->find_sync_point_lock); while (this->find_sync_point && (have == 6) && (buf[0] == 0x00) && (buf[1] == 0x00) && (buf[2] == 0x01)) { int l; /* sync point? */ if ((buf[3] == 0xbe) && (buf[4] == 0xff)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: found sync point %d.\n", (int)buf[5]); if (buf[5] == this->find_sync_point) { this->find_sync_point = 0; break; } } /* unknown packet type? */ if (((buf[3] & 0xf0) != 0xe0) && ((buf[3] & 0xe0) != 0xc0) && (buf[3] != 0xbd) && (buf[3] != 0xbe)) break; /* payload size */ l = ((uint32_t)buf[4] << 8) + buf[5]; if (l <= 0) break; /* skip this */ while (l >= (int)sizeof (this->seek_buf)) { int n = vdr_main_read (this, this->seek_buf, sizeof (this->seek_buf)); if (n <= 0) break; l -= n; } if (l >= (int)sizeof (this->seek_buf)) break; if (l > 0) { int n = vdr_main_read (this, this->seek_buf, l); if (n < l) break; } /* get next head */ have = vdr_main_read (this, buf, 6); } pthread_mutex_unlock(&this->find_sync_point_lock); } return have; } static buf_element_t *vdr_plugin_read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { off_t total_bytes; buf_element_t *buf; if (todo < 0) return NULL; buf = fifo->buffer_pool_size_alloc (fifo, todo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; if (todo > buf->max_size) todo = buf->max_size; total_bytes = vdr_plugin_read(this_gen, (char *)buf->content, todo); if (total_bytes != todo) { buf->free_buffer(buf); return NULL; } buf->size = total_bytes; return buf; } /* forward reference */ static off_t vdr_plugin_get_current_pos(input_plugin_t *this_gen); static off_t vdr_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; lprintf("seek %" PRId64 " offset, %d origin...\n", (int64_t)offset, origin); if (origin == SEEK_SET) { if (offset < this->curpos) { lprintf ("cannot seek back! (%" PRId64 " > %" PRId64 ")\n", (int64_t)this->curpos, (int64_t)offset); return this->curpos; } offset -= this->curpos; origin = SEEK_CUR; } if (origin == SEEK_CUR) { while (offset > 0) { int part = offset > BUF_SIZE ? BUF_SIZE : offset; part = this_gen->read (this_gen, this->seek_buf, part); if (part <= 0) break; this->curpos += part; offset -= part; } } return this->curpos; } static off_t vdr_plugin_get_length(input_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t vdr_plugin_get_capabilities(input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_PREVIEW | INPUT_CAP_NO_CACHE; } static uint32_t vdr_plugin_get_blocksize(input_plugin_t *this_gen) { (void)this_gen; return 0; } static off_t vdr_plugin_get_current_pos(input_plugin_t *this_gen) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; return this->curpos; } static const char *vdr_plugin_get_mrl(input_plugin_t *this_gen) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; return this->mrl; } static void vdr_plugin_dispose(input_plugin_t *this_gen) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; int i; external_stream_stop(this); if (this->event_queue) xine_event_dispose_queue(this->event_queue); if (this->rpc_thread_created) { struct timespec abstime; int ms_to_time_out = 10000; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: shutting down rpc thread (timeout: %d ms) ...\n"), LOG_MODULE, ms_to_time_out); pthread_mutex_lock(&this->rpc_thread_shutdown_lock); if (this->rpc_thread_shutdown > -1) { this->rpc_thread_shutdown = 1; { struct timeval now; gettimeofday(&now, 0); abstime.tv_sec = now.tv_sec + ms_to_time_out / 1000; abstime.tv_nsec = now.tv_usec * 1000 + (ms_to_time_out % 1000) * 1e6; if (abstime.tv_nsec > 1e9) { abstime.tv_nsec -= 1e9; abstime.tv_sec++; } } if (0 != pthread_cond_timedwait(&this->rpc_thread_shutdown_cond, &this->rpc_thread_shutdown_lock, &abstime)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: cancelling rpc thread in function %d...\n"), LOG_MODULE, this->cur_func); pthread_cancel(this->rpc_thread); } } pthread_mutex_unlock(&this->rpc_thread_shutdown_lock); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: joining rpc thread ...\n"), LOG_MODULE); pthread_join(this->rpc_thread, 0); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: rpc thread joined.\n"), LOG_MODULE); } pthread_cond_destroy(&this->rpc_thread_shutdown_cond); pthread_mutex_destroy(&this->rpc_thread_shutdown_lock); pthread_mutex_destroy(&this->find_sync_point_lock); pthread_mutex_destroy(&this->adjust_zoom_lock); if (this->fh_result != -1) close(this->fh_result); if (this->fh_control != -1) close(this->fh_control); if (this->fh_event != -1) close(this->fh_event); for (i = 0; i < VDR_MAX_NUM_WINDOWS; i++) { int k; if (NULL == this->osd[ i ].window) continue; xine_osd_hide(this->osd[ i ].window, 0); xine_osd_free(this->osd[ i ].window); for (k = 0; k < 2; k++) free(this->osd[ i ].argb_buffer[ k ]); } if (this->osd_buffer) free(this->osd_buffer); if ((this->fh != STDIN_FILENO) && (this->fh != -1)) close(this->fh); free(this->mrl); /* unset metronom */ this->stream->metronom = this->metronom.stream_metronom; this->metronom.stream_metronom = NULL; vdr_vpts_offset_queue_purge (this); vdr_vpts_offset_queue_deinit (this); pthread_mutex_destroy (&this->metronom.mutex); /* see comment above */ if (this->stream->audio_fifo) this->stream->audio_fifo->unregister_alloc_cb (this->stream->audio_fifo, input_vdr_dummy); if (this->stream->video_fifo) this->stream->video_fifo->unregister_alloc_cb (this->stream->video_fifo, input_vdr_dummy); free(this); } static int vdr_plugin_get_optional_data(input_plugin_t *this_gen, void *data, int data_type) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; (void)this; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: /* just fake what mpeg_pes demuxer expects */ memcpy (data, "\x00\x00\x01\xe0\x00\x03\x80\x00\x00", 9); return 9; } return INPUT_OPTIONAL_UNSUPPORTED; } static inline const char *mrl_to_fifo (const char *mrl) { /* vdr://foo -> /foo */ return mrl + 3 + strspn (mrl + 4, "/"); } static inline const char *mrl_to_host (const char *mrl) { /* netvdr://host:port -> host:port */ return strrchr (mrl, '/') + 1; } static int vdr_plugin_open_fifo_mrl(input_plugin_t *this_gen) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; const char *fifoname = mrl_to_fifo (this->mrl); if(!strcmp(fifoname, "/")) { fifoname = VDR_ABS_FIFO_DIR "/stream"; } char *filename = strdup(fifoname); _x_mrl_unescape (filename); this->fh = xine_open_cloexec(filename, O_RDONLY | O_NONBLOCK); lprintf("filename '%s'\n", filename); if (this->fh == -1) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to open '%s' (%s)\n"), LOG_MODULE, filename, strerror(errno)); free (filename); return 0; } { struct pollfd poll_fh = { this->fh, POLLIN, 0 }; int r = poll(&poll_fh, 1, 300); if (1 != r) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to open '%s' (%s)\n"), LOG_MODULE, filename, _("timeout expired during setup phase")); free (filename); return 0; } } fcntl(this->fh, F_SETFL, ~O_NONBLOCK & fcntl(this->fh, F_GETFL, 0)); /* eat initial handshake byte */ { char b; if (1 != read(this->fh, &b, 1)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to read '%s' (%s)\n"), LOG_MODULE, filename, strerror(errno)); } } { char *filename_control = NULL; filename_control = _x_asprintf("%s.control", filename); this->fh_control = xine_open_cloexec(filename_control, O_RDONLY); if (this->fh_control == -1) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to open '%s' (%s)\n"), LOG_MODULE, filename_control, strerror(errno)); free(filename_control); free (filename); return 0; } free(filename_control); } { char *filename_result = NULL; filename_result = _x_asprintf("%s.result", filename); this->fh_result = xine_open_cloexec(filename_result, O_WRONLY); if (this->fh_result == -1) { perror("failed"); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to open '%s' (%s)\n"), LOG_MODULE, filename_result, strerror(errno)); free(filename_result); free (filename); return 0; } free(filename_result); } { char *filename_event = NULL; filename_event = _x_asprintf("%s.event", filename); this->fh_event = xine_open_cloexec(filename_event, O_WRONLY); if (this->fh_event == -1) { perror("failed"); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to open '%s' (%s)\n"), LOG_MODULE, filename_event, strerror(errno)); free(filename_event); free (filename); return 0; } free(filename_event); } free (filename); return 1; } static int vdr_plugin_open_socket(vdr_input_plugin_t *this, struct hostent *host, unsigned short port) { int fd; struct sockaddr_in sain; struct in_addr iaddr; if ((fd = xine_socket_cloexec(PF_INET, SOCK_STREAM, 0)) == -1) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to create socket for port %d (%s)\n"), LOG_MODULE, port, strerror(errno)); return -1; } iaddr.s_addr = *((unsigned int *)host->h_addr_list[0]); sain.sin_port = htons(port); sain.sin_family = AF_INET; sain.sin_addr = iaddr; if (connect(fd, (struct sockaddr *)&sain, sizeof (sain)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to connect to port %d (%s)\n"), LOG_MODULE, port, strerror(errno)); close(fd); return -1; } xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: socket opening (port %d) successful, fd = %d\n"), LOG_MODULE, port, fd); return fd; } static int vdr_plugin_open_sockets(vdr_input_plugin_t *this) { struct hostent *host; char *mrl_host = strdup (mrl_to_host (this->mrl)); char *mrl_port; int port = 18701; mrl_port = strchr(mrl_host, '#'); if (mrl_port) *mrl_port = 0; /* strip off things like '#demux:mpeg_pes' */ _x_mrl_unescape (mrl_host); mrl_port = strchr(mrl_host, ':'); if (mrl_port) { port = atoi(mrl_port + 1); *mrl_port = 0; } host = gethostbyname(mrl_host); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: connecting to vdr.\n"), LOG_MODULE); if (!host) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: failed to resolve hostname '%s' (%s)\n"), LOG_MODULE, mrl_host, strerror(errno)); free (mrl_host); return 0; } free (mrl_host); if ((this->fh = vdr_plugin_open_socket(this, host, port + 0)) == -1) return 0; fcntl(this->fh, F_SETFL, ~O_NONBLOCK & fcntl(this->fh, F_GETFL, 0)); if ((this->fh_control = vdr_plugin_open_socket(this, host, port + 1)) == -1) return 0; if ((this->fh_result = vdr_plugin_open_socket(this, host, port + 2)) == -1) return 0; if ((this->fh_event = vdr_plugin_open_socket(this, host, port + 3)) == -1) return 0; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: connecting to all sockets (port %d .. %d) was successful.\n"), LOG_MODULE, port, port + 3); return 1; } static int vdr_plugin_open_socket_mrl(input_plugin_t *this_gen) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; lprintf("input_vdr: connecting to vdr-xine-server...\n"); if (!vdr_plugin_open_sockets(this)) return 0; return 1; } static void vdr_vpts_offset_queue_add (vdr_input_plugin_t *this, int type, int64_t disc_off) { pthread_mutex_lock (&this->vpts_offs_queue.lock); if ((type == DISC_ABSOLUTE) || (type == DISC_STREAMSTART)) vdr_vpts_offset_queue_add_int (this, disc_off); else vdr_vpts_offset_queue_purge(this); this->last_disc_type = type; if (type != DISC_STREAMSTART) pthread_cond_broadcast (&this->vpts_offs_queue.changed); pthread_mutex_unlock (&this->vpts_offs_queue.lock); if (!this->metronom.trick_mode) { xine_event_t event; event.type = XINE_EVENT_VDR_DISCONTINUITY; event.data = NULL; event.data_length = type; xine_event_send(this->stream, &event); } } static int vdr_plugin_open(input_plugin_t *this_gen) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)this_gen; lprintf("trying to open '%s'...\n", this->mrl); if (this->fh == -1) { int err = 0; if (!strncasecmp (&this->mrl[0], "vdr:/", 5)) { this->is_netvdr = 0; if (!vdr_plugin_open_fifo_mrl (this_gen)) return 0; } else if (!strncasecmp (&this->mrl[0], "netvdr:/", 8)) { this->is_netvdr = 1; if (!vdr_plugin_open_socket_mrl (this_gen)) return 0; } else { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("%s: MRL (%s) invalid! MRL should start with vdr://path/to/fifo/stream or netvdr://host:port where ':port' is optional.\n"), LOG_MODULE, strerror (err)); return 0; } this->rpc_thread_shutdown = 0; /* let this thread handle rpc commands in startup phase */ this->startup_phase = 1; if (0 == vdr_rpc_thread_loop(this)) return 0; /* fprintf(stderr, "####################################################\n"); */ if ((err = pthread_create(&this->rpc_thread, NULL, vdr_rpc_thread_loop, (void *)this)) != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: can't create new thread (%s)\n"), LOG_MODULE, strerror(err)); return 0; } this->rpc_thread_created = 1; } /* * mrl accepted and opened successfully at this point * * => create plugin instance */ this->curpos = 0; return 1; } static void event_handler(void *user_data, const xine_event_t *event) { vdr_input_plugin_t *this = (vdr_input_plugin_t *)user_data; uint32_t key = key_none; lprintf("eventHandler(): event->type: %d\n", event->type); if (XINE_EVENT_VDR_FRAMESIZECHANGED == event->type) { memcpy(&this->frame_size, event->data, event->data_length); if (0 != internal_write_event_frame_size(this)) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: input event write: %s.\n"), LOG_MODULE, strerror(errno)); adjust_zoom(this); return; } if (XINE_EVENT_VDR_DISCONTINUITY == event->type) { if (0 != internal_write_event_discontinuity(this, event->data_length)) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: input event write: %s.\n"), LOG_MODULE, strerror(errno)); return; } if (XINE_EVENT_VDR_PLUGINSTARTED == event->type) { if (0 == event->data_length) /* vdr_video */ { xine_event_t event; event.type = XINE_EVENT_VDR_TRICKSPEEDMODE; event.data = NULL; event.data_length = 0; /* this->trick_speed_mode; */ xine_event_send(this->stream, &event); } else if (1 == event->data_length) /* vdr_audio */ { xine_event_t event; vdr_select_audio_data_t event_data; event_data.channels = this->audio_channels; event.type = XINE_EVENT_VDR_SELECTAUDIO; event.data = &event_data; event.data_length = sizeof (event_data); xine_event_send(this->stream, &event); } else { fprintf(stderr, "input_vdr: illegal XINE_EVENT_VDR_PLUGINSTARTED: %d\n", event->data_length); } return; } if ((event->type >= 101) && (event->type < 130)) { static const uint8_t input_keys[130 - 101] = { [XINE_EVENT_INPUT_UP - 101] = key_up, [XINE_EVENT_INPUT_DOWN - 101] = key_down, [XINE_EVENT_INPUT_LEFT - 101] = key_left, [XINE_EVENT_INPUT_RIGHT - 101] = key_right, [XINE_EVENT_INPUT_SELECT - 101] = key_ok, [XINE_EVENT_INPUT_MENU1 - 101] = key_menu, [XINE_EVENT_INPUT_NUMBER_0 - 101] = key_0, [XINE_EVENT_INPUT_NUMBER_1 - 101] = key_1, [XINE_EVENT_INPUT_NUMBER_2 - 101] = key_2, [XINE_EVENT_INPUT_NUMBER_3 - 101] = key_3, [XINE_EVENT_INPUT_NUMBER_4 - 101] = key_4, [XINE_EVENT_INPUT_NUMBER_5 - 101] = key_5, [XINE_EVENT_INPUT_NUMBER_6 - 101] = key_6, [XINE_EVENT_INPUT_NUMBER_7 - 101] = key_7, [XINE_EVENT_INPUT_NUMBER_8 - 101] = key_8, [XINE_EVENT_INPUT_NUMBER_9 - 101] = key_9, [XINE_EVENT_INPUT_NEXT - 101] = key_next, [XINE_EVENT_INPUT_PREVIOUS - 101] = key_previous }; key = input_keys[event->type - 101]; if (key == 0) return; } else if ((event->type >= 300) && (event->type < 337)) { static const uint8_t vdr_keys[337 - 300] = { [XINE_EVENT_VDR_BACK - 300] = key_back, [XINE_EVENT_VDR_CHANNELPLUS - 300] = key_channel_plus, [XINE_EVENT_VDR_CHANNELMINUS - 300] = key_channel_minus, [XINE_EVENT_VDR_RED - 300] = key_red, [XINE_EVENT_VDR_GREEN - 300] = key_green, [XINE_EVENT_VDR_YELLOW - 300] = key_yellow, [XINE_EVENT_VDR_BLUE - 300] = key_blue, [XINE_EVENT_VDR_PLAY - 300] = key_play, [XINE_EVENT_VDR_PAUSE - 300] = key_pause, [XINE_EVENT_VDR_STOP - 300] = key_stop, [XINE_EVENT_VDR_RECORD - 300] = key_record, [XINE_EVENT_VDR_FASTFWD - 300] = key_fast_fwd, [XINE_EVENT_VDR_FASTREW - 300] = key_fast_rew, [XINE_EVENT_VDR_POWER - 300] = key_power, [XINE_EVENT_VDR_SCHEDULE - 300] = key_schedule, [XINE_EVENT_VDR_CHANNELS - 300] = key_channels, [XINE_EVENT_VDR_TIMERS - 300] = key_timers, [XINE_EVENT_VDR_RECORDINGS - 300] = key_recordings, [XINE_EVENT_VDR_SETUP - 300] = key_setup, [XINE_EVENT_VDR_COMMANDS - 300] = key_commands, [XINE_EVENT_VDR_USER0 - 300] = key_user0, [XINE_EVENT_VDR_USER1 - 300] = key_user1, [XINE_EVENT_VDR_USER2 - 300] = key_user2, [XINE_EVENT_VDR_USER3 - 300] = key_user3, [XINE_EVENT_VDR_USER4 - 300] = key_user4, [XINE_EVENT_VDR_USER5 - 300] = key_user5, [XINE_EVENT_VDR_USER6 - 300] = key_user6, [XINE_EVENT_VDR_USER7 - 300] = key_user7, [XINE_EVENT_VDR_USER8 - 300] = key_user8, [XINE_EVENT_VDR_USER9 - 300] = key_user9, [XINE_EVENT_VDR_VOLPLUS - 300] = key_volume_plus, [XINE_EVENT_VDR_VOLMINUS - 300] = key_volume_minus, [XINE_EVENT_VDR_MUTE - 300] = key_mute, [XINE_EVENT_VDR_AUDIO - 300] = key_audio, [XINE_EVENT_VDR_INFO - 300] = key_info, [XINE_EVENT_VDR_CHANNELPREVIOUS - 300] = key_channel_previous, [XINE_EVENT_VDR_SUBTITLES - 300] = key_subtitles }; key = vdr_keys[event->type - 300]; if (key == 0) return; } else { return; } if (0 != internal_write_event_key(this, key)) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("%s: input event write: %s.\n"), LOG_MODULE, strerror(errno)); } static void vdr_metronom_handle_audio_discontinuity (metronom_t *self, int type, int64_t disc_off) { vdr_metronom_t *metr = (vdr_metronom_t *)self; int diff, num, trick_mode, trick_new_mode, add, relay_type = type; /* just 1 finite time lock session. */ pthread_mutex_lock (&metr->mutex); /* just relay all we dont need (in particular, DISC_GAPLESS). */ if ((type != DISC_STREAMSTART) && (type != DISC_RELATIVE) && (type != DISC_ABSOLUTE) && (type != DISC_STREAMSEEK)) { pthread_mutex_unlock (&metr->mutex); metr->stream_metronom->handle_audio_discontinuity (metr->stream_metronom, type, disc_off); return; } /* make sure we dont respond too early. */ if (!metr->audio.on) { if ((type != DISC_STREAMSEEK) || (disc_off != VDR_DISC_START)) { pthread_mutex_unlock (&metr->mutex); metr->stream_metronom->handle_audio_discontinuity (metr->stream_metronom, type, disc_off); return; } metr->audio.on = 1; pthread_mutex_unlock (&metr->mutex); xprintf (metr->input->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: audio discontinuity handling now on.\n"); return; } /* Demux knows nothing about vdr seek. It just sees a pts jump, and sends a plain absolute * discontinuity. That will make metronom try a seamless append, leaving a 1..2s gap there. * Thus, after a seek, manually upgrade first "absolute" to "streamseek" here. */ if (type == DISC_STREAMSTART) { metr->audio.seek = 1; } else if ((type == DISC_ABSOLUTE) && metr->audio.seek) { metr->audio.seek = 0; relay_type = DISC_STREAMSEEK; } trick_mode = metr->trick_mode; trick_new_mode = metr->trick_new_mode; metr->audio.disc_num += 1; num = metr->audio.disc_num; add = diff = metr->audio.disc_num - metr->video.disc_num; if (trick_mode && (type == DISC_ABSOLUTE) && (diff <= 0)) { if (trick_mode == 1) metr->trick_mode = 2; else add = 1; } if ((diff == 0) && (trick_new_mode >= 0)) { metr->trick_mode = trick_new_mode; metr->trick_new_mode = -1; } else { trick_new_mode = -1; } pthread_mutex_unlock (&metr->mutex); /* report */ xprintf (metr->input->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: %s audio discontinuity #%d, type is %d, disc off %" PRId64 ".\n", trick_mode ? "trick play" : "", num, type, disc_off); /* relay */ if (!trick_mode) metr->stream_metronom->handle_audio_discontinuity (metr->stream_metronom, relay_type, disc_off); /* if we are behind: complete this pair. */ if (add <= 0) vdr_vpts_offset_queue_add (metr->input, type, disc_off); /* new trick mode */ if (trick_new_mode >= 0) trick_speed_send_event (metr->input, trick_new_mode); } static void vdr_metronom_handle_video_discontinuity (metronom_t *self, int type, int64_t disc_off) { vdr_metronom_t *metr = (vdr_metronom_t *)self; int diff, num, trick_mode, trick_new_mode, add, relay_type = type; /* just 1 finite time lock session. */ pthread_mutex_lock (&metr->mutex); /* just relay all we dont need (in particular, DISC_GAPLESS). */ if ((type != DISC_STREAMSTART) && (type != DISC_RELATIVE) && (type != DISC_ABSOLUTE) && (type != DISC_STREAMSEEK)) { pthread_mutex_unlock (&metr->mutex); metr->stream_metronom->handle_video_discontinuity (metr->stream_metronom, type, disc_off); return; } /* make sure we dont respond too early. */ if (!metr->video.on) { if ((type != DISC_STREAMSEEK) || (disc_off != VDR_DISC_START)) { pthread_mutex_unlock (&metr->mutex); metr->stream_metronom->handle_video_discontinuity (metr->stream_metronom, type, disc_off); return; } metr->video.on = 1; pthread_mutex_unlock (&metr->mutex); xprintf (metr->input->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: video discontinuity handling now on.\n"); return; } /* Demux knows nothing about vdr seek. It just sees a pts jump, and sends a plain absolute * discontinuity. That will make metronom try a seamless append, leaving a 1..2s gap there. * Thus, after a seek, manually upgrade first "absolute" to "streamseek" here. */ if (type == DISC_STREAMSTART) { metr->video.seek = 1; } else if ((type == DISC_ABSOLUTE) && metr->video.seek) { metr->video.seek = 0; relay_type = DISC_STREAMSEEK; } trick_mode = metr->trick_mode; trick_new_mode = metr->trick_new_mode; metr->video.disc_num += 1; num = metr->video.disc_num; add = diff = metr->video.disc_num - metr->audio.disc_num; if (trick_mode && (type == DISC_ABSOLUTE) && (diff <= 0)) { if (trick_mode == 1) metr->trick_mode = 2; else add = 1; } if ((diff == 0) && (trick_new_mode >= 0)) { metr->trick_mode = trick_new_mode; metr->trick_new_mode = -1; } else { trick_new_mode = -1; } pthread_mutex_unlock (&metr->mutex); /* report */ xprintf (metr->input->stream->xine, XINE_VERBOSITY_DEBUG, "input_vdr: %s video discontinuity #%d, type is %d, disc off %" PRId64 ".\n", trick_mode ? "trick play" : "", num, type, disc_off); /* relay */ if (!trick_mode) metr->stream_metronom->handle_video_discontinuity (metr->stream_metronom, relay_type, disc_off); /* if we are behind: complete this pair. */ if (add <= 0) vdr_vpts_offset_queue_add (metr->input, type, disc_off); /* new trick mode */ if (trick_new_mode >= 0) trick_speed_send_event (metr->input, trick_new_mode); } static void vdr_metronom_got_video_frame(metronom_t *self, vo_frame_t *frame) { vdr_metronom_t *metr = (vdr_metronom_t *)self; if (frame->pts) { pthread_mutex_lock (&metr->mutex); if (!metr->trick_mode) { pthread_mutex_unlock (&metr->mutex); metr->stream_metronom->got_video_frame (metr->stream_metronom, frame); } else { frame->progressive_frame = -1; /* force progressive */ metr->stream_metronom->set_option (metr->stream_metronom, METRONOM_VDR_TRICK_PTS, frame->pts); metr->stream_metronom->got_video_frame (metr->stream_metronom, frame); vdr_vpts_offset_queue_add (metr->input, DISC_ABSOLUTE, frame->pts); pthread_mutex_unlock (&metr->mutex); /* fprintf (stderr, "vpts: %12ld, pts: %12ld, offset: %12ld\n", frame->vpts, frame->pts, metr->stream_metronom->get_option (metr->stream_metronom, METRONOM_VPTS_OFFSET)); */ } } else { metr->stream_metronom->got_video_frame (metr->stream_metronom, frame); } } static int64_t vdr_metronom_got_audio_samples(metronom_t *self, int64_t pts, int nsamples) { vdr_metronom_t *this = (vdr_metronom_t *)self; return this->stream_metronom->got_audio_samples(this->stream_metronom, pts, nsamples); } static int64_t vdr_metronom_got_spu_packet(metronom_t *self, int64_t pts) { vdr_metronom_t *this = (vdr_metronom_t *)self; return this->stream_metronom->got_spu_packet(this->stream_metronom, pts); } static void vdr_metronom_set_audio_rate(metronom_t *self, int64_t pts_per_smpls) { vdr_metronom_t *this = (vdr_metronom_t *)self; this->stream_metronom->set_audio_rate(this->stream_metronom, pts_per_smpls); } static void vdr_metronom_set_option(metronom_t *self, int option, int64_t value) { vdr_metronom_t *this = (vdr_metronom_t *)self; this->stream_metronom->set_option(this->stream_metronom, option, value); } static int64_t vdr_metronom_get_option(metronom_t *self, int option) { vdr_metronom_t *this = (vdr_metronom_t *)self; return this->stream_metronom->get_option(this->stream_metronom, option); } static void vdr_metronom_set_master(metronom_t *self, metronom_t *master) { vdr_metronom_t *this = (vdr_metronom_t *)self; this->stream_metronom->set_master(this->stream_metronom, master); } static void vdr_metronom_exit(metronom_t *self) { (void)self; int this_shall_never_be_called = 1; _x_assert (this_shall_never_be_called == 0); } static input_plugin_t *vdr_class_get_instance(input_class_t *cls_gen, xine_stream_t *stream, const char *data) { vdr_input_plugin_t *this; char *mrl = strdup(data); if (!strncasecmp(mrl, "vdr:/", 5)) lprintf("filename '%s'\n", mrl_to_fifo (mrl)); else if (!strncasecmp(mrl, "netvdr:/", 5)) lprintf("host '%s'\n", mrl_to_host (mrl)); else { free(mrl); return NULL; } /* * mrl accepted and opened successfully at this point * * => create plugin instance */ this = calloc(1, sizeof (vdr_input_plugin_t)); if (!this) { free(mrl); return NULL; } #ifndef HAVE_ZERO_SAFE_MEM this->curpos = 0; this->cur_size = 0; this->cur_done = 0; this->osd_buffer = NULL; this->osd_buffer_size = 0; this->osd_unscaled_blending = 0; this->audio_channels = 0; this->frame_size.x = 0; this->frame_size.y = 0; this->frame_size.w = 0; this->frame_size.h = 0; this->frame_size.r = 0; this->stream_external = NULL; this->event_queue_external = NULL; this->image4_3_zoom_x = 0; this->image4_3_zoom_y = 0; this->image16_9_zoom_x = 0; this->image16_9_zoom_y = 0; this->metronom.audio.on = 0; this->metronom.audio.seek = 0; this->metronom.audio.disc_num = 0; this->metronom.video.on = 0; this->metronom.video.seek = 0; this->metronom.video.disc_num = 0; this->metronom.trick_mode = 0; #endif this->stream = stream; this->mrl = mrl; this->fh = -1; this->fh_control = -1; this->fh_result = -1; this->fh_event = -1; this->metronom.trick_new_mode = -1; this->input_plugin.open = vdr_plugin_open; this->input_plugin.get_capabilities = vdr_plugin_get_capabilities; this->input_plugin.read = vdr_plugin_read; this->input_plugin.read_block = vdr_plugin_read_block; this->input_plugin.seek = vdr_plugin_seek; this->input_plugin.get_current_pos = vdr_plugin_get_current_pos; this->input_plugin.get_length = vdr_plugin_get_length; this->input_plugin.get_blocksize = vdr_plugin_get_blocksize; this->input_plugin.get_mrl = vdr_plugin_get_mrl; this->input_plugin.dispose = vdr_plugin_dispose; this->input_plugin.get_optional_data = vdr_plugin_get_optional_data; this->input_plugin.input_class = cls_gen; this->cur_func = func_unknown; memset(this->osd, 0, sizeof (this->osd)); { xine_osd_t *osd = xine_osd_new(this->stream, 0, 0, 16, 16); uint32_t caps = xine_osd_get_capabilities(osd); xine_osd_free(osd); this->osd_supports_argb_layer = !!(caps & XINE_OSD_CAP_ARGB_LAYER); this->osd_supports_custom_extent = !!(caps & XINE_OSD_CAP_CUSTOM_EXTENT); } this->mute_mode = XINE_VDR_MUTE_SIMULATE; this->volume_mode = XINE_VDR_VOLUME_CHANGE_HW; this->last_volume = -1; pthread_mutex_init (&this->rpc_thread_shutdown_lock, NULL); pthread_cond_init (&this->rpc_thread_shutdown_cond, NULL); pthread_mutex_init (&this->find_sync_point_lock, NULL); pthread_mutex_init (&this->adjust_zoom_lock, NULL); vdr_vpts_offset_queue_init (this); this->event_queue = xine_event_new_queue(this->stream); if (this->event_queue) xine_event_create_listener_thread(this->event_queue, event_handler, this); /* see comment above */ if (this->stream->audio_fifo) this->stream->audio_fifo->register_alloc_cb (this->stream->audio_fifo, input_vdr_dummy, this); if (this->stream->video_fifo) this->stream->video_fifo->register_alloc_cb (this->stream->video_fifo, input_vdr_dummy, this); /* init metronom */ this->metronom.input = this; this->metronom.metronom.set_audio_rate = vdr_metronom_set_audio_rate; this->metronom.metronom.got_video_frame = vdr_metronom_got_video_frame; this->metronom.metronom.got_audio_samples = vdr_metronom_got_audio_samples; this->metronom.metronom.got_spu_packet = vdr_metronom_got_spu_packet; this->metronom.metronom.handle_audio_discontinuity = vdr_metronom_handle_audio_discontinuity; this->metronom.metronom.handle_video_discontinuity = vdr_metronom_handle_video_discontinuity; this->metronom.metronom.set_option = vdr_metronom_set_option; this->metronom.metronom.get_option = vdr_metronom_get_option; this->metronom.metronom.set_master = vdr_metronom_set_master; this->metronom.metronom.exit = vdr_metronom_exit; pthread_mutex_init (&this->metronom.mutex, NULL); /* set metronom */ stream->metronom = &this->metronom.metronom; /* send start discontinuities */ _x_demux_control_newpts (stream, VDR_DISC_START, BUF_FLAG_SEEK); return &this->input_plugin; } /* * vdr input plugin class stuff */ static const char * const *vdr_class_get_autoplay_list(input_class_t *this_gen, int *num_files) { static const char * const mrls[] = {"vdr:/" VDR_ABS_FIFO_DIR "/stream#demux:mpeg_pes", NULL}; (void)this_gen; *num_files = 1; return mrls; } void *vdr_input_init_plugin(xine_t *xine, const void *data) { lprintf("init_class\n"); static const input_class_t this = { .get_instance = vdr_class_get_instance, .identifier = "VDR", .description = N_("VDR display device plugin"), .get_dir = NULL, .get_autoplay_list = vdr_class_get_autoplay_list, .dispose = NULL, .eject_media = NULL }; (void)xine; (void)data; return (input_class_t *)&this; } xine-lib-1.2/src/vdr/Makefile.am0000644000175000017500000000071614647725152014306 0ustar memeinclude $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) if ENABLE_VDR xineplug_LTLIBRARIES = xineplug_vdr.la endif xineplug_vdr_la_SOURCES = combined_vdr.c combined_vdr.h input_vdr.c post_vdr_video.c post_vdr_audio.c xineplug_vdr_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing xineplug_vdr_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xine-lib-1.2/src/vdr/post_vdr_video.c0000644000175000017500000003237414647725152015451 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * frame scaler plugin for VDR */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "vdr_video" /* #define LOG #define LOG_VERBOSE */ #include #include #include "combined_vdr.h" typedef struct vdr_video_post_plugin_s { post_plugin_t post_plugin; xine_event_queue_t *event_queue; xine_stream_t *vdr_stream; int8_t trick_speed_mode; int8_t enabled; int32_t x; int32_t y; int32_t w; int32_t h; int32_t w_ref; int32_t h_ref; int32_t old_frame_left; int32_t old_frame_top; int32_t old_frame_width; int32_t old_frame_height; double old_frame_ratio; } vdr_video_post_plugin_t; static void vdr_video_set_video_window(vdr_video_post_plugin_t *this, int32_t x, int32_t y, int32_t w, int32_t h, int32_t w_ref, int32_t h_ref) { this->enabled = 0; this->x = x; this->y = y; this->w = w; this->h = h; this->w_ref = w_ref; this->h_ref = h_ref; if (w != w_ref || h != h_ref) this->enabled = 1; } /* plugin class functions */ static post_plugin_t *vdr_video_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target); /* plugin instance functions */ static void vdr_video_dispose(post_plugin_t *this_gen); /* route preprocessing functions check */ static int vdr_video_route_preprocessing_procs(post_video_port_t *port, vo_frame_t *frame); /* replaced vo_frame functions */ static int vdr_video_draw(vo_frame_t *frame, xine_stream_t *stream); void *vdr_video_init_plugin(xine_t *xine, const void *data) { post_class_t *class = calloc(1, sizeof (post_class_t)); (void)xine; (void)data; if (!class) return NULL; class->open_plugin = vdr_video_open_plugin; class->identifier = "vdr"; class->description = N_("modifies every video frame as requested by VDR"); class->dispose = default_post_class_dispose; return class; } static post_plugin_t *vdr_video_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { vdr_video_post_plugin_t *this = calloc(1, sizeof (vdr_video_post_plugin_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; if (!this || !video_target || !video_target[ 0 ]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post_plugin, 0, 1); this->post_plugin.dispose = vdr_video_dispose; port = _x_post_intercept_video_port(&this->post_plugin, video_target[ 0 ], &input, &output); port->route_preprocessing_procs = vdr_video_route_preprocessing_procs; port->new_frame->draw = vdr_video_draw; this->post_plugin.xine_post.video_input[ 0 ] = &port->new_port; this->enabled = 0; this->vdr_stream = 0; this->event_queue = 0; this->old_frame_left = 0; this->old_frame_top = 0; this->old_frame_width = 0; this->old_frame_height = 0; this->old_frame_ratio = 0; this->trick_speed_mode = 0; return &this->post_plugin; } static void vdr_video_dispose(post_plugin_t *this_gen) { if (_x_post_dispose(this_gen)) { vdr_video_post_plugin_t *this = (vdr_video_post_plugin_t *)this_gen; if (this->vdr_stream) { xine_event_t event; vdr_frame_size_changed_data_t event_data; event_data.x = 0; event_data.y = 0; event_data.w = 0; event_data.h = 0; event.type = XINE_EVENT_VDR_FRAMESIZECHANGED; event.data = &event_data; event.data_length = sizeof (event_data); xine_event_send(this->vdr_stream, &event); xine_event_dispose_queue(this->event_queue); } free(this_gen); } } static int vdr_video_route_preprocessing_procs(post_video_port_t *port, vo_frame_t *frame) { vdr_video_post_plugin_t *this = (vdr_video_post_plugin_t *)port->post; return !this->enabled || (frame->format != XINE_IMGFMT_YUY2 && frame->format != XINE_IMGFMT_YV12); } static inline void vdr_video_scale(uint8_t *src, uint8_t *dst, int y_inc, int x_inc, int w_dst, int h_dst, int x, int y, int w, int h, int w_ref, int h_ref, int init) { int x0 = x * w_dst / w_ref; int y0 = y * h_dst / h_ref; int x1 = ((x + w) * w_dst - 1 + w_ref) / w_ref; int y1 = ((y + h) * h_dst - 1 + h_ref) / h_ref; int dx = x1 - x0; int dy = y1 - y0; int yy, xx; int dy2 = dy + dy; int h_dst2 = h_dst + h_dst; int y_eps = h_dst - dy2; int dx2 = dx + dx; int w_dst2 = w_dst + w_dst; int x_eps0 = w_dst - dx2; for (yy = 0; yy < y0; yy++) { uint8_t *dst0 = dst; for (xx = 0; xx < w_dst; xx++) { *dst0 = init; dst0 += x_inc; } dst += y_inc; } for (yy = y0; yy < y1; yy++) { uint8_t *dst0 = dst; uint8_t *src0 = src; int x_eps = x_eps0; for (xx = 0; xx < x0; xx++) { *dst0 = init; dst0 += x_inc; } for (xx = x0; xx < x1; xx++) { *dst0 = *src0; dst0 += x_inc; x_eps += w_dst2; while (x_eps >= 0) { src0 += x_inc; x_eps -= dx2; } } for (xx = x1; xx < w_dst; xx++) { *dst0 = init; dst0 += x_inc; } dst += y_inc; y_eps += h_dst2; while (y_eps >= 0) { src += y_inc; y_eps -= dy2; } } for (yy = y1; yy < h_dst; yy++) { uint8_t *dst0 = dst; for (xx = 0; xx < w_dst; xx++) { *dst0 = init; dst0 += x_inc; } dst += y_inc; } } static void vdr_video_scale_YUY2(vdr_video_post_plugin_t *this, vo_frame_t *src, vo_frame_t *dst) { int w = dst->width - dst->crop_left - dst->crop_right; int h = dst->height - dst->crop_top - dst->crop_bottom; int offset; if (w < 0) w = 0; if (h < 0) h = 0; offset = dst->pitches[ 0 ] * dst->crop_top + 2 * dst->crop_left; vdr_video_scale(&src->base[ 0 ][ 0 ] + offset, &dst->base[ 0 ][ 0 ] + offset, dst->pitches[ 0 ], 2, w , h, this->x, this->y, this->w, this->h, this->w_ref, this->h_ref, 0x00); offset = dst->pitches[ 0 ] * dst->crop_top + 4 * ((dst->crop_left + 1) / 2); vdr_video_scale(&src->base[ 0 ][ 1 ] + offset, &dst->base[ 0 ][ 1 ] + offset, dst->pitches[ 0 ], 4, (w + 1) / 2, h, this->x, this->y, this->w, this->h, this->w_ref, this->h_ref, 0x80); offset = dst->pitches[ 0 ] * dst->crop_top + 4 * ((dst->crop_left + 1) / 2); vdr_video_scale(&src->base[ 0 ][ 3 ] + offset, &dst->base[ 0 ][ 3 ] + offset, dst->pitches[ 0 ], 4, (w + 1) / 2, h, this->x, this->y, this->w, this->h, this->w_ref, this->h_ref, 0x80); } static void vdr_video_scale_YV12(vdr_video_post_plugin_t *this, vo_frame_t *src, vo_frame_t *dst) { int w = dst->width - dst->crop_left - dst->crop_right; int h = dst->height - dst->crop_top - dst->crop_bottom; int offset; if (w < 0) w = 0; if (h < 0) h = 0; offset = dst->pitches[ 0 ] * dst->crop_top + 1 * dst->crop_left; vdr_video_scale(&src->base[ 0 ][ 0 ] + offset, &dst->base[ 0 ][ 0 ] + offset, dst->pitches[ 0 ], 1, w , h , this->x, this->y, this->w, this->h, this->w_ref, this->h_ref, 0x00); offset = dst->pitches[ 1 ] * ((dst->crop_top + 1) / 2) + 1 * ((dst->crop_left + 1) / 2); vdr_video_scale(&src->base[ 1 ][ 0 ] + offset, &dst->base[ 1 ][ 0 ] + offset, dst->pitches[ 1 ], 1, (w + 1) / 2, (h + 1) / 2, this->x, this->y, this->w, this->h, this->w_ref, this->h_ref, 0x80); offset = dst->pitches[ 2 ] * ((dst->crop_top + 1) / 2) + 1 * ((dst->crop_left + 1) / 2); vdr_video_scale(&src->base[ 2 ][ 0 ] + offset, &dst->base[ 2 ][ 0 ] + offset, dst->pitches[ 2 ], 1, (w + 1) / 2, (h + 1) / 2, this->x, this->y, this->w, this->h, this->w_ref, this->h_ref, 0x80); } static int vdr_video_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; vdr_video_post_plugin_t *this = (vdr_video_post_plugin_t *)port->post; vo_frame_t *vdr_frame; xine_event_t *event; int skip; if (this->vdr_stream && !_x_continue_stream_processing(this->vdr_stream)) { this->vdr_stream = 0; xine_event_dispose_queue(this->event_queue); this->event_queue = 0; this->old_frame_left = 0; this->old_frame_top = 0; this->old_frame_width = 0; this->old_frame_height = 0; this->old_frame_ratio = 0; } if (!this->vdr_stream && vdr_is_vdr_stream(stream)) { this->event_queue = xine_event_new_queue(stream); if (this->event_queue) { this->vdr_stream = stream; { xine_event_t event; event.type = XINE_EVENT_VDR_PLUGINSTARTED; event.data = 0; event.data_length = 0; /* vdr_video */ xine_event_send(this->vdr_stream, &event); } } } if (this->event_queue) { while ((event = xine_event_get(this->event_queue))) { if (event->type == XINE_EVENT_VDR_SETVIDEOWINDOW) { vdr_set_video_window_data_t *data = (vdr_set_video_window_data_t *)event->data; vdr_video_set_video_window(this, data->x, data->y, data->w, data->h, data->w_ref, data->h_ref); } else if (event->type == XINE_EVENT_VDR_TRICKSPEEDMODE) { /* fprintf(stderr, "###############################: %p, %d\n", event->data, event->data_length); this->trick_speed_mode = (0 != event->data_length); */ } xine_event_free(event); } } { int32_t frame_left = frame->crop_left; int32_t frame_width = frame->width - frame->crop_left - frame->crop_right; int32_t frame_top = frame->crop_top; int32_t frame_height = frame->height - frame->crop_top - frame->crop_bottom; double frame_ratio = frame->ratio; if (frame_left < 0) frame_left = 0; if (frame_width > frame->width) frame_width = frame->width; if (frame_top < 0) frame_top = 0; if (frame_height > frame->height) frame_height = frame->height; if (this->vdr_stream && frame_width != 0 && frame_height != 0 && (this->old_frame_left != frame_left || this->old_frame_top != frame_top || this->old_frame_width != frame_width || this->old_frame_height != frame_height || this->old_frame_ratio != frame_ratio)) { xine_event_t event; vdr_frame_size_changed_data_t event_data; event_data.x = frame_left; event_data.y = frame_top; event_data.w = frame_width; event_data.h = frame_height; event_data.r = frame_ratio; xprintf(this->vdr_stream->xine, XINE_VERBOSITY_LOG, _(LOG_MODULE ": osd: (%d, %d)-(%d, %d)@%lg\n"), frame_left, frame_top, frame_width, frame_height, frame_ratio); event.type = XINE_EVENT_VDR_FRAMESIZECHANGED; event.data = &event_data; event.data_length = sizeof (event_data); xine_event_send(this->vdr_stream, &event); this->old_frame_left = frame_left; this->old_frame_top = frame_top; this->old_frame_width = frame_width; this->old_frame_height = frame_height; this->old_frame_ratio = frame_ratio; } } /* fprintf(stderr, "~~~~~~~~~~~~ trickspeedmode: %d\n", this->trick_speed_mode); if (this->vdr_stream && this->trick_speed_mode) { frame->pts = 0; frame->next->pts = 0; } */ #if defined(LOG) && defined(LOG_VERBOSE) { int a = 0, b = 0, c = 0, d = 0; if (stream) _x_query_buffer_usage(stream, &a, &b, &c, &d); lprintf("buffer usage: %3d, %2d, %2d, %2d, %p\n", a, b, c, d, stream); } #endif if (!this->enabled || frame->bad_frame || (frame->format != XINE_IMGFMT_YUY2 && frame->format != XINE_IMGFMT_YV12) || frame->proc_frame || frame->proc_slice) { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); return skip; } vdr_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, frame->format, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, vdr_frame); switch (vdr_frame->format) { case XINE_IMGFMT_YUY2: vdr_video_scale_YUY2(this, frame, vdr_frame); break; case XINE_IMGFMT_YV12: vdr_video_scale_YV12(this, frame, vdr_frame); break; } skip = vdr_frame->draw(vdr_frame, stream); _x_post_frame_copy_up(frame, vdr_frame); vdr_frame->free(vdr_frame); return skip; } xine-lib-1.2/src/vdr/post_vdr_audio.c0000644000175000017500000001637114647725152015443 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * select audio channel plugin for VDR */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "vdr_audio" #define LOG_VERBOSE /* #define LOG */ #include #include #include "combined_vdr.h" typedef struct vdr_audio_post_plugin_s { post_plugin_t post_plugin; xine_event_queue_t *event_queue; xine_stream_t *vdr_stream; uint8_t audio_channels; int num_channels; } vdr_audio_post_plugin_t; static void vdr_audio_select_audio(vdr_audio_post_plugin_t *this, uint8_t channels) { this->audio_channels = channels; } /* plugin class functions */ static post_plugin_t *vdr_audio_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target); /* plugin instance functions */ static void vdr_audio_dispose(post_plugin_t *this_gen); /* replaced ao_port functions */ static int vdr_audio_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode); static void vdr_audio_port_put_buffer(xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream); void *vdr_audio_init_plugin(xine_t *xine, const void *data) { post_class_t *class = calloc(1, sizeof (post_class_t)); (void)xine; (void)data; if (!class) return NULL; class->open_plugin = vdr_audio_open_plugin; class->identifier = "vdr_audio"; class->description = N_("modifies every audio frame as requested by VDR"); class->dispose = default_post_class_dispose; return class; } static post_plugin_t *vdr_audio_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { vdr_audio_post_plugin_t *this = calloc(1, sizeof (vdr_audio_post_plugin_t)); post_in_t *input; post_out_t *output; post_audio_port_t *port; /* fprintf(stderr, "~~~~~~~~~~ vdr open plugin\n"); */ if (!this || !audio_target || !audio_target[ 0 ]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)video_target; _x_post_init(&this->post_plugin, 1, 0); this->post_plugin.dispose = vdr_audio_dispose; port = _x_post_intercept_audio_port(&this->post_plugin, audio_target[ 0 ], &input, &output); port->new_port.open = vdr_audio_port_open; port->new_port.put_buffer = vdr_audio_port_put_buffer; this->post_plugin.xine_post.audio_input[ 0 ] = &port->new_port; this->audio_channels = 0; return &this->post_plugin; } static void vdr_audio_dispose(post_plugin_t *this_gen) { /* fprintf(stderr, "~~~~~~~~~~ vdr dispose\n"); */ if (_x_post_dispose(this_gen)) { vdr_audio_post_plugin_t *this = (vdr_audio_post_plugin_t *)this_gen; if (this->vdr_stream) xine_event_dispose_queue(this->event_queue); free(this_gen); } } static int vdr_audio_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; vdr_audio_post_plugin_t *this = (vdr_audio_post_plugin_t *)port->post; _x_post_rewire(&this->post_plugin); _x_post_inc_usage(port); /* fprintf(stderr, "~~~~~~~~~~ vdr port open\n"); */ port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->num_channels = _x_ao_mode2channels(mode); return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } static void vdr_audio_port_put_buffer(xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; vdr_audio_post_plugin_t *this = (vdr_audio_post_plugin_t *)port->post; xine_event_t *event; /* fprintf(stderr, "~~~~~~ vdr_audio\n"); */ if (this->vdr_stream && !_x_continue_stream_processing(this->vdr_stream)) { this->vdr_stream = 0; xine_event_dispose_queue(this->event_queue); this->event_queue = 0; this->audio_channels = 0; } if (!this->vdr_stream && vdr_is_vdr_stream(stream)) { this->event_queue = xine_event_new_queue(stream); if (this->event_queue) { this->vdr_stream = stream; { xine_event_t event; event.type = XINE_EVENT_VDR_PLUGINSTARTED; event.data = 0; event.data_length = 1; /* vdr_audio */ xine_event_send(this->vdr_stream, &event); } } } if (this->event_queue) { while ((event = xine_event_get(this->event_queue))) { if (event->type == XINE_EVENT_VDR_SELECTAUDIO) { vdr_select_audio_data_t *data = (vdr_select_audio_data_t *)event->data; vdr_audio_select_audio(this, data->channels); } xine_event_free(event); } } if (this->num_channels == 2 && this->audio_channels != 0 && this->audio_channels != 3) { audio_buffer_t *vdr_buf = port->original_port->get_buffer(port->original_port); vdr_buf->num_frames = buf->num_frames; vdr_buf->vpts = buf->vpts; vdr_buf->frame_header_count = buf->frame_header_count; vdr_buf->first_access_unit = buf->first_access_unit; /* FIXME: The audio buffer should contain this info. * We should not have to get it from the open call. */ vdr_buf->format.bits = buf->format.bits; vdr_buf->format.rate = buf->format.rate; vdr_buf->format.mode = buf->format.mode; _x_extra_info_merge(vdr_buf->extra_info, buf->extra_info); { int step = buf->format.bits / 8; uint8_t *src = (uint8_t *)buf->mem; uint8_t *dst = (uint8_t *)vdr_buf->mem; if (this->audio_channels == 2) src += step; /* fprintf(stderr, "~~~~~~~~~~ vdr port put buffer: channels: %d, %d\n" , this->audio_channels , buf->format.bits); */ int i, k; for (i = 0; i < buf->num_frames; i++) { for (k = 0; k < step; k++) *dst++ = *src++; src -= step; for (k = 0; k < step; k++) *dst++ = *src++; src += step; } } /* pass data to original port */ port->original_port->put_buffer(port->original_port, vdr_buf, stream); /* free data from origial buffer */ buf->num_frames = 0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */ } port->original_port->put_buffer(port->original_port, buf, stream); return; } xine-lib-1.2/src/video_out/0000755000175000017500000000000014647725152013450 5ustar memexine-lib-1.2/src/video_out/x11osd.h0000644000175000017500000000313314647725152014740 0ustar meme/* * Copyright (C) 2003-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * x11osd.h, use X11 Nonrectangular Window Shape Extension to draw xine OSD * * Nov 2003 - Miguel Freitas * * based on ideas and code of * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net) */ #ifndef X11OSD_H #define X11OSD_H #include typedef struct x11osd x11osd; enum x11osd_mode {X11OSD_SHAPED, X11OSD_COLORKEY}; x11osd *x11osd_create (xine_t *xine, Display *display, int screen, Window window, enum x11osd_mode mode); void x11osd_colorkey(x11osd * osd, uint32_t colorkey, vo_scale_t *scaling); void x11osd_destroy (x11osd * osd); void x11osd_expose (x11osd * osd); void x11osd_resize (x11osd * osd, int width, int height); void x11osd_drawable_changed (x11osd * osd, Window window); void x11osd_clear(x11osd *osd); void x11osd_blend(x11osd *osd, vo_overlay_t *overlay); #endif xine-lib-1.2/src/video_out/color_matrix.c0000644000175000017500000002347014647725152016324 0ustar meme/* * Copyright (C) 2012-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ /* TJ. the output color matrix selection feature. Example use: */ #if 0 #define CM_LUT /* recommended optimization */ typedef struct { ... int cm_state; #ifdef CM_LUT uint8_t cm_lut[32]; #endif ... } xxxx_driver_t; #define CM_HAVE_YCGCO_SUPPORT /* if you already handle that */ #define CM_DRIVER_T xxxx_driver_t #include "color_matrix.c" #endif /* cm_from_frame () returns current (color_matrix << 1) | color_range control value. Having only 1 var simplifies change event handling and avoids unecessary vo reconfiguration. In the libyuv2rgb case, they are even handled by same code. In theory, HD video uses a different YUV->RGB matrix than the rest. It shall come closer to the human eye's brightness feel, and give more shades of green even without higher bit depth. I discussed this topic with local TV engineers earlier. They say their studio equipment throws around uncompressed YUV with no extra info attached to it. Anything smaller than 720p is assumed to be ITU-R 601, otherwise ITU-R 709. A rematrix filter applies whenever video is scaled across the above mentioned HD threshold. However, the weak point of their argumentation is potentially non-standard input material. Those machines obviously dont verify input data, and ocasionally they dont even respect stream info (tested by comparing TV against retail DVD version of same movie). Consumer TV sets handle this fairly inconsistent - stream info, video size, hard-wired matrix, user choice or so-called intelligent picture enhancers that effectively go way off standards. So I decided to provide functionality, and let the user decide if and how to actually use it. */ /* eveybody gets these */ /* user configuration settings */ #define CM_CONFIG_NAME "video.output.color_matrix" #define CM_CONFIG_SIGNAL 0 #define CM_CONFIG_SIZE 1 #define CM_CONFIG_SD 2 #define CM_CONFIG_HD 3 #define CR_CONFIG_NAME "video.output.color_range" #define CR_CONFIG_AUTO 0 #define CR_CONFIG_MPEG 1 #define CR_CONFIG_FULL 2 static const char * const cm_names[] = { "RGB", "RGB", "ITU-R 709 / HDTV", "full range ITU-R 709 / HDTV", "undefined", "full range, undefined", "ITU-R 470 BG / SDTV", "full range ITU-R 470 BG / SDTV", "FCC", "full range FCC", "ITU-R 470 BG / SDTV", "full range ITU-R 470 BG / SDTV", "SMPTE 170M", "full range SMPTE 170M", "SMPTE 240M", "full range SMPTE 240M", #if defined(CM_HAVE_YCGCO_SUPPORT) || defined(CM_HAVE_BT2020_SUPPORT) "YCgCo", "YCgCo", /* this is always fullrange */ "BT.2020 NCL", "fullrange BT.2020 NCL", "BT.2020 CL", "fullrange BT.2020 CL", "#11", "fullrange #11", "#12", "fullrange #12", "#13", "fullrange #13", "#14", "fullrange #14", "#15", "fullrange #15", #endif }; #ifdef CM_DRIVER_T /* this is for vo plugins only */ /* the option names */ static const char * const cm_conf_labels[] = { "Signal", "Signal+Size", "SD", "HD", NULL }; static const char * const cr_conf_labels[] = { "Auto", "MPEG", "FULL", NULL }; #ifdef CM_HAVE_YCGCO_SUPPORT # define CM_G 16 #else # define CM_G 10 #endif #ifdef CM_HAVE_BT2020_SUPPORT # define CM_2020 18,20 #else # define CM_2020 10,10 #endif static #ifdef CM_LUT const #endif uint8_t cm_m[] = { 10, 2,10, 6, 8,10,12,14,CM_G,CM_2020,10,10,10,10,10, /* SIGNAL */ 10, 2, 0, 6, 8,10,12,14,CM_G,CM_2020,10,10,10,10,10, /* SIZE */ 10,10,10,10,10,10,10,10,CM_G, 10, 10,10,10,10,10,10, /* SD */ 10, 2, 2, 2, 2, 2, 2, 2,CM_G, 2, 2, 2, 2, 2, 2, 2 /* HD */ }; static void cm_lut_setup (CM_DRIVER_T *this) { #ifdef CM_LUT { const uint8_t *a = cm_m + ((this->cm_state >> 2) << 4); uint8_t *d = this->cm_lut, *e = d + 32; while (d < e) { d[0] = d[1] = *a++; d += 2; } } if ((this->cm_state & 3) == CR_CONFIG_AUTO) { /* keep range */ int i; for (i = 1; i < 32; i += 2) this->cm_lut[i] |= 1; } else if ((this->cm_state & 3) == CR_CONFIG_FULL) { /* force full range */ int i; for (i = 0; i < 32; i += 1) this->cm_lut[i] |= 1; } #endif } /* callback when user changes them */ static void cm_cb_config (void *this_gen, xine_cfg_entry_t *entry) { CM_DRIVER_T *this = (CM_DRIVER_T *)this_gen; this->cm_state = (this->cm_state & 3) | (entry->num_value << 2); cm_lut_setup (this); } static void cr_cb_config (void *this_gen, xine_cfg_entry_t *entry) { CM_DRIVER_T *this = (CM_DRIVER_T *)this_gen; this->cm_state = (this->cm_state & 0x1c) | entry->num_value; cm_lut_setup (this); } static void cm_init (CM_DRIVER_T *this) { /* register configuration */ this->cm_state = this->xine->config->register_enum ( this->xine->config, CM_CONFIG_NAME, CM_CONFIG_SIZE, (char **)cm_conf_labels, _("Output colour matrix"), _("Tell how output colours should be calculated.\n\n" "Signal: Do as current stream suggests.\n" " This may be wrong sometimes.\n\n" "Signal+Size: Same as above,\n" " but assume HD colour for unmarked HD streams.\n\n" "SD: Force SD video standard ITU-R 470/601.\n" " Try this if you get too little green.\n\n" "HD: Force HD video standard ITU-R 709.\n" " Try when there is too much green coming out.\n\n"), 10, cm_cb_config, this ) << 2; this->cm_state |= this->xine->config->register_enum ( this->xine->config, CR_CONFIG_NAME, CR_CONFIG_AUTO, (char **)cr_conf_labels, _("Output colour range"), _("Tell how output colours should be ranged.\n\n" "Auto: Do as current stream suggests.\n" " This may be wrong sometimes.\n\n" "MPEG: Force MPEG colour range (16..235) / studio swing / video mode.\n" " Try if image looks dull (no real black or white in it).\n\n" "FULL: Force FULL colour range (0..255) / full swing / PC mode.\n" " Try when flat black and white spots appear.\n\n"), 10, cr_cb_config, this ); cm_lut_setup (this); } static int cm_from_frame (vo_frame_t *frame) { CM_DRIVER_T *this = (CM_DRIVER_T *)frame->driver; int cm = VO_GET_FLAGS_CM (frame->flags); #ifdef CM_LUT cm = this->cm_lut[cm & 31]; if (cm & ~1) return cm; return cm | ((frame->height - frame->crop_top - frame->crop_bottom >= 720) || (frame->width - frame->crop_left - frame->crop_right >= 1280) ? 2 : 10); #else static uint8_t cm_r[] = {0, 0, 1, 0}; /* AUTO, MPEG, FULL, safety */ int cf = this->cm_state; cm_m[18] = (frame->height - frame->crop_top - frame->crop_bottom >= 720) || (frame->width - frame->crop_left - frame->crop_right >= 1280) ? 2 : 10; cm_r[0] = cm & 1; return cm_m[((cf >> 2) << 4) | (cm >> 1)] | cm_r[cf & 3]; #endif } static inline void cm_fill_matrix(float *matrix, int color_matrix, float hue, float saturation, float contrast, float brightness) { float uvcos = saturation * cos( hue ); float uvsin = saturation * sin( hue ); int i; if ((color_matrix >> 1) == 8) { /* YCgCo. This is really quite simple. */ uvsin *= contrast; uvcos *= contrast; /* matrix[rgb][yuv1] */ matrix[1] = -1.0 * uvcos - 1.0 * uvsin; matrix[2] = 1.0 * uvcos - 1.0 * uvsin; matrix[5] = 1.0 * uvcos; matrix[6] = 1.0 * uvsin; matrix[9] = -1.0 * uvcos + 1.0 * uvsin; matrix[10] = -1.0 * uvcos - 1.0 * uvsin; for (i = 0; i < 12; i += 4) { matrix[i] = contrast; matrix[i + 3] = (brightness * contrast - 128.0 * (matrix[i + 1] + matrix[i + 2])) / 255.0; } } else { /* YCbCr */ float kb, kr; float vr, vg, ug, ub; float ygain, yoffset; switch (color_matrix >> 1) { case 1: kb = 0.0722; kr = 0.2126; break; /* ITU-R 709 */ case 4: kb = 0.1100; kr = 0.3000; break; /* FCC */ case 7: kb = 0.0870; kr = 0.2120; break; /* SMPTE 240 */ case 10: case 9: kb = 0.0593; kr = 0.2627; break; /* BT.2020 */ default: kb = 0.1140; kr = 0.2990; /* ITU-R 601 */ } vr = 2.0 * (1.0 - kr); vg = -2.0 * kr * (1.0 - kr) / (1.0 - kb - kr); ug = -2.0 * kb * (1.0 - kb) / (1.0 - kb - kr); ub = 2.0 * (1.0 - kb); if (color_matrix & 1) { /* fullrange mode */ yoffset = brightness; ygain = contrast; uvcos *= contrast * 255.0 / 254.0; uvsin *= contrast * 255.0 / 254.0; } else { /* mpeg range */ yoffset = brightness - 16.0; ygain = contrast * 255.0 / 219.0; uvcos *= contrast * 255.0 / 224.0; uvsin *= contrast * 255.0 / 224.0; } /* matrix[rgb][yuv1] */ matrix[1] = -uvsin * vr; matrix[2] = uvcos * vr; matrix[5] = uvcos * ug - uvsin * vg; matrix[6] = uvcos * vg + uvsin * ug; matrix[9] = uvcos * ub; matrix[10] = uvsin * ub; for (i = 0; i < 12; i += 4) { matrix[i] = ygain; matrix[i + 3] = (yoffset * ygain - 128.0 * (matrix[i + 1] + matrix[i + 2])) / 255.0; } } } static void cm_close (CM_DRIVER_T *this) { /* dont know whether this is really necessary */ this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, this, sizeof (*this)); } #endif /* defined CM_DRIVER_T */ xine-lib-1.2/src/video_out/video_out_caca.c0000644000175000017500000002466614647725152016576 0ustar meme/* * Copyright (C) 2003-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_caca.c, Color AsCii Art output plugin for xine */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_CUCUL # include # define caca_canvas_t cucul_canvas_t # define caca_create_canvas cucul_create_canvas # define caca_get_canvas_width cucul_get_canvas_width # define caca_get_canvas_height cucul_get_canvas_height # define caca_free_canvas cucul_free_canvas # define caca_dither_t cucul_dither_t # define caca_create_dither cucul_create_dither # define caca_dither_bitmap cucul_dither_bitmap # define caca_free_dither cucul_free_dither #endif #include #include "xine.h" #include #include #include "yuv2rgb.h" #include /* * structures */ typedef struct caca_frame_s { vo_frame_t vo_frame; caca_dither_t *pixmap_s; /* pixmap info structure */ uint8_t *pixmap_d; /* pixmap data */ unsigned int width, height; int format; /* XINE_IMGFMT_* flags */ yuv2rgb_t *yuv2rgb; } caca_frame_t; typedef struct { vo_driver_t vo_driver; xine_t *xine; int user_ratio; yuv2rgb_factory_t *yuv2rgb_factory; caca_canvas_t *cv; caca_display_t *dp; } caca_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } caca_class_t; /* * video driver */ static uint32_t caca_get_capabilities (vo_driver_t *this) { (void)this; return VO_CAP_YV12 | VO_CAP_YUY2; } static void caca_dispose_frame (vo_frame_t *vo_img) { caca_frame_t *frame = (caca_frame_t *)vo_img; xine_free_aligned (frame->vo_frame.base[0]); xine_free_aligned (frame->vo_frame.base[1]); xine_free_aligned (frame->vo_frame.base[2]); free (frame->pixmap_d); if (frame->pixmap_s) caca_free_dither (frame->pixmap_s); frame->yuv2rgb->dispose (frame->yuv2rgb); free (frame); } static void caca_frame_field (vo_frame_t *vo_img, int which_field) { /* nothing to be done here */ (void)vo_img; (void)which_field; } static vo_frame_t *caca_alloc_frame(vo_driver_t *this_gen) { caca_driver_t *this = (caca_driver_t*) this_gen; caca_frame_t *frame; frame = calloc(1, sizeof (caca_frame_t)); if (!frame) return NULL; /* colorspace converter for this frame */ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory); if (!frame->yuv2rgb) { free(frame); return NULL; } pthread_mutex_init(&frame->vo_frame.mutex, NULL); frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = caca_frame_field; frame->vo_frame.dispose = caca_dispose_frame; frame->vo_frame.driver = this_gen; return (vo_frame_t*) frame; } static void caca_update_frame_format (vo_driver_t *this_gen, vo_frame_t *img, uint32_t width, uint32_t height, double ratio, int format, int flags) { caca_driver_t *this = (caca_driver_t*) this_gen; caca_frame_t *frame = (caca_frame_t *) img; (void)flags; (void)ratio; if ((frame->width != width) || (frame->height != height) || (frame->format != format)) { xine_freep_aligned (&frame->vo_frame.base[0]); xine_freep_aligned (&frame->vo_frame.base[1]); xine_freep_aligned (&frame->vo_frame.base[2]); _x_freep (&frame->pixmap_d); if (frame->pixmap_s) { caca_free_dither (frame->pixmap_s); frame->pixmap_s = NULL; } frame->width = width; frame->height = height; frame->format = format; frame->pixmap_d = (uint8_t *) calloc (height, width * 4); frame->pixmap_s = caca_create_dither (32, width, height, width * 4, 0xff0000, 0xff00, 0xff, 0); if (format == XINE_IMGFMT_YV12) { frame->vo_frame.pitches[0] = 8*((width + 7) / 8); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = xine_mallocz_aligned(frame->vo_frame.pitches[1] * ((height+1)/2)); frame->vo_frame.base[2] = xine_mallocz_aligned(frame->vo_frame.pitches[2] * ((height+1)/2)); frame->yuv2rgb->configure (frame->yuv2rgb, width, height, frame->vo_frame.pitches[0], frame->vo_frame.pitches[1], width, height, width * 4); } else if (format == XINE_IMGFMT_YUY2) { frame->vo_frame.pitches[0] = 8*((width + 3) / 4); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); frame->yuv2rgb->configure (frame->yuv2rgb, width, height, frame->vo_frame.pitches[0], frame->vo_frame.pitches[0], width, height, width * 4); } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "alert! unsupported image format %04x\n", format); frame->vo_frame.width = frame->width = 0; } } } static void caca_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { /* caca_driver_t *this = (caca_driver_t*) this_gen; */ caca_frame_t *frame = (caca_frame_t *) frame_gen; caca_driver_t *this = (caca_driver_t*) this_gen; if (frame->format == XINE_IMGFMT_YV12) { frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->pixmap_d, frame->vo_frame.base[0], frame->vo_frame.base[1], frame->vo_frame.base[2]); } else { /* frame->format == XINE_IMGFMT_YUY2 */ frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->pixmap_d, frame->vo_frame.base[0]); } frame->vo_frame.free (&frame->vo_frame); caca_dither_bitmap(this->cv, 0, 0, caca_get_canvas_width(this->cv)-1, caca_get_canvas_height(this->cv)-1, frame->pixmap_s, frame->pixmap_d); caca_refresh_display (this->dp); } static int caca_get_property (vo_driver_t *this_gen, int property) { caca_driver_t *this = (caca_driver_t*) this_gen; if ( property == VO_PROP_ASPECT_RATIO) { return this->user_ratio; } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_caca: tried to get unsupported property %d\n", property); } return 0; } static int caca_set_property (vo_driver_t *this_gen, int property, int value) { caca_driver_t *this = (caca_driver_t*) this_gen; if ( property == VO_PROP_ASPECT_RATIO) { if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->user_ratio = value; } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_caca: tried to set unsupported property %d\n", property); } return value; } static void caca_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { (void)this_gen; (void)property; *min = 0; *max = 0; } static void caca_dispose_driver (vo_driver_t *this_gen) { caca_driver_t *this = (caca_driver_t*) this_gen; this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); caca_free_display(this->dp); caca_free_canvas(this->cv); free(this); } static int caca_redraw_needed (vo_driver_t *this_gen) { (void)this_gen; return 0; } static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { caca_class_t *class = (caca_class_t *) class_gen; caca_display_t *dp = (caca_display_t *)visual_gen; caca_driver_t *this; this = calloc(1, sizeof (caca_driver_t)); if (!this) return NULL; this->xine = class->xine; this->vo_driver.get_capabilities = caca_get_capabilities; this->vo_driver.alloc_frame = caca_alloc_frame; this->vo_driver.update_frame_format = caca_update_frame_format; this->vo_driver.display_frame = caca_display_frame; this->vo_driver.overlay_begin = NULL; this->vo_driver.overlay_blend = NULL; this->vo_driver.overlay_end = NULL; this->vo_driver.get_property = caca_get_property; this->vo_driver.set_property = caca_set_property; this->vo_driver.get_property_min_max = caca_get_property_min_max; this->vo_driver.gui_data_exchange = NULL; this->vo_driver.redraw_needed = caca_redraw_needed; this->vo_driver.dispose = caca_dispose_driver; this->yuv2rgb_factory = yuv2rgb_factory_init(MODE_32_RGB, 0, NULL); if (!this->yuv2rgb_factory) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": yuv2rgb initialization failed\n"); free(this); return NULL; } this->yuv2rgb_factory->set_csc_levels(this->yuv2rgb_factory, 0, 128, 128, CM_DEFAULT); if (dp) { this->cv = caca_get_canvas(dp); this->dp = dp; } else { this->cv = caca_create_canvas(0, 0); this->dp = caca_create_display(this->cv); } caca_refresh_display(this->dp); return &this->vo_driver; } static void *init_class (xine_t *xine, const void *visual_gen) { caca_class_t *this; (void)visual_gen; this = calloc(1, sizeof(caca_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "CACA"; this->driver_class.description = N_("xine video output plugin using the Color AsCii Art library"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_caca = { .priority = 6, .visual_type = XINE_VISUAL_TYPE_CACA, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "caca", XINE_VERSION_CODE, &vo_info_caca, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_xvmc.c0000644000175000017500000015263014647725152016655 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_xvmc.c, X11 video motion compensation extension interface for xine * * based on mpeg2dec code from * Aaron Holtzman * * XvMC image support by Jack Kelliher * * TODO: * - support non-XvMC output, probably falling back to Xv. * - support XvMC overlays for spu/osd */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_XVMC #include #include #include #include #include #include #if defined(__FreeBSD__) #include #endif #include #include #include #include #include #include #include #include #include #include #include #define LOG_MODULE "video_out_xvmc" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include #include #include "accel_xvmc.h" #include #include #include "xv_common.h" /* #define LOG1 */ /* #define DLOG */ /* #define PRINTDATA */ /* #define PRINTFRAME */ #define MAX_NUM_FRAMES 8 typedef struct { xine_macroblocks_t xine_mc; XvMCBlockArray *blocks; /* pointer to memory for dct block array */ int num_blocks; XvMCMacroBlock *macroblockptr; /* pointer to current macro block */ XvMCMacroBlock *macroblockbaseptr; /* pointer to base MacroBlock in MB array */ XvMCMacroBlockArray *macro_blocks; /* pointer to memory for macroblock array */ int slices; } xvmc_macroblocks_t; typedef struct { void *xid; } cxid_t; typedef struct xvmc_driver_s xvmc_driver_t; typedef struct { int value; int min; int max; Atom atom; cfg_entry_t *entry; xvmc_driver_t *this; } xvmc_property_t; typedef struct { vo_frame_t vo_frame; int width, height, format; double ratio; XvMCSurface surface; /* temporary Xv only storage */ xine_xvmc_t xvmc_data; } xvmc_frame_t; struct xvmc_driver_s { vo_driver_t vo_driver; config_values_t *config; /* X11 / XvMC related stuff */ Display *display; int screen; Drawable drawable; unsigned int xvmc_format_yv12; unsigned int xvmc_format_yuy2; XVisualInfo vinfo; GC gc; XvPortID xv_port; XvMCContext context; xvmc_frame_t *frames[MAX_NUM_FRAMES]; int surface_type_id; int max_surface_width; int max_surface_height; int num_frame_buffers; int surface_width; int surface_height; int surface_ratio; int surface_format; int surface_flags; short acceleration; cxid_t context_id; xvmc_macroblocks_t macroblocks; /* all scaling information goes here */ vo_scale_t sc; XColor black; /* display anatomy */ double display_ratio; /* given by visual parameter from init function */ xvmc_property_t props[VO_NUM_PROPERTIES]; uint32_t capabilities; xvmc_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; xvmc_frame_t *cur_frame; vo_overlay_t *overlay; /* TODO CLEAN THIS UP all unused vars sizes moved to vo_scale */ /* size / aspect ratio calculations */ /* * "delivered" size: * frame dimension / aspect as delivered by the decoder * used (among other things) to detect frame size changes */ int delivered_duration; /* * "ideal" size : * displayed width/height corrected by aspect ratio */ double ratio_factor; /* output frame must fullfill: height = width * ratio_factor */ /* gui callback */ void (*frame_output_cb) (void *user_data, int video_width, int video_height, int *dest_x, int *dest_y, int *dest_height, int *dest_width, int *win_x, int *win_y); int use_colorkey; uint32_t colorkey; void *user_data; xine_t *xine; alphablend_t alphablend_extra_data; }; typedef struct { video_driver_class_t driver_class; Display *display; XvPortID xv_port; XvAdaptorInfo *adaptor_info; unsigned int adaptor_num; int surface_type_id; unsigned int max_surface_width; unsigned int max_surface_height; short acceleration; xine_t *xine; } xvmc_class_t; static void xvmc_render_macro_blocks(vo_frame_t *current_image, vo_frame_t *backward_ref_image, vo_frame_t *forward_ref_image, int picture_structure, int second_field, xvmc_macroblocks_t *macroblocks); /*********************** XVMC specific routines *********************/ /**************************************************************************/ /* * dmvector: differential motion vector * mvx, mvy: decoded mv components (always in field format) */ static void calc_DMV(int DMV[][2], int *dmvector, int mvx, int mvy, int picture_structure, int top_field_first) { if (picture_structure==VO_BOTH_FIELDS) { if (top_field_first) { /* vector for prediction of top field from bottom field */ DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1; /* vector for prediction of bottom field from top field */ DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1; } else { /* vector for prediction of top field from bottom field */ DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1; /* vector for prediction of bottom field from top field */ DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1; } } else { /* vector for prediction from field of opposite 'parity' */ DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0]; DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1]; /* correct for vertical field shift */ if (picture_structure==VO_TOP_FIELD) DMV[0][1]--; else DMV[0][1]++; } } static void xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type, int (*mv_field_sel)[2], int *dmvector, int cbp, int dct_type, vo_frame_t *current_frame, vo_frame_t *forward_ref_frame, vo_frame_t *backward_ref_frame, int picture_structure, int second_field, int (*f_mot_pmv)[2], int (*b_mot_pmv)[2]) { xvmc_driver_t *this = (xvmc_driver_t *) current_frame->driver; xvmc_macroblocks_t *mbs = &this->macroblocks; int top_field_first = current_frame->top_field_first; int picture_coding_type = current_frame->picture_coding_type; mbs->macroblockptr->x = x; mbs->macroblockptr->y = y; if(mb_type & XINE_MACROBLOCK_INTRA) { mbs->macroblockptr->macroblock_type = XVMC_MB_TYPE_INTRA; } else { mbs->macroblockptr->macroblock_type = 0; /* XvMC doesn't support skips */ if(!(mb_type & (XINE_MACROBLOCK_MOTION_BACKWARD | XINE_MACROBLOCK_MOTION_FORWARD))) { mb_type |= XINE_MACROBLOCK_MOTION_FORWARD; motion_type = (picture_structure == VO_BOTH_FIELDS) ? XINE_MC_FRAME : XINE_MC_FIELD; mbs->macroblockptr->PMV[0][0][0] = 0; mbs->macroblockptr->PMV[0][0][1] = 0; } else { if(mb_type & XINE_MACROBLOCK_MOTION_BACKWARD) { mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD; mbs->macroblockptr->PMV[0][1][0] = b_mot_pmv[0][0]; mbs->macroblockptr->PMV[0][1][1] = b_mot_pmv[0][1]; mbs->macroblockptr->PMV[1][1][0] = b_mot_pmv[1][0]; mbs->macroblockptr->PMV[1][1][1] = b_mot_pmv[1][1]; } if(mb_type & XINE_MACROBLOCK_MOTION_FORWARD) { mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD; mbs->macroblockptr->PMV[0][0][0] = f_mot_pmv[0][0]; mbs->macroblockptr->PMV[0][0][1] = f_mot_pmv[0][1]; mbs->macroblockptr->PMV[1][0][0] = f_mot_pmv[1][0]; mbs->macroblockptr->PMV[1][0][1] = f_mot_pmv[1][1]; } } if((mb_type & XINE_MACROBLOCK_PATTERN) && cbp) mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_PATTERN; mbs->macroblockptr->motion_type = motion_type; if(motion_type == XINE_MC_DMV) { int DMV[2][2]; if(picture_structure == VO_BOTH_FIELDS) { calc_DMV(DMV,dmvector, f_mot_pmv[0][0], f_mot_pmv[0][1]>>1, picture_structure, top_field_first); mbs->macroblockptr->PMV[1][0][0] = DMV[0][0]; mbs->macroblockptr->PMV[1][0][1] = DMV[0][1]; mbs->macroblockptr->PMV[1][1][0] = DMV[1][0]; mbs->macroblockptr->PMV[1][1][1] = DMV[1][1]; } else { calc_DMV(DMV,dmvector, f_mot_pmv[0][0], f_mot_pmv[0][1]>>1, picture_structure, top_field_first); mbs->macroblockptr->PMV[0][1][0] = DMV[0][0]; mbs->macroblockptr->PMV[0][1][1] = DMV[0][1]; } } if((motion_type == XINE_MC_FIELD) || (motion_type == XINE_MC_16X8)) { mbs->macroblockptr->motion_vertical_field_select = 0; if(mv_field_sel[0][0]) mbs->macroblockptr->motion_vertical_field_select |= 1; if(mv_field_sel[0][1]) mbs->macroblockptr->motion_vertical_field_select |= 2; if(mv_field_sel[1][0]) mbs->macroblockptr->motion_vertical_field_select |= 4; if(mv_field_sel[1][1]) mbs->macroblockptr->motion_vertical_field_select |= 8; } } /* else of if(mb_type & XINE_MACROBLOCK_INTRA) */ mbs->macroblockptr->index = ((unsigned long)mbs->xine_mc.blockptr - (unsigned long)mbs->xine_mc.blockbaseptr) >> 7; mbs->macroblockptr->dct_type = dct_type; mbs->macroblockptr->coded_block_pattern = cbp; while(cbp) { if(cbp & 1) mbs->macroblockptr->index--; cbp >>= 1; } #ifdef PRINTDATA printf("\n"); printf("-- %04d %04d %02x %02x %02x %02x",mbs->macroblockptr->x,mbs->macroblockptr->y,mbs->macroblockptr->macroblock_type, mbs->macroblockptr->motion_type,mbs->macroblockptr->motion_vertical_field_select,mbs->macroblockptr->dct_type); printf(" [%04d %04d %04d %04d %04d %04d %04d %04d] ", mbs->macroblockptr->PMV[0][0][0],mbs->macroblockptr->PMV[0][0][1],mbs->macroblockptr->PMV[0][1][0],mbs->macroblockptr->PMV[0][1][1], mbs->macroblockptr->PMV[1][0][0],mbs->macroblockptr->PMV[1][0][1],mbs->macroblockptr->PMV[1][1][0],mbs->macroblockptr->PMV[1][1][1]); printf(" %04d %04x\n",mbs->macroblockptr->index,mbs->macroblockptr->coded_block_pattern); #endif mbs->num_blocks++; mbs->macroblockptr++; if(mbs->num_blocks == mbs->slices) { #ifdef PRINTDATA printf("macroblockptr %lx", mbs->macroblockptr); printf("** RenderSurface %04d %04x\n",picture_structure, second_field ? XVMC_SECOND_FIELD : 0); fflush(stdout); #endif #ifdef PRINTFRAME printf(" target %08x past %08x future %08x\n", current_frame, forward_ref_frame, backward_ref_frame); #endif #ifdef PRINTFRAME if (picture_coding_type == XINE_PICT_P_TYPE) printf(" coding type P_TYPE\n"); if (picture_coding_type == XINE_PICT_I_TYPE) printf(" coding type I_TYPE\n"); if (picture_coding_type == XINE_PICT_B_TYPE) printf(" coding type B_TYPE\n"); if (picture_coding_type == XINE_PICT_D_TYPE) printf(" coding type D_TYPE\n"); fflush(stdout); #endif if (picture_coding_type == XINE_PICT_B_TYPE) xvmc_render_macro_blocks( current_frame, backward_ref_frame, forward_ref_frame, picture_structure, second_field ? XVMC_SECOND_FIELD : 0, mbs); if (picture_coding_type == XINE_PICT_P_TYPE) xvmc_render_macro_blocks( current_frame, NULL, forward_ref_frame, picture_structure, second_field ? XVMC_SECOND_FIELD : 0, mbs); if (picture_coding_type == XINE_PICT_I_TYPE) xvmc_render_macro_blocks( current_frame, NULL, NULL, picture_structure, second_field ? XVMC_SECOND_FIELD : 0, mbs); mbs->num_blocks = 0; mbs->macroblockptr = mbs->macroblockbaseptr; mbs->xine_mc.blockptr = mbs->xine_mc.blockbaseptr; } } static uint32_t xvmc_get_capabilities (vo_driver_t *this_gen) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; lprintf ("xvmc_get_capabilities\n"); return this->capabilities; } static void xvmc_frame_field (vo_frame_t *vo_img, int which_field) { lprintf ("xvmc_frame_field\n"); (void)vo_img; (void)which_field; } static void xvmc_frame_dispose (vo_frame_t *vo_img) { xvmc_frame_t *frame = (xvmc_frame_t *) vo_img ; lprintf ("xvmc_frame_dispose\n"); /* * TODO - clean up of images/surfaces and frames * Note this function is not really needed * set_context does the work */ free (frame); } static void xvmc_render_macro_blocks(vo_frame_t *current_image, vo_frame_t *backward_ref_image, vo_frame_t *forward_ref_image, int picture_structure, int second_field, xvmc_macroblocks_t *macroblocks) { xvmc_driver_t *this = (xvmc_driver_t *) current_image->driver; xvmc_frame_t *current_frame = XVMC_FRAME(current_image); xvmc_frame_t *forward_frame = XVMC_FRAME(forward_ref_image); xvmc_frame_t *backward_frame = XVMC_FRAME(backward_ref_image); int flags; lprintf ("xvmc_render_macro_blocks\n"); lprintf ("slices %d %p %p %p\n", macroblocks->slices, (void *) current_frame, (void *) backward_frame, (void *) forward_frame); /* lprintf ("slices %d 0x%08lx 0x%08lx 0x%08lx\n",macroblocks->slices, (long) current_frame->surface, (long) backward_frame->surface, (long) forward_frame->surface); */ flags = second_field; if(forward_frame) { if(backward_frame) { XvMCRenderSurface(this->display, &this->context, picture_structure, ¤t_frame->surface, &forward_frame->surface, &backward_frame->surface, flags, macroblocks->slices, 0, macroblocks->macro_blocks, macroblocks->blocks); } else { XvMCRenderSurface(this->display, &this->context, picture_structure, ¤t_frame->surface, &forward_frame->surface, NULL, flags, macroblocks->slices, 0, macroblocks->macro_blocks, macroblocks->blocks); } } else { if(backward_frame) { XvMCRenderSurface(this->display, &this->context, picture_structure, ¤t_frame->surface, NULL, &backward_frame->surface, flags, macroblocks->slices, 0, macroblocks->macro_blocks, macroblocks->blocks); } else { XvMCRenderSurface(this->display, &this->context, picture_structure, ¤t_frame->surface, NULL, NULL, flags, macroblocks->slices, 0, macroblocks->macro_blocks, macroblocks->blocks); } } XvMCFlushSurface(this->display, ¤t_frame->surface); lprintf ("xvmc_render_macro_blocks done\n"); } static vo_frame_t *xvmc_alloc_frame (vo_driver_t *this_gen) { xvmc_frame_t *frame; xvmc_driver_t *this = (xvmc_driver_t *) this_gen; lprintf ("xvmc_alloc_frame\n"); frame = calloc(1, sizeof (xvmc_frame_t)); if (!frame) return NULL; frame->vo_frame.accel_data = &frame->xvmc_data; frame->xvmc_data.vo_frame = &frame->vo_frame; /* keep track of frames and how many frames alocated. */ this->frames[this->num_frame_buffers++] = frame; pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions */ frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = xvmc_frame_field; frame->vo_frame.dispose = xvmc_frame_dispose; frame->vo_frame.driver = this_gen; frame->xvmc_data.proc_macro_block = xvmc_proc_macro_block; return (vo_frame_t *) frame; } static cxid_t *xvmc_set_context (xvmc_driver_t *this, uint32_t width, uint32_t height, double ratio, int format, int flags, xine_macroblocks_t *macro_blocks) { int i; int result = 0; int slices = 1; xvmc_macroblocks_t *macroblocks = (xvmc_macroblocks_t *) macro_blocks; lprintf ("xvmc_set_context %dx%d %04x\n",width,height,format); (void)ratio; /* initialize block & macro block pointers first time */ if(macroblocks->blocks == NULL || macroblocks->macro_blocks == NULL) { macroblocks->blocks = calloc(1, sizeof(XvMCBlockArray)); macroblocks->macro_blocks = calloc(1, sizeof(XvMCMacroBlockArray)); lprintf("macroblocks->blocks %p ->macro_blocks %p\n", (void *)macroblocks->blocks, (void *)macroblocks->macro_blocks); } if((this->context_id.xid != NULL) && ((int)width == this->surface_width) && ((int)height == this->surface_height) && (format == this->surface_format) && (flags == this->surface_flags)) { /* don't need to change context */ lprintf ("didn't change context\n"); return(&this->context_id); } else { if(this->context_id.xid != NULL) { /* * flush any drawing and wait till we are done with the old stuff * blow away the old stuff */ lprintf ("freeing previous context\n"); XvMCDestroyBlocks(this->display, macroblocks->blocks); XvMCDestroyMacroBlocks(this->display, macroblocks->macro_blocks); for(i = 0; i < this->num_frame_buffers; i++) { XvMCFlushSurface(this->display, &this->frames[i]->surface); XvMCSyncSurface(this->display, &this->frames[i]->surface); XvMCDestroySurface(this->display, &this->frames[i]->surface); } XvMCDestroyContext(this->display, &this->context); this->context_id.xid = NULL; } lprintf("CreateContext w %d h %d id %x portNum %x\n", width,height, this->surface_type_id, (int)this->xv_port); /* now create a new context */ result = XvMCCreateContext(this->display, this->xv_port, this->surface_type_id, width, height, XVMC_DIRECT, &this->context); if(result != Success) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "set_context: couldn't create XvMCContext\n"); macroblocks->xine_mc.xvmc_accel = 0; _x_abort(); } this->context_id.xid = (void *)this->context.context_id; for(i = 0; i < this->num_frame_buffers; i++) { result = XvMCCreateSurface(this->display, &this->context, &this->frames[i]->surface); if(result != Success) { XvMCDestroyContext(this->display, &this->context); xprintf(this->xine, XINE_VERBOSITY_DEBUG, "set_context: couldn't create XvMCSurfaces\n"); this->context_id.xid = NULL; macroblocks->xine_mc.xvmc_accel = 0; _x_abort(); } lprintf (" CreatedSurface %d 0x%lx\n",i,(long)&this->frames[i]->surface); } slices = (slices * width/16); lprintf("CreateBlocks slices %d\n",slices); result = XvMCCreateBlocks(this->display, &this->context, slices * 6, macroblocks->blocks); if(result != Success) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "set_context: ERROR XvMCCreateBlocks failed\n"); macroblocks->xine_mc.xvmc_accel = 0; _x_abort(); } result =XvMCCreateMacroBlocks(this->display, &this->context, slices, macroblocks->macro_blocks); if(result != Success) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "set_context: ERROR XvMCCreateMacroBlocks failed\n"); macroblocks->xine_mc.xvmc_accel = 0; _x_abort(); } lprintf (" Created bock and macro block arrays\n"); macroblocks->xine_mc.blockbaseptr = macroblocks->blocks->blocks; macroblocks->xine_mc.blockptr = macroblocks->xine_mc.blockbaseptr; macroblocks->num_blocks = 0; macroblocks->macroblockbaseptr = macroblocks->macro_blocks->macro_blocks; macroblocks->macroblockptr = macroblocks->macroblockbaseptr; macroblocks->slices = slices; macroblocks->xine_mc.xvmc_accel = this->acceleration; return(&this->context_id); } return NULL; } #if 0 static XvImage *create_ximage (xvmc_driver_t *this, XShmSegmentInfo *shminfo, int width, int height, int format) { unsigned int xvmc_format; XvImage *image = NULL; lprintf ("create_ximage\n"); switch (format) { case XINE_IMGFMT_YV12: case XINE_IMGFMT_XVMC: xvmc_format = this->xvmc_format_yv12; break; case XINE_IMGFMT_YUY2: xvmc_format = this->xvmc_format_yuy2; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); _x_abort(); } /* * plain Xv */ if (1) { char *data; switch (format) { case XINE_IMGFMT_YV12: case XINE_IMGFMT_XVMC: data = malloc (width * height * 3/2); break; case XINE_IMGFMT_YUY2: data = malloc (width * height * 2); break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); _x_abort(); } image = XvCreateImage (this->display, this->xv_port, xvmc_format, data, width, height); } return image; } /* Already Xlocked */ static void dispose_ximage (xvmc_driver_t *this, XShmSegmentInfo *shminfo, XvImage *myimage) { lprintf ("dispose_ximage\n"); XFree(myimage); } #endif static void xvmc_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; xvmc_frame_t *frame = (xvmc_frame_t *) frame_gen; xine_xvmc_t *xvmc = (xine_xvmc_t *) frame_gen->accel_data; if (format != XINE_IMGFMT_XVMC) { xprintf (this->xine, XINE_VERBOSITY_LOG, "xvmc_update_frame_format: frame format %08x not supported\n", format); frame->vo_frame.width = frame->width = 0; return; } lprintf ("xvmc_update_frame_format\n"); if ((frame->width != (int)width) || (frame->height != (int)height) || (frame->format != format)) { lprintf ("updating frame to %d x %d (ratio=%f, format=%08x)\n", width, height, ratio, format); /* Note that since we are rendering in hardware, we do not need to * allocate any ximage's for the software rendering buffers. */ frame->width = width; frame->height = height; frame->format = format; frame->ratio = ratio; } xvmc->macroblocks = &this->macroblocks.xine_mc; this->macroblocks.num_blocks = 0; this->macroblocks.macroblockptr = this->macroblocks.macroblockbaseptr; this->macroblocks.xine_mc.blockptr = this->macroblocks.xine_mc.blockbaseptr; if( flags & VO_NEW_SEQUENCE_FLAG ) { xvmc_set_context (this, width, height, ratio, format, flags, xvmc->macroblocks); } } static void xvmc_clean_output_area (xvmc_driver_t *this) { lprintf ("xvmc_clean_output_area\n"); XLockDisplay (this->display); XSetForeground (this->display, this->gc, this->black.pixel); XFillRectangle (this->display, this->drawable, this->gc, this->sc.gui_x, this->sc.gui_y, this->sc.gui_width, this->sc.gui_height); if (this->use_colorkey) { XSetForeground (this->display, this->gc, this->colorkey); XFillRectangle (this->display, this->drawable, this->gc, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } XUnlockDisplay (this->display); } /* * convert delivered height/width to ideal width/height * taking into account aspect ratio and zoom factor */ static void xvmc_compute_ideal_size (xvmc_driver_t *this) { _x_vo_scale_compute_ideal_size( &this->sc ); } /* * make ideal width/height "fit" into the gui */ static void xvmc_compute_output_size (xvmc_driver_t *this) { _x_vo_scale_compute_output_size( &this->sc ); } static void xvmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; xvmc_frame_t *frame = (xvmc_frame_t *) frame_gen; lprintf ("xvmc_overlay_blend\n"); this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; /* Alpha Blend here * As XV drivers improve to support Hardware overlay, we will change this function. */ if (overlay->rle) { if (frame->format == XINE_IMGFMT_YV12) _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else if (frame->format != XINE_IMGFMT_XVMC) _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); else xprintf (this->xine, XINE_VERBOSITY_LOG, "xvmc_overlay_blend: overlay blending not supported for frame format %08x\n", frame->format); } } static void xvmc_add_recent_frame (xvmc_driver_t *this, xvmc_frame_t *frame) { int i; lprintf ("xvmc_add_recent_frame\n"); i = VO_NUM_RECENT_FRAMES-1; if( this->recent_frames[i] ) this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); for( ; i ; i-- ) this->recent_frames[i] = this->recent_frames[i-1]; this->recent_frames[0] = frame; } static int xv_flush_recent_frames (xvmc_driver_t *this) { int i, n = 0; for (i = 0; i < VO_NUM_RECENT_FRAMES; i++) { if (this->recent_frames[i]) { this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; n++; } } return n; } static int xvmc_redraw_needed (vo_driver_t *this_gen) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; int ret = 0; if(this->cur_frame) { this->sc.delivered_height = this->cur_frame->height; this->sc.delivered_width = this->cur_frame->width; this->sc.delivered_ratio = this->cur_frame->ratio; this->sc.crop_left = this->cur_frame->vo_frame.crop_left; this->sc.crop_right = this->cur_frame->vo_frame.crop_right; this->sc.crop_top = this->cur_frame->vo_frame.crop_top; this->sc.crop_bottom = this->cur_frame->vo_frame.crop_bottom; xvmc_compute_ideal_size(this); if(_x_vo_scale_redraw_needed(&this->sc)) { xvmc_compute_output_size (this); xvmc_clean_output_area (this); ret = 1; } } else ret = 1; return ret; } static void xvmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; xvmc_frame_t *frame = (xvmc_frame_t *) frame_gen; lprintf ("xvmc_display_frame %d %p\n", frame_gen->id, (void *)frame_gen); /* * queue frames (deinterlacing) * free old frames */ xvmc_add_recent_frame (this, frame); /* deinterlacing */ this->cur_frame = frame; /* * let's see if this frame is different in size / aspect * ratio from the previous one */ if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) || (frame->vo_frame.crop_left != this->sc.crop_left) || (frame->vo_frame.crop_right != this->sc.crop_right) || (frame->vo_frame.crop_top != this->sc.crop_top) || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) { lprintf("frame format changed\n"); /* this->delivered_width = frame->width; this->delivered_height = frame->height; this->delivered_ratio = frame->ratio; this->delivered_duration = frame->vo_frame.duration; xvmc_compute_ideal_size (this); */ /* this->gui_width = 0; */ /* trigger re-calc of output size */ this->sc.force_redraw = 1; /* trigger re-calc of output size */ } /* * tell gui that we are about to display a frame, * ask for offset and output size */ xvmc_redraw_needed (this_gen); XLockDisplay (this->display); /* Make sure the surface has finished rendering before we display */ XvMCSyncSurface(this->display, &this->cur_frame->surface); XvMCPutSurface(this->display, &this->cur_frame->surface, this->drawable, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, XVMC_FRAME_PICTURE); XUnlockDisplay (this->display); /* printf ("video_out_xvmc: xvmc_display_frame... done\n"); */ } static int xvmc_get_property (vo_driver_t *this_gen, int property) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; lprintf ("xvmc_get_property\n"); if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; switch (property) { case VO_PROP_WINDOW_WIDTH: this->props[property].value = this->sc.gui_width; break; case VO_PROP_WINDOW_HEIGHT: this->props[property].value = this->sc.gui_height; break; case VO_PROP_OUTPUT_WIDTH: this->props[property].value = this->sc.output_width; break; case VO_PROP_OUTPUT_HEIGHT: this->props[property].value = this->sc.output_height; break; case VO_PROP_OUTPUT_XOFFSET: this->props[property].value = this->sc.output_xoffset; break; case VO_PROP_OUTPUT_YOFFSET: this->props[property].value = this->sc.output_yoffset; break; } return this->props[property].value; } static void xvmc_property_callback (void *property_gen, xine_cfg_entry_t *entry) { xvmc_property_t *property = (xvmc_property_t *) property_gen; xvmc_driver_t *this = property->this; lprintf ("xvmc_property_callback\n"); XLockDisplay(this->display); XvSetPortAttribute (this->display, this->xv_port, property->atom, entry->num_value); XUnlockDisplay(this->display); } static int xvmc_set_property (vo_driver_t *this_gen, int property, int value) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; lprintf ("xvmc_set_property %d value %d\n",property,value); if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; if (this->props[property].atom != None) { /* value is out of bound */ if((value < this->props[property].min) || (value > this->props[property].max)) value = (this->props[property].min + this->props[property].max) >> 1; XLockDisplay(this->display); XvSetPortAttribute (this->display, this->xv_port, this->props[property].atom, value); XvGetPortAttribute (this->display, this->xv_port, this->props[property].atom, &this->props[property].value); XUnlockDisplay(this->display); if (this->props[property].entry) this->props[property].entry->num_value = this->props[property].value; return this->props[property].value; } else { switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) value = xv_flush_recent_frames (this); break; case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->props[property].value = value; lprintf("VO_PROP_ASPECT_RATIO(%d)\n", this->props[property].value); xvmc_compute_ideal_size (this); xvmc_compute_output_size (this); xvmc_clean_output_area (this); break; case VO_PROP_ZOOM_X: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: VO_PROP_ZOOM_X = %d\n", this->props[property].value); this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; xvmc_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; case VO_PROP_ZOOM_Y: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: VO_PROP_ZOOM_Y = %d\n", this->props[property].value); this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; xvmc_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; } } return value; } static void xvmc_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; lprintf ("xvmc_get_property_min_max\n"); if ((property < 0) || (property >= VO_NUM_PROPERTIES)) { *min = *max = 0; return; } *min = this->props[property].min; *max = this->props[property].max; } static int xvmc_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; lprintf ("xvmc_gui_data_exchange\n"); switch (data_type) { case XINE_GUI_SEND_EXPOSE_EVENT: { /* XExposeEvent * xev = (XExposeEvent *) data; */ /* FIXME : take care of completion events */ lprintf ("XINE_GUI_SEND_EXPOSE_EVENT\n"); if (this->cur_frame) { int i; XLockDisplay (this->display); XSetForeground (this->display, this->gc, this->black.pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } if (this->use_colorkey) { XSetForeground (this->display, this->gc, this->colorkey); XFillRectangle (this->display, this->drawable, this->gc, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } XvMCPutSurface(this->display, &this->cur_frame->surface, this->drawable, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, XVMC_FRAME_PICTURE); XSync(this->display, False); XUnlockDisplay (this->display); } } break; case XINE_GUI_SEND_DRAWABLE_CHANGED: this->drawable = (Drawable) data; XLockDisplay(this->display); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); XUnlockDisplay(this->display); break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; /* xvmc_translate_gui2video(this, rect->x, rect->y, &x1, &y1); xvmc_translate_gui2video(this, rect->x + rect->w, rect->y + rect->h, &x2, &y2); */ _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void xvmc_dispose (vo_driver_t *this_gen) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; int i; lprintf ("xvmc_dispose\n"); if(this->context_id.xid) { XLockDisplay(this->display); for(i = 0; i < this->num_frame_buffers; i++) { /* if(useOverlay) *//* only one is displaying but I don't want to keep track*/ XvMCHideSurface(this->display, &this->frames[i]->surface); XvMCDestroySurface(this->display, &this->frames[i]->surface); } /* XvMCDestroyBlocks(this->display, ¯oblocks->blocks); */ /* XvMCDestroyMacroBlocks(this->display, ¯oblocks->macro_blocks); */ XvMCDestroyContext(this->display, &this->context); XUnlockDisplay(this->display); } XLockDisplay (this->display); XFreeGC(this->display, this->gc); if(XvUngrabPort (this->display, this->xv_port, CurrentTime) != Success) { lprintf ("xvmc_dispose: XvUngrabPort() failed.\n"); } XUnlockDisplay (this->display); for( i=0; i < VO_NUM_RECENT_FRAMES; i++ ) { if(this->recent_frames[i]) this->recent_frames[i]->vo_frame.dispose (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; } _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); free (this); } /* called xlocked */ static void xvmc_check_capability (xvmc_driver_t *this, int property, XvAttribute attr, int base_id, const char *config_name, const char *config_desc, const char *config_help) { int int_default; cfg_entry_t *entry; const char *str_prop = attr.name; (void)base_id; /* * some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing. */ if (attr.max_value == ~0) attr.max_value = 2147483615; this->props[property].min = attr.min_value; this->props[property].max = attr.max_value; this->props[property].atom = XInternAtom (this->display, str_prop, False); XvGetPortAttribute (this->display, this->xv_port, this->props[property].atom, &int_default); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: port attribute %s (%d) value is %d\n", str_prop, property, int_default); if (config_name) { /* is this a boolean property ? */ if ((attr.min_value == 0) && (attr.max_value == 1)) { this->config->register_bool (this->config, config_name, int_default, config_desc, config_help, 20, xvmc_property_callback, &this->props[property]); } else { this->config->register_range (this->config, config_name, int_default, this->props[property].min, this->props[property].max, config_desc, config_help, 20, xvmc_property_callback, &this->props[property]); } entry = this->config->lookup_entry (this->config, config_name); this->props[property].entry = entry; xvmc_set_property (&this->vo_driver, property, entry->num_value); if (strcmp(str_prop,"XV_COLORKEY") == 0) { this->use_colorkey = 1; this->colorkey = entry->num_value; } } else this->props[property].value = int_default; } static void xvmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) { xvmc_driver_t *this = (xvmc_driver_t *) this_gen; Atom atom; int xvmc_double_buffer; xvmc_double_buffer = entry->num_value; XLockDisplay(this->display); atom = XInternAtom (this->display, "XV_DOUBLE_BUFFER", False); XvSetPortAttribute (this->display, this->xv_port, atom, xvmc_double_buffer); XUnlockDisplay(this->display); lprintf("double buffering mode = %d\n",xvmc_double_buffer); } static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { xvmc_class_t *class = (xvmc_class_t *) class_gen; config_values_t *config = class->xine->config; xvmc_driver_t *this = NULL; unsigned int i, formats; XvPortID xv_port = class->xv_port; XvAttribute *attr; XvImageFormatValues *fo; int nattr; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; XColor dummy; XvAdaptorInfo *adaptor_info = class->adaptor_info; unsigned int adaptor_num = class->adaptor_num; /* XvImage *myimage; */ lprintf ("open_plugin\n"); /* TODO ??? */ this = calloc(1, sizeof (xvmc_driver_t)); if (!this) return NULL; _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->display = visual->display; this->overlay = NULL; this->screen = visual->screen; this->xv_port = class->xv_port; this->config = config; this->xine = class->xine; _x_vo_scale_init (&this->sc, 1, 0, config ); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; this->drawable = visual->d; XLockDisplay(this->display); this->gc = XCreateGC(this->display, this->drawable, 0, NULL); XUnlockDisplay(this->display); this->capabilities = VO_CAP_XVMC_MOCOMP | VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; this->surface_type_id = class->surface_type_id; this->max_surface_width = class->max_surface_width; this->max_surface_height = class->max_surface_height; this->context_id.xid = NULL; this->num_frame_buffers = 0; this->acceleration = class->acceleration; /* TODO CLEAN UP THIS */ this->user_data = visual->user_data; this->use_colorkey = 0; this->colorkey = 0; XLockDisplay(this->display); XAllocNamedColor(this->display, DefaultColormap(this->display, this->screen), "black", &this->black, &dummy); XUnlockDisplay(this->display); this->vo_driver.get_capabilities = xvmc_get_capabilities; this->vo_driver.alloc_frame = xvmc_alloc_frame; this->vo_driver.update_frame_format = xvmc_update_frame_format; this->vo_driver.overlay_blend = xvmc_overlay_blend; this->vo_driver.display_frame = xvmc_display_frame; this->vo_driver.get_property = xvmc_get_property; this->vo_driver.set_property = xvmc_set_property; this->vo_driver.get_property_min_max = xvmc_get_property_min_max; this->vo_driver.gui_data_exchange = xvmc_gui_data_exchange; this->vo_driver.dispose = xvmc_dispose; this->vo_driver.redraw_needed = xvmc_redraw_needed; /* * init properties */ for (i=0; iprops[i].value = 0; this->props[i].min = 0; this->props[i].max = 0; this->props[i].atom = None; this->props[i].entry = NULL; this->props[i].this = this; } this->props[VO_PROP_INTERLACED].value = 0; this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; this->props[VO_PROP_ZOOM_X].value = 100; this->props[VO_PROP_ZOOM_Y].value = 100; this->props[VO_PROP_MAX_NUM_FRAMES].value = MAX_NUM_FRAMES; /* * check this adaptor's capabilities */ if(this->acceleration&XINE_VO_IDCT_ACCEL) this->capabilities |= VO_CAP_XVMC_IDCT; XLockDisplay(this->display); attr = XvQueryPortAttributes(this->display, xv_port, &nattr); if(attr && nattr) { int k; for(k = 0; k < nattr; k++) { if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) { const char *const name = attr[k].name; if(!strcmp(name, "XV_HUE")) { if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) { xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); } else { this->capabilities |= VO_CAP_HUE; xvmc_check_capability (this, VO_PROP_HUE, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } } else if(!strcmp(name, "XV_SATURATION")) { this->capabilities |= VO_CAP_SATURATION; xvmc_check_capability (this, VO_PROP_SATURATION, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(attr[k].name, "XV_BRIGHTNESS")) { this->capabilities |= VO_CAP_BRIGHTNESS; xvmc_check_capability (this, VO_PROP_BRIGHTNESS, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(name, "XV_CONTRAST")) { this->capabilities |= VO_CAP_CONTRAST; xvmc_check_capability (this, VO_PROP_CONTRAST, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(name, "XV_GAMMA")) { this->capabilities |= VO_CAP_GAMMA; xvmc_check_capability (this, VO_PROP_GAMMA, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(name, "XV_COLORKEY")) { this->capabilities |= VO_CAP_COLORKEY; xvmc_check_capability (this, VO_PROP_COLORKEY, attr[k], adaptor_info[adaptor_num].base_id, "video.device.xv_colorkey", VIDEO_DEVICE_XV_COLORKEY_HELP); } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) { this->capabilities |= VO_CAP_AUTOPAINT_COLORKEY; xvmc_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k], adaptor_info[adaptor_num].base_id, "video.device.xv_autopaint_colorkey", VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) { int xvmc_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, 20, xvmc_update_XV_DOUBLE_BUFFER, this); config->update_num(config,"video.device.xv_double_buffer",xvmc_double_buffer); } } } XFree(attr); } else { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: no port attributes defined.\n"); } /* * check supported image formats */ fo = XvListImageFormats(this->display, this->xv_port, (int*)&formats); XUnlockDisplay(this->display); this->xvmc_format_yv12 = 0; this->xvmc_format_yuy2 = 0; for(i = 0; i < formats; i++) { lprintf ("XvMC image format: 0x%x (%4.4s) %s\n", fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); switch (fo[i].id) { case XINE_IMGFMT_YV12: this->xvmc_format_yv12 = fo[i].id; this->capabilities |= VO_CAP_YV12; xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); break; case XINE_IMGFMT_YUY2: this->xvmc_format_yuy2 = fo[i].id; this->capabilities |= VO_CAP_YUY2; xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); break; default: break; } } if(fo) { XLockDisplay(this->display); XFree(fo); XUnlockDisplay(this->display); } /* * try to create a shared image * to find out if MIT shm really works, using supported format */ /* XLockDisplay(this->display); myimage = create_ximage (this, &myshminfo, 100, 100, (this->xvmc_format_yv12 != 0) ? XINE_IMGFMT_YV12 : IMGFMT_YUY2); dispose_ximage (this, &myshminfo, myimage); XUnLockDisplay(this->display); */ lprintf("initialization of plugin successful\n"); return &this->vo_driver; } /* * class functions */ static void dispose_class (video_driver_class_t *this_gen) { xvmc_class_t *this = (xvmc_class_t *) this_gen; XLockDisplay(this->display); XvFreeAdaptorInfo (this->adaptor_info); XUnlockDisplay(this->display); free (this); } static void *init_class (xine_t *xine, const void *visual_gen) { const x11_visual_t *visual = (const x11_visual_t *) visual_gen; xvmc_class_t *this; Display *display = NULL; unsigned int adaptors, j = 0; unsigned int ver,rel,req,ev,err; XvPortID xv_port; XvAdaptorInfo *adaptor_info; unsigned int adaptor_num; /* XvMC */ int IDCTaccel = 0; int useOverlay = 0; int unsignedIntra = 0; unsigned int surface_num, types; unsigned int max_width=0, max_height=0; XvMCSurfaceInfo *surfaceInfo; int surface_type = 0; display = visual->display; /* * check for Xv and XvMC video support */ lprintf ("XvMC init_class\n"); XLockDisplay(display); if (Success != XvQueryExtension(display, &ver, &rel, &req, &ev, &err)) { xprintf (xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: Xv extension not present.\n"); XUnlockDisplay(display); return NULL; } if(!XvMCQueryExtension(display, &ev, &err)) { xprintf (xine, XINE_VERBOSITY_LOG, _("video_out_xvmc: XvMC extension not present.\n")); XUnlockDisplay(display); return 0; } /* * check adaptors, search for one that supports (at least) yuv12 */ if(Success != XvQueryAdaptors(display, DefaultRootWindow(display), &adaptors, &adaptor_info)) { xprintf (xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: XvQueryAdaptors failed.\n"); XUnlockDisplay(display); return 0; } xv_port = 0; for ( adaptor_num = 0; (adaptor_num < adaptors) && !xv_port; adaptor_num++ ) { xprintf (xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: checking adaptor %d\n",adaptor_num); if (adaptor_info[adaptor_num].type & XvImageMask) { surfaceInfo = XvMCListSurfaceTypes(display, adaptor_info[adaptor_num].base_id, &types); if(surfaceInfo) { for(surface_num = 0; surface_num < types; surface_num++) { if((surfaceInfo[surface_num].chroma_format == XVMC_CHROMA_FORMAT_420) && (surfaceInfo[surface_num].mc_type == (XVMC_IDCT | XVMC_MPEG_2))) { max_width = surfaceInfo[surface_num].max_width; max_height = surfaceInfo[surface_num].max_height; for(j = 0; j < adaptor_info[adaptor_num].num_ports; j++) { /* try to grab a port */ if(Success == XvGrabPort(display, adaptor_info[adaptor_num].base_id + j, CurrentTime)) { xv_port = adaptor_info[adaptor_num].base_id + j; surface_type = surfaceInfo[surface_num].surface_type_id; break; } } if(xv_port) break; } } if(!xv_port) { /* try for just XVMC_MOCOMP */ xprintf (xine, XINE_VERBOSITY_DEBUG, "didn't find XVMC_IDCT acceleration trying for MC\n"); for(surface_num = 0; surface_num < types; surface_num++) { if((surfaceInfo[surface_num].chroma_format == XVMC_CHROMA_FORMAT_420) && ((surfaceInfo[surface_num].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)))) { xprintf (xine, XINE_VERBOSITY_DEBUG, "Found XVMC_MOCOMP\n"); max_width = surfaceInfo[surface_num].max_width; max_height = surfaceInfo[surface_num].max_height; for(j = 0; j < adaptor_info[adaptor_num].num_ports; j++) { /* try to grab a port */ if(Success == XvGrabPort(display, adaptor_info[adaptor_num].base_id + j, CurrentTime)) { xv_port = adaptor_info[adaptor_num].base_id + j; surface_type = surfaceInfo[surface_num].surface_type_id; break; } } if(xv_port) break; } } } if(xv_port) { lprintf ("port %ld surface %d\n",xv_port,j); IDCTaccel = 0; if(surfaceInfo[surface_num].flags & XVMC_OVERLAID_SURFACE) useOverlay = 1; if(surfaceInfo[surface_num].flags & XVMC_INTRA_UNSIGNED) unsignedIntra = 1; if(surfaceInfo[surface_num].mc_type == (XVMC_IDCT | XVMC_MPEG_2)) IDCTaccel |= XINE_VO_IDCT_ACCEL | XINE_VO_MOTION_ACCEL; else if(surfaceInfo[surface_num].mc_type == (XVMC_MOCOMP | XVMC_MPEG_2)) { IDCTaccel |= XINE_VO_MOTION_ACCEL; if(!unsignedIntra) IDCTaccel |= XINE_VO_SIGNED_INTRA; } xprintf (xine, XINE_VERBOSITY_DEBUG, "video_out_xvmc: IDCTaccel %02x\n",IDCTaccel); break; } XFree(surfaceInfo); } } } /* outer for adaptor_num loop */ if (!xv_port) { xprintf (xine, XINE_VERBOSITY_LOG, _("video_out_xvmc: Xv extension is present but I couldn't find a usable yuv12 port.\n")); xprintf (xine, XINE_VERBOSITY_LOG, " Looks like your graphics hardware " "driver doesn't support Xv?!\n"); /* XvFreeAdaptorInfo (adaptor_info); this crashed on me (gb)*/ XUnlockDisplay(display); return NULL; } else { xprintf (xine, XINE_VERBOSITY_LOG, _("video_out_xvmc: using Xv port %ld from adaptor %s\n" " for hardware colour space conversion and scaling\n"), xv_port, adaptor_info[adaptor_num].name); if(IDCTaccel&XINE_VO_IDCT_ACCEL) xprintf (xine, XINE_VERBOSITY_LOG, _(" idct and motion compensation acceleration \n")); else if (IDCTaccel&XINE_VO_MOTION_ACCEL) xprintf (xine, XINE_VERBOSITY_LOG, _(" motion compensation acceleration only\n")); else xprintf (xine, XINE_VERBOSITY_LOG, _(" no XvMC support \n")); xprintf (xine, XINE_VERBOSITY_LOG, _(" With Overlay = %d; UnsignedIntra = %d.\n"), useOverlay, unsignedIntra); } XUnlockDisplay(display); this = (xvmc_class_t *) malloc (sizeof (xvmc_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "XvMC"; this->driver_class.description = N_("xine video output plugin using the XvMC X video extension"); this->driver_class.dispose = dispose_class; this->display = display; this->xv_port = xv_port; this->adaptor_info = adaptor_info; this->adaptor_num = adaptor_num; this->surface_type_id = surface_type; this->max_surface_width = max_width; this->max_surface_height = max_height; this->acceleration = IDCTaccel; this->xine = xine; lprintf("init_class done\n"); return this; } static const vo_info_t vo_info_xvmc = { /* priority must be low until it supports displaying non-accelerated stuff */ .priority = 0, .visual_type = XINE_VISUAL_TYPE_X11, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "xvmc", XINE_VERSION_CODE, &vo_info_xvmc, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif xine-lib-1.2/src/video_out/video_out_opengl2.c0000644000175000017500000030076114647725152017246 0ustar meme/* * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; * Copyright (C) 2012-2023 the xine project * Copyright (C) 2012 Christophe Thommeret * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * * video_out_opengl2.c, a video output plugin using opengl 2.0 * * */ /* #define LOG */ #define LOG_MODULE "video_out_opengl2" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #define GL_GLEXT_PROTOTYPES #include #include #include "opengl/xine_gl.h" #include "mem_frame.h" #include "hw_frame.h" #define _FLAG2BIT(_flag) (( \ ((0x80000000 - ((_flag) & 0xffff0000)) >> 31) * 16 \ + ((0x80000000 - ((_flag) & 0xff00ff00)) >> 31) * 8 \ + ((0x80000000 - ((_flag) & 0xf0f0f0f0)) >> 31) * 4 \ + ((0x80000000 - ((_flag) & 0xcccccccc)) >> 31) * 2 \ + ((0x80000000 - ((_flag) & 0xaaaaaaaa)) >> 31) * 1) ^ 31) /* Availability of GL_RED and GL_RG is checked at runtime. Define here to avoid build-time dependency. */ #ifndef GL_RED # define GL_RED 0x1903 #endif #ifndef GL_RG # define GL_RG 0x8227 #endif typedef union { uint16_t w[2]; uint32_t lw; } _opengl2_w2_t; typedef mem_frame_t opengl2_frame_t; typedef struct { int ovl_w, ovl_h; int ovl_x, ovl_y; int tex_w, tex_h; int unscaled; _opengl2_w2_t extent_size, extent_known; /* ~0u (yes), 0 (no) */ } opengl2_overlay_t; typedef enum { OGL2_cscs_NONE = 0, OGL2_cscs_yuv420, OGL2_cscs_yuv420g, OGL2_cscs_yuv420j, OGL2_cscs_yuv420jg, OGL2_cscs_yuv420j16, OGL2_cscs_yuv420j16g, OGL2_cscs_nv12, OGL2_cscs_nv12g, OGL2_cscs_yuv422, OGL2_cscs_yuv422g, OGL2_cscs_LAST } opengl2_csc_shader_t; typedef struct { /* 0 or ~0 */ unsigned int compiled; /* The uniform locatiins if this shaders arguments. * They seem not to change after compilation, so lets * caache them here and avoid many server round trips. */ GLint args[8]; GLuint shader; GLuint program; const char *name; } opengl2_program_t; typedef enum { OGL2_TEX_VIDEO_0 = 0, OGL2_TEX_VIDEO_1, OGL2_TEX_y, OGL2_TEX_u_v, OGL2_TEX_u, OGL2_TEX_v, OGL2_TEX_yuv, OGL2_TEX_uv, OGL2_TEX_HW0, OGL2_TEX_HW1, OGL2_TEX_HW2, OGL2_TEX_CUBIC_TEMP, OGL2_TEX_CUBIC_LUT, OGL2_TEX_LAST } opengl2_tex_t; static const char _ogl2_tex_names[OGL2_TEX_LAST][12] = { [OGL2_TEX_VIDEO_0] = "VIDEO_0", [OGL2_TEX_VIDEO_1] = "VIDEO_1", [OGL2_TEX_y] = "y", [OGL2_TEX_u_v] = "u_v", [OGL2_TEX_u] = "u", [OGL2_TEX_v] = "v", [OGL2_TEX_yuv] = "yuv", [OGL2_TEX_uv] = "uv", [OGL2_TEX_HW0] = "HW0", [OGL2_TEX_HW1] = "HW1", [OGL2_TEX_HW2] = "HW2", [OGL2_TEX_CUBIC_TEMP] = "cubic_temp", [OGL2_TEX_CUBIC_LUT] = "cubic_lut" }; typedef struct { int width; int height; int bytes_per_pixel; float relw, yuy2_mul, yuy2_div; } opengl2_yuvtex_t; typedef enum { SPLINE_CATMULLROM = 0, SPLINE_COS, SPLINE_LAST } opengl2_spline_t; typedef enum { SCALE_SIMPLE = 0, SCALE_LINEAR, SCALE_CATMULLROM, SCALE_COS, SCALE_LAST } opengl2_scale_t; #define SCALE_MASK 3 static const char _opengl2_scale_names[SCALE_LAST][16] = { [SCALE_SIMPLE] = "Simple", [SCALE_LINEAR] = "Linear", [SCALE_CATMULLROM] = "Catmullrom", [SCALE_COS] = "Cosinus" }; static const float _opengl2_lut_y[SCALE_LAST] = { [SCALE_SIMPLE] = SPLINE_CATMULLROM + 0.5, [SCALE_LINEAR] = SPLINE_CATMULLROM + 0.5, [SCALE_CATMULLROM] = SPLINE_CATMULLROM + 0.5, [SCALE_COS] = SPLINE_COS + 0.5 }; typedef struct opengl2_driver_s { vo_driver_t vo_driver; vo_scale_t sc; xine_gl_t *gl; int texture_float; GLenum fmt_1p; /* texture format for single Y/U/V plane */ GLenum fmt_2p; /* texture format for interleaved YUY2 or UV plane */ GLint lsize; GLchar *log; opengl2_program_t csc_shaders[OGL2_cscs_LAST]; opengl2_csc_shader_t last_csc_shader; GLuint tex[OGL2_TEX_LAST]; GLuint overlay_tex[XINE_VORAW_MAX_OVL + 1]; opengl2_yuvtex_t yuvtex; struct { uint32_t index; GLuint tex; } vtex; uint32_t vPBOindex; #define OGL2_NUM_VIDEO_PBO 2 #define OGL2_OVERLAY_PBO OGL2_NUM_VIDEO_PBO + 1 GLuint PBO[OGL2_NUM_VIDEO_PBO + 2]; GLuint fbo; int last_gui_width; int last_gui_height; struct { /* "no action" is way most frequent. tweaking this->vo_driver.foo () looks * more elegant, but would it confuse the outside world? */ void (*blend) (struct opengl2_driver_s *this, vo_frame_t *frame_gen, vo_overlay_t *overlay); void (*end) (struct opengl2_driver_s *this, vo_frame_t *vo_img); int changed, num; uint8_t unscaled_list[XINE_VORAW_MAX_OVL + 1]; opengl2_overlay_t buf[XINE_VORAW_MAX_OVL]; } ovl; float csc_matrix[3 * 4]; float join16[2]; int input_bits; int color_standard; int update_csc; int saturation; int contrast; int brightness; int hue; struct { /* 누를가마 ;-) */ int value, changed; float gamma2, gamma1; } gamma; struct { int value, changed; float mid, side, corn; opengl2_program_t program; } sharp; struct { int flags, changed; } transform; struct { opengl2_program_t pass1_program, pass2_program; GLuint fbo; int pass1_tex_w, pass1_tex_h; int mode_changed, mode_changing, mode1; opengl2_scale_t mode2; float lut_y; #define OGL2_BC_LUT 1 #define OGL2_BC_PROG_1 2 #define OGL2_BC_PROG_2 4 #define OGL2_BC_FBO 8 uint32_t flags; } bicubic; pthread_mutex_t drawable_lock; uint32_t display_width; uint32_t display_height; config_values_t *config; xine_t *xine; int zoom_x; int zoom_y; int cm_state; uint8_t cm_lut[32]; int max_video_width; int max_video_height; int max_display_width; int max_display_height; vo_accel_generic_t accel; int exit_indx; int exiting; /* HW decoding support */ xine_hwdec_t *hw; xine_glconv_t *glconv; } opengl2_driver_t; /* libGL likes to install its own exit handlers. * Trying to render after one of them will freeze or crash, * so make sure we're last. * HAIR RAISING HACK: * Passing arguments to an exit handler is supported on SunOS, * deprecated in Linux, and impossible anywhere else. */ #define MAX_EXIT_TARGETS 8 /* These are process local, right? */ opengl2_driver_t *opengl2_exit_vector[MAX_EXIT_TARGETS] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; static void opengl2_exit (void) { int i; for (i = MAX_EXIT_TARGETS - 1; i >= 0; i--) { opengl2_driver_t *this = opengl2_exit_vector[i]; if (this) { if (this != (opengl2_driver_t *)1) { this->exiting = 1; /* wait for last render */ pthread_mutex_lock (&this->drawable_lock); pthread_mutex_unlock (&this->drawable_lock); } opengl2_exit_vector[i] = NULL; } } } static void opengl2_exit_unregister (opengl2_driver_t *this) { int indx = this->exit_indx; if (indx == 1) opengl2_exit_vector[0] = (opengl2_driver_t *)1; else if ((indx > 1) && (indx <= MAX_EXIT_TARGETS)) opengl2_exit_vector[indx - 1] = NULL; } static void opengl2_exit_register (opengl2_driver_t *this) { int i; if (!opengl2_exit_vector[0]) { opengl2_exit_vector[0] = this; this->exit_indx = 1; atexit (opengl2_exit); return; } if (opengl2_exit_vector[0] == (opengl2_driver_t *)1) { opengl2_exit_vector[0] = this; this->exit_indx = 1; return; } for (i = 1; i < MAX_EXIT_TARGETS; i++) { if (!opengl2_exit_vector[i]) { opengl2_exit_vector[i] = this; this->exit_indx = i + 1; return; } } this->exit_indx = MAX_EXIT_TARGETS + 1; } /* !exit_stuff */ /* import common color matrix stuff */ #define CM_LUT #define CM_HAVE_YCGCO_SUPPORT 1 #define CM_HAVE_BT2020_SUPPORT 1 #define CM_DRIVER_T opengl2_driver_t #include "color_matrix.c" typedef struct { video_driver_class_t driver_class; xine_t *xine; unsigned visual_type; uint8_t texture_float; uint8_t texture_rg; } opengl2_class_t; static void opengl2_accel_lock (vo_frame_t *frame, int lock) { (void)frame; (void)lock; } static GLint _opengl2_next_videoPBO (opengl2_driver_t *this) { this->vPBOindex = (this->vPBOindex + 1) & (OGL2_NUM_VIDEO_PBO - 1); return this->PBO[this->vPBOindex]; } static const char *_ogl2_fmt2str (uint32_t v) { static const struct { uint32_t v; char name[16]; } list[] = { {0x1900, "INDEX"}, {0x1903, "RED"}, {0x1904, "GREEN"}, {0x1905, "BLUE"}, {0x1906, "ALPHA"}, {0x1907, "RGB"}, {0x1908, "RGBA"}, {0x1909, "LUMA"}, {0x190A, "LUMA_ALPHA"}, {0x2A10, "R3_G3_B2"}, {0x803B, "ALPHA4"}, {0x803C, "ALPHA8"}, {0x803D, "ALPHA12"}, {0x803E, "ALPHA16"}, {0x803F, "LUMA4"}, {0x8040, "LUMA8"}, {0x8041, "LUMA12"}, {0x8042, "LUMA16"}, {0x8043, "LUMA4_ALPHA4"}, {0x8044, "LUMA6_ALPHA2"}, {0x8045, "LUMA8_ALPHA8"}, {0x8046, "LUMA12_ALPHA4"}, {0x8047, "LUMA12_ALPHA12"}, {0x8048, "LUMA16_ALPHA16"}, {0x8049, "INTENSITY"}, {0x804A, "INTENSITY4"}, {0x804B, "INTENSITY8"}, {0x804C, "INTENSITY12"}, {0x804D, "INTENSITY16"}, {0x804F, "RGB4"}, {0x8050, "RGB5"}, {0x8051, "RGB8"}, {0x8052, "RGB10"}, {0x8053, "RGB12"}, {0x8054, "RGB16"}, {0x8055, "RGBA2"}, {0x8056, "RGBA4"}, {0x8057, "RGB5_A1"}, {0x8058, "RGBA8"}, {0x8059, "RGB10_A2"}, {0x805A, "RGBA12"}, {0x805B, "RGBA16"}, {0x80E0, "BGR"}, {0x80E1, "BGRA"}, {0x8227, "RG"}, {0x8228, "RG_INT"}, {0x8229, "R8"}, {0x822A, "R16"}, {0x822B, "RG8"}, {0x822C, "RG16"}, {0x822D, "R16F"}, {0x822E, "R32F"}, {0x822F, "RG16F"}, {0x8230, "RG32F"}, {0x8231, "R8I"}, {0x8232, "R8UI"}, {0x8233, "R16I"}, {0x8234, "R16UI"}, {0x8235, "R32I"}, {0x8236, "R32UI"}, {0x8237, "RG8I"}, {0x8238, "RG8UI"}, {0x8239, "RG16I"}, {0x823A, "RG16UI"}, {0x823B, "RG32I"}, {0x823C, "RG32UI"}, {0x8814, "RGBA32F"}, {0x8815, "RGB32F"}, {0x881A, "RGBA16F"}, {0x881B, "RGB16F"}, {0x8D70, "RGBA32UI"}, {0x8D71, "RGB32UI"}, {0x8D76, "RGBA16UI"}, {0x8D77, "RGB16UI"}, {0x8D7C, "RGBA8UI"}, {0x8D7D, "RGB8UI"}, {0x8D82, "RGBA32I"}, {0x8D83, "RGB32I"}, {0x8D88, "RGBA16I"}, {0x8D89, "RGB16I"}, {0x8D8E, "RGBA8I"}, {0x8D8F, "RGB8I"}, {0x8D94, "RED_INT"}, {0x8D95, "GREEN_INT"}, {0x8D96, "BLUE_INT"}, {0x8D98, "RGB_INT"}, {0x8D99, "RGBA_INT"}, {0x8D9A, "BGR_INT"}, {0x8D9B, "BGRA_INT"}, }; uint32_t b = 0, e = sizeof (list) / sizeof (list[0]); do { uint32_t m = (b + e) >> 1; if (v < list[m].v) e = m; else if (v > list[m].v) b = m + 1; else return list[m].name; } while (b != e); return ""; } static void _ogl2_str2hex (char **q, uint32_t v) { static const char tab_hex[16] = "0123456789abcdef"; char *d = *q; uint32_t n = 8; while ((n > 1) && !(v & 0xf0000000)) v <<= 4, n--; while (n > 0) { *d++ = tab_hex[v >> 28]; v <<= 4, n--; } *q = d; } static void _ogl2_dump_tex_fmts (opengl2_driver_t *this) { char buf[2048], *q = buf; const char *p; uint32_t u, l; GLint res[OGL2_TEX_LAST + 1]; if (this->xine->verbosity < XINE_VERBOSITY_DEBUG) return; glActiveTexture (GL_TEXTURE0); for (u = 0; u < OGL2_TEX_LAST; u++) { res[u] = 0; if (this->tex[u]) { glBindTexture (GL_TEXTURE_RECTANGLE_ARB, this->tex[u]); glGetTexLevelParameteriv (GL_TEXTURE_RECTANGLE_ARB, 0, GL_TEXTURE_INTERNAL_FORMAT, res + u); } } glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glFlush (); p = LOG_MODULE ": internal texture formats:\n "; l = strlen (p); memcpy (q, p, l); q += l; res[OGL2_TEX_LAST] = res[OGL2_TEX_LAST - 1] + 1; for (u = 0; u < OGL2_TEX_LAST; u++) { p = _ogl2_tex_names[u]; l = strlen (p); memcpy (q, p, l); q += l; if (res[u] == res[u + 1]) { memcpy (q, ", ", 2); q += 2; } else { const char *name = _ogl2_fmt2str (res[u]); memcpy (q, ": 0x", 4); q += 4; _ogl2_str2hex (&q, res[u]); if (name[0]) { memcpy (q, " (", 2); q += 2; l = strlen (name); memcpy (q, name, l); q += l; *q++ = ')'; } memcpy (q, "\n ", 3); q += 3; } } q -= 2; q[0] = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "%s", buf); } typedef char opengl2_shader_arg_name_t[8]; static const opengl2_shader_arg_name_t bicubic_pass1_args[] = {"ARB", "tex", "lut", "spline", ""}; static const char bicubic_pass1_frag[] = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex, lut;\n" "uniform float spline;\n" "void main() {\n" " vec2 coord = gl_TexCoord[0].xy;\n" " vec2 TexCoord = vec2( floor( coord.x - 0.5 ) + 0.5, coord.y );\n" " vec4 wlut = texture2DRect( lut, vec2( ( coord.x - TexCoord.x ) * 1000.0, spline ) );\n" " vec4 sum = texture2DRect( tex, TexCoord + vec2( -1.0, 0.0) ) * wlut[0];\n" " sum += texture2DRect( tex, TexCoord ) * wlut[1];\n" " sum += texture2DRect( tex, TexCoord + vec2( 1.0, 0.0) ) * wlut[2];\n" " sum += texture2DRect( tex, TexCoord + vec2( 2.0, 0.0) ) * wlut[3];\n" " gl_FragColor = sum;\n" "}\n"; static const opengl2_shader_arg_name_t bicubic_pass2_args[] = {"ARB", "tex", "lut", "spline", ""}; static const char bicubic_pass2_frag[] = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex, lut;\n" "uniform float spline;\n" "void main() {\n" " vec2 coord = gl_TexCoord[0].xy;\n" " vec2 TexCoord = vec2( coord.x, floor( coord.y - 0.5 ) + 0.5 );\n" " vec4 wlut = texture2DRect( lut, vec2( ( coord.y - TexCoord.y ) * 1000.0, spline ) );\n" " vec4 sum = texture2DRect( tex, TexCoord + vec2( 0.0, -1.0 ) ) * wlut[0];\n" " sum += texture2DRect( tex, TexCoord ) * wlut[1];\n" " sum += texture2DRect( tex, TexCoord + vec2( 0.0, 1.0 ) ) * wlut[2];\n" " sum += texture2DRect( tex, TexCoord + vec2( 0.0, 2.0 ) ) * wlut[3];\n" " gl_FragColor = sum;\n" "}\n"; #define LUTWIDTH 1000 /* TJ. This came out while experimenting with test://y_resolution.bmp :-) * (0.00 +0.25 2.00) = { 1.0000 0,5971 0,3150 0,1199 0.0000 -0,0526 -0,0533 -0,0269 0.0000 } */ static double _opengl2_cos_spline (double x) { if (x < 0.0) x = -x; return cos (M_PI * 0.25 * x * (x + 1.0)) * pow (2.0, -2.8 * x); } /* (0.00 +0.25 2.00) = { 1.0000 0.8672 0.5625 0,2265 0.0000 -0,0703 -0,0625 -0,0234 0.0000 } */ static double _opengl2_catmullrom_spline (double x) { if (x < 0.0) x = -x; if (x < 1.0) return 1.5 * x * x * x - 2.5 * x * x + 1.0; return -0.5 * x * x * x + 2.5 * x * x - 4.0 * x + 2.0; } static double (* const _opengl2_spline[SPLINE_LAST]) (double x) = { [SPLINE_CATMULLROM] = _opengl2_catmullrom_spline, [SPLINE_COS] = _opengl2_cos_spline }; static int create_lut_texture( opengl2_driver_t *that ) { uint32_t i; float *lut = calloc( sizeof(float) * LUTWIDTH * 4 * SPLINE_LAST, 1 ); if ( !lut ) return 0; for (i = 0; i < LUTWIDTH; i++) { opengl2_spline_t s; float *p = lut + i * 4; double t = (double)i / (double)LUTWIDTH; for (s = (opengl2_spline_t)0; s < SPLINE_LAST; s++) { double v1, v2, v3, v4, coefsum; v1 = _opengl2_spline[s] (t + 1.0); coefsum = v1; v2 = _opengl2_spline[s] (t); coefsum += v2; v3 = _opengl2_spline[s] (t - 1.0); coefsum += v3; v4 = _opengl2_spline[s] (t - 2.0); coefsum += v4; coefsum = 1.0 / coefsum; p[(uint32_t)s * LUTWIDTH * 4 + 0] = v1 * coefsum; p[(uint32_t)s * LUTWIDTH * 4 + 1] = v2 * coefsum; p[(uint32_t)s * LUTWIDTH * 4 + 2] = v3 * coefsum; p[(uint32_t)s * LUTWIDTH * 4 + 3] = v4 * coefsum; } } that->tex[OGL2_TEX_CUBIC_LUT] = 0; glGenTextures (1, &that->tex[OGL2_TEX_CUBIC_LUT]); if (!that->tex[OGL2_TEX_CUBIC_LUT]) { free (lut); return 0; } that->bicubic.flags &= ~OGL2_BC_LUT; glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_LUT]); glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA32F, LUTWIDTH, SPLINE_LAST, 0, GL_RGBA, GL_FLOAT, lut ); free( lut ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 ); return 1; } static const opengl2_shader_arg_name_t blur_sharpen_args[] = {"ARB", "tex", "mid", "side", "corn", ""}; static const char blur_sharpen_frag[] = "#extension GL_ARB_texture_rectangle : enable\n" "uniform sampler2DRect tex;\n" "uniform float mid, side, corn;\n" "void main() {\n" " vec2 pos = gl_TexCoord[0].xy;\n" " vec4 c1;\n" " c1 = texture2DRect (tex, pos) * mid\n" " + (texture2DRect (tex, pos + vec2 (-1.0, 0.0))\n" " + texture2DRect (tex, pos + vec2 ( 0.0, -1.0))\n" " + texture2DRect (tex, pos + vec2 ( 1.0, 0.0))\n" " + texture2DRect (tex, pos + vec2 ( 0.0, 1.0))) * side\n" " + (texture2DRect (tex, pos + vec2 (-1.0, -1.0))\n" " + texture2DRect (tex, pos + vec2 ( 1.0, -1.0))\n" " + texture2DRect (tex, pos + vec2 (-1.0, 1.0))\n" " + texture2DRect (tex, pos + vec2 ( 1.0, 1.0))) * corn;\n" " gl_FragColor = c1 ;\n" "}\n"; static const opengl2_shader_arg_name_t yuv420_args[] = {"r_coefs", "g_coefs", "b_coefs", "texY", "texU", "texV", ""}; static const char yuv420_frag[] = "uniform sampler2D texY, texU, texV;\n" "uniform vec4 r_coefs, g_coefs, b_coefs;\n" "void main(void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord = gl_TexCoord[0].xy;\n" " yuv.r = texture2D (texY, coord).r;\n" " yuv.g = texture2D (texU, coord).r;\n" " yuv.b = texture2D (texV, coord).r;\n" " yuv.a = 1.0;\n" " rgb.r = dot (yuv, r_coefs);\n" " rgb.g = dot (yuv, g_coefs);\n" " rgb.b = dot (yuv, b_coefs);\n" " rgb.a = 1.0;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t yuv420g_args[] = { "r_coefs", "g_coefs", "b_coefs", "texY", "texU", "texV", "gamma2", "gamma1", "" }; static const char yuv420g_frag[] = "uniform sampler2D texY, texU, texV;\n" "uniform vec4 r_coefs, g_coefs, b_coefs, gamma2, gamma1;\n" "void main(void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord = gl_TexCoord[0].xy;\n" " yuv.r = texture2D (texY, coord).r;\n" " yuv.g = texture2D (texU, coord).r;\n" " yuv.b = texture2D (texV, coord).r;\n" " yuv.a = 1.0;\n" " rgb.r = dot (yuv, r_coefs);\n" " rgb.g = dot (yuv, g_coefs);\n" " rgb.b = dot (yuv, b_coefs);\n" " rgb.a = 1.0;\n" " rgb = rgb * rgb * gamma2 + rgb * gamma1;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t yuv420jg_args[] = { "r_coefs", "g_coefs", "b_coefs", "texY", "tex_U_V", "gamma2", "gamma1", "" }; static const char yuv420jg_frag[] = "uniform sampler2D texY, tex_U_V;\n" "uniform vec4 r_coefs, g_coefs, b_coefs, gamma2, gamma1;\n" "void main(void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord_y = gl_TexCoord[0].xy;\n" " vec2 coord_u_v = coord_y * vec2 (1.0, 0.5);\n" " yuv.r = texture2D (texY, coord_y).r;\n" " yuv.g = texture2D (tex_U_V, coord_u_v).r;\n" " yuv.b = texture2D (tex_U_V, coord_u_v + vec2 (0.0, 0.5)).r;\n" " yuv.a = 1.0;\n" " rgb.r = dot (yuv, r_coefs);\n" " rgb.g = dot (yuv, g_coefs);\n" " rgb.b = dot (yuv, b_coefs);\n" " rgb.a = 1.0;\n" " rgb = rgb * rgb * gamma2 + rgb * gamma1;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t yuv420j_args[] = {"r_coefs", "g_coefs", "b_coefs", "texY", "tex_U_V", ""}; static const char yuv420j_frag[] = "uniform sampler2D texY, tex_U_V;\n" "uniform vec4 r_coefs, g_coefs, b_coefs;\n" "void main(void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord_y = gl_TexCoord[0].xy;\n" " vec2 coord_u_v = coord_y * vec2 (1.0, 0.5);\n" " yuv.r = texture2D (texY, coord_y).r;\n" " yuv.g = texture2D (tex_U_V, coord_u_v).r;\n" " yuv.b = texture2D (tex_U_V, coord_u_v + vec2 (0.0, 0.5)).r;\n" " yuv.a = 1.0;\n" " rgb.r = dot (yuv, r_coefs);\n" " rgb.g = dot (yuv, g_coefs);\n" " rgb.b = dot (yuv, b_coefs);\n" " rgb.a = 1.0;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t yuv420j16_args[] = {"r_coefs", "g_coefs", "b_coefs", "texY", "tex_U_V", "join16", ""}; static const char yuv420j16_frag[] = "uniform sampler2D texY, tex_U_V;\n" "uniform vec4 r_coefs, g_coefs, b_coefs;\n" "uniform vec2 join16;\n" "void main(void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord_y = gl_TexCoord[0].xy;\n" " vec2 coord_u_v = coord_y * vec2 (1.0, 0.5);\n" " yuv.r = dot (texture2D (texY, coord_y).r$, join16);\n" " yuv.g = dot (texture2D (tex_U_V, coord_u_v).r$, join16);\n" " yuv.b = dot (texture2D (tex_U_V, coord_u_v + vec2 (0.0, 0.5)).r$, join16);\n" " yuv.a = 1.0;\n" " rgb.r = dot (yuv, r_coefs);\n" " rgb.g = dot (yuv, g_coefs);\n" " rgb.b = dot (yuv, b_coefs);\n" " rgb.a = 1.0;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t yuv420j16g_args[] = { "r_coefs", "g_coefs", "b_coefs", "texY", "tex_U_V", "join16", "gamma2", "gamma1", "" }; static const char yuv420j16g_frag[] = "uniform sampler2D texY, tex_U_V;\n" "uniform vec4 r_coefs, g_coefs, b_coefs, gamma2, gamma1;\n" "uniform vec2 join16;\n" "void main(void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord_y = gl_TexCoord[0].xy;\n" " vec2 coord_u_v = coord_y * vec2 (1.0, 0.5);\n" " yuv.r = dot (texture2D (texY, coord_y).r$, join16);\n" " yuv.g = dot (texture2D (tex_U_V, coord_u_v).r$, join16);\n" " yuv.b = dot (texture2D (tex_U_V, coord_u_v + vec2 (0.0, 0.5)).r$, join16);\n" " yuv.a = 1.0;\n" " rgb.r = dot (yuv, r_coefs);\n" " rgb.g = dot (yuv, g_coefs);\n" " rgb.b = dot (yuv, b_coefs);\n" " rgb.a = 1.0;\n" " rgb = rgb * rgb * gamma2 + rgb * gamma1;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t nv12_args[] = {"r_coefs", "g_coefs", "b_coefs", "texY", "texUV", ""}; static const char nv12_frag[] = "uniform sampler2D texY, texUV;\n" "uniform vec4 r_coefs, g_coefs, b_coefs;\n" "void main (void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord = gl_TexCoord[0].xy;\n" " yuv.r = texture2D (texY, coord).r;\n" " yuv.g = texture2D (texUV, coord).r;\n" " yuv.b = texture2D (texUV, coord).$;\n" " yuv.a = 1.0;\n" " rgb.r = dot( yuv, r_coefs );\n" " rgb.g = dot( yuv, g_coefs );\n" " rgb.b = dot( yuv, b_coefs );\n" " rgb.a = 1.0;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t nv12g_args[] = { "r_coefs", "g_coefs", "b_coefs", "texY", "texUV", "gamma2", "gamma1", ""}; static const char nv12g_frag[] = "uniform sampler2D texY, texUV;\n" "uniform vec4 r_coefs, g_coefs, b_coefs, gamma2, gamma1;\n" "void main (void) {\n" " vec4 rgb;\n" " vec4 yuv;\n" " vec2 coord = gl_TexCoord[0].xy;\n" " yuv.r = texture2D (texY, coord).r;\n" " yuv.g = texture2D (texUV, coord).r;\n" " yuv.b = texture2D (texUV, coord).$;\n" " yuv.a = 1.0;\n" " rgb.r = dot( yuv, r_coefs );\n" " rgb.g = dot( yuv, g_coefs );\n" " rgb.b = dot( yuv, b_coefs );\n" " rgb.a = 1.0;\n" " rgb = rgb * rgb * gamma2 + rgb * gamma1;\n" " gl_FragColor = rgb;\n" "}\n"; static const opengl2_shader_arg_name_t yuv422_args[] = {"r_coefs", "g_coefs", "b_coefs", "texYUV", "yuy2v", ""}; static const char yuv422_frag[] = "uniform sampler2D texYUV;\n" "uniform vec4 r_coefs, g_coefs, b_coefs;\n" "uniform vec2 yuy2v;\n" "void main(void) {\n" " vec4 rgba;\n" " vec4 yuv;\n" " vec4 coord = gl_TexCoord[0].xyxx;\n" " float group_x = floor (coord.x * yuy2v.x);\n" " coord.z = (group_x + 0.25) * yuy2v.y;\n" " coord.w = (group_x + 0.75) * yuy2v.y;\n" " yuv.r = texture2D (texYUV, coord.xy).r;\n" " yuv.g = texture2D (texYUV, coord.zy).$;\n" " yuv.b = texture2D (texYUV, coord.wy).$;\n" " yuv.a = 1.0;\n" " rgba.r = dot (yuv, r_coefs);\n" " rgba.g = dot (yuv, g_coefs);\n" " rgba.b = dot (yuv, b_coefs);\n" " rgba.a = 1.0;\n" " gl_FragColor = rgba;\n" "}\n"; static const opengl2_shader_arg_name_t yuv422g_args[] = { "r_coefs", "g_coefs", "b_coefs", "texYUV", "yuy2v", "gamma2", "gamma1", "" }; static const char yuv422g_frag[] = "uniform sampler2D texYUV;\n" "uniform vec4 r_coefs, g_coefs, b_coefs, gamma2, gamma1;\n" "uniform vec2 yuy2v;\n" "void main(void) {\n" " vec4 rgba;\n" " vec4 yuv;\n" " vec4 coord = gl_TexCoord[0].xyxx;\n" " float group_x = floor (coord.x * yuy2v.x);\n" " coord.z = (group_x + 0.25) * yuy2v.y;\n" " coord.w = (group_x + 0.75) * yuy2v.y;\n" " yuv.r = texture2D (texYUV, coord.xy).r;\n" " yuv.g = texture2D (texYUV, coord.zy).$;\n" " yuv.b = texture2D (texYUV, coord.wy).$;\n" " yuv.a = 1.0;\n" " rgba.r = dot (yuv, r_coefs);\n" " rgba.g = dot (yuv, g_coefs);\n" " rgba.b = dot (yuv, b_coefs);\n" " rgba.a = 1.0;\n" " rgba = rgba * rgba * gamma2 + rgba * gamma1;\n" " gl_FragColor = rgba;\n" "}\n"; static void opengl2_free_log_buf (opengl2_driver_t *this) { free (this->log); this->log = NULL; this->lsize = 0; } static int opengl2_log_buf (opengl2_driver_t *this, GLint size) { /* a log size of 1 usually means just 1 empty line, skip. */ if ((unsigned int)(size - 2) >= (1 << 20)) return 0; if (size <= this->lsize) return 1; this->lsize = 0; free (this->log); size = (size + 1023) & ~1023; this->log = malloc (size); if (!this->log) return 0; this->lsize = size; return 1; } static int opengl2_build_program (opengl2_driver_t *this, opengl2_program_t *prog, const char *source, const char *name, const opengl2_shader_arg_name_t *arg_names) { const char *s = source; GLint length, result; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": compiling shader %s.\n", name); prog->name = name; if ( !(prog->shader = glCreateShader( GL_FRAGMENT_SHADER )) ) return 0; if ( !(prog->program = glCreateProgram()) ) return 0; glShaderSource (prog->shader, 1, &s, NULL); glCompileShader (prog->shader); length = 0; glGetShaderiv (prog->shader, GL_INFO_LOG_LENGTH, &length); if (opengl2_log_buf (this, length)) { length = 0; glGetShaderInfoLog (prog->shader, length, &length, this->log); if ((unsigned int)(length - 1) < (1 << 20)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Shader %s Compilation Log:\n", name); if (this->xine->verbosity >= XINE_VERBOSITY_DEBUG) { fwrite (this->log, 1, length, stdout); fflush (stdout); } } } result = GL_FALSE; glGetShaderiv (prog->shader, GL_COMPILE_STATUS, &result); if (result != GL_TRUE) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": compiling shader %s failed.\n", name); return 0; } glAttachShader( prog->program, prog->shader ); glLinkProgram( prog->program ); length = 0; glGetProgramiv (prog->program, GL_INFO_LOG_LENGTH, &length); if (opengl2_log_buf (this, length)) { length = 0; glGetProgramInfoLog (prog->program, length, &length, this->log); if ((unsigned int)(length - 1) < (1 << 20)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Shader %s Linking Log:\n", name); if (this->xine->verbosity >= XINE_VERBOSITY_DEBUG) { fwrite (this->log, 1, length, stdout); fwrite ("\n", 1, 1, stdout); fflush (stdout); } } } result = GL_FALSE; glGetProgramiv( prog->program, GL_LINK_STATUS, &result ); if (result != GL_TRUE) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": linking shader %s failed.\n", name); return 0; } prog->compiled = ~0u; { unsigned int u; if (!memcmp (arg_names[0], "ARB", 4)) { for (u = 0; arg_names[u + 1][0]; u++) prog->args[u] = glGetUniformLocationARB (prog->program, arg_names[u + 1]); } else { for (u = 0; arg_names[u][0]; u++) prog->args[u] = glGetUniformLocation (prog->program, arg_names[u]); } for (; u < sizeof (prog->args) / sizeof (prog->args[0]); u++) prog->args[u] = 0; } return 1; } static void opengl2_delete_program (opengl2_program_t *prog) { if (prog->compiled) { glDeleteProgram (prog->program); glDeleteShader (prog->shader); } } static void _config_texture(GLenum target, GLuint texture, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum minmag_filter) { if (texture) { glBindTexture(target, texture); if (format) glTexImage2D(target, 0, format, width, height, 0, format, type, NULL); glTexParameterf(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameterf(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, minmag_filter); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, minmag_filter); } } #define _OGL2_STATE_OK 1 #define _OGL2_STATE_CHANGED 2 static uint32_t opengl2_check_textures_size (opengl2_driver_t *this_gen, int w, int h, int bits) { opengl2_driver_t *this = this_gen; opengl2_yuvtex_t *ytex = &this->yuvtex; int bytes_per_pixel = (bits + 7) >> 3; int realw = w, uvh; w = (w + 15) & ~15; /* usually no change. */ if (!((w ^ ytex->width) | (h ^ ytex->height) | (bytes_per_pixel ^ ytex->bytes_per_pixel))) return _OGL2_STATE_OK; ytex->relw = (float)realw / (float)w; ytex->yuy2_mul = w >> 1; ytex->yuy2_div = 1.0 / ytex->yuy2_mul; ytex->bytes_per_pixel = bytes_per_pixel; /* changing size most likely invalidates cubic scale temp as well. * reduce gpu memory fragmentation and free that as well here. */ glDeleteTextures (OGL2_TEX_CUBIC_TEMP + 1, this->tex); this->tex[OGL2_TEX_CUBIC_TEMP] = 0; this->bicubic.pass1_tex_w = this->bicubic.pass1_tex_h = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": textures %dbit %dx%d.\n", bits, w, h); if (!this->PBO[0]) { uint32_t i; glGenBuffers (sizeof (this->PBO) / sizeof (this->PBO[0]), this->PBO); for (i = 0; i < sizeof (this->PBO) / sizeof (this->PBO[0]); i++) { if (!this->PBO[i]) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": falied to create pixel buffer objects.\n"); return 0; } } } if ( !this->fbo ) { glGenFramebuffers( 1, &this->fbo ); if ( !this->fbo ) return 0; } glGenTextures (OGL2_TEX_CUBIC_TEMP, this->tex); if (!this->tex[OGL2_TEX_VIDEO_0] || !this->tex[OGL2_TEX_VIDEO_1]) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": falied to create video textures.\n"); return 0; } uvh = (h + 1) >> 1; if (bytes_per_pixel <= 1) { _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_y], w, h, this->fmt_1p, GL_UNSIGNED_BYTE, GL_NEAREST); _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_u_v], w >> 1, uvh * 2, this->fmt_1p, GL_UNSIGNED_BYTE, GL_NEAREST); _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_u], w >> 1, uvh, this->fmt_1p, GL_UNSIGNED_BYTE, GL_NEAREST); _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_v], w >> 1, uvh, this->fmt_1p, GL_UNSIGNED_BYTE, GL_NEAREST); } else { /* TJ. Ums Verrecke net... * I'm sorry. * Not even under death threat... * After hours of trying GL_UNSIGNED_SHORT, GL_LUMINANCE16, GL_R16UI etc, I can tell: * 16bit texture upload is widely unsupported. * The closest thing working is extracting the high bytes. * This extends 10bit deep color to massive 2 bits :-/ * And not even this is portable to all of my drivers. * Furthermore, both nvidia and mesa seem to always use RGBA32F when requested * explicitly, or RGBA in all other cases internally. 16bit upload to the former * may work but would waste a lot of gpu mem there. * Lets try and upload as pairs of 8bit, and rejoin later in the shader. */ _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_y], w, h, this->fmt_2p, GL_UNSIGNED_BYTE, GL_NEAREST); _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_u_v], w >> 1, uvh * 2, this->fmt_2p, GL_UNSIGNED_BYTE, GL_NEAREST); _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_u], w >> 1, uvh, this->fmt_2p, GL_UNSIGNED_BYTE, GL_NEAREST); _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_v], w >> 1, uvh, this->fmt_2p, GL_UNSIGNED_BYTE, GL_NEAREST); } _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_yuv], w, h, this->fmt_2p, GL_UNSIGNED_BYTE, GL_NEAREST); _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_uv], w >> 1, uvh, this->fmt_2p, GL_UNSIGNED_BYTE, GL_NEAREST); if (this->hw) { uint32_t i; for (i = 0; i < 3; i++) { _config_texture (GL_TEXTURE_2D, this->tex[OGL2_TEX_HW0 + i], 0, 0, 0, 0, GL_NEAREST); } } glBindTexture( GL_TEXTURE_2D, 0 ); { uint32_t i; for (i = 0; i < OGL2_NUM_VIDEO_PBO; i++) { glBindBuffer (GL_PIXEL_UNPACK_BUFFER, this->PBO[i]); glBufferData (GL_PIXEL_UNPACK_BUFFER, w * uvh * 4, NULL, GL_STREAM_DRAW); } glBindBuffer (GL_PIXEL_UNPACK_BUFFER, 0); } ytex->width = w; ytex->height = h; _config_texture (GL_TEXTURE_RECTANGLE_ARB, this->tex[OGL2_TEX_VIDEO_0], w, h, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR); _config_texture (GL_TEXTURE_RECTANGLE_ARB, this->tex[OGL2_TEX_VIDEO_1], w, h, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); glBindFramebuffer( GL_FRAMEBUFFER, this->fbo ); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, this->tex[OGL2_TEX_VIDEO_0], 0); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_RECTANGLE_ARB, this->tex[OGL2_TEX_VIDEO_1], 0); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); return _OGL2_STATE_OK | _OGL2_STATE_CHANGED; } static void opengl2_upload_overlay (opengl2_driver_t *this, opengl2_overlay_t *o, vo_overlay_t *overlay) { uint32_t ii = o - this->ovl.buf; if (this->overlay_tex[ii] && ((o->tex_w != o->ovl_w) || (o->tex_h != o->ovl_h))) { glDeleteTextures (1, this->overlay_tex + ii); this->overlay_tex[ii] = 0; } if (!this->overlay_tex[ii]) { glGenTextures (1, this->overlay_tex + ii); o->tex_w = o->ovl_w; o->tex_h = o->ovl_h; } if (overlay->rle && !this->PBO[OGL2_OVERLAY_PBO]) return; glActiveTexture( GL_TEXTURE0 ); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, this->overlay_tex[ii]); if (overlay->argb_layer) { pthread_mutex_lock(&overlay->argb_layer->mutex); /* buffer can be changed or freed while unlocked */ glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, o->tex_w, o->tex_h, 0, GL_BGRA, GL_UNSIGNED_BYTE, overlay->argb_layer->buffer ); pthread_mutex_unlock(&overlay->argb_layer->mutex); } else { glBindBuffer (GL_PIXEL_UNPACK_BUFFER_ARB, this->PBO[OGL2_OVERLAY_PBO]); glBufferData( GL_PIXEL_UNPACK_BUFFER_ARB, o->tex_w * o->tex_h * 4, NULL, GL_STREAM_DRAW ); void *rgba = glMapBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY ); _x_overlay_to_argb32(overlay, rgba, o->tex_w, "RGBA"); glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER_ARB ); glTexImage2D( GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, o->tex_w, o->tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 ); glBindBuffer( GL_PIXEL_UNPACK_BUFFER_ARB, 0 ); } glTexParameterf( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); glTexParameterf( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glBindTexture( GL_TEXTURE_RECTANGLE_ARB, 0 ); } static void opengl2_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { opengl2_driver_t *this = (opengl2_driver_t *) this_gen; this->ovl.blend (this, frame_gen, overlay); } static void _opengl2_overlay_dummy_blend (opengl2_driver_t *this, vo_frame_t *frame_gen, vo_overlay_t *overlay) { (void)this; (void)frame_gen; (void)overlay; } static void _opengl2_overlay_blend (opengl2_driver_t *this, vo_frame_t *frame_gen, vo_overlay_t *overlay) { opengl2_overlay_t *ovl; (void)frame_gen; if (this->ovl.changed >= XINE_VORAW_MAX_OVL) { this->ovl.blend = _opengl2_overlay_dummy_blend; return; } if ( overlay->width<=0 || overlay->height<=0 ) return; ovl = this->ovl.buf + this->ovl.changed; ovl->ovl_w = overlay->width; ovl->ovl_h = overlay->height; ovl->ovl_x = overlay->x; ovl->ovl_y = overlay->y; /* prepare fast scaled/unscaled test in opengl2_draw_scaled_overlays (): * not user marked as unscaled and extent unknown or same as video size: scaled. */ if ((ovl->unscaled = overlay->unscaled)) { ovl->extent_size.lw = 0; ovl->extent_known.lw = ~0u; } else { ovl->extent_size.w[0] = overlay->extent_width; ovl->extent_size.w[1] = overlay->extent_height; ovl->extent_known.w[0] = ~(((int32_t)overlay->extent_width - 1) >> 31); ovl->extent_known.w[1] = ~(((int32_t)overlay->extent_height - 1) >> 31); ovl->extent_size.lw &= ovl->extent_known.lw; } if (overlay->rle) { if (!overlay->rgb_clut || !overlay->hili_rgb_clut) { _x_overlay_clut_yuv2rgb(overlay, this->color_standard); } } if (overlay->argb_layer || overlay->rle) { opengl2_upload_overlay(this, ovl, overlay); ++this->ovl.changed; } } static void opengl2_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { opengl2_driver_t *this = (opengl2_driver_t *) this_gen; this->ovl.end (this, vo_img); } static void _opengl2_overlay_dummy_end (opengl2_driver_t *this, vo_frame_t *vo_img) { (void)this; (void)vo_img; } static void _opengl2_overlay_end (opengl2_driver_t *this, vo_frame_t *vo_img) { int i; (void)vo_img; this->ovl.num = this->ovl.changed; /* free unused textures and buffers */ for (i = this->ovl.num; this->overlay_tex[i]; i++) this->ovl.buf[i].ovl_w = this->ovl.buf[i].ovl_h = 0; i -= this->ovl.num; if (i > 0) { glDeleteTextures (i, this->overlay_tex + this->ovl.num); memset (this->overlay_tex + this->ovl.num, 0, i * sizeof (this->overlay_tex[0])); } this->gl->release_current (this->gl); this->ovl.changed = 0; this->ovl.blend = _opengl2_overlay_dummy_blend; this->ovl.end = _opengl2_overlay_dummy_end; } static void opengl2_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { opengl2_driver_t *this = (opengl2_driver_t *) this_gen; (void)frame_gen; if (changed && this->gl->make_current (this->gl)) { this->ovl.blend = _opengl2_overlay_blend; this->ovl.end = _opengl2_overlay_end; this->ovl.changed = 0; } } static int opengl2_redraw_needed( vo_driver_t *this_gen ) { opengl2_driver_t *this = (opengl2_driver_t *) this_gen; _x_vo_scale_compute_ideal_size( &this->sc ); if ( _x_vo_scale_redraw_needed( &this->sc ) ) { _x_vo_scale_compute_output_size( &this->sc ); return 1; } return this->update_csc | this->gamma.changed | this->sharp.changed | this->transform.changed | this->bicubic.mode_changed; } static void opengl2_update_csc_matrix (opengl2_driver_t *that, opengl2_frame_t *frame, int bits) { int color_standard; color_standard = cm_from_frame (&frame->vo_frame); if ( that->update_csc || that->color_standard != color_standard || that->input_bits != bits) { const union {uint32_t w; uint8_t little;} endian_is = {1}; float hue = (float)that->hue * M_PI / 128.0; float saturation = (float)that->saturation / 128.0; float contrast = (float)that->contrast / 128.0; float brightness = that->brightness; cm_fill_matrix (that->csc_matrix, color_standard, hue, saturation, contrast, brightness); that->join16[endian_is.little] = 1u << (16 - bits); that->join16[1 - endian_is.little] = that->join16[endian_is.little] / 256.0; that->color_standard = color_standard; that->input_bits = bits; that->update_csc = 0; xprintf (that->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": b %d c %d s %d h %d [%dbit %s].\n", that->brightness, that->contrast, that->saturation, that->hue, bits, cm_names[color_standard]); } } /* DVB subtitles are split into rectangular regions, with no respect to text lines. * Instead, they just touch each other exactly. Make sure they still do after scaling. */ typedef struct { int x1, y1, x2, y2; } opengl2_rect_t; static void opengl2_rect_set (opengl2_rect_t *r, opengl2_overlay_t *o) { r->x1 = o->ovl_x; r->y1 = o->ovl_y; r->x2 = r->x1 + o->ovl_w; r->y2 = r->y1 + o->ovl_h; } static void opengl2_draw_scaled_overlays (opengl2_driver_t *that, opengl2_frame_t *frame) { _opengl2_w2_t framesize; opengl2_overlay_t *o = NULL; int i, us; #if 0 /* skip high qual hack when there is too much zoom, to keep subs/osd readable. */ i = (int)(that->sc.zoom_factor_x * 160.0) - (int)(0.95 * 160.0); us = (int)(that->sc.zoom_factor_y * 160.0) - (int)(0.95 * 160.0); if ((i | us) & ~15) { for (i = 0; i < that->ovl.num; i++) that->ovl.unscaled_list[i] = i; that->ovl.unscaled_list[i] = 255; return; } #endif /* skip padding. */ framesize.w[0] = frame->width - frame->vo_frame.crop_right; framesize.w[1] = frame->height - frame->vo_frame.crop_bottom; /* look ahaed first. */ for (us = 0, i = 0; i < that->ovl.num; i++) { o = that->ovl.buf + i; /* if extent == video size or unknown, blend it here, and make it take part in bicubic scaling. * other scaled overlays with known extent: * draw overlay over scaled video frame -> more sharpness in overlay. */ if (!(o->extent_known.lw & (o->extent_size.lw ^ framesize.lw))) break; that->ovl.unscaled_list[us++] = i; } if (i >= that->ovl.num) { that->ovl.unscaled_list[us] = 255; return; } /* ok we have scaled ones. */ glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0.0, frame->width, 0.0, frame->height, -1.0, 1.0); glEnable (GL_BLEND); { opengl2_rect_t or; opengl2_rect_set (&or, o); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->overlay_tex[o - that->ovl.buf]); glBegin (GL_QUADS); glTexCoord2f (0, 0); glVertex3f (or.x1, or.y1, 0); glTexCoord2f (0, o->tex_h); glVertex3f (or.x1, or.y2, 0); glTexCoord2f (o->tex_w, o->tex_h); glVertex3f (or.x2, or.y2, 0); glTexCoord2f (o->tex_w, 0); glVertex3f (or.x2, or.y1, 0); glEnd (); } for (i++; i < that->ovl.num; i++) { opengl2_rect_t or; o = that->ovl.buf + i; if (o->extent_known.lw & (o->extent_size.lw ^ framesize.lw)) { that->ovl.unscaled_list[us++] = i; continue; } opengl2_rect_set (&or, o); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->overlay_tex[o - that->ovl.buf]); glBegin (GL_QUADS); glTexCoord2f (0, 0); glVertex3f (or.x1, or.y1, 0); glTexCoord2f (0, o->tex_h); glVertex3f (or.x1, or.y2, 0); glTexCoord2f (o->tex_w, o->tex_h); glVertex3f (or.x2, or.y2, 0); glTexCoord2f (o->tex_w, 0); glVertex3f (or.x2, or.y1, 0); glEnd (); } glDisable (GL_BLEND); that->ovl.unscaled_list[us] = 255; } static void opengl2_draw_unscaled_overlays( opengl2_driver_t *that ) { int us; glEnable( GL_BLEND ); for (us = 0; that->ovl.unscaled_list[us] != 255; us++) { opengl2_overlay_t *o = that->ovl.buf + that->ovl.unscaled_list[us]; vo_scale_map_t map; map.in.x0 = 0; map.in.y0 = 0; map.in.x1 = o->ovl_w; map.in.y1 = o->ovl_h; map.out.x0 = o->ovl_x; map.out.y0 = o->ovl_y; if (!o->unscaled) { map.out.x1 = o->extent_size.w[0]; map.out.y1 = o->extent_size.w[1]; if (_x_vo_scale_map (&that->sc, &map) != VO_SCALE_MAP_OK) continue; } else { map.out.x1 = o->ovl_x + o->ovl_w; map.out.y1 = o->ovl_y + o->ovl_h; } glActiveTexture( GL_TEXTURE0 ); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->overlay_tex[o - that->ovl.buf]); glBegin( GL_QUADS ); glTexCoord2f (map.in.x0, map.in.y0); glVertex3f (map.out.x0, map.out.y0, 0.); glTexCoord2f (map.in.x0, map.in.y1); glVertex3f (map.out.x0, map.out.y1, 0.); glTexCoord2f (map.in.x1, map.in.y1); glVertex3f (map.out.x1, map.out.y1, 0.); glTexCoord2f (map.in.x1, map.in.y0); glVertex3f (map.out.x1, map.out.y0, 0.); glEnd(); } glDisable( GL_BLEND ); } static GLuint opengl2_vtex_swap (opengl2_driver_t *that) { static const uint8_t ti[2] = { OGL2_TEX_VIDEO_0, OGL2_TEX_VIDEO_1 }; static const GLuint ca[2] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 }; GLuint old_vtex; old_vtex = that->tex[ti[that->vtex.index]]; that->vtex.index ^= 1; glDrawBuffer (ca[that->vtex.index]); that->vtex.tex = that->tex[ti[that->vtex.index]]; return old_vtex; } static int opengl2_sharpness (opengl2_driver_t *that, opengl2_frame_t *frame) { GLuint vtex; if (!that->sharp.program.compiled) { if (!opengl2_build_program (that, &that->sharp.program, blur_sharpen_frag, "blur_sharpen_frag", blur_sharpen_args)) return 0; } vtex = opengl2_vtex_swap (that); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( 0.0, frame->width, 0.0, frame->height, -1.0, 1.0 ); glActiveTexture( GL_TEXTURE0 ); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, vtex); glUseProgram (that->sharp.program.program); glUniform1i (that->sharp.program.args[0], 0); glUniform1f (that->sharp.program.args[1], that->sharp.mid); glUniform1f (that->sharp.program.args[2], that->sharp.side); glUniform1f (that->sharp.program.args[3], that->sharp.corn); glBegin( GL_QUADS ); glTexCoord2f( 0, 0 ); glVertex3f( 0, 0, 0.); glTexCoord2f( 0, frame->height ); glVertex3f( 0, frame->height, 0.); glTexCoord2f( frame->width, frame->height ); glVertex3f( frame->width, frame->height, 0.); glTexCoord2f( frame->width, 0 ); glVertex3f( frame->width, 0, 0.); glEnd(); glUseProgram( 0 ); return 1; } typedef struct { int guiw, guih; int sx1, sx2, sy1, sy2, dx[2], dy[2], dw, dh; GLuint video_texture; } opengl2_draw_info_t; static uint32_t _opengl2_setup_bicubic (opengl2_driver_t *that, uint32_t flags) { uint32_t state = _OGL2_STATE_OK; if (flags & OGL2_BC_LUT) { if (!that->tex[OGL2_TEX_CUBIC_LUT]) { if (!create_lut_texture (that)) return 0; state |= _OGL2_STATE_CHANGED; } that->bicubic.flags &= ~OGL2_BC_LUT; } if (flags & OGL2_BC_PROG_1) { if (!that->bicubic.pass1_program.compiled && !opengl2_build_program (that, &that->bicubic.pass1_program, bicubic_pass1_frag, "bicubic_pass1_frag", bicubic_pass1_args)) return 0; that->bicubic.flags &= ~OGL2_BC_PROG_1; } if (flags & OGL2_BC_PROG_2) { if (!that->bicubic.pass2_program.compiled && !opengl2_build_program (that, &that->bicubic.pass2_program, bicubic_pass2_frag, "bicubic_pass2_frag", bicubic_pass2_args)) return 0; that->bicubic.flags &= ~OGL2_BC_PROG_2; } if (flags & OGL2_BC_FBO) { if (!that->bicubic.fbo) { glGenFramebuffers (1, &that->bicubic.fbo); if (!that->bicubic.fbo) return 0; } that->bicubic.flags &= ~OGL2_BC_FBO; } return state; } static inline int opengl2_setup_bicubic (opengl2_driver_t *that, uint32_t flags) { flags &= that->bicubic.flags; if (!flags) return _OGL2_STATE_OK; return _opengl2_setup_bicubic (that, flags); } static uint32_t opengl2_draw_video_bicubic (opengl2_driver_t *that, const opengl2_draw_info_t *info) { uint32_t state = opengl2_setup_bicubic (that, OGL2_BC_LUT | OGL2_BC_PROG_1 | OGL2_BC_PROG_2 | OGL2_BC_FBO); if (!state) return 0; if ((that->bicubic.pass1_tex_w ^ info->dw) | (that->bicubic.pass1_tex_h ^ info->dh)) { if (that->tex[OGL2_TEX_CUBIC_TEMP]) glDeleteTextures (1, &that->tex[OGL2_TEX_CUBIC_TEMP]); glGenTextures (1, &that->tex[OGL2_TEX_CUBIC_TEMP]); if (!that->tex[OGL2_TEX_CUBIC_TEMP]) return 0; state |= _OGL2_STATE_CHANGED; _config_texture (GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_TEMP], info->dw, info->dh, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, 0); that->bicubic.pass1_tex_w = info->dw; that->bicubic.pass1_tex_h = info->dh; xprintf (that->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": bicubic temp texture %dx%d.\n", info->dw, info->dh); } glBindFramebuffer (GL_FRAMEBUFFER, that->bicubic.fbo); glFramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_TEMP], 0); glViewport (0, 0, info->dw, info->dh); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0, info->dw, 0, info->dh, -1, 1); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, info->video_texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture (GL_TEXTURE1); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_LUT]); glUseProgram (that->bicubic.pass1_program.program); glUniform1i (that->bicubic.pass1_program.args[0], 0); glUniform1i (that->bicubic.pass1_program.args[1], 1); glUniform1f (that->bicubic.pass1_program.args[2], that->bicubic.lut_y); glBegin (GL_QUADS); glTexCoord2f (info->sx1, info->sy1); glVertex3f ( 0, 0, 0); glTexCoord2f (info->sx1, info->sy2); glVertex3f ( 0, info->dh, 0); glTexCoord2f (info->sx2, info->sy2); glVertex3f (info->dw, info->dh, 0); glTexCoord2f (info->sx2, info->sy1); glVertex3f (info->dw, 0, 0); glEnd (); glActiveTexture (GL_TEXTURE0); glBindFramebuffer (GL_FRAMEBUFFER, 0); glViewport (0, 0, info->guiw, info->guih); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0, info->guiw, info->guih, 0, -1, 1); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_TEMP]); glActiveTexture (GL_TEXTURE1); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_LUT]); glUseProgram (that->bicubic.pass2_program.program); glUniform1i (that->bicubic.pass2_program.args[0], 0); glUniform1i (that->bicubic.pass2_program.args[1], 1); glUniform1f (that->bicubic.pass2_program.args[2], that->bicubic.lut_y); glBegin (GL_QUADS); glTexCoord2f ( 0, 0); glVertex3f (info->dx[0], info->dy[0], 0); glTexCoord2f ( 0, info->dh); glVertex3f (info->dx[0], info->dy[1], 0); glTexCoord2f (info->dw, info->dh); glVertex3f (info->dx[1], info->dy[1], 0); glTexCoord2f (info->dw, 0); glVertex3f (info->dx[1], info->dy[0], 0); glEnd (); glUseProgram (0); return state; } static uint32_t opengl2_draw_video_cubic_x (opengl2_driver_t *that, const opengl2_draw_info_t *info) { uint32_t state = opengl2_setup_bicubic (that, OGL2_BC_LUT | OGL2_BC_PROG_1); if (!state) return 0; glViewport (0, 0, info->guiw, info->guih); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0, info->guiw, info->guih, 0, -1, 1); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, info->video_texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture (GL_TEXTURE1); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_LUT]); glUseProgram (that->bicubic.pass1_program.program); glUniform1i (that->bicubic.pass1_program.args[0], 0); glUniform1i (that->bicubic.pass1_program.args[1], 1); glUniform1f (that->bicubic.pass1_program.args[2], that->bicubic.lut_y); glBegin (GL_QUADS); glTexCoord2f (info->sx1, info->sy1); glVertex3f (info->dx[0], info->dy[0], 0); glTexCoord2f (info->sx1, info->sy2); glVertex3f (info->dx[0], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy2); glVertex3f (info->dx[1], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy1); glVertex3f (info->dx[1], info->dy[0], 0); glEnd (); glUseProgram (0); return state; } static uint32_t opengl2_draw_video_cubic_y (opengl2_driver_t *that, const opengl2_draw_info_t *info) { uint32_t state = opengl2_setup_bicubic (that, OGL2_BC_LUT | OGL2_BC_PROG_2); if (!state) return 0; glViewport (0, 0, info->guiw, info->guih); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0, info->guiw, info->guih, 0, -1, 1); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, info->video_texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glActiveTexture (GL_TEXTURE1); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, that->tex[OGL2_TEX_CUBIC_LUT]); glUseProgram (that->bicubic.pass2_program.program); glUniform1i (that->bicubic.pass2_program.args[0], 0); glUniform1i (that->bicubic.pass2_program.args[1], 1); glUniform1f (that->bicubic.pass2_program.args[2], that->bicubic.lut_y); glBegin (GL_QUADS); glTexCoord2f (info->sx1, info->sy1); glVertex3f (info->dx[0], info->dy[0], 0); glTexCoord2f (info->sx1, info->sy2); glVertex3f (info->dx[0], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy2); glVertex3f (info->dx[1], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy1); glVertex3f (info->dx[1], info->dy[0], 0); glEnd (); glUseProgram (0); return state; } static int opengl2_draw_video_simple (opengl2_driver_t *that, const opengl2_draw_info_t *info) { (void)that; glViewport (0, 0, info->guiw, info->guih); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0, info->guiw, info->guih, 0, -1, 1); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, info->video_texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glBegin (GL_QUADS); glTexCoord2f (info->sx1, info->sy1); glVertex3f (info->dx[0], info->dy[0], 0); glTexCoord2f (info->sx1, info->sy2); glVertex3f (info->dx[0], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy2); glVertex3f (info->dx[1], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy1); glVertex3f (info->dx[1], info->dy[0], 0); glEnd (); return _OGL2_STATE_OK; } static uint32_t opengl2_draw_video_bilinear (opengl2_driver_t *that, const opengl2_draw_info_t *info) { (void)that; glViewport (0, 0, info->guiw, info->guih); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0, info->guiw, info->guih, 0, -1, 1); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glActiveTexture (GL_TEXTURE0); glBindTexture (GL_TEXTURE_RECTANGLE_ARB, info->video_texture); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glBegin (GL_QUADS); glTexCoord2f (info->sx1, info->sy1); glVertex3f (info->dx[0], info->dy[0], 0); glTexCoord2f (info->sx1, info->sy2); glVertex3f (info->dx[0], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy2); glVertex3f (info->dx[1], info->dy[1], 0); glTexCoord2f (info->sx2, info->sy1); glVertex3f (info->dx[1], info->dy[0], 0); glEnd (); return _OGL2_STATE_OK; } static void _upload_texture (GLenum target, GLuint tex, GLenum format, GLenum type, const void *data, unsigned pitch, GLuint bpp, GLuint height, GLuint pbo) { GLenum pbo_target = (target == GL_TEXTURE_2D ? GL_PIXEL_UNPACK_BUFFER : GL_PIXEL_UNPACK_BUFFER_ARB); { void *mem; /* glPixelTransferi (GL_UNPACK_SWAP_BYTES, GL_TRUE); */ glBindBuffer (pbo_target, pbo); glBindTexture (target, tex); mem = glMapBuffer (pbo_target, GL_WRITE_ONLY); xine_fast_memcpy (mem, data, pitch * height); glUnmapBuffer (pbo_target); glTexSubImage2D (target, 0, 0, 0, pitch / bpp, height, format, type, NULL); glBindBuffer (pbo_target, 0); } } typedef enum { OGL2_FT_UNKNOWN = 0, OGL2_FT_YV12, OGL2_FT_YV12_DEEP, OGL2_FT_NV12, OGL2_FT_YUY2, OGL2_FT_HW_UNKNOWN, OGL2_FT_HW_YV12, OGL2_FT_HW_YV12_DEEP, OGL2_FT_HW_NV12, OGL2_FT_HW_YUY2, OGL2_FT_LAST } _ogl2_ft_t; #define OGL2_FT_MASK 15 static uint32_t opengl2_get_ft (uint32_t type) { uint32_t _type, ret = 0; /* NOTE: correct [u]int32_t use needed for gcc 7 autovectorization. */ _type = (type & 0x7fffffff) ^ (XINE_IMGFMT_YV12 ^ 0x7fffffff); ret += ((int32_t)(_type + 1) >> 31) & (uint32_t)OGL2_FT_YV12; _type ^= XINE_IMGFMT_YV12 ^ XINE_IMGFMT_YV12_DEEP; ret += ((int32_t)(_type + 1) >> 31) & (uint32_t)OGL2_FT_YV12_DEEP; _type ^= XINE_IMGFMT_YV12_DEEP ^ XINE_IMGFMT_NV12; ret += ((int32_t)(_type + 1) >> 31) & (uint32_t)OGL2_FT_NV12; _type ^= XINE_IMGFMT_NV12 ^ XINE_IMGFMT_YUY2; ret += ((int32_t)(_type + 1) >> 31) & (uint32_t)OGL2_FT_YUY2; return ret; } static int opengl2_draw (opengl2_driver_t *that, opengl2_frame_t *frame) { int bits = (frame->vo_frame.format == XINE_IMGFMT_YV12_DEEP) ? VO_GET_FLAGS_DEPTH(frame->vo_frame.flags) : 8; int bpp = (bits + 7) >> 3, uvh = 0; uint32_t ft, state; opengl2_csc_shader_t shader; if (!that->gl->make_current (that->gl)) return 0; state = opengl2_check_textures_size (that, frame->width, frame->height, bits); if (!state) { that->gl->release_current (that->gl); return 0; } opengl2_update_csc_matrix (that, frame, bits); glBindFramebuffer( GL_FRAMEBUFFER, that->fbo ); { unsigned int sw_format = frame->format; ft = OGL2_FT_UNKNOWN; if (that->hw && (frame->format == that->hw->frame_format)) { unsigned int tex, num_texture = 0; ft = OGL2_FT_HW_UNKNOWN; that->glconv->get_textures (that->glconv, &frame->vo_frame, GL_TEXTURE_2D, &that->tex[OGL2_TEX_HW0], &num_texture, &sw_format); /* XXX: does a hardware decoder use our joined YV12 hack? */ uvh = !(num_texture - 2); for (tex = 0; tex < num_texture; tex++) { glActiveTexture (GL_TEXTURE0 + tex); glBindTexture (GL_TEXTURE_2D, that->tex[OGL2_TEX_HW0 + tex]); } } ft += opengl2_get_ft (sw_format); } shader = that->last_csc_shader; /* make gcc avoid range check code. */ switch (ft & OGL2_FT_MASK) { case OGL2_FT_YV12: uvh = (frame->height + 1) >> 1; glActiveTexture (GL_TEXTURE0); _upload_texture (GL_TEXTURE_2D, that->tex[OGL2_TEX_y], that->fmt_1p, GL_UNSIGNED_BYTE, frame->vo_frame.base[0], frame->vo_frame.pitches[0], bpp, frame->height, _opengl2_next_videoPBO (that)); glActiveTexture (GL_TEXTURE1); /* should always be true. yuv420[g]_frag is still needed for YV12 hardware decoders. */ if (!(((uintptr_t)frame->vo_frame.pitches[1] ^ (uintptr_t)frame->vo_frame.pitches[2]) | ((uintptr_t)(frame->vo_frame.base[1] + frame->vo_frame.pitches[1] * uvh) ^ (uintptr_t)frame->vo_frame.base[2]))) { _upload_texture (GL_TEXTURE_2D, that->tex[OGL2_TEX_u_v], that->fmt_1p, GL_UNSIGNED_BYTE, frame->vo_frame.base[1], frame->vo_frame.pitches[1], bpp, uvh * 2, _opengl2_next_videoPBO (that)); /* help gcc jump target optimization. */ uvh = 1; } else { _upload_texture (GL_TEXTURE_2D, that->tex[OGL2_TEX_u], that->fmt_1p, GL_UNSIGNED_BYTE, frame->vo_frame.base[1], frame->vo_frame.pitches[1], bpp, uvh, _opengl2_next_videoPBO (that)); glActiveTexture (GL_TEXTURE2); _upload_texture (GL_TEXTURE_2D, that->tex[OGL2_TEX_v], that->fmt_1p, GL_UNSIGNED_BYTE, frame->vo_frame.base[2], frame->vo_frame.pitches[2], bpp, uvh, _opengl2_next_videoPBO (that)); uvh = 0; } /* fall through */ case OGL2_FT_HW_YV12: if (uvh) { if (that->gamma.value & that->csc_shaders[OGL2_cscs_yuv420jg].compiled) { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv420jg].program); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420jg].args[4], 1); glUniform4f (that->csc_shaders[OGL2_cscs_yuv420jg].args[5], that->gamma.gamma2, that->gamma.gamma2, that->gamma.gamma2, 0.0); glUniform4f (that->csc_shaders[OGL2_cscs_yuv420jg].args[6], that->gamma.gamma1, that->gamma.gamma1, that->gamma.gamma1, 1.0); } else { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv420j].program); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420j].args[4], 1); } } else { if (that->gamma.value & that->csc_shaders[OGL2_cscs_yuv420g].compiled) { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv420g].program); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420g].args[4], 1); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420g].args[5], 2); glUniform4f (that->csc_shaders[OGL2_cscs_yuv420g].args[6], that->gamma.gamma2, that->gamma.gamma2, that->gamma.gamma2, 0.0); glUniform4f (that->csc_shaders[OGL2_cscs_yuv420g].args[7], that->gamma.gamma1, that->gamma.gamma1, that->gamma.gamma1, 1.0); } else { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv420].program); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420].args[4], 1); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420].args[5], 2); } } break; case OGL2_FT_YV12_DEEP: uvh = (frame->height + 1) >> 1; glActiveTexture (GL_TEXTURE0); _upload_texture (GL_TEXTURE_2D, that->tex[OGL2_TEX_y], that->fmt_2p, GL_UNSIGNED_BYTE, frame->vo_frame.base[0], frame->vo_frame.pitches[0], bpp, frame->height, _opengl2_next_videoPBO (that)); glActiveTexture (GL_TEXTURE1); _upload_texture (GL_TEXTURE_2D, that->tex[OGL2_TEX_u_v], that->fmt_2p, GL_UNSIGNED_BYTE, frame->vo_frame.base[1], frame->vo_frame.pitches[1], bpp, uvh * 2, _opengl2_next_videoPBO (that)); /* fall through */ case OGL2_FT_HW_YV12_DEEP: if (that->gamma.value & that->csc_shaders[OGL2_cscs_yuv420j16g].compiled) { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv420j16g].program); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420j16g].args[4], 1); glUniform2f (that->csc_shaders[OGL2_cscs_yuv420j16g].args[5], that->join16[0], that->join16[1]); glUniform4f (that->csc_shaders[OGL2_cscs_yuv420j16g].args[6], that->gamma.gamma2, that->gamma.gamma2, that->gamma.gamma2, 0.0); glUniform4f (that->csc_shaders[OGL2_cscs_yuv420j16g].args[7], that->gamma.gamma1, that->gamma.gamma1, that->gamma.gamma1, 1.0); } else { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv420j16].program); glUniform1i (that->csc_shaders[OGL2_cscs_yuv420j16].args[4], 1); glUniform2f (that->csc_shaders[OGL2_cscs_yuv420j16].args[5], that->join16[0], that->join16[1]); } break; case OGL2_FT_NV12: glActiveTexture (GL_TEXTURE0); _upload_texture(GL_TEXTURE_2D, that->tex[OGL2_TEX_y], that->fmt_1p, GL_UNSIGNED_BYTE, frame->vo_frame.base[0], frame->vo_frame.pitches[0], 1, frame->height, _opengl2_next_videoPBO (that)); glActiveTexture (GL_TEXTURE1); _upload_texture(GL_TEXTURE_2D, that->tex[OGL2_TEX_uv], that->fmt_2p, GL_UNSIGNED_BYTE, frame->vo_frame.base[1], frame->vo_frame.pitches[1], 2, (frame->height + 1) >> 1, _opengl2_next_videoPBO (that)); /* fall through */ case OGL2_FT_HW_NV12: if (that->gamma.value & that->csc_shaders[OGL2_cscs_nv12g].compiled) { glUseProgram (that->csc_shaders[shader = OGL2_cscs_nv12g].program); glUniform1i (that->csc_shaders[OGL2_cscs_nv12g].args[4], 1); glUniform4f (that->csc_shaders[OGL2_cscs_nv12g].args[5], that->gamma.gamma2, that->gamma.gamma2, that->gamma.gamma2, 0.0); glUniform4f (that->csc_shaders[OGL2_cscs_nv12g].args[6], that->gamma.gamma1, that->gamma.gamma1, that->gamma.gamma1, 1.0); } else { glUseProgram (that->csc_shaders[shader = OGL2_cscs_nv12].program); glUniform1i (that->csc_shaders[OGL2_cscs_nv12].args[4], 1); } break; case OGL2_FT_YUY2: glActiveTexture (GL_TEXTURE0); _upload_texture(GL_TEXTURE_2D, that->tex[OGL2_TEX_yuv], that->fmt_2p, GL_UNSIGNED_BYTE, frame->vo_frame.base[0], frame->vo_frame.pitches[0], 2, frame->height, _opengl2_next_videoPBO (that)); /* fall through */ case OGL2_FT_HW_YUY2: if (that->gamma.value & that->csc_shaders[OGL2_cscs_yuv422g].compiled) { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv422g].program); glUniform2f (that->csc_shaders[OGL2_cscs_yuv422g].args[4], that->yuvtex.yuy2_mul, that->yuvtex.yuy2_div); glUniform4f (that->csc_shaders[OGL2_cscs_yuv422g].args[5], that->gamma.gamma2, that->gamma.gamma2, that->gamma.gamma2, 0.0); glUniform4f (that->csc_shaders[OGL2_cscs_yuv422g].args[6], that->gamma.gamma1, that->gamma.gamma1, that->gamma.gamma1, 1.0); } else { glUseProgram (that->csc_shaders[shader = OGL2_cscs_yuv422].program); glUniform2f (that->csc_shaders[OGL2_cscs_yuv422].args[4], that->yuvtex.yuy2_mul, that->yuvtex.yuy2_div); } break; default: /* unknown format */ xprintf (that->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": unknown image format 0x%08x.\n", frame->format); return 0; } if (shader != that->last_csc_shader) { that->last_csc_shader = shader; xprintf (that->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": using csc shader %s.\n", that->csc_shaders[shader].name); } { opengl2_program_t *p = that->csc_shaders + shader; glUniform4f (p->args[0], that->csc_matrix[0], that->csc_matrix[1], that->csc_matrix[2], that->csc_matrix[3]); glUniform4f (p->args[1], that->csc_matrix[4], that->csc_matrix[5], that->csc_matrix[6], that->csc_matrix[7]); glUniform4f (p->args[2], that->csc_matrix[8], that->csc_matrix[9], that->csc_matrix[10], that->csc_matrix[11]); glUniform1i (p->args[3], 0); } glViewport( 0, 0, frame->width, frame->height ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( 0.0, that->yuvtex.relw, 0.0, 1.0, -1.0, 1.0 ); glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); opengl2_vtex_swap (that); glBegin( GL_QUADS ); glTexCoord2f( 0, 0 ); glVertex2i( 0, 0 ); glTexCoord2f( 0, 1 ); glVertex2i( 0, 1 ); glTexCoord2f( 1, 1 ); glVertex2i( 1, 1 ); glTexCoord2f( 1, 0 ); glVertex2i( 1, 0 ); glEnd(); glUseProgram( 0 ); if (that->gamma.changed) { that->gamma.changed = 0; xprintf (that->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": gamma %d.\n", that->gamma.value); } // post-processing if (that->sharp.changed) { that->sharp.side = that->sharp.value / 100.0 * frame->width / 1920.0; if (that->sharp.value < 0) that->sharp.side /= -6.8; else that->sharp.side /= -3.4; that->sharp.corn = that->sharp.side * 0.707; that->sharp.mid = 1.0 - 4.0 * (that->sharp.side + that->sharp.corn); that->sharp.changed = 0; xprintf (that->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": sharpness %d.\n", that->sharp.value); } if (that->sharp.value) opengl2_sharpness (that, frame); // draw scaled overlays opengl2_draw_scaled_overlays( that, frame ); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); // draw on screen { opengl2_draw_info_t info; info.video_texture = that->vtex.tex; info.guiw = that->sc.gui_width; info.guih = that->sc.gui_height; info.sx1 = that->sc.displayed_xoffset; info.sy1 = that->sc.displayed_yoffset; info.sx2 = that->sc.displayed_width + that->sc.displayed_xoffset; info.sy2 = that->sc.displayed_height + that->sc.displayed_yoffset; info.dw = that->sc.output_width; info.dh = that->sc.displayed_height; { uint32_t indx; indx = ((that->transform.flags >> _FLAG2BIT (XINE_VO_TRANSFORM_FLIP_H)) & 1) ^ 1; info.dx[0] = info.dx[1] = that->sc.output_xoffset; info.dx[indx] += that->sc.output_width; indx = ((that->transform.flags >> _FLAG2BIT (XINE_VO_TRANSFORM_FLIP_V)) & 1) ^ 1; info.dy[0] = info.dy[1] = that->sc.output_yoffset; info.dy[indx] += that->sc.output_height; } that->transform.changed = 0; state &= ~_OGL2_STATE_OK; switch (that->bicubic.mode2 & SCALE_MASK) { case SCALE_CATMULLROM: case SCALE_COS: if (that->sc.displayed_width != that->sc.output_width) { if (that->sc.displayed_height != that->sc.output_height) state |= opengl2_draw_video_bicubic (that, &info); else state |= opengl2_draw_video_cubic_x (that, &info); break; } if (that->sc.displayed_height != that->sc.output_height) { state |= opengl2_draw_video_cubic_y (that, &info); break; } /* fall through */ case SCALE_SIMPLE: state |= opengl2_draw_video_simple (that, &info); break; default: ; } if (!(state & _OGL2_STATE_OK)) state |= opengl2_draw_video_bilinear (that, &info); that->bicubic.mode_changed = 0; } // draw unscaled overlays opengl2_draw_unscaled_overlays (that); // if (that->mglXSwapInterval) //that->mglXSwapInterval (1); that->gl->swap_buffers (that->gl); if (state & _OGL2_STATE_CHANGED) _ogl2_dump_tex_fmts (that); that->gl->release_current (that->gl); return state & _OGL2_STATE_OK; } static void opengl2_display_frame( vo_driver_t *this_gen, vo_frame_t *frame_gen ) { opengl2_driver_t *this = (opengl2_driver_t *) this_gen; opengl2_frame_t *frame = (opengl2_frame_t *) frame_gen; int rd = (frame->width ^ this->sc.delivered_width) | (frame->height ^ this->sc.delivered_height) | (frame->vo_frame.crop_left ^ this->sc.crop_left) | (frame->vo_frame.crop_right ^ this->sc.crop_right) | (frame->vo_frame.crop_top ^ this->sc.crop_top) | (frame->vo_frame.crop_bottom ^ this->sc.crop_bottom); if (rd || (frame->ratio != this->sc.delivered_ratio)) { this->sc.delivered_height = frame->height; this->sc.delivered_width = frame->width; this->sc.delivered_ratio = frame->ratio; this->sc.crop_left = frame->vo_frame.crop_left; this->sc.crop_right = frame->vo_frame.crop_right; this->sc.crop_top = frame->vo_frame.crop_top; this->sc.crop_bottom = frame->vo_frame.crop_bottom; this->sc.force_redraw = 1; /* trigger re-calc of output size */ } /* opengl2_redraw_needed (this_gen); */ _x_vo_scale_compute_ideal_size (&this->sc); if (_x_vo_scale_redraw_needed (&this->sc)) _x_vo_scale_compute_output_size (&this->sc); rd = (this->last_gui_width ^ this->sc.gui_width) | (this->last_gui_height ^ this->sc.gui_height); if (rd) { this->last_gui_width = this->sc.gui_width; this->last_gui_height = this->sc.gui_height; if (this->gl->resize) this->gl->resize (this->gl, this->last_gui_width, this->last_gui_height); } if( !this->exiting ) { pthread_mutex_lock(&this->drawable_lock); /* protect drawable from being changed */ opengl2_draw( this, frame ); pthread_mutex_unlock(&this->drawable_lock); /* allow changing drawable again */ } if( !this->exit_indx ) opengl2_exit_register( this ); frame->vo_frame.free( &frame->vo_frame ); } static int opengl2_get_property( vo_driver_t *this_gen, int property ) { opengl2_driver_t *this = (opengl2_driver_t*)this_gen; switch (property) { case VO_PROP_MAX_NUM_FRAMES: return 22; case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; case VO_PROP_OUTPUT_WIDTH: return this->sc.output_width; case VO_PROP_OUTPUT_HEIGHT: return this->sc.output_height; case VO_PROP_OUTPUT_XOFFSET: return this->sc.output_xoffset; case VO_PROP_OUTPUT_YOFFSET: return this->sc.output_yoffset; case VO_PROP_HUE: return this->hue; case VO_PROP_SATURATION: return this->saturation; case VO_PROP_CONTRAST: return this->contrast; case VO_PROP_BRIGHTNESS: return this->brightness; case VO_PROP_GAMMA: return this->gamma.value; case VO_PROP_SHARPNESS: return this->sharp.value; case VO_PROP_ZOOM_X: return this->zoom_x; case VO_PROP_ZOOM_Y: return this->zoom_y; case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; case VO_PROP_MAX_VIDEO_WIDTH: return this->max_video_width; case VO_PROP_MAX_VIDEO_HEIGHT: return this->max_video_height; case VO_PROP_CAPS2: return VO_CAP2_NV12 | VO_CAP2_TRANSFORM | VO_CAP2_ACCEL_GENERIC; case VO_PROP_TRANSFORM: return this->transform.flags; } return -1; } static int opengl2_set_property( vo_driver_t *this_gen, int property, int value ) { opengl2_driver_t *this = (opengl2_driver_t*)this_gen; //fprintf(stderr,"opengl2_set_property: property=%d, value=%d\n", property, value ); switch (property) { case VO_PROP_ZOOM_X: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->zoom_x = value; this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size( &this->sc ); this->sc.force_redraw = 1; //trigger re-calc of output size } break; case VO_PROP_ZOOM_Y: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->zoom_y = value; this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size( &this->sc ); this->sc.force_redraw = 1; // trigger re-calc of output size } break; case VO_PROP_ASPECT_RATIO: if ( value>=XINE_VO_ASPECT_NUM_RATIOS ) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; this->sc.force_redraw = 1; // trigger re-calc of output size break; case VO_PROP_HUE: this->hue = value; this->update_csc = 1; break; case VO_PROP_SATURATION: this->saturation = value; this->update_csc = 1; break; case VO_PROP_CONTRAST: this->contrast = value; this->update_csc = 1; break; case VO_PROP_BRIGHTNESS: this->brightness = value; this->update_csc = 1; break; case VO_PROP_GAMMA: this->gamma.value = value; this->gamma.changed = 1; this->gamma.gamma2 = -(float)value / (float)128; this->gamma.gamma1 = 1.0 - this->gamma.gamma2; break; case VO_PROP_SHARPNESS: this->sharp.value = value; this->sharp.changed = 1; break; case VO_PROP_TRANSFORM: value &= XINE_VO_TRANSFORM_FLIP_H | XINE_VO_TRANSFORM_FLIP_V; this->transform.changed |= value ^ this->transform.flags; this->transform.flags = value; break; } return value; } static void opengl2_get_property_min_max( vo_driver_t *this_gen, int property, int *min, int *max ) { (void)this_gen; switch ( property ) { case VO_PROP_HUE: case VO_PROP_BRIGHTNESS: case VO_PROP_GAMMA: *max = 127; *min = -128; break; case VO_PROP_SATURATION: *max = 255; *min = 0; break; case VO_PROP_CONTRAST: *max = 255; *min = 0; break; case VO_PROP_SHARPNESS: *max = 100; *min = -100; break; default: *max = 0; *min = 0; } } static int opengl2_gui_data_exchange( vo_driver_t *this_gen, int data_type, void *data ) { opengl2_driver_t *this = (opengl2_driver_t*)this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: { this->sc.force_redraw = 1; break; } case XINE_GUI_SEND_DRAWABLE_CHANGED: { pthread_mutex_lock(&this->drawable_lock); /* wait for other thread which is currently displaying */ this->gl->set_native_window(this->gl, data); pthread_mutex_unlock(&this->drawable_lock); this->sc.force_redraw = 1; break; } case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; break; } default: return -1; } return 0; } static uint32_t opengl2_get_capabilities( vo_driver_t *this_gen ) { opengl2_driver_t *this = (opengl2_driver_t *) this_gen; return VO_CAP_YV12 | VO_CAP_YV12_DEEP | VO_CAP_YUY2 | (this->hw ? this->hw->driver_capabilities : 0) | VO_CAP_CROP | VO_CAP_UNSCALED_OVERLAY | VO_CAP_CUSTOM_EXTENT_OVERLAY | VO_CAP_ARGB_LAYER_OVERLAY | /* VO_CAP_VIDEO_WINDOW_OVERLAY | */ VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE | VO_CAP_HUE | VO_CAP_SATURATION | VO_CAP_CONTRAST | VO_CAP_BRIGHTNESS | VO_CAP_GAMMA | VO_CAP_SHARPNESS; } static void opengl2_set_bicubic (void *this_gen, xine_cfg_entry_t *entry) { opengl2_driver_t *this = (opengl2_driver_t *)this_gen; int mode1 = !!entry->num_value; if ((this->bicubic.mode1 == mode1) || this->bicubic.mode_changing) return; this->bicubic.mode_changed = 1; this->bicubic.mode_changing = 1; this->bicubic.mode1 = mode1; this->bicubic.mode2 = mode1 ? SCALE_CATMULLROM : SCALE_LINEAR; this->bicubic.lut_y = _opengl2_lut_y[this->bicubic.mode2]; this->xine->config->update_num (this->xine->config, "video.output.opengl2_scale_mode", this->bicubic.mode2); this->bicubic.mode_changing = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": scale mode %s.\n", _opengl2_scale_names[this->bicubic.mode2]); } static void opengl2_set_scale_mode (void *this_gen, xine_cfg_entry_t *entry) { opengl2_driver_t *this = (opengl2_driver_t *)this_gen; opengl2_scale_t mode2 = entry->num_value; int mode1; if ((this->bicubic.mode2 == mode2) || this->bicubic.mode_changing) return; this->bicubic.mode_changed = 1; this->bicubic.mode_changing = 1; this->bicubic.mode2 = mode2; this->bicubic.lut_y = _opengl2_lut_y[this->bicubic.mode2]; mode1 = mode2 <= SCALE_LINEAR ? 0 : 1; if (mode1 != this->bicubic.mode1) { this->bicubic.mode1 = mode1; this->xine->config->update_num (this->xine->config, "video.output.opengl2_bicubic_scaling", mode1); } this->bicubic.mode_changing = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": scale mode %s.\n", _opengl2_scale_names[this->bicubic.mode2]); } static void opengl2_dispose (vo_driver_t *this_gen) { opengl2_driver_t *this = (opengl2_driver_t *) this_gen; opengl2_exit_unregister (this); opengl2_free_log_buf (this); if (this->glconv) this->glconv->destroy(&this->glconv); if (this->hw) this->hw->destroy(&this->hw); /* cm_close already does this. this->xine->config->unregister_callbacks (this->xine->config, "video.output.opengl2_bicubic_scaling", NULL, this, sizeof (*this)); */ cm_close (this); _x_vo_scale_cleanup (&this->sc, this->xine->config); pthread_mutex_destroy(&this->drawable_lock); this->gl->make_current(this->gl); { unsigned int u; for (u = 1; u < OGL2_cscs_LAST; u++) opengl2_delete_program (&this->csc_shaders[u]); } opengl2_delete_program (&this->sharp.program); opengl2_delete_program (&this->bicubic.pass1_program); opengl2_delete_program (&this->bicubic.pass2_program); if (this->bicubic.fbo) glDeleteFramebuffers (1, &this->bicubic.fbo); glDeleteTextures (OGL2_TEX_LAST, this->tex); if ( this->fbo ) glDeleteFramebuffers( 1, &this->fbo ); if (this->PBO[0]) glDeleteBuffers (sizeof (this->PBO) / sizeof (this->PBO[0]), this->PBO); glDeleteTextures (XINE_VORAW_MAX_OVL, this->overlay_tex); this->gl->release_current(this->gl); this->gl->dispose(&this->gl); free (this); } static vo_frame_t *opengl2_alloc_frame (vo_driver_t *this_gen) { opengl2_driver_t *this = (opengl2_driver_t *)this_gen; vo_frame_t *frame; if (this->hw) { mem_frame_t *mem_frame = this->hw->alloc_frame(this->hw); if (mem_frame) { return &mem_frame->vo_frame; } return NULL; } frame = mem_frame_alloc_frame (&this->vo_driver); if (frame) frame->accel_data = &this->accel; return frame; } static vo_driver_t *opengl2_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { opengl2_class_t *class = (opengl2_class_t *)class_gen; opengl2_driver_t *this; config_values_t *config = class->xine->config; this = calloc (1, sizeof (*this)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->log = NULL; this->lsize = 0; this->last_csc_shader = OGL2_cscs_NONE; this->hue = 0; this->brightness = 0; this->gamma.value = 0; this->sharp.value = 0; this->transform.flags = 0; this->transform.changed = 0; this->sharp.program.compiled = 0; this->bicubic.pass1_program.compiled = 0; this->bicubic.pass2_program.compiled = 0; this->bicubic.pass1_tex_w = 0; this->bicubic.pass1_tex_h = 0; this->bicubic.fbo = 0; this->bicubic.mode_changed = 0; this->bicubic.mode_changing = 0; this->ovl.changed = 0; this->ovl.num = 0; { int32_t i; for (i = 0; i < OGL2_TEX_LAST; i++) this->tex[i] = 0; for (i = 0; i < XINE_VORAW_MAX_OVL + 1; i++) this->overlay_tex[i] = 0; } this->yuvtex.width = 0; this->yuvtex.height = 0; this->yuvtex.bytes_per_pixel = 0; this->fbo = 0; this->PBO[0] = 0; this->PBO[1] = 0; this->PBO[2] = 0; { int i; for (i = 0; i < XINE_VORAW_MAX_OVL; ++i) { this->ovl.buf[i].ovl_w = this->ovl.buf[i].ovl_h = 0; this->ovl.buf[i].ovl_x = this->ovl.buf[i].ovl_y = 0; this->ovl.buf[i].unscaled = 0; this->ovl.buf[i].tex_w = this->ovl.buf[i].tex_h = 0; } } #endif this->bicubic.flags = ~0; this->ovl.blend = _opengl2_overlay_dummy_blend; this->ovl.end = _opengl2_overlay_dummy_end; this->vtex.index = 1; this->gl = _x_load_gl (class->xine, class->visual_type, visual_gen, XINE_GL_API_OPENGL); if (this->gl) { { /* TJ. If X server link gets lost, our next render attempt will fire the * Xlib fatal error handler -> exit () -> opengl2_exit () with drawable_lock held. * opengl2_display_frame () does quite a lot anyway so the "recursive mutex" * performance drop should not matter. */ pthread_mutexattr_t attr; pthread_mutexattr_init (&attr); pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&this->drawable_lock, &attr); pthread_mutexattr_destroy (&attr); } _x_vo_scale_init (&this->sc, 1, 0, config); this->accel.lock = opengl2_accel_lock; if (class->visual_type == XINE_VISUAL_TYPE_X11) { const x11_visual_t *visual = (const x11_visual_t *)visual_gen; this->sc.frame_output_cb = visual->frame_output_cb; this->sc.dest_size_cb = visual->dest_size_cb; this->sc.user_data = visual->user_data; this->accel.display = visual->display; this->accel.disp_type = VO_DISP_TYPE_X11; } else /* class->visual_type == XINE_VISUAL_TYPE_WAYLAND) */ { const xine_wayland_visual_t *visual = (const xine_wayland_visual_t *)visual_gen; this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; this->accel.display = visual->display; this->accel.disp_type = VO_DISP_TYPE_WAYLAND; } this->sc.user_ratio = XINE_VO_ASPECT_AUTO; this->zoom_x = 100; this->zoom_y = 100; this->xine = class->xine; this->config = config; this->vo_driver.get_capabilities = opengl2_get_capabilities; this->vo_driver.alloc_frame = opengl2_alloc_frame; this->vo_driver.update_frame_format = mem_frame_update_frame_format; this->vo_driver.overlay_begin = opengl2_overlay_begin; this->vo_driver.overlay_blend = opengl2_overlay_blend; this->vo_driver.overlay_end = opengl2_overlay_end; this->vo_driver.display_frame = opengl2_display_frame; this->vo_driver.get_property = opengl2_get_property; this->vo_driver.set_property = opengl2_set_property; this->vo_driver.get_property_min_max = opengl2_get_property_min_max; this->vo_driver.gui_data_exchange = opengl2_gui_data_exchange; this->vo_driver.dispose = opengl2_dispose; this->vo_driver.redraw_needed = opengl2_redraw_needed; if (!this->gl->make_current (this->gl)) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": display unavailable for initialization.\n"); } else { { GLint v[1] = {0}; glGetIntegerv (GL_MAX_TEXTURE_SIZE, v); if (v[0] > 0) { this->max_video_width = this->max_video_height = v[0]; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": max video size %dx%d.\n", this->max_video_width, this->max_video_height); } } { GLint v[2] = {0, 0}; glGetIntegerv (GL_MAX_VIEWPORT_DIMS, v); if (v[0] > 0) { this->max_display_width = v[0]; this->max_display_height = v[1] > 0 ? v[1] : v[0]; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": max output size %dx%d.\n", this->max_display_width, this->max_display_height); } } glClearColor (0.0f, 0.0f, 0.0f, 0.0f); glClearDepth (1.0f); glDepthFunc (GL_LEQUAL); glDisable (GL_DEPTH_TEST); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable (GL_BLEND); glShadeModel (GL_SMOOTH); glEnable (GL_TEXTURE_RECTANGLE_ARB); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); this->texture_float = class->texture_float; this->fmt_1p = class->texture_rg ? GL_RED : GL_LUMINANCE; this->fmt_2p = class->texture_rg ? GL_RG : GL_LUMINANCE_ALPHA; #define INITWIDTH 720 #define INITHEIGHT 576 do { char buf[1024]; const char p2_swizzle = (this->fmt_2p == GL_RG) ? 'g' : 'a'; uint32_t u; if (!opengl2_check_textures_size (this, INITWIDTH, INITHEIGHT, 8)) break; if (!opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv420], yuv420_frag, "yuv420_frag", yuv420_args)) break; opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv420g], yuv420g_frag, "yuv420g_frag", yuv420g_args); if (!opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv420j], yuv420j_frag, "yuv420j_frag", yuv420j_args)) break; opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv420jg], yuv420jg_frag, "yuv420jg_frag", yuv420jg_args); memcpy (buf, yuv420j16_frag, sizeof (yuv420j16_frag)); u = strchr (yuv420j16_frag, '$') - yuv420j16_frag; buf[u] = p2_swizzle; u = strchr (yuv420j16_frag + u + 1, '$') - yuv420j16_frag; buf[u] = p2_swizzle; u = strchr (yuv420j16_frag + u + 1, '$') - yuv420j16_frag; buf[u] = p2_swizzle; if (!opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv420j16], buf, "yuv420j16_frag", yuv420j16_args)) break; memcpy (buf, yuv420j16g_frag, sizeof (yuv420j16g_frag)); u = strchr (yuv420j16g_frag, '$') - yuv420j16g_frag; buf[u] = p2_swizzle; u = strchr (yuv420j16g_frag + u + 1, '$') - yuv420j16g_frag; buf[u] = p2_swizzle; u = strchr (yuv420j16g_frag + u + 1, '$') - yuv420j16g_frag; buf[u] = p2_swizzle; opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv420j16g], buf, "yuv420j16g_frag", yuv420j16g_args); memcpy (buf, nv12_frag, sizeof (nv12_frag)); /* gcc sees these "u" really are compile time constants :-)) */ u = strchr (nv12_frag, '$') - nv12_frag; buf[u] = p2_swizzle; if (!opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_nv12], buf, "nv12_frag", nv12_args)) break; memcpy (buf, nv12g_frag, sizeof (nv12g_frag)); u = strchr (nv12g_frag, '$') - nv12g_frag; buf[u] = p2_swizzle; opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_nv12g], buf, "nv12g_frag", nv12g_args); memcpy (buf, yuv422_frag, sizeof (yuv422_frag)); u = strchr (yuv422_frag, '$') - yuv422_frag; buf[u] = p2_swizzle; u = strchr (yuv422_frag + u + 1, '$') - yuv422_frag; buf[u] = p2_swizzle; if (!opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv422], buf, "yuv422_frag", yuv422_args)) break; memcpy (buf, yuv422g_frag, sizeof (yuv422g_frag)); u = strchr (yuv422g_frag, '$') - yuv422g_frag; buf[u] = p2_swizzle; u = strchr (yuv422g_frag + u + 1, '$') - yuv422g_frag; buf[u] = p2_swizzle; opengl2_build_program (this, &this->csc_shaders[OGL2_cscs_yuv422g], buf, "yuv422g_frag", yuv422g_args); this->gl->release_current (this->gl); opengl2_free_log_buf (this); this->update_csc = 1; this->color_standard = 10; this->saturation = 128; this->contrast = 128; cm_init (this); /* force initial debug message */ this->gamma.changed = 1; this->sharp.changed = 1; { opengl2_scale_t scale_max; if (this->texture_float) { scale_max = SCALE_LAST - 1; this->bicubic.mode1 = config->register_bool (config, "video.output.opengl2_bicubic_scaling", 0, _("opengl2: use a bicubic algo to scale the video"), _("Set to true if you want bicubic scaling.\n\n"), 10, opengl2_set_bicubic, this); } else { scale_max = SCALE_LINEAR; this->bicubic.mode1 = 0; } this->bicubic.mode2 = config->register_range (config, "video.output.opengl2_scale_mode", SCALE_LINEAR, 0, scale_max, _("opengl2: video scale mode"), _("0: Simple. Very fast, very sharp,\n" " but also stairsteps, uneven lines, and flickering movement.\n\n" "1: Linear blending. Fast, very smooth, but also a bit blurry.\n\n" "2: Catmullrom blending. Very smooth, sharp, but needs fast hardware.\n\n" "3: Cosinus blending. Smooth, very sharp, but needs fast hardware.\n"), 10, opengl2_set_scale_mode, this); if (this->bicubic.mode2 == SCALE_LINEAR) { if (this->bicubic.mode1) { this->bicubic.mode_changing = 1; this->bicubic.mode2 = SCALE_CATMULLROM; config->update_num (config, "video.output.opengl2_scale_mode", this->bicubic.mode2); this->bicubic.mode_changing = 0; } } else { int mode1 = this->bicubic.mode2 <= SCALE_LINEAR ? 0 : 1; if (this->bicubic.mode1 != mode1) { this->bicubic.mode_changing = 1; this->bicubic.mode1 = mode1; config->update_num (config, "video.output.opengl2_bicubic_scaling", mode1); this->bicubic.mode_changing = 0; } } this->bicubic.lut_y = _opengl2_lut_y[this->bicubic.mode2]; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": scale mode %s.\n", _opengl2_scale_names[this->bicubic.mode2]); } this->hw = _x_hwdec_new(this->xine, &this->vo_driver, class->visual_type, visual_gen, 0); if (this->hw) { this->glconv = this->hw->opengl_interop(this->hw, this->gl); if (!this->glconv) this->hw->destroy(&this->hw); else this->vo_driver.update_frame_format = this->hw->update_frame_format; } xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "%s hardware decoding.\n", this->hw ? "Enabled" : "Not using"); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": initialized.\n"); return &this->vo_driver; } while (0); this->gl->release_current (this->gl); } pthread_mutex_destroy (&this->drawable_lock); this->gl->dispose (&this->gl); } free (this); return NULL; } static uint32_t opengl2_check_platform (xine_t *xine, unsigned visual_type, const void *visual) { xine_gl_t *gl; uint32_t result = 0; gl = _x_load_gl (xine, visual_type, visual, XINE_GL_API_OPENGL); if (!gl) return 0; if (gl->make_current (gl)) { xine_gl_extensions_t extensions; const char *names = (const char *)glGetString (GL_EXTENSIONS); xine_gl_extensions_load (&extensions, names); result = xine_gl_extensions_test (&extensions, "GL_ARB_texture_float") ? 2 : 0; result |= xine_gl_extensions_test (&extensions, "GL_ARB_texture_rg") ? 4 : 0; if (xine_gl_extensions_test (&extensions, "GL_ARB_texture_rectangle") && xine_gl_extensions_test (&extensions, "GL_ARB_texture_non_power_of_two") && xine_gl_extensions_test (&extensions, "GL_ARB_pixel_buffer_object") && xine_gl_extensions_test (&extensions, "GL_ARB_framebuffer_object") && xine_gl_extensions_test (&extensions, "GL_ARB_fragment_shader") && xine_gl_extensions_test (&extensions, "GL_ARB_vertex_shader")) result |= 1; gl->release_current (gl); xine_gl_extensions_unload (&extensions); } gl->dispose (&gl); return result; } /* * class functions */ static void *opengl2_init_class( xine_t *xine, unsigned visual_type, const void *visual_gen ) { opengl2_class_t *this; uint32_t ext = opengl2_check_platform (xine, visual_type, visual_gen); if (!(ext & 1)) return NULL; this = calloc (1, sizeof (*this)); if (!this) return NULL; this->driver_class.open_plugin = opengl2_open_plugin; this->driver_class.identifier = "opengl2"; this->driver_class.description = N_("xine video output plugin using opengl 2.0"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; this->visual_type = visual_type; this->texture_float = !!(ext & 2); this->texture_rg = !!(ext & 4); return this; } static void *opengl2_init_class_x11 (xine_t *xine, const void *visual_gen) { return opengl2_init_class (xine, XINE_VISUAL_TYPE_X11, visual_gen); } static void *opengl2_init_class_wl (xine_t *xine, const void *visual_gen) { return opengl2_init_class (xine, XINE_VISUAL_TYPE_WAYLAND, visual_gen); } static const vo_info_t vo_info_opengl2 = { .priority = 8, .visual_type = XINE_VISUAL_TYPE_X11, }; static const vo_info_t vo_info_opengl2_wl = { .priority = 8, .visual_type = XINE_VISUAL_TYPE_WAYLAND, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "opengl2", XINE_VERSION_CODE, &vo_info_opengl2, opengl2_init_class_x11 }, { PLUGIN_VIDEO_OUT, 22, "opengl2", XINE_VERSION_CODE, &vo_info_opengl2_wl, opengl2_init_class_wl }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_xcbshm.c0000644000175000017500000012522414647725152017163 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_xcbshm.c, X11 shared memory extension interface for xine * * based on mpeg2dec code from * Aaron Holtzman * * xine-specific code by Guenter Bartsch * * ported to xcb by Christoph Pfister - Feb 2007 * * fullrange/HD color and crop support added by Torsten Jager */ #define LOG_MODULE "video_out_xcbshm" #define LOG_VERBOSE /* #define LOG */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "xine.h" #include #include #include #include #include #include #include #include #include #include "yuv2rgb.h" #include #include #include "xcbosd.h" #include "xine_mmx.h" typedef struct { vo_frame_t vo_frame; /* frame properties as delivered by the decoder: */ /* obs: for width/height use vo_scale_t struct */ int format; int flags; vo_scale_t sc; uint8_t *image; int bytes_per_line; xcb_shm_seg_t shmseg; yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */ uint8_t *rgb_dst; int state, offs0, offs1; /* crop helpers */ uint8_t *crop_start, *crop_flush, *crop_stop; } xshm_frame_t; /* frame.state */ #define FS_DONE 1 #define FS_LATE 2 #define FS_FLAGS 4 typedef struct { vo_driver_t vo_driver; /* xcb / shm related stuff */ xcb_connection_t *connection; xcb_screen_t *screen; xcb_window_t window; xcb_gcontext_t gc; int depth; int bpp; int scanline_pad; int use_shm; int brightness; int contrast; int saturation; uint8_t *yuv2rgb_cmap; yuv2rgb_factory_t *yuv2rgb_factory; /* color matrix switching */ int cm_active, cm_state; uint8_t cm_lut[32]; vo_scale_t sc; xshm_frame_t *cur_frame; xcbosd *xoverlay; int ovl_changed; xine_t *xine; alphablend_t alphablend_extra_data; pthread_mutex_t main_mutex; } xshm_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } xshm_class_t; /* import common color matrix stuff */ #define CM_LUT #define CM_DRIVER_T xshm_driver_t #include "color_matrix.c" /* * allocate an XImage, try XShm first but fall back to * plain X11 if XShm should fail */ static void create_ximage(xshm_driver_t *this, xshm_frame_t *frame, int width, int height) { frame->bytes_per_line = ((this->bpp * width + this->scanline_pad - 1) & (~(this->scanline_pad - 1))) >> 3; if (this->use_shm) { int shmid; xcb_void_cookie_t shm_attach_cookie; xcb_generic_error_t *generic_error; /* * try shm */ shmid = shmget(IPC_PRIVATE, frame->bytes_per_line * height, IPC_CREAT | 0777); if (shmid < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: %s: allocating image\n"), LOG_MODULE, strerror(errno)); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); goto shm_fail1; } frame->image = shmat(shmid, 0, 0); if (frame->image == ((void *) -1)) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: shared memory error (address error) when allocating image \n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); goto shm_fail2; } frame->shmseg = xcb_generate_id(this->connection); shm_attach_cookie = xcb_shm_attach_checked(this->connection, frame->shmseg, shmid, 0); generic_error = xcb_request_check(this->connection, shm_attach_cookie); if (generic_error != NULL) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: x11 error during shared memory XImage creation\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); free(generic_error); goto shm_fail3; } /* * Now that the Xserver has learned about and attached to the * shared memory segment, delete it. It's actually deleted by * the kernel when all users of that segment have detached from * it. Gives an automatic shared memory cleanup in case we crash. */ shmctl(shmid, IPC_RMID, 0); return; shm_fail3: frame->shmseg = 0; shmdt(frame->image); shm_fail2: shmctl(shmid, IPC_RMID, 0); shm_fail1: this->use_shm = 0; } /* * fall back to plain X11 if necessary */ frame->image = malloc(frame->bytes_per_line * height); } static void dispose_ximage(xshm_driver_t *this, xshm_frame_t *frame) { if (frame->shmseg) { xcb_shm_detach(this->connection, frame->shmseg); frame->shmseg = 0; shmdt(frame->image); } else free(frame->image); frame->image = NULL; } /* * and now, the driver functions */ static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; uint32_t capabilities = VO_CAP_CROP | VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE; if( this->xoverlay ) capabilities |= VO_CAP_UNSCALED_OVERLAY; return capabilities; } static void xshm_compute_ideal_size (xshm_driver_t *this, xshm_frame_t *frame) { (void)this; _x_vo_scale_compute_ideal_size (&frame->sc); } static void xshm_compute_rgb_size (xshm_driver_t *this, xshm_frame_t *frame) { (void)this; _x_vo_scale_compute_output_size (&frame->sc); /* avoid problems in yuv2rgb */ if (frame->sc.output_height < 1) frame->sc.output_height = 1; if (frame->sc.output_width < 8) frame->sc.output_width = 8; if (frame->sc.output_width & 1) /* yuv2rgb_mlib needs an even YUV2 width */ frame->sc.output_width++; lprintf("frame source (%d) %d x %d => screen output %d x %d%s\n", frame->vo_frame.id, frame->sc.delivered_width, frame->sc.delivered_height, frame->sc.output_width, frame->sc.output_height, ( frame->sc.delivered_width != frame->sc.output_width || frame->sc.delivered_height != frame->sc.output_height ? ", software scaling" : "" ) ); } static void xshm_frame_field (vo_frame_t *vo_img, int which_field) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; switch (which_field) { case VO_BOTH_FIELDS: case VO_TOP_FIELD: frame->rgb_dst = (uint8_t *)frame->image; break; case VO_BOTTOM_FIELD: frame->rgb_dst = (uint8_t *)frame->image + frame->bytes_per_line ; break; } frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL); } static void xshm_frame_proc_setup (vo_frame_t *vo_img) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; int changed = 0, i; int width, height, gui_width, gui_height; double gui_pixel_aspect; /* Aargh... libmpeg2 decoder calls frame->proc_slice directly, preferredly while still in mmx mode. This will trash our floating point aspect ratio calculations below. Switching back once per frame should not harm performance too much. */ #ifdef HAVE_MMX emms (); #endif if (!(frame->state & FS_LATE)) { /* adjust cropping to what yuv2rgb can handle */ if (vo_img->format == XINE_IMGFMT_YV12) { vo_img->crop_left &= ~7; vo_img->crop_top &= ~1; } else { vo_img->crop_left &= ~3; } /* check for crop changes */ if ((vo_img->crop_left != frame->sc.crop_left) || (vo_img->crop_top != frame->sc.crop_top) || (vo_img->crop_right != frame->sc.crop_right) || (vo_img->crop_bottom != frame->sc.crop_bottom)) { frame->sc.crop_left = vo_img->crop_left; frame->sc.crop_top = vo_img->crop_top; frame->sc.crop_right = vo_img->crop_right; frame->sc.crop_bottom = vo_img->crop_bottom; changed = 1; } } if (!(frame->state & FS_DONE)) changed = 1; /* just deal with cropped part */ width = frame->sc.delivered_width - frame->sc.crop_left - frame->sc.crop_right; height = frame->sc.delivered_height - frame->sc.crop_top - frame->sc.crop_bottom; if (frame->sc.delivered_ratio == 0.0) { frame->sc.delivered_ratio = height ? (double)width / (double)height : 1.0; changed = 1; } /* ask gui what output size we'll have for this frame */ /* get the gui_pixel_aspect before calling xshm_compute_ideal_size() */ /* note: gui_width and gui_height may be bogus because we may have not yet */ /* updated video_pixel_aspect (see _x_vo_scale_compute_ideal_size). */ frame->sc.dest_size_cb (frame->sc.user_data, width, height, frame->sc.video_pixel_aspect, &gui_width, &gui_height, &gui_pixel_aspect); if (changed || (gui_pixel_aspect != frame->sc.gui_pixel_aspect) || (this->sc.user_ratio != frame->sc.user_ratio)) { frame->sc.gui_pixel_aspect = gui_pixel_aspect; frame->sc.user_ratio = this->sc.user_ratio; xshm_compute_ideal_size (this, frame); /* now we have updated video_aspect_pixel we use the callback */ /* again to obtain the correct gui_width and gui_height values. */ frame->sc.dest_size_cb (frame->sc.user_data, width, height, frame->sc.video_pixel_aspect, &gui_width, &gui_height, &gui_pixel_aspect); changed = 1; } if (changed || (frame->sc.gui_width != gui_width) || (frame->sc.gui_height != gui_height)) { int w = frame->sc.output_width, h = frame->sc.output_height; frame->sc.gui_width = gui_width; frame->sc.gui_height = gui_height; xshm_compute_rgb_size (this, frame); if (!frame->image || (w != frame->sc.output_width) || (h != frame->sc.output_height)) { /* (re)allocate XImage */ pthread_mutex_lock(&this->main_mutex); if (frame->image) dispose_ximage (this, frame); create_ximage (this, frame, frame->sc.output_width, frame->sc.output_height); pthread_mutex_unlock(&this->main_mutex); } changed = 1; } if (changed || !(frame->state & FS_FLAGS)) { /* set up colorspace converter */ switch (vo_img->flags & VO_BOTH_FIELDS) { case VO_TOP_FIELD: case VO_BOTTOM_FIELD: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, 2 * frame->vo_frame.pitches[0], 2 * frame->vo_frame.pitches[1], frame->sc.output_width, frame->sc.output_height, frame->bytes_per_line * 2); break; case VO_BOTH_FIELDS: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, frame->vo_frame.pitches[0], frame->vo_frame.pitches[1], frame->sc.output_width, frame->sc.output_height, frame->bytes_per_line); break; } } frame->state |= FS_FLAGS | FS_DONE; xshm_frame_field (vo_img, vo_img->flags & VO_BOTH_FIELDS); /* cache helpers */ i = frame->sc.crop_top & 15; if (i) i -= 16; if (vo_img->format == XINE_IMGFMT_YV12) { frame->offs0 = i * vo_img->pitches[0] + frame->sc.crop_left; frame->offs1 = (i * vo_img->pitches[1] + frame->sc.crop_left) / 2; } else { frame->offs0 = i * vo_img->pitches[0] + frame->sc.crop_left * 2; } frame->crop_start = vo_img->base[0] + frame->sc.crop_top * vo_img->pitches[0]; frame->crop_flush = frame->crop_stop = vo_img->base[0] + (frame->sc.delivered_height - frame->sc.crop_bottom) * vo_img->pitches[0]; if (i + frame->sc.crop_bottom < 0) frame->crop_flush -= 16 * vo_img->pitches[0]; /* switch color matrix/range */ i = cm_from_frame (vo_img); if (i != this->cm_active) { this->cm_active = i; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->brightness, this->contrast, this->saturation, i); xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_xcbshm: b %d c %d s %d [%s]\n", this->brightness, this->contrast, this->saturation, cm_names[i]); } } static void xshm_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; uint8_t *src0; /* delayed setup */ if (!vo_img->proc_called) { xshm_frame_proc_setup (vo_img); vo_img->proc_called = 1; } src0 = src[0] + frame->offs0; if ((src0 < frame->crop_start) || (src0 >= frame->crop_stop)) return; lprintf ("copy... (format %d)\n", frame->format); if (vo_img->format == XINE_IMGFMT_YV12) frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0, src[1] + frame->offs1, src[2] + frame->offs1); else frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0); if (src0 >= frame->crop_flush) { if (vo_img->format == XINE_IMGFMT_YV12) { frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0 + 16 * vo_img->pitches[0], src[1] + frame->offs1 + 8 * vo_img->pitches[1], src[2] + frame->offs1 + 8 * vo_img->pitches[2]); } else { frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0 + 16 * vo_img->pitches[0]); } } lprintf ("copy...done\n"); } static void xshm_frame_dispose (vo_frame_t *vo_img) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; if (frame->image) { pthread_mutex_lock(&this->main_mutex); dispose_ximage(this, frame); pthread_mutex_unlock(&this->main_mutex); } frame->yuv2rgb->dispose (frame->yuv2rgb); xine_free_aligned (frame->vo_frame.base[0]); xine_free_aligned (frame->vo_frame.base[1]); xine_free_aligned (frame->vo_frame.base[2]); pthread_mutex_destroy (&frame->vo_frame.mutex); free (frame); } static vo_frame_t *xshm_alloc_frame (vo_driver_t *this_gen) { xshm_frame_t *frame; xshm_driver_t *this = (xshm_driver_t *) this_gen; frame = (xshm_frame_t *) calloc(1, sizeof(xshm_frame_t)); if (!frame) return NULL; /* * colorspace converter for this frame */ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory); if (!frame->yuv2rgb) { free(frame); return NULL; } memcpy (&frame->sc, &this->sc, sizeof(vo_scale_t)); pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions/fields */ frame->vo_frame.proc_slice = xshm_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = xshm_frame_field; frame->vo_frame.dispose = xshm_frame_dispose; frame->vo_frame.driver = this_gen; return (vo_frame_t *) frame; } static void xshm_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { xshm_frame_t *frame = (xshm_frame_t *) frame_gen; int j, y_pitch, uv_pitch; (void)this_gen; flags &= VO_BOTH_FIELDS; /* (re)allocate yuv buffers */ if (((int)width != frame->sc.delivered_width) || ((int)height != frame->sc.delivered_height) || (format != frame->format)) { frame->sc.delivered_width = width; frame->sc.delivered_height = height; frame->format = format; xine_freep_aligned(&frame->vo_frame.base[0]); xine_freep_aligned(&frame->vo_frame.base[1]); xine_freep_aligned(&frame->vo_frame.base[2]); /* bottom black pad for certain crop_top > crop_bottom cases */ if (format == XINE_IMGFMT_YV12) { y_pitch = (width + 7) & ~7; frame->vo_frame.pitches[0] = y_pitch; frame->vo_frame.base[0] = xine_malloc_aligned (y_pitch * (height + 16)); uv_pitch = ((width + 15) & ~15) >> 1; frame->vo_frame.pitches[1] = uv_pitch; frame->vo_frame.pitches[2] = uv_pitch; frame->vo_frame.base[1] = xine_malloc_aligned (uv_pitch * ((height + 17) / 2)); frame->vo_frame.base[2] = xine_malloc_aligned (uv_pitch * ((height + 17) / 2)); if (!frame->vo_frame.base[0] || !frame->vo_frame.base[1] || !frame->vo_frame.base[2]) { xine_freep_aligned (&frame->vo_frame.base[0]); xine_freep_aligned (&frame->vo_frame.base[1]); xine_freep_aligned (&frame->vo_frame.base[2]); frame->sc.delivered_width = 0; frame->vo_frame.width = 0; } else { memset (frame->vo_frame.base[0], 0, y_pitch * (height + 16)); memset (frame->vo_frame.base[1], 128, uv_pitch * (height + 16) / 2); memset (frame->vo_frame.base[2], 128, uv_pitch * (height + 16) / 2); } } else { y_pitch = ((width + 3) & ~3) << 1; frame->vo_frame.pitches[0] = y_pitch; frame->vo_frame.base[0] = xine_malloc_aligned (y_pitch * (height + 16)); if (frame->vo_frame.base[0]) { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)frame->vo_frame.base[0]; for (j = y_pitch * (height + 16) / 4; j > 0; j--) *q++ = black.word; } else { frame->sc.delivered_width = 0; frame->vo_frame.width = 0; } } /* defer the rest to xshm_frame_proc_setup () */ frame->state &= ~(FS_DONE | FS_LATE); } if (!isnan (ratio) && (ratio < 1000.0) && (ratio > 0.001) && (ratio != frame->sc.delivered_ratio)) { frame->sc.delivered_ratio = ratio; frame->state &= ~FS_DONE; } if (flags != frame->flags) { frame->flags = flags; frame->state &= ~FS_FLAGS; } } static void xshm_overlay_clut_yuv2rgb(xshm_driver_t *this, vo_overlay_t *overlay, xshm_frame_t *frame) { int i; uint32_t *rgb; (void)this; if (!overlay->rgb_clut) { rgb = overlay->color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->rgb_clut++; } if (!overlay->hili_rgb_clut) { rgb = overlay->hili_color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->hili_rgb_clut++; } } static void xshm_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { xshm_driver_t *this = (xshm_driver_t *) this_gen; this->ovl_changed += changed; if( this->ovl_changed && this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_clear(this->xoverlay); pthread_mutex_unlock(&this->main_mutex); } this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void xshm_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { xshm_driver_t *this = (xshm_driver_t *) this_gen; (void)vo_img; if( this->ovl_changed && this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_expose(this->xoverlay); pthread_mutex_unlock(&this->main_mutex); } this->ovl_changed = 0; } static void xshm_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { xshm_driver_t *this = (xshm_driver_t *) this_gen; xshm_frame_t *frame = (xshm_frame_t *) frame_gen; int width = frame->sc.delivered_width - frame->sc.crop_left - frame->sc.crop_right; int height = frame->sc.delivered_height - frame->sc.crop_top - frame->sc.crop_bottom; /* Alpha Blend here */ if (overlay->rle) { if( overlay->unscaled ) { if( this->ovl_changed && this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_blend(this->xoverlay, overlay); pthread_mutex_unlock(&this->main_mutex); } } else { if (!overlay->rgb_clut || !overlay->hili_rgb_clut) xshm_overlay_clut_yuv2rgb (this, overlay, frame); switch (this->bpp) { case 16: _x_blend_rgb16(frame->image, overlay, frame->sc.output_width, frame->sc.output_height, width, height, &this->alphablend_extra_data); break; case 24: _x_blend_rgb24(frame->image, overlay, frame->sc.output_width, frame->sc.output_height, width, height, &this->alphablend_extra_data); break; case 32: _x_blend_rgb32(frame->image, overlay, frame->sc.output_width, frame->sc.output_height, width, height, &this->alphablend_extra_data); break; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "xine-lib:video_out_xcbshm:xshm_overlay_blend: Cannot blend bpp:%i\n", this->bpp); /* it should never get here, unless a user tries to play in bpp:8 */ break; } } } } static void clean_output_area (xshm_driver_t *this, xshm_frame_t *frame) { int i; xcb_rectangle_t rects[4]; int rects_count = 0; memcpy( this->sc.border, frame->sc.border, sizeof(this->sc.border) ); pthread_mutex_lock(&this->main_mutex); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { rects[rects_count].x = this->sc.border[i].x; rects[rects_count].y = this->sc.border[i].y; rects[rects_count].width = this->sc.border[i].w; rects[rects_count].height = this->sc.border[i].h; rects_count++; } } if (rects_count > 0) xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); if (this->xoverlay) { xcbosd_resize(this->xoverlay, this->sc.gui_width, this->sc.gui_height); this->ovl_changed = 1; } pthread_mutex_unlock(&this->main_mutex); } static int xshm_redraw_needed (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; int ret = 0; if( this->cur_frame ) { this->sc.delivered_height = this->cur_frame->sc.delivered_height; this->sc.delivered_width = this->cur_frame->sc.delivered_width; this->sc.video_pixel_aspect = this->cur_frame->sc.video_pixel_aspect; this->sc.crop_left = this->cur_frame->sc.crop_left; this->sc.crop_right = this->cur_frame->sc.crop_right; this->sc.crop_top = this->cur_frame->sc.crop_top; this->sc.crop_bottom = this->cur_frame->sc.crop_bottom; if( _x_vo_scale_redraw_needed( &this->sc ) ) { clean_output_area (this, this->cur_frame); ret = 1; } } else ret = 1; return ret; } static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; xshm_frame_t *frame = (xshm_frame_t *) frame_gen; lprintf ("display frame...\n"); lprintf ("about to draw frame (%d) %d x %d...\n", frame->vo_frame.id, frame->sc.output_width, frame->sc.output_height); /* * tell gui that we are about to display a frame, * ask for offset */ this->sc.delivered_height = frame->sc.delivered_height; this->sc.delivered_width = frame->sc.delivered_width; this->sc.video_pixel_aspect = frame->sc.video_pixel_aspect; this->sc.crop_left = frame->sc.crop_left; this->sc.crop_right = frame->sc.crop_right; this->sc.crop_top = frame->sc.crop_top; this->sc.crop_bottom = frame->sc.crop_bottom; if( _x_vo_scale_redraw_needed( &this->sc ) ) { clean_output_area (this, frame); } if (this->cur_frame) { if ( (this->cur_frame->sc.output_width != frame->sc.output_width) || (this->cur_frame->sc.output_height != frame->sc.output_height) || (this->cur_frame->sc.output_xoffset != frame->sc.output_xoffset) || (this->cur_frame->sc.output_yoffset != frame->sc.output_yoffset) ) clean_output_area (this, frame); this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); } this->cur_frame = frame; pthread_mutex_lock(&this->main_mutex); lprintf ("display locked...\n"); if (frame->shmseg) { lprintf ("put image (shm)\n"); xcb_shm_put_image(this->connection, this->window, this->gc, this->cur_frame->sc.output_width, this->cur_frame->sc.output_height, 0, 0, this->cur_frame->sc.output_width, this->cur_frame->sc.output_height, this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset, this->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, 0, this->cur_frame->shmseg, 0); } else { lprintf ("put image (plain/remote)\n"); xcb_put_image(this->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, this->window, this->gc, frame->sc.output_width, frame->sc.output_height, frame->sc.output_xoffset, frame->sc.output_yoffset, 0, this->depth, frame->bytes_per_line * frame->sc.output_height, frame->image); } xcb_flush(this->connection); pthread_mutex_unlock(&this->main_mutex); lprintf ("display frame done\n"); /* just in case somebody changes crop this late - take over for next time */ /* adjust cropping to what yuv2rgb can handle */ if (frame_gen->format == XINE_IMGFMT_YV12) { frame_gen->crop_left &= ~7; frame_gen->crop_top &= ~1; } else { frame_gen->crop_left &= ~3; } /* check for crop changes */ if ((frame_gen->crop_left != frame->sc.crop_left) || (frame_gen->crop_top != frame->sc.crop_top) || (frame_gen->crop_right != frame->sc.crop_right) || (frame_gen->crop_bottom != frame->sc.crop_bottom)) { frame->sc.crop_left = frame_gen->crop_left; frame->sc.crop_top = frame_gen->crop_top; frame->sc.crop_right = frame_gen->crop_right; frame->sc.crop_bottom = frame_gen->crop_bottom; frame->state &= ~FS_DONE; frame->state |= FS_LATE; } } static int xshm_get_property (vo_driver_t *this_gen, int property) { xshm_driver_t *this = (xshm_driver_t *) this_gen; switch (property) { case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; case VO_PROP_MAX_NUM_FRAMES: return 15; case VO_PROP_BRIGHTNESS: return this->brightness; case VO_PROP_CONTRAST: return this->contrast; case VO_PROP_SATURATION: return this->saturation; case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; case VO_PROP_OUTPUT_WIDTH: return this->cur_frame->sc.output_width; case VO_PROP_OUTPUT_HEIGHT: return this->cur_frame->sc.output_height; case VO_PROP_OUTPUT_XOFFSET: return this->cur_frame->sc.output_xoffset; case VO_PROP_OUTPUT_YOFFSET: return this->cur_frame->sc.output_yoffset; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": tried to get unsupported property %d\n", property); } return 0; } static int xshm_set_property (vo_driver_t *this_gen, int property, int value) { xshm_driver_t *this = (xshm_driver_t *) this_gen; switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) { value = 0; if (this->cur_frame) { this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); this->cur_frame = NULL; value = 1; } } break; case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); break; case VO_PROP_BRIGHTNESS: this->brightness = value; this->cm_active = 0; this->sc.force_redraw = 1; break; case VO_PROP_CONTRAST: this->contrast = value; this->cm_active = 0; this->sc.force_redraw = 1; break; case VO_PROP_SATURATION: this->saturation = value; this->cm_active = 0; this->sc.force_redraw = 1; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": tried to set unsupported property %d\n", property); } return value; } static void xshm_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { /* xshm_driver_t *this = (xshm_driver_t *) this_gen; */ (void)this_gen; if (property == VO_PROP_BRIGHTNESS) { *min = -128; *max = +127; } else if (property == VO_PROP_CONTRAST) { *min = 0; *max = 255; } else if (property == VO_PROP_SATURATION) { *min = 0; *max = 255; } else { *min = 0; *max = 0; } } static int xshm_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { xshm_driver_t *this = (xshm_driver_t *) this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: lprintf ("expose event\n"); if (this->cur_frame) { xcb_expose_event_t *xev = (xcb_expose_event_t *) data; if (xev && xev->count == 0) { int i; xcb_rectangle_t rects[4]; int rects_count = 0; pthread_mutex_lock(&this->main_mutex); if (this->cur_frame->shmseg) xcb_shm_put_image(this->connection, this->window, this->gc, this->cur_frame->sc.output_width, this->cur_frame->sc.output_height, 0, 0, this->cur_frame->sc.output_width, this->cur_frame->sc.output_height, this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset, this->depth, XCB_IMAGE_FORMAT_Z_PIXMAP, 0, this->cur_frame->shmseg, 0); else xcb_put_image(this->connection, XCB_IMAGE_FORMAT_Z_PIXMAP, this->window, this->gc, this->cur_frame->sc.output_width, this->cur_frame->sc.output_height, this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset, 0, this->depth, this->cur_frame->bytes_per_line * this->cur_frame->sc.output_height, this->cur_frame->image); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { rects[rects_count].x = this->sc.border[i].x; rects[rects_count].y = this->sc.border[i].y; rects[rects_count].width = this->sc.border[i].w; rects[rects_count].height = this->sc.border[i].h; rects_count++; } } if (rects_count > 0) xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); if(this->xoverlay) xcbosd_expose(this->xoverlay); xcb_flush(this->connection); pthread_mutex_unlock(&this->main_mutex); } } break; case XINE_GUI_SEND_DRAWABLE_CHANGED: this->window = (xcb_window_t) (long) data; pthread_mutex_lock(&this->main_mutex); xcb_free_gc(this->connection, this->gc); this->gc = xcb_generate_id(this->connection); xcb_create_gc(this->connection, this->gc, this->window, XCB_GC_FOREGROUND, &this->screen->black_pixel); if(this->xoverlay) xcbosd_drawable_changed(this->xoverlay, this->window); this->ovl_changed = 1; pthread_mutex_unlock(&this->main_mutex); break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: if (this->cur_frame) { x11_rectangle_t *rect = data; int x1, y1, x2, y2; _x_vo_scale_translate_gui2video(&this->cur_frame->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->cur_frame->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void xshm_dispose (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; if (this->cur_frame) this->cur_frame->vo_frame.dispose (&this->cur_frame->vo_frame); if (this->yuv2rgb_factory) this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); cm_close (this); _x_vo_scale_cleanup (&this->sc, this->xine->config); pthread_mutex_lock(&this->main_mutex); xcb_free_gc(this->connection, this->gc); pthread_mutex_unlock(&this->main_mutex); if( this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_destroy(this->xoverlay); pthread_mutex_unlock(&this->main_mutex); } pthread_mutex_destroy(&this->main_mutex); _x_alphablend_free(&this->alphablend_extra_data); free (this); } static int ImlibPaletteLUTGet(xshm_driver_t *this) { static const xcb_atom_t CARDINAL = 6; xcb_intern_atom_cookie_t atom_cookie; xcb_intern_atom_reply_t *atom_reply; xcb_get_property_cookie_t prop_cookie; xcb_get_property_reply_t *prop_reply; atom_cookie = xcb_intern_atom(this->connection, 0, sizeof("_IMLIB_COLORMAP"), "_IMLIB_COLORMAP"); atom_reply = xcb_intern_atom_reply(this->connection, atom_cookie, NULL); if (atom_reply == NULL) return 0; prop_cookie = xcb_get_property(this->connection, 0, this->window, atom_reply->atom, CARDINAL, 0, 0x7fffffff); prop_reply = xcb_get_property_reply(this->connection, prop_cookie, NULL); free(atom_reply); if (prop_reply == NULL) return 0; do { unsigned int i, j; int num_ret; uint8_t *retval; if (prop_reply->format != 8) break; num_ret = xcb_get_property_value_length (prop_reply); if (num_ret <= 0) break; retval = (uint8_t *)xcb_get_property_value (prop_reply); if (!retval) break; j = 1 + retval[0]*4; this->yuv2rgb_cmap = calloc(sizeof(uint8_t), 32 * 32 * 32); if (!this->yuv2rgb_cmap) break; for (i = 0; i < 32 * 32 * 32 && j < (unsigned int)num_ret; i++) { unsigned int d = 1 + 4 * retval[j++] + 3; if (d < (unsigned int)num_ret) this->yuv2rgb_cmap[i] = retval[d]; } free(prop_reply); return 1; } while (0); free(prop_reply); return 0; } /* TODO replace this with a string table. */ static const char *visual_class_name(xcb_visualtype_t *visual) { switch (visual->_class) { case XCB_VISUAL_CLASS_STATIC_GRAY: return "StaticGray"; case XCB_VISUAL_CLASS_GRAY_SCALE: return "GrayScale"; case XCB_VISUAL_CLASS_STATIC_COLOR: return "StaticColor"; case XCB_VISUAL_CLASS_PSEUDO_COLOR: return "PseudoColor"; case XCB_VISUAL_CLASS_TRUE_COLOR: return "TrueColor"; case XCB_VISUAL_CLASS_DIRECT_COLOR: return "DirectColor"; default: return "unknown visual class"; } } static vo_driver_t *xshm_open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { xshm_class_t *class = (xshm_class_t *) class_gen; config_values_t *config = class->xine->config; const xcb_visual_t *visual = (const xcb_visual_t *) visual_gen; xshm_driver_t *this; xcb_visualtype_t *visualtype; int mode; int swapped; int cpu_byte_order; int image_byte_order; xcb_get_window_attributes_cookie_t window_attrs_cookie; xcb_get_window_attributes_reply_t *window_attrs_reply; xcb_get_geometry_cookie_t geometry_cookie; xcb_get_geometry_reply_t *geometry_reply; const xcb_query_extension_reply_t *query_extension_reply; this = (xshm_driver_t *) calloc(1, sizeof(xshm_driver_t)); if (!this) return NULL; pthread_mutex_init(&this->main_mutex, NULL); _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->connection = visual->connection; this->screen = visual->screen; this->window = visual->window; _x_vo_scale_init( &this->sc, 0, 0, config ); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.dest_size_cb = visual->dest_size_cb; this->sc.user_data = visual->user_data; this->sc.user_ratio = XINE_VO_ASPECT_AUTO; this->cur_frame = NULL; this->gc = xcb_generate_id(this->connection); xcb_create_gc(this->connection, this->gc, this->window, XCB_GC_FOREGROUND, &this->screen->black_pixel); this->xoverlay = NULL; this->ovl_changed = 0; this->xine = class->xine; this->vo_driver.get_capabilities = xshm_get_capabilities; this->vo_driver.alloc_frame = xshm_alloc_frame; this->vo_driver.update_frame_format = xshm_update_frame_format; this->vo_driver.overlay_begin = xshm_overlay_begin; this->vo_driver.overlay_blend = xshm_overlay_blend; this->vo_driver.overlay_end = xshm_overlay_end; this->vo_driver.display_frame = xshm_display_frame; this->vo_driver.get_property = xshm_get_property; this->vo_driver.set_property = xshm_set_property; this->vo_driver.get_property_min_max = xshm_get_property_min_max; this->vo_driver.gui_data_exchange = xshm_gui_data_exchange; this->vo_driver.dispose = xshm_dispose; this->vo_driver.redraw_needed = xshm_redraw_needed; /* * * depth in X11 terminology land is the number of bits used to * actually represent the colour. * * bpp in X11 land means how many bits in the frame buffer per * pixel. * * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit * color is 24 bit depth, but can be 24 bpp or 32 bpp. */ window_attrs_cookie = xcb_get_window_attributes(this->connection, this->window); geometry_cookie = xcb_get_geometry(this->connection, this->window); xcb_prefetch_extension_data(this->connection, &xcb_shm_id); window_attrs_reply = xcb_get_window_attributes_reply(this->connection, window_attrs_cookie, NULL); visualtype = NULL; { xcb_depth_t *depth = xcb_screen_allowed_depths_iterator(this->screen).data; xcb_visualtype_t *vis = xcb_depth_visuals(depth); xcb_visualtype_t *vis_end = vis + xcb_depth_visuals_length(depth); for (; vis != vis_end; ++vis) if (window_attrs_reply->visual == vis->visual_id) { visualtype = vis; break; } } free(window_attrs_reply); if (!visualtype) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": visual type was not recognized\n"); xshm_dispose(&this->vo_driver); return NULL; } geometry_reply = xcb_get_geometry_reply(this->connection, geometry_cookie, NULL); this->depth = geometry_reply->depth; free(geometry_reply); if (this->depth>16) xprintf(this->xine, XINE_VERBOSITY_LOG, _("\n\nWARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n\n"), this->depth); /* * check for X shared memory support */ query_extension_reply = xcb_get_extension_data(this->connection, &xcb_shm_id); if (query_extension_reply && query_extension_reply->present) { this->use_shm = 1; } else { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: MIT shared memory extension not present on display.\n"), LOG_MODULE); this->use_shm = 0; } { const xcb_setup_t *setup = xcb_get_setup(this->connection); xcb_format_t *fmt = xcb_setup_pixmap_formats(setup); xcb_format_t *fmt_end = fmt + xcb_setup_pixmap_formats_length(setup); for (; fmt != fmt_end; ++fmt) if(fmt->depth == this->depth) { this->bpp = fmt->bits_per_pixel; this->scanline_pad = fmt->scanline_pad; break; } if (fmt == fmt_end) { if (this->depth <= 4) this->bpp = 4; else if (this->depth <= 8) this->bpp = 8; else if (this->depth <= 16) this->bpp = 16; else this->bpp = 32; this->scanline_pad = setup->bitmap_format_scanline_pad; } image_byte_order = setup->image_byte_order; } /* * Is the same byte order in use on the X11 client and server? */ cpu_byte_order = htonl(1) == 1 ? XCB_IMAGE_ORDER_MSB_FIRST : XCB_IMAGE_ORDER_LSB_FIRST; swapped = cpu_byte_order != image_byte_order; xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": video mode depth is %d (%d bpp), %s, %sswapped,\n" LOG_MODULE ": red: %08x, green: %08x, blue: %08x\n", this->depth, this->bpp, visual_class_name(visualtype), swapped ? "" : "not ", visualtype->red_mask, visualtype->green_mask, visualtype->blue_mask); mode = 0; switch (visualtype->_class) { case XCB_VISUAL_CLASS_TRUE_COLOR: switch (this->depth) { case 24: case 32: if (this->bpp == 32) { if (visualtype->red_mask == 0x00ff0000) mode = MODE_32_RGB; else mode = MODE_32_BGR; } else { if (visualtype->red_mask == 0x00ff0000) mode = MODE_24_RGB; else mode = MODE_24_BGR; } break; case 16: if (visualtype->red_mask == 0xf800) mode = MODE_16_RGB; else mode = MODE_16_BGR; break; case 15: if (visualtype->red_mask == 0x7C00) mode = MODE_15_RGB; else mode = MODE_15_BGR; break; case 8: if (visualtype->red_mask == 0xE0) mode = MODE_8_RGB; /* Solaris x86: RGB332 */ else mode = MODE_8_BGR; /* XFree86: BGR233 */ break; } break; case XCB_VISUAL_CLASS_STATIC_GRAY: if (this->depth == 8) mode = MODE_8_GRAY; break; case XCB_VISUAL_CLASS_PSEUDO_COLOR: case XCB_VISUAL_CLASS_GRAY_SCALE: if (this->depth <= 8 && ImlibPaletteLUTGet(this)) mode = MODE_PALETTE; break; } if (!mode) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("%s: your video mode was not recognized, sorry :-(\n"), LOG_MODULE); xshm_dispose(&this->vo_driver); return NULL; } cm_init (this); this->brightness = 0; this->contrast = 128; this->saturation = 128; this->yuv2rgb_factory = yuv2rgb_factory_init (mode, swapped, this->yuv2rgb_cmap); if (!this->yuv2rgb_factory) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": yuv2rgb initialization failed\n"); xshm_dispose(&this->vo_driver); return NULL; } this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen, this->window, XCBOSD_SHAPED); return &this->vo_driver; } /* * class functions */ static void *xshm_init_class (xine_t *xine, const void *visual_gen) { xshm_class_t *this; (void)visual_gen; this = calloc(1, sizeof(xshm_class_t)); if (!this) return NULL; this->driver_class.open_plugin = xshm_open_plugin; this->driver_class.identifier = "XShm"; this->driver_class.description = N_("xine video output plugin using the MIT X shared memory extension"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_xshm = { .priority = 6, .visual_type = XINE_VISUAL_TYPE_XCB, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "xshm", XINE_VERSION_CODE, &vo_info_xshm, xshm_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/xcbosd.h0000644000175000017500000000324414647725152015106 0ustar meme/* * Copyright (C) 2003-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xcbosd.h, use X11 Nonrectangular Window Shape Extension to draw xine OSD * * Nov 2003 - Miguel Freitas * Feb 2007 - ported to xcb by Christoph Pfister * * based on ideas and code of * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net) */ #ifndef XCBOSD_H #define XCBOSD_H #include typedef struct xcbosd xcbosd; enum xcbosd_mode {XCBOSD_SHAPED, XCBOSD_COLORKEY}; xcbosd *xcbosd_create(xine_t *xine, xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window, enum xcbosd_mode mode); void xcbosd_colorkey(xcbosd *osd, uint32_t colorkey, vo_scale_t *scaling); void xcbosd_destroy(xcbosd *osd); void xcbosd_expose(xcbosd *osd); void xcbosd_resize(xcbosd *osd, int width, int height); void xcbosd_drawable_changed(xcbosd *osd, xcb_window_t window); void xcbosd_clear(xcbosd *osd); void xcbosd_blend(xcbosd *osd, vo_overlay_t *overlay); #endif xine-lib-1.2/src/video_out/xvmc_mocomp.c0000644000175000017500000002142514647725152016147 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * XvMC image support by Jack Kelliher */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xxmc.h" static void calc_DMV(int DMV[][2], int *dmvector, int mvx, int mvy, int picture_structure, int top_field_first) { if (picture_structure==VO_BOTH_FIELDS) { if (top_field_first) { /* vector for prediction of top field from bottom field */ DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1; /* vector for prediction of bottom field from top field */ DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1; } else { /* vector for prediction of top field from bottom field */ DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1; /* vector for prediction of bottom field from top field */ DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1; } } else { /* vector for prediction from field of opposite 'parity' */ DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0]; DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1]; /* correct for vertical field shift */ if (picture_structure==VO_TOP_FIELD) DMV[0][1]--; else DMV[0][1]++; } } static void xvmc_render_macro_blocks(vo_frame_t *current_image, vo_frame_t *backward_ref_image, vo_frame_t *forward_ref_image, int picture_structure, int second_field, xvmc_macroblocks_t *macroblocks) { xxmc_driver_t *this = (xxmc_driver_t *) current_image->driver; xxmc_frame_t *current_frame = XXMC_FRAME(current_image); xxmc_frame_t *forward_frame = XXMC_FRAME(forward_ref_image); xxmc_frame_t *backward_frame = XXMC_FRAME(backward_ref_image); int flags; lprintf ("xvmc_render_macro_blocks\n"); lprintf ("slices %d 0x%08lx 0x%08lx 0x%08lx\n", macroblocks->slices, (long) current_frame, (long) backward_frame, (long) forward_frame); flags = second_field; XVMCLOCKDISPLAY( this->display); XvMCRenderSurface(this->display, &this->context, picture_structure, current_frame->xvmc_surf, forward_frame ? forward_frame->xvmc_surf : NULL, backward_frame ? backward_frame->xvmc_surf : NULL, flags, macroblocks->slices, 0, ¯oblocks->macro_blocks, ¯oblocks->blocks); XVMCUNLOCKDISPLAY( this->display); } void xxmc_xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type, int (*mv_field_sel)[2], int *dmvector, int cbp, int dct_type, vo_frame_t *current_frame, vo_frame_t *forward_ref_frame, vo_frame_t *backward_ref_frame, int picture_structure, int second_field, int (*f_mot_pmv)[2], int (*b_mot_pmv)[2]) { xxmc_driver_t *this = (xxmc_driver_t *) current_frame->driver; xvmc_macroblocks_t *mbs = &this->macroblocks; int top_field_first = current_frame->top_field_first; int picture_coding_type = current_frame->picture_coding_type; mbs->macroblockptr->x = x; mbs->macroblockptr->y = y; if(mb_type & XINE_MACROBLOCK_INTRA) { mbs->macroblockptr->macroblock_type = XVMC_MB_TYPE_INTRA; } else { mbs->macroblockptr->macroblock_type = 0; /* XvMC doesn't support skips */ if(!(mb_type & (XINE_MACROBLOCK_MOTION_BACKWARD | XINE_MACROBLOCK_MOTION_FORWARD))) { mb_type |= XINE_MACROBLOCK_MOTION_FORWARD; motion_type = (picture_structure == VO_BOTH_FIELDS) ? XINE_MC_FRAME : XINE_MC_FIELD; mbs->macroblockptr->PMV[0][0][0] = 0; mbs->macroblockptr->PMV[0][0][1] = 0; } else { if(mb_type & XINE_MACROBLOCK_MOTION_BACKWARD) { mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_BACKWARD; mbs->macroblockptr->PMV[0][1][0] = b_mot_pmv[0][0]; mbs->macroblockptr->PMV[0][1][1] = b_mot_pmv[0][1]; mbs->macroblockptr->PMV[1][1][0] = b_mot_pmv[1][0]; mbs->macroblockptr->PMV[1][1][1] = b_mot_pmv[1][1]; } if(mb_type & XINE_MACROBLOCK_MOTION_FORWARD) { mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_MOTION_FORWARD; mbs->macroblockptr->PMV[0][0][0] = f_mot_pmv[0][0]; mbs->macroblockptr->PMV[0][0][1] = f_mot_pmv[0][1]; mbs->macroblockptr->PMV[1][0][0] = f_mot_pmv[1][0]; mbs->macroblockptr->PMV[1][0][1] = f_mot_pmv[1][1]; } } if((mb_type & XINE_MACROBLOCK_PATTERN) && cbp) mbs->macroblockptr->macroblock_type |= XVMC_MB_TYPE_PATTERN; mbs->macroblockptr->motion_type = motion_type; if(motion_type == XINE_MC_DMV) { int DMV[2][2]; if(picture_structure == VO_BOTH_FIELDS) { calc_DMV(DMV,dmvector, f_mot_pmv[0][0], f_mot_pmv[0][1]>>1, picture_structure, top_field_first); mbs->macroblockptr->PMV[1][0][0] = DMV[0][0]; mbs->macroblockptr->PMV[1][0][1] = DMV[0][1]; mbs->macroblockptr->PMV[1][1][0] = DMV[1][0]; mbs->macroblockptr->PMV[1][1][1] = DMV[1][1]; } else { calc_DMV(DMV,dmvector, f_mot_pmv[0][0], f_mot_pmv[0][1]>>1, picture_structure, top_field_first); mbs->macroblockptr->PMV[0][1][0] = DMV[0][0]; mbs->macroblockptr->PMV[0][1][1] = DMV[0][1]; } } if((motion_type == XINE_MC_FIELD) || (motion_type == XINE_MC_16X8)) { mbs->macroblockptr->motion_vertical_field_select = 0; if(mv_field_sel[0][0]) mbs->macroblockptr->motion_vertical_field_select |= 1; if(mv_field_sel[0][1]) mbs->macroblockptr->motion_vertical_field_select |= 2; if(mv_field_sel[1][0]) mbs->macroblockptr->motion_vertical_field_select |= 4; if(mv_field_sel[1][1]) mbs->macroblockptr->motion_vertical_field_select |= 8; } } /* else of if(mb_type & XINE_MACROBLOCK_INTRA) */ mbs->macroblockptr->index = ((unsigned long)mbs->xine_mc.blockptr - (unsigned long)mbs->xine_mc.blockbaseptr) >> 7; mbs->macroblockptr->dct_type = dct_type; mbs->macroblockptr->coded_block_pattern = cbp; cbp &= 0x3F; mbs->macroblockptr->coded_block_pattern = cbp; while(cbp) { if(cbp & 1) mbs->macroblockptr->index--; cbp >>= 1; } #ifdef PRINTDATA printf("\n"); printf("-- %04d %04d %02x %02x %02x %02x",mbs->macroblockptr->x,mbs->macroblockptr->y,mbs->macroblockptr->macroblock_type, mbs->macroblockptr->motion_type,mbs->macroblockptr->motion_vertical_field_select,mbs->macroblockptr->dct_type); printf(" [%04d %04d %04d %04d %04d %04d %04d %04d] ", mbs->macroblockptr->PMV[0][0][0],mbs->macroblockptr->PMV[0][0][1],mbs->macroblockptr->PMV[0][1][0],mbs->macroblockptr->PMV[0][1][1], mbs->macroblockptr->PMV[1][0][0],mbs->macroblockptr->PMV[1][0][1],mbs->macroblockptr->PMV[1][1][0],mbs->macroblockptr->PMV[1][1][1]); printf(" %04d %04x\n",mbs->macroblockptr->index,mbs->macroblockptr->coded_block_pattern); #endif mbs->num_blocks++; mbs->macroblockptr++; if(mbs->num_blocks == mbs->slices) { #ifdef PRINTDATA printf("macroblockptr %lx", mbs->macroblockptr); printf("** RenderSurface %04d %04x\n",picture_structure, second_field ? XVMC_SECOND_FIELD : 0); fflush(stdout); #endif #ifdef PRINTFRAME printf(" target %08x past %08x future %08x\n", current_frame, forward_ref_frame, backward_ref_frame); #endif #ifdef PRINTFRAME if (picture_coding_type == XINE_PICT_P_TYPE) printf(" coding type P_TYPE\n"); if (picture_coding_type == XINE_PICT_I_TYPE) printf(" coding type I_TYPE\n"); if (picture_coding_type == XINE_PICT_B_TYPE) printf(" coding type B_TYPE\n"); if (picture_coding_type == XINE_PICT_D_TYPE) printf(" coding type D_TYPE\n"); fflush(stdout); #endif xvmc_render_macro_blocks( current_frame, (picture_coding_type == XINE_PICT_B_TYPE) ? backward_ref_frame : NULL, (picture_coding_type != XINE_PICT_I_TYPE) ? forward_ref_frame : NULL, picture_structure, second_field ? XVMC_SECOND_FIELD : 0, mbs); mbs->num_blocks = 0; mbs->macroblockptr = mbs->macroblockbaseptr; mbs->xine_mc.blockptr = mbs->xine_mc.blockbaseptr; } } xine-lib-1.2/src/video_out/xxmc.h0000644000175000017500000002071314647725152014603 0ustar meme/* * Copyright (C) 2000-2020 the xine project * Copyright (C) 2004 the unichrome project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_xxmc.c, X11 decoding accelerated video extension interface for xine * * based on mpeg2dec code from * Aaron Holtzman * * Xv image support by Gerd Knorr * * xine-specific code by Guenter Bartsch * * overlay support by James Courtier-Dutton - July 2001 * X11 unscaled overlay support by Miguel Freitas - Nov 2003 * XxMC implementation by Thomas Hellström - August 2004 */ #ifndef _XXMC_H #define _XXMC_H #define XVMC_THREAD_SAFE /* * some implementations are not aware of the display having been locked * already before calling the xvmc function and may therefore deadlock. */ /* #define XVMC_LOCKDISPLAY_SAFE */ #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included #endif #include #include #include #include #include #if defined (__SVR4) && defined (__sun) # include #else # include #endif #include #if defined(__FreeBSD__) #include #endif #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_VLDXVMC #include #endif #define LOG_MODULE "video_out_xxmc" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include #include #include #include #include "x11osd.h" #include "accel_xvmc.h" #define FOURCC_IA44 0x34344149 #define FOURCC_AI44 0x34344941 #define XVMC_MAX_SURFACES 16 #define XVMC_MAX_SUBPICTURES 4 typedef struct xxmc_driver_s xxmc_driver_t; typedef struct { xine_macroblocks_t xine_mc; XvMCBlockArray blocks; /* pointer to memory for dct block array */ int num_blocks; XvMCMacroBlock *macroblockptr; /* pointer to current macro block */ XvMCMacroBlock *macroblockbaseptr; /* pointer to base MacroBlock in MB array */ XvMCMacroBlockArray macro_blocks; /* pointer to memory for macroblock array */ int slices; } xvmc_macroblocks_t; typedef struct { int value; int min; int max; Atom atom; cfg_entry_t *entry; xxmc_driver_t *this; } xxmc_property_t; typedef struct { vo_frame_t vo_frame; int width, height, format; double ratio; XvImage *image; XShmSegmentInfo shminfo; /* XvMC specific stuff */ XvMCSurface *xvmc_surf; xine_xxmc_t xxmc_data; int last_sw_format; } xxmc_frame_t; typedef struct{ unsigned int mpeg_flags; unsigned int accel_flags; unsigned int max_width; unsigned int max_height; unsigned int sub_max_width; unsigned int sub_max_height; int type_id; XvImageFormatValues subPicType; int flags; } xvmc_capabilities_t; typedef struct xvmc_surface_handler_s { XvMCSurface surfaces[XVMC_MAX_SURFACES]; int surfInUse[XVMC_MAX_SURFACES]; int surfValid[XVMC_MAX_SURFACES]; XvMCSubpicture subpictures[XVMC_MAX_SUBPICTURES]; int subInUse[XVMC_MAX_SUBPICTURES]; int subValid[XVMC_MAX_SUBPICTURES]; pthread_mutex_t mutex; } xvmc_surface_handler_t; typedef struct context_lock_s { pthread_mutex_t mutex; pthread_cond_t cond; int num_readers; } context_lock_t; #define LOCK_AND_SURFACE_VALID(driver, surface) \ xvmc_context_reader_lock( &(driver)->xvmc_lock ); \ if (!xxmc_xvmc_surface_valid((driver),(surface))) { \ xvmc_context_reader_unlock( &(driver)->xvmc_lock ); \ return; \ } #if defined(XVMC_THREAD_SAFE) && defined(XVMC_LOCKDISPLAY_SAFE) #define XVMCLOCKDISPLAY(display) #define XVMCUNLOCKDISPLAY(display) #else #define XVMCLOCKDISPLAY(display) XLockDisplay(display) #define XVMCUNLOCKDISPLAY(display) XUnlockDisplay(display) #endif struct xxmc_driver_s { vo_driver_t vo_driver; config_values_t *config; /* X11 / Xv related stuff */ Display *display; int screen; Drawable drawable; unsigned int xv_format_yv12; unsigned int xv_format_yuy2; XVisualInfo vinfo; GC gc; XvPortID xv_port; XColor black; int use_shm; int use_pitch_alignment; xxmc_property_t props[VO_NUM_PROPERTIES]; uint32_t capabilities; xxmc_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; xxmc_frame_t *cur_frame; int cur_field; int bob; int disable_bob_for_progressive_frames; int disable_bob_for_scaled_osd; int scaled_osd_active; x11osd *xoverlay; int xv_xoverlay_type; int xoverlay_type; int ovl_changed; /* all scaling information goes here */ vo_scale_t sc; int deinterlace_enabled; int use_colorkey; uint32_t colorkey; int (*x11_old_error_handler) (Display *, XErrorEvent *); xine_t *xine; /* XvMC related stuff here */ xvmc_macroblocks_t macroblocks; xvmc_capabilities_t *xvmc_cap; unsigned xvmc_num_cap; unsigned int xvmc_max_subpic_x; unsigned int xvmc_max_subpic_y; int xvmc_eventbase; int xvmc_errbase; int hwSubpictures; XvMCSubpicture *old_subpic,*new_subpic; xx44_palette_t palette; int first_overlay; float cpu_saver; int cpu_save_enabled; int reverse_nvidia_palette; int context_flags; /* * These variables are protected by the context lock: */ unsigned xvmc_cur_cap; int xvmc_backend_subpic; XvMCContext context; int contextActive; xvmc_surface_handler_t xvmc_surf_handler; unsigned xvmc_mpeg; unsigned xvmc_accel; unsigned last_accel_request; unsigned xvmc_width; unsigned xvmc_height; int have_xvmc_autopaint; int xvmc_xoverlay_type; int unsigned_intra; /* * Only creation and destruction of the below. */ char *xvmc_palette; XvImage *subImage; XShmSegmentInfo subShmInfo; /* * The mutex below is needed since XlockDisplay wasn't really enough * to protect the XvMC Calls. */ context_lock_t xvmc_lock; alphablend_t alphablend_extra_data; }; typedef struct { video_driver_class_t driver_class; xine_t *xine; } xxmc_class_t; extern void xvmc_context_reader_unlock(context_lock_t *c); extern void xvmc_context_reader_lock(context_lock_t *c); extern int xxmc_xvmc_surface_valid(xxmc_driver_t *this, XvMCSurface *surf); extern void xvmc_vld_slice(vo_frame_t *this_gen); extern void xvmc_vld_frame(struct vo_frame_s *this_gen); extern void xxmc_xvmc_proc_macro_block(int x, int y, int mb_type, int motion_type, int (*mv_field_sel)[2], int *dmvector, int cbp, int dct_type, vo_frame_t *current_frame, vo_frame_t *forward_ref_frame, vo_frame_t *backward_ref_frame, int picture_structure, int second_field, int (*f_mot_pmv)[2], int (*b_mot_pmv)[2]); #endif xine-lib-1.2/src/video_out/video_out_macosx.m0000644000175000017500000002716314647725152017206 0ustar meme/* * Copyright (C) 2000-2003 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * This output driver makes use of xine's objective-c video_output * classes located in the macosx folder. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #define LOG_MODULE "video_out_macosx" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include "xine/video_out.h" #include "xine/vo_scale.h" #include "xine/xine_internal.h" #include "xine/xineutils.h" #include "macosx/video_window.h" typedef struct { vo_frame_t vo_frame; int width; int height; double ratio; int format; xine_t *xine; } macosx_frame_t; typedef struct { vo_driver_t vo_driver; config_values_t *config; int ratio; xine_t *xine; id view; alphablend_t alphablend_extra_data; } macosx_driver_t; typedef struct { video_driver_class_t driver_class; config_values_t *config; xine_t *xine; } macosx_class_t; static void free_framedata(macosx_frame_t* frame) { if(frame->vo_frame.base[0]) { free(frame->vo_frame.base[0]); frame->vo_frame.base[0] = NULL; frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; } } static void macosx_frame_dispose(vo_frame_t *vo_frame) { macosx_frame_t *frame = (macosx_frame_t *)vo_frame; free_framedata(frame); free (frame); } static void macosx_frame_field(vo_frame_t *vo_frame, int which_field) { /* do nothing */ } static uint32_t macosx_get_capabilities(vo_driver_t *vo_driver) { /* both styles, country and western */ return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_UNSCALED_OVERLAY; } static vo_frame_t *macosx_alloc_frame(vo_driver_t *vo_driver) { /* macosx_driver_t *this = (macosx_driver_t *) vo_driver; */ macosx_frame_t *frame; frame = calloc(1, sizeof(macosx_frame_t)); if(!frame) return NULL; pthread_mutex_init(&frame->vo_frame.mutex, NULL); frame->vo_frame.base[0] = NULL; frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = macosx_frame_field; frame->vo_frame.dispose = macosx_frame_dispose; frame->vo_frame.driver = vo_driver; return (vo_frame_t *)frame; } static void macosx_update_frame_format(vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags) { macosx_driver_t *this = (macosx_driver_t *) vo_driver; macosx_frame_t *frame = (macosx_frame_t *) vo_frame; if((frame->width != width) || (frame->height != height) || (frame->format != format)) { NSSize video_size = NSMakeSize(width, height); free_framedata(frame); frame->width = width; frame->height = height; frame->format = format; lprintf ("frame change, new height:%d width:%d (ratio:%lf) format:%d\n", height, width, ratio, format); switch(format) { case XINE_IMGFMT_YV12: { int y_size, uv_size; frame->vo_frame.pitches[0] = 8*((width + 7) / 8); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); y_size = frame->vo_frame.pitches[0] * height; uv_size = frame->vo_frame.pitches[1] * ((height+1)/2); frame->vo_frame.base[0] = malloc (y_size + 2*uv_size); frame->vo_frame.base[1] = frame->vo_frame.base[0]+y_size+uv_size; frame->vo_frame.base[2] = frame->vo_frame.base[0]+y_size; } break; case XINE_IMGFMT_YUY2: frame->vo_frame.pitches[0] = 8*((width + 3) / 4); frame->vo_frame.base[0] = malloc(frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_macosx: unknown frame format %04x)\n", format); break; } NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [this->view setVideoSize:video_size]; [pool release]; if((format == XINE_IMGFMT_YV12 && (frame->vo_frame.base[0] == NULL || frame->vo_frame.base[1] == NULL || frame->vo_frame.base[2] == NULL)) || (format == XINE_IMGFMT_YUY2 && frame->vo_frame.base[0] == NULL)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_macosx: error. (framedata allocation failed: out of memory)\n"); free_framedata(frame); } } frame->ratio = ratio; } static void macosx_display_frame(vo_driver_t *vo_driver, vo_frame_t *vo_frame) { macosx_driver_t *driver = (macosx_driver_t *)vo_driver; macosx_frame_t *frame = (macosx_frame_t *)vo_frame; char *texture_buffer; NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; if ((texture_buffer = [driver->view textureBuffer]) != NULL) { switch (vo_frame->format) { case XINE_IMGFMT_YV12: yv12_to_yuy2 (vo_frame->base[0], vo_frame->pitches[0], vo_frame->base[1], vo_frame->pitches[1], vo_frame->base[2], vo_frame->pitches[2], (unsigned char *)texture_buffer, vo_frame->width * 2, vo_frame->width, vo_frame->height, 0); [driver->view updateTexture]; break; case XINE_IMGFMT_YUY2: xine_fast_memcpy (texture_buffer, vo_frame->base[0], vo_frame->pitches[0] * vo_frame->height); [driver->view updateTexture]; break; default: /* unsupported frame format, do nothing. */ break; } } frame->vo_frame.free(&frame->vo_frame); [pool release]; } static void macosx_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { macosx_driver_t *this = (macosx_driver_t *) this_gen; macosx_frame_t *frame = (macosx_frame_t *) frame_gen; this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; /* TODO: should check here whether the overlay has changed or not: use a * ovl_changed boolean variable similarly to video_out_xv */ if (overlay->rle) { if (frame->format == XINE_IMGFMT_YV12) /* TODO: It may be possible to accelerate the blending via Quartz * Extreme ... */ _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } static int macosx_get_property(vo_driver_t *vo_driver, int property) { macosx_driver_t *driver = (macosx_driver_t *)vo_driver; switch(property) { case VO_PROP_ASPECT_RATIO: return driver->ratio; break; default: break; } return 0; } static int macosx_set_property(vo_driver_t *vo_driver, int property, int value) { macosx_driver_t *driver = (macosx_driver_t *)vo_driver; switch(property) { case VO_PROP_ASPECT_RATIO: if(value >= XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; driver->ratio = value; break; default: break; } return value; } static void macosx_get_property_min_max(vo_driver_t *vo_driver, int property, int *min, int *max) { *min = 0; *max = 0; } static int macosx_gui_data_exchange(vo_driver_t *vo_driver, int data_type, void *data) { /* macosx_driver_t *this = (macosx_driver_t *) vo_driver; */ switch (data_type) { case XINE_GUI_SEND_COMPLETION_EVENT: case XINE_GUI_SEND_DRAWABLE_CHANGED: case XINE_GUI_SEND_EXPOSE_EVENT: case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: case XINE_GUI_SEND_VIDEOWIN_VISIBLE: case XINE_GUI_SEND_SELECT_VISUAL: default: lprintf("unknown GUI data type %d\n", data_type); break; } return 0; } static void macosx_dispose(vo_driver_t *vo_driver) { macosx_driver_t *this = (macosx_driver_t *) vo_driver; _x_alphablend_free(&this->alphablend_extra_data); [this->view releaseInMainThread]; free(this); } static int macosx_redraw_needed(vo_driver_t *vo_driver) { return 0; } static vo_driver_t *open_plugin(video_driver_class_t *driver_class, const void *visual) { macosx_class_t *class = (macosx_class_t *) driver_class; macosx_driver_t *driver; XineOpenGLView *view = (XineOpenGLView *) visual; driver = calloc(1, sizeof(macosx_driver_t)); driver->config = class->config; driver->xine = class->xine; driver->ratio = XINE_VO_ASPECT_AUTO; driver->view = [view retain]; driver->vo_driver.get_capabilities = macosx_get_capabilities; driver->vo_driver.alloc_frame = macosx_alloc_frame; driver->vo_driver.update_frame_format = macosx_update_frame_format; driver->vo_driver.overlay_begin = NULL; /* not used */ driver->vo_driver.overlay_blend = macosx_overlay_blend; driver->vo_driver.overlay_end = NULL; /* not used */ driver->vo_driver.display_frame = macosx_display_frame; driver->vo_driver.get_property = macosx_get_property; driver->vo_driver.set_property = macosx_set_property; driver->vo_driver.get_property_min_max = macosx_get_property_min_max; driver->vo_driver.gui_data_exchange = macosx_gui_data_exchange; driver->vo_driver.dispose = macosx_dispose; driver->vo_driver.redraw_needed = macosx_redraw_needed; _x_alphablend_init(&driver->alphablend_extra_data, class->xine); return &driver->vo_driver; } /* * Class related functions. */ static void *init_class (xine_t *xine, void *visual) { macosx_class_t *this; this = calloc(1, sizeof(macosx_class_t)); this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "MacOSX"; this->driver_class.description = N_("xine video output plugin for Mac OS X"); this->driver_class.dispose = default_video_driver_class_dispose; this->config = xine->config; this->xine = xine; return this; } static const vo_info_t vo_info_macosx = { 1, /* Priority */ XINE_VISUAL_TYPE_MACOSX /* Visual type */ }; plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ /* work around the problem that dlclose() is not allowed to * get rid of an image module which contains objective C code and simply * crashes with a Trace/BPT trap when we try to do so */ { PLUGIN_VIDEO_OUT | PLUGIN_NO_UNLOAD, 22, "macosx", XINE_VERSION_CODE, &vo_info_macosx, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/xcbosd.c0000644000175000017500000004374414647725152015112 0ustar meme/* * Copyright (C) 2003-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xcbosd.c, use X11 Nonrectangular Window Shape Extension to draw xine OSD * * Nov 2003 - Miguel Freitas * Feb 2007 - ported to xcb by Christoph Pfister * * based on ideas and code of * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net) * * colorkey support by Yann Vernier */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #define LOG_MODULE "xcbosd" #define LOG_VERBOSE /* #define LOG */ #include #include "xcbosd.h" struct xcbosd { xcb_connection_t *connection; xcb_screen_t *screen; enum xcbosd_mode mode; union { struct { xcb_window_t window; xcb_pixmap_t mask_bitmap; xcb_gc_t mask_gc; xcb_gc_t mask_gc_back; int mapped; } shaped; struct { uint32_t colorkey; vo_scale_t *sc; } colorkey; } u; xcb_window_t window; unsigned int depth; xcb_pixmap_t bitmap; xcb_visualid_t visual; xcb_colormap_t cmap; xcb_gc_t gc; int width; int height; int x; int y; enum {DRAWN, WIPED, UNDEFINED} clean; xine_t *xine; }; void xcbosd_expose(xcbosd *osd) { assert (osd); lprintf("expose (state:%d)\n", osd->clean ); switch (osd->mode) { case XCBOSD_SHAPED: xcb_shape_mask(osd->connection, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_BOUNDING, osd->u.shaped.window, 0, 0, osd->u.shaped.mask_bitmap); if( osd->clean==DRAWN ) { if( !osd->u.shaped.mapped ) { unsigned int stack_mode = XCB_STACK_MODE_ABOVE; xcb_configure_window(osd->connection, osd->u.shaped.window, XCB_CONFIG_WINDOW_STACK_MODE, &stack_mode); xcb_map_window(osd->connection, osd->u.shaped.window); } osd->u.shaped.mapped = 1; xcb_copy_area(osd->connection, osd->bitmap, osd->u.shaped.window, osd->gc, 0, 0, 0, 0, osd->width, osd->height); } else { if( osd->u.shaped.mapped ) xcb_unmap_window(osd->connection, osd->u.shaped.window); osd->u.shaped.mapped = 0; } break; case XCBOSD_COLORKEY: if( osd->clean!=UNDEFINED ) xcb_copy_area(osd->connection, osd->bitmap, osd->window, osd->gc, 0, 0, 0, 0, osd->width, osd->height); } } void xcbosd_resize(xcbosd *osd, int width, int height) { assert (osd); assert (width); assert (height); lprintf("resize old:%dx%d new:%dx%d\n", osd->width, osd->height, width, height ); osd->width = width; osd->height = height; xcb_free_pixmap(osd->connection, osd->bitmap); switch(osd->mode) { case XCBOSD_SHAPED: { unsigned int window_config[] = { osd->width, osd->height }; xcb_configure_window(osd->connection, osd->u.shaped.window, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, window_config); xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); break; } case XCBOSD_COLORKEY: osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); break; } osd->clean = UNDEFINED; xcbosd_clear(osd); } void xcbosd_drawable_changed(xcbosd *osd, xcb_window_t window) { xcb_get_geometry_cookie_t get_geometry_cookie; xcb_get_geometry_reply_t *get_geometry_reply; assert (osd); lprintf("drawable changed\n"); /* Do I need to recreate the GC's?? XFreeGC (osd->display, osd->gc); XFreeGC (osd->display, osd->mask_gc); XFreeGC (osd->display, osd->mask_gc_back); */ xcb_free_pixmap(osd->connection, osd->bitmap); xcb_free_colormap(osd->connection, osd->cmap); /* we need to call XSync(), because otherwise, calling XDestroyWindow() on the parent window could destroy our OSD window twice !! */ /* XSync (osd->display, False); FIXME don't think that we need that --pfister */ osd->window = window; get_geometry_cookie = xcb_get_geometry(osd->connection, osd->window); get_geometry_reply = xcb_get_geometry_reply(osd->connection, get_geometry_cookie, NULL); osd->depth = get_geometry_reply->depth; osd->width = get_geometry_reply->width; osd->height = get_geometry_reply->height; free(get_geometry_reply); assert(osd->width); assert(osd->height); switch(osd->mode) { case XCBOSD_SHAPED: { xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); xcb_destroy_window(osd->connection, osd->u.shaped.window); unsigned int window_params[] = { osd->screen->black_pixel, 1, XCB_EVENT_MASK_EXPOSURE }; osd->u.shaped.window = xcb_generate_id(osd->connection); xcb_create_window(osd->connection, XCB_COPY_FROM_PARENT, osd->u.shaped.window, osd->window, 0, 0, osd->width, osd->height, 0, XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, window_params); osd->u.shaped.mapped = 0; osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->u.shaped.window, osd->visual); break; } case XCBOSD_COLORKEY: osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->window, osd->visual); break; } osd->clean = UNDEFINED; /* do not xcbosd_clear() here: osd->u.colorkey.sc has not being updated yet */ } xcbosd *xcbosd_create(xine_t *xine, xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window, enum xcbosd_mode mode) { xcbosd *osd; xcb_get_geometry_cookie_t get_geometry_cookie; xcb_get_geometry_reply_t *get_geometry_reply; xcb_void_cookie_t generic_cookie; xcb_generic_error_t *generic_error; osd = calloc(1, sizeof(xcbosd)); if (!osd) return NULL; osd->mode = mode; osd->xine = xine; osd->connection = connection; osd->screen = screen; osd->window = window; osd->visual = osd->screen->root_visual; get_geometry_cookie = xcb_get_geometry(osd->connection, osd->window); get_geometry_reply = xcb_get_geometry_reply(osd->connection, get_geometry_cookie, NULL); osd->depth = get_geometry_reply->depth; osd->width = get_geometry_reply->width; osd->height = get_geometry_reply->height; free(get_geometry_reply); assert(osd->width); assert(osd->height); switch (mode) { case XCBOSD_SHAPED: { const xcb_query_extension_reply_t *query_extension_reply = xcb_get_extension_data(osd->connection, &xcb_shape_id); if (!query_extension_reply || !query_extension_reply->present) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: XShape extension not available. unscaled overlay disabled.\n")); goto error2; } unsigned int window_params[] = { osd->screen->black_pixel, 1, XCB_EVENT_MASK_EXPOSURE }; osd->u.shaped.window = xcb_generate_id(osd->connection); generic_cookie = xcb_create_window_checked(osd->connection, XCB_COPY_FROM_PARENT, osd->u.shaped.window, osd->window, 0, 0, osd->width, osd->height, 0, XCB_COPY_FROM_PARENT, XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK, window_params); generic_error = xcb_request_check(osd->connection, generic_cookie); if (generic_error != NULL) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating window. unscaled overlay disabled.\n")); free(generic_error); goto error_window; } osd->u.shaped.mask_bitmap = xcb_generate_id(osd->connection); generic_cookie = xcb_create_pixmap_checked(osd->connection, 1, osd->u.shaped.mask_bitmap, osd->u.shaped.window, osd->width, osd->height); generic_error = xcb_request_check(osd->connection, generic_cookie); if (generic_error != NULL) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating pixmap. unscaled overlay disabled.\n")); free(generic_error); goto error_aftermaskbitmap; } osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->u.shaped.window, osd->width, osd->height); osd->gc = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->gc, osd->u.shaped.window, 0, NULL); osd->u.shaped.mask_gc = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->u.shaped.mask_gc, osd->u.shaped.mask_bitmap, XCB_GC_FOREGROUND, &osd->screen->white_pixel); osd->u.shaped.mask_gc_back = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->u.shaped.mask_gc_back, osd->u.shaped.mask_bitmap, XCB_GC_FOREGROUND, &osd->screen->black_pixel); osd->u.shaped.mapped = 0; osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->u.shaped.window, osd->visual); break; } case XCBOSD_COLORKEY: osd->bitmap = xcb_generate_id(osd->connection); xcb_create_pixmap(osd->connection, osd->depth, osd->bitmap, osd->window, osd->width, osd->height); osd->gc = xcb_generate_id(osd->connection); xcb_create_gc(osd->connection, osd->gc, osd->window, 0, NULL); osd->cmap = xcb_generate_id(osd->connection); xcb_create_colormap(osd->connection, XCB_COLORMAP_ALLOC_NONE, osd->cmap, osd->window, osd->visual); /* FIXME: the expose event doesn't seem to happen? */ /*XSelectInput (osd->display, osd->window, ExposureMask);*/ break; default: goto error2; } osd->clean = UNDEFINED; xcbosd_expose(osd); xprintf(osd->xine, XINE_VERBOSITY_DEBUG, _("x11osd: unscaled overlay created (%s mode).\n"), (mode==XCBOSD_SHAPED) ? "XShape" : "Colorkey" ); return osd; /* XFreeGC (osd->display, osd->gc); XFreeGC (osd->display, osd->mask_gc); XFreeGC (osd->display, osd->mask_gc_back); */ error_aftermaskbitmap: if(mode==XCBOSD_SHAPED) xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); error_window: if(mode==XCBOSD_SHAPED) xcb_destroy_window(osd->connection, osd->u.shaped.window); error2: free (osd); return NULL; } void xcbosd_colorkey(xcbosd *osd, uint32_t colorkey, vo_scale_t *scaling) { assert (osd); assert (osd->mode==XCBOSD_COLORKEY); osd->u.colorkey.colorkey=colorkey; osd->u.colorkey.sc=scaling; osd->clean = UNDEFINED; xcbosd_clear(osd); xcbosd_expose(osd); } void xcbosd_destroy(xcbosd *osd) { assert (osd); xcb_free_gc(osd->connection, osd->gc); xcb_free_pixmap(osd->connection, osd->bitmap); xcb_free_colormap(osd->connection, osd->cmap); if(osd->mode==XCBOSD_SHAPED) { xcb_free_gc(osd->connection, osd->u.shaped.mask_gc); xcb_free_gc(osd->connection, osd->u.shaped.mask_gc_back); xcb_free_pixmap(osd->connection, osd->u.shaped.mask_bitmap); xcb_destroy_window(osd->connection, osd->u.shaped.window); } free (osd); } void xcbosd_clear(xcbosd *osd) { int i; lprintf("clear (state:%d)\n", osd->clean ); if( osd->clean != WIPED ) switch (osd->mode) { case XCBOSD_SHAPED: { xcb_rectangle_t rectangle = { 0, 0, osd->width, osd->height }; xcb_poly_fill_rectangle(osd->connection, osd->u.shaped.mask_bitmap, osd->u.shaped.mask_gc_back, 1, &rectangle); break; } case XCBOSD_COLORKEY: xcb_change_gc(osd->connection, osd->gc, XCB_GC_FOREGROUND, &osd->u.colorkey.colorkey); if(osd->u.colorkey.sc) { xcb_rectangle_t rectangle = { osd->u.colorkey.sc->output_xoffset, osd->u.colorkey.sc->output_yoffset, osd->u.colorkey.sc->output_width, osd->u.colorkey.sc->output_height }; xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, 1, &rectangle); xcb_change_gc(osd->connection, osd->gc, XCB_GC_FOREGROUND, &osd->screen->black_pixel); xcb_rectangle_t rects[4]; int rects_count = 0; for( i = 0; i < 4; i++ ) { if( osd->u.colorkey.sc->border[i].w && osd->u.colorkey.sc->border[i].h ) { rects[rects_count].x = osd->u.colorkey.sc->border[i].x; rects[rects_count].y = osd->u.colorkey.sc->border[i].y; rects[rects_count].width = osd->u.colorkey.sc->border[i].w; rects[rects_count].height = osd->u.colorkey.sc->border[i].h; rects_count++; } if (rects_count > 0) xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, rects_count, rects); } } else { xcb_rectangle_t rectangle = { 0, 0, osd->width, osd->height }; xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, 1, &rectangle); } break; } osd->clean = WIPED; } #define TRANSPARENT 0xffffffff #define saturate(n, l, u) ((n) < (l) ? (l) : ((n) > (u) ? (u) : (n))) void xcbosd_blend(xcbosd *osd, vo_overlay_t *overlay) { xcb_alloc_color_cookie_t alloc_color_cookie; xcb_alloc_color_reply_t *alloc_color_reply; if (osd->clean==UNDEFINED) xcbosd_clear(osd); /* Workaround. Colorkey mode needs sc data before the clear. */ if (overlay->rle) { int i, x, y, len, width; int use_clip_palette, max_palette_colour[2]; uint32_t palette[2][OVL_PALETTE_SIZE]; max_palette_colour[0] = -1; max_palette_colour[1] = -1; for (i=0, x=0, y=0; inum_rle; i++) { len = overlay->rle[i].len; while (len > 0) { use_clip_palette = 0; if (len > overlay->width) { width = overlay->width; len -= overlay->width; } else { width = len; len = 0; } if ((y >= overlay->hili_top) && (y <= overlay->hili_bottom) && (x <= overlay->hili_right)) { if ((x < overlay->hili_left) && (x + width - 1 >= overlay->hili_left)) { width -= overlay->hili_left - x; len += overlay->hili_left - x; } else if (x > overlay->hili_left) { use_clip_palette = 1; if (x + width - 1 > overlay->hili_right) { width -= overlay->hili_right - x; len += overlay->hili_right - x; } } } if (overlay->rle[i].color > max_palette_colour[use_clip_palette]) { int j; uint32_t *src_color; uint8_t *src_trans; if (use_clip_palette) { src_color = overlay->hili_color; src_trans = (uint8_t *)&overlay->hili_trans; } else { src_color = overlay->color; src_trans = (uint8_t *)&overlay->trans; } for (j=max_palette_colour[use_clip_palette]+1; j<=overlay->rle[i].color; j++) { if (src_trans[j]) { union { uint32_t u32; clut_t c; } tmp = { src_color[j] }; if (1) { int red, green, blue; int y, u, v, r, g, b; y = saturate(tmp.c.y, 16, 235); u = saturate(tmp.c.cb, 16, 240); v = saturate(tmp.c.cr, 16, 240); y = (9 * y) / 8; r = y + (25 * v) / 16 - 218; red = (65536 * saturate(r, 0, 255)) / 256; g = y + (-13 * v) / 16 + (-25 * u) / 64 + 136; green = (65536 * saturate(g, 0, 255)) / 256; b = y + 2 * u - 274; blue = (65536 * saturate(b, 0, 255)) / 256; alloc_color_cookie = xcb_alloc_color(osd->connection, osd->cmap, red, green, blue); alloc_color_reply = xcb_alloc_color_reply(osd->connection, alloc_color_cookie, NULL); palette[use_clip_palette][j] = alloc_color_reply->pixel; free(alloc_color_reply); } else { if (tmp.c.y > 127) { palette[use_clip_palette][j] = osd->screen->white_pixel; } else { palette[use_clip_palette][j] = osd->screen->black_pixel; } } } else { palette[use_clip_palette][j] = TRANSPARENT; } } max_palette_colour[use_clip_palette] = overlay->rle[i].color; } if(palette[use_clip_palette][overlay->rle[i].color] != TRANSPARENT) { xcb_change_gc(osd->connection, osd->gc, XCB_GC_FOREGROUND, &palette[use_clip_palette][overlay->rle[i].color]); xcb_rectangle_t rectangle = { overlay->x + x, overlay->y + y, width, 1 }; xcb_poly_fill_rectangle(osd->connection, osd->bitmap, osd->gc, 1, &rectangle); if(osd->mode==XCBOSD_SHAPED) xcb_poly_fill_rectangle(osd->connection, osd->u.shaped.mask_bitmap, osd->u.shaped.mask_gc, 1, &rectangle); } x += width; if (x == overlay->width) { x = 0; y++; } } } osd->clean = DRAWN; } } xine-lib-1.2/src/video_out/video_out_opengl.c0000644000175000017500000021550414647725152017164 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_opengl.c, OpenGL based interface for xine * * Written by Matthias Hopf , * based on the xshm and xv video output plugins. */ /* #define LOG */ #define LOG_MODULE "video_out_opengl" #define BYTES_PER_PIXEL 4 #define NUM_FRAMES_BACKLOG 4 /* Allow thread some time to render frames */ #define SECONDS_PER_CYCLE 60 /* Animation parameters */ #define CYCLE_FACTOR1 3 #define CYCLE_FACTOR2 5 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include /* defines for debugging extensions only */ /* #define GL_GLEXT_LEGACY */ #include /* #undef GL_GLEXT_LEGACY */ #ifdef HAVE_GLU # include #endif /* * *Sigh* * glext.h really makes a lot of trouble, so we are providing our own. * It has been created from the original one from * http://oss.sgi.com/projects/ogl-sample/registry/ with * perl -ne 's/\bGL_\B/MYGL_/g;s/\bgl\B/mygl/g;s/\b__gl\B/__mygl/g;s/\bPFNGL\B/PFNMYGL/g;print' glext.h >myglext.h */ #define GLchar MYGLChar #define GLintptr MYGLintptr #define GLsizeiptr MYGLsizeiptr #define GLintptrARB MYGLintptrARB #define GLsizeiptrARB MYGLsizeiptrARB #define GLcharARB MYGLcharARB #define GLhandleARB MYGLhandleARB #define GLhalfARB MYGLhalfARB #define GLhalfNV MYGLhalfNV #include "myglext.h" #if defined (_WIN32) # define WIN32_LEAN_AND_MEAN # ifndef NOMINMAX # define NOMINMAX # endif /* NOMINMAX */ # include #elif defined (__APPLE__) # include # include #else # include # include #endif #include "xine.h" #include #include #include "yuv2rgb.h" #include #include "x11osd.h" #ifdef LOG # ifdef HAVE_GLU # define CHECKERR(a) do { int i = glGetError (); if (i != GL_NO_ERROR) fprintf (stderr, " *** %s: 0x%x = %s\n", a, i, gluErrorString (i)); } while (0) # else # define CHECKERR(a) do { int i = glGetError (); if (i != GL_NO_ERROR) fprintf (stderr, " *** %s: 0x%x\n", a, i); } while (0) # endif #else # define CHECKERR(a) ((void)0) #endif #if (BYTES_PER_PIXEL != 4) /* currently nothing else is supported */ # error "BYTES_PER_PIXEL bad" #endif /* TODO: haven't checked bigendian for a long time... */ #ifdef WORDS_BIGENDIAN # define RGB_TEXTURE_FORMAT GL_RGBA # define YUV_FORMAT MODE_32_BGR # define YUV_SWAP_MODE 1 #else /* TODO: Use GL_BGRA extension check for dynamically changing this */ #if 1 /* Might be faster on ix86, but yuv2rgb often buggy, needs extension */ # define RGB_TEXTURE_FORMAT GL_BGRA # define YUV_FORMAT MODE_32_RGB #else /* Slower on ix86 and overlays use wrong pixel order, but needs no extension */ # define RGB_TEXTURE_FORMAT GL_RGBA # define YUV_FORMAT MODE_32_BGR #endif # define YUV_SWAP_MODE 0 #endif #define MY_2PI (M_PI * 2) typedef struct { vo_frame_t vo_frame; int width, height, format, flags; double ratio; uint8_t *rgb, *rgb_dst; yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */ } opengl_frame_t; /* RENDER_DRAW to RENDER_SETUP are asynchronous actions, but later actions * imply former actions -> only check '>' on update */ /* RENDER_CREATE and later are synchronous actions and override async ones */ enum render_e { RENDER_NONE=0, RENDER_DRAW, RENDER_CLEAN, RENDER_SETUP, RENDER_CREATE, RENDER_VISUAL, RENDER_RELEASE, RENDER_EXIT }; typedef struct { vo_driver_t vo_driver; vo_scale_t sc; alphablend_t alphablend_extra_data; /* X11 related stuff */ Display *display; int screen; Drawable drawable; /* Render thread */ pthread_t render_thread; enum render_e render_action; int render_frame_changed; pthread_mutex_t render_action_mutex; pthread_cond_t render_action_cond; pthread_cond_t render_return_cond; int last_width, last_height; /* Render parameters */ int render_fun_id; int render_min_fps; int render_double_buffer; int gui_width, gui_height; /* OpenGL state */ GLXContext context; XVisualInfo *vinfo; GLuint fprog; int tex_width, tex_height; /* independend of frame */ /* OpenGL capabilities */ const GLubyte *gl_exts; /* extension string - NULL if uninitialized */ int has_bgra; int has_texobj; /* TODO: use */ int has_fragprog; int has_pixbufobj; /* OpenGL extensions */ PFNMYGLBINDPROGRAMARBPROC glBindProgramARB; PFNMYGLGENPROGRAMSARBPROC glGenProgramsARB; PFNMYGLPROGRAMSTRINGARBPROC glProgramStringARB; PFNMYGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB; PFNMYGLGENTEXTURESEXTPROC glGenTexturesEXT; PFNMYGLBINDTEXTUREEXTPROC glBindTextureEXT; int brightness; int contrast; int saturation; uint8_t *yuv2rgb_cmap; yuv2rgb_factory_t *yuv2rgb_factory; /* color matrix switching */ int cm_yuv2rgb, cm_fragprog, cm_state; uint8_t cm_lut[32]; /* Frame state */ opengl_frame_t *frame[NUM_FRAMES_BACKLOG]; x11osd *xoverlay; int ovl_changed; config_values_t *config; xine_t *xine; } opengl_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } opengl_class_t; typedef void *(*thread_run_t)(void *); typedef struct { /* Name of render backend */ const char * const name; /* Finally display current image (needed for Redraw) */ void (*display)(opengl_driver_t *, opengl_frame_t *); /* Upload new image; Returns 0 if failed */ int (*image)(opengl_driver_t *, opengl_frame_t *); /* Setup; Returns 0 if failed */ int (*setup)(opengl_driver_t *); /* Flag: needs output converted to rgb (is able to do YUV otherwise) */ int needsrgb; /* Default action: what to do if there's no new image * typically either RENDER_NONE or RENDER_DRAW (for animated render's) */ enum render_e defaction; /* Fallback: change to following render backend if this one doesn't work */ int fallback; } opengl_render_t; /* import common color matrix stuff */ #define CM_LUT #define CM_DRIVER_T opengl_driver_t #include "color_matrix.c" static const int32_t Inverse_Table_6_9[8][4] = { {117504, 138453, 13954, 34903}, /* no sequence_display_extension */ {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */ {104597, 132201, 25675, 53279}, /* unspecified */ {104597, 132201, 25675, 53279}, /* reserved */ {104448, 132798, 24759, 53109}, /* FCC */ {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */ {104597, 132201, 25675, 53279}, /* SMPTE 170M */ {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ }; /* * Render functions */ /* Static 2d texture based display */ static void render_tex2d (opengl_driver_t *this, opengl_frame_t *frame) { int x1, x2, y1, y2; float tx, ty; /* Calc texture/rectangle coords */ x1 = this->sc.output_xoffset; y1 = this->sc.output_yoffset; x2 = x1 + this->sc.output_width; y2 = y1 + this->sc.output_height; tx = (float) frame->width / this->tex_width; ty = (float) frame->height / this->tex_height; /* Draw quad */ glBegin (GL_QUADS); glTexCoord2f (tx, ty); glVertex2i (x2, y2); glTexCoord2f (0, ty); glVertex2i (x1, y2); glTexCoord2f (0, 0); glVertex2i (x1, y1); glTexCoord2f (tx, 0); glVertex2i (x2, y1); glEnd (); } /* Static 2d texture tiled based display */ static void render_tex2dtiled (opengl_driver_t *this, opengl_frame_t *frame) { int tex_w, tex_h, frame_w, frame_h; int i, j, nx, ny; float x1, x2, y1, y2, txa, txb, tya, tyb, xa, xb, xn, ya, yb, yn; tex_w = this->tex_width; tex_h = this->tex_height; frame_w = frame->width; frame_h = frame->height; /* Calc texture/rectangle coords */ x1 = this->sc.output_xoffset; y1 = this->sc.output_yoffset; x2 = x1 + this->sc.output_width; y2 = y1 + this->sc.output_height; txa = 1.0 / tex_w; tya = 1.0 / tex_h; txb = (float) frame_w / (tex_w-2); /* temporary: total */ tyb = (float) frame_h / (tex_h-2); xn = this->sc.output_width / txb; yn = this->sc.output_height / tyb; nx = txb; ny = tyb; /* Draw quads */ for (i = 0, ya = y1; i <= ny; i++, ya += yn) { for (j = 0, xa = x1; j <= nx; j++, xa += xn) { if (this->glBindTextureEXT) this->glBindTextureEXT (GL_TEXTURE_2D, i*(nx+1)+j+1); txb = (float) (j == nx ? frame_w - j*(tex_w-2)+1 : (tex_w-1)) / tex_w; tyb = (float) (i == ny ? frame_h - i*(tex_h-2)+1 : (tex_h-1)) / tex_h; xb = (j == nx ? x2 : xa + xn); yb = (i == ny ? y2 : ya + yn); glBegin (GL_QUADS); glTexCoord2f (txb, tyb); glVertex2f (xb, yb); glTexCoord2f (txa, tyb); glVertex2f (xa, yb); glTexCoord2f (txa, tya); glVertex2f (xa, ya); glTexCoord2f (txb, tya); glVertex2f (xb, ya); glEnd (); } } } /* Static image pipline based display */ static void render_draw (opengl_driver_t *this, opengl_frame_t *frame) { glPixelZoom (((float)this->sc.output_width) / frame->width, - ((float)this->sc.output_height) / frame->height); glRasterPos2i (this->sc.output_xoffset, this->sc.output_yoffset); glDrawPixels (frame->width, frame->height, RGB_TEXTURE_FORMAT, GL_UNSIGNED_BYTE, frame->rgb); } /* Animated spinning cylinder */ #define CYL_TESSELATION 128 #define CYL_WIDTH 2.5 #define CYL_HEIGHT 3.0 static void render_cyl (opengl_driver_t *this, opengl_frame_t *frame) { int i; float off; float tx, ty; struct timeval curtime; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); /* Calc timing + texture coords */ gettimeofday (&curtime, NULL); off = ((curtime.tv_sec % SECONDS_PER_CYCLE) + curtime.tv_usec * 1e-6) * (360.0 / SECONDS_PER_CYCLE); tx = (float) frame->width / this->tex_width; ty = (float) frame->height / this->tex_height; /* Spin it */ glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glTranslatef (0, 0, -10); glRotatef (off * CYCLE_FACTOR1, 1, 0, 0); glRotatef (off, 0, 0, 1); glRotatef (off * CYCLE_FACTOR2, 0, 1, 0); /* Note that this is not aspect ratio corrected */ glBegin (GL_QUADS); for (i = 0; i < CYL_TESSELATION; i++) { float x1 = CYL_WIDTH * sin (i * MY_2PI / CYL_TESSELATION); float x2 = CYL_WIDTH * sin ((i+1) * MY_2PI / CYL_TESSELATION); float z1 = CYL_WIDTH * cos (i * MY_2PI / CYL_TESSELATION); float z2 = CYL_WIDTH * cos ((i+1) * MY_2PI / CYL_TESSELATION); float tx1 = tx * i / CYL_TESSELATION; float tx2 = tx * (i+1) / CYL_TESSELATION; glTexCoord2f (tx1, 0); glVertex3f (x1, CYL_HEIGHT, z1); glTexCoord2f (tx2, 0); glVertex3f (x2, CYL_HEIGHT, z2); glTexCoord2f (tx2, ty); glVertex3f (x2, -CYL_HEIGHT, z2); glTexCoord2f (tx1, ty); glVertex3f (x1, -CYL_HEIGHT, z1); } glEnd (); } /* Animated spinning environment mapped torus */ #define DIST_FACTOR 16.568542 /* 2 * (sqrt(2)-1) * 20 */ static void render_env_tor (opengl_driver_t *this, opengl_frame_t *frame) { float off; float x1, y1, x2, y2, tx, ty; struct timeval curtime; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); /* Calc timing + texture coords */ gettimeofday (&curtime, NULL); off = ((curtime.tv_sec % SECONDS_PER_CYCLE) + curtime.tv_usec * 1e-6) * (360.0 / SECONDS_PER_CYCLE); /* Fovy is angle in y direction */ x1 = (this->sc.output_xoffset - this->gui_width/2.0) * DIST_FACTOR / this->gui_height; x2 = (this->sc.output_xoffset+this->sc.output_width - this->gui_width/2.0) * DIST_FACTOR / this->gui_height; y1 = (this->sc.output_yoffset - this->gui_height/2.0) * DIST_FACTOR / this->gui_height; y2 = (this->sc.output_yoffset+this->sc.output_height - this->gui_height/2.0) * DIST_FACTOR / this->gui_height; tx = (float) frame->width / this->tex_width; ty = (float) frame->height / this->tex_height; glMatrixMode (GL_MODELVIEW); glLoadIdentity (); /* Draw background, Y swapped */ glMatrixMode (GL_TEXTURE); glPushMatrix (); glLoadIdentity (); glDepthFunc (GL_ALWAYS); glDepthMask (GL_FALSE); glBegin (GL_QUADS); glColor3f (1, 1, 1); glTexCoord2f (tx, 0); glVertex3f (x2, y2, -20); glTexCoord2f (0, 0); glVertex3f (x1, y2, -20); glTexCoord2f (0, ty); glVertex3f (x1, y1, -20); glTexCoord2f (tx, ty); glVertex3f (x2, y1, -20); glEnd (); glPopMatrix (); glDepthFunc (GL_LEQUAL); glDepthMask (GL_TRUE); /* Spin it */ glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glTranslatef (0, 0, -10); glRotatef (off * CYCLE_FACTOR1, 1, 0, 0); glRotatef (off, 0, 0, 1); glRotatef (off * CYCLE_FACTOR2, 0, 1, 0); glEnable (GL_TEXTURE_GEN_S); glEnable (GL_TEXTURE_GEN_T); glColor3f (1, 0.8, 0.6); glCallList (1); glDisable (GL_TEXTURE_GEN_S); glDisable (GL_TEXTURE_GEN_T); } /* * Image setup functions */ /* returns 0: allocation failure 1: texture updated 2: texture kept */ static int render_help_image_tex (opengl_driver_t *this, int new_w, int new_h, GLint glformat, GLint texformat) { int tex_w, tex_h, err; /* check necessary texture size and allocate */ if (new_w != this->last_width || new_h != this->last_height || ! this->tex_width || ! this->tex_height) { tex_w = tex_h = 16; while (tex_w < new_w) tex_w <<= 1; while (tex_h < new_h) tex_h <<= 1; if (tex_w != this->tex_width || tex_h != this->tex_height) { char *tmp = calloc (tex_w * tex_h, 4); /* 4 enough until RGBA */ if (this->glBindTextureEXT) this->glBindTextureEXT (GL_TEXTURE_2D, 0); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D (GL_TEXTURE_2D, 0, glformat, tex_w, tex_h, 0, texformat, GL_UNSIGNED_BYTE, tmp); err = glGetError (); free (tmp); if (err) return 0; this->tex_width = tex_w; this->tex_height = tex_h; lprintf ("* new texsize: %dx%d\n", tex_w, tex_h); } this->last_width = new_w; this->last_height = new_h; return 1; } return 2; } /* returns 0: allocation failure 1: textures updated 2: textures kept */ static int render_help_image_tiledtex (opengl_driver_t *this, int new_w, int new_h, GLint glformat, GLint texformat) { int tex_w, tex_h, err, i, num; /* check necessary texture size and allocate */ if (new_w != this->last_width || new_h != this->last_height || ! this->tex_width || ! this->tex_height) { tex_w = tex_h = 16; while (tex_w < new_w) tex_w <<= 1; while (tex_h < new_h) tex_h <<= 1; if (tex_w != this->tex_width || tex_h != this->tex_height) { char *tmp = calloc (tex_w * tex_h, 4); /* 4 enough until RGBA */ if (this->glBindTextureEXT) this->glBindTextureEXT (GL_TEXTURE_2D, 1); /* allocate and figure out maximum texture size */ do { glTexImage2D (GL_TEXTURE_2D, 0, glformat, tex_w, tex_h, 0, texformat, GL_UNSIGNED_BYTE, tmp); err = glGetError (); if (err) { if (tex_w > tex_h) tex_w >>= 1; else tex_h >>= 1; if (tex_w < 64 && tex_h < 64) break; } } while (err); /* tiles have to overlap by one pixel in each direction * -> (tex_w-2) x (tex_h-2) */ num = (new_w / (tex_w-2) + 1) * (new_h / (tex_h-2) + 1); if (! this->has_texobj && num > 1) err = 1; if (! err) { for (i = 1; i <= num; i++) { if (this->glBindTextureEXT) this->glBindTextureEXT (GL_TEXTURE_2D, i); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D (GL_TEXTURE_2D, 0, glformat, tex_w, tex_h, 0, texformat, GL_UNSIGNED_BYTE, tmp); } } free (tmp); if (err) return 0; this->tex_width = tex_w; this->tex_height = tex_h; lprintf ("* new texsize: %dx%d on %d tiles\n", tex_w, tex_h, num); } this->last_width = new_w; this->last_height = new_h; return 1; } return 2; } static int render_image_nop (opengl_driver_t *this, opengl_frame_t *frame) { (void)this; (void)frame; return 1; } static int render_image_tex (opengl_driver_t *this, opengl_frame_t *frame) { int ret; ret = render_help_image_tex (this, frame->width, frame->height, GL_RGB, RGB_TEXTURE_FORMAT); if (! ret) return 0; /* TODO: asynchronous texture upload (ARB_pixel_buffer_object) */ /* texture data is already not destroyed immedeately after this call */ /* Load texture */ glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, frame->width, frame->height, RGB_TEXTURE_FORMAT, GL_UNSIGNED_BYTE, frame->rgb); return 1; } static int render_image_tiledtex (opengl_driver_t *this, opengl_frame_t *frame) { int ret; int frame_w, frame_h, tex_w, tex_h, i, j, nx, ny; ret = render_help_image_tiledtex (this, frame->width, frame->height, GL_RGB, RGB_TEXTURE_FORMAT); if (! ret) return 0; frame_w = frame->width; frame_h = frame->height; tex_w = this->tex_width; tex_h = this->tex_height; nx = frame_w / (tex_w-2); ny = frame_h / (tex_h-2); glPixelStorei (GL_UNPACK_ROW_LENGTH, frame_w); for (i = 0; i <= ny; i++) { for (j = 0; j <= nx; j++) { if (this->glBindTextureEXT) this->glBindTextureEXT (GL_TEXTURE_2D, i*(nx+1)+j+1); /* TODO: asynchronous texture upload (ARB_pixel_buffer_object) */ /* gets a bit ugly in order not to address data above frame->rgb */ glTexSubImage2D (GL_TEXTURE_2D, 0, (j==0), (i==0), j == nx ? frame_w-j*(tex_w-2)+(j!=0) : tex_w-(j==0), i == ny ? frame_h-i*(tex_h-2)+(i!=0) : tex_h-(i==0), RGB_TEXTURE_FORMAT, GL_UNSIGNED_BYTE, &frame->rgb[4*(frame_w*((tex_h-2)*i-(i!=0))+(tex_w-2)*j-(j!=0))]); } } glPixelStorei (GL_UNPACK_ROW_LENGTH, 0); CHECKERR ("texsubimage"); return 1; } /* YUV texture layout .llllll. * .llllll. * lum size 6x4 -> .llllll. * .llllll. * empty w/ 0 (box filter y) ....... * empty w/ 0.5 (box filter u+v) ///////// * /uuu/vvv/ * u, v size 3x2 each -> /uuu/vvv/ * ///////// */ /* TODO: use non-power-of-2 textures */ /* TODO: don't calculate texcoords in fragprog, but get interpolated coords */ static int render_image_fp_yuv (opengl_driver_t *this, opengl_frame_t *frame) { int w2 = frame->width/2, h2 = frame->height/2; int i, ret; if (! this->has_fragprog) return 0; if (frame->format != XINE_IMGFMT_YV12) { fprintf (stderr, "Fragment program only supported for YV12 data\n"); return 0; } ret = render_help_image_tex (this, w2 + frame->vo_frame.pitches[2] + 3, frame->height + h2 + 3, GL_LUMINANCE, GL_LUMINANCE); if (! ret) return 0; if (ret == 1) { uint8_t *tmp = calloc (this->tex_width * this->tex_height, 1); for (i = 0; i < frame->width+3; i++) { tmp[this->tex_width*(frame->height+1)+i] = 128; tmp[this->tex_width*(frame->height+h2+2)+i] = 128; } for (i = 0; i < h2; i++) { tmp[this->tex_width*(frame->height+2+i)] = 128; tmp[this->tex_width*(frame->height+2+i)+w2+1] = 128; tmp[this->tex_width*(frame->height+2+i)+2*w2+2] = 128; } glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, this->tex_width, this->tex_height, GL_LUMINANCE, GL_UNSIGNED_BYTE, tmp); CHECKERR ("clean-texsubimage"); free (tmp); this->glProgramEnvParameter4fARB (MYGL_FRAGMENT_PROGRAM_ARB, 0, 1.0 /this->tex_width, (float)(frame->height+2)/this->tex_height, (float)(w2+2) /this->tex_width, 0); } if (w2 & 7) for (i = 0; i < h2; i++) { frame->vo_frame.base[1][i*frame->vo_frame.pitches[1]+w2] = 128; frame->vo_frame.base[2][i*frame->vo_frame.pitches[2]+w2] = 128; } /* Load texture */ CHECKERR ("pre-texsubimage"); glTexSubImage2D (GL_TEXTURE_2D, 0, 1, 0, frame->vo_frame.pitches[0], frame->height, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->vo_frame.base[0]); glTexSubImage2D (GL_TEXTURE_2D, 0, 1, frame->height+2, frame->vo_frame.pitches[1], h2, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->vo_frame.base[1]); glTexSubImage2D (GL_TEXTURE_2D, 0, w2+2, frame->height+2, frame->vo_frame.pitches[2], h2, GL_LUMINANCE, GL_UNSIGNED_BYTE, frame->vo_frame.base[2]); CHECKERR ("texsubimage"); return 1; } static int render_image_envtex (opengl_driver_t *this, opengl_frame_t *frame) { static float mTex[] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; int ret; /* update texture matrix if frame size changed */ if (frame->width != this->last_width || frame->height != this->last_height || ! this->tex_width || ! this->tex_height) { ret = render_image_tex (this, frame); /* Texture matrix has to skale/shift tex origin + swap y coords */ mTex[0] = this->tex_width ? ( 1.0 * frame->width / this->tex_width) : 1.0; mTex[5] = this->tex_height ? (-1.0 * frame->height / this->tex_height) : -1.0; mTex[12] = (-2.0 * mTex[0]) / mTex[0]; mTex[13] = -mTex[5]; glMatrixMode (GL_TEXTURE); glLoadMatrixf (mTex); } else { ret = render_image_tex (this, frame); } return ret; } /* * Render setup functions */ static int render_help_verify_ext (opengl_driver_t *this, const char *ext) { int ret = 0; const size_t l = strlen (ext); const char *e; for (e = (const char *) this->gl_exts; e && *e; e = strchr (e, ' ')) { while (isspace (*e)) e++; if (strncmp (e, ext, l) == 0 && (e[l] == 0 || e[l] == ' ')) { ret = 1; break; } } xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_opengl: extension %s: %s\n", ext, ret ? "OK" : "missing"); return ret; } /* Return the address of a linked function */ static void *getdladdr (const GLubyte *_funcName) { const char *funcName = (const char *) _funcName; #if defined(_WIN32) return NULL; #elif defined(__APPLE__) char *temp; temp = _x_asprintf("_%s", funcName); void *res = NULL; if (NSIsSymbolNameDefined (temp)) { NSSymbol symbol = NSLookupAndBindSymbol (temp); res = NSAddressOfSymbol (symbol); } free (temp); return res; #elif defined (__sun) || defined (__sgi) static void *handle = NULL; if (!handle) { handle = dlopen (NULL, RTLD_LAZY); } return dlsym (handle, funcName); #else /* all other Un*xes */ return dlsym (0, funcName); #endif } /* Return the address of the specified OpenGL extension function */ static void *getaddr (const char *funcName) { #if defined(_WIN32) return (void*) wglGetProcAddress ((const GLubyte *) funcName); #else void * (*MYgetProcAddress) (const GLubyte *); void *res; /* Try to get address of extension via glXGetProcAddress[ARB], if that * fails try to get the address of a linked function */ MYgetProcAddress = getdladdr ((const GLubyte *) "glXGetProcAddress"); if (! MYgetProcAddress) MYgetProcAddress = getdladdr ((const GLubyte *) "glXGetProcAddressARB"); if (! MYgetProcAddress) MYgetProcAddress = getdladdr; res = MYgetProcAddress ((const GLubyte *) funcName); if (! res) fprintf (stderr, "Cannot find address for OpenGL extension function '%s',\n" "which should be available according to extension specs.\n", funcName); return res; #endif } static void render_help_check_exts (opengl_driver_t *this) { static int num_tests = 0; if (this->gl_exts) return; this->gl_exts = glGetString (GL_EXTENSIONS); if (! this->gl_exts) { if (++num_tests > 10) { fprintf (stderr, "video_out_opengl: Cannot find OpenGL extensions (tried multiple times).\n"); this->gl_exts = (const GLubyte *) ""; } } else num_tests = 0; if (! this->gl_exts) xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: No extensions found - assuming bad visual, testing later.\n"); this->has_bgra = render_help_verify_ext (this, "GL_EXT_bgra"); if (! this->has_bgra && RGB_TEXTURE_FORMAT == GL_BGRA && this->gl_exts) fprintf (stderr, "video_out_opengl: compiled for BGRA output, but missing extension.\n"); if ( (this->has_texobj = render_help_verify_ext (this, "GL_EXT_texture_object")) ) { this->glGenTexturesEXT = getaddr ("glGenTexturesEXT"); /* TODO: use for alloc */ this->glBindTextureEXT = getaddr ("glBindTextureEXT"); if (! this->glGenTexturesEXT || ! this->glBindTextureEXT) this->has_texobj = 0; } if ( (this->has_fragprog = render_help_verify_ext (this, "GL_ARB_fragment_program")) ) { this->glBindProgramARB = getaddr ("glBindProgramARB"); this->glGenProgramsARB = getaddr ("glGenProgramsARB"); this->glProgramStringARB = getaddr ("glProgramStringARB"); this->glProgramEnvParameter4fARB = getaddr ("glProgramEnvParameter4fARB"); if (! this->glBindProgramARB || ! this->glGenProgramsARB || ! this->glProgramStringARB || ! this->glProgramEnvParameter4fARB) this->has_fragprog = 0; } this->has_pixbufobj = render_help_verify_ext (this, "GL_ARB_pixel_buffer_object"); } static int render_help_setup_tex (opengl_driver_t *this) { (void)this; CHECKERR ("pre-tex_setup"); glEnable (GL_TEXTURE_2D); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glMatrixMode (GL_TEXTURE); glLoadIdentity (); CHECKERR ("post-tex_setup"); return 1; } #ifndef HAVE_GLU #define gluPerspective myGluPerspective static void myGluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) { double ymax = zNear * tan(fovy * M_PI / 360.0); double ymin = -ymax; glFrustum (ymin * aspect, ymax * aspect, ymin, ymax, zNear, zFar); } #endif static int render_setup_2d (opengl_driver_t *this) { render_help_check_exts (this); CHECKERR ("pre-viewport"); if (this->gui_width > 0 && this->gui_height > 0) glViewport (0, 0, this->gui_width, this->gui_height); glDepthRange (-1, 1); glClearColor (0, 0, 0, 0); glColor3f (1, 1, 1); glClearDepth (1); CHECKERR ("pre-frustum_setup"); glMatrixMode (GL_PROJECTION); glLoadIdentity (); glOrtho (0, this->gui_width, this->gui_height, 0, -1, 1); CHECKERR ("post-frustum_setup"); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); glDisable (GL_BLEND); glDisable (GL_DEPTH_TEST); glDepthMask (GL_FALSE); glDisable (GL_CULL_FACE); glShadeModel (GL_FLAT); glDisable (GL_TEXTURE_2D); CHECKERR ("post-en/disable"); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); glDisable (MYGL_FRAGMENT_PROGRAM_ARB); glGetError (); return 1; } static int render_setup_tex2d (opengl_driver_t *this) { int ret; ret = render_setup_2d (this); ret &= render_help_setup_tex (this); return ret; } static int render_setup_3d (opengl_driver_t *this) { render_help_check_exts (this); if (this->gui_width > 0 && this->gui_height > 0) { CHECKERR ("pre-3dfrustum_setup"); glViewport (0, 0, this->gui_width, this->gui_height); glDepthRange (0, 1); glClearColor (0, 0, 0, 0); glClearDepth (1.0f); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (45.0f, (GLfloat)(this->gui_width) / (GLfloat)(this->gui_height), 1.0f, 1000.0f); } glDisable (GL_BLEND); glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL); glDepthMask (GL_TRUE); glDisable (GL_CULL_FACE); glShadeModel (GL_FLAT); glDisable (GL_TEXTURE_2D); glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); CHECKERR ("post-3dfrustum_setup"); glDisable (MYGL_FRAGMENT_PROGRAM_ARB); glGetError (); return 1; } static int render_setup_cyl (opengl_driver_t *this) { int ret; ret = render_setup_3d (this); ret &= render_help_setup_tex (this); glClearColor (0, .2, .3, 0); return ret; } #define TOR_TESSELATION_B 128 #define TOR_TESSELATION_S 64 #define TOR_RADIUS_B 2.5 #define TOR_RADIUS_S 1.0 static int render_setup_torus (opengl_driver_t *this) { int i, j, k; int ret; ret = render_setup_3d (this); ret &= render_help_setup_tex (this); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexGeni (GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); glTexGeni (GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); /* create display list */ glNewList (1, GL_COMPILE); for (i = 0; i < TOR_TESSELATION_B; i++) { glBegin (GL_QUAD_STRIP); for (j = 0; j <= TOR_TESSELATION_S; j++) { float phi = MY_2PI * j / TOR_TESSELATION_S; for (k = 0; k <= 1; k++) { float theta = MY_2PI * (i + k) / TOR_TESSELATION_B; float nx = TOR_RADIUS_S * cos(phi) * cos(theta); float ny = TOR_RADIUS_S * cos(phi) * sin(theta); float nz = TOR_RADIUS_S * sin(phi); float nnorm = 1.0 / sqrt (nx*nx + ny*ny + nz*nz); float x = (TOR_RADIUS_B + TOR_RADIUS_S * cos(phi)) * cos(theta); float y = (TOR_RADIUS_B + TOR_RADIUS_S * cos(phi)) * sin(theta); float z = TOR_RADIUS_S * sin(phi); glNormal3f (nx * nnorm, ny * nnorm, nz * nnorm); glVertex3f (x, y, z); } } glEnd (); } glEndList (); return ret; } static int render_setup_fp_yuv (opengl_driver_t *this) { GLint errorpos; int ret; int i = (this->cm_fragprog >> 1) & 7; int vr = Inverse_Table_6_9[i][0]; int ug = Inverse_Table_6_9[i][2]; int vg = Inverse_Table_6_9[i][3]; int ub = Inverse_Table_6_9[i][1]; int ygain, yoffset; /* TV set behaviour: contrast affects colour difference as well */ int saturation = (this->saturation * this->contrast + 64) / 128; static char fragprog_yuv[512]; const char *s = ""; /* full range mode */ if (this->cm_fragprog & 1) { ygain = (1000 * this->contrast + 64) / 128; yoffset = this->brightness * ygain / 255; /* be careful to stay within 32 bit */ vr = (saturation * (112 / 4) * vr + 127 * 16) / (127 * 128 / 4); ug = (saturation * (112 / 4) * ug + 127 * 16) / (127 * 128 / 4); vg = (saturation * (112 / 4) * vg + 127 * 16) / (127 * 128 / 4); ub = (saturation * (112 / 4) * ub + 127 * 16) / (127 * 128 / 4); } else { ygain = (1000 * 255 * this->contrast + 219 * 64) / (219 * 128); yoffset = (this->brightness - 16) * ygain / 255; vr = (saturation * vr + 64) / 128; ug = (saturation * ug + 64) / 128; vg = (saturation * vg + 64) / 128; ub = (saturation * ub + 64) / 128; } vr = 1000 * vr / 65536; ug = 1000 * ug / 65536; vg = 1000 * vg / 65536; ub = 1000 * ub / 65536; if (yoffset < 0) { s = "-"; yoffset = -yoffset; } sprintf (fragprog_yuv, "!!ARBfp1.0\n" "ATTRIB tex = fragment.texcoord[0];" "PARAM off = program.env[0];" "TEMP u, v;" "TEMP res, tmp;" "ADD u, tex, off.xwww;" "TEX res, u, texture[0], 2D;" "MUL v, tex, .5;" "ADD u, v, off.xyww;" "ADD v, v, off.zyww;" "TEX tmp.x, u, texture[0], 2D;" "MAD res, res, %d.%03d, %s%d.%03d;" "TEX tmp.y, v, texture[0], 2D;" "SUB tmp, tmp, { .5, .5 };" "MAD res, { 0, -%d.%03d, %d.%03d }, tmp.xxxw, res;" "MAD result.color, { %d.%03d, -%d.%03d, 0 }, tmp.yyyw, res;" "END", /* nasty: "%.3f" may use comma as decimal point... */ ygain / 1000, ygain % 1000, s, yoffset / 1000, yoffset % 1000, ug / 1000, ug % 1000, ub / 1000, ub % 1000, vr / 1000, vr % 1000, vg / 1000, vg % 1000); ret = render_setup_tex2d (this); if (! this->has_fragprog) return 0; xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_opengl_fragprog: b %d c %d s %d [%s]\n", this->brightness, this->contrast, this->saturation, cm_names[this->cm_fragprog]); if (this->fprog == (GLuint)-1) this->glGenProgramsARB (1, &this->fprog); this->glBindProgramARB (MYGL_FRAGMENT_PROGRAM_ARB, this->fprog); this->glProgramStringARB (MYGL_FRAGMENT_PROGRAM_ARB, MYGL_PROGRAM_FORMAT_ASCII_ARB, strlen (fragprog_yuv), fragprog_yuv); glGetIntegerv (MYGL_PROGRAM_ERROR_POSITION_ARB, &errorpos); if (errorpos != -1) xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: fragprog_yuv errorpos %d beginning with '%.20s'. Ask a wizard.\n", errorpos, fragprog_yuv+errorpos); glEnable (MYGL_FRAGMENT_PROGRAM_ARB); CHECKERR ("fragprog"); return ret; } /* * List of render backends */ /* name, display, image, setup, needsrgb, defaction, fallback */ static const opengl_render_t opengl_rb[] = { { "2D_Tex_Fragprog", render_tex2d, render_image_fp_yuv, render_setup_fp_yuv, 0, RENDER_NONE, 1 }, { "2D_Tex", render_tex2d, render_image_tex, render_setup_tex2d, 1, RENDER_NONE, 2 }, { "2D_Tex_Tiled", render_tex2dtiled, render_image_tiledtex, render_setup_tex2d, 1, RENDER_NONE, 3 }, { "Image_Pipeline", render_draw, render_image_nop, render_setup_2d, 1, RENDER_NONE, -1 }, { "Cylinder", render_cyl, render_image_tex, render_setup_cyl, 1, RENDER_DRAW, 1 }, { "Env_Mapped_Torus", render_env_tor, render_image_envtex, render_setup_torus, 1, RENDER_DRAW, 1 } } ; /* * GFX state management */ static void render_gfx_vinfo (opengl_driver_t *this) { static int glxAttrib[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 1, None, None } ; if (this->render_double_buffer) glxAttrib[9] = GLX_DOUBLEBUFFER; else glxAttrib[9] = None; if (this->vinfo) XFree(this->vinfo); this->vinfo = glXChooseVisual (this->display, this->screen, glxAttrib); CHECKERR ("choosevisual"); } /* * Render thread */ static void *render_run (opengl_driver_t *this) { int action, changed; int ret; opengl_frame_t *frame; struct timeval curtime; struct timespec timeout; const opengl_render_t *render; lprintf ("* render thread created\n"); while (1) { /* Wait for render action */ pthread_mutex_lock (&this->render_action_mutex); if (! this->render_action) { this->render_action = opengl_rb[this->render_fun_id].defaction; if (this->render_action) { /* we have to animate even static images */ gettimeofday (&curtime, NULL); timeout.tv_nsec = 1000 * curtime.tv_usec + 1e9L / this->render_min_fps; timeout.tv_sec = curtime.tv_sec; if (timeout.tv_nsec > 1e9L) { timeout.tv_nsec -= 1e9L; timeout.tv_sec += 1; } pthread_cond_timedwait (&this->render_action_cond, &this->render_action_mutex, &timeout); } else { pthread_cond_wait (&this->render_action_cond, &this->render_action_mutex); } } action = this->render_action; changed = this->render_frame_changed; render = &opengl_rb[this->render_fun_id]; /* frame may be updated/deleted outside mutex, but still atomically */ /* we do not (yet) care to check frames for validity - this is a race.. */ /* but we do not delete/change frames for at least 4 frames after update */ frame = this->frame[0]; lprintf ("* render action: %d frame %d changed %d drawable %lx context %lx\n", action, frame ? frame->vo_frame.id : -1, changed, this->drawable, (unsigned long) this->context); switch (action) { case RENDER_NONE: pthread_mutex_unlock (&this->render_action_mutex); break; case RENDER_DRAW: this->render_action = RENDER_NONE; this->render_frame_changed = 0; if (this->context && frame) { /* update fragprog if color matrix changed */ if (this->render_fun_id == 0) { int cm = cm_from_frame ((vo_frame_t *)frame); if (cm != this->cm_fragprog) { this->cm_fragprog = cm; this->render_action = RENDER_SETUP; pthread_mutex_unlock (&this->render_action_mutex); break; } } pthread_mutex_unlock (&this->render_action_mutex); XLockDisplay (this->display); CHECKERR ("pre-render"); ret = 1; if (changed) ret = (render->image) (this, frame); (render->display) (this, frame); if (this->render_double_buffer) glXSwapBuffers(this->display, this->drawable); else glFlush (); /* Note: no glFinish() - work concurrently to the graphics pipe */ CHECKERR ("post-render"); XUnlockDisplay (this->display); if (! ret) { xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: rendering '%s' failed, switching to fallback\n", render->name); if (render->fallback != -1 && this->gl_exts) this->config->update_num (this->config, "video.output.opengl_renderer", render->fallback); } } else { pthread_mutex_unlock (&this->render_action_mutex); } break; case RENDER_CLEAN: this->render_action = RENDER_DRAW; this->render_frame_changed = 0; pthread_mutex_unlock (&this->render_action_mutex); if (this->context && frame) { XLockDisplay (this->display); CHECKERR ("pre-clean"); ret = 1; if (changed) ret = (render->image) (this, frame); if (this->render_double_buffer) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); (render->display) (this, frame); glXSwapBuffers(this->display, this->drawable); } glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glFlush (); CHECKERR ("post-clean"); XUnlockDisplay (this->display); if (! ret) { xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: rendering '%s' failed, switching to fallback\n", render->name); if (render->fallback != -1 && this->gl_exts) this->config->update_num (this->config, "video.output.opengl_renderer", render->fallback); } } break; case RENDER_SETUP: this->render_action = RENDER_CLEAN; this->render_frame_changed = 1; pthread_mutex_unlock (&this->render_action_mutex); if (this->context) { XLockDisplay (this->display); xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: setup of '%s'\n", render->name); if (! (render->setup) (this)) { xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: setup of '%s' failed, switching to fallback\n", render->name); if (render->fallback != -1 && this->gl_exts) this->config->update_num (this->config, "video.output.opengl_renderer", render->fallback); } XUnlockDisplay (this->display); this->tex_width = this->tex_height = 0; } break; case RENDER_CREATE: this->render_action = RENDER_SETUP; this->gl_exts = NULL; _x_assert (this->vinfo); _x_assert (! this->context); XLockDisplay (this->display); glXMakeCurrent (this->display, None, NULL); this->context = glXCreateContext (this->display, this->vinfo, NULL, True); if (this->context) { glXMakeCurrent (this->display, this->drawable, this->context); CHECKERR ("create+makecurrent"); } XUnlockDisplay (this->display); pthread_cond_signal (&this->render_return_cond); pthread_mutex_unlock (&this->render_action_mutex); break; case RENDER_VISUAL: this->render_action = RENDER_NONE; XLockDisplay (this->display); render_gfx_vinfo (this); XUnlockDisplay (this->display); if (this->vinfo == NULL) xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: no OpenGL support available (glXChooseVisual)\n"); else lprintf ("* visual %p id %lx depth %d\n", (void*)this->vinfo->visual, this->vinfo->visualid, this->vinfo->depth); pthread_cond_signal (&this->render_return_cond); pthread_mutex_unlock (&this->render_action_mutex); break; case RENDER_RELEASE: this->render_action = RENDER_NONE; if (this->context) { XLockDisplay (this->display); glXMakeCurrent (this->display, None, NULL); glXDestroyContext (this->display, this->context); CHECKERR ("release"); XUnlockDisplay (this->display); this->context = NULL; } pthread_cond_signal (&this->render_return_cond); pthread_mutex_unlock (&this->render_action_mutex); break; case RENDER_EXIT: pthread_mutex_unlock (&this->render_action_mutex); if (this->context) { XLockDisplay (this->display); glXMakeCurrent (this->display, None, NULL); glXDestroyContext (this->display, this->context); CHECKERR ("exit"); XUnlockDisplay (this->display); } pthread_exit (NULL); break; default: this->render_action = RENDER_NONE; pthread_mutex_unlock (&this->render_action_mutex); _x_assert (!action); /* unknown action */ } lprintf ("* render action: %d frame %d done\n", action, frame ? frame->vo_frame.id : -1); } /* NOTREACHED */ return NULL; } /* * and now, the driver functions */ static uint32_t opengl_get_capabilities (vo_driver_t *this_gen) { /* opengl_driver_t *this = (opengl_driver_t *) this_gen; */ uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE; /* TODO: somehow performance goes down during the first few frames */ /* if (this->xoverlay) */ /* capabilities |= VO_CAP_UNSCALED_OVERLAY; */ (void)this_gen; return capabilities; } static void opengl_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { opengl_frame_t *frame = (opengl_frame_t *) vo_img ; opengl_driver_t *this = (opengl_driver_t *) vo_img->driver; int cm; vo_img->proc_called = 1; if (! frame->rgb_dst) return; /* lprintf ("%p: frame_copy src %p=%p to %p\n", frame, src[0], frame->chunk[0], frame->rgb_dst); */ if( frame->vo_frame.crop_left || frame->vo_frame.crop_top || frame->vo_frame.crop_right || frame->vo_frame.crop_bottom ) { /* TODO: opengl *could* support this?!? */ /* cropping will be performed by video_out.c */ return; } cm = cm_from_frame (vo_img); if (cm != this->cm_yuv2rgb) { this->cm_yuv2rgb = cm; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->brightness, this->contrast, this->saturation, cm); xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_opengl: b %d c %d s %d [%s]\n", this->brightness, this->contrast, this->saturation, cm_names[cm]); } if (frame->format == XINE_IMGFMT_YV12) frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0], src[1], src[2]); else frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0]); /* lprintf ("frame_copy...done\n"); */ } static void opengl_frame_field (vo_frame_t *vo_img, int which_field) { opengl_frame_t *frame = (opengl_frame_t *) vo_img ; opengl_driver_t *this = (opengl_driver_t *) vo_img->driver; /* lprintf ("%p: frame_field rgb %p which_field %x\n", frame, frame->rgb, which_field); */ if (! opengl_rb[this->render_fun_id].needsrgb) { frame->rgb_dst = NULL; return; } switch (which_field) { case VO_TOP_FIELD: frame->rgb_dst = (uint8_t *)frame->rgb; break; case VO_BOTTOM_FIELD: frame->rgb_dst = (uint8_t *)frame->rgb + frame->width * BYTES_PER_PIXEL; break; case VO_BOTH_FIELDS: frame->rgb_dst = (uint8_t *)frame->rgb; break; } frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL); /* lprintf ("frame_field...done\n"); */ } static void opengl_frame_dispose (vo_frame_t *vo_img) { opengl_frame_t *frame = (opengl_frame_t *) vo_img ; frame->yuv2rgb->dispose (frame->yuv2rgb); xine_free_aligned (frame->vo_frame.base[0]); xine_free_aligned (frame->vo_frame.base[1]); xine_free_aligned (frame->vo_frame.base[2]); xine_free_aligned (frame->rgb); pthread_mutex_destroy (&frame->vo_frame.mutex); free (frame); } static vo_frame_t *opengl_alloc_frame (vo_driver_t *this_gen) { opengl_frame_t *frame; opengl_driver_t *this = (opengl_driver_t *) this_gen; frame = (opengl_frame_t *) calloc(1, sizeof(opengl_frame_t)); if (!frame) return NULL; /* * colorspace converter for this frame */ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory); if (!frame->yuv2rgb) { free(frame); return NULL; } pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions/fields */ frame->vo_frame.proc_slice = opengl_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = opengl_frame_field; frame->vo_frame.dispose = opengl_frame_dispose; frame->vo_frame.driver = this_gen; return (vo_frame_t *) frame; } static void opengl_compute_ideal_size (opengl_driver_t *this) { _x_vo_scale_compute_ideal_size( &this->sc ); } static void opengl_compute_rgb_size (opengl_driver_t *this) { _x_vo_scale_compute_output_size( &this->sc ); } static void opengl_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { opengl_driver_t *this = (opengl_driver_t *) this_gen; opengl_frame_t *frame = (opengl_frame_t *) frame_gen; int g_width, g_height; double g_pixel_aspect; int changed = 0; /* Check output size to signal render thread output size changes */ this->sc.dest_size_cb (this->sc.user_data, width, height, this->sc.video_pixel_aspect, &g_width, &g_height, &g_pixel_aspect); /* lprintf ("update_frame_format %dx%d output %dx%d\n", width, height, g_width, g_height); */ if (g_width != this->gui_width || g_height != this->gui_height) { this->gui_width = g_width; this->gui_height = g_height; pthread_mutex_lock (&this->render_action_mutex); if (this->render_action <= RENDER_SETUP) { this->render_action = RENDER_SETUP; pthread_cond_signal (&this->render_action_cond); } pthread_mutex_unlock (&this->render_action_mutex); } /* Check frame size and format and reallocate if necessary */ if ((frame->width != (int)width) || (frame->height != (int)height) || (frame->format != format)) { /* lprintf ("updating frame to %d x %d (ratio=%g, format=%08x)\n", width, height, ratio, format); */ /* make sure we dont pull the rug from under the renderer */ XLockDisplay (this->display); /* (re-) allocate render space */ xine_freep_aligned(&frame->vo_frame.base[0]); xine_freep_aligned(&frame->vo_frame.base[1]); xine_freep_aligned(&frame->vo_frame.base[2]); xine_freep_aligned(&frame->rgb); if (format == XINE_IMGFMT_YV12) { frame->vo_frame.pitches[0] = 8*((width + 7) / 8); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = xine_mallocz_aligned(frame->vo_frame.pitches[1] * ((height+1)/2)); frame->vo_frame.base[2] = xine_mallocz_aligned(frame->vo_frame.pitches[2] * ((height+1)/2)); } else { frame->vo_frame.pitches[0] = 8*((width + 3) / 4); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); } frame->rgb = xine_mallocz_aligned(BYTES_PER_PIXEL*width*height); changed = 1; } else if ((frame->flags ^ flags) & VO_BOTH_FIELDS) { XLockDisplay (this->display); changed = 1; } frame->flags = flags; if (changed) { flags &= VO_BOTH_FIELDS; /* set up colorspace converter */ switch (flags) { case VO_TOP_FIELD: case VO_BOTTOM_FIELD: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, 2*frame->vo_frame.pitches[0], 2*frame->vo_frame.pitches[1], width, height, BYTES_PER_PIXEL*width * 2); break; case VO_BOTH_FIELDS: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, frame->vo_frame.pitches[0], frame->vo_frame.pitches[1], width, height, BYTES_PER_PIXEL*width); break; } frame->width = width; frame->height = height; frame->format = format; XUnlockDisplay (this->display); opengl_frame_field ((vo_frame_t *)frame, flags); } frame->ratio = ratio; /* lprintf ("done...update_frame_format\n"); */ } static void opengl_overlay_clut_yuv2rgb(opengl_driver_t *this, vo_overlay_t *overlay, opengl_frame_t *frame) { int i; uint32_t *rgb; (void)this; if (!overlay->rgb_clut) { rgb = overlay->color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->rgb_clut++; } if (!overlay->hili_rgb_clut) { rgb = overlay->hili_color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->hili_rgb_clut++; } } static void opengl_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { opengl_driver_t *this = (opengl_driver_t *) this_gen; this->ovl_changed += changed; if (this->ovl_changed && this->xoverlay) { XLockDisplay (this->display); x11osd_clear(this->xoverlay); XUnlockDisplay (this->display); } this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void opengl_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { opengl_driver_t *this = (opengl_driver_t *) this_gen; (void)vo_img; if (this->ovl_changed && this->xoverlay) { XLockDisplay (this->display); x11osd_expose(this->xoverlay); XUnlockDisplay (this->display); } this->ovl_changed = 0; } static void opengl_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { opengl_driver_t *this = (opengl_driver_t *) this_gen; opengl_frame_t *frame = (opengl_frame_t *) frame_gen; /* Alpha Blend here */ if (overlay->rle) { if (overlay->unscaled) { if (this->ovl_changed && this->xoverlay) { XLockDisplay (this->display); x11osd_blend (this->xoverlay, overlay); XUnlockDisplay (this->display); } } else { if (!frame->rgb_dst) { if (frame->format == XINE_IMGFMT_YV12) { _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); } else { _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } return; } if (!overlay->rgb_clut || !overlay->hili_rgb_clut) opengl_overlay_clut_yuv2rgb (this, overlay, frame); # if BYTES_PER_PIXEL == 3 _x_blend_rgb24 ((uint8_t *)frame->rgb, overlay, frame->width, frame->height, frame->width, frame->height, &this->alphablend_extra_data); # elif BYTES_PER_PIXEL == 4 _x_blend_rgb32 ((uint8_t *)frame->rgb, overlay, frame->width, frame->height, frame->width, frame->height, &this->alphablend_extra_data); # else # error "bad BYTES_PER_PIXEL" # endif } } } static int opengl_redraw_needed (vo_driver_t *this_gen) { opengl_driver_t *this = (opengl_driver_t *) this_gen; int ret = 0; /* lprintf ("redraw_needed\n"); */ if (this->frame[0]) { this->sc.delivered_height = this->frame[0]->height; this->sc.delivered_width = this->frame[0]->width; this->sc.delivered_ratio = this->frame[0]->ratio; this->sc.crop_left = this->frame[0]->vo_frame.crop_left; this->sc.crop_right = this->frame[0]->vo_frame.crop_right; this->sc.crop_top = this->frame[0]->vo_frame.crop_top; this->sc.crop_bottom = this->frame[0]->vo_frame.crop_bottom; opengl_compute_ideal_size(this); if( _x_vo_scale_redraw_needed( &this->sc ) ) { opengl_compute_rgb_size(this); pthread_mutex_lock (&this->render_action_mutex); if (this->render_action <= RENDER_CLEAN) { this->render_action = RENDER_CLEAN; pthread_cond_signal (&this->render_action_cond); } pthread_mutex_unlock (&this->render_action_mutex); ret = 1; } } else ret = 1; /* lprintf ("done...redraw_needed: %d\n", ret); */ return ret; } static void opengl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { opengl_driver_t *this = (opengl_driver_t *) this_gen; opengl_frame_t *frame = (opengl_frame_t *) frame_gen; int i; /* lprintf ("about to draw frame (%d) %d x %d...\n", frame->vo_frame.id, frame->width, frame->height); */ /* lprintf ("video_out_opengl: freeing frame %d\n", this->frame[NUM_FRAMES_BACKLOG-1] ? this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame.id : -1); */ if (this->frame[NUM_FRAMES_BACKLOG-1]) this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame.free (&this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame); for (i = NUM_FRAMES_BACKLOG-1; i > 0; i--) this->frame[i] = this->frame[i-1]; this->frame[0] = frame; this->render_frame_changed = 1; /* lprintf ("video_out_opengl: cur_frame updated to %d\n", frame->vo_frame.id); */ /* * let's see if this frame is different in size / aspect * ratio from the previous one */ if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) ) { /* lprintf("frame format changed\n"); */ this->sc.force_redraw = 1; /* trigger re-calc of output size */ } /* * tell gui that we are about to display a frame, * ask for offset and output size */ opengl_redraw_needed (this_gen); pthread_mutex_lock (&this->render_action_mutex); if (this->render_action <= RENDER_DRAW) { this->render_action = RENDER_DRAW; pthread_cond_signal (&this->render_action_cond); } pthread_mutex_unlock (&this->render_action_mutex); /* lprintf ("display frame done\n"); */ } static int opengl_get_property (vo_driver_t *this_gen, int property) { opengl_driver_t *this = (opengl_driver_t *) this_gen; switch (property) { case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; case VO_PROP_MAX_NUM_FRAMES: return 15; case VO_PROP_BRIGHTNESS: return this->brightness; case VO_PROP_CONTRAST: return this->contrast; case VO_PROP_SATURATION: return this->saturation; case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_opengl: tried to get unsupported property %d\n", property); } return 0; } static int opengl_set_property (vo_driver_t *this_gen, int property, int value) { opengl_driver_t *this = (opengl_driver_t *) this_gen; switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) { int i, n = 0; for (i = NUM_FRAMES_BACKLOG - 1; i >= 0; i--) { if (this->frame[i]) { this->frame[i]->vo_frame.free (&this->frame[i]->vo_frame); this->frame[i] = NULL; n++; } } value = n; } break; case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; opengl_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_opengl: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); break; case VO_PROP_BRIGHTNESS: this->brightness = value; this->cm_yuv2rgb = 0; this->cm_fragprog = 0; this->sc.force_redraw = 1; break; case VO_PROP_CONTRAST: this->contrast = value; this->cm_yuv2rgb = 0; this->cm_fragprog = 0; this->sc.force_redraw = 1; break; case VO_PROP_SATURATION: this->saturation = value; this->cm_yuv2rgb = 0; this->cm_fragprog = 0; this->sc.force_redraw = 1; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_opengl: tried to set unsupported property %d\n", property); } return value; } static void opengl_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { /* opengl_driver_t *this = (opengl_driver_t *) this_gen; */ (void)this_gen; switch (property) { case VO_PROP_BRIGHTNESS: *min = -128; *max = 127; break; case VO_PROP_CONTRAST: *min = 0; *max = 255; break; case VO_PROP_SATURATION: *min = 0; *max = 255; break; default: *min = 0; *max = 0; } } static int opengl_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { opengl_driver_t *this = (opengl_driver_t *) this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: /* lprintf ("expose event\n"); */ if (this->frame[0]) { XExposeEvent * xev = (XExposeEvent *) data; if (xev && xev->count == 0) { pthread_mutex_lock (&this->render_action_mutex); if (this->render_action <= RENDER_CLEAN) { this->render_action = RENDER_CLEAN; pthread_cond_signal (&this->render_action_cond); } pthread_mutex_unlock (&this->render_action_mutex); XLockDisplay (this->display); if(this->xoverlay) x11osd_expose(this->xoverlay); XSync(this->display, False); XUnlockDisplay (this->display); } } break; case XINE_GUI_SEND_SELECT_VISUAL: pthread_mutex_lock (&this->render_action_mutex); this->render_action = RENDER_VISUAL; pthread_cond_signal (&this->render_action_cond); pthread_cond_wait (&this->render_return_cond, &this->render_action_mutex); pthread_mutex_unlock (&this->render_action_mutex); *(XVisualInfo**)data = this->vinfo; break; case XINE_GUI_SEND_WILL_DESTROY_DRAWABLE: pthread_mutex_lock (&this->render_action_mutex); this->render_action = RENDER_RELEASE; pthread_cond_signal (&this->render_action_cond); pthread_cond_wait (&this->render_return_cond, &this->render_action_mutex); pthread_mutex_unlock (&this->render_action_mutex); break; case XINE_GUI_SEND_DRAWABLE_CHANGED: pthread_mutex_lock (&this->render_action_mutex); this->render_action = RENDER_RELEASE; pthread_cond_signal (&this->render_action_cond); pthread_cond_wait (&this->render_return_cond, &this->render_action_mutex); this->drawable = (Drawable) data; this->render_action = RENDER_CREATE; pthread_cond_signal (&this->render_action_cond); pthread_cond_wait (&this->render_return_cond, &this->render_action_mutex); pthread_mutex_unlock (&this->render_action_mutex); if (! this->context) xprintf (this->xine, XINE_VERBOSITY_NONE, "video_out_opengl: cannot create OpenGL capable visual.\n" " plugin will not work.\n"); XLockDisplay (this->display); if(this->xoverlay) x11osd_drawable_changed(this->xoverlay, this->drawable); this->ovl_changed = 1; XUnlockDisplay (this->display); break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: if (this->frame[0]) { x11_rectangle_t *rect = data; int x1, y1, x2, y2; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void opengl_dispose_internal (opengl_driver_t *this, int thread_running) { int i; if (thread_running) { pthread_mutex_lock (&this->render_action_mutex); this->render_action = RENDER_EXIT; pthread_cond_signal (&this->render_action_cond); pthread_mutex_unlock (&this->render_action_mutex); pthread_join (this->render_thread, NULL); } pthread_mutex_destroy (&this->render_action_mutex); pthread_cond_destroy (&this->render_action_cond); pthread_cond_destroy (&this->render_return_cond); for (i = 0; i < NUM_FRAMES_BACKLOG; i++) if (this->frame[i]) this->frame[i]->vo_frame.dispose (&this->frame[i]->vo_frame); this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); cm_close (this); if (this->xoverlay) { XLockDisplay (this->display); x11osd_destroy (this->xoverlay); XUnlockDisplay (this->display); } if (this->vinfo) { XFree(this->vinfo); } _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); free (this); } static void opengl_dispose (vo_driver_t *this_gen) { opengl_driver_t *this = (opengl_driver_t *) this_gen; opengl_dispose_internal(this, 1); } static void opengl_cb_render_fun (void *this_gen, xine_cfg_entry_t *entry) { opengl_driver_t *this = (opengl_driver_t *) this_gen; pthread_mutex_lock (&this->render_action_mutex); this->render_fun_id = entry->num_value; if (this->render_action <= RENDER_SETUP) { this->render_action = RENDER_SETUP; pthread_cond_signal (&this->render_action_cond); } pthread_mutex_unlock (&this->render_action_mutex); } static void opengl_cb_default (void *val_gen, xine_cfg_entry_t *entry) { int *val = (int *) val_gen; *val = entry->num_value; } static vo_driver_t *opengl_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { opengl_class_t *class = (opengl_class_t *) class_gen; config_values_t *config = class->xine->config; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; opengl_driver_t *this; const char **render_fun_names; unsigned int i; this = (opengl_driver_t *) calloc(1, sizeof(opengl_driver_t)); if (!this) return NULL; this->yuv2rgb_factory = yuv2rgb_factory_init (YUV_FORMAT, YUV_SWAP_MODE, NULL); if (!this->yuv2rgb_factory) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": yuv2rgb initialization failed\n"); free(this); return NULL; } this->display = visual->display; this->screen = visual->screen; _x_vo_scale_init (&this->sc, 0, 0, config); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.dest_size_cb = visual->dest_size_cb; this->sc.user_data = visual->user_data; this->sc.user_ratio = XINE_VO_ASPECT_AUTO; _x_alphablend_init (&this->alphablend_extra_data, class->xine); this->drawable = visual->d; this->gui_width = this->gui_height = -1; this->last_width = this->last_height = -1; this->fprog = -1; this->xoverlay = NULL; this->ovl_changed = 0; this->xine = class->xine; this->config = config; this->vo_driver.get_capabilities = opengl_get_capabilities; this->vo_driver.alloc_frame = opengl_alloc_frame; this->vo_driver.update_frame_format = opengl_update_frame_format; this->vo_driver.overlay_begin = opengl_overlay_begin; this->vo_driver.overlay_blend = opengl_overlay_blend; this->vo_driver.overlay_end = opengl_overlay_end; this->vo_driver.display_frame = opengl_display_frame; this->vo_driver.get_property = opengl_get_property; this->vo_driver.set_property = opengl_set_property; this->vo_driver.get_property_min_max = opengl_get_property_min_max; this->vo_driver.gui_data_exchange = opengl_gui_data_exchange; this->vo_driver.dispose = opengl_dispose; this->vo_driver.redraw_needed = opengl_redraw_needed; this->brightness = 0; this->contrast = 128; this->saturation = 128; cm_init (this); XLockDisplay (this->display); this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_SHAPED); XUnlockDisplay (this->display); render_fun_names = calloc((sizeof(opengl_rb)/sizeof(opengl_render_t)+1), sizeof(const char*)); for (i = 0; i < sizeof (opengl_rb) / sizeof (opengl_render_t); i++) render_fun_names[i] = opengl_rb[i].name; render_fun_names[i] = NULL; this->render_fun_id = config->register_enum (config, "video.output.opengl_renderer", 0, (char **)render_fun_names, _("OpenGL renderer"), _("The OpenGL plugin provides several render modules:\n\n" "2D_Tex_Fragprog\n" "This module downloads the images as YUV 2D textures and renders a textured slice\n" "using fragment programs for reconstructing RGB.\n" "This is the best and fastest method on modern graphics cards.\n\n" "2D_Tex\n" "This module downloads the images as 2D textures and renders a textured slice.\n" "2D_Tex_Tiled\n" "This module downloads the images as multiple 2D textures and renders a textured\n" "slice. Thus this works with smaller maximum texture sizes as well.\n" "Image_Pipeline\n" "This module uses glDraw() to render the images.\n" "Only accelerated on few drivers.\n" "Does not interpolate on scaling.\n\n" "Cylinder\n" "Shows images on a rotating cylinder. Nice effect :)\n\n" "Environment_Mapped_Torus\n" "Show images reflected in a spinning torus. Way cool =)"), 10, opengl_cb_render_fun, this); free(render_fun_names); this->render_min_fps = config->register_range (config, "video.output.opengl_min_fps", 20, 1, 120, _("OpenGL minimum framerate"), _("Minimum framerate for animated render routines.\n" "Ignored for static render routines.\n"), 20, opengl_cb_default, &this->render_min_fps); this->render_double_buffer = config->register_bool (config, "video.device.opengl_double_buffer", 1, _("enable double buffering"), _("For OpenGL double buffering does not only remove tearing artifacts,\n" "it also reduces flickering a lot.\n" "It should not have any performance impact."), 20, NULL, NULL); pthread_mutex_init (&this->render_action_mutex, NULL); pthread_cond_init (&this->render_action_cond, NULL); pthread_cond_init (&this->render_return_cond, NULL); if (pthread_create (&this->render_thread, NULL, (thread_run_t) render_run, this)) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": pthread_create() failed\n"); opengl_dispose_internal (this, 0); return NULL; } /* Check for OpenGL capable visual */ pthread_mutex_lock (&this->render_action_mutex); this->render_action = RENDER_VISUAL; pthread_cond_signal (&this->render_action_cond); pthread_cond_wait (&this->render_return_cond, &this->render_action_mutex); if (this->vinfo) { /* Create context if possible w/o drawable change */ this->render_action = RENDER_CREATE; pthread_cond_signal (&this->render_action_cond); pthread_cond_wait (&this->render_return_cond, &this->render_action_mutex); } pthread_mutex_unlock (&this->render_action_mutex); if (! this->vinfo) { /* no OpenGL capable visual available */ opengl_dispose_internal (this, 1); return NULL; } if (! this->context) xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_opengl: default visual not OpenGL capable\n" " plugin will only work with clients supporting XINE_GUI_SEND_SELECT_VISUAL.\n"); return &this->vo_driver; } /* * class functions */ static int opengl_verify_direct (x11_visual_t *vis) { int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, None }; Window root, win; XVisualInfo *visinfo; GLXContext ctx; XSetWindowAttributes xattr; int ret = 0; if (!vis || !vis->display || ! (root = RootWindow (vis->display, vis->screen))) { fprintf (stderr, "[videoout_opengl]: Don't have a root window to verify\n"); return 0; } if (! (visinfo = glXChooseVisual (vis->display, vis->screen, attribs))) return 0; if (! (ctx = glXCreateContext (vis->display, visinfo, NULL, 1))) { XFree(visinfo); return 0; } memset (&xattr, 0, sizeof (xattr)); xattr.colormap = XCreateColormap(vis->display, root, visinfo->visual, AllocNone); xattr.event_mask = StructureNotifyMask | ExposureMask; if ( (win = XCreateWindow (vis->display, root, 0, 0, 1, 1, 0, visinfo->depth, InputOutput, visinfo->visual, CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &xattr))) { if (glXMakeCurrent (vis->display, win, ctx)) { const char *renderer = (const char *) glGetString(GL_RENDERER); if (glXIsDirect (vis->display, ctx) && ! strstr (renderer, "Software") && ! strstr (renderer, "Indirect")) ret = 1; glXMakeCurrent (vis->display, None, NULL); } XDestroyWindow (vis->display, win); } glXDestroyContext (vis->display, ctx); XFreeColormap (vis->display, xattr.colormap); XFree (visinfo); return ret; } static void *opengl_init_class (xine_t *xine, const void *visual_gen) { opengl_class_t *this; xprintf (xine, XINE_VERBOSITY_LOG, "video_out_opengl: Testing for hardware accelerated direct rendering visual\n"); if (! opengl_verify_direct ((x11_visual_t *)visual_gen)) { xprintf (xine, XINE_VERBOSITY_LOG, "video_out_opengl: Didn't find any\n"); return NULL; } this = calloc (1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = opengl_open_plugin; this->driver_class.identifier = "opengl"; this->driver_class.description = N_("xine video output plugin using the OpenGL 3D graphics API"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_opengl = { .priority = 7, .visual_type = XINE_VISUAL_TYPE_X11, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "opengl", XINE_VERSION_CODE, &vo_info_opengl, opengl_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/hw_frame.h0000644000175000017500000000434214647725152015414 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2021-2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * hw_frame.h, Interface between video output and HW decoders * */ #ifndef XINE_HW_FRAME_H_ #define XINE_HW_FRAME_H_ #include #include struct mem_frame_t; struct xine_gl; typedef struct xine_glconv_t xine_glconv_t; struct xine_glconv_t { int (*get_textures)(xine_glconv_t *, vo_frame_t *, unsigned target, unsigned *textures, unsigned *textures_count, unsigned *sw_format); void (*destroy) (xine_glconv_t **); }; typedef struct xine_hwdec_t xine_hwdec_t; struct xine_hwdec_t { int frame_format; /* Frame format (XINE_IMGFMT_*) */ uint32_t driver_capabilities; /* VO_CAP_* */ struct mem_frame_t *(*alloc_frame) (xine_hwdec_t *); void (*update_frame_format) (vo_driver_t *vo_driver, vo_frame_t *vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags); void (*destroy) (xine_hwdec_t **); xine_glconv_t *(*opengl_interop) (xine_hwdec_t *, struct xine_gl *); }; xine_hwdec_t *_x_hwdec_new(xine_t *xine, vo_driver_t *vo_driver, unsigned visual_type, const void *visual, unsigned flags); #endif /* XINE_HW_FRAME_H_ */ xine-lib-1.2/src/video_out/mem_frame.h0000644000175000017500000001364714647725152015564 0ustar meme/* * Copyright (C) 2012-2022 the xine project * Copyright (C) 2012 Christophe Thommeret * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * * mem_frame.h, generic memory backed frame * * */ #ifndef XINE_MEM_FRAME_H #define XINE_MEM_FRAME_H #include typedef struct mem_frame_t { vo_frame_t vo_frame; int width, height, format, flags; double ratio; } mem_frame_t; static void _mem_frame_proc_slice(vo_frame_t *vo_img, uint8_t **src) { (void)src; vo_img->proc_called = 1; } static void _mem_frame_field(vo_frame_t *vo_img, int which_field) { (void)vo_img; (void)which_field; } static void _mem_frame_free_framedata(vo_frame_t *vo_img) { xine_freep_aligned (&vo_img->base[0]); vo_img->base[1] = NULL; vo_img->base[2] = NULL; vo_img->pitches[0] = vo_img->pitches[1] = vo_img->pitches[2] = 0; } static void _mem_frame_dispose(vo_frame_t *vo_img) { _mem_frame_free_framedata(vo_img); pthread_mutex_destroy (&vo_img->mutex); free (vo_img); } static void _mem_frame_init(mem_frame_t *frame, vo_driver_t *driver) { frame->vo_frame.base[0] = frame->vo_frame.base[1] = frame->vo_frame.base[2] = NULL; frame->width = frame->height = frame->format = frame->flags = 0; frame->ratio = 0.0; pthread_mutex_init (&frame->vo_frame.mutex, NULL); frame->vo_frame.proc_slice = _mem_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = _mem_frame_field; frame->vo_frame.dispose = _mem_frame_dispose; frame->vo_frame.driver = driver; } static vo_frame_t *_mem_frame_alloc_frame(vo_driver_t *this_gen, size_t frame_size) { mem_frame_t *frame; frame = calloc(1, frame_size); if (!frame) return NULL; _mem_frame_init(frame, this_gen); return &frame->vo_frame; } static inline vo_frame_t *mem_frame_alloc_frame(vo_driver_t *this_gen) { return _mem_frame_alloc_frame(this_gen, sizeof(mem_frame_t)); } static inline void *_memset32(void *mem, uint32_t val, size_t n) { uint32_t *m32 = mem, *ret = mem; size_t i; for (i = n; i; i--) *m32++ = val; return ret; } static inline void mem_frame_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { mem_frame_t *frame = xine_container_of(frame_gen, mem_frame_t, vo_frame); (void)this_gen; /* vo_none and vo_opengl2 need no buffer adjustment for these. */ frame->flags = flags; frame->ratio = ratio; /* Check frame size and format and reallocate if necessary (rare case). */ if (!((frame->width ^ width) | (frame->height ^ height) | (frame->format ^ format))) return; frame->width = width; frame->height = height; frame->format = format; /* (re-) allocate render space */ _mem_frame_free_framedata(frame_gen); if (format == XINE_IMGFMT_YV12) { uint32_t w = (width + 15) & ~15; uint32_t ysize = w * height; uint32_t uvsize = (w >> 1) * ((height + 1) >> 1); frame->vo_frame.base[0] = xine_malloc_aligned (ysize + 2 * uvsize); if (frame->vo_frame.base[0]) { frame->vo_frame.base[1] = frame->vo_frame.base[0] + ysize; frame->vo_frame.base[2] = frame->vo_frame.base[1] + uvsize; frame->vo_frame.pitches[0] = w; frame->vo_frame.pitches[1] = w >> 1; frame->vo_frame.pitches[2] = w >> 1; memset (frame->vo_frame.base[0], 0, ysize); memset (frame->vo_frame.base[1], 128, 2 * uvsize); } } else if (format == XINE_IMGFMT_YV12_DEEP) { unsigned w = (width + 15) & ~15; unsigned ysize = 2 * w * height; unsigned uvsize = w * ((height + 1) >> 1); frame->vo_frame.base[0] = xine_malloc_aligned (ysize + 2 * uvsize); if (frame->vo_frame.base[0]) { unsigned depth = VO_GET_FLAGS_DEPTH(flags); uint32_t black = 0x00010001U * (1U << (depth - 1)); frame->vo_frame.base[1] = frame->vo_frame.base[0] + ysize; frame->vo_frame.base[2] = frame->vo_frame.base[1] + uvsize; frame->vo_frame.pitches[0] = w * 2; frame->vo_frame.pitches[1] = w; frame->vo_frame.pitches[2] = w; memset (frame->vo_frame.base[0], 0, ysize); _memset32 (frame->vo_frame.base[1], black, 2 * uvsize / sizeof(uint32_t)); } } else if (format == XINE_IMGFMT_NV12) { uint32_t w = (width + 15) & ~15; uint32_t ysize = w * height; uint32_t uvsize = w * ((height + 1) >> 1); frame->vo_frame.base[0] = xine_malloc_aligned (ysize + uvsize); if (frame->vo_frame.base[0]) { frame->vo_frame.base[1] = frame->vo_frame.base[0] + ysize; frame->vo_frame.pitches[0] = w; frame->vo_frame.pitches[1] = w; memset (frame->vo_frame.base[0], 0, ysize); memset (frame->vo_frame.base[1], 128, uvsize); } } else if (format == XINE_IMGFMT_YUY2) { uint32_t w = (width + 15) & ~15; frame->vo_frame.base[0] = xine_malloc_aligned ((w << 1) * height); if (frame->vo_frame.base[0]) { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; frame->vo_frame.pitches[0] = w << 1; _memset32 (frame->vo_frame.base[0], black.word, frame->vo_frame.pitches[0] * height / sizeof(uint32_t)); } } if (!frame->vo_frame.base[0]) { /* tell vo_get_frame () to retry later */ frame->width = 0; frame->vo_frame.width = 0; } } #endif /* XINE_MEM_FRAME_H */ xine-lib-1.2/src/video_out/vaapi/0000755000175000017500000000000014647725152014550 5ustar memexine-lib-1.2/src/video_out/vaapi/vaapi_frame.h0000644000175000017500000001061514647725152017176 0ustar meme/* * Copyright (C) 2012 Edgar Hucek * Copyright (C) 2012-2022 xine developers * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vaapi_frame.c, VAAPI video extension interface for xine * */ #ifndef XINE_VAAPI_FRAME_H #define XINE_VAAPI_FRAME_H #include #include "accel_vaapi.h" #include "vaapi_util.h" #include "../mem_frame.h" typedef struct { mem_frame_t mem_frame; vaapi_accel_t vaapi_accel_data; vaapi_context_impl_t *ctx_impl; } vaapi_frame_t; vaapi_frame_t *_x_va_frame_alloc_frame (vaapi_context_impl_t *va, vo_driver_t *driver, int guarded_render); void _x_va_frame_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags); void _x_va_frame_provide_standard_frame_data (vo_frame_t *vo_frame, xine_current_frame_data_t *data); void _x_va_frame_duplicate_frame_data (vo_frame_t *this_gen, vo_frame_t *original); /* * */ static inline vaapi_context_impl_t *_ctx_from_frame(vo_frame_t *vo_frame) { vaapi_frame_t *frame = xine_container_of(vo_frame, vaapi_frame_t, mem_frame.vo_frame); return frame->ctx_impl; } /* * accel */ static inline int _x_va_accel_profile_from_imgfmt(vo_frame_t *vo_frame, unsigned format) { vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); return _x_va_profile_from_imgfmt(va, format); } static inline ff_vaapi_context_t *_x_va_accel_get_context(vo_frame_t *vo_frame) { vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); return &va->c; } static inline int _x_va_accel_vaapi_init(vo_frame_t *vo_frame, int va_profile, int width, int height) { vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); return _x_va_init(va, va_profile, width, height); } static inline int _x_va_accel_guarded_render(vo_frame_t *vo_frame) { vaapi_accel_t *accel = vo_frame->accel_data; return accel->f->render_vaapi_surface != NULL; } /* * non-guarded mode */ static inline int _x_va_accel_lock_decode_dummy(vo_frame_t *vo_frame) { (void)vo_frame; return 0; } static inline ff_vaapi_surface_t *_x_va_accel_get_vaapi_surface(vo_frame_t *vo_frame) { vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); vaapi_accel_t *accel = vo_frame->accel_data; _x_assert(accel->index < RENDER_SURFACES); /* index is constant in this mode */ return &va->c.va_render_surfaces[accel->index]; } /* * guarded mode */ static inline ff_vaapi_surface_t *_x_va_accel_alloc_vaapi_surface(vo_frame_t *vo_frame) { vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); return _x_va_alloc_surface(va); } static inline void _x_va_accel_render_vaapi_surface(vo_frame_t *vo_frame, ff_vaapi_surface_t *va_surface) { vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); vaapi_accel_t *accel = vo_frame->accel_data; accel->index = va_surface->index; _x_va_render_surface(va, va_surface); } static inline void _x_va_accel_release_vaapi_surface(vo_frame_t *vo_frame, ff_vaapi_surface_t *va_surface) { /* surface was not binded to this vo_frame */ vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); _x_va_release_surface(va, va_surface); } /* * video out */ static inline void _x_va_frame_displayed(vo_frame_t *vo_frame) { vaapi_context_impl_t *va_context = _ctx_from_frame(vo_frame); vaapi_accel_t *accel = vo_frame->accel_data; if (accel->index < RENDER_SURFACES) { ff_vaapi_surface_t *va_surface = &va_context->c.va_render_surfaces[accel->index]; _x_va_surface_displayed(va_context, va_surface); accel->index = RENDER_SURFACES; /* invalid */ } } #endif /* XINE_VAAPI_UTIL_H */ xine-lib-1.2/src/video_out/vaapi/xine_va_display.c0000644000175000017500000000422114647725152020071 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2018-2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine_va_display.c: VAAPI display plugin loader * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xine_va_display_plugin.h" #include #include #define DISPLAY_PLUGIN(_dpy) xine_container_of(_dpy, xine_va_display_plugin_t, display) /* technically, we can't unload dynamic module from the module itself. * it would work now (nothing is unloaded), but there may be problems in * the future if plugin loader unloads the library in _x_free_module(). */ static void default_va_display_dispose(xine_va_display_t **dpy) { if (*dpy) { xine_va_display_plugin_t *plugin = DISPLAY_PLUGIN(*dpy); xine_module_t *module = &plugin->module; *dpy = NULL; _x_free_module(plugin->xine, &module); } } /* * loader wrapper */ xine_va_display_t *_x_va_display_open(xine_t *xine, unsigned visual_type, const void *visual, unsigned flags) { const va_display_plugin_params_t params = { .xine = xine, .visual_type = visual_type, .visual = visual, .flags = flags, }; xine_va_display_plugin_t *p; p = (xine_va_display_plugin_t*)_x_find_module(xine, VA_DISPLAY_PLUGIN_TYPE, NULL, visual_type, ¶ms); if (p) { p->display.dispose = default_va_display_dispose; return &p->display; } return NULL; } xine-lib-1.2/src/video_out/vaapi/xine_va_display_x11.c0000644000175000017500000000625314647725152020571 0ustar meme/* * Copyright (C) 2022 the xine project * Copyright (C) 2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * VAAPI display for X11 * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "va_display_x11" #include "xine_va_display_plugin.h" #include #include /* visual types */ #include #include #include /* * xine module */ static void _module_dispose(xine_module_t *module) { xine_va_display_plugin_t *p = xine_container_of(module, xine_va_display_plugin_t, module); vaTerminate(p->display.va_display); free(p); } static xine_module_t *_get_instance(xine_module_class_t *class_gen, const void *data) { const va_display_plugin_params_t *params = data; const x11_visual_t *vis_x11 = params->visual; xine_va_display_plugin_t *p; VADisplay dpy = NULL; VAStatus vaStatus; int maj, min; (void)class_gen; if (params->visual_type != XINE_VISUAL_TYPE_X11) return NULL; if (params->flags & XINE_VA_DISPLAY_GLX) return NULL; dpy = vaGetDisplay(vis_x11->display); if (!vaDisplayIsValid(dpy)) return NULL; vaStatus = vaInitialize(dpy, &maj, &min); if (vaStatus != VA_STATUS_SUCCESS) { xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Error: vaInitialize: %s [0x%04x]\n", vaErrorStr(vaStatus), vaStatus); vaTerminate(dpy); return NULL; } p = calloc(1, sizeof(*p)); if (!p) { vaTerminate(dpy); return NULL; } p->xine = params->xine; p->module.dispose = _module_dispose; p->display.va_display = dpy; xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Using libva %d.%d\n", maj, min); return &p->module; } /* * plugin */ static void *_init_class(xine_t *xine, const void *params) { static const xine_module_class_t xine_class = { .get_instance = _get_instance, .description = N_("VA display provider (X11)"), .identifier = "va_display_x11", .dispose = NULL, }; (void)xine; (void)params; return (void *)&xine_class; } static const xine_module_info_t module_info = { .priority = 10, .type = "va_display_v1", .sub_type = XINE_VISUAL_TYPE_X11, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "va_display_x11", XINE_VERSION_CODE, &module_info, _init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }, }; xine-lib-1.2/src/video_out/vaapi/vaapi_util.h0000644000175000017500000000574514647725152017071 0ustar meme/* * Copyright (C) 2012 Edgar Hucek * Copyright (C) 2012-2022 xine developers * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vaapi_util.c, VAAPI video extension interface for xine * */ #ifndef XINE_VAAPI_UTIL_H #define XINE_VAAPI_UTIL_H #include #include "accel_vaapi.h" #include #include /* * */ const char *_x_va_profile_to_string(VAProfile profile); const char *_x_va_entrypoint_to_string(VAEntrypoint entrypoint); void _x_va_reset_va_context(ff_vaapi_context_t *va_context); /* * */ struct xine_va_display_t; typedef struct vaapi_context_impl vaapi_context_impl_t; #define RENDER_SURFACES 50 struct vaapi_context_impl { ff_vaapi_context_t c; xine_t *xine; struct xine_va_display_t *va_display_plugin; int query_va_status; pthread_mutex_t ctx_lock; /* lock init / close / surface usage */ unsigned int num_frames; vo_frame_t *frames[RENDER_SURFACES]; pthread_mutex_t surfaces_lock; unsigned va_head; ff_vaapi_surface_t va_render_surfaces_storage[RENDER_SURFACES + 1]; VASurfaceID va_surface_ids_storage[RENDER_SURFACES + 1]; }; vaapi_context_impl_t *_x_va_new(xine_t *xine, int visual_type, const void *visual, unsigned va_display_flags); void _x_va_free(vaapi_context_impl_t **va_context); int _x_va_check_status(vaapi_context_impl_t *va_context, VAStatus vaStatus, const char *msg); void _x_va_destroy_image(vaapi_context_impl_t *va_context, VAImage *va_image); VAStatus _x_va_create_image(vaapi_context_impl_t *va_context, VASurfaceID va_surface_id, VAImage *va_image, int width, int height, int clear, int *is_bound); int _x_va_profile_from_imgfmt(vaapi_context_impl_t *va_context, unsigned format); /* * surface pool */ void _x_va_close(vaapi_context_impl_t *va_context); VAStatus _x_va_init(vaapi_context_impl_t *va_context, int va_profile, int width, int height); ff_vaapi_surface_t *_x_va_alloc_surface(vaapi_context_impl_t *va_context); void _x_va_render_surface(vaapi_context_impl_t *va_context, ff_vaapi_surface_t *va_surface); void _x_va_release_surface(vaapi_context_impl_t *va_context, ff_vaapi_surface_t *va_surface); void _x_va_surface_displayed(vaapi_context_impl_t *va_context, ff_vaapi_surface_t *va_surface); #endif /* XINE_VAAPI_UTIL_H */ xine-lib-1.2/src/video_out/vaapi/xine_va_display_drm.c0000644000175000017500000001127214647725152020737 0ustar meme/* * Copyright (C) 2022 the xine project * Copyright (C) 2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * VAAPI display for DRM * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "va_display_drm" #include "xine_va_display_plugin.h" #include #include #include #include #include #include /* visual types */ #include #include #include typedef struct { xine_va_display_plugin_t p; int drm_fd; } xine_va_display_impl_t; /* * xine module */ static void _module_dispose(xine_module_t *module) { xine_va_display_impl_t *impl = xine_container_of(module, xine_va_display_impl_t, p.module); vaTerminate(impl->p.display.va_display); close(impl->drm_fd); impl->drm_fd = -1; free(impl); } static xine_module_t *_get_instance(xine_module_class_t *class_gen, const void *data) { const va_display_plugin_params_t *params = data; xine_va_display_impl_t *impl; VADisplay dpy = NULL; VAStatus vaStatus; static const char *default_drm_device[] = { "/dev/dri/renderD128", "/dev/dri/card0", "/dev/dri/renderD129", "/dev/dri/card1", }; int drm_fd = -1, maj, min; size_t i; (void)class_gen; /* bail out if X11 or GLX interop requested */ if (params->visual_type == XINE_VISUAL_TYPE_X11) { if (params->flags & (XINE_VA_DISPLAY_GLX | XINE_VA_DISPLAY_X11)) { return NULL; } } /* accept all other visuals */ for (i = 0; i < sizeof(default_drm_device)/sizeof(default_drm_device[0]); i++) { drm_fd = open(default_drm_device[i], O_RDWR); if (drm_fd >= 0) { dpy = vaGetDisplayDRM(drm_fd); if (vaDisplayIsValid(dpy)) break; close(drm_fd); drm_fd = -1; } } if (!vaDisplayIsValid(dpy)) return NULL; vaStatus = vaInitialize(dpy, &maj, &min); if (vaStatus != VA_STATUS_SUCCESS) { xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Error: vaInitialize: %s [0x%04x]\n", vaErrorStr(vaStatus), vaStatus); vaTerminate(dpy); close(drm_fd); return NULL; } impl = calloc(1, sizeof(*impl)); if (!impl) { vaTerminate(dpy); close(drm_fd); return NULL; } impl->drm_fd = drm_fd; impl->p.xine = params->xine; impl->p.module.dispose = _module_dispose; impl->p.display.va_display = dpy; xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Using libva %d.%d\n", maj, min); return &impl->p.module; } /* * plugin */ static void *_init_class(xine_t *xine, const void *params) { static const xine_module_class_t xine_class = { .get_instance = _get_instance, .description = N_("VA display provider (DRM)"), .identifier = "va_display_drm", .dispose = NULL, }; (void)xine; (void)params; return (void *)&xine_class; } static const xine_module_info_t module_info_x11 = { .priority = 1, .type = "va_display_v1", .sub_type = XINE_VISUAL_TYPE_X11, }; static const xine_module_info_t module_info_wl = { .priority = 1, .type = "va_display_v1", .sub_type = XINE_VISUAL_TYPE_WAYLAND, }; static const xine_module_info_t module_info_none = { .priority = 1, .type = "va_display_v1", .sub_type = XINE_VISUAL_TYPE_NONE, }; static const xine_module_info_t module_info_fb = { .priority = 1, .type = "va_display_v1", .sub_type = XINE_VISUAL_TYPE_FB, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "va_display_drm", XINE_VERSION_CODE, &module_info_x11, _init_class }, { PLUGIN_XINE_MODULE, 1, "va_display_drm", XINE_VERSION_CODE, &module_info_wl, _init_class }, { PLUGIN_XINE_MODULE, 1, "va_display_drm", XINE_VERSION_CODE, &module_info_fb, _init_class }, { PLUGIN_XINE_MODULE, 1, "va_display_drm", XINE_VERSION_CODE, &module_info_none, _init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }, }; xine-lib-1.2/src/video_out/vaapi/vaapi_util.c0000644000175000017500000005052114647725152017054 0ustar meme/* * Copyright (C) 2012 Edgar Hucek * Copyright (C) 2012-2022 xine developers * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vaapi_util.c, VAAPI video extension interface for xine * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "vaapi" #include "vaapi_util.h" #include #include #include #include #include #include "xine_va_display.h" #if defined(LOG) || defined(DEBUG) static const char *_x_va_string_of_VAImageFormat(VAImageFormat *imgfmt) { static char str[5]; str[0] = imgfmt->fourcc; str[1] = imgfmt->fourcc >> 8; str[2] = imgfmt->fourcc >> 16; str[3] = imgfmt->fourcc >> 24; str[4] = '\0'; return str; } #endif const char *_x_va_profile_to_string(VAProfile profile) { switch(profile) { #define PROFILE(profile) \ case VAProfile##profile: return "VAProfile" #profile PROFILE(MPEG2Simple); PROFILE(MPEG2Main); PROFILE(MPEG4Simple); PROFILE(MPEG4AdvancedSimple); PROFILE(MPEG4Main); PROFILE(H264Main); PROFILE(H264High); PROFILE(VC1Simple); PROFILE(VC1Main); PROFILE(VC1Advanced); #if VA_CHECK_VERSION(0, 37, 0) PROFILE(HEVCMain); PROFILE(HEVCMain10); #endif #undef PROFILE default: break; } return ""; } const char *_x_va_entrypoint_to_string(VAEntrypoint entrypoint) { switch(entrypoint) { #define ENTRYPOINT(entrypoint) \ case VAEntrypoint##entrypoint: return "VAEntrypoint" #entrypoint ENTRYPOINT(VLD); ENTRYPOINT(IZZ); ENTRYPOINT(IDCT); ENTRYPOINT(MoComp); ENTRYPOINT(Deblocking); #undef ENTRYPOINT default: break; } return ""; } int _x_va_check_status(vaapi_context_impl_t *this, VAStatus vaStatus, const char *msg) { if (vaStatus != VA_STATUS_SUCCESS) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error : %s: %s [0x%04x]\n", msg, vaErrorStr(vaStatus), vaStatus); return 0; } return 1; } void _x_va_reset_va_context(ff_vaapi_context_t *va_context) { int i; va_context->va_config_id = VA_INVALID_ID; va_context->va_context_id = VA_INVALID_ID; va_context->valid_context = 0; for(i = 0; i < RENDER_SURFACES + 1; i++) { ff_vaapi_surface_t *va_surface = &va_context->va_render_surfaces[i]; va_surface->index = i; va_surface->status = SURFACE_FREE; va_surface->va_surface_id = VA_INVALID_SURFACE; va_context->va_surface_ids[i] = VA_INVALID_SURFACE; } } void _x_va_free(vaapi_context_impl_t **p_va_context) { if (*p_va_context) { vaapi_context_impl_t *va_context = *p_va_context; if (va_context->va_display_plugin) va_context->va_display_plugin->dispose(&va_context->va_display_plugin); va_context->c.va_display = NULL; _x_freep(&va_context->c.va_image_formats); va_context->c.va_num_image_formats = 0; pthread_mutex_destroy(&va_context->surfaces_lock); pthread_mutex_destroy(&va_context->ctx_lock); _x_freep(p_va_context); } } vaapi_context_impl_t *_x_va_new(xine_t *xine, int visual_type, const void *visual, unsigned va_display_flags) { vaapi_context_impl_t *va_context; xine_va_display_t *va_display; const char *p, *vendor; VAStatus vaStatus; int fmt_count = 0; size_t i; va_display = _x_va_display_open(xine, visual_type, visual, va_display_flags); if (!va_display) return NULL; va_context = calloc(1, sizeof(*va_context)); if (!va_context) { va_display->dispose(&va_display); return NULL; } va_context->xine = xine; va_context->va_display_plugin = va_display; va_context->c.va_render_surfaces = va_context->va_render_surfaces_storage; va_context->c.va_surface_ids = va_context->va_surface_ids_storage; va_context->c.va_display = va_context->va_display_plugin->va_display; _x_va_reset_va_context(&va_context->c); pthread_mutex_init(&va_context->surfaces_lock, NULL); pthread_mutex_init(&va_context->ctx_lock, NULL); fmt_count = vaMaxNumImageFormats(va_context->c.va_display); va_context->c.va_image_formats = calloc(fmt_count, sizeof(*va_context->c.va_image_formats)); if (!va_context->c.va_image_formats) { _x_va_free(&va_context); return NULL; } vaStatus = vaQueryImageFormats(va_context->c.va_display, va_context->c.va_image_formats, &va_context->c.va_num_image_formats); if (!_x_va_check_status(va_context, vaStatus, "vaQueryImageFormats")) { _x_va_free(&va_context); return NULL; } va_context->query_va_status = 1; va_context->va_head = 0; vendor = vaQueryVendorString(va_context->c.va_display); xprintf(va_context->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Vendor : %s\n", vendor); for (p = vendor, i = strlen (vendor); i > 0; i--, p++) { if (strncmp(p, "VDPAU", strlen("VDPAU")) == 0) { xprintf(va_context->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Enable Splitted-Desktop Systems VDPAU-VIDEO workarounds.\n"); va_context->query_va_status = 0; break; } } return va_context; } void _x_va_destroy_image(vaapi_context_impl_t *va_context, VAImage *va_image) { VAStatus vaStatus; if (va_image->image_id != VA_INVALID_ID) { lprintf("vaapi_destroy_image 0x%08x\n", va_image->image_id); vaStatus = vaDestroyImage(va_context->c.va_display, va_image->image_id); _x_va_check_status(va_context, vaStatus, "vaDestroyImage()"); } va_image->image_id = VA_INVALID_ID; va_image->width = 0; va_image->height = 0; } VAStatus _x_va_create_image(vaapi_context_impl_t *va_context, VASurfaceID va_surface_id, VAImage *va_image, int width, int height, int clear, int *is_bound) { int i = 0; VAStatus vaStatus; if (va_context->c.va_image_formats == NULL || va_context->c.va_num_image_formats == 0) return VA_STATUS_ERROR_UNKNOWN; *is_bound = 0; vaStatus = vaDeriveImage(va_context->c.va_display, va_surface_id, va_image); if (vaStatus == VA_STATUS_SUCCESS) { if (va_image->image_id != VA_INVALID_ID && va_image->buf != VA_INVALID_ID) { *is_bound = 1; } } if (!*is_bound) { for (i = 0; i < va_context->c.va_num_image_formats; i++) { if (va_context->c.va_image_formats[i].fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) || va_context->c.va_image_formats[i].fourcc == VA_FOURCC( 'I', '4', '2', '0' ) /*|| va_context->c.va_image_formats[i].fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) */) { vaStatus = vaCreateImage( va_context->c.va_display, &va_context->c.va_image_formats[i], width, height, va_image ); if (!_x_va_check_status(va_context, vaStatus, "vaCreateImage()")) goto error; break; } } } void *p_base = NULL; vaStatus = vaMapBuffer( va_context->c.va_display, va_image->buf, &p_base ); if (!_x_va_check_status(va_context, vaStatus, "vaMapBuffer()")) goto error; if (clear) { if (va_image->format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) || va_image->format.fourcc == VA_FOURCC( 'I', '4', '2', '0' )) { memset((uint8_t*)p_base + va_image->offsets[0], 0, va_image->pitches[0] * va_image->height); memset((uint8_t*)p_base + va_image->offsets[1], 128, va_image->pitches[1] * (va_image->height/2)); memset((uint8_t*)p_base + va_image->offsets[2], 128, va_image->pitches[2] * (va_image->height/2)); } else if (va_image->format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' ) ) { memset((uint8_t*)p_base + va_image->offsets[0], 0, va_image->pitches[0] * va_image->height); memset((uint8_t*)p_base + va_image->offsets[1], 128, va_image->pitches[1] * (va_image->height/2)); } } vaStatus = vaUnmapBuffer( va_context->c.va_display, va_image->buf ); _x_va_check_status(va_context, vaStatus, "vaUnmapBuffer()"); lprintf("_x_va_create_image 0x%08x width %d height %d format %s\n", va_image->image_id, va_image->width, va_image->height, _x_va_string_of_VAImageFormat(&va_image->format)); return VA_STATUS_SUCCESS; error: /* house keeping */ _x_va_destroy_image(va_context, va_image); return VA_STATUS_ERROR_UNKNOWN; } static VAStatus _x_va_destroy_render_surfaces(vaapi_context_impl_t *va_context) { int i; VAStatus vaStatus; pthread_mutex_lock(&va_context->surfaces_lock); for (i = 0; i < RENDER_SURFACES; i++) { if (va_context->c.va_surface_ids[i] != VA_INVALID_SURFACE) { vaStatus = vaSyncSurface(va_context->c.va_display, va_context->c.va_surface_ids[i]); _x_va_check_status(va_context, vaStatus, "vaSyncSurface()"); vaStatus = vaDestroySurfaces(va_context->c.va_display, &va_context->c.va_surface_ids[i], 1); _x_va_check_status(va_context, vaStatus, "vaDestroySurfaces()"); va_context->c.va_surface_ids[i] = VA_INVALID_SURFACE; ff_vaapi_surface_t *va_surface = &va_context->c.va_render_surfaces[i]; va_surface->index = i; va_surface->status = SURFACE_FREE; va_surface->va_surface_id = va_context->c.va_surface_ids[i]; } } pthread_mutex_unlock(&va_context->surfaces_lock); return VA_STATUS_SUCCESS; } void _x_va_close(vaapi_context_impl_t *va_context) { VAStatus vaStatus; pthread_mutex_lock(&va_context->ctx_lock); if (va_context->c.va_context_id != VA_INVALID_ID) { vaStatus = vaDestroyContext(va_context->c.va_display, va_context->c.va_context_id); _x_va_check_status(va_context, vaStatus, "vaDestroyContext()"); va_context->c.va_context_id = VA_INVALID_ID; } _x_va_destroy_render_surfaces(va_context); if (va_context->c.va_config_id != VA_INVALID_ID) { vaStatus = vaDestroyConfig(va_context->c.va_display, va_context->c.va_config_id); _x_va_check_status(va_context, vaStatus, "vaDestroyConfig()"); va_context->c.va_config_id = VA_INVALID_ID; } va_context->c.valid_context = 0; pthread_mutex_unlock(&va_context->ctx_lock); } VAStatus _x_va_init(vaapi_context_impl_t *va_context, int va_profile, int width, int height) { VAConfigAttrib va_attrib; VAStatus vaStatus; size_t i; _x_va_close(va_context); pthread_mutex_lock(&va_context->ctx_lock); va_context->c.width = width; va_context->c.height = height; xprintf(va_context->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Context width %d height %d\n", va_context->c.width, va_context->c.height); /* allocate decoding surfaces */ unsigned rt_format = VA_RT_FORMAT_YUV420; #if VA_CHECK_VERSION(0, 37, 0) && defined (VA_RT_FORMAT_YUV420_10BPP) if (va_profile == VAProfileHEVCMain10) { rt_format = VA_RT_FORMAT_YUV420_10BPP; } #endif vaStatus = vaCreateSurfaces(va_context->c.va_display, rt_format, va_context->c.width, va_context->c.height, va_context->c.va_surface_ids, RENDER_SURFACES, NULL, 0); if (!_x_va_check_status(va_context, vaStatus, "vaCreateSurfaces()")) goto error; /* hardware decoding needs more setup */ if (va_profile >= 0) { xprintf(va_context->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Profile: %d (%s) Entrypoint %d (%s) Surfaces %d\n", va_profile, _x_va_profile_to_string(va_profile), VAEntrypointVLD, _x_va_entrypoint_to_string(VAEntrypointVLD), RENDER_SURFACES); memset (&va_attrib, 0, sizeof(va_attrib)); va_attrib.type = VAConfigAttribRTFormat; vaStatus = vaGetConfigAttributes(va_context->c.va_display, va_profile, VAEntrypointVLD, &va_attrib, 1); if (!_x_va_check_status(va_context, vaStatus, "vaGetConfigAttributes()")) goto error; if ((va_attrib.value & VA_RT_FORMAT_YUV420) == 0) goto error; vaStatus = vaCreateConfig(va_context->c.va_display, va_profile, VAEntrypointVLD, &va_attrib, 1, &va_context->c.va_config_id); if (!_x_va_check_status(va_context, vaStatus, "vaCreateConfig()")) { va_context->c.va_config_id = VA_INVALID_ID; goto error; } vaStatus = vaCreateContext(va_context->c.va_display, va_context->c.va_config_id, va_context->c.width, va_context->c.height, VA_PROGRESSIVE, va_context->c.va_surface_ids, RENDER_SURFACES, &va_context->c.va_context_id); if (!_x_va_check_status(va_context, vaStatus, "vaCreateContext()")) { va_context->c.va_context_id = VA_INVALID_ID; goto error; } } pthread_mutex_lock(&va_context->surfaces_lock); /* assign surfaces */ for (i = 0; i < RENDER_SURFACES; i++) { ff_vaapi_surface_t *va_surface = &va_context->c.va_render_surfaces[i]; va_surface->index = i; va_surface->status = SURFACE_FREE; va_surface->va_surface_id = va_context->c.va_surface_ids[i]; } va_context->va_head = 0; pthread_mutex_unlock(&va_context->surfaces_lock); /* unbind frames from surfaces */ for (i = 0; i < RENDER_SURFACES; i++) { if (va_context->frames[i]) { vaapi_accel_t *accel = va_context->frames[i]->accel_data; if (!accel->f->render_vaapi_surface) { _x_assert(accel->index == i); } else { accel->index = RENDER_SURFACES; } } } va_context->c.valid_context = 1; pthread_mutex_unlock(&va_context->ctx_lock); return VA_STATUS_SUCCESS; error: pthread_mutex_unlock(&va_context->ctx_lock); xprintf(va_context->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error initializing VAAPI decoding\n"); _x_va_close(va_context); return VA_STATUS_ERROR_UNKNOWN; } static int _x_va_has_profile(VAProfile *va_profiles, int va_num_profiles, VAProfile profile) { int i; for (i = 0; i < va_num_profiles; i++) { if (va_profiles[i] == profile) return 1; } return 0; } int _x_va_profile_from_imgfmt(vaapi_context_impl_t *va_context, unsigned format) { VAStatus vaStatus; int profile = -1; int i; int va_num_profiles; int max_profiles; VAProfile *va_profiles = NULL; _x_assert(va_context->c.va_display); max_profiles = vaMaxNumProfiles(va_context->c.va_display); va_profiles = calloc(max_profiles, sizeof(*va_profiles)); if (!va_profiles) goto out; vaStatus = vaQueryConfigProfiles(va_context->c.va_display, va_profiles, &va_num_profiles); if(!_x_va_check_status(va_context, vaStatus, "vaQueryConfigProfiles()")) goto out; xprintf(va_context->xine, XINE_VERBOSITY_DEBUG + 1, LOG_MODULE ": VAAPI Supported Profiles :\n"); for (i = 0; i < va_num_profiles; i++) { xprintf(va_context->xine, XINE_VERBOSITY_DEBUG + 1, LOG_MODULE ": %s\n", _x_va_profile_to_string(va_profiles[i])); } static const int mpeg2_profiles[] = { VAProfileMPEG2Main, VAProfileMPEG2Simple, -1 }; static const int mpeg4_profiles[] = { VAProfileMPEG4Main, VAProfileMPEG4AdvancedSimple, VAProfileMPEG4Simple, -1 }; static const int h264_profiles[] = { VAProfileH264High, VAProfileH264Main, -1 }; #if VA_CHECK_VERSION(0, 37, 0) static const int hevc_profiles[] = { VAProfileHEVCMain, VAProfileHEVCMain10, -1 }; static const int hevc_profiles10[] = { VAProfileHEVCMain10, -1 }; #endif static const int wmv3_profiles[] = { VAProfileVC1Main, VAProfileVC1Simple, -1 }; static const int vc1_profiles[] = { VAProfileVC1Advanced, -1 }; const int *profiles = NULL; switch (IMGFMT_VAAPI_CODEC(format)) { case IMGFMT_VAAPI_CODEC_MPEG2: profiles = mpeg2_profiles; break; case IMGFMT_VAAPI_CODEC_MPEG4: profiles = mpeg4_profiles; break; case IMGFMT_VAAPI_CODEC_H264: profiles = h264_profiles; break; #if VA_CHECK_VERSION(0, 37, 0) case IMGFMT_VAAPI_CODEC_HEVC: switch (format) { case IMGFMT_VAAPI_HEVC_MAIN10: profiles = hevc_profiles10; break; case IMGFMT_VAAPI_HEVC: default: profiles = hevc_profiles; break; } break; #endif case IMGFMT_VAAPI_CODEC_VC1: switch (format) { case IMGFMT_VAAPI_WMV3: profiles = wmv3_profiles; break; case IMGFMT_VAAPI_VC1: profiles = vc1_profiles; break; } break; } if (profiles) { int i; for (i = 0; profiles[i] != -1; i++) { if (_x_va_has_profile(va_profiles, va_num_profiles, profiles[i])) { profile = profiles[i]; xprintf(va_context->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "VAAPI Profile %s supported by your hardware\n", _x_va_profile_to_string(profiles[i])); break; } } } if (profile < 0) xprintf(va_context->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "VAAPI Profile for video format 0x%08x not supported by hardware\n", format); out: free(va_profiles); return profile; } #ifdef DEBUG_SURFACE # define DBG_SURFACE printf #else # define DBG_SURFACE(...) do { } while (0) #endif ff_vaapi_surface_t *_x_va_alloc_surface(vaapi_context_impl_t *va_context) { ff_vaapi_surface_t *va_surface = NULL; VAStatus vaStatus; lprintf("get_vaapi_surface\n"); pthread_mutex_lock(&va_context->surfaces_lock); /* Get next VAAPI surface marked as SURFACE_FREE */ while (1) { va_surface = &va_context->c.va_render_surfaces[va_context->va_head]; va_context->va_head = (va_context->va_head + 1) % RENDER_SURFACES; if (va_surface->status == SURFACE_FREE) { VASurfaceStatus surf_status = 0; if (va_context->query_va_status) { vaStatus = vaQuerySurfaceStatus(va_context->c.va_display, va_surface->va_surface_id, &surf_status); _x_va_check_status(va_context, vaStatus, "vaQuerySurfaceStatus()"); } else { surf_status = VASurfaceReady; } if (surf_status == VASurfaceReady) { va_surface->status = SURFACE_ALOC; DBG_SURFACE("alloc_vaapi_surface 0x%08x\n", va_surface->va_surface_id); break; } DBG_SURFACE("alloc_vaapi_surface busy\n"); } DBG_SURFACE("alloc_vaapi_surface miss\n"); } pthread_mutex_unlock(&va_context->surfaces_lock); return va_surface; } void _x_va_render_surface(vaapi_context_impl_t *va_context, ff_vaapi_surface_t *va_surface) { DBG_SURFACE("render_vaapi_surface 0x%08x\n", va_surface->va_surface_id); _x_assert(va_surface->status == SURFACE_ALOC); pthread_mutex_lock(&va_context->surfaces_lock); va_surface->status = SURFACE_RENDER; pthread_mutex_unlock(&va_context->surfaces_lock); } void _x_va_release_surface(vaapi_context_impl_t *va_context, ff_vaapi_surface_t *va_surface) { _x_assert(va_surface->status == SURFACE_ALOC || va_surface->status == SURFACE_RENDER || va_surface->status == SURFACE_RELEASE); pthread_mutex_lock(&va_context->surfaces_lock); if (va_surface->status == SURFACE_RENDER) { va_surface->status = SURFACE_RENDER_RELEASE; DBG_SURFACE("release_surface 0x%08x -> RENDER_RELEASE\n", va_surface->va_surface_id); } else if (va_surface->status != SURFACE_RENDER_RELEASE) { va_surface->status = SURFACE_FREE; DBG_SURFACE("release_surface 0x%08x -> FREE\n", va_surface->va_surface_id); } pthread_mutex_unlock(&va_context->surfaces_lock); } void _x_va_surface_displayed(vaapi_context_impl_t *va_context, ff_vaapi_surface_t *va_surface) { _x_assert(va_surface->status == SURFACE_RENDER || va_surface->status == SURFACE_RENDER_RELEASE); pthread_mutex_lock(&va_context->surfaces_lock); if (va_surface->status == SURFACE_RENDER_RELEASE) { va_surface->status = SURFACE_FREE; DBG_SURFACE("release_surface 0x%08x -> FREE\n", va_surface->va_surface_id, vo_frame); } else if (va_surface->status == SURFACE_RENDER) { va_surface->status = SURFACE_RELEASE; DBG_SURFACE("release_surface 0x%08x -> RELEASE\n", va_surface->va_surface_id, vo_frame); } else { DBG_SURFACE("release_surface 0x%08x INVALID STATE %d\n", va_surface->va_surface_id, vo_frame, va_surface->status); } pthread_mutex_unlock(&va_context->surfaces_lock); } xine-lib-1.2/src/video_out/vaapi/xine_va_display_glx.c0000644000175000017500000000626414647725152020754 0ustar meme/* * Copyright (C) 2022 the xine project * Copyright (C) 2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * VAAPI display for GLX * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "va_display_glx" #include "xine_va_display_plugin.h" #include #include /* visual types */ #include #include #include /* * xine module */ static void _module_dispose(xine_module_t *module) { xine_va_display_plugin_t *p = xine_container_of(module, xine_va_display_plugin_t, module); vaTerminate(p->display.va_display); free(p); } static xine_module_t *_get_instance(xine_module_class_t *class_gen, const void *data) { const va_display_plugin_params_t *params = data; const x11_visual_t *vis_x11 = params->visual; xine_va_display_plugin_t *p; VADisplay dpy = NULL; VAStatus vaStatus; int maj, min; (void)class_gen; if (params->visual_type != XINE_VISUAL_TYPE_X11) return NULL; if (!(params->flags & XINE_VA_DISPLAY_GLX)) return NULL; dpy = vaGetDisplayGLX(vis_x11->display); if (!vaDisplayIsValid(dpy)) return NULL; vaStatus = vaInitialize(dpy, &maj, &min); if (vaStatus != VA_STATUS_SUCCESS) { xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Error: vaInitialize: %s [0x%04x]\n", vaErrorStr(vaStatus), vaStatus); vaTerminate(dpy); return NULL; } p = calloc(1, sizeof(*p)); if (!p) { vaTerminate(dpy); return NULL; } p->xine = params->xine; p->module.dispose = _module_dispose; p->display.va_display = dpy; xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Using libva %d.%d\n", maj, min); return &p->module; } /* * plugin */ static void *_init_class(xine_t *xine, const void *params) { static const xine_module_class_t xine_class = { .get_instance = _get_instance, .description = N_("VA display provider (X11/GLX)"), .identifier = "va_display_glx", .dispose = NULL, }; (void)xine; (void)params; return (void *)&xine_class; } static const xine_module_info_t module_info = { .priority = 9, .type = "va_display_v1", .sub_type = XINE_VISUAL_TYPE_X11, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "va_display_glx", XINE_VERSION_CODE, &module_info, _init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }, }; xine-lib-1.2/src/video_out/vaapi/xine_va_display.h0000644000175000017500000000270114647725152020077 0ustar meme/* * Copyright (C) 2022 the xine project * Copyright (C) 2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine_va_display.h: VAAPI display (plugin loader) * */ #ifndef XINE_VAAPI_H_ #define XINE_VAAPI_H_ #include typedef struct xine_va_display_t xine_va_display_t; struct xine_va_display_t { void *va_display; void (*dispose) (xine_va_display_t **); }; /* flags */ #define XINE_VA_DISPLAY_GLX 0x0001 /* Require GLX interop (vaCopySurfaceGLX) */ #define XINE_VA_DISPLAY_X11 0x0002 /* Require X11 interop (vaPutSurface) */ xine_va_display_t *_x_va_display_open(xine_t *xine, unsigned visual_type, const void *visual, unsigned flags); #endif /* XINE_VAAPI_H_ */ xine-lib-1.2/src/video_out/vaapi/xine_va_display_plugin.h0000644000175000017500000000310314647725152021452 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2018-2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine VAAPI display interface plugin * interface between VAAPI and native windowing system (X11/GLX/EGL/Wayland/...) * */ #ifndef XINE_VA_DISPLAY_PLUGIN_H_ #define XINE_VA_DISPLAY_PLUGIN_H_ #include #include #include #include "xine_va_display.h" #define VA_DISPLAY_PLUGIN_TYPE "va_display_v1" typedef struct xine_va_display_plugin_s xine_va_display_plugin_t; struct xine_va_display_plugin_s { xine_module_t module; xine_va_display_t display; xine_t *xine; }; typedef struct { xine_t *xine; unsigned visual_type; const void *visual; unsigned flags; } va_display_plugin_params_t; #endif /* XINE_VA_DISPLAY_PLUGIN_H_ */ xine-lib-1.2/src/video_out/vaapi/xine_hw_frame_vaapi.c0000644000175000017500000001123014647725152020704 0ustar meme/* * Copyright (C) 2022 the xine project * Copyright (C) 2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * VAAPI HW frame plugin * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xine_hw_frame_plugin.h" #include #include /* visual types */ #include #include "vaapi_util.h" #include "vaapi_frame.h" #include "vaapi_egl.h" typedef struct { xine_hw_frame_plugin_t plugin; vaapi_context_impl_t *va_context; int guarded_render; } va_hw_frame_plugin_t; /* * xine module */ static void _module_dispose(xine_module_t *module) { va_hw_frame_plugin_t *p = xine_container_of(module, va_hw_frame_plugin_t, plugin.module); _x_va_free(&p->va_context); free(p); } static mem_frame_t *_alloc_frame(xine_hwdec_t *api) { va_hw_frame_plugin_t *p = xine_container_of(api, va_hw_frame_plugin_t, plugin.api); vaapi_frame_t *frame = _x_va_frame_alloc_frame(p->va_context, p->va_context->c.driver, p->guarded_render); return &frame->mem_frame; } static xine_glconv_t *_opengl_interop(xine_hwdec_t *api, struct xine_gl *gl) { va_hw_frame_plugin_t *p = xine_container_of(api, va_hw_frame_plugin_t, plugin.api); /* - may need plugins if ex. need to link against X11 */ return _glconv_vaegl_init(p->plugin.xine, gl, p->va_context->va_display_plugin); } static xine_module_t *_get_instance(xine_module_class_t *class_gen, const void *data) { const hw_frame_plugin_params_t *params = data; config_values_t *config = params->xine->config; vaapi_context_impl_t *va_context; va_hw_frame_plugin_t *p; int enable, guarded_render; (void)class_gen; enable = config->register_bool(config, "video.output.enable_vaapi", 0, _("Enable VAAPI"), _("Enable VAAPI video decoding with any video output driver. " "When disabled, only vaapi video output driver uses VAAPI accelerated decoding. " "Currently only opengl2 video output driver supports this."), 10, NULL, NULL); guarded_render = config->register_num(config, "video.output.vaapi_guarded_render", 1, _("vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )"), _("vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )"), 10, NULL, NULL); if (!enable) return NULL; /* initialize vaapi */ va_context = _x_va_new(params->xine, params->visual_type, params->visual, 0); if (!va_context) return NULL; va_context->c.driver = params->vo_driver; /* test it */ if (_x_va_init(va_context, -1, 1920, 1080)) { _x_va_free(&va_context); return NULL; } _x_va_close(va_context); p = calloc(1, sizeof(*p)); if (!p) { _x_va_free(&va_context); return NULL; } p->plugin.module.dispose = _module_dispose; p->plugin.api.frame_format = XINE_IMGFMT_VAAPI; p->plugin.api.driver_capabilities = VO_CAP_VAAPI; p->plugin.api.alloc_frame = _alloc_frame; p->plugin.api.update_frame_format = _x_va_frame_update_frame_format; p->plugin.api.opengl_interop = _opengl_interop; p->plugin.api.destroy = NULL; /* filled by hw_frame loader */ p->va_context = va_context; p->guarded_render = guarded_render; return &p->plugin.module; } /* * plugin */ static void *_init_class(xine_t *xine, const void *params) { static const xine_module_class_t xine_class = { .get_instance = _get_instance, .description = N_("VAAPI frame provider"), .identifier = "hw_frame_vaapi", .dispose = NULL, }; (void)xine; (void)params; return (void *)&xine_class; } static const xine_module_info_t module_info = { .priority = 9, .type = "hw_frame_v1", .sub_type = 0, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "hwframe_vaapi", XINE_VERSION_CODE, &module_info, _init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }, }; xine-lib-1.2/src/video_out/vaapi/vaapi_frame.c0000644000175000017500000003652614647725152017202 0ustar meme/* * Copyright (C) 2012 Edgar Hucek * Copyright (C) 2012-2022 xine developers * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vaapi_frame.c, VAAPI video extension interface for xine * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "vaapi_frame" #include #include #include #include #include #include #include "vaapi_frame.h" #include "accel_vaapi.h" #define FRAME_FORMAT_STR(f) \ ( (f) == XINE_IMGFMT_VAAPI ? "XINE_IMGFMT_VAAPI" : \ (f) == XINE_IMGFMT_YV12 ? "XINE_IMGFMT_YV12" : \ (f) == XINE_IMGFMT_YUY2 ? "XINE_IMGFMT_YUY2" : \ (f) == XINE_IMGFMT_NV12 ? "XINE_IMGFMT_NV12" : \ "UNKNOWN") void _x_va_frame_provide_standard_frame_data (vo_frame_t *vo_frame, xine_current_frame_data_t *data) { vaapi_context_impl_t *va; vaapi_accel_t *accel = vo_frame->accel_data; ff_vaapi_surface_t *va_surface; VAStatus vaStatus; uint32_t pitches[3]; uint8_t *base[3]; int width, height; _x_assert(vo_frame->format == XINE_IMGFMT_VAAPI); va = _ctx_from_frame(vo_frame); if (accel->index >= RENDER_SURFACES /* invalid */) { xprintf(va->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "vaapi_provide_standard_frame_data: invalid surface\n"); return; } pthread_mutex_lock(&va->ctx_lock); va_surface = &va->c.va_render_surfaces[accel->index]; if (va_surface->va_surface_id == VA_INVALID_SURFACE) goto error; lprintf("vaapi_provide_standard_frame_data 0x%08x width %d height %d\n", va_surface->va_surface_id, vo_frame->width, vo_frame->height); width = va->c.width; height = va->c.height; data->format = XINE_IMGFMT_YV12; data->img_size = width * height + ((width + 1) / 2) * ((height + 1) / 2) + ((width + 1) / 2) * ((height + 1) / 2); data->width = width; data->height = height; if (!data->img) goto error; pitches[0] = width; pitches[1] = width / 2; pitches[2] = width / 2; base[0] = data->img; base[1] = data->img + width * height; base[2] = data->img + width * height + width * height / 4; VAImage va_image; void *p_base; int is_bound; VASurfaceStatus surf_status = 0; vaStatus = vaSyncSurface(va->c.va_display, va_surface->va_surface_id); _x_va_check_status(va, vaStatus, "vaSyncSurface()"); if (va->query_va_status) { vaStatus = vaQuerySurfaceStatus(va->c.va_display, va_surface->va_surface_id, &surf_status); _x_va_check_status(va, vaStatus, "vaQuerySurfaceStatus()"); } else { surf_status = VASurfaceReady; } if (surf_status != VASurfaceReady) goto error; vaStatus = _x_va_create_image(va, va_surface->va_surface_id, &va_image, width, height, 0, &is_bound); if (!_x_va_check_status(va, vaStatus, "_x_va_create_image()")) goto error; lprintf("vaapi_provide_standard_frame_data accel->va_surface_id 0x%08x va_image.image_id 0x%08x " "va_context->width %d va_context->height %d va_image.width %d va_image.height %d " "width %d height %d size1 %d size2 %d %d %d %d status %d num_planes %d\n", va_surface->va_surface_id, va_image.image_id, va->c.width, va->c.height, va_image.width, va_image.height, width, height, va_image.data_size, data->img_size, va_image.pitches[0], va_image.pitches[1], va_image.pitches[2], surf_status, va_image.num_planes); if (va_image.image_id == VA_INVALID_ID) goto error; if (!is_bound) { vaStatus = vaGetImage(va->c.va_display, va_surface->va_surface_id, 0, 0, va_image.width, va_image.height, va_image.image_id); if (!_x_va_check_status(va, vaStatus, "vaGetImage()")) goto error; } vaStatus = vaMapBuffer( va->c.va_display, va_image.buf, &p_base ) ; if (!_x_va_check_status(va, vaStatus, "vaMapBuffer()")) goto error_image; /* uint8_t *src[3] = { NULL, }; src[0] = (uint8_t *)p_base + va_image.offsets[0]; src[1] = (uint8_t *)p_base + va_image.offsets[1]; src[2] = (uint8_t *)p_base + va_image.offsets[2]; */ if (va_image.format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) || va_image.format.fourcc == VA_FOURCC( 'I', '4', '2', '0' )) { lprintf("VAAPI YV12 image\n"); yv12_to_yv12((uint8_t*)p_base + va_image.offsets[0], va_image.pitches[0], base[0], pitches[0], (uint8_t*)p_base + va_image.offsets[1], va_image.pitches[1], base[2], pitches[2], (uint8_t*)p_base + va_image.offsets[2], va_image.pitches[2], base[1], pitches[1], va_image.width, va_image.height); } else if (va_image.format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' )) { lprintf("VAAPI NV12 image\n"); lprintf("va_image.offsets[0] %d va_image.offsets[1] %d va_image.offsets[2] %d size %d size %d size %d width %d height %d width %d height %d\n", va_image.offsets[0], va_image.offsets[1], va_image.offsets[2], va_image.data_size, va_image.width * va_image.height, data->img_size, width, height, va_image.width, va_image.height); _x_nv12_to_yv12((uint8_t *)p_base + va_image.offsets[0], va_image.pitches[0], (uint8_t *)p_base + va_image.offsets[1], va_image.pitches[1], base[0], pitches[0], base[1], pitches[1], base[2], pitches[2], va_image.width > width ? width : va_image.width, va_image.height > height ? height : va_image.height); } else { printf("vaapi_provide_standard_frame_data unsupported image format\n"); } vaStatus = vaUnmapBuffer(va->c.va_display, va_image.buf); _x_va_check_status(va, vaStatus, "vaUnmapBuffer()"); error_image: _x_va_destroy_image(va, &va_image); error: pthread_mutex_unlock(&va->ctx_lock); } void _x_va_frame_duplicate_frame_data (vo_frame_t *this_gen, vo_frame_t *original) { vaapi_accel_t *accel_this = this_gen->accel_data; vaapi_accel_t *accel_orig = original->accel_data; vaapi_context_impl_t *va; ff_vaapi_surface_t *va_surface_this = NULL; ff_vaapi_surface_t *va_surface_orig; VAImage va_image_orig; VAImage va_image_this; VAStatus vaStatus; void *p_base_orig = NULL; void *p_base_this = NULL; int this_is_bound, orig_is_bound; _x_assert (this_gen->format == XINE_IMGFMT_VAAPI); va = _ctx_from_frame(this_gen); if (original->format != XINE_IMGFMT_VAAPI) { xprintf(va->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "vaapi_duplicate_frame_data: unexpected frame format 0x%08x!\n", original->format); return; } va_image_this.image_id = VA_INVALID_ID; va_image_orig.image_id = VA_INVALID_ID; pthread_mutex_lock(&va->ctx_lock); if (_x_va_accel_guarded_render(this_gen)) { if (accel_orig->index >= RENDER_SURFACES) { xprintf(va->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "vaapi_duplicate_frame_data: invalid source surface\n"); goto error; } va_surface_orig = &va->c.va_render_surfaces[accel_orig->index]; va_surface_this = _x_va_accel_alloc_vaapi_surface(this_gen); if (!va_surface_this) { xprintf(va->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "vaapi_duplicate_frame_data: surface allocation failed\n"); goto error; } } else { _x_assert (accel_this->index < RENDER_SURFACES); /* "fixed" in this mode */ _x_assert (accel_orig->index < RENDER_SURFACES); /* "fixed" in this mode */ va_surface_this = &va->c.va_render_surfaces[accel_this->index]; va_surface_orig = &va->c.va_render_surfaces[accel_orig->index]; } lprintf("vaapi_duplicate_frame_data 0x%08x <- 0x%08x\n", va_surface_this->va_surface_id, va_surface_orig->va_surface_id); vaStatus = vaSyncSurface(va->c.va_display, va_surface_orig->va_surface_id); _x_va_check_status(va, vaStatus, "vaSyncSurface()"); vaStatus = _x_va_create_image(va, va_surface_orig->va_surface_id, &va_image_orig, va->c.width, va->c.height, 0, &orig_is_bound); if (!_x_va_check_status(va, vaStatus, "_x_va_create_image()")) { va_image_orig.image_id = VA_INVALID_ID; goto error; } vaStatus = _x_va_create_image(va, va_surface_this->va_surface_id, &va_image_this, va->c.width, va->c.height, 0, &this_is_bound); if (!_x_va_check_status(va, vaStatus, "_x_va_create_image()")) { va_image_this.image_id = VA_INVALID_ID; goto error; } if(va_image_orig.image_id == VA_INVALID_ID || va_image_this.image_id == VA_INVALID_ID) { printf("vaapi_duplicate_frame_data invalid image\n"); goto error; } lprintf("vaapi_duplicate_frame_data va_image_orig.image_id 0x%08x " "va_image_orig.width %d va_image_orig.height %d width %d height %d " "size %d %d %d %d\n", va_image_orig.image_id, va_image_orig.width, va_image_orig.height, this_gen->width, this_gen->height, va_image_orig.data_size, va_image_orig.pitches[0], va_image_orig.pitches[1], va_image_orig.pitches[2]); if (!orig_is_bound) { vaStatus = vaGetImage(va->c.va_display, va_surface_orig->va_surface_id, 0, 0, va_image_orig.width, va_image_orig.height, va_image_orig.image_id); if (!_x_va_check_status(va, vaStatus, "vaGetImage()")) goto error; } if (!this_is_bound) { vaStatus = vaPutImage(va->c.va_display, va_surface_this->va_surface_id, va_image_orig.image_id, 0, 0, va_image_orig.width, va_image_orig.height, 0, 0, va_image_this.width, va_image_this.height); _x_va_check_status(va, vaStatus, "vaPutImage()"); } else { vaStatus = vaMapBuffer(va->c.va_display, va_image_orig.buf, &p_base_orig); if (!_x_va_check_status(va, vaStatus, "vaMapBuffer()")) goto error; vaStatus = vaMapBuffer(va->c.va_display, va_image_this.buf, &p_base_this); if (!_x_va_check_status(va, vaStatus, "vaMapBuffer()")) goto error; int size = (va_image_orig.data_size > va_image_this.data_size) ? va_image_this.data_size : va_image_orig.data_size; xine_fast_memcpy((uint8_t *) p_base_this, (uint8_t *) p_base_orig, size); } if (_x_va_accel_guarded_render(this_gen)) { accel_this->index = va_surface_this->index; va_surface_this->status = SURFACE_RENDER_RELEASE; } va_surface_this = NULL; /* do not release */ error: if(p_base_orig) { vaStatus = vaUnmapBuffer(va->c.va_display, va_image_orig.buf); _x_va_check_status(va, vaStatus, "vaUnmapBuffer()"); } if(p_base_this) { vaStatus = vaUnmapBuffer(va->c.va_display, va_image_this.buf); _x_va_check_status(va, vaStatus, "vaUnmapBuffer()"); } if (va_image_orig.image_id != VA_INVALID_ID) _x_va_destroy_image(va, &va_image_orig); if (va_image_this.image_id != VA_INVALID_ID) _x_va_destroy_image(va, &va_image_this); if (va_surface_this) { /* --> failed, need to release allocated surface */ if (_x_va_accel_guarded_render(this_gen)) { _x_va_surface_displayed(va, va_surface_this); accel_this->index = RENDER_SURFACES; /* invalid */ } } pthread_mutex_unlock(&va->ctx_lock); } void _x_va_frame_update_frame_format (vo_driver_t *this_gen, vo_frame_t *vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags) { mem_frame_t *frame = xine_container_of(vo_frame, mem_frame_t, vo_frame); if (frame->format == XINE_IMGFMT_VAAPI /* check _old_ format */) { if (_x_va_accel_guarded_render(vo_frame)) { /* This code handles frames that were dropped (used in decoder, but not drawn). */ vaapi_context_impl_t *va = _ctx_from_frame(vo_frame); pthread_mutex_lock(&va->ctx_lock); _x_va_frame_displayed(vo_frame); pthread_mutex_unlock(&va->ctx_lock); } } lprintf("vaapi_update_frame_format %s -> %s width %d height %d\n", FRAME_FORMAT_STR(frame->format), FRAME_FORMAT_STR(format), width, height); mem_frame_update_frame_format(this_gen, vo_frame, width, height, ratio, format, flags); if (format == XINE_IMGFMT_VAAPI) { frame->width = width; /* mem_frame freed frame->base */ frame->vo_frame.width = width; frame->vo_frame.proc_duplicate_frame_data = _x_va_frame_duplicate_frame_data; frame->vo_frame.proc_provide_standard_frame_data = _x_va_frame_provide_standard_frame_data; lprintf("XINE_IMGFMT_VAAPI width %d height %d\n", width, height); } else { frame->vo_frame.proc_duplicate_frame_data = NULL; frame->vo_frame.proc_provide_standard_frame_data = NULL; } #ifdef DEBUG if (_x_va_accel_guarded_render(vo_frame)) { vaapi_accel_t *accel = vo_frame->accel_data; _x_assert(accel->index == RENDER_SURFACES); } #endif } vaapi_frame_t *_x_va_frame_alloc_frame (vaapi_context_impl_t *va, vo_driver_t *driver, int guarded_render) { static const struct vaapi_accel_funcs_s accel_funcs = { .vaapi_init = _x_va_accel_vaapi_init, .profile_from_imgfmt = _x_va_accel_profile_from_imgfmt, .get_context = _x_va_accel_get_context, .lock_vaapi = _x_va_accel_lock_decode_dummy, .unlock_vaapi = NULL, .get_vaapi_surface = _x_va_accel_get_vaapi_surface, .render_vaapi_surface = NULL, .release_vaapi_surface = NULL, .guarded_render = _x_va_accel_guarded_render, }; static const struct vaapi_accel_funcs_s accel_funcs_guarded = { .vaapi_init = _x_va_accel_vaapi_init, .profile_from_imgfmt = _x_va_accel_profile_from_imgfmt, .get_context = _x_va_accel_get_context, .lock_vaapi = _x_va_accel_lock_decode_dummy, .unlock_vaapi = NULL, .get_vaapi_surface = _x_va_accel_alloc_vaapi_surface, .render_vaapi_surface = _x_va_accel_render_vaapi_surface, .release_vaapi_surface = _x_va_accel_release_vaapi_surface, .guarded_render = _x_va_accel_guarded_render, }; vaapi_frame_t *frame; if (va->num_frames >= sizeof(va->frames) / sizeof(va->frames[0])) { xprintf(va->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "frame limit (%u) exceeded\n", va->num_frames); return NULL; } frame = (vaapi_frame_t *)_mem_frame_alloc_frame(driver, sizeof(vaapi_frame_t)); if (!frame) return NULL; frame->mem_frame.vo_frame.accel_data = &frame->vaapi_accel_data; frame->ctx_impl = va; frame->vaapi_accel_data.f = guarded_render ? &accel_funcs_guarded : &accel_funcs; frame->vaapi_accel_data.index = guarded_render ? RENDER_SURFACES : va->num_frames; va->frames[va->num_frames] = &frame->mem_frame.vo_frame; va->num_frames++; return frame; } xine-lib-1.2/src/video_out/vaapi/xine_va_display_wl.c0000644000175000017500000000617614647725152020606 0ustar meme/* * Copyright (C) 2022 the xine project * Copyright (C) 2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * VAAPI display for Wayland * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "va_display_wayland" #include "xine_va_display_plugin.h" #include #include /* visual types */ #include #include #include /* * xine module */ static void _module_dispose(xine_module_t *module) { xine_va_display_plugin_t *p = (xine_va_display_plugin_t *)module; vaTerminate(p->display.va_display); free(p); } static xine_module_t *_get_instance(xine_module_class_t *class_gen, const void *data) { const va_display_plugin_params_t *params = data; const xine_wayland_visual_t *vis_wl = params->visual; xine_va_display_plugin_t *p; VADisplay dpy = NULL; VAStatus vaStatus; int maj, min; (void)class_gen; if (params->visual_type != XINE_VISUAL_TYPE_WAYLAND) return NULL; dpy = vaGetDisplayWl(vis_wl->display); if (!vaDisplayIsValid(dpy)) return NULL; vaStatus = vaInitialize(dpy, &maj, &min); if (vaStatus != VA_STATUS_SUCCESS) { xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Error: vaInitialize: %s [0x%04x]\n", vaErrorStr(vaStatus), vaStatus); vaTerminate(dpy); return NULL; } p = calloc(1, sizeof(*p)); if (!p) { vaTerminate(dpy); return NULL; } p->xine = params->xine; p->display.va_display = dpy; p->module.dispose = _module_dispose; xprintf(params->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Using libva %d.%d\n", maj, min); return &p->module; } /* * plugin */ static void *_init_class(xine_t *xine, const void *params) { static const xine_module_class_t xine_class = { .get_instance = _get_instance, .description = N_("VA display provider (WAYLAND)"), .identifier = "va_display_wayland", .dispose = NULL, }; (void)xine; (void)params; return (void *)&xine_class; } static const xine_module_info_t module_info = { .priority = 10, .type = "va_display_v1", .sub_type = XINE_VISUAL_TYPE_WAYLAND, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "va_display_wayland", XINE_VERSION_CODE, &module_info, _init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }, }; xine-lib-1.2/src/video_out/vaapi/vaapi_egl.h0000644000175000017500000000227014647725152016651 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2021-2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * vaapi_egl.c, VAAPI -> OpenGL/EGL interop * */ #ifndef XINE_VAAPI_EGL_H_ #define XINE_VAAPI_EGL_H_ #include struct xine_gl; struct xine_glconv_t; struct xine_va_display_t; struct xine_glconv_t *_glconv_vaegl_init(xine_t *xine, struct xine_gl *gl, struct xine_va_display_t *); #endif /* XINE_VAAPI_EGL_H_ */ xine-lib-1.2/src/video_out/vaapi/vaapi_egl.c0000644000175000017500000003672614647725152016661 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2021-2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * vaapi_egl.c, VAAPI -> OpenGL/EGL interop * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "vaapi_egl.h" #include #include #include #include #ifdef HAVE_VA_VA_DRMCOMMON_H # include #endif #define LOG_MODULE "vaapi_egl" #include #include //#include "vaapi_util.h" #include "accel_vaapi.h" #include "xine_va_display.h" /* * NOTE: this module is linked against VAAPI only. * OpenGL and EGL is used via xine_gl. */ #include "../opengl/xine_gl.h" #include "../hw_frame.h" /* Required: VAAPI surface DRM export */ #ifdef VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 /* * OpenGL(ES) compat */ #if 1||defined(HAVE_GLES2_GL_H) # include #elif defined(HAVE_GL_GL_H) # include #else typedef unsigned int GLenum; typedef unsigned int GLuint; typedef unsigned char GLubyte; typedef int GLsizei; #endif #ifndef GL_EXTENSIONS # define GL_EXTENSIONS 0x1F03 #endif #ifndef APIENTRY # define APIENTRY #endif #ifndef APIENTRYP # define APIENTRYP APIENTRY * #endif #ifndef GL_TEXTURE_2D # define GL_TEXTURE_2D 0x0DE1 #endif #ifndef GL_TEXTURE0 #define GL_TEXTURE0 0x84C0 #endif /* * EGL compat */ #ifdef HAVE_EGL_EGL_H # include #else # define EGL_HEIGHT 0x3056 # define EGL_NONE 0x3038 # define EGL_WIDTH 0x3057 typedef int32_t EGLint; #endif #ifdef HAVE_EGL_EGLEXT_H # include #endif #ifndef EGL_EXT_image_dma_buf_import # define EGL_LINUX_DMA_BUF_EXT 0x3270 # define EGL_LINUX_DRM_FOURCC_EXT 0x3271 # define EGL_DMA_BUF_PLANE0_FD_EXT 0x3272 # define EGL_DMA_BUF_PLANE0_OFFSET_EXT 0x3273 # define EGL_DMA_BUF_PLANE0_PITCH_EXT 0x3274 #endif #ifndef EGL_EXT_image_dma_buf_import_modifiers # define EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT 0x3443 # define EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT 0x3444 #endif #ifndef GL_OES_EGL_image #define GL_OES_EGL_image 1 typedef void *GLeglImageOES; typedef void (*PFNGLEGLIMAGETARGETTEXTURE2DOESPROC)(GLenum target, GLeglImageOES image); #endif /* * VAAPI -> OpenGL texture import */ typedef struct glconv_vaapi_egl_t glconv_vaapi_egl_t; struct glconv_vaapi_egl_t { xine_glconv_t api; xine_t *xine; xine_gl_t *gl; PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES; void (APIENTRYP glBindTexture) (GLenum target, GLuint texture); GLenum (APIENTRYP glGetError) (void); void *egl_image[3]; }; static inline int _va_check_status(glconv_vaapi_egl_t *this, VAStatus vaStatus, const char *msg) { if (vaStatus != VA_STATUS_SUCCESS) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error : %s: %s [0x%04x]\n", msg, vaErrorStr(vaStatus), vaStatus); return 0; } return 1; } static void _release_images(glconv_vaapi_egl_t *c) { unsigned i; for (i = 0; i < sizeof(c->egl_image) / sizeof(c->egl_image[0]); i++) if (c->egl_image[i]) c->gl->eglDestroyImageKHR(c->gl, c->egl_image[i]); } static void *_create_egl_image(glconv_vaapi_egl_t *c, unsigned width, unsigned height, unsigned drm_format, int fd, unsigned offset, unsigned pitch, uint64_t modifier) { EGLint attribs[] = { EGL_WIDTH, width, EGL_HEIGHT, height, EGL_LINUX_DRM_FOURCC_EXT, drm_format, EGL_DMA_BUF_PLANE0_FD_EXT, fd, EGL_DMA_BUF_PLANE0_OFFSET_EXT, offset, EGL_DMA_BUF_PLANE0_PITCH_EXT, pitch, EGL_DMA_BUF_PLANE0_MODIFIER_LO_EXT, modifier & 0xffffffff, EGL_DMA_BUF_PLANE0_MODIFIER_HI_EXT, modifier >> 32, EGL_NONE }; void *egl_image; egl_image = c->gl->eglCreateImageKHR(c->gl, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); if (!egl_image) xprintf(c->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": eglCreateImageKHR() failed\n"); return egl_image; } static int _glconv_vaegl_get_textures(xine_glconv_t *glconv, vo_frame_t *vo_frame, unsigned target, unsigned *texture, unsigned *_num_texture, unsigned *_sw_format) { glconv_vaapi_egl_t *c = xine_container_of(glconv, glconv_vaapi_egl_t, api); vaapi_accel_t *accel = vo_frame->accel_data; ff_vaapi_context_t *va_context; ff_vaapi_surface_t *va_surface; unsigned layer, sw_format, num_texture, plane_width[3], plane_height[3]; int vaapi_locked, result = -1; VADRMPRIMESurfaceDescriptor desc; VAStatus vaStatus; #if 0 vaapi_context_impl_t *va; #endif _x_assert(vo_frame->format == XINE_IMGFMT_VAAPI); _x_assert(vo_frame->accel_data != NULL); *_sw_format = *_num_texture = 0; va_context = accel->f->get_context (vo_frame); if (!va_context) { xprintf(c->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Invalid VA context\n"); return -1; } /* driver lock */ vaapi_locked = accel->f->lock_vaapi(vo_frame); #if 0 /* no context change, please */ va = xine_container_of(va_context, vaapi_context_impl_t, c); pthread_mutex_lock(&va->ctx_lock); if (accel->index >= RENDER_SURFACES) { xprintf(c->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Invalid VA surface index\n"); goto fail; } #endif va_surface = &va_context->va_render_surfaces[accel->index]; if (va_surface->va_surface_id == VA_INVALID_SURFACE) { xprintf(c->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Invalid VA surface\n"); goto fail; } _release_images(c); vaStatus = vaSyncSurface(va_context->va_display, va_surface->va_surface_id); if (!_va_check_status(c, vaStatus, "vaSyncSurface()")) goto fail; vaStatus = vaExportSurfaceHandle (va_context->va_display, va_surface->va_surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, VA_EXPORT_SURFACE_SEPARATE_LAYERS | VA_EXPORT_SURFACE_READ_ONLY, &desc); if (!_va_check_status(c, vaStatus, "vaExportSurfaceHandle()")) goto fail; if (desc.num_layers > sizeof(c->egl_image) / sizeof(c->egl_image[0])) { xprintf(c->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Too many layers (%d)\n", desc.num_layers); goto fail_fds; } switch (desc.fourcc) { case VA_FOURCC_P010: /* 'R16 ', 'GR32' */ case VA_FOURCC_NV12: /* 'R8 ', 'GR88' */ num_texture = 2; for (layer = 0; layer < 2; layer++) { plane_width[layer] = va_context->width >> layer; plane_height[layer] = va_context->height >> layer; } sw_format = XINE_IMGFMT_NV12; break; case VA_FOURCC_YV12: case VA_FOURCC_I420: num_texture = 3; for (layer = 0; layer < 3; layer++) { plane_width[layer] = va_context->width >> (!!layer); plane_height[layer] = va_context->height >> (!!layer); } sw_format = XINE_IMGFMT_YV12; break; default: xprintf(c->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VA DRM fourcc %4.4s not supported\n", (const char *)&desc.fourcc); goto fail_fds; } for (layer = 0; layer < desc.num_layers; layer++) { unsigned obj_idx = desc.layers[layer].object_index[0]; GLenum err; if (desc.layers[layer].num_planes > 1) { xprintf(c->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": DRM composed layers not supported\n"); goto fail_fds; } lprintf(" layer %d: fd %d, pitch %d, VAAPI image fourcc %4.4s, DRM plane fourcc %4.4s\n", layer, desc.objects[obj_idx].fd, desc.layers[layer].pitch[0], (const char *)&desc.fourcc, (const char *)&desc.layers[layer].drm_format); c->egl_image[layer] = _create_egl_image(c, plane_width[layer], plane_height[layer], desc.layers[layer].drm_format, desc.objects[obj_idx].fd, desc.layers[layer].offset[0], desc.layers[layer].pitch[0], desc.objects[obj_idx].drm_format_modifier); if (!c->egl_image[layer]) { xprintf(c->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": eglCreateImageKHR() failed\n"); goto fail_fds; } c->glBindTexture (target, texture[layer]); c->glEGLImageTargetTexture2DOES (target, c->egl_image[layer]); if ((err = c->glGetError())) { xprintf(c->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Texture import failed: 0x%04x\n", err); goto fail_fds; } } *_num_texture = num_texture; *_sw_format = sw_format; result = 0; fail_fds: for (layer = 0; layer < desc.num_objects; layer++) close (desc.objects[layer].fd); fail: #if 0 pthread_mutex_unlock(&va->ctx_lock); #endif if (vaapi_locked) accel->f->unlock_vaapi(vo_frame); return result; } static void _glconv_vaegl_destroy(xine_glconv_t **p) { if (*p) { glconv_vaapi_egl_t *c = xine_container_of(*p, glconv_vaapi_egl_t, api); _release_images(c); _x_freep(p); } } /* test conversion */ static int _test(glconv_vaapi_egl_t *c, VADisplay *va_display) { VASurfaceID va_surface_id; VAStatus vaStatus; int result = -1; if (!c->gl->make_current (c->gl)) return -1; void (*glGenTextures) (GLsizei n, GLuint *textures) = c->gl->get_proc_address(c->gl, "glGenTextures"); void (*glDeleteTextures) (GLsizei n, const GLuint *textures) = c->gl->get_proc_address(c->gl, "glDeleteTextures"); void (*glActiveTexture) (GLenum texture) = c->gl->get_proc_address(c->gl, "glActiveTexture"); void (*glEnable) (GLenum cap) = c->gl->get_proc_address(c->gl, "glEnable"); void (*glDisable) (GLenum cap) = c->gl->get_proc_address(c->gl, "glDisable"); if (!glGenTextures || !glDeleteTextures || !glActiveTexture || !glEnable || !glDisable) { c->gl->release_current (c->gl); return -1; } vaStatus = vaCreateSurfaces(va_display, VA_RT_FORMAT_YUV420, 1920, 1080, &va_surface_id, 1, NULL, 0); if (_va_check_status(c, vaStatus, "vaCreateSurfaces()")) { VAImage va_image; vaStatus = vaDeriveImage(va_display, va_surface_id, &va_image); if (_va_check_status(c, vaStatus, "vaDeriveImage()")) { vaStatus = vaSyncSurface(va_display, va_surface_id); if (_va_check_status(c, vaStatus, "vaSyncSurface()")) { VADRMPRIMESurfaceDescriptor desc; vaStatus = vaExportSurfaceHandle (va_display, va_surface_id, VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2, VA_EXPORT_SURFACE_SEPARATE_LAYERS | VA_EXPORT_SURFACE_READ_ONLY, &desc); if (_va_check_status(c, vaStatus, "vaExportSurfaceHandle()")) { unsigned layer; result = 0; for (layer = 0; layer < desc.num_layers; layer++) { unsigned obj_idx = desc.layers[layer].object_index[0]; if (desc.layers[layer].num_planes > 1) { xprintf(c->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": DRM composed layers not supported\n"); result = -1; } else { void *egl_image = _create_egl_image(c, va_image.width >> (!!layer), va_image.height >> (!!layer), desc.layers[layer].drm_format, desc.objects[obj_idx].fd, desc.layers[layer].offset[0], desc.layers[layer].pitch[0], desc.objects[obj_idx].drm_format_modifier); if (!egl_image) { result = -1; } else { GLuint tex, err; glEnable(GL_TEXTURE_2D); glGenTextures(1, &tex); glActiveTexture (GL_TEXTURE0); c->glBindTexture (GL_TEXTURE_2D, tex); c->glEGLImageTargetTexture2DOES (GL_TEXTURE_2D, egl_image); if ((err = c->glGetError())) { xprintf(c->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Texture import failed: 0x%x\n", err); result = -1; } c->gl->eglDestroyImageKHR(c->gl, egl_image); glDeleteTextures(1, &tex); glDisable(GL_TEXTURE_2D); } } } for (layer = 0; layer < desc.num_objects; layer++) close(desc.objects[layer].fd); } } } vaStatus = vaSyncSurface(va_display, va_surface_id); _va_check_status(c, vaStatus, "vaSyncSurface()"); vaStatus = vaDestroySurfaces(va_display, &va_surface_id, 1); _va_check_status(c, vaStatus, "vaDestroySurfaces()"); } c->gl->release_current (c->gl); return result; } xine_glconv_t *_glconv_vaegl_init(xine_t *xine, xine_gl_t *gl, xine_va_display_t *va_display) { glconv_vaapi_egl_t *c = NULL; int has_egl_image = 0; const GLubyte *(APIENTRYP glGetString) (GLenum name); if (!gl || !gl->get_proc_address || !gl->query_extensions) return NULL; if (!gl->eglCreateImageKHR) { xprintf(xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "No eglCreateImageKHR() detected\n"); return NULL; } if (!_x_gl_has_extension(gl->query_extensions(gl), "EGL_EXT_image_dma_buf_import")) { xprintf(xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "EGL extension EGL_EXT_image_dma_buf_import not available\n"); goto fail; } if (!gl->make_current (gl)) return NULL; glGetString = gl->get_proc_address(gl, "glGetString"); if (glGetString) has_egl_image = _x_gl_has_extension(glGetString(GL_EXTENSIONS), "GL_OES_EGL_image"); gl->release_current (gl); if (!has_egl_image) { xprintf(xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "OpenGL extension GL_OES_EGL_image not available\n"); goto fail; } c = calloc(1, sizeof(*c)); if (!c) return NULL; c->glGetError = gl->get_proc_address(gl, "glGetError"); c->glBindTexture = gl->get_proc_address(gl, "glBindTexture"); c->glEGLImageTargetTexture2DOES = gl->get_proc_address(gl, "glEGLImageTargetTexture2DOES"); if (!c->glGetError || !c->glBindTexture || !c->glEGLImageTargetTexture2DOES) goto fail; c->api.get_textures = _glconv_vaegl_get_textures; c->api.destroy = _glconv_vaegl_destroy; c->xine = xine; c->gl = gl; if (_test(c, va_display->va_display) < 0) goto fail; xprintf(xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VAAPI EGL interop enabled\n"); return &c->api; fail: free(c); xprintf(xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VAAPI EGL interop disabled\n"); return NULL; } #else /* VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 */ # warning VAAPI OpenGL/EGL interop disabled (old libva ?) xine_glconv_t *_glconv_vaegl_init(xine_t *xine, xine_gl_t *gl, xine_va_display_t *va_display) { (void)gl; (void)va_display; xprintf(xine, XINE_VERBOSITY_LOG, LOG_MODULE " VAAPI EGL interop not compiled in\n"); return NULL; } #endif /* VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2 */ xine-lib-1.2/src/video_out/xvmc_vld.c0000644000175000017500000001057314647725152015444 0ustar meme/* * Copyright (C) 2000-2020 the xine project * Copyright (C) 2004 the Unichrome project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xvmc_vld.c, X11 decoding accelerated video extension interface for xine * * Author: Thomas Hellström, (2004) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xxmc.h" #include #ifdef HAVE_VLDXVMC void xvmc_vld_frame(struct vo_frame_s *this_gen) { vo_frame_t *this = (vo_frame_t *) this_gen; xxmc_frame_t *cf = XXMC_FRAME(this); xine_vld_frame_t *vft = &(cf->xxmc_data.vld_frame); xxmc_frame_t *ff = XXMC_FRAME(vft->forward_reference_frame), *bf = XXMC_FRAME(vft->backward_reference_frame); XvMCMpegControl ctl; xxmc_driver_t *driver = (xxmc_driver_t *) cf->vo_frame.driver; XvMCSurface *fs=0, *bs=0; XvMCQMatrix qmx; ctl.BHMV_range = vft->mv_ranges[0][0]; ctl.BVMV_range = vft->mv_ranges[0][1]; ctl.FHMV_range = vft->mv_ranges[1][0]; ctl.FVMV_range = vft->mv_ranges[1][1]; ctl.picture_structure = vft->picture_structure; ctl.intra_dc_precision = vft->intra_dc_precision; ctl.picture_coding_type = vft->picture_coding_type; ctl.mpeg_coding = (vft->mpeg_coding == 0) ? XVMC_MPEG_1 : XVMC_MPEG_2; ctl.flags = 0; ctl.flags |= (vft->progressive_sequence) ? XVMC_PROGRESSIVE_SEQUENCE : 0 ; ctl.flags |= (vft->scan) ? XVMC_ALTERNATE_SCAN : XVMC_ZIG_ZAG_SCAN; ctl.flags |= (vft->pred_dct_frame) ? XVMC_PRED_DCT_FRAME : XVMC_PRED_DCT_FIELD; ctl.flags |= (this->top_field_first) ? XVMC_TOP_FIELD_FIRST : XVMC_BOTTOM_FIELD_FIRST; ctl.flags |= (vft->concealment_motion_vectors) ? XVMC_CONCEALMENT_MOTION_VECTORS : 0 ; ctl.flags |= (vft->q_scale_type) ? XVMC_Q_SCALE_TYPE : 0; ctl.flags |= (vft->intra_vlc_format) ? XVMC_INTRA_VLC_FORMAT : 0; ctl.flags |= (vft->second_field) ? XVMC_SECOND_FIELD : 0 ; if (ff) fs=ff->xvmc_surf; if (bf) bs=bf->xvmc_surf; /* * Below is for interlaced streams and second_field. */ if (ctl.picture_coding_type == XVMC_P_PICTURE) bs = cf->xvmc_surf; if ((qmx.load_intra_quantiser_matrix = vft->load_intra_quantizer_matrix)) { memcpy(qmx.intra_quantiser_matrix,vft->intra_quantizer_matrix, sizeof(qmx.intra_quantiser_matrix)); } if ((qmx.load_non_intra_quantiser_matrix = vft->load_non_intra_quantizer_matrix)) { memcpy(qmx.non_intra_quantiser_matrix,vft->non_intra_quantizer_matrix, sizeof(qmx.non_intra_quantiser_matrix)); } qmx.load_chroma_intra_quantiser_matrix = 0; qmx.load_chroma_non_intra_quantiser_matrix = 0; XVMCLOCKDISPLAY( driver->display ); XvMCLoadQMatrix(driver->display, &driver->context, &qmx); while((cf->xxmc_data.result = XvMCBeginSurface(driver->display, &driver->context, cf->xvmc_surf, fs, bs, &ctl))); XVMCUNLOCKDISPLAY( driver->display ); driver->cpu_saver = 0.; } void xvmc_vld_slice(vo_frame_t *this_gen) { xxmc_frame_t *cf = XXMC_FRAME(this_gen); xxmc_driver_t *driver = (xxmc_driver_t *) cf->vo_frame.driver; XVMCLOCKDISPLAY( driver->display ); cf->xxmc_data.result = XvMCPutSlice2(driver->display,&driver->context,cf->xxmc_data.slice_data, cf->xxmc_data.slice_data_size,cf->xxmc_data.slice_code); /* * If CPU-saving mode is enabled, sleep after every xxmc->sleep slice. This will free * up the cpu while the decoder is working on the slice. The value of xxmc->sleep is calculated * so that the decoder thread sleeps at most 50% of the frame delay, * assuming a 2.6 kernel clock of 1000 Hz. */ XVMCUNLOCKDISPLAY( driver->display ); if (driver->cpu_save_enabled) { driver->cpu_saver += 1.; if (driver->cpu_saver >= cf->xxmc_data.sleep) { usleep(1); driver->cpu_saver -= cf->xxmc_data.sleep; } } } #endif xine-lib-1.2/src/video_out/video_out_pgx64.c0000644000175000017500000014330014647725152016642 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_pgx64.c, Sun XVR100/PGX64/PGX24 output plugin for xine * * written and currently maintained by * Robin Kay * * Sun XVR-100 framebuffer graciously donated by Jake Goerzen. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include #include /* * The maximum number of frames that can be used in multi-buffering * configuration. */ #define MAX_MULTIBUF_FRAMES 15 /* * The maximum number of frames that can be safely taken out of circulation. */ #define MAX_DETAINED_FRAMES 10 /* m64 register defines */ #define M64_VRAM_MMAPBASE 0x00000000 #define M64_VRAM_MMAPLEN 0x00800000 #define M64_BUS_CNTL 0x128 #define M64_BUS_EXT_REG_EN 0x08000000 #define M64_OVERLAY_X_Y_START 0x000 #define M64_OVERLAY_X_Y_END 0x001 #define M64_OVERLAY_X_Y_LOCK 0x80000000 #define M64_OVERLAY_GRAPHICS_KEY_CLR 0x004 #define M64_OVERLAY_GRAPHICS_KEY_MSK 0x005 #define M64_OVERLAY_KEY_CNTL 0x006 #define M64_OVERLAY_KEY_EN 0x00000050 #define M64_OVERLAY_SCALE_INC 0x008 #define M64_OVERLAY_EXCLUSIVE_HORZ 0x016 #define M64_OVERLAY_EXCLUSIVE_VERT 0x017 #define M64_OVERLAY_EXCLUSIVE_EN 0x80000000 #define M64_OVERLAY_SCALE_CNTL 0x009 #define M64_OVERLAY_SCALE_EN 0xC0000000 #define M64_SCALER_HEIGHT_WIDTH 0x00A #define M64_SCALER_COLOUR_CNTL 0x054 #define M64_SCALER_H_COEFF0 0x055 #define M64_SCALER_H_COEFF0_DEFAULT 0x00002000 #define M64_SCALER_H_COEFF1 0x056 #define M64_SCALER_H_COEFF1_DEFAULT 0x0D06200D #define M64_SCALER_H_COEFF2 0x057 #define M64_SCALER_H_COEFF2_DEFAULT 0x0D0A1C0D #define M64_SCALER_H_COEFF3 0x058 #define M64_SCALER_H_COEFF3_DEFAULT 0x0C0E1A0C #define M64_SCALER_H_COEFF4 0x059 #define M64_SCALER_H_COEFF4_DEFAULT 0x0C14140C #define M64_SCALER_BUF0_OFFSET 0x00D #define M64_SCALER_BUF0_OFFSET_U 0x075 #define M64_SCALER_BUF0_OFFSET_V 0x076 #define M64_SCALER_BUF1_OFFSET 0x00E #define M64_SCALER_BUF1_OFFSET_U 0x077 #define M64_SCALER_BUF1_OFFSET_V 0x078 #define M64_SCALER_BUF_PITCH 0x00F #define M64_VIDEO_FORMAT 0x012 #define M64_VIDEO_FORMAT_YUV12 0x000A0000 #define M64_VIDEO_FORMAT_VYUY422 0x000B0000 #define M64_CAPTURE_CONFIG 0x014 #define M64_CAPTURE_CONFIG_BUF0 0x00000000 #define M64_CAPTURE_CONFIG_BUF1 0x20000000 static const int m64_bufaddr_regs_tbl[2][3] = { {M64_SCALER_BUF0_OFFSET, M64_SCALER_BUF0_OFFSET_U, M64_SCALER_BUF0_OFFSET_V}, {M64_SCALER_BUF1_OFFSET, M64_SCALER_BUF1_OFFSET_U, M64_SCALER_BUF1_OFFSET_V} }; /* pfb register defines */ #define PFB_VRAM_MMAPBASE 0x08000000 #define PFB_VRAM_MMAPLEN 0x02000000 #define PFB_REGS_MMAPBASE 0x10000000 #define PFB_REGS_MMAPLEN 0x00040000 #define PFB_CLOCK_CNTL_INDEX 0x002 #define PFB_CLOCK_CNTL_DATA 0x003 #define PFB_MC_FB_LOCATION 0x052 #define PFB_OV0_Y_X_START 0x100 #define PFB_OV0_Y_X_END 0x101 #define PFB_OV0_REG_LOAD_CNTL 0x104 #define PFB_OV0_REG_LOAD_LOCK 0x00000001 #define PFB_OV0_REG_LOAD_LOCK_READBACK 0x00000008 #define PFB_OV0_SCALE_CNTL 0x108 #define PFB_OV0_SCALE_EN 0x417f0000 #define PFB_OV0_SCALE_YUV12 0x00000A00 #define PFB_OV0_SCALE_VYUY422 0x00000B00 #define PFB_OV0_V_INC 0x109 #define PFB_OV0_P1_V_ACCUM_INIT 0x10A #define PFB_OV0_P23_V_ACCUM_INIT 0x10B #define PFB_OV0_P1_BLANK_LINES_AT_TOP 0x10C #define PFB_OV0_P23_BLANK_LINES_AT_TOP 0x10D #define PFB_OV0_BASE_ADDR 0x10F #define PFB_OV0_BUF0_BASE_ADRS 0x110 #define PFB_OV0_BUF1_BASE_ADRS 0x111 #define PFB_OV0_BUF2_BASE_ADRS 0x112 #define PFB_OV0_BUF3_BASE_ADRS 0x113 #define PFB_OV0_BUF4_BASE_ADRS 0x114 #define PFB_OV0_BUF5_BASE_ADRS 0x115 #define PFB_OV0_VID_BUF_PITCH0_VALUE 0x118 #define PFB_OV0_VID_BUF_PITCH1_VALUE 0x119 #define PFB_OV0_AUTO_FLIP_CNTL 0x11C #define PFB_OV0_AUTO_FLIP_BUF0 0x00000200 #define PFB_OV0_AUTO_FLIP_BUF3 0x00000243 #define PFB_OV0_DEINTERLACE_PATTERN 0x11D #define PFB_OV0_H_INC 0x120 #define PFB_OV0_STEP_BY 0x121 #define PFB_OV0_P1_H_ACCUM_INIT 0x122 #define PFB_OV0_P23_H_ACCUM_INIT 0x123 #define PFB_OV0_P1_X_START_END 0x125 #define PFB_OV0_P2_X_START_END 0x126 #define PFB_OV0_P3_X_START_END 0x127 #define PFB_OV0_FILTER_CNTL 0x128 #define PFB_OV0_FILTER_EN 0x0000000f #define PFB_OV0_GRPH_KEY_CLR_LOW 0x13B #define PFB_OV0_GRPH_KEY_CLR_HIGH 0x13C #define PFB_OV0_KEY_CNTL 0x13D #define PFB_OV0_KEY_EN 0x00000121 #define PFB_DISP_MERGE_CNTL 0x358 #define PFB_DISP_MERGE_EN 0xffff0000 static const int pfb_bufaddr_regs_tbl[2][3] = { {PFB_OV0_BUF0_BASE_ADRS, PFB_OV0_BUF1_BASE_ADRS, PFB_OV0_BUF2_BASE_ADRS}, {PFB_OV0_BUF3_BASE_ADRS, PFB_OV0_BUF4_BASE_ADRS, PFB_OV0_BUF5_BASE_ADRS}, }; /* Enumerations */ typedef enum { FB_TYPE_M64, FB_TYPE_PFB } fb_type_t; typedef enum { BUF_MODE_MULTI, BUF_MODE_MULTI_FAILED, BUF_MODE_SINGLE, BUF_MODE_DOUBLE } buf_mode_t; /* Structures */ struct pgx64_overlay_s { int x, y, width, height; Pixmap p; struct pgx64_overlay_s *next; }; typedef struct pgx64_overlay_s pgx64_overlay_t; typedef struct { video_driver_class_t vo_driver_class; xine_t *xine; } pgx64_driver_class_t; typedef struct { vo_frame_t vo_frame; int lengths[3], stripe_lengths[3], stripe_offsets[3], buffers[3]; int width, height, format, pitch, native_format, planes, procs_en; double ratio; uint8_t *buffer_ptrs[3]; } pgx64_frame_t; typedef struct { vo_driver_t vo_driver; vo_scale_t vo_scale; pgx64_driver_class_t *class; Display *display; int screen, depth; Drawable drawable; Dga_drawable dgadraw; GC gc; Visual *visual; Colormap cmap; fb_type_t fb_type; int devfd, fb_width, fb_depth, free_top, free_bottom, free_mark; int buffers[2][3]; uint32_t yuv12_native_format, yuv12_align; uint32_t vyuy422_native_format, vyuy422_align; uint8_t *vbase, *buffer_ptrs[2][3]; volatile uint32_t *vregs; pgx64_frame_t *current; pgx64_frame_t *multibuf[MAX_MULTIBUF_FRAMES]; pgx64_frame_t *detained[MAX_DETAINED_FRAMES]; int multibuf_frames, detained_frames; int chromakey_en, chromakey_changed, chromakey_regen_needed; pthread_mutex_t chromakey_mutex; pgx64_overlay_t *first_overlay; buf_mode_t buf_mode; int multibuf_en, dblbuf_select, delivered_format; int colour_key, colour_key_rgb, brightness, saturation, deinterlace_en; alphablend_t alphablend_extra_data; } pgx64_driver_t; /* * Dummy X11 error handler */ static int dummy_error_handler(Display *disp, XErrorEvent *errev) { return 0; } /* * Setup X11/DGA */ static int setup_dga(pgx64_driver_t *this) { Atom VIDEO_OVERLAY_WINDOW, VIDEO_OVERLAY_IN_USE, type_return; int format_return; unsigned long nitems_return, bytes_after_return; unsigned char *prop_return; XWindowAttributes win_attrs; XLockDisplay(this->display); this->dgadraw = XDgaGrabDrawable(this->display, this->drawable); if (!this->dgadraw) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: can't grab DGA drawable for video window\n")); XUnlockDisplay(this->display); return 0; } /* If the framebuffer hasn't already been mapped then open it and check it's * a supported type. We don't use the file descriptor returned from * dga_draw_devfd() because the FBIOVERTICAL ioctl doesn't work with it. */ if (!this->vbase) { char *devname; struct vis_identifier ident; DGA_DRAW_LOCK(this->dgadraw, -1); devname = dga_draw_devname(this->dgadraw); DGA_DRAW_UNLOCK(this->dgadraw); if ((this->devfd = xine_open_cloexec(devname, O_RDWR)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: can't open framebuffer device '%s'\n"), devname); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } if (ioctl(this->devfd, VIS_GETIDENTIFIER, &ident) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: ioctl failed (VIS_GETIDENTIFIER), bad device (%s)\n"), devname); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } if (strcmp("SUNWm64", ident.name) == 0) { this->fb_type = FB_TYPE_M64; } else if (strcmp("SUNWpfb", ident.name) == 0) { this->fb_type = FB_TYPE_PFB; } else { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: '%s' is not a xvr100/pgx64/pgx24 framebuffer device\n"), devname); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } } VIDEO_OVERLAY_WINDOW = XInternAtom(this->display, "VIDEO_OVERLAY_WINDOW", False); VIDEO_OVERLAY_IN_USE = XInternAtom(this->display, "VIDEO_OVERLAY_IN_USE", False); XGrabServer(this->display); if (XGetWindowProperty(this->display, RootWindow(this->display, this->screen), VIDEO_OVERLAY_WINDOW, 0, 1, False, XA_WINDOW, &type_return, &format_return, &nitems_return, &bytes_after_return, &prop_return) == Success) { if ((type_return == XA_WINDOW) && (format_return == 32) && (nitems_return == 1)) { Window wins = *(Window *)(void *)prop_return; XErrorHandler old_error_handler; old_error_handler = XSetErrorHandler(dummy_error_handler); if (XGetWindowProperty(this->display, wins, VIDEO_OVERLAY_IN_USE, 0, 0, False, AnyPropertyType, &type_return, &format_return, &nitems_return, &bytes_after_return, &prop_return) == Success) { XFree(prop_return); if (type_return != None) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: video overlay on this screen is already in use\n")); close(this->devfd); XSetErrorHandler(old_error_handler); XUngrabServer(this->display); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } } XSetErrorHandler(old_error_handler); } } if (!(XChangeProperty(this->display, RootWindow(this->display, this->screen), VIDEO_OVERLAY_WINDOW, XA_WINDOW, 32, PropModeReplace, (unsigned char *)&this->drawable, 1) && XChangeProperty(this->display, this->drawable, VIDEO_OVERLAY_IN_USE, XA_STRING, 8, PropModeReplace, NULL, 0))) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: unable to set window properties\n")); close(this->devfd); XUngrabServer(this->display); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } XUngrabServer(this->display); this->gc = XCreateGC(this->display, this->drawable, 0, NULL); XGetWindowAttributes(this->display, this->drawable, &win_attrs); this->depth = win_attrs.depth; this->visual = win_attrs.visual; this->cmap = XCreateColormap(this->display, this->drawable, this->visual, AllocNone); XSetWindowColormap(this->display, this->drawable, this->cmap); XUnlockDisplay(this->display); return 1; } /* * Cleanup X11/DGA */ static void cleanup_dga(pgx64_driver_t *this) { XLockDisplay(this->display); XFreeColormap(this->display, this->cmap); XFreeGC(this->display, this->gc); XDeleteProperty(this->display, this->drawable, XInternAtom(this->display, "VIDEO_OVERLAY_WINDOW", True)); XDeleteProperty(this->display, this->drawable, XInternAtom(this->display, "VIDEO_OVERLAY_IN_USE", True)); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); } /* * Dispose of any allocated image data within a pgx64_frame_t */ static void dispose_frame_internals(pgx64_frame_t *frame) { if (frame->vo_frame.base[0]) { free(frame->vo_frame.base[0]); frame->vo_frame.base[0] = NULL; } if (frame->vo_frame.base[1]) { free(frame->vo_frame.base[1]); frame->vo_frame.base[1] = NULL; } if (frame->vo_frame.base[2]) { free(frame->vo_frame.base[2]); frame->vo_frame.base[2] = NULL; } } /* * Update colour_key_rgb using the colour_key index */ static void update_colour_key_rgb(pgx64_driver_t *this) { XColor colour; colour.pixel = this->colour_key; XQueryColor(this->display, this->cmap, &colour); this->colour_key_rgb = ((colour.red & 0xff00) << 8) | (colour.green & 0xff00) | ((colour.blue & 0xff00) >> 8); } /* * Paint the output area with black borders, colour key, and any chorma keyed * overlays */ static void draw_overlays(pgx64_driver_t *this) { pgx64_overlay_t *ovl; ovl = this->first_overlay; XLockDisplay(this->display); while (ovl != NULL) { XCopyArea(this->display, ovl->p, this->drawable, this->gc, 0, 0, ovl->width, ovl->height, this->vo_scale.output_xoffset + ovl->x, this->vo_scale.output_yoffset + ovl->y); ovl = ovl->next; } XFlush(this->display); XUnlockDisplay(this->display); } static void repaint_output_area(pgx64_driver_t *this) { int i; XLockDisplay(this->display); XSetForeground(this->display, this->gc, BlackPixel(this->display, this->screen)); for (i=0; i<4; i++) { XFillRectangle(this->display, this->drawable, this->gc, this->vo_scale.border[i].x, this->vo_scale.border[i].y, this->vo_scale.border[i].w, this->vo_scale.border[i].h); } XSetForeground(this->display, this->gc, this->colour_key); XFillRectangle(this->display, this->drawable, this->gc, this->vo_scale.output_xoffset, this->vo_scale.output_yoffset, this->vo_scale.output_width, this->vo_scale.output_height); XFlush(this->display); XUnlockDisplay(this->display); pthread_mutex_lock(&this->chromakey_mutex); if (this->chromakey_en) { draw_overlays(this); } pthread_mutex_unlock(&this->chromakey_mutex); } /* * Reset video memory allocator and release detained frames */ static void vram_reset(pgx64_driver_t *this) { int i; this->free_mark = this->free_top; for (i=0; imultibuf_frames; i++) { this->multibuf[i]->procs_en = 0; } this->multibuf_frames = 0; for (i=0; idetained_frames; i++) { this->detained[i]->vo_frame.free(&this->detained[i]->vo_frame); } this->detained_frames = 0; } /* * Allocate a portion of video memory */ static int vram_alloc(pgx64_driver_t *this, int size) { if (this->free_mark - size < this->free_bottom) { return -1; } else { return this->free_mark -= size; } } /* * XINE VIDEO DRIVER FUNCTIONS */ static void pgx64_frame_proc_frame(vo_frame_t *frame_gen) { pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen; int i; frame->vo_frame.proc_called = 1; if (frame->procs_en) { for (i=0; iplanes; i++) { memcpy(frame->buffer_ptrs[i], frame->vo_frame.base[i], frame->lengths[i]); } } else { frame->vo_frame.proc_frame = NULL; frame->vo_frame.proc_slice = NULL; } } static void pgx64_frame_proc_slice(vo_frame_t *frame_gen, uint8_t **src) { pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen; int i, len; frame->vo_frame.proc_called = 1; if (frame->procs_en) { for (i=0; iplanes; i++) { len = (frame->lengths[i] - frame->stripe_offsets[i] < frame->stripe_lengths[i]) ? frame->lengths[i] - frame->stripe_offsets[i] : frame->stripe_lengths[i]; memcpy(frame->buffer_ptrs[i]+frame->stripe_offsets[i], src[i], len); frame->stripe_offsets[i] += len; } } else { frame->vo_frame.proc_frame = NULL; frame->vo_frame.proc_slice = NULL; } } static void pgx64_frame_field(vo_frame_t *frame_gen, int which_field) { /*pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen;*/ } static void pgx64_frame_dispose(vo_frame_t *frame_gen) { pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen; dispose_frame_internals(frame); free(frame); } static uint32_t pgx64_get_capabilities(vo_driver_t *this_gen) { /*pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen;*/ return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_SATURATION; } static vo_frame_t *pgx64_alloc_frame(vo_driver_t *this_gen) { /*pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen;*/ pgx64_frame_t *frame; frame = calloc(1, sizeof(pgx64_frame_t)); if (!frame) { return NULL; } pthread_mutex_init(&frame->vo_frame.mutex, NULL); frame->vo_frame.proc_frame = NULL; frame->vo_frame.proc_slice = NULL; frame->vo_frame.field = pgx64_frame_field; frame->vo_frame.dispose = pgx64_frame_dispose; return (vo_frame_t *)frame; } static void pgx64_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen; if ((width != frame->width) || (height != frame->height) || (ratio != frame->ratio) || (format != frame->format)) { int i; frame->procs_en = 0; dispose_frame_internals(frame); frame->width = width; frame->height = height; frame->ratio = ratio; frame->format = format; switch (format) { case XINE_IMGFMT_YUY2: frame->native_format = this->vyuy422_native_format; frame->pitch = ((width + this->vyuy422_align - 1) / this->vyuy422_align) * this->vyuy422_align; frame->planes = 1; frame->vo_frame.pitches[0] = frame->pitch * 2; frame->lengths[0] = frame->vo_frame.pitches[0] * height; frame->stripe_lengths[0] = frame->vo_frame.pitches[0] * 16; frame->vo_frame.base[0] = memalign(8, frame->lengths[0]); break; case XINE_IMGFMT_YV12: frame->native_format = this->yuv12_native_format; frame->pitch = ((width + this->yuv12_align - 1) / this->yuv12_align) * this->yuv12_align; frame->planes = 3; frame->vo_frame.pitches[0] = frame->pitch; frame->vo_frame.pitches[1] = ((((width + 1) / 2) + this->yuv12_align - 1) / this->yuv12_align) * this->yuv12_align; frame->vo_frame.pitches[2] = ((((width + 1) / 2) + this->yuv12_align - 1) / this->yuv12_align) * this->yuv12_align; frame->lengths[0] = frame->vo_frame.pitches[0] * height; frame->lengths[1] = frame->vo_frame.pitches[1] * ((height + 1) / 2); frame->lengths[2] = frame->vo_frame.pitches[2] * ((height + 1) / 2); frame->stripe_lengths[0] = frame->vo_frame.pitches[0] * 16; frame->stripe_lengths[1] = frame->vo_frame.pitches[1] * 8; frame->stripe_lengths[2] = frame->vo_frame.pitches[2] * 8; frame->vo_frame.base[0] = memalign(8, frame->lengths[0]); frame->vo_frame.base[1] = memalign(8, frame->lengths[1]); frame->vo_frame.base[2] = memalign(8, frame->lengths[2]); break; } for (i=0; iplanes; i++) { if (!frame->vo_frame.base[i]) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: frame plane malloc failed\n"); _x_abort(); } } } frame->stripe_offsets[0] = 0; frame->stripe_offsets[1] = 0; frame->stripe_offsets[2] = 0; } static void pgx64_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen; if ((frame->width != this->vo_scale.delivered_width) || (frame->height != this->vo_scale.delivered_height) || (frame->ratio != this->vo_scale.delivered_ratio) || (frame->format != this->delivered_format)) { this->vo_scale.delivered_width = frame->width; this->vo_scale.delivered_height = frame->height; this->vo_scale.delivered_ratio = frame->ratio; this->delivered_format = frame->format; this->vo_scale.force_redraw = 1; _x_vo_scale_compute_ideal_size(&this->vo_scale); vram_reset(this); if (this->multibuf_en) { this->buf_mode = BUF_MODE_MULTI; } else { this->buf_mode = BUF_MODE_MULTI_FAILED; } } XLockDisplay(this->display); DGA_DRAW_LOCK(this->dgadraw, -1); this->vo_scale.force_redraw = this->vo_scale.force_redraw || DGA_DRAW_MODIF(this->dgadraw); DGA_DRAW_UNLOCK(this->dgadraw); XUnlockDisplay(this->display); if (_x_vo_scale_redraw_needed(&this->vo_scale)) { short int *cliprects, wx0, wy0, wx1, wy1, cx0, cy0, cx1, cy1; int dgavis; _x_vo_scale_compute_output_size(&this->vo_scale); repaint_output_area(this); this->chromakey_regen_needed = 1; XLockDisplay(this->display); DGA_DRAW_LOCK(this->dgadraw, -1); dgavis = DGA_VIS_FULLY_OBSCURED; cliprects = dga_draw_clipinfo(this->dgadraw); wx0 = this->vo_scale.gui_win_x + this->vo_scale.output_xoffset; wy0 = this->vo_scale.gui_win_y + this->vo_scale.output_yoffset; wx1 = wx0 + this->vo_scale.output_width; wy1 = wy0 + this->vo_scale.output_height; while ((cy0 = *cliprects++) != DGA_Y_EOL) { cy1 = *cliprects++; while ((cx0 = *cliprects++) != DGA_X_EOL) { cx1 = *cliprects++; if ((cx0 < wx1) && (cy0 < wy1) && (cx1 > wx0) && (cy1 > wy0)) { dgavis = DGA_VIS_PARTIALLY_OBSCURED; } if ((cx0 <= wx0) && (cy0 <= wy0) && (cx1 >= wx1) && (cy1 >= wy1)) { dgavis = DGA_VIS_UNOBSCURED; } } } DGA_DRAW_UNLOCK(this->dgadraw); XUnlockDisplay(this->display); switch (this->fb_type) { case FB_TYPE_M64: this->vregs[M64_BUS_CNTL] |= le2me_32(M64_BUS_EXT_REG_EN); if (dgavis == DGA_VIS_FULLY_OBSCURED) { this->vregs[M64_OVERLAY_SCALE_CNTL] = 0; } else { this->vregs[M64_OVERLAY_X_Y_START] = le2me_32((wx0 << 16) | wy0 | M64_OVERLAY_X_Y_LOCK); this->vregs[M64_OVERLAY_X_Y_END] = le2me_32(((wx1 - 1) << 16) | (wy1 - 1)); this->vregs[M64_OVERLAY_GRAPHICS_KEY_CLR] = le2me_32(this->colour_key); this->vregs[M64_OVERLAY_GRAPHICS_KEY_MSK] = le2me_32(0xffffffff >> (32 - this->fb_depth)); this->vregs[M64_OVERLAY_KEY_CNTL] = le2me_32(M64_OVERLAY_KEY_EN); this->vregs[M64_OVERLAY_SCALE_INC] = le2me_32((((frame->width << 12) / this->vo_scale.output_width) << 16) | (((this->deinterlace_en ? frame->height/2 : frame->height) << 12) / this->vo_scale.output_height)); this->vregs[M64_SCALER_HEIGHT_WIDTH] = le2me_32((frame->width << 16) | (this->deinterlace_en ? frame->height/2 : frame->height)); this->vregs[M64_SCALER_COLOUR_CNTL] = le2me_32((this->saturation<<16) | (this->saturation<<8) | (this->brightness&0x7F)); this->vregs[M64_SCALER_H_COEFF0] = le2me_32(M64_SCALER_H_COEFF0_DEFAULT); this->vregs[M64_SCALER_H_COEFF1] = le2me_32(M64_SCALER_H_COEFF1_DEFAULT); this->vregs[M64_SCALER_H_COEFF2] = le2me_32(M64_SCALER_H_COEFF2_DEFAULT); this->vregs[M64_SCALER_H_COEFF3] = le2me_32(M64_SCALER_H_COEFF3_DEFAULT); this->vregs[M64_SCALER_H_COEFF4] = le2me_32(M64_SCALER_H_COEFF4_DEFAULT); this->vregs[M64_SCALER_BUF_PITCH] = le2me_32(this->deinterlace_en ? frame->pitch*2 : frame->pitch); this->vregs[M64_VIDEO_FORMAT] = le2me_32(frame->native_format); this->vregs[M64_OVERLAY_SCALE_CNTL] = le2me_32(M64_OVERLAY_SCALE_EN); } if ((dgavis == DGA_VIS_UNOBSCURED) && !this->chromakey_en) { this->vregs[M64_OVERLAY_EXCLUSIVE_VERT] = le2me_32((wy0 - 1) | ((wy1 - 1) << 16)); this->vregs[M64_OVERLAY_EXCLUSIVE_HORZ] = le2me_32(((wx0 + 7) / 8) | ((wx1 / 8) << 8) | (((this->fb_width / 8) - (wx1 / 8)) << 16) | M64_OVERLAY_EXCLUSIVE_EN); } else { this->vregs[M64_OVERLAY_EXCLUSIVE_HORZ] = 0; } break; case FB_TYPE_PFB: if (dgavis == DGA_VIS_FULLY_OBSCURED) { this->vregs[PFB_OV0_SCALE_CNTL] = 0; } else { int h_inc, h_step, ecp_div; this->vregs[PFB_CLOCK_CNTL_INDEX] = (this->vregs[PFB_CLOCK_CNTL_INDEX] & ~0x0000003f) | 0x00000008; ecp_div = (this->vregs[PFB_CLOCK_CNTL_DATA] >> 8) & 0x3; h_inc = (frame->width << (12 + ecp_div)) / this->vo_scale.output_width; h_step = 1; while (h_inc > 0x1fff) { h_inc >>= 1; h_step++; } this->vregs[PFB_OV0_REG_LOAD_CNTL] = PFB_OV0_REG_LOAD_LOCK; while (!(this->vregs[PFB_OV0_REG_LOAD_CNTL] & PFB_OV0_REG_LOAD_LOCK_READBACK)) {} this->vregs[PFB_DISP_MERGE_CNTL] = PFB_DISP_MERGE_EN; this->vregs[PFB_OV0_Y_X_START] = (wy0 << 16) | wx0; this->vregs[PFB_OV0_Y_X_END] = ((wy1 - 1) << 16) | (wx1 - 1); this->vregs[PFB_OV0_V_INC] = ((this->deinterlace_en ? frame->height/2 : frame->height) << 20) / this->vo_scale.output_height; this->vregs[PFB_OV0_P1_V_ACCUM_INIT] = 0x00180001; this->vregs[PFB_OV0_P23_V_ACCUM_INIT] = 0x00180001; this->vregs[PFB_OV0_P1_BLANK_LINES_AT_TOP] = (((this->deinterlace_en ? frame->height/2 : frame->height) - 1) << 16) | 0xfff; this->vregs[PFB_OV0_P23_BLANK_LINES_AT_TOP] = (((this->deinterlace_en ? frame->height/2 : frame->height) / 2 - 1) << 16) | 0x7ff; this->vregs[PFB_OV0_BASE_ADDR] = (this->vregs[PFB_MC_FB_LOCATION] & 0xffff) << 16; this->vregs[PFB_OV0_VID_BUF_PITCH0_VALUE] = this->deinterlace_en ? frame->vo_frame.pitches[0]*2 : frame->vo_frame.pitches[0]; this->vregs[PFB_OV0_VID_BUF_PITCH1_VALUE] = this->deinterlace_en ? frame->vo_frame.pitches[1]*2 : frame->vo_frame.pitches[1]; this->vregs[PFB_OV0_DEINTERLACE_PATTERN] = 0x000aaaaa; this->vregs[PFB_OV0_H_INC] = ((h_inc / 2) << 16) | h_inc; this->vregs[PFB_OV0_STEP_BY] = (h_step << 8) | h_step; this->vregs[PFB_OV0_P1_H_ACCUM_INIT] = (((0x00005000 + h_inc) << 7) & 0x000f8000) | (((0x00005000 + h_inc) << 15) & 0xf0000000); this->vregs[PFB_OV0_P23_H_ACCUM_INIT] = (((0x0000A000 + h_inc) << 6) & 0x000f8000) | (((0x0000A000 + h_inc) << 14) & 0x70000000); this->vregs[PFB_OV0_P1_X_START_END] = frame->width - 1; this->vregs[PFB_OV0_P2_X_START_END] = (frame->width / 2) - 1; this->vregs[PFB_OV0_P3_X_START_END] = (frame->width / 2) - 1; this->vregs[PFB_OV0_FILTER_CNTL] = PFB_OV0_FILTER_EN; this->vregs[PFB_OV0_GRPH_KEY_CLR_LOW] = this->colour_key_rgb; this->vregs[PFB_OV0_GRPH_KEY_CLR_HIGH] = this->colour_key_rgb | 0xff000000; this->vregs[PFB_OV0_KEY_CNTL] = PFB_OV0_KEY_EN; this->vregs[PFB_OV0_SCALE_CNTL] = PFB_OV0_SCALE_EN | frame->native_format; this->vregs[PFB_OV0_REG_LOAD_CNTL] = 0; } break; } } if (this->buf_mode == BUF_MODE_MULTI) { int i; if (!frame->procs_en) { for (i=0; iplanes; i++) { if ((frame->buffers[i] = vram_alloc(this, frame->lengths[i])) < 0) { if (this->detained_frames < MAX_DETAINED_FRAMES) { this->detained[this->detained_frames++] = frame; return; } else { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Warning: low video memory, multi-buffering disabled\n")); vram_reset(this); this->buf_mode = BUF_MODE_MULTI_FAILED; break; } } else { frame->buffer_ptrs[i] = this->vbase + frame->buffers[i]; memcpy(frame->buffer_ptrs[i], frame->vo_frame.base[i], frame->lengths[i]); } } if (this->buf_mode == BUF_MODE_MULTI) { frame->procs_en = 1; frame->vo_frame.proc_frame = pgx64_frame_proc_frame; frame->vo_frame.proc_slice = pgx64_frame_proc_slice; _x_assert(this->multibuf_frames < MAX_MULTIBUF_FRAMES); this->multibuf[this->multibuf_frames++] = frame; } } for (i=0; iplanes; i++) { this->buffers[this->dblbuf_select][i] = frame->buffers[i]; } } if (this->buf_mode != BUF_MODE_MULTI) { int i; if (this->buf_mode == BUF_MODE_MULTI_FAILED) { for (i=0; iplanes; i++) { if ((this->buffers[0][i] = vram_alloc(this, frame->lengths[i])) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: insuffucient video memory\n")); if (this->current != NULL) { this->current->vo_frame.free(&this->current->vo_frame); this->current = NULL; } frame->vo_frame.free(&frame->vo_frame); return; } else { this->buffer_ptrs[0][i] = this->vbase + this->buffers[0][i]; } } this->buf_mode = BUF_MODE_DOUBLE; for (i=0; iplanes; i++) { if ((this->buffers[1][i] = vram_alloc(this, frame->lengths[i])) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Warning: low video memory, double-buffering disabled\n")); this->buf_mode = BUF_MODE_SINGLE; break; } else { this->buffer_ptrs[1][i] = this->vbase + this->buffers[1][i]; } } if (this->buf_mode == BUF_MODE_SINGLE) { for (i=0; iplanes; i++) { this->buffers[1][i] = this->buffers[0][i]; this->buffer_ptrs[1][i] = this->vbase + this->buffers[1][i]; } } } for (i=0; iplanes; i++) { memcpy(this->buffer_ptrs[this->dblbuf_select][i], frame->vo_frame.base[i], frame->lengths[i]); } } switch (this->fb_type) { case FB_TYPE_M64: this->vregs[m64_bufaddr_regs_tbl[this->dblbuf_select][0]] = le2me_32(this->buffers[this->dblbuf_select][0]); this->vregs[m64_bufaddr_regs_tbl[this->dblbuf_select][1]] = le2me_32(this->buffers[this->dblbuf_select][1]); this->vregs[m64_bufaddr_regs_tbl[this->dblbuf_select][2]] = le2me_32(this->buffers[this->dblbuf_select][2]); this->vregs[M64_CAPTURE_CONFIG] = this->dblbuf_select ? le2me_32(M64_CAPTURE_CONFIG_BUF1) : le2me_32(M64_CAPTURE_CONFIG_BUF0); ioctl(this->devfd, FBIOVERTICAL); break; case FB_TYPE_PFB: this->vregs[pfb_bufaddr_regs_tbl[this->dblbuf_select][0]] = this->buffers[this->dblbuf_select][0]; this->vregs[pfb_bufaddr_regs_tbl[this->dblbuf_select][1]] = this->buffers[this->dblbuf_select][1] | 0x00000001; this->vregs[pfb_bufaddr_regs_tbl[this->dblbuf_select][2]] = this->buffers[this->dblbuf_select][2] | 0x00000001; this->vregs[PFB_OV0_AUTO_FLIP_CNTL] = this->dblbuf_select ? PFB_OV0_AUTO_FLIP_BUF3 : PFB_OV0_AUTO_FLIP_BUF0; ioctl(this->devfd, FBIOVERTICAL); /* Two vertical retraces are required for the new buffer to become active */ ioctl(this->devfd, FBIOVERTICAL); break; } this->dblbuf_select = 1 - this->dblbuf_select; if (this->current != NULL) { this->current->vo_frame.free(&this->current->vo_frame); } this->current = frame; } static void pgx64_overlay_begin(vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; /*pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen;*/ this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; if ((this->chromakey_en) && (changed || this->chromakey_regen_needed)) { pgx64_overlay_t *ovl, *next_ovl; this->chromakey_regen_needed = 0; this->chromakey_changed = 1; pthread_mutex_lock(&this->chromakey_mutex); XLockDisplay(this->display); XSetForeground(this->display, this->gc, this->colour_key); ovl = this->first_overlay; while (ovl != NULL) { next_ovl = ovl->next; XFreePixmap(this->display, ovl->p); XFillRectangle(this->display, this->drawable, this->gc, this->vo_scale.output_xoffset + ovl->x, this->vo_scale.output_yoffset + ovl->y, ovl->width, ovl->height); free(ovl); ovl = next_ovl; } this->first_overlay = NULL; XFreeColors(this->display, this->cmap, NULL, 0, ~0); XUnlockDisplay(this->display); } } #define scale_up(n) ((n) << 16) #define scale_down(n) ((n) >> 16) #define saturate(n, l, u) ((n) < (l) ? (l) : ((n) > (u) ? (u) : (n))) static void pgx64_overlay_key_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen; pgx64_overlay_t *ovl, **chromakey_ptr; int x_scale, y_scale, i, x, y, len, width; int use_clip_palette, max_palette_colour[2]; unsigned long palette[2][OVL_PALETTE_SIZE]; x_scale = scale_up(this->vo_scale.output_width) / frame->width; y_scale = scale_up(this->vo_scale.output_height) / frame->height; max_palette_colour[0] = -1; max_palette_colour[1] = -1; ovl = (pgx64_overlay_t *)malloc(sizeof(pgx64_overlay_t)); if (!ovl) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: overlay malloc failed\n"); return; } ovl->x = scale_down(overlay->x * x_scale); ovl->y = scale_down(overlay->y * y_scale); ovl->width = scale_down(overlay->width * x_scale); ovl->height = scale_down(overlay->height * y_scale); ovl->next = NULL; XLockDisplay(this->display); ovl->p = XCreatePixmap(this->display, this->drawable, ovl->width, ovl->height, this->depth); for (i=0, x=0, y=0; inum_rle; i++) { len = overlay->rle[i].len; while (len > 0) { use_clip_palette = 0; if (len > overlay->width) { width = overlay->width; len -= overlay->width; } else { width = len; len = 0; } if ((y >= overlay->hili_top) && (y <= overlay->hili_bottom) && (x <= overlay->hili_right)) { if ((x < overlay->hili_left) && (x + width - 1 >= overlay->hili_left)) { width -= overlay->hili_left - x; len += overlay->hili_left - x; } else if (x > overlay->hili_left) { use_clip_palette = 1; if (x + width - 1 > overlay->hili_right) { width -= overlay->hili_right - x; len += overlay->hili_right - x; } } } if (overlay->rle[i].color > max_palette_colour[use_clip_palette]) { int j; clut_t *src_clut; uint8_t *src_trans; if (use_clip_palette) { src_clut = (clut_t *)&overlay->hili_color; src_trans = (uint8_t *)&overlay->hili_trans; } else { src_clut = (clut_t *)&overlay->color; src_trans = (uint8_t *)&overlay->trans; } for (j=max_palette_colour[use_clip_palette]+1; j<=overlay->rle[i].color; j++) { if (src_trans[j]) { XColor col; int y, u, v, r, g, b; y = saturate(src_clut[j].y, 16, 235); u = saturate(src_clut[j].cb, 16, 240); v = saturate(src_clut[j].cr, 16, 240); y = (9 * y) / 8; r = y + (25 * v) / 16 - 218; g = y + (-13 * v) / 16 + (-25 * u) / 64 + 136; b = y + 2 * u - 274; col.red = saturate(r, 0, 255) << 8; col.green = saturate(g, 0, 255) << 8; col.blue = saturate(b, 0, 255) << 8; if (XAllocColor(this->display, this->cmap, &col)) { palette[use_clip_palette][j] = col.pixel; } else { if (src_clut[j].y > 127) { palette[use_clip_palette][j] = WhitePixel(this->display, this->screen); } else { palette[use_clip_palette][j] = BlackPixel(this->display, this->screen); } } } else { palette[use_clip_palette][j] = this->colour_key; } } max_palette_colour[use_clip_palette] = overlay->rle[i].color; } XSetForeground(this->display, this->gc, palette[use_clip_palette][overlay->rle[i].color]); XFillRectangle(this->display, ovl->p, this->gc, scale_down(x * x_scale), scale_down(y * y_scale), scale_down((x + width) * x_scale) - scale_down(x * x_scale), scale_down((y + 1) * y_scale) - scale_down(y * y_scale)); x += width; if (x == overlay->width) { x = 0; y++; } } } if (y < overlay->height) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: Notice: RLE data doesn't extend to height of overlay\n"); XFillRectangle(this->display, ovl->p, this->gc, scale_down(x * x_scale), scale_down(y * y_scale), ovl->width, scale_down(overlay->height * y_scale) - scale_down(y * y_scale)); } XUnlockDisplay(this->display); chromakey_ptr = &this->first_overlay; while ( *chromakey_ptr != NULL) { chromakey_ptr = &( *chromakey_ptr)->next; } *chromakey_ptr = ovl; } static void pgx64_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen; if (overlay->rle) { if (this->chromakey_changed) { pgx64_overlay_key_blend(this_gen, frame_gen, overlay); } else { if (frame->vo_frame.proc_slice == pgx64_frame_proc_slice) { /* FIXME: Implement out of place alphablending functions for better performance */ switch (frame->format) { case XINE_IMGFMT_YV12: { _x_blend_yuv(frame->buffer_ptrs, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); } break; case XINE_IMGFMT_YUY2: { _x_blend_yuy2(frame->buffer_ptrs[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } break; } } else { switch (frame->format) { case XINE_IMGFMT_YV12: { _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); } break; case XINE_IMGFMT_YUY2: { _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } break; } } } } } static void pgx64_overlay_end(vo_driver_t *this_gen, vo_frame_t *frame_gen) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; /*pgx64_frame_t *frame = (pgx64_frame_t *)frame_gen;*/ if (this->chromakey_changed) { draw_overlays(this); pthread_mutex_unlock(&this->chromakey_mutex); this->chromakey_changed = 0; } } static int pgx64_get_property(vo_driver_t *this_gen, int property) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; switch (property) { case VO_PROP_INTERLACED: return this->deinterlace_en; break; case VO_PROP_ASPECT_RATIO: return this->vo_scale.user_ratio; break; case VO_PROP_SATURATION: return this->saturation; break; case VO_PROP_BRIGHTNESS: return this->brightness; break; case VO_PROP_COLORKEY: return this->colour_key; break; default: return 0; break; } } static int pgx64_set_property(vo_driver_t *this_gen, int property, int value) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; switch (property) { case VO_PROP_INTERLACED: { this->deinterlace_en = value; this->vo_scale.force_redraw = 1; } break; case VO_PROP_ASPECT_RATIO: { if (value >= XINE_VO_ASPECT_NUM_RATIOS) { value = XINE_VO_ASPECT_AUTO; } this->vo_scale.user_ratio = value; this->vo_scale.force_redraw = 1; _x_vo_scale_compute_ideal_size(&this->vo_scale); } break; case VO_PROP_SATURATION: { this->saturation = value; this->vo_scale.force_redraw = 1; } break; case VO_PROP_BRIGHTNESS: { this->brightness = value; this->vo_scale.force_redraw = 1; } break; case VO_PROP_COLORKEY: { this->colour_key = value; this->vo_scale.force_redraw = 1; } break; } return value; } static void pgx64_get_property_min_max(vo_driver_t *this_gen, int property, int *min, int *max) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; switch (property) { case VO_PROP_SATURATION: { *min = 0; *max = 31; } break; case VO_PROP_BRIGHTNESS: { *min = -64; *max = 63; } break; case VO_PROP_COLORKEY: { *min = 0; *max = 0xffffffff >> (32 - this->fb_depth); } default: *min = 0; *max = 0; break; } } static int pgx64_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *data) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; switch (data_type) { case XINE_GUI_SEND_DRAWABLE_CHANGED: { XLockDisplay(this->display); cleanup_dga(this); this->drawable = (Drawable)data; if (!setup_dga(this)) { /* FIXME! There should be a better way to handle this */ _x_abort(); } XUnlockDisplay(this->display); } break; case XINE_GUI_SEND_EXPOSE_EVENT: { repaint_output_area(this); } break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { x11_rectangle_t *rect = data; int x1, y1, x2, y2; _x_vo_scale_translate_gui2video(&this->vo_scale, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->vo_scale, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2 - x1; rect->h = y2 - y1; } break; } return 0; } static int pgx64_redraw_needed(vo_driver_t *this_gen) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; int modif; XLockDisplay(this->display); DGA_DRAW_LOCK(this->dgadraw, -1); modif = DGA_DRAW_MODIF(this->dgadraw); DGA_DRAW_UNLOCK(this->dgadraw); XUnlockDisplay(this->display); if (modif || _x_vo_scale_redraw_needed(&this->vo_scale)) { this->vo_scale.force_redraw = 1; this->chromakey_regen_needed = 1; return 1; } return 0; } static void pgx64_dispose(vo_driver_t *this_gen) { pgx64_driver_t *this = (pgx64_driver_t *)(void *)this_gen; long page_size; cleanup_dga(this); page_size = sysconf(_SC_PAGE_SIZE); switch (this->fb_type) { case FB_TYPE_M64: this->vregs[M64_OVERLAY_EXCLUSIVE_HORZ] = 0; this->vregs[M64_OVERLAY_SCALE_CNTL] = 0; munmap(this->vbase, (((M64_VRAM_MMAPLEN + page_size - 1) / page_size) * page_size)); break; case FB_TYPE_PFB: this->vregs[PFB_OV0_SCALE_CNTL] = 0; munmap(this->vbase, (((PFB_VRAM_MMAPLEN + page_size - 1) / page_size) * page_size)); munmap((void *)this->vregs, (((PFB_REGS_MMAPLEN + page_size - 1) / page_size) * page_size)); break; } close(this->devfd); _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->vo_scale, this->class->xine->config); free(this); } static void pgx64_config_changed(void *user_data, xine_cfg_entry_t *entry) { vo_driver_t *this_gen = (vo_driver_t *)user_data; pgx64_driver_t *this = (pgx64_driver_t *)(void *)user_data; if (strcmp(entry->key, "video.device.pgx64_colour_key") == 0) { pgx64_set_property(this_gen, VO_PROP_COLORKEY, entry->num_value); update_colour_key_rgb(this); } else if (strcmp(entry->key, "video.device.pgx64_chromakey_en") == 0) { this->chromakey_en = entry->num_value; } else if (strcmp(entry->key, "video.device.pgx64_multibuf_en") == 0) { this->multibuf_en = entry->num_value; } } /* * XINE VIDEO DRIVER CLASS FUNCTIONS */ static const vo_info_t vo_info_pgx64 = { .priority = 10, .visual_type = XINE_VISUAL_TYPE_X11, }; static vo_driver_t *pgx64_init_driver(video_driver_class_t *class_gen, const void *visual_gen) { pgx64_driver_class_t *class = (pgx64_driver_class_t *)(void *)class_gen; config_values_t *config = class->xine->config; pgx64_driver_t *this; struct fbgattr attr; long page_size; this = calloc(1, sizeof(pgx64_driver_t)); if (!this) { return NULL; } _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->vo_driver.get_capabilities = pgx64_get_capabilities; this->vo_driver.alloc_frame = pgx64_alloc_frame; this->vo_driver.update_frame_format = pgx64_update_frame_format; this->vo_driver.overlay_begin = pgx64_overlay_begin; this->vo_driver.overlay_blend = pgx64_overlay_blend; this->vo_driver.overlay_end = pgx64_overlay_end; this->vo_driver.display_frame = pgx64_display_frame; this->vo_driver.get_property = pgx64_get_property; this->vo_driver.set_property = pgx64_set_property; this->vo_driver.get_property_min_max = pgx64_get_property_min_max; this->vo_driver.gui_data_exchange = pgx64_gui_data_exchange; this->vo_driver.redraw_needed = pgx64_redraw_needed; this->vo_driver.dispose = pgx64_dispose; _x_vo_scale_init(&this->vo_scale, 0, 0, config); this->vo_scale.user_ratio = XINE_VO_ASPECT_AUTO; this->vo_scale.user_data = ((x11_visual_t *)visual_gen)->user_data; this->vo_scale.frame_output_cb = ((x11_visual_t *)visual_gen)->frame_output_cb; this->vo_scale.dest_size_cb = ((x11_visual_t *)visual_gen)->dest_size_cb; this->class = class; this->display = ((x11_visual_t *)visual_gen)->display; this->screen = ((x11_visual_t *)visual_gen)->screen; this->drawable = ((x11_visual_t *)visual_gen)->d; if (!setup_dga(this)) { _x_vo_scale_cleanup (&this->vo_scale, config); free(this); return NULL; } if (ioctl(this->devfd, FBIOGATTR, &attr) < 0) { xprintf(class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx64: Error: ioctl failed (FBIOGATTR)\n")); cleanup_dga(this); close(this->devfd); free(this); return NULL; } page_size = sysconf(_SC_PAGE_SIZE); switch (this->fb_type) { case FB_TYPE_M64: if ((this->vbase = mmap(NULL, (((M64_VRAM_MMAPLEN + page_size - 1) / page_size) * page_size), PROT_READ | PROT_WRITE, MAP_SHARED, this->devfd, 0)) == MAP_FAILED) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: Error: unable to memory map framebuffer\n"); cleanup_dga(this); close(this->devfd); free(this); return NULL; } /* Using the endian swapped register page at 0x00800000 causes the * X server to behave abnormally so we use the one at the end of the * memory aperture and perform the swap ourselves. */ this->vregs = (uint32_t *)(void *)(this->vbase + 0x007ff800); this->fb_width = attr.fbtype.fb_width; this->fb_depth = attr.fbtype.fb_depth; this->free_top = attr.sattr.dev_specific[0]; this->free_bottom = attr.sattr.dev_specific[5] + attr.fbtype.fb_size; this->yuv12_native_format = M64_VIDEO_FORMAT_YUV12; this->yuv12_align = 8; this->vyuy422_native_format = M64_VIDEO_FORMAT_VYUY422; this->vyuy422_align = 8; break; case FB_TYPE_PFB: if ((this->vbase = mmap(NULL, (((PFB_VRAM_MMAPLEN + page_size - 1) / page_size) * page_size), PROT_READ | PROT_WRITE, MAP_SHARED, this->devfd, PFB_VRAM_MMAPBASE)) == MAP_FAILED) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: Error: unable to memory map framebuffer\n"); cleanup_dga(this); close(this->devfd); free(this); return NULL; } if ((this->vregs = (uint32_t *)(void *)mmap(NULL, (((PFB_REGS_MMAPLEN + page_size - 1) / page_size) * page_size), PROT_READ | PROT_WRITE, MAP_SHARED, this->devfd, PFB_REGS_MMAPBASE)) == MAP_FAILED) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx64: Error: unable to memory map framebuffer\n"); munmap(this->vbase, (((PFB_VRAM_MMAPLEN + page_size - 1) / page_size) * page_size)); cleanup_dga(this); close(this->devfd); free(this); return NULL; } this->fb_width = attr.fbtype.fb_width; this->fb_depth = attr.fbtype.fb_depth; this->free_top = attr.fbtype.fb_size - 0x2000; this->free_bottom = ((attr.fbtype.fb_width + 255) / 256) * 256 * attr.fbtype.fb_height * (attr.fbtype.fb_depth / 8); this->yuv12_native_format = PFB_OV0_SCALE_YUV12; this->yuv12_align = 16; this->vyuy422_native_format = PFB_OV0_SCALE_VYUY422; this->vyuy422_align = 8; break; } this->colour_key = config->register_num(config, "video.device.pgx64_colour_key", 1, _("video overlay colour key"), _("The colour key is used to tell the graphics card where it can overlay the video image. " "Try using different values if you see the video showing through other windows."), 20, pgx64_config_changed, this); update_colour_key_rgb(this); this->brightness = 0; this->saturation = 16; this->chromakey_en = config->register_bool(config, "video.device.pgx64_chromakey_en", 0, _("enable chroma keying"), _("Draw OSD graphics on top of the overlay colour key rather than blend them into each frame."), 20, pgx64_config_changed, this); this->multibuf_en = config->register_bool(config, "video.device.pgx64_multibuf_en", 1, _("enable multi-buffering"), _("Multi buffering increases performance at the expense of using more graphics memory."), 20, pgx64_config_changed, this); pthread_mutex_init(&this->chromakey_mutex, NULL); return (vo_driver_t *)this; } static void *pgx64_init_class(xine_t *xine, const void *visual_gen) { pgx64_driver_class_t *class; class = calloc(1, sizeof(pgx64_driver_class_t)); if (!class) { return NULL; } DGA_INIT(); class->vo_driver_class.open_plugin = pgx64_init_driver; class->vo_driver_class.identifier = "pgx64"; class->vo_driver_class.description = N_("xine video output plugin for Sun XVR100/PGX64/PGX24 framebuffers"); class->vo_driver_class.dispose = default_video_driver_class_dispose; class->xine = xine; return class; } const plugin_info_t xine_plugin_info[] EXPORTED = { {PLUGIN_VIDEO_OUT, 22, "pgx64", XINE_VERSION_CODE, &vo_info_pgx64, pgx64_init_class}, {PLUGIN_NONE, 0, NULL, 0, NULL, NULL} }; xine-lib-1.2/src/video_out/video_out_vdpau.c0000644000175000017500000036534614647725152017031 0ustar meme/* * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; * Copyright (C) 2008-2023 the xine project * Copyright (C) 2008 Christophe Thommeret * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * * video_out_vdpau.c, a video output plugin * using VDPAU (Video Decode and Presentation Api for Unix) * * */ /* #define LOG */ #define LOG_MODULE "video_out_vdpau" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "accel_vdpau.h" #define NUM_FRAMES_BACK 1 #ifndef HAVE_THREAD_SAFE_X11 #define LOCKDISPLAY /*define this if you have a buggy libX11/xcb*/ #endif typedef enum { DEINT_NONE = 0, DEINT_BOB, DEINT_HALF_TEMPORAL, DEINT_HALF_TEMPORAL_SPATIAL, DEINT_TEMPORAL, DEINT_TEMPORAL_SPATIAL, DEINT_LAST } _vdpau_deint_t; #define NUMBER_OF_DEINTERLACERS 5 static const char *const vdpau_deinterlacer_name[] = { "bob", "half temporal", "half temporal_spatial", "temporal", "temporal_spatial", NULL }; static const char *const vdpau_deinterlacer_description [] = { "bob\nBasic deinterlacing, doing 50i->50p.\n\n", "half temporal\nDisplays first field only, doing 50i->25p\n\n", "half temporal_spatial\nDisplays first field only, doing 50i->25p\n\n", "temporal\nVery good, 50i->50p\n\n", "temporal_spatial\nThe best, but very GPU intensive.\n\n", NULL }; static const VdpOutputSurfaceRenderBlendState blend = { VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION, VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_COLOR, VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, { 0.f, 0.f, 0.f, 0.f } }; typedef struct { VdpOutputSurface surface; uint32_t width, height, size; } vdpau_output_surface_t; typedef struct { VdpVideoSurface surface; VdpChromaType chroma; uint32_t width, height, a_width, a_height; } vdpau_video_surface_t; typedef struct { xine_grab_video_frame_t grab_frame; vo_driver_t *vo_driver; vdpau_output_surface_t render_surface; int width, height; uint32_t *rgba; } vdpau_grab_video_frame_t; typedef struct { vo_frame_t vo_frame; int width, height, format, flags; double ratio; vdpau_video_surface_t surf; int surface_cleared_nr; vdpau_accel_t vdpau_accel_data; } vdpau_frame_t; typedef struct { int x; /* x start of subpicture area */ int y; /* y start of subpicture area */ int width; /* width of subpicture area */ int height; /* height of subpicture area */ /* area within osd extent to scale video to */ int video_window_x; int video_window_y; int video_window_width; int video_window_height; /* extent of reference coordinate system */ int extent_width; int extent_height; int unscaled; /* true if it should be blended unscaled */ int use_dirty_rect; /* true if update of dirty rect only is possible */ vo_overlay_t *ovl; vdpau_output_surface_t render_surface; } vdpau_overlay_t; typedef struct { int id; const char *name; } vdpau_func_t; static const vdpau_func_t vdpau_funcs[] = { { VDP_FUNC_ID_PREEMPTION_CALLBACK_REGISTER, "VdpPreemptionCallbackRegister" }, { VDP_FUNC_ID_DEVICE_DESTROY, "VdpDeviceDestroy" }, { VDP_FUNC_ID_GET_ERROR_STRING, "VdpGetErrorString" }, { VDP_FUNC_ID_GET_API_VERSION, "VdpGetApiVersion" }, { VDP_FUNC_ID_GET_INFORMATION_STRING, "VdpGetInformationString" }, { VDP_FUNC_ID_VIDEO_SURFACE_QUERY_CAPABILITIES, "VdpVideoSurfaceQueryCapabilities" }, { VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES, "VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities" }, { VDP_FUNC_ID_VIDEO_SURFACE_CREATE, "VdpVideoSurfaceCreate" }, { VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, "VdpVideoSurfaceDestroy" }, { VDP_FUNC_ID_VIDEO_SURFACE_PUT_BITS_Y_CB_CR, "VdpVideoSurfacePutBitsYCbCr" }, { VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, "VdpVideoSurfaceGetBitsYCbCr" }, { VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, "VdpVideoSurfaceGetParameters" }, { VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_CAPABILITIES, "VdpOutputSurfaceQueryCapabilities" }, { VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES, "VdpOutputSurfaceQueryGetPutBitsNativeCapabilities" }, { VDP_FUNC_ID_OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES, "VdpOutputSurfaceQueryPutBitsYCbCrCapabilities" }, { VDP_FUNC_ID_OUTPUT_SURFACE_CREATE, "VdpOutputSurfaceCreate" }, { VDP_FUNC_ID_OUTPUT_SURFACE_DESTROY, "VdpOutputSurfaceDestroy" }, { VDP_FUNC_ID_OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE, "VdpOutputSurfaceRenderOutputSurface" }, { VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_NATIVE, "VdpOutputSurfacePutBitsNative"}, { VDP_FUNC_ID_OUTPUT_SURFACE_PUT_BITS_Y_CB_CR, "VdpOutputSurfacePutBitsYCbCr" }, { VDP_FUNC_ID_OUTPUT_SURFACE_GET_BITS_NATIVE, "VdpOutputSurfaceGetBitsNative" }, { VDP_FUNC_ID_VIDEO_MIXER_CREATE, "VdpVideoMixerCreate" }, { VDP_FUNC_ID_VIDEO_MIXER_DESTROY, "VdpVideoMixerDestroy" }, { VDP_FUNC_ID_VIDEO_MIXER_RENDER, "VdpVideoMixerRender" }, { VDP_FUNC_ID_VIDEO_MIXER_SET_ATTRIBUTE_VALUES, "VdpVideoMixerSetAttributeValues" }, { VDP_FUNC_ID_VIDEO_MIXER_SET_FEATURE_ENABLES, "VdpVideoMixerSetFeatureEnables" }, { VDP_FUNC_ID_VIDEO_MIXER_GET_FEATURE_ENABLES, "VdpVideoMixerGetFeatureEnables" }, { VDP_FUNC_ID_VIDEO_MIXER_QUERY_FEATURE_SUPPORT, "VdpVideoMixerQueryFeatureSupport" }, { VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_SUPPORT, "VdpVideoMixerQueryParameterSupport" }, { VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT, "VdpVideoMixerQueryAttributeSupport" }, { VDP_FUNC_ID_VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE, "VdpVideoMixerQueryParameterValueRange" }, { VDP_FUNC_ID_VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE, "VdpVideoMixerQueryAttributeValueRange" }, { VDP_FUNC_ID_GENERATE_CSC_MATRIX, "VdpGenerateCscMatrix" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, "VdpPresentationQueueTargetCreateX11" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_DESTROY, "VdpPresentationQueueTargetDestroy" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_CREATE, "VdpPresentationQueueCreate" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_DESTROY, "VdpPresentationQueueDestroy" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_DISPLAY, "VdpPresentationQueueDisplay" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE, "VdpPresentationQueueBlockUntilSurfaceIdle" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_SET_BACKGROUND_COLOR, "VdpPresentationQueueSetBackgroundColor" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_GET_TIME, "VdpPresentationQueueGetTime" }, { VDP_FUNC_ID_PRESENTATION_QUEUE_QUERY_SURFACE_STATUS, "VdpPresentationQueueQuerySurfaceStatus" }, { VDP_FUNC_ID_DECODER_QUERY_CAPABILITIES, "VdpDecoderQueryCapabilities" }, { VDP_FUNC_ID_DECODER_CREATE, "VdpDecoderCreate" }, { VDP_FUNC_ID_DECODER_DESTROY, "VdpDecoderDestroy" }, { VDP_FUNC_ID_DECODER_RENDER, "VdpDecoderRender" }, { 0, NULL } }; typedef struct { vo_driver_t vo_driver; VdpDevice vdp_device; VdpPresentationQueue vdp_queue; VdpPresentationQueueTarget vdp_queue_target; VdpGetProcAddress *vdp_get_proc_address; /* vdpau api funcs - same order as in vdpau_funcs!! */ union { void *funcs[46]; struct { VdpPreemptionCallbackRegister *preemption_callback_register; struct { VdpDeviceDestroy *destroy; } device; struct { VdpGetErrorString *error_string; VdpGetApiVersion *api_version; VdpGetInformationString *information_string; } get; struct { VdpVideoSurfaceQueryCapabilities *query_capabilities; VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *query_get_put_bits_ycbcr_capabilities; VdpVideoSurfaceCreate *create; VdpVideoSurfaceDestroy *destroy; VdpVideoSurfacePutBitsYCbCr *putbits_ycbcr; VdpVideoSurfaceGetBitsYCbCr *getbits_ycbcr; VdpVideoSurfaceGetParameters *get_parameters; } video_surface; struct { VdpOutputSurfaceQueryCapabilities *query_capabilities; VdpOutputSurfaceQueryGetPutBitsNativeCapabilities *query_get_put_bits_native_capabilities; VdpOutputSurfaceQueryPutBitsYCbCrCapabilities *query_put_bits_ycbcr_capabilities; VdpOutputSurfaceCreate *create; VdpOutputSurfaceDestroy *destroy; VdpOutputSurfaceRenderOutputSurface *render_output_surface; VdpOutputSurfacePutBitsNative *put_bits; VdpOutputSurfacePutBitsYCbCr *put_bits_ycbcr; VdpOutputSurfaceGetBitsNative *get_bits; } output_surface; struct { VdpVideoMixerCreate *create; VdpVideoMixerDestroy *destroy; VdpVideoMixerRender *render; VdpVideoMixerSetAttributeValues *set_attribute_values; VdpVideoMixerSetFeatureEnables *set_feature_enables; VdpVideoMixerGetFeatureEnables *get_feature_enables; VdpVideoMixerQueryFeatureSupport *query_feature_support; VdpVideoMixerQueryParameterSupport *query_parameter_support; VdpVideoMixerQueryAttributeSupport *query_attribute_support; VdpVideoMixerQueryParameterValueRange *query_parameter_value_range; VdpVideoMixerQueryAttributeValueRange *query_attribute_value_range; } video_mixer; VdpGenerateCSCMatrix *generate_csc_matrix; struct { VdpPresentationQueueTargetCreateX11 *target_create_x11; VdpPresentationQueueTargetDestroy *target_destroy; VdpPresentationQueueCreate *create; VdpPresentationQueueDestroy *destroy; VdpPresentationQueueDisplay *display; VdpPresentationQueueBlockUntilSurfaceIdle *block; VdpPresentationQueueSetBackgroundColor *set_background_color; VdpPresentationQueueGetTime *get_time; VdpPresentationQueueQuerySurfaceStatus *query_surface_status; } queue; struct { VdpDecoderQueryCapabilities *query_capabilities; VdpDecoderCreate *create; VdpDecoderDestroy *destroy; VdpDecoderRender *render; } decoder; } vdp; } a; vo_scale_t sc; Display *display; int screen; Drawable drawable; pthread_mutex_t drawable_lock; uint32_t display_width; uint32_t display_height; int ovl_changed; int num_ovls; int old_num_ovls; vdpau_overlay_t overlays[XINE_VORAW_MAX_OVL]; uint32_t *ovl_pixmap; int ovl_pixmap_size; VdpOutputSurface ovl_layer_surface; VdpRect ovl_src_rect; VdpRect ovl_dest_rect; VdpRect ovl_video_dest_rect; vdpau_output_surface_t ovl_main_render_surface; vdpau_video_surface_t soft_surface; int soft_surface_format; #define NOUTPUTSURFACEBUFFER 25 vdpau_output_surface_t output_surface_buffer[NOUTPUTSURFACEBUFFER]; int output_surface_buffer_size; int num_big_output_surfaces_created; pthread_mutex_t os_mutex; #define NOUTPUTSURFACE 8 vdpau_output_surface_t output_surfaces[NOUTPUTSURFACE]; uint8_t init_queue; uint8_t queue_user_length; uint8_t queue_length; uint8_t current_output_surface; vdpau_grab_video_frame_t *pending_grab_request; pthread_mutex_t grab_lock; pthread_cond_t grab_cond; struct { VdpVideoMixer handle; VdpChromaType chroma; int layer_bug; uint32_t width, height; uint32_t max_width, max_height, max_layers[4]; } video_mixer; const char* deinterlacers_name[NUMBER_OF_DEINTERLACERS+1]; int deinterlacers_method[NUMBER_OF_DEINTERLACERS]; int scaling_level_max; int scaling_level_current; VdpColor back_color; vdpau_frame_t *back_frame[ NUM_FRAMES_BACK ]; uint32_t capabilities, features; xine_t *xine; #define _VOVDP_S_BRIGHTNESS 0x0001 #define _VOVDP_S_CONTRAST 0x0002 #define _VOVDP_S_SATURATION 0x0004 #define _VOVDP_S_HUE 0x0008 #define _VOVDP_S_SHARPNESS 0x0010 #define _VOVDP_S_NOISE_RED 0x0020 #define _VOVDP_S_CSC 0x0040 #define _VOVDP_S_TRANSFORM 0x0080 #define _VOVDP_S_SCALE_LEVEL 0x0100 #define _VOVDP_S_DEINT 0x0200 #define _VOVDP_S_NO_CHROMA 0x0400 #define _VOVDP_S_INV_TELE 0x0800 #define _VOVDP_S_BGCOLOR 0x1000 #define _VOVDP_S_ALL 0x1fff uint32_t prop_changed; int transform; int hue; int saturation; int brightness; int contrast; int sharpness; int noise; int deinterlace; int deinterlace_method_hd; int deinterlace_method_sd; int enable_inverse_telecine; int honor_progressive; int skip_chroma; int sd_only_properties; int background; int vdp_runtime_nr; int reinit_needed; int surface_cleared_nr; int allocated_surfaces; int zoom_x; int zoom_y; int color_matrix; int cm_state; uint8_t cm_lut[32]; } vdpau_driver_t; /* import common color matrix stuff */ #define CM_LUT #define CM_HAVE_YCGCO_SUPPORT 1 #define CM_HAVE_BT2020_SUPPORT 1 #define CM_DRIVER_T vdpau_driver_t #include "color_matrix.c" typedef struct { video_driver_class_t driver_class; xine_t *xine; } vdpau_class_t; typedef struct { uint32_t val1, val2; uint8_t func; char name[31]; } _vdpau_features_t; #ifndef VDP_DECODER_PROFILE_MPEG4_PART2_ASP # define VDP_DECODER_PROFILE_MPEG4_PART2_ASP 13 #endif typedef enum { _VOVDP_V_yuv422 = 0, _VOVDP_V_yuv420, _VOVDP_V_yuy2, _VOVDP_V_yv12, _VOVDP_O_rgba, _VOVDP_O_rgba_soft, _VOVDP_O_yuv, _VOVDP_D_h264, _VOVDP_D_vc1, _VOVDP_D_mpeg12, _VOVDP_D_mpeg4, _VOVDP_M_noise_reduction, _VOVDP_M_sharpness, _VOVDP_I_temporal, _VOVDP_I_temporal_spatial, _VOVDP_I_inverse_telecine, _VOVDP_I_no_chroma, _VOVDP_A_background_color, _VOVDP_A_color_matrix, _VOVDP_LAST } _vdpau_feature_t; static const _vdpau_features_t vdpau_feature_list[] = { [_VOVDP_V_yuv422] = { VDP_CHROMA_TYPE_422, 0, 1, "video_yuv422" }, [_VOVDP_V_yuv420] = { VDP_CHROMA_TYPE_420, 0, 1, "video_yuv420" }, [_VOVDP_V_yuy2] = { VDP_CHROMA_TYPE_422, VDP_YCBCR_FORMAT_YUYV, 2, "video_yuy2" }, [_VOVDP_V_yv12] = { VDP_CHROMA_TYPE_420, VDP_YCBCR_FORMAT_YV12, 2, "video_yv12" }, [_VOVDP_O_rgba] = { VDP_RGBA_FORMAT_B8G8R8A8, 0, 3, "output_rgba" }, [_VOVDP_O_rgba_soft] = { VDP_RGBA_FORMAT_B8G8R8A8, 0, 4, "output_rgba_soft" }, [_VOVDP_O_yuv] = { VDP_RGBA_FORMAT_B8G8R8A8, VDP_YCBCR_FORMAT_V8U8Y8A8, 5, "output_yuv" }, [_VOVDP_D_h264] = { VDP_DECODER_PROFILE_H264_MAIN, VO_CAP_VDPAU_H264, 6, "decode_h264" }, [_VOVDP_D_vc1] = { VDP_DECODER_PROFILE_VC1_MAIN, VO_CAP_VDPAU_VC1, 6, "decode_vc1" }, [_VOVDP_D_mpeg12] = { VDP_DECODER_PROFILE_MPEG2_MAIN, VO_CAP_VDPAU_MPEG12, 6, "decode_mpeg12" }, [_VOVDP_D_mpeg4] = { VDP_DECODER_PROFILE_MPEG4_PART2_ASP, VO_CAP_VDPAU_MPEG4, 6, "decode_mpeg4" }, [_VOVDP_M_noise_reduction] = { VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION,VO_CAP_NOISE_REDUCTION, 7, "mix_noise_reduction" }, [_VOVDP_M_sharpness] = { VDP_VIDEO_MIXER_FEATURE_SHARPNESS, VO_CAP_SHARPNESS, 7, "mix_sharpness" }, [_VOVDP_I_temporal] = { VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL, 0, 7, "deint_temporal" }, [_VOVDP_I_temporal_spatial] = { VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL, 0, 7, "deint_temporal_spatial" }, [_VOVDP_I_inverse_telecine] = { VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE, 0, 7, "deint_inverse_telecine" }, [_VOVDP_I_no_chroma] = { VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE, 0, 8, "deint_no_chroma" }, [_VOVDP_A_background_color] = { VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR, 0, 8, "attr_background_color" }, [_VOVDP_A_color_matrix] = { VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX, 0, 8, "attr_color_matrix" }, [_VOVDP_LAST] = { 0, 0, 0, "" } }; static const uint32_t _vdpau_required_features = (1 << _VOVDP_V_yuv422) | (1 << _VOVDP_V_yuv420) | (1 << _VOVDP_V_yuy2) | (1 << _VOVDP_V_yv12) | (1 << _VOVDP_O_rgba) | (1 << _VOVDP_O_rgba_soft) | (1 << _VOVDP_O_yuv); static int _vdpau_feature_have (vdpau_driver_t *this, _vdpau_feature_t feature) { return (this->features & (1 << feature)) ? 1 : 0; } static void _vdpau_feature_names (char *buf, size_t bsize, uint32_t features) { char *p = buf, *e = buf + bsize; uint32_t u, bit; for (u = 0, bit = 1; u < sizeof(vdpau_feature_list)/sizeof(vdpau_feature_list[0]); u++, bit <<= 1) { if (features & bit) p += snprintf (p, e - p, "%s ", vdpau_feature_list[u].name); } if (p > buf) p--; *p = 0; } static void _vdpau_video_mixer_test (vdpau_driver_t *this, VdpVideoMixerParameter p, uint32_t *max_value) { uint32_t mx, my = 0; VdpStatus st; VdpBool ok; *max_value = 0; ok = VDP_FALSE; st = this->a.vdp.video_mixer.query_parameter_support (this->vdp_device, p, &ok); if ((st == VDP_STATUS_OK) && (ok != VDP_FALSE)) { st = this->a.vdp.video_mixer.query_parameter_value_range (this->vdp_device, p, &mx, &my); if (st == VDP_STATUS_OK) *max_value = my; } } static void _vdpau_feature_test (vdpau_driver_t *this) { char buf[1024], *p = buf, *e = buf + sizeof (buf); const _vdpau_features_t *f; uint32_t res = 0, bit, mx, my; VdpStatus st; VdpBool ok; { const char *s; this->video_mixer.max_layers[2] = ~0u; st = this->a.vdp.get.information_string (&s); if (st == VDP_STATUS_OK) { if (strstr (s, "G3DVL VDPAU")) this->video_mixer.max_layers[2] = 0; } else { s = this->a.vdp.get.error_string (st); } xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": implementation: %s\n", s); } for (bit = 1, f = vdpau_feature_list; f->func; bit <<= 1, f++) { uint32_t ml = 0, mr = 0; mx = my = 0; ok = VDP_FALSE; switch (f->func) { case 1: st = this->a.vdp.video_surface.query_capabilities (this->vdp_device, f->val1, &ok, &mx, &my); break; case 2: st = this->a.vdp.video_surface.query_get_put_bits_ycbcr_capabilities (this->vdp_device, f->val1, f->val2, &ok); break; case 3: st = this->a.vdp.output_surface.query_capabilities (this->vdp_device, f->val1, &ok, &mx, &my); break; case 4: st = this->a.vdp.output_surface.query_get_put_bits_native_capabilities (this->vdp_device, f->val1, &ok); break; case 5: st = this->a.vdp.output_surface.query_put_bits_ycbcr_capabilities (this->vdp_device, f->val1, f->val2, &ok); break; case 6: st = this->a.vdp.decoder.query_capabilities (this->vdp_device, f->val1, &ok, &ml, &mr, &mx, &my); break; case 7: st = this->a.vdp.video_mixer.query_feature_support (this->vdp_device, f->val1, &ok); break; case 8: st = this->a.vdp.video_mixer.query_attribute_support (this->vdp_device, f->val1, &ok); break; default: continue; } if (st != VDP_STATUS_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": failed to test %s: %s.\n", f->name, this->a.vdp.get.error_string (st)); } else if (ok != VDP_FALSE) { res |= bit; if ((f->func == 6) || (f->func == 7)) this->capabilities |= f->val2; if (mx && my) { p += snprintf (p, e - p, "%s(%ux%u) ", f->name, (unsigned int)mx, (unsigned int)my); } else { p += snprintf (p, e - p, "%s ", f->name); } } } #ifdef VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 for (mx = 0; mx < 9; mx++) { ok = VDP_FALSE; st = this->a.vdp.video_mixer.query_feature_support (this->vdp_device, VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 + mx, &ok); if ((st != VDP_STATUS_OK) || (ok == VDP_FALSE)) break; } this->scaling_level_max = mx; p += snprintf (p, e - p, "mix_scale_level_%u ", (unsigned int)mx); #endif _vdpau_video_mixer_test (this, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, &this->video_mixer.max_width); _vdpau_video_mixer_test (this, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT, &this->video_mixer.max_height); _vdpau_video_mixer_test (this, VDP_VIDEO_MIXER_PARAMETER_LAYERS, &this->video_mixer.max_layers[0]); if (this->video_mixer.max_width && this->video_mixer.max_height) p += snprintf (p, e - p, "mix(%ux%u) ", (unsigned int)this->video_mixer.max_width, (unsigned int)this->video_mixer.max_height); if (this->video_mixer.max_layers[0]) p += snprintf (p, e - p, "mix_layers(%u) ", (unsigned int)this->video_mixer.max_layers[0]); /* for performance, we join OSD layers before use. */ this->video_mixer.max_layers[0] = this->video_mixer.max_layers[0] ? 1 : 0; this->video_mixer.max_layers[1] = 0; this->video_mixer.max_layers[2] &= this->video_mixer.max_layers[0]; this->video_mixer.max_layers[3] = 0; if (p > buf) p--; *p = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": features available: %s.\n", buf); this->features = res; } static void vdpau_oslock_lock (vdpau_driver_t *this) { pthread_mutex_lock (&this->os_mutex); } static void vdpau_oslock_unlock (vdpau_driver_t *this) { pthread_mutex_unlock (&this->os_mutex); } #ifdef LOCKDISPLAY #define DO_LOCKDISPLAY(this) XLockDisplay (this->display) #define DO_UNLOCKDISPLAY(this) XUnlockDisplay (this->display) static void vdpau_lockdisplay (vo_frame_t *frame) { vdpau_driver_t *this = (vdpau_driver_t *)frame->driver; XLockDisplay (this->display); } static void vdpau_unlockdisplay (vo_frame_t *frame) { vdpau_driver_t *this = (vdpau_driver_t *)frame->driver; XUnlockDisplay (this->display); } #else #define DO_LOCKDISPLAY(this) #define DO_UNLOCKDISPLAY(this) #endif #define VDPAU_IF_ERROR(msg) \ if (st != VDP_STATUS_OK) \ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " msg ": %s.\n", this->a.vdp.get.error_string (st)) #define VDPAU_ERROR(msg) \ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " msg ": %s.\n", this->a.vdp.get.error_string (st)) static void vdpau_video_surf_delete (vdpau_driver_t *this, vdpau_video_surface_t *s) { if (s->surface != VDP_INVALID_HANDLE) { DO_LOCKDISPLAY (this); this->a.vdp.video_surface.destroy (s->surface); DO_UNLOCKDISPLAY (this); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": deleted video surface #%u.\n", (unsigned int)s->surface); s->surface = VDP_INVALID_HANDLE; } } static VdpStatus vdpau_video_surf_new (vdpau_driver_t *this, vdpau_video_surface_t *s) { VdpStatus st; DO_LOCKDISPLAY (this); st = this->a.vdp.video_surface.create (this->vdp_device, s->chroma, s->width, s->height, &s->surface); DO_UNLOCKDISPLAY (this); if (st != VDP_STATUS_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": failed to create %s video surface %u x %u: %s!!\n", s->chroma == VDP_CHROMA_TYPE_422 ? "4:2:2" : "4:2:0", (unsigned int)s->width, (unsigned int)s->height, this->a.vdp.get.error_string (st)); return st; } s->a_width = 0; s->a_height = 0; st = this->a.vdp.video_surface.get_parameters (s->surface, &s->chroma, &s->a_width, &s->a_height); if (st != VDP_STATUS_OK) { s->a_width = s->width; s->a_height = s->height; xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": failed to get video surface #%u parameters!!\n", (unsigned int)s->surface); return VDP_STATUS_OK; } if ((s->a_width < s->width) || (s->a_height < s->height)) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": video surface #%u size mismatch (%u x %u) != (%u x %u). Segfaults ahead!\n", (unsigned int)s->surface, (unsigned int)s->width, (unsigned int)s->height, (unsigned int)s->a_width, (unsigned int)s->a_height); } else if ((s->a_width != s->width) || (s->a_height != s->height)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": video surface #%u (%u x %u) aligned to (%u x %u).\n", (unsigned int)s->surface, (unsigned int)s->width, (unsigned int)s->height, (unsigned int)s->a_width, (unsigned int)s->a_height); } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": video surface #%u (%u x %u).\n", (unsigned int)s->surface, (unsigned int)s->width, (unsigned int)s->height); } return VDP_STATUS_OK; } static void vdpau_output_surf_delete (vdpau_driver_t *this, vdpau_output_surface_t *s) { if (s->surface != VDP_INVALID_HANDLE) { DO_LOCKDISPLAY (this); this->a.vdp.output_surface.destroy (s->surface); DO_UNLOCKDISPLAY (this); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": deleted output surface #%u.\n", (unsigned int)s->surface); s->surface = VDP_INVALID_HANDLE; } } static VdpStatus vdpau_output_surf_new (vdpau_driver_t *this, vdpau_output_surface_t *s) { VdpStatus st; DO_LOCKDISPLAY (this); st = this->a.vdp.output_surface.create (this->vdp_device, VDP_RGBA_FORMAT_B8G8R8A8, s->width, s->height, &s->surface); DO_UNLOCKDISPLAY (this); if (st != VDP_STATUS_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": failed to create output surface %u x %u: %s!!\n", (unsigned int)s->width, (unsigned int)s->height, this->a.vdp.get.error_string (st)); return st; } s->size = s->width * s->height; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": output surface #%u (%u x %u).\n", (unsigned int)s->surface, (unsigned int)s->width, (unsigned int)s->height); return VDP_STATUS_OK; } static VdpStatus vdpau_get_output_surface (vdpau_driver_t *this, uint32_t width, uint32_t height, vdpau_output_surface_t *r) { int i, full = 1; vdpau_output_surface_t *smallest = NULL, *best = NULL; vdpau_output_surface_t *l = &this->output_surface_buffer[0]; VdpStatus st = VDP_STATUS_OK; vdpau_oslock_lock (this); for (i = this->output_surface_buffer_size; i; --i, ++l) { if (l->surface == VDP_INVALID_HANDLE) full = 0; else if ((l->width >= width && l->height >= height) && (best == NULL || l->size < best->size)) best = l; else if (smallest == NULL || l->size < smallest->size) smallest = l; } if (best != NULL) { *r = *best; best->surface = VDP_INVALID_HANDLE; } else if (full) { *r = *smallest; smallest->surface = VDP_INVALID_HANDLE; } else r->surface = VDP_INVALID_HANDLE; vdpau_oslock_unlock (this); if (r->surface != VDP_INVALID_HANDLE && (r->width < width || r->height < height)) vdpau_output_surf_delete (this, r); if (r->surface == VDP_INVALID_HANDLE) { if (this->num_big_output_surfaces_created < this->output_surface_buffer_size) { /* We create big output surfaces which should fit for many output buffer requests as long * as the reuse buffer can hold them */ if (width < this->video_mixer.width) width = this->video_mixer.width; if (height < this->video_mixer.height) height = this->video_mixer.height; if (width < this->display_width) width = this->display_width; if (height < this->display_height) height = this->display_height; ++this->num_big_output_surfaces_created; } r->width = width; r->height = height; st = vdpau_output_surf_new (this, r); } return st; } static void vdpau_free_output_surface (vdpau_driver_t *this, vdpau_output_surface_t *os) { vdpau_output_surface_t *smallest = NULL, *l = &this->output_surface_buffer[0], temp; int i; if (os->surface == VDP_INVALID_HANDLE) return; vdpau_oslock_lock (this); for (i = this->output_surface_buffer_size; i; --i, ++l) { if (l->surface == VDP_INVALID_HANDLE) { *l = *os; vdpau_oslock_unlock (this); os->surface = VDP_INVALID_HANDLE; return; } else if (smallest == NULL || l->size < smallest->size) smallest = l; } if (smallest && smallest->size < os->size) { temp = *smallest; *smallest = *os; vdpau_oslock_unlock (this); } else { vdpau_oslock_unlock (this); temp = *os; } vdpau_output_surf_delete (this, &temp); os->surface = VDP_INVALID_HANDLE; } static void vdpau_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; (void)frame_gen; this->ovl_changed = changed; if ( changed ) { this->old_num_ovls = this->num_ovls; this->num_ovls = 0; lprintf("overlay begin\n"); } } static void vdpau_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *voovl) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; (void)frame_gen; if (!this->ovl_changed) return; int i = this->num_ovls; if (i >= XINE_VORAW_MAX_OVL) return; if (voovl->width <= 0 || voovl->height <= 0 || voovl->width > 32768 || voovl->height > 32768) return; if (!voovl->rle && (!voovl->argb_layer || !voovl->argb_layer->buffer)) return; if (voovl->rle) lprintf("overlay[%d] rle %s%s %dx%d@%d,%d extend %dx%d hili %d,%d-%d,%d video %dx%d@%d,%d\n", i, voovl->unscaled ? " unscaled ": " scaled ", (voovl->rgb_clut > 0 || voovl->hili_rgb_clut > 0) ? " rgb ": " ycbcr ", voovl->width, voovl->height, voovl->x, voovl->y, voovl->extent_width, voovl->extent_height, voovl->hili_left, voovl->hili_top, voovl->hili_right, voovl->hili_bottom, voovl->video_window_width,voovl->video_window_height, voovl->video_window_x,voovl->video_window_y); if (voovl->argb_layer && voovl->argb_layer->buffer) lprintf("overlay[%d] argb %s %dx%d@%d,%d extend %dx%d, dirty %d,%d-%d,%d video %dx%d@%d,%d\n", i, voovl->unscaled ? " unscaled ": " scaled ", voovl->width, voovl->height, voovl->x, voovl->y, voovl->extent_width, voovl->extent_height, voovl->argb_layer->x1, voovl->argb_layer->y1, voovl->argb_layer->x2, voovl->argb_layer->y2, voovl->video_window_width,voovl->video_window_height, voovl->video_window_x,voovl->video_window_y); vdpau_overlay_t *ovl = &this->overlays[i]; if (i >= this->old_num_ovls || (ovl->use_dirty_rect && (ovl->render_surface.surface == VDP_INVALID_HANDLE || voovl->rle || ovl->x != voovl->x || ovl->y != voovl->y || ovl->width != voovl->width || ovl->height != voovl->height))) ovl->use_dirty_rect = 0; ovl->ovl = voovl; ovl->x = voovl->x; ovl->y = voovl->y; ovl->width = voovl->width; ovl->height = voovl->height; ovl->extent_width = voovl->extent_width; ovl->extent_height = voovl->extent_height; ovl->unscaled = voovl->unscaled; ovl->video_window_x = voovl->video_window_x; ovl->video_window_y = voovl->video_window_y; ovl->video_window_width = voovl->video_window_width; ovl->video_window_height = voovl->video_window_height; this->num_ovls = i + 1; } static void vdpau_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; (void)frame_gen; if (!this->ovl_changed) return; int i; for (i = 0; i < this->old_num_ovls; ++i) { vdpau_overlay_t *ovl = &this->overlays[i]; if (i >= this->num_ovls || !ovl->use_dirty_rect) { lprintf("overlay[%d] free render surface %d\n", i, (int)ovl->render_surface.surface); vdpau_free_output_surface(this, &ovl->render_surface); } } if (this->ovl_main_render_surface.surface != VDP_INVALID_HANDLE) { lprintf("overlay free main render surface %d\n", (int)this->ovl_main_render_surface.surface); vdpau_free_output_surface(this, &this->ovl_main_render_surface); } for (i = 0; i < this->num_ovls; ++i) { vdpau_overlay_t *ovl = &this->overlays[i]; vo_overlay_t *voovl = ovl->ovl; int aw = ovl->width, ah = ovl->height; uint32_t *pixmap; if (!ovl->use_dirty_rect) { vdpau_get_output_surface(this, ovl->width, ovl->height, &ovl->render_surface); lprintf("overlay[%d] get render surface %dx%d -> %d\n", i, ovl->width, ovl->height, (int)ovl->render_surface.surface); } if (voovl->rle) { int pmsize; if (!voovl->rgb_clut || !voovl->hili_rgb_clut) { _x_overlay_clut_yuv2rgb (voovl, this->color_matrix); } aw = (aw + 31) & ~31; ah = (ah + 31) & ~31; pmsize = aw * ah; if (pmsize > this->ovl_pixmap_size) { this->ovl_pixmap_size = pmsize; xine_free_aligned (this->ovl_pixmap); this->ovl_pixmap = xine_mallocz_aligned (pmsize * sizeof (uint32_t)); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": overlay argb buffer enlarged to %dx%d = %d.\n", aw, ah, pmsize); } pixmap = this->ovl_pixmap; if (!pixmap) continue; _x_overlay_to_argb32 (voovl, pixmap, aw, "BGRA"); } else { pthread_mutex_lock(&voovl->argb_layer->mutex); pixmap = voovl->argb_layer->buffer; } VdpRect put_rect; if (ovl->use_dirty_rect) { put_rect.x0 = voovl->argb_layer->x1; put_rect.y0 = voovl->argb_layer->y1; put_rect.x1 = voovl->argb_layer->x2; put_rect.y1 = voovl->argb_layer->y2; } else { put_rect.x0 = 0; put_rect.y0 = 0; put_rect.x1 = ovl->width; put_rect.y1 = ovl->height; } VdpStatus st; uint32_t pitch = aw * sizeof (uint32_t); const void * const ppixmap = pixmap; lprintf("overlay[%d] put %s %d,%d:%d,%d\n", i, ovl->use_dirty_rect ? "dirty argb": "argb", put_rect.x0, put_rect.y0, put_rect.x1, put_rect.y1); st = this->a.vdp.output_surface.put_bits (ovl->render_surface.surface, &ppixmap, &pitch, &put_rect); VDPAU_IF_ERROR ("vdpau_overlay_end: vdp_output_surface_put_bits_native failed"); if (voovl->rle) ovl->use_dirty_rect = 0; else { pthread_mutex_unlock(&voovl->argb_layer->mutex); ovl->use_dirty_rect = 1; } } } static void vdpau_process_overlays (vdpau_driver_t *this) { int novls = this->num_ovls; if (!novls) { this->ovl_changed = 0; return; } int zoom = (this->sc.delivered_width > this->sc.displayed_width || this->sc.delivered_height > this->sc.displayed_height); VdpRect vid_src_rect; if (zoom) { /* compute displayed video window coordinates */ vid_src_rect.x0 = this->sc.displayed_xoffset; vid_src_rect.y0 = this->sc.displayed_yoffset; vid_src_rect.x1 = this->sc.displayed_width + this->sc.displayed_xoffset; vid_src_rect.y1 = this->sc.displayed_height + this->sc.displayed_yoffset; } /* compute video window output coordinates */ VdpRect vid_rect; vid_rect.x0 = this->sc.output_xoffset; vid_rect.y0 = this->sc.output_yoffset; vid_rect.x1 = this->sc.output_xoffset + this->sc.output_width; vid_rect.y1 = this->sc.output_yoffset + this->sc.output_height; this->ovl_video_dest_rect = vid_rect; VdpRect ovl_rects[XINE_VORAW_MAX_OVL], ovl_src_rects[XINE_VORAW_MAX_OVL]; int i, first_visible = 0, nvisible = 0; for (i = 0; i < novls; ++i) { vdpau_overlay_t *ovl = &this->overlays[i]; /* compute unscaled displayed overlay window coordinates */ VdpRect ovl_src_rect; ovl_src_rect.x0 = 0; ovl_src_rect.y0 = 0; ovl_src_rect.x1 = ovl->width; ovl_src_rect.y1 = ovl->height; /* compute unscaled overlay window output coordinates */ VdpRect ovl_rect; ovl_rect.x0 = ovl->x; ovl_rect.y0 = ovl->y; ovl_rect.x1 = ovl->x + ovl->width; ovl_rect.y1 = ovl->y + ovl->height; /* Note: Always coordinates of last overlay osd video window is taken into account */ if (ovl->video_window_width > 0 && ovl->video_window_height > 0) { /* compute unscaled osd video window output coordinates */ vid_rect.x0 = ovl->video_window_x; vid_rect.y0 = ovl->video_window_y; vid_rect.x1 = ovl->video_window_x + ovl->video_window_width; vid_rect.y1 = ovl->video_window_y + ovl->video_window_height; this->ovl_video_dest_rect = vid_rect; } if (!ovl->unscaled) { double rx, ry; if (zoom) { VdpRect clip_rect; if (ovl->extent_width > 0 && ovl->extent_height > 0) { /* compute frame size to extend size scaling factor */ rx = (double)ovl->extent_width / (double)this->sc.delivered_width; ry = (double)ovl->extent_height / (double)this->sc.delivered_height; /* scale displayed video window coordinates to extend coordinates */ clip_rect.x0 = vid_src_rect.x0 * rx + 0.5; clip_rect.y0 = vid_src_rect.y0 * ry + 0.5; clip_rect.x1 = vid_src_rect.x1 * rx + 0.5; clip_rect.y1 = vid_src_rect.y1 * ry + 0.5; /* compute displayed size to output size scaling factor */ rx = (double)this->sc.output_width / (double)(clip_rect.x1 - clip_rect.x0); ry = (double)this->sc.output_height / (double)(clip_rect.y1 - clip_rect.y0); } else { clip_rect = vid_src_rect; /* compute displayed size to output size scaling factor */ rx = (double)this->sc.output_width / (double)this->sc.displayed_width; ry = (double)this->sc.output_height / (double)this->sc.displayed_height; } /* clip overlay window to margins of displayed video window */ if (ovl_rect.x0 < clip_rect.x0) { ovl_src_rect.x0 = clip_rect.x0 - ovl_rect.x0; ovl_rect.x0 = clip_rect.x0; } if (ovl_rect.y0 < clip_rect.y0) { ovl_src_rect.y0 = clip_rect.y0 - ovl_rect.y0; ovl_rect.y0 = clip_rect.y0; } if (ovl_rect.x1 > clip_rect.x1) { ovl_src_rect.x1 -= (ovl_rect.x1 - clip_rect.x1); ovl_rect.x1 = clip_rect.x1; } if (ovl_rect.y1 > clip_rect.y1) { ovl_src_rect.y1 -= (ovl_rect.y1 - clip_rect.y1); ovl_rect.y1 = clip_rect.y1; } ovl_rect.x0 -= clip_rect.x0; ovl_rect.y0 -= clip_rect.y0; ovl_rect.x1 -= clip_rect.x0; ovl_rect.y1 -= clip_rect.y0; /* scale overlay window coordinates to output window coordinates */ ovl_rect.x0 = (double)ovl_rect.x0 * rx + 0.5; ovl_rect.y0 = (double)ovl_rect.y0 * ry + 0.5; ovl_rect.x1 = (double)ovl_rect.x1 * rx + 0.5; ovl_rect.y1 = (double)ovl_rect.y1 * ry + 0.5; ovl_rect.x0 += this->sc.output_xoffset; ovl_rect.y0 += this->sc.output_yoffset; ovl_rect.x1 += this->sc.output_xoffset; ovl_rect.y1 += this->sc.output_yoffset; if (ovl->video_window_width > 0 && ovl->video_window_height > 0) { /* clip osd video window to margins of displayed video window */ if (vid_rect.x0 < clip_rect.x0) vid_rect.x0 = clip_rect.x0; if (vid_rect.y0 < clip_rect.y0) vid_rect.y0 = clip_rect.y0; if (vid_rect.x1 > clip_rect.x1) vid_rect.x1 = clip_rect.x1; if (vid_rect.y1 > clip_rect.y1) vid_rect.y1 = clip_rect.y1; vid_rect.x0 -= clip_rect.x0; vid_rect.y0 -= clip_rect.y0; vid_rect.x1 -= clip_rect.x0; vid_rect.y1 -= clip_rect.y0; /* scale osd video window coordinates to output window coordinates */ vid_rect.x0 = (double)vid_rect.x0 * rx + 0.5; vid_rect.y0 = (double)vid_rect.y0 * ry + 0.5; vid_rect.x1 = (double)vid_rect.x1 * rx + 0.5; vid_rect.y1 = (double)vid_rect.y1 * ry + 0.5; vid_rect.x0 += this->sc.output_xoffset; vid_rect.y0 += this->sc.output_yoffset; vid_rect.x1 += this->sc.output_xoffset; vid_rect.y1 += this->sc.output_yoffset; /* take only visible osd video windows into account */ if (vid_rect.x0 < vid_rect.x1 && vid_rect.y0 < vid_rect.y1) this->ovl_video_dest_rect = vid_rect; } this->ovl_changed = 1; } else { /* no zoom */ if (ovl->extent_width > 0 && ovl->extent_height > 0) { /* compute extend size to output size scaling factor */ rx = (double)this->sc.output_width / (double)ovl->extent_width; ry = (double)this->sc.output_height / (double)ovl->extent_height; } else { /* compute displayed size to output size scaling factor */ rx = (double)this->sc.output_width / (double)this->sc.displayed_width; ry = (double)this->sc.output_height / (double)this->sc.displayed_height; } /* scale overlay window coordinates to output window coordinates */ ovl_rect.x0 = (double)ovl_rect.x0 * rx + 0.5; ovl_rect.y0 = (double)ovl_rect.y0 * ry + 0.5; ovl_rect.x1 = (double)ovl_rect.x1 * rx + 0.5; ovl_rect.y1 = (double)ovl_rect.y1 * ry + 0.5; ovl_rect.x0 += this->sc.output_xoffset; ovl_rect.y0 += this->sc.output_yoffset; ovl_rect.x1 += this->sc.output_xoffset; ovl_rect.y1 += this->sc.output_yoffset; if (ovl->video_window_width > 0 && ovl->video_window_height > 0) { /* scale osd video window coordinates to output window coordinates */ vid_rect.x0 = (double)vid_rect.x0 * rx + 0.5; vid_rect.y0 = (double)vid_rect.y0 * ry + 0.5; vid_rect.x1 = (double)vid_rect.x1 * rx + 0.5; vid_rect.y1 = (double)vid_rect.y1 * ry + 0.5; vid_rect.x0 += this->sc.output_xoffset; vid_rect.y0 += this->sc.output_yoffset; vid_rect.x1 += this->sc.output_xoffset; vid_rect.y1 += this->sc.output_yoffset; /* take only visible osd video windows into account */ if (vid_rect.x0 < vid_rect.x1 && vid_rect.y0 < vid_rect.y1) this->ovl_video_dest_rect = vid_rect; } this->ovl_changed = 1; } } ovl_rects[i] = ovl_rect; ovl_src_rects[i] = ovl_src_rect; /* take only visible overlays into account */ if (ovl_rect.x0 < ovl_rect.x1 && ovl_rect.y0 < ovl_rect.y1) { /* compute overall output window size */ if (nvisible == 0) { first_visible = i; this->ovl_dest_rect = ovl_rect; } else { if (ovl_rect.x0 < this->ovl_dest_rect.x0) this->ovl_dest_rect.x0 = ovl_rect.x0; if (ovl_rect.y0 < this->ovl_dest_rect.y0) this->ovl_dest_rect.y0 = ovl_rect.y0; if (ovl_rect.x1 > this->ovl_dest_rect.x1) this->ovl_dest_rect.x1 = ovl_rect.x1; if (ovl_rect.y1 > this->ovl_dest_rect.y1) this->ovl_dest_rect.y1 = ovl_rect.y1; } ++nvisible; } } if (nvisible == 0) { this->ovl_layer_surface = VDP_INVALID_HANDLE; this->ovl_changed = 0; lprintf("overlays not visible\n"); return; } else if (nvisible == 1) { /* we have only one visible overlay object so we can use it directly as overlay layer surface */ this->ovl_src_rect = ovl_src_rects[first_visible]; this->ovl_layer_surface = this->overlays[first_visible].render_surface.surface; } else { this->ovl_src_rect.x0 = 0; this->ovl_src_rect.y0 = 0; this->ovl_src_rect.x1 = this->ovl_dest_rect.x1 - this->ovl_dest_rect.x0; this->ovl_src_rect.y1 = this->ovl_dest_rect.y1 - this->ovl_dest_rect.y0; this->ovl_layer_surface = this->ovl_main_render_surface.surface; } lprintf("overlay output %d,%d:%d,%d -> %d,%d:%d,%d video window %d,%d:%d,%d\n", this->ovl_src_rect.x0, this->ovl_src_rect.y0, this->ovl_src_rect.x1, this->ovl_src_rect.y1, this->ovl_dest_rect.x0, this->ovl_dest_rect.y0, this->ovl_dest_rect.x1, this->ovl_dest_rect.y1, this->ovl_video_dest_rect.x0, this->ovl_video_dest_rect.y0, this->ovl_video_dest_rect.x1, this->ovl_video_dest_rect.y1); if (!this->ovl_changed) return; if (nvisible == 1) { this->ovl_changed = 0; return; } if (this->ovl_main_render_surface.surface != VDP_INVALID_HANDLE) { lprintf("overlay free main render surface %d\n", (int)this->ovl_main_render_surface.surface); vdpau_free_output_surface(this, &this->ovl_main_render_surface); } vdpau_get_output_surface(this, this->ovl_src_rect.x1, this->ovl_src_rect.y1, &this->ovl_main_render_surface); lprintf("overlay get main render surface %dx%d -> %d\n", this->ovl_src_rect.x1, this->ovl_src_rect.y1, (int)this->ovl_main_render_surface.surface); this->ovl_layer_surface = this->ovl_main_render_surface.surface; /* Clear main render surface if first overlay does not cover hole output window */ if (this->ovl_dest_rect.x0 != ovl_rects[first_visible].x0 || this->ovl_dest_rect.x1 != ovl_rects[first_visible].x1 || this->ovl_dest_rect.y0 != ovl_rects[first_visible].y0 || this->ovl_dest_rect.y1 != ovl_rects[first_visible].y1) { int aw = (this->ovl_src_rect.x1 + 31) & ~31; lprintf("overlay clear main render output surface %dx%d\n", this->ovl_src_rect.x1, this->ovl_src_rect.y1); if (aw > this->ovl_pixmap_size) { this->ovl_pixmap_size = aw; xine_free_aligned (this->ovl_pixmap); this->ovl_pixmap = xine_mallocz_aligned (this->ovl_pixmap_size * sizeof (uint32_t)); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": overlay argb buffer enlarged to %dx%d = %d.\n", aw, 1, aw); } else { memset (this->ovl_pixmap, 0, aw * sizeof (uint32_t)); } uint32_t pitch = 0; const void * const prgba = this->ovl_pixmap; VdpStatus st = this->a.vdp.output_surface.put_bits (this->ovl_layer_surface, &prgba, &pitch, &this->ovl_src_rect); VDPAU_IF_ERROR ("vdpau_process_overlays: vdp_output_surface_put_bits (clear) failed"); } /* Render all visible overlays into main render surface */ for (i = 0; i < novls; ++i) { vdpau_overlay_t *ovl = &this->overlays[i]; if (ovl_rects[i].x0 < ovl_rects[i].x1 && ovl_rects[i].y0 < ovl_rects[i].y1) { /* compensate overall output offset of main render surface */ VdpRect render_rect; render_rect.x0 = ovl_rects[i].x0 - this->ovl_dest_rect.x0; render_rect.x1 = ovl_rects[i].x1 - this->ovl_dest_rect.x0; render_rect.y0 = ovl_rects[i].y0 - this->ovl_dest_rect.y0; render_rect.y1 = ovl_rects[i].y1 - this->ovl_dest_rect.y0; lprintf("overlay[%d] render %d,%d:%d,%d -> %d,%d:%d,%d\n", i, ovl_rects[i].x0, ovl_rects[i].y0, ovl_rects[i].x1, ovl_rects[i].y1, render_rect.x0, render_rect.y0, render_rect.x1, render_rect.y1); const VdpOutputSurfaceRenderBlendState *bs = (i > first_visible) ? &blend: NULL; VdpStatus st = this->a.vdp.output_surface.render_output_surface (this->ovl_layer_surface, &render_rect, ovl->render_surface.surface, &ovl_src_rects[i], NULL, bs, 0 ); VDPAU_IF_ERROR ("vdpau_process_overlays: vdp_output_surface_render_output_surface failed"); } } this->ovl_changed = 0; } static void vdpau_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { /*vdpau_frame_t *frame = (vdpau_frame_t *) vo_img;*/ (void)src; vo_img->proc_called = 1; } static void vdpau_frame_field (vo_frame_t *vo_img, int which_field) { (void)vo_img; (void)which_field; } static void vdpau_frame_dispose (vo_frame_t *vo_img) { vdpau_frame_t *frame = (vdpau_frame_t *) vo_img ; vdpau_driver_t *this = (vdpau_driver_t *) frame->vo_frame.driver; xine_freep_aligned (&frame->vo_frame.base[0]); frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; vdpau_video_surf_delete (this, &frame->surf); pthread_mutex_destroy (&frame->vo_frame.mutex); free (frame); } static vo_frame_t *vdpau_alloc_frame (vo_driver_t *this_gen) { vdpau_frame_t *frame; vdpau_driver_t *this = (vdpau_driver_t *) this_gen; lprintf("vdpau_alloc_frame\n" ); frame = (vdpau_frame_t *) calloc(1, sizeof(vdpau_frame_t)); if (!frame) return NULL; frame->vo_frame.base[0] = frame->vo_frame.base[1] = frame->vo_frame.base[2] = NULL; frame->width = frame->height = frame->format = frame->flags = 0; frame->vo_frame.accel_data = &frame->vdpau_accel_data; pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions/fields */ frame->vo_frame.proc_duplicate_frame_data = NULL; frame->vo_frame.proc_slice = vdpau_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = vdpau_frame_field; frame->vo_frame.dispose = vdpau_frame_dispose; frame->vo_frame.driver = this_gen; frame->surf.surface = VDP_INVALID_HANDLE; frame->surface_cleared_nr = 0; frame->vdpau_accel_data.vo_frame = &frame->vo_frame; frame->vdpau_accel_data.vdp_device = this->vdp_device; frame->vdpau_accel_data.surface = VDP_INVALID_HANDLE; frame->vdpau_accel_data.chroma = VDP_CHROMA_TYPE_420; #ifdef LOCKDISPLAY frame->vdpau_accel_data.lock = vdpau_lockdisplay; frame->vdpau_accel_data.unlock = vdpau_unlockdisplay; #else frame->vdpau_accel_data.lock = NULL; frame->vdpau_accel_data.unlock = NULL; #endif frame->vdpau_accel_data.vdp_decoder_create = this->a.vdp.decoder.create; frame->vdpau_accel_data.vdp_decoder_destroy = this->a.vdp.decoder.destroy; frame->vdpau_accel_data.vdp_decoder_render = this->a.vdp.decoder.render; frame->vdpau_accel_data.vdp_get_error_string = this->a.vdp.get.error_string; frame->vdpau_accel_data.vdp_runtime_nr = this->vdp_runtime_nr; frame->vdpau_accel_data.current_vdp_runtime_nr = &this->vdp_runtime_nr; return &frame->vo_frame; } static void vdpau_provide_standard_frame_data (vo_frame_t *frame, xine_current_frame_data_t *data) { VdpStatus st; VdpYCbCrFormat format; uint32_t pitches[3]; void *base[3]; vdpau_driver_t *this = (vdpau_driver_t *)frame->driver; if (frame->format != XINE_IMGFMT_VDPAU) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": vdpau_provide_standard_frame_data: unexpected frame format 0x%08x!\n", frame->format); return; } vdpau_accel_t *accel = (vdpau_accel_t *) frame->accel_data; if (accel->vdp_runtime_nr != *(accel->current_vdp_runtime_nr)) return; frame = accel->vo_frame; if (accel->chroma == VDP_CHROMA_TYPE_420) { data->format = XINE_IMGFMT_YV12; data->img_size = frame->width * frame->height + ((frame->width + 1) / 2) * ((frame->height + 1) / 2) + ((frame->width + 1) / 2) * ((frame->height + 1) / 2); if (data->img) { pitches[0] = frame->width; pitches[2] = frame->width / 2; pitches[1] = frame->width / 2; base[0] = data->img; base[2] = data->img + frame->width * frame->height; base[1] = data->img + frame->width * frame->height + frame->width * frame->height / 4; format = VDP_YCBCR_FORMAT_YV12; } } else { data->format = XINE_IMGFMT_YUY2; data->img_size = frame->width * frame->height + ((frame->width + 1) / 2) * frame->height + ((frame->width + 1) / 2) * frame->height; if (data->img) { pitches[0] = frame->width * 2; base[0] = data->img; format = VDP_YCBCR_FORMAT_YUYV; } } if (data->img) { st = this->a.vdp.video_surface.getbits_ycbcr (accel->surface, format, base, pitches); VDPAU_IF_ERROR ("failed to get surface bits !!"); } } static void vdpau_duplicate_frame_data (vo_frame_t *frame_gen, vo_frame_t *original) { vdpau_driver_t *this = (vdpau_driver_t *)frame_gen->driver; vdpau_frame_t *frame = (vdpau_frame_t *)frame_gen; vdpau_frame_t *orig = (vdpau_frame_t *)original; VdpStatus st; VdpYCbCrFormat format; if (orig->vo_frame.format != XINE_IMGFMT_VDPAU) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": vdpau_duplicate_frame_data: unexpected frame format 0x%08x!\n", orig->vo_frame.format); return; } if(orig->vdpau_accel_data.vdp_runtime_nr != frame->vdpau_accel_data.vdp_runtime_nr) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": vdpau_duplicate_frame_data: called with invalid frame\n"); return; } if (frame->vo_frame.format != XINE_IMGFMT_VDPAU) { /* should not happen */ xine_freep_aligned (&frame->vo_frame.base[0]); frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; frame->vo_frame.format = XINE_IMGFMT_VDPAU; frame->surf.surface = VDP_INVALID_HANDLE; } if ((frame->surf.width ^ orig->surf.width) | (frame->surf.height ^ orig->surf.height) | (frame->surf.chroma ^ orig->surf.chroma) | !(frame->surf.surface ^ VDP_INVALID_HANDLE)) { vdpau_video_surf_delete (this, &frame->surf); frame->vdpau_accel_data.surface = VDP_INVALID_HANDLE; frame->surf.width = orig->surf.width; frame->surf.height = orig->surf.height; frame->surf.chroma = orig->surf.chroma; } if (frame->surf.surface == VDP_INVALID_HANDLE) vdpau_video_surf_new (this, &frame->surf); frame->vdpau_accel_data.surface = frame->surf.surface; if (!(orig->flags & VO_CHROMA_422)) { int w = (orig->surf.a_width + 15) & ~15; int ysize = w * orig->surf.a_height; int uvsize = (w >> 1) * ((orig->surf.a_height + 1) >> 1); frame->vo_frame.pitches[0] = w; frame->vo_frame.pitches[1] = w >> 1; frame->vo_frame.pitches[2] = w >> 1; frame->vo_frame.base[0] = xine_malloc_aligned (ysize + 2 * uvsize); frame->vo_frame.base[1] = frame->vo_frame.base[0] + ysize; frame->vo_frame.base[2] = frame->vo_frame.base[1] + uvsize; format = VDP_YCBCR_FORMAT_YV12; } else { frame->vo_frame.pitches[0] = ((orig->surf.a_width + 15) & ~15) << 1; frame->vo_frame.base[0] = xine_malloc_aligned (frame->vo_frame.pitches[0] * orig->surf.a_height); format = VDP_YCBCR_FORMAT_YUYV; } if (frame->vo_frame.base[0]) { void * const ptemp[] = {frame->vo_frame.base[0], frame->vo_frame.base[1], frame->vo_frame.base[2]}; const uint32_t pitches[] = {frame->vo_frame.pitches[0], frame->vo_frame.pitches[1], frame->vo_frame.pitches[2]}; st = this->a.vdp.video_surface.getbits_ycbcr (orig->vdpau_accel_data.surface, format, ptemp, pitches); VDPAU_IF_ERROR ("failed to get surface bits !!"); DO_LOCKDISPLAY (this); st = this->a.vdp.video_surface.putbits_ycbcr (frame->vdpau_accel_data.surface, format, (const void * const *)ptemp, pitches); DO_UNLOCKDISPLAY (this); VDPAU_IF_ERROR ("failed to put surface bits !!"); } xine_freep_aligned (&frame->vo_frame.base[0]); frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; } static void vdpau_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; vdpau_frame_t *frame = (vdpau_frame_t *) frame_gen; int clear = 0; if ( flags & VO_NEW_SEQUENCE_FLAG ) ++this->surface_cleared_nr; /* VDPAU constraints?? */ width = (width + 3) & ~3; height = (height + 3) & ~3; /* fast check the most common case */ if ((frame->width ^ width) | (frame->height ^ height) | (frame->format ^ format) | ((frame->flags ^ flags) & VO_CHROMA_422) | (frame->vdpau_accel_data.vdp_runtime_nr ^ this->vdp_runtime_nr)) { /* (re-) allocate render space */ xine_freep_aligned (&frame->vo_frame.base[0]); frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; if (format == XINE_IMGFMT_YV12) { int w = (width + 15) & ~15; int ysize = w * height; int uvsize = (w >> 1) * ((height + 1) >> 1); frame->surf.a_width = w; frame->surf.a_height = height; frame->vo_frame.pitches[0] = w; frame->vo_frame.pitches[1] = w >> 1; frame->vo_frame.pitches[2] = w >> 1; frame->vo_frame.base[0] = xine_malloc_aligned (ysize + 2 * uvsize); if (!frame->vo_frame.base[0]) { frame->width = 0; frame->vo_frame.width = 0; /* tell vo_get_frame () to retry later */ return; } memset (frame->vo_frame.base[0], 0, ysize); frame->vo_frame.base[1] = frame->vo_frame.base[0] + ysize; memset (frame->vo_frame.base[1], 128, 2 * uvsize); frame->vo_frame.base[2] = frame->vo_frame.base[1] + uvsize; } else if (format == XINE_IMGFMT_YUY2){ frame->vo_frame.pitches[0] = ((width + 15) & ~15) << 1; frame->surf.a_width = frame->vo_frame.pitches[0] >> 1; frame->surf.a_height = height; frame->vo_frame.base[0] = xine_malloc_aligned (frame->vo_frame.pitches[0] * height); if (frame->vo_frame.base[0]) { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)frame->vo_frame.base[0]; int i; for (i = frame->vo_frame.pitches[0] * height / 4; i > 0; i--) *q++ = black.word; } else { frame->width = 0; frame->vo_frame.width = 0; /* tell vo_get_frame () to retry later */ return; } } if (frame->vdpau_accel_data.vdp_runtime_nr != this->vdp_runtime_nr) { frame->surf.surface = frame->vdpau_accel_data.surface = VDP_INVALID_HANDLE; frame->vdpau_accel_data.vdp_runtime_nr = this->vdp_runtime_nr; frame->vdpau_accel_data.vdp_device = this->vdp_device; frame->vo_frame.proc_duplicate_frame_data = NULL; frame->vo_frame.proc_provide_standard_frame_data = NULL; } if (frame->vdpau_accel_data.surface != VDP_INVALID_HANDLE) { if ((frame->width ^ width) | (frame->height ^ height) | ((frame->flags ^ flags) & VO_CHROMA_422) | (format ^ XINE_IMGFMT_VDPAU)) { lprintf(LOG_MODULE ": update_frame - destroy surface\n"); vdpau_video_surf_delete (this, &frame->surf); frame->vdpau_accel_data.surface = VDP_INVALID_HANDLE; --this->allocated_surfaces; frame->vo_frame.proc_duplicate_frame_data = NULL; frame->vo_frame.proc_provide_standard_frame_data = NULL; } } if ((format == XINE_IMGFMT_VDPAU) && (frame->vdpau_accel_data.surface == VDP_INVALID_HANDLE)) { VdpStatus st; frame->surf.chroma = (flags & VO_CHROMA_422) ? VDP_CHROMA_TYPE_422 : VDP_CHROMA_TYPE_420; frame->surf.width = width; frame->surf.height = height; st = vdpau_video_surf_new (this, &frame->surf); if (st == VDP_STATUS_OK) { clear = 1; frame->vdpau_accel_data.surface = frame->surf.surface; frame->vdpau_accel_data.chroma = frame->surf.chroma; ++this->allocated_surfaces; frame->vo_frame.proc_duplicate_frame_data = vdpau_duplicate_frame_data; frame->vo_frame.proc_provide_standard_frame_data = vdpau_provide_standard_frame_data; } } frame->width = width; frame->height = height; frame->format = format; frame->flags = flags; vdpau_frame_field (&frame->vo_frame, flags); } if ( (format == XINE_IMGFMT_VDPAU) && (clear || (frame->surface_cleared_nr != this->surface_cleared_nr)) ) { static const uint32_t pitches[] = { 0, 0, 0 }; lprintf( "clear surface: %d\n", frame->vdpau_accel_data.surface ); if ( frame->vdpau_accel_data.chroma == VDP_CHROMA_TYPE_422 ) { uint8_t *cb = malloc (frame->surf.a_width * 2); if (cb) { VdpStatus st; const void * const data[] = { cb }; const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)cb; int i; for (i = frame->surf.a_width * 2 / 4; i > 0; i--) *q++ = black.word; DO_LOCKDISPLAY (this); st = this->a.vdp.video_surface.putbits_ycbcr (frame->vdpau_accel_data.surface, VDP_YCBCR_FORMAT_YUYV, data, pitches); DO_UNLOCKDISPLAY (this); free (cb); VDPAU_IF_ERROR ("failed to clear surface"); } } else { uint8_t *cb = malloc ((frame->surf.a_width * 3 + 1) / 2); if (cb) { VdpStatus st; const void * const data[] = { cb, cb + frame->surf.a_width, cb + frame->surf.a_width }; memset (cb, 0, frame->surf.a_width); memset (cb + frame->surf.a_width, 128, (frame->surf.a_width + 1) >> 1); DO_LOCKDISPLAY (this); st = this->a.vdp.video_surface.putbits_ycbcr (frame->vdpau_accel_data.surface, VDP_YCBCR_FORMAT_YV12, data, pitches); DO_UNLOCKDISPLAY (this); free (cb); VDPAU_IF_ERROR ("failed to clear surface"); } } if ( frame->surface_cleared_nr != this->surface_cleared_nr ) frame->surface_cleared_nr = this->surface_cleared_nr; } frame->ratio = ratio; frame->vo_frame.future_frame = NULL; } static int vdpau_redraw_needed (vo_driver_t *this_gen) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; _x_vo_scale_compute_ideal_size( &this->sc ); if ( _x_vo_scale_redraw_needed( &this->sc ) ) { _x_vo_scale_compute_output_size( &this->sc ); return 1; } return this->prop_changed ? 1 : 0; } static int vdpau_release_back_frames (vdpau_driver_t *this) { int i, n = 0; for (i = 0; i < NUM_FRAMES_BACK; ++i) { if (this->back_frame[i]) { this->back_frame[i]->vo_frame.free (&this->back_frame[i]->vo_frame); this->back_frame[i] = NULL; n++; } } return n; } static void vdpau_backup_frame (vdpau_driver_t *this, vdpau_frame_t *frame) { #if NUM_FRAMES_BACK > 1 int i; #endif if ( this->back_frame[NUM_FRAMES_BACK-1]) { this->back_frame[NUM_FRAMES_BACK-1]->vo_frame.free (&this->back_frame[NUM_FRAMES_BACK-1]->vo_frame); } #if NUM_FRAMES_BACK > 1 for ( i=NUM_FRAMES_BACK-1; i>0; i-- ) this->back_frame[i] = this->back_frame[i-1]; #endif this->back_frame[0] = frame; } static void vdpau_update_deinterlace_method_sd( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; this->deinterlace_method_sd = entry->num_value; lprintf(LOG_MODULE ": deinterlace_method_sd=%d\n", this->deinterlace_method_sd ); this->prop_changed |= _VOVDP_S_DEINT; } static void vdpau_update_deinterlace_method_hd( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; this->deinterlace_method_hd = entry->num_value; lprintf(LOG_MODULE ": deinterlace_method_hd=%d\n", this->deinterlace_method_hd ); this->prop_changed |= _VOVDP_S_DEINT; } static void vdpau_update_scaling_level( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; this->scaling_level_current = entry->num_value; lprintf(LOG_MODULE ": scaling_quality=%d\n", this->scaling_level_current ); this->prop_changed |= _VOVDP_S_SCALE_LEVEL; } static void vdpau_update_enable_inverse_telecine( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; this->enable_inverse_telecine = entry->num_value; lprintf(LOG_MODULE ": enable inverse_telecine=%d\n", this->enable_inverse_telecine ); this->prop_changed |= _VOVDP_S_INV_TELE; } static void vdpau_honor_progressive_flag( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; this->honor_progressive = entry->num_value; lprintf(LOG_MODULE ": honor_progressive=%d\n", this->honor_progressive ); } static void vdpau_update_prop (vdpau_driver_t *this) { VdpVideoMixerFeature mixer_features[20]; VdpBool mixer_feature_enables[20]; VdpVideoMixerAttribute mixer_attributes[8]; VdpColor bg; float attribute_values[8]; void *attribute_ptrs[8]; uint32_t n_features = 0, n_values = 0; VdpStatus st; if (!(this->prop_changed & (_VOVDP_S_BGCOLOR | _VOVDP_S_NOISE_RED | _VOVDP_S_SHARPNESS | _VOVDP_S_SCALE_LEVEL | _VOVDP_S_DEINT | _VOVDP_S_NO_CHROMA | _VOVDP_S_INV_TELE))) return; if ((this->prop_changed & _VOVDP_S_BGCOLOR) && _vdpau_feature_have (this, _VOVDP_A_background_color)) { mixer_attributes[n_values] = VDP_VIDEO_MIXER_ATTRIBUTE_BACKGROUND_COLOR; bg.red = (this->background >> 16) / 255.f; bg.green = ((this->background >> 8) & 0xff) / 255.f; bg.blue = (this->background & 0xff) / 255.f; bg.alpha = 1; attribute_ptrs[n_values] = &bg; n_values++; } if ((this->prop_changed & _VOVDP_S_NOISE_RED) && _vdpau_feature_have (this, _VOVDP_M_noise_reduction)) { mixer_features[n_features] = VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION; mixer_feature_enables[n_features] = ((this->noise == 0) || ((this->sd_only_properties & 1) && (this->video_mixer.width >= 800))) ? VDP_FALSE : VDP_TRUE; n_features++; mixer_attributes[n_values] = VDP_VIDEO_MIXER_ATTRIBUTE_NOISE_REDUCTION_LEVEL; attribute_values[n_values] = this->noise / 100.0; attribute_ptrs[n_values] = attribute_values + n_features; n_values++; } if ((this->prop_changed & _VOVDP_S_SHARPNESS) && _vdpau_feature_have (this, _VOVDP_M_sharpness)) { mixer_features[n_features] = VDP_VIDEO_MIXER_FEATURE_SHARPNESS; mixer_feature_enables[n_features] = ((this->sharpness == 0) || ((this->sd_only_properties & 2) && (this->video_mixer.width >= 800))) ? VDP_FALSE : VDP_TRUE; n_features++; mixer_attributes[n_values] = VDP_VIDEO_MIXER_ATTRIBUTE_SHARPNESS_LEVEL; attribute_values[n_values] = this->sharpness / 100.0; attribute_ptrs[n_values] = attribute_values + n_values; n_values++; } #ifdef VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 if (this->prop_changed & _VOVDP_S_SCALE_LEVEL) { int l; for (l = 0; l < this->scaling_level_max; l++) { mixer_features[n_features + l] = VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 + l; mixer_feature_enables[n_features + l] = VDP_FALSE; } if (this->scaling_level_current > 0) mixer_feature_enables[n_features + this->scaling_level_current - 1] = VDP_TRUE; n_features += this->scaling_level_max; } #endif if (this->prop_changed & _VOVDP_S_DEINT) { static const uint8_t e[DEINT_LAST][2] = { [DEINT_NONE] = {0, 0}, [DEINT_BOB] = {0, 0}, [DEINT_HALF_TEMPORAL] = {1, 0}, [DEINT_HALF_TEMPORAL_SPATIAL] = {1, 1}, [DEINT_TEMPORAL] = {1, 0}, [DEINT_TEMPORAL_SPATIAL] = {1, 1} }; int deinterlace_method; if (this->deinterlace) { deinterlace_method = (this->video_mixer.width < 800) ? this->deinterlace_method_sd : this->deinterlace_method_hd; deinterlace_method = this->deinterlacers_method[deinterlace_method]; if ((deinterlace_method < 0) || (deinterlace_method >= DEINT_LAST)) deinterlace_method = DEINT_BOB; } else { deinterlace_method = DEINT_NONE; } if (_vdpau_feature_have (this, _VOVDP_I_temporal)) { mixer_features[n_features] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL; mixer_feature_enables[n_features] = e[deinterlace_method][0] ? VDP_TRUE : VDP_FALSE; n_features++; } if (_vdpau_feature_have (this, _VOVDP_I_temporal_spatial)) { mixer_features[n_features] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL; mixer_feature_enables[n_features] = e[deinterlace_method][1] ? VDP_TRUE : VDP_FALSE; n_features++; } } if ((this->prop_changed & _VOVDP_S_NO_CHROMA) && _vdpau_feature_have (this, _VOVDP_I_no_chroma)) { mixer_attributes[n_values] = VDP_VIDEO_MIXER_ATTRIBUTE_SKIP_CHROMA_DEINTERLACE; attribute_ptrs[n_values] = &this->skip_chroma; n_values++; } if ((this->prop_changed & (_VOVDP_S_DEINT | _VOVDP_S_INV_TELE)) && _vdpau_feature_have (this, _VOVDP_I_inverse_telecine)) { mixer_features[n_features] = VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE; mixer_feature_enables[n_features] = (this->deinterlace && this->enable_inverse_telecine) ? VDP_TRUE : VDP_FALSE; n_features++; } if (n_features > 0) { this->a.vdp.video_mixer.set_feature_enables (this->video_mixer.handle, n_features, mixer_features, mixer_feature_enables); } if (n_values > 0) { st = this->a.vdp.video_mixer.set_attribute_values (this->video_mixer.handle, n_values, mixer_attributes, (const void * const)attribute_ptrs); VDPAU_IF_ERROR ("can't set mixer props !!"); } this->prop_changed &= ~(_VOVDP_S_BGCOLOR | _VOVDP_S_NOISE_RED | _VOVDP_S_SHARPNESS | _VOVDP_S_SCALE_LEVEL | _VOVDP_S_DEINT | _VOVDP_S_NO_CHROMA | _VOVDP_S_INV_TELE); } static void vdpau_update_sd_only_properties( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; this->sd_only_properties = entry->num_value; lprintf( LOG_MODULE ": enable sd only noise=%d, sd only sharpness %d\n", ((this->sd_only_properties & 1) != 0), (this->sd_only_properties >= 2) ); this->prop_changed |= _VOVDP_S_NOISE_RED | _VOVDP_S_SHARPNESS; } static void vdpau_update_csc_matrix (vdpau_driver_t *this, vdpau_frame_t *frame) { int color_matrix; color_matrix = cm_from_frame (&frame->vo_frame); if ((this->prop_changed & (_VOVDP_S_HUE | _VOVDP_S_SATURATION | _VOVDP_S_CONTRAST | _VOVDP_S_BRIGHTNESS | _VOVDP_S_CSC)) || (this->color_matrix != color_matrix)) { VdpStatus st; float matrix[12]; float hue = (float)this->hue * M_PI / 128.0; float saturation = (float)this->saturation / 128.0; float contrast = (float)this->contrast / 128.0; float brightness = this->brightness; cm_fill_matrix(matrix, color_matrix, hue, saturation, contrast, brightness); this->color_matrix = color_matrix; this->prop_changed &= ~(_VOVDP_S_HUE | _VOVDP_S_SATURATION | _VOVDP_S_CONTRAST | _VOVDP_S_BRIGHTNESS | _VOVDP_S_CSC); VdpCSCMatrix _matrix = {{matrix[0], matrix[1], matrix[2], matrix[3]}, {matrix[4], matrix[5], matrix[6], matrix[7]}, {matrix[8], matrix[9], matrix[10], matrix[11]}}; const VdpVideoMixerAttribute attributes [] = {VDP_VIDEO_MIXER_ATTRIBUTE_CSC_MATRIX}; const void * const attribute_values[] = {&_matrix}; st = this->a.vdp.video_mixer.set_attribute_values (this->video_mixer.handle, 1, attributes, attribute_values); VDPAU_IF_ERROR ("can't set csc matrix !!"); xprintf (this->xine, XINE_VERBOSITY_LOG,LOG_MODULE ": b %d c %d s %d h %d [%s]\n", this->brightness, this->contrast, this->saturation, this->hue, cm_names[color_matrix]); } } static void vdpau_set_skip_chroma( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; this->skip_chroma = entry->num_value; this->prop_changed |= _VOVDP_S_NO_CHROMA; } static void vdpau_set_background( void *this_gen, xine_cfg_entry_t *entry ) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; entry->num_value &= 0xffffff; this->background = entry->num_value; this->prop_changed |= _VOVDP_S_BGCOLOR; } static void vdpau_shift_queue (vdpau_driver_t *this) { if ( this->init_queue < this->queue_length ) ++this->init_queue; ++this->current_output_surface; if ( this->current_output_surface >= this->queue_length ) this->current_output_surface = 0; } static void vdpau_check_output_size (vdpau_driver_t *this) { vdpau_output_surface_t *s = &this->output_surfaces[this->current_output_surface]; if ((this->sc.gui_width > (int)s->width) || (this->sc.gui_height > (int)s->height)) { /* recreate output surface to match window size */ lprintf( LOG_MODULE ": output_surface size update\n" ); vdpau_output_surf_delete (this, s); s->width = this->sc.gui_width; s->height = this->sc.gui_height; vdpau_output_surf_new (this, s); } } static void vdpau_grab_current_output_surface (vdpau_driver_t *this, int64_t vpts) { pthread_mutex_lock(&this->grab_lock); vdpau_grab_video_frame_t *frame = this->pending_grab_request; if (frame) { vdpau_output_surface_t *s = &this->output_surfaces[this->current_output_surface]; int width = this->sc.gui_width; int height = this->sc.gui_height; VdpStatus st; this->pending_grab_request = NULL; frame->grab_frame.vpts = -1; /* take cropping parameters into account */ width -= frame->grab_frame.crop_left - frame->grab_frame.crop_right; height -= frame->grab_frame.crop_top - frame->grab_frame.crop_bottom; if (width < 1) width = 1; if (height < 1) height = 1; /* if caller does not specify frame size we return the actual size of grabbed frame */ if (frame->grab_frame.width <= 0) frame->grab_frame.width = width; if (frame->grab_frame.height <= 0) frame->grab_frame.height = height; if (frame->grab_frame.width != frame->width || frame->grab_frame.height != frame->height) { free(frame->rgba); free(frame->grab_frame.img); frame->rgba = NULL; frame->grab_frame.img = NULL; frame->width = frame->grab_frame.width; frame->height = frame->grab_frame.height; } if (frame->rgba == NULL) { frame->rgba = (uint32_t *) calloc(frame->width * frame->height, sizeof(uint32_t)); if (frame->rgba == NULL) { pthread_cond_broadcast(&this->grab_cond); pthread_mutex_unlock(&this->grab_lock); return; } } if (frame->grab_frame.img == NULL) { frame->grab_frame.img = (uint8_t *) calloc(frame->width * frame->height, 3); if (frame->grab_frame.img == NULL) { pthread_cond_broadcast(&this->grab_cond); pthread_mutex_unlock(&this->grab_lock); return; } } { uint32_t pitches = frame->width * sizeof(uint32_t); void * const prgba = frame->rgba; VdpRect src_rect = { frame->grab_frame.crop_left, frame->grab_frame.crop_top, width + frame->grab_frame.crop_left, height + frame->grab_frame.crop_top }; if (frame->width != width || frame->height != height) { VdpRect dst_rect = { 0, 0, frame->width, frame->height }; st = vdpau_get_output_surface (this, frame->width, frame->height, &frame->render_surface); if (st == VDP_STATUS_OK) { lprintf("grab got render output surface %dx%d -> %d\n", frame->width, frame->height, (int)frame->render_surface.surface); st = this->a.vdp.output_surface.render_output_surface (frame->render_surface.surface, &dst_rect, s->surface, &src_rect, NULL, NULL, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); if (st == VDP_STATUS_OK) { st = this->a.vdp.output_surface.get_bits (frame->render_surface.surface, &dst_rect, &prgba, &pitches); VDPAU_IF_ERROR ("Can't get output surface bits for raw frame grabbing"); } else VDPAU_ERROR ("Can't render output surface for raw frame grabbing"); vdpau_free_output_surface (this, &frame->render_surface); } } else { st = this->a.vdp.output_surface.get_bits (s->surface, &src_rect, &prgba, &pitches); VDPAU_IF_ERROR ("Can't get output surface bits for raw frame grabbing"); } } if (st == VDP_STATUS_OK) frame->grab_frame.vpts = vpts; pthread_cond_broadcast(&this->grab_cond); } pthread_mutex_unlock(&this->grab_lock); } static VdpStatus vdpau_new_video_mixer (vdpau_driver_t *this) { VdpVideoMixerFeature features[15]; int features_count = 0; if (_vdpau_feature_have (this, _VOVDP_M_noise_reduction)) features[features_count++] = VDP_VIDEO_MIXER_FEATURE_NOISE_REDUCTION; if (_vdpau_feature_have (this, _VOVDP_M_sharpness)) features[features_count++] = VDP_VIDEO_MIXER_FEATURE_SHARPNESS; if (_vdpau_feature_have (this, _VOVDP_I_temporal)) features[features_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL; if (_vdpau_feature_have (this, _VOVDP_I_temporal_spatial)) features[features_count++] = VDP_VIDEO_MIXER_FEATURE_DEINTERLACE_TEMPORAL_SPATIAL; if (_vdpau_feature_have (this, _VOVDP_I_inverse_telecine)) features[features_count++] = VDP_VIDEO_MIXER_FEATURE_INVERSE_TELECINE; #ifdef VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1 { int n = this->scaling_level_max; int f = VDP_VIDEO_MIXER_FEATURE_HIGH_QUALITY_SCALING_L1; while (n--) features[features_count++] = f++; } #endif static const VdpVideoMixerParameter params[] = { VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_WIDTH, VDP_VIDEO_MIXER_PARAMETER_VIDEO_SURFACE_HEIGHT, VDP_VIDEO_MIXER_PARAMETER_CHROMA_TYPE, VDP_VIDEO_MIXER_PARAMETER_LAYERS }; void const *param_values[] = { &this->video_mixer.width, &this->video_mixer.height, &this->video_mixer.chroma, /* requesting buggy layers seems safe, while using them is not. */ &this->video_mixer.max_layers[0] }; return this->a.vdp.video_mixer.create (this->vdp_device, features_count, features, this->video_mixer.max_layers[0] ? 4 : 3, params, param_values, &this->video_mixer.handle); } static void vdpau_update_display_dimension (vdpau_driver_t *this) { XLockDisplay (this->display); this->display_width = DisplayWidth(this->display, this->screen); this->display_height = DisplayHeight(this->display, this->screen); XUnlockDisplay(this->display); } static void vdp_preemption_callback(VdpDevice device, void *context) { vdpau_driver_t *this = (vdpau_driver_t *)context; this->reinit_needed = 1; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": VDPAU preemption callback\n"); (void)device; } static void vdpau_reinit (vdpau_driver_t *this) { int i; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": VDPAU was pre-empted. Reinit.\n"); DO_LOCKDISPLAY (this); vdpau_release_back_frames (this); VdpStatus st = vdp_device_create_x11 (this->display, this->screen, &this->vdp_device, &this->vdp_get_proc_address); if (st != VDP_STATUS_OK) { if (st == VDP_STATUS_NO_IMPLEMENTATION) xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Can't create vdp device: No vdpau implementation.\n"); else xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Can't create vdp device: unsupported GPU?\n"); DO_UNLOCKDISPLAY (this); return; } #define VDPAU_BAIL_REINIT(msg) \ if (st != VDP_STATUS_OK) { \ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s: %s.\n", msg, this->a.vdp.get.error_string (st)); \ DO_UNLOCKDISPLAY (this); \ } st = this->a.vdp.queue.target_create_x11 (this->vdp_device, this->drawable, &this->vdp_queue_target); VDPAU_BAIL_REINIT ("Can't create presentation queue target !!"); st = this->a.vdp.queue.create (this->vdp_device, this->vdp_queue_target, &this->vdp_queue); VDPAU_BAIL_REINIT ("Can't create presentation queue !!"); this->a.vdp.queue.set_background_color (this->vdp_queue, &this->back_color); this->soft_surface.chroma = VDP_CHROMA_TYPE_420; st = vdpau_video_surf_new (this, &this->soft_surface); VDPAU_BAIL_REINIT ("Can't create video surface !!"); vdpau_update_display_dimension(this); this->current_output_surface = 0; this->init_queue = 0; this->queue_length = this->queue_user_length; for (i = 0; i < this->queue_length; ++i) { vdpau_output_surface_t *s = this->output_surfaces + i; s->width = this->display_width; s->height = this->display_height; st = vdpau_output_surf_new (this, s); if (st != VDP_STATUS_OK) break; } if (i < this->queue_length) { int j; for (j = i; j >= 0; j--) vdpau_output_surf_delete (this, this->output_surfaces + j); vdpau_video_surf_delete (this, &this->soft_surface); this->queue_length = i; VDPAU_BAIL_REINIT ("Can't create output surface !!"); } this->num_big_output_surfaces_created = 0; for (i = 0; i < this->output_surface_buffer_size; ++i) this->output_surface_buffer[i].surface = VDP_INVALID_HANDLE; this->ovl_layer_surface = VDP_INVALID_HANDLE; this->ovl_main_render_surface.surface = VDP_INVALID_HANDLE; for (i = 0; i < this->num_ovls; ++i) this->overlays[i].render_surface.surface = VDP_INVALID_HANDLE; this->num_ovls = 0; this->ovl_changed = 1; this->video_mixer.chroma = this->soft_surface.chroma; st = vdpau_new_video_mixer (this); if (st != VDP_STATUS_OK) { int j; for (j = this->queue_length; j >= 0; j--) vdpau_output_surf_delete (this, this->output_surfaces + j); vdpau_video_surf_delete (this, &this->soft_surface); this->queue_length = 0; VDPAU_BAIL_REINIT ("Can't create video mixer !!"); } this->prop_changed = _VOVDP_S_ALL; this->a.vdp.preemption_callback_register (this->vdp_device, &vdp_preemption_callback, (void*)this); this->vdp_runtime_nr++; this->reinit_needed = 0; DO_UNLOCKDISPLAY (this); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Reinit done.\n"); } static void vdpau_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; vdpau_frame_t *frame = (vdpau_frame_t *) frame_gen; static const VdpOutputSurfaceRenderBlendState ovl_blend = { .struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION, .blend_factor_source_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA, .blend_factor_destination_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, .blend_factor_source_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO, .blend_factor_destination_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE, .blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD, .blend_constant = {.red = 0, .green = 0, .blue = 0, .alpha = 0 } }; VdpStatus st; VdpVideoSurface surface; VdpChromaType chroma = this->video_mixer.chroma; uint32_t mix_w = this->video_mixer.width; uint32_t mix_h = this->video_mixer.height; VdpTime stream_speed; int redraw_needed; this->sc.force_redraw |= (((frame->width ^ this->sc.delivered_width) | (frame->height ^ this->sc.delivered_height) | (frame->vo_frame.crop_left ^ this->sc.crop_left) | (frame->vo_frame.crop_right ^ this->sc.crop_right) | (frame->vo_frame.crop_top ^ this->sc.crop_top) | (frame->vo_frame.crop_bottom ^ this->sc.crop_bottom)) || (frame->ratio != this->sc.delivered_ratio)) ? 1 : 0; this->sc.delivered_height = frame->height; this->sc.delivered_width = frame->width; this->sc.delivered_ratio = frame->ratio; this->sc.crop_left = frame->vo_frame.crop_left; this->sc.crop_right = frame->vo_frame.crop_right; this->sc.crop_top = frame->vo_frame.crop_top; this->sc.crop_bottom = frame->vo_frame.crop_bottom; redraw_needed = vdpau_redraw_needed( this_gen ); pthread_mutex_lock(&this->drawable_lock); /* protect drawble from being changed */ if(this->reinit_needed) vdpau_reinit (this); if ( (frame->format == XINE_IMGFMT_YV12) || (frame->format == XINE_IMGFMT_YUY2) ) { chroma = ( frame->format==XINE_IMGFMT_YV12 )? VDP_CHROMA_TYPE_420 : VDP_CHROMA_TYPE_422; if ((frame->width != (int)this->soft_surface.width) || (frame->height != (int)this->soft_surface.height) || (frame->format != this->soft_surface_format)) { lprintf( LOG_MODULE ": soft_surface size update\n" ); /* recreate surface to match frame changes */ this->soft_surface.chroma = chroma; this->soft_surface.width = frame->width; this->soft_surface.height = frame->height; this->soft_surface_format = frame->format; vdpau_video_surf_delete (this, &this->soft_surface); vdpau_video_surf_new (this, &this->soft_surface); } /* FIXME: have to swap U and V planes to get correct colors !! */ uint32_t pitches[] = { frame->vo_frame.pitches[0], frame->vo_frame.pitches[2], frame->vo_frame.pitches[1] }; const void* const data[] = { frame->vo_frame.base[0], frame->vo_frame.base[2], frame->vo_frame.base[1] }; if ( frame->format==XINE_IMGFMT_YV12 ) { DO_LOCKDISPLAY (this); st = this->a.vdp.video_surface.putbits_ycbcr (this->soft_surface.surface, VDP_YCBCR_FORMAT_YV12, data, pitches); DO_UNLOCKDISPLAY (this); VDPAU_IF_ERROR ("vdp_video_surface_putbits_ycbcr YV12 error"); } else { DO_LOCKDISPLAY (this); st = this->a.vdp.video_surface.putbits_ycbcr (this->soft_surface.surface, VDP_YCBCR_FORMAT_YUYV, data, pitches); DO_UNLOCKDISPLAY (this); VDPAU_IF_ERROR ("vdp_video_surface_putbits_ycbcr YUY2 error"); } surface = this->soft_surface.surface; mix_w = this->soft_surface.width; mix_h = this->soft_surface.height; } else if (frame->format == XINE_IMGFMT_VDPAU) { surface = frame->vdpau_accel_data.surface; mix_w = frame->width; mix_h = frame->height; chroma = (frame->vo_frame.flags & VO_CHROMA_422) ? VDP_CHROMA_TYPE_422 : VDP_CHROMA_TYPE_420; } else { /* unknown format */ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": got an unknown image -------------\n"); frame->vo_frame.free( &frame->vo_frame ); pthread_mutex_unlock(&this->drawable_lock); /* allow changing drawable again */ return; } vdpau_update_csc_matrix (this, frame); vdpau_update_prop (this); if ( (mix_w != this->video_mixer.width) || (mix_h != this->video_mixer.height) || (chroma != this->video_mixer.chroma)) { vdpau_release_back_frames (this); /* empty past frames array */ lprintf(LOG_MODULE ": recreate mixer to match frames: width=%d, height=%d, chroma=%d\n", mix_w, mix_h, chroma); this->a.vdp.video_mixer.destroy (this->video_mixer.handle); this->video_mixer.handle = VDP_INVALID_HANDLE; this->video_mixer.chroma = chroma; this->video_mixer.width = mix_w; this->video_mixer.height = mix_h; vdpau_new_video_mixer (this); this->prop_changed = _VOVDP_S_ALL; } if (this->ovl_changed || redraw_needed) vdpau_process_overlays(this); uint32_t layer_count1, layer_count2 = 0; VdpLayer *layer1, *layer2 = NULL, ovl_layer; VdpRect *vid_dest, vid_dest_rect; if (this->num_ovls && this->ovl_layer_surface != VDP_INVALID_HANDLE) { ovl_layer.struct_version = VDP_LAYER_VERSION; ovl_layer.source_surface = this->ovl_layer_surface; ovl_layer.source_rect = &this->ovl_src_rect; ovl_layer.destination_rect = &this->ovl_dest_rect; layer1 = &ovl_layer; layer_count1 = 1; vid_dest = &this->ovl_video_dest_rect; } else { layer1 = NULL; layer_count1 = 0; vid_dest_rect.x0 = this->sc.output_xoffset; vid_dest_rect.y0 = this->sc.output_yoffset; vid_dest_rect.x1 = this->sc.output_xoffset + this->sc.output_width; vid_dest_rect.y1 = this->sc.output_yoffset + this->sc.output_height; vid_dest = &vid_dest_rect; } VdpRect vid_source, out_dest; if (!(this->transform & XINE_VO_TRANSFORM_FLIP_H)) { vid_source.x0 = this->sc.displayed_xoffset; vid_source.x1 = this->sc.displayed_width + this->sc.displayed_xoffset; } else { vid_source.x0 = this->sc.displayed_width + this->sc.displayed_xoffset; vid_source.x1 = this->sc.displayed_xoffset; } if (!(this->transform & XINE_VO_TRANSFORM_FLIP_V)) { vid_source.y0 = this->sc.displayed_yoffset; vid_source.y1 = this->sc.displayed_height + this->sc.displayed_yoffset; } else { vid_source.y0 = this->sc.displayed_height + this->sc.displayed_yoffset; vid_source.y1 = this->sc.displayed_yoffset; } out_dest.x0 = out_dest.y0 = 0; out_dest.x1 = this->sc.gui_width; out_dest.y1 = this->sc.gui_height; this->prop_changed = 0; stream_speed = frame->vo_frame.stream ? xine_get_param(frame->vo_frame.stream, XINE_PARAM_FINE_SPEED) : 0; /* try to get frame duration from previous img->pts when frame->duration is 0 */ int frame_duration = frame->vo_frame.duration; if ( !frame_duration && this->back_frame[0] ) { int duration = frame->vo_frame.pts - this->back_frame[0]->vo_frame.pts; if ( duration>0 && duration<4000 ) frame_duration = duration; } int non_progressive; if ( frame->vo_frame.progressive_frame < 0 ) non_progressive = 0; else non_progressive = (this->honor_progressive && !frame->vo_frame.progressive_frame) || !this->honor_progressive; /* render may crash if we add too much. */ { uint32_t num_layers = this->video_mixer.max_layers[this->video_mixer.layer_bug & 3]; if (layer_count1 > num_layers) { layer_count2 = layer_count1 - num_layers; layer_count1 = num_layers; layer2 = layer1 + layer_count1; } } if (!layer_count1) layer1 = NULL; vdpau_output_surface_t *s = this->output_surfaces + this->current_output_surface; VdpTime last_time; if ( this->init_queue>1 ) this->a.vdp.queue.block (this->vdp_queue, s->surface, &last_time); DO_LOCKDISPLAY (this); vdpau_check_output_size (this); if ( frame->format==XINE_IMGFMT_VDPAU && this->deinterlace && non_progressive && !(frame->vo_frame.flags & VO_STILL_IMAGE) && frame_duration>2500 ) { VdpTime current_time = 0; VdpVideoSurface past[2]; VdpVideoSurface future[1]; VdpVideoMixerPictureStructure picture_structure; past[1] = past[0] = (this->back_frame[0] && (this->back_frame[0]->format==XINE_IMGFMT_VDPAU)) ? this->back_frame[0]->vdpau_accel_data.surface : VDP_INVALID_HANDLE; future[0] = surface; picture_structure = ( frame->vo_frame.top_field_first ) ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD : VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD; st = this->a.vdp.video_mixer.render (this->video_mixer.handle, VDP_INVALID_HANDLE, NULL, picture_structure, 2, past, surface, 1, future, &vid_source, s->surface, &out_dest, vid_dest, layer_count1, layer1 ); VDPAU_IF_ERROR ("vdp_video_mixer_render error"); while (layer_count2) { /* blend manually */ this->a.vdp.output_surface.render_output_surface (s->surface, layer2->destination_rect, layer2->source_surface, layer2->source_rect, NULL, &ovl_blend, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); layer2++; layer_count2--; } vdpau_grab_current_output_surface( this, frame->vo_frame.vpts ); this->a.vdp.queue.get_time (this->vdp_queue, ¤t_time); this->a.vdp.queue.display (this->vdp_queue, s->surface, this->sc.gui_width, this->sc.gui_height, 0); /* display _now_ */ vdpau_shift_queue (this); s = this->output_surfaces + this->current_output_surface; int dm; if ( this->video_mixer.width < 800 ) dm = this->deinterlacers_method[this->deinterlace_method_sd]; else dm = this->deinterlacers_method[this->deinterlace_method_hd]; if ( (dm != DEINT_HALF_TEMPORAL) && (dm != DEINT_HALF_TEMPORAL_SPATIAL) && frame->vo_frame.future_frame ) { /* process second field */ if ( this->init_queue >= this->queue_length ) { DO_UNLOCKDISPLAY (this); this->a.vdp.queue.block (this->vdp_queue, s->surface, &last_time); DO_LOCKDISPLAY (this); } vdpau_check_output_size (this); picture_structure = ( frame->vo_frame.top_field_first ) ? VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD : VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD; past[0] = surface; if ( frame->vo_frame.future_frame!=NULL && ((vdpau_frame_t*)(frame->vo_frame.future_frame))->format==XINE_IMGFMT_VDPAU ) future[0] = ((vdpau_frame_t*)(frame->vo_frame.future_frame))->vdpau_accel_data.surface; else future[0] = VDP_INVALID_HANDLE; st = this->a.vdp.video_mixer.render (this->video_mixer.handle, VDP_INVALID_HANDLE, NULL, picture_structure, 2, past, surface, 1, future, &vid_source, s->surface, &out_dest, vid_dest, layer_count1, layer1 ); VDPAU_IF_ERROR ("vdp_video_mixer_render error"); while (layer_count2) { /* blend manually */ this->a.vdp.output_surface.render_output_surface (s->surface, layer2->destination_rect, layer2->source_surface, layer2->source_rect, NULL, &ovl_blend, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); layer2++; layer_count2--; } if ( stream_speed > 0 ) current_time += frame->vo_frame.duration * 1000000ull * XINE_FINE_SPEED_NORMAL / (180 * stream_speed); this->a.vdp.queue.display (this->vdp_queue, s->surface, this->sc.gui_width, this->sc.gui_height, current_time); vdpau_shift_queue (this); } } else { if ( frame->vo_frame.flags & VO_STILL_IMAGE ) lprintf( LOG_MODULE ": VO_STILL_IMAGE\n"); st = this->a.vdp.video_mixer.render (this->video_mixer.handle, VDP_INVALID_HANDLE, NULL, /* background */ VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME, /* src */ 0, NULL, /* past */ surface, /* src */ 0, NULL, /* future */ &vid_source, /* src rect */ s->surface, /* dest */ &out_dest, /* dest clip */ vid_dest, /* dest video rect */ layer_count1, layer1 /* ovl */ ); VDPAU_IF_ERROR ("vdp_video_mixer_render error"); while (layer_count2) { /* blend manually */ this->a.vdp.output_surface.render_output_surface (s->surface, layer2->destination_rect, layer2->source_surface, layer2->source_rect, NULL, &ovl_blend, VDP_OUTPUT_SURFACE_RENDER_ROTATE_0); layer2++; layer_count2--; } vdpau_grab_current_output_surface( this, frame->vo_frame.vpts ); this->a.vdp.queue.display (this->vdp_queue, s->surface, this->sc.gui_width, this->sc.gui_height, 0); vdpau_shift_queue (this); /* s = this->output_surfaces + this->current_output_surface; */ } DO_UNLOCKDISPLAY (this); if ( stream_speed ) vdpau_backup_frame (this, frame); else /* do not release past frame if paused, it will be used for redrawing */ frame->vo_frame.free( &frame->vo_frame ); pthread_mutex_unlock(&this->drawable_lock); /* allow changing drawable again */ } static int vdpau_get_property (vo_driver_t *this_gen, int property) { vdpau_driver_t *this = (vdpau_driver_t*)this_gen; switch (property) { case VO_PROP_MAX_NUM_FRAMES: return 30; case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; case VO_PROP_OUTPUT_WIDTH: return this->sc.output_width; case VO_PROP_OUTPUT_HEIGHT: return this->sc.output_height; case VO_PROP_OUTPUT_XOFFSET: return this->sc.output_xoffset; case VO_PROP_OUTPUT_YOFFSET: return this->sc.output_yoffset; case VO_PROP_HUE: return this->hue; case VO_PROP_SATURATION: return this->saturation; case VO_PROP_CONTRAST: return this->contrast; case VO_PROP_BRIGHTNESS: return this->brightness; case VO_PROP_SHARPNESS: return this->sharpness; case VO_PROP_NOISE_REDUCTION: return this->noise; case VO_PROP_ZOOM_X: return this->zoom_x; case VO_PROP_ZOOM_Y: return this->zoom_y; case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; case VO_PROP_CAPS2: return VO_CAP2_TRANSFORM; case VO_PROP_TRANSFORM: return this->transform; } return -1; } static int vdpau_set_property (vo_driver_t *this_gen, int property, int value) { vdpau_driver_t *this = (vdpau_driver_t*)this_gen; lprintf("vdpau_set_property: property=%d, value=%d\n", property, value ); switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) value = vdpau_release_back_frames (this); break; case VO_PROP_INTERLACED: this->deinterlace = value; this->prop_changed |= _VOVDP_S_DEINT; break; case VO_PROP_ZOOM_X: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->zoom_x = value; this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size( &this->sc ); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; case VO_PROP_ZOOM_Y: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->zoom_y = value; this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size( &this->sc ); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; case VO_PROP_ASPECT_RATIO: if ( value>=XINE_VO_ASPECT_NUM_RATIOS ) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; this->sc.force_redraw = 1; /* trigger re-calc of output size */ break; case VO_PROP_HUE: this->hue = value; this->prop_changed |= _VOVDP_S_HUE; break; case VO_PROP_SATURATION: this->saturation = value; this->prop_changed |= _VOVDP_S_SATURATION; break; case VO_PROP_CONTRAST: this->contrast = value; this->prop_changed |= _VOVDP_S_CONTRAST; break; case VO_PROP_BRIGHTNESS: this->brightness = value; this->prop_changed |= _VOVDP_S_BRIGHTNESS; break; case VO_PROP_SHARPNESS: this->sharpness = value; this->prop_changed |= _VOVDP_S_SHARPNESS; break; case VO_PROP_NOISE_REDUCTION: this->noise = value; this->prop_changed |= _VOVDP_S_NOISE_RED; break; case VO_PROP_TRANSFORM: value &= XINE_VO_TRANSFORM_FLIP_H | XINE_VO_TRANSFORM_FLIP_V; this->prop_changed |= (value ^ this->transform) ? _VOVDP_S_TRANSFORM : 0; this->transform = value; break; } return value; } static void vdpau_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { (void)this_gen; switch ( property ) { case VO_PROP_HUE: *max = 127; *min = -128; break; case VO_PROP_SATURATION: *max = 255; *min = 0; break; case VO_PROP_CONTRAST: *max = 255; *min = 0; break; case VO_PROP_BRIGHTNESS: *max = 127; *min = -128; break; case VO_PROP_SHARPNESS: *max = 100; *min = -100; break; case VO_PROP_NOISE_REDUCTION: *max = 100; *min = 0; break; default: *max = 0; *min = 0; } } /* * functions for grabbing RGB images from displayed frames */ static void vdpau_dispose_grab_video_frame(xine_grab_video_frame_t *frame_gen) { vdpau_grab_video_frame_t *frame = (vdpau_grab_video_frame_t *) frame_gen; free(frame->grab_frame.img); free(frame->rgba); free(frame); } /* * grab next displayed output surface. */ static int vdpau_grab_grab_video_frame (xine_grab_video_frame_t *frame_gen) { vdpau_grab_video_frame_t *frame = (vdpau_grab_video_frame_t *) frame_gen; vdpau_driver_t *this = (vdpau_driver_t *) frame->vo_driver; int yes = 0; do { if (frame->grab_frame.flags & XINE_GRAB_VIDEO_FRAME_FLAGS_WAIT_NEXT) break; pthread_mutex_lock (&this->drawable_lock); if (this->back_frame[0]) { vdpau_grab_video_frame_t *pending_frame; pthread_mutex_lock (&this->grab_lock); pending_frame = this->pending_grab_request; this->pending_grab_request = frame; pthread_mutex_unlock (&this->grab_lock); vdpau_grab_current_output_surface (this, this->back_frame[0]->vo_frame.vpts); pthread_mutex_lock (&this->grab_lock); this->pending_grab_request = pending_frame; pthread_mutex_unlock (&this->grab_lock); yes = 1; } pthread_mutex_unlock (&this->drawable_lock); } while (0); if (!yes) { struct timeval tvnow; struct timespec ts; /* calculate absolute timeout time */ gettimeofday (&tvnow, NULL); tvnow.tv_sec += frame->grab_frame.timeout / 1000; tvnow.tv_usec += (frame->grab_frame.timeout % 1000) * 1000; if (tvnow.tv_usec >= 1000000) { tvnow.tv_usec -= 1000000; tvnow.tv_sec += 1; } ts.tv_sec = tvnow.tv_sec; ts.tv_nsec = tvnow.tv_usec * 1000; pthread_mutex_lock (&this->grab_lock); /* wait until other pending grab request is finished */ while (this->pending_grab_request) { if (pthread_cond_timedwait (&this->grab_cond, &this->grab_lock, &ts) == ETIMEDOUT) { pthread_mutex_unlock (&this->grab_lock); return 1; /* no frame available */ } } this->pending_grab_request = frame; /* wait until our request is finished */ while (this->pending_grab_request) { if (pthread_cond_timedwait (&this->grab_cond, &this->grab_lock, &ts) == ETIMEDOUT) { this->pending_grab_request = NULL; pthread_mutex_unlock (&this->grab_lock); return 1; /* no frame available */ } } pthread_mutex_unlock (&this->grab_lock); } if (frame->grab_frame.vpts == -1) return -1; /* error happened */ /* convert ARGB image to RGB image */ uint32_t *src = frame->rgba; uint8_t *dst = frame->grab_frame.img; int n = frame->width * frame->height; while (n--) { uint32_t rgba = *src++; *dst++ = (uint8_t)(rgba >> 16); /*R*/ *dst++ = (uint8_t)(rgba >> 8); /*G*/ *dst++ = (uint8_t)(rgba); /*B*/ } return 0; } static xine_grab_video_frame_t * vdpau_new_grab_video_frame(vo_driver_t *this) { vdpau_grab_video_frame_t *frame = calloc(1, sizeof(vdpau_grab_video_frame_t)); if (frame) { frame->grab_frame.dispose = vdpau_dispose_grab_video_frame; frame->grab_frame.grab = vdpau_grab_grab_video_frame; frame->grab_frame.vpts = -1; frame->grab_frame.timeout = XINE_GRAB_VIDEO_FRAME_DEFAULT_TIMEOUT; frame->vo_driver = this; frame->render_surface.surface = VDP_INVALID_HANDLE; } return (xine_grab_video_frame_t *) frame; } static void vdpau_set_process_snapshots (void *this_gen, xine_cfg_entry_t *entry) { vdpau_driver_t *this = (vdpau_driver_t *)this_gen; /* vdpau_new_grab_video_frame () is always there, and the pointer to it * reads and writes atomically. i guess we dont need locks here ;-) */ this->vo_driver.new_grab_video_frame = entry->num_value ? vdpau_new_grab_video_frame : NULL; } static void vdpau_set_layer_bug (void *this_gen, xine_cfg_entry_t *entry) { vdpau_driver_t *this = (vdpau_driver_t *)this_gen; if (this->video_mixer.layer_bug != entry->num_value) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": layer bug workaround %s%s.\n", (entry->num_value == 2) ? "auto " : "", this->video_mixer.max_layers[entry->num_value & 3] ? "off" : "on"); } this->video_mixer.layer_bug = entry->num_value; } static int vdpau_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { vdpau_driver_t *this = (vdpau_driver_t*)this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: { if ( this->init_queue ) { pthread_mutex_lock(&this->drawable_lock); /* wait for other thread which is currently displaying */ DO_LOCKDISPLAY (this); int previous; if ( this->current_output_surface ) previous = this->current_output_surface - 1; else previous = this->queue_length - 1; this->a.vdp.queue.display (this->vdp_queue, this->output_surfaces[previous].surface, 0, 0, 0); DO_UNLOCKDISPLAY (this); pthread_mutex_unlock(&this->drawable_lock); } break; } case XINE_GUI_SEND_DRAWABLE_CHANGED: { VdpStatus st; pthread_mutex_lock(&this->drawable_lock); /* wait for other thread which is currently displaying */ DO_LOCKDISPLAY (this); this->drawable = (Drawable) data; this->a.vdp.queue.destroy (this->vdp_queue); this->a.vdp.queue.target_destroy (this->vdp_queue_target); st = this->a.vdp.queue.target_create_x11 (this->vdp_device, this->drawable, &this->vdp_queue_target); if ( st != VDP_STATUS_OK ) { VDPAU_ERROR ("FATAL !! Can't recreate presentation queue target after drawable change !!"); DO_UNLOCKDISPLAY (this); pthread_mutex_unlock(&this->drawable_lock); break; } st = this->a.vdp.queue.create (this->vdp_device, this->vdp_queue_target, &this->vdp_queue); if ( st != VDP_STATUS_OK ) { VDPAU_ERROR ("FATAL !! Can't recreate presentation queue after drawable change !!"); DO_UNLOCKDISPLAY (this); pthread_mutex_unlock(&this->drawable_lock); break; } this->a.vdp.queue.set_background_color (this->vdp_queue, &this->back_color); DO_UNLOCKDISPLAY (this); pthread_mutex_unlock(&this->drawable_lock); this->sc.force_redraw = 1; break; } case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; break; } default: return -1; } return 0; } static uint32_t vdpau_get_capabilities (vo_driver_t *this_gen) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; return this->capabilities; } static void vdpau_dispose (vo_driver_t *this_gen) { vdpau_driver_t *this = (vdpau_driver_t *) this_gen; int i; pthread_mutex_destroy (&this->os_mutex); /* cm_close already does this. this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, this, sizeof (*this)); */ cm_close (this); _x_vo_scale_cleanup (&this->sc, this->xine->config); if ( this->vdp_queue != VDP_INVALID_HANDLE ) this->a.vdp.queue.destroy (this->vdp_queue); if ( this->vdp_queue_target != VDP_INVALID_HANDLE ) this->a.vdp.queue.target_destroy (this->vdp_queue_target); if (this->video_mixer.handle != VDP_INVALID_HANDLE) this->a.vdp.video_mixer.destroy (this->video_mixer.handle); vdpau_video_surf_delete (this, &this->soft_surface); if (this->a.vdp.output_surface.destroy) { DO_LOCKDISPLAY (this); vdpau_output_surf_delete (this, &this->ovl_main_render_surface); for (i = 0; i < this->num_ovls; ++i) { vdpau_overlay_t *ovl = &this->overlays[i]; vdpau_output_surf_delete (this, &ovl->render_surface); } for (i = 0; i < this->queue_length; ++i) vdpau_output_surf_delete (this, this->output_surfaces + i); for (i = 0; i < this->output_surface_buffer_size; ++i) vdpau_output_surf_delete (this, this->output_surface_buffer + i); DO_UNLOCKDISPLAY (this); } for ( i=0; iback_frame[i] ) this->back_frame[i]->vo_frame.dispose( &this->back_frame[i]->vo_frame ); if ( (this->vdp_device != VDP_INVALID_HANDLE) && this->a.vdp.device.destroy ) this->a.vdp.device.destroy (this->vdp_device); pthread_mutex_destroy(&this->grab_lock); pthread_cond_destroy(&this->grab_cond); pthread_mutex_destroy(&this->drawable_lock); xine_free_aligned (this->ovl_pixmap); free (this); } static int vdpau_get_funcs (vdpau_driver_t *this) { const vdpau_func_t *func = &vdpau_funcs[0]; void **t = this->a.funcs; { VdpStatus st = this->vdp_get_proc_address (this->vdp_device, func->id, t); if (st != VDP_STATUS_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": no address for %s.\n", func->name); return 1; } func++; t++; } while (func->name) { VdpStatus st = this->vdp_get_proc_address (this->vdp_device, func->id, t); if (st != VDP_STATUS_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": no address for %s: %s.\n", func->name, this->a.vdp.get.error_string (st)); return 1; } func++; t++; } return 0; } static vo_driver_t *vdpau_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { vdpau_class_t *class = (vdpau_class_t *) class_gen; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; vdpau_driver_t *this; config_values_t *config = class->xine->config; int i; this = (vdpau_driver_t *) calloc(1, sizeof(vdpau_driver_t)); if (!this) return NULL; this->xine = class->xine; this->vdp_device = VDP_INVALID_HANDLE; VdpStatus st = vdp_device_create_x11 (visual->display, visual->screen, &this->vdp_device, &this->vdp_get_proc_address); if (st != VDP_STATUS_OK) { if (st == VDP_STATUS_NO_IMPLEMENTATION) xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": no vdp device: No vdpau implementation.\n"); else xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": no vdp device: unsupported GPU?\n"); free (this); return NULL; } if (vdpau_get_funcs (this)) { free (this); return NULL; } this->display = visual->display; this->screen = visual->screen; this->drawable = visual->d; pthread_mutex_init(&this->drawable_lock, 0); _x_vo_scale_init(&this->sc, 1, 0, config); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.dest_size_cb = visual->dest_size_cb; this->sc.user_data = visual->user_data; this->sc.user_ratio = XINE_VO_ASPECT_AUTO; this->zoom_x = 100; this->zoom_y = 100; this->vo_driver.get_capabilities = vdpau_get_capabilities; this->vo_driver.alloc_frame = vdpau_alloc_frame; this->vo_driver.update_frame_format = vdpau_update_frame_format; this->vo_driver.overlay_begin = vdpau_overlay_begin; this->vo_driver.overlay_blend = vdpau_overlay_blend; this->vo_driver.overlay_end = vdpau_overlay_end; this->vo_driver.display_frame = vdpau_display_frame; this->vo_driver.get_property = vdpau_get_property; this->vo_driver.set_property = vdpau_set_property; this->vo_driver.get_property_min_max = vdpau_get_property_min_max; this->vo_driver.gui_data_exchange = vdpau_gui_data_exchange; this->vo_driver.dispose = vdpau_dispose; this->vo_driver.redraw_needed = vdpau_redraw_needed; this->vo_driver.new_grab_video_frame = NULL; /* see below */ this->video_mixer.handle = VDP_INVALID_HANDLE; for (i = 0; i < NOUTPUTSURFACE; ++i) this->output_surfaces[i].surface = VDP_INVALID_HANDLE; this->soft_surface.surface = VDP_INVALID_HANDLE; this->vdp_queue = VDP_INVALID_HANDLE; this->vdp_queue_target = VDP_INVALID_HANDLE; /* this->vdp_output_surface.destroy = NULL; this->vdp_device.destroy = NULL; */ #ifndef HAVE_ZERO_SAFE_MEM for (i = 0; i < NUM_FRAMES_BACK; i++) this->back_frame[i] = NULL; this->pending_grab_request = NULL; this->allocated_surfaces = 0; this->noise = 0; this->deinterlace = 0; this->hue = 0; this->brightness = 0; this->sharpness = 0; this->scaling_level_max = 0; this->scaling_level_current = 0; this->transform = 0; this->surface_cleared_nr = 0; this->ovl_changed = 0; this->num_ovls = 0; this->old_num_ovls = 0; this->ovl_pixmap = NULL; this->ovl_pixmap_size = 0; this->ovl_src_rect.x0 = 0; this->ovl_src_rect.y0 = 0; #endif this->saturation = 128; this->contrast = 128; this->color_matrix = 10; this->vdp_runtime_nr = 1; this->ovl_layer_surface = VDP_INVALID_HANDLE; this->ovl_main_render_surface.surface = VDP_INVALID_HANDLE; this->capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE | VO_CAP_CROP | VO_CAP_UNSCALED_OVERLAY | VO_CAP_CUSTOM_EXTENT_OVERLAY | VO_CAP_ARGB_LAYER_OVERLAY | VO_CAP_VIDEO_WINDOW_OVERLAY | VO_CAP_HUE | VO_CAP_SATURATION | VO_CAP_CONTRAST | VO_CAP_BRIGHTNESS; { uint32_t tmp = 0; this->a.vdp.get.api_version (&tmp); xprintf (class->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": API version %u\n", (unsigned int)tmp); } #define VDPAU_INIT_BAIL(text) \ if (st != VDP_STATUS_OK) { \ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s: %s.\n", text, this->a.vdp.get.error_string (st)); \ this->vo_driver.dispose (&this->vo_driver); \ return NULL; \ } _vdpau_feature_test (this); { uint32_t missing = (~this->features) & _vdpau_required_features; if (missing) { char buf[1024]; _vdpau_feature_names (buf, sizeof (buf), missing); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": features required but missing: %s.\n", buf); this->vo_driver.dispose (&this->vo_driver); return NULL; } } st = this->a.vdp.preemption_callback_register (this->vdp_device, &vdp_preemption_callback, (void*)this); VDPAU_INIT_BAIL ("Can't register preemption callback !!"); st = this->a.vdp.queue.target_create_x11 (this->vdp_device, this->drawable, &this->vdp_queue_target); VDPAU_INIT_BAIL ("Can't create presentation queue target !!"); st = this->a.vdp.queue.create (this->vdp_device, this->vdp_queue_target, &this->vdp_queue); VDPAU_INIT_BAIL ("Can't create presentation queue !!"); /* choose almost black as backcolor for color keying */ this->back_color.red = 0.02; this->back_color.green = 0.01; this->back_color.blue = 0.03; this->back_color.alpha = 1; this->a.vdp.queue.set_background_color (this->vdp_queue, &this->back_color); this->soft_surface.width = 320; this->soft_surface.height = 240; this->soft_surface_format = XINE_IMGFMT_YV12; this->soft_surface.chroma = VDP_CHROMA_TYPE_420; st = vdpau_video_surf_new (this, &this->soft_surface); VDPAU_INIT_BAIL ("Can't create video surface !!"); this->output_surface_buffer_size = config->register_num (config, "video.output.vdpau_output_surface_buffer_size", 10, /* default */ _("maximum number of output surfaces buffered for reuse"), _("The maximum number of video output surfaces buffered for reuse"), 20, NULL, this); if (this->output_surface_buffer_size < 2) this->output_surface_buffer_size = 2; if (this->output_surface_buffer_size > NOUTPUTSURFACEBUFFER) this->output_surface_buffer_size = NOUTPUTSURFACEBUFFER; xprintf (class->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": hold a maximum of %d video output surfaces for reuse\n", this->output_surface_buffer_size); this->num_big_output_surfaces_created = 0; for (i = 0; i < this->output_surface_buffer_size; ++i) this->output_surface_buffer[i].surface = VDP_INVALID_HANDLE; vdpau_update_display_dimension(this); this->queue_user_length = config->register_num (config, "video.output.vdpau_display_queue_length", 3, /* default */ _("default length of display queue"), _("The default number of video output surfaces to create for the display queue"), 20, NULL, this); if (this->queue_user_length < 2) this->queue_user_length = 2; if (this->queue_user_length > NOUTPUTSURFACE) this->queue_user_length = NOUTPUTSURFACE; this->queue_length = this->queue_user_length; xprintf (class->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": using %d output surfaces of size %dx%d for display queue\n", this->queue_length, this->display_width, this->display_height); DO_LOCKDISPLAY (this); this->current_output_surface = 0; this->init_queue = 0; for ( i=0; iqueue_length; ++i ) { this->output_surfaces[i].width = this->display_width; this->output_surfaces[i].height = this->display_height; st = vdpau_output_surf_new (this, this->output_surfaces + i); if (st != VDP_STATUS_OK) break; } DO_UNLOCKDISPLAY (this); if (i < this->queue_length) { this->queue_length = i; VDPAU_INIT_BAIL ("Can't create output surface !!"); } { char deinterlacers_description[1024], *q = deinterlacers_description, *e = deinterlacers_description + 1024; int deint_count = 0, deint_default = 0; this->deinterlacers_name[deint_count] = vdpau_deinterlacer_name[0]; this->deinterlacers_method[deint_count++] = DEINT_BOB; q += strlcpy (q, vdpau_deinterlacer_description[0], e - q); if (_vdpau_feature_have (this, _VOVDP_I_temporal)) { this->deinterlacers_name[deint_count] = vdpau_deinterlacer_name[1]; this->deinterlacers_method[deint_count++] = DEINT_HALF_TEMPORAL; q += strlcpy (q, vdpau_deinterlacer_description[1], e - q); } if (_vdpau_feature_have (this, _VOVDP_I_temporal_spatial)) { this->deinterlacers_name[deint_count] = vdpau_deinterlacer_name[2]; this->deinterlacers_method[deint_count++] = DEINT_HALF_TEMPORAL_SPATIAL; q += strlcpy (q, vdpau_deinterlacer_description[2], e - q); } if (_vdpau_feature_have (this, _VOVDP_I_temporal)) { this->deinterlacers_name[deint_count] = vdpau_deinterlacer_name[3]; this->deinterlacers_method[deint_count] = DEINT_TEMPORAL; q += strlcpy (q, vdpau_deinterlacer_description[3], e - q); deint_default = deint_count++; } if (_vdpau_feature_have (this, _VOVDP_I_temporal_spatial)) { this->deinterlacers_name[deint_count] = vdpau_deinterlacer_name[4]; this->deinterlacers_method[deint_count++] = DEINT_TEMPORAL_SPATIAL; q += strlcpy (q, vdpau_deinterlacer_description[4], e - q); } *q = 0; this->deinterlacers_name[deint_count] = NULL; this->video_mixer.chroma = this->soft_surface.chroma; this->video_mixer.width = this->soft_surface.width; this->video_mixer.height = this->soft_surface.height; st = vdpau_new_video_mixer (this); VDPAU_INIT_BAIL ("Can't create video mixer !!"); this->deinterlace_method_hd = config->register_enum (config, "video.output.vdpau_hd_deinterlace_method", deint_default, (char **)this->deinterlacers_name, _("vdpau: HD deinterlace method"), deinterlacers_description, 10, vdpau_update_deinterlace_method_hd, this); this->deinterlace_method_sd = config->register_enum (config, "video.output.vdpau_sd_deinterlace_method", deint_default, (char **)this->deinterlacers_name, _("vdpau: SD deinterlace method"), deinterlacers_description, 10, vdpau_update_deinterlace_method_sd, this); } if (this->scaling_level_max) this->scaling_level_current = config->register_range (config, "video.output.vdpau_scaling_quality", 0, 0, this->scaling_level_max, _("vdpau: Scaling Quality"), _("Scaling Quality Level"), 10, vdpau_update_scaling_level, this); if (_vdpau_feature_have (this, _VOVDP_I_inverse_telecine)) this->enable_inverse_telecine = config->register_bool (config, "video.output.vdpau_enable_inverse_telecine", 1, _("vdpau: Try to recreate progressive frames from pulldown material"), _("Enable this to detect bad-flagged progressive content to which\n" "a 2:2 or 3:2 pulldown was applied.\n\n"), 10, vdpau_update_enable_inverse_telecine, this); this->honor_progressive = config->register_bool (config, "video.output.vdpau_honor_progressive", 0, _("vdpau: disable deinterlacing when progressive_frame flag is set"), _("Set to true if you want to trust the progressive_frame stream's flag.\n" "This flag is not always reliable.\n\n"), 10, vdpau_honor_progressive_flag, this); if (_vdpau_feature_have (this, _VOVDP_I_no_chroma)) this->skip_chroma = config->register_bool (config, "video.output.vdpau_skip_chroma_deinterlace", 0, _("vdpau: disable advanced deinterlacers chroma filter"), _("Setting to true may help if your video card isn't able to run advanced deinterlacers.\n\n"), 10, vdpau_set_skip_chroma, this); if (_vdpau_feature_have (this, _VOVDP_A_background_color)) this->background = config->register_num (config, "video.output.vdpau_background_color", 0, _("vdpau: colour of none video area in output window"), _("Displaying 4:3 images on 16:9 plasma TV sets lets the inactive pixels outside the " "video age slower than the pixels in the active area. Setting a different background " "colour (e. g. 8421504) makes all pixels age similarly. The number to enter for a " "certain colour can be derived from its 6 digit hexadecimal RGB value.\n\n"), 10, vdpau_set_background, this); { static const char *const vdpau_sd_only_properties[] = { "none", "noise", "sharpness", "noise+sharpness", NULL }; this->sd_only_properties = config->register_enum (config, "video.output.vdpau_sd_only_properties", 0, (char **)vdpau_sd_only_properties, _("vdpau: restrict enabling video properties for SD video only"), _("none\n" "No restrictions\n\n" "noise\n" "Restrict noise reduction property.\n\n" "sharpness\n" "Restrict sharpness property.\n\n" "noise+sharpness" "Restrict noise and sharpness properties.\n\n"), 10, vdpau_update_sd_only_properties, this); } /* number of video frames from config - register it with the default value. */ { int frame_num = config->register_num (config, "engine.buffers.video_num_frames", 15, /* default */ _("default number of video frames"), _("The default number of video frames to request from xine video out driver. " "Some drivers will override this setting with their own values."), 20, NULL, this); /* now make sure we have at least 22 frames, to prevent locks with vdpau_h264. */ if (frame_num < 22) config->update_num (config, "engine.buffers.video_num_frames", 22); } this->vo_driver.new_grab_video_frame = config->register_bool (config, "video.output.vdpau_process_snapshots", 0, _("vdpau: take snapshots as shown on the screen"), _("If set, snapshots will be scaled, cropped, padded and subtitled.\n" "Otherwise, you get the pure original video image.\n"), 10, vdpau_set_process_snapshots, this) ? vdpau_new_grab_video_frame : NULL; { static const char * const vdpau_layer_bug_opts[] = {"Off", "On", "Auto", NULL}; this->video_mixer.layer_bug = config->register_enum (config, "video.output.vdpau_layer_bug", 2, (char **)vdpau_layer_bug_opts, _("vdpau: work around broken video mixer overlays"), _("Some 2022 vdpau_radeonsi system driver crashes when showing\n" "subtitles or onscreen messages the regular way.\n" "The \"On\" setting is slightly slower but helps there.\n" "The \"Off\" setting avoids flicker on some other drivers.\n"), 10, vdpau_set_layer_bug, this); } xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": layer bug workaround %s%s.\n", (this->video_mixer.layer_bug == 2) ? "auto " : "", this->video_mixer.max_layers[this->video_mixer.layer_bug & 3] ? "off" : "on"); pthread_mutex_init(&this->os_mutex, NULL); pthread_mutex_init(&this->grab_lock, NULL); pthread_cond_init(&this->grab_cond, NULL); cm_init (this); return &this->vo_driver; } /* * class functions */ static void *vdpau_init_class (xine_t *xine, const void *visual_gen) { vdpau_class_t *this; (void)visual_gen; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = vdpau_open_plugin; this->driver_class.identifier = "vdpau"; this->driver_class.description = N_("xine video output plugin using VDPAU hardware acceleration"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_vdpau = { .priority = 11, .visual_type = XINE_VISUAL_TYPE_X11, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "vdpau", XINE_VERSION_CODE, &vo_info_vdpau, vdpau_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/Makefile.am0000644000175000017500000003213514647725152015510 0ustar memeAUTOMAKE_OPTIONS = subdir-objects include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) AM_OBJCFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) SUBDIRS = if ENABLE_MACOSX_VIDEO SUBDIRS += macosx endif EXTRA_DIST = video_out_macosx.m color_matrix.c noinst_HEADERS = xv_common.h # helper libraries libx11osd_la_SOURCES = x11osd.c x11osd.h libx11osd_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) libx11osd_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(LTLIBINTL) libxcbosd_la_SOURCES = xcbosd.c xcbosd.h libxcbosd_la_CFLAGS = $(AM_CFLAGS) $(XCB_CFLAGS) libxcbosd_la_LIBADD = $(XINE_LIB) $(XCB_LIBS) $(LTLIBINTL) opengl_xine_gl_la_SOURCES = opengl/xine_gl.c opengl/xine_gl.h opengl/xine_gl_plugin.h opengl_xine_gl_la_CFLAGS = $(AM_CFLAGS) opengl_xine_gl_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) vaapi_xine_vaapi_la_SOURCES = \ vaapi/xine_va_display.c vaapi/xine_va_display.h vaapi/xine_va_display_plugin.h \ vaapi/vaapi_util.h vaapi/vaapi_util.c vaapi/vaapi_frame.h vaapi/vaapi_frame.c vaapi_xine_vaapi_la_CFLAGS = $(AM_CFLAGS) vaapi_xine_vaapi_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) hw_frame_la_SOURCES = hw_frame.h hw_frame.c xine_hw_frame_plugin.h hw_frame_la_CFLAGS = $(AM_CFLAGS) hw_frame_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) # if !ENABLE_LIBXINE_BUILTINS vo_builtins = xineplug_vo_out_none.la endif if ENABLE_OPENGL2 XINE_HWFRAME_LIB = hw_frame.la XINE_GL_LIB = opengl/xine_gl.la opengl2_module = xineplug_vo_out_opengl2.la endif if ENABLE_VAAPI XINE_VAAPI_LIB = vaapi/xine_vaapi.la endif if HAVE_X11 X11OSD_LIB = libx11osd.la xshm_module = xineplug_vo_out_xshm.la if HAVE_XV xv_module = xineplug_vo_out_xv.la endif if ENABLE_XVMC xvmc_module = xineplug_vo_out_xvmc.la endif if ENABLE_XXMC xxmc_module = xineplug_vo_out_xxmc.la endif if ENABLE_OPENGL opengl_module = xineplug_vo_out_opengl.la endif if ENABLE_SUNFB if ENABLE_SUNDGA pgx64_module = xineplug_vo_out_pgx64.la pgx32_module = xineplug_vo_out_pgx32.la endif endif endif if ENABLE_VDPAU vdpau_module = xineplug_vo_out_vdpau.la endif if HAVE_X11 if ENABLE_VAAPI_X11 vaapi_module = xineplug_vo_out_vaapi.la endif endif if ENABLE_XCB XCBOSD_LIB = libxcbosd.la if ENABLE_XCBSHM xcbshm_module = xineplug_vo_out_xcbshm.la endif if ENABLE_XCBXV xcbxv_module = xineplug_vo_out_xcbxv.la endif endif if ENABLE_VIDIX vidix_module = xineplug_vo_out_vidix.la $(top_builddir)/contrib/vidix/libvidix.la: $(MAKE) -C $(top_builddir)/contrib/vidix libvidix.la endif if ENABLE_AA aa_module = xineplug_vo_out_aa.la endif if ENABLE_CACA caca_module = xineplug_vo_out_caca.la endif if ENABLE_FB fb_module = xineplug_vo_out_fb.la endif if ENABLE_DIRECTFB directfb_module = xineplug_vo_out_directfb.la if HAVE_X11 directfb_module += xineplug_vo_out_xdirectfb.la endif endif if ENABLE_SDL sdl_module = xineplug_vo_out_sdl.la endif if ENABLE_MMAL mmal_module = xineplug_vo_out_mmal.la endif if ENABLE_STK stk_module = xineplug_vo_out_stk.la endif if ENABLE_DIRECTX directx_module = xineplug_vo_out_directx.la endif if ENABLE_MACOSX_VIDEO macosx_module = xineplug_vo_out_macosx.la endif noinst_LTLIBRARIES = $(X11OSD_LIB) $(XCBOSD_LIB) $(XINE_GL_LIB) $(XINE_VAAPI_LIB) $(XINE_HWFRAME_LIB) xineplug_LTLIBRARIES = $(xshm_module) $(xv_module) $(xvmc_module) \ $(opengl_module) \ $(opengl2_module) \ $(pgx64_module) $(pgx32_module)\ $(vidix_module) \ $(aa_module) \ $(fb_module) $(directfb_module) \ $(sdl_module) \ $(stk_module) \ $(directx_module) \ $(caca_module) \ $(macosx_module) \ $(xxmc_module) \ $(xcbshm_module) \ $(xcbxv_module) \ $(vdpau_module) \ $(vaapi_module) \ $(mmal_module) \ $(vo_builtins) \ xineplug_vo_out_raw.la xineplug_vo_out_vdpau_la_SOURCES = video_out_vdpau.c xineplug_vo_out_vdpau_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(X_LIBS) $(LTLIBINTL) $(VDPAU_LIBS) -lm xineplug_vo_out_vdpau_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(VDPAU_CFLAGS) xineplug_vo_out_vaapi_la_SOURCES = video_out_vaapi.c xineplug_vo_out_vaapi_la_LIBADD = $(XINE_LIB) $(OPENGL_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) $(DYNAMIC_LD_LIBS) $(GLU_LIBS) $(LIBVA_LIBS) $(LIBVA_GLX_LIBS) $(LIBVA_X11_LIBS) $(XINE_VAAPI_LIB) -lm xineplug_vo_out_vaapi_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(XV_CFLAGS) $(LIBVA_CFLAGS) $(LIBVA_GLX_CFLAGS) $(LIBVA_X11_CFLAGS) xineplug_vo_out_xcbshm_la_SOURCES = video_out_xcbshm.c xineplug_vo_out_xcbshm_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(XCB_LIBS) $(XCBSHM_LIBS) $(LTLIBINTL) $(XCBOSD_LIB) xineplug_vo_out_xcbshm_la_CFLAGS = $(AM_CFLAGS) $(XCB_CFLAGS) $(XCBSHM_CFLAGS) xineplug_vo_out_xcbxv_la_SOURCES = video_out_xcbxv.c xineplug_vo_out_xcbxv_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) $(XCBXV_LIBS) $(XCB_LIBS) $(XCBSHM_LIBS) $(XCBOSD_LIB) xineplug_vo_out_xcbxv_la_CFLAGS = $(AM_CFLAGS) $(XCB_CFLAGS) $(XCBXV_CFLAGS) xineplug_vo_out_xshm_la_SOURCES = video_out_xshm.c xineplug_vo_out_xshm_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) $(X11OSD_LIB) xineplug_vo_out_xshm_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) xineplug_vo_out_xv_la_SOURCES = video_out_xv.c xineplug_vo_out_xv_la_LIBADD = $(XINE_LIB) $(XV_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) $(X11OSD_LIB) xineplug_vo_out_xv_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(XV_CFLAGS) xineplug_vo_out_xvmc_la_SOURCES = video_out_xvmc.c xineplug_vo_out_xvmc_la_LIBADD = $(XINE_LIB) $(XVMC_LIBS) $(XV_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_xvmc_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(XV_CFLAGS) -fno-strict-aliasing xineplug_vo_out_xxmc_la_SOURCES = video_out_xxmc.c \ xvmc_mocomp.c xvmc_vld.c xxmc.h xineplug_vo_out_xxmc_la_LIBADD = $(XINE_LIB) $(XXMC_LIBS) $(XV_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) $(X11OSD_LIB) xineplug_vo_out_xxmc_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(XV_CFLAGS) -fno-strict-aliasing xineplug_vo_out_opengl_la_SOURCES = video_out_opengl.c myglext.h xineplug_vo_out_opengl_la_LIBADD = $(XINE_LIB) $(OPENGL_LIBS) $(GLUT_LIBS) \ $(GLUT_LIBS) $(GLU_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) $(X11OSD_LIB) -lm xineplug_vo_out_opengl_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) xineplug_vo_out_opengl2_la_SOURCES = video_out_opengl2.c mem_frame.h xineplug_vo_out_opengl2_la_LIBADD = $(XINE_LIB) $(OPENGL_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) $(XINE_GL_LIB) $(XINE_HWFRAME_LIB) -lm xineplug_vo_out_opengl2_la_CFLAGS = $(AM_CFLAGS) xineplug_vo_out_pgx64_la_SOURCES = video_out_pgx64.c xineplug_vo_out_pgx64_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(SUNDGA_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_pgx64_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) xineplug_vo_out_pgx64_la_CPPFLAGS = $(AM_CPPFLAGS) $(SUNDGA_CPPFLAGS) xineplug_vo_out_pgx32_la_SOURCES = video_out_pgx32.c xineplug_vo_out_pgx32_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(SUNDGA_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_pgx32_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) xineplug_vo_out_pgx32_la_CPPFLAGS = $(AM_CPPFLAGS) $(SUNDGA_CPPFLAGS) xineplug_vo_out_vidix_la_SOURCES = video_out_vidix.c xineplug_vo_out_vidix_la_LIBADD = $(XINE_LIB) $(X_LIBS) \ $(top_builddir)/contrib/vidix/libvidix.la $(PTHREAD_LIBS) $(LTLIBINTL) $(X11OSD_LIB) xineplug_vo_out_vidix_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) -fno-strict-aliasing xineplug_vo_out_vidix_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_builddir)/contrib/vidix \ -I$(top_srcdir)/contrib/vidix xineplug_vo_out_aa_la_SOURCES = video_out_aa.c xineplug_vo_out_aa_la_LIBADD = $(XINE_LIB) $(AALIB_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_aa_la_CFLAGS = $(AM_CFLAGS) $(AALIB_CFLAGS) xineplug_vo_out_caca_la_SOURCES = video_out_caca.c xineplug_vo_out_caca_la_LIBADD = $(XINE_LIB) $(CACA_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_caca_la_CFLAGS = $(AM_CFLAGS) $(CACA_CFLAGS) xineplug_vo_out_fb_la_SOURCES = video_out_fb.c xineplug_vo_out_fb_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_fb_la_CFLAGS = $(AM_CFLAGS) xineplug_vo_out_directfb_la_SOURCES = video_out_directfb.c xineplug_vo_out_directfb_la_LIBADD = $(XINE_LIB) $(DIRECTFB_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_directfb_la_CFLAGS = $(AM_CFLAGS) $(DIRECTFB_CFLAGS) -fno-strict-aliasing xineplug_vo_out_xdirectfb_la_SOURCES = video_out_directfb.c xineplug_vo_out_xdirectfb_la_LIBADD = $(XINE_LIB) $(DIRECTFB_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) $(X11OSD_LIB) xineplug_vo_out_xdirectfb_la_CFLAGS = $(AM_CFLAGS) $(DIRECTFB_CFLAGS) -fno-strict-aliasing -DDIRECTFB_X11 xineplug_vo_out_sdl_la_SOURCES = video_out_sdl.c xineplug_vo_out_sdl_la_LIBADD = $(XINE_LIB) $(SDL_LIBS) $(X_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_sdl_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) $(SDL_CFLAGS) xineplug_vo_out_mmal_la_SOURCES = video_out_mmal.c xineplug_vo_out_mmal_la_LIBADD = $(XINE_LIB) $(MMAL_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_mmal_la_CFLAGS = $(AM_CFLAGS) $(MMAL_CFLAGS) xineplug_vo_out_mmal_la_LDFLAGS = $(AM_LDFLAGS) $(MMAL_LDFLAGS) xineplug_vo_out_stk_la_SOURCES = video_out_stk.c xineplug_vo_out_stk_la_LIBADD = $(XINE_LIB) $(LIBSTK_LIBS) $(PTHREAD_LIBS) xineplug_vo_out_stk_la_CFLAGS = $(AM_CFLAGS) $(LIBSTK_CFLAGS) xineplug_vo_out_directx_la_SOURCES = video_out_directx.c xineplug_vo_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_VIDEO_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_directx_la_CPPFLAGS = $(AM_CPPFLAGS) $(DIRECTX_CPPFLAGS) xineplug_vo_out_none_la_SOURCES = video_out_none.c mem_frame.h xineplug_vo_out_none_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_raw_la_SOURCES = video_out_raw.c xineplug_vo_out_raw_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_vo_out_raw_la_CFLAGS = $(AM_CFLAGS) xineplug_vo_out_macosx_la_SOURCES = video_out_macosx.m xineplug_vo_out_macosx_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) xineplug_vo_out_macosx_la_LDFLAGS = $(AM_LDFLAGS) -framework Cocoa -framework OpenGL # GL provider plugins if ENABLE_OPENGL2 if HAVE_X11 if ENABLE_GLX gl_glx_module = xineplug_vo_gl_glx.la endif # ENABLE_GLX if ENABLE_EGL gl_egl_x11_module = xineplug_vo_gl_egl_x11.la endif # ENABLE_EGL endif # HAVE_X11 if ENABLE_WAYLAND gl_egl_wl_module = xineplug_vo_gl_egl_wl.la endif # ENABLE_WAYLAND endif # ENABLE_OPENGL2 xineplug_LTLIBRARIES += \ $(gl_glx_module) \ $(gl_egl_wl_module) \ $(gl_egl_x11_module) xineplug_vo_gl_glx_la_SOURCES = opengl/xine_glx.c opengl/xine_gl_plugin.h xineplug_vo_gl_glx_la_LIBADD = $(XINE_LIB) $(OPENGL_LIBS) $(X_LIBS) $(LTLIBINTL) xineplug_vo_gl_glx_la_CFLAGS = $(AM_CFLAGS) $(X_CFLAGS) xineplug_vo_gl_egl_x11_la_SOURCES = opengl/xine_egl.c opengl/xine_gl_plugin.h xineplug_vo_gl_egl_x11_la_LIBADD = $(XINE_LIB) $(X_LIBS) $(EGL_LIBS) $(LTLIBINTL) xineplug_vo_gl_egl_x11_la_CFLAGS = -DXINE_EGL_USE_X11 $(AM_CFLAGS) $(X_CFLAGS) $(EGL_CFLAGS) xineplug_vo_gl_egl_wl_la_SOURCES = opengl/xine_egl.c opengl/xine_gl_plugin.h xineplug_vo_gl_egl_wl_la_LIBADD = $(XINE_LIB) $(WAYLAND_LIBS) $(EGL_LIBS) $(LTLIBINTL) xineplug_vo_gl_egl_wl_la_CFLAGS = -DXINE_EGL_USE_WAYLAND $(AM_CFLAGS) $(WAYLAND_CFLAGS) $(EGL_CFLAGS) # HW decoding if ENABLE_VAAPI va_hw_frame_module = xineplug_hw_frame_vaapi.la endif xineplug_LTLIBRARIES += \ $(va_hw_frame_module) xineplug_hw_frame_vaapi_la_SOURCES = vaapi/xine_hw_frame_vaapi.c xine_hw_frame_plugin.h vaapi/vaapi_egl.c vaapi/vaapi_egl.h xineplug_hw_frame_vaapi_la_LIBADD = $(XINE_LIB) $(LIBVA_LIBS) $(LTLIBINTL) $(XINE_VAAPI_LIB) xineplug_hw_frame_vaapi_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS) # vaapi display provider plugins if ENABLE_VAAPI if ENABLE_VAAPI_X11 va_display_x11_module = xineplug_va_display_x11.la endif if ENABLE_VAAPI_GLX va_display_glx_module = xineplug_va_display_glx.la endif # ENABLE_VAAPI_GLX if ENABLE_VAAPI_WAYLAND va_display_wl_module = xineplug_va_display_wl.la endif # ENABLE_VAAPI_WAYLAND if ENABLE_VAAPI_DRM va_display_drm_module = xineplug_va_display_drm.la endif # ENABLE_VAAPI_DRM endif # ENABLE_VAAPI xineplug_LTLIBRARIES += \ $(va_display_x11_module) \ $(va_display_glx_module) \ $(va_display_wl_module) \ $(va_display_drm_module) xineplug_va_display_x11_la_SOURCES = vaapi/xine_va_display_x11.c vaapi/xine_va_display_plugin.h xineplug_va_display_x11_la_LIBADD = $(XINE_LIB) $(LIBVA_LIBS) $(LIBVA_X11_LIBS) $(LTLIBINTL) xineplug_va_display_x11_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS) $(LIBVA_X11_CFLAGS) xineplug_va_display_glx_la_SOURCES = vaapi/xine_va_display_glx.c vaapi/xine_va_display_plugin.h xineplug_va_display_glx_la_LIBADD = $(XINE_LIB) $(LIBVA_LIBS) $(LIBVA_GLX_LIBS) $(LTLIBINTL) xineplug_va_display_glx_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS) $(LIBVA_GLX_CFLAGS) xineplug_va_display_wl_la_SOURCES = vaapi/xine_va_display_wl.c vaapi/xine_va_display_plugin.h xineplug_va_display_wl_la_LIBADD = $(XINE_LIB) $(LIBVA_LIBS) $(LIBVA_WAYLAND_LIBS) $(LTLIBINTL) xineplug_va_display_wl_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS) $(LIBVA_WAYLAND_CFLAGS) xineplug_va_display_drm_la_SOURCES = vaapi/xine_va_display_drm.c vaapi/xine_va_display_plugin.h xineplug_va_display_drm_la_LIBADD = $(XINE_LIB) $(LIBVA_LIBS) $(LIBVA_DRM_LIBS) $(LTLIBINTL) xineplug_va_display_drm_la_CFLAGS = $(AM_CFLAGS) $(LIBVA_CFLAGS) $(LIBVA_DRM_CFLAGS) xine-lib-1.2/src/video_out/hw_frame.c0000644000175000017500000000433714647725152015413 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2021-2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * hw_frame.c, HW decoder loader * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "xine_hw_frame_plugin.h" #define HW_FRAME_PLUGIN(_api) xine_container_of(_api, xine_hw_frame_plugin_t, api) /* technically, we can't unload dynamic module from the module itself. * it would work now (nothing is unloaded), but there may be problems in * the future if plugin loader unloads the library in _x_free_module(). */ static void default_hwdec_destroy(xine_hwdec_t **api) { if (*api) { xine_hw_frame_plugin_t *plugin = HW_FRAME_PLUGIN(*api); xine_module_t *module = &plugin->module; *api = NULL; _x_free_module(plugin->xine, &module); } } /* * loader wrapper */ xine_hwdec_t *_x_hwdec_new(xine_t *xine, vo_driver_t *vo_driver, unsigned visual_type, const void *visual, unsigned flags) { const hw_frame_plugin_params_t params = { .xine = xine, .visual_type = visual_type, .visual = visual, .flags = flags, .vo_driver = vo_driver, }; xine_hw_frame_plugin_t *p; p = (xine_hw_frame_plugin_t *)_x_find_module(xine, HW_FRAME_PLUGIN_TYPE, NULL, 0, ¶ms); if (p) { p->xine = xine; p->api.destroy = default_hwdec_destroy; return &p->api; } return NULL; } xine-lib-1.2/src/video_out/xine_hw_frame_plugin.h0000644000175000017500000000275314647725152020021 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2018-2022 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Plugin interface for HW decoder * */ #ifndef XINE_HW_FRAME_PLUGIN_H_ #define XINE_HW_FRAME_PLUGIN_H_ #include #include #include #include "hw_frame.h" #define HW_FRAME_PLUGIN_TYPE "hw_frame_v1" typedef struct xine_hw_frame_plugin_s xine_hw_frame_plugin_t; struct xine_hw_frame_plugin_s { xine_module_t module; xine_hwdec_t api; xine_t *xine; }; typedef struct { xine_t *xine; unsigned visual_type; const void *visual; unsigned flags; vo_driver_t *vo_driver; } hw_frame_plugin_params_t; #endif /* XINE_HW_FRAME_PLUGIN_H_ */ xine-lib-1.2/src/video_out/x11osd.c0000644000175000017500000004022114647725152014732 0ustar meme/* * Copyright (C) 2003-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * x11osd.c, use X11 Nonrectangular Window Shape Extension to draw xine OSD * * Nov 2003 - Miguel Freitas * * based on ideas and code of * xosd Copyright (c) 2000 Andre Renaud (andre@ignavus.net) * * colorkey support by Yann Vernier */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #define LOG_MODULE "x11osd" #define LOG_VERBOSE /* #define LOG */ #include #include "x11osd.h" struct x11osd { Display *display; int screen; enum x11osd_mode mode; union { struct { Window window; Pixmap mask_bitmap; GC mask_gc; GC mask_gc_back; int mapped; } shaped; struct { uint32_t colorkey; vo_scale_t *sc; } colorkey; } u; Window window; unsigned int depth; Pixmap bitmap; Visual *visual; Colormap cmap; GC gc; int width; int height; int x; int y; enum {DRAWN, WIPED, UNDEFINED} clean; xine_t *xine; }; void x11osd_expose (x11osd * osd) { _x_assert (osd); lprintf("expose (state:%d)\n", osd->clean ); switch (osd->mode) { case X11OSD_SHAPED: XShapeCombineMask (osd->display, osd->u.shaped.window, ShapeBounding, 0, 0, osd->u.shaped.mask_bitmap, ShapeSet); if( osd->clean==DRAWN ) { if( !osd->u.shaped.mapped ) XMapRaised (osd->display, osd->u.shaped.window); osd->u.shaped.mapped = 1; XCopyArea (osd->display, osd->bitmap, osd->u.shaped.window, osd->gc, 0, 0, osd->width, osd->height, 0, 0); } else { if( osd->u.shaped.mapped ) XUnmapWindow (osd->display, osd->u.shaped.window); osd->u.shaped.mapped = 0; } break; case X11OSD_COLORKEY: if( osd->clean!=UNDEFINED ) XCopyArea (osd->display, osd->bitmap, osd->window, osd->gc, 0, 0, osd->width, osd->height, 0, 0); } } void x11osd_resize (x11osd * osd, int width, int height) { _x_assert (osd); _x_assert (width); _x_assert (height); lprintf("resize old:%dx%d new:%dx%d\n", osd->width, osd->height, width, height ); osd->width = width; osd->height = height; XFreePixmap (osd->display, osd->bitmap); switch(osd->mode) { case X11OSD_SHAPED: XResizeWindow (osd->display, osd->u.shaped.window, osd->width, osd->height); XFreePixmap (osd->display, osd->u.shaped.mask_bitmap); osd->u.shaped.mask_bitmap = XCreatePixmap (osd->display, osd->u.shaped.window, osd->width, osd->height, 1); osd->bitmap = XCreatePixmap (osd->display, osd->u.shaped.window, osd->width, osd->height, osd->depth); break; case X11OSD_COLORKEY: osd->bitmap = XCreatePixmap (osd->display, osd->window, osd->width, osd->height, osd->depth); break; } osd->clean = UNDEFINED; x11osd_clear(osd); } void x11osd_drawable_changed (x11osd * osd, Window window) { XSetWindowAttributes attr; XWindowAttributes getattr; _x_assert (osd); lprintf("drawable changed\n"); /* Do I need to recreate the GC's?? XFreeGC (osd->display, osd->gc); XFreeGC (osd->display, osd->mask_gc); XFreeGC (osd->display, osd->mask_gc_back); */ XFreePixmap (osd->display, osd->bitmap); XFreeColormap (osd->display, osd->cmap); /* we need to call XSync(), because otherwise, calling XDestroyWindow() on the parent window could destroy our OSD window twice !! */ XSync (osd->display, False); osd->window = window; XGetWindowAttributes (osd->display, osd->window, &getattr); osd->width = getattr.width; osd->height = getattr.height; _x_assert(osd->width); _x_assert(osd->height); switch(osd->mode) { case X11OSD_SHAPED: XFreePixmap (osd->display, osd->u.shaped.mask_bitmap); XDestroyWindow (osd->display, osd->u.shaped.window); attr.override_redirect = True; attr.background_pixel = BlackPixel (osd->display, osd->screen); osd->u.shaped.window = XCreateWindow(osd->display, osd->window, 0, 0, osd->width, osd->height, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWOverrideRedirect, &attr); XSelectInput (osd->display, osd->u.shaped.window, ExposureMask); osd->u.shaped.mapped = 0; osd->u.shaped.mask_bitmap = XCreatePixmap (osd->display, osd->u.shaped.window, osd->width, osd->height, 1); osd->bitmap = XCreatePixmap (osd->display, osd->u.shaped.window, osd->width, osd->height, osd->depth); osd->cmap = XCreateColormap(osd->display, osd->u.shaped.window, osd->visual, AllocNone); break; case X11OSD_COLORKEY: osd->bitmap = XCreatePixmap (osd->display, osd->window, osd->width, osd->height, osd->depth); osd->cmap = XCreateColormap(osd->display, osd->window, osd->visual, AllocNone); break; } osd->clean = UNDEFINED; /* do not x11osd_clear() here: osd->u.colorkey.sc has not being updated yet */ } static int x11_error = False ; static int x11_error_handler(Display *dpy, XErrorEvent *error) { (void)dpy; (void)error; x11_error = True; return 0; } x11osd * x11osd_create (xine_t *xine, Display *display, int screen, Window window, enum x11osd_mode mode) { x11osd *osd; int event_basep, error_basep; XErrorHandler old_handler = NULL; XSetWindowAttributes attr; XWindowAttributes getattr; osd = calloc(1, sizeof(x11osd)); if (!osd) return NULL; osd->mode = mode; osd->xine = xine; osd->display = display; osd->screen = screen; osd->window = window; x11_error = False; old_handler = XSetErrorHandler(x11_error_handler); osd->visual = DefaultVisual (osd->display, osd->screen); osd->depth = DefaultDepth (osd->display, osd->screen); XGetWindowAttributes (osd->display, osd->window, &getattr); osd->width = getattr.width; osd->height = getattr.height; _x_assert(osd->width); _x_assert(osd->height); switch (mode) { case X11OSD_SHAPED: if (!XShapeQueryExtension (osd->display, &event_basep, &error_basep)) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: XShape extension not available. unscaled overlay disabled.\n")); goto error2; } attr.override_redirect = True; attr.background_pixel = BlackPixel (osd->display, osd->screen); osd->u.shaped.window = XCreateWindow(osd->display, osd->window, 0, 0, osd->width, osd->height, 0, CopyFromParent, CopyFromParent, CopyFromParent, CWBackPixel | CWOverrideRedirect, &attr); XSync(osd->display, False); if( x11_error ) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating window. unscaled overlay disabled.\n")); goto error_window; } osd->u.shaped.mask_bitmap = XCreatePixmap (osd->display, osd->u.shaped.window, osd->width, osd->height, 1); XSync(osd->display, False); if( x11_error ) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating pixmap. unscaled overlay disabled.\n")); goto error_aftermaskbitmap; } osd->bitmap = XCreatePixmap (osd->display, osd->u.shaped.window, osd->width, osd->height, osd->depth); osd->gc = XCreateGC (osd->display, osd->u.shaped.window, 0, NULL); osd->u.shaped.mask_gc = XCreateGC (osd->display, osd->u.shaped.mask_bitmap, 0, NULL); XSetForeground (osd->display, osd->u.shaped.mask_gc, WhitePixel (osd->display, osd->screen)); XSetBackground (osd->display, osd->u.shaped.mask_gc, BlackPixel (osd->display, osd->screen)); osd->u.shaped.mask_gc_back = XCreateGC (osd->display, osd->u.shaped.mask_bitmap, 0, NULL); XSetForeground (osd->display, osd->u.shaped.mask_gc_back, BlackPixel (osd->display, osd->screen)); XSetBackground (osd->display, osd->u.shaped.mask_gc_back, WhitePixel (osd->display, osd->screen)); XSelectInput (osd->display, osd->u.shaped.window, ExposureMask); osd->u.shaped.mapped = 0; osd->cmap = XCreateColormap(osd->display, osd->u.shaped.window, osd->visual, AllocNone); break; case X11OSD_COLORKEY: osd->bitmap = XCreatePixmap (osd->display, osd->window, osd->width, osd->height, osd->depth); osd->gc = XCreateGC (osd->display, osd->window, 0, NULL); osd->cmap = XCreateColormap(osd->display, osd->window, osd->visual, AllocNone); /* FIXME: the expose event doesn't seem to happen? */ /*XSelectInput (osd->display, osd->window, ExposureMask);*/ break; default: goto error2; } XSync(osd->display, False); if( x11_error ) { xprintf(osd->xine, XINE_VERBOSITY_LOG, _("x11osd: error creating pixmap. unscaled overlay disabled.\n")); goto error_pixmap; } osd->clean = UNDEFINED; x11osd_expose(osd); XSetErrorHandler(old_handler); xprintf(osd->xine, XINE_VERBOSITY_DEBUG, _("x11osd: unscaled overlay created (%s mode).\n"), (mode==X11OSD_SHAPED) ? "XShape" : "Colorkey" ); return osd; /* XFreeGC (osd->display, osd->gc); XFreeGC (osd->display, osd->mask_gc); XFreeGC (osd->display, osd->mask_gc_back); */ error_pixmap: XFreePixmap (osd->display, osd->bitmap); error_aftermaskbitmap: if(mode==X11OSD_SHAPED) XFreePixmap (osd->display, osd->u.shaped.mask_bitmap); error_window: if(mode==X11OSD_SHAPED) XDestroyWindow (osd->display, osd->u.shaped.window); XSetErrorHandler(old_handler); error2: free (osd); return NULL; } void x11osd_colorkey(x11osd * osd, uint32_t colorkey, vo_scale_t *sc) { _x_assert (osd); _x_assert (osd->mode==X11OSD_COLORKEY); osd->u.colorkey.colorkey=colorkey; osd->u.colorkey.sc=sc; osd->clean = UNDEFINED; x11osd_clear(osd); x11osd_expose(osd); } void x11osd_destroy (x11osd * osd) { _x_assert (osd); XFreeGC (osd->display, osd->gc); XFreePixmap (osd->display, osd->bitmap); XFreeColormap (osd->display, osd->cmap); if(osd->mode==X11OSD_SHAPED) { XFreeGC (osd->display, osd->u.shaped.mask_gc); XFreeGC (osd->display, osd->u.shaped.mask_gc_back); XFreePixmap (osd->display, osd->u.shaped.mask_bitmap); XDestroyWindow (osd->display, osd->u.shaped.window); } free (osd); } void x11osd_clear(x11osd *osd) { int i; lprintf("clear (state:%d)\n", osd->clean ); if( osd->clean != WIPED ) switch (osd->mode) { case X11OSD_SHAPED: XFillRectangle (osd->display, osd->u.shaped.mask_bitmap, osd->u.shaped.mask_gc_back, 0, 0, osd->width, osd->height); break; case X11OSD_COLORKEY: XSetForeground(osd->display, osd->gc, osd->u.colorkey.colorkey); if(osd->u.colorkey.sc) { XFillRectangle (osd->display, osd->bitmap, osd->gc, osd->u.colorkey.sc->output_xoffset, osd->u.colorkey.sc->output_yoffset, osd->u.colorkey.sc->output_width, osd->u.colorkey.sc->output_height); XSetForeground(osd->display, osd->gc, BlackPixel(osd->display, osd->screen)); for( i = 0; i < 4; i++ ) { if( osd->u.colorkey.sc->border[i].w && osd->u.colorkey.sc->border[i].h ) { XFillRectangle(osd->display, osd->bitmap, osd->gc, osd->u.colorkey.sc->border[i].x, osd->u.colorkey.sc->border[i].y, osd->u.colorkey.sc->border[i].w, osd->u.colorkey.sc->border[i].h); } } } else XFillRectangle (osd->display, osd->bitmap, osd->gc, 0, 0, osd->width, osd->height); break; } osd->clean = WIPED; } #define X11OSD_TRANSPARENT 0xffffffff #define saturate(n, l, u) ((n) < (l) ? (l) : ((n) > (u) ? (u) : (n))) void x11osd_blend(x11osd *osd, vo_overlay_t *overlay) { if (osd->clean==UNDEFINED) x11osd_clear(osd); /* Workaround. Colorkey mode needs sc data before the clear. */ if (overlay->rle) { int i, x, y, len, width; int use_clip_palette, max_palette_colour[2]; uint32_t palette[2][OVL_PALETTE_SIZE]; max_palette_colour[0] = -1; max_palette_colour[1] = -1; for (i=0, x=0, y=0; inum_rle; i++) { len = overlay->rle[i].len; while (len > 0) { use_clip_palette = 0; if (len > overlay->width) { width = overlay->width; len -= overlay->width; } else { width = len; len = 0; } if ((y >= overlay->hili_top) && (y <= overlay->hili_bottom) && (x <= overlay->hili_right)) { if ((x < overlay->hili_left) && (x + width - 1 >= overlay->hili_left)) { width -= overlay->hili_left - x; len += overlay->hili_left - x; } else if (x > overlay->hili_left) { use_clip_palette = 1; if (x + width - 1 > overlay->hili_right) { width -= overlay->hili_right - x; len += overlay->hili_right - x; } } } if (overlay->rle[i].color > max_palette_colour[use_clip_palette]) { int j; uint32_t *src_color; uint8_t *src_trans; if (use_clip_palette) { src_color = overlay->hili_color; src_trans = (uint8_t *)&overlay->hili_trans; } else { src_color = overlay->color; src_trans = (uint8_t *)&overlay->trans; } for (j=max_palette_colour[use_clip_palette]+1; j<=overlay->rle[i].color; j++) { if (src_trans[j]) { union { uint32_t u32; clut_t c; } tmp = { src_color[j] }; if (1) { XColor xcolor; int y, u, v, r, g, b; y = saturate(tmp.c.y, 16, 235); u = saturate(tmp.c.cb, 16, 240); v = saturate(tmp.c.cr, 16, 240); y = (9 * y) / 8; r = y + (25 * v) / 16 - 218; xcolor.red = (65536 * saturate(r, 0, 255)) / 256; g = y + (-13 * v) / 16 + (-25 * u) / 64 + 136; xcolor.green = (65536 * saturate(g, 0, 255)) / 256; b = y + 2 * u - 274; xcolor.blue = (65536 * saturate(b, 0, 255)) / 256; xcolor.flags = DoRed | DoBlue | DoGreen; XAllocColor(osd->display, osd->cmap, &xcolor); palette[use_clip_palette][j] = xcolor.pixel; } else { if (tmp.c.y > 127) { palette[use_clip_palette][j] = WhitePixel(osd->display, osd->screen); } else { palette[use_clip_palette][j] = BlackPixel(osd->display, osd->screen); } } } else { palette[use_clip_palette][j] = X11OSD_TRANSPARENT; } } max_palette_colour[use_clip_palette] = overlay->rle[i].color; } if(palette[use_clip_palette][overlay->rle[i].color] != X11OSD_TRANSPARENT) { XSetForeground(osd->display, osd->gc, palette[use_clip_palette][overlay->rle[i].color]); XFillRectangle(osd->display, osd->bitmap, osd->gc, overlay->x + x, overlay->y + y, width, 1); if(osd->mode==X11OSD_SHAPED) XFillRectangle(osd->display, osd->u.shaped.mask_bitmap, osd->u.shaped.mask_gc, overlay->x + x, overlay->y + y, width, 1); } x += width; if (x == overlay->width) { x = 0; y++; } } } osd->clean = DRAWN; } } xine-lib-1.2/src/video_out/video_out_pgx32.c0000644000175000017500000006001014647725152016631 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_pgx32.c, Sun PGX32 output plugin for xine * * written and currently maintained by * Robin Kay */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include #include /* gfxp register defines */ #define GFXP_VRAM_MMAPLEN 0x00800000 #define GFXP_REGS_MMAPLEN 0x00020000 #define GFXP_REGSBASE 0x00800000 #define FIFO_SPACE 0x0003 #define RASTERISER_MODE 0x1014 #define RECT_ORIGIN 0x101A #define RECT_SIZE 0x101B #define SCISSOR_MODE 0x1030 #define SCISSOR_MIN_XY 0x1031 #define SCISSOR_MAX_XY 0x1032 #define AREA_STIPPLE_MODE 0x1034 #define WINDOW_ORIGIN 0x1039 #define DY 0x1005 #define TEXTURE_ADDR_MODE 0x1070 #define SSTART 0x1071 #define DSDX 0x1072 #define DSDY_DOM 0x1073 #define TSTART 0x1074 #define DTDX 0x1075 #define DTDY_DOM 0x1076 #define TEXTURE_BASE_ADDR 0x10B0 #define TEXTURE_MAP_FORMAT 0x10B1 #define TEXTURE_DATA_FORMAT 0x10B2 #define TEXTURE_READ_MODE 0x10CE #define TEXTURE_COLOUR_MODE 0x10D0 #define SHADING_MODE 0x10FC #define ALPHA_BLENDING_MODE 0x1102 #define DITHERING_MODE 0x1103 #define LOGICAL_OP_MODE 0x1105 #define STENCIL_MODE 0x1131 #define WRITE_MODE 0x1157 #define WRITE_MASK 0x1158 #define YUV_MODE 0x11E0 #define RENDER 0x1007 #define RENDER_BEGIN 0x00000000006020C0L static const int pitch_code_table[33][2] = { {0, 0000}, {32, 0001}, {64, 0011}, {96, 0111}, {128, 0112}, {160, 0122}, {192, 0222}, {224, 0123}, {256, 0223}, {288, 0133}, {320, 0233}, {384, 0333}, {416, 0134}, {448, 0234}, {512, 0334}, {544, 0144}, {576, 0244}, {640, 0344}, {768, 0444}, {800, 0145}, {832, 0245}, {896, 0345}, {1024, 0445}, {1056, 0155}, {1088, 0255}, {1152, 0355}, {1280, 0455}, {1536, 0555}, {1568, 0156}, {1600, 0256}, {1664, 0356}, {1792, 0456}, {2048, 0556} }; /* Structures */ typedef struct { video_driver_class_t vo_driver_class; xine_t *xine; } pgx32_driver_class_t; typedef struct { vo_frame_t vo_frame; uint32_t *packedbuf, *stripe_dst; int width, height, format, pitch, pitch_code, packedlen, lines_remaining; double ratio; } pgx32_frame_t; typedef struct { vo_driver_t vo_driver; vo_scale_t vo_scale; pgx32_driver_class_t *class; Display *display; int screen, depth; Visual *visual; Drawable drawable; GC gc; Dga_drawable dgadraw; int devfd, fb_width, fb_height, fb_depth; uint8_t *vbase; volatile uint64_t *vregs; pgx32_frame_t *current; int delivered_format, deinterlace_en; alphablend_t alphablend_extra_data; } pgx32_driver_t; /* * Setup X11/DGA */ static int setup_dga(pgx32_driver_t *this) { XWindowAttributes win_attrs; XLockDisplay(this->display); this->dgadraw = XDgaGrabDrawable(this->display, this->drawable); if (!this->dgadraw) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx32: Error: can't grab DGA drawable for video window\n")); XUnlockDisplay(this->display); return 0; } /* If the framebuffer hasn't already been mapped then open it and check it's * a supported type. */ if (!this->vbase) { char *devname; struct vis_identifier ident; struct fbgattr attr; DGA_DRAW_LOCK(this->dgadraw, -1); this->devfd = dga_draw_devfd(this->dgadraw); devname = dga_draw_devname(this->dgadraw); DGA_DRAW_UNLOCK(this->dgadraw); if (ioctl(this->devfd, VIS_GETIDENTIFIER, &ident) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx32: Error: ioctl failed, bad device (%s)\n"), devname); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } if (strcmp("TSIgfxp", ident.name) != 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx32: Error: '%s' is not a pgx32 framebuffer device\n"), devname); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } if (ioctl(this->devfd, FBIOGATTR, &attr) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_pgx32: Error: ioctl failed, bad device (%s)\n"), devname); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); return 0; } this->fb_width = attr.fbtype.fb_width; this->fb_height = attr.fbtype.fb_height; this->fb_depth = attr.fbtype.fb_depth; } this->gc = XCreateGC(this->display, this->drawable, 0, NULL); XGetWindowAttributes(this->display, this->drawable, &win_attrs); this->depth = win_attrs.depth; this->visual = win_attrs.visual; XUnlockDisplay(this->display); return 1; } /* * Cleanup X11/DGA */ static void cleanup_dga(pgx32_driver_t *this) { XLockDisplay(this->display); XFreeGC(this->display, this->gc); XDgaUnGrabDrawable(this->dgadraw); XUnlockDisplay(this->display); } /* * Dispose of any allocated image data within a pgx32_frame_t */ static void dispose_frame_internals(pgx32_frame_t *frame) { if (frame->vo_frame.base[0]) { free(frame->vo_frame.base[0]); frame->vo_frame.base[0] = NULL; } if (frame->vo_frame.base[1]) { free(frame->vo_frame.base[1]); frame->vo_frame.base[1] = NULL; } if (frame->vo_frame.base[2]) { free(frame->vo_frame.base[2]); frame->vo_frame.base[2] = NULL; } if (frame->packedbuf) { free(frame->packedbuf); frame->packedbuf = NULL; } } /* * Convert yuy2 frame/slice to GFXP internal YUV format */ static uint32_t *convert_yuy2(uint32_t *src, int width, int pitch, int height, uint32_t *dst) { int l, x; for (l=0; l> 16) | ((*src & 0xffff) << 16); src++; } dst += (pitch-width)/2; } return dst; } /* * Convert yv12 frame/slice to GFXP internal YUV format */ static uint32_t *convert_yv12(uint16_t *ysrc, uint8_t *usrc, uint8_t *vsrc, int width, int pitch, int height, uint32_t *dst) { int l, x, y, u, v; for (l=0; lvo_frame.proc_called = 1; switch (frame->format) { case XINE_IMGFMT_YUY2: convert_yuy2((uint32_t *)(void *)frame->vo_frame.base[0], frame->width, frame->pitch, frame->height, frame->stripe_dst); break; case XINE_IMGFMT_YV12: convert_yv12((uint16_t *)(void *)frame->vo_frame.base[0], frame->vo_frame.base[1], frame->vo_frame.base[2], frame->width, frame->pitch, frame->height, frame->stripe_dst); break; } } static void pgx32_frame_proc_slice(vo_frame_t *frame_gen, uint8_t **src) { pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen; int slice_height; frame->vo_frame.proc_called = 1; slice_height = (frame->lines_remaining > 16) ? 16 : frame->lines_remaining; frame->lines_remaining -= slice_height; switch (frame->format) { case XINE_IMGFMT_YUY2: frame->stripe_dst = convert_yuy2((uint32_t *)(void *)src[0], frame->width, frame->pitch, slice_height, frame->stripe_dst); break; case XINE_IMGFMT_YV12: frame->stripe_dst = convert_yv12((uint16_t *)(void *)src[0], src[1], src[2], frame->width, frame->pitch, slice_height, frame->stripe_dst); break; } } static void pgx32_frame_field(vo_frame_t *frame_gen, int which_field) { /*pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen;*/ } static void pgx32_frame_dispose(vo_frame_t *frame_gen) { pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen; dispose_frame_internals(frame); free(frame); } static uint32_t pgx32_get_capabilities(vo_driver_t *this_gen) { /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/ return VO_CAP_YV12 | VO_CAP_YUY2; } static vo_frame_t *pgx32_alloc_frame(vo_driver_t *this_gen) { /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/ pgx32_frame_t *frame; frame = calloc(1, sizeof(pgx32_frame_t)); if (!frame) { return NULL; } pthread_mutex_init(&frame->vo_frame.mutex, NULL); frame->vo_frame.proc_frame = pgx32_frame_proc_frame; frame->vo_frame.proc_slice = pgx32_frame_proc_slice; frame->vo_frame.field = pgx32_frame_field; frame->vo_frame.dispose = pgx32_frame_dispose; return (vo_frame_t *)frame; } static void pgx32_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen; pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen; if ((width != frame->width) || (height != frame->height) || (ratio != frame->ratio) || (format != frame->format)) { int i, planes; dispose_frame_internals(frame); frame->width = width; frame->height = height; frame->ratio = ratio; frame->format = format; frame->pitch = 2048; for (i=0; i= frame->width) && (pitch_code_table[i][0] <= frame->pitch)) { frame->pitch = pitch_code_table[i][0]; frame->pitch_code = pitch_code_table[i][1]; } } frame->packedlen = frame->pitch * 2 * height; if (!(frame->packedbuf = memalign(8, frame->packedlen))) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: frame packed buffer malloc failed\n"); _x_abort(); } planes = 0; switch (format) { case XINE_IMGFMT_YUY2: planes = 1; frame->vo_frame.pitches[0] = ((width + 1) / 2) * 4; frame->vo_frame.base[0] = memalign(8, frame->vo_frame.pitches[0] * height); break; case XINE_IMGFMT_YV12: planes = 3; frame->vo_frame.pitches[0] = ((width + 1) / 2) * 2; frame->vo_frame.pitches[1] = (width + 1) / 2; frame->vo_frame.pitches[2] = (width + 1) / 2; frame->vo_frame.base[0] = memalign(8, frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = memalign(8, frame->vo_frame.pitches[1] * ((height + 1) / 2)); frame->vo_frame.base[2] = memalign(8, frame->vo_frame.pitches[2] * ((height + 1) / 2)); break; } for (i=0;ivo_frame.base[i]) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: frame plane malloc failed\n"); _x_abort(); } } } frame->stripe_dst = frame->packedbuf; frame->lines_remaining = frame->height; } static void pgx32_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen) { pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen; pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen; short int *cliprects, wx0, wy0, wx1, wy1, cx0, cy0, cx1, cy1; if ((frame->width != this->vo_scale.delivered_width) || (frame->height != this->vo_scale.delivered_height) || (frame->ratio != this->vo_scale.delivered_ratio) || (frame->format != this->delivered_format)) { this->vo_scale.delivered_width = frame->width; this->vo_scale.delivered_height = frame->height; this->vo_scale.delivered_ratio = frame->ratio; this->delivered_format = frame->format; this->vo_scale.force_redraw = 1; _x_vo_scale_compute_ideal_size(&this->vo_scale); } if (_x_vo_scale_redraw_needed(&this->vo_scale)) { int i; _x_vo_scale_compute_output_size(&this->vo_scale); XLockDisplay(this->display); XSetForeground(this->display, this->gc, BlackPixel(this->display, this->screen)); for (i=0;i<4;i++) { XFillRectangle(this->display, this->drawable, this->gc, this->vo_scale.border[i].x, this->vo_scale.border[i].y, this->vo_scale.border[i].w, this->vo_scale.border[i].h); } XUnlockDisplay(this->display); } memcpy((this->vbase+GFXP_VRAM_MMAPLEN)-frame->packedlen, frame->packedbuf, frame->packedlen); XLockDisplay(this->display); DGA_DRAW_LOCK(this->dgadraw, -1); while(le2me_64(this->vregs[FIFO_SPACE]) < 24) {} this->vregs[RASTERISER_MODE] = 0; this->vregs[SCISSOR_MODE] = 0; this->vregs[AREA_STIPPLE_MODE] = 0; this->vregs[WINDOW_ORIGIN] = 0; this->vregs[DY] = le2me_64(1 << 16); this->vregs[TEXTURE_ADDR_MODE] = le2me_64(1); this->vregs[SSTART] = 0; this->vregs[DSDX] = le2me_64((frame->width << 20) / this->vo_scale.output_width); this->vregs[DSDY_DOM] = 0; this->vregs[TSTART] = 0; this->vregs[DTDX] = 0; this->vregs[DTDY_DOM] = le2me_64((frame->height << 20) / this->vo_scale.output_height); this->vregs[TEXTURE_MAP_FORMAT] = le2me_64((1 << 19) | frame->pitch_code); this->vregs[TEXTURE_DATA_FORMAT] = le2me_64(0x63); this->vregs[TEXTURE_READ_MODE] = le2me_64((1 << 17) | (11 << 13) | (11 << 9) | 1); this->vregs[TEXTURE_COLOUR_MODE] = le2me_64((0 << 4) | (3 << 1) | 1); this->vregs[SHADING_MODE] = 0; this->vregs[ALPHA_BLENDING_MODE] = 0; this->vregs[DITHERING_MODE] = le2me_64((1 << 10) | 1); this->vregs[LOGICAL_OP_MODE] = 0; this->vregs[STENCIL_MODE] = 0; this->vregs[WRITE_MODE] = le2me_64(1); this->vregs[WRITE_MASK] = le2me_64(0x00ffffff); this->vregs[YUV_MODE] = le2me_64(1); wx0 = this->vo_scale.gui_win_x + this->vo_scale.output_xoffset; wy0 = this->vo_scale.gui_win_y + this->vo_scale.output_yoffset; wx1 = wx0 + this->vo_scale.output_width; wy1 = wy0 + this->vo_scale.output_height; cliprects = dga_draw_clipinfo(this->dgadraw); while ((cy0 = *cliprects++) != DGA_Y_EOL) { cy1 = *cliprects++; while ((cx0 = *cliprects++) != DGA_X_EOL) { cx1 = *cliprects++; if ((cx0 >= wx1) || (cy0 >= wy1)) { continue; } if ((cx1 <= wx0) || (cy1 <= wy0)) { continue; } cx0 = (cx0 < wx0) ? wx0 : cx0; cy0 = (cy0 < wy0) ? wy0 : cy0; cx1 = (cx1 > wx1) ? wx1 : cx1; cy1 = (cy1 > wy1) ? wy1 : cy1; while(le2me_64(this->vregs[FIFO_SPACE]) < 4) {} this->vregs[RECT_ORIGIN] = le2me_64(cx0 | (cy0 << 16)); this->vregs[RECT_SIZE] = le2me_64((cx1-cx0) | ((cy1-cy0) << 16)); this->vregs[TEXTURE_BASE_ADDR] = le2me_64(((GFXP_VRAM_MMAPLEN-frame->packedlen) >> 1) + (((cx0-wx0)*frame->width)/this->vo_scale.output_width) + (((cy0-wy0)*frame->height)/this->vo_scale.output_height) * frame->pitch); this->vregs[RENDER] = le2me_64(RENDER_BEGIN); } } while(le2me_64(this->vregs[FIFO_SPACE]) < 5) {} this->vregs[TEXTURE_ADDR_MODE] = 0; this->vregs[TEXTURE_READ_MODE] = 0; this->vregs[TEXTURE_COLOUR_MODE] = 0; this->vregs[DITHERING_MODE] = 0; this->vregs[YUV_MODE] = 0; DGA_DRAW_UNLOCK(this->dgadraw); XUnlockDisplay(this->display); if (this->current != NULL) { this->current->vo_frame.free(&this->current->vo_frame); } this->current = frame; } #define blend(a, b, trans) (((a)*(trans) + (b)*(15-(trans))) / 15) static void pgx32_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/ pgx32_frame_t *frame = (pgx32_frame_t *)frame_gen; if (overlay->rle) { int i, j, x, y, len, width; int use_clip_palette; uint16_t *dst; clut_t clut; uint8_t trans; dst = (uint16_t *)frame->packedbuf + (overlay->y * frame->pitch) + overlay->x; for (i=0, x=0, y=0; inum_rle; i++) { len = overlay->rle[i].len; while (len > 0) { use_clip_palette = 0; if (len > overlay->width) { width = overlay->width; len -= overlay->width; } else { width = len; len = 0; } if ((y >= overlay->hili_top) && (y <= overlay->hili_bottom) && (x <= overlay->hili_right)) { if ((x < overlay->hili_left) && (x + width - 1 >= overlay->hili_left)) { width -= overlay->hili_left - x; len += overlay->hili_left - x; } else if (x > overlay->hili_left) { use_clip_palette = 1; if (x + width - 1 > overlay->hili_right) { width -= overlay->hili_right - x; len += overlay->hili_right - x; } } } if (use_clip_palette) { clut = *(clut_t *)&overlay->hili_color[overlay->rle[i].color]; trans = overlay->hili_trans[overlay->rle[i].color]; } else { clut = *(clut_t *)&overlay->color[overlay->rle[i].color]; trans = overlay->trans[overlay->rle[i].color]; } for (j=0; jx + x + j) & 1) { *(dst-1) = (blend(clut.y, (*(dst-1) >> 8), trans) << 8) | blend(clut.cr, (*(dst-1) & 0xff), trans); } else { *(dst+1) = (blend(clut.y, (*(dst+1) >> 8), trans) << 8) | blend(clut.cb, (*(dst+1) & 0xff), trans); } dst++; } x += width; if (x == overlay->width) { x = 0; y++; dst += frame->pitch - overlay->width; } } } } } static int pgx32_get_property(vo_driver_t *this_gen, int property) { pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen; switch (property) { case VO_PROP_INTERLACED: return this->deinterlace_en; break; case VO_PROP_ASPECT_RATIO: return this->vo_scale.user_ratio; break; default: return 0; break; } } static int pgx32_set_property(vo_driver_t *this_gen, int property, int value) { pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen; switch (property) { case VO_PROP_INTERLACED: { this->deinterlace_en = value; this->vo_scale.force_redraw = 1; } break; case VO_PROP_ASPECT_RATIO: { if (value >= XINE_VO_ASPECT_NUM_RATIOS) { value = XINE_VO_ASPECT_AUTO; } this->vo_scale.user_ratio = value; this->vo_scale.force_redraw = 1; _x_vo_scale_compute_ideal_size(&this->vo_scale); } break; } return value; } static void pgx32_get_property_min_max(vo_driver_t *this_gen, int property, int *min, int *max) { /*pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen;*/ switch (property) { default: *min = 0; *max = 0; break; } } static int pgx32_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *data) { pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen; switch (data_type) { case XINE_GUI_SEND_DRAWABLE_CHANGED: { XLockDisplay(this->display); cleanup_dga(this); this->drawable = (Drawable)data; if (!setup_dga(this)) { /* FIXME! There should be a better way to handle this */ _x_abort(); } XUnlockDisplay(this->display); } break; case XINE_GUI_SEND_EXPOSE_EVENT: { this->vo_scale.force_redraw = 1; } break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { x11_rectangle_t *rect = data; int x1, y1, x2, y2; _x_vo_scale_translate_gui2video(&this->vo_scale, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->vo_scale, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2 - x1; rect->h = y2 - y1; } break; } return 0; } static int pgx32_redraw_needed(vo_driver_t *this_gen) { pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen; if (_x_vo_scale_redraw_needed(&this->vo_scale)) { this->vo_scale.force_redraw = 1; return 1; } return 0; } static void pgx32_dispose(vo_driver_t *this_gen) { pgx32_driver_t *this = (pgx32_driver_t *)(void *)this_gen; cleanup_dga(this); munmap(this->vbase, GFXP_VRAM_MMAPLEN); munmap((void *)this->vregs, GFXP_REGS_MMAPLEN); _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->vo_scale, this->class->xine->config); free(this); } /* * XINE VIDEO DRIVER CLASS FUNCTIONS */ static const vo_info_t vo_info_pgx32 = { .priority = 10, .visual_type = XINE_VISUAL_TYPE_X11, }; static vo_driver_t *pgx32_init_driver(video_driver_class_t *class_gen, const void *visual_gen) { pgx32_driver_class_t *class = (pgx32_driver_class_t *)(void *)class_gen; pgx32_driver_t *this; this = calloc(1, sizeof(pgx32_driver_t)); if (!this) { return NULL; } _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->vo_driver.get_capabilities = pgx32_get_capabilities; this->vo_driver.alloc_frame = pgx32_alloc_frame; this->vo_driver.update_frame_format = pgx32_update_frame_format; this->vo_driver.overlay_begin = NULL; this->vo_driver.overlay_blend = pgx32_overlay_blend; this->vo_driver.overlay_end = NULL; this->vo_driver.display_frame = pgx32_display_frame; this->vo_driver.get_property = pgx32_get_property; this->vo_driver.set_property = pgx32_set_property; this->vo_driver.get_property_min_max = pgx32_get_property_min_max; this->vo_driver.gui_data_exchange = pgx32_gui_data_exchange; this->vo_driver.redraw_needed = pgx32_redraw_needed; this->vo_driver.dispose = pgx32_dispose; _x_vo_scale_init(&this->vo_scale, 0, 0, class->xine->config); this->vo_scale.user_ratio = XINE_VO_ASPECT_AUTO; this->vo_scale.user_data = ((x11_visual_t *)visual_gen)->user_data; this->vo_scale.frame_output_cb = ((x11_visual_t *)visual_gen)->frame_output_cb; this->vo_scale.dest_size_cb = ((x11_visual_t *)visual_gen)->dest_size_cb; this->class = class; this->display = ((x11_visual_t *)visual_gen)->display; this->screen = ((x11_visual_t *)visual_gen)->screen; this->drawable = ((x11_visual_t *)visual_gen)->d; if (!setup_dga(this)) { _x_vo_scale_cleanup (&this->vo_scale, class->xine->config); free(this); return NULL; } if ((this->vbase = mmap(0, GFXP_VRAM_MMAPLEN, PROT_READ | PROT_WRITE, MAP_SHARED, this->devfd, 0x04000000)) == MAP_FAILED) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: Error: unable to memory map framebuffer\n"); cleanup_dga(this); free(this); return NULL; } if ((this->vregs = (uint64_t *)(void *)mmap(0, GFXP_REGS_MMAPLEN, PROT_READ | PROT_WRITE, MAP_SHARED, this->devfd, 0x02000000)) == MAP_FAILED) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_pgx32: Error: unable to memory map framebuffer\n"); munmap(this->vbase, GFXP_VRAM_MMAPLEN); cleanup_dga(this); free(this); return NULL; } return (vo_driver_t *)this; } static void *pgx32_init_class(xine_t *xine, const void *visual_gen) { pgx32_driver_class_t *class; class = calloc(1, sizeof(pgx32_driver_class_t)); if (!class) { return NULL; } DGA_INIT(); class->vo_driver_class.open_plugin = pgx32_init_driver; class->vo_driver_class.identifier = "pgx32"; class->vo_driver_class.description = N_("xine video output plugin for Sun PGX32 framebuffers"); class->vo_driver_class.dispose = default_video_driver_class_dispose; class->xine = xine; return class; } const plugin_info_t xine_plugin_info[] EXPORTED = { {PLUGIN_VIDEO_OUT, 22, "pgx32", XINE_VERSION_CODE, &vo_info_pgx32, pgx32_init_class}, {PLUGIN_NONE, 0, NULL, 0, NULL, NULL} }; xine-lib-1.2/src/video_out/opengl/0000755000175000017500000000000014647725152014734 5ustar memexine-lib-1.2/src/video_out/opengl/xine_glx.c0000644000175000017500000001661614647725152016727 0ustar meme/* * Copyright (C) 2012-2022 the xine project * Copyright (C) 2012 Christophe Thommeret * Copyright (C) 2012-2019 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * * video_out_opengl2.c, a video output plugin using opengl 2.0 * * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xine_gl_plugin.h" #include "xine_gl.h" #include #include /* visual types */ #include #include #include typedef struct { xine_gl_plugin_t p; Display *display; Drawable drawable; int screen; GLXContext context; int lock1, lock2; /* DEBUG */ int is_current; } xine_glx_t; #define GLX(_gl) xine_container_of(_gl, xine_glx_t, p.gl) static int _glx_make_current(xine_gl_t *gl) { xine_glx_t *glx = GLX(gl); int result; _x_assert(!glx->is_current); /* User may change lock1 anytime, make sure we pair lock calls properly. */ glx->lock2 = glx->lock1; XLockDisplay(glx->display); result = glXMakeCurrent(glx->display, glx->drawable, glx->context); if (!result) { XUnlockDisplay (glx->display); xprintf(glx->p.xine, XINE_VERBOSITY_LOG, "glx: display unavailable for rendering\n"); return 0; } if (!glx->lock2) XUnlockDisplay (glx->display); glx->is_current = 1; return result; } static void _glx_release_current(xine_gl_t *gl) { xine_glx_t *glx = GLX(gl); _x_assert(glx->is_current); if (!glx->lock2) XLockDisplay (glx->display); glXMakeCurrent(glx->display, None, NULL); XUnlockDisplay(glx->display); glx->is_current = 0; } static void _glx_swap_buffers(xine_gl_t *gl) { xine_glx_t *glx = GLX(gl); XLockDisplay(glx->display); glXSwapBuffers(glx->display, glx->drawable); XUnlockDisplay(glx->display); } static void _glx_set_native_window(xine_gl_t *gl, void *drawable) { xine_glx_t *glx = GLX(gl); _x_assert(!glx->is_current); XLockDisplay(glx->display); glx->drawable = (intptr_t)drawable; XUnlockDisplay(glx->display); } static void _glx_resize(xine_gl_t *gl, int w, int h) { (void)gl; (void)w; (void)h; } static void *_glx_get_proc_address(xine_gl_t *gl, const char *procname) { (void)gl; #ifdef GLX_ARB_get_proc_address return glXGetProcAddressARB(procname); #else # warning GLX_ARB_get_proc_address extension missing (void)procname; return NULL; #endif } static const char *_glx_query_extensions(xine_gl_t *gl) { #ifdef GLX_VERSION_1_1 xine_glx_t *glx = GLX(gl); return glXQueryExtensionsString (glx->display, glx->screen); #else # warning GLX version 1.1 not detected ! return NULL; #endif } /* * xine module */ static void _module_dispose(xine_module_t *module) { xine_glx_t *glx = (xine_glx_t *)module; lprintf("Destroying glx context %p\n", (void*)glx->context); glx->p.xine->config->unregister_callback (glx->p.xine->config, "video.output.lockdisplay"); _x_assert(!glx->is_current); XLockDisplay(glx->display); if (glx->is_current) { glXMakeCurrent(glx->display, None, NULL); } glXDestroyContext(glx->display, glx->context); XUnlockDisplay(glx->display); free(glx); } static void _glx_set_lockdisplay (void *this_gen, xine_cfg_entry_t *entry) { xine_glx_t *glx = (xine_glx_t *)this_gen; glx->lock1 = entry->num_value; xprintf (glx->p.xine, XINE_VERBOSITY_DEBUG, "glx: lockdisplay=%d\n", glx->lock1); } static void _register_config(config_values_t *config, xine_glx_t *glx) { int r = config->register_bool (config, "video.output.lockdisplay", 0, _("Lock X display during whole frame output."), _("This sometimes reduces system load and jitter.\n"), 10, glx ? _glx_set_lockdisplay : NULL, glx); if (glx) glx->lock1 = r; } static xine_module_t *_glx_get_instance(xine_module_class_t *class_gen, const void *data) { const gl_plugin_params_t *params = data; const x11_visual_t *vis = params->visual; Window root; XVisualInfo *visinfo; GLXContext ctx; int is_direct = 0; xine_glx_t *glx; int attribs[] = { GLX_RGBA, GLX_DOUBLEBUFFER, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 16, None, }; (void)class_gen; if (!(params->flags & XINE_GL_API_OPENGL)) { return NULL; } _x_assert(vis); _x_assert(vis->display); XLockDisplay(vis->display); root = RootWindow(vis->display, vis->screen); if (!root) { goto fail_locked; } visinfo = glXChooseVisual(vis->display, vis->screen, attribs); if (!visinfo) { goto fail_locked; } ctx = glXCreateContext(vis->display, visinfo, NULL, GL_TRUE); XFree(visinfo); if (!ctx) { goto fail_locked; } if (!glXMakeCurrent(vis->display, vis->d, ctx)) { goto fail_created; } is_direct = glXIsDirect(vis->display, ctx); glXMakeCurrent(vis->display, None, NULL); if (!is_direct) { goto fail_created; } glx = calloc(1, sizeof(*glx)); if (!glx) { goto fail_created; } XUnlockDisplay(vis->display); glx->p.module.dispose = _module_dispose; glx->p.gl.make_current = _glx_make_current; glx->p.gl.release_current = _glx_release_current; glx->p.gl.swap_buffers = _glx_swap_buffers; glx->p.gl.resize = _glx_resize; glx->p.gl.set_native_window = _glx_set_native_window; glx->p.gl.dispose = NULL; glx->p.gl.query_extensions = _glx_query_extensions; glx->p.gl.get_proc_address = _glx_get_proc_address; glx->p.xine = params->xine; glx->context = ctx; glx->display = vis->display; glx->drawable = vis->d; glx->screen = vis->screen; _register_config(glx->p.xine->config, glx); return &glx->p.module; fail_created: glXDestroyContext( vis->display, ctx ); fail_locked: XUnlockDisplay (vis->display); return NULL; } /* * plugin */ static void *glx_init_class(xine_t *xine, const void *params) { static const xine_module_class_t xine_glx_class = { .get_instance = _glx_get_instance, .description = N_("GL provider (GLX)"), .identifier = "glx", .dispose = NULL, }; _register_config(xine->config, NULL); (void)xine; (void)params; return (void *)&xine_glx_class; } static const xine_module_info_t module_info_glx = { .priority = 10, .type = "gl_v1", .sub_type = XINE_VISUAL_TYPE_X11, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "glx", XINE_VERSION_CODE, &module_info_glx, glx_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }, }; xine-lib-1.2/src/video_out/opengl/xine_egl.c0000644000175000017500000002555714647725152016710 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2018-2021 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine_egl.c, EGL bindings for OpenGL video output * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xine_gl.h" #include #include /* visual types */ #include #include "xine_gl_plugin.h" #if defined(XINE_EGL_USE_X11) #elif defined(XINE_EGL_USE_WAYLAND) # include #else # error EGL platform undefined #endif #include #include #define EGL(_gl) xine_container_of(_gl, xine_egl_t, p.gl) typedef struct { xine_gl_plugin_t p; EGLDisplay display; EGLContext context; EGLSurface surface; EGLConfig config; #if defined(XINE_EGL_USE_WAYLAND) struct wl_egl_window *window; int width, height; #endif #ifdef EGL_KHR_image PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR; PFNEGLDESTROYIMAGEKHRPROC eglDestroyImageKHR; #endif /* DEBUG */ int is_current; } xine_egl_t; static const char *_egl_error_str(EGLint error) { switch (error) { case EGL_SUCCESS: return "No error"; case EGL_NOT_INITIALIZED: return "EGL not initialized or failed to initialize"; case EGL_BAD_ACCESS: return "Resource inaccessible"; case EGL_BAD_ALLOC: return "Cannot allocate resources"; case EGL_BAD_ATTRIBUTE: return "Unrecognized attribute or attribute value"; case EGL_BAD_CONTEXT: return "Invalid EGL context"; case EGL_BAD_CONFIG: return "Invalid EGL frame buffer configuration"; case EGL_BAD_CURRENT_SURFACE: return "Current surface is no longer valid"; case EGL_BAD_DISPLAY: return "Invalid EGL display"; case EGL_BAD_SURFACE: return "Invalid surface"; case EGL_BAD_MATCH: return "Inconsistent arguments"; case EGL_BAD_PARAMETER: return "Invalid argument"; case EGL_BAD_NATIVE_PIXMAP: return "Invalid native pixmap"; case EGL_BAD_NATIVE_WINDOW: return "Invalid native window"; case EGL_CONTEXT_LOST: return "Context lost"; } return "Unknown error "; } static inline void _egl_log_error(xine_t *xine, const char *msg) { EGLint error = eglGetError(); xprintf(xine, XINE_VERBOSITY_LOG, "egl: %s : %s (%d)\n", msg, _egl_error_str(error), error); } static int _egl_make_current(xine_gl_t *gl) { xine_egl_t *egl = EGL(gl); int result; _x_assert(!egl->is_current); result = eglMakeCurrent(egl->display, egl->surface, egl->surface, egl->context); if (!result) { _egl_log_error(egl->p.xine, "eglMakeCurrent() failed"); return 0; } egl->is_current = 1; return result; } static void _egl_release_current(xine_gl_t *gl) { xine_egl_t *egl = EGL(gl); _x_assert(egl->is_current); eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); egl->is_current = 0; } static void _egl_swap_buffers(xine_gl_t *gl) { xine_egl_t *egl = EGL(gl); eglSwapBuffers(egl->display, egl->surface); } static void _egl_set_native_window(xine_gl_t *gl, void *drawable) { xine_egl_t *egl = EGL(gl); EGLNativeWindowType window; _x_assert(!egl->is_current); eglDestroySurface (egl->display, egl->surface); #if defined(XINE_EGL_USE_X11) window = (intptr_t)drawable; #elif defined(XINE_EGL_USE_WAYLAND) wl_egl_window_destroy(egl->window); window = egl->window = wl_egl_window_create(drawable, egl->width, egl->height); #endif egl->surface = eglCreateWindowSurface(egl->display, egl->config, window, NULL); if (egl->surface == EGL_NO_SURFACE) { _egl_log_error(egl->p.xine, "eglCreateWindowSurface() failed"); } } static void _egl_resize(xine_gl_t *gl, int w, int h) { #if defined(XINE_EGL_USE_WAYLAND) xine_egl_t *egl = EGL(gl); wl_egl_window_resize(egl->window, w, h, 0, 0); egl->width = w; egl->height = h; #else (void)gl; (void)w; (void)h; #endif } static const char *_egl_query_string(xine_gl_t *gl, int type) { xine_egl_t *egl = EGL(gl); return eglQueryString(egl->display, type); } static const char *_egl_query_extensions(xine_gl_t *gl) { return _egl_query_string(gl, EGL_EXTENSIONS); } static void *_egl_get_proc_address(xine_gl_t *gl, const char *procname) { (void)gl; return (void *)eglGetProcAddress(procname); } #ifdef EGL_KHR_image static void *_egl_create_image_khr(xine_gl_t *gl, unsigned target, void *buffer, const int32_t *attrib_list) { xine_egl_t *egl = EGL(gl); void *img; img = egl->eglCreateImageKHR(egl->display, EGL_NO_CONTEXT, target, buffer, attrib_list); if (!img) { _egl_log_error(egl->p.xine, "eglCreateImageKHR"); } return img; } static int _egl_destroy_image_khr(xine_gl_t *gl, void *image) { xine_egl_t *egl = EGL(gl); return egl->eglDestroyImageKHR(egl->display, image); } #endif /* EGL_KHR_image */ static int _egl_init(xine_egl_t *egl, EGLNativeDisplayType native_display, int api) { static const EGLint attributes[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, EGL_DEPTH_SIZE, 16, EGL_NONE }; static const EGLint context_attribs[] = { //EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; EGLint num_config; egl->display = eglGetDisplay(native_display); if (egl->display == EGL_NO_DISPLAY) { _egl_log_error(egl->p.xine, "eglGetDisplay() failed"); return 0; } if (!eglInitialize (egl->display, NULL, NULL)) { _egl_log_error(egl->p.xine, "eglInitialize() failed"); goto fail; } eglChooseConfig(egl->display, attributes, &egl->config, 1, &num_config); if (!eglBindAPI (api)) { _egl_log_error(egl->p.xine, "OpenGL API unavailable"); goto fail; } egl->context = eglCreateContext(egl->display, egl->config, EGL_NO_CONTEXT, context_attribs); if (egl->context == EGL_NO_CONTEXT) { _egl_log_error(egl->p.xine, "eglCreateContext() failed"); goto fail; } return 1; fail: eglTerminate(egl->display); return 0; } static void _egl_dispose(xine_gl_t *gl) { xine_egl_t *egl = EGL(gl); lprintf("Destroying egl context %p\n", (void*)egl->context); _x_assert(!egl->is_current); if (egl->is_current) { eglMakeCurrent(egl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); } eglDestroySurface (egl->display, egl->surface); #if defined(XINE_EGL_USE_WAYLAND) wl_egl_window_destroy(egl->window); #endif eglDestroyContext(egl->display, egl->context); eglTerminate(egl->display); free(egl); } /* * xine module */ static void _module_dispose(xine_module_t *module) { xine_egl_t *egl = xine_container_of(module, xine_egl_t, p.module); _egl_dispose(&egl->p.gl); } static xine_module_t *_egl_get_instance(xine_module_class_t *class_gen, const void *data) { const gl_plugin_params_t *params = data; EGLNativeWindowType native_window; xine_egl_t *egl; #if defined(XINE_EGL_USE_X11) const x11_visual_t *vis = params->visual; _x_assert(params->visual_type == XINE_VISUAL_TYPE_X11 || params->visual_type == XINE_VISUAL_TYPE_X11_2); #elif defined(XINE_EGL_USE_WAYLAND) const xine_wayland_visual_t *vis = params->visual; _x_assert (params->visual_type == XINE_VISUAL_TYPE_WAYLAND); #endif (void)class_gen; if (!(params->flags & (XINE_GL_API_OPENGL | XINE_GL_API_OPENGLES))) { return NULL; } _x_assert(params->visual); _x_assert(vis->display); egl = calloc(1, sizeof(*egl)); if (!egl) { return NULL; } egl->p.module.dispose = _module_dispose; egl->p.gl.make_current = _egl_make_current; egl->p.gl.release_current = _egl_release_current; egl->p.gl.swap_buffers = _egl_swap_buffers; egl->p.gl.resize = _egl_resize; egl->p.gl.set_native_window = _egl_set_native_window; egl->p.gl.dispose = NULL; egl->p.gl.query_extensions = _egl_query_extensions; egl->p.gl.get_proc_address = _egl_get_proc_address; #ifdef EGL_KHR_image egl->eglCreateImageKHR = (void *)eglGetProcAddress("eglCreateImageKHR"); egl->eglDestroyImageKHR = (void *)eglGetProcAddress("eglDestroyImageKHR"); if (egl->eglCreateImageKHR && egl->eglDestroyImageKHR) { egl->p.gl.eglCreateImageKHR = _egl_create_image_khr; egl->p.gl.eglDestroyImageKHR = _egl_destroy_image_khr; } #endif /* EGL_KHR_image */ egl->p.xine = params->xine; do { if (params->flags & XINE_GL_API_OPENGL) if (_egl_init(egl, vis->display, EGL_OPENGL_API)) break; if (params->flags & XINE_GL_API_OPENGLES) if (_egl_init(egl, vis->display, EGL_OPENGL_ES_API)) break; free(egl); return NULL; } while (0); #if defined(XINE_EGL_USE_X11) native_window = vis->d; #elif defined(XINE_EGL_USE_WAYLAND) egl->width = 720; egl->height = 576; native_window = wl_egl_window_create(vis->surface, egl->width, egl->height); egl->window = native_window; egl->surface = vis->surface; #endif egl->surface = eglCreateWindowSurface(egl->display, egl->config, native_window, NULL); if (egl->surface == EGL_NO_SURFACE) { _egl_log_error(egl->p.xine, "eglCreateWindowSurface() failed"); goto fail; } return &egl->p.module; fail: eglDestroyContext(egl->display, egl->context); eglTerminate(egl->display); free(egl); return NULL; } /* * plugin */ static void *egl_init_class(xine_t *xine, const void *params) { static const xine_module_class_t xine_egl_class = { .get_instance = _egl_get_instance, #if defined(XINE_EGL_USE_X11) .description = "GL provider (EGL/X11)", #elif defined(XINE_EGL_USE_WAYLAND) .description = "GL provider (EGL/Wayland)", #endif .identifier = "egl", .dispose = NULL, }; (void)xine; (void)params; return (void *)&xine_egl_class; } #if defined(XINE_EGL_USE_X11) static const xine_module_info_t module_info_egl = { .priority = 9, .type = "gl_v1", .sub_type = XINE_VISUAL_TYPE_X11, }; #elif defined(XINE_EGL_USE_WAYLAND) static const xine_module_info_t module_info_egl = { .priority = 10, .type = "gl_v1", .sub_type = XINE_VISUAL_TYPE_WAYLAND, }; #endif const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "egl", XINE_VERSION_CODE, &module_info_egl, egl_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL }, }; xine-lib-1.2/src/video_out/opengl/xine_gl.h0000644000175000017500000001152414647725152016535 0ustar meme/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2018-2021 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine_gl.h, Interface between OpenGL and native windowing system * * GL provider API, used in vo drivers * */ #ifndef XINE_GL_H_ #define XINE_GL_H_ #include #include #include #include typedef struct xine_gl xine_gl_t; struct xine_gl { int (*make_current) (xine_gl_t *); void (*release_current) (xine_gl_t *); void (*swap_buffers) (xine_gl_t *); /* resize is needed only with WAYLAND visual */ void (*resize) (xine_gl_t *, int width, int height); /* set_native_window is used only with X11 */ void (*set_native_window)(xine_gl_t *, void *); void (*dispose) (xine_gl_t **); void *(*get_proc_address)(xine_gl_t *, const char *); const char * (*query_extensions)(xine_gl_t *); /* EGL */ void * (*eglCreateImageKHR) (xine_gl_t *, unsigned /* EGLenum target */, void * /* EGLClientBuffer buffer */, const int32_t * /*const EGLint * attrib_list */); int (*eglDestroyImageKHR) (xine_gl_t *, void *); }; xine_gl_t *_x_load_gl(xine_t *xine, unsigned visual_type, const void *visual, unsigned flags); static inline int _x_gl_has_extension(const char *extensions, const char * const ext) { if (extensions) while (*extensions) { const char *p = ext; while (*extensions == ' ') extensions++; while (*p && *p == *extensions) p++, extensions++; if (*p == 0 && (*extensions == 0 || *extensions == ' ')) return 1; while (*extensions && *extensions != ' ') extensions++; } return 0; } /* flags */ #define XINE_GL_API_OPENGL 0x0001 #define XINE_GL_API_OPENGLES 0x0002 typedef struct { xine_sarray_t *list; unsigned char *buf; } xine_gl_extensions_t; static inline void xine_gl_extensions_unload (xine_gl_extensions_t *e) { xine_sarray_delete (e->list); free (e->buf); e->list = NULL; e->buf = NULL; } static inline void xine_gl_extensions_load (xine_gl_extensions_t *e, const char *list) { size_t llen; unsigned char *p, *d; e->list = NULL; e->buf = NULL; if (!list) return; llen = strlen (list); e->buf = malloc (llen + 2); /* TJ. I got 298 strings here :-) */ e->list = xine_sarray_new (1024, (xine_sarray_comparator_t)strcmp); if (!e->list || !e->buf) { xine_gl_extensions_unload (e); return; } p = e->buf; memcpy (p, list, llen + 1); /* safe end plug */ d = p + llen; memcpy (d, " 0", 2); while (1) { unsigned char *q; /* skip spaces (simple, there should be just 1). */ while (*p <= ' ') p++; /* are we done? */ if (p >= d) break; q = p; /* find next spc (fast). */ { const union { unsigned char *b; uint32_t *u; } u = { p - ((uintptr_t)p & 3) }; uint32_t *s = u.u; static const union { uint8_t b[4]; uint32_t v; } mask[4] = { {{0xff, 0xff, 0xff, 0xff}}, {{0x00, 0xff, 0xff, 0xff}}, {{0x00, 0x00, 0xff, 0xff}}, {{0x00, 0x00, 0x00, 0xff}}, }; static const uint8_t rest[32] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, /* big wndian */ 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4 /* little endian */ }; const union { uint32_t v; uint8_t b[4]; } endian = {16}; uint32_t w = (~(*s++)) & mask[(uintptr_t)p & 3].v; while (1) { w = w & 0x80808080 & ((w & 0x7f7f7f7f) + 0x21212121); if (w) break; w = ~(*s++); } /* bits 31, 23, 15, 7 -> 3, 2, 1, 0 */ w = (w * 0x00204081) & 0xffffffff; w >>= 28; p = (unsigned char *)s - rest[endian.b[0] + w]; } *p++ = 0; xine_sarray_add (e->list, q); } } static inline int xine_gl_extensions_test (xine_gl_extensions_t *e, const char *name) { return xine_sarray_binary_search (e->list, (void *)name) >= 0; /** << will not be written to */ } #endif /* XINE_GL_H_ */ xine-lib-1.2/src/video_out/opengl/xine_gl.c0000644000175000017500000000406514647725152016532 0ustar meme/* * Copyright (C) 2018-2019 the xine project * Copyright (C) 2018-2019 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine_gl.c, Interface between OpenGL and native windowing system * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xine_gl.h" #include "xine_gl_plugin.h" #include #include #define PLUGIN(_gl) xine_container_of(_gl, xine_gl_plugin_t, gl) /* technically, we can't unload dynamic module from the module itself. * it would work now (nothing is unloaded), but there may be problems in * the future if plugin loader unloads the library in _x_free_module(). */ static void default_gl_dispose(xine_gl_t **pgl) { if (*pgl) { xine_gl_plugin_t *plugin = PLUGIN(*pgl); xine_module_t *module = &plugin->module; *pgl = NULL; _x_free_module(plugin->xine, &module); } } /* * loader wrapper */ xine_gl_t *_x_load_gl(xine_t *xine, unsigned visual_type, const void *visual, unsigned flags) { const gl_plugin_params_t params = { .xine = xine, .visual_type = visual_type, .visual = visual, .flags = flags, }; xine_gl_plugin_t *p; p = (xine_gl_plugin_t*)_x_find_module(xine, GL_PLUGIN_TYPE, NULL, visual_type, ¶ms); if (p) { p->gl.dispose = default_gl_dispose; return &p->gl; } return NULL; } xine-lib-1.2/src/video_out/opengl/xine_gl_plugin.h0000644000175000017500000000300414647725152020105 0ustar meme/* * Copyright (C) 2018-2019 the xine project * Copyright (C) 2018-2019 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine GL interface plugin: * interface between OpenGL and native windowing system (GLX/EGL/WGL/Wayland/...) * * GL plugin API, used in GL provider plugins */ #ifndef XINE_GL_PLUGIN_H_ #define XINE_GL_PLUGIN_H_ #include #include #include #include "xine_gl.h" #define GL_PLUGIN_TYPE "gl_v1" typedef struct xine_gl_plugin_s xine_gl_plugin_t; struct xine_gl_plugin_s { xine_module_t module; xine_gl_t gl; xine_t *xine; }; typedef struct { xine_t *xine; unsigned visual_type; const void *visual; unsigned flags; } gl_plugin_params_t; #endif /* XINE_GL_PLUGIN_H_ */ xine-lib-1.2/src/video_out/video_out_sdl.c0000644000175000017500000004267014647725152016464 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_sdl.c, Simple DirectMedia Layer * * based on mpeg2dec code from * Ryan C. Gordon and * Dominik Schnitzer * * xine version by Miguel Freitas (Jan/2002) * Missing features: * - mouse position translation * - fullscreen * - stability, testing, etc?? ;) * Known bugs: * - without X11, a resize is need to show image (?) * * BIG WARNING HERE: if you use RedHat SDL packages you will probably * get segfault when no hwaccel is available. more info at: * https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=58408 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_SDL11_SDL_H # include #else # include #endif #define LOG_MODULE "video_out_sdl" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include #include #include #include #ifdef HAVE_X11 #include #endif typedef struct sdl_driver_s sdl_driver_t; typedef struct sdl_frame_s { vo_frame_t vo_frame; int width, height, format; double ratio; SDL_Overlay * overlay; } sdl_frame_t; struct sdl_driver_s { vo_driver_t vo_driver; int hw_accel; SDL_Surface *surface; uint32_t sdlflags; uint8_t bpp; pthread_mutex_t mutex; uint32_t capabilities; vo_scale_t sc; xine_t *xine; alphablend_t alphablend_extra_data; int last_gui_width; /* used when frontend does not provide frame_output_cb */ int last_gui_height; }; typedef struct { video_driver_class_t driver_class; config_values_t *config; xine_t *xine; int visual_type; } sdl_class_t; static uint32_t sdl_get_capabilities (vo_driver_t *this_gen) { sdl_driver_t *this = (sdl_driver_t *) this_gen; return this->capabilities; } static void sdl_frame_field (vo_frame_t *vo_img, int which_field) { /* not needed for SDL */ (void)vo_img; (void)which_field; } static void sdl_frame_dispose (vo_frame_t *vo_img) { sdl_frame_t *frame = (sdl_frame_t *) vo_img ; if( frame->overlay ) SDL_FreeYUVOverlay (frame->overlay); free (frame); } static vo_frame_t *sdl_alloc_frame (vo_driver_t *this_gen) { /* sdl_driver_t *this = (sdl_driver_t *) this_gen; */ sdl_frame_t *frame ; (void)this_gen; frame = (sdl_frame_t *) calloc(1, sizeof(sdl_frame_t)); if (!frame) return NULL; pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions */ frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = sdl_frame_field; frame->vo_frame.dispose = sdl_frame_dispose; return (vo_frame_t *) frame; } static void sdl_compute_ideal_size (sdl_driver_t *this) { _x_vo_scale_compute_ideal_size( &this->sc ); } static void sdl_compute_output_size (sdl_driver_t *this) { _x_vo_scale_compute_output_size( &this->sc ); lprintf ("frame source %d x %d => screen output %d x %d\n", this->sc.delivered_width, this->sc.delivered_height, this->sc.output_width, this->sc.output_height); } static void sdl_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { sdl_driver_t *this = (sdl_driver_t *) this_gen; sdl_frame_t *frame = (sdl_frame_t *) frame_gen; (void)flags; if ((frame->width != (int)width) || (frame->height != (int)height) || (frame->format != format)) { /* * (re-) allocate image */ if( frame->overlay ) { SDL_FreeYUVOverlay (frame->overlay); frame->overlay = NULL; } if( format == XINE_IMGFMT_YV12 ) { lprintf ("format YV12 "); frame->overlay = SDL_CreateYUVOverlay (width, height, SDL_YV12_OVERLAY, this->surface); } else if( format == XINE_IMGFMT_YUY2 ) { lprintf ("format YUY2 "); frame->overlay = SDL_CreateYUVOverlay (width, height, SDL_YUY2_OVERLAY, this->surface); } if (frame->overlay == NULL) return; /* * This needs to be done becuase I have found that * pixels isn't setup until this is called. */ SDL_LockYUVOverlay (frame->overlay); frame->vo_frame.pitches[0] = frame->overlay->pitches[0]; frame->vo_frame.pitches[1] = frame->overlay->pitches[2]; frame->vo_frame.pitches[2] = frame->overlay->pitches[1]; frame->vo_frame.base[0] = frame->overlay->pixels[0]; frame->vo_frame.base[1] = frame->overlay->pixels[2]; frame->vo_frame.base[2] = frame->overlay->pixels[1]; frame->width = width; frame->height = height; frame->format = format; } else { SDL_LockYUVOverlay (frame->overlay); } frame->ratio = ratio; } /* * */ static void sdl_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { sdl_driver_t *this = (sdl_driver_t *) this_gen; sdl_frame_t *frame = (sdl_frame_t *) frame_gen; this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; if (overlay->rle) { if( frame->format == XINE_IMGFMT_YV12 ) _x_blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else _x_blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } static void sdl_check_events (sdl_driver_t * this) { SDL_Event event; while (SDL_PollEvent (&event)) { if (event.type == SDL_VIDEORESIZE) { if( event.resize.w != this->sc.gui_width || event.resize.h != this->sc.gui_height ) { this->sc.gui_width = event.resize.w; this->sc.gui_height = event.resize.h; sdl_compute_output_size(this); this->surface = SDL_SetVideoMode (this->sc.gui_width, this->sc.gui_height, this->bpp, this->sdlflags); } } } } static int sdl_redraw_needed (vo_driver_t *this_gen) { sdl_driver_t *this = (sdl_driver_t *) this_gen; int ret = 0; if (this->sc.frame_output_cb) { if( _x_vo_scale_redraw_needed( &this->sc ) ) { sdl_compute_output_size (this); ret = 1; } return ret; } else { if( this->last_gui_width != this->sc.gui_width || this->last_gui_height != this->sc.gui_height || this->sc.force_redraw ) { this->last_gui_width = this->sc.gui_width; this->last_gui_height = this->sc.gui_height; sdl_compute_output_size (this); ret = 1; } this->sc.force_redraw = 0; return ret; } } static void sdl_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { sdl_driver_t *this = (sdl_driver_t *) this_gen; sdl_frame_t *frame = (sdl_frame_t *) frame_gen; SDL_Rect clip_rect; pthread_mutex_lock(&this->mutex); if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) ) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: change frame format\n"); this->sc.delivered_width = frame->width; this->sc.delivered_height = frame->height; this->sc.delivered_ratio = frame->ratio; sdl_compute_ideal_size( this ); this->sc.force_redraw = 1; } /* * tell gui that we are about to display a frame, * ask for offset and output size */ sdl_check_events (this); sdl_redraw_needed (this_gen); SDL_UnlockYUVOverlay (frame->overlay); clip_rect.x = this->sc.output_xoffset; clip_rect.y = this->sc.output_yoffset; clip_rect.w = this->sc.output_width; clip_rect.h = this->sc.output_height; SDL_DisplayYUVOverlay (frame->overlay, &clip_rect); frame->vo_frame.free (&frame->vo_frame); pthread_mutex_unlock(&this->mutex); } static int sdl_get_property (vo_driver_t *this_gen, int property) { sdl_driver_t *this = (sdl_driver_t *) this_gen; switch (property) { case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; case VO_PROP_OUTPUT_WIDTH: return this->sc.output_width; case VO_PROP_OUTPUT_HEIGHT: return this->sc.output_height; case VO_PROP_OUTPUT_XOFFSET: return this->sc.output_xoffset; case VO_PROP_OUTPUT_YOFFSET: return this->sc.output_yoffset; case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; } return 0; } static int sdl_set_property (vo_driver_t *this_gen, int property, int value) { sdl_driver_t *this = (sdl_driver_t *) this_gen; if ( property == VO_PROP_ASPECT_RATIO) { if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); sdl_compute_ideal_size (this); this->sc.force_redraw = 1; } return value; } static void sdl_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { /* sdl_driver_t *this = (sdl_driver_t *) this_gen; */ (void)this_gen; (void)property; (void)min; (void)max; } static int sdl_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { int ret = 0; #ifdef HAVE_X11 sdl_driver_t *this = (sdl_driver_t *) this_gen; pthread_mutex_lock(&this->mutex); switch (data_type) { case XINE_GUI_SEND_DRAWABLE_CHANGED: lprintf ("XINE_GUI_SEND_DRAWABLE_CHANGED\n"); //this->drawable = (Drawable) data; /* OOPS! Is it possible to change SDL window id? */ /* probably we need to close and reinitialize SDL */ break; case XINE_GUI_SEND_EXPOSE_EVENT: lprintf ("XINE_GUI_SEND_EXPOSE_EVENT\n"); break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: ret = -1; } pthread_mutex_unlock(&this->mutex); #else ret = -1; #endif return ret; } static void sdl_dispose (vo_driver_t * this_gen) { sdl_driver_t *this = (sdl_driver_t*) this_gen; SDL_FreeSurface (this->surface); SDL_QuitSubSystem (SDL_INIT_VIDEO); _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); free(this); } static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { sdl_class_t *class = (sdl_class_t*) class_gen; config_values_t *config = class->xine->config; sdl_driver_t *this; const SDL_VideoInfo *vidInfo; static char SDL_windowhack[32]; #ifdef HAVE_X11 XWindowAttributes window_attributes; #endif if ((SDL_Init (SDL_INIT_VIDEO)) < 0) { xprintf (class->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: open_plugin - sdl video initialization failed.\n"); return NULL; } this = (sdl_driver_t *) calloc(1, sizeof(sdl_driver_t)); if (!this) return NULL; vidInfo = SDL_GetVideoInfo (); if (!SDL_ListModes (vidInfo->vfmt, SDL_HWSURFACE | SDL_RESIZABLE)) { this->sdlflags = SDL_RESIZABLE; if (!SDL_ListModes (vidInfo->vfmt, SDL_RESIZABLE)) { xprintf (class->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: open_plugin - sdl couldn't get any acceptable video mode\n"); free(this); return NULL; } } _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->sdlflags = SDL_HWSURFACE | SDL_RESIZABLE; this->hw_accel = config->register_bool(config, "video.device.sdl_hw_accel", 1, _("use hardware acceleration if available"), _("When your system supports it, hardware acceleration provided by your " "graphics hardware will be used. This might not work, so you can disable it, " "if things go wrong."), 10, NULL, NULL); xine_setenv("SDL_VIDEO_YUV_HWACCEL", (this->hw_accel) ? "1" : "0", 1); xine_setenv("SDL_VIDEO_X11_NODIRECTCOLOR", "1", 1); this->xine = class->xine; _x_vo_scale_init( &this->sc, 0, 0, config); if (visual_gen) { if (class->visual_type == XINE_VISUAL_TYPE_X11) { const x11_visual_t *visual = (const x11_visual_t *) visual_gen; this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; /* set SDL to use our existing X11/win32 window */ if (visual->d) { sprintf(SDL_windowhack,"SDL_WINDOWID=0x%x", (uint32_t) visual->d); putenv(SDL_windowhack); } } else { const fb_visual_t *visual = (const fb_visual_t *) visual_gen; this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; } } this->bpp = vidInfo->vfmt->BitsPerPixel; if (this->bpp < 16) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("sdl has to emulate a 16 bit surfaces, that will slow things down.\n")); this->bpp = 16; } pthread_mutex_init (&this->mutex, NULL); this->capabilities = VO_CAP_YUY2 | VO_CAP_YV12; this->sc.gui_width = 320; this->sc.gui_height = 240; #ifdef HAVE_X11 if (visual_gen && class->visual_type == XINE_VISUAL_TYPE_X11) { const x11_visual_t *visual = (const x11_visual_t *) visual_gen; XGetWindowAttributes(visual->display, visual->d, &window_attributes); this->sc.gui_width = window_attributes.width; this->sc.gui_height = window_attributes.height; } #endif this->surface = SDL_SetVideoMode (this->sc.gui_width, this->sc.gui_height, this->bpp, this->sdlflags); this->vo_driver.get_capabilities = sdl_get_capabilities; this->vo_driver.alloc_frame = sdl_alloc_frame; this->vo_driver.update_frame_format = sdl_update_frame_format; this->vo_driver.overlay_begin = NULL; /* not used */ this->vo_driver.overlay_blend = sdl_overlay_blend; this->vo_driver.overlay_end = NULL; /* not used */ this->vo_driver.display_frame = sdl_display_frame; this->vo_driver.get_property = sdl_get_property; this->vo_driver.set_property = sdl_set_property; this->vo_driver.get_property_min_max = sdl_get_property_min_max; this->vo_driver.gui_data_exchange = sdl_gui_data_exchange; this->vo_driver.dispose = sdl_dispose; this->vo_driver.redraw_needed = sdl_redraw_needed; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: warning, xine's SDL driver is EXPERIMENTAL\n"); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: in case of trouble, try setting video.device.sdl_hw_accel=0\n"); xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_sdl: fullscreen mode is NOT supported\n")); return &this->vo_driver; } /** * Class Functions */ static void *init_class (xine_t *xine, const void *visual_gen) { /* x11_visual_t *visual = (x11_visual_t *) visual_gen; */ sdl_class_t *this; (void)visual_gen; /* check if we have SDL */ if ((SDL_Init (SDL_INIT_VIDEO)) < 0) { xprintf (xine, XINE_VERBOSITY_DEBUG, "video_out_sdl: open_plugin - sdl video initialization failed.\n"); return NULL; } SDL_QuitSubSystem (SDL_INIT_VIDEO); this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "SDL"; this->driver_class.description = N_("xine video output plugin using the Simple Direct Media Layer"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; this->visual_type = XINE_VISUAL_TYPE_X11; return this; } static void *init_class_fb (xine_t *xine, const void *visual_gen) { sdl_class_t *this = (sdl_class_t *)init_class(xine, visual_gen); if (this) { this->visual_type = XINE_VISUAL_TYPE_FB; } return this; } static const vo_info_t vo_info_sdl = { .priority = 4, .visual_type = XINE_VISUAL_TYPE_X11, }; static const vo_info_t vo_info_sdl_fb = { .priority = 4, .visual_type = XINE_VISUAL_TYPE_FB, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "sdl", XINE_VERSION_CODE, &vo_info_sdl, init_class }, { PLUGIN_VIDEO_OUT, 22, "sdl", XINE_VERSION_CODE, &vo_info_sdl_fb, init_class_fb }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_directfb.c0000644000175000017500000021067714647725152017470 0ustar meme/* * Copyright (C) 2000-2020 the xine project and Claudio Ciccani * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * DirectFB based output plugin by Claudio Ciccani * * Based on video_out_xv.c and video_out_vidix.c. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #ifdef DIRECTFB_X11 # include #endif #define LOG_MODULE "video_out_directfb" #define LOG_VERBOSE #include "xine.h" #include #include #include #include #ifdef DIRECTFB_X11 # include "x11osd.h" #endif #include #include #define VERSION_CODE( M, m, r ) (((M) * 1000) + ((m) * 100) + (r)) #define DIRECTFB_VERSION_CODE VERSION_CODE( DIRECTFB_MAJOR_VERSION,\ DIRECTFB_MINOR_VERSION,\ DIRECTFB_MICRO_VERSION ) typedef struct directfb_frame_s { vo_frame_t vo_frame; int width; int height; DFBSurfacePixelFormat format; double ratio; IDirectFBSurface *surface; int locked; } directfb_frame_t; typedef struct directfb_driver_s { vo_driver_t vo_driver; int visual_type; uint32_t capabilities; xine_t *xine; directfb_frame_t *cur_frame; /* DirectFB related stuff */ IDirectFB *dfb; IDirectFBDisplayLayer *underlay; /* Video Layer */ IDirectFBDisplayLayer *layer; IDirectFBSurface *surface; DFBDisplayLayerTypeFlags type; DFBDisplayLayerCapabilities caps; DFBDisplayLayerConfig config; DFBColorAdjustment cadj; DFBColorAdjustment default_cadj; int default_level; int visible; /* Subpicture layer */ IDirectFBDisplayLayer *spic_layer; IDirectFBSurface *spic_surface; /* for hardware scaling */ IDirectFBSurface *temp; int temp_frame_width; int temp_frame_height; DFBSurfacePixelFormat temp_frame_format; /* wheter card supports stretchblit with deinterlacing */ int hw_deinterlace; /* wheter to enable deinterlacing */ int deinterlace; /* configurable options */ int buffermode; int vsync; int colorkeying; uint32_t colorkey; int flicker_filtering; int field_parity; #ifdef DIRECTFB_X11 /* X11 related stuff */ Display *display; int screen; Drawable drawable; GC gc; int depth; x11osd *xoverlay; void *user_data; void (*lock_display) (void *user_data); void (*unlock_display) (void *user_data); #endif int ovl_changed; /* screen size */ int screen_width; int screen_height; /* size / aspect ratio calculations */ vo_scale_t sc; /* gui callbacks */ alphablend_t alphablend_extra_data; } directfb_driver_t; typedef struct { video_driver_class_t driver_class; int visual_type; xine_t *xine; } directfb_class_t; #define DEFAULT_COLORKEY 0x202040 #define DIRECTFB_OPTIONS "no-banner,"\ "bg-colour=00000000,"\ "no-vt-switch,"\ "no-vt-switching,"\ "no-sighandler,"\ "no-deinit-check,"\ "disable-module=linux_input,"\ "disable-module=keyboard" #define XDIRECTFB_OPTIONS "no-banner,"\ "no-sighandler,"\ "no-deinit-check" #define YCBCR_TO_RGB( y, cb, cr, r, g, b ) \ do { \ int _y, _cb, _cr, _r, _g, _b; \ _y = ((y) - 16) * 76309; \ _cb = (cb) - 128; \ _cr = (cr) - 128; \ _r = (_y + _cr * 104597 + 0x8000) >> 16; \ _g = (_y - _cb * 25675 - _cr * 53279 + 0x8000) >> 16; \ _b = (_y + _cb * 132201 + 0x8000) >> 16; \ (r) = (_r < 0) ? 0 : ((_r > 255) ? 255 : _r); \ (g) = (_g < 0) ? 0 : ((_g > 255) ? 255 : _g); \ (b) = (_b < 0) ? 0 : ((_b > 255) ? 255 : _b); \ } while (0) #define LOCK_DISPLAY() \ do { \ if (this->lock_display) \ this->lock_display (this->user_data); \ else \ XLockDisplay (this->display); \ } while (0) #define UNLOCK_DISPLAY() \ do { \ if (this->unlock_display) \ this->unlock_display (this->user_data); \ else \ XUnlockDisplay (this->display); \ } while (0) /*** driver functions ***/ static uint32_t directfb_get_capabilities (vo_driver_t *this_gen) { directfb_driver_t *this = (directfb_driver_t *) this_gen; return this->capabilities; } static void directfb_frame_field (vo_frame_t *vo_img, int which_field) { /* not needed */ (void)vo_img; (void)which_field; } static void directfb_frame_dispose (vo_frame_t *vo_img) { directfb_frame_t *frame = (directfb_frame_t *) vo_img; if (frame) { if (frame->surface) { if (frame->locked) frame->surface->Unlock (frame->surface); frame->surface->Release (frame->surface); } free (frame); } } static vo_frame_t *directfb_alloc_frame (vo_driver_t *this_gen) { directfb_driver_t *this = (directfb_driver_t *) this_gen; directfb_frame_t *frame; frame = (directfb_frame_t *) calloc(1, sizeof(directfb_frame_t)); if (!frame) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: directfb_alloc_frame: out of memory\n"); return NULL; } pthread_mutex_init (&frame->vo_frame.mutex, NULL); frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = directfb_frame_field; frame->vo_frame.dispose = directfb_frame_dispose; frame->vo_frame.driver = this_gen; return &frame->vo_frame; } static void directfb_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int fmt, int flags) { directfb_driver_t *this = (directfb_driver_t *) this_gen; directfb_frame_t *frame = (directfb_frame_t *) frame_gen; DFBSurfacePixelFormat format = (fmt == XINE_IMGFMT_YUY2) ? DSPF_YUY2 : DSPF_YV12; (void)flags; if (frame->surface == NULL || frame->width != (int)width || frame->height != (int)height || frame->format != format) { DFBSurfaceDescription dsc; DFBResult ret; lprintf ("frame %p: format changed to %dx%d %s.\n", (void*)frame, width, height, (format == DSPF_YUY2) ? "YUY2" : "YV12"); if (frame->surface) { if (frame->locked) frame->surface->Unlock (frame->surface); frame->surface->Release (frame->surface); frame->surface = NULL; frame->locked = 0; } dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; dsc.caps = DSCAPS_SYSTEMONLY | DSCAPS_INTERLACED; dsc.width = (width + 7) & ~7; dsc.height = (height + 1) & ~1; dsc.pixelformat = format; ret = this->dfb->CreateSurface (this->dfb, &dsc, &frame->surface); if (ret != DFB_OK) { DirectFBError ("IDirectFB::CreateSurface()", ret); return; } frame->width = width; frame->height = height; frame->format = format; ret = frame->surface->Lock (frame->surface, DSLF_READ | DSLF_WRITE, (void**)&frame->vo_frame.base[0], (int *)&frame->vo_frame.pitches[0]); if (ret != DFB_OK) { DirectFBError ("IDirectFBSurface::Lock()", ret); return; } frame->locked = 1; if (frame->format == DSPF_YV12) { frame->vo_frame.pitches[1] = frame->vo_frame.pitches[0]/2; frame->vo_frame.pitches[2] = frame->vo_frame.pitches[0]/2; frame->vo_frame.base[2] = frame->vo_frame.base[0] + dsc.height * frame->vo_frame.pitches[0]; frame->vo_frame.base[1] = frame->vo_frame.base[2] + dsc.height/2 * frame->vo_frame.pitches[2]; } } frame->ratio = ratio; } #ifdef DIRECTFB_X11 static uint32_t directfb_colorkey_to_pixel (directfb_driver_t *this) { switch (this->depth) { case 8: return ((this->colorkey & 0xe00000) >> 16) | ((this->colorkey & 0x00e000) >> 11) | ((this->colorkey & 0x0000c0) >> 6); case 15: return ((this->colorkey & 0xf80000) >> 9) | ((this->colorkey & 0x00f800) >> 6) | ((this->colorkey & 0x0000f8) >> 3); case 16: return ((this->colorkey & 0xf80000) >> 8) | ((this->colorkey & 0x00fc00) >> 5) | ((this->colorkey & 0x0000f8) >> 3); default: break; } return this->colorkey; } #endif static void directfb_clean_output_area (directfb_driver_t *this) { if (this->visual_type == XINE_VISUAL_TYPE_X11 || this->visual_type == XINE_VISUAL_TYPE_X11_2) { #ifdef DIRECTFB_X11 if (this->config.options & DLOP_DST_COLORKEY) { int i; LOCK_DISPLAY(); XSetForeground (this->display, this->gc, BlackPixel(this->display, this->screen)); for (i = 0; i < 4; i++) { if (this->sc.border[i].w && this->sc.border[i].h) { XFillRectangle (this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } } XSetForeground (this->display, this->gc, directfb_colorkey_to_pixel(this)); XFillRectangle (this->display, this->drawable, this->gc, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); if (this->xoverlay) { x11osd_resize (this->xoverlay, this->sc.gui_width, this->sc.gui_height); this->ovl_changed = 1; } XFlush (this->display); UNLOCK_DISPLAY(); } #endif } else if (!(this->caps & DLCAPS_SCREEN_LOCATION)) { DFBRectangle rect[4]; DFBSurfaceCapabilities caps; int bufs = 1; int i; for (i = 0; i < 4; i++) { rect[i].x = MAX(this->sc.border[i].x, 0); rect[i].y = MAX(this->sc.border[i].y, 0); rect[i].w = MAX(this->sc.border[i].w, 0); rect[i].h = MAX(this->sc.border[i].h, 0); } this->surface->GetCapabilities (this->surface, &caps); if (caps & DSCAPS_DOUBLE) bufs++; if (caps & DSCAPS_TRIPLE) bufs++; this->surface->SetColor (this->surface, 0x00, 0x00, 0x00, 0xff); for (i = 0; i < bufs; i++) { this->surface->FillRectangles (this->surface, &rect[0], 4); this->surface->Flip (this->surface, NULL, 0); } } } static void directfb_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { directfb_driver_t *this = (directfb_driver_t *) this_gen; this->ovl_changed += changed; if (this->ovl_changed) { #ifdef DIRECTFB_X11 if (this->xoverlay) { LOCK_DISPLAY(); x11osd_clear (this->xoverlay); UNLOCK_DISPLAY(); } #endif if (this->spic_surface) { lprintf ("clearing subpicture.\n"); this->spic_surface->SetClip (this->spic_surface, NULL); this->spic_surface->Clear (this->spic_surface, 0, 0, 0, 0); } } this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void directfb_subpicture_paint (directfb_driver_t *this, vo_overlay_t *overlay) { #define MAX_RECTS 100 DFBRegion clip; DFBRectangle rects[MAX_RECTS]; int n_rects = 0; DFBColor colors[OVL_PALETTE_SIZE*2]; int p_index = -1; int xoffset; int yoffset; int x, y, i; memset (colors, 0, sizeof(colors)); xoffset = this->sc.gui_win_x+overlay->x; yoffset = this->sc.gui_win_y+overlay->y; clip.x1 = xoffset; clip.y1 = yoffset; clip.x2 = xoffset + overlay->width - 1; clip.y2 = yoffset + overlay->height - 1; this->spic_surface->SetClip (this->spic_surface, &clip); for (x = 0, y= 0, i = 0; i < overlay->num_rle; i++) { int idx = overlay->rle[i].color; int len = overlay->rle[i].len; while (len > 0) { clut_t color = ((clut_t *)overlay->color)[idx]; uint8_t alpha = overlay->trans[idx]; int index = idx; int width; if ((len+x) > overlay->width) { width = overlay->width - x; len -= width; } else { width = len; len = 0; } if ((y >= overlay->hili_top) && (y <= overlay->hili_bottom) && (x <= overlay->hili_right)) { if ((x < overlay->hili_left) && (x+width-1 >= overlay->hili_left)) { width -= overlay->hili_left - x; len += overlay->hili_left - x; } else if (x > overlay->hili_left) { color = ((clut_t *)overlay->hili_color)[idx]; alpha = overlay->hili_trans[idx]; index += OVL_PALETTE_SIZE; if (x+width-1 > overlay->hili_right) { width -= overlay->hili_right - x; len += overlay->hili_right - x; } } } if (alpha) { if (n_rects == MAX_RECTS || (p_index != -1 && p_index != index)) { lprintf ("flushing %d rect(s).\n", n_rects); this->spic_surface->FillRectangles (this->spic_surface, rects, n_rects); n_rects = 0; } if (p_index != index) { if (!colors[index].a) { YCBCR_TO_RGB (color.y, color.cb, color.cr, colors[index].r, colors[index].g, colors[index].b); colors[index].a = alpha | (alpha << 4); } lprintf ("colour change to %02x%02x%02x%02x.\n", colors[index].a, colors[index].r, colors[index].g, colors[index].b); this->spic_surface->SetColor (this->spic_surface, colors[index].r, colors[index].g, colors[index].b, colors[index].a); p_index = index; } rects[n_rects].x = x + xoffset; rects[n_rects].y = y + yoffset; rects[n_rects].w = width; rects[n_rects].h = 1; if (n_rects) { if (rects[n_rects-1].x == rects[n_rects].x && rects[n_rects-1].w == rects[n_rects].w && rects[n_rects-1].y+rects[n_rects-1].h == rects[n_rects].y) { n_rects--; rects[n_rects].h++; } } n_rects++; } x += width; if (x == overlay->width) { if (++y == overlay->height) break; x = 0; } } } if (n_rects) { lprintf ("flushing %d remaining rect(s).\n", n_rects); this->spic_surface->FillRectangles (this->spic_surface, rects, n_rects); } } static void directfb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { directfb_driver_t *this = (directfb_driver_t *) this_gen; directfb_frame_t *frame = (directfb_frame_t *) frame_gen; if (!overlay->rle) return; if (overlay->unscaled) { if (!this->ovl_changed) return; #ifdef DIRECTFB_X11 if (this->xoverlay) { LOCK_DISPLAY(); x11osd_blend (this->xoverlay, overlay); UNLOCK_DISPLAY(); } #endif if (this->spic_surface) { lprintf ("repainting subpicture.\n"); directfb_subpicture_paint (this, overlay); } } else { if (frame->format == DSPF_YUY2) { _x_blend_yuy2 (frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } else { _x_blend_yuv (frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); } } } static void directfb_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen) { directfb_driver_t *this = (directfb_driver_t *) this_gen; (void)frame_gen; if (this->ovl_changed) { #ifdef DIRECTFB_X11 if (this->xoverlay) { LOCK_DISPLAY(); x11osd_expose (this->xoverlay); UNLOCK_DISPLAY(); } #endif if (this->spic_surface) { lprintf ("flipping subpicture.\n"); this->spic_surface->SetClip (this->spic_surface, NULL); this->spic_surface->Flip (this->spic_surface, NULL, 0); } this->ovl_changed = 0; } } static int directfb_redraw_needed (vo_driver_t *this_gen) { directfb_driver_t *this = (directfb_driver_t *) this_gen; directfb_frame_t *frame = this->cur_frame; if (!frame) return 1; this->sc.delivered_width = frame->width; this->sc.delivered_height = frame->height; this->sc.delivered_ratio = frame->ratio; this->sc.crop_left = frame->vo_frame.crop_left; this->sc.crop_right = frame->vo_frame.crop_right; this->sc.crop_top = frame->vo_frame.crop_top; this->sc.crop_bottom = frame->vo_frame.crop_bottom; _x_vo_scale_compute_ideal_size (&this->sc); if (_x_vo_scale_redraw_needed (&this->sc)) { lprintf ("redraw needed.\n"); _x_vo_scale_compute_output_size (&this->sc); if (this->caps & DLCAPS_SCREEN_LOCATION) { this->layer->SetSourceRectangle (this->layer, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height ); this->layer->SetScreenRectangle (this->layer, this->sc.gui_win_x+this->sc.output_xoffset, this->sc.gui_win_y+this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } directfb_clean_output_area (this); return 1; } return 0; } /* directfb_display_frame(): output to overlay */ static void directfb_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { directfb_driver_t *this = (directfb_driver_t *) this_gen; directfb_frame_t *frame = (directfb_frame_t *) frame_gen; if (this->cur_frame) this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); this->cur_frame = frame; this->config.flags = DLCONF_NONE; if (frame->width != this->config.width) { this->config.flags |= DLCONF_WIDTH; this->config.width = frame->width; } if (frame->height != this->config.height) { this->config.flags |= DLCONF_HEIGHT; this->config.height = frame->height; } if (this->type & DLTF_VIDEO) { if (frame->format != this->config.pixelformat) { this->config.flags |= DLCONF_PIXELFORMAT; this->config.pixelformat = frame->format; } } if (this->caps & DLCAPS_DEINTERLACING) { if (this->deinterlace && !(this->config.options & DLOP_DEINTERLACING)) { this->config.flags |= DLCONF_OPTIONS; this->config.options |= DLOP_DEINTERLACING; } else if (!this->deinterlace && (this->config.options & DLOP_DEINTERLACING)) { this->config.flags |= DLCONF_OPTIONS; this->config.options &= ~DLOP_DEINTERLACING; } } if (this->config.flags) { DFBDisplayLayerConfigFlags failed = 0; lprintf ("changing layer configuration to %dx%d %s.\n", this->config.width, this->config.height, (this->config.pixelformat == DSPF_YUY2) ? "YUY2" : "YV12"); this->layer->TestConfiguration (this->layer, &this->config, &failed); this->config.flags &= ~failed; if (this->config.flags) { this->layer->SetConfiguration (this->layer, &this->config); this->layer->GetConfiguration (this->layer, &this->config); this->surface->Release (this->surface); this->layer->GetSurface (this->layer, &this->surface); } lprintf ("failed=0x%08x.\n", failed); } if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) || (frame->vo_frame.crop_left != this->sc.crop_left) || (frame->vo_frame.crop_right != this->sc.crop_right) || (frame->vo_frame.crop_top != this->sc.crop_top) || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) { lprintf ("forcing redraw.\n"); this->sc.force_redraw = 1; } directfb_redraw_needed (&this->vo_driver); if (!this->visible) { this->layer->SetOpacity (this->layer, 0xff); this->visible = 1; } if (frame->locked) { frame->surface->Unlock (frame->surface); frame->locked = 0; } if (this->deinterlace) { if (!(this->config.options & DLOP_DEINTERLACING)) { frame->surface->SetField (frame->surface, frame->vo_frame.top_field_first ? 0 : 1); this->surface->SetBlittingFlags (this->surface, DSBLIT_DEINTERLACE); } else { this->surface->SetField (this->surface, frame->vo_frame.top_field_first ? 0 : 1); } } else { this->surface->SetBlittingFlags (this->surface, DSBLIT_NOFX); } this->surface->Blit (this->surface, frame->surface, NULL, 0, 0); this->surface->Flip (this->surface, NULL, (this->vsync) ? DSFLIP_WAITFORSYNC : DSFLIP_ONSYNC); frame->surface->Lock (frame->surface, DSLF_READ | DSLF_WRITE, (void**)&frame->vo_frame.base[0], (int *)&frame->vo_frame.pitches[0]); frame->locked = 1; } #ifndef DIRECTFB_X11 /* directfb_display_frame2(): output to underlay */ static void directfb_display_frame2 (vo_driver_t *this_gen, vo_frame_t *frame_gen) { directfb_driver_t *this = (directfb_driver_t *) this_gen; directfb_frame_t *frame = (directfb_frame_t *) frame_gen; DFBSurfaceBlittingFlags flags; DFBRectangle s, d; DFBResult ret; if (this->cur_frame) this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); this->cur_frame = frame; /* TODO: try to change video mode when frame size changes */ if (this->type & DLTF_VIDEO) { if (frame->format != this->config.pixelformat) { this->config.flags = DLCONF_PIXELFORMAT; this->config.pixelformat = frame->format; lprintf ("changing layer pixelformat to %s.\n", (this->config.pixelformat == DSPF_YUY2) ? "YUY2" : "YV12"); ret = this->layer->SetConfiguration (this->layer, &this->config); this->layer->GetConfiguration (this->layer, &this->config); lprintf ("%s.\n", ret ? "failed" : "ok"); } } if (this->temp) { /* try to reduce video memory fragmentation */ if (this->temp_frame_width < frame->width || this->temp_frame_height < frame->height || this->temp_frame_format != this->config.pixelformat) { DFBSurfaceDescription dsc; lprintf ("reallocating temporary surface.\n"); this->temp->Release (this->temp); this->temp = NULL; dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; dsc.caps = DSCAPS_INTERLACED; dsc.width = frame->width; dsc.height = frame->height; dsc.pixelformat = this->config.pixelformat; ret = this->dfb->CreateSurface (this->dfb, &dsc, &this->temp); if (ret != DFB_OK) DirectFBError ("IDirectFB::CreateSurface()", ret); this->temp_frame_width = frame->width; this->temp_frame_height = frame->height; this->temp_frame_format = this->config.pixelformat; } } if (this->sc.delivered_width != frame->width || this->sc.delivered_height != frame->height || this->sc.delivered_ratio != frame->ratio) { lprintf ("forcing redraw.\n"); this->sc.force_redraw = 1; } directfb_redraw_needed (&this->vo_driver); if (!this->visible) { this->layer->SetOpacity (this->layer, 0xff); this->visible = 1; } if (frame->locked) { frame->surface->Unlock (frame->surface); frame->locked = 0; } /* source rectangle */ s.x = this->sc.displayed_xoffset; s.y = this->sc.displayed_yoffset; s.w = this->sc.displayed_width; s.h = this->sc.displayed_height; /* destination rectangle */ d.x = this->sc.gui_win_x+this->sc.output_xoffset; d.y = this->sc.gui_win_y+this->sc.output_yoffset; d.w = this->sc.output_width; d.h = this->sc.output_height; flags = (this->deinterlace) ? DSBLIT_DEINTERLACE : DSBLIT_NOFX; if (this->temp) { if (this->hw_deinterlace) { this->temp->SetField (this->temp, frame->vo_frame.top_field_first ? 0 : 1); this->surface->SetBlittingFlags (this->surface, flags); } else { frame->surface->SetField (frame->surface, frame->vo_frame.top_field_first ? 0 : 1); this->temp->SetBlittingFlags (this->temp, flags); } this->temp->Blit (this->temp, frame->surface, &s, 0, 0); s.x = 0; s.y = 0; this->surface->StretchBlit (this->surface, this->temp, &s, &d); } else { frame->surface->SetField (frame->surface, frame->vo_frame.top_field_first ? 0 : 1); this->surface->SetBlittingFlags (this->surface, flags); this->surface->StretchBlit (this->surface, frame->surface, &s, &d); } this->surface->Flip (this->surface, NULL, (this->vsync) ? DSFLIP_WAITFORSYNC : DSFLIP_ONSYNC); frame->surface->Lock (frame->surface, DSLF_READ | DSLF_WRITE, (void**)&frame->vo_frame.base[0], (int *)&frame->vo_frame.pitches[0]); frame->locked = 1; } #endif static int directfb_get_property (vo_driver_t *this_gen, int property) { directfb_driver_t *this = (directfb_driver_t *) this_gen; switch (property) { case VO_PROP_INTERLACED: return this->deinterlace; case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; case VO_PROP_HUE: if (this->caps & DLCAPS_HUE) return this->cadj.hue; break; case VO_PROP_SATURATION: if (this->caps & DLCAPS_SATURATION) return this->cadj.saturation; break; case VO_PROP_CONTRAST: if (this->caps & DLCAPS_CONTRAST) return this->cadj.contrast; break; case VO_PROP_BRIGHTNESS: if (this->caps & DLCAPS_BRIGHTNESS) return this->cadj.brightness; break; case VO_PROP_COLORKEY: if (this->caps & DLCAPS_DST_COLORKEY) return this->colorkey; break; case VO_PROP_ZOOM_X: return this->sc.zoom_factor_x * XINE_VO_ZOOM_STEP; case VO_PROP_ZOOM_Y: return this->sc.zoom_factor_y * XINE_VO_ZOOM_STEP; case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; case VO_PROP_MAX_NUM_FRAMES: return (this->type & DLTF_VIDEO) ? 8 : 15; default: break; } return 0; } static int directfb_set_property (vo_driver_t *this_gen, int property, int value) { directfb_driver_t *this = (directfb_driver_t *) this_gen; switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) { value = 0; if (this->cur_frame) { this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); this->cur_frame = NULL; value = 1; } } break; case VO_PROP_INTERLACED: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: deinterlacing set to %d.\n", value); this->deinterlace = value; break; case VO_PROP_ASPECT_RATIO: if (value >= XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_NUM_RATIOS-1; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: aspect ratio changed to %s.\n", _x_vo_scale_aspect_ratio_name_table[value]); this->sc.user_ratio = value; _x_vo_scale_compute_ideal_size (&this->sc); this->sc.force_redraw = 1; break; case VO_PROP_HUE: if (this->caps & DLCAPS_HUE) { if (value > 0xffff) value = 0xffff; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: setting hue to %d.\n", value); this->cadj.flags = DCAF_HUE; this->cadj.hue = value; this->layer->SetColorAdjustment (this->layer, &this->cadj); } break; case VO_PROP_SATURATION: if (this->caps & DLCAPS_SATURATION) { if (value > 0xffff) value = 0xffff; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: setting saturation to %d.\n", value); this->cadj.flags = DCAF_SATURATION; this->cadj.saturation = value; this->layer->SetColorAdjustment (this->layer, &this->cadj); } break; case VO_PROP_CONTRAST: if (this->caps & DLCAPS_CONTRAST) { if (value > 0xffff) value = 0xffff; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: setting contrast to %d.\n", value); this->cadj.flags = DCAF_CONTRAST; this->cadj.contrast = value; this->layer->SetColorAdjustment (this->layer, &this->cadj); } break; case VO_PROP_BRIGHTNESS: if (this->caps & DLCAPS_BRIGHTNESS) { if (value > 0xffff) value = 0xffff; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: setting brightness to %d.\n", value); this->cadj.flags = DCAF_BRIGHTNESS; this->cadj.brightness = value; this->layer->SetColorAdjustment (this->layer, &this->cadj); } break; case VO_PROP_COLORKEY: if (this->caps & DLCAPS_DST_COLORKEY) { if (value > 0xffffff) value = 0xffffff; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: setting colour key to 0x%06x.\n", value); this->colorkey = value; this->layer->SetDstColorKey (this->layer, (value & 0xff0000) >> 16, (value & 0x00ff00) >> 8, (value & 0x0000ff) >> 0); directfb_clean_output_area (this); } break; case VO_PROP_ZOOM_X: if (value >= XINE_VO_ZOOM_MIN && value <= XINE_VO_ZOOM_MAX) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: Zoom X by factor %d.\n", value); this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size (&this->sc); this->sc.force_redraw = 1; } break; case VO_PROP_ZOOM_Y: if (value >= XINE_VO_ZOOM_MIN && value <= XINE_VO_ZOOM_MAX) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: Zoom Y by factor %d.\n", value); this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size (&this->sc); this->sc.force_redraw = 1; } break; default: break; } return value; } static void directfb_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { directfb_driver_t *this = (directfb_driver_t *) this_gen; switch (property) { case VO_PROP_INTERLACED: *min = 0; *max = 1; return; case VO_PROP_ASPECT_RATIO: *min = 0; *max = XINE_VO_ASPECT_NUM_RATIOS-1; return; case VO_PROP_HUE: if (this->caps & DLCAPS_HUE) { *min = 0x0000; *max = 0xffff; return; } break; case VO_PROP_SATURATION: if (this->caps & DLCAPS_SATURATION) { *min = 0x0000; *max = 0xffff; return; } break; case VO_PROP_CONTRAST: if (this->caps & DLCAPS_CONTRAST) { *min = 0x0000; *max = 0xffff; return; } break; case VO_PROP_BRIGHTNESS: if (this->caps & DLCAPS_BRIGHTNESS) { *min = 0x0000; *max = 0xffff; return; } break; case VO_PROP_COLORKEY: if (this->caps & DLCAPS_DST_COLORKEY) { *min = 0x000000; *max = 0xffffff; return; } break; case VO_PROP_ZOOM_X: case VO_PROP_ZOOM_Y: *min = XINE_VO_ZOOM_MIN; *max = XINE_VO_ZOOM_MAX; return; default: break; } *min = 0; *max = 0; } static int directfb_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { directfb_driver_t *this = (directfb_driver_t *) this_gen; switch (data_type) { case XINE_GUI_SEND_DRAWABLE_CHANGED: lprintf ("drawable changed.\n"); #ifdef DIRECTFB_X11 if (this->visual_type == XINE_VISUAL_TYPE_X11 || this->visual_type == XINE_VISUAL_TYPE_X11_2) { this->drawable = (Drawable) data; LOCK_DISPLAY(); XFreeGC (this->display, this->gc); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); if (this->xoverlay) { x11osd_drawable_changed (this->xoverlay, this->drawable); this->ovl_changed = 1; } UNLOCK_DISPLAY(); this->sc.force_redraw = 1; } #endif directfb_clean_output_area (this); break; case XINE_GUI_SEND_EXPOSE_EVENT: lprintf ("expose event.\n"); #ifdef DIRECTFB_X11 if (this->visual_type == XINE_VISUAL_TYPE_X11 || this->visual_type == XINE_VISUAL_TYPE_X11_2) { if (this->xoverlay) { LOCK_DISPLAY(); x11osd_expose (this->xoverlay); UNLOCK_DISPLAY(); } } #endif directfb_clean_output_area (this); break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video (&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video (&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void directfb_dispose (vo_driver_t *this_gen) { directfb_driver_t *this = (directfb_driver_t *) this_gen; _x_vo_scale_cleanup (&this->sc, this->xine->config); if (this->cur_frame) this->cur_frame->vo_frame.dispose (&this->cur_frame->vo_frame); #ifdef DIRECTFB_X11 if (this->visual_type == XINE_VISUAL_TYPE_X11 || this->visual_type == XINE_VISUAL_TYPE_X11_2) { LOCK_DISPLAY(); if (this->xoverlay) x11osd_destroy (this->xoverlay); XFreeGC (this->display, this->gc); UNLOCK_DISPLAY(); } #endif if (this->temp) this->temp->Release (this->temp); if (this->spic_surface) this->spic_surface->Release (this->spic_surface); if (this->spic_layer) this->spic_layer->Release (this->spic_layer); if (this->surface) this->surface->Release (this->surface); if (this->layer) { this->layer->SetColorAdjustment (this->layer, &this->default_cadj); this->layer->SetLevel (this->layer, this->default_level); this->layer->Release (this->layer); } if (this->underlay) this->underlay->Release (this->underlay); if (this->dfb) this->dfb->Release (this->dfb); _x_alphablend_free (&this->alphablend_extra_data); free (this); } /*** misc functions ****/ static void update_config_cb (void *data, xine_cfg_entry_t *entry) { directfb_driver_t *this = (directfb_driver_t *) data; lprintf ("update_config_cb(%s).\n", entry->key); if (strcmp (entry->key, "video.device.directfb_buffermode") == 0) { DFBDisplayLayerConfig config = { .flags = DLCONF_BUFFERMODE }; switch (entry->num_value) { case 0: config.buffermode = DLBM_FRONTONLY; break; case 2: config.buffermode = DLBM_TRIPLE; break; default: config.buffermode = DLBM_BACKVIDEO; break; } if (config.buffermode != this->config.buffermode) { if (this->layer->SetConfiguration (this->layer, &config ) != DFB_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_directfb: failed to set buffermode to %d!\n", entry->num_value); return; } this->layer->GetConfiguration (this->layer, &this->config); } } else if (strcmp (entry->key, "video.device.directfb_colorkeying") == 0) { DFBDisplayLayerConfig config = { .flags = DLCONF_OPTIONS }; if (entry->num_value) config.options = this->config.options | DLOP_DST_COLORKEY; else config.options = this->config.options & ~DLOP_DST_COLORKEY; if (config.options != this->config.options) { if (this->layer->SetConfiguration (this->layer, &config) != DFB_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_directfb: failed to set colour keying to %d!\n", entry->num_value); return; } this->layer->GetConfiguration (this->layer, &this->config); directfb_clean_output_area (this); } } else if (strcmp (entry->key, "video.device.directfb_colorkey") == 0) { this->colorkey = entry->num_value; this->layer->SetDstColorKey (this->layer, (this->colorkey & 0xff0000) >> 16, (this->colorkey & 0x00ff00) >> 8, (this->colorkey & 0x0000ff) >> 0); #ifdef DIRECTFB_X11 if (this->xoverlay) { x11osd_colorkey (this->xoverlay, directfb_colorkey_to_pixel(this), &this->sc); } #endif directfb_clean_output_area (this); } else if (strcmp (entry->key, "video.device.directfb_flicker_filtering") == 0) { DFBDisplayLayerConfig config = { .flags = DLCONF_OPTIONS }; if (entry->num_value) config.options = this->config.options | DLOP_FLICKER_FILTERING; else config.options = this->config.options & ~DLOP_FLICKER_FILTERING; if (config.options != this->config.options) { if (this->layer->SetConfiguration (this->layer, &config) != DFB_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_directfb: failed to set flicker_filtering to %d!\n", entry->num_value); return; } this->layer->GetConfiguration (this->layer, &this->config); } } else if (strcmp (entry->key, "video.device.directfb_field_parity") == 0) { DFBDisplayLayerConfig config = { .flags = DLCONF_OPTIONS }; if (entry->num_value) config.options = this->config.options | DLOP_FIELD_PARITY; else config.options = this->config.options & ~DLOP_FIELD_PARITY; if (config.options != this->config.options) { if (this->layer->SetConfiguration (this->layer, &config) != DFB_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_directfb: failed to set field_parity to %d!\n", entry->num_value); return; } this->layer->GetConfiguration (this->layer, &this->config); } } else if (strcmp (entry->key, "video.device.directfb_vsync") == 0) { this->vsync = entry->num_value; } } static void init_config (directfb_driver_t *this) { config_values_t *config = this->xine->config; static const char *const buffermode_enum[] = {"single", "double", "triple", 0}; static const char *const fieldparity_enum[] = {"none", "top", "bottom", 0}; this->buffermode = config->register_enum (config, "video.device.directfb_buffermode", this->buffermode, (char**)buffermode_enum, _("video layer buffering mode"), _("Select the buffering mode of the output layer. " "Double or triple buffering give a smoother playback, " "but consume more video memory."), 10, update_config_cb, (void *)this); this->vsync = config->register_bool (config, "video.device.directfb_vsync", this->vsync, _("wait for vertical retrace"), _("Enable synchronizing the update of the video image to the " "repainting of the entire screen (\"vertical retrace\")."), 10, update_config_cb, (void *)this); if (this->caps & DLCAPS_DST_COLORKEY) { this->colorkeying = config->register_bool (config, "video.device.directfb_colorkeying", this->colorkeying, _("enable video colour key"), _("Enable using a colour key to tell the graphics card " "where to overlay the video image."), 20, update_config_cb, (void *)this); this->colorkey = config->register_range (config, "video.device.directfb_colorkey", this->colorkey, 0, 0xffffff, _("video colour key"), _("The colour key is used to tell the graphics card " "where to overlay the video image. Try different values, " "if you experience windows becoming transparent."), 10, update_config_cb, (void *)this); } if (this->caps & DLCAPS_FLICKER_FILTERING) { this->flicker_filtering = config->register_bool( config, "video.device.directfb_flicker_filtering", this->flicker_filtering, _("flicker filtering"), _("Enable Flicker Filetring for a smooth output on an interlaced display."), 10, update_config_cb, (void *)this); } if (this->caps & DLCAPS_FIELD_PARITY) { this->field_parity = config->register_enum( config, "video.device.directfb_field_parity", this->field_parity, (char**)fieldparity_enum, _("field parity"), _("For an interlaced display, enable controlling " "the field parity (\"none\"=disabled)."), 10, update_config_cb, (void *)this); } } static DFBEnumerationResult find_overlay (DFBDisplayLayerID id, DFBDisplayLayerDescription dsc, void *ctx) { DFBDisplayLayerID *ret_id = (DFBDisplayLayerID *) ctx; if (dsc.type & DLTF_VIDEO && dsc.caps & DLCAPS_SURFACE && dsc.caps & DLCAPS_SCREEN_LOCATION) { lprintf ("overlay's id = %d.\n", id); *ret_id = id; return DFENUM_CANCEL; } return DFENUM_OK; } static DFBEnumerationResult find_underlay (DFBDisplayLayerID id, DFBDisplayLayerDescription dsc, void *ctx) { DFBDisplayLayerID *ret_id = (DFBDisplayLayerID *) ctx; if (dsc.caps & DLCAPS_SURFACE) { lprintf ("underlay's id = %d.\n", id); *ret_id = id; return DFENUM_CANCEL; } return DFENUM_OK; } #if 0 static DFBEnumerationResult find_subpicture (DFBDisplayLayerID id, DFBDisplayLayerDescription dsc, void *ctx) { DFBDisplayLayerID *ret_id = (DFBDisplayLayerID *) ctx; if (id != DLID_PRIMARY && dsc.caps & DLCAPS_SURFACE && dsc.caps & DLCAPS_ALPHACHANNEL) { lprintf ("subpicture's id = %d.\n", id); *ret_id = id; return DFENUM_CANCEL; } return DFENUM_OK; } #endif #ifndef DIRECTFB_X11 static void init_subpicture (directfb_driver_t *this) { DFBResult ret; /* subpicture layer supported by Unichrome and Radeon */ if (this->caps & DLCAPS_LEVELS && this->underlay) { DFBDisplayLayerDescription dsc; this->underlay->GetDescription (this->underlay, &dsc); if (dsc.caps & DLCAPS_ALPHACHANNEL) { DFBDisplayLayerConfig config; /* enable alphachannel on the underlay */ config.flags = DLCONF_PIXELFORMAT | DLCONF_OPTIONS; config.pixelformat = DSPF_ARGB; config.options = DLOP_ALPHACHANNEL; ret = this->underlay->SetConfiguration (this->underlay, &config); if (ret) { /* try AiRGB if the previous failed */ config.pixelformat = DSPF_AiRGB; ret = this->underlay->SetConfiguration (this->underlay, &config); } if (ret == DFB_OK) { this->underlay->AddRef (this->underlay); this->spic_layer = this->underlay; /* put overlay under underlay */ this->layer->SetLevel (this->layer, -1); } } } #if 0 /* most common type of supicture layer */ if (!this->spic_layer) { IDirectFBScreen *screen; DFBDisplayLayerID video_id, id = -1; this->layer->GetID (this->layer, &video_id); if (this->layer->GetScreen (this->layer, &screen) == DFB_OK) { screen->EnumDisplayLayers (screen, find_subpicture, (void *)&id); screen->Release (screen); } if (id != -1 && id != video_id) { ret = this->dfb->GetDisplayLayer (this->dfb, id, &this->spic_layer); if (ret == DFB_OK) { DFBDisplayLayerConfig config; this->spic_layer->GetConfiguration (this->spic_layer, &config); config.flags = DLCONF_OPTIONS; config.options = DLOP_ALPHACHANNEL; if (!DFB_PIXELFORMAT_HAS_ALPHA(config.pixelformat)) { config.flags |= DLCONF_PIXELFORMAT; config.pixelformat = DSPF_ALUT44; } ret = this->spic_layer->SetConfiguration (this->spic_layer, &config); if (ret) { lprintf ("failed to set subpicture layer configuration!\n"); this->spic_layer->Release (this->spic_layer); this->spic_layer = NULL; } } else { DirectFBError ("IDirectFB::GetDisplayLayer()", ret); } } } #endif if (this->spic_layer) { ret = this->spic_layer->GetSurface (this->spic_layer, &this->spic_surface); if (ret) { DirectFBError ("IDirectFBDisplayLayer::GetSurface()", ret); this->spic_layer->Release (this->spic_layer); this->spic_layer = NULL; return; } this->spic_surface->Clear (this->spic_surface, 0, 0, 0, 0); this->spic_surface->Flip (this->spic_surface, NULL, 0); xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: using hardware subpicture acceleration.\n")); } } #endif static DFBResult init_device (directfb_driver_t *this) { IDirectFBSurface *surface; DFBDisplayLayerConfig config; DFBDisplayLayerConfigFlags failed = 0; DFBResult ret; config.flags = DLCONF_NONE; if (this->type & DLTF_VIDEO) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: layer supports video output.\n")); config.flags |= DLCONF_PIXELFORMAT; /* test for YV12 support */ config.pixelformat = DSPF_YV12; ret = this->layer->TestConfiguration (this->layer, &config, NULL); if (ret) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: layer doesn't support YV12!\n")); /* test for YUY2 support */ config.pixelformat = DSPF_YUY2; ret = this->layer->TestConfiguration (this->layer, &config, NULL); if (ret) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: layer doesn't support YUY2!\n")); /* layer supports video output but none of the formats we need */ this->type &= ~DLTF_VIDEO; config.flags &= ~DLCONF_PIXELFORMAT; } } } #if DIRECTFB_VERSION_CODE < VERSION_CODE(0,9,25) if (!(this->type & DLTF_VIDEO)) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb:" "need at least DirectFB 0.9.25 to play on this layer!\n")); return DFB_UNSUPPORTED; } #endif /* set layer configuration */ config.flags |= DLCONF_BUFFERMODE | DLCONF_OPTIONS; config.options = DLOP_NONE; switch (this->buffermode) { case 0: config.buffermode = DLBM_FRONTONLY; break; case 2: config.buffermode = DLBM_TRIPLE; break; default: config.buffermode = DLBM_BACKVIDEO; break; } if (this->colorkeying) config.options |= DLOP_DST_COLORKEY; if (this->flicker_filtering) config.options |= DLOP_FLICKER_FILTERING; if (this->field_parity) config.options |= DLOP_FIELD_PARITY; /* test current configuration */ ret = this->layer->TestConfiguration (this->layer, &config, &failed); if (failed & DLCONF_BUFFERMODE) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: layer doesn't support buffermode %d!\n"), this->buffermode); config.flags &= ~DLCONF_BUFFERMODE; } if (failed & DLCONF_OPTIONS) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: layer doesn't support options 0x%08x!\n"), config.options); config.flags &= ~DLCONF_OPTIONS; } ret = this->layer->SetConfiguration (this->layer, &config); /* this should never happen */ if (ret) { DirectFBError ("IDirectFBDisplayLayer::SetConfiguration()", ret); return ret; } this->layer->GetConfiguration (this->layer, &this->config); if (this->caps & DLCAPS_DST_COLORKEY) { this->layer->SetDstColorKey (this->layer, (this->colorkey & 0xff0000) >> 16, (this->colorkey & 0x00ff00) >> 8, (this->colorkey & 0x0000ff) >> 0); } if (this->field_parity) this->layer->SetFieldParity (this->layer, this->field_parity-1); /* get current color cadjustment */ this->layer->GetColorAdjustment (this->layer, &this->default_cadj); this->cadj = this->default_cadj; /* get current level */ this->layer->GetLevel (this->layer, &this->default_level); /* retrieve layer's surface */ ret = this->layer->GetSurface (this->layer, &surface); if (ret != DFB_OK) { DirectFBError ("IDirectFBDisplayLayer::GetSurface()", ret); return ret; } /* clear surface buffers */ surface->Clear (surface, 0x00, 0x00, 0x00, 0xff); surface->Flip (surface, NULL, 0); surface->Clear (surface, 0x00, 0x00, 0x00, 0xff); surface->Flip (surface, NULL, 0); surface->Clear (surface, 0x00, 0x00, 0x00, 0xff); surface->Flip (surface, NULL, 0); this->surface = surface; if (this->caps & DLCAPS_SCREEN_LOCATION) { IDirectFBScreen *screen = NULL; DFBDisplayLayerID id = -1; this->screen_width = 640; this->screen_height = 480; this->layer->GetScreen (this->layer, &screen); if (screen) { screen->EnumDisplayLayers (screen, find_underlay, (void *)&id); screen->Release (screen); } this->dfb->GetDisplayLayer (this->dfb, id, &this->underlay); if (this->underlay) { this->underlay->GetConfiguration (this->underlay, &config); this->screen_width = config.width; this->screen_height = config.height; if (this->visual_type == XINE_VISUAL_TYPE_FB) { this->underlay->SetCooperativeLevel (this->underlay, DLSCL_EXCLUSIVE); this->underlay->SetConfiguration (this->underlay, &config); } } } else { /* playing to underlay, * check whether stretchblit is hardware accelerated. */ IDirectFBSurface *temp; DFBSurfaceDescription dsc; DFBAccelerationMask mask = DFXL_NONE; this->layer->AddRef (this->layer); this->underlay = this->layer; dsc.flags = DSDESC_CAPS | DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT; dsc.caps = DSCAPS_INTERLACED; dsc.width = 320; dsc.height = 240; dsc.pixelformat = this->config.pixelformat; if (this->dfb->CreateSurface (this->dfb, &dsc, &temp) == DFB_OK) { this->surface->GetAccelerationMask (this->surface, temp, &mask); if (mask & DFXL_STRETCHBLIT) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: " "using hardware accelerated image scaling.\n")); this->temp = temp; /* check if stretchblit with deinterlacing is supported */ this->surface->SetBlittingFlags (this->surface, DSBLIT_DEINTERLACE); this->surface->GetAccelerationMask (this->surface, temp, &mask); this->surface->SetBlittingFlags (this->surface, DSBLIT_NOFX); this->hw_deinterlace = (mask & DFXL_STRETCHBLIT) ? 1 : 0; if (this->hw_deinterlace) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: " "image scaling with deinterlacing is hardware accelerated.\n")); } /* used to decide reallocation */ temp->GetSize (temp, &this->temp_frame_width, &this->temp_frame_height); temp->GetPixelFormat (temp, &this->temp_frame_format); } else temp->Release (temp); } this->screen_width = this->config.width; this->screen_height = this->config.height; } xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: screen size is %dx%d.\n", this->screen_width, this->screen_height); return DFB_OK; } #ifndef DIRECTFB_X11 static void directfb_frame_output_cb (void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y) { directfb_driver_t *this = (directfb_driver_t *) user_data; (void)video_width; (void)video_height; *dest_x = 0; *dest_y = 0; *dest_width = this->screen_width; *dest_height = this->screen_height; *dest_pixel_aspect = (video_pixel_aspect > 0.01) ? video_pixel_aspect : (double)this->screen_width/(double)this->screen_height; *win_x = 0; *win_y = 0; } #endif /*** DirectFB plugin functions ***/ static inline int convert_caps (DFBDisplayLayerCapabilities caps) { int vo = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; if (caps & DLCAPS_HUE) vo |= VO_CAP_HUE; if (caps & DLCAPS_SATURATION) vo |= VO_CAP_SATURATION; if (caps & DLCAPS_CONTRAST) vo |= VO_CAP_CONTRAST; if (caps & DLCAPS_BRIGHTNESS) vo |= VO_CAP_BRIGHTNESS; return vo; } #ifndef DIRECTFB_X11 static vo_driver_t *open_plugin_fb (video_driver_class_t *class_gen, const void *visual_gen) { directfb_class_t *class = (directfb_class_t *) class_gen; directfb_driver_t *this; const char *args[] = { "xine", "--dfb:" DIRECTFB_OPTIONS }; int argn = 2; char **argp = (char **) args; const fb_visual_t *visual = (const fb_visual_t *) visual_gen; config_values_t *config = class->xine->config; DFBDisplayLayerID id; DFBResult ret; this = calloc(1, sizeof(directfb_driver_t)); if (!this) return NULL; this->visual_type = XINE_VISUAL_TYPE_FB; this->xine = class->xine; /* initialize DirectFB */ ret = DirectFBInit (&argn, &argp); if (ret != DFB_OK) { DirectFBError ("DirectFBInit()", ret); free (this); return NULL; } /* create the main interface or retrieve an already existing one */ ret = DirectFBCreate (&this->dfb); if (ret != DFB_OK) { DirectFBError ("DirectFBCreate()", ret); free (this); return NULL; } /* allow user/application to select a different layer */ id = config->register_num (config, "video.device.directfb_layer_id", -1, _("video layer id (auto: -1)"), _("Select the video output layer by its id."), 20, NULL, 0); if (id == (DFBDisplayLayerID)-1) { IDirectFBScreen *screen; /* retrieve an interface to the current screen */ ret = this->dfb->GetScreen (this->dfb, DSCID_PRIMARY, &screen); if (ret != DFB_OK) { DirectFBError ("IDirectFB::GetScreen( DSCID_PRIMARY )", ret); this->dfb->Release (this->dfb); free (this); return NULL; } /* find an overlay layer on the current screen */ id = DLID_PRIMARY; screen->EnumDisplayLayers (screen, find_overlay, (void*)&id); screen->Release (screen); } xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: using display layer #%d.\n"), id); ret = this->dfb->GetDisplayLayer (this->dfb, id, &this->layer); if (ret == DFB_OK) { DFBDisplayLayerDescription dsc; this->layer->SetCooperativeLevel (this->layer, DLSCL_EXCLUSIVE); this->layer->SetOpacity (this->layer, 0x00); this->layer->GetDescription (this->layer, &dsc); this->type = dsc.type; this->caps = dsc.caps; if (id == DLID_PRIMARY) this->caps &= ~(DLCAPS_SCREEN_LOCATION | DLCAPS_DST_COLORKEY); } else { DirectFBError ("IDirectFB::GetDisplayLayer()", ret); this->dfb->Release (this->dfb); free (this); return NULL; } this->capabilities = convert_caps (this->caps); /* set default configuration */ this->buffermode = 1; // double this->vsync = 0; this->colorkeying = 0; this->colorkey = DEFAULT_COLORKEY; this->flicker_filtering = 0; this->field_parity = 0; /* get user configuration */ init_config (this); /* initialize video layer */ if (init_device (this) != DFB_OK) { this->layer->Release (this->layer); this->dfb->Release (this->dfb); free (this); return NULL; } /* initialize subpicture layer (if available) */ init_subpicture (this); if (this->spic_layer) this->capabilities |= VO_CAP_UNSCALED_OVERLAY; _x_alphablend_init (&this->alphablend_extra_data, this->xine); _x_vo_scale_init (&this->sc, 1, 0, this->xine->config); this->sc.user_ratio = XINE_VO_ASPECT_AUTO; this->sc.gui_width = this->screen_width; this->sc.gui_height = this->screen_height; if (visual) { this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; } else { this->sc.frame_output_cb = directfb_frame_output_cb; this->sc.user_data = (void *) this; } this->vo_driver.get_capabilities = directfb_get_capabilities; this->vo_driver.alloc_frame = directfb_alloc_frame; this->vo_driver.update_frame_format = directfb_update_frame_format; this->vo_driver.overlay_begin = directfb_overlay_begin; this->vo_driver.overlay_blend = directfb_overlay_blend; this->vo_driver.overlay_end = directfb_overlay_end; this->vo_driver.display_frame = (this->caps & DLCAPS_SCREEN_LOCATION) ? directfb_display_frame : directfb_display_frame2; this->vo_driver.get_property = directfb_get_property; this->vo_driver.set_property = directfb_set_property; this->vo_driver.get_property_min_max = directfb_get_property_min_max; this->vo_driver.gui_data_exchange = directfb_gui_data_exchange; this->vo_driver.redraw_needed = directfb_redraw_needed; this->vo_driver.dispose = directfb_dispose; return &this->vo_driver; } #endif #ifndef DIRECTFB_X11 static void *init_class_fb (xine_t *xine, const void *visual_gen) { directfb_class_t *this; const char *error; (void)visual_gen; /* check DirectFB version */ error = DirectFBCheckVersion( DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION ); if (error) { xprintf (xine, XINE_VERBOSITY_LOG, "video_out_directfb: %s!\n", error); return NULL; } this = (directfb_class_t *) calloc(1, sizeof(directfb_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin_fb; this->driver_class.identifier = "DirectFB"; this->driver_class.description = N_("xine video output plugin using DirectFB."); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_directfb_fb = { .priority = 8, .visual_type = XINE_VISUAL_TYPE_FB, }; /*** XDirectFB plugin functions ****/ #else static vo_driver_t *open_plugin_x11 (video_driver_class_t *class_gen, const void *visual_gen) { directfb_class_t *class = (directfb_class_t *) class_gen; directfb_driver_t *this; const char *args[] = { "xine", "--dfb:" XDIRECTFB_OPTIONS }; int argn = 2; char **argp = (char **) args; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; XWindowAttributes attrs; IDirectFBScreen *screen; DFBDisplayLayerID id = DLID_PRIMARY; DFBResult ret; this = calloc(1, sizeof(directfb_driver_t)); if (!this) return NULL; this->visual_type = class->visual_type; this->xine = class->xine; /* initialize DirectFB */ ret = DirectFBInit (&argn, &argp); if (ret != DFB_OK) { DirectFBError ("DirectFBInit()", ret); free (this); return NULL; } /* create the main interface or retrieve an already existing one */ ret = DirectFBCreate (&this->dfb); if (ret != DFB_OK) { DirectFBError ("DirectFBCreate()", ret); free (this); return NULL; } /* retrieve an interface to the current screen */ ret = this->dfb->GetScreen (this->dfb, DSCID_PRIMARY, &screen); if (ret != DFB_OK) { DirectFBError ("IDirectFB::GetScreen( DSCID_PRIMARY )", ret); this->dfb->Release (this->dfb); free (this); return NULL; } /* find an overlay layer on the current screen */ ret = screen->EnumDisplayLayers (screen, find_overlay, (void*)&id); screen->Release (screen); if (ret != DFB_OK) { DirectFBError( "IDirectFBScreen::EnumDisplayLayers()", ret); this->dfb->Release (this->dfb); free (this); return NULL; } if (id != DLID_PRIMARY) { DFBDisplayLayerDescription dsc; /* get overlay access */ ret = this->dfb->GetDisplayLayer (this->dfb, id, &this->layer); if (ret) { DirectFBError ("IDirectFB::GetDisplayLayer()", ret); this->dfb->Release (this->dfb); free (this); return NULL; } this->layer->SetCooperativeLevel (this->layer, DLSCL_EXCLUSIVE); this->layer->SetOpacity (this->layer, 0x00); this->layer->GetDescription (this->layer, &dsc); this->type = dsc.type; this->caps = dsc.caps; if (!(this->caps & DLCAPS_SCREEN_LOCATION)) { this->layer->Release (this->layer); this->layer = NULL; } } if (!this->layer) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: no usable display layer was found!\n")); this->dfb->Release (this->dfb); free (this); return NULL; } xprintf (this->xine, XINE_VERBOSITY_LOG, _("video_out_directfb: using display layer #%d.\n"), id); this->capabilities = convert_caps (this->caps); /* set default configuration */ this->buffermode = 1; // double this->vsync = 0; this->colorkeying = (this->caps & DLCAPS_DST_COLORKEY) ? 1 : 0; this->colorkey = DEFAULT_COLORKEY; this->flicker_filtering = 0; this->field_parity = 0; /* get user configuration */ init_config (this); /* set layer configuration */ if (init_device (this) != DFB_OK) { this->layer->Release (this->layer); this->dfb->Release (this->dfb); free (this); return NULL; } this->display = visual->display; this->screen = visual->screen; this->drawable = visual->d; this->gc = XCreateGC (this->display, this->drawable, 0, NULL); XGetWindowAttributes (this->display, this->drawable, &attrs); this->depth = attrs.depth; _x_alphablend_init (&this->alphablend_extra_data, this->xine); _x_vo_scale_init (&this->sc, 1, 0, this->xine->config); this->sc.user_ratio = XINE_VO_ASPECT_AUTO; this->sc.gui_width = attrs.width; this->sc.gui_height = attrs.height; this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; if (this->visual_type == XINE_VISUAL_TYPE_X11_2) { this->user_data = visual->user_data; this->lock_display = visual->lock_display; this->unlock_display = visual->unlock_display; } if (this->colorkeying) { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_COLORKEY); if (this->xoverlay) { x11osd_colorkey (this->xoverlay, directfb_colorkey_to_pixel(this), &this->sc); } } else { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_SHAPED); } if (this->xoverlay) this->capabilities |= VO_CAP_UNSCALED_OVERLAY; this->vo_driver.get_capabilities = directfb_get_capabilities; this->vo_driver.alloc_frame = directfb_alloc_frame; this->vo_driver.update_frame_format = directfb_update_frame_format; this->vo_driver.overlay_begin = directfb_overlay_begin; this->vo_driver.overlay_blend = directfb_overlay_blend; this->vo_driver.overlay_end = directfb_overlay_end; this->vo_driver.display_frame = directfb_display_frame; this->vo_driver.get_property = directfb_get_property; this->vo_driver.set_property = directfb_set_property; this->vo_driver.get_property_min_max = directfb_get_property_min_max; this->vo_driver.gui_data_exchange = directfb_gui_data_exchange; this->vo_driver.redraw_needed = directfb_redraw_needed; this->vo_driver.dispose = directfb_dispose; return &this->vo_driver; } static void *init_class_x11 (xine_t *xine, const void *visual_gen) { directfb_class_t *this; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; const char *error; /* check DirectFB version */ error = DirectFBCheckVersion( DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION ); if (error) { xprintf (xine, XINE_VERBOSITY_LOG, "video_out_directfb: %s!\n", error); return NULL; } if (!visual) { xprintf (xine, XINE_VERBOSITY_DEBUG, "video_out_directfb: x11 visual is required!\n"); return NULL; } /* check if we are running under XDirectFB */ if (strcmp (XServerVendor (visual->display), "Denis Oliver Kropp")) return NULL; this = (directfb_class_t *) calloc(1, sizeof(directfb_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin_x11; this->driver_class.identifier = "XDirectFB"; this->driver_class.description = N_("xine video output plugin using DirectFB under XDirectFB."); this->driver_class.dispose = default_video_driver_class_dispose; this->visual_type = XINE_VISUAL_TYPE_X11; this->xine = xine; return this; } static void *init_class_x11_2 (xine_t *xine, const void *visual_gen) { directfb_class_t *this; this = init_class_x11( xine, visual_gen ); if (this) this->visual_type = XINE_VISUAL_TYPE_X11_2; return this; } static const vo_info_t vo_info_directfb_x11 = { .priority = 8, .visual_type = XINE_VISUAL_TYPE_X11, }; static const vo_info_t vo_info_directfb_x11_2 = { .priority = 8, .visual_type = XINE_VISUAL_TYPE_X11_2, }; #endif /* HAVE_X11 */ /*********/ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ #ifndef DIRECTFB_X11 { PLUGIN_VIDEO_OUT, VIDEO_OUT_DRIVER_IFACE_VERSION, "DirectFB", XINE_VERSION_CODE, &vo_info_directfb_fb, init_class_fb }, #else { PLUGIN_VIDEO_OUT, VIDEO_OUT_DRIVER_IFACE_VERSION, "XDirectFB", XINE_VERSION_CODE, &vo_info_directfb_x11, init_class_x11 }, { PLUGIN_VIDEO_OUT, VIDEO_OUT_DRIVER_IFACE_VERSION, "XDirectFB", XINE_VERSION_CODE, &vo_info_directfb_x11_2, init_class_x11_2 }, #endif { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/myglext.h0000644000175000017500000124145114647725152015322 0ustar meme#ifndef __myglext_h_ #define __myglext_h_ #ifdef __cplusplus extern "C" { #endif /* ** License Applicability. Except to the extent portions of this file are ** made subject to an alternative license as permitted in the SGI Free ** Software License B, Version 1.1 (the "License"), the contents of this ** file are subject only to the provisions of the License. You may not use ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: ** ** http://oss.sgi.com/projects/FreeB ** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. ** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2004 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. ** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) ** version 1.2.1 Specification. */ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) #define WIN32_LEAN_AND_MEAN 1 #include #endif #ifndef APIENTRY #define APIENTRY #endif #ifndef APIENTRYP #define APIENTRYP APIENTRY * #endif #ifndef GLAPI #define GLAPI extern #endif /*************************************************************/ /* Header file version number, required by OpenGL ABI for Linux */ /* myglext.h last updated 2005/03/17 */ /* Current version at http://oss.sgi.com/projects/ogl-sample/registry/ */ #define MYGL_GLEXT_VERSION 27 #ifndef MYGL_VERSION_1_2 #define MYGL_UNSIGNED_BYTE_3_3_2 0x8032 #define MYGL_UNSIGNED_SHORT_4_4_4_4 0x8033 #define MYGL_UNSIGNED_SHORT_5_5_5_1 0x8034 #define MYGL_UNSIGNED_INT_8_8_8_8 0x8035 #define MYGL_UNSIGNED_INT_10_10_10_2 0x8036 #define MYGL_RESCALE_NORMAL 0x803A #define MYGL_TEXTURE_BINDING_3D 0x806A #define MYGL_PACK_SKIP_IMAGES 0x806B #define MYGL_PACK_IMAGE_HEIGHT 0x806C #define MYGL_UNPACK_SKIP_IMAGES 0x806D #define MYGL_UNPACK_IMAGE_HEIGHT 0x806E #define MYGL_TEXTURE_3D 0x806F #define MYGL_PROXY_TEXTURE_3D 0x8070 #define MYGL_TEXTURE_DEPTH 0x8071 #define MYGL_TEXTURE_WRAP_R 0x8072 #define MYGL_MAX_3D_TEXTURE_SIZE 0x8073 #define MYGL_UNSIGNED_BYTE_2_3_3_REV 0x8362 #define MYGL_UNSIGNED_SHORT_5_6_5 0x8363 #define MYGL_UNSIGNED_SHORT_5_6_5_REV 0x8364 #define MYGL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 #define MYGL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 #define MYGL_UNSIGNED_INT_8_8_8_8_REV 0x8367 #define MYGL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #define MYGL_BGR 0x80E0 #define MYGL_BGRA 0x80E1 #define MYGL_MAX_ELEMENTS_VERTICES 0x80E8 #define MYGL_MAX_ELEMENTS_INDICES 0x80E9 #define MYGL_CLAMP_TO_EDGE 0x812F #define MYGL_TEXTURE_MIN_LOD 0x813A #define MYGL_TEXTURE_MAX_LOD 0x813B #define MYGL_TEXTURE_BASE_LEVEL 0x813C #define MYGL_TEXTURE_MAX_LEVEL 0x813D #define MYGL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 #define MYGL_SINGLE_COLOR 0x81F9 #define MYGL_SEPARATE_SPECULAR_COLOR 0x81FA #define MYGL_SMOOTH_POINT_SIZE_RANGE 0x0B12 #define MYGL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 #define MYGL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 #define MYGL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 #define MYGL_ALIASED_POINT_SIZE_RANGE 0x846D #define MYGL_ALIASED_LINE_WIDTH_RANGE 0x846E #endif #ifndef MYGL_ARB_imaging #define MYGL_CONSTANT_COLOR 0x8001 #define MYGL_ONE_MINUS_CONSTANT_COLOR 0x8002 #define MYGL_CONSTANT_ALPHA 0x8003 #define MYGL_ONE_MINUS_CONSTANT_ALPHA 0x8004 #define MYGL_BLEND_COLOR 0x8005 #define MYGL_FUNC_ADD 0x8006 #define MYGL_MIN 0x8007 #define MYGL_MAX 0x8008 #define MYGL_BLEND_EQUATION 0x8009 #define MYGL_FUNC_SUBTRACT 0x800A #define MYGL_FUNC_REVERSE_SUBTRACT 0x800B #define MYGL_CONVOLUTION_1D 0x8010 #define MYGL_CONVOLUTION_2D 0x8011 #define MYGL_SEPARABLE_2D 0x8012 #define MYGL_CONVOLUTION_BORDER_MODE 0x8013 #define MYGL_CONVOLUTION_FILTER_SCALE 0x8014 #define MYGL_CONVOLUTION_FILTER_BIAS 0x8015 #define MYGL_REDUCE 0x8016 #define MYGL_CONVOLUTION_FORMAT 0x8017 #define MYGL_CONVOLUTION_WIDTH 0x8018 #define MYGL_CONVOLUTION_HEIGHT 0x8019 #define MYGL_MAX_CONVOLUTION_WIDTH 0x801A #define MYGL_MAX_CONVOLUTION_HEIGHT 0x801B #define MYGL_POST_CONVOLUTION_RED_SCALE 0x801C #define MYGL_POST_CONVOLUTION_GREEN_SCALE 0x801D #define MYGL_POST_CONVOLUTION_BLUE_SCALE 0x801E #define MYGL_POST_CONVOLUTION_ALPHA_SCALE 0x801F #define MYGL_POST_CONVOLUTION_RED_BIAS 0x8020 #define MYGL_POST_CONVOLUTION_GREEN_BIAS 0x8021 #define MYGL_POST_CONVOLUTION_BLUE_BIAS 0x8022 #define MYGL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 #define MYGL_HISTOGRAM 0x8024 #define MYGL_PROXY_HISTOGRAM 0x8025 #define MYGL_HISTOGRAM_WIDTH 0x8026 #define MYGL_HISTOGRAM_FORMAT 0x8027 #define MYGL_HISTOGRAM_RED_SIZE 0x8028 #define MYGL_HISTOGRAM_GREEN_SIZE 0x8029 #define MYGL_HISTOGRAM_BLUE_SIZE 0x802A #define MYGL_HISTOGRAM_ALPHA_SIZE 0x802B #define MYGL_HISTOGRAM_LUMINANCE_SIZE 0x802C #define MYGL_HISTOGRAM_SINK 0x802D #define MYGL_MINMAX 0x802E #define MYGL_MINMAX_FORMAT 0x802F #define MYGL_MINMAX_SINK 0x8030 #define MYGL_TABLE_TOO_LARGE 0x8031 #define MYGL_COLOR_MATRIX 0x80B1 #define MYGL_COLOR_MATRIX_STACK_DEPTH 0x80B2 #define MYGL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 #define MYGL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 #define MYGL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 #define MYGL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 #define MYGL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 #define MYGL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 #define MYGL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 #define MYGL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA #define MYGL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB #define MYGL_COLOR_TABLE 0x80D0 #define MYGL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 #define MYGL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 #define MYGL_PROXY_COLOR_TABLE 0x80D3 #define MYGL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 #define MYGL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 #define MYGL_COLOR_TABLE_SCALE 0x80D6 #define MYGL_COLOR_TABLE_BIAS 0x80D7 #define MYGL_COLOR_TABLE_FORMAT 0x80D8 #define MYGL_COLOR_TABLE_WIDTH 0x80D9 #define MYGL_COLOR_TABLE_RED_SIZE 0x80DA #define MYGL_COLOR_TABLE_GREEN_SIZE 0x80DB #define MYGL_COLOR_TABLE_BLUE_SIZE 0x80DC #define MYGL_COLOR_TABLE_ALPHA_SIZE 0x80DD #define MYGL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE #define MYGL_COLOR_TABLE_INTENSITY_SIZE 0x80DF #define MYGL_CONSTANT_BORDER 0x8151 #define MYGL_REPLICATE_BORDER 0x8153 #define MYGL_CONVOLUTION_BORDER_COLOR 0x8154 #endif #ifndef MYGL_VERSION_1_3 #define MYGL_TEXTURE0 0x84C0 #define MYGL_TEXTURE1 0x84C1 #define MYGL_TEXTURE2 0x84C2 #define MYGL_TEXTURE3 0x84C3 #define MYGL_TEXTURE4 0x84C4 #define MYGL_TEXTURE5 0x84C5 #define MYGL_TEXTURE6 0x84C6 #define MYGL_TEXTURE7 0x84C7 #define MYGL_TEXTURE8 0x84C8 #define MYGL_TEXTURE9 0x84C9 #define MYGL_TEXTURE10 0x84CA #define MYGL_TEXTURE11 0x84CB #define MYGL_TEXTURE12 0x84CC #define MYGL_TEXTURE13 0x84CD #define MYGL_TEXTURE14 0x84CE #define MYGL_TEXTURE15 0x84CF #define MYGL_TEXTURE16 0x84D0 #define MYGL_TEXTURE17 0x84D1 #define MYGL_TEXTURE18 0x84D2 #define MYGL_TEXTURE19 0x84D3 #define MYGL_TEXTURE20 0x84D4 #define MYGL_TEXTURE21 0x84D5 #define MYGL_TEXTURE22 0x84D6 #define MYGL_TEXTURE23 0x84D7 #define MYGL_TEXTURE24 0x84D8 #define MYGL_TEXTURE25 0x84D9 #define MYGL_TEXTURE26 0x84DA #define MYGL_TEXTURE27 0x84DB #define MYGL_TEXTURE28 0x84DC #define MYGL_TEXTURE29 0x84DD #define MYGL_TEXTURE30 0x84DE #define MYGL_TEXTURE31 0x84DF #define MYGL_ACTIVE_TEXTURE 0x84E0 #define MYGL_CLIENT_ACTIVE_TEXTURE 0x84E1 #define MYGL_MAX_TEXTURE_UNITS 0x84E2 #define MYGL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 #define MYGL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 #define MYGL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 #define MYGL_TRANSPOSE_COLOR_MATRIX 0x84E6 #define MYGL_MULTISAMPLE 0x809D #define MYGL_SAMPLE_ALPHA_TO_COVERAGE 0x809E #define MYGL_SAMPLE_ALPHA_TO_ONE 0x809F #define MYGL_SAMPLE_COVERAGE 0x80A0 #define MYGL_SAMPLE_BUFFERS 0x80A8 #define MYGL_SAMPLES 0x80A9 #define MYGL_SAMPLE_COVERAGE_VALUE 0x80AA #define MYGL_SAMPLE_COVERAGE_INVERT 0x80AB #define MYGL_MULTISAMPLE_BIT 0x20000000 #define MYGL_NORMAL_MAP 0x8511 #define MYGL_REFLECTION_MAP 0x8512 #define MYGL_TEXTURE_CUBE_MAP 0x8513 #define MYGL_TEXTURE_BINDING_CUBE_MAP 0x8514 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A #define MYGL_PROXY_TEXTURE_CUBE_MAP 0x851B #define MYGL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C #define MYGL_COMPRESSED_ALPHA 0x84E9 #define MYGL_COMPRESSED_LUMINANCE 0x84EA #define MYGL_COMPRESSED_LUMINANCE_ALPHA 0x84EB #define MYGL_COMPRESSED_INTENSITY 0x84EC #define MYGL_COMPRESSED_RGB 0x84ED #define MYGL_COMPRESSED_RGBA 0x84EE #define MYGL_TEXTURE_COMPRESSION_HINT 0x84EF #define MYGL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 #define MYGL_TEXTURE_COMPRESSED 0x86A1 #define MYGL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 #define MYGL_COMPRESSED_TEXTURE_FORMATS 0x86A3 #define MYGL_CLAMP_TO_BORDER 0x812D #define MYGL_COMBINE 0x8570 #define MYGL_COMBINE_RGB 0x8571 #define MYGL_COMBINE_ALPHA 0x8572 #define MYGL_SOURCE0_RGB 0x8580 #define MYGL_SOURCE1_RGB 0x8581 #define MYGL_SOURCE2_RGB 0x8582 #define MYGL_SOURCE0_ALPHA 0x8588 #define MYGL_SOURCE1_ALPHA 0x8589 #define MYGL_SOURCE2_ALPHA 0x858A #define MYGL_OPERAND0_RGB 0x8590 #define MYGL_OPERAND1_RGB 0x8591 #define MYGL_OPERAND2_RGB 0x8592 #define MYGL_OPERAND0_ALPHA 0x8598 #define MYGL_OPERAND1_ALPHA 0x8599 #define MYGL_OPERAND2_ALPHA 0x859A #define MYGL_RGB_SCALE 0x8573 #define MYGL_ADD_SIGNED 0x8574 #define MYGL_INTERPOLATE 0x8575 #define MYGL_SUBTRACT 0x84E7 #define MYGL_CONSTANT 0x8576 #define MYGL_PRIMARY_COLOR 0x8577 #define MYGL_PREVIOUS 0x8578 #define MYGL_DOT3_RGB 0x86AE #define MYGL_DOT3_RGBA 0x86AF #endif #ifndef MYGL_VERSION_1_4 #define MYGL_BLEND_DST_RGB 0x80C8 #define MYGL_BLEND_SRC_RGB 0x80C9 #define MYGL_BLEND_DST_ALPHA 0x80CA #define MYGL_BLEND_SRC_ALPHA 0x80CB #define MYGL_POINT_SIZE_MIN 0x8126 #define MYGL_POINT_SIZE_MAX 0x8127 #define MYGL_POINT_FADE_THRESHOLD_SIZE 0x8128 #define MYGL_POINT_DISTANCE_ATTENUATION 0x8129 #define MYGL_GENERATE_MIPMAP 0x8191 #define MYGL_GENERATE_MIPMAP_HINT 0x8192 #define MYGL_DEPTH_COMPONENT16 0x81A5 #define MYGL_DEPTH_COMPONENT24 0x81A6 #define MYGL_DEPTH_COMPONENT32 0x81A7 #define MYGL_MIRRORED_REPEAT 0x8370 #define MYGL_FOG_COORDINATE_SOURCE 0x8450 #define MYGL_FOG_COORDINATE 0x8451 #define MYGL_FRAGMENT_DEPTH 0x8452 #define MYGL_CURRENT_FOG_COORDINATE 0x8453 #define MYGL_FOG_COORDINATE_ARRAY_TYPE 0x8454 #define MYGL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 #define MYGL_FOG_COORDINATE_ARRAY_POINTER 0x8456 #define MYGL_FOG_COORDINATE_ARRAY 0x8457 #define MYGL_COLOR_SUM 0x8458 #define MYGL_CURRENT_SECONDARY_COLOR 0x8459 #define MYGL_SECONDARY_COLOR_ARRAY_SIZE 0x845A #define MYGL_SECONDARY_COLOR_ARRAY_TYPE 0x845B #define MYGL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C #define MYGL_SECONDARY_COLOR_ARRAY_POINTER 0x845D #define MYGL_SECONDARY_COLOR_ARRAY 0x845E #define MYGL_MAX_TEXTURE_LOD_BIAS 0x84FD #define MYGL_TEXTURE_FILTER_CONTROL 0x8500 #define MYGL_TEXTURE_LOD_BIAS 0x8501 #define MYGL_INCR_WRAP 0x8507 #define MYGL_DECR_WRAP 0x8508 #define MYGL_TEXTURE_DEPTH_SIZE 0x884A #define MYGL_DEPTH_TEXTURE_MODE 0x884B #define MYGL_TEXTURE_COMPARE_MODE 0x884C #define MYGL_TEXTURE_COMPARE_FUNC 0x884D #define MYGL_COMPARE_R_TO_TEXTURE 0x884E #endif #ifndef MYGL_VERSION_1_5 #define MYGL_BUFFER_SIZE 0x8764 #define MYGL_BUFFER_USAGE 0x8765 #define MYGL_QUERY_COUNTER_BITS 0x8864 #define MYGL_CURRENT_QUERY 0x8865 #define MYGL_QUERY_RESULT 0x8866 #define MYGL_QUERY_RESULT_AVAILABLE 0x8867 #define MYGL_ARRAY_BUFFER 0x8892 #define MYGL_ELEMENT_ARRAY_BUFFER 0x8893 #define MYGL_ARRAY_BUFFER_BINDING 0x8894 #define MYGL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 #define MYGL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 #define MYGL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 #define MYGL_COLOR_ARRAY_BUFFER_BINDING 0x8898 #define MYGL_INDEX_ARRAY_BUFFER_BINDING 0x8899 #define MYGL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A #define MYGL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B #define MYGL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C #define MYGL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D #define MYGL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E #define MYGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F #define MYGL_READ_ONLY 0x88B8 #define MYGL_WRITE_ONLY 0x88B9 #define MYGL_READ_WRITE 0x88BA #define MYGL_BUFFER_ACCESS 0x88BB #define MYGL_BUFFER_MAPPED 0x88BC #define MYGL_BUFFER_MAP_POINTER 0x88BD #define MYGL_STREAM_DRAW 0x88E0 #define MYGL_STREAM_READ 0x88E1 #define MYGL_STREAM_COPY 0x88E2 #define MYGL_STATIC_DRAW 0x88E4 #define MYGL_STATIC_READ 0x88E5 #define MYGL_STATIC_COPY 0x88E6 #define MYGL_DYNAMIC_DRAW 0x88E8 #define MYGL_DYNAMIC_READ 0x88E9 #define MYGL_DYNAMIC_COPY 0x88EA #define MYGL_SAMPLES_PASSED 0x8914 #define MYGL_FOG_COORD_SRC MYGL_FOG_COORDINATE_SOURCE #define MYGL_FOG_COORD MYGL_FOG_COORDINATE #define MYGL_CURRENT_FOG_COORD MYGL_CURRENT_FOG_COORDINATE #define MYGL_FOG_COORD_ARRAY_TYPE MYGL_FOG_COORDINATE_ARRAY_TYPE #define MYGL_FOG_COORD_ARRAY_STRIDE MYGL_FOG_COORDINATE_ARRAY_STRIDE #define MYGL_FOG_COORD_ARRAY_POINTER MYGL_FOG_COORDINATE_ARRAY_POINTER #define MYGL_FOG_COORD_ARRAY MYGL_FOG_COORDINATE_ARRAY #define MYGL_FOG_COORD_ARRAY_BUFFER_BINDING MYGL_FOG_COORDINATE_ARRAY_BUFFER_BINDING #define MYGL_SRC0_RGB MYGL_SOURCE0_RGB #define MYGL_SRC1_RGB MYGL_SOURCE1_RGB #define MYGL_SRC2_RGB MYGL_SOURCE2_RGB #define MYGL_SRC0_ALPHA MYGL_SOURCE0_ALPHA #define MYGL_SRC1_ALPHA MYGL_SOURCE1_ALPHA #define MYGL_SRC2_ALPHA MYGL_SOURCE2_ALPHA #endif #ifndef MYGL_VERSION_2_0 #define MYGL_BLEND_EQUATION_RGB MYGL_BLEND_EQUATION #define MYGL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 #define MYGL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 #define MYGL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 #define MYGL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 #define MYGL_CURRENT_VERTEX_ATTRIB 0x8626 #define MYGL_VERTEX_PROGRAM_POINT_SIZE 0x8642 #define MYGL_VERTEX_PROGRAM_TWO_SIDE 0x8643 #define MYGL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 #define MYGL_STENCIL_BACK_FUNC 0x8800 #define MYGL_STENCIL_BACK_FAIL 0x8801 #define MYGL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 #define MYGL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 #define MYGL_MAX_DRAW_BUFFERS 0x8824 #define MYGL_DRAW_BUFFER0 0x8825 #define MYGL_DRAW_BUFFER1 0x8826 #define MYGL_DRAW_BUFFER2 0x8827 #define MYGL_DRAW_BUFFER3 0x8828 #define MYGL_DRAW_BUFFER4 0x8829 #define MYGL_DRAW_BUFFER5 0x882A #define MYGL_DRAW_BUFFER6 0x882B #define MYGL_DRAW_BUFFER7 0x882C #define MYGL_DRAW_BUFFER8 0x882D #define MYGL_DRAW_BUFFER9 0x882E #define MYGL_DRAW_BUFFER10 0x882F #define MYGL_DRAW_BUFFER11 0x8830 #define MYGL_DRAW_BUFFER12 0x8831 #define MYGL_DRAW_BUFFER13 0x8832 #define MYGL_DRAW_BUFFER14 0x8833 #define MYGL_DRAW_BUFFER15 0x8834 #define MYGL_BLEND_EQUATION_ALPHA 0x883D #define MYGL_POINT_SPRITE 0x8861 #define MYGL_COORD_REPLACE 0x8862 #define MYGL_MAX_VERTEX_ATTRIBS 0x8869 #define MYGL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A #define MYGL_MAX_TEXTURE_COORDS 0x8871 #define MYGL_MAX_TEXTURE_IMAGE_UNITS 0x8872 #define MYGL_FRAGMENT_SHADER 0x8B30 #define MYGL_VERTEX_SHADER 0x8B31 #define MYGL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 #define MYGL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A #define MYGL_MAX_VARYING_FLOATS 0x8B4B #define MYGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C #define MYGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D #define MYGL_SHADER_TYPE 0x8B4F #define MYGL_FLOAT_VEC2 0x8B50 #define MYGL_FLOAT_VEC3 0x8B51 #define MYGL_FLOAT_VEC4 0x8B52 #define MYGL_INT_VEC2 0x8B53 #define MYGL_INT_VEC3 0x8B54 #define MYGL_INT_VEC4 0x8B55 #define MYGL_BOOL 0x8B56 #define MYGL_BOOL_VEC2 0x8B57 #define MYGL_BOOL_VEC3 0x8B58 #define MYGL_BOOL_VEC4 0x8B59 #define MYGL_FLOAT_MAT2 0x8B5A #define MYGL_FLOAT_MAT3 0x8B5B #define MYGL_FLOAT_MAT4 0x8B5C #define MYGL_SAMPLER_1D 0x8B5D #define MYGL_SAMPLER_2D 0x8B5E #define MYGL_SAMPLER_3D 0x8B5F #define MYGL_SAMPLER_CUBE 0x8B60 #define MYGL_SAMPLER_1D_SHADOW 0x8B61 #define MYGL_SAMPLER_2D_SHADOW 0x8B62 #define MYGL_DELETE_STATUS 0x8B80 #define MYGL_COMPILE_STATUS 0x8B81 #define MYGL_LINK_STATUS 0x8B82 #define MYGL_VALIDATE_STATUS 0x8B83 #define MYGL_INFO_LOG_LENGTH 0x8B84 #define MYGL_ATTACHED_SHADERS 0x8B85 #define MYGL_ACTIVE_UNIFORMS 0x8B86 #define MYGL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 #define MYGL_SHADER_SOURCE_LENGTH 0x8B88 #define MYGL_ACTIVE_ATTRIBUTES 0x8B89 #define MYGL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A #define MYGL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B #define MYGL_SHADING_LANGUAGE_VERSION 0x8B8C #define MYGL_CURRENT_PROGRAM 0x8B8D #define MYGL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 #define MYGL_LOWER_LEFT 0x8CA1 #define MYGL_UPPER_LEFT 0x8CA2 #define MYGL_STENCIL_BACK_REF 0x8CA3 #define MYGL_STENCIL_BACK_VALUE_MASK 0x8CA4 #define MYGL_STENCIL_BACK_WRITEMASK 0x8CA5 #endif #ifndef MYGL_ARB_multitexture #define MYGL_TEXTURE0_ARB 0x84C0 #define MYGL_TEXTURE1_ARB 0x84C1 #define MYGL_TEXTURE2_ARB 0x84C2 #define MYGL_TEXTURE3_ARB 0x84C3 #define MYGL_TEXTURE4_ARB 0x84C4 #define MYGL_TEXTURE5_ARB 0x84C5 #define MYGL_TEXTURE6_ARB 0x84C6 #define MYGL_TEXTURE7_ARB 0x84C7 #define MYGL_TEXTURE8_ARB 0x84C8 #define MYGL_TEXTURE9_ARB 0x84C9 #define MYGL_TEXTURE10_ARB 0x84CA #define MYGL_TEXTURE11_ARB 0x84CB #define MYGL_TEXTURE12_ARB 0x84CC #define MYGL_TEXTURE13_ARB 0x84CD #define MYGL_TEXTURE14_ARB 0x84CE #define MYGL_TEXTURE15_ARB 0x84CF #define MYGL_TEXTURE16_ARB 0x84D0 #define MYGL_TEXTURE17_ARB 0x84D1 #define MYGL_TEXTURE18_ARB 0x84D2 #define MYGL_TEXTURE19_ARB 0x84D3 #define MYGL_TEXTURE20_ARB 0x84D4 #define MYGL_TEXTURE21_ARB 0x84D5 #define MYGL_TEXTURE22_ARB 0x84D6 #define MYGL_TEXTURE23_ARB 0x84D7 #define MYGL_TEXTURE24_ARB 0x84D8 #define MYGL_TEXTURE25_ARB 0x84D9 #define MYGL_TEXTURE26_ARB 0x84DA #define MYGL_TEXTURE27_ARB 0x84DB #define MYGL_TEXTURE28_ARB 0x84DC #define MYGL_TEXTURE29_ARB 0x84DD #define MYGL_TEXTURE30_ARB 0x84DE #define MYGL_TEXTURE31_ARB 0x84DF #define MYGL_ACTIVE_TEXTURE_ARB 0x84E0 #define MYGL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 #define MYGL_MAX_TEXTURE_UNITS_ARB 0x84E2 #endif #ifndef MYGL_ARB_transpose_matrix #define MYGL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 #define MYGL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 #define MYGL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 #define MYGL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 #endif #ifndef MYGL_ARB_multisample #define MYGL_MULTISAMPLE_ARB 0x809D #define MYGL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E #define MYGL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F #define MYGL_SAMPLE_COVERAGE_ARB 0x80A0 #define MYGL_SAMPLE_BUFFERS_ARB 0x80A8 #define MYGL_SAMPLES_ARB 0x80A9 #define MYGL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA #define MYGL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB #define MYGL_MULTISAMPLE_BIT_ARB 0x20000000 #endif #ifndef MYGL_ARB_texture_env_add #endif #ifndef MYGL_ARB_texture_cube_map #define MYGL_NORMAL_MAP_ARB 0x8511 #define MYGL_REFLECTION_MAP_ARB 0x8512 #define MYGL_TEXTURE_CUBE_MAP_ARB 0x8513 #define MYGL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A #define MYGL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B #define MYGL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C #endif #ifndef MYGL_ARB_texture_compression #define MYGL_COMPRESSED_ALPHA_ARB 0x84E9 #define MYGL_COMPRESSED_LUMINANCE_ARB 0x84EA #define MYGL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB #define MYGL_COMPRESSED_INTENSITY_ARB 0x84EC #define MYGL_COMPRESSED_RGB_ARB 0x84ED #define MYGL_COMPRESSED_RGBA_ARB 0x84EE #define MYGL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF #define MYGL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 #define MYGL_TEXTURE_COMPRESSED_ARB 0x86A1 #define MYGL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 #define MYGL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 #endif #ifndef MYGL_ARB_texture_border_clamp #define MYGL_CLAMP_TO_BORDER_ARB 0x812D #endif #ifndef MYGL_ARB_point_parameters #define MYGL_POINT_SIZE_MIN_ARB 0x8126 #define MYGL_POINT_SIZE_MAX_ARB 0x8127 #define MYGL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 #define MYGL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 #endif #ifndef MYGL_ARB_vertex_blend #define MYGL_MAX_VERTEX_UNITS_ARB 0x86A4 #define MYGL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 #define MYGL_WEIGHT_SUM_UNITY_ARB 0x86A6 #define MYGL_VERTEX_BLEND_ARB 0x86A7 #define MYGL_CURRENT_WEIGHT_ARB 0x86A8 #define MYGL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 #define MYGL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA #define MYGL_WEIGHT_ARRAY_SIZE_ARB 0x86AB #define MYGL_WEIGHT_ARRAY_POINTER_ARB 0x86AC #define MYGL_WEIGHT_ARRAY_ARB 0x86AD #define MYGL_MODELVIEW0_ARB 0x1700 #define MYGL_MODELVIEW1_ARB 0x850A #define MYGL_MODELVIEW2_ARB 0x8722 #define MYGL_MODELVIEW3_ARB 0x8723 #define MYGL_MODELVIEW4_ARB 0x8724 #define MYGL_MODELVIEW5_ARB 0x8725 #define MYGL_MODELVIEW6_ARB 0x8726 #define MYGL_MODELVIEW7_ARB 0x8727 #define MYGL_MODELVIEW8_ARB 0x8728 #define MYGL_MODELVIEW9_ARB 0x8729 #define MYGL_MODELVIEW10_ARB 0x872A #define MYGL_MODELVIEW11_ARB 0x872B #define MYGL_MODELVIEW12_ARB 0x872C #define MYGL_MODELVIEW13_ARB 0x872D #define MYGL_MODELVIEW14_ARB 0x872E #define MYGL_MODELVIEW15_ARB 0x872F #define MYGL_MODELVIEW16_ARB 0x8730 #define MYGL_MODELVIEW17_ARB 0x8731 #define MYGL_MODELVIEW18_ARB 0x8732 #define MYGL_MODELVIEW19_ARB 0x8733 #define MYGL_MODELVIEW20_ARB 0x8734 #define MYGL_MODELVIEW21_ARB 0x8735 #define MYGL_MODELVIEW22_ARB 0x8736 #define MYGL_MODELVIEW23_ARB 0x8737 #define MYGL_MODELVIEW24_ARB 0x8738 #define MYGL_MODELVIEW25_ARB 0x8739 #define MYGL_MODELVIEW26_ARB 0x873A #define MYGL_MODELVIEW27_ARB 0x873B #define MYGL_MODELVIEW28_ARB 0x873C #define MYGL_MODELVIEW29_ARB 0x873D #define MYGL_MODELVIEW30_ARB 0x873E #define MYGL_MODELVIEW31_ARB 0x873F #endif #ifndef MYGL_ARB_matrix_palette #define MYGL_MATRIX_PALETTE_ARB 0x8840 #define MYGL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 #define MYGL_MAX_PALETTE_MATRICES_ARB 0x8842 #define MYGL_CURRENT_PALETTE_MATRIX_ARB 0x8843 #define MYGL_MATRIX_INDEX_ARRAY_ARB 0x8844 #define MYGL_CURRENT_MATRIX_INDEX_ARB 0x8845 #define MYGL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 #define MYGL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 #define MYGL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 #define MYGL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 #endif #ifndef MYGL_ARB_texture_env_combine #define MYGL_COMBINE_ARB 0x8570 #define MYGL_COMBINE_RGB_ARB 0x8571 #define MYGL_COMBINE_ALPHA_ARB 0x8572 #define MYGL_SOURCE0_RGB_ARB 0x8580 #define MYGL_SOURCE1_RGB_ARB 0x8581 #define MYGL_SOURCE2_RGB_ARB 0x8582 #define MYGL_SOURCE0_ALPHA_ARB 0x8588 #define MYGL_SOURCE1_ALPHA_ARB 0x8589 #define MYGL_SOURCE2_ALPHA_ARB 0x858A #define MYGL_OPERAND0_RGB_ARB 0x8590 #define MYGL_OPERAND1_RGB_ARB 0x8591 #define MYGL_OPERAND2_RGB_ARB 0x8592 #define MYGL_OPERAND0_ALPHA_ARB 0x8598 #define MYGL_OPERAND1_ALPHA_ARB 0x8599 #define MYGL_OPERAND2_ALPHA_ARB 0x859A #define MYGL_RGB_SCALE_ARB 0x8573 #define MYGL_ADD_SIGNED_ARB 0x8574 #define MYGL_INTERPOLATE_ARB 0x8575 #define MYGL_SUBTRACT_ARB 0x84E7 #define MYGL_CONSTANT_ARB 0x8576 #define MYGL_PRIMARY_COLOR_ARB 0x8577 #define MYGL_PREVIOUS_ARB 0x8578 #endif #ifndef MYGL_ARB_texture_env_crossbar #endif #ifndef MYGL_ARB_texture_env_dot3 #define MYGL_DOT3_RGB_ARB 0x86AE #define MYGL_DOT3_RGBA_ARB 0x86AF #endif #ifndef MYGL_ARB_texture_mirrored_repeat #define MYGL_MIRRORED_REPEAT_ARB 0x8370 #endif #ifndef MYGL_ARB_depth_texture #define MYGL_DEPTH_COMPONENT16_ARB 0x81A5 #define MYGL_DEPTH_COMPONENT24_ARB 0x81A6 #define MYGL_DEPTH_COMPONENT32_ARB 0x81A7 #define MYGL_TEXTURE_DEPTH_SIZE_ARB 0x884A #define MYGL_DEPTH_TEXTURE_MODE_ARB 0x884B #endif #ifndef MYGL_ARB_shadow #define MYGL_TEXTURE_COMPARE_MODE_ARB 0x884C #define MYGL_TEXTURE_COMPARE_FUNC_ARB 0x884D #define MYGL_COMPARE_R_TO_TEXTURE_ARB 0x884E #endif #ifndef MYGL_ARB_shadow_ambient #define MYGL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF #endif #ifndef MYGL_ARB_window_pos #endif #ifndef MYGL_ARB_vertex_program #define MYGL_COLOR_SUM_ARB 0x8458 #define MYGL_VERTEX_PROGRAM_ARB 0x8620 #define MYGL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 #define MYGL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 #define MYGL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 #define MYGL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 #define MYGL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 #define MYGL_PROGRAM_LENGTH_ARB 0x8627 #define MYGL_PROGRAM_STRING_ARB 0x8628 #define MYGL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E #define MYGL_MAX_PROGRAM_MATRICES_ARB 0x862F #define MYGL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 #define MYGL_CURRENT_MATRIX_ARB 0x8641 #define MYGL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 #define MYGL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 #define MYGL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 #define MYGL_PROGRAM_ERROR_POSITION_ARB 0x864B #define MYGL_PROGRAM_BINDING_ARB 0x8677 #define MYGL_MAX_VERTEX_ATTRIBS_ARB 0x8869 #define MYGL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A #define MYGL_PROGRAM_ERROR_STRING_ARB 0x8874 #define MYGL_PROGRAM_FORMAT_ASCII_ARB 0x8875 #define MYGL_PROGRAM_FORMAT_ARB 0x8876 #define MYGL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 #define MYGL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 #define MYGL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 #define MYGL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 #define MYGL_PROGRAM_TEMPORARIES_ARB 0x88A4 #define MYGL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 #define MYGL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 #define MYGL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 #define MYGL_PROGRAM_PARAMETERS_ARB 0x88A8 #define MYGL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 #define MYGL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA #define MYGL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB #define MYGL_PROGRAM_ATTRIBS_ARB 0x88AC #define MYGL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD #define MYGL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE #define MYGL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF #define MYGL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 #define MYGL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 #define MYGL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 #define MYGL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 #define MYGL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 #define MYGL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 #define MYGL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 #define MYGL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 #define MYGL_MATRIX0_ARB 0x88C0 #define MYGL_MATRIX1_ARB 0x88C1 #define MYGL_MATRIX2_ARB 0x88C2 #define MYGL_MATRIX3_ARB 0x88C3 #define MYGL_MATRIX4_ARB 0x88C4 #define MYGL_MATRIX5_ARB 0x88C5 #define MYGL_MATRIX6_ARB 0x88C6 #define MYGL_MATRIX7_ARB 0x88C7 #define MYGL_MATRIX8_ARB 0x88C8 #define MYGL_MATRIX9_ARB 0x88C9 #define MYGL_MATRIX10_ARB 0x88CA #define MYGL_MATRIX11_ARB 0x88CB #define MYGL_MATRIX12_ARB 0x88CC #define MYGL_MATRIX13_ARB 0x88CD #define MYGL_MATRIX14_ARB 0x88CE #define MYGL_MATRIX15_ARB 0x88CF #define MYGL_MATRIX16_ARB 0x88D0 #define MYGL_MATRIX17_ARB 0x88D1 #define MYGL_MATRIX18_ARB 0x88D2 #define MYGL_MATRIX19_ARB 0x88D3 #define MYGL_MATRIX20_ARB 0x88D4 #define MYGL_MATRIX21_ARB 0x88D5 #define MYGL_MATRIX22_ARB 0x88D6 #define MYGL_MATRIX23_ARB 0x88D7 #define MYGL_MATRIX24_ARB 0x88D8 #define MYGL_MATRIX25_ARB 0x88D9 #define MYGL_MATRIX26_ARB 0x88DA #define MYGL_MATRIX27_ARB 0x88DB #define MYGL_MATRIX28_ARB 0x88DC #define MYGL_MATRIX29_ARB 0x88DD #define MYGL_MATRIX30_ARB 0x88DE #define MYGL_MATRIX31_ARB 0x88DF #endif #ifndef MYGL_ARB_fragment_program #define MYGL_FRAGMENT_PROGRAM_ARB 0x8804 #define MYGL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 #define MYGL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 #define MYGL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 #define MYGL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 #define MYGL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 #define MYGL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A #define MYGL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B #define MYGL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C #define MYGL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D #define MYGL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E #define MYGL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F #define MYGL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 #define MYGL_MAX_TEXTURE_COORDS_ARB 0x8871 #define MYGL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 #endif #ifndef MYGL_ARB_vertex_buffer_object #define MYGL_BUFFER_SIZE_ARB 0x8764 #define MYGL_BUFFER_USAGE_ARB 0x8765 #define MYGL_ARRAY_BUFFER_ARB 0x8892 #define MYGL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 #define MYGL_ARRAY_BUFFER_BINDING_ARB 0x8894 #define MYGL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 #define MYGL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 #define MYGL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 #define MYGL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 #define MYGL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 #define MYGL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A #define MYGL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B #define MYGL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C #define MYGL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D #define MYGL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E #define MYGL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F #define MYGL_READ_ONLY_ARB 0x88B8 #define MYGL_WRITE_ONLY_ARB 0x88B9 #define MYGL_READ_WRITE_ARB 0x88BA #define MYGL_BUFFER_ACCESS_ARB 0x88BB #define MYGL_BUFFER_MAPPED_ARB 0x88BC #define MYGL_BUFFER_MAP_POINTER_ARB 0x88BD #define MYGL_STREAM_DRAW_ARB 0x88E0 #define MYGL_STREAM_READ_ARB 0x88E1 #define MYGL_STREAM_COPY_ARB 0x88E2 #define MYGL_STATIC_DRAW_ARB 0x88E4 #define MYGL_STATIC_READ_ARB 0x88E5 #define MYGL_STATIC_COPY_ARB 0x88E6 #define MYGL_DYNAMIC_DRAW_ARB 0x88E8 #define MYGL_DYNAMIC_READ_ARB 0x88E9 #define MYGL_DYNAMIC_COPY_ARB 0x88EA #endif #ifndef MYGL_ARB_occlusion_query #define MYGL_QUERY_COUNTER_BITS_ARB 0x8864 #define MYGL_CURRENT_QUERY_ARB 0x8865 #define MYGL_QUERY_RESULT_ARB 0x8866 #define MYGL_QUERY_RESULT_AVAILABLE_ARB 0x8867 #define MYGL_SAMPLES_PASSED_ARB 0x8914 #endif #ifndef MYGL_ARB_shader_objects #define MYGL_PROGRAM_OBJECT_ARB 0x8B40 #define MYGL_SHADER_OBJECT_ARB 0x8B48 #define MYGL_OBJECT_TYPE_ARB 0x8B4E #define MYGL_OBJECT_SUBTYPE_ARB 0x8B4F #define MYGL_FLOAT_VEC2_ARB 0x8B50 #define MYGL_FLOAT_VEC3_ARB 0x8B51 #define MYGL_FLOAT_VEC4_ARB 0x8B52 #define MYGL_INT_VEC2_ARB 0x8B53 #define MYGL_INT_VEC3_ARB 0x8B54 #define MYGL_INT_VEC4_ARB 0x8B55 #define MYGL_BOOL_ARB 0x8B56 #define MYGL_BOOL_VEC2_ARB 0x8B57 #define MYGL_BOOL_VEC3_ARB 0x8B58 #define MYGL_BOOL_VEC4_ARB 0x8B59 #define MYGL_FLOAT_MAT2_ARB 0x8B5A #define MYGL_FLOAT_MAT3_ARB 0x8B5B #define MYGL_FLOAT_MAT4_ARB 0x8B5C #define MYGL_SAMPLER_1D_ARB 0x8B5D #define MYGL_SAMPLER_2D_ARB 0x8B5E #define MYGL_SAMPLER_3D_ARB 0x8B5F #define MYGL_SAMPLER_CUBE_ARB 0x8B60 #define MYGL_SAMPLER_1D_SHADOW_ARB 0x8B61 #define MYGL_SAMPLER_2D_SHADOW_ARB 0x8B62 #define MYGL_SAMPLER_2D_RECT_ARB 0x8B63 #define MYGL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 #define MYGL_OBJECT_DELETE_STATUS_ARB 0x8B80 #define MYGL_OBJECT_COMPILE_STATUS_ARB 0x8B81 #define MYGL_OBJECT_LINK_STATUS_ARB 0x8B82 #define MYGL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 #define MYGL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 #define MYGL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 #define MYGL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 #define MYGL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 #define MYGL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 #endif #ifndef MYGL_ARB_vertex_shader #define MYGL_VERTEX_SHADER_ARB 0x8B31 #define MYGL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A #define MYGL_MAX_VARYING_FLOATS_ARB 0x8B4B #define MYGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C #define MYGL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D #define MYGL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 #define MYGL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A #endif #ifndef MYGL_ARB_fragment_shader #define MYGL_FRAGMENT_SHADER_ARB 0x8B30 #define MYGL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 #define MYGL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B #endif #ifndef MYGL_ARB_shading_language_100 #define MYGL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C #endif #ifndef MYGL_ARB_texture_non_power_of_two #endif #ifndef MYGL_ARB_point_sprite #define MYGL_POINT_SPRITE_ARB 0x8861 #define MYGL_COORD_REPLACE_ARB 0x8862 #endif #ifndef MYGL_ARB_fragment_program_shadow #endif #ifndef MYGL_ARB_draw_buffers #define MYGL_MAX_DRAW_BUFFERS_ARB 0x8824 #define MYGL_DRAW_BUFFER0_ARB 0x8825 #define MYGL_DRAW_BUFFER1_ARB 0x8826 #define MYGL_DRAW_BUFFER2_ARB 0x8827 #define MYGL_DRAW_BUFFER3_ARB 0x8828 #define MYGL_DRAW_BUFFER4_ARB 0x8829 #define MYGL_DRAW_BUFFER5_ARB 0x882A #define MYGL_DRAW_BUFFER6_ARB 0x882B #define MYGL_DRAW_BUFFER7_ARB 0x882C #define MYGL_DRAW_BUFFER8_ARB 0x882D #define MYGL_DRAW_BUFFER9_ARB 0x882E #define MYGL_DRAW_BUFFER10_ARB 0x882F #define MYGL_DRAW_BUFFER11_ARB 0x8830 #define MYGL_DRAW_BUFFER12_ARB 0x8831 #define MYGL_DRAW_BUFFER13_ARB 0x8832 #define MYGL_DRAW_BUFFER14_ARB 0x8833 #define MYGL_DRAW_BUFFER15_ARB 0x8834 #endif #ifndef MYGL_ARB_texture_rectangle #define MYGL_TEXTURE_RECTANGLE_ARB 0x84F5 #define MYGL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 #define MYGL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 #define MYGL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 #endif #ifndef MYGL_ARB_color_buffer_float #define MYGL_RGBA_FLOAT_MODE_ARB 0x8820 #define MYGL_CLAMP_VERTEX_COLOR_ARB 0x891A #define MYGL_CLAMP_FRAGMENT_COLOR_ARB 0x891B #define MYGL_CLAMP_READ_COLOR_ARB 0x891C #define MYGL_FIXED_ONLY_ARB 0x891D #endif #ifndef MYGL_ARB_half_float_pixel #define MYGL_HALF_FLOAT_ARB 0x140B #endif #ifndef MYGL_ARB_texture_float #define MYGL_TEXTURE_RED_TYPE_ARB 0x8C10 #define MYGL_TEXTURE_GREEN_TYPE_ARB 0x8C11 #define MYGL_TEXTURE_BLUE_TYPE_ARB 0x8C12 #define MYGL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 #define MYGL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 #define MYGL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 #define MYGL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 #define MYGL_UNSIGNED_NORMALIZED_ARB 0x8C17 #define MYGL_RGBA32F_ARB 0x8814 #define MYGL_RGB32F_ARB 0x8815 #define MYGL_ALPHA32F_ARB 0x8816 #define MYGL_INTENSITY32F_ARB 0x8817 #define MYGL_LUMINANCE32F_ARB 0x8818 #define MYGL_LUMINANCE_ALPHA32F_ARB 0x8819 #define MYGL_RGBA16F_ARB 0x881A #define MYGL_RGB16F_ARB 0x881B #define MYGL_ALPHA16F_ARB 0x881C #define MYGL_INTENSITY16F_ARB 0x881D #define MYGL_LUMINANCE16F_ARB 0x881E #define MYGL_LUMINANCE_ALPHA16F_ARB 0x881F #endif #ifndef MYGL_ARB_pixel_buffer_object #define MYGL_PIXEL_PACK_BUFFER_ARB 0x88EB #define MYGL_PIXEL_UNPACK_BUFFER_ARB 0x88EC #define MYGL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED #define MYGL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF #endif #ifndef MYGL_EXT_abgr #define MYGL_ABGR_EXT 0x8000 #endif #ifndef MYGL_EXT_blend_color #define MYGL_CONSTANT_COLOR_EXT 0x8001 #define MYGL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 #define MYGL_CONSTANT_ALPHA_EXT 0x8003 #define MYGL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 #define MYGL_BLEND_COLOR_EXT 0x8005 #endif #ifndef MYGL_EXT_polygon_offset #define MYGL_POLYGON_OFFSET_EXT 0x8037 #define MYGL_POLYGON_OFFSET_FACTOR_EXT 0x8038 #define MYGL_POLYGON_OFFSET_BIAS_EXT 0x8039 #endif #ifndef MYGL_EXT_texture #define MYGL_ALPHA4_EXT 0x803B #define MYGL_ALPHA8_EXT 0x803C #define MYGL_ALPHA12_EXT 0x803D #define MYGL_ALPHA16_EXT 0x803E #define MYGL_LUMINANCE4_EXT 0x803F #define MYGL_LUMINANCE8_EXT 0x8040 #define MYGL_LUMINANCE12_EXT 0x8041 #define MYGL_LUMINANCE16_EXT 0x8042 #define MYGL_LUMINANCE4_ALPHA4_EXT 0x8043 #define MYGL_LUMINANCE6_ALPHA2_EXT 0x8044 #define MYGL_LUMINANCE8_ALPHA8_EXT 0x8045 #define MYGL_LUMINANCE12_ALPHA4_EXT 0x8046 #define MYGL_LUMINANCE12_ALPHA12_EXT 0x8047 #define MYGL_LUMINANCE16_ALPHA16_EXT 0x8048 #define MYGL_INTENSITY_EXT 0x8049 #define MYGL_INTENSITY4_EXT 0x804A #define MYGL_INTENSITY8_EXT 0x804B #define MYGL_INTENSITY12_EXT 0x804C #define MYGL_INTENSITY16_EXT 0x804D #define MYGL_RGB2_EXT 0x804E #define MYGL_RGB4_EXT 0x804F #define MYGL_RGB5_EXT 0x8050 #define MYGL_RGB8_EXT 0x8051 #define MYGL_RGB10_EXT 0x8052 #define MYGL_RGB12_EXT 0x8053 #define MYGL_RGB16_EXT 0x8054 #define MYGL_RGBA2_EXT 0x8055 #define MYGL_RGBA4_EXT 0x8056 #define MYGL_RGB5_A1_EXT 0x8057 #define MYGL_RGBA8_EXT 0x8058 #define MYGL_RGB10_A2_EXT 0x8059 #define MYGL_RGBA12_EXT 0x805A #define MYGL_RGBA16_EXT 0x805B #define MYGL_TEXTURE_RED_SIZE_EXT 0x805C #define MYGL_TEXTURE_GREEN_SIZE_EXT 0x805D #define MYGL_TEXTURE_BLUE_SIZE_EXT 0x805E #define MYGL_TEXTURE_ALPHA_SIZE_EXT 0x805F #define MYGL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 #define MYGL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 #define MYGL_REPLACE_EXT 0x8062 #define MYGL_PROXY_TEXTURE_1D_EXT 0x8063 #define MYGL_PROXY_TEXTURE_2D_EXT 0x8064 #define MYGL_TEXTURE_TOO_LARGE_EXT 0x8065 #endif #ifndef MYGL_EXT_texture3D #define MYGL_PACK_SKIP_IMAGES_EXT 0x806B #define MYGL_PACK_IMAGE_HEIGHT_EXT 0x806C #define MYGL_UNPACK_SKIP_IMAGES_EXT 0x806D #define MYGL_UNPACK_IMAGE_HEIGHT_EXT 0x806E #define MYGL_TEXTURE_3D_EXT 0x806F #define MYGL_PROXY_TEXTURE_3D_EXT 0x8070 #define MYGL_TEXTURE_DEPTH_EXT 0x8071 #define MYGL_TEXTURE_WRAP_R_EXT 0x8072 #define MYGL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 #endif #ifndef MYGL_SGIS_texture_filter4 #define MYGL_FILTER4_SGIS 0x8146 #define MYGL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 #endif #ifndef MYGL_EXT_subtexture #endif #ifndef MYGL_EXT_copy_texture #endif #ifndef MYGL_EXT_histogram #define MYGL_HISTOGRAM_EXT 0x8024 #define MYGL_PROXY_HISTOGRAM_EXT 0x8025 #define MYGL_HISTOGRAM_WIDTH_EXT 0x8026 #define MYGL_HISTOGRAM_FORMAT_EXT 0x8027 #define MYGL_HISTOGRAM_RED_SIZE_EXT 0x8028 #define MYGL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 #define MYGL_HISTOGRAM_BLUE_SIZE_EXT 0x802A #define MYGL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B #define MYGL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C #define MYGL_HISTOGRAM_SINK_EXT 0x802D #define MYGL_MINMAX_EXT 0x802E #define MYGL_MINMAX_FORMAT_EXT 0x802F #define MYGL_MINMAX_SINK_EXT 0x8030 #define MYGL_TABLE_TOO_LARGE_EXT 0x8031 #endif #ifndef MYGL_EXT_convolution #define MYGL_CONVOLUTION_1D_EXT 0x8010 #define MYGL_CONVOLUTION_2D_EXT 0x8011 #define MYGL_SEPARABLE_2D_EXT 0x8012 #define MYGL_CONVOLUTION_BORDER_MODE_EXT 0x8013 #define MYGL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 #define MYGL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 #define MYGL_REDUCE_EXT 0x8016 #define MYGL_CONVOLUTION_FORMAT_EXT 0x8017 #define MYGL_CONVOLUTION_WIDTH_EXT 0x8018 #define MYGL_CONVOLUTION_HEIGHT_EXT 0x8019 #define MYGL_MAX_CONVOLUTION_WIDTH_EXT 0x801A #define MYGL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B #define MYGL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C #define MYGL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D #define MYGL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E #define MYGL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F #define MYGL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 #define MYGL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 #define MYGL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 #define MYGL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 #endif #ifndef MYGL_SGI_color_matrix #define MYGL_COLOR_MATRIX_SGI 0x80B1 #define MYGL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 #define MYGL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 #define MYGL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 #define MYGL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 #define MYGL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 #define MYGL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 #define MYGL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 #define MYGL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 #define MYGL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA #define MYGL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB #endif #ifndef MYGL_SGI_color_table #define MYGL_COLOR_TABLE_SGI 0x80D0 #define MYGL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 #define MYGL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 #define MYGL_PROXY_COLOR_TABLE_SGI 0x80D3 #define MYGL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 #define MYGL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 #define MYGL_COLOR_TABLE_SCALE_SGI 0x80D6 #define MYGL_COLOR_TABLE_BIAS_SGI 0x80D7 #define MYGL_COLOR_TABLE_FORMAT_SGI 0x80D8 #define MYGL_COLOR_TABLE_WIDTH_SGI 0x80D9 #define MYGL_COLOR_TABLE_RED_SIZE_SGI 0x80DA #define MYGL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB #define MYGL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC #define MYGL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD #define MYGL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE #define MYGL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF #endif #ifndef MYGL_SGIS_pixel_texture #define MYGL_PIXEL_TEXTURE_SGIS 0x8353 #define MYGL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 #define MYGL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 #define MYGL_PIXEL_GROUP_COLOR_SGIS 0x8356 #endif #ifndef MYGL_SGIX_pixel_texture #define MYGL_PIXEL_TEX_GEN_SGIX 0x8139 #define MYGL_PIXEL_TEX_GEN_MODE_SGIX 0x832B #endif #ifndef MYGL_SGIS_texture4D #define MYGL_PACK_SKIP_VOLUMES_SGIS 0x8130 #define MYGL_PACK_IMAGE_DEPTH_SGIS 0x8131 #define MYGL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 #define MYGL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 #define MYGL_TEXTURE_4D_SGIS 0x8134 #define MYGL_PROXY_TEXTURE_4D_SGIS 0x8135 #define MYGL_TEXTURE_4DSIZE_SGIS 0x8136 #define MYGL_TEXTURE_WRAP_Q_SGIS 0x8137 #define MYGL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 #define MYGL_TEXTURE_4D_BINDING_SGIS 0x814F #endif #ifndef MYGL_SGI_texture_color_table #define MYGL_TEXTURE_COLOR_TABLE_SGI 0x80BC #define MYGL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD #endif #ifndef MYGL_EXT_cmyka #define MYGL_CMYK_EXT 0x800C #define MYGL_CMYKA_EXT 0x800D #define MYGL_PACK_CMYK_HINT_EXT 0x800E #define MYGL_UNPACK_CMYK_HINT_EXT 0x800F #endif #ifndef MYGL_EXT_texture_object #define MYGL_TEXTURE_PRIORITY_EXT 0x8066 #define MYGL_TEXTURE_RESIDENT_EXT 0x8067 #define MYGL_TEXTURE_1D_BINDING_EXT 0x8068 #define MYGL_TEXTURE_2D_BINDING_EXT 0x8069 #define MYGL_TEXTURE_3D_BINDING_EXT 0x806A #endif #ifndef MYGL_SGIS_detail_texture #define MYGL_DETAIL_TEXTURE_2D_SGIS 0x8095 #define MYGL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 #define MYGL_LINEAR_DETAIL_SGIS 0x8097 #define MYGL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 #define MYGL_LINEAR_DETAIL_COLOR_SGIS 0x8099 #define MYGL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A #define MYGL_DETAIL_TEXTURE_MODE_SGIS 0x809B #define MYGL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C #endif #ifndef MYGL_SGIS_sharpen_texture #define MYGL_LINEAR_SHARPEN_SGIS 0x80AD #define MYGL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE #define MYGL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF #define MYGL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 #endif #ifndef MYGL_EXT_packed_pixels #define MYGL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 #define MYGL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 #define MYGL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 #define MYGL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 #define MYGL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 #endif #ifndef MYGL_SGIS_texture_lod #define MYGL_TEXTURE_MIN_LOD_SGIS 0x813A #define MYGL_TEXTURE_MAX_LOD_SGIS 0x813B #define MYGL_TEXTURE_BASE_LEVEL_SGIS 0x813C #define MYGL_TEXTURE_MAX_LEVEL_SGIS 0x813D #endif #ifndef MYGL_SGIS_multisample #define MYGL_MULTISAMPLE_SGIS 0x809D #define MYGL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E #define MYGL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F #define MYGL_SAMPLE_MASK_SGIS 0x80A0 #define MYGL_1PASS_SGIS 0x80A1 #define MYGL_2PASS_0_SGIS 0x80A2 #define MYGL_2PASS_1_SGIS 0x80A3 #define MYGL_4PASS_0_SGIS 0x80A4 #define MYGL_4PASS_1_SGIS 0x80A5 #define MYGL_4PASS_2_SGIS 0x80A6 #define MYGL_4PASS_3_SGIS 0x80A7 #define MYGL_SAMPLE_BUFFERS_SGIS 0x80A8 #define MYGL_SAMPLES_SGIS 0x80A9 #define MYGL_SAMPLE_MASK_VALUE_SGIS 0x80AA #define MYGL_SAMPLE_MASK_INVERT_SGIS 0x80AB #define MYGL_SAMPLE_PATTERN_SGIS 0x80AC #endif #ifndef MYGL_EXT_rescale_normal #define MYGL_RESCALE_NORMAL_EXT 0x803A #endif #ifndef MYGL_EXT_vertex_array #define MYGL_VERTEX_ARRAY_EXT 0x8074 #define MYGL_NORMAL_ARRAY_EXT 0x8075 #define MYGL_COLOR_ARRAY_EXT 0x8076 #define MYGL_INDEX_ARRAY_EXT 0x8077 #define MYGL_TEXTURE_COORD_ARRAY_EXT 0x8078 #define MYGL_EDGE_FLAG_ARRAY_EXT 0x8079 #define MYGL_VERTEX_ARRAY_SIZE_EXT 0x807A #define MYGL_VERTEX_ARRAY_TYPE_EXT 0x807B #define MYGL_VERTEX_ARRAY_STRIDE_EXT 0x807C #define MYGL_VERTEX_ARRAY_COUNT_EXT 0x807D #define MYGL_NORMAL_ARRAY_TYPE_EXT 0x807E #define MYGL_NORMAL_ARRAY_STRIDE_EXT 0x807F #define MYGL_NORMAL_ARRAY_COUNT_EXT 0x8080 #define MYGL_COLOR_ARRAY_SIZE_EXT 0x8081 #define MYGL_COLOR_ARRAY_TYPE_EXT 0x8082 #define MYGL_COLOR_ARRAY_STRIDE_EXT 0x8083 #define MYGL_COLOR_ARRAY_COUNT_EXT 0x8084 #define MYGL_INDEX_ARRAY_TYPE_EXT 0x8085 #define MYGL_INDEX_ARRAY_STRIDE_EXT 0x8086 #define MYGL_INDEX_ARRAY_COUNT_EXT 0x8087 #define MYGL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 #define MYGL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 #define MYGL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A #define MYGL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B #define MYGL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C #define MYGL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D #define MYGL_VERTEX_ARRAY_POINTER_EXT 0x808E #define MYGL_NORMAL_ARRAY_POINTER_EXT 0x808F #define MYGL_COLOR_ARRAY_POINTER_EXT 0x8090 #define MYGL_INDEX_ARRAY_POINTER_EXT 0x8091 #define MYGL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 #define MYGL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 #endif #ifndef MYGL_EXT_misc_attribute #endif #ifndef MYGL_SGIS_generate_mipmap #define MYGL_GENERATE_MIPMAP_SGIS 0x8191 #define MYGL_GENERATE_MIPMAP_HINT_SGIS 0x8192 #endif #ifndef MYGL_SGIX_clipmap #define MYGL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 #define MYGL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 #define MYGL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 #define MYGL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 #define MYGL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 #define MYGL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 #define MYGL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 #define MYGL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 #define MYGL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 #define MYGL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D #define MYGL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E #define MYGL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F #endif #ifndef MYGL_SGIX_shadow #define MYGL_TEXTURE_COMPARE_SGIX 0x819A #define MYGL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B #define MYGL_TEXTURE_LEQUAL_R_SGIX 0x819C #define MYGL_TEXTURE_GEQUAL_R_SGIX 0x819D #endif #ifndef MYGL_SGIS_texture_edge_clamp #define MYGL_CLAMP_TO_EDGE_SGIS 0x812F #endif #ifndef MYGL_SGIS_texture_border_clamp #define MYGL_CLAMP_TO_BORDER_SGIS 0x812D #endif #ifndef MYGL_EXT_blend_minmax #define MYGL_FUNC_ADD_EXT 0x8006 #define MYGL_MIN_EXT 0x8007 #define MYGL_MAX_EXT 0x8008 #define MYGL_BLEND_EQUATION_EXT 0x8009 #endif #ifndef MYGL_EXT_blend_subtract #define MYGL_FUNC_SUBTRACT_EXT 0x800A #define MYGL_FUNC_REVERSE_SUBTRACT_EXT 0x800B #endif #ifndef MYGL_EXT_blend_logic_op #endif #ifndef MYGL_SGIX_interlace #define MYGL_INTERLACE_SGIX 0x8094 #endif #ifndef MYGL_SGIX_pixel_tiles #define MYGL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E #define MYGL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F #define MYGL_PIXEL_TILE_WIDTH_SGIX 0x8140 #define MYGL_PIXEL_TILE_HEIGHT_SGIX 0x8141 #define MYGL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 #define MYGL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 #define MYGL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 #define MYGL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 #endif #ifndef MYGL_SGIS_texture_select #define MYGL_DUAL_ALPHA4_SGIS 0x8110 #define MYGL_DUAL_ALPHA8_SGIS 0x8111 #define MYGL_DUAL_ALPHA12_SGIS 0x8112 #define MYGL_DUAL_ALPHA16_SGIS 0x8113 #define MYGL_DUAL_LUMINANCE4_SGIS 0x8114 #define MYGL_DUAL_LUMINANCE8_SGIS 0x8115 #define MYGL_DUAL_LUMINANCE12_SGIS 0x8116 #define MYGL_DUAL_LUMINANCE16_SGIS 0x8117 #define MYGL_DUAL_INTENSITY4_SGIS 0x8118 #define MYGL_DUAL_INTENSITY8_SGIS 0x8119 #define MYGL_DUAL_INTENSITY12_SGIS 0x811A #define MYGL_DUAL_INTENSITY16_SGIS 0x811B #define MYGL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C #define MYGL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D #define MYGL_QUAD_ALPHA4_SGIS 0x811E #define MYGL_QUAD_ALPHA8_SGIS 0x811F #define MYGL_QUAD_LUMINANCE4_SGIS 0x8120 #define MYGL_QUAD_LUMINANCE8_SGIS 0x8121 #define MYGL_QUAD_INTENSITY4_SGIS 0x8122 #define MYGL_QUAD_INTENSITY8_SGIS 0x8123 #define MYGL_DUAL_TEXTURE_SELECT_SGIS 0x8124 #define MYGL_QUAD_TEXTURE_SELECT_SGIS 0x8125 #endif #ifndef MYGL_SGIX_sprite #define MYGL_SPRITE_SGIX 0x8148 #define MYGL_SPRITE_MODE_SGIX 0x8149 #define MYGL_SPRITE_AXIS_SGIX 0x814A #define MYGL_SPRITE_TRANSLATION_SGIX 0x814B #define MYGL_SPRITE_AXIAL_SGIX 0x814C #define MYGL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D #define MYGL_SPRITE_EYE_ALIGNED_SGIX 0x814E #endif #ifndef MYGL_SGIX_texture_multi_buffer #define MYGL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E #endif #ifndef MYGL_EXT_point_parameters #define MYGL_POINT_SIZE_MIN_EXT 0x8126 #define MYGL_POINT_SIZE_MAX_EXT 0x8127 #define MYGL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 #define MYGL_DISTANCE_ATTENUATION_EXT 0x8129 #endif #ifndef MYGL_SGIS_point_parameters #define MYGL_POINT_SIZE_MIN_SGIS 0x8126 #define MYGL_POINT_SIZE_MAX_SGIS 0x8127 #define MYGL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 #define MYGL_DISTANCE_ATTENUATION_SGIS 0x8129 #endif #ifndef MYGL_SGIX_instruments #define MYGL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 #define MYGL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 #endif #ifndef MYGL_SGIX_texture_scale_bias #define MYGL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 #define MYGL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A #define MYGL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B #define MYGL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C #endif #ifndef MYGL_SGIX_framezoom #define MYGL_FRAMEZOOM_SGIX 0x818B #define MYGL_FRAMEZOOM_FACTOR_SGIX 0x818C #define MYGL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D #endif #ifndef MYGL_SGIX_tag_sample_buffer #endif #ifndef MYGL_FfdMaskSGIX #define MYGL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 #define MYGL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 #endif #ifndef MYGL_SGIX_polynomial_ffd #define MYGL_GEOMETRY_DEFORMATION_SGIX 0x8194 #define MYGL_TEXTURE_DEFORMATION_SGIX 0x8195 #define MYGL_DEFORMATIONS_MASK_SGIX 0x8196 #define MYGL_MAX_DEFORMATION_ORDER_SGIX 0x8197 #endif #ifndef MYGL_SGIX_reference_plane #define MYGL_REFERENCE_PLANE_SGIX 0x817D #define MYGL_REFERENCE_PLANE_EQUATION_SGIX 0x817E #endif #ifndef MYGL_SGIX_flush_raster #endif #ifndef MYGL_SGIX_depth_texture #define MYGL_DEPTH_COMPONENT16_SGIX 0x81A5 #define MYGL_DEPTH_COMPONENT24_SGIX 0x81A6 #define MYGL_DEPTH_COMPONENT32_SGIX 0x81A7 #endif #ifndef MYGL_SGIS_fog_function #define MYGL_FOG_FUNC_SGIS 0x812A #define MYGL_FOG_FUNC_POINTS_SGIS 0x812B #define MYGL_MAX_FOG_FUNC_POINTS_SGIS 0x812C #endif #ifndef MYGL_SGIX_fog_offset #define MYGL_FOG_OFFSET_SGIX 0x8198 #define MYGL_FOG_OFFSET_VALUE_SGIX 0x8199 #endif #ifndef MYGL_HP_image_transform #define MYGL_IMAGE_SCALE_X_HP 0x8155 #define MYGL_IMAGE_SCALE_Y_HP 0x8156 #define MYGL_IMAGE_TRANSLATE_X_HP 0x8157 #define MYGL_IMAGE_TRANSLATE_Y_HP 0x8158 #define MYGL_IMAGE_ROTATE_ANGLE_HP 0x8159 #define MYGL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A #define MYGL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B #define MYGL_IMAGE_MAG_FILTER_HP 0x815C #define MYGL_IMAGE_MIN_FILTER_HP 0x815D #define MYGL_IMAGE_CUBIC_WEIGHT_HP 0x815E #define MYGL_CUBIC_HP 0x815F #define MYGL_AVERAGE_HP 0x8160 #define MYGL_IMAGE_TRANSFORM_2D_HP 0x8161 #define MYGL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 #define MYGL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 #endif #ifndef MYGL_HP_convolution_border_modes #define MYGL_IGNORE_BORDER_HP 0x8150 #define MYGL_CONSTANT_BORDER_HP 0x8151 #define MYGL_REPLICATE_BORDER_HP 0x8153 #define MYGL_CONVOLUTION_BORDER_COLOR_HP 0x8154 #endif #ifndef MYGL_INGR_palette_buffer #endif #ifndef MYGL_SGIX_texture_add_env #define MYGL_TEXTURE_ENV_BIAS_SGIX 0x80BE #endif #ifndef MYGL_EXT_color_subtable #endif #ifndef MYGL_PGI_vertex_hints #define MYGL_VERTEX_DATA_HINT_PGI 0x1A22A #define MYGL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B #define MYGL_MATERIAL_SIDE_HINT_PGI 0x1A22C #define MYGL_MAX_VERTEX_HINT_PGI 0x1A22D #define MYGL_COLOR3_BIT_PGI 0x00010000 #define MYGL_COLOR4_BIT_PGI 0x00020000 #define MYGL_EDGEFLAG_BIT_PGI 0x00040000 #define MYGL_INDEX_BIT_PGI 0x00080000 #define MYGL_MAT_AMBIENT_BIT_PGI 0x00100000 #define MYGL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 #define MYGL_MAT_DIFFUSE_BIT_PGI 0x00400000 #define MYGL_MAT_EMISSION_BIT_PGI 0x00800000 #define MYGL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 #define MYGL_MAT_SHININESS_BIT_PGI 0x02000000 #define MYGL_MAT_SPECULAR_BIT_PGI 0x04000000 #define MYGL_NORMAL_BIT_PGI 0x08000000 #define MYGL_TEXCOORD1_BIT_PGI 0x10000000 #define MYGL_TEXCOORD2_BIT_PGI 0x20000000 #define MYGL_TEXCOORD3_BIT_PGI 0x40000000 #define MYGL_TEXCOORD4_BIT_PGI 0x80000000 #define MYGL_VERTEX23_BIT_PGI 0x00000004 #define MYGL_VERTEX4_BIT_PGI 0x00000008 #endif #ifndef MYGL_PGI_misc_hints #define MYGL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 #define MYGL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD #define MYGL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE #define MYGL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 #define MYGL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 #define MYGL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 #define MYGL_ALWAYS_FAST_HINT_PGI 0x1A20C #define MYGL_ALWAYS_SOFT_HINT_PGI 0x1A20D #define MYGL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E #define MYGL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F #define MYGL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 #define MYGL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 #define MYGL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 #define MYGL_STRICT_LIGHTING_HINT_PGI 0x1A217 #define MYGL_STRICT_SCISSOR_HINT_PGI 0x1A218 #define MYGL_FULL_STIPPLE_HINT_PGI 0x1A219 #define MYGL_CLIP_NEAR_HINT_PGI 0x1A220 #define MYGL_CLIP_FAR_HINT_PGI 0x1A221 #define MYGL_WIDE_LINE_HINT_PGI 0x1A222 #define MYGL_BACK_NORMALS_HINT_PGI 0x1A223 #endif #ifndef MYGL_EXT_paletted_texture #define MYGL_COLOR_INDEX1_EXT 0x80E2 #define MYGL_COLOR_INDEX2_EXT 0x80E3 #define MYGL_COLOR_INDEX4_EXT 0x80E4 #define MYGL_COLOR_INDEX8_EXT 0x80E5 #define MYGL_COLOR_INDEX12_EXT 0x80E6 #define MYGL_COLOR_INDEX16_EXT 0x80E7 #define MYGL_TEXTURE_INDEX_SIZE_EXT 0x80ED #endif #ifndef MYGL_EXT_clip_volume_hint #define MYGL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 #endif #ifndef MYGL_SGIX_list_priority #define MYGL_LIST_PRIORITY_SGIX 0x8182 #endif #ifndef MYGL_SGIX_ir_instrument1 #define MYGL_IR_INSTRUMENT1_SGIX 0x817F #endif #ifndef MYGL_SGIX_calligraphic_fragment #define MYGL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 #endif #ifndef MYGL_SGIX_texture_lod_bias #define MYGL_TEXTURE_LOD_BIAS_S_SGIX 0x818E #define MYGL_TEXTURE_LOD_BIAS_T_SGIX 0x818F #define MYGL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 #endif #ifndef MYGL_SGIX_shadow_ambient #define MYGL_SHADOW_AMBIENT_SGIX 0x80BF #endif #ifndef MYGL_EXT_index_texture #endif #ifndef MYGL_EXT_index_material #define MYGL_INDEX_MATERIAL_EXT 0x81B8 #define MYGL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 #define MYGL_INDEX_MATERIAL_FACE_EXT 0x81BA #endif #ifndef MYGL_EXT_index_func #define MYGL_INDEX_TEST_EXT 0x81B5 #define MYGL_INDEX_TEST_FUNC_EXT 0x81B6 #define MYGL_INDEX_TEST_REF_EXT 0x81B7 #endif #ifndef MYGL_EXT_index_array_formats #define MYGL_IUI_V2F_EXT 0x81AD #define MYGL_IUI_V3F_EXT 0x81AE #define MYGL_IUI_N3F_V2F_EXT 0x81AF #define MYGL_IUI_N3F_V3F_EXT 0x81B0 #define MYGL_T2F_IUI_V2F_EXT 0x81B1 #define MYGL_T2F_IUI_V3F_EXT 0x81B2 #define MYGL_T2F_IUI_N3F_V2F_EXT 0x81B3 #define MYGL_T2F_IUI_N3F_V3F_EXT 0x81B4 #endif #ifndef MYGL_EXT_compiled_vertex_array #define MYGL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 #define MYGL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 #endif #ifndef MYGL_EXT_cull_vertex #define MYGL_CULL_VERTEX_EXT 0x81AA #define MYGL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB #define MYGL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC #endif #ifndef MYGL_SGIX_ycrcb #define MYGL_YCRCB_422_SGIX 0x81BB #define MYGL_YCRCB_444_SGIX 0x81BC #endif #ifndef MYGL_SGIX_fragment_lighting #define MYGL_FRAGMENT_LIGHTING_SGIX 0x8400 #define MYGL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 #define MYGL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 #define MYGL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 #define MYGL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 #define MYGL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 #define MYGL_CURRENT_RASTER_NORMAL_SGIX 0x8406 #define MYGL_LIGHT_ENV_MODE_SGIX 0x8407 #define MYGL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 #define MYGL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 #define MYGL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A #define MYGL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B #define MYGL_FRAGMENT_LIGHT0_SGIX 0x840C #define MYGL_FRAGMENT_LIGHT1_SGIX 0x840D #define MYGL_FRAGMENT_LIGHT2_SGIX 0x840E #define MYGL_FRAGMENT_LIGHT3_SGIX 0x840F #define MYGL_FRAGMENT_LIGHT4_SGIX 0x8410 #define MYGL_FRAGMENT_LIGHT5_SGIX 0x8411 #define MYGL_FRAGMENT_LIGHT6_SGIX 0x8412 #define MYGL_FRAGMENT_LIGHT7_SGIX 0x8413 #endif #ifndef MYGL_IBM_rasterpos_clip #define MYGL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 #endif #ifndef MYGL_HP_texture_lighting #define MYGL_TEXTURE_LIGHTING_MODE_HP 0x8167 #define MYGL_TEXTURE_POST_SPECULAR_HP 0x8168 #define MYGL_TEXTURE_PRE_SPECULAR_HP 0x8169 #endif #ifndef MYGL_EXT_draw_range_elements #define MYGL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 #define MYGL_MAX_ELEMENTS_INDICES_EXT 0x80E9 #endif #ifndef MYGL_WIN_phong_shading #define MYGL_PHONG_WIN 0x80EA #define MYGL_PHONG_HINT_WIN 0x80EB #endif #ifndef MYGL_WIN_specular_fog #define MYGL_FOG_SPECULAR_TEXTURE_WIN 0x80EC #endif #ifndef MYGL_EXT_light_texture #define MYGL_FRAGMENT_MATERIAL_EXT 0x8349 #define MYGL_FRAGMENT_NORMAL_EXT 0x834A #define MYGL_FRAGMENT_COLOR_EXT 0x834C #define MYGL_ATTENUATION_EXT 0x834D #define MYGL_SHADOW_ATTENUATION_EXT 0x834E #define MYGL_TEXTURE_APPLICATION_MODE_EXT 0x834F #define MYGL_TEXTURE_LIGHT_EXT 0x8350 #define MYGL_TEXTURE_MATERIAL_FACE_EXT 0x8351 #define MYGL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 /* reuse MYGL_FRAGMENT_DEPTH_EXT */ #endif #ifndef MYGL_SGIX_blend_alpha_minmax #define MYGL_ALPHA_MIN_SGIX 0x8320 #define MYGL_ALPHA_MAX_SGIX 0x8321 #endif #ifndef MYGL_SGIX_impact_pixel_texture #define MYGL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 #define MYGL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 #define MYGL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 #define MYGL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 #define MYGL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 #define MYGL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 #define MYGL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A #endif #ifndef MYGL_EXT_bgra #define MYGL_BGR_EXT 0x80E0 #define MYGL_BGRA_EXT 0x80E1 #endif #ifndef MYGL_SGIX_async #define MYGL_ASYNC_MARKER_SGIX 0x8329 #endif #ifndef MYGL_SGIX_async_pixel #define MYGL_ASYNC_TEX_IMAGE_SGIX 0x835C #define MYGL_ASYNC_DRAW_PIXELS_SGIX 0x835D #define MYGL_ASYNC_READ_PIXELS_SGIX 0x835E #define MYGL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F #define MYGL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 #define MYGL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 #endif #ifndef MYGL_SGIX_async_histogram #define MYGL_ASYNC_HISTOGRAM_SGIX 0x832C #define MYGL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D #endif #ifndef MYGL_INTEL_texture_scissor #endif #ifndef MYGL_INTEL_parallel_arrays #define MYGL_PARALLEL_ARRAYS_INTEL 0x83F4 #define MYGL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 #define MYGL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 #define MYGL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 #define MYGL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 #endif #ifndef MYGL_HP_occlusion_test #define MYGL_OCCLUSION_TEST_HP 0x8165 #define MYGL_OCCLUSION_TEST_RESULT_HP 0x8166 #endif #ifndef MYGL_EXT_pixel_transform #define MYGL_PIXEL_TRANSFORM_2D_EXT 0x8330 #define MYGL_PIXEL_MAG_FILTER_EXT 0x8331 #define MYGL_PIXEL_MIN_FILTER_EXT 0x8332 #define MYGL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 #define MYGL_CUBIC_EXT 0x8334 #define MYGL_AVERAGE_EXT 0x8335 #define MYGL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 #define MYGL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 #define MYGL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 #endif #ifndef MYGL_EXT_pixel_transform_color_table #endif #ifndef MYGL_EXT_shared_texture_palette #define MYGL_SHARED_TEXTURE_PALETTE_EXT 0x81FB #endif #ifndef MYGL_EXT_separate_specular_color #define MYGL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 #define MYGL_SINGLE_COLOR_EXT 0x81F9 #define MYGL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA #endif #ifndef MYGL_EXT_secondary_color #define MYGL_COLOR_SUM_EXT 0x8458 #define MYGL_CURRENT_SECONDARY_COLOR_EXT 0x8459 #define MYGL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A #define MYGL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B #define MYGL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C #define MYGL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D #define MYGL_SECONDARY_COLOR_ARRAY_EXT 0x845E #endif #ifndef MYGL_EXT_texture_perturb_normal #define MYGL_PERTURB_EXT 0x85AE #define MYGL_TEXTURE_NORMAL_EXT 0x85AF #endif #ifndef MYGL_EXT_multi_draw_arrays #endif #ifndef MYGL_EXT_fog_coord #define MYGL_FOG_COORDINATE_SOURCE_EXT 0x8450 #define MYGL_FOG_COORDINATE_EXT 0x8451 #define MYGL_FRAGMENT_DEPTH_EXT 0x8452 #define MYGL_CURRENT_FOG_COORDINATE_EXT 0x8453 #define MYGL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 #define MYGL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 #define MYGL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 #define MYGL_FOG_COORDINATE_ARRAY_EXT 0x8457 #endif #ifndef MYGL_REND_screen_coordinates #define MYGL_SCREEN_COORDINATES_REND 0x8490 #define MYGL_INVERTED_SCREEN_W_REND 0x8491 #endif #ifndef MYGL_EXT_coordinate_frame #define MYGL_TANGENT_ARRAY_EXT 0x8439 #define MYGL_BINORMAL_ARRAY_EXT 0x843A #define MYGL_CURRENT_TANGENT_EXT 0x843B #define MYGL_CURRENT_BINORMAL_EXT 0x843C #define MYGL_TANGENT_ARRAY_TYPE_EXT 0x843E #define MYGL_TANGENT_ARRAY_STRIDE_EXT 0x843F #define MYGL_BINORMAL_ARRAY_TYPE_EXT 0x8440 #define MYGL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 #define MYGL_TANGENT_ARRAY_POINTER_EXT 0x8442 #define MYGL_BINORMAL_ARRAY_POINTER_EXT 0x8443 #define MYGL_MAP1_TANGENT_EXT 0x8444 #define MYGL_MAP2_TANGENT_EXT 0x8445 #define MYGL_MAP1_BINORMAL_EXT 0x8446 #define MYGL_MAP2_BINORMAL_EXT 0x8447 #endif #ifndef MYGL_EXT_texture_env_combine #define MYGL_COMBINE_EXT 0x8570 #define MYGL_COMBINE_RGB_EXT 0x8571 #define MYGL_COMBINE_ALPHA_EXT 0x8572 #define MYGL_RGB_SCALE_EXT 0x8573 #define MYGL_ADD_SIGNED_EXT 0x8574 #define MYGL_INTERPOLATE_EXT 0x8575 #define MYGL_CONSTANT_EXT 0x8576 #define MYGL_PRIMARY_COLOR_EXT 0x8577 #define MYGL_PREVIOUS_EXT 0x8578 #define MYGL_SOURCE0_RGB_EXT 0x8580 #define MYGL_SOURCE1_RGB_EXT 0x8581 #define MYGL_SOURCE2_RGB_EXT 0x8582 #define MYGL_SOURCE0_ALPHA_EXT 0x8588 #define MYGL_SOURCE1_ALPHA_EXT 0x8589 #define MYGL_SOURCE2_ALPHA_EXT 0x858A #define MYGL_OPERAND0_RGB_EXT 0x8590 #define MYGL_OPERAND1_RGB_EXT 0x8591 #define MYGL_OPERAND2_RGB_EXT 0x8592 #define MYGL_OPERAND0_ALPHA_EXT 0x8598 #define MYGL_OPERAND1_ALPHA_EXT 0x8599 #define MYGL_OPERAND2_ALPHA_EXT 0x859A #endif #ifndef MYGL_APPLE_specular_vector #define MYGL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 #endif #ifndef MYGL_APPLE_transform_hint #define MYGL_TRANSFORM_HINT_APPLE 0x85B1 #endif #ifndef MYGL_SGIX_fog_scale #define MYGL_FOG_SCALE_SGIX 0x81FC #define MYGL_FOG_SCALE_VALUE_SGIX 0x81FD #endif #ifndef MYGL_SUNX_constant_data #define MYGL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 #define MYGL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 #endif #ifndef MYGL_SUN_global_alpha #define MYGL_GLOBAL_ALPHA_SUN 0x81D9 #define MYGL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA #endif #ifndef MYGL_SUN_triangle_list #define MYGL_RESTART_SUN 0x0001 #define MYGL_REPLACE_MIDDLE_SUN 0x0002 #define MYGL_REPLACE_OLDEST_SUN 0x0003 #define MYGL_TRIANGLE_LIST_SUN 0x81D7 #define MYGL_REPLACEMENT_CODE_SUN 0x81D8 #define MYGL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 #define MYGL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 #define MYGL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 #define MYGL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 #define MYGL_R1UI_V3F_SUN 0x85C4 #define MYGL_R1UI_C4UB_V3F_SUN 0x85C5 #define MYGL_R1UI_C3F_V3F_SUN 0x85C6 #define MYGL_R1UI_N3F_V3F_SUN 0x85C7 #define MYGL_R1UI_C4F_N3F_V3F_SUN 0x85C8 #define MYGL_R1UI_T2F_V3F_SUN 0x85C9 #define MYGL_R1UI_T2F_N3F_V3F_SUN 0x85CA #define MYGL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB #endif #ifndef MYGL_SUN_vertex #endif #ifndef MYGL_EXT_blend_func_separate #define MYGL_BLEND_DST_RGB_EXT 0x80C8 #define MYGL_BLEND_SRC_RGB_EXT 0x80C9 #define MYGL_BLEND_DST_ALPHA_EXT 0x80CA #define MYGL_BLEND_SRC_ALPHA_EXT 0x80CB #endif #ifndef MYGL_INGR_color_clamp #define MYGL_RED_MIN_CLAMP_INGR 0x8560 #define MYGL_GREEN_MIN_CLAMP_INGR 0x8561 #define MYGL_BLUE_MIN_CLAMP_INGR 0x8562 #define MYGL_ALPHA_MIN_CLAMP_INGR 0x8563 #define MYGL_RED_MAX_CLAMP_INGR 0x8564 #define MYGL_GREEN_MAX_CLAMP_INGR 0x8565 #define MYGL_BLUE_MAX_CLAMP_INGR 0x8566 #define MYGL_ALPHA_MAX_CLAMP_INGR 0x8567 #endif #ifndef MYGL_INGR_interlace_read #define MYGL_INTERLACE_READ_INGR 0x8568 #endif #ifndef MYGL_EXT_stencil_wrap #define MYGL_INCR_WRAP_EXT 0x8507 #define MYGL_DECR_WRAP_EXT 0x8508 #endif #ifndef MYGL_EXT_422_pixels #define MYGL_422_EXT 0x80CC #define MYGL_422_REV_EXT 0x80CD #define MYGL_422_AVERAGE_EXT 0x80CE #define MYGL_422_REV_AVERAGE_EXT 0x80CF #endif #ifndef MYGL_NV_texgen_reflection #define MYGL_NORMAL_MAP_NV 0x8511 #define MYGL_REFLECTION_MAP_NV 0x8512 #endif #ifndef MYGL_EXT_texture_cube_map #define MYGL_NORMAL_MAP_EXT 0x8511 #define MYGL_REFLECTION_MAP_EXT 0x8512 #define MYGL_TEXTURE_CUBE_MAP_EXT 0x8513 #define MYGL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 #define MYGL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 #define MYGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A #define MYGL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B #define MYGL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C #endif #ifndef MYGL_SUN_convolution_border_modes #define MYGL_WRAP_BORDER_SUN 0x81D4 #endif #ifndef MYGL_EXT_texture_env_add #endif #ifndef MYGL_EXT_texture_lod_bias #define MYGL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD #define MYGL_TEXTURE_FILTER_CONTROL_EXT 0x8500 #define MYGL_TEXTURE_LOD_BIAS_EXT 0x8501 #endif #ifndef MYGL_EXT_texture_filter_anisotropic #define MYGL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE #define MYGL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF #endif #ifndef MYGL_EXT_vertex_weighting #define MYGL_MODELVIEW0_STACK_DEPTH_EXT MYGL_MODELVIEW_STACK_DEPTH #define MYGL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 #define MYGL_MODELVIEW0_MATRIX_EXT MYGL_MODELVIEW_MATRIX #define MYGL_MODELVIEW1_MATRIX_EXT 0x8506 #define MYGL_VERTEX_WEIGHTING_EXT 0x8509 #define MYGL_MODELVIEW0_EXT MYGL_MODELVIEW #define MYGL_MODELVIEW1_EXT 0x850A #define MYGL_CURRENT_VERTEX_WEIGHT_EXT 0x850B #define MYGL_VERTEX_WEIGHT_ARRAY_EXT 0x850C #define MYGL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D #define MYGL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E #define MYGL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F #define MYGL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 #endif #ifndef MYGL_NV_light_max_exponent #define MYGL_MAX_SHININESS_NV 0x8504 #define MYGL_MAX_SPOT_EXPONENT_NV 0x8505 #endif #ifndef MYGL_NV_vertex_array_range #define MYGL_VERTEX_ARRAY_RANGE_NV 0x851D #define MYGL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E #define MYGL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F #define MYGL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 #define MYGL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 #endif #ifndef MYGL_NV_register_combiners #define MYGL_REGISTER_COMBINERS_NV 0x8522 #define MYGL_VARIABLE_A_NV 0x8523 #define MYGL_VARIABLE_B_NV 0x8524 #define MYGL_VARIABLE_C_NV 0x8525 #define MYGL_VARIABLE_D_NV 0x8526 #define MYGL_VARIABLE_E_NV 0x8527 #define MYGL_VARIABLE_F_NV 0x8528 #define MYGL_VARIABLE_G_NV 0x8529 #define MYGL_CONSTANT_COLOR0_NV 0x852A #define MYGL_CONSTANT_COLOR1_NV 0x852B #define MYGL_PRIMARY_COLOR_NV 0x852C #define MYGL_SECONDARY_COLOR_NV 0x852D #define MYGL_SPARE0_NV 0x852E #define MYGL_SPARE1_NV 0x852F #define MYGL_DISCARD_NV 0x8530 #define MYGL_E_TIMES_F_NV 0x8531 #define MYGL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 #define MYGL_UNSIGNED_IDENTITY_NV 0x8536 #define MYGL_UNSIGNED_INVERT_NV 0x8537 #define MYGL_EXPAND_NORMAL_NV 0x8538 #define MYGL_EXPAND_NEGATE_NV 0x8539 #define MYGL_HALF_BIAS_NORMAL_NV 0x853A #define MYGL_HALF_BIAS_NEGATE_NV 0x853B #define MYGL_SIGNED_IDENTITY_NV 0x853C #define MYGL_SIGNED_NEGATE_NV 0x853D #define MYGL_SCALE_BY_TWO_NV 0x853E #define MYGL_SCALE_BY_FOUR_NV 0x853F #define MYGL_SCALE_BY_ONE_HALF_NV 0x8540 #define MYGL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 #define MYGL_COMBINER_INPUT_NV 0x8542 #define MYGL_COMBINER_MAPPING_NV 0x8543 #define MYGL_COMBINER_COMPONENT_USAGE_NV 0x8544 #define MYGL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 #define MYGL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 #define MYGL_COMBINER_MUX_SUM_NV 0x8547 #define MYGL_COMBINER_SCALE_NV 0x8548 #define MYGL_COMBINER_BIAS_NV 0x8549 #define MYGL_COMBINER_AB_OUTPUT_NV 0x854A #define MYGL_COMBINER_CD_OUTPUT_NV 0x854B #define MYGL_COMBINER_SUM_OUTPUT_NV 0x854C #define MYGL_MAX_GENERAL_COMBINERS_NV 0x854D #define MYGL_NUM_GENERAL_COMBINERS_NV 0x854E #define MYGL_COLOR_SUM_CLAMP_NV 0x854F #define MYGL_COMBINER0_NV 0x8550 #define MYGL_COMBINER1_NV 0x8551 #define MYGL_COMBINER2_NV 0x8552 #define MYGL_COMBINER3_NV 0x8553 #define MYGL_COMBINER4_NV 0x8554 #define MYGL_COMBINER5_NV 0x8555 #define MYGL_COMBINER6_NV 0x8556 #define MYGL_COMBINER7_NV 0x8557 /* reuse MYGL_TEXTURE0_ARB */ /* reuse MYGL_TEXTURE1_ARB */ /* reuse MYGL_ZERO */ /* reuse MYGL_NONE */ /* reuse MYGL_FOG */ #endif #ifndef MYGL_NV_fog_distance #define MYGL_FOG_DISTANCE_MODE_NV 0x855A #define MYGL_EYE_RADIAL_NV 0x855B #define MYGL_EYE_PLANE_ABSOLUTE_NV 0x855C /* reuse MYGL_EYE_PLANE */ #endif #ifndef MYGL_NV_texgen_emboss #define MYGL_EMBOSS_LIGHT_NV 0x855D #define MYGL_EMBOSS_CONSTANT_NV 0x855E #define MYGL_EMBOSS_MAP_NV 0x855F #endif #ifndef MYGL_NV_blend_square #endif #ifndef MYGL_NV_texture_env_combine4 #define MYGL_COMBINE4_NV 0x8503 #define MYGL_SOURCE3_RGB_NV 0x8583 #define MYGL_SOURCE3_ALPHA_NV 0x858B #define MYGL_OPERAND3_RGB_NV 0x8593 #define MYGL_OPERAND3_ALPHA_NV 0x859B #endif #ifndef MYGL_MESA_resize_buffers #endif #ifndef MYGL_MESA_window_pos #endif #ifndef MYGL_EXT_texture_compression_s3tc #define MYGL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 #define MYGL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 #define MYGL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 #define MYGL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 #endif #ifndef MYGL_IBM_cull_vertex #define MYGL_CULL_VERTEX_IBM 103050 #endif #ifndef MYGL_IBM_multimode_draw_arrays #endif #ifndef MYGL_IBM_vertex_array_lists #define MYGL_VERTEX_ARRAY_LIST_IBM 103070 #define MYGL_NORMAL_ARRAY_LIST_IBM 103071 #define MYGL_COLOR_ARRAY_LIST_IBM 103072 #define MYGL_INDEX_ARRAY_LIST_IBM 103073 #define MYGL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 #define MYGL_EDGE_FLAG_ARRAY_LIST_IBM 103075 #define MYGL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 #define MYGL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 #define MYGL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 #define MYGL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 #define MYGL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 #define MYGL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 #define MYGL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 #define MYGL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 #define MYGL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 #define MYGL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 #endif #ifndef MYGL_SGIX_subsample #define MYGL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 #define MYGL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 #define MYGL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 #define MYGL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 #define MYGL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 #endif #ifndef MYGL_SGIX_ycrcb_subsample #endif #ifndef MYGL_SGIX_ycrcba #define MYGL_YCRCB_SGIX 0x8318 #define MYGL_YCRCBA_SGIX 0x8319 #endif #ifndef MYGL_SGI_depth_pass_instrument #define MYGL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 #define MYGL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 #define MYGL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 #endif #ifndef MYGL_3DFX_texture_compression_FXT1 #define MYGL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 #define MYGL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 #endif #ifndef MYGL_3DFX_multisample #define MYGL_MULTISAMPLE_3DFX 0x86B2 #define MYGL_SAMPLE_BUFFERS_3DFX 0x86B3 #define MYGL_SAMPLES_3DFX 0x86B4 #define MYGL_MULTISAMPLE_BIT_3DFX 0x20000000 #endif #ifndef MYGL_3DFX_tbuffer #endif #ifndef MYGL_EXT_multisample #define MYGL_MULTISAMPLE_EXT 0x809D #define MYGL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E #define MYGL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F #define MYGL_SAMPLE_MASK_EXT 0x80A0 #define MYGL_1PASS_EXT 0x80A1 #define MYGL_2PASS_0_EXT 0x80A2 #define MYGL_2PASS_1_EXT 0x80A3 #define MYGL_4PASS_0_EXT 0x80A4 #define MYGL_4PASS_1_EXT 0x80A5 #define MYGL_4PASS_2_EXT 0x80A6 #define MYGL_4PASS_3_EXT 0x80A7 #define MYGL_SAMPLE_BUFFERS_EXT 0x80A8 #define MYGL_SAMPLES_EXT 0x80A9 #define MYGL_SAMPLE_MASK_VALUE_EXT 0x80AA #define MYGL_SAMPLE_MASK_INVERT_EXT 0x80AB #define MYGL_SAMPLE_PATTERN_EXT 0x80AC #define MYGL_MULTISAMPLE_BIT_EXT 0x20000000 #endif #ifndef MYGL_SGIX_vertex_preclip #define MYGL_VERTEX_PRECLIP_SGIX 0x83EE #define MYGL_VERTEX_PRECLIP_HINT_SGIX 0x83EF #endif #ifndef MYGL_SGIX_convolution_accuracy #define MYGL_CONVOLUTION_HINT_SGIX 0x8316 #endif #ifndef MYGL_SGIX_resample #define MYGL_PACK_RESAMPLE_SGIX 0x842C #define MYGL_UNPACK_RESAMPLE_SGIX 0x842D #define MYGL_RESAMPLE_REPLICATE_SGIX 0x842E #define MYGL_RESAMPLE_ZERO_FILL_SGIX 0x842F #define MYGL_RESAMPLE_DECIMATE_SGIX 0x8430 #endif #ifndef MYGL_SGIS_point_line_texgen #define MYGL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 #define MYGL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 #define MYGL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 #define MYGL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 #define MYGL_EYE_POINT_SGIS 0x81F4 #define MYGL_OBJECT_POINT_SGIS 0x81F5 #define MYGL_EYE_LINE_SGIS 0x81F6 #define MYGL_OBJECT_LINE_SGIS 0x81F7 #endif #ifndef MYGL_SGIS_texture_color_mask #define MYGL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF #endif #ifndef MYGL_EXT_texture_env_dot3 #define MYGL_DOT3_RGB_EXT 0x8740 #define MYGL_DOT3_RGBA_EXT 0x8741 #endif #ifndef MYGL_ATI_texture_mirror_once #define MYGL_MIRROR_CLAMP_ATI 0x8742 #define MYGL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 #endif #ifndef MYGL_NV_fence #define MYGL_ALL_COMPLETED_NV 0x84F2 #define MYGL_FENCE_STATUS_NV 0x84F3 #define MYGL_FENCE_CONDITION_NV 0x84F4 #endif #ifndef MYGL_IBM_texture_mirrored_repeat #define MYGL_MIRRORED_REPEAT_IBM 0x8370 #endif #ifndef MYGL_NV_evaluators #define MYGL_EVAL_2D_NV 0x86C0 #define MYGL_EVAL_TRIANGULAR_2D_NV 0x86C1 #define MYGL_MAP_TESSELLATION_NV 0x86C2 #define MYGL_MAP_ATTRIB_U_ORDER_NV 0x86C3 #define MYGL_MAP_ATTRIB_V_ORDER_NV 0x86C4 #define MYGL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 #define MYGL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 #define MYGL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 #define MYGL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 #define MYGL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 #define MYGL_EVAL_VERTEX_ATTRIB4_NV 0x86CA #define MYGL_EVAL_VERTEX_ATTRIB5_NV 0x86CB #define MYGL_EVAL_VERTEX_ATTRIB6_NV 0x86CC #define MYGL_EVAL_VERTEX_ATTRIB7_NV 0x86CD #define MYGL_EVAL_VERTEX_ATTRIB8_NV 0x86CE #define MYGL_EVAL_VERTEX_ATTRIB9_NV 0x86CF #define MYGL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 #define MYGL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 #define MYGL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 #define MYGL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 #define MYGL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 #define MYGL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 #define MYGL_MAX_MAP_TESSELLATION_NV 0x86D6 #define MYGL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 #endif #ifndef MYGL_NV_packed_depth_stencil #define MYGL_DEPTH_STENCIL_NV 0x84F9 #define MYGL_UNSIGNED_INT_24_8_NV 0x84FA #endif #ifndef MYGL_NV_register_combiners2 #define MYGL_PER_STAGE_CONSTANTS_NV 0x8535 #endif #ifndef MYGL_NV_texture_compression_vtc #endif #ifndef MYGL_NV_texture_rectangle #define MYGL_TEXTURE_RECTANGLE_NV 0x84F5 #define MYGL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 #define MYGL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 #define MYGL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 #endif #ifndef MYGL_NV_texture_shader #define MYGL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C #define MYGL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D #define MYGL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E #define MYGL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 #define MYGL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA #define MYGL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB #define MYGL_DSDT_MAG_INTENSITY_NV 0x86DC #define MYGL_SHADER_CONSISTENT_NV 0x86DD #define MYGL_TEXTURE_SHADER_NV 0x86DE #define MYGL_SHADER_OPERATION_NV 0x86DF #define MYGL_CULL_MODES_NV 0x86E0 #define MYGL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 #define MYGL_OFFSET_TEXTURE_SCALE_NV 0x86E2 #define MYGL_OFFSET_TEXTURE_BIAS_NV 0x86E3 #define MYGL_OFFSET_TEXTURE_2D_MATRIX_NV MYGL_OFFSET_TEXTURE_MATRIX_NV #define MYGL_OFFSET_TEXTURE_2D_SCALE_NV MYGL_OFFSET_TEXTURE_SCALE_NV #define MYGL_OFFSET_TEXTURE_2D_BIAS_NV MYGL_OFFSET_TEXTURE_BIAS_NV #define MYGL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 #define MYGL_CONST_EYE_NV 0x86E5 #define MYGL_PASS_THROUGH_NV 0x86E6 #define MYGL_CULL_FRAGMENT_NV 0x86E7 #define MYGL_OFFSET_TEXTURE_2D_NV 0x86E8 #define MYGL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 #define MYGL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA #define MYGL_DOT_PRODUCT_NV 0x86EC #define MYGL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED #define MYGL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE #define MYGL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 #define MYGL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 #define MYGL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 #define MYGL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 #define MYGL_HILO_NV 0x86F4 #define MYGL_DSDT_NV 0x86F5 #define MYGL_DSDT_MAG_NV 0x86F6 #define MYGL_DSDT_MAG_VIB_NV 0x86F7 #define MYGL_HILO16_NV 0x86F8 #define MYGL_SIGNED_HILO_NV 0x86F9 #define MYGL_SIGNED_HILO16_NV 0x86FA #define MYGL_SIGNED_RGBA_NV 0x86FB #define MYGL_SIGNED_RGBA8_NV 0x86FC #define MYGL_SIGNED_RGB_NV 0x86FE #define MYGL_SIGNED_RGB8_NV 0x86FF #define MYGL_SIGNED_LUMINANCE_NV 0x8701 #define MYGL_SIGNED_LUMINANCE8_NV 0x8702 #define MYGL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 #define MYGL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 #define MYGL_SIGNED_ALPHA_NV 0x8705 #define MYGL_SIGNED_ALPHA8_NV 0x8706 #define MYGL_SIGNED_INTENSITY_NV 0x8707 #define MYGL_SIGNED_INTENSITY8_NV 0x8708 #define MYGL_DSDT8_NV 0x8709 #define MYGL_DSDT8_MAG8_NV 0x870A #define MYGL_DSDT8_MAG8_INTENSITY8_NV 0x870B #define MYGL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C #define MYGL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D #define MYGL_HI_SCALE_NV 0x870E #define MYGL_LO_SCALE_NV 0x870F #define MYGL_DS_SCALE_NV 0x8710 #define MYGL_DT_SCALE_NV 0x8711 #define MYGL_MAGNITUDE_SCALE_NV 0x8712 #define MYGL_VIBRANCE_SCALE_NV 0x8713 #define MYGL_HI_BIAS_NV 0x8714 #define MYGL_LO_BIAS_NV 0x8715 #define MYGL_DS_BIAS_NV 0x8716 #define MYGL_DT_BIAS_NV 0x8717 #define MYGL_MAGNITUDE_BIAS_NV 0x8718 #define MYGL_VIBRANCE_BIAS_NV 0x8719 #define MYGL_TEXTURE_BORDER_VALUES_NV 0x871A #define MYGL_TEXTURE_HI_SIZE_NV 0x871B #define MYGL_TEXTURE_LO_SIZE_NV 0x871C #define MYGL_TEXTURE_DS_SIZE_NV 0x871D #define MYGL_TEXTURE_DT_SIZE_NV 0x871E #define MYGL_TEXTURE_MAG_SIZE_NV 0x871F #endif #ifndef MYGL_NV_texture_shader2 #define MYGL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF #endif #ifndef MYGL_NV_vertex_array_range2 #define MYGL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 #endif #ifndef MYGL_NV_vertex_program #define MYGL_VERTEX_PROGRAM_NV 0x8620 #define MYGL_VERTEX_STATE_PROGRAM_NV 0x8621 #define MYGL_ATTRIB_ARRAY_SIZE_NV 0x8623 #define MYGL_ATTRIB_ARRAY_STRIDE_NV 0x8624 #define MYGL_ATTRIB_ARRAY_TYPE_NV 0x8625 #define MYGL_CURRENT_ATTRIB_NV 0x8626 #define MYGL_PROGRAM_LENGTH_NV 0x8627 #define MYGL_PROGRAM_STRING_NV 0x8628 #define MYGL_MODELVIEW_PROJECTION_NV 0x8629 #define MYGL_IDENTITY_NV 0x862A #define MYGL_INVERSE_NV 0x862B #define MYGL_TRANSPOSE_NV 0x862C #define MYGL_INVERSE_TRANSPOSE_NV 0x862D #define MYGL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E #define MYGL_MAX_TRACK_MATRICES_NV 0x862F #define MYGL_MATRIX0_NV 0x8630 #define MYGL_MATRIX1_NV 0x8631 #define MYGL_MATRIX2_NV 0x8632 #define MYGL_MATRIX3_NV 0x8633 #define MYGL_MATRIX4_NV 0x8634 #define MYGL_MATRIX5_NV 0x8635 #define MYGL_MATRIX6_NV 0x8636 #define MYGL_MATRIX7_NV 0x8637 #define MYGL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 #define MYGL_CURRENT_MATRIX_NV 0x8641 #define MYGL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 #define MYGL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 #define MYGL_PROGRAM_PARAMETER_NV 0x8644 #define MYGL_ATTRIB_ARRAY_POINTER_NV 0x8645 #define MYGL_PROGRAM_TARGET_NV 0x8646 #define MYGL_PROGRAM_RESIDENT_NV 0x8647 #define MYGL_TRACK_MATRIX_NV 0x8648 #define MYGL_TRACK_MATRIX_TRANSFORM_NV 0x8649 #define MYGL_VERTEX_PROGRAM_BINDING_NV 0x864A #define MYGL_PROGRAM_ERROR_POSITION_NV 0x864B #define MYGL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 #define MYGL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 #define MYGL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 #define MYGL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 #define MYGL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 #define MYGL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 #define MYGL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 #define MYGL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 #define MYGL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 #define MYGL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 #define MYGL_VERTEX_ATTRIB_ARRAY10_NV 0x865A #define MYGL_VERTEX_ATTRIB_ARRAY11_NV 0x865B #define MYGL_VERTEX_ATTRIB_ARRAY12_NV 0x865C #define MYGL_VERTEX_ATTRIB_ARRAY13_NV 0x865D #define MYGL_VERTEX_ATTRIB_ARRAY14_NV 0x865E #define MYGL_VERTEX_ATTRIB_ARRAY15_NV 0x865F #define MYGL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 #define MYGL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 #define MYGL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 #define MYGL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 #define MYGL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 #define MYGL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 #define MYGL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 #define MYGL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 #define MYGL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 #define MYGL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 #define MYGL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A #define MYGL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B #define MYGL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C #define MYGL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D #define MYGL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E #define MYGL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F #define MYGL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 #define MYGL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 #define MYGL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 #define MYGL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 #define MYGL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 #define MYGL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 #define MYGL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 #define MYGL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 #define MYGL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 #define MYGL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 #define MYGL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A #define MYGL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B #define MYGL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C #define MYGL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D #define MYGL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E #define MYGL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F #endif #ifndef MYGL_SGIX_texture_coordinate_clamp #define MYGL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 #define MYGL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A #define MYGL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B #endif #ifndef MYGL_SGIX_scalebias_hint #define MYGL_SCALEBIAS_HINT_SGIX 0x8322 #endif #ifndef MYGL_OML_interlace #define MYGL_INTERLACE_OML 0x8980 #define MYGL_INTERLACE_READ_OML 0x8981 #endif #ifndef MYGL_OML_subsample #define MYGL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 #define MYGL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 #endif #ifndef MYGL_OML_resample #define MYGL_PACK_RESAMPLE_OML 0x8984 #define MYGL_UNPACK_RESAMPLE_OML 0x8985 #define MYGL_RESAMPLE_REPLICATE_OML 0x8986 #define MYGL_RESAMPLE_ZERO_FILL_OML 0x8987 #define MYGL_RESAMPLE_AVERAGE_OML 0x8988 #define MYGL_RESAMPLE_DECIMATE_OML 0x8989 #endif #ifndef MYGL_NV_copy_depth_to_color #define MYGL_DEPTH_STENCIL_TO_RGBA_NV 0x886E #define MYGL_DEPTH_STENCIL_TO_BGRA_NV 0x886F #endif #ifndef MYGL_ATI_envmap_bumpmap #define MYGL_BUMP_ROT_MATRIX_ATI 0x8775 #define MYGL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 #define MYGL_BUMP_NUM_TEX_UNITS_ATI 0x8777 #define MYGL_BUMP_TEX_UNITS_ATI 0x8778 #define MYGL_DUDV_ATI 0x8779 #define MYGL_DU8DV8_ATI 0x877A #define MYGL_BUMP_ENVMAP_ATI 0x877B #define MYGL_BUMP_TARGET_ATI 0x877C #endif #ifndef MYGL_ATI_fragment_shader #define MYGL_FRAGMENT_SHADER_ATI 0x8920 #define MYGL_REG_0_ATI 0x8921 #define MYGL_REG_1_ATI 0x8922 #define MYGL_REG_2_ATI 0x8923 #define MYGL_REG_3_ATI 0x8924 #define MYGL_REG_4_ATI 0x8925 #define MYGL_REG_5_ATI 0x8926 #define MYGL_REG_6_ATI 0x8927 #define MYGL_REG_7_ATI 0x8928 #define MYGL_REG_8_ATI 0x8929 #define MYGL_REG_9_ATI 0x892A #define MYGL_REG_10_ATI 0x892B #define MYGL_REG_11_ATI 0x892C #define MYGL_REG_12_ATI 0x892D #define MYGL_REG_13_ATI 0x892E #define MYGL_REG_14_ATI 0x892F #define MYGL_REG_15_ATI 0x8930 #define MYGL_REG_16_ATI 0x8931 #define MYGL_REG_17_ATI 0x8932 #define MYGL_REG_18_ATI 0x8933 #define MYGL_REG_19_ATI 0x8934 #define MYGL_REG_20_ATI 0x8935 #define MYGL_REG_21_ATI 0x8936 #define MYGL_REG_22_ATI 0x8937 #define MYGL_REG_23_ATI 0x8938 #define MYGL_REG_24_ATI 0x8939 #define MYGL_REG_25_ATI 0x893A #define MYGL_REG_26_ATI 0x893B #define MYGL_REG_27_ATI 0x893C #define MYGL_REG_28_ATI 0x893D #define MYGL_REG_29_ATI 0x893E #define MYGL_REG_30_ATI 0x893F #define MYGL_REG_31_ATI 0x8940 #define MYGL_CON_0_ATI 0x8941 #define MYGL_CON_1_ATI 0x8942 #define MYGL_CON_2_ATI 0x8943 #define MYGL_CON_3_ATI 0x8944 #define MYGL_CON_4_ATI 0x8945 #define MYGL_CON_5_ATI 0x8946 #define MYGL_CON_6_ATI 0x8947 #define MYGL_CON_7_ATI 0x8948 #define MYGL_CON_8_ATI 0x8949 #define MYGL_CON_9_ATI 0x894A #define MYGL_CON_10_ATI 0x894B #define MYGL_CON_11_ATI 0x894C #define MYGL_CON_12_ATI 0x894D #define MYGL_CON_13_ATI 0x894E #define MYGL_CON_14_ATI 0x894F #define MYGL_CON_15_ATI 0x8950 #define MYGL_CON_16_ATI 0x8951 #define MYGL_CON_17_ATI 0x8952 #define MYGL_CON_18_ATI 0x8953 #define MYGL_CON_19_ATI 0x8954 #define MYGL_CON_20_ATI 0x8955 #define MYGL_CON_21_ATI 0x8956 #define MYGL_CON_22_ATI 0x8957 #define MYGL_CON_23_ATI 0x8958 #define MYGL_CON_24_ATI 0x8959 #define MYGL_CON_25_ATI 0x895A #define MYGL_CON_26_ATI 0x895B #define MYGL_CON_27_ATI 0x895C #define MYGL_CON_28_ATI 0x895D #define MYGL_CON_29_ATI 0x895E #define MYGL_CON_30_ATI 0x895F #define MYGL_CON_31_ATI 0x8960 #define MYGL_MOV_ATI 0x8961 #define MYGL_ADD_ATI 0x8963 #define MYGL_MUL_ATI 0x8964 #define MYGL_SUB_ATI 0x8965 #define MYGL_DOT3_ATI 0x8966 #define MYGL_DOT4_ATI 0x8967 #define MYGL_MAD_ATI 0x8968 #define MYGL_LERP_ATI 0x8969 #define MYGL_CND_ATI 0x896A #define MYGL_CND0_ATI 0x896B #define MYGL_DOT2_ADD_ATI 0x896C #define MYGL_SECONDARY_INTERPOLATOR_ATI 0x896D #define MYGL_NUM_FRAGMENT_REGISTERS_ATI 0x896E #define MYGL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F #define MYGL_NUM_PASSES_ATI 0x8970 #define MYGL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 #define MYGL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 #define MYGL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 #define MYGL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 #define MYGL_COLOR_ALPHA_PAIRING_ATI 0x8975 #define MYGL_SWIZZLE_STR_ATI 0x8976 #define MYGL_SWIZZLE_STQ_ATI 0x8977 #define MYGL_SWIZZLE_STR_DR_ATI 0x8978 #define MYGL_SWIZZLE_STQ_DQ_ATI 0x8979 #define MYGL_SWIZZLE_STRQ_ATI 0x897A #define MYGL_SWIZZLE_STRQ_DQ_ATI 0x897B #define MYGL_RED_BIT_ATI 0x00000001 #define MYGL_GREEN_BIT_ATI 0x00000002 #define MYGL_BLUE_BIT_ATI 0x00000004 #define MYGL_2X_BIT_ATI 0x00000001 #define MYGL_4X_BIT_ATI 0x00000002 #define MYGL_8X_BIT_ATI 0x00000004 #define MYGL_HALF_BIT_ATI 0x00000008 #define MYGL_QUARTER_BIT_ATI 0x00000010 #define MYGL_EIGHTH_BIT_ATI 0x00000020 #define MYGL_SATURATE_BIT_ATI 0x00000040 #define MYGL_COMP_BIT_ATI 0x00000002 #define MYGL_NEGATE_BIT_ATI 0x00000004 #define MYGL_BIAS_BIT_ATI 0x00000008 #endif #ifndef MYGL_ATI_pn_triangles #define MYGL_PN_TRIANGLES_ATI 0x87F0 #define MYGL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 #define MYGL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 #define MYGL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 #define MYGL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 #define MYGL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 #define MYGL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 #define MYGL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 #define MYGL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 #endif #ifndef MYGL_ATI_vertex_array_object #define MYGL_STATIC_ATI 0x8760 #define MYGL_DYNAMIC_ATI 0x8761 #define MYGL_PRESERVE_ATI 0x8762 #define MYGL_DISCARD_ATI 0x8763 #define MYGL_OBJECT_BUFFER_SIZE_ATI 0x8764 #define MYGL_OBJECT_BUFFER_USAGE_ATI 0x8765 #define MYGL_ARRAY_OBJECT_BUFFER_ATI 0x8766 #define MYGL_ARRAY_OBJECT_OFFSET_ATI 0x8767 #endif #ifndef MYGL_EXT_vertex_shader #define MYGL_VERTEX_SHADER_EXT 0x8780 #define MYGL_VERTEX_SHADER_BINDING_EXT 0x8781 #define MYGL_OP_INDEX_EXT 0x8782 #define MYGL_OP_NEGATE_EXT 0x8783 #define MYGL_OP_DOT3_EXT 0x8784 #define MYGL_OP_DOT4_EXT 0x8785 #define MYGL_OP_MUL_EXT 0x8786 #define MYGL_OP_ADD_EXT 0x8787 #define MYGL_OP_MADD_EXT 0x8788 #define MYGL_OP_FRAC_EXT 0x8789 #define MYGL_OP_MAX_EXT 0x878A #define MYGL_OP_MIN_EXT 0x878B #define MYGL_OP_SET_GE_EXT 0x878C #define MYGL_OP_SET_LT_EXT 0x878D #define MYGL_OP_CLAMP_EXT 0x878E #define MYGL_OP_FLOOR_EXT 0x878F #define MYGL_OP_ROUND_EXT 0x8790 #define MYGL_OP_EXP_BASE_2_EXT 0x8791 #define MYGL_OP_LOG_BASE_2_EXT 0x8792 #define MYGL_OP_POWER_EXT 0x8793 #define MYGL_OP_RECIP_EXT 0x8794 #define MYGL_OP_RECIP_SQRT_EXT 0x8795 #define MYGL_OP_SUB_EXT 0x8796 #define MYGL_OP_CROSS_PRODUCT_EXT 0x8797 #define MYGL_OP_MULTIPLY_MATRIX_EXT 0x8798 #define MYGL_OP_MOV_EXT 0x8799 #define MYGL_OUTPUT_VERTEX_EXT 0x879A #define MYGL_OUTPUT_COLOR0_EXT 0x879B #define MYGL_OUTPUT_COLOR1_EXT 0x879C #define MYGL_OUTPUT_TEXTURE_COORD0_EXT 0x879D #define MYGL_OUTPUT_TEXTURE_COORD1_EXT 0x879E #define MYGL_OUTPUT_TEXTURE_COORD2_EXT 0x879F #define MYGL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 #define MYGL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 #define MYGL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 #define MYGL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 #define MYGL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 #define MYGL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 #define MYGL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 #define MYGL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 #define MYGL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 #define MYGL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 #define MYGL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA #define MYGL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB #define MYGL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC #define MYGL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD #define MYGL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE #define MYGL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF #define MYGL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 #define MYGL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 #define MYGL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 #define MYGL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 #define MYGL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 #define MYGL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 #define MYGL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 #define MYGL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 #define MYGL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 #define MYGL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 #define MYGL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA #define MYGL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB #define MYGL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC #define MYGL_OUTPUT_FOG_EXT 0x87BD #define MYGL_SCALAR_EXT 0x87BE #define MYGL_VECTOR_EXT 0x87BF #define MYGL_MATRIX_EXT 0x87C0 #define MYGL_VARIANT_EXT 0x87C1 #define MYGL_INVARIANT_EXT 0x87C2 #define MYGL_LOCAL_CONSTANT_EXT 0x87C3 #define MYGL_LOCAL_EXT 0x87C4 #define MYGL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 #define MYGL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 #define MYGL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 #define MYGL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 #define MYGL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 #define MYGL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA #define MYGL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB #define MYGL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC #define MYGL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD #define MYGL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE #define MYGL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF #define MYGL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 #define MYGL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 #define MYGL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 #define MYGL_VERTEX_SHADER_LOCALS_EXT 0x87D3 #define MYGL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 #define MYGL_X_EXT 0x87D5 #define MYGL_Y_EXT 0x87D6 #define MYGL_Z_EXT 0x87D7 #define MYGL_W_EXT 0x87D8 #define MYGL_NEGATIVE_X_EXT 0x87D9 #define MYGL_NEGATIVE_Y_EXT 0x87DA #define MYGL_NEGATIVE_Z_EXT 0x87DB #define MYGL_NEGATIVE_W_EXT 0x87DC #define MYGL_ZERO_EXT 0x87DD #define MYGL_ONE_EXT 0x87DE #define MYGL_NEGATIVE_ONE_EXT 0x87DF #define MYGL_NORMALIZED_RANGE_EXT 0x87E0 #define MYGL_FULL_RANGE_EXT 0x87E1 #define MYGL_CURRENT_VERTEX_EXT 0x87E2 #define MYGL_MVP_MATRIX_EXT 0x87E3 #define MYGL_VARIANT_VALUE_EXT 0x87E4 #define MYGL_VARIANT_DATATYPE_EXT 0x87E5 #define MYGL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 #define MYGL_VARIANT_ARRAY_TYPE_EXT 0x87E7 #define MYGL_VARIANT_ARRAY_EXT 0x87E8 #define MYGL_VARIANT_ARRAY_POINTER_EXT 0x87E9 #define MYGL_INVARIANT_VALUE_EXT 0x87EA #define MYGL_INVARIANT_DATATYPE_EXT 0x87EB #define MYGL_LOCAL_CONSTANT_VALUE_EXT 0x87EC #define MYGL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED #endif #ifndef MYGL_ATI_vertex_streams #define MYGL_MAX_VERTEX_STREAMS_ATI 0x876B #define MYGL_VERTEX_STREAM0_ATI 0x876C #define MYGL_VERTEX_STREAM1_ATI 0x876D #define MYGL_VERTEX_STREAM2_ATI 0x876E #define MYGL_VERTEX_STREAM3_ATI 0x876F #define MYGL_VERTEX_STREAM4_ATI 0x8770 #define MYGL_VERTEX_STREAM5_ATI 0x8771 #define MYGL_VERTEX_STREAM6_ATI 0x8772 #define MYGL_VERTEX_STREAM7_ATI 0x8773 #define MYGL_VERTEX_SOURCE_ATI 0x8774 #endif #ifndef MYGL_ATI_element_array #define MYGL_ELEMENT_ARRAY_ATI 0x8768 #define MYGL_ELEMENT_ARRAY_TYPE_ATI 0x8769 #define MYGL_ELEMENT_ARRAY_POINTER_ATI 0x876A #endif #ifndef MYGL_SUN_mesh_array #define MYGL_QUAD_MESH_SUN 0x8614 #define MYGL_TRIANGLE_MESH_SUN 0x8615 #endif #ifndef MYGL_SUN_slice_accum #define MYGL_SLICE_ACCUM_SUN 0x85CC #endif #ifndef MYGL_NV_multisample_filter_hint #define MYGL_MULTISAMPLE_FILTER_HINT_NV 0x8534 #endif #ifndef MYGL_NV_depth_clamp #define MYGL_DEPTH_CLAMP_NV 0x864F #endif #ifndef MYGL_NV_occlusion_query #define MYGL_PIXEL_COUNTER_BITS_NV 0x8864 #define MYGL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 #define MYGL_PIXEL_COUNT_NV 0x8866 #define MYGL_PIXEL_COUNT_AVAILABLE_NV 0x8867 #endif #ifndef MYGL_NV_point_sprite #define MYGL_POINT_SPRITE_NV 0x8861 #define MYGL_COORD_REPLACE_NV 0x8862 #define MYGL_POINT_SPRITE_R_MODE_NV 0x8863 #endif #ifndef MYGL_NV_texture_shader3 #define MYGL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 #define MYGL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 #define MYGL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 #define MYGL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 #define MYGL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 #define MYGL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 #define MYGL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 #define MYGL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 #define MYGL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 #define MYGL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 #define MYGL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A #define MYGL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B #define MYGL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C #define MYGL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D #define MYGL_HILO8_NV 0x885E #define MYGL_SIGNED_HILO8_NV 0x885F #define MYGL_FORCE_BLUE_TO_ONE_NV 0x8860 #endif #ifndef MYGL_NV_vertex_program1_1 #endif #ifndef MYGL_EXT_shadow_funcs #endif #ifndef MYGL_EXT_stencil_two_side #define MYGL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 #define MYGL_ACTIVE_STENCIL_FACE_EXT 0x8911 #endif #ifndef MYGL_ATI_text_fragment_shader #define MYGL_TEXT_FRAGMENT_SHADER_ATI 0x8200 #endif #ifndef MYGL_APPLE_client_storage #define MYGL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 #endif #ifndef MYGL_APPLE_element_array #define MYGL_ELEMENT_ARRAY_APPLE 0x8768 #define MYGL_ELEMENT_ARRAY_TYPE_APPLE 0x8769 #define MYGL_ELEMENT_ARRAY_POINTER_APPLE 0x876A #endif #ifndef MYGL_APPLE_fence #define MYGL_DRAW_PIXELS_APPLE 0x8A0A #define MYGL_FENCE_APPLE 0x8A0B #endif #ifndef MYGL_APPLE_vertex_array_object #define MYGL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 #endif #ifndef MYGL_APPLE_vertex_array_range #define MYGL_VERTEX_ARRAY_RANGE_APPLE 0x851D #define MYGL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E #define MYGL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F #define MYGL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 #define MYGL_STORAGE_CACHED_APPLE 0x85BE #define MYGL_STORAGE_SHARED_APPLE 0x85BF #endif #ifndef MYGL_APPLE_ycbcr_422 #define MYGL_YCBCR_422_APPLE 0x85B9 #define MYGL_UNSIGNED_SHORT_8_8_APPLE 0x85BA #define MYGL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB #endif #ifndef MYGL_S3_s3tc #define MYGL_RGB_S3TC 0x83A0 #define MYGL_RGB4_S3TC 0x83A1 #define MYGL_RGBA_S3TC 0x83A2 #define MYGL_RGBA4_S3TC 0x83A3 #endif #ifndef MYGL_ATI_draw_buffers #define MYGL_MAX_DRAW_BUFFERS_ATI 0x8824 #define MYGL_DRAW_BUFFER0_ATI 0x8825 #define MYGL_DRAW_BUFFER1_ATI 0x8826 #define MYGL_DRAW_BUFFER2_ATI 0x8827 #define MYGL_DRAW_BUFFER3_ATI 0x8828 #define MYGL_DRAW_BUFFER4_ATI 0x8829 #define MYGL_DRAW_BUFFER5_ATI 0x882A #define MYGL_DRAW_BUFFER6_ATI 0x882B #define MYGL_DRAW_BUFFER7_ATI 0x882C #define MYGL_DRAW_BUFFER8_ATI 0x882D #define MYGL_DRAW_BUFFER9_ATI 0x882E #define MYGL_DRAW_BUFFER10_ATI 0x882F #define MYGL_DRAW_BUFFER11_ATI 0x8830 #define MYGL_DRAW_BUFFER12_ATI 0x8831 #define MYGL_DRAW_BUFFER13_ATI 0x8832 #define MYGL_DRAW_BUFFER14_ATI 0x8833 #define MYGL_DRAW_BUFFER15_ATI 0x8834 #endif #ifndef MYGL_ATI_pixel_format_float #define MYGL_TYPE_RGBA_FLOAT_ATI 0x8820 #define MYGL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 #endif #ifndef MYGL_ATI_texture_env_combine3 #define MYGL_MODULATE_ADD_ATI 0x8744 #define MYGL_MODULATE_SIGNED_ADD_ATI 0x8745 #define MYGL_MODULATE_SUBTRACT_ATI 0x8746 #endif #ifndef MYGL_ATI_texture_float #define MYGL_RGBA_FLOAT32_ATI 0x8814 #define MYGL_RGB_FLOAT32_ATI 0x8815 #define MYGL_ALPHA_FLOAT32_ATI 0x8816 #define MYGL_INTENSITY_FLOAT32_ATI 0x8817 #define MYGL_LUMINANCE_FLOAT32_ATI 0x8818 #define MYGL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 #define MYGL_RGBA_FLOAT16_ATI 0x881A #define MYGL_RGB_FLOAT16_ATI 0x881B #define MYGL_ALPHA_FLOAT16_ATI 0x881C #define MYGL_INTENSITY_FLOAT16_ATI 0x881D #define MYGL_LUMINANCE_FLOAT16_ATI 0x881E #define MYGL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F #endif #ifndef MYGL_NV_float_buffer #define MYGL_FLOAT_R_NV 0x8880 #define MYGL_FLOAT_RG_NV 0x8881 #define MYGL_FLOAT_RGB_NV 0x8882 #define MYGL_FLOAT_RGBA_NV 0x8883 #define MYGL_FLOAT_R16_NV 0x8884 #define MYGL_FLOAT_R32_NV 0x8885 #define MYGL_FLOAT_RG16_NV 0x8886 #define MYGL_FLOAT_RG32_NV 0x8887 #define MYGL_FLOAT_RGB16_NV 0x8888 #define MYGL_FLOAT_RGB32_NV 0x8889 #define MYGL_FLOAT_RGBA16_NV 0x888A #define MYGL_FLOAT_RGBA32_NV 0x888B #define MYGL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C #define MYGL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D #define MYGL_FLOAT_RGBA_MODE_NV 0x888E #endif #ifndef MYGL_NV_fragment_program #define MYGL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 #define MYGL_FRAGMENT_PROGRAM_NV 0x8870 #define MYGL_MAX_TEXTURE_COORDS_NV 0x8871 #define MYGL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 #define MYGL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 #define MYGL_PROGRAM_ERROR_STRING_NV 0x8874 #endif #ifndef MYGL_NV_half_float #define MYGL_HALF_FLOAT_NV 0x140B #endif #ifndef MYGL_NV_pixel_data_range #define MYGL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 #define MYGL_READ_PIXEL_DATA_RANGE_NV 0x8879 #define MYGL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A #define MYGL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B #define MYGL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C #define MYGL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D #endif #ifndef MYGL_NV_primitive_restart #define MYGL_PRIMITIVE_RESTART_NV 0x8558 #define MYGL_PRIMITIVE_RESTART_INDEX_NV 0x8559 #endif #ifndef MYGL_NV_texture_expand_normal #define MYGL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F #endif #ifndef MYGL_NV_vertex_program2 #endif #ifndef MYGL_ATI_map_object_buffer #endif #ifndef MYGL_ATI_separate_stencil #define MYGL_STENCIL_BACK_FUNC_ATI 0x8800 #define MYGL_STENCIL_BACK_FAIL_ATI 0x8801 #define MYGL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 #define MYGL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 #endif #ifndef MYGL_ATI_vertex_attrib_array_object #endif #ifndef MYGL_OES_read_format #define MYGL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A #define MYGL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B #endif #ifndef MYGL_EXT_depth_bounds_test #define MYGL_DEPTH_BOUNDS_TEST_EXT 0x8890 #define MYGL_DEPTH_BOUNDS_EXT 0x8891 #endif #ifndef MYGL_EXT_texture_mirror_clamp #define MYGL_MIRROR_CLAMP_EXT 0x8742 #define MYGL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 #define MYGL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 #endif #ifndef MYGL_EXT_blend_equation_separate #define MYGL_BLEND_EQUATION_RGB_EXT MYGL_BLEND_EQUATION #define MYGL_BLEND_EQUATION_ALPHA_EXT 0x883D #endif #ifndef MYGL_MESA_pack_invert #define MYGL_PACK_INVERT_MESA 0x8758 #endif #ifndef MYGL_MESA_ycbcr_texture #define MYGL_UNSIGNED_SHORT_8_8_MESA 0x85BA #define MYGL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB #define MYGL_YCBCR_MESA 0x8757 #endif #ifndef MYGL_EXT_pixel_buffer_object #define MYGL_PIXEL_PACK_BUFFER_EXT 0x88EB #define MYGL_PIXEL_UNPACK_BUFFER_EXT 0x88EC #define MYGL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED #define MYGL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF #endif #ifndef MYGL_NV_fragment_program_option #endif #ifndef MYGL_NV_fragment_program2 #define MYGL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 #define MYGL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 #define MYGL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 #define MYGL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 #define MYGL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 #endif #ifndef MYGL_NV_vertex_program2_option /* reuse MYGL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ /* reuse MYGL_MAX_PROGRAM_CALL_DEPTH_NV */ #endif #ifndef MYGL_NV_vertex_program3 /* reuse MYGL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ #endif #ifndef MYGL_EXT_framebuffer_object #define MYGL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 #define MYGL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 #define MYGL_FRAMEBUFFER_BINDING_EXT 0x8CA6 #define MYGL_RENDERBUFFER_BINDING_EXT 0x8CA7 #define MYGL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 #define MYGL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 #define MYGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 #define MYGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 #define MYGL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 #define MYGL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 #define MYGL_FRAMEBUFFER_INCOMPLETE_ATTACHMENTS_EXT 0x8CD6 #define MYGL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 #define MYGL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT 0x8CD8 #define MYGL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 #define MYGL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA #define MYGL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB #define MYGL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC #define MYGL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD #define MYGL_FRAMEBUFFER_STATUS_ERROR_EXT 0x8CDE #define MYGL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF #define MYGL_COLOR_ATTACHMENT0_EXT 0x8CE0 #define MYGL_COLOR_ATTACHMENT1_EXT 0x8CE1 #define MYGL_COLOR_ATTACHMENT2_EXT 0x8CE2 #define MYGL_COLOR_ATTACHMENT3_EXT 0x8CE3 #define MYGL_COLOR_ATTACHMENT4_EXT 0x8CE4 #define MYGL_COLOR_ATTACHMENT5_EXT 0x8CE5 #define MYGL_COLOR_ATTACHMENT6_EXT 0x8CE6 #define MYGL_COLOR_ATTACHMENT7_EXT 0x8CE7 #define MYGL_COLOR_ATTACHMENT8_EXT 0x8CE8 #define MYGL_COLOR_ATTACHMENT9_EXT 0x8CE9 #define MYGL_COLOR_ATTACHMENT10_EXT 0x8CEA #define MYGL_COLOR_ATTACHMENT11_EXT 0x8CEB #define MYGL_COLOR_ATTACHMENT12_EXT 0x8CEC #define MYGL_COLOR_ATTACHMENT13_EXT 0x8CED #define MYGL_COLOR_ATTACHMENT14_EXT 0x8CEE #define MYGL_COLOR_ATTACHMENT15_EXT 0x8CEF #define MYGL_DEPTH_ATTACHMENT_EXT 0x8D00 #define MYGL_STENCIL_ATTACHMENT_EXT 0x8D20 #define MYGL_FRAMEBUFFER_EXT 0x8D40 #define MYGL_RENDERBUFFER_EXT 0x8D41 #define MYGL_RENDERBUFFER_WIDTH_EXT 0x8D42 #define MYGL_RENDERBUFFER_HEIGHT_EXT 0x8D43 #define MYGL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 #define MYGL_STENCIL_INDEX_EXT 0x8D45 #define MYGL_STENCIL_INDEX1_EXT 0x8D46 #define MYGL_STENCIL_INDEX4_EXT 0x8D47 #define MYGL_STENCIL_INDEX8_EXT 0x8D48 #define MYGL_STENCIL_INDEX16_EXT 0x8D49 #endif #ifndef MYGL_GREMEDY_string_marker #endif /*************************************************************/ #include #ifndef MYGL_VERSION_2_0 /* GL type for program/shader text */ typedef char GLchar; /* native character */ #endif #ifndef MYGL_VERSION_1_5 /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptr; typedef ptrdiff_t GLsizeiptr; #endif #ifndef MYGL_ARB_vertex_buffer_object /* GL types for handling large vertex buffer objects */ typedef ptrdiff_t GLintptrARB; typedef ptrdiff_t GLsizeiptrARB; #endif #ifndef MYGL_ARB_shader_objects /* GL types for handling shader object handles and program/shader text */ typedef char GLcharARB; /* native character */ typedef unsigned int GLhandleARB; /* shader object handle */ #endif /* GL types for "half" precision (s10e5) float data in host memory */ #ifndef MYGL_ARB_half_float_pixel typedef unsigned short GLhalfARB; #endif #ifndef MYGL_NV_half_float typedef unsigned short GLhalfNV; #endif #ifndef MYGL_VERSION_1_2 #define MYGL_VERSION_1_2 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendColor (GLclampf, GLclampf, GLclampf, GLclampf); GLAPI void APIENTRY myglBlendEquation (GLenum); GLAPI void APIENTRY myglDrawRangeElements (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); GLAPI void APIENTRY myglColorTable (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglColorTableParameterfv (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglColorTableParameteriv (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglCopyColorTable (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY myglGetColorTable (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetColorTableParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetColorTableParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglColorSubTable (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglCopyColorSubTable (GLenum, GLsizei, GLint, GLint, GLsizei); GLAPI void APIENTRY myglConvolutionFilter1D (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglConvolutionFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglConvolutionParameterf (GLenum, GLenum, GLfloat); GLAPI void APIENTRY myglConvolutionParameterfv (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglConvolutionParameteri (GLenum, GLenum, GLint); GLAPI void APIENTRY myglConvolutionParameteriv (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglCopyConvolutionFilter1D (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY myglCopyConvolutionFilter2D (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY myglGetConvolutionFilter (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetConvolutionParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetConvolutionParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetSeparableFilter (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); GLAPI void APIENTRY myglSeparableFilter2D (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); GLAPI void APIENTRY myglGetHistogram (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetHistogramParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetHistogramParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetMinmax (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetMinmaxParameterfv (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetMinmaxParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglHistogram (GLenum, GLsizei, GLenum, GLboolean); GLAPI void APIENTRY myglMinmax (GLenum, GLenum, GLboolean); GLAPI void APIENTRY myglResetHistogram (GLenum); GLAPI void APIENTRY myglResetMinmax (GLenum); GLAPI void APIENTRY myglTexImage3D (GLenum, GLint, GLint, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglCopyTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); typedef void (APIENTRYP PFNMYGLBLENDEQUATIONPROC) (GLenum mode); typedef void (APIENTRYP PFNMYGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); typedef void (APIENTRYP PFNMYGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNMYGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNMYGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNMYGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNMYGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNMYGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNMYGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNMYGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); typedef void (APIENTRYP PFNMYGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNMYGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNMYGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNMYGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNMYGLRESETHISTOGRAMPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLRESETMINMAXPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNMYGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNMYGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef MYGL_VERSION_1_3 #define MYGL_VERSION_1_3 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglActiveTexture (GLenum); GLAPI void APIENTRY myglClientActiveTexture (GLenum); GLAPI void APIENTRY myglMultiTexCoord1d (GLenum, GLdouble); GLAPI void APIENTRY myglMultiTexCoord1dv (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord1f (GLenum, GLfloat); GLAPI void APIENTRY myglMultiTexCoord1fv (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord1i (GLenum, GLint); GLAPI void APIENTRY myglMultiTexCoord1iv (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord1s (GLenum, GLshort); GLAPI void APIENTRY myglMultiTexCoord1sv (GLenum, const GLshort *); GLAPI void APIENTRY myglMultiTexCoord2d (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY myglMultiTexCoord2dv (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord2f (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY myglMultiTexCoord2fv (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord2i (GLenum, GLint, GLint); GLAPI void APIENTRY myglMultiTexCoord2iv (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord2s (GLenum, GLshort, GLshort); GLAPI void APIENTRY myglMultiTexCoord2sv (GLenum, const GLshort *); GLAPI void APIENTRY myglMultiTexCoord3d (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglMultiTexCoord3dv (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord3f (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglMultiTexCoord3fv (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord3i (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY myglMultiTexCoord3iv (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord3s (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglMultiTexCoord3sv (GLenum, const GLshort *); GLAPI void APIENTRY myglMultiTexCoord4d (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglMultiTexCoord4dv (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord4f (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglMultiTexCoord4fv (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord4i (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglMultiTexCoord4iv (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord4s (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglMultiTexCoord4sv (GLenum, const GLshort *); GLAPI void APIENTRY myglLoadTransposeMatrixf (const GLfloat *); GLAPI void APIENTRY myglLoadTransposeMatrixd (const GLdouble *); GLAPI void APIENTRY myglMultTransposeMatrixf (const GLfloat *); GLAPI void APIENTRY myglMultTransposeMatrixd (const GLdouble *); GLAPI void APIENTRY myglSampleCoverage (GLclampf, GLboolean); GLAPI void APIENTRY myglCompressedTexImage3D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexImage2D (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexImage1D (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexSubImage3D (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexSubImage2D (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexSubImage1D (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglGetCompressedTexImage (GLenum, GLint, GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNMYGLCLIENTACTIVETEXTUREPROC) (GLenum texture); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNMYGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNMYGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP PFNMYGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); typedef void (APIENTRYP PFNMYGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); typedef void (APIENTRYP PFNMYGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); #endif #ifndef MYGL_VERSION_1_4 #define MYGL_VERSION_1_4 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendFuncSeparate (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY myglFogCoordf (GLfloat); GLAPI void APIENTRY myglFogCoordfv (const GLfloat *); GLAPI void APIENTRY myglFogCoordd (GLdouble); GLAPI void APIENTRY myglFogCoorddv (const GLdouble *); GLAPI void APIENTRY myglFogCoordPointer (GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglMultiDrawArrays (GLenum, GLint *, GLsizei *, GLsizei); GLAPI void APIENTRY myglMultiDrawElements (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); GLAPI void APIENTRY myglPointParameterf (GLenum, GLfloat); GLAPI void APIENTRY myglPointParameterfv (GLenum, const GLfloat *); GLAPI void APIENTRY myglPointParameteri (GLenum, GLint); GLAPI void APIENTRY myglPointParameteriv (GLenum, const GLint *); GLAPI void APIENTRY myglSecondaryColor3b (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY myglSecondaryColor3bv (const GLbyte *); GLAPI void APIENTRY myglSecondaryColor3d (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglSecondaryColor3dv (const GLdouble *); GLAPI void APIENTRY myglSecondaryColor3f (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglSecondaryColor3fv (const GLfloat *); GLAPI void APIENTRY myglSecondaryColor3i (GLint, GLint, GLint); GLAPI void APIENTRY myglSecondaryColor3iv (const GLint *); GLAPI void APIENTRY myglSecondaryColor3s (GLshort, GLshort, GLshort); GLAPI void APIENTRY myglSecondaryColor3sv (const GLshort *); GLAPI void APIENTRY myglSecondaryColor3ub (GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY myglSecondaryColor3ubv (const GLubyte *); GLAPI void APIENTRY myglSecondaryColor3ui (GLuint, GLuint, GLuint); GLAPI void APIENTRY myglSecondaryColor3uiv (const GLuint *); GLAPI void APIENTRY myglSecondaryColor3us (GLushort, GLushort, GLushort); GLAPI void APIENTRY myglSecondaryColor3usv (const GLushort *); GLAPI void APIENTRY myglSecondaryColorPointer (GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglWindowPos2d (GLdouble, GLdouble); GLAPI void APIENTRY myglWindowPos2dv (const GLdouble *); GLAPI void APIENTRY myglWindowPos2f (GLfloat, GLfloat); GLAPI void APIENTRY myglWindowPos2fv (const GLfloat *); GLAPI void APIENTRY myglWindowPos2i (GLint, GLint); GLAPI void APIENTRY myglWindowPos2iv (const GLint *); GLAPI void APIENTRY myglWindowPos2s (GLshort, GLshort); GLAPI void APIENTRY myglWindowPos2sv (const GLshort *); GLAPI void APIENTRY myglWindowPos3d (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglWindowPos3dv (const GLdouble *); GLAPI void APIENTRY myglWindowPos3f (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglWindowPos3fv (const GLfloat *); GLAPI void APIENTRY myglWindowPos3i (GLint, GLint, GLint); GLAPI void APIENTRY myglWindowPos3iv (const GLint *); GLAPI void APIENTRY myglWindowPos3s (GLshort, GLshort, GLshort); GLAPI void APIENTRY myglWindowPos3sv (const GLshort *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); typedef void (APIENTRYP PFNMYGLFOGCOORDFPROC) (GLfloat coord); typedef void (APIENTRYP PFNMYGLFOGCOORDFVPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNMYGLFOGCOORDDPROC) (GLdouble coord); typedef void (APIENTRYP PFNMYGLFOGCOORDDVPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNMYGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLMULTIDRAWARRAYSPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNMYGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3USVPROC) (const GLushort *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2IPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2IVPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2SPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2SVPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3DVPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3FVPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3IVPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3SVPROC) (const GLshort *v); #endif #ifndef MYGL_VERSION_1_5 #define MYGL_VERSION_1_5 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGenQueries (GLsizei, GLuint *); GLAPI void APIENTRY myglDeleteQueries (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY myglIsQuery (GLuint); GLAPI void APIENTRY myglBeginQuery (GLenum, GLuint); GLAPI void APIENTRY myglEndQuery (GLenum); GLAPI void APIENTRY myglGetQueryiv (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetQueryObjectiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetQueryObjectuiv (GLuint, GLenum, GLuint *); GLAPI void APIENTRY myglBindBuffer (GLenum, GLuint); GLAPI void APIENTRY myglDeleteBuffers (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenBuffers (GLsizei, GLuint *); GLAPI GLboolean APIENTRY myglIsBuffer (GLuint); GLAPI void APIENTRY myglBufferData (GLenum, GLsizeiptr, const GLvoid *, GLenum); GLAPI void APIENTRY myglBufferSubData (GLenum, GLintptr, GLsizeiptr, const GLvoid *); GLAPI void APIENTRY myglGetBufferSubData (GLenum, GLintptr, GLsizeiptr, GLvoid *); GLAPI GLvoid* APIENTRY myglMapBuffer (GLenum, GLenum); GLAPI GLboolean APIENTRY myglUnmapBuffer (GLenum); GLAPI void APIENTRY myglGetBufferParameteriv (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetBufferPointerv (GLenum, GLenum, GLvoid* *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGENQUERIESPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNMYGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNMYGLISQUERYPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLBEGINQUERYPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNMYGLENDQUERYPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); typedef void (APIENTRYP PFNMYGLBINDBUFFERPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNMYGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNMYGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNMYGLISBUFFERPROC) (GLuint buffer); typedef void (APIENTRYP PFNMYGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNMYGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); typedef void (APIENTRYP PFNMYGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNMYGLMAPBUFFERPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNMYGLUNMAPBUFFERPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef MYGL_VERSION_2_0 #define MYGL_VERSION_2_0 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendEquationSeparate (GLenum, GLenum); GLAPI void APIENTRY myglDrawBuffers (GLsizei, const GLenum *); GLAPI void APIENTRY myglStencilOpSeparate (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY myglStencilFuncSeparate (GLenum, GLenum, GLint, GLuint); GLAPI void APIENTRY myglStencilMaskSeparate (GLenum, GLuint); GLAPI void APIENTRY myglAttachShader (GLuint, GLuint); GLAPI void APIENTRY myglBindAttribLocation (GLuint, GLuint, const GLchar *); GLAPI void APIENTRY myglCompileShader (GLuint); GLAPI GLuint APIENTRY myglCreateProgram (void); GLAPI GLuint APIENTRY myglCreateShader (GLenum); GLAPI void APIENTRY myglDeleteProgram (GLuint); GLAPI void APIENTRY myglDeleteShader (GLuint); GLAPI void APIENTRY myglDetachShader (GLuint, GLuint); GLAPI void APIENTRY myglDisableVertexAttribArray (GLuint); GLAPI void APIENTRY myglEnableVertexAttribArray (GLuint); GLAPI void APIENTRY myglGetActiveAttrib (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); GLAPI void APIENTRY myglGetActiveUniform (GLuint, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLchar *); GLAPI void APIENTRY myglGetAttachedShaders (GLuint, GLsizei, GLsizei *, GLuint *); GLAPI GLint APIENTRY myglGetAttribLocation (GLuint, const GLchar *); GLAPI void APIENTRY myglGetProgramiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetProgramInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); GLAPI void APIENTRY myglGetShaderiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetShaderInfoLog (GLuint, GLsizei, GLsizei *, GLchar *); GLAPI void APIENTRY myglGetShaderSource (GLuint, GLsizei, GLsizei *, GLchar *); GLAPI GLint APIENTRY myglGetUniformLocation (GLuint, const GLchar *); GLAPI void APIENTRY myglGetUniformfv (GLuint, GLint, GLfloat *); GLAPI void APIENTRY myglGetUniformiv (GLuint, GLint, GLint *); GLAPI void APIENTRY myglGetVertexAttribdv (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY myglGetVertexAttribfv (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetVertexAttribiv (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetVertexAttribPointerv (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY myglIsProgram (GLuint); GLAPI GLboolean APIENTRY myglIsShader (GLuint); GLAPI void APIENTRY myglLinkProgram (GLuint); GLAPI void APIENTRY myglShaderSource (GLuint, GLsizei, const GLchar* *, const GLint *); GLAPI void APIENTRY myglUseProgram (GLuint); GLAPI void APIENTRY myglUniform1f (GLint, GLfloat); GLAPI void APIENTRY myglUniform2f (GLint, GLfloat, GLfloat); GLAPI void APIENTRY myglUniform3f (GLint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglUniform4f (GLint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglUniform1i (GLint, GLint); GLAPI void APIENTRY myglUniform2i (GLint, GLint, GLint); GLAPI void APIENTRY myglUniform3i (GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglUniform4i (GLint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglUniform1fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform2fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform3fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform4fv (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform1iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniform2iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniform3iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniform4iv (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniformMatrix2fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY myglUniformMatrix3fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY myglUniformMatrix4fv (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY myglValidateProgram (GLuint); GLAPI void APIENTRY myglVertexAttrib1d (GLuint, GLdouble); GLAPI void APIENTRY myglVertexAttrib1dv (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib1f (GLuint, GLfloat); GLAPI void APIENTRY myglVertexAttrib1fv (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib1s (GLuint, GLshort); GLAPI void APIENTRY myglVertexAttrib1sv (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib2d (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib2dv (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib2f (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib2fv (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib2s (GLuint, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib2sv (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib3d (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib3dv (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib3f (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib3fv (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib3s (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib3sv (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4Nbv (GLuint, const GLbyte *); GLAPI void APIENTRY myglVertexAttrib4Niv (GLuint, const GLint *); GLAPI void APIENTRY myglVertexAttrib4Nsv (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4Nub (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY myglVertexAttrib4Nubv (GLuint, const GLubyte *); GLAPI void APIENTRY myglVertexAttrib4Nuiv (GLuint, const GLuint *); GLAPI void APIENTRY myglVertexAttrib4Nusv (GLuint, const GLushort *); GLAPI void APIENTRY myglVertexAttrib4bv (GLuint, const GLbyte *); GLAPI void APIENTRY myglVertexAttrib4d (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib4dv (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib4f (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib4fv (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib4iv (GLuint, const GLint *); GLAPI void APIENTRY myglVertexAttrib4s (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib4sv (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4ubv (GLuint, const GLubyte *); GLAPI void APIENTRY myglVertexAttrib4uiv (GLuint, const GLuint *); GLAPI void APIENTRY myglVertexAttrib4usv (GLuint, const GLushort *); GLAPI void APIENTRY myglVertexAttribPointer (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); typedef void (APIENTRYP PFNMYGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); typedef void (APIENTRYP PFNMYGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNMYGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); typedef void (APIENTRYP PFNMYGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); typedef void (APIENTRYP PFNMYGLATTACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNMYGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); typedef void (APIENTRYP PFNMYGLCOMPILESHADERPROC) (GLuint shader); typedef GLuint (APIENTRYP PFNMYGLCREATEPROGRAMPROC) (void); typedef GLuint (APIENTRYP PFNMYGLCREATESHADERPROC) (GLenum type); typedef void (APIENTRYP PFNMYGLDELETEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNMYGLDELETESHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNMYGLDETACHSHADERPROC) (GLuint program, GLuint shader); typedef void (APIENTRYP PFNMYGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNMYGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); typedef void (APIENTRYP PFNMYGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNMYGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); typedef void (APIENTRYP PFNMYGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); typedef GLint (APIENTRYP PFNMYGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNMYGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNMYGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); typedef void (APIENTRYP PFNMYGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); typedef GLint (APIENTRYP PFNMYGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); typedef void (APIENTRYP PFNMYGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNMYGLISPROGRAMPROC) (GLuint program); typedef GLboolean (APIENTRYP PFNMYGLISSHADERPROC) (GLuint shader); typedef void (APIENTRYP PFNMYGLLINKPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNMYGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); typedef void (APIENTRYP PFNMYGLUSEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNMYGLUNIFORM1FPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNMYGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNMYGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNMYGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNMYGLUNIFORM1IPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNMYGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNMYGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNMYGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNMYGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNMYGLVALIDATEPROGRAMPROC) (GLuint program); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); #endif #ifndef MYGL_ARB_multitexture #define MYGL_ARB_multitexture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglActiveTextureARB (GLenum); GLAPI void APIENTRY myglClientActiveTextureARB (GLenum); GLAPI void APIENTRY myglMultiTexCoord1dARB (GLenum, GLdouble); GLAPI void APIENTRY myglMultiTexCoord1dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord1fARB (GLenum, GLfloat); GLAPI void APIENTRY myglMultiTexCoord1fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord1iARB (GLenum, GLint); GLAPI void APIENTRY myglMultiTexCoord1ivARB (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord1sARB (GLenum, GLshort); GLAPI void APIENTRY myglMultiTexCoord1svARB (GLenum, const GLshort *); GLAPI void APIENTRY myglMultiTexCoord2dARB (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY myglMultiTexCoord2dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord2fARB (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY myglMultiTexCoord2fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord2iARB (GLenum, GLint, GLint); GLAPI void APIENTRY myglMultiTexCoord2ivARB (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord2sARB (GLenum, GLshort, GLshort); GLAPI void APIENTRY myglMultiTexCoord2svARB (GLenum, const GLshort *); GLAPI void APIENTRY myglMultiTexCoord3dARB (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglMultiTexCoord3dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord3fARB (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglMultiTexCoord3fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord3iARB (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY myglMultiTexCoord3ivARB (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord3sARB (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglMultiTexCoord3svARB (GLenum, const GLshort *); GLAPI void APIENTRY myglMultiTexCoord4dARB (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglMultiTexCoord4dvARB (GLenum, const GLdouble *); GLAPI void APIENTRY myglMultiTexCoord4fARB (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglMultiTexCoord4fvARB (GLenum, const GLfloat *); GLAPI void APIENTRY myglMultiTexCoord4iARB (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglMultiTexCoord4ivARB (GLenum, const GLint *); GLAPI void APIENTRY myglMultiTexCoord4sARB (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglMultiTexCoord4svARB (GLenum, const GLshort *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNMYGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); #endif #ifndef MYGL_ARB_transpose_matrix #define MYGL_ARB_transpose_matrix 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglLoadTransposeMatrixfARB (const GLfloat *); GLAPI void APIENTRY myglLoadTransposeMatrixdARB (const GLdouble *); GLAPI void APIENTRY myglMultTransposeMatrixfARB (const GLfloat *); GLAPI void APIENTRY myglMultTransposeMatrixdARB (const GLdouble *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNMYGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); typedef void (APIENTRYP PFNMYGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); typedef void (APIENTRYP PFNMYGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); #endif #ifndef MYGL_ARB_multisample #define MYGL_ARB_multisample 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglSampleCoverageARB (GLclampf, GLboolean); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); #endif #ifndef MYGL_ARB_texture_env_add #define MYGL_ARB_texture_env_add 1 #endif #ifndef MYGL_ARB_texture_cube_map #define MYGL_ARB_texture_cube_map 1 #endif #ifndef MYGL_ARB_texture_compression #define MYGL_ARB_texture_compression 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglCompressedTexImage3DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexImage2DARB (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexImage1DARB (GLenum, GLint, GLenum, GLsizei, GLint, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexSubImage3DARB (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexSubImage2DARB (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglCompressedTexSubImage1DARB (GLenum, GLint, GLint, GLsizei, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglGetCompressedTexImageARB (GLenum, GLint, GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); typedef void (APIENTRYP PFNMYGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); #endif #ifndef MYGL_ARB_texture_border_clamp #define MYGL_ARB_texture_border_clamp 1 #endif #ifndef MYGL_ARB_point_parameters #define MYGL_ARB_point_parameters 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPointParameterfARB (GLenum, GLfloat); GLAPI void APIENTRY myglPointParameterfvARB (GLenum, const GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); #endif #ifndef MYGL_ARB_vertex_blend #define MYGL_ARB_vertex_blend 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglWeightbvARB (GLint, const GLbyte *); GLAPI void APIENTRY myglWeightsvARB (GLint, const GLshort *); GLAPI void APIENTRY myglWeightivARB (GLint, const GLint *); GLAPI void APIENTRY myglWeightfvARB (GLint, const GLfloat *); GLAPI void APIENTRY myglWeightdvARB (GLint, const GLdouble *); GLAPI void APIENTRY myglWeightubvARB (GLint, const GLubyte *); GLAPI void APIENTRY myglWeightusvARB (GLint, const GLushort *); GLAPI void APIENTRY myglWeightuivARB (GLint, const GLuint *); GLAPI void APIENTRY myglWeightPointerARB (GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglVertexBlendARB (GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); typedef void (APIENTRYP PFNMYGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); typedef void (APIENTRYP PFNMYGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); typedef void (APIENTRYP PFNMYGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); typedef void (APIENTRYP PFNMYGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); typedef void (APIENTRYP PFNMYGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); typedef void (APIENTRYP PFNMYGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); typedef void (APIENTRYP PFNMYGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); typedef void (APIENTRYP PFNMYGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLVERTEXBLENDARBPROC) (GLint count); #endif #ifndef MYGL_ARB_matrix_palette #define MYGL_ARB_matrix_palette 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglCurrentPaletteMatrixARB (GLint); GLAPI void APIENTRY myglMatrixIndexubvARB (GLint, const GLubyte *); GLAPI void APIENTRY myglMatrixIndexusvARB (GLint, const GLushort *); GLAPI void APIENTRY myglMatrixIndexuivARB (GLint, const GLuint *); GLAPI void APIENTRY myglMatrixIndexPointerARB (GLint, GLenum, GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCURRENTPALETTEMATRIXARBPROC) (GLint index); typedef void (APIENTRYP PFNMYGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); typedef void (APIENTRYP PFNMYGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); typedef void (APIENTRYP PFNMYGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); typedef void (APIENTRYP PFNMYGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef MYGL_ARB_texture_env_combine #define MYGL_ARB_texture_env_combine 1 #endif #ifndef MYGL_ARB_texture_env_crossbar #define MYGL_ARB_texture_env_crossbar 1 #endif #ifndef MYGL_ARB_texture_env_dot3 #define MYGL_ARB_texture_env_dot3 1 #endif #ifndef MYGL_ARB_texture_mirrored_repeat #define MYGL_ARB_texture_mirrored_repeat 1 #endif #ifndef MYGL_ARB_depth_texture #define MYGL_ARB_depth_texture 1 #endif #ifndef MYGL_ARB_shadow #define MYGL_ARB_shadow 1 #endif #ifndef MYGL_ARB_shadow_ambient #define MYGL_ARB_shadow_ambient 1 #endif #ifndef MYGL_ARB_window_pos #define MYGL_ARB_window_pos 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglWindowPos2dARB (GLdouble, GLdouble); GLAPI void APIENTRY myglWindowPos2dvARB (const GLdouble *); GLAPI void APIENTRY myglWindowPos2fARB (GLfloat, GLfloat); GLAPI void APIENTRY myglWindowPos2fvARB (const GLfloat *); GLAPI void APIENTRY myglWindowPos2iARB (GLint, GLint); GLAPI void APIENTRY myglWindowPos2ivARB (const GLint *); GLAPI void APIENTRY myglWindowPos2sARB (GLshort, GLshort); GLAPI void APIENTRY myglWindowPos2svARB (const GLshort *); GLAPI void APIENTRY myglWindowPos3dARB (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglWindowPos3dvARB (const GLdouble *); GLAPI void APIENTRY myglWindowPos3fARB (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglWindowPos3fvARB (const GLfloat *); GLAPI void APIENTRY myglWindowPos3iARB (GLint, GLint, GLint); GLAPI void APIENTRY myglWindowPos3ivARB (const GLint *); GLAPI void APIENTRY myglWindowPos3sARB (GLshort, GLshort, GLshort); GLAPI void APIENTRY myglWindowPos3svARB (const GLshort *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2IARBPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2SVARBPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3DVARBPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3FVARBPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3IVARBPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3SVARBPROC) (const GLshort *v); #endif #ifndef MYGL_ARB_vertex_program #define MYGL_ARB_vertex_program 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglVertexAttrib1dARB (GLuint, GLdouble); GLAPI void APIENTRY myglVertexAttrib1dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib1fARB (GLuint, GLfloat); GLAPI void APIENTRY myglVertexAttrib1fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib1sARB (GLuint, GLshort); GLAPI void APIENTRY myglVertexAttrib1svARB (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib2dARB (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib2dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib2fARB (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib2fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib2sARB (GLuint, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib2svARB (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib3dARB (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib3dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib3fARB (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib3fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib3sARB (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib3svARB (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4NbvARB (GLuint, const GLbyte *); GLAPI void APIENTRY myglVertexAttrib4NivARB (GLuint, const GLint *); GLAPI void APIENTRY myglVertexAttrib4NsvARB (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4NubARB (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY myglVertexAttrib4NubvARB (GLuint, const GLubyte *); GLAPI void APIENTRY myglVertexAttrib4NuivARB (GLuint, const GLuint *); GLAPI void APIENTRY myglVertexAttrib4NusvARB (GLuint, const GLushort *); GLAPI void APIENTRY myglVertexAttrib4bvARB (GLuint, const GLbyte *); GLAPI void APIENTRY myglVertexAttrib4dARB (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib4dvARB (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib4fARB (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib4fvARB (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib4ivARB (GLuint, const GLint *); GLAPI void APIENTRY myglVertexAttrib4sARB (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib4svARB (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4ubvARB (GLuint, const GLubyte *); GLAPI void APIENTRY myglVertexAttrib4uivARB (GLuint, const GLuint *); GLAPI void APIENTRY myglVertexAttrib4usvARB (GLuint, const GLushort *); GLAPI void APIENTRY myglVertexAttribPointerARB (GLuint, GLint, GLenum, GLboolean, GLsizei, const GLvoid *); GLAPI void APIENTRY myglEnableVertexAttribArrayARB (GLuint); GLAPI void APIENTRY myglDisableVertexAttribArrayARB (GLuint); GLAPI void APIENTRY myglProgramStringARB (GLenum, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglBindProgramARB (GLenum, GLuint); GLAPI void APIENTRY myglDeleteProgramsARB (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenProgramsARB (GLsizei, GLuint *); GLAPI void APIENTRY myglProgramEnvParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglProgramEnvParameter4dvARB (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY myglProgramEnvParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglProgramEnvParameter4fvARB (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY myglProgramLocalParameter4dARB (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglProgramLocalParameter4dvARB (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY myglProgramLocalParameter4fARB (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglProgramLocalParameter4fvARB (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY myglGetProgramEnvParameterdvARB (GLenum, GLuint, GLdouble *); GLAPI void APIENTRY myglGetProgramEnvParameterfvARB (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY myglGetProgramLocalParameterdvARB (GLenum, GLuint, GLdouble *); GLAPI void APIENTRY myglGetProgramLocalParameterfvARB (GLenum, GLuint, GLfloat *); GLAPI void APIENTRY myglGetProgramivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetProgramStringARB (GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetVertexAttribdvARB (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY myglGetVertexAttribfvARB (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetVertexAttribivARB (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetVertexAttribPointervARB (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY myglIsProgramARB (GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNMYGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); typedef void (APIENTRYP PFNMYGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); typedef void (APIENTRYP PFNMYGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); typedef void (APIENTRYP PFNMYGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNMYGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNMYGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNMYGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNMYGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); typedef void (APIENTRYP PFNMYGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNMYGLISPROGRAMARBPROC) (GLuint program); #endif #ifndef MYGL_ARB_fragment_program #define MYGL_ARB_fragment_program 1 /* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ #endif #ifndef MYGL_ARB_vertex_buffer_object #define MYGL_ARB_vertex_buffer_object 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBindBufferARB (GLenum, GLuint); GLAPI void APIENTRY myglDeleteBuffersARB (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenBuffersARB (GLsizei, GLuint *); GLAPI GLboolean APIENTRY myglIsBufferARB (GLuint); GLAPI void APIENTRY myglBufferDataARB (GLenum, GLsizeiptrARB, const GLvoid *, GLenum); GLAPI void APIENTRY myglBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *); GLAPI void APIENTRY myglGetBufferSubDataARB (GLenum, GLintptrARB, GLsizeiptrARB, GLvoid *); GLAPI GLvoid* APIENTRY myglMapBufferARB (GLenum, GLenum); GLAPI GLboolean APIENTRY myglUnmapBufferARB (GLenum); GLAPI void APIENTRY myglGetBufferParameterivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetBufferPointervARB (GLenum, GLenum, GLvoid* *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); typedef void (APIENTRYP PFNMYGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); typedef void (APIENTRYP PFNMYGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); typedef GLboolean (APIENTRYP PFNMYGLISBUFFERARBPROC) (GLuint buffer); typedef void (APIENTRYP PFNMYGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); typedef void (APIENTRYP PFNMYGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); typedef void (APIENTRYP PFNMYGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); typedef GLvoid* (APIENTRYP PFNMYGLMAPBUFFERARBPROC) (GLenum target, GLenum access); typedef GLboolean (APIENTRYP PFNMYGLUNMAPBUFFERARBPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); #endif #ifndef MYGL_ARB_occlusion_query #define MYGL_ARB_occlusion_query 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGenQueriesARB (GLsizei, GLuint *); GLAPI void APIENTRY myglDeleteQueriesARB (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY myglIsQueryARB (GLuint); GLAPI void APIENTRY myglBeginQueryARB (GLenum, GLuint); GLAPI void APIENTRY myglEndQueryARB (GLenum); GLAPI void APIENTRY myglGetQueryivARB (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetQueryObjectivARB (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetQueryObjectuivARB (GLuint, GLenum, GLuint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNMYGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNMYGLISQUERYARBPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLBEGINQUERYARBPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNMYGLENDQUERYARBPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef MYGL_ARB_shader_objects #define MYGL_ARB_shader_objects 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDeleteObjectARB (GLhandleARB); GLAPI GLhandleARB APIENTRY myglGetHandleARB (GLenum); GLAPI void APIENTRY myglDetachObjectARB (GLhandleARB, GLhandleARB); GLAPI GLhandleARB APIENTRY myglCreateShaderObjectARB (GLenum); GLAPI void APIENTRY myglShaderSourceARB (GLhandleARB, GLsizei, const GLcharARB* *, const GLint *); GLAPI void APIENTRY myglCompileShaderARB (GLhandleARB); GLAPI GLhandleARB APIENTRY myglCreateProgramObjectARB (void); GLAPI void APIENTRY myglAttachObjectARB (GLhandleARB, GLhandleARB); GLAPI void APIENTRY myglLinkProgramARB (GLhandleARB); GLAPI void APIENTRY myglUseProgramObjectARB (GLhandleARB); GLAPI void APIENTRY myglValidateProgramARB (GLhandleARB); GLAPI void APIENTRY myglUniform1fARB (GLint, GLfloat); GLAPI void APIENTRY myglUniform2fARB (GLint, GLfloat, GLfloat); GLAPI void APIENTRY myglUniform3fARB (GLint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglUniform4fARB (GLint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglUniform1iARB (GLint, GLint); GLAPI void APIENTRY myglUniform2iARB (GLint, GLint, GLint); GLAPI void APIENTRY myglUniform3iARB (GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglUniform4iARB (GLint, GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglUniform1fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform2fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform3fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform4fvARB (GLint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglUniform1ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniform2ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniform3ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniform4ivARB (GLint, GLsizei, const GLint *); GLAPI void APIENTRY myglUniformMatrix2fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY myglUniformMatrix3fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY myglUniformMatrix4fvARB (GLint, GLsizei, GLboolean, const GLfloat *); GLAPI void APIENTRY myglGetObjectParameterfvARB (GLhandleARB, GLenum, GLfloat *); GLAPI void APIENTRY myglGetObjectParameterivARB (GLhandleARB, GLenum, GLint *); GLAPI void APIENTRY myglGetInfoLogARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); GLAPI void APIENTRY myglGetAttachedObjectsARB (GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); GLAPI GLint APIENTRY myglGetUniformLocationARB (GLhandleARB, const GLcharARB *); GLAPI void APIENTRY myglGetActiveUniformARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); GLAPI void APIENTRY myglGetUniformfvARB (GLhandleARB, GLint, GLfloat *); GLAPI void APIENTRY myglGetUniformivARB (GLhandleARB, GLint, GLint *); GLAPI void APIENTRY myglGetShaderSourceARB (GLhandleARB, GLsizei, GLsizei *, GLcharARB *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDELETEOBJECTARBPROC) (GLhandleARB obj); typedef GLhandleARB (APIENTRYP PFNMYGLGETHANDLEARBPROC) (GLenum pname); typedef void (APIENTRYP PFNMYGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); typedef GLhandleARB (APIENTRYP PFNMYGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); typedef void (APIENTRYP PFNMYGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); typedef void (APIENTRYP PFNMYGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); typedef GLhandleARB (APIENTRYP PFNMYGLCREATEPROGRAMOBJECTARBPROC) (void); typedef void (APIENTRYP PFNMYGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); typedef void (APIENTRYP PFNMYGLLINKPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNMYGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNMYGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); typedef void (APIENTRYP PFNMYGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); typedef void (APIENTRYP PFNMYGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); typedef void (APIENTRYP PFNMYGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); typedef void (APIENTRYP PFNMYGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); typedef void (APIENTRYP PFNMYGLUNIFORM1IARBPROC) (GLint location, GLint v0); typedef void (APIENTRYP PFNMYGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); typedef void (APIENTRYP PFNMYGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); typedef void (APIENTRYP PFNMYGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); typedef void (APIENTRYP PFNMYGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); typedef void (APIENTRYP PFNMYGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNMYGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); typedef void (APIENTRYP PFNMYGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); typedef void (APIENTRYP PFNMYGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); typedef GLint (APIENTRYP PFNMYGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); typedef void (APIENTRYP PFNMYGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef void (APIENTRYP PFNMYGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); typedef void (APIENTRYP PFNMYGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); #endif #ifndef MYGL_ARB_vertex_shader #define MYGL_ARB_vertex_shader 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBindAttribLocationARB (GLhandleARB, GLuint, const GLcharARB *); GLAPI void APIENTRY myglGetActiveAttribARB (GLhandleARB, GLuint, GLsizei, GLsizei *, GLint *, GLenum *, GLcharARB *); GLAPI GLint APIENTRY myglGetAttribLocationARB (GLhandleARB, const GLcharARB *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); typedef void (APIENTRYP PFNMYGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); typedef GLint (APIENTRYP PFNMYGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); #endif #ifndef MYGL_ARB_fragment_shader #define MYGL_ARB_fragment_shader 1 #endif #ifndef MYGL_ARB_shading_language_100 #define MYGL_ARB_shading_language_100 1 #endif #ifndef MYGL_ARB_texture_non_power_of_two #define MYGL_ARB_texture_non_power_of_two 1 #endif #ifndef MYGL_ARB_point_sprite #define MYGL_ARB_point_sprite 1 #endif #ifndef MYGL_ARB_fragment_program_shadow #define MYGL_ARB_fragment_program_shadow 1 #endif #ifndef MYGL_ARB_draw_buffers #define MYGL_ARB_draw_buffers 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDrawBuffersARB (GLsizei, const GLenum *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); #endif #ifndef MYGL_ARB_texture_rectangle #define MYGL_ARB_texture_rectangle 1 #endif #ifndef MYGL_ARB_color_buffer_float #define MYGL_ARB_color_buffer_float 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglClampColorARB (GLenum, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); #endif #ifndef MYGL_ARB_half_float_pixel #define MYGL_ARB_half_float_pixel 1 #endif #ifndef MYGL_ARB_texture_float #define MYGL_ARB_texture_float 1 #endif #ifndef MYGL_ARB_pixel_buffer_object #define MYGL_ARB_pixel_buffer_object 1 #endif #ifndef MYGL_EXT_abgr #define MYGL_EXT_abgr 1 #endif #ifndef MYGL_EXT_blend_color #define MYGL_EXT_blend_color 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendColorEXT (GLclampf, GLclampf, GLclampf, GLclampf); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); #endif #ifndef MYGL_EXT_polygon_offset #define MYGL_EXT_polygon_offset 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPolygonOffsetEXT (GLfloat, GLfloat); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); #endif #ifndef MYGL_EXT_texture #define MYGL_EXT_texture 1 #endif #ifndef MYGL_EXT_texture3D #define MYGL_EXT_texture3D 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTexImage3DEXT (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNMYGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef MYGL_SGIS_texture_filter4 #define MYGL_SGIS_texture_filter4 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGetTexFilterFuncSGIS (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglTexFilterFuncSGIS (GLenum, GLenum, GLsizei, const GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); typedef void (APIENTRYP PFNMYGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); #endif #ifndef MYGL_EXT_subtexture #define MYGL_EXT_subtexture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTexSubImage1DEXT (GLenum, GLint, GLint, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNMYGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef MYGL_EXT_copy_texture #define MYGL_EXT_copy_texture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglCopyTexImage1DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLint); GLAPI void APIENTRY myglCopyTexImage2DEXT (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); GLAPI void APIENTRY myglCopyTexSubImage1DEXT (GLenum, GLint, GLint, GLint, GLint, GLsizei); GLAPI void APIENTRY myglCopyTexSubImage2DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY myglCopyTexSubImage3DEXT (GLenum, GLint, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); typedef void (APIENTRYP PFNMYGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); typedef void (APIENTRYP PFNMYGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNMYGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNMYGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); #endif #ifndef MYGL_EXT_histogram #define MYGL_EXT_histogram 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGetHistogramEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetHistogramParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetHistogramParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetMinmaxEXT (GLenum, GLboolean, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetMinmaxParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetMinmaxParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglHistogramEXT (GLenum, GLsizei, GLenum, GLboolean); GLAPI void APIENTRY myglMinmaxEXT (GLenum, GLenum, GLboolean); GLAPI void APIENTRY myglResetHistogramEXT (GLenum); GLAPI void APIENTRY myglResetMinmaxEXT (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNMYGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); typedef void (APIENTRYP PFNMYGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNMYGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); typedef void (APIENTRYP PFNMYGLRESETHISTOGRAMEXTPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLRESETMINMAXEXTPROC) (GLenum target); #endif #ifndef MYGL_EXT_convolution #define MYGL_EXT_convolution 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglConvolutionFilter1DEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglConvolutionFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglConvolutionParameterfEXT (GLenum, GLenum, GLfloat); GLAPI void APIENTRY myglConvolutionParameterfvEXT (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglConvolutionParameteriEXT (GLenum, GLenum, GLint); GLAPI void APIENTRY myglConvolutionParameterivEXT (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglCopyConvolutionFilter1DEXT (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY myglCopyConvolutionFilter2DEXT (GLenum, GLenum, GLint, GLint, GLsizei, GLsizei); GLAPI void APIENTRY myglGetConvolutionFilterEXT (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetConvolutionParameterfvEXT (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetConvolutionParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetSeparableFilterEXT (GLenum, GLenum, GLenum, GLvoid *, GLvoid *, GLvoid *); GLAPI void APIENTRY myglSeparableFilter2DEXT (GLenum, GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNMYGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); typedef void (APIENTRYP PFNMYGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNMYGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNMYGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); typedef void (APIENTRYP PFNMYGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); typedef void (APIENTRYP PFNMYGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); #endif #ifndef MYGL_EXT_color_matrix #define MYGL_EXT_color_matrix 1 #endif #ifndef MYGL_SGI_color_table #define MYGL_SGI_color_table 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglColorTableSGI (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglColorTableParameterfvSGI (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglColorTableParameterivSGI (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglCopyColorTableSGI (GLenum, GLenum, GLint, GLint, GLsizei); GLAPI void APIENTRY myglGetColorTableSGI (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetColorTableParameterfvSGI (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetColorTableParameterivSGI (GLenum, GLenum, GLint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNMYGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); typedef void (APIENTRYP PFNMYGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); #endif #ifndef MYGL_SGIX_pixel_texture #define MYGL_SGIX_pixel_texture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPixelTexGenSGIX (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPIXELTEXGENSGIXPROC) (GLenum mode); #endif #ifndef MYGL_SGIS_pixel_texture #define MYGL_SGIS_pixel_texture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPixelTexGenParameteriSGIS (GLenum, GLint); GLAPI void APIENTRY myglPixelTexGenParameterivSGIS (GLenum, const GLint *); GLAPI void APIENTRY myglPixelTexGenParameterfSGIS (GLenum, GLfloat); GLAPI void APIENTRY myglPixelTexGenParameterfvSGIS (GLenum, const GLfloat *); GLAPI void APIENTRY myglGetPixelTexGenParameterivSGIS (GLenum, GLint *); GLAPI void APIENTRY myglGetPixelTexGenParameterfvSGIS (GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); #endif #ifndef MYGL_SGIS_texture4D #define MYGL_SGIS_texture4D 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTexImage4DSGIS (GLenum, GLint, GLenum, GLsizei, GLsizei, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglTexSubImage4DSGIS (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); typedef void (APIENTRYP PFNMYGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); #endif #ifndef MYGL_SGI_texture_color_table #define MYGL_SGI_texture_color_table 1 #endif #ifndef MYGL_EXT_cmyka #define MYGL_EXT_cmyka 1 #endif #ifndef MYGL_EXT_texture_object #define MYGL_EXT_texture_object 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY myglAreTexturesResidentEXT (GLsizei, const GLuint *, GLboolean *); GLAPI void APIENTRY myglBindTextureEXT (GLenum, GLuint); GLAPI void APIENTRY myglDeleteTexturesEXT (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenTexturesEXT (GLsizei, GLuint *); GLAPI GLboolean APIENTRY myglIsTextureEXT (GLuint); GLAPI void APIENTRY myglPrioritizeTexturesEXT (GLsizei, const GLuint *, const GLclampf *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNMYGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); typedef void (APIENTRYP PFNMYGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); typedef void (APIENTRYP PFNMYGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); typedef void (APIENTRYP PFNMYGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); typedef GLboolean (APIENTRYP PFNMYGLISTEXTUREEXTPROC) (GLuint texture); typedef void (APIENTRYP PFNMYGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); #endif #ifndef MYGL_SGIS_detail_texture #define MYGL_SGIS_detail_texture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDetailTexFuncSGIS (GLenum, GLsizei, const GLfloat *); GLAPI void APIENTRY myglGetDetailTexFuncSGIS (GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNMYGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef MYGL_SGIS_sharpen_texture #define MYGL_SGIS_sharpen_texture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglSharpenTexFuncSGIS (GLenum, GLsizei, const GLfloat *); GLAPI void APIENTRY myglGetSharpenTexFuncSGIS (GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNMYGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); #endif #ifndef MYGL_EXT_packed_pixels #define MYGL_EXT_packed_pixels 1 #endif #ifndef MYGL_SGIS_texture_lod #define MYGL_SGIS_texture_lod 1 #endif #ifndef MYGL_SGIS_multisample #define MYGL_SGIS_multisample 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglSampleMaskSGIS (GLclampf, GLboolean); GLAPI void APIENTRY myglSamplePatternSGIS (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNMYGLSAMPLEPATTERNSGISPROC) (GLenum pattern); #endif #ifndef MYGL_EXT_rescale_normal #define MYGL_EXT_rescale_normal 1 #endif #ifndef MYGL_EXT_vertex_array #define MYGL_EXT_vertex_array 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglArrayElementEXT (GLint); GLAPI void APIENTRY myglColorPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY myglDrawArraysEXT (GLenum, GLint, GLsizei); GLAPI void APIENTRY myglEdgeFlagPointerEXT (GLsizei, GLsizei, const GLboolean *); GLAPI void APIENTRY myglGetPointervEXT (GLenum, GLvoid* *); GLAPI void APIENTRY myglIndexPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY myglNormalPointerEXT (GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY myglTexCoordPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); GLAPI void APIENTRY myglVertexPointerEXT (GLint, GLenum, GLsizei, GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLARRAYELEMENTEXTPROC) (GLint i); typedef void (APIENTRYP PFNMYGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNMYGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); typedef void (APIENTRYP PFNMYGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); typedef void (APIENTRYP PFNMYGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); #endif #ifndef MYGL_EXT_misc_attribute #define MYGL_EXT_misc_attribute 1 #endif #ifndef MYGL_SGIS_generate_mipmap #define MYGL_SGIS_generate_mipmap 1 #endif #ifndef MYGL_SGIX_clipmap #define MYGL_SGIX_clipmap 1 #endif #ifndef MYGL_SGIX_shadow #define MYGL_SGIX_shadow 1 #endif #ifndef MYGL_SGIS_texture_edge_clamp #define MYGL_SGIS_texture_edge_clamp 1 #endif #ifndef MYGL_SGIS_texture_border_clamp #define MYGL_SGIS_texture_border_clamp 1 #endif #ifndef MYGL_EXT_blend_minmax #define MYGL_EXT_blend_minmax 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendEquationEXT (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDEQUATIONEXTPROC) (GLenum mode); #endif #ifndef MYGL_EXT_blend_subtract #define MYGL_EXT_blend_subtract 1 #endif #ifndef MYGL_EXT_blend_logic_op #define MYGL_EXT_blend_logic_op 1 #endif #ifndef MYGL_SGIX_interlace #define MYGL_SGIX_interlace 1 #endif #ifndef MYGL_SGIX_pixel_tiles #define MYGL_SGIX_pixel_tiles 1 #endif #ifndef MYGL_SGIX_texture_select #define MYGL_SGIX_texture_select 1 #endif #ifndef MYGL_SGIX_sprite #define MYGL_SGIX_sprite 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglSpriteParameterfSGIX (GLenum, GLfloat); GLAPI void APIENTRY myglSpriteParameterfvSGIX (GLenum, const GLfloat *); GLAPI void APIENTRY myglSpriteParameteriSGIX (GLenum, GLint); GLAPI void APIENTRY myglSpriteParameterivSGIX (GLenum, const GLint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); #endif #ifndef MYGL_SGIX_texture_multi_buffer #define MYGL_SGIX_texture_multi_buffer 1 #endif #ifndef MYGL_EXT_point_parameters #define MYGL_EXT_point_parameters 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPointParameterfEXT (GLenum, GLfloat); GLAPI void APIENTRY myglPointParameterfvEXT (GLenum, const GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); #endif #ifndef MYGL_SGIS_point_parameters #define MYGL_SGIS_point_parameters 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPointParameterfSGIS (GLenum, GLfloat); GLAPI void APIENTRY myglPointParameterfvSGIS (GLenum, const GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); #endif #ifndef MYGL_SGIX_instruments #define MYGL_SGIX_instruments 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI GLint APIENTRY myglGetInstrumentsSGIX (void); GLAPI void APIENTRY myglInstrumentsBufferSGIX (GLsizei, GLint *); GLAPI GLint APIENTRY myglPollInstrumentsSGIX (GLint *); GLAPI void APIENTRY myglReadInstrumentsSGIX (GLint); GLAPI void APIENTRY myglStartInstrumentsSGIX (void); GLAPI void APIENTRY myglStopInstrumentsSGIX (GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef GLint (APIENTRYP PFNMYGLGETINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNMYGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); typedef GLint (APIENTRYP PFNMYGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); typedef void (APIENTRYP PFNMYGLREADINSTRUMENTSSGIXPROC) (GLint marker); typedef void (APIENTRYP PFNMYGLSTARTINSTRUMENTSSGIXPROC) (void); typedef void (APIENTRYP PFNMYGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); #endif #ifndef MYGL_SGIX_texture_scale_bias #define MYGL_SGIX_texture_scale_bias 1 #endif #ifndef MYGL_SGIX_framezoom #define MYGL_SGIX_framezoom 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglFrameZoomSGIX (GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLFRAMEZOOMSGIXPROC) (GLint factor); #endif #ifndef MYGL_SGIX_tag_sample_buffer #define MYGL_SGIX_tag_sample_buffer 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTagSampleBufferSGIX (void); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTAGSAMPLEBUFFERSGIXPROC) (void); #endif #ifndef MYGL_SGIX_polynomial_ffd #define MYGL_SGIX_polynomial_ffd 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDeformationMap3dSGIX (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *); GLAPI void APIENTRY myglDeformationMap3fSGIX (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *); GLAPI void APIENTRY myglDeformSGIX (GLbitfield); GLAPI void APIENTRY myglLoadIdentityDeformationMapSGIX (GLbitfield); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); typedef void (APIENTRYP PFNMYGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); typedef void (APIENTRYP PFNMYGLDEFORMSGIXPROC) (GLbitfield mask); typedef void (APIENTRYP PFNMYGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); #endif #ifndef MYGL_SGIX_reference_plane #define MYGL_SGIX_reference_plane 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglReferencePlaneSGIX (const GLdouble *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); #endif #ifndef MYGL_SGIX_flush_raster #define MYGL_SGIX_flush_raster 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglFlushRasterSGIX (void); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLFLUSHRASTERSGIXPROC) (void); #endif #ifndef MYGL_SGIX_depth_texture #define MYGL_SGIX_depth_texture 1 #endif #ifndef MYGL_SGIS_fog_function #define MYGL_SGIS_fog_function 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglFogFuncSGIS (GLsizei, const GLfloat *); GLAPI void APIENTRY myglGetFogFuncSGIS (GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); typedef void (APIENTRYP PFNMYGLGETFOGFUNCSGISPROC) (GLfloat *points); #endif #ifndef MYGL_SGIX_fog_offset #define MYGL_SGIX_fog_offset 1 #endif #ifndef MYGL_HP_image_transform #define MYGL_HP_image_transform 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglImageTransformParameteriHP (GLenum, GLenum, GLint); GLAPI void APIENTRY myglImageTransformParameterfHP (GLenum, GLenum, GLfloat); GLAPI void APIENTRY myglImageTransformParameterivHP (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglImageTransformParameterfvHP (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglGetImageTransformParameterivHP (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetImageTransformParameterfvHP (GLenum, GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef MYGL_HP_convolution_border_modes #define MYGL_HP_convolution_border_modes 1 #endif #ifndef MYGL_SGIX_texture_add_env #define MYGL_SGIX_texture_add_env 1 #endif #ifndef MYGL_EXT_color_subtable #define MYGL_EXT_color_subtable 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglColorSubTableEXT (GLenum, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglCopyColorSubTableEXT (GLenum, GLsizei, GLint, GLint, GLsizei); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); typedef void (APIENTRYP PFNMYGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); #endif #ifndef MYGL_PGI_vertex_hints #define MYGL_PGI_vertex_hints 1 #endif #ifndef MYGL_PGI_misc_hints #define MYGL_PGI_misc_hints 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglHintPGI (GLenum, GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLHINTPGIPROC) (GLenum target, GLint mode); #endif #ifndef MYGL_EXT_paletted_texture #define MYGL_EXT_paletted_texture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglColorTableEXT (GLenum, GLenum, GLsizei, GLenum, GLenum, const GLvoid *); GLAPI void APIENTRY myglGetColorTableEXT (GLenum, GLenum, GLenum, GLvoid *); GLAPI void APIENTRY myglGetColorTableParameterivEXT (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetColorTableParameterfvEXT (GLenum, GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); #endif #ifndef MYGL_EXT_clip_volume_hint #define MYGL_EXT_clip_volume_hint 1 #endif #ifndef MYGL_SGIX_list_priority #define MYGL_SGIX_list_priority 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGetListParameterfvSGIX (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetListParameterivSGIX (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglListParameterfSGIX (GLuint, GLenum, GLfloat); GLAPI void APIENTRY myglListParameterfvSGIX (GLuint, GLenum, const GLfloat *); GLAPI void APIENTRY myglListParameteriSGIX (GLuint, GLenum, GLint); GLAPI void APIENTRY myglListParameterivSGIX (GLuint, GLenum, const GLint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); #endif #ifndef MYGL_SGIX_ir_instrument1 #define MYGL_SGIX_ir_instrument1 1 #endif #ifndef MYGL_SGIX_calligraphic_fragment #define MYGL_SGIX_calligraphic_fragment 1 #endif #ifndef MYGL_SGIX_texture_lod_bias #define MYGL_SGIX_texture_lod_bias 1 #endif #ifndef MYGL_SGIX_shadow_ambient #define MYGL_SGIX_shadow_ambient 1 #endif #ifndef MYGL_EXT_index_texture #define MYGL_EXT_index_texture 1 #endif #ifndef MYGL_EXT_index_material #define MYGL_EXT_index_material 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglIndexMaterialEXT (GLenum, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef MYGL_EXT_index_func #define MYGL_EXT_index_func 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglIndexFuncEXT (GLenum, GLclampf); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); #endif #ifndef MYGL_EXT_index_array_formats #define MYGL_EXT_index_array_formats 1 #endif #ifndef MYGL_EXT_compiled_vertex_array #define MYGL_EXT_compiled_vertex_array 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglLockArraysEXT (GLint, GLsizei); GLAPI void APIENTRY myglUnlockArraysEXT (void); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); typedef void (APIENTRYP PFNMYGLUNLOCKARRAYSEXTPROC) (void); #endif #ifndef MYGL_EXT_cull_vertex #define MYGL_EXT_cull_vertex 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglCullParameterdvEXT (GLenum, GLdouble *); GLAPI void APIENTRY myglCullParameterfvEXT (GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNMYGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); #endif #ifndef MYGL_SGIX_ycrcb #define MYGL_SGIX_ycrcb 1 #endif #ifndef MYGL_SGIX_fragment_lighting #define MYGL_SGIX_fragment_lighting 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglFragmentColorMaterialSGIX (GLenum, GLenum); GLAPI void APIENTRY myglFragmentLightfSGIX (GLenum, GLenum, GLfloat); GLAPI void APIENTRY myglFragmentLightfvSGIX (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglFragmentLightiSGIX (GLenum, GLenum, GLint); GLAPI void APIENTRY myglFragmentLightivSGIX (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglFragmentLightModelfSGIX (GLenum, GLfloat); GLAPI void APIENTRY myglFragmentLightModelfvSGIX (GLenum, const GLfloat *); GLAPI void APIENTRY myglFragmentLightModeliSGIX (GLenum, GLint); GLAPI void APIENTRY myglFragmentLightModelivSGIX (GLenum, const GLint *); GLAPI void APIENTRY myglFragmentMaterialfSGIX (GLenum, GLenum, GLfloat); GLAPI void APIENTRY myglFragmentMaterialfvSGIX (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglFragmentMaterialiSGIX (GLenum, GLenum, GLint); GLAPI void APIENTRY myglFragmentMaterialivSGIX (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglGetFragmentLightfvSGIX (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetFragmentLightivSGIX (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetFragmentMaterialfvSGIX (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetFragmentMaterialivSGIX (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglLightEnviSGIX (GLenum, GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); #endif #ifndef MYGL_IBM_rasterpos_clip #define MYGL_IBM_rasterpos_clip 1 #endif #ifndef MYGL_HP_texture_lighting #define MYGL_HP_texture_lighting 1 #endif #ifndef MYGL_EXT_draw_range_elements #define MYGL_EXT_draw_range_elements 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDrawRangeElementsEXT (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); #endif #ifndef MYGL_WIN_phong_shading #define MYGL_WIN_phong_shading 1 #endif #ifndef MYGL_WIN_specular_fog #define MYGL_WIN_specular_fog 1 #endif #ifndef MYGL_EXT_light_texture #define MYGL_EXT_light_texture 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglApplyTextureEXT (GLenum); GLAPI void APIENTRY myglTextureLightEXT (GLenum); GLAPI void APIENTRY myglTextureMaterialEXT (GLenum, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLAPPLYTEXTUREEXTPROC) (GLenum mode); typedef void (APIENTRYP PFNMYGLTEXTURELIGHTEXTPROC) (GLenum pname); typedef void (APIENTRYP PFNMYGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); #endif #ifndef MYGL_SGIX_blend_alpha_minmax #define MYGL_SGIX_blend_alpha_minmax 1 #endif #ifndef MYGL_EXT_bgra #define MYGL_EXT_bgra 1 #endif #ifndef MYGL_SGIX_async #define MYGL_SGIX_async 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglAsyncMarkerSGIX (GLuint); GLAPI GLint APIENTRY myglFinishAsyncSGIX (GLuint *); GLAPI GLint APIENTRY myglPollAsyncSGIX (GLuint *); GLAPI GLuint APIENTRY myglGenAsyncMarkersSGIX (GLsizei); GLAPI void APIENTRY myglDeleteAsyncMarkersSGIX (GLuint, GLsizei); GLAPI GLboolean APIENTRY myglIsAsyncMarkerSGIX (GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLASYNCMARKERSGIXPROC) (GLuint marker); typedef GLint (APIENTRYP PFNMYGLFINISHASYNCSGIXPROC) (GLuint *markerp); typedef GLint (APIENTRYP PFNMYGLPOLLASYNCSGIXPROC) (GLuint *markerp); typedef GLuint (APIENTRYP PFNMYGLGENASYNCMARKERSSGIXPROC) (GLsizei range); typedef void (APIENTRYP PFNMYGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); typedef GLboolean (APIENTRYP PFNMYGLISASYNCMARKERSGIXPROC) (GLuint marker); #endif #ifndef MYGL_SGIX_async_pixel #define MYGL_SGIX_async_pixel 1 #endif #ifndef MYGL_SGIX_async_histogram #define MYGL_SGIX_async_histogram 1 #endif #ifndef MYGL_INTEL_parallel_arrays #define MYGL_INTEL_parallel_arrays 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglVertexPointervINTEL (GLint, GLenum, const GLvoid* *); GLAPI void APIENTRY myglNormalPointervINTEL (GLenum, const GLvoid* *); GLAPI void APIENTRY myglColorPointervINTEL (GLint, GLenum, const GLvoid* *); GLAPI void APIENTRY myglTexCoordPointervINTEL (GLint, GLenum, const GLvoid* *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNMYGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNMYGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); typedef void (APIENTRYP PFNMYGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); #endif #ifndef MYGL_HP_occlusion_test #define MYGL_HP_occlusion_test 1 #endif #ifndef MYGL_EXT_pixel_transform #define MYGL_EXT_pixel_transform 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPixelTransformParameteriEXT (GLenum, GLenum, GLint); GLAPI void APIENTRY myglPixelTransformParameterfEXT (GLenum, GLenum, GLfloat); GLAPI void APIENTRY myglPixelTransformParameterivEXT (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglPixelTransformParameterfvEXT (GLenum, GLenum, const GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); #endif #ifndef MYGL_EXT_pixel_transform_color_table #define MYGL_EXT_pixel_transform_color_table 1 #endif #ifndef MYGL_EXT_shared_texture_palette #define MYGL_EXT_shared_texture_palette 1 #endif #ifndef MYGL_EXT_separate_specular_color #define MYGL_EXT_separate_specular_color 1 #endif #ifndef MYGL_EXT_secondary_color #define MYGL_EXT_secondary_color 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglSecondaryColor3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY myglSecondaryColor3bvEXT (const GLbyte *); GLAPI void APIENTRY myglSecondaryColor3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglSecondaryColor3dvEXT (const GLdouble *); GLAPI void APIENTRY myglSecondaryColor3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglSecondaryColor3fvEXT (const GLfloat *); GLAPI void APIENTRY myglSecondaryColor3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY myglSecondaryColor3ivEXT (const GLint *); GLAPI void APIENTRY myglSecondaryColor3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY myglSecondaryColor3svEXT (const GLshort *); GLAPI void APIENTRY myglSecondaryColor3ubEXT (GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY myglSecondaryColor3ubvEXT (const GLubyte *); GLAPI void APIENTRY myglSecondaryColor3uiEXT (GLuint, GLuint, GLuint); GLAPI void APIENTRY myglSecondaryColor3uivEXT (const GLuint *); GLAPI void APIENTRY myglSecondaryColor3usEXT (GLushort, GLushort, GLushort); GLAPI void APIENTRY myglSecondaryColor3usvEXT (const GLushort *); GLAPI void APIENTRY myglSecondaryColorPointerEXT (GLint, GLenum, GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); typedef void (APIENTRYP PFNMYGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef MYGL_EXT_texture_perturb_normal #define MYGL_EXT_texture_perturb_normal 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTextureNormalEXT (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTEXTURENORMALEXTPROC) (GLenum mode); #endif #ifndef MYGL_EXT_multi_draw_arrays #define MYGL_EXT_multi_draw_arrays 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglMultiDrawArraysEXT (GLenum, GLint *, GLsizei *, GLsizei); GLAPI void APIENTRY myglMultiDrawElementsEXT (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, GLint *first, GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNMYGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); #endif #ifndef MYGL_EXT_fog_coord #define MYGL_EXT_fog_coord 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglFogCoordfEXT (GLfloat); GLAPI void APIENTRY myglFogCoordfvEXT (const GLfloat *); GLAPI void APIENTRY myglFogCoorddEXT (GLdouble); GLAPI void APIENTRY myglFogCoorddvEXT (const GLdouble *); GLAPI void APIENTRY myglFogCoordPointerEXT (GLenum, GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLFOGCOORDFEXTPROC) (GLfloat coord); typedef void (APIENTRYP PFNMYGLFOGCOORDFVEXTPROC) (const GLfloat *coord); typedef void (APIENTRYP PFNMYGLFOGCOORDDEXTPROC) (GLdouble coord); typedef void (APIENTRYP PFNMYGLFOGCOORDDVEXTPROC) (const GLdouble *coord); typedef void (APIENTRYP PFNMYGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef MYGL_REND_screen_coordinates #define MYGL_REND_screen_coordinates 1 #endif #ifndef MYGL_EXT_coordinate_frame #define MYGL_EXT_coordinate_frame 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTangent3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY myglTangent3bvEXT (const GLbyte *); GLAPI void APIENTRY myglTangent3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglTangent3dvEXT (const GLdouble *); GLAPI void APIENTRY myglTangent3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTangent3fvEXT (const GLfloat *); GLAPI void APIENTRY myglTangent3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY myglTangent3ivEXT (const GLint *); GLAPI void APIENTRY myglTangent3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY myglTangent3svEXT (const GLshort *); GLAPI void APIENTRY myglBinormal3bEXT (GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY myglBinormal3bvEXT (const GLbyte *); GLAPI void APIENTRY myglBinormal3dEXT (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglBinormal3dvEXT (const GLdouble *); GLAPI void APIENTRY myglBinormal3fEXT (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglBinormal3fvEXT (const GLfloat *); GLAPI void APIENTRY myglBinormal3iEXT (GLint, GLint, GLint); GLAPI void APIENTRY myglBinormal3ivEXT (const GLint *); GLAPI void APIENTRY myglBinormal3sEXT (GLshort, GLshort, GLshort); GLAPI void APIENTRY myglBinormal3svEXT (const GLshort *); GLAPI void APIENTRY myglTangentPointerEXT (GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglBinormalPointerEXT (GLenum, GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); typedef void (APIENTRYP PFNMYGLTANGENT3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNMYGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); typedef void (APIENTRYP PFNMYGLTANGENT3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); typedef void (APIENTRYP PFNMYGLTANGENT3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); typedef void (APIENTRYP PFNMYGLTANGENT3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); typedef void (APIENTRYP PFNMYGLTANGENT3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); typedef void (APIENTRYP PFNMYGLBINORMAL3BVEXTPROC) (const GLbyte *v); typedef void (APIENTRYP PFNMYGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); typedef void (APIENTRYP PFNMYGLBINORMAL3DVEXTPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); typedef void (APIENTRYP PFNMYGLBINORMAL3FVEXTPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); typedef void (APIENTRYP PFNMYGLBINORMAL3IVEXTPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); typedef void (APIENTRYP PFNMYGLBINORMAL3SVEXTPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef MYGL_EXT_texture_env_combine #define MYGL_EXT_texture_env_combine 1 #endif #ifndef MYGL_APPLE_specular_vector #define MYGL_APPLE_specular_vector 1 #endif #ifndef MYGL_APPLE_transform_hint #define MYGL_APPLE_transform_hint 1 #endif #ifndef MYGL_SGIX_fog_scale #define MYGL_SGIX_fog_scale 1 #endif #ifndef MYGL_SUNX_constant_data #define MYGL_SUNX_constant_data 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglFinishTextureSUNX (void); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLFINISHTEXTURESUNXPROC) (void); #endif #ifndef MYGL_SUN_global_alpha #define MYGL_SUN_global_alpha 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGlobalAlphaFactorbSUN (GLbyte); GLAPI void APIENTRY myglGlobalAlphaFactorsSUN (GLshort); GLAPI void APIENTRY myglGlobalAlphaFactoriSUN (GLint); GLAPI void APIENTRY myglGlobalAlphaFactorfSUN (GLfloat); GLAPI void APIENTRY myglGlobalAlphaFactordSUN (GLdouble); GLAPI void APIENTRY myglGlobalAlphaFactorubSUN (GLubyte); GLAPI void APIENTRY myglGlobalAlphaFactorusSUN (GLushort); GLAPI void APIENTRY myglGlobalAlphaFactoruiSUN (GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORISUNPROC) (GLint factor); typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); typedef void (APIENTRYP PFNMYGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); #endif #ifndef MYGL_SUN_triangle_list #define MYGL_SUN_triangle_list 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglReplacementCodeuiSUN (GLuint); GLAPI void APIENTRY myglReplacementCodeusSUN (GLushort); GLAPI void APIENTRY myglReplacementCodeubSUN (GLubyte); GLAPI void APIENTRY myglReplacementCodeuivSUN (const GLuint *); GLAPI void APIENTRY myglReplacementCodeusvSUN (const GLushort *); GLAPI void APIENTRY myglReplacementCodeubvSUN (const GLubyte *); GLAPI void APIENTRY myglReplacementCodePointerSUN (GLenum, GLsizei, const GLvoid* *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUISUNPROC) (GLuint code); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUSSUNPROC) (GLushort code); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); #endif #ifndef MYGL_SUN_vertex #define MYGL_SUN_vertex 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglColor4ubVertex2fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat); GLAPI void APIENTRY myglColor4ubVertex2fvSUN (const GLubyte *, const GLfloat *); GLAPI void APIENTRY myglColor4ubVertex3fSUN (GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglColor4ubVertex3fvSUN (const GLubyte *, const GLfloat *); GLAPI void APIENTRY myglColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglColor3fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglTexCoord2fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTexCoord2fVertex3fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglTexCoord4fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTexCoord4fVertex4fvSUN (const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglTexCoord2fColor4ubVertex3fSUN (GLfloat, GLfloat, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTexCoord2fColor4ubVertex3fvSUN (const GLfloat *, const GLubyte *, const GLfloat *); GLAPI void APIENTRY myglTexCoord2fColor3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTexCoord2fColor3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglTexCoord2fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTexCoord2fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiVertex3fvSUN (const GLuint *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiColor4ubVertex3fSUN (GLuint, GLubyte, GLubyte, GLubyte, GLubyte, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *, const GLubyte *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiColor3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiColor3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiTexCoord2fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *); GLAPI void APIENTRY myglReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *, const GLfloat *, const GLfloat *, const GLfloat *, const GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNMYGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNMYGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNMYGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNMYGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNMYGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNMYGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNMYGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); #endif #ifndef MYGL_EXT_blend_func_separate #define MYGL_EXT_blend_func_separate 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendFuncSeparateEXT (GLenum, GLenum, GLenum, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef MYGL_INGR_blend_func_separate #define MYGL_INGR_blend_func_separate 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendFuncSeparateINGR (GLenum, GLenum, GLenum, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); #endif #ifndef MYGL_INGR_color_clamp #define MYGL_INGR_color_clamp 1 #endif #ifndef MYGL_INGR_interlace_read #define MYGL_INGR_interlace_read 1 #endif #ifndef MYGL_EXT_stencil_wrap #define MYGL_EXT_stencil_wrap 1 #endif #ifndef MYGL_EXT_422_pixels #define MYGL_EXT_422_pixels 1 #endif #ifndef MYGL_NV_texgen_reflection #define MYGL_NV_texgen_reflection 1 #endif #ifndef MYGL_SUN_convolution_border_modes #define MYGL_SUN_convolution_border_modes 1 #endif #ifndef MYGL_EXT_texture_env_add #define MYGL_EXT_texture_env_add 1 #endif #ifndef MYGL_EXT_texture_lod_bias #define MYGL_EXT_texture_lod_bias 1 #endif #ifndef MYGL_EXT_texture_filter_anisotropic #define MYGL_EXT_texture_filter_anisotropic 1 #endif #ifndef MYGL_EXT_vertex_weighting #define MYGL_EXT_vertex_weighting 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglVertexWeightfEXT (GLfloat); GLAPI void APIENTRY myglVertexWeightfvEXT (const GLfloat *); GLAPI void APIENTRY myglVertexWeightPointerEXT (GLsizei, GLenum, GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); typedef void (APIENTRYP PFNMYGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); typedef void (APIENTRYP PFNMYGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); #endif #ifndef MYGL_NV_light_max_exponent #define MYGL_NV_light_max_exponent 1 #endif #ifndef MYGL_NV_vertex_array_range #define MYGL_NV_vertex_array_range 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglFlushVertexArrayRangeNV (void); GLAPI void APIENTRY myglVertexArrayRangeNV (GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLFLUSHVERTEXARRAYRANGENVPROC) (void); typedef void (APIENTRYP PFNMYGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); #endif #ifndef MYGL_NV_register_combiners #define MYGL_NV_register_combiners 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglCombinerParameterfvNV (GLenum, const GLfloat *); GLAPI void APIENTRY myglCombinerParameterfNV (GLenum, GLfloat); GLAPI void APIENTRY myglCombinerParameterivNV (GLenum, const GLint *); GLAPI void APIENTRY myglCombinerParameteriNV (GLenum, GLint); GLAPI void APIENTRY myglCombinerInputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY myglCombinerOutputNV (GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLenum, GLboolean, GLboolean, GLboolean); GLAPI void APIENTRY myglFinalCombinerInputNV (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY myglGetCombinerInputParameterfvNV (GLenum, GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetCombinerInputParameterivNV (GLenum, GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetCombinerOutputParameterfvNV (GLenum, GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetCombinerOutputParameterivNV (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetFinalCombinerInputParameterfvNV (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetFinalCombinerInputParameterivNV (GLenum, GLenum, GLint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); typedef void (APIENTRYP PFNMYGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNMYGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); typedef void (APIENTRYP PFNMYGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); typedef void (APIENTRYP PFNMYGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); #endif #ifndef MYGL_NV_fog_distance #define MYGL_NV_fog_distance 1 #endif #ifndef MYGL_NV_texgen_emboss #define MYGL_NV_texgen_emboss 1 #endif #ifndef MYGL_NV_blend_square #define MYGL_NV_blend_square 1 #endif #ifndef MYGL_NV_texture_env_combine4 #define MYGL_NV_texture_env_combine4 1 #endif #ifndef MYGL_MESA_resize_buffers #define MYGL_MESA_resize_buffers 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglResizeBuffersMESA (void); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLRESIZEBUFFERSMESAPROC) (void); #endif #ifndef MYGL_MESA_window_pos #define MYGL_MESA_window_pos 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglWindowPos2dMESA (GLdouble, GLdouble); GLAPI void APIENTRY myglWindowPos2dvMESA (const GLdouble *); GLAPI void APIENTRY myglWindowPos2fMESA (GLfloat, GLfloat); GLAPI void APIENTRY myglWindowPos2fvMESA (const GLfloat *); GLAPI void APIENTRY myglWindowPos2iMESA (GLint, GLint); GLAPI void APIENTRY myglWindowPos2ivMESA (const GLint *); GLAPI void APIENTRY myglWindowPos2sMESA (GLshort, GLshort); GLAPI void APIENTRY myglWindowPos2svMESA (const GLshort *); GLAPI void APIENTRY myglWindowPos3dMESA (GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglWindowPos3dvMESA (const GLdouble *); GLAPI void APIENTRY myglWindowPos3fMESA (GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglWindowPos3fvMESA (const GLfloat *); GLAPI void APIENTRY myglWindowPos3iMESA (GLint, GLint, GLint); GLAPI void APIENTRY myglWindowPos3ivMESA (const GLint *); GLAPI void APIENTRY myglWindowPos3sMESA (GLshort, GLshort, GLshort); GLAPI void APIENTRY myglWindowPos3svMESA (const GLshort *); GLAPI void APIENTRY myglWindowPos4dMESA (GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglWindowPos4dvMESA (const GLdouble *); GLAPI void APIENTRY myglWindowPos4fMESA (GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglWindowPos4fvMESA (const GLfloat *); GLAPI void APIENTRY myglWindowPos4iMESA (GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglWindowPos4ivMESA (const GLint *); GLAPI void APIENTRY myglWindowPos4sMESA (GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglWindowPos4svMESA (const GLshort *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); typedef void (APIENTRYP PFNMYGLWINDOWPOS2SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNMYGLWINDOWPOS3SVMESAPROC) (const GLshort *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNMYGLWINDOWPOS4IVMESAPROC) (const GLint *v); typedef void (APIENTRYP PFNMYGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNMYGLWINDOWPOS4SVMESAPROC) (const GLshort *v); #endif #ifndef MYGL_IBM_cull_vertex #define MYGL_IBM_cull_vertex 1 #endif #ifndef MYGL_IBM_multimode_draw_arrays #define MYGL_IBM_multimode_draw_arrays 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglMultiModeDrawArraysIBM (const GLenum *, const GLint *, const GLsizei *, GLsizei, GLint); GLAPI void APIENTRY myglMultiModeDrawElementsIBM (const GLenum *, const GLsizei *, GLenum, const GLvoid* const *, GLsizei, GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); typedef void (APIENTRYP PFNMYGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); #endif #ifndef MYGL_IBM_vertex_array_lists #define MYGL_IBM_vertex_array_lists 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY myglSecondaryColorPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY myglEdgeFlagPointerListIBM (GLint, const GLboolean* *, GLint); GLAPI void APIENTRY myglFogCoordPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY myglIndexPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY myglNormalPointerListIBM (GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY myglTexCoordPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); GLAPI void APIENTRY myglVertexPointerListIBM (GLint, GLenum, GLint, const GLvoid* *, GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNMYGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNMYGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNMYGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNMYGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNMYGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNMYGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); typedef void (APIENTRYP PFNMYGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); #endif #ifndef MYGL_SGIX_subsample #define MYGL_SGIX_subsample 1 #endif #ifndef MYGL_SGIX_ycrcba #define MYGL_SGIX_ycrcba 1 #endif #ifndef MYGL_SGIX_ycrcb_subsample #define MYGL_SGIX_ycrcb_subsample 1 #endif #ifndef MYGL_SGIX_depth_pass_instrument #define MYGL_SGIX_depth_pass_instrument 1 #endif #ifndef MYGL_3DFX_texture_compression_FXT1 #define MYGL_3DFX_texture_compression_FXT1 1 #endif #ifndef MYGL_3DFX_multisample #define MYGL_3DFX_multisample 1 #endif #ifndef MYGL_3DFX_tbuffer #define MYGL_3DFX_tbuffer 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTbufferMask3DFX (GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTBUFFERMASK3DFXPROC) (GLuint mask); #endif #ifndef MYGL_EXT_multisample #define MYGL_EXT_multisample 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglSampleMaskEXT (GLclampf, GLboolean); GLAPI void APIENTRY myglSamplePatternEXT (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); typedef void (APIENTRYP PFNMYGLSAMPLEPATTERNEXTPROC) (GLenum pattern); #endif #ifndef MYGL_SGIX_vertex_preclip #define MYGL_SGIX_vertex_preclip 1 #endif #ifndef MYGL_SGIX_convolution_accuracy #define MYGL_SGIX_convolution_accuracy 1 #endif #ifndef MYGL_SGIX_resample #define MYGL_SGIX_resample 1 #endif #ifndef MYGL_SGIS_point_line_texgen #define MYGL_SGIS_point_line_texgen 1 #endif #ifndef MYGL_SGIS_texture_color_mask #define MYGL_SGIS_texture_color_mask 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GLboolean); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); #endif #ifndef MYGL_SGIX_igloo_interface #define MYGL_SGIX_igloo_interface 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglIglooInterfaceSGIX (GLenum, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); #endif #ifndef MYGL_EXT_texture_env_dot3 #define MYGL_EXT_texture_env_dot3 1 #endif #ifndef MYGL_ATI_texture_mirror_once #define MYGL_ATI_texture_mirror_once 1 #endif #ifndef MYGL_NV_fence #define MYGL_NV_fence 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDeleteFencesNV (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenFencesNV (GLsizei, GLuint *); GLAPI GLboolean APIENTRY myglIsFenceNV (GLuint); GLAPI GLboolean APIENTRY myglTestFenceNV (GLuint); GLAPI void APIENTRY myglGetFenceivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglFinishFenceNV (GLuint); GLAPI void APIENTRY myglSetFenceNV (GLuint, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNMYGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); typedef GLboolean (APIENTRYP PFNMYGLISFENCENVPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNMYGLTESTFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNMYGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLFINISHFENCENVPROC) (GLuint fence); typedef void (APIENTRYP PFNMYGLSETFENCENVPROC) (GLuint fence, GLenum condition); #endif #ifndef MYGL_NV_evaluators #define MYGL_NV_evaluators 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLint, GLint, GLboolean, const GLvoid *); GLAPI void APIENTRY myglMapParameterivNV (GLenum, GLenum, const GLint *); GLAPI void APIENTRY myglMapParameterfvNV (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglGetMapControlPointsNV (GLenum, GLuint, GLenum, GLsizei, GLsizei, GLboolean, GLvoid *); GLAPI void APIENTRY myglGetMapParameterivNV (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGetMapParameterfvNV (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetMapAttribParameterivNV (GLenum, GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetMapAttribParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglEvalMapsNV (GLenum, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); typedef void (APIENTRYP PFNMYGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); typedef void (APIENTRYP PFNMYGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); typedef void (APIENTRYP PFNMYGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLEVALMAPSNVPROC) (GLenum target, GLenum mode); #endif #ifndef MYGL_NV_packed_depth_stencil #define MYGL_NV_packed_depth_stencil 1 #endif #ifndef MYGL_NV_register_combiners2 #define MYGL_NV_register_combiners2 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglCombinerStageParameterfvNV (GLenum, GLenum, const GLfloat *); GLAPI void APIENTRY myglGetCombinerStageParameterfvNV (GLenum, GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); typedef void (APIENTRYP PFNMYGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); #endif #ifndef MYGL_NV_texture_compression_vtc #define MYGL_NV_texture_compression_vtc 1 #endif #ifndef MYGL_NV_texture_rectangle #define MYGL_NV_texture_rectangle 1 #endif #ifndef MYGL_NV_texture_shader #define MYGL_NV_texture_shader 1 #endif #ifndef MYGL_NV_texture_shader2 #define MYGL_NV_texture_shader2 1 #endif #ifndef MYGL_NV_vertex_array_range2 #define MYGL_NV_vertex_array_range2 1 #endif #ifndef MYGL_NV_vertex_program #define MYGL_NV_vertex_program 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY myglAreProgramsResidentNV (GLsizei, const GLuint *, GLboolean *); GLAPI void APIENTRY myglBindProgramNV (GLenum, GLuint); GLAPI void APIENTRY myglDeleteProgramsNV (GLsizei, const GLuint *); GLAPI void APIENTRY myglExecuteProgramNV (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY myglGenProgramsNV (GLsizei, GLuint *); GLAPI void APIENTRY myglGetProgramParameterdvNV (GLenum, GLuint, GLenum, GLdouble *); GLAPI void APIENTRY myglGetProgramParameterfvNV (GLenum, GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetProgramivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetProgramStringNV (GLuint, GLenum, GLubyte *); GLAPI void APIENTRY myglGetTrackMatrixivNV (GLenum, GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetVertexAttribdvNV (GLuint, GLenum, GLdouble *); GLAPI void APIENTRY myglGetVertexAttribfvNV (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetVertexAttribivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetVertexAttribPointervNV (GLuint, GLenum, GLvoid* *); GLAPI GLboolean APIENTRY myglIsProgramNV (GLuint); GLAPI void APIENTRY myglLoadProgramNV (GLenum, GLuint, GLsizei, const GLubyte *); GLAPI void APIENTRY myglProgramParameter4dNV (GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglProgramParameter4dvNV (GLenum, GLuint, const GLdouble *); GLAPI void APIENTRY myglProgramParameter4fNV (GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglProgramParameter4fvNV (GLenum, GLuint, const GLfloat *); GLAPI void APIENTRY myglProgramParameters4dvNV (GLenum, GLuint, GLuint, const GLdouble *); GLAPI void APIENTRY myglProgramParameters4fvNV (GLenum, GLuint, GLuint, const GLfloat *); GLAPI void APIENTRY myglRequestResidentProgramsNV (GLsizei, const GLuint *); GLAPI void APIENTRY myglTrackMatrixNV (GLenum, GLuint, GLenum, GLenum); GLAPI void APIENTRY myglVertexAttribPointerNV (GLuint, GLint, GLenum, GLsizei, const GLvoid *); GLAPI void APIENTRY myglVertexAttrib1dNV (GLuint, GLdouble); GLAPI void APIENTRY myglVertexAttrib1dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib1fNV (GLuint, GLfloat); GLAPI void APIENTRY myglVertexAttrib1fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib1sNV (GLuint, GLshort); GLAPI void APIENTRY myglVertexAttrib1svNV (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib2dNV (GLuint, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib2dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib2fNV (GLuint, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib2fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib2sNV (GLuint, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib2svNV (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib3dNV (GLuint, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib3dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib3fNV (GLuint, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib3fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib3sNV (GLuint, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib3svNV (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4dNV (GLuint, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexAttrib4dvNV (GLuint, const GLdouble *); GLAPI void APIENTRY myglVertexAttrib4fNV (GLuint, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexAttrib4fvNV (GLuint, const GLfloat *); GLAPI void APIENTRY myglVertexAttrib4sNV (GLuint, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexAttrib4svNV (GLuint, const GLshort *); GLAPI void APIENTRY myglVertexAttrib4ubNV (GLuint, GLubyte, GLubyte, GLubyte, GLubyte); GLAPI void APIENTRY myglVertexAttrib4ubvNV (GLuint, const GLubyte *); GLAPI void APIENTRY myglVertexAttribs1dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY myglVertexAttribs1fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglVertexAttribs1svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY myglVertexAttribs2dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY myglVertexAttribs2fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglVertexAttribs2svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY myglVertexAttribs3dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY myglVertexAttribs3fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglVertexAttribs3svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY myglVertexAttribs4dvNV (GLuint, GLsizei, const GLdouble *); GLAPI void APIENTRY myglVertexAttribs4fvNV (GLuint, GLsizei, const GLfloat *); GLAPI void APIENTRY myglVertexAttribs4svNV (GLuint, GLsizei, const GLshort *); GLAPI void APIENTRY myglVertexAttribs4ubvNV (GLuint, GLsizei, const GLubyte *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNMYGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); typedef void (APIENTRYP PFNMYGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); typedef void (APIENTRYP PFNMYGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNMYGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); typedef void (APIENTRYP PFNMYGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); typedef void (APIENTRYP PFNMYGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); typedef void (APIENTRYP PFNMYGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); typedef GLboolean (APIENTRYP PFNMYGLISPROGRAMNVPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); typedef void (APIENTRYP PFNMYGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLuint count, const GLdouble *v); typedef void (APIENTRYP PFNMYGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLuint count, const GLfloat *v); typedef void (APIENTRYP PFNMYGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); typedef void (APIENTRYP PFNMYGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); #endif #ifndef MYGL_SGIX_texture_coordinate_clamp #define MYGL_SGIX_texture_coordinate_clamp 1 #endif #ifndef MYGL_SGIX_scalebias_hint #define MYGL_SGIX_scalebias_hint 1 #endif #ifndef MYGL_OML_interlace #define MYGL_OML_interlace 1 #endif #ifndef MYGL_OML_subsample #define MYGL_OML_subsample 1 #endif #ifndef MYGL_OML_resample #define MYGL_OML_resample 1 #endif #ifndef MYGL_NV_copy_depth_to_color #define MYGL_NV_copy_depth_to_color 1 #endif #ifndef MYGL_ATI_envmap_bumpmap #define MYGL_ATI_envmap_bumpmap 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglTexBumpParameterivATI (GLenum, const GLint *); GLAPI void APIENTRY myglTexBumpParameterfvATI (GLenum, const GLfloat *); GLAPI void APIENTRY myglGetTexBumpParameterivATI (GLenum, GLint *); GLAPI void APIENTRY myglGetTexBumpParameterfvATI (GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); typedef void (APIENTRYP PFNMYGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); typedef void (APIENTRYP PFNMYGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); typedef void (APIENTRYP PFNMYGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); #endif #ifndef MYGL_ATI_fragment_shader #define MYGL_ATI_fragment_shader 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY myglGenFragmentShadersATI (GLuint); GLAPI void APIENTRY myglBindFragmentShaderATI (GLuint); GLAPI void APIENTRY myglDeleteFragmentShaderATI (GLuint); GLAPI void APIENTRY myglBeginFragmentShaderATI (void); GLAPI void APIENTRY myglEndFragmentShaderATI (void); GLAPI void APIENTRY myglPassTexCoordATI (GLuint, GLuint, GLenum); GLAPI void APIENTRY myglSampleMapATI (GLuint, GLuint, GLenum); GLAPI void APIENTRY myglColorFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglColorFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglColorFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglAlphaFragmentOp1ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglAlphaFragmentOp2ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglAlphaFragmentOp3ATI (GLenum, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglSetFragmentShaderConstantATI (GLuint, const GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNMYGLGENFRAGMENTSHADERSATIPROC) (GLuint range); typedef void (APIENTRYP PFNMYGLBINDFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLBEGINFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNMYGLENDFRAGMENTSHADERATIPROC) (void); typedef void (APIENTRYP PFNMYGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); typedef void (APIENTRYP PFNMYGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); typedef void (APIENTRYP PFNMYGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNMYGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNMYGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNMYGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); typedef void (APIENTRYP PFNMYGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); typedef void (APIENTRYP PFNMYGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); typedef void (APIENTRYP PFNMYGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); #endif #ifndef MYGL_ATI_pn_triangles #define MYGL_ATI_pn_triangles 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPNTrianglesiATI (GLenum, GLint); GLAPI void APIENTRY myglPNTrianglesfATI (GLenum, GLfloat); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef MYGL_ATI_vertex_array_object #define MYGL_ATI_vertex_array_object 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI GLuint APIENTRY myglNewObjectBufferATI (GLsizei, const GLvoid *, GLenum); GLAPI GLboolean APIENTRY myglIsObjectBufferATI (GLuint); GLAPI void APIENTRY myglUpdateObjectBufferATI (GLuint, GLuint, GLsizei, const GLvoid *, GLenum); GLAPI void APIENTRY myglGetObjectBufferfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetObjectBufferivATI (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglFreeObjectBufferATI (GLuint); GLAPI void APIENTRY myglArrayObjectATI (GLenum, GLint, GLenum, GLsizei, GLuint, GLuint); GLAPI void APIENTRY myglGetArrayObjectfvATI (GLenum, GLenum, GLfloat *); GLAPI void APIENTRY myglGetArrayObjectivATI (GLenum, GLenum, GLint *); GLAPI void APIENTRY myglVariantArrayObjectATI (GLuint, GLenum, GLsizei, GLuint, GLuint); GLAPI void APIENTRY myglGetVariantArrayObjectfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetVariantArrayObjectivATI (GLuint, GLenum, GLint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef GLuint (APIENTRYP PFNMYGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); typedef GLboolean (APIENTRYP PFNMYGLISOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNMYGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); typedef void (APIENTRYP PFNMYGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNMYGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNMYGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNMYGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); #endif #ifndef MYGL_EXT_vertex_shader #define MYGL_EXT_vertex_shader 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBeginVertexShaderEXT (void); GLAPI void APIENTRY myglEndVertexShaderEXT (void); GLAPI void APIENTRY myglBindVertexShaderEXT (GLuint); GLAPI GLuint APIENTRY myglGenVertexShadersEXT (GLuint); GLAPI void APIENTRY myglDeleteVertexShaderEXT (GLuint); GLAPI void APIENTRY myglShaderOp1EXT (GLenum, GLuint, GLuint); GLAPI void APIENTRY myglShaderOp2EXT (GLenum, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglShaderOp3EXT (GLenum, GLuint, GLuint, GLuint, GLuint); GLAPI void APIENTRY myglSwizzleEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY myglWriteMaskEXT (GLuint, GLuint, GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY myglInsertComponentEXT (GLuint, GLuint, GLuint); GLAPI void APIENTRY myglExtractComponentEXT (GLuint, GLuint, GLuint); GLAPI GLuint APIENTRY myglGenSymbolsEXT (GLenum, GLenum, GLenum, GLuint); GLAPI void APIENTRY myglSetInvariantEXT (GLuint, GLenum, const GLvoid *); GLAPI void APIENTRY myglSetLocalConstantEXT (GLuint, GLenum, const GLvoid *); GLAPI void APIENTRY myglVariantbvEXT (GLuint, const GLbyte *); GLAPI void APIENTRY myglVariantsvEXT (GLuint, const GLshort *); GLAPI void APIENTRY myglVariantivEXT (GLuint, const GLint *); GLAPI void APIENTRY myglVariantfvEXT (GLuint, const GLfloat *); GLAPI void APIENTRY myglVariantdvEXT (GLuint, const GLdouble *); GLAPI void APIENTRY myglVariantubvEXT (GLuint, const GLubyte *); GLAPI void APIENTRY myglVariantusvEXT (GLuint, const GLushort *); GLAPI void APIENTRY myglVariantuivEXT (GLuint, const GLuint *); GLAPI void APIENTRY myglVariantPointerEXT (GLuint, GLenum, GLuint, const GLvoid *); GLAPI void APIENTRY myglEnableVariantClientStateEXT (GLuint); GLAPI void APIENTRY myglDisableVariantClientStateEXT (GLuint); GLAPI GLuint APIENTRY myglBindLightParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY myglBindMaterialParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY myglBindTexGenParameterEXT (GLenum, GLenum, GLenum); GLAPI GLuint APIENTRY myglBindTextureUnitParameterEXT (GLenum, GLenum); GLAPI GLuint APIENTRY myglBindParameterEXT (GLenum); GLAPI GLboolean APIENTRY myglIsVariantEnabledEXT (GLuint, GLenum); GLAPI void APIENTRY myglGetVariantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY myglGetVariantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetVariantFloatvEXT (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetVariantPointervEXT (GLuint, GLenum, GLvoid* *); GLAPI void APIENTRY myglGetInvariantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY myglGetInvariantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetInvariantFloatvEXT (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetLocalConstantBooleanvEXT (GLuint, GLenum, GLboolean *); GLAPI void APIENTRY myglGetLocalConstantIntegervEXT (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetLocalConstantFloatvEXT (GLuint, GLenum, GLfloat *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBEGINVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNMYGLENDVERTEXSHADEREXTPROC) (void); typedef void (APIENTRYP PFNMYGLBINDVERTEXSHADEREXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNMYGLGENVERTEXSHADERSEXTPROC) (GLuint range); typedef void (APIENTRYP PFNMYGLDELETEVERTEXSHADEREXTPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); typedef void (APIENTRYP PFNMYGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); typedef void (APIENTRYP PFNMYGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); typedef void (APIENTRYP PFNMYGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNMYGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); typedef void (APIENTRYP PFNMYGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef void (APIENTRYP PFNMYGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); typedef GLuint (APIENTRYP PFNMYGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); typedef void (APIENTRYP PFNMYGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNMYGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); typedef void (APIENTRYP PFNMYGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); typedef void (APIENTRYP PFNMYGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); typedef void (APIENTRYP PFNMYGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); typedef void (APIENTRYP PFNMYGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); typedef void (APIENTRYP PFNMYGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); typedef void (APIENTRYP PFNMYGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); typedef void (APIENTRYP PFNMYGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); typedef void (APIENTRYP PFNMYGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); typedef void (APIENTRYP PFNMYGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); typedef void (APIENTRYP PFNMYGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); typedef GLuint (APIENTRYP PFNMYGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); typedef GLuint (APIENTRYP PFNMYGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); typedef GLuint (APIENTRYP PFNMYGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); typedef GLuint (APIENTRYP PFNMYGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); typedef GLuint (APIENTRYP PFNMYGLBINDPARAMETEREXTPROC) (GLenum value); typedef GLboolean (APIENTRYP PFNMYGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); typedef void (APIENTRYP PFNMYGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNMYGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNMYGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNMYGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); typedef void (APIENTRYP PFNMYGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNMYGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNMYGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); typedef void (APIENTRYP PFNMYGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); typedef void (APIENTRYP PFNMYGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); typedef void (APIENTRYP PFNMYGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); #endif #ifndef MYGL_ATI_vertex_streams #define MYGL_ATI_vertex_streams 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglVertexStream1sATI (GLenum, GLshort); GLAPI void APIENTRY myglVertexStream1svATI (GLenum, const GLshort *); GLAPI void APIENTRY myglVertexStream1iATI (GLenum, GLint); GLAPI void APIENTRY myglVertexStream1ivATI (GLenum, const GLint *); GLAPI void APIENTRY myglVertexStream1fATI (GLenum, GLfloat); GLAPI void APIENTRY myglVertexStream1fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY myglVertexStream1dATI (GLenum, GLdouble); GLAPI void APIENTRY myglVertexStream1dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY myglVertexStream2sATI (GLenum, GLshort, GLshort); GLAPI void APIENTRY myglVertexStream2svATI (GLenum, const GLshort *); GLAPI void APIENTRY myglVertexStream2iATI (GLenum, GLint, GLint); GLAPI void APIENTRY myglVertexStream2ivATI (GLenum, const GLint *); GLAPI void APIENTRY myglVertexStream2fATI (GLenum, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexStream2fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY myglVertexStream2dATI (GLenum, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexStream2dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY myglVertexStream3sATI (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexStream3svATI (GLenum, const GLshort *); GLAPI void APIENTRY myglVertexStream3iATI (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY myglVertexStream3ivATI (GLenum, const GLint *); GLAPI void APIENTRY myglVertexStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexStream3fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY myglVertexStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexStream3dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY myglVertexStream4sATI (GLenum, GLshort, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglVertexStream4svATI (GLenum, const GLshort *); GLAPI void APIENTRY myglVertexStream4iATI (GLenum, GLint, GLint, GLint, GLint); GLAPI void APIENTRY myglVertexStream4ivATI (GLenum, const GLint *); GLAPI void APIENTRY myglVertexStream4fATI (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglVertexStream4fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY myglVertexStream4dATI (GLenum, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglVertexStream4dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY myglNormalStream3bATI (GLenum, GLbyte, GLbyte, GLbyte); GLAPI void APIENTRY myglNormalStream3bvATI (GLenum, const GLbyte *); GLAPI void APIENTRY myglNormalStream3sATI (GLenum, GLshort, GLshort, GLshort); GLAPI void APIENTRY myglNormalStream3svATI (GLenum, const GLshort *); GLAPI void APIENTRY myglNormalStream3iATI (GLenum, GLint, GLint, GLint); GLAPI void APIENTRY myglNormalStream3ivATI (GLenum, const GLint *); GLAPI void APIENTRY myglNormalStream3fATI (GLenum, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglNormalStream3fvATI (GLenum, const GLfloat *); GLAPI void APIENTRY myglNormalStream3dATI (GLenum, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglNormalStream3dvATI (GLenum, const GLdouble *); GLAPI void APIENTRY myglClientActiveVertexStreamATI (GLenum); GLAPI void APIENTRY myglVertexBlendEnviATI (GLenum, GLint); GLAPI void APIENTRY myglVertexBlendEnvfATI (GLenum, GLfloat); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); typedef void (APIENTRYP PFNMYGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); typedef void (APIENTRYP PFNMYGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); typedef void (APIENTRYP PFNMYGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); #endif #ifndef MYGL_ATI_element_array #define MYGL_ATI_element_array 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglElementPointerATI (GLenum, const GLvoid *); GLAPI void APIENTRY myglDrawElementArrayATI (GLenum, GLsizei); GLAPI void APIENTRY myglDrawRangeElementArrayATI (GLenum, GLuint, GLuint, GLsizei); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); typedef void (APIENTRYP PFNMYGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); #endif #ifndef MYGL_SUN_mesh_array #define MYGL_SUN_mesh_array 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDrawMeshArraysSUN (GLenum, GLint, GLsizei, GLsizei); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); #endif #ifndef MYGL_SUN_slice_accum #define MYGL_SUN_slice_accum 1 #endif #ifndef MYGL_NV_multisample_filter_hint #define MYGL_NV_multisample_filter_hint 1 #endif #ifndef MYGL_NV_depth_clamp #define MYGL_NV_depth_clamp 1 #endif #ifndef MYGL_NV_occlusion_query #define MYGL_NV_occlusion_query 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGenOcclusionQueriesNV (GLsizei, GLuint *); GLAPI void APIENTRY myglDeleteOcclusionQueriesNV (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY myglIsOcclusionQueryNV (GLuint); GLAPI void APIENTRY myglBeginOcclusionQueryNV (GLuint); GLAPI void APIENTRY myglEndOcclusionQueryNV (void); GLAPI void APIENTRY myglGetOcclusionQueryivNV (GLuint, GLenum, GLint *); GLAPI void APIENTRY myglGetOcclusionQueryuivNV (GLuint, GLenum, GLuint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); typedef void (APIENTRYP PFNMYGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); typedef GLboolean (APIENTRYP PFNMYGLISOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); typedef void (APIENTRYP PFNMYGLENDOCCLUSIONQUERYNVPROC) (void); typedef void (APIENTRYP PFNMYGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); #endif #ifndef MYGL_NV_point_sprite #define MYGL_NV_point_sprite 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPointParameteriNV (GLenum, GLint); GLAPI void APIENTRY myglPointParameterivNV (GLenum, const GLint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); typedef void (APIENTRYP PFNMYGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); #endif #ifndef MYGL_NV_texture_shader3 #define MYGL_NV_texture_shader3 1 #endif #ifndef MYGL_NV_vertex_program1_1 #define MYGL_NV_vertex_program1_1 1 #endif #ifndef MYGL_EXT_shadow_funcs #define MYGL_EXT_shadow_funcs 1 #endif #ifndef MYGL_EXT_stencil_two_side #define MYGL_EXT_stencil_two_side 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglActiveStencilFaceEXT (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLACTIVESTENCILFACEEXTPROC) (GLenum face); #endif #ifndef MYGL_ATI_text_fragment_shader #define MYGL_ATI_text_fragment_shader 1 #endif #ifndef MYGL_APPLE_client_storage #define MYGL_APPLE_client_storage 1 #endif #ifndef MYGL_APPLE_element_array #define MYGL_APPLE_element_array 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglElementPointerAPPLE (GLenum, const GLvoid *); GLAPI void APIENTRY myglDrawElementArrayAPPLE (GLenum, GLint, GLsizei); GLAPI void APIENTRY myglDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, GLint, GLsizei); GLAPI void APIENTRY myglMultiDrawElementArrayAPPLE (GLenum, const GLint *, const GLsizei *, GLsizei); GLAPI void APIENTRY myglMultiDrawRangeElementArrayAPPLE (GLenum, GLuint, GLuint, const GLint *, const GLsizei *, GLsizei); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); typedef void (APIENTRYP PFNMYGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); typedef void (APIENTRYP PFNMYGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); typedef void (APIENTRYP PFNMYGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); typedef void (APIENTRYP PFNMYGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); #endif #ifndef MYGL_APPLE_fence #define MYGL_APPLE_fence 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglGenFencesAPPLE (GLsizei, GLuint *); GLAPI void APIENTRY myglDeleteFencesAPPLE (GLsizei, const GLuint *); GLAPI void APIENTRY myglSetFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY myglIsFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY myglTestFenceAPPLE (GLuint); GLAPI void APIENTRY myglFinishFenceAPPLE (GLuint); GLAPI GLboolean APIENTRY myglTestObjectAPPLE (GLenum, GLuint); GLAPI void APIENTRY myglFinishObjectAPPLE (GLenum, GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); typedef void (APIENTRYP PFNMYGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); typedef void (APIENTRYP PFNMYGLSETFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNMYGLISFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNMYGLTESTFENCEAPPLEPROC) (GLuint fence); typedef void (APIENTRYP PFNMYGLFINISHFENCEAPPLEPROC) (GLuint fence); typedef GLboolean (APIENTRYP PFNMYGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); typedef void (APIENTRYP PFNMYGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); #endif #ifndef MYGL_APPLE_vertex_array_object #define MYGL_APPLE_vertex_array_object 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBindVertexArrayAPPLE (GLuint); GLAPI void APIENTRY myglDeleteVertexArraysAPPLE (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenVertexArraysAPPLE (GLsizei, const GLuint *); GLAPI GLboolean APIENTRY myglIsVertexArrayAPPLE (GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); typedef void (APIENTRYP PFNMYGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); typedef void (APIENTRYP PFNMYGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); typedef GLboolean (APIENTRYP PFNMYGLISVERTEXARRAYAPPLEPROC) (GLuint array); #endif #ifndef MYGL_APPLE_vertex_array_range #define MYGL_APPLE_vertex_array_range 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglVertexArrayRangeAPPLE (GLsizei, GLvoid *); GLAPI void APIENTRY myglFlushVertexArrayRangeAPPLE (GLsizei, GLvoid *); GLAPI void APIENTRY myglVertexArrayParameteriAPPLE (GLenum, GLint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNMYGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNMYGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); #endif #ifndef MYGL_APPLE_ycbcr_422 #define MYGL_APPLE_ycbcr_422 1 #endif #ifndef MYGL_S3_s3tc #define MYGL_S3_s3tc 1 #endif #ifndef MYGL_ATI_draw_buffers #define MYGL_ATI_draw_buffers 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDrawBuffersATI (GLsizei, const GLenum *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); #endif #ifndef MYGL_ATI_pixel_format_float #define MYGL_ATI_pixel_format_float 1 /* This is really a WGL extension, but defines some associated GL enums. * ATI does not export "MYGL_ATI_pixel_format_float" in the MYGL_EXTENSIONS string. */ #endif #ifndef MYGL_ATI_texture_env_combine3 #define MYGL_ATI_texture_env_combine3 1 #endif #ifndef MYGL_ATI_texture_float #define MYGL_ATI_texture_float 1 #endif #ifndef MYGL_NV_float_buffer #define MYGL_NV_float_buffer 1 #endif #ifndef MYGL_NV_fragment_program #define MYGL_NV_fragment_program 1 /* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglProgramNamedParameter4fNV (GLuint, GLsizei, const GLubyte *, GLfloat, GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY myglProgramNamedParameter4dNV (GLuint, GLsizei, const GLubyte *, GLdouble, GLdouble, GLdouble, GLdouble); GLAPI void APIENTRY myglProgramNamedParameter4fvNV (GLuint, GLsizei, const GLubyte *, const GLfloat *); GLAPI void APIENTRY myglProgramNamedParameter4dvNV (GLuint, GLsizei, const GLubyte *, const GLdouble *); GLAPI void APIENTRY myglGetProgramNamedParameterfvNV (GLuint, GLsizei, const GLubyte *, GLfloat *); GLAPI void APIENTRY myglGetProgramNamedParameterdvNV (GLuint, GLsizei, const GLubyte *, GLdouble *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); typedef void (APIENTRYP PFNMYGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); typedef void (APIENTRYP PFNMYGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); typedef void (APIENTRYP PFNMYGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); typedef void (APIENTRYP PFNMYGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); #endif #ifndef MYGL_NV_half_float #define MYGL_NV_half_float 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglVertex2hNV (GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglVertex2hvNV (const GLhalfNV *); GLAPI void APIENTRY myglVertex3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglVertex3hvNV (const GLhalfNV *); GLAPI void APIENTRY myglVertex4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglVertex4hvNV (const GLhalfNV *); GLAPI void APIENTRY myglNormal3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglNormal3hvNV (const GLhalfNV *); GLAPI void APIENTRY myglColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglColor3hvNV (const GLhalfNV *); GLAPI void APIENTRY myglColor4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglColor4hvNV (const GLhalfNV *); GLAPI void APIENTRY myglTexCoord1hNV (GLhalfNV); GLAPI void APIENTRY myglTexCoord1hvNV (const GLhalfNV *); GLAPI void APIENTRY myglTexCoord2hNV (GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglTexCoord2hvNV (const GLhalfNV *); GLAPI void APIENTRY myglTexCoord3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglTexCoord3hvNV (const GLhalfNV *); GLAPI void APIENTRY myglTexCoord4hNV (GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglTexCoord4hvNV (const GLhalfNV *); GLAPI void APIENTRY myglMultiTexCoord1hNV (GLenum, GLhalfNV); GLAPI void APIENTRY myglMultiTexCoord1hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY myglMultiTexCoord2hNV (GLenum, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglMultiTexCoord2hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY myglMultiTexCoord3hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglMultiTexCoord3hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY myglMultiTexCoord4hNV (GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglMultiTexCoord4hvNV (GLenum, const GLhalfNV *); GLAPI void APIENTRY myglFogCoordhNV (GLhalfNV); GLAPI void APIENTRY myglFogCoordhvNV (const GLhalfNV *); GLAPI void APIENTRY myglSecondaryColor3hNV (GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglSecondaryColor3hvNV (const GLhalfNV *); GLAPI void APIENTRY myglVertexWeighthNV (GLhalfNV); GLAPI void APIENTRY myglVertexWeighthvNV (const GLhalfNV *); GLAPI void APIENTRY myglVertexAttrib1hNV (GLuint, GLhalfNV); GLAPI void APIENTRY myglVertexAttrib1hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY myglVertexAttrib2hNV (GLuint, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglVertexAttrib2hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY myglVertexAttrib3hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglVertexAttrib3hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY myglVertexAttrib4hNV (GLuint, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV); GLAPI void APIENTRY myglVertexAttrib4hvNV (GLuint, const GLhalfNV *); GLAPI void APIENTRY myglVertexAttribs1hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY myglVertexAttribs2hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY myglVertexAttribs3hvNV (GLuint, GLsizei, const GLhalfNV *); GLAPI void APIENTRY myglVertexAttribs4hvNV (GLuint, GLsizei, const GLhalfNV *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNMYGLVERTEX2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNMYGLVERTEX3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNMYGLVERTEX4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); typedef void (APIENTRYP PFNMYGLNORMAL3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNMYGLCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); typedef void (APIENTRYP PFNMYGLCOLOR4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLTEXCOORD1HNVPROC) (GLhalfNV s); typedef void (APIENTRYP PFNMYGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNMYGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNMYGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNMYGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); typedef void (APIENTRYP PFNMYGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLFOGCOORDHNVPROC) (GLhalfNV fog); typedef void (APIENTRYP PFNMYGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); typedef void (APIENTRYP PFNMYGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); typedef void (APIENTRYP PFNMYGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); typedef void (APIENTRYP PFNMYGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); typedef void (APIENTRYP PFNMYGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); #endif #ifndef MYGL_NV_pixel_data_range #define MYGL_NV_pixel_data_range 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPixelDataRangeNV (GLenum, GLsizei, GLvoid *); GLAPI void APIENTRY myglFlushPixelDataRangeNV (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); typedef void (APIENTRYP PFNMYGLFLUSHPIXELDATARANGENVPROC) (GLenum target); #endif #ifndef MYGL_NV_primitive_restart #define MYGL_NV_primitive_restart 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglPrimitiveRestartNV (void); GLAPI void APIENTRY myglPrimitiveRestartIndexNV (GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLPRIMITIVERESTARTNVPROC) (void); typedef void (APIENTRYP PFNMYGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); #endif #ifndef MYGL_NV_texture_expand_normal #define MYGL_NV_texture_expand_normal 1 #endif #ifndef MYGL_NV_vertex_program2 #define MYGL_NV_vertex_program2 1 #endif #ifndef MYGL_ATI_map_object_buffer #define MYGL_ATI_map_object_buffer 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI GLvoid* APIENTRY myglMapObjectBufferATI (GLuint); GLAPI void APIENTRY myglUnmapObjectBufferATI (GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef GLvoid* (APIENTRYP PFNMYGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); typedef void (APIENTRYP PFNMYGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); #endif #ifndef MYGL_ATI_separate_stencil #define MYGL_ATI_separate_stencil 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglStencilOpSeparateATI (GLenum, GLenum, GLenum, GLenum); GLAPI void APIENTRY myglStencilFuncSeparateATI (GLenum, GLenum, GLint, GLuint); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); typedef void (APIENTRYP PFNMYGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); #endif #ifndef MYGL_ATI_vertex_attrib_array_object #define MYGL_ATI_vertex_attrib_array_object 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglVertexAttribArrayObjectATI (GLuint, GLint, GLenum, GLboolean, GLsizei, GLuint, GLuint); GLAPI void APIENTRY myglGetVertexAttribArrayObjectfvATI (GLuint, GLenum, GLfloat *); GLAPI void APIENTRY myglGetVertexAttribArrayObjectivATI (GLuint, GLenum, GLint *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); typedef void (APIENTRYP PFNMYGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); #endif #ifndef MYGL_OES_read_format #define MYGL_OES_read_format 1 #endif #ifndef MYGL_EXT_depth_bounds_test #define MYGL_EXT_depth_bounds_test 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglDepthBoundsEXT (GLclampd, GLclampd); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); #endif #ifndef MYGL_EXT_texture_mirror_clamp #define MYGL_EXT_texture_mirror_clamp 1 #endif #ifndef MYGL_EXT_blend_equation_separate #define MYGL_EXT_blend_equation_separate 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglBlendEquationSeparateEXT (GLenum, GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); #endif #ifndef MYGL_MESA_pack_invert #define MYGL_MESA_pack_invert 1 #endif #ifndef MYGL_MESA_ycbcr_texture #define MYGL_MESA_ycbcr_texture 1 #endif #ifndef MYGL_EXT_pixel_buffer_object #define MYGL_EXT_pixel_buffer_object 1 #endif #ifndef MYGL_NV_fragment_program_option #define MYGL_NV_fragment_program_option 1 #endif #ifndef MYGL_NV_fragment_program2 #define MYGL_NV_fragment_program2 1 #endif #ifndef MYGL_NV_vertex_program2_option #define MYGL_NV_vertex_program2_option 1 #endif #ifndef MYGL_NV_vertex_program3 #define MYGL_NV_vertex_program3 1 #endif #ifndef MYGL_EXT_framebuffer_object #define MYGL_EXT_framebuffer_object 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI GLboolean APIENTRY myglIsRenderbufferEXT (GLuint); GLAPI void APIENTRY myglBindRenderbufferEXT (GLenum, GLuint); GLAPI void APIENTRY myglDeleteRenderbuffersEXT (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenRenderbuffersEXT (GLsizei, GLuint *); GLAPI void APIENTRY myglRenderbufferStorageEXT (GLenum, GLenum, GLsizei, GLsizei); GLAPI void APIENTRY myglGetRenderbufferParameterivEXT (GLenum, GLenum, GLint *); GLAPI GLboolean APIENTRY myglIsFramebufferEXT (GLuint); GLAPI void APIENTRY myglBindFramebufferEXT (GLenum, GLuint); GLAPI void APIENTRY myglDeleteFramebuffersEXT (GLsizei, const GLuint *); GLAPI void APIENTRY myglGenFramebuffersEXT (GLsizei, GLuint *); GLAPI GLenum APIENTRY myglCheckFramebufferStatusEXT (GLenum); GLAPI void APIENTRY myglFramebufferTexture1DEXT (GLenum, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY myglFramebufferTexture2DEXT (GLenum, GLenum, GLenum, GLuint, GLint); GLAPI void APIENTRY myglFramebufferTexture3DEXT (GLenum, GLenum, GLenum, GLuint, GLint, GLint); GLAPI void APIENTRY myglFramebufferRenderbufferEXT (GLenum, GLenum, GLenum, GLuint); GLAPI void APIENTRY myglGetFramebufferAttachmentParameterivEXT (GLenum, GLenum, GLenum, GLint *); GLAPI void APIENTRY myglGenerateMipmapEXT (GLenum); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef GLboolean (APIENTRYP PFNMYGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); typedef void (APIENTRYP PFNMYGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); typedef void (APIENTRYP PFNMYGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); typedef void (APIENTRYP PFNMYGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); typedef void (APIENTRYP PFNMYGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); typedef void (APIENTRYP PFNMYGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); typedef GLboolean (APIENTRYP PFNMYGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); typedef void (APIENTRYP PFNMYGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); typedef void (APIENTRYP PFNMYGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); typedef void (APIENTRYP PFNMYGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); typedef GLenum (APIENTRYP PFNMYGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); typedef void (APIENTRYP PFNMYGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNMYGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); typedef void (APIENTRYP PFNMYGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); typedef void (APIENTRYP PFNMYGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); typedef void (APIENTRYP PFNMYGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); typedef void (APIENTRYP PFNMYGLGENERATEMIPMAPEXTPROC) (GLenum target); #endif #ifndef MYGL_GREMEDY_string_marker #define MYGL_GREMEDY_string_marker 1 #ifdef MYGL_GLEXT_PROTOTYPES GLAPI void APIENTRY myglStringMarkerGREMEDY (GLsizei, const GLvoid *); #endif /* MYGL_GLEXT_PROTOTYPES */ typedef void (APIENTRYP PFNMYGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); #endif #ifdef __cplusplus } #endif #endif xine-lib-1.2/src/video_out/macosx/0000755000175000017500000000000014647725152014742 5ustar memexine-lib-1.2/src/video_out/macosx/XineVideoWindow.h0000644000175000017500000000264514647725152020204 0ustar meme/* * Copyright (C) 2004-2007 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifndef __HAVE_XINE_VIDEO_WINDOW_H__ #define __HAVE_XINE_VIDEO_WINDOW_H__ #import typedef enum { XINE_FULLSCREEN_OVERSCAN, XINE_FULLSCREEN_CROP } XineVideoWindowFullScreenMode; @interface XineVideoWindow : NSWindow { int width, height; id /* XineOpenGLView * */ xineView; } - (id) initWithContentSize:(NSSize)size; - (id /* XineOpenGLView * */) xineView; @end /* NSWindow aspect ratio convenience methods */ @interface NSWindow (AspectRatioAdditions) - (void) setKeepsAspectRatio:(BOOL)flag; - (BOOL) keepsAspectRatio; @end #endif /* __HAVE_XINE_VIDEO_WINDOW_H__ */ xine-lib-1.2/src/video_out/macosx/Makefile.am0000644000175000017500000000074714647725152017006 0ustar memeinclude $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_OBJCFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) xineinclude_HEADERS = video_window.h XineOpenGLView.h XineVideoWindow.h lib_LTLIBRARIES = libxineMacOSXVideo.la libxineMacOSXVideo_la_SOURCES = XineOpenGLView.m XineVideoWindow.m libxineMacOSXVideo_la_LDFLAGS = $(AM_LDFLAGS) -framework Cocoa -framework OpenGL \ -version-info $(XINE_LT_CURRENT):$(XINE_LT_REVISION):$(XINE_LT_AGE) xine-lib-1.2/src/video_out/macosx/XineVideoWindow.m0000644000175000017500000001164214647725152020206 0ustar meme/* * Copyright (C) 2004 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Written by Daniel Mack * * Most parts of this code were taken from VLC, http://www.videolan.org * Thanks for the good research! */ #import "XineOpenGLView.h" #import "XineVideoWindow.h" #define DEFAULT_VIDEO_WINDOW_SIZE (NSMakeSize(320, 200)) @implementation XineVideoWindow - (void) setContentSize: (NSSize) size { #ifdef LOG NSLog(@"setContent called with new size w:%d h:%d", size.width, size.height); #endif [xineView setViewSizeInMainThread:size]; [super setContentSize: size]; } - (id) init { return [self initWithContentSize:DEFAULT_VIDEO_WINDOW_SIZE]; } - (id) initWithContentSize:(NSSize)size { NSScreen *screen = [NSScreen mainScreen]; NSSize screen_size = [screen frame].size; /* make a centered window */ NSRect frame; frame.size = size; frame.origin.x = (screen_size.width - frame.size.width) / 2; frame.origin.y = (screen_size.height - frame.size.height) / 2; unsigned int style_mask = NSTitledWindowMask | NSMiniaturizableWindowMask | NSClosableWindowMask | NSResizableWindowMask; return ([self initWithContentRect:frame styleMask:style_mask backing:NSBackingStoreBuffered defer:NO screen:screen]); } - (id) initWithContentRect: (NSRect)rect styleMask:(unsigned int)styleMask backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag screen:(NSScreen *)aScreen { self = [super initWithContentRect: rect styleMask: styleMask backing: bufferingType defer: flag screen: aScreen]; #ifdef LOG NSLog(@"initWithContentRect called with rect x:%d y:%d w:%d h:%d", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); #endif xineView = [[XineOpenGLView alloc] initWithFrame:rect]; [xineView setResizeViewOnVideoSizeChange:YES]; /* receive notifications about window resizing from the xine view */ NSNotificationCenter *noticeBoard = [NSNotificationCenter defaultCenter]; [noticeBoard addObserver:self selector:@selector(xineViewDidResize:) name:XineViewDidResizeNotification object:xineView]; [self setContentView: xineView]; [self setTitle: @"xine video output"]; return self; } - (void) dealloc { [xineView release]; xineView = nil; [super dealloc]; } - (id) xineView { return xineView; } - (NSRect)windowWillUseStandardFrame:(NSWindow *)sender defaultFrame:(NSRect)defaultFrame { NSSize screen_size, video_size; NSRect standard_frame; if ([xineView isFullScreen]) return defaultFrame; screen_size = defaultFrame.size; video_size = [xineView videoSize]; if (screen_size.width / screen_size.height > video_size.width / video_size.height) { standard_frame.size.width = video_size.width * (screen_size.height / video_size.height); standard_frame.size.height = screen_size.height; } else { standard_frame.size.width = screen_size.width; standard_frame.size.height = video_size.height * (screen_size.width / video_size.width); } standard_frame.origin.x = (screen_size.width - standard_frame.size.width) / 2; standard_frame.origin.y = (screen_size.height - standard_frame.size.height) / 2; return standard_frame; } /* Notifications */ - (void) xineViewDidResize:(NSNotification *)note { NSRect frame = [self frame]; frame.size = [[self contentView] frame].size; [self setFrame:[self frameRectForContentRect:frame] display:YES]; } @end /* XineVideoWindow */ @implementation NSWindow (AspectRatioAdditions) - (void) setKeepsAspectRatio: (BOOL) flag { if (flag) { NSSize size = [self frame].size; [self setAspectRatio:size]; } else { [self setResizeIncrements:NSMakeSize(1.0, 1.0)]; } } /* XXX: This is 100% untested ... */ - (BOOL) keepsAspectRatio { NSSize size = [self aspectRatio]; if (size.width == 0 && size.height == 0) return false; else return true; } @end /* NSWindow (AspectRatioAdditions) */ xine-lib-1.2/src/video_out/macosx/XineOpenGLView.h0000644000175000017500000001023614647725152017720 0ustar meme/* * Copyright (C) 2004-2007 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifndef __HAVE_XINE_OPENGL_VIEW_H__ #define __HAVE_XINE_OPENGL_VIEW_H__ #import #import #import "XineVideoWindow.h" @protocol XineOpenGLViewDelegate; extern NSString *XineViewDidResizeNotification; @interface XineOpenGLView : NSOpenGLView { @private IBOutlet id delegate; IBOutlet id controller; NSRecursiveLock * mutex; BOOL initDone; NSSize videoSize; char * textureBuffer; GLuint texture; BOOL keepsVideoAspectRatio; BOOL resizeViewOnVideoSizeChange; NSCursor * currentCursor; NSColor * initialColor; unsigned int initialColorYUV; BOOL initialColorYUVIsSet; BOOL isFullScreen; BOOL isFullScreenPrepared; XineVideoWindowFullScreenMode fullScreenMode; NSOpenGLContext * fullScreenContext; } + (NSOpenGLPixelFormat *)defaultPixelFormat; + (NSOpenGLPixelFormat *)fullScreenPixelFormat; - (id)initWithCoder:(NSCoder *)coder; - (id)initWithFrame:(NSRect)frame; - (id)initWithFrame:(NSRect)frame pixelFormat:(NSOpenGLPixelFormat *)pixelFormat; - (void)dealloc; - (void)encodeWithCoder:(NSCoder *)coder; - (NSOpenGLContext *)openGLContext; - (void)prepareOpenGL; - (void)reshape; - (void)update; - (void)initTextures; - (void)updateTexture; - (void)drawRect:(NSRect)rect; - (NSColor *)initialColor; - (void)setInitialColor:(NSColor *)color; - (void)setNormalSize; - (void)setHalfSize; - (void)setDoubleSize; - (NSSize)videoSize; - (BOOL)keepsVideoAspectRatio; - (void)setKeepsVideoAspectRatio:(BOOL)flag; - (BOOL)resizeViewOnVideoSizeChange; - (void)setResizeViewOnVideoSizeChange:(BOOL)flag; - (void)setViewSize:(NSValue *)sizeWrapper; - (void)setViewSizeInMainThread:(NSSize)size; - (NSCursor *)currentCursor; - (void)setCurrentCursor:(NSCursor *)cursor; - (BOOL)isFullScreen; - (void)goFullScreen:(XineVideoWindowFullScreenMode)mode; - (void)exitFullScreen; - (id)delegate; - (void)setDelegate:(id)aDelegate; - (id)xineController; - (void)setXineController:(id)aController; - (BOOL)acceptsFirstResponder; - (BOOL)mouseDownCanMoveWindow; // Not intended for public use: - (char *)textureBuffer; - (void)setVideoSize:(NSSize)size; - (void)resetCursorRects; - (void)resetCursorRectsInMainThread; - (void)calcFullScreenAspect; - (void)releaseInMainThread; - (void)passEventToDelegate:(NSEvent *)theEvent withSelector:(SEL)selector; - (BOOL)acceptsFirstResponder; - (BOOL)mouseDownCanMoveWindow; @end /* XineOpenGLView delegate methods */ @protocol XineOpenGLViewDelegate - (void)mouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView; - (void)mouseMoved:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView; - (void)otherMouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView; - (void)rightMouseDown:(NSEvent *)theEvent inXineView:(XineOpenGLView *)theView; - (NSSize)xineViewWillResize:(NSSize)oldSize toSize:(NSSize)proposedSize; - (void)xineViewDidResize:(NSNotification *)note; @end #endif /* __HAVE_XINE_OPENGL_VIEW_H__ */ xine-lib-1.2/src/video_out/macosx/XineOpenGLView.m0000644000175000017500000005054414647725152017733 0ustar meme/* * Copyright (C) 2004 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ /* #define LOG */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #import #import #import #import #import "XineOpenGLView.h" #include NSString *XineViewDidResizeNotification EXPORTED = @"XineViewDidResizeNotification"; static uint32_t NSColorToYUV(NSColor *color) { float red, green, blue, alpha; uint32_t yuv; unsigned char r, g, b; unsigned char y, u, v; NSColor *calibratedColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace]; [calibratedColor getRed:&red green:&green blue:&blue alpha:&alpha]; r = red * 255; g = green * 255; b = blue * 255; init_yuv_conversion(); y = COMPUTE_Y(r, g, b); u = COMPUTE_U(r, g, b); v = COMPUTE_V(r, g, b); yuv = (y << 24) | (u << 16) | (y << 8) | v; return yuv; } @implementation XineOpenGLView + (NSOpenGLPixelFormat *)defaultPixelFormat { NSOpenGLPixelFormatAttribute attributes[] = { NSOpenGLPFAAccelerated, NSOpenGLPFANoRecovery, NSOpenGLPFADoubleBuffer, NSOpenGLPFAColorSize, 24, NSOpenGLPFAAlphaSize, 8, NSOpenGLPFADepthSize, 24, NSOpenGLPFAWindow, 0 }; return [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]; } + (NSOpenGLPixelFormat *)fullScreenPixelFormat { NSOpenGLPixelFormatAttribute attributes[] = { NSOpenGLPFAAccelerated, NSOpenGLPFANoRecovery, NSOpenGLPFADoubleBuffer, NSOpenGLPFAColorSize, 24, NSOpenGLPFAAlphaSize, 8, NSOpenGLPFADepthSize, 24, NSOpenGLPFAFullScreen, NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay), 0 }; return [[[NSOpenGLPixelFormat alloc] initWithAttributes:attributes] autorelease]; } - (id)initWithCoder:(NSCoder *)coder { NSColor *color; if ((self = [super initWithCoder:coder]) != nil) { videoSize = [self frame].size; mutex = [[NSRecursiveLock alloc] init]; currentCursor = [[NSCursor arrowCursor] retain]; if ([coder allowsKeyedCoding]) { keepsVideoAspectRatio = [coder decodeBoolForKey:@"keepsVideoAspectRatio"]; resizeViewOnVideoSizeChange = [coder decodeBoolForKey:@"resizeViewOnVideoSizeChange"]; color = [coder decodeObjectForKey:@"initialColor"]; } else { /* Must decode values in the same order as encodeWithCoder: */ [coder decodeValueOfObjCType:@encode(BOOL) at:&keepsVideoAspectRatio]; [coder decodeValueOfObjCType:@encode(BOOL) at:&resizeViewOnVideoSizeChange]; color = [coder decodeObject]; } [self setInitialColor:color]; #ifdef LOG NSLog(@"XineOpenGLView: initWithCoder called"); #endif } return self; } - (id)initWithFrame:(NSRect)frame { return [self initWithFrame:frame pixelFormat:[[self class] defaultPixelFormat]]; } - (id)initWithFrame:(NSRect)frame pixelFormat:(NSOpenGLPixelFormat *)format { format = (format ? : [[self class] defaultPixelFormat]); if ((self = [super initWithFrame:frame pixelFormat:format]) != nil) { videoSize = frame.size; mutex = [[NSRecursiveLock alloc] init]; currentCursor = [[NSCursor arrowCursor] retain]; [self setInitialColor:nil]; #ifdef LOG NSLog(@"XineOpenGLView: initWithFrame called"); #endif } return self; } - (void)dealloc { if (isFullScreen) { [self exitFullScreen]; } if (texture) { [[self openGLContext] makeCurrentContext]; glDeleteTextures(1, &texture); texture = 0; } free(textureBuffer); [currentCursor release], currentCursor = nil; [initialColor release], initialColor = nil; [delegate release], delegate = nil; [controller release], controller = nil; [mutex release], mutex = nil; [super dealloc]; } - (void)encodeWithCoder:(NSCoder *)coder { [super encodeWithCoder:coder]; if ([coder allowsKeyedCoding]) { [coder encodeBool:keepsVideoAspectRatio forKey:@"keepsVideoAspectRatio"]; [coder encodeBool:resizeViewOnVideoSizeChange forKey:@"resizeViewOnVideoSizeChange"]; [coder encodeObject:initialColor forKey:@"initialColor"]; } else { [coder encodeValueOfObjCType:@encode(BOOL) at:&keepsVideoAspectRatio]; [coder encodeValueOfObjCType:@encode(BOOL) at:&resizeViewOnVideoSizeChange]; [coder encodeObject:initialColor]; } } - (NSOpenGLContext *)openGLContext { NSOpenGLContext *context; [mutex lock]; if (!(context = [[fullScreenContext retain] autorelease])) { context = [[[super openGLContext] retain] autorelease]; } else if (!isFullScreenPrepared) { [self prepareOpenGL]; isFullScreenPrepared = YES; } [mutex unlock]; return context; } // NOTE: This does not exist prior to Panther (10.3) - (void)prepareOpenGL { long swapInterval = 1; [mutex lock]; [super prepareOpenGL]; [[self openGLContext] setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; [self initTextures]; /* Set GL_COLOR_BUFFER_BIT to black */ glClearColor (0.0, 0.0, 0.0, 0.0); [mutex unlock]; } - (void)reshape { [mutex lock]; [super reshape]; if (initDone) { [[self openGLContext] makeCurrentContext]; NSRect bounds = [self bounds]; glViewport(0, 0, bounds.size.width, bounds.size.height); #ifdef LOG NSLog(@"XineOpenGLView: Reshape: %x%x%x%x%x%x%x%x", textureBuffer[0], textureBuffer[1], textureBuffer[2], textureBuffer[3], textureBuffer[4], textureBuffer[5], textureBuffer[6], textureBuffer[7]); #endif } [mutex unlock]; } - (void)update { [mutex lock]; [super update]; [mutex unlock]; } - (void)initTextures { uint32_t *p, *q, yuv; [mutex lock]; /* Free previous texture if any */ if (texture) { glDeleteTextures(1, &texture); texture = 0; } if (!initialColorYUVIsSet && initialColor) { initialColorYUV = NSColorToYUV(initialColor); initialColorYUVIsSet = YES; } if (textureBuffer) { textureBuffer = (char *)realloc(textureBuffer, videoSize.width * videoSize.height * 4); } else { textureBuffer = (char *)malloc(videoSize.width * videoSize.height * 4); // There _has_ to be a better way of doing this ... yuv = OSSwapHostToBigInt32(initialColorYUV); q = (uint32_t *)(char *)(textureBuffer + (int)(videoSize.width * videoSize.height * 4)); for (p = (uint32_t *)textureBuffer; p < q; *p++ = yuv); } /* Create textures */ glGenTextures(1, &texture); glEnable(GL_TEXTURE_RECTANGLE_EXT); glEnable(GL_UNPACK_CLIENT_STORAGE_APPLE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ROW_LENGTH, videoSize.width); glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texture); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); /* Use VRAM texturing */ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_CACHED_APPLE); /* Tell the driver not to make a copy of the texture but to use our buffer */ glPixelStorei(GL_UNPACK_CLIENT_STORAGE_APPLE, GL_TRUE); /* Linear interpolation */ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* I have no idea what this exactly does, but it seems to be necessary for scaling */ glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, videoSize.width, videoSize.height, 0, GL_YCBCR_422_APPLE, #if WORDS_BIGENDIAN GL_UNSIGNED_SHORT_8_8_APPLE, #else GL_UNSIGNED_SHORT_8_8_REV_APPLE, #endif textureBuffer); initDone = YES; [mutex unlock]; #ifdef LOG NSLog(@"XineOpenGLView: initTextures called: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx", textureBuffer[0], textureBuffer[1], textureBuffer[2], textureBuffer[3], textureBuffer[4], textureBuffer[5], textureBuffer[6], textureBuffer[7]); #endif } - (void)updateTexture { [mutex lock]; [[self openGLContext] makeCurrentContext]; glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texture); glPixelStorei(GL_UNPACK_ROW_LENGTH, videoSize.width); // glTexSubImage2D is faster than glTexImage2D // http://developer.apple.com/samplecode/Sample_Code/Graphics_3D/TextureRange/MainOpenGLView.m.htm glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, 0, 0, videoSize.width, videoSize.height, GL_YCBCR_422_APPLE, #if WORDS_BIGENDIAN GL_UNSIGNED_SHORT_8_8_APPLE, #else GL_UNSIGNED_SHORT_8_8_REV_APPLE, #endif textureBuffer); [self setNeedsDisplay:YES]; [mutex unlock]; } - (void)drawRect:(NSRect)rect { [mutex lock]; if (initDone && texture) { glBindTexture(GL_TEXTURE_RECTANGLE_EXT, texture); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, 1.0); // top left glTexCoord2f(0.0, videoSize.height); glVertex2f(-1.0, -1.0); // bottom left glTexCoord2f(videoSize.width, videoSize.height); glVertex2f( 1.0, -1.0); // bottom right glTexCoord2f(videoSize.width, 0.0); glVertex2f( 1.0, 1.0); // top right glEnd(); [[self openGLContext] flushBuffer]; } [mutex unlock]; } - (NSColor *)initialColor { return initialColor; } - (void) setInitialColor:(NSColor *)color { [initialColor autorelease]; initialColor = (color ? [color copy] : [[NSColor blackColor] retain]); } - (void)setNormalSize { [mutex lock]; if (!isFullScreen) { [self setViewSizeInMainThread:videoSize]; } [mutex unlock]; } - (void)setHalfSize { NSSize size; [mutex lock]; if (!isFullScreen) { size.width = trunc(videoSize.width / 2); size.height = trunc(videoSize.height / 2); [self setViewSizeInMainThread:size]; } [mutex unlock]; } - (void)setDoubleSize { NSSize size; [mutex lock]; if (!isFullScreen) { size.width = videoSize.width * 2; size.height = videoSize.height * 2; [self setViewSizeInMainThread:size]; } [mutex unlock]; } - (NSSize)videoSize { return videoSize; } - (BOOL)keepsVideoAspectRatio { return keepsVideoAspectRatio; } - (void)setKeepsVideoAspectRatio:(BOOL)flag { keepsVideoAspectRatio = flag; } - (BOOL)resizeViewOnVideoSizeChange { return resizeViewOnVideoSizeChange; } - (void)setResizeViewOnVideoSizeChange:(BOOL)flag { resizeViewOnVideoSizeChange = flag; } - (void)setViewSize:(NSValue *)sizeWrapper { NSSize currentSize, newSize, proposedSize; [sizeWrapper getValue:&proposedSize]; newSize = proposedSize; currentSize = [self frame].size; if (proposedSize.width == currentSize.width && proposedSize.height == currentSize.height) { return; } // If our controller handles xineViewWillResize:toSize:, send the // message to him first. Note that the delegate still has a chance // to override the controller's resize preference ... if ([controller respondsToSelector:@selector(xineViewWillResize:toSize:)]) { NSSize oldSize = [self frame].size; newSize = [controller xineViewWillResize:oldSize toSize:proposedSize]; } // If our delegate handles xineViewWillResize:toSize:, send the // message to him; otherwise, just resize ourselves if ([delegate respondsToSelector:@selector(xineViewWillResize:toSize:)]) { NSSize oldSize = [self frame].size; newSize = [delegate xineViewWillResize:oldSize toSize:proposedSize]; } [self setFrameSize:newSize]; [self setBoundsSize:newSize]; /* Post a notification that we resized and also notify our controller */ /* and delegate */ NSNotification *note = [NSNotification notificationWithName:XineViewDidResizeNotification object:self]; [[NSNotificationCenter defaultCenter] postNotification:note]; if ([controller respondsToSelector:@selector(xineViewDidResize:)]) { [controller xineViewDidResize:note]; } if ([delegate respondsToSelector:@selector(xineViewDidResize:)]) { [delegate xineViewDidResize:note]; } [mutex lock]; [[self openGLContext] makeCurrentContext]; if (isFullScreen) { [self calcFullScreenAspect]; } [self initTextures]; [mutex unlock]; } - (void)setViewSizeInMainThread:(NSSize)size { // Create an autorelease pool, since we're running in a xine thread that // may not have a pool of its own NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSValue *sizeWrapper = [NSValue valueWithBytes:&size objCType:@encode(NSSize)]; [self performSelectorOnMainThread:@selector(setViewSize:) withObject:sizeWrapper waitUntilDone:NO]; #ifdef LOG NSLog(@"setViewSizeInMainThread called"); #endif [pool release]; } - (NSCursor *)currentCursor { return currentCursor; } - (void)setCurrentCursor:(NSCursor *)cursor { [currentCursor autorelease]; currentCursor = [cursor retain]; [self resetCursorRectsInMainThread]; } - (BOOL)isFullScreen { return isFullScreen; } - (void)goFullScreen:(XineVideoWindowFullScreenMode)mode { NSOpenGLPixelFormat *pixelFormat; if (!(pixelFormat = [[self class] fullScreenPixelFormat])) { NSLog(@"Cannot create NSOpenGLPixelFormat for full screen mode"); return; } if (!(fullScreenContext = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil])) { NSLog(@"Cannot create NSOpenGLContext for full screen mode"); return; } if (CGCaptureAllDisplays() != CGDisplayNoErr) { [fullScreenContext release], fullScreenContext = nil; NSLog(@"CGCaptureAllDisplays() failed"); return; } [mutex lock]; fullScreenMode = mode; isFullScreenPrepared = NO; [fullScreenContext setFullScreen]; [[self openGLContext] makeCurrentContext]; // Redraw the last picture [self setNeedsDisplay:YES]; isFullScreen = YES; [mutex unlock]; } - (void)exitFullScreen { NSOpenGLContext *context; [mutex lock]; if (isFullScreen) { context = fullScreenContext; fullScreenContext = nil; [[self openGLContext] makeCurrentContext]; [context clearDrawable]; [context release]; [self reshape]; [self initTextures]; CGReleaseAllDisplays(); [self setNeedsDisplay:YES]; isFullScreen = NO; } [mutex unlock]; } - (id)delegate { return [[delegate retain] autorelease]; } - (void)setDelegate:(id)aDelegate { [delegate autorelease]; delegate = [aDelegate retain]; } - (id)xineController { return controller; } - (void)setXineController:(id)aController { [controller autorelease]; controller = [aController retain]; } - (char *)textureBuffer { return textureBuffer; } - (void)setVideoSize:(NSSize)size { [mutex lock]; videoSize = size; if (resizeViewOnVideoSizeChange) { [self setViewSizeInMainThread:size]; } if (initDone) { [[self openGLContext] makeCurrentContext]; [self initTextures]; } [mutex unlock]; } - (void)resetCursorRects { [mutex lock]; [self discardCursorRects]; [self addCursorRect:[self visibleRect] cursor:currentCursor]; [currentCursor set]; [mutex unlock]; } - (void)resetCursorRectsInMainThread { [self performSelectorOnMainThread:@selector(resetCursorRects) withObject:nil waitUntilDone:NO]; } - (void)releaseInMainThread { [self performSelectorOnMainThread:@selector(release) withObject:nil waitUntilDone:NO]; } - (void)calcFullScreenAspect { float fs_height, fs_width, h, w, x, y; // Feh, should go to main or should go to current display of window? fs_width = CGDisplayPixelsWide(kCGDirectMainDisplay); fs_height = CGDisplayPixelsHigh(kCGDirectMainDisplay); switch (fullScreenMode) { case XINE_FULLSCREEN_OVERSCAN: if ((fs_width / fs_height) > (videoSize.width / videoSize.height)) { w = videoSize.width * (fs_height / videoSize.height); h = fs_height; x = (fs_width - w) / 2; y = 0; } else { w = fs_width; h = videoSize.height * (fs_width / videoSize.width); x = 0; y = (fs_height - h) / 2; } break; case XINE_FULLSCREEN_CROP: if ((fs_width / fs_height) > (videoSize.width / videoSize.height)) { w = fs_width; h = videoSize.height * (fs_width / videoSize.width); x = 0; y = (fs_height - h) / 2; } else { w = videoSize.width * (fs_height / videoSize.height); h = fs_height; x = (fs_width - w) / 2; y = 0; } break; default: NSLog(@"Mac OS X fullscreen mode unrecognized: %d", fullScreenMode); return; } #ifdef LOG NSLog(@"Mac OS X fullscreen mode: %fx%f => %fx%f @ %f,%f\n", videoSize.width, videoSize.height, w, h, x, y); #endif // Assumes locked and current context set glViewport(x, y, w, h); } - (void)passEventToDelegate:(NSEvent *)theEvent withSelector:(SEL)selector { NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil]; if (NSMouseInRect(point, [self bounds], [self isFlipped])) { if ([delegate respondsToSelector:selector]) { [delegate performSelector:selector withObject:theEvent withObject:self]; } else if ([controller respondsToSelector:selector]) { [controller performSelector:selector withObject:theEvent withObject:self]; } } } - (void)mouseMoved:(NSEvent *)theEvent { [self passEventToDelegate:theEvent withSelector:@selector(mouseMoved:inXineView:)]; [super mouseMoved:theEvent]; } - (void)mouseDown:(NSEvent *)theEvent { [self passEventToDelegate:theEvent withSelector:@selector(mouseDown:inXineView:)]; [super mouseDown:theEvent]; } - (void)rightMouseDown:(NSEvent *)theEvent { [self passEventToDelegate:theEvent withSelector:@selector(rightMouseDown:inXineView:)]; [super rightMouseDown:theEvent]; } - (void)otherMouseDown:(NSEvent *)theEvent { [self passEventToDelegate:theEvent withSelector:@selector(otherMouseDown:inXineView:)]; [super otherMouseDown:theEvent]; } - (BOOL)acceptsFirstResponder { return YES; } - (BOOL)mouseDownCanMoveWindow { return YES; } @end xine-lib-1.2/src/video_out/macosx/video_window.h0000644000175000017500000000207314647725152017612 0ustar meme/* * Copyright (C) 2004-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Written by Daniel Mack * * Most parts of this code were taken from VLC, http://www.videolan.org * Thanks for the good research! */ #ifndef HAVE_VIDEO_WINDOW_H #define HAVE_VIDEO_WINDOW_H #include "XineOpenGLView.h" #include "XineVideoWindow.h" #endif xine-lib-1.2/src/video_out/video_out_directx.c0000644000175000017500000012445114647725152017342 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_directx.c, direct draw video output plugin for xine * by Matthew Grooms */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define XINE_NEED_WIN32_VISUAL typedef unsigned char boolean; #include #include #include #define LOG_MODULE "video_out_directx" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include #include #include "yuv2rgb.h" /* Set to 1 for RGB support */ #define RGB_SUPPORT 0 #define BORDER_SIZE 8 #define IMGFMT_NATIVE 4 /***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during * the linking stage. *****************************************************************************/ #if 1 static const GUID xine_IID_IDirectDraw = { 0x6C14DB80,0xA733,0x11CE,{0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60} }; #ifdef IID_IDirectDraw # undef IID_IDirectDraw #endif #define IID_IDirectDraw xine_IID_IDirectDraw #endif #if 0 static const GUID IID_IDirectDraw2 = { 0xB3A6F3E0,0x2B43,0x11CF,{0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56} }; #ifdef IID_IDirectDraw2 # undef IID_IDirectDraw2 #endif #define IID_IDirectDraw2 xine_IID_IDirectDraw2 #endif #if 0 static const GUID IID_IDirectDraw4 = { 0x9C59509A,0x39BD,0x11D1,{0x8C,0x4A,0x00,0xC0,0x4F,0xD9,0x30,0xC5} }; #ifdef IID_IDirectDraw4 # undef IID_IDirectDraw4 #endif #define IID_IDirectDraw4 xine_IID_IDirectDraw4 #endif /* ----------------------------------------- * * vo_directx frame struct * * ----------------------------------------- */ typedef struct { vo_frame_t vo_frame; uint8_t *buffer; int format; uint32_t width; uint32_t height; int size; double ratio; } win32_frame_t; /* ----------------------------------------- * * vo_directx driver struct * * ----------------------------------------- */ typedef enum { VO_DIRECTX_HWACCEL_FULL = 0, VO_DIRECTX_HWACCEL_SCALE = 1, VO_DIRECTX_HWACCEL_NONE = 2 } vo_directx_hwaccel_enum; typedef struct { vo_driver_t vo_driver; const win32_visual_t *win32_visual; HWND WndHnd; RECT WndRect; xine_t *xine; LPDIRECTDRAW ddobj; /* direct draw object */ LPDIRECTDRAWSURFACE primary; /* primary dd surface */ LPDIRECTDRAWSURFACE secondary; /* secondary dd surface */ LPDIRECTDRAWCLIPPER ddclipper; /* dd clipper object */ uint8_t * contents; /* secondary contents */ win32_frame_t *current; /* current frame */ int req_format; /* requested frame format */ int act_format; /* actual frame format */ uint32_t width; /* frame with */ uint32_t height; /* frame height */ double ratio; /* frame ratio */ vo_directx_hwaccel_enum hwaccel; /* requested level of HW acceleration */ yuv2rgb_factory_t *yuv2rgb_factory; /* used for format conversion */ yuv2rgb_t *yuv2rgb; /* used for format conversion */ int mode; /* rgb mode */ int bytespp; /* rgb bits per pixel */ DDPIXELFORMAT primary_pixel_format; DDSURFACEDESC ddsd; /* set by Lock(), used during display_frame */ alphablend_t alphablend_extra_data; } win32_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } directx_class_t; /* ----------------------------------------- * * BEGIN : Direct Draw and win32 handlers * for xine video output plugins. * * ----------------------------------------- */ /* Display formatted error message in * popup message box.*/ static void Error( HWND hwnd, LPCSTR szfmt, ... ) { char tempbuff[ 256 ]; *tempbuff = 0; wvsprintf( &tempbuff[ strlen( tempbuff ) ], szfmt, ( char * )( &szfmt + 1 ) ); MessageBox( hwnd, tempbuff, "Error", MB_ICONERROR | MB_OK | MB_APPLMODAL | MB_SYSTEMMODAL ); } /* Update our drivers current knowledge * of our windows video out posistion */ static void UpdateRect( HWND WndHnd, RECT *rect, const win32_visual_t * win32_visual ) { if( win32_visual->FullScreen ) { SetRect( rect, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ) ); } else { POINT p0, p1; GetClientRect( WndHnd, rect ); p0.x = rect->left; p0.y = rect->top; p1.x = rect->right; p1.y = rect->bottom; ClientToScreen( WndHnd, &p0); ClientToScreen( WndHnd, &p1); rect->left = p0.x; rect->top = p0.y; rect->right = p1.x; rect->bottom = p1.y; } } /* Create our direct draw object, primary * surface and clipper object. * * NOTE : The primary surface is more or * less a viewport into the parent desktop * window and will always have a pixel format * identical to the current display mode. */ static boolean CreatePrimary( win32_driver_t * win32_driver ) { LPDIRECTDRAW ddobj; DDSURFACEDESC ddsd; HRESULT result; /* create direct draw object */ result = DirectDrawCreate( 0, &ddobj, 0 ); if( result != DD_OK ) { Error( 0, "DirectDrawCreate : error %ld", result ); xprintf(win32_driver->xine, XINE_VERBOSITY_DEBUG, "vo_out_directx : DirectDrawCreate : error %ld\n", result ); return 0; } /* set cooperative level */ result = IDirectDraw_SetCooperativeLevel( ddobj, win32_driver->WndHnd, DDSCL_NORMAL ); if( result != DD_OK ) { Error( 0, "SetCooperativeLevel : error 0x%lx", result ); return 0; } /* try to get new interface */ result = IDirectDraw_QueryInterface( ddobj, &IID_IDirectDraw, (LPVOID *) &win32_driver->ddobj ); if( result != DD_OK ) { Error( 0, "ddobj->QueryInterface : DirectX required" ); return 0; } /* release our old interface */ IDirectDraw_Release( ddobj ); /* create primary_surface */ memset( &ddsd, 0, sizeof( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; result = IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->primary, 0 ); if( result != DD_OK ) { Error( 0, "CreateSurface ( primary ) : error 0x%lx", result ); return 0; } /* create our clipper object */ result = IDirectDraw_CreateClipper( win32_driver->ddobj, 0, &win32_driver->ddclipper, 0 ); if( result != DD_OK ) { Error( 0, "CreateClipper : error 0x%lx", result ); return 0; } /* associate our clipper with our window */ result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, win32_driver->WndHnd ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error 0x%lx", result ); return 0; } /* associate our primary surface with our clipper */ result = IDirectDrawSurface_SetClipper( win32_driver->primary, win32_driver->ddclipper ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error 0x%lx", result ); return 0; } /* store our objects in our visual struct */ UpdateRect( win32_driver->WndHnd, &win32_driver->WndRect, win32_driver->win32_visual ); return 1; } /* Create our secondary ( off screen ) buffer. * The optimal secondary buffer is a h/w * overlay with the same pixel format as the * xine frame type. However, since this is * not always supported by the host h/w, * we will fall back to creating an rgb buffer * in video memory qith the same pixel format * as the primary surface. At least then we * can use h/w scaling if supported. */ static boolean CreateSecondary( win32_driver_t * win32_driver, int width, int height, int format ) { DDSURFACEDESC ddsd; HRESULT result; if( format == XINE_IMGFMT_YV12 ) xprintf(win32_driver->xine, XINE_VERBOSITY_DEBUG, "vo_out_directx : switching to YV12 overlay type\n" ); if( format == XINE_IMGFMT_YUY2 ) xprintf(win32_driver->xine, XINE_VERBOSITY_DEBUG, "vo_out_directx : switching to YUY2 overlay type\n" ); #if RGB_SUPPORT if( format == IMGFMT_RGB ) xprintf(win32_driver->xine, XINE_VERBOSITY_DEBUG, "vo_out_directx : switching to RGB overlay type\n" ); #endif if( !win32_driver->ddobj ) return FALSE; /* store our reqested format, * width and height */ win32_driver->req_format = format; win32_driver->width = width; win32_driver->height = height; /* if we already have a secondary * surface then release it */ if( win32_driver->secondary ) IDirectDrawSurface_Release( win32_driver->secondary ); memset( &ddsd, 0, sizeof( ddsd ) ); ddsd.dwSize = sizeof( ddsd ); ddsd.dwWidth = width; ddsd.dwHeight = height; if (win32_driver->hwaccel <= VO_DIRECTX_HWACCEL_FULL) { if( format == XINE_IMGFMT_YV12 ) { /* the requested format is XINE_IMGFMT_YV12 */ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OVERLAY; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.ddpfPixelFormat.dwYUVBitCount = 16; ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC( 'Y', 'V', '1', '2' ); lprintf("CreateSecondary() - act_format = (YV12) %d\n", XINE_IMGFMT_YV12); win32_driver->act_format = XINE_IMGFMT_YV12; } if( format == XINE_IMGFMT_YUY2 ) { /* the requested format is XINE_IMGFMT_YUY2 */ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OVERLAY; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC; ddsd.ddpfPixelFormat.dwYUVBitCount = 16; ddsd.ddpfPixelFormat.dwFourCC = mmioFOURCC( 'Y', 'U', 'Y', '2' ); lprintf("CreateSecondary() - act_format = (YUY2) %d\n", XINE_IMGFMT_YUY2); win32_driver->act_format = XINE_IMGFMT_YUY2; } #if RGB_SUPPORT if( format == IMGFMT_RGB ) { /* the requested format is IMGFMT_RGB */ ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_OVERLAY; ddsd.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT); ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB; ddsd.ddpfPixelFormat.dwYUVBitCount = 24; ddsd.ddpfPixelFormat.dwRBitMask = 0xff0000; ddsd.ddpfPixelFormat.dwGBitMask = 0x00ff00; ddsd.ddpfPixelFormat.dwBBitMask = 0x0000ff; lprintf("CreateSecondary() - act_format = (RGB) %d\n", IMGFMT_RGB); win32_driver->act_format = IMGFMT_RGB; } #endif /* RGB_SUPPORT */ lprintf("CreateSecondary() - IDirectDraw_CreateSurface()\n"); if( IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 ) == DD_OK ) return TRUE; } if (win32_driver->hwaccel <= VO_DIRECTX_HWACCEL_SCALE) { /* Our fallback method is to create a back buffer * with the same image format as the primary surface */ lprintf("CreateSecondary() - Falling back to back buffer same as primary\n"); lprintf("CreateSecondary() - act_format = (NATIVE) %d\n", IMGFMT_NATIVE); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; ddsd.ddpfPixelFormat = win32_driver->primary_pixel_format; win32_driver->act_format = IMGFMT_NATIVE; if( IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 ) == DD_OK ) return TRUE; } /* Our second fallback - all w/o HW acceleration */ lprintf("CreateSecondary() - Falling back, disabling HW acceleration \n"); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; win32_driver->act_format = IMGFMT_NATIVE; if( (result = IDirectDraw_CreateSurface( win32_driver->ddobj, &ddsd, &win32_driver->secondary, 0 )) == DD_OK ) return TRUE; /* This is bad. We cant even create a surface with * the same format as the primary surface. */ Error( 0, "CreateSurface ( Secondary ) : unable to create a suitable rendering surface: 0x%08lX", result ); return FALSE; } /* Destroy all direct draw driver allocated * resources. */ static void Destroy( win32_driver_t * win32_driver ) { if( win32_driver->ddclipper ) IDirectDrawClipper_Release( win32_driver->ddclipper ); if( win32_driver->primary ) IDirectDrawSurface_Release( win32_driver->primary ); if( win32_driver->secondary ) IDirectDrawSurface_Release( win32_driver->secondary ); if( win32_driver->ddobj ) IDirectDraw_Release( win32_driver->ddobj ); if (win32_driver->yuv2rgb) win32_driver->yuv2rgb->dispose(win32_driver->yuv2rgb); if (win32_driver->yuv2rgb_factory) win32_driver->yuv2rgb_factory->dispose(win32_driver->yuv2rgb_factory); _x_alphablend_free(&win32_driver->alphablend_extra_data); free( win32_driver ); } /* Check the current pixel format of the * display mode. This is neccesary in case * the h/w does not support an overlay for * the native frame format. */ static boolean CheckPixelFormat( win32_driver_t * win32_driver ) { DDPIXELFORMAT ddpf; HRESULT result; /* get the pixel format of our primary surface */ memset( &ddpf, 0, sizeof( DDPIXELFORMAT )); ddpf.dwSize = sizeof( DDPIXELFORMAT ); result = IDirectDrawSurface_GetPixelFormat( win32_driver->primary, &ddpf ); if( result != DD_OK ) { Error( 0, "IDirectDrawSurface_GetPixelFormat ( CheckPixelFormat ) : error 0x%lx", result ); return 0; } /* store pixel format for CreateSecondary */ win32_driver->primary_pixel_format = ddpf; /* TODO : support paletized video modes */ if( ( ddpf.dwFlags & DDPF_PALETTEINDEXED1 ) || ( ddpf.dwFlags & DDPF_PALETTEINDEXED2 ) || ( ddpf.dwFlags & DDPF_PALETTEINDEXED4 ) || ( ddpf.dwFlags & DDPF_PALETTEINDEXED8 ) || ( ddpf.dwFlags & DDPF_PALETTEINDEXEDTO8 ) ) return FALSE; /* store bytes per pixel */ win32_driver->bytespp = ddpf.dwRGBBitCount / 8; /* find the rgb mode for software * colorspace conversion */ if( ddpf.dwRGBBitCount == 32 ) { if( ddpf.dwRBitMask == 0xff0000 ) win32_driver->mode = MODE_32_RGB; else win32_driver->mode = MODE_32_BGR; } if( ddpf.dwRGBBitCount == 24 ) { if( ddpf.dwRBitMask == 0xff0000 ) win32_driver->mode = MODE_24_RGB; else win32_driver->mode = MODE_24_BGR; } if( ddpf.dwRGBBitCount == 16 ) { if( ddpf.dwRBitMask == 0xf800 ) win32_driver->mode = MODE_16_RGB; else win32_driver->mode = MODE_16_BGR; } if( ddpf.dwRGBBitCount == 15 ) { if( ddpf.dwRBitMask == 0x7C00 ) win32_driver->mode = MODE_15_RGB; else win32_driver->mode = MODE_15_BGR; } lprintf("win32 mode: %u\n", win32_driver->mode); return TRUE; } #if 0 /* Create a Direct draw surface from * a bitmap resource.. * * NOTE : This is not really useful * anymore since the xine logo code is * being pushed to the backend. */ static LPDIRECTDRAWSURFACE CreateBMP( win32_driver_t * win32_driver, int resource ) { LPDIRECTDRAWSURFACE bmp_surf; DDSURFACEDESC bmp_ddsd; HBITMAP bmp_hndl; BITMAP bmp_head; HDC hdc_dds; HDC hdc_mem; /* load our bitmap from a resource */ if( !( bmp_hndl = LoadBitmap( win32_driver->win32_visual->HInst, MAKEINTRESOURCE( resource ) ) ) ) { Error( 0, "CreateBitmap : could not load bmp resource" ); return 0; } /* create an off screen surface with * the same dimentions as our bitmap */ GetObject( bmp_hndl, sizeof( bmp_head ), &bmp_head ); memset( &bmp_ddsd, 0, sizeof( bmp_ddsd ) ); bmp_ddsd.dwSize = sizeof( bmp_ddsd ); bmp_ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; bmp_ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY; bmp_ddsd.dwWidth = bmp_head.bmWidth; bmp_ddsd.dwHeight = bmp_head.bmHeight; if( IDirectDraw_CreateSurface( win32_driver->ddobj, &bmp_ddsd, &bmp_surf, 0 ) != DD_OK ) { Error( 0, "CreateSurface ( bitmap ) : could not create dd surface" ); return 0; } /* get a handle to our surface dc, * create a compat dc and load * our bitmap into the compat dc */ IDirectDrawSurface_GetDC( bmp_surf, &hdc_dds ); hdc_mem = CreateCompatibleDC( hdc_dds ); SelectObject( hdc_mem, bmp_hndl ); /* copy our bmp from the compat dc * into our dd surface */ BitBlt( hdc_dds, 0, 0, bmp_head.bmWidth, bmp_head.bmHeight, hdc_mem, 0, 0, SRCCOPY ); /* clean up */ DeleteDC( hdc_mem ); DeleteObject( bmp_hndl ); IDirectDrawSurface_ReleaseDC( bmp_surf, hdc_dds ); return bmp_surf; } #endif /* Merge overlay with the current primary * surface. This funtion is only used when * a h/w overlay of the current frame type * is supported. */ static boolean Overlay( LPDIRECTDRAWSURFACE src_surface, RECT * src_rect, LPDIRECTDRAWSURFACE dst_surface, RECT * dst_rect, COLORREF color_key ) { DWORD dw_color_key; DDPIXELFORMAT ddpf; DDOVERLAYFX ddofx; int flags; HRESULT result; /* compute the colorkey pixel value from the RGB value we've got/ * NOTE : based on videolan colorkey code */ memset( &ddpf, 0, sizeof( DDPIXELFORMAT )); ddpf.dwSize = sizeof( DDPIXELFORMAT ); result = IDirectDrawSurface_GetPixelFormat( dst_surface, &ddpf ); if( result != DD_OK ) { Error( 0, "IDirectDrawSurface_GetPixelFormat : could not get surface pixel format" ); return FALSE; } dw_color_key = ( DWORD ) color_key; dw_color_key = ( DWORD ) ( ( ( dw_color_key * ddpf.dwRBitMask ) / 255 ) & ddpf.dwRBitMask ); memset( &ddofx, 0, sizeof( DDOVERLAYFX ) ); ddofx.dwSize = sizeof( DDOVERLAYFX ); ddofx.dckDestColorkey.dwColorSpaceLowValue = dw_color_key; ddofx.dckDestColorkey.dwColorSpaceHighValue = dw_color_key; /* set our overlay flags */ flags = DDOVER_SHOW | DDOVER_KEYDESTOVERRIDE; /* attempt to overlay the surface */ result = IDirectDrawSurface_UpdateOverlay( src_surface, src_rect, dst_surface, dst_rect, flags, &ddofx ); if( result != DD_OK ) { if( result == DDERR_SURFACELOST ) { IDirectDrawSurface_Restore( src_surface ); IDirectDrawSurface_Restore( dst_surface ); IDirectDrawSurface_UpdateOverlay( src_surface, src_rect, dst_surface, dst_rect, flags, &ddofx ); } else { Error( 0, "IDirectDrawSurface_UpdateOverlay : error 0x%lx. You can try disable hardware acceleration (option video.directx.hwaccel).", result ); return FALSE; } } return TRUE; } /* Copy our off screen surface into our primary * surface. This funtion is only used when a * h/w overlay of the current frame format is * not supported. */ static boolean BltCopy( LPDIRECTDRAWSURFACE src_surface, RECT * src_rect, LPDIRECTDRAWSURFACE dst_surface, RECT * dst_rect ) { DDSURFACEDESC ddsd_target; HRESULT result; memset( &ddsd_target, 0, sizeof( ddsd_target ) ); ddsd_target.dwSize = sizeof( ddsd_target ); /* attempt to blt the surface sontents */ result = IDirectDrawSurface_Blt( dst_surface, dst_rect, src_surface, src_rect, DDBLT_WAIT, 0 ); if( result != DD_OK ) { if( result != DDERR_SURFACELOST ) { IDirectDrawSurface_Restore( src_surface ); IDirectDrawSurface_Restore( dst_surface ); IDirectDrawSurface_Blt( dst_surface, dst_rect, src_surface, src_rect, DDBLT_WAIT, 0 ); } else { Error( 0, "IDirectDrawSurface_Blt : error 0x%lx", result ); return FALSE; } } return TRUE; } /* Display our current frame. This function * corrects frame output ratio and clipps the * frame if nessesary. It will then handle * moving the image contents contained in our * secondary surface to our primary surface. */ static boolean DisplayFrame( win32_driver_t * win32_driver ) { int view_width; int view_height; int scaled_width; int scaled_height; int screen_width; int screen_height; RECT clipped; RECT centered; /* aspect ratio calculations */ /* TODO : account for screen ratio as well */ view_width = win32_driver->WndRect.right - win32_driver->WndRect.left; view_height = win32_driver->WndRect.bottom - win32_driver->WndRect.top; if( view_width / win32_driver->ratio < view_height ) { scaled_width = view_width - BORDER_SIZE; scaled_height = view_width / win32_driver->ratio - BORDER_SIZE; } else { scaled_width = view_height * win32_driver->ratio - BORDER_SIZE; scaled_height = view_height - BORDER_SIZE; } /* center our overlay in our view frame */ centered.left = ( view_width - scaled_width ) / 2 + win32_driver->WndRect.left; centered.right = centered.left + scaled_width; centered.top = ( view_height - scaled_height ) / 2 + win32_driver->WndRect.top; centered.bottom = centered.top + scaled_height; /* clip our overlay if it is off screen */ screen_width = GetSystemMetrics( SM_CXSCREEN ); screen_height = GetSystemMetrics( SM_CYSCREEN ); if( centered.left < 0 ) { double x_scale = ( double ) ( view_width + centered.left ) / ( double ) view_width; clipped.left = win32_driver->width - ( int ) ( win32_driver->width * x_scale ); centered.left = 0; } else clipped.left = 0; if( centered.top < 0 ) { double y_scale = ( double ) ( view_height + centered.top ) / ( double ) view_height; clipped.left = win32_driver->height - ( int ) ( win32_driver->height * y_scale ); centered.left = 0; } else clipped.top = 0; if( centered.right > screen_width ) { double x_scale = ( double ) ( view_width - ( centered.right - screen_width ) ) / ( double ) view_width; clipped.right = ( int ) ( win32_driver->width * x_scale ); centered.right = screen_width; } else clipped.right = win32_driver->width; if( centered.bottom > screen_height ) { double y_scale = ( double ) ( view_height - ( centered.bottom - screen_height ) ) / ( double ) view_height; clipped.bottom = ( int ) ( win32_driver->height * y_scale ); centered.bottom = screen_height; } else clipped.bottom = win32_driver->height; /* if surface is entirely off screen or the * width or height is 0 for the overlay or * the output view area, then return without * overlay update */ if( ( centered.left > screen_width ) || ( centered.top > screen_height ) || ( centered.right < 0 ) || ( centered.bottom < 0 ) || ( clipped.left >= clipped.right ) || ( clipped.top >= clipped.bottom ) || ( view_width <= 0 ) || ( view_height <= 0 ) ) return 1; /* we have a h/w supported overlay */ if( ( win32_driver->act_format == XINE_IMGFMT_YV12 ) || ( win32_driver->act_format == XINE_IMGFMT_YUY2 ) ) return Overlay( win32_driver->secondary, &clipped, win32_driver->primary, ¢ered, win32_driver->win32_visual->ColorKey ); /* we do not have a h/w supported overlay */ return BltCopy( win32_driver->secondary, &clipped, win32_driver->primary, ¢ered ); } /* Lock our back buffer to update its contents. */ static void * Lock( win32_driver_t * win32_driver, void * surface ) { LPDIRECTDRAWSURFACE lock_surface = ( LPDIRECTDRAWSURFACE ) surface; HRESULT result; if( !surface ) return 0; memset( &win32_driver->ddsd, 0, sizeof( win32_driver->ddsd ) ); win32_driver->ddsd.dwSize = sizeof( win32_driver->ddsd ); result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 ); if( result == DDERR_SURFACELOST ) { IDirectDrawSurface_Restore( lock_surface ); result = IDirectDrawSurface_Lock( lock_surface, 0, &win32_driver->ddsd, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0 ); if( result != DD_OK ) return 0; } else if( result != DD_OK ) { if( result == DDERR_GENERIC ) { Error( 0, "surface->Lock : error, DDERR_GENERIC" ); exit( 1 ); } } return win32_driver->ddsd.lpSurface; } /* Unlock our back buffer to prepair for display. */ static void Unlock( void * surface ) { LPDIRECTDRAWSURFACE lock_surface = ( LPDIRECTDRAWSURFACE ) surface; if( !surface ) return; IDirectDrawSurface_Unlock( lock_surface, 0 ); } /* ----------------------------------------- * * BEGIN : Xine driver video output plugin * handlers. * * ----------------------------------------- */ static uint32_t win32_get_capabilities( vo_driver_t * vo_driver ) { uint32_t retVal; retVal = VO_CAP_YV12 | VO_CAP_YUY2; #if RGB_SUPPORT retVal |= VO_CAP_RGB; #endif /* RGB_SUPPORT */ return retVal; } static void win32_frame_field( vo_frame_t * vo_frame, int which_field ) { /* I have no idea what this even * does, frame interlace stuff? */ } static void win32_free_framedata(vo_frame_t* vo_frame) { win32_frame_t * frame = ( win32_frame_t * ) vo_frame; if(frame->vo_frame.base[0]) { free(frame->vo_frame.base[0]); frame->vo_frame.base[0] = NULL; } if(frame->vo_frame.base[1]) { free(frame->vo_frame.base[1]); frame->vo_frame.base[1] = NULL; } if(frame->vo_frame.base[2]) { free(frame->vo_frame.base[2]); frame->vo_frame.base[2] = NULL; } } static void win32_frame_dispose( vo_frame_t * vo_frame ) { win32_frame_t * win32_frame = ( win32_frame_t * ) vo_frame; free(win32_frame->buffer); win32_free_framedata(vo_frame); free( win32_frame ); } static vo_frame_t * win32_alloc_frame( vo_driver_t * vo_driver ) { win32_frame_t *win32_frame; win32_frame = calloc(1, sizeof(win32_frame_t)); if (!win32_frame) return NULL; pthread_mutex_init(&win32_frame->vo_frame.mutex, NULL); win32_frame->vo_frame.proc_slice = NULL; win32_frame->vo_frame.proc_frame = NULL; win32_frame->vo_frame.field = win32_frame_field; win32_frame->vo_frame.dispose = win32_frame_dispose; win32_frame->format = -1; return ( vo_frame_t * ) win32_frame; } static void win32_update_frame_format( vo_driver_t * vo_driver, vo_frame_t * vo_frame, uint32_t width, uint32_t height, double ratio, int format, int flags ) { win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver; win32_frame_t *win32_frame = ( win32_frame_t * ) vo_frame; /*printf("vo_out_directx : win32_update_frame_format() - width = %d, height=%d, ratio_code=%d, format=%d, flags=%d\n", width, height, ratio_code, format, flags);*/ if( ( win32_frame->format != format ) || ( win32_frame->width != width ) || ( win32_frame->height != height ) ) { /* free our allocated memory */ win32_free_framedata((vo_frame_t *)&win32_frame->vo_frame); /* create new render buffer */ if( format == XINE_IMGFMT_YV12 ) { win32_frame->vo_frame.pitches[0] = 8*((width + 7) / 8); win32_frame->vo_frame.pitches[1] = 8*((width + 15) / 16); win32_frame->vo_frame.pitches[2] = 8*((width + 15) / 16); win32_frame->vo_frame.base[0] = malloc(win32_frame->vo_frame.pitches[0] * height); win32_frame->vo_frame.base[1] = malloc(win32_frame->vo_frame.pitches[1] * ((height+1)/2)); win32_frame->vo_frame.base[2] = malloc(win32_frame->vo_frame.pitches[2] * ((height+1)/2)); win32_frame->size = win32_frame->vo_frame.pitches[0] * height * 2; } else if( format == XINE_IMGFMT_YUY2 ) { win32_frame->vo_frame.pitches[0] = 8*((width + 3) / 4); win32_frame->vo_frame.base[0] = malloc(win32_frame->vo_frame.pitches[0] * height * 2); win32_frame->vo_frame.base[1] = NULL; win32_frame->vo_frame.base[2] = NULL; win32_frame->size = win32_frame->vo_frame.pitches[0] * height * 2; } #if RGB_SUPPORT else if( format == IMGFMT_RGB ) { win32_frame->size = width * height * 3; win32_frame->buffer = malloc( win32_frame->size ); vo_frame->base[0] = win32_frame->buffer; } #endif else { xprintf (win32_driver->xine, XINE_VERBOSITY_DEBUG, "vo_out_directx : !!! unsupported image format %04x !!!\n", format ); exit (1); } win32_frame->format = format; win32_frame->width = width; win32_frame->height = height; win32_frame->ratio = ratio; } } static void win32_display_frame( vo_driver_t * vo_driver, vo_frame_t * vo_frame ) { win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver; win32_frame_t *win32_frame = ( win32_frame_t * ) vo_frame; /* if the required width, height or format has changed * then recreate the secondary buffer */ if( ( win32_driver->req_format != win32_frame->format ) || ( win32_driver->width != win32_frame->width ) || ( win32_driver->height != win32_frame->height ) ) { CreateSecondary( win32_driver, win32_frame->width, win32_frame->height, win32_frame->format ); } /* determine desired ratio */ win32_driver->ratio = win32_frame->ratio; /* lock our surface to update its contents */ win32_driver->contents = Lock( win32_driver, win32_driver->secondary ); /* surface unavailable, skip frame render */ if( !win32_driver->contents ) { vo_frame->free( vo_frame ); return; } /* if our actual frame format is the native screen * pixel format, we need to convert it */ if( win32_driver->act_format == IMGFMT_NATIVE ) { /* use the software color conversion functions * to rebuild the frame in our native screen * pixel format ... this is slow */ if( win32_driver->req_format == XINE_IMGFMT_YV12 ) { /* convert from yv12 to native * screen pixel format */ win32_driver->yuv2rgb->configure( win32_driver->yuv2rgb, win32_driver->width, win32_driver->height, win32_frame->vo_frame.pitches[0], win32_frame->vo_frame.pitches[1], win32_driver->width, win32_driver->height, win32_driver->width * win32_driver->bytespp); win32_driver->yuv2rgb->yuv2rgb_fun( win32_driver->yuv2rgb, win32_driver->contents, win32_frame->vo_frame.base[0], win32_frame->vo_frame.base[1], win32_frame->vo_frame.base[2] ); } if( win32_driver->req_format == XINE_IMGFMT_YUY2 ) { /* convert from yuy2 to native * screen pixel format */ win32_driver->yuv2rgb->configure( win32_driver->yuv2rgb, win32_driver->width, win32_driver->height, win32_frame->vo_frame.pitches[0], win32_frame->vo_frame.pitches[0] / 2, win32_driver->width, win32_driver->height, win32_driver->width * win32_driver->bytespp ); win32_driver->yuv2rgb->yuy22rgb_fun( win32_driver->yuv2rgb, win32_driver->contents, win32_frame->vo_frame.base[0] ); } #if RGB_SUPPORT if( win32_driver->req_format == IMGFMT_RGB ) { /* convert from 24 bit rgb to native * screen pixel format */ /* TODO : rgb2rgb conversion */ } #endif } else { /* the actual format is identical to our * stream format. we just need to copy it */ int line; uint8_t * src; vo_frame_t * frame = vo_frame; uint8_t * dst = (uint8_t *)win32_driver->contents; switch(win32_frame->format) { case XINE_IMGFMT_YV12: src = frame->base[0]; for (line = 0; line < frame->height ; line++){ xine_fast_memcpy( dst, src, frame->width); src += vo_frame->pitches[0]; dst += win32_driver->ddsd.lPitch; } src = frame->base[2]; for (line = 0; line < frame->height/2 ; line++){ xine_fast_memcpy( dst, src, frame->width/2); src += vo_frame->pitches[2]; dst += win32_driver->ddsd.lPitch/2; } src = frame->base[1]; for (line = 0; line < frame->height/2 ; line++){ xine_fast_memcpy( dst, src, frame->width/2); src += vo_frame->pitches[1]; dst += win32_driver->ddsd.lPitch/2; } break; case XINE_IMGFMT_YUY2: default: src = frame->base[0]; for (line = 0; line < frame->height ; line++){ xine_fast_memcpy( dst, src, frame->width*2); src += vo_frame->pitches[0]; dst += win32_driver->ddsd.lPitch; } break; } } /* unlock the surface */ Unlock( win32_driver->secondary ); /* scale, clip and display our frame */ DisplayFrame( win32_driver ); /* tag our frame as displayed */ if((win32_driver->current != NULL) && ((vo_frame_t *)win32_driver->current != vo_frame)) { vo_frame->free(&win32_driver->current->vo_frame); } win32_driver->current = (win32_frame_t *)vo_frame; } static void win32_overlay_blend( vo_driver_t * vo_driver, vo_frame_t * vo_frame, vo_overlay_t * vo_overlay ) { win32_frame_t * win32_frame = ( win32_frame_t * ) vo_frame; win32_driver_t * win32_driver = ( win32_driver_t * ) vo_driver; win32_driver->alphablend_extra_data.offset_x = vo_frame->overlay_offset_x; win32_driver->alphablend_extra_data.offset_y = vo_frame->overlay_offset_y; /* temporary overlay support, somthing more appropriate * for win32 will be devised at a later date */ if( vo_overlay->rle ) { if( vo_frame->format == XINE_IMGFMT_YV12 ) _x_blend_yuv( win32_frame->vo_frame.base, vo_overlay, win32_frame->width, win32_frame->height, win32_frame->vo_frame.pitches, &win32_driver->alphablend_extra_data ); else _x_blend_yuy2( win32_frame->vo_frame.base[0], vo_overlay, win32_frame->width, win32_frame->height, win32_frame->vo_frame.pitches[0], &win32_driver->alphablend_extra_data ); } } static int win32_get_property( vo_driver_t * vo_driver, int property ) { lprintf( "win32_get_property\n" ); return 0; } static int win32_set_property( vo_driver_t * vo_driver, int property, int value ) { win32_driver_t *win32_driver = (win32_driver_t *)vo_driver; if (property == VO_PROP_DISCARD_FRAMES) { if (value == -1) { value = 0; if (win32_driver->current) { win32_driver->current->vo_frame.free (&win32_driver->current->vo_frame); win32_driver->current = NULL; value = 1; } } } return value; } static void win32_get_property_min_max( vo_driver_t * vo_driver, int property, int * min, int * max ) { *min = 0; *max = 0; } static int win32_gui_data_exchange( vo_driver_t * vo_driver, int data_type, void * data ) { win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver; switch( data_type ) { case GUI_WIN32_MOVED_OR_RESIZED: UpdateRect( win32_driver->WndHnd, &win32_driver->WndRect, win32_driver->win32_visual ); DisplayFrame( win32_driver ); break; case XINE_GUI_SEND_DRAWABLE_CHANGED: { HRESULT result; HWND newWndHnd = (HWND) data; /* set cooperative level */ result = IDirectDraw_SetCooperativeLevel( win32_driver->ddobj, newWndHnd, DDSCL_NORMAL ); if( result != DD_OK ) { Error( 0, "SetCooperativeLevel : error 0x%lx", result ); return 0; } /* associate our clipper with new window */ result = IDirectDrawClipper_SetHWnd( win32_driver->ddclipper, 0, newWndHnd ); if( result != DD_OK ) { Error( 0, "ddclipper->SetHWnd : error 0x%lx", result ); return 0; } /* store our objects in our visual struct */ win32_driver->WndHnd = newWndHnd; /* update video area and redraw current frame */ UpdateRect( win32_driver->WndHnd, &win32_driver->WndRect, win32_driver->win32_visual ); DisplayFrame( win32_driver ); break; } } return 0; } static int win32_redraw_needed(vo_driver_t* this_gen) { int ret = 0; /* TC - May need to revisit this! */ #ifdef TC win32_driver_t *win32_driver = (win32_driver_t *) this_gen; if( _x_vo_scale_redraw_needed( &win32_driver->sc ) ) { win32_gui_data_exchange(this_gen, GUI_WIN32_MOVED_OR_RESIZED, 0); ret = 1; } #endif return ret; } static void win32_exit( vo_driver_t * vo_driver ) { win32_driver_t *win32_driver = ( win32_driver_t * ) vo_driver; Destroy( win32_driver ); } static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual) /*vo_driver_t *init_video_out_plugin( config_values_t * config, void * win32_visual )*/ { static const char * const config_hwaccel_values[] = {"full", "scale", "none", NULL }; const win32_visual_t *win32_visual = visual; directx_class_t *class = (directx_class_t *)class_gen; win32_driver_t *win32_driver; config_values_t *config = class->xine->config; win32_driver = calloc(1, sizeof(win32_driver_t)); if (!win32_driver || !visual) return NULL; _x_alphablend_init(&win32_driver->alphablend_extra_data, class->xine); win32_driver->xine = class->xine; win32_driver->WndHnd = win32_visual->WndHnd; win32_driver->WndRect.left = win32_visual->WndRect.left; win32_driver->WndRect.right = win32_visual->WndRect.right; win32_driver->WndRect.top = win32_visual->WndRect.top; win32_driver->WndRect.bottom = win32_visual->WndRect.bottom; /* Make sure that the DirectX drivers are available and present! */ /* Not complete yet */ win32_driver->win32_visual = win32_visual; win32_driver->vo_driver.get_capabilities = win32_get_capabilities; win32_driver->vo_driver.alloc_frame = win32_alloc_frame ; win32_driver->vo_driver.update_frame_format = win32_update_frame_format; win32_driver->vo_driver.display_frame = win32_display_frame; win32_driver->vo_driver.overlay_blend = win32_overlay_blend; win32_driver->vo_driver.get_property = win32_get_property; win32_driver->vo_driver.set_property = win32_set_property; win32_driver->vo_driver.get_property_min_max = win32_get_property_min_max; win32_driver->vo_driver.gui_data_exchange = win32_gui_data_exchange; win32_driver->vo_driver.dispose = win32_exit; win32_driver->vo_driver.redraw_needed = win32_redraw_needed; win32_driver->hwaccel = config->register_enum(config, "video.directx.hwaccel", 0, (char**)config_hwaccel_values, _("HW acceleration level"), _("Possible values (default full):\n\n" "full: full acceleration\n" "scale: disable colorspace conversion (HW scaling only)\n" "none: disable all acceleration"), 10, NULL, NULL); if (!CreatePrimary( win32_driver )) { Destroy( win32_driver ); return NULL; } if( !CheckPixelFormat( win32_driver ) ) { Error( 0, "vo_directx : Your screen pixel format is not supported" ); Destroy( win32_driver ); return NULL; } win32_driver->yuv2rgb_factory = yuv2rgb_factory_init( win32_driver->mode, 0, 0 ); if (!win32_driver->yuv2rgb_factory) { xprintf (win32_driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": yuv2rgb initialization failed\n"); Destroy (win32_driver); return NULL; } win32_driver->yuv2rgb = win32_driver->yuv2rgb_factory->create_converter(win32_driver->yuv2rgb_factory); if (!win32_driver->yuv2rgb) { Destroy( win32_driver ); return NULL; } return ( vo_driver_t * ) win32_driver; } static void *init_class (xine_t *xine, const void *visual_gen) { directx_class_t *directx; /* * from this point on, nothing should go wrong anymore */ directx = calloc(1, sizeof (directx_class_t)); if (!directx) return NULL; directx->driver_class.open_plugin = open_plugin; directx->driver_class.identifier = "DirectX"; directx->driver_class.description = N_("xine video output plugin for win32 using directx"); directx->driver_class.dispose = default_video_driver_class_dispose; directx->xine = xine; return directx; } static const vo_info_t vo_info_win32 = { .priority = 7, .visual_type = XINE_VISUAL_TYPE_DIRECTX, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "vo_directx", XINE_VERSION_CODE, &vo_info_win32, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_stk.c0000644000175000017500000003653714647725152016510 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_stk.c, Libstk Surface Video Driver * more info on Libstk at http://www.libstk.org * * based on video_out_sdl from * Miguel Freitas * * based on mpeg2dec code from * Ryan C. Gordon and * Dominik Schnitzer * * (SDL) xine version by Miguel Freitas (Jan/2002) * Missing features: * - event handling * - fullscreen * - surface locking (for Xlib error noted below) * - stability, testing, etc?? ;) * Known bugs: * - using stk SDL backend, a window move is sometimes needed for the video * to show up, alghough the audio is playing * - using stk SDL backend an XLib unexpected async response error sometimes * occurs */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #define LOG_MODULE "video_out_stk" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include #include #include #include /* Extend the video frame class with stk private data */ typedef struct stk_frame_s { /* public interface */ vo_frame_t vo_frame; /* stk private data */ int width, height, format; double ratio; overlay_t* overlay; } stk_frame_t; /* Extend the video output class with stk private data */ typedef struct stk_driver_s { /* public interface */ vo_driver_t vo_driver; /* stk private data */ surface_t* surface; xine_panel_t* xine_panel; uint8_t bpp; /* do we need this ? */ pthread_mutex_t mutex; uint32_t capabilities; vo_scale_t sc; xine_t *xine; alphablend_t alphablend_extra_data; } stk_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } stk_class_t; static uint32_t stk_get_capabilities (vo_driver_t *this_gen) { stk_driver_t* this = (stk_driver_t *)this_gen; //printf("video_out_stk: get_capabilities()\n"); return this->capabilities; } /* copy YUV to RGB data (see fb driver)*/ static void stk_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { /* not needed by SDL, we may need it for other stk backends */ //printf("video_out_stk: frame_copy()\n"); } /* set up the rgb_dst and strides (see fb driver) */ static void stk_frame_field (vo_frame_t *vo_img, int which_field) { /* not needed for SDL, maybe not for libstk ? */ //printf("video_out_stk: frame_field()\n"); } static void stk_frame_dispose (vo_frame_t *vo_img) { stk_frame_t* frame = (stk_frame_t *)vo_img; //printf("video_out_stk: frame_dispose()\n"); if (frame->overlay) stk_overlay_free(frame->overlay); free (frame); } static vo_frame_t *stk_alloc_frame(vo_driver_t *this_gen) { stk_driver_t* this = (stk_driver_t*)this_gen; /* allocate the frame */ stk_frame_t* frame; //printf("video_out_stk: alloc_frame()\n"); frame = calloc(1, sizeof(stk_frame_t)); if (!frame) return NULL; /* populate the frame members*/ pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* map the frame function pointers */ frame->vo_frame.proc_slice = stk_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = stk_frame_field; frame->vo_frame.dispose = stk_frame_dispose; return (vo_frame_t *) frame; } static void stk_compute_ideal_size (stk_driver_t* this) { //printf("video_out_stk: compute_ideal_size()\n"); _x_vo_scale_compute_ideal_size(&this->sc); } static void stk_compute_output_size (stk_driver_t *this) { //printf("video_out_stk: compute_output_size()\n"); _x_vo_scale_compute_output_size( &this->sc ); lprintf ("frame source %d x %d => screen output %d x %d\n", this->sc.delivered_width, this->sc.delivered_height, this->sc.output_width, this->sc.output_height); } static void stk_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { stk_driver_t* this = (stk_driver_t*)this_gen; stk_frame_t* frame = (stk_frame_t*)frame_gen; //printf("video_out_stk: update_frame_format()\n"); if ((frame->width != width) || (frame->height != height) || (frame->format != format)) { lprintf("update_frame_format - %d=%d, %d=%d, %d=%d\n", frame->width, width, frame->height, height, frame->format, format); lprintf("vo_frame data - width, height, format: %d, %d, %d\n", frame->vo_frame.width, frame->vo_frame.height, frame->vo_frame.format); /* (re-) allocate image */ if (frame->overlay) { stk_overlay_free(frame->overlay); frame->overlay = NULL; } if (format == XINE_IMGFMT_YV12) { lprintf ("format YV12\n"); frame->overlay = stk_surface_create_overlay(this->surface, width, height, STK_FORMAT_YV12); } else if (format == XINE_IMGFMT_YUY2) { lprintf("format YUY2\n"); frame->overlay = stk_surface_create_overlay(this->surface, width, height, STK_FORMAT_YUY2); } if (frame->overlay == NULL) return; /* From the SDL driver: * This needs to be done becuase I have found that * pixels isn't setup until this is called. */ stk_overlay_lock(frame->overlay); frame->vo_frame.pitches[0] = stk_overlay_pitches(frame->overlay, 0); frame->vo_frame.pitches[1] = stk_overlay_pitches(frame->overlay, 2); frame->vo_frame.pitches[2] = stk_overlay_pitches(frame->overlay, 1); frame->vo_frame.base[0] = stk_overlay_pixels(frame->overlay, 0); frame->vo_frame.base[1] = stk_overlay_pixels(frame->overlay, 2); frame->vo_frame.base[2] = stk_overlay_pixels(frame->overlay, 1); frame->width = width; frame->height = height; frame->format = format; } else { stk_overlay_lock(frame->overlay); } frame->ratio = ratio; } static void stk_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { stk_driver_t* this = (stk_driver_t*)this_gen; stk_frame_t* frame = (stk_frame_t*)frame_gen; //printf("video_out_stk: overlay_blend()\n"); this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; if (overlay->rle) { if (frame->format == XINE_IMGFMT_YV12) _x_blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else _x_blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } static void stk_check_events (stk_driver_t* this) { /* SDL checks for a resize, our video panels aren't resizeable... */ //printf("video_out_stk: check_events()\n"); } /* when is this called ? */ static int stk_redraw_needed (vo_driver_t* this_gen) { stk_driver_t* this = (stk_driver_t*)this_gen; int ret = 0; static int last_gui_width, last_gui_height; //printf("video_out_stk: redraw_needed()\n"); if( last_gui_width != this->sc.gui_width || last_gui_height != this->sc.gui_height || this->sc.force_redraw ) { last_gui_width = this->sc.gui_width; last_gui_height = this->sc.gui_height; stk_compute_output_size (this); ret = 1; } this->sc.force_redraw = 0; return ret; } static void stk_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { stk_driver_t* this = (stk_driver_t*)this_gen; stk_frame_t* frame = (stk_frame_t*)frame_gen; //printf("video_out_stk: display_frame()\n"); pthread_mutex_lock(&this->mutex); if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) ) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_stk: change frame format\n"); this->sc.delivered_width = frame->width; this->sc.delivered_height = frame->height; this->sc.delivered_ratio = frame->ratio; stk_compute_ideal_size(this); this->sc.force_redraw = 1; } /* * tell gui that we are about to display a frame, * ask for offset and output size */ stk_check_events (this); stk_redraw_needed (this_gen); stk_overlay_unlock(frame->overlay); stk_overlay_display(frame->overlay, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); frame->vo_frame.free (&frame->vo_frame); pthread_mutex_unlock(&this->mutex); } static int stk_get_property (vo_driver_t* this_gen, int property) { stk_driver_t* this = (stk_driver_t *)this_gen; //printf("video_out_stk: get_property()\n"); if (property == VO_PROP_ASPECT_RATIO) return this->sc.user_ratio; return 0; } static int stk_set_property (vo_driver_t* this_gen, int property, int value) { stk_driver_t* this = (stk_driver_t*)this_gen; //printf("video_out_stk: set_property()\n"); if ( property == VO_PROP_ASPECT_RATIO) { if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_stk: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); stk_compute_ideal_size (this); this->sc.force_redraw = 1; } return value; } static void stk_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { /* stk_driver_t* this = (stk_driver_t*)this_gen; */ //printf("video_out_stk: get_property_min_max()\n"); } static int stk_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { stk_driver_t *this = (stk_driver_t*)this_gen; switch (data_type) { case XINE_GUI_SEND_COMPLETION_EVENT: break; case XINE_GUI_SEND_EXPOSE_EVENT: break; case XINE_GUI_SEND_DRAWABLE_CHANGED: this->xine_panel = (xine_panel_t*)data; this->surface = stk_xine_panel_surface(this->xine_panel); this->sc.gui_x = stk_xine_panel_x(this->xine_panel); this->sc.gui_y = stk_xine_panel_y(this->xine_panel); this->sc.gui_width = stk_xine_panel_width(this->xine_panel); this->sc.gui_height = stk_xine_panel_height(this->xine_panel); this->sc.force_redraw = 1; break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: break; } return 0; } static void stk_dispose (vo_driver_t * this_gen) { stk_driver_t* this = (stk_driver_t*)this_gen; //printf("video_out_stk: dispose()\n"); /* FIXME: any libstk deleting must be done in the app or library * since we didn't create the surface */ _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); free(this); } static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { stk_class_t * class = (stk_class_t *) class_gen; /* allocate the video output driver class */ stk_driver_t* this; //printf("video_out_stk: open_plugin()\n"); this = calloc(1, sizeof (stk_driver_t)); if (!this) return NULL; _x_alphablend_init(&this->alphablend_extra_data, class->xine); /* populate the video output driver members */ this->xine = class->xine; this->xine_panel = (xine_panel_t*)visual_gen; this->surface = stk_xine_panel_surface(this->xine_panel); /* FIXME: provide a way to get bpp from stk surfaces */ /* this->bpp = stk_surface_bpp(this->surface); */ this->bpp = 32; pthread_mutex_init(&this->mutex, NULL); /* FIXME: provide a way to get YUV formats from stk surfaces */ /* this->capabilities = stk_surface_formats(this->surface); */ this->capabilities = VO_CAP_YUY2 | VO_CAP_YV12; /* FIXME: what does this do ? */ _x_vo_scale_init( &this->sc, 0, 0, this->xine->config ); this->sc.gui_x = stk_xine_panel_x(this->xine_panel); this->sc.gui_y = stk_xine_panel_y(this->xine_panel); this->sc.gui_width = stk_xine_panel_width(this->xine_panel); this->sc.gui_height = stk_xine_panel_height(this->xine_panel); /* map the video output driver function pointers */ this->vo_driver.get_capabilities = stk_get_capabilities; this->vo_driver.alloc_frame = stk_alloc_frame; this->vo_driver.update_frame_format = stk_update_frame_format; this->vo_driver.overlay_begin = NULL; /* not used */ this->vo_driver.overlay_blend = stk_overlay_blend; this->vo_driver.overlay_end = NULL; /* not used */ this->vo_driver.display_frame = stk_display_frame; this->vo_driver.get_property = stk_get_property; this->vo_driver.set_property = stk_set_property; this->vo_driver.get_property_min_max = stk_get_property_min_max; this->vo_driver.gui_data_exchange = stk_gui_data_exchange; this->vo_driver.dispose = stk_dispose; this->vo_driver.redraw_needed = stk_redraw_needed; /* FIXME: move this to the stk SDL driver code */ xine_setenv("SDL_VIDEO_YUV_HWACCEL", "1", 1); xine_setenv("SDL_VIDEO_X11_NODIRECTCOLOR", "1", 1); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_stk: warning, xine's STK driver is EXPERIMENTAL\n"); return &this->vo_driver; } /** * Class Functions */ static void *init_class (xine_t *xine, const void *visual_gen) { stk_class_t* this; //printf("video_out_stk: init_class()\n"); this = calloc(1, sizeof(stk_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "stk"; this->driver_class.description = N_("xine video output plugin using the Libstk Surface Set-top Toolkit"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } /* what priority should we be (what is low), what vistype should we declare ? */ static const vo_info_t vo_info_stk = { .priority = 4, .visual_type = XINE_VISUAL_TYPE_FB, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "stk", XINE_VERSION_CODE, &vo_info_stk, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_raw.c0000644000175000017500000003513514647725152016471 0ustar meme /* * Copyright (C) 2007-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * * video_out_raw.c, a video output plugin to pass raw data to frontend * * Written by Christophe Thommeret , * based on others' video output plugins. * */ /* #define LOG */ #define LOG_MODULE "video_out_raw" /* Allow frontend some time to render frames * However, frontends are strongly advised to render synchronously */ #define NUM_FRAMES_BACKLOG 4 #define BYTES_PER_PIXEL 3 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include "yuv2rgb.h" #include typedef struct { vo_frame_t vo_frame; int width, height, format, flags; double ratio; uint8_t *rgb, *rgb_dst; yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */ } raw_frame_t; typedef struct { vo_driver_t vo_driver; void *user_data; void (*raw_output_cb) (void *user_data, int format, int frame_width, int frame_height, double frame_aspect, void *data0, void *data1, void *data2); void (*raw_overlay_cb) (void *user_data, int num_ovl, raw_overlay_t *overlays_p); int ovl_changed; raw_overlay_t overlays[XINE_VORAW_MAX_OVL]; int doYV12; int doYUY2; yuv2rgb_factory_t *yuv2rgb_factory; /* Frame state */ raw_frame_t *frame[NUM_FRAMES_BACKLOG]; xine_t *xine; } raw_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } raw_class_t; static int raw_process_ovl( raw_driver_t *this_gen, vo_overlay_t *overlay ) { raw_overlay_t *ovl = &this_gen->overlays[this_gen->ovl_changed-1]; if ( overlay->width<=0 || overlay->height<=0 ) return 0; if ( (overlay->width*overlay->height)!=(ovl->ovl_w*ovl->ovl_h) ) ovl->ovl_rgba = (uint8_t*)realloc( ovl->ovl_rgba, overlay->width*overlay->height*4 ); ovl->ovl_w = overlay->width; ovl->ovl_h = overlay->height; ovl->ovl_x = overlay->x; ovl->ovl_y = overlay->y; _x_overlay_to_argb32(overlay, (uint32_t*)ovl->ovl_rgba, overlay->width, "RGBA"); return 1; } static void raw_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { raw_driver_t *this = (raw_driver_t *) this_gen; (void)frame_gen; if ( !changed ) return; ++this->ovl_changed; } static void raw_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { raw_driver_t *this = (raw_driver_t *) this_gen; (void)frame_gen; if ( !this->ovl_changed || this->ovl_changed>XINE_VORAW_MAX_OVL ) return; if (overlay->rle) { if (!overlay->rgb_clut || !overlay->hili_rgb_clut) _x_overlay_clut_yuv2rgb (overlay, 0); if ( raw_process_ovl( this, overlay ) ) ++this->ovl_changed; } } static void raw_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { raw_driver_t *this = (raw_driver_t *) this_gen; (void)vo_img; if ( !this->ovl_changed ) return; this->raw_overlay_cb( this->user_data, this->ovl_changed-1, this->overlays ); this->ovl_changed = 0; } static void raw_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { raw_frame_t *frame = (raw_frame_t *) vo_img ; vo_img->proc_called = 1; if (! frame->rgb_dst) return; if( frame->vo_frame.crop_left || frame->vo_frame.crop_top || frame->vo_frame.crop_right || frame->vo_frame.crop_bottom ) { /* TODO: ?!? */ return; } if (frame->format == XINE_IMGFMT_YV12) frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0], src[1], src[2]); else frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src[0]); } static void raw_frame_field (vo_frame_t *vo_img, int which_field) { raw_frame_t *frame = (raw_frame_t *) vo_img ; raw_driver_t *this = (raw_driver_t *) vo_img->driver; if ( frame->format==XINE_IMGFMT_YV12 && this->doYV12 ) { frame->rgb_dst = 0; return; } else if ( frame->format==XINE_IMGFMT_YUY2 && this->doYUY2 ) { frame->rgb_dst = 0; return; } switch (which_field) { case VO_TOP_FIELD: frame->rgb_dst = (uint8_t *)frame->rgb; break; case VO_BOTTOM_FIELD: frame->rgb_dst = (uint8_t *)frame->rgb + frame->width * BYTES_PER_PIXEL; break; case VO_BOTH_FIELDS: frame->rgb_dst = (uint8_t *)frame->rgb; break; } frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL); } static void raw_frame_dispose (vo_frame_t *vo_img) { raw_frame_t *frame = (raw_frame_t *) vo_img ; frame->yuv2rgb->dispose (frame->yuv2rgb); xine_free_aligned (frame->vo_frame.base[0]); xine_free_aligned (frame->vo_frame.base[1]); xine_free_aligned (frame->vo_frame.base[2]); xine_free_aligned (frame->rgb); free (frame); } static vo_frame_t *raw_alloc_frame (vo_driver_t *this_gen) { raw_frame_t *frame; raw_driver_t *this = (raw_driver_t *) this_gen; frame = (raw_frame_t *) calloc(1, sizeof(raw_frame_t)); if (!frame) return NULL; /* * colorspace converter for this frame */ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory); if (!frame->yuv2rgb) { free(frame); return NULL; } frame->vo_frame.base[0] = frame->vo_frame.base[1] = frame->vo_frame.base[2] = frame->rgb = NULL; frame->width = frame->height = frame->format = frame->flags = 0; pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions/fields */ frame->vo_frame.proc_slice = raw_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = raw_frame_field; frame->vo_frame.dispose = raw_frame_dispose; frame->vo_frame.driver = this_gen; return (vo_frame_t *) frame; } static void raw_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { raw_frame_t *frame = (raw_frame_t *) frame_gen; (void)this_gen; /* Check frame size and format and reallocate if necessary */ if ((frame->width != (int)width) || (frame->height != (int)height) || (frame->format != format) || (frame->flags != flags)) { /* lprintf ("updating frame to %d x %d (ratio=%g, format=%08x)\n", width, height, ratio, format); */ /* (re-) allocate render space */ xine_free_aligned (frame->vo_frame.base[0]); xine_free_aligned (frame->vo_frame.base[1]); xine_free_aligned (frame->vo_frame.base[2]); xine_free_aligned (frame->rgb); if (format == XINE_IMGFMT_YV12) { frame->vo_frame.pitches[0] = 8*((width + 7) / 8); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); frame->vo_frame.base[0] = xine_mallocz_aligned (frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = xine_mallocz_aligned (frame->vo_frame.pitches[1] * ((height+1)/2)); frame->vo_frame.base[2] = xine_mallocz_aligned (frame->vo_frame.pitches[2] * ((height+1)/2)); } else { frame->vo_frame.pitches[0] = 8*((width + 3) / 4); frame->vo_frame.base[0] = xine_mallocz_aligned (frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; } frame->rgb = xine_mallocz_aligned (BYTES_PER_PIXEL*width*height); /* set up colorspace converter */ switch (flags & VO_BOTH_FIELDS) { case VO_TOP_FIELD: case VO_BOTTOM_FIELD: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, 2*frame->vo_frame.pitches[0], 2*frame->vo_frame.pitches[1], width, height, BYTES_PER_PIXEL*width * 2); break; case VO_BOTH_FIELDS: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, frame->vo_frame.pitches[0], frame->vo_frame.pitches[1], width, height, BYTES_PER_PIXEL*width); break; } frame->width = width; frame->height = height; frame->format = format; frame->flags = flags; raw_frame_field ((vo_frame_t *)frame, flags); } frame->ratio = ratio; } static int raw_redraw_needed (vo_driver_t *this_gen) { (void)this_gen; return 0; } static void raw_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { raw_driver_t *this = (raw_driver_t *) this_gen; raw_frame_t *frame = (raw_frame_t *) frame_gen; int i; if (this->frame[NUM_FRAMES_BACKLOG-1]) { this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame.free (&this->frame[NUM_FRAMES_BACKLOG-1]->vo_frame); } for (i = NUM_FRAMES_BACKLOG-1; i > 0; i--) this->frame[i] = this->frame[i-1]; this->frame[0] = frame; if ( frame->rgb_dst ) { this->raw_output_cb( this->user_data, XINE_VORAW_RGB, frame->width, frame->height, frame->ratio, frame->rgb, 0, 0 ); } else if ( frame->format==XINE_IMGFMT_YV12 ) { this->raw_output_cb( this->user_data, XINE_VORAW_YV12, frame->width, frame->height, frame->ratio, frame->vo_frame.base[0], frame->vo_frame.base[1], frame->vo_frame.base[2] ); } else { this->raw_output_cb( this->user_data, XINE_VORAW_YUY2, frame->width, frame->height, frame->ratio, frame->vo_frame.base[0], 0, 0 ); } } static int raw_get_property (vo_driver_t *this_gen, int property) { (void)this_gen; switch (property) { case VO_PROP_ASPECT_RATIO: return XINE_VO_ASPECT_AUTO; case VO_PROP_MAX_NUM_FRAMES: return 15; case VO_PROP_BRIGHTNESS: return 0; case VO_PROP_CONTRAST: return 128; case VO_PROP_SATURATION: return 128; case VO_PROP_WINDOW_WIDTH: return 0; case VO_PROP_WINDOW_HEIGHT: return 0; default: return 0; } } static int raw_set_property (vo_driver_t *this_gen, int property, int value) { raw_driver_t *this = (raw_driver_t *) this_gen; if (property == VO_PROP_DISCARD_FRAMES) { if (value == -1) { int i, n = 0; for (i = NUM_FRAMES_BACKLOG - 1; i >= 0; i--) { if (this->frame[i]) { this->frame[i]->vo_frame.free (&this->frame[i]->vo_frame); this->frame[i] = NULL; n++; } } value = n; } } return value; } static void raw_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { (void)this_gen; (void)property; *min = 0; *max = 0; } static int raw_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { (void)this_gen; (void)data_type; (void)data; return 0; } static uint32_t raw_get_capabilities (vo_driver_t *this_gen) { uint32_t capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP; (void)this_gen; return capabilities; } static void raw_dispose (vo_driver_t *this_gen) { raw_driver_t *this = (raw_driver_t *) this_gen; int i; for (i = 0; i < NUM_FRAMES_BACKLOG; i++) if (this->frame[i]) this->frame[i]->vo_frame.dispose (&this->frame[i]->vo_frame); this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); for ( i=0; ioverlays[i].ovl_rgba ); free (this); } static vo_driver_t *raw_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { const raw_visual_t *visual = (const raw_visual_t *) visual_gen; raw_class_t *class = (raw_class_t *) class_gen; raw_driver_t *this; int i; this = (raw_driver_t *) calloc(1, sizeof(raw_driver_t)); if (!this) return NULL; this->raw_output_cb = visual->raw_output_cb; this->user_data = visual->user_data; this->xine = class->xine; this->raw_overlay_cb = visual->raw_overlay_cb; this->doYV12 = visual->supported_formats&XINE_VORAW_YV12; this->doYUY2 = visual->supported_formats&XINE_VORAW_YUY2; this->vo_driver.get_capabilities = raw_get_capabilities; this->vo_driver.alloc_frame = raw_alloc_frame; this->vo_driver.update_frame_format = raw_update_frame_format; this->vo_driver.overlay_begin = raw_overlay_begin; this->vo_driver.overlay_blend = raw_overlay_blend; this->vo_driver.overlay_end = raw_overlay_end; this->vo_driver.display_frame = raw_display_frame; this->vo_driver.get_property = raw_get_property; this->vo_driver.set_property = raw_set_property; this->vo_driver.get_property_min_max = raw_get_property_min_max; this->vo_driver.gui_data_exchange = raw_gui_data_exchange; this->vo_driver.dispose = raw_dispose; this->vo_driver.redraw_needed = raw_redraw_needed; this->yuv2rgb_factory = yuv2rgb_factory_init (MODE_24_BGR, 1, NULL); /* converts to rgb */ if (!this->yuv2rgb_factory) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": yuv2rgb initialization failed\n"); free(this); return NULL; } for (i = 0; i < NUM_FRAMES_BACKLOG; i++) this->frame[i] = 0; for ( i=0; ioverlays[i].ovl_w = this->overlays[i].ovl_h = 2; this->overlays[i].ovl_rgba = (uint8_t*)malloc(2*2*4); this->overlays[i].ovl_x = this->overlays[i].ovl_y = 0; } this->ovl_changed = 0; return &this->vo_driver; } /* * class functions */ static void *raw_init_class (xine_t *xine, const void *visual_gen) { raw_class_t *this; (void)visual_gen; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = raw_open_plugin; this->driver_class.identifier = "raw"; this->driver_class.description = _("xine video output plugin passing raw data to supplied callback"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_raw = { .priority = 7, .visual_type = XINE_VISUAL_TYPE_RAW, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "raw", XINE_VERSION_CODE, &vo_info_raw, raw_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_xcbxv.c0000644000175000017500000015762214647725152017040 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_xcbxv.c, X11 video extension interface for xine * * based on mpeg2dec code from * Aaron Holtzman * * Xv image support by Gerd Knorr * * xine-specific code by Guenter Bartsch * * overlay support by James Courtier-Dutton - July 2001 * X11 unscaled overlay support by Miguel Freitas - Nov 2003 * ported to xcb by Christoph Pfister - Feb 2007 */ #define LOG_MODULE "video_out_xcbxv" #define LOG_VERBOSE /* #define LOG */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #if defined(__FreeBSD__) #include #endif #include #include #include #include #define DEBUG_EMU #include "xine.h" #include #include /* #include "overlay.h" */ #include #include #include "xcbosd.h" #define XV_PROPS #include "xv_common.h" typedef struct xv_driver_s xv_driver_t; typedef struct { int initial_value; int value; int min; int max; xcb_atom_t atom; int defer; const char *name; cfg_entry_t *entry; xv_driver_t *this; } xv_property_t; typedef struct { /* public part */ vo_frame_t vo_frame; /* change detection */ double ratio; int req_width, req_height, format; /* xv image */ int width, height, xvformat; uint8_t *image; xcb_shm_seg_t shmseg; unsigned int xv_format; unsigned int xv_data_size; unsigned int xv_width; unsigned int xv_height; unsigned int xv_pitches[3]; unsigned int xv_offsets[3]; /* yv12 backend for yuy2 emulation */ uint8_t *base[3]; int pitches[3]; } xv_frame_t; struct xv_driver_s { vo_driver_t vo_driver; /* xcb / xv related stuff */ xcb_connection_t *connection; xcb_screen_t *screen; xcb_window_t window; unsigned int xv_format_yv12; unsigned int xv_format_yuy2; xcb_gc_t gc; xcb_xv_port_t xv_port; int use_shm; int use_pitch_alignment; uint32_t capabilities; xv_property_t props[XV_NUM_PROPERTIES]; xv_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; xv_frame_t *cur_frame; xcbosd *xoverlay; int ovl_changed; /* all scaling information goes here */ vo_scale_t sc; xine_t *xine; alphablend_t alphablend_extra_data; pthread_mutex_t main_mutex; int emu_yuy2; /* color matrix switching */ uint8_t cm_lut[32]; int cm_active, cm_state; int fullrange_mode; }; typedef struct { video_driver_class_t driver_class; xine_t *xine; } xv_class_t; /* import common color matrix stuff */ #define CM_LUT #define CM_DRIVER_T xv_driver_t #include "color_matrix.c" VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES VIDEO_DEVICE_XV_DECL_PREFER_TYPES static uint32_t xv_get_capabilities (vo_driver_t *this_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; return this->capabilities; } static void xv_frame_field (vo_frame_t *vo_img, int which_field) { /* not needed for Xv */ (void)vo_img; (void)which_field; } static void xv_rem_yuy2_emu (xv_frame_t *f); static void xv_frame_dispose (vo_frame_t *vo_img) { xv_frame_t *frame = (xv_frame_t *) vo_img ; xv_driver_t *this = (xv_driver_t *) vo_img->driver; xv_rem_yuy2_emu (frame); if (frame->shmseg) { pthread_mutex_lock(&this->main_mutex); xcb_shm_detach(this->connection, frame->shmseg); frame->shmseg = 0; pthread_mutex_unlock(&this->main_mutex); shmdt(frame->image); } else free(frame->image); pthread_mutex_destroy (&frame->vo_frame.mutex); free (frame); } static vo_frame_t *xv_alloc_frame (vo_driver_t *this_gen) { /* xv_driver_t *this = (xv_driver_t *) this_gen; */ xv_frame_t *frame ; frame = (xv_frame_t *) calloc(1, sizeof(xv_frame_t)); if (!frame) return NULL; frame->req_width = 0; frame->req_height = 0; frame->format = 0; frame->width = 0; frame->height = 0; frame->xvformat = 0; frame->image = NULL; frame->base[0] = NULL; frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions */ frame->vo_frame.field = xv_frame_field; frame->vo_frame.dispose = xv_frame_dispose; frame->vo_frame.driver = this_gen; return &frame->vo_frame; } static void create_ximage(xv_driver_t *this, xv_frame_t *frame, int width, int height, int format) { xcb_xv_query_image_attributes_cookie_t query_attributes_cookie; xcb_xv_query_image_attributes_reply_t *query_attributes_reply; unsigned int length; if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } switch (format) { case XINE_IMGFMT_YV12: frame->xv_format = this->xv_format_yv12; break; case XINE_IMGFMT_YUY2: frame->xv_format = this->xv_format_yuy2; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); return; } if (frame->xv_format == 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unsupported format %08x\n", format); return; } query_attributes_cookie = xcb_xv_query_image_attributes(this->connection, this->xv_port, frame->xv_format, width, height); query_attributes_reply = xcb_xv_query_image_attributes_reply(this->connection, query_attributes_cookie, NULL); if (query_attributes_reply == NULL) return; frame->xv_data_size = query_attributes_reply->data_size; frame->xv_width = query_attributes_reply->width; frame->xv_height = query_attributes_reply->height; length = xcb_xv_query_image_attributes_pitches_length(query_attributes_reply); if (length > 3) length = 3; memcpy(frame->xv_pitches, xcb_xv_query_image_attributes_pitches(query_attributes_reply), length * sizeof(frame->xv_pitches[0])); length = xcb_xv_query_image_attributes_offsets_length(query_attributes_reply); if (length > 3) length = 3; memcpy(frame->xv_offsets, xcb_xv_query_image_attributes_offsets(query_attributes_reply), length * sizeof(frame->xv_offsets[0])); free(query_attributes_reply); if (this->use_shm) { int shmid; xcb_void_cookie_t shm_attach_cookie; xcb_generic_error_t *generic_error; /* * try shm */ if (frame->xv_data_size == 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: XvShmCreateImage returned a zero size\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); goto shm_fail1; } shmid = shmget(IPC_PRIVATE, frame->xv_data_size, IPC_CREAT | 0777); if (shmid < 0 ) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: shared memory error in shmget: %s\n"), LOG_MODULE, strerror(errno)); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); goto shm_fail1; } frame->image = shmat(shmid, 0, 0); if (frame->image == ((void *) -1)) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, _("%s: shared memory error (address error)\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); goto shm_fail2; } frame->shmseg = xcb_generate_id(this->connection); shm_attach_cookie = xcb_shm_attach_checked(this->connection, frame->shmseg, shmid, 0); generic_error = xcb_request_check(this->connection, shm_attach_cookie); if (generic_error != NULL) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: x11 error during shared memory XImage creation\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); free(generic_error); goto shm_fail3; } /* * Now that the Xserver has learned about and attached to the * shared memory segment, delete it. It's actually deleted by * the kernel when all users of that segment have detached from * it. Gives an automatic shared memory cleanup in case we crash. */ shmctl(shmid, IPC_RMID, 0); return; shm_fail3: frame->shmseg = 0; shmdt(frame->image); shm_fail2: shmctl(shmid, IPC_RMID, 0); shm_fail1: this->use_shm = 0; } /* * fall back to plain Xv if necessary */ switch (format) { case XINE_IMGFMT_YV12: frame->image = malloc(width * height * 3/2); break; case XINE_IMGFMT_YUY2: frame->image = malloc(width * height * 2); break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); return; } } static void dispose_ximage(xv_driver_t *this, xv_frame_t *frame) { if (frame->shmseg) { xcb_shm_detach(this->connection, frame->shmseg); frame->shmseg = 0; shmdt(frame->image); } else free(frame->image); frame->image = NULL; } static void xv_slice_yuy2_emu (vo_frame_t *vo_img, uint8_t **src) { xv_frame_t *frame = (xv_frame_t *)vo_img; int y = (src[0] - frame->vo_frame.base[0]) / frame->vo_frame.pitches[0]; int h; if ((y < 0) || (y >= frame->height)) return; if (!vo_img->proc_called) vo_img->proc_called = 1; h = frame->height - y; h = h > 16 ? 16 : h; yuy2_to_yv12 (src[0], frame->vo_frame.pitches[0], frame->base[0] + y * frame->pitches[0], frame->pitches[0], frame->base[1] + (y >> 1) * frame->pitches[1], frame->pitches[1], frame->base[2] + (y >> 1) * frame->pitches[2], frame->pitches[2], frame->width, h); } static int xv_add_yuy2_emu (xv_frame_t *f) { uint8_t *base; int pitch; if (f->base[0]) return 0; pitch = f->xv_pitches[0] * 2; base = xine_malloc_aligned (pitch * f->xv_height); if (!base) return 1; /* save backend */ f->base[0] = f->vo_frame.base[0]; f->base[1] = f->vo_frame.base[1]; f->base[2] = f->vo_frame.base[2]; f->pitches[0] = f->vo_frame.pitches[0]; f->pitches[1] = f->vo_frame.pitches[1]; f->pitches[2] = f->vo_frame.pitches[2]; /* new frontend */ f->vo_frame.base[0] = base; f->vo_frame.base[1] = f->vo_frame.base[2] = NULL; f->vo_frame.pitches[0] = pitch; f->vo_frame.pitches[1] = f->vo_frame.pitches[2] = 0; f->format = XINE_IMGFMT_YUY2; f->vo_frame.proc_slice = xv_slice_yuy2_emu; { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)base; int i; for (i = pitch * f->xv_height / 4; i > 0; i--) *q++ = black.word; } return 0; } static void xv_rem_yuy2_emu (xv_frame_t *f) { if (!f->base[0]) return; xine_free_aligned (f->vo_frame.base[0]); f->vo_frame.base[0] = f->base[0]; f->vo_frame.base[1] = f->base[1]; f->vo_frame.base[2] = f->base[2]; f->vo_frame.pitches[0] = f->pitches[0]; f->vo_frame.pitches[1] = f->pitches[1]; f->vo_frame.pitches[2] = f->pitches[2]; f->base[0] = NULL; f->format = XINE_IMGFMT_YV12; f->vo_frame.proc_slice = NULL; } static void xv_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { xv_driver_t *this = (xv_driver_t *) this_gen; xv_frame_t *frame = (xv_frame_t *) frame_gen; int resize; (void)flags; if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } resize = (frame->req_width != (int)width) || (frame->req_height != (int)height); if (resize || (frame->format != format)) { int fmt = format; if ((fmt == XINE_IMGFMT_YUY2) && (this->emu_yuy2 || !this->xv_format_yuy2)) fmt = XINE_IMGFMT_YV12; if (resize || (frame->xvformat != fmt)) { /* get emulation out of the way first if any */ xv_rem_yuy2_emu (frame); /* (re-) allocate xvimage */ pthread_mutex_lock (&this->main_mutex); if (frame->image) dispose_ximage (this, frame); create_ximage (this, frame, width, height, fmt); pthread_mutex_unlock (&this->main_mutex); if (!frame->image) { frame->vo_frame.base[0] = NULL; frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; frame->req_width = 0; frame->vo_frame.width = 0; return; } frame->xvformat = fmt; /* get params, blackfill */ if (fmt == XINE_IMGFMT_YUY2) { frame->vo_frame.pitches[0] = frame->xv_pitches[0]; frame->vo_frame.base[0] = frame->image + frame->xv_offsets[0]; { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)frame->vo_frame.base[0]; int i; for (i = frame->vo_frame.pitches[0] * frame->xv_height / 4; i > 0; i--) *q++ = black.word; } } else { /* XINE_IMGFMT_YV12 */ frame->vo_frame.pitches[0] = frame->xv_pitches[0]; frame->vo_frame.pitches[1] = frame->xv_pitches[2]; frame->vo_frame.pitches[2] = frame->xv_pitches[1]; frame->vo_frame.base[0] = frame->image + frame->xv_offsets[0]; frame->vo_frame.base[1] = frame->image + frame->xv_offsets[2]; frame->vo_frame.base[2] = frame->image + frame->xv_offsets[1]; memset (frame->vo_frame.base[0], 0, frame->vo_frame.pitches[0] * frame->xv_height); memset (frame->vo_frame.base[1], 128, frame->vo_frame.pitches[1] * (frame->xv_height >> 1)); memset (frame->vo_frame.base[2], 128, frame->vo_frame.pitches[2] * (frame->xv_height >> 1)); } } /* update emulation */ frame->format = format; if (fmt != format) { if (xv_add_yuy2_emu (frame)) { pthread_mutex_lock (&this->main_mutex); dispose_ximage (this, frame); pthread_mutex_unlock (&this->main_mutex); frame->image = NULL; frame->vo_frame.base[0] = NULL; frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; frame->req_width = 0; frame->vo_frame.width = 0; return; } } else xv_rem_yuy2_emu (frame); /* allocated frame size may not match requested size */ frame->req_width = width; frame->req_height = height; frame->width = frame->xv_width; frame->height = frame->xv_height; } if (frame->vo_frame.width > frame->width) frame->vo_frame.width = frame->width; if (frame->vo_frame.height > frame->height) frame->vo_frame.height = frame->height; frame->ratio = ratio; } static void xv_clean_output_area (xv_driver_t *this) { int i; xcb_rectangle_t rects[4]; int rects_count = 0; pthread_mutex_lock(&this->main_mutex); xcb_change_gc(this->connection, this->gc, XCB_GC_FOREGROUND, &this->screen->black_pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { rects[rects_count].x = this->sc.border[i].x; rects[rects_count].y = this->sc.border[i].y; rects[rects_count].width = this->sc.border[i].w; rects[rects_count].height = this->sc.border[i].h; rects_count++; } } if (rects_count > 0) xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); if ((this->props[VO_PROP_COLORKEY].atom != XCB_NONE) || (this->props[VO_PROP_AUTOPAINT_COLORKEY].value == 1)) { uint32_t colorkey = this->props[VO_PROP_COLORKEY].value; xcb_change_gc (this->connection, this->gc, XCB_GC_FOREGROUND, &colorkey); xcb_rectangle_t rectangle = { this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height }; xcb_poly_fill_rectangle(this->connection, this->window, this->gc, 1, &rectangle); } if (this->xoverlay) { xcbosd_resize(this->xoverlay, this->sc.gui_width, this->sc.gui_height); this->ovl_changed = 1; } pthread_mutex_unlock(&this->main_mutex); } /* * convert delivered height/width to ideal width/height * taking into account aspect ratio and zoom factor */ static void xv_compute_ideal_size (xv_driver_t *this) { _x_vo_scale_compute_ideal_size( &this->sc ); } /* * make ideal width/height "fit" into the gui */ static void xv_compute_output_size (xv_driver_t *this) { _x_vo_scale_compute_output_size( &this->sc ); } static void xv_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { xv_driver_t *this = (xv_driver_t *) this_gen; this->ovl_changed += changed; if( this->ovl_changed && this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_clear(this->xoverlay); pthread_mutex_unlock(&this->main_mutex); } this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void xv_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { xv_driver_t *this = (xv_driver_t *) this_gen; (void)vo_img; if( this->ovl_changed && this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_expose(this->xoverlay); pthread_mutex_unlock(&this->main_mutex); } this->ovl_changed = 0; } static void xv_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { xv_driver_t *this = (xv_driver_t *) this_gen; xv_frame_t *frame = (xv_frame_t *) frame_gen; if (overlay->rle) { if( overlay->unscaled ) { if( this->ovl_changed && this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_blend(this->xoverlay, overlay); pthread_mutex_unlock(&this->main_mutex); } } else { if (frame->format == XINE_IMGFMT_YV12) _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } } static void xv_add_recent_frame (xv_driver_t *this, xv_frame_t *frame) { int i; i = VO_NUM_RECENT_FRAMES-1; if( this->recent_frames[i] ) this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); for( ; i ; i-- ) this->recent_frames[i] = this->recent_frames[i-1]; this->recent_frames[0] = frame; } static int xv_flush_recent_frames (xv_driver_t *this) { int i, n = 0; for (i = 0; i < VO_NUM_RECENT_FRAMES; i++) { if (this->recent_frames[i]) { this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; n++; } } return n; } static int xv_redraw_needed (vo_driver_t *this_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; int ret = !this->cm_active; if( this->cur_frame ) { this->sc.delivered_height = this->cur_frame->height; this->sc.delivered_width = this->cur_frame->width; this->sc.delivered_ratio = this->cur_frame->ratio; this->sc.crop_left = this->cur_frame->vo_frame.crop_left; this->sc.crop_right = this->cur_frame->vo_frame.crop_right; this->sc.crop_top = this->cur_frame->vo_frame.crop_top; this->sc.crop_bottom = this->cur_frame->vo_frame.crop_bottom; xv_compute_ideal_size(this); if( _x_vo_scale_redraw_needed( &this->sc ) ) { xv_compute_output_size (this); xv_clean_output_area (this); ret = 1; } } else ret = 1; return ret; } static void xv_new_color (xv_driver_t *this, int cm) { int brig = this->props[VO_PROP_BRIGHTNESS].value; int cont = this->props[VO_PROP_CONTRAST].value; int satu = this->props[VO_PROP_SATURATION].value; int cm2, fr = 0, a, b; xcb_atom_t atom; if (cm & 1) { /* fullrange emulation. Do not report this via get_property (). */ if (this->fullrange_mode == 1) { /* modification routine 1 for TV set style bcs controls 0% - 200% */ satu -= this->props[VO_PROP_SATURATION].min; satu = (satu * (112 * 255) + (127 * 219 / 2)) / (127 * 219); satu += this->props[VO_PROP_SATURATION].min; if (satu > this->props[VO_PROP_SATURATION].max) satu = this->props[VO_PROP_SATURATION].max; cont -= this->props[VO_PROP_CONTRAST].min; cont = (cont * 219 + 127) / 255; a = cont * (this->props[VO_PROP_BRIGHTNESS].max - this->props[VO_PROP_BRIGHTNESS].min); cont += this->props[VO_PROP_CONTRAST].min; b = 256 * (this->props[VO_PROP_CONTRAST].max - this->props[VO_PROP_CONTRAST].min); brig += (16 * a + b / 2) / b; if (brig > this->props[VO_PROP_BRIGHTNESS].max) brig = this->props[VO_PROP_BRIGHTNESS].max; fr = 1; } /* maybe add more routines for non-standard controls later */ } pthread_mutex_lock(&this->main_mutex); atom = this->props[VO_PROP_BRIGHTNESS].atom; if (atom != XCB_NONE) xcb_xv_set_port_attribute (this->connection, this->xv_port, atom, brig); atom = this->props[VO_PROP_CONTRAST].atom; if (atom != XCB_NONE) xcb_xv_set_port_attribute (this->connection, this->xv_port, atom, cont); atom = this->props[VO_PROP_SATURATION].atom; if (atom != XCB_NONE) xcb_xv_set_port_attribute (this->connection, this->xv_port, atom, satu); pthread_mutex_unlock(&this->main_mutex); if (this->props[XV_PROP_ITURBT_709].atom != XCB_NONE) { /* 0 = 601 (SD), 1 = 709 (HD) */ /* so far only binary nvidia drivers support this. why not nuveau? */ cm2 = (0xc00c >> cm) & 1; pthread_mutex_lock(&this->main_mutex); xcb_xv_set_port_attribute (this->connection, this->xv_port, this->props[XV_PROP_ITURBT_709].atom, cm2); pthread_mutex_unlock(&this->main_mutex); this->props[XV_PROP_ITURBT_709].value = cm2; cm2 = cm2 ? 2 : 10; } else if (this->props[XV_PROP_COLORSPACE].atom != XCB_NONE) { /* radeonhd: 0 = size based auto, 1 = 601 (SD), 2 = 709 (HD) */ cm2 = ((0xc00c >> cm) & 1) + 1; pthread_mutex_lock(&this->main_mutex); xcb_xv_set_port_attribute (this->connection, this->xv_port, this->props[XV_PROP_COLORSPACE].atom, cm2); pthread_mutex_unlock(&this->main_mutex); this->props[XV_PROP_COLORSPACE].value = cm2; cm2 = cm2 == 2 ? 2 : 10; } else { cm2 = 10; } cm2 |= fr; xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_xcbxv: %s b %d c %d s %d [%s]\n", fr ? "modified " : "", brig, cont, satu, cm_names[cm2]); this->cm_active = cm; } static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; xv_frame_t *frame = (xv_frame_t *) frame_gen; int cm; /* printf (LOG_MODULE ": xv_display_frame...\n"); */ cm = cm_from_frame (frame_gen); if (cm != this->cm_active) xv_new_color (this, cm); /* * queue frames (deinterlacing) * free old frames */ xv_add_recent_frame (this, frame); /* deinterlacing */ this->cur_frame = frame; /* * let's see if this frame is different in size / aspect * ratio from the previous one */ if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) || (frame->vo_frame.crop_left != this->sc.crop_left) || (frame->vo_frame.crop_right != this->sc.crop_right) || (frame->vo_frame.crop_top != this->sc.crop_top) || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) { lprintf("frame format changed\n"); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } /* * tell gui that we are about to display a frame, * ask for offset and output size */ xv_redraw_needed (this_gen); pthread_mutex_lock(&this->main_mutex); if (this->cur_frame->shmseg) { xcb_xv_shm_put_image(this->connection, this->xv_port, this->window, this->gc, this->cur_frame->shmseg, this->cur_frame->xv_format, 0, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, this->cur_frame->xv_width, this->cur_frame->xv_height, 0); } else { xcb_xv_put_image(this->connection, this->xv_port, this->window, this->gc, this->cur_frame->xv_format, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, this->cur_frame->xv_width, this->cur_frame->xv_height, this->cur_frame->xv_data_size, this->cur_frame->image); } xcb_flush(this->connection); pthread_mutex_unlock(&this->main_mutex); /* printf (LOG_MODULE ": xv_display_frame... done\n"); */ } static int xv_get_property (vo_driver_t *this_gen, int property) { xv_driver_t *this = (xv_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return (0); switch (property) { case VO_PROP_WINDOW_WIDTH: this->props[property].value = this->sc.gui_width; break; case VO_PROP_WINDOW_HEIGHT: this->props[property].value = this->sc.gui_height; break; case VO_PROP_OUTPUT_WIDTH: this->props[property].value = this->sc.output_width; break; case VO_PROP_OUTPUT_HEIGHT: this->props[property].value = this->sc.output_height; break; case VO_PROP_OUTPUT_XOFFSET: this->props[property].value = this->sc.output_xoffset; break; case VO_PROP_OUTPUT_YOFFSET: this->props[property].value = this->sc.output_yoffset; break; } lprintf(LOG_MODULE ": property #%d = %d\n", property, this->props[property].value); return this->props[property].value; } static int xv_set_property (vo_driver_t *this_gen, int property, int value) { xv_driver_t *this = (xv_driver_t *) this_gen; xv_property_t *prop; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; prop = &this->props[property]; if (prop->defer == 1) { /* value is out of bound */ if((value < prop->min) || (value > prop->max)) value = (prop->min + prop->max) >> 1; prop->value = value; this->cm_active = 0; return value; } if (prop->atom != XCB_NONE) { xcb_void_cookie_t set_attribute_cookie; xcb_generic_error_t *error; xcb_xv_get_port_attribute_cookie_t get_attribute_cookie; xcb_xv_get_port_attribute_reply_t *get_attribute_reply; /* value is out of bound */ if((value < prop->min) || (value > prop->max)) value = (prop->min + prop->max) >> 1; pthread_mutex_lock(&this->main_mutex); set_attribute_cookie = xcb_xv_set_port_attribute_checked (this->connection, this->xv_port, prop->atom, value); error = xcb_request_check (this->connection, set_attribute_cookie); if (error) { xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_xcbxv: error %d when setting attribute #%d to %d\n", error->error_code, property, value); free (error); } get_attribute_cookie = xcb_xv_get_port_attribute(this->connection, this->xv_port, prop->atom); get_attribute_reply = xcb_xv_get_port_attribute_reply(this->connection, get_attribute_cookie, NULL); prop->value = get_attribute_reply->value; free(get_attribute_reply); pthread_mutex_unlock(&this->main_mutex); if (prop->entry) prop->entry->num_value = prop->value; return prop->value; } else { switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) value = xv_flush_recent_frames (this); break; case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; prop->value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ASPECT_RATIO(%d)\n", prop->value); this->sc.user_ratio = value; xv_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ break; case VO_PROP_ZOOM_X: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { prop->value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ZOOM_X = %d\n", prop->value); this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; xv_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; case VO_PROP_ZOOM_Y: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { prop->value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ZOOM_Y = %d\n", prop->value); this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; xv_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; } } return value; } static void xv_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { xv_driver_t *this = (xv_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) { *min = *max = 0; return; } *min = this->props[property].min; *max = this->props[property].max; } static int xv_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { xv_driver_t *this = (xv_driver_t *) this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: { /* XExposeEvent * xev = (XExposeEvent *) data; */ if (this->cur_frame) { int i; xcb_rectangle_t rects[4]; int rects_count = 0; pthread_mutex_lock(&this->main_mutex); if (this->cur_frame->shmseg) { xcb_xv_shm_put_image(this->connection, this->xv_port, this->window, this->gc, this->cur_frame->shmseg, this->cur_frame->xv_format, 0, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, this->cur_frame->xv_width, this->cur_frame->xv_height, 0); } else { xcb_xv_put_image(this->connection, this->xv_port, this->window, this->gc, this->cur_frame->xv_format, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, this->cur_frame->xv_width, this->cur_frame->xv_height, this->cur_frame->xv_data_size, this->cur_frame->image); } xcb_change_gc(this->connection, this->gc, XCB_GC_FOREGROUND, &this->screen->black_pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { rects[rects_count].x = this->sc.border[i].x; rects[rects_count].y = this->sc.border[i].y; rects[rects_count].width = this->sc.border[i].w; rects[rects_count].height = this->sc.border[i].h; rects_count++; } } if (rects_count > 0) xcb_poly_fill_rectangle(this->connection, this->window, this->gc, rects_count, rects); if(this->xoverlay) xcbosd_expose(this->xoverlay); xcb_flush(this->connection); pthread_mutex_unlock(&this->main_mutex); } } break; case XINE_GUI_SEND_DRAWABLE_CHANGED: pthread_mutex_lock(&this->main_mutex); this->window = (xcb_window_t) (long) data; xcb_free_gc(this->connection, this->gc); this->gc = xcb_generate_id(this->connection); xcb_create_gc(this->connection, this->gc, this->window, 0, NULL); if(this->xoverlay) xcbosd_drawable_changed(this->xoverlay, this->window); this->ovl_changed = 1; pthread_mutex_unlock(&this->main_mutex); this->sc.force_redraw = 1; break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static xcb_atom_t xv_atom_from_name (xv_driver_t *this, const char *name) { xcb_atom_t ret = XCB_NONE; xcb_intern_atom_cookie_t atom_cookie; xcb_intern_atom_reply_t *atom_reply; xcb_generic_error_t *err = NULL; atom_cookie = xcb_intern_atom (this->connection, 0, strlen (name), name); atom_reply = xcb_intern_atom_reply (this->connection, atom_cookie, &err); free (err); if (atom_reply) { ret = atom_reply->atom; free (atom_reply); } return ret; } static void xv_restore_port_attributes(xv_driver_t *this) { int i; for (i = 0; i < XV_NUM_PROPERTIES; i++) { xv_property_t *prop = &this->props[i]; if (prop->atom == XCB_NONE) continue; if (prop->defer || (prop->value != prop->initial_value)) { pthread_mutex_lock (&this->main_mutex); xcb_xv_set_port_attribute (this->connection, this->xv_port, prop->atom, prop->initial_value); pthread_mutex_unlock (&this->main_mutex); } } pthread_mutex_lock(&this->main_mutex); xcb_flush(this->connection); pthread_mutex_unlock(&this->main_mutex); } static void xv_dispose (vo_driver_t *this_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; int i; /* restore port attributes to their initial values */ xv_restore_port_attributes (this); pthread_mutex_lock(&this->main_mutex); if (this->xv_port) { xcb_xv_ungrab_port(this->connection, this->xv_port, XCB_CURRENT_TIME); } if (this->gc) { xcb_free_gc(this->connection, this->gc); } pthread_mutex_unlock(&this->main_mutex); /* should do nothing as video_out has sent VO_PROP_DISCARD_FRAMES = -1 before */ for( i=0; i < VO_NUM_RECENT_FRAMES; i++ ) { if( this->recent_frames[i] ) this->recent_frames[i]->vo_frame.dispose (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; } if( this->xoverlay ) { pthread_mutex_lock(&this->main_mutex); xcbosd_destroy(this->xoverlay); pthread_mutex_unlock(&this->main_mutex); } pthread_mutex_destroy(&this->main_mutex); _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); cm_close (this); /* cm_close already does this. this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, this, sizeof (*this)); */ free (this); } static void xv_prop_init (xv_driver_t *this, const xv_prop_list_t *l, const xcb_xv_attribute_info_t *attr) { xv_property_t *prop = &this->props[l->index]; xcb_atom_t atom = xv_atom_from_name (this, l->name); if (atom == XCB_NONE) return; prop->atom = atom; prop->name = l->name; this->capabilities |= l->caps; /* * some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing. */ prop->min = attr->min; prop->max = attr->max; if ((prop->min >= 0) && (prop->max < 0)) prop->max = 2147483615; { xcb_xv_get_port_attribute_cookie_t get_attribute_cookie; xcb_xv_get_port_attribute_reply_t *get_attribute_reply; pthread_mutex_lock (&this->main_mutex); get_attribute_cookie = xcb_xv_get_port_attribute (this->connection, this->xv_port, atom); get_attribute_reply = xcb_xv_get_port_attribute_reply (this->connection, get_attribute_cookie, NULL); pthread_mutex_unlock (&this->main_mutex); if (!get_attribute_reply) return; prop->initial_value = prop->value = get_attribute_reply->value; free (get_attribute_reply); } xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": port attribute %s (%d) value is %d\n", l->name, l->index, prop->value); } static void xv_prop_update_int (xv_property_t *prop, int value) { xv_driver_t *this = prop->this; pthread_mutex_lock (&this->main_mutex); xcb_xv_set_port_attribute (this->connection, this->xv_port, prop->atom, value); pthread_mutex_unlock (&this->main_mutex); prop->value = value; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": %s = %d\n", prop->name, value); } static void xv_prop_update (void *prop_gen, xine_cfg_entry_t *entry) { xv_prop_update_int ((xv_property_t *)prop_gen, entry->num_value); } static void xv_prop_conf (xv_driver_t *this, int property, const char *config_name, const char *config_desc, const char *config_help) { config_values_t *config = this->xine->config; xv_property_t *prop = &this->props[property]; cfg_entry_t *entry; /* is this a boolean property ? */ if ((prop->min == 0) && (prop->max == 1)) config->register_bool (config, config_name, prop->value, config_desc, config_help, 20, xv_prop_update, prop); else config->register_range (config, config_name, prop->value, prop->min, prop->max, config_desc, config_help, 20, xv_prop_update, prop); entry = config->lookup_entry (config, config_name); if ((entry->num_value < prop->min) || (entry->num_value > prop->max)) xv_prop_update_int (prop, (prop->min + prop->max) >> 1); prop->entry = entry; xv_set_property (&this->vo_driver, property, entry->num_value); } static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *) this_gen; this->use_pitch_alignment = entry->num_value; } static void xv_fullrange_cb_config (void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *)this_gen; this->fullrange_mode = entry->num_value; if (this->fullrange_mode) this->capabilities |= VO_CAP_FULLRANGE; else this->capabilities &= ~VO_CAP_FULLRANGE; this->cm_active = 0; } #ifdef DEBUG_EMU static void xv_debug_emu_cb_config (void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *)this_gen; this->emu_yuy2 = entry->num_value; } #endif static xcb_xv_port_t xv_open_port (xv_driver_t *this, xcb_xv_port_t port) { { xcb_xv_list_image_formats_cookie_t list_formats_cookie; xcb_xv_list_image_formats_reply_t *list_formats_reply; xcb_xv_image_format_info_iterator_t format_it; xcb_generic_error_t *err = NULL; list_formats_cookie = xcb_xv_list_image_formats (this->connection, port); list_formats_reply = xcb_xv_list_image_formats_reply (this->connection, list_formats_cookie, &err); free (err); if (!list_formats_reply) return 0; this->xv_format_yv12 = 0; this->xv_format_yuy2 = 0; format_it = xcb_xv_list_image_formats_format_iterator (list_formats_reply); for (; format_it.rem; xcb_xv_image_format_info_next (&format_it)) { lprintf ("Xv image format: 0x%x (%4.4s) %s\n", format_it.data->id, (char*)&format_it.data->id, (format_it.data->format == XCB_XV_IMAGE_FORMAT_INFO_FORMAT_PACKED) ? "packed" : "planar"); switch (format_it.data->id) { case XINE_IMGFMT_YV12: this->xv_format_yv12 = format_it.data->id; this->capabilities |= VO_CAP_YV12; xprintf (this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); break; case XINE_IMGFMT_YUY2: this->xv_format_yuy2 = format_it.data->id; this->capabilities |= VO_CAP_YUY2; xprintf (this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); break; default: ; } } xcb_xv_image_format_info_end (format_it); free (list_formats_reply); } /* No yv12: bail out. */ if (!this->xv_format_yv12) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": this adaptor does not support YV12 format.\n"); return 0; } /* No yuy2: just report. Who can deliver yv12 with little effort shall do that. * Otherwise, accept anyway and emulate. */ { xcb_xv_grab_port_cookie_t grab_port_cookie; xcb_xv_grab_port_reply_t *grab_port_reply; grab_port_cookie = xcb_xv_grab_port (this->connection, port, XCB_CURRENT_TIME); grab_port_reply = xcb_xv_grab_port_reply (this->connection, grab_port_cookie, NULL); if (grab_port_reply && (grab_port_reply->result == XCB_GRAB_STATUS_SUCCESS)) { free (grab_port_reply); return port; } free (grab_port_reply); return 0; } } static xcb_xv_adaptor_info_iterator_t * xv_find_adaptor_by_port (int port, xcb_xv_adaptor_info_iterator_t *adaptor_it) { for (; adaptor_it->rem; xcb_xv_adaptor_info_next(adaptor_it)) if (adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK) if (port >= (int)adaptor_it->data->base_id && port < (int)(adaptor_it->data->base_id + adaptor_it->data->num_ports)) return adaptor_it; return NULL; /* shouldn't happen */ } static xcb_xv_port_t xv_autodetect_port(xv_driver_t *this, xcb_xv_adaptor_info_iterator_t *adaptor_it, xcb_xv_port_t base, xv_prefertype prefer_type) { for (; adaptor_it->rem; xcb_xv_adaptor_info_next (adaptor_it)) { if (!(adaptor_it->data->type & XCB_XV_TYPE_IMAGE_MASK)) continue; if (prefer_type != xv_prefer_none) { char *name = xcb_xv_adaptor_info_name (adaptor_it->data); if (!name) continue; if (!strcasestr (name, prefer_substrings[prefer_type])) { xcb_xv_adaptor_info_name_end (adaptor_it->data); continue; } xcb_xv_adaptor_info_name_end (adaptor_it->data); } { int j; for (j = 0; j < adaptor_it->data->num_ports; ++j) { xcb_xv_port_t port = adaptor_it->data->base_id + j; if (port >= base && xv_open_port (this, port)) return port; } } } return 0; } static vo_driver_t *open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { xv_class_t *class = (xv_class_t *) class_gen; config_values_t *config = class->xine->config; xv_driver_t *this; int i; const xcb_visual_t *visual = (const xcb_visual_t *) visual_gen; xcb_xv_port_t xv_port; xv_prefertype prefer_type; char *adaptor_name; const xcb_query_extension_reply_t *query_extension_reply; this = (xv_driver_t *) calloc(1, sizeof(xv_driver_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM /* 0/NULL inits, for optimizing away. */ this->xoverlay = NULL; this->ovl_changed = 0; this->xv_format_yv12 = 0; this->xv_format_yuy2 = 0; this->emu_yuy2 = 0; this->fullrange_mode = 0; for (i = 0; i < XV_NUM_PROPERTIES; i++) { this->props[i].initial_value = 0; this->props[i].value = 0; this->props[i].min = 0; this->props[i].max = 0; this->props[i].defer = 0; this->props[i].name = NULL; this->props[i].entry = NULL; } #endif this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; this->use_shm = 1; this->xine = class->xine; this->connection = visual->connection; this->screen = visual->screen; this->window = visual->window; /* * check for Xvideo support */ query_extension_reply = xcb_get_extension_data(this->connection, &xcb_xv_id); if (!query_extension_reply || !query_extension_reply->present) { xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: Xv extension not present.\n"), LOG_MODULE); free(this); return NULL; } /* * check adaptors, search for one that supports (at least) yuv12 */ { xcb_xv_query_adaptors_cookie_t query_adaptors_cookie; xcb_xv_query_adaptors_reply_t *query_adaptors_reply; xcb_xv_adaptor_info_iterator_t adaptor_it; xcb_generic_error_t *err = NULL; query_adaptors_cookie = xcb_xv_query_adaptors (this->connection, this->window); query_adaptors_reply = xcb_xv_query_adaptors_reply (this->connection, query_adaptors_cookie, &err); if (err) { free (err); err = NULL; } if (!query_adaptors_reply) { xprintf (class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": XvQueryAdaptors failed.\n"); free (this); return NULL; } xv_port = config->register_num (config, "video.device.xv_port", 0, VIDEO_DEVICE_XV_PORT_HELP, 20, NULL, NULL); prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0, (char **)prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP, 10, NULL, NULL); adaptor_it = xcb_xv_query_adaptors_info_iterator (query_adaptors_reply); if (xv_port != 0) { if (!xv_open_port (this, xv_port)) { xprintf (class->xine, XINE_VERBOSITY_NONE, _("%s: could not open Xv port %lu - autodetecting\n"), LOG_MODULE, (unsigned long)xv_port); xv_port = xv_autodetect_port (this, &adaptor_it, xv_port, prefer_type); } else xv_find_adaptor_by_port (xv_port, &adaptor_it); } if (!xv_port) { xcb_xv_adaptor_info_end (adaptor_it); adaptor_it = xcb_xv_query_adaptors_info_iterator (query_adaptors_reply); xv_port = xv_autodetect_port (this, &adaptor_it, 0, prefer_type); } if (!xv_port) { if (prefer_type) xprintf (class->xine, XINE_VERBOSITY_NONE, _("%s: no available ports of type \"%s\", defaulting...\n"), LOG_MODULE, prefer_labels[prefer_type]); xcb_xv_adaptor_info_end (adaptor_it); adaptor_it = xcb_xv_query_adaptors_info_iterator (query_adaptors_reply); xv_port = xv_autodetect_port (this, &adaptor_it, 0, xv_prefer_none); } if (!xv_port) { xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n"), LOG_MODULE); xcb_xv_adaptor_info_end (adaptor_it); free (query_adaptors_reply); free (this); return NULL; } adaptor_name = xcb_xv_adaptor_info_name (adaptor_it.data); adaptor_name = strdup (adaptor_name ? adaptor_name : ""); xcb_xv_adaptor_info_name_end (adaptor_it.data); xcb_xv_adaptor_info_end (adaptor_it); free (query_adaptors_reply); } xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: using Xv port %d from adaptor %s for hardware " "colour space conversion and scaling.\n"), LOG_MODULE, xv_port, adaptor_name); this->xv_port = xv_port; pthread_mutex_init(&this->main_mutex, NULL); _x_alphablend_init(&this->alphablend_extra_data, class->xine); _x_vo_scale_init (&this->sc, 1, 0, config ); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; this->gc = xcb_generate_id(this->connection); xcb_create_gc(this->connection, this->gc, this->window, 0, NULL); this->vo_driver.get_capabilities = xv_get_capabilities; this->vo_driver.alloc_frame = xv_alloc_frame; this->vo_driver.update_frame_format = xv_update_frame_format; this->vo_driver.overlay_begin = xv_overlay_begin; this->vo_driver.overlay_blend = xv_overlay_blend; this->vo_driver.overlay_end = xv_overlay_end; this->vo_driver.display_frame = xv_display_frame; this->vo_driver.get_property = xv_get_property; this->vo_driver.set_property = xv_set_property; this->vo_driver.get_property_min_max = xv_get_property_min_max; this->vo_driver.gui_data_exchange = xv_gui_data_exchange; this->vo_driver.dispose = xv_dispose; this->vo_driver.redraw_needed = xv_redraw_needed; /* * init properties */ for (i = 0; i < XV_NUM_PROPERTIES; i++) { this->props[i].atom = XCB_NONE; this->props[i].this = this; } this->sc.user_ratio = this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; this->props[VO_PROP_ZOOM_X].value = 100; this->props[VO_PROP_ZOOM_Y].value = 100; cm_init (this); /* * check this adaptor's capabilities */ { xcb_xv_query_port_attributes_cookie_t query_attributes_cookie; xcb_xv_query_port_attributes_reply_t *query_attributes_reply; xcb_generic_error_t *err = NULL; query_attributes_cookie = xcb_xv_query_port_attributes (this->connection, xv_port); query_attributes_reply = xcb_xv_query_port_attributes_reply (this->connection, query_attributes_cookie, &err); if (err) { free (err); err = NULL; } if (query_attributes_reply) { xcb_xv_attribute_info_iterator_t attribute_it; attribute_it = xcb_xv_query_port_attributes_attributes_iterator (query_attributes_reply); for (; attribute_it.rem; xcb_xv_attribute_info_next (&attribute_it)) { if ((attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_SETTABLE) && (attribute_it.data->flags & XCB_XV_ATTRIBUTE_FLAG_GETTABLE)) { const char *name = xcb_xv_attribute_info_name (attribute_it.data); const xv_prop_list_t *l = xv_find_prop (name); xcb_xv_attribute_info_name_end (attribute_it.data); if (!l) continue; if ((l->index == VO_PROP_HUE) && (!strncmp (adaptor_name, "NV", 2))) { xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); continue; } xv_prop_init (this, l, attribute_it.data); switch (l->index) { case XV_PROP_ITURBT_709: /* nvidia */ this->cm_active = this->props[XV_PROP_ITURBT_709].value ? 2 : 10; break; case XV_PROP_COLORSPACE: /* radeonhd */ this->cm_active = this->props[XV_PROP_COLORSPACE].value == 2 ? 2 : (this->props[XV_PROP_COLORSPACE].value == 1 ? 10 : 0); break; case VO_PROP_COLORKEY: xv_prop_conf (this, VO_PROP_COLORKEY, "video.device.xv_colorkey", VIDEO_DEVICE_XV_COLORKEY_HELP); break; case VO_PROP_AUTOPAINT_COLORKEY: /* disable autopaint colorkey by default, might be overridden using config entry */ this->props[VO_PROP_AUTOPAINT_COLORKEY].value = 0; xv_prop_conf (this, VO_PROP_AUTOPAINT_COLORKEY, "video.device.xv_autopaint_colorkey", VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); break; case XV_PROP_FILTER: { /* This setting is specific to Permedia 2/3 cards. */ int xv_filter = config->register_range (config, "video.device.xv_filter", 0, attribute_it.data->min, attribute_it.data->max, VIDEO_DEVICE_XV_FILTER_HELP, 20, xv_prop_update, &this->props[XV_PROP_FILTER]); xv_prop_update_int (&this->props[XV_PROP_FILTER], xv_filter); break; } case XV_PROP_DOUBLE_BUFFER: { int xv_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, 20, xv_prop_update, &this->props[XV_PROP_DOUBLE_BUFFER]); xv_prop_update_int (&this->props[XV_PROP_DOUBLE_BUFFER], xv_double_buffer); break; } case XV_PROP_SYNC_TO_VBLANK: { int xv_sync_to_vblank = config->register_bool (config, "video.device.xv_sync_to_vblank", 1, _("enable vblank sync"), _("This option will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts. On nvidia cards one may also " "need to run \"nvidia-settings\" and choose which display device to " "sync to under the XVideo Settings tab"), 20, xv_prop_update, &this->props[XV_PROP_SYNC_TO_VBLANK]); xv_prop_update_int (&this->props[XV_PROP_SYNC_TO_VBLANK], xv_sync_to_vblank); break; } case XV_PROP_BICUBIC: { int xv_bicubic = config->register_enum (config, "video.device.xv_bicubic", 2, (char **)bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP, 20, xv_prop_update, &this->props[XV_PROP_BICUBIC]); xv_prop_update_int (&this->props[XV_PROP_BICUBIC], xv_bicubic); break; } } } } xcb_xv_attribute_info_end (attribute_it); free (query_attributes_reply); } else xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": no port attributes defined.\n"); } free (adaptor_name); adaptor_name = NULL; this->props[VO_PROP_BRIGHTNESS].defer = 1; this->props[VO_PROP_CONTRAST].defer = 1; this->props[VO_PROP_SATURATION].defer = 1; if ((this->props[VO_PROP_BRIGHTNESS].atom != XCB_NONE) && (this->props[VO_PROP_CONTRAST].atom != XCB_NONE)) { static const char * const xv_fullrange_conf_labels[] = {"Off", "Normal", NULL}; this->fullrange_mode = config->register_enum ( config, "video.output.xv_fullrange", 0, (char **)xv_fullrange_conf_labels, _("Fullrange colour emulation"), _("Emulate fullrange colour by modifying brightness/contrast/saturation settings.\n\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n\n"), 10, xv_fullrange_cb_config, this ); if (this->fullrange_mode) this->capabilities |= VO_CAP_FULLRANGE; } #ifdef DEBUG_EMU this->emu_yuy2 = config->register_bool ( config, "video.output.xv_debug_emu", 0, _("Force emulating yuy2"), _("Debug."), 10, xv_debug_emu_cb_config, this ); #endif this->use_pitch_alignment = config->register_bool (config, "video.device.xv_pitch_alignment", 0, VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP, 10, xv_update_xv_pitch_alignment, this); if ((this->props[VO_PROP_COLORKEY].atom != XCB_NONE) && (this->props[VO_PROP_AUTOPAINT_COLORKEY].value != 1)) { this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen, this->window, XCBOSD_COLORKEY); if(this->xoverlay) xcbosd_colorkey (this->xoverlay, this->props[VO_PROP_COLORKEY].value, &this->sc); } else { this->xoverlay = xcbosd_create(this->xine, this->connection, this->screen, this->window, XCBOSD_SHAPED); } if( this->xoverlay ) this->capabilities |= VO_CAP_UNSCALED_OVERLAY; return &this->vo_driver; } /* * class functions */ static void *init_class (xine_t *xine, const void *visual_gen) { xv_class_t *this; (void)visual_gen; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "Xv"; this->driver_class.description = N_("xine video output plugin using the MIT X video extension"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_xv = { .priority = 9, .visual_type = XINE_VISUAL_TYPE_XCB, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "xv", XINE_VERSION_CODE, &vo_info_xv, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/xv_common.h0000644000175000017500000001244614647725152015635 0ustar meme/* * Copyright (C) 2008-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xv_common.h: X11 Xv common bits */ #include #define VIDEO_DEVICE_XV_COLORKEY_HELP \ _("video overlay colour key"), \ _("The colour key is used to tell the graphics card where to " \ "overlay the video image. Try different values, if you "\ "experience windows becoming transparent.") #define VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP \ _("autopaint colour key"), \ _("Make Xv autopaint its colour key.") #define VIDEO_DEVICE_XV_FILTER_HELP \ _("bilinear scaling mode"), \ _("Selects the bilinear scaling mode for Permedia cards. " \ "The individual values are:\n\n" \ "Permedia 2\n" \ "0 - disable bilinear filtering\n" \ "1 - enable bilinear filtering\n\n" \ "Permedia 3\n" \ "0 - disable bilinear filtering\n" \ "1 - horizontal linear filtering\n" \ "2 - enable full bilinear filtering") #define VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP \ _("enable double buffering"), \ _("Double buffering will synchronize the update of the video " \ "image to the repainting of the entire screen (\"vertical " \ "retrace\"). This eliminates flickering and tearing artifacts, " \ "but will use more graphics memory.") #define VIDEO_DEVICE_XV_PORT_HELP \ _("Xv port number"), \ _("Selects the Xv port number to use (0 to autodetect).") #define VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP \ _("pitch alignment workaround"), \ _("Some buggy video drivers need a workaround to function properly.") #define VIDEO_DEVICE_XV_DECL_SYNC_ATOMS \ static const char *const sync_atoms[] = \ { "XV_SYNC_TO_VBLANK", "XV_VSYNC" }; #define VIDEO_DEVICE_XV_DECL_PREFER_TYPES \ typedef enum { \ xv_prefer_none, xv_prefer_overlay, xv_prefer_textured, xv_prefer_blitter, \ } xv_prefertype; \ static const char *const prefer_labels[] = \ { "Any", "Overlay", "Textured Video", "Blitter", NULL }; \ static const char prefer_substrings[][8] = \ { "", "Overlay", "Texture", "Blitter" }; #define VIDEO_DEVICE_XV_PREFER_TYPE_HELP \ _("video display method preference"), \ _("Selects which video output method is preferred. " \ "Detection is done using the reported Xv adaptor names.\n" \ "(Only applies when auto-detecting which Xv port to use.)") #define VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES \ static const char *const bicubic_types[] = { "Off", "On", "Auto", NULL }; #define VIDEO_DEVICE_XV_BICUBIC_HELP \ _("bicubic filtering"), \ _("This option controls bicubic filtering of the video image. " \ "It may be used instead of, or as well as, xine's deinterlacers.") #ifdef XV_PROPS /* port attributes that dont map to a standard vo prop */ typedef enum { XV_PROP_ITURBT_709 = VO_NUM_PROPERTIES, XV_PROP_COLORSPACE, XV_PROP_COLORKEY, XV_PROP_AUTOPAINT_COLORKEY, XV_PROP_FILTER, XV_PROP_DOUBLE_BUFFER, XV_PROP_SYNC_TO_VBLANK, XV_PROP_BICUBIC, XV_NUM_PROPERTIES } xv_prop_enum_t; typedef struct { const char *name; int index; int caps; } xv_prop_list_t; static const xv_prop_list_t xv_props_list[] = { { "XV_AUTOPAINT_COLORKEY", XV_PROP_AUTOPAINT_COLORKEY, VO_CAP_AUTOPAINT_COLORKEY }, { "XV_BICUBIC", XV_PROP_BICUBIC, 0 }, { "XV_BRIGHTNESS", VO_PROP_BRIGHTNESS, VO_CAP_BRIGHTNESS }, { "XV_COLORKEY", XV_PROP_COLORKEY, VO_CAP_COLORKEY }, { "XV_COLORSPACE", XV_PROP_COLORSPACE, VO_CAP_COLOR_MATRIX }, { "XV_CONTRAST", VO_PROP_CONTRAST, VO_CAP_CONTRAST }, { "XV_DOUBLE_BUFFER", XV_PROP_DOUBLE_BUFFER, 0 }, { "XV_FILTER", XV_PROP_FILTER, 0 }, { "XV_GAMMA", VO_PROP_GAMMA, VO_CAP_GAMMA }, { "XV_HUE", VO_PROP_HUE, VO_CAP_HUE }, { "XV_ITURBT_709", XV_PROP_ITURBT_709, VO_CAP_COLOR_MATRIX }, { "XV_SATURATION", VO_PROP_SATURATION, VO_CAP_SATURATION }, { "XV_SYNC_TO_VBLANK", XV_PROP_SYNC_TO_VBLANK, 0 }, { "XV_VSYNC", XV_PROP_SYNC_TO_VBLANK, 0 } }; static const xv_prop_list_t *xv_find_prop (const char *name) { unsigned int b = 0, e = sizeof (xv_props_list) / sizeof (xv_prop_list_t), m = e >> 1; do { int d = strcmp (name, xv_props_list[m].name); if (d == 0) return &xv_props_list[m]; if (d < 0) e = m; else b = m + 1; m = (b + e) >> 1; } while (b != e); return NULL; } #endif /* XV_PROPS */ xine-lib-1.2/src/video_out/video_out_xshm.c0000644000175000017500000012612614647725152016660 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_xshm.c, X11 shared memory extension interface for xine * * based on mpeg2dec code from * Aaron Holtzman * * xine-specific code by Guenter Bartsch * * fullrange/HD color and crop support added by Torsten Jager */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LOG_MODULE "video_out_xshm" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include #include #include "yuv2rgb.h" #include #include #include "x11osd.h" #include "xine_mmx.h" #define LOCK_DISPLAY(this) {if(this->lock_display) this->lock_display(this->user_data); \ else XLockDisplay(this->display);} #define UNLOCK_DISPLAY(this) {if(this->unlock_display) this->unlock_display(this->user_data); \ else XUnlockDisplay(this->display);} typedef struct { vo_frame_t vo_frame; /* frame properties as delivered by the decoder: */ /* obs: for width/height use vo_scale_t struct */ int format; int flags; vo_scale_t sc; XImage *image; XShmSegmentInfo shminfo; yuv2rgb_t *yuv2rgb; /* yuv2rgb converter set up for this frame */ uint8_t *rgb_dst; int state, offs0, offs1; /* crop helpers */ uint8_t *crop_start, *crop_flush, *crop_stop; } xshm_frame_t; /* frame.state */ #define FS_DONE 1 #define FS_LATE 2 #define FS_FLAGS 4 typedef struct { vo_driver_t vo_driver; /* X11 / XShm related stuff */ Display *display; int screen; Drawable drawable; Visual *visual; GC gc; int depth, bpp, bytes_per_pixel, image_byte_order; int use_shm; XColor black; int brightness; int contrast; int saturation; uint8_t *yuv2rgb_cmap; yuv2rgb_factory_t *yuv2rgb_factory; /* color matrix switching */ int cm_active, cm_state; uint8_t cm_lut[32]; vo_scale_t sc; xshm_frame_t *cur_frame; x11osd *xoverlay; int ovl_changed; int (*x11_old_error_handler) (Display *, XErrorEvent *); xine_t *xine; alphablend_t alphablend_extra_data; void (*lock_display) (void *); void (*unlock_display) (void *); void *user_data; } xshm_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } xshm_class_t; /* import common color matrix stuff */ #define CM_LUT #define CM_DRIVER_T xshm_driver_t #include "color_matrix.c" static int gX11Fail; /* * first, some utility functions */ /* called xlocked */ static int HandleXError (Display *display, XErrorEvent *xevent) { char str [1024]; XGetErrorText (display, xevent->error_code, str, 1024); printf (LOG_MODULE ": received X error event: %s\n", str); gX11Fail = 1; return 0; } /* called xlocked */ static void x11_InstallXErrorHandler (xshm_driver_t *this) { this->x11_old_error_handler = XSetErrorHandler (HandleXError); XSync(this->display, False); } static void x11_DeInstallXErrorHandler (xshm_driver_t *this) { XSetErrorHandler (this->x11_old_error_handler); XSync(this->display, False); this->x11_old_error_handler = NULL; } /* * allocate an XImage, try XShm first but fall back to * plain X11 if XShm should fail */ /* called xlocked */ static XImage *create_ximage (xshm_driver_t *this, XShmSegmentInfo *shminfo, int width, int height) { XImage *myimage = NULL; if (this->use_shm) { /* * try shm */ gX11Fail = 0; x11_InstallXErrorHandler (this); myimage = XShmCreateImage(this->display, this->visual, this->depth, ZPixmap, NULL, shminfo, width, height); if (myimage == NULL ) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: shared memory error when allocating image\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } this->bpp = myimage->bits_per_pixel; this->bytes_per_pixel = this->bpp / 8; this->image_byte_order = myimage->byte_order; shminfo->shmid=shmget(IPC_PRIVATE, myimage->bytes_per_line * myimage->height, IPC_CREAT | 0777); if (shminfo->shmid < 0 ) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: %s: allocating image\n"), LOG_MODULE, strerror(errno)); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); if (shminfo->shmaddr == ((char *) -1)) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: shared memory error (address error) when allocating image \n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; this->use_shm = 0; goto finishShmTesting; } shminfo->readOnly = False; myimage->data = shminfo->shmaddr; XShmAttach(this->display, shminfo); XSync(this->display, False); if (gX11Fail) { shmdt (shminfo->shmaddr); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: x11 error during shared memory XImage creation\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; this->use_shm = 0; goto finishShmTesting; } /* * Now that the Xserver has learned about and attached to the * shared memory segment, delete it. It's actually deleted by * the kernel when all users of that segment have detached from * it. Gives an automatic shared memory cleanup in case we crash. */ shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; finishShmTesting: x11_DeInstallXErrorHandler(this); } /* * fall back to plain X11 if necessary */ if (!this->use_shm) { myimage = XCreateImage (this->display, this->visual, this->depth, ZPixmap, 0, NULL, width, height, 8, 0); this->bpp = myimage->bits_per_pixel; this->bytes_per_pixel = this->bpp / 8; this->image_byte_order = myimage->byte_order; myimage->data = calloc (width * height, this->bytes_per_pixel); } return myimage; } /* called xlocked */ static void dispose_ximage (xshm_driver_t *this, XShmSegmentInfo *shminfo, XImage *myimage) { if (this->use_shm) { XShmDetach (this->display, shminfo); XDestroyImage (myimage); shmdt (shminfo->shmaddr); if (shminfo->shmid >= 0) { shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; } } else XDestroyImage (myimage); } /* * and now, the driver functions */ static uint32_t xshm_get_capabilities (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; uint32_t capabilities = VO_CAP_CROP | VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE; if( this->xoverlay ) capabilities |= VO_CAP_UNSCALED_OVERLAY; return capabilities; } static void xshm_compute_ideal_size (xshm_driver_t *this, xshm_frame_t *frame) { (void)this; _x_vo_scale_compute_ideal_size( &frame->sc ); } static void xshm_compute_rgb_size (xshm_driver_t *this, xshm_frame_t *frame) { (void)this; _x_vo_scale_compute_output_size( &frame->sc ); /* avoid problems in yuv2rgb */ if (frame->sc.output_height < 1) frame->sc.output_height = 1; if (frame->sc.output_width < 8) frame->sc.output_width = 8; if (frame->sc.output_width & 1) /* yuv2rgb_mlib needs an even YUV2 width */ frame->sc.output_width++; lprintf("frame source (%d) %d x %d => screen output %d x %d%s\n", frame->vo_frame.id, frame->sc.delivered_width, frame->sc.delivered_height, frame->sc.output_width, frame->sc.output_height, ( frame->sc.delivered_width != frame->sc.output_width || frame->sc.delivered_height != frame->sc.output_height ? ", software scaling" : "" ) ); } static void xshm_frame_field (vo_frame_t *vo_img, int which_field) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; /* xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; */ switch (which_field) { case VO_TOP_FIELD: frame->rgb_dst = (uint8_t *)frame->image->data; break; case VO_BOTTOM_FIELD: frame->rgb_dst = (uint8_t *)frame->image->data + frame->image->bytes_per_line ; break; case VO_BOTH_FIELDS: frame->rgb_dst = (uint8_t *)frame->image->data; break; } frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL); } static void xshm_frame_proc_setup (vo_frame_t *vo_img) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; int changed = 0, i; int width, height, gui_width, gui_height; double gui_pixel_aspect; /* Aargh... libmpeg2 decoder calls frame->proc_slice directly, preferredly while still in mmx mode. This will trash our floating point aspect ratio calculations below. Switching back once per frame should not harm performance too much. */ #ifdef HAVE_MMX emms (); #endif if (!(frame->state & FS_LATE)) { /* adjust cropping to what yuv2rgb can handle */ if (vo_img->format == XINE_IMGFMT_YV12) { vo_img->crop_left &= ~7; vo_img->crop_top &= ~1; } else { vo_img->crop_left &= ~3; } /* check for crop changes */ if ((vo_img->crop_left != frame->sc.crop_left) || (vo_img->crop_top != frame->sc.crop_top) || (vo_img->crop_right != frame->sc.crop_right) || (vo_img->crop_bottom != frame->sc.crop_bottom)) { frame->sc.crop_left = vo_img->crop_left; frame->sc.crop_top = vo_img->crop_top; frame->sc.crop_right = vo_img->crop_right; frame->sc.crop_bottom = vo_img->crop_bottom; changed = 1; } } if (!(frame->state & FS_DONE)) changed = 1; /* just deal with cropped part */ width = frame->sc.delivered_width - frame->sc.crop_left - frame->sc.crop_right; height = frame->sc.delivered_height - frame->sc.crop_top - frame->sc.crop_bottom; if (frame->sc.delivered_ratio == 0.0) { frame->sc.delivered_ratio = height ? (double)width / (double)height : 1.0; changed = 1; } /* ask gui what output size we'll have for this frame */ /* get the gui_pixel_aspect before calling xshm_compute_ideal_size() */ /* note: gui_width and gui_height may be bogus because we may have not yet */ /* updated video_pixel_aspect (see _x_vo_scale_compute_ideal_size). */ frame->sc.dest_size_cb (frame->sc.user_data, width, height, frame->sc.video_pixel_aspect, &gui_width, &gui_height, &gui_pixel_aspect); if (changed || (gui_pixel_aspect != frame->sc.gui_pixel_aspect) || (this->sc.user_ratio != frame->sc.user_ratio)) { frame->sc.gui_pixel_aspect = gui_pixel_aspect; frame->sc.user_ratio = this->sc.user_ratio; xshm_compute_ideal_size (this, frame); /* now we have updated video_aspect_pixel we use the callback */ /* again to obtain the correct gui_width and gui_height values. */ frame->sc.dest_size_cb (frame->sc.user_data, width, height, frame->sc.video_pixel_aspect, &gui_width, &gui_height, &gui_pixel_aspect); changed = 1; } if (changed || (frame->sc.gui_width != gui_width) || (frame->sc.gui_height != gui_height)) { int w = frame->sc.output_width, h = frame->sc.output_height; frame->sc.gui_width = gui_width; frame->sc.gui_height = gui_height; xshm_compute_rgb_size (this, frame); if (!frame->image || (w != frame->sc.output_width) || (h != frame->sc.output_height)) { /* (re)allocate XImage */ LOCK_DISPLAY(this); if (frame->image) dispose_ximage (this, &frame->shminfo, frame->image); frame->image = create_ximage (this, &frame->shminfo, frame->sc.output_width, frame->sc.output_height); UNLOCK_DISPLAY(this); } changed = 1; } if (changed || !(frame->state & FS_FLAGS)) { /* set up colorspace converter */ switch (vo_img->flags & VO_BOTH_FIELDS) { case VO_TOP_FIELD: case VO_BOTTOM_FIELD: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, 2 * frame->vo_frame.pitches[0], 2 * frame->vo_frame.pitches[1], frame->sc.output_width, frame->sc.output_height, frame->image->bytes_per_line * 2); break; case VO_BOTH_FIELDS: frame->yuv2rgb->configure (frame->yuv2rgb, width, height, frame->vo_frame.pitches[0], frame->vo_frame.pitches[1], frame->sc.output_width, frame->sc.output_height, frame->image->bytes_per_line); break; } } frame->state |= FS_FLAGS | FS_DONE; xshm_frame_field (vo_img, vo_img->flags & VO_BOTH_FIELDS); /* cache helpers */ i = frame->sc.crop_top & 15; if (i) i -= 16; if (vo_img->format == XINE_IMGFMT_YV12) { frame->offs0 = i * vo_img->pitches[0] + frame->sc.crop_left; frame->offs1 = (i * vo_img->pitches[1] + frame->sc.crop_left) / 2; } else { frame->offs0 = i * vo_img->pitches[0] + frame->sc.crop_left * 2; } frame->crop_start = vo_img->base[0] + frame->sc.crop_top * vo_img->pitches[0]; frame->crop_flush = frame->crop_stop = vo_img->base[0] + (frame->sc.delivered_height - frame->sc.crop_bottom) * vo_img->pitches[0]; if (i + frame->sc.crop_bottom < 0) frame->crop_flush -= 16 * vo_img->pitches[0]; /* switch color matrix/range */ i = cm_from_frame (vo_img); if (i != this->cm_active) { this->cm_active = i; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->brightness, this->contrast, this->saturation, i); xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_xshm: b %d c %d s %d [%s]\n", this->brightness, this->contrast, this->saturation, cm_names[i]); } } static void xshm_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; uint8_t *src0; /* delayed setup */ if (!vo_img->proc_called) { xshm_frame_proc_setup (vo_img); vo_img->proc_called = 1; } src0 = src[0] + frame->offs0; if ((src0 < frame->crop_start) || (src0 >= frame->crop_stop)) return; lprintf ("copy... (format %d)\n", frame->format); if (frame->format == XINE_IMGFMT_YV12) frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0, src[1] + frame->offs1, src[2] + frame->offs1); else frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0); if (src0 >= frame->crop_flush) { if (vo_img->format == XINE_IMGFMT_YV12) { frame->yuv2rgb->yuv2rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0 + 16 * vo_img->pitches[0], src[1] + frame->offs1 + 8 * vo_img->pitches[1], src[2] + frame->offs1 + 8 * vo_img->pitches[2]); } else { frame->yuv2rgb->yuy22rgb_fun (frame->yuv2rgb, frame->rgb_dst, src0 + 16 * vo_img->pitches[0]); } } lprintf ("copy...done\n"); } static void xshm_frame_dispose (vo_frame_t *vo_img) { xshm_frame_t *frame = (xshm_frame_t *) vo_img ; xshm_driver_t *this = (xshm_driver_t *) vo_img->driver; if (frame->image) { LOCK_DISPLAY(this); dispose_ximage (this, &frame->shminfo, frame->image); UNLOCK_DISPLAY(this); } frame->yuv2rgb->dispose (frame->yuv2rgb); xine_free_aligned (frame->vo_frame.base[0]); xine_free_aligned (frame->vo_frame.base[1]); xine_free_aligned (frame->vo_frame.base[2]); pthread_mutex_destroy (&frame->vo_frame.mutex); free (frame); } static vo_frame_t *xshm_alloc_frame (vo_driver_t *this_gen) { xshm_frame_t *frame; xshm_driver_t *this = (xshm_driver_t *) this_gen; frame = (xshm_frame_t *) calloc(1, sizeof(xshm_frame_t)); if (!frame) return NULL; /* * colorspace converter for this frame */ frame->yuv2rgb = this->yuv2rgb_factory->create_converter (this->yuv2rgb_factory); if (!frame->yuv2rgb) { free(frame); return NULL; } memcpy (&frame->sc, &this->sc, sizeof(vo_scale_t)); pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions/fields */ frame->vo_frame.proc_slice = xshm_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = xshm_frame_field; frame->vo_frame.dispose = xshm_frame_dispose; frame->vo_frame.driver = this_gen; return (vo_frame_t *) frame; } static void xshm_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { xshm_frame_t *frame = (xshm_frame_t *) frame_gen; int j, y_pitch, uv_pitch; (void)this_gen; flags &= VO_BOTH_FIELDS; /* (re)allocate yuv buffers */ if (((int)width != frame->sc.delivered_width) || ((int)height != frame->sc.delivered_height) || (format != frame->format)) { frame->sc.delivered_width = width; frame->sc.delivered_height = height; frame->format = format; xine_freep_aligned (&frame->vo_frame.base[0]); xine_freep_aligned (&frame->vo_frame.base[1]); xine_freep_aligned (&frame->vo_frame.base[2]); /* bottom black pad for certain crop_top > crop_bottom cases */ if (format == XINE_IMGFMT_YV12) { y_pitch = (width + 7) & ~7; frame->vo_frame.pitches[0] = y_pitch; frame->vo_frame.base[0] = xine_malloc_aligned (y_pitch * (height + 16)); uv_pitch = ((width + 15) & ~15) >> 1; frame->vo_frame.pitches[1] = uv_pitch; frame->vo_frame.pitches[2] = uv_pitch; frame->vo_frame.base[1] = xine_malloc_aligned (uv_pitch * ((height + 17) / 2)); frame->vo_frame.base[2] = xine_malloc_aligned (uv_pitch * ((height + 17) / 2)); if (!frame->vo_frame.base[0] || !frame->vo_frame.base[1] || !frame->vo_frame.base[2]) { xine_freep_aligned (&frame->vo_frame.base[0]); xine_freep_aligned (&frame->vo_frame.base[1]); xine_freep_aligned (&frame->vo_frame.base[2]); frame->sc.delivered_width = 0; frame->vo_frame.width = 0; } else { memset (frame->vo_frame.base[0], 0, y_pitch * (height + 16)); memset (frame->vo_frame.base[1], 128, uv_pitch * (height + 16) / 2); memset (frame->vo_frame.base[2], 128, uv_pitch * (height + 16) / 2); } } else { y_pitch = ((width + 3) & ~3) << 1; frame->vo_frame.pitches[0] = y_pitch; frame->vo_frame.base[0] = xine_malloc_aligned (y_pitch * (height + 16)); if (frame->vo_frame.base[0]) { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)frame->vo_frame.base[0]; for (j = y_pitch * (height + 16) / 4; j > 0; j--) *q++ = black.word; } else { frame->sc.delivered_width = 0; frame->vo_frame.width = 0; } } /* defer the rest to xshm_frame_proc_setup () */ frame->state &= ~(FS_DONE | FS_LATE); } if (!isnan (ratio) && (ratio < 1000.0) && (ratio > 0.001) && (ratio != frame->sc.delivered_ratio)) { frame->sc.delivered_ratio = ratio; frame->state &= ~FS_DONE; } if (flags != frame->flags) { frame->flags = flags; frame->state &= ~FS_FLAGS; } } static void xshm_overlay_clut_yuv2rgb(xshm_driver_t *this, vo_overlay_t *overlay, xshm_frame_t *frame) { int i; uint32_t *rgb; (void)this; if (!overlay->rgb_clut) { rgb = overlay->color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->rgb_clut++; } if (!overlay->hili_rgb_clut) { rgb = overlay->hili_color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->hili_rgb_clut++; } } static void xshm_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { xshm_driver_t *this = (xshm_driver_t *) this_gen; this->ovl_changed += changed; if( this->ovl_changed && this->xoverlay ) { LOCK_DISPLAY(this); x11osd_clear(this->xoverlay); UNLOCK_DISPLAY(this); } this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void xshm_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { xshm_driver_t *this = (xshm_driver_t *) this_gen; (void)vo_img; if( this->ovl_changed && this->xoverlay ) { LOCK_DISPLAY(this); x11osd_expose(this->xoverlay); UNLOCK_DISPLAY(this); } this->ovl_changed = 0; } static void xshm_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { xshm_driver_t *this = (xshm_driver_t *) this_gen; xshm_frame_t *frame = (xshm_frame_t *) frame_gen; int width = frame->sc.delivered_width - frame->sc.crop_left - frame->sc.crop_right; int height = frame->sc.delivered_height - frame->sc.crop_top - frame->sc.crop_bottom; /* Alpha Blend here */ if (overlay->rle) { if( overlay->unscaled ) { if( this->ovl_changed && this->xoverlay ) { LOCK_DISPLAY(this); x11osd_blend(this->xoverlay, overlay); UNLOCK_DISPLAY(this); } } else { if (!overlay->rgb_clut || !overlay->hili_rgb_clut) xshm_overlay_clut_yuv2rgb (this, overlay, frame); switch (this->bpp) { case 16: _x_blend_rgb16 ((uint8_t *)frame->image->data, overlay, frame->sc.output_width, frame->sc.output_height, width, height, &this->alphablend_extra_data); break; case 24: _x_blend_rgb24 ((uint8_t *)frame->image->data, overlay, frame->sc.output_width, frame->sc.output_height, width, height, &this->alphablend_extra_data); break; case 32: _x_blend_rgb32 ((uint8_t *)frame->image->data, overlay, frame->sc.output_width, frame->sc.output_height, width, height, &this->alphablend_extra_data); break; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "xine-lib:video_out_xshm:xshm_overlay_blend: Cannot blend bpp:%i\n", this->bpp); /* it should never get here, unless a user tries to play in bpp:8 */ break; } } } } static void clean_output_area (xshm_driver_t *this, xshm_frame_t *frame) { int i; memcpy( this->sc.border, frame->sc.border, sizeof(this->sc.border) ); LOCK_DISPLAY(this); XSetForeground (this->display, this->gc, this->black.pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } if (this->xoverlay) { x11osd_resize (this->xoverlay, this->sc.gui_width, this->sc.gui_height); this->ovl_changed = 1; } UNLOCK_DISPLAY(this); } static int xshm_redraw_needed (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; int ret = 0; if( this->cur_frame ) { this->sc.delivered_height = this->cur_frame->sc.delivered_height; this->sc.delivered_width = this->cur_frame->sc.delivered_width; this->sc.video_pixel_aspect = this->cur_frame->sc.video_pixel_aspect; this->sc.crop_left = this->cur_frame->sc.crop_left; this->sc.crop_right = this->cur_frame->sc.crop_right; this->sc.crop_top = this->cur_frame->sc.crop_top; this->sc.crop_bottom = this->cur_frame->sc.crop_bottom; if( _x_vo_scale_redraw_needed( &this->sc ) ) { clean_output_area (this, this->cur_frame); ret = 1; } } else ret = 1; return ret; } static void xshm_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; xshm_frame_t *frame = (xshm_frame_t *) frame_gen; lprintf ("display frame...\n"); lprintf ("about to draw frame (%d) %d x %d...\n", frame->vo_frame.id, frame->sc.output_width, frame->sc.output_height); /* * tell gui that we are about to display a frame, * ask for offset */ this->sc.delivered_height = frame->sc.delivered_height; this->sc.delivered_width = frame->sc.delivered_width; this->sc.video_pixel_aspect = frame->sc.video_pixel_aspect; this->sc.crop_left = frame->sc.crop_left; this->sc.crop_right = frame->sc.crop_right; this->sc.crop_top = frame->sc.crop_top; this->sc.crop_bottom = frame->sc.crop_bottom; if( _x_vo_scale_redraw_needed( &this->sc ) ) { clean_output_area (this, frame); } if (this->cur_frame) { if ( (this->cur_frame->sc.output_width != frame->sc.output_width) || (this->cur_frame->sc.output_height != frame->sc.output_height) || (this->cur_frame->sc.output_xoffset != frame->sc.output_xoffset) || (this->cur_frame->sc.output_yoffset != frame->sc.output_yoffset) ) clean_output_area (this, frame); this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); } this->cur_frame = frame; LOCK_DISPLAY(this); lprintf ("display locked...\n"); if (this->use_shm) { lprintf ("put image (shm)\n"); XShmPutImage(this->display, this->drawable, this->gc, frame->image, 0, 0, frame->sc.output_xoffset, frame->sc.output_yoffset, frame->sc.output_width, frame->sc.output_height, True); } else { lprintf ("put image (plain/remote)\n"); XPutImage(this->display, this->drawable, this->gc, frame->image, 0, 0, frame->sc.output_xoffset, frame->sc.output_yoffset, frame->sc.output_width, frame->sc.output_height); } XSync(this->display, False); UNLOCK_DISPLAY(this); lprintf ("display frame done\n"); /* just in case somebody changes crop this late - take over for next time */ /* adjust cropping to what yuv2rgb can handle */ if (frame_gen->format == XINE_IMGFMT_YV12) { frame_gen->crop_left &= ~7; frame_gen->crop_top &= ~1; } else { frame_gen->crop_left &= ~3; } /* check for crop changes */ if ((frame_gen->crop_left != frame->sc.crop_left) || (frame_gen->crop_top != frame->sc.crop_top) || (frame_gen->crop_right != frame->sc.crop_right) || (frame_gen->crop_bottom != frame->sc.crop_bottom)) { frame->sc.crop_left = frame_gen->crop_left; frame->sc.crop_top = frame_gen->crop_top; frame->sc.crop_right = frame_gen->crop_right; frame->sc.crop_bottom = frame_gen->crop_bottom; frame->state &= ~FS_DONE; frame->state |= FS_LATE; } } static int xshm_get_property (vo_driver_t *this_gen, int property) { xshm_driver_t *this = (xshm_driver_t *) this_gen; switch (property) { case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; case VO_PROP_MAX_NUM_FRAMES: return 15; case VO_PROP_BRIGHTNESS: return this->brightness; case VO_PROP_CONTRAST: return this->contrast; case VO_PROP_SATURATION: return this->saturation; case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; case VO_PROP_OUTPUT_WIDTH: return this->cur_frame->sc.output_width; case VO_PROP_OUTPUT_HEIGHT: return this->cur_frame->sc.output_height; case VO_PROP_OUTPUT_XOFFSET: return this->cur_frame->sc.output_xoffset; case VO_PROP_OUTPUT_YOFFSET: return this->cur_frame->sc.output_yoffset; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": tried to get unsupported property %d\n", property); } return 0; } static int xshm_set_property (vo_driver_t *this_gen, int property, int value) { xshm_driver_t *this = (xshm_driver_t *) this_gen; switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) { value = 0; if (this->cur_frame) { this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); this->cur_frame = NULL; value = 1; } } break; case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); break; case VO_PROP_BRIGHTNESS: this->brightness = value; this->cm_active = 0; this->sc.force_redraw = 1; break; case VO_PROP_CONTRAST: this->contrast = value; this->cm_active = 0; this->sc.force_redraw = 1; break; case VO_PROP_SATURATION: this->saturation = value; this->cm_active = 0; this->sc.force_redraw = 1; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": tried to set unsupported property %d\n", property); } return value; } static void xshm_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { /* xshm_driver_t *this = (xshm_driver_t *) this_gen; */ (void)this_gen; if (property == VO_PROP_BRIGHTNESS) { *min = -128; *max = +127; } else if (property == VO_PROP_CONTRAST) { *min = 0; *max = 255; } else if (property == VO_PROP_SATURATION) { *min = 0; *max = 255; } else { *min = 0; *max = 0; } } static int xshm_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { xshm_driver_t *this = (xshm_driver_t *) this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: lprintf ("expose event\n"); if (this->cur_frame) { XExposeEvent * xev = (XExposeEvent *) data; if (xev && xev->count == 0) { int i; LOCK_DISPLAY(this); if (this->use_shm) { XShmPutImage(this->display, this->drawable, this->gc, this->cur_frame->image, 0, 0, this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset, this->cur_frame->sc.output_width, this->cur_frame->sc.output_height, False); } else { XPutImage(this->display, this->drawable, this->gc, this->cur_frame->image, 0, 0, this->cur_frame->sc.output_xoffset, this->cur_frame->sc.output_yoffset, this->cur_frame->sc.output_width, this->cur_frame->sc.output_height); } XSetForeground (this->display, this->gc, this->black.pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } if(this->xoverlay) x11osd_expose(this->xoverlay); XSync(this->display, False); UNLOCK_DISPLAY(this); } } break; case XINE_GUI_SEND_DRAWABLE_CHANGED: this->drawable = (Drawable) data; LOCK_DISPLAY(this); XFreeGC(this->display, this->gc); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); if(this->xoverlay) x11osd_drawable_changed(this->xoverlay, this->drawable); this->ovl_changed = 1; UNLOCK_DISPLAY(this); break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: if (this->cur_frame) { x11_rectangle_t *rect = data; int x1, y1, x2, y2; _x_vo_scale_translate_gui2video(&this->cur_frame->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->cur_frame->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void xshm_dispose (vo_driver_t *this_gen) { xshm_driver_t *this = (xshm_driver_t *) this_gen; if (this->cur_frame) this->cur_frame->vo_frame.dispose (&this->cur_frame->vo_frame); if (this->yuv2rgb_factory) this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); cm_close (this); LOCK_DISPLAY(this); XFreeGC(this->display, this->gc); UNLOCK_DISPLAY(this); if( this->xoverlay ) { LOCK_DISPLAY(this); x11osd_destroy (this->xoverlay); UNLOCK_DISPLAY(this); } _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); free (this); } /* called xlocked */ static int ImlibPaletteLUTGet(xshm_driver_t *this) { unsigned char *retval; Atom type_ret; unsigned long bytes_after, num_ret; int format_ret; long length; Atom to_get; retval = NULL; length = 0x7fffffff; to_get = XInternAtom(this->display, "_IMLIB_COLORMAP", False); XGetWindowProperty(this->display, RootWindow(this->display, this->screen), to_get, 0, length, False, XA_CARDINAL, &type_ret, &format_ret, &num_ret, &bytes_after, &retval); if (retval != 0 && num_ret > 0 && format_ret > 0) { if (format_ret == 8) { unsigned int i; unsigned long j; j = 1 + retval[0]*4; this->yuv2rgb_cmap = malloc(sizeof(uint8_t) * 32 * 32 * 32); for (i = 0; i < 32 * 32 * 32 && j < num_ret; i++) this->yuv2rgb_cmap[i] = retval[1+4*retval[j++]+3]; XFree(retval); return 1; } else XFree(retval); } return 0; } static const char *visual_class_name(Visual *visual) { switch (visual->class) { case StaticGray: return "StaticGray"; case GrayScale: return "GrayScale"; case StaticColor: return "StaticColor"; case PseudoColor: return "PseudoColor"; case TrueColor: return "TrueColor"; case DirectColor: return "DirectColor"; default: return "unknown visual class"; } } /* expects XINE_VISUAL_TYPE_X11_2 with configurable locking */ static vo_driver_t *xshm_open_plugin_2 (video_driver_class_t *class_gen, const void *visual_gen) { xshm_class_t *class = (xshm_class_t *) class_gen; config_values_t *config = class->xine->config; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; xshm_driver_t *this; XWindowAttributes attribs; XImage *myimage; XShmSegmentInfo myshminfo; int mode; int swapped; int cpu_byte_order; XColor dummy; this = (xshm_driver_t *) calloc(1, sizeof(xshm_driver_t)); if (!this) return NULL; _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->display = visual->display; this->screen = visual->screen; /* configurable X11 locking */ this->lock_display = visual->lock_display; this->unlock_display = visual->unlock_display; this->user_data = visual->user_data; _x_vo_scale_init( &this->sc, 0, 0, config ); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.dest_size_cb = visual->dest_size_cb; this->sc.user_data = visual->user_data; this->sc.user_ratio = XINE_VO_ASPECT_AUTO; this->drawable = visual->d; this->cur_frame = NULL; LOCK_DISPLAY(this); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); UNLOCK_DISPLAY(this); this->xoverlay = NULL; this->ovl_changed = 0; this->x11_old_error_handler = NULL; this->xine = class->xine; this->vo_driver.get_capabilities = xshm_get_capabilities; this->vo_driver.alloc_frame = xshm_alloc_frame; this->vo_driver.update_frame_format = xshm_update_frame_format; this->vo_driver.overlay_begin = xshm_overlay_begin; this->vo_driver.overlay_blend = xshm_overlay_blend; this->vo_driver.overlay_end = xshm_overlay_end; this->vo_driver.display_frame = xshm_display_frame; this->vo_driver.get_property = xshm_get_property; this->vo_driver.set_property = xshm_set_property; this->vo_driver.get_property_min_max = xshm_get_property_min_max; this->vo_driver.gui_data_exchange = xshm_gui_data_exchange; this->vo_driver.dispose = xshm_dispose; this->vo_driver.redraw_needed = xshm_redraw_needed; LOCK_DISPLAY(this); XAllocNamedColor (this->display, DefaultColormap (this->display, this->screen), "black", &this->black, &dummy); /* * * depth in X11 terminology land is the number of bits used to * actually represent the colour. * * bpp in X11 land means how many bits in the frame buffer per * pixel. * * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit * color is 24 bit depth, but can be 24 bpp or 32 bpp. */ XGetWindowAttributes(this->display, this->drawable, &attribs); UNLOCK_DISPLAY(this); this->visual = attribs.visual; this->depth = attribs.depth; if (this->depth>16) xprintf(this->xine, XINE_VERBOSITY_LOG, _("\n\nWARNING: current display depth is %d. For better performance\n" "a depth of 16 bpp is recommended!\n\n"), this->depth); /* * check for X shared memory support */ LOCK_DISPLAY(this); if (XShmQueryExtension(this->display)) { this->use_shm = 1; } else { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: MIT shared memory extension not present on display.\n"), LOG_MODULE); this->use_shm = 0; } /* * try to create a shared image * to find out if MIT shm really works * and what bpp it uses */ myimage = create_ximage (this, &myshminfo, 100, 100); dispose_ximage (this, &myshminfo, myimage); UNLOCK_DISPLAY(this); /* * Is the same byte order in use on the X11 client and server? */ cpu_byte_order = htonl(1) == 1 ? MSBFirst : LSBFirst; swapped = cpu_byte_order != this->image_byte_order; xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": video mode depth is %d (%d bpp), %s, %sswapped,\n" LOG_MODULE ": red: %08lx, green: %08lx, blue: %08lx\n", this->depth, this->bpp, visual_class_name(this->visual), swapped ? "" : "not ", this->visual->red_mask, this->visual->green_mask, this->visual->blue_mask); mode = 0; switch (this->visual->class) { case TrueColor: switch (this->depth) { case 24: case 32: if (this->bpp == 32) { if (this->visual->red_mask == 0x00ff0000) mode = MODE_32_RGB; else mode = MODE_32_BGR; } else { if (this->visual->red_mask == 0x00ff0000) mode = MODE_24_RGB; else mode = MODE_24_BGR; } break; case 16: if (this->visual->red_mask == 0xf800) mode = MODE_16_RGB; else mode = MODE_16_BGR; break; case 15: if (this->visual->red_mask == 0x7C00) mode = MODE_15_RGB; else mode = MODE_15_BGR; break; case 8: if (this->visual->red_mask == 0xE0) mode = MODE_8_RGB; /* Solaris x86: RGB332 */ else mode = MODE_8_BGR; /* XFree86: BGR233 */ break; } break; case StaticGray: if (this->depth == 8) mode = MODE_8_GRAY; break; case PseudoColor: case GrayScale: LOCK_DISPLAY(this); if (this->depth <= 8 && ImlibPaletteLUTGet(this)) mode = MODE_PALETTE; UNLOCK_DISPLAY(this); break; } if (!mode) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("%s: your video mode was not recognized, sorry :-(\n"), LOG_MODULE); return NULL; } cm_init (this); this->brightness = 0; this->contrast = 128; this->saturation = 128; this->yuv2rgb_factory = yuv2rgb_factory_init (mode, swapped, this->yuv2rgb_cmap); if (!this->yuv2rgb_factory) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": yuv2rgb initialization failed\n"); xshm_dispose(&this->vo_driver); return NULL; } LOCK_DISPLAY(this); this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_SHAPED); UNLOCK_DISPLAY(this); return &this->vo_driver; } static vo_driver_t *xshm_open_plugin_old (video_driver_class_t *class_gen, const void *visual_gen) { const x11_visual_t *old_visual = (const x11_visual_t *) visual_gen; x11_visual_t visual; /* provides compatibility for XINE_VISUAL_TYPE_X11 */ visual.display = old_visual->display; visual.screen = old_visual->screen; visual.d = old_visual->d; visual.user_data = old_visual->user_data; visual.dest_size_cb = old_visual->dest_size_cb; visual.frame_output_cb = old_visual->frame_output_cb; visual.lock_display = NULL; visual.unlock_display = NULL; return xshm_open_plugin_2(class_gen, (void *)&visual); } /* * class functions */ static void *xshm_init_class (xine_t *xine, const void *visual_gen) { xshm_class_t *this; (void)visual_gen; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = xshm_open_plugin_old; this->driver_class.identifier = "XShm"; this->driver_class.description = N_("xine video output plugin using the MIT X shared memory extension"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static void *xshm_init_class_2 (xine_t *xine, const void *visual_gen) { xshm_class_t *this; this = xshm_init_class (xine, visual_gen); if (this) { this->driver_class.open_plugin = xshm_open_plugin_2; } return this; } static const vo_info_t vo_info_xshm = { .priority = 6, .visual_type = XINE_VISUAL_TYPE_X11, }; /* visual type with configurable X11 locking */ static const vo_info_t vo_info_xshm_2 = { .priority = 6, .visual_type = XINE_VISUAL_TYPE_X11_2, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "xshm", XINE_VERSION_CODE, &vo_info_xshm, xshm_init_class }, { PLUGIN_VIDEO_OUT, 22, "xshm", XINE_VERSION_CODE, &vo_info_xshm_2, xshm_init_class_2 }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_none.c0000644000175000017500000001253314647725152016634 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Was originally part of toxine frontend. * ...but has now been adapted to xine coding style standards ;) * ......what changes, impressive! */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xine.h" #include #include #include #include #include "mem_frame.h" typedef mem_frame_t vo_none_frame_t; typedef struct { vo_driver_t vo_driver; int ratio; } vo_none_driver_t; static uint32_t vo_none_get_capabilities(vo_driver_t *vo_driver) { /* No, we dont crop. Neither do we interpret color matrix or range. */ /* But we also dont ask decoders to convert data just for the trash ;-) */ (void)vo_driver; return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE; } static void vo_none_display_frame(vo_driver_t *vo_driver, vo_frame_t *vo_frame) { /* vo_none_driver_t *driver = (vo_none_driver_t *)vo_driver; */ (void)vo_driver; vo_frame->free(vo_frame); } static int vo_none_get_property(vo_driver_t *vo_driver, int property) { vo_none_driver_t *driver = (vo_none_driver_t *)vo_driver; switch(property) { case VO_PROP_ASPECT_RATIO: return driver->ratio; break; case VO_PROP_CAPS2: return VO_CAP2_NV12; default: break; } return 0; } static int vo_none_set_property(vo_driver_t *vo_driver, int property, int value) { vo_none_driver_t *driver = (vo_none_driver_t *)vo_driver; switch(property) { case VO_PROP_ASPECT_RATIO: if(value >= XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; driver->ratio = value; break; default: break; } return value; } static void vo_none_get_property_min_max(vo_driver_t *vo_driver, int property, int *min, int *max) { (void)vo_driver; (void)property; *min = 0; *max = 0; } static int vo_none_gui_data_exchange(vo_driver_t *vo_driver, int data_type, void *data) { /* vo_none_driver_t *this = (vo_none_driver_t *) vo_driver; */ (void)vo_driver; (void)data; switch (data_type) { case XINE_GUI_SEND_COMPLETION_EVENT: case XINE_GUI_SEND_DRAWABLE_CHANGED: case XINE_GUI_SEND_EXPOSE_EVENT: case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: case XINE_GUI_SEND_VIDEOWIN_VISIBLE: case XINE_GUI_SEND_SELECT_VISUAL: break; } return 0; } static void vo_none_dispose(vo_driver_t *vo_driver) { vo_none_driver_t *this = (vo_none_driver_t *) vo_driver; free(this); } static int vo_none_redraw_needed(vo_driver_t *vo_driver) { (void)vo_driver; return 0; } static vo_driver_t *vo_none_open_plugin(video_driver_class_t *driver_class, const void *visual) { vo_none_driver_t *driver; (void)visual; (void)driver_class; driver = calloc(1, sizeof(vo_none_driver_t)); if (!driver) return NULL; driver->ratio = XINE_VO_ASPECT_AUTO; driver->vo_driver.get_capabilities = vo_none_get_capabilities; driver->vo_driver.alloc_frame = mem_frame_alloc_frame; driver->vo_driver.update_frame_format = mem_frame_update_frame_format; driver->vo_driver.overlay_begin = NULL; driver->vo_driver.overlay_blend = NULL; driver->vo_driver.overlay_end = NULL; driver->vo_driver.display_frame = vo_none_display_frame; driver->vo_driver.get_property = vo_none_get_property; driver->vo_driver.set_property = vo_none_set_property; driver->vo_driver.get_property_min_max = vo_none_get_property_min_max; driver->vo_driver.gui_data_exchange = vo_none_gui_data_exchange; driver->vo_driver.dispose = vo_none_dispose; driver->vo_driver.redraw_needed = vo_none_redraw_needed; return &driver->vo_driver; } /* * Class related functions. */ static void *vo_none_init_class (xine_t *xine, const void *visual) { static const video_driver_class_t driver_class = { .open_plugin = vo_none_open_plugin, .identifier = "none", .description = N_("xine video output plugin which displays nothing"), .dispose = NULL, }; (void)visual; (void)xine; return (void*)&driver_class; } static const vo_info_t vo_info_none = { .priority = 5, .visual_type = XINE_VISUAL_TYPE_NONE, }; #define VO_NONE_CATALOG { PLUGIN_VIDEO_OUT, 22, "none", XINE_VERSION_CODE, &vo_info_none, vo_none_init_class } #ifndef XINE_MAKE_BUILTINS const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ VO_NONE_CATALOG, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif xine-lib-1.2/src/video_out/video_out_vidix.c0000644000175000017500000012174614647725152017027 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_vidix.c * * xine video_out driver to vidix library by Miguel Freitas 30/05/2002 * * based on video_out_xv.c, video_out_syncfb.c and video_out_pgx64.c * * some vidix specific code from mplayer (file vosub_vidix.c) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifdef HAVE_X11 #include #endif #ifdef HAVE_FB #include #include #include #include #endif #include "xine.h" #include "vidixlib.h" #include "fourcc.h" #define LOG_MODULE "video_out_vidix" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #ifdef HAVE_X11 #include "x11osd.h" #endif #define NUM_FRAMES 3 typedef struct vidix_driver_s vidix_driver_t; typedef struct vidix_property_s { int value; int min; int max; cfg_entry_t *entry; vidix_driver_t *this; } vidix_property_t; typedef struct vidix_frame_s { vo_frame_t vo_frame; int width, height, format; double ratio; } vidix_frame_t; struct vidix_driver_s { vo_driver_t vo_driver; config_values_t *config; char *vidix_name; VDL_HANDLE vidix_handler; uint8_t *vidix_mem; vidix_capability_t vidix_cap; vidix_playback_t vidix_play; vidix_grkey_t vidix_grkey; vidix_video_eq_t vidix_eq; vidix_yuv_t dstrides; int vidix_started; int next_frame; int got_frame_data; uint32_t colourkey; int use_doublebuffer; int supports_yv12; pthread_mutex_t mutex; vidix_property_t props[VO_NUM_PROPERTIES]; uint32_t capabilities; int visual_type; /* X11 related stuff */ #ifdef HAVE_X11 Display *display; int screen; Drawable drawable; GC gc; x11osd *xoverlay; int ovl_changed; #endif /* fb related stuff */ int fb_width; int fb_height; int depth; vo_scale_t sc; int delivered_format; xine_t *xine; alphablend_t alphablend_extra_data; }; typedef struct vidix_class_s { video_driver_class_t driver_class; VDL_HANDLE vidix_handler; vidix_capability_t vidix_cap; xine_t *xine; } vidix_class_t; static void free_framedata(vidix_frame_t* frame) { if(frame->vo_frame.base[0]) { free(frame->vo_frame.base[0]); frame->vo_frame.base[0] = NULL; } if(frame->vo_frame.base[1]) { free(frame->vo_frame.base[1]); frame->vo_frame.base[1] = NULL; } if(frame->vo_frame.base[2]) { free(frame->vo_frame.base[2]); frame->vo_frame.base[2] = NULL; } } static void write_frame_YUV420P2(vidix_driver_t* this, vidix_frame_t* frame) { uint8_t* y = frame->vo_frame.base[0] + this->sc.displayed_xoffset + this->sc.displayed_yoffset*frame->vo_frame.pitches[0]; uint8_t* cb = frame->vo_frame.base[1] + this->sc.displayed_xoffset/2 + this->sc.displayed_yoffset*frame->vo_frame.pitches[1]/2; uint8_t* cr = frame->vo_frame.base[2]+this->sc.displayed_xoffset/2 + this->sc.displayed_yoffset*frame->vo_frame.pitches[2]/2; uint8_t* dst8 = (this->vidix_mem + this->vidix_play.offsets[this->next_frame] + this->vidix_play.offset.y); int h, w; for(h = 0; h < this->sc.displayed_height; h++) { xine_fast_memcpy(dst8, y, this->sc.displayed_width); y += frame->vo_frame.pitches[0]; dst8 += this->dstrides.y; } dst8 = (this->vidix_mem + this->vidix_play.offsets[this->next_frame] + this->vidix_play.offset.v); for(h = 0; h < (this->sc.displayed_height / 2); h++) { for(w = 0; w < (this->sc.displayed_height / 2); w++) { dst8[2*w+0] = cb[w]; dst8[2*w+1] = cr[w]; } cb += frame->vo_frame.pitches[2]; cr += frame->vo_frame.pitches[1]; dst8 += this->dstrides.y; } } static void write_frame_sfb(vidix_driver_t* this, vidix_frame_t* frame) { uint8_t *base = this->vidix_mem+this->vidix_play.offsets[this->next_frame]; switch(frame->format) { case XINE_IMGFMT_YUY2: yuy2_to_yuy2( /* src */ frame->vo_frame.base[0]+this->sc.displayed_xoffset*2+ this->sc.displayed_yoffset*frame->vo_frame.pitches[0], frame->vo_frame.pitches[0], /* dst */ base+this->vidix_play.offset.y, this->dstrides.y, /* width x height */ this->sc.displayed_width, this->sc.displayed_height); break; case XINE_IMGFMT_YV12: { uint8_t* y = frame->vo_frame.base[0] + this->sc.displayed_xoffset + this->sc.displayed_yoffset*frame->vo_frame.pitches[0]; uint8_t* cb = frame->vo_frame.base[1] + this->sc.displayed_xoffset/2 + this->sc.displayed_yoffset*frame->vo_frame.pitches[1]/2; uint8_t* cr = frame->vo_frame.base[2] + this->sc.displayed_xoffset/2 + this->sc.displayed_yoffset*frame->vo_frame.pitches[2]/2; if(this->supports_yv12) { if(this->vidix_play.flags & VID_PLAY_INTERLEAVED_UV) write_frame_YUV420P2(this, frame); else yv12_to_yv12( /* Y */ y, frame->vo_frame.pitches[0], base+this->vidix_play.offset.y, this->dstrides.y, /* U */ cr, frame->vo_frame.pitches[2], base+this->vidix_play.offset.u, this->dstrides.u/2, /* V */ cb, frame->vo_frame.pitches[1], base+this->vidix_play.offset.v, this->dstrides.v/2, /* width x height */ this->sc.displayed_width, this->sc.displayed_height); } else yv12_to_yuy2( /* src */ y, frame->vo_frame.pitches[0], cb, frame->vo_frame.pitches[1], cr, frame->vo_frame.pitches[2], /* dst */ base+this->vidix_play.offset.y, this->dstrides.y, /* width x height */ this->sc.displayed_width, this->sc.displayed_height, /* progressive */ frame->vo_frame.progressive_frame); break; } default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: error. (unknown frame format %04x)\n", frame->format); break; } } static void vidix_clean_output_area(vidix_driver_t *this) { if(this->visual_type == XINE_VISUAL_TYPE_X11) { #ifdef HAVE_X11 int i; XLockDisplay(this->display); XSetForeground(this->display, this->gc, BlackPixel(this->display, this->screen)); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } } XSetForeground(this->display, this->gc, this->colourkey); XFillRectangle(this->display, this->drawable, this->gc, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); if (this->xoverlay) { x11osd_resize (this->xoverlay, this->sc.gui_width, this->sc.gui_height); this->ovl_changed = 1; } XFlush(this->display); XUnlockDisplay(this->display); #endif } } static void vidix_update_colourkey(vidix_driver_t *this) { switch(this->depth) { case 15: this->colourkey = ((this->vidix_grkey.ckey.red & 0xF8) << 7) | ((this->vidix_grkey.ckey.green & 0xF8) << 2) | ((this->vidix_grkey.ckey.blue & 0xF8) >> 3); break; case 16: this->colourkey = ((this->vidix_grkey.ckey.red & 0xF8) << 8) | ((this->vidix_grkey.ckey.green & 0xFC) << 3) | ((this->vidix_grkey.ckey.blue & 0xF8) >> 3); break; case 24: case 32: this->colourkey = ((this->vidix_grkey.ckey.red & 0xFF) << 16) | ((this->vidix_grkey.ckey.green & 0xFF) << 8) | ((this->vidix_grkey.ckey.blue & 0xFF)); break; default: break; } vidix_clean_output_area(this); vdlSetGrKeys(this->vidix_handler, &this->vidix_grkey); } static uint32_t vidix_get_capabilities (vo_driver_t *this_gen) { vidix_driver_t *this = (vidix_driver_t *) this_gen; return this->capabilities; } #ifdef HAVE_FB static void vidixfb_frame_output_cb(void *user_data, int video_width, int video_height, double video_pixel_aspect, int *dest_x, int *dest_y, int *dest_width, int *dest_height, double *dest_pixel_aspect, int *win_x, int *win_y) { vidix_driver_t *this = (vidix_driver_t *) user_data; (void)video_width; (void)video_height; (void)video_pixel_aspect; *dest_x = 0; *dest_y = 0; *dest_width = this->fb_width; *dest_height = this->fb_height; *dest_pixel_aspect = 1.0; *win_x = 0; *win_y = 0; } #endif static void vidix_frame_field (vo_frame_t *vo_img, int which_field) { /* not needed for vidix */ (void)vo_img; (void)which_field; } static void vidix_frame_dispose (vo_frame_t *vo_img) { vidix_frame_t *frame = (vidix_frame_t *) vo_img ; free_framedata(frame); free (frame); } static vo_frame_t *vidix_alloc_frame (vo_driver_t *this_gen) { /* vidix_driver_t *this = (vidix_driver_t *) this_gen; */ vidix_frame_t *frame ; (void)this_gen; frame = (vidix_frame_t *) calloc(1, sizeof(vidix_frame_t)); if (!frame) return NULL; pthread_mutex_init (&frame->vo_frame.mutex, NULL); frame->vo_frame.base[0] = NULL; frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; /* * supply required functions */ frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = vidix_frame_field; frame->vo_frame.dispose = vidix_frame_dispose; return (vo_frame_t *) frame; } static void vidix_compute_ideal_size (vidix_driver_t *this) { _x_vo_scale_compute_ideal_size( &this->sc ); } /* * Configure vidix device */ static void vidix_config_playback (vidix_driver_t *this) { uint32_t apitch; int err; unsigned int i; _x_vo_scale_compute_output_size( &this->sc ); /* We require that the displayed xoffset and width are even. * To prevent displaying more than we're supposed to we round the * xoffset up and the width down */ this->sc.displayed_xoffset = (this->sc.displayed_xoffset+1) & ~1; this->sc.displayed_width = this->sc.displayed_width & ~1; /* For yv12 source displayed yoffset and height need to be even too */ if(this->delivered_format == XINE_IMGFMT_YV12) { this->sc.displayed_yoffset = (this->sc.displayed_yoffset+1) & ~1; this->sc.displayed_height = this->sc.displayed_height & ~1; } if( this->vidix_started > 0 ) { lprintf("video_out_vidix: overlay off\n"); vdlPlaybackOff(this->vidix_handler); } memset(&this->vidix_play,0,sizeof(vidix_playback_t)); if(this->delivered_format == XINE_IMGFMT_YV12 && this->supports_yv12) this->vidix_play.fourcc = IMGFMT_YV12; else this->vidix_play.fourcc = IMGFMT_YUY2; this->vidix_play.capability = this->vidix_cap.flags; /* every ;) */ this->vidix_play.blend_factor = 0; /* for now */ this->vidix_play.src.x = 0; this->vidix_play.src.y = 0; this->vidix_play.src.w = this->sc.displayed_width; this->vidix_play.src.h = this->sc.displayed_height; this->vidix_play.dest.x = this->sc.gui_win_x+this->sc.output_xoffset; this->vidix_play.dest.y = this->sc.gui_win_y+this->sc.output_yoffset; this->vidix_play.dest.w = this->sc.output_width; this->vidix_play.dest.h = this->sc.output_height; this->vidix_play.num_frames= this->use_doublebuffer ? NUM_FRAMES : 1; this->vidix_play.src.pitch.y = this->vidix_play.src.pitch.u = this->vidix_play.src.pitch.v = 0; if((err=vdlConfigPlayback(this->vidix_handler,&this->vidix_play))!=0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: Can't configure playback: %s\n",strerror(err)); this->vidix_started = -1; return; } lprintf("video_out_vidix: dga_addr = %p frame_size = %u frames = %u\n", this->vidix_play.dga_addr, this->vidix_play.frame_size, this->vidix_play.num_frames ); lprintf("video_out_vidix: offsets[0..2] = %u %u %u\n", this->vidix_play.offsets[0], this->vidix_play.offsets[1], this->vidix_play.offsets[2] ); lprintf("video_out_vidix: offset.y/u/v = %u/%u/%u\n", this->vidix_play.offset.y, this->vidix_play.offset.u, this->vidix_play.offset.v ); lprintf("video_out_vidix: src.x/y/w/h = %u/%u/%u/%u\n", this->vidix_play.src.x, this->vidix_play.src.y, this->vidix_play.src.w, this->vidix_play.src.h ); lprintf("video_out_vidix: dest.x/y/w/h = %u/%u/%u/%u\n", this->vidix_play.dest.x, this->vidix_play.dest.y, this->vidix_play.dest.w, this->vidix_play.dest.h ); lprintf("video_out_vidix: dest.pitch.y/u/v = %u/%u/%u\n", this->vidix_play.dest.pitch.y, this->vidix_play.dest.pitch.u, this->vidix_play.dest.pitch.v ); this->vidix_mem = this->vidix_play.dga_addr; this->next_frame = 0; /* clear every frame with correct address and frame_size */ for (i = 0; i < this->vidix_play.num_frames; i++) memset(this->vidix_mem + this->vidix_play.offsets[i], 0x80, this->vidix_play.frame_size); switch(this->vidix_play.fourcc) { case IMGFMT_YV12: apitch = this->vidix_play.dest.pitch.y-1; this->dstrides.y = (this->sc.displayed_width + apitch) & ~apitch; apitch = this->vidix_play.dest.pitch.v-1; this->dstrides.v = (this->sc.displayed_width + apitch) & ~apitch; apitch = this->vidix_play.dest.pitch.u-1; this->dstrides.u = (this->sc.displayed_width + apitch) & ~apitch; break; case IMGFMT_YUY2: apitch = this->vidix_play.dest.pitch.y-1; this->dstrides.y = (this->sc.displayed_width*2 + apitch) & ~apitch; break; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: error. (unknown frame format: %04x)\n", this->delivered_format); } lprintf("video_out_vidix: overlay on\n"); vdlPlaybackOn(this->vidix_handler); this->vidix_started = 1; } static void vidix_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { vidix_driver_t *this = (vidix_driver_t *) this_gen; vidix_frame_t *frame = (vidix_frame_t *) frame_gen; (void)flags; if ((frame->width != (int)width) || (frame->height != (int)height) || (frame->format != format)) { /* * (re-) allocate image */ free_framedata(frame); frame->width = width; frame->height = height; frame->format = format; switch(format) { case XINE_IMGFMT_YV12: frame->vo_frame.pitches[0] = 8*((width + 7) / 8); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); frame->vo_frame.base[0] = malloc(frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = malloc(frame->vo_frame.pitches[1] * ((height+1)/2)); frame->vo_frame.base[2] = malloc(frame->vo_frame.pitches[2] * ((height+1)/2)); break; case XINE_IMGFMT_YUY2: frame->vo_frame.pitches[0] = 8*((width + 3) / 4); frame->vo_frame.base[0] = malloc(frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; break; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: error. (unknown frame format: %04x)\n", format); } if((format == XINE_IMGFMT_YV12 && (frame->vo_frame.base[0] == NULL || frame->vo_frame.base[1] == NULL || frame->vo_frame.base[2] == NULL)) || (format == XINE_IMGFMT_YUY2 && frame->vo_frame.base[0] == NULL)) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: error. (framedata allocation failed: out of memory)\n"); free_framedata(frame); } } frame->ratio = ratio; } static void vidix_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { vidix_driver_t *this = (vidix_driver_t *) this_gen; #ifdef HAVE_X11 this->ovl_changed += changed; if( this->ovl_changed && this->xoverlay ) { XLockDisplay (this->display); x11osd_clear(this->xoverlay); XUnlockDisplay (this->display); } #endif this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void vidix_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { #ifdef HAVE_X11 vidix_driver_t *this = (vidix_driver_t *) this_gen; (void)vo_img; if( this->ovl_changed && this->xoverlay ) { XLockDisplay (this->display); x11osd_expose(this->xoverlay); XUnlockDisplay (this->display); } this->ovl_changed = 0; #endif } /* * */ static void vidix_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { vidix_frame_t *frame = (vidix_frame_t *) frame_gen; vidix_driver_t *this = (vidix_driver_t *) this_gen; if (overlay->rle) { if( overlay->unscaled ) { #ifdef HAVE_X11 if( this->ovl_changed && this->xoverlay ) { XLockDisplay (this->display); x11osd_blend(this->xoverlay, overlay); XUnlockDisplay (this->display); } #endif } else { if( frame->format == XINE_IMGFMT_YV12 ) _x_blend_yuv( frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else _x_blend_yuy2( frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } } static int vidix_redraw_needed (vo_driver_t *this_gen) { vidix_driver_t *this = (vidix_driver_t *) this_gen; int ret = 0; if(_x_vo_scale_redraw_needed(&this->sc)) { if(this->got_frame_data) { vidix_config_playback(this); vidix_clean_output_area(this); ret = 1; } } return ret; } static void vidix_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { vidix_driver_t *this = (vidix_driver_t *) this_gen; vidix_frame_t *frame = (vidix_frame_t *) frame_gen; pthread_mutex_lock(&this->mutex); if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) || (frame->format != this->delivered_format ) || (frame->vo_frame.crop_left != this->sc.crop_left) || (frame->vo_frame.crop_right != this->sc.crop_right) || (frame->vo_frame.crop_top != this->sc.crop_top) || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) { lprintf("video_out_vidix: change frame format\n"); this->sc.delivered_width = frame->width; this->sc.delivered_height = frame->height; this->sc.delivered_ratio = frame->ratio; this->delivered_format = frame->format; this->sc.crop_left = frame->vo_frame.crop_left; this->sc.crop_right = frame->vo_frame.crop_right; this->sc.crop_top = frame->vo_frame.crop_top; this->sc.crop_bottom = frame->vo_frame.crop_bottom; vidix_compute_ideal_size( this ); this->sc.force_redraw = 1; } /* * check if we have to reconfigure vidix because of * format/window position change */ this->got_frame_data = 1; vidix_redraw_needed(this_gen); if(this->vidix_started > 0) { write_frame_sfb(this, frame); if( this->vidix_play.num_frames > 1 ) { vdlPlaybackFrameSelect(this->vidix_handler,this->next_frame); this->next_frame=(this->next_frame+1)%this->vidix_play.num_frames; } } frame->vo_frame.free(frame_gen); pthread_mutex_unlock(&this->mutex); } static int vidix_get_property (vo_driver_t *this_gen, int property) { vidix_driver_t *this = (vidix_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; switch (property) { case VO_PROP_WINDOW_WIDTH: this->props[property].value = this->sc.gui_width; break; case VO_PROP_WINDOW_HEIGHT: this->props[property].value = this->sc.gui_height; break; case VO_PROP_OUTPUT_WIDTH: this->props[property].value = this->sc.output_width; break; case VO_PROP_OUTPUT_HEIGHT: this->props[property].value = this->sc.output_height; break; case VO_PROP_OUTPUT_XOFFSET: this->props[property].value = this->sc.output_xoffset; break; case VO_PROP_OUTPUT_YOFFSET: this->props[property].value = this->sc.output_yoffset; break; } lprintf ("video_out_vidix: property #%d = %d\n", property, this->props[property].value); return this->props[property].value; } static int vidix_set_property (vo_driver_t *this_gen, int property, int value) { vidix_driver_t *this = (vidix_driver_t *) this_gen; int err; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; if ((value >= this->props[property].min) && (value <= this->props[property].max)) { this->props[property].value = value; if ( property == VO_PROP_ASPECT_RATIO) { if(value >= XINE_VO_ASPECT_NUM_RATIOS) value = this->props[property].value = XINE_VO_ASPECT_AUTO; lprintf("video_out_vidix: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); this->sc.user_ratio = value; vidix_compute_ideal_size (this); this->sc.force_redraw = 1; } if ( property == VO_PROP_ZOOM_X ) { this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; vidix_compute_ideal_size (this); this->sc.force_redraw = 1; } if ( property == VO_PROP_ZOOM_Y ) { this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; vidix_compute_ideal_size (this); this->sc.force_redraw = 1; } if ( property == VO_PROP_HUE ) { this->vidix_eq.cap = VEQ_CAP_HUE; this->vidix_eq.hue = value; if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: can't set hue: %s\n", strerror(err)); } if ( property == VO_PROP_SATURATION ) { this->vidix_eq.cap = VEQ_CAP_SATURATION; this->vidix_eq.saturation = value; if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: can't set saturation: %s\n", strerror(err)); } if ( property == VO_PROP_BRIGHTNESS ) { this->vidix_eq.cap = VEQ_CAP_BRIGHTNESS; this->vidix_eq.brightness = value; if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: can't set brightness: %s\n", strerror(err)); } if ( property == VO_PROP_CONTRAST ) { this->vidix_eq.cap = VEQ_CAP_CONTRAST; this->vidix_eq.contrast = value; if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq)) != 0) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: can't set contrast: %s\n", strerror(err)); } } return value; } static void vidix_ckey_callback(vo_driver_t *this_gen, xine_cfg_entry_t *entry) { vidix_driver_t *this = (vidix_driver_t *) this_gen; if(strcmp(entry->key, "video.device.vidix_colour_key_red") == 0) { this->vidix_grkey.ckey.red = entry->num_value; } if(strcmp(entry->key, "video.device.vidix_colour_key_green") == 0) { this->vidix_grkey.ckey.green = entry->num_value; } if(strcmp(entry->key, "video.device.vidix_colour_key_blue") == 0) { this->vidix_grkey.ckey.blue = entry->num_value; } vidix_update_colourkey(this); this->sc.force_redraw = 1; } static void vidix_db_callback(vo_driver_t *this_gen, xine_cfg_entry_t *entry) { vidix_driver_t *this = (vidix_driver_t *) this_gen; this->use_doublebuffer = entry->num_value; this->sc.force_redraw = 1; } static void vidix_rgb_callback(vo_driver_t *this_gen, xine_cfg_entry_t *entry) { int err; vidix_driver_t *this = (vidix_driver_t *) this_gen; this->vidix_eq.cap = VEQ_CAP_RGB_INTENSITY; if(!strcmp(entry->key, "video.output.vidix_red_intensity")) { this->vidix_eq.red_intensity = entry->num_value; } else if(!strcmp(entry->key, "video.output.vidix_green_intensity")) { this->vidix_eq.green_intensity = entry->num_value; } else if(!strcmp(entry->key, "video.output.vidix_blue_intensity")) { this->vidix_eq.blue_intensity = entry->num_value; } if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq))) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: can't set rgb intensity: %s\n", strerror(err)); } static void vidix_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { vidix_driver_t *this = (vidix_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) { *min = *max = 0; return; } *min = this->props[property].min; *max = this->props[property].max; } static int vidix_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { int ret = 0; vidix_driver_t *this = (vidix_driver_t *) this_gen; pthread_mutex_lock(&this->mutex); switch (data_type) { case XINE_GUI_SEND_DRAWABLE_CHANGED: lprintf ("video_out_vidix: GUI_DATA_EX_DRAWABLE_CHANGED\n"); if(this->visual_type == XINE_VISUAL_TYPE_X11) { #ifdef HAVE_X11 this->drawable = (Drawable) data; XLockDisplay(this->display); XFreeGC(this->display, this->gc); this->gc = XCreateGC(this->display, this->drawable, 0, NULL); if(this->xoverlay) x11osd_drawable_changed(this->xoverlay, this->drawable); this->ovl_changed = 1; XUnlockDisplay(this->display); #endif } break; case XINE_GUI_SEND_EXPOSE_EVENT: lprintf ("video_out_vidix: GUI_DATA_EX_EXPOSE_EVENT\n"); vidix_clean_output_area(this); #ifdef HAVE_X11 XLockDisplay (this->display); if(this->xoverlay) x11osd_expose(this->xoverlay); XSync(this->display, False); XUnlockDisplay (this->display); #endif break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: ret = -1; } pthread_mutex_unlock(&this->mutex); return ret; } static void vidix_exit (vo_driver_t *this_gen) { vidix_driver_t *this = (vidix_driver_t *) this_gen; if( this->vidix_started > 0 ) { vdlPlaybackOff(this->vidix_handler); } vdlClose(this->vidix_handler); #ifdef HAVE_X11 XLockDisplay (this->display); XFreeGC(this->display, this->gc); if( this->xoverlay ) x11osd_destroy (this->xoverlay); XUnlockDisplay (this->display); #endif _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->config); free (this); } static vidix_driver_t *open_plugin (video_driver_class_t *class_gen) { vidix_class_t *class = (vidix_class_t *) class_gen; config_values_t *config = class->xine->config; vidix_driver_t *this; int err; this = (vidix_driver_t *) calloc(1, sizeof(vidix_driver_t)); if (!this) return NULL; _x_alphablend_init(&this->alphablend_extra_data, class->xine); pthread_mutex_init (&this->mutex, NULL); this->vidix_handler = class->vidix_handler; this->vidix_cap = class->vidix_cap; _x_vo_scale_init( &this->sc, 1, /*this->vidix_cap.flags & FLAG_UPSCALER,*/ 0, config ); this->xine = class->xine; this->config = config; this->got_frame_data = 0; this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; /* Find what equalizer flags are supported */ if(this->vidix_cap.flags & FLAG_EQUALIZER) { if((err = vdlPlaybackGetEq(this->vidix_handler, &this->vidix_eq)) != 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: couldn't get equalizer capabilities: %s\n", strerror(err)); } else { if(this->vidix_eq.cap & VEQ_CAP_BRIGHTNESS) { this->capabilities |= VO_CAP_BRIGHTNESS; this->props[VO_PROP_BRIGHTNESS].value = 0; this->props[VO_PROP_BRIGHTNESS].min = -1000; this->props[VO_PROP_BRIGHTNESS].max = 1000; } if(this->vidix_eq.cap & VEQ_CAP_CONTRAST) { this->capabilities |= VO_CAP_CONTRAST; this->props[VO_PROP_CONTRAST].value = 0; this->props[VO_PROP_CONTRAST].min = -1000; this->props[VO_PROP_CONTRAST].max = 1000; } if(this->vidix_eq.cap & VEQ_CAP_SATURATION) { this->capabilities |= VO_CAP_SATURATION; this->props[VO_PROP_SATURATION].value = 0; this->props[VO_PROP_SATURATION].min = -1000; this->props[VO_PROP_SATURATION].max = 1000; } if(this->vidix_eq.cap & VEQ_CAP_HUE) { this->capabilities |= VO_CAP_HUE; this->props[VO_PROP_HUE].value = 0; this->props[VO_PROP_HUE].min = -1000; this->props[VO_PROP_HUE].max = 1000; } if(this->vidix_eq.cap & VEQ_CAP_RGB_INTENSITY) { this->vidix_eq.red_intensity = config->register_range(config, "video.output.vidix_red_intensity", 0, -1000, 1000, _("red intensity"), _("The intensity of the red colour components."), 10, (void*) vidix_rgb_callback, this); this->vidix_eq.green_intensity = config->register_range(config, "video.output.vidix_green_intensity", 0, -1000, 1000, _("green intensity"), _("The intensity of the green colour components."), 10, (void*) vidix_rgb_callback, this); this->vidix_eq.blue_intensity = config->register_range(config, "video.output.vidix_blue_intensity", 0, -1000, 1000, _("blue intensity"), _("The intensity of the blue colour components."), 10, (void*) vidix_rgb_callback, this); if((err = vdlPlaybackSetEq(this->vidix_handler, &this->vidix_eq))) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: can't set rgb intensity: %s\n", strerror(err)); } } } /* Configuration for double buffering */ this->use_doublebuffer = config->register_bool(config, "video.device.vidix_double_buffer", 1, _("enable double buffering"), _("Double buffering will synchronize the update of the video image to the repainting of the entire " "screen (\"vertical retrace\"). This eliminates flickering and tearing artifacts, but will use " "more graphics memory."), 20, (void*) vidix_db_callback, this); /* Set up remaining props */ this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; this->props[VO_PROP_ASPECT_RATIO].min = 0; this->props[VO_PROP_ASPECT_RATIO].max = XINE_VO_ASPECT_NUM_RATIOS; this->props[VO_PROP_ZOOM_X].value = 100; this->props[VO_PROP_ZOOM_X].min = XINE_VO_ZOOM_MIN; this->props[VO_PROP_ZOOM_X].max = XINE_VO_ZOOM_MAX; this->props[VO_PROP_ZOOM_Y].value = 100; this->props[VO_PROP_ZOOM_Y].min = XINE_VO_ZOOM_MIN; this->props[VO_PROP_ZOOM_Y].max = XINE_VO_ZOOM_MAX; this->vo_driver.get_capabilities = vidix_get_capabilities; this->vo_driver.alloc_frame = vidix_alloc_frame; this->vo_driver.update_frame_format = vidix_update_frame_format; this->vo_driver.overlay_begin = vidix_overlay_begin; this->vo_driver.overlay_blend = vidix_overlay_blend; this->vo_driver.overlay_end = vidix_overlay_end; this->vo_driver.display_frame = vidix_display_frame; this->vo_driver.get_property = vidix_get_property; this->vo_driver.set_property = vidix_set_property; this->vo_driver.get_property_min_max = vidix_get_property_min_max; this->vo_driver.gui_data_exchange = vidix_gui_data_exchange; this->vo_driver.dispose = vidix_exit; this->vo_driver.redraw_needed = vidix_redraw_needed; return this; } static void query_fourccs (vidix_driver_t *this) { vidix_fourcc_t vidix_fourcc; int err; /* Detect if YUY2 is supported */ memset(&vidix_fourcc, 0, sizeof(vidix_fourcc_t)); vidix_fourcc.fourcc = IMGFMT_YUY2; vidix_fourcc.depth = this->depth; if((err = vdlQueryFourcc(this->vidix_handler, &vidix_fourcc)) == 0) { this->capabilities |= VO_CAP_YUY2; xprintf(this->xine, XINE_VERBOSITY_LOG, _("video_out_vidix: adaptor supports the yuy2 format\n")); } /* Detect if YV12 is supported - we always support yv12 but we need to know if we have to convert */ this->capabilities |= VO_CAP_YV12; vidix_fourcc.fourcc = IMGFMT_YV12; if((err = vdlQueryFourcc(this->vidix_handler, &vidix_fourcc)) == 0) { this->supports_yv12 = 1; xprintf(this->xine, XINE_VERBOSITY_LOG, _("video_out_vidix: adaptor supports the yv12 format\n")); } else this->supports_yv12 = 0; } static void *init_class (xine_t *xine, const void *visual_gen) { vidix_class_t *this; int err; (void)visual_gen; this = (vidix_class_t *) calloc(1, sizeof(vidix_class_t)); if (!this) return NULL; if(vdlGetVersion() != VIDIX_VERSION) { xprintf(xine, XINE_VERBOSITY_LOG, _("video_out_vidix: You have wrong version of VIDIX library\n")); free(this); return NULL; } this->vidix_handler = vdlOpen((XINE_PLUGINDIR"/vidix/"), NULL, TYPE_OUTPUT, 0); if(this->vidix_handler == NULL) { xprintf(xine, XINE_VERBOSITY_LOG, _("video_out_vidix: Couldn't find working VIDIX driver\n")); free(this); return NULL; } if((err=vdlGetCapability(this->vidix_handler,&this->vidix_cap)) != 0) { xprintf(xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: Couldn't get capability: %s\n",strerror(err)); free(this); return NULL; } xprintf(xine, XINE_VERBOSITY_LOG, _("video_out_vidix: using driver: %s by %s\n"), this->vidix_cap.name, this->vidix_cap.author); this->xine = xine; return this; } #ifdef HAVE_X11 static vo_driver_t *vidix_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { vidix_driver_t *this = open_plugin(class_gen); config_values_t *config = this->config; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; XWindowAttributes window_attributes; (void)visual_gen; this->visual_type = XINE_VISUAL_TYPE_X11; this->display = visual->display; this->screen = visual->screen; this->drawable = visual->d; this->gc = XCreateGC(this->display, this->drawable, 0, NULL); this->xoverlay = NULL; this->ovl_changed = 0; XGetWindowAttributes(this->display, this->drawable, &window_attributes); this->sc.gui_width = window_attributes.width; this->sc.gui_height = window_attributes.height; this->depth = window_attributes.depth; this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; /* We'll assume all drivers support colour keying (which they do at the moment) */ this->vidix_grkey.ckey.op = CKEY_TRUE; /* Colour key components */ this->vidix_grkey.ckey.red = config->register_range(config, "video.device.vidix_colour_key_red", 255, 0, 255, _("video overlay colour key red component"), _("The colour key is used to tell the graphics card where to overlay the video image. " "Try different values, if you experience windows becoming transparent."), 20, (void*) vidix_ckey_callback, this); this->vidix_grkey.ckey.green = config->register_range(config, "video.device.vidix_colour_key_green", 0, 0, 255, _("video overlay colour key green component"), _("The colour key is used to tell the graphics card where to overlay the video image. " "Try different values, if you experience windows becoming transparent."), 20, (void*) vidix_ckey_callback, this); this->vidix_grkey.ckey.blue = config->register_range(config, "video.device.vidix_colour_key_blue", 255, 0, 255, _("video overlay colour key blue component"), _("The colour key is used to tell the graphics card where to overlay the video image. " "Try different values, if you experience windows becoming transparent."), 20, (void*) vidix_ckey_callback, this); vidix_update_colourkey(this); query_fourccs(this); XLockDisplay (this->display); if(this->colourkey) { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_COLORKEY); if(this->xoverlay) x11osd_colorkey(this->xoverlay, this->colourkey, &this->sc); } else { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_SHAPED); } XUnlockDisplay (this->display); if( this->xoverlay ) this->capabilities |= VO_CAP_UNSCALED_OVERLAY; return &this->vo_driver; } static void *vidix_init_class (xine_t *xine, const void *visual_gen) { vidix_class_t *this = init_class (xine, visual_gen); if(this) { this->driver_class.open_plugin = vidix_open_plugin; this->driver_class.identifier = "vidix"; this->driver_class.description = N_("xine video output plugin using libvidix for x11"); this->driver_class.dispose = default_video_driver_class_dispose; } return this; } static const vo_info_t vo_info_vidix = { .priority = 2, .visual_type = XINE_VISUAL_TYPE_X11, }; #endif #ifdef HAVE_FB static vo_driver_t *vidixfb_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { vidix_driver_t *this = open_plugin(class_gen); config_values_t *config = this->config; char *device; int fd; struct fb_var_screeninfo fb_var; (void)visual_gen; this->visual_type = XINE_VISUAL_TYPE_FB; /* Register config option for fb device */ device = config->register_filename(config, "video.device.vidixfb_device", "/dev/fb0", XINE_CONFIG_STRING_IS_DEVICE_NAME, _("framebuffer device name"), _("Specifies the file name for the framebuffer device to be used.\n" "This setting is security critical, because when changed to a different file, xine " "can be used to fill this file with arbitrary content. So you should be careful that " "the value you enter really is a proper framebuffer device."), XINE_CONFIG_SECURITY, NULL, NULL); /* Open fb device for reading */ if((fd = xine_open_cloexec("/dev/fb0", O_RDONLY)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: unable to open frame buffer device \"%s\": %s\n", device, strerror(errno)); return NULL; } /* Read screen info */ if(ioctl(fd, FBIOGET_VSCREENINFO, &fb_var) != 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_vidix: error in ioctl FBIOGET_VSCREENINFO: %s", strerror(errno)); close(fd); return NULL; } /* Store screen bpp and dimensions */ this->depth = fb_var.bits_per_pixel; this->fb_width = fb_var.xres; this->fb_height = fb_var.yres; /* Close device */ close(fd); this->sc.frame_output_cb = vidixfb_frame_output_cb; this->sc.user_data = this; /* Make sure colour keying is turned off */ this->vidix_grkey.ckey.op = CKEY_FALSE; vdlSetGrKeys(this->vidix_handler, &this->vidix_grkey); query_fourccs(this); return &this->vo_driver; } static void *vidixfb_init_class (xine_t *xine, const void *visual_gen) { vidix_class_t *this = init_class (xine, visual_gen); if(this) { this->driver_class.open_plugin = vidixfb_open_plugin; this->driver_class.identifier = "vidixfb"; this->driver_class.description = N_("xine video output plugin using libvidix for linux frame buffer"); this->driver_class.dispose = default_video_driver_class_dispose; } return this; } static const vo_info_t vo_info_vidixfb = { .priority = 2, .visual_type = XINE_VISUAL_TYPE_FB, }; #endif /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ #ifdef HAVE_X11 { PLUGIN_VIDEO_OUT, 22, "vidix", XINE_VERSION_CODE, &vo_info_vidix, vidix_init_class }, #endif #ifdef HAVE_FB { PLUGIN_VIDEO_OUT, 22, "vidixfb", XINE_VERSION_CODE, &vo_info_vidixfb, vidixfb_init_class }, #endif { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_fb.c0000644000175000017500000007642414647725152016275 0ustar meme/* * Copyright (C) 2000-2022 the xine project and Fredrik Noring * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /** * @file * @brief Frame buffer xine driver * * @author Miguel Freitas * * @author Fredrik Noring : * Zero copy buffers and clean up. * * @author Aaron Holtzman : * Based on xine's video_out_xshm.c, based on mpeg2dec code from * * @author Geert Uytterhoeven and Chris Lawrence: * Ideas from ppmtofb - Display P?M graphics on framebuffer devices. * * @note Use this with fbxine. * * @todo VT Switching (configurable) */ #define RECOMMENDED_NUM_BUFFERS 5 #define MAXIMUM_NUM_BUFFERS 25 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LOG_MODULE "video_out_fb" #define LOG_VERBOSE /* #define LOG */ #include "xine.h" #include #include #include "yuv2rgb.h" #include #include typedef struct fb_frame_s { vo_frame_t vo_frame; int format; int flags; vo_scale_t sc; yuv2rgb_t *yuv2rgb; /* yuv2rgb converter for this frame */ uint8_t *rgb_dst; int yuv_stride; int bytes_per_line; uint8_t* video_mem; /* mmapped video memory */ uint8_t* data; int yoffset; } fb_frame_t; typedef struct fb_driver_s { vo_driver_t vo_driver; int fd; int mem_size; uint8_t* video_mem_base; /* mmapped video memory */ int depth, bpp, bytes_per_pixel; int total_num_native_buffers; int used_num_buffers; int yuv2rgb_mode; int yuv2rgb_swap; int yuv2rgb_brightness; int yuv2rgb_contrast; int yuv2rgb_saturation; uint8_t *yuv2rgb_cmap; yuv2rgb_factory_t *yuv2rgb_factory; vo_overlay_t *overlay; /* size / aspect ratio calculations */ vo_scale_t sc; int fb_bytes_per_line; fb_frame_t *cur_frame, *old_frame; struct fb_var_screeninfo fb_var; struct fb_fix_screeninfo fb_fix; int use_zero_copy; xine_t *xine; alphablend_t alphablend_extra_data; } fb_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } fb_class_t; static uint32_t fb_get_capabilities(vo_driver_t *this_gen) { (void)this_gen; return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION; } static void fb_frame_proc_slice(vo_frame_t *vo_img, uint8_t **src) { fb_frame_t *frame = xine_container_of(vo_img, fb_frame_t, vo_frame); vo_img->proc_called = 1; if( frame->vo_frame.crop_left || frame->vo_frame.crop_top || frame->vo_frame.crop_right || frame->vo_frame.crop_bottom ) { /* we don't support crop, so don't even waste cpu cycles. * cropping will be performed by video_out.c */ return; } if(frame->format == XINE_IMGFMT_YV12) frame->yuv2rgb->yuv2rgb_fun(frame->yuv2rgb, frame->rgb_dst, src[0], src[1], src[2]); else frame->yuv2rgb->yuy22rgb_fun(frame->yuv2rgb, frame->rgb_dst, src[0]); } static void fb_frame_field(vo_frame_t *vo_img, int which_field) { fb_frame_t *frame = xine_container_of(vo_img, fb_frame_t, vo_frame); switch(which_field) { case VO_TOP_FIELD: frame->rgb_dst = frame->data; break; case VO_BOTTOM_FIELD: frame->rgb_dst = frame->data + frame->bytes_per_line ; break; case VO_BOTH_FIELDS: frame->rgb_dst = frame->data; break; } frame->yuv2rgb->next_slice (frame->yuv2rgb, NULL); } static void fb_frame_dispose(vo_frame_t *vo_img) { fb_frame_t *frame = xine_container_of(vo_img, fb_frame_t, vo_frame); fb_driver_t *this = xine_container_of(vo_img->driver, fb_driver_t, vo_driver); frame->yuv2rgb->dispose (frame->yuv2rgb); if(!this->use_zero_copy) free(frame->data); free(frame); } static vo_frame_t *fb_alloc_frame(vo_driver_t *this_gen) { fb_driver_t *this = xine_container_of(this_gen, fb_driver_t, vo_driver); fb_frame_t *frame; if(this->use_zero_copy && this->total_num_native_buffers <= this->used_num_buffers) return 0; frame = calloc(1, sizeof(fb_frame_t)); if(!frame) return NULL; /* colorspace converter for this frame */ frame->yuv2rgb = this->yuv2rgb_factory->create_converter(this->yuv2rgb_factory); if (!frame->yuv2rgb) { free(frame); return NULL; } memcpy(&frame->sc, &this->sc, sizeof(vo_scale_t)); pthread_mutex_init(&frame->vo_frame.mutex, NULL); /* supply required functions */ frame->vo_frame.proc_slice = fb_frame_proc_slice; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = fb_frame_field; frame->vo_frame.dispose = fb_frame_dispose; frame->vo_frame.driver = this_gen; if(this->use_zero_copy) { frame->yoffset = this->used_num_buffers * this->fb_var.yres; frame->video_mem = this->video_mem_base + this->used_num_buffers * this->fb_var.yres * this->fb_bytes_per_line; memset(frame->video_mem, 0, this->fb_var.yres * this->fb_bytes_per_line); } else frame->video_mem = this->video_mem_base; this->used_num_buffers++; return &frame->vo_frame; } static void fb_compute_ideal_size(fb_driver_t *this, fb_frame_t *frame) { (void)this; _x_vo_scale_compute_ideal_size(&frame->sc); } static void fb_compute_rgb_size(fb_driver_t *this, fb_frame_t *frame) { (void)this; _x_vo_scale_compute_output_size(&frame->sc); /* avoid problems in yuv2rgb */ if(frame->sc.output_height < (frame->sc.delivered_height+15) >> 4) frame->sc.output_height = (frame->sc.delivered_height+15) >> 4; if (frame->sc.output_width < 8) frame->sc.output_width = 8; /* yuv2rgb_mlib needs an even YUV2 width */ if (frame->sc.output_width & 1) frame->sc.output_width++; lprintf("frame source %d x %d => screen output %d x %d%s\n", frame->sc.delivered_width, frame->sc.delivered_height, frame->sc.output_width, frame->sc.output_height, (frame->sc.delivered_width != frame->sc.output_width || frame->sc.delivered_height != frame->sc.output_height ? ", software scaling" : "")); } static void setup_colorspace_converter(fb_frame_t *frame, int flags) { switch(flags) { case VO_TOP_FIELD: case VO_BOTTOM_FIELD: frame->yuv2rgb-> configure(frame->yuv2rgb, frame->sc.delivered_width, frame->sc.delivered_height, 2 * frame->vo_frame.pitches[0], 2 * frame->vo_frame.pitches[1], frame->sc.output_width, frame->sc.output_height, frame->bytes_per_line * 2); frame->yuv_stride = frame->bytes_per_line * 2; break; case VO_BOTH_FIELDS: frame->yuv2rgb-> configure(frame->yuv2rgb, frame->sc.delivered_width, frame->sc.delivered_height, frame->vo_frame.pitches[0], frame->vo_frame.pitches[1], frame->sc.output_width, frame->sc.output_height, frame->bytes_per_line); frame->yuv_stride = frame->bytes_per_line; break; } } static void frame_reallocate(fb_driver_t *this, fb_frame_t *frame, uint32_t width, uint32_t height, int format) { xine_freep_aligned(&frame->vo_frame.base[0]); xine_freep_aligned(&frame->vo_frame.base[1]); xine_freep_aligned(&frame->vo_frame.base[2]); if(this->use_zero_copy) { frame->data = frame->video_mem + frame->sc.output_yoffset*this->fb_bytes_per_line+ frame->sc.output_xoffset*this->bytes_per_pixel; } else { free(frame->data); frame->data = calloc(frame->sc.output_width * frame->sc.output_height, this->bytes_per_pixel); } if(format == XINE_IMGFMT_YV12) { frame->vo_frame.pitches[0] = 8*((width + 7) / 8); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = xine_mallocz_aligned(frame->vo_frame.pitches[1] * ((height+1)/2)); frame->vo_frame.base[2] = xine_mallocz_aligned(frame->vo_frame.pitches[2] * ((height+1)/2)); } else { frame->vo_frame.pitches[0] = 8 * ((width + 3) / 4); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); } } static void fb_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { fb_driver_t *this = xine_container_of(this_gen, fb_driver_t, vo_driver); fb_frame_t *frame = xine_container_of(frame_gen, fb_frame_t, vo_frame); flags &= VO_BOTH_FIELDS; /* Find out if we need to adapt this frame. */ if ((int)width != frame->sc.delivered_width || (int)height != frame->sc.delivered_height || ratio != frame->sc.delivered_ratio || flags != frame->flags || format != frame->format || this->sc.user_ratio != frame->sc.user_ratio) { lprintf("frame format (from decoder) has changed => adapt\n"); frame->sc.delivered_width = width; frame->sc.delivered_height = height; frame->sc.delivered_ratio = ratio; frame->flags = flags; frame->format = format; frame->sc.user_ratio = this->sc.user_ratio; fb_compute_ideal_size(this, frame); fb_compute_rgb_size(this, frame); frame_reallocate(this, frame, width, height, format); if(this->use_zero_copy) frame->bytes_per_line = this->fb_bytes_per_line; else frame->bytes_per_line = frame->sc.output_width * this->bytes_per_pixel; setup_colorspace_converter(frame, flags); } fb_frame_field(frame_gen, flags); } static void fb_overlay_clut_yuv2rgb(fb_driver_t *this, vo_overlay_t *overlay, fb_frame_t *frame) { int i; uint32_t *rgb; (void)this; if (!overlay->rgb_clut) { rgb = overlay->color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->rgb_clut++; } if (!overlay->hili_rgb_clut) { rgb = overlay->hili_color; for (i = sizeof (overlay->color) / sizeof (overlay->color[0]); i > 0; i--) { clut_t *yuv = (clut_t *)rgb; *rgb++ = frame->yuv2rgb->yuv2rgb_single_pixel_fun (frame->yuv2rgb, yuv->y, yuv->cb, yuv->cr); } overlay->hili_rgb_clut++; } } static void fb_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { fb_driver_t *this = xine_container_of(this_gen, fb_driver_t, vo_driver); fb_frame_t *frame = xine_container_of(frame_gen, fb_frame_t, vo_frame); this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; /* Alpha Blend here */ if(overlay->rle) { if(!overlay->rgb_clut || !overlay->hili_rgb_clut) fb_overlay_clut_yuv2rgb(this,overlay,frame); switch(this->bpp) { case 16: _x_blend_rgb16(frame->data, overlay, frame->sc.output_width, frame->sc.output_height, frame->sc.delivered_width, frame->sc.delivered_height, &this->alphablend_extra_data); break; case 24: _x_blend_rgb24(frame->data, overlay, frame->sc.output_width, frame->sc.output_height, frame->sc.delivered_width, frame->sc.delivered_height, &this->alphablend_extra_data); break; case 32: _x_blend_rgb32(frame->data, overlay, frame->sc.output_width, frame->sc.output_height, frame->sc.delivered_width, frame->sc.delivered_height, &this->alphablend_extra_data); break; } } } static int fb_redraw_needed(vo_driver_t *this_gen) { (void)this_gen; return 0; } static void fb_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen) { fb_driver_t *this = xine_container_of(this_gen, fb_driver_t, vo_driver); fb_frame_t *frame = xine_container_of(frame_gen, fb_frame_t, vo_frame); uint8_t *dst, *src; int y; if(frame->sc.output_width != this->sc.output_width || frame->sc.output_height != this->sc.output_height) { this->sc.output_width = frame->sc.output_width; this->sc.output_height = frame->sc.output_height; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_fb: gui size %d x %d, frame size %d x %d\n", this->sc.gui_width, this->sc.gui_height, frame->sc.output_width, frame->sc.output_height); memset(this->video_mem_base, 0, this->mem_size); } if (this->sc.frame_output_cb) { this->sc.delivered_height = frame->sc.delivered_height; this->sc.delivered_width = frame->sc.delivered_width; _x_vo_scale_redraw_needed( &this->sc ); } if(this->use_zero_copy) { if(this->old_frame) this->old_frame->vo_frame.free (&this->old_frame->vo_frame); this->old_frame = this->cur_frame; this->cur_frame = frame; this->fb_var.yoffset = frame->yoffset; if(ioctl(this->fd, FBIOPAN_DISPLAY, &this->fb_var) == -1) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_fb: ioctl FBIOPAN_DISPLAY failed: %s\n", strerror(errno)); } else { dst = frame->video_mem + frame->sc.output_yoffset * this->fb_bytes_per_line + frame->sc.output_xoffset * this->bytes_per_pixel; src = frame->data; for(y = 0; y < frame->sc.output_height; y++) { xine_fast_memcpy(dst, src, frame->bytes_per_line); src += frame->bytes_per_line; dst += this->fb_bytes_per_line; } frame->vo_frame.free(&frame->vo_frame); } } static int fb_get_property(vo_driver_t *this_gen, int property) { fb_driver_t *this = xine_container_of(this_gen, fb_driver_t, vo_driver); switch(property) { case VO_PROP_ASPECT_RATIO: return this->sc.user_ratio; case VO_PROP_BRIGHTNESS: return this->yuv2rgb_brightness; case VO_PROP_CONTRAST: return this->yuv2rgb_contrast; case VO_PROP_SATURATION: return this->yuv2rgb_saturation; case VO_PROP_WINDOW_WIDTH: return this->sc.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->sc.gui_height; case VO_PROP_OUTPUT_WIDTH: return this->cur_frame->sc.output_width; case VO_PROP_OUTPUT_HEIGHT: return this->cur_frame->sc.output_height; case VO_PROP_OUTPUT_XOFFSET: return this->cur_frame->sc.output_xoffset; case VO_PROP_OUTPUT_YOFFSET: return this->cur_frame->sc.output_yoffset; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_fb: tried to get unsupported property %d\n", property); } return 0; } static int fb_set_property(vo_driver_t *this_gen, int property, int value) { fb_driver_t *this = xine_container_of(this_gen, fb_driver_t, vo_driver); switch(property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) { int n = 0; if (this->old_frame) { this->old_frame->vo_frame.free (&this->old_frame->vo_frame); this->old_frame = NULL; n++; } if (this->cur_frame) { this->cur_frame->vo_frame.free (&this->cur_frame->vo_frame); this->cur_frame = NULL; n++; } value = n; } break; case VO_PROP_ASPECT_RATIO: if(value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->sc.user_ratio = value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_fb: aspect ratio changed to %s\n", _x_vo_scale_aspect_ratio_name_table[value]); break; case VO_PROP_BRIGHTNESS: this->yuv2rgb_brightness = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation, CM_DEFAULT); break; case VO_PROP_CONTRAST: this->yuv2rgb_contrast = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation, CM_DEFAULT); break; case VO_PROP_SATURATION: this->yuv2rgb_saturation = value; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation, CM_DEFAULT); break; default: xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_fb: tried to set unsupported property %d\n", property); } return value; } static void fb_get_property_min_max(vo_driver_t *this_gen, int property, int *min, int *max) { /* fb_driver_t *this = (fb_driver_t *) this_gen; */ (void)this_gen; switch (property) { case VO_PROP_BRIGHTNESS: *min = -128; *max = +127; break; case VO_PROP_CONTRAST: case VO_PROP_SATURATION: *min = 0; *max = 255; break; default: *min = 0; *max = 0; break; } } static int fb_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *data) { (void)this_gen; (void)data_type; (void)data; return 0; } static void fb_dispose(vo_driver_t *this_gen) { fb_driver_t *this = xine_container_of(this_gen, fb_driver_t, vo_driver); if (this->video_mem_base != MAP_FAILED) munmap(this->video_mem_base, this->mem_size); if (this->fd >= 0) close(this->fd); _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); if (this->yuv2rgb_factory) this->yuv2rgb_factory->dispose (this->yuv2rgb_factory); free(this); } static int get_fb_var_screeninfo(int fd, struct fb_var_screeninfo *var, xine_t *xine) { int i; if(ioctl(fd, FBIOGET_VSCREENINFO, var)) { xprintf(xine, XINE_VERBOSITY_DEBUG, "video_out_fb: ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); return 0; } var->xres_virtual = var->xres; var->xoffset = 0; var->yoffset = 0; var->nonstd = 0; var->vmode &= ~FB_VMODE_YWRAP; /* Maximize virtual yres to fit as many buffers as possible. */ for(i = MAXIMUM_NUM_BUFFERS; i > 0; i--) { var->yres_virtual = i * var->yres; if(ioctl(fd, FBIOPUT_VSCREENINFO, var) == -1) continue; break; } /* Get proper value for maximized var->yres_virtual. */ if(ioctl(fd, FBIOGET_VSCREENINFO, var) == -1) { xprintf(xine, XINE_VERBOSITY_DEBUG, "video_out_fb: ioctl FBIOGET_VSCREENINFO: %s\n", strerror(errno)); return 0; } return 1; } static int get_fb_fix_screeninfo(int fd, struct fb_fix_screeninfo *fix, xine_t *xine) { if(ioctl(fd, FBIOGET_FSCREENINFO, fix)) { xprintf(xine, XINE_VERBOSITY_DEBUG, "video_out_fb: ioctl FBIOGET_FSCREENINFO: %s\n", strerror(errno)); return 0; } if((fix->visual != FB_VISUAL_TRUECOLOR && fix->visual != FB_VISUAL_DIRECTCOLOR) || fix->type != FB_TYPE_PACKED_PIXELS) { xprintf(xine, XINE_VERBOSITY_LOG, _("video_out_fb: only packed truecolour/directcolour is supported (%d).\n" " Check 'fbset -i' or try 'fbset -depth 16'.\n"), fix->visual); return 0; } return 1; } static int set_fb_palette (int fd, const struct fb_var_screeninfo *var) { unsigned short red[256], green[256], blue[256]; const struct fb_cmap fb_cmap = { 0, 256, red, green, blue, NULL }; int i, mask; if (!var->red.offset && !var->green.offset && !var->blue.offset) return 1; /* we only handle true-colour modes */ /* Fill in the palette data */ mask = (1 << var->red.length) - 1; for (i = 0; i < 256; ++i) red[i] = (i & mask) * 65535.0 / mask; mask = (1 << var->green.length) - 1; for (i = 0; i < 256; ++i) green[i] = (i & mask) * 65535.0 / mask; mask = (1 << var->blue.length) - 1; for (i = 0; i < 256; ++i) blue[i] = (i & mask) * 65535.0 / mask; /* Set the palette; return true on success */ return !ioctl (fd, FBIOPUTCMAP, &fb_cmap); } static void register_callbacks(fb_driver_t *this) { this->vo_driver.get_capabilities = fb_get_capabilities; this->vo_driver.alloc_frame = fb_alloc_frame; this->vo_driver.update_frame_format = fb_update_frame_format; this->vo_driver.overlay_begin = 0; /* not used */ this->vo_driver.overlay_blend = fb_overlay_blend; this->vo_driver.overlay_end = 0; /* not used */ this->vo_driver.display_frame = fb_display_frame; this->vo_driver.get_property = fb_get_property; this->vo_driver.set_property = fb_set_property; this->vo_driver.get_property_min_max = fb_get_property_min_max; this->vo_driver.gui_data_exchange = fb_gui_data_exchange; this->vo_driver.dispose = fb_dispose; this->vo_driver.redraw_needed = fb_redraw_needed; } static int open_fb_device(config_values_t *config, xine_t *xine) { static const char devkey[] = "video.device.fb_device"; const char *device_name; int fd; /* This config entry is security critical, is it really necessary * or is a number enough? */ device_name = config->register_filename(config, devkey, "", XINE_CONFIG_STRING_IS_DEVICE_NAME, _("framebuffer device name"), _("Specifies the file name for the framebuffer device " "to be used.\nThis setting is security critical, " "because when changed to a different file, xine " "can be used to fill this file with arbitrary content. " "So you should be careful that the value you enter " "really is a proper framebuffer device."), XINE_CONFIG_SECURITY, NULL, NULL); if(strlen(device_name) > 3) { fd = xine_open_cloexec(device_name, O_RDWR); } else { device_name = "/dev/fb1"; fd = xine_open_cloexec(device_name, O_RDWR); if(fd < 0) { device_name = "/dev/fb0"; fd = xine_open_cloexec(device_name, O_RDWR); } } if(fd < 0) { xprintf(xine, XINE_VERBOSITY_DEBUG, "video_out_fb: Unable to open device \"%s\", aborting: %s\n", device_name, strerror(errno)); return -1; } config->update_string(config, devkey, device_name); return fd; } static int mode_visual(fb_driver_t *this, config_values_t *config, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix) { (void)config; switch(fix->visual) { case FB_VISUAL_TRUECOLOR: case FB_VISUAL_DIRECTCOLOR: switch(this->depth) { case 24: if(this->bpp == 32) { if(!var->blue.offset) return MODE_32_RGB; return MODE_32_BGR; } if(!var->blue.offset) return MODE_24_RGB; return MODE_24_BGR; case 16: if(!var->blue.offset) return MODE_16_RGB; return MODE_16_BGR; case 15: if(!var->blue.offset) return MODE_15_RGB; return MODE_15_BGR; case 8: if(!var->blue.offset) return MODE_8_RGB; return MODE_8_BGR; } } xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: Your video mode was not recognized, sorry.\n"), LOG_MODULE); return 0; } static int setup_yuv2rgb(fb_driver_t *this, config_values_t *config, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix) { this->yuv2rgb_mode = mode_visual(this, config, var, fix); if(!this->yuv2rgb_mode) return 0; this->yuv2rgb_swap = 0; this->yuv2rgb_brightness = 0; this->yuv2rgb_contrast = this->yuv2rgb_saturation = 128; this->yuv2rgb_factory = yuv2rgb_factory_init(this->yuv2rgb_mode, this->yuv2rgb_swap, this->yuv2rgb_cmap); if (!this->yuv2rgb_factory) return 0; this->yuv2rgb_factory->set_csc_levels (this->yuv2rgb_factory, this->yuv2rgb_brightness, this->yuv2rgb_contrast, this->yuv2rgb_saturation, CM_DEFAULT); return 1; } static void setup_buffers(fb_driver_t *this, struct fb_var_screeninfo *var) { /* * depth in X11 terminology land is the number of bits used to * actually represent the colour. * * bpp in X11 land means how many bits in the frame buffer per * pixel. * * ex. 15 bit color is 15 bit depth and 16 bpp. Also 24 bit * color is 24 bit depth, but can be 24 bpp or 32 bpp. * * fb assumptions: bpp % 8 = 0 (e.g. 8, 16, 24, 32 bpp) * bpp <= 32 * msb_right = 0 */ this->bytes_per_pixel = (this->fb_var.bits_per_pixel + 7)/8; this->bpp = this->bytes_per_pixel * 8; this->depth = this->fb_var.red.length + this->fb_var.green.length + this->fb_var.blue.length; this->total_num_native_buffers = var->yres_virtual / var->yres; this->used_num_buffers = 0; this->cur_frame = this->old_frame = 0; xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: %d video RAM buffers are available.\n"), LOG_MODULE, this->total_num_native_buffers); if(this->total_num_native_buffers < RECOMMENDED_NUM_BUFFERS) { this->use_zero_copy = 0; xprintf(this->xine, XINE_VERBOSITY_LOG, _("WARNING: %s: Zero copy buffers are DISABLED because only %d buffers\n" " are available which is less than the recommended %d buffers. Lowering\n" " the frame buffer resolution might help.\n"), LOG_MODULE, this->total_num_native_buffers, RECOMMENDED_NUM_BUFFERS); } else { /* test if FBIOPAN_DISPLAY works */ this->fb_var.yoffset = this->fb_var.yres; if(ioctl(this->fd, FBIOPAN_DISPLAY, &this->fb_var) == -1) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("WARNING: %s: Zero copy buffers are DISABLED because kernel driver\n" " do not support screen panning (used for frame flips).\n"), LOG_MODULE); } else { this->fb_var.yoffset = 0; ioctl(this->fd, FBIOPAN_DISPLAY, &this->fb_var); this->use_zero_copy = 1; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_fb: Using zero copy buffers.\n"); } } } static vo_driver_t *fb_open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { config_values_t *config; fb_driver_t *this; fb_class_t *class; const fb_visual_t *visual = (const fb_visual_t *)visual_gen; class = (fb_class_t *)class_gen; config = class->xine->config; /* allocate plugin struct */ this = calloc(1, sizeof(fb_driver_t)); if(!this) return NULL; this->video_mem_base = MAP_FAILED; this->xine = class->xine; _x_alphablend_init(&this->alphablend_extra_data, class->xine); _x_vo_scale_init(&this->sc, 0, 0, config); register_callbacks(this); this->fd = open_fb_device(config, class->xine); if(this->fd == -1) goto error; if(!get_fb_var_screeninfo(this->fd, &this->fb_var, class->xine)) { xprintf(this->xine, XINE_VERBOSITY_LOG, "video_out_fb: get_fb_var_screeninfo() failed: %s\n", strerror(errno)); goto error; } if(!get_fb_fix_screeninfo(this->fd, &this->fb_fix, class->xine)) { xprintf(this->xine, XINE_VERBOSITY_LOG, "video_out_fb: get_fb_fix_screeninfo() failed: %s\n", strerror(errno)); goto error; } if (!set_fb_palette (this->fd, &this->fb_var)) { xprintf(this->xine, XINE_VERBOSITY_LOG, "video_out_fb: set_fb_palette() failed: %s\n", strerror(errno)); if (this->fb_var.bits_per_pixel < 24) { goto error; } } if(this->fb_fix.line_length) this->fb_bytes_per_line = this->fb_fix.line_length; else this->fb_bytes_per_line = (this->fb_var.xres_virtual * this->fb_var.bits_per_pixel)/8; this->sc.gui_width = this->fb_var.xres; this->sc.gui_height = this->fb_var.yres; this->sc.user_ratio = XINE_VO_ASPECT_AUTO; if (visual) { this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; } setup_buffers(this, &this->fb_var); if(this->depth > 16) xprintf(this->xine, XINE_VERBOSITY_LOG, _("WARNING: %s: current display depth is %d. For better performance\n" " a depth of 16 bpp is recommended!\n\n"), LOG_MODULE, this->depth); xprintf(class->xine, XINE_VERBOSITY_DEBUG, "%s: video mode depth is %d (%d bpp),\n" " red: %d/%d, green: %d/%d, blue: %d/%d\n" " resolution %dx%x\n", LOG_MODULE, this->depth, this->bpp, this->fb_var.red.length, this->fb_var.red.offset, this->fb_var.green.length, this->fb_var.green.offset, this->fb_var.blue.length, this->fb_var.blue.offset, this->fb_var.xres, this->fb_var.yres); if (!setup_yuv2rgb(this, config, &this->fb_var, &this->fb_fix)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": yuv2rgb setup failed\n"); goto error; } /* mmap whole video memory */ this->mem_size = this->fb_fix.smem_len; this->video_mem_base = mmap(0, this->mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, 0); if (this->video_mem_base == MAP_FAILED) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "mapping frame buffer failed: %s\n", strerror(errno)); goto error; } return &this->vo_driver; error: xprintf(class->xine, XINE_VERBOSITY_DEBUG, "video_out_fb: Unable to configure fb device, aborting: %s\n", strerror(errno)); fb_dispose(&this->vo_driver); return 0; } static void *fb_init_class(xine_t *xine, const void *visual_gen) { fb_class_t *this; (void)visual_gen; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = fb_open_plugin; this->driver_class.identifier = "fb"; this->driver_class.description = N_("Xine video output plugin using the Linux frame buffer device"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_fb = { .priority = 1, .visual_type = XINE_VISUAL_TYPE_FB, }; /* exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "fb", XINE_VERSION_CODE, &vo_info_fb, fb_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_mmal.c0000644000175000017500000006551614647725152016634 0ustar meme/* * Copyright (C) 2000-2020 the xine project * Copyright (C) 2014-2020 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #define LOG_MODULE "video_out_mmal" #define LOG_VERBOSE /* #define LOG */ #define FRAME_ALLOC /* allocate buffer based on frame size. if not defined, all buffers are suitable for 1920x1088 YUY2. */ #define HW_OVERLAY /* draw overlay using HW. if undefined, draw in software. */ #include "xine.h" #include #include #include #ifdef FRAME_ALLOC #define MAX_VIDEO_WIDTH (2*1920) #define MAX_VIDEO_HEIGHT (2*1088) #define MAX_VIDEO_FRAMES 20 #else #define MAX_VIDEO_WIDTH 1920 #define MAX_VIDEO_HEIGHT 1088 #define MAX_VIDEO_FRAMES 20 #endif typedef struct { vo_frame_t vo_frame; #ifdef FRAME_ALLOC MMAL_PORT_T *input; #endif MMAL_BUFFER_HEADER_T *buffer; int width, height, format; double ratio; int displayed; } mmal_frame_t; typedef struct mmal_overlay_s mmal_overlay_t; struct mmal_overlay_s { mmal_overlay_t *next; void *mem; /* temp storage for rle -> argb */ int src_width, src_height, src_pitch; VC_RECT_T src_rect; VC_RECT_T dst_rect; DISPMANX_ELEMENT_HANDLE_T element; DISPMANX_RESOURCE_HANDLE_T resource; }; typedef struct { vo_driver_t vo_driver; /* xine */ xine_t *xine; #ifndef HW_OVERLAY alphablend_t alphablend_extra_data; #endif int gui_width, gui_height; /* mmal */ MMAL_COMPONENT_T *renderer; MMAL_POOL_T *pool; int frames_in_renderer; double renderer_ratio; /* dispmanx */ DISPMANX_DISPLAY_HANDLE_T dispmanx_handle; DISPMANX_UPDATE_HANDLE_T overlay_update; /* overlays */ mmal_overlay_t *overlays; mmal_overlay_t *old_overlays; pthread_mutex_t mutex; pthread_cond_t cond; } mmal_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } mmal_class_t; #define LOG_STATUS(msg) \ xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " msg ": %s (%d)\n", \ mmal_status_to_string(status), status) /* * display config */ static int update_tv_resolution(mmal_driver_t *this) { TV_DISPLAY_STATE_T display_state; if (vc_tv_get_display_state(&display_state) != 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to query display resolution\n"); return -1; } if (display_state.state & 0xFF) { this->gui_width = display_state.display.hdmi.width; this->gui_height = display_state.display.hdmi.height; } else if (display_state.state & 0xFF00) { this->gui_width = display_state.display.sdtv.width; this->gui_height = display_state.display.sdtv.height; } else { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "invalid display state %x", (unsigned)display_state.state); return -1; } xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE": " "display size %dx%d\n", this->gui_width, this->gui_height); return 0; } /* * */ static int config_display(mmal_driver_t *this, int src_x, int src_y, int src_w, int src_h) { MMAL_DISPLAYREGION_T display_region; MMAL_STATUS_T status; display_region.hdr.id = MMAL_PARAMETER_DISPLAYREGION; display_region.hdr.size = sizeof(MMAL_DISPLAYREGION_T); display_region.fullscreen = MMAL_FALSE; display_region.src_rect.x = src_x; display_region.src_rect.y = src_y; display_region.src_rect.width = src_w; display_region.src_rect.height = src_h; display_region.dest_rect.x = 0; display_region.dest_rect.y = 0; display_region.dest_rect.width = this->gui_width; display_region.dest_rect.height = this->gui_height; display_region.layer = 1; display_region.set = MMAL_DISPLAY_SET_FULLSCREEN | MMAL_DISPLAY_SET_SRC_RECT | MMAL_DISPLAY_SET_DEST_RECT | MMAL_DISPLAY_SET_LAYER; status = mmal_port_parameter_set(this->renderer->input[0], &display_region.hdr); if (status != MMAL_SUCCESS) { LOG_STATUS("failed to set display region"); return -1; } return 0; } /* * MMAL callbacks */ static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { mmal_driver_t *this = (mmal_driver_t *)port->userdata; MMAL_STATUS_T status; if (buffer->cmd == MMAL_EVENT_ERROR) { status = *(uint32_t *)buffer->data; LOG_STATUS("MMAL error"); } mmal_buffer_header_release(buffer); } static void input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { mmal_driver_t *this = (mmal_driver_t *)port->userdata; vo_frame_t *frame = (vo_frame_t *)buffer->user_data; pthread_mutex_lock(&this->mutex); --this->frames_in_renderer; pthread_cond_signal(&this->cond); pthread_mutex_unlock(&this->mutex); if (frame) { frame->free(frame); } } /* * renderer configuration */ static void disable_renderer(mmal_driver_t *this) { if (this->renderer) { if (this->renderer->control->is_enabled) { mmal_port_disable(this->renderer->control); } if (this->renderer->input[0]->is_enabled) { mmal_port_disable(this->renderer->input[0]); } if (this->renderer->is_enabled) { mmal_component_disable(this->renderer); } } } static int configure_renderer(mmal_driver_t *this, int format, int width, int height, int crop_x, int crop_y, int crop_w, int crop_h, double ratio) { MMAL_PORT_T *input = this->renderer->input[0]; MMAL_STATUS_T status; disable_renderer(this); this->renderer_ratio = ratio; input->userdata = (struct MMAL_PORT_USERDATA_T *)this; input->format->encoding = (format == XINE_IMGFMT_YV12 ? MMAL_ENCODING_I420 : MMAL_ENCODING_YUYV); input->format->es->video.width = width; input->format->es->video.height = height; input->format->es->video.crop.x = crop_x; input->format->es->video.crop.y = crop_y; input->format->es->video.crop.width = crop_w; input->format->es->video.crop.height = crop_h; input->format->es->video.par.num = height * ratio; input->format->es->video.par.den = width; status = mmal_port_format_commit(input); if (status != MMAL_SUCCESS) { LOG_STATUS("failed to commit input format"); } input->buffer_size = input->buffer_size_recommended; status = mmal_port_enable(this->renderer->control, control_port_cb); if (status != MMAL_SUCCESS) { LOG_STATUS("failed to enable control port"); return -1; } status = mmal_port_enable(input, input_port_cb); if (status != MMAL_SUCCESS) { LOG_STATUS("failed to enable input port"); return -1; } status = mmal_component_enable(this->renderer); if (status != MMAL_SUCCESS) { LOG_STATUS("failed to enable renderer component"); return -1; } if (!this->pool) { #ifdef FRAME_ALLOC this->pool = mmal_port_pool_create(input, MAX_VIDEO_FRAMES, 0); if (!this->pool) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to create MMAL pool for %u buffers\n", MAX_VIDEO_FRAMES); return -1; } #else int buffer_size = MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT * 2; this->pool = mmal_pool_create_with_allocator(MAX_VIDEO_FRAMES, buffer_size, input, (mmal_pool_allocator_alloc_t)mmal_port_payload_alloc, (mmal_pool_allocator_free_t)mmal_port_payload_free); if (!this->pool) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to create MMAL pool for %u buffers of size %d\n", MAX_VIDEO_FRAMES, buffer_size); return -1; } #endif } return 0; } /* * xine interface */ static uint32_t mmal_get_capabilities (vo_driver_t *this_gen) { return VO_CAP_YUY2 | VO_CAP_YV12 | VO_CAP_CROP | VO_CAP_UNSCALED_OVERLAY | VO_CAP_CUSTOM_EXTENT_OVERLAY; } static void mmal_frame_field (vo_frame_t *vo_img, int which_field) { } static void mmal_frame_dispose (vo_frame_t *vo_img) { mmal_frame_t *frame = xine_container_of(vo_img, mmal_frame_t, vo_frame); if (frame->buffer) { #ifdef FRAME_ALLOC if (frame->buffer->data) { mmal_port_payload_free(frame->input, frame->buffer->data); frame->buffer->data = NULL; frame->buffer->alloc_size = 0; } #endif frame->buffer->user_data = NULL; mmal_buffer_header_release(frame->buffer); frame->buffer = NULL; } free(frame); } static vo_frame_t *mmal_alloc_frame (vo_driver_t *this_gen) { #ifdef FRAME_ALLOC mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); #endif mmal_frame_t *frame; frame = (mmal_frame_t *) calloc(1, sizeof(mmal_frame_t)); if (!frame) return NULL; pthread_mutex_init (&frame->vo_frame.mutex, NULL); frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = mmal_frame_field; frame->vo_frame.dispose = mmal_frame_dispose; #ifdef FRAME_ALLOC frame->input = this->renderer->input[0]; #endif return &frame->vo_frame; } static void mmal_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); mmal_frame_t *frame = xine_container_of(frame_gen, mmal_frame_t, vo_frame); /* limit frame size */ if (width > MAX_VIDEO_WIDTH) { width = MAX_VIDEO_WIDTH; frame->vo_frame.width = width; } if (height > MAX_VIDEO_HEIGHT) { height = MAX_VIDEO_HEIGHT; frame->vo_frame.height = height; } /* alignment */ width = (width + 31) & ~31; height = (height + 15) & ~15; #ifdef FRAME_ALLOC /* required storage */ uint32_t size = width * height; if (format == XINE_IMGFMT_YV12) { size = size * 3 / 2; } else if (format == XINE_IMGFMT_YUY2) { size *= 2; } /* free buffer if it is too small */ if (frame->buffer && frame->buffer->alloc_size < size) { mmal_port_payload_free(this->renderer->input[0], frame->buffer->data); frame->buffer->data = NULL; frame->buffer->user_data = NULL; mmal_buffer_header_release(frame->buffer); frame->buffer = NULL; } #endif if (!frame->buffer) { frame->buffer = mmal_queue_wait(this->pool->queue); if (!frame->buffer) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to get mmal buffer for frame\n"); frame->vo_frame.width = frame->vo_frame.height = 0; return; } #ifdef FRAME_ALLOC frame->buffer->data = mmal_port_payload_alloc(this->renderer->input[0], size); frame->buffer->alloc_size = size; #endif frame->buffer->user_data = frame; } frame->width = width; frame->height = height; frame->format = format; frame->ratio = ratio; if (format == XINE_IMGFMT_YV12) { frame->vo_frame.pitches[0] = width; frame->vo_frame.pitches[1] = width/2; frame->vo_frame.pitches[2] = width/2; frame->vo_frame.base[0] = frame->buffer->data; frame->vo_frame.base[1] = frame->vo_frame.base[0] + width * height; frame->vo_frame.base[2] = frame->vo_frame.base[1] + width/2 * height/2; } else if (format == XINE_IMGFMT_YUY2) { frame->vo_frame.pitches[0] = width * 2; frame->vo_frame.base[0] = frame->buffer->data; } else { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "unsupported frame format %x\n", format); frame->vo_frame.width = frame->vo_frame.height = 0; } frame->displayed = 0; } /* * overlay */ static void overlay_free(mmal_overlay_t *ovl, DISPMANX_UPDATE_HANDLE_T update) { if (ovl->resource != DISPMANX_NO_HANDLE) { vc_dispmanx_element_remove(update, ovl->element); vc_dispmanx_resource_delete(ovl->resource); } free(ovl->mem); free(ovl); } static void overlay_update(mmal_overlay_t *ovl, DISPMANX_UPDATE_HANDLE_T update, uint32_t *argb) { vc_dispmanx_resource_write_data(ovl->resource, VC_IMAGE_RGBA32, ovl->src_pitch, argb, &ovl->src_rect); vc_dispmanx_element_change_source(update, ovl->element, ovl->resource); } static mmal_overlay_t *overlay_new(mmal_driver_t *this, DISPMANX_UPDATE_HANDLE_T update, int src_width, int src_height, int src_pitch, int x, int y, int width, int height, int layer, uint32_t *argb) { mmal_overlay_t *ovl; uint32_t image_handle; static VC_DISPMANX_ALPHA_T alpha; VC_RECT_T src_rect; ovl = calloc(1, sizeof(*ovl)); if (!ovl) return NULL; //src_width &= 31; //dst_width &= 15; ovl->src_pitch = src_pitch; ovl->src_width = src_width; ovl->src_height = src_height; vc_dispmanx_rect_set(&src_rect, 0, 0, src_width << 16, src_height << 16); vc_dispmanx_rect_set(&ovl->src_rect, 0, 0, src_width, src_height); vc_dispmanx_rect_set(&ovl->dst_rect, x, y, width, height); ovl->resource = vc_dispmanx_resource_create(VC_IMAGE_RGBA32, src_pitch | (src_pitch<<16), src_height | (src_height<<16), &image_handle); if (ovl->resource == DISPMANX_NO_HANDLE) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to create dispmanx resource for overlay\n"); overlay_free(ovl, update); return NULL; } if (vc_dispmanx_resource_write_data(ovl->resource, VC_IMAGE_RGBA32, src_pitch, argb, &ovl->src_rect)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to write overlay data to dispmanx resource\n"); overlay_free(ovl, update); return NULL; } alpha.flags = DISPMANX_FLAGS_ALPHA_FROM_SOURCE /*| DISPMANX_FLAGS_ALPHA_MIX*/; alpha.mask = DISPMANX_NO_HANDLE; ovl->element = vc_dispmanx_element_add(update, this->dispmanx_handle, layer, &ovl->dst_rect, ovl->resource, &src_rect, DISPMANX_PROTECTION_NONE, &alpha, NULL, VC_IMAGE_ROT0); if (ovl->element == DISPMANX_NO_HANDLE) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "vc_dispmanx_element_add() failed\n"); overlay_free(ovl, update); return NULL; } return ovl; } static void close_overlays(mmal_driver_t *this, mmal_overlay_t *ovls) { while (ovls) { mmal_overlay_t *tmp = ovls; ovls = ovls->next; overlay_free(tmp, this->overlay_update); } } /* * */ static void mmal_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { #ifdef HW_OVERLAY mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); if (changed) { this->overlay_update = vc_dispmanx_update_start(10); /* re-create active overlay list to maintain blending order */ this->old_overlays = this->overlays; this->overlays = NULL; } #endif } static void mmal_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame, vo_overlay_t *overlay) { mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); if (overlay->width <= 0 || overlay->height <= 0 || !overlay->rle) return; #ifndef HW_OVERLAY this->alphablend_extra_data.offset_x = frame->overlay_offset_x; this->alphablend_extra_data.offset_y = frame->overlay_offset_y; if (overlay->rle) { if( frame->format == XINE_IMGFMT_YV12 ) _x_blend_yuv( frame->base, overlay, frame->width, frame->height, frame->pitches, &this->alphablend_extra_data); else _x_blend_yuy2( frame->base[0], overlay, frame->width, frame->height, frame->pitches[0], &this->alphablend_extra_data); } #else if (!this->overlay_update) { return; } int dst_x = overlay->x, dst_y = overlay->y, dst_w = overlay->width, dst_h = overlay->height; /* coordinate system */ int extent_width = overlay->extent_width; int extent_height = overlay->extent_height; if (extent_width < 1 || extent_height < 1) { if (overlay->unscaled) { extent_width = this->gui_width; extent_height = this->gui_height; } else { extent_width = frame->width; extent_height = frame->height; } } /* scale dst region if needed */ if (extent_width != this->gui_width) { dst_x = dst_x * this->gui_width / extent_width; dst_w = dst_w * this->gui_width / extent_width; } if (extent_height != this->gui_height) { dst_y = dst_y * this->gui_height / extent_height; dst_h = dst_h * this->gui_height / extent_height; } #ifdef LOG fprintf(stderr, "overlay: %d,%d %dx%d unscaled:%d extent: %dx%d argb: %d-> surface %dx%d\n", overlay->x, overlay->y, overlay->width, overlay->height, overlay->unscaled, overlay->extent_width, overlay->extent_height, (overlay->argb_layer && overlay->argb_layer->buffer), extent_width, extent_height); #endif /* find suitable region, maintain overlay blending order */ mmal_overlay_t *ovl = this->old_overlays, *prev = NULL; while (ovl) { /* source, dst coordinates must be same (= size + location + scaling) */ if (ovl->src_width == overlay->width && ovl->src_height == overlay->height && dst_x == ovl->dst_rect.x && dst_y == ovl->dst_rect.y && dst_w == ovl->dst_rect.width && dst_h == ovl->dst_rect.height) { if (prev) { prev->next = ovl->next; } else { this->old_overlays = ovl->next; } ovl->next = NULL; break; } prev = ovl; ovl = ovl->next; } /* new overlay */ if (!ovl) { if (overlay->rle) { _x_overlay_clut_yuv2rgb(overlay, 0); void *mem = NULL; int src_pitch = (sizeof(uint32_t) * overlay->width + 31) & ~31; mem = malloc(src_pitch * overlay->height); _x_overlay_to_argb32(overlay, mem, src_pitch/4, "RGBA"); ovl = overlay_new(this, this->overlay_update, overlay->width, overlay->height, src_pitch, dst_x, dst_y, dst_w, dst_h, 2, mem); if (!ovl) return; ovl->mem = mem; } } /* update overlay */ else if (overlay->rle) { _x_overlay_clut_yuv2rgb(overlay, 0); if (!ovl->mem) { int src_pitch = (sizeof(uint32_t) * overlay->width + 31) & ~31; ovl->mem = malloc(src_pitch * overlay->height); ovl->src_pitch = src_pitch; } _x_overlay_to_argb32(overlay, ovl->mem, ovl->src_pitch/4, "RGBA"); overlay_update(ovl, this->overlay_update, ovl->mem); } /* add to list */ mmal_overlay_t **tail = &this->overlays; while (*tail) { tail = &(*tail)->next; } *tail = ovl; #endif /* HW_OVERLAY */ } static void mmal_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen) { #ifdef HW_OVERLAY mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); if (!this->overlay_update) { return; } /* remove handles not in use */ close_overlays(this, this->old_overlays); this->old_overlays = NULL; /* commit updates */ vc_dispmanx_update_submit_sync(this->overlay_update); this->overlay_update = 0; #endif } /* * */ static int mmal_redraw_needed (vo_driver_t *this_gen) { return 0; } static void mmal_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); mmal_frame_t *frame = xine_container_of(frame_gen, mmal_frame_t, vo_frame); MMAL_PORT_T *input = this->renderer->input[0]; MMAL_STATUS_T status; int visible_width = frame_gen->width - frame_gen->crop_left - frame_gen->crop_right; int visible_height = frame_gen->height - frame_gen->crop_top - frame_gen->crop_bottom; if (input->format->es->video.width != frame->width || input->format->es->video.height != frame->height || this->renderer_ratio != frame_gen->ratio || input->format->es->video.crop.x != frame_gen->crop_left || input->format->es->video.crop.y != frame_gen->crop_top || input->format->es->video.crop.width != visible_width || input->format->es->video.crop.height != visible_height) { configure_renderer(this, frame->format, frame->width, frame->height, frame_gen->crop_left, frame_gen->crop_top, visible_width, visible_height, frame_gen->ratio); config_display(this, 0, 0, frame_gen->width, frame_gen->height); } frame->buffer->cmd = 0; frame->buffer->length = this->renderer->input[0]->buffer_size; pthread_mutex_lock(&this->mutex); while (this->frames_in_renderer > 1) { pthread_cond_wait(&this->cond, &this->mutex); } status = mmal_port_send_buffer(this->renderer->input[0], frame->buffer); if (status == MMAL_SUCCESS) { this->frames_in_renderer++; } pthread_mutex_unlock(&this->mutex); if (status != MMAL_SUCCESS) { LOG_STATUS("failed to send frame to renderer input port"); frame_gen->free(frame_gen); return; } if (frame->displayed) { frame_gen->free(frame_gen); return; } frame->displayed = 1; } static int mmal_get_property (vo_driver_t *this_gen, int property) { mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); switch (property) { case VO_PROP_WINDOW_WIDTH: return this->gui_width; case VO_PROP_WINDOW_HEIGHT: return this->gui_height; case VO_PROP_MAX_VIDEO_WIDTH: return MAX_VIDEO_WIDTH; case VO_PROP_MAX_VIDEO_HEIGHT: return MAX_VIDEO_HEIGHT; case VO_PROP_MAX_NUM_FRAMES: return MAX_VIDEO_FRAMES; } return 0; } static int mmal_set_property (vo_driver_t *this_gen, int property, int value) { return value; } static void mmal_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { *min = *max = 0; } static int mmal_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { return -1; } static void mmal_dispose (vo_driver_t * this_gen) { mmal_driver_t *this = xine_container_of(this_gen, mmal_driver_t, vo_driver); if (this->dispmanx_handle) { if (this->overlays) { this->overlay_update = vc_dispmanx_update_start(10); close_overlays(this, this->overlays); this->overlays = NULL; vc_dispmanx_update_submit_sync(this->overlay_update); this->overlay_update = 0; } vc_dispmanx_display_close(this->dispmanx_handle); this->dispmanx_handle = DISPMANX_NO_HANDLE; } if (this->pool) { #ifdef FRAME_ALLOC MMAL_PORT_T *input = this->renderer->input[0]; mmal_port_pool_destroy(input, this->pool); #else mmal_port_pool_destroy(this->pool); #endif } if (this->renderer) { disable_renderer(this); mmal_component_release(this->renderer); } #ifndef HW_OVERLAY _x_alphablend_free(&this->alphablend_extra_data); #endif pthread_cond_destroy(&this->cond); pthread_mutex_destroy(&this->mutex); free(this); bcm_host_deinit(); } static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { mmal_class_t *class = (mmal_class_t*) class_gen; mmal_driver_t *this; MMAL_STATUS_T status; this = (mmal_driver_t *) calloc(1, sizeof(mmal_driver_t)); if (!this) return NULL; this->xine = class->xine; #ifndef HW_OVERLAY _x_alphablend_init(&this->alphablend_extra_data, class->xine); #endif pthread_mutex_init (&this->mutex, NULL); pthread_cond_init (&this->cond, NULL); bcm_host_init(); status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER, &this->renderer); if (status != MMAL_SUCCESS) { LOG_STATUS("failed to create MMAL component " MMAL_COMPONENT_DEFAULT_VIDEO_RENDERER); mmal_dispose(&this->vo_driver); return NULL; } this->renderer->control->userdata = (struct MMAL_PORT_USERDATA_T *)this; this->renderer->input[0]->userdata = (struct MMAL_PORT_USERDATA_T *)this; configure_renderer(this, XINE_IMGFMT_YV12, 720, 576, 0, 0, 720, 576, 4.0/3.0); update_tv_resolution(this); config_display(this, 0, 0, 720, 576); this->dispmanx_handle = vc_dispmanx_display_open(0); if (this->dispmanx_handle == DISPMANX_NO_HANDLE) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to open dispmanx display\n"); mmal_dispose(&this->vo_driver); return NULL; } this->vo_driver.get_capabilities = mmal_get_capabilities; this->vo_driver.alloc_frame = mmal_alloc_frame; this->vo_driver.update_frame_format = mmal_update_frame_format; this->vo_driver.overlay_begin = mmal_overlay_begin; this->vo_driver.overlay_blend = mmal_overlay_blend; this->vo_driver.overlay_end = mmal_overlay_end; this->vo_driver.display_frame = mmal_display_frame; this->vo_driver.get_property = mmal_get_property; this->vo_driver.set_property = mmal_set_property; this->vo_driver.get_property_min_max = mmal_get_property_min_max; this->vo_driver.gui_data_exchange = mmal_gui_data_exchange; this->vo_driver.dispose = mmal_dispose; this->vo_driver.redraw_needed = mmal_redraw_needed; return &this->vo_driver; } /** * Class Functions */ static void *init_class (xine_t *xine, const void *visual_gen) { mmal_class_t *this; this = (mmal_class_t*) calloc(1, sizeof(mmal_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "MMAL"; this->driver_class.description = N_("xine video output plugin using MMAL"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_mmal = { .priority = 10, .visual_type = XINE_VISUAL_TYPE_FB, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "mmal", XINE_VERSION_CODE, &vo_info_mmal, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_vaapi.c0000644000175000017500000031574214647725152017005 0ustar meme/* * Copyright (C) 2012 Edgar Hucek * Copyright (C) 2012-2023 xine developers * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_vaapi.c, VAAPI video extension interface for xine * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #if defined(__FreeBSD__) #include #endif #include #include #include #include #include #include #include #define LOG_MODULE "video_out_vaapi" #define LOG_VERBOSE /* #define LOG */ /* #define DEBUG_SURFACE */ #include "xine.h" #include #include #include #include #include #if defined(HAVE_OPENGL) && defined(HAVE_VA_VA_GLX_H) # ifdef HAVE_GLU # include # endif # include # include # include # include # include # define ENABLE_VA_GLX #endif /* OPENGL */ #include "vaapi/vaapi_util.h" #include "vaapi/vaapi_frame.h" #include "vaapi/xine_va_display.h" /* interop flags */ #include #ifndef VA_SURFACE_ATTRIB_SETTABLE #define vaCreateSurfaces(d, f, w, h, s, ns, a, na) \ vaCreateSurfaces(d, w, h, f, ns, s) #endif #define MIN_SURFACES 22 #define SOFT_SURFACES 3 #define SW_WIDTH 1920 #define SW_HEIGHT 1080 #define STABLE_FRAME_COUNTER 4 #define SW_CONTEXT_INIT_FORMAT -1 //VAProfileH264Main #if defined VA_SRC_BT601 && defined VA_SRC_BT709 # define USE_VAAPI_COLORSPACE 1 #else # define USE_VAAPI_COLORSPACE 0 #endif #define FOVY 60.0f #define ASPECT 1.0f #define Z_NEAR 0.1f #define Z_FAR 100.0f #define Z_CAMERA 0.869f #ifndef GLAPIENTRY #ifdef APIENTRY #define GLAPIENTRY APIENTRY #else #define GLAPIENTRY #endif #endif #ifndef HAVE_THREAD_SAFE_X11 #define LOCK_DISPLAY(_this) XLockDisplay (_this->display) #define UNLOCK_DISPLAY(_this) XUnlockDisplay (_this->display) #else #define LOCK_DISPLAY(_this) #define UNLOCK_DISPLAY(_this) #endif #define RECT_IS_EQ(a, b) ((a).x1 == (b).x1 && (a).y1 == (b).y1 && (a).x2 == (b).x2 && (a).y2 == (b).y2) static const char *const scaling_level_enum_names[] = { "default", /* VA_FILTER_SCALING_DEFAULT */ "fast", /* VA_FILTER_SCALING_FAST */ "hq", /* VA_FILTER_SCALING_HQ */ "nla", /* VA_FILTER_SCALING_NL_ANAMORPHIC */ NULL }; static const int scaling_level_enum_values[] = { VA_FILTER_SCALING_DEFAULT, VA_FILTER_SCALING_FAST, VA_FILTER_SCALING_HQ, VA_FILTER_SCALING_NL_ANAMORPHIC }; typedef struct vaapi_driver_s vaapi_driver_t; typedef struct { int x1, y1, x2, y2; } vaapi_rect_t; typedef struct { VADisplayAttribType type; int value; int min; int max; int atom; cfg_entry_t *entry; vaapi_driver_t *this; } va_property_t; struct vaapi_driver_s { vo_driver_t vo_driver; /* X11 related stuff */ Display *display; int screen; Drawable drawable; XColor black; Window window; uint32_t capabilities; int ovl_changed; vo_overlay_t *overlays[XINE_VORAW_MAX_OVL]; uint32_t *overlay_bitmap; uint32_t overlay_bitmap_size; uint32_t overlay_bitmap_width; uint32_t overlay_bitmap_height; vaapi_rect_t overlay_bitmap_src; vaapi_rect_t overlay_bitmap_dst; uint32_t vdr_osd_width; uint32_t vdr_osd_height; uint32_t overlay_output_width; uint32_t overlay_output_height; vaapi_rect_t overlay_dirty_rect; int has_overlay; /* all scaling information goes here */ vo_scale_t sc; xine_t *xine; unsigned int deinterlace; #ifdef ENABLE_VA_GLX int opengl_render; unsigned int init_opengl_render; int opengl_use_tfp; GLuint gl_texture; GLXContext gl_context; Pixmap gl_pixmap; Pixmap gl_image_pixmap; /* OpenGL surface */ void *gl_surface; #endif ff_vaapi_context_t *va_context; /* soft surfaces */ int sw_width; int sw_height; VASurfaceID *va_soft_surface_ids; VAImage *va_soft_images; unsigned int va_soft_head; int soft_image_is_bound; /* subpicture */ VAImageFormat bgra_subpic_format; unsigned int bgra_subpic_flags; VAImage va_subpic_image; VASubpictureID va_subpic_id; int va_subpic_width; int va_subpic_height; unsigned int last_sub_image_fmt; int overlay_mode; pthread_mutex_t vaapi_lock; unsigned int guarded_render; unsigned int scaling_level_enum; unsigned int scaling_level; va_property_t props[VO_NUM_PROPERTIES]; unsigned int swap_uv_planes; /* color matrix and fullrange emulation */ uint8_t cm_lut[32]; int cm_state; int color_matrix; int vaapi_cm_flags; #define CSC_MODE_USER_MATRIX 0 #define CSC_MODE_FLAGS 1 #define CSC_MODE_FLAGS_FULLRANGE2 2 #define CSC_MODE_FLAGS_FULLRANGE3 3 int csc_mode; int have_user_csc_matrix; float user_csc_matrix[12]; /* keep last frame surface alive (video_out shamelessy uses it ...) */ /* XXX maybe this issue could be solved with some kind of release callback. * Such callback could be useful with dropped frames too. */ vo_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; /* */ VASurfaceID va_soft_surface_ids_storage[SOFT_SURFACES + 1]; VAImage va_soft_images_storage[SOFT_SURFACES + 1]; vaapi_context_impl_t *va; #ifdef ENABLE_VA_GLX void (GLAPIENTRY *mpglBindTexture) (GLenum, GLuint); void (GLAPIENTRY *mpglXBindTexImage) (Display *, GLXDrawable, int, const int *); void (GLAPIENTRY *mpglXReleaseTexImage) (Display *, GLXDrawable, int); GLXPixmap (GLAPIENTRY *mpglXCreatePixmap) (Display *, GLXFBConfig, Pixmap, const int *); void (GLAPIENTRY *mpglXDestroyPixmap) (Display *, GLXPixmap); const GLubyte *(GLAPIENTRY *mpglGetString) (GLenum); void (GLAPIENTRY *mpglGenPrograms) (GLsizei, GLuint *); #endif }; /* import common color matrix stuff */ #define CM_LUT #define CM_HAVE_YCGCO_SUPPORT 1 #define CM_HAVE_BT2020_SUPPORT 1 #define CM_DRIVER_T vaapi_driver_t #include "color_matrix.c" static void vaapi_destroy_subpicture (vaapi_driver_t *this); static int vaapi_ovl_associate (vaapi_driver_t *this, int format, int bShow); static VAStatus vaapi_destroy_soft_surfaces (vaapi_driver_t *this); static int vaapi_set_property (vo_driver_t *this_gen, int property, int value); #if defined(LOG) || defined(DEBUG) static const char *string_of_VAImageFormat(VAImageFormat *imgfmt) { static char str[5]; str[0] = imgfmt->fourcc; str[1] = imgfmt->fourcc >> 8; str[2] = imgfmt->fourcc >> 16; str[3] = imgfmt->fourcc >> 24; str[4] = '\0'; return str; } #endif static int vaapi_check_status(vaapi_driver_t *this, VAStatus vaStatus, const char *msg) { if (vaStatus != VA_STATUS_SUCCESS) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " Error : %s: %s\n", msg, vaErrorStr(vaStatus)); return 0; } return 1; } static int vaapi_lock_decode_guarded(vo_frame_t *frame_gen) { vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver; pthread_mutex_lock(&this->vaapi_lock); return 1; } static void vaapi_unlock_decode_guarded(vo_frame_t *frame_gen) { vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver; /* unconditional unlock - this is called only if lock was acquired */ pthread_mutex_unlock(&this->vaapi_lock); } typedef struct { video_driver_class_t driver_class; xine_t *xine; unsigned visual_type; } vaapi_class_t; static void vaapi_x11_wait_event(Display *dpy, Window w, int type) { XEvent e; while (!XCheckTypedWindowEvent(dpy, w, type, &e)) xine_usec_sleep(10); } /* X11 Error handler and error functions */ static int vaapi_x11_error_code = 0; static int (*vaapi_x11_old_error_handler)(Display *, XErrorEvent *); static int vaapi_x11_error_handler(Display *dpy, XErrorEvent *error) { (void)dpy; vaapi_x11_error_code = error->error_code; return 0; } static void vaapi_x11_trap_errors(void) { vaapi_x11_error_code = 0; vaapi_x11_old_error_handler = XSetErrorHandler(vaapi_x11_error_handler); } static int vaapi_x11_untrap_errors(void) { XSetErrorHandler(vaapi_x11_old_error_handler); return vaapi_x11_error_code; } #ifdef ENABLE_VA_GLX static void vaapi_appendstr (char **dst, size_t *len, const char *str) { size_t newsize, slen; char *newstr; if (!str) return; slen = strlen (str); newsize = *len + 1 + slen; newstr = realloc (*dst, newsize + 1); if (!newstr) return; *dst = newstr; newstr[*len] = ' '; memcpy (newstr + *len + 1, str, slen + 1); *len = newsize; } /* Return the address of a linked function */ static void *vaapi_getdladdr (const char *s) { void *ret = NULL; void *handle = dlopen(NULL, RTLD_LAZY); if (!handle) return NULL; ret = dlsym(handle, s); dlclose(handle); return ret; } /* Resolve opengl functions. */ static void vaapi_get_functions (vaapi_driver_t *this, void *(*getProcAddress)(const GLubyte *), const char *ext2) { const char *extensions; char *allexts; size_t l1, l2; if (!getProcAddress) getProcAddress = (void *)vaapi_getdladdr; /* special case, we need glGetString before starting to find the other functions */ this->mpglGetString = getProcAddress ("glGetString"); if (!this->mpglGetString) this->mpglGetString = glGetString; extensions = (const char *)this->mpglGetString (GL_EXTENSIONS); if (!extensions) extensions = ""; if (!ext2) ext2 = ""; l1 = strlen (extensions); l2 = strlen (ext2); allexts = malloc (l1 + 1 + l2 + 1); memcpy (allexts, extensions, l1); allexts[l1] = ' '; memcpy (allexts + l1 + 1, ext2, l2); allexts[l1 + 1 + l2] = 0; lprintf("vaapi_get_functions: OpenGL extensions string:\n%s\n", allexts); this->mpglBindTexture = getProcAddress ((const GLubyte *)"glBindTexture"); if (!this->mpglBindTexture) this->mpglBindTexture = getProcAddress ((const GLubyte *)"glBindTextureARB"); if (!this->mpglBindTexture) this->mpglBindTexture = getProcAddress ((const GLubyte *)"glBindTextureEXT"); this->mpglXBindTexImage = NULL; this->mpglXReleaseTexImage = NULL; this->mpglXCreatePixmap = NULL; this->mpglXDestroyPixmap = NULL; if (strstr (allexts, "GLX_EXT_texture_from_pixmap")) { this->mpglXBindTexImage = getProcAddress ((const GLubyte *)"glXBindTexImageEXT"); this->mpglXReleaseTexImage = getProcAddress ((const GLubyte *)"glXReleaseTexImageEXT"); this->mpglXCreatePixmap = getProcAddress ((const GLubyte *)"glXCreatePixmap"); this->mpglXDestroyPixmap = getProcAddress ((const GLubyte *)"glXDestroyPixmap"); } this->mpglGenPrograms = NULL; if (strstr (allexts, "_program")) this->mpglGenPrograms = getProcAddress ((const GLubyte *)"glGenProgramsARB"); lprintf("\n"); free(allexts); } #define VAAPI_GLX_VISUAL_ATTR \ { \ GLX_RGBA, \ GLX_RED_SIZE, 1, \ GLX_GREEN_SIZE, 1, \ GLX_BLUE_SIZE, 1, \ GLX_DOUBLEBUFFER, \ GL_NONE \ } \ /* Check if opengl indirect/software rendering is used */ static int vaapi_opengl_verify_direct (const x11_visual_t *vis) { Window root, win; XVisualInfo *visinfo; GLXContext ctx; XSetWindowAttributes xattr; int ret = 0; int gl_visual_attr[] = VAAPI_GLX_VISUAL_ATTR; if (!vis || !vis->display || ! (root = RootWindow (vis->display, vis->screen))) { lprintf ("vaapi_opengl_verify_direct: Don't have a root window to verify\n"); return 0; } if (! (visinfo = glXChooseVisual (vis->display, vis->screen, gl_visual_attr))) return 0; if (! (ctx = glXCreateContext (vis->display, visinfo, NULL, 1))) { XFree(visinfo); return 0; } memset (&xattr, 0, sizeof (xattr)); xattr.colormap = XCreateColormap(vis->display, root, visinfo->visual, AllocNone); xattr.event_mask = StructureNotifyMask | ExposureMask; if ( (win = XCreateWindow (vis->display, root, 0, 0, 1, 1, 0, visinfo->depth, InputOutput, visinfo->visual, CWBackPixel | CWBorderPixel | CWColormap | CWEventMask, &xattr))) { if (glXMakeCurrent (vis->display, win, ctx)) { const char *renderer = (const char *) glGetString(GL_RENDERER); if (glXIsDirect (vis->display, ctx) && ! strstr (renderer, "Software") && ! strstr (renderer, "Indirect")) ret = 1; glXMakeCurrent (vis->display, None, NULL); } XDestroyWindow (vis->display, win); } glXDestroyContext (vis->display, ctx); XFreeColormap (vis->display, xattr.colormap); XFree(visinfo); return ret; } static int vaapi_glx_bind_texture(vaapi_driver_t *this) { glEnable(GL_TEXTURE_2D); this->mpglBindTexture (GL_TEXTURE_2D, this->gl_texture); if (this->opengl_use_tfp) { vaapi_x11_trap_errors(); this->mpglXBindTexImage (this->display, this->gl_pixmap, GLX_FRONT_LEFT_EXT, NULL); XSync(this->display, False); if (vaapi_x11_untrap_errors()) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_bind_texture : Update bind_tex_image failed\n"); } return 0; } static int vaapi_glx_unbind_texture(vaapi_driver_t *this) { if (this->opengl_use_tfp) { vaapi_x11_trap_errors(); this->mpglXReleaseTexImage (this->display, this->gl_pixmap, GLX_FRONT_LEFT_EXT); if (vaapi_x11_untrap_errors()) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_unbind_texture : Failed to release?\n"); } this->mpglBindTexture (GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); return 0; } static void vaapi_glx_render_frame(vaapi_driver_t *this, mem_frame_t *frame, int left, int top, int right, int bottom) { ff_vaapi_context_t *va_context = this->va_context; int x1, x2, y1, y2; float tx, ty; (void)left; (void)top; (void)right; (void)bottom; if (vaapi_glx_bind_texture(this) < 0) return; /* Calc texture/rectangle coords */ x1 = this->sc.output_xoffset; y1 = this->sc.output_yoffset; x2 = x1 + this->sc.output_width; y2 = y1 + this->sc.output_height; tx = (float) frame->width / va_context->width; ty = (float) frame->height / va_context->height; glColor4f(1.0f, 1.0f, 1.0f, 1.0f); /* Draw quad */ glBegin (GL_QUADS); glTexCoord2f (tx, ty); glVertex2i (x2, y2); glTexCoord2f (0, ty); glVertex2i (x1, y2); glTexCoord2f (0, 0); glVertex2i (x1, y1); glTexCoord2f (tx, 0); glVertex2i (x2, y1); lprintf("render_frame left %d top %d right %d bottom %d\n", x1, y1, x2, y2); glEnd (); if (vaapi_glx_unbind_texture(this) < 0) return; } static void vaapi_glx_flip_page(vaapi_driver_t *this, mem_frame_t *frame, int left, int top, int right, int bottom) { glClear(GL_COLOR_BUFFER_BIT); vaapi_glx_render_frame(this, frame, left, top, right, bottom); //if (gl_finish) // glFinish(); glXSwapBuffers(this->display, this->window); } static void destroy_glx(vaapi_driver_t *this) { ff_vaapi_context_t *va_context = this->va_context; if(!this->opengl_render || !va_context->valid_context) return; //if (gl_finish) // glFinish(); if (this->gl_surface) { VAStatus vaStatus = vaDestroySurfaceGLX(va_context->va_display, this->gl_surface); vaapi_check_status(this, vaStatus, "vaDestroySurfaceGLX()"); this->gl_surface = NULL; } if(this->gl_context) glXMakeCurrent(this->display, None, NULL); if(this->gl_pixmap) { vaapi_x11_trap_errors(); this->mpglXDestroyPixmap (this->display, this->gl_pixmap); XSync(this->display, False); if (vaapi_x11_untrap_errors()) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_destroy_glx : mpglXDestroyPixmap failed\n"); this->gl_pixmap = None; } if(this->gl_image_pixmap) { XFreePixmap(this->display, this->gl_image_pixmap); this->gl_image_pixmap = None; } if(this->gl_texture) { glDeleteTextures(1, &this->gl_texture); this->gl_texture = GL_NONE; } if(this->gl_context) { glXDestroyContext(this->display, this->gl_context); this->gl_context = NULL; } } static GLXFBConfig *get_fbconfig_for_depth(vaapi_driver_t *this, int depth) { GLXFBConfig *fbconfigs, *ret = NULL; int n_elements, i, found; int db, stencil, alpha, rgba, value; static GLXFBConfig *cached_config = NULL; static int have_cached_config = 0; if (have_cached_config) return cached_config; fbconfigs = glXGetFBConfigs(this->display, this->screen, &n_elements); db = SHRT_MAX; stencil = SHRT_MAX; rgba = 0; found = n_elements; for (i = 0; i < n_elements; i++) { XVisualInfo *vi; int visual_depth; vi = glXGetVisualFromFBConfig(this->display, fbconfigs[i]); if (!vi) continue; visual_depth = vi->depth; XFree(vi); vi = NULL; if (visual_depth != depth) continue; glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_ALPHA_SIZE, &alpha); glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_BUFFER_SIZE, &value); if (value != depth && (value - alpha) != depth) continue; value = 0; if (depth == 32) { glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_BIND_TO_TEXTURE_RGBA_EXT, &value); if (value) rgba = 1; } if (!value) { if (rgba) continue; glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_BIND_TO_TEXTURE_RGB_EXT, &value); if (!value) continue; } glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_DOUBLEBUFFER, &value); if (value > db) continue; db = value; glXGetFBConfigAttrib(this->display, fbconfigs[i], GLX_STENCIL_SIZE, &value); if (value > stencil) continue; stencil = value; found = i; } if (found != n_elements) { ret = malloc(sizeof(*ret)); *ret = fbconfigs[found]; } if (n_elements) XFree(fbconfigs); have_cached_config = 1; cached_config = ret; return ret; } static int vaapi_glx_config_tfp(vaapi_driver_t *this, unsigned int width, unsigned int height) { GLXFBConfig *fbconfig; int attribs[7], i = 0; const int depth = 24; if (!this->mpglXBindTexImage || !this->mpglXReleaseTexImage) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : No GLX texture-from-pixmap extension available\n"); return 0; } if (depth != 24 && depth != 32) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : colour depth wrong.\n"); return 0; } this->gl_image_pixmap = XCreatePixmap(this->display, this->window, width, height, depth); if (!this->gl_image_pixmap) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : Could not create X11 pixmap\n"); return 0; } fbconfig = get_fbconfig_for_depth(this, depth); if (!fbconfig) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : Could not find an FBConfig for 32-bit pixmap\n"); return 0; } attribs[i++] = GLX_TEXTURE_TARGET_EXT; attribs[i++] = GLX_TEXTURE_2D_EXT; attribs[i++] = GLX_TEXTURE_FORMAT_EXT; if (depth == 24) attribs[i++] = GLX_TEXTURE_FORMAT_RGB_EXT; else if (depth == 32) attribs[i++] = GLX_TEXTURE_FORMAT_RGBA_EXT; attribs[i++] = GLX_MIPMAP_TEXTURE_EXT; attribs[i++] = GL_FALSE; attribs[i++] = None; vaapi_x11_trap_errors(); this->gl_pixmap = this->mpglXCreatePixmap(this->display, *fbconfig, this->gl_image_pixmap, attribs); XSync(this->display, False); if (vaapi_x11_untrap_errors()) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_tfp : Could not create GLX pixmap\n"); return 0; } return 1; } static int vaapi_glx_config_glx (vaapi_driver_t *this, unsigned int width, unsigned int height) { ff_vaapi_context_t *va_context = this->va_context; int gl_visual_attr[] = VAAPI_GLX_VISUAL_ATTR; XVisualInfo *gl_vinfo; gl_vinfo = glXChooseVisual(this->display, this->screen, gl_visual_attr); if(!gl_vinfo) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : error glXChooseVisual\n"); this->opengl_render = 0; } do { void *(*getProcAddress) (const GLubyte *); const char *(*glXExtStr) (Display *, int); char *glxstr; size_t slen; glXMakeCurrent (this->display, None, NULL); this->gl_context = glXCreateContext (this->display, gl_vinfo, NULL, True); XFree (gl_vinfo); gl_vinfo = NULL; if (this->gl_context) { if (!glXMakeCurrent (this->display, this->window, this->gl_context)) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : error glXMakeCurrent\n"); break; } } else { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : error glXCreateContext\n"); break; } glxstr = strdup (" "); slen = 0; getProcAddress = vaapi_getdladdr ("glXGetProcAddress"); if (!getProcAddress) getProcAddress = vaapi_getdladdr ("glXGetProcAddressARB"); glXExtStr = vaapi_getdladdr ("glXQueryExtensionsString"); if (glXExtStr) vaapi_appendstr (&glxstr, &slen, glXExtStr (this->display, this->screen)); glXExtStr = vaapi_getdladdr ("glXGetClientString"); if (glXExtStr) vaapi_appendstr (&glxstr, &slen, glXExtStr (this->display, GLX_EXTENSIONS)); glXExtStr = vaapi_getdladdr ("glXGetServerString"); if (glXExtStr) vaapi_appendstr (&glxstr, &slen, glXExtStr(this->display, GLX_EXTENSIONS)); vaapi_get_functions (this, getProcAddress, glxstr); if (!this->mpglGenPrograms && this->mpglGetString && getProcAddress && strstr (this->mpglGetString (GL_EXTENSIONS), "GL_ARB_vertex_program")) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : Broken glXGetProcAddress detected, trying workaround\n"); vaapi_get_functions (this, NULL, glxstr); } free (glxstr); glxstr = NULL; glDisable (GL_DEPTH_TEST); glDepthMask (GL_FALSE); glDisable (GL_CULL_FACE); glEnable (GL_TEXTURE_2D); glDrawBuffer (GL_BACK); glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); /* Create TFP resources */ if (this->opengl_use_tfp && vaapi_glx_config_tfp (this, width, height)) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : Using GLX texture-from-pixmap extension\n"); } else { this->opengl_use_tfp = 0; } /* Create OpenGL texture */ /* XXX: assume GL_ARB_texture_non_power_of_two is available */ glEnable (GL_TEXTURE_2D); glGenTextures (1, &this->gl_texture); this->mpglBindTexture (GL_TEXTURE_2D, this->gl_texture); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (!this->opengl_use_tfp) { glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glPixelStorei (GL_UNPACK_ALIGNMENT, 4); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL); } this->mpglBindTexture (GL_TEXTURE_2D, 0); glDisable (GL_TEXTURE_2D); glClearColor (0.0, 0.0, 0.0, 1.0); glClear (GL_COLOR_BUFFER_BIT); if (!this->gl_texture) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_glx_config_glx : gl_texture NULL\n"); break; } if (!this->opengl_use_tfp) { VAStatus vaStatus = vaCreateSurfaceGLX (va_context->va_display, GL_TEXTURE_2D, this->gl_texture, &this->gl_surface); if (!vaapi_check_status (this, vaStatus, "vaCreateSurfaceGLX()")) { this->gl_surface = NULL; break; } } else { this->gl_surface = NULL; } lprintf ("vaapi_glx_config_glx : GL setup done\n"); return 1; } while (0); destroy_glx (this); return 0; } #endif /* ENABLE_VA_GLX */ static uint32_t vaapi_get_capabilities (vo_driver_t *this_gen) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; return this->capabilities; } /* Init subpicture */ static void vaapi_init_subpicture(vaapi_driver_t *this) { this->va_subpic_width = 0; this->va_subpic_height = 0; this->va_subpic_id = VA_INVALID_ID; this->va_subpic_image.image_id = VA_INVALID_ID; this->overlay_output_width = this->overlay_output_height = 0; this->ovl_changed = 0; this->has_overlay = 0; this->overlay_bitmap = NULL; this->overlay_bitmap_size = 0; this->bgra_subpic_format.fourcc = 0; this->bgra_subpic_flags = 0; } /* Close vaapi */ static void vaapi_close(vaapi_driver_t *this) { ff_vaapi_context_t *va_context = this->va_context; if(!va_context || !va_context->va_display || !va_context->valid_context) return; vaapi_ovl_associate(this, 0, 0); #ifdef ENABLE_VA_GLX destroy_glx(this); #endif vaapi_destroy_subpicture(this); vaapi_destroy_soft_surfaces(this); _x_va_close(this->va); } /* Deassociate and free subpicture */ static void vaapi_destroy_subpicture(vaapi_driver_t *this) { ff_vaapi_context_t *va_context = this->va_context; VAStatus vaStatus; lprintf("destroy sub 0x%08x 0x%08x 0x%08x\n", this->va_subpic_id, this->va_subpic_image.image_id, this->va_subpic_image.buf); if (this->va_subpic_id != VA_INVALID_ID) { vaStatus = vaDestroySubpicture(va_context->va_display, this->va_subpic_id); vaapi_check_status(this, vaStatus, "vaDestroySubpicture()"); } this->va_subpic_id = VA_INVALID_ID; _x_va_destroy_image(this->va, &this->va_subpic_image); } /* Create VAAPI subpicture */ static VAStatus vaapi_create_subpicture(vaapi_driver_t *this, int width, int height) { do { ff_vaapi_context_t *va_context = this->va_context; void *p_base = NULL; VAStatus vaStatus; if (!va_context->valid_context || !this->bgra_subpic_format.fourcc) return VA_STATUS_ERROR_UNKNOWN; vaStatus = vaCreateImage (va_context->va_display, &this->bgra_subpic_format, width, height, &this->va_subpic_image); if (!vaapi_check_status (this, vaStatus, "vaCreateImage()")) break; vaStatus = vaCreateSubpicture (va_context->va_display, this->va_subpic_image.image_id, &this->va_subpic_id); if (!vaapi_check_status (this, vaStatus, "vaCreateSubpicture()")) break; if ((this->va_subpic_image.image_id == VA_INVALID_ID) || (this->va_subpic_id == VA_INVALID_ID)) break; lprintf ("create sub 0x%08x 0x%08x 0x%08x\n", this->va_subpic_id, this->va_subpic_image.image_id, this->va_subpic_image.buf); vaStatus = vaMapBuffer(va_context->va_display, this->va_subpic_image.buf, &p_base); if (!vaapi_check_status(this, vaStatus, "vaMapBuffer()")) break; memset ((uint32_t *)p_base, 0x0, this->va_subpic_image.data_size); vaStatus = vaUnmapBuffer(va_context->va_display, this->va_subpic_image.buf); vaapi_check_status (this, vaStatus, "vaUnmapBuffer()"); this->overlay_output_width = width; this->overlay_output_height = height; lprintf ("vaapi_create_subpicture 0x%08x format %s\n", this->va_subpic_image.image_id, string_of_VAImageFormat(&this->va_subpic_image.format)); return VA_STATUS_SUCCESS; } while (0); /* house keeping */ if (this->va_subpic_id != VA_INVALID_ID) vaapi_destroy_subpicture(this); this->va_subpic_id = VA_INVALID_ID; _x_va_destroy_image (this->va, &this->va_subpic_image); this->overlay_output_width = 0; this->overlay_output_height = 0; return VA_STATUS_ERROR_UNKNOWN; } static void vaapi_set_csc_mode(vaapi_driver_t *this, int new_mode) { if (new_mode == CSC_MODE_USER_MATRIX) { this->capabilities |= VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_HUE | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE; } else { this->capabilities &= ~(VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST | VO_CAP_SATURATION | VO_CAP_HUE | VO_CAP_COLOR_MATRIX | VO_CAP_FULLRANGE); if (this->props[VO_PROP_BRIGHTNESS].atom) this->capabilities |= VO_CAP_BRIGHTNESS; if (this->props[VO_PROP_CONTRAST].atom) this->capabilities |= VO_CAP_CONTRAST; if (this->props[VO_PROP_SATURATION].atom) this->capabilities |= VO_CAP_SATURATION; if (this->props[VO_PROP_HUE].atom) this->capabilities |= VO_CAP_HUE; #if (defined VA_SRC_BT601) && ((defined VA_SRC_BT709) || (defined VA_SRC_SMPTE_240)) this->capabilities |= VO_CAP_COLOR_MATRIX; #endif if (new_mode != CSC_MODE_FLAGS) { if ((this->capabilities & (VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST)) == (VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST)) this->capabilities |= VO_CAP_FULLRANGE; } } this->csc_mode = new_mode; this->color_matrix = 0; } static const char * const vaapi_csc_mode_labels[] = { "user_matrix", "simple", "simple+2", "simple+3", NULL }; /* normalize to 0.0 ~ 2.0 */ static float vaapi_normalized_prop (vaapi_driver_t *this, int prop) { int range = (this->props[prop].max - this->props[prop].min) >> 1; if (range) return (float)(this->props[prop].value - this->props[prop].min) / (float)range; return 1.0; } static void vaapi_update_csc (vaapi_driver_t *that, mem_frame_t *frame) { int color_matrix; int i; color_matrix = cm_from_frame (&frame->vo_frame); if (that->color_matrix != color_matrix) { /* revert unsupported modes */ i = that->csc_mode; if (i == CSC_MODE_USER_MATRIX && !that->have_user_csc_matrix) i = CSC_MODE_FLAGS_FULLRANGE3; if (i == CSC_MODE_FLAGS_FULLRANGE3 && !that->props[VO_PROP_SATURATION].atom) i = CSC_MODE_FLAGS_FULLRANGE2; if (i == CSC_MODE_FLAGS_FULLRANGE2 && !that->props[VO_PROP_BRIGHTNESS].atom) i = CSC_MODE_FLAGS; if (i != that->csc_mode) { xprintf (that->xine, XINE_VERBOSITY_LOG, _("video_out_vaapi: driver does not support \"%s\" colourspace conversion mode\n"), vaapi_csc_mode_labels[that->csc_mode]); vaapi_set_csc_mode (that, i); } that->color_matrix = color_matrix; if (that->csc_mode == CSC_MODE_USER_MATRIX) { /* WOW - full support */ float hue = (vaapi_normalized_prop (that, VO_PROP_HUE) - 1.0) * M_PI; float saturation = vaapi_normalized_prop (that, VO_PROP_SATURATION); float contrast = vaapi_normalized_prop (that, VO_PROP_CONTRAST); float brightness = (vaapi_normalized_prop (that, VO_PROP_BRIGHTNESS) - 1.0) * 128.0; float *matrix = that->user_csc_matrix; VADisplayAttribute attr; cm_fill_matrix(matrix, color_matrix, hue, saturation, contrast, brightness); attr.type = VADisplayAttribCSCMatrix; /* libva design bug: VADisplayAttribute.value is plain int. On 64bit system, a pointer value put here will overwrite the following "flags" field too. */ memcpy (&(attr.value), &matrix, sizeof (float *)); vaSetDisplayAttributes (that->va_context->va_display, &attr, 1); xprintf (that->xine, XINE_VERBOSITY_LOG,"video_out_vaapi: b %d c %d s %d h %d [%s]\n", that->props[VO_PROP_BRIGHTNESS].value, that->props[VO_PROP_CONTRAST].value, that->props[VO_PROP_SATURATION].value, that->props[VO_PROP_HUE].value, cm_names[color_matrix]); } else { /* fall back to old style */ int brightness = that->props[VO_PROP_BRIGHTNESS].value; int contrast = that->props[VO_PROP_CONTRAST].value; int saturation = that->props[VO_PROP_SATURATION].value; int hue = that->props[VO_PROP_HUE].value; int i; VADisplayAttribute attr[4]; /* The fallback rhapsody */ #if defined(VA_SRC_BT601) && (defined(VA_SRC_BT709) || defined(VA_SRC_SMPTE_240)) i = color_matrix >> 1; switch (i) { case 1: #if defined(VA_SRC_BT709) that->vaapi_cm_flags = VA_SRC_BT709; #elif defined(VA_SRC_SMPTE_240) that->vaapi_cm_flags = VA_SRC_SMPTE_240; i = 7; #endif break; case 7: #if defined(VA_SRC_SMPTE_240) that->vaapi_cm_flags = VA_SRC_SMPTE_240; #elif defined(VA_SRC_BT709) that->vaapi_cm_flags = VA_SRC_BT709; i = 1; #endif break; default: that->vaapi_cm_flags = VA_SRC_BT601; i = 5; } #else that->vaapi_cm_flags = 0; i = 2; /* undefined */ #endif color_matrix &= 1; color_matrix |= i << 1; if ((that->csc_mode != CSC_MODE_FLAGS) && (color_matrix & 1)) { int a, b; /* fullrange mode. XXX assuming TV set style bcs controls 0% - 200% */ if (that->csc_mode == CSC_MODE_FLAGS_FULLRANGE3) { saturation -= that->props[VO_PROP_SATURATION].min; saturation = (saturation * (112 * 255) + (127 * 219 / 2)) / (127 * 219); saturation += that->props[VO_PROP_SATURATION].min; if (saturation > that->props[VO_PROP_SATURATION].max) saturation = that->props[VO_PROP_SATURATION].max; } contrast -= that->props[VO_PROP_CONTRAST].min; contrast = (contrast * 219 + 127) / 255; a = contrast * (that->props[VO_PROP_BRIGHTNESS].max - that->props[VO_PROP_BRIGHTNESS].min); contrast += that->props[VO_PROP_CONTRAST].min; b = 256 * (that->props[VO_PROP_CONTRAST].max - that->props[VO_PROP_CONTRAST].min); brightness += (16 * a + b / 2) / b; if (brightness > that->props[VO_PROP_BRIGHTNESS].max) brightness = that->props[VO_PROP_BRIGHTNESS].max; } i = 0; if (that->props[VO_PROP_BRIGHTNESS].atom) { attr[i].type = that->props[VO_PROP_BRIGHTNESS].type; attr[i].value = brightness; i++; } if (that->props[VO_PROP_CONTRAST].atom) { attr[i].type = that->props[VO_PROP_CONTRAST].type; attr[i].value = contrast; i++; } if (that->props[VO_PROP_SATURATION].atom) { attr[i].type = that->props[VO_PROP_SATURATION].type; attr[i].value = saturation; i++; } if (that->props[VO_PROP_HUE].atom) { attr[i].type = that->props[VO_PROP_HUE].type; attr[i].value = hue; i++; } if (i) vaSetDisplayAttributes (that->va_context->va_display, attr, i); xprintf (that->xine, XINE_VERBOSITY_LOG,"video_out_vaapi: %s b %d c %d s %d h %d [%s]\n", color_matrix & 1 ? "modified" : "", brightness, contrast, saturation, hue, cm_names[color_matrix]); } } } static void vaapi_property_callback (void *property_gen, xine_cfg_entry_t *entry) { va_property_t *property = (va_property_t *) property_gen; vaapi_driver_t *this = property->this; ff_vaapi_context_t *va_context = this->va_context; pthread_mutex_lock(&this->vaapi_lock); LOCK_DISPLAY (this); VADisplayAttribute attr; attr.type = property->type; attr.value = entry->num_value; lprintf("vaapi_property_callback property=%d, value=%d\n", property->type, entry->num_value ); /*VAStatus vaStatus = */ vaSetDisplayAttributes(va_context->va_display, &attr, 1); //vaapi_check_status(this, vaStatus, "vaSetDisplayAttributes()"); UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); } /* called xlocked */ static void vaapi_check_capability (vaapi_driver_t *this, int property, VADisplayAttribute attr, const char *config_name, const char *config_desc, const char *config_help) { config_values_t *config = this->xine->config; int int_default = 0; cfg_entry_t *entry; this->props[property].type = attr.type; this->props[property].min = attr.min_value; this->props[property].max = attr.max_value; int_default = attr.value; this->props[property].atom = 1; if (config_name) { /* is this a boolean property ? */ if ((attr.min_value == 0) && (attr.max_value == 1)) { config->register_bool (config, config_name, int_default, config_desc, config_help, 20, vaapi_property_callback, &this->props[property]); } else { config->register_range (config, config_name, int_default, this->props[property].min, this->props[property].max, config_desc, config_help, 20, vaapi_property_callback, &this->props[property]); } entry = config->lookup_entry (config, config_name); if((entry->num_value < this->props[property].min) || (entry->num_value > this->props[property].max)) { config->update_num(config, config_name, ((this->props[property].min + this->props[property].max) >> 1)); entry = config->lookup_entry (config, config_name); } this->props[property].entry = entry; vaapi_set_property(&this->vo_driver, property, entry->num_value); } else { this->props[property].value = int_default; } } /* VAAPI display attributes. */ static void vaapi_display_attribs(vaapi_driver_t *this) { ff_vaapi_context_t *va_context = this->va_context; int num_display_attrs, max_display_attrs; VAStatus vaStatus; VADisplayAttribute *display_attrs; int i; max_display_attrs = vaMaxNumDisplayAttributes(va_context->va_display); display_attrs = calloc(max_display_attrs, sizeof(*display_attrs)); if (display_attrs) { num_display_attrs = 0; vaStatus = vaQueryDisplayAttributes(va_context->va_display, display_attrs, &num_display_attrs); if(vaapi_check_status(this, vaStatus, "vaQueryDisplayAttributes()")) { for (i = 0; i < num_display_attrs; i++) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_vaapi: display attribute #%d = %d [%d .. %d], flags %d\n", (int)display_attrs[i].type, display_attrs[i].value, display_attrs[i].min_value, display_attrs[i].max_value, display_attrs[i].flags); switch (display_attrs[i].type) { case VADisplayAttribBrightness: if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) && ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) { this->capabilities |= VO_CAP_BRIGHTNESS; vaapi_check_capability(this, VO_PROP_BRIGHTNESS, display_attrs[i], "video.output.vaapi_brightness", "Brightness setting", "Brightness setting"); } break; case VADisplayAttribContrast: if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) && ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) { this->capabilities |= VO_CAP_CONTRAST; vaapi_check_capability(this, VO_PROP_CONTRAST, display_attrs[i], "video.output.vaapi_contrast", "Contrast setting", "Contrast setting"); } break; case VADisplayAttribHue: if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) && ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) { this->capabilities |= VO_CAP_HUE; vaapi_check_capability(this, VO_PROP_HUE, display_attrs[i], "video.output.vaapi_hue", "Hue setting", "Hue setting"); } break; case VADisplayAttribSaturation: if( ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_GETTABLE ) && ( display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE ) ) { this->capabilities |= VO_CAP_SATURATION; vaapi_check_capability(this, VO_PROP_SATURATION, display_attrs[i], "video.output.vaapi_saturation", "Saturation setting", "Saturation setting"); } break; case VADisplayAttribCSCMatrix: if (display_attrs[i].flags & VA_DISPLAY_ATTRIB_SETTABLE) { this->have_user_csc_matrix = 1; } break; default: break; } } } free(display_attrs); display_attrs = NULL; } if (this->have_user_csc_matrix) { /* make sure video eq is full usable for user matrix mode */ if (!this->props[VO_PROP_BRIGHTNESS].atom) { this->props[VO_PROP_BRIGHTNESS].min = -1000; this->props[VO_PROP_BRIGHTNESS].max = 1000; this->props[VO_PROP_BRIGHTNESS].value = 0; } if (!this->props[VO_PROP_CONTRAST].atom) { this->props[VO_PROP_CONTRAST].min = this->props[VO_PROP_BRIGHTNESS].min; this->props[VO_PROP_CONTRAST].max = this->props[VO_PROP_BRIGHTNESS].max; this->props[VO_PROP_CONTRAST].value = (this->props[VO_PROP_CONTRAST].max - this->props[VO_PROP_CONTRAST].min) >> 1; } if (!this->props[VO_PROP_SATURATION].atom) { this->props[VO_PROP_SATURATION].min = this->props[VO_PROP_CONTRAST].min; this->props[VO_PROP_SATURATION].max = this->props[VO_PROP_CONTRAST].max; this->props[VO_PROP_SATURATION].value = (this->props[VO_PROP_CONTRAST].max - this->props[VO_PROP_CONTRAST].min) >> 1; } if (!this->props[VO_PROP_HUE].atom) { this->props[VO_PROP_HUE].min = this->props[VO_PROP_BRIGHTNESS].min; this->props[VO_PROP_HUE].max = this->props[VO_PROP_BRIGHTNESS].max; this->props[VO_PROP_HUE].value = (this->props[VO_PROP_BRIGHTNESS].max - this->props[VO_PROP_BRIGHTNESS].min) >> 1; } } } static void vaapi_set_background_color(vaapi_driver_t *this) { ff_vaapi_context_t *va_context = this->va_context; //VAStatus vaStatus; if(!va_context->valid_context) return; VADisplayAttribute attr; memset( &attr, 0, sizeof(attr) ); attr.type = VADisplayAttribBackgroundColor; attr.value = 0x000000; /*vaStatus =*/ vaSetDisplayAttributes(va_context->va_display, &attr, 1); //vaapi_check_status(this, vaStatus, "vaSetDisplayAttributes()"); } static VAStatus vaapi_destroy_soft_surfaces(vaapi_driver_t *this) { ff_vaapi_context_t *va_context = this->va_context; int i; VAStatus vaStatus; for(i = 0; i < SOFT_SURFACES; i++) { if (this->va_soft_images[i].image_id != VA_INVALID_ID) _x_va_destroy_image(this->va, &this->va_soft_images[i]); this->va_soft_images[i].image_id = VA_INVALID_ID; if (this->va_soft_surface_ids[i] != VA_INVALID_SURFACE) { #ifdef DEBUG_SURFACE printf("vaapi_close destroy render surface 0x%08x\n", this->va_soft_surface_ids[i]); #endif vaStatus = vaSyncSurface(va_context->va_display, this->va_soft_surface_ids[i]); vaapi_check_status(this, vaStatus, "vaSyncSurface()"); vaStatus = vaDestroySurfaces(va_context->va_display, &this->va_soft_surface_ids[i], 1); vaapi_check_status(this, vaStatus, "vaDestroySurfaces()"); this->va_soft_surface_ids[i] = VA_INVALID_SURFACE; } } this->sw_width = 0; this->sw_height = 0; return VA_STATUS_SUCCESS; } static VAStatus vaapi_init_soft_surfaces(vaapi_driver_t *this, int width, int height) { vaapi_destroy_soft_surfaces(this); do { ff_vaapi_context_t *va_context = this->va_context; VAStatus vaStatus; int i; vaStatus = vaCreateSurfaces (va_context->va_display, VA_RT_FORMAT_YUV420, width, height, this->va_soft_surface_ids, SOFT_SURFACES, NULL, 0); if (!vaapi_check_status (this, vaStatus, "vaCreateSurfaces()")) break; /* allocate software surfaces */ for (i = 0; i < SOFT_SURFACES; i++) { vaStatus = _x_va_create_image (this->va, this->va_soft_surface_ids[i], &this->va_soft_images[i], width, height, 1, &this->soft_image_is_bound); if (!vaapi_check_status(this, vaStatus, "_x_va_create_image()")) { this->va_soft_images[i].image_id = VA_INVALID_ID; break; } if (!this->soft_image_is_bound) { vaStatus = vaPutImage (va_context->va_display, this->va_soft_surface_ids[i], this->va_soft_images[i].image_id, 0, 0, this->va_soft_images[i].width, this->va_soft_images[i].height, 0, 0, this->va_soft_images[i].width, this->va_soft_images[i].height); vaapi_check_status (this, vaStatus, "vaPutImage()"); } #ifdef DEBUG_SURFACE printf("vaapi_init_soft_surfaces 0x%08x\n", this->va_soft_surface_ids[i]); #endif } if (i < SOFT_SURFACES) break; this->sw_width = width; this->sw_height = height; this->va_soft_head = 0; return VA_STATUS_SUCCESS; } while (0); this->sw_width = 0; this->sw_height = 0; vaapi_destroy_soft_surfaces (this); return VA_STATUS_ERROR_UNKNOWN; } static int _flush_recent_frames (vaapi_driver_t *this) { int i, n = 0; for (i = 0; i < VO_NUM_RECENT_FRAMES; i++) { if (this->recent_frames[i]) { if (this->guarded_render && this->recent_frames[i]->format == XINE_IMGFMT_VAAPI) _x_va_frame_displayed(this->recent_frames[i]); this->recent_frames[i]->free (this->recent_frames[i]); this->recent_frames[i] = NULL; n++; } } return n; } static VAStatus vaapi_init_internal(vaapi_driver_t *this, int va_profile, int width, int height) { VAStatus vaStatus; vaapi_close(this); _flush_recent_frames (this); vaStatus = _x_va_init(this->va, va_profile, width, height); if (vaStatus != VA_STATUS_SUCCESS) goto error; #if 0 int i; for(i = 0; i < RENDER_SURFACES; i++) { if(this->va->frames[i]) { /* this seems to break decoding to the surface ? */ VAImage va_image; int is_bound; vaStatus = _x_va_create_image(this->va, va_context->va_surface_ids[i], &va_image, width, height, 1, &is_bound); if (vaapi_check_status(this, vaStatus, "_x_va_create_image()") && !is_bound) { vaStatus = vaPutImage(va_context->va_display, va_context->va_surface_ids[i], va_image.image_id, 0, 0, va_image.width, va_image.height, 0, 0, va_image.width, va_image.height); _x_va_destroy_image(this->va, &va_image); } } #ifdef DEBUG_SURFACE printf("vaapi_init_internal 0x%08x\n", va_context->va_surface_ids[i]); #endif } #endif vaStatus = vaapi_init_soft_surfaces(this, width, height); if(!vaapi_check_status(this, vaStatus, "vaapi_init_soft_surfaces()")) { vaapi_destroy_soft_surfaces(this); goto error; } xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : guarded render : %d\n", this->guarded_render); #ifdef ENABLE_VA_GLX xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : glxrender : %d\n", this->opengl_render); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : glxrender tfp : %d\n", this->opengl_use_tfp); #endif //xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : is_bound : %d\n", this->is_bound); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : scaling level : name %s value 0x%08x\n", scaling_level_enum_names[this->scaling_level_enum], this->scaling_level); #ifdef ENABLE_VA_GLX this->init_opengl_render = 1; #endif return VA_STATUS_SUCCESS; error: vaapi_close(this); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_init : error init vaapi\n"); return VA_STATUS_ERROR_UNKNOWN; } /* * Init VAAPI. This function is called from the decoder side. * When the decoder uses software decoding vaapi_init is not called. * Therefore we do it in vaapi_display_frame to get a valid VAAPI context */ static VAStatus vaapi_init(vo_frame_t *frame_gen, int va_profile, int width, int height) { if(!frame_gen) return VA_STATUS_ERROR_UNKNOWN; vaapi_driver_t *this = (vaapi_driver_t *) frame_gen->driver; VAStatus vaStatus; unsigned int last_sub_img_fmt = this->last_sub_image_fmt; if(last_sub_img_fmt) vaapi_ovl_associate(this, frame_gen->format, 0); if(!this->guarded_render) { pthread_mutex_lock(&this->vaapi_lock); LOCK_DISPLAY (this); } vaStatus = vaapi_init_internal(this, va_profile, width, height); if(!this->guarded_render) { UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); } if(last_sub_img_fmt) vaapi_ovl_associate(this, frame_gen->format, this->has_overlay); return vaStatus; } static vo_frame_t *vaapi_alloc_frame (vo_driver_t *this_gen) { vaapi_driver_t *this = xine_container_of(this_gen, vaapi_driver_t, vo_driver); vaapi_frame_t *frame; static const struct vaapi_accel_funcs_s accel_funcs = { .vaapi_init = vaapi_init, .profile_from_imgfmt = _x_va_accel_profile_from_imgfmt, .get_context = _x_va_accel_get_context, .lock_vaapi = _x_va_accel_lock_decode_dummy, .unlock_vaapi = NULL, .get_vaapi_surface = _x_va_accel_get_vaapi_surface, .render_vaapi_surface = NULL, .release_vaapi_surface = NULL, .guarded_render = _x_va_accel_guarded_render, }; static const struct vaapi_accel_funcs_s accel_funcs_guarded = { .vaapi_init = vaapi_init, .profile_from_imgfmt = _x_va_accel_profile_from_imgfmt, .get_context = _x_va_accel_get_context, .lock_vaapi = vaapi_lock_decode_guarded, .unlock_vaapi = vaapi_unlock_decode_guarded, .get_vaapi_surface = _x_va_accel_alloc_vaapi_surface, .render_vaapi_surface = _x_va_accel_render_vaapi_surface, .release_vaapi_surface = _x_va_accel_release_vaapi_surface, .guarded_render = _x_va_accel_guarded_render, }; frame = _x_va_frame_alloc_frame(this->va, this_gen, this->guarded_render); if (!frame) return NULL; /* override accel functions */ frame->vaapi_accel_data.f = this->guarded_render ? &accel_funcs_guarded : &accel_funcs; lprintf("alloc frame\n"); return &frame->mem_frame.vo_frame; } /* Display OSD */ static int vaapi_ovl_associate(vaapi_driver_t *this, int format, int bShow) { ff_vaapi_context_t *va_context = this->va_context; VAStatus vaStatus; if (!va_context->valid_context) return 0; if (this->last_sub_image_fmt && !bShow) { if (this->va_subpic_id != VA_INVALID_ID) { if (this->last_sub_image_fmt == XINE_IMGFMT_VAAPI) { vaStatus = vaDeassociateSubpicture(va_context->va_display, this->va_subpic_id, va_context->va_surface_ids, RENDER_SURFACES); vaapi_check_status(this, vaStatus, "vaDeassociateSubpicture()"); } else if (this->last_sub_image_fmt == XINE_IMGFMT_YV12 || this->last_sub_image_fmt == XINE_IMGFMT_YUY2) { vaStatus = vaDeassociateSubpicture(va_context->va_display, this->va_subpic_id, this->va_soft_surface_ids, SOFT_SURFACES); vaapi_check_status(this, vaStatus, "vaDeassociateSubpicture()"); } } this->last_sub_image_fmt = 0; return 1; } if (!this->last_sub_image_fmt && bShow) { unsigned int flags = 0; unsigned int output_width = va_context->width; unsigned int output_height = va_context->height; unsigned char *p_dest; uint32_t *p_src; void *p_base = NULL; VAStatus vaStatus; uint32_t i; vaapi_destroy_subpicture(this); vaStatus = vaapi_create_subpicture(this, this->overlay_bitmap_width, this->overlay_bitmap_height); if(!vaapi_check_status(this, vaStatus, "vaapi_create_subpicture()")) return 0; vaStatus = vaMapBuffer(va_context->va_display, this->va_subpic_image.buf, &p_base); if(!vaapi_check_status(this, vaStatus, "vaMapBuffer()")) return 0; p_src = this->overlay_bitmap; p_dest = p_base; for (i = 0; i < this->overlay_bitmap_height; i++) { xine_fast_memcpy(p_dest, p_src, this->overlay_bitmap_width * sizeof(uint32_t)); p_dest += this->va_subpic_image.pitches[0]; p_src += this->overlay_bitmap_width; } vaStatus = vaUnmapBuffer(va_context->va_display, this->va_subpic_image.buf); vaapi_check_status(this, vaStatus, "vaUnmapBuffer()"); lprintf( "vaapi_ovl_associate: overlay_width=%d overlay_height=%d unscaled %d va_subpic_id 0x%08x ovl_changed %d has_overlay %d bShow %d overlay_bitmap_width %d overlay_bitmap_height %d va_context->width %d va_context->height %d\n", this->overlay_output_width, this->overlay_output_height, this->has_overlay, this->va_subpic_id, this->ovl_changed, this->has_overlay, bShow, this->overlay_bitmap_width, this->overlay_bitmap_height, va_context->width, va_context->height); if(format == XINE_IMGFMT_VAAPI) { lprintf("vaapi_ovl_associate hw\n"); vaStatus = vaAssociateSubpicture(va_context->va_display, this->va_subpic_id, va_context->va_surface_ids, RENDER_SURFACES, 0, 0, this->va_subpic_image.width, this->va_subpic_image.height, 0, 0, output_width, output_height, flags); } else { lprintf("vaapi_ovl_associate sw\n"); vaStatus = vaAssociateSubpicture(va_context->va_display, this->va_subpic_id, this->va_soft_surface_ids, SOFT_SURFACES, 0, 0, this->va_subpic_image.width, this->va_subpic_image.height, 0, 0, this->va_soft_images[0].width, this->va_soft_images[0].height, flags); } if(vaapi_check_status(this, vaStatus, "vaAssociateSubpicture()")) { this->last_sub_image_fmt = format; return 1; } } return 0; } static void vaapi_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; ff_vaapi_context_t *va_context = this->va_context; if ( !changed ) return; this->has_overlay = 0; ++this->ovl_changed; /* Apply OSD layer. */ if(va_context->valid_context) { lprintf("vaapi_overlay_begin chaned %d\n", changed); pthread_mutex_lock(&this->vaapi_lock); LOCK_DISPLAY (this); vaapi_ovl_associate(this, frame_gen->format, this->has_overlay); UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); } } static void vaapi_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; int i = this->ovl_changed; (void)frame_gen; if (!i) return; if (--i >= XINE_VORAW_MAX_OVL) return; if (overlay->width <= 0 || overlay->height <= 0 || (!overlay->rle && (!overlay->argb_layer || !overlay->argb_layer->buffer))) return; if (overlay->rle) lprintf("overlay[%d] rle %s%s %dx%d@%d,%d hili rect %d,%d-%d,%d\n", i, overlay->unscaled ? " unscaled ": " scaled ", (overlay->rgb_clut > 0 || overlay->hili_rgb_clut > 0) ? " rgb ": " ycbcr ", overlay->width, overlay->height, overlay->x, overlay->y, overlay->hili_left, overlay->hili_top, overlay->hili_right, overlay->hili_bottom); if (overlay->argb_layer && overlay->argb_layer->buffer) lprintf("overlay[%d] argb %s %dx%d@%d,%d dirty rect %d,%d-%d,%d\n", i, overlay->unscaled ? " unscaled ": " scaled ", overlay->width, overlay->height, overlay->x, overlay->y, overlay->argb_layer->x1, overlay->argb_layer->y1, overlay->argb_layer->x2, overlay->argb_layer->y2); this->overlays[i] = overlay; ++this->ovl_changed; } static void _merge_rects(vaapi_rect_t *rect, const vo_overlay_t *ovl) { if (ovl->x < rect->x1) rect->x1 = ovl->x; if (ovl->y < rect->y1) rect->y1 = ovl->y; if ((ovl->x + ovl->width) > rect->x2) rect->x2 = ovl->x + ovl->width; if ((ovl->y + ovl->height) > rect->y2) rect->y2 = ovl->y + ovl->height; } static void vaapi_overlay_end (vo_driver_t *this_gen, vo_frame_t *frame_gen) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; mem_frame_t *frame = xine_container_of(frame_gen, mem_frame_t, vo_frame); ff_vaapi_context_t *va_context = this->va_context; int novls = this->ovl_changed; if (novls < 2) { this->ovl_changed = 0; return; } --novls; uint32_t output_width = frame->width, output_height = frame->height; uint32_t unscaled_width = 0, unscaled_height = 0; vo_overlay_t *first_scaled = NULL, *first_unscaled = NULL; /* calm down compiler */ vaapi_rect_t dirty_rect = { 0, 0, 0, 0}; vaapi_rect_t unscaled_dirty_rect = {0, 0, 0, 0}; int has_rle = 0; int i; for (i = 0; i < novls; ++i) { vo_overlay_t *ovl = this->overlays[i]; if (ovl->rle) has_rle = 1; if (ovl->unscaled) { if (first_unscaled) { _merge_rects(&unscaled_dirty_rect, ovl); } else { first_unscaled = ovl; unscaled_dirty_rect.x1 = ovl->x; unscaled_dirty_rect.y1 = ovl->y; unscaled_dirty_rect.x2 = ovl->x + ovl->width; unscaled_dirty_rect.y2 = ovl->y + ovl->height; } unscaled_width = unscaled_dirty_rect.x2; unscaled_height = unscaled_dirty_rect.y2; } else { if (first_scaled) { _merge_rects(&dirty_rect, ovl); } else { first_scaled = ovl; dirty_rect.x1 = ovl->x; dirty_rect.y1 = ovl->y; dirty_rect.x2 = ovl->x + ovl->width; dirty_rect.y2 = ovl->y + ovl->height; } if (dirty_rect.x2 > (int)output_width) output_width = dirty_rect.x2; if (dirty_rect.y2 > (int)output_height) output_height = dirty_rect.y2; } } int need_init = 0; lprintf("dirty_rect.x1 %d dirty_rect.y1 %d dirty_rect.x2 %d dirty_rect.y2 %d output_width %d output_height %d\n", dirty_rect.x1, dirty_rect.y1, dirty_rect.x2, dirty_rect.y2, output_width, output_height); if (first_scaled) { vaapi_rect_t dest; dest.x1 = first_scaled->x; dest.y1 = first_scaled->y; dest.x2 = first_scaled->x + first_scaled->width; dest.y2 = first_scaled->y + first_scaled->height; if (!RECT_IS_EQ(dest, dirty_rect)) need_init = 1; } int need_unscaled_init = (first_unscaled && (first_unscaled->x != unscaled_dirty_rect.x1 || first_unscaled->y != unscaled_dirty_rect.y1 || (first_unscaled->x + first_unscaled->width) != unscaled_dirty_rect.x2 || (first_unscaled->y + first_unscaled->height) != unscaled_dirty_rect.y2)); if (first_scaled) { this->overlay_output_width = output_width; this->overlay_output_height = output_height; need_init = 1; this->overlay_dirty_rect = dirty_rect; } if (first_unscaled) { need_unscaled_init = 1; } if (has_rle || need_init || need_unscaled_init) { lprintf("has_rle %d need_init %d need_unscaled_init %d unscaled_width %d unscaled_height %d output_width %d output_height %d\n", has_rle, need_init, need_unscaled_init, unscaled_width, unscaled_height, output_width, output_height); if (need_init) { this->overlay_bitmap_width = output_width; this->overlay_bitmap_height = output_height; } #define UMAX(a,b) ((a) > (uint32_t)(b) ? (a) : (uint32_t)(b)) if (need_unscaled_init) { if(this->vdr_osd_width) this->overlay_bitmap_width = UMAX (this->vdr_osd_width, this->sc.gui_width); else this->overlay_bitmap_width = UMAX (unscaled_width, this->sc.gui_width); if(this->vdr_osd_height) this->overlay_bitmap_height = UMAX (this->vdr_osd_height, this->sc.gui_height); else this->overlay_bitmap_height = UMAX (unscaled_height, this->sc.gui_height); } else if (need_init) { if(this->vdr_osd_width) this->overlay_bitmap_width = UMAX (this->vdr_osd_width, this->sc.gui_width); else this->overlay_bitmap_width = UMAX (output_width, this->sc.gui_width); if(this->vdr_osd_height) this->overlay_bitmap_height = UMAX (this->vdr_osd_height, this->sc.gui_height); else this->overlay_bitmap_height = UMAX (output_height, this->sc.gui_height); } } if ((this->overlay_bitmap_width * this->overlay_bitmap_height) > this->overlay_bitmap_size) { this->overlay_bitmap_size = this->overlay_bitmap_width * this->overlay_bitmap_height; free(this->overlay_bitmap); this->overlay_bitmap = calloc( this->overlay_bitmap_size, sizeof(uint32_t)); } else { memset(this->overlay_bitmap, 0x0, this->overlay_bitmap_size * sizeof(uint32_t)); } for (i = 0; i < novls; ++i) { vo_overlay_t *ovl = this->overlays[i]; uint32_t *bitmap = NULL; if (ovl->rle) { if(ovl->width<=0 || ovl->height<=0) continue; if (!ovl->rgb_clut || !ovl->hili_rgb_clut) _x_overlay_clut_yuv2rgb (ovl, this->color_matrix); bitmap = malloc(ovl->width * ovl->height * sizeof(uint32_t)); _x_overlay_to_argb32(ovl, bitmap, ovl->width, "BGRA"); lprintf("width %d height %d\n", ovl->width, ovl->height); } else { pthread_mutex_lock(&ovl->argb_layer->mutex); bitmap = ovl->argb_layer->buffer; } /* Blit overlay to destination */ uint32_t pitch = ovl->width * sizeof(uint32_t); uint32_t *copy_dst = this->overlay_bitmap; uint32_t *copy_src = NULL; uint32_t height = 0; copy_src = bitmap; copy_dst += ovl->y * this->overlay_bitmap_width; lprintf("overlay_bitmap_width %d overlay_bitmap_height %d ovl->x %d ovl->y %d ovl->width %d ovl->height %d width %d height %d\n", this->overlay_bitmap_width, this->overlay_bitmap_height, ovl->x, ovl->y, ovl->width, ovl->height, this->overlay_bitmap_width, this->overlay_bitmap_height); for(height = 0; (int)height < ovl->height; height++) { if((height + ovl->y) >= this->overlay_bitmap_height) break; xine_fast_memcpy(copy_dst + ovl->x, copy_src, pitch); copy_dst += this->overlay_bitmap_width; copy_src += ovl->width; } if (ovl->rle) { free(bitmap); bitmap = NULL; } if (!ovl->rle) pthread_mutex_unlock(&ovl->argb_layer->mutex); } this->ovl_changed = 0; this->has_overlay = (first_scaled != NULL) | (first_unscaled != NULL); lprintf("this->has_overlay %d\n", this->has_overlay); /* Apply OSD layer. */ if(va_context->valid_context) { pthread_mutex_lock(&this->vaapi_lock); LOCK_DISPLAY (this); vaapi_ovl_associate(this, frame_gen->format, this->has_overlay); UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); } } #ifdef ENABLE_VA_GLX #ifndef HAVE_GLU #define gluPerspective myGluPerspective static void myGluPerspective (GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar) { double ymax = zNear * tan(fovy * M_PI / 360.0); double ymin = -ymax; glFrustum (ymin * aspect, ymax * aspect, ymin, ymax, zNear, zFar); } #endif static void vaapi_resize_glx_window (vaapi_driver_t *this, int width, int height) { if (this->gl_context) { glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(FOVY, ASPECT, Z_NEAR, Z_FAR); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(-0.5f, -0.5f, -Z_CAMERA); glScalef(1.0f / (GLfloat)width, -1.0f / (GLfloat)height, 1.0f / (GLfloat)width); glTranslatef(0.0f, -1.0f * (GLfloat)height, 0.0f); } } #endif static int vaapi_redraw_needed (vo_driver_t *this_gen) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; int ret = 0; _x_vo_scale_compute_ideal_size( &this->sc ); if ( _x_vo_scale_redraw_needed( &this->sc ) ) { _x_vo_scale_compute_output_size( &this->sc ); XMoveResizeWindow(this->display, this->window, 0, 0, this->sc.gui_width, this->sc.gui_height); #ifdef ENABLE_VA_GLX vaapi_resize_glx_window(this, this->sc.gui_width, this->sc.gui_height); #endif ret = 1; } if (this->color_matrix == 0) ret = 1; return ret; } static VAStatus vaapi_software_render_frame(vaapi_driver_t *this, mem_frame_t *frame, VAImage *va_image, int is_bound, VASurfaceID va_surface_id) { ff_vaapi_context_t *va_context = this->va_context; void *p_base = NULL; VAStatus vaStatus; if(va_image == NULL || va_image->image_id == VA_INVALID_ID || va_surface_id == VA_INVALID_SURFACE || !va_context->valid_context) return VA_STATUS_ERROR_UNKNOWN; lprintf("vaapi_software_render_frame : va_surface_id 0x%08x va_image.image_id 0x%08x width %d height %d f_width %d f_height %d sw_width %d sw_height %d\n", va_surface_id, va_image->image_id, va_image->width, va_image->height, frame->width, frame->height, this->sw_width, this->sw_height); if(frame->width != va_image->width || frame->height != va_image->height) return VA_STATUS_SUCCESS; vaStatus = vaMapBuffer( va_context->va_display, va_image->buf, &p_base ) ; if(!vaapi_check_status(this, vaStatus, "vaMapBuffer()")) return vaStatus; uint8_t *dst[3] = { NULL, }; uint32_t pitches[3]; if(this->swap_uv_planes) { dst[0] = (uint8_t *)p_base + va_image->offsets[0]; pitches[0] = va_image->pitches[0]; dst[1] = (uint8_t *)p_base + va_image->offsets[1]; pitches[1] = va_image->pitches[1]; dst[2] = (uint8_t *)p_base + va_image->offsets[2]; pitches[2] = va_image->pitches[2]; } else { dst[0] = (uint8_t *)p_base + va_image->offsets[0]; pitches[0] = va_image->pitches[0]; dst[1] = (uint8_t *)p_base + va_image->offsets[2]; pitches[1] = va_image->pitches[1]; dst[2] = (uint8_t *)p_base + va_image->offsets[1]; pitches[2] = va_image->pitches[2]; } /* Copy xine frames into VAAPI images */ if(frame->format == XINE_IMGFMT_YV12) { if (va_image->format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) || va_image->format.fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ) { lprintf("vaapi_software_render_frame yv12 -> yv12 convert\n"); yv12_to_yv12( /* Y */ frame->vo_frame.base[0], frame->vo_frame.pitches[0], dst[0], pitches[0], /* U */ frame->vo_frame.base[1], frame->vo_frame.pitches[1], dst[1], pitches[1], /* V */ frame->vo_frame.base[2], frame->vo_frame.pitches[2], dst[2], pitches[2], /* width x height */ frame->vo_frame.width, frame->vo_frame.height); } else if (va_image->format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' )) { lprintf("vaapi_software_render_frame yv12 -> nv12 convert\n"); _x_yv12_to_nv12(frame->vo_frame.base[0], frame->vo_frame.pitches[0], frame->vo_frame.base[1], frame->vo_frame.pitches[1], frame->vo_frame.base[2], frame->vo_frame.pitches[2], (uint8_t *)p_base + va_image->offsets[0], va_image->pitches[0], (uint8_t *)p_base + va_image->offsets[1], va_image->pitches[1], frame->vo_frame.width, frame->vo_frame.height); } } else if (frame->format == XINE_IMGFMT_YUY2) { if (va_image->format.fourcc == VA_FOURCC( 'Y', 'V', '1', '2' ) || va_image->format.fourcc == VA_FOURCC( 'I', '4', '2', '0' ) ) { lprintf("vaapi_software_render_frame yuy2 -> yv12 convert\n"); yuy2_to_yv12(frame->vo_frame.base[0], frame->vo_frame.pitches[0], dst[0], pitches[0], dst[1], pitches[1], dst[2], pitches[2], frame->vo_frame.width, frame->vo_frame.height); } else if (va_image->format.fourcc == VA_FOURCC( 'N', 'V', '1', '2' )) { lprintf("vaapi_software_render_frame yuy2 -> nv12 convert\n"); _x_yuy2_to_nv12(frame->vo_frame.base[0], frame->vo_frame.pitches[0], (uint8_t *)p_base + va_image->offsets[0], va_image->pitches[0], (uint8_t *)p_base + va_image->offsets[1], va_image->pitches[1], frame->vo_frame.width, frame->vo_frame.height); } } vaStatus = vaUnmapBuffer(va_context->va_display, va_image->buf); if(!vaapi_check_status(this, vaStatus, "vaUnmapBuffer()")) return vaStatus; if (!is_bound) { vaStatus = vaPutImage(va_context->va_display, va_surface_id, va_image->image_id, 0, 0, va_image->width, va_image->height, 0, 0, va_image->width, va_image->height); if(!vaapi_check_status(this, vaStatus, "vaPutImage()")) return vaStatus; } return VA_STATUS_SUCCESS; } static VAStatus vaapi_hardware_render_frame (vaapi_driver_t *this, mem_frame_t *frame, VASurfaceID va_surface_id) { ff_vaapi_context_t *va_context = this->va_context; VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; int i = 0; int interlaced_frame = !frame->vo_frame.progressive_frame; int top_field_first = frame->vo_frame.top_field_first; #if defined(ENABLE_VA_GLX) || defined(LOG) int width, height; if(frame->format == XINE_IMGFMT_VAAPI) { width = va_context->width; height = va_context->height; } else { width = (frame->width > this->sw_width) ? this->sw_width : frame->width; height = (frame->height > this->sw_height) ? this->sw_height : frame->height; } #endif if(!va_context->valid_context || va_surface_id == VA_INVALID_SURFACE) return VA_STATUS_ERROR_UNKNOWN; #ifdef ENABLE_VA_GLX if(this->opengl_render && !this->gl_context) return VA_STATUS_ERROR_UNKNOWN; #endif /* Final VAAPI rendering. The deinterlacing can be controled by xine config.*/ unsigned int deint = this->deinterlace; for(i = 0; i <= !!((deint > 1) && interlaced_frame); i++) { unsigned int flags = (deint && (interlaced_frame) ? (((!!(top_field_first)) ^ i) == 0 ? VA_BOTTOM_FIELD : VA_TOP_FIELD) : VA_FRAME_PICTURE); vaapi_update_csc (this, frame); flags |= this->vaapi_cm_flags; flags |= VA_CLEAR_DRAWABLE; flags |= this->scaling_level; lprintf("Putsrfc srfc 0x%08X flags 0x%08x %dx%d -> %dx%d interlaced %d top_field_first %d\n", va_surface_id, flags, width, height, this->sc.output_width, this->sc.output_height, interlaced_frame, top_field_first); #ifdef ENABLE_VA_GLX if(this->opengl_render) { const char *msg; vaapi_x11_trap_errors(); if(this->opengl_use_tfp) { lprintf("opengl render tfp\n"); vaStatus = vaPutSurface(va_context->va_display, va_surface_id, this->gl_image_pixmap, 0, 0, width, height, 0, 0, width, height, NULL, 0, flags); msg = "vaPutSurface()"; } else { lprintf("opengl render\n"); vaStatus = vaCopySurfaceGLX(va_context->va_display, this->gl_surface, va_surface_id, flags); msg = "vaCopySurfaceGLX()"; } if(vaapi_x11_untrap_errors()) return VA_STATUS_ERROR_UNKNOWN; if(!vaapi_check_status(this, vaStatus, msg)) return vaStatus; vaapi_glx_flip_page(this, frame, 0, 0, va_context->width, va_context->height); } else #endif { vaStatus = vaPutSurface(va_context->va_display, va_surface_id, this->window, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, NULL, 0, flags); if(!vaapi_check_status(this, vaStatus, "vaPutSurface()")) return vaStatus; } // workaround by johns from vdrportal.de usleep(1 * 1000); } return VA_STATUS_SUCCESS; } /* Used in vaapi_display_frame to determine how long displaying a frame takes - if slower than 60fps, print a message */ /* static double timeOfDay() { struct timeval t; gettimeofday( &t, NULL ); return ((double)t.tv_sec) + (((double)t.tv_usec)/1000000.0); } */ static void _add_recent_frame (vaapi_driver_t *this, vo_frame_t *vo_frame) { int i; i = VO_NUM_RECENT_FRAMES-1; if (this->recent_frames[i]) { if (this->guarded_render && this->recent_frames[i]->format == XINE_IMGFMT_VAAPI) _x_va_frame_displayed(this->recent_frames[i]); this->recent_frames[i]->free (this->recent_frames[i]); } for( ; i ; i-- ) this->recent_frames[i] = this->recent_frames[i-1]; this->recent_frames[0] = vo_frame; } static void vaapi_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; vaapi_accel_t *accel = frame_gen->accel_data; mem_frame_t *frame = xine_container_of(frame_gen, mem_frame_t, vo_frame); ff_vaapi_context_t *va_context = this->va_context; VASurfaceID va_surface_id = VA_INVALID_SURFACE; VAImage *va_image = NULL; VAStatus vaStatus; lprintf("vaapi_display_frame\n"); if (frame->format != XINE_IMGFMT_VAAPI && frame->format != XINE_IMGFMT_YV12 && frame->format != XINE_IMGFMT_YUY2) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " unsupported image format %x width %d height %d valid_context %d\n", frame->format, frame->width, frame->height, va_context->valid_context); frame_gen->free (frame_gen); return; } /* if((frame->height < 17 || frame->width < 17) && ((frame->format == XINE_IMGFMT_YV12) || (frame->format == XINE_IMGFMT_YUY2))) { frame->vo_frame.free( frame_gen ); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " frame size to small width %d height %d\n", frame->height, frame->width); return; } */ /* * let's see if this frame is different in size / aspect * ratio from the previous one */ pthread_mutex_lock(&this->vaapi_lock); LOCK_DISPLAY (this); if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) || (frame->vo_frame.crop_left != this->sc.crop_left) || (frame->vo_frame.crop_right != this->sc.crop_right) || (frame->vo_frame.crop_top != this->sc.crop_top) || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) { lprintf("frame format changed\n"); this->sc.force_redraw = 1; } /* * tell gui that we are about to display a frame, * ask for offset and output size */ this->sc.delivered_height = frame->height; this->sc.delivered_width = frame->width; this->sc.delivered_ratio = frame->ratio; this->sc.crop_left = frame->vo_frame.crop_left; this->sc.crop_right = frame->vo_frame.crop_right; this->sc.crop_top = frame->vo_frame.crop_top; this->sc.crop_bottom = frame->vo_frame.crop_bottom; lprintf("vaapi_display_frame %s frame->width %d frame->height %d va_context->sw_width %d va_context->sw_height %d valid_context %d\n", (frame->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((frame->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2") , frame->width, frame->height, this->sw_width, this->sw_height, va_context->valid_context); if( ((frame->format == XINE_IMGFMT_YV12) || (frame->format == XINE_IMGFMT_YUY2)) && ((frame->width != this->sw_width) ||(frame->height != this->sw_height )) ) { lprintf("vaapi_display_frame %s frame->width %d frame->height %d\n", (frame->format == XINE_IMGFMT_VAAPI) ? "XINE_IMGFMT_VAAPI" : ((frame->format == XINE_IMGFMT_YV12) ? "XINE_IMGFMT_YV12" : "XINE_IMGFMT_YUY2") , frame->width, frame->height); unsigned int last_sub_img_fmt = this->last_sub_image_fmt; if(last_sub_img_fmt) vaapi_ovl_associate(this, frame_gen->format, 0); if(!va_context->valid_context) { lprintf("vaapi_display_frame init full context\n"); vaapi_init_internal(this, SW_CONTEXT_INIT_FORMAT, frame->width, frame->height); } else { lprintf("vaapi_display_frame init soft surfaces\n"); vaapi_init_soft_surfaces(this, frame->width, frame->height); } this->sc.force_redraw = 1; #ifdef ENABLE_VA_GLX this->init_opengl_render = 1; #endif if(last_sub_img_fmt) vaapi_ovl_associate(this, frame_gen->format, this->has_overlay); } UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); vaapi_redraw_needed (this_gen); pthread_mutex_lock(&this->vaapi_lock); LOCK_DISPLAY (this); /* posible race could happen while the lock is opened */ if (!va_context->valid_context) { UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); frame_gen->free (frame_gen); return; } #ifdef ENABLE_VA_GLX /* initialize opengl rendering */ if(this->opengl_render && this->init_opengl_render) { unsigned int last_sub_img_fmt = this->last_sub_image_fmt; if(last_sub_img_fmt) vaapi_ovl_associate(this, frame_gen->format, 0); destroy_glx(this); vaapi_glx_config_glx(this, va_context->width, va_context->height); vaapi_resize_glx_window(this, this->sc.gui_width, this->sc.gui_height); if(last_sub_img_fmt) vaapi_ovl_associate(this, frame_gen->format, this->has_overlay); this->sc.force_redraw = 1; this->init_opengl_render = 0; } #endif /* double start_time; double end_time; double elapse_time; int factor; start_time = timeOfDay(); */ if (frame->format != XINE_IMGFMT_VAAPI) { va_surface_id = this->va_soft_surface_ids[this->va_soft_head]; va_image = &this->va_soft_images[this->va_soft_head]; this->va_soft_head = (this->va_soft_head + 1) % (SOFT_SURFACES); } else if (accel->index < RENDER_SURFACES) { // (frame->format == XINE_IMGFMT_VAAPI) ff_vaapi_surface_t *va_surface = &va_context->va_render_surfaces[accel->index]; if (this->guarded_render) { if (va_surface->status == SURFACE_RENDER || va_surface->status == SURFACE_RENDER_RELEASE) { va_surface_id = va_surface->va_surface_id; } #ifdef DEBUG_SURFACE printf("vaapi_display_frame va_surface 0x%08x status %d index %d\n", va_surface_id, va_surface->status, accel->index); #endif } else { va_surface_id = va_surface->va_surface_id; } va_image = NULL; } lprintf("2: 0x%08x\n", va_surface_id); if (va_surface_id != VA_INVALID_SURFACE) { VASurfaceStatus surf_status = 0; if (this->va->query_va_status) { vaStatus = vaQuerySurfaceStatus(va_context->va_display, va_surface_id, &surf_status); vaapi_check_status(this, vaStatus, "vaQuerySurfaceStatus()"); } else { surf_status = VASurfaceReady; } if (surf_status != VASurfaceReady) { va_surface_id = VA_INVALID_SURFACE; va_image = NULL; #ifdef DEBUG_SURFACE printf("Surface srfc 0x%08X not ready for render\n", va_surface_id); #endif } } else { #ifdef DEBUG_SURFACE printf("Invalid srfc 0x%08X\n", va_surface_id); #endif } if (va_surface_id != VA_INVALID_SURFACE) { lprintf("vaapi_display_frame: 0x%08x %d %d\n", va_surface_id, va_context->width, va_context->height); vaStatus = vaSyncSurface(va_context->va_display, va_surface_id); vaapi_check_status(this, vaStatus, "vaSyncSurface()"); /* transfer image data to a VAAPI surface */ if (frame->format != XINE_IMGFMT_VAAPI) { vaapi_software_render_frame(this, frame, va_image, this->soft_image_is_bound, va_surface_id); } vaapi_hardware_render_frame(this, frame, va_surface_id); } XSync(this->display, False); //end_time = timeOfDay(); _add_recent_frame (this, frame_gen); pthread_mutex_unlock(&this->vaapi_lock); UNLOCK_DISPLAY (this); /* elapse_time = end_time - start_time; factor = (int)(elapse_time/(1.0/60.0)); if( factor > 1 ) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " PutImage %dX interval (%fs)\n", factor, elapse_time ); } */ } static int vaapi_get_property (vo_driver_t *this_gen, int property) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; switch (property) { case VO_PROP_WINDOW_WIDTH: this->props[property].value = this->sc.gui_width; break; case VO_PROP_WINDOW_HEIGHT: this->props[property].value = this->sc.gui_height; break; case VO_PROP_OUTPUT_WIDTH: this->props[property].value = this->sc.output_width; break; case VO_PROP_OUTPUT_HEIGHT: this->props[property].value = this->sc.output_height; break; case VO_PROP_OUTPUT_XOFFSET: this->props[property].value = this->sc.output_xoffset; break; case VO_PROP_OUTPUT_YOFFSET: this->props[property].value = this->sc.output_yoffset; break; case VO_PROP_MAX_NUM_FRAMES: /* Split surfaces between decoding and output. * Needed to prevent crashes with heavy seeking, * bright green flashes, and frame jumping with some h.264. */ this->props[property].value = RENDER_SURFACES / 2; break; } lprintf("vaapi_get_property property=%d, value=%d\n", property, this->props[property].value ); return this->props[property].value; } static int vaapi_set_property (vo_driver_t *this_gen, int property, int value) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; ff_vaapi_context_t *va_context = this->va_context; lprintf("vaapi_set_property property=%d, value=%d\n", property, value ); if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; if ((property == VO_PROP_BRIGHTNESS) || (property == VO_PROP_CONTRAST) || (property == VO_PROP_SATURATION) || (property == VO_PROP_HUE)) { /* defer these to vaapi_update_csc () */ if((value < this->props[property].min) || (value > this->props[property].max)) value = (this->props[property].min + this->props[property].max) >> 1; this->props[property].value = value; this->color_matrix = 0; return value; } if(this->props[property].atom) { VADisplayAttribute attr; if((value < this->props[property].min) || (value > this->props[property].max)) value = (this->props[property].min + this->props[property].max) >> 1; this->props[property].value = value; attr.type = this->props[property].type; attr.value = value; if(va_context && va_context->valid_context) { vaSetDisplayAttributes(va_context->va_display, &attr, 1); //vaapi_check_status(this, vaStatus, "vaSetDisplayAttributes()"); } if (this->props[property].entry) this->props[property].entry->num_value = this->props[property].value; return this->props[property].value; } else { switch (property) { case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->props[property].value = value; this->sc.user_ratio = value; _x_vo_scale_compute_ideal_size (&this->sc); this->sc.force_redraw = 1; break; case VO_PROP_ZOOM_X: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size (&this->sc); this->sc.force_redraw = 1; } break; case VO_PROP_ZOOM_Y: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; _x_vo_scale_compute_ideal_size (&this->sc); this->sc.force_redraw = 1; } break; case VO_PROP_DISCARD_FRAMES: this->props[property].value = _flush_recent_frames (this); break; } } return value; } static void vaapi_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; *min = this->props[property].min; *max = this->props[property].max; } static int vaapi_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; lprintf("vaapi_gui_data_exchange %d\n", data_type); switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: { /* We should get this * 1. after initial video window open, and * 2. when video window gets revealed behind an other window * while no desktop compositor is running. * This works with opengl2 and vdpau. * FIXME: With vaapi here, 2. does _not_ work. Why? */ pthread_mutex_lock(&this->vaapi_lock); lprintf("XINE_GUI_SEND_EXPOSE_EVENT:\n"); this->sc.force_redraw = 1; #ifdef ENABLE_VA_GLX this->init_opengl_render = 1; #endif pthread_mutex_unlock(&this->vaapi_lock); } break; case XINE_GUI_SEND_WILL_DESTROY_DRAWABLE: { printf("XINE_GUI_SEND_WILL_DESTROY_DRAWABLE\n"); } break; case XINE_GUI_SEND_DRAWABLE_CHANGED: { pthread_mutex_lock(&this->vaapi_lock); LOCK_DISPLAY (this); lprintf("XINE_GUI_SEND_DRAWABLE_CHANGED\n"); this->drawable = (Drawable) data; XReparentWindow(this->display, this->window, this->drawable, 0, 0); this->sc.force_redraw = 1; #ifdef ENABLE_VA_GLX this->init_opengl_render = 1; #endif UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); } break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void vaapi_dispose_locked (vaapi_driver_t *this) { config_values_t *config = this->xine->config; /* cm_close already does this. config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); */ cm_close (this); _x_vo_scale_cleanup (&this->sc, config); // vaapi_lock is locked at this point, either from vaapi_dispose or vaapi_open_plugin LOCK_DISPLAY (this); vaapi_close(this); _x_va_free(&this->va); _x_freep(&this->overlay_bitmap); if (this->window != None) { vaapi_x11_trap_errors(); XDestroyWindow(this->display, this->window); XSync(this->display, False); if (vaapi_x11_untrap_errors()) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " XDestroyWindow() failed\n"); } } UNLOCK_DISPLAY (this); pthread_mutex_unlock(&this->vaapi_lock); pthread_mutex_destroy(&this->vaapi_lock); _x_assert(this->recent_frames[0] == NULL); free (this); } static void vaapi_dispose (vo_driver_t *this_gen) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; lprintf("vaapi_dispose\n"); pthread_mutex_lock(&this->vaapi_lock); vaapi_dispose_locked(this); } static void vaapi_vdr_osd_width_flag( void *this_gen, xine_cfg_entry_t *entry ) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; this->vdr_osd_width = entry->num_value < 0 ? 0 : entry->num_value; } static void vaapi_vdr_osd_height_flag( void *this_gen, xine_cfg_entry_t *entry ) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; this->vdr_osd_height = entry->num_value < 0 ? 0 : entry->num_value; } static void vaapi_deinterlace_flag( void *this_gen, xine_cfg_entry_t *entry ) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; this->deinterlace = entry->num_value; if(this->deinterlace > 2) this->deinterlace = 2; } #ifdef ENABLE_VA_GLX static void vaapi_opengl_use_tfp( void *this_gen, xine_cfg_entry_t *entry ) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; this->opengl_use_tfp = entry->num_value; } #endif /* ENABLE_VA_GLX */ static void vaapi_scaling_level( void *this_gen, xine_cfg_entry_t *entry ) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; this->scaling_level = entry->num_value; } static void vaapi_swap_uv_planes(void *this_gen, xine_cfg_entry_t *entry) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; this->swap_uv_planes = entry->num_value; } static void vaapi_csc_mode(void *this_gen, xine_cfg_entry_t *entry) { vaapi_driver_t *this = (vaapi_driver_t *) this_gen; int new_mode = entry->num_value; /* skip unchanged */ if (new_mode == this->csc_mode) return; vaapi_set_csc_mode (this, new_mode); } static int vaapi_init_x11(vaapi_driver_t *this) { XSetWindowAttributes xswa; unsigned long xswa_mask; XWindowAttributes wattr; unsigned long black_pixel; XVisualInfo visualInfo; XVisualInfo *vi; int depth; int result = 0; const int x11_event_mask = ExposureMask | StructureNotifyMask; LOCK_DISPLAY (this); black_pixel = BlackPixel(this->display, this->screen); XGetWindowAttributes(this->display, this->drawable, &wattr); depth = wattr.depth; if (depth != 15 && depth != 16 && depth != 24 && depth != 32) depth = 24; vi = &visualInfo; XMatchVisualInfo(this->display, this->screen, depth, TrueColor, vi); xswa_mask = CWBorderPixel | CWBackPixel | CWColormap; xswa.border_pixel = black_pixel; xswa.background_pixel = black_pixel; xswa.colormap = CopyFromParent; vaapi_x11_trap_errors(); this->window = XCreateWindow(this->display, this->drawable, 0, 0, 1, 1, 0, depth, InputOutput, vi->visual, xswa_mask, &xswa); XSync(this->display, False); if (vaapi_x11_untrap_errors() || this->window == None) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " XCreateWindow() failed\n"); goto out; } XSelectInput(this->display, this->window, x11_event_mask); XMapWindow(this->display, this->window); vaapi_x11_wait_event(this->display, this->window, MapNotify); result = 1; out: UNLOCK_DISPLAY (this); if (vi != &visualInfo) XFree(vi); return result; } static int vaapi_initialize(vaapi_driver_t *this, int visual_type, const void *visual) { VAStatus vaStatus; unsigned interop_flags = XINE_VA_DISPLAY_X11; #ifdef ENABLE_VA_GLX if (this->opengl_render) interop_flags = XINE_VA_DISPLAY_GLX; #endif this->va = _x_va_new(this->xine, visual_type, visual, interop_flags); if (!this->va) return 0; this->va_context = &this->va->c; this->va_context->driver = &this->vo_driver; #ifdef ENABLE_VA_GLX { const char *p, *vendor; size_t i; vendor = vaQueryVendorString(this->va_context->va_display); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Vendor : %s\n", vendor); for (p = vendor, i = strlen (vendor); i > 0; i--, p++) { if(strncmp(p, "VDPAU", strlen("VDPAU")) == 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Enable Splitted-Desktop Systems VDPAU-VIDEO workarounds.\n"); this->opengl_use_tfp = 0; break; } } } #endif vaapi_set_background_color(this); vaapi_display_attribs(this); if (this->overlay_mode == 1) { VAImageFormat *va_subpic_formats = NULL; unsigned int *va_subpic_flags = NULL; int fmt_count = vaMaxNumSubpictureFormats (this->va_context->va_display); if ((unsigned int)(fmt_count - 1) < 256) { va_subpic_formats = calloc (fmt_count, sizeof (*va_subpic_formats)); va_subpic_flags = calloc (fmt_count, sizeof (*va_subpic_flags)); /* FIXME: the mesa radeonsi driver has a severe overlay bug. * for vdpau, we got a usable workaround (see video_out_vdpau.c). * for vaapi, glx mode should be 1 2. * in any case, treat missing overlays as non fatal. */ vaStatus = vaQuerySubpictureFormats (this->va_context->va_display, va_subpic_formats, va_subpic_flags, &fmt_count); if (!vaapi_check_status (this, vaStatus, "vaQuerySubpictureFormats()")) fmt_count = 0; } if ((unsigned int)(fmt_count - 1) < 256) { char buf[256 * 22], *q = buf; int i; for (i = 0; i < fmt_count; i++) { *q++ = ' '; q += _x_tag32_me2str (q, va_subpic_formats[i].fourcc); if (va_subpic_formats[i].fourcc == VA_FOURCC ('B', 'G', 'R', 'A')) { this->bgra_subpic_format = va_subpic_formats[i]; this->bgra_subpic_flags = va_subpic_flags[i]; } } *q = 0; xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: subpicture formats: %s.\n", buf); } else { /* this->overlay_mode = 0; * this->xine->config->update_num (this->xine->config, "video.output.vaapi_overlay_mode", 0); */ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: bogus subpicture format count %d, overlays disabled.\n", fmt_count); } free (va_subpic_flags); free (va_subpic_formats); } else if (this->overlay_mode == 2) { /* DEBUG only. */ this->bgra_subpic_format.fourcc = VA_FOURCC ('B', 'G', 'R', 'A'); this->bgra_subpic_format.byte_order = 1; this->bgra_subpic_format.bits_per_pixel = 32; this->bgra_subpic_format.depth = 32; this->bgra_subpic_format.red_mask = 0x00ff0000; this->bgra_subpic_format.green_mask = 0x0000ff00; this->bgra_subpic_format.blue_mask = 0x000000ff; this->bgra_subpic_format.alpha_mask = 0xff000000; this->bgra_subpic_flags = 0; xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: warning: forcing BGRA overlays, this may crash.\n"); } else { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: overlays disabled manually.\n"); } if(vaapi_init_internal(this, SW_CONTEXT_INIT_FORMAT, SW_WIDTH, SW_HEIGHT) != VA_STATUS_SUCCESS) return 0; vaapi_close(this); return 1; } static vo_driver_t *vaapi_open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { vaapi_class_t *class = (vaapi_class_t *) class_gen; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; vaapi_driver_t *this; config_values_t *config = class->xine->config; int i; this = (vaapi_driver_t *) calloc(1, sizeof(vaapi_driver_t)); if (!this) return NULL; pthread_mutex_init(&this->vaapi_lock, NULL); pthread_mutex_lock(&this->vaapi_lock); this->xine = class->xine; this->display = visual->display; this->screen = visual->screen; this->drawable = visual->d; /* number of video frames from config - register it with the default value. */ int frame_num = config->register_num (config, "engine.buffers.video_num_frames", MIN_SURFACES, /* default */ _("default number of video frames"), _("The default number of video frames to request " "from xine video out driver. Some drivers will " "override this setting with their own values."), 20, NULL, NULL); /* now make sure we have at least 22 frames, to prevent * locks with vdpau_h264 */ if (frame_num < MIN_SURFACES) config->update_num (config,"engine.buffers.video_num_frames", MIN_SURFACES); #ifdef ENABLE_VA_GLX /* This is not really live switchable. */ this->opengl_render = config->register_bool( config, "video.output.vaapi_opengl_render", 0, _("vaapi: opengl output rendering"), _("vaapi: opengl output rendering"), 20, NULL, NULL); this->init_opengl_render = 1; this->opengl_use_tfp = config->register_bool( config, "video.output.vaapi_opengl_use_tfp", 0, _("vaapi: opengl rendering tfp"), _("vaapi: opengl rendering tfp"), 20, vaapi_opengl_use_tfp, this ); if(this->opengl_render) { LOCK_DISPLAY (this); this->opengl_render = vaapi_opengl_verify_direct (visual); UNLOCK_DISPLAY (this); if(!this->opengl_render) xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Opengl indirect/software rendering does not work. Fallback to plain VAAPI output !!!!\n"); } this->gl_context = NULL; this->gl_pixmap = None; this->gl_image_pixmap = None; this->gl_texture = GL_NONE; #endif /* ENABLE_VA_GLX */ this->va_soft_surface_ids = this->va_soft_surface_ids_storage; this->va_soft_images = this->va_soft_images_storage; for (i = 0; i < SOFT_SURFACES; i++) { this->va_soft_surface_ids[i] = VA_INVALID_SURFACE; this->va_soft_images[i].image_id = VA_INVALID_ID; } vaapi_init_subpicture(this); _x_vo_scale_init (&this->sc, 1, 0, config ); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.dest_size_cb = visual->dest_size_cb; this->sc.user_data = visual->user_data; this->sc.user_ratio = XINE_VO_ASPECT_AUTO; this->capabilities = VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_CROP | VO_CAP_UNSCALED_OVERLAY | VO_CAP_ARGB_LAYER_OVERLAY | VO_CAP_VAAPI | VO_CAP_CUSTOM_EXTENT_OVERLAY; this->vo_driver.get_capabilities = vaapi_get_capabilities; this->vo_driver.alloc_frame = vaapi_alloc_frame; this->vo_driver.update_frame_format = _x_va_frame_update_frame_format; this->vo_driver.overlay_begin = vaapi_overlay_begin; this->vo_driver.overlay_blend = vaapi_overlay_blend; this->vo_driver.overlay_end = vaapi_overlay_end; this->vo_driver.display_frame = vaapi_display_frame; this->vo_driver.get_property = vaapi_get_property; this->vo_driver.set_property = vaapi_set_property; this->vo_driver.get_property_min_max = vaapi_get_property_min_max; this->vo_driver.gui_data_exchange = vaapi_gui_data_exchange; this->vo_driver.dispose = vaapi_dispose; this->vo_driver.redraw_needed = vaapi_redraw_needed; this->deinterlace = 0; this->vdr_osd_width = 0; this->vdr_osd_height = 0; i = config->register_num( config, "video.output.vaapi_vdr_osd_width", 0, _("vaapi: VDR osd width workaround."), _("vaapi: VDR osd width workaround."), 10, vaapi_vdr_osd_width_flag, this ); this->vdr_osd_width = i < 0 ? 0 : i; i = config->register_num( config, "video.output.vaapi_vdr_osd_height", 0, _("vaapi: VDR osd height workaround."), _("vaapi: VDR osd height workaround."), 10, vaapi_vdr_osd_height_flag, this ); this->vdr_osd_height = i < 0 ? 0 : i; this->deinterlace = config->register_num( config, "video.output.vaapi_deinterlace", 0, _("vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )."), _("vaapi: set deinterlace to 0 ( none ), 1 ( top field ), 2 ( bob )."), 10, vaapi_deinterlace_flag, this ); this->guarded_render = config->register_num( config, "video.output.vaapi_guarded_render", 1, _("vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )"), _("vaapi: set vaapi_guarded_render to 0 ( no ) 1 ( yes )"), 10, NULL, NULL ); this->scaling_level_enum = config->register_enum(config, "video.output.vaapi_scaling_level", 0, (char **)scaling_level_enum_names, _("vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla (anamorphic)"), _("vaapi: set scaling level to : default (default) fast (fast) hq (HQ) nla (anamorphic)"), 10, vaapi_scaling_level, this); this->scaling_level = scaling_level_enum_values[this->scaling_level_enum]; this->swap_uv_planes = config->register_bool( config, "video.output.vaapi_swap_uv_planes", 0, _("vaapi: swap UV planes."), _("vaapi: this is a workaround for buggy drivers ( intel IronLake ).\n" "There the UV planes are swapped.\n"), 10, vaapi_swap_uv_planes, this); for (i = 0; i < VO_NUM_PROPERTIES; i++) { this->props[i].value = 0; this->props[i].min = 0; this->props[i].max = 0; this->props[i].atom = 0; this->props[i].entry = NULL; this->props[i].this = this; } cm_init (this); this->sc.user_ratio = this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; this->props[VO_PROP_ZOOM_X].value = 100; this->props[VO_PROP_ZOOM_Y].value = 100; this->last_sub_image_fmt = 0; this->csc_mode = this->xine->config->register_enum (this->xine->config, "video.output.vaapi_csc_mode", 3, (char **)vaapi_csc_mode_labels, _("VAAPI colour conversion method"), _("How to handle colour conversion in VAAPI:\n\n" "user_matrix: The best way - if your driver supports it.\n" "simple: Switch SD/HD colour spaces, and let decoders convert fullrange video.\n" "simple+2: Switch SD/HD colour spaces, and emulate full-range colour by modifying\n" " brightness/contrast settings.\n" "simple+3: Like above, but adjust saturation as well.\n\n" "Hint: play \"test://rgb_levels.bmp\" while trying this.\n"), 10, vaapi_csc_mode, this); vaapi_set_csc_mode (this, this->csc_mode); this->overlay_mode = this->xine->config->register_range (this->xine->config, "video.output.vaapi_overlay_mode", 1, 0, 2, _("VAAPI overlay mode"), _("How to display onscreen messages and subtitles:\n" "0: Disable overlays for broken driver (eg Mesa radeonsi),\n" "1: Auto.\n" "2: Force BGRA.\n"), 10, NULL, NULL); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Deinterlace : %d\n", this->deinterlace); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Render surfaces : %d\n", RENDER_SURFACES); #ifdef ENABLE_VA_GLX xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE " vaapi_open: Opengl render : %d\n", this->opengl_render); #endif if (!vaapi_init_x11(this) || !vaapi_initialize(this, XINE_VISUAL_TYPE_X11, visual_gen)) { vaapi_dispose_locked(this); return NULL; } pthread_mutex_unlock(&this->vaapi_lock); return &this->vo_driver; } /* * class functions */ static void *vaapi_init_class (xine_t *xine, const void *visual_gen) { vaapi_class_t *this; (void)visual_gen; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = vaapi_open_plugin; this->driver_class.identifier = "vaapi"; this->driver_class.description = N_("xine video output plugin using VAAPI"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_vaapi = { .priority = 9, .visual_type = XINE_VISUAL_TYPE_X11, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "vaapi", XINE_VERSION_CODE, &vo_info_vaapi, vaapi_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_xxmc.c0000644000175000017500000026347514647725152016671 0ustar meme/* * Copyright (C) 2000-2020 the xine project * Copyright (C) 2004 the Unichrome project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_xxmc.c, X11 decoding accelerated video extension interface for xine * * based on mpeg2dec code from * Aaron Holtzman * * Xv image support by Gerd Knorr * * xine-specific code by Guenter Bartsch * * overlay support by James Courtier-Dutton - July 2001 * X11 unscaled overlay support by Miguel Freitas - Nov 2003 * XvMC VLD implementation by Thomas Hellström - 2004, 2005. * XvMC merge by Thomas Hellström - Sep 2004 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "xxmc.h" #include #include #include "xv_common.h" static int gX11Fail; static void xxmc_frame_updates(xxmc_driver_t *driver, xxmc_frame_t *frame, int init_macroblocks); static void dispose_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, XvImage *myimage); VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES VIDEO_DEVICE_XV_DECL_PREFER_TYPES /* * Acceleration level priority. Static for now. It may well turn out that IDCT * is more efficient than VLD. */ static const unsigned int accel_priority[] = { #ifdef HAVE_VLDXVMC XINE_XVMC_ACCEL_VLD, #endif XINE_XVMC_ACCEL_IDCT, XINE_XVMC_ACCEL_MOCOMP}; #define NUM_ACCEL_PRIORITY (sizeof(accel_priority)/sizeof(accel_priority[0])) #ifndef XVMC_VLD #define XVMC_VLD 0 #endif /* * Additional thread safety, since the plugin may decide to destroy a context * while it's surfaces are still active in the video-out loop. * When / If XvMC libs are reasonably thread-safe, the locks can be made * more efficient by allowing multiple threads in that do not destroy * the context or surfaces that may be active in other threads. */ static void init_context_lock(context_lock_t *c) { pthread_cond_init(&c->cond,NULL); pthread_mutex_init(&c->mutex,NULL); c->num_readers = 0; } static void free_context_lock(context_lock_t *c) { pthread_mutex_destroy(&c->mutex); pthread_cond_destroy(&c->cond); } void xvmc_context_reader_lock(context_lock_t *c) { pthread_mutex_lock(&c->mutex); #ifdef XVMC_THREAD_SAFE c->num_readers++; pthread_mutex_unlock(&c->mutex); #endif } void xvmc_context_reader_unlock(context_lock_t *c) { #ifdef XVMC_THREAD_SAFE pthread_mutex_lock(&c->mutex); if (c->num_readers > 0) { if (--(c->num_readers) == 0) { pthread_cond_broadcast(&c->cond); } } #endif pthread_mutex_unlock(&c->mutex); } static void xvmc_context_writer_lock(context_lock_t *c) { pthread_mutex_lock(&c->mutex); #ifdef XVMC_THREAD_SAFE while(c->num_readers) { pthread_cond_wait(&c->cond, &c->mutex); } #endif } static void xvmc_context_writer_unlock(context_lock_t *c) { pthread_mutex_unlock(&c->mutex); } /* * A number of simple surface allocator functions that implements the * notion that a surface may be invalid if it is asynchronously * destroyed. Both surfaces and subpictures are handled this way. */ static void xxmc_xvmc_dump_surfaces(xxmc_driver_t *this ) { int i; xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; for (i=0; ixine, XINE_VERBOSITY_DEBUG, "%d %d;",handler->surfInUse[i], handler->surfValid[i]); } xprintf(this->xine, XINE_VERBOSITY_DEBUG, "\n"); } static void xxmc_xvmc_dump_subpictures(xxmc_driver_t *this) { int i; xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; for (i=0; ixine, XINE_VERBOSITY_DEBUG, "%d %d;",handler->subInUse[i], handler->subValid[i]); } xprintf(this->xine, XINE_VERBOSITY_DEBUG, "\n"); } static void xxmc_xvmc_surface_handler_construct(xxmc_driver_t *this) { xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; pthread_mutex_init(&handler->mutex,NULL); memset(handler->surfInUse, 0, sizeof(*handler->surfInUse)*XVMC_MAX_SURFACES); memset(handler->surfValid, 0, sizeof(*handler->surfValid)*XVMC_MAX_SURFACES); memset(handler->subInUse, 0, sizeof(*handler->subInUse)*XVMC_MAX_SUBPICTURES); memset(handler->subValid, 0, sizeof(*handler->subValid)*XVMC_MAX_SUBPICTURES); } static void xxmc_xvmc_destroy_surfaces(xxmc_driver_t *this) { int i; xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; pthread_mutex_lock(&handler->mutex); for (i=0; i < XVMC_MAX_SURFACES; ++i) { XVMCLOCKDISPLAY( this->display ); if (handler->surfValid[i]) { XvMCFlushSurface( this->display , handler->surfaces+i); XvMCSyncSurface( this->display, handler->surfaces+i ); XvMCHideSurface( this->display, handler->surfaces+i ); XvMCDestroySurface( this->display, handler->surfaces+i ); } XVMCUNLOCKDISPLAY( this->display ); handler->surfValid[i] = 0; } pthread_mutex_unlock(&handler->mutex); } static void xxmc_xvmc_destroy_subpictures(xxmc_driver_t *this) { int i; xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; pthread_mutex_lock(&handler->mutex); for (i=0; i < XVMC_MAX_SUBPICTURES; ++i) { XVMCLOCKDISPLAY( this->display ); if (handler->subValid[i]) { XvMCFlushSubpicture( this->display , handler->subpictures+i); XvMCSyncSubpicture( this->display, handler->subpictures+i ); XvMCDestroySubpicture( this->display, handler->subpictures+i ); } XVMCUNLOCKDISPLAY( this->display ); handler->subValid[i] = 0; } pthread_mutex_unlock(&handler->mutex); } static XvMCSurface *xxmc_xvmc_alloc_surface(xxmc_driver_t *this, XvMCContext *context) { xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; int i; pthread_mutex_lock(&handler->mutex); xxmc_xvmc_dump_surfaces(this); for (i=0; isurfValid[i] && !handler->surfInUse[i]) { handler->surfInUse[i] = 1; xxmc_xvmc_dump_surfaces(this); pthread_mutex_unlock(&handler->mutex); return handler->surfaces + i; } } for (i=0; isurfInUse[i]) { XVMCLOCKDISPLAY( this->display ); if (Success != XvMCCreateSurface( this->display, context, handler->surfaces + i)) { XVMCUNLOCKDISPLAY( this->display ); pthread_mutex_unlock(&handler->mutex); return NULL; } XVMCUNLOCKDISPLAY( this->display ); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Created surface %d\n",i); handler->surfInUse[i] = 1; handler->surfValid[i] = 1; pthread_mutex_unlock(&handler->mutex); return handler->surfaces + i; } } pthread_mutex_unlock(&handler->mutex); return NULL; } static void xxmc_xvmc_free_surface(xxmc_driver_t *this, XvMCSurface *surf) { xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; unsigned index = surf - handler->surfaces; if (index >= XVMC_MAX_SURFACES) return; pthread_mutex_lock(&handler->mutex); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Disposing of surface %d\n",index); handler->surfInUse[index]--; xxmc_xvmc_dump_surfaces(this); pthread_mutex_unlock(&handler->mutex); } int xxmc_xvmc_surface_valid(xxmc_driver_t *this, XvMCSurface *surf) { xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; unsigned index = surf - handler->surfaces; int ret; if (index >= XVMC_MAX_SURFACES) return 0; pthread_mutex_lock(&handler->mutex); ret = handler->surfValid[index]; pthread_mutex_unlock(&handler->mutex); return ret; } static XvMCSubpicture *xxmc_xvmc_alloc_subpicture (xxmc_driver_t *this, XvMCContext *context, unsigned short width, unsigned short height, int xvimage_id) { int i; xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; int status; pthread_mutex_lock(&handler->mutex); xxmc_xvmc_dump_subpictures(this); for (i=0; isubValid[i] && !handler->subInUse[i]) { XVMCLOCKDISPLAY( this->display ); if (XvMCGetSubpictureStatus( this->display, handler->subpictures + i, &status)) { XVMCUNLOCKDISPLAY( this->display ); continue; } XVMCUNLOCKDISPLAY( this->display ); if (status & XVMC_DISPLAYING) continue; handler->subInUse[i] = 1; xxmc_xvmc_dump_subpictures(this); pthread_mutex_unlock(&handler->mutex); return handler->subpictures + i; } } for (i=0; isubInUse[i]) { XVMCLOCKDISPLAY( this->display ); if (Success != XvMCCreateSubpicture( this->display, context, handler->subpictures + i, width, height, xvimage_id)) { XVMCUNLOCKDISPLAY( this->display ); pthread_mutex_unlock(&handler->mutex); return NULL; } XVMCUNLOCKDISPLAY( this->display ); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Created subpicture %d\n",i); handler->subInUse[i] = 1; handler->subValid[i] = 1; pthread_mutex_unlock(&handler->mutex); return handler->subpictures + i; } } pthread_mutex_unlock(&handler->mutex); return NULL; } static void xxmc_xvmc_free_subpicture(xxmc_driver_t *this, XvMCSubpicture *sub) { xvmc_surface_handler_t *handler = &this->xvmc_surf_handler; unsigned index = sub - handler->subpictures; if (index >= XVMC_MAX_SUBPICTURES) return; pthread_mutex_lock(&handler->mutex); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Disposing of subpicture %d\n",index); handler->subInUse[index] = 0; xxmc_xvmc_dump_subpictures(this); pthread_mutex_unlock(&handler->mutex); } /* * Callback used by decoder to check that surfaces are still valid, * and to lock the context so that it won't get destroyed during * decoding. */ static int xxmc_lock_and_validate_surfaces(vo_frame_t *cur_frame, vo_frame_t *fw_frame, vo_frame_t *bw_frame, unsigned pc_type) { xxmc_driver_t *driver = (xxmc_driver_t *) cur_frame->driver; xxmc_frame_t *frame; xvmc_context_reader_lock( &driver->xvmc_lock ); switch(pc_type) { case XINE_PICT_B_TYPE: frame = XXMC_FRAME(bw_frame); if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break; /* fall through */ case XINE_PICT_P_TYPE: frame = XXMC_FRAME(fw_frame); if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break; /* fall through */ default: frame = XXMC_FRAME(cur_frame); if (!xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) break; return 0; } xvmc_context_reader_unlock( &driver->xvmc_lock ); return -1; } /* * Callback for decoder. Decoding temporarily halted. Release the context. */ static void xxmc_unlock_surfaces(vo_driver_t *this_gen) { xxmc_driver_t *driver = (xxmc_driver_t *) this_gen; xvmc_context_reader_unlock( &driver->xvmc_lock ); } /* * Callback for decoder. * Check that the surface is vaid and * flush outstanding rendering requests on this surface. */ static void xvmc_flush(vo_frame_t *this_gen) { xxmc_frame_t *frame = XXMC_FRAME(this_gen); xxmc_driver_t *driver = (xxmc_driver_t *) this_gen->driver; xvmc_context_reader_lock( &driver->xvmc_lock ); if ( ! xxmc_xvmc_surface_valid( driver, frame->xvmc_surf)) { frame->xxmc_data.result = 128; xvmc_context_reader_unlock( &driver->xvmc_lock ); return; } XVMCLOCKDISPLAY( driver->display ); frame->xxmc_data.result = XvMCFlushSurface( driver->display, frame->xvmc_surf ); XVMCUNLOCKDISPLAY( driver->display ); xvmc_context_reader_unlock( &driver->xvmc_lock ); } /* * Callback function for the VO-loop to duplicate frame data. * YV12 and YUY2 formats are taken care of in the xine-engine. * This one only deals with hardware surfaces and duplicates them * using a call to XvMCBlendSubpicture2 with a blank subpicture. */ static void xxmc_duplicate_frame_data(vo_frame_t *this_gen, vo_frame_t *original) { xxmc_frame_t *this = (xxmc_frame_t *) this_gen, *orig = (xxmc_frame_t *) original; xxmc_driver_t *driver = (xxmc_driver_t *) this_gen->driver; xine_t *xine = driver->xine; xine_xxmc_t *xxmc; XvMCSubpicture *tmp; int need_dummy; if (original->format != XINE_IMGFMT_XXMC) return; xxmc = &orig->xxmc_data; xvmc_context_writer_lock( &driver->xvmc_lock); if (!xxmc_xvmc_surface_valid(driver,orig->xvmc_surf)) { xvmc_context_writer_unlock( &driver->xvmc_lock ); return; } this->xxmc_data = *xxmc; this->xxmc_data.xvmc.vo_frame = &this->vo_frame; this->width = original->width; this->height = original->height; this->format = original->format; this->ratio = original->ratio; xxmc_frame_updates(driver,this,0); /* * Allocate a dummy subpicture and copy using * XvMCBlendsubpicture2. VLD implementations can do blending with a * NULL subpicture. Use that if possible. */ need_dummy = (xxmc->acceleration != XINE_XVMC_ACCEL_VLD); tmp = NULL; if (need_dummy) { tmp = xxmc_xvmc_alloc_subpicture( driver, &driver->context, this->width, this->height, driver->xvmc_cap [driver->xvmc_cur_cap].subPicType.id); } if (tmp || !need_dummy) { XVMCLOCKDISPLAY( driver->display ); if (tmp) XvMCClearSubpicture(driver->display, tmp , 0,0, this->width, this->height, 0); if (Success == XvMCBlendSubpicture2( driver->display, orig->xvmc_surf, this->xvmc_surf, tmp, 0,0,this->width, this->height, 0,0,this->width, this->height)) { this->xxmc_data.decoded = 1; } XVMCUNLOCKDISPLAY( driver->display ); if (tmp) xxmc_xvmc_free_subpicture( driver, tmp); } xvmc_context_writer_unlock( &driver->xvmc_lock ); xprintf(xine, XINE_VERBOSITY_DEBUG, "Duplicated XvMC frame %d %d.\n", this->width,this->height); } static uint32_t xxmc_get_capabilities (vo_driver_t *this_gen) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; return this->capabilities; } static void xxmc_frame_field (vo_frame_t *vo_img, int which_field) { lprintf ("xvmc_frame_field\n"); (void)vo_img; (void)which_field; } static void xxmc_frame_dispose (vo_frame_t *vo_img) { xxmc_frame_t *frame = (xxmc_frame_t *) vo_img ; xxmc_driver_t *this = (xxmc_driver_t *) vo_img->driver; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "Disposing of frame\n"); xvmc_context_writer_lock( &this->xvmc_lock ); if (this->xvmc_cap && frame->xvmc_surf) { xxmc_xvmc_free_surface( this, frame->xvmc_surf ); frame->xvmc_surf = 0; } xvmc_context_writer_unlock( &this->xvmc_lock ); if (frame->image) { if (this->use_shm) { XLockDisplay (this->display); XShmDetach (this->display, &frame->shminfo); XFree (frame->image); XUnlockDisplay (this->display); shmdt (frame->shminfo.shmaddr); shmctl (frame->shminfo.shmid, IPC_RMID, NULL); } else { if (frame->image->data) free(frame->image->data); XLockDisplay (this->display); XFree (frame->image); XUnlockDisplay (this->display); } } free (frame); } /* * Note that this one does NOT allocate the XvMC surface. That is * done by an additional decoder callback. */ static vo_frame_t *xxmc_alloc_frame (vo_driver_t *this_gen) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; xxmc_frame_t *frame ; frame = calloc(1, sizeof (xxmc_frame_t)); if (!frame) return NULL; pthread_mutex_init (&frame->vo_frame.mutex, NULL); frame->xvmc_surf = NULL; /* * supply required functions */ frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.proc_duplicate_frame_data = NULL; frame->vo_frame.field = xxmc_frame_field; frame->vo_frame.dispose = xxmc_frame_dispose; frame->vo_frame.driver = this_gen; frame->last_sw_format = 0; frame->vo_frame.accel_data = &frame->xxmc_data; frame->xxmc_data.xvmc.vo_frame = &frame->vo_frame; frame->image = NULL; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "Allocating frame\n"); return (vo_frame_t *) frame; } static int HandleXError (Display *display, XErrorEvent *xevent) { char str [1024]; XGetErrorText (display, xevent->error_code, str, 1024); printf ("received X error event: %s\n", str); gX11Fail = 1; return 0; } /* called xlocked */ static void x11_InstallXErrorHandler (xxmc_driver_t *this) { this->x11_old_error_handler = XSetErrorHandler (HandleXError); XSync(this->display, False); } /* called xlocked */ static void x11_DeInstallXErrorHandler (xxmc_driver_t *this) { XSetErrorHandler (this->x11_old_error_handler); XSync(this->display, False); this->x11_old_error_handler = NULL; } /* called xlocked */ static XvImage *create_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, int width, int height, int format) { unsigned int xv_format; XvImage *image = NULL; if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } switch (format) { case XINE_IMGFMT_YV12: xv_format = this->xv_format_yv12; break; case XINE_IMGFMT_YUY2: xv_format = this->xv_format_yuy2; break; case FOURCC_IA44: case FOURCC_AI44: xv_format = format; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); return NULL; } if (this->use_shm) { /* * try shm */ gX11Fail = 0; x11_InstallXErrorHandler (this); image = XvShmCreateImage(this->display, this->xv_port, xv_format, 0, width, height, shminfo); if (image == NULL ) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: XvShmCreateImage failed\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } shminfo->shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777); if (image->data_size==0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: XvShmCreateImage returned a zero size\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } if (shminfo->shmid < 0 ) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: shared memory error in shmget: %s\n"), LOG_MODULE, strerror(errno)); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); if (shminfo->shmaddr == NULL) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": shared memory error (address error NULL)\n"); this->use_shm = 0; goto finishShmTesting; } if (shminfo->shmaddr == ((char *) -1)) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": shared memory error (address error)\n"); this->use_shm = 0; goto finishShmTesting; } shminfo->readOnly = False; image->data = shminfo->shmaddr; XShmAttach(this->display, shminfo); XSync(this->display, False); shmctl(shminfo->shmid, IPC_RMID, 0); if (gX11Fail) { shmdt (shminfo->shmaddr); shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: x11 error during shared memory XImage creation\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } /* * Now that the Xserver has learned about and attached to the * shared memory segment, delete it. It's actually deleted by * the kernel when all users of that segment have detached from * it. Gives an automatic shared memory cleanup in case we crash. */ shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; finishShmTesting: x11_DeInstallXErrorHandler(this); } /* * fall back to plain Xv if necessary */ if (!this->use_shm) { char *data = NULL; switch (format) { case XINE_IMGFMT_YV12: data = malloc (width * height * 3/2); break; case XINE_IMGFMT_YUY2: data = malloc (width * height * 2); break; case FOURCC_IA44: case FOURCC_AI44: data = malloc (width * height); break; default: /* not reached */ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); // _x_abort(); } image = XvCreateImage (this->display, this->xv_port, xv_format, data, width, height); } return image; } /* * Utility functions for the main update surface callback. */ static void xxmc_dispose_context(xxmc_driver_t *driver) { if (driver->contextActive) { if (driver->xvmc_accel & (XINE_XVMC_ACCEL_MOCOMP | XINE_XVMC_ACCEL_IDCT)) { xvmc_macroblocks_t *macroblocks = &driver->macroblocks; XvMCDestroyMacroBlocks( driver->display, ¯oblocks->macro_blocks ); XvMCDestroyBlocks( driver->display , ¯oblocks->blocks ); } xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Freeing up XvMC Surfaces and subpictures.\n"); _x_freep(&driver->xvmc_palette); _x_dispose_xx44_palette( &driver->palette ); xxmc_xvmc_destroy_subpictures( driver ); xxmc_xvmc_destroy_surfaces( driver ); xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Freeing up XvMC Context.\n"); XLockDisplay (driver->display); if (driver->subImage) dispose_ximage(driver, &driver->subShmInfo, driver->subImage); driver->subImage = NULL; XUnlockDisplay (driver->display); XVMCLOCKDISPLAY( driver->display ); XvMCDestroyContext( driver->display, &driver->context); XVMCUNLOCKDISPLAY( driver->display ); driver->contextActive = 0; driver->hwSubpictures = 0; driver->xvmc_accel = 0; } } /* * Find a suitable XvMC Context according to the acceleration request * passed to us in the xxmc variable, and to the acceleration type * priority set up in this plugin. Result is returned in * driver->xvmc_cur_cap. */ static int xxmc_find_context(xxmc_driver_t *driver, xine_xxmc_t *xxmc, unsigned width, unsigned height) { unsigned int i,k,found; xvmc_capabilities_t *curCap; unsigned request_mpeg_flags, request_accel_flags; request_mpeg_flags = xxmc->mpeg; found = 0; curCap = NULL; for (k = 0; k < NUM_ACCEL_PRIORITY; ++k) { request_accel_flags = xxmc->acceleration & accel_priority[k]; if (!request_accel_flags) continue; curCap = driver->xvmc_cap; for (i =0; i < driver->xvmc_num_cap; ++i) { xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Surface type %d. Capabilities 0x%8x 0x%8x\n",i, curCap->mpeg_flags,curCap->accel_flags); xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Requests: 0x%8x 0x%8x\n", request_mpeg_flags,request_accel_flags); if (((curCap->mpeg_flags & request_mpeg_flags) == request_mpeg_flags) && ((curCap->accel_flags & request_accel_flags)) && (width <= curCap->max_width) && (height <= curCap->max_height)) { found = 1; break; } curCap++; } if ( found ) { driver->xvmc_cur_cap = i; break; } } if ( found ) { driver->xvmc_accel = request_accel_flags; driver->unsigned_intra = curCap->flags & XVMC_INTRA_UNSIGNED; return 1; } driver->xvmc_accel = 0; return 0; } static int xxmc_create_context(xxmc_driver_t *driver, unsigned width, unsigned height) { xvmc_capabilities_t *curCap; curCap = driver->xvmc_cap + driver->xvmc_cur_cap; xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Creating new XvMC Context %d\n",curCap->type_id); XVMCLOCKDISPLAY( driver->display ); if (Success == XvMCCreateContext( driver->display, driver->xv_port, curCap->type_id, width, height, driver->context_flags, &driver->context)) { driver->xvmc_mpeg = curCap->mpeg_flags; driver->xvmc_width = width; driver->xvmc_height = height; driver->contextActive = 1; } XVMCUNLOCKDISPLAY( driver->display ); return driver->contextActive; } static void xxmc_setup_subpictures(xxmc_driver_t *driver, unsigned width, unsigned height) { xvmc_capabilities_t *curCap; XvMCSubpicture *sp; if (driver->contextActive) { /* * Determine if we can use hardware subpictures, and in that case, set up an * XvImage that we can use for blending. */ curCap = driver->xvmc_cap + driver->xvmc_cur_cap; if ((width > curCap->sub_max_width) || (height > curCap->sub_max_height)) return; if ((driver->xvmc_backend_subpic = (curCap->flags & XVMC_BACKEND_SUBPICTURE))) xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Using Backend subpictures.\n"); if (!driver->subImage) { /* * Note: If other image formats than xx44 are to be used here, they must be * translated to XINE_IMGFMT_XXX, since that is what create_ximage * expects. */ XLockDisplay (driver->display); driver->subImage = create_ximage(driver, &driver->subShmInfo, width, height, curCap->subPicType.id); XUnlockDisplay (driver->display); if (NULL == driver->subImage) { xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Failed allocating XvImage for supbictures.\n"); return; } } sp = xxmc_xvmc_alloc_subpicture( driver, &driver->context, width, height, curCap->subPicType.id); if (sp == NULL) return; _x_init_xx44_palette( &driver->palette, sp->num_palette_entries); driver->xvmc_palette = (char *)calloc(sp->num_palette_entries, sp->entry_bytes); xxmc_xvmc_free_subpicture( driver, sp); if (driver->xvmc_palette == NULL) return; driver->hwSubpictures = 1; } } static int xxmc_mocomp_create_macroblocks(xxmc_driver_t *driver, xxmc_frame_t *frame, int slices) { Status ret; xvmc_macroblocks_t *macroblocks = &driver->macroblocks; xine_xxmc_t *xxmc = (xine_xxmc_t *) frame->vo_frame.accel_data; slices = (slices * driver->xvmc_width) / 16; ret = XvMCCreateMacroBlocks(driver->display, &driver->context, slices, ¯oblocks->macro_blocks); if (ret) return 0; ret = XvMCCreateBlocks(driver->display, &driver->context, slices*6, ¯oblocks->blocks); if (ret) return 0; macroblocks->xine_mc.blockbaseptr = macroblocks->blocks.blocks; macroblocks->xine_mc.blockptr = macroblocks->xine_mc.blockbaseptr; macroblocks->num_blocks = 0; macroblocks->macroblockbaseptr = macroblocks->macro_blocks.macro_blocks; macroblocks->macroblockptr = macroblocks->macroblockbaseptr; macroblocks->slices = slices; xxmc->xvmc.macroblocks = (xine_macroblocks_t *)macroblocks; return 1; } static void xvmc_check_colorkey_properties(xxmc_driver_t *driver) { int num,i; XvAttribute *xvmc_attributes; Atom ap; /* * Determine if the context is of "Overlay" type. If so, * check whether we can autopaint. */ driver->have_xvmc_autopaint = 0; if (driver->context_flags & XVMC_OVERLAID_SURFACE) { XVMCLOCKDISPLAY( driver->display ); xvmc_attributes = XvMCQueryAttributes( driver->display, &driver->context, &num); if (xvmc_attributes) { for (i=0; idisplay, "XV_AUTOPAINT_COLORKEY", False); XvMCSetAttribute(driver->display, &driver->context,ap, driver->props[VO_PROP_AUTOPAINT_COLORKEY].value); driver->have_xvmc_autopaint = 1; } } } XFree(xvmc_attributes); XVMCUNLOCKDISPLAY( driver->display ); driver->xvmc_xoverlay_type = X11OSD_COLORKEY; } else { driver->xvmc_xoverlay_type = X11OSD_SHAPED; } } static int xxmc_xvmc_update_context(xxmc_driver_t *driver, xxmc_frame_t *frame, uint32_t width, uint32_t height, int frame_format_xxmc) { xine_xxmc_t *xxmc = &frame->xxmc_data; /* * Are we at all capable of doing XvMC ? */ if (driver->xvmc_cap == 0) return 0; xprintf(driver->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": New format. Need to change XvMC Context.\n" LOG_MODULE ": width: %d height: %d", width, height); if (frame_format_xxmc) { xprintf(driver->xine, XINE_VERBOSITY_LOG, " mpeg: %d acceleration: %d", xxmc->mpeg, xxmc->acceleration); } xprintf(driver->xine, XINE_VERBOSITY_LOG, "\n"); if (frame->xvmc_surf) xxmc_xvmc_free_surface( driver , frame->xvmc_surf); frame->xvmc_surf = NULL; xxmc_dispose_context( driver ); if (frame_format_xxmc && xxmc_find_context( driver, xxmc, width, height )) { xxmc_create_context( driver, width, height); xvmc_check_colorkey_properties( driver ); xxmc_setup_subpictures(driver, width, height); if ((driver->xvmc_accel & (XINE_XVMC_ACCEL_MOCOMP | XINE_XVMC_ACCEL_IDCT))) { if (!xxmc_mocomp_create_macroblocks(driver, frame, 1)) { printf(LOG_MODULE ": ERROR: Macroblock allocation failed\n"); xxmc_dispose_context( driver ); } } } if (!driver->contextActive) { printf(LOG_MODULE ": Using software decoding for this stream.\n"); driver->xvmc_accel = 0; } else { printf(LOG_MODULE ": Using hardware decoding for this stream.\n"); } driver->xvmc_mpeg = xxmc->mpeg; driver->xvmc_width = width; driver->xvmc_height = height; return driver->contextActive; } static void xxmc_frame_updates(xxmc_driver_t *driver, xxmc_frame_t *frame, int init_macroblocks) { xine_xxmc_t *xxmc = &frame->xxmc_data; /* * If we have changed context since the surface was updated, xvmc_surf * is either NULL or invalid. If it is invalid. Set it to NULL. * Also if there are other users of this surface, deregister our use of * it and later try to allocate a new, fresh one. */ if (frame->xvmc_surf) { if (! xxmc_xvmc_surface_valid( driver, frame->xvmc_surf )) { xxmc_xvmc_free_surface(driver , frame->xvmc_surf); frame->xvmc_surf = NULL; } } /* * If it is NULL create a new surface. */ if (frame->xvmc_surf == NULL) { if (NULL == (frame->xvmc_surf = xxmc_xvmc_alloc_surface( driver, &driver->context))) { fprintf(stderr, LOG_MODULE ": ERROR: Accelerated surface allocation failed.\n" LOG_MODULE ": You are probably out of framebuffer memory.\n" LOG_MODULE ": Falling back to software decoding.\n"); driver->xvmc_accel = 0; xxmc_dispose_context( driver ); return; } xxmc->xvmc.macroblocks = (xine_macroblocks_t *) &driver->macroblocks; xxmc->xvmc.macroblocks->xvmc_accel = (driver->unsigned_intra) ? 0 : XINE_VO_SIGNED_INTRA; switch(driver->xvmc_accel) { case XINE_XVMC_ACCEL_IDCT: xxmc->xvmc.macroblocks->xvmc_accel |= XINE_VO_IDCT_ACCEL; break; case XINE_XVMC_ACCEL_MOCOMP: xxmc->xvmc.macroblocks->xvmc_accel |= XINE_VO_MOTION_ACCEL; break; default: xxmc->xvmc.macroblocks->xvmc_accel = 0; } xxmc->proc_xxmc_flush = xvmc_flush; xxmc->proc_xxmc_lock_valid = xxmc_lock_and_validate_surfaces; xxmc->proc_xxmc_unlock = xxmc_unlock_surfaces; xxmc->xvmc.proc_macro_block = xxmc_xvmc_proc_macro_block; frame->vo_frame.proc_duplicate_frame_data = xxmc_duplicate_frame_data; #ifdef HAVE_VLDXVMC xxmc->proc_xxmc_begin = xvmc_vld_frame; xxmc->proc_xxmc_slice = xvmc_vld_slice; #endif } if (init_macroblocks) { driver->macroblocks.num_blocks = 0; driver->macroblocks.macroblockptr = driver->macroblocks.macroblockbaseptr; driver->macroblocks.xine_mc.blockptr = driver->macroblocks.xine_mc.blockbaseptr; } xxmc->acceleration = driver->xvmc_accel; } /* called xlocked */ static void dispose_ximage (xxmc_driver_t *this, XShmSegmentInfo *shminfo, XvImage *myimage) { if (this->use_shm) { XShmDetach (this->display, shminfo); XFree (myimage); shmdt (shminfo->shmaddr); if (shminfo->shmid >= 0) { shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; } } else { _x_freep(&myimage->data); XFree (myimage); } } static void xxmc_do_update_frame_xv(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen; (void)flags; if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } if ((frame->width != (int)width) || (frame->height != (int)height) || (frame->last_sw_format != format)) { frame->width = width; frame->height = height; frame->format = format; frame->last_sw_format = format; XLockDisplay (this->display); /* * (re-) allocate xvimage */ if (frame->image) { dispose_ximage (this, &frame->shminfo, frame->image); frame->image = NULL; } frame->image = create_ximage (this, &frame->shminfo, width, height, format); if( frame->image && format == XINE_IMGFMT_YUY2) { frame->vo_frame.pitches[0] = frame->image->pitches[0]; frame->vo_frame.base[0] = frame->image->data + frame->image->offsets[0]; } else if (frame->image && format == XINE_IMGFMT_YV12) { frame->vo_frame.pitches[0] = frame->image->pitches[0]; frame->vo_frame.pitches[1] = frame->image->pitches[2]; frame->vo_frame.pitches[2] = frame->image->pitches[1]; frame->vo_frame.base[0] = frame->image->data + frame->image->offsets[0]; frame->vo_frame.base[1] = frame->image->data + frame->image->offsets[2]; frame->vo_frame.base[2] = frame->image->data + frame->image->offsets[1]; } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "alert! unsupported image format %04x\n", format); frame->vo_frame.width = frame->width = 0; } XUnlockDisplay (this->display); } frame->ratio = ratio; frame->vo_frame.format = frame->format; } /* * Check if we need to change XvMC context due to an * acceleration request change. */ static int xxmc_accel_update(xxmc_driver_t *driver, uint32_t last_request, uint32_t new_request) { unsigned int k; /* * Same acceleration request. No need to change. */ if (last_request == new_request) return 0; /* * Current acceleration not valid. Change. */ if ((driver->xvmc_accel & new_request) == 0) return 1; /* * Test for possible use of a higher acceleration level. */ for (k = 0; k < NUM_ACCEL_PRIORITY; ++k) { if (last_request & accel_priority[k]) return 0; if (new_request & accel_priority[k]) return 1; } /* * Should never get here. */ return 0; } static void xxmc_do_update_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; xxmc_frame_t *frame = XXMC_FRAME(frame_gen); if ( XINE_IMGFMT_XXMC == format ) { xine_xxmc_t *xxmc = &frame->xxmc_data; vo_frame_t orig_frame_content; if (frame_gen != &frame->vo_frame) { /* this is an intercepted frame, so we need to detect and propagate any * changes on the original vo_frame to all the intercepted frames */ xine_fast_memcpy(&orig_frame_content, &frame->vo_frame, sizeof (vo_frame_t)); } xvmc_context_writer_lock( &this->xvmc_lock); if (xxmc_accel_update(this, this->last_accel_request, xxmc->acceleration) || (this->xvmc_mpeg != xxmc->mpeg) || (this->xvmc_width != width) || (this->xvmc_height != height)) { this->last_accel_request = xxmc->acceleration; xxmc_xvmc_update_context(this, frame, width, height, 1); } else { this->last_accel_request = xxmc->acceleration; } if (this->contextActive) xxmc_frame_updates(this, frame, 1); xxmc_do_update_frame_xv(this_gen, &frame->vo_frame, width, height, ratio, xxmc->fallback_format, flags); if (!this->contextActive) { xxmc->acceleration = 0; xxmc->xvmc.macroblocks = 0; frame->vo_frame.proc_duplicate_frame_data = NULL; } else { frame->format = format; frame->vo_frame.format = format; } xvmc_context_writer_unlock( &this->xvmc_lock); if (frame_gen != &frame->vo_frame) { /* this is an intercepted frame, so we need to detect and propagate any * changes on the original vo_frame to all the intercepted frames */ unsigned char *p0 = (unsigned char *)&orig_frame_content; unsigned char *p1 = (unsigned char *)&frame->vo_frame; unsigned int i; for (i = 0; i < sizeof (vo_frame_t); i++) { if (*p0 != *p1) { /* propagate the change */ vo_frame_t *f = frame_gen; while (f->next) { /* serveral restrictions apply when intercepting XXMC frames. So let's check * the intercepted frames before modifing them and fail otherwise. */ unsigned char *p = (unsigned char *)f + i; if (*p != *p0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "xxmc_do_update_frame: a post plugin violates the restrictions on intercepting XXMC frames\n"); _x_abort(); } *p = *p1; f = f->next; } } p0++; p1++; } } } else { /* switch back to an unaccelerated context */ if (this->last_accel_request != 0xFFFFFFFF) { this->last_accel_request = 0xFFFFFFFF; xxmc_xvmc_update_context(this, frame, width, height, 0); } frame->vo_frame.proc_duplicate_frame_data = NULL; xxmc_do_update_frame_xv(this_gen, &frame->vo_frame, width, height, ratio, format, flags); } } static void xxmc_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { if (format != XINE_IMGFMT_XXMC) { xxmc_do_update_frame(this_gen, frame_gen, width, height, ratio, format, flags); } else { /* * More parameters are needed to xxmc_do_update_frame(). * Register the function as a callback and return. * The decoder needs to call the callback with more parameters * in the xine_xxmc_t structure. */ xine_xxmc_t *xxmc = (xine_xxmc_t *)frame_gen->accel_data; xxmc->decoded = 0; xxmc->proc_xxmc_update_frame = xxmc_do_update_frame; frame_gen->proc_duplicate_frame_data = xxmc_duplicate_frame_data; } } /* * From Xv. */ static int xxmc_clean_output_area (xxmc_driver_t *this, int xvmc_active) { int i, autopainting, ret; XLockDisplay (this->display); XSetForeground (this->display, this->gc, this->black.pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } } /* * XvMC does not support autopainting regardless of whether there's an * Xv attribute for it. However, if there is an XvMC attribute for * autopainting, we should be able to assume it is supported. * That support is checked whenever a context is changed. */ autopainting = (this->props[VO_PROP_AUTOPAINT_COLORKEY].value == 1); if ((xvmc_active && (this->context_flags & XVMC_OVERLAID_SURFACE) && (! this->have_xvmc_autopaint || ! autopainting)) || (! xvmc_active && !autopainting)) { XSetForeground (this->display, this->gc, this->colorkey); XFillRectangle (this->display, this->drawable, this->gc, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); ret = 1; } else { ret = 0; } if (this->xoverlay) { x11osd_resize (this->xoverlay, this->sc.gui_width, this->sc.gui_height); this->ovl_changed = 1; } XUnlockDisplay (this->display); return ret; } /* * convert delivered height/width to ideal width/height * taking into account aspect ratio and zoom factor */ static void xxmc_compute_ideal_size (xxmc_driver_t *this) { _x_vo_scale_compute_ideal_size( &this->sc ); } /* * make ideal width/height "fit" into the gui */ static void xxmc_compute_output_size (xxmc_driver_t *this) { _x_vo_scale_compute_output_size( &this->sc ); } static void xxmc_check_xoverlay_type(xxmc_driver_t *driver, xxmc_frame_t *frame) { int new_overlay_type = (frame->format == XINE_IMGFMT_XXMC) ? driver->xvmc_xoverlay_type : driver->xv_xoverlay_type; if (driver->xoverlay_type != new_overlay_type) { printf("Warning! Changing xoverlay\n"); x11osd_destroy( driver->xoverlay ); driver->xoverlay = x11osd_create( driver->xine, driver->display, driver->screen, driver->drawable, new_overlay_type); driver->xoverlay_type = new_overlay_type; } } static void xxmc_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen; this->ovl_changed += changed; xvmc_context_reader_lock( &this->xvmc_lock ); if ((frame->format == XINE_IMGFMT_XXMC) && !xxmc_xvmc_surface_valid(this, frame->xvmc_surf)) { xvmc_context_reader_unlock( &this->xvmc_lock ); return; } if( this->ovl_changed && this->xoverlay ) { XLockDisplay (this->display); xxmc_check_xoverlay_type(this, frame); x11osd_clear(this->xoverlay); XUnlockDisplay (this->display); } if (this->ovl_changed && (frame->format == XINE_IMGFMT_XXMC) && this->hwSubpictures ) { this->new_subpic = xxmc_xvmc_alloc_subpicture ( this, &this->context, this->xvmc_width, this->xvmc_height, this->xvmc_cap[this->xvmc_cur_cap].subPicType.id); if (this->new_subpic) { this->first_overlay = 1; XVMCLOCKDISPLAY( this->display ); XvMCClearSubpicture(this->display, this->new_subpic, 0,0, this->xvmc_width, this->xvmc_height, 0x00); XVMCUNLOCKDISPLAY( this->display ); _x_clear_xx44_palette(&this->palette); } } xvmc_context_reader_unlock( &this->xvmc_lock ); this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void xxmc_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; xxmc_frame_t *frame = (xxmc_frame_t *) vo_img; if( this->ovl_changed && this->xoverlay ) { XLockDisplay (this->display); x11osd_expose(this->xoverlay); XUnlockDisplay (this->display); } if ((frame->format == XINE_IMGFMT_XXMC) && this->hwSubpictures) { LOCK_AND_SURFACE_VALID( this, frame->xvmc_surf ); if (this->ovl_changed) { if (this->old_subpic) { xxmc_xvmc_free_subpicture(this, this->old_subpic); this->old_subpic = NULL; } if (this->new_subpic) { this->old_subpic = this->new_subpic; this->new_subpic = NULL; _x_xx44_to_xvmc_palette( &this->palette, this->xvmc_palette, 0, this->old_subpic->num_palette_entries, this->old_subpic->entry_bytes, this->reverse_nvidia_palette ? "YVU" : this->old_subpic->component_order); XVMCLOCKDISPLAY( this->display ); XvMCSetSubpicturePalette( this->display, this->old_subpic, this->xvmc_palette); XvMCFlushSubpicture( this->display , this->old_subpic); XvMCSyncSubpicture( this->display, this->old_subpic ); XVMCUNLOCKDISPLAY( this->display ); } } if (this->old_subpic && (! this->first_overlay)) { XVMCLOCKDISPLAY( this->display ); if (this->xvmc_backend_subpic ) { XvMCBlendSubpicture( this->display, frame->xvmc_surf, this->old_subpic,0,0,this->xvmc_width, this->xvmc_height, 0, 0, this->xvmc_width, this->xvmc_height ); } else { XvMCBlendSubpicture2( this->display, frame->xvmc_surf, frame->xvmc_surf, this->old_subpic, 0,0,this->xvmc_width, this->xvmc_height,0,0,this->xvmc_width, this->xvmc_height); } XVMCUNLOCKDISPLAY( this->display ); } xvmc_context_reader_unlock(&this->xvmc_lock ); } this->ovl_changed = 0; } static void xxmc_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen; if (overlay->rle) { this->scaled_osd_active = !overlay->unscaled; if( overlay->unscaled ) { if( this->ovl_changed && this->xoverlay ) { XLockDisplay (this->display); x11osd_blend(this->xoverlay, overlay); XUnlockDisplay (this->display); } } else if (frame->format == XINE_IMGFMT_XXMC) { if (this->ovl_changed && this->hwSubpictures) { if (this->new_subpic) { int x0, y0, x1, y1, w, h; LOCK_AND_SURFACE_VALID( this, frame->xvmc_surf ); if (this->first_overlay) { memset(this->subImage->data,0,this->subImage->width* this->subImage->height); this->first_overlay = 0; } _x_blend_xx44(this->subImage->data, overlay, this->subImage->width, this->subImage->height, this->subImage->width, &this->alphablend_extra_data, &this->palette, (this->subImage->id == FOURCC_IA44)); /* clip overlay against sub image like in _x_blend_xx44() */ x0 = overlay->x; y0 = overlay->y; x1 = x0 + overlay->width; y1 = y0 + overlay->height; w = this->subImage->width; h = this->subImage->height; x0 = (x0 < 0) ? 0 : ((x0 > w) ? w : x0); y0 = (y0 < 0) ? 0 : ((y0 > h) ? h : y0); x1 = (x1 < 0) ? 0 : ((x1 > w) ? w : x1); y1 = (y1 < 0) ? 0 : ((y1 > h) ? h : y1); /* anything left after clipping? */ if (x0 != x1 && y0 != y1) { XVMCLOCKDISPLAY( this->display ); XvMCCompositeSubpicture( this->display, this->new_subpic, this->subImage, x0, y0, x1 - x0, y1 - y0, x0, y0); XVMCUNLOCKDISPLAY( this->display ); } xvmc_context_reader_unlock( &this->xvmc_lock ); } } } else { if (frame->format == XINE_IMGFMT_YV12) { _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); } else { _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } } } static void xxmc_add_recent_frame (xxmc_driver_t *this, xxmc_frame_t *frame) { int i; i = VO_NUM_RECENT_FRAMES-1; if( this->recent_frames[i] ) { this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); } for( ; i ; i-- ) this->recent_frames[i] = this->recent_frames[i-1]; this->recent_frames[0] = frame; } static int xv_flush_recent_frames (xxmc_driver_t *this) { int i, n = 0; for (i = 0; i < VO_NUM_RECENT_FRAMES; i++) { if (this->recent_frames[i]) { this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; n++; } } return n; } static int xxmc_redraw_needed (vo_driver_t *this_gen) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; int ret = 0; if( this->cur_frame ) { this->sc.delivered_height = this->cur_frame->height; this->sc.delivered_width = this->cur_frame->width; this->sc.delivered_ratio = this->cur_frame->ratio; this->sc.crop_left = this->cur_frame->vo_frame.crop_left; this->sc.crop_right = this->cur_frame->vo_frame.crop_right; this->sc.crop_top = this->cur_frame->vo_frame.crop_top; this->sc.crop_bottom = this->cur_frame->vo_frame.crop_bottom; xxmc_compute_ideal_size(this); if( _x_vo_scale_redraw_needed( &this->sc ) ) { xxmc_compute_output_size (this); xxmc_clean_output_area (this, (this->cur_frame->format == XINE_IMGFMT_XXMC)); ret = 1; } } else ret = 1; return ret; } static void xxmc_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; xxmc_frame_t *frame = (xxmc_frame_t *) frame_gen; xine_xxmc_t *xxmc = &frame->xxmc_data; int first_field; int disable_deinterlace = 0; struct timeval tv_top; /* * take time to calculate the time to sleep for the bottom field */ gettimeofday(&tv_top, 0); /* * bob deinterlacing doesn't make much sense for still images or at replay speeds * other than 100 %, so let's disable deinterlacing at all for this frame */ if (this->deinterlace_enabled && this->bob) { disable_deinterlace = (this->disable_bob_for_progressive_frames && frame->vo_frame.progressive_frame) || (this->disable_bob_for_scaled_osd && this->scaled_osd_active) || !frame->vo_frame.stream || xine_get_param(frame->vo_frame.stream, XINE_PARAM_FINE_SPEED) != XINE_FINE_SPEED_NORMAL; if (!disable_deinterlace) { int vo_bufs_in_fifo = 0; _x_query_buffer_usage(frame->vo_frame.stream, NULL, NULL, &vo_bufs_in_fifo, NULL); disable_deinterlace = (vo_bufs_in_fifo <= 0); } } /* * reset this flag now -- it will be set again before the next call to * xxmc_display_frame() as long as there is a scaled OSD active on screen. */ this->scaled_osd_active = 0; /* * queue frames (deinterlacing) * free old frames */ xvmc_context_reader_lock( &this->xvmc_lock ); /* * the current implementation doesn't need recent frames for deinterlacing, * but we need to hold references on the frame we are about to show and to * the previous frame which is currently shown on screen. Otherwise, the * frame on screen will be immediately reused for decoding which will then * most often result in mixed images on screen, especially when decoding * is faster than sending the image to the monitor, and/or when exchanging * the overlay image is synced to retrace. */ xxmc_add_recent_frame (this, frame); /* deinterlacing */ if ((frame->format == XINE_IMGFMT_XXMC) && (!xxmc->decoded || !xxmc_xvmc_surface_valid(this, frame->xvmc_surf))) { xvmc_context_reader_unlock( &this->xvmc_lock ); return; } this->cur_frame = frame; /* * let's see if this frame is different in size / aspect * ratio from the previous one */ if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) || (frame->vo_frame.crop_left != this->sc.crop_left) || (frame->vo_frame.crop_right != this->sc.crop_right) || (frame->vo_frame.crop_top != this->sc.crop_top) || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) { lprintf("frame format changed\n"); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } /* * tell gui that we are about to display a frame, * ask for offset and output size */ first_field = (frame->vo_frame.top_field_first) ? XVMC_TOP_FIELD : XVMC_BOTTOM_FIELD; first_field = (this->bob) ? first_field : XVMC_TOP_FIELD; this->cur_field = (this->deinterlace_enabled && !disable_deinterlace) ? first_field : XVMC_FRAME_PICTURE; xxmc_redraw_needed (this_gen); if (frame->format == XINE_IMGFMT_XXMC) { XVMCLOCKDISPLAY( this->display ); XvMCSyncSurface( this->display, frame->xvmc_surf ); XLockDisplay( this->display ); /* blocks XINE_GUI_SEND_DRAWABLE_CHANGED from changing drawable */ XvMCPutSurface( this->display, frame->xvmc_surf , this->drawable, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, this->cur_field); XUnlockDisplay( this->display ); /* unblocks XINE_GUI_SEND_DRAWABLE_CHANGED from changing drawable */ XVMCUNLOCKDISPLAY( this->display ); if (this->deinterlace_enabled && !disable_deinterlace && this->bob) { struct timeval tv_middle; long us_spent_so_far, us_per_field = frame->vo_frame.duration * 50 / 9; gettimeofday(&tv_middle, 0); us_spent_so_far = (tv_middle.tv_sec - tv_top.tv_sec) * 1000000 + (tv_middle.tv_usec - tv_top.tv_usec); if (us_spent_so_far < 0) us_spent_so_far = 0; /* * typically, the operations above take just a few milliseconds, but when the * driver actively waits to sync on the next field, we better skip showing the * other field as it would lead to further busy waiting * so display the other field only if we've spent less than 75 % of the per * field time so far */ if (4 * us_spent_so_far < 3 * us_per_field) { long us_delay = (us_per_field - 2000) - us_spent_so_far; if (us_delay > 0) { xvmc_context_reader_unlock( &this->xvmc_lock ); xine_usec_sleep(us_delay); LOCK_AND_SURFACE_VALID( this, frame->xvmc_surf ); } this->cur_field = (frame->vo_frame.top_field_first) ? XVMC_BOTTOM_FIELD : XVMC_TOP_FIELD; XVMCLOCKDISPLAY( this->display ); XLockDisplay( this->display ); /* blocks XINE_GUI_SEND_DRAWABLE_CHANGED from changing drawable */ XvMCPutSurface( this->display, frame->xvmc_surf , this->drawable, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, this->cur_field); XUnlockDisplay( this->display ); /* unblocks XINE_GUI_SEND_DRAWABLE_CHANGED from changing drawable */ XVMCUNLOCKDISPLAY( this->display ); } } } else { XLockDisplay (this->display); if (this->use_shm) { XvShmPutImage(this->display, this->xv_port, this->drawable, this->gc, frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, True); } else { XvPutImage(this->display, this->xv_port, this->drawable, this->gc, frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } XSync(this->display, False); XUnlockDisplay (this->display); } xvmc_context_reader_unlock( &this->xvmc_lock ); } static int xxmc_get_property (vo_driver_t *this_gen, int property) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; switch (property) { case VO_PROP_WINDOW_WIDTH: this->props[property].value = this->sc.gui_width; break; case VO_PROP_WINDOW_HEIGHT: this->props[property].value = this->sc.gui_height; break; case VO_PROP_OUTPUT_WIDTH: this->props[property].value = this->sc.output_width; break; case VO_PROP_OUTPUT_HEIGHT: this->props[property].value = this->sc.output_height; break; case VO_PROP_OUTPUT_XOFFSET: this->props[property].value = this->sc.output_xoffset; break; case VO_PROP_OUTPUT_YOFFSET: this->props[property].value = this->sc.output_yoffset; break; } lprintf("%s: property #%d = %d\n", LOG_MODULE, property, this->props[property].value); return this->props[property].value; } static void xxmc_property_callback (void *property_gen, xine_cfg_entry_t *entry) { xxmc_property_t *property = (xxmc_property_t *) property_gen; xxmc_driver_t *this = property->this; xvmc_context_reader_lock( &this->xvmc_lock ); XLockDisplay (this->display); XvSetPortAttribute (this->display, this->xv_port, property->atom, entry->num_value); XUnlockDisplay (this->display); if (this->contextActive) { XVMCLOCKDISPLAY( this->display ); XvMCSetAttribute(this->display, &this->context, property->atom, entry->num_value); XVMCUNLOCKDISPLAY( this->display ); } xvmc_context_reader_unlock( &this->xvmc_lock ); } static int xxmc_set_property (vo_driver_t *this_gen, int property, int value) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; if (this->props[property].atom != None) { /* value is out of bound */ if((value < this->props[property].min) || (value > this->props[property].max)) value = (this->props[property].min + this->props[property].max) >> 1; xvmc_context_reader_lock( &this->xvmc_lock ); if (this->contextActive) { XVMCLOCKDISPLAY( this->display ); XvMCSetAttribute(this->display, &this->context, this->props[property].atom, value); XVMCUNLOCKDISPLAY( this->display ); } xvmc_context_reader_unlock( &this->xvmc_lock ); XLockDisplay (this->display); XvSetPortAttribute (this->display, this->xv_port, this->props[property].atom, value); XvGetPortAttribute (this->display, this->xv_port, this->props[property].atom, &this->props[property].value); XUnlockDisplay (this->display); if (this->props[property].entry) this->props[property].entry->num_value = this->props[property].value; return this->props[property].value; } else { switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) value = xv_flush_recent_frames (this); break; case VO_PROP_INTERLACED: this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_INTERLACED(%d)\n", this->props[property].value); this->deinterlace_enabled = value; break; case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ASPECT_RATIO(%d)\n", this->props[property].value); this->sc.user_ratio = value; xxmc_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ break; case VO_PROP_ZOOM_X: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ZOOM_X = %d\n", this->props[property].value); this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; xxmc_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; case VO_PROP_ZOOM_Y: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ZOOM_Y = %d\n", this->props[property].value); this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; xxmc_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; } } return value; } static void xxmc_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) { *min = *max = 0; return; } *min = this->props[property].min; *max = this->props[property].max; } static int xxmc_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: { /* XExposeEvent * xev = (XExposeEvent *) data; */ if (this->cur_frame) { xxmc_frame_t *frame = this->cur_frame; xine_xxmc_t *xxmc = &frame->xxmc_data; xvmc_context_reader_lock( &this->xvmc_lock ); if ((frame->format == XINE_IMGFMT_XXMC) && (!xxmc->decoded || !xxmc_xvmc_surface_valid(this, frame->xvmc_surf))) { xvmc_context_reader_unlock( &this->xvmc_lock ); if (! xxmc_redraw_needed (this_gen)) xxmc_clean_output_area(this, (frame->format == XINE_IMGFMT_XXMC)); break; } if (!xxmc_redraw_needed (this_gen) && !this->xoverlay) xxmc_clean_output_area(this,(frame->format == XINE_IMGFMT_XXMC)); if (frame->format == XINE_IMGFMT_XXMC) { XVMCLOCKDISPLAY( this->display ); XvMCSyncSurface( this->display, frame->xvmc_surf ); XvMCPutSurface( this->display, frame->xvmc_surf, this->drawable, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, this->cur_field); XVMCUNLOCKDISPLAY( this->display ); } else { XLockDisplay (this->display); if (this->use_shm) { XvShmPutImage(this->display, this->xv_port, this->drawable, this->gc, frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, True); } else { XvPutImage(this->display, this->xv_port, this->drawable, this->gc, frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } XSync(this->display, False); XUnlockDisplay (this->display); } xvmc_context_reader_unlock( &this->xvmc_lock ); } if(this->xoverlay) x11osd_expose(this->xoverlay); } break; case XINE_GUI_SEND_DRAWABLE_CHANGED: XLockDisplay (this->display); this->drawable = (Drawable) data; XFreeGC(this->display, this->gc); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); if(this->xoverlay) x11osd_drawable_changed(this->xoverlay, this->drawable); this->ovl_changed = 1; XUnlockDisplay (this->display); this->sc.force_redraw = 1; break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void xxmc_dispose (vo_driver_t *this_gen) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; int i; if (this->xvmc_cap) { xvmc_context_writer_lock( &this->xvmc_lock ); xxmc_dispose_context( this ); if (this->old_subpic) { xxmc_xvmc_free_subpicture(this, this->old_subpic); this->old_subpic = NULL; } if (this->new_subpic) { xxmc_xvmc_free_subpicture(this, this->new_subpic); this->new_subpic = NULL; } xvmc_context_writer_unlock( &this->xvmc_lock ); } XLockDisplay (this->display); if(XvUngrabPort (this->display, this->xv_port, CurrentTime) != Success) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": xxmc_exit: XvUngrabPort() failed.\n"); } XFreeGC(this->display, this->gc); XUnlockDisplay (this->display); for( i=0; i < VO_NUM_RECENT_FRAMES; i++ ) { if( this->recent_frames[i] ) this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; } if( this->xoverlay ) { XLockDisplay (this->display); x11osd_destroy (this->xoverlay); XUnlockDisplay (this->display); } free_context_lock(&this->xvmc_lock); _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); free (this); } /* called xlocked */ static int xxmc_check_yv12 (Display *display, XvPortID port) { XvImageFormatValues *formatValues; int formats; int i; formatValues = XvListImageFormats (display, port, &formats); for (i = 0; i < formats; i++) if ((formatValues[i].id == XINE_IMGFMT_YV12) && (! (strcmp (formatValues[i].guid, "YV12")))) { XFree (formatValues); return 0; } XFree (formatValues); return 1; } /* called xlocked */ static void xxmc_check_capability (xxmc_driver_t *this, int property, XvAttribute attr, int base_id, const char *config_name, const char *config_desc, const char *config_help) { int int_default; cfg_entry_t *entry; const char *str_prop = attr.name; (void)base_id; if (VO_PROP_COLORKEY && (attr.max_value == ~0)) attr.max_value = 2147483615; this->props[property].min = attr.min_value; this->props[property].max = attr.max_value; this->props[property].atom = XInternAtom (this->display, str_prop, False); XvGetPortAttribute (this->display, this->xv_port, this->props[property].atom, &int_default); xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": port attribute %s (%d) value is %d\n", str_prop, property, int_default); /* * We enable autopaint by default. */ if(strcmp(str_prop, "XV_AUTOPAINT_COLORKEY") == 0) int_default = 1; if (config_name) { /* is this a boolean property ? */ if ((attr.min_value == 0) && (attr.max_value == 1)) { this->config->register_bool (this->config, config_name, int_default, config_desc, config_help, 20, xxmc_property_callback, &this->props[property]); } else { this->config->register_range (this->config, config_name, int_default, this->props[property].min, this->props[property].max, config_desc, config_help, 20, xxmc_property_callback, &this->props[property]); } entry = this->config->lookup_entry (this->config, config_name); if((entry->num_value < this->props[property].min) || (entry->num_value > this->props[property].max)) { this->config->update_num(this->config, config_name, ((this->props[property].min + this->props[property].max) >> 1)); entry = this->config->lookup_entry (this->config, config_name); } this->props[property].entry = entry; xxmc_set_property (&this->vo_driver, property, entry->num_value); if (strcmp(str_prop, "XV_COLORKEY") == 0) { this->use_colorkey |= 1; this->colorkey = entry->num_value; } else if(strcmp(str_prop, "XV_AUTOPAINT_COLORKEY") == 0) { if(entry->num_value==1) this->use_colorkey |= 2; } } else this->props[property].value = int_default; } static void xxmc_update_attr (void *this_gen, xine_cfg_entry_t *entry, const char *atomstr, const char *debugstr) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; Atom atom; XLockDisplay(this->display); atom = XInternAtom (this->display, atomstr, False); XvSetPortAttribute (this->display, this->xv_port, atom, entry->num_value); XUnlockDisplay(this->display); xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": %s = %d\n", debugstr, entry->num_value); } static void xxmc_update_XV_FILTER(void *this_gen, xine_cfg_entry_t *entry) { xxmc_update_attr (this_gen, entry, "XV_FILTER", "bilinear scaling mode"); } static void xxmc_update_XV_DOUBLE_BUFFER(void *this_gen, xine_cfg_entry_t *entry) { xxmc_update_attr (this_gen, entry, "XV_DOUBLE_BUFFER", "double buffering mode"); } static void xxmc_update_XV_BICUBIC(void *this_gen, xine_cfg_entry_t *entry) { xxmc_update_attr (this_gen, entry, "XV_BICUBIC", "bicubic filtering mode"); } static void xxmc_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; this->use_pitch_alignment = entry->num_value; } static void xxmc_update_cpu_save(void *this_gen, xine_cfg_entry_t *entry) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; this->cpu_save_enabled = entry->num_value; } static void xxmc_update_nvidia_fix(void *this_gen, xine_cfg_entry_t *entry) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; this->reverse_nvidia_palette = entry->num_value; } static void xxmc_update_bob(void *this_gen, xine_cfg_entry_t *entry) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; this->bob = entry->num_value; } static void xxmc_update_disable_bob_for_progressive_frames(void *this_gen, xine_cfg_entry_t *entry) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; this->disable_bob_for_progressive_frames = entry->num_value; } static void xxmc_update_disable_bob_for_scaled_osd(void *this_gen, xine_cfg_entry_t *entry) { xxmc_driver_t *this = (xxmc_driver_t *) this_gen; this->disable_bob_for_scaled_osd = entry->num_value; } static int xxmc_open_port (xxmc_driver_t *this, XvPortID port) { int ret; x11_InstallXErrorHandler (this); ret = ! xxmc_check_yv12(this->display, port) && XvGrabPort(this->display, port, 0) == Success; x11_DeInstallXErrorHandler (this); return ret; } static unsigned int xxmc_find_adaptor_by_port (int port, unsigned int adaptors, XvAdaptorInfo *adaptor_info) { unsigned int an; for (an = 0; an < adaptors; an++) if (adaptor_info[an].type & XvImageMask) if (port >= (int)adaptor_info[an].base_id && port < (int)(adaptor_info[an].base_id + adaptor_info[an].num_ports)) return an; return 0; /* shouldn't happen */ } static XvPortID xxmc_autodetect_port(xxmc_driver_t *this, unsigned int adaptors, XvAdaptorInfo *adaptor_info, unsigned int *adaptor_num, XvPortID base, xv_prefertype prefer_type) { unsigned int an, j; for (an = 0; an < adaptors; an++) if (adaptor_info[an].type & XvImageMask && (prefer_type == xv_prefer_none || strcasestr (adaptor_info[an].name, prefer_substrings[prefer_type]))) for (j = 0; j < adaptor_info[an].num_ports; j++) { XvPortID port = adaptor_info[an].base_id + j; if (port >= base && xxmc_open_port(this, port)) { *adaptor_num = an; return port; } } return 0; } static void checkXvMCCap( xxmc_driver_t *this, XvPortID xv_port) { int numSurf,numSub,i,j; XvMCSurfaceInfo *surfaceInfo,*curInfo; XvMCContext c; xvmc_capabilities_t *curCap; XvImageFormatValues *formatValues; this->xvmc_cap = 0; init_context_lock( &this->xvmc_lock ); xvmc_context_writer_lock( &this->xvmc_lock ); this->old_subpic = NULL; this->new_subpic = NULL; this->contextActive = 0; this->subImage = NULL; this->hwSubpictures = 0; this->xvmc_palette = NULL; XVMCLOCKDISPLAY( this->display ); if ( !XvMCQueryExtension(this->display, &this->xvmc_eventbase, &this->xvmc_errbase)) { XVMCUNLOCKDISPLAY( this->display ); xvmc_context_writer_unlock( &this->xvmc_lock ); return; } xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": XvMC extension present.\n"); surfaceInfo = XvMCListSurfaceTypes(this->display, xv_port, &numSurf); if (0 == surfaceInfo) { XVMCUNLOCKDISPLAY( this->display ); xvmc_context_writer_unlock( &this->xvmc_lock ); return; } this->xvmc_cap = (xvmc_capabilities_t *)calloc(numSurf, sizeof(xvmc_capabilities_t)); if (NULL == this->xvmc_cap) { XVMCUNLOCKDISPLAY( this->display ); xvmc_context_writer_unlock( &this->xvmc_lock ); return; } this->xvmc_num_cap = numSurf; curInfo = surfaceInfo; curCap = this->xvmc_cap; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Found %d XvMC surface types\n", numSurf); for (i=0; i< numSurf; ++i) { curCap->mpeg_flags = 0; curCap->accel_flags = 0; if (curInfo->chroma_format == XVMC_CHROMA_FORMAT_420) { curCap->mpeg_flags |= ((curInfo->mc_type & XVMC_MPEG_1) ? XINE_XVMC_MPEG_1 : 0); curCap->mpeg_flags |= ((curInfo->mc_type & XVMC_MPEG_2) ? XINE_XVMC_MPEG_2 : 0); curCap->mpeg_flags |= ((curInfo->mc_type & XVMC_MPEG_4) ? XINE_XVMC_MPEG_4 : 0); curCap->accel_flags |= ((curInfo->mc_type & XVMC_VLD) ? XINE_XVMC_ACCEL_VLD : 0); curCap->accel_flags |= ((curInfo->mc_type & XVMC_IDCT) ? XINE_XVMC_ACCEL_IDCT : 0); curCap->accel_flags |= ((curInfo->mc_type & (XVMC_VLD | XVMC_IDCT)) ? 0 : XINE_XVMC_ACCEL_MOCOMP); curCap->max_width = curInfo->max_width; curCap->max_height = curInfo->max_height; curCap->sub_max_width = curInfo->subpicture_max_width; curCap->sub_max_height = curInfo->subpicture_max_height; curCap->flags = curInfo->flags; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Surface type %d: Max size: %d %d.\n", i,curCap->max_width,curCap->max_height); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Surface type %d: Max subpic size: %d %d.\n", i,curCap->sub_max_width,curCap->sub_max_height); curCap->type_id = curInfo->surface_type_id; formatValues = XvMCListSubpictureTypes( this->display, xv_port, curCap->type_id, &numSub); curCap->subPicType.id = 0; if (formatValues) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Surface type %d: Found %d XvMC subpicture types\n",i,numSub); for (j = 0; jsubPicType = formatValues[j]; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Surface type %d: Detected and using IA44 subpicture type.\n",i); /* Prefer IA44 */ break; } else if (formatValues[j].id == FOURCC_AI44) { curCap->subPicType = formatValues[j]; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Surface type %d: Detected AI44 subpicture type.\n",i); } } } XFree(formatValues); curInfo++; curCap++; } } XFree(surfaceInfo); /* * Try to create a direct rendering context. This will fail if we are not * on the displaying computer or an indirect context is not available. */ curCap = this->xvmc_cap; if (Success == XvMCCreateContext( this->display, xv_port, curCap->type_id, curCap->max_width,curCap->max_height, XVMC_DIRECT, &c)) { this->context_flags = XVMC_DIRECT; } else if (Success == XvMCCreateContext( this->display, xv_port, curCap->type_id, curCap->max_width,curCap->max_height, 0, &c)) { this->context_flags = 0; } else { free(this->xvmc_cap); this->xvmc_cap = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": Apparent attempt to use a direct XvMC context on a remote display.\n" LOG_MODULE ": Falling back to Xv.\n"); XVMCUNLOCKDISPLAY( this->display ); xvmc_context_writer_unlock( &this->xvmc_lock ); return; } XvMCDestroyContext( this->display, &c); xxmc_xvmc_surface_handler_construct(this); this->capabilities |= VO_CAP_XXMC; XVMCUNLOCKDISPLAY( this->display ); _x_init_xx44_palette( &this->palette , 0); this->last_accel_request = 0xFFFFFFFF; xvmc_context_writer_unlock( &this->xvmc_lock ); return; } static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { xxmc_class_t *class = (xxmc_class_t *) class_gen; config_values_t *config = class->xine->config; xxmc_driver_t *this; int i, formats; XvAttribute *attr; XvImageFormatValues *fo; int nattr; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; XColor dummy; XvImage *myimage; unsigned int adaptors; unsigned int ver,rel,req,ev,err; XShmSegmentInfo myshminfo; XvPortID xv_port; XvAdaptorInfo *adaptor_info; unsigned int adaptor_num; xv_prefertype prefer_type; cfg_entry_t *entry; int use_more_frames; int use_unscaled; this = calloc(1, sizeof (xxmc_driver_t)); if (!this) return NULL; _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->display = visual->display; this->screen = visual->screen; this->config = config; /* * check for Xvideo support */ XLockDisplay(this->display); if (Success != XvQueryExtension(this->display, &ver,&rel, &req, &ev,&err)) { xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: Xv extension not present.\n"), LOG_MODULE); XUnlockDisplay(this->display); return NULL; } /* * check adaptors, search for one that supports (at least) yuv12 */ if (Success != XvQueryAdaptors(this->display,DefaultRootWindow(this->display), &adaptors, &adaptor_info)) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": XvQueryAdaptors failed.\n"); XUnlockDisplay(this->display); return NULL; } xv_port = config->register_num (config, "video.device.xv_port", 0, VIDEO_DEVICE_XV_PORT_HELP, 20, NULL, NULL); prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0, (char **)prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP, 10, NULL, NULL); if (xv_port != 0) { if (! xxmc_open_port(this, xv_port)) { xprintf(class->xine, XINE_VERBOSITY_NONE, _("%s: could not open Xv port %lu - autodetecting\n"), LOG_MODULE, (unsigned long)xv_port); xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, xv_port, prefer_type); } else adaptor_num = xxmc_find_adaptor_by_port (xv_port, adaptors, adaptor_info); } if (!xv_port) xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, prefer_type); if (!xv_port) { if (prefer_type) xprintf(class->xine, XINE_VERBOSITY_NONE, _("%s: no available ports of type \"%s\", defaulting...\n"), LOG_MODULE, prefer_labels[prefer_type]); xv_port = xxmc_autodetect_port(this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none); } if (!xv_port) { xprintf(class->xine, XINE_VERBOSITY_LOG, _("%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n"), LOG_MODULE); /* XvFreeAdaptorInfo (adaptor_info); this crashed on me (gb)*/ XUnlockDisplay(this->display); return NULL; } else xprintf(class->xine, XINE_VERBOSITY_LOG, _("%s: using Xv port %ld from adaptor %s for hardware " "colour space conversion and scaling.\n"), LOG_MODULE, xv_port, adaptor_info[adaptor_num].name); XUnlockDisplay(this->display); this->xv_port = xv_port; _x_vo_scale_init (&this->sc, 1, 0, config ); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; this->drawable = visual->d; XLockDisplay (this->display); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); XUnlockDisplay (this->display); this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; this->use_shm = 1; this->use_colorkey = 0; this->colorkey = 0; this->xoverlay = NULL; this->ovl_changed = 0; this->x11_old_error_handler = NULL; this->xine = class->xine; XLockDisplay (this->display); XAllocNamedColor (this->display, DefaultColormap(this->display, this->screen), "black", &this->black, &dummy); XUnlockDisplay (this->display); this->vo_driver.get_capabilities = xxmc_get_capabilities; this->vo_driver.alloc_frame = xxmc_alloc_frame; this->vo_driver.update_frame_format = xxmc_update_frame_format; this->vo_driver.overlay_begin = xxmc_overlay_begin; this->vo_driver.overlay_blend = xxmc_overlay_blend; this->vo_driver.overlay_end = xxmc_overlay_end; this->vo_driver.display_frame = xxmc_display_frame; this->vo_driver.get_property = xxmc_get_property; this->vo_driver.set_property = xxmc_set_property; this->vo_driver.get_property_min_max = xxmc_get_property_min_max; this->vo_driver.gui_data_exchange = xxmc_gui_data_exchange; this->vo_driver.dispose = xxmc_dispose; this->vo_driver.redraw_needed = xxmc_redraw_needed; /* * init properties */ for (i = 0; i < VO_NUM_PROPERTIES; i++) { this->props[i].value = 0; this->props[i].min = 0; this->props[i].max = 0; this->props[i].atom = None; this->props[i].entry = NULL; this->props[i].this = this; } this->props[VO_PROP_INTERLACED].value = 0; this->sc.user_ratio = this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; this->props[VO_PROP_ZOOM_X].value = 100; this->props[VO_PROP_ZOOM_Y].value = 100; /* * check this adaptor's capabilities */ XLockDisplay (this->display); attr = XvQueryPortAttributes(this->display, xv_port, &nattr); if(attr && nattr) { int k; for(k = 0; k < nattr; k++) { if((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) { const char *const name = attr[k].name; if(!strcmp(name, "XV_HUE")) { if (!strncmp(adaptor_info[adaptor_num].name, "NV", 2)) { xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); } else { this->capabilities |= VO_CAP_HUE; xxmc_check_capability (this, VO_PROP_HUE, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } } else if(!strcmp(name, "XV_SATURATION")) { this->capabilities |= VO_CAP_SATURATION; xxmc_check_capability (this, VO_PROP_SATURATION, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(name, "XV_BRIGHTNESS")) { this->capabilities |= VO_CAP_BRIGHTNESS; xxmc_check_capability (this, VO_PROP_BRIGHTNESS, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(name, "XV_CONTRAST")) { this->capabilities |= VO_CAP_CONTRAST; xxmc_check_capability (this, VO_PROP_CONTRAST, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(name, "XV_GAMMA")) { this->capabilities |= VO_CAP_GAMMA; xxmc_check_capability (this, VO_PROP_GAMMA, attr[k], adaptor_info[adaptor_num].base_id, NULL, NULL, NULL); } else if(!strcmp(name, "XV_COLORKEY")) { this->capabilities |= VO_CAP_COLORKEY; xxmc_check_capability (this, VO_PROP_COLORKEY, attr[k], adaptor_info[adaptor_num].base_id, "video.device.xv_colorkey", VIDEO_DEVICE_XV_COLORKEY_HELP); } else if(!strcmp(name, "XV_AUTOPAINT_COLORKEY")) { this->capabilities |= VO_CAP_AUTOPAINT_COLORKEY; xxmc_check_capability (this, VO_PROP_AUTOPAINT_COLORKEY, attr[k], adaptor_info[adaptor_num].base_id, "video.device.xv_autopaint_colorkey", VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); } else if(!strcmp(name, "XV_FILTER")) { int xv_filter; /* This setting is specific to Permedia 2/3 cards. */ xv_filter = config->register_range (config, "video.device.xv_filter", 0, attr[k].min_value, attr[k].max_value, VIDEO_DEVICE_XV_FILTER_HELP, 20, xxmc_update_XV_FILTER, this); config->update_num(config,"video.device.xv_filter",xv_filter); } else if(!strcmp(name, "XV_DOUBLE_BUFFER")) { int xv_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, 20, xxmc_update_XV_DOUBLE_BUFFER, this); config->update_num(config,"video.device.xv_double_buffer",xv_double_buffer); } else if(!strcmp(name, "XV_BICUBIC")) { int xv_bicubic = config->register_enum (config, "video.device.xv_bicubic", 2, (char **)bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP, 20, xxmc_update_XV_BICUBIC, this); config->update_num(config,"video.device.xv_bicubic",xv_bicubic); } } } XFree(attr); } else xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": no port attributes defined.\n"); XvFreeAdaptorInfo(adaptor_info); /* * check XvMC capabilities */ checkXvMCCap( this, xv_port ); /* * check supported image formats */ fo = XvListImageFormats(this->display, this->xv_port, (int*)&formats); XUnlockDisplay (this->display); this->xv_format_yv12 = 0; this->xv_format_yuy2 = 0; for(i = 0; i < formats; i++) { lprintf ("Xv image format: 0x%x (%4.4s) %s\n", fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); switch (fo[i].id) { case XINE_IMGFMT_YV12: this->xv_format_yv12 = fo[i].id; this->capabilities |= VO_CAP_YV12; xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); break; case XINE_IMGFMT_YUY2: this->xv_format_yuy2 = fo[i].id; this->capabilities |= VO_CAP_YUY2; xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); break; default: break; } } if(fo) { XLockDisplay(this->display); XFree(fo); XUnlockDisplay(this->display); } /* * try to create a shared image * to find out if MIT shm really works, using supported format */ XLockDisplay (this->display); myimage = create_ximage (this, &myshminfo, 100, 100, (this->xv_format_yv12 != 0) ? XINE_IMGFMT_YV12 : XINE_IMGFMT_YUY2); dispose_ximage (this, &myshminfo, myimage); XUnlockDisplay (this->display); this->use_pitch_alignment = config->register_bool (config, "video.device.xv_pitch_alignment", 0, VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP, 10, xxmc_update_xv_pitch_alignment, this); use_more_frames= config->register_bool (config, "video.device.xvmc_more_frames", 0, _("Make XvMC allocate more frames for better buffering."), _("Some XvMC implementations allow more than 8 frames.\n" "This option, when turned on, makes the driver try to\n" "allocate 15 frames. A must for unichrome and live VDR.\n"), 10, NULL, this); this->cpu_save_enabled = config->register_bool (config, "video.device.unichrome_cpu_save", 0, _("Unichrome cpu save"), _("Saves CPU time by sleeping while decoder works.\n" "Only for Linux kernel 2.6 series or 2.4 with multimedia patch.\n" "Experimental.\n"), 10, xxmc_update_cpu_save, this); this->reverse_nvidia_palette = config->register_bool (config, "video.device.xvmc_nvidia_color_fix", 0, _("Fix buggy NVIDIA XvMC subpicture colours"), _("There's a bug in NVIDIA's XvMC lib that makes red OSD colours\n" "look blue and vice versa. This option provides a workaround.\n"), 10, xxmc_update_nvidia_fix, this); this->bob = config->register_bool (config, "video.device.xvmc_bob_deinterlacing", 0, _("Use bob as accelerated deinterlace method."), _("When interlacing is enabled for hardware accelerated frames,\n" "alternate between top and bottom field at double the frame rate.\n"), 10, xxmc_update_bob, this); this->disable_bob_for_progressive_frames = config->register_bool (config, "video.device.xvmc_disable_bob_deinterlacing_for_progressive_frames", 0, _("Don't use bob deinterlacing for progressive frames."), _("Progressive frames don't need deinterlacing, so disabling it on\n" "demand should result in a better picture.\n"), 10, xxmc_update_disable_bob_for_progressive_frames, this); this->disable_bob_for_scaled_osd = config->register_bool (config, "video.device.xvmc_disable_bob_deinterlacing_for_scaled_osd", 0, _("Don't use bob deinterlacing while a scaled OSD is active."), _("Bob deinterlacing adds some noise to horizontal lines, so disabling it\n" "on demand should result in a better OSD picture.\n"), 10, xxmc_update_disable_bob_for_scaled_osd, this); this->deinterlace_enabled = 0; this->cur_field = XVMC_FRAME_PICTURE; #ifdef HAVE_VLDXVMC printf("%s: Unichrome CPU saving is %s.\n", LOG_MODULE, (this->cpu_save_enabled) ? "on":"off"); #else printf("%s: warning - compiled with no vld extensions.\n", LOG_MODULE); #endif this->props[VO_PROP_MAX_NUM_FRAMES].value = (use_more_frames) ? 15:8; this->cpu_saver = 0.; this->xoverlay = NULL; use_unscaled = 1; entry = this->config->lookup_entry (this->config, "gui.osd_use_unscaled"); if (entry) use_unscaled = entry->num_value; if (use_unscaled) { XLockDisplay (this->display); if( this->use_colorkey ) { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_COLORKEY); this->xv_xoverlay_type = X11OSD_COLORKEY; if(this->xoverlay) x11osd_colorkey(this->xoverlay, this->colorkey, &this->sc); this->xoverlay_type = X11OSD_COLORKEY; } else { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_SHAPED); this->xv_xoverlay_type = X11OSD_SHAPED; this->xoverlay_type = X11OSD_SHAPED; } XUnlockDisplay (this->display); } if( this->xoverlay ) { this->capabilities |= VO_CAP_UNSCALED_OVERLAY; } return &this->vo_driver; } /* * class functions */ static void *init_class (xine_t *xine, const void *visual_gen) { xxmc_class_t *this; (void)visual_gen; this = calloc(1, sizeof (*this)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "XxMC"; this->driver_class.description = N_("xine video output plugin using the MIT X video extension"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_xxmc = { /* keep priority lower than Xv for now. we may increase this * when the xxmc driver is more mature/tested. */ .priority = 5, .visual_type = XINE_VISUAL_TYPE_X11, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "xxmc", XINE_VERSION_CODE, &vo_info_xxmc, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_aa.c0000644000175000017500000002132714647725152016257 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_aa.c, ascii-art output plugin for xine */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "xine.h" #include #include #include /* * global variables */ typedef struct aa_frame_s { vo_frame_t vo_frame; unsigned int width, height; double ratio; int format; } aa_frame_t; typedef struct { vo_driver_t vo_driver; xine_t *xine; int user_ratio; aa_context *context; } aa_driver_t; typedef struct { video_driver_class_t driver_class; xine_t *xine; } aa_class_t; /* * our video driver */ static uint32_t aa_get_capabilities (vo_driver_t *this) { (void)this; return VO_CAP_YV12 | VO_CAP_YUY2; } static void aa_dispose_frame (vo_frame_t *vo_img) { aa_frame_t *frame = (aa_frame_t *)vo_img; xine_free_aligned (frame->vo_frame.base[0]); xine_free_aligned (frame->vo_frame.base[1]); xine_free_aligned (frame->vo_frame.base[2]); free (frame); } static void aa_frame_field (vo_frame_t *vo_img, int which_field) { /* nothing to be done here */ (void)vo_img; (void)which_field; } static vo_frame_t *aa_alloc_frame(vo_driver_t *this_gen) { /* aa_driver_t *this = (aa_driver_t*) this_gen; */ aa_frame_t *frame; frame = calloc(1, sizeof (aa_frame_t)); if (!frame) return NULL; pthread_mutex_init(&frame->vo_frame.mutex, NULL); frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; frame->vo_frame.field = aa_frame_field; frame->vo_frame.dispose = aa_dispose_frame; frame->vo_frame.driver = this_gen; return (vo_frame_t*) frame; } static void aa_update_frame_format (vo_driver_t *this_gen, vo_frame_t *img, uint32_t width, uint32_t height, double ratio, int format, int flags) { aa_driver_t *this = (aa_driver_t*) this_gen; aa_frame_t *frame = (aa_frame_t *) img; (void)flags; /* printf ("aa_update_format...\n"); */ if ((frame->width != width) || (frame->height != height) || (frame->format != format)) { xine_freep_aligned (&frame->vo_frame.base[0]); xine_freep_aligned (&frame->vo_frame.base[1]); xine_freep_aligned (&frame->vo_frame.base[2]); frame->width = width; frame->height = height; frame->format = format; if (format == XINE_IMGFMT_YV12) { frame->vo_frame.pitches[0] = 8*((width + 7) / 8); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); frame->vo_frame.base[1] = xine_mallocz_aligned(frame->vo_frame.pitches[1] * ((height+1)/2)); frame->vo_frame.base[2] = xine_mallocz_aligned(frame->vo_frame.pitches[2] * ((height+1)/2)); /* printf ("allocated yuv memory for %d x %d image\n", width, height); */ } else if (format == XINE_IMGFMT_YUY2) { frame->vo_frame.pitches[0] = 8*((width + 3) / 4); frame->vo_frame.base[0] = xine_mallocz_aligned(frame->vo_frame.pitches[0] * height); } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "alert! unsupported image format %04x\n", format); frame->vo_frame.width = frame->width = 0; } frame->ratio = ratio; } /* printf ("aa_update_format done\n"); */ } static void aa_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { int x,y; double x_fact, y_fact; /* ratio between aa's and frame's width/height */ uint8_t *img; uint8_t *src_image; aa_driver_t *this = (aa_driver_t*) this_gen; aa_frame_t *frame = (aa_frame_t *) frame_gen; x_fact = (double) frame->width / (double) aa_imgwidth (this->context); y_fact = (double) frame->height / (double) aa_imgheight (this->context); src_image = frame->vo_frame.base[0]; img = aa_image(this->context); /* pointer to the beginning of the output */ /* fprintf(stderr, "aalib sez: width: %d, height: %d\n", aa_imgwidth (this->context), aa_imgheight (this->context)); */ if (frame->format == XINE_IMGFMT_YV12) { for (y = 0; ycontext); y++) { for (x = 0; xcontext); x++) { *img++ = src_image[((int)((double) x * x_fact) + frame->width * (int)((double) y * y_fact))]; } } } else { for (y = 0; ycontext); y++) { for (x = 0; xcontext); x++) { *img++ = src_image[((int)((double) x * x_fact) * 2 + frame->width * 2 * (int)((double) y * y_fact))]; } } } frame->vo_frame.free (&frame->vo_frame); aa_fastrender(this->context, 0, 0, aa_imgwidth (this->context), aa_imgheight (this->context)); aa_flush (this->context); } static int aa_get_property (vo_driver_t *this_gen, int property) { aa_driver_t *this = (aa_driver_t*) this_gen; if ( property == VO_PROP_ASPECT_RATIO) { return this->user_ratio ; } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_aa: tried to get unsupported property %d\n", property); } return 0; } static int aa_set_property (vo_driver_t *this_gen, int property, int value) { aa_driver_t *this = (aa_driver_t*) this_gen; if ( property == VO_PROP_ASPECT_RATIO) { if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->user_ratio = value; } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "video_out_aa: tried to set unsupported property %d\n", property); } return value; } static void aa_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { (void)this_gen; (void)property; *min = 0; *max = 0; } static void aa_dispose (vo_driver_t *this_gen) { (void)this_gen; } static int aa_redraw_needed (vo_driver_t *this_gen) { (void)this_gen; return 0; } static vo_driver_t *open_plugin (video_driver_class_t *class_gen, const void *visual_gen) { aa_class_t *class = (aa_class_t *) class_gen; aa_driver_t *this; this = (aa_driver_t*) calloc(1, sizeof(aa_driver_t)); if (!this) return NULL; this->context = (aa_context*) visual_gen; this->xine = class->xine; this->vo_driver.get_capabilities = aa_get_capabilities; this->vo_driver.alloc_frame = aa_alloc_frame ; this->vo_driver.update_frame_format = aa_update_frame_format; this->vo_driver.display_frame = aa_display_frame; this->vo_driver.overlay_begin = NULL; this->vo_driver.overlay_blend = NULL; this->vo_driver.overlay_end = NULL; this->vo_driver.get_property = aa_get_property; this->vo_driver.set_property = aa_set_property; this->vo_driver.get_property_min_max = aa_get_property_min_max; this->vo_driver.gui_data_exchange = NULL; this->vo_driver.redraw_needed = aa_redraw_needed; this->vo_driver.dispose = aa_dispose; return &this->vo_driver; } static void *init_class (xine_t *xine, const void *visual_gen) { /* aa_context *context = (aa_context*) visual_gen; */ aa_class_t *this; (void)visual_gen; this = calloc(1, sizeof(aa_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "AA"; this->driver_class.description = N_("xine video output plugin using the ascii-art library"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static const vo_info_t vo_info_aa = { .priority = 6, .visual_type = XINE_VISUAL_TYPE_AA, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "aa", XINE_VERSION_CODE, &vo_info_aa, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/video_out/video_out_xv.c0000644000175000017500000016004214647725152016331 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * video_out_xv.c, X11 video extension interface for xine * * based on mpeg2dec code from * Aaron Holtzman * * Xv image support by Gerd Knorr * * xine-specific code by Guenter Bartsch * * overlay support by James Courtier-Dutton - July 2001 * X11 unscaled overlay support by Miguel Freitas - Nov 2003 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #if defined(__FreeBSD__) #include #endif #include #include #include #include #include #include #include #include #include #define LOG_MODULE "video_out_xv" #define LOG_VERBOSE /* #define LOG */ #define DEBUG_EMU #include "xine.h" #include #include /* #include "overlay.h" */ #include #include #include "x11osd.h" #define XV_PROPS #include "xv_common.h" #define LOCK_DISPLAY(this) this->lock_display (this->ld_user_data) #define UNLOCK_DISPLAY(this) this->unlock_display (this->ud_user_data); typedef struct xv_driver_s xv_driver_t; typedef struct { int initial_value; int value; int min; int max; Atom atom; int defer; const char *name; cfg_entry_t *entry; xv_driver_t *this; } xv_property_t; typedef struct { /* public part */ vo_frame_t vo_frame; /* change detection */ double ratio; int req_width, req_height, format; /* xv image */ int width, height, xvformat; XvImage *image; XShmSegmentInfo shminfo; /* yv12 backend for yuy2 emulation */ uint8_t *base[3]; int pitches[3]; } xv_frame_t; struct xv_driver_s { vo_driver_t vo_driver; /* X11 / Xv related stuff */ Display *display; int screen; Drawable drawable; unsigned int xv_format_yv12; unsigned int xv_format_yuy2; XVisualInfo vinfo; GC gc; XvPortID xv_port; XColor black; int use_shm; int use_pitch_alignment; xv_property_t props[XV_NUM_PROPERTIES]; uint32_t capabilities; int ovl_changed; xv_frame_t *recent_frames[VO_NUM_RECENT_FRAMES]; xv_frame_t *cur_frame; x11osd *xoverlay; /* all scaling information goes here */ vo_scale_t sc; int (*x11_old_error_handler) (Display *, XErrorEvent *); xine_t *xine; alphablend_t alphablend_extra_data; void (*lock_display) (void *); void *ld_user_data; void (*unlock_display) (void *); void *ud_user_data; int emu_yuy2; /* color matrix switching */ uint8_t cm_lut[32]; int cm_active, cm_state; int fullrange_mode; }; typedef struct { video_driver_class_t driver_class; xine_t *xine; } xv_class_t; /* import common color matrix stuff */ #define CM_LUT #define CM_DRIVER_T xv_driver_t #include "color_matrix.c" static int gX11Fail; VIDEO_DEVICE_XV_DECL_BICUBIC_TYPES VIDEO_DEVICE_XV_DECL_PREFER_TYPES static uint32_t xv_get_capabilities (vo_driver_t *this_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; return this->capabilities; } static void xv_frame_field (vo_frame_t *vo_img, int which_field) { /* not needed for Xv */ (void)vo_img; (void)which_field; } static void xv_rem_yuy2_emu (xv_frame_t *f); static void xv_frame_dispose (vo_frame_t *vo_img) { xv_frame_t *frame = (xv_frame_t *) vo_img ; xv_driver_t *this = (xv_driver_t *) vo_img->driver; xv_rem_yuy2_emu (frame); if (frame->image) { if (frame->shminfo.shmaddr) { LOCK_DISPLAY(this); XShmDetach (this->display, &frame->shminfo); XFree (frame->image); UNLOCK_DISPLAY(this); shmdt (frame->shminfo.shmaddr); shmctl (frame->shminfo.shmid, IPC_RMID, NULL); } else { LOCK_DISPLAY(this); xine_free_aligned (frame->image->data); XFree (frame->image); UNLOCK_DISPLAY(this); } } pthread_mutex_destroy (&frame->vo_frame.mutex); free (frame); } static vo_frame_t *xv_alloc_frame (vo_driver_t *this_gen) { /* xv_driver_t *this = (xv_driver_t *) this_gen; */ xv_frame_t *frame ; frame = (xv_frame_t *) calloc(1, sizeof(xv_frame_t)); if (!frame) return NULL; frame->req_width = 0; frame->req_height = 0; frame->format = 0; frame->width = 0; frame->height = 0; frame->xvformat = 0; frame->image = NULL; frame->base[0] = NULL; frame->vo_frame.proc_slice = NULL; frame->vo_frame.proc_frame = NULL; pthread_mutex_init (&frame->vo_frame.mutex, NULL); /* * supply required functions */ frame->vo_frame.field = xv_frame_field; frame->vo_frame.dispose = xv_frame_dispose; frame->vo_frame.driver = this_gen; return &frame->vo_frame; } static int HandleXError (Display *display, XErrorEvent *xevent) { char str [1024]; XGetErrorText (display, xevent->error_code, str, 1024); printf ("received X error event: %s\n", str); gX11Fail = 1; return 0; } /* called xlocked */ static void x11_InstallXErrorHandler (xv_driver_t *this) { this->x11_old_error_handler = XSetErrorHandler (HandleXError); XSync(this->display, False); } /* called xlocked */ static void x11_DeInstallXErrorHandler (xv_driver_t *this) { XSetErrorHandler (this->x11_old_error_handler); XSync(this->display, False); this->x11_old_error_handler = NULL; } /* called xlocked */ static XvImage *create_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, int width, int height, int format) { unsigned int xv_format; XvImage *image = NULL; if (this->use_pitch_alignment) { lprintf ("use_pitch_alignment old width=%d",width); width = (width + 7) & ~0x7; lprintf ("use_pitch_alignment new width=%d",width); } switch (format) { case XINE_IMGFMT_YV12: xv_format = this->xv_format_yv12; break; case XINE_IMGFMT_YUY2: xv_format = this->xv_format_yuy2; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unknown format %08x\n",format); return NULL; } if (xv_format == 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "create_ximage: unsupported format %08x\n",format); return NULL; } if (this->use_shm) { /* * try shm */ gX11Fail = 0; x11_InstallXErrorHandler (this); lprintf( "XvShmCreateImage format=0x%x, width=%d, height=%d\n", xv_format, width, height ); image = XvShmCreateImage(this->display, this->xv_port, xv_format, 0, width, height, shminfo); if (image == NULL ) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: XvShmCreateImage failed\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } { int q; lprintf( "XvImage id %d\n", image->id ); lprintf( "XvImage width %d\n", image->width ); lprintf( "XvImage height %d\n", image->height ); lprintf( "XvImage data_size %d\n", image->data_size ); lprintf( "XvImage num_planes %d\n", image->num_planes ); for( q=0; q < image->num_planes; q++) { lprintf( "XvImage pitches[%d] %d\n", q, image->pitches[q] ); lprintf( "XvImage offsets[%d] %d\n", q, image->offsets[q] ); } } shminfo->shmid = shmget(IPC_PRIVATE, image->data_size, IPC_CREAT | 0777); if (image->data_size==0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: XvShmCreateImage returned a zero size\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } if (shminfo->shmid < 0 ) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: shared memory error in shmget: %s\n"), LOG_MODULE, strerror(errno)); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0); if (shminfo->shmaddr == NULL) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": shared memory error (address error NULL)\n"); this->use_shm = 0; goto finishShmTesting; } if (shminfo->shmaddr == ((char *) -1)) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": shared memory error (address error)\n"); this->use_shm = 0; goto finishShmTesting; } shminfo->readOnly = False; image->data = shminfo->shmaddr; XShmAttach(this->display, shminfo); XSync(this->display, False); shmctl(shminfo->shmid, IPC_RMID, 0); if (gX11Fail) { shmdt (shminfo->shmaddr); shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: x11 error during shared memory XImage creation\n"), LOG_MODULE); xprintf(this->xine, XINE_VERBOSITY_LOG, _("%s: => not using MIT Shared Memory extension.\n"), LOG_MODULE); this->use_shm = 0; goto finishShmTesting; } /* * Now that the Xserver has learned about and attached to the * shared memory segment, delete it. It's actually deleted by * the kernel when all users of that segment have detached from * it. Gives an automatic shared memory cleanup in case we crash. */ shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; finishShmTesting: XSync(this->display, False); x11_DeInstallXErrorHandler(this); } /* * fall back to plain Xv if necessary */ if (!this->use_shm) { image = XvCreateImage (this->display, this->xv_port, xv_format, NULL, width, height); if (image) { image->data = xine_malloc_aligned (image->data_size); if (!image->data) { XFree (image); image = NULL; } } shminfo->shmaddr = 0; } return image; } /* called xlocked */ static void dispose_ximage (xv_driver_t *this, XShmSegmentInfo *shminfo, XvImage *myimage) { if (shminfo->shmaddr) { XShmDetach (this->display, shminfo); XFree (myimage); shmdt (shminfo->shmaddr); if (shminfo->shmid >= 0) { shmctl (shminfo->shmid, IPC_RMID, 0); shminfo->shmid = -1; } } else { xine_free_aligned (myimage->data); XFree (myimage); } } static void xv_slice_yuy2_emu (vo_frame_t *vo_img, uint8_t **src) { xv_frame_t *frame = (xv_frame_t *)vo_img; int y = (src[0] - frame->vo_frame.base[0]) / frame->vo_frame.pitches[0]; int h; if ((y < 0) || (y >= frame->height)) return; if (!vo_img->proc_called) vo_img->proc_called = 1; h = frame->height - y; h = h > 16 ? 16 : h; yuy2_to_yv12 (src[0], frame->vo_frame.pitches[0], frame->base[0] + y * frame->pitches[0], frame->pitches[0], frame->base[1] + (y >> 1) * frame->pitches[1], frame->pitches[1], frame->base[2] + (y >> 1) * frame->pitches[2], frame->pitches[2], frame->width, h); } static int xv_add_yuy2_emu (xv_frame_t *f) { uint8_t *base; int pitch; if (f->base[0]) return 0; pitch = f->image->pitches[0] * 2; base = xine_malloc_aligned (pitch * f->image->height); if (!base) return 1; /* save backend */ f->base[0] = f->vo_frame.base[0]; f->base[1] = f->vo_frame.base[1]; f->base[2] = f->vo_frame.base[2]; f->pitches[0] = f->vo_frame.pitches[0]; f->pitches[1] = f->vo_frame.pitches[1]; f->pitches[2] = f->vo_frame.pitches[2]; /* new frontend */ f->vo_frame.base[0] = base; f->vo_frame.base[1] = f->vo_frame.base[2] = NULL; f->vo_frame.pitches[0] = pitch; f->vo_frame.pitches[1] = f->vo_frame.pitches[2] = 0; f->format = XINE_IMGFMT_YUY2; f->vo_frame.proc_slice = xv_slice_yuy2_emu; { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)base; int i; for (i = pitch * f->image->height / 4; i > 0; i--) *q++ = black.word; } return 0; } static void xv_rem_yuy2_emu (xv_frame_t *f) { if (!f->base[0]) return; xine_free_aligned (f->vo_frame.base[0]); f->vo_frame.base[0] = f->base[0]; f->vo_frame.base[1] = f->base[1]; f->vo_frame.base[2] = f->base[2]; f->vo_frame.pitches[0] = f->pitches[0]; f->vo_frame.pitches[1] = f->pitches[1]; f->vo_frame.pitches[2] = f->pitches[2]; f->base[0] = NULL; f->format = XINE_IMGFMT_YV12; f->vo_frame.proc_slice = NULL; } static void xv_update_frame_format (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { xv_driver_t *this = (xv_driver_t *) this_gen; xv_frame_t *frame = (xv_frame_t *) frame_gen; int resize; (void)flags; if (this->use_pitch_alignment) { width = (width + 7) & ~0x7; } resize = (frame->req_width != (int)width) || (frame->req_height != (int)height); if (resize || (frame->format != format)) { int fmt = format; if ((fmt == XINE_IMGFMT_YUY2) && (this->emu_yuy2 || !this->xv_format_yuy2)) fmt = XINE_IMGFMT_YV12; if (resize || (frame->xvformat != fmt)) { /* get emulation out of the way first if any */ xv_rem_yuy2_emu (frame); /* (re-) allocate xvimage */ LOCK_DISPLAY (this); if (frame->image) dispose_ximage (this, &frame->shminfo, frame->image); frame->image = create_ximage (this, &frame->shminfo, width, height, fmt); UNLOCK_DISPLAY (this); if (!frame->image) { frame->vo_frame.base[0] = NULL; frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; frame->req_width = 0; frame->vo_frame.width = 0; return; } frame->xvformat = fmt; /* get params, blackfill */ if (fmt == XINE_IMGFMT_YUY2) { frame->vo_frame.pitches[0] = frame->image->pitches[0]; frame->vo_frame.base[0] = frame->image->data + frame->image->offsets[0]; { const union {uint8_t bytes[4]; uint32_t word;} black = {{0, 128, 0, 128}}; uint32_t *q = (uint32_t *)frame->vo_frame.base[0]; int i; for (i = frame->vo_frame.pitches[0] * frame->image->height / 4; i > 0; i--) *q++ = black.word; } } else { /* XINE_IMGFMT_YV12 */ frame->vo_frame.pitches[0] = frame->image->pitches[0]; frame->vo_frame.pitches[1] = frame->image->pitches[2]; frame->vo_frame.pitches[2] = frame->image->pitches[1]; frame->vo_frame.base[0] = frame->image->data + frame->image->offsets[0]; frame->vo_frame.base[1] = frame->image->data + frame->image->offsets[2]; frame->vo_frame.base[2] = frame->image->data + frame->image->offsets[1]; memset (frame->vo_frame.base[0], 0, frame->vo_frame.pitches[0] * frame->image->height); memset (frame->vo_frame.base[1], 128, frame->vo_frame.pitches[1] * (frame->image->height >> 1)); memset (frame->vo_frame.base[2], 128, frame->vo_frame.pitches[2] * (frame->image->height >> 1)); } } /* update emulation */ frame->format = format; if (fmt != format) { if (xv_add_yuy2_emu (frame)) { LOCK_DISPLAY (this); dispose_ximage (this, &frame->shminfo, frame->image); UNLOCK_DISPLAY (this); frame->image = NULL; frame->vo_frame.base[0] = NULL; frame->vo_frame.base[1] = NULL; frame->vo_frame.base[2] = NULL; frame->req_width = 0; frame->vo_frame.width = 0; return; } } else xv_rem_yuy2_emu (frame); /* allocated frame size may not match requested size */ frame->req_width = width; frame->req_height = height; frame->width = frame->image->width; frame->height = frame->image->height; } if (frame->vo_frame.width > frame->width) frame->vo_frame.width = frame->width; if (frame->vo_frame.height > frame->height) frame->vo_frame.height = frame->height; frame->ratio = ratio; } static void xv_clean_output_area (xv_driver_t *this) { int i; LOCK_DISPLAY(this); XSetForeground (this->display, this->gc, this->black.pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } } if ((this->props[VO_PROP_COLORKEY].atom != None) || (this->props[VO_PROP_AUTOPAINT_COLORKEY].value == 1)) { XSetForeground (this->display, this->gc, this->props[VO_PROP_COLORKEY].value); XFillRectangle (this->display, this->drawable, this->gc, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } if (this->xoverlay) { x11osd_resize (this->xoverlay, this->sc.gui_width, this->sc.gui_height); this->ovl_changed = 1; } UNLOCK_DISPLAY(this); } /* * convert delivered height/width to ideal width/height * taking into account aspect ratio and zoom factor */ static void xv_compute_ideal_size (xv_driver_t *this) { _x_vo_scale_compute_ideal_size( &this->sc ); } /* * make ideal width/height "fit" into the gui */ static void xv_compute_output_size (xv_driver_t *this) { _x_vo_scale_compute_output_size( &this->sc ); } static void xv_overlay_begin (vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { xv_driver_t *this = (xv_driver_t *) this_gen; this->ovl_changed += changed; if( this->ovl_changed && this->xoverlay ) { LOCK_DISPLAY(this); x11osd_clear(this->xoverlay); UNLOCK_DISPLAY(this); } this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void xv_overlay_end (vo_driver_t *this_gen, vo_frame_t *vo_img) { xv_driver_t *this = (xv_driver_t *) this_gen; (void)vo_img; if( this->ovl_changed && this->xoverlay ) { LOCK_DISPLAY(this); x11osd_expose(this->xoverlay); UNLOCK_DISPLAY(this); } this->ovl_changed = 0; } static void xv_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { xv_driver_t *this = (xv_driver_t *) this_gen; xv_frame_t *frame = (xv_frame_t *) frame_gen; if (overlay->rle) { if( overlay->unscaled ) { if( this->ovl_changed && this->xoverlay ) { LOCK_DISPLAY(this); x11osd_blend(this->xoverlay, overlay); UNLOCK_DISPLAY(this); } } else { if (frame->format == XINE_IMGFMT_YV12) _x_blend_yuv(frame->vo_frame.base, overlay, frame->width, frame->height, frame->vo_frame.pitches, &this->alphablend_extra_data); else _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->width, frame->height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } } static void xv_add_recent_frame (xv_driver_t *this, xv_frame_t *frame) { int i; i = VO_NUM_RECENT_FRAMES-1; if( this->recent_frames[i] ) this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); for( ; i ; i-- ) this->recent_frames[i] = this->recent_frames[i-1]; this->recent_frames[0] = frame; } static int xv_flush_recent_frames (xv_driver_t *this) { int i, n = 0; for (i = 0; i < VO_NUM_RECENT_FRAMES; i++) { if (this->recent_frames[i]) { this->recent_frames[i]->vo_frame.free (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; n++; } } return n; } static int xv_redraw_needed (vo_driver_t *this_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; int ret = !this->cm_active; if( this->cur_frame ) { this->sc.delivered_height = this->cur_frame->height; this->sc.delivered_width = this->cur_frame->width; this->sc.delivered_ratio = this->cur_frame->ratio; this->sc.crop_left = this->cur_frame->vo_frame.crop_left; this->sc.crop_right = this->cur_frame->vo_frame.crop_right; this->sc.crop_top = this->cur_frame->vo_frame.crop_top; this->sc.crop_bottom = this->cur_frame->vo_frame.crop_bottom; xv_compute_ideal_size(this); if( _x_vo_scale_redraw_needed( &this->sc ) ) { xv_compute_output_size (this); xv_clean_output_area (this); ret = 1; } } else ret = 1; return ret; } /* Used in xv_display_frame to determine how long XvShmPutImage takes - if slower than 60fps, print a message */ static double timeOfDay() { struct timeval t; gettimeofday( &t, NULL ); return ((double)t.tv_sec) + (((double)t.tv_usec)/1000000.0); } static void xv_new_color (xv_driver_t *this, int cm) { int brig = this->props[VO_PROP_BRIGHTNESS].value; int cont = this->props[VO_PROP_CONTRAST].value; int satu = this->props[VO_PROP_SATURATION].value; int cm2, fr = 0, a, b; Atom atom; if (cm & 1) { /* fullrange emulation. Do not report this via get_property (). */ if (this->fullrange_mode == 1) { /* modification routine 1 for TV set style bcs controls 0% - 200% */ satu -= this->props[VO_PROP_SATURATION].min; satu = (satu * (112 * 255) + (127 * 219 / 2)) / (127 * 219); satu += this->props[VO_PROP_SATURATION].min; if (satu > this->props[VO_PROP_SATURATION].max) satu = this->props[VO_PROP_SATURATION].max; cont -= this->props[VO_PROP_CONTRAST].min; cont = (cont * 219 + 127) / 255; a = cont * (this->props[VO_PROP_BRIGHTNESS].max - this->props[VO_PROP_BRIGHTNESS].min); cont += this->props[VO_PROP_CONTRAST].min; b = 256 * (this->props[VO_PROP_CONTRAST].max - this->props[VO_PROP_CONTRAST].min); brig += (16 * a + b / 2) / b; if (brig > this->props[VO_PROP_BRIGHTNESS].max) brig = this->props[VO_PROP_BRIGHTNESS].max; fr = 1; } /* maybe add more routines for non-standard controls later */ } LOCK_DISPLAY (this); atom = this->props[VO_PROP_BRIGHTNESS].atom; if (atom != None) XvSetPortAttribute (this->display, this->xv_port, atom, brig); atom = this->props[VO_PROP_CONTRAST].atom; if (atom != None) XvSetPortAttribute (this->display, this->xv_port, atom, cont); atom = this->props[VO_PROP_SATURATION].atom; if (atom != None) XvSetPortAttribute (this->display, this->xv_port, atom, satu); UNLOCK_DISPLAY(this); if (this->props[XV_PROP_ITURBT_709].atom != None) { /* 0 = 601 (SD), 1 = 709 (HD) */ /* so far only binary nvidia drivers support this. why not nuveau? */ cm2 = (0xc00c >> cm) & 1; LOCK_DISPLAY(this); XvSetPortAttribute (this->display, this->xv_port, this->props[XV_PROP_ITURBT_709].atom, cm2); UNLOCK_DISPLAY(this); this->props[XV_PROP_ITURBT_709].value = cm2; cm2 = cm2 ? 2 : 10; } else if (this->props[XV_PROP_COLORSPACE].atom != None) { /* radeonhd: 0 = size based auto, 1 = 601 (SD), 2 = 709 (HD) */ cm2 = ((0xc00c >> cm) & 1) + 1; LOCK_DISPLAY(this); XvSetPortAttribute (this->display, this->xv_port, this->props[XV_PROP_COLORSPACE].atom, cm2); UNLOCK_DISPLAY(this); this->props[XV_PROP_COLORSPACE].value = cm2; cm2 = cm2 == 2 ? 2 : 10; } else { cm2 = 10; } cm2 |= fr; xprintf (this->xine, XINE_VERBOSITY_LOG, "video_out_xv: %s b %d c %d s %d [%s]\n", fr ? "modified " : "", brig, cont, satu, cm_names[cm2]); this->cm_active = cm; } static void xv_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; xv_frame_t *frame = (xv_frame_t *) frame_gen; int cm; /* printf (LOG_MODULE ": xv_display_frame...\n"); */ cm = cm_from_frame (frame_gen); if (cm != this->cm_active) xv_new_color (this, cm); /* * queue frames (deinterlacing) * free old frames */ xv_add_recent_frame (this, frame); /* deinterlacing */ this->cur_frame = frame; /* * let's see if this frame is different in size / aspect * ratio from the previous one */ if ( (frame->width != this->sc.delivered_width) || (frame->height != this->sc.delivered_height) || (frame->ratio != this->sc.delivered_ratio) || (frame->vo_frame.crop_left != this->sc.crop_left) || (frame->vo_frame.crop_right != this->sc.crop_right) || (frame->vo_frame.crop_top != this->sc.crop_top) || (frame->vo_frame.crop_bottom != this->sc.crop_bottom) ) { lprintf("frame format changed\n"); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } /* * tell gui that we are about to display a frame, * ask for offset and output size */ xv_redraw_needed (this_gen); { double start_time; double end_time; double elapse_time; int factor; LOCK_DISPLAY(this); start_time = timeOfDay(); if (this->use_shm) { XvShmPutImage(this->display, this->xv_port, this->drawable, this->gc, this->cur_frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, True); } else { XvPutImage(this->display, this->xv_port, this->drawable, this->gc, this->cur_frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } XSync(this->display, False); end_time = timeOfDay(); UNLOCK_DISPLAY(this); elapse_time = end_time - start_time; factor = (int)(elapse_time/(1.0/60.0)); if( factor > 1 ) { lprintf( "%s PutImage %dX interval (%fs)\n", LOG_MODULE, factor, elapse_time ); } } /* printf (LOG_MODULE ": xv_display_frame... done\n"); */ } static int xv_get_property (vo_driver_t *this_gen, int property) { xv_driver_t *this = (xv_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return (0); switch (property) { case VO_PROP_WINDOW_WIDTH: this->props[property].value = this->sc.gui_width; break; case VO_PROP_WINDOW_HEIGHT: this->props[property].value = this->sc.gui_height; break; case VO_PROP_OUTPUT_WIDTH: this->props[property].value = this->sc.output_width; break; case VO_PROP_OUTPUT_HEIGHT: this->props[property].value = this->sc.output_height; break; case VO_PROP_OUTPUT_XOFFSET: this->props[property].value = this->sc.output_xoffset; break; case VO_PROP_OUTPUT_YOFFSET: this->props[property].value = this->sc.output_yoffset; break; } lprintf(LOG_MODULE ": property #%d = %d\n", property, this->props[property].value); return this->props[property].value; } static int xv_set_property (vo_driver_t *this_gen, int property, int value) { xv_driver_t *this = (xv_driver_t *) this_gen; printf("xv_set_property: property=%d, value=%d\n", property, value ); if ((property < 0) || (property >= VO_NUM_PROPERTIES)) return 0; if (this->props[property].defer == 1) { /* value is out of bound */ if((value < this->props[property].min) || (value > this->props[property].max)) value = (this->props[property].min + this->props[property].max) >> 1; this->props[property].value = value; this->cm_active = 0; return value; } if (this->props[property].atom != None) { /* value is out of bound */ if((value < this->props[property].min) || (value > this->props[property].max)) value = (this->props[property].min + this->props[property].max) >> 1; LOCK_DISPLAY(this); XvSetPortAttribute (this->display, this->xv_port, this->props[property].atom, value); XvGetPortAttribute (this->display, this->xv_port, this->props[property].atom, &this->props[property].value); UNLOCK_DISPLAY(this); if (this->props[property].entry) this->props[property].entry->num_value = this->props[property].value; return this->props[property].value; } else { switch (property) { case VO_PROP_DISCARD_FRAMES: if (value == -1) value = xv_flush_recent_frames (this); break; case VO_PROP_ASPECT_RATIO: if (value>=XINE_VO_ASPECT_NUM_RATIOS) value = XINE_VO_ASPECT_AUTO; this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ASPECT_RATIO(%d)\n", this->props[property].value); this->sc.user_ratio = value; xv_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ break; case VO_PROP_ZOOM_X: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ZOOM_X = %d\n", this->props[property].value); this->sc.zoom_factor_x = (double)value / (double)XINE_VO_ZOOM_STEP; xv_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; case VO_PROP_ZOOM_Y: if ((value >= XINE_VO_ZOOM_MIN) && (value <= XINE_VO_ZOOM_MAX)) { this->props[property].value = value; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": VO_PROP_ZOOM_Y = %d\n", this->props[property].value); this->sc.zoom_factor_y = (double)value / (double)XINE_VO_ZOOM_STEP; xv_compute_ideal_size (this); this->sc.force_redraw = 1; /* trigger re-calc of output size */ } break; } } return value; } static void xv_get_property_min_max (vo_driver_t *this_gen, int property, int *min, int *max) { xv_driver_t *this = (xv_driver_t *) this_gen; if ((property < 0) || (property >= VO_NUM_PROPERTIES)) { *min = *max = 0; return; } *min = this->props[property].min; *max = this->props[property].max; } static int xv_gui_data_exchange (vo_driver_t *this_gen, int data_type, void *data) { xv_driver_t *this = (xv_driver_t *) this_gen; switch (data_type) { #ifndef XINE_DISABLE_DEPRECATED_FEATURES case XINE_GUI_SEND_COMPLETION_EVENT: break; #endif case XINE_GUI_SEND_EXPOSE_EVENT: { /* XExposeEvent * xev = (XExposeEvent *) data; */ if (this->cur_frame) { int i; LOCK_DISPLAY(this); if (this->use_shm) { XvShmPutImage(this->display, this->xv_port, this->drawable, this->gc, this->cur_frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height, True); } else { XvPutImage(this->display, this->xv_port, this->drawable, this->gc, this->cur_frame->image, this->sc.displayed_xoffset, this->sc.displayed_yoffset, this->sc.displayed_width, this->sc.displayed_height, this->sc.output_xoffset, this->sc.output_yoffset, this->sc.output_width, this->sc.output_height); } XSetForeground (this->display, this->gc, this->black.pixel); for( i = 0; i < 4; i++ ) { if( this->sc.border[i].w && this->sc.border[i].h ) { XFillRectangle(this->display, this->drawable, this->gc, this->sc.border[i].x, this->sc.border[i].y, this->sc.border[i].w, this->sc.border[i].h); } } if(this->xoverlay) x11osd_expose(this->xoverlay); XSync(this->display, False); UNLOCK_DISPLAY(this); } } break; case XINE_GUI_SEND_DRAWABLE_CHANGED: LOCK_DISPLAY(this); this->drawable = (Drawable) data; XFreeGC(this->display, this->gc); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); if(this->xoverlay) x11osd_drawable_changed(this->xoverlay, this->drawable); this->ovl_changed = 1; UNLOCK_DISPLAY(this); this->sc.force_redraw = 1; break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->sc, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->sc, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1; rect->w = x2-x1; rect->h = y2-y1; } break; default: return -1; } return 0; } static void xv_restore_port_attributes(xv_driver_t *this) { int i; for (i = 0; i < XV_NUM_PROPERTIES; i++) { xv_property_t *prop = &this->props[i]; if (prop->atom == None) continue; if (prop->defer || (prop->value != prop->initial_value)) { LOCK_DISPLAY (this); XvSetPortAttribute (this->display, this->xv_port, prop->atom, prop->initial_value); UNLOCK_DISPLAY(this); } } LOCK_DISPLAY(this); XSync(this->display, False); UNLOCK_DISPLAY(this); } static void xv_dispose (vo_driver_t *this_gen) { xv_driver_t *this = (xv_driver_t *) this_gen; int i; /* restore port attributes to their initial values */ xv_restore_port_attributes (this); LOCK_DISPLAY(this); if (this->xv_port) { if (XvUngrabPort (this->display, this->xv_port, CurrentTime) != Success) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": xv_exit: XvUngrabPort() failed.\n"); } } if (this->gc) { XFreeGC(this->display, this->gc); } UNLOCK_DISPLAY(this); /* should do nothing as video_out has sent VO_PROP_DISCARD_FRAMES = -1 before */ for( i=0; i < VO_NUM_RECENT_FRAMES; i++ ) { if( this->recent_frames[i] ) this->recent_frames[i]->vo_frame.dispose (&this->recent_frames[i]->vo_frame); this->recent_frames[i] = NULL; } if( this->xoverlay ) { LOCK_DISPLAY(this); x11osd_destroy (this->xoverlay); UNLOCK_DISPLAY(this); } _x_alphablend_free(&this->alphablend_extra_data); _x_vo_scale_cleanup (&this->sc, this->xine->config); cm_close (this); /* cm_close already does this. this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, this, sizeof (*this)); */ free (this); } /* called xlocked */ static void xv_prop_init (xv_driver_t *this, const xv_prop_list_t *l, const XvAttribute attr) { xv_property_t *prop = &this->props[l->index]; Atom atom = XInternAtom (this->display, l->name, False); if (atom == None) return; prop->atom = atom; prop->name = l->name; this->capabilities |= l->caps; /* * some Xv drivers (Gatos ATI) report some ~0 as max values, this is confusing. */ prop->min = attr.min_value; prop->max = attr.max_value; if ((prop->min >= 0) && (prop->max < 0)) prop->max = 2147483615; XvGetPortAttribute (this->display, this->xv_port, atom, &prop->initial_value); prop->value = prop->initial_value; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": port attribute %s (%d) value is %d\n", l->name, l->index, prop->value); } static void xv_prop_update_int (xv_property_t *prop, int value) { xv_driver_t *this = prop->this; LOCK_DISPLAY (this); XvSetPortAttribute (this->display, this->xv_port, prop->atom, value); UNLOCK_DISPLAY (this); prop->value = value; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": %s = %d\n", prop->name, value); } static void xv_prop_update (void *prop_gen, xine_cfg_entry_t *entry) { xv_prop_update_int ((xv_property_t *)prop_gen, entry->num_value); } static void xv_prop_conf (xv_driver_t *this, int property, const char *config_name, const char *config_desc, const char *config_help) { config_values_t *config = this->xine->config; xv_property_t *prop = &this->props[property]; cfg_entry_t *entry; /* is this a boolean property ? */ if ((prop->min == 0) && (prop->max == 1)) config->register_bool (config, config_name, prop->value, config_desc, config_help, 20, xv_prop_update, prop); else config->register_range (config, config_name, prop->value, prop->min, prop->max, config_desc, config_help, 20, xv_prop_update, prop); entry = config->lookup_entry (config, config_name); if ((entry->num_value < prop->min) || (entry->num_value > prop->max)) xv_prop_update_int (prop, (prop->min + prop->max) >> 1); prop->entry = entry; xv_set_property (&this->vo_driver, property, entry->num_value); } static void xv_update_xv_pitch_alignment(void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *) this_gen; this->use_pitch_alignment = entry->num_value; } static void xv_fullrange_cb_config (void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *)this_gen; this->fullrange_mode = entry->num_value; if (this->fullrange_mode) this->capabilities |= VO_CAP_FULLRANGE; else this->capabilities &= ~VO_CAP_FULLRANGE; this->cm_active = 0; } #ifdef DEBUG_EMU static void xv_debug_emu_cb_config (void *this_gen, xine_cfg_entry_t *entry) { xv_driver_t *this = (xv_driver_t *)this_gen; this->emu_yuy2 = entry->num_value; } #endif static int xv_open_port (xv_driver_t *this, XvPortID port) { { int i, formats; XvImageFormatValues *fo; LOCK_DISPLAY (this); fo = XvListImageFormats (this->display, port, (int*)&formats); UNLOCK_DISPLAY (this); if (!fo) return 0; this->xv_format_yv12 = 0; this->xv_format_yuy2 = 0; for (i = 0; i < formats; i++) { lprintf ("Xv image format: 0x%x (%4.4s) %s\n", fo[i].id, (char*)&fo[i].id, (fo[i].format == XvPacked) ? "packed" : "planar"); switch (fo[i].id) { case XINE_IMGFMT_YV12: this->xv_format_yv12 = fo[i].id; this->capabilities |= VO_CAP_YV12; xprintf (this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YV12"); break; case XINE_IMGFMT_YUY2: this->xv_format_yuy2 = fo[i].id; this->capabilities |= VO_CAP_YUY2; xprintf (this->xine, XINE_VERBOSITY_LOG, _("%s: this adaptor supports the %s format.\n"), LOG_MODULE, "YUY2"); break; default: ; } } LOCK_DISPLAY (this); XFree (fo); UNLOCK_DISPLAY (this); } /* No yv12: bail out. */ if (!this->xv_format_yv12) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": this adaptor does not support YV12 format.\n"); return 0; } /* No yuy2: just report. Who can deliver yv12 with little effort shall do that. * Otherwise, accept anyway and emulate. */ { int ret; x11_InstallXErrorHandler (this); ret = XvGrabPort(this->display, port, 0) == Success; x11_DeInstallXErrorHandler (this); return ret; } } static unsigned int xv_find_adaptor_by_port (int port, unsigned int adaptors, XvAdaptorInfo *adaptor_info) { unsigned int an; for (an = 0; an < adaptors; an++) if (adaptor_info[an].type & XvImageMask) if (port >= (int)adaptor_info[an].base_id && port < (int)(adaptor_info[an].base_id + adaptor_info[an].num_ports)) return an; return 0; /* shouldn't happen */ } static XvPortID xv_autodetect_port(xv_driver_t *this, unsigned int adaptors, XvAdaptorInfo *adaptor_info, unsigned int *adaptor_num, XvPortID base, xv_prefertype prefer_type) { unsigned int an, j; for (an = 0; an < adaptors; an++) if (adaptor_info[an].type & XvImageMask && (prefer_type == xv_prefer_none || strcasestr (adaptor_info[an].name, prefer_substrings[prefer_type]))) for (j = 0; j < adaptor_info[an].num_ports; j++) { XvPortID port = adaptor_info[an].base_id + j; if (port >= base && xv_open_port(this, port)) { *adaptor_num = an; return port; } } return 0; } static void xv_default_lock_display (void *user_data) { xv_driver_t *this = user_data; XLockDisplay (this->display); } static void xv_default_unlock_display (void *user_data) { xv_driver_t *this = user_data; XUnlockDisplay (this->display); } /* expects XINE_VISUAL_TYPE_X11_2 with configurable locking */ static vo_driver_t *open_plugin_2 (video_driver_class_t *class_gen, const void *visual_gen) { xv_class_t *class = (xv_class_t *) class_gen; config_values_t *config = class->xine->config; xv_driver_t *this; int i; const x11_visual_t *visual = (const x11_visual_t *) visual_gen; XvPortID xv_port; char *adaptor_name; this = (xv_driver_t *) calloc(1, sizeof(xv_driver_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM /* 0/NULL inits, for optimizing away. */ this->x11_old_error_handler = NULL; this->xoverlay = NULL; this->ovl_changed = 0; this->xv_format_yv12 = 0; this->xv_format_yuy2 = 0; this->emu_yuy2 = 0; this->fullrange_mode = 0; for (i = 0; i < XV_NUM_PROPERTIES; i++) { this->props[i].initial_value = 0; this->props[i].value = 0; this->props[i].min = 0; this->props[i].max = 0; this->props[i].defer = 0; this->props[i].name = NULL; this->props[i].entry = NULL; } #endif this->use_shm = 1; this->xine = class->xine; this->display = visual->display; this->screen = visual->screen; this->capabilities = VO_CAP_CROP | VO_CAP_ZOOM_X | VO_CAP_ZOOM_Y; /* configurable X11 locking */ if (visual->lock_display) { this->lock_display = visual->lock_display; this->ld_user_data = visual->user_data; } else { this->lock_display = xv_default_lock_display; this->ld_user_data = this; } if (visual->unlock_display) { this->unlock_display = visual->unlock_display; this->ud_user_data = visual->user_data; } else { this->unlock_display = xv_default_unlock_display; this->ud_user_data = this; } LOCK_DISPLAY(this); /* * check for Xvideo support */ { unsigned int ver, rel, req, ev, err; if (Success != XvQueryExtension (this->display, &ver, &rel, &req, &ev, &err)) { UNLOCK_DISPLAY (this); xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: Xv extension not present.\n"), LOG_MODULE); free (this); return NULL; } } /* * check adaptors, search for one that supports (at least) yuv12 */ { unsigned int adaptor_num; xv_prefertype prefer_type; unsigned int adaptors; XvAdaptorInfo *adaptor_info; if (Success != XvQueryAdaptors (this->display, DefaultRootWindow (this->display), &adaptors, &adaptor_info)) { xprintf (class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": XvQueryAdaptors failed.\n"); UNLOCK_DISPLAY (this); free (this); return NULL; } xv_port = config->register_num (config, "video.device.xv_port", 0, VIDEO_DEVICE_XV_PORT_HELP, 20, NULL, NULL); prefer_type = config->register_enum (config, "video.device.xv_preferred_method", 0, (char **)prefer_labels, VIDEO_DEVICE_XV_PREFER_TYPE_HELP, 10, NULL, NULL); if (xv_port != 0) { if (!xv_open_port (this, xv_port)) { xprintf (class->xine, XINE_VERBOSITY_NONE, _("%s: could not open Xv port %lu - autodetecting\n"), LOG_MODULE, (unsigned long)xv_port); xv_port = xv_autodetect_port (this, adaptors, adaptor_info, &adaptor_num, xv_port, prefer_type); } else adaptor_num = xv_find_adaptor_by_port (xv_port, adaptors, adaptor_info); } if (!xv_port) xv_port = xv_autodetect_port (this, adaptors, adaptor_info, &adaptor_num, 0, prefer_type); if (!xv_port) { if (prefer_type) xprintf (class->xine, XINE_VERBOSITY_NONE, _("%s: no available ports of type \"%s\", defaulting...\n"), LOG_MODULE, prefer_labels[prefer_type]); xv_port = xv_autodetect_port (this, adaptors, adaptor_info, &adaptor_num, 0, xv_prefer_none); } if (!xv_port) { xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: Xv extension is present but I couldn't find a usable yuv12 port.\n" "\tLooks like your graphics hardware driver doesn't support Xv?!\n"), LOG_MODULE); /* XvFreeAdaptorInfo (adaptor_info); this crashed on me (gb)*/ XvFreeAdaptorInfo (adaptor_info); UNLOCK_DISPLAY (this); free (this); return NULL; } adaptor_name = strdup (adaptor_info[adaptor_num].name ? adaptor_info[adaptor_num].name : ""); XvFreeAdaptorInfo (adaptor_info); } xprintf (class->xine, XINE_VERBOSITY_LOG, _("%s: using Xv port %ld from adaptor %s for hardware " "colour space conversion and scaling.\n"), LOG_MODULE, xv_port, adaptor_name); UNLOCK_DISPLAY (this); _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->xv_port = xv_port; _x_vo_scale_init (&this->sc, 1, 0, config ); this->sc.frame_output_cb = visual->frame_output_cb; this->sc.user_data = visual->user_data; this->drawable = visual->d; LOCK_DISPLAY(this); this->gc = XCreateGC (this->display, this->drawable, 0, NULL); UNLOCK_DISPLAY(this); LOCK_DISPLAY(this); { XColor dummy; XAllocNamedColor (this->display, DefaultColormap (this->display, this->screen), "black", &this->black, &dummy); } UNLOCK_DISPLAY(this); this->vo_driver.get_capabilities = xv_get_capabilities; this->vo_driver.alloc_frame = xv_alloc_frame; this->vo_driver.update_frame_format = xv_update_frame_format; this->vo_driver.overlay_begin = xv_overlay_begin; this->vo_driver.overlay_blend = xv_overlay_blend; this->vo_driver.overlay_end = xv_overlay_end; this->vo_driver.display_frame = xv_display_frame; this->vo_driver.get_property = xv_get_property; this->vo_driver.set_property = xv_set_property; this->vo_driver.get_property_min_max = xv_get_property_min_max; this->vo_driver.gui_data_exchange = xv_gui_data_exchange; this->vo_driver.dispose = xv_dispose; this->vo_driver.redraw_needed = xv_redraw_needed; /* * init properties */ for (i = 0; i < XV_NUM_PROPERTIES; i++) { this->props[i].atom = None; this->props[i].this = this; } this->sc.user_ratio = this->props[VO_PROP_ASPECT_RATIO].value = XINE_VO_ASPECT_AUTO; this->props[VO_PROP_ZOOM_X].value = 100; this->props[VO_PROP_ZOOM_Y].value = 100; cm_init (this); /* * check this adaptor's capabilities */ { XvAttribute *attr; int nattr; LOCK_DISPLAY (this); attr = XvQueryPortAttributes (this->display, xv_port, &nattr); if (attr && nattr) { int k; for (k = 0; k < nattr; k++) { if ((attr[k].flags & XvSettable) && (attr[k].flags & XvGettable)) { const xv_prop_list_t *l = xv_find_prop (attr[k].name); if (!l) continue; if ((l->index == VO_PROP_HUE) && !strncmp (adaptor_name, "NV", 2)) { xprintf (this->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": ignoring broken XV_HUE settings on NVidia cards\n"); continue; } xv_prop_init (this, l, attr[k]); switch (l->index) { case XV_PROP_ITURBT_709: /* nvidia */ this->cm_active = this->props[XV_PROP_ITURBT_709].value ? 2 : 10; break; case XV_PROP_COLORSPACE: /* radeonhd */ this->cm_active = this->props[XV_PROP_COLORSPACE].value == 2 ? 2 : (this->props[XV_PROP_COLORSPACE].value == 1 ? 10 : 0); break; case VO_PROP_COLORKEY: xv_prop_conf (this, VO_PROP_COLORKEY, "video.device.xv_colorkey", VIDEO_DEVICE_XV_COLORKEY_HELP); break; case VO_PROP_AUTOPAINT_COLORKEY: /* disable autopaint colorkey by default, might be overridden using config entry */ this->props[VO_PROP_AUTOPAINT_COLORKEY].value = 0; xv_prop_conf (this, VO_PROP_AUTOPAINT_COLORKEY, "video.device.xv_autopaint_colorkey", VIDEO_DEVICE_XV_AUTOPAINT_COLORKEY_HELP); break; case XV_PROP_FILTER: { /* This setting is specific to Permedia 2/3 cards. */ int xv_filter = config->register_range (config, "video.device.xv_filter", 0, attr[k].min_value, attr[k].max_value, VIDEO_DEVICE_XV_FILTER_HELP, 20, xv_prop_update, &this->props[XV_PROP_FILTER]); xv_prop_update_int (&this->props[XV_PROP_FILTER], xv_filter); break; } case XV_PROP_DOUBLE_BUFFER: { int xv_double_buffer = config->register_bool (config, "video.device.xv_double_buffer", 1, VIDEO_DEVICE_XV_DOUBLE_BUFFER_HELP, 20, xv_prop_update, &this->props[XV_PROP_DOUBLE_BUFFER]); xv_prop_update_int (&this->props[XV_PROP_DOUBLE_BUFFER], xv_double_buffer); break; } case XV_PROP_SYNC_TO_VBLANK: { int xv_sync_to_vblank = config->register_bool (config, "video.device.xv_sync_to_vblank", 1, _("enable vblank sync"), _("This option will synchronize the update of the video image to the " "repainting of the entire screen (\"vertical retrace\"). This eliminates " "flickering and tearing artifacts. On nvidia cards one may also " "need to run \"nvidia-settings\" and choose which display device to " "sync to under the XVideo Settings tab"), 20, xv_prop_update, &this->props[XV_PROP_SYNC_TO_VBLANK]); xv_prop_update_int (&this->props[XV_PROP_SYNC_TO_VBLANK], xv_sync_to_vblank); break; } case XV_PROP_BICUBIC: { int xv_bicubic = config->register_enum (config, "video.device.xv_bicubic", 2, (char **)bicubic_types, VIDEO_DEVICE_XV_BICUBIC_HELP, 20, xv_prop_update, &this->props[XV_PROP_BICUBIC]); xv_prop_update_int (&this->props[XV_PROP_BICUBIC], xv_bicubic); break; } } } } XFree (attr); } else xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": no port attributes defined.\n"); UNLOCK_DISPLAY (this); } free (adaptor_name); this->props[VO_PROP_BRIGHTNESS].defer = 1; this->props[VO_PROP_CONTRAST].defer = 1; this->props[VO_PROP_SATURATION].defer = 1; if ((this->props[VO_PROP_BRIGHTNESS].atom != None) && (this->props[VO_PROP_CONTRAST].atom != None)) { static const char * const xv_fullrange_conf_labels[] = {"Off", "Normal", NULL}; this->fullrange_mode = config->register_enum ( config, "video.output.xv_fullrange", 0, (char **)xv_fullrange_conf_labels, _("Fullrange colour emulation"), _("Emulate fullrange colour by modifying brightness/contrast/saturation settings.\n\n" "Off: Let decoders convert such video.\n" " Works with all graphics cards, but needs a bit more CPU power.\n\n" "Normal: Fast and better quality. Should work at least with some newer cards\n" " (GeForce 7+, 210+).\n\n"), 10, xv_fullrange_cb_config, this ); if (this->fullrange_mode) this->capabilities |= VO_CAP_FULLRANGE; } #ifdef DEBUG_EMU this->emu_yuy2 = config->register_bool ( config, "video.output.xv_debug_emu", 0, _("Force emulating yuy2"), _("Debug."), 10, xv_debug_emu_cb_config, this ); #endif /* * check max. supported image size */ { unsigned int nencode = 0; XvEncodingInfo *encodings = NULL; LOCK_DISPLAY (this); XvQueryEncodings (this->display, xv_port, &nencode, &encodings); if (encodings) { unsigned int n; for (n = 0; n < nencode; n++) { if (!strcmp (encodings[n].name, "XV_IMAGE")) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": max XvImage size %li x %li\n", encodings[n].width, encodings[n].height); this->props[VO_PROP_MAX_VIDEO_WIDTH].value = encodings[n].width; this->props[VO_PROP_MAX_VIDEO_HEIGHT].value = encodings[n].height; break; } } XvFreeEncodingInfo (encodings); } UNLOCK_DISPLAY (this); } /* * try to create a shared image * to find out if MIT shm really works, using supported format */ LOCK_DISPLAY(this); { XvImage *myimage; XShmSegmentInfo myshminfo; myimage = create_ximage (this, &myshminfo, 100, 100, (this->xv_format_yv12 != 0) ? XINE_IMGFMT_YV12 : XINE_IMGFMT_YUY2); if (myimage) dispose_ximage (this, &myshminfo, myimage); } UNLOCK_DISPLAY(this); this->use_pitch_alignment = config->register_bool (config, "video.device.xv_pitch_alignment", 0, VIDEO_DEVICE_XV_PITCH_ALIGNMENT_HELP, 10, xv_update_xv_pitch_alignment, this); LOCK_DISPLAY(this); if ((this->props[VO_PROP_COLORKEY].atom != None) && (this->props[VO_PROP_AUTOPAINT_COLORKEY].value != 1)) { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_COLORKEY); if(this->xoverlay) x11osd_colorkey (this->xoverlay, this->props[VO_PROP_COLORKEY].value, &this->sc); } else { this->xoverlay = x11osd_create (this->xine, this->display, this->screen, this->drawable, X11OSD_SHAPED); } UNLOCK_DISPLAY(this); if( this->xoverlay ) this->capabilities |= VO_CAP_UNSCALED_OVERLAY; return &this->vo_driver; } static vo_driver_t *open_plugin_old (video_driver_class_t *class_gen, const void *visual_gen) { const x11_visual_t *old_visual = (const x11_visual_t *) visual_gen; x11_visual_t visual; /* provides compatibility for XINE_VISUAL_TYPE_X11 */ visual.display = old_visual->display; visual.screen = old_visual->screen; visual.d = old_visual->d; visual.user_data = old_visual->user_data; visual.dest_size_cb = old_visual->dest_size_cb; visual.frame_output_cb = old_visual->frame_output_cb; visual.lock_display = NULL; visual.unlock_display = NULL; return open_plugin_2(class_gen, (void *)&visual); } /* * class functions */ static void *init_class (xine_t *xine, const void *visual_gen) { xv_class_t *this; (void)visual_gen; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin_old; this->driver_class.identifier = "Xv"; this->driver_class.description = N_("xine video output plugin using the MIT X video extension"); this->driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; return this; } static void *init_class_2 (xine_t *xine, const void *visual_gen) { xv_class_t *this; this = init_class (xine, visual_gen); if (this) { this->driver_class.open_plugin = open_plugin_2; } return this; } static const vo_info_t vo_info_xv = { .priority = 9, .visual_type = XINE_VISUAL_TYPE_X11, }; /* visual type with configurable X11 locking */ static const vo_info_t vo_info_xv_2 = { .priority = 9, .visual_type = XINE_VISUAL_TYPE_X11_2, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_OUT, 22, "xv", XINE_VERSION_CODE, &vo_info_xv, init_class }, { PLUGIN_VIDEO_OUT, 22, "xv", XINE_VERSION_CODE, &vo_info_xv_2, init_class_2 }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/0000755000175000017500000000000014647725152013307 5ustar memexine-lib-1.2/src/demuxers/asfheader.c0000644000175000017500000012413214647725152015400 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for asf streams * * based on ffmpeg's * ASF compatible encoder and decoder. * Copyright (c) 2000, 2001 Gerard Lantau. * * GUID list from avifile * some other ideas from MPlayer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_ICONV #include #endif #include #include #include #define LOG_MODULE "asfheader" #define LOG_VERBOSE /* #define LOG */ #include #include "bswap.h" #include "asfheader.h" /* #define TEST_INTERNAL_ICONV */ #if !defined(HAVE_ICONV) || defined(TEST_INTERNAL_ICONV) /* manual straightforward utf16 -> utf8 conversion */ # define iconv_open(TO, FROM) 0 # define iconv(CD, INBUF, INLEFT, OUTBUF, OUTLEFT) iconv_internal(INBUF, INLEFT, OUTBUF, OUTLEFT) # define iconv_close(CD) # ifdef ICONV_CONST # undef ICONV_CONST # endif # define ICONV_CONST const # if !defined(HAVE_ICONV) typedef int iconv_t; # endif static size_t iconv_internal (const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) { const uint8_t *p = (const uint8_t *)*inbuf; uint8_t *q = (uint8_t *)*outbuf; uint32_t a = (*inbytesleft) >> 1; uint32_t b = *outbytesleft; while (a) { uint32_t z = _X_LE_16 (p); if (z & 0xff80) { if (z & 0xf800) { /* 1110xxxx 10xxxxxx 10xxxxxx */ if (b < 3) break; *q++ = 0xe0 | (z >> 12); *q++ = 0x80 | ((z >> 6) & 0x3f); *q++ = 0x80 | (z & 0x3f); b -= 3; } else { /* 110xxxxx 10xxxxxx */ if (b < 2) break; *q++ = 0xc0 | (z >> 6); *q++ = 0x80 | (z & 0x3f); b -= 2; } } else { /* 0xxxxxxx */ if (!b) break; *q++ = z; b -= 1; } p += 2; a -= 1; } *inbuf = (const char *)p; *outbuf = (char *)q; *inbytesleft = a << 1; *outbytesleft = b; /* We just did a generic 1:1 conversion that is fully reversible. * Furthermore, code below only tests for (size_t)-1. */ return 0; } #endif typedef struct { const uint8_t *buffer; const uint8_t *p; const uint8_t *end; } asf_reader_t; typedef struct { asf_header_t pub; /* private part */ uint8_t *raw_data; int number_count; uint16_t numbers[ASF_MAX_NUM_STREAMS]; uint32_t bitrate_offsets[ASF_MAX_NUM_STREAMS]; } asf_header_internal_t; static void asf_reader_init (asf_reader_t *reader, const uint8_t *buffer, int size) { if (size < 0) size = 0; reader->buffer = reader->p = buffer; reader->end = buffer + size; } static const uint8_t *asf_reader_get_block (asf_reader_t *reader, uint32_t n) { const uint8_t *p; if ((uint32_t)(reader->end - reader->p) < n) return NULL; p = reader->p; reader->p += n; return p; } static uint8_t *asf_reader_get_bytes (asf_reader_t *reader, uint32_t size) { uint8_t *buffer; if (!size) return NULL; if ((uint32_t)(reader->end - reader->p) < size) return NULL; buffer = malloc (size); if (!buffer) return NULL; memcpy (buffer, reader->p, size); reader->p += size; return buffer; } /* get an utf8 string */ static char *asf_reader_get_string(asf_reader_t *reader, size_t size, iconv_t cd) { char *inbuf, *outbuf; size_t inbytesleft, outbytesleft; char scratch[2048]; if ((size == 0) || ((uint32_t)(reader->end - reader->p) < size)) return NULL; inbuf = (char *)reader->p; inbytesleft = size; outbuf = scratch; outbytesleft = sizeof (scratch) - 1; reader->p += size; if (iconv (cd, (ICONV_CONST char **)&inbuf, &inbytesleft, &outbuf, &outbytesleft) != (size_t)-1) { /* Those utf16 input strings normally are 0 terminated, but just in case... */ scratch[sizeof (scratch) - 1 - outbytesleft] = 0; return strdup(scratch); } else { lprintf("iconv error\n"); return NULL; } } static int asf_reader_skip (asf_reader_t *reader, uint32_t size) { if ((uint32_t)(reader->end - reader->p) < size) { reader->p = reader->end; return 0; } reader->p += size; return size; } static const uint8_t *asf_reader_get_buffer(asf_reader_t *reader) { return reader->p; } static int asf_reader_eos (asf_reader_t *reader) { return reader->p >= reader->end; } static size_t asf_reader_get_size(asf_reader_t *reader) { return reader->end - reader->p; } /* Manage id mapping */ static int asf_header_get_stream_id(asf_header_t *header_pub, uint16_t stream_number) { asf_header_internal_t *header = (asf_header_internal_t *)header_pub; int i; /* linear search */ for (i = 0; i < header->number_count; i++) { if (stream_number == header->numbers[i]) { lprintf("asf_header_get_stream_id: id found: %d\n", i); return i; } } /* not found */ if (header->number_count >= ASF_MAX_NUM_STREAMS) return -1; header->numbers[header->number_count] = stream_number; header->number_count++; return header->number_count - 1; } static int asf_header_parse_file_properties(asf_header_t *header, const uint8_t *buffer, int buffer_len) { asf_reader_t reader; asf_file_t *asf_file; const uint8_t *p; uint32_t flags = 0; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 16 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 4); if (!p) return 0; asf_file = malloc (sizeof (*asf_file)); if (!asf_file) { lprintf("cannot allocate asf_file_struct\n"); return 0; } /* full init here, no need to 0 first. */ memcpy (asf_file->file_id, p, 16); p += 16; asf_file->file_size = _X_LE_64 (p); p += 8; /* creation date */ p += 8; asf_file->data_packet_count = _X_LE_64 (p); p += 8; asf_file->play_duration = _X_LE_64 (p); p += 8; asf_file->send_duration = _X_LE_64 (p); p += 8; asf_file->preroll = _X_LE_64 (p); p += 8; flags = _X_LE_32 (p); p += 4; asf_file->packet_size = _X_LE_32 (p); p += 4; /* duplicated packet size */ p += 4; asf_file->max_bitrate = _X_LE_32 (p); p += 4; asf_file->broadcast_flag = flags & 0x1; asf_file->seekable_flag = flags & 0x2; header->file = asf_file; lprintf("File properties\n"); lprintf(" file_id: %04X\n", _X_LE_16(&asf_file->file_id[4])); lprintf(" file_size: %"PRIu64"\n", asf_file->file_size); lprintf(" data_packet_count: %"PRIu64"\n", asf_file->data_packet_count); lprintf(" play_duration: %"PRIu64"\n", asf_file->play_duration); lprintf(" send_duration: %"PRIu64"\n", asf_file->send_duration); lprintf(" preroll: %"PRIu64"\n", asf_file->preroll); lprintf(" broadcast_flag: %d\n", asf_file->broadcast_flag); lprintf(" seekable_flag: %d\n", asf_file->seekable_flag); lprintf(" packet_size: %"PRIu32"\n", asf_file->packet_size); lprintf(" max_bitrate: %"PRIu32"\n", asf_file->max_bitrate); return 1; } static void asf_header_delete_stream_properties(asf_stream_t *asf_stream) { if (asf_stream) { free (asf_stream->private_data); free (asf_stream->error_correction_data); free (asf_stream); } } static int asf_header_parse_stream_properties (asf_header_t *header, const uint8_t *buffer, int buffer_len) { asf_reader_t reader; const uint8_t *p; uint16_t flags = 0; asf_stream_t *asf_stream = NULL; int stream_id; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 16 + 16 + 8 + 4 + 4 + 2 + 4); if (!p) goto exit_error; asf_stream = malloc (sizeof (*asf_stream)); if (!asf_stream) goto exit_error; asf_stream->private_data = NULL; asf_stream->error_correction_data = NULL; asf_stream->stream_type = asf_guid_2_num (p); p += 16; asf_stream->error_correction_type = asf_guid_2_num (p); p += 16; asf_stream->time_offset = _X_LE_64 (p); p += 8; asf_stream->private_data_length = _X_LE_32 (p); p += 4; asf_stream->error_correction_data_length = _X_LE_32 (p); p += 4; flags = _X_LE_16 (p); p += 2; asf_stream->stream_number = flags & 0x7F; asf_stream->encrypted_flag = flags >> 15; /* junk */ p += 4; if (asf_stream->private_data_length) { asf_stream->private_data = asf_reader_get_bytes (&reader, asf_stream->private_data_length); if (!asf_stream->private_data) goto exit_error; } if (asf_stream->error_correction_data_length) { asf_stream->error_correction_data = asf_reader_get_bytes(&reader, asf_stream->error_correction_data_length); if (!asf_stream->error_correction_data) goto exit_error; } lprintf("Stream_properties\n"); lprintf(" stream_number: %d\n", asf_stream->stream_number); lprintf(" stream_type: %s\n", asf_guid_name (asf_stream->stream_type)); lprintf(" error_correction_type: %s\n", asf_guid_name (asf_stream->error_correction_type)); lprintf(" time_offset: %"PRIu64"\n", asf_stream->time_offset); lprintf(" private_data_length: %"PRIu32"\n", asf_stream->private_data_length); lprintf(" error_correction_data_length: %"PRIu32"\n", asf_stream->error_correction_data_length); lprintf(" encrypted_flag: %d\n", asf_stream->encrypted_flag); stream_id = asf_header_get_stream_id(header, asf_stream->stream_number); if (stream_id >= 0) { header->streams[stream_id] = asf_stream; header->stream_count++; } else { asf_header_delete_stream_properties(asf_stream); } return 1; exit_error: asf_header_delete_stream_properties(asf_stream); return 0; } static void asf_header_delete_stream_extended_properties(asf_stream_extension_t *asf_stream_extension) { if (asf_stream_extension) { if (asf_stream_extension->stream_names) { int i; for (i = 0; i < asf_stream_extension->stream_name_count; i++) free (asf_stream_extension->stream_names[i]); free (asf_stream_extension->stream_names); } free (asf_stream_extension); } } static int asf_header_parse_stream_extended_properties (asf_header_t *header, const uint8_t *buffer, int buffer_len) { asf_reader_t reader; const uint8_t *p; uint32_t flags = 0; uint16_t stream_number = 0; int i; int stream_id; asf_stream_extension_t *asf_stream_extension; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 2 * 8 + 7 * 4 + 4 + 2 + 2 + 8 + 2 + 2); if (!p) return 0; asf_stream_extension = malloc (sizeof (*asf_stream_extension)); if (!asf_stream_extension) return 0; asf_stream_extension->stream_names = NULL; asf_stream_extension->start_time = _X_LE_64 (p); p += 8; asf_stream_extension->end_time = _X_LE_64 (p); p += 8; asf_stream_extension->data_bitrate = _X_LE_32 (p); p += 4; asf_stream_extension->buffer_size = _X_LE_32 (p); p += 4; asf_stream_extension->initial_buffer_fullness = _X_LE_32 (p); p += 4; asf_stream_extension->alternate_data_bitrate = _X_LE_32 (p); p += 4; asf_stream_extension->alternate_buffer_size = _X_LE_32 (p); p += 4; asf_stream_extension->alternate_initial_buffer_fullness = _X_LE_32 (p); p += 4; asf_stream_extension->max_object_size = _X_LE_32 (p); p += 4; /* 4 flags */ flags = _X_LE_32 (p); p += 4; asf_stream_extension->reliable_flag = flags & 1; asf_stream_extension->seekable_flag = (flags >> 1) & 1; asf_stream_extension->no_cleanpoints_flag = (flags >> 2) & 1; asf_stream_extension->resend_live_cleanpoints_flag = (flags >> 3) & 1; stream_number = _X_LE_16 (p); p += 2; asf_stream_extension->language_id = _X_LE_16 (p); p += 2; asf_stream_extension->average_time_per_frame = _X_LE_64 (p); p += 8; asf_stream_extension->stream_name_count = _X_LE_16 (p); p += 2; asf_stream_extension->payload_extension_system_count = _X_LE_16 (p); p += 2; /* get stream names */ if (asf_stream_extension->stream_name_count) { asf_stream_extension->stream_names = calloc (asf_stream_extension->stream_name_count, sizeof (void*)); for (i = 0; i < asf_stream_extension->stream_name_count; i++) { char *name; uint16_t length; p = asf_reader_get_block (&reader, 2 + 2); /* lang_index, length */ if (!p) break; length = _X_LE_16 (p + 2); name = (char*)asf_reader_get_bytes (&reader, length); /* store them */ if (asf_stream_extension->stream_names) asf_stream_extension->stream_names[i] = name; else free(name); } } /* skip payload extensions */ for (i = 0; i < asf_stream_extension->payload_extension_system_count; i++) { uint32_t length; p = asf_reader_get_block (&reader, 16 + 2 + 4); /* guid, data_size, length */ if (!p) break; length = _X_LE_32 (p + 16 + 2); asf_reader_skip (&reader, length); } stream_id = asf_header_get_stream_id(header, stream_number); if (stream_id >= 0) { header->stream_extensions[stream_id] = asf_stream_extension; } /* embeded stream properties */ p = asf_reader_get_block (&reader, 16 + 8); if (p) { uint64_t object_length = _X_LE_64 (p + 16); /* check length validity */ if (asf_reader_get_size(&reader) == (object_length - 24)) { asf_guid_t object_id = asf_guid_2_num (p); switch (object_id) { case GUID_ASF_STREAM_PROPERTIES: asf_header_parse_stream_properties(header, asf_reader_get_buffer(&reader), object_length - 24); break; default: lprintf ("unexpected object\n"); break; } } else { lprintf ("invalid object length\n"); } } lprintf("Stream extension properties\n"); lprintf(" stream_number: %"PRIu16"\n", stream_number); lprintf(" start_time: %"PRIu64"\n", asf_stream_extension->start_time); lprintf(" end_time: %"PRIu64"\n", asf_stream_extension->end_time); lprintf(" data_bitrate: %"PRIu32"\n", asf_stream_extension->data_bitrate); lprintf(" buffer_size: %"PRIu32"\n", asf_stream_extension->buffer_size); lprintf(" initial_buffer_fullness: %"PRIu32"\n", asf_stream_extension->initial_buffer_fullness); lprintf(" alternate_data_bitrate: %"PRIu32"\n", asf_stream_extension->alternate_data_bitrate); lprintf(" alternate_buffer_size: %"PRIu32"\n", asf_stream_extension->alternate_buffer_size); lprintf(" alternate_initial_buffer_fullness: %"PRIu32"\n", asf_stream_extension->alternate_initial_buffer_fullness); lprintf(" max_object_size: %"PRIu32"\n", asf_stream_extension->max_object_size); lprintf(" language_id: %"PRIu16"\n", asf_stream_extension->language_id); lprintf(" average_time_per_frame: %"PRIu64"\n", asf_stream_extension->average_time_per_frame); lprintf(" stream_name_count: %"PRIu16"\n", asf_stream_extension->stream_name_count); lprintf(" payload_extension_system_count: %"PRIu16"\n", asf_stream_extension->payload_extension_system_count); lprintf(" reliable_flag: %d\n", asf_stream_extension->reliable_flag); lprintf(" seekable_flag: %d\n", asf_stream_extension->seekable_flag); lprintf(" no_cleanpoints_flag: %d\n", asf_stream_extension->no_cleanpoints_flag); lprintf(" resend_live_cleanpoints_flag: %d\n", asf_stream_extension->resend_live_cleanpoints_flag); if (stream_id < 0) { asf_header_delete_stream_extended_properties(asf_stream_extension); } return 1; } static int asf_header_parse_stream_bitrate_properties (asf_header_t *header_pub, const uint8_t *buffer, int buffer_len) { asf_header_internal_t *header = (asf_header_internal_t *)header_pub; asf_reader_t reader; const uint8_t *p; uint16_t bitrate_count = 0; int i; int stream_id; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 2); if (!p) return 0; bitrate_count = _X_LE_16 (p); p = asf_reader_get_block (&reader, 6 * bitrate_count); if (!p) return 0; lprintf (" bitrate count: %d\n", bitrate_count); for(i = 0; i < bitrate_count; i++) { uint16_t flags = 0; uint32_t bitrate = 0; int stream_number; uint32_t bitrate_offs; flags = _X_LE_16 (p); p += 2; stream_number = flags & 0x7f; bitrate_offs = p - (const uint8_t *)(header->raw_data); bitrate = _X_LE_32 (p); p += 4; lprintf (" stream num %d, bitrate %"PRIu32"\n", stream_number, bitrate); stream_id = asf_header_get_stream_id(&header->pub, stream_number); if (stream_id >= 0) { header->pub.bitrates[stream_id] = bitrate; header->bitrate_offsets[stream_id] = bitrate_offs; } } return 1; } static int asf_header_parse_metadata (asf_header_t *header_pub, const uint8_t *buffer, int buffer_len) { asf_header_internal_t *header = (asf_header_internal_t *)header_pub; asf_reader_t reader; const uint8_t *p; uint16_t i, records_count = 0; if (buffer_len < 2) return 0; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 2); if (!p) return 0; records_count = _X_LE_16 (p); for (i = 0; i < records_count; i++) { uint16_t index, stream = 0, name_len = 0, data_type; uint32_t data_len = 0; int stream_id; p = asf_reader_get_block (&reader, 4 * 2 + 4); if (!p) break; index = _X_LE_16 (p); p += 2; stream = _X_LE_16 (p); p += 2; stream &= 0x7f; name_len = _X_LE_16 (p); p += 2; data_type = _X_LE_16 (p); p += 2; data_len = _X_LE_32 (p); p += 4; /* not used yet */ (void)index; (void)data_type; stream_id = asf_header_get_stream_id (&header->pub, stream); if (stream_id >= 0 && data_len >= 4) { static const uint8_t name_ar[] = {'A',0,'s',0,'p',0,'e',0,'c',0,'t',0,'R',0,'a',0,'t',0,'i',0,'o',0}; static const uint8_t name_x[] = {'X',0,0,0}; static const uint8_t name_y[] = {'Y',0,0,0}; const uint8_t *p = asf_reader_get_block (&reader, name_len); if (p && (name_len >= sizeof (name_ar) + sizeof (name_x)) && !memcmp (p, name_ar, sizeof (name_ar))) { if (!memcmp (p + sizeof (name_ar), name_x, sizeof (name_x))) { p = asf_reader_get_block (&reader, 4); if (!p) break; header->pub.aspect_ratios[stream_id].x = _X_LE_32 (p); data_len -= 4; } else if (!memcmp (p + sizeof (name_ar), name_y, sizeof (name_y))) { p = asf_reader_get_block (&reader, 4); if (!p) break; header->pub.aspect_ratios[stream_id].y = _X_LE_32 (p); data_len -= 4; } } asf_reader_skip (&reader, data_len); } else { /* avoid uint32_t overflow */ asf_reader_skip (&reader, name_len); asf_reader_skip (&reader, data_len); } } return 1; } static int asf_header_parse_header_extension (asf_header_t *header, const uint8_t *buffer, int buffer_len) { asf_reader_t reader; const uint8_t *p; uint32_t data_length; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 16 + 2 + 4); /* guid, junk, data_length */ if (!p) return 0; data_length = _X_LE_32 (p + 16 + 2); lprintf("parse_asf_header_extension: length: %"PRIu32"\n", data_length); /* used in LOG mode only */ (void)data_length; while (!asf_reader_eos(&reader)) { asf_guid_t object_id; uint64_t object_length; uint32_t object_data_length; p = asf_reader_get_block (&reader, 16 + 8); if (!p) { printf("invalid buffer size\n"); return 0; } object_length = _X_LE_64 (p + 16); if (object_length & ~(uint64_t)0xffffffff) return 0; if ((uint32_t)object_length < 24) return 0; object_data_length = object_length - 24; object_id = asf_guid_2_num (p); switch (object_id) { case GUID_EXTENDED_STREAM_PROPERTIES: asf_header_parse_stream_extended_properties(header, asf_reader_get_buffer(&reader), object_data_length); break; case GUID_METADATA: asf_header_parse_metadata(header, asf_reader_get_buffer(&reader), object_data_length); break; case GUID_ADVANCED_MUTUAL_EXCLUSION: case GUID_GROUP_MUTUAL_EXCLUSION: case GUID_STREAM_PRIORITIZATION: case GUID_BANDWIDTH_SHARING: case GUID_LANGUAGE_LIST: case GUID_METADATA_LIBRARY: case GUID_INDEX_PARAMETERS: case GUID_MEDIA_OBJECT_INDEX_PARAMETERS: case GUID_TIMECODE_INDEX_PARAMETERS: case GUID_ADVANCED_CONTENT_ENCRYPTION: case GUID_COMPATIBILITY: case GUID_ASF_PADDING: break; default: lprintf ("unexpected object\n"); break; } asf_reader_skip(&reader, object_data_length); } return 1; } static int asf_header_parse_content_description (asf_header_t *header_pub, const uint8_t *buffer, int buffer_len) { asf_header_internal_t *header = (asf_header_internal_t *)header_pub; asf_reader_t reader; const uint8_t *p; asf_content_t *content; uint16_t title_length = 0, author_length = 0, copyright_length = 0, description_length = 0, rating_length = 0; iconv_t iconv_cd; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 5 * 2); if (!p) return 0; content = malloc (sizeof (*content)); if (!content) return 0; if ( (iconv_cd = iconv_open("UTF-8", "UCS-2LE")) == (iconv_t)-1 ) { free(content); return 0; } /* full init here, no need to 0 first. */ title_length = _X_LE_16 (p); author_length = _X_LE_16 (p + 2); copyright_length = _X_LE_16 (p + 4); description_length = _X_LE_16 (p + 6); rating_length = _X_LE_16 (p + 8); content->title = asf_reader_get_string(&reader, title_length, iconv_cd); content->author = asf_reader_get_string(&reader, author_length, iconv_cd); content->copyright = asf_reader_get_string(&reader, copyright_length, iconv_cd); content->description = asf_reader_get_string(&reader, description_length, iconv_cd); content->rating = asf_reader_get_string(&reader, rating_length, iconv_cd); lprintf("title: %d chars: \"%s\"\n", title_length, content->title); lprintf("author: %d chars: \"%s\"\n", author_length, content->author); lprintf("copyright: %d chars: \"%s\"\n", copyright_length, content->copyright); lprintf("description: %d chars: \"%s\"\n", description_length, content->description); lprintf("rating: %d chars: \"%s\"\n", rating_length, content->rating); header->pub.content = content; iconv_close(iconv_cd); return 1; } asf_header_t *asf_header_new (uint8_t *buffer, int buffer_len) { asf_header_internal_t *asf_header; asf_reader_t reader; const uint8_t *p; uint32_t object_count; #ifndef HAVE_ZERO_SAFE_MEM int i; #endif lprintf("parsing_asf_header\n"); if (buffer_len < 6) { printf("invalid buffer size\n"); return NULL; } asf_header = calloc (1, sizeof (*asf_header)); if (!asf_header) return NULL; #ifndef HAVE_ZERO_SAFE_MEM asf_header->pub.file = NULL; asf_header->pub.content = NULL; asf_header->pub.stream_count = 0; asf_header->number_count = 0; for (i = 0; i < ASF_MAX_NUM_STREAMS; i++) { asf_header->pub.streams[i] = NULL; asf_header->pub.stream_extensions[i] = NULL; asf_header->pub.bitrates[i] = 0; asf_header->pub.aspect_ratios[i].x = 0; asf_header->pub.aspect_ratios[i].y = 0; asf_header->numbers[i] = 0; asf_header->bitrate_offsets[i] = 0; } #endif asf_header->raw_data = buffer; asf_reader_init (&reader, buffer, buffer_len); p = asf_reader_get_block (&reader, 4 + 2); if (!p) goto exit_error; object_count = _X_LE_32 (p); /* not used yet */ (void)object_count; while (!asf_reader_eos(&reader)) { asf_guid_t object_id; uint64_t object_length; uint32_t object_data_length; p = asf_reader_get_block (&reader, 16 + 8); if (!p) { printf("invalid buffer size\n"); goto exit_error; } object_length = _X_LE_64 (p + 16); if (object_length & ~(uint64_t)0xffffffff) goto exit_error; if ((uint32_t)object_length < 24) goto exit_error; object_data_length = object_length - 24; object_id = asf_guid_2_num (p); switch (object_id) { case GUID_ASF_FILE_PROPERTIES: asf_header_parse_file_properties(&asf_header->pub, asf_reader_get_buffer(&reader), object_data_length); break; case GUID_ASF_STREAM_PROPERTIES: asf_header_parse_stream_properties(&asf_header->pub, asf_reader_get_buffer(&reader), object_data_length); break; case GUID_ASF_STREAM_BITRATE_PROPERTIES: asf_header_parse_stream_bitrate_properties(&asf_header->pub, asf_reader_get_buffer(&reader), object_data_length); break; case GUID_ASF_HEADER_EXTENSION: asf_header_parse_header_extension(&asf_header->pub, asf_reader_get_buffer(&reader), object_data_length); break; case GUID_ASF_CONTENT_DESCRIPTION: asf_header_parse_content_description(&asf_header->pub, asf_reader_get_buffer(&reader), object_data_length); break; case GUID_ASF_CODEC_LIST: case GUID_ASF_SCRIPT_COMMAND: case GUID_ASF_MARKER: case GUID_ASF_BITRATE_MUTUAL_EXCLUSION: case GUID_ASF_ERROR_CORRECTION: case GUID_ASF_EXTENDED_CONTENT_DESCRIPTION: case GUID_ASF_EXTENDED_CONTENT_ENCRYPTION: case GUID_ASF_PADDING: break; default: lprintf ("unexpected object\n"); break; } asf_reader_skip(&reader, object_data_length); } /* basic checks */ if (!asf_header->pub.file) { lprintf("no file object present\n"); goto exit_error; } if (!asf_header->pub.content) { lprintf("no content object present\n"); asf_header->pub.content = calloc(1, sizeof(asf_content_t)); if (!asf_header->pub.content) goto exit_error; } return &asf_header->pub; exit_error: asf_header_delete(&asf_header->pub); return NULL; } static void asf_header_delete_file_properties(asf_file_t *asf_file) { free(asf_file); } static void asf_header_delete_content(asf_content_t *asf_content) { if (asf_content) { free (asf_content->title); free (asf_content->author); free (asf_content->copyright); free (asf_content->description); free (asf_content->rating); free (asf_content); } } void asf_header_delete (asf_header_t *header_pub) { asf_header_internal_t *header = (asf_header_internal_t *)header_pub; if (header) { int i; asf_header_delete_file_properties (header->pub.file); asf_header_delete_content (header->pub.content); for (i = 0; i < ASF_MAX_NUM_STREAMS; i++) { asf_header_delete_stream_properties (header->pub.streams[i]); asf_header_delete_stream_extended_properties (header->pub.stream_extensions[i]); } free (header); } } /* Given a bandwidth, select the best stream */ static int asf_header_choose_stream (asf_header_internal_t *header, int stream_type, uint32_t bandwidth) { int i; int max_lt, min_gt; max_lt = min_gt = -1; for (i = 0; i < header->pub.stream_count; i++) { if ((int)header->pub.streams[i]->stream_type == stream_type) { if (header->pub.bitrates[i] <= bandwidth) { if ((max_lt == -1) || (header->pub.bitrates[i] > header->pub.bitrates[max_lt])) max_lt = i; } else { if ((min_gt == -1) || (header->pub.bitrates[i] < header->pub.bitrates[min_gt])) min_gt = i; } } } return (max_lt != -1) ? max_lt : min_gt; } void asf_header_choose_streams (asf_header_t *header_pub, uint32_t bandwidth, int *video_id, int *audio_id) { asf_header_internal_t *header = (asf_header_internal_t *)header_pub; uint32_t bandwidth_left; *video_id = *audio_id = -1; bandwidth_left = bandwidth; lprintf("%d streams, bandwidth %"PRIu32"\n", header->pub.stream_count, bandwidth_left); /* choose a video stream adapted to the user bandwidth */ *video_id = asf_header_choose_stream (header, GUID_ASF_VIDEO_MEDIA, bandwidth_left); if (*video_id != -1) { if (header->pub.bitrates[*video_id] < bandwidth_left) { bandwidth_left -= header->pub.bitrates[*video_id]; } else { bandwidth_left = 0; } lprintf("selected video stream %d, bandwidth left: %"PRIu32"\n", header->pub.streams[*video_id]->stream_number, bandwidth_left); } else { lprintf("no video stream\n"); } /* choose a audio stream adapted to the user bandwidth */ *audio_id = asf_header_choose_stream (header, GUID_ASF_AUDIO_MEDIA, bandwidth_left); if (*audio_id != -1) { if (header->pub.bitrates[*audio_id] < bandwidth_left) { bandwidth_left -= header->pub.bitrates[*audio_id]; } else { bandwidth_left = 0; } lprintf("selected audio stream %d, bandwidth left: %"PRIu32"\n", header->pub.streams[*audio_id]->stream_number, bandwidth_left); } else { lprintf("no audio stream\n"); } } void asf_header_disable_streams (asf_header_t *header_pub, int video_id, int audio_id) { asf_header_internal_t *header = (asf_header_internal_t *)header_pub; int i; for (i = 0; i < header->pub.stream_count; i++) { asf_guid_t stream_type = header->pub.streams[i]->stream_type; if (header->bitrate_offsets[i] && (((stream_type == GUID_ASF_VIDEO_MEDIA) && (i != video_id)) || ((stream_type == GUID_ASF_AUDIO_MEDIA) && (i != audio_id)))) { /* XXX: Only used by input/mmsh.c. Tweak the raw header data for later reinterpretation * by demuxer. Do NOT call this after freeing raw buffer!! */ uint8_t *bitrate_pointer = header->raw_data + header->bitrate_offsets[i]; /* disable the stream */ lprintf("stream %d disabled\n", header->pub.streams[i]->stream_number); *bitrate_pointer++ = 0; *bitrate_pointer++ = 0; *bitrate_pointer++ = 0; *bitrate_pointer = 0; } } } static const asf_guid_t sorted_nums[] = { GUID_ERROR, GUID_ASF_NO_ERROR_CORRECTION, GUID_ASF_JFIF_MEDIA, GUID_ASF_MUTEX_BITRATE, GUID_ASF_MARKER, GUID_ASF_MUTEX_UKNOWN, GUID_ASF_RESERVED_1, GUID_ASF_EXTENDED_CONTENT_ENCRYPTION, GUID_ASF_RESERVED_MARKER, GUID_ASF_FILE_TRANSFER_MEDIA, GUID_ASF_SCRIPT_COMMAND, GUID_ASF_HEADER, GUID_ASF_CONTENT_DESCRIPTION, GUID_ADVANCED_CONTENT_ENCRYPTION, GUID_ASF_ERROR_CORRECTION, GUID_ASF_DATA, GUID_ASF_CODEC_LIST, GUID_GROUP_MUTUAL_EXCLUSION, GUID_ASF_AUDIO_MEDIA, GUID_ASF_EXTENDED_CONTENT_DESCRIPTION, GUID_ASF_AUDIO_CONCEAL_NONE, GUID_ASF_CODEC_COMMENT1_HEADER, GUID_ASF_AUDIO_SPREAD, GUID_STREAM_PRIORITIZATION, GUID_COMPATIBILITY, GUID_TIMECODE_INDEX_PARAMETERS, GUID_ASF_PADDING, GUID_ASF_SIMPLE_INDEX, GUID_ASF_STREAM_PROPERTIES, GUID_METADATA_LIBRARY, GUID_ASF_FILE_PROPERTIES, GUID_LANGUAGE_LIST, GUID_MEDIA_OBJECT_INDEX_PARAMETERS, GUID_ASF_HEADER_EXTENSION, GUID_ASF_COMMAND_MEDIA, GUID_ASF_VIDEO_MEDIA, GUID_EXTENDED_STREAM_PROPERTIES, GUID_ASF_STREAM_BITRATE_PROPERTIES, GUID_ADVANCED_MUTUAL_EXCLUSION, GUID_TIMECODE_INDEX, GUID_ASF_2_0_HEADER, GUID_INDEX, GUID_ASF_BITRATE_MUTUAL_EXCLUSION, GUID_INDEX_PARAMETERS, GUID_ASF_DEGRADABLE_JPEG_MEDIA, GUID_ASF_BINARY_MEDIA, GUID_ASF_RESERVED_SCRIPT_COMMNAND, GUID_BANDWIDTH_SHARING, GUID_METADATA, GUID_MEDIA_OBJECT_INDEX }; static const uint8_t sorted_guids[] = { 0x00,0x00,0x00,0x00, 0x00,0x00, 0x00,0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* GUID_ERROR */ 0x00,0x57,0xfb,0x20, 0x55,0x5b, 0xcf,0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b, /* GUID_ASF_NO_ERROR_CORRECTION */ 0x00,0xe1,0x1b,0xb6, 0x4e,0x5b, 0xcf,0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b, /* GUID_ASF_JFIF_MEDIA */ 0x01,0x2a,0xe2,0xd6, 0xda,0x35, 0xd1,0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe, /* GUID_ASF_MUTEX_BITRATE */ 0x01,0xcd,0x87,0xf4, 0x51,0xa9, 0xcf,0x11, 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65, /* GUID_ASF_MARKER */ 0x02,0x2a,0xe2,0xd6, 0xda,0x35, 0xd1,0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe, /* GUID_ASF_MUTEX_UKNOWN */ 0x11,0xd2,0xd3,0xab, 0xba,0xa9, 0xcf,0x11, 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65, /* GUID_ASF_RESERVED_1 */ 0x14,0xe6,0x8a,0x29, 0x22,0x26, 0x17,0x4c, 0xb9, 0x35, 0xda, 0xe0, 0x7e, 0xe9, 0x28, 0x9c, /* GUID_ASF_EXTENDED_CONTENT_ENCRYPTION */ 0x20,0xdb,0xfe,0x4c, 0xf6,0x75, 0xcf,0x11, 0x9c, 0x0f, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb, /* GUID_ASF_RESERVED_MARKER */ 0x2c,0x22,0xbd,0x91, 0x1c,0xf2, 0x7a,0x49, 0x8b, 0x6d, 0x5a, 0xa8, 0x6b, 0xfc, 0x01, 0x85, /* GUID_ASF_FILE_TRANSFER_MEDIA */ 0x30,0x1a,0xfb,0x1e, 0x62,0x0b, 0xd0,0x11, 0xa3, 0x9b, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6, /* GUID_ASF_SCRIPT_COMMAND */ 0x30,0x26,0xb2,0x75, 0x8e,0x66, 0xcf,0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c, /* GUID_ASF_HEADER */ 0x33,0x26,0xb2,0x75, 0x8e,0x66, 0xcf,0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c, /* GUID_ASF_CONTENT_DESCRIPTION */ 0x33,0x85,0x05,0x43, 0x81,0x69, 0xe6,0x49, 0x9b, 0x74, 0xad, 0x12, 0xcb, 0x86, 0xd5, 0x8c, /* GUID_ADVANCED_CONTENT_ENCRYPTION */ 0x35,0x26,0xb2,0x75, 0x8e,0x66, 0xcf,0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c, /* GUID_ASF_ERROR_CORRECTION */ 0x36,0x26,0xb2,0x75, 0x8e,0x66, 0xcf,0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c, /* GUID_ASF_DATA */ 0x40,0x52,0xd1,0x86, 0x1d,0x31, 0xd0,0x11, 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6, /* GUID_ASF_CODEC_LIST */ 0x40,0x5a,0x46,0xd1, 0x79,0x5a, 0x38,0x43, 0xb7, 0x1b, 0xe3, 0x6b, 0x8f, 0xd6, 0xc2, 0x49, /* GUID_GROUP_MUTUAL_EXCLUSION */ 0x40,0x9e,0x69,0xf8, 0x4d,0x5b, 0xcf,0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b, /* GUID_ASF_AUDIO_MEDIA */ 0x40,0xa4,0xd0,0xd2, 0x07,0xe3, 0xd2,0x11, 0x97, 0xf0, 0x00, 0xa0, 0xc9, 0x5e, 0xa8, 0x50, /* GUID_ASF_EXTENDED_CONTENT_DESCRIPTION */ 0x40,0xa4,0xf1,0x49, 0xce,0x4e, 0xd0,0x11, 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6, /* GUID_ASF_AUDIO_CONCEAL_NONE */ 0x41,0x52,0xd1,0x86, 0x1d,0x31, 0xd0,0x11, 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6, /* GUID_ASF_CODEC_COMMENT1_HEADER */ 0x50,0xcd,0xc3,0xbf, 0x8f,0x61, 0xcf,0x11, 0x8b, 0xb2, 0x00, 0xaa, 0x00, 0xb4, 0xe2, 0x20, /* GUID_ASF_AUDIO_SPREAD */ 0x5b,0xd1,0xfe,0xd4, 0xd3,0x88, 0x4f,0x45, 0x81, 0xf0, 0xed, 0x5c, 0x45, 0x99, 0x9e, 0x24, /* GUID_STREAM_PRIORITIZATION */ 0x5d,0x8b,0xf1,0x26, 0x84,0x45, 0xec,0x47, 0x9f, 0x5f, 0x0e, 0x65, 0x1f, 0x04, 0x52, 0xc9, /* GUID_COMPATIBILITY */ 0x6d,0x49,0x5e,0xf5, 0x97,0x97, 0x5d,0x4b, 0x8c, 0x8b, 0x60, 0x4d, 0xf9, 0x9b, 0xfb, 0x24, /* GUID_TIMECODE_INDEX_PARAMETERS */ 0x74,0xd4,0x06,0x18, 0xdf,0xca, 0x09,0x45, 0xa4, 0xba, 0x9a, 0xab, 0xcb, 0x96, 0xaa, 0xe8, /* GUID_ASF_PADDING */ 0x90,0x08,0x00,0x33, 0xb1,0xe5, 0xcf,0x11, 0x89, 0xf4, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb, /* GUID_ASF_SIMPLE_INDEX */ 0x91,0x07,0xdc,0xb7, 0xb7,0xa9, 0xcf,0x11, 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65, /* GUID_ASF_STREAM_PROPERTIES */ 0x94,0x1c,0x23,0x44, 0x98,0x94, 0xd1,0x49, 0xa1, 0x41, 0x1d, 0x13, 0x4e, 0x45, 0x70, 0x54, /* GUID_METADATA_LIBRARY */ 0xa1,0xdc,0xab,0x8c, 0x47,0xa9, 0xcf,0x11, 0x8e, 0xe4, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65, /* GUID_ASF_FILE_PROPERTIES */ 0xa9,0x46,0x43,0x7c, 0xe0,0xef, 0xfc,0x4b, 0xb2, 0x29, 0x39, 0x3e, 0xde, 0x41, 0x5c, 0x85, /* GUID_LANGUAGE_LIST */ 0xad,0x3b,0x20,0x6b, 0x11,0x3f, 0xe4,0x48, 0xac, 0xa8, 0xd7, 0x61, 0x3d, 0xe2, 0xcf, 0xa7, /* GUID_MEDIA_OBJECT_INDEX_PARAMETERS */ 0xb5,0x03,0xbf,0x5f, 0x2e,0xa9, 0xcf,0x11, 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65, /* GUID_ASF_HEADER_EXTENSION */ 0xc0,0xcf,0xda,0x59, 0xe6,0x59, 0xd0,0x11, 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6, /* GUID_ASF_COMMAND_MEDIA */ 0xc0,0xef,0x19,0xbc, 0x4d,0x5b, 0xcf,0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b, /* GUID_ASF_VIDEO_MEDIA */ 0xcb,0xa5,0xe6,0x14, 0x72,0xc6, 0x32,0x43, 0x83, 0x99, 0xa9, 0x69, 0x52, 0x06, 0x5b, 0x5a, /* GUID_EXTENDED_STREAM_PROPERTIES */ 0xce,0x75,0xf8,0x7b, 0x8d,0x46, 0xd1,0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2, /* GUID_ASF_STREAM_BITRATE_PROPERTIES */ 0xcf,0x49,0x86,0xa0, 0x75,0x47, 0x70,0x46, 0x8a, 0x16, 0x6e, 0x35, 0x35, 0x75, 0x66, 0xcd, /* GUID_ADVANCED_MUTUAL_EXCLUSION */ 0xd0,0x3f,0xb7,0x3c, 0x4a,0x0c, 0x03,0x48, 0x95, 0x3d, 0xed, 0xf7, 0xb6, 0x22, 0x8f, 0x0c, /* GUID_TIMECODE_INDEX */ 0xd1,0x29,0xe2,0xd6, 0xda,0x35, 0xd1,0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe, /* GUID_ASF_2_0_HEADER */ 0xd3,0x29,0xe2,0xd6, 0xda,0x35, 0xd1,0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe, /* GUID_INDEX */ 0xdc,0x29,0xe2,0xd6, 0xda,0x35, 0xd1,0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe, /* GUID_ASF_BITRATE_MUTUAL_EXCLUSION */ 0xdf,0x29,0xe2,0xd6, 0xda,0x35, 0xd1,0x11, 0x90, 0x34, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xbe, /* GUID_INDEX_PARAMETERS */ 0xe0,0x7d,0x90,0x35, 0x15,0xe4, 0xcf,0x11, 0xa9, 0x17, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b, /* GUID_ASF_DEGRADABLE_JPEG_MEDIA */ 0xe2,0x65,0xfb,0x3a, 0xef,0x47, 0xf2,0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43, /* GUID_ASF_BINARY_MEDIA */ 0xe3,0xcb,0x1a,0x4b, 0x0b,0x10, 0xd0,0x11, 0xa3, 0x9b, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6, /* GUID_ASF_RESERVED_SCRIPT_COMMNAND */ 0xe6,0x09,0x96,0xa6, 0x7b,0x51, 0xd2,0x11, 0xb6, 0xaf, 0x00, 0xc0, 0x4f, 0xd9, 0x08, 0xe9, /* GUID_BANDWIDTH_SHARING */ 0xea,0xcb,0xf8,0xc5, 0xaf,0x5b, 0x77,0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca, /* GUID_METADATA */ 0xf8,0x03,0xb1,0xfe, 0xad,0x12, 0x64,0x4c, 0x84, 0x0f, 0x2a, 0x1d, 0x2f, 0x7a, 0xd4, 0x8c, /* GUID_MEDIA_OBJECT_INDEX */ }; asf_guid_t asf_guid_2_num (const uint8_t *guid) { int b = 0, m = -1, l, e = sizeof (sorted_guids) >> 4; do { const uint8_t *p, *q; int i; l = m; m = (b + e) >> 1; p = sorted_guids + (m << 4); q = guid; i = 16; do { int d = (int)*q++ - (int)*p++; if (d < 0) { e = m; break; } else if (d > 0) { b = m; break; } i--; } while (i); if (!i) return sorted_nums[m]; } while (m != l); return sorted_nums[0]; } static const char tab_hex[16] = "0123456789abcdef"; void asf_guid_2_str (uint8_t *str, const uint8_t *guid) { *str++ = tab_hex[guid[3] >> 4]; *str++ = tab_hex[guid[3] & 15]; *str++ = tab_hex[guid[2] >> 4]; *str++ = tab_hex[guid[2] & 15]; *str++ = tab_hex[guid[1] >> 4]; *str++ = tab_hex[guid[1] & 15]; *str++ = tab_hex[guid[0] >> 4]; *str++ = tab_hex[guid[0] & 15]; *str++ = '-'; *str++ = tab_hex[guid[5] >> 4]; *str++ = tab_hex[guid[5] & 15]; *str++ = tab_hex[guid[4] >> 4]; *str++ = tab_hex[guid[4] & 15]; *str++ = '-'; *str++ = tab_hex[guid[7] >> 4]; *str++ = tab_hex[guid[7] & 15]; *str++ = tab_hex[guid[6] >> 4]; *str++ = tab_hex[guid[6] & 15]; *str++ = '-'; guid += 8; int i = 8; while (i > 0) { *str++ = tab_hex[guid[0] >> 4]; *str++ = tab_hex[guid[0] & 15]; guid++; i--; } *str = 0; } static const char * guid_names[] = { "error", /* base ASF objects */ "header", "data", "simple index", "index", "media object index", "timecode index", /* header ASF objects */ "file properties", "stream header", "header extension", "codec list", "script command", "marker", "bitrate mutual exclusion", "error correction", "content description", "extended content description", "stream bitrate properties", /* (http://get.to/sdp) */ "extended content encryption", "padding", /* stream properties object stream type */ "audio media", "video media", "command media", "JFIF media (JPEG)", "Degradable JPEG media", "File Transfer media", "Binary media", /* stream properties object error correction */ "no error correction", "audio spread", /* mutual exclusion object exlusion type */ "mutex bitrate", "mutex unknown", /* header extension */ "reserved_1", /* script command */ "reserved script command", /* marker object */ "reserved marker", /* various */ "audio conceal none", "codec comment1 header", "asf 2.0 header", /* header extension GUIDs */ "extended stream properties", "advanced mutual exclusion", "group mutual exclusion", "stream prioritization", "bandwidth sharing", "language list", "metadata", "metadata library", "index parameters", "media object index parameters", "timecode index parameters", "advanced content encryption", /* exotic stuff */ "compatibility", }; const char *asf_guid_name (asf_guid_t num) { if (num >= GUID_END) num = GUID_ERROR; return guid_names[num]; } xine-lib-1.2/src/demuxers/demux_nsv.c0000644000175000017500000004106014647725152015464 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * Nullsoft Video (NSV) file demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the NSV file format, visit: * http://www.pcisys.net/~melanson/codecs/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_nsv" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include #define FOURCC_TAG BE_FOURCC #define NSVf_TAG FOURCC_TAG('N', 'S', 'V', 'f') #define NSVs_TAG FOURCC_TAG('N', 'S', 'V', 's') #define BEEF 0xEFBE #define NSV_MAX_RESYNC (1024 * 1024) #define NSV_RESYNC_ERROR 0 #define NSV_RESYNC_BEEF 1 #define NSV_RESYNC_NSVf 2 #define NSV_RESYNC_NSVs 3 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_size; unsigned int fps; unsigned int frame_pts_inc; unsigned int video_type; int64_t video_pts; unsigned int audio_type; uint32_t video_fourcc; uint32_t audio_fourcc; int keyframe_found; int is_first_chunk; xine_bmiheader bih; /* ultravox stuff */ int is_ultravox; int ultravox_size; int ultravox_pos; int ultravox_first; } demux_nsv_t; static void nsv_parse_framerate(demux_nsv_t *this, uint8_t framerate) { /* need 1 more byte */ this->fps = framerate; if (this->fps & 0x80) { switch (this->fps & 0x7F) { case 1: /* 29.97 fps */ this->frame_pts_inc = 3003; break; case 3: /* 23.976 fps */ this->frame_pts_inc = 3753; break; case 5: /* 14.98 fps */ this->frame_pts_inc = 6006; break; default: lprintf("unknown framerate: 0x%02X\n", this->fps); this->frame_pts_inc = 90000; break; } } else this->frame_pts_inc = 90000 / this->fps; lprintf("frame_pts_inc=%d\n", this->frame_pts_inc); } static off_t nsv_read(demux_nsv_t *this, uint8_t *buffer, off_t len) { if (this->is_ultravox != 2) { return this->input->read(this->input, buffer, len); } else { int ultravox_rest; int buffer_pos = 0; /* ultravox stuff */ while (len) { ultravox_rest = this->ultravox_size - this->ultravox_pos; if (len > ultravox_rest) { uint8_t ultravox_buf[7]; if (ultravox_rest) { if (this->input->read(this->input, buffer + buffer_pos, ultravox_rest) != ultravox_rest) return -1; buffer_pos += ultravox_rest; len -= ultravox_rest; } /* parse ultravox packet header */ if (this->ultravox_first) { /* only 6 bytes */ this->ultravox_first = 0; ultravox_buf[0] = 0; if (this->input->read(this->input, ultravox_buf + 1, 6) != 6) return -1; } else { if (this->input->read(this->input, ultravox_buf, 7) != 7) return -1; } /* check signature */ if ((ultravox_buf[0] != 0x00) || (ultravox_buf[1] != 0x5A)) { lprintf("lost ultravox sync\n"); return -1; } /* read packet payload len */ this->ultravox_size = _X_BE_16(&ultravox_buf[5]); this->ultravox_pos = 0; lprintf("ultravox_size: %d\n", this->ultravox_size); } else { if (this->input->read(this->input, buffer + buffer_pos, len) != len) return -1; buffer_pos += len; this->ultravox_pos += len; len = 0; } } return buffer_pos; } } static off_t nsv_seek(demux_nsv_t *this, off_t offset, int origin) { if (this->is_ultravox != 2) { return this->input->seek(this->input, offset, origin); } else { /* ultravox stuff */ if (origin == SEEK_CUR) { uint8_t buffer[1024]; while (offset) { if (offset > (off_t)sizeof(buffer)) { if (nsv_read(this, buffer, sizeof(buffer)) != sizeof(buffer)) return -1; offset = 0; } else { if (nsv_read(this, buffer, offset) != offset) return -1; offset -= sizeof(buffer); } } return 0; } else { /* not supported */ return -1; } } } static int nsv_resync(demux_nsv_t *this) { int i; uint32_t tag = 0; for (i = 0; i < NSV_MAX_RESYNC; i++) { uint8_t byte; if (nsv_read(this, &byte, 1) != 1) return NSV_RESYNC_ERROR; #ifdef LOG printf("%2X ", byte); #endif tag = (tag << 8) | byte; if ((tag & 0x0000ffff) == BEEF) { lprintf("found BEEF after %d bytes\n", i + 1); return NSV_RESYNC_BEEF; } else if (tag == NSVs_TAG) { lprintf("found NSVs after %d bytes\n", i + 1); return NSV_RESYNC_NSVs; } else if (tag == NSVf_TAG) { lprintf("found NSVf after %d bytes\n", i + 1); return NSV_RESYNC_NSVf; } } lprintf("can't resync\n"); return NSV_RESYNC_ERROR; } /* returns 1 if the NSV file was opened successfully, 0 otherwise */ static int open_nsv_file(demux_nsv_t *this) { unsigned char preview[28]; int NSVs_found = 0; if (_x_demux_read_header(this->input, preview, 4) != 4) return 0; /* check for a 'NSV' signature */ if ( memcmp(preview, "Z\09", 3) == 0) { this->is_ultravox = preview[3]; this->ultravox_first = 1; } else if ( memcmp(preview, "NSV", 3) != 0 ) return 0; lprintf("NSV file detected, ultravox=%d\n", this->is_ultravox); this->data_size = this->input->get_length(this->input); while (!NSVs_found) { switch (nsv_resync(this)) { case NSV_RESYNC_NSVf: { uint32_t chunk_size; /* if there is a NSVs tag, load 24 more header bytes; load starting at * offset 4 in buffer to keep header data in line with document */ if (nsv_read(this, &preview[4], 24) != 24) return 0; lprintf("found NSVf chunk\n"); /* this->data_size = _X_LE_32(&preview[8]);*/ /*lprintf("data_size: %lld\n", this->data_size);*/ /* skip the rest of the data */ chunk_size = _X_LE_32(&preview[4]); nsv_seek(this, chunk_size - 28, SEEK_CUR); } break; case NSV_RESYNC_NSVs: /* fetch the remaining 15 header bytes of the first chunk to get the * relevant information */ if (nsv_read(this, &preview[4], 15) != 15) return 0; this->video_fourcc = _X_ME_32(&preview[4]); if (_x_is_fourcc(&preview[4], "NONE")) this->video_type = 0; else { this->video_type = _x_fourcc_to_buf_video(this->video_fourcc); if (!this->video_type) _x_report_video_fourcc (this->stream->xine, LOG_MODULE, this->video_fourcc); } this->audio_fourcc = _X_ME_32(&preview[8]); if (_x_is_fourcc(&preview[8], "NONE")) this->audio_type = 0; else { this->audio_type = _x_formattag_to_buf_audio(this->audio_fourcc); if (!this->audio_type) _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, this->audio_fourcc); } this->bih.biSize = sizeof(this->bih); this->bih.biWidth = _X_LE_16(&preview[12]); this->bih.biHeight = _X_LE_16(&preview[14]); this->bih.biCompression = this->video_fourcc; this->video_pts = 0; /* may not be true, but set it for the time being */ this->frame_pts_inc = 3003; lprintf("video: %c%c%c%c, buffer type %08X, %dx%d\n", preview[4], preview[5], preview[6], preview[7], this->video_type, this->bih.biWidth, this->bih.biHeight); lprintf("audio: %c%c%c%c, buffer type %08X\n", preview[8], preview[9], preview[10], preview[11], this->audio_type); nsv_parse_framerate(this, preview[16]); NSVs_found = 1; break; case NSV_RESYNC_ERROR: return 0; } } this->is_first_chunk = 1; return 1; } static int nsv_parse_payload(demux_nsv_t *this, int video_size, int audio_size) { buf_element_t *buf; off_t current_file_pos; lprintf("video_size=%d, audio_size=%d\n", video_size, audio_size); current_file_pos = this->input->get_current_pos(this->input); while (video_size) { int buf_num = 0; buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); if (video_size > buf->max_size) buf->size = buf->max_size; else buf->size = video_size; video_size -= buf->size; if (nsv_read(this, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } /* HACK: parse decoder data to detect a keyframe */ if ((buf_num == 0) && (!this->keyframe_found)) { switch (this->video_type) { case BUF_VIDEO_VP31: if ((buf->content[1] == 0x00) && (buf->content[2] == 0x08)) { lprintf("keyframe detected !\n"); this->keyframe_found = 1; } break; case BUF_VIDEO_VP6: if ((buf->content[1] & 0x0e) == 0x06) { lprintf("keyframe detected !\n"); this->keyframe_found = 1; } break; default: /* don't know how to detect keyframe */ this->keyframe_found = 1; } buf_num++; } if (this->keyframe_found) { buf->type = this->video_type; if( this->data_size ) buf->extra_info->input_normpos = (int)((double)current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = this->frame_pts_inc; if (!video_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put(this->video_fifo, buf); } else { buf->free_buffer(buf); } } while (audio_size) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); if (audio_size > buf->max_size) buf->size = buf->max_size; else buf->size = audio_size; audio_size -= buf->size; if (nsv_read(this, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } buf->type = this->audio_type; if( this->data_size ) buf->extra_info->input_normpos = (int)((double)current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = this->frame_pts_inc; if (!audio_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put(this->audio_fifo, buf); } this->video_pts += this->frame_pts_inc; return this->status; } static int demux_nsv_send_chunk(demux_plugin_t *this_gen) { demux_nsv_t *this = (demux_nsv_t *) this_gen; uint8_t buffer[15]; int video_size; int audio_size; int chunk_type; lprintf("dispatching video & audio chunks...\n"); if (this->is_first_chunk) { chunk_type = NSV_RESYNC_BEEF; this->is_first_chunk = 0; } else { chunk_type = nsv_resync(this); } switch (chunk_type) { case NSV_RESYNC_NSVf: /* do nothing */ break; case NSV_RESYNC_NSVs: /* skip header */ if (nsv_read(this, buffer, 15) != 15) return 0; nsv_parse_framerate(this, buffer[12]); /* fall thru */ case NSV_RESYNC_BEEF: if (nsv_read(this, buffer, 5) != 5) { this->status = DEMUX_FINISHED; return this->status; } video_size = _X_LE_32(&buffer[0]); video_size >>= 4; video_size &= 0xFFFFF; audio_size = _X_LE_16(&buffer[3]); nsv_parse_payload(this, video_size, audio_size); break; case NSV_RESYNC_ERROR: this->status = DEMUX_FINISHED; break; } return this->status; } static void demux_nsv_send_headers(demux_plugin_t *this_gen) { demux_nsv_t *this = (demux_nsv_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, this->video_fourcc); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->audio_fourcc); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, (this->video_type) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->audio_type) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to the video decoder */ if (this->video_type) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->frame_pts_inc; memcpy(buf->content, &this->bih, sizeof(this->bih)); buf->size = sizeof(this->bih); buf->type = this->video_type; this->video_fifo->put (this->video_fifo, buf); } } static int demux_nsv_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_nsv_t *this = (demux_nsv_t *) this_gen; lprintf("starting demuxer\n"); (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static int demux_nsv_get_status (demux_plugin_t *this_gen) { demux_nsv_t *this = (demux_nsv_t *) this_gen; return this->status; } static int demux_nsv_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_nsv_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_nsv_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_nsv_t *this; this = calloc(1, sizeof(demux_nsv_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_nsv_send_headers; this->demux_plugin.send_chunk = demux_nsv_send_chunk; this->demux_plugin.seek = demux_nsv_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_nsv_get_status; this->demux_plugin.get_stream_length = demux_nsv_get_stream_length; this->demux_plugin.get_capabilities = demux_nsv_get_capabilities; this->demux_plugin.get_optional_data = demux_nsv_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_nsv_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } static void *demux_nsv_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_nsv_class = { .open_plugin = open_plugin, .description = N_("Nullsoft Video demux plugin"), .identifier = "Nullsoft NSV", .mimetypes = NULL, .extensions = "nsv", .dispose = NULL, }; return (void *)&demux_nsv_class; } /* * exported plugin catalog entry */ static const demuxer_info_t demux_info_nsv = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "nsv", XINE_VERSION_CODE, &demux_info_nsv, demux_nsv_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_image.c0000644000175000017500000001761314647725152015747 0ustar meme/* * Copyright (C) 2003-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * image dummy demultiplexer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_image" #define LOG_VERBOSE /* #define LOG */ #include #include #include "bswap.h" #include #define IMAGE_HEADER_LEN 4 typedef struct demux_image_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int buf_type; int decoder_flags; int bytes_left; } demux_image_t ; static uint32_t _probe (xine_t *xine, const uint8_t *header) { if (memcmp (header, "GIF", 3) == 0) { /* GIF */ if (_x_decoder_available (xine, BUF_VIDEO_IMAGE)) return BUF_VIDEO_IMAGE; } else if (memcmp (header, "BM", 2) == 0) { /* BMP */ if (_x_decoder_available (xine, BUF_VIDEO_IMAGE)) return BUF_VIDEO_IMAGE; } else if (memcmp (header, "\x89PNG", 4) == 0) { /* PNG */ if (_x_decoder_available (xine, BUF_VIDEO_PNG)) return BUF_VIDEO_PNG; } else if (memcmp (header, "\xff\xd8", 2) == 0) { /* JPEG */ if (_x_decoder_available (xine, BUF_VIDEO_JPEG)) return BUF_VIDEO_JPEG; } return 0; } static int demux_image_get_status (demux_plugin_t *this_gen) { demux_image_t *this = (demux_image_t *) this_gen; return this->status; } static int demux_image_next (demux_plugin_t *this_gen, int decoder_flags) { demux_image_t *this = (demux_image_t *) this_gen; buf_element_t *buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, this->bytes_left); buf->content = buf->mem; buf->decoder_flags = this->decoder_flags | decoder_flags; this->decoder_flags = 0; buf->size = this->input->read (this->input, (char *)buf->mem, buf->max_size); this->bytes_left -= buf->size; if (this->bytes_left < 0) this->bytes_left = 0; if (buf->size <= 0) { buf->size = 0; buf->decoder_flags |= BUF_FLAG_FRAME_END; this->status = DEMUX_FINISHED; } else { if (!this->buf_type) { this->buf_type = _probe (this->stream->xine, buf->content); if (!this->buf_type) { /* allow forcing any file to generic image decoders */ this->buf_type = BUF_VIDEO_IMAGE; } } this->status = DEMUX_OK; } buf->type = this->buf_type; this->video_fifo->put (this->video_fifo, buf); return this->status; } static int demux_image_send_chunk (demux_plugin_t *this_gen) { return demux_image_next(this_gen, 0); } static void demux_image_send_headers (demux_plugin_t *this_gen) { demux_image_t *this = (demux_image_t *) this_gen; this->video_fifo = this->stream->video_fifo; _x_demux_control_start(this->stream); if (this->input->seek (this->input, 0, SEEK_SET) != 0) { this->status = DEMUX_FINISHED; return; } this->decoder_flags = BUF_FLAG_FRAME_START; this->bytes_left = this->input->get_length (this->input); if (this->bytes_left < 0) this->bytes_left = 0; /* we can send everything here. this makes image decoder a lot easier */ while (demux_image_next(this_gen, BUF_FLAG_PREVIEW) == DEMUX_OK); this->decoder_flags = BUF_FLAG_FRAME_START; this->status = DEMUX_OK; _x_stream_info_set (this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); } static int demux_image_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_image_t *this = (demux_image_t *) this_gen; (void)start_pos; (void)start_time; if (!playing) _x_demux_control_newpts (this->stream, 0, 0); /* delay finished event for presentation mode. * -1 => wait forever * 0 => do not wait * xx => wait xx/10 seconds */ xine_set_param (this->stream, XINE_PARAM_DELAY_FINISHED_EVENT, -1); return this->status; } static int demux_image_get_stream_length (demux_plugin_t *this_gen) { /* demux_image_t *this = (demux_image_t *) this_gen; */ (void)this_gen; return 0; } static uint32_t demux_image_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_image_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_image_t *this; int buf_type = 0; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint8_t header[IMAGE_HEADER_LEN]; if (_x_demux_read_header(input, header, IMAGE_HEADER_LEN) != IMAGE_HEADER_LEN) { return NULL; } buf_type = _probe (stream->xine, header); if (buf_type) break; return NULL; } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } lprintf ("input accepted.\n"); /* * if we reach this point, the input has been accepted. */ this = calloc(1, sizeof(demux_image_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_image_send_headers; this->demux_plugin.send_chunk = demux_image_send_chunk; this->demux_plugin.seek = demux_image_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_image_get_status; this->demux_plugin.get_stream_length = demux_image_get_stream_length; this->demux_plugin.get_capabilities = demux_image_get_capabilities; this->demux_plugin.get_optional_data = demux_image_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; this->buf_type = buf_type; lprintf("opened\n"); return &this->demux_plugin; } /* * image demuxer class */ static void *init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_image_class = { .open_plugin = open_plugin, .description = N_("image demux plugin"), .identifier = "imagedmx", .mimetypes = NULL, /* NOTE: a leading, trailing, or double space would add the empty extension "" to the list. Avoid that. * FIXME: this frozen at build time. */ .extensions = "" #if defined(HAVE_GDK_PIXBUF) || defined(HAVE_IMAGEMAGICK) "bmp gif jpg jpeg png" #else # if defined(HAVE_LIBJPEG) "jpg jpeg" # endif # if defined(HAVE_LIBJPEG) && defined(HAVE_LIBPNG) " " # endif # if defined(HAVE_LIBPNG) "png" # endif #endif , .dispose = NULL, }; return (void *)&demux_image_class; } /* * exported plugin catalog entry */ static const demuxer_info_t demux_info_image = { .priority = 11, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "image", XINE_VERSION_CODE, &demux_info_image, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_ac3.c0000644000175000017500000003326714647725152015336 0ustar meme/* * Copyright (C) 2001-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * AC3 File Demuxer by Mike Melanson (melanson@pcisys.net) * This demuxer detects raw AC3 data in a file and shovels AC3 data * directly to the AC3 decoder. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_ALLOCA_H #include #endif #ifdef HAVE_MALLOC_H #include #endif #define LOG_MODULE "demux_ac3" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_audio.h" #define DATA_TAG 0x61746164 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int seek_flag; int sample_rate; int frame_size; int running_time; unsigned frame_number; uint32_t buf_type; unsigned start_offset; } demux_ac3_t; static int _frame_size(const uint8_t *buf) { static const uint8_t byterates[19] = { 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 64, 72, 80 }; uint32_t idx, rate; idx = buf[4]; if ((idx & 0x3f) > 37) return -1; rate = (uint32_t)byterates[(idx >> 1) & 0x1f]; if (idx & 0x80) { if (idx & 0x40) { return -1; } else { return rate * 24 * 2; } } else { if (idx & 0x40) { return ((rate * 16 * 48000 / 44100) + (idx & 0x01)) * 2; } else { return rate * 16 * 2; } } return -1; } /* returns 1 if the AC3 file was opened successfully, 0 otherwise */ static int open_ac3_file(demux_ac3_t *this) { buf_element_t *buf = NULL; uint32_t offset = 0; int ret = 0; do { uint32_t bsize = 0; int spdif_mode = 0; uint8_t hb[MAX_PREVIEW_SIZE]; const uint8_t *b; do { if (!INPUT_IS_SEEKABLE (this->input)) break; bsize = this->input->get_blocksize (this->input); if (!bsize) break; if (this->input->seek (this->input, 0, SEEK_SET) != 0) break; buf = this->input->read_block (this->input, this->stream->audio_fifo, bsize); if (!buf) break; if (this->input->seek (this->input, 0, SEEK_SET) != 0) { /* should not happen */ buf->free_buffer (buf); buf = NULL; break; } b = buf->content; bsize = buf->size; } while (0); if (!buf) { int s; s = _x_demux_read_header (this->input, hb, MAX_PREVIEW_SIZE); if (s <= 0) break; bsize = s; b = hb; } lprintf ("peek size: %u\n", (unsigned int)bsize); if (bsize < 16) break; do { /* Check for wav header, as we'll handle AC3 with a wav header shoved * on the front for CD burning. * FIXME: This is risky. Real LPCM may contain anything, even sync words. */ unsigned int audio_type; xine_waveformatex *wave; uint32_t o; /* Check this looks like a cd audio wav */ if (bsize < 20 + sizeof (xine_waveformatex)) break; if (memcmp (b, "RIFF", 4) && memcmp (b + 8, "WAVEfmt ", 8)) break; wave = (xine_waveformatex *)(b + 20); _x_waveformatex_le2me (wave); audio_type = _x_formattag_to_buf_audio (wave->wFormatTag); if ((audio_type != BUF_AUDIO_LPCM_LE) || (wave->nChannels != 2) || (wave->nSamplesPerSec != 44100) || (wave->wBitsPerSample != 16)) break; lprintf ("looks like a cd audio wav file\n"); /* Find the data chunk */ o = _X_LE_32 (b + 16); if (o > bsize - 20 - 8) break; o += 20; do { uint32_t chunk_tag = _X_LE_32 (b + o); uint32_t chunk_size = _X_LE_32 (b + o + 4); o += 8; if (chunk_tag == DATA_TAG) { offset = o; lprintf ("found the start of the data at offset %d\n", offset); break; } if (o >= bsize) break; if (chunk_size > bsize - o) break; o += chunk_size; } while (o <= bsize - 8); } while (0); /* Look for a valid AC3 sync word */ { uint32_t syncword = 0; while (offset < bsize) { if ((syncword & 0xffff) == 0x0b77) { offset -= 2; lprintf ("found AC3 syncword at offset %u\n", (unsigned int)offset); break; } if ((syncword == 0x72f81f4e) && (b[offset] == 0x01)) { spdif_mode = 1; lprintf ("found AC3 SPDIF header at offset %u\n", (unsigned int)offset - 4); offset += 4; break; } syncword = (syncword << 8) | b[offset]; offset++; } } if (offset >= bsize - 2) break; this->start_offset = offset; if (spdif_mode) { this->sample_rate = 44100; this->frame_size = 256 * 6 * 4; this->buf_type = BUF_AUDIO_DNET; ret = 1; break; } this->frame_size = _frame_size(b + offset); if (this->frame_size < 0) break; { const uint16_t srate[4] = { 48000, 44100, 32000, 0 }; this->sample_rate = srate[b[offset + 4] >> 6]; if (this->sample_rate == 0) break; } /* Look for a second sync word */ if ((offset + this->frame_size + 1 >= bsize) || (b[offset + this->frame_size] != 0x0b) || (b[offset + this->frame_size + 1] != 0x77)) { break; } lprintf ("found second AC3 sync word\n"); this->buf_type = BUF_AUDIO_A52; ret = 1; } while (0); if (buf) buf->free_buffer (buf); if (ret) { this->running_time = this->input->get_length (this->input) - offset; this->running_time /= this->frame_size; this->running_time *= (90000 / 1000) * (256 * 6); this->running_time /= this->sample_rate; lprintf ("sample rate: %d\n", this->sample_rate); lprintf ("frame size: %d\n", this->frame_size); lprintf("running time: %d\n", this->running_time); } return ret; } static int demux_ac3_send_chunk (demux_plugin_t *this_gen) { demux_ac3_t *this = (demux_ac3_t *) this_gen; buf_element_t *buf = NULL; off_t current_stream_pos; int64_t audio_pts; uint32_t blocksize; current_stream_pos = this->input->get_current_pos(this->input); if (this->seek_flag) { this->frame_number = current_stream_pos / this->frame_size; } /* * Each frame represents 256*6 new audio samples according to the a52 spec. * Thus, the pts computation should work something like: * * pts = frame # * 256*6 samples 1 sec 90000 pts * ------------- * ----------- * --------- * 1 frame sample rate 1 sec */ audio_pts = this->frame_number; audio_pts *= 90000; audio_pts *= 256 * 6; audio_pts /= this->sample_rate; this->frame_number++; if (this->seek_flag) { _x_demux_control_newpts(this->stream, audio_pts, BUF_FLAG_SEEK); this->seek_flag = 0; } blocksize = this->input->get_blocksize(this->input); if (blocksize) { buf = this->input->read_block(this->input, this->audio_fifo, blocksize); if (!buf) { this->status = DEMUX_FINISHED; return this->status; } } else { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); _x_assert(buf->max_size >= this->frame_size); if (this->buf_type != BUF_AUDIO_A52) { buf->size = this->input->read(this->input, buf->content, this->frame_size); } else { buf->size = this->input->read(this->input, buf->content, 8); if (buf->size == 8) { /* re-sync (rare case, usually after seek) */ while (buf->content[0] != 0x0b || buf->content[1] != 0x77) { memmove(buf->content, buf->content + 1, buf->size); if (this->input->read(this->input, buf->content + buf->size - 1, 1) != 1) { buf->size -= 1; break; } } /* check frame size and read the rest */ if (buf->content[0] == 0x0b && buf->content[1] == 0x77) { int got, frame_size = _frame_size(buf->content); if (frame_size > 0) this->frame_size = frame_size; got = this->input->read(this->input, buf->content + buf->size, this->frame_size - buf->size); if (got > 0) buf->size += got; } } } } if (buf->size <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } buf->type = this->buf_type; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) current_stream_pos * 65535 / this->input->get_length (this->input) ); buf->extra_info->input_time = audio_pts / 90; buf->extra_info->total_time = this->running_time; buf->pts = audio_pts; buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); return this->status; } static void demux_ac3_send_headers(demux_plugin_t *this_gen) { demux_ac3_t *this = (demux_ac3_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->buf_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_ac3_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_ac3_t *this = (demux_ac3_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); (void)start_time; (void)playing; this->seek_flag = 1; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* divide the requested offset integer-wise by the frame alignment and * multiply by the frame alignment to determine the new starting block */ start_pos /= this->frame_size; start_pos *= this->frame_size; /* skip possible file header */ start_pos += this->start_offset; this->input->seek(this->input, start_pos, SEEK_SET); return this->status; } static int demux_ac3_get_status (demux_plugin_t *this_gen) { demux_ac3_t *this = (demux_ac3_t *) this_gen; return this->status; } /* return the approximate length in milliseconds */ static int demux_ac3_get_stream_length (demux_plugin_t *this_gen) { demux_ac3_t *this = (demux_ac3_t *) this_gen; return this->running_time; } static uint32_t demux_ac3_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_ac3_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_ac3_t *this; this = calloc(1, sizeof(demux_ac3_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_ac3_send_headers; this->demux_plugin.send_chunk = demux_ac3_send_chunk; this->demux_plugin.seek = demux_ac3_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_ac3_get_status; this->demux_plugin.get_stream_length = demux_ac3_get_stream_length; this->demux_plugin.get_capabilities = demux_ac3_get_capabilities; this->demux_plugin.get_optional_data = demux_ac3_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_ac3_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_ac3_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_ac3_class = { .open_plugin = open_plugin, .description = N_("Raw AC3 demux plugin"), .identifier = "AC3", .mimetypes = "audio/ac3: ac3: Dolby Digital audio;", .extensions = "ac3", .dispose = NULL, }; return (void *)&demux_ac3_class; } xine-lib-1.2/src/demuxers/demux_flv.c0000644000175000017500000012244714647725152015456 0ustar meme/* * Copyright (C) 2004-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * Flash Video (.flv) File Demuxer * by Mike Melanson (melanson@pcisys.net) and * Claudio Ciccani (klan@users.sf.net) * rewritten by Torsten Jager (t.jager@gmx.de) * * For more information on the FLV file format, visit: * http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf * * TJ. FLV actually is a persistent variant of Realtime Messaging Protocol * (rtmp). Some features, most notably message interleaving and relative * timestamps, have been removed. Official spec imposes further restrictions. * We should nevertheless be prepared for more general stuff left by rtmp * stream recorders. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #define LOG_MODULE "demux_flv" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #include #include "bswap.h" typedef struct { unsigned int pts; off_t offset; } flv_index_entry_t; typedef struct { demux_plugin_t demux_plugin; xine_t *xine; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; unsigned char flags; off_t start; /* in bytes */ off_t size; /* in bytes */ unsigned char got_video_header, got_audio_header, got_info; unsigned int length; /* in ms */ int width; int height; int duration; int videocodec; int samplerate; int samplesize; int audio_channels; int audiocodec; off_t filesize; flv_index_entry_t *index; unsigned int num_indices; unsigned int cur_pts; int64_t last_pts[2]; int send_newpts; int buf_flag_seek; int audiodelay; /* fine tune a/v sync */ uint32_t video_time; unsigned int zero_pts_count; #define TEMPBUFSIZE 4096 uint8_t *tempbuf; } demux_flv_t ; /* an early FLV specification had 24bit bigendian timestamps. This limited clip duration to 4:39:37.215. The backwards compatible solution: hand over 1 byte from stream ID. Hence the weird byte order 2-1-0-3 */ #define gettimestamp(p,o) (((((((uint32_t)p[o+3]<<8)|p[o])<<8)|p[o+1])<<8)|p[o+2]) #if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 3)) || defined(__clang__) #if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) #undef gettimestamp #define gettimestamp(p,o) ({ \ uint32_t tempi; \ __builtin_memcpy (&tempi, (p + o), 4); \ __asm__ __volatile__ ("bswapl\t%0\n\trorl\t$8, %0" : "=r" (tempi) : "0" (tempi) : "cc"); \ tempi; \ }) #endif #endif #define FLV_FLAG_HAS_VIDEO 0x01 #define FLV_FLAG_HAS_AUDIO 0x04 #define FLV_TAG_TYPE_AUDIO 0x08 #define FLV_TAG_TYPE_VIDEO 0x09 #define FLV_TAG_TYPE_NOTIFY 0x12 typedef enum { AF_PCM_BE, /* officially "native endian"?? */ AF_ADPCM, AF_MP3, AF_PCM_LE, /* little endian */ AF_NELLY16, /* Nellymoser 16KHz */ AF_NELLY8, /* Nellymoser 8KHz */ AF_NELLY, /* Nellymoser */ AF_ALAW, /* G.711 A-LAW */ AF_MULAW, /* G.711 MU-LAW */ AF_reserved9, AF_AAC, /* mp4a with global header */ AF_SPEEX, AF_reserved12, AF_reserved13, AF_MP38, /* MP3 8KHz */ AF_DS /* device specific sound */ } af_t; /* audio types that support free samplerate from header */ /* got the message ? ;-) */ #define IS_PCM(id) ((((1<>(id))&1) typedef enum { VF_reserved0, VF_JPEG, VF_FLV1, /* modified Sorenson H.263 */ VF_SCREEN, /* Macromedia screen video v1 */ VF_VP6, /* On2 VP6 */ VF_VP6A, /* On2 VP6 with alphachannel */ VF_SCREEN2, /* v2 */ VF_H264, /* MPEG4 part 10, usually with global sequence parameter set */ VF_H263, VF_MP4, /* MPEG4 part 2, usually with global sequence parameter set */ VF_reserved10, VF_reserved11, VF_HEVC /* H265 */ } vf_t; /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) #define WRAP_THRESHOLD 220000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 static void check_newpts (demux_flv_t *this, int64_t pts, int video) { int64_t diff; lprintf ("check_newpts %"PRId64"\n", pts); if (this->buf_flag_seek) { _x_demux_control_newpts (this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; this->send_newpts = 0; this->last_pts[1 - video] = 0; } else { diff = pts - this->last_pts[video]; if (pts && this->last_pts[video] && abs (diff) > WRAP_THRESHOLD) { lprintf ("diff=%"PRId64"\n", diff); _x_demux_control_newpts (this->stream, pts, 0); this->send_newpts = 0; this->last_pts[1-video] = 0; } } this->last_pts[video] = pts; } #define BE_F64(buf) ({\ union { uint64_t q; double d; } _tmp;\ _tmp.q = _X_BE_64(buf);\ _tmp.d;\ })\ /* Action Message Format data types */ typedef enum { AMF0_NUMBER = 0x00, /* double_be */ AMF0_BOOLEAN = 0x01, /* 1 byte TRUE or FALSE */ AMF0_STRING = 0x02, /* u16_be length, then utf8 string without end byte */ AMF0_OBJECT = 0x03, /* name/type/data triplets, then empty name plus AMF0_OBJECT_END. name stored same way as AMF0_STRING */ AMF0_MOVIECLIP = 0x04, /* reserved */ AMF0_NULL_VALUE = 0x05, /* no data */ AMF0_UNDEFINED = 0x06, /* no data */ AMF0_REFERENCE = 0x07, /* u16be index into previous items table */ AMF0_ECMA_ARRAY = 0x08, /* u32_be number_of_entries, then same as AMF0_OBJECT */ AMF0_OBJECT_END = 0x09, /* end marker of AMF0_OBJECT */ AMF0_STRICT_ARRAY = 0x0a, /* u32_be n, then exactly n type/value pairs */ AMF0_DATE = 0x0b, /* double_be milliseconds since Jan 01, 1970, then s16_be minutes off UTC */ AMF0_LONG_STRING = 0x0c, /* u32_be length, then utf8 string */ AMF0_UNSUPPORTED = 0x0d, /* no data */ AMF0_RECORD_SET = 0x0e, /* reserved */ AMF0_XML_OBJECT = 0x0f, /* physically same as AMF0_LONG_STRING */ AMF0_TYPED_OBJECT = 0x10, /* very complex, should not appear in FLV */ AMF0_AMF3 = 0x11, /* switch to AMF3 from here */ } amf_type_t; #define MAX_AMF_LEVELS 10 #define SPC (space + 2 * (MAX_AMF_LEVELS - level)) #define NEEDBYTES(n) if ((unsigned long int)(end - p) < n) return 0 typedef enum { _K_NONE = 0, _K_duration, _K_width, _K_height, _K_videoframerate, _K_videodatarate, _K_videocodecid, _K_audiosamplerate, _K_audiosamplesize, _K_stereo, _K_audiodatarate, _K_audiocodecid, _K_filesize, _K_audiodelay, _K_onMetaData, _K_times, _K_filepositions, _K_LAST } _k_t; static _k_t key_num (const char *key, uint32_t klen) { switch (klen) { case 5: if (!memcmp (key, "times", 5)) return _K_times; if (!memcmp (key, "width", 5)) return _K_width; break; case 6: if (!memcmp (key, "height", 6)) return _K_height; if (!memcmp (key, "stereo", 6)) return _K_stereo; break; case 8: if (!memcmp (key, "duration", 8)) return _K_duration; if (!memcmp (key, "filesize", 8)) return _K_filesize; break; case 9: if (!memcmp (key, "framerate", 9)) return _K_videoframerate; break; case 10: if (!memcmp (key, "audiodelay", 10)) return _K_audiodelay; if (!memcmp (key, "onMetaData", 10)) return _K_onMetaData; break; case 12: if (!memcmp (key, "audiocodecid", 12)) return _K_audiocodecid; if (!memcmp (key, "videocodecid", 12)) return _K_videocodecid; break; case 13: if (!memcmp (key, "audiodatarate", 13)) return _K_audiodatarate; if (!memcmp (key, "filepositions", 13)) return _K_filepositions; if (!memcmp (key, "videodatarate", 13)) return _K_videodatarate; break; case 14: if (!memcmp (key, "videoframerate", 14)) return _K_videoframerate; break; case 15: if (!memcmp (key, "audiosamplerate", 15)) return _K_audiosamplerate; if (!memcmp (key, "audiosamplesize", 15)) return _K_audiosamplesize; break; default: ; } return _K_NONE; } static int parse_amf (demux_flv_t *this, unsigned char *buf, int size) { unsigned char *p = buf, *end = buf + size, *name, space[2 * MAX_AMF_LEVELS + 3]; int level = 0, i, type, count[MAX_AMF_LEVELS], info = 0; unsigned int u, c; time_t tsecs; struct tm *tstruct; double val; /* init prettyprinter */ memset (space, ' ', 2 * MAX_AMF_LEVELS + 2); space[2 * MAX_AMF_LEVELS + 2] = 0x00; /* top level has nameless vars */ count[0] = 10000; while (1) { _k_t keynum; if (count[level] > 0) { /* next strict array item */ if (--count[level] == 0) { /* one level up */ if (--level < 0) return 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "%s}\n", SPC); continue; } if (p >= end) break; type = *p++; name = NULL; keynum = _K_NONE; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "%s", SPC); } else { /* get current name */ NEEDBYTES (2); u = _X_BE_16 (p); p += 2; NEEDBYTES (u); name = p; p += u; if (u == 0) { /* object end, 1 level up */ if (--level < 0) return 0; if ((p < end) && (*p == AMF0_OBJECT_END)) p++; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "%s}\n", SPC); continue; } NEEDBYTES (1); type = *p; *p++ = 0x00; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "%s%s = ", SPC, name); keynum = key_num ((char *)name, u); } switch (type) { case AMF0_NUMBER: NEEDBYTES (8); val = BE_F64 (p); i = val; if (i == val) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "%d\n", i); else xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "%.03lf\n", val); p += 8; if (info) { switch (keynum) { case _K_duration: this->length = val * (double)1000; break; case _K_width: this->width = i; _x_stream_info_set (this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, i); break; case _K_height: this->height = i; _x_stream_info_set (this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, i); break; case _K_videoframerate: if ((i > 0) && (i < 1000)) { this->duration = (double)90000 / val; _x_stream_info_set (this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration); } break; case _K_videodatarate: _x_stream_info_set (this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, val * (double)1000); break; case _K_videocodecid: this->videocodec = i; break; case _K_audiosamplerate: this->samplerate = i; _x_stream_info_set (this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, i); break; case _K_audiosamplesize: this->samplesize = i; _x_stream_info_set (this->stream, XINE_STREAM_INFO_AUDIO_BITS, i); break; case _K_stereo: this->audio_channels = i ? 2 : 1; _x_stream_info_set (this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, i); break; case _K_audiodatarate: _x_stream_info_set (this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, val * (double)1000); break; case _K_audiocodecid: this->audiocodec = i; break; case _K_filesize: this->filesize = val; break; case _K_audiodelay: this->audiodelay = val * (double)-1000; break; default: ; } } break; case AMF0_BOOLEAN: NEEDBYTES (1); i = !!(*p++); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "%s\n", i ? "yes" : "no"); if (info) { if (keynum == _K_stereo) this->audio_channels = i ? 2 : 1; } break; case AMF0_STRING: NEEDBYTES (2); u = _X_BE_16 (p); p += 2; NEEDBYTES (u); c = p[u]; p[u] = 0x00; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "\"%s\"\n", p); if (!level && !memcmp (p, "onMetaData", 11)) info = this->got_info = 1; if (info) { switch (keynum) { case _K_audiocodecid: if (!memcmp (p, "mp4a", 5)) this->audiocodec = AF_AAC; break; case _K_videocodecid: if (!memcmp (p, "avc1", 5)) this->videocodec = VF_H264; break; case _K_stereo: if (!memcmp (p, "true", 5) || !memcmp (p, "yes", 4)) this->audio_channels = 2; break; default: ; } } p[u] = c; p += u; break; case AMF0_LONG_STRING: case AMF0_XML_OBJECT: NEEDBYTES (4); u = _X_BE_32 (p); p += 4; NEEDBYTES (u); /* avoid printf() overload */ if (u > 4000) p[4000] = 0x00; c = p[u]; p[u] = 0x00; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "%s\n", p); p[u] = c; p += u; break; case AMF0_ECMA_ARRAY: NEEDBYTES (4); u = _X_BE_32 (p); /* this value is unreliable */ p += 4; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "[%d] ", u); /* fall through */ case AMF0_OBJECT: if (++level >= MAX_AMF_LEVELS) return 0; count[level] = -1; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "{\n"); continue; case AMF0_STRICT_ARRAY: NEEDBYTES (4); u = _X_BE_32 (p); p += 4; if ((keynum == _K_times) || (keynum == _K_filepositions)) { NEEDBYTES (u * 9); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "[%d] {..}\n", u); if (!this->index || (this->num_indices != u)) { if (this->index) free (this->index); this->index = calloc (u, sizeof (flv_index_entry_t)); if (!this->index) return 0; this->num_indices = u; } if (keynum == _K_times) { for (i = 0; i < (int)u; i++) { if (*p++ != AMF0_NUMBER) return 0; this->index[i].pts = BE_F64 (p) * (double)1000; p += 8; } } else { /* _K_filepositions */ for (i = 0; i < (int)u; i++) { if (*p++ != AMF0_NUMBER) return 0; this->index[i].offset = BE_F64 (p); p += 8; } } } else { if (++level >= MAX_AMF_LEVELS) return 0; count[level] = u + 1; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "[%d] {\n", u); } break; case AMF0_DATE: NEEDBYTES (10); val = BE_F64 (p) / (double)1000; tsecs = val; p += 8; i = _X_BE_16 (p); p += 2; if (i & 0x8000) i |= ~0x7fff; tsecs += i * 60; tstruct = gmtime (&tsecs); if (tstruct) { char ts[200]; if (strftime (ts, 200, "%x %X", tstruct) > 0) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "%s\n", ts); } break; case AMF0_NULL_VALUE: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "(null)\n"); break; case AMF0_UNDEFINED: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "(undefined)\n"); break; case AMF0_REFERENCE: NEEDBYTES (2); u = _X_BE_16 (p); p += 2; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "(see #%u)\n", u); break; default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "(unhandled type %d)\n", type); return 0; break; } } return level == 0; } #define GETBYTES(n) \ if (remaining_bytes < n) \ continue; \ if (this->input->read (this->input, (char *)buffer + 16, n) != n) \ goto fail; \ remaining_bytes -= n; static int read_flv_packet(demux_flv_t *this, int preview) { fifo_buffer_t *fifo = NULL; buf_element_t *buf = NULL; unsigned int tag_type, mp4header, buf_type = 0; unsigned int buf_flags = BUF_FLAG_FRAME_START; int remaining_bytes = 0; unsigned int pts; /* ms */ int ptsoffs = 0; /* pts ticks */ int64_t buf_pts; off_t size, normpos = 0; this->status = DEMUX_OK; while (1) { /* define this here to prevent compiler caching it across multiple this->input->read ()'s. layout: 0 .. 3 previous tags footer (not needed here) 4 tag type 5 .. 7 payload size 8 .. 11 dts (= pts unless H.264 or MPEG4) 12 .. 14 stream id (usually 0) 15 codec id / frame type / audio params (A/V only) 16 right / bottom crop (VP6(F)) frame subtype (AAC, H264, MPEG4, HEVC) 17 .. 19 ?? (VP6F) pts - dts (H264, MPEG4, HEVC) */ unsigned char buffer[20]; /* skip rest, if any */ if (remaining_bytes) this->input->seek (this->input, remaining_bytes, SEEK_CUR); /* we have a/v tags mostly, optimize for them */ if (this->input->read (this->input, (char *)buffer, 16) != 16) { fail: this->status = DEMUX_FINISHED; return this->status; } remaining_bytes = _X_BE_32 (&buffer[4]) & 0xffffff; /* skip empty tags */ if (--remaining_bytes < 0) continue; tag_type = buffer[4]; pts = gettimestamp (buffer, 8); mp4header = 0; switch (tag_type) { case FLV_TAG_TYPE_AUDIO: if (!pts) this->zero_pts_count++; else if (this->audiodelay > 0) pts += this->audiodelay; this->audiocodec = buffer[15] >> 4; switch (this->audiocodec) { case AF_PCM_BE: buf_type = BUF_AUDIO_LPCM_BE; break; case AF_ADPCM: buf_type = BUF_AUDIO_FLVADPCM; break; case AF_MP3: case AF_MP38: buf_type = BUF_AUDIO_MPEG; break; case AF_PCM_LE: buf_type = BUF_AUDIO_LPCM_LE; break; case AF_ALAW: buf_type = BUF_AUDIO_ALAW; break; case AF_MULAW: buf_type = BUF_AUDIO_MULAW; break; #ifdef BUF_AUDIO_NELLYMOSER case AF_NELLY: case AF_NELLY8: case AF_NELLY16: buf_type = BUF_AUDIO_NELLYMOSER; break; #endif case AF_AAC: buf_type = BUF_AUDIO_AAC; GETBYTES (1); if (!buffer[16]) mp4header = 1; break; case AF_SPEEX: buf_type = BUF_AUDIO_SPEEX; break; default: lprintf(" unsupported audio format (%d)...\n", this->audiocodec); buf_type = BUF_AUDIO_UNKNOWN; break; } fifo = this->audio_fifo; if (!this->got_audio_header) { /* prefer tag header settings, unless we hit some unofficial libavformat extension */ if (!IS_PCM (this->audiocodec) || (buffer[15] & 0x0c) || (this->samplerate < 4000)) { this->samplerate = this->audiocodec == AF_NELLY8 || this->audiocodec == AF_MP38 ? 8000 : this->audiocodec == AF_NELLY16 ? 16000 : 44100 >> (3 - ((buffer[15] >> 2) & 3)); this->audio_channels = (buffer[15] & 1) + 1; } if (!this->audio_channels) this->audio_channels = (buffer[15] & 1) + 1; /* send init info to audio decoder */ buf = fifo->buffer_pool_alloc(fifo); buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->samplerate; buf->decoder_info[2] = (buffer[15] & 2) ? 16 : 8; /* bits per sample */ buf->decoder_info[3] = this->audio_channels; buf->size = 0; /* no extra data */ buf->type = buf_type; fifo->put(fifo, buf); this->got_audio_header = 1; } break; case FLV_TAG_TYPE_VIDEO: if (!pts) this->zero_pts_count++; else if (this->audiodelay < 0) pts -= this->audiodelay; /* check frame type */ switch (buffer[15] >> 4) { case 1: /* Key or seekable frame */ case 4: /* server generated keyframe */ buf_flags |= BUF_FLAG_KEYFRAME; break; case 5: /* This is a rtmp server command. One known use: When doing a rtmp time seek between key frames, server may send: 1. a type 5 frame of one 0x00 byte 2. the nearest keyframe before the seek time 3. the following frames before the seek time, if any 4. a type 5 frame of one 0x01 byte */ continue; default: ; } this->videocodec = buffer[15] & 0x0F; switch (this->videocodec) { case VF_FLV1: buf_type = BUF_VIDEO_FLV1; this->video_time = pts; break; case VF_H263: buf_type = BUF_VIDEO_H263; this->video_time = pts; break; case VF_MP4: buf_type = BUF_VIDEO_MPEG4; goto comm_mpeg4; case VF_HEVC: buf_type = BUF_VIDEO_HEVC; goto comm_mpeg4; case VF_H264: buf_type = BUF_VIDEO_H264; /* AVC extra header */ comm_mpeg4: GETBYTES (4); if (buffer[16] == 2) continue; /* skip sequence footer */ if (!buffer[16]) mp4header = 1; else this->video_time = pts; /* pts really is dts here, buffer[17..19] has (pts - dts) signed big endian. */ ptsoffs = _X_BE_32 (buffer + 16) & 0xffffff; if (ptsoffs & 0x800000) ptsoffs |= ~0xffffff; /* better: +/- 16 frames, but we cannot trust header framerate */ if ((ptsoffs < -1000) || (ptsoffs > 1000)) ptsoffs = 0; break; case VF_VP6: buf_type = BUF_VIDEO_VP6F; GETBYTES (1); this->video_time = pts; break; case VF_VP6A: buf_type = BUF_VIDEO_VP6F; GETBYTES (4); this->video_time = pts; break; case VF_JPEG: buf_type = BUF_VIDEO_JPEG; this->video_time = pts; break; default: lprintf(" unsupported video format (%d)...\n", this->videocodec); buf_type = BUF_VIDEO_UNKNOWN; break; } fifo = this->video_fifo; if (!this->got_video_header) { xine_bmiheader *bih; /* send init info to video decoder; send the bitmapinfo header to the decoder * primarily as a formality since there is no real data inside */ buf = fifo->buffer_pool_alloc(fifo); buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; if (this->duration) { buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = this->duration; } bih = (xine_bmiheader *) buf->content; memset (bih, 0, sizeof(xine_bmiheader)); bih->biSize = sizeof(xine_bmiheader); bih->biWidth = this->width; bih->biHeight = this->height; buf->size = sizeof(xine_bmiheader); buf->type = buf_type; if (buf_type == BUF_VIDEO_VP6F) { *((unsigned char *)buf->content+buf->size) = buffer[16]; bih->biSize++; buf->size++; } fifo->put(fifo, buf); this->got_video_header = 1; } break; case FLV_TAG_TYPE_NOTIFY: if (!this->got_info) { unsigned char *text; this->input->seek (this->input, -1, SEEK_CUR); remaining_bytes++; text = malloc (remaining_bytes + 1); /* 1 more byte for possible string end */ if (!text || this->input->read (this->input, (char *)text, remaining_bytes) != remaining_bytes) { free (text); goto fail; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flv: stream info:\n"); parse_amf (this, text, remaining_bytes); free (text); return (this->status); } /* fall through */ default: lprintf(" skipping packet...\n"); continue; } /* send mpeg4 style headers in both normal and preview mode. This makes sure that they get through before they are needed. And it supports multiple sequences per stream (unless we seek too far). */ if (mp4header) { buf = fifo->buffer_pool_alloc (fifo); buf->type = buf_type; buf->size = 0; buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG; buf->decoder_info[2] = remaining_bytes > buf->max_size ? buf->max_size : remaining_bytes; buf->decoder_info_ptr[2] = buf->mem; if ((this->input->read (this->input, (char *)buf->mem, buf->decoder_info[2])) != buf->decoder_info[2]) { buf->free_buffer (buf); goto fail; } remaining_bytes -= buf->decoder_info[2]; if (remaining_bytes) this->input->seek (this->input, remaining_bytes, SEEK_CUR); remaining_bytes = 0; fifo->put (fifo, buf); break; } /* fkip frame contents in preview mode */ if (preview) { if (remaining_bytes) this->input->seek (this->input, remaining_bytes, SEEK_CUR); return this->status; } /* send frame contents */ buf_pts = (int64_t)pts * 90; check_newpts (this, buf_pts, (tag_type == FLV_TAG_TYPE_VIDEO)); pts += ptsoffs; buf_pts += ptsoffs * 90; size = this->input->get_length (this->input); if (size > 0) { this->size = size; normpos = (int64_t)this->input->get_current_pos (this->input) * 65535 / size; } if (buf_flags & BUF_FLAG_KEYFRAME) { xine_keyframes_entry_t entry; entry.msecs = pts; entry.normpos = normpos; _x_keyframes_add (this->stream, &entry); } while (remaining_bytes) { buf = fifo->buffer_pool_size_alloc (fifo, remaining_bytes); buf->type = buf_type; buf->pts = buf_pts; buf->extra_info->input_time = pts; buf->extra_info->total_time = this->length; if (size > 0) buf->extra_info->input_normpos = normpos; buf->size = remaining_bytes > buf->max_size ? buf->max_size : remaining_bytes; remaining_bytes -= buf->size; if (!remaining_bytes) buf_flags |= BUF_FLAG_FRAME_END; buf->decoder_flags = buf_flags; buf_flags &= ~BUF_FLAG_FRAME_START; if (this->input->read (this->input, (char *)buf->content, buf->size) != buf->size) { buf->free_buffer (buf); goto fail; } fifo->put(fifo, buf); } this->cur_pts = pts; break; } return this->status; } static void seek_flv_file (demux_flv_t *this, off_t seek_pos, int seek_pts) { /* we start where we are */ off_t pos2, size, used, found; uint8_t *buf = this->tempbuf; unsigned int now = 0, fpts = this->cur_pts, try; size = this->input->get_length (this->input); if (size > 0) this->size = size; found = this->input->get_current_pos (this->input) + 4; if (!seek_pos && this->length) pos2 = (uint64_t)size * seek_pts / this->length; else pos2 = (uint64_t)size * seek_pos / 65535; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "demux_flv: seek (%u.%03u, %"PRId64")\n", seek_pts / 1000, seek_pts % 1000, (int64_t)pos2); /* force send newpts */ this->buf_flag_seek = 1; /* neither fileposition nor time given, restart at beginning */ if (seek_pos == 0 && seek_pts == 0) { this->input->seek(this->input, this->start, SEEK_SET); this->cur_pts = 0; this->zero_pts_count = 0; this->video_time = ~0u; return; } /* use file index for time based seek (if we got 1) */ if (seek_pts && this->index) { flv_index_entry_t *x; uint32_t a = 0, b, c = this->num_indices; while (a + 1 < c) { b = (a + c) >> 1; if (this->index[b].pts <= (unsigned int)seek_pts) a = b; else c = b; } x = &this->index[a]; if ((x->offset >= this->start + 4) && (x->offset + 15 < size)) { if (this->input->seek (this->input, x->offset, SEEK_SET) == x->offset) { if (this->input->read (this->input, (char *)buf, 15) == 15) { if (!buf[8] && !buf[9] && !buf[10] && ( ((buf[0] == FLV_TAG_TYPE_VIDEO) && ((buf[11] >> 4) == 1)) || (buf[0] == FLV_TAG_TYPE_AUDIO) )) { uint32_t found_pts = gettimestamp (buf, 4); if (found_pts == 0) found_pts = x->pts; if ((found_pts < x->pts + 1000) && (x->pts < found_pts + 1000)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "demux_flv: seek_index (%u.%03u, %"PRId64")\n", found_pts / 1000, found_pts % 1000, (int64_t)x->offset); this->input->seek (this->input, x->offset - 4, SEEK_SET); this->cur_pts = found_pts; this->video_time = buf[0] == FLV_TAG_TYPE_VIDEO ? found_pts : ~0u; return; } } } } } xprintf (this->xine, XINE_VERBOSITY_LOG, _("demux_flv: Not using broken seek index.\n")); } /* Up to 4 zero pts are OK (2 AAC/AVC sequence headers, 2 av tags). Otherwise, the file is non seekable. Try a size based seek. */ if (this->zero_pts_count > 8) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("demux_flv: This file is non seekable. A/V lag may occur.\n" " Recommend fixing the file with some flvtool.\n")); seek_pts = 0; } /* Step 1: phonebook search. Estimate file position, find next tag header, check time, make better estimation, repeat. */ for (try = 4; try && (!seek_pts || abs ((int)seek_pts - (int)fpts) > 800); try--) { int i; this->input->seek (this->input, pos2, SEEK_SET); used = this->input->read (this->input, (char *)buf + TEMPBUFSIZE - 32, 32); for (i = 256; i; i--) { uint8_t *p1, *p2; memcpy (buf, buf + TEMPBUFSIZE - 32, 32); used = this->input->read (this->input, (char *)buf + 32, TEMPBUFSIZE - 32); if (used <= 0) break; p1 = buf + 4; p2 = buf + used + 4; while (p1 < p2) { if (p1[0] == FLV_TAG_TYPE_AUDIO) { /* prev_size < 2^24; size < 2^20; stream == 0; codec_match; */ if (!p1[-4] && !(p1[1] & 0xf0) && !p1[8] && !p1[9] && !p1[10] && ((p1[11] >> 4) == this->audiocodec)) break; } else if (p1[0] == FLV_TAG_TYPE_VIDEO) { /* prev_size < 2^24; stream == 0; codec_match; */ if (!p1[-4] && !p1[8] && !p1[9] && !p1[10] && ((p1[11] & 0x0f) == this->videocodec)) break; } p1++; } if (p1 < p2) { fpts = gettimestamp (p1, 4); found = pos2 + (p1 - buf); if (seek_pts && fpts) pos2 = (uint64_t)found * seek_pts / fpts; else try = 1; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "demux_flv: seek_quick (%u.%03u, %"PRId64")\n", fpts / 1000, fpts % 1000, (int64_t)found); break; } pos2 += TEMPBUFSIZE - 32; } } /* Step 2: Traverse towards the desired time. */ if (seek_pts) { off_t keypos = 0, pos = found; int i = 0; while (1) { if (pos < this->start + 4) break; this->input->seek (this->input, pos - 4, SEEK_SET); if (this->input->read (this->input, (char *)buf, 16) != 16) break; now = gettimestamp (buf, 8); if ((buf[4] == FLV_TAG_TYPE_VIDEO) && ((buf[15] >> 4) == 1)) { keypos = pos; /* Shortcut xine_keyframes users. */ if (now == (unsigned int)seek_pts) break; } /* Non seekable file ?? */ if (now == 0) break; /* Stop at reversal of direction, dont slow when tags are not sorted by pts properly. */ /* Stop at latest tag at, or at first tag right after seek_pts to make step 3 work. */ if (now > (unsigned int)seek_pts) { found = pos; if (i > 0) break; /* Traverse backwards. */ if ((i = _X_BE_32 (buf)) == 0) break; pos -= i + 4; i = -1; } else { /* If there is video, dont mark this as found, so step 3 dont traverse it again. */ if (!this->videocodec) found = pos; if (i < 0) break; /* Traverse forward. */ pos += (_X_BE_32 (&buf[4]) & 0xffffff) + 15; i = 1; } } /* Stay at closest already found keyframe. */ if (keypos) found = keypos; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "demux_flv: seek_traverse (%u.%03u, %"PRId64")\n", now / 1000, now % 1000, (int64_t)pos); } /* Go back to previous keyframe. */ if (this->videocodec) { off_t pos = found; while (1) { int i; if (pos < this->start + 4) break; this->input->seek (this->input, pos - 4, SEEK_SET); if (this->input->read (this->input, (char *)buf, 16) != 16) break; if ((buf[4] == FLV_TAG_TYPE_VIDEO) && ((buf[15] >> 4) == 1)) { found = pos; now = gettimestamp (buf, 8); this->video_time = now; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "demux_flv: seek_keyframe (%u.%03u, %"PRId64")\n", now / 1000, now % 1000, (int64_t)found); break; } if ((i = _X_BE_32 (buf)) == 0) break; pos -= i + 4; } } /* we are there!! */ if (this->input->seek (this->input, found + 4, SEEK_SET) == found + 4) { if (this->input->read (this->input, (char *)buf, 4) == 4) { this->cur_pts = gettimestamp (buf, 0); this->input->seek (this->input, found - 4, SEEK_SET); } } return; } static int demux_flv_send_chunk(demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; return read_flv_packet(this, 0); } static void demux_flv_send_headers(demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; int i; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; this->buf_flag_seek = 1; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, (this->flags & FLV_FLAG_HAS_VIDEO) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->flags & FLV_FLAG_HAS_AUDIO) ? 1 : 0); /* send start buffers */ _x_demux_control_start(this->stream); /* find first audio/video packets and send headers */ for (i = 0; i < 20; i++) { if (read_flv_packet(this, 1) != DEMUX_OK) break; if (((!(this->flags & FLV_FLAG_HAS_VIDEO)) || this->got_video_header) && ((!(this->flags & FLV_FLAG_HAS_AUDIO)) || this->got_audio_header)) { lprintf(" headers sent...\n"); break; } } } static int demux_flv_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_flv_t *this = (demux_flv_t *) this_gen; this->status = DEMUX_OK; /* if demux thread is not running, do some init stuff */ if (!playing) { this->last_pts[0] = 0; this->last_pts[1] = 0; _x_demux_flush_engine(this->stream); seek_flv_file(this, start_pos, start_time); _x_demux_control_newpts (this->stream, 0, 0); return (this->status); } if (start_pos && !start_time) start_time = (int64_t) this->length * start_pos / 65535; /* always allow initial seek (this, 0, 0, 1) after send_headers (). It usually works at least due to xine input cache. Even if not, no problem there. */ if ((!start_time && !start_pos) || INPUT_IS_SEEKABLE (this->input)) { if (!this->length || (unsigned int)start_time < this->length) { _x_demux_flush_engine(this->stream); seek_flv_file(this, start_pos, start_time); } } return this->status; } static void demux_flv_dispose (demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; if (this->index) free(this->index); free(this); } static int demux_flv_get_status (demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; return this->status; } static int demux_flv_get_stream_length (demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; return this->length; } static uint32_t demux_flv_get_capabilities(demux_plugin_t *this_gen) { demux_flv_t *this = (demux_flv_t *) this_gen; return DEMUX_CAP_AUDIOLANG | (this->video_time != ~0u ? DEMUX_CAP_VIDEO_TIME : 0); } static int demux_flv_get_optional_data (demux_plugin_t *this_gen, void *data, int data_type) { demux_flv_t *this = (demux_flv_t *) this_gen; /* be a bit paranoid */ if (this == NULL || this->stream == NULL) return DEMUX_OPTIONAL_UNSUPPORTED; switch (data_type) { case DEMUX_OPTIONAL_DATA_AUDIOLANG: if (data) { char *str = data; int channel; memcpy (&channel, data, sizeof (channel)); if (channel != 0) { strcpy (str, "none"); } else { strcpy (str, "und"); return DEMUX_OPTIONAL_SUCCESS; } } break; case DEMUX_OPTIONAL_DATA_VIDEO_TIME: if ((this->video_time != ~0u) && data) { memcpy (data, &this->video_time, sizeof (this->video_time)); return DEMUX_OPTIONAL_SUCCESS; } break; default: ; } return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_flv_t *this; unsigned char buffer[9]; off_t start; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: break; default: return NULL; } if (_x_demux_read_header (input, buffer, 9) != 9) return NULL; if ((buffer[0] != 'F') || (buffer[1] != 'L') || (buffer[2] != 'V')) return NULL; if (buffer[3] != 0x01) { xprintf (stream->xine, XINE_VERBOSITY_LOG, _("unsupported FLV version (%d).\n"), (int)buffer[3]); return NULL; } if ((buffer[4] & (FLV_FLAG_HAS_VIDEO | FLV_FLAG_HAS_AUDIO)) == 0) { xprintf (stream->xine, XINE_VERBOSITY_LOG, _("neither video nor audio stream in this file.\n")); return NULL; } this = calloc (1, sizeof (*this) + 32 + TEMPBUFSIZE); if (!this) return NULL; start = _X_BE_32 (buffer + 5); if (input->seek (input, start, SEEK_SET) != start) { input->seek (input, 0, SEEK_SET); free (this); return NULL; } lprintf (" qualified FLV file, repositioned @ offset 0x%" PRIxMAX "\n", (intmax_t)start); this->flags = buffer[4]; this->start = start; this->size = input->get_length (input); this->tempbuf = (uint8_t *)(((uintptr_t)this + sizeof (demux_flv_t) + 31) & ~(uintptr_t)31); this->xine = stream->xine; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_flv_send_headers; this->demux_plugin.send_chunk = demux_flv_send_chunk; this->demux_plugin.seek = demux_flv_seek; this->demux_plugin.dispose = demux_flv_dispose; this->demux_plugin.get_status = demux_flv_get_status; this->demux_plugin.get_stream_length = demux_flv_get_stream_length; this->demux_plugin.get_capabilities = demux_flv_get_capabilities; this->demux_plugin.get_optional_data = demux_flv_get_optional_data; this->demux_plugin.demux_class = class_gen; this->video_time = ~0u; this->status = DEMUX_FINISHED; return &this->demux_plugin; } void *demux_flv_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_flv_class = { .open_plugin = open_plugin, .description = N_("Flash Video file demux plugin"), .identifier = "FLV", .mimetypes = "video/x-flv: flv: Flash video;" "video/flv: flv: Flash video;" "application/x-flash-video: flv: Flash video;", .extensions = "flv", .dispose = NULL, }; return (void *)&demux_flv_class; } xine-lib-1.2/src/demuxers/demux_ts.c0000644000175000017500000032673514647725152015323 0ustar meme /* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Demultiplexer for MPEG2 Transport Streams. * * For the purposes of playing video, we make some assumptions about the * kinds of TS we have to process. The most important simplification is to * assume that the TS contains a single program (SPTS) because this then * allows significant simplifications to be made in processing PATs. * * The next simplification is to assume that the program has a reasonable * number of video, audio and other streams. This allows PMT processing to * be simplified. * * MODIFICATION HISTORY * * Date Author * ---- ------ * * 8-Apr-2009 Petri Hintukainen * - support for 192-byte packets (HDMV/BluRay) * - support for audio inside PES PID 0xfd (HDMV/BluRay) * - demux HDMV/BluRay bitmap subtitles * * 28-Nov-2004 Mike Lampard * - Added support for PMT sections larger than 1 ts packet * * 28-Aug-2004 James Courtier-Dutton * - Improve PAT and PMT handling. Added some FIXME comments. * * 9-Aug-2003 James Courtier-Dutton * - Improve readability of code. Added some FIXME comments. * * 25-Nov-2002 Peter Liljenberg * - Added DVBSUB support * * 07-Nov-2992 Howdy Pierce * - various bugfixes * * 30-May-2002 Mauro Borghi * - dynamic allocation leaks fixes * * 27-May-2002 Giovanni Baronetti and Mauro Borghi * - fill buffers before putting them in fifos * - force PMT reparsing when PMT PID changes * - accept non seekable input plugins -- FIX? * - accept dvb as input plugin * - optimised read operations * - modified resync code * * 16-May-2002 Thibaut Mattern * - fix demux loop * * 07-Jan-2002 Andr Draszik * - added support for single-section PMTs * spanning multiple TS packets * * 10-Sep-2001 James Courtier-Dutton * - re-wrote sync code so that it now does not loose any data * * 27-Aug-2001 Hubert Matthews Reviewed by: n/a * - added in synchronisation code * * 1-Aug-2001 James Courtier-Dutton Reviewed by: n/a * - TS Streams with zero PES length should now work * * 30-Jul-2001 shaheedhaque Reviewed by: n/a * - PATs and PMTs seem to work * * 29-Jul-2001 shaheedhaque Reviewed by: n/a * - Compiles! * * * TODO: do without memcpys, preview buffers */ /** HOW TO IMPLEMENT A DVBSUB DECODER. * * The DVBSUB protocol is specified in ETSI EN 300 743. It can be * downloaded for free (registration required, though) from * www.etsi.org. * * The spu_decoder should handle the packet type BUF_SPU_DVB. * * BUF_SPU_DVBSUB packets without the flag BUF_FLAG_SPECIAL contain * the payload of the PES packets carrying DVBSUB data. Since the * payload can be broken up over several buf_element_t and the DVBSUB * is PES oriented, the decoder_info[2] field (low 16 bits) is used to convey the * packet boundaries to the decoder: * * + For the first buffer of a packet, buf->content points to the * first byte of the PES payload. decoder_info[2] is set to the length of the * payload. The decoder can use this value to determine when a * complete PES packet has been collected. * * + For the following buffers of the PES packet, decoder_info[2] is 0. * * The decoder can either use this information to reconstruct the PES * payload, or ignore it and implement a parser that handles the * irregularites at the start and end of PES packets. * * In any case buf->pts is always set to the PTS of the PES packet. * * * BUF_SPU_DVB with BUF_FLAG_SPECIAL set contains no payload, and is * used to pass control information to the decoder. * * If decoder_info[1] == BUF_SPECIAL_SPU_DVB_DESCRIPTOR then * decoder_info_ptr[2] either points to a spu_dvb_descriptor_t or is NULL. * * If it is 0, the user has disabled the subtitling, or has selected a * channel that is not present in the stream. The decoder should * remove any visible subtitling. * * If it is a pointer, the decoder should reset itself and start * extracting the subtitle service identified by comp_page_id and * aux_page_id in the spu_dvb_descriptor_t, (the composition and * auxilliary page ids, respectively). **/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_ARPA_INET_H #include /* htonl */ #endif #ifdef _WIN32 #include /* htonl */ #endif #define LOG_MODULE "demux_ts" #define LOG_VERBOSE /* #define LOG */ #define LOG_DYNAMIC_PMT #define DUMP_VIDEO_HEADS #ifdef DUMP_VIDEO_HEADS # include #endif #include "group_video.h" #include #include #include #include "bswap.h" /* #define TS_LOG #define TS_PMT_LOG #define TS_PAT_LOG #define TS_READ_STATS // activates read statistics generation #define TS_HEADER_LOG // prints out the Transport packet header. */ /* Packet readers: 1 (original), 2 (fast experimental) */ #define TS_PACKET_READER 2 /* transport stream packet layer */ #define TSP_sync_byte 0xff000000 #define TSP_transport_error 0x00800000 #define TSP_payload_unit_start 0x00400000 #define TSP_transport_priority 0x00200000 #define TSP_pid 0x001fff00 #define TSP_scrambling_control 0x000000c0 #define TSP_adaptation_field_1 0x00000020 #define TSP_adaptation_field_0 0x00000010 #define TSP_continuity_counter 0x0000000f /* * The maximum number of PIDs we are prepared to handle in a single program * is the number that fits in a single-packet PMT. */ #define PKT_SIZE 188 #define BODY_SIZE (188 - 4) /* more PIDS are needed due "auto-detection". 40 spare media entries */ #define MAX_PIDS ((BODY_SIZE - 1 - 13) / 4) + 40 #define MAX_PMTS 126 #define PAT_BUF_SIZE (4 * MAX_PMTS + 20) #define MAX_PROGRAMS MAX_PMTS #define SYNC_BYTE 0x47 #if TS_PACKET_READER == 1 # define MIN_SYNCS 3 # define NPKT_PER_READ 96 // 96*188 = 94*192 # define BUF_SIZE (NPKT_PER_READ * (PKT_SIZE + 4)) #endif #if TS_PACKET_READER == 2 /* smallest common multiple of 188 and 192 is 9024 */ # define BUF_SIZE (2 * 9024) /* Kaffeine feeds us through a named pipe. When recording to disk at the same time, * a large read buffer provokes a lot of waiting and extra video frame drops. */ # define SMALL_BUF_SIZE (1 * 9024) #endif #define CORRUPT_PES_THRESHOLD 10 #define NULL_PID 0x1fff #define INVALID_PID ((unsigned int)(-1)) #define INVALID_PROGRAM ((unsigned int)(-1)) #define INVALID_CC ((unsigned int)(-1)) #define PROG_STREAM_MAP 0xBC #define PRIVATE_STREAM1 0xBD #define PADDING_STREAM 0xBE #define PRIVATE_STREAM2 0xBF #define AUDIO_STREAM_S 0xC0 #define AUDIO_STREAM_E 0xDF #define VIDEO_STREAM_S 0xE0 #define VIDEO_STREAM_E 0xEF #define ECM_STREAM 0xF0 #define EMM_STREAM 0xF1 #define DSM_CC_STREAM 0xF2 #define ISO13522_STREAM 0xF3 #define PROG_STREAM_DIR 0xFF /* descriptors in PMT stream info */ #define DESCRIPTOR_REG_FORMAT 0x05 #define DESCRIPTOR_LANG 0x0a #define DESCRIPTOR_TELETEXT 0x56 #define DESCRIPTOR_DVBSUB 0x59 #define DESCRIPTOR_AC3 0x6a #define DESCRIPTOR_EAC3 0x7a #define DESCRIPTOR_DTS 0x7b #define DESCRIPTOR_AAC 0x7c typedef enum { ISO_11172_VIDEO = 0x01, /* ISO/IEC 11172 Video */ ISO_13818_VIDEO = 0x02, /* ISO/IEC 13818-2 Video */ ISO_11172_AUDIO = 0x03, /* ISO/IEC 11172 Audio */ ISO_13818_AUDIO = 0x04, /* ISO/IEC 13818-3 Audi */ ISO_13818_PRIVATE = 0x05, /* ISO/IEC 13818-1 private sections */ ISO_13818_PES_PRIVATE = 0x06, /* ISO/IEC 13818-1 PES packets containing private data */ ISO_13522_MHEG = 0x07, /* ISO/IEC 13512 MHEG */ ISO_13818_DSMCC = 0x08, /* ISO/IEC 13818-1 Annex A DSM CC */ ISO_13818_TYPE_A = 0x0a, /* ISO/IEC 13818-6 Multiprotocol encapsulation */ ISO_13818_TYPE_B = 0x0b, /* ISO/IEC 13818-6 DSM-CC U-N Messages */ ISO_13818_TYPE_C = 0x0c, /* ISO/IEC 13818-6 Stream Descriptors */ ISO_13818_TYPE_D = 0x0d, /* ISO/IEC 13818-6 Sections (any type, including private data) */ ISO_13818_AUX = 0x0e, /* ISO/IEC 13818-1 auxiliary */ ISO_13818_PART7_AUDIO = 0x0f, /* ISO/IEC 13818-7 Audio with ADTS transport sytax */ ISO_14496_PART2_VIDEO = 0x10, /* ISO/IEC 14496-2 Visual (MPEG-4) */ ISO_14496_PART3_AUDIO = 0x11, /* ISO/IEC 14496-3 Audio with LATM transport syntax */ ISO_14496_PART10_VIDEO = 0x1b, /* ISO/IEC 14496-10 Video (MPEG-4 part 10/AVC, aka H.264) */ STREAM_VIDEO_HEVC = 0x24, STREAM_VIDEO_MPEG = 0x80, STREAM_AUDIO_AC3 = 0x81, STREAM_VIDEO_VC1 = 0xea, /* VC-1 Video */ HDMV_AUDIO_80_PCM = 0x80, /* BluRay PCM */ HDMV_AUDIO_82_DTS = 0x82, /* DTS */ HDMV_AUDIO_83_TRUEHD = 0x83, /* Dolby TrueHD, primary audio */ HDMV_AUDIO_84_EAC3 = 0x84, /* Dolby Digital plus, primary audio */ HDMV_AUDIO_85_DTS_HRA = 0x85, /* DTS-HRA */ HDMV_AUDIO_86_DTS_HD_MA = 0x86, /* DTS-HD Master audio */ HDMV_SPU_BITMAP = 0x90, HDMV_SPU_INTERACTIVE = 0x91, HDMV_SPU_TEXT = 0x92, HDMV_AUDIO_A1_EAC3_SEC = 0xa1, /* Dolby Digital plus, secondary audio */ HDMV_AUDIO_A2_DTSHD_SEC = 0xa2, /* DTS HD, secondary audio */ /* pseudo tags */ STREAM_AUDIO_EAC3 = (DESCRIPTOR_EAC3 << 8), STREAM_AUDIO_DTS = (DESCRIPTOR_DTS << 8), } streamType; #define WRAP_THRESHOLD 360000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 /* bitrate estimation */ #define TBRE_MIN_TIME ( 2 * 90000) #define TBRE_TIME (480 * 90000) #define TBRE_MODE_PROBE 0 #define TBRE_MODE_AUDIO_PTS 1 #define TBRE_MODE_AUDIO_PCR 2 #define TBRE_MODE_PCR 3 #define TBRE_MODE_DONE 4 #undef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) #undef MAX #define MAX(a,b) ((a)>(b)?(a):(b)) /* seek helpers: try to figure out the type of each video frame from its * first ts packet (~150 bytes). the basic idea is: * mpeg-ts shall support broadcasting. unlike streaming, client has no * return channel to request setup info by. instead, pat and pmt repeat * every half second, and video decoder configuration aka sequence head * repeats before each keyframe. * if easy to do, read frame type directly. * also, consider some special cases of related info. * if this seems to work during normal business, use it to find next * keyframe after seek as well. */ typedef enum { FRAMETYPE_UNKNOWN = 0, FRAMETYPE_I, FRAMETYPE_P, FRAMETYPE_B } frametype_t; static frametype_t frametype_h264 (const uint8_t *f, uint32_t len) { static const uint8_t t[16] = { FRAMETYPE_UNKNOWN, FRAMETYPE_I, FRAMETYPE_UNKNOWN, FRAMETYPE_P, FRAMETYPE_UNKNOWN, FRAMETYPE_B, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN }; const uint8_t *e = f + len - 5; while (f <= e) { uint32_t v = _X_BE_32 (f); f += 1; if ((v >> 8) != 1) continue; v &= 0x1f; /* nal unit type */ if (v == 7) /* sequence parameter set */ return FRAMETYPE_I; if ((v == 1) || (v == 5)) /* (non) IDR slice, no use to scan further */ break; f += 4 - 1; if (v != 9) /* access unit delimiter */ continue; v = t[f[0] >> 4]; if (v != FRAMETYPE_UNKNOWN) return v; f += 1; } return FRAMETYPE_UNKNOWN; } static frametype_t frametype_h265 (const uint8_t *f, uint32_t len) { static const uint8_t t[8] = { FRAMETYPE_UNKNOWN, FRAMETYPE_I, FRAMETYPE_P, FRAMETYPE_P, FRAMETYPE_B, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN }; const uint8_t *e = f + len - 5; while (f <= e) { uint32_t v = _X_BE_32 (f); f += 1; if ((v >> 8) != 1) continue; v = (v & 0x7e) >> 1; /* nal unit type */ if (v == 32) /* video parameter set */ return FRAMETYPE_I; if (v == 33) /* sequence parameter set */ return FRAMETYPE_I; if ((v >= 16) && (v <= 23)) /* IRAP slice */ return FRAMETYPE_I; f += 4 - 1; if (v == 39) /* slice extra info prefix */ continue; if (v != 35) /* access unit delimiter */ continue; /* misusing nal unit temporal id as a frame type indicator, * as we only have data from first ts packet. * seems to be better than nothing with some dvb streams. */ v = t[f[0] & 7]; if (v != FRAMETYPE_UNKNOWN) return v; f += 1; } return FRAMETYPE_UNKNOWN; } static frametype_t frametype_mpeg (const uint8_t *f, uint32_t len) { static const uint8_t t[8] = { FRAMETYPE_UNKNOWN, FRAMETYPE_I, FRAMETYPE_P, FRAMETYPE_B, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN, FRAMETYPE_UNKNOWN }; const uint8_t *e = f + len - 4 - 2; while (f <= e) { uint32_t v = _X_BE_32 (f); f += 1; if ((v >> 8) != 1) continue; v &= 0xff; /* nal unit type */ if (v == 0xb3) /* sequence head */ return FRAMETYPE_I; f += 4 - 1; if (v != 0) /* picture start */ continue; return t[(f[1] & 0x38) >> 3]; } return FRAMETYPE_UNKNOWN; } static frametype_t frametype_vc1 (const uint8_t *f, uint32_t len) { const uint8_t *e = f + len - 4 - 1; while (f <= e) { uint32_t v = _X_BE_32 (f); f += 1; if ((v >> 8) != 1) continue; v &= 0xff; /* nal unit type */ if (v == 15) /* sequence head */ return FRAMETYPE_I; if (v == 13) /* frame start */ break; f += 4 - 1; } return FRAMETYPE_UNKNOWN; } /* ** ** DATA STRUCTURES ** */ /* * Describe a single elementary stream. */ typedef struct { unsigned int pid; uint32_t type; int64_t pts; fifo_buffer_t *fifo; buf_element_t *buf; uint32_t audio_type; /* defaults from pmt */ uint32_t video_type; uint32_t spu_type; uint32_t hdmv_type; uint32_t sure_type; unsigned int counter; uint16_t descriptor_tag; /* +0x100 for PES stream IDs (no available TS descriptor tag?) */ uint8_t keep; /* used by demux_ts_dynamic_pmt_*() */ #define PES_FLUSHED 1 #define PES_RESUME 2 uint8_t resume; int corrupted_pes; int pes_bytes_left; /* butes left if PES packet size is known */ int input_normpos; int input_time; } demux_ts_media; /* DVBSUB */ #define MAX_SPU_LANGS 32 typedef struct { spu_dvb_descriptor_t desc; unsigned int pid; unsigned int media_index; } demux_ts_spu_lang; /* Audio Channels */ #define MAX_AUDIO_TRACKS 32 typedef struct { unsigned int pid; unsigned int media_index; char lang[4]; } demux_ts_audio_track; typedef struct { uint32_t program; uint32_t pid; uint32_t length; uint32_t crc; unsigned write_pos; uint8_t buf[4098]; } demux_ts_pmt; typedef struct { /* * The first field must be the "base class" for the plugin! */ demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; unsigned int read_retries; int status; int hdmv; /* -1 = unknown, 0 = mpeg-ts, 1 = hdmv/m2ts */ unsigned int rate; unsigned int media_num; demux_ts_media media[MAX_PIDS]; /* PAT */ unsigned int pat_length; uint32_t pat_crc; unsigned int pat_write_pos; uint32_t transport_stream_id; /* seek helpers */ int64_t last_pat_time; int64_t last_keyframe_time; uint32_t pat_interval; uint32_t keyframe_interval; frametype_t (*get_frametype)(const uint8_t *f, uint32_t len); /* programs */ demux_ts_pmt *pmts[MAX_PMTS]; uint32_t programs[MAX_PMTS + 1]; /* * Stuff to do with the transport header. As well as the video * and audio PIDs, we keep the index of the corresponding entry * inthe media[] array. */ unsigned int pcr_pid; unsigned int videoPid; unsigned int videoMedia; demux_ts_audio_track audio_tracks[MAX_AUDIO_TRACKS]; unsigned int audio_tracks_count; int64_t first_pts, last_pts[2], apts, bpts; int32_t bounce_left; int send_newpts; int buf_flag_seek; unsigned int scrambled_pids[MAX_PIDS]; unsigned int scrambled_npids; #ifdef TS_READ_STATS uint32_t rstat[NPKT_PER_READ + 1]; #endif /* DVBSUB */ unsigned int spu_pid; unsigned int spu_media_index; demux_ts_spu_lang spu_langs[MAX_SPU_LANGS]; unsigned int spu_langs_count; int current_spu_channel; /* dvb */ xine_event_queue_t *event_queue; #if TS_PACKET_READER == 1 int pkt_size; /* TS packet size */ int pkt_offset; /* TS packet offset */ /* For syncronisation */ int32_t packet_number; /* NEW: var to keep track of number of last read packets */ int32_t npkt_read; #endif off_t frame_pos; /* current ts packet position in input stream (bytes from beginning) */ /* bitrate estimation */ off_t tbre_bytes, tbre_lastpos; int64_t tbre_time, tbre_lasttime; unsigned int tbre_mode, tbre_pid; #ifdef DUMP_VIDEO_HEADS FILE *vhdfile; #endif /* statistics */ int enlarge_total, enlarge_ok; uint8_t pat[PAT_BUF_SIZE]; /* 0x00 | media_index (video/audio/subtitle) * 0x80 | pmt_index (pmt) * 0xff (special/unused) */ uint8_t pid_index[0x2000]; #if TS_PACKET_READER == 2 int buf_pos; int buf_size; int buf_max; #endif uint8_t buf[BUF_SIZE]; /* == PKT_SIZE * NPKT_PER_READ */ } demux_ts_t; static void demux_ts_hexdump (demux_ts_t *this, const char *intro, const uint8_t *p, uint32_t len) { static const uint8_t tab_hex[16] = "0123456789abcdef"; uint8_t sb[512 * 3], *q = sb; sb[0] = 0; if (len > 512) len = 512; if (len) { do { *q++ = tab_hex[p[0] >> 4]; *q++ = tab_hex[p[0] & 15]; *q++ = ' '; p++; } while (--len); q[-1] = 0; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "%s %s\n", intro, sb); } static void reset_track_map(fifo_buffer_t *fifo) { buf_element_t *buf = fifo->buffer_pool_alloc (fifo); buf->type = BUF_CONTROL_RESET_TRACK_MAP; buf->decoder_info[1] = -1; fifo->put (fifo, buf); } /* TJ. dynamic PMT support. The idea is: First, reuse unchanged pids and add new ones. Then, comb out those who are no longer referenced. For example, the Kaffeine dvb frontend preserves original pids but only sends the currently user selected ones, plus matching generated pat/pmt */ static int demux_ts_dynamic_pmt_find (demux_ts_t *this, int pid, int type, unsigned int descriptor_tag) { unsigned int i; demux_ts_media *m; /* do we already have this one? */ pid &= 0x1fff; i = this->pid_index[pid]; if (!(i & 0x80)) { m = &this->media[i]; if (((int)m->pid == pid) && ((m->type & BUF_MAJOR_MASK) == (unsigned int)type) && (m->descriptor_tag == descriptor_tag)) { /* mark this media decriptor for reuse */ m->keep = 1; return i; } } i = this->media_num; if (i < MAX_PIDS) { /* prepare new media descriptor */ this->pid_index[pid] = i; m = &this->media[i]; m->pid = pid; m->descriptor_tag = descriptor_tag; m->type = type; m->audio_type = BUF_AUDIO_MPEG; m->video_type = BUF_VIDEO_MPEG; m->spu_type = 0; m->hdmv_type = 0; m->sure_type = 0; m->counter = INVALID_CC; m->corrupted_pes = 1; m->pts = 0; m->keep = 1; m->resume = 0; if (type == BUF_AUDIO_BASE) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: new audio pid %d\n", pid); /* allocate new audio track as well */ if (this->audio_tracks_count >= MAX_AUDIO_TRACKS) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: too many audio PIDs, ignoring pid %d\n", pid); return -1; } m->type |= this->audio_tracks_count; this->audio_tracks[this->audio_tracks_count].pid = pid; this->audio_tracks[this->audio_tracks_count].media_index = i; this->audio_tracks_count++; m->fifo = this->audio_fifo; switch (descriptor_tag) { case ISO_13818_PART7_AUDIO: m->audio_type = BUF_AUDIO_AAC; break; case ISO_14496_PART3_AUDIO: m->audio_type = BUF_AUDIO_AAC_LATM; break; case HDMV_AUDIO_84_EAC3: case STREAM_AUDIO_EAC3: m->hdmv_type = BUF_AUDIO_EAC3; break; case STREAM_AUDIO_AC3: m->hdmv_type = BUF_AUDIO_A52; break; /* ac3 - raw */ case STREAM_AUDIO_DTS: case HDMV_AUDIO_82_DTS: case HDMV_AUDIO_86_DTS_HD_MA: m->hdmv_type = BUF_AUDIO_DTS; break; default: ; } } else if (type == BUF_VIDEO_BASE) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: new video pid %d\n", pid); this->get_frametype = frametype_mpeg; m->fifo = this->video_fifo; switch (descriptor_tag) { case ISO_14496_PART2_VIDEO: m->video_type = BUF_VIDEO_MPEG4; this->get_frametype = NULL; break; case ISO_14496_PART10_VIDEO: m->video_type = BUF_VIDEO_H264; this->get_frametype = frametype_h264; break; case STREAM_VIDEO_VC1: m->sure_type = BUF_VIDEO_VC1; this->get_frametype = frametype_vc1; break; case STREAM_VIDEO_HEVC: m->sure_type = BUF_VIDEO_HEVC; this->get_frametype = frametype_h265; break; default: ; } } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: new subtitle pid %d\n", pid); m->fifo = this->video_fifo; } if (m->buf) { m->buf->free_buffer(m->buf); m->buf = NULL; } this->media_num++; return i; } /* table full */ #ifdef LOG_DYNAMIC_PMT xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: media descriptor table full.\n"); #endif return -1; } static void demux_ts_dynamic_pmt_clean (demux_ts_t *this) { unsigned int i, count = 0, tracks = 0, spus = 0; /* densify media table */ for (i = 0; i < this->media_num; i++) { demux_ts_media *m = &this->media[i]; unsigned int type = m->type & BUF_MAJOR_MASK; unsigned int chan = m->type & 0xff; if (m->keep) { m->keep = 0; if (type == BUF_VIDEO_BASE) { /* adjust single video link */ this->videoMedia = count; } else if (type == BUF_AUDIO_BASE) { /* densify audio track table */ this->audio_tracks[chan].media_index = count; if (chan > tracks) { m->type = (m->type & ~0xff) | tracks; this->audio_tracks[tracks] = this->audio_tracks[chan]; } tracks++; } else if (type == BUF_SPU_BASE) { /* spu language table has already been rebuilt from scratch. Adjust backlinks only */ while ((spus < this->spu_langs_count) && (this->spu_langs[spus].pid == m->pid)) { this->spu_langs[spus].media_index = count; spus++; } if (i == this->spu_media_index) this->spu_media_index = count; } if (i > count) { this->pid_index[m->pid & 0x1fff] = count; this->media[count] = *m; m->buf = NULL; m->pid = INVALID_PID; } count++; } else { /* drop this no longer needed media descriptor */ #ifdef LOG_DYNAMIC_PMT const char *name = ""; if (type == BUF_VIDEO_BASE) name = "video"; else if (type == BUF_AUDIO_BASE) name = "audio"; else if (type == BUF_SPU_BASE) name = "subtitle"; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: dropped %s pid %d\n", name, m->pid); #endif this->pid_index[m->pid & 0x1fff] = 0xff; m->pid = INVALID_PID; if (m->buf) { m->buf->free_buffer (m->buf); m->buf = NULL; } } } if ((tracks < this->audio_tracks_count) && this->audio_fifo) { /* at least 1 audio track removed, tell audio decoder loop */ reset_track_map(this->audio_fifo); #ifdef LOG_DYNAMIC_PMT xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: new audio track map\n"); #endif } #ifdef LOG_DYNAMIC_PMT xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: using %u pids, %u audio %u subtitle channels\n", count, tracks, spus); #endif /* adjust table sizes */ this->media_num = count; this->audio_tracks_count = tracks; /* should really have no effect */ this->spu_langs_count = spus; _x_stream_info_set (this->stream, XINE_STREAM_INFO_HAS_VIDEO, this->videoPid == INVALID_PID ? 0 : 1); _x_stream_info_set (this->stream, XINE_STREAM_INFO_HAS_AUDIO, this->audio_tracks_count > 0 ? 1 : 0); } static void demux_ts_dynamic_pmt_clear (demux_ts_t *this) { unsigned int i; #ifdef LOG_DYNAMIC_PMT if (this->media_num) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: deleting %u media descriptors.\n", this->media_num); #endif for (i = 0; i < this->media_num; i++) { this->pid_index[this->media[i].pid & 0x1fff] = 0xff; if (this->media[i].buf) { this->media[i].buf->free_buffer (this->media[i].buf); this->media[i].buf = NULL; } } this->media_num = 0; this->videoPid = INVALID_PID; this->audio_tracks_count = 0; this->spu_pid = INVALID_PID; this->spu_langs_count = 0; this->pcr_pid = INVALID_PID; for (i = 0; this->programs[i] != INVALID_PROGRAM; i++) if (this->pmts[i]) this->pmts[i]->length = 0; } static void demux_ts_tbre_reset (demux_ts_t *this) { if (this->tbre_time <= TBRE_TIME) { this->tbre_pid = INVALID_PID; this->tbre_mode = TBRE_MODE_PROBE; } } static void demux_ts_tbre_update (demux_ts_t *this, unsigned int mode, int64_t now) { /* select best available timesource on the fly */ if ((mode < this->tbre_mode) || (now <= 0)) return; if (mode == this->tbre_mode) { /* skip discontinuities */ int64_t diff = now - this->tbre_lasttime; if ((diff < 0 ? -diff : diff) < 220000) { /* add this step */ this->tbre_bytes += this->frame_pos - this->tbre_lastpos; this->tbre_time += diff; /* update bitrate */ if (this->tbre_time > TBRE_MIN_TIME) this->rate = this->tbre_bytes * 90000 / this->tbre_time; /* stop analyzing */ if (this->tbre_time > TBRE_TIME) this->tbre_mode = TBRE_MODE_DONE; } } else { /* upgrade timesource */ this->tbre_mode = mode; } /* remember where and when */ this->tbre_lastpos = this->frame_pos; this->tbre_lasttime = now; } /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define ts_abs(x) (((x) < 0) ? -(x) : (x)) /* bounce detection like in metronom. looks like double work but saves * up to 80 discontinuity messages. */ static void newpts_test (demux_ts_t *this, int64_t pts, int video) { #ifdef TS_LOG printf ("demux_ts: newpts_test %lld, send_newpts %d, buf_flag_seek %d\n", pts, this->send_newpts, this->buf_flag_seek); #endif if (!this->first_pts) this->first_pts = pts; /*if (pts)*/ { int64_t diff; do { this->last_pts[video] = pts; if (!this->apts) { diff = 0; this->apts = pts; break; } diff = pts - this->apts; if (ts_abs (diff) <= WRAP_THRESHOLD) { this->apts = pts; break; } if (this->bpts) { diff = pts - this->bpts; if (ts_abs (diff) <= WRAP_THRESHOLD) { this->bpts = pts; break; } } this->bpts = this->apts; this->apts = pts; this->bounce_left = WRAP_THRESHOLD; _x_demux_control_newpts (this->stream, pts, this->buf_flag_seek ? BUF_FLAG_SEEK : 0); this->send_newpts = 0; this->buf_flag_seek = 0; return; } while (0); if (this->bounce_left) { this->bounce_left -= diff; if (this->bounce_left <= 0) { this->bpts = 0; this->bounce_left = 0; } } if (this->send_newpts || this->buf_flag_seek) { _x_demux_control_newpts (this->stream, pts, this->buf_flag_seek ? BUF_FLAG_SEEK : 0); this->send_newpts = 0; this->buf_flag_seek = 0; } } } #if 0 static void check_newpts( demux_ts_t *this, int64_t pts, int video ) { #ifdef TS_LOG printf ("demux_ts: check_newpts %lld, send_newpts %d, buf_flag_seek %d\n", pts, this->send_newpts, this->buf_flag_seek); #endif if (pts) { int64_t diff = pts - this->last_pts[video]; if (this->send_newpts || (this->last_pts[video] && (abs (diff) > WRAP_THRESHOLD))) { if (this->buf_flag_seek) { _x_demux_control_newpts (this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts (this->stream, pts, 0); } this->send_newpts = 0; this->last_pts[1 - video] = 0; } /* don't detect a discontinuity only for video respectively audio. It's also a discontinuity indication when audio and video pts differ to much e. g. when a pts wrap happens. The original code worked well when the wrap happend like this: V7 A7 V8 V9 A9 Dv V0 V1 da A1 V2 V3 A3 V4 Legend: Vn = video packet with timestamp n An = audio packet with timestamp n Dv = discontinuity detected on following video packet Da = discontinuity detected on following audio packet dv = discontinuity detected on following video packet but ignored da = discontinuity detected on following audio packet but ignored But with a certain delay between audio and video packets (e. g. the way DVB-S broadcasts the packets) the code didn't work: V7 V8 A7 V9 Dv V0 _A9_ V1 V2 Da _A1_ V3 V4 A3 Packet A9 caused audio to jump forward and A1 caused it to jump backward with inserting a delay of almoust 26.5 hours! The new code gives the following sequences for the above examples: V7 A7 V8 V9 A9 Dv V0 V1 A1 V2 V3 A3 V4 V7 V8 A7 V9 Dv V0 Da A9 Dv V1 V2 A1 V3 V4 A3 After proving this code it should be cleaned up to use just a single variable "last_pts". */ /* this->last_pts[video] = pts; */ this->last_pts[video] = this->last_pts[1-video] = pts; } } #endif /* Send a BUF_SPU_DVB to let xine know of that channel. */ static void demux_send_special_spu_buf( demux_ts_t *this, uint32_t spu_type, int spu_channel ) { buf_element_t *buf; buf = this->video_fifo->buffer_pool_alloc( this->video_fifo ); buf->type = spu_type|spu_channel; this->video_fifo->put( this->video_fifo, buf ); } static void demux_ts_send_buffer (demux_ts_t *this, demux_ts_media *m, int flags) { if (m->buf) { /* test/tell discontinuity right before sending it. * dont bother this on every ts packet. :-) */ if (m->pts) { uint32_t t = m->type & BUF_MAJOR_MASK; if ((t == BUF_VIDEO_BASE) || (t == BUF_AUDIO_BASE)) newpts_test (this, m->pts, (t == BUF_VIDEO_BASE) ? PTS_VIDEO : PTS_AUDIO); } m->buf->content = m->buf->mem; m->buf->type = m->type; m->buf->decoder_flags |= flags; m->buf->pts = m->pts; m->buf->decoder_info[0] = 1; m->buf->extra_info->input_normpos = m->input_normpos; m->buf->extra_info->input_time = m->input_time; m->fifo->put(m->fifo, m->buf); m->buf = NULL; #ifdef TS_LOG printf ("demux_ts: produced buffer, pts=%lld\n", m->pts); #endif } } static void demux_ts_flush_media (demux_ts_t *this, demux_ts_media *m) { m->resume |= PES_FLUSHED; demux_ts_send_buffer (this, m, BUF_FLAG_FRAME_END); } /* * demux_ts_update_spu_channel * * Normally, we would handle spu like audio - send all we got, with * channel numbers, and let decoder loop do the rest. * However: * 1. We like to reduce video fifo load, and more importantly, * 2. There may be joint packets with multiple spus of same type, * to be selected by decoder. * NOTE: there are 2 reasons for calling this: * a) pmt change, called while both old and new media descriptors are valid. * b) user channel change. * * Send a BUF_SPU_DVB with BUF_SPECIAL_SPU_DVB_DESCRIPTOR to tell * the decoder to reset itself on the new channel. */ static void demux_ts_update_spu_channel(demux_ts_t *this) { unsigned int old_mi = this->spu_media_index; this->current_spu_channel = this->stream->spu_channel; if ((this->current_spu_channel >= 0) && ((unsigned int)this->current_spu_channel < this->spu_langs_count)) { demux_ts_spu_lang *lang = &this->spu_langs[this->current_spu_channel]; this->spu_pid = lang->pid; this->spu_media_index = lang->media_index; /* same media -> skip flushing old buf. */ if (old_mi == lang->media_index) old_mi = 0xffffffff; this->media[lang->media_index].type = this->media[lang->media_index].spu_type | this->current_spu_channel; #ifdef TS_LOG printf ("demux_ts: DVBSUB: selecting lang: %s page %ld %ld\n", lang->desc.lang, lang->desc.comp_page_id, lang->desc.aux_page_id); #endif } else { this->spu_pid = INVALID_PID; this->spu_media_index = 0xffffffff; #ifdef TS_LOG printf ("demux_ts: DVBSUB: deselecting lang\n"); #endif } if (old_mi < this->media_num) { demux_ts_flush_media (this, this->media + old_mi); this->media[old_mi].corrupted_pes = 1; if ((this->media[old_mi].type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_SPU_DVB) { buf_element_t *buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR; buf->decoder_info[2] = 0; buf->decoder_info_ptr[2] = NULL; buf->type = this->media[old_mi].type; this->video_fifo->put (this->video_fifo, buf); } } if (this->spu_media_index < this->media_num) { if ((this->media[this->spu_media_index].type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_SPU_DVB) { buf_element_t *buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR; buf->decoder_info[2] = sizeof (this->spu_langs[0].desc); buf->decoder_info_ptr[2] = buf->content; memcpy (buf->content, &this->spu_langs[this->current_spu_channel].desc, sizeof (this->spu_langs[0].desc)); buf->type = this->media[this->spu_media_index].type; this->video_fifo->put (this->video_fifo, buf); } } } static void post_sequence_end(fifo_buffer_t *fifo, uint32_t video_type) { if (video_type == BUF_VIDEO_H264 || video_type == BUF_VIDEO_MPEG || video_type == BUF_VIDEO_VC1) { buf_element_t *buf = fifo->buffer_pool_try_alloc(fifo); if (buf) { buf->type = video_type; buf->size = 4; buf->decoder_flags = BUF_FLAG_FRAME_END; buf->content[0] = 0x00; buf->content[1] = 0x00; buf->content[2] = 0x01; buf->content[3] = (video_type == BUF_VIDEO_MPEG) ? 0xb7 : 0x0a; fifo->put(fifo, buf); } } } static void demux_ts_flush(demux_ts_t *this) { unsigned int i; for (i = 0; i < this->media_num; ++i) { demux_ts_flush_media (this, &this->media[i]); this->media[i].corrupted_pes = 1; } /* append sequence end code to video stream */ if (this->videoPid != INVALID_PID) post_sequence_end(this->video_fifo, this->media[this->videoMedia].type); } /* * demux_ts_parse_pat * * Parse a program association table (PAT). * The PAT is expected to be exactly one section long. * * We can cope with the stupidity of SPTSs which contain NITs. */ static void demux_ts_parse_pat (demux_ts_t*this, const uint8_t *pkt, unsigned int pusi, unsigned int len) { #ifdef TS_PAT_LOG uint32_t table_id; uint32_t version_number; #endif uint32_t section_syntax_indicator; uint32_t section_length; uint32_t transport_stream_id; uint32_t current_next_indicator; uint32_t section_number; uint32_t last_section_number; uint32_t crc32; uint32_t calc_crc32; const uint8_t *program; unsigned int program_count; unsigned int pid_count; /* reassemble the section */ if (pusi) { unsigned int pointer = (unsigned int)pkt[0] + 1; this->pat_write_pos = 0; /* offset the section by n + 1 bytes. this is sometimes used to let it end at an exact TS packet boundary */ if (len <= pointer) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: demux error! PAT with invalid pointer\n"); return; } len -= pointer; pkt += pointer; } else { if (!this->pat_write_pos) return; } if (len > PAT_BUF_SIZE - this->pat_write_pos) len = PAT_BUF_SIZE - this->pat_write_pos; xine_small_memcpy (this->pat + this->pat_write_pos, pkt, len); this->pat_write_pos +=len; /* lets see if we got the section length already */ pkt = this->pat; if (this->pat_write_pos < 3) return; section_length = ((((uint32_t)pkt[1] << 8) | pkt[2]) & 0x03ff) + 3; /* this should be at least the head plus crc */ if (section_length < 8 + 4) { this->pat_write_pos = 0; return; } /* and it should fit into buf */ if (section_length > PAT_BUF_SIZE) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PAT too large (%u bytes)\n", section_length); this->pat_write_pos = 0; return; } /* lets see if we got the section complete */ if (this->pat_write_pos < section_length) return; /* figure out PAT repeat interval. */ do { int64_t diff, now = this->last_pts[0]; if (!now) { now = this->last_pts[1]; if (!now) break; } if (!this->last_pat_time) { this->last_pat_time = now; break; } diff = now - this->last_pat_time; this->last_pat_time = now; if (diff < 0) break; this->pat_interval = diff <= (int64_t)0xffffffff ? diff : 0xffffffff; } while (0); /* same crc means either same table, or wrong crc - both are reason for skipping. */ crc32 = _X_BE_32 (pkt + section_length - 4); if ((this->pat_length == section_length) && (this->pat_crc == crc32)) return; /* OK now parse it */ this->pat_write_pos = 0; #ifdef TS_PAT_LOG table_id = (unsigned int)pkt[0]; #endif section_syntax_indicator = (pkt[1] >> 7) & 0x01; transport_stream_id = ((uint32_t)pkt[3] << 8) | pkt[4]; #ifdef TS_PAT_LOG version_number = ((uint32_t)pkt[5] >> 1) & 0x1f; #endif current_next_indicator = pkt[5] & 0x01; section_number = pkt[6]; last_section_number = pkt[7]; #ifdef TS_PAT_LOG printf ("demux_ts: PAT table_id: %.2x\n", table_id); printf (" section_syntax: %d\n", section_syntax_indicator); printf (" section_length: %u (%#.3x)\n", section_length, section_length); printf (" transport_stream_id: %#.4x\n", transport_stream_id); printf (" version_number: %d\n", version_number); printf (" c/n indicator: %d\n", current_next_indicator); printf (" section_number: %d\n", section_number); printf (" last_section_number: %d\n", last_section_number); #endif if ((section_syntax_indicator != 1) || !current_next_indicator) return; if ((section_number != 0) || (last_section_number != 0)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: FIXME (unsupported) PAT consists of multiple (%d) sections\n", last_section_number); return; } /* Check CRC. */ calc_crc32 = htonl (xine_crc32_ieee (0xffffffff, pkt, section_length - 4)); if (crc32 != calc_crc32) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: demux error! PAT with invalid CRC32: packet_crc32: %.8x calc_crc32: %.8x\n", crc32,calc_crc32); return; } #ifdef TS_PAT_LOG printf ("demux_ts: PAT CRC32 ok.\n"); #endif if (this->transport_stream_id != transport_stream_id) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PAT transport stream id %u.\n", transport_stream_id); this->transport_stream_id = transport_stream_id; } this->pat_length = section_length; this->pat_crc = crc32; /* Unregister previous pmts. */ for (program_count = 0; program_count < 0x2000; program_count++) { if (this->pid_index[program_count] & 0x80) this->pid_index[program_count] = 0xff; } for (program_count = 0; this->programs[program_count] != INVALID_PROGRAM; program_count++) { if (this->pmts[program_count]) { free (this->pmts[program_count]); this->pmts[program_count] = NULL; } } /* * Process all programs in the program loop. */ program_count = 0; pid_count = 0; for (program = pkt + 8; (program < pkt + section_length - 4) && (program_count < MAX_PMTS); program += 4) { uint32_t v = _X_BE_32 (program); uint32_t program_number = v >> 16; uint32_t pmt_pid = v & 0x1fff; /* * completely skip NIT pids. */ if (program_number == 0x0000) continue; /* register this pmt */ this->programs[program_count] = program_number; if (this->pid_index[pmt_pid] == 0xff) { this->pid_index[pmt_pid] = 0x80 | program_count; pid_count++; } #if 0 /* force PMT reparsing when pmt_pid changes */ if (this->pmts[program_count] && (this->pmts[program_count]->pid != pmt_pid)) { demux_ts_dynamic_pmt_clear (this); } #endif #ifdef TS_PAT_LOG if (this->program_number[program_count] != INVALID_PROGRAM) printf ("demux_ts: PAT acquired count=%d programNumber=0x%04x pmtPid=0x%04x\n", program_count, program_number, pmt_pid); #endif ++program_count; } /* Add "end of table" marker. */ this->programs[program_count] = INVALID_PROGRAM; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found %u programs, %u pmt pids.\n", program_count, pid_count); } static int demux_ts_parse_pes_header (demux_ts_t *this, demux_ts_media *m, const uint8_t *buf, unsigned int packet_len) { const uint8_t *p; uint32_t header_len; int64_t pts; uint32_t stream_id; if (this->stream->xine->verbosity == 4) demux_ts_hexdump (this, "demux_ts: PES header", buf, buf[8] + 9); if (packet_len < 9) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: too short PES packet header (%d bytes)\n", packet_len); return 0; } p = buf; /* we should have a PES packet here */ stream_id = _X_BE_32 (p); if ((stream_id >> 8) != 1) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: pes header error 0x%06x (should be 0x000001) \n", stream_id >> 8); return 0 ; } stream_id &= 0xff; if (stream_id == PRIVATE_STREAM2 && this->hdmv) { header_len = 6; pts = 0; } else if (stream_id == PADDING_STREAM) { return 0; } else { header_len = p[8] + 9; /* sometimes corruption on header_len causes segfault in memcpy below */ if (header_len > packet_len) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: illegal value for PES_header_data_length (0x%x) pid %d type 0x%08x\n", p[8], m->pid, m->type); return 0; } if (p[7] & 0x80) { /* pts avail */ uint32_t v; if (header_len < 14) { return 0; } pts = (uint64_t)(p[9] & 0x0e) << 29; v = _X_BE_32 (p + 10); v = ((v >> 1) & 0x7fff) | ((v >> 2) & 0x3fff8000); pts |= v; } else pts = 0; /* code works but not used in xine if ((p[7] & 0x40) && (header_len >= 19)) { DTS = (p[14] & 0x0E) << 29 ; DTS |= p[15] << 22 ; DTS |= (p[16] & 0xFE) << 14 ; DTS |= p[17] << 7 ; DTS |= (p[18] & 0xFE) >> 1 ; } else DTS = 0; */ } #ifdef TS_LOG printf ("demux_ts: packet stream id: %.2x len: %u (%x)\n", stream_id, packet_len, packet_len); #endif #ifdef DUMP_VIDEO_HEADS if ((m->pid == this->videoPid) && this->vhdfile) { static const uint8_t tab_hex[16] = "0123456789abcdef"; const uint8_t *a = p + header_len; uint8_t sb[1024], *q = sb; int len = packet_len - header_len; memcpy (q, "> ", 2); q += 2; if (len) { do { *q++ = tab_hex[a[0] >> 4]; *q++ = tab_hex[a[0] & 15]; *q++ = ' '; a++; } while (--len); q--; } *q++ = '\n'; fwrite (sb, 1, q - sb, this->vhdfile); } #endif if ((m->pid == this->videoPid) && this->get_frametype) { frametype_t t = this->get_frametype (p + header_len, packet_len - header_len); if (t == FRAMETYPE_I) { if (!this->last_keyframe_time) { this->last_keyframe_time = pts; } else if (pts) { int64_t diff = pts - this->last_keyframe_time; this->keyframe_interval = ((diff < 0) || (diff > (int64_t)0xffffffff)) ? 0xffffffff : diff; this->last_keyframe_time = pts; } } } /* TJ. p[4,5] has the payload size in bytes. This is limited to roughly 64k. * For video frames larger than that, it usually is just 0, and payload extends * to the beginning of the next one. * However, I found an hls live stream that always sets size like this: * (1) [4,5] == 0xffd2, [6] == 0x84; (2) [4,5] == 0xffd2, [6] == 0x80; (3) [4,5] == 0x1288, [6] == 0x80; * I dont know whether [6] & 0x04 is reliable elsewhere. So lets try this HACK: * If [4,5] is > 0xff00, wait for a possible resume, * Accept a resume if it has same pts. */ m->pes_bytes_left = (int)(p[4] << 8 | p[5]) - header_len + 6; lprintf("PES packet payload left: %d bytes\n", m->pes_bytes_left); if (!(m->resume & PES_RESUME)) { if (!(m->resume & PES_FLUSHED)) demux_ts_flush_media (this, m); if (m->pes_bytes_left > 0xff00) m->resume |= PES_RESUME; } else { if ((pts != m->pts) && pts) { m->resume &= ~PES_RESUME; if (!(m->resume & PES_FLUSHED)) demux_ts_flush_media (this, m); } else if (m->pes_bytes_left <= 0xff00) { m->resume &= ~PES_RESUME; } } /* now that finished previous buf is sent, set new pts. */ m->pts = pts; /* allocate the buffer here, as pes_header needs a valid buf for dvbsubs */ if (!m->buf) m->buf = m->fifo->buffer_pool_alloc (m->fifo); p += header_len; packet_len -= header_len; if (m->sure_type) { m->type = m->sure_type; return header_len; } if (stream_id == 0xbd || stream_id == 0xfd /* HDMV */) { int spu_id; lprintf ("audio buf = %02X %02X %02X %02X %02X %02X %02X %02X\n", p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); /* * we check the descriptor tag first because some stations * do not include any of the ac3 header info in their audio tracks * these "raw" streams may begin with a byte that looks like a stream type. * For audio streams, m->type already contains the stream no. */ if (m->hdmv_type) { m->type = (m->type & 0xff) | m->hdmv_type; return header_len; } if (m->descriptor_tag == HDMV_AUDIO_83_TRUEHD) { /* TODO: separate AC3 and TrueHD streams ... */ m->type = (m->type & 0xff) | BUF_AUDIO_A52; return header_len; } else if (packet_len < 2) { return 0; } else if (m->descriptor_tag == HDMV_AUDIO_80_PCM) { if (packet_len < 4) { return 0; } m->type = (m->type & 0xff) | BUF_AUDIO_LPCM_BE; m->buf->decoder_flags |= BUF_FLAG_SPECIAL; m->buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG; m->buf->decoder_info[2] = (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0]; m->pes_bytes_left -= 4; return header_len + 4; } else if (m->descriptor_tag == ISO_13818_PES_PRIVATE && p[0] == 0x20 && p[1] == 0x00) { /* DVBSUB */ m->type = (m->type & 0xff) | BUF_SPU_DVB; m->buf->decoder_info[2] = m->pes_bytes_left; return header_len; } else if (p[0] == 0x0B && p[1] == 0x77) { /* ac3 - syncword */ m->type = (m->type & 0xff) | BUF_AUDIO_A52; return header_len; } else if ((p[0] & 0xE0) == 0x20) { spu_id = (p[0] & 0x1f); m->type = BUF_SPU_DVD + spu_id; m->pes_bytes_left -= 1; return header_len + 1; } else if ((p[0] & 0xF0) == 0x80) { if (packet_len < 4) { return 0; } m->type = (m->type & 0xff) | BUF_AUDIO_A52; m->pes_bytes_left -= 4; return header_len + 4; #if 0 /* commented out: does not set PCM type. Decoder can't handle raw PCM stream without configuration. */ } else if ((p[0]&0xf0) == 0xa0) { unsigned int pcm_offset; for (pcm_offset=0; ++pcm_offset < packet_len-1 ; ){ if (p[pcm_offset] == 0x01 && p[pcm_offset+1] == 0x80 ) { /* START */ pcm_offset += 2; break; } } if (packet_len < pcm_offset) { return 0; } m->type |= BUF_AUDIO_LPCM_BE; m->pes_bytes_left -= pcm_offset; return header_len + pcm_offset; #endif } } else if ((stream_id & 0xf0) == 0xe0) { m->type = m->video_type; return header_len; } else if ((stream_id & 0xe0) == 0xc0) { m->type = (m->type & 0xff) | m->audio_type; return header_len; } else { #ifdef TS_LOG printf ("demux_ts: unknown packet, id: %x\n", stream_id); #endif } return 0 ; } static void update_extra_info(demux_ts_t *this, demux_ts_media *m) { off_t length = this->input->get_length (this->input); int32_t pts_time; /* cache frame position */ if (length > 0) { m->input_normpos = (double)this->frame_pos * 65535.0 / length; } pts_time = (m->pts - this->first_pts) / 90; if (this->rate) do { int32_t rate_time = this->frame_pos * 1000 / this->rate; int32_t d = pts_time - rate_time; d = d < 0 ? -d : d; if (d >= 60000) { /* off by 1 minute or more. try pts wrap compensation. */ pts_time += 95443717; d = pts_time - rate_time; d = d < 0 ? -d : d; if (d >= 60000) { /* no, thats not it. use rate based time. */ pts_time = rate_time; break; } } /* update rate here? */ } while (0); m->input_time = pts_time; } /* * buffer arriving pes data */ static void demux_ts_buffer_pes (demux_ts_t*this, const uint8_t *ts, unsigned int mediaIndex, unsigned int tsp_head, unsigned int len) { demux_ts_media *m = &this->media[mediaIndex]; if (!m->fifo) { #ifdef TS_LOG printf ("fifo unavailable (%d)\n", mediaIndex); #endif return; /* To avoid segfault if video out or audio out plugin not loaded */ } /* By checking the CC here, we avoid the need to check for the no-payload case (i.e. adaptation field only) when it does not get bumped. */ { uint32_t cc = tsp_head & TSP_continuity_counter; if (m->counter != INVALID_CC) { if ((m->counter & 0x0f) != cc) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID %u: unexpected cc %u (expected %u)\n", m->pid, cc, m->counter); } } m->counter = cc; m->counter++; } if (tsp_head & TSP_payload_unit_start) { /* new PES packet */ int pes_header_len; pes_header_len = demux_ts_parse_pes_header (this, m, ts, len); if (pes_header_len <= 0) { if (m->buf) m->buf->free_buffer(m->buf); m->buf = NULL; m->corrupted_pes = 1; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID %u: corrupted pes encountered\n", m->pid); } else { m->corrupted_pes = 0; if (m->pes_bytes_left > 0) m->pes_bytes_left += m->buf->size; /* skip PES header */ ts += pes_header_len; len -= pes_header_len; update_extra_info (this, m); /* rate estimation */ if ((this->tbre_pid == INVALID_PID) && (this->audio_fifo == m->fifo)) this->tbre_pid = m->pid; if (m->pid == this->tbre_pid) demux_ts_tbre_update (this, TBRE_MODE_AUDIO_PTS, m->pts); } } if (!m->corrupted_pes) { int room = m->buf->max_size - m->buf->size; /* append data */ m->resume &= ~PES_FLUSHED; if ((int)len > room) { buf_element_t *new_buf; new_buf = m->fifo->buffer_pool_realloc (m->buf, m->buf->size + len); this->enlarge_total++; if (!new_buf) { this->enlarge_ok++; xine_small_memcpy (m->buf->mem + m->buf->size, ts, len); m->buf->size += len; } else { if (room > 0) xine_small_memcpy (m->buf->mem + m->buf->size, ts, room); m->pes_bytes_left -= m->buf->max_size; m->buf->size = m->buf->max_size; demux_ts_send_buffer (this, m, 0); m->buf = new_buf; /* m->buf->decoder_flags = BUF_FLAG_MERGE; */ xine_small_memcpy (m->buf->mem, ts + room, len - room); m->buf->size = len - room; } } else { xine_small_memcpy (m->buf->mem + m->buf->size, ts, len); m->buf->size += len; } /* flush now? */ do { if ((m->pes_bytes_left > 0) && (m->buf->size >= m->pes_bytes_left)) { /* PES payload complete */ m->pes_bytes_left -= m->buf->size; /* skip rest data - there shouldn't be any */ m->corrupted_pes = 1; if (m->resume & PES_RESUME) return; break; } /* If video data ends to sequence end code, flush buffer. */ /* (there won't be any more data -> no pusi -> last buffer is never flushed) */ if (m->pid == this->videoPid && m->buf->size > 4 && m->buf->mem[m->buf->size-4] == 0) { if (m->type == BUF_VIDEO_MPEG) { if (!memcmp(&m->buf->mem[m->buf->size-4], "\x00\x00\x01\xb7", 4)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID %u: flushing after MPEG end of sequence code\n", m->pid); break; } } else if (m->type == BUF_VIDEO_H264) { if ((!memcmp(&m->buf->mem[m->buf->size-4], "\x00\x00\x01\x0a", 4)) || ((m->buf->size > 5) && !memcmp(&m->buf->mem[m->buf->size-5], "\x00\x00\x01\x0a", 4))) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID %u: flushing after H.264 end of sequence code\n", m->pid); break; } } else if (m->type == BUF_VIDEO_VC1) { if (!memcmp(&m->buf->mem[m->buf->size-4], "\x00\x00\x01\x0a", 4)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID %u: flushing after VC-1 end of sequence code\n", m->pid); break; } } } return; } while (0); demux_ts_flush_media (this, m); m->buf = m->fifo->buffer_pool_alloc (m->fifo); } } /* Find the first ISO 639 language descriptor (tag 10) and * store the 3-char code in dest, nullterminated. If no * code is found, zero out dest. **/ static void demux_ts_get_lang_desc(demux_ts_t *this, char *dest, const uint8_t *data, int length) { const uint8_t *d = data; while (d < (data + length)) { if (d[0] == DESCRIPTOR_LANG && d[1] >= 4) { memcpy(dest, d + 2, 3); dest[3] = 0; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found ISO 639 lang: %s\n", dest); return; } d += 2 + d[1]; } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found no ISO 639 lang\n"); memset(dest, 0, 4); } /* Find the registration code (tag=5) and return it as a uint32_t * This should return "AC-3" or 0x41432d33 for AC3/A52 audio tracks. */ static uint32_t demux_ts_get_reg_desc (demux_ts_t *this, const uint8_t *data, int length) { const uint8_t *d = data, *e = data + length - 5; while (d < e) { if ((d[0] == DESCRIPTOR_REG_FORMAT) && (d[1] >= 4)) { char b[20]; uint32_t r = _X_ME_32 (d + 2); _x_tag32_me2str (b, r); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found registration format identifier [%s].\n", b); return r; } d += 2 + d[1]; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: found no format id.\n"); return 0; } /* * NAME demux_ts_parse_pmt * * Parse a PMT. The PMT is expected to be exactly one section long. * * In other words, the PMT is assumed to describe a reasonable number of * video, audio and other streams (with descriptors). * FIXME: Implement support for multi section PMT. */ static void demux_ts_parse_pmt (demux_ts_t *this, const uint8_t *pkt, unsigned int pusi, unsigned int plen, uint32_t program_count, uint32_t pid) { #ifdef TS_PMT_LOG uint32_t table_id; uint32_t version_number; #endif uint32_t section_syntax_indicator; uint32_t section_length; uint32_t program_number; uint32_t current_next_indicator; uint32_t section_number; uint32_t last_section_number; uint32_t program_info_length; uint32_t crc32; uint32_t calc_crc32; uint32_t coded_length; const uint8_t *stream; unsigned int i; int mi; demux_ts_pmt *pmt; pmt = this->pmts[program_count]; if (!pmt) { /* allocate space for largest possible section */ pmt = malloc (sizeof (demux_ts_pmt)); if (!pmt) return; this->pmts[program_count] = pmt; pmt->program = this->programs[program_count]; pmt->pid = INVALID_PID; pmt->length = 0; pmt->crc = 0; pmt->write_pos = 0; } /* reassemble the section */ if (pusi) { unsigned int pointer = (unsigned int)pkt[0] + 1; pmt->write_pos = 0; /* offset the section by n + 1 bytes. this is sometimes used to let it end at an exact TS packet boundary */ if (plen <= pointer) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: demux error! PMT with invalid pointer\n"); return; } plen -= pointer; pkt += pointer; } else { if (!pmt->write_pos) return; } if (plen > sizeof (pmt->buf) - pmt->write_pos) plen = sizeof (pmt->buf) - pmt->write_pos; xine_small_memcpy (pmt->buf + pmt->write_pos, pkt, plen); pmt->write_pos += plen; /* lets see if we got the section length already */ pkt = pmt->buf; if (pmt->write_pos < 3) return; section_length = ((((uint32_t)pkt[1] << 8) | pkt[2]) & 0xfff) + 3; /* this should be at least the head plus crc */ if (section_length < 8 + 4) { pmt->write_pos = 0; return; } /* lets see if we got the section complete */ if (pmt->write_pos < section_length) return; /* same crc means either same table, or wrong crc - both are reason for skipping. */ crc32 = _X_BE_32 (pkt + section_length - 4); if ((pmt->length == section_length) && (pmt->crc == crc32) && (pmt->pid == pid)) return; /* Check CRC. */ calc_crc32 = htonl (xine_crc32_ieee (0xffffffff, pkt, section_length - 4)); if (crc32 != calc_crc32) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: error! PMT pid %u with invalid CRC32 0x%08x (should be 0x%08x).\n", pid, crc32, calc_crc32); return; } #ifdef TS_PMT_LOG printf ("demux_ts: PMT CRC32 ok.\n"); #endif /* OK now parse it */ pmt->write_pos = 0; #ifdef TS_PMT_LOG table_id = (unsigned int)pkt[0]; #endif section_syntax_indicator = (pkt[1] >> 7) & 0x01; program_number = ((uint32_t)pkt[3] << 8) | pkt[4]; #ifdef TS_PMT_LOG version_number = ((uint32_t)pkt[5] >> 1) & 0x1f; #endif current_next_indicator = pkt[5] & 0x01; section_number = pkt[6]; last_section_number = pkt[7]; #ifdef TS_PMT_LOG printf ("demux_ts: PMT table_id: %.2x\n", table_id); printf (" section_syntax: %d\n", section_syntax_indicator); printf (" section_length: %d (%#.3x)\n", section_length, section_length); printf (" program_number: %#.4x\n", program_number); printf (" version_number: %d\n", version_number); printf (" c/n indicator: %d\n", current_next_indicator); printf (" section_number: %d\n", section_number); printf (" last_section_number: %d\n", last_section_number); #endif if ((section_syntax_indicator != 1) || !current_next_indicator) return; if ((section_number != 0) || (last_section_number != 0)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: FIXME (unsupported) PMT consists of multiple (%d) sections\n", last_section_number); return; } if (program_number != pmt->program) { /* several programs can share the same PMT pid */ #ifdef TS_PMT_LOG printf ("Program Number is %i, looking for %i\n", program_number, pmt->program); printf ("demux_ts: waiting for next PMT on this PID...\n"); #endif return; } pmt->length = section_length; pmt->crc = crc32; pmt->pid = pid; /* dont "parse" the CRC */ section_length -= 4; /* * ES definitions start here...we are going to learn upto one video * PID and one audio PID. */ program_info_length = ((pkt[10] << 8) | pkt[11]) & 0x0fff; /* Program info descriptor is currently just ignored. * printf ("demux_ts: program_info_desc: "); * for (i = 0; i < program_info_length; i++) * printf ("%.2x ", this->pmt[program_count][12+i]); * printf ("\n"); */ stream = pkt + 12 + program_info_length; coded_length = 12 + program_info_length; if (coded_length > section_length) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux error! PMT with inconsistent progInfo length\n"); return; } section_length -= coded_length; /* * Forget the current video, audio and subtitle PIDs; if the PMT has not * changed, we'll pick them up again when we parse this PMT, while if the * PMT has changed (e.g. an IPTV streamer that's just changed its source), * we'll get new PIDs that we should follow. */ this->videoPid = INVALID_PID; this->spu_pid = INVALID_PID; this->spu_langs_count = 0; reset_track_map(this->video_fifo); /* * Extract the elementary streams. */ while (section_length > 0) { uint32_t v = _X_BE_32 (stream + 1); uint32_t pid = (v >> 16) & 0x1fff; uint32_t stream_info_length = v & 0xfff; uint32_t coded_length = 5 + stream_info_length; if (coded_length > section_length) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux error! PMT with inconsistent streamInfo length\n"); return; } /* * Squirrel away the first audio and the first video stream. TBD: there * should really be a way to select the stream of interest. */ switch (stream[0]) { case ISO_11172_VIDEO: case ISO_13818_VIDEO: case ISO_14496_PART2_VIDEO: case ISO_14496_PART10_VIDEO: case STREAM_VIDEO_HEVC: case STREAM_VIDEO_VC1: if (this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) demux_ts_hexdump (this, "demux_ts: pmt video descriptor", stream, coded_length); if (this->videoPid == INVALID_PID) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT video pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif mi = demux_ts_dynamic_pmt_find (this, pid, BUF_VIDEO_BASE, stream[0]); if (mi >= 0) { this->videoMedia = mi; this->videoPid = pid; } } break; case ISO_11172_AUDIO: case ISO_13818_AUDIO: case ISO_13818_PART7_AUDIO: case ISO_14496_PART3_AUDIO: if (this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) demux_ts_hexdump (this, "demux_ts: pmt audio descriptor", stream, coded_length); if (this->audio_tracks_count < MAX_AUDIO_TRACKS) { mi = demux_ts_dynamic_pmt_find (this, pid, BUF_AUDIO_BASE, stream[0]); if (mi >= 0) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif demux_ts_get_lang_desc (this, this->audio_tracks[this->media[mi].type & 0xff].lang, stream + 5, stream_info_length); } } break; case ISO_13818_PRIVATE: #ifdef TS_PMT_LOG printf ("demux_ts: PMT streamtype 13818_PRIVATE, pid: 0x%.4x type %2.2x\n", pid, stream[0]); for (i = 5; i < coded_length; i++) printf ("%.2x ", stream[i]); printf ("\n"); #endif break; case ISO_13818_TYPE_C: /* data carousel */ #ifdef TS_PMT_LOG printf ("demux_ts: PMT streamtype 13818_TYPE_C, pid: 0x%.4x type %2.2x\n", pid, stream[0]); #endif break; case ISO_13818_PES_PRIVATE: { uint32_t format_identifier = demux_ts_get_reg_desc (this, stream + 5, stream_info_length); if (format_identifier == ME_FOURCC ('H','E','V','C')) { mi = demux_ts_dynamic_pmt_find (this, pid, BUF_VIDEO_BASE, STREAM_VIDEO_HEVC); if (mi >= 0) { this->videoMedia = mi; this->videoPid = pid; } break; } } /* FIXME: We may have multiple streams in this pid. * For now, we only handle 1 per base type (a/v/s). */ for (i = 5; i < coded_length; i += stream[i+1] + 2) { if ((stream[i] == DESCRIPTOR_AC3) || (stream[i] == DESCRIPTOR_EAC3) || (stream[i] == DESCRIPTOR_DTS)) { mi = demux_ts_dynamic_pmt_find (this, pid, BUF_AUDIO_BASE, stream[i] == DESCRIPTOR_AC3 ? STREAM_AUDIO_AC3 : stream[i] == DESCRIPTOR_DTS ? STREAM_AUDIO_DTS : STREAM_AUDIO_EAC3); if (mi >= 0) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT AC3 audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif demux_ts_get_lang_desc (this, this->audio_tracks[this->media[mi].type & 0xff].lang, stream + 5, stream_info_length); break; } } /* Teletext */ else if (stream[i] == DESCRIPTOR_TELETEXT) { #ifdef TS_PMT_LOG printf ("demux_ts: PMT Teletext, pid: 0x%.4x type %2.2x\n", pid, stream[0]); for (i = 5; i < coded_length; i++) printf ("%.2x ", stream[i]); printf ("\n"); #endif break; } /* DVBSUB */ else if (stream[i] == DESCRIPTOR_DVBSUB) { int pos; mi = demux_ts_dynamic_pmt_find (this, pid, BUF_SPU_BASE, stream[0]); if (mi < 0) break; /* set this early for demux_ts_update_spu_channel () below. */ this->media[mi].spu_type = BUF_SPU_DVB; for (pos = i + 2; pos + 8 <= (int)i + 2 + stream[i + 1] && this->spu_langs_count < MAX_SPU_LANGS; pos += 8) { int no = this->spu_langs_count; demux_ts_spu_lang *lang = &this->spu_langs[no]; this->spu_langs_count++; memcpy(lang->desc.lang, &stream[pos], 3); lang->desc.lang[3] = 0; lang->desc.comp_page_id = (stream[pos + 4] << 8) | stream[pos + 5]; lang->desc.aux_page_id = (stream[pos + 6] << 8) | stream[pos + 7]; lang->pid = pid; lang->media_index = mi; demux_send_special_spu_buf( this, BUF_SPU_DVB, no ); #ifdef TS_LOG printf("demux_ts: DVBSUB: pid 0x%.4x: %s page %ld %ld type %2.2x\n", pid, lang->desc.lang, lang->desc.comp_page_id, lang->desc.aux_page_id, stream[0]); #endif } } } break; case HDMV_SPU_INTERACTIVE: if (this->hdmv > 0) /* ignore BluRay menu streams */ break; /* fall thru */ case HDMV_SPU_TEXT: case HDMV_SPU_BITMAP: if (this->hdmv > 0) { if ((pid >= 0x1200 && pid < 0x1300) || pid == 0x1800) { /* HDMV Presentation Graphics / SPU */ if (this->spu_langs_count >= MAX_SPU_LANGS) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: too many SPU tracks! ignoring pid %u\n", pid); break; } mi = demux_ts_dynamic_pmt_find (this, pid, BUF_SPU_BASE, stream[0]); if (mi < 0) break; demux_ts_spu_lang *lang = &this->spu_langs[this->spu_langs_count]; strcpy(lang->desc.lang, "und"); lang->pid = pid; lang->media_index = mi; if (stream[0] == HDMV_SPU_TEXT) { /* This is the only stream in the mux */ this->media[mi].type = BUF_SPU_HDMV_TEXT; this->spu_pid = pid; } else { this->media[mi].type = BUF_SPU_HDMV; } demux_send_special_spu_buf( this, this->media[mi].type, this->spu_langs_count ); this->media[mi].spu_type = this->media[mi].type; this->media[mi].type |= this->spu_langs_count; this->media[mi].sure_type = this->media[mi].type; this->spu_langs_count++; #ifdef TS_PMT_LOG printf("demux_ts: HDMV subtitle stream_type: 0x%.2x pid: 0x%.4x\n", stream[0], pid); #endif break; } } /* fall thru */ case HDMV_AUDIO_A1_EAC3_SEC: case HDMV_AUDIO_A2_DTSHD_SEC: if (this->hdmv > 0) { if (pid >= 0x1a00 && pid < 0x1a20) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: Skipping unsupported HDMV secondary audio stream_type: 0x%.2x pid: 0x%.4x\n", stream[0], pid); break; } } /* fall thru */ default: /* This following section handles all the cases where the audio track info is stored in PMT user info with stream id >= 0x80 * We first check that the stream id >= 0x80, because all values below that are invalid if not handled above, * then we check the registration format identifier to see if it holds "AC-3" (0x41432d33) and * if is does, we tag this as an audio stream. * FIXME: This will need expanding if we ever see a DTS or other media format here. */ if ((this->audio_tracks_count < MAX_AUDIO_TRACKS) && (stream[0] >= 0x80) ) { uint32_t format_identifier = demux_ts_get_reg_desc (this, stream + 5, stream_info_length); /* If no format identifier, assume A52 */ if ((format_identifier == ME_FOURCC ('A','C','-','3')) || (format_identifier == 0) || (((format_identifier == ME_FOURCC ('H','D','M','V')) || (this->hdmv > 0)) && (stream[0] == HDMV_AUDIO_80_PCM)) /* BluRay PCM */) { mi = demux_ts_dynamic_pmt_find (this, pid, BUF_AUDIO_BASE, stream[0]); if (mi >= 0) { demux_ts_get_lang_desc (this, this->audio_tracks[this->media[mi].type & 0xff].lang, stream + 5, stream_info_length); #ifdef TS_PMT_LOG printf ("demux_ts: PMT audio pid 0x%.4x type %2.2x\n", pid, stream[0]); #endif break; } } } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PMT unknown stream_type: 0x%.2x pid: %u\n", stream[0], pid); #ifdef TS_PMT_LOG printf ("demux_ts: PMT unknown stream_type: 0x%.2x pid: 0x%.4x\n", stream[0], pid); for (i = 5; i < coded_length; i++) printf ("%.2x ", stream[i]); printf ("\n"); #endif break; } stream += coded_length; section_length -= coded_length; } /* * Get the current PCR PID. */ { uint32_t pid = _X_BE_32 (pmt->buf + 6) & 0x1fff; if (this->pcr_pid != pid) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PCR pid %u.\n", pid); this->pcr_pid = pid; } } if (this->stream->spu_channel >= 0) demux_ts_update_spu_channel (this); demux_ts_dynamic_pmt_clean (this); demux_ts_tbre_reset (this); /* Inform UI of channels changes */ xine_event_t ui_event; ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send( this->stream, &ui_event ); } #if TS_PACKET_READER == 1 static int sync_correct(demux_ts_t*this, uint8_t *buf, int32_t npkt_read) { int p = 0; int n = 0; int i = 0; int sync_ok = 0; int read_length; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: about to resync!\n"); for (p=0; p < npkt_read; p++) { for(n=0; n < this->pkt_size; n++) { sync_ok = 1; for (i=0; i < MIN(MIN_SYNCS, npkt_read - p); i++) { if (buf[this->pkt_offset + n + ((i+p) * this->pkt_size)] != SYNC_BYTE) { sync_ok = 0; break; } } if (sync_ok) break; } if (sync_ok) break; } if (sync_ok) { /* Found sync, fill in */ memmove(&buf[0], &buf[n + p * this->pkt_size], ((this->pkt_size * (npkt_read - p)) - n)); read_length = this->input->read(this->input, &buf[(this->pkt_size * (npkt_read - p)) - n], n + p * this->pkt_size); /* FIXME: when read_length is not as required... we now stop demuxing */ if (read_length != (n + p * this->pkt_size)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts_tsync_correct: sync found, but read failed\n"); return 0; } } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts_tsync_correct: sync not found! Stop demuxing\n"); return 0; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: resync successful!\n"); return 1; } static int sync_detect(demux_ts_t*this, uint8_t *buf, int32_t npkt_read) { int i, sync_ok; sync_ok = 1; if (this->hdmv) { this->pkt_size = PKT_SIZE + 4; this->pkt_offset = 4; for (i=0; i < MIN(MIN_SYNCS, npkt_read - 3); i++) { if (buf[this->pkt_offset + i * this->pkt_size] != SYNC_BYTE) { sync_ok = 0; break; } } if (sync_ok) { if (this->hdmv < 0) { /* fix npkt_read (packet size is 192, not 188) */ this->npkt_read = npkt_read * PKT_SIZE / this->pkt_size; } this->hdmv = 1; return sync_ok; } if (this->hdmv > 0) return sync_correct(this, buf, npkt_read); /* plain ts */ this->hdmv = 0; this->pkt_size = PKT_SIZE; this->pkt_offset = 0; } for (i=0; i < MIN(MIN_SYNCS, npkt_read); i++) { if (buf[i * PKT_SIZE] != SYNC_BYTE) { sync_ok = 0; break; } } if (!sync_ok) return sync_correct(this, buf, npkt_read); return sync_ok; } /* * Main synchronisation routine. */ static unsigned char * demux_synchronise(demux_ts_t* this) { uint8_t *return_pointer = NULL; int32_t read_length; this->frame_pos += this->pkt_size; if ( (this->packet_number) >= this->npkt_read) { /* NEW: handle read returning less packets than NPKT_PER_READ... */ do { this->frame_pos = this->input->get_current_pos (this->input); read_length = this->input->read(this->input, this->buf, this->pkt_size * NPKT_PER_READ); if (read_length < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: read returned %d\n", read_length); if (this->read_retries > 2) this->status = DEMUX_FINISHED; this->read_retries++; return NULL; } this->read_retries = 0; if (read_length % this->pkt_size) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: read returned %d bytes (not a multiple of %d!)\n", read_length, this->pkt_size); this->status = DEMUX_FINISHED; return NULL; } this->npkt_read = read_length / this->pkt_size; #ifdef TS_READ_STATS this->rstat[this->npkt_read]++; #endif /* * what if this->npkt_read < 5 ? --> ok in sync_detect * * NEW: stop demuxing if read returns 0 a few times... (200) */ if (this->npkt_read == 0) { demux_ts_flush(this); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: read 0 packets\n"); this->status = DEMUX_FINISHED; return NULL; } } while (! read_length); this->packet_number = 0; if (!sync_detect(this, &(this->buf)[0], this->npkt_read)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: sync error.\n"); this->status = DEMUX_FINISHED; return NULL; } } return_pointer = &(this->buf)[this->pkt_offset + this->pkt_size * this->packet_number]; this->packet_number++; return return_pointer; } #endif static int64_t demux_ts_adaptation_field_parse (const uint8_t *data, uint32_t adaptation_field_length) { #ifdef TS_LOG uint32_t discontinuity_indicator=0; uint32_t random_access_indicator=0; uint32_t elementary_stream_priority_indicator=0; #endif uint32_t PCR_flag=0; int64_t PCR=-1; #ifdef TS_LOG uint32_t EPCR=0; uint32_t OPCR_flag=0; uint32_t OPCR=0; uint32_t EOPCR=0; uint32_t slicing_point_flag=0; uint32_t transport_private_data_flag=0; uint32_t adaptation_field_extension_flag=0; #endif uint32_t offset = 1; #ifdef TS_LOG discontinuity_indicator = ((data[0] >> 7) & 0x01); random_access_indicator = ((data[0] >> 6) & 0x01); elementary_stream_priority_indicator = ((data[0] >> 5) & 0x01); #endif PCR_flag = ((data[0] >> 4) & 0x01); #ifdef TS_LOG OPCR_flag = ((data[0] >> 3) & 0x01); slicing_point_flag = ((data[0] >> 2) & 0x01); transport_private_data_flag = ((data[0] >> 1) & 0x01); adaptation_field_extension_flag = (data[0] & 0x01); #endif #ifdef TS_LOG printf ("demux_ts: ADAPTATION FIELD length: %d (%x)\n", adaptation_field_length, adaptation_field_length); if(discontinuity_indicator) { printf (" Discontinuity indicator: %d\n", discontinuity_indicator); } if(random_access_indicator) { printf (" Random_access indicator: %d\n", random_access_indicator); } if(elementary_stream_priority_indicator) { printf (" Elementary_stream_priority_indicator: %d\n", elementary_stream_priority_indicator); } #endif if(PCR_flag) { if (adaptation_field_length < offset + 6) return -1; PCR = _X_BE_32 (data + offset); PCR <<= 1; PCR |= data[offset + 4] >> 7; #ifdef TS_LOG EPCR = ((data[offset+4] & 0x1) << 8) | data[offset+5]; printf ("demux_ts: PCR: %lld, EPCR: %u\n", PCR, EPCR); #endif offset+=6; } #ifdef TS_LOG if(OPCR_flag) { if (adaptation_field_length < offset + 6) return PCR; OPCR = _X_BE_32 (data + offset); OPCR <<= 1; OPCR |= data[offset + 4] >> 7; EOPCR = ((data[offset+4] & 0x1) << 8) | data[offset+5]; printf ("demux_ts: OPCR: %u, EOPCR: %u\n", OPCR,EOPCR); offset+=6; } if(slicing_point_flag) { printf ("demux_ts: slicing_point_flag: %d\n", slicing_point_flag); } if(transport_private_data_flag) { printf ("demux_ts: transport_private_data_flag: %d\n", transport_private_data_flag); } if(adaptation_field_extension_flag) { printf ("demux_ts: adaptation_field_extension_flag: %d\n", adaptation_field_extension_flag); } #endif /* TS_LOG */ return PCR; } #if TS_PACKET_READER == 2 static int sync_ts (const uint8_t *buf, int len) { int offs = len - 377; while (offs > 0) { if ((buf[0] == SYNC_BYTE) && (buf[188] == SYNC_BYTE) && (buf[376] == SYNC_BYTE)) return len - 377 - offs; buf++; offs--; } return -1; } static int sync_hdmv (const uint8_t *buf, int len) { int offs = len - 385; while (offs > 0) { if ((buf[0] == SYNC_BYTE) && (buf[192] == SYNC_BYTE) && (buf[384] == SYNC_BYTE)) return len - 385 - offs; buf++; offs--; } return -1; } static const uint8_t *sync_next (demux_ts_t *this) { int reread = 3; int rescan = 8; while (1) { const uint8_t *p = this->buf + this->buf_pos; int left = this->buf_size - this->buf_pos; if (this->hdmv > 0) { /* next packet already there? */ if ((left >= 192) && (p[0] == SYNC_BYTE)) { this->buf_pos += 192; this->frame_pos += 192; return p; } if (left <= 0) { this->buf_pos = 0; this->buf_size = 0; } else { int n; if (p[0] != SYNC_BYTE) { /* skip junk already there */ n = sync_hdmv (p, left); if (n >= 0) { this->frame_pos += 192; this->buf_pos += n + 192; p += n; return p; } /* wrong mode ?? */ if (sync_ts (p, left) >= 0) { this->hdmv = 0; continue; } if (left > 192) left = 192; this->buf_pos = this->buf_size - left; /* return without error, allow engine to stop */ if (--rescan <= 0) return NULL; } this->buf_size = left; /* align */ n = this->buf_pos; if (n > 0) { this->buf_pos = 0; if (left <= n) memcpy (this->buf, this->buf + n, left); else memmove (this->buf, this->buf + n, left); } } } else { /* plain ts */ /* next packet already there? */ if ((left >= 188) && (p[0] == SYNC_BYTE)) { this->buf_pos += 188; this->frame_pos += 188; return p; } if (left <= 0) { this->buf_pos = 0; this->buf_size = 0; } else { int n; if (p[0] != SYNC_BYTE) { /* skip junk already there */ n = sync_ts (p, left); if (n >= 0) { this->frame_pos += 188; this->buf_pos += n + 188; p += n; return p; } /* wrong mode ?? */ if (sync_hdmv (p, left) >= 0) { this->hdmv = 1; continue; } if (left > 188) left = 188; this->buf_pos = this->buf_size - left; /* return without error, allow engine to stop */ if (--rescan <= 0) return NULL; } this->buf_size = left; /* align */ n = this->buf_pos; if (n > 0) { this->buf_pos = 0; if (left <= n) memcpy (this->buf, this->buf + n, left); else memmove (this->buf, this->buf + n, left); } } } /* refill */ this->frame_pos = this->input->get_current_pos (this->input); { errno = 0; int n = this->input->read (this->input, this->buf + this->buf_size, this->buf_max - this->buf_size); if (n <= 0) { if (n < 0 && (errno == EINTR || errno == EAGAIN)) { return NULL; } if (_x_action_pending(this->stream)) { return NULL; } if (--reread <= 0) { demux_ts_flush (this); this->status = DEMUX_FINISHED; return NULL; } } this->buf_size += n; } } } #endif /* transport stream packet layer */ static void demux_ts_parse_packet (demux_ts_t*this) { const uint8_t *originalPkt; uint32_t tsp_head; uint32_t pid; unsigned int data_offset; unsigned int data_len; uint32_t index; /* get next synchronised packet, or NULL */ #if TS_PACKET_READER == 2 originalPkt = sync_next (this); #elif TS_PACKET_READER == 1 originalPkt = demux_synchronise(this); #endif if (originalPkt == NULL) return; tsp_head = _X_BE_32 (originalPkt); pid = (tsp_head & TSP_pid) >> 8; #ifdef TS_HEADER_LOG printf ("demux_ts:ts_header:sync_byte=0x%.2x\n", tsp_head >> 24); printf ("demux_ts:ts_header:transport_error_indicator=%d\n", !!(tsp_head & TSP_transport_error)); printf ("demux_ts:ts_header:payload_unit_start_indicator=%d\n", !!(tsp_head & TSP_payload_unit_start)); printf ("demux_ts:ts_header:transport_priority=%d\n", !!(tsp_head & TSP_transport_priority)); printf ("demux_ts:ts_header:pid=0x%.4x\n", pid); printf ("demux_ts:ts_header:transport_scrambling_control=0x%.1x\n", (tsp_head & TSP_scrambling_control) >> 6); printf ("demux_ts:ts_header:adaptation_field_control=0x%.1x\n", (tsp_head & (TSP_adaptation_field_1 | TSP_adaptation_field_0)) >> 4); printf ("demux_ts:ts_header:continuity_counter=0x%.1x\n", tsp_head & TSP_continuity_counter); #endif /* * Discard packets that are obviously bad. */ if ((tsp_head >> 24) != SYNC_BYTE) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: error! invalid ts sync byte %.2x\n", tsp_head >> 24); return; } if (tsp_head & TSP_transport_error) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: error! transport error\n"); return; } if (tsp_head & TSP_scrambling_control) { unsigned int u; for (u = 0; u < this->scrambled_npids; u++) { if (this->scrambled_pids[u] == pid) return; } if (this->scrambled_npids < MAX_PIDS) { this->scrambled_pids[this->scrambled_npids] = pid; this->scrambled_npids++; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: PID %u is scrambled!\n", pid); } return; } data_offset = 4; if (tsp_head & TSP_adaptation_field_1) { uint32_t adaptation_field_length = originalPkt[4]; if (adaptation_field_length > PKT_SIZE - 5) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: invalid adaptation field length\n"); return; } if (adaptation_field_length > 0) { int64_t pcr = demux_ts_adaptation_field_parse (originalPkt+5, adaptation_field_length); if (pid == this->pcr_pid) demux_ts_tbre_update (this, TBRE_MODE_PCR, pcr); else if (pid == this->tbre_pid) demux_ts_tbre_update (this, TBRE_MODE_AUDIO_PCR, pcr); } /* * Skip adaptation header. */ data_offset += adaptation_field_length + 1; if (data_offset >= PKT_SIZE) { /* no payload or invalid header */ return; } } if (!(tsp_head & TSP_adaptation_field_0)) { return; } data_len = PKT_SIZE - data_offset; index = this->pid_index[pid]; /* Do the demuxing in descending order of packet frequency! */ if (!(index & 0x80)) { do { if (pid == this->videoPid) { #ifdef TS_LOG printf ("demux_ts: Video pid: 0x%.4x\n", pid); #endif break; } if ((this->media[index].type & BUF_MAJOR_MASK) == BUF_AUDIO_BASE) { #ifdef TS_LOG printf ("demux_ts: Audio pid: 0x%.4x\n", pid); #endif break; } if (pid == this->spu_pid) { /* DVBSUB */ #ifdef TS_LOG printf ("demux_ts: SPU pid: 0x%.4x\n", pid); #endif break; } return; } while (0); demux_ts_buffer_pes (this, originalPkt + data_offset, index, tsp_head, data_len); return; } if (index != 0xff) { /* PMT */ index &= 0x7f; #ifdef TS_LOG printf ("demux_ts: PMT prog: 0x%.4x pid: 0x%.4x\n", this->program_number[index], this->pmt_pid[index]); #endif demux_ts_parse_pmt (this, originalPkt + data_offset, tsp_head & TSP_payload_unit_start, data_len, index, pid); return; } if (pid == NULL_PID) { #ifdef TS_LOG printf ("demux_ts: Null Packet\n"); #endif return; } /* PAT */ if (pid == 0) { demux_ts_parse_pat (this, originalPkt + data_offset, tsp_head & TSP_payload_unit_start, data_len); return; } if (pid == 0x1ffb) { /* printf ("demux_ts: PSIP table. Program Guide etc....not supported yet. PID = 0x1ffb\n"); */ return; } } /* 0 (go on), 1 (recheck), 2 (stop) */ static int demux_ts_parse_pat_pmt_packet (demux_ts_t*this) { const uint8_t *originalPkt; uint32_t tsp_head; uint32_t pid; unsigned int data_offset; unsigned int data_len; uint32_t index; /* get next synchronised packet, or NULL */ #if TS_PACKET_READER == 2 originalPkt = sync_next (this); #elif TS_PACKET_READER == 1 originalPkt = demux_synchronise(this); #endif if (originalPkt == NULL) return 2; tsp_head = _X_BE_32 (originalPkt); pid = (tsp_head & TSP_pid) >> 8; /* * Discard packets that are obviously bad. */ if ((tsp_head >> 24) != SYNC_BYTE) return 2; if (tsp_head & TSP_transport_error) return 0; if (tsp_head & TSP_scrambling_control) return 0; data_offset = 4; if (tsp_head & TSP_adaptation_field_1) { uint32_t adaptation_field_length = originalPkt[4]; if (adaptation_field_length > PKT_SIZE - 5) return 0; if (adaptation_field_length > 0) { int64_t pcr = demux_ts_adaptation_field_parse (originalPkt+5, adaptation_field_length); if (pid == this->pcr_pid) demux_ts_tbre_update (this, TBRE_MODE_PCR, pcr); else if (pid == this->tbre_pid) demux_ts_tbre_update (this, TBRE_MODE_AUDIO_PCR, pcr); } /* * Skip adaptation header. */ data_offset += adaptation_field_length + 1; if (data_offset >= PKT_SIZE) { /* no payload or invalid header */ return 0; } } if (!(tsp_head & TSP_adaptation_field_0)) { return 0; } data_len = PKT_SIZE - data_offset; index = this->pid_index[pid]; if (!(index & 0x80)) return 0; if (index != 0xff) { /* PMT */ index &= 0x7f; demux_ts_parse_pmt (this, originalPkt + data_offset, tsp_head & TSP_payload_unit_start, data_len, index, pid); return 1; } /* PAT */ if (pid == 0) { demux_ts_parse_pat (this, originalPkt + data_offset, tsp_head & TSP_payload_unit_start, data_len); return 1; } return 0; } static void demux_ts_scan_pat_pmt (demux_ts_t *this) { unsigned int max; if ((this->videoPid != INVALID_PID) || (this->audio_tracks_count > 0)) return; /* we naed first pat/pmt before outputting anything anyway. * do the scan even if the rewind below fails. */ for (max = (2 << 20) / 188; max; max--) { int r = demux_ts_parse_pat_pmt_packet (this); if (r == 2) break; if (r == 1) { if ((this->videoPid != INVALID_PID) || (this->audio_tracks_count > 0)) break; } } if ((this->videoPid != INVALID_PID) || (this->audio_tracks_count > 0)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": found pat/pmt after %u packets.\n", (2 << 20) / 188 + 1 - max); } if (this->input->seek (this->input, 0, SEEK_SET) == 0) { /* in dvb, pat/pmt repeat every half second regardless of key frames. * rewind did work, lets try to play the very beginning as well :-) */ #if TS_PACKET_READER == 2 this->buf_pos = 0; this->buf_size = 0; #endif } } /* * check for pids change events */ static void demux_ts_event_handler (demux_ts_t *this) { xine_event_t *event = NULL; while ((event = xine_event_next (this->event_queue, event))) { switch (event->type) { case XINE_EVENT_END_OF_CLIP: /* flush all streams */ demux_ts_flush(this); /* fall thru */ case XINE_EVENT_PIDS_CHANGE: demux_ts_dynamic_pmt_clear(this); this->send_newpts = 1; _x_demux_control_start (this->stream); break; } } } /* * send a piece of data down the fifos */ static int demux_ts_send_chunk (demux_plugin_t *this_gen) { demux_ts_t*this = (demux_ts_t*)this_gen; demux_ts_event_handler (this); demux_ts_parse_packet(this); /* DVBSUB: check if channel has changed. Dunno if I should, or * even could, lock the xine object. */ if (this->stream->spu_channel != this->current_spu_channel) { demux_ts_update_spu_channel(this); } return this->status; } static void demux_ts_dispose (demux_plugin_t *this_gen) { int i; demux_ts_t*this = (demux_ts_t*)this_gen; for (i = 0; this->programs[i] != INVALID_PROGRAM; i++) { if (this->pmts[i] != NULL) { free (this->pmts[i]); this->pmts[i] = NULL; } } for (i=0; i < MAX_PIDS; i++) { if (this->media[i].buf != NULL) { this->media[i].buf->free_buffer(this->media[i].buf); this->media[i].buf = NULL; } } xine_event_dispose_queue (this->event_queue); #ifdef DUMP_VIDEO_HEADS if (this->vhdfile) fclose (this->vhdfile); #endif if (this->enlarge_total) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: %d of %d buffer enlarges worked.\n", this->enlarge_ok, this->enlarge_total); free(this_gen); } static int demux_ts_get_status(demux_plugin_t *this_gen) { demux_ts_t*this = (demux_ts_t*)this_gen; return this->status; } static void demux_ts_send_headers (demux_plugin_t *this_gen) { demux_ts_t *this = (demux_ts_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* * send start buffers */ this->videoPid = INVALID_PID; this->pcr_pid = INVALID_PID; this->audio_tracks_count = 0; this->media_num= 0; _x_demux_control_start (this->stream); this->input->seek (this->input, 0, SEEK_SET); this->send_newpts = 1; this->status = DEMUX_OK ; this->scrambled_npids = 0; /* DVBSUB */ this->spu_pid = INVALID_PID; this->spu_langs_count = 0; this->current_spu_channel = -1; _x_stream_info_set (this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set (this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); demux_ts_scan_pat_pmt (this); } static int demux_ts_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_ts_t *this = (demux_ts_t *) this_gen; uint32_t caps; int i; if (playing) { /* Keyframe search below may mean waiting on input for several seconds (hls). * Output layers are in flush mode already, so there is no need to let fifos * run dry naturally. Flush them first here. */ this->buf_flag_seek = 1; _x_demux_flush_engine (this->stream); /* Append sequence end code to video stream. */ /* Keep ffmpeg h.264 video decoder from piling up too many DR1 frames, */ /* and thus freezing video out. */ if (this->videoPid != INVALID_PID) post_sequence_end (this->video_fifo, this->media[this->videoMedia].type); } if (this->stream->master != this->stream) { if (this->media_num == 1 && this->spu_langs_count == 1 && this->media[this->spu_langs[0].media_index].type == BUF_SPU_HDMV_TEXT) { /* this stream is used as subtitle slave stream. Need to seek to 0. */ start_pos = 0; start_time = 0; } } caps = this->input->get_capabilities (this->input); if (caps & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_TIME_SEEKABLE)) { if ((caps & INPUT_CAP_TIME_SEEKABLE) && this->input->seek_time) { if (start_pos > 0) { int32_t duration = 0; if ((this->input->get_optional_data (this->input, &duration, INPUT_OPTIONAL_DATA_DURATION) == INPUT_OPTIONAL_SUCCESS) && (duration > 0)) { start_time = (double)start_pos * duration / 65535; } } this->input->seek_time (this->input, start_time, SEEK_SET); } else { start_pos = (off_t)((double)start_pos / 65535 * this->input->get_length (this->input)); if ((!start_pos) && (start_time)) { if (this->input->seek_time) { this->input->seek_time (this->input, start_time, SEEK_SET); } else { start_pos = (int64_t)start_time * this->rate / 1000; this->input->seek (this->input, start_pos, SEEK_SET); } } else { this->input->seek (this->input, start_pos, SEEK_SET); } } #if TS_PACKET_READER == 2 this->buf_pos = 0; this->buf_size = 0; #endif /* Ideally, we seek to video keyframes. * Unfortunately, they are marked in a codec specific way, * and may even hide behind escape codes. * Limit scan to ~10 seconds / 8Mbyte. */ if ((this->videoPid != INVALID_PID) && this->get_frametype && (this->keyframe_interval < 1000000)) { uint32_t n; uint32_t want_phead = (SYNC_BYTE << 24) | TSP_payload_unit_start | (this->videoPid << 8) | TSP_adaptation_field_0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: seek: keyframes repeat every %u pts, try finding next one.\n", this->keyframe_interval); n = (8 << 20) / 188; while (n--) { const uint8_t *p; uint32_t phead, len = 188; #if TS_PACKET_READER == 2 p = sync_next (this); #elif TS_PACKET_READER == 1 p = demux_synchronise(this); #endif if (!p) break; /* ts packet head */ phead = _X_BE_32 (p); if ((phead & (TSP_sync_byte | TSP_transport_error | TSP_payload_unit_start | TSP_pid | TSP_scrambling_control | TSP_adaptation_field_0)) != want_phead) continue; p += 4; len -= 4; /* optional adaptation field */ if (phead & TSP_adaptation_field_1) { uint32_t al = 1 + p[0]; if (len < al) continue; p += al; len -= al; } /* pes head */ if ((len < 9) || (_X_BE_32 (p) >> 8) != 1) continue; { uint32_t el = 9 + p[8]; if (len < el) continue; p += el; len -= el; } /* frame type */ if (this->get_frametype (p, len) != FRAMETYPE_I) continue; #if TS_PACKET_READER == 2 this->buf_pos -= this->hdmv > 0 ? 192 : 188; #endif /* it works -- dont disable ourselves ;-) */ this->last_keyframe_time = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: seek: found keyframe after %u packets.\n", (8 << 20) / 188 - n); break; } } /* If no keyframe info, lets use a sufficiently frequent PAT as a seek target instead. */ else if ((this->videoPid != INVALID_PID) && (this->pat_interval < 900000)) { uint32_t n; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: seek: PAT repeats every %u pts, try finding next one.\n", this->pat_interval); n = (8 << 20) / 188; while (n--) { const uint8_t *originalPkt; #if TS_PACKET_READER == 2 originalPkt = sync_next (this); #elif TS_PACKET_READER == 1 originalPkt = demux_synchronise(this); #endif if (!originalPkt) break; if ((_X_BE_32 (originalPkt) & (TSP_sync_byte | TSP_transport_error | TSP_payload_unit_start | TSP_pid | TSP_scrambling_control | TSP_adaptation_field_0)) == ((SYNC_BYTE << 24) | TSP_payload_unit_start | TSP_adaptation_field_0)) { #if TS_PACKET_READER == 2 this->buf_pos -= this->hdmv > 0 ? 192 : 188; #endif this->last_pat_time = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ts: seek: found PAT after %u packets.\n", (8 << 20) / 188 - n); break; } } } /* seek is called from outside the demux thread. * DEMUX_FINISHED here may be a leftover from previous run, or the result of a seek * behind last keyframe. but that would trigger an annoying error message, and keep * user stuck until an explicit new seek, stop or open. * instead, defer a possible error to send_chunk () what will trigger a regular * stream end/switch. */ this->status = DEMUX_OK; } this->send_newpts = 1; for (i=0; imedia[i]; if (m->buf != NULL) m->buf->free_buffer(m->buf); m->buf = NULL; m->counter = INVALID_CC; m->corrupted_pes = 1; m->pts = 0; m->resume = 0; } if( !playing ) { this->status = DEMUX_OK; this->buf_flag_seek = 0; } demux_ts_tbre_reset (this); return this->status; } static int demux_ts_get_stream_length (demux_plugin_t *this_gen) { demux_ts_t*this = (demux_ts_t*)this_gen; unsigned int rate = this->rate; if (rate) return (int)((int64_t) this->input->get_length (this->input) * 1000 / rate); return 0; } static uint32_t demux_ts_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_AUDIOLANG | DEMUX_CAP_SPULANG; } static int demux_ts_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { demux_ts_t *this = (demux_ts_t *) this_gen; /* be a bit paranoid */ if (this == NULL || this->stream == NULL) return DEMUX_OPTIONAL_UNSUPPORTED; switch (data_type) { case DEMUX_OPTIONAL_DATA_AUDIOLANG: { char *str = data; int channel = *((int *)data); if ((channel >= 0) && ((unsigned int)channel < this->audio_tracks_count)) { if (this->audio_tracks[channel].lang[0]) { strcpy (str, this->audio_tracks[channel].lang); } else { /* input plugin may know the language */ if (this->input->get_capabilities(this->input) & INPUT_CAP_AUDIOLANG) return DEMUX_OPTIONAL_UNSUPPORTED; sprintf (str, "%3i", channel); } return DEMUX_OPTIONAL_SUCCESS; } else { strcpy (str, "none"); } return DEMUX_OPTIONAL_UNSUPPORTED; } case DEMUX_OPTIONAL_DATA_SPULANG: { char *str = data; int channel = *((int *)data); if ((channel >= 0) && ((unsigned int)channel < this->spu_langs_count)) { if (this->spu_langs[channel].desc.lang[0]) { strcpy (str, this->spu_langs[channel].desc.lang); } else { /* input plugin may know the language */ if (this->input->get_capabilities(this->input) & INPUT_CAP_SPULANG) return DEMUX_OPTIONAL_UNSUPPORTED; sprintf (str, "%3i", channel); } return DEMUX_OPTIONAL_SUCCESS; } else { strcpy (str, "none"); } return DEMUX_OPTIONAL_UNSUPPORTED; } default: return DEMUX_OPTIONAL_UNSUPPORTED; } } static int detect_ts (const uint32_t *buf, size_t len) { uint32_t stats_ts[188 / 4], stats_hdmv[192 / 4]; /* Fold 188 or 192 counter slots over the buffer. * Count bytes that are 0x47. * Consider a slot passed when >= 80% (4/5) of its bytes match. * NOTE: this works with buffer size <= 188 * 127, or 23876. * we just need 2048. */ { uint32_t i, v; v = 128 - len * 4 / (5 * 188); v += v << 8; v += v << 16; for (i = 0; i < 188 / 4; i++) stats_ts[i] = v; v = 128 - len * 4 / (5 * 192); v += v << 8; v += v << 16; for (i = 0; i < 192 / 4; i++) stats_hdmv[i] = v; } { const uint32_t *b = buf, *e = buf + len / 4; int i, j; i = 188 / 4 - 1; j = 192 / 4 - 1; while (b < e) { /* misuse plain int as a vector register. * endian does not matter here. */ uint32_t a = *b++ ^ ~0x47474747; a = ((a & 0x80808080) & ((a & 0x7f7f7f7f) + 0x01010101)) >> 7; stats_ts[i] += a; stats_hdmv[j] += a; if (--i < 0) i = 188 / 4 - 1; if (--j < 0) j = 192 / 4 - 1; } } { uint32_t s, i; /* Now count the _passed_ slots. */ s = 0; for (i = 0; i < 188 / 4; i++) s += (stats_ts[i] >> 7) & 0x01010101; s += s >> 16; s += s >> 8; s &= 0x000000ff; /* 0x47 may appear again in packet head. */ if ((s > 0) && (s < 5)) return 0; s = 0; for (i = 0; i < 192 / 4; i++) s += (stats_hdmv[i] >> 7) & 0x01010101; s += s >> 16; s += s >> 8; s &= 0x000000ff; /* 0x47 may appear again in packet head, and in timestamp field. * FIXME: main read resync code is not really prepared for the latter. */ if ((s > 0) && (s < 7)) return 1; } return -1; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_ts_t *this; int i; int hdmv = -1; int size; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint32_t buf[2048 / 4]; size = _x_demux_read_header (input, (uint8_t *)buf, sizeof (buf)); if (size < PKT_SIZE) return NULL; hdmv = detect_ts (buf, size); if (hdmv < 0) return NULL; } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } /* * if we reach this point, the input has been accepted. */ this = calloc (1, sizeof (*this)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->scrambled_npids = 0; this->audio_tracks_count = 0; this->spu_langs_count = 0; this->pat_length = 0; this->pat_crc = 0; this->last_pat_time = 0; this->last_keyframe_time = 0; this->get_frametype = NULL; this->bounce_left = 0; this->first_pts = 0; this->apts = 0; this->bpts = 0; this->last_pts[0] = 0; this->last_pts[1] = 0; # if TS_PACKET_READER == 2 this->buf_pos = 0; this->buf_size = 0; # endif this->enlarge_total = 0; this->enlarge_ok = 0; #endif # if TS_PACKET_READER == 2 this->buf_max = (input->get_capabilities (input) & INPUT_CAP_SEEKABLE) ? BUF_SIZE : SMALL_BUF_SIZE; # endif this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_ts_send_headers; this->demux_plugin.send_chunk = demux_ts_send_chunk; this->demux_plugin.seek = demux_ts_seek; this->demux_plugin.dispose = demux_ts_dispose; this->demux_plugin.get_status = demux_ts_get_status; this->demux_plugin.get_stream_length = demux_ts_get_stream_length; this->demux_plugin.get_capabilities = demux_ts_get_capabilities; this->demux_plugin.get_optional_data = demux_ts_get_optional_data; this->demux_plugin.demux_class = class_gen; /* * Initialise our specialised data. */ this->transport_stream_id = -1; for (i = 0; i < MAX_PIDS; i++) { this->media[i].pid = INVALID_PID; #ifndef HAVE_ZERO_SAFE_MEM this->media[i].buf = NULL; #endif } #ifndef HAVE_ZERO_SAFE_MEM for (i = 0; i < MAX_PMTS; i++) { this->pmts[i] = NULL; } #endif this->programs[0] = INVALID_PROGRAM; memset (this->pid_index, 0xff, sizeof (this->pid_index)); this->videoPid = INVALID_PID; this->pcr_pid = INVALID_PID; this->rate = 1000000; /* byte/sec */ this->tbre_pid = INVALID_PID; this->pat_interval = 0xffffffff; this->keyframe_interval = 0xffffffff; this->status = DEMUX_FINISHED; /* DVBSUB */ this->spu_pid = INVALID_PID; this->spu_media_index = 0xffffffff; this->current_spu_channel = -1; /* dvb */ this->event_queue = xine_event_new_queue (this->stream); { static const int want_types[] = { XINE_EVENT_END_OF_CLIP, XINE_EVENT_PIDS_CHANGE, XINE_EVENT_QUIT }; xine_event_select (this->event_queue, want_types); } /* HDMV */ this->hdmv = hdmv; #if TS_PACKET_READER == 1 this->pkt_offset = (hdmv > 0) ? 4 : 0; this->pkt_size = PKT_SIZE + this->pkt_offset; #endif #ifdef DUMP_VIDEO_HEADS this->vhdfile = fopen ("video_heads.log", "rb+"); #endif return &this->demux_plugin; } /* * ts demuxer class */ void *demux_ts_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_ts_class = { .open_plugin = open_plugin, .description = N_("MPEG Transport Stream demuxer"), .identifier = "MPEG_TS", .mimetypes = "video/mp2t: m2t: MPEG2 transport stream;", /* accept dvb streams; also handle the special dvbs,dvbt and dvbc * mrl formats: the content is exactly the same but the input plugin * uses a different tuning algorithm [Pragma] */ .extensions = "ts m2t trp m2ts mts dvb:// dvbs:// dvbc:// dvbt://", .dispose = NULL, }; return (void *)&demux_ts_class; } xine-lib-1.2/src/demuxers/demux_4xm.c0000644000175000017500000003752214647725152015376 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * 4X Technologies (.4xm) File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information on the 4xm file format, visit: * http://www.pcisys.net/~melanson/codecs/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_4xm" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" #define FOURCC_TAG LE_FOURCC #define RIFF_TAG FOURCC_TAG('R', 'I', 'F', 'F') #define _4XMV_TAG FOURCC_TAG('4', 'X', 'M', 'V') #define LIST_TAG FOURCC_TAG('L', 'I', 'S', 'T') #define HEAD_TAG FOURCC_TAG('H', 'E', 'A', 'D') #define TRK__TAG FOURCC_TAG('T', 'R', 'K', '_') #define MOVI_TAG FOURCC_TAG('M', 'O', 'V', 'I') #define VTRK_TAG FOURCC_TAG('V', 'T', 'R', 'K') #define STRK_TAG FOURCC_TAG('S', 'T', 'R', 'K') #define std__TAG FOURCC_TAG('s', 't', 'd', '_') #define name_TAG FOURCC_TAG('n', 'a', 'm', 'e') #define vtrk_TAG FOURCC_TAG('v', 't', 'r', 'k') #define strk_TAG FOURCC_TAG('s', 't', 'r', 'k') #define ifrm_TAG FOURCC_TAG('i', 'f', 'r', 'm') #define pfrm_TAG FOURCC_TAG('p', 'f', 'r', 'm') #define cfrm_TAG FOURCC_TAG('c', 'f', 'r', 'm') #define snd__TAG FOURCC_TAG('s', 'n', 'd', '_') #define vtrk_SIZE 0x44 #define strk_SIZE 0x28 typedef struct AudioTrack { unsigned int audio_type; int sample_rate; int bits; int channels; } audio_track_t; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; unsigned int filesize; xine_bmiheader bih; unsigned int track_count; audio_track_t *tracks; int64_t video_pts; int64_t video_pts_inc; int64_t duration_in_ms; } demux_fourxm_t; static float get_le_float(unsigned char *buffer) { float f; unsigned char *float_buffer = (unsigned char *)&f; #ifdef WORDS_BIGENDIAN float_buffer[0] = buffer[3]; float_buffer[1] = buffer[2]; float_buffer[2] = buffer[1]; float_buffer[3] = buffer[0]; #else float_buffer[0] = buffer[0]; float_buffer[1] = buffer[1]; float_buffer[2] = buffer[2]; float_buffer[3] = buffer[3]; #endif return f; } static int probe_fourxm_file(input_plugin_t *input, uint32_t *header_size) { unsigned char preview[24]; /* the file signature will be in the first 12 bytes */ if (_x_demux_read_header(input, preview, 24) != 24) return 0; /* check for the signature tags */ if (!_x_is_fourcc(&preview[0], "RIFF") || !_x_is_fourcc(&preview[8], "4XMV")) return 0; if (!_x_is_fourcc(&preview[12 + 0], "LIST") || !_x_is_fourcc(&preview[12 + 8], "HEAD") ) return 0; *header_size = _X_LE_32(&preview[12 + 4]); if (*header_size < 12) return 0; *header_size -= 4; return 1; } /* Open a 4xm file * This function is called from the _open() function of this demuxer. * It returns 1 if 4xm file was opened successfully. */ static int open_fourxm_file(demux_fourxm_t *fourxm, uint32_t header_size) { uint8_t *const header = malloc(header_size); if (!header || fourxm->input->read(fourxm->input, header, header_size) != header_size) { free(header); return 0; } fourxm->bih.biWidth = 0; fourxm->bih.biHeight = 0; fourxm->track_count = 0; fourxm->tracks = NULL; fourxm->video_pts_inc = 0; /* take the lazy approach and search for any and all vtrk and strk chunks */ int i; for (i = 0; i < (int)header_size - 8; i++) { const uint32_t fourcc_tag = _X_LE_32(&header[i]); const uint32_t size = _X_LE_32(&header[i + 4]); if (fourcc_tag == std__TAG) { const float fps = get_le_float(&header[i + 12]); fourxm->video_pts_inc = (int64_t)(90000.0 / fps); } else if (fourcc_tag == vtrk_TAG) { /* check that there is enough data */ if (size != vtrk_SIZE) { free(header); return 0; } const uint32_t total_frames = _X_LE_32(&header[i + 24]); fourxm->duration_in_ms = total_frames; fourxm->duration_in_ms *= fourxm->video_pts_inc; fourxm->duration_in_ms /= 90000; fourxm->duration_in_ms *= 1000; fourxm->bih.biWidth = _X_LE_32(&header[i + 36]); fourxm->bih.biHeight = _X_LE_32(&header[i + 40]); i += 8 + size; } else if (fourcc_tag == strk_TAG) { /* check that there is enough data */ if (size != strk_SIZE) { free(header); return 0; } const uint32_t current_track = _X_LE_32(&header[i + 8]); if (current_track >= fourxm->track_count) { fourxm->track_count = current_track + 1; if (!fourxm->track_count || fourxm->track_count >= UINT_MAX / sizeof(audio_track_t)) { free(header); return 0; } void *tmp = realloc(fourxm->tracks, fourxm->track_count * sizeof(audio_track_t)); if (!tmp) { free(header); return 0; } fourxm->tracks = tmp; } fourxm->tracks[current_track].channels = _X_LE_32(&header[i + 36]); fourxm->tracks[current_track].sample_rate = _X_LE_32(&header[i + 40]); fourxm->tracks[current_track].bits = _X_LE_32(&header[i + 44]); const uint32_t audio_type = _X_LE_32(&header[i + 12]); if (audio_type == 0) fourxm->tracks[current_track].audio_type = BUF_AUDIO_LPCM_LE; else if (audio_type == 1) fourxm->tracks[current_track].audio_type = BUF_AUDIO_4X_ADPCM; fourxm->tracks[current_track].audio_type += (current_track & 0x0000FFFF); i += 8 + size; } } fourxm->filesize = fourxm->input->get_length(fourxm->input); /* this will get bumped to 0 on the first iteration */ fourxm->video_pts = -fourxm->video_pts_inc; free(header); /* skip the data body LIST header */ if (fourxm->input->seek(fourxm->input, 12, SEEK_CUR) < 0) return 0; return 1; } static int demux_fourxm_send_chunk(demux_plugin_t *this_gen) { demux_fourxm_t *this = (demux_fourxm_t *) this_gen; buf_element_t *buf = NULL; unsigned int remaining_bytes; unsigned int current_track; /* read the next header */ uint8_t header[8]; if (this->input->read(this->input, header, 8) != 8) { this->status = DEMUX_FINISHED; return this->status; } const uint32_t fourcc_tag = _X_LE_32(&header[0]); const uint32_t size = _X_LE_32(&header[4]); switch (fourcc_tag) { case ifrm_TAG: case pfrm_TAG: case cfrm_TAG: /* send the 8-byte chunk header first */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_4XM; if( this->filesize ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->filesize ); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; buf->size = 8; memcpy(buf->content, header, 8); if (fourcc_tag == ifrm_TAG) buf->decoder_flags |= BUF_FLAG_KEYFRAME; this->video_fifo->put(this->video_fifo, buf); remaining_bytes = size; while (remaining_bytes) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_4XM; if( this->filesize ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->filesize ); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; if ((int)remaining_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_bytes; remaining_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!remaining_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; if (fourcc_tag == ifrm_TAG) buf->decoder_flags |= BUF_FLAG_KEYFRAME; this->video_fifo->put(this->video_fifo, buf); } break; case snd__TAG: /* fetch the track number and audio chunk size */ if (this->input->read(this->input, header, 8) != 8) { this->status = DEMUX_FINISHED; return this->status; } current_track = _X_LE_32(&header[0]); // size = _X_LE_32(&header[4]); if (current_track >= this->track_count) { lprintf ("bad audio track number (%d >= %d)\n", current_track, this->track_count); this->status = DEMUX_FINISHED; return this->status; } remaining_bytes = size - 8; while (remaining_bytes) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->tracks[current_track].audio_type; if( this->filesize ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->filesize ); /* let the engine sort it out */ buf->extra_info->input_time = 0; buf->pts = 0; if ((int)remaining_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_bytes; remaining_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!remaining_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put(this->audio_fifo, buf); } break; case LIST_TAG: /* skip LIST header */ if (this->input->seek(this->input, 4, SEEK_CUR) < 0) this->status = DEMUX_FINISHED; /* take this opportunity to bump the video pts */ this->video_pts += this->video_pts_inc; break; default: lprintf("bad chunk: %c%c%c%c (%02X%02X%02X%02X)\n", header[0], header[1], header[2], header[3], header[0], header[1], header[2], header[3]); this->status = DEMUX_FINISHED; break; } return this->status; } static void demux_fourxm_send_headers(demux_plugin_t *this_gen) { demux_fourxm_t *this = (demux_fourxm_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->track_count > 0) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); if (this->track_count > 0) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->tracks[0].channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->tracks[0].sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->tracks[0].bits); } /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->video_pts_inc; /* initial video_step */ memcpy(buf->content, &this->bih, sizeof(this->bih)); buf->size = sizeof(this->bih); buf->type = BUF_VIDEO_4XM; this->video_fifo->put (this->video_fifo, buf); if (this->audio_fifo && this->track_count > 0) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->tracks[0].audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->tracks[0].sample_rate; buf->decoder_info[2] = this->tracks[0].bits; buf->decoder_info[3] = this->tracks[0].channels; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_fourxm_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_fourxm_t *this = (demux_fourxm_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static int demux_fourxm_get_status (demux_plugin_t *this_gen) { demux_fourxm_t *this = (demux_fourxm_t *) this_gen; return this->status; } static int demux_fourxm_get_stream_length (demux_plugin_t *this_gen) { demux_fourxm_t *this = (demux_fourxm_t *) this_gen; return this->duration_in_ms; } static uint32_t demux_fourxm_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_fourxm_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static void demux_fourxm_dispose(demux_plugin_t *this_gen) { demux_fourxm_t *this = (demux_fourxm_t *) this_gen; _x_freep (&this->tracks); free (this_gen); } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_fourxm_t *this; uint32_t header_size; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_fourxm_file(input, &header_size)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_fourxm_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_fourxm_send_headers; this->demux_plugin.send_chunk = demux_fourxm_send_chunk; this->demux_plugin.seek = demux_fourxm_seek; this->demux_plugin.dispose = demux_fourxm_dispose; this->demux_plugin.get_status = demux_fourxm_get_status; this->demux_plugin.get_stream_length = demux_fourxm_get_stream_length; this->demux_plugin.get_capabilities = demux_fourxm_get_capabilities; this->demux_plugin.get_optional_data = demux_fourxm_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_fourxm_file(this, header_size)) { demux_fourxm_dispose (&this->demux_plugin); return NULL; } return &this->demux_plugin; } void *demux_fourxm_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_fourxm_class = { .open_plugin = open_plugin, .description = N_("4X Technologies (4xm) demux plugin"), .identifier = "4X Technologies", .mimetypes = NULL, .extensions = "4xm", .dispose = NULL, }; return (void *)&demux_fourxm_class; } xine-lib-1.2/src/demuxers/demux_real.c0000644000175000017500000021637714647725152015620 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * Real Media File Demuxer by Mike Melanson (melanson@pcisys.net) * improved by James Stembridge (jstembridge@users.sourceforge.net) * For more information regarding the Real file format, visit: * http://www.pcisys.net/~melanson/codecs/ * * video packet sub-demuxer ported from mplayer code (www.mplayerhq.hu): * Real parser & demuxer * * (C) Alex Beregszaszi * * Based on FFmpeg's libav/rm.c. * * Reworked by Torsten Jager */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_MALLOC_H #include #endif #define LOG_MODULE "demux_real" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #include #include "bswap.h" #include "demux_real_common.h" #define FOURCC_TAG BE_FOURCC #define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P') #define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R') #define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T') #define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A') #define RA_TAG FOURCC_TAG('.', 'r', 'a', 0xfd) #define VIDO_TAG FOURCC_TAG('V', 'I', 'D', 'O') #define PREAMBLE_SIZE 8 #define REAL_SIGNATURE_SIZE 8 #define DATA_CHUNK_HEADER_SIZE 10 #define DATA_PACKET_HEADER_SIZE 12 #define INDEX_CHUNK_HEADER_SIZE 20 #define INDEX_RECORD_SIZE 14 #define PN_KEYFRAME_FLAG 0x0002 #define MAX_VIDEO_STREAMS 10 #define MAX_AUDIO_STREAMS 8 #define FRAGMENT_TAB_SIZE 256 typedef struct { uint16_t object_version; uint16_t stream_number; uint32_t max_bit_rate; uint32_t avg_bit_rate; uint32_t max_packet_size; uint32_t avg_packet_size; uint32_t start_time; uint32_t preroll; uint32_t duration; size_t stream_name_size; char *stream_name; size_t mime_type_size; char *mime_type; size_t type_specific_len; uint8_t *type_specific_data; } mdpr_t; typedef struct { uint32_t timestamp; uint32_t offset; uint32_t packetno; } real_index_entry_t; typedef struct { uint32_t fourcc; uint32_t buf_type; uint32_t format; /* seek index */ int index_entries; real_index_entry_t *index; /* stream info */ mdpr_t *mdpr; /* interleaver type and settings */ uint32_t intl; int sps, cfs, w, h; int block_align; size_t frame_size; uint8_t *frame_buffer; uint32_t frame_num_bytes; uint32_t sub_packet_cnt; uint32_t audio_time; } real_stream_t; typedef struct { demux_plugin_t demux_plugin; /* xine engine */ xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; /* an input or 2 ;-) */ input_plugin_t *input, *in1, *in2; off_t startpos1; off_t startpos2; uint32_t pos1, endpos1, pos2, endpos2; uint32_t lasttime1, lasttime2; /* seek */ off_t index_start; off_t data_start; off_t data_size; unsigned int duration; /* top level chunk parser */ unsigned int current_data_chunk_packet_count; unsigned int next_data_chunk_offset; unsigned int data_chunk_size; /* multirate database */ int num_audio_streams; int num_video_streams; real_stream_t audio_streams[MAX_AUDIO_STREAMS]; real_stream_t video_streams[MAX_VIDEO_STREAMS]; /* and what we use of it */ real_stream_t *audio_stream; real_stream_t *video_stream; int audio_id; int video_id; /* audio deobfuscation */ int audio_need_keyframe; /* video deobfuscation */ uint32_t *fragment_tab; int fragment_tab_max; int fragment_size; int fragment_count; int old_seqnum; /* mp4 video depacketizer */ buf_element_t *vbuf; uint32_t vtime; uint32_t vkeyframe; /* timeline */ off_t avg_bitrate; int64_t last_pts[2]; int send_newpts; /* redirection */ int reference_mode; /* our status */ int status; } demux_real_t ; static void real_parse_index(demux_real_t *this) { off_t next_index_chunk = this->index_start; off_t original_pos = this->input->get_current_pos(this->input); uint8_t index_chunk_header[INDEX_CHUNK_HEADER_SIZE]; int i; while(next_index_chunk) { uint16_t version; uint32_t entries; uint16_t stream_num; uint8_t *q; real_index_entry_t **index = NULL; lprintf("reading index chunk at %"PRIX64"\n", next_index_chunk); /* Seek to index chunk */ this->input->seek(this->input, next_index_chunk, SEEK_SET); /* Read index chunk header */ if(this->input->read(this->input, index_chunk_header, INDEX_CHUNK_HEADER_SIZE) != INDEX_CHUNK_HEADER_SIZE) { lprintf("index chunk header not read\n"); break; } /* Check chunk is actually an index chunk */ if(!_x_is_fourcc(&index_chunk_header[0], "INDX")) { lprintf("expected index chunk found chunk type: %.4s\n", &index_chunk_header[0]); break; } /* Check version */ version = _X_BE_16(&index_chunk_header[8]); if(version != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: unknown object version in INDX: 0x%04x\n", version); break; } /* Read data from header */ entries = _X_BE_32(&index_chunk_header[10]); stream_num = _X_BE_16(&index_chunk_header[14]); next_index_chunk = _X_BE_32(&index_chunk_header[16]); /* Find which stream this index is for */ for(i = 0; i < this->num_video_streams; i++) { if(stream_num == this->video_streams[i].mdpr->stream_number) { index = &this->video_streams[i].index; this->video_streams[i].index_entries = entries; lprintf("found index chunk for video stream with num %d\n", stream_num); break; } } if(!index) { for(i = 0; i < this->num_audio_streams; i++) { if(stream_num == this->audio_streams[i].mdpr->stream_number) { index = &this->audio_streams[i].index; this->audio_streams[i].index_entries = entries; lprintf("found index chunk for audio stream with num %d\n", stream_num); break; } } } q = NULL; if (index && entries && (entries < (1 << 18))) { free (*index); *index = NULL; /* Allocate memory for index */ if (sizeof (real_index_entry_t) > INDEX_RECORD_SIZE) q = malloc (entries * sizeof (real_index_entry_t)); else q = malloc (entries * INDEX_RECORD_SIZE); } if (index && entries && q) { real_index_entry_t *e = (real_index_entry_t *)q; if (sizeof (real_index_entry_t) > INDEX_RECORD_SIZE) q += entries * (sizeof (real_index_entry_t) - INDEX_RECORD_SIZE); /* Read index */ if (this->input->read (this->input, q, entries * INDEX_RECORD_SIZE) != entries * INDEX_RECORD_SIZE) { lprintf ("index record not read\n"); free (e); *index = NULL; } else { *index = e; while (entries--) { e->timestamp = _X_BE_32 (q + 2); e->offset = _X_BE_32 (q + 6); e->packetno = _X_BE_32 (q + 10); e++; q += INDEX_RECORD_SIZE; } } } else { lprintf("unused index chunk with %d entries for stream num %d\n", entries, stream_num); } } /* Seek back to position before index reading */ this->input->seek(this->input, original_pos, SEEK_SET); } static mdpr_t *real_parse_mdpr (const char *data, uint32_t size) { const uint8_t *p, *p1, *p2, *p3; uint8_t *q; mdpr_t *mdpr; uint32_t sall, s1, s2, s3; /* get size needed */ if (size < 38) return NULL; p = (const uint8_t *)data + 32; sall = size - 38; s1 = *p++; if (sall < s1) return NULL; p1 = p; p += s1; sall -= s1; s2 = *p++; if (sall < s2) return NULL; p2 = p; p += s2; sall -= s2; s3 = _X_BE_32 (p); p += 4; if (sall < s3) return NULL; p3 = p; /* now build */ q = malloc (sizeof (mdpr_t) + s1 + s2 + s3 + 8); if (!q) return NULL; mdpr = (mdpr_t *)q; p = (const uint8_t *)data; mdpr->object_version = _X_BE_16 (p); mdpr->stream_number = _X_BE_16 (p + 2); mdpr->max_bit_rate = _X_BE_32 (p + 4); mdpr->avg_bit_rate = _X_BE_32 (p + 8); mdpr->max_packet_size = _X_BE_32 (p + 12); mdpr->avg_packet_size = _X_BE_32 (p + 16); mdpr->start_time = _X_BE_32 (p + 20); mdpr->preroll = _X_BE_32 (p + 24); mdpr->duration = _X_BE_32 (p + 28); q += sizeof (mdpr_t); #define ALIGN4(q) q = (uint8_t *)(((uintptr_t)q + 3) & ~(uintptr_t)3) memcpy (q, p1, s1); mdpr->stream_name = (char *)q; mdpr->stream_name_size = s1; q += s1; *q++ = 0; ALIGN4 (q); memcpy (q, p2, s2); mdpr->mime_type = (char *)q; mdpr->mime_type_size = s2; q += s2; *q++ = 0; ALIGN4 (q); memcpy (q, p3, s3); mdpr->type_specific_data = q; mdpr->type_specific_len = s3; #undef ALIGN4 lprintf("MDPR: stream number: %i\n", mdpr->stream_number); lprintf("MDPR: maximal bit rate: %i\n", mdpr->max_bit_rate); lprintf("MDPR: average bit rate: %i\n", mdpr->avg_bit_rate); lprintf("MDPR: largest packet size: %i bytes\n", mdpr->max_packet_size); lprintf("MDPR: average packet size: %i bytes\n", mdpr->avg_packet_size); lprintf("MDPR: start time: %i\n", mdpr->start_time); lprintf("MDPR: pre-buffer: %i ms\n", mdpr->preroll); lprintf("MDPR: duration of stream: %i ms\n", mdpr->duration); lprintf("MDPR: stream name: %s\n", mdpr->stream_name); lprintf("MDPR: mime type: %s\n", mdpr->mime_type); lprintf("MDPR: type specific data:\n"); #ifdef LOG xine_hexdump(mdpr->type_specific_data, mdpr->type_specific_len); #endif return mdpr; } static void real_free_mdpr (mdpr_t *mdpr) { free (mdpr); } static int real_parse_audio_specific_data (demux_real_t *this, real_stream_t *stream) { uint8_t *p, *e; uint32_t version; uint32_t head_size, flavor, coded_frame_size, h, frame_size, subpacket_size; uint32_t samplerate, samplesize, channels, intl, fourcc; uint32_t codecdata_length; p = stream->mdpr->type_specific_data; e = p + stream->mdpr->type_specific_len; if (p + 6 > e) goto truncated; version = p[5]; if (version == 3) { frame_size = 240; samplerate = 8000; samplesize = 16; channels = 1; intl = 0; coded_frame_size = 0; h = 0; subpacket_size = 0; if (p + 11 > e) goto truncated; p = e - 5; fourcc = _X_ME_32 (p); } else { if (p + 48 > e) goto truncated; p += 20; head_size = _X_BE_16 (p); p += 2; flavor = _X_BE_16 (p); p += 2; coded_frame_size = _X_BE_32 (p); p += 4; p += 12; h = _X_BE_16 (p); p += 2; frame_size = _X_BE_16 (p); p += 2; subpacket_size = _X_BE_16 (p); p += 2; p += 2; if (version == 5) p += 6; if (p + 8 > e) goto truncated; samplerate = _X_BE_16 (p); p += 2; p += 2; samplesize = _X_BE_16 (p); p += 2; channels = _X_BE_16 (p); p += 2; if (version == 5) { if (p + 8 > e) goto truncated; intl = _X_ME_32 (p); p += 4; /* integer ID's */ fourcc = _X_ME_32 (p); p += 4; } else { if (p + 10 > e) goto truncated; intl = _X_ME_32 (p + 1); p += p[0] + 1; /* string ID's */ fourcc = _X_ME_32 (p + 1); p += p[0] + 1; } stream->block_align = frame_size; switch (fourcc) { case ME_FOURCC('d','n','e','t'): /* AC3 with swapped byte order */ break; case ME_FOURCC('1','4','_','4'): stream->block_align = 20; break; case ME_FOURCC('2','8','_','8'): stream->block_align = coded_frame_size; break; case ME_FOURCC('s','i','p','r'): case ME_FOURCC('a','t','r','c'): case ME_FOURCC('c','o','o','k'): p += 3; if (version == 5) p += 1; if (p + 4 > e) goto truncated; codecdata_length = _X_BE_32 (p); p += 4; stream->block_align = intl == ME_FOURCC('g','e','n','r') ? subpacket_size : coded_frame_size; break; case ME_FOURCC('r','a','a','c'): case ME_FOURCC('r','a','c','p'): /* AAC */ p += 3; if (version == 5) p += 1; if (p + 4 > e) goto truncated; codecdata_length = _X_BE_32 (p); p += 4; fourcc = ME_FOURCC('m','p','4','a'); break; } } if (0) { truncated: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_real: truncated MDPR chunk\n"); return 0; } /* return 4CC */ stream->fourcc = fourcc; /* return interleaver type and settings */ if (!((intl == ME_FOURCC('g','e','n','r')) || (intl == ME_FOURCC('I','n','t','4')) || (intl == ME_FOURCC('s','i','p','r')))) intl = 0; stream->intl = intl; stream->sps = subpacket_size; stream->w = frame_size; stream->h = h; stream->cfs = coded_frame_size; { char b[20]; _x_tag32_me2str (b, fourcc); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: stream #%d: audio v%d, [%s] %ubps, %dch, %dHz, %dbit, start %d\n", (int)stream->mdpr->stream_number, version, b, (unsigned int)stream->mdpr->avg_bit_rate, channels, samplerate, samplesize, (int)stream->mdpr->start_time); if (intl) { _x_tag32_me2str (b, intl); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, " interleaved [%s] %dx%d, align %d, sps %d, cfs %d\n", b, stream->w, stream->h, stream->block_align, stream->sps, stream->cfs); } } /* * when stream->sps is set it used to do this: * stream->frame_size = stream->w / stream->sps * stream->h * stream->sps; * but it looks pointless? the compiler will probably optimise it away, I suppose? */ free (stream->frame_buffer); if (stream->w < 32768 && stream->h < 32768) { stream->frame_size = stream->w * stream->h; stream->frame_buffer = calloc (stream->frame_size, 1); } else { stream->frame_size = 0; stream->frame_buffer = NULL; } stream->frame_num_bytes = 0; stream->sub_packet_cnt = 0; /* XXX: decoder parses these again - skip "unused" warning */ (void)head_size; (void)flavor; (void)codecdata_length; if (!stream->frame_buffer) xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_real: failed to allocate the audio frame buffer!\n"); return 1; } static void real_parse_headers (demux_real_t *this) { char preamble[PREAMBLE_SIZE]; unsigned int chunk_type = 0; unsigned int chunk_size; unsigned int audio_bitrate = 0; unsigned int video_bitrate = 0; real_stream_t *stream; if (INPUT_IS_SEEKABLE(this->input)) this->input->seek (this->input, 0, SEEK_SET); { uint8_t signature[REAL_SIGNATURE_SIZE]; if (this->input->read(this->input, signature, REAL_SIGNATURE_SIZE) != REAL_SIGNATURE_SIZE) { lprintf ("signature not read\n"); this->status = DEMUX_FINISHED; return; } if ( !_x_is_fourcc(signature, ".RMF") ) { this->status = DEMUX_FINISHED; lprintf ("signature not found '%.4s'\n", signature); return; } /* skip to the start of the first chunk and start traversing */ chunk_size = _X_BE_32(&signature[4]); } this->data_start = 0; this->data_size = 0; this->num_video_streams = 0; this->num_audio_streams = 0; this->input->seek(this->input, chunk_size-8, SEEK_CUR); /* iterate through chunks and gather information until the first DATA * chunk is located */ while (chunk_type != DATA_TAG) { if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return; } chunk_type = _X_BE_32(&preamble[0]); chunk_size = _X_BE_32(&preamble[4]); lprintf ("chunktype %.4s len %d\n", (char *) &chunk_type, chunk_size); switch (chunk_type) { case PROP_TAG: case MDPR_TAG: case CONT_TAG: { if (chunk_size < PREAMBLE_SIZE+1) { this->status = DEMUX_FINISHED; return; } chunk_size -= PREAMBLE_SIZE; uint8_t *const chunk_buffer = malloc(chunk_size); if (! chunk_buffer || this->input->read(this->input, chunk_buffer, chunk_size) != chunk_size) { free (chunk_buffer); this->status = DEMUX_FINISHED; return; } uint16_t version = _X_BE_16(&chunk_buffer[0]); if (chunk_type == PROP_TAG) { if(version != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demuxe_real: unknown object version in PROP: 0x%04x\n", version); free(chunk_buffer); this->status = DEMUX_FINISHED; return; } this->duration = _X_BE_32(&chunk_buffer[22]); this->index_start = _X_BE_32(&chunk_buffer[30]); this->data_start = _X_BE_32(&chunk_buffer[34]); this->avg_bitrate = _X_BE_32(&chunk_buffer[6]); lprintf("PROP: duration: %d ms\n", this->duration); lprintf("PROP: index start: %"PRIX64"\n", this->index_start); lprintf("PROP: data start: %"PRIX64"\n", this->data_start); lprintf("PROP: average bit rate: %"PRId64"\n", this->avg_bitrate); if (this->avg_bitrate<1) this->avg_bitrate = 1; _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->avg_bitrate); } else if (chunk_type == MDPR_TAG) { mdpr_t *mdpr; uint32_t fourcc = 0, isvideo = 0; if (version != 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: unknown object version in MDPR: 0x%04x\n", version); free (chunk_buffer); continue; } mdpr = real_parse_mdpr ((char *)chunk_buffer, chunk_size); if (!mdpr) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: invalid MDPR\n"); free (chunk_buffer); continue; } lprintf ("parsing type specific data...\n"); /* identify by mime type */ if (!strcmp (mdpr->mime_type, "audio/X-MP3-draft-00")) { fourcc = ME_FOURCC ('a','d','u',0x55); } else if (!strcmp (mdpr->mime_type, "audio/mpeg4-generic")) { fourcc = ME_FOURCC ('m','p','4','a'); } else if (!strcmp (mdpr->mime_type, "video/MP4V-ES")) { fourcc = ME_FOURCC ('m','p','4','v'); isvideo = 1; } if (fourcc) { if (isvideo) { if (this->num_video_streams == MAX_VIDEO_STREAMS) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: maximum number of video stream exceeded\n"); goto unknown; } stream = &this->video_streams[this->num_video_streams]; /* stream->format = _X_BE_32(mdpr->type_specific_data + 30); */ } else { char b[20]; if (this->num_audio_streams == MAX_AUDIO_STREAMS) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: maximum number of audio stream exceeded\n"); goto unknown; } stream = &this->audio_streams[this->num_audio_streams]; stream->mdpr = mdpr; _x_tag32_me2str (b, fourcc); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: stream #%d: audio [%s] %ubps, start %d\n", (int)mdpr->stream_number, b, (unsigned int)mdpr->avg_bit_rate, (int)mdpr->start_time); } } else if ((mdpr->type_specific_len >= 4) && (_X_BE_32 (mdpr->type_specific_data) == RA_TAG)) { /* identify by type specific data */ if(this->num_audio_streams == MAX_AUDIO_STREAMS) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: maximum number of audio stream exceeded\n"); goto unknown; } stream = &this->audio_streams[this->num_audio_streams]; stream->mdpr = mdpr; if (!real_parse_audio_specific_data (this, stream)) goto unknown; fourcc = stream->fourcc; } else if ((mdpr->type_specific_len >= 34) && (_X_BE_32 (mdpr->type_specific_data + 4) == VIDO_TAG)) { if(this->num_video_streams == MAX_VIDEO_STREAMS) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: maximum number of video stream exceeded\n"); goto unknown; } isvideo = 1; lprintf ("video detected\n"); fourcc = _X_ME_32 (mdpr->type_specific_data + 8); stream = &this->video_streams[this->num_video_streams]; stream->format = _X_BE_32 (mdpr->type_specific_data + 30); } if (fourcc) { if (isvideo) { char b[20]; _x_tag32_me2str (b, fourcc); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: stream #%d: video [%s] %ubps, start %d\n", (int)mdpr->stream_number, b, (unsigned int)mdpr->avg_bit_rate, (int)mdpr->start_time); stream->index = NULL; stream->mdpr = mdpr; stream->fourcc = fourcc; stream->buf_type = _x_fourcc_to_buf_video (fourcc); if (!stream->buf_type) _x_report_video_fourcc (this->stream->xine, LOG_MODULE, fourcc); if (mdpr->avg_bit_rate > video_bitrate) { /* select best video */ video_bitrate = mdpr->avg_bit_rate; this->video_stream = stream; } this->num_video_streams++; } else { stream->index = NULL; stream->fourcc = fourcc; stream->buf_type = _x_formattag_to_buf_audio (fourcc); if (mdpr->avg_bit_rate > audio_bitrate) { /* select best audio */ audio_bitrate = mdpr->avg_bit_rate; this->audio_stream = stream; } this->num_audio_streams++; } } else { lprintf ("unrecognised mdpr or type specific data\n"); unknown: real_free_mdpr (mdpr); } } else if (chunk_type == CONT_TAG) { if(version != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: unknown object version in CONT: 0x%04x\n", version); free(chunk_buffer); continue; } int stream_ptr = 2; #define SET_METADATA_STRING(type) \ do { \ const uint16_t field_size = _X_BE_16(&chunk_buffer[stream_ptr]); \ stream_ptr += 2; \ _x_meta_info_n_set(this->stream, type, (char *)&chunk_buffer[stream_ptr], field_size); \ stream_ptr += field_size; \ } while(0) /* load the title string */ SET_METADATA_STRING(XINE_META_INFO_TITLE); /* load the author string */ SET_METADATA_STRING(XINE_META_INFO_ARTIST); /* load the copyright string as the year */ SET_METADATA_STRING(XINE_META_INFO_YEAR); /* load the comment string */ SET_METADATA_STRING(XINE_META_INFO_COMMENT); } free(chunk_buffer); } break; case DATA_TAG: { uint8_t data_chunk_header[DATA_CHUNK_HEADER_SIZE]; if (this->input->read(this->input, data_chunk_header, DATA_CHUNK_HEADER_SIZE) != DATA_CHUNK_HEADER_SIZE) { this->status = DEMUX_FINISHED; return ; } /* check version */ const uint16_t version = _X_BE_16(&data_chunk_header[0]); if(version != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: unknown object version in DATA: 0x%04x\n", version); this->status = DEMUX_FINISHED; return; } this->current_data_chunk_packet_count = _X_BE_32(&data_chunk_header[2]); this->next_data_chunk_offset = _X_BE_32(&data_chunk_header[6]); this->data_chunk_size = chunk_size; } break; default: /* this should not occur, but in case it does, skip the chunk */ lprintf("skipping a chunk!\n"); this->input->seek(this->input, chunk_size - PREAMBLE_SIZE, SEEK_CUR); break; } } /* Read index tables */ if(INPUT_IS_SEEKABLE(this->input)) real_parse_index(this); /* Simple stream selection case - 0/1 audio/video streams */ if (!this->video_stream) this->video_stream = (this->num_video_streams == 1) ? &this->video_streams[0] : NULL; if (!this->audio_stream) this->audio_stream = (this->num_audio_streams == 1) ? &this->audio_streams[0] : NULL; /* Last resort in the case of multiple audio/video streams: * select the first streams found in the file */ if ((!this->video_stream && (this->num_video_streams > 1)) || (!this->audio_stream && (this->num_audio_streams > 1))) { int len, offset; off_t original_pos = 0; char search_buffer[MAX_PREVIEW_SIZE]; /* Get data to search through for stream chunks */ if(INPUT_IS_SEEKABLE(this->input)) { original_pos = this->input->get_current_pos(this->input); if((len = this->input->read(this->input, search_buffer, MAX_PREVIEW_SIZE)) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read header\n"); this->status = DEMUX_FINISHED; return; } offset = 0; } else if((this->input->get_capabilities(this->input) & INPUT_CAP_PREVIEW) != 0) { if((len = this->input->get_optional_data(this->input, search_buffer, INPUT_OPTIONAL_DATA_PREVIEW)) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read header\n"); this->status = DEMUX_FINISHED; return; } /* Preview data starts at the beginning of the file */ offset = this->data_start + 18; } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: unable to search for correct stream\n"); this->status = DEMUX_FINISHED; return; } while((offset < len) && ((!this->video_stream && (this->num_video_streams > 0)) || (!this->audio_stream && (this->num_audio_streams > 0)))) { int i; /* Check for end of the data chunk */ if (_x_is_fourcc(&search_buffer[offset], "INDX") || _x_is_fourcc(&search_buffer[offset], "DATA")) break; const int stream = _X_BE_16(&search_buffer[offset + 4]); for(i = 0; !this->video_stream && (i < this->num_video_streams); i++) { if(stream == this->video_streams[i].mdpr->stream_number) { this->video_stream = &this->video_streams[i]; lprintf("selecting video stream: %d\n", stream); } } for(i = 0; !this->audio_stream && (i < this->num_audio_streams); i++) { if(stream == this->audio_streams[i].mdpr->stream_number) { this->audio_stream = &this->audio_streams[i]; lprintf("selecting audio stream: %d\n", stream); } } offset += _X_BE_16(&search_buffer[offset + 2]); } if(INPUT_IS_SEEKABLE(this->input)) this->input->seek(this->input, original_pos, SEEK_SET); } /* Let the user know if we haven't managed to detect what streams to play */ if((!this->video_stream && this->num_video_streams) || (!this->audio_stream && this->num_audio_streams)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_real: unable to determine which audio/video streams to play\n"); this->status = DEMUX_FINISHED; return; } this->audio_id = this->audio_stream ? this->audio_stream->mdpr->stream_number : -1; this->video_id = this->video_stream ? this->video_stream->mdpr->stream_number : -1; this->pos1 = 18; this->endpos1 = chunk_size; this->pos2 = 18; this->endpos2 = chunk_size; this->startpos1 = this->input->get_current_pos (this->input) - 18; /* noninterleaved file (1 DATA chunk per stream) ? */ if (INPUT_IS_SEEKABLE (this->input)) { uint32_t need = (this->audio_stream ? 1 : 0) | (this->video_stream ? 2 : 0); off_t here = this->startpos1; off_t last_pos = here + 18; this->input->seek (this->input, here, SEEK_SET); while (need) { uint8_t b[20]; uint32_t size; if (this->input->read (this->input, b, 18) != 18) break; size = _X_BE_32 (b + 4); if (_X_ME_32 (b) == ME_FOURCC('D','A','T','A')) { int n = 32; while (--n) { int stream, psize; if (this->input->read (this->input, b, 12) != 12) break; psize = _X_BE_16 (b + 2); if (_X_BE_16 (b) < 2) { stream = _X_BE_16 (b + 4); if ((need & 1) && (stream == this->audio_id)) { this->startpos1 = here; this->endpos1 = size; need &= ~1; if (!need) break; } else if ((need & 2) && (stream == this->video_id)) { this->startpos2 = here; this->endpos2 = size; need &= ~2; if (!need) break; } } this->input->seek (this->input, psize - 12, SEEK_CUR); } } here += size; this->input->seek (this->input, here, SEEK_SET); } if (this->startpos1) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: audio stream #%d found in DATA chunk @%"PRId64".\n", this->audio_id, (int64_t)this->startpos1); if (this->startpos2) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: video stream #%d found in DATA chunk @%"PRId64".\n", this->video_id, (int64_t)this->startpos2); if (this->startpos1) { this->input->seek (this->input, this->startpos1 + 18, SEEK_SET); if (this->startpos2) { if (this->startpos1 != this->startpos2) { /* Noninterleaved file. Try cloning input. */ if (this->input->get_capabilities (this->input) & INPUT_CAP_CLONE) { input_plugin_t *in2 = NULL; if (this->input->get_optional_data (this->input, &in2, INPUT_OPTIONAL_DATA_CLONE) == INPUT_OPTIONAL_SUCCESS) this->in2 = in2; } if (this->in2) { this->in2->seek (this->in2, this->startpos2 + 18, SEEK_SET); this->lasttime2 = 0; } } } } else { if (this->startpos2) { this->input->seek (this->input, this->startpos2 + 18, SEEK_SET); this->startpos1 = this->startpos2; this->endpos1 = this->endpos2; } else { /* should not happen */ this->input->seek (this->input, last_pos, SEEK_SET); } } } /* should not happen */ if (!this->endpos1) this->endpos1 = 1; if (!this->endpos2) this->endpos2 = 1; /* Send headers and set meta info */ if (this->video_stream) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, this->video_stream->fourcc); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, this->video_stream->mdpr->avg_bit_rate); } else _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); if (this->audio_stream) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->audio_stream->fourcc); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->audio_stream->mdpr->avg_bit_rate); } else _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); /* send start buffers */ _x_demux_control_start(this->stream); if(this->video_stream) { static const uint8_t h[] = { 0x00,0x00,0x01,0xb0,0xf3,0x00,0x00,0x01, 0xb5,0x0e,0xe0,0x40,0xc0,0xcf,0x00,0x00, 0x01,0x00,0x00,0x00,0x01,0x20,0x00,0x84, 0x40,0x07,0xa8,0x50,0x20,0xf0,0xa2,0x1f }; const uint8_t *info = this->video_stream->mdpr->type_specific_data; uint32_t ilen = this->video_stream->mdpr->type_specific_len; buf_element_t *buf; /* Check for recognised codec*/ if(!this->video_stream->buf_type) this->video_stream->buf_type = BUF_VIDEO_UNKNOWN; /* Send header */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->content = buf->mem; if (!ilen && (this->video_stream->fourcc == ME_FOURCC ('m','p','4','v'))) { xine_bmiheader *bih; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_real: missing mp4v config, trying generic 320x240...\n"); buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; bih = (xine_bmiheader *)buf->content; memset (bih, 0, sizeof (xine_bmiheader)); bih->biSize = sizeof (xine_bmiheader); bih->biWidth = 320; bih->biHeight = 240; buf->size = sizeof (xine_bmiheader); buf->type = this->video_stream->buf_type; this->video_fifo->put (this->video_fifo, buf); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); info = h; ilen = sizeof (h); } if (ilen > (uint32_t)buf->max_size) ilen = buf->max_size; if (ilen) memcpy (buf->content, info, ilen); buf->size = ilen; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END; buf->extra_info->input_normpos = 0; buf->extra_info->input_time = 0; buf->extra_info->total_time = this->duration; buf->type = this->video_stream->buf_type; this->video_fifo->put (this->video_fifo, buf); /* Allocate fragment offset table */ this->fragment_tab = calloc(FRAGMENT_TAB_SIZE, sizeof(uint32_t)); this->fragment_tab_max = FRAGMENT_TAB_SIZE; } if(this->audio_stream) { /* Check for recognised codec */ if(!this->audio_stream->buf_type) this->audio_stream->buf_type = BUF_AUDIO_UNKNOWN; /* Send headers */ if(this->audio_fifo) { mdpr_t *const mdpr = this->audio_stream->mdpr; buf_element_t *buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_stream->buf_type; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END; if (!mdpr->type_specific_len) { /* we dont have anything to tell, maybe it still works */ buf->decoder_flags |= BUF_FLAG_STDHEADER; buf->size = 0; buf->decoder_info[0] = 0; buf->decoder_info[1] = 0; buf->decoder_info[2] = 0; buf->decoder_info[3] = 0; } else if (buf->type == BUF_AUDIO_AAC) { /* For AAC we send two header buffers, the first is a standard audio * header giving bits per sample, sample rate and number of channels. * The second is the codec initialisation data found at the end of * the type specific data for the audio stream */ if (mdpr->type_specific_len >= 62) { uint16_t version = _X_BE_16 (mdpr->type_specific_data + 4); if (version != 5) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: unsupported audio header version for AAC: %d\n", version); buf->free_buffer (buf); goto unsupported; } buf->decoder_info[1] = _X_BE_16 (mdpr->type_specific_data + 54); buf->decoder_info[2] = _X_BE_16 (mdpr->type_specific_data + 58); buf->decoder_info[3] = _X_BE_16 (mdpr->type_specific_data + 60); buf->decoder_flags |= BUF_FLAG_STDHEADER; buf->content = NULL; buf->size = 0; if (mdpr->type_specific_len >= 80) { uint32_t s; this->audio_fifo->put (this->audio_fifo, buf); buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); s = _X_BE_32 (mdpr->type_specific_data + 74); if (s >= 1) s -= 1; if (s > mdpr->type_specific_len - 79) s = mdpr->type_specific_len - 79; buf->type = this->audio_stream->buf_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END|BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG; buf->decoder_info[2] = s; buf->decoder_info_ptr[2] = buf->content; buf->size = 0; memcpy (buf->content, mdpr->type_specific_data + 79, s); } } } else { memcpy (buf->content, mdpr->type_specific_data, mdpr->type_specific_len); buf->size = mdpr->type_specific_len; } this->audio_fifo->put (this->audio_fifo, buf); } unsupported: ; } } /* very naive approach for parsing ram files. it will extract known * mrls directly so it should work for simple smil files too. * no attempt is made to support smil features: * http://service.real.com/help/library/guides/production/htmfiles/smil.htm */ static int demux_real_parse_references( demux_real_t *this) { char *buf = NULL; int buf_size = 0; int buf_used = 0; int len, i, j; int alternative = 0; int comment = 0; lprintf("parsing references\n"); /* read file to memory. * warning: dumb code, but hopefuly ok since reference file is small */ do { buf_size += 1024; buf = realloc(buf, buf_size+1); len = this->input->read(this->input, &buf[buf_used], buf_size-buf_used); if( len > 0 ) buf_used += len; /* 50k of reference file? no way. something must be wrong */ if( buf_used > 50*1024 ) break; } while( len > 0 ); if(buf_used) buf[buf_used] = '\0'; lprintf("received %d bytes [%s]\n", buf_used, buf); if (!strncmp(buf,"http://",7)) { i = 0; while (buf[i]) { j = i; while (buf[i] && !isspace(buf[i])) ++i; /* skip non-space */ len = buf[i]; buf[i] = 0; if (strncmp (buf + j, "http://", 7) || (i - j) < 8) break; /* stop at the first non-http reference */ lprintf("reference [%s] found\n", buf + j); _x_demux_send_mrl_reference (this->stream, 0, buf + j, NULL, 0, 0); buf[i] = (char) len; while (buf[i] && isspace(buf[i])) ++i; /* skip spaces */ } } else for (i = 0; i < buf_used; ++i) { /* "--stop--" is used to have pnm alternative for old real clients * new real clients will stop processing the file and thus use * rtsp protocol. */ if( !strncmp(&buf[i],"--stop--",8) ) alternative++; /* rpm files can contain comments which should be skipped */ if( !strncmp(&buf[i],"",3) ) comment = 0; if( (!strncmp(&buf[i],"pnm://",6) || !strncmp(&buf[i],"rtsp://",7)) && !comment ) { for(j=i; buf[j] && buf[j] != '"' && !isspace(buf[j]); j++ ) ; buf[j]='\0'; lprintf("reference [%s] found\n", &buf[i]); _x_demux_send_mrl_reference (this->stream, alternative, &buf[i], NULL, 0, 0); i = j; } } free(buf); this->status = DEMUX_FINISHED; return this->status; } /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) #define WRAP_THRESHOLD 220000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 #define PTS_BOTH 2 static void check_newpts (demux_real_t *this, int64_t pts, int video, int preview) { const int64_t diff = pts - this->last_pts[video]; if (preview) return; /* Metronom does not strictly follow audio pts. They usually are too coarse for seamless playback. Instead, it takes the latest discontinuity as a starting point. This can lead to terrible lags for our very long audio frames. So let's make sure audio has the last word here. */ if (this->send_newpts > video) { _x_demux_control_newpts (this->stream, pts, BUF_FLAG_SEEK); this->send_newpts = video; this->last_pts[video] = pts; this->last_pts[1 - video] = 0; } else if (pts && (this->last_pts[video]) && (abs (diff) > WRAP_THRESHOLD)) { _x_demux_control_newpts (this->stream, pts, 0); this->send_newpts = 0; this->last_pts[1 - video] = 0; } if (pts) this->last_pts[video] = pts; } static uint32_t real_get_reordered_pts (demux_real_t *this, uint8_t *hdr, uint32_t dts) { int pict_type; /* I1/I2/P/B-frame */ uint32_t t, pts; /* lower 13 bits of pts are stored within the frame */ pict_type = hdr[0]; t = ((((uint32_t)hdr[1] << 8) | hdr[2]) << 8) | hdr[3]; switch (this->video_stream->buf_type) { case BUF_VIDEO_RV20: pict_type >>= 6; t >>= 10; break; case BUF_VIDEO_RV30: pict_type >>= 3; t >>= 7; break; case BUF_VIDEO_RV40: pict_type >>= 5; t >>= 6; break; default: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: can't fix timestamp for buf type 0x%08x\n", this->video_stream->buf_type); return (dts); break; } pict_type &= 3; t &= 0x1fff; pts = (dts & (~0x1fff)) | t; /* snap to dts +/- 4.095 seconds */ if (dts + 0x1000 < pts) pts -= 0x2000; else if (dts > pts + 0x1000) pts += 0x2000; if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1, "demux_real: video pts: %d.%03d:%04d -> %d.%03d (%d)\n", dts / 1000, dts % 1000, t, pts / 1000, pts % 1000, pict_type); } return (pts); } static void demux_real_flush (demux_real_t *this) { if (this->vbuf) { /* flush previous frame */ this->vbuf->free_buffer (this->vbuf); this->vbuf = NULL; } } static int demux_real_send_chunk(demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; uint32_t timestamp; uint32_t stream; uint32_t size; uint32_t flags; int64_t pts; int keyframe, input_time = 0; int normpos; uint32_t bytes; if(this->reference_mode) return demux_real_parse_references(this); { uint8_t header[DATA_PACKET_HEADER_SIZE + 2]; uint32_t version; /* load a header from wherever the stream happens to be pointing */ if (this->input->read(this->input, header, DATA_PACKET_HEADER_SIZE) != DATA_PACKET_HEADER_SIZE) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read data packet header\n"); goto fail0; } /* Check to see if we've gone past the end of the data chunk */ if (_x_is_fourcc(&header[0], "INDX") || _x_is_fourcc(&header[0], "DATA")) { lprintf("finished reading data chunk\n"); goto fail0; } bytes = DATA_PACKET_HEADER_SIZE; if (this->input == this->in1) normpos = (uint64_t)this->pos1 * 0xffff / this->endpos1; else normpos = (uint64_t)this->pos2 * 0xffff / this->endpos2; /* check version */ version = _X_BE_16 (&header[0]); if (version > 1) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: unknown object version in data packet: 0x%04x\n", version); goto fail0; } /* read the packet information */ stream = _X_BE_16 (&header[4]); size = _X_BE_16 (&header[2]); if (size < DATA_PACKET_HEADER_SIZE) goto fail0; size -= DATA_PACKET_HEADER_SIZE; timestamp = _X_BE_32 (&header[6]); pts = (int64_t)timestamp * 90; /* Data packet header with version 1 contains 1 extra byte */ if (version == 0) { header[12] = 0; keyframe = header[11] & PN_KEYFRAME_FLAG; } else { if (this->input->read (this->input, header + DATA_PACKET_HEADER_SIZE, 1) != 1) goto fail0; keyframe = header[DATA_PACKET_HEADER_SIZE] & PN_KEYFRAME_FLAG; size--; bytes += 1; } header[13] = 0; flags = _X_BE_32 (header + 10); } lprintf ("packet of stream %d, 0x%X bytes @ %"PRIX64", pts = %"PRId64"%s\n", stream, size, this->input == this->in1 ? this->startpos1 + this->pos1 : this->startpos2 + this->pos2, pts, keyframe ? ", keyframe" : ""); if (this->video_stream && ((int)stream == this->video_id)) { int vpkg_seqnum = -1; int vpkg_subseq = 0; buf_element_t *buf; uint32_t decoder_flags; lprintf ("video chunk detected.\n"); pts = (int64_t) timestamp * 90; if (this->video_stream->fourcc == ME_FOURCC ('m','p','4','v')) { int left = size; #ifdef DEBUG_MP4V int64_t here = this->input->get_current_pos (this->input); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: mp4v @%" PRId64 ", %u bytes, time %u, flags 0x%08x.\n", here, size, timestamp, flags); #else (void)flags; #endif buf = this->vbuf; if (timestamp != this->vtime) { if (buf) { /* finish previous frame */ buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put (this->video_fifo, buf); this->vbuf = buf = NULL; } /* start new frame */ this->vtime = timestamp; this->vkeyframe = keyframe ? BUF_FLAG_KEYFRAME : 0; } if (!buf) { buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, size); this->vbuf = buf; buf->size = 0; buf->type = this->video_stream->buf_type; buf->decoder_flags = BUF_FLAG_FRAME_START | this->vkeyframe; buf->pts = pts; if (pts) { check_newpts (this, pts, PTS_VIDEO, 0); pts = 0; } } while (left) { int part = buf->max_size - buf->size; if (part > left) part = left; if (this->input->read (this->input, buf->content + buf->size, part) != part) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read video"); break; } buf->size += part; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = timestamp; buf->extra_info->total_time = this->duration; bytes += part; if (buf->size == buf->max_size) { this->video_fifo->put (this->video_fifo, buf); buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, size); buf->size = 0; buf->type = this->video_stream->buf_type; buf->decoder_flags = this->vkeyframe; this->vbuf = buf; } left -= part; } } else /* sub-demuxer */ while (size > 2) { /* * read packet header * bit 7: 1=last block in block chain * bit 6: 1=short header (only one block?) */ int vpkg_header, vpkg_length, vpkg_offset; uint8_t b[16], *p = b, *q = b; #define NEEDBYTES(n) { \ int need = n - (q - p); \ if (need > 0) { \ if (this->input->read (this->input, q, need) != need) \ goto fail0; \ q += need; \ } \ } NEEDBYTES (2); vpkg_header = *p++; lprintf ("vpkg_hdr: %02x (size=%d)\n", vpkg_header, size); if (0x40 == (vpkg_header & 0xc0)) { /* seems to be a very short header (2 bytes), purpose of the second byte yet unknown */ lprintf ("bummer == %02X\n", (unsigned int)*p); p++; vpkg_offset = 0; vpkg_length = size - 2; } else { if (0 == (vpkg_header & 0x40)) { /* sub-seqnum (bits 0-6: number of fragment. bit 7: ???) */ vpkg_subseq = (*p++) & 0x7f; } /* size of the complete packet. bit 14 is always one (same applies to the offset) */ NEEDBYTES (5); vpkg_length = _X_BE_16 (p); p += 2; if (!(vpkg_length & 0xC000)) { vpkg_length <<= 16; vpkg_length |= _X_BE_16 (p); p += 2; } else vpkg_length &= 0x3fff; /* * offset of the following data inside the complete packet * Note: if (hdr&0xC0)==0x80 then offset is relative to the * _end_ of the packet, so it's equal to fragment size!!! */ NEEDBYTES (3); vpkg_offset = _X_BE_16 (p); p += 2; if (!(vpkg_offset & 0xC000)) { NEEDBYTES (3); vpkg_offset <<= 16; vpkg_offset |= _X_BE_16 (p); p += 2; } else vpkg_offset &= 0x3fff; vpkg_seqnum = *p++; } bytes += p - b; size -= p - b; #undef NEEDBYTES /* not (yet) needed */ (void)vpkg_subseq; lprintf ("seq=%d, offset=%d, length=%d, size=%d, frag size=%d, flags=%02x\n", vpkg_seqnum, vpkg_offset, vpkg_length, size, this->fragment_size, vpkg_header); if (vpkg_seqnum != this->old_seqnum) { lprintf ("new seqnum\n"); this->fragment_size = 0; this->old_seqnum = vpkg_seqnum; } /* if we have a seekable stream then use the timestamp for the data * packet for more accurate seeking - if not then estimate time using * average bitrate */ if(this->video_stream->index) input_time = timestamp; else input_time = (int)((int64_t) this->input->get_current_pos(this->input) * 8 * 1000 / this->avg_bitrate); decoder_flags = keyframe ? BUF_FLAG_KEYFRAME : 0; if (this->fragment_size == 0) { lprintf ("new packet starting\n"); /* send fragment offset table */ if(this->fragment_count) { lprintf("sending fragment offset table\n"); buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL | BUF_FLAG_FRAME_END; buf->decoder_info[1] = BUF_SPECIAL_RV_CHUNK_TABLE; buf->decoder_info[2] = this->fragment_count - 1; buf->decoder_info_ptr[2] = buf->content; buf->decoder_info[3] = 0; buf->size = 0; buf->type = this->video_stream->buf_type; xine_fast_memcpy(buf->content, this->fragment_tab, this->fragment_count*8); this->video_fifo->put(this->video_fifo, buf); this->fragment_count = 0; } decoder_flags |= BUF_FLAG_FRAME_START; } else { lprintf ("continuing packet \n"); } /* add entry to fragment offset table */ this->fragment_tab[2*this->fragment_count] = 1; this->fragment_tab[2*this->fragment_count+1] = this->fragment_size; this->fragment_count++; /* * calc size of fragment */ int fragment_size; switch(vpkg_header & 0xc0) { case 0x80: fragment_size = vpkg_offset; break; case 0x00: fragment_size = size; break; default: fragment_size = vpkg_length; break; } lprintf ("fragment size is %d\n", fragment_size); /* * read fragment_size bytes of data */ int n = fragment_size; while(n) { buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->size = MIN(n, buf->max_size); buf->decoder_flags = decoder_flags; decoder_flags &= ~BUF_FLAG_FRAME_START; buf->type = this->video_stream->buf_type; if(this->input->read(this->input, buf->content, buf->size) < buf->size) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read video fragment"); buf->free_buffer(buf); goto fail0; } bytes += buf->size; /* RV30 and RV40 streams contain some fragments that shouldn't be passed * to the decoder. The purpose of these fragments is unknown, but * realplayer doesn't appear to pass them to the decoder either */ if((n == fragment_size) && (((buf->type == BUF_VIDEO_RV30) && (buf->content[0] & 0x20)) || ((buf->type == BUF_VIDEO_RV40) && (buf->content[0] & 0x80)))) { lprintf("ignoring fragment\n"); /* Discard buffer and skip over rest of fragment */ buf->free_buffer(buf); this->input->seek(this->input, n - buf->size, SEEK_CUR); this->fragment_count--; break; } /* if the video stream has b-frames fix the timestamps */ if ((this->video_stream->format >= 0x20200002) && (buf->decoder_flags & BUF_FLAG_FRAME_START)) { input_time = real_get_reordered_pts (this, buf->content, timestamp); pts = (int64_t)input_time * 90; } /* this test was moved from ffmpeg video decoder. * fixme: is pts only valid on frame start? */ if (buf->decoder_flags & BUF_FLAG_FRAME_START) { buf->pts = pts; check_newpts (this, pts, PTS_VIDEO, 0); } else buf->pts = 0; pts = 0; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = input_time; buf->extra_info->total_time = this->duration; this->video_fifo->put(this->video_fifo, buf); n -= buf->size; } size -= fragment_size; lprintf ("size left %d\n", size); this->fragment_size += fragment_size; if (this->fragment_size >= vpkg_length) { lprintf ("fragment finished (%d/%d)\n", this->fragment_size, vpkg_length); this->fragment_size = 0; } } /* while(size>2) */ } else if (this->audio_fifo && this->audio_stream && ((int)stream == this->audio_id)) { lprintf ("audio chunk detected.\n"); if(this->audio_need_keyframe && !keyframe) goto discard; else this->audio_need_keyframe = 0; /* speed up when not debugging */ if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1, "demux_real: audio pts: %d.%03d %s%s\n", timestamp / 1000, timestamp % 1000, keyframe ? "*" : " ", this->audio_stream->sub_packet_cnt ? " " : "s"); } /* cook audio frames are fairly long (almost 2 seconds). For obfuscation purposes, they are sent as multiple fragments in intentionally wrong order. The first sent fragment has the timestamp for the whole frame. Sometimes, the remaining fragments all carry the same time, and appear immediately thereafter. This is easy. Sometimes, the remaining fragments carry fake timestamps interpolated across the frame duration. Consequently, they will be muxed between the next few video frames. We get the complete frame ~2 seconds late. This is ugly. Let's be careful not to trap metronom into a big lag. */ if (!this->audio_stream->sub_packet_cnt) this->audio_stream->audio_time = timestamp; else timestamp = this->audio_stream->audio_time; /* nasty kludge was here due to a ff_audio_dec bug. if (this->audio_stream->buf_type == BUF_AUDIO_COOK) timestamp += 120; */ pts = (int64_t) timestamp * 90; /* if we have a seekable stream then use the timestamp for the data * packet for more accurate seeking - if not then estimate time using * average bitrate */ if(this->audio_stream->index) input_time = timestamp; else input_time = (int)((int64_t) this->input->get_current_pos(this->input) * 8 * 1000 / this->avg_bitrate); check_newpts (this, pts, PTS_AUDIO, 0); /* Each packet of AAC is made up of several AAC frames preceded by a * header defining the size of the frames in bits (!) */ if(this->audio_stream->buf_type == BUF_AUDIO_AAC) { int i, frames, sizes[16]; uint8_t b[32]; /* Upper 4 bits of second byte is frame count */ if (this->input->read (this->input, b, 2) != 2) goto fail0; bytes += 2; frames = b[1] >> 4; /* 2 bytes per frame size */ if (this->input->read (this->input, b, 2 * frames) != 2 * frames) goto fail0; bytes += 2 * frames; for (i = 0; i < frames; i++) sizes[i] = (_X_BE_16 (b + 2 * i) + 7) >> 3; for(i = 0; i < frames; i++) { if(_x_demux_read_send_data(this->audio_fifo, this->input, sizes[i], pts, this->audio_stream->buf_type, !i && keyframe ? BUF_FLAG_KEYFRAME : 0, normpos, input_time, this->duration, 0) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read AAC frame\n"); goto fail0; } bytes += sizes[i]; pts = 0; /* Only set pts on first frame */ } } else if (this->audio_stream->intl) { /* reorder */ uint8_t * buffer = this->audio_stream->frame_buffer; const int sps = this->audio_stream->sps; const int sph = this->audio_stream->h; const int cfs = this->audio_stream->cfs; const int w = this->audio_stream->w; const int spc = this->audio_stream->sub_packet_cnt; int x; const int fs = this->audio_stream->frame_size; if (!buffer) { this->status = DEMUX_FINISHED; return this->status; } switch (this->audio_stream->intl) { case ME_FOURCC('I','n','t','4'): for (x = 0; x < sph / 2; x++) { int pos = x * 2 * w + spc * cfs; if (pos + cfs > fs || this->input->read (this->input, buffer + pos, cfs) < cfs) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read audio chunk\n"); goto fail0; } bytes += cfs; } break; case ME_FOURCC('g','e','n','r'): for (x = 0; x < w / sps; x++) { int pos = sps * (sph * x + ((sph + 1) / 2) * (spc & 1) + (spc >> 1)); if (pos + sps > fs || this->input->read (this->input, buffer + pos, sps) < sps) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read audio chunk\n"); goto fail0; } bytes += sps; } break; case ME_FOURCC('s','i','p','r'): { int pos = spc * w; if (pos + w > fs || this->input->read (this->input, buffer + pos, w) < w) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read audio chunk\n"); goto fail0; } } bytes += w; if (spc == sph - 1) demux_real_sipro_swap ((char *)buffer, sph * w * 2 / 96); break; } this->audio_stream->sub_packet_cnt++; if ((int)this->audio_stream->sub_packet_cnt == sph) { this->audio_stream->sub_packet_cnt = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1, "demux_real: sending audio %d.%03d\n", input_time / 1000, input_time % 1000); _x_demux_send_data(this->audio_fifo, buffer, this->audio_stream->frame_size, pts, this->audio_stream->buf_type, keyframe ? BUF_FLAG_KEYFRAME : 0, normpos, input_time, this->duration, 0); } } else { if(_x_demux_read_send_data(this->audio_fifo, this->input, size, pts, this->audio_stream->buf_type, keyframe ? BUF_FLAG_KEYFRAME : 0, normpos, input_time, this->duration, 0) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_real: failed to read audio chunk\n"); goto fail0; } bytes += size; /* FIXME: dp->flags = (flags & 0x2) ? 0x10 : 0; */ } } else { /* discard */ lprintf ("chunk not detected; discarding.\n"); discard: this->input->seek(this->input, size, SEEK_CUR); bytes += size; } /* Every good demuxer also is a muxer ;-) */ if (this->input == this->in1) { this->lasttime1 = timestamp; this->pos1 += bytes; } else { this->lasttime2 = timestamp; this->pos2 += bytes; } if (this->in2) { if (this->lasttime1 > this->lasttime2) this->input = this->in2; else this->input = this->in1; } #if 0 this->current_data_chunk_packet_count--; /* check if it's time to reload */ if (!this->current_data_chunk_packet_count && this->next_data_chunk_offset) { unsigned char data_chunk_header[DATA_CHUNK_HEADER_SIZE]; /* seek to the next DATA chunk offset */ this->input->seek(this->input, this->next_data_chunk_offset + PREAMBLE_SIZE, SEEK_SET); /* load the rest of the DATA chunk header */ if (this->input->read(this->input, data_chunk_header, DATA_CHUNK_HEADER_SIZE) != DATA_CHUNK_HEADER_SIZE) { this->status = DEMUX_FINISHED; return this->status; } lprintf ("**** found next DATA tag\n"); this->current_data_chunk_packet_count = _X_BE_32(&data_chunk_header[2]); this->next_data_chunk_offset = _X_BE_32(&data_chunk_header[6]); } if (!this->current_data_chunk_packet_count) { this->status = DEMUX_FINISHED; return this->status; } #endif return this->status; fail0: if (this->vbuf) { /* finish last frame */ this->vbuf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put (this->video_fifo, this->vbuf); this->vbuf = NULL; } if (this->input == this->in1) { this->lasttime1 = 0xffffffff; if (this->lasttime2 == 0xffffffff) { this->status = DEMUX_FINISHED; return this->status; } if (this->in2) this->input = this->in2; } else { this->lasttime2 = 0xffffffff; this->input = this->in1; if (this->lasttime1 == 0xffffffff) { this->status = DEMUX_FINISHED; return this->status; } } return this->status; } static void demux_real_send_headers(demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; this->last_pts[0] = 0; this->last_pts[1] = 0; this->send_newpts = PTS_BOTH; this->avg_bitrate = 1; /* send init info to decoders */ this->input->seek (this->input, 0, SEEK_SET); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); if( !this->reference_mode ) { real_parse_headers (this); } else { if ((this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) != 0) this->input->seek (this->input, 0, SEEK_SET); } } static int demux_real_find_time (real_index_entry_t *index, int n, uint32_t t) { int b = 0, l, m = -1, e = n; if (e <= 0) return -1; do { l = m; m = (b + e) >> 1; if (t < index[m].timestamp) e = m; else b = m; } while (l != m); return m; } static int demux_real_find_offs (real_index_entry_t *index, int n, uint32_t offs) { int b = 0, l, m = -1, e = n; if (e <= 0) return -1; do { l = m; m = (b + e) >> 1; if (offs < index[m].offset) e = m; else b = m; } while (l != m); return m; } static int demux_real_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_real_t *this = (demux_real_t *) this_gen; lprintf("seek start_pos=%d, start_time=%d, playing=%d\n", (int)start_pos, start_time, playing); demux_real_flush (this); this->input = this->in1; do { int have; if (!(this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE)) { if (playing || !this->input->seek_time) return this->status; /* RTSP supports only time based seek */ if (start_pos && !start_time) start_time = (int64_t)this->duration * start_pos / 65535; this->input->seek_time (this->input, start_time, SEEK_SET); break; } if (!start_pos && !start_time) { /* We can always return to the beginning. */ this->lasttime1 = 0; this->pos1 = 18; this->pos2 = 18; this->in1->seek (this->in1, this->startpos1 + 18, SEEK_SET); if (this->in2) { this->lasttime2 = 0; this->in2->seek (this->in2, this->startpos2 + 18, SEEK_SET); } break; } have = ((this->audio_stream && this->audio_stream->index) ? 1 : 0) | ((this->video_stream && this->video_stream->index) ? 2 : 0); if (!have) return this->status; if (this->in2) { uint32_t pos1, pos2; int i1, i2; /* Noninterleaved seek. We need both indices. */ if (have != 3) return this->status; if (start_time) { i1 = demux_real_find_time (this->audio_stream->index, this->audio_stream->index_entries, start_time); i2 = demux_real_find_time (this->video_stream->index, this->video_stream->index_entries, start_time); if ((i1 < 0) || (i2 < 0)) return this->status; } else { /* start_pos */ pos1 = (uint32_t)((double)start_pos / 65535.0 * this->endpos1) + this->startpos1; pos2 = (uint32_t)((double)start_pos / 65535.0 * this->endpos2) + this->startpos2; i1 = demux_real_find_offs (this->audio_stream->index, this->audio_stream->index_entries, pos1); i2 = demux_real_find_offs (this->video_stream->index, this->video_stream->index_entries, pos2); if ((i1 < 0) || (i2 < 0)) return this->status; } pos1 = this->audio_stream->index[i1].offset; pos2 = this->video_stream->index[i2].offset; this->input->seek (this->in1, pos1, SEEK_SET); this->input->seek (this->in2, pos2, SEEK_SET); this->pos1 = pos1 - this->startpos1; this->pos2 = pos2 - this->startpos2; this->lasttime1 = 0; this->lasttime2 = 0; break; } { real_index_entry_t *index, *other_index = NULL; int i, entries; start_pos = (off_t)((double) start_pos / 65535 * this->input->get_length (this->input)); /* video index has priority over audio index */ if (have & 2) { index = this->video_stream->index; entries = this->video_stream->index_entries; if (have & 1) other_index = this->audio_stream->index; } else { index = this->audio_stream->index; entries = this->audio_stream->index_entries; } if (start_pos) i = demux_real_find_offs (index, entries, start_pos); else /* start_time */ i = demux_real_find_time (index, entries, start_time); if (i < 0) return this->status; /* make sure we don't skip past audio/video at start of file */ if ((i == 0) && other_index && (other_index[0].offset < index[0].offset)) index = other_index; this->input->seek (this->input, index[i].offset, SEEK_SET); this->pos1 = index[i].offset - this->startpos1; this->lasttime1 = 0; break; } } while (0); this->send_newpts = PTS_BOTH; this->old_seqnum = -1; this->fragment_size = 0; this->fragment_count = 0; this->audio_need_keyframe = 1; if (this->audio_stream) this->audio_stream->sub_packet_cnt = 0; if (playing) _x_demux_flush_engine (this->stream); this->status = DEMUX_OK; return this->status; } static void demux_real_dispose (demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; int i; demux_real_flush (this); if (this->in2) this->in2->dispose (this->in2); for(i = 0; i < this->num_video_streams; i++) { real_free_mdpr(this->video_streams[i].mdpr); free(this->video_streams[i].index); } for(i = 0; i < this->num_audio_streams; i++) { real_free_mdpr(this->audio_streams[i].mdpr); free(this->audio_streams[i].index); free(this->audio_streams[i].frame_buffer); } free(this->fragment_tab); free(this); } static int demux_real_get_status (demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; return this->status; } static int demux_real_get_stream_length (demux_plugin_t *this_gen) { demux_real_t *this = (demux_real_t *) this_gen; /* duration is stored in the file as milliseconds */ return this->duration; } static uint32_t demux_real_get_capabilities (demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_real_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } /* help function to discover stream type. returns: * -1 if couldn't read * 0 if not known. * 1 if normal stream. * 2 if reference stream. */ static int real_check_stream_type(input_plugin_t *input) { uint8_t buf[1024]; off_t len = _x_demux_read_header(input, buf, sizeof(buf)); if ( len < 4 ) return -1; if ( memcmp(buf, "\x2eRMF", 4) == 0 ) return 1; #define my_strnstr(haystack, haystacklen, needle) \ memmem(haystack, haystacklen, needle, sizeof(needle)) if( my_strnstr(buf, len, "pnm://") || my_strnstr(buf, len, "rtsp://") || my_strnstr(buf, len, "") || !strncmp((char *)buf, "http://", MIN(7, len)) ) return 2; return 0; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_real_t *this; /* discover stream type */ const int stream_type = real_check_stream_type(input); if ( stream_type < 0 ) return NULL; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: if ( stream_type < 1 ) return NULL; lprintf ("by content accepted.\n"); break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } this = calloc (1, sizeof (demux_real_t)); if (!this) return NULL; this->status = 0; this->num_audio_streams = 0; this->num_video_streams = 0; this->audio_stream = NULL; this->video_stream = NULL; this->startpos1 = 0; this->startpos2 = 0; this->audio_need_keyframe = 0; this->current_data_chunk_packet_count = 0; this->last_pts[0] = 0; this->last_pts[1] = 0; this->send_newpts = 0; this->fragment_count = 0; this->fragment_tab = NULL; this->fragment_tab_max = 0; this->vbuf = NULL; this->vtime = 0; this->vkeyframe = 0; this->reference_mode = 0; this->in2 = NULL; this->lasttime1 = 0; this->stream = stream; this->input = this->in1 = input; this->lasttime2 = 0xffffffff; if(stream_type == 2){ this->reference_mode = 1; lprintf("reference stream detected\n"); } this->demux_plugin.send_headers = demux_real_send_headers; this->demux_plugin.send_chunk = demux_real_send_chunk; this->demux_plugin.seek = demux_real_seek; this->demux_plugin.dispose = demux_real_dispose; this->demux_plugin.get_status = demux_real_get_status; this->demux_plugin.get_stream_length = demux_real_get_stream_length; this->demux_plugin.get_capabilities = demux_real_get_capabilities; this->demux_plugin.get_optional_data = demux_real_get_optional_data; this->demux_plugin.demux_class = class_gen; return &this->demux_plugin; } void *demux_real_init_class (xine_t *xine, const void *data) { /* We explicitely dont need these here. */ (void)xine; (void)data; static const demux_class_t demux_real_class = { .open_plugin = open_plugin, .description = N_("RealMedia file demux plugin"), .identifier = "Real", .mimetypes = "audio/x-pn-realaudio: ra, rm, ram: Real Media file;" "audio/x-pn-realaudio-plugin: rpm: Real Media plugin file;" "audio/x-real-audio: ra, rm, ram: Real Media file;" "application/vnd.rn-realmedia: ra, rm, ram: Real Media file;", .extensions = "rm rmvb ram", .dispose = NULL, }; return (void *)&demux_real_class; } xine-lib-1.2/src/demuxers/demux_snd.c0000644000175000017500000002647514647725152015457 0ustar meme/* * Copyright (C) 2001-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * SND/AU File Demuxer by Mike Melanson (melanson@pcisys.net) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_audio.h" #define SND_HEADER_SIZE 24 #define PCM_BLOCK_ALIGN 1024 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; unsigned int audio_type; unsigned int audio_frames; unsigned int audio_sample_rate; unsigned int audio_bits; unsigned int audio_channels; unsigned int audio_block_align; unsigned int audio_bytes_per_second; unsigned int running_time; off_t data_start; off_t data_size; int seek_flag; /* this is set when a seek just occurred */ } demux_snd_t; static int probe_snd_file(input_plugin_t *input) { unsigned char fourcc[4]; if (_x_demux_read_header(input, fourcc, 4) != 4) return 0; /* check the signature */ if ( !_x_is_fourcc(&fourcc[0], ".snd") ) return 0; return 1; } /* returns 1 if the SND file was opened successfully, 0 otherwise */ static int open_snd_file(demux_snd_t *this) { unsigned char header[SND_HEADER_SIZE]; unsigned int encoding; if (_x_demux_read_header(this->input, header, SND_HEADER_SIZE) != SND_HEADER_SIZE) return 0; this->data_start = _X_BE_32(&header[0x04]); this->data_size = _X_BE_32(&header[0x08]); encoding = _X_BE_32(&header[0x0C]); this->audio_sample_rate = _X_BE_32(&header[0x10]); this->audio_channels = _X_BE_32(&header[0x14]); /* basic sanity checks on the loaded audio parameters */ if ((!this->audio_sample_rate) || (!this->audio_channels)) { xine_log(this->stream->xine, XINE_LOG_MSG, _("demux_snd: bad header parameters\n")); return 0; } switch (encoding) { case 1: this->audio_type = BUF_AUDIO_MULAW; this->audio_bits = 16; this->audio_frames = this->data_size / this->audio_channels; this->audio_block_align = PCM_BLOCK_ALIGN; this->audio_bytes_per_second = this->audio_channels * this->audio_sample_rate; break; case 2: this->audio_type = BUF_AUDIO_LPCM_BE; this->audio_bits = 8; this->audio_frames = this->data_size / (this->audio_channels * this->audio_bits / 8); this->audio_block_align = PCM_BLOCK_ALIGN; this->audio_bytes_per_second = this->audio_channels * (this->audio_bits / 8) * this->audio_sample_rate; break; case 3: this->audio_type = BUF_AUDIO_LPCM_BE; this->audio_bits = 16; this->audio_frames = this->data_size / (this->audio_channels * this->audio_bits / 8); this->audio_block_align = PCM_BLOCK_ALIGN; this->audio_bytes_per_second = this->audio_channels * (this->audio_bits / 8) * this->audio_sample_rate; break; case 27: this->audio_type = BUF_AUDIO_ALAW; this->audio_bits = 16; this->audio_frames = this->data_size / this->audio_channels; this->audio_block_align = PCM_BLOCK_ALIGN; this->audio_bytes_per_second = this->audio_channels * this->audio_sample_rate; break; default: xine_log(this->stream->xine, XINE_LOG_MSG, _("demux_snd: unsupported audio type: %d\n"), encoding); return 0; break; } this->running_time = this->audio_frames / this->audio_sample_rate; /* file is qualified; skip over the header bytes in the stream */ if (this->input->seek(this->input, SND_HEADER_SIZE, SEEK_SET) != SND_HEADER_SIZE) return 0; return 1; } static int demux_snd_send_chunk(demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; buf_element_t *buf = NULL; unsigned int remaining_sample_bytes; off_t current_file_pos; int64_t current_pts; /* just load data chunks from wherever the stream happens to be * pointing; issue a DEMUX_FINISHED status if EOF is reached */ remaining_sample_bytes = this->audio_block_align; current_file_pos = this->input->get_current_pos(this->input) - this->data_start; current_pts = current_file_pos; current_pts *= 90000; current_pts /= this->audio_bytes_per_second; if (this->seek_flag) { _x_demux_control_newpts(this->stream, current_pts, BUF_FLAG_SEEK); this->seek_flag = 0; } while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, 8 << 10); buf->type = this->audio_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = current_pts / 90; buf->pts = current_pts; if ((int)remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; /* convert 8-bit signed -> unsigned */ if (this->audio_bits == 8) { int i; for (i = 0; i < buf->size; i++) buf->content[i] += 0x80; } this->audio_fifo->put (this->audio_fifo, buf); } return this->status; } static void demux_snd_send_headers(demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->audio_channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->audio_sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->audio_bits); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo && this->audio_type) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->audio_sample_rate; buf->decoder_info[2] = this->audio_bits; buf->decoder_info[3] = this->audio_channels; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_snd_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_snd_t *this = (demux_snd_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); (void)start_time; (void)playing; this->seek_flag = 1; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* check the boundary offsets */ if (start_pos < 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by * the block alignment integer-wise, and multiply the quotient by the * block alignment to get the new aligned offset. Add the data start * offset and seek to the new position. */ start_pos /= this->audio_block_align; start_pos *= this->audio_block_align; start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); } return this->status; } static int demux_snd_get_status (demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_snd_get_stream_length (demux_plugin_t *this_gen) { demux_snd_t *this = (demux_snd_t *) this_gen; return this->running_time * 1000; } static uint32_t demux_snd_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_snd_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_snd_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_snd_file(input)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_snd_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_snd_send_headers; this->demux_plugin.send_chunk = demux_snd_send_chunk; this->demux_plugin.seek = demux_snd_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_snd_get_status; this->demux_plugin.get_stream_length = demux_snd_get_stream_length; this->demux_plugin.get_capabilities = demux_snd_get_capabilities; this->demux_plugin.get_optional_data = demux_snd_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_snd_file(this)) { free (this); return NULL; } return &this->demux_plugin; } void *demux_snd_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_snd_class = { .open_plugin = open_plugin, .description = N_("SND/AU file demux plugin"), .identifier = "SND/AU", .mimetypes = "audio/basic: snd,au: ULAW (Sun) audio;" "audio/x-basic: snd,au: ULAW (Sun) audio;" "audio/x-pn-au: snd,au: ULAW (Sun) audio;", .extensions = "snd au", .dispose = NULL, }; return (void *)&demux_snd_class; } xine-lib-1.2/src/demuxers/demux_smjpeg.c0000644000175000017500000003425714647725152016155 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * SMJPEG File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information on the SMJPEG file format, visit: * http://www.lokigames.com/development/smjpeg.php3 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include /********** logging **********/ #define LOG_MODULE "demux_smjpeg" /* #define LOG_VERBOSE */ /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" #define FOURCC_TAG BE_FOURCC #define _TXT_TAG FOURCC_TAG('_', 'T', 'X', 'T') #define _SND_TAG FOURCC_TAG('_', 'S', 'N', 'D') #define _VID_TAG FOURCC_TAG('_', 'V', 'I', 'D') #define HEND_TAG FOURCC_TAG('H', 'E', 'N', 'D') #define sndD_TAG FOURCC_TAG('s', 'n', 'd', 'D') #define vidD_TAG FOURCC_TAG('v', 'i', 'd', 'D') #define APCM_TAG FOURCC_TAG('A', 'P', 'C', 'M') /* 16 is the max size of a header chunk (the video header) */ #define SMJPEG_VIDEO_HEADER_SIZE 16 #define SMJPEG_AUDIO_HEADER_SIZE 12 #define SMJPEG_HEADER_CHUNK_MAX_SIZE SMJPEG_VIDEO_HEADER_SIZE #define SMJPEG_CHUNK_PREAMBLE_SIZE 12 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t input_length; /* video information */ unsigned int video_type; xine_bmiheader bih; int64_t last_frame_pts; /* audio information */ unsigned int audio_type; unsigned int audio_sample_rate; unsigned int audio_bits; unsigned int audio_channels; /* playback information */ unsigned int duration; /* duration in milliseconds */ } demux_smjpeg_t; /* returns 1 if the SMJPEG file was opened successfully, 0 otherwise */ static int open_smjpeg_file(demux_smjpeg_t *this) { unsigned int chunk_tag; unsigned char signature[8]; unsigned char header_chunk[SMJPEG_HEADER_CHUNK_MAX_SIZE]; uint32_t audio_codec = 0; static const uint8_t SMJPEG_SIGNATURE[8] = { 0x00, 0x0A, 'S', 'M', 'J', 'P', 'E', 'G' }; if (_x_demux_read_header(this->input, signature, sizeof(SMJPEG_SIGNATURE)) != sizeof(SMJPEG_SIGNATURE)) return 0; if (memcmp(signature, SMJPEG_SIGNATURE, sizeof(SMJPEG_SIGNATURE)) != 0) return 0; /* file is qualified; jump over the header + version to the duration */ if (this->input->seek(this->input, sizeof(SMJPEG_SIGNATURE) + 4, SEEK_SET) < 0) return 0; if (this->input->read(this->input, header_chunk, 4) != 4) return 0; this->duration = _X_BE_32(&header_chunk[0]); /* initial state: no video and no audio (until headers found) */ this->video_type = this->audio_type = 0; this->input_length = this->input->get_length (this->input); /* traverse the header chunks until the HEND tag is found */ chunk_tag = 0; while (chunk_tag != HEND_TAG) { if (this->input->read(this->input, header_chunk, 4) != 4) return 0; chunk_tag = _X_BE_32(&header_chunk[0]); switch(chunk_tag) { case HEND_TAG: /* this indicates the end of the header; do nothing and fall * out of the loop on the next iteration */ break; case _VID_TAG: if (this->input->read(this->input, header_chunk, SMJPEG_VIDEO_HEADER_SIZE) != SMJPEG_VIDEO_HEADER_SIZE) return 0; this->bih.biWidth = _X_BE_16(&header_chunk[8]); this->bih.biHeight = _X_BE_16(&header_chunk[10]); memcpy(&this->bih.biCompression, &header_chunk[12], sizeof(uint32_t)); this->video_type = _x_fourcc_to_buf_video(this->bih.biCompression); if (!this->video_type) _x_report_video_fourcc (this->stream->xine, LOG_MODULE, this->bih.biCompression); break; case _SND_TAG: if (this->input->read(this->input, header_chunk, SMJPEG_AUDIO_HEADER_SIZE) != SMJPEG_AUDIO_HEADER_SIZE) return 0; this->audio_sample_rate = _X_BE_16(&header_chunk[4]); this->audio_bits = header_chunk[6]; this->audio_channels = header_chunk[7]; /* ADPCM in these files is ID'd by 'APCM' which is used in other * files to denote a slightly different format; thus, use the * following special case */ if (_X_BE_32(&header_chunk[8]) == APCM_TAG) { audio_codec = be2me_32(APCM_TAG); this->audio_type = BUF_AUDIO_SMJPEG_IMA; } else { memcpy(&audio_codec, &header_chunk[8], sizeof(uint32_t)); this->audio_type = _x_formattag_to_buf_audio(audio_codec); if (!this->audio_type) _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, audio_codec); } break; default: /* for all other chunk types, read the length and skip the rest * of the chunk */ if (this->input->read(this->input, header_chunk, 4) != 4) return 0; if (this->input->seek(this->input, _X_BE_32(&header_chunk[0]), SEEK_CUR) < 0) return 0; break; } } if(!this->video_type) this->video_type = BUF_VIDEO_UNKNOWN; if(!this->audio_type && audio_codec) this->audio_type = BUF_AUDIO_UNKNOWN; return 1; } static int demux_smjpeg_send_chunk(demux_plugin_t *this_gen) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; buf_element_t *buf = NULL; unsigned int chunk_tag; int64_t pts; unsigned int remaining_sample_bytes; unsigned char preamble[SMJPEG_CHUNK_PREAMBLE_SIZE]; off_t current_file_pos; unsigned int audio_frame_count = 0; /* load the next sample */ current_file_pos = this->input->get_current_pos(this->input); if (this->input->read(this->input, preamble, SMJPEG_CHUNK_PREAMBLE_SIZE) != SMJPEG_CHUNK_PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; /* skip to next while() iteration to bail out */ } chunk_tag = _X_BE_32(&preamble[0]); remaining_sample_bytes = _X_BE_32(&preamble[8]); /* * Each sample has an absolute timestamp in millisecond units: * * xine pts timestamp (ms) * -------- = -------------- * 90000 1000 * * therefore, xine pts = timestamp * 90000 / 1000 => timestamp * 90 * * However, millisecond timestamps are not completely accurate * for the audio samples. These audio chunks usually have 256 bytes, * or 512 nibbles, which corresponds to 512 samples. * * 512 samples * (1 sec / 22050 samples) * (1000 ms / 1 sec) * = 23.2 ms * * where the audio samples claim that each chunk is 23 ms long. * Therefore, manually compute the pts values for the audio samples. */ if (chunk_tag == sndD_TAG) { pts = INT64_C(90000) * audio_frame_count / ((int64_t)this->audio_sample_rate * this->audio_channels); audio_frame_count += ((remaining_sample_bytes - 4) * 2); } else { pts = _X_BE_32(&preamble[4]); pts *= 90; } /* break up the data into packets and dispatch them */ if (((chunk_tag == sndD_TAG) && this->audio_fifo && this->audio_type) || (chunk_tag == vidD_TAG)) { while (remaining_sample_bytes) { if (chunk_tag == sndD_TAG) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; } else { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = this->video_type; } if( this->input_length ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->input_length); buf->extra_info->input_time = pts / 90; buf->extra_info->total_time = this->duration; buf->pts = pts; if (this->last_frame_pts) { buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = buf->pts - this->last_frame_pts; } if (remaining_sample_bytes > (unsigned)buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } /* every frame is a keyframe */ buf->decoder_flags |= BUF_FLAG_KEYFRAME; if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; if (chunk_tag == sndD_TAG) this->audio_fifo->put(this->audio_fifo, buf); else this->video_fifo->put(this->video_fifo, buf); } } else { /* skip the chunk if it can't be handled */ if (this->input->seek(this->input, remaining_sample_bytes, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; return this->status; } } if (chunk_tag == vidD_TAG) this->last_frame_pts = pts; return this->status; } static void demux_smjpeg_send_headers(demux_plugin_t *this_gen) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->audio_channels) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->audio_channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->audio_sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->audio_bits); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = 3000; /* initial video_step */ memcpy(buf->content, &this->bih, sizeof(this->bih)); buf->size = sizeof(this->bih); buf->type = this->video_type; this->video_fifo->put (this->video_fifo, buf); if (this->audio_fifo && this->audio_type) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->audio_sample_rate; buf->decoder_info[2] = this->audio_bits; buf->decoder_info[3] = this->audio_channels; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_smjpeg_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { this->status = DEMUX_OK; } this->last_frame_pts = 0; return this->status; } static int demux_smjpeg_get_status (demux_plugin_t *this_gen) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; return this->status; } static int demux_smjpeg_get_stream_length (demux_plugin_t *this_gen) { demux_smjpeg_t *this = (demux_smjpeg_t *) this_gen; /* return total running time in miliseconds */ return this->duration; } static uint32_t demux_smjpeg_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_smjpeg_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_smjpeg_t *this; if (!INPUT_IS_SEEKABLE(input)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input not seekable, can not handle!\n"); return NULL; } this = calloc(1, sizeof(demux_smjpeg_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_smjpeg_send_headers; this->demux_plugin.send_chunk = demux_smjpeg_send_chunk; this->demux_plugin.seek = demux_smjpeg_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_smjpeg_get_status; this->demux_plugin.get_stream_length = demux_smjpeg_get_stream_length; this->demux_plugin.get_capabilities = demux_smjpeg_get_capabilities; this->demux_plugin.get_optional_data = demux_smjpeg_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_smjpeg_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_smjpeg_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_smjpeg_class = { .open_plugin = open_plugin, .description = N_("SMJPEG file demux plugin"), .identifier = "SMJPEG", .mimetypes = NULL, .extensions = "mjpg", .dispose = NULL, }; return (void *)&demux_smjpeg_class; } xine-lib-1.2/src/demuxers/ebml.c0000644000175000017500000002712214647725152014376 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * EBML parser * a lot of ideas from the gstreamer parser */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #define LOG_MODULE "ebml" #define LOG_VERBOSE /* #define LOG */ #include #include #include "bswap.h" #include "ebml.h" ebml_parser_t *new_ebml_parser (xine_t *xine, input_plugin_t *input) { ebml_parser_t *ebml; ebml = calloc(1, sizeof(ebml_parser_t)); if (ebml) { ebml->xine = xine; ebml->input = input; } return ebml; } void dispose_ebml_parser(ebml_parser_t *ebml) { if (ebml) { _x_freep(&ebml->doctype); free(ebml); } } uint32_t ebml_get_next_level(ebml_parser_t *ebml, ebml_elem_t *elem) { ebml_elem_t *parent_elem; if (ebml->level > 0) { parent_elem = &ebml->elem_stack[ebml->level - 1]; while (/* avoid overflows with undefined len (=UINT64_MAX) */ /* (elem->start + elem->len) >= (parent_elem->start + parent_elem->len) */ (elem->start - parent_elem->start + elem->len) >= parent_elem->len) { lprintf("parent: %" PRIdMAX ", %" PRIu64 "; elem: %" PRIdMAX ", %" PRIu64 "\n", (intmax_t)parent_elem->start, parent_elem->len, (intmax_t)elem->start, elem->len); ebml->level--; if (ebml->level == 0) break; parent_elem = &ebml->elem_stack[ebml->level - 1]; } } lprintf("id: 0x%x, len: %" PRIu64 ", next_level: %d\n", elem->id, elem->len, ebml->level); return ebml->level; } static int ebml_read_elem_id(ebml_parser_t *ebml, uint32_t *id) { uint8_t data[4]; uint32_t mask = 0x80; uint32_t value; int size = 1; int i; if (ebml->input->read(ebml->input, data, 1) != 1) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: read error\n"); return 0; } value = data[0]; /* compute the size of the ID (1-4 bytes)*/ while (size <= 4 && !(value & mask)) { size++; mask >>= 1; } if (size > 4) { off_t pos = ebml->input->get_current_pos(ebml->input); xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: invalid EBML ID size (0x%x) at position %" PRIdMAX "\n", data[0], (intmax_t)pos); return 0; } /* read the rest of the id */ if (ebml->input->read(ebml->input, data + 1, size - 1) != (size - 1)) { off_t pos = ebml->input->get_current_pos(ebml->input); xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos); return 0; } for(i = 1; i < size; i++) { value = (value << 8) | data[i]; } *id = value; return 1; } static int ebml_read_elem_len(ebml_parser_t *ebml, uint64_t *len) { uint8_t data[8]; uint32_t mask = 0x80; int size = 1; int ff_bytes; uint64_t value; int i; if (ebml->input->read(ebml->input, data, 1) != 1) { off_t pos = ebml->input->get_current_pos(ebml->input); xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos); return 0; } value = data[0]; /* compute the size of the "data len" (1-8 bytes) */ while (size <= 8 && !(value & mask)) { size++; mask >>= 1; } if (size > 8) { off_t pos = ebml->input->get_current_pos(ebml->input); xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: Invalid EBML length size (0x%x) at position %" PRIdMAX "\n", data[0], (intmax_t)pos); return 0; } /* remove size bits */ value &= mask - 1; /* check if the first byte is full */ if (value == (mask - 1)) ff_bytes = 1; else ff_bytes = 0; /* read the rest of the len */ if (ebml->input->read(ebml->input, data + 1, size - 1) != (size - 1)) { off_t pos = ebml->input->get_current_pos(ebml->input); xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos); return 0; } for (i = 1; i < size; i++) { if (data[i] == 0xff) ff_bytes++; value = (value << 8) | data[i]; } if (ff_bytes == size) *len = -1; else *len = value; return 1; } static int ebml_read_elem_data(ebml_parser_t *ebml, void *buf, int64_t len) { if (ebml->input->read(ebml->input, buf, len) != len) { off_t pos = ebml->input->get_current_pos(ebml->input); xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: read error at position %" PRIdMAX "\n", (intmax_t)pos); return 0; } return 1; } int ebml_skip(ebml_parser_t *ebml, ebml_elem_t *elem) { if (ebml->input->seek(ebml->input, elem->len, SEEK_CUR) < 0) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: seek error (failed skipping %" PRId64 " bytes)\n", (int64_t)elem->len); return 0; } return 1; } int ebml_read_elem_head(ebml_parser_t *ebml, ebml_elem_t *elem) { int ret_id = ebml_read_elem_id(ebml, &elem->id); int ret_len = ebml_read_elem_len(ebml, &elem->len); elem->start = ebml->input->get_current_pos(ebml->input); return (ret_id && ret_len); } int ebml_read_uint(ebml_parser_t *ebml, ebml_elem_t *elem, uint64_t *num) { uint8_t data[8]; uint64_t size = elem->len; if ((elem->len < 1) || (elem->len > 8)) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: Invalid integer element size %" PRIu64 "\n", size); return 0; } if (!ebml_read_elem_data (ebml, data, size)) return 0; *num = 0; while (size > 0) { *num = (*num << 8) | data[elem->len - size]; size--; } return 1; } #if 0 int ebml_read_sint (ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *num) { uint8_t data[8]; uint64_t size = elem->len; if ((elem->len < 1) || (elem->len > 8)) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: Invalid integer element size %" PRIu64 "\n", size); return 0; } if (!ebml_read_elem_data(ebml, data, size)) return 0; /* propagate negative bit */ if (data[0] & 80) *num = -1; else *num = 0; while (size > 0) { *num = (*num << 8) | data[elem->len - size]; size--; } return 1; } #endif int ebml_read_float (ebml_parser_t *ebml, ebml_elem_t *elem, double *num) { uint8_t data[10]; uint64_t size = elem->len; if ((size != 4) && (size != 8) && (size != 10)) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: Invalid float element size %" PRIu64 "\n", size); return 0; } if (!ebml_read_elem_data(ebml, data, size)) return 0; if (size == 10) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: FIXME! 10-byte floats unimplemented\n"); return 0; } if (size == 4) { union { float f; uint32_t u32; } tmp; tmp.u32 = _X_BE_32(data); *num = tmp.f; } else { union { double d; uint64_t u64; } tmp; tmp.u64 = _X_BE_64(data); *num = tmp.d; } return 1; } int ebml_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem, char *str) { uint64_t size = elem->len; if (!ebml_read_elem_data(ebml, str, size)) return 0; return 1; } #if 0 int ebml_read_utf8 (ebml_parser_t *ebml, ebml_elem_t *elem, char *str) { return ebml_read_ascii (ebml, elem, str); } #endif char *ebml_alloc_read_ascii (ebml_parser_t *ebml, ebml_elem_t *elem) { char *text; if (elem->len >= 4096) return NULL; text = malloc(elem->len + 1); if (text) { text[elem->len] = '\0'; if (ebml_read_ascii (ebml, elem, text)) return text; free (text); } return NULL; } #if 0 int ebml_read_date (ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date) { return ebml_read_sint (ebml, elem, date); } #endif int ebml_read_master (ebml_parser_t *ebml, ebml_elem_t *elem) { ebml_elem_t *top_elem; if (ebml->level < 0) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: invalid current level\n"); return 0; } top_elem = &ebml->elem_stack[ebml->level]; top_elem->start = elem->start; top_elem->len = elem->len; top_elem->id = elem->id; ebml->level++; lprintf("id: 0x%x, len: %" PRIu64 ", level: %d\n", elem->id, elem->len, ebml->level); if (ebml->level >= EBML_STACK_SIZE) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: max level exceeded\n"); return 0; } return 1; } int ebml_read_binary(ebml_parser_t *ebml, ebml_elem_t *elem, void *binary) { return ebml_read_elem_data(ebml, binary, elem->len); } int ebml_check_header(ebml_parser_t *ebml) { uint32_t next_level; ebml_elem_t master; if (!ebml_read_elem_head(ebml, &master)) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: invalid master element\n"); return 0; } if (master.id != EBML_ID_EBML) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: invalid master element 0x%x\n", master.id); return 0; } if (!ebml_read_master (ebml, &master)) return 0; next_level = 1; while (next_level == 1) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case EBML_ID_EBMLVERSION: { uint64_t num; if (!ebml_read_uint (ebml, &elem, &num)) return 0; lprintf("ebml_version: %" PRIu64 "\n", num); ebml->version = num; break; } case EBML_ID_EBMLREADVERSION: { uint64_t num; if (!ebml_read_uint (ebml, &elem, &num)) return 0; lprintf("ebml_read_version: %" PRIu64 "\n", num); if (num != EBML_VERSION) return 0; ebml->read_version = num; break; } case EBML_ID_EBMLMAXIDLENGTH: { uint64_t num; if (!ebml_read_uint (ebml, &elem, &num)) return 0; lprintf("ebml_max_id_length: %" PRIu64 "\n", num); ebml->max_id_len = num; break; } case EBML_ID_EBMLMAXSIZELENGTH: { uint64_t num; if (!ebml_read_uint (ebml, &elem, &num)) return 0; lprintf("ebml_max_size_length: %" PRIu64 "\n", num); ebml->max_size_len = num; break; } case EBML_ID_DOCTYPE: { char *text = ebml_alloc_read_ascii (ebml, &elem); if (!text) return 0; lprintf("doctype: %s\n", text); if (ebml->doctype) free (ebml->doctype); ebml->doctype = text; break; } case EBML_ID_DOCTYPEVERSION: { uint64_t num; if (!ebml_read_uint (ebml, &elem, &num)) return 0; lprintf("doctype_version: %" PRIu64 "\n", num); ebml->doctype_version = num; break; } case EBML_ID_DOCTYPEREADVERSION: { uint64_t num; if (!ebml_read_uint (ebml, &elem, &num)) return 0; lprintf("doctype_read_version: %" PRIu64 "\n", num); ebml->doctype_read_version = num; break; } default: xprintf(ebml->xine, XINE_VERBOSITY_LOG, "ebml: Unknown data type 0x%x in EBML header (ignored)\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } xine-lib-1.2/src/demuxers/demux_aud.c0000644000175000017500000002326114647725152015432 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * Westwood Studios AUD File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the AUD file format, refer to: * http://www.geocities.com/SiliconValley/8682/aud3.txt * * Implementation note: There is no definite file signature in this format. * This demuxer uses a probabilistic strategy for content detection. This * entails performing sanity checks on certain header values in order to * qualify a file. Refer to open_aud_file() for the precise parameters. * * Implementation note #2: The IMA ADPCM data stored in this file format * does not encode any initialization information; decoding parameters are * initialized to 0 at the start of the file and maintained throughout the * data. This makes seeking conceptually impossible. Upshot: Random * seeking is not supported. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_audio.h" #define AUD_HEADER_SIZE 12 #define AUD_CHUNK_PREAMBLE_SIZE 8 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_start; off_t data_size; int audio_samplerate; int audio_channels; int audio_bits; int audio_type; int64_t audio_frame_counter; } demux_aud_t; /* returns 1 if the AUD file was opened successfully, 0 otherwise */ static int open_aud_file(demux_aud_t *this) { unsigned char header[AUD_HEADER_SIZE]; if (_x_demux_read_header(this->input, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE) return 0; /* Probabilistic content detection strategy: There is no file signature * so perform sanity checks on various header parameters: * 8000 <= sample rate (16 bits) <= 48000 ==> 40001 acceptable numbers * compression type (8 bits) = 1 or 99 ==> 2 acceptable numbers * There is a total of 24 bits. The number space contains 2^24 = * 16777216 numbers. There are 40001 * 2 = 80002 acceptable combinations * of numbers. There is a 80002/16777216 = 0.48% chance of a false * positive. */ this->audio_samplerate = _X_LE_16(&header[0]); if ((this->audio_samplerate < 8000) || (this->audio_samplerate > 48000)) return 0; #if 0 note: This loose content detection strategy is causing a few false positives; remove this case for the time being since this audio type is not supported anyway. if (header[11] == 1) this->audio_type = BUF_AUDIO_WESTWOOD; else #endif if (header[11] == 99) this->audio_type = BUF_AUDIO_VQA_IMA; else return 0; /* file is qualified; skip over the header bytes in the stream */ if (this->input->seek(this->input, AUD_HEADER_SIZE, SEEK_SET) != AUD_HEADER_SIZE) return 0; /* flag 0 indicates stereo */ this->audio_channels = (header[10] & 0x1) + 1; /* flag 1 indicates 16 bit audio */ this->audio_bits = (((header[10] & 0x2) >> 1) + 1) * 8; this->data_start = AUD_HEADER_SIZE; this->data_size = this->input->get_length(this->input) - this->data_start; this->audio_frame_counter = 0; return 1; } static int demux_aud_send_chunk(demux_plugin_t *this_gen) { demux_aud_t *this = (demux_aud_t *) this_gen; unsigned char chunk_preamble[AUD_CHUNK_PREAMBLE_SIZE]; int chunk_size; off_t current_file_pos; int64_t audio_pts; buf_element_t *buf; if (this->input->read(this->input, chunk_preamble, AUD_CHUNK_PREAMBLE_SIZE) != AUD_CHUNK_PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } /* validate the chunk */ if (!_x_is_fourcc(&chunk_preamble[4], "\xAF\xDE\x00\x00")) { this->status = DEMUX_FINISHED; return this->status; } chunk_size = _X_LE_16(&chunk_preamble[0]); current_file_pos = this->input->get_current_pos(this->input) - this->data_start; /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ this->audio_frame_counter += (chunk_size * 2) / this->audio_channels; audio_pts = this->audio_frame_counter; audio_pts *= 90000; audio_pts /= this->audio_samplerate; while (chunk_size) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = audio_pts / 90; buf->pts = audio_pts; if (chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); } return this->status; } static void demux_aud_send_headers(demux_plugin_t *this_gen) { demux_aud_t *this = (demux_aud_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->audio_channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->audio_samplerate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->audio_bits); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to the audio decoder */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->audio_samplerate; buf->decoder_info[2] = this->audio_bits; buf->decoder_info[3] = this->audio_channels; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_aud_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_aud_t *this = (demux_aud_t *) this_gen; (void)start_pos; (void)start_time; (void)playing; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* no seeking yet */ return this->status; } static int demux_aud_get_status (demux_plugin_t *this_gen) { demux_aud_t *this = (demux_aud_t *) this_gen; return this->status; } static int demux_aud_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_aud_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_aud_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_aud_t *this; this = calloc(1, sizeof(demux_aud_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_aud_send_headers; this->demux_plugin.send_chunk = demux_aud_send_chunk; this->demux_plugin.seek = demux_aud_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_aud_get_status; this->demux_plugin.get_stream_length = demux_aud_get_stream_length; this->demux_plugin.get_capabilities = demux_aud_get_capabilities; this->demux_plugin.get_optional_data = demux_aud_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: /* no reliable detection */ case METHOD_BY_MRL: case METHOD_EXPLICIT: if (!open_aud_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_aud_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_aud_class = { .open_plugin = open_plugin, .description = N_("Westwood Studios AUD file demux plugin"), .identifier = "Westwood Studios AUD", .mimetypes = NULL, .extensions = "aud", .dispose = NULL, }; return (void *)&demux_aud_class; } xine-lib-1.2/src/demuxers/demux_eawve.c0000644000175000017500000002532314647725152015771 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demux_eawve.c, Demuxer plugin for Electronic Arts' WVE file format * * written and currently maintained by Robin Kay */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #define LOG_MODULE "demux_eawve" #define LOG_VERBOSE /* #define LOG */ #include #include #include "bswap.h" #include #include "group_games.h" #define FOURCC_TAG BE_FOURCC typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int thread_running; int num_channels; int compression_type; int num_samples; int sample_counter; } demux_eawve_t; typedef struct { uint32_t id; uint32_t size; } chunk_header_t; /* * Read an arbitary number of byte into a word */ static uint32_t read_arbitary(input_plugin_t *input){ uint8_t size; if (input->read(input, (void*)&size, 1) != 1) { return 0; } uint32_t word = 0; int i; for (i=0;iread(input, (void*)&byte, 1) != 1) { return 0; } word <<= 8; word |= byte; } return word; } /* * Process WVE file header * Returns 1 if the WVE file is valid and successfully opened, 0 otherwise */ static int process_header(demux_eawve_t *this){ uint8_t header[12]; if (this->input->get_current_pos(this->input) != 0) if (this->input->seek(this->input, 0, SEEK_SET) != 0) return 0; if (this->input->read(this->input, header, sizeof(header)) != sizeof(header)) return 0; if (!_x_is_fourcc(&header[0], "SCHl")) return 0; if (!_x_is_fourcc(&header[8], "PT\0\0")) { lprintf("PT header missing\n"); return 0; } const uint32_t size = _X_LE_32(&header[4]); int inHeader = 1; while (inHeader) { int inSubheader; uint8_t byte; if (this->input->read(this->input, (void*)&byte, 1) != 1) { return 0; } switch (byte) { case 0xFD: lprintf("entered audio subheader\n"); inSubheader = 1; while (inSubheader) { uint8_t subbyte; if (this->input->read(this->input, (void*)&subbyte, 1) != 1) { return 0; } switch (subbyte) { case 0x82: this->num_channels = read_arbitary(this->input); lprintf("num_channels (element 0x82) set to 0x%08x\n", this->num_channels); break; case 0x83: this->compression_type = read_arbitary(this->input); lprintf("compression_type (element 0x83) set to 0x%08x\n", this->compression_type); break; case 0x85: this->num_samples = read_arbitary(this->input); lprintf("num_samples (element 0x85) set to 0x%08x\n", this->num_samples); break; default: lprintf("element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(this->input)); break; case 0x8A: lprintf("element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(this->input)); lprintf("exited audio subheader\n"); inSubheader = 0; break; } } break; default: lprintf("header element 0x%02x set to 0x%08x\n", byte, read_arbitary(this->input)); break; case 0xFF: lprintf("end of header block reached\n"); inHeader = 0; break; } } if ((this->num_channels != 2) || (this->compression_type != 7)) { lprintf("unsupported stream type\n"); return 0; } if (this->input->seek(this->input, size - this->input->get_current_pos(this->input), SEEK_CUR) < 0) { return 0; } return 1; } /* * !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! * All the following functions are defined by the xine demuxer API * !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! */ static int demux_eawve_send_chunk(demux_plugin_t *this_gen){ demux_eawve_t *this = (demux_eawve_t *)this_gen; chunk_header_t header; if (this->input->read(this->input, (void*)&header, sizeof(chunk_header_t)) != sizeof(chunk_header_t)) { lprintf("read error\n"); this->status = DEMUX_FINISHED; return this->status; } header.id = be2me_32(header.id); header.size = le2me_32(header.size) - 8; switch (header.id) { case FOURCC_TAG('S', 'C', 'D', 'l'): { int first_segment = 1; while (header.size > 0) { buf_element_t *buf; buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_EA_ADPCM; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); buf->extra_info->input_time = (int)((int64_t)this->sample_counter * 1000 / 22050); buf->pts = this->sample_counter; buf->pts *= 90000; buf->pts /= 22050; if ((int)(header.size) > buf->max_size) { buf->size = buf->max_size; } else { buf->size = header.size; } header.size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { lprintf("read error\n"); this->status = DEMUX_FINISHED; buf->free_buffer(buf); break; } if (first_segment) { buf->decoder_flags |= BUF_FLAG_FRAME_START; this->sample_counter += _X_LE_32(buf->content); first_segment = 0; } if (header.size == 0) { buf->decoder_flags |= BUF_FLAG_FRAME_END; } this->audio_fifo->put(this->audio_fifo, buf); } } break; case FOURCC_TAG('S', 'C', 'E', 'l'): { this->status = DEMUX_FINISHED; } break; default: { if (this->input->seek(this->input, header.size, SEEK_CUR) < 0) { lprintf("read error\n"); this->status = DEMUX_FINISHED; } } break; } return this->status; } static void demux_eawve_send_headers(demux_plugin_t *this_gen){ demux_eawve_t *this = (demux_eawve_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, 2); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, 22050); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, 16); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf_element_t *buf; buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_EA_ADPCM; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = 22050; buf->decoder_info[2] = 16; buf->decoder_info[3] = 2; this->audio_fifo->put(this->audio_fifo, buf); } } static int demux_eawve_seek(demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing){ demux_eawve_t *this = (demux_eawve_t *)this_gen; (void)start_pos; (void)start_time; (void)playing; if (!this->thread_running) { _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; this->sample_counter = 0; this->thread_running = 1; } return this->status; } static int demux_eawve_get_status(demux_plugin_t *this_gen){ demux_eawve_t *this = (demux_eawve_t *)this_gen; return this->status; } static int demux_eawve_get_stream_length(demux_plugin_t *this_gen){ demux_eawve_t *this = (demux_eawve_t *)this_gen; return (int)((int64_t)this->num_samples * 1000 / 22050); } static uint32_t demux_eawve_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_eawve_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input){ demux_eawve_t *this; if (!INPUT_IS_SEEKABLE(input)) return NULL; this = calloc(1, sizeof(demux_eawve_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_eawve_send_headers; this->demux_plugin.send_chunk = demux_eawve_send_chunk; this->demux_plugin.seek = demux_eawve_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_eawve_get_status; this->demux_plugin.get_stream_length = demux_eawve_get_stream_length; this->demux_plugin.get_capabilities = demux_eawve_get_capabilities; this->demux_plugin.get_optional_data = demux_eawve_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!process_header(this)) { free(this); return NULL; } break; default: free(this); return NULL; } return &this->demux_plugin; } void *demux_eawve_init_plugin(xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_eawve_class = { .open_plugin = open_plugin, .description = N_("Electronics Arts WVE format demux plugin"), .identifier = "EA WVE", .mimetypes = NULL, .extensions = "wve", .dispose = NULL, }; return (void *)&demux_eawve_class; } xine-lib-1.2/src/demuxers/demux_mod.c0000644000175000017500000003052714647725152015443 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * MOD File "demuxer" by Paul Eggleton (bluelightning@bluelightning.org) * This is really just a loader for Amiga MOD (and similar) music files * which reads an entire MOD file and passes it over to the ModPlug library * for playback. * * This file was based on demux_nsf.c by Mike Melanson. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include /********** logging **********/ #define LOG_MODULE "demux_mod" /* #define LOG_VERBOSE */ /* #define LOG */ #include #include #include #include #include #include "bswap.h" #define MOD_SAMPLERATE 44100 #define MOD_BITS 16 #define MOD_CHANNELS 2 #define OUT_BYTES_PER_SECOND (MOD_SAMPLERATE * MOD_CHANNELS * (MOD_BITS >> 3)) #define BLOCK_SIZE 4096 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; int status; char *title; char *artist; char *copyright; char *buffer; int64_t current_pts; ModPlug_Settings settings; ModPlugFile *mpfile; int mod_length; int seek_flag; /* this is set when a seek just occurred */ } demux_mod_t; #define FOURCC_32(a, b, c, d) (d + (c<<8) + (b<<16) + (a<<24)) /** * @brief Probes if the given file can be demuxed using modplug or not * @retval 0 The file is not a valid modplug file (or the probe isn't complete yet) * @retval 1 The file has been identified as a valid modplug file * @todo Just Protracker files are detected right now. */ static int probe_mod_file(input_plugin_t *input) { /* We need the value present at offset 1080, of size 4 */ union { uint8_t buffer[1080+4]; /* The raw buffer */ uint32_t values[(1080+4)/sizeof(uint32_t)]; } header; if (_x_demux_read_header(input, header.buffer, 1080+4) != 1080+4) return 0; /* Magic numbers taken from GNU file's magic description */ switch( _X_ABE_32(header.values + (1080/sizeof(uint32_t))) ) { case FOURCC_32('M', '.', 'K', '.'): /* 4-channel Protracker module sound data */ case FOURCC_32('M', '!', 'K', '!'): /* 4-channel Protracker module sound data */ case FOURCC_32('F', 'L', 'T', '4'): /* 4-channel Startracker module sound data */ case FOURCC_32('F', 'L', 'T', '8'): /* 8-channel Startracker module sound data */ case FOURCC_32('4', 'C', 'H', 'N'): /* 4-channel Fasttracker module sound data */ case FOURCC_32('6', 'C', 'H', 'N'): /* 6-channel Fasttracker module sound data */ case FOURCC_32('8', 'C', 'H', 'N'): /* 8-channel Fasttracker module sound data */ case FOURCC_32('C', 'D', '8', '1'): /* 8-channel Octalyser module sound data */ case FOURCC_32('O', 'K', 'T', 'A'): /* 8-channel Oktalyzer module sound data */ case FOURCC_32('1', '6', 'C', 'N'): /* 16-channel Taketracker module sound data */ case FOURCC_32('3', '2', 'C', 'N'): /* 32-channel Taketracker module sound data */ return 1; } /* ScreamTracker 2 */ if (!memcmp (header.buffer + 20, "!Scream!", 7)) return 1; /* ScreamTracker 3 */ if (_X_ABE_32(header.values + 0x2C / sizeof (uint32_t)) == FOURCC_32('S', 'C', 'R', 'M')) return 1; return 0; } /* returns 1 if the MOD file was opened successfully, 0 otherwise */ static int open_mod_file(demux_mod_t *this, input_plugin_t *input) { off_t total_read; off_t input_length; /* Get size and create buffer */ input_length = input->get_length(input); /* Avoid potential issues with signed variables and e.g. read() returning -1 */ if (input_length > 0x7FFFFFFF || input_length < 0) { xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - size overflow\n"); return 0; } this->buffer = malloc(input_length); if(!this->buffer) { xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - allocation failure\n"); return 0; } /* Seek to beginning */ input->seek(input, 0, SEEK_SET); /* Read data */ total_read = input->read(input, this->buffer, input_length); if (total_read != input_length) { xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - filesize error\n"); return 0; } /* Set up modplug engine */ ModPlug_GetSettings(&this->settings); this->settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; /* RESAMP */ this->settings.mChannels = MOD_CHANNELS; this->settings.mBits = MOD_BITS; this->settings.mFrequency = MOD_SAMPLERATE; ModPlug_SetSettings(&this->settings); this->mpfile = ModPlug_Load(this->buffer, input_length); if (this->mpfile==NULL) { xine_log(this->stream->xine, XINE_LOG_PLUGIN, "modplug - load error\n"); return 0; } this->title = strdup(ModPlug_GetName(this->mpfile)); this->artist = strdup(""); this->copyright = strdup(""); this->mod_length = ModPlug_GetLength(this->mpfile); if (this->mod_length < 1) this->mod_length = 1; /* avoids -ve & div-by-0 */ return 1; } static int demux_mod_send_chunk(demux_plugin_t *this_gen) { demux_mod_t *this = (demux_mod_t *) this_gen; buf_element_t *buf; int mlen; buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_LE; mlen = ModPlug_Read(this->mpfile, buf->content, buf->max_size); if (mlen == 0) { this->status = DEMUX_FINISHED; buf->free_buffer(buf); } else { buf->size = mlen; buf->pts = this->current_pts; buf->extra_info->input_time = buf->pts / 90; buf->extra_info->input_normpos = buf->extra_info->input_time * 65535 / this->mod_length; buf->decoder_flags = BUF_FLAG_FRAME_END; if (this->seek_flag) { _x_demux_control_newpts(this->stream, buf->pts, BUF_FLAG_SEEK); this->seek_flag = 0; } this->audio_fifo->put (this->audio_fifo, buf); this->current_pts += 90000 * mlen / OUT_BYTES_PER_SECOND; } return this->status; } static void demux_mod_send_headers(demux_plugin_t *this_gen) { demux_mod_t *this = (demux_mod_t *) this_gen; buf_element_t *buf; char copyright[100]; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, MOD_CHANNELS); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, MOD_SAMPLERATE); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, MOD_BITS); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->title); _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->artist); snprintf(copyright, 100, "(C) %s", this->copyright); _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, copyright); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to the audio decoder */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_LE; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = MOD_SAMPLERATE; buf->decoder_info[2] = MOD_BITS; buf->decoder_info[3] = MOD_CHANNELS; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } static int demux_mod_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mod_t *this = (demux_mod_t *) this_gen; int64_t seek_millis; (void)playing; if (start_pos) { seek_millis = this->mod_length; seek_millis *= start_pos; seek_millis /= 65535; } else { seek_millis = start_time; } _x_demux_flush_engine(this->stream); ModPlug_Seek(this->mpfile, seek_millis); this->current_pts = seek_millis * 90; this->seek_flag = 1; return this->status; } static void demux_mod_dispose (demux_plugin_t *this_gen) { demux_mod_t *this = (demux_mod_t *) this_gen; if (this->mpfile) ModPlug_Unload(this->mpfile); _x_freep(&this->buffer); _x_freep(&this->title); _x_freep(&this->artist); _x_freep(&this->copyright); free(this); } static int demux_mod_get_status (demux_plugin_t *this_gen) { demux_mod_t *this = (demux_mod_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_mod_get_stream_length (demux_plugin_t *this_gen) { demux_mod_t *this = (demux_mod_t *) this_gen; return ModPlug_GetLength(this->mpfile); } static uint32_t demux_mod_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mod_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_mod_t *this; if (!INPUT_IS_SEEKABLE(input)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input not seekable, can not handle!\n"); return NULL; } switch (stream->content_detection_method) { case METHOD_EXPLICIT: case METHOD_BY_MRL: case METHOD_BY_CONTENT: if (!probe_mod_file(input)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_mod_t)); if (!this) return NULL; this->stream = stream; this->demux_plugin.send_headers = demux_mod_send_headers; this->demux_plugin.send_chunk = demux_mod_send_chunk; this->demux_plugin.seek = demux_mod_seek; this->demux_plugin.dispose = demux_mod_dispose; this->demux_plugin.get_status = demux_mod_get_status; this->demux_plugin.get_stream_length = demux_mod_get_stream_length; this->demux_plugin.get_capabilities = demux_mod_get_capabilities; this->demux_plugin.get_optional_data = demux_mod_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "TEST mod decode\n"); if (!open_mod_file(this, input)) { demux_mod_dispose(&this->demux_plugin); return NULL; } return &this->demux_plugin; } static void *demux_mod_init_plugin (xine_t *xine, const void *data) { static const demux_class_t demux_mod_class = { .open_plugin = open_plugin, .description = N_("ModPlug Amiga MOD Music file demux plugin"), .identifier = "mod", .mimetypes = "audio/x-mod: mod: SoundTracker/NoiseTracker/ProTracker Module;" "audio/mod: mod: SoundTracker/NoiseTracker/ProTracker Module;" "audio/it: it: ImpulseTracker Module;" "audio/x-it: it: ImpulseTracker Module;" "audio/x-stm: stm: ScreamTracker 2 Module;" "audio/x-s3m: s3m: ScreamTracker 3 Module;" "audio/s3m: s3m: ScreamTracker 3 Module;" "application/playerpro: 669: 669 Tracker Module;" "application/adrift: amf: ADRIFT Module File;" "audio/med: med: Amiga MED/OctaMED Tracker Module Sound File;" "audio/x-amf: amf: ADRIFT Module File;" "audio/x-xm: xm: FastTracker II Audio;" "audio/xm: xm: FastTracker II Audio;", .extensions = "mod it stm s3m 669 amf med mdl xm", .dispose = NULL, }; (void)xine; (void)data; return (void *)&demux_mod_class; } static const demuxer_info_t demux_info_mod = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_DEMUX, 27, "modplug", XINE_VERSION_CODE, &demux_info_mod, demux_mod_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_mpc.c0000644000175000017500000002405314647725152015440 0ustar meme/* * Copyright (C) 2005-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Musepack demuxer by James Stembridge * * TODO: * ID3 tag reading * APE tag reading * Seeking?? */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_mpc" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_audio.h" #include "id3.h" /* Note that the header is actually 25 bytes long, so we'd only read 28 * (because of byte swapping we have to round up to nearest multiple of 4) * if it weren't for libmusepack reading 32 bytes when it parses the header */ #define HEADER_SIZE 32 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int start; unsigned char header[HEADER_SIZE]; unsigned int frames; double samplerate; unsigned int length; unsigned int current_frame; unsigned int next_frame_bits; } demux_mpc_t; /* Open a musepack file * This function is called from the _open() function of this demuxer. * It returns 1 if the musepack file was opened successfully. */ static int open_mpc_file(demux_mpc_t *this) { unsigned int first_frame_size; unsigned int id3v2_size = 0; /* Read the file header */ this->start = xine_parse_id3v2_tag (this->stream, this->input); if (_x_demux_read_header(this->input, this->header, HEADER_SIZE) != HEADER_SIZE) return 0; /* Validate signature - We only support SV 7.x at the moment */ if ( memcmp(this->header, "MP+", 3) != 0 || ((this->header[3]&0x0f) != 0x07)) return 0; /* Get frame count */ this->current_frame = 0; this->frames = _X_LE_32(&this->header[4]); lprintf("number of frames: %u\n", this->frames); /* Get sample rate */ switch ((_X_LE_32(&this->header[8]) >> 16) & 0x3) { case 0: this->samplerate = 44.1; break; case 1: this->samplerate = 48.0; break; case 2: this->samplerate = 37.8; break; case 3: this->samplerate = 32.0; break; default: break; } lprintf("samplerate: %f kHz\n", this->samplerate); /* Calculate stream length */ this->length = (int) ((double) this->frames * 1152 / this->samplerate); lprintf("stream length: %d ms\n", this->length); /* Calculate the number of bits of the first frame that are still be sent */ first_frame_size = (_X_LE_32(&this->header[24]) >> 4) & 0xFFFFF; this->next_frame_bits = first_frame_size - 4; lprintf("first frame size: %u\n", first_frame_size); /* Move input to start of data (to nearest multiple of 4) */ if (this->input->seek(this->input, 28+id3v2_size, SEEK_SET) < 0) return 0; /* Set stream info */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, _X_ME_32(this->header)); return 1; } static int demux_mpc_send_chunk(demux_plugin_t *this_gen) { demux_mpc_t *this = (demux_mpc_t *) this_gen; unsigned int bits_to_read, bytes_to_read, extra_bits_read, next_frame_size; off_t bytes_read; buf_element_t *buf = NULL; /* Check if we've finished */ if (this->current_frame++ == this->frames) { lprintf("all frames read\n"); this->status = DEMUX_FINISHED; return this->status; } lprintf("current frame: %u\n", this->current_frame); /* Get a buffer */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_MPC; buf->pts = 0; buf->extra_info->total_time = this->length; /* Set normalised position */ buf->extra_info->input_normpos = (int) ((double) this->input->get_current_pos(this->input) * 65535 / this->input->get_length(this->input)); /* Set time based on there being 1152 audio frames per frame */ buf->extra_info->input_time = (int) ((double) this->current_frame * 1152 / this->samplerate); /* Calculate the number of bits that need to be read to finish reading * the current frame and read the size of the next frame. This number * has to be rounded up to the nearest 4 bytes on account of the * byte swapping used */ bits_to_read = (this->next_frame_bits+20+31) & ~31; bytes_to_read = bits_to_read / 8; /* Check we'll be able to read directly into the buffer */ if ((int)bytes_to_read > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("demux_mpc: frame too big for buffer")); this->status = DEMUX_FINISHED; return this->status; } /* Read data */ bytes_read = this->input->read(this->input, buf->content, bytes_to_read); if(bytes_read <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } else buf->size = bytes_read; /* Read the size of the next frame */ if (this->current_frame < this->frames) { /* The number of bits of the next frame we've read */ extra_bits_read = bits_to_read - (this->next_frame_bits+20); if(extra_bits_read <= 12) next_frame_size = (_X_LE_32(&buf->content[bytes_to_read-4]) >> extra_bits_read) & 0xFFFFF; else next_frame_size = ((_X_LE_32(&buf->content[bytes_to_read-8]) << (32-extra_bits_read)) | (_X_LE_32(&buf->content[bytes_to_read-4]) >> extra_bits_read)) & 0xFFFFF; lprintf("next frame size: %u\n", next_frame_size); /* The number of bits of the next frame still to read */ this->next_frame_bits = next_frame_size - extra_bits_read; } /* Each buffer contains at least one frame */ buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put(this->audio_fifo, buf); return this->status; } static void demux_mpc_send_headers(demux_plugin_t *this_gen) { demux_mpc_t *this = (demux_mpc_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* Send start buffers */ _x_demux_control_start(this->stream); /* Send header to decoder */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_MPC; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->input->get_length(this->input); buf->decoder_info[1] = 0; buf->decoder_info[2] = 0; buf->decoder_info[3] = 0; /* Copy the header */ buf->size = HEADER_SIZE; memcpy(buf->content, this->header, buf->size); this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_mpc_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mpc_t *this = (demux_mpc_t *) this_gen; (void)start_pos; (void)start_time; /* If thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static int demux_mpc_get_status (demux_plugin_t *this_gen) { demux_mpc_t *this = (demux_mpc_t *) this_gen; return this->status; } static int demux_mpc_get_stream_length (demux_plugin_t *this_gen) { // demux_mpc_t *this = (demux_mpc_t *) this_gen; (void)this_gen; return 0; } static uint32_t demux_mpc_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mpc_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_mpc_t *this; this = calloc(1, sizeof(demux_mpc_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_mpc_send_headers; this->demux_plugin.send_chunk = demux_mpc_send_chunk; this->demux_plugin.seek = demux_mpc_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_mpc_get_status; this->demux_plugin.get_stream_length = demux_mpc_get_stream_length; this->demux_plugin.get_capabilities = demux_mpc_get_capabilities; this->demux_plugin.get_optional_data = demux_mpc_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_mpc_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_mpc_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_mpc_class = { .open_plugin = open_plugin, .description = N_("Musepack demux plugin"), .identifier = "Musepack", .mimetypes = "audio/musepack: mpc, mp+, mpp: Musepack audio;" "audio/x-musepack: mpc, mp+, mpp: Musepack audio;", .extensions = "mpc mp+ mpp", .dispose = NULL, }; return (void *)&demux_mpc_class; } xine-lib-1.2/src/demuxers/flacutils.h0000644000175000017500000000530214647725152015446 0ustar meme/* * Copyright (C) 2006-2007 the xine project * Based on the FLAC File Demuxer by Mike Melanson * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef __FLACUTILS_H__ #define __FLACUTILS_H__ typedef struct { off_t offset; int64_t sample_number; int64_t pts; int size; } flac_seekpoint_t; #define FLAC_SIGNATURE_SIZE 4 #define FLAC_STREAMINFO_SIZE 34 #define FLAC_SEEKPOINT_SIZE 18 enum { FLAC_BLOCKTYPE_STREAMINFO, FLAC_BLOCKTYPE_PADDING, FLAC_BLOCKTYPE_APPLICATION, FLAC_BLOCKTYPE_SEEKTABLE, FLAC_BLOCKTYPE_VORBIS_COMMENT, FLAC_BLOCKTYPE_CUESHEET, FLAC_BLOCKTYPE_INVALID = 127 }; /* * WARNING: These structures are *not* using the same format * used by FLAC files, bitwise. * * Using bitfields to read the whole data is unfeasible because * of endianness problems with non-byte-aligned values. */ typedef struct { uint8_t last; uint8_t blocktype; uint32_t length; } xine_flac_metadata_header; typedef struct { uint16_t blocksize_min; uint16_t blocksize_max; uint32_t framesize_min; uint32_t framesize_max; uint32_t samplerate; uint8_t channels; uint8_t bits_per_sample; uint64_t total_samples; uint8_t md5[16]; } xine_flac_streaminfo_block; static inline void _x_parse_flac_metadata_header(uint8_t *buffer, xine_flac_metadata_header *parsed) { parsed->last = buffer[0] & 0x80 ? 1 : 0; parsed->blocktype = buffer[0] & 0x7f; parsed->length = _X_BE_24(&buffer[1]); } static inline void _x_parse_flac_streaminfo_block(uint8_t *buffer, xine_flac_streaminfo_block *parsed) { parsed->blocksize_min = _X_BE_16(&buffer[0]); parsed->blocksize_max = _X_BE_16(&buffer[2]); parsed->framesize_min = _X_BE_24(&buffer[4]); parsed->framesize_max = _X_BE_24(&buffer[7]); parsed->samplerate = _X_BE_32(&buffer[10]); parsed->channels = ((parsed->samplerate >> 9) & 0x07) + 1; parsed->bits_per_sample = ((parsed->samplerate >> 4) & 0x1F) + 1; parsed->samplerate >>= 12; parsed->total_samples = _X_BE_64(&buffer[10]) & UINT64_C(0x0FFFFFFFFF); /* 36 bits */ } #endif xine-lib-1.2/src/demuxers/Makefile.am0000644000175000017500000000634514647725152015353 0ustar memeinclude $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) noinst_LTLIBRARIES = libasfheader.la libasfheader_la_SOURCES = asfheader.c asfheader.h ## # IMPORTANT: # --------- # All of xine demuxer plugins should be named like the scheme "xineplug_dmx_" if ENABLE_ASF asf_module = xineplug_dmx_asf.la endif if ENABLE_MNG mng_module = xineplug_dmx_mng.la endif if ENABLE_MODPLUG modplug_module = xineplug_dmx_modplug.la endif if BUILD_DMX_IMAGE image_module = xineplug_dmx_image.la endif xineplug_LTLIBRARIES = \ $(asf_module) \ $(mng_module) \ $(image_module) \ $(modplug_module) \ xineplug_dmx_audio.la \ xineplug_dmx_fli.la \ xineplug_dmx_games.la \ xineplug_dmx_nsv.la \ xineplug_dmx_playlist.la \ xineplug_dmx_pva.la \ xineplug_dmx_slave.la \ xineplug_dmx_video.la xineplug_dmx_video_la_SOURCES = \ group_video.c \ group_video.h \ demux_avi.c \ demux_elem.c \ iff.h \ demux_iff.c \ demux_ivf.c \ demux_matroska.c \ demux_matroska.h \ demux_matroska-chapters.c \ demux_mpeg.c \ demux_mpeg_block.c \ demux_mpeg_pes.c \ demux_qt.c \ demux_rawdv.c \ demux_real.c \ demux_real_common.h \ demux_ts.c \ demux_vc1es.c \ demux_flv.c \ demux_yuv_frames.c \ demux_yuv4mpeg2.c \ ebml.c \ ebml.h \ matroska.h \ qtpalette.h xineplug_dmx_video_la_CFLAGS = $(AM_CFLAGS) xineplug_dmx_video_la_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CPPFLAGS) xineplug_dmx_video_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(ZLIB_LIBS) xineplug_dmx_asf_la_SOURCES = demux_asf.c xineplug_dmx_asf_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(LTLIBICONV) libasfheader.la xineplug_dmx_fli_la_SOURCES = demux_fli.c xineplug_dmx_fli_la_LIBADD = $(XINE_LIB) xineplug_dmx_mng_la_SOURCES = demux_mng.c xineplug_dmx_mng_la_LIBADD = $(XINE_LIB) $(ZLIB_LIBS) $(MNG_LIBS) xineplug_dmx_mng_la_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CPPFLAGS) xineplug_dmx_pva_la_SOURCES = demux_pva.c xineplug_dmx_pva_la_LIBADD = $(XINE_LIB) xineplug_dmx_games_la_SOURCES = \ group_games.c \ group_games.h \ demux_4xm.c \ demux_eawve.c \ demux_film.c \ demux_idcin.c \ demux_ipmovie.c \ demux_roq.c \ demux_smjpeg.c \ demux_str.c \ demux_vmd.c \ demux_vqa.c \ demux_wc3movie.c xineplug_dmx_games_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_dmx_audio_la_SOURCES = \ group_audio.c \ group_audio.h \ demux_aac.c \ demux_ac3.c \ demux_aiff.c \ demux_aud.c \ demux_cdda.c \ demux_dts.c \ demux_flac.c \ demux_mpc.c \ demux_mpgaudio.c \ demux_realaudio.c \ demux_real_common.h \ demux_shn.c \ demux_snd.c \ demux_tta.c \ demux_voc.c \ demux_vox.c \ demux_wav.c \ flacutils.h \ id3.h xineplug_dmx_audio_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_dmx_modplug_la_SOURCES = demux_mod.c xineplug_dmx_modplug_la_LIBADD = $(XINE_LIB) $(LIBMODPLUG_LIBS) xineplug_dmx_modplug_la_CFLAGS = $(AM_CFLAGS) $(LIBMODPLUG_CFLAGS) xineplug_dmx_slave_la_SOURCES = demux_slave.c xineplug_dmx_slave_la_LIBADD = $(XINE_LIB) xineplug_dmx_image_la_SOURCES = demux_image.c xineplug_dmx_image_la_LIBADD = $(XINE_LIB) xineplug_dmx_nsv_la_SOURCES = demux_nsv.c xineplug_dmx_nsv_la_LIBADD = $(XINE_LIB) xineplug_dmx_playlist_la_SOURCES = demux_playlist.c xineplug_dmx_playlist_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xine-lib-1.2/src/demuxers/group_audio.h0000644000175000017500000000370514647725152016002 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_GROUP_AUDIO_H #define HAVE_GROUP_AUDIO_H #include void *demux_aac_init_plugin (xine_t *xine, const void *data); void *demux_ac3_init_plugin (xine_t *xine, const void *data); void *demux_aud_init_plugin (xine_t *xine, const void *data); void *demux_aiff_init_plugin (xine_t *xine, const void *data); void *demux_cdda_init_plugin (xine_t *xine, const void *data); void *demux_dts_init_plugin (xine_t *xine, const void *data); void *demux_flac_init_plugin (xine_t *xine, const void *data); void *demux_mpgaudio_init_class (xine_t *xine, const void *data); void *demux_mpc_init_plugin (xine_t *xine, const void *data); void *demux_realaudio_init_plugin (xine_t *xine, const void *data); void *demux_shn_init_plugin (xine_t *xine, const void *data); void *demux_snd_init_plugin (xine_t *xine, const void *data); void *demux_tta_init_plugin (xine_t *xine, const void *data); void *demux_voc_init_plugin (xine_t *xine, const void *data); void *demux_vox_init_plugin (xine_t *xine, const void *data); void *demux_wav_init_plugin (xine_t *xine, const void *data); #endif xine-lib-1.2/src/demuxers/demux_voc.c0000644000175000017500000002471714647725152015457 0ustar meme/* * Copyright (C) 2001-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * Creative Voice File Demuxer by Mike Melanson (melanson@pcisys.net) * Note that this demuxer does not yet support very many things that can * possibly be seen in a VOC file. It only plays the first block in a file. * It will only play that block if it is PCM data. More variations will be * supported as they are encountered. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_audio.h" #define PCM_BLOCK_ALIGN 1024 #define VOC_HEADER_SIZE 0x1A #define VOC_SIGNATURE "Creative Voice File\x1A" #define BLOCK_PREAMBLE_SIZE 4 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; unsigned int audio_type; unsigned int audio_sample_rate; unsigned int audio_bits; unsigned int audio_channels; off_t data_start; off_t data_size; unsigned int running_time; int seek_flag; /* this is set when a seek just occurred */ } demux_voc_t; static int probe_voc_file(input_plugin_t *input, int *first_block_offset) { unsigned char header[VOC_HEADER_SIZE]; if (_x_demux_read_header(input, header, VOC_HEADER_SIZE) != VOC_HEADER_SIZE) return 0; /* check the signature */ if (memcmp(header, VOC_SIGNATURE, sizeof(VOC_SIGNATURE)-1) != 0) return 0; *first_block_offset = _X_LE_16(&header[0x14]); return 1; } /* returns 1 if the VOC file was opened successfully, 0 otherwise */ static int open_voc_file(demux_voc_t *this, int first_block_offset) { unsigned char preamble[BLOCK_PREAMBLE_SIZE]; unsigned char sample_rate_divisor; if (this->input->seek(this->input, first_block_offset, SEEK_SET) != first_block_offset) return 0; /* load the block preamble */ if (this->input->read(this->input, preamble, BLOCK_PREAMBLE_SIZE) != BLOCK_PREAMBLE_SIZE) return 0; /* so far, this demuxer only cares about type 1 blocks */ if (preamble[0] != 1) { xine_log(this->stream->xine, XINE_LOG_MSG, _("unknown VOC block type (0x%02X); please report to xine developers\n"), preamble[0]); return 0; } /* assemble 24-bit, little endian length */ this->data_size = _X_LE_24(&preamble[1]); /* get the next 2 bytes (re-use preamble bytes) */ if (this->input->read(this->input, preamble, 2) != 2) return 0; /* this app only knows how to deal with format 0 data (raw PCM) */ if (preamble[1] != 0) { xine_log(this->stream->xine, XINE_LOG_MSG, _("unknown VOC compression type (0x%02X); please report to xine developers\n"), preamble[1]); return 0; } this->audio_type = BUF_AUDIO_LPCM_BE; sample_rate_divisor = preamble[0]; this->audio_sample_rate = 1000000 / (256 - sample_rate_divisor); this->data_start = this->input->get_current_pos(this->input); this->audio_bits = 8; this->audio_channels = 1; this->running_time = this->data_size / this->audio_sample_rate; return 1; } static int demux_voc_send_chunk(demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; buf_element_t *buf = NULL; unsigned int remaining_sample_bytes; off_t current_file_pos; int64_t current_pts; /* just load data chunks from wherever the stream happens to be * pointing; issue a DEMUX_FINISHED status if EOF is reached */ remaining_sample_bytes = PCM_BLOCK_ALIGN; current_file_pos = this->input->get_current_pos(this->input) - this->data_start; current_pts = current_file_pos; current_pts *= 90000; current_pts /= this->audio_sample_rate; if (this->seek_flag) { _x_demux_control_newpts(this->stream, current_pts, BUF_FLAG_SEEK); this->seek_flag = 0; } while (remaining_sample_bytes) { /* abort if no audio fifo */ if(!this->audio_fifo) { this->status = DEMUX_FINISHED; break; } buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = current_pts / 90; buf->pts = current_pts; if ((int)remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); } return this->status; } static void demux_voc_send_headers(demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->audio_channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->audio_sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->audio_bits); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo && this->audio_type) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->audio_sample_rate; buf->decoder_info[2] = this->audio_bits; buf->decoder_info[3] = this->audio_channels; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_voc_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_voc_t *this = (demux_voc_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); (void)start_time; (void)playing; this->seek_flag = 1; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* check the boundary offsets */ if (start_pos < 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by * the block alignment integer-wise, and multiply the quotient by the * block alignment to get the new aligned offset. Add the data start * offset and seek to the new position. */ start_pos /= PCM_BLOCK_ALIGN; start_pos *= PCM_BLOCK_ALIGN; start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); } return this->status; } static int demux_voc_get_status (demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_voc_get_stream_length (demux_plugin_t *this_gen) { demux_voc_t *this = (demux_voc_t *) this_gen; return this->running_time * 1000; } static uint32_t demux_voc_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_voc_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_voc_t *this; int first_block_offset; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_voc_file(input, &first_block_offset)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_voc_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_voc_send_headers; this->demux_plugin.send_chunk = demux_voc_send_chunk; this->demux_plugin.seek = demux_voc_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_voc_get_status; this->demux_plugin.get_stream_length = demux_voc_get_stream_length; this->demux_plugin.get_capabilities = demux_voc_get_capabilities; this->demux_plugin.get_optional_data = demux_voc_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_voc_file(this, first_block_offset)) { free (this); return NULL; } return &this->demux_plugin; } void *demux_voc_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_voc_class = { .open_plugin = open_plugin, .description = N_("VOC file demux plugin"), .identifier = "VOC", .mimetypes = NULL, .extensions = "voc", .dispose = NULL, }; return (void *)&demux_voc_class; } xine-lib-1.2/src/demuxers/demux_film.c0000644000175000017500000007207614647725152015620 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * FILM (CPK) File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information on the FILM file format, visit: * http://www.pcisys.net/~melanson/codecs/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_film" #define LOG_VERBOSE /* #define LOG */ /* set DEBUG_FILM_LOAD to dump the frame index after the demuxer loads a * FILM file */ #define DEBUG_FILM_LOAD 0 /* set DEBUG_FILM_DEMUX to output information about the A/V chunks that the * demuxer is dispatching to the engine */ #define DEBUG_FILM_DEMUX 0 #include #include #include #include #include "bswap.h" #include "group_games.h" #define FOURCC_TAG BE_FOURCC #define FILM_TAG FOURCC_TAG('F', 'I', 'L', 'M') #define FDSC_TAG FOURCC_TAG('F', 'D', 'S', 'C') #define STAB_TAG FOURCC_TAG('S', 'T', 'A', 'B') #define CVID_TAG FOURCC_TAG('c', 'v', 'i', 'd') typedef struct { int audio; /* audio = 1, video = 0 */ off_t sample_offset; unsigned int sample_size; int64_t pts; int64_t duration; int keyframe; } film_sample_t; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_start; off_t data_size; /* when this flag is set, demuxer only dispatches audio samples until it * encounters a video keyframe, then it starts sending every frame again */ int waiting_for_keyframe; char version[4]; /* video information */ unsigned int video_codec; unsigned int video_type; xine_bmiheader bih; /* audio information */ unsigned int audio_type; unsigned int sample_rate; unsigned int audio_bits; unsigned int audio_channels; unsigned char *interleave_buffer; /* playback information */ unsigned int frequency; unsigned int sample_count; film_sample_t *sample_table; unsigned int current_sample; unsigned int last_sample; int total_time; } demux_film_t ; static int probe_film_file(input_plugin_t *input, int *film_header_size) { unsigned char header[8]; if (_x_demux_read_header(input, header, 8) != 8) return 0; /* FILM signature correct? */ if (!_x_is_fourcc(header, "FILM")) return 0; llprintf(DEBUG_FILM_LOAD, "found 'FILM' signature\n"); /* header size = header size - 16-byte FILM signature */ *film_header_size = _X_BE_32(&header[4]); if (*film_header_size < 16) return 0; *film_header_size -= 16; return 1; } /* Open a FILM file * This function is called from the _open() function of this demuxer. * It returns 1 if FILM file was opened successfully. */ static int open_film_file(demux_film_t *film, int film_header_size) { unsigned char *film_header; unsigned int hsize = film_header_size < 0 ? 0 : film_header_size; unsigned int chunk_type; unsigned int chunk_size; unsigned int i, j; unsigned int audio_byte_count = 0; int64_t largest_pts = 0; unsigned int pts; /* initialize structure fields */ film->bih.biWidth = 0; film->bih.biHeight = 0; film->video_codec = 0; film->sample_rate = 0; film->audio_bits = 0; film->audio_channels = 0; if (film->input->seek(film->input, 8, SEEK_SET) != 8) return 0; /* read version */ if (film->input->read(film->input, film->version, 4) != 4) return 0; llprintf(DEBUG_FILM_LOAD, "0x%X header bytes, version %c%c%c%c\n", film_header_size, film->version[0], film->version[1], film->version[2], film->version[3]); /* file is qualified; skip over the header bytes in the stream */ if (film->input->seek(film->input, 16, SEEK_SET) != 16) return 0; film_header = malloc(film_header_size); if (!film_header) return 0; /* load the rest of the FILM header */ if (film->input->read(film->input, film_header, film_header_size) != film_header_size) { free (film_header); return 0; } /* get the starting offset */ film->data_start = film->input->get_current_pos(film->input); film->data_size = film->input->get_length(film->input) - film->data_start; if (film->data_size < 0) film->data_size = 0; /* traverse the FILM header */ i = 0; while (i + 7 < hsize) { chunk_type = _X_BE_32(&film_header[i]); chunk_size = _X_BE_32(&film_header[i + 4]); /* sanity check the chunk size */ if (i + chunk_size > hsize) { xine_log(film->stream->xine, XINE_LOG_MSG, _("invalid FILM chunk size\n")); free (film_header); return 0; } switch(chunk_type) { case FDSC_TAG: llprintf(DEBUG_FILM_LOAD, "parsing FDSC chunk\n"); /* always fetch the video information */ film->bih.biWidth = _X_BE_32(&film_header[i + 16]); film->bih.biHeight = _X_BE_32(&film_header[i + 12]); film->video_codec = *(uint32_t *)&film_header[i + 8]; film->video_type = _x_fourcc_to_buf_video(*(uint32_t *)&film_header[i + 8]); if( !film->video_type ) { film->video_type = BUF_VIDEO_UNKNOWN; _x_report_video_fourcc (film->stream->xine, LOG_MODULE, *(uint32_t *)&film_header[i + 8]); } /* fetch the audio information if the chunk size checks out */ if (chunk_size == 32) { film->audio_channels = film_header[21]; film->audio_bits = film_header[22]; film->sample_rate = _X_BE_16(&film_header[24]); } else { /* If the FDSC chunk is not 32 bytes long, this is an early FILM * file. Make a few assumptions about the audio parms based on the * video codec used in the file. */ if (film->video_type == BUF_VIDEO_CINEPAK) { film->audio_channels = 1; film->audio_bits = 8; film->sample_rate = 22050; } else if (film->video_type == BUF_VIDEO_SEGA) { film->audio_channels = 1; film->audio_bits = 8; film->sample_rate = 16000; } } if (film->sample_rate) film->audio_type = BUF_AUDIO_LPCM_BE; else film->audio_type = 0; if (film->video_type) llprintf(DEBUG_FILM_LOAD, "video: %dx%d %c%c%c%c\n", film->bih.biWidth, film->bih.biHeight, film_header[i + 8], film_header[i + 9], film_header[i + 10], film_header[i + 11]); else llprintf(DEBUG_FILM_LOAD, "no video\n"); if (film->audio_type) llprintf(DEBUG_FILM_LOAD, "audio: %d Hz, %d channels, %d bits PCM\n", film->sample_rate, film->audio_channels, film->audio_bits); else llprintf(DEBUG_FILM_LOAD, "no audio\n"); break; case STAB_TAG: llprintf(DEBUG_FILM_LOAD, "parsing STAB chunk\n"); /* load the sample table */ free(film->sample_table); film->frequency = _X_BE_32(&film_header[i + 8]); film->sample_count = _X_BE_32(&film_header[i + 12]); film->sample_table = xine_xcalloc(film->sample_count, sizeof(film_sample_t)); if (!film->sample_table) goto film_abort; for (j = 0; j < film->sample_count; j++) { film->sample_table[j].sample_offset = _X_BE_32(&film_header[(i + 16) + j * 16 + 0]) + film_header_size + 16; film->sample_table[j].sample_size = _X_BE_32(&film_header[(i + 16) + j * 16 + 4]); pts = _X_BE_32(&film_header[(i + 16) + j * 16 + 8]); film->sample_table[j].duration = _X_BE_32(&film_header[(i + 16) + j * 16 + 12]); if (pts == 0xFFFFFFFF) { film->sample_table[j].audio = 1; film->sample_table[j].keyframe = 0; /* figure out audio pts */ film->sample_table[j].pts = audio_byte_count; film->sample_table[j].pts *= 90000; film->sample_table[j].pts /= (film->sample_rate * film->audio_channels * (film->audio_bits / 8)); audio_byte_count += film->sample_table[j].sample_size; } else { /* figure out video pts, duration, and keyframe */ film->sample_table[j].audio = 0; /* keyframe if top bit of this field is 0 */ if (pts & 0x80000000) film->sample_table[j].keyframe = 0; else film->sample_table[j].keyframe = 1; /* remove the keyframe bit */ film->sample_table[j].pts = pts & 0x7FFFFFFF; /* compute the pts */ film->sample_table[j].pts *= 90000; film->sample_table[j].pts /= film->frequency; /* compute the frame duration */ film->sample_table[j].duration *= 90000; film->sample_table[j].duration /= film->frequency; } /* use this to calculate the total running time of the file */ if (film->sample_table[j].pts > largest_pts) largest_pts = film->sample_table[j].pts; llprintf(DEBUG_FILM_LOAD, "sample %4d @ %8" PRIxMAX ", %8X bytes, %s, pts %" PRId64 ", duration %" PRId64 "%s\n", j, (intmax_t)film->sample_table[j].sample_offset, film->sample_table[j].sample_size, (film->sample_table[j].audio) ? "audio" : "video", film->sample_table[j].pts, film->sample_table[j].duration, (film->sample_table[j].keyframe) ? " (keyframe)" : ""); } /* * in some files, this chunk length does not account for the 16-byte * chunk preamble; watch for it */ if (chunk_size == film->sample_count * 16) i += 16; /* allocate enough space in the interleave preload buffer for the * first chunk (which will be more than enough for successive chunks) */ if (film->audio_type) { free(film->interleave_buffer); film->interleave_buffer = calloc(1, film->sample_table[0].sample_size); if (!film->interleave_buffer) goto film_abort; } break; default: xine_log(film->stream->xine, XINE_LOG_MSG, _("unrecognized FILM chunk\n")); film_abort: free (film_header); return 0; } i += chunk_size; } film->total_time = largest_pts / 90; free (film_header); return 1; } static int demux_film_send_chunk(demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; buf_element_t *buf = NULL; unsigned int cvid_chunk_size; unsigned int i, j, k; int fixed_cvid_header; unsigned int remaining_sample_bytes; int first_buf; int interleave_index; i = this->current_sample; /* if there is an incongruency between last and current sample, it * must be time to send a new pts */ if (this->last_sample + 1 != this->current_sample) { /* send new pts */ _x_demux_control_newpts(this->stream, this->sample_table[i].pts, (this->sample_table[i].pts) ? BUF_FLAG_SEEK : 0); } this->last_sample = this->current_sample; this->current_sample++; /* check if all the samples have been sent */ if (i >= this->sample_count) { goto finished; } /* check if we're only sending audio samples until the next keyframe */ if ((this->waiting_for_keyframe) && (!this->sample_table[i].audio)) { if (this->sample_table[i].keyframe) { this->waiting_for_keyframe = 0; } else { /* move on to the next sample */ return this->status; } } llprintf(DEBUG_FILM_DEMUX, "dispatching frame...\n"); if ((!this->sample_table[i].audio) && (this->video_type == BUF_VIDEO_CINEPAK)) { /* do a special song and dance when loading CVID data */ if (this->version[0]) { if (this->sample_table[i].sample_size < 2) return this->status; cvid_chunk_size = this->sample_table[i].sample_size - 2; } else { if (this->sample_table[i].sample_size < 6) return this->status; cvid_chunk_size = this->sample_table[i].sample_size - 6; } /* reset flag */ fixed_cvid_header = 0; remaining_sample_bytes = cvid_chunk_size; if (this->input->seek(this->input, this->sample_table[i].sample_offset, SEEK_SET) < 0) { goto finished; } while (remaining_sample_bytes) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = this->video_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double)(this->sample_table[i].sample_offset - this->data_start) * 65535 / this->data_size); buf->extra_info->input_time = this->sample_table[i].pts / 90; buf->pts = this->sample_table[i].pts; /* set the frame duration */ buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = this->sample_table[i].duration; if ((int)remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (!fixed_cvid_header && buf->size >= 10) { if (this->input->read(this->input, buf->content, 10) != 10) { goto fail_buf; } /* skip over the extra non-spec CVID bytes */ if (this->input->seek(this->input, this->sample_table[i].sample_size - cvid_chunk_size, SEEK_CUR) < 0) { goto fail_buf; } /* load the rest of the chunk */ if (this->input->read(this->input, buf->content + 10, buf->size - 10) != buf->size - 10) { goto fail_buf; } /* adjust the length in the CVID data chunk */ buf->content[1] = (cvid_chunk_size >> 16) & 0xFF; buf->content[2] = (cvid_chunk_size >> 8) & 0xFF; buf->content[3] = (cvid_chunk_size >> 0) & 0xFF; fixed_cvid_header = 1; } else { if (this->input->read(this->input, buf->content, buf->size) != buf->size) { goto fail_buf; } } if (this->sample_table[i].keyframe) buf->decoder_flags |= BUF_FLAG_KEYFRAME; if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; llprintf(DEBUG_FILM_DEMUX, "sending video buf with %" PRId32 " bytes, %" PRId64 " pts, %" PRId32 " duration\n", buf->size, buf->pts, buf->decoder_info[0]); this->video_fifo->put(this->video_fifo, buf); } } else if (!this->sample_table[i].audio) { /* load a non-cvid video chunk */ remaining_sample_bytes = this->sample_table[i].sample_size; if (this->input->seek(this->input, this->sample_table[i].sample_offset, SEEK_SET) < 0) { goto finished; } while (remaining_sample_bytes) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = this->video_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double)(this->sample_table[i].sample_offset - this->data_start) * 65535 / this->data_size); buf->extra_info->input_time = this->sample_table[i].pts / 90; buf->pts = this->sample_table[i].pts; /* set the frame duration */ buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = this->sample_table[i].duration; if ((int)remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { goto fail_buf; } if (this->sample_table[i].keyframe) buf->decoder_flags |= BUF_FLAG_KEYFRAME; if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; llprintf(DEBUG_FILM_DEMUX, "sending video buf with %" PRId32 " bytes, %" PRId64 " pts, %" PRId32 " duration\n", buf->size, buf->pts, buf->decoder_info[0]); this->video_fifo->put(this->video_fifo, buf); } } else if(this->audio_fifo && this->audio_channels == 1) { /* load a mono audio sample and packetize it */ remaining_sample_bytes = this->sample_table[i].sample_size; if (this->input->seek(this->input, this->sample_table[i].sample_offset, SEEK_SET) < 0) { goto finished; } first_buf = 1; while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double)(this->sample_table[i].sample_offset - this->data_start) * 65535 / this->data_size); /* special hack to accomodate linear PCM decoder: only the first * buffer gets the real pts */ if (first_buf) { buf->pts = this->sample_table[i].pts; first_buf = 0; } else buf->pts = 0; buf->extra_info->input_time = buf->pts / 90; if ((int)remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { goto fail_buf; } if (this->video_type == BUF_VIDEO_SEGA) { /* if the file uses the SEGA video codec, assume this is * sign/magnitude audio */ for (j = 0; j < (unsigned int)(buf->size); j++) if (buf->content[j] < 0x80) buf->content[j] += 0x80; else buf->content[j] = -(buf->content[j] & 0x7F) + 0x80; } else if (this->audio_bits == 8) { /* convert 8-bit data from signed -> unsigned */ for (j = 0; j < (unsigned int)(buf->size); j++) buf->content[j] += 0x80; } if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; llprintf(DEBUG_FILM_DEMUX, "sending mono audio buf with %" PRId32 " bytes, %" PRId64 " pts, %" PRId32 " duration\n", buf->size, buf->pts, buf->decoder_info[0]); this->audio_fifo->put(this->audio_fifo, buf); } } else if(this->audio_fifo && this->audio_channels == 2) { /* load an entire stereo sample and interleave the channels */ /* load the whole chunk into the buffer */ if (this->input->read(this->input, this->interleave_buffer, this->sample_table[i].sample_size) != this->sample_table[i].sample_size) { goto finished; } /* proceed to de-interleave into individual buffers */ remaining_sample_bytes = this->sample_table[i].sample_size / 2; interleave_index = 0; first_buf = 1; while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double)(this->sample_table[i].sample_offset - this->data_start) * 65535 / this->data_size); /* special hack to accomodate linear PCM decoder: only the first * buffer gets the real pts */ if (first_buf) { buf->pts = this->sample_table[i].pts; first_buf = 0; } else buf->pts = 0; buf->extra_info->input_time = buf->pts / 90; if ((int)remaining_sample_bytes > buf->max_size / 2) buf->size = buf->max_size; else buf->size = remaining_sample_bytes * 2; remaining_sample_bytes -= buf->size / 2; if (this->audio_bits == 16) { for (j = 0, k = interleave_index; j < (unsigned int)(buf->size); j += 4, k += 2) { buf->content[j] = this->interleave_buffer[k]; buf->content[j + 1] = this->interleave_buffer[k + 1]; } for (j = 2, k = interleave_index + this->sample_table[i].sample_size / 2; j < (unsigned int)(buf->size); j += 4, k += 2) { buf->content[j] = this->interleave_buffer[k]; buf->content[j + 1] = this->interleave_buffer[k + 1]; } interleave_index += buf->size / 2; } else { for (j = 0, k = interleave_index; j < (unsigned int)(buf->size); j += 2, k += 1) { buf->content[j] = this->interleave_buffer[k] += 0x80; } for (j = 1, k = interleave_index + this->sample_table[i].sample_size / 2; j < (unsigned int)(buf->size); j += 2, k += 1) { buf->content[j] = this->interleave_buffer[k] += 0x80; } interleave_index += buf->size / 2; } if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; llprintf(DEBUG_FILM_DEMUX, "sending stereo audio buf with %" PRId32 " bytes, %" PRId64 " pts, %" PRId32 " duration\n", buf->size, buf->pts, buf->decoder_info[0]); this->audio_fifo->put(this->audio_fifo, buf); } } return this->status; fail_buf: buf->free_buffer(buf); finished: this->status = DEMUX_FINISHED; return this->status; } static void demux_film_send_headers(demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; buf_element_t *buf; int64_t initial_duration = 3000; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, (this->video_type) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->audio_type) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, this->video_codec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->audio_channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->audio_bits); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->video_type) { unsigned int i; /* find the first video frame duration */ for (i = 0; i < this->sample_count; i++) if (!this->sample_table[i].audio) { initial_duration = this->sample_table[i].duration; break; } buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = initial_duration; memcpy(buf->content, &this->bih, sizeof(this->bih)); buf->size = sizeof(this->bih); buf->type = this->video_type; this->video_fifo->put (this->video_fifo, buf); } if (this->audio_fifo && this->audio_type) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_BE; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->sample_rate; buf->decoder_info[2] = this->audio_bits; buf->decoder_info[3] = this->audio_channels; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_film_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_film_t *this = (demux_film_t *) this_gen; int best_index; int left, middle, right; int found; int64_t keyframe_pts; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); this->waiting_for_keyframe = 1; this->status = DEMUX_OK; _x_demux_flush_engine(this->stream); if( !playing ) { this->waiting_for_keyframe = 0; this->last_sample = 0; } /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* perform a binary search on the sample table, testing the offset * boundaries first */ if (start_pos) { if (start_pos <= 0) best_index = 0; else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; return this->status; } else { start_pos += this->data_start; left = 0; right = this->sample_count - 1; found = 0; while (!found) { middle = (left + right) / 2; if ((start_pos >= this->sample_table[middle].sample_offset) && (start_pos <= this->sample_table[middle].sample_offset + this->sample_table[middle].sample_size)) { found = 1; } else if (start_pos < this->sample_table[middle].sample_offset) { right = middle; } else { left = middle; } } best_index = middle; } } else { int64_t pts = 90 * start_time; if (pts <= this->sample_table[0].pts) best_index = 0; else if (pts >= this->sample_table[this->sample_count - 1].pts) { this->status = DEMUX_FINISHED; return this->status; } else { left = 0; right = this->sample_count - 1; do { middle = (left + right + 1) / 2; if (pts < this->sample_table[middle].pts) { right = (middle - 1); } else { left = middle; } } while (left < right); best_index = left; } } /* search back in the table for the nearest keyframe */ while (best_index) { if (this->sample_table[best_index].keyframe) { break; } best_index--; } /* not done yet; now that the nearest keyframe has been found, seek * back to the first audio frame that has a pts less than or equal to * that of the keyframe */ keyframe_pts = this->sample_table[best_index].pts; while (best_index) { if ((this->sample_table[best_index].audio) && (this->sample_table[best_index].pts < keyframe_pts)) { break; } best_index--; } this->current_sample = best_index; return this->status; } static void demux_film_dispose (demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; _x_freep(&this->sample_table); _x_freep(&this->interleave_buffer); free(this); } static int demux_film_get_status (demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; return this->status; } static int demux_film_get_stream_length (demux_plugin_t *this_gen) { demux_film_t *this = (demux_film_t *) this_gen; return this->total_time; } static uint32_t demux_film_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_film_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_film_t *this; int film_header_size; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_film_file(input, &film_header_size)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_film_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_film_send_headers; this->demux_plugin.send_chunk = demux_film_send_chunk; this->demux_plugin.seek = demux_film_seek; this->demux_plugin.dispose = demux_film_dispose; this->demux_plugin.get_status = demux_film_get_status; this->demux_plugin.get_stream_length = demux_film_get_stream_length; this->demux_plugin.get_capabilities = demux_film_get_capabilities; this->demux_plugin.get_optional_data = demux_film_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_film_file(this, film_header_size)) { demux_film_dispose(&this->demux_plugin); return NULL; } return &this->demux_plugin; } void *demux_film_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_film_class = { .open_plugin = open_plugin, .description = N_("FILM (CPK) demux plugin"), .identifier = "FILM (CPK)", .mimetypes = NULL, .extensions = "cpk cak film", .dispose = NULL, }; return (void *)&demux_film_class; } xine-lib-1.2/src/demuxers/id3.h0000644000175000017500000001465014647725152014145 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * ID3 tag parser * * Supported versions: v1, v1.1, v2.2, v2.3, v2.4 */ #ifndef ID3_H #define ID3_H #include #include #include "bswap.h" /* id3v2 */ #define ID3V22_TAG ME_FOURCC('I', 'D', '3', 2) /* id3 v2.2 header tag */ #define ID3V23_TAG ME_FOURCC('I', 'D', '3', 3) /* id3 v2.3 header tag */ #define ID3V24_TAG ME_FOURCC('I', 'D', '3', 4) /* id3 v2.4 header tag */ #define ID3V24_FOOTER_TAG ME_FOURCC('3', 'D', 'I', 0) /* id3 v2.4 footer tag */ #define ID3V2X_TAG ME_FOURCC('I', 'D', '3', 0) /* id3 v2.x header tag */ #define ID3V2X_MASK ~ME_FOURCC( 0 , 0 , 0 , 0xFF) /* id3 v2.x header mask */ /* * ID3 v2.2 */ /* tag header */ #define ID3V22_UNSYNCH_FLAG 0x80 #define ID3V22_COMPRESS_FLAG 0x40 #define ID3V22_ZERO_FLAG 0x3F /* frame header */ #define ID3V22_FRAME_HEADER_SIZE 6 /* * ID3 v2.3 */ /* tag header */ #define ID3V23_UNSYNCH_FLAG 0x80 #define ID3V23_EXT_HEADER_FLAG 0x40 #define ID3V23_EXPERIMENTAL_FLAG 0x20 #define ID3V23_ZERO_FLAG 0x1F /* frame header */ #define ID3V23_FRAME_HEADER_SIZE 10 #define ID3V23_FRAME_TAG_PRESERV_FLAG 0x8000 #define ID3V23_FRAME_FILE_PRESERV_FLAG 0x4000 #define ID3V23_FRAME_READ_ONLY_FLAG 0x2000 #define ID3V23_FRAME_COMPRESS_FLAG 0x0080 #define ID3V23_FRAME_ENCRYPT_FLAG 0x0040 #define ID3V23_FRAME_GROUP_ID_FLAG 0x0020 #define ID3V23_FRAME_ZERO_FLAG 0x1F1F /* * ID3 v2.4 */ /* tag header */ #define ID3V24_UNSYNCH_FLAG 0x80 #define ID3V24_EXT_HEADER_FLAG 0x40 #define ID3V24_EXPERIMENTAL_FLAG 0x20 #define ID3V24_FOOTER_FLAG 0x10 #define ID3V24_ZERO_FLAG 0x0F /* extended header */ #define ID3V24_EXT_UPDATE_FLAG 0x40 #define ID3V24_EXT_CRC_FLAG 0x20 #define ID3V24_EXT_RESTRICTIONS_FLAG 0x10 #define ID3V24_EXT_ZERO_FLAG 0x8F /* frame header */ #define ID3V24_FRAME_HEADER_SIZE 10 #define ID3V24_FRAME_TAG_PRESERV_FLAG 0x4000 #define ID3V24_FRAME_FILE_PRESERV_FLAG 0x2000 #define ID3V24_FRAME_READ_ONLY_FLAG 0x1000 #define ID3V24_FRAME_GROUP_ID_FLAG 0x0040 #define ID3V24_FRAME_COMPRESS_FLAG 0x0008 #define ID3V24_FRAME_ENCRYPT_FLAG 0x0004 #define ID3V24_FRAME_UNSYNCH_FLAG 0x0002 #define ID3V24_FRAME_DATA_LEN_FLAG 0x0001 #define ID3V24_FRAME_ZERO_FLAG 0x8FB0 /* footer */ #define ID3V24_FOOTER_SIZE 10 typedef struct { uint32_t id; uint8_t revision; uint8_t flags; size_t size; } id3v2_header_t; typedef struct { uint32_t id; size_t size; } id3v22_frame_header_t; typedef struct { uint32_t id; size_t size; uint16_t flags; } id3v23_frame_header_t; typedef struct { size_t size; uint16_t flags; uint32_t padding_size; uint32_t crc; } id3v23_frame_ext_header_t; typedef id3v2_header_t id3v24_footer_t; typedef struct { uint32_t id; size_t size; uint16_t flags; } id3v24_frame_header_t; typedef struct { size_t size; uint8_t flags; uint32_t crc; uint8_t restrictions; } id3v24_frame_ext_header_t; typedef struct { char tag[3]; char title[30]; char artist[30]; char album[30]; char year[4]; char comment[30]; uint8_t genre; } id3v1_tag_t; int id3v1_parse_tag (input_plugin_t *input, xine_stream_t *stream) XINE_PROTECTED; /** * @brief Check/parse/skip a possible initial ID3 v2 tag from the (side) stream. * @param stream The xine stream currently being read. * @param input The input plugin to use, or NULL for the stream default. * @note Safe to call during stream type detection. * @return The byte count skipped or 0. */ int xine_parse_id3v2_tag (xine_stream_t *stream, input_plugin_t *input) XINE_PROTECTED; /** * @brief Generic function for ID3v2 tags parsing. * @param input Pointer to the input plugin used by the demuxer, used * to access the tag's data. * @param stream Pointer to the xine stream currently being read. * @param mp3_frame_header Header of the MP3 frame carrying the tag. * * @note This function will take care of calling the proper function for * parsing ID3v2.2, ID3v2.3 or ID3v2.4 tags. */ int id3v2_parse_tag(input_plugin_t *input, xine_stream_t *stream, uint32_t id3_signature) XINE_PROTECTED; /** * @brief Checks if the given buffer is an ID3 tag preamble * @param ptr Pointer to the first 10 bytes of the ID3 tag */ static inline int id3v2_istag(uint32_t id3_signature) { return (id3_signature & ID3V2X_MASK) == ID3V2X_TAG; } #if 0 /* parse an unsynchronized 16bits integer */ static inline uint16_t _X_BE_16_synchsafe(uint8_t buf[2]) { return ((uint16_t)(buf[0] & 0x7F) << 7) | (uint16_t)(buf[1] & 0x7F); } #endif /* parse an unsynchronized 24bits integer */ static inline uint32_t _X_BE_24_synchsafe(uint8_t buf[3]) { return ((uint32_t)(buf[0] & 0x7F) << 14) | ((uint32_t)(buf[1] & 0x7F) << 7) | (uint32_t)(buf[2] & 0x7F); } /* parse an unsynchronized 32bits integer */ static inline uint32_t _X_BE_32_synchsafe(uint8_t buf[4]) { return ((uint32_t)(buf[0] & 0x7F) << 21) | ((uint32_t)(buf[1] & 0x7F) << 14) | ((uint32_t)(buf[2] & 0x7F) << 7) | (uint32_t)(buf[3] & 0x7F); } /* parse an unsynchronized 35bits integer */ static inline uint32_t BE_35_synchsafe(uint8_t buf[5]) { return ((uint32_t)(buf[0] & 0x07) << 28) | ((uint32_t)(buf[1] & 0x7F) << 21) | ((uint32_t)(buf[2] & 0x7F) << 14) | ((uint32_t)(buf[3] & 0x7F) << 7) | (uint32_t)(buf[4] & 0x7F); } #endif /* ID3_H */ xine-lib-1.2/src/demuxers/demux_vox.c0000644000175000017500000001526714647725152015504 0ustar meme/* * Copyright (C) 2001-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * VOX Demuxer by Mike Melanson (melanson@pcisys.net) * This a demuxer for .vox files containing raw Dialogic ADPCM data. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_audio.h" #define DIALOGIC_SAMPLERATE 8000 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; } demux_vox_t; static int demux_vox_send_chunk (demux_plugin_t *this_gen) { demux_vox_t *this = (demux_vox_t *) this_gen; buf_element_t *buf = NULL; off_t current_file_pos; int64_t audio_pts; int bytes_read; current_file_pos = this->input->get_current_pos(this->input); audio_pts = current_file_pos; /* each byte is 2 samples */ audio_pts *= 2 * 90000; audio_pts /= DIALOGIC_SAMPLERATE; /* read a buffer-sized block from the stream; if there is less than a * buffer of data, send whatever there is; if there are no bytes returned, * demux is finished */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_DIALOGIC_IMA; bytes_read = this->input->read(this->input, buf->content, buf->max_size); if (bytes_read <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } else if (bytes_read < buf->max_size) buf->size = bytes_read; else buf->size = buf->max_size; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->input->get_length (this->input) ); buf->extra_info->input_time = audio_pts / 90; buf->pts = audio_pts; buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); return this->status; } static void demux_vox_send_headers(demux_plugin_t *this_gen) { demux_vox_t *this = (demux_vox_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, DIALOGIC_SAMPLERATE); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, 16); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_DIALOGIC_IMA; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = DIALOGIC_SAMPLERATE; buf->decoder_info[2] = 16; buf->decoder_info[3] = 1; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_vox_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_vox_t *this = (demux_vox_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; /* start at the beginning of the file */ if (this->input->seek(this->input, 0, SEEK_SET) != 0) this->status = DEMUX_FINISHED; } return this->status; } static int demux_vox_get_status (demux_plugin_t *this_gen) { demux_vox_t *this = (demux_vox_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_vox_get_stream_length (demux_plugin_t *this_gen) { demux_vox_t *this = (demux_vox_t *) this_gen; return (int)((int64_t)this->input->get_length(this->input) * 2 * 1000 / DIALOGIC_SAMPLERATE); } static uint32_t demux_vox_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_vox_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_vox_t *this; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: return NULL; case METHOD_EXPLICIT: case METHOD_BY_MRL: break; default: return NULL; } this = calloc(1, sizeof(demux_vox_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_vox_send_headers; this->demux_plugin.send_chunk = demux_vox_send_chunk; this->demux_plugin.seek = demux_vox_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_vox_get_status; this->demux_plugin.get_stream_length = demux_vox_get_stream_length; this->demux_plugin.get_capabilities = demux_vox_get_capabilities; this->demux_plugin.get_optional_data = demux_vox_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } void *demux_vox_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_vox_class = { .open_plugin = open_plugin, .description = N_("Dialogic VOX file demux plugin"), .identifier = "VOX", .mimetypes = NULL, .extensions = "vox", .dispose = NULL, }; return (void *)&demux_vox_class; } xine-lib-1.2/src/demuxers/demux_rawdv.c0000644000175000017500000002772514647725152016015 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demultiplexer for raw dv streams */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_rawdv" #include "group_video.h" #include #include #include #include #define NTSC_FRAME_SIZE 120000 #define NTSC_FRAME_RATE 29.97 #define PAL_FRAME_SIZE 144000 #define PAL_FRAME_RATE 25 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int frame_size; int bytes_left; uint32_t cur_frame; uint32_t duration; uint64_t pts; } demux_raw_dv_t ; static int demux_raw_dv_next (demux_raw_dv_t *this) { int64_t length; buf_element_t *buf, *abuf; int n; buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->content = buf->mem; if( this->bytes_left <= buf->max_size ) { buf->size = this->bytes_left; buf->decoder_flags |= BUF_FLAG_FRAME_END; } else { buf->size = buf->max_size; } this->bytes_left -= buf->size; n = this->input->read (this->input, buf->content, buf->size); if (n != buf->size) { buf->free_buffer(buf); return 0; } /* TODO: duplicate data and send to audio fifo. * however we don't have dvaudio decoder yet. */ buf->pts = this->pts; buf->extra_info->input_time = this->pts/90; length = this->input->get_length (this->input); if (length > 0) { buf->extra_info->total_time = (int64_t)this->duration * length / (this->frame_size * 90); buf->extra_info->input_normpos = (double)this->input->get_current_pos(this->input) * 65535 / length; } buf->extra_info->frame_number = this->cur_frame; buf->type = BUF_VIDEO_DV; this->video_fifo->put(this->video_fifo, buf); if (this->audio_fifo) { abuf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); abuf->content = abuf->mem; memcpy( abuf->content, buf->content, buf->size ); abuf->type = BUF_AUDIO_DV; abuf->pts = buf->pts; abuf->size = buf->size; abuf->decoder_flags = buf->decoder_flags; abuf->extra_info->input_time = buf->extra_info->input_time; abuf->extra_info->total_time = buf->extra_info->total_time; abuf->extra_info->input_normpos = buf->extra_info->input_normpos; this->audio_fifo->put (this->audio_fifo, abuf); } if (!this->bytes_left) { this->bytes_left = this->frame_size; this->pts += this->duration; this->cur_frame++; } return 1; } static int demux_raw_dv_send_chunk (demux_plugin_t *this_gen) { demux_raw_dv_t *this = (demux_raw_dv_t *) this_gen; if (!demux_raw_dv_next(this)) this->status = DEMUX_FINISHED; return this->status; } static int demux_raw_dv_get_status (demux_plugin_t *this_gen) { demux_raw_dv_t *this = (demux_raw_dv_t *) this_gen; return this->status; } static void demux_raw_dv_send_headers (demux_plugin_t *this_gen) { demux_raw_dv_t *this = (demux_raw_dv_t *) this_gen; buf_element_t *buf, *abuf; xine_bmiheader *bih; unsigned char *scratch, scratch2[4]; int i, j; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; _x_demux_control_start(this->stream); scratch = (unsigned char *) malloc(NTSC_FRAME_SIZE); if (scratch == NULL ) return; if (INPUT_IS_SEEKABLE(this->input)) { if (this->input->seek(this->input, 0, SEEK_SET) != 0) goto out; if( this->input->read (this->input, scratch, NTSC_FRAME_SIZE) != NTSC_FRAME_SIZE ) goto out; if (this->input->seek(this->input, 0, SEEK_SET) != 0) goto out; } else { if( this->input->read (this->input, scratch, NTSC_FRAME_SIZE) != NTSC_FRAME_SIZE ) goto out; if( !(scratch[3] & 0x80) ) i = NTSC_FRAME_SIZE; else i = PAL_FRAME_SIZE; i -= NTSC_FRAME_SIZE; while (i > 0) { if( this->input->read (this->input, scratch2, 4) != 4 ) goto out; i -= 4; } } buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->content = buf->mem; buf->type = BUF_VIDEO_DV; buf->decoder_flags |= BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; bih = (xine_bmiheader *)buf->content; if( !(scratch[3] & 0x80) ) { /* NTSC */ this->frame_size = NTSC_FRAME_SIZE; this->duration = buf->decoder_info[0] = 3003; bih->biWidth = 720; bih->biHeight = 480; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, NTSC_FRAME_SIZE * NTSC_FRAME_RATE * 8); } else { /* PAL */ this->frame_size = PAL_FRAME_SIZE; this->duration = buf->decoder_info[0] = 3600; bih->biWidth = 720; bih->biHeight = 576; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, PAL_FRAME_SIZE * PAL_FRAME_RATE * 8); } _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, bih->biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, bih->biHeight); bih->biSize = sizeof(xine_bmiheader); bih->biPlanes = 1; bih->biBitCount = 24; memcpy(&bih->biCompression,"dvsd",4); bih->biSizeImage = bih->biWidth*bih->biHeight; this->video_fifo->put(this->video_fifo, buf); this->pts = 0; this->cur_frame = 0; this->bytes_left = this->frame_size; this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); if (this->audio_fifo) { int done = 0; abuf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); abuf->content = abuf->mem; /* This code GPL from Arne Schirmacher (dvgrab/Kino) */ /* 10 DIF sequences per NTSC frame */ for (i = 0; i < 10 && done == 0; ++i) { /* 9 audio DIF blocks per sequence */ for (j = 0; j < 9 && done == 0; ++j) { /* calculate address: 150 DIF blocks per sequence, 80 bytes per DIF block, audio blocks start at every 16th beginning with block 6, block has 3 bytes header, followed by one packet. */ const unsigned char *s = &scratch[i * 150 * 80 + 6 * 80 + j * 16 * 80 + 3]; /* Pack id 0x50 contains audio metadata */ if (s[0] == 0x50) { /* printf("aaux %d: %2.2x %2.2x %2.2x %2.2x %2.2x\n", j, s[0], s[1], s[2], s[3], s[4]); */ int smp/*, flag*/; done = 1; smp = (s[4] >> 3) & 0x07; /*flag = s[3] & 0x20; if (flag == 0) { switch (smp) { case 0: abuf->decoder_info[1] = 48000; break; case 1: abuf->decoder_info[1] = 44100; break; case 2: abuf->decoder_info[1] = 32000; break; } } else {*/ switch (smp) { case 0: abuf->decoder_info[1] = 48000; break; case 1: abuf->decoder_info[1] = 44100; break; case 2: abuf->decoder_info[1] = 32000; break; } /*}*/ } } } abuf->type = BUF_AUDIO_DV; abuf->size = buf->size; abuf->decoder_flags = buf->decoder_flags; abuf->decoder_info[0] = 0; /* first package, containing wavex */ abuf->decoder_info[2] = 16; /* Audio bits (ffmpeg upsamples 12 to 16bit) */ abuf->decoder_info[3] = 2; /* Audio bits (ffmpeg only supports 2 channels) */ this->audio_fifo->put (this->audio_fifo, abuf); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); } out: free(scratch); } static int demux_raw_dv_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_raw_dv_t *this = (demux_raw_dv_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); if (!INPUT_IS_SEEKABLE(this->input)) { this->status = DEMUX_OK; return this->status; } (void)playing; if( !start_pos && start_time ) { /* Upcast start_time in case sizeof(off_t) > sizeof(int) */ start_pos = ((off_t) start_time * 90 / this->duration) * this->frame_size; } start_pos = start_pos - (start_pos % this->frame_size); this->input->seek(this->input, start_pos, SEEK_SET); this->cur_frame = start_pos / this->frame_size; this->pts = this->cur_frame * this->duration; this->bytes_left = this->frame_size; _x_demux_flush_engine (this->stream); _x_demux_control_newpts (this->stream, this->pts, BUF_FLAG_SEEK); this->status = DEMUX_OK; return this->status; } static int demux_raw_dv_get_stream_length(demux_plugin_t *this_gen) { demux_raw_dv_t *this = (demux_raw_dv_t *) this_gen; return (int)((int64_t) this->duration * this->input->get_length (this->input) / (this->frame_size * 90)); } static uint32_t demux_raw_dv_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_raw_dv_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_raw_dv_t *this; uint8_t buf[8]; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: if (_x_demux_read_header(input, buf, 8) != 8) return NULL; /* DIF (DV) movie file */ if (memcmp(buf, "\x1F\x07\x00", 3) != 0 || !(buf[4] ^ 0x01)) return NULL; break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } this = calloc(1, sizeof(demux_raw_dv_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_raw_dv_send_headers; this->demux_plugin.send_chunk = demux_raw_dv_send_chunk; this->demux_plugin.seek = demux_raw_dv_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_raw_dv_get_status; this->demux_plugin.get_stream_length = demux_raw_dv_get_stream_length; this->demux_plugin.get_capabilities = demux_raw_dv_get_capabilities; this->demux_plugin.get_optional_data = demux_raw_dv_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!INPUT_IS_SEEKABLE(this->input)) { /* "live" DV streams require more prebuffering */ this->stream->metronom->set_option(this->stream->metronom, METRONOM_PREBUFFER, 90000); } return &this->demux_plugin; } void *demux_rawdv_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_rawdv_class = { .open_plugin = open_plugin, .description = N_("Raw DV Video stream"), .identifier = "raw_dv", .mimetypes = NULL, .extensions = "dv dif", .dispose = NULL, }; return (void *)&demux_rawdv_class; } xine-lib-1.2/src/demuxers/demux_tta.c0000644000175000017500000002535714647725152015461 0ustar meme/* * Copyright (C) 2006-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * True Audio demuxer by Diego Pettenò * Inspired by tta libavformat demuxer by Alex Beregszaszi * * Seek + time support added by Kelvie Wong */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "demux_tta" #define LOG_VERBOSE // This is from the TTA spec, the length (in seconds) of a frame // http://www.true-audio.com/TTA_Lossless_Audio_Codec_-_Format_Description #define FRAME_TIME 1.04489795918367346939 #include #include #include #include #include "bswap.h" #include "group_audio.h" #include typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; uint32_t *seektable; uint32_t totalframes; uint32_t currentframe; off_t datastart; int status; union { struct tta_header { uint32_t signature; /* TTA1 */ uint16_t flags; /* Skipped */ uint16_t channels; uint16_t bits_per_sample; uint32_t samplerate; uint32_t data_length; /* Number of samples */ uint32_t crc32; } XINE_PACKED tta; uint8_t buffer[22]; /* This is the size of the header */ } header; } demux_tta_t; static int probe_tta_file(input_plugin_t *input) { uint32_t peek; if (_x_demux_read_header(input, &peek, 4) != 4) return 0; if ( !_x_is_fourcc(&peek, "TTA1") ) return 0; return 1; } static int open_tta_file(demux_tta_t *this) { uint32_t framelen; if ( this->input->read(this->input, this->header.buffer, sizeof(this->header)) != sizeof(this->header) ) return 0; framelen = (uint32_t)(FRAME_TIME * le2me_32(this->header.tta.samplerate)); this->totalframes = le2me_32(this->header.tta.data_length) / framelen + ((le2me_32(this->header.tta.data_length) % framelen) ? 1 : 0); this->currentframe = 0; if(this->totalframes >= UINT_MAX/sizeof(uint32_t)) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, _("demux_tta: total frames count too high\n")); return 0; } this->seektable = xine_xcalloc(this->totalframes, sizeof(uint32_t)); if (!this->seektable) return 0; if (this->input->read(this->input, (uint8_t*)this->seektable, sizeof(uint32_t)*this->totalframes) != (int)sizeof(uint32_t)*this->totalframes) return 0; /* Skip the CRC32 */ if (this->input->seek(this->input, 4, SEEK_CUR) < 0) return 0; /* Store the offset after the header for seeking */ this->datastart = this->input->get_current_pos(this->input); return 1; } static int demux_tta_send_chunk(demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; uint32_t bytes_to_read; if ( this->currentframe >= this->totalframes ) { this->status = DEMUX_FINISHED; return this->status; } bytes_to_read = le2me_32(this->seektable[this->currentframe]); if (_x_demux_read_send_data(this->audio_fifo, this->input, bytes_to_read, (int64_t)(FRAME_TIME * this->currentframe * 90000), BUF_AUDIO_TTA, /*decoder_flags*/ 0, (int) ((double) this->currentframe * 65535.0 / this->totalframes), (int)(FRAME_TIME * this->currentframe * 1000), (int)(le2me_32(this->header.tta.data_length) * 1000.0 / le2me_32(this->header.tta.samplerate)), this->currentframe) < 0) { this->status = DEMUX_FINISHED; } this->currentframe++; return this->status; } static void demux_tta_send_headers(demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; buf_element_t *buf; xine_waveformatex wave; uint32_t total_size = sizeof(xine_waveformatex) + sizeof(this->header) + sizeof(uint32_t)*this->totalframes; unsigned char *header; memset(&wave, 0, sizeof(wave)); this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, le2me_16(this->header.tta.channels)); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, le2me_32(this->header.tta.samplerate)); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, le2me_16(this->header.tta.bits_per_sample)); /* send start buffers */ _x_demux_control_start(this->stream); /* create header */ wave.cbSize = total_size - sizeof(xine_waveformatex); header = malloc(total_size); if (!header) return; memcpy(header, &wave, sizeof(wave)); memcpy(header+sizeof(xine_waveformatex), this->header.buffer, sizeof(this->header)); memcpy(header+sizeof(xine_waveformatex)+sizeof(this->header), this->seektable, sizeof(uint32_t)*this->totalframes); /* send init info to decoders */ if (this->audio_fifo) { uint32_t bytes_left = total_size; /* We are sending the seektable as well, and this may be larger than buf->max_size */ while (bytes_left) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER; buf->type = BUF_AUDIO_TTA; /* Copy min(bytes_left, max_size) bytes */ buf->size = (int)bytes_left < buf->max_size ? (int)bytes_left : buf->max_size; memcpy(buf->content, header+(total_size-bytes_left), buf->size); bytes_left -= buf->size; /* The decoder information only needs the decoder information on the last buffer element. */ if (!bytes_left) { buf->decoder_flags |= BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = le2me_32(this->header.tta.samplerate); buf->decoder_info[2] = le2me_16(this->header.tta.bits_per_sample); buf->decoder_info[3] = le2me_16(this->header.tta.channels); } this->audio_fifo->put (this->audio_fifo, buf); } } free(header); } static int demux_tta_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_tta_t *this = (demux_tta_t *) this_gen; uint32_t start_frame; uint32_t frame_index; int64_t pts; off_t start_off = this->datastart; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } else { /* Get the starting frame */ if( start_pos ) { pts = start_pos * le2me_32(this->header.tta.data_length) * 1000.0 / le2me_32(this->header.tta.samplerate) * 90 / 65535; start_frame = start_pos * this->totalframes / 65535; } else { pts = start_time * 90; start_frame = (uint32_t)((double)start_time/ 1000.0 / FRAME_TIME); } /* Now we find the offset */ for( frame_index = 0; frame_index < start_frame; frame_index++ ) start_off += le2me_32(this->seektable[frame_index]); /* Let's seek! We store the current frame internally, so let's update that * as well */ _x_demux_flush_engine(this->stream); this->input->seek(this->input, start_off, SEEK_SET); this->currentframe = start_frame; _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->status = DEMUX_OK; } return this->status; } static void demux_tta_dispose (demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; _x_freep(&this->seektable); free(this); } static int demux_tta_get_status (demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; return this->status; } static int demux_tta_get_stream_length (demux_plugin_t *this_gen) { demux_tta_t *this = (demux_tta_t *) this_gen; return le2me_32(this->header.tta.data_length) * 1000.0 / le2me_32(this->header.tta.samplerate); /* milliseconds */ } static uint32_t demux_tta_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_tta_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_tta_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_tta_file(input)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_tta_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_tta_send_headers; this->demux_plugin.send_chunk = demux_tta_send_chunk; this->demux_plugin.seek = demux_tta_seek; this->demux_plugin.dispose = demux_tta_dispose; this->demux_plugin.get_status = demux_tta_get_status; this->demux_plugin.get_stream_length = demux_tta_get_stream_length; this->demux_plugin.get_capabilities = demux_tta_get_capabilities; this->demux_plugin.get_optional_data = demux_tta_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; this->seektable = NULL; if (!open_tta_file(this)) { demux_tta_dispose(&this->demux_plugin); return NULL; } return &this->demux_plugin; } void *demux_tta_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_tta_class = { .open_plugin = open_plugin, .description = N_("True Audio demux plugin"), .identifier = "True Audio", .mimetypes = NULL, .extensions = "tta", .dispose = NULL, }; return (void *)&demux_tta_class; } xine-lib-1.2/src/demuxers/demux_qt.c0000644000175000017500000043504614647725152015315 0ustar meme/* * Copyright (C) 2001-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Quicktime File Demuxer by Mike Melanson (melanson@pcisys.net) * based on a Quicktime parsing experiment entitled 'lazyqt' * * Atom finder, trak builder rewrite, multiaudio and ISO fragment * media file support by Torsten Jager (t.jager@gmx.de) * * Ideally, more documentation is forthcoming, but in the meantime: * functional flow: * create_qt_info * open_qt_file * parse_moov_atom * parse_mvhd_atom * parse_trak_atom * build_frame_table * free_qt_info */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #define LOG_MODULE "demux_qt" #include "group_video.h" #include #include #include #include #include #include "bswap.h" #include "qtpalette.h" typedef unsigned int qt_atom; #define QT_ATOM BE_FOURCC /* top level atoms */ #define FREE_ATOM QT_ATOM('f', 'r', 'e', 'e') #define JUNK_ATOM QT_ATOM('j', 'u', 'n', 'k') #define MDAT_ATOM QT_ATOM('m', 'd', 'a', 't') #define MOOV_ATOM QT_ATOM('m', 'o', 'o', 'v') #define PNOT_ATOM QT_ATOM('p', 'n', 'o', 't') #define SKIP_ATOM QT_ATOM('s', 'k', 'i', 'p') #define WIDE_ATOM QT_ATOM('w', 'i', 'd', 'e') #define PICT_ATOM QT_ATOM('P', 'I', 'C', 'T') #define FTYP_ATOM QT_ATOM('f', 't', 'y', 'p') #define SIDX_ATOM QT_ATOM('s', 'i', 'd', 'x') #define CMOV_ATOM QT_ATOM('c', 'm', 'o', 'v') #define MVHD_ATOM QT_ATOM('m', 'v', 'h', 'd') #define VMHD_ATOM QT_ATOM('v', 'm', 'h', 'd') #define SMHD_ATOM QT_ATOM('s', 'm', 'h', 'd') #define TRAK_ATOM QT_ATOM('t', 'r', 'a', 'k') #define TKHD_ATOM QT_ATOM('t', 'k', 'h', 'd') #define MDHD_ATOM QT_ATOM('m', 'd', 'h', 'd') #define ELST_ATOM QT_ATOM('e', 'l', 's', 't') /* atoms in a sample table */ #define STSD_ATOM QT_ATOM('s', 't', 's', 'd') #define STSZ_ATOM QT_ATOM('s', 't', 's', 'z') #define STZ2_ATOM QT_ATOM('s', 't', 'z', '2') #define STSC_ATOM QT_ATOM('s', 't', 's', 'c') #define STCO_ATOM QT_ATOM('s', 't', 'c', 'o') #define STTS_ATOM QT_ATOM('s', 't', 't', 's') #define CTTS_ATOM QT_ATOM('c', 't', 't', 's') #define STSS_ATOM QT_ATOM('s', 't', 's', 's') #define CO64_ATOM QT_ATOM('c', 'o', '6', '4') #define ESDS_ATOM QT_ATOM('e', 's', 'd', 's') #define WAVE_ATOM QT_ATOM('w', 'a', 'v', 'e') #define FRMA_ATOM QT_ATOM('f', 'r', 'm', 'a') #define AVCC_ATOM QT_ATOM('a', 'v', 'c', 'C') #define HVCC_ATOM QT_ATOM('h', 'v', 'c', 'C') #define ENDA_ATOM QT_ATOM('e', 'n', 'd', 'a') #define IMA4_FOURCC ME_FOURCC('i', 'm', 'a', '4') #define MAC3_FOURCC ME_FOURCC('M', 'A', 'C', '3') #define MAC6_FOURCC ME_FOURCC('M', 'A', 'C', '6') #define ULAW_FOURCC ME_FOURCC('u', 'l', 'a', 'w') #define ALAW_FOURCC ME_FOURCC('a', 'l', 'a', 'w') #define MP4A_FOURCC ME_FOURCC('m', 'p', '4', 'a') #define SAMR_FOURCC ME_FOURCC('s', 'a', 'm', 'r') #define ALAC_FOURCC ME_FOURCC('a', 'l', 'a', 'c') #define DRMS_FOURCC ME_FOURCC('d', 'r', 'm', 's') #define TWOS_FOURCC ME_FOURCC('t', 'w', 'o', 's') #define SOWT_FOURCC ME_FOURCC('s', 'o', 'w', 't') #define RAW_FOURCC ME_FOURCC('r', 'a', 'w', ' ') #define IN24_FOURCC ME_FOURCC('i', 'n', '2', '4') #define NI42_FOURCC ME_FOURCC('4', '2', 'n', 'i') #define AVC1_FOURCC ME_FOURCC('a', 'v', 'c', '1') #define HVC1_FOURCC ME_FOURCC('h', 'v', 'c', '1') #define HEV1_FOURCC ME_FOURCC('h', 'e', 'v', '1') #define HEVC_FOURCC ME_FOURCC('h', 'e', 'v', 'c') #define AC_3_FOURCC ME_FOURCC('a', 'c', '-', '3') #define EAC3_FOURCC ME_FOURCC('e', 'c', '-', '3') #define QCLP_FOURCC ME_FOURCC('Q', 'c', 'l', 'p') #define UDTA_ATOM QT_ATOM('u', 'd', 't', 'a') #define META_ATOM QT_ATOM('m', 'e', 't', 'a') #define HDLR_ATOM QT_ATOM('h', 'd', 'l', 'r') #define ILST_ATOM QT_ATOM('i', 'l', 's', 't') #define NAM_ATOM QT_ATOM(0xA9, 'n', 'a', 'm') #define CPY_ATOM QT_ATOM(0xA9, 'c', 'p', 'y') #define DES_ATOM QT_ATOM(0xA9, 'd', 'e', 's') #define CMT_ATOM QT_ATOM(0xA9, 'c', 'm', 't') #define ALB_ATOM QT_ATOM(0xA9, 'a', 'l', 'b') #define GEN_ATOM QT_ATOM(0xA9, 'g', 'e', 'n') #define ART_ATOM QT_ATOM(0xA9, 'A', 'R', 'T') #define TOO_ATOM QT_ATOM(0xA9, 't', 'o', 'o') #define WRT_ATOM QT_ATOM(0xA9, 'w', 'r', 't') #define DAY_ATOM QT_ATOM(0xA9, 'd', 'a', 'y') #define RMRA_ATOM QT_ATOM('r', 'm', 'r', 'a') #define RMDA_ATOM QT_ATOM('r', 'm', 'd', 'a') #define RDRF_ATOM QT_ATOM('r', 'd', 'r', 'f') #define RMDR_ATOM QT_ATOM('r', 'm', 'd', 'r') #define RMVC_ATOM QT_ATOM('r', 'm', 'v', 'c') #define QTIM_ATOM QT_ATOM('q', 't', 'i', 'm') #define URL__ATOM QT_ATOM('u', 'r', 'l', ' ') #define DATA_ATOM QT_ATOM('d', 'a', 't', 'a') /* fragment stuff */ #define MVEX_ATOM QT_ATOM('m', 'v', 'e', 'x') #define MEHD_ATOM QT_ATOM('m', 'e', 'h', 'd') #define TREX_ATOM QT_ATOM('t', 'r', 'e', 'x') #define MOOF_ATOM QT_ATOM('m', 'o', 'o', 'f') #define MFHD_ATOM QT_ATOM('m', 'v', 'h', 'd') #define TRAF_ATOM QT_ATOM('t', 'r', 'a', 'f') #define TFHD_ATOM QT_ATOM('t', 'f', 'h', 'd') #define TRUN_ATOM QT_ATOM('t', 'r', 'u', 'n') /* placeholder for cutting and pasting #define _ATOM QT_ATOM('', '', '', '') */ /* TJ. I have not seen more than 20Mb yet... */ #define MAX_MOOV_SIZE (128 << 20) #define ATOM_PREAMBLE_SIZE 8 #define PALETTE_COUNT 256 #define MAX_PTS_DIFF 100000 #ifdef ARCH_X86 # define HAVE_FAST_FLOAT #endif typedef struct { #ifdef HAVE_FAST_FLOAT double mul; #else int32_t num; int32_t den; #endif } scale_int_t; static void scale_int_init (scale_int_t *scale, uint32_t num, uint32_t den) { if (!den) den = 1; #ifdef HAVE_FAST_FLOAT scale->mul = (double)num / (double)den; #else scale->num = num; scale->den = den; #endif } static void scale_int_do (scale_int_t *scale, int64_t *v) { #ifdef HAVE_FAST_FLOAT *v = (double)(*v) * scale->mul; #else *v = *v * scale->num / scale->den; #endif } /** * @brief Network bandwidth, cribbed from src/input/input_mms.c */ static const uint32_t bandwidths[] = { 14400, 19200, 28800, 33600, 34430, 57600, 115200, 262200, 393216, 524300, 1544000, 10485800 }; /* these are things that can go wrong */ typedef enum { QT_OK, QT_FILE_READ_ERROR, QT_NO_MEMORY, QT_NOT_A_VALID_FILE, QT_NO_MOOV_ATOM, QT_NO_ZLIB, QT_ZLIB_ERROR, QT_HEADER_TROUBLE, QT_DRM_NOT_SUPPORTED } qt_error; /* there are other types but these are the ones we usually care about */ typedef enum { MEDIA_AUDIO, MEDIA_VIDEO, MEDIA_OTHER } media_type; /* TJ. Cinematic movies reach > 200000 frames easily, so we better save space here. * offset / file size should well fit into 48 bits :-) */ typedef struct { union { int64_t offset; uint8_t bytes[8]; } _ffs; unsigned int size; /* pts actually is dts for reordered video. Edit list and frame duration code relies on that, so keep the offset separately until sending to video fifo. Value is small enough for plain int. */ int ptsoffs; int64_t pts; } qt_frame; #define QTF_OFFSET(f) ((f)._ffs.offset & ~((uint64_t)0xffff << 48)) #ifdef WORDS_BIGENDIAN # define QTF_KEYFRAME(f) ((f)._ffs.bytes[0]) # define QTF_MEDIA_ID(f) ((f)._ffs.bytes[1]) #else # define QTF_KEYFRAME(f) ((f)._ffs.bytes[7]) # define QTF_MEDIA_ID(f) ((f)._ffs.bytes[6]) #endif typedef struct { int64_t track_duration; int64_t media_time; } edit_list_table_t; typedef struct { unsigned int first_chunk; unsigned int samples_per_chunk; unsigned int media_id; } sample_to_chunk_table_t; typedef struct { char *url; int64_t data_rate; int qtim_version; } reference_t; typedef struct { /* the media id that corresponds to this trak */ uint8_t *properties_atom; uint8_t *decoder_config; unsigned int media_id; unsigned int codec_fourcc; unsigned int codec_buftype; unsigned int properties_atom_size; unsigned int decoder_config_len; /* formattag-like field that specifies codec in mp4 files */ int object_type_id; char codec_str[20]; union { struct { unsigned int width; unsigned int height; int depth; int edit_list_compensation; /* special trick for edit lists */ int palette_count; palette_entry_t palette[PALETTE_COUNT]; } video; struct { xine_waveformatex *wave; unsigned int wave_size; unsigned int sample_rate; unsigned int channels; unsigned int bits; unsigned int vbr; /* special audio parameters */ unsigned int samples_per_packet; unsigned int bytes_per_packet; unsigned int bytes_per_frame; unsigned int bytes_per_sample; unsigned int samples_per_frame; } audio; } s; } properties_t; typedef struct { /* trak description */ media_type type; int id; /* internal frame table corresponding to this trak */ qt_frame *frames; unsigned int frame_count; unsigned int current_frame; /* this is the current properties atom in use */ properties_t *properties; /* one or more properties atoms for this trak */ properties_t *stsd_atoms; unsigned int stsd_atoms_count; /* trak timescale */ int timescale; int ptsoffs_mul; scale_int_t si; /* flags that indicate how a trak is supposed to be used */ unsigned int flags; /* temporary tables for loading a chunk */ /* edit list table */ edit_list_table_t *edit_list_table; /* chunk offsets */ uint8_t *chunk_offset_table32; uint8_t *chunk_offset_table64; /* sample sizes */ uint8_t *sample_size_table; /* sync samples, a.k.a., keyframes */ uint8_t *sync_sample_table; xine_keyframes_entry_t *keyframes_list; /* sample to chunk table */ sample_to_chunk_table_t *sample_to_chunk_table; /* time to sample table */ uint8_t *time_to_sample_table; /* pts to dts timeoffset to sample table */ uint8_t *timeoffs_to_sample_table; /* and the sizes thereof */ unsigned int edit_list_count; unsigned int chunk_offset_count; unsigned int samples; unsigned int sample_size; unsigned int sample_size_count; unsigned int sample_size_bytes; unsigned int sample_size_shift; unsigned int sync_sample_count; unsigned int keyframes_used; unsigned int keyframes_size; unsigned int sample_to_chunk_count; unsigned int time_to_sample_count; unsigned int timeoffs_to_sample_count; /* what to add to output buffer type */ int audio_index; int lang; /* fragment defaults */ int default_sample_description_index; int default_sample_duration; int default_sample_size; int default_sample_flags; /* fragment seamless dts */ int64_t fragment_dts; int delay_index; /* fragment frame array size */ int fragment_frames; } qt_trak; typedef struct { int compressed_header; /* 1 if there was a compressed moov; just FYI */ unsigned int creation_time; /* in ms since Jan-01-1904 */ unsigned int modification_time; unsigned int timescale; /* base clock frequency is Hz */ unsigned int duration; int32_t msecs; uint32_t normpos_mul; uint32_t normpos_shift; int64_t moov_first_offset; unsigned int trak_count; qt_trak *traks; #define MAX_AUDIO_TRAKS 8 int audio_trak_count; int audio_traks[MAX_AUDIO_TRAKS]; /* the trak numbers that won their respective frame count competitions */ int video_trak; int audio_trak; int seek_flag; /* this is set to indicate that a seek has just occurred */ /* fragment mode */ xine_mfrag_list_t *fraglist; int fragment_count; size_t fragbuf_size; uint8_t *fragment_buf; off_t fragment_next; char *artist; char *name; char *album; char *genre; char *copyright; char *description; char *comment; char *composer; char *year; /* a QT movie may contain a number of references pointing to URLs */ reference_t *references; unsigned int reference_count; int chosen_reference; /* need to know base MRL to construct URLs from relative paths */ char *base_mrl; qt_error last_error; } qt_info; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; config_values_t *config; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int ptsoffs; int status; qt_info qt; xine_bmiheader bih; #ifdef QT_OFFSET_SEEK off_t data_start; off_t data_size; #endif int64_t bandwidth; } demux_qt_t; /********************************************************************** * lazyqt special debugging functions **********************************************************************/ /* define DEBUG_ATOM_LOAD as 1 to get a verbose parsing of the relevant * atoms */ #define DEBUG_ATOM_LOAD 0 /* define DEBUG_EDIT_LIST as 1 to get a detailed look at how the demuxer is * handling edit lists */ #define DEBUG_EDIT_LIST 0 /* define DEBUG_FRAME_TABLE as 1 to dump the complete frame table that the * demuxer plans to use during file playback */ #define DEBUG_FRAME_TABLE 0 /* define DEBUG_VIDEO_DEMUX as 1 to see details about the video chunks the * demuxer is sending off to the video decoder */ #define DEBUG_VIDEO_DEMUX 0 /* define DEBUG_AUDIO_DEMUX as 1 to see details about the audio chunks the * demuxer is sending off to the audio decoder */ #define DEBUG_AUDIO_DEMUX 0 /* define DEBUG_META_LOAD as 1 to see details about the metadata chunks the * demuxer is reading from the file */ #define DEBUG_META_LOAD 0 /* Define DEBUG_DUMP_MOOV as 1 to dump the raw moov atom to disk. This is * particularly useful in debugging a file with a compressed moov (cmov) * atom. The atom will be dumped to the filename specified as * RAW_MOOV_FILENAME. */ #define DEBUG_DUMP_MOOV 0 #define RAW_MOOV_FILENAME "moovatom.raw" #if DEBUG_ATOM_LOAD #define debug_atom_load printf #else static inline void XINE_FORMAT_PRINTF (1, 2) debug_atom_load (const char *format, ...) {(void)format;} #endif #if DEBUG_EDIT_LIST #define debug_edit_list printf #else static inline void XINE_FORMAT_PRINTF (1, 2) debug_edit_list (const char *format, ...) {(void)format;} #endif #if DEBUG_FRAME_TABLE #define debug_frame_table printf #else static inline void XINE_FORMAT_PRINTF (1, 2) debug_frame_table (const char *format, ...) {(void)format;} #endif #if DEBUG_VIDEO_DEMUX #define debug_video_demux printf #else static inline void XINE_FORMAT_PRINTF (1, 2) debug_video_demux (const char *format, ...) {(void)format;} #endif #if DEBUG_AUDIO_DEMUX #define debug_audio_demux printf #else static inline void XINE_FORMAT_PRINTF (1, 2) debug_audio_demux (const char *format, ...) {(void)format;} #endif #if DEBUG_META_LOAD #define debug_meta_load printf #else static inline void XINE_FORMAT_PRINTF (1, 2) debug_meta_load (const char *format, ...) {(void)format;} #endif static inline void dump_moov_atom (uint8_t *moov_atom, int moov_atom_size) { #if DEBUG_DUMP_MOOV FILE *f; f = fopen(RAW_MOOV_FILENAME, "wb"); if (!f) { perror(RAW_MOOV_FILENAME); return; } if (fwrite(moov_atom, moov_atom_size, 1, f) != 1) printf (" qt debug: could not write moov atom to disk\n"); fclose(f); #else (void)moov_atom; (void)moov_atom_size; #endif } /********************************************************************** * lazyqt functions **********************************************************************/ static void reset_qt_info (demux_qt_t *this) { #ifndef HAVE_ZERO_SAFE_MEM this->qt.compressed_header = 0; this->qt.creation_time = 0; this->qt.modification_time = 0; this->qt.duration = 0; this->qt.normpos_mul = 0; this->qt.normpos_shift = 0; this->qt.trak_count = 0; this->qt.traks = NULL; this->qt.artist = NULL; this->qt.name = NULL; this->qt.album = NULL; this->qt.genre = NULL; this->qt.copyright = NULL; this->qt.description = NULL; this->qt.comment = NULL; this->qt.composer = NULL; this->qt.year = NULL; this->qt.references = NULL; this->qt.reference_count = 0; this->qt.base_mrl = NULL; this->qt.fragbuf_size = 0; this->qt.fragment_buf = NULL; this->qt.fragment_next = 0; #else memset (&this->qt, 0, sizeof (this->qt)); #endif this->qt.last_error = QT_OK; this->qt.timescale = 1; this->qt.msecs = 1; this->qt.video_trak = -1; this->qt.audio_trak = -1; this->qt.chosen_reference = -1; this->qt.fragment_count = -1; } /* create a qt_info structure */ static qt_info *create_qt_info (demux_qt_t *this) { reset_qt_info (this); return &this->qt; } /* release a qt_info structure and associated data */ static void free_qt_info (demux_qt_t *this) { if (this->qt.traks) { unsigned int i; for (i = 0; i < this->qt.trak_count; i++) { free (this->qt.traks[i].frames); free (this->qt.traks[i].edit_list_table); free (this->qt.traks[i].sample_to_chunk_table); if (this->qt.traks[i].type == MEDIA_AUDIO) { unsigned int j; for (j = 0; j < this->qt.traks[i].stsd_atoms_count; j++) free (this->qt.traks[i].stsd_atoms[j].s.audio.wave); } free (this->qt.traks[i].stsd_atoms); } free (this->qt.traks); } if (this->qt.references) { unsigned int i; for (i = 0; i < this->qt.reference_count; i++) free (this->qt.references[i].url); free (this->qt.references); } free (this->qt.fragment_buf); free (this->qt.base_mrl); free (this->qt.artist); free (this->qt.name); free (this->qt.album); free (this->qt.genre); free (this->qt.copyright); free (this->qt.description); free (this->qt.comment); free (this->qt.composer); free (this->qt.year); reset_qt_info (this); } /* fetch interesting information from the movie header atom */ static void parse_mvhd_atom (demux_qt_t *this, uint8_t *mvhd_atom) { this->qt.creation_time = _X_BE_32 (mvhd_atom + 0x0c); this->qt.modification_time = _X_BE_32 (mvhd_atom + 0x10); this->qt.timescale = _X_BE_32 (mvhd_atom + 0x14); this->qt.duration = _X_BE_32 (mvhd_atom + 0x18); if (this->qt.timescale == 0) this->qt.timescale = 1; debug_atom_load(" qt: timescale = %d, duration = %d (%d seconds)\n", this->qt.timescale, this->qt.duration, this->qt.duration / this->qt.timescale); } /* helper function from mplayer's parse_mp4.c */ static int mp4_read_descr_len (uint8_t *s, uint32_t *length) { uint8_t b; uint8_t numBytes = 0; *length = 0; do { b = *s++; numBytes++; *length = (*length << 7) | (b & 0x7F); } while ((b & 0x80) && numBytes < 4); return numBytes; } #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) # define WRITE_BE_32(v,p) { \ uint8_t *wp = (uint8_t *)(p); \ int32_t n = __builtin_bswap32 ((int32_t)(v)); \ __builtin_memcpy (wp, &n, 4); \ } #else # define WRITE_BE_32(v,p) { \ uint8_t *wp = (uint8_t *)(p); \ uint32_t wv = (v); \ wp[0] = wv >> 24; \ wp[1] = wv >> 16; \ wp[2] = wv >> 8; \ wp[3] = wv; \ } #endif /* find sub atoms somewhere inside this atom */ static void find_embedded_atoms (uint8_t *atom, const uint32_t *types, uint8_t **found, uint32_t *sizes) { uint8_t *here; uint32_t atomsize, v, n; uint8_t *end; if (!atom || !types || !found) return; for (n = 0; types[n]; n++) found[n] = NULL, sizes[n] = 0; atomsize = _X_BE_32 (atom); if (atomsize < 16) return; end = atom + atomsize; atomsize -= 16; here = atom + 16; v = _X_BE_32 (here - 4); while (1) { for (n = 0; types[n]; n++) { if (v == types[n]) { uint32_t fsize = _X_BE_32 (here - 8); if (fsize == 0) { found[n] = here - 8; sizes[n] = atomsize + 8; return; } if ((fsize < 8) || (fsize - 8 > atomsize)) break; found[n] = here - 8; sizes[n] = fsize; atomsize -= fsize - 8; if (atomsize < 8) return; here += fsize - 1; v = _X_BE_32 (here - 4); atomsize += 1; break; } } if (!atomsize) break; if (here >= end) break; v = (v << 8) | *here++; atomsize -= 1; } } static int atom_scan ( /** << return value: # of missing atoms. */ uint8_t *atom, /** << the atom to parse. */ int depth, /** << how many levels of hierarchy to examine. */ const uint32_t *types, /** << zero terminated list of interesting atom types. */ uint8_t **found, /** << list of atom pointers to fill in. */ unsigned int *sizes) { /** << list of atom sizes to fill in. */ static const uint8_t containers[] = /* look into these from "trak". */ "edtsmdiaminfdinfstbl" /* look into these from "moov" (intentionally hide "trak"). */ "udtametailstiprosinfrmrarmdardrfrmvc"; unsigned int atomtype, atomsize, subsize = 0; unsigned int i = 8, n, left; if (!atom || !types || !found) return 0; if (depth > 0) { for (n = 0; types[n]; n++) { found[n] = NULL; sizes[n] = 0; } left = n; depth = -depth; } else { for (left = n = 0; types[n]; n++) if (!(found[n])) left++; } atomsize = _X_BE_32 (atom); atomtype = _X_BE_32 (&atom[4]); if (atomtype == META_ATOM) { if ((atomsize < 12) || (atom[8] != 0)) return left; i = 12; } for (; i + 8 <= atomsize; i += subsize) { unsigned int j; uint32_t subtype = _X_BE_32 (&atom[i + 4]); subsize = _X_BE_32 (&atom[i]); if (subsize == 0) { subsize = atomsize - i; WRITE_BE_32 (subsize, &atom[i]); } if ((subsize < 8) || (i + subsize > atomsize)) break; for (n = 0; types[n]; n++) { if (found[n]) continue; if (!(subtype ^ types[n])) { #if DEBUG_ATOM_LOAD xine_hexdump (atom + i, subsize); #endif found[n] = atom + i; sizes[n] = subsize; if (!(--left)) return 0; break; } } if (depth > -2) continue; for (j = 0; j < sizeof (containers) - 1; j += 4) { if (!memcmp (atom + i + 4, containers + j, 4)) { if (!(left = atom_scan (atom + i, depth + 1, types, found, sizes))) return 0; break; } } } return left; } /* * This function traverses through a trak atom searching for the sample * table atoms, which it loads into an internal trak structure. */ static qt_error parse_trak_atom (qt_trak *trak, uint8_t *trak_atom) { uint8_t *atom; int j; unsigned int atomsize; qt_error last_error = QT_OK; static const uint32_t types_trak[] = { VMHD_ATOM, SMHD_ATOM, TKHD_ATOM, ELST_ATOM, MDHD_ATOM, STSD_ATOM, STSZ_ATOM, STSS_ATOM, STCO_ATOM, CO64_ATOM, STSC_ATOM, STTS_ATOM, CTTS_ATOM, STZ2_ATOM, 0}; unsigned int sizes[14]; uint8_t *atoms[14]; /* initialize trak structure */ #ifdef HAVE_ZERO_SAFE_MEM memset (trak, 0, sizeof (*trak)); #else trak->edit_list_count = 0; trak->edit_list_table = NULL; trak->chunk_offset_count = 0; trak->chunk_offset_table32 = NULL; trak->chunk_offset_table64 = NULL; trak->samples = 0; trak->sample_size = 0; trak->sample_size_count = 0; trak->sample_size_bytes = 0; trak->sample_size_shift = 0; trak->sample_size_table = NULL; trak->sync_sample_count = 0; trak->sync_sample_table = NULL; trak->keyframes_list = NULL; trak->keyframes_size = 0; trak->keyframes_used = 0; trak->sample_to_chunk_count = 0; trak->sample_to_chunk_table = NULL; trak->time_to_sample_count = 0; trak->time_to_sample_table = NULL; trak->timeoffs_to_sample_count = 0; trak->timeoffs_to_sample_table = NULL; trak->frames = NULL; trak->frame_count = 0; trak->current_frame = 0; trak->flags = 0; trak->stsd_atoms_count = 0; trak->stsd_atoms = NULL; #endif trak->id = -1; trak->timescale = 1; trak->delay_index = -1; /* default type */ trak->type = MEDIA_OTHER; /* search for media type atoms */ atom_scan (trak_atom, 5, types_trak, atoms, sizes); if (atoms[0]) /* VMHD_ATOM */ trak->type = MEDIA_VIDEO; else if (atoms[1]) /* SMHD_ATOM */ trak->type = MEDIA_AUDIO; debug_atom_load(" qt: parsing %s trak atom\n", (trak->type == MEDIA_VIDEO) ? "video" : (trak->type == MEDIA_AUDIO) ? "audio" : "other"); /* search for the useful atoms */ atom = atoms[2]; /* TKHD_ATOM */ atomsize = sizes[2]; if (atomsize >= 12) { trak->flags = _X_BE_24(&atom[9]); if (atom[8] == 1) { if (atomsize >= 32) trak->id = _X_BE_32 (&atom[28]); } else { if (atomsize >= 24) trak->id = _X_BE_32 (&atom[20]); } } atom = atoms[3]; /* ELST_ATOM */ atomsize = sizes[3]; if (atomsize >= 16) { trak->edit_list_count = _X_BE_32 (&atom[12]); debug_atom_load (" qt elst atom (edit list atom): %d entries\n", trak->edit_list_count); if (atom[8] == 1) { unsigned int j; if (trak->edit_list_count > (atomsize - 16) / 20) trak->edit_list_count = (atomsize - 16) / 20; trak->edit_list_table = calloc (trak->edit_list_count + 1, sizeof (edit_list_table_t)); if (!trak->edit_list_table) { last_error = QT_NO_MEMORY; goto free_trak; } for (j = 0; j < trak->edit_list_count; j++) { trak->edit_list_table[j].track_duration = _X_BE_64 (&atom[16 + j * 20 + 0]); trak->edit_list_table[j].media_time = _X_BE_64 (&atom[16 + j * 20 + 8]); debug_atom_load (" %d: track duration = %"PRId64", media time = %"PRId64"\n", j, trak->edit_list_table[j].track_duration, trak->edit_list_table[j].media_time); } } else { unsigned int j; if (trak->edit_list_count > (atomsize - 16) / 12) trak->edit_list_count = (atomsize - 16) / 12; /* dont bail on zero items */ trak->edit_list_table = calloc (trak->edit_list_count + 1, sizeof (edit_list_table_t)); if (!trak->edit_list_table) { last_error = QT_NO_MEMORY; goto free_trak; } /* load the edit list table */ for (j = 0; j < trak->edit_list_count; j++) { trak->edit_list_table[j].track_duration = _X_BE_32 (&atom[16 + j * 12 + 0]); trak->edit_list_table[j].media_time = _X_BE_32 (&atom[16 + j * 12 + 4]); if (trak->edit_list_table[j].media_time == 0xffffffff) trak->edit_list_table[j].media_time = -1ll; debug_atom_load (" %d: track duration = %"PRId64", media time = %"PRId64"\n", j, trak->edit_list_table[j].track_duration, trak->edit_list_table[j].media_time); } } } atom = atoms[4]; /* MDHD_ATOM */ atomsize = sizes[4]; if (atomsize >= 12) { const int version = atom[8]; debug_atom_load ("demux_qt: mdhd atom\n"); if (version == 0) { if (atomsize >= 30) { trak->timescale = _X_BE_32 (&atom[20]) & 0x7fffffff; trak->lang = _X_BE_16 (&atom[28]); } } else if (version == 1) { if (atomsize >= 42) { trak->timescale = _X_BE_32 (&atom[28]) & 0x7fffffff; trak->lang = _X_BE_16 (&atom[40]); } } } if (trak->timescale == 0) trak->timescale = 1; scale_int_init (&trak->si, 90000, trak->timescale); atom = atoms[5]; /* STSD_ATOM */ atomsize = sizes[5]; if (atomsize >= 16) { uint8_t *item; unsigned int k; debug_atom_load ("demux_qt: stsd atom\n"); /* Allocate space for our prop array, plus a copy of the STSD atom. * It is usually small (< 200 bytes). * All decoder config pointers will use that buf, no need to allocate separately. */ k = _X_BE_32 (&atom[12]); if (!k) { last_error = QT_HEADER_TROUBLE; goto free_trak; } /* safety */ if (k > 32) k = 32; item = malloc (k * sizeof (properties_t) + atomsize); if (!item) { last_error = QT_NO_MEMORY; goto free_trak; } memset (item, 0, k * sizeof (properties_t)); trak->stsd_atoms = (properties_t *)item; trak->stsd_atoms_count = k; item += k * sizeof (properties_t); memcpy (item, atom, atomsize); atomsize -= 16; item += 16; /* use first properties atom for now */ trak->properties = trak->stsd_atoms; k = 0; while (k < trak->stsd_atoms_count) { static const uint32_t stsd_types[] = {ESDS_ATOM, AVCC_ATOM, HVCC_ATOM, 0}; uint32_t stsd_sizes[3]; uint8_t *stsd_atoms[3]; properties_t *p; uint32_t isize; if (atomsize < 8) break; p = trak->stsd_atoms + k; isize = _X_BE_32 (item); if (!isize) isize = atomsize; if (isize < 8) { last_error = QT_HEADER_TROUBLE; goto free_trak; } if (isize > atomsize) isize = atomsize; p->properties_atom = item; p->properties_atom_size = isize; #ifndef HAVE_ZERO_SAFE_MEM p->decoder_config_len = 0; p->decoder_config = NULL; #endif p->media_id = k + 1; p->codec_fourcc = _X_ME_32 (item + 4); _x_tag32_me2str (p->codec_str, p->codec_fourcc); p->object_type_id = -1; /* look for generic decoder config */ find_embedded_atoms (item, stsd_types, stsd_atoms, stsd_sizes); do { unsigned int j, subsize = stsd_sizes[0], len; uint8_t *subatom = stsd_atoms[0]; /* ESDS_ATOM */ if (subsize < 13) break; debug_atom_load (" qt/mpeg-4 esds atom\n"); j = 12; if (subatom[j++] == 0x03) { j += mp4_read_descr_len (subatom + j, &len); j++; } j += 2; if (subatom[j++] != 0x04) break; j += mp4_read_descr_len (subatom + j, &len); p->object_type_id = subatom[j++]; debug_atom_load (" object type id is %d\n", p->object_type_id); j += 12; if (subatom[j++] != 0x05) break; j += mp4_read_descr_len (subatom + j, &len); debug_atom_load (" decoder config is %d (0x%X) bytes long\n", len, len); if (len > isize - j) len = isize - j; p->decoder_config = subatom + j; p->decoder_config_len = len; } while (0); if (trak->type == MEDIA_VIDEO) do { /* for palette traversal */ int color_depth; int color_greyscale; if (isize < 0x24) break; /* look for decoder config */ do { if (stsd_sizes[1] > 8) { /* AVCC_ATOM */ debug_atom_load (" avcC atom\n"); p->decoder_config_len = stsd_sizes[1] - 8; p->decoder_config = stsd_atoms[1] + 8; break; } if (stsd_sizes[2] > 8) { /* HVCC_ATOM */ debug_atom_load (" hvcC atom\n"); p->decoder_config_len = stsd_sizes[2] - 8; p->decoder_config = stsd_atoms[2] + 8; break; } } while (0); /* initialize to sane values */ p->s.video.width = _X_BE_16 (item + 0x20); p->s.video.height = _X_BE_16 (item + 0x22); if (!p->s.video.width) p->s.video.height = 0; else if (!p->s.video.height) p->s.video.width = 0; p->s.video.depth = 0; /* assume no palette at first */ p->s.video.palette_count = 0; /* fetch video parameters */ k++; debug_atom_load(" video properties atom #%d [%s], %d x %d\n", k, p->codec_str, p->s.video.width, p->s.video.height); if (isize < 0x54) break; /* figure out the palette situation */ color_depth = item[0x53]; p->s.video.depth = color_depth; color_greyscale = color_depth & 0x20; color_depth &= 0x1F; /* if the depth is 2, 4, or 8 bpp, file is palettized */ if ((isize >= 0x56) && ((color_depth == 2) || (color_depth == 4) || (color_depth == 8))) { int color_flag; color_flag = _X_BE_16 (item + 0x54); if (color_greyscale) { int color_index, color_dec; p->s.video.palette_count = 1 << color_depth; /* compute the greyscale palette */ color_index = 255; color_dec = 256 / (p->s.video.palette_count - 1); for (j = 0; j < p->s.video.palette_count; j++) { p->s.video.palette[j].r = color_index; p->s.video.palette[j].g = color_index; p->s.video.palette[j].b = color_index; color_index -= color_dec; if (color_index < 0) color_index = 0; } } else if (color_flag & 0x08) { const uint8_t *color_table; /* if flag bit 3 is set, load the default palette */ p->s.video.palette_count = 1 << color_depth; if (color_depth == 2) color_table = qt_default_palette_4; else if (color_depth == 4) color_table = qt_default_palette_16; else color_table = qt_default_palette_256; for (j = 0; j < p->s.video.palette_count; j++) { p->s.video.palette[j].r = color_table[j * 4 + 0]; p->s.video.palette[j].g = color_table[j * 4 + 1]; p->s.video.palette[j].b = color_table[j * 4 + 2]; } } else { /* load the palette from the file */ if (isize >= 0x5e) { int color_start = _X_BE_32 (item + 0x56); int color_count = _X_BE_16 (item + 0x5a); int color_end = _X_BE_16 (item + 0x5c); color_end++; if (color_end > PALETTE_COUNT) color_end = PALETTE_COUNT; p->s.video.palette_count = color_end; if (color_end > (int)((isize - 0x5e) >> 3)) color_end = (isize - 0x5e) >> 3; if (color_count & 0x8000) { int j; for (j = color_start; j < color_end; j++) { p->s.video.palette[j].r = item[0x5e + j * 8 + 2]; p->s.video.palette[j].g = item[0x5e + j * 8 + 4]; p->s.video.palette[j].b = item[0x5e + j * 8 + 6]; } } else { int j; for (j = color_start; j < color_end; j++) { int color_index = _X_BE_16 (item + 0x5e + j * 8); if (color_index < p->s.video.palette_count) { p->s.video.palette[color_index].r = item[0x5e + j * 8 + 2]; p->s.video.palette[color_index].g = item[0x5e + j * 8 + 4]; p->s.video.palette[color_index].b = item[0x5e + j * 8 + 6]; } } } } } } #ifdef DEBUG_ATOM_LOAD debug_atom_load(" %d RGB colours\n", p->s.video.palette_count); for (j = 0; j < p->s.video.palette_count; j++) debug_atom_load(" %d: %3d %3d %3d\n", j, p->s.video.palette[j].r, p->s.video.palette[j].g, p->s.video.palette[j].b); #endif } while (0); else if (trak->type == MEDIA_AUDIO) do { #ifndef HAVE_ZERO_SAFE_MEM p->s.audio.wave_size = 0; p->s.audio.wave = NULL; #endif if (isize < 0x22) break; /* fetch audio parameters, assume uncompressed */ p->s.audio.sample_rate = _X_BE_16 (item + 0x20); p->s.audio.channels = p->s.audio.samples_per_frame = p->s.audio.samples_per_packet = item[0x19]; p->s.audio.bits = item[0x1b]; p->s.audio.bytes_per_sample = p->s.audio.bytes_per_packet = p->s.audio.bits / 8; p->s.audio.bytes_per_frame = p->s.audio.bytes_per_sample * p->s.audio.samples_per_frame; /* 24-bit audio doesn't always declare itself properly, and can be big- or little-endian */ if ((p->codec_fourcc == IN24_FOURCC) && (isize >= 0x52)) { p->s.audio.bits = 24; if (_X_BE_32 (item + 0x4c) == ENDA_ATOM && item[0x51]) p->codec_fourcc = NI42_FOURCC; } p->codec_buftype = _x_formattag_to_buf_audio (p->codec_fourcc); /* see if the trak deserves a promotion to VBR */ p->s.audio.vbr = (_X_BE_16 (item + 0x1c) == 0xFFFE) ? 1 : 0; /* in mp4 files the audio fourcc is always 'mp4a' - the codec is * specified by the object type id field in the esds atom */ if (p->codec_fourcc == MP4A_FOURCC) { static const uint8_t atag_index[256] = { [0x40] = 0, /* AAC, MP4ALS */ [0x66] = 0, /* MPEG2 AAC Main */ [0x67] = 0, /* MPEG2 AAC Low */ [0x68] = 0, /* MPEG2 AAC SSR */ [0x69] = 1, /* MP3 13818-3, MP2 11172-3 */ [0x6B] = 1, /* MP3 11172-3 */ [0xA5] = 2, /* AC3 */ [0xA6] = 3, /* EAC3 */ [0xA9] = 4, /* DTS mp4ra.org */ [0xDD] = 5, /* Vorbis non standard, gpac uses it */ [0xE1] = 6, /* QCELP */ }; static const struct { uint32_t buftype; char name[8]; } atag_info[7] = { [0] = { BUF_AUDIO_AAC, "aac" }, /** << note: using this as default. */ [1] = { BUF_AUDIO_MPEG, "mp3" }, [2] = { BUF_AUDIO_A52, "ac3" }, [3] = { BUF_AUDIO_EAC3, "eac3" }, [4] = { BUF_AUDIO_DTS, "dts" }, [5] = { BUF_AUDIO_VORBIS, "vorbis" }, [6] = { BUF_AUDIO_QCLP, "qcelp" }, }; p->s.audio.vbr = 1; p->codec_buftype = atag_info[atag_index[p->object_type_id & 255]].buftype; strcpy (p->codec_str, atag_info[atag_index[p->object_type_id & 255]].name); } /* if this is MP4 audio, mark the trak as VBR */ else if ((p->codec_fourcc == SAMR_FOURCC) || (p->codec_fourcc == AC_3_FOURCC) || (p->codec_fourcc == EAC3_FOURCC) || (p->codec_fourcc == QCLP_FOURCC)) { p->s.audio.vbr = 1; } else if (p->codec_fourcc == ALAC_FOURCC) { p->s.audio.vbr = 1; if (isize >= 0x24 + 36) { /* further, FFmpeg's ALAC decoder requires 36 out-of-band bytes */ p->decoder_config_len = 36; p->decoder_config = item + 0x24; } } /* special case time: A lot of CBR audio codecs stored in the * early days lacked the extra header; compensate */ else if (p->codec_fourcc == IMA4_FOURCC) { p->s.audio.samples_per_packet = 64; p->s.audio.bytes_per_packet = 34; p->s.audio.bytes_per_frame = 34 * p->s.audio.channels; p->s.audio.bytes_per_sample = 2; p->s.audio.samples_per_frame = 64 * p->s.audio.channels; } else if (p->codec_fourcc == MAC3_FOURCC) { p->s.audio.samples_per_packet = 3; p->s.audio.bytes_per_packet = 1; p->s.audio.bytes_per_frame = 1 * p->s.audio.channels; p->s.audio.bytes_per_sample = 1; p->s.audio.samples_per_frame = 3 * p->s.audio.channels; } else if (p->codec_fourcc == MAC6_FOURCC) { p->s.audio.samples_per_packet = 6; p->s.audio.bytes_per_packet = 1; p->s.audio.bytes_per_frame = 1 * p->s.audio.channels; p->s.audio.bytes_per_sample = 1; p->s.audio.samples_per_frame = 6 * p->s.audio.channels; } else if (p->codec_fourcc == ALAW_FOURCC) { p->s.audio.samples_per_packet = 1; p->s.audio.bytes_per_packet = 1; p->s.audio.bytes_per_frame = 1 * p->s.audio.channels; p->s.audio.bytes_per_sample = 2; p->s.audio.samples_per_frame = 2 * p->s.audio.channels; } else if (p->codec_fourcc == ULAW_FOURCC) { p->s.audio.samples_per_packet = 1; p->s.audio.bytes_per_packet = 1; p->s.audio.bytes_per_frame = 1 * p->s.audio.channels; p->s.audio.bytes_per_sample = 2; p->s.audio.samples_per_frame = 2 * p->s.audio.channels; } else if (p->codec_fourcc == DRMS_FOURCC) { last_error = QT_DRM_NOT_SUPPORTED; goto free_trak; } /* it's time to dig a little deeper to determine the real audio * properties; if a the stsd compressor atom has 0x24 bytes, it * appears to be a handler for uncompressed data; if there are an * extra 0x10 bytes, there are some more useful decoding params; * further, do not do load these parameters if the audio is just * PCM ('raw ', 'twos', 'sowt' or 'in24') */ if ((isize >= 0x34) && (p->codec_fourcc != AC_3_FOURCC) && (p->codec_fourcc != EAC3_FOURCC) && (p->codec_fourcc != TWOS_FOURCC) && (p->codec_fourcc != SOWT_FOURCC) && (p->codec_fourcc != RAW_FOURCC) && (p->codec_fourcc != IN24_FOURCC) && (p->codec_fourcc != NI42_FOURCC)) { if (_X_BE_32 (item + 0x24)) p->s.audio.samples_per_packet = _X_BE_32 (item + 0x24); if (_X_BE_32 (item + 0x28)) p->s.audio.bytes_per_packet = _X_BE_32 (item + 0x28); if (_X_BE_32 (item + 0x2c)) p->s.audio.bytes_per_frame = _X_BE_32 (item + 0x2c); if (_X_BE_32 (item + 0x30)) p->s.audio.bytes_per_sample = _X_BE_32 (item + 0x30); if (p->s.audio.bytes_per_packet) p->s.audio.samples_per_frame = (p->s.audio.bytes_per_frame / p->s.audio.bytes_per_packet) * p->s.audio.samples_per_packet; } /* div by 0 safety */ if (!p->s.audio.samples_per_frame) p->s.audio.samples_per_frame = 1; /* check for a MS-style WAVE format header */ if ((isize >= 0x50) && (_X_BE_32 (item + 0x38) == WAVE_ATOM) && (_X_BE_32 (item + 0x40) == FRMA_ATOM) && (_X_ME_32 (item + 0x4c) == p->codec_fourcc)) { unsigned int wave_size = _X_BE_32 (item + 0x48); if ((wave_size >= sizeof (xine_waveformatex) + 8) && (isize >= (0x50 + wave_size - 8))) { wave_size -= 8; p->s.audio.wave_size = wave_size; p->s.audio.wave = malloc (wave_size); if (!p->s.audio.wave) { last_error = QT_NO_MEMORY; goto free_trak; } memcpy (p->s.audio.wave, item + 0x50, wave_size); _x_waveformatex_le2me (p->s.audio.wave); } } k++; debug_atom_load(" audio properties atom #%d [%s], %d Hz, %d bits, %d channels, %s\n", k, p->codec_str, p->s.audio.sample_rate, p->s.audio.bits, p->s.audio.channels, (p->s.audio.vbr) ? "vbr, " : ""); if (isize > 0x28) { debug_atom_load(" %d samples/packet, %d bytes/packet, %d bytes/frame\n", p->s.audio.samples_per_packet, p->s.audio.bytes_per_packet, p->s.audio.bytes_per_frame); debug_atom_load(" %d bytes/sample (%d samples/frame)\n", p->s.audio.bytes_per_sample, p->s.audio.samples_per_frame); } } while (0); else { /* MEDIA_OTHER */ k++; } /* forward to the next atom */ item += isize; atomsize -= isize; } trak->stsd_atoms_count = k; if (!k) goto free_trak; } atom = atoms[6]; /* STSZ_ATOM */ atomsize = sizes[6]; if (atomsize >= 20) { trak->sample_size = _X_BE_32(&atom[12]); /* load table only if sample size is 0 */ /* there may be 0 items + moof fragments later */ if (trak->sample_size == 0) { trak->sample_size_count = _X_BE_32(&atom[16]); trak->samples = trak->sample_size_count; if (trak->sample_size_count > (atomsize - 20) / 4) trak->sample_size_count = (atomsize - 20) / 4; debug_atom_load (" qt stsz atom (sample size atom): sample size = %d, %d entries\n", trak->sample_size, trak->sample_size_count); trak->sample_size_table = atom + 20; trak->sample_size_bytes = 4; trak->sample_size_shift = 0; } } else { atom = atoms[13]; /* STZ2_ATOM */ atomsize = sizes[13]; if (atomsize >= 20) { trak->sample_size_count = _X_BE_32 (&atom[16]); trak->sample_size_table = atom + 20; if (atom[15] == 16) { trak->sample_size_bytes = 2; trak->sample_size_shift = 16; if (trak->sample_size_count > (atomsize - 20) / 2) trak->sample_size_count = (atomsize - 20) / 2; } else if (atom[15] == 8) { trak->sample_size_bytes = 1; trak->sample_size_shift = 24; if (trak->sample_size_count > (atomsize - 20)) trak->sample_size_count = atomsize - 20; } else { /* There is also a 4bit mode but i never saw all <= 15 byte frames. */ trak->sample_size_count = 0; trak->sample_size_table = NULL; } } } atom = atoms[7]; /* STSS_ATOM */ atomsize = sizes[7]; if (atomsize >= 16) { trak->sync_sample_count = _X_BE_32 (&atom[12]); if (trak->sync_sample_count > (atomsize - 16) / 4) trak->sync_sample_count = (atomsize - 16) / 4; debug_atom_load (" qt stss atom (sample sync atom): %d sync samples\n", trak->sync_sample_count); trak->sync_sample_table = atom + 16; } atom = atoms[8]; /* STCO_ATOM */ atomsize = sizes[8]; if (atomsize >= 16) { trak->chunk_offset_count = _X_BE_32 (&atom[12]); debug_atom_load (" qt stco atom (32-bit chunk offset atom): %d chunk offsets\n", trak->chunk_offset_count); if (trak->chunk_offset_count > (atomsize - 16) / 4) trak->chunk_offset_count = (atomsize - 16) / 4; trak->chunk_offset_table32 = atom + 16; } else { atom = atoms[9]; /* CO64_ATOM */ atomsize = sizes[9]; if (atomsize >= 16) { trak->chunk_offset_count = _X_BE_32 (&atom[12]); if (trak->chunk_offset_count > (atomsize - 16) / 8) trak->chunk_offset_count = (atomsize - 16) / 8; debug_atom_load (" qt co64 atom (64-bit chunk offset atom): %d chunk offsets\n", trak->chunk_offset_count); trak->chunk_offset_table64 = atom + 16; } } atom = atoms[10]; /* STSC_ATOM */ atomsize = sizes[10]; if (atomsize >= 16) { unsigned int j; trak->sample_to_chunk_count = _X_BE_32 (&atom[12]); if (trak->sample_to_chunk_count > (atomsize - 16) / 12) trak->sample_to_chunk_count = (atomsize - 16) / 12; debug_atom_load (" qt stsc atom (sample-to-chunk atom): %d entries\n", trak->sample_to_chunk_count); trak->sample_to_chunk_table = calloc (trak->sample_to_chunk_count + 1, sizeof (sample_to_chunk_table_t)); if (!trak->sample_to_chunk_table) { last_error = QT_NO_MEMORY; goto free_trak; } /* load the sample to chunk table */ for (j = 0; j < trak->sample_to_chunk_count; j++) { trak->sample_to_chunk_table[j].first_chunk = _X_BE_32 (&atom[16 + j * 12 + 0]); trak->sample_to_chunk_table[j].samples_per_chunk = _X_BE_32 (&atom[16 + j * 12 + 4]); trak->sample_to_chunk_table[j].media_id = _X_BE_32 (&atom[16 + j * 12 + 8]); debug_atom_load (" %d: %d samples/chunk starting at chunk %d (%d) for media id %d\n", j, trak->sample_to_chunk_table[j].samples_per_chunk, trak->sample_to_chunk_table[j].first_chunk, trak->sample_to_chunk_table[j].first_chunk - 1, trak->sample_to_chunk_table[j].media_id); } } atom = atoms[11]; /* STTS_ATOM */ atomsize = sizes[11]; if (atomsize >= 16) { trak->time_to_sample_count = _X_BE_32 (&atom[12]); debug_atom_load (" qt stts atom (time-to-sample atom): %d entries\n", trak->time_to_sample_count); if (trak->time_to_sample_count > (atomsize - 16) / 8) trak->time_to_sample_count = (atomsize - 16) / 8; trak->time_to_sample_table = atom + 16; } atom = atoms[12]; /* CTTS_ATOM */ atomsize = sizes[12]; if (atomsize >= 16) { /* TJ. this has the same format as stts. If present, duration here means (pts - dts), while the corresponding stts defines dts. */ trak->timeoffs_to_sample_count = _X_BE_32 (&atom[12]); debug_atom_load (" qt ctts atom (timeoffset-to-sample atom): %d entries\n", trak->timeoffs_to_sample_count); if (trak->timeoffs_to_sample_count > (atomsize - 16) / 8) trak->timeoffs_to_sample_count = (atomsize - 16) / 8; trak->timeoffs_to_sample_table = atom + 16; } return QT_OK; /* jump here to make sure everything is free'd and avoid leaking memory */ free_trak: free(trak->edit_list_table); free(trak->sample_to_chunk_table); free(trak->stsd_atoms); return last_error; } /* Traverse through a reference atom and extract the URL and data rate. */ static qt_error parse_reference_atom (demux_qt_t *this, uint8_t *ref_atom, char *base_mrl) { unsigned int sizes[4]; reference_t ref; uint8_t *atoms[4] = { NULL, NULL, NULL, NULL }; static const uint32_t types_ref[] = { URL__ATOM, RMDR_ATOM, QTIM_ATOM, 0 }; /* initialize reference atom */ ref.url = NULL; ref.data_rate = 0; ref.qtim_version = 0; atom_scan (ref_atom, 4, types_ref, atoms, sizes); if (sizes[0] > 12) { size_t string_size = _X_BE_32 (&atoms[0][8]); size_t url_offset = 0; int http = 0; if (12 + string_size > sizes[0]) return QT_NOT_A_VALID_FILE; /* if the URL starts with "http://", copy it */ if (string_size >= 7 && memcmp (&atoms[0][12], "http://", 7) && memcmp (&atoms[0][12], "rtsp://", 7) && base_mrl) { /* We need a "qt" prefix hack for Apple trailers */ http = !strncasecmp (base_mrl, "http://", 7); url_offset = strlen(base_mrl) + 2 * http; } if (url_offset >= 0x80000000) return QT_NOT_A_VALID_FILE; /* otherwise, append relative URL to base MRL */ string_size += url_offset; ref.url = calloc (1, string_size + 1); if (url_offset) sprintf (ref.url, "%s%s", http ? "qt" : "", base_mrl); memcpy (ref.url + url_offset, &atoms[0][12], _X_BE_32 (&atoms[0][8])); ref.url[string_size] = '\0'; debug_atom_load (" qt rdrf URL reference:\n %s\n", ref.url); } if (sizes[1] >= 16) { /* load the data rate */ ref.data_rate = _X_BE_32 (&atoms[1][12]); ref.data_rate *= 10; debug_atom_load (" qt rmdr data rate = %"PRId64"\n", ref.data_rate); } if (sizes[2] >= 10) { ref.qtim_version = _X_BE_16 (&atoms[2][8]); debug_atom_load (" qtim version = %04X\n", ref.qtim_version); } if (ref.url) { this->qt.references = realloc (this->qt.references, (this->qt.reference_count + 1) * sizeof (reference_t)); if (this->qt.references) this->qt.references[this->qt.reference_count++] = ref; } return QT_OK; } static void qt_normpos_init (demux_qt_t *this) { uint32_t n = this->qt.msecs, dbits = 32, sbits; while (!(n & 0x80000000)) dbits--, n <<= 1; /* _mul setup limit: sbits <= 64 - 16 * mbits = 16 + sbits - dbits; * _mul usage limit: mbits <= 64 - dbits * 16 + sbits - dbits <= 64 - dbits * sbits <= 48 * usage simplifiction: mbits <= 32 * 16 + sbits - dbits <= 32 * sbits <= 16 + dbits */ sbits = 16 + dbits - 1; /* safety */ this->qt.normpos_shift = sbits; this->qt.normpos_mul = ((uint64_t)0xffff << sbits) / (uint32_t)this->qt.msecs; } static int32_t qt_msec_2_normpos (demux_qt_t *this, int32_t msec) { return ((uint64_t)msec * this->qt.normpos_mul) >> this->qt.normpos_shift; } static int32_t qt_pts_2_msecs (int64_t pts) { #ifdef ARCH_X86_32 return (pts * (int32_t)((((uint32_t)1 << 31) + 22) / 45)) >> 32; #else return pts / 90; #endif } #define KEYFRAMES_SIZE 1024 static void qt_keyframes_size (qt_trak *trak, uint32_t n) { xine_keyframes_entry_t *e = trak->keyframes_list; n = (n + KEYFRAMES_SIZE - 1) & ~(KEYFRAMES_SIZE - 1); if (n > trak->keyframes_size) { e = realloc (e, n * sizeof (*e)); if (!e) return; trak->keyframes_list = e; trak->keyframes_size = n; } } static void qt_keyframes_simple_add (qt_trak *trak, qt_frame *f) { if (trak->keyframes_used < trak->keyframes_size) { xine_keyframes_entry_t *e = trak->keyframes_list; e += trak->keyframes_used++; e->msecs = qt_pts_2_msecs (f->pts); } } static qt_error build_frame_table (qt_trak *trak, unsigned int global_timescale) { if ((trak->type != MEDIA_VIDEO) && (trak->type != MEDIA_AUDIO)) return QT_OK; /* Simplified ptsoffs conversion, no rounding error cumulation. */ trak->ptsoffs_mul = 90000 * (1 << 12) / trak->timescale; /* Sample to chunk sanity test. */ if (trak->sample_to_chunk_count) { unsigned int i; sample_to_chunk_table_t *e = trak->sample_to_chunk_table + trak->sample_to_chunk_count; /* add convenience tail, table is large enough. */ e[0].first_chunk = trak->chunk_offset_count + 1; for (i = trak->sample_to_chunk_count; i; i--) { e--; if (e[0].first_chunk == 0) e[0].first_chunk = 1; if (e[0].first_chunk > e[1].first_chunk) e[0].first_chunk = e[1].first_chunk; if (e[0].media_id > trak->stsd_atoms_count) { printf ("QT: help! media ID out of range! (%u > %u)\n", e[0].media_id, trak->stsd_atoms_count); e[0].media_id = 0; } } } /* AUDIO and OTHER frame types follow the same rules; VIDEO and vbr audio * frame types follow a different set */ if ((trak->type == MEDIA_VIDEO) || ((trak->type == MEDIA_AUDIO) && (trak->properties->s.audio.vbr))) { /* maintain counters for each of the subtracks within the trak */ int *media_id_counts = NULL; qt_frame *frame; unsigned int samples_per_frame; /* test for legacy compressed audio */ if ((trak->type == MEDIA_AUDIO) && (trak->properties->s.audio.samples_per_frame > 1) && (trak->time_to_sample_count == 1) && (_X_BE_32 (&trak->time_to_sample_table[4]) == 1)) /* Oh dear. Old style. */ samples_per_frame = trak->properties->s.audio.samples_per_frame; else samples_per_frame = 1; /* figure out # of samples */ trak->frame_count = 0; { unsigned int u; int n = trak->chunk_offset_count; if (!n) return QT_OK; if (!trak->sample_to_chunk_count) return QT_OK; for (u = 0; u + 1 < trak->sample_to_chunk_count; u++) { int j, s = trak->sample_to_chunk_table[u].samples_per_chunk; if ((samples_per_frame != 1) && (s % samples_per_frame)) return QT_OK; /* unaligned chunk, should not happen */ j = trak->sample_to_chunk_table[u + 1].first_chunk - trak->sample_to_chunk_table[u].first_chunk; if (j > n) j = n; trak->frame_count += j * s; n -= j; } trak->frame_count += n * trak->sample_to_chunk_table[u].samples_per_chunk; } trak->frame_count = (trak->frame_count + samples_per_frame - 1) / samples_per_frame; if (!trak->frame_count) return QT_OK; /* 1 more for convenient end marker. */ trak->frames = malloc ((trak->frame_count + 1) * sizeof (qt_frame)); if (!trak->frames) return QT_NO_MEMORY; frame = trak->frames; frame->pts = 0; trak->current_frame = 0; media_id_counts = calloc (trak->stsd_atoms_count + 1, sizeof (int)); if (!media_id_counts) { free (trak->frames); trak->frames = NULL; return QT_NO_MEMORY; } { unsigned int u; /* initialize more accounting variables */ /* file position */ const uint8_t *o = trak->chunk_offset_table32 ? trak->chunk_offset_table32 : trak->chunk_offset_table64; uint64_t offset_value = 0; /* size */ const uint8_t *s = trak->sample_size_table; uint32_t size_left = trak->sample_size_count; uint32_t size_value = trak->sample_size; /* sample duration */ const uint8_t *p = trak->time_to_sample_table; uint32_t duration_left = trak->time_to_sample_count; uint32_t duration_countdown = 0; uint32_t duration_value = 1; int64_t pts_value = 0; /* used by reordered video */ const uint8_t *q = trak->timeoffs_to_sample_table; uint32_t ptsoffs_left = trak->timeoffs_to_sample_count; uint32_t ptsoffs_countdown = 0; int32_t ptsoffs_value = 0; if (samples_per_frame != 1) { /* Old style demuxing. Tweak our frame builder. * Treating whole chunks as frames would be faster, but unfortunately * some ffmpeg decoders dont like multiple frames in one go. */ size_left = 0; size_value = trak->properties->s.audio.bytes_per_frame; duration_left = 0; duration_value = samples_per_frame; ptsoffs_left = 0; trak->samples = _X_BE_32 (trak->time_to_sample_table) / samples_per_frame; } /* iterate through each start chunk in the stsc table */ for (u = 0; u < trak->sample_to_chunk_count; u++) { unsigned int keyframe_default = trak->sync_sample_table ? 0 : 1; unsigned int media_id = trak->sample_to_chunk_table[u].media_id; int _samples_per_chunk = trak->sample_to_chunk_table[u].samples_per_chunk; unsigned int sn; /* Iterate from the first chunk of the current table entry to * the first chunk of the next table entry. * Entries are 1 based. * If the first chunk is in the last table entry, iterate to the * final chunk number (the number of offsets in stco table). */ sn = trak->sample_to_chunk_table[u + 1].first_chunk - trak->sample_to_chunk_table[u].first_chunk; /* iterate through each sample in a chunk */ while (sn--) { int samples_per_chunk = _samples_per_chunk; if (trak->chunk_offset_table32) offset_value = _X_BE_32 (o), o += 4; else offset_value = _X_BE_64 (o), o += 8; while (samples_per_chunk > 0) { /* figure out the offset and size. * far most files use 4 byte sizes, optimize for them. * for others, moov buffer is safety padded. */ if (size_left) { size_value = _X_BE_32 (s); s += trak->sample_size_bytes; size_value >>= trak->sample_size_shift; size_left--; } frame->_ffs.offset = offset_value; frame->size = size_value; offset_value += size_value; /* media id accounting */ QTF_MEDIA_ID(frame[0]) = media_id; media_id_counts[media_id] += 1; /* if there is no stss (sample sync) table, make all of the frames * keyframes; otherwise, clear the keyframe bits for now */ QTF_KEYFRAME(frame[0]) = keyframe_default; /* figure out the pts situation */ if (!duration_countdown && duration_left) { duration_countdown = _X_BE_32 (p); p += 4; duration_value = _X_BE_32 (p); p += 4; duration_left--; } frame->pts = pts_value; pts_value += duration_value; duration_countdown--; /* offset pts for reordered video */ if (!ptsoffs_countdown && ptsoffs_left) { unsigned int v; ptsoffs_countdown = _X_BE_32 (q); q += 4; v = _X_BE_32 (q); q += 4; /* TJ. this is 32 bit signed. */ ptsoffs_value = v; if ((sizeof (int) > 4) && (ptsoffs_value & 0x80000000)) ptsoffs_value |= ~0xffffffffL; ptsoffs_left--; } frame->ptsoffs = ptsoffs_value; ptsoffs_countdown--; if (!trak->edit_list_count) { scale_int_do (&trak->si, &frame->pts); frame->ptsoffs = (frame->ptsoffs * trak->ptsoffs_mul) >> 12; } frame++; samples_per_chunk -= samples_per_frame; } } } /* provide append time for fragments */ trak->fragment_dts = pts_value; /* convenience frame */ frame->pts = pts_value; if (!trak->edit_list_count) scale_int_do (&trak->si, &frame->pts); } /* was the last chunk incomplete? */ if (trak->samples && (trak->samples < trak->frame_count)) trak->frame_count = trak->samples; /* fill in the keyframe information */ qt_keyframes_size (trak, trak->sync_sample_count); if (!trak->edit_list_count && (trak->keyframes_size >= trak->sync_sample_count)) { unsigned int u; uint8_t *p = trak->sync_sample_table; for (u = 0; u < trak->sync_sample_count; u++) { unsigned int fr = _X_BE_32 (p); p += 4; if ((fr > 0) && (fr <= trak->frame_count)) { QTF_KEYFRAME(trak->frames[fr - 1]) = 1; /* we already have xine pts, register them */ qt_keyframes_simple_add (trak, trak->frames + fr - 1); } } } else { unsigned int u; uint8_t *p = trak->sync_sample_table; for (u = 0; u < trak->sync_sample_count; u++) { unsigned int fr = _X_BE_32 (p); p += 4; if ((fr > 0) && (fr <= trak->frame_count)) QTF_KEYFRAME(trak->frames[fr - 1]) = 1; } } /* decide which video properties atom to use */ { unsigned int u; int atom_to_use = 0; for (u = 1; u < trak->stsd_atoms_count; u++) if (media_id_counts[u + 1] > media_id_counts[u]) atom_to_use = u; trak->properties = &trak->stsd_atoms[atom_to_use]; } free(media_id_counts); } else { /* trak->type == MEDIA_AUDIO */ unsigned int u; int64_t pts_value = 0; const uint8_t *p = trak->chunk_offset_table32 ? trak->chunk_offset_table32 : trak->chunk_offset_table64; /* in this case, the total number of frames is equal to the number of chunks */ trak->frame_count = trak->chunk_offset_count; trak->frames = malloc ((trak->frame_count + 1) * sizeof (qt_frame)); if (!trak->frames) return QT_NO_MEMORY; trak->frames[0].pts = 0; /* iterate through each start chunk in the stsc table */ for (u = 0; u < trak->sample_to_chunk_count; u++) { uint32_t media_id = trak->sample_to_chunk_table[u].media_id; /* the chunk size is actually the audio frame count */ uint32_t duration = trak->sample_to_chunk_table[u].samples_per_chunk; uint32_t fsize = (duration * trak->properties->s.audio.channels) / trak->properties->s.audio.samples_per_frame * trak->properties->s.audio.bytes_per_frame; /* iterate through each sample in a chunk and fill in size and * pts information */ qt_frame *af = trak->frames + trak->sample_to_chunk_table[u].first_chunk - 1; /* Iterate from the first chunk of the current table entry to * the first chunk of the next table entry. * Entries are 1 based. * If the first chunk is in the last table entry, iterate to the * final chunk number (the number of offsets in stco table) */ unsigned int sn = trak->sample_to_chunk_table[u + 1].first_chunk - trak->sample_to_chunk_table[u].first_chunk; while (sn--) { /* figure out the pts for this chunk */ af->pts = pts_value; if (!trak->edit_list_count) { scale_int_do (&trak->si, &af->pts); } pts_value += duration; af->ptsoffs = 0; if (trak->chunk_offset_table32) af->_ffs.offset = _X_BE_32 (p), p += 4; else af->_ffs.offset = _X_BE_64 (p), p += 8; /* fetch the alleged chunk size according to the QT header */ af->size = fsize; /* media id accounting */ QTF_MEDIA_ID(af[0]) = media_id; QTF_KEYFRAME(af[0]) = 0; af++; } /* convenience frame */ af->pts = pts_value; if (!trak->edit_list_count) { scale_int_do (&trak->si, &af->pts); } } /* provide append time for fragments */ trak->fragment_dts = pts_value; } if (trak->frame_count && trak->edit_list_count) { /* Fix up pts information w.r.t. the edit list table. * Supported: initial trak delay, gaps, and skipped intervals. * Not supported: repeating and reordering intervals. * Also, make xine timestamps right here and avoid an extra pass. */ uint32_t edit_list_index; uint32_t use_keyframes = trak->sync_sample_count && (trak->keyframes_size >= trak->sync_sample_count); int64_t edit_list_pts = 0, edit_list_duration = 0; qt_frame *sf = trak->frames, *tf = sf, *ef = sf + trak->frame_count; for (edit_list_index = 0; edit_list_index < trak->edit_list_count; edit_list_index++) { int64_t edit_list_media_time, offs = 0; /* snap to exact end of previous edit */ edit_list_pts += edit_list_duration; /* duration is in global timescale units; convert to trak timescale */ edit_list_media_time = trak->edit_list_table[edit_list_index].media_time; edit_list_duration = trak->edit_list_table[edit_list_index].track_duration; edit_list_duration *= trak->timescale; edit_list_duration /= global_timescale; /* insert delay */ if (trak->edit_list_table[edit_list_index].media_time == -1ll) continue; /* extend last edit to end of trak, why? * anyway, add 1 second and catch ptsoffs. */ if (edit_list_index == trak->edit_list_count - 1) edit_list_duration = ef->pts - edit_list_pts + trak->timescale; /* skip interval */ if (trak->sync_sample_count) { /* find edit start, and the nearest keyframe before. */ qt_frame *f = sf; for (; sf < ef; sf++) { offs = sf->pts; offs += sf->ptsoffs; offs -= edit_list_media_time; if (QTF_KEYFRAME(sf[0])) f = sf; if (offs >= 0) break; } if (sf == ef) break; offs -= sf->ptsoffs; edit_list_pts += offs; /* insert decoder preroll area */ for (; f < sf; f++) { if (f != tf) *tf = *f; tf->pts = edit_list_pts; scale_int_do (&trak->si, &tf->pts); tf->ptsoffs = (tf->ptsoffs * trak->ptsoffs_mul) >> 12; tf++; } } else { /* find edit start. */ for (; sf < ef; sf++) { offs = sf->pts; offs += sf->ptsoffs; offs -= edit_list_media_time; if (offs >= 0) break; } if (sf == ef) break; offs -= sf->ptsoffs; edit_list_pts += offs; } /* avoid separate end of table test */ if (edit_list_duration > ef[0].pts - sf[0].pts) edit_list_duration = ef[0].pts - sf[0].pts; /* ">= 0" is easier than "> 0" in 32bit mode */ edit_list_duration -= 1; /* insert interval */ if (sf == tf) { /* no frames skipped yet (usual case) */ do { /* this _does_ fit, see above */ uint32_t d = sf[1].pts - sf[0].pts; sf[0].pts = edit_list_pts; scale_int_do (&trak->si, &sf[0].pts); sf[0].ptsoffs = (sf[0].ptsoffs * trak->ptsoffs_mul) >> 12; if (QTF_KEYFRAME(sf[0]) & use_keyframes) qt_keyframes_simple_add (trak, sf); sf++; edit_list_pts += d; edit_list_duration -= d; } while (edit_list_duration >= 0); tf = sf; } else { /* shift out skipped frames */ do { uint32_t d = sf[1].pts - sf[0].pts; tf[0] = sf[0]; tf[0].pts = edit_list_pts; scale_int_do (&trak->si, &tf[0].pts); tf[0].ptsoffs = (tf[0].ptsoffs * trak->ptsoffs_mul) >> 12; if (QTF_KEYFRAME(tf[0]) & use_keyframes) qt_keyframes_simple_add (trak, tf); sf++; tf++; edit_list_pts += d; edit_list_duration -= d; } while (edit_list_duration >= 0); } edit_list_duration += 1; edit_list_pts -= offs; } trak->fragment_dts = edit_list_pts; /* convenience frame */ tf->pts = edit_list_pts; scale_int_do (&trak->si, &tf[0].pts); trak->frame_count = tf - trak->frames; } #ifdef DEBUG_EDIT_LIST { unsigned int u; qt_frame *f = trak->frames; for (u = 0; u <= trak->frame_count; u++) { debug_edit_list (" final pts for sample %u = %"PRId64"\n", u, f->pts); f++; } } #endif return QT_OK; } /************************************************************************ * Fragment stuff * ************************************************************************/ static int demux_qt_load_fragment_index (demux_qt_t *this, const uint8_t *head, uint32_t hsize) { uint32_t inum, timebase; { uint8_t fullhead[32]; uint32_t isize; int n = 32 - hsize; if (hsize) memcpy (fullhead, head, hsize); if (n > 0) { if (this->input->read (this->input, fullhead + hsize, n) != n) return 0; } isize = _X_BE_32 (fullhead); if (isize < 32) return 0; inum = _X_BE_32 (fullhead + 28); if (inum > (isize - 32) / 12) inum = (isize - 32) / 12; timebase = _X_BE_32 (fullhead + 16); if (!timebase) timebase = this->qt.timescale; } { xine_mfrag_list_t *fraglist = NULL; if (this->input->get_optional_data (this->input, &fraglist, INPUT_OPTIONAL_DATA_FRAGLIST) == INPUT_OPTIONAL_SUCCESS) this->qt.fraglist = fraglist; } xine_mfrag_set_index_frag (this->qt.fraglist, 0, timebase, -1); { uint32_t idx = 1; inum += 1; while (idx < inum) { uint8_t buf[256 * 12], *p; uint32_t stop = idx + sizeof (buf) / 12; if (stop > inum) stop = inum; if (this->input->read (this->input, buf, (stop - idx) * 12) != (int32_t)((stop - idx) * 12)) break; p = buf; while (idx < stop) { xine_mfrag_set_index_frag (this->qt.fraglist, idx, _X_BE_32 (p + 4), _X_BE_32 (p)); p += 12; idx += 1; } } } if (this->qt.fraglist) { int64_t d, l; unsigned int v, s, m; inum = xine_mfrag_get_frag_count (this->qt.fraglist); xine_mfrag_get_index_start (this->qt.fraglist, inum + 1, &d, &l); v = d / timebase; s = v % 60; v /= 60; m = v % 60; v /= 60; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: found index of %u fragments, %"PRId64" bytes, %0u:%02u:%02u.\n", (unsigned int)inum, l, v, m, s); return 1; } return 0; } static qt_trak *find_trak_by_id (demux_qt_t *this, int id) { unsigned int i; for (i = 0; i < this->qt.trak_count; i++) { if (this->qt.traks[i].id == id) return &(this->qt.traks[i]); } return NULL; } static int parse_mvex_atom (demux_qt_t *this, uint8_t *mvex_atom, unsigned int bufsize) { unsigned int i, mvex_size; uint32_t traknum = 0, subtype, subsize = 0; qt_trak *trak; /* limit to atom size */ if (bufsize < 8) return 0; mvex_size = _X_BE_32 (mvex_atom); if (bufsize < mvex_size) mvex_size = bufsize; /* scan subatoms */ for (i = 8; i + 8 <= mvex_size; i += subsize) { subsize = _X_BE_32 (&mvex_atom[i]); subtype = _X_BE_32 (&mvex_atom[i + 4]); if (subsize == 0) subsize = mvex_size - i; if ((subsize < 8) || (i + subsize > mvex_size)) break; switch (subtype) { case MEHD_ATOM: break; case TREX_ATOM: if (subsize < 8 + 24) break; traknum = _X_BE_32 (&mvex_atom[i + 8 + 4]); trak = find_trak_by_id (this, traknum); if (!trak) break; trak->default_sample_description_index = _X_BE_32 (&mvex_atom[i + 8 + 8]); trak->default_sample_duration = _X_BE_32 (&mvex_atom[i + 8 + 12]); trak->default_sample_size = _X_BE_32 (&mvex_atom[i + 8 + 16]); trak->default_sample_flags = _X_BE_32 (&mvex_atom[i + 8 + 20]); if (!trak->frame_count) { trak->fragment_dts = 0; /* No frames defined yet. Apply initial delay if present. * There are 2 ways for an edit list to do that: * 1. A gap descriptor with media_time == -1. This is easy. * 2. A regular interval descriptor with media_time _before_ * first frame pts (dts + ptsoffs). We can only flag that here, * and apply later when we saw that frame. */ if (trak->edit_list_count) { unsigned int n = 0; if (trak->edit_list_table[0].media_time == -1ll) { /* Gap. Duration is in global timescale units; convert to trak timescale. */ int64_t d; d = trak->edit_list_table[0].track_duration; if (d > 0) { d *= trak->timescale; d /= this->qt.timescale; trak->fragment_dts = d; } n = 1; } if ((trak->edit_list_count > n) && (trak->edit_list_table[n].media_time != -1ll)) { /* Interval. Flag for parse_traf_atom (). */ trak->delay_index = n; } } } trak->fragment_frames = trak->frame_count; this->qt.fragment_count = 0; break; default: ; } } return 1; } static int parse_traf_atom (demux_qt_t *this, uint8_t *traf_atom, unsigned int trafsize, off_t moofpos) { unsigned int i, done = 0; uint32_t subtype, subsize = 0; uint32_t sample_description_index = 0; uint32_t default_sample_duration = 0; uint32_t default_sample_size = 0; uint32_t default_sample_flags = 0; off_t base_data_offset = 0, data_pos = 0; qt_trak *trak = NULL; for (i = 8; i + 8 <= trafsize; i += subsize) { subsize = _X_BE_32 (&traf_atom[i]); subtype = _X_BE_32 (&traf_atom[i + 4]); if (subsize == 0) subsize = trafsize - i; if ((subsize < 8) || (i + subsize > trafsize)) break; switch (subtype) { case TFHD_ATOM: { uint32_t tfhd_flags; uint8_t *p; if (subsize < 8 + 8) break; p = traf_atom + i + 8; tfhd_flags = _X_BE_32 (p); p += 4; trak = find_trak_by_id (this, _X_BE_32 (p)); p += 4; { unsigned int n; n = ((tfhd_flags << 3) & 8) + ((tfhd_flags << 1) & 4) + ((tfhd_flags >> 1) & 4) + ((tfhd_flags >> 2) & 4) + ((tfhd_flags >> 3) & 4) + 8 + 8; if (subsize < n) trak = NULL; } if (!trak) break; if (tfhd_flags & 1) base_data_offset = _X_BE_64 (p), p += 8; else base_data_offset = moofpos; data_pos = base_data_offset; if (tfhd_flags & 2) sample_description_index = _X_BE_32 (p), p += 4; else sample_description_index = trak->default_sample_description_index; if (tfhd_flags & 8) default_sample_duration = _X_BE_32 (p), p += 4; else default_sample_duration = trak->default_sample_duration; if (tfhd_flags & 0x10) default_sample_size = _X_BE_32 (p), p += 4; else default_sample_size = trak->default_sample_size; if (tfhd_flags & 0x20) default_sample_flags = _X_BE_32 (p), p += 4; else default_sample_flags = trak->default_sample_flags; break; } case TRUN_ATOM: { uint32_t trun_flags; uint32_t samples; uint32_t sample_duration, sample_size; uint32_t first_sample_flags, sample_flags; int64_t sample_dts; uint8_t *p; qt_frame *frame; /* get head */ if (!trak) break; if (subsize < 8 + 8) break; p = traf_atom + i + 8; trun_flags = _X_BE_32 (p); p += 4; samples = _X_BE_32 (p); p += 4; { unsigned int n; n = ((trun_flags << 2) & 4) + ( trun_flags & 4) + 8 + 8; if (subsize < n) break; } if (trun_flags & 1) { uint32_t o = _X_BE_32 (p); p += 4; data_pos = base_data_offset + (off_t)((int32_t)o); } if (trun_flags & 4) first_sample_flags = _X_BE_32 (p), p += 4; else first_sample_flags = default_sample_flags; /* truncation paranoia */ { unsigned int n; n = ((trun_flags >> 6) & 4) + ((trun_flags >> 7) & 4) + ((trun_flags >> 8) & 4) + ((trun_flags >> 9) & 4); if (n) { n = (i + subsize - (p - traf_atom)) / n; if (samples > n) samples = n; } } if (!samples) break; /* enlarge frame table in steps of 64k frames, to avoid a flood of reallocations */ frame = trak->frames; { unsigned int n = trak->frame_count + samples; if (n + 1 > (unsigned int)trak->fragment_frames) { n = (n + 1 + 0xffff) & ~0xffff; frame = realloc (trak->frames, n * sizeof (*frame)); if (!frame) break; trak->fragment_frames = n; trak->frames = frame; } } frame += trak->frame_count; /* add pending delay. first frame dts is always 0, so just test ptsoffs. * this happens at most once, so keep it away from main loop. */ if (trak->delay_index >= 0) { uint32_t n = 0; int64_t t; if (trun_flags & 0x800) { n = ((trun_flags >> 6) & 4) + ((trun_flags >> 7) & 4) + ((trun_flags >> 8) & 4); n = _X_BE_32 (p + n); } t = trak->edit_list_table[trak->delay_index].media_time; if (t > (int)n) { /* this actually means skipping framees, and makes not much sense in fragment mode. */ t = (int)n; } trak->fragment_dts -= t; trak->delay_index = -1; } /* get defaults */ sample_dts = trak->fragment_dts; sample_duration = default_sample_duration; sample_size = default_sample_size; sample_flags = first_sample_flags; /* prepare for keyframes */ if (trak->type == MEDIA_VIDEO) qt_keyframes_size (trak, trak->keyframes_used + samples); /* add frames */ trak->frame_count += samples; switch ((trun_flags & 0xf00) >> 8) { case 0xf: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0xe: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0xd: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0xc: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0xb: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0xa: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x9: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x8: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; { uint32_t o = _X_BE_32 (p); p += 4; frame->ptsoffs = ((int)o * trak->ptsoffs_mul) >> 12; } if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x7: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x6: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x5: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x4: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; sample_flags = _X_BE_32 (p), p += 4; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x3: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x2: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; sample_size = _X_BE_32 (p), p += 4; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x1: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_duration = _X_BE_32 (p), p += 4; sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; case 0x0: do { frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); sample_dts += sample_duration; frame[0]._ffs.offset = data_pos; frame->size = sample_size; data_pos += sample_size; QTF_MEDIA_ID(frame[0]) = sample_description_index; QTF_KEYFRAME(frame[0]) = !(sample_flags & 0x10000); sample_flags = default_sample_flags; frame->ptsoffs = 0; if (QTF_KEYFRAME(frame[0])) qt_keyframes_simple_add (trak, frame); frame++; } while (--samples); break; } trak->fragment_dts = sample_dts; /* convenience frame */ frame->pts = sample_dts; scale_int_do (&trak->si, &frame->pts); done++; break; } default: ; } } return done; } static int parse_moof_atom (demux_qt_t *this, uint8_t *moof_atom, int moofsize, off_t moofpos) { int i, subtype, subsize = 0, done = 0; for (i = 8; i + 8 <= moofsize; i += subsize) { subsize = _X_BE_32 (&moof_atom[i]); subtype = _X_BE_32 (&moof_atom[i + 4]); if (subsize == 0) subsize = moofsize - i; if ((subsize < 8) || (i + subsize > moofsize)) break; switch (subtype) { case MFHD_ATOM: /* TODO: check sequence # here */ break; case TRAF_ATOM: if (parse_traf_atom (this, &moof_atom[i], subsize, moofpos)) done++; break; default: ; } } return done; } static int fragment_scan (demux_qt_t *this) { uint8_t hbuf[16]; off_t pos, fsize; uint64_t atomsize; uint32_t caps, atomtype; /* prerequisites */ if (this->qt.fragment_count < 0) return 0; caps = this->input->get_capabilities (this->input); fsize = this->input->get_length (this->input); if ((caps & INPUT_CAP_SEEKABLE) && (fsize > 0)) { /* Plain file, possibly being written right now. * Get all fragments known so far. */ int frags = 0; for (pos = this->qt.fragment_next; pos < fsize; pos += atomsize) { if (this->input->seek (this->input, pos, SEEK_SET) != pos) break; if (this->input->read (this->input, hbuf, 16) != 16) break; atomsize = _X_BE_32 (hbuf); atomtype = _X_BE_32 (hbuf + 4); if (atomsize == 0) atomsize = fsize - pos; else if (atomsize == 1) { atomsize = _X_BE_64 (hbuf + 8); if (atomsize < 16) break; } else if (atomsize < 8) break; if (atomtype == MOOF_ATOM) { if (atomsize > (80 << 20)) break; if (atomsize > this->qt.fragbuf_size) { size_t size2 = atomsize + (atomsize >> 1); uint8_t *b2 = realloc (this->qt.fragment_buf, size2); if (!b2) break; this->qt.fragment_buf = b2; this->qt.fragbuf_size = size2; } memcpy (this->qt.fragment_buf, hbuf, 16); if (atomsize > 16) { if (this->input->read (this->input, this->qt.fragment_buf + 16, atomsize - 16) != (off_t)atomsize - 16) break; } if (parse_moof_atom (this, this->qt.fragment_buf, atomsize, pos)) frags++; } else if (atomtype == SIDX_ATOM) { demux_qt_load_fragment_index (this, hbuf, 16); } } this->qt.fragment_next = pos; this->qt.fragment_count += frags; return frags; } else { /* Stay patient, get 1 fragment only. */ /* find next moof */ pos = this->qt.fragment_next; if (pos == 0) pos = this->input->get_current_pos (this->input); while (1) { uint32_t atomtype, hsize; if (pos <= 0) return 0; if (this->input->seek (this->input, pos, SEEK_SET) != pos) return 0; if (this->input->read (this->input, hbuf, 8) != 8) return 0; atomsize = _X_BE_32 (hbuf); atomtype = _X_BE_32 (hbuf + 4); if (atomtype == MOOF_ATOM) break; hsize = 8; if (atomsize < 8) { if (atomsize != 1) return 0; if (this->input->read (this->input, hbuf + 8, 8) != 8) return 0; atomsize = _X_BE_64 (hbuf + 8); if (atomsize < 16) return 0; hsize = 16; } if (atomtype == SIDX_ATOM) demux_qt_load_fragment_index (this, hbuf, hsize); pos += atomsize; } /* add it */ if (atomsize < 16) return 0; if (atomsize > (80 << 20)) return 0; if (atomsize > this->qt.fragbuf_size) { size_t size2 = atomsize + (atomsize >> 1); uint8_t *b2 = realloc (this->qt.fragment_buf, size2); if (!b2) return 0; this->qt.fragment_buf = b2; this->qt.fragbuf_size = size2; } memcpy (this->qt.fragment_buf, hbuf, 8); if (this->input->read (this->input, this->qt.fragment_buf + 8, atomsize - 8) != (off_t)atomsize - 8) return 0; if (!parse_moof_atom (this, this->qt.fragment_buf, atomsize, pos)) return 0; this->qt.fragment_count += 1; pos += atomsize; /* next should be mdat. remember its end for next try. * dont actually skip it here, we will roughly do that by playing. */ if (this->input->read (this->input, hbuf, 8) != 8) return 0; atomsize = _X_BE_32 (hbuf); if (_X_BE_32 (hbuf + 4) != MDAT_ATOM) return 0; if (atomsize < 8) { if (atomsize != 1) return 0; if (this->input->read (this->input, hbuf + 8, 8) != 8) return 0; atomsize = _X_BE_64 (hbuf + 8); if (atomsize < 16) return 0; } pos += atomsize; this->qt.fragment_next = pos; return 1; } } /************************************************************************ * /Fragment stuff * ************************************************************************/ static void info_string_from_atom (uint8_t *atom, char **target) { uint32_t size, string_size, i; if (!atom) return; size = _X_BE_32 (atom); if ((size >= 24) && (_X_BE_32 (&atom[12]) == DATA_ATOM)) { if (_X_BE_32 (&atom[16]) != 1) /* # of portions */ return; i = 24; string_size = _X_BE_32 (&atom[20]); if (string_size == 0) string_size = size - i; } else if (size >= 12) { i = 12; string_size = _X_BE_16 (&atom[8]); } else return; if (i + string_size > size) return; *target = realloc (*target, string_size + 1); if (*target == NULL) return; memcpy (*target, &atom[i], string_size); (*target)[string_size] = 0; } /* get real duration */ static void qt_update_duration (demux_qt_t *this) { qt_trak *trak = this->qt.traks; uint32_t n; for (n = this->qt.trak_count; n; n--) { if (trak->frame_count) { int32_t msecs = qt_pts_2_msecs (trak->frames[trak->frame_count].pts); if (msecs > this->qt.msecs) this->qt.msecs = msecs; } trak++; } qt_normpos_init (this); } /* * This function takes a pointer to a qt_info structure and a pointer to * a buffer containing an uncompressed moov atom. When the function * finishes successfully, qt_info will have a list of qt_frame objects, * ordered by offset. */ static void parse_moov_atom (demux_qt_t *this, uint8_t *moov_atom) { unsigned int i; int error; unsigned int sizes[20]; uint8_t *atoms[20]; unsigned int max_video_frames = 0; unsigned int max_audio_frames = 0; uint8_t *mvex_atom; int mvex_size; static const uint32_t types_base[] = { MVHD_ATOM, MVEX_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, TRAK_ATOM, 0 }; static const uint32_t types_meta[] = { NAM_ATOM, CPY_ATOM, DES_ATOM, CMT_ATOM, ART_ATOM, ALB_ATOM, GEN_ATOM, WRT_ATOM, DAY_ATOM, 0 }; static const uint32_t types_rmda[] = { RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, RMDA_ATOM, 0 }; /* make sure this is actually a moov atom (will also accept 'free' as * a special case) */ if ((_X_BE_32(&moov_atom[4]) != MOOV_ATOM) && (_X_BE_32(&moov_atom[4]) != FREE_ATOM)) { this->qt.last_error = QT_NO_MOOV_ATOM; return; } /* prowl through the moov atom looking for very specific targets */ atom_scan (moov_atom, 1, types_base, atoms, sizes); if (atoms[0]) { parse_mvhd_atom (this, atoms[0]); if (this->qt.last_error != QT_OK) return; } mvex_atom = atoms[1]; mvex_size = sizes[1]; atoms[19] = NULL; { uint8_t **a = atoms + 2; while (*a) a++; this->qt.traks = malloc ((a - (atoms + 2)) * sizeof (qt_trak)); if (!this->qt.traks) { this->qt.last_error = QT_NO_MEMORY; return; } a = atoms + 2; while (*a) { /* create a new trak structure */ this->qt.last_error = parse_trak_atom (&this->qt.traks[this->qt.trak_count], *a); if (this->qt.last_error != QT_OK) return; this->qt.trak_count++; a++; } } atom_scan (moov_atom, 4, types_meta, atoms, sizes); info_string_from_atom (atoms[0], &this->qt.name); info_string_from_atom (atoms[1], &this->qt.copyright); info_string_from_atom (atoms[2], &this->qt.description); info_string_from_atom (atoms[3], &this->qt.comment); info_string_from_atom (atoms[4], &this->qt.artist); info_string_from_atom (atoms[5], &this->qt.album); info_string_from_atom (atoms[6], &this->qt.genre); info_string_from_atom (atoms[7], &this->qt.composer); info_string_from_atom (atoms[8], &this->qt.year); atom_scan (moov_atom, 2, types_rmda, atoms, sizes); atoms[8] = NULL; { uint8_t **a = atoms; while (*a) { parse_reference_atom (this, *a, this->qt.base_mrl); a++; } } debug_atom_load(" qt: finished parsing moov atom\n"); /* build frame tables corresponding to each trak */ debug_frame_table(" qt: preparing to build %d frame tables\n", this->qt.trak_count); for (i = 0; i < this->qt.trak_count; i++) { qt_trak *trak = &this->qt.traks[i]; if (trak->type == MEDIA_VIDEO) { if (trak->properties) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: stream #%u: video [%s], %u x %u.\n", i, trak->properties->codec_str, trak->properties->s.video.width, trak->properties->s.video.height); } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: stream #%u: video [unknown].\n", i); } } else if (trak->type == MEDIA_AUDIO) { if (trak->properties) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: stream #%u: audio [%s], %uch, %uHz, %ubit.\n", i, trak->properties->codec_str, trak->properties->s.audio.channels, trak->properties->s.audio.sample_rate, trak->properties->s.audio.bits); } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: stream #%u: audio [unknown].\n", i); } } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: stream #%u: other.\n", i); } debug_frame_table(" qt: building frame table #%d (%s)\n", i, (this->qt.traks[i].type == MEDIA_VIDEO) ? "video" : "audio"); error = build_frame_table(&this->qt.traks[i], this->qt.timescale); if (error != QT_OK) { this->qt.last_error = error; return; } if (trak->frame_count) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: start %" PRId64 "pts, %u frames.\n", trak->frames[0].pts + trak->frames[0].ptsoffs, trak->frame_count); } } /* must parse mvex _after_ building traks */ if (mvex_atom) { parse_mvex_atom (this, mvex_atom, mvex_size); /* reassemble fragments, if any */ fragment_scan (this); } qt_update_duration (this); for (i = 0; i < this->qt.trak_count; i++) { qt_trak *trak = this->qt.traks + i; #if DEBUG_DUMP_MOOV unsigned int j; /* dump the frame table in debug mode */ for (j = 0; j < trak->frame_count; j++) debug_frame_table(" %d: %8X bytes @ %"PRIX64", %"PRId64" pts, media id %d%s\n", j, trak->frames[j].size, QTF_OFFSET(trak[0].frames[j]), trak->frames[j].pts, (int)QTF_MEDIA_ID(trak[0].frames[j]), (QTF_KEYFRAME(trak[0].frames[j])) ? " (keyframe)" : ""); #endif /* decide which audio trak and which video trak has the most frames */ if ((trak->type == MEDIA_VIDEO) && (trak->frame_count > max_video_frames)) { this->qt.video_trak = i; max_video_frames = trak->frame_count; if (trak->keyframes_list) { xine_keyframes_entry_t *e = trak->keyframes_list; uint32_t n = trak->keyframes_used; while (n--) { e->normpos = qt_msec_2_normpos (this, e->msecs); e++; } _x_keyframes_set (this->stream, trak->keyframes_list, trak->keyframes_used); } } else if ((trak->type == MEDIA_AUDIO) && (trak->frame_count > max_audio_frames)) { this->qt.audio_trak = i; max_audio_frames = trak->frame_count; } free (trak->keyframes_list); trak->keyframes_list = NULL; trak->keyframes_size = 0; trak->keyframes_used = 0; } /* check for references */ if (this->qt.reference_count > 0) { /* init chosen reference to the first entry */ this->qt.chosen_reference = 0; /* iterate through 1..n-1 reference entries and decide on the right one */ for (i = 1; i < this->qt.reference_count; i++) { if (this->qt.references[i].qtim_version > this->qt.references[this->qt.chosen_reference].qtim_version) this->qt.chosen_reference = i; else if ((this->qt.references[i].data_rate <= this->bandwidth) && (this->qt.references[i].data_rate > this->qt.references[this->qt.chosen_reference].data_rate)) this->qt.chosen_reference = i; } debug_atom_load(" qt: chosen reference is ref #%d, qtim version %04X, %"PRId64" bps\n URL: %s\n", this->qt.chosen_reference, this->qt.references[this->qt.chosen_reference].qtim_version, this->qt.references[this->qt.chosen_reference].data_rate, this->qt.references[this->qt.chosen_reference].url); } } static qt_error load_moov_atom (input_plugin_t *input, uint8_t **moov_atom, off_t *moov_atom_offset) { uint8_t buf[MAX_PREVIEW_SIZE] = { 0, }, *p; uint64_t size = 0; uint32_t hsize; uint32_t type = 0; uint64_t pos = 0; /* "moov" sometimes is wrongly marked as "free". Use that when there is no real one. */ uint64_t free_pos = 0; uint64_t free_size = 0; /* Quick detect non-qt files: more than 1 unknown top level atom. */ int unknown_atoms = 1; /* ffmpeg encodes .mp4 with "mdat" before "moov" because it does not know the table sizes needed before. * Some folks actually offer such files as is for streaming. * Thats why we distinctly use slow seek here as well. */ if (input->get_capabilities (input) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) { while (1) { hsize = 8; if (input->seek (input, pos, SEEK_SET) != (off_t)pos) break; if (input->read (input, buf, 8) != 8) break; size = _X_BE_32 (buf); if (size == 1) { hsize = 16; if (input->read (input, buf + 8, 8) != 8) return QT_FILE_READ_ERROR; size = _X_BE_64 (buf + 8); if (size < 16) break; if (size >= ((uint64_t)1 << 63)) break; } else if (size < 8) { off_t len = input->get_length (input); size = len > (off_t)(pos + 8) ? len - pos : 8; } type = _X_BE_32 (buf + 4); if (type == MOOV_ATOM) break; if (type == FREE_ATOM) { if ((size - hsize >= 8) && (input->read (input, buf + hsize, 8) == 8)) { uint32_t stype = _X_BE_32 (buf + hsize + 4); hsize += 8; if ((stype == MVHD_ATOM) || (stype == CMOV_ATOM)) { free_pos = pos; free_size = size; } } } if ((type != FREE_ATOM) && (type != JUNK_ATOM) && (type != MDAT_ATOM) && (type != PNOT_ATOM) && (type != SKIP_ATOM) && (type != WIDE_ATOM) && (type != PICT_ATOM) && (type != FTYP_ATOM)) { if (--unknown_atoms < 0) return QT_NOT_A_VALID_FILE; } pos += size; } p = buf; if ((type != MOOV_ATOM) && free_size) { type = MOOV_ATOM; pos = free_pos; size = free_size; hsize = 0; if (input->seek (input, pos, SEEK_SET) != (off_t)pos) return QT_NO_MOOV_ATOM; } if (type != MOOV_ATOM) return QT_NOT_A_VALID_FILE; } else { int have = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW); if (have < 32) return QT_FILE_READ_ERROR; while (1) { hsize = 8; if (pos > (unsigned int)have - 8) break; p = buf + pos; size = _X_BE_32 (p); if (size == 1) { hsize = 16; if (pos > (unsigned int)have - 16) break; size = _X_BE_64 (p + 8); if (size < 16) return QT_NO_MOOV_ATOM; if (size >= ((uint64_t)1 << 63)) return QT_NO_MOOV_ATOM; } else if (size < 8) { size = have - pos; } type = _X_BE_32 (p + 4); if (type == MOOV_ATOM) break; if (type == FREE_ATOM) { if (pos <= (unsigned int)have - hsize - 8) { uint32_t stype = _X_BE_32 (p + hsize + 4); hsize += 8; if ((stype == MVHD_ATOM) || (stype == CMOV_ATOM)) { free_pos = pos; free_size = size; } } } if ((type != FREE_ATOM) && (type != JUNK_ATOM) && (type != MDAT_ATOM) && (type != PNOT_ATOM) && (type != SKIP_ATOM) && (type != WIDE_ATOM) && (type != PICT_ATOM) && (type != FTYP_ATOM)) { if (--unknown_atoms < 0) return QT_NOT_A_VALID_FILE; } pos += size; } if ((type != MOOV_ATOM) && free_size) { type = MOOV_ATOM; pos = free_pos; size = free_size; hsize = 0; } if (type != MOOV_ATOM) return QT_NOT_A_VALID_FILE; if (input->seek (input, pos + hsize, SEEK_SET) != (off_t)pos + hsize) return QT_NO_MOOV_ATOM; } if (size >= MAX_MOOV_SIZE) return QT_NOT_A_VALID_FILE; *moov_atom_offset = pos; *moov_atom = malloc (size + 4); if (!*moov_atom) return QT_NO_MEMORY; if (hsize) memcpy (*moov_atom, p, hsize); if (input->read (input, *moov_atom + hsize, size - hsize) != (off_t)size - hsize) { free (*moov_atom); return QT_FILE_READ_ERROR; } return QT_OK; } static qt_error open_qt_file (demux_qt_t *this, uint8_t *moov_atom, off_t moov_atom_offset) { uint32_t moov_atom_size; /* extract the base MRL if this is a http MRL */ if (strncmp (this->input->get_mrl (this->input), "http://", 7) == 0) { char *slash; /* this will copy a few bytes too many, but no big deal */ this->qt.base_mrl = strdup (this->input->get_mrl (this->input)); /* terminate the string after the last slash character */ slash = strrchr (this->qt.base_mrl, '/'); if (slash) *(slash + 1) = '\0'; } this->qt.moov_first_offset = moov_atom_offset; moov_atom_size = _X_BE_32 (moov_atom); /* check if moov is compressed */ if ((moov_atom_size >= 0x28) && (_X_BE_32 (moov_atom + 12) == CMOV_ATOM)) do { uint8_t *unzip_buffer; uint32_t size2; this->qt.compressed_header = 1; this->qt.last_error = QT_NO_MEMORY; size2 = _X_BE_32 (moov_atom + 0x24); if (size2 > MAX_MOOV_SIZE) size2 = MAX_MOOV_SIZE; unzip_buffer = malloc (size2 + 4); if (unzip_buffer) { /* zlib stuff */ z_stream z_state; int z_ret_code1, z_ret_code2; this->qt.last_error = QT_ZLIB_ERROR; memset(&z_state, 0, sizeof(z_state)); z_state.next_in = moov_atom + 0x28; z_state.avail_in = moov_atom_size - 0x28; z_state.next_out = unzip_buffer; z_state.avail_out = size2; z_state.zalloc = NULL; z_state.zfree = NULL; z_state.opaque = NULL; z_ret_code1 = inflateInit (&z_state); if (Z_OK == z_ret_code1) { z_ret_code1 = inflate (&z_state, Z_NO_FLUSH); z_ret_code2 = inflateEnd (&z_state); if (((z_ret_code1 == Z_OK) || (z_ret_code1 == Z_STREAM_END)) && (Z_OK == z_ret_code2)) { /* replace the compressed moov atom with the decompressed atom */ this->qt.last_error = QT_OK; free (moov_atom); moov_atom = unzip_buffer; moov_atom_size = _X_BE_32 (moov_atom); if (moov_atom_size > size2) { moov_atom_size = size2; WRITE_BE_32 (size2, moov_atom); } break; } } free (unzip_buffer); } free (moov_atom); return this->qt.last_error; } while (0); /* write moov atom to disk if debugging option is turned on */ dump_moov_atom(moov_atom, moov_atom_size); /* take apart the moov atom */ parse_moov_atom (this, moov_atom); free (moov_atom); return this->qt.last_error; } /********************************************************************** * xine demuxer functions **********************************************************************/ static int demux_qt_send_chunk(demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; buf_element_t *buf = NULL; unsigned int i; unsigned int remaining_sample_bytes; unsigned int frame_aligned_buf_size; int frame_duration; int first_buf; qt_trak *trak = NULL; off_t current_pos = this->input->get_current_pos (this->input); /* if this is DRM-protected content, finish playback before it even * tries to start */ if (this->qt.last_error == QT_DRM_NOT_SUPPORTED) { this->status = DEMUX_FINISHED; return this->status; } /* check if it's time to send a reference up to the UI */ if (this->qt.chosen_reference != -1) { _x_demux_send_mrl_reference (this->stream, 0, this->qt.references[this->qt.chosen_reference].url, NULL, 0, 0); this->status = DEMUX_FINISHED; return this->status; } /* Decide the trak from which to dispatch a frame. Policy: Dispatch * the frames in offset order as much as possible. If the pts difference * between the current frames from the audio and video traks is too * wide, make an exception. This exception deals with non-interleaved * Quicktime files. */ do { int traks[MAX_AUDIO_TRAKS + 1]; int trak_count = 0; int min_trak = -1, next_trak = -1; int64_t min_pts = 0, max_pts = 0; /* avoid warning */ off_t next_pos = 0x7fffffffffffffffLL; int i; /* Step 1: list yet unfinished traks. */ if (this->qt.video_trak >= 0) { trak = &this->qt.traks[this->qt.video_trak]; if (trak->current_frame < trak->frame_count) traks[trak_count++] = this->qt.video_trak; } for (i = 0; i < this->qt.audio_trak_count; i++) { trak = &this->qt.traks[this->qt.audio_traks[i]]; if (trak->current_frame < trak->frame_count) traks[trak_count++] = this->qt.audio_traks[i]; } /* Step 2: handle trivial cases. */ if (trak_count == 0) { if (fragment_scan (this)) { qt_update_duration (this); this->status = DEMUX_OK; } else this->status = DEMUX_FINISHED; return this->status; } if (trak_count == 1) { trak = &this->qt.traks[traks[0]]; break; } /* Step 3: find * The minimum pts and the trak who has it. * The maximum pts. * The forward nearest to current position and the trak thereof. */ for (i = 0; i < trak_count; i++) { int64_t pts; off_t pos; trak = &this->qt.traks[traks[i]]; pts = trak->frames[trak->current_frame].pts; if (i == 0) { min_pts = max_pts = pts; min_trak = traks[i]; } else if (pts < min_pts) { min_pts = pts; min_trak = traks[i]; } else if (pts > max_pts) max_pts = pts; pos = QTF_OFFSET(trak->frames[trak->current_frame]); if ((pos >= current_pos) && (pos < next_pos)) { next_pos = pos; next_trak = traks[i]; } } /* Step 4: after seek, or if the pts scissors opened too much, send minimum pts trak next. Otherwise, take next one by offset. */ i = this->qt.seek_flag || (next_trak < 0) || (max_pts - min_pts > MAX_PTS_DIFF) ? min_trak : next_trak; trak = &this->qt.traks[i]; } while (0); if (this->stream->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1, "demux_qt: sending trak %d dts %"PRId64" pos %"PRId64"\n", (int)(trak - this->qt.traks), trak->frames[trak->current_frame].pts, QTF_OFFSET(trak->frames[trak->current_frame])); } /* check if it is time to seek */ if (this->qt.seek_flag) { this->qt.seek_flag = 0; /* send min pts of all used traks, usually audio (see demux_qt_seek ()). */ _x_demux_control_newpts (this->stream, trak->frames[trak->current_frame].pts + trak->frames[trak->current_frame].ptsoffs, BUF_FLAG_SEEK); } if (trak->type == MEDIA_VIDEO) { i = trak->current_frame++; if (QTF_MEDIA_ID(trak->frames[i]) != trak->properties->media_id) { this->status = DEMUX_OK; return this->status; } remaining_sample_bytes = trak->frames[i].size; if ((off_t)QTF_OFFSET(trak->frames[i]) != current_pos) { if (this->input->seek (this->input, QTF_OFFSET(trak->frames[i]), SEEK_SET) < 0) { /* Do not stop demuxing. Maybe corrupt file or broken track. */ return this->status; } } /* frame duration is the pts diff between this video frame and the next video frame * or the convenience frame at the end of list */ frame_duration = trak->frames[i + 1].pts; frame_duration -= trak->frames[i].pts; /* Due to the edit lists, some successive frames have the same pts * which would ordinarily cause frame_duration to be 0 which can * cause DIV-by-0 errors in the engine. Perform this little trick * to compensate. */ if (!frame_duration) { frame_duration = 1; trak->properties->s.video.edit_list_compensation++; } else { frame_duration -= trak->properties->s.video.edit_list_compensation; trak->properties->s.video.edit_list_compensation = 0; } _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, frame_duration); debug_video_demux(" qt: sending off video frame %d from offset 0x%"PRIX64", %d bytes, media id %d, %"PRId64" pts\n", i, QTF_OFFSET(trak->frames[i]), trak->frames[i].size, (int)QTF_MEDIA_ID(trak->frames[i]), trak->frames[i].pts); while (remaining_sample_bytes) { buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, remaining_sample_bytes); buf->type = trak->properties->codec_buftype; buf->pts = trak->frames[i].pts + (int64_t)trak->frames[i].ptsoffs + this->ptsoffs; buf->extra_info->input_time = qt_pts_2_msecs (buf->pts); buf->extra_info->total_time = this->qt.msecs; buf->extra_info->input_normpos = qt_msec_2_normpos (this, buf->extra_info->input_time); buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = frame_duration; if (remaining_sample_bytes > (unsigned int)buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); trak->current_frame = trak->frame_count; break; } if (QTF_KEYFRAME(trak->frames[i])) buf->decoder_flags |= BUF_FLAG_KEYFRAME; if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put(this->video_fifo, buf); } } else { /* trak->type == MEDIA_AUDIO */ /* load an audio sample and packetize it */ i = trak->current_frame++; if (QTF_MEDIA_ID(trak->frames[i]) != trak->properties->media_id) { this->status = DEMUX_OK; return this->status; } /* only go through with this procedure if audio_fifo exists */ if (!this->audio_fifo) return this->status; remaining_sample_bytes = trak->frames[i].size; if ((off_t)QTF_OFFSET(trak->frames[i]) != current_pos) { if (this->input->seek (this->input, QTF_OFFSET(trak->frames[i]), SEEK_SET) < 0) { /* Do not stop demuxing. Maybe corrupt file or broken track. */ return this->status; } } debug_audio_demux(" qt: sending off audio frame %d from offset 0x%"PRIX64", %d bytes, media id %d, %"PRId64" pts\n", i, QTF_OFFSET(trak->frames[i]), trak->frames[i].size, (int)QTF_MEDIA_ID(trak->frames[i]), trak->frames[i].pts); first_buf = 1; while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, remaining_sample_bytes); buf->type = trak->properties->codec_buftype; buf->extra_info->input_time = qt_pts_2_msecs (trak->frames[i].pts); buf->extra_info->total_time = this->qt.msecs; buf->extra_info->input_normpos = qt_msec_2_normpos (this, buf->extra_info->input_time); /* The audio chunk is often broken up into multiple 8K buffers when * it is sent to the audio decoder. Only attach the proper timestamp * to the first buffer. This is for the linear PCM decoder which * turns around and sends out audio buffers as soon as they are * received. If 2 or more consecutive audio buffers are dispatched to * the audio out unit, the engine will compensate with pops. */ if ((buf->type == BUF_AUDIO_LPCM_BE) || (buf->type == BUF_AUDIO_LPCM_LE)) { if (first_buf) { buf->pts = trak->frames[i].pts + this->ptsoffs; first_buf = 0; } else { buf->extra_info->input_time = 0; buf->pts = 0; } } else { buf->pts = trak->frames[i].pts + this->ptsoffs; } /* 24-bit audio doesn't fit evenly into the default 8192-byte buffers */ frame_aligned_buf_size = buf->max_size; if (trak->properties->s.audio.bits == 24) frame_aligned_buf_size = (frame_aligned_buf_size / 8184) * 8184; if (remaining_sample_bytes > frame_aligned_buf_size) buf->size = frame_aligned_buf_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); trak->current_frame = trak->frame_count; break; } /* Special case alert: If this is signed, 8-bit data, transform * the data to unsigned. */ if ((trak->properties->s.audio.bits == 8) && ((trak->properties->codec_fourcc == TWOS_FOURCC) || (trak->properties->codec_fourcc == SOWT_FOURCC))) { int j; for (j = 0; j < buf->size; j++) buf->content[j] += 0x80; } if (!remaining_sample_bytes) { buf->decoder_flags |= BUF_FLAG_FRAME_END; } buf->type |= trak->audio_index; this->audio_fifo->put(this->audio_fifo, buf); } } return this->status; } static void demux_qt_send_headers(demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; buf_element_t *buf; qt_trak *video_trak = NULL; qt_trak *audio_trak = NULL; unsigned int audio_bitrate; unsigned int tnum; int audio_index = 0; #ifdef QT_OFFSET_SEEK /* for deciding data start and data size */ int64_t first_video_offset = -1; int64_t last_video_offset = -1; int64_t first_audio_offset = -1; int64_t last_audio_offset = -1; #endif this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* figure out where the data begins and ends */ if (this->qt.video_trak != -1) { video_trak = &this->qt.traks[this->qt.video_trak]; #ifdef QT_OFFSET_SEEK first_video_offset = QTF_OFFSET(video_trak->frames[0]); last_video_offset = video_trak->frames[video_trak->frame_count - 1].size + QTF_OFFSET(video_trak->frames[video_trak->frame_count - 1]); #endif } if (this->qt.audio_trak != -1) { audio_trak = &this->qt.traks[this->qt.audio_trak]; #ifdef QT_OFFSET_SEEK first_audio_offset = QTF_OFFSET(audio_trak->frames[0]); last_audio_offset = audio_trak->frames[audio_trak->frame_count - 1].size + QTF_OFFSET(audio_trak->frames[audio_trak->frame_count - 1]); #endif } #ifdef QT_OFFSET_SEEK if (first_video_offset < first_audio_offset) this->data_start = first_video_offset; else this->data_start = first_audio_offset; if (last_video_offset > last_audio_offset) this->data_size = last_video_offset - this->data_size; else this->data_size = last_audio_offset - this->data_size; #endif /* sort out the A/V information */ if (this->qt.video_trak != -1) { this->bih.biSize = sizeof(this->bih); this->bih.biWidth = video_trak->properties->s.video.width; this->bih.biHeight = video_trak->properties->s.video.height; this->bih.biBitCount = video_trak->properties->s.video.depth; this->bih.biCompression = video_trak->properties->codec_fourcc; video_trak->properties->codec_buftype = _x_fourcc_to_buf_video(this->bih.biCompression); /* hack: workaround a fourcc clash! 'mpg4' is used by MS and Sorenson * mpeg4 codecs (they are not compatible). */ if( video_trak->properties->codec_buftype == BUF_VIDEO_MSMPEG4_V1 ) video_trak->properties->codec_buftype = BUF_VIDEO_MPEG4; if( !video_trak->properties->codec_buftype && video_trak->properties->codec_fourcc ) { video_trak->properties->codec_buftype = BUF_VIDEO_UNKNOWN; _x_report_video_fourcc (this->stream->xine, LOG_MODULE, video_trak->properties->codec_fourcc); } _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, video_trak->properties->codec_fourcc); } else { memset(&this->bih, 0, sizeof(this->bih)); this->bih.biSize = sizeof(this->bih); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, 0); } if (this->qt.audio_trak != -1) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, audio_trak->properties->s.audio.channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, audio_trak->properties->s.audio.sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, audio_trak->properties->s.audio.bits); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, audio_trak->properties->codec_fourcc); } else { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, 0); } /* copy over the meta information like artist and title */ if (this->qt.artist) _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->qt.artist); else if (this->qt.copyright) _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->qt.copyright); if (this->qt.name) _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->qt.name); else if (this->qt.description) _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->qt.description); if (this->qt.composer) _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, this->qt.composer); else if (this->qt.comment) _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, this->qt.comment); if (this->qt.album) _x_meta_info_set(this->stream, XINE_META_INFO_ALBUM, this->qt.album); if (this->qt.genre) _x_meta_info_set(this->stream, XINE_META_INFO_GENRE, this->qt.genre); if (this->qt.year) _x_meta_info_set(this->stream, XINE_META_INFO_YEAR, this->qt.year); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (video_trak && (video_trak->properties->codec_buftype)) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; memcpy(buf->content, &this->bih, sizeof(this->bih)); buf->size = sizeof(this->bih); buf->type = video_trak->properties->codec_buftype; this->video_fifo->put (this->video_fifo, buf); /* send header info to decoder. some mpeg4 streams need this */ if (video_trak->properties->decoder_config) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = video_trak->properties->codec_buftype; if (video_trak->properties->codec_fourcc == AVC1_FOURCC || video_trak->properties->codec_fourcc == HVC1_FOURCC || video_trak->properties->codec_fourcc == HEV1_FOURCC || video_trak->properties->codec_fourcc == HEVC_FOURCC) { buf->size = 0; buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG; buf->decoder_info[2] = video_trak->properties->decoder_config_len; buf->decoder_info_ptr[2] = video_trak->properties->decoder_config; } else { buf->size = video_trak->properties->decoder_config_len; buf->content = video_trak->properties->decoder_config; } this->video_fifo->put (this->video_fifo, buf); } /* send off the palette, if there is one */ if (video_trak->properties->s.video.palette_count) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = video_trak->properties->s.video.palette_count; buf->decoder_info_ptr[2] = &video_trak->properties->s.video.palette; buf->size = 0; buf->type = video_trak->properties->codec_buftype; this->video_fifo->put (this->video_fifo, buf); } /* send stsd to the decoder */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_STSD_ATOM; buf->decoder_info[2] = video_trak->properties->properties_atom_size - 4; buf->decoder_info_ptr[2] = video_trak->properties->properties_atom + 4; buf->size = 0; buf->type = video_trak->properties->codec_buftype; this->video_fifo->put (this->video_fifo, buf); } for (tnum = 0; tnum < this->qt.trak_count; tnum++) { audio_trak = &this->qt.traks[tnum]; if (audio_trak->type != MEDIA_AUDIO) continue; if (!audio_trak->properties->codec_buftype && audio_trak->properties->codec_fourcc) { audio_trak->properties->codec_buftype = BUF_AUDIO_UNKNOWN; _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, audio_trak->properties->codec_fourcc); } if ((audio_trak->properties->codec_buftype == 0) || (audio_index >= MAX_AUDIO_TRAKS) || (this->audio_fifo == NULL)) continue; this->qt.audio_traks[audio_index] = tnum; audio_trak->audio_index = audio_index; /* set the audio bitrate field (only for CBR audio) */ if (!audio_trak->properties->s.audio.vbr) { audio_bitrate = audio_trak->properties->s.audio.sample_rate / audio_trak->properties->s.audio.samples_per_frame * audio_trak->properties->s.audio.bytes_per_frame * audio_trak->properties->s.audio.channels * 8; _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, audio_bitrate); } buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = audio_trak->properties->codec_buftype | audio_index; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = audio_trak->properties->s.audio.sample_rate; buf->decoder_info[2] = audio_trak->properties->s.audio.bits; buf->decoder_info[3] = audio_trak->properties->s.audio.channels; if( audio_trak->properties->s.audio.wave_size ) { if (audio_trak->properties->s.audio.wave_size > (unsigned int)buf->max_size) buf->size = buf->max_size; else buf->size = audio_trak->properties->s.audio.wave_size; memcpy (buf->content, audio_trak->properties->s.audio.wave, buf->size); } else { buf->size = 0; buf->content = NULL; } this->audio_fifo->put (this->audio_fifo, buf); if (audio_trak->properties->decoder_config) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = audio_trak->properties->codec_buftype | audio_index; buf->size = 0; buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG; buf->decoder_info[2] = audio_trak->properties->decoder_config_len; buf->decoder_info_ptr[2] = audio_trak->properties->decoder_config; this->audio_fifo->put (this->audio_fifo, buf); } /* send stsd to the decoder */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_STSD_ATOM; buf->decoder_info[2] = audio_trak->properties->properties_atom_size - 4; buf->decoder_info_ptr[2] = audio_trak->properties->properties_atom + 4; buf->size = 0; buf->type = audio_trak->properties->codec_buftype | audio_index; this->audio_fifo->put (this->audio_fifo, buf); this->qt.audio_trak_count = ++audio_index; } } /* support function that performs a binary seek on a trak; returns the * demux status */ static int binary_seek (demux_qt_t *this, qt_trak *trak, off_t start_pos, int start_time) { int best_index; int left, middle, right; #ifdef QT_OFFSET_SEEK int found; #endif if (!trak->frame_count) return QT_OK; #ifdef QT_OFFSET_SEEK (void)this; /* perform a binary search on the trak, testing the offset * boundaries first; offset request has precedent over time request */ if (start_pos) { if (start_pos <= (off_t)QTF_OFFSET(trak->frames[0])) best_index = 0; else if (start_pos >= (off_t)QTF_OFFSET(trak->frames[trak->frame_count - 1])) best_index = trak->frame_count - 1; else { left = 0; right = trak->frame_count - 1; found = 0; while (!found) { middle = (left + right + 1) / 2; if ((start_pos >= (off_t)QTF_OFFSET(trak->frames[middle])) && (start_pos < (off_t)QTF_OFFSET(trak->frames[middle + 1]))) { found = 1; } else if (start_pos < (off_t)QTF_OFFSET(trak->frames[middle])) { right = middle - 1; } else { left = middle; } } best_index = middle; } } else #else if (start_pos) { start_time = (uint64_t)(start_pos & 0xffff) * (uint32_t)this->qt.msecs / 0xffff; } #endif { int64_t pts = (int64_t)90 * start_time; if (pts <= trak->frames[0].pts) best_index = 0; else if (pts >= trak->frames[trak->frame_count - 1].pts) best_index = trak->frame_count - 1; else { left = 0; right = trak->frame_count - 1; do { middle = (left + right + 1) / 2; if (pts < trak->frames[middle].pts) { right = (middle - 1); } else { left = middle; } } while (left < right); best_index = left; } } trak->current_frame = best_index; return DEMUX_OK; } static int demux_qt_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_qt_t *this = (demux_qt_t *) this_gen; qt_trak *video_trak = NULL; qt_trak *audio_trak = NULL; int i; int64_t keyframe_pts = -1; #ifdef QT_OFFSET_SEEK start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); #endif /* short-circuit any attempts to seek in a non-seekable stream, including * seeking in the forward direction; this may change later */ if ((this->input->get_capabilities(this->input) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) == 0) { this->qt.seek_flag = 1; this->status = DEMUX_OK; return this->status; } /* if there is a video trak, position it as close as possible to the * requested position */ if (this->qt.video_trak != -1) { video_trak = &this->qt.traks[this->qt.video_trak]; this->status = binary_seek (this, video_trak, start_pos, start_time); if (this->status != DEMUX_OK) return this->status; /* search back in the video trak for the nearest keyframe */ while (video_trak->current_frame) { if (QTF_KEYFRAME(video_trak->frames[video_trak->current_frame])) { break; } video_trak->current_frame--; } keyframe_pts = video_trak->frames[video_trak->current_frame].pts; } /* seek all supported audio traks */ for (i = 0; i < this->qt.audio_trak_count; i++) { audio_trak = &this->qt.traks[this->qt.audio_traks[i]]; this->status = binary_seek (this, audio_trak, start_pos, start_time); if (this->status != DEMUX_OK) return this->status; } /* not done yet; now that the nearest keyframe has been found, seek * back to the first audio frame that has a pts less than or equal to * that of the keyframe; do not go through with this process there is * no video trak */ if (keyframe_pts >= 0) for (i = 0; i < this->qt.audio_trak_count; i++) { audio_trak = &this->qt.traks[this->qt.audio_traks[i]]; if (keyframe_pts > audio_trak->frames[audio_trak->frame_count - 1].pts) { /* whoops, this trak is too short, mark it finished */ audio_trak->current_frame = audio_trak->frame_count; } else while (audio_trak->current_frame) { if (audio_trak->frames[audio_trak->current_frame].pts <= keyframe_pts) { break; } audio_trak->current_frame--; } } this->qt.seek_flag = 1; this->status = DEMUX_OK; /* * do only flush if already running (seeking). * otherwise decoder_config is flushed too. */ if(playing) _x_demux_flush_engine(this->stream); return this->status; } static void demux_qt_dispose (demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; free_qt_info (this); free(this); } static int demux_qt_get_status (demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; return this->status; } static int demux_qt_get_stream_length (demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; return this->qt.msecs; } static uint32_t demux_qt_get_capabilities(demux_plugin_t *this_gen) { demux_qt_t *this = (demux_qt_t *) this_gen; return DEMUX_CAP_AUDIOLANG | (this->qt.video_trak >= 0 ? DEMUX_CAP_VIDEO_TIME : 0); } static int demux_qt_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { demux_qt_t *this = (demux_qt_t *) this_gen; /* be a bit paranoid */ if (this == NULL || this->stream == NULL) return DEMUX_OPTIONAL_UNSUPPORTED; switch (data_type) { case DEMUX_OPTIONAL_DATA_AUDIOLANG: { char *str = data; int channel = *((int *)data); if ((channel < 0) || (channel >= this->qt.audio_trak_count)) { strcpy (str, "none"); } else { int lang = this->qt.traks[this->qt.audio_traks[channel]].lang; if ((lang < 0x400) || (lang == 0x7fff)) { sprintf (str, "%d", channel); } else { int i; for (i = 10; i >= 0; i -= 5) *str++ = 0x60 | ((lang >> i) & 0x1f); *str = 0; } return DEMUX_OPTIONAL_SUCCESS; } } break; case DEMUX_OPTIONAL_DATA_VIDEO_TIME: if (data && (this->qt.video_trak >= 0)) { qt_trak *trak = &this->qt.traks[this->qt.video_trak]; int32_t vtime = (trak->frames[trak->current_frame].pts + trak->frames[trak->current_frame].ptsoffs) / 90; memcpy (data, &vtime, sizeof (vtime)); return DEMUX_OPTIONAL_SUCCESS; } break; default: ; } return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_qt_t *this; xine_cfg_entry_t entry; uint8_t *moov_atom = NULL; off_t moov_atom_offset; qt_error last_error; if ((input->get_capabilities(input) & INPUT_CAP_BLOCK)) { return NULL; } switch (stream->content_detection_method) { case METHOD_BY_CONTENT: case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } last_error = load_moov_atom (input, &moov_atom, &moov_atom_offset); if (last_error != QT_OK) return NULL; /* check that the next atom in the chunk contains alphanumeric characters * in the atom type field; if not, disqualify the file as a QT file */ if (_X_BE_32 (moov_atom) < 16) { free (moov_atom); return NULL; } { int i; for (i = 12; i < 16; i++) { if (!isalnum (moov_atom[i])) { free (moov_atom); return NULL; } } } this = calloc (1, sizeof (demux_qt_t)); if (!this) { free (moov_atom); return NULL; } this->stream = stream; this->input = input; this->ptsoffs = this->input->get_optional_data (this->input, NULL, INPUT_OPTIONAL_DATA_PTSOFFS); if (this->ptsoffs) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_qt: using input offset %d pts.\n", this->ptsoffs); } /* fetch bandwidth config */ this->bandwidth = 0x7FFFFFFFFFFFFFFFLL; /* assume infinite bandwidth */ if (xine_config_lookup_entry (stream->xine, "media.network.bandwidth", &entry)) { if ((entry.num_value >= 0) && (entry.num_value <= 11)) this->bandwidth = bandwidths[entry.num_value]; } this->demux_plugin.send_headers = demux_qt_send_headers; this->demux_plugin.send_chunk = demux_qt_send_chunk; this->demux_plugin.seek = demux_qt_seek; this->demux_plugin.dispose = demux_qt_dispose; this->demux_plugin.get_status = demux_qt_get_status; this->demux_plugin.get_stream_length = demux_qt_get_stream_length; this->demux_plugin.get_capabilities = demux_qt_get_capabilities; this->demux_plugin.get_optional_data = demux_qt_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; create_qt_info (this); last_error = open_qt_file (this, moov_atom, moov_atom_offset); switch (stream->content_detection_method) { case METHOD_BY_CONTENT: if (last_error == QT_DRM_NOT_SUPPORTED) { /* special consideration for DRM-protected files */ _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "DRM-protected Quicktime file", NULL); break; } /* fall through */ default: if (last_error != QT_OK) { free_qt_info (this); free (this); return NULL; } } if (this->qt.fragment_count > 0) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, _("demux_qt: added %d fragments\n"), this->qt.fragment_count); return &this->demux_plugin; } void *demux_qt_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_qt_class = { .open_plugin = open_plugin, .description = N_("Apple Quicktime (MOV) and MPEG-4 demux plugin"), .identifier = "MOV/MPEG-4", .mimetypes = "video/quicktime: mov,qt: Quicktime animation;" "video/x-quicktime: mov,qt: Quicktime animation;" "audio/x-m4a: m4a,m4b: MPEG-4 audio;" "video/mp4: f4v,mp4,mpg4: MPEG-4 video;" "audio/mp4: f4a,mp4,mpg4: MPEG-4 audio;", .extensions = "mov qt mp4 m4a m4b f4a f4v", .dispose = NULL, }; return (void *)&demux_qt_class; } xine-lib-1.2/src/demuxers/demux_vqa.c0000644000175000017500000003016014647725152015444 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * VQA File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the VQA file format, visit: * http://www.pcisys.net/~melanson/codecs/ * * Quick technical note: VQA files begin with a header that includes a * frame index. This ought to be useful for seeking within a VQA file. * However, seeking is infeasible due to the audio encoding: Each audio * block needs information from the previous audio block in order to be * decoded, thus making random seeking difficult. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_games.h" #define FOURCC_TAG BE_FOURCC #define FORM_TAG FOURCC_TAG('F', 'O', 'R', 'M') #define WVQA_TAG FOURCC_TAG('W', 'V', 'Q', 'A') #define VQHD_TAG FOURCC_TAG('V', 'Q', 'H', 'D') #define FINF_TAG FOURCC_TAG('F', 'I', 'N', 'F') #define SND0_TAG FOURCC_TAG('S', 'N', 'D', '0') #define SND2_TAG FOURCC_TAG('S', 'N', 'D', '2') #define VQFR_TAG FOURCC_TAG('V', 'Q', 'F', 'R') #define VQA_HEADER_SIZE 0x2A #define VQA_FRAMERATE 15 #define VQA_PTS_INC (90000 / VQA_FRAMERATE) #define VQA_PREAMBLE_SIZE 8 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_start; off_t filesize; xine_bmiheader bih; unsigned char vqa_header[VQA_HEADER_SIZE]; xine_waveformatex wave; int64_t video_pts; unsigned int audio_frames; unsigned int iteration; } demux_vqa_t; static int probe_vqa_file(input_plugin_t *input) { unsigned char scratch[12]; if (_x_demux_read_header(input, scratch, 12) != 12) return 0; /* check for the VQA signatures */ if (!_x_is_fourcc(&scratch[0], "FORM") || !_x_is_fourcc(&scratch[8], "WVQA") ) return 0; return 1; } /* returns 1 if the VQA file was opened successfully, 0 otherwise */ static int open_vqa_file(demux_vqa_t *this) { unsigned char scratch[12]; unsigned int chunk_size; /* file is qualified; skip to the start of the VQA header */ if (this->input->seek(this->input, 20, SEEK_SET) != 20) return 0; /* get the actual filesize */ if ( !(this->filesize = this->input->get_length(this->input)) ) this->filesize = 1; /* load the VQA header */ if (this->input->read(this->input, this->vqa_header, VQA_HEADER_SIZE) != VQA_HEADER_SIZE) return 0; this->bih.biSize = sizeof(xine_bmiheader) + VQA_HEADER_SIZE; this->bih.biWidth = _X_LE_16(&this->vqa_header[6]); this->bih.biHeight = _X_LE_16(&this->vqa_header[8]); this->wave.nSamplesPerSec = _X_LE_16(&this->vqa_header[24]); this->wave.nChannels = this->vqa_header[26]; this->wave.wBitsPerSample = 16; /* skip the FINF chunk */ if (this->input->read(this->input, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) return 0; chunk_size = _X_BE_32(&scratch[4]); if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) return 0; this->video_pts = this->audio_frames = 0; this->iteration = 0; return 1; } static int demux_vqa_send_chunk(demux_plugin_t *this_gen) { demux_vqa_t *this = (demux_vqa_t *) this_gen; buf_element_t *buf = NULL; unsigned char preamble[VQA_PREAMBLE_SIZE]; unsigned int chunk_size; off_t current_file_pos; int skip_byte; int64_t audio_pts; /* load and dispatch the audio portion of the frame */ if (this->input->read(this->input, preamble, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } current_file_pos = this->input->get_current_pos(this->input); chunk_size = _X_BE_32(&preamble[4]); skip_byte = chunk_size & 0x1; audio_pts = this->audio_frames; audio_pts *= 90000; audio_pts /= this->wave.nSamplesPerSec; this->audio_frames += (chunk_size * 2 / this->wave.nChannels); while (chunk_size) { if(this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_VQA_IMA; if( this->filesize ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->filesize); buf->extra_info->input_time = audio_pts / 90; buf->pts = audio_pts; if ((int)chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); }else{ if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; return this->status; } break; } } /* stay on 16-bit alignment */ if (skip_byte) if (this->input->seek(this->input, 1, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; return this->status; } /* load and dispatch the video portion of the frame but only if this * is not frame #0 */ if (this->iteration > 0) { if (this->input->read(this->input, preamble, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } current_file_pos = this->input->get_current_pos(this->input); chunk_size = _X_BE_32(&preamble[4]); while (chunk_size) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_VQA; if( this->filesize ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->filesize); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; if ((int)chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put (this->video_fifo, buf); } this->video_pts += VQA_PTS_INC; } this->iteration++; return this->status; } static void demux_vqa_send_headers(demux_plugin_t *this_gen) { demux_vqa_t *this = (demux_vqa_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->wave.nChannels) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->wave.nChannels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->wave.nSamplesPerSec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->wave.wBitsPerSample); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = VQA_PTS_INC; /* initial video_step */ memcpy(buf->content, &this->bih, sizeof(xine_bmiheader)); memcpy(buf->content + sizeof(xine_bmiheader), this->vqa_header, VQA_HEADER_SIZE); buf->size = sizeof(xine_bmiheader) + VQA_HEADER_SIZE; buf->type = BUF_VIDEO_VQA; this->video_fifo->put (this->video_fifo, buf); if (this->audio_fifo && this->wave.nChannels) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_VQA_IMA; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->wave.nSamplesPerSec; buf->decoder_info[2] = 16; /* bits/samples */ buf->decoder_info[3] = 1; /* channels */ this->wave.nBlockAlign = (this->wave.wBitsPerSample / 8) * this->wave.nChannels; this->wave.nAvgBytesPerSec = this->wave.nBlockAlign * this->wave.nSamplesPerSec; memcpy(buf->content, &this->wave, sizeof(this->wave)); buf->size = sizeof(this->wave); this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_vqa_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_vqa_t *this = (demux_vqa_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { this->status = DEMUX_OK; } return this->status; } static int demux_vqa_get_status (demux_plugin_t *this_gen) { demux_vqa_t *this = (demux_vqa_t *) this_gen; return this->status; } static int demux_vqa_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_vqa_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_vqa_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_vqa_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_vqa_file(input)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_vqa_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_vqa_send_headers; this->demux_plugin.send_chunk = demux_vqa_send_chunk; this->demux_plugin.seek = demux_vqa_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_vqa_get_status; this->demux_plugin.get_stream_length = demux_vqa_get_stream_length; this->demux_plugin.get_capabilities = demux_vqa_get_capabilities; this->demux_plugin.get_optional_data = demux_vqa_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_vqa_file(this)) { free (this); return NULL; } return &this->demux_plugin; } void *demux_vqa_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_vqa_class = { .open_plugin = open_plugin, .description = N_("Westwood Studios VQA file demux plugin"), .identifier = "VQA", .mimetypes = NULL, .extensions = "vqa", .dispose = NULL, }; return (void *)&demux_vqa_class; } xine-lib-1.2/src/demuxers/demux_mpeg_pes.c0000644000175000017500000016111214647725152016456 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for mpeg 2 PES (Packetized Elementary Streams) * reads streams of variable blocksizes * * 1-7-2003 New implementation of mpeg 2 PES demuxers. * (c) 2003 James Courtier-Dutton James@superbug.demon.co.uk * This code might also decode normal MPG files. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_mpeg_pes" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #define NUM_PREVIEW_BUFFERS 250 #define DISC_TRESHOLD 90000 #define WRAP_THRESHOLD 270000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 /* disabled for now. #define PTS_BOUNCE */ /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) typedef struct demux_mpeg_pes_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int is_vdr; int status; int rate; int64_t nav_last_end_pts; int64_t nav_last_start_pts; int64_t last_pts[2]; #ifdef PTS_BOUNCE int64_t apts, bpts; int32_t bounce_left; #endif int64_t scr; uint32_t packet_len; uint32_t stream_id; int64_t pts; int64_t dts; uint8_t send_newpts:1; uint8_t buf_flag_seek:1; uint8_t preview_mode:1; uint8_t mpeg1:1; uint8_t wait_for_program_stream_pack_header:1; uint8_t mpeg12_h264_detected:2; int last_begin_time; int64_t last_cell_time; off_t last_cell_pos; uint8_t preview_data[ MAX_PREVIEW_SIZE ]; off_t preview_size, preview_done; } demux_mpeg_pes_t ; static int32_t parse_video_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_audio_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_ancillary_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_system_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_private_stream_1(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); //static int32_t parse_private_stream_2(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_map(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_padding_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_ecm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_emm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_dsmcc_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_emm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_iec_13522_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeA_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeB_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeC_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeD_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeE_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_directory(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_pack_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf); #ifdef PTS_BOUNCE #define ts_abs(x) (((x) < 0) ? -(x) : (x)) /* bounce detection like in metronom. looks like double work but saves * up to 80 discontinuity messages. */ static void check_newpts (demux_mpeg_pes_t *this, int64_t pts, int video) { #ifdef TS_LOG printf ("demux_mpeg_pes: check_newpts %lld, send_newpts %d, buf_flag_seek %d\n", pts, this->send_newpts, this->buf_flag_seek); #endif /*if (pts)*/ { int64_t diff; do { this->last_pts[video] = pts; if (!this->apts) { diff = 0; this->apts = pts; break; } diff = pts - this->apts; if (ts_abs (diff) <= WRAP_THRESHOLD) { this->apts = pts; break; } if (this->bpts) { diff = pts - this->bpts; if (ts_abs (diff) <= WRAP_THRESHOLD) { this->bpts = pts; break; } } this->bpts = this->apts; this->apts = pts; this->bounce_left = WRAP_THRESHOLD; _x_demux_control_newpts (this->stream, pts, this->buf_flag_seek ? BUF_FLAG_SEEK : 0); this->send_newpts = 0; this->buf_flag_seek = 0; return; } while (0); if (this->bounce_left) { this->bounce_left -= diff; if (this->bounce_left <= 0) { this->bpts = 0; this->bounce_left = 0; } } if (this->send_newpts || this->buf_flag_seek) { _x_demux_control_newpts (this->stream, pts, this->buf_flag_seek ? BUF_FLAG_SEEK : 0); this->send_newpts = 0; this->buf_flag_seek = 0; } } } #else /* !PTS_BOUNCE */ static int detect_pts_discontinuity( demux_mpeg_pes_t *this, int64_t pts, int video ) { int64_t diff; /* discontinuity detection is difficult to implement in the demuxer as it gets * for example video packets in decoding order and there can be multiple audio * and video tracks. So for simplicity, let's just deal with a single audio and * a single video track. * * To start with, let's have a look at the audio and video track independently. * Whenever pts differs from last_pts[video] by at least WRAP_THRESHOLD, a jump * in pts is detected. Such a jump can happen for example when the pts counter * overflows, as shown below (video decoding order ignored for simplicity; the * variable values are shown after returning from the below function check_newpts; * an asterisk means that this value has been cleared (see check_newpts)): * * pts: 7v 7a 8v 9v 9a : 0v 1v 1a 2v 3v 3a 4v * last_pts[0]: 6 7 7 7 9 : * * 1 1 1 3 3 * last_pts[1]: 7 7 8 9 9 : 0 1 1 2 3 3 4 * | | | * | | +--- audio pts wrap ignored * | +--------- video pts wrap detected * +----------- pts wrap boundary */ diff = pts - this->last_pts[video]; if (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) return 1; /* but the above code can cause a huge delay while replaying when audio and video * track are not aligned on a common pts wrap boundery, as shown below: * * pts: 7v 8v 7a 9v : 0v 9a 1v 2v : 1a 3v 4v 3a * last_pts[0]: 6 6 7 7 : * 9 9 9 : 1 1 1 3 * last_pts[1]: 7 8 8 9 : 0 0 1 2 : * 3 4 4 * | | | | | * | | | | +--- audio pts wrap detected * | | | +----- audio pts wrap boundary * | | +-------------- audio packet causes a huge delay * | +----------------- video pts wrap detected * +------------------- video pts wrap boundery * * So there is the need to compare audio track pts against video track pts * to detect when pts values are in between pts wrap bounderies, where a * jump needs to be detected too, as shown below: * * pts: 7v 8v 7a 9v : 0v 9a 1v 2v : 1a 3v 4v 3a * last_pts[0]: 6 6 7 7 : * 9 * * : 1 1 1 3 * last_pts[1]: 7 8 8 9 : 0 * 1 2 : 2 3 4 4 * | | | | | | * | | | | | +--- (audio pts wrap ignored) * | | | | +----- audio pts wrap boundary * | | | +----------- video pts wrap detected * | | +-------------- audio pts wrap detected * | +----------------- video pts wrap detected * +------------------- (video pts wrap boundery) * * Basically, it's almost the same test like above, but against the other track's * pts value and with a different limit. As the pts counter is a 33 bit unsigned * integer, we choose 2^31 as limit (2^32 would require the tracks to be aligned). */ diff = pts - this->last_pts[1-video]; if (this->last_pts[1-video] && abs(diff)>(1u<<31)) return 1; /* no discontinuity detected */ return 0; } static void check_newpts( demux_mpeg_pes_t *this, int64_t pts, int video ) { if( pts && (this->send_newpts || detect_pts_discontinuity(this, pts, video) ) ) { /* check if pts is outside nav pts range. any stream without nav must enter here. */ if( pts > this->nav_last_end_pts || pts < this->nav_last_start_pts ) { lprintf("discontinuity detected by pts wrap\n"); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; } else { lprintf("no wrap detected\n" ); } /* clear pts on the other track to avoid detecting the same discontinuity again */ this->last_pts[1-video] = 0; } if( pts ) this->last_pts[video] = pts; } #endif static off_t read_data(demux_mpeg_pes_t *this, uint8_t *buf, off_t nlen) { int preview_avail; if (this->preview_size <= 0) return this->input->read(this->input, (char *)buf, nlen); preview_avail = this->preview_size - this->preview_done; if (preview_avail <= 0) return 0; if (nlen > preview_avail) nlen = preview_avail; memcpy(buf, &this->preview_data[ this->preview_done ], nlen); this->preview_done += nlen; return nlen; } static void demux_mpeg_pes_parse_pack (demux_mpeg_pes_t *this, int preview_mode) { buf_element_t *buf = NULL; uint8_t *p; int32_t result; off_t i; uint8_t buf6[ 6 ]; this->scr = 0; this->preview_mode = preview_mode; /* read first 6 bytes of PES packet into a local buffer. */ i = read_data(this, buf6, (off_t) 6); if (i != 6) { this->status = DEMUX_FINISHED; return; } p = buf6; while ((p[2] != 1) || p[0] || p[1]) { /* resync code */ memmove(p, p+1, 5); i = read_data(this, p+5, (off_t) 1); if (i != 1) { this->status = DEMUX_FINISHED; return; } } /* FIXME: buf must be allocated from somewhere before calling here. */ /* these streams should be allocated on the audio_fifo, if available. */ if ((0xC0 <= p[ 3 ] && p[ 3 ] <= 0xDF) /* audio_stream */ || 0xBD == p[ 3 ]) /* private_sream_1 */ { if (this->audio_fifo) buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); } if (!buf) /* still no buffer => try video fifo first. */ { if (this->video_fifo) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); } else if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); } else { return; } } p = buf->mem; /* copy local buffer to fifo element. */ memcpy(p, buf6, sizeof(buf6)); if (preview_mode) buf->decoder_flags = BUF_FLAG_PREVIEW; else buf->decoder_flags = 0; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); this->stream_id = p[3]; if (this->stream_id == 0xBA) { this->wait_for_program_stream_pack_header=0; /* This just fills this->scr, this->rate and this->mpeg1 */ result = parse_program_stream_pack_header(this, p, buf); return; } else if (this->stream_id == 0xB9) { /* End of stream marker */ buf->free_buffer (buf); return; } else if (this->stream_id < 0xB9) { /* FIXME: This should only be tested for after a seek. */ buf->free_buffer (buf); return; } #if 0 /* FIXME: #if 0 while trying to detect mpeg1 in parse_pes_for_pts() */ if (this->wait_for_program_stream_pack_header==1) { /* Wait until this->mpeg1 has been initialised. */ buf->free_buffer (buf); return; } #endif this->packet_len = p[4] << 8 | p[5]; lprintf("stream_id=0x%x, packet_len=%d\n",this->stream_id, this->packet_len); if ((int)(this->packet_len) <= (buf->max_size - 6)) { i = read_data(this, buf->mem+6, (off_t) this->packet_len); if (i != this->packet_len) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } buf->size = this->packet_len + 6; } else { lprintf("Jumbo PES packet length=%d, stream_id=0x%x\n",this->packet_len, this->stream_id); i = read_data(this, buf->mem+6, (off_t) (buf->max_size - 6)); if (i != ( buf->max_size - 6)) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } buf->size = buf->max_size; } if (this->stream_id == 0xBB) { result = parse_program_stream_system_header(this, p, buf); } else if (this->stream_id == 0xBC) { result = parse_program_stream_map(this, p, buf); } else if (this->stream_id == 0xBD) { result = parse_private_stream_1(this, p, buf); } else if (this->stream_id == 0xBE) { result = parse_padding_stream(this, p, buf); } else if (this->stream_id == 0xBF) { buf->free_buffer (buf); return; //result = parse_private_stream_2(this, p, buf); } else if ((this->stream_id >= 0xC0) && (this->stream_id <= 0xDF)) { result = parse_audio_stream(this, p, buf); } else if ((this->stream_id >= 0xE0) && (this->stream_id <= 0xEF)) { result = parse_video_stream(this, p, buf); } else if (this->stream_id == 0xF0) { result = parse_ecm_stream(this, p, buf); } else if (this->stream_id == 0xF1) { result = parse_emm_stream(this, p, buf); } else if (this->stream_id == 0xF2) { result = parse_dsmcc_stream(this, p, buf); } else if (this->stream_id == 0xF3) { result = parse_iec_13522_stream(this, p, buf); } else if (this->stream_id == 0xF4) { result = parse_h222_typeA_stream(this, p, buf); } else if (this->stream_id == 0xF5) { result = parse_h222_typeB_stream(this, p, buf); } else if (this->stream_id == 0xF6) { result = parse_h222_typeC_stream(this, p, buf); } else if (this->stream_id == 0xF7) { result = parse_h222_typeD_stream(this, p, buf); } else if (this->stream_id == 0xF8) { result = parse_h222_typeE_stream(this, p, buf); } else if (this->stream_id == 0xF9) { result = parse_ancillary_stream(this, p, buf); } else if (this->stream_id == 0xFA) { result = parse_IEC14496_SL_packetized_stream(this, p, buf); } else if (this->stream_id == 0xFB) { result = parse_IEC14496_FlexMux_stream(this, p, buf); /* 0xFC, 0xFD, 0xFE reserved */ } else if (this->stream_id == 0xFF) { result = parse_program_stream_directory(this, p, buf); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("xine-lib:demux_mpeg_pes: Unrecognised stream_id 0x%02x. " "Please report this to xine developers.\n"), this->stream_id); xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: packet_len=%d\n", this->packet_len); buf->free_buffer (buf); return; } if (result < 0) { xine_log (this->stream->xine, XINE_LOG_MSG, _("demux_mpeg_pes: warning: PACK stream id=0x%x decode failed.\n"), this->stream_id); /* What to do here? */ return; } return; } static void demux_mpeg_pes_vdr_seek_0 (demux_mpeg_pes_t *this, int n) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_mpeg_pes: vdr sync point #%d.\n", n); this->last_cell_time = 0; this->send_newpts = 1; this->buf_flag_seek = 0; this->nav_last_end_pts = this->nav_last_start_pts = 0; this->status = DEMUX_OK ; this->last_pts[0] = 0; this->last_pts[1] = 0; #ifdef PTS_BOUNCE this->apts = this->bpts = 0; this->bounce_left = 0; #endif } static int32_t parse_padding_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* Just skip padding. */ int todo = 6 + this->packet_len; int done = buf->size; (void)p; if (this->is_vdr && (buf->content[4] == 0xff)) demux_mpeg_pes_vdr_seek_0 (this, buf->content[5]); while (done < todo) { /* Handle Jumbo frames from VDR. */ int i; int size = buf->max_size; if ((todo - done) < size) size = todo - done; i = read_data(this, buf->mem, (off_t)size); if (i != size) break; done += i; } /* trigger detection of MPEG 1/2 respectively H.264 content */ this->mpeg12_h264_detected = 0; buf->free_buffer(buf); return this->packet_len + 6; } static int32_t parse_program_stream_map(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x.\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_ecm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_emm_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_dsmcc_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_iec_13522_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeA_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeB_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeC_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeD_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeE_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_program_stream_directory(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_ancillary_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_pes: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_program_stream_pack_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* program stream pack header */ off_t i; i = read_data(this, buf->mem+6, (off_t) 6); if (i != 6) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return -1; } this->mpeg1 = (p[4] & 0x40) == 0; if (this->mpeg1) { /* system_clock_reference */ this->scr = (int64_t)(p[4] & 0x02) << 30; this->scr |= (p[5] & 0xFF) << 22; this->scr |= (p[6] & 0xFE) << 14; this->scr |= (p[7] & 0xFF) << 7; this->scr |= (p[8] & 0xFE) >> 1; /* buf->scr = scr; */ /* mux_rate */ if (!this->rate) { this->rate = (p[9] & 0x7F) << 15; this->rate |= (p[10] << 7); this->rate |= (p[11] >> 1); } buf->free_buffer (buf); return 12; } else { /* mpeg2 */ int num_stuffing_bytes; /* system_clock_reference */ this->scr = (int64_t)(p[4] & 0x08) << 27 ; this->scr |= (p[4] & 0x03) << 28 ; this->scr |= p[5] << 20; this->scr |= (p[6] & 0xF8) << 12 ; this->scr |= (p[6] & 0x03) << 13 ; this->scr |= p[7] << 5; this->scr |= (p[8] & 0xF8) >> 3; /* optional - decode extension: this->scr *=300; this->scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) ); */ lprintf ("SCR=%"PRId64"\n", this->scr); /* mux_rate */ if (!this->rate) { this->rate = (p[0xA] << 14); this->rate |= (p[0xB] << 6); this->rate |= (p[0xC] >> 2); } i = read_data(this, buf->mem+12, (off_t) 2); if (i != 2) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return -1; } num_stuffing_bytes = p[0xD] & 0x07; i = read_data(this, buf->mem+14, (off_t) num_stuffing_bytes); if (i != num_stuffing_bytes) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return -1; } buf->free_buffer (buf); return 14 + num_stuffing_bytes; } } static int32_t parse_program_stream_system_header(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { /* program stream system header */ /* FIXME: Implement */ (void)p; buf->free_buffer (buf); return 6 + this->packet_len; } #if 0 static int32_t parse_private_stream_2(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { int64_t start_pts, end_pts; /* NAV Packet */ start_pts = ((int64_t)p[7+12] << 24); start_pts |= (p[7+13] << 16); start_pts |= (p[7+14] << 8); start_pts |= p[7+15]; end_pts = ((int64_t)p[7+16] << 24); end_pts |= (p[7+17] << 16); end_pts |= (p[7+18] << 8); end_pts |= p[7+19]; /* some input plugins like DVD can have better timing information and have * already set the input_time, so we can use the cell elapsed time from * the NAV packet for a much more accurate timing */ if (buf->extra_info->input_time) { int64_t cell_time, frames; cell_time = (p[7+0x18] >> 4 ) * 10 * 60 * 60 * 1000; cell_time += (p[7+0x18] & 0x0f) * 60 * 60 * 1000; cell_time += (p[7+0x19] >> 4 ) * 10 * 60 * 1000; cell_time += (p[7+0x19] & 0x0f) * 60 * 1000; cell_time += (p[7+0x1a] >> 4 ) * 10 * 1000; cell_time += (p[7+0x1a] & 0x0f) * 1000; frames = ((p[7+0x1b] & 0x30) >> 4) * 10; frames += ((p[7+0x1b] & 0x0f) ) ; if (p[7+0x1b] & 0x80) cell_time += (frames * 1000)/25; else cell_time += (frames * 1000)/30; this->last_cell_time = cell_time; this->last_cell_pos = this->input->get_current_pos (this->input); this->last_begin_time = buf->extra_info->input_time; } lprintf ("NAV packet, start pts = %"PRId64", end_pts = %"PRId64"\n", start_pts, end_pts); if (this->nav_last_end_pts != start_pts && !this->preview_mode) { lprintf("discontinuity detected by nav packet\n" ); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, start_pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, start_pts, 0); } } this->nav_last_end_pts = end_pts; this->nav_last_start_pts = start_pts; this->send_newpts = 0; this->last_pts[PTS_AUDIO] = this->last_pts[PTS_VIDEO] = 0; buf->content = p; buf->size = this->packet_len; buf->type = BUF_SPU_DVD; buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_NAV; buf->pts = 0; /* NAV packets do not have PES values */ this->video_fifo->put (this->video_fifo, buf); return this->packet_len; } #endif /* FIXME: Extension data is not parsed, and is also not skipped. */ static int32_t parse_pes_for_pts(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { int32_t header_len; /* some input plugins like DVD can have better timing information and have * already set the total_time, so we can derive our datarate from this */ if (buf->extra_info->total_time) this->rate = (int)((int64_t)this->input->get_length (this->input) * 1000 / (buf->extra_info->total_time * 50)); if (this->rate && this->last_cell_time) { if( this->last_begin_time == buf->extra_info->input_time ) buf->extra_info->input_time = this->last_cell_time + buf->extra_info->input_time + ((this->input->get_current_pos (this->input) - this->last_cell_pos) * 1000 / (this->rate * 50)); } if (this->rate && !buf->extra_info->input_time) buf->extra_info->input_time = (int)((int64_t)this->input->get_current_pos (this->input) * 1000 / (this->rate * 50)); /* FIXME: This was determined by comparing a single MPEG1 and a single MPEG2 stream */ if ((p[6] & 0xC0) != 0x80) { this->mpeg1 = 1; } else { this->mpeg1 = 0; } if (this->mpeg1) { header_len = 6; p += 6; /* packet_len -= 6; */ while ((p[0] & 0x80) == 0x80) { p++; header_len++; this->packet_len--; /* printf ("stuffing\n");*/ } if ((p[0] & 0xc0) == 0x40) { /* STD_buffer_scale, STD_buffer_size */ p += 2; header_len += 2; this->packet_len -= 2; } this->pts = 0; this->dts = 0; if ((p[0] & 0xf0) == 0x20) { this->pts = (int64_t) (p[ 0] & 0x0E) << 29 ; this->pts |= (int64_t) p[ 1] << 22 ; this->pts |= (int64_t) (p[ 2] & 0xFE) << 14 ; this->pts |= (int64_t) p[ 3] << 7 ; this->pts |= (int64_t) (p[ 4] & 0xFE) >> 1 ; p += 5; header_len+= 5; this->packet_len -=5; return header_len; } else if ((p[0] & 0xf0) == 0x30) { this->pts = (int64_t) (p[ 0] & 0x0E) << 29 ; this->pts |= (int64_t) p[ 1] << 22 ; this->pts |= (int64_t) (p[ 2] & 0xFE) << 14 ; this->pts |= (int64_t) p[ 3] << 7 ; this->pts |= (int64_t) (p[ 4] & 0xFE) >> 1 ; this->dts = (int64_t) (p[ 5] & 0x0E) << 29 ; this->dts |= (int64_t) p[ 6] << 22 ; this->dts |= (int64_t) (p[ 7] & 0xFE) << 14 ; this->dts |= (int64_t) p[ 8] << 7 ; this->dts |= (int64_t) (p[ 9] & 0xFE) >> 1 ; p += 10; header_len += 10; this->packet_len -= 10; return header_len; } else { p++; header_len++; this->packet_len--; return header_len; } } else { /* mpeg 2 */ if ((p[6] & 0xC0) != 0x80) { xine_log (this->stream->xine, XINE_LOG_MSG, _("demux_mpeg_pes: warning: PES header reserved 10 bits not found\n")); buf->free_buffer(buf); return -1; } /* check PES scrambling_control */ if ((p[6] & 0x30) != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("demux_mpeg_pes: warning: PES header indicates that " "this stream may be encrypted (encryption mode %d)\n"), (p[6] & 0x30) >> 4); _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "Media stream scrambled/encrypted", NULL); this->status = DEMUX_FINISHED; buf->free_buffer(buf); return -1; } if (p[7] & 0x80) { /* pts avail */ this->pts = (int64_t) (p[ 9] & 0x0E) << 29 ; this->pts |= (int64_t) p[10] << 22 ; this->pts |= (int64_t) (p[11] & 0xFE) << 14 ; this->pts |= (int64_t) p[12] << 7 ; this->pts |= (int64_t) (p[13] & 0xFE) >> 1 ; lprintf ("pts = %"PRId64"\n", this->pts); } else this->pts = 0; if (p[7] & 0x40) { /* dts avail */ this->dts = (int64_t) (p[14] & 0x0E) << 29 ; this->dts |= (int64_t) p[15] << 22 ; this->dts |= (int64_t) (p[16] & 0xFE) << 14 ; this->dts |= (int64_t) p[17] << 7 ; this->dts |= (int64_t) (p[18] & 0xFE) >> 1 ; } else this->dts = 0; header_len = p[8]; this->packet_len -= header_len + 3; return header_len + 9; } return 0; } static int32_t parse_private_stream_1(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { int track, spu_id; int32_t result; result = parse_pes_for_pts(this, p, buf); if (result < 0) return -1; p += result; /* printf("demux_mpeg_pes: private_stream_1: p[0] = 0x%02X\n", p[0]); */ if((p[0] & 0xE0) == 0x20) { spu_id = (p[0] & 0x1f); buf->content = p+1; buf->size = this->packet_len-1; buf->type = BUF_SPU_DVD + spu_id; buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; buf->pts = this->pts; this->video_fifo->put (this->video_fifo, buf); lprintf ("SPU PACK put on fifo\n"); return this->packet_len + result; } /* SVCD OGT subtitles in stream 0x70 */ if(p[0] == 0x70 && (p[1] & 0xFC) == 0x00) { spu_id = p[1]; buf->content = p+1; buf->size = this->packet_len-1; buf->type = BUF_SPU_SVCD + spu_id; buf->pts = this->pts; /* this is probably wrong: if( !preview_mode ) check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); lprintf ("SPU SVCD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return this->packet_len + result; } /* SVCD CVD subtitles in streams 0x00-0x03 */ if((p[0] & 0xFC) == 0x00) { spu_id = (p[0] & 0x03); buf->content = p+1; buf->size = this->packet_len-1; buf->type = BUF_SPU_CVD + spu_id; buf->pts = this->pts; /* this is probably wrong: if( !preview_mode ) check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); lprintf ("SPU CVD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return this->packet_len + result; } if ((p[0]&0xF0) == 0x80) { track = p[0] & 0x0F; /* hack : ac3 track */ buf->decoder_info[1] = p[1]; /* Number of frame headers */ buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */ buf->content = p+4; buf->size = this->packet_len-4; if (track & 0x8) { buf->type = BUF_AUDIO_DTS + (track & 0x07); /* DVDs only have 8 tracks */ } else { buf->type = BUF_AUDIO_A52 + track; } buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("A52 PACK put on fifo\n"); } else { buf->free_buffer(buf); } return this->packet_len + result; /* EVOB AC3/E-AC-3 */ } else if ((p[0]&0xf0) == 0xc0) { track = p[0] & 0x0F; /* hack : ac3 track */ buf->decoder_info[1] = p[1]; /* Number of frame headers */ buf->decoder_info[2] = p[2] << 8 | p[3]; /* First access unit pointer */ buf->content = p+4; buf->size = this->packet_len-4; if (p[4] == 0x0b && p[5] == 0x77 && ((p[9] >> 3) & 0x1f) <= 8) { buf->type = BUF_AUDIO_A52 + track; } else { buf->type = BUF_AUDIO_EAC3 + track; buf->decoder_flags |= BUF_FLAG_FRAME_END; } buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("A52/EAC3 PACK put on fifo\n"); } else { buf->free_buffer(buf); } return this->packet_len + result; } else if ((p[0]&0xf0) == 0xa0) { int pcm_offset; #if 0 int number_of_frame_headers; int first_access_unit_pointer; int audio_frame_number; int bits_per_sample; int sample_rate; int num_channels; int dynamic_range; #endif /* * found in http://members.freemail.absa.co.za/ginggs/dvd/mpeg2_lpcm.txt * appears to be correct. */ track = p[0] & 0x0F; #if 0 number_of_frame_headers = p[1]; /* unknown = p[2]; */ first_access_unit_pointer = p[3]; audio_frame_number = p[4]; /* * 000 => mono * 001 => stereo * 010 => 3 channel * ... * 111 => 8 channel */ num_channels = (p[5] & 0x7) + 1; switch ((p[5]>>4) & 3) { case 0: sample_rate = 48000; break; case 1: sample_rate = 96000; break; case 2: sample_rate = 44100; break; case 3: sample_rate = 32000; break; } switch ((p[5]>>6) & 3) { case 3: /* illegal, use 16-bits? */ default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "illegal lpcm sample format (%d), assume 16-bit samples\n", (p[5]>>6) & 3 ); case 0: bits_per_sample = 16; break; case 1: bits_per_sample = 20; break; case 2: bits_per_sample = 24; break; } dynamic_range = p[6]; #endif /* send lpcm config byte */ buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG; buf->decoder_info[2] = p[5]; pcm_offset = 7; buf->content = p+pcm_offset; buf->size = this->packet_len-pcm_offset; buf->type = BUF_AUDIO_LPCM_BE + track; buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("LPCM PACK put on fifo\n"); } else { buf->free_buffer(buf); } return this->packet_len + result; } else if((p[0]==0x0b) && (p[1]==0x77)) { int offset; int size; /* * A52/AC3 streams in some DVB-S recordings made with VDR. * It is broadcast by a german tv-station called PRO7. * PRO7 uses dolby 5.1 (A52 5.1) in some of the movies they broadcast, * (and they would switch it to stereo-sound(A52 2.0) during commercials.) * Here is the coresponding line from a channel.conf for the astra-satelite: * Pro-7:12480:v:S19.2E:27500:255:256;257:32:0:898:0:0:0 */ buf->decoder_info[1] = 0; /* Number of frame headers */ buf->decoder_info[2] = 0; /* First access unit pointer */ buf->content = p; size = this->packet_len; if ((size + result) > buf->max_size) { size = buf->max_size - result; } buf->size = size; buf->type = BUF_AUDIO_A52; buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if (this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("A52 PACK put on fifo\n"); } else { buf->free_buffer(buf); /* skip tail */ if (this->input->seek (this->input, this->packet_len - size, SEEK_CUR) < 0) return -1; return this->packet_len + result; } if (size == (int)(this->packet_len)) { return this->packet_len + result; } /* Handle Jumbo A52 frames from VDR. */ offset = size; while (offset < (int)(this->packet_len)) { int i; buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); size = this->packet_len - offset; if (size > buf->max_size) size = buf->max_size; offset += size; i = read_data(this, buf->mem, (off_t) (size)); if (i != size) { buf->free_buffer(buf); return this->packet_len + result; } buf->content = buf->mem; buf->size = size; buf->type = BUF_AUDIO_A52; buf->pts = 0; this->audio_fifo->put (this->audio_fifo, buf); lprintf ("A52 PACK put on fifo\n"); } return this->packet_len + result; } /* Some new streams have been encountered. 1) DVD+RW disc recorded with a Philips DVD recorder: - new unknown sub-stream id of 0xff */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("demux_mpeg_pes:Unrecognised private stream 1 0x%02x. Please report this to xine developers.\n"), p[0]); buf->free_buffer(buf); return this->packet_len + result; } static int32_t parse_video_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { int32_t result; uint32_t todo_length=0; uint32_t i; uint32_t chunk_length; int buf_type = BUF_VIDEO_MPEG; int payload_size; result = parse_pes_for_pts(this, p, buf); if (result < 0) return -1; p += result; buf->content = p; payload_size = buf->max_size - result; if (payload_size > (int)(this->packet_len)) payload_size = this->packet_len; /* H.264 broadcasts via DVB-S use standard video PES packets, so there is no way other than scanning the video data to detect whether BUF_VIDEO_H264 needs to be used. For performance reasons, this is not a general scanner for H.264 content, as this kind of data format is likely to be used only by VDR and VDR will ensure that an AUD-NAL unit will be at the beginning of the PES packet's payload. To minimize false hits, the whole payload is scanned for MPEG 1/2 start codes, so there is only a little chance left that a MPEG 1/2 slice 9 start code will be considered as a H.264 access unit delimiter (should only happen after a seek). Meaning of bit 0 and 1 of mpeg12_h264_detected: Bit 0: H.264 access unit delimiter seen Bit 1: H.264 AUD seen again or MPEG 1/2 start code seen For performance reasons, the scanner is only active until a H.264 AUD has been seen a second time or a MPEG 1/2 start code has been seen. The scanner get's activated initially (e. g. when opening the stream), after seeking or when VDR sends a padding packet. Until the scanner is convinced of it's decision by setting bit 1, the default behaviour is to assume MPEG 1/2 unless an AUD has been found at the beginning of the payload. */ if (this->mpeg12_h264_detected < 2) { uint8_t *pp = p + 2, *pp_limit = p + payload_size - 1; while (pp && pp < pp_limit) { if (pp[0] == 0x01 && pp[-1] == 0x00 && pp[-2] == 0x00) { if (pp[1] >= 0x80 || !pp[1]) { /* MPEG 1/2 start code */ this->mpeg12_h264_detected = 2; break; } else { int nal_type_code = pp[1] & 0x1f; if (nal_type_code == 9 && pp == (p + 2)) { /* access unit delimiter */ if (this->mpeg12_h264_detected == 1) { this->mpeg12_h264_detected = 3; break; } this->mpeg12_h264_detected = 1; } } } pp++; pp = memchr(pp, 0x01, pp_limit - pp); } lprintf("%s%c\n", (this->mpeg12_h264_detected & 1) ? "H.264" : "MPEG1/2", (this->mpeg12_h264_detected & 2) ? '!' : '?'); } /* when an H.264 AUD is seen, we first need to tell the decoder that the previous frame was complete. */ if (this->mpeg12_h264_detected & 1) { buf_type = BUF_VIDEO_H264; /* omit sending BUF_FLAG_FRAME_END for the first AUD occurence */ if (this->mpeg12_h264_detected > 2) { int nal_type_code = -1; if (payload_size >= 4 && p[2] == 0x01 && p[1] == 0x00 && p[0] == 0x00) nal_type_code = p[3] & 0x1f; if (nal_type_code == 9) { /* access unit delimiter */ buf_element_t *b = this->video_fifo->buffer_pool_alloc (this->video_fifo); b->content = b->mem; b->size = 0; b->pts = 0; b->type = buf_type; b->decoder_flags = BUF_FLAG_FRAME_END | (this->preview_mode ? BUF_FLAG_PREVIEW : 0); this->video_fifo->put (this->video_fifo, b); } } } if ((int)(this->packet_len) <= (buf->max_size - result)) { buf->size = this->packet_len; /* VDR ensures that H.264 still images end with an end of sequence NAL unit. We need to detect this to inform the decoder that the current frame is complete. */ if (this->mpeg12_h264_detected & 1) { uint8_t *t = buf->content + buf->size; if (buf->size >=4 && t[-1] == 10 && t[-2] == 0x01 && t[-3] == 0x00 && t[-4] == 0x00) /* end of sequence */ buf->decoder_flags = BUF_FLAG_FRAME_END | (this->preview_mode ? BUF_FLAG_PREVIEW : 0); } } else { buf->size = buf->max_size - result; todo_length = this->packet_len - buf->size; } buf->type = buf_type; buf->pts = this->pts; buf->decoder_info[0] = this->pts - this->dts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_VIDEO ); this->video_fifo->put (this->video_fifo, buf); while (todo_length > 0) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); if ((int)todo_length < buf->max_size) { chunk_length = todo_length; } else { chunk_length = buf->max_size; } i = read_data(this, buf->mem, (off_t) (chunk_length)); if (i != chunk_length) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return -1; } buf->content = buf->mem; buf->size = chunk_length; buf->type = buf_type; buf->pts = 0; todo_length -= chunk_length; /* VDR ensures that H.264 still images end with an end of sequence NAL unit. We need to detect this to inform the decoder that the current frame is complete. */ if ((this->mpeg12_h264_detected & 1) && todo_length <= 0) { uint8_t *t = buf->content + buf->size; if (buf->size >= 4 && t[-1] == 10 && t[-2] == 0x01 && t[-3] == 0x00 && t[-4] == 0x00) /* end of sequence */ buf->decoder_flags = BUF_FLAG_FRAME_END | (this->preview_mode ? BUF_FLAG_PREVIEW : 0); } this->video_fifo->put (this->video_fifo, buf); } lprintf ("MPEG Video PACK put on fifo\n"); return this->packet_len + result; } static int32_t parse_audio_stream(demux_mpeg_pes_t *this, uint8_t *p, buf_element_t *buf) { int track; int32_t result; result = parse_pes_for_pts(this, p, buf); if (result < 0) return -1; p += result; track = this->stream_id & 0x1f; buf->content = p; buf->size = this->packet_len; buf->type = BUF_AUDIO_MPEG + track; buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("MPEG Audio PACK put on fifo\n"); } else { buf->free_buffer(buf); } return this->packet_len + result; } static int demux_mpeg_pes_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen; demux_mpeg_pes_parse_pack(this, 0); return this->status; } #ifdef ESTIMATE_RATE_FIXED /*! Estimate bitrate by looking inside the MPEG file for presentation time stamps (PTS) and computing how far apart these are in bytes and in time. On failure return 0. This might be used after deciding that mux_rate in a stream is faulty. */ /* How many *sucessful* PTS samples do we take? */ #define MAX_SAMPLES 5 /* How many times we read blocks before giving up. */ #define MAX_READS 30 /* TRUNCATE x to the nearest multiple of y. */ #define TRUNC(x,y) (((x) / (y)) * (y)) static int demux_mpeg_pes_estimate_rate (demux_mpeg_pes_t *this) { buf_element_t *buf = NULL; unsigned char *p; int is_mpeg1=0; off_t pos, last_pos=0; off_t step, mpeg_length; int64_t pts, last_pts=0; int reads=0 /* Number of blocks read so far */; int count=0; /* Number of sucessful PTS found so far */ int rate=0; /* The return rate value */ int stream_id; /* We can't estimate by sampling if we don't thave the ability to randomly access the and more importantly reset after accessessing. */ if (!(this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE)) return 0; mpeg_length= this->input->get_length (this->input); step = TRUNC((mpeg_length/MAX_SAMPLES), 2048); if (step <= 0) step = 2048; /* avoid endless loop for tiny files */ pos = step; /* At this point "pos", and "step" are a multiple of blocksize and they should continue to be so throughout. */ if (this->input->seek (this->input, pos, SEEK_SET) != pos) return 0; while ( (buf = this->input->read_block (this->input, this->video_fifo, 2048)) && count < MAX_SAMPLES && reads++ < MAX_READS ) { p = buf->content; /* len = this->mnBlocksize; */ if (p[3] == 0xBA) { /* program stream pack header */ is_mpeg1 = (p[4] & 0x40) == 0; if (is_mpeg1) p += 12; else p += 14 + (p[0xD] & 0x07); } if (p[3] == 0xbb) /* program stream system header */ p += 6 + ((p[4] << 8) | p[5]); /* we should now have a PES packet here */ if (p[0] || p[1] || (p[2] != 1)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_mpeg_pes: error %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]); buf->free_buffer (buf); return rate; } stream_id = p[3]; pts = 0; if ((stream_id < 0xbc) || ((stream_id & 0xf0) != 0xe0)) { pos += (off_t) 2048; buf->free_buffer (buf); continue; /* only use video packets */ } if (is_mpeg1) { if (p[3] != 0xBF) { /* stream_id */ p += 6; /* packet_len -= 6; */ while ((p[0] & 0x80) == 0x80) { p++; /* stuffing */ } if ((p[0] & 0xc0) == 0x40) { /* STD_buffer_scale, STD_buffer_size */ p += 2; } if ( ((p[0] & 0xf0) == 0x20) || ((p[0] & 0xf0) == 0x30) ) { pts = (int64_t)(p[ 0] & 0x0E) << 29 ; pts |= p[ 1] << 22 ; pts |= (p[ 2] & 0xFE) << 14 ; pts |= p[ 3] << 7 ; pts |= (p[ 4] & 0xFE) >> 1 ; } } } else { /* mpeg 2 */ if (p[7] & 0x80) { /* pts avail */ pts = (int64_t)(p[ 9] & 0x0E) << 29 ; pts |= p[10] << 22 ; pts |= (p[11] & 0xFE) << 14 ; pts |= p[12] << 7 ; pts |= (p[13] & 0xFE) >> 1 ; } else pts = 0; } if (pts) { if ( (pos>last_pos) && (pts>last_pts) ) { int cur_rate; cur_rate = ((pos - last_pos)*90000) / ((pts - last_pts) * 50); rate = (count * rate + cur_rate) / (count+1); count ++; /* printf ("demux_mpeg_pes: stream_id %02x, pos: %"PRId64", pts: %d, cur_rate = %d, overall rate : %d\n", stream_id, pos, pts, cur_rate, rate); */ } last_pos = pos; last_pts = pts; pos += step; } else pos += 2048; buf->free_buffer (buf); if (pos > mpeg_length || this->input->seek (this->input, pos, SEEK_SET) == (off_t)-1) break; } } lprintf("est_rate=%d\n",rate); return rate; } #endif /*ESTIMATE_RATE_FIXED*/ static int demux_mpeg_pes_get_status (demux_plugin_t *this_gen) { demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen; return this->status; } static void demux_mpeg_pes_send_headers (demux_plugin_t *this_gen) { demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; /* * send start buffer */ _x_demux_control_start(this->stream); #ifdef USE_ILL_ADVISED_ESTIMATE_RATE_INITIALLY if (!this->rate) this->rate = demux_mpeg_pes_estimate_rate (this); #else /* Set to Use rate given in by stream initially. */ this->rate = 0; #endif if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { int num_buffers = NUM_PREVIEW_BUFFERS; if (this->input->seek (this->input, 0, SEEK_SET) != 0) { this->status = DEMUX_FINISHED; return; } this->status = DEMUX_OK ; while ( (num_buffers>0) && (this->status == DEMUX_OK) ) { demux_mpeg_pes_parse_pack(this, 1); num_buffers --; } } else if((this->input->get_capabilities(this->input) & INPUT_CAP_PREVIEW) != 0) { this->preview_size = this->input->get_optional_data(this->input, &this->preview_data, INPUT_OPTIONAL_DATA_PREVIEW); this->preview_done = 0; this->status = DEMUX_OK ; while ( (this->preview_done < this->preview_size) && (this->status == DEMUX_OK) ) demux_mpeg_pes_parse_pack(this, 1); this->preview_size = 0; } this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->rate * 50 * 8); } static int demux_mpeg_pes_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen; start_time /= 1000; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { if (start_pos) { start_pos /= (off_t) 2048; start_pos *= (off_t) 2048; this->input->seek (this->input, start_pos, SEEK_SET); } else if (start_time) { if (this->last_cell_time) { start_pos = start_time - (this->last_cell_time + this->last_begin_time)/1000; start_pos *= this->rate; start_pos *= 50; start_pos += this->last_cell_pos; } else { start_pos = start_time; start_pos *= this->rate; start_pos *= 50; } start_pos /= (off_t) 2048; start_pos *= (off_t) 2048; this->input->seek (this->input, start_pos, SEEK_SET); } else this->input->seek (this->input, 0, SEEK_SET); } /* * now start demuxing */ this->last_cell_time = 0; this->send_newpts = 1; if( !playing ) { this->buf_flag_seek = 0; this->nav_last_end_pts = this->nav_last_start_pts = 0; this->status = DEMUX_OK ; this->last_pts[0] = 0; this->last_pts[1] = 0; #ifdef PTS_BOUNCE this->apts = this->bpts = 0; this->bounce_left = 0; #endif } else { this->buf_flag_seek = 1; this->nav_last_end_pts = this->nav_last_start_pts = 0; /* trigger detection of MPEG 1/2 respectively H.264 content */ this->mpeg12_h264_detected = 0; _x_demux_flush_engine(this->stream); } return this->status; } static int demux_mpeg_pes_get_stream_length (demux_plugin_t *this_gen) { demux_mpeg_pes_t *this = (demux_mpeg_pes_t *) this_gen; /* * find input plugin */ if (this->rate) return (int)((int64_t) 1000 * this->input->get_length (this->input) / (this->rate * 50)); else return 0; } static uint32_t demux_mpeg_pes_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mpeg_pes_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_mpeg_pes_t *this; lprintf ("open_plugin:detection_method=%d\n", stream->content_detection_method); switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint8_t buf[6]; /* use demux_mpeg_block for block devices */ if ((input->get_capabilities(input) & INPUT_CAP_BLOCK)) { return NULL; } if (_x_demux_read_header(input, buf, sizeof(buf)) != 6) { return NULL; } if (buf[0] || buf[1] || (buf[2] != 0x01)) { lprintf("open_plugin:preview_data failed\n"); return NULL; } switch (buf[3]) { case 0xe0 ... 0xef: case 0xc0 ... 0xdf: case 0xbd ... 0xbe: break; default: return NULL; } lprintf("open_plugin:Accepting detection_method XINE_DEMUX_CONTENT_STRATEGY (preview_data)\n"); } break; case METHOD_BY_MRL: break; case METHOD_EXPLICIT: break; default: return NULL; } this = calloc(1, sizeof(demux_mpeg_pes_t)); if (!this) return NULL; /* trigger detection of MPEG 1/2 respectively H.264 content */ this->mpeg12_h264_detected = 0; this->preview_size = 0; this->stream = stream; this->input = input; this->status = DEMUX_FINISHED; this->is_vdr = 0; if (input->input_class->identifier && !strcmp (input->input_class->identifier, "VDR")) this->is_vdr = 1; /* Don't start demuxing stream until we see a program_stream_pack_header */ /* We need to system header in order to identify is the stream is mpeg1 or mpeg2. */ this->wait_for_program_stream_pack_header = 1; this->demux_plugin.send_headers = demux_mpeg_pes_send_headers; this->demux_plugin.send_chunk = demux_mpeg_pes_send_chunk; this->demux_plugin.seek = demux_mpeg_pes_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_mpeg_pes_get_status; this->demux_plugin.get_stream_length = demux_mpeg_pes_get_stream_length; this->demux_plugin.get_capabilities = demux_mpeg_pes_get_capabilities; this->demux_plugin.get_optional_data = demux_mpeg_pes_get_optional_data; this->demux_plugin.demux_class = class_gen; return &this->demux_plugin; } void *demux_pes_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_mpeg_pes_class = { .open_plugin = open_plugin, .description = N_("mpeg pes demux plugin"), .identifier = "MPEG_PES", .mimetypes = "video/mp2p: m2p: MPEG2 program stream;", .extensions = "pes vdr:/ netvdr:/", .dispose = NULL, }; return (void *)&demux_mpeg_pes_class; } xine-lib-1.2/src/demuxers/demux_ivf.c0000644000175000017500000002256514647725152015453 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* #define LOG */ #define LOG_MODULE "demux_ivf" #define LOG_VERBOSE #include "group_video.h" #include #include #include "bswap.h" static const struct { uint32_t buf_type; char fourcc[4]; } ivf_tag_map[] = { { BUF_VIDEO_AV1, "AV01" }, { BUF_VIDEO_H264, "H264" }, { BUF_VIDEO_HEVC, "HEVC" }, { BUF_VIDEO_VP8, "VP80" }, { BUF_VIDEO_VP9, "VP90" }, }; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int seek_flag; int64_t last_pts; uint32_t buf_type; uint32_t num_frames; uint32_t frame_number; uint32_t frame_rate_num, frame_rate_den; } demux_ivf_t; static int demux_ivf_send_chunk(demux_plugin_t *this_gen) { demux_ivf_t *this = (demux_ivf_t *)this_gen; uint8_t hdr[12]; uint32_t len; int64_t pts; int normpos = 0; off_t length; int input_time, total_time; /* read and parse header */ if (this->input->read(this->input, hdr, 12) != 12) { this->status = DEMUX_FINISHED; return this->status; } len = _X_LE_32(hdr); pts = _X_LE_64(hdr + 4); lprintf("frame %d: pts %ld %ld\n", this->frame_number, pts, pts * 90000 * this->frame_rate_num / this->frame_rate_den); pts = pts * 90000 * this->frame_rate_num / this->frame_rate_den; /* handle seek and discontinuity */ if (this->seek_flag) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->seek_flag = 0; } else if (this->last_pts - pts > 270000 || this->last_pts - pts < -270000) { _x_demux_control_newpts(this->stream, pts, 0); } this->last_pts = pts; /* calculate normpos */ length = this->input->get_length(this->input); if (length > 0) { off_t curpos = this->input->get_current_pos(this->input); if (curpos > 0) { normpos = (int)((double) curpos * 65535 / length); } } /* calculate timepos */ input_time = (uint64_t)this->frame_number * 1000 * this->frame_rate_num / this->frame_rate_den; total_time = (uint64_t)this->num_frames * 1000 * this->frame_rate_num / this->frame_rate_den; /* send frame */ if (_x_demux_read_send_data(this->video_fifo, this->input, len, pts, this->buf_type, 0, normpos, input_time, total_time, this->frame_number) < 0) { this->status = DEMUX_FINISHED; return this->status; } this->frame_number++; return this->status; } static int demux_ivf_get_status(demux_plugin_t *this_gen) { demux_ivf_t *this = (demux_ivf_t *)this_gen; return this->status; } static void demux_ivf_send_headers(demux_plugin_t *this_gen) { demux_ivf_t *this = (demux_ivf_t *)this_gen; buf_element_t *buf; uint8_t hdr[32]; int width, height; xine_bmiheader *bih; off_t file_length; this->video_fifo = this->stream->video_fifo; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_demux_control_start(this->stream); /* read and parse header */ if (this->input->seek(this->input, 0, SEEK_SET) != 0) { this->status = DEMUX_FINISHED; return; } if (this->input->read(this->input, hdr, 32) != 32) { this->status = DEMUX_FINISHED; return; } width = _X_LE_16(&hdr[12]); height = _X_LE_16(&hdr[14]); this->frame_rate_den = _X_LE_32(&hdr[16]); this->frame_rate_num = _X_LE_32(&hdr[20]); this->num_frames = _X_LE_32(&hdr[24]); if (!this->frame_rate_num || !this->frame_rate_den) { this->status = DEMUX_FINISHED; return; } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "codec=%4.4s size=%dx%d rate=%u:%u num_frames=%u\n", (const char *)hdr + 8, width, height, this->frame_rate_num, this->frame_rate_den, this->num_frames); _x_stream_info_set (this->stream, XINE_STREAM_INFO_FRAME_DURATION, (int64_t)this->frame_rate_num * 90000 / this->frame_rate_den); file_length = this->input->get_length(this->input); if (file_length > 32 + 12*this->num_frames) { file_length = file_length - 32 - 12*this->num_frames; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, file_length / this->frame_rate_num * this->frame_rate_den / this->num_frames * 8); } /* configure decoder */ buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; buf->type = this->buf_type; bih = (xine_bmiheader *)buf->content; memset(bih, 0, sizeof(*bih)); bih->biSize = sizeof(xine_bmiheader); bih->biWidth = width; bih->biHeight = height; buf->size = sizeof(*bih); buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = (int64_t)this->frame_rate_num * 90000 / this->frame_rate_den; buf->decoder_flags |= BUF_FLAG_ASPECT; buf->decoder_info[1] = width; buf->decoder_info[2] = height; this->video_fifo->put(this->video_fifo, buf); this->status = DEMUX_OK; } static int demux_ivf_seek(demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_ivf_t *this = (demux_ivf_t *)this_gen; this->seek_flag = 1; /* no seek table, only seeking to beginning is supported */ if (start_pos == 0 && start_time == 0) { if (playing) _x_demux_flush_engine(this->stream); if (this->input->seek (this->input, 32, SEEK_SET) != 32) { return this->status; } this->frame_number = 0; this->status = DEMUX_OK; return this->status; } return this->status; } static int demux_ivf_get_stream_length(demux_plugin_t *this_gen) { demux_ivf_t *this = (demux_ivf_t *)this_gen; if (!this->frame_rate_den) return 0; return (uint64_t)this->num_frames * 1000 * this->frame_rate_num / this->frame_rate_den; } static uint32_t demux_ivf_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_ivf_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin(demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_ivf_t *this; uint8_t scratch[32]; size_t i; uint32_t buf_type = 0; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: if (_x_demux_read_header(input, scratch, 32) != 32) return 0; if ( !_x_is_fourcc(scratch, "DKIF") ) return 0; if (_X_LE_16(scratch + 4) != 0 /* version */ || _X_LE_16(scratch + 6) != 32 /* header size */) return 0; if (!_X_LE_32(scratch + 16) /* frame_rate_den */ || !_X_LE_32(scratch + 20) /* frame_rate_num */ ) return 0; for (i = 0; i < sizeof(ivf_tag_map) / sizeof(ivf_tag_map[0]); i++) { if (_x_is_fourcc(&scratch[8], ivf_tag_map[i].fourcc)) { buf_type = ivf_tag_map[i].buf_type; break; } } if (!buf_type) { xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unsupportd codec tag %4.4s\n", &scratch[8]); return 0; } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } this = calloc(1, sizeof(*this)); if (!this) return NULL; this->stream = stream; this->input = input; this->status = DEMUX_FINISHED; this->buf_type = buf_type; this->demux_plugin.send_headers = demux_ivf_send_headers; this->demux_plugin.send_chunk = demux_ivf_send_chunk; this->demux_plugin.seek = demux_ivf_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_ivf_get_status; this->demux_plugin.get_stream_length = demux_ivf_get_stream_length; this->demux_plugin.get_capabilities = demux_ivf_get_capabilities; this->demux_plugin.get_optional_data = demux_ivf_get_optional_data; this->demux_plugin.demux_class = class_gen; return &this->demux_plugin; } void *demux_ivf_init_class(xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_ivf_class = { .open_plugin = open_plugin, .description = N_("IVF demuxer"), .identifier = "ivf", .mimetypes = NULL, .extensions = "ivf", .dispose = NULL, }; return (void *)&demux_ivf_class; } xine-lib-1.2/src/demuxers/demux_aiff.c0000644000175000017500000003125614647725152015571 0ustar meme/* * Copyright (C) 2001-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * AIFF File Demuxer by Mike Melanson (melanson@pcisys.net) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_audio.h" #define FOURCC_TAG BE_FOURCC #define FORM_TAG FOURCC_TAG('F', 'O', 'R', 'M') #define AIFF_TAG FOURCC_TAG('A', 'I', 'F', 'F') #define COMM_TAG FOURCC_TAG('C', 'O', 'M', 'M') #define SSND_TAG FOURCC_TAG('S', 'S', 'N', 'D') #define APCM_TAG FOURCC_TAG('A', 'P', 'C', 'M') #define NAME_TAG FOURCC_TAG('N', 'A', 'M', 'E') #define AUTH_TAG FOURCC_TAG('A', 'U', 'T', 'H') #define COPY_TAG FOURCC_TAG('(', 'c', ')', ' ') #define ANNO_TAG FOURCC_TAG('A', 'N', 'N', 'O') #define PREAMBLE_SIZE 8 #define AIFF_SIGNATURE_SIZE 12 #define PCM_BLOCK_ALIGN 1024 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; unsigned int audio_sample_rate; unsigned int audio_bits; unsigned int audio_channels; unsigned int audio_block_align; unsigned int audio_bytes_per_second; unsigned int running_time; off_t data_start; off_t data_size; int seek_flag; /* this is set when a seek just occurred */ } demux_aiff_t; /* converts IEEE 80bit extended into int, based on FFMPEG code */ static int extended_to_int(const unsigned char p[10]) { uint64_t m = 0; int e, i; for (i = 0; i < 8; i++) m = (m<<8) + p[2+i];; e = (((int)p[0]&0x7f)<<8) | p[1]; if (e == 0x7fff && m) return (int)(0.0/0.0); e -= 16383 + 63; if (p[0]&0x80) m= -m; return (int) ldexp(m, e); } /* returns 1 if the AIFF file was opened successfully, 0 otherwise */ static int probe_aiff_file(input_plugin_t *input) { unsigned char signature[AIFF_SIGNATURE_SIZE]; if (_x_demux_read_header(input, signature, AIFF_SIGNATURE_SIZE) != AIFF_SIGNATURE_SIZE) return 0; /* check the signature */ if( !_x_is_fourcc(&signature[0], "FORM") || !_x_is_fourcc(&signature[8], "AIFF") ) return 0; return 1; } static int open_aiff_file(demux_aiff_t *this) { unsigned char preamble[PREAMBLE_SIZE]; unsigned int chunk_type; unsigned int chunk_size; unsigned char extended_sample_rate[10]; unsigned int audio_frames = 0; /* file is qualified; skip over the header bytes in the stream */ if (this->input->seek(this->input, AIFF_SIGNATURE_SIZE, SEEK_SET) != AIFF_SIGNATURE_SIZE) return 0; this->audio_channels = 0; this->audio_bits = 0; this->audio_sample_rate = 0; this->audio_bytes_per_second = 0; /* traverse the chunks */ while (1) { if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return 0; } chunk_type = _X_BE_32(&preamble[0]); chunk_size = _X_BE_32(&preamble[4]); if (chunk_type == COMM_TAG) { unsigned char buffer[100]; if (chunk_size > sizeof(buffer) / sizeof(buffer[0])) { /* the chunk is too large to fit in the buffer -> this cannot be an aiff chunk */ this->status = DEMUX_FINISHED; return 0; } if (this->input->read(this->input, buffer, chunk_size) != chunk_size) { this->status = DEMUX_FINISHED; return 0; } this->audio_channels = _X_BE_16(&buffer[0]); audio_frames = _X_BE_32(&buffer[2]); this->audio_bits = _X_BE_16(&buffer[6]); memcpy(&extended_sample_rate, &buffer[8], sizeof(extended_sample_rate)); this->audio_sample_rate = extended_to_int(extended_sample_rate); this->audio_bytes_per_second = this->audio_channels * (this->audio_bits / 8) * this->audio_sample_rate; } else if ((chunk_type == SSND_TAG) || (chunk_type == APCM_TAG)) { /* audio data has been located; proceed to demux loop after * skipping 8 more bytes (2 more 4-byte numbers) */ if (this->input->seek(this->input, 8, SEEK_CUR) < 0) return 0; this->data_start = this->input->get_current_pos(this->input); this->data_size = audio_frames * this->audio_channels * (this->audio_bits / 8); if (this->audio_sample_rate) this->running_time = (audio_frames / this->audio_sample_rate) * 1000; break; } else { /* if chunk contains metadata, it will be word-aligned (as seen at sox and ffmpeg) */ if ( ((chunk_type == NAME_TAG) || (chunk_type==AUTH_TAG) || (chunk_type == COPY_TAG) || (chunk_type==ANNO_TAG)) && (chunk_size&1)) chunk_size++; /* unrecognized; skip it */ if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) return 0; } } /* the audio parameters should have been set at this point */ if (!this->audio_channels) return 0; /* we should send only complete frames to decoder, as it * doesn't handle underconsumption yet */ this->audio_block_align = PCM_BLOCK_ALIGN - PCM_BLOCK_ALIGN % (this->audio_bits / 8 * this->audio_channels); return 1; } static int demux_aiff_send_chunk (demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; buf_element_t *buf = NULL; unsigned int remaining_sample_bytes; off_t current_file_pos; int64_t current_pts; int i; /* just load data chunks from wherever the stream happens to be * pointing; issue a DEMUX_FINISHED status if EOF is reached */ remaining_sample_bytes = this->audio_block_align; current_file_pos = this->input->get_current_pos(this->input) - this->data_start; current_pts = current_file_pos; current_pts *= 90000; current_pts /= this->audio_bytes_per_second; if (this->seek_flag) { _x_demux_control_newpts(this->stream, current_pts, BUF_FLAG_SEEK); this->seek_flag = 0; } while (remaining_sample_bytes) { if( !this->audio_fifo ) { this->status = DEMUX_FINISHED; break; } buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_BE; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = current_pts / 90; buf->pts = current_pts; if ((int)remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } /* convert 8-bit signed -> unsigned */ if (this->audio_bits == 8) for (i = 0; i < buf->size; i++) buf->content[i] += 0x80; if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); } return this->status; } static void demux_aiff_send_headers(demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->audio_channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->audio_sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->audio_bits); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_BE; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->audio_sample_rate; buf->decoder_info[2] = this->audio_bits; buf->decoder_info[3] = this->audio_channels; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_aiff_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_aiff_t *this = (demux_aiff_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); (void)start_time; (void)playing; this->seek_flag = 1; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* check the boundary offsets */ if (start_pos < 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by * the block alignment integer-wise, and multiply the quotient by the * block alignment to get the new aligned offset. Add the data start * offset and seek to the new position. */ start_pos /= this->audio_block_align; start_pos *= this->audio_block_align; start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); } return this->status; } static int demux_aiff_get_status (demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_aiff_get_stream_length (demux_plugin_t *this_gen) { demux_aiff_t *this = (demux_aiff_t *) this_gen; return this->running_time; } static uint32_t demux_aiff_get_capabilities(demux_plugin_t *this_gen){ (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_aiff_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type){ (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_aiff_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_aiff_file(input)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_aiff_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_aiff_send_headers; this->demux_plugin.send_chunk = demux_aiff_send_chunk; this->demux_plugin.seek = demux_aiff_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_aiff_get_status; this->demux_plugin.get_stream_length = demux_aiff_get_stream_length; this->demux_plugin.get_capabilities = demux_aiff_get_capabilities; this->demux_plugin.get_optional_data = demux_aiff_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_aiff_file(this)) { free (this); return NULL; } return &this->demux_plugin; } void *demux_aiff_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_aiff_class = { .open_plugin = open_plugin, .description = N_("AIFF file demux plugin"), .identifier = "AIFF", .mimetypes = "audio/x-aiff: aif, aiff: AIFF audio;" "audio/aiff: aif, aiff: AIFF audio;" "audio/x-pn-aiff: aif, aiff: AIFF audio;", .extensions = "aif aiff", .dispose = NULL, }; return (void *)&demux_aiff_class; } xine-lib-1.2/src/demuxers/demux_realaudio.c0000644000175000017500000003242614647725152016631 0ustar meme/* * Copyright (C) 2001-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * RealAudio File Demuxer by Mike Melanson (melanson@pcisys.net) * improved by James Stembridge (jstembridge@users.sourceforge.net) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_audio.h" #include "demux_real_common.h" #define RA_FILE_HEADER_PREV_SIZE 22 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; unsigned int fourcc; unsigned int audio_type; unsigned short block_align; uint8_t seek_flag:1; /* this is set when a seek just occurred */ off_t data_start; off_t data_size; uint32_t cfs; uint16_t w, h; int frame_len; size_t frame_size; uint8_t *frame_buffer; unsigned char *header; unsigned int header_size; } demux_ra_t; /* Map flavour to bytes per second */ //static const int sipr_fl2bps[4] = {813, 1062, 625, 2000}; // 6.5, 8.5, 5, 16 kbit per second /* returns 1 if the RealAudio file was opened successfully, 0 otherwise */ static int open_ra_file(demux_ra_t *this) { uint8_t file_header[RA_FILE_HEADER_PREV_SIZE]; /* check the signature */ if (_x_demux_read_header(this->input, file_header, RA_FILE_HEADER_PREV_SIZE) != RA_FILE_HEADER_PREV_SIZE) return 0; if ( memcmp(file_header, ".ra", 3) != 0 ) return 0; /* read version */ const uint16_t version = _X_BE_16(&file_header[0x04]); /* read header size according to version */ if (version == 3) this->header_size = _X_BE_16(&file_header[0x06]) + 8; else if (version == 4) this->header_size = _X_BE_32(&file_header[0x12]) + 16; else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unknown version number %d\n", version); return 0; } /* allocate for and read header data */ this->header = malloc(this->header_size); if (!this->header || _x_demux_read_header (this->input, this->header, this->header_size) != (int)this->header_size) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unable to read header\n"); free(this->header); return 0; } off_t offset; /* read header data according to version */ if((version == 3) && (this->header_size >= 32)) { this->data_size = _X_BE_32(&this->header[0x12]); this->block_align = 240; offset = 0x16; } else if(this->header_size >= 72) { this->data_size = _X_BE_32(&this->header[0x1C]); this->block_align = _X_BE_16(&this->header[0x2A]); if(this->header[0x3D] == 4) this->fourcc = _X_ME_32(&this->header[0x3E]); else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: invalid fourcc size %d\n", this->header[0x3D]); free(this->header); return 0; } offset = 0x45; } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: header too small\n"); free(this->header); return 0; } /* Read title */ { const uint8_t len = this->header[offset]; if(len && ((offset+len+2) < this->header_size)) { _x_meta_info_n_set(this->stream, XINE_META_INFO_TITLE, &this->header[offset+1], len); offset += len+1; } else offset++; } /* Author */ { const uint8_t len = this->header[offset]; if(len && ((offset+len+1) < this->header_size)) { _x_meta_info_n_set(this->stream, XINE_META_INFO_ARTIST, &this->header[offset+1], len); offset += len+1; } else offset++; } /* Copyright/Date */ { const uint8_t len = this->header[offset]; if(len && ((offset+len) <= this->header_size)) { _x_meta_info_n_set(this->stream, XINE_META_INFO_YEAR, &this->header[offset+1], len); offset += len+1; } else offset++; } /* Fourcc for version 3 comes after meta info */ if(version == 3) { if (((offset+7) <= this->header_size)) { if(this->header[offset+2] == 4) this->fourcc = _X_ME_32(&this->header[offset+3]); else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: invalid fourcc size %d\n", this->header[offset+2]); free(this->header); return 0; } } else { this->fourcc = ME_FOURCC('l', 'p', 'c', 'J'); } } _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->fourcc); this->audio_type = _x_formattag_to_buf_audio(this->fourcc); if (version == 4) { uint16_t sps = _X_BE_16 (this->header+44); if (!sps) sps = 1; this->w = _X_BE_16 (this->header+42); this->h = _X_BE_16 (this->header+40); this->cfs = _X_BE_32 (this->header+24); if (this->w < 0x8000 && this->h < 0x8000) { uint64_t fs; this->frame_len = this->w * this->h; fs = (uint64_t) this->frame_len * sps; if (fs < 0x80000000) { this->frame_size = fs; this->frame_buffer = calloc(this->frame_size, 1); } } if (! this->frame_buffer) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: malloc failed\n"); return 0; } if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO) this->block_align = this->cfs; } /* seek to start of data */ this->data_start = this->header_size; if (this->input->seek(this->input, this->data_start, SEEK_SET) != this->data_start) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: unable to seek to data start\n"); return 0; } if( !this->audio_type ) this->audio_type = BUF_AUDIO_UNKNOWN; return 1; } static int demux_ra_send_chunk(demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; off_t current_normpos = 0; /* just load data chunks from wherever the stream happens to be * pointing; issue a DEMUX_FINISHED status if EOF is reached */ if( this->input->get_length (this->input) ) current_normpos = (int)( (double) (this->input->get_current_pos (this->input) - this->data_start) * 65535 / this->data_size ); const int64_t current_pts = 0; /* let the engine sort out the pts for now */ if (this->seek_flag) { _x_demux_control_newpts(this->stream, current_pts, BUF_FLAG_SEEK); this->seek_flag = 0; } if (this->audio_type == BUF_AUDIO_28_8 || this->audio_type == BUF_AUDIO_SIPRO) { if (this->audio_type == BUF_AUDIO_SIPRO) { if(this->input->read(this->input, this->frame_buffer, this->frame_len) < this->frame_len) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: failed to read audio chunk\n"); this->status = DEMUX_FINISHED; return this->status; } demux_real_sipro_swap (this->frame_buffer, this->frame_len * 2 / 96); } else { int x, y; for (y = 0; y < this->h; y++) for (x = 0; x < this->h / 2; x++) { const int pos = x * 2 * this->w + y * this->cfs; if(this->input->read(this->input, this->frame_buffer + pos, this->cfs) < this->cfs) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_realaudio: failed to read audio chunk\n"); this->status = DEMUX_FINISHED; return this->status; } } } _x_demux_send_data(this->audio_fifo, this->frame_buffer, this->frame_size, current_pts, this->audio_type, 0, current_normpos, current_pts / 90, 0, 0); } else if(_x_demux_read_send_data(this->audio_fifo, this->input, this->block_align, current_pts, this->audio_type, 0, current_normpos, current_pts / 90, 0, 0) < 0) { this->status = DEMUX_FINISHED; } return this->status; } static void demux_ra_send_headers(demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->fourcc); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo && this->audio_type) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END; buf->size = MIN ((int)(this->header_size), buf->max_size); memcpy(buf->content, this->header, buf->size); this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_ra_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_ra_t *this = (demux_ra_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); (void)start_time; (void)playing; this->seek_flag = 1; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* check the boundary offsets */ if (start_pos <= 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by * the block alignment integer-wise, and multiply the quotient by the * block alignment to get the new aligned offset. Add the data start * offset and seek to the new position. */ start_pos /= this->block_align; start_pos *= this->block_align; start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); } return this->status; } static void demux_ra_dispose (demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; free(this->header); free(this->frame_buffer); free(this); } static int demux_ra_get_status (demux_plugin_t *this_gen) { demux_ra_t *this = (demux_ra_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_ra_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_ra_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_ra_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_ra_t *this; this = calloc(1, sizeof(demux_ra_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->frame_buffer = NULL; this->demux_plugin.send_headers = demux_ra_send_headers; this->demux_plugin.send_chunk = demux_ra_send_chunk; this->demux_plugin.seek = demux_ra_seek; this->demux_plugin.dispose = demux_ra_dispose; this->demux_plugin.get_status = demux_ra_get_status; this->demux_plugin.get_stream_length = demux_ra_get_stream_length; this->demux_plugin.get_capabilities = demux_ra_get_capabilities; this->demux_plugin.get_optional_data = demux_ra_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_ra_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_realaudio_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_realaudio_class = { .open_plugin = open_plugin, .description = N_("RealAudio file demux plugin"), .identifier = "RA", .mimetypes = "audio/x-realaudio: ra: RealAudio File;", .extensions = "ra", .dispose = NULL, }; return (void *)&demux_realaudio_class; } xine-lib-1.2/src/demuxers/demux_fli.c0000644000175000017500000002622314647725152015434 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * FLI File Demuxer by Mike Melanson (melanson@pcisys.net) * For information on the FLI format, as well as various traps to * avoid while programming a FLI decoder, visit: * http://www.pcisys.net/~melanson/codecs/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include "bswap.h" #define FLI_HEADER_SIZE 128 #define FLI_HEADER_SIZE_MC 12 /* header size for Magic Carpet game FLIs */ #define FLI_FILE_MAGIC_1 0xAF11 #define FLI_FILE_MAGIC_2 0xAF12 #define FLI_FILE_MAGIC_3 0xAF13 /* for internal use only */ #define FLI_CHUNK_MAGIC_1 0xF1FA #define FLI_CHUNK_MAGIC_2 0xF5FA #define FLI_MC_PTS_INC 6000 /* pts increment for Magic Carpet game FLIs */ typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; /* video information */ xine_bmiheader bih; unsigned char fli_header[FLI_HEADER_SIZE]; /* playback info */ unsigned int magic_number; unsigned int speed; unsigned int frame_pts_inc; unsigned int frame_count; int64_t pts_counter; off_t stream_len; } demux_fli_t; /* returns 1 if the FLI file was opened successfully, 0 otherwise */ static int open_fli_file(demux_fli_t *this) { if (_x_demux_read_header(this->input, this->fli_header, FLI_HEADER_SIZE) != FLI_HEADER_SIZE) return 0; /* validate the file */ this->magic_number = _X_LE_16(&this->fli_header[4]); if ((this->magic_number != FLI_FILE_MAGIC_1) && (this->magic_number != FLI_FILE_MAGIC_2)) return 0; /* file is qualified; skip over the signature bytes in the stream */ if (this->input->seek(this->input, FLI_HEADER_SIZE, SEEK_SET) != FLI_HEADER_SIZE) return 0; /* check if this is a special FLI file from Magic Carpet game */ if (_X_LE_16(&this->fli_header[16]) == FLI_CHUNK_MAGIC_1) { /* if the input is non-seekable, do not bother with playing the * special file type */ if (!INPUT_IS_SEEKABLE(this->input)) return 0; if (this->input->seek(this->input, FLI_HEADER_SIZE_MC, SEEK_SET) < 0) return 0; /* use a contrived internal FLI type, 0xAF13 */ this->magic_number = FLI_FILE_MAGIC_3; } this->frame_count = _X_LE_16(&this->fli_header[6]); this->bih.biWidth = _X_LE_16(&this->fli_header[8]); this->bih.biHeight = _X_LE_16(&this->fli_header[10]); this->speed = _X_LE_32(&this->fli_header[16]); if (this->magic_number == FLI_FILE_MAGIC_1) { /* * in this case, the speed (n) is number of 1/70s ticks between frames: * * xine pts n * frame # * -------- = ----------- => xine pts = n * (90000/70) * frame # * 90000 70 * * therefore, the frame pts increment = n * 1285.7 */ this->frame_pts_inc = this->speed * 1285.7; } else if (this->magic_number == FLI_FILE_MAGIC_2) { /* * in this case, the speed (n) is number of milliseconds between frames: * * xine pts n * frame # * -------- = ----------- => xine pts = n * 90 * frame # * 90000 1000 * * therefore, the frame pts increment = n * 90 */ this->frame_pts_inc = this->speed * 90; } else { /* special case for Magic Carpet FLIs which don't carry speed info */ this->frame_pts_inc = FLI_MC_PTS_INC; } /* sanity check: the FLI file must have non-zero values for width, height, * and frame count */ if ((!this->bih.biWidth) || (!this->bih.biHeight) || (!this->frame_count)) return 0; if (this->magic_number == FLI_FILE_MAGIC_3) this->bih.biSize = sizeof(xine_bmiheader) + FLI_HEADER_SIZE_MC; else this->bih.biSize = sizeof(xine_bmiheader) + FLI_HEADER_SIZE; return 1; } static int demux_fli_send_chunk(demux_plugin_t *this_gen) { demux_fli_t *this = (demux_fli_t *) this_gen; buf_element_t *buf = NULL; unsigned char fli_buf[6]; unsigned int chunk_size; unsigned int chunk_magic; off_t current_file_pos; current_file_pos = this->input->get_current_pos(this->input); /* get the chunk size nd magic number */ if (this->input->read(this->input, fli_buf, 6) != 6) { this->status = DEMUX_FINISHED; return this->status; } chunk_size = _X_LE_32(&fli_buf[0]); chunk_magic = _X_LE_16(&fli_buf[4]); if ((chunk_magic == FLI_CHUNK_MAGIC_1) || (chunk_magic == FLI_CHUNK_MAGIC_2)) { /* send a buffer with only the chunk header */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_FLI; if( this->stream_len ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->stream_len); buf->extra_info->input_time = this->pts_counter / 90; buf->pts = this->pts_counter; buf->size = 6; memcpy(buf->content, fli_buf, 6); this->video_fifo->put(this->video_fifo, buf); chunk_size -= 6; while (chunk_size) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_FLI; if( this->stream_len ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->stream_len); buf->extra_info->input_time = this->pts_counter / 90; buf->pts = this->pts_counter; if ((int)chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put(this->video_fifo, buf); } this->pts_counter += this->frame_pts_inc; } else { if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; } } return this->status; } static void demux_fli_send_headers(demux_plugin_t *this_gen) { demux_fli_t *this = (demux_fli_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->frame_pts_inc); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to FLI decoder */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->frame_pts_inc; /* initial video_step */ buf->size = this->bih.biSize; memcpy(buf->content, &this->bih, this->bih.biSize); buf->type = BUF_VIDEO_FLI; this->video_fifo->put (this->video_fifo, buf); } static int demux_fli_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_fli_t *this = (demux_fli_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; this->stream_len = this->input->get_length(this->input); this->pts_counter = 0; } return this->status; } static int demux_fli_get_status (demux_plugin_t *this_gen) { demux_fli_t *this = (demux_fli_t *) this_gen; return this->status; } static int demux_fli_get_stream_length (demux_plugin_t *this_gen) { demux_fli_t *this = (demux_fli_t *) this_gen; int64_t end_pts; end_pts = this->frame_count; end_pts *= this->frame_pts_inc; end_pts /= 90; return (int)end_pts; } static uint32_t demux_fli_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_fli_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_fli_t *this; this = calloc(1, sizeof(demux_fli_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_fli_send_headers; this->demux_plugin.send_chunk = demux_fli_send_chunk; this->demux_plugin.seek = demux_fli_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_fli_get_status; this->demux_plugin.get_stream_length = demux_fli_get_stream_length; this->demux_plugin.get_capabilities = demux_fli_get_capabilities; this->demux_plugin.get_optional_data = demux_fli_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_fli_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } static void *init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_fli_class = { .open_plugin = open_plugin, .description = N_("Autodesk Animator FLI/FLC demux plugin"), .identifier = "FLI/FLC", .mimetypes = "video/x-flic: fli,flc: Autodesk FLIC files;", .extensions = "fli flc", .dispose = NULL, }; return (void *)&demux_fli_class; } /* * exported plugin catalog entry */ static const demuxer_info_t demux_info_fli = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "fli", XINE_VERSION_CODE, &demux_info_fli, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_vc1es.c0000644000175000017500000002255714647725152015711 0ustar meme/* * Copyright (C) 2008-2018 the xine project * Copyright (C) 2008 Christophe Thommeret * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demultiplexer for wmv9/vc1 elementary streams * * * SMP (.rcv) format: * * ** header *** * le24 number of frames * C5 04 00 00 00 * 4 bytes sequence header * le32 height * le32 width * 0C 00 00 00 * 8 bytes unknown * le32 fps * ************ * le24 frame_size * 80 * le32 pts (ms) * frame_size bytes of picture data */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include /* #define LOG */ #define LOG_MODULE "demux_vc1es" #define LOG_VERBOSE #include "group_video.h" #include #include #include #include #include "bswap.h" #define SCRATCH_SIZE 36 #define PRIVATE_SIZE 44 #define MODE_SMP 1 #define MODE_AP 2 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int mode; uint8_t private[PRIVATE_SIZE]; uint32_t video_step; uint32_t blocksize; } demux_vc1_es_t ; static int demux_vc1_es_next_smp( demux_vc1_es_t *this ) { buf_element_t *buf; uint32_t pts=0, frame_size=0; off_t done; uint8_t head[SCRATCH_SIZE]; int start_flag = 1; if (this->input->read( this->input, head, 8 ) != 8) return 0; frame_size = _X_LE_24( head ); pts = _X_LE_32( head+4 ); while ( frame_size>0 ) { buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); off_t read = ((int)frame_size > buf->max_size) ? buf->max_size : (int)frame_size; done = this->input->read( this->input, buf->mem, read ); if ( done<=0 ) { buf->free_buffer( buf ); return 0; } buf->size = done; buf->content = buf->mem; buf->type = BUF_VIDEO_WMV9; buf->pts = pts*90; frame_size -= done; if ( start_flag ) { buf->decoder_flags = BUF_FLAG_FRAME_START; start_flag = 0; } if ( !(frame_size>0) ) buf->decoder_flags = BUF_FLAG_FRAME_END; this->video_fifo->put(this->video_fifo, buf); } return 1; } static int demux_vc1_es_next_ap( demux_vc1_es_t *this ) { buf_element_t *buf; uint32_t blocksize; off_t done; buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); blocksize = (this->blocksize ? this->blocksize : (uint32_t)buf->max_size); done = this->input->read(this->input, buf->mem, blocksize); if (done <= 0) { buf->free_buffer (buf); return 0; } buf->size = done; buf->content = buf->mem; buf->pts = 0; buf->type = BUF_VIDEO_VC1; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double)this->input->get_current_pos( this->input )*65535/this->input->get_length( this->input ) ); this->video_fifo->put(this->video_fifo, buf); return 1; } static int demux_vc1_es_send_chunk( demux_plugin_t *this_gen ) { demux_vc1_es_t *this = (demux_vc1_es_t *) this_gen; if ( this->mode==MODE_SMP ) { if (!demux_vc1_es_next_smp(this)) this->status = DEMUX_FINISHED; return this->status; } if (!demux_vc1_es_next_ap(this)) this->status = DEMUX_FINISHED; return this->status; } static int demux_vc1_es_get_status( demux_plugin_t *this_gen ) { demux_vc1_es_t *this = (demux_vc1_es_t *) this_gen; return this->status; } static void demux_vc1_es_send_headers( demux_plugin_t *this_gen ) { demux_vc1_es_t *this = (demux_vc1_es_t *) this_gen; this->video_fifo = this->stream->video_fifo; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_demux_control_start(this->stream); this->blocksize = this->input->get_blocksize(this->input); this->status = DEMUX_OK; if ( this->mode==MODE_SMP ) { buf_element_t *buf; buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); xine_fast_memcpy( buf->mem, this->private, PRIVATE_SIZE ); buf->size = PRIVATE_SIZE; buf->content = buf->mem; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; if ( this->video_step ) { buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = 90000/this->video_step; } buf->type = BUF_VIDEO_WMV9; this->video_fifo->put(this->video_fifo, buf); } } static int demux_vc1_es_seek( demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing ) { demux_vc1_es_t *this = (demux_vc1_es_t *) this_gen; (void)start_time; if ( this->mode==MODE_SMP ) { this->status = DEMUX_OK; return this->status; } start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); this->status = DEMUX_OK; if (playing) _x_demux_flush_engine(this->stream); if (INPUT_IS_SEEKABLE(this->input)) { /* FIXME: implement time seek */ if (start_pos != this->input->seek (this->input, start_pos, SEEK_SET)) { this->status = DEMUX_FINISHED; return this->status; } lprintf ("seeking to %"PRId64"\n", start_pos); } /* * now start demuxing */ this->status = DEMUX_OK; return this->status; } static void demux_vc1_es_dispose( demux_plugin_t *this ) { free (this); } static int demux_vc1_es_get_stream_length( demux_plugin_t *this_gen ) { (void)this_gen; return 0 ; /*FIXME: implement */ } static uint32_t demux_vc1_es_get_capabilities( demux_plugin_t *this_gen ) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_vc1_es_get_optional_data( demux_plugin_t *this_gen, void *data, int data_type ) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin( demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input ) { demux_vc1_es_t *this; uint8_t scratch[SCRATCH_SIZE]; int i, read, found=0; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { read = _x_demux_read_header(input, scratch, SCRATCH_SIZE); if (!read) return NULL; lprintf("read size =%d\n",read); /* simple and main profiles */ if ( read>=SCRATCH_SIZE ) { lprintf("searching for rcv format..\n"); if ( scratch[3]==0xc5 && scratch[4]==4 && scratch[5]==0 && scratch[6]==0 && scratch[7]==0 && scratch[20]==0x0c && scratch[21]==0 && scratch[22]==0 && scratch[23]==0 ) { lprintf("rcv format found\n"); found = MODE_SMP; } } if ( found==0 ) { /* advanced profile */ for (i = 0; i < read-4; i++) { lprintf ("%02x %02x %02x %02x\n", scratch[i], scratch[i+1], scratch[i+2], scratch[i+3]); if ((scratch[i] == 0x00) && (scratch[i+1] == 0x00) && (scratch[i+2] == 0x01)) { if (scratch[i+3] == 0x0f) { found = MODE_AP; lprintf ("found header at offset 0x%x\n", i); break; } } } } if (found == 0) return NULL; lprintf ("input accepted.\n"); } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } if ( input->seek( input, SCRATCH_SIZE, SEEK_SET ) != SCRATCH_SIZE ) return NULL; this = calloc(1, sizeof(demux_vc1_es_t)); if (!this) return NULL; this->mode = found; if ( found==MODE_SMP ) { xine_fast_memcpy( this->private+8, scratch+12, 4 ); /* height */ xine_fast_memcpy( this->private+4, scratch+16, 4 ); /* width */ xine_fast_memcpy( this->private+40, scratch+8, 4 ); /* sequence header */ this->video_step = _X_LE_32( scratch+32 ); } this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_vc1_es_send_headers; this->demux_plugin.send_chunk = demux_vc1_es_send_chunk; this->demux_plugin.seek = demux_vc1_es_seek; this->demux_plugin.dispose = demux_vc1_es_dispose; this->demux_plugin.get_status = demux_vc1_es_get_status; this->demux_plugin.get_stream_length = demux_vc1_es_get_stream_length; this->demux_plugin.get_capabilities = demux_vc1_es_get_capabilities; this->demux_plugin.get_optional_data = demux_vc1_es_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } void *demux_vc1es_init_class ( xine_t *xine, const void *data ) { (void)xine; (void)data; static const demux_class_t demux_vc1es_class = { .open_plugin = open_plugin, .description = N_("VC1 elementary stream demux plugin"), .identifier = "VC1_ES", .mimetypes = NULL, .extensions = "", .dispose = NULL, }; return (void *)&demux_vc1es_class; } xine-lib-1.2/src/demuxers/demux_roq.c0000644000175000017500000003474014647725152015466 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * RoQ File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the RoQ file format, visit: * http://www.csse.monash.edu.au/~timf/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_roq" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" #define RoQ_CHUNK_PREAMBLE_SIZE 8 #define RoQ_AUDIO_SAMPLE_RATE 22050 #define RoQ_INFO 0x1001 #define RoQ_QUAD_CODEBOOK 0x1002 #define RoQ_QUAD_VQ 0x1011 #define RoQ_SOUND_MONO 0x1020 #define RoQ_SOUND_STEREO 0x1021 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; unsigned int frame_pts_inc; xine_bmiheader bih; xine_waveformatex wave; int64_t video_pts_counter; unsigned int audio_byte_count; } demux_roq_t ; /* returns 1 if the RoQ file was opened successfully, 0 otherwise */ static int open_roq_file(demux_roq_t *this) { char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; int i; unsigned int chunk_type; unsigned int chunk_size; unsigned int fps; if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) return 0; /* check for the RoQ magic numbers */ static const uint8_t RoQ_MAGIC_STRING[] = { 0x10, 0x84, 0xFF, 0xFF, 0xFF, 0xFF }; if( memcmp(preamble, RoQ_MAGIC_STRING, sizeof(RoQ_MAGIC_STRING)) != 0 ) return 0; this->bih.biSize = sizeof(xine_bmiheader); this->bih.biWidth = this->bih.biHeight = 0; this->wave.nChannels = 0; /* assume no audio at first */ /* * RoQ files enjoy a constant framerate; pts calculation: * * xine pts frame # * -------- = ------- => xine pts = 90000 * frame # / fps * 90000 fps * * therefore, the frame pts increment is 90000 / fps */ fps = _X_LE_16(&preamble[6]); this->frame_pts_inc = 90000 / fps; /* iterate through the first 2 seconds worth of chunks searching for * the RoQ_INFO chunk and an audio chunk */ i = fps * 2; while (i-- > 0) { /* if this read fails, then maybe it's just a really small RoQ file * (even less than 2 seconds) */ if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) break; chunk_type = _X_LE_16(&preamble[0]); chunk_size = _X_LE_32(&preamble[2]); if (chunk_type == RoQ_INFO) { /* fetch the width and height; reuse the preamble bytes */ if (this->input->read(this->input, preamble, 8) != 8) break; this->bih.biWidth = _X_LE_16(&preamble[0]); this->bih.biHeight = _X_LE_16(&preamble[2]); /* if an audio chunk was already found, search is done */ if (this->wave.nChannels) break; /* prep the size for a seek */ chunk_size -= 8; } else { /* if it was an audio chunk and the info chunk has already been * found (as indicated by width and height) then break */ if (chunk_type == RoQ_SOUND_MONO) { this->wave.nChannels = 1; if (this->bih.biWidth && this->bih.biHeight) break; } else if (chunk_type == RoQ_SOUND_STEREO) { this->wave.nChannels = 2; if (this->bih.biWidth && this->bih.biHeight) break; } } /* skip the rest of the chunk */ if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) break; } /* after all is said and done, if there is a width and a height, * regard it as being a valid file and reset to the first chunk */ if (this->bih.biWidth && this->bih.biHeight) { if (this->input->seek(this->input, 8, SEEK_SET) != 8) return 0; } else { return 0; } this->video_pts_counter = this->audio_byte_count = 0; return 1; } static int demux_roq_send_chunk(demux_plugin_t *this_gen) { demux_roq_t *this = (demux_roq_t *) this_gen; buf_element_t *buf = NULL; char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; unsigned int chunk_type; unsigned int chunk_size; int64_t audio_pts; off_t current_file_pos; /* fetch the next preamble */ if (this->input->read(this->input, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } chunk_type = _X_LE_16(&preamble[0]); chunk_size = _X_LE_32(&preamble[2]); /* if the chunk is an audio chunk, route it to the audio fifo */ if ((chunk_type == RoQ_SOUND_MONO) || (chunk_type == RoQ_SOUND_STEREO)) { if( this->audio_fifo ) { /* do this calculation carefully because I can't trust the * 64-bit numerical manipulation */ audio_pts = this->audio_byte_count; audio_pts *= 90000; audio_pts /= (RoQ_AUDIO_SAMPLE_RATE * this->wave.nChannels); this->audio_byte_count += chunk_size - 8; /* do not count the preamble */ current_file_pos = this->input->get_current_pos(this->input); /* send out the preamble */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_ROQ; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) (current_file_pos - RoQ_CHUNK_PREAMBLE_SIZE) * 65535 / this->input->get_length (this->input) ); buf->pts = 0; buf->size = RoQ_CHUNK_PREAMBLE_SIZE; memcpy(buf->content, preamble, RoQ_CHUNK_PREAMBLE_SIZE); this->audio_fifo->put(this->audio_fifo, buf); /* packetize the audio */ while (chunk_size) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_ROQ; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->input->get_length (this->input) ); buf->pts = audio_pts; if ((int)chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put(this->audio_fifo, buf); } } else { /* no audio -> skip chunk */ this->input->seek(this->input, chunk_size, SEEK_CUR); } } else if (chunk_type == RoQ_INFO) { /* skip 8 bytes */ this->input->seek(this->input, chunk_size, SEEK_CUR); } else if ((chunk_type == RoQ_QUAD_CODEBOOK) || (chunk_type == RoQ_QUAD_VQ)) { current_file_pos = this->input->get_current_pos(this->input); /* send out the preamble */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_ROQ; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) (current_file_pos - RoQ_CHUNK_PREAMBLE_SIZE) * 65535 / this->input->get_length (this->input) ); buf->pts = this->video_pts_counter; buf->size = RoQ_CHUNK_PREAMBLE_SIZE; memcpy(buf->content, preamble, RoQ_CHUNK_PREAMBLE_SIZE); this->video_fifo->put(this->video_fifo, buf); while (chunk_size) { buf = this->video_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_VIDEO_ROQ; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->input->get_length (this->input) ); buf->pts = this->video_pts_counter; if ((int)chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } /* only indicate end of video frame if this is a VQ chunk */ if (!chunk_size && (chunk_type == RoQ_QUAD_VQ)) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put(this->video_fifo, buf); } /* only advance pts counter on VQ frames */ if (chunk_type == RoQ_QUAD_VQ) this->video_pts_counter += this->frame_pts_inc; } else { lprintf("encountered bad chunk type: %d\n", chunk_type); } return this->status; } static void demux_roq_send_headers(demux_plugin_t *this_gen) { demux_roq_t *this = (demux_roq_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->wave.nChannels) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->wave.nChannels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, RoQ_AUDIO_SAMPLE_RATE); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, 16); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->frame_pts_inc; /* initial video_step */ buf->size = sizeof(xine_bmiheader); memcpy(buf->content, &this->bih, buf->size); buf->type = BUF_VIDEO_ROQ; this->video_fifo->put (this->video_fifo, buf); if (this->audio_fifo && this->wave.nChannels) { this->wave.nSamplesPerSec = RoQ_AUDIO_SAMPLE_RATE; this->wave.wBitsPerSample = 16; this->wave.nBlockAlign = (this->wave.wBitsPerSample / 8) * this->wave.nChannels; this->wave.nAvgBytesPerSec = this->wave.nBlockAlign * this->wave.nSamplesPerSec; buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_ROQ; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = RoQ_AUDIO_SAMPLE_RATE; buf->decoder_info[2] = 16; buf->decoder_info[3] = this->wave.nChannels; buf->size = sizeof(this->wave); memcpy(buf->content, &this->wave, buf->size); this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_roq_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_roq_t *this = (demux_roq_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; /* start after the signature chunk */ this->input->seek(this->input, RoQ_CHUNK_PREAMBLE_SIZE, SEEK_SET); this->status = DEMUX_OK; } return this->status; } static int demux_roq_get_status (demux_plugin_t *this_gen) { demux_roq_t *this = (demux_roq_t *) this_gen; return this->status; } static int demux_roq_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_roq_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_roq_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_roq_t *this; if (!INPUT_IS_SEEKABLE(input)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input not seekable, can not handle!\n"); return NULL; } this = calloc(1, sizeof(demux_roq_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_roq_send_headers; this->demux_plugin.send_chunk = demux_roq_send_chunk; this->demux_plugin.seek = demux_roq_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_roq_get_status; this->demux_plugin.get_stream_length = demux_roq_get_stream_length; this->demux_plugin.get_capabilities = demux_roq_get_capabilities; this->demux_plugin.get_optional_data = demux_roq_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_roq_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_roq_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_roq_class = { .open_plugin = open_plugin, .description = N_("Id RoQ file demux plugin"), .identifier = "RoQ", .mimetypes = NULL, .extensions = "roq", .dispose = NULL, }; return (void *)&demux_roq_class; } xine-lib-1.2/src/demuxers/demux_iff.c0000644000175000017500000015101714647725152015426 0ustar meme/* * Copyright (C) 2004-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * IFF File Demuxer by Manfred Tremmel (Manfred.Tremmel@iiv.de) * Based on the AIFF demuxer and the information of the Amiga Developer CD * * currently supported iff-formats: * * 8SVX (uncompressed, deltacompression fibonacci and exponential) * + volume rescaling is supported * + multiple channels using CHAN and PAN Chunks are supported * - SEQN and FADE chunks are not supported at the moment * (I do understand what to do, but I hate the work behind it ;-) ) * - the optional data chunks ATAK and RLSE are not supported at the moment * (no examples found and description isn't as clear as it should) * * 16SV, the same support as 8SVX * * ILBM (Bitmap Picturs) * - simple pictures work, nothing more (most work is done in bitmap-decoder) * * ANIM (Animations) * - Animation works fine, without seeking. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_iff" #include "group_video.h" #include #include #include #include #include "bswap.h" #include "iff.h" typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; xine_bmiheader bih; int status; uint32_t iff_type; /* Type of iff-file */ uint32_t iff_sub_type; /* Type of iff-sub-file */ /* Sound chunks */ Voice8Header *vhdr; /* vhdr chunk */ EGPoint *atak; /* atak chunk */ EGPoint *rlse; /* rlse chunk */ uint32_t chan_settings; /* Mono, Stereo, Left or Right Channel */ uint32_t pan_sposition; /* */ /* picture chunks */ BitMapHeader *bmhd; /* BITMAP-Header-Date (IFF-ILBM/ANIM */ ColorRegister *cmap; /* colors of the bitmap picture */ uint32_t cmap_num; /* number of the bitmap colors */ Point2D *grab; /* grab chunk */ DestMerge *dest; /* dest chunk */ SpritePrecedence sprt; /* sprt chunk */ CamgChunk *camg; /* camg chunk */ CRange crng[256]; /* color range infos for color cycling */ uint32_t crng_used; /* number of color range fields used */ CcrtChunk *ccrt; /* ccrt chunk */ DPIHeader *dpi; /* dpi chunk */ /* anim chunks */ AnimHeader *anhd; /* anhd chunk */ DPAnimChunk *dpan; /* dpan chunk */ /* some common informations */ char *title; /* Name of the stream from NAME-Tag*/ char *copyright; /* Copyright entry */ char *author; /* author entry */ char *annotations; /* comment of the author, maybe authoring tool */ char *version; /* version information of the file */ char *text; /* anny other text information */ /* audio information */ unsigned int audio_type; unsigned int audio_frames; unsigned int audio_bits; unsigned int audio_channels; unsigned int audio_block_align; unsigned int audio_bytes_per_second; unsigned char *audio_interleave_buffer; uint32_t audio_interleave_buffer_size; unsigned char *audio_read_buffer; uint32_t audio_read_buffer_size; int audio_buffer_filled; uint32_t audio_volume_left; uint32_t audio_volume_right; uint32_t audio_position; int audio_compression_factor; /* picture information */ int video_send_palette; unsigned int video_type; int64_t video_pts; int64_t video_pts_inc; unsigned int running_time; off_t data_start; off_t data_size; } demux_iff_t; /* Decode delta encoded data from n byte source * buffer into double as long dest buffer, given initial data * value x. The value x is also returned for incrementally * decompression. With different decoding tables you can use * different decoding deltas */ static int8_t delta_decode_block(const int8_t *source, int32_t n, int8_t *dest, int8_t x, const int8_t *table) { int32_t i; int lim = n * 2; for (i=0; i < lim; i++) { /* Decode a data nibble, high nibble then low nibble */ x += (i & 1) ? table[((uint8_t)(source[i >> 1]) & 0xf)] : table[((uint8_t)(source[i >> 1]) >> 4)]; dest[i] = x; /* store a 1 byte sample */ } return(x); } /* Decode a complete delta encoded array */ static void delta_decode(int8_t *dest, const int8_t *source, int32_t n, const int8_t *table){ delta_decode_block(&source[2], n-2, dest, source[1], table); } /* returns 1 if the IFF file was opened successfully, 0 otherwise */ static int read_iff_chunk(demux_iff_t *this) { unsigned char signature[IFF_SIGNATURE_SIZE]; unsigned char buffer[512]; unsigned int keep_on_reading = 1; uint32_t junk_size, junk_type; while ( keep_on_reading == 1 ) { if (this->input->read(this->input, signature, IFF_JUNK_SIZE) == IFF_JUNK_SIZE) { if( signature[0] == 0 && signature[1] > 0 ) { signature[0] = signature[1]; signature[1] = signature[2]; signature[2] = signature[3]; signature[3] = signature[4]; signature[4] = signature[5]; signature[5] = signature[6]; signature[6] = signature[7]; if (this->input->read(this->input, &signature[7], 1) != 1) return 0; } junk_type = _X_BE_32(&signature[0]); junk_size = _X_BE_32(&signature[4]); switch (junk_type) { case IFF_CMAP_CHUNK: case IFF_BODY_CHUNK: case IFF_DLTA_CHUNK: case IFF_FORM_CHUNK: /* don't read this chunks, will be done later */ break; default: if ( junk_size < 512 ) { if (this->input->read(this->input, buffer, junk_size) != junk_size) return 0; } else { this->input->seek(this->input, junk_size, SEEK_SET); buffer[0] = 0; } break; } switch (junk_type) { case IFF_FORM_CHUNK: if (this->input->read(this->input, buffer, 4) != 4) return 0; this->iff_sub_type = _X_BE_32(&buffer[0]); break; case IFF_VHDR_CHUNK: if( this->vhdr == NULL ) this->vhdr = (Voice8Header *)calloc(1, sizeof(Voice8Header)); this->vhdr->oneShotHiSamples = _X_BE_32(&buffer[0]); this->vhdr->repeatHiSamples = _X_BE_32(&buffer[4]); this->vhdr->samplesPerHiCycle = _X_BE_32(&buffer[8]); this->vhdr->samplesPerSec = _X_BE_16(&buffer[12]); this->vhdr->ctOctave = buffer[14]; this->vhdr->sCompression = buffer[15]; this->audio_channels = 1; this->chan_settings = MONO; switch( this->vhdr->sCompression ) { case SND_COMPRESSION_NONE: /* uncompressed */ case SND_COMPRESSION_FIBONACCI: /* Fibonacci */ case SND_COMPRESSION_EXPONENTIAL: /* Exponential*/ this->audio_block_align = PCM_BLOCK_ALIGN; this->audio_type = BUF_AUDIO_LPCM_BE; break; default: /* unknown codec */ xine_log(this->stream->xine, XINE_LOG_MSG, _("iff-8svx/16sv: unknown compression: %d\n"), this->vhdr->sCompression); return 0; break; } this->vhdr->volume = _X_BE_32(&buffer[16]); if (this->vhdr->volume > max_volume) this->vhdr->volume = max_volume; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->oneShotHiSamples %d\n", this->vhdr->oneShotHiSamples); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->repeatHiSamples %d\n", this->vhdr->repeatHiSamples); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->samplesPerHiCycle %d\n", this->vhdr->samplesPerHiCycle); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->samplesPerSec %d\n", this->vhdr->samplesPerSec); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->ctOctave %d\n", this->vhdr->ctOctave); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->sCompression %d\n", this->vhdr->sCompression); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "vhdr->volume %d\n", this->vhdr->volume); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "chan_settings %d\n", this->chan_settings); break; case IFF_NAME_CHUNK: if (this->title == NULL) this->title = strndup( (const char *)buffer, (size_t)junk_size); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "title %s\n", this->title); break; case IFF_COPY_CHUNK: if (this->copyright == NULL) this->copyright = strndup( (const char *)buffer, (size_t)junk_size); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "copyright %s\n", this->copyright); break; case IFF_AUTH_CHUNK: if (this->author == NULL) this->author = strndup( (const char *)buffer, (size_t)junk_size); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "author %s\n", this->author); break; case IFF_ANNO_CHUNK: if (this->annotations == NULL) this->annotations = strndup( (const char *)buffer, (size_t)junk_size); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "annotations %s\n", this->annotations); break; case IFF_FVER_CHUNK: if (this->version == NULL) this->version = strndup( (const char *)buffer, (size_t)junk_size); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "version %s\n", this->version); break; case IFF_TEXT_CHUNK: if (this->text == NULL) this->text = strndup( (const char *)buffer, (size_t)junk_size); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "text %s\n", this->text); break; case IFF_ATAK_CHUNK: /* not yet implemented */ break; case IFF_RLSE_CHUNK: /* not yet implemented */ break; case IFF_CHAN_CHUNK: if (!this->vhdr) break; this->chan_settings = _X_BE_32(&buffer[0]); switch( this->chan_settings ) { case STEREO: this->audio_volume_left = this->vhdr->volume; this->audio_volume_right = this->vhdr->volume; this->audio_channels = 2; break; case LEFT: this->audio_volume_left = this->vhdr->volume; this->audio_volume_right = 0; this->audio_channels = 2; break; case RIGHT: this->audio_volume_left = 0; this->audio_volume_right = this->vhdr->volume; this->audio_channels = 2; break; default: this->chan_settings = MONO; this->audio_channels = 1; break; } break; case IFF_PAN_CHUNK: if (!this->vhdr) break; this->chan_settings = PAN; this->pan_sposition = _X_BE_32(&buffer[0]); this->audio_channels = 2; this->audio_volume_left = this->vhdr->volume / (max_volume / this->pan_sposition); this->audio_volume_right = this->vhdr->volume - this->audio_volume_left; break; case IFF_BMHD_CHUNK: if( this->bmhd == NULL ) this->bmhd = (BitMapHeader *)calloc(1, sizeof(BitMapHeader)); if( this->bmhd == NULL ) break; this->bmhd->w = _X_BE_16(&buffer[0]); this->bmhd->h = _X_BE_16(&buffer[2]); this->bmhd->x = _X_BE_16(&buffer[4]); this->bmhd->y = _X_BE_16(&buffer[6]); this->bmhd->nplanes = buffer[8]; this->bmhd->masking = buffer[9]; this->bmhd->compression = buffer[10]; this->bmhd->pad1 = buffer[11]; this->bmhd->transparentColor = _X_BE_16(&buffer[12]); this->bmhd->xaspect = buffer[14]; this->bmhd->yaspect = buffer[15]; this->bmhd->pagewidth = _X_BE_16(&buffer[16]); this->bmhd->pageheight = _X_BE_16(&buffer[18]); if (this->bmhd->w > 0) this->bih.biWidth = this->bmhd->w; else this->bih.biWidth = this->bmhd->pagewidth; if (this->bmhd->h > 0) this->bih.biHeight = this->bmhd->h; else this->bih.biHeight = this->bmhd->pageheight; this->bih.biPlanes = this->bmhd->nplanes; this->bih.biBitCount = this->bmhd->nplanes; switch( this->bmhd->compression ) { case PIC_COMPRESSION_NONE: /* uncompressed */ this->video_type = BUF_VIDEO_BITPLANE; break; case PIC_COMPRESSION_BYTERUN1: this->video_type = BUF_VIDEO_BITPLANE_BR1; break; default: xine_log(this->stream->xine, XINE_LOG_MSG, _("iff-ilbm: unknown compression: %d\n"), this->bmhd->compression); return 0; break; } xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->w %d\n", this->bmhd->w); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->h %d\n", this->bmhd->h); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->x %d\n", this->bmhd->x); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->y %d\n", this->bmhd->y); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->nplanes %d\n", this->bmhd->nplanes); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->masking %d\n", this->bmhd->masking); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->compression %d\n", this->bmhd->compression); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->pad1 %d\n", this->bmhd->pad1); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->transparentColor %d\n", this->bmhd->transparentColor); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->xaspect %d\n", this->bmhd->xaspect); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->yaspect %d\n", this->bmhd->yaspect); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->pagewidth %d\n", this->bmhd->pagewidth); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "bmhd->pageheight %d\n", this->bmhd->pageheight); break; case IFF_CMAP_CHUNK: /* every color contains red, green and blue componente using 8Bit */ this->cmap_num = junk_size / PIC_SIZE_OF_COLOR_REGISTER; this->cmap = (ColorRegister *)malloc(junk_size); this->video_send_palette = 1; if (!this->cmap || this->input->read(this->input, (char *)this->cmap, junk_size) != junk_size) return 0; break; case IFF_GRAB_CHUNK: if( this->grab == NULL ) this->grab = (Point2D *)calloc(1, sizeof(Point2D)); if( this->grab == NULL ) break; this->grab->x = _X_BE_16(&buffer[0]); this->grab->y = _X_BE_16(&buffer[2]); break; case IFF_DEST_CHUNK: if( this->dest == NULL ) this->dest = (DestMerge *)calloc(1, sizeof(DestMerge)); if( this->dest == NULL ) break; this->dest->depth = buffer[0]; this->dest->pad1 = buffer[1]; this->dest->plane_pick = _X_BE_16(&buffer[2]); this->dest->plane_onoff = _X_BE_16(&buffer[4]); this->dest->plane_mask = _X_BE_16(&buffer[6]); break; case IFF_SPRT_CHUNK: this->sprt = _X_BE_16(&buffer[0]); break; case IFF_CAMG_CHUNK: if( this->camg == NULL ) this->camg = (CamgChunk *)calloc(1, sizeof(CamgChunk)); if( this->camg == NULL ) break; this->camg->view_modes = _X_BE_32(&buffer[0]); this->bih.biCompression = this->camg->view_modes; if( this->camg->view_modes & CAMG_PAL && this->video_pts_inc == 4500 ) this->video_pts_inc = 5400; break; case IFF_CRNG_CHUNK: if (this->crng_used < 256) { this->crng[this->crng_used].pad1 = _X_BE_16(&buffer[0]); this->crng[this->crng_used].rate = _X_BE_16(&buffer[2]); this->crng[this->crng_used].active = _X_BE_16(&buffer[4]); this->crng[this->crng_used].low = buffer[6]; this->crng[this->crng_used].high = buffer[7]; this->crng_used++; } break; case IFF_CCRT_CHUNK: if( this->ccrt == NULL ) this->ccrt = (CcrtChunk *)calloc(1, sizeof(CcrtChunk)); if( this->ccrt == NULL ) break; this->ccrt->direction = _X_BE_16(&buffer[0]); this->ccrt->start = buffer[2]; this->ccrt->end = buffer[3]; this->ccrt->seconds = _X_BE_32(&buffer[4]); this->ccrt->microseconds = _X_BE_32(&buffer[8]); this->ccrt->pad = _X_BE_16(&buffer[12]); break; case IFF_DPI_CHUNK: if( this->dpi == NULL ) this->dpi = (DPIHeader *)calloc(1, sizeof(DPIHeader)); if( this->dpi == NULL ) break; this->dpi->x = _X_BE_16(&buffer[0]); this->dpi->y = _X_BE_16(&buffer[0]); break; case IFF_ANHD_CHUNK: if( this->anhd == NULL ) this->anhd = (AnimHeader *)calloc(1, sizeof(AnimHeader)); if( this->anhd == NULL ) break; this->anhd->operation = buffer[0]; this->anhd->mask = buffer[1]; this->anhd->w = _X_BE_16(&buffer[2]); this->anhd->h = _X_BE_16(&buffer[4]); this->anhd->x = _X_BE_16(&buffer[6]); this->anhd->y = _X_BE_16(&buffer[8]); this->anhd->abs_time = _X_BE_32(&buffer[10]); this->anhd->rel_time = _X_BE_32(&buffer[14]); this->anhd->interleave = buffer[18]; this->anhd->pad0 = buffer[19]; this->anhd->bits = _X_BE_32(&buffer[20]); /* Using rel_time deaktivated, seems to be broken in most animations */ /*if( this->dpan == NULL ) this->video_pts += this->video_pts_inc * ((this->anhd->rel_time > 0) ? this->anhd->rel_time : 1); else*/ this->video_pts += this->video_pts_inc; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->operation %d\n", this->anhd->operation); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->mask %d\n", this->anhd->mask); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->w %d\n", this->anhd->w); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->h %d\n", this->anhd->h); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->x %d\n", this->anhd->x); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->y %d\n", this->anhd->y); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->abs_time %d\n", this->anhd->abs_time); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->rel_time %d\n", this->anhd->rel_time); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->interleave %d\n", this->anhd->interleave); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "anhd->bits %d\n", this->anhd->bits); break; case IFF_DPAN_CHUNK: if( this->dpan == NULL ) this->dpan = (DPAnimChunk *)calloc(1, sizeof(DPAnimChunk)); if( this->dpan == NULL ) break; this->dpan->version = _X_BE_16(&buffer[0]); this->dpan->nframes = _X_BE_16(&buffer[2]); this->dpan->fps = buffer[4]; this->dpan->unused1 = buffer[5]; this->dpan->unused2 = buffer[6]; this->dpan->unused3 = buffer[7]; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "dpan->version %d\n", this->dpan->version); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "dpan->nframes %d\n", this->dpan->nframes); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "dpan->fps %d\n", this->dpan->fps); break; case IFF_DPPS_CHUNK: /* DPPS contains DeluxePaint specific information, no documentation available */ break; case IFF_JUNK_CHUNK: /* JUNK contains garbage and should be ignored */ break; case IFF_BODY_CHUNK: case IFF_DLTA_CHUNK: if (!this->vhdr) break; this->data_start = this->input->get_current_pos(this->input); this->data_size = junk_size; switch( this->iff_type ) { case IFF_8SVX_CHUNK: case IFF_16SV_CHUNK: if( this->vhdr->sCompression > SND_COMPRESSION_NONE ) { this->audio_interleave_buffer_size = this->data_size * 2; this->audio_read_buffer_size = this->data_size; } else { this->audio_interleave_buffer_size = this->data_size; this->audio_read_buffer_size = 0; } if( this->chan_settings == MONO) this->audio_volume_left = this->vhdr->volume; this->audio_bytes_per_second = this->audio_channels * (this->audio_bits / 8) * this->vhdr->samplesPerSec; if (this->audio_channels > 0 && this->vhdr->samplesPerSec > 0) this->running_time = ((this->vhdr->oneShotHiSamples + this->vhdr->repeatHiSamples) * 1000 / this->vhdr->samplesPerSec) / this->audio_channels; break; case IFF_ILBM_CHUNK: this->bih.biSize = this->data_size; this->bih.biSizeImage = this->data_size; break; case IFF_ANIM_CHUNK: this->bih.biSize = this->data_size; this->bih.biSizeImage = this->data_size; if( this->dpan ) { if( this->dpan->fps > 0 && this->dpan->fps <= 60) this->video_pts_inc = 90000 / this->dpan->fps; this->running_time = (this->video_pts_inc * this->dpan->nframes) / 90; } break; default: break; } keep_on_reading = 0; break; default: signature[4] = 0; xine_log(this->stream->xine, XINE_LOG_MSG, _("iff: unknown Chunk: %s\n"), signature); break; } } else return 0; } return 1; } /* returns 1 if the IFF file was opened successfully, 0 otherwise */ static int open_iff_file(demux_iff_t *this) { unsigned char signature[IFF_SIGNATURE_SIZE]; if (_x_demux_read_header(this->input, signature, IFF_SIGNATURE_SIZE) != IFF_SIGNATURE_SIZE) return 0; this->title = NULL; this->copyright = NULL; this->author = NULL; this->annotations = NULL; this->version = NULL; this->text = NULL; this->vhdr = NULL; this->atak = NULL; this->rlse = NULL; this->chan_settings = 0; this->audio_type = 0; this->audio_frames = 0; this->audio_bits = 0; this->audio_channels = 0; this->audio_block_align = 0; this->audio_bytes_per_second = 0; this->running_time = 0; this->data_start = 0; this->data_size = 0; this->audio_interleave_buffer = 0; this->audio_interleave_buffer_size = 0; this->audio_read_buffer = 0; this->audio_read_buffer_size = 0; this->audio_buffer_filled = 0; this->audio_compression_factor = 1; this->audio_position = 0; this->bmhd = NULL; this->cmap = NULL; this->cmap_num = 0; this->grab = NULL; this->dest = NULL; this->sprt = 0; this->camg = NULL; this->crng_used = 0; this->ccrt = NULL; this->dpi = NULL; this->anhd = NULL; this->dpan = NULL; this->iff_type = _X_BE_32(&signature[8]); this->iff_sub_type = this->iff_type; this->video_type = 0; this->video_pts = 0; this->video_pts_inc = 0; this->video_send_palette = 0; this->bih.biSize = 0; this->bih.biWidth = 0; this->bih.biHeight = 0; this->bih.biPlanes = 0; this->bih.biBitCount = 0; this->bih.biCompression = 0; this->bih.biSizeImage = 0; this->bih.biXPelsPerMeter = 0; this->bih.biYPelsPerMeter = 0; this->bih.biClrUsed = 0; this->bih.biClrImportant = 0; /* check the signature */ if (_X_BE_32(&signature[0]) == IFF_FORM_CHUNK) { switch( this->iff_type ) { case IFF_8SVX_CHUNK: this->audio_bits = 8; break; case IFF_16SV_CHUNK: this->audio_bits = 16; break; case IFF_ILBM_CHUNK: this->video_pts_inc = 10000000; break; case IFF_ANIM_CHUNK: this->video_pts_inc = 4500; break; default: return 0; break; } } else return 0; /* file is qualified; skip over the header bytes in the stream */ if (this->input->seek(this->input, IFF_SIGNATURE_SIZE, SEEK_SET) != IFF_SIGNATURE_SIZE) return 0; return read_iff_chunk( this ); } static int demux_iff_send_chunk(demux_plugin_t *this_gen) { demux_iff_t *this = (demux_iff_t *) this_gen; buf_element_t *buf = NULL; unsigned int remaining_sample_bytes = 0; off_t current_file_pos; int16_t *pointer16_from; int16_t *pointer16_to; int16_t zw_16; int32_t input_length; int64_t zw_pts; int64_t zw_rescale; int j, k; int interleave_index; int size; /* when audio is available and it's a stereo, left or right stream * at iff 8svx, the complete left stream at the beginning and the * right channel at the end of the stream. Both have to be inter- * leaved, the same way as in the sega film demuxer. I've copied * it out there */ switch( this->iff_sub_type ) { case IFF_8SVX_CHUNK: case IFF_16SV_CHUNK: /* just load data chunks from wherever the stream happens to be * pointing; issue a DEMUX_FINISHED status if EOF is reached */ current_file_pos = this->audio_position; /* load the whole chunk into the buffer */ if (this->audio_buffer_filled == 0) { if (this->audio_interleave_buffer_size > 0) { this->audio_interleave_buffer = calloc(1, this->audio_interleave_buffer_size); if (!this->audio_interleave_buffer) return this->status = DEMUX_FINISHED; } if (this->audio_read_buffer_size > 0) { this->audio_read_buffer = calloc(1, this->audio_read_buffer_size); if (!this->audio_read_buffer) return this->status = DEMUX_FINISHED; } if (this->audio_read_buffer) { if (this->input->read(this->input, this->audio_read_buffer, this->data_size) != this->data_size) { this->status = DEMUX_FINISHED; return this->status; } switch( this->vhdr->sCompression ) { case SND_COMPRESSION_FIBONACCI: if (this->chan_settings == STEREO) { delta_decode((int8_t *)(this->audio_interleave_buffer), (int8_t *)(this->audio_read_buffer), (this->data_size/2), fibonacci); delta_decode((int8_t *)(&(this->audio_interleave_buffer[this->data_size])), (int8_t *)(&(this->audio_read_buffer[(this->data_size/2)])), (this->data_size/2), fibonacci); } else delta_decode((int8_t *)(this->audio_interleave_buffer), (int8_t *)(this->audio_read_buffer), this->data_size, fibonacci); this->audio_compression_factor = 2; break; case SND_COMPRESSION_EXPONENTIAL: if (this->chan_settings == STEREO) { delta_decode((int8_t *)(this->audio_interleave_buffer), (int8_t *)(this->audio_read_buffer), (this->data_size/2), exponential); delta_decode((int8_t *)(&(this->audio_interleave_buffer[this->data_size])), (int8_t *)(&(this->audio_read_buffer[(this->data_size/2)])), (this->data_size/2), exponential); } else delta_decode((int8_t *)(this->audio_interleave_buffer), (int8_t *)(this->audio_read_buffer), this->data_size, exponential); this->audio_compression_factor = 2; break; default: break; } free( this->audio_read_buffer ); this->audio_read_buffer = NULL; } else { if (this->input->read(this->input, this->audio_interleave_buffer, this->data_size) != this->data_size) { this->status = DEMUX_FINISHED; return this->status; } } this->audio_buffer_filled = 1; } /* proceed to de-interleave into individual buffers */ if (this->chan_settings == STEREO) { remaining_sample_bytes = ((this->data_size - current_file_pos) * this->audio_compression_factor) / 2; interleave_index = (current_file_pos * this->audio_compression_factor) / 2; } else { remaining_sample_bytes = ((this->data_size - current_file_pos) * this->audio_compression_factor); interleave_index = (current_file_pos * this->audio_compression_factor); } zw_pts = current_file_pos; if (this->chan_settings == STEREO) input_length = this->data_size * this->audio_compression_factor; else input_length = this->data_size * this->audio_compression_factor * this->audio_channels; while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; if( input_length ) buf->extra_info->input_normpos = (int)((double)zw_pts * 65535 / input_length); buf->pts = zw_pts * 90000 / this->audio_bytes_per_second; buf->extra_info->input_time = buf->pts / 90; buf->extra_info->total_time = this->running_time; if (remaining_sample_bytes > buf->max_size / this->audio_channels) buf->size = buf->max_size; else buf->size = remaining_sample_bytes * this->audio_channels; remaining_sample_bytes -= buf->size / this->audio_channels; zw_pts += buf->size; /* 16 bit sound */ if (this->audio_bits == 16) { pointer16_from = (int16_t *)this->audio_interleave_buffer; pointer16_to = (int16_t *)buf->content; if (this->chan_settings == STEREO || this->chan_settings == LEFT || this->chan_settings == PAN || this->chan_settings == MONO) { if( this->audio_volume_left == max_volume ) { for (j = 0, k = (interleave_index / 2); j < (buf->size / 2); j += this->audio_channels) { pointer16_to[j] = pointer16_from[k++]; } } else { for (j = 0, k = (interleave_index / 2); j < (buf->size / 2); j += this->audio_channels) { zw_16 = _X_BE_16(&pointer16_from[k]); k++; zw_rescale = zw_16; zw_rescale *= this->audio_volume_left; zw_rescale /= max_volume; zw_16 = (zw_rescale>32767) ? 32767 : ((zw_rescale<-32768) ? -32768 : zw_rescale); pointer16_to[j] = _X_BE_16(&zw_16); } } } else { for (j = 0; j < (buf->size / 2); j += this->audio_channels) { pointer16_to[j] = 0; } } if (this->chan_settings == STEREO || this->chan_settings == RIGHT || this->chan_settings == PAN) { if (this->chan_settings == STEREO) k = (interleave_index + (this->data_size * this->audio_compression_factor / 2)) / 2; else k = interleave_index / 2; if( this->audio_volume_right == max_volume ) { for (j = 1; j < (buf->size / 2); j += this->audio_channels) { pointer16_to[j] = pointer16_from[k++]; } } else { for (j = 1; j < (buf->size / 2); j += this->audio_channels) { zw_16 = _X_BE_16(&pointer16_from[k]); k++; zw_rescale = zw_16; zw_rescale *= this->audio_volume_left; zw_rescale /= max_volume; zw_16 = (zw_rescale>32767) ? 32767 : ((zw_rescale<-32768) ? -32768 : zw_rescale); pointer16_to[j] = _X_BE_16(&zw_16); } } } else if (this->chan_settings == LEFT) { for (j = 1; j < (buf->size / 2); j += this->audio_channels) { pointer16_to[j] = 0; } } /* 8 bit sound */ } else { if (this->chan_settings == STEREO || this->chan_settings == LEFT || this->chan_settings == PAN || this->chan_settings == MONO) { if( this->audio_volume_left == max_volume ) { for (j = 0, k = interleave_index; j < buf->size; j += this->audio_channels) { buf->content[j] = this->audio_interleave_buffer[k++] + 0x80; } } else { for (j = 0, k = interleave_index; j < buf->size; j += this->audio_channels) { zw_rescale = this->audio_interleave_buffer[k++]; zw_rescale *= this->audio_volume_left; zw_rescale /= max_volume; zw_rescale += 0x80; buf->content[j] = (zw_rescale>255) ? 255 : ((zw_rescale<0) ? 0 : zw_rescale); } } } else { for (j = 0; j < buf->size; j += 2) { buf->content[j] = 0; } } if (this->chan_settings == STEREO || this->chan_settings == RIGHT || this->chan_settings == PAN) { if (this->chan_settings == STEREO) k = interleave_index + (this->data_size * this->audio_compression_factor / 2); else k = interleave_index; if( this->audio_volume_right == max_volume ) { for (j = 1; j < buf->size; j += this->audio_channels) { buf->content[j] = this->audio_interleave_buffer[k++] + 0x80; } } else { for (j = 1; j < buf->size; j += this->audio_channels) { zw_rescale = this->audio_interleave_buffer[k++]; zw_rescale *= this->audio_volume_right; zw_rescale /= max_volume; zw_rescale += 0x80; buf->content[j] = (zw_rescale>255) ? 255 : ((zw_rescale<0) ? 0 : zw_rescale); } } } else if (this->chan_settings == LEFT) { for (j = 1; j < buf->size; j += this->audio_channels) { buf->content[j] = 0; } } } interleave_index += buf->size / this->audio_channels; if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "sending audio buf with %" PRId32 " bytes, %" PRId64 " pts, %" PRId32 " duration\n", buf->size, buf->pts, buf->decoder_info[0]); this->audio_fifo->put(this->audio_fifo, buf); } break; case IFF_ILBM_CHUNK: /* send off the palette, if there is one */ if ( this->video_send_palette == 1 ) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = this->cmap_num; buf->decoder_info_ptr[2] = this->cmap; buf->size = 0; buf->type = this->video_type; this->video_fifo->put (this->video_fifo, buf); this->video_send_palette = 0; } /* And now let's start with the picture */ size = this->data_size; while (size > 0) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->content = buf->mem; buf->type = this->video_type; buf->decoder_flags = BUF_FLAG_FRAMERATE; if( this->anhd == NULL ) buf->decoder_info[0] = 0; else buf->decoder_info[0] = this->video_pts_inc; buf->decoder_info_ptr[0] = this->anhd; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); buf->pts = this->video_pts; buf->extra_info->input_time = buf->pts / 90; buf->extra_info->total_time = this->running_time; if (size > buf->max_size) { buf->size = buf->max_size; } else { buf->size = size; } size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; } if (size <= 0) { buf->decoder_flags |= BUF_FLAG_FRAME_END; if (this->iff_type == IFF_ILBM_CHUNK ) buf->decoder_info[1] = this->video_pts_inc; /* initial video_step */ } this->video_fifo->put(this->video_fifo, buf); } break; } /* look for other multimedia parts */ if( read_iff_chunk( this ) ) this->status = DEMUX_OK; else this->status = DEMUX_FINISHED; return this->status; } static void demux_iff_send_headers(demux_plugin_t *this_gen) { demux_iff_t *this = (demux_iff_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; if( this->title ) _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->title); if( this->author ) _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->author); if( this->annotations ) _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, this->annotations); /* load stream information */ switch( this->iff_type ) { case IFF_8SVX_CHUNK: case IFF_16SV_CHUNK: _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->audio_channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->vhdr->samplesPerSec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->audio_bits); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo && this->audio_type) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->vhdr->samplesPerSec; buf->decoder_info[2] = this->audio_bits; buf->decoder_info[3] = this->audio_channels; this->audio_fifo->put (this->audio_fifo, buf); } break; case IFF_ILBM_CHUNK: case IFF_ANIM_CHUNK: _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_pts_inc); /* send start buffers */ _x_demux_control_start(this->stream); buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->type = this->video_type; buf->size = sizeof(xine_bmiheader); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE|BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->video_pts_inc; /* initial video_step */ buf->decoder_info[1] = 0; if( this->bmhd ) { buf->decoder_info[2] = this->bmhd->xaspect; buf->decoder_info[3] = this->bmhd->yaspect; } memcpy(buf->content, &this->bih, sizeof(this->bih)); this->video_fifo->put(this->video_fifo, buf); break; default: break; } } static int demux_iff_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_iff_t *this = (demux_iff_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); (void)start_time; switch( this->iff_type ) { case IFF_8SVX_CHUNK: case IFF_16SV_CHUNK: this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* check the boundary offsets */ this->audio_position = (start_pos < 0) ? 0 : ((start_pos >= this->data_size) ? this->data_size : start_pos); break; case IFF_ILBM_CHUNK: case IFF_ANIM_CHUNK: /* disable seeking for ILBM and ANIM */ if( !playing ) { this->status = DEMUX_OK; } break; default: break; } return this->status; } static void demux_iff_dispose (demux_plugin_t *this_gen) { demux_iff_t *this = (demux_iff_t *) this_gen; free(this->bmhd); free(this->cmap); free(this->grab); free(this->dest); free(this->camg); free(this->ccrt); free(this->dpi); free(this->vhdr); free(this->atak); free(this->rlse); free(this->anhd); free(this->dpan); free(this->title); free(this->copyright); free(this->author); free(this->annotations); free(this->version); free(this->text); free (this->audio_interleave_buffer); free (this->audio_read_buffer); this->audio_buffer_filled = 0; free(this); } static int demux_iff_get_status (demux_plugin_t *this_gen) { demux_iff_t *this = (demux_iff_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_iff_get_stream_length (demux_plugin_t *this_gen) { demux_iff_t *this = (demux_iff_t *) this_gen; return this->running_time; } static uint32_t demux_iff_get_capabilities(demux_plugin_t *this_gen){ (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_iff_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type){ (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_iff_t *this; this = calloc(1, sizeof(demux_iff_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_iff_send_headers; this->demux_plugin.send_chunk = demux_iff_send_chunk; this->demux_plugin.seek = demux_iff_seek; this->demux_plugin.dispose = demux_iff_dispose; this->demux_plugin.get_status = demux_iff_get_status; this->demux_plugin.get_stream_length = demux_iff_get_stream_length; this->demux_plugin.get_capabilities = demux_iff_get_capabilities; this->demux_plugin.get_optional_data = demux_iff_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_iff_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_iff_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_iff_class = { .open_plugin = open_plugin, .description = N_("IFF demux plugin"), .identifier = "IFF", .mimetypes = "audio/x-8svx: 8svx: IFF-8SVX Audio;" "audio/8svx: 8svx: IFF-8SVX Audio;" "audio/x-16sv: 16sv: IFF-16SV Audio;" "audio/168sv: 16sv: IFF-16SV Audio;" "image/x-ilbm: ilbm: IFF-ILBM Picture;" "image/ilbm: ilbm: IFF-ILBM Picture;" "video/x-anim: anim: IFF-ANIM Video;" "video/anim: anim: IFF-ANIM Video;", .extensions = "iff svx 8svx 16sv ilbm ham ham6 ham8 anim anim3 anim5 anim7 anim8", .dispose = NULL, }; return (void *)&demux_iff_class; } xine-lib-1.2/src/demuxers/demux_wc3movie.c0000644000175000017500000005573314647725152016426 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * File Demuxer for Wing Commander III MVE movie files * by Mike Melanson (melanson@pcisys.net) * For more information on the MVE file format, visit: * http://www.pcisys.net/~melanson/codecs/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include /********** logging **********/ #define LOG_MODULE "demux_wc3movie" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" #define FOURCC_TAG BE_FOURCC #define FORM_TAG FOURCC_TAG('F', 'O', 'R', 'M') #define MOVE_TAG FOURCC_TAG('M', 'O', 'V', 'E') #define PC_TAG FOURCC_TAG('_', 'P', 'C', '_') #define SOND_TAG FOURCC_TAG('S', 'O', 'N', 'D') #define PALT_TAG FOURCC_TAG('P', 'A', 'L', 'T') #define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X') #define BNAM_TAG FOURCC_TAG('B', 'N', 'A', 'M') #define SIZE_TAG FOURCC_TAG('S', 'I', 'Z', 'E') #define BRCH_TAG FOURCC_TAG('B', 'R', 'C', 'H') #define SHOT_TAG FOURCC_TAG('S', 'H', 'O', 'T') #define VGA_TAG FOURCC_TAG('V', 'G', 'A', ' ') #define AUDI_TAG FOURCC_TAG('A', 'U', 'D', 'I') #define TEXT_TAG FOURCC_TAG('T', 'E', 'X', 'T') #define PALETTE_SIZE 256 #define PALETTE_CHUNK_SIZE (PALETTE_SIZE * 3) #define WC3_FRAMERATE 15 #define WC3_PTS_INC (90000 / 15) #define WC3_USUAL_WIDTH 320 #define WC3_USUAL_HEIGHT 165 #define WC3_HEADER_SIZE 16 #define PREAMBLE_SIZE 8 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; xine_bmiheader bih; xine_waveformatex wave; palette_entry_t *palettes; unsigned int number_of_shots; unsigned int current_shot; off_t *shot_offsets; int seek_flag; /* this is set when a seek occurs */ off_t data_start; off_t data_size; int64_t video_pts; } demux_mve_t; /* bizarre palette lookup table */ static const unsigned char wc3_pal_lookup[] = { 0x00, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0E, 0x10, 0x12, 0x13, 0x15, 0x16, 0x18, 0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x20, 0x21, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2A, 0x2C, 0x2D, 0x2E, 0x2F, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 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, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD }; static int demux_mve_send_chunk(demux_plugin_t *this_gen) { demux_mve_t *this = (demux_mve_t *) this_gen; buf_element_t *buf = NULL; int64_t audio_pts = 0; unsigned char preamble[PREAMBLE_SIZE]; unsigned int chunk_tag; unsigned int chunk_size; off_t current_file_pos; unsigned int palette_number; /* compensate for the initial data in the file */ current_file_pos = this->input->get_current_pos(this->input) - this->data_start; if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) this->status = DEMUX_FINISHED; else { chunk_tag = _X_BE_32(&preamble[0]); /* round up to the nearest even size */ chunk_size = (_X_BE_32(&preamble[4]) + 1) & (~1); if (chunk_tag == BRCH_TAG) { /* empty chunk; do nothing */ } else if (chunk_tag == SHOT_TAG) { if (this->seek_flag) { /* reset pts */ this->video_pts = 0; _x_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK); this->seek_flag = 0; } else { /* record the offset of the SHOT chunk */ if (this->current_shot < this->number_of_shots) { this->shot_offsets[this->current_shot] = this->input->get_current_pos(this->input) - PREAMBLE_SIZE; } } this->current_shot++; /* this is the start of a new shot; send a new palette */ if (this->input->read(this->input, preamble, 4) != 4) { this->status = DEMUX_FINISHED; return this->status; } palette_number = _X_LE_32(&preamble[0]); if (palette_number >= this->number_of_shots) { xine_log(this->stream->xine, XINE_LOG_MSG, _("demux_wc3movie: SHOT chunk referenced invalid palette (%d >= %d)\n"), palette_number, this->number_of_shots); this->status = DEMUX_FINISHED; return this->status; } buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = PALETTE_SIZE; buf->decoder_info_ptr[2] = &this->palettes[PALETTE_SIZE * palette_number]; buf->size = 0; buf->type = BUF_VIDEO_WC3; this->video_fifo->put (this->video_fifo, buf); } else if (chunk_tag == AUDI_TAG) { if( this->audio_fifo ) { audio_pts = this->video_pts - WC3_PTS_INC; while (chunk_size) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_LE; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = audio_pts / 90; buf->pts = audio_pts; if ((int)chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); } }else{ if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; } } } else if (chunk_tag == VGA_TAG) { while (chunk_size) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_WC3; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; if ((int)chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put (this->video_fifo, buf); } this->video_pts += WC3_PTS_INC; } else if (chunk_tag == TEXT_TAG) { /*text_pts = this->video_pts - WC3_PTS_INC;*/ /* unhandled thus far */ if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; } } else { /* report an unknown chunk and skip it */ lprintf("encountered unknown chunk: %c%c%c%c\n", (chunk_tag >> 24) & 0xFF, (chunk_tag >> 16) & 0xFF, (chunk_tag >> 8) & 0xFF, (chunk_tag >> 0) & 0xFF); if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; } } } return this->status; } static void demux_mve_send_headers(demux_plugin_t *this_gen) { demux_mve_t *this = (demux_mve_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); /* this is not strictly correct-- some WC3 MVE files do not contain * audio, but I'm too lazy to check if that is the case */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->wave.nChannels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->wave.nSamplesPerSec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->wave.wBitsPerSample); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = WC3_PTS_INC; /* initial video_step */ buf->content = (void *)&this->bih; buf->size = sizeof(this->bih); buf->type = BUF_VIDEO_WC3; this->video_fifo->put (this->video_fifo, buf); if (this->audio_fifo) { this->wave.wFormatTag = 1; this->wave.nChannels = 1; this->wave.nSamplesPerSec = 22050; this->wave.wBitsPerSample = 16; this->wave.nBlockAlign = (this->wave.wBitsPerSample / 8) * this->wave.nChannels; this->wave.nAvgBytesPerSec = this->wave.nBlockAlign * this->wave.nSamplesPerSec; buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_LE; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->wave.nSamplesPerSec; buf->decoder_info[2] = this->wave.wBitsPerSample; buf->decoder_info[3] = this->wave.nChannels; buf->content = (void *)&this->wave; buf->size = sizeof(this->wave); this->audio_fifo->put (this->audio_fifo, buf); } } static int probe_mve_file(input_plugin_t *input) { unsigned char header[WC3_HEADER_SIZE]; if (_x_demux_read_header(input, header, WC3_HEADER_SIZE) != WC3_HEADER_SIZE) return 0; if ( !_x_is_fourcc(&header[0], "FORM") || !_x_is_fourcc(&header[8], "MOVE") || !_x_is_fourcc(&header[12], "_PC_") ) return 0; return 1; } /* returns 1 if the MVE file was opened successfully, 0 otherwise */ static int open_mve_file(demux_mve_t *this) { unsigned char preamble[PREAMBLE_SIZE]; unsigned int chunk_tag; unsigned int chunk_size; unsigned char disk_palette[PALETTE_CHUNK_SIZE]; int i, j; unsigned char r, g, b; int temp; /* file is qualified */ this->bih.biSize = sizeof(xine_bmiheader); /* these are the frame dimensions unless others are found */ this->bih.biWidth = WC3_USUAL_WIDTH; this->bih.biHeight = WC3_USUAL_HEIGHT; /* load the number of palettes, the only interesting piece of information * in the _PC_ chunk; take it for granted that it will always appear at * position 0x1C */ if (this->input->seek(this->input, 0x1C, SEEK_SET) != 0x1c) return 0; if (this->input->read(this->input, preamble, 4) != 4) return 0; this->number_of_shots = _X_LE_32(&preamble[0]); /* allocate space for the shot offset index and set offsets to 0 */ this->shot_offsets = xine_xcalloc(this->number_of_shots, sizeof(off_t)); this->current_shot = 0; /* skip the SOND chunk */ if (this->input->seek(this->input, 12, SEEK_CUR) < 0) return 0; /* load the palette chunks */ this->palettes = xine_xcalloc(this->number_of_shots, PALETTE_SIZE * sizeof(palette_entry_t)); if (!this->shot_offsets || !this->palettes) { return 0; } for (i = 0; i < (int)this->number_of_shots; i++) { /* make sure there was a valid palette chunk preamble */ if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { return 0; } if ( !_x_is_fourcc(&preamble[0], "PALT") || (_X_BE_32(&preamble[4]) != PALETTE_CHUNK_SIZE)) { xine_log(this->stream->xine, XINE_LOG_MSG, _("demux_wc3movie: There was a problem while loading palette chunks\n")); return 0; } /* load the palette chunk */ if (this->input->read(this->input, disk_palette, PALETTE_CHUNK_SIZE) != PALETTE_CHUNK_SIZE) { return 0; } /* convert and store the palette */ for (j = 0; j < PALETTE_SIZE; j++) { r = disk_palette[j * 3 + 0]; g = disk_palette[j * 3 + 1]; b = disk_palette[j * 3 + 2]; /* rotate each component left by 2 */ temp = r << 2; r = (temp & 0xff) | (temp >> 8); r = wc3_pal_lookup[r]; temp = g << 2; g = (temp & 0xff) | (temp >> 8); g = wc3_pal_lookup[g]; temp = b << 2; b = (temp & 0xff) | (temp >> 8); b = wc3_pal_lookup[b]; this->palettes[i * 256 + j].r = r; this->palettes[i * 256 + j].g = g; this->palettes[i * 256 + j].b = b; } } /* after the palette chunks comes any number of chunks such as INDX, * BNAM, SIZE and perhaps others; traverse chunks until first BRCH * chunk is found */ chunk_tag = 0; while (chunk_tag != BRCH_TAG) { if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { return 0; } chunk_tag = _X_BE_32(&preamble[0]); /* round up to the nearest even size */ chunk_size = (_X_BE_32(&preamble[4]) + 1) & (~1); switch (chunk_tag) { case BRCH_TAG: /* time to start demuxing */ break; case BNAM_TAG: { /* load the name into the stream attributes */ char *title = malloc (chunk_size); if (!title || this->input->read(this->input, title, chunk_size) != chunk_size) { free (title); return 0; } title[chunk_size - 1] = 0; _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, title); free(title); break; } case SIZE_TAG: /* override the default width and height */ /* reuse the preamble bytes */ if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { return 0; } this->bih.biWidth = _X_BE_32(&preamble[0]); this->bih.biHeight = _X_BE_32(&preamble[4]); break; case INDX_TAG: /* index is not useful for this demuxer */ if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) return 0; break; default: /* report an unknown chunk and skip it */ lprintf("encountered unknown chunk: %c%c%c%c\n", (chunk_tag >> 24) & 0xFF, (chunk_tag >> 16) & 0xFF, (chunk_tag >> 8) & 0xFF, (chunk_tag >> 0) & 0xFF); if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) return 0; break; } } /* note the data start offset */ this->data_start = this->input->get_current_pos(this->input); this->data_size = this->input->get_length(this->input) - this->data_start; this->video_pts = 0; return 1; } static int demux_mve_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { /* * MVE files are comprised of a series of SHOTs. A SHOT begins when the * camera angle changes. The first frame of a SHOT is effectively a * keyframe so it is safe to seek to the start of a SHOT. A/V sync is * not a concern since each video or audio chunk represents exactly * 1/15 sec. * * When a seek is requested, traverse the list of SHOT offsets and find * the best match. If not enough SHOT boundaries have been crossed while * demuxing the file, traverse the file until enough SHOTs are found. */ demux_mve_t *this = (demux_mve_t *) this_gen; int i; unsigned char preamble[PREAMBLE_SIZE]; unsigned int chunk_tag; unsigned int chunk_size; int new_shot = -1; (void)playing; start_time /= 1000; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); this->status = DEMUX_OK; _x_demux_flush_engine(this->stream); this->seek_flag = 1; /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; /* make sure the first shot has been recorded */ if (this->shot_offsets[0] == 0) { while (1) { if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } chunk_tag = _X_BE_32(&preamble[0]); /* round up to the nearest even size */ chunk_size = (_X_BE_32(&preamble[4]) + 1) & (~1); if (chunk_tag == SHOT_TAG) { this->shot_offsets[0] = this->input->get_current_pos(this->input) - PREAMBLE_SIZE; /* skip the four SHOT data bytes (palette index) */ this->input->seek(this->input, 4, SEEK_CUR); break; /* get out of the infinite while loop */ } else { this->input->seek(this->input, chunk_size, SEEK_CUR); } } } /* compensate for data at start of file */ start_pos += this->data_start; for (i = 0; i < (int)this->number_of_shots - 1; i++) { /* if the next shot offset has not been recorded, traverse through the * file until it is found */ if (this->shot_offsets[i + 1] == 0) { off_t current_pos; /* be sure to be just after the last known shot_offset */ current_pos = this->input->get_current_pos(this->input); if (current_pos < this->shot_offsets[i]) { this->input->seek(this->input, this->shot_offsets[i] + PREAMBLE_SIZE + 4, SEEK_SET); } while (1) { if (this->input->read(this->input, preamble, PREAMBLE_SIZE) != PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } chunk_tag = _X_BE_32(&preamble[0]); /* round up to the nearest even size */ chunk_size = (_X_BE_32(&preamble[4]) + 1) & (~1); if (chunk_tag == SHOT_TAG) { this->shot_offsets[i + 1] = this->input->get_current_pos(this->input) - PREAMBLE_SIZE; /* skip the four SHOT data bytes (palette index) */ this->input->seek(this->input, 4, SEEK_CUR); break; /* get out of the infinite while loop */ } else { this->input->seek(this->input, chunk_size, SEEK_CUR); } } } /* check if the seek-to offset falls in between this shot offset and * the next one */ if ((start_pos >= this->shot_offsets[i]) && (start_pos < this->shot_offsets[i + 1])) { new_shot = i; break; } } /* if no new shot was found in the loop, the new shot must be the last * shot */ if (new_shot == -1) new_shot = this->number_of_shots - 1; this->current_shot = new_shot; /* reposition the stream at new shot */ this->input->seek(this->input, this->shot_offsets[new_shot], SEEK_SET); return this->status; } static void demux_mve_dispose (demux_plugin_t *this_gen) { demux_mve_t *this = (demux_mve_t *) this_gen; _x_freep(&this->palettes); _x_freep(&this->shot_offsets); free(this); } static int demux_mve_get_status (demux_plugin_t *this_gen) { demux_mve_t *this = (demux_mve_t *) this_gen; return this->status; } static int demux_mve_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_mve_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mve_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_mve_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_mve_file(input)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_mve_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_mve_send_headers; this->demux_plugin.send_chunk = demux_mve_send_chunk; this->demux_plugin.seek = demux_mve_seek; this->demux_plugin.dispose = demux_mve_dispose; this->demux_plugin.get_status = demux_mve_get_status; this->demux_plugin.get_stream_length = demux_mve_get_stream_length; this->demux_plugin.get_capabilities = demux_mve_get_capabilities; this->demux_plugin.get_optional_data = demux_mve_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_mve_file(this)) { demux_mve_dispose (&this->demux_plugin); return NULL; } return &this->demux_plugin; } void *demux_wc3movie_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_wc3movie_class = { .open_plugin = open_plugin, .description = N_("Wing Commander III Movie (MVE) demux plugin"), .identifier = "WC3 Movie", .mimetypes = NULL, .extensions = "mve", .dispose = NULL, }; return (void *)&demux_wc3movie_class; } xine-lib-1.2/src/demuxers/demux_matroska.c0000644000175000017500000031364214647725152016507 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for matroska streams * * TODO: * more decoders init * metadata * non seekable input plugins support */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #define LOG_MODULE "demux_matroska" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #include #include "bswap.h" #include "ebml.h" #include "matroska.h" #include "demux_matroska.h" #define LITERAL_UTF_8_LEN 5 #define LITERAL_UTF_8_SIZE 6 #define LITERAL_UTF_8 "utf-8" static void check_newpts (demux_matroska_t *this, int64_t pts, matroska_track_t *track) { int64_t diff; if ((track->track_type == MATROSKA_TRACK_VIDEO) || (track->track_type == MATROSKA_TRACK_AUDIO)) { diff = pts - track->last_pts; if (pts && (this->send_newpts || (track->last_pts && llabs(diff)>WRAP_THRESHOLD)) ) { int i; lprintf ("sending newpts %" PRId64 ", diff %" PRId64 ", track %d\n", pts, diff, track->track_num); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; for (i = 0; i < this->num_tracks; i++) { this->tracks[i]->last_pts = 0; } } else { #ifdef LOG if (pts) lprintf ("diff %" PRId64 ", track %d\n", diff, track->track_num); #endif } if (pts) track->last_pts = pts; } } /* Add an entry to the top_level element list */ static int add_top_level_entry (demux_matroska_t *this, off_t pos) { if (this->top_level_list_size == this->top_level_list_max_size) { void *tmp = this->top_level_list; this->top_level_list_max_size += 50; lprintf("top_level_list_max_size: %d\n", this->top_level_list_max_size); this->top_level_list = realloc(this->top_level_list, this->top_level_list_max_size * sizeof(off_t)); if (this->top_level_list == NULL) { this->top_level_list_max_size = 0; this->top_level_list_size = 0; free(tmp); return 0; } } this->top_level_list[this->top_level_list_size] = pos; this->top_level_list_size++; return 1; } /* Find an entry in the top_level elem list * return * 0: not found * 1: found */ static int find_top_level_entry (demux_matroska_t *this, off_t pos) { int i; for (i = 0; i < this->top_level_list_size; i++) { if (this->top_level_list[i] == pos) return 1; } return 0; } static int parse_info(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 2; double duration = 0.0; /* in matroska unit */ while (next_level == 2) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_I_TIMECODESCALE: lprintf("timecode_scale\n"); if (!ebml_read_uint(ebml, &elem, &this->timecode_scale)) return 0; break; case MATROSKA_ID_I_DURATION: lprintf("duration\n"); if (!ebml_read_float(ebml, &elem, &duration)) return 0; break; case MATROSKA_ID_I_TITLE: lprintf("title\n"); if (NULL != this->title) free(this->title); this->title = ebml_alloc_read_ascii(ebml, &elem); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, this->title); break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } if (this->timecode_scale == 0) { this->timecode_scale = 1000000; } this->duration = (int)(duration * (double)this->timecode_scale / 1000000.0); lprintf("timecode_scale: %" PRId64 "\n", this->timecode_scale); lprintf("duration: %d\n", this->duration); lprintf("title: %s\n", (NULL != this->title ? this->title : "(none)")); return 1; } static int parse_video_track (demux_matroska_t *this, matroska_video_track_t *vt) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; uint64_t val; while (next_level == this_level) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_TV_FLAGINTERLACED: lprintf("MATROSKA_ID_TV_FLAGINTERLACED\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; vt->flag_interlaced = val; break; case MATROSKA_ID_TV_PIXELWIDTH: lprintf("MATROSKA_ID_TV_PIXELWIDTH\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; vt->pixel_width = val; break; case MATROSKA_ID_TV_PIXELHEIGHT: lprintf("MATROSKA_ID_TV_PIXELHEIGHT\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; vt->pixel_height = val; break; case MATROSKA_ID_TV_VIDEODISPLAYWIDTH: lprintf("MATROSKA_ID_TV_VIDEODISPLAYWIDTH\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; vt->display_width = val; break; case MATROSKA_ID_TV_VIDEODISPLAYHEIGHT: lprintf("MATROSKA_ID_TV_VIDEODISPLAYHEIGHT\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; vt->display_height = val; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_audio_track (demux_matroska_t *this, matroska_audio_track_t *at) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; while (next_level == this_level) { ebml_elem_t elem; uint64_t val; double fval; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_TA_SAMPLINGFREQUENCY: lprintf("MATROSKA_ID_TA_SAMPLINGFREQUENCY\n"); if (!ebml_read_float(ebml, &elem, &fval)) return 0; at->sampling_freq = (int)fval; break; case MATROSKA_ID_TA_OUTPUTSAMPLINGFREQUENCY: lprintf("MATROSKA_ID_TA_OUTPUTSAMPLINGFREQUENCY\n"); if (!ebml_read_float(ebml, &elem, &fval)) return 0; at->output_sampling_freq = (int)fval; break; case MATROSKA_ID_TA_CHANNELS: lprintf("MATROSKA_ID_TA_CHANNELS\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; at->channels = val; break; case MATROSKA_ID_TA_BITDEPTH: lprintf("MATROSKA_ID_TA_BITDEPTH\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; at->bits_per_sample = val; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_content_compression (demux_matroska_t *this, matroska_track_t *track) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; while (next_level == this_level) { ebml_elem_t elem; uint64_t val; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CE_COMPALGO: lprintf("ContentCompAlgo\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; switch (val) { case MATROSKA_COMPRESS_ZLIB: case MATROSKA_COMPRESS_BZLIB: case MATROSKA_COMPRESS_LZO1X: case MATROSKA_COMPRESS_HEADER_STRIP: track->compress_algo = val; break; default: track->compress_algo = MATROSKA_COMPRESS_UNKNOWN; break; } break; case MATROSKA_ID_CE_COMPSETTINGS: lprintf("ContentCompSettings\n"); track->compress_settings = calloc(1, elem.len); track->compress_len = elem.len; if (elem.len > this->compress_maxlen) this->compress_maxlen = elem.len; if(!ebml_read_binary(ebml, &elem, track->compress_settings)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_content_encoding (demux_matroska_t *this, matroska_track_t *track) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; while (next_level == this_level) { ebml_elem_t elem; uint64_t val; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CE_ORDER: lprintf("ContentEncodingOrder\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; if (val != 0) { // multiple content encoding isn't supported lprintf(" warning: a non-zero encoding order is UNSUPPORTED\n"); return 0; } break; case MATROSKA_ID_CE_SCOPE: lprintf("ContentEncodingScope\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; if (val != 1) { // 1 (all frame contents) is the only supported option lprintf(" warning: UNSUPPORTED encoding scope (%" PRId64 ")\n", val); return 0; } break; case MATROSKA_ID_CE_TYPE: lprintf("ContentEncodingType\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; if (val != 0) // only compression (0) is supported return 0; break; case MATROSKA_ID_CE_COMPRESSION: lprintf("ContentCompression\n"); if (!ebml_read_master (ebml, &elem)) return 0; track->compress_algo = 0; /* default */ if ((elem.len > 0) && !parse_content_compression(this, track)) return 0; break; case MATROSKA_ID_CE_ENCRYPTION: lprintf("ContentEncryption (UNSUPPORTED)\n"); if (!ebml_skip(ebml, &elem)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_content_encodings (demux_matroska_t *this, matroska_track_t *track) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; while (next_level == this_level) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CONTENTENCODING: lprintf("ContentEncoding\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_content_encoding(this, track)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static void init_codec_video(demux_matroska_t *this, matroska_track_t *track) { buf_element_t *buf; buf = track->fifo->buffer_pool_size_alloc (track->fifo, track->codec_private_len); if (track->codec_private_len > (unsigned int)(buf->max_size)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: private decoder data length (%d) is greater than fifo buffer length (%" PRId32 ")\n", track->codec_private_len, buf->max_size); buf->free_buffer(buf); return; } buf->size = track->codec_private_len; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; buf->type = track->buf_type; buf->pts = 0; if (buf->size) xine_fast_memcpy (buf->content, track->codec_private, buf->size); if(track->default_duration) { buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = (int64_t)track->default_duration * (int64_t)90 / (int64_t)1000000; } if(track->video_track && track->video_track->display_width && track->video_track->display_height) { buf->decoder_flags |= BUF_FLAG_ASPECT; buf->decoder_info[1] = track->video_track->display_width; buf->decoder_info[2] = track->video_track->display_height; } track->fifo->put (track->fifo, buf); } static void init_codec_audio(demux_matroska_t *this, matroska_track_t *track) { buf_element_t *buf; /* Standard head shall either be empty, or contain a xine_waveformatex struct, * optioally appended by codec private data. Unfortunatly, we have no format tag * for Opus. Thus, send private data as a second buf. */ buf = track->fifo->buffer_pool_size_alloc (track->fifo, 0); buf->size = 0; /* default param */ buf->decoder_info[0] = 0; buf->decoder_info[1] = 44100; buf->decoder_info[2] = 16; buf->decoder_info[3] = 2; /* track param */ if (track->audio_track) { if (track->audio_track->sampling_freq) buf->decoder_info[1] = track->audio_track->sampling_freq; if (track->audio_track->bits_per_sample) buf->decoder_info[2] = track->audio_track->bits_per_sample; if (track->audio_track->channels) buf->decoder_info[3] = track->audio_track->channels; } lprintf ("%d Hz, %d bits, %d channels\n", buf->decoder_info[1], buf->decoder_info[2], buf->decoder_info[3]); buf->type = track->buf_type; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; buf->pts = 0; track->fifo->put (track->fifo, buf); if (track->codec_private_len > 0) { buf = track->fifo->buffer_pool_size_alloc (track->fifo, track->codec_private_len); if (track->codec_private_len > (unsigned int)buf->max_size) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: private decoder data length (%d) is greater than fifo buffer length (%d).\n", track->codec_private_len, buf->max_size); buf->free_buffer (buf); } else { memcpy (buf->content, track->codec_private, track->codec_private_len); buf->decoder_info_ptr[2] = buf->content; buf->decoder_info[2] = track->codec_private_len; buf->type = track->buf_type; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG; buf->pts = 0; track->fifo->put (track->fifo, buf); } } } static void init_codec_real(demux_matroska_t *this, matroska_track_t * track) { buf_element_t *buf; buf = track->fifo->buffer_pool_size_alloc (track->fifo, track->codec_private_len); if (track->codec_private_len > (unsigned int)buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: private decoder data length (%d) is greater than fifo buffer length (%" PRId32 ")\n", track->codec_private_len, buf->max_size); buf->free_buffer(buf); return; } buf->size = track->codec_private_len; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END; buf->type = track->buf_type; buf->pts = 0; if (buf->size) xine_fast_memcpy (buf->content, track->codec_private, buf->size); if(track->default_duration) { buf->decoder_flags |= BUF_FLAG_FRAMERATE; buf->decoder_info[0] = (int64_t)track->default_duration * (int64_t)90 / (int64_t)1000000; } if(track->video_track && track->video_track->display_width && track->video_track->display_height) { buf->decoder_flags |= BUF_FLAG_ASPECT; buf->decoder_info[1] = track->video_track->display_width; buf->decoder_info[2] = track->video_track->display_height; } track->fifo->put (track->fifo, buf); } static void init_codec_xiph(demux_matroska_t *this, matroska_track_t *track) { buf_element_t *buf; uint8_t nb_lace; int frame[3]; int i; uint8_t *data; if (track->codec_private_len < 3) return; nb_lace = track->codec_private[0]; if (nb_lace != 2) return; frame[0] = track->codec_private[1]; frame[1] = track->codec_private[2]; frame[2] = track->codec_private_len - frame[0] - frame[1] - 3; if (frame[2] < 0) return; data = track->codec_private + 3; for (i = 0; i < 3; i++) { buf = track->fifo->buffer_pool_size_alloc (track->fifo, frame[i]); if (frame[i] > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: private decoder data length (%d) is greater than fifo buffer length (%" PRId32 ")\n", frame[i], buf->max_size); buf->free_buffer(buf); return; } buf->size = frame[i]; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_START | BUF_FLAG_FRAME_END; buf->type = track->buf_type; buf->pts = 0; xine_fast_memcpy (buf->content, data, buf->size); data += buf->size; track->fifo->put (track->fifo, buf); } } static int aac_get_sr_index (uint32_t sample_rate) { if (92017 <= sample_rate) return 0; else if (75132 <= sample_rate) return 1; else if (55426 <= sample_rate) return 2; else if (46009 <= sample_rate) return 3; else if (37566 <= sample_rate) return 4; else if (27713 <= sample_rate) return 5; else if (23004 <= sample_rate) return 6; else if (18783 <= sample_rate) return 7; else if (13856 <= sample_rate) return 8; else if (11502 <= sample_rate) return 9; else if (9391 <= sample_rate) return 10; else return 11; } #define AAC_SYNC_EXTENSION_TYPE 0x02b7 static void init_codec_aac(demux_matroska_t *this, matroska_track_t *track) { matroska_audio_track_t *atrack = track->audio_track; buf_element_t *buf; int profile; int sr_index; (void)this; /* Create a DecoderSpecificInfo for initialising libfaad */ sr_index = aac_get_sr_index(atrack->sampling_freq); /* newer specification with appended CodecPrivate */ if (strlen(track->codec_id) <= 12) profile = 3; /* older specification */ else if (!strncmp (&track->codec_id[12], "MAIN", 4)) profile = 0; else if (!strncmp (&track->codec_id[12], "LC", 2)) profile = 1; else if (!strncmp (&track->codec_id[12], "SSR", 3)) profile = 2; else profile = 3; buf = track->fifo->buffer_pool_alloc (track->fifo); buf->size = 0; buf->type = track->buf_type; buf->pts = 0; buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_DECODER_CONFIG; buf->decoder_info_ptr[2] = buf->mem; buf->mem[0] = ((profile + 1) << 3) | ((sr_index & 0x0e) >> 1); buf->mem[1] = ((sr_index & 0x01) << 7) | (atrack->channels << 3); if (strstr(track->codec_id, "SBR") == NULL) buf->decoder_info[2] = 2; else { /* HE-AAC (aka SBR AAC) */ sr_index = aac_get_sr_index(atrack->sampling_freq*2); buf->mem[2] = AAC_SYNC_EXTENSION_TYPE >> 3; buf->mem[3] = ((AAC_SYNC_EXTENSION_TYPE & 0x07) << 5) | 5; buf->mem[4] = (1 << 7) | (sr_index << 3); buf->decoder_info[2] = 5; } track->fifo->put(track->fifo, buf); } static int vobsub_parse_size(matroska_track_t *t, const char *start) { if (sscanf(&start[6], "%dx%d", &t->sub_track->width, &t->sub_track->height) == 2) { lprintf("VobSub size: %ux%u\n", t->sub_track->width, t->sub_track->height); return 1; } return 0; } static int vobsub_parse_palette(matroska_track_t *t, const char *start) { int i, r, g, b, y, u, v; unsigned tmp; start += 8; while (isspace(*start)) start++; for (i = 0; i < 16; i++) { if (sscanf(start, "%06x", &tmp) != 1) break; r = tmp >> 16 & 0xff; g = tmp >> 8 & 0xff; b = tmp & 0xff; y = MIN(MAX((int)(0.1494 * r + 0.6061 * g + 0.2445 * b), 0), 0xff); u = MIN(MAX((int)(0.6066 * r - 0.4322 * g - 0.1744 * b) + 128, 0), 0xff); v = MIN(MAX((int)(-0.08435 * r - 0.3422 * g + 0.4266 * b) + 128, 0), 0xff); t->sub_track->palette[i] = y << 16 | u << 8 | v; start += 6; while ((*start == ',') || isspace(*start)) start++; } if (i == 16) { lprintf("VobSub palette: %06x,%06x,%06x,%06x,%06x,%06x,%06x,%06x,%06x," "%06x,%06x,%06x,%06x,%06x,%06x,%06x\n", t->sub_track->palette[0], t->sub_track->palette[1], t->sub_track->palette[2], t->sub_track->palette[3], t->sub_track->palette[4], t->sub_track->palette[5], t->sub_track->palette[6], t->sub_track->palette[7], t->sub_track->palette[8], t->sub_track->palette[9], t->sub_track->palette[10], t->sub_track->palette[11], t->sub_track->palette[12], t->sub_track->palette[13], t->sub_track->palette[14], t->sub_track->palette[15]); return 2; } return 0; } static int vobsub_parse_custom_colors(matroska_track_t *t, const char *start) { int use_custom_colors, i; start += 14; while (isspace(*start)) start++; use_custom_colors = 0; if (!strncasecmp(start, "ON", 2) || (*start == '1')) use_custom_colors = 1; else if (!strncasecmp(start, "OFF", 3) || (*start == '0')) use_custom_colors = 0; lprintf("VobSub custom colours: %s\n", use_custom_colors ? "ON" : "OFF"); if ((start = strstr(start, "colors:")) != NULL) { start += 7; while (isspace(*start)) start++; for (i = 0; i < 4; i++) { if (sscanf(start, "%06x", &t->sub_track->colors[i]) != 1) break; start += 6; while ((*start == ',') || isspace(*start)) start++; } if (i == 4) { t->sub_track->custom_colors = 4; lprintf("VobSub colours: %06x,%06x,%06x,%06x\n", t->sub_track->colors[0], t->sub_track->colors[1], t->sub_track->colors[2], t->sub_track->colors[3]); } } if (!use_custom_colors) t->sub_track->custom_colors = 0; return 4; } static int vobsub_parse_forced_subs(matroska_track_t *t, const char *start) { start += 12; while (isspace(*start)) start++; if (!strncasecmp(start, "on", 2) || (*start == '1')) t->sub_track->forced_subs_only = 1; else if (!strncasecmp(start, "off", 3) || (*start == '0')) t->sub_track->forced_subs_only = 0; else return 0; lprintf("VobSub forced subs: %d\n", t->sub_track->forced_subs_only); return 8; } static void init_codec_vobsub(demux_matroska_t *this, matroska_track_t *track) { int things_found, last; char *buf, *pos, *start; buf_element_t *buf_el; lprintf("init_codec_vobsub for %d\n", track->track_num); (void)this; if ((track->codec_private == NULL) || (track->codec_private_len == 0)) return; track->sub_track = calloc(1, sizeof(matroska_sub_track_t)); if (track->sub_track == NULL) return; things_found = 0; buf = (char *)malloc(track->codec_private_len + 1); if (buf == NULL) return; xine_fast_memcpy(buf, track->codec_private, track->codec_private_len); buf[track->codec_private_len] = 0; track->sub_track->type = 'v'; pos = buf; start = buf; last = 0; do { if ((*pos == 0) || (*pos == '\r') || (*pos == '\n')) { if (*pos == 0) last = 1; *pos = 0; if (!strncasecmp(start, "size: ", 6)) things_found |= vobsub_parse_size(track, start); else if (!strncasecmp(start, "palette:", 8)) things_found |= vobsub_parse_palette(track, start); else if (!strncasecmp(start, "custom colours:", 14)) things_found |= vobsub_parse_custom_colors(track, start); else if (!strncasecmp(start, "forced subs:", 12)) things_found |= vobsub_parse_forced_subs(track, start); if (last) break; do { pos++; } while ((*pos == '\r') || (*pos == '\n')); start = pos; } else pos++; } while (!last && (*start != 0)); free(buf); if ((things_found & 2) == 2) { buf_el = track->fifo->buffer_pool_alloc(track->fifo); xine_fast_memcpy(buf_el->content, track->sub_track->palette, 16 * sizeof(uint32_t)); buf_el->type = BUF_SPU_DVD; buf_el->decoder_flags |= BUF_FLAG_SPECIAL; buf_el->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf_el->decoder_info[2] = SPU_DVD_SUBTYPE_CLUT; track->fifo->put(track->fifo, buf_el); } } static void init_codec_dvbsub(demux_matroska_t *this, matroska_track_t *track) { buf_element_t *buf; spu_dvb_descriptor_t *desc; (void)this; if (!track->codec_private || track->codec_private_len < 4) return; buf = track->fifo->buffer_pool_alloc (track->fifo); desc = (spu_dvb_descriptor_t *)buf->mem; memset(desc, 0, sizeof(*desc)); desc->comp_page_id = _X_BE_16(track->codec_private); desc->aux_page_id = _X_BE_16(track->codec_private + 2); buf->type = track->buf_type; buf->decoder_flags = BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVB_DESCRIPTOR; buf->decoder_info[2] = sizeof(*desc); buf->decoder_info_ptr[2] = desc; track->fifo->put (track->fifo, buf); } static void init_codec_spu(demux_matroska_t *this, matroska_track_t *track) { buf_element_t *buf; (void)this; buf = track->fifo->buffer_pool_alloc (track->fifo); buf->type = track->buf_type; track->fifo->put (track->fifo, buf); } static void handle_realvideo (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { demux_matroska_t *this = (demux_matroska_t *) this_gen; int chunks; int chunk_tab_size; if (data_len < 1) return; chunks = data[0]; chunk_tab_size = (chunks + 1) * 8; if ((int)data_len - 1 < chunk_tab_size) return; lprintf("chunks: %d, chunk_tab_size: %d\n", chunks, chunk_tab_size); _x_demux_send_data(track->fifo, data + chunk_tab_size + 1, data_len - chunk_tab_size - 1, data_pts, track->buf_type, decoder_flags, input_normpos, input_time, this->duration, 0); /* sends the fragment table */ { buf_element_t *buf; buf = track->fifo->buffer_pool_size_alloc(track->fifo, chunk_tab_size); if (chunk_tab_size > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: Real Chunk Table length (%d) is greater than fifo buffer length (%" PRId32 ")\n", chunk_tab_size, buf->max_size); buf->free_buffer(buf); return; } buf->decoder_flags = decoder_flags | BUF_FLAG_SPECIAL | BUF_FLAG_FRAMERATE; buf->decoder_info[0] = data_duration; buf->decoder_info[1] = BUF_SPECIAL_RV_CHUNK_TABLE; buf->decoder_info[2] = chunks; buf->decoder_info_ptr[2] = buf->content; buf->type = track->buf_type; xine_fast_memcpy(buf->decoder_info_ptr[2], data + 1, chunk_tab_size); track->fifo->put(track->fifo, buf); } } static void handle_sub_ssa (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { demux_matroska_t *this = (demux_matroska_t *) this_gen; buf_element_t *buf; uint32_t *val; int commas = 0; int lines = 1; char last_char = 0; char *dest; int dest_len; int skip = 0; lprintf ("pts: %" PRId64 ", duration: %d\n", data_pts, data_duration); /* skip ',' */ while (data_len && (commas < 8)) { if (*data == ',') commas++; data++; data_len--; } buf = track->fifo->buffer_pool_size_alloc(track->fifo, data_len + 8 + LITERAL_UTF_8_SIZE); buf->type = track->buf_type; buf->decoder_flags = decoder_flags | BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_CHARSET_ENCODING; buf->decoder_info_ptr[2] = buf->content + buf->max_size - LITERAL_UTF_8_SIZE; buf->decoder_info[2] = LITERAL_UTF_8_LEN; memcpy(buf->decoder_info_ptr[2], "utf-8", LITERAL_UTF_8_SIZE); val = (uint32_t *)buf->content; *val++ = data_pts / 90; /* start time */ *val++ = (data_pts + data_duration) / 90; /* end time */ dest = buf->content + 8; dest_len = buf->max_size - 8 - LITERAL_UTF_8_SIZE; while (data_len && dest_len) { if (skip) { if (*data == '}') skip--; else if (*data == '{') skip++; } else { if ((last_char == '\\') && ((*data == 'n') || (*data == 'N'))) { lines++; *dest = '\n'; dest++; dest_len--; } else { if (*data != '\\') { if (*data == '{') { skip++; } else { *dest = *data; dest++; dest_len--; } } } } last_char = *data; data++; data_len--; } if (dest_len) { *dest = '\0'; dest++; dest_len--; buf->size = dest - (char *)buf->content; buf->extra_info->input_normpos = input_normpos; buf->extra_info->input_time = input_time; buf->extra_info->total_time = this->duration; track->fifo->put(track->fifo, buf); } else { buf->free_buffer(buf); } } static void handle_sub_utf8 (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { demux_matroska_t *this = (demux_matroska_t *) this_gen; buf_element_t *buf; uint32_t *val; buf = track->fifo->buffer_pool_size_alloc(track->fifo, data_len + 9 + LITERAL_UTF_8_SIZE); buf->size = data_len + 9; /* 2 uint32_t + '\0' */ if (buf->max_size >= buf->size + LITERAL_UTF_8_SIZE) { buf->decoder_flags = decoder_flags; buf->type = track->buf_type; buf->decoder_flags = decoder_flags | BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_CHARSET_ENCODING; buf->decoder_info_ptr[2] = buf->content + buf->max_size - LITERAL_UTF_8_SIZE; buf->decoder_info[2] = LITERAL_UTF_8_LEN; memcpy(buf->decoder_info_ptr[2], "utf-8", LITERAL_UTF_8_SIZE); val = (uint32_t *)buf->content; *val++ = data_pts / 90; /* start time */ *val++ = (data_pts + data_duration) / 90; /* end time */ xine_fast_memcpy(buf->content + 8, data, data_len); buf->content[8 + data_len] = '\0'; lprintf("sub: %s\n", buf->content + 8); buf->extra_info->input_normpos = input_normpos; buf->extra_info->input_time = input_time; buf->extra_info->total_time = this->duration; track->fifo->put(track->fifo, buf); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: data length is greater than fifo buffer length\n"); buf->free_buffer(buf); } } /* 0x02 (not a keyframe) | 0x01 (is visible) */ static int vp9_frametype (const uint8_t *h) { if ((h[0] & 0xc0) != 0x80) /* frame marker missing */ return 1; if ((h[0] & 0x30) == 0x30) { /* profile 3+ */ if (h[0] & 0x08) /* profile 4+ not supported */ return 0; if (h[0] & 0x04) /* 3 bits ref */ return 1; return h[0] & 3; } if (h[0] & 0x08) /* 3 bits ref */ return 1; return (h[0] >> 1) & 3; } static void handle_vp9 (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { (void)this_gen; /* !@$%*#~ undocumented multiframe feature */ do { uint8_t mfhead; uint8_t *l; int mfframes, i; size_t mfbytes, mfsize; if (!data_len) return; mfhead = data[data_len - 1]; if ((mfhead & 0xe0) != 0xc0) break; mfframes = (mfhead & 7) + 1; mfbytes = ((mfhead >> 3) & 3) + 1; mfsize = mfframes * mfbytes + 2; if (mfsize > data_len) break; l = data + data_len - mfsize; if (*l++ != mfhead) break; data_len -= mfsize; data_duration /= mfframes; for (i = 0; i < mfframes; i++) { size_t flen = *l++; if (mfbytes > 1) flen += (size_t)(*l++) << 8; if (mfbytes > 2) flen += (size_t)(*l++) << 16; if (mfbytes > 3) flen += (size_t)(*l++) << 24; if (flen > data_len) flen = data_len; if (flen) { /* Nasty kludge: take invisible frames out of pts sequence. * A conventional b-frame sequence looks like this: * I1 P1 B1 B2 B3 P2 B4 ... * after reordering: * I1 B1 B2 B3 P1 B4 ... P2 * VP9 now avoids reordering and storing both dts and pts * by adding "P" as "invisible" to a (multiframe group): * I1 (P1 B1) B2 B3 (P2 B4) ... * "B3" usually is very small, and yields a quite verbatim copy of "P1", * which does not stay completely hidden this way. */ int64_t pts = data_pts; int type = vp9_frametype (data); if (type & 2) decoder_flags &= ~BUF_FLAG_KEYFRAME; else decoder_flags |= BUF_FLAG_KEYFRAME; if (type & 1) { /* visible */ if (!pts) pts = track->delayed_pts; track->delayed_pts = data_pts = 0; } else { /* invisible */ pts = 0; track->delayed_pts = data_pts; } _x_demux_send_data (track->fifo, data, flen, pts, track->buf_type, decoder_flags, input_normpos, input_time, data_duration, 0); data += flen; data_len -= flen; } } return; } while (0); { int64_t pts = data_pts; int type = vp9_frametype (data); if (type & 2) decoder_flags &= ~BUF_FLAG_KEYFRAME; else decoder_flags |= BUF_FLAG_KEYFRAME; if (type & 1) { /* visible */ if (!pts) pts = track->delayed_pts; track->delayed_pts = data_pts = 0; } else { /* invisible */ pts = 0; track->delayed_pts = data_pts; } _x_demux_send_data (track->fifo, data, data_len, pts, track->buf_type, decoder_flags, input_normpos, input_time, data_duration, 0); } } static int uncompress_zlib(demux_matroska_t *this, const uint8_t *data, size_t data_len, uint8_t **out_data, size_t *out_data_len) { z_stream zstream; uint8_t *dest; int result; *out_data = NULL; memset(&zstream, 0, sizeof(zstream)); zstream.zalloc = (alloc_func) 0; zstream.zfree = (free_func) 0; zstream.opaque = (voidpf) 0; if (inflateInit (&zstream) != Z_OK) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: zlib inflateInit failed.\n"); return -1; } zstream.next_in = (Bytef *)data; zstream.avail_in = data_len; dest = (uint8_t *)malloc(data_len); zstream.avail_out = data_len; do { data_len += 4000; dest = (uint8_t *)realloc(dest, data_len); zstream.next_out = (Bytef *)(dest + zstream.total_out); result = inflate (&zstream, Z_NO_FLUSH); if ((result != Z_OK) && (result != Z_STREAM_END)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: zlib decompression failed: %d\n", result); free(dest); inflateEnd(&zstream); return 0; } zstream.avail_out += 4000; } while ((zstream.avail_out == 4000) && (zstream.avail_in != 0) && (result != Z_STREAM_END)); *out_data = dest; *out_data_len = zstream.total_out; inflateEnd(&zstream); return 1; } /* Note: This function assumes that the VobSub track is compressed with zlib. * This is not necessarily true - or not enough. The Matroska 'content * encoding' elements allow for a layer of changes applied to the contents, * e.g. compression or encryption. Anyway, only zlib compression is used * at the moment, and everyone compresses the VobSubs. */ static void handle_vobsub (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { demux_matroska_t *this = (demux_matroska_t *) this_gen; buf_element_t *buf; uint8_t *new_data = NULL; size_t new_data_len = 0; (void)data_duration; if (track->compress_algo == MATROSKA_COMPRESS_ZLIB || track->compress_algo == MATROSKA_COMPRESS_UNKNOWN) { if (uncompress_zlib(this, data, data_len, &new_data, &new_data_len) < 0) { return; } if (!new_data) { if (track->compress_algo == MATROSKA_COMPRESS_UNKNOWN) { track->compress_algo = MATROSKA_COMPRESS_NONE; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: VobSub: falling back to uncompressed mode.\n"); } else { return; } } else { track->compress_algo = MATROSKA_COMPRESS_ZLIB; data = new_data; data_len = new_data_len; } } else { lprintf("VobSub: track %d isn't compressed (%zu bytes)\n", (int)track->track_num, data_len); } buf = track->fifo->buffer_pool_size_alloc(track->fifo, data_len); if ((size_t)buf->max_size >= data_len) { buf->decoder_flags = decoder_flags | BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_VOBSUB_PACKAGE; buf->type = track->buf_type; buf->size = data_len; xine_fast_memcpy(buf->content, data, data_len); buf->extra_info->input_normpos = input_normpos; buf->extra_info->input_time = input_time; buf->extra_info->total_time = this->duration; buf->pts = data_pts; track->fifo->put(track->fifo, buf); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: VobSub: data length is greater than fifo buffer length\n"); buf->free_buffer(buf); } free(new_data); } static void handle_dvbsub (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { demux_matroska_t *this = (demux_matroska_t *) this_gen; uint8_t *new_data = NULL; size_t new_data_len = 0; (void)data_duration; if (track->compress_algo == MATROSKA_COMPRESS_ZLIB) { uncompress_zlib(this, data, data_len, &new_data, &new_data_len); if (!new_data) return; data = new_data; data_len = new_data_len; } /* hmm ... */ buf_element_t *buf = track->fifo->buffer_pool_alloc(track->fifo); buf->decoder_info[2] = data_len + 2; buf->size = 2; buf->pts = data_pts; buf->content[0] = 0x20; buf->content[1] = 0x00; buf->type = track->buf_type; track->fifo->put(track->fifo, buf); _x_demux_send_data(track->fifo, data, data_len, data_pts, track->buf_type, decoder_flags, input_normpos, input_time, 0, 0); free(new_data); } static void handle_hdmv_pgs (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { demux_matroska_t *this = (demux_matroska_t *) this_gen; uint8_t *new_data = NULL; size_t new_data_len = 0; (void)data_duration; if (track->compress_algo == MATROSKA_COMPRESS_ZLIB) { uncompress_zlib(this, data, data_len, &new_data, &new_data_len); if (!new_data) return; data = new_data; data_len = new_data_len; } _x_demux_send_data(track->fifo, data, data_len, data_pts, track->buf_type, decoder_flags, input_normpos, input_time, 0, 0); free(new_data); } static void handle_hdmv_textst (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time) { buf_element_t *buf; uint32_t *val; char *dest; int dest_len; int dest_pos; int i; uint8_t *ptr; int palette_update_flag; int num_regions; (void)this_gen; (void)data_len; (void)input_normpos; (void)input_time; ptr = data; if (*ptr != 0x82) { lprintf("Not a dialog presentation segment\n"); return; } ++ptr; // Skip length and start/end pts values ptr += 12; palette_update_flag = *ptr++; if (palette_update_flag) { lprintf("Dunno what to do with palette updates\n"); return; } buf = track->fifo->buffer_pool_alloc(track->fifo); buf->type = track->buf_type; buf->decoder_flags = decoder_flags | BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_CHARSET_ENCODING; buf->decoder_info_ptr[2] = buf->content + buf->max_size - LITERAL_UTF_8_SIZE; buf->decoder_info[2] = LITERAL_UTF_8_LEN; memcpy (buf->decoder_info_ptr[2], "utf-8", LITERAL_UTF_8_SIZE); val = (uint32_t *)buf->content; *val++ = data_pts / 90; /* start time */ *val++ = (data_pts + data_duration) / 90; /* end time */ dest = buf->content + 8; dest_len = buf->max_size - 8 - LITERAL_UTF_8_SIZE; dest_pos = 0; num_regions = *ptr++; for (i = 0; i < num_regions; ++i) { int length; uint8_t *end; // skip flags and style id reference ptr += 2; length = (ptr[0]<<8) | ptr[1]; ptr += 2; end = ptr + length; while (ptr < end && dest_pos < dest_len - 2) { int marker; int type; int length; marker = *ptr++; if (marker != 0x1B) continue; type = *ptr++; length = *ptr++; if (type == 0x01) { int k; for (k = 0; k < length && dest_pos < dest_len - 1; ++k) dest[dest_pos++] = ptr[k]; } else if (type == 0x0A) { dest[dest_pos++] = '\n'; } else { lprintf("Unknown TextST data %02X\n", type); } ptr += length; } } dest[dest_pos] = 0; track->fifo->put(track->fifo, buf); } static void fill_extra_data(matroska_track_t *track, uint32_t fourcc) { xine_bmiheader *bih; if (track->codec_private_len > 0x7fffffff - sizeof(xine_bmiheader)) track->codec_private_len = 0x7fffffff - sizeof(xine_bmiheader); /* create a bitmap info header struct */ bih = calloc(1, sizeof(xine_bmiheader) + track->codec_private_len); if (!bih) return; bih->biSize = sizeof(xine_bmiheader) + track->codec_private_len; bih->biCompression = fourcc; if (track->video_track) { bih->biWidth = track->video_track->pixel_width; bih->biHeight = track->video_track->pixel_height; } /* this is to be passed to decoder in native machine endian */ /* (no _x_bmiheader_le2me(bih);) */ /* add bih extra data */ if (track->codec_private_len > 0) memcpy(bih + 1, track->codec_private, track->codec_private_len); free(track->codec_private); track->codec_private = (uint8_t *)bih; track->codec_private_len = bih->biSize; } static int parse_track_entry(demux_matroska_t *this, matroska_track_t *track) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; while (next_level == this_level) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_TR_NUMBER: { uint64_t num; lprintf("TrackNumber\n"); if (!ebml_read_uint(ebml, &elem, &num)) return 0; track->track_num = num; } break; case MATROSKA_ID_TR_TYPE: { uint64_t num; lprintf("TrackType\n"); if (!ebml_read_uint(ebml, &elem, &num)) return 0; track->track_type = num; } break; case MATROSKA_ID_TR_CODECID: { char *codec_id = ebml_alloc_read_ascii (ebml, &elem); lprintf("CodecID\n"); if (!codec_id) return 0; track->codec_id = codec_id; } break; case MATROSKA_ID_TR_CODECPRIVATE: { uint8_t *codec_private; if (elem.len >= 0x80000000) return 0; codec_private = malloc (elem.len); if (! codec_private) return 0; lprintf("CodecPrivate\n"); if (!ebml_read_binary(ebml, &elem, codec_private)) { free(codec_private); return 0; } track->codec_private = codec_private; track->codec_private_len = elem.len; } break; case MATROSKA_ID_TR_LANGUAGE: { char *language = ebml_alloc_read_ascii (ebml, &elem); lprintf("Language\n"); if (!language) return 0; track->language = language; } break; case MATROSKA_ID_TV: lprintf("Video\n"); if (track->video_track) return 1; track->video_track = (matroska_video_track_t *)calloc(1, sizeof(matroska_video_track_t)); if (!track->video_track) return 0; if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_video_track(this, track->video_track)) return 0; break; case MATROSKA_ID_TA: lprintf("Audio\n"); if (track->audio_track) return 1; track->audio_track = (matroska_audio_track_t *)calloc(1, sizeof(matroska_audio_track_t)); if (!track->audio_track) return 0; if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_audio_track(this, track->audio_track)) return 0; break; case MATROSKA_ID_TR_FLAGDEFAULT: { uint64_t val; lprintf("Default\n"); if (!ebml_read_uint(ebml, &elem, &val)) return 0; track->default_flag = (int)val; } break; case MATROSKA_ID_TR_DEFAULTDURATION: { uint64_t val; if (!ebml_read_uint(ebml, &elem, &val)) return 0; track->default_duration = val; lprintf("Default Duration: %"PRIu64"\n", track->default_duration); } break; case MATROSKA_ID_CONTENTENCODINGS: { lprintf("ContentEncodings\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_content_encodings(this, track)) return 0; } break; case MATROSKA_ID_TR_UID: { uint64_t val; if (!ebml_read_uint(ebml, &elem, &val)) { lprintf("Track UID (invalid)\n"); return 0; } track->uid = val; lprintf("Track UID: 0x%" PRIx64 "\n", track->uid); } break; case MATROSKA_ID_TR_FLAGENABLED: case MATROSKA_ID_TR_FLAGLACING: case MATROSKA_ID_TR_MINCACHE: case MATROSKA_ID_TR_MAXCACHE: case MATROSKA_ID_TR_TIMECODESCALE: case MATROSKA_ID_TR_NAME: case MATROSKA_ID_TR_CODECNAME: case MATROSKA_ID_TR_CODECSETTINGS: case MATROSKA_ID_TR_CODECINFOURL: case MATROSKA_ID_TR_CODECDOWNLOADURL: case MATROSKA_ID_TR_CODECDECODEALL: case MATROSKA_ID_TR_OVERLAY: default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) { return 0; } } next_level = ebml_get_next_level(ebml, &elem); } xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: Track %d, %s %s\n", track->track_num, (track->codec_id ? track->codec_id : ""), (track->language ? track->language : "")); if (track->codec_id) { void (*init_codec)(demux_matroska_t *, matroska_track_t *) = NULL; if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_VFW_FOURCC)) { xine_bmiheader *bih; if (track->codec_private_len >= sizeof(xine_bmiheader)) { lprintf("MATROSKA_CODEC_ID_V_VFW_FOURCC\n"); bih = (xine_bmiheader*)track->codec_private; _x_bmiheader_le2me(bih); track->buf_type = _x_fourcc_to_buf_video(bih->biCompression); if (!track->buf_type) _x_report_video_fourcc (this->stream->xine, LOG_MODULE, bih->biCompression); init_codec = init_codec_video; } } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_UNCOMPRESSED)) { } else if ((!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG4_SP)) || (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG4_ASP)) || (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG4_AP))) { lprintf("MATROSKA_CODEC_ID_V_MPEG4_*\n"); fill_extra_data(track, ME_FOURCC('M', 'P', '4', 'S')); track->buf_type = BUF_VIDEO_MPEG4; /* init as a vfw decoder */ init_codec = init_codec_video; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG4_AVC)) { lprintf("MATROSKA_CODEC_ID_V_MPEG4_AVC\n"); fill_extra_data(track, ME_FOURCC('a', 'v', 'c', '1')); track->buf_type = BUF_VIDEO_H264; /* init as a vfw decoder */ init_codec = init_codec_video; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MSMPEG4V3)) { track->buf_type = BUF_VIDEO_MSMPEG4_V3; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG1)) { lprintf("MATROSKA_CODEC_ID_V_MPEG1\n"); track->buf_type = BUF_VIDEO_MPEG; init_codec = init_codec_video; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MPEG2)) { lprintf("MATROSKA_CODEC_ID_V_MPEG2\n"); track->buf_type = BUF_VIDEO_MPEG; init_codec = init_codec_video; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_VP8)) { lprintf("MATROSKA_CODEC_ID_V_VP8\n"); fill_extra_data(track, ME_FOURCC('v', 'p', '8', '0')); track->buf_type = BUF_VIDEO_VP8; init_codec = init_codec_video; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_VP9)) { lprintf("MATROSKA_CODEC_ID_V_VP9\n"); fill_extra_data(track, ME_FOURCC('v', 'p', '9', '0')); track->buf_type = BUF_VIDEO_VP9; init_codec = init_codec_video; track->handle_content = handle_vp9; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_HEVC)) { lprintf("MATROSKA_CODEC_ID_V_HEVC\n"); fill_extra_data(track, ME_FOURCC('h', 'e', 'v', 'c')); track->buf_type = BUF_VIDEO_HEVC; init_codec = init_codec_video; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_AV1)) { lprintf("MATROSKA_CODEC_ID_V_AV1\n"); fill_extra_data(track, ME_FOURCC('a', 'v', '1', '0')); track->buf_type = BUF_VIDEO_AV1; init_codec = init_codec_video; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_REAL_RV10)) { } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_REAL_RV20)) { } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_REAL_RV30)) { lprintf("MATROSKA_CODEC_ID_V_REAL_RV30\n"); track->buf_type = BUF_VIDEO_RV30; track->handle_content = handle_realvideo; init_codec = init_codec_real; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_REAL_RV40)) { lprintf("MATROSKA_CODEC_ID_V_REAL_RV40\n"); track->buf_type = BUF_VIDEO_RV40; track->handle_content = handle_realvideo; init_codec = init_codec_real; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_MJPEG)) { } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_V_THEORA)) { lprintf("MATROSKA_CODEC_ID_V_THEORA\n"); track->buf_type = BUF_VIDEO_THEORA_RAW; init_codec = init_codec_xiph; } else if ((!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_MPEG1_L1)) || (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_MPEG1_L2)) || (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_MPEG1_L3))) { lprintf("MATROSKA_CODEC_ID_A_MPEG1\n"); track->buf_type = BUF_AUDIO_MPEG; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_PCM_INT_BE)) { lprintf("MATROSKA_CODEC_ID_A_PCM_INT_BE"); track->buf_type = BUF_AUDIO_LPCM_BE; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_PCM_INT_LE)) { lprintf("MATROSKA_CODEC_ID_A_PCM_INT_LE"); track->buf_type = BUF_AUDIO_LPCM_LE; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_PCM_FLOAT)) { } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_AC3)) { lprintf("MATROSKA_CODEC_ID_A_AC3\n"); track->buf_type = BUF_AUDIO_A52; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_EAC3)) { lprintf("MATROSKA_CODEC_ID_A_EAC3\n"); track->buf_type = BUF_AUDIO_EAC3; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_TRUEHD)) { lprintf("MATROSKA_CODEC_ID_A_TRUEHD\n"); track->buf_type = BUF_AUDIO_TRUEHD; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_FLAC)) { lprintf("MATROSKA_CODEC_ID_A_FLAC\n"); track->buf_type = BUF_AUDIO_FLAC; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_DTS)) { lprintf("MATROSKA_CODEC_ID_A_DTS\n"); track->buf_type = BUF_AUDIO_DTS; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_VORBIS)) { lprintf("MATROSKA_CODEC_ID_A_VORBIS\n"); track->buf_type = BUF_AUDIO_VORBIS; init_codec = init_codec_xiph; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_OPUS)) { lprintf("MATROSKA_CODEC_ID_A_OPUS\n"); track->buf_type = BUF_AUDIO_OPUS; init_codec = init_codec_audio; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_ACM)) { xine_waveformatex *wfh; lprintf("MATROSKA_CODEC_ID_A_ACM\n"); if (track->codec_private_len >= sizeof(xine_waveformatex)) { wfh = (xine_waveformatex*)track->codec_private; _x_waveformatex_le2me(wfh); track->buf_type = _x_formattag_to_buf_audio(wfh->wFormatTag); if (!track->buf_type) _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, wfh->wFormatTag); init_codec = init_codec_audio; } } else if (!strncmp(track->codec_id, MATROSKA_CODEC_ID_A_AAC, sizeof(MATROSKA_CODEC_ID_A_AAC) - 1)) { lprintf("MATROSKA_CODEC_ID_A_AAC\n"); track->buf_type = BUF_AUDIO_AAC; init_codec = init_codec_aac; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_REAL_14_4)) { } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_REAL_28_8)) { } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_REAL_COOK)) { lprintf("MATROSKA_CODEC_ID_A_REAL_COOK\n"); track->buf_type = BUF_AUDIO_COOK; init_codec = init_codec_real; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_REAL_SIPR)) { lprintf("MATROSKA_CODEC_ID_A_REAL_SIPR\n"); track->buf_type = BUF_AUDIO_SIPRO; init_codec = init_codec_real; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_REAL_RALF)) { } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_A_REAL_ATRC)) { lprintf("MATROSKA_CODEC_ID_A_REAL_ATRC\n"); track->buf_type = BUF_AUDIO_ATRK; init_codec = init_codec_real; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_TEXT_UTF8) || !strcmp(track->codec_id, MATROSKA_CODEC_ID_S_UTF8)) { lprintf("MATROSKA_CODEC_ID_S_TEXT_UTF8\n"); track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_utf8; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_TEXT_SSA) || !strcmp(track->codec_id, MATROSKA_CODEC_ID_S_SSA)) { lprintf("MATROSKA_CODEC_ID_S_TEXT_SSA\n"); track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_ssa; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_TEXT_ASS) || !strcmp(track->codec_id, MATROSKA_CODEC_ID_S_ASS)) { lprintf("MATROSKA_CODEC_ID_S_TEXT_ASS\n"); track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_ssa; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_TEXT_USF)) { lprintf("MATROSKA_CODEC_ID_S_TEXT_USF\n"); track->buf_type = BUF_SPU_OGM; track->handle_content = handle_sub_utf8; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_DVBSUB)) { lprintf("MATROSKA_CODEC_ID_S_DVBSUB\n"); track->buf_type = BUF_SPU_DVB; track->handle_content = handle_dvbsub; init_codec = init_codec_dvbsub; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_VOBSUB)) { lprintf("MATROSKA_CODEC_ID_S_VOBSUB\n"); track->buf_type = BUF_SPU_DVD; track->handle_content = handle_vobsub; init_codec = init_codec_vobsub; /* Enable autodetection of the zlib compression, unless it was * explicitely set. Most vobsubs are compressed with zlib but * are not declared as such. */ if (track->compress_algo == MATROSKA_COMPRESS_NONE) { track->compress_algo = MATROSKA_COMPRESS_UNKNOWN; } } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_HDMV_PGS)) { lprintf("MATROSKA_CODEC_ID_S_HDMV_PGS\n"); track->buf_type = BUF_SPU_HDMV; track->handle_content = handle_hdmv_pgs; init_codec = init_codec_spu; } else if (!strcmp(track->codec_id, MATROSKA_CODEC_ID_S_HDMV_TEXTST)) { lprintf("MATROSKA_CODEC_ID_S_HDMV_TEXTST\n"); track->buf_type = BUF_SPU_OGM; track->handle_content = handle_hdmv_textst; init_codec = init_codec_spu; } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "unknown codec %s\n", track->codec_id); } if (track->buf_type) { switch(track->track_type) { case MATROSKA_TRACK_VIDEO: track->fifo = this->stream->video_fifo; track->buf_type |= this->num_video_tracks; this->num_video_tracks++; break; case MATROSKA_TRACK_AUDIO: track->fifo = this->stream->audio_fifo; track->buf_type |= this->num_audio_tracks; this->num_audio_tracks++; break; case MATROSKA_TRACK_SUBTITLE: track->fifo = this->stream->video_fifo; track->buf_type |= this->num_sub_tracks; this->num_sub_tracks++; break; case MATROSKA_TRACK_COMPLEX: case MATROSKA_TRACK_LOGO: case MATROSKA_TRACK_CONTROL: break; } if (init_codec) { if (! track->fifo) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: Error: fifo not set up for track of type type %" PRIu32 "\n", track->track_type); return 0; } init_codec(this, track); } } } return 1; } static int parse_tracks(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; while (next_level == this_level) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_TR_ENTRY: { matroska_track_t *track; /* bail out early if no more tracks can be handled! */ if (this->num_tracks >= MAX_STREAMS) { lprintf("Too many tracks!\n"); return 0; } /* alloc and initialize a track with 0 */ track = calloc(1, sizeof(matroska_track_t)); if (!track) return 0; track->compress_algo = MATROSKA_COMPRESS_NONE; this->tracks[this->num_tracks] = track; lprintf("TrackEntry\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_track_entry(this, track)) return 0; this->num_tracks++; } break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_cue_trackposition(demux_matroska_t *this, int *track_num, int64_t *pos) { ebml_parser_t *ebml = this->ebml; int next_level = 4; while (next_level == 4) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CU_TRACK: { uint64_t num; lprintf("CueTrackpositionTrack\n"); if (!ebml_read_uint(ebml, &elem, &num)) return 0; *track_num = num; break; } case MATROSKA_ID_CU_CLUSTERPOSITION: { uint64_t num; lprintf("CueTrackpositionClusterposition\n"); if (!ebml_read_uint(ebml, &elem, &num)) return 0; *pos = this->segment.start + num; break; } default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_cue_point(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 3; int64_t timecode = -1, pos = -1; int track_num = -1; while (next_level == 3) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CU_TIME: { uint64_t num; lprintf("CueTime\n"); if (!ebml_read_uint(ebml, &elem, &num)) return 0; timecode = num; break; } case MATROSKA_ID_CU_TRACKPOSITION: lprintf("CueTrackPosition\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_cue_trackposition(this, &track_num, &pos)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } if ((timecode != -1) && (track_num != -1) && (pos != -1)) { matroska_index_t *index; int i; index = NULL; for (i = 0; i < this->num_indexes; i++) if (this->indexes[i].track_num == track_num) { index = &this->indexes[i]; break; } if (index == NULL) { this->indexes = (matroska_index_t *)realloc(this->indexes, (this->num_indexes + 1) * sizeof(matroska_index_t)); memset(&this->indexes[this->num_indexes], 0, sizeof(matroska_index_t)); index = &this->indexes[this->num_indexes]; index->track_num = track_num; this->num_indexes++; } if ((index->num_entries % 1024) == 0) { index->pos = realloc(index->pos, sizeof(off_t) * (index->num_entries + 1024)); index->timecode = realloc(index->timecode, sizeof(uint64_t) * (index->num_entries + 1024)); } index->pos[index->num_entries] = pos; index->timecode[index->num_entries] = timecode; index->num_entries++; } return 1; } static int parse_cues(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 2; while (next_level == 2) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CU_POINT: lprintf("CuePoint\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_cue_point(this)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_attachments(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 2; while (next_level == 2) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static int parse_tags(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 2; while (next_level == 2) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } static void alloc_block_data (demux_matroska_t *this, size_t len) { /* memory management */ if (this->block_data_size < len) { this->block_data = realloc(this->block_data, len); this->block_data_size = len; } } static int parse_ebml_uint(demux_matroska_t *this, uint8_t *data, uint64_t *num) { uint8_t mask = 0x80; int size = 1; int i; /* compute the size of the "data len" (1-8 bytes) */ while (size <= 8 && !(data[0] & mask)) { size++; mask >>= 1; } if (size > 8) { off_t pos = this->input->get_current_pos(this->input); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: Invalid Track Number at position %" PRIdMAX "\n", (intmax_t)pos); return 0; } *num = data[0]; *num &= mask - 1; for (i = 1; i < size; i++) { *num = (*num << 8) | data[i]; } return size; } static int parse_ebml_sint(demux_matroska_t *this, uint8_t *data, int64_t *num) { uint64_t unum; int size; size = parse_ebml_uint(this, data, &unum); if (!size) return 0; /* formula taken from gstreamer demuxer */ if (unum == (uint64_t)-1) *num = -1; else *num = unum - ((1 << ((7 * size) - 1)) - 1); return size; } static int find_track_by_id(demux_matroska_t *this, int track_num, matroska_track_t **track) { int i; *track = NULL; for (i = 0; i < this->num_tracks; i++) { if (this->tracks[i]->track_num == track_num) { *track = this->tracks[i]; return 1; } } return 0; } static int read_block_data (demux_matroska_t *this, size_t len, size_t offset) { alloc_block_data(this, len + offset); /* block datas */ if (! this->block_data) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: memory allocation error\n"); return 0; } if (this->input->read (this->input, this->block_data + offset, len) != (int)len) { off_t pos = this->input->get_current_pos(this->input); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: read error at position %" PRIdMAX "\n", (intmax_t)pos); return 0; } return 1; } static int parse_int16(uint8_t *data) { int value = (int)_X_BE_16(data); if (value & 1<<15) { value -= 1<<16; } return value; } static int parse_block (demux_matroska_t *this, size_t block_size, uint64_t cluster_timecode, uint64_t block_duration, int normpos, int is_key) { matroska_track_t *track; uint64_t track_num; uint8_t *data; uint8_t flags; int lacing; unsigned int num_len; int16_t timecode_diff; int64_t pts, xduration; int decoder_flags = 0; size_t headers_len = 0; data = this->block_data + this->compress_maxlen; if (!(num_len = parse_ebml_uint(this, data, &track_num))) return 0; data += num_len; /* timecode_diff is signed */ timecode_diff = (int16_t)parse_int16(data); data += 2; flags = *data; data += 1; lprintf("track_num: %" PRIu64 ", timecode_diff: %d, flags: 0x%x\n", track_num, timecode_diff, flags); /*gap = flags & 1;*/ lacing = (flags >> 1) & 0x3; lprintf("lacing: %x\n", lacing); if (!find_track_by_id(this, (int)track_num, &track)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: invalid track id: %" PRIu64 "\n", track_num); return 0; } pts = ((int64_t)cluster_timecode + timecode_diff) * (int64_t)this->timecode_scale * (int64_t)90 / (int64_t)1000000; /* After seeking we have to skip to the next key frame. */ if (this->skip_to_timecode > 0) { if ((this->skip_for_track != track->track_num) || !is_key || (pts < this->skip_to_timecode)) return 1; this->skip_to_timecode = 0; } if (block_duration) { xduration = (int64_t)block_duration * (int64_t)this->timecode_scale * (int64_t)90 / (int64_t)1000000; } else { block_duration = track->default_duration; xduration = (int64_t)block_duration * (int64_t)90 / (int64_t)1000000; } lprintf("pts: %" PRId64 ", duration: %" PRId64 "\n", pts, xduration); check_newpts(this, pts, track); if (this->preview_mode) { this->preview_sent++; decoder_flags |= BUF_FLAG_PREVIEW; } if (track->compress_algo == MATROSKA_COMPRESS_HEADER_STRIP) headers_len = track->compress_len; if (lacing == MATROSKA_NO_LACING) { size_t block_size_left; lprintf("no lacing\n"); if (is_key) decoder_flags |= BUF_FLAG_KEYFRAME; block_size_left = (this->block_data + block_size + this->compress_maxlen) - data; lprintf("size: %zu, block_size: %zu, block_offset: %zu\n", block_size_left, block_size, this->compress_maxlen); if (headers_len) { data -= headers_len; xine_fast_memcpy(data, track->compress_settings, headers_len); block_size_left += headers_len; } if (track->handle_content != NULL) { track->handle_content ((demux_plugin_t *)this, track, decoder_flags, data, block_size_left, pts, xduration, normpos, pts / 90); } else { _x_demux_send_data (track->fifo, data, block_size_left, pts, track->buf_type, decoder_flags, normpos, pts / 90, this->duration, 0); } } else { size_t block_size_left; uint8_t lace_num; size_t frame[MAX_FRAMES]; int i; /* number of laced frames */ lace_num = *data; data++; lprintf("lace_num: %d\n", lace_num); if ((lace_num + 1) > MAX_FRAMES) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: too many frames: %d\n", lace_num); return 0; } block_size_left = this->block_data + block_size + this->compress_maxlen - data; switch (lacing) { case MATROSKA_XIPH_LACING: { lprintf("xiph lacing\n"); /* size of each frame */ for (i = 0; i < lace_num; i++) { int size = 0; int partial_size; do { partial_size = *data; size += partial_size; data++; block_size_left--; } while (partial_size == 255); frame[i] = size; block_size_left -= size; } /* last frame */ frame[lace_num] = block_size_left; } break; case MATROSKA_FIXED_SIZE_LACING: { size_t frame_size; lprintf("fixed size lacing\n"); frame_size = block_size_left / (lace_num + 1); for (i = 0; i < lace_num; i++) { frame[i] = frame_size; } frame[lace_num] = block_size_left - ((size_t)lace_num * frame_size); block_size_left = 0; } break; case MATROSKA_EBML_LACING: { uint64_t first_frame_size; lprintf("ebml lacing\n"); /* size of each frame */ if (!(num_len = parse_ebml_uint(this, data, &first_frame_size))) return 0; if (num_len > block_size_left) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: block too small\n"); return 0; } if (first_frame_size > INT_MAX) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: invalid first frame size (%" PRIu64 ")\n", first_frame_size); return 0; } data += num_len; block_size_left -= num_len; frame[0] = (int) first_frame_size; lprintf("first frame len: %zu\n", frame[0]); block_size_left -= frame[0]; for (i = 1; i < lace_num; i++) { int64_t frame_size_diff; int64_t frame_size; if (!(num_len = parse_ebml_sint(this, data, &frame_size_diff))) return 0; if (num_len > block_size_left) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: block too small\n"); return 0; } data += num_len; block_size_left -= num_len; frame_size = frame[i-1] + frame_size_diff; if (frame_size > INT_MAX || frame_size < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: invalid frame size (%" PRId64 ")\n", frame_size); return 0; } frame[i] = frame_size; block_size_left -= frame[i]; } /* last frame */ frame[lace_num] = block_size_left; } break; default: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_matroska: invalid lacing: %d\n", lacing); return 0; } /* send each frame to the decoder */ for (i = 0; i <= lace_num; i++) { if (headers_len) { data -= headers_len; xine_fast_memcpy(data, track->compress_settings, headers_len); frame[i] += headers_len; } if (track->handle_content != NULL) { track->handle_content((demux_plugin_t *)this, track, decoder_flags, data, frame[i], pts, 0, normpos, pts / 90); } else { _x_demux_send_data(track->fifo, data, frame[i], pts, track->buf_type, decoder_flags, normpos, pts / 90, this->duration, 0); } data += frame[i]; pts = 0; } } return 1; } static int parse_simpleblock(demux_matroska_t *this, size_t block_len, uint64_t cluster_timecode, uint64_t block_duration) { off_t block_pos = 0; off_t file_len = 0; int normpos = 0; int is_key = 1; lprintf("simpleblock\n"); block_pos = this->input->get_current_pos(this->input); file_len = this->input->get_length(this->input); if( file_len ) normpos = (int) ( (double) block_pos * 65535 / file_len ); if (!read_block_data(this, block_len, this->compress_maxlen)) return 0; /* we have the duration, we can parse the block now */ if (!parse_block(this, block_len, cluster_timecode, block_duration, normpos, is_key)) return 0; return 1; } static int parse_block_group(demux_matroska_t *this, uint64_t cluster_timecode, uint64_t cluster_duration) { ebml_parser_t *ebml = this->ebml; int next_level = 3; int has_block = 0; uint64_t block_duration = 0; off_t block_pos = 0; off_t file_len = 0; int normpos = 0; size_t block_len = 0; int is_key = 1; (void)cluster_duration; while (next_level == 3) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CL_BLOCK: lprintf("block\n"); block_pos = this->input->get_current_pos(this->input); block_len = elem.len; file_len = this->input->get_length(this->input); if( file_len ) normpos = (int) ( (double) block_pos * 65535 / file_len ); if (!read_block_data(this, elem.len, this->compress_maxlen)) return 0; has_block = 1; break; case MATROSKA_ID_CL_BLOCKDURATION: /* should override track duration */ if (!ebml_read_uint(ebml, &elem, &block_duration)) return 0; lprintf("duration: %" PRIu64 "\n", block_duration); break; case MATROSKA_ID_CL_REFERENCEBLOCK: is_key = 0; if (!ebml_skip(ebml, &elem)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } if (!has_block) return 0; /* we have the duration, we can parse the block now */ if (!parse_block(this, block_len, cluster_timecode, block_duration, normpos, is_key)) return 0; return 1; } static int demux_matroska_seek (demux_plugin_t*, off_t, int, int); static void handle_events(demux_matroska_t *this) { xine_event_t* event; while ((event = xine_event_get(this->event_queue))) { if (this->num_editions > 0) { matroska_edition_t* ed = this->editions[0]; int chapter_idx = matroska_get_chapter(this, this->last_timecode, &ed); uint64_t next_time; if (chapter_idx < 0) { xine_event_free(event); continue; } switch(event->type) { case XINE_EVENT_INPUT_NEXT: if (chapter_idx < ed->num_chapters-1) { next_time = ed->chapters[chapter_idx+1]->time_start / 90; demux_matroska_seek((demux_plugin_t*)this, 0, next_time, 1); } break; /* TODO: should this try to implement common "start of chapter" * functionality? */ case XINE_EVENT_INPUT_PREVIOUS: if (chapter_idx > 0) { next_time = ed->chapters[chapter_idx-1]->time_start / 90; demux_matroska_seek((demux_plugin_t*)this, 0, next_time, 1); } break; default: break; } } xine_event_free(event); } } static int parse_cluster(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int this_level = ebml->level; int next_level = this_level; uint64_t timecode = 0; uint64_t duration = 0; if (!this->first_cluster_found) { int idx, entry; /* Scale the cues to ms precision. */ for (idx = 0; idx < this->num_indexes; idx++) { matroska_index_t *index = &this->indexes[idx]; for (entry = 0; entry < index->num_entries; entry++) index->timecode[entry] = index->timecode[entry] * this->timecode_scale / 1000000; } this->first_cluster_found = 1; } handle_events(this); while (next_level == this_level) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CL_TIMECODE: lprintf("timecode\n"); if (!ebml_read_uint(ebml, &elem, &timecode)) return 0; break; case MATROSKA_ID_CL_DURATION: lprintf("duration\n"); if (!ebml_read_uint(ebml, &elem, &duration)) return 0; break; case MATROSKA_ID_CL_BLOCKGROUP: lprintf("blockgroup\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_block_group(this, timecode, duration)) return 0; break; case MATROSKA_ID_CL_SIMPLEBLOCK: lprintf("simpleblock\n"); if (!parse_simpleblock(this, elem.len, timecode, duration)) return 0; break; case MATROSKA_ID_CL_BLOCK: lprintf("block\n"); if (!ebml_skip(ebml, &elem)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } /* at this point, we MUST have a timecode (according to format spec). * Use that to find the chapter we are in, and adjust the title. * * TODO: this only looks at the chapters in the first edition. */ this->last_timecode = timecode; if (this->num_editions <= 0) return 1; matroska_edition_t *ed = this->editions[0]; if (ed->num_chapters <= 0) return 1; /* fix up a makeshift title if none has been set yet (e.g. filename) */ if (NULL == this->title && NULL != _x_meta_info_get(this->stream, XINE_META_INFO_TITLE)) this->title = strdup(_x_meta_info_get(this->stream, XINE_META_INFO_TITLE)); if (NULL == this->title) this->title = strdup("(No title)"); if (NULL == this->title) { lprintf("Failed to determine a valid stream title!\n"); return 1; } int chapter_idx = matroska_get_chapter(this, timecode, &ed); if (chapter_idx < 0) { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, this->title); return 1; } xine_ui_data_t uidata = { .str = {0, }, .str_len = 0, }; uidata.str_len = snprintf(uidata.str, sizeof(uidata.str), "%s / (%d) %s", this->title, chapter_idx+1, ed->chapters[chapter_idx]->title); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, uidata.str); return 1; } static int parse_top_level_head(demux_matroska_t *this, int *next_level); static int parse_seek_entry(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 3; int has_id = 0; int has_position = 0; uint64_t id = 0; uint64_t pos; while (next_level == 3) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_S_ID: lprintf("SeekID\n"); if (!ebml_read_uint(ebml, &elem, &id)) return 0; has_id = 1; break; case MATROSKA_ID_S_POSITION: lprintf("SeekPosition\n"); if (!ebml_read_uint(ebml, &elem, &pos)) return 0; has_position = 1; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } /* do not parse clusters */ if (id == MATROSKA_ID_CLUSTER) { lprintf("skip cluster\n"); return 1; } /* parse the referenced element */ if (has_id && has_position) { off_t current_pos, seek_pos; seek_pos = this->segment.start + pos; if ((seek_pos > 0) && (seek_pos < this->input->get_length(this->input))) { ebml_parser_t ebml_bak; /* backup current state */ current_pos = this->input->get_current_pos(this->input); memcpy(&ebml_bak, this->ebml, sizeof(ebml_parser_t)); /* FIXME */ /* seek and parse the top_level element */ this->ebml->level = 1; if (this->input->seek(this->input, seek_pos, SEEK_SET) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_matroska: failed to seek to pos: %" PRIdMAX "\n", (intmax_t)seek_pos); return 0; } if (!parse_top_level_head(this, &next_level)) return 0; /* restore old state */ memcpy(this->ebml, &ebml_bak, sizeof(ebml_parser_t)); /* FIXME */ if (this->input->seek(this->input, current_pos, SEEK_SET) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_matroska: failed to seek to pos: %" PRIdMAX "\n", (intmax_t)current_pos); return 0; } } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_matroska: out of stream seek pos: %" PRIdMAX "\n", (intmax_t)seek_pos); } return 1; } else { lprintf("incomplete Seek Entry\n"); return 1; } } static int parse_seekhead(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 2; while (next_level == 2) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_S_ENTRY: lprintf("Seek Entry\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_seek_entry(this)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } /* * Function used to parse a top level when opening the file. * It does'nt parse clusters. * retuned value: * 0: error * 1: ok * 2: cluster */ static int parse_top_level_head(demux_matroska_t *this, int *next_level) { ebml_parser_t *ebml = this->ebml; ebml_elem_t elem; int ret_value = 1; off_t current_pos; current_pos = this->input->get_current_pos(this->input); lprintf("current_pos: %" PRIdMAX "\n", (intmax_t)current_pos); if (!ebml_read_elem_head(ebml, &elem)) return 0; if (!find_top_level_entry(this, current_pos)) { if (!add_top_level_entry(this, current_pos)) return 0; switch (elem.id) { case MATROSKA_ID_SEEKHEAD: lprintf("SeekHead\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_seekhead(this)) return 0; break; case MATROSKA_ID_INFO: lprintf("Info\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_info(this)) return 0; break; case MATROSKA_ID_TRACKS: lprintf("Tracks\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_tracks(this)) return 0; break; case MATROSKA_ID_CHAPTERS: lprintf("Chapters\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !matroska_parse_chapters(this)) return 0; break; case MATROSKA_ID_CLUSTER: lprintf("Slipping Cluster\n"); if (!ebml_skip(ebml, &elem)) return 0; ret_value = 2; break; case MATROSKA_ID_CUES: lprintf("Cues\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_cues(this)) return 0; break; case MATROSKA_ID_ATTACHMENTS: lprintf("Attachments\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_attachments(this)) return 0; break; case MATROSKA_ID_TAGS: lprintf("Tags\n"); if (!ebml_read_master (ebml, &elem)) return 0; if ((elem.len > 0) && !parse_tags(this)) return 0; break; default: lprintf("unknown top_level ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } } else { lprintf("top_level entry already parsed, ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } if (next_level) *next_level = ebml_get_next_level(ebml, &elem); return ret_value; } /* * Function used to parse a top level element during the playback. * It skips all elements except clusters. * Others elements should have been parsed before by the send_headers() function. */ static int parse_top_level(demux_matroska_t *this, int *next_level) { ebml_parser_t *ebml = this->ebml; ebml_elem_t elem; off_t cluster_pos, cluster_len; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_SEEKHEAD: lprintf("Skipping SeekHead\n"); if (!ebml_skip(ebml, &elem)) return 0; this->has_seekhead = 1; break; case MATROSKA_ID_INFO: lprintf("Skipping Info\n"); if (!ebml_skip(ebml, &elem)) return 0; break; case MATROSKA_ID_TRACKS: lprintf("Skipping Tracks\n"); if (!ebml_skip(ebml, &elem)) return 0; break; case MATROSKA_ID_CHAPTERS: lprintf("Skipping Chapters\n"); if (!ebml_skip(ebml, &elem)) return 0; break; case MATROSKA_ID_CLUSTER: lprintf("Cluster\n"); cluster_pos = this->input->get_current_pos(this->input); cluster_len = elem.len; if (!ebml_read_master (ebml, &elem)) return 0; if (!parse_cluster(this)) { off_t fail_pos = this->input->get_current_pos(this->input); off_t skip = cluster_pos + cluster_len - fail_pos; xprintf(ebml->xine, XINE_VERBOSITY_LOG, LOG_MODULE "parse_cluster failed ! Skipping %" PRId64 " bytes\n", (int64_t)skip); if (this->input->seek(ebml->input, skip, SEEK_CUR) < 0) { xprintf(ebml->xine, XINE_VERBOSITY_LOG, "seek error (skipping %" PRId64 " bytes)\n", (int64_t)skip); } } break; case MATROSKA_ID_CUES: lprintf("Skipping Cues\n"); if (!ebml_skip(ebml, &elem)) return 0; break; case MATROSKA_ID_ATTACHMENTS: lprintf("Skipping Attachments\n"); if (!ebml_skip(ebml, &elem)) return 0; break; case MATROSKA_ID_TAGS: lprintf("Skipping Tags\n"); if (!ebml_skip(ebml, &elem)) return 0; break; default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } if (next_level) *next_level = ebml_get_next_level(ebml, &elem); lprintf("parse_top_level() done\n"); return 1; } /* * Parse the mkv file structure. */ static int parse_segment(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; /* check segment id */ if (!ebml_read_elem_head(ebml, &this->segment)) return 0; if (this->segment.id == MATROSKA_ID_SEGMENT) { int res; int next_level; lprintf("Segment detected\n"); if (!ebml_read_master (ebml, &this->segment)) return 0; res = 1; next_level = 1; /* stop the loop on the first cluster */ while ((next_level == 1) && (res == 1)) { res = parse_top_level_head(this, &next_level); if (!res) return 0; } return 1; } else { /* not a segment */ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_matroska: invalid segment\n"); return 0; } } static int demux_matroska_send_chunk (demux_plugin_t *this_gen) { demux_matroska_t *this = (demux_matroska_t *) this_gen; int next_level; if (!parse_top_level(this, &next_level)) { this->status = DEMUX_FINISHED; } return this->status; } static int demux_matroska_get_status (demux_plugin_t *this_gen) { demux_matroska_t *this = (demux_matroska_t *) this_gen; return this->status; } static void demux_matroska_send_headers (demux_plugin_t *this_gen) { demux_matroska_t *this = (demux_matroska_t *) this_gen; int next_level; _x_demux_control_start (this->stream); if (!parse_segment(this)) this->status = DEMUX_FINISHED; else this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, (this->num_video_tracks != 0)); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->num_audio_tracks != 0)); /* * send preview buffers */ /* enter in the segment */ if (!ebml_read_master (this->ebml, &this->segment)) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_matroska: failed to read file header\n"); this->status = DEMUX_FINISHED; return; } /* seek back to the beginning of the segment */ next_level = 1; if (this->input->seek(this->input, this->segment.start, SEEK_SET) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_matroska: failed to seek to pos: %" PRIdMAX "\n", (intmax_t)this->segment.start); this->status = DEMUX_FINISHED; return; } this->preview_sent = 0; this->preview_mode = 1; while ((this->preview_sent < NUM_PREVIEW_BUFFERS) && (next_level == 1)) { if (!parse_top_level (this, &next_level)) { break; } } this->preview_mode = 0; /* seek back to the beginning of the segment */ next_level = 1; if (this->input->seek(this->input, this->segment.start, SEEK_SET) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_matroska: failed to seek to pos: %" PRIdMAX "\n", (intmax_t)this->segment.start); this->status = DEMUX_FINISHED; } } /* support function that performs a binary seek on a track; returns the * best index entry or -1 if the seek was beyond the end of the file */ static int binary_seek(matroska_index_t *index, off_t start_pos, int start_time) { int best_index; int left, middle, right; int found; uint32_t stime = start_time < 0 ? 0 : start_time; /* perform a binary search on the trak, testing the offset * boundaries first; offset request has precedent over time request */ if (start_pos) { if (start_pos <= index->pos[0]) best_index = 0; else if (start_pos >= index->pos[index->num_entries - 1]) best_index = index->num_entries - 1; else { left = 0; right = index->num_entries - 1; found = 0; while (!found) { middle = (left + right + 1) / 2; if ((start_pos >= index->pos[middle]) && (start_pos < index->pos[middle + 1])) found = 1; else if ((uint32_t)start_pos < index->pos[middle]) right = middle - 1; else left = middle; } best_index = middle; } } else { if (stime <= index->timecode[0]) best_index = 0; else if (stime >= index->timecode[index->num_entries - 1]) best_index = index->num_entries - 1; else { left = 0; right = index->num_entries - 1; do { middle = (left + right + 1) / 2; if (stime < index->timecode[middle]) right = (middle - 1); else left = middle; } while (left < right); best_index = left; } } return best_index; } static int demux_matroska_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_matroska_t *this = (demux_matroska_t *) this_gen; matroska_index_t *index; matroska_track_t *track; int i, entry; (void)playing; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); this->status = DEMUX_OK; /* engine sync stuff */ for (i = 0; i < this->num_tracks; i++) { this->tracks[i]->last_pts = 0; } this->send_newpts = 1; this->buf_flag_seek = 1; /* Seeking without an index is not supported yet. */ if (!this->num_indexes) return this->status; /* Find an index for a video track and use the first available index otherwise. */ index = NULL; for (i = 0; i < this->num_indexes; i++) { if (this->indexes[i].num_entries == 0) continue; if ((find_track_by_id(this, this->indexes[i].track_num, &track)) && (track->track_type == MATROSKA_TRACK_VIDEO)) { lprintf("video track found\n"); index = &this->indexes[i]; break; } } if (index == NULL) for (i = 0; i < this->num_indexes; i++) { if (this->indexes[i].num_entries == 0) continue; if (find_track_by_id(this, this->indexes[i].track_num, &track)) { index = &this->indexes[i]; break; } } /* No suitable index found. */ if (index == NULL) return this->status; entry = binary_seek(index, start_pos, start_time); if (entry == -1) { lprintf("seeking for track %d to %s %" PRIdMAX " - no entry found/EOS.\n", index->track_num, start_pos ? "pos" : "time", start_pos ? (intmax_t)start_pos : (intmax_t)start_time); this->status = DEMUX_FINISHED; } else { lprintf("seeking for track %d to %s %" PRIdMAX ". decision is #%d at %" PRIu64 "/%" PRIdMAX "\n", index->track_num, start_pos ? "pos" : "time", start_pos ? (intmax_t)start_pos : (intmax_t)start_time, index->track_num, index->timecode[entry], (intmax_t)index->pos[entry]); if (this->input->seek(this->input, index->pos[entry], SEEK_SET) < 0) this->status = DEMUX_FINISHED; /* we always seek to the ebml level 1 */ this->ebml->level = 1; this->skip_to_timecode = index->timecode[entry]; this->skip_for_track = track->track_num; _x_demux_flush_engine(this->stream); } return this->status; } static void demux_matroska_dispose (demux_plugin_t *this_gen) { demux_matroska_t *this = (demux_matroska_t *) this_gen; int i; _x_freep (&this->block_data); /* free tracks */ for (i = 0; i < this->num_tracks; i++) { matroska_track_t *const track = this->tracks[i]; _x_freep (&track->language); _x_freep (&track->codec_id); _x_freep (&track->codec_private); _x_freep (&track->video_track); _x_freep (&track->audio_track); _x_freep (&track->sub_track); _x_freep (&this->tracks[i]); } /* Free the cues. */ for (i = 0; i < this->num_indexes; i++) { _x_freep(&this->indexes[i].pos); _x_freep(&this->indexes[i].timecode); } _x_freep(&this->indexes); /* Free the top_level elem list */ _x_freep(&this->top_level_list); _x_freep(&this->title); matroska_free_editions(this); dispose_ebml_parser(this->ebml); xine_event_dispose_queue(this->event_queue); free (this); } static int demux_matroska_get_stream_length (demux_plugin_t *this_gen) { demux_matroska_t *this = (demux_matroska_t *) this_gen; return (int)this->duration; } static uint32_t demux_matroska_get_capabilities (demux_plugin_t *this_gen) { demux_matroska_t* this = (demux_matroska_t*)this_gen; uint32_t caps = DEMUX_CAP_SPULANG | DEMUX_CAP_AUDIOLANG; if(this->num_editions > 0 && this->editions[0]->num_chapters > 0) caps |= DEMUX_CAP_CHAPTERS; return caps; } static int demux_matroska_get_optional_data (demux_plugin_t *this_gen, void *data, int data_type) { demux_matroska_t *this = (demux_matroska_t *) this_gen; char *str = (char *) data; int channel = *((int *)data); int track_num; switch (data_type) { case DEMUX_OPTIONAL_DATA_SPULANG: lprintf ("DEMUX_OPTIONAL_DATA_SPULANG channel = %d\n",channel); if ((channel >= 0) && (channel < this->num_sub_tracks)) { for (track_num = 0; track_num < this->num_tracks; track_num++) { matroska_track_t *track = this->tracks[track_num]; if ((int)(track->buf_type & 0xFF00001F) == (BUF_SPU_BASE + channel)) { if (track->language) { strncpy (str, track->language, XINE_LANG_MAX); str[XINE_LANG_MAX - 1] = '\0'; if (strlen(track->language) >= XINE_LANG_MAX) /* the string got truncated */ str[XINE_LANG_MAX - 2] = str[XINE_LANG_MAX - 3] = str[XINE_LANG_MAX - 4] = '.'; } else { snprintf(str, XINE_LANG_MAX, "eng"); } return DEMUX_OPTIONAL_SUCCESS; } } } return DEMUX_OPTIONAL_UNSUPPORTED; case DEMUX_OPTIONAL_DATA_AUDIOLANG: lprintf ("DEMUX_OPTIONAL_DATA_AUDIOLANG channel = %d\n",channel); if ((channel >= 0) && (channel < this->num_audio_tracks)) { for (track_num = 0; track_num < this->num_tracks; track_num++) { matroska_track_t *track = this->tracks[track_num]; if ((int)(track->buf_type & 0xFF00001F) == (BUF_AUDIO_BASE + channel)) { if (track->language) { strncpy (str, track->language, XINE_LANG_MAX); str[XINE_LANG_MAX - 1] = '\0'; if (strlen(track->language) >= XINE_LANG_MAX) /* the string got truncated */ str[XINE_LANG_MAX - 2] = str[XINE_LANG_MAX - 3] = str[XINE_LANG_MAX - 4] = '.'; } else { snprintf(str, XINE_LANG_MAX, "eng"); } return DEMUX_OPTIONAL_SUCCESS; } } } return DEMUX_OPTIONAL_UNSUPPORTED; default: return DEMUX_OPTIONAL_UNSUPPORTED; } } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_matroska_t *this = NULL; ebml_parser_t *ebml = NULL; lprintf("trying to open %s...\n", input->get_mrl(input)); switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { if (!(input->get_capabilities (input) & INPUT_CAP_SEEKABLE)) return NULL; if (input->seek(input, 0, SEEK_SET) != 0) return NULL; ebml = new_ebml_parser(stream->xine, input); if (!ebml) goto error; if (!ebml_check_header(ebml)) goto error; } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } this = calloc(1, sizeof(demux_matroska_t)); if (!this) goto error; this->demux_plugin.send_headers = demux_matroska_send_headers; this->demux_plugin.send_chunk = demux_matroska_send_chunk; this->demux_plugin.seek = demux_matroska_seek; this->demux_plugin.dispose = demux_matroska_dispose; this->demux_plugin.get_status = demux_matroska_get_status; this->demux_plugin.get_stream_length = demux_matroska_get_stream_length; this->demux_plugin.get_capabilities = demux_matroska_get_capabilities; this->demux_plugin.get_optional_data = demux_matroska_get_optional_data; this->demux_plugin.demux_class = class_gen; this->input = input; this->status = DEMUX_FINISHED; this->stream = stream; if (!ebml) { ebml = new_ebml_parser(stream->xine, input); if (!ebml) goto error; if (!ebml_check_header(ebml)) goto error; } this->ebml = ebml; /* check header fields */ if (ebml->max_id_len > 4) goto error; if (ebml->max_size_len > 8) goto error; /* handle both Matroska and WebM here; we don't (presently) differentiate */ if (!ebml->doctype || (strcmp(ebml->doctype, "matroska") && strcmp(ebml->doctype, "webm"))) goto error; this->event_queue = xine_event_new_queue(this->stream); return &this->demux_plugin; error: dispose_ebml_parser(ebml); if (this != NULL && this->event_queue != NULL) { xine_event_dispose_queue(this->event_queue); } free(this); return NULL; } /* * demux matroska class */ void *demux_matroska_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_matroska_class = { .open_plugin = open_plugin, .description = N_("matroska & webm demux plugin"), .identifier = "matroska", .mimetypes = "video/mkv: mkv: matroska;" "video/x-matroska: mkv: matroska;" "video/webm: wbm,webm: WebM;", .extensions = "mkv wbm webm", .dispose = NULL, }; return (void *)&demux_matroska_class; } xine-lib-1.2/src/demuxers/qtpalette.h0000644000175000017500000002722014647725152015466 0ustar meme/* * Default Palettes for Quicktime Files * Automatically generated from a utility derived from XAnim: * http://xanim.va.pubnix.com/home.html */ #ifndef QTPALETTE_H #define QTPALETTE_H static const unsigned char qt_default_palette_4[4 * 4] = { 0x93, 0x65, 0x5E, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xDF, 0xD0, 0xAB, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char qt_default_palette_16[16 * 4] = { 0xFF, 0xFB, 0xFF, 0x00, 0xEF, 0xD9, 0xBB, 0x00, 0xE8, 0xC9, 0xB1, 0x00, 0x93, 0x65, 0x5E, 0x00, 0xFC, 0xDE, 0xE8, 0x00, 0x9D, 0x88, 0x91, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x47, 0x48, 0x37, 0x00, 0x7A, 0x5E, 0x55, 0x00, 0xDF, 0xD0, 0xAB, 0x00, 0xFF, 0xFB, 0xF9, 0x00, 0xE8, 0xCA, 0xC5, 0x00, 0x8A, 0x7C, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00 }; static const unsigned char qt_default_palette_256[256 * 4] = { /* 0, 0x00 */ 0xFF, 0xFF, 0xFF, 0x00, /* 1, 0x01 */ 0xFF, 0xFF, 0xCC, 0x00, /* 2, 0x02 */ 0xFF, 0xFF, 0x99, 0x00, /* 3, 0x03 */ 0xFF, 0xFF, 0x66, 0x00, /* 4, 0x04 */ 0xFF, 0xFF, 0x33, 0x00, /* 5, 0x05 */ 0xFF, 0xFF, 0x00, 0x00, /* 6, 0x06 */ 0xFF, 0xCC, 0xFF, 0x00, /* 7, 0x07 */ 0xFF, 0xCC, 0xCC, 0x00, /* 8, 0x08 */ 0xFF, 0xCC, 0x99, 0x00, /* 9, 0x09 */ 0xFF, 0xCC, 0x66, 0x00, /* 10, 0x0A */ 0xFF, 0xCC, 0x33, 0x00, /* 11, 0x0B */ 0xFF, 0xCC, 0x00, 0x00, /* 12, 0x0C */ 0xFF, 0x99, 0xFF, 0x00, /* 13, 0x0D */ 0xFF, 0x99, 0xCC, 0x00, /* 14, 0x0E */ 0xFF, 0x99, 0x99, 0x00, /* 15, 0x0F */ 0xFF, 0x99, 0x66, 0x00, /* 16, 0x10 */ 0xFF, 0x99, 0x33, 0x00, /* 17, 0x11 */ 0xFF, 0x99, 0x00, 0x00, /* 18, 0x12 */ 0xFF, 0x66, 0xFF, 0x00, /* 19, 0x13 */ 0xFF, 0x66, 0xCC, 0x00, /* 20, 0x14 */ 0xFF, 0x66, 0x99, 0x00, /* 21, 0x15 */ 0xFF, 0x66, 0x66, 0x00, /* 22, 0x16 */ 0xFF, 0x66, 0x33, 0x00, /* 23, 0x17 */ 0xFF, 0x66, 0x00, 0x00, /* 24, 0x18 */ 0xFF, 0x33, 0xFF, 0x00, /* 25, 0x19 */ 0xFF, 0x33, 0xCC, 0x00, /* 26, 0x1A */ 0xFF, 0x33, 0x99, 0x00, /* 27, 0x1B */ 0xFF, 0x33, 0x66, 0x00, /* 28, 0x1C */ 0xFF, 0x33, 0x33, 0x00, /* 29, 0x1D */ 0xFF, 0x33, 0x00, 0x00, /* 30, 0x1E */ 0xFF, 0x00, 0xFF, 0x00, /* 31, 0x1F */ 0xFF, 0x00, 0xCC, 0x00, /* 32, 0x20 */ 0xFF, 0x00, 0x99, 0x00, /* 33, 0x21 */ 0xFF, 0x00, 0x66, 0x00, /* 34, 0x22 */ 0xFF, 0x00, 0x33, 0x00, /* 35, 0x23 */ 0xFF, 0x00, 0x00, 0x00, /* 36, 0x24 */ 0xCC, 0xFF, 0xFF, 0x00, /* 37, 0x25 */ 0xCC, 0xFF, 0xCC, 0x00, /* 38, 0x26 */ 0xCC, 0xFF, 0x99, 0x00, /* 39, 0x27 */ 0xCC, 0xFF, 0x66, 0x00, /* 40, 0x28 */ 0xCC, 0xFF, 0x33, 0x00, /* 41, 0x29 */ 0xCC, 0xFF, 0x00, 0x00, /* 42, 0x2A */ 0xCC, 0xCC, 0xFF, 0x00, /* 43, 0x2B */ 0xCC, 0xCC, 0xCC, 0x00, /* 44, 0x2C */ 0xCC, 0xCC, 0x99, 0x00, /* 45, 0x2D */ 0xCC, 0xCC, 0x66, 0x00, /* 46, 0x2E */ 0xCC, 0xCC, 0x33, 0x00, /* 47, 0x2F */ 0xCC, 0xCC, 0x00, 0x00, /* 48, 0x30 */ 0xCC, 0x99, 0xFF, 0x00, /* 49, 0x31 */ 0xCC, 0x99, 0xCC, 0x00, /* 50, 0x32 */ 0xCC, 0x99, 0x99, 0x00, /* 51, 0x33 */ 0xCC, 0x99, 0x66, 0x00, /* 52, 0x34 */ 0xCC, 0x99, 0x33, 0x00, /* 53, 0x35 */ 0xCC, 0x99, 0x00, 0x00, /* 54, 0x36 */ 0xCC, 0x66, 0xFF, 0x00, /* 55, 0x37 */ 0xCC, 0x66, 0xCC, 0x00, /* 56, 0x38 */ 0xCC, 0x66, 0x99, 0x00, /* 57, 0x39 */ 0xCC, 0x66, 0x66, 0x00, /* 58, 0x3A */ 0xCC, 0x66, 0x33, 0x00, /* 59, 0x3B */ 0xCC, 0x66, 0x00, 0x00, /* 60, 0x3C */ 0xCC, 0x33, 0xFF, 0x00, /* 61, 0x3D */ 0xCC, 0x33, 0xCC, 0x00, /* 62, 0x3E */ 0xCC, 0x33, 0x99, 0x00, /* 63, 0x3F */ 0xCC, 0x33, 0x66, 0x00, /* 64, 0x40 */ 0xCC, 0x33, 0x33, 0x00, /* 65, 0x41 */ 0xCC, 0x33, 0x00, 0x00, /* 66, 0x42 */ 0xCC, 0x00, 0xFF, 0x00, /* 67, 0x43 */ 0xCC, 0x00, 0xCC, 0x00, /* 68, 0x44 */ 0xCC, 0x00, 0x99, 0x00, /* 69, 0x45 */ 0xCC, 0x00, 0x66, 0x00, /* 70, 0x46 */ 0xCC, 0x00, 0x33, 0x00, /* 71, 0x47 */ 0xCC, 0x00, 0x00, 0x00, /* 72, 0x48 */ 0x99, 0xFF, 0xFF, 0x00, /* 73, 0x49 */ 0x99, 0xFF, 0xCC, 0x00, /* 74, 0x4A */ 0x99, 0xFF, 0x99, 0x00, /* 75, 0x4B */ 0x99, 0xFF, 0x66, 0x00, /* 76, 0x4C */ 0x99, 0xFF, 0x33, 0x00, /* 77, 0x4D */ 0x99, 0xFF, 0x00, 0x00, /* 78, 0x4E */ 0x99, 0xCC, 0xFF, 0x00, /* 79, 0x4F */ 0x99, 0xCC, 0xCC, 0x00, /* 80, 0x50 */ 0x99, 0xCC, 0x99, 0x00, /* 81, 0x51 */ 0x99, 0xCC, 0x66, 0x00, /* 82, 0x52 */ 0x99, 0xCC, 0x33, 0x00, /* 83, 0x53 */ 0x99, 0xCC, 0x00, 0x00, /* 84, 0x54 */ 0x99, 0x99, 0xFF, 0x00, /* 85, 0x55 */ 0x99, 0x99, 0xCC, 0x00, /* 86, 0x56 */ 0x99, 0x99, 0x99, 0x00, /* 87, 0x57 */ 0x99, 0x99, 0x66, 0x00, /* 88, 0x58 */ 0x99, 0x99, 0x33, 0x00, /* 89, 0x59 */ 0x99, 0x99, 0x00, 0x00, /* 90, 0x5A */ 0x99, 0x66, 0xFF, 0x00, /* 91, 0x5B */ 0x99, 0x66, 0xCC, 0x00, /* 92, 0x5C */ 0x99, 0x66, 0x99, 0x00, /* 93, 0x5D */ 0x99, 0x66, 0x66, 0x00, /* 94, 0x5E */ 0x99, 0x66, 0x33, 0x00, /* 95, 0x5F */ 0x99, 0x66, 0x00, 0x00, /* 96, 0x60 */ 0x99, 0x33, 0xFF, 0x00, /* 97, 0x61 */ 0x99, 0x33, 0xCC, 0x00, /* 98, 0x62 */ 0x99, 0x33, 0x99, 0x00, /* 99, 0x63 */ 0x99, 0x33, 0x66, 0x00, /* 100, 0x64 */ 0x99, 0x33, 0x33, 0x00, /* 101, 0x65 */ 0x99, 0x33, 0x00, 0x00, /* 102, 0x66 */ 0x99, 0x00, 0xFF, 0x00, /* 103, 0x67 */ 0x99, 0x00, 0xCC, 0x00, /* 104, 0x68 */ 0x99, 0x00, 0x99, 0x00, /* 105, 0x69 */ 0x99, 0x00, 0x66, 0x00, /* 106, 0x6A */ 0x99, 0x00, 0x33, 0x00, /* 107, 0x6B */ 0x99, 0x00, 0x00, 0x00, /* 108, 0x6C */ 0x66, 0xFF, 0xFF, 0x00, /* 109, 0x6D */ 0x66, 0xFF, 0xCC, 0x00, /* 110, 0x6E */ 0x66, 0xFF, 0x99, 0x00, /* 111, 0x6F */ 0x66, 0xFF, 0x66, 0x00, /* 112, 0x70 */ 0x66, 0xFF, 0x33, 0x00, /* 113, 0x71 */ 0x66, 0xFF, 0x00, 0x00, /* 114, 0x72 */ 0x66, 0xCC, 0xFF, 0x00, /* 115, 0x73 */ 0x66, 0xCC, 0xCC, 0x00, /* 116, 0x74 */ 0x66, 0xCC, 0x99, 0x00, /* 117, 0x75 */ 0x66, 0xCC, 0x66, 0x00, /* 118, 0x76 */ 0x66, 0xCC, 0x33, 0x00, /* 119, 0x77 */ 0x66, 0xCC, 0x00, 0x00, /* 120, 0x78 */ 0x66, 0x99, 0xFF, 0x00, /* 121, 0x79 */ 0x66, 0x99, 0xCC, 0x00, /* 122, 0x7A */ 0x66, 0x99, 0x99, 0x00, /* 123, 0x7B */ 0x66, 0x99, 0x66, 0x00, /* 124, 0x7C */ 0x66, 0x99, 0x33, 0x00, /* 125, 0x7D */ 0x66, 0x99, 0x00, 0x00, /* 126, 0x7E */ 0x66, 0x66, 0xFF, 0x00, /* 127, 0x7F */ 0x66, 0x66, 0xCC, 0x00, /* 128, 0x80 */ 0x66, 0x66, 0x99, 0x00, /* 129, 0x81 */ 0x66, 0x66, 0x66, 0x00, /* 130, 0x82 */ 0x66, 0x66, 0x33, 0x00, /* 131, 0x83 */ 0x66, 0x66, 0x00, 0x00, /* 132, 0x84 */ 0x66, 0x33, 0xFF, 0x00, /* 133, 0x85 */ 0x66, 0x33, 0xCC, 0x00, /* 134, 0x86 */ 0x66, 0x33, 0x99, 0x00, /* 135, 0x87 */ 0x66, 0x33, 0x66, 0x00, /* 136, 0x88 */ 0x66, 0x33, 0x33, 0x00, /* 137, 0x89 */ 0x66, 0x33, 0x00, 0x00, /* 138, 0x8A */ 0x66, 0x00, 0xFF, 0x00, /* 139, 0x8B */ 0x66, 0x00, 0xCC, 0x00, /* 140, 0x8C */ 0x66, 0x00, 0x99, 0x00, /* 141, 0x8D */ 0x66, 0x00, 0x66, 0x00, /* 142, 0x8E */ 0x66, 0x00, 0x33, 0x00, /* 143, 0x8F */ 0x66, 0x00, 0x00, 0x00, /* 144, 0x90 */ 0x33, 0xFF, 0xFF, 0x00, /* 145, 0x91 */ 0x33, 0xFF, 0xCC, 0x00, /* 146, 0x92 */ 0x33, 0xFF, 0x99, 0x00, /* 147, 0x93 */ 0x33, 0xFF, 0x66, 0x00, /* 148, 0x94 */ 0x33, 0xFF, 0x33, 0x00, /* 149, 0x95 */ 0x33, 0xFF, 0x00, 0x00, /* 150, 0x96 */ 0x33, 0xCC, 0xFF, 0x00, /* 151, 0x97 */ 0x33, 0xCC, 0xCC, 0x00, /* 152, 0x98 */ 0x33, 0xCC, 0x99, 0x00, /* 153, 0x99 */ 0x33, 0xCC, 0x66, 0x00, /* 154, 0x9A */ 0x33, 0xCC, 0x33, 0x00, /* 155, 0x9B */ 0x33, 0xCC, 0x00, 0x00, /* 156, 0x9C */ 0x33, 0x99, 0xFF, 0x00, /* 157, 0x9D */ 0x33, 0x99, 0xCC, 0x00, /* 158, 0x9E */ 0x33, 0x99, 0x99, 0x00, /* 159, 0x9F */ 0x33, 0x99, 0x66, 0x00, /* 160, 0xA0 */ 0x33, 0x99, 0x33, 0x00, /* 161, 0xA1 */ 0x33, 0x99, 0x00, 0x00, /* 162, 0xA2 */ 0x33, 0x66, 0xFF, 0x00, /* 163, 0xA3 */ 0x33, 0x66, 0xCC, 0x00, /* 164, 0xA4 */ 0x33, 0x66, 0x99, 0x00, /* 165, 0xA5 */ 0x33, 0x66, 0x66, 0x00, /* 166, 0xA6 */ 0x33, 0x66, 0x33, 0x00, /* 167, 0xA7 */ 0x33, 0x66, 0x00, 0x00, /* 168, 0xA8 */ 0x33, 0x33, 0xFF, 0x00, /* 169, 0xA9 */ 0x33, 0x33, 0xCC, 0x00, /* 170, 0xAA */ 0x33, 0x33, 0x99, 0x00, /* 171, 0xAB */ 0x33, 0x33, 0x66, 0x00, /* 172, 0xAC */ 0x33, 0x33, 0x33, 0x00, /* 173, 0xAD */ 0x33, 0x33, 0x00, 0x00, /* 174, 0xAE */ 0x33, 0x00, 0xFF, 0x00, /* 175, 0xAF */ 0x33, 0x00, 0xCC, 0x00, /* 176, 0xB0 */ 0x33, 0x00, 0x99, 0x00, /* 177, 0xB1 */ 0x33, 0x00, 0x66, 0x00, /* 178, 0xB2 */ 0x33, 0x00, 0x33, 0x00, /* 179, 0xB3 */ 0x33, 0x00, 0x00, 0x00, /* 180, 0xB4 */ 0x00, 0xFF, 0xFF, 0x00, /* 181, 0xB5 */ 0x00, 0xFF, 0xCC, 0x00, /* 182, 0xB6 */ 0x00, 0xFF, 0x99, 0x00, /* 183, 0xB7 */ 0x00, 0xFF, 0x66, 0x00, /* 184, 0xB8 */ 0x00, 0xFF, 0x33, 0x00, /* 185, 0xB9 */ 0x00, 0xFF, 0x00, 0x00, /* 186, 0xBA */ 0x00, 0xCC, 0xFF, 0x00, /* 187, 0xBB */ 0x00, 0xCC, 0xCC, 0x00, /* 188, 0xBC */ 0x00, 0xCC, 0x99, 0x00, /* 189, 0xBD */ 0x00, 0xCC, 0x66, 0x00, /* 190, 0xBE */ 0x00, 0xCC, 0x33, 0x00, /* 191, 0xBF */ 0x00, 0xCC, 0x00, 0x00, /* 192, 0xC0 */ 0x00, 0x99, 0xFF, 0x00, /* 193, 0xC1 */ 0x00, 0x99, 0xCC, 0x00, /* 194, 0xC2 */ 0x00, 0x99, 0x99, 0x00, /* 195, 0xC3 */ 0x00, 0x99, 0x66, 0x00, /* 196, 0xC4 */ 0x00, 0x99, 0x33, 0x00, /* 197, 0xC5 */ 0x00, 0x99, 0x00, 0x00, /* 198, 0xC6 */ 0x00, 0x66, 0xFF, 0x00, /* 199, 0xC7 */ 0x00, 0x66, 0xCC, 0x00, /* 200, 0xC8 */ 0x00, 0x66, 0x99, 0x00, /* 201, 0xC9 */ 0x00, 0x66, 0x66, 0x00, /* 202, 0xCA */ 0x00, 0x66, 0x33, 0x00, /* 203, 0xCB */ 0x00, 0x66, 0x00, 0x00, /* 204, 0xCC */ 0x00, 0x33, 0xFF, 0x00, /* 205, 0xCD */ 0x00, 0x33, 0xCC, 0x00, /* 206, 0xCE */ 0x00, 0x33, 0x99, 0x00, /* 207, 0xCF */ 0x00, 0x33, 0x66, 0x00, /* 208, 0xD0 */ 0x00, 0x33, 0x33, 0x00, /* 209, 0xD1 */ 0x00, 0x33, 0x00, 0x00, /* 210, 0xD2 */ 0x00, 0x00, 0xFF, 0x00, /* 211, 0xD3 */ 0x00, 0x00, 0xCC, 0x00, /* 212, 0xD4 */ 0x00, 0x00, 0x99, 0x00, /* 213, 0xD5 */ 0x00, 0x00, 0x66, 0x00, /* 214, 0xD6 */ 0x00, 0x00, 0x33, 0x00, /* 215, 0xD7 */ 0xEE, 0x00, 0x00, 0x00, /* 216, 0xD8 */ 0xDD, 0x00, 0x00, 0x00, /* 217, 0xD9 */ 0xBB, 0x00, 0x00, 0x00, /* 218, 0xDA */ 0xAA, 0x00, 0x00, 0x00, /* 219, 0xDB */ 0x88, 0x00, 0x00, 0x00, /* 220, 0xDC */ 0x77, 0x00, 0x00, 0x00, /* 221, 0xDD */ 0x55, 0x00, 0x00, 0x00, /* 222, 0xDE */ 0x44, 0x00, 0x00, 0x00, /* 223, 0xDF */ 0x22, 0x00, 0x00, 0x00, /* 224, 0xE0 */ 0x11, 0x00, 0x00, 0x00, /* 225, 0xE1 */ 0x00, 0xEE, 0x00, 0x00, /* 226, 0xE2 */ 0x00, 0xDD, 0x00, 0x00, /* 227, 0xE3 */ 0x00, 0xBB, 0x00, 0x00, /* 228, 0xE4 */ 0x00, 0xAA, 0x00, 0x00, /* 229, 0xE5 */ 0x00, 0x88, 0x00, 0x00, /* 230, 0xE6 */ 0x00, 0x77, 0x00, 0x00, /* 231, 0xE7 */ 0x00, 0x55, 0x00, 0x00, /* 232, 0xE8 */ 0x00, 0x44, 0x00, 0x00, /* 233, 0xE9 */ 0x00, 0x22, 0x00, 0x00, /* 234, 0xEA */ 0x00, 0x11, 0x00, 0x00, /* 235, 0xEB */ 0x00, 0x00, 0xEE, 0x00, /* 236, 0xEC */ 0x00, 0x00, 0xDD, 0x00, /* 237, 0xED */ 0x00, 0x00, 0xBB, 0x00, /* 238, 0xEE */ 0x00, 0x00, 0xAA, 0x00, /* 239, 0xEF */ 0x00, 0x00, 0x88, 0x00, /* 240, 0xF0 */ 0x00, 0x00, 0x77, 0x00, /* 241, 0xF1 */ 0x00, 0x00, 0x55, 0x00, /* 242, 0xF2 */ 0x00, 0x00, 0x44, 0x00, /* 243, 0xF3 */ 0x00, 0x00, 0x22, 0x00, /* 244, 0xF4 */ 0x00, 0x00, 0x11, 0x00, /* 245, 0xF5 */ 0xEE, 0xEE, 0xEE, 0x00, /* 246, 0xF6 */ 0xDD, 0xDD, 0xDD, 0x00, /* 247, 0xF7 */ 0xBB, 0xBB, 0xBB, 0x00, /* 248, 0xF8 */ 0xAA, 0xAA, 0xAA, 0x00, /* 249, 0xF9 */ 0x88, 0x88, 0x88, 0x00, /* 250, 0xFA */ 0x77, 0x77, 0x77, 0x00, /* 251, 0xFB */ 0x55, 0x55, 0x55, 0x00, /* 252, 0xFC */ 0x44, 0x44, 0x44, 0x00, /* 253, 0xFD */ 0x22, 0x22, 0x22, 0x00, /* 254, 0xFE */ 0x11, 0x11, 0x11, 0x00, /* 255, 0xFF */ 0x00, 0x00, 0x00, 0x00 }; #endif xine-lib-1.2/src/demuxers/group_video.h0000644000175000017500000000372614647725152016012 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_GROUP_VIDEO_H #define HAVE_GROUP_VIDEO_H #include void *demux_avi_init_class (xine_t *xine, const void *data); void *demux_elem_init_class (xine_t *xine, const void *data); void *demux_flv_init_class (xine_t *xine, const void *data); void *demux_iff_init_class (xine_t *xine, const void *data); void *demux_ivf_init_class (xine_t *xine, const void *data); void *demux_matroska_init_class (xine_t *xine, const void *data); void *demux_mpeg_init_class (xine_t *xine, const void *data); void *demux_pes_init_class (xine_t *xine, const void *data); void *demux_mpeg_block_init_class (xine_t *xine, const void *data); void *demux_qt_init_class (xine_t *xine, const void *data); void *demux_rawdv_init_class (xine_t *xine, const void *data); void *demux_real_init_class (xine_t *xine, const void *data); void *demux_ts_init_class (xine_t *xine, const void *data); void *demux_vc1es_init_class (xine_t *xine, const void *data); void *demux_yuv_frames_init_class (xine_t *xine, const void *data); void *demux_yuv4mpeg2_init_class (xine_t *xine, const void *data); #endif xine-lib-1.2/src/demuxers/demux_avi.c0000644000175000017500000022720014647725152015437 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demultiplexer for avi streams * * part of the code is taken from * avilib (C) 1999 Rainer Johanni */ /* * Ian Goldberg modified this code so that it can * handle "streaming" AVI files. By that I mean real seekable files, but * ones that are growing as we're displaying them. Examples include * AVI's you're downloading, or ones you're writing in real time using * xawtv streamer, or whatever. This latter is really useful, for * example, for doing the PVR trick of starting the streamer to record * TV, starting to watch it ~10 minutes later, and skipping the * commercials to catch up to real time. If you accidentally hit the * end of the stream, just hit your "back 15 seconds" key, and all is * good. * * Theory of operation: the video and audio indices have been separated * out of the main avi_t and avi_audio_t structures into separate * structures that can grow during playback. We use the idx_grow_t * structure to keep track of the offset into the AVI file where we * expect to find the next A/V frame. We periodically check if we can * read data from the file at that offset. If we can, we append index * data for as many frames as we can read at the time. */ /* * OpenDML (AVI2.0) stuff was done by Tilmann Bitterberg * in December 2003. * Transcode's and xine's avi code comes from the same source and * still has a very similar architecture, so it wasn't much effort to * port it from transcode to xine. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_avi" #define LOG_VERBOSE /* #define DEBUG_ODML #define LOG */ #include "group_video.h" #include #include #include #include "bswap.h" /* * stolen from wine headers */ #define AVIIF_KEYFRAME 0x00000010L #define MAX_AUDIO_STREAMS 8 #define NUM_PREVIEW_BUFFERS 10 typedef struct{ off_t pos; uint32_t len; uint32_t flags; } video_index_entry_t; typedef struct{ off_t pos; uint32_t len; off_t tot; uint32_t block_no; /* block number, used compute pts in audio VBR streams */ } audio_index_entry_t; /* For parsing OpenDML AVI2.0 files */ #define AVI_INDEX_OF_INDEXES 0x00 /* when each entry in aIndex */ /* array points to an index chunk */ #define AVI_INDEX_OF_CHUNKS 0x01 /* when each entry in aIndex */ /* array points to a chunk in the file */ #define AVI_INDEX_IS_DATA 0x80 /* when each entry is aIndex is */ /* really the data */ /* bIndexSubtype codes for INDEX_OF_CHUNKS */ #define AVI_INDEX_2FIELD 0x01 /* when fields within frames */ /* are also indexed */ typedef struct _avisuperindex_entry { uint64_t qwOffset; /* absolute file offset */ uint32_t dwSize; /* size of index chunk at this offset */ uint32_t dwDuration; /* time span in stream ticks */ } avisuperindex_entry; typedef struct _avistdindex_entry { uint32_t dwOffset; /* qwBaseOffset + this is absolute file offset */ uint32_t dwSize; /* bit 31 is set if this is NOT a keyframe */ } avistdindex_entry; /* Standard index */ typedef struct _avistdindex_chunk { char fcc[4]; /* ix## */ uint32_t dwSize; /* size of this chunk */ uint16_t wLongsPerEntry; /* must be sizeof(aIndex[0])/sizeof(DWORD) */ uint8_t bIndexSubType; /* must be 0 */ uint8_t bIndexType; /* must be AVI_INDEX_OF_CHUNKS */ uint32_t nEntriesInUse; /* */ char dwChunkId[4]; /* '##dc' or '##db' or '##wb' etc.. */ uint64_t qwBaseOffset; /* all dwOffsets in aIndex array are relative to this */ uint32_t dwReserved3; /* must be 0 */ avistdindex_entry *aIndex; } avistdindex_chunk; /* Base Index Form 'indx' */ typedef struct _avisuperindex_chunk { char fcc[4]; uint32_t dwSize; /* size of this chunk */ uint16_t wLongsPerEntry; /* size of each entry in aIndex array (must be 8 for us) */ uint8_t bIndexSubType; /* future use. must be 0 */ uint8_t bIndexType; /* one of AVI_INDEX_* codes */ uint32_t nEntriesInUse; /* index of first unused member in aIndex array */ char dwChunkId[4]; /* fcc of what is indexed */ uint32_t dwReserved[3]; /* meaning differs for each index type/subtype. */ /* 0 if unused */ avisuperindex_entry *aIndex; /* where are the ix## chunks */ avistdindex_chunk **stdindex; /* the ix## chunks itself (array) */ } avisuperindex_chunk; /* These next three are the video and audio structures that can grow * during the playback of a streaming file. */ typedef struct{ uint32_t video_frames; /* Number of video frames */ uint32_t alloc_frames; /* Allocated number of frames */ video_index_entry_t *vindex; } video_index_t; typedef struct{ uint32_t audio_chunks; /* Chunks of audio data in the file */ uint32_t alloc_chunks; /* Allocated number of chunks */ audio_index_entry_t *aindex; } audio_index_t; typedef struct{ off_t nexttagoffset; /* The offset into the AVI file where we expect */ /* to find the next A/V frame */ } idx_grow_t; typedef struct{ uint32_t dwInitialFrames; uint32_t dwScale; uint32_t dwRate; uint32_t dwStart; uint32_t dwSampleSize; uint32_t block_no; uint32_t audio_type; /* BUF_AUDIO_xxx type */ uint32_t audio_strn; /* Audio stream number */ char audio_tag[4]; /* Tag of audio data */ uint32_t audio_posc; /* Audio position: chunk */ uint32_t audio_posb; /* Audio position: byte within chunk */ int wavex_len; xine_waveformatex *wavex; audio_index_t audio_idx; avisuperindex_chunk *audio_superindex; off_t audio_tot; /* Total number of audio bytes */ } avi_audio_t; typedef struct{ int32_t width; /* Width of a video frame */ int32_t height; /* Height of a video frame */ uint32_t dwInitialFrames; uint32_t dwScale; uint32_t dwRate; uint32_t dwStart; double fps; /* Frames per second */ uint32_t compressor; /* Type of compressor */ uint32_t video_strn; /* Video stream number */ char video_tag[4]; /* Tag of video data */ uint32_t video_posf; /* Number of next frame to be read (if index present) */ uint32_t video_posb; /* Video position: byte within frame */ avi_audio_t *audio[MAX_AUDIO_STREAMS]; int n_audio; uint32_t video_type; /* BUF_VIDEO_xxx type */ uint32_t n_idx; /* number of index entries actually filled */ uint32_t max_idx; /* number of index entries actually allocated */ unsigned char (*idx)[16]; /* index entries (AVI idx1 tag) */ video_index_t video_idx; xine_bmiheader *bih; off_t movi_start; off_t movi_end; int palette_count; palette_entry_t palette[256]; int is_opendml; /* set to 1 if this is an odml file with multiple index chunks */ avisuperindex_chunk *video_superindex; /* index of indices */ int total_frames; /* total number of frames if dmlh is present */ } avi_t; typedef struct demux_avi_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; uint32_t video_step; uint32_t AVI_errno; /* seeking args backup */ int seek_start_time; off_t seek_start_pos; avi_t *avi; idx_grow_t idx_grow; uint8_t no_audio:1; uint8_t streaming:1; uint8_t has_index:1; uint8_t seek_request:1; /* discontinuity detection (only at seek) */ uint8_t buf_flag_seek:1; uint8_t send_newpts:1; } demux_avi_t ; /* The following variable indicates the kind of error */ #define AVI_ERR_SIZELIM 1 /* The write of the data would exceed the maximum size of the AVI file. This is more a warning than an error since the file may be closed safely */ #define AVI_ERR_OPEN 2 /* Error opening the AVI file - wrong path name or file nor readable/writable */ #define AVI_ERR_READ 3 /* Error reading from AVI File */ #define AVI_ERR_WRITE 4 /* Error writing to AVI File, disk full ??? */ #define AVI_ERR_WRITE_INDEX 5 /* Could not write index to AVI file during close, file may still be usable */ #define AVI_ERR_CLOSE 6 /* Could not write header to AVI file or not truncate the file during close, file is most probably corrupted */ #define AVI_ERR_NOT_PERM 7 /* Operation not permitted: trying to read from a file open for writing or vice versa */ #define AVI_ERR_NO_MEM 8 /* malloc failed */ #define AVI_ERR_NO_AVI 9 /* Not an AVI file */ #define AVI_ERR_NO_HDRL 10 /* AVI file has no header list, corrupted ??? */ #define AVI_ERR_NO_MOVI 11 /* AVI file has no MOVI list, corrupted ??? */ #define AVI_ERR_NO_VIDS 12 /* AVI file contains no video data */ #define AVI_ERR_NO_IDX 13 /* The file has been opened with getIndex==0, but an operation has been performed that needs an index */ #define AVI_ERR_BAD_SIZE 14 /* A chunk has an invalid size */ #define AVI_HEADER_UNKNOWN -1 #define AVI_HEADER_AUDIO 0 #define AVI_HEADER_VIDEO 1 #define AVI_HEADER_SIZE 8 #define WRAP_THRESHOLD 90000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 /* bit 31 denotes a keyframe */ static uint32_t odml_len (unsigned char *str) { return _X_LE_32(str) & 0x7fffffff; } /* if bit 31 is 0, its a keyframe */ static uint32_t odml_key (unsigned char *str) { return (_X_LE_32(str) & 0x80000000)?0:0x10; } static void check_newpts (demux_avi_t *this, int64_t pts, int video) { (void)video; if (this->send_newpts) { lprintf ("sending newpts %" PRId64 " (video = %d)\n", pts, video); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; } } /* Append an index entry for a newly-found video frame */ static int video_index_append(avi_t *AVI, off_t pos, uint32_t len, uint32_t flags) { video_index_t *vit = &(AVI->video_idx); /* Make sure there's room */ if (vit->video_frames == vit->alloc_frames) { long newalloc = vit->alloc_frames + 4096; video_index_entry_t *newindex = realloc(vit->vindex, newalloc * sizeof(video_index_entry_t)); if (!newindex) return -1; vit->vindex = newindex; vit->alloc_frames = newalloc; } /* Set the new index entry */ vit->vindex[vit->video_frames].pos = pos; vit->vindex[vit->video_frames].len = len; vit->vindex[vit->video_frames].flags = flags; vit->video_frames += 1; return 0; } /* Append an index entry for a newly-found audio frame */ static int audio_index_append(avi_t *AVI, int stream, off_t pos, uint32_t len, off_t tot, uint32_t block_no) { audio_index_t *ait = &(AVI->audio[stream]->audio_idx); /* Make sure there's room */ if (ait->audio_chunks == ait->alloc_chunks) { uint32_t newalloc = ait->alloc_chunks + 4096; audio_index_entry_t *newindex = realloc(ait->aindex, newalloc * sizeof(audio_index_entry_t)); if (!newindex) return -1; ait->aindex = newindex; ait->alloc_chunks = newalloc; } /* Set the new index entry */ ait->aindex[ait->audio_chunks].pos = pos; ait->aindex[ait->audio_chunks].len = len; ait->aindex[ait->audio_chunks].tot = tot; ait->aindex[ait->audio_chunks].block_no = block_no; ait->audio_chunks += 1; return 0; } #define PAD_EVEN(x) ( ((x)+1) & ~1 ) static int64_t get_audio_pts (demux_avi_t *this, int track, uint32_t posc, off_t postot, uint32_t posb) { avi_audio_t *at = this->avi->audio[track]; lprintf("get_audio_pts: track=%d, posc=%d, postot=%" PRIdMAX ", posb=%d\n", track, posc, (intmax_t)postot, posb); if (at->dwRate == 0) return 0; if ((at->dwSampleSize == 0) && (at->dwScale > 1)) { /* variable bitrate */ lprintf("get_audio_pts: VBR: nBlockAlign=%d, dwSampleSize=%d, dwScale=%d, dwRate=%d\n", at->wavex ? at->wavex->nBlockAlign : 0, at->dwSampleSize, at->dwScale, at->dwRate); return (int64_t)(90000.0 * (double)(posc + at->dwStart) * (double)at->dwScale / (double)at->dwRate); } else { /* constant bitrate */ lprintf("get_audio_pts: CBR: nBlockAlign=%d, dwSampleSize=%d, dwScale=%d, dwRate=%d\n", at->wavex ? at->wavex->nBlockAlign : 0, at->dwSampleSize, at->dwScale, at->dwRate); if( at->wavex && at->wavex->nBlockAlign ) { return (int64_t)((double)((postot + posb) / (double)at->wavex->nBlockAlign + at->dwStart) * (double)at->dwScale / (double)at->dwRate * 90000.0); } else { if (!at->dwSampleSize) return 0; return (int64_t)((double)((postot + posb) / (double)at->dwSampleSize + at->dwStart) * (double)at->dwScale / (double)at->dwRate * 90000.0); } } } static int64_t get_video_pts (demux_avi_t *this, off_t pos) { lprintf("get_video_pts: dwScale=%d, dwRate=%d, pos=%" PRIdMAX "\n", this->avi->dwScale, this->avi->dwRate, (intmax_t)pos); return (int64_t)(90000.0 * (double)(pos + this->avi->dwStart) * (double)this->avi->dwScale / (double)this->avi->dwRate); } /* Some handy stopper tests for idx_grow, below. */ /* Use this one to ensure the current video frame is in the index. */ static int video_pos_stopper(demux_avi_t *this, void *data){ (void)data; if (this->avi->video_posf >= this->avi->video_idx.video_frames) { return -1; } return 1; } /* Use this one to ensure the current audio chunk is in the index. */ static int audio_pos_stopper(demux_avi_t *this, void *data) { avi_audio_t *AVI_A = (avi_audio_t *)data; (void)this; if (AVI_A->audio_posc >= AVI_A->audio_idx.audio_chunks) { return -1; } return 1; } /* Use this one to ensure that a video frame with the given position * is in the index. */ static int start_pos_stopper(demux_avi_t *this, void *data) { off_t start_pos = *(off_t *)data; int32_t maxframe = this->avi->video_idx.video_frames - 1; while( maxframe >= 0 && this->avi->video_idx.vindex[maxframe].pos >= start_pos ) { if ( this->avi->video_idx.vindex[maxframe].flags & AVIIF_KEYFRAME ) return 1; maxframe--; } return -1; } /* Use this one to ensure that a video frame with the given timestamp * is in the index. */ static int start_time_stopper(demux_avi_t *this, void *data) { int64_t video_pts = *(int64_t *)data; int32_t maxframe = this->avi->video_idx.video_frames - 1; while( maxframe >= 0 && get_video_pts(this,maxframe) >= video_pts ) { if ( this->avi->video_idx.vindex[maxframe].flags & AVIIF_KEYFRAME ) return 1; maxframe--; } return -1; } /* This is called periodically to check if there's more file now than * there was before. If there is, we constuct the index for (just) the * new part, and append it to the index we've got so far. We stop * slurping in the new part when stopper(this, stopdata) returns a * non-negative value, or there's no more file to read. If we're taking * a long time slurping in the new part, use the on-screen display to * notify the user. Returns -1 if EOF was reached, the non-negative * return value of stopper otherwise. */ static int idx_grow(demux_avi_t *this, int (*stopper)(demux_avi_t *, void *), void *stopdata) { int retval = -1; int num_read = 0; uint8_t data[AVI_HEADER_SIZE]; uint8_t data2[4]; off_t savepos = this->input->seek(this->input, 0, SEEK_CUR); off_t chunk_pos; uint32_t chunk_len; int sent_event = 0; this->input->seek(this->input, this->idx_grow.nexttagoffset, SEEK_SET); chunk_pos = this->idx_grow.nexttagoffset; while (((retval = stopper(this, stopdata)) < 0) && (!_x_action_pending(this->stream))) { int valid_chunk = 0; num_read += 1; if (num_read % 1000 == 0) { /* send event to frontend about index generation progress */ xine_event_t event; xine_progress_data_t prg; off_t file_len; file_len = this->input->get_length (this->input); prg.description = _("Restoring index..."); prg.percent = 100 * this->idx_grow.nexttagoffset / file_len; event.type = XINE_EVENT_PROGRESS; event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (this->stream, &event); sent_event = 1; } if (this->input->read(this->input, data, AVI_HEADER_SIZE) != AVI_HEADER_SIZE) { lprintf("read failed, chunk_pos=%" PRIdMAX "\n", (intmax_t)chunk_pos); break; } /* Dive into RIFF and LIST entries */ if(strncasecmp(data, "LIST", 4) == 0 || strncasecmp(data, "RIFF", 4) == 0) { this->idx_grow.nexttagoffset = this->input->seek(this->input, 4,SEEK_CUR); continue; } chunk_len = _X_LE_32(data + 4); this->idx_grow.nexttagoffset += PAD_EVEN(chunk_len + AVI_HEADER_SIZE); /* Video chunk */ if ((data[0] == this->avi->video_tag[0]) && (data[1] == this->avi->video_tag[1])) { int flags = AVIIF_KEYFRAME; off_t pos = chunk_pos + AVI_HEADER_SIZE; uint32_t tmp; valid_chunk = 1; /* FIXME: * UGLY hack to detect a keyframe parsing decoder data * AVI chuncks doesn't provide this info and we need it during * index building * this hack comes from mplayer (aviheader.c) * i've added XVID which looks like iso mpeg 4 */ if (this->input->read(this->input, data2, 4) != 4) { read_failed: lprintf("read failed\n"); break; } tmp = data2[3] | (data2[2]<<8) | (data2[1]<<16) | (data2[0]<<24); switch(this->avi->video_type) { case BUF_VIDEO_MSMPEG4_V1: if (this->input->read(this->input, data2, 4) != 4) goto read_failed; tmp = data2[3] | (data2[2]<<8) | (data2[1]<<16) | (data2[0]<<24); tmp = tmp << 5; /* fall through */ case BUF_VIDEO_MSMPEG4_V2: case BUF_VIDEO_MSMPEG4_V3: if (tmp & 0x40000000) flags = 0; break; case BUF_VIDEO_DIVX5: case BUF_VIDEO_MPEG4: case BUF_VIDEO_XVID: if (tmp == 0x000001B6) flags = 0; break; } if (video_index_append(this->avi, pos, chunk_len, flags) == -1) { /* If we're out of memory, we just don't grow the index, but * nothing really bad happens. */ } } else { int i; /* Audio chunk */ for(i = 0; i < this->avi->n_audio; ++i) { avi_audio_t *audio = this->avi->audio[i]; if ((data[0] == audio->audio_tag[0]) && (data[1] == audio->audio_tag[1])) { off_t pos = chunk_pos + AVI_HEADER_SIZE; valid_chunk = 1; /* VBR streams (hack from mplayer) */ if (audio->wavex && audio->wavex->nBlockAlign) { audio->block_no += (chunk_len + audio->wavex->nBlockAlign - 1) / audio->wavex->nBlockAlign; } else { audio->block_no += 1; } if (audio_index_append(this->avi, i, pos, chunk_len, audio->audio_tot, audio->block_no) == -1) { /* As above. */ } this->avi->audio[i]->audio_tot += chunk_len; } } } if (!valid_chunk) { xine_log(this->stream->xine, XINE_LOG_MSG, _("demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %" PRIdMAX "\n"), data[0], data[1], data[2], data[3], (intmax_t)chunk_pos); } chunk_pos = this->input->seek(this->input, this->idx_grow.nexttagoffset, SEEK_SET); if (chunk_pos != this->idx_grow.nexttagoffset) { lprintf("seek failed: %" PRIdMAX " != %" PRIdMAX "\n", (intmax_t)chunk_pos, (intmax_t)this->idx_grow.nexttagoffset); break; } } if (sent_event == 1) { /* send event to frontend about index generation progress */ xine_event_t event; xine_progress_data_t prg; prg.description = _("Restoring index..."); prg.percent = 100; event.type = XINE_EVENT_PROGRESS; event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (this->stream, &event); } this->input->seek (this->input, savepos, SEEK_SET); if (retval < 0) retval = -1; return retval; } /* Fetch the current video index entry, growing the index if necessary. */ static video_index_entry_t *video_cur_index_entry(demux_avi_t *this) { avi_t *AVI = this->avi; if (AVI->video_posf >= AVI->video_idx.video_frames) { /* We don't have enough frames; see if the file's bigger yet. */ if (idx_grow(this, video_pos_stopper, NULL) < 0) { /* We still don't have enough frames. Oh, well. */ return NULL; } } return &(AVI->video_idx.vindex[AVI->video_posf]); } /* Fetch the current audio index entry, growing the index if necessary. */ static audio_index_entry_t *audio_cur_index_entry(demux_avi_t *this, avi_audio_t *AVI_A) { lprintf("posc: %d, chunks: %d\n", AVI_A->audio_posc, AVI_A->audio_idx.audio_chunks); if (AVI_A->audio_posc >= AVI_A->audio_idx.audio_chunks) { /* We don't have enough chunks; see if the file's bigger yet. */ if (idx_grow(this, audio_pos_stopper, AVI_A) < 0) { /* We still don't have enough chunks. Oh, well. */ return NULL; } } return &(AVI_A->audio_idx.aindex[AVI_A->audio_posc]); } static void free_superindex(avisuperindex_chunk **p) { if (*p) { _x_freep(&(*p)->aIndex); } _x_freep(p); } static void AVI_close(avi_t *AVI){ int i; _x_freep(&AVI->idx); _x_freep(&AVI->video_idx.vindex); _x_freep(&AVI->bih); free_superindex(&AVI->video_superindex); for(i=0; in_audio; i++) { free_superindex(&AVI->audio[i]->audio_superindex); _x_freep(&AVI->audio[i]->audio_idx.aindex); _x_freep(&AVI->audio[i]->wavex); _x_freep(&AVI->audio[i]); } free(AVI); } #define ERR_EXIT(x) \ do { \ this->AVI_errno = x; \ free (AVI); \ return 0; \ } while(0) static void reset_idx(demux_avi_t *this, avi_t *AVI) { int n; this->idx_grow.nexttagoffset = AVI->movi_start; this->has_index = 0; AVI->video_idx.video_frames = 0; for(n = 0; n < AVI->n_audio; n++) { AVI->audio[n]->audio_idx.audio_chunks = 0; } } static avi_t *XINE_MALLOC AVI_init(demux_avi_t *this) { avi_t *AVI; int i, j, idx_type; uint32_t n; uint8_t *hdrl_data; int hdrl_len = 0; off_t ioff; int lasttag = 0; int vids_strh_seen = 0; int vids_strf_seen = 0; int num_stream = 0; uint8_t data[256]; /* Create avi_t structure */ lprintf("start\n"); AVI = (avi_t *) calloc(1, sizeof(avi_t)); if(AVI==NULL) { this->AVI_errno = AVI_ERR_NO_MEM; return 0; } /* Read first 12 bytes and check that this is an AVI file */ if (!this->streaming) this->input->seek(this->input, 0, SEEK_SET); if( this->input->read(this->input, data,12) != 12 ) ERR_EXIT(AVI_ERR_READ) ; if( !( (strncasecmp(data ,"ON2 ",4) == 0 && strncasecmp(data+8,"ON2f",4) == 0) || (strncasecmp(data ,"RIFF",4) == 0 && strncasecmp(data+8,"AVI ",4) == 0) ) ) ERR_EXIT(AVI_ERR_NO_AVI) ; /* Go through the AVI file and extract the header list, the start position of the 'movi' list and an optionally present idx1 tag */ hdrl_data = NULL; while(1) { off_t next_chunk; /* Keep track of the last place we tried to read something. */ this->idx_grow.nexttagoffset = this->input->get_current_pos(this->input); if (this->input->read(this->input, data,8) != 8 ) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "failed to read 8 bytes at pos %" PRIdMAX "\n", (intmax_t)this->idx_grow.nexttagoffset); break; /* We assume it's EOF */ } n = _X_LE_32(data + 4); n = PAD_EVEN(n); next_chunk = this->idx_grow.nexttagoffset + 8 + n; lprintf("chunk: %c%c%c%c, size: %" PRId64 "\n", data[0], data[1], data[2], data[3], (int64_t)n); if (n >= 4 && strncasecmp(data,"LIST",4) == 0) { if( this->input->read(this->input, data,4) != 4 ) ERR_EXIT(AVI_ERR_READ); n -= 4; lprintf(" chunk: %c%c%c%c\n", data[0], data[1], data[2], data[3]); if(strncasecmp(data,"hdrl",4) == 0) { hdrl_len = n; hdrl_data = (unsigned char *) malloc(n); if(hdrl_data==0) ERR_EXIT(AVI_ERR_NO_MEM); if (this->input->read(this->input, hdrl_data,n) != n ) ERR_EXIT(AVI_ERR_READ); } else if(strncasecmp(data,"movi",4) == 0) { AVI->movi_start = this->input->get_current_pos(this->input); AVI->movi_end = AVI->movi_start + n - 1; if (this->streaming) /* stop reading here, we can't seek back */ break; } } else if(strncasecmp(data,"idx1",4) == 0 || strncasecmp(data,"iddx",4) == 0) { /* n must be a multiple of 16, but the reading does not break if this is not the case */ AVI->n_idx = AVI->max_idx = n / 16; free(AVI->idx); /* On the off chance there are multiple index chunks */ AVI->idx = (unsigned char((*)[16])) malloc(n); if (AVI->idx == 0) ERR_EXIT(AVI_ERR_NO_MEM); if (this->input->read(this->input, (char *)AVI->idx, n) != n ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("demux_avi: avi index is broken\n")); free (AVI->idx); /* Index is broken, reconstruct */ AVI->idx = NULL; AVI->n_idx = AVI->max_idx = 0; break; /* EOF */ } } if (next_chunk != this->input->seek(this->input, next_chunk, SEEK_SET)) { xine_log (this->stream->xine, XINE_LOG_MSG, _("demux_avi: failed to seek to the next chunk (pos %" PRIdMAX ")\n"), (intmax_t)next_chunk); break; /* probably slow seek */ } } /* Interpret the header list */ for (i = 0; i < hdrl_len;) { const int old_i = i; /* List tags are completly ignored */ lprintf("tag: %c%c%c%c\n", hdrl_data[i], hdrl_data[i+1], hdrl_data[i+2], hdrl_data[i+3]); if (strncasecmp(hdrl_data + i, "LIST", 4) == 0) { i += 12; continue; } n = _X_LE_32(hdrl_data + i + 4); n = PAD_EVEN(n); /* Interpret the tag and its args */ if(strncasecmp(hdrl_data + i, "strh", 4) == 0) { i += 8; lprintf("tag: %c%c%c%c\n", hdrl_data[i], hdrl_data[i+1], hdrl_data[i+2], hdrl_data[i+3]); if(strncasecmp(hdrl_data + i, "vids", 4) == 0 && !vids_strh_seen) { AVI->compressor = *(uint32_t *) (hdrl_data + i + 4); AVI->dwInitialFrames = _X_LE_32(hdrl_data + i + 16); AVI->dwScale = _X_LE_32(hdrl_data + i + 20); AVI->dwRate = _X_LE_32(hdrl_data + i + 24); AVI->dwStart = _X_LE_32(hdrl_data + i + 28); if(AVI->dwScale!=0) AVI->fps = (double)AVI->dwRate/(double)AVI->dwScale; this->video_step = (long) (90000.0 / AVI->fps); AVI->video_strn = num_stream; vids_strh_seen = 1; lprintf("video stream header, num_stream=%d\n", num_stream); lasttag = 1; /* vids */ lprintf("dwScale=%d, dwRate=%d, dwInitialFrames=%d, dwStart=%d, num_stream=%d\n", AVI->dwScale, AVI->dwRate, AVI->dwInitialFrames, AVI->dwStart, num_stream); } else if (strncasecmp (hdrl_data+i,"auds",4) ==0 /* && ! auds_strh_seen*/) { if(AVI->n_audio < MAX_AUDIO_STREAMS) { avi_audio_t *a = (avi_audio_t *) calloc(1, sizeof(avi_audio_t)); if(a==NULL) { this->AVI_errno = AVI_ERR_NO_MEM; AVI_close(AVI); return NULL; } AVI->audio[AVI->n_audio] = a; a->audio_strn = num_stream; a->dwInitialFrames = _X_LE_32(hdrl_data + i + 16); a->dwScale = _X_LE_32(hdrl_data + i + 20); a->dwRate = _X_LE_32(hdrl_data + i + 24); a->dwStart = _X_LE_32(hdrl_data + i + 28); lprintf("dwScale=%d, dwRate=%d, dwInitialFrames=%d, dwStart=%d, num_stream=%d\n", a->dwScale, a->dwRate, a->dwInitialFrames, a->dwStart, num_stream); a->dwSampleSize = _X_LE_32(hdrl_data + i + 44); a->audio_tot = 0; lprintf("audio stream header, num_stream=%d\n", num_stream); lasttag = 2; /* auds */ AVI->n_audio++; } } else { /* unknown stream type */ lasttag = 0; } num_stream++; } else if(strncasecmp(hdrl_data+i,"dmlh",4) == 0) { AVI->total_frames = _X_LE_32(hdrl_data+i+8); #ifdef DEBUG_ODML lprintf( "AVI: real number of frames %d\n", AVI->total_frames); #endif i += 8; } else if(strncasecmp(hdrl_data + i, "strf", 4) == 0) { uint32_t strf_size; i += 4; strf_size = _X_LE_32(hdrl_data + i); i += 4; if(lasttag == 1) { /* lprintf ("size : %d\n",sizeof(AVI->bih)); */ AVI->bih = (xine_bmiheader *) malloc((n < sizeof(xine_bmiheader)) ? sizeof(xine_bmiheader) : n); if(AVI->bih == NULL) { this->AVI_errno = AVI_ERR_NO_MEM; AVI_close(AVI); return NULL; } memcpy (AVI->bih, hdrl_data+i, n); _x_bmiheader_le2me( AVI->bih ); /* stream_read(demuxer->stream,(char*) &avi_header.bih,MIN(size2,sizeof(avi_header.bih))); */ AVI->width = AVI->bih->biWidth; AVI->height = AVI->bih->biHeight; /* lprintf ("size : %d x %d (%d x %d)\n", AVI->width, AVI->height, AVI->bih.biWidth, AVI->bih.biHeight); lprintf (" biCompression %d='%.4s'\n", AVI->bih.biCompression, &AVI->bih.biCompression); */ lprintf("video stream format\n"); vids_strf_seen = 1; /* load the palette, if there is one */ AVI->palette_count = AVI->bih->biClrUsed; lprintf ("palette_count: %d\n", AVI->palette_count); if (AVI->palette_count > 256) { lprintf ("number of colours exceeded 256 (%d)", AVI->palette_count); AVI->palette_count = 256; } if ((strf_size - sizeof (xine_bmiheader)) >= (uint32_t)(AVI->palette_count * 4)) { /* load the palette from the end of the strf chunk */ for (j = 0; j < AVI->palette_count; j++) { AVI->palette[j].b = *(hdrl_data + i + sizeof(xine_bmiheader) + j * 4 + 0); AVI->palette[j].g = *(hdrl_data + i + sizeof(xine_bmiheader) + j * 4 + 1); AVI->palette[j].r = *(hdrl_data + i + sizeof(xine_bmiheader) + j * 4 + 2); } } else { /* generate a greyscale palette */ AVI->palette_count = 256; for (j = 0; j < AVI->palette_count; j++) { AVI->palette[j].r = j; AVI->palette[j].g = j; AVI->palette[j].b = j; } } } else if(lasttag == 2) { xine_waveformatex *wavex; wavex = (xine_waveformatex *)malloc(n); if (!wavex) { this->AVI_errno = AVI_ERR_NO_MEM; AVI_close(AVI); return NULL; } memcpy((void *)wavex, hdrl_data+i, n); _x_waveformatex_le2me( wavex ); AVI->audio[AVI->n_audio-1]->wavex = wavex; AVI->audio[AVI->n_audio-1]->wavex_len = n; lprintf("audio stream format\n"); } } else if(strncasecmp(hdrl_data + i, "indx",4) == 0) { uint8_t *a; unsigned int j; avisuperindex_chunk *superindex; if (n < sizeof (avisuperindex_chunk)) { lprintf("broken index !, dwSize=%d\n", n); i += 8 + n; continue; } superindex = (avisuperindex_chunk *) malloc (sizeof (avisuperindex_chunk)); a = hdrl_data + i; memcpy (superindex->fcc, a, 4); a += 4; superindex->dwSize = _X_LE_32(a); a += 4; superindex->wLongsPerEntry = _X_LE_16(a); a += 2; superindex->bIndexSubType = *a; a += 1; superindex->bIndexType = *a; a += 1; superindex->nEntriesInUse = _X_LE_32(a); a += 4; memcpy (superindex->dwChunkId, a, 4); a += 4; #ifdef DEBUG_ODML printf("FOURCC \"%c%c%c%c\"\n", superindex->fcc[0], superindex->fcc[1], superindex->fcc[2], superindex->fcc[3]); printf("LEN \"%ld\"\n", (long)superindex->dwSize); printf("wLongsPerEntry \"%d\"\n", superindex->wLongsPerEntry); printf("bIndexSubType \"%d\"\n", superindex->bIndexSubType); printf("bIndexType \"%d\"\n", superindex->bIndexType); printf("nEntriesInUse \"%ld\"\n", (long)superindex->nEntriesInUse); printf("dwChunkId \"%c%c%c%c\"\n", superindex->dwChunkId[0], superindex->dwChunkId[1], superindex->dwChunkId[2], superindex->dwChunkId[3]); printf("--\n"); #endif /* 3 * reserved */ a += 4; a += 4; a += 4; if (superindex->bIndexSubType != 0) { lprintf("Invalid Header, bIndexSubType != 0\n"); } if (superindex->nEntriesInUse > n / sizeof (avisuperindex_entry)) { lprintf("broken index !, dwSize=%d, entries=%d\n", n, superindex->nEntriesInUse); i += 8 + n; free(superindex); continue; } superindex->aIndex = malloc (superindex->nEntriesInUse * sizeof (avisuperindex_entry)); /* position of ix## chunks */ for (j = 0; j < superindex->nEntriesInUse; ++j) { superindex->aIndex[j].qwOffset = _X_LE_64 (a); a += 8; superindex->aIndex[j].dwSize = _X_LE_32 (a); a += 4; superindex->aIndex[j].dwDuration = _X_LE_32 (a); a += 4; #ifdef DEBUG_ODML printf("[%d] 0x%llx 0x%x %u\n", j, (uint64_t)superindex->aIndex[j].qwOffset, (uint32_t)superindex->aIndex[j].dwSize, (uint32_t)superindex->aIndex[j].dwDuration); #endif } this->has_index = 1; if (lasttag == 1) { /* V I D E O */ AVI->video_superindex = superindex; AVI->is_opendml = 1; } else if (lasttag == 2) { /* A U D I O */ AVI->audio[AVI->n_audio-1]->audio_superindex = superindex; AVI->is_opendml = 1; } else { free(superindex->aIndex); free(superindex); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: there should not be an index there, lasttag = %d\n", lasttag); } i += 8; } else if(strncasecmp(hdrl_data + i, "JUNK", 4) == 0) { i += 8; /* do not reset lasttag */ } else if(strncasecmp(hdrl_data + i, "strd", 4) == 0) { /* additional header data */ i += 8; /* do not reset lasttag */ } else if(strncasecmp(hdrl_data + i, "strn", 4) == 0) { /* stream name */ i += 8; /* do not reset lasttag */ } else if(strncasecmp(hdrl_data + i, "vprp", 4) == 0) { /* video properties header*/ i += 8; /* do not reset lasttag */ } else { i += 8; lasttag = 0; } i += n; if (i <= old_i) ERR_EXIT(AVI_ERR_BAD_SIZE); } if( hdrl_data ) free( hdrl_data ); hdrl_data = NULL; /* somehow ffmpeg doesn't specify the number of frames here */ /* if (!vids_strh_seen || !vids_strf_seen || AVI->video_frames==0) */ if (!vids_strh_seen || !vids_strf_seen) ERR_EXIT(AVI_ERR_NO_VIDS); AVI->video_tag[0] = AVI->video_strn / 10 + '0'; AVI->video_tag[1] = AVI->video_strn % 10 + '0'; /* do not use the two following bytes */ AVI->video_tag[2] = 'd'; AVI->video_tag[3] = 'b'; for(i = 0; i < AVI->n_audio; i++) { /* Audio tag is set to "99wb" if no audio present */ if (!AVI->audio[i]->wavex->nChannels) AVI->audio[i]->audio_strn = 99; AVI->audio[i]->audio_tag[0] = AVI->audio[i]->audio_strn / 10 + '0'; AVI->audio[i]->audio_tag[1] = AVI->audio[i]->audio_strn % 10 + '0'; /* do not use the two following bytes */ AVI->audio[i]->audio_tag[2] = 'w'; AVI->audio[i]->audio_tag[3] = 'b'; } idx_type = 0; if (!this->streaming) { this->input->seek(this->input, AVI->movi_start, SEEK_SET); /* if the file has an idx1, check if this is relative to the start of the file or to the start of the movi list */ if(AVI->idx) { off_t pos; uint32_t len; unsigned int i; /* Search the first videoframe in the idx1 and look where it is in the file */ for(i = 0; i < AVI->n_idx; i++) if( (AVI->idx[i][0] == AVI->video_tag[0]) && (AVI->idx[i][1] == AVI->video_tag[1])) break; #if 0 /* try again for ##ix */ if (i >= AVI->n_idx) { AVI->video_tag[2] = 'i'; AVI->video_tag[3] = 'x'; } for(i = 0; i < AVI->n_idx; i++) if( strncasecmp(AVI->idx[i], AVI->video_tag, 3) == 0 ) break; #endif if (i >= AVI->n_idx) { ERR_EXIT(AVI_ERR_NO_VIDS); } pos = _X_LE_32(AVI->idx[i] + 8); len = _X_LE_32(AVI->idx[i] + 12); this->input->seek(this->input, pos, SEEK_SET); if(this->input->read(this->input, data, 8) != 8) ERR_EXIT(AVI_ERR_READ) ; if( (strncasecmp(data, AVI->idx[i], 4) == 0) && (_X_LE_32(data + 4) == len) ) { idx_type = 1; /* Index from start of file */ } else { this->input->seek(this->input, pos + AVI->movi_start - 4, SEEK_SET); if(this->input->read(this->input, data, 8) != 8) ERR_EXIT(AVI_ERR_READ) ; if( strncasecmp(data,AVI->idx[i], 4) == 0 && _X_LE_32(data + 4) == len ) { idx_type = 2; /* Index from start of movi list */ } } /* idx_type remains 0 if neither of the two tests above succeeds */ } } lprintf("idx_type=%d, AVI->n_idx=%d\n", idx_type, AVI->n_idx); if (idx_type != 0 && !AVI->is_opendml) { unsigned int i; /* Now generate the video index and audio index arrays from the * idx1 record. */ this->has_index = 1; ioff = (idx_type == 1) ? AVI_HEADER_SIZE : AVI->movi_start + 4; for(i = 0; i < AVI->n_idx; i++) { if((AVI->idx[i][0] == AVI->video_tag[0]) && (AVI->idx[i][1] == AVI->video_tag[1])) { off_t pos = _X_LE_32(AVI->idx[i] + 8) + ioff; uint32_t len = _X_LE_32(AVI->idx[i] + 12); uint32_t flags = _X_LE_32(AVI->idx[i] + 4); if (video_index_append(AVI, pos, len, flags) == -1) { ERR_EXIT(AVI_ERR_NO_MEM) ; } } else { int n; for(n = 0; n < AVI->n_audio; n++) { avi_audio_t *audio = AVI->audio[n]; if((AVI->idx[i][0] == audio->audio_tag[0]) && (AVI->idx[i][1] == audio->audio_tag[1])) { off_t pos = _X_LE_32(AVI->idx[i] + 8) + ioff; uint32_t len = _X_LE_32(AVI->idx[i] + 12); /* VBR streams (hack from mplayer) */ if (audio->wavex && audio->wavex->nBlockAlign) { audio->block_no += (len + audio->wavex->nBlockAlign - 1) / audio->wavex->nBlockAlign; } else { audio->block_no += 1; } if (audio_index_append(AVI, n, pos, len, audio->audio_tot, audio->block_no) == -1) { ERR_EXIT(AVI_ERR_NO_MEM) ; } AVI->audio[n]->audio_tot += len; break; } } } } } else if (AVI->is_opendml && !this->streaming) { uint64_t offset = 0; int hdrl_len = 4+4+2+1+1+4+4+8+4; char *en, *chunk_start; int k = 0, audtr = 0; uint32_t nrEntries = 0; int nvi, nai[MAX_AUDIO_STREAMS]; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_avi: This is an OpenDML stream\n"); nvi = 0; for(audtr=0; audtrn_audio; ++audtr) nai[audtr] = 0; /* ************************ */ /* VIDEO */ /* ************************ */ lprintf("video track\n"); if (AVI->video_superindex != NULL) { unsigned int j; for (j=0; jvideo_superindex->nEntriesInUse; j++) { /* read from file */ chunk_start = en = malloc (AVI->video_superindex->aIndex[j].dwSize+hdrl_len); if (!chunk_start) ERR_EXIT(AVI_ERR_NO_MEM); if (this->input->seek(this->input, AVI->video_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) { lprintf("cannot seek to 0x%" PRIx64 "\n", AVI->video_superindex->aIndex[j].qwOffset); free(chunk_start); continue; } if (this->input->read(this->input, en, AVI->video_superindex->aIndex[j].dwSize+hdrl_len) <= 0) { lprintf("cannot read from offset 0x%" PRIx64 " %ld bytes; broken (incomplete) file?\n", AVI->video_superindex->aIndex[j].qwOffset, (unsigned long)AVI->video_superindex->aIndex[j].dwSize+hdrl_len); free(chunk_start); continue; } nrEntries = _X_LE_32(en + 12); #ifdef DEBUG_ODML printf("[%d:0] Video nrEntries %ld\n", j, (long)nrEntries); #endif offset = _X_LE_64(en + 20); /* skip header */ en += hdrl_len; nvi += nrEntries; while (k < nvi) { off_t pos; uint32_t len; uint32_t flags; pos = offset + _X_LE_32(en); en += 4; len = odml_len(en); flags = odml_key(en); en += 4; video_index_append(AVI, pos, len, flags); #ifdef DEBUG_ODML /* printf("[%d] POS 0x%llX len=%d key=%s offset (%llx) (%ld)\n", k, pos, len, flags?"yes":"no ", offset, (long)AVI->video_superindex->aIndex[j].dwSize); */ #endif k++; } free(chunk_start); } } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: Warning: the video super index is NULL\n"); } /* ************************ */ /* AUDIO */ /* ************************ */ lprintf("audio tracks\n"); for(audtr=0; audtrn_audio; ++audtr) { avi_audio_t *audio = AVI->audio[audtr]; unsigned int j; k = 0; if (!audio->audio_superindex) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: Warning: cannot read audio index for track %d\n", audtr); continue; } for (j=0; jaudio_superindex->nEntriesInUse; j++) { /* read from file */ chunk_start = en = malloc (audio->audio_superindex->aIndex[j].dwSize+hdrl_len); if (!chunk_start) ERR_EXIT(AVI_ERR_NO_MEM); if (this->input->seek(this->input, audio->audio_superindex->aIndex[j].qwOffset, SEEK_SET) == (off_t)-1) { lprintf("cannot seek to 0x%" PRIx64 "\n", audio->audio_superindex->aIndex[j].qwOffset); free(chunk_start); continue; } if (this->input->read(this->input, en, audio->audio_superindex->aIndex[j].dwSize+hdrl_len) <= 0) { lprintf("cannot read from offset 0x%" PRIx64 "; broken (incomplete) file?\n", audio->audio_superindex->aIndex[j].qwOffset); free(chunk_start); continue; } nrEntries = _X_LE_32(en + 12); #ifdef DEBUG_ODML /*printf("[%d:%d] Audio nrEntries %ld\n", j, audtr, nrEntries); */ #endif offset = _X_LE_64(en + 20); /* skip header */ en += hdrl_len; nai[audtr] += nrEntries; while (k < nai[audtr]) { off_t pos; uint32_t len; pos = offset + _X_LE_32(en); en += 4; len = odml_len(en); en += 4; /* VBR streams (hack from mplayer) */ if (audio->wavex && audio->wavex->nBlockAlign) { audio->block_no += (len + audio->wavex->nBlockAlign - 1) / audio->wavex->nBlockAlign; } else { audio->block_no += 1; } audio_index_append(AVI, audtr, pos, len, audio->audio_tot, audio->block_no); #ifdef DEBUG_ODML /* printf("[%d:%d] POS 0x%llX len=%d offset (%llx) (%ld)\n", k, audtr, pos, (int)len, offset, (long)audio->audio_superindex->aIndex[j].dwSize); */ #endif audio->audio_tot += len; ++k; } free(chunk_start); } } } if (this->has_index) { int n; /* check index validity, there must be an index for each video/audio stream */ if (AVI->video_idx.video_frames == 0) { reset_idx(this, AVI); } for (n = 0; n < AVI->n_audio; n++) { if (AVI->audio[n]->audio_idx.audio_chunks == 0) { reset_idx(this, AVI); } } } else { /* We'll just dynamically grow the index as needed. */ lprintf("no index\n"); this->idx_grow.nexttagoffset = AVI->movi_start; this->has_index = 0; } /* Reposition the file */ if (!this->streaming) this->input->seek(this->input, AVI->movi_start, SEEK_SET); AVI->video_posf = 0; AVI->video_posb = 0; lprintf("done, pos=%"PRId64", AVI->movi_start=%" PRIdMAX "\n", this->input->get_current_pos(this->input), (intmax_t)AVI->movi_start); return AVI; } static void AVI_seek_start(avi_t *AVI) { int i; AVI->video_posf = 0; AVI->video_posb = 0; for(i = 0; i < AVI->n_audio; i++) { AVI->audio[i]->audio_posc = 0; AVI->audio[i]->audio_posb = 0; } } static int AVI_read_audio(demux_avi_t *this, avi_audio_t *AVI_A, char *audbuf, uint32_t bytes, int *buf_flags) { off_t pos; int nr, left, todo; audio_index_entry_t *aie = audio_cur_index_entry(this, AVI_A); if(!aie) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; } nr = 0; /* total number of bytes read */ /* lprintf ("avi audio package len: %d\n", AVI_A->audio_index[AVI_A->audio_posc].len); */ left = aie->len - AVI_A->audio_posb; while ((bytes > 0) && (left > 0)) { if ((int)bytes < left) todo = bytes; else todo = left; pos = aie->pos + AVI_A->audio_posb; /* lprintf ("read audio from %lld\n", pos); */ if (this->input->seek (this->input, pos, SEEK_SET)<0) return -1; if (this->input->read(this->input, audbuf + nr, todo) != todo) { this->AVI_errno = AVI_ERR_READ; *buf_flags = 0; return -1; } bytes -= todo; nr += todo; AVI_A->audio_posb += todo; left = aie->len - AVI_A->audio_posb; } if (left == 0) { AVI_A->audio_posc++; AVI_A->audio_posb = 0; *buf_flags = BUF_FLAG_FRAME_END; } else { *buf_flags = 0; } return nr; } static int AVI_read_video(demux_avi_t *this, avi_t *AVI, char *vidbuf, uint32_t bytes, int *buf_flags) { off_t pos; int nr, left, todo; video_index_entry_t *vie = video_cur_index_entry(this); if (!vie) { this->AVI_errno = AVI_ERR_NO_IDX; return -1; } nr = 0; /* total number of bytes read */ left = vie->len - AVI->video_posb; while ((bytes > 0) && (left > 0)) { if ((int)bytes < left) todo = bytes; else todo = left; pos = vie->pos + AVI->video_posb; /* lprintf ("read video from %lld\n", pos); */ if (this->input->seek (this->input, pos, SEEK_SET)<0) return -1; if (this->input->read(this->input, vidbuf + nr, todo) != todo) { this->AVI_errno = AVI_ERR_READ; *buf_flags = 0; return -1; } bytes -= todo; nr += todo; AVI->video_posb += todo; left = vie->len - AVI->video_posb; } if (left == 0) { AVI->video_posf++; AVI->video_posb = 0; *buf_flags = BUF_FLAG_FRAME_END; } else { *buf_flags = 0; } return nr; } static int demux_avi_next (demux_avi_t *this, int decoder_flags) { int i; buf_element_t *buf = NULL; int64_t audio_pts, video_pts; int do_read_video = (this->avi->n_audio == 0); int video_sent = 0; int audio_sent = 0; lprintf("begin\n"); /* Try to grow the index, in case more of the avi file has shown up * since we last checked. If it's still too small, well then we're at * the end of the stream. */ if (this->avi->video_idx.video_frames <= this->avi->video_posf) { if (idx_grow(this, video_pos_stopper, NULL) < 0) { lprintf("end of stream\n"); } } for (i = 0; i < this->avi->n_audio; i++) { avi_audio_t *audio = this->avi->audio[i]; if (!this->no_audio && (audio->audio_idx.audio_chunks <= audio->audio_posc)) { if (idx_grow(this, audio_pos_stopper, this->avi->audio[i]) < 0) { lprintf("end of stream\n"); } } } video_pts = get_video_pts (this, this->avi->video_posf); for (i=0; i < this->avi->n_audio; i++) { avi_audio_t *audio = this->avi->audio[i]; audio_index_entry_t *aie = audio_cur_index_entry(this, audio); /* The tests above mean aie should never be NULL, but just to be * safe. */ if (!aie) { lprintf("aie == NULL\n"); continue; } audio_pts = get_audio_pts (this, i, aie->block_no, aie->tot, audio->audio_posb); lprintf ("video_pts %" PRId64 " audio_pts %" PRId64 "\n", video_pts, audio_pts); if (!this->no_audio && (audio_pts < video_pts)) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); /* read audio */ buf->pts = audio_pts; buf->size = AVI_read_audio (this, audio, buf->mem, buf->max_size, &buf->decoder_flags); buf->decoder_flags |= decoder_flags; if (buf->size < 0) { buf->free_buffer (buf); lprintf("audio buf->size < 0\n"); } else { buf->type = audio->audio_type | i; buf->extra_info->input_time = audio_pts / 90; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); check_newpts (this, buf->pts, PTS_AUDIO); this->audio_fifo->put (this->audio_fifo, buf); audio_sent++; } } else do_read_video = 1; } if (audio_sent == 0) { do_read_video = 1; } if (do_read_video) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); /* read video */ buf->pts = video_pts; buf->size = AVI_read_video (this, this->avi, buf->mem, buf->max_size, &buf->decoder_flags); buf->type = this->avi->video_type; buf->extra_info->input_time = video_pts / 90; if (this->has_index && this->avi->video_idx.video_frames > 2) { /* use video_frames-2 instead of video_frames-1 to fix problems with weird non-interleaved streams */ buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->avi->video_idx.vindex[this->avi->video_idx.video_frames - 2].pos); } else { if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); } buf->extra_info->frame_number = this->avi->video_posf; buf->decoder_flags |= decoder_flags; if (buf->size < 0) { buf->free_buffer (buf); lprintf("video buf->size < 0\n"); } else { /* lprintf ("adding buf %d to video fifo, decoder_info[0]: %d\n", buf, buf->decoder_info[0]); */ check_newpts (this, buf->pts, PTS_VIDEO); this->video_fifo->put (this->video_fifo, buf); video_sent++; } } if (!audio_sent && !video_sent) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_avi: video and audio streams are ended\n"); return 0; } return 1; } /* * Returns next chunk type * It's used in streaming mode */ static int get_chunk_header(demux_avi_t *this, uint32_t *len, int *audio_stream) { int i; char data[AVI_HEADER_SIZE]; while (1) { if (this->input->read(this->input, data, AVI_HEADER_SIZE) != AVI_HEADER_SIZE) break; *len = _X_LE_32(data + 4); lprintf("header: %c%c%c%c, pos=%" PRIdMAX ", len=%u\n", data[0], data[1], data[2], data[3], (intmax_t)this->input->get_current_pos(this->input), *len); /* Dive into RIFF and LIST entries */ if(strncasecmp(data, "LIST", 4) == 0 || strncasecmp(data, "RIFF", 4) == 0) { this->idx_grow.nexttagoffset = this->input->seek(this->input, 4,SEEK_CUR); continue; } /* * Check if we got a tag ##db, ##dc or ##wb * only the 2 first bytes are reliable */ if ((data[0] == this->avi->video_tag[0]) && (data[1] == this->avi->video_tag[1])) { lprintf("video header: %c %c %c %c\n", data[0], data[1], data[2], data[3]); return AVI_HEADER_VIDEO; } for(i = 0; i < this->avi->n_audio; ++i) { avi_audio_t *audio = this->avi->audio[i]; /* * only the 2 first bytes are reliable */ if ((data[0] == audio->audio_tag[0]) && (data[1] == audio->audio_tag[1])) { *audio_stream = i; audio->audio_tot += *len; lprintf("audio header: %c %c %c %c\n", data[0], data[1], data[2], data[3]); return AVI_HEADER_AUDIO; } } xine_log (this->stream->xine, XINE_LOG_MSG, _("demux_avi: invalid avi chunk \"%c%c%c%c\" at pos %" PRIdMAX "\n"), data[0], data[1], data[2], data[3], (intmax_t)this->input->get_current_pos(this->input)); return AVI_HEADER_UNKNOWN; } /* unreachable code */ return AVI_HEADER_UNKNOWN; } /* * Read next chunk * It's streaming version of demux_avi_next() * There is no seeking here. */ static int demux_avi_next_streaming (demux_avi_t *this, int decoder_flags) { buf_element_t *buf = NULL; int64_t audio_pts, video_pts; off_t current_pos; int left; int header, chunk_len = 0, audio_stream; avi_audio_t *audio; current_pos = this->input->get_current_pos(this->input); lprintf("input_pos=%" PRIdMAX "\n", (intmax_t)current_pos); header = get_chunk_header(this, &chunk_len, &audio_stream); switch (header) { case AVI_HEADER_AUDIO: audio = this->avi->audio[audio_stream]; left = chunk_len; lprintf("AVI_HEADER_AUDIO: chunk %d, len=%d\n", audio->audio_posc, chunk_len); while (left > 0) { audio_pts = get_audio_pts (this, audio_stream, audio->block_no, audio->audio_tot - chunk_len, chunk_len - left); buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); /* read audio */ buf->pts = audio_pts; lprintf("audio pts: %" PRId64 "\n", audio_pts); if (left > this->audio_fifo->buffer_pool_buf_size) { buf->size = this->audio_fifo->buffer_pool_buf_size; buf->decoder_flags = 0; } else { buf->size = left; buf->decoder_flags = BUF_FLAG_FRAME_END; } left -= buf->size; if (this->input->read(this->input, buf->mem, buf->size) != buf->size) { buf->free_buffer (buf); return 0; } buf->extra_info->input_time = audio_pts / 90; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); buf->type = audio->audio_type | audio_stream; this->audio_fifo->put (this->audio_fifo, buf); } audio->audio_posc++; /* VBR streams (hack from mplayer) */ if (audio->wavex && audio->wavex->nBlockAlign) { audio->block_no += (chunk_len + audio->wavex->nBlockAlign - 1) / audio->wavex->nBlockAlign; } else { audio->block_no += 1; } break; case AVI_HEADER_VIDEO: left = chunk_len; lprintf("AVI_HEADER_VIDEO: chunk %d, len=%d\n", this->avi->video_posf, chunk_len); while (left > 0) { video_pts = get_video_pts (this, this->avi->video_posf); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); /* read video */ buf->pts = video_pts; lprintf("video pts: %" PRId64 "\n", video_pts); if (left > this->video_fifo->buffer_pool_buf_size) { buf->size = this->video_fifo->buffer_pool_buf_size; buf->decoder_flags = 0; } else { buf->size = left; buf->decoder_flags = BUF_FLAG_FRAME_END; } left -= buf->size; if (this->input->read(this->input, buf->mem, buf->size) != buf->size) { buf->free_buffer (buf); return 0; } buf->type = this->avi->video_type; buf->extra_info->input_time = video_pts / 90; buf->extra_info->input_normpos = 65535; buf->extra_info->frame_number = this->avi->video_posf; buf->decoder_flags |= decoder_flags; this->video_fifo->put (this->video_fifo, buf); } this->avi->video_posf++; break; case AVI_HEADER_UNKNOWN: current_pos = this->input->get_current_pos(this->input); if (this->input->seek(this->input, chunk_len, SEEK_CUR) != (current_pos + chunk_len)) { return 0; } break; } /* skip padding */ this->input->seek (this->input, this->input->get_current_pos(this->input) & 1, SEEK_CUR); lprintf("done\n"); return 1; } static int demux_avi_seek_internal (demux_avi_t *this); static int demux_avi_send_chunk (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; if (this->streaming) { if (!demux_avi_next_streaming (this, 0)) { this->status = DEMUX_FINISHED; } } else { if (this->seek_request) { this->seek_request = 0; demux_avi_seek_internal(this); } if (!demux_avi_next (this, 0)) { this->status = DEMUX_FINISHED; } } return this->status; } static void demux_avi_dispose (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; if (this->avi) AVI_close (this->avi); free(this); } static int demux_avi_get_status (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; return this->status; } static void demux_avi_send_headers (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; int i; lprintf("start\n"); this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->avi->width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->avi->height); if (this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) { for (i=0; i < this->avi->n_audio; i++) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: audio format[%d] = 0x%x\n", i, this->avi->audio[i]->wavex->wFormatTag); } this->no_audio = 0; if (!this->avi->bih->biCompression) this->avi->video_type = BUF_VIDEO_RGB; else { this->avi->video_type = _x_fourcc_to_buf_video(this->avi->bih->biCompression); if (!this->avi->video_type) _x_report_video_fourcc (this->stream->xine, LOG_MODULE, this->avi->bih->biCompression); } for(i=0; i < this->avi->n_audio; i++) { this->avi->audio[i]->audio_type = _x_formattag_to_buf_audio (this->avi->audio[i]->wavex->wFormatTag); if ((uint16_t)this->avi->audio[i]->wavex->wFormatTag == 0xfffe /*WAVE_FORMAT_EXTENSIBLE */ && this->avi->audio[i]->wavex_len >= 18 + 6 + 4 ) { /* extended header */ char *p = (char *)this->avi->audio[i]->wavex + 18 /*sizeof(this->avi->audio[i]->wavex*/; uint32_t fourcc = _X_LE_32(p + 6); this->avi->audio[i]->audio_type = _x_formattag_to_buf_audio (fourcc); } /* special case time: An AVI file encoded with Xan video will have Xan * DPCM audio marked as PCM; hack around this */ if (this->avi->video_type == BUF_VIDEO_XXAN) { this->avi->audio[i]->audio_type = BUF_AUDIO_XAN_DPCM; this->avi->audio[i]->dwRate = 11025; /* why this ??? */ } if( !this->avi->audio[i]->audio_type ) { this->no_audio = 1; this->avi->audio[i]->audio_type = BUF_AUDIO_UNKNOWN; _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, this->avi->audio[i]->wavex->wFormatTag); } else xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: audio type %s (wFormatTag 0x%x)\n", _x_buf_audio_name(this->avi->audio[i]->audio_type), (int)this->avi->audio[i]->wavex->wFormatTag); } /* * I don't know who should we trust more, if avi->compressor or bih->biCompression. * however, at least for this case (compressor: xvid biCompression: DIVX), the * xvid fourcc must prevail as it is used by ffmpeg to detect encoder bugs. [MF] */ if( this->avi->video_type == BUF_VIDEO_MPEG4 && _x_fourcc_to_buf_video(this->avi->compressor) == BUF_VIDEO_XVID ) { this->avi->bih->biCompression = this->avi->compressor; this->avi->video_type = BUF_VIDEO_XVID; } _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, !this->no_audio); _x_meta_info_set(this->stream, XINE_META_INFO_VIDEOCODEC, _x_buf_video_name(this->avi->video_type)); if (this->avi->audio[0] && !this->no_audio) _x_meta_info_set(this->stream, XINE_META_INFO_AUDIOCODEC, _x_buf_audio_name(this->avi->audio[0]->audio_type)); /* * send start/header buffers */ { buf_element_t *buf; int i; _x_demux_control_start (this->stream); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); if (this->avi->bih->biSize > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_avi: private video decoder data length (%d) is greater than fifo buffer length (%d)\n", this->avi->bih->biSize, buf->max_size); buf->free_buffer(buf); this->status = DEMUX_FINISHED; return; } /* wait, before sending out the video header, one more special case hack: * if the video type is RGB, indicate that it is upside down with a * negative height */ if (this->avi->video_type == BUF_VIDEO_RGB) { this->avi->bih->biHeight = -this->avi->bih->biHeight; } buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->video_step; memcpy (buf->content, this->avi->bih, this->avi->bih->biSize); buf->size = this->avi->bih->biSize; if (this->avi->video_type) { this->avi->compressor = this->avi->bih->biCompression; } else { this->avi->video_type = _x_fourcc_to_buf_video(this->avi->compressor); if (!this->avi->video_type) _x_fourcc_to_buf_video(this->avi->bih->biCompression); } _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, this->avi->compressor); if (!this->avi->video_type) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: unknown video codec '%.4s'\n", (char*)&this->avi->bih->biCompression); this->avi->video_type = BUF_VIDEO_UNKNOWN; } buf->type = this->avi->video_type; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: video codec is '%s'\n", _x_buf_video_name(buf->type)); this->video_fifo->put (this->video_fifo, buf); /* send off the palette, if there is one */ if (this->avi->palette_count) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = this->avi->palette_count; buf->decoder_info_ptr[2] = &this->avi->palette; buf->size = 0; buf->type = this->avi->video_type; this->video_fifo->put (this->video_fifo, buf); } if (this->audio_fifo) { for (i=0; iavi->n_audio; i++) { avi_audio_t *a = this->avi->audio[i]; uint32_t todo = a->wavex_len; uint32_t done = 0; while (todo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); if ((int)todo > buf->max_size) { buf->size = buf->max_size; } else { buf->size = todo; } todo -= buf->size; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER; if (todo == 0) buf->decoder_flags |= BUF_FLAG_FRAME_END; memcpy (buf->content, (uint8_t *)a->wavex + done, buf->size); buf->type = a->audio_type | i; buf->decoder_info[0] = 0; /* first package, containing wavex */ buf->decoder_info[1] = a->wavex->nSamplesPerSec; /* Audio Rate */ buf->decoder_info[2] = a->wavex->wBitsPerSample; /* Audio bits */ buf->decoder_info[3] = a->wavex->nChannels; /* Audio channels */ this->audio_fifo->put (this->audio_fifo, buf); done += buf->size; } } if(this->avi->n_audio == 1) _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, this->avi->audio[0]->wavex->wFormatTag); } /* * send preview buffers */ AVI_seek_start (this->avi); if (!this->streaming) { for (i=0; istreaming) { _x_demux_flush_engine (this->stream); this->seek_request = 1; this->seek_start_pos = start_pos; this->seek_start_time = start_time; this->status = DEMUX_OK; } return this->status; } static int demux_avi_seek_internal (demux_avi_t *this) { int64_t video_pts = 0, max_pos, min_pos = 0, cur_pos; video_index_entry_t *vie = NULL; int64_t audio_pts; off_t start_pos = this->seek_start_pos; int start_time = this->seek_start_time; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); this->status = DEMUX_OK; if (this->streaming) return this->status; AVI_seek_start (this->avi); /* * seek to start pos / time */ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "start pos is %" PRIdMAX ", start time is %d\n", (intmax_t)start_pos, start_time); /* Seek video. We do a single idx_grow at the beginning rather than * incrementally growing the index in a loop, so that if the index * grow is going to take a while, the user is notified via the OSD * (which only shows up if >= 1000 index entries are added at a time). */ /* We know for sure the last index entry is past our starting * point; find the lowest index entry that's past our starting * point. */ min_pos = 0; if (start_pos) { idx_grow(this, start_pos_stopper, &start_pos); } else if (start_time) { video_pts = start_time * 90; idx_grow(this, start_time_stopper, &video_pts); } if (start_pos || start_time) max_pos = this->avi->video_idx.video_frames - 1; else max_pos=0; cur_pos = this->avi->video_posf; if (max_pos < 0) { this->status = DEMUX_FINISHED; return this->status; } else if (start_pos) { while (min_pos < max_pos) { this->avi->video_posf = cur_pos = (min_pos + max_pos) / 2; if (cur_pos == min_pos) break; vie = video_cur_index_entry(this); if (vie->pos >= start_pos) { max_pos = cur_pos; } else { min_pos = cur_pos; } } } else if (start_time) { while (min_pos < max_pos) { this->avi->video_posf = cur_pos = (min_pos + max_pos) / 2; if (cur_pos == min_pos) break; vie = video_cur_index_entry(this); if (get_video_pts (this, cur_pos) >= video_pts) { max_pos = cur_pos; } else { min_pos = cur_pos; } } } while (vie && !(vie->flags & AVIIF_KEYFRAME) && cur_pos) { this->avi->video_posf = --cur_pos; vie = video_cur_index_entry(this); } if (!vie || !(vie->flags & AVIIF_KEYFRAME)) { lprintf ("No previous keyframe found\n"); } video_pts = get_video_pts (this, cur_pos); /* Seek audio. We can do this incrementally, on the theory that the * audio position we're looking for will be pretty close to the video * position we've already found, so we won't be seeking though the * file much at this point. */ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "video_pts = %" PRId64 "\n", video_pts); /* FIXME ? */ audio_pts = 77777777; if (!this->no_audio && this->status == DEMUX_OK) { audio_index_entry_t *aie; int i; for(i = 0; i < this->avi->n_audio; i++) { max_pos = this->avi->audio[i]->audio_idx.audio_chunks - 1; min_pos = 0; lprintf("audio_chunks=%d, min=%" PRId64 ", max=%" PRId64 "\n", this->avi->audio[i]->audio_idx.audio_chunks, min_pos, max_pos); while (min_pos < max_pos) { cur_pos = this->avi->audio[i]->audio_posc = (max_pos + min_pos) / 2; if (cur_pos == min_pos) break; aie = audio_cur_index_entry(this, this->avi->audio[i]); if (aie) { if ( (audio_pts = get_audio_pts(this, i, aie->block_no, aie->tot, 0)) >= video_pts) { max_pos = cur_pos; } else { min_pos = cur_pos; } lprintf ("audio_pts = %" PRId64 " %" PRId64 " < %" PRId64 " < %" PRId64 "\n", audio_pts, min_pos, cur_pos, max_pos); } else { if (cur_pos > min_pos) { max_pos = cur_pos; } else { this->status = DEMUX_FINISHED; lprintf ("audio seek to start failed\n"); break; } } } lprintf ("audio_pts = %" PRId64 "\n", audio_pts); /* * try to make audio pos more accurate for long index entries * * yeah, i know this implementation is pathetic (gb) */ if ((audio_pts > video_pts) && (this->avi->audio[i]->audio_posc>0)) this->avi->audio[i]->audio_posc--; aie = audio_cur_index_entry(this, this->avi->audio[i]); if (aie) { while ((this->avi->audio[i]->audio_posb < aie->len) && ((audio_pts = get_audio_pts(this, i, aie->block_no, aie->tot, this->avi->audio[i]->audio_posb)) < video_pts)) this->avi->audio[i]->audio_posb++; } } } lprintf ("video posc: %d\n", this->avi->video_posf); this->send_newpts = 1; this->buf_flag_seek = 1; _x_demux_control_newpts (this->stream, video_pts, BUF_FLAG_SEEK); return this->status; } static int demux_avi_get_stream_length (demux_plugin_t *this_gen) { demux_avi_t *this = (demux_avi_t *) this_gen; if (this->avi) { if (this->streaming) { return (int)(get_video_pts(this, this->avi->video_posf) / 90); } else { return (int)(get_video_pts(this, this->avi->video_idx.video_frames) / 90); } } return 0; } static uint32_t demux_avi_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_avi_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_avi_t *this; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint8_t buf[12]; if (input->get_capabilities(input) & INPUT_CAP_BLOCK) return NULL; if (_x_demux_read_header(input, buf, 12) != 12) return NULL; if( !( (strncasecmp(buf ,"ON2 ",4) == 0 && strncasecmp(buf+8,"ON2f",4) == 0) || (strncasecmp(buf ,"RIFF",4) == 0 && strncasecmp(buf+8,"AVI ",4) == 0) ) ) return NULL; } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } this = calloc(1, sizeof(demux_avi_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_avi_send_headers; this->demux_plugin.send_chunk = demux_avi_send_chunk; this->demux_plugin.seek = demux_avi_seek; this->demux_plugin.dispose = demux_avi_dispose; this->demux_plugin.get_status = demux_avi_get_status; this->demux_plugin.get_stream_length = demux_avi_get_stream_length; this->demux_plugin.get_capabilities = demux_avi_get_capabilities; this->demux_plugin.get_optional_data = demux_avi_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!INPUT_IS_SEEKABLE(input)) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "streaming mode\n"); this->streaming = 1; } this->avi = AVI_init (this); if (!this->avi) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "AVI_init failed (AVI_errno: %d)\n", this->AVI_errno); free (this); return NULL; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_avi: %d frames\n", this->avi->video_idx.video_frames); return &this->demux_plugin; } /* * demux avi class */ void *demux_avi_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_avi_class = { .open_plugin = open_plugin, .description = N_("AVI/RIFF demux plugin"), .identifier = "AVI", .mimetypes = "video/msvideo: avi: AVI video;" "video/x-msvideo: avi: AVI video;", .extensions = "avi", .dispose = NULL, }; return (void *)&demux_avi_class; } xine-lib-1.2/src/demuxers/demux_flac.c0000644000175000017500000007217014647725152015571 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * FLAC File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information on the FLAC file format, visit: * http://flac.sourceforge.net/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifdef HAVE_MALLOC_H #include #endif #define LOG_MODULE "demux_flac" #define LOG_VERBOSE /* #define LOG */ #define USE_FRAME_BUF #include #include #include #include #include "bswap.h" #include "group_audio.h" #include "id3.h" #include "flacutils.h" typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int sample_rate; int bits_per_sample; int channels; int64_t total_samples; off_t data_start; off_t data_size; flac_seekpoint_t *seekpoints; int seekpoint_count; #ifdef USE_FRAME_BUF uint8_t frame_head_crc_tab[256]; uint8_t frame_head[16]; uint8_t *frame_buf; uint32_t frame_buf_used; uint32_t frame_buf_size; off_t frame_buf_filepos; struct { off_t filepos; uint32_t rate; uint32_t bits; uint32_t channels; uint32_t vbs; uint32_t hsize; uint32_t bsize; uint32_t num; uint32_t max_size; uint32_t buf_pos; } frame1, frame2; int64_t last_pts; int seek_flag; int read_errs; #endif unsigned char streaminfo[sizeof(xine_waveformatex) + FLAC_STREAMINFO_SIZE]; } demux_flac_t; #ifdef USE_FRAME_BUF static const uint32_t flac_sample_rates[16] = { 0, 88200, 176400, 192000, 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 1, 2, 3, 0 }; static const uint32_t flac_blocksizes[16] = { 0, 192, 576, 2 * 576, 4 * 576, 8 * 576, 1, 2, 256, 2 * 256, 4 * 256, 8 * 256, 16 * 256, 32 * 256, 64 * 256, 128 * 256 }; static const uint8_t flac_sample_sizes[8] = { 0, 8, 12, 0, 16, 20, 24, 0 }; static const uint8_t flac_channels[16] = { 1, /* mono */ 2, /* stereo */ 3, /* surround */ 4, /* quadrophonic */ 5, /* 5.0 */ 6, /* 5.1 */ 7, /* 6.1 */ 8, /* 7.1 */ 2, /* left + side */ 2, /* right + side */ 2, /* mid + side */ 0, 0, 0, 0, 0 }; static void flac_init_frame_head (demux_flac_t *flac) { uint32_t i, j, v; for (i = 0; i < 256; i++) { v = i << 24; for (j = 0; j < 8; j++) v = (v << 1) ^ (0x07000000 & (((int32_t)v) >> 31)); flac->frame_head_crc_tab[i] = v >> 24; } } static void flac_reset_head (demux_flac_t *flac) { flac->frame1.buf_pos = 0; flac->frame2.buf_pos = 0; flac->frame1.hsize = 0; flac->frame2.hsize = 0; flac->frame_buf_used = 0; } static uint32_t flac_test_frame_head (demux_flac_t *flac, uint32_t len) { uint8_t *p = flac->frame_head; uint32_t v = 0; while (len--) v = (v >> 8) ^ flac->frame_head_crc_tab[*p++ ^ (v & 0xff)]; return v; } static int flac_parse_frame_head (demux_flac_t *flac) { const uint8_t *p = flac->frame_head; uint32_t v; /* sync word */ if (p[0] != 0xff) return 1; if ((p[1] & 0xfe) != 0xf8) return 1; /* reserved */ if (flac->frame_head[3] & 1) return 2; /* variable block size */ flac->frame2.vbs = flac->frame_head[1] & 0x01; /* channels */ v = flac_channels[flac->frame_head[3] >> 4]; if (v == 0) return 2; flac->frame2.channels = v; /* bits */ v = flac_sample_sizes[(flac->frame_head[3] >> 1) & 7]; if (v == 0) return 2; flac->frame2.bits = v; /* frame num (fixed block size) or sample num (utf8) */ p += 4; v = _X_BE_32 (p); if ((v & 0x80000000) == 0) { flac->frame2.num = v >> 24; p += 1; } else if ((v & 0xe0c00000) == 0xc0800000) { flac->frame2.num = ((v & 0x1f000000) >> 18) | ((v & 0x003f0000) >> 16); p += 2; } else if ((v & 0xf0c0c000) == 0xe0808000) { flac->frame2.num = ((v & 0x0f000000) >> 12) | ((v & 0x003f0000) >> 10) | ((v & 0x00003f00) >> 8); p += 3; } else if ((v & 0xf8c0c0c0) == 0xf0808080) { flac->frame2.num = ((v & 0x07000000) >> 6) | ((v & 0x003f0000) >> 4) | ((v & 0x00003f00) >> 2) | (v & 0x0000003f); p += 4; } else if ((v & 0xfcc0c0c0) == 0xf8808080) { flac->frame2.num = (v & 0x03000000) | ((v & 0x003f0000) << 2) | ((v & 0x00003f00) << 4) | ((v & 0x0000003f) << 6) | (p[4] & 0x3f); p += 5; } else if ((v & 0xfec0c0c0) == 0xfc808080) { flac->frame2.num = ((v & 0x01000000) << 6) | ((v & 0x003f0000) << 8) | ((v & 0x00003f00) << 10) | ((v & 0x0000003f) << 12) | ((p[4] & 0x3f) << 6) | (p[5] & 0x3f); p += 6; } else { return 2; } /* block size */ v = flac_blocksizes[flac->frame_head[2] >> 4]; if (v < 4) { switch (v) { case 1: v = *p++ + 1; break; case 2: v = _X_BE_16 (p) + 1; p += 2; break; default: return 2; } } flac->frame2.bsize = v; /* sample rate */ v = flac_sample_rates[flac->frame_head[2] & 0x0f]; if (v < 4) { switch (v) { case 1: v = *p++ * 1000; break; case 2: v = _X_BE_16 (p); p += 2; break; case 3: v = _X_BE_16 (p) * 10; p += 2; break; default: return 2; } } flac->frame2.rate = v; /* crc test */ p++; flac->frame2.hsize = p - flac->frame_head; if (flac_test_frame_head (flac, flac->frame2.hsize) != 0) return 2; /* flac shall make things smaller than the uncompressed size. */ /* frame head + frame crc + channel heads */ v = 18 + flac->frame2.channels * (((flac->frame2.bits + 7) >> 3) + 1); /* uncompressed samples */ if (flac->frame2.channels == 2) v += ((2 * flac->frame2.bits + 1) * flac->frame2.bsize + 7) >> 3; else v += (flac->frame2.channels * flac->frame2.bits * flac->frame2.bsize + 7) >> 3; flac->frame2.max_size = v; return 0; } static int flac_get_frame (demux_flac_t *flac) { int r = -1; uint32_t v; uint8_t *p, *e; flac->frame1 = flac->frame2; p = flac->frame_buf + flac->frame2.buf_pos + flac->frame2.hsize; e = flac->frame_buf + flac->frame_buf_used; memcpy (e, "\xff\xf8\x00\x00", 4); v = _X_BE_32 (p); p += 4; while (1) { uint32_t l; int32_t s; while ((v & 0xfffe0001) != 0xfff80000) v = (v << 8) | *p++; if (p + sizeof (flac->frame_head) - 4 <= e) { flac->frame2.buf_pos = p - 4 - flac->frame_buf; flac->frame2.filepos = flac->frame_buf_filepos + flac->frame2.buf_pos; memcpy (flac->frame_head, flac->frame_buf + flac->frame2.buf_pos, sizeof (flac->frame_head)); r = flac_parse_frame_head (flac); if (r == 0) break; v = (v << 8) | *p++; continue; } if (flac->frame1.bits == 0) { p = flac->frame_buf + 4; flac->frame1.buf_pos = 0; flac->frame_buf_used = 0; } else if (flac->frame1.buf_pos) { l = flac->frame_buf_used - flac->frame1.buf_pos; if (l) { if (l <= flac->frame1.buf_pos) memcpy (flac->frame_buf, flac->frame_buf + flac->frame1.buf_pos, l); else memmove (flac->frame_buf, flac->frame_buf + flac->frame1.buf_pos, l); } p -= flac->frame1.buf_pos; flac->frame1.buf_pos = 0; flac->frame_buf_used = l; } flac->frame2.buf_pos = p - 4 - flac->frame_buf; flac->frame2.hsize = 0; l = flac->frame_buf_size - flac->frame_buf_used; if (!l) break; flac->frame_buf_filepos = flac->input->get_current_pos (flac->input) - flac->frame_buf_used; s = flac->input->read (flac->input, flac->frame_buf + flac->frame_buf_used, l); if (s <= 0) break; flac->frame_buf_used += s; e = flac->frame_buf + flac->frame_buf_used; memcpy (e, "\xff\xf8\x00\x00", 4); v = _X_BE_32 (p - 4); } /* enlarge buf? */ if ((r == 0) && (flac->frame2.max_size > flac->frame_buf_size)) { uint32_t need = 3 * flac->frame2.max_size / 2; uint8_t *n = realloc (flac->frame_buf, need + 16); if (n) { flac->frame_buf = n; flac->frame_buf_size = need; xprintf (flac->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: frame buffer enlarged to %u bytes.\n", (unsigned int)need); } } return flac->frame2.buf_pos - flac->frame1.buf_pos; } #endif /* Open a flac file * This function is called from the _open() function of this demuxer. * It returns 1 if flac file was opened successfully. */ static int open_flac_file(demux_flac_t *flac) { uint32_t signature; unsigned char preamble[10]; unsigned int block_length; unsigned char buffer[FLAC_SEEKPOINT_SIZE]; unsigned char *streaminfo = flac->streaminfo + sizeof(xine_waveformatex); int id3v2_tag_size, i; /* Unfortunately some FLAC files have an ID3 flag prefixed on them * before the actual FLAC headers... these are barely legal, but * users use them and want them working, so check and skip the ID3 * tag if present. */ id3v2_tag_size = xine_parse_id3v2_tag (flac->stream, flac->input); /* fetch the file signature, 4 bytes will read both the fLaC * signature and the */ if (_x_demux_read_stream_header (flac->stream, flac->input, &signature, 4) != 4) return 0; flac->input->seek (flac->input, id3v2_tag_size + 4, SEEK_SET); /* validate signature */ if ( signature != ME_FOURCC('f', 'L', 'a', 'C') ) return 0; /* loop through the metadata blocks; use a do-while construct since there * will always be 1 metadata block */ do { if (flac->input->read(flac->input, preamble, FLAC_SIGNATURE_SIZE) != FLAC_SIGNATURE_SIZE) return 0; block_length = (preamble[1] << 16) | (preamble[2] << 8) | (preamble[3] << 0); switch (preamble[0] & 0x7F) { /* STREAMINFO */ case 0: lprintf ("STREAMINFO metadata\n"); if (block_length != FLAC_STREAMINFO_SIZE) { lprintf ("expected STREAMINFO chunk of %d bytes\n", FLAC_STREAMINFO_SIZE); return 0; } if (flac->input->read(flac->input, flac->streaminfo + sizeof(xine_waveformatex), FLAC_STREAMINFO_SIZE) != FLAC_STREAMINFO_SIZE) return 0; flac->sample_rate = _X_BE_32(&streaminfo[10]); flac->channels = ((flac->sample_rate >> 9) & 0x07) + 1; flac->bits_per_sample = ((flac->sample_rate >> 4) & 0x1F) + 1; flac->sample_rate >>= 12; flac->total_samples = _X_BE_64(&streaminfo[10]) & UINT64_C(0x0FFFFFFFFF); /* 36 bits */ lprintf ("%d Hz, %d bits, %d channels, %"PRId64" total samples\n", flac->sample_rate, flac->bits_per_sample, flac->channels, flac->total_samples); break; /* PADDING */ case 1: lprintf ("PADDING metadata\n"); flac->input->seek(flac->input, block_length, SEEK_CUR); break; /* APPLICATION */ case 2: lprintf ("APPLICATION metadata\n"); flac->input->seek(flac->input, block_length, SEEK_CUR); break; /* SEEKTABLE */ case 3: lprintf ("SEEKTABLE metadata, %d bytes\n", block_length); if (!flac->sample_rate) break; flac->seekpoint_count = block_length / FLAC_SEEKPOINT_SIZE; if (!flac->seekpoint_count) break; flac->seekpoints = calloc(flac->seekpoint_count, sizeof(flac_seekpoint_t)); if (!flac->seekpoints) return 0; for (i = 0; i < flac->seekpoint_count; i++) { if (flac->input->read(flac->input, buffer, FLAC_SEEKPOINT_SIZE) != FLAC_SEEKPOINT_SIZE) return 0; flac->seekpoints[i].sample_number = _X_BE_64(&buffer[0]); lprintf (" %d: sample %"PRId64", ", i, flac->seekpoints[i].sample_number); flac->seekpoints[i].offset = _X_BE_64(&buffer[8]); flac->seekpoints[i].size = _X_BE_16(&buffer[16]); lprintf ("@ 0x%"PRIX64", size = %d bytes, ", flac->seekpoints[i].offset, flac->seekpoints[i].size); flac->seekpoints[i].pts = flac->seekpoints[i].sample_number; flac->seekpoints[i].pts *= 90000; flac->seekpoints[i].pts /= flac->sample_rate; lprintf ("pts = %"PRId64"\n", flac->seekpoints[i].pts); } break; /* VORBIS_COMMENT * * For a description of the format please have a look at * http://www.xiph.org/vorbis/doc/v-comment.html */ case 4: lprintf ("VORBIS_COMMENT metadata\n"); { char *comments; uint32_t length, user_comment_list_length, cn; char *comment; char c; if (block_length < 8) break; comments = malloc(block_length + 1); /* last byte for NUL termination */ if (!comments) break; if (flac->input->read(flac->input, comments, block_length) == block_length) { char *ptr = comments; int tracknumber = -1; int tracktotal = -1; length = _X_LE_32(ptr); ptr += 4 + length; if (length > block_length - 8) { free(comments); return 0; /* bad length or too little left in the buffer */ } user_comment_list_length = _X_LE_32(ptr); ptr += 4; cn = 0; for (; cn < user_comment_list_length; cn++) { if (ptr > comments + block_length - 4) { free(comments); return 0; /* too little left in the buffer */ } length = _X_LE_32(ptr); ptr += 4; if (length >= block_length || ptr + length > comments + block_length) { free(comments); return 0; /* bad length */ } comment = (char*) ptr; c = comment[length]; comment[length] = 0; /* NUL termination */ lprintf ("comment[%02d] = %s\n", cn, comment); if ((strncasecmp ("TITLE=", comment, 6) == 0) && (length - 6 > 0)) { _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_TITLE, comment + 6); } else if ((strncasecmp ("ARTIST=", comment, 7) == 0) && (length - 7 > 0)) { _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_ARTIST, comment + 7); } else if ((strncasecmp ("COMPOSER=", comment, 9) == 0) && (length - 9 > 0)) { _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_COMPOSER, comment + 9); } else if ((strncasecmp ("ALBUM=", comment, 6) == 0) && (length - 6 > 0)) { _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_ALBUM, comment + 6); } else if ((strncasecmp ("DATE=", comment, 5) == 0) && (length - 5 > 0)) { _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_YEAR, comment + 5); } else if ((strncasecmp ("GENRE=", comment, 6) == 0) && (length - 6 > 0)) { _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_GENRE, comment + 6); } else if ((strncasecmp ("Comment=", comment, 8) == 0) && (length - 8 > 0)) { _x_meta_info_set_utf8 (flac->stream, XINE_META_INFO_COMMENT, comment + 8); } else if ((strncasecmp ("TRACKNUMBER=", comment, 12) == 0) && (length - 12 > 0)) { tracknumber = atoi (comment + 12); } else if ((strncasecmp ("TRACKTOTAL=", comment, 11) == 0) && (length - 11 > 0)) { tracktotal = atoi (comment + 11); } comment[length] = c; ptr += length; } if ((tracknumber > 0) && (tracktotal > 0)) { char tn[24]; snprintf (tn, 24, "%02d/%02d", tracknumber, tracktotal); _x_meta_info_set(flac->stream, XINE_META_INFO_TRACK_NUMBER, tn); } else if (tracknumber > 0) { char tn[16]; snprintf (tn, 16, "%02d", tracknumber); _x_meta_info_set(flac->stream, XINE_META_INFO_TRACK_NUMBER, tn); } } free(comments); } break; /* CUESHEET */ case 5: lprintf ("CUESHEET metadata\n"); flac->input->seek(flac->input, block_length, SEEK_CUR); break; /* 6-127 are presently reserved */ default: lprintf ("unknown metadata chunk: %d\n", preamble[0] & 0x7F); flac->input->seek(flac->input, block_length, SEEK_CUR); break; } } while ((preamble[0] & 0x80) == 0); /* do not bail out yet, maybe decoder can handle this if (!flac->sample_rate) return 0; */ flac->data_start = flac->input->get_current_pos(flac->input); flac->data_size = flac->input->get_length(flac->input) - flac->data_start; /* now at the beginning of the audio, adjust the seekpoint offsets */ for (i = 0; i < flac->seekpoint_count; i++) { flac->seekpoints[i].offset += flac->data_start; } return 1; } static int demux_flac_send_chunk(demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; buf_element_t *buf = NULL; #ifdef USE_FRAME_BUF int l; #else int64_t input_time_guess; #endif #ifdef USE_FRAME_BUF l = flac_get_frame (this); if (l) { uint32_t flags, normpos = 0; uint8_t *p; int64_t pts; int itime; if (this->data_size > 0) normpos = (double)(this->frame1.filepos - this->data_start) * 65535 / this->data_size; if (this->frame1.rate) { if (this->frame1.vbs) pts = (double)this->frame1.num * 90000 / this->frame1.rate; else pts = (double)this->frame1.num * this->frame1.bsize * 90000 / this->frame1.rate; itime = pts / 90; } else { pts = 0; itime = 0; } if (this->seek_flag) { _x_demux_control_newpts (this->stream, pts, BUF_FLAG_SEEK); this->seek_flag = 0; } else { int64_t diff = pts - this->last_pts; if (diff < 0) diff = -diff; if (diff > 220000) _x_demux_control_newpts (this->stream, pts, 0); } this->last_pts = pts; this->read_errs = 3; flags = BUF_FLAG_FRAME_START; p = this->frame_buf + this->frame1.buf_pos; while (l) { buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, l); buf->type = BUF_AUDIO_FLAC; buf->size = l > buf->max_size ? buf->max_size : l; memcpy (buf->content, p, buf->size); p += buf->size; l -= buf->size; if (!l) flags |= BUF_FLAG_FRAME_END; buf->decoder_flags |= flags; flags &= ~BUF_FLAG_FRAME_START; buf->extra_info->input_normpos = normpos; buf->pts = pts; buf->extra_info->input_time = itime; if (this->sample_rate) buf->extra_info->total_time = (int64_t)this->total_samples * 1000 / this->sample_rate; pts = 0; itime = 0; this->audio_fifo->put (this->audio_fifo, buf); } } else if (!this->seek_flag) { if (--this->read_errs < 0) this->status = DEMUX_FINISHED; } #else /* just send a buffer-sized chunk; let the decoder figure out the * boundaries and let the engine figure out the pts */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_FLAC; if( this->data_size ) buf->extra_info->input_normpos = (int) ( (double) (this->input->get_current_pos(this->input) - this->data_start) * 65535 / this->data_size ); buf->pts = 0; buf->size = buf->max_size; /* * Estimate the input_time field based on file position: * * current_pos input time * ----------- = ---------- * total_pos total time * * total time = total samples / sample rate * 1000 */ /* do this one step at a time to make sure all the numbers stay safe */ if (this->sample_rate) { input_time_guess = this->total_samples; input_time_guess /= this->sample_rate; input_time_guess *= 1000; input_time_guess *= buf->extra_info->input_normpos; input_time_guess /= 65535; buf->extra_info->input_time = input_time_guess; buf->extra_info->total_time = (int64_t)this->total_samples * 1000 / this->sample_rate; } if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put(this->audio_fifo, buf); #endif return this->status; } static void demux_flac_send_headers(demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; buf_element_t *buf; xine_waveformatex wave; int bits; memset(&wave, 0, sizeof(wave)); this->audio_fifo = this->stream->audio_fifo; /* send start buffers */ _x_demux_control_start(this->stream); if ( ! this->audio_fifo ) { this->status = DEMUX_FINISHED; return; } /* lie about 24bps */ bits = this->bits_per_sample > 16 ? 16 : this->bits_per_sample; buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_FLAC; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->sample_rate; buf->decoder_info[2] = bits; buf->decoder_info[3] = this->channels; /* copy the faux WAV header */ buf->size = sizeof(xine_waveformatex) + FLAC_STREAMINFO_SIZE; memcpy(buf->content, this->streaminfo, buf->size); /* forge a WAV header with the proper length */ wave.cbSize = FLAC_STREAMINFO_SIZE; memcpy(buf->content, &wave, sizeof(xine_waveformatex)); this->audio_fifo->put (this->audio_fifo, buf); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, bits); this->status = DEMUX_OK; } static int demux_flac_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_flac_t *this = (demux_flac_t *) this_gen; int seekpoint_index = 0; int64_t start_pts; #ifndef USE_FRAME_BUF unsigned char buf[4]; #endif start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); /* if thread is not running, initialize demuxer */ if( !playing && !start_pos) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } else { if (this->seekpoints == NULL && !start_pos) { /* cannot seek if there is no seekpoints */ this->status = DEMUX_OK; return this->status; } /* Don't use seekpoints if start_pos != 0. This allows smooth seeking */ if (start_pos) { /* offset-based seek */ this->status = DEMUX_OK; start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); #ifdef USE_FRAME_BUF flac_reset_head (this); this->seek_flag = 1; #else while(1){ /* here we try to find something that resembles a frame header */ if (this->input->read(this->input, buf, 2) != 2){ this->status = DEMUX_FINISHED; /* we sought past the end of stream ? */ break; } if (buf[0] == 0xff && buf[1] == 0xf8) break; /* this might be the frame header... or it may be not. We pass it to the decoder * to decide, but this way we reduce the number of warnings */ start_pos +=2; } #endif _x_demux_flush_engine(this->stream); this->input->seek(this->input, start_pos, SEEK_SET); _x_demux_control_newpts(this->stream, 0, BUF_FLAG_SEEK); return this->status; } else { #ifdef USE_FRAME_BUF flac_reset_head (this); this->seek_flag = 1; #endif /* do a lazy, linear seek based on the assumption that there are not * that many seek points; time-based seek */ start_pts = start_time; start_pts *= 90; if (start_pts < this->seekpoints[0].pts) seekpoint_index = 0; else { for (seekpoint_index = 0; seekpoint_index < this->seekpoint_count - 1; seekpoint_index++) { if (start_pts < this->seekpoints[seekpoint_index + 1].pts) { break; } } } } _x_demux_flush_engine(this->stream); this->input->seek(this->input, this->seekpoints[seekpoint_index].offset, SEEK_SET); _x_demux_control_newpts(this->stream, this->seekpoints[seekpoint_index].pts, BUF_FLAG_SEEK); } return this->status; } static void demux_flac_dispose (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; free(this->seekpoints); #ifdef USE_FRAME_BUF free (this->frame_buf); #endif free(this); } static int demux_flac_get_status (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; return this->status; } static int demux_flac_get_stream_length (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; int64_t length = this->total_samples; if (!this->sample_rate) return 0; length *= 1000; length /= this->sample_rate; return length; } static uint32_t demux_flac_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_flac_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_flac_t *this; /* this should change eventually... */ if (!INPUT_IS_SEEKABLE(input)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input not seekable, can not handle!\n"); return NULL; } this = calloc(1, sizeof(demux_flac_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM # ifdef USE_FRAME_BUF this->frame_buf_filepos = 0; this->frame_buf_used = 0; this->frame2.filepos = 0; this->frame2.rate = 0; this->frame2.bits = 0; this->frame2.channels = 0; this->frame2.vbs = 0; this->frame2.bsize = 0; this->frame2.num = 0; this->frame2.max_size = 0; this->frame2.buf_pos = 0; this->last_pts = 0; this->seek_flag = 0; # endif this->seekpoints = NULL; #endif #ifdef USE_FRAME_BUF this->frame_buf_size = 8 << 10; this->frame_buf = malloc (this->frame_buf_size + 16); if (!this->frame_buf) { free (this); return NULL; } flac_init_frame_head (this); this->read_errs = 3; #endif this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_flac_send_headers; this->demux_plugin.send_chunk = demux_flac_send_chunk; this->demux_plugin.seek = demux_flac_seek; this->demux_plugin.dispose = demux_flac_dispose; this->demux_plugin.get_status = demux_flac_get_status; this->demux_plugin.get_stream_length = demux_flac_get_stream_length; this->demux_plugin.get_capabilities = demux_flac_get_capabilities; this->demux_plugin.get_optional_data = demux_flac_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_flac_file(this)) { demux_flac_dispose (&this->demux_plugin); return NULL; } break; default: #ifdef USE_FRAME_BUF free (this->frame_buf); #endif free (this); return NULL; } return &this->demux_plugin; } void *demux_flac_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_flac_class = { .open_plugin = open_plugin, .description = N_("Free Lossless Audio Codec (flac) demux plugin"), .identifier = "FLAC", .mimetypes = "audio/x-flac: flac: FLAC Audio;" "audio/flac: flac: FLAC Audio;", .extensions = "flac", .dispose = NULL, }; return (void *)&demux_flac_class; } xine-lib-1.2/src/demuxers/demux_mng.c0000644000175000017500000002441514647725152015444 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demux_mng.c, Demuxer plugin for Multiple-image Network Graphics format * * written and currently maintained by Robin Kay */ #ifdef HAVE_CONFIG_H #include "config.h" #undef HAVE_CONFIG_H #endif #include #include #include #include #ifdef HAVE_STDLIB_H #undef HAVE_STDLIB_H #endif #define LOG_MODULE "demux_mng" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; mng_handle mngh; xine_bmiheader bih; int left_edge; uint8_t *image; int started; int tick_count; int timer_count; } demux_mng_t; static mng_ptr mymng_alloc(mng_size_t size){ return (mng_ptr)calloc(1, size); } static void mymng_free(mng_ptr p, mng_size_t size){ (void)size; free(p); } static mng_bool mymng_open_stream(mng_handle mngh){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); if (this->input->get_current_pos(this->input) != 0) { if (!INPUT_IS_SEEKABLE(this->input)) { return MNG_FALSE; } if (this->input->seek(this->input, 0, SEEK_SET) != 0) { return MNG_FALSE; } } return MNG_TRUE; } static mng_bool mymng_close_stream(mng_handle mngh){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); this->status = DEMUX_FINISHED; return MNG_TRUE; } static mng_bool mymng_read_stream(mng_handle mngh, mng_ptr buffer, mng_uint32 size, mng_uint32 *bytesread){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); off_t n = this->input->read(this->input, buffer, size); if (n < 0) { *bytesread = 0; return MNG_FALSE; } *bytesread = n; return MNG_TRUE; } static mng_bool mymng_process_header(mng_handle mngh, mng_uint32 width, mng_uint32 height){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); if (width > 0x8000 || height > 0x8000) return MNG_FALSE; this->bih.biWidth = (width + 7) & ~7; this->bih.biHeight = height; this->left_edge = (this->bih.biWidth - width) / 2; this->image = malloc((mng_size_t)this->bih.biWidth * (mng_size_t)height * 3); if (!this->image) return MNG_FALSE; mng_set_canvasstyle(mngh, MNG_CANVAS_RGB8); return MNG_TRUE; } static mng_uint32 mymng_get_tick_count(mng_handle mngh){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); return this->tick_count; } static mng_bool mymng_set_timer(mng_handle mngh, mng_uint32 msecs){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); this->timer_count = msecs; return MNG_TRUE; } static mng_ptr mymng_get_canvas_line(mng_handle mngh, mng_uint32 line){ demux_mng_t *this = (demux_mng_t*)mng_get_userdata(mngh); return this->image + (this->left_edge + line * this->bih.biWidth) * 3; } static mng_bool mymng_refresh(mng_handle mngh, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h){ (void)mngh; (void)x; (void)y; (void)w; (void)h; return MNG_TRUE; } /* * !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! * All the following functions are defined by the xine demuxer API * !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! !IMPORTANT! */ static int demux_mng_send_chunk(demux_plugin_t *this_gen){ demux_mng_t *this = (demux_mng_t *)this_gen; int size = this->bih.biWidth * this->bih.biHeight * 3; uint8_t *image_ptr = this->image; int err = mng_display_resume(this->mngh); if ((err != MNG_NOERROR) && (err != MNG_NEEDTIMERWAIT)) { lprintf("mng_display_resume returned an error (%d)\n", err); this->status = DEMUX_FINISHED; } while (size > 0) { buf_element_t *buf; buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->type = BUF_VIDEO_RGB; buf->decoder_flags = BUF_FLAG_FRAMERATE; buf->decoder_info[0] = 90 * this->timer_count; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); buf->extra_info->input_time = this->tick_count; buf->pts = 90 * this->tick_count; if (size > buf->max_size) { buf->size = buf->max_size; } else { buf->size = size; } size -= buf->size; memcpy(buf->content, image_ptr, buf->size); image_ptr += buf->size; if (size == 0) { buf->decoder_flags |= BUF_FLAG_FRAME_END; } this->video_fifo->put(this->video_fifo, buf); } this->tick_count += this->timer_count; this->timer_count = 0; return this->status; } static void demux_mng_send_headers(demux_plugin_t *this_gen){ demux_mng_t *this = (demux_mng_t *)this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); /* send start buffers */ _x_demux_control_start(this->stream); /* required when loop playing short streams (gapless switch) */ _x_demux_control_newpts(this->stream, 0, 0); /* send init info to decoder */ this->bih.biBitCount = 24; buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->type = BUF_VIDEO_RGB; buf->size = sizeof(xine_bmiheader); memcpy(buf->content, &this->bih, sizeof(xine_bmiheader)); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; this->video_fifo->put(this->video_fifo, buf); } static int demux_mng_seek(demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing){ demux_mng_t *this = (demux_mng_t *)this_gen; (void)start_pos; (void)start_time; (void)playing; return this->status; } static void demux_mng_dispose(demux_plugin_t *this_gen){ demux_mng_t *this = (demux_mng_t *)this_gen; mng_cleanup(&this->mngh); if (this->image) free(this->image); free(this); } static int demux_mng_get_status(demux_plugin_t *this_gen){ demux_mng_t *this = (demux_mng_t *)this_gen; return this->status; } static int demux_mng_get_stream_length(demux_plugin_t *this_gen){ (void)this_gen; return 0; } static uint32_t demux_mng_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mng_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t* open_plugin(demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input){ demux_mng_t *this; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!INPUT_IS_SEEKABLE(input)) return NULL; break; case METHOD_BY_MRL: break; default: return NULL; } this = calloc(1, sizeof(demux_mng_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_mng_send_headers; this->demux_plugin.send_chunk = demux_mng_send_chunk; this->demux_plugin.seek = demux_mng_seek; this->demux_plugin.dispose = demux_mng_dispose; this->demux_plugin.get_status = demux_mng_get_status; this->demux_plugin.get_stream_length = demux_mng_get_stream_length; this->demux_plugin.get_capabilities = demux_mng_get_capabilities; this->demux_plugin.get_optional_data = demux_mng_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if ((this->mngh = mng_initialize(this, mymng_alloc, mymng_free, MNG_NULL)) == MNG_NULL) { free(this); return NULL; } if (mng_setcb_openstream(this->mngh, mymng_open_stream) || mng_setcb_closestream(this->mngh, mymng_close_stream) || mng_setcb_readdata(this->mngh, mymng_read_stream) || mng_setcb_processheader(this->mngh, mymng_process_header) || mng_setcb_gettickcount(this->mngh, mymng_get_tick_count) || mng_setcb_settimer(this->mngh, mymng_set_timer) || mng_setcb_getcanvasline(this->mngh, mymng_get_canvas_line) || mng_setcb_refresh(this->mngh, mymng_refresh)) { mng_cleanup(&this->mngh); free(this); return NULL; } { int err = mng_readdisplay(this->mngh); if ((err != MNG_NOERROR) && (err != MNG_NEEDTIMERWAIT)) { mng_cleanup(&this->mngh); free(this); return NULL; } } return &this->demux_plugin; } static void *init_plugin(xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_mng_class = { .open_plugin = open_plugin, .description = N_("Multiple-image Network Graphics demux plugin"), .identifier = "MNG", .mimetypes = "image/png: png: PNG image;" "image/x-png: png: PNG image;" "video/mng: mng: MNG animation;" "video/x-mng: mng: MNG animation;", .extensions = "png mng", .dispose = NULL, }; return (void *)&demux_mng_class; } static const demuxer_info_t demux_info_mng = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_DEMUX, 27, "mng", XINE_VERSION_CODE, &demux_info_mng, init_plugin}, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_mpgaudio.c0000644000175000017500000011027514647725152016470 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for mpeg audio (i.e. mp3) streams * * mp3 file structure: * [id3v2][Xing|Vbri] Frame1 Frame2 Frame3...FrameX [Lyrics][id3v2][id3v1] */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_mpgaudio" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_audio.h" #include "id3.h" /* 2 preview buffers are enough, * the first mp3 frame is potentially a vbr header (xing, vbri) * the second mp3 frame is sent to the decoder */ #define NUM_PREVIEW_BUFFERS 2 #define NUM_VALID_FRAMES 3 #define FOURCC_TAG BE_FOURCC #define RIFF_CHECK_BYTES 1024 #define RIFF_TAG FOURCC_TAG('R', 'I', 'F', 'F') #define AVI_TAG FOURCC_TAG('A', 'V', 'I', ' ') #define CDXA_TAG FOURCC_TAG('C', 'D', 'X', 'A') #define MPEG_MARKER ME_FOURCC( 0x00, 0x00, 0x01, 0xBA ) /* Xing header stuff */ #define XING_TAG FOURCC_TAG('X', 'i', 'n', 'g') #define INFO_TAG FOURCC_TAG('I', 'n', 'f', 'o') #define LAME_TAG FOURCC_TAG('L', 'A', 'M', 'E') #define XING_FRAMES_FLAG 0x0001 #define XING_BYTES_FLAG 0x0002 #define XING_TOC_FLAG 0x0004 #define XING_VBR_SCALE_FLAG 0x0008 #define XING_TOC_LENGTH 100 #define LAME_HEADER_LENGTH 0xC0 /* Xing header stuff */ #define VBRI_TAG FOURCC_TAG('V', 'B', 'R', 'I') /* mp3 frame struct */ typedef struct { /* header */ double duration; /* in milliseconds */ uint32_t size; /* in bytes; including padding */ uint32_t bitrate; /* in bit per second */ uint16_t freq; /* in Hz */ uint8_t layer; uint8_t version_idx:2; /* 0: mpeg1, 1: mpeg2, 2: mpeg2.5 */ uint8_t lsf_bit:1; uint8_t channel_mode:3; uint8_t padding:3; /* in bytes */ uint8_t is_free_bitrate:1; } mpg_audio_frame_t; /* Xing Vbr Header struct */ typedef struct { uint32_t flags; uint32_t stream_frames; uint32_t stream_size; uint8_t toc[XING_TOC_LENGTH]; uint32_t vbr_scale; /* Lame extension */ uint16_t start_delay; uint16_t end_delay; } xing_header_t; /* Vbri Vbr Header struct */ typedef struct { uint16_t version; uint16_t delai; uint16_t quality; uint32_t stream_size; uint32_t stream_frames; uint16_t toc_entries; uint16_t toc_scale_factor; uint16_t entry_size; uint16_t entry_frames; int *toc; } vbri_header_t; /* demuxer instance struct */ typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; uint32_t stream_length; /* in seconds */ int br; /* bitrate in bits/second */ uint32_t blocksize; /* current mp3 frame */ mpg_audio_frame_t cur_frame; /* next mp3 frame, used when the frame size cannot be computed from the * current frame header */ mpg_audio_frame_t next_frame; double cur_time; /* in milliseconds */ off_t mpg_frame_start; /* offset */ off_t mpg_frame_end; /* offset */ off_t mpg_size; /* in bytes */ int check_vbr_header; xing_header_t *xing_header; vbri_header_t *vbri_header; unsigned int found_next_frame : 1; int free_bitrate_count; off_t free_bitrate_size; /* use this size if 3 free bitrate frames are encountered */ uint8_t next_header[4]; int mpg_version; int mpg_layer; int valid_frames; } demux_mpgaudio_t ; /* * Parse a mp3 frame * return 1 on success */ static int parse_frame_header(mpg_audio_frame_t *const frame, const uint8_t *const buf) { /* bitrate table[mpeg version][layer][bitrate index] * values stored in kbps */ static const uint16_t mp3_bitrates[3][3][16] = { { {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448,}, {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,}, {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320,} }, { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} }, { {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256,}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,}, {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160,} } }; /* frequency table[mpeg version][frequence index] (in KHz) */ static const uint16_t mp3_freqs[3][3] = { { 44100, 48000, 32000 }, { 22050, 24000, 16000 }, { 11025, 12000, 8000 } }; /* samples per frame table[mpeg version][layer] */ static const uint16_t mp3_samples[3][3] = { { 384, 1152, 1152 }, { 384, 1152, 576 }, { 384, 1152, 576 } }; struct { uint16_t mpeg25_bit:1; uint16_t bitrate_idx:4; uint16_t freq_idx:3; uint16_t padding_bit:1; uint16_t channel_mode:3; #if 0 /* Unused */ uint16_t protection_bit:1; uint16_t private_bit:1; uint16_t mode_extension:3; uint16_t copyright:1; uint16_t original:1; #endif #if defined(OPT_STRICT) uint16_t emphasis:3; #endif } frame_header; const uint32_t head = _X_BE_32(buf); const uint16_t frame_sync = head >> 21; if (frame_sync != 0x7ff) { lprintf("invalid frame sync %08X\n", head); return 0; } lprintf("header: %08X\n", head); frame_header.mpeg25_bit = (head >> 20) & 0x1; frame->lsf_bit = (head >> 19) & 0x1; if (!frame_header.mpeg25_bit) { if (frame->lsf_bit) { lprintf("reserved mpeg25 lsf combination\n"); return 0; } else frame->version_idx = 2; /* MPEG Version 2.5 */ } else { if (!frame->lsf_bit) frame->version_idx = 1; /* MPEG Version 2 */ else frame->version_idx = 0; /* MPEG Version 1 */ } frame->layer = 4 - ((head >> 17) & 0x3); if (frame->layer == 4) { lprintf("reserved layer\n"); return 0; } frame_header.bitrate_idx = (head >> 12) & 0xf; if (frame_header.bitrate_idx == 15) { lprintf("invalid bitrate index: %d\n", frame_header.bitrate_idx); return 0; } frame_header.freq_idx = (head >> 10) & 0x3; if (frame_header.freq_idx == 3) { lprintf("invalid frequence index: %d\n", frame_header.freq_idx); return 0; } frame_header.padding_bit = (head >> 9) & 0x1; frame_header.channel_mode = (head >> 6) & 0x3; #if 0 /* Unused */ frame_header.protection_bit = (head >> 16) & 0x1; frame_header.private_bit = (head >> 8) & 0x1; frame_header.mode_extension = (head >> 4) & 0x3; frame_header.copyright = (head >> 3) & 0x1; frame_header.original = (head >> 2) & 0x1; #endif #if defined(OPT_STRICT) frame_header.emphasis = head & 0x3; /* * ISO/IEC 11172-3 says this is a reserved emphasis value, but * streams exist which use it anyway. Since the value is not important * to the decoder proper, we allow it unless OPT_STRICT is defined. */ if (frame_header.emphasis == 2) { lprintf("reserved emphasis\n"); return 0; } #endif { const uint16_t samples = mp3_samples[frame->version_idx][frame->layer - 1]; frame->bitrate = mp3_bitrates[frame->version_idx][frame->layer - 1][frame_header.bitrate_idx] * 1000; frame->freq = mp3_freqs[frame->version_idx][frame_header.freq_idx]; frame->duration = 1000.0f * (double)samples / (double)frame->freq; frame->padding = ( frame_header.padding_bit ? ( frame->layer == 1 ? 4 : 1 ) : 0 ); frame->channel_mode = frame_header.channel_mode; if (frame->bitrate > 0) { frame->size = samples * (frame->bitrate / 8); frame->size /= frame->freq; /* Padding: only if padding_bit is set; 4 bytes for Layer 1 and 1 byte for others */ frame->size += frame->padding; } else { /* Free bitrate frame, the size of the frame cannot be computed from the header. */ frame->is_free_bitrate = 1; frame->size = 0; } } lprintf("mpeg %d, layer %d, channel_mode: %d\n", frame->version_idx + 1, frame->layer, frame->channel_mode); lprintf("bitrate: %d bps, output freq: %d Hz\n", frame->bitrate, frame->freq); lprintf("length: %d bytes, %f ms\n", frame->size, frame->duration); lprintf("padding: %d bytes\n", frame->padding); return 1; } /* * Parse a Xing header * return the Xing header or NULL on error */ static xing_header_t *XINE_MALLOC parse_xing_header(mpg_audio_frame_t *frame, uint8_t *buf, int bufsize) { uint8_t *ptr = buf; xing_header_t *xing = NULL; /* offset of the Xing header */ if (frame->lsf_bit) { if (frame->channel_mode != 3) ptr += (32 + 4); else ptr += (17 + 4); } else { if (frame->channel_mode != 3) ptr += (17 + 4); else ptr += (9 + 4); } if (ptr >= (buf + bufsize - 4)) goto exit_error; lprintf("checking %08X\n", *ptr); if (_X_BE_32(ptr) == XING_TAG) { int has_frames_flag = 0; int has_bytes_flag = 0; xing = calloc(1, sizeof(xing_header_t)); if (!xing) goto exit_error; lprintf("found Xing header\n"); ptr += 4; if (ptr >= (buf + bufsize - 4)) goto exit_error; xing->flags = _X_BE_32(ptr); ptr += 4; if (xing->flags & XING_FRAMES_FLAG) { if (ptr >= (buf + bufsize - 4)) goto exit_error; xing->stream_frames = _X_BE_32(ptr); ptr += 4; lprintf("stream frames: %d\n", xing->stream_frames); has_frames_flag = 1; } if (xing->flags & XING_BYTES_FLAG) { if (ptr >= (buf + bufsize - 4)) goto exit_error; xing->stream_size = _X_BE_32(ptr); ptr += 4; lprintf("stream size: %d\n", xing->stream_size); has_bytes_flag = 1; } /* check if it's a useful Xing header */ if (!has_frames_flag || !has_bytes_flag) { lprintf("Stupid Xing tag, cannot do anything with it !\n"); goto exit_error; } if (xing->flags & XING_TOC_FLAG) { int i; lprintf("toc found\n"); if (ptr >= (buf + bufsize - XING_TOC_LENGTH)) goto exit_error; memcpy(xing->toc, ptr, XING_TOC_LENGTH); #ifdef LOG for (i = 0; i < XING_TOC_LENGTH; i++) { printf("%d ", xing->toc[i]); } printf("\n"); #endif /* check the table validity * - MUST start with 0 * - values MUST increase */ if (xing->toc[0] != 0) { lprintf("invalid Xing toc\n"); goto exit_error; } for (i = 1; i < XING_TOC_LENGTH; i++) { if (xing->toc[i] < xing->toc[i-1]) { lprintf("invalid Xing toc\n"); goto exit_error; } } ptr += XING_TOC_LENGTH; } xing->vbr_scale = -1; if (xing->flags & XING_VBR_SCALE_FLAG) { if (ptr >= (buf + bufsize - 4)) goto exit_error; xing->vbr_scale = _X_BE_32(ptr); ptr += 4; lprintf("vbr_scale: %d\n", xing->vbr_scale); } /* LAME extension */ /* see http://gabriel.mp3-tech.org/mp3infotag.html */ ptr -= 0x9C; /* move offset to match LAME header specs */ if (ptr + LAME_HEADER_LENGTH >= (buf + bufsize - 4)) goto exit_error; if (_X_BE_32(&ptr[0x9C]) == LAME_TAG) { lprintf("Lame header found\n"); xing->start_delay = (ptr[0xb1] << 4) | (ptr[0xb2] >> 4); xing->end_delay = ((ptr[0xb2] & 0x0f) << 4) | ptr[0xb3]; lprintf("start delay : %d samples\n", xing->start_delay); lprintf("end delay : %d samples\n", xing->end_delay); } } else { lprintf("Xing header not found\n"); } return xing; exit_error: lprintf("Xing header parse error\n"); free(xing); return NULL; } /* * Parse a Vbri header * return the Vbri header or NULL on error */ static void _free_vbri_header(vbri_header_t **pp) { if (*pp) { vbri_header_t *p = *pp; _x_freep(&p->toc); _x_freep(pp); } } static vbri_header_t *XINE_MALLOC parse_vbri_header(mpg_audio_frame_t *frame, uint8_t *buf, int bufsize) { int i; uint8_t *ptr = buf; vbri_header_t *vbri; (void)frame; ptr += (32 + 4); if ((ptr + 4) >= (buf + bufsize)) return 0; vbri = calloc(1, sizeof(vbri_header_t)); if (!vbri) return NULL; lprintf("Checking %08X\n", *ptr); if (_X_BE_32(ptr) == VBRI_TAG) { lprintf("found Vbri header\n"); ptr += 4; if ((ptr + 22) >= (buf + bufsize)) { free(vbri); return NULL; } vbri->version = _X_BE_16(ptr); ptr += 2; vbri->delai = _X_BE_16(ptr); ptr += 2; vbri->quality = _X_BE_16(ptr); ptr += 2; vbri->stream_size = _X_BE_32(ptr); ptr += 4; vbri->stream_frames = _X_BE_32(ptr); ptr += 4; vbri->toc_entries = _X_BE_16(ptr); ptr += 2; vbri->toc_scale_factor = _X_BE_16(ptr); ptr += 2; vbri->entry_size = _X_BE_16(ptr); ptr += 2; vbri->entry_frames = _X_BE_16(ptr); ptr += 2; lprintf("version: %d\n", vbri->version); lprintf("delai: %d\n", vbri->delai); lprintf("quality: %d\n", vbri->quality); lprintf("stream_size: %d\n", vbri->stream_size); lprintf("stream_frames: %d\n", vbri->stream_frames); lprintf("toc_entries: %d\n", vbri->toc_entries); lprintf("toc_scale_factor: %d\n", vbri->toc_scale_factor); lprintf("entry_size: %d\n", vbri->entry_size); lprintf("entry_frames: %d\n", vbri->entry_frames); if ((ptr + (vbri->toc_entries + 1) * vbri->entry_size) >= (buf + bufsize)) { free (vbri); return NULL; } vbri->toc = xine_xcalloc ((vbri->toc_entries + 1), sizeof(int)); if (!vbri->toc) { free (vbri); return NULL; } lprintf("toc entries: %d\n", vbri->toc_entries); for (i = 0; i <= vbri->toc_entries; i++) { int j; uint32_t value = 0; for (j = 0; j < vbri->entry_size; j++) { value = (value << 8) | *(ptr + i * vbri->entry_size + j); } vbri->toc[i] = value; #ifdef LOG printf("%d ", vbri->toc[i]); #endif } #ifdef LOG printf("\n"); #endif { int64_t toc_stream_size = 0; /* Compute the stream size using the toc */ for (i = 0; i <= vbri->toc_entries; i++) { toc_stream_size += vbri->toc[i]; } lprintf("stream size from toc: %"PRId64"\n", toc_stream_size); } return vbri; } else { lprintf("Vbri header not found\n"); free (vbri); return NULL; } } /* * Parse a mp3 frame paylod * return 1 on success, 0 on error */ static int parse_frame_payload(demux_mpgaudio_t *this, uint8_t *frame_header, int decoder_flags) { buf_element_t *buf; off_t frame_pos, len; uint64_t pts = 0; int payload_size = 0; frame_pos = this->input->get_current_pos(this->input) - 4; lprintf("frame_pos = %"PRId64", header: %08X\n", frame_pos, _X_BE_32(frame_header)); buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); if ((int)(this->cur_frame.size) > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": frame size is greater than fifo buffer size\n"); buf->free_buffer(buf); return 0; } memcpy(buf->content, frame_header, 4); /* compute the payload size */ if (this->cur_frame.size > 0) { payload_size = this->cur_frame.size - 4; this->free_bitrate_count = 0; } else if (this->free_bitrate_count >= NUM_VALID_FRAMES) { payload_size = this->free_bitrate_size + this->cur_frame.padding - 4; this->cur_frame.size = payload_size + 4; } else { this->free_bitrate_count++; payload_size = 0; } /* Read the payload data. */ if (payload_size > 0) { off_t len; /* If we know the payload size, it's easy */ this->found_next_frame = 0; len = this->input->read(this->input, buf->content + 4, payload_size); if (len != payload_size) { buf->free_buffer(buf); return 0; } } else { /* Search for the beginning of the next frame and deduce the size of the * current frame from the position of the next one. */ int payload_size = 0; int max_size = buf->max_size - 4; while (payload_size < max_size) { len = this->input->read(this->input, &buf->content[4 + payload_size], 1); if (len != 1) { lprintf("EOF\n"); buf->free_buffer(buf); return 0; } payload_size += len; if (parse_frame_header(&this->next_frame, &buf->content[payload_size])) { lprintf("found next frame header\n"); if (this->free_bitrate_size == 0) { this->free_bitrate_size = payload_size - this->cur_frame.padding; } /* don't read the frame header twice */ this->found_next_frame = 1; memcpy(&this->next_header[0], &buf->content[payload_size], 4); payload_size -= 4; break; } } this->cur_frame.size = payload_size + 4; this->cur_frame.bitrate = 8000 * this->cur_frame.size / this->cur_frame.duration; lprintf("free bitrate: bitrate: %d, frame size: %d\n", this->br, this->cur_frame.size); } if (this->check_vbr_header) { this->check_vbr_header = 0; this->mpg_frame_start = frame_pos; free(this->xing_header); this->xing_header = parse_xing_header(&this->cur_frame, buf->content, this->cur_frame.size); if (this->xing_header) { buf->free_buffer(buf); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": found Xing header at offset %"PRId64"\n", frame_pos); return 1; } _free_vbri_header(&this->vbri_header); this->vbri_header = parse_vbri_header(&this->cur_frame, buf->content, this->cur_frame.size); if (this->vbri_header) { buf->free_buffer(buf); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": found Vbri header at offset %"PRId64"\n", frame_pos); return 1; } } pts = (int64_t)(this->cur_time * 90.0f); if (this->stream_length) buf->extra_info->input_normpos = (this->cur_time * 65535.0f) / this->stream_length; buf->extra_info->input_time = this->cur_time; if (this->stream_length > 0) buf->extra_info->total_time = this->stream_length; buf->pts = pts; buf->size = this->cur_frame.size; buf->type = BUF_AUDIO_MPEG; buf->decoder_info[0] = 1; buf->decoder_flags = decoder_flags | BUF_FLAG_FRAME_END; /* send encoder padding */ if (this->xing_header) { if (frame_pos == this->mpg_frame_start) { lprintf("sending a start padding of %d samples.\n", this->xing_header->start_delay); buf->decoder_flags = buf->decoder_flags | BUF_FLAG_AUDIO_PADDING; buf->decoder_info[1] = this->xing_header->start_delay; buf->decoder_info[2] = 0; } else if ((frame_pos + this->cur_frame.size) == this->mpg_frame_end) { lprintf("sending a end padding of %d samples.\n", this->xing_header->end_delay); buf->decoder_flags = buf->decoder_flags | BUF_FLAG_AUDIO_PADDING; buf->decoder_info[1] = 0; buf->decoder_info[2] = this->xing_header->end_delay; } } lprintf("send buffer: size=%d, pts=%"PRId64"\n", buf->size, pts); this->audio_fifo->put(this->audio_fifo, buf); this->cur_time += this->cur_frame.duration; return 1; } /* Scan through the preview buffer to find a potential * 32-bit MP3 frame header. * return 1 if found, 0 if not found */ static int sniff_buffer_looks_like_mp3 (uint8_t *buf, int buflen, int *version, int *layer) { int offset; mpg_audio_frame_t frame; *version = *layer = 0; if (buf == NULL) return 0; for (offset = 0; (offset + 4) < buflen; offset++) { if (parse_frame_header(&frame, buf + offset)) { size_t size = frame.size; if (size > 0) { /* Since one frame is available, is there another frame * just to be sure this is more likely to be a real MP3 * buffer? */ if (offset + (int)size + 4 >= buflen) { return 0; } if (parse_frame_header(&frame, buf + offset + size)) { *version = frame.version_idx + 1; *layer = frame.layer; lprintf("frame detected, mpeg %d layer %d\n", *version, *layer); return 1; } } } } return 0; } /* * Read a mp3 frame header (4 bytes) */ static int read_frame_header(demux_mpgaudio_t *this, uint8_t *header_buf, int bytes) { off_t len; int i; for (i = 0; i < (4 - bytes); i++) { header_buf[i] = header_buf[i + bytes]; } len = this->input->read(this->input, header_buf + 4 - bytes, bytes); if (len != ((off_t) bytes)) { return 0; } return 1; } /* * Parse next mp3 frame */ static int demux_mpgaudio_next (demux_mpgaudio_t *this, int decoder_flags, int send_header) { uint8_t buffer[4]; uint8_t *header = buffer; if (this->found_next_frame) { lprintf("skip header reading\n"); header = this->next_header; memcpy(&this->cur_frame, &this->next_frame, sizeof(mpg_audio_frame_t)); } else { int bytes = 4; int loose_sync = 0; for (;;) { if (!read_frame_header(this, header, bytes)) return 0; if (parse_frame_header(&this->cur_frame, header)) { lprintf("frame found\n"); /* additionnal checks */ if ((this->mpg_version == (this->cur_frame.version_idx + 1)) && (this->mpg_layer == this->cur_frame.layer)) { this->valid_frames++; break; } else { if (this->valid_frames >= NUM_VALID_FRAMES) { lprintf("invalid frame. expected mpeg %d, layer %d\n", this->mpg_version, this->mpg_layer); } else { this->mpg_version = this->cur_frame.version_idx + 1; this->mpg_layer = this->cur_frame.layer; this->valid_frames = 0; break; } } } if (!loose_sync) { off_t frame_pos = this->input->get_current_pos(this->input) - 4; loose_sync = 1; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": loose mp3 sync at offset %"PRId64"\n", frame_pos); } /* the stream is broken, don't keep info about previous frames */ this->free_bitrate_size = 0; if ( id3v2_istag(_X_ME_32(header)) ) { if (!id3v2_parse_tag(this->input, this->stream, _X_ME_32(header))) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2 tag parsing error\n"); bytes = 1; /* resync */ } else { bytes = 4; } } else { /* skip */ bytes = 1; } } } /* send header buffer */ if ( send_header ) { buf_element_t *buf; buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_MPEG; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->cur_frame.freq; buf->decoder_info[2] = 0; /* bits_per_sample */ /* Only for channel_mode == 3 (mono) there is one channel, for any other case, there are 2 */ buf->decoder_info[3] = ( this->cur_frame.channel_mode == 3 ) ? 1 : 2; buf->size = 0; /* No extra header data */ this->audio_fifo->put(this->audio_fifo, buf); } return parse_frame_payload(this, header, decoder_flags); } static int demux_mpgaudio_send_chunk (demux_plugin_t *this_gen) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; if (!demux_mpgaudio_next (this, 0, 0)) { /* Hack: send 8 zero bytes to flush the libmad decoder */ buf_element_t *buf; buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_MPEG; buf->decoder_flags = BUF_FLAG_FRAME_END; buf->size = 8; memset(buf->content, 0, buf->size); this->audio_fifo->put(this->audio_fifo, buf); this->status = DEMUX_FINISHED; } return this->status; } static int demux_mpgaudio_get_status (demux_plugin_t *this_gen) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; return this->status; } /* * mp3 stream detection * return 1 if detected, 0 otherwise */ static int detect_mpgaudio_file (xine_stream_t *stream, input_plugin_t *input, int *version, int *layer) { uint8_t buf[MAX_PREVIEW_SIZE]; int id3v2_tag_size, preview_len; uint32_t head; *version = *layer = 0; /* check if a mp3 frame follows the tag. id3v2 are not specific to mp3 files, * flac files can contain id3v2 tags. */ id3v2_tag_size = xine_parse_id3v2_tag (stream, input); preview_len = _x_demux_read_stream_header (stream, input, buf, sizeof (buf)); if (preview_len < 4) return -1; head = _X_ME_32(buf); lprintf("got preview %08x\n", head); if (head == MPEG_MARKER) { return -1; } else if (!sniff_buffer_looks_like_mp3(buf, preview_len, version, layer)) { lprintf ("sniff_buffer_looks_like_mp3 failed\n"); return -1; } return id3v2_tag_size; } static void demux_mpgaudio_send_headers (demux_plugin_t *this_gen) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; int i; this->stream_length = 0; this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_demux_control_start (this->stream); /* read id3 info only from inputs with seeking and without "live" flag */ if (INPUT_IS_SEEKABLE(this->input)) { off_t pos; /* check ID3 v1 at the end of the stream */ pos = this->input->get_length(this->input) - 128; if(pos > 0) { if (pos == this->input->seek (this->input, pos, SEEK_SET)) id3v1_parse_tag (this->input, this->stream); } /* seek back to the beginning */ if (this->input->seek (this->input, 0, SEEK_SET) != 0) { this->status = DEMUX_FINISHED; return; } /* * send preview buffers */ this->check_vbr_header = 1; for (i = 0; i < NUM_PREVIEW_BUFFERS; i++) { lprintf("preview buffer number %d / %d\n", i + 1, NUM_PREVIEW_BUFFERS); if (!demux_mpgaudio_next (this, BUF_FLAG_PREVIEW, i == 0)) { break; } } if (this->xing_header) { xing_header_t *xing = this->xing_header; this->mpg_size = xing->stream_size; this->mpg_frame_end = this->mpg_frame_start + this->mpg_size; this->stream_length = (double)xing->stream_frames * this->cur_frame.duration; /* compute abr */ if (this->stream_length) { this->br = ((uint64_t)xing->stream_size * 8 * 1000) / this->stream_length; } } else if (this->vbri_header) { vbri_header_t *vbri = this->vbri_header; this->mpg_size = vbri->stream_size; this->mpg_frame_end = this->mpg_frame_start + this->mpg_size; this->stream_length = (double)vbri->stream_frames * this->cur_frame.duration; /* compute abr */ if (this->stream_length) { this->br = ((uint64_t)vbri->stream_size * 8 * 1000) / this->stream_length; } } /* Set to default if Vbr header is incomplete or not present */ if (!this->br) { /* assume CBR */ this->br = this->cur_frame.bitrate; } if (!this->mpg_frame_end) { this->mpg_frame_end = this->input->get_length(this->input); } if (!this->mpg_size) { this->mpg_size = this->mpg_frame_end - this->mpg_frame_start; } if (!this->stream_length && this->br) { this->stream_length = (this->mpg_size * 1000) / (this->br / 8); } _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->br); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->br); lprintf("frame_start: %"PRId64", frame_end: %"PRId64"\n", this->mpg_frame_start, this->mpg_frame_end); lprintf("stream size: %"PRId64", mp3 size: %"PRId64"\n", this->input->get_length(this->input), this->mpg_size); lprintf("stream_length: %d ms\n", this->stream_length); /* set codec infos here * the decoder doesn't know if the stream is VBR */ { char scratch_buf[256]; static const char mpeg_ver[3][4] = {"1", "2", "2.5"}; snprintf(scratch_buf, 256, "MPEG %s Layer %1d%s", mpeg_ver[this->cur_frame.version_idx], this->cur_frame.layer, (this->xing_header)? " VBR" : " CBR" ); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, scratch_buf); } } else { for (i = 0; i < NUM_PREVIEW_BUFFERS; i++) { if (!demux_mpgaudio_next (this, BUF_FLAG_PREVIEW, i == 0)) { break; } } } this->status = DEMUX_OK; } /* * interpolate in Xing TOC to get file seek point in bytes * return the stream offset of the seekpoint */ static off_t xing_get_seek_point(xing_header_t *xing, int time, int stream_length) { off_t seekpoint; int a; float fa, fb, fx; float percent; percent = ((float)time * 100.0f)/ (float)stream_length; if (percent < 0.0f) percent = 0.0f; if (percent > 100.0f) percent = 100.0f; a = (int)percent; if (a > 99) a = 99; fa = xing->toc[a]; if (a < 99) { fb = xing->toc[a + 1]; } else { fb = 256.0f; } fx = fa + (fb - fa) * (percent - a); seekpoint = (off_t)((1.0f / 256.0f) * fx * xing->stream_size); return seekpoint; } /* * Interpolate in Vbri TOC to get file seek point in bytes * return the stream offset of the seekpoint */ static off_t vbri_get_seek_point(vbri_header_t *vbri, int time, int stream_length) { double fa, fb, fx; double toc_entry; int i; int a; toc_entry = ((float)time * (float)(vbri->toc_entries + 1)) / (float)stream_length; lprintf("time: %d, stream length: %d, toc entry: %f\n", time, stream_length, toc_entry); if (toc_entry < 0.0f) toc_entry = 0.0f; if (toc_entry > (float)vbri->toc_entries) toc_entry = (float)vbri->toc_entries; a = (int)toc_entry; if (a > (vbri->toc_entries - 1)) a = vbri->toc_entries - 1; /* compute the stream offset of the toc entry */ fa = 0.0f; for (i = 0; i < a; i++) { fa += (double)vbri->toc[i]; } /* compute the stream offset of the next toc entry */ fb = fa + (double)vbri->toc[a]; /* interpolate */ fx = fa + (fb - fa) * (toc_entry - (double)a); return (off_t)fx; } /* * Seeking function * Try to use the Vbr header if present. * If no Vbr header is present then use a CBR formula * * Position seek is relative to the total time of the stream, the position * is converted to a time at the beginning of the function */ static int demux_mpgaudio_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; off_t seek_pos = this->mpg_frame_start; if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { /* Convert position seek to time seek */ if (!start_time) { start_time = (int)((double)start_pos * (double)this->stream_length / 65535.0f); lprintf("position seek: start_pos=%"PRId64" => start_time=%d\n", start_pos, start_time); } if (start_time < 0) start_time = 0; if ((unsigned int)start_time > this->stream_length) start_time = this->stream_length; if (this->stream_length > 0) { if (this->xing_header && (this->xing_header->flags & XING_TOC_FLAG)) { seek_pos += xing_get_seek_point(this->xing_header, start_time, this->stream_length); lprintf("time seek: xing: time=%d, pos=%"PRId64"\n", start_time, seek_pos); } else if (this->vbri_header) { seek_pos += vbri_get_seek_point(this->vbri_header, start_time, this->stream_length); lprintf("time seek: vbri: time=%d, pos=%"PRId64"\n", start_time, seek_pos); } else { /* cbr */ seek_pos += ((double)start_time / 1000.0) * ((double)this->br / 8.0); lprintf("time seek: cbr: time=%d, pos=%"PRId64"\n", start_time, seek_pos); } } /* assume seeking is always perfect... */ this->cur_time = start_time; this->input->seek (this->input, seek_pos, SEEK_SET); this->found_next_frame = 0; if (playing) { _x_demux_flush_engine(this->stream); } _x_demux_control_newpts(this->stream, (int64_t)(this->cur_time * 90.0f), (playing) ? BUF_FLAG_SEEK : 0); } this->status = DEMUX_OK; return this->status; } static int demux_mpgaudio_get_stream_length (demux_plugin_t *this_gen) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; if (this->stream_length > 0) { return this->stream_length; } else return 0; } static uint32_t demux_mpgaudio_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mpgaudio_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static void demux_mpgaudio_dispose (demux_plugin_t *this_gen) { demux_mpgaudio_t *this = (demux_mpgaudio_t *) this_gen; _free_vbri_header(&this->vbri_header); _x_freep(&this->xing_header); free(this); } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_mpgaudio_t *this; int version = 0; int layer = 0; lprintf("trying to open %s...\n", input->get_mrl(input)); switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { if (detect_mpgaudio_file (stream, input, &version, &layer) < 0) return NULL; } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } this = calloc(1, sizeof(demux_mpgaudio_t)); if (!this) return NULL; this->demux_plugin.send_headers = demux_mpgaudio_send_headers; this->demux_plugin.send_chunk = demux_mpgaudio_send_chunk; this->demux_plugin.seek = demux_mpgaudio_seek; this->demux_plugin.dispose = demux_mpgaudio_dispose; this->demux_plugin.get_status = demux_mpgaudio_get_status; this->demux_plugin.get_stream_length = demux_mpgaudio_get_stream_length; this->demux_plugin.get_capabilities = demux_mpgaudio_get_capabilities; this->demux_plugin.get_optional_data = demux_mpgaudio_get_optional_data; this->demux_plugin.demux_class = class_gen; this->input = input; this->audio_fifo = stream->audio_fifo; this->status = DEMUX_FINISHED; this->stream = stream; this->mpg_version = version; this->mpg_layer = layer; if (version || layer) { this->valid_frames = NUM_VALID_FRAMES; } return &this->demux_plugin; } /* * demux mpegaudio class */ void *demux_mpgaudio_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_mpgaudio_class = { .open_plugin = open_plugin, .description = N_("MPEG audio demux plugin"), .identifier = "MPEGAUDIO", .mimetypes = "audio/mpeg2: mp2: MPEG audio;" "audio/x-mpeg2: mp2: MPEG audio;" "audio/mpeg3: mp3: MPEG audio;" "audio/x-mpeg3: mp3: MPEG audio;" "audio/mpeg: mpa,abs,mpega: MPEG audio;" "audio/x-mpeg: mpa,abs,mpega: MPEG audio;" "audio/x-mpegurl: mp3: MPEG audio;" "audio/mpegurl: mp3: MPEG audio;" "audio/mp3: mp3: MPEG audio;" "audio/x-mp3: mp3: MPEG audio;", .extensions = "mp3 mp2 mpa mpega", .dispose = NULL, }; return (void *)&demux_mpgaudio_class; } xine-lib-1.2/src/demuxers/group_games.h0000644000175000017500000000314614647725152015774 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_GROUP_GAMES_H #define HAVE_GROUP_GAMES_H #include void *demux_eawve_init_plugin (xine_t *xine, const void *data); void *demux_idcin_init_plugin (xine_t *xine, const void *data); void *demux_ipmovie_init_plugin (xine_t *xine, const void *data); void *demux_vqa_init_plugin (xine_t *xine, const void *data); void *demux_wc3movie_init_plugin (xine_t *xine, const void *data); void *demux_roq_init_plugin (xine_t *xine, const void *data); void *demux_str_init_plugin (xine_t *xine, const void *data); void *demux_film_init_plugin (xine_t *xine, const void *data); void *demux_smjpeg_init_plugin (xine_t *xine, const void *data); void *demux_fourxm_init_plugin (xine_t *xine, const void *data); void *demux_vmd_init_plugin (xine_t *xine, const void *data); #endif xine-lib-1.2/src/demuxers/demux_ipmovie.c0000644000175000017500000005750414647725152016340 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * Interplay MVE File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the Interplay MVE file format, visit: * http://www.pcisys.net/~melanson/codecs/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_ipmovie" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" #define IPMOVIE_SIGNATURE "Interplay MVE File\x1A\0" #define IPMOVIE_SIGNATURE_SIZE 20 #define CHUNK_PREAMBLE_SIZE 4 #define OPCODE_PREAMBLE_SIZE 4 #define CHUNK_INIT_AUDIO 0x0000 #define CHUNK_AUDIO_ONLY 0x0001 #define CHUNK_INIT_VIDEO 0x0002 #define CHUNK_VIDEO 0x0003 #define CHUNK_SHUTDOWN 0x0004 #define CHUNK_END 0x0005 /* this last type is used internally */ #define CHUNK_BAD 0xFFFF #define OPCODE_END_OF_STREAM 0x00 #define OPCODE_END_OF_CHUNK 0x01 #define OPCODE_CREATE_TIMER 0x02 #define OPCODE_INIT_AUDIO_BUFFERS 0x03 #define OPCODE_START_STOP_AUDIO 0x04 #define OPCODE_INIT_VIDEO_BUFFERS 0x05 #define OPCODE_UNKNOWN_06 0x06 #define OPCODE_SEND_BUFFER 0x07 #define OPCODE_AUDIO_FRAME 0x08 #define OPCODE_SILENCE_FRAME 0x09 #define OPCODE_INIT_VIDEO_MODE 0x0A #define OPCODE_CREATE_GRADIENT 0x0B #define OPCODE_SET_PALETTE 0x0C #define OPCODE_SET_PALETTE_COMPRESSED 0x0D #define OPCODE_UNKNOWN_0E 0x0E #define OPCODE_SET_DECODING_MAP 0x0F #define OPCODE_UNKNOWN_10 0x10 #define OPCODE_VIDEO_DATA 0x11 #define OPCODE_UNKNOWN_12 0x12 #define OPCODE_UNKNOWN_13 0x13 #define OPCODE_UNKNOWN_14 0x14 #define OPCODE_UNKNOWN_15 0x15 #define PALETTE_COUNT 256 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_size; float fps; unsigned int frame_pts_inc; xine_bmiheader bih; xine_waveformatex wave; int64_t video_pts; unsigned int audio_type; unsigned int audio_frame_count; palette_entry_t palette[PALETTE_COUNT + 1]; unsigned char *decode_map; int decode_map_size; int new_palette; } demux_ipmovie_t; /* This function loads and processes a single chunk in an IP movie file. * It returns the type of chunk that was processed. */ static int process_ipmovie_chunk(demux_ipmovie_t *this) { unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; int chunk_type; int chunk_size; unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE]; unsigned char opcode_type; unsigned char opcode_version; int opcode_size; unsigned char scratch[1024]; int i, j; int first_color, color_count; int audio_flags; buf_element_t *buf = NULL; off_t current_file_pos; int64_t audio_pts = 0; int decode_map_index; int decode_map_size_countdown; /* read the next chunk, wherever the file happens to be pointing */ if (this->input->read(this->input, chunk_preamble, CHUNK_PREAMBLE_SIZE) != CHUNK_PREAMBLE_SIZE) return CHUNK_BAD; chunk_size = _X_LE_16(&chunk_preamble[0]); chunk_type = _X_LE_16(&chunk_preamble[2]); lprintf("chunk type 0x%04X, 0x%04X bytes:\n", chunk_type, chunk_size); switch (chunk_type) { case CHUNK_INIT_AUDIO: lprintf("initialize audio\n"); break; case CHUNK_AUDIO_ONLY: lprintf("audio only\n"); break; case CHUNK_INIT_VIDEO: lprintf("initialize video\n"); break; case CHUNK_VIDEO: lprintf("video (and audio)\n"); break; case CHUNK_SHUTDOWN: lprintf("shutdown\n"); break; case CHUNK_END: lprintf("end\n"); break; default: lprintf("invalid chunk\n"); chunk_type = CHUNK_BAD; break; } while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) { /* read the next chunk, wherever the file happens to be pointing */ if (this->input->read(this->input, opcode_preamble, OPCODE_PREAMBLE_SIZE) != OPCODE_PREAMBLE_SIZE) { chunk_type = CHUNK_BAD; break; } opcode_size = _X_LE_16(&opcode_preamble[0]); opcode_type = opcode_preamble[2]; opcode_version = opcode_preamble[3]; chunk_size -= OPCODE_PREAMBLE_SIZE; chunk_size -= opcode_size; if (chunk_size < 0) { lprintf("chunk_size countdown just went negative\n"); chunk_type = CHUNK_BAD; break; } lprintf("opcode type %02X, version %d, 0x%04X bytes:\n", opcode_type, opcode_version, opcode_size); switch (opcode_type) { case OPCODE_END_OF_STREAM: lprintf("end of stream\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_END_OF_CHUNK: lprintf("end of chunk\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_CREATE_TIMER: lprintf("create timer\n"); if ((opcode_version > 0) || (opcode_size > 6)) { lprintf("bad create_timer opcode\n"); chunk_type = CHUNK_BAD; break; } if (this->input->read(this->input, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } this->fps = 1000000.0 / (_X_LE_32(&scratch[0]) * _X_LE_16(&scratch[4])); this->frame_pts_inc = (int)(90000.0 / this->fps); lprintf("%.1f frames/second (timer div = %d, subdiv = %d)\n", this->fps, _X_LE_32(&scratch[0]), _X_LE_16(&scratch[4])); break; case OPCODE_INIT_AUDIO_BUFFERS: lprintf("initialize audio buffers\n"); if ((opcode_version > 1) || (opcode_size > 10)) { lprintf("bad init_audio_buffers opcode\n"); chunk_type = CHUNK_BAD; break; } if (this->input->read(this->input, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } this->wave.nSamplesPerSec = _X_LE_16(&scratch[4]); audio_flags = _X_LE_16(&scratch[2]); /* bit 0 of the flags: 0 = mono, 1 = stereo */ this->wave.nChannels = (audio_flags & 1) + 1; /* bit 1 of the flags: 0 = 8 bit, 1 = 16 bit */ this->wave.wBitsPerSample = (((audio_flags >> 1) & 1) + 1) * 8; /* bit 2 indicates compressed audio in version 1 opcode */ if ((opcode_version == 1) && (audio_flags & 0x4)) this->audio_type = BUF_AUDIO_INTERPLAY; else this->audio_type = BUF_AUDIO_LPCM_LE; lprintf("audio: %d bits, %d Hz, %s, %s format\n", this->wave.wBitsPerSample, this->wave.nSamplesPerSec, (this->wave.nChannels == 2) ? "stereo" : "mono", (this->audio_type == BUF_AUDIO_LPCM_LE) ? "PCM" : "Interplay audio"); break; case OPCODE_START_STOP_AUDIO: lprintf("start/stop audio\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_INIT_VIDEO_BUFFERS: lprintf("initialize video buffers\n"); _x_freep(&this->decode_map); if ((opcode_version > 2) || (opcode_size > 8)) { lprintf("bad init_video_buffers opcode\n"); chunk_type = CHUNK_BAD; break; } if (this->input->read(this->input, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } this->bih.biWidth = _X_LE_16(&scratch[0]) * 8; this->bih.biHeight = _X_LE_16(&scratch[2]) * 8; /* set up staging area for decode map */ this->decode_map_size = (this->bih.biWidth / 8) * (this->bih.biHeight / 8) / 2; this->decode_map = calloc(1, this->decode_map_size); if (!this->decode_map) this->status = DEMUX_FINISHED; lprintf("video resolution: %d x %d\n", this->bih.biWidth, this->bih.biHeight); break; case OPCODE_UNKNOWN_06: case OPCODE_UNKNOWN_0E: case OPCODE_UNKNOWN_10: case OPCODE_UNKNOWN_12: case OPCODE_UNKNOWN_13: case OPCODE_UNKNOWN_14: case OPCODE_UNKNOWN_15: lprintf("unknown (but documented) opcode %02X\n", opcode_type); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_SEND_BUFFER: lprintf("send buffer\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_AUDIO_FRAME: lprintf("audio frame\n"); current_file_pos = this->input->get_current_pos(this->input); /* figure out the number of audio frames */ if (this->audio_type == BUF_AUDIO_LPCM_LE) { opcode_size -= 6; this->audio_frame_count += (opcode_size / this->wave.nChannels / (this->wave.wBitsPerSample / 8)); if (this->input->seek(this->input, 6, SEEK_CUR) < 0) return CHUNK_BAD; } else this->audio_frame_count += (opcode_size - 6) / this->wave.nChannels; audio_pts = 90000; audio_pts *= this->audio_frame_count; audio_pts /= this->wave.nSamplesPerSec; lprintf("sending audio frame with pts %"PRId64" (%d audio frames)\n", audio_pts, this->audio_frame_count); if(this->audio_fifo) { while (opcode_size) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = audio_pts / 90; buf->pts = audio_pts; if (opcode_size > buf->max_size) buf->size = buf->max_size; else buf->size = opcode_size; opcode_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); chunk_type = CHUNK_BAD; break; } if (!opcode_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); } }else{ if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; } break; case OPCODE_SILENCE_FRAME: lprintf("silence frame\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_INIT_VIDEO_MODE: lprintf("initialize video mode\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_CREATE_GRADIENT: lprintf("create gradient\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_SET_PALETTE: lprintf("set palette\n"); /* check for the logical maximum palette size * (3 * 256 + 4 bytes) */ if (opcode_size > 0x304) { lprintf("set_palette opcode too large\n"); chunk_type = CHUNK_BAD; break; } if (this->input->read(this->input, scratch, opcode_size) != opcode_size) { chunk_type = CHUNK_BAD; break; } /* load the palette into internal data structure */ first_color = _X_LE_16(&scratch[0]); color_count = _X_LE_16(&scratch[2]); /* sanity check (since they are 16 bit values) */ if ((first_color > 0xFF) || (first_color + color_count > 0x100)) { lprintf("set_palette indices out of range (%d -> %d)\n", first_color, first_color + color_count); chunk_type = CHUNK_BAD; break; } j = 4; /* offset of first palette data */ for (i = first_color; i < first_color + color_count; i++) { this->palette[i].r = scratch[j++] * 4; this->palette[i].g = scratch[j++] * 4; this->palette[i].b = scratch[j++] * 4; } this->new_palette = 1; break; case OPCODE_SET_PALETTE_COMPRESSED: lprintf("set palette compressed\n"); if (this->input->seek(this->input, opcode_size, SEEK_CUR) < 0) return CHUNK_BAD; break; case OPCODE_SET_DECODING_MAP: lprintf("set decoding map\n"); //current_file_pos = this->input->get_current_pos(this->input); lprintf("sending decoding map along with duration %d\n", this->frame_pts_inc); /* load the decode map into the staging area */ if (!this->decode_map || this->input->read(this->input, this->decode_map, this->decode_map_size) != this->decode_map_size) this->status = DEMUX_FINISHED; break; case OPCODE_VIDEO_DATA: lprintf("set video data\n"); current_file_pos = this->input->get_current_pos(this->input); lprintf("sending video data with pts %"PRId64"\n", this->video_pts); /* send off any new palette data */ if (this->new_palette) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = 256; buf->decoder_info_ptr[2] = &this->palette; buf->size = 0; buf->type = BUF_VIDEO_INTERPLAY; this->video_fifo->put (this->video_fifo, buf); this->new_palette = 0; } /* send the decode map first */ decode_map_index = 0; decode_map_size_countdown = this->decode_map ? this->decode_map_size : 0; while (decode_map_size_countdown) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_INTERPLAY; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; if (decode_map_size_countdown > buf->max_size) buf->size = buf->max_size; else buf->size = decode_map_size_countdown; decode_map_size_countdown -= buf->size; memcpy(buf->content, &this->decode_map[decode_map_index], buf->size); decode_map_index += buf->size; this->video_fifo->put (this->video_fifo, buf); } /* then send the video data */ while (opcode_size) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_INTERPLAY; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = this->video_pts / 90; buf->pts = this->video_pts; buf->decoder_flags = BUF_FLAG_FRAMERATE; buf->decoder_info[0] = this->frame_pts_inc; if (opcode_size > buf->max_size) buf->size = buf->max_size; else buf->size = opcode_size; opcode_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!opcode_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; /* Abuse the keyframe flag: Since a video chunk consists of 2 * distinct parts (the decode map, then the video data), and since * the format has no real notion of keyframes or seeking, use the * keyframe flag to indicate that this is the video portion of * the frame. */ buf->decoder_flags |= BUF_FLAG_KEYFRAME; this->video_fifo->put (this->video_fifo, buf); } this->video_pts += this->frame_pts_inc; break; default: lprintf("*** unknown opcode type\n"); chunk_type = CHUNK_BAD; break; } } return chunk_type; } /* returns 1 if the MVE file was opened successfully, 0 otherwise */ static int open_ipmovie_file(demux_ipmovie_t *this) { unsigned char signature[IPMOVIE_SIGNATURE_SIZE]; this->audio_type = 0; if (_x_demux_read_header(this->input, signature, IPMOVIE_SIGNATURE_SIZE) != IPMOVIE_SIGNATURE_SIZE) return 0; if (memcmp(signature, IPMOVIE_SIGNATURE, IPMOVIE_SIGNATURE_SIZE) != 0) return 0; /* file is qualified; skip over the signature bytes (+ 6 unknown) in the stream */ if (this->input->seek(this->input, IPMOVIE_SIGNATURE_SIZE+6, SEEK_SET) < 0) return 0; /* process the first chunk which should be CHUNK_INIT_VIDEO */ if (process_ipmovie_chunk(this) != CHUNK_INIT_VIDEO) return 0; /* process the next chunk which should be CHUNK_INIT_AUDIO */ if (process_ipmovie_chunk(this) != CHUNK_INIT_AUDIO) return 0; lprintf("detected Interplay MVE file\n"); this->data_size = this->input->get_length(this->input); this->audio_frame_count = 0; this->video_pts = 0; return 1; } static int demux_ipmovie_send_chunk(demux_plugin_t *this_gen) { demux_ipmovie_t *this = (demux_ipmovie_t *) this_gen; if (process_ipmovie_chunk(this) == CHUNK_BAD) this->status = DEMUX_FINISHED; return this->status; } static void demux_ipmovie_send_headers(demux_plugin_t *this_gen) { demux_ipmovie_t *this = (demux_ipmovie_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to video decoder */ this->bih.biSize = sizeof(xine_bmiheader); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; /* bogus initial video_step, but we won't know for sure until we see * the first video frame; however, fps for these files is usually 15 */ buf->decoder_info[0] = 6000; buf->size = sizeof(xine_bmiheader); memcpy(buf->content, &this->bih, buf->size); buf->type = BUF_VIDEO_INTERPLAY; this->video_fifo->put (this->video_fifo, buf); /* send off the palette */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = 256; buf->decoder_info_ptr[2] = &this->palette; buf->size = 0; buf->type = BUF_VIDEO_INTERPLAY; this->video_fifo->put (this->video_fifo, buf); /* send init info to the audio decoder */ if ((this->audio_fifo) && (this->audio_type)) { //this->wave.nSamplesPerSec = this->wave.nSamplesPerSec; //this->wave.wBitsPerSample = this->wave.wBitsPerSample; this->wave.nBlockAlign = (this->wave.wBitsPerSample / 8) * this->wave.nChannels; this->wave.nAvgBytesPerSec = this->wave.nBlockAlign * this->wave.nSamplesPerSec; buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->wave.nSamplesPerSec; buf->decoder_info[2] = this->wave.wBitsPerSample; buf->decoder_info[3] = this->wave.nChannels; buf->size = sizeof(this->wave); memcpy(buf->content, &this->wave, buf->size); this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_ipmovie_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_ipmovie_t *this = (demux_ipmovie_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static void demux_ipmovie_dispose (demux_plugin_t *this_gen) { demux_ipmovie_t *this = (demux_ipmovie_t *) this_gen; _x_freep(&this->decode_map); free(this); } static int demux_ipmovie_get_status (demux_plugin_t *this_gen) { demux_ipmovie_t *this = (demux_ipmovie_t *) this_gen; return this->status; } static int demux_ipmovie_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_ipmovie_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_ipmovie_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_ipmovie_t *this; this = calloc(1, sizeof(demux_ipmovie_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_ipmovie_send_headers; this->demux_plugin.send_chunk = demux_ipmovie_send_chunk; this->demux_plugin.seek = demux_ipmovie_seek; this->demux_plugin.dispose = demux_ipmovie_dispose; this->demux_plugin.get_status = demux_ipmovie_get_status; this->demux_plugin.get_stream_length = demux_ipmovie_get_stream_length; this->demux_plugin.get_capabilities = demux_ipmovie_get_capabilities; this->demux_plugin.get_optional_data = demux_ipmovie_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; this->decode_map = NULL; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_ipmovie_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_ipmovie_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_ipmovie_class = { .open_plugin = open_plugin, .description = N_("Interplay MVE Movie demux plugin"), .identifier = "Interplay MVE", .mimetypes = NULL, .extensions = "mve mv8", .dispose = NULL, }; return (void *)&demux_ipmovie_class; } xine-lib-1.2/src/demuxers/demux_dts.c0000644000175000017500000003116314647725152015453 0ustar meme/* * Copyright (C) 2005-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Raw DTS Demuxer by James Stembridge (jstembridge@gmail.com) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_ALLOCA_H #include #endif #ifdef HAVE_MALLOC_H #include #endif #define LOG_MODULE "demux_dts" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_audio.h" #define DATA_TAG 0x61746164 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int seek_flag; int samples_per_frame; int sample_rate; int frame_size; off_t data_start; } demux_dts_t; static const int dts_sample_rates[] = { 0, 8000, 16000, 32000, 0, 0, 11025, 22050, 44100, 0, 0, 12000, 24000, 48000, 96000, 192000 }; static int open_dts_file(demux_dts_t *this) { int i, offset = 0; uint32_t syncword = 0; size_t peak_size = 0; uint32_t blocksize; uint8_t *peak; lprintf("open_dts_file\n"); blocksize = this->input->get_blocksize(this->input); if (blocksize && INPUT_IS_SEEKABLE(this->input)) { // this->input->seek(this->input, 0, SEEK_SET); buf_element_t *buf = this->input->read_block(this->input, this->stream->audio_fifo, blocksize); if (!buf) return 0; peak = alloca(peak_size = buf->size); xine_fast_memcpy(peak, buf->content, peak_size); buf->free_buffer(buf); if (this->input->seek(this->input, 0, SEEK_SET) != 0) return 0; } else { peak = alloca(peak_size = MAX_PREVIEW_SIZE); if (_x_demux_read_header (this->input, peak, peak_size) != (int)peak_size) return 0; } lprintf("peak size: %zu\n", peak_size); /* Check for wav header, as we'll handle DTS with a wav header shoved * on the front for CD burning */ /* FIXME: This is risky. Real LPCM may contain anything, even sync words. */ if ( memcmp(peak, "RIFF", 4) == 0 || memcmp(&peak[8], "WAVEfmt ", 8) == 0 ) { /* Check this looks like a cd audio wav */ unsigned int audio_type; xine_waveformatex *wave = (xine_waveformatex *) &peak[20]; _x_waveformatex_le2me(wave); audio_type = _x_formattag_to_buf_audio(wave->wFormatTag); if ((audio_type != BUF_AUDIO_LPCM_LE) || (wave->nChannels != 2) || (wave->nSamplesPerSec != 44100) || (wave->wBitsPerSample != 16)) return 0; lprintf("looks like a cd audio wav file\n"); /* Find the data chunk */ offset = 20 + _X_LE_32(&peak[16]); while (offset < (int)peak_size - 8) { unsigned int chunk_tag = _X_LE_32(&peak[offset]); unsigned int chunk_size = _X_LE_32(&peak[offset+4]); if (chunk_tag == DATA_TAG) { offset += 8; lprintf("found the start of the data at offset %d\n", offset); break; } else offset += 8 + chunk_size; } } /* DTS bitstream encoding version * -1 - not detected * 0 - 16 bits and big endian * 1 - 16 bits and low endian (detection not implemented) * 2 - 14 bits and big endian (detection not implemented) * 3 - 14 bits and low endian */ int dts_version = -1; /* Look for a valid DTS syncword */ for (i = offset; i < (int)peak_size - 1; i++) { /* 16 bits and big endian bitstream */ if (syncword == 0x7ffe8001) { dts_version = 0; break; } /* 14 bits and little endian bitstream */ else if ((syncword == 0xff1f00e8) && ((peak[i] & 0xf0) == 0xf0) && (peak[i+1] == 0x07)) { dts_version = 3; break; } syncword = (syncword << 8) | peak[i]; } if (dts_version == -1) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": unsupported DTS stream type, or not a DTS stream\n"); return 0; } this->data_start = i-4; lprintf("found DTS syncword at offset %d\n", i-4); if (i < (int)peak_size - 9) { unsigned int nblks, fsize, sfreq; switch (dts_version) { case 0: /* BE16 */ nblks = ((peak[this->data_start+4] & 0x01) << 6) | ((peak[this->data_start+5] & 0xfc) >> 2); fsize = (((peak[this->data_start+5] & 0x03) << 12) |(peak[this->data_start+6] << 4) | ((peak[this->data_start+7] & 0xf0) >> 4)) + 1; sfreq = (peak[this->data_start+8] & 0x3c) >> 2; break; case 3: /* LE14 */ nblks = ((peak[this->data_start+4] & 0x07) << 4) | ((peak[this->data_start+7] & 0x3c) >> 2); fsize = (((peak[this->data_start+7] & 0x03) << 12) | (peak[this->data_start+6] << 4) | ((peak[this->data_start+9] & 0x3c) >> 2)) + 1; sfreq = peak[this->data_start+8] & 0x0f; break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": unsupported DTS bitstream encoding %d\n", dts_version); return 0; } if ((sfreq >= sizeof(dts_sample_rates)/sizeof(int)) || (dts_sample_rates[sfreq] == 0)) return 0; /* Big assumption - this is CBR data */ this->samples_per_frame = (nblks + 1) * 32; switch (dts_version) { case 0: /* BE16 */ //case 1: /* LE16 */ this->frame_size = fsize * 8 / 16 * 2; break; //case 2: /* BE14 */ case 3: /* LE14 */ this->frame_size = fsize * 8 / 14 * 2; break; } this->sample_rate = dts_sample_rates[sfreq]; lprintf("samples per frame: %d\n", this->samples_per_frame); lprintf("frame size: %d\n", this->frame_size); lprintf("sample rate: %d\n", this->sample_rate); /* Seek to start of DTS data */ if (this->input->seek(this->input, this->data_start, SEEK_SET) != this->data_start) return 0; return 1; } return 0; } static int demux_dts_send_chunk (demux_plugin_t *this_gen) { demux_dts_t *this = (demux_dts_t *) this_gen; buf_element_t *buf = NULL; off_t current_stream_pos; int64_t audio_pts; int frame_number; uint32_t blocksize; current_stream_pos = this->input->get_current_pos(this->input) - this->data_start; frame_number = current_stream_pos / this->frame_size; audio_pts = frame_number; audio_pts *= 90000; audio_pts *= this->samples_per_frame; audio_pts /= this->sample_rate; if (this->seek_flag) { _x_demux_control_newpts(this->stream, audio_pts, BUF_FLAG_SEEK); this->seek_flag = 0; } blocksize = this->input->get_blocksize(this->input); if (blocksize) { buf = this->input->read_block(this->input, this->audio_fifo, blocksize); if (!buf) { this->status = DEMUX_FINISHED; return this->status; } } else { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->size = this->input->read(this->input, buf->content, this->frame_size); } if (buf->size <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } buf->type = BUF_AUDIO_DTS; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) current_stream_pos * 65535 / (this->input->get_length(this->input) - this->data_start) ); buf->extra_info->input_time = audio_pts / 90; buf->pts = audio_pts; buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); return this->status; } static void demux_dts_send_headers(demux_plugin_t *this_gen) { demux_dts_t *this = (demux_dts_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_DTS; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_dts_get_stream_length (demux_plugin_t *this_gen) { demux_dts_t *this = (demux_dts_t *) this_gen; int stream_length = 0; if (this->input->get_length(this->input)) { stream_length = this->input->get_length(this->input) - this->data_start; stream_length /= this->frame_size; stream_length *= this->samples_per_frame; stream_length /= this->sample_rate; stream_length *= 1000; lprintf("running time: %u\n", stream_length); } return stream_length; } static int demux_dts_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_dts_t *this = (demux_dts_t *) this_gen; (void)playing; this->seek_flag = 1; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!INPUT_IS_SEEKABLE(this->input)) return this->status; start_pos = (off_t) ( (double) start_pos / 65535 * (this->input->get_length(this->input) - this->data_start) ); if (start_time) { int length = demux_dts_get_stream_length (this_gen); if (length != 0) { start_pos = start_time * (this->input->get_length(this->input) - this->data_start) / length; } } /* divide the requested offset integer-wise by the frame alignment and * multiply by the frame alignment to determine the new starting block */ start_pos /= this->frame_size; start_pos *= this->frame_size; start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); return this->status; } static int demux_dts_get_status (demux_plugin_t *this_gen) { demux_dts_t *this = (demux_dts_t *) this_gen; return this->status; } static uint32_t demux_dts_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_dts_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_dts_t *this; this = calloc(1, sizeof(demux_dts_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_dts_send_headers; this->demux_plugin.send_chunk = demux_dts_send_chunk; this->demux_plugin.seek = demux_dts_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_dts_get_status; this->demux_plugin.get_stream_length = demux_dts_get_stream_length; this->demux_plugin.get_capabilities = demux_dts_get_capabilities; this->demux_plugin.get_optional_data = demux_dts_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_dts_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_dts_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_dts_class = { .open_plugin = open_plugin, .description = N_("Raw DTS demux plugin"), .identifier = "DTS", .mimetypes = NULL, .extensions = "dts", .dispose = NULL, }; return (void *)&demux_dts_class; } xine-lib-1.2/src/demuxers/group_audio.c0000644000175000017500000000636614647725152016003 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * This file contains plugin entries for several demuxers used in games */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "group_audio.h" /* * exported plugin catalog entries */ static const demuxer_info_t demux_info_minus_3 = { .priority = -3 }; static const demuxer_info_t demux_info_minus_1 = { .priority = -1 }; static const demuxer_info_t demux_info_plus__0 = { .priority = 0 }; static const demuxer_info_t demux_info_plus__1 = { .priority = 1 }; static const demuxer_info_t demux_info_plus__6 = { .priority = 6 }; static const demuxer_info_t demux_info_plus__8 = { .priority = 8 }; static const demuxer_info_t demux_info_plus_10 = { .priority = 10 }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "aac", XINE_VERSION_CODE, &demux_info_minus_1, demux_aac_init_plugin }, { PLUGIN_DEMUX, 27, "ac3", XINE_VERSION_CODE, &demux_info_plus__8, demux_ac3_init_plugin }, { PLUGIN_DEMUX, 27, "aud", XINE_VERSION_CODE, &demux_info_minus_3, demux_aud_init_plugin }, { PLUGIN_DEMUX, 27, "aiff", XINE_VERSION_CODE, &demux_info_plus_10, demux_aiff_init_plugin }, { PLUGIN_DEMUX, 27, "cdda", XINE_VERSION_CODE, &demux_info_plus__6, demux_cdda_init_plugin }, { PLUGIN_DEMUX, 27, "dts", XINE_VERSION_CODE, &demux_info_plus__8, demux_dts_init_plugin }, { PLUGIN_DEMUX, 27, "flac", XINE_VERSION_CODE, &demux_info_plus_10, demux_flac_init_plugin }, { PLUGIN_DEMUX, 27, "mp3", XINE_VERSION_CODE, &demux_info_plus__0, demux_mpgaudio_init_class }, { PLUGIN_DEMUX, 27, "mpc", XINE_VERSION_CODE, &demux_info_plus__1, demux_mpc_init_plugin }, { PLUGIN_DEMUX, 27, "realaudio", XINE_VERSION_CODE, &demux_info_plus_10, demux_realaudio_init_plugin }, { PLUGIN_DEMUX, 27, "shn", XINE_VERSION_CODE, &demux_info_plus__0, demux_shn_init_plugin }, { PLUGIN_DEMUX, 27, "snd", XINE_VERSION_CODE, &demux_info_plus_10, demux_snd_init_plugin }, { PLUGIN_DEMUX, 27, "tta", XINE_VERSION_CODE, &demux_info_plus_10, demux_tta_init_plugin }, { PLUGIN_DEMUX, 27, "voc", XINE_VERSION_CODE, &demux_info_plus_10, demux_voc_init_plugin }, { PLUGIN_DEMUX, 27, "vox", XINE_VERSION_CODE, &demux_info_plus_10, demux_vox_init_plugin }, { PLUGIN_DEMUX, 27, "wav", XINE_VERSION_CODE, &demux_info_plus__6, demux_wav_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_vmd.c0000644000175000017500000003563714647725152015461 0ustar meme/* * Copyright (C) 2004-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * Sierra Video and Music Data (.vmd) File Demuxer * by Mike Melanson (melanson@pcisys.net) * For more information on the VMD file format, visit: * http://www.pcisys.net/~melanson/codecs/ * * Note that the only way that this demuxer validates by content is by * checking the first 2 bytes, which are 0x2E 0x03 in a Sierra VMD file. * There is a 1/65536 chance of a false positive using this method. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_vmd" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" #define VMD_HEADER_SIZE 0x330 #define BYTES_PER_FRAME_RECORD 16 typedef struct { int is_audio_frame; off_t frame_offset; unsigned int frame_size; int64_t pts; int keyframe; unsigned char frame_record[BYTES_PER_FRAME_RECORD]; } vmd_frame_t; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_start; off_t data_size; xine_bmiheader bih; unsigned char vmd_header[VMD_HEADER_SIZE]; xine_waveformatex wave; unsigned int audio_frames; unsigned int iteration; unsigned int frame_count; vmd_frame_t *frame_table; unsigned int current_frame; int64_t video_pts_inc; int64_t total_pts; } demux_vmd_t; /* returns 1 if the VMD file was opened successfully, 0 otherwise */ static int open_vmd_file(demux_vmd_t *this) { unsigned char *vmd_header = this->vmd_header; off_t toc_offset; unsigned char *raw_frame_table; unsigned int raw_frame_table_size; unsigned char *current_frame_record; off_t current_offset; int i; unsigned int total_frames; int64_t current_video_pts = 0; if (_x_demux_read_header(this->input, vmd_header, VMD_HEADER_SIZE) != VMD_HEADER_SIZE) return 0; if (_X_LE_16(&vmd_header[0]) != VMD_HEADER_SIZE - 2) return 0; /* file is minimally qualified at this point, proceed to load */ /* get the actual filesize */ if ( !(this->data_size = this->input->get_length(this->input)) ) this->data_size = 1; this->bih.biSize = sizeof(xine_bmiheader) + VMD_HEADER_SIZE; this->bih.biWidth = _X_LE_16(&vmd_header[12]); this->bih.biHeight = _X_LE_16(&vmd_header[14]); this->wave.nSamplesPerSec = _X_LE_16(&vmd_header[804]); this->wave.nChannels = (vmd_header[811] & 0x80) ? 2 : 1; this->wave.nBlockAlign = _X_LE_16(&vmd_header[806]); if (this->wave.nBlockAlign & 0x8000) { this->wave.nBlockAlign -= 0x8000; this->wave.wBitsPerSample = 16; } else { this->wave.wBitsPerSample = 8; } /* decide on a framerate */ if (this->wave.nSamplesPerSec) { this->video_pts_inc = 90000; this->video_pts_inc *= this->wave.nBlockAlign; this->video_pts_inc /= this->wave.nSamplesPerSec; } else { this->video_pts_inc = 90000 / 10; } /* skip over the offset table and load the table of contents; don't * care about the offset table since demuxer will calculate those * independently */ toc_offset = _X_LE_32(&vmd_header[812]); this->frame_count = _X_LE_16(&vmd_header[6]); if (this->input->seek(this->input, toc_offset + this->frame_count * 6, SEEK_SET) < 0) return 0; /* while we have the toal number of blocks, calculate the total running * time */ this->total_pts = this->frame_count; this->total_pts *= this->video_pts_inc; this->total_pts /= 90; /* 2 frames for every block reported on disk */ this->frame_count *= 2; raw_frame_table_size = this->frame_count * BYTES_PER_FRAME_RECORD; raw_frame_table = malloc(raw_frame_table_size); if (!raw_frame_table) return 0; if (this->input->read(this->input, raw_frame_table, raw_frame_table_size) != raw_frame_table_size) { free(raw_frame_table); return 0; } this->frame_table = calloc(this->frame_count, sizeof(vmd_frame_t)); if (!this->frame_table) { free(raw_frame_table); return 0; } current_offset = this->data_start = _X_LE_32(&vmd_header[20]); this->data_size = toc_offset - this->data_start; current_frame_record = raw_frame_table; total_frames = this->frame_count; i = 0; while (total_frames--) { /* if the frame size is 0, do not count the frame and bring the * total frame count down */ this->frame_table[i].frame_size = _X_LE_32(¤t_frame_record[2]); /* this logic is present so that 0-length audio chunks are not * accounted */ if (!this->frame_table[i].frame_size) { this->frame_count--; /* one less frame to count */ current_frame_record += BYTES_PER_FRAME_RECORD; continue; } if (current_frame_record[0] == 0x02) { this->frame_table[i].is_audio_frame = 0; this->frame_table[i].pts = current_video_pts; current_video_pts += this->video_pts_inc; } else { this->frame_table[i].is_audio_frame = 1; this->frame_table[i].pts = 0; } this->frame_table[i].frame_offset = current_offset; current_offset += this->frame_table[i].frame_size; memcpy(this->frame_table[i].frame_record, current_frame_record, BYTES_PER_FRAME_RECORD); current_frame_record += BYTES_PER_FRAME_RECORD; i++; } free(raw_frame_table); this->current_frame = 0; return 1; } static int demux_vmd_send_chunk(demux_plugin_t *this_gen) { demux_vmd_t *this = (demux_vmd_t *) this_gen; buf_element_t *buf = NULL; unsigned int remaining_bytes; vmd_frame_t *frame; if (this->current_frame >= this->frame_count) { this->status = DEMUX_FINISHED; return this->status; } frame = &this->frame_table[this->current_frame]; /* position the stream (will probably be there already) */ if (this->input->seek(this->input, frame->frame_offset, SEEK_SET) < 0) { /* skip to next frame */ this->current_frame++; return this->status; } remaining_bytes = frame->frame_size; if (!frame->is_audio_frame) { /* send off the frame record first in its own buffer */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_VMD; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) (frame->frame_offset - this->data_start) * 65535 / this->data_size); memcpy(buf->content, frame->frame_record, BYTES_PER_FRAME_RECORD); buf->size = BYTES_PER_FRAME_RECORD; buf->pts = frame->pts; buf->extra_info->input_time = buf->pts / 90; this->video_fifo->put(this->video_fifo, buf); while (remaining_bytes) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_VMD; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) (frame->frame_offset - this->data_start) * 65535 / this->data_size); if ((int)remaining_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_bytes; remaining_bytes -= buf->size; if (!remaining_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } buf->pts = frame->pts; buf->extra_info->input_time = buf->pts / 90; this->video_fifo->put(this->video_fifo, buf); } } else if (frame->is_audio_frame && this->audio_fifo) { #if 0 /* send off the frame record first in its own buffer */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_VMD; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) (frame->frame_offset - this->data_start) * 65535 / this->data_size); memcpy(buf->content, frame->frame_record, BYTES_PER_FRAME_RECORD); buf->size = BYTES_PER_FRAME_RECORD; buf->pts = 0; /* let the engine sort out the audio pts */ buf->extra_info->input_time = 0; this->audio_fifo->put(this->audio_fifo, buf); while (remaining_bytes) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_VMD; if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) (frame->frame_offset - this->data_start) * 65535 / this->data_size); if (remaining_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_bytes; remaining_bytes -= buf->size; if (!remaining_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } buf->pts = 0; /* let the engine sort out the audio pts */ buf->extra_info->input_time = 0; this->audio_fifo->put(this->audio_fifo, buf); } #endif } this->current_frame++; return this->status; } static void demux_vmd_send_headers(demux_plugin_t *this_gen) { demux_vmd_t *this = (demux_vmd_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->wave.nSamplesPerSec) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->wave.nChannels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->wave.nSamplesPerSec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->wave.wBitsPerSample); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->video_pts_inc; /* initial duration */ memcpy(buf->content, &this->bih, sizeof(xine_bmiheader)); memcpy(buf->content + sizeof(xine_bmiheader), this->vmd_header, VMD_HEADER_SIZE); buf->size = sizeof(xine_bmiheader) + VMD_HEADER_SIZE; buf->type = BUF_VIDEO_VMD; this->video_fifo->put (this->video_fifo, buf); #if 0 if (this->audio_fifo && this->wave.nSamplesPerSec) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_VMD; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->wave.nSamplesPerSec; buf->decoder_info[2] = this->wave.wBitsPerSample; buf->decoder_info[3] = this->wave.nChannels; this->wave.nBlockAlign = (this->wave.wBitsPerSample / 8) * this->wave.nChannels; this->wave.nAvgBytesPerSec = this->wave.nBlockAlign * this->wave.nSamplesPerSec; memcpy(buf->content, &this->wave, sizeof(this->wave)); buf->size = sizeof(this->wave); this->audio_fifo->put (this->audio_fifo, buf); } #endif } static int demux_vmd_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_vmd_t *this = (demux_vmd_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { this->status = DEMUX_OK; } return this->status; } static int demux_vmd_get_status (demux_plugin_t *this_gen) { demux_vmd_t *this = (demux_vmd_t *) this_gen; return this->status; } static int demux_vmd_get_stream_length (demux_plugin_t *this_gen) { demux_vmd_t *this = (demux_vmd_t *) this_gen; return this->total_pts; } static uint32_t demux_vmd_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_vmd_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_vmd_t *this; this = calloc(1, sizeof(demux_vmd_t)); if (!this) { return NULL; } this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_vmd_send_headers; this->demux_plugin.send_chunk = demux_vmd_send_chunk; this->demux_plugin.seek = demux_vmd_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_vmd_get_status; this->demux_plugin.get_stream_length = demux_vmd_get_stream_length; this->demux_plugin.get_capabilities = demux_vmd_get_capabilities; this->demux_plugin.get_optional_data = demux_vmd_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_vmd_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_vmd_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_vmd_class = { .open_plugin = open_plugin, .description = N_("Sierra VMD file demux plugin"), .identifier = "VMD", .mimetypes = NULL, .extensions = "vmd", .dispose = NULL, }; return (void *)&demux_vmd_class; } xine-lib-1.2/src/demuxers/matroska.h0000644000175000017500000003716614647725152015316 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Matroska EBML stream handling */ #ifndef MATROSKA_H #define MATROSKA_H #include #include #include #include "ebml.h" /* * Matroska Element IDs */ /* Segment */ #define MATROSKA_ID_SEGMENT 0x18538067 /* Meta Seek Information */ #define MATROSKA_ID_SEEKHEAD 0x114D9B74 #define MATROSKA_ID_S_ENTRY 0x4DBB #define MATROSKA_ID_S_ID 0x53AB #define MATROSKA_ID_S_POSITION 0x53AC /* Segment Information */ #define MATROSKA_ID_INFO 0x1549A966 #define MATROSKA_ID_I_SEGMENTUID 0x73A4 #define MATROSKA_ID_I_FILENAME 0x7384 #define MATROSKA_ID_I_PREVUID 0x3CB923 #define MATROSKA_ID_I_PREVFILENAME 0x3C83AB #define MATROSKA_ID_I_NEXTUID 0x3EB923 #define MATROSKA_ID_I_NEXTFILENAME 0x3E83BB #define MATROSKA_ID_I_TIMECODESCALE 0x2AD7B1 #define MATROSKA_ID_I_DURATION 0x4489 #define MATROSKA_ID_I_DATEUTC 0x4461 #define MATROSKA_ID_I_TITLE 0x7BA9 #define MATROSKA_ID_I_MUXINGAPP 0x4D80 #define MATROSKA_ID_I_WRITINGAPP 0x5741 /* Cluster */ #define MATROSKA_ID_CLUSTER 0x1F43B675 #define MATROSKA_ID_CL_TIMECODE 0xE7 #define MATROSKA_ID_CL_POSITION 0xA7 #define MATROSKA_ID_CL_PREVSIZE 0xAB #define MATROSKA_ID_CL_BLOCKGROUP 0xA0 #define MATROSKA_ID_CL_BLOCK 0xA1 #define MATROSKA_ID_CL_BLOCKVIRTUAL 0xA2 #define MATROSKA_ID_CL_SIMPLEBLOCK 0xA3 #define MATROSKA_ID_CL_BLOCKADDITIONS 0x75A1 #define MATROSKA_ID_CL_BLOCKMORE 0xA6 #define MATROSKA_ID_CL_BLOCKADDID 0xEE #define MATROSKA_ID_CL_BLOCKADDITIONAL 0xA5 #define MATROSKA_ID_CL_BLOCKDURATION 0x9B #define MATROSKA_ID_CL_REFERENCEPRIORITY 0xFA #define MATROSKA_ID_CL_REFERENCEBLOCK 0xFB #define MATROSKA_ID_CL_REFERENCEVIRTUAL 0xFD #define MATROSKA_ID_CL_CODECSTATE 0xA4 #define MATROSKA_ID_CL_SLICES 0x8E #define MATROSKA_ID_CL_TIMESLICE 0xE8 #define MATROSKA_ID_CL_LACENUMBER 0xCC #define MATROSKA_ID_CL_FRAMENUMBER 0xCD #define MATROSKA_ID_CL_BLOCKADDITIONID 0xCB #define MATROSKA_ID_CL_DELAY 0xCE #define MATROSKA_ID_CL_DURATION 0xCF /* Track */ #define MATROSKA_ID_TRACKS 0x1654AE6B #define MATROSKA_ID_TR_ENTRY 0xAE #define MATROSKA_ID_TR_NUMBER 0xD7 #define MATROSKA_ID_TR_UID 0x73C5 #define MATROSKA_ID_TR_TYPE 0x83 #define MATROSKA_ID_TR_FLAGENABLED 0xB9 #define MATROSKA_ID_TR_FLAGDEFAULT 0x88 #define MATROSKA_ID_TR_FLAGLACING 0x9C #define MATROSKA_ID_TR_MINCACHE 0x6DE7 #define MATROSKA_ID_TR_MAXCACHE 0x6DF8 #define MATROSKA_ID_TR_DEFAULTDURATION 0x23E383 #define MATROSKA_ID_TR_TIMECODESCALE 0x23314F #define MATROSKA_ID_TR_NAME 0x536E #define MATROSKA_ID_TR_LANGUAGE 0x22B59C #define MATROSKA_ID_TR_CODECID 0x86 #define MATROSKA_ID_TR_CODECPRIVATE 0x63A2 #define MATROSKA_ID_TR_CODECNAME 0x258688 #define MATROSKA_ID_TR_CODECSETTINGS 0x3A9697 #define MATROSKA_ID_TR_CODECINFOURL 0x3B4040 #define MATROSKA_ID_TR_CODECDOWNLOADURL 0x26B240 #define MATROSKA_ID_TR_CODECDECODEALL 0xAA #define MATROSKA_ID_TR_OVERLAY 0x6FAB /* Video */ #define MATROSKA_ID_TV 0xE0 #define MATROSKA_ID_TV_FLAGINTERLACED 0x9A #define MATROSKA_ID_TV_STEREOMODE 0x53B9 #define MATROSKA_ID_TV_PIXELWIDTH 0xB0 #define MATROSKA_ID_TV_PIXELHEIGHT 0xBA #define MATROSKA_ID_TV_VIDEODISPLAYWIDTH 0x54B0 #define MATROSKA_ID_TV_VIDEODISPLAYHEIGHT 0x54BA #define MATROSKA_ID_TV_VIDEOUNIT 0x54B2 #define MATROSKA_ID_TV_ASPECTRATIOTYPE 0x54B3 #define MATROSKA_ID_TV_COLOURSPACE 0x2EB524 #define MATROSKA_ID_TV_GAMMAVALUE 0x2FB523 /* Audio */ #define MATROSKA_ID_TA 0xE1 #define MATROSKA_ID_TA_SAMPLINGFREQUENCY 0xB5 #define MATROSKA_ID_TA_OUTPUTSAMPLINGFREQUENCY 0x78B5 #define MATROSKA_ID_TA_CHANNELS 0x9F #define MATROSKA_ID_TA_CHANNELPOSITIONS 0x9F #define MATROSKA_ID_TA_BITDEPTH 0x6264 /* Content Encoding */ #define MATROSKA_ID_CONTENTENCODINGS 0x6D80 #define MATROSKA_ID_CONTENTENCODING 0x6240 #define MATROSKA_ID_CE_ORDER 0x5031 #define MATROSKA_ID_CE_SCOPE 0x5032 #define MATROSKA_ID_CE_TYPE 0x5033 #define MATROSKA_ID_CE_COMPRESSION 0x5034 #define MATROSKA_ID_CE_COMPALGO 0x4254 #define MATROSKA_ID_CE_COMPSETTINGS 0x4255 #define MATROSKA_ID_CE_ENCRYPTION 0x5035 #define MATROSKA_ID_CE_ENCALGO 0x47E1 #define MATROSKA_ID_CE_ENCKEYID 0x47E2 #define MATROSKA_ID_CE_SIGNATURE 0x47E3 #define MATROSKA_ID_CE_SIGKEYID 0x47E4 #define MATROSKA_ID_CE_SIGALGO 0x47E5 #define MATROSKA_ID_CE_SIGHASHALGO 0x47E6 /* Cueing Data */ #define MATROSKA_ID_CUES 0x1C53BB6B #define MATROSKA_ID_CU_POINT 0xBB #define MATROSKA_ID_CU_TIME 0xB3 #define MATROSKA_ID_CU_TRACKPOSITION 0xB7 #define MATROSKA_ID_CU_TRACK 0xF7 #define MATROSKA_ID_CU_CLUSTERPOSITION 0xF1 #define MATROSKA_ID_CU_BLOCKNUMBER 0x5387 #define MATROSKA_ID_CU_CODECSTATE 0xEA #define MATROSKA_ID_CU_REFERENCE 0xDB #define MATROSKA_ID_CU_REFTIME 0x96 #define MATROSKA_ID_CU_REFCLUSTER 0x97 #define MATROSKA_ID_CU_REFNUMBER 0x535F #define MATROSKA_ID_CU_REFCODECSTATE 0xEB /* Attachements */ #define MATROSKA_ID_ATTACHMENTS 0x1941A469 #define MATROSKA_ID_AT_FILE 0x61A7 #define MATROSKA_ID_AT_FILEDESCRIPTION 0x467E #define MATROSKA_ID_AT_FILENAME 0x466E #define MATROSKA_ID_AT_FILEMIMETYPE 0x4660 #define MATROSKA_ID_AT_FILEDATA 0x465C #define MATROSKA_ID_AT_FILEUID 0x46AE /* Chapters */ #define MATROSKA_ID_CHAPTERS 0x1043A770 #define MATROSKA_ID_CH_EDITIONENTRY 0x45B9 #define MATROSKA_ID_CH_ED_UID 0x45BC #define MATROSKA_ID_CH_ED_HIDDEN 0x45BD #define MATROSKA_ID_CH_ED_DEFAULT 0x45DB #define MATROSKA_ID_CH_ED_ORDERED 0x45DD #define MATROSKA_ID_CH_ATOM 0xB6 #define MATROSKA_ID_CH_UID 0x73C4 #define MATROSKA_ID_CH_TIMESTART 0x91 #define MATROSKA_ID_CH_TIMEEND 0x92 #define MATROSKA_ID_CH_HIDDEN 0x98 #define MATROSKA_ID_CH_ENABLED 0x4598 #define MATROSKA_ID_CH_TRACK 0x8F #define MATROSKA_ID_CH_TRACKNUMBER 0x89 #define MATROSKA_ID_CH_DISPLAY 0x80 #define MATROSKA_ID_CH_STRING 0x85 #define MATROSKA_ID_CH_LANGUAGE 0x437C #define MATROSKA_ID_CH_COUNTRY 0x437E /* Tags */ #define MATROSKA_ID_TAGS 0x1254C367 /* Chapter (used in tracks) */ typedef struct { uint64_t uid; uint64_t time_start; uint64_t time_end; /* if not 0, the chapter could e.g. be used for skipping, but not * be shown in the chapter list */ int hidden; /* disabled chapters should be skipped during playback (using this * would require parsing control blocks) */ int enabled; /* Tracks this chapter belongs to. * Remember that elements can occur in any order, so in theory the * chapters could become available before the tracks do. * TODO: currently unused */ /* uint64_t* tracks; */ /* Chapter titles and locale information * TODO: chapters can have multiple sets of those, i.e. several tuples * (title, language, country). The current implementation picks from * those by the following rules: * 1) remember the first element * 2) overwrite with an element where language=="eng" */ char* title; char* language; char* country; } matroska_chapter_t; /* Edition */ typedef struct { uint64_t uid; unsigned int hidden; unsigned int is_default; unsigned int ordered; int num_chapters, cap_chapters; matroska_chapter_t** chapters; } matroska_edition_t; /* Matroska Track */ typedef struct { int flag_interlaced; int pixel_width; int pixel_height; int display_width; int display_height; } matroska_video_track_t; typedef struct { int sampling_freq; int output_sampling_freq; int channels; int bits_per_sample; } matroska_audio_track_t; typedef struct { char type; /* The rest is used for VobSubs (type = 'v'). */ int width; int height; uint32_t palette[16]; int custom_colors; uint32_t colors[4]; int forced_subs_only; } matroska_sub_track_t; typedef struct matroska_track_s matroska_track_t; struct matroska_track_s { int track_num; uint64_t uid; uint32_t track_type; uint64_t default_duration; char *language; char *codec_id; uint8_t *codec_private; uint32_t codec_private_len; int default_flag; uint32_t compress_algo; uint32_t compress_len; char *compress_settings; uint32_t buf_type; fifo_buffer_t *fifo; matroska_video_track_t *video_track; matroska_audio_track_t *audio_track; matroska_sub_track_t *sub_track; int64_t last_pts; int64_t delayed_pts; void (*handle_content) (demux_plugin_t *this_gen, matroska_track_t *track, int decoder_flags, uint8_t *data, size_t data_len, int64_t data_pts, int data_duration, int input_normpos, int input_time); }; /* IDs in the tags master */ /* * Matroska Codec IDs. Strings. */ #define MATROSKA_CODEC_ID_V_VFW_FOURCC "V_MS/VFW/FOURCC" #define MATROSKA_CODEC_ID_V_UNCOMPRESSED "V_UNCOMPRESSED" #define MATROSKA_CODEC_ID_V_MPEG4_SP "V_MPEG4/ISO/SP" #define MATROSKA_CODEC_ID_V_MPEG4_ASP "V_MPEG4/ISO/ASP" #define MATROSKA_CODEC_ID_V_MPEG4_AP "V_MPEG4/ISO/AP" #define MATROSKA_CODEC_ID_V_MPEG4_AVC "V_MPEG4/ISO/AVC" #define MATROSKA_CODEC_ID_V_MSMPEG4V3 "V_MPEG4/MS/V3" #define MATROSKA_CODEC_ID_V_MPEG1 "V_MPEG1" #define MATROSKA_CODEC_ID_V_MPEG2 "V_MPEG2" #define MATROSKA_CODEC_ID_V_MPEG2 "V_MPEG2" #define MATROSKA_CODEC_ID_V_REAL_RV10 "V_REAL/RV10" #define MATROSKA_CODEC_ID_V_REAL_RV20 "V_REAL/RV20" #define MATROSKA_CODEC_ID_V_REAL_RV30 "V_REAL/RV30" #define MATROSKA_CODEC_ID_V_REAL_RV40 "V_REAL/RV40" #define MATROSKA_CODEC_ID_V_MJPEG "V_MJPEG" #define MATROSKA_CODEC_ID_V_THEORA "V_THEORA" #define MATROSKA_CODEC_ID_V_VP8 "V_VP8" #define MATROSKA_CODEC_ID_V_VP9 "V_VP9" #define MATROSKA_CODEC_ID_V_HEVC "V_MPEGH/ISO/HEVC" #define MATROSKA_CODEC_ID_V_AV1 "V_AV1" #define MATROSKA_CODEC_ID_A_MPEG1_L1 "A_MPEG/L1" #define MATROSKA_CODEC_ID_A_MPEG1_L2 "A_MPEG/L2" #define MATROSKA_CODEC_ID_A_MPEG1_L3 "A_MPEG/L3" #define MATROSKA_CODEC_ID_A_PCM_INT_BE "A_PCM/INT/BIG" #define MATROSKA_CODEC_ID_A_PCM_INT_LE "A_PCM/INT/LIT" #define MATROSKA_CODEC_ID_A_PCM_FLOAT "A_PCM/FLOAT/IEEE" #define MATROSKA_CODEC_ID_A_AC3 "A_AC3" #define MATROSKA_CODEC_ID_A_EAC3 "A_EAC3" #define MATROSKA_CODEC_ID_A_DTS "A_DTS" #define MATROSKA_CODEC_ID_A_VORBIS "A_VORBIS" #define MATROSKA_CODEC_ID_A_ACM "A_MS/ACM" #define MATROSKA_CODEC_ID_A_AAC "A_AAC" #define MATROSKA_CODEC_ID_A_REAL_14_4 "A_REAL/14_4" #define MATROSKA_CODEC_ID_A_REAL_28_8 "A_REAL/28_8" #define MATROSKA_CODEC_ID_A_REAL_COOK "A_REAL/COOK" #define MATROSKA_CODEC_ID_A_REAL_SIPR "A_REAL/SIPR" #define MATROSKA_CODEC_ID_A_REAL_RALF "A_REAL/RALF" #define MATROSKA_CODEC_ID_A_REAL_ATRC "A_REAL/ATRC" #define MATROSKA_CODEC_ID_A_FLAC "A_FLAC" #define MATROSKA_CODEC_ID_A_OPUS "A_OPUS" #define MATROSKA_CODEC_ID_A_TRUEHD "A_TRUEHD" #define MATROSKA_CODEC_ID_S_TEXT_UTF8 "S_TEXT/UTF8" #define MATROSKA_CODEC_ID_S_TEXT_SSA "S_TEXT/SSA" #define MATROSKA_CODEC_ID_S_TEXT_ASS "S_TEXT/ASS" #define MATROSKA_CODEC_ID_S_TEXT_USF "S_TEXT/USF" #define MATROSKA_CODEC_ID_S_UTF8 "S_UTF8" /* deprecated */ #define MATROSKA_CODEC_ID_S_SSA "S_SSA" /* deprecated */ #define MATROSKA_CODEC_ID_S_ASS "S_ASS" /* deprecated */ #define MATROSKA_CODEC_ID_S_DVBSUB "S_DVBSUB" #define MATROSKA_CODEC_ID_S_VOBSUB "S_VOBSUB" #define MATROSKA_CODEC_ID_S_HDMV_PGS "S_HDMV/PGS" #define MATROSKA_CODEC_ID_S_HDMV_TEXTST "S_HDMV/TEXTST" /* block lacing */ #define MATROSKA_NO_LACING 0x0 #define MATROSKA_XIPH_LACING 0x1 #define MATROSKA_FIXED_SIZE_LACING 0x2 #define MATROSKA_EBML_LACING 0x3 /* track types */ #define MATROSKA_TRACK_VIDEO 0x01 #define MATROSKA_TRACK_AUDIO 0x02 #define MATROSKA_TRACK_COMPLEX 0x03 #define MATROSKA_TRACK_LOGO 0x10 #define MATROSKA_TRACK_SUBTITLE 0x11 #define MATROSKA_TRACK_CONTROL 0x20 /* compression algorithms */ #define MATROSKA_COMPRESS_ZLIB 0x00 #define MATROSKA_COMPRESS_BZLIB 0x01 #define MATROSKA_COMPRESS_LZO1X 0x02 #define MATROSKA_COMPRESS_HEADER_STRIP 0x03 #define MATROSKA_COMPRESS_UNKNOWN 0xFFFFFFFE /* Xine internal type */ #define MATROSKA_COMPRESS_NONE 0xFFFFFFFF /* Xine internal type */ #endif /* MATROSKA_H */ xine-lib-1.2/src/demuxers/group_video.c0000644000175000017500000000630514647725152016001 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * This file contains plugin entries for several av demuxers. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "group_video.h" /* * exported plugin catalog entries */ static const demuxer_info_t demux_info_plus__0 = { .priority = 0 }; static const demuxer_info_t demux_info_plus__1 = { .priority = 1 }; static const demuxer_info_t demux_info_plus__9 = { .priority = 9 }; static const demuxer_info_t demux_info_plus_10 = { .priority = 10 }; /* probe mpeg-ts first, and detect TV recordings cut at an unhappy byte pos. */ static const demuxer_info_t demux_info_plus_12 = { .priority = 12 }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "avi", XINE_VERSION_CODE, &demux_info_plus_10, demux_avi_init_class }, { PLUGIN_DEMUX, 27, "elem", XINE_VERSION_CODE, &demux_info_plus__0, demux_elem_init_class }, { PLUGIN_DEMUX, 27, "flashvideo", XINE_VERSION_CODE, &demux_info_plus_10, demux_flv_init_class }, { PLUGIN_DEMUX, 27, "iff", XINE_VERSION_CODE, &demux_info_plus_10, demux_iff_init_class }, { PLUGIN_DEMUX, 27, "ivf", XINE_VERSION_CODE, &demux_info_plus__1, demux_ivf_init_class }, { PLUGIN_DEMUX, 27, "matroska", XINE_VERSION_CODE, &demux_info_plus_10, demux_matroska_init_class }, { PLUGIN_DEMUX, 27, "mpeg", XINE_VERSION_CODE, &demux_info_plus__9, demux_mpeg_init_class }, { PLUGIN_DEMUX, 27, "mpeg_block", XINE_VERSION_CODE, &demux_info_plus_10, demux_mpeg_block_init_class }, { PLUGIN_DEMUX, 27, "mpeg-ts", XINE_VERSION_CODE, &demux_info_plus_12, demux_ts_init_class }, { PLUGIN_DEMUX, 27, "mpeg_pes", XINE_VERSION_CODE, &demux_info_plus_10, demux_pes_init_class }, { PLUGIN_DEMUX, 27, "quicktime", XINE_VERSION_CODE, &demux_info_plus_10, demux_qt_init_class }, { PLUGIN_DEMUX, 27, "rawdv", XINE_VERSION_CODE, &demux_info_plus__1, demux_rawdv_init_class }, { PLUGIN_DEMUX, 27, "real", XINE_VERSION_CODE, &demux_info_plus_10, demux_real_init_class }, { PLUGIN_DEMUX, 27, "vc1es", XINE_VERSION_CODE, &demux_info_plus__0, demux_vc1es_init_class }, { PLUGIN_DEMUX, 27, "yuv_frames", XINE_VERSION_CODE, &demux_info_plus__0, demux_yuv_frames_init_class }, { PLUGIN_DEMUX, 27, "yuv4mpeg2", XINE_VERSION_CODE, &demux_info_plus_10, demux_yuv4mpeg2_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/iff.h0000644000175000017500000004522314647725152014232 0ustar meme/* * Copyright (C) 2004-2008 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * IFF header file by Manfred Tremmel (Manfred.Tremmel@iiv.de) * Based on the information of the Amiga Developer CD */ #ifndef IFFP_IFF_H #define IFFP_IFF_H #define IFF_OKAY 0L #define IFF_CLIENT_ERROR 1L #define IFF_NOFILE 5L #define FOURCC_CHUNK BE_FOURCC #define IFF_16SV_CHUNK FOURCC_CHUNK('1', '6', 'S', 'V') #define IFF_8SVX_CHUNK FOURCC_CHUNK('8', 'S', 'V', 'X') #define IFF_ANFI_CHUNK FOURCC_CHUNK('A', 'N', 'F', 'I') #define IFF_ANHD_CHUNK FOURCC_CHUNK('A', 'N', 'H', 'D') #define IFF_ANIM_CHUNK FOURCC_CHUNK('A', 'N', 'I', 'M') #define IFF_ANNO_CHUNK FOURCC_CHUNK('A', 'N', 'N', 'O') #define IFF_ANSQ_CHUNK FOURCC_CHUNK('A', 'N', 'S', 'Q') #define IFF_ATAK_CHUNK FOURCC_CHUNK('A', 'T', 'A', 'K') #define IFF_AUTH_CHUNK FOURCC_CHUNK('A', 'U', 'T', 'H') #define IFF_BMHD_CHUNK FOURCC_CHUNK('B', 'M', 'H', 'D') #define IFF_BODY_CHUNK FOURCC_CHUNK('B', 'O', 'D', 'Y') #define IFF_CAMG_CHUNK FOURCC_CHUNK('C', 'A', 'M', 'G') #define IFF_CCRT_CHUNK FOURCC_CHUNK('C', 'C', 'R', 'T') #define IFF_CHAN_CHUNK FOURCC_CHUNK('C', 'H', 'A', 'N') #define IFF_CMAP_CHUNK FOURCC_CHUNK('C', 'M', 'A', 'P') #define IFF_COPY_CHUNK FOURCC_CHUNK('(', 'c', ')', ' ') #define IFF_CRNG_CHUNK FOURCC_CHUNK('C', 'R', 'N', 'G') #define IFF_DEST_CHUNK FOURCC_CHUNK('D', 'E', 'S', 'T') #define IFF_DLTA_CHUNK FOURCC_CHUNK('D', 'L', 'T', 'A') #define IFF_DPAN_CHUNK FOURCC_CHUNK('D', 'P', 'A', 'N') #define IFF_DPI_CHUNK FOURCC_CHUNK('D', 'P', 'I', ' ') #define IFF_DPPS_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'S') #define IFF_DPPV_CHUNK FOURCC_CHUNK('D', 'P', 'P', 'V') #define IFF_DRNG_CHUNK FOURCC_CHUNK('D', 'R', 'N', 'G') #define IFF_FACE_CHUNK FOURCC_CHUNK('F', 'A', 'C', 'E') #define IFF_FADE_CHUNK FOURCC_CHUNK('F', 'A', 'D', 'E') #define IFF_FORM_CHUNK FOURCC_CHUNK('F', 'O', 'R', 'M') #define IFF_FVER_CHUNK FOURCC_CHUNK('F', 'V', 'E', 'R') #define IFF_GRAB_CHUNK FOURCC_CHUNK('G', 'R', 'A', 'B') #define IFF_ILBM_CHUNK FOURCC_CHUNK('I', 'L', 'B', 'M') #define IFF_INS1_CHUNK FOURCC_CHUNK('I', 'N', 'S', '1') #define IFF_IMRT_CHUNK FOURCC_CHUNK('I', 'M', 'R', 'T') #define IFF_JUNK_CHUNK FOURCC_CHUNK('J', 'U', 'N', 'K') #define IFF_LIST_CHUNK FOURCC_CHUNK('L', 'I', 'S', 'T') #define IFF_MHDR_CHUNK FOURCC_CHUNK('M', 'H', 'D', 'R') #define IFF_NAME_CHUNK FOURCC_CHUNK('N', 'A', 'M', 'E') #define IFF_PAN_CHUNK FOURCC_CHUNK('P', 'A', 'N', ' ') #define IFF_PROP_CHUNK FOURCC_CHUNK('P', 'R', 'O', 'P') #define IFF_RLSE_CHUNK FOURCC_CHUNK('R', 'L', 'S', 'E') #define IFF_SAMP_CHUNK FOURCC_CHUNK('S', 'A', 'M', 'P') #define IFF_SEQN_CHUNK FOURCC_CHUNK('S', 'E', 'Q', 'N') #define IFF_SHDR_CHUNK FOURCC_CHUNK('S', 'H', 'D', 'R') #define IFF_SMUS_CHUNK FOURCC_CHUNK('S', 'M', 'U', 'S') #define IFF_SPRT_CHUNK FOURCC_CHUNK('S', 'P', 'R', 'T') #define IFF_TEXT_CHUNK FOURCC_CHUNK('T', 'E', 'X', 'T') #define IFF_TINY_CHUNK FOURCC_CHUNK('T', 'I', 'N', 'Y') #define IFF_TRAK_CHUNK FOURCC_CHUNK('T', 'R', 'A', 'K') #define IFF_VHDR_CHUNK FOURCC_CHUNK('V', 'H', 'D', 'R') /* IFF-ILBM Definitions */ /* Use this constant instead of sizeof(ColorRegister). */ #define PIC_SIZE_OF_COLOR_REGISTER 3 /* Maximum number of bitplanes storable in BitMap structure */ #define PIC_MAXAMDEPTH 8 /* Maximum planes we can save */ #define PIC_MAXSAVEDEPTH 24 /* Masking techniques */ #define PIC_MASK_NONE 0 #define PIC_MASK_HASMASK 1 #define PIC_MASK_HASTRANSPARENTMASK 2 #define PIC_MASK_LASSO 3 /* Compression techniques */ #define PIC_COMPRESSION_NONE 0 #define PIC_COMPRESSION_BYTERUN1 1 #define VIDEOBUFSIZE 128*1024 #define CAMG_LACE 0x0004 /* Interlaced Modi */ #define CAMG_EHB 0x0080 /* extra halfe brite */ #define CAMG_HAM 0x0800 /* hold and modify */ #define CAMG_HIRES 0x8000 /* Hires Modi */ #define CAMG_PAL 0x00021000 /* Hires Modi */ #define CAMG_NTSC 0x00011000 /* Hires Modi */ #define HAMBITS_CMAP 0 /* take color from colormap */ #define HAMBITS_BLUE 1 /* modify blue component */ #define HAMBITS_RED 2 /* modify red component */ #define HAMBITS_GREEN 3 /* modify green component */ static const int bitplainoffeset[] = { 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128 }; /* ---------- BitMapHeader ---------------------------------------------*/ /* Required Bitmap header (BMHD) structure describes an ILBM */ typedef struct { uint16_t w; /* raster width in pixels */ uint16_t h; /* raster height in pixels */ int16_t x; /* raster width in pixels */ int16_t y; /* raster height in pixels */ uint8_t nplanes; /* # source bitplanes */ uint8_t masking; /* masking technique */ uint8_t compression; /* compression algoithm */ uint8_t pad1; /* UNUSED. For consistency, put 0 here. */ uint16_t transparentColor; /* transparent "colour number" */ uint8_t xaspect; /* aspect ratio, a rational number x/y */ uint8_t yaspect; /* aspect ratio, a rational number x/y */ int16_t pagewidth; /* source "page" size in pixels */ int16_t pageheight; /* source "page" size in pixels */ } BitMapHeader; /* ---------- ColorRegister --------------------------------------------*/ /* A CMAP chunk is a packed array of ColorRegisters (3 bytes each). */ typedef struct { uint8_t cmap_red; /* red color component */ uint8_t cmap_green; /* green color component */ uint8_t cmap_blue; /* blue color component */ } ColorRegister; /* ---------- Point2D --------------------------------------------------*/ /* A Point2D is stored in a GRAB chunk. */ typedef struct { int16_t x; /* coordinates x pixels */ int16_t y; /* coordinates y pixels */ } Point2D; /* ---------- DestMerge ------------------------------------------------*/ /* A DestMerge is stored in a DEST chunk. */ typedef struct { uint8_t depth; /* # bitplanes in the original source */ uint8_t pad1; /* UNUSED; for consistency store 0 here */ uint16_t plane_pick; /* how to scatter source bitplanes into destination */ uint16_t plane_onoff; /* default bitplane data for planePick */ uint16_t plane_mask; /* selects which bitplanes to store into */ } DestMerge; /* ---------- SpritePrecedence -----------------------------------------*/ /* A SpritePrecedence is stored in a SPRT chunk. */ typedef uint16_t SpritePrecedence; /* ---------- Camg Amiga Viewport Mode Display ID ----------------------*/ /* The CAMG chunk is used to store the Amiga display mode in which * an ILBM is meant to be displayed. This is very important, especially * for special display modes such as HAM and HALFBRITE where the * pixels are interpreted differently. * Under V37 and higher, store a 32-bit Amiga DisplayID (aka. ModeID) * in the ULONG ViewModes CAMG variable (from GetVPModeID(viewport)). * Pre-V37, instead store the 16-bit viewport->Modes. * See the current IFF manual for information on screening for bad CAMG * chunks when interpreting a CAMG as a 32-bit DisplayID or 16-bit ViewMode. * The chunk's content is declared as a ULONG. */ typedef struct { uint32_t view_modes; } CamgChunk; /* ---------- CRange cycling chunk -------------------------------------*/ #define RNG_NORATE 36 /* Dpaint uses this rate to mean non-active */ /* A CRange is store in a CRNG chunk. */ typedef struct { int16_t pad1; /* reserved for future use; store 0 here */ int16_t rate; /* 60/sec=16384, 30/sec=8192, 1/sec=16384/60=273 */ int16_t active; /* bit0 set = active, bit 1 set = reverse */ uint8_t low; /* lower color registers selected */ uint8_t high; /* upper color registers selected */ } CRange; /* ---------- Ccrt (Graphicraft) cycling chunk -------------------------*/ /* A Ccrt is stored in a CCRT chunk. */ typedef struct { int16_t direction; /* 0=don't cycle, 1=forward, -1=backwards */ uint8_t start; /* range lower */ uint8_t end; /* range upper */ int32_t seconds; /* seconds between cycling */ int32_t microseconds; /* msecs between cycling */ int16_t pad; /* future exp - store 0 here */ } CcrtChunk; /* ---------- DPIHeader chunk ------------------------------------------*/ /* A DPIHeader is stored in a DPI chunk. */ typedef struct { int16_t x; int16_t y; } DPIHeader; /* IFF-8SVX/16SV Definitions */ #define MONO 0L #define PAN 1L #define LEFT 2L #define RIGHT 4L #define STEREO 6L #define SND_COMPRESSION_NONE 0 #define SND_COMPRESSION_FIBONACCI 1 #define SND_COMPRESSION_EXPONENTIAL 2 #define PREAMBLE_SIZE 8 #define IFF_JUNK_SIZE 8 #define IFF_SIGNATURE_SIZE 12 #define PCM_BLOCK_ALIGN 1024 #define max_volume 65536 /* Unity = Fixed 1.0 = maximum volume */ static const int8_t fibonacci[] = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 }; static const int8_t exponential[] = { -128, -64, -32, -16, -8, -4, -2, -1, 0, 1, 2, 4, 8, 16, 32, 64 }; typedef struct { uint32_t oneShotHiSamples; /* # samples in the high octave 1-shot part */ uint32_t repeatHiSamples; /* # samples in the high octave repeat part */ uint32_t samplesPerHiCycle; /* # samples/cycle in high octave, else 0 */ uint16_t samplesPerSec; /* data sampling rate */ uint8_t ctOctave; /* # of octaves of waveforms */ uint8_t sCompression; /* data compression technique used */ uint32_t volume; /* playback nominal volume from 0 to Unity * (full volume). Map this value into * the output hardware's dynamic range. */ } Voice8Header; typedef struct { uint16_t duration; /* segment duration in milliseconds */ uint32_t dest; /* destination volume factor */ } EGPoint; /* IFF-ANIM Definitions */ #define IFF_ANHD_ILBM 0 #define IFF_ANHD_XOR 1 #define IFF_ANHD_LDELTA 2 #define IFF_ANHD_SDELTA 3 #define IFF_ANHD_SLDELTA 4 #define IFF_ANHD_BVDELTA 5 #define IFF_ANHD_STEREOO5 6 #define IFF_ANHD_OPT7 7 #define IFF_ANHD_OPT8 8 #define IFF_ANHD_ASCIIJ 74 /* ---------- AnimHeader ----------------------------------------------*/ /* Required Anim Header (anhd) structure describes an ANIM-Frame */ typedef struct { uint8_t operation; /* The compression method: * 0 set directly (normal ILBM BODY), * 1 XOR ILBM mode, * 2 Long Delta mode, * 3 Short Delta mode, * 4 Generalized short/long Delta mode, * 5 Byte Vertical Delta mode * 6 Stereo op 5 (third party) * 74 (ascii 'J') reserved for Eric Graham's * compression technique */ uint8_t mask; /* (XOR mode only - plane mask where each * bit is set =1 if there is data and =0 * if not.) */ uint16_t w; /* (XOR mode only - width and height of the */ uint16_t h; /* area represented by the BODY to eliminate */ /* unnecessary un-changed data) */ int16_t x; /* (XOR mode only - position of rectangular */ int16_t y; /* area representd by the BODY) */ uint32_t abs_time; /* (currently unused - timing for a frame */ /* relative to the time the first frame */ /* was displayed - in jiffies (1/60 sec)) */ uint32_t rel_time; /* (timing for frame relative to time */ /* previous frame was displayed - in */ /* jiffies (1/60 sec)) */ uint8_t interleave; /* (unused so far - indicates how may frames */ /* back this data is to modify. =0 defaults */ /* to indicate two frames back (for double */ /* buffering). =n indicates n frames back. */ /* The main intent here is to allow values */ /* of =1 for special applications where */ /* frame data would modify the immediately */ /* previous frame) */ uint8_t pad0; /* Pad byte, not used at present. */ uint32_t bits; /* 32 option bits used by options=4 and 5. */ /* At present only 6 are identified, but the */ /* rest are set =0 so they can be used to */ /* implement future ideas. These are defined*/ /* for option 4 only at this point. It is */ /* recommended that all bits be set =0 for */ /* option 5 and that any bit settings */ /* used in the future (such as for XOR mode) */ /* be compatible with the option 4 */ /* bit settings. Player code should check */ /*undefined bits in options 4 and 5 to assure*/ /* they are zero. */ /* */ /* The six bits for current use are: */ /* */ /* bit # set =0 set =1 */ /* ========================================= */ /* 0 short data long data */ /* 1 set XOR */ /* 2 separate info one info list */ /* for each plane for all planes*/ /* 3 not RLC RLC(run length c.)*/ /* 4 horizontal vertical */ /* 5 short info offsets long info offs.*/ uint8_t pad[16]; /* This is a pad for future use for future */ /* compression modes. */ } AnimHeader; /* ---------- DPAnim-Chunk ----------------------------------------------*/ /* Deluxe Paint Anim (DPAN) Chunk */ typedef struct { uint16_t version; /* Version */ uint16_t nframes; /* number of frames in the animation.*/ uint8_t fps; /* frames per second */ uint8_t unused1; uint8_t unused2; uint8_t unused3; } DPAnimChunk; #endif /* IFFP_IFF_H */ xine-lib-1.2/src/demuxers/demux_asf.c0000644000175000017500000020414514647725152015434 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for asf streams * * based on ffmpeg's * ASF compatible encoder and decoder. * Copyright (c) 2000, 2001 Gerard Lantau. * * GUID list from avifile * some other ideas from MPlayer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifdef HAVE_ALLOCA_H #include #endif #define LOG_MODULE "demux_asf" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "bswap.h" #include "asfheader.h" #include #define CODEC_TYPE_AUDIO 0 #define CODEC_TYPE_VIDEO 1 #define CODEC_TYPE_CONTROL 2 #define MAX_NUM_STREAMS 23 #define DEFRAG_BUFSIZE 65536 #define WRAP_THRESHOLD 20*90000 #define MAX_FRAME_DUR 90000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 #define ASF_MODE_NORMAL 0 #define ASF_MODE_ASX_REF 1 #define ASF_MODE_HTTP_REF 2 #define ASF_MODE_ASF_REF 3 #define ASF_MODE_ENCRYPTED_CONTENT 4 #define ASF_MODE_NO_CONTENT 5 typedef struct { int seq; int frag_offset; int64_t timestamp; int ts_per_kbyte; int defrag; uint32_t buf_type; int stream_id; fifo_buffer_t *fifo; uint8_t *buffer; int skip; int resync; int first_seq; int payload_size; /* palette handling */ int palette_count; palette_entry_t palette[256]; } asf_demux_stream_t; typedef struct demux_asf_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int64_t keyframe_ts; int keyframe_found; int seqno; uint32_t packet_size; uint8_t packet_len_flags; uint32_t data_size; uint64_t packet_count; asf_demux_stream_t streams[MAX_NUM_STREAMS]; int video_stream; int audio_stream; int video_id; int audio_id; int64_t length; uint32_t rate; /* packet filling */ int packet_size_left; /* discontinuity detection */ int64_t last_pts[2]; int send_newpts; /* only for reading */ uint32_t packet_padsize; int nb_frames; uint8_t frame_flag; uint8_t packet_prop_flags; int frame; int status; /* byte reordering from audio streams */ uint8_t *reorder_temp; int reorder_h; int reorder_w; int reorder_b; int buf_flag_seek; /* first packet position */ int64_t first_packet_pos; int mode; /* for fewer error messages */ uint8_t last_unknown_guid[16]; uint8_t seen_streams[24]; asf_header_t *asf_header; } demux_asf_t ; typedef enum { ASF_OK = 0, ASF_EOF, ASF_SEEK_ERROR, ASF_EOS, ASF_NEW_STREAM, ASF_INVALID_DATA_LENGTH, ASF_INVALID_FRAGMENT_LENGTH, ASF_INVALID_RLEN, ASF_INVALID_PAD_SIZE, ASF_UNFINISHED_PACKET } asf_error_t; static const char *error_strings[] = { "success", "unexpected end of input", "seek error", "end of stream", "unexpected new stream", "invalid data length", "invalid fragment length", "invalid rlen", "invalid pad size", "unfinished packet" }; static asf_guid_t get_guid_id (demux_asf_t *this, const uint8_t *guid) { uint8_t b[40]; asf_guid_t i = asf_guid_2_num (guid); if (i != GUID_ERROR) return i; if (!memcmp (guid, &this->last_unknown_guid, 16)) return GUID_ERROR; memcpy (&this->last_unknown_guid, guid, 16); asf_guid_2_str (b, guid); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: unknown GUID: %s\n", b); return GUID_ERROR; } static asf_guid_t get_guid (demux_asf_t *this) { uint8_t buf[16]; if (this->input->read (this->input, buf, 16) != 16) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: end of data\n"); this->status = DEMUX_FINISHED; return GUID_ERROR; } return get_guid_id (this, buf); } #if 0 static void get_str16_nolen(demux_asf_t *this, int len, char *buf, int buf_size) { int c; char *q; q = buf; while (len > 0) { c = get_le16(this); if ((q - buf) < buf_size - 1) *q++ = c; len-=2; } *q = '\0'; } #endif static void asf_send_audio_header (demux_asf_t *this, int stream) { buf_element_t *buf; asf_stream_t *asf_stream = this->asf_header->streams[stream]; xine_waveformatex *wavex = (xine_waveformatex *)asf_stream->private_data; if (!this->audio_fifo) return; buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); if ((int)(asf_stream->private_data_length) > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_asf: private decoder data length (%d) is greater than fifo buffer length (%d)\n", asf_stream->private_data_length, buf->max_size); buf->free_buffer(buf); this->status = DEMUX_FINISHED; return; } memcpy (buf->content, wavex, asf_stream->private_data_length); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, wavex->wFormatTag); lprintf ("wavex header is %d bytes long\n", asf_stream->private_data_length); buf->size = asf_stream->private_data_length; buf->type = this->streams[stream].buf_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[1] = wavex->nSamplesPerSec; buf->decoder_info[2] = wavex->wBitsPerSample; buf->decoder_info[3] = wavex->nChannels; this->audio_fifo->put (this->audio_fifo, buf); } #if 0 static unsigned long str2ulong(unsigned char *str) { return ( str[0] | (str[1]<<8) | (str[2]<<16) | (str[3]<<24) ); } #endif static void asf_send_video_header (demux_asf_t *this, int stream) { buf_element_t *buf; asf_demux_stream_t *demux_stream = &this->streams[stream]; asf_stream_t *asf_stream = this->asf_header->streams[stream]; xine_bmiheader *bih = (xine_bmiheader *)(asf_stream->private_data + 11); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, bih->biCompression); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); if (((int)(asf_stream->private_data_length) - 11) > buf->max_size) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_asf: private decoder data length (%d) is greater than fifo buffer length (%d)\n", asf_stream->private_data_length-10, buf->max_size); buf->free_buffer(buf); this->status = DEMUX_FINISHED; return; } buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; if (this->asf_header->aspect_ratios[stream].x && this->asf_header->aspect_ratios[stream].y) { buf->decoder_flags |= BUF_FLAG_ASPECT; buf->decoder_info[1] = bih->biWidth * this->asf_header->aspect_ratios[stream].x; buf->decoder_info[2] = bih->biHeight * this->asf_header->aspect_ratios[stream].y; } buf->size = asf_stream->private_data_length - 11; memcpy (buf->content, bih, buf->size); buf->type = this->streams[stream].buf_type; this->video_fifo->put (this->video_fifo, buf); /* send off the palette, if there is one */ if (demux_stream->palette_count) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_asf: stream %d, palette : %d entries\n", stream, demux_stream->palette_count); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = demux_stream->palette_count; buf->decoder_info_ptr[2] = &demux_stream->palette; buf->size = 0; buf->type = this->streams[stream].buf_type; this->video_fifo->put (this->video_fifo, buf); } } static int asf_read_header (demux_asf_t *this) { int i; { uint64_t asf_header_len; uint8_t *asf_header_buffer = NULL; uint8_t buf[8]; if (this->input->read (this->input, buf, 8) != 8) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: end of data\n"); this->status = DEMUX_FINISHED; return 0; } asf_header_len = _X_LE_64 (buf); if (asf_header_len > (4 << 20)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_read_header: overly-large header? (%"PRIu64" bytes)\n", asf_header_len); return 0; } asf_header_buffer = malloc (asf_header_len); if (!asf_header_buffer) return 0; if (this->input->read (this->input, asf_header_buffer, asf_header_len) != (int)asf_header_len) { free (asf_header_buffer); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: end of data\n"); this->status = DEMUX_FINISHED; return 0; } /* delete previous header */ if (this->asf_header) asf_header_delete (this->asf_header); /* the header starts with : * byte 0-15: header guid * byte 16-23: header length */ this->asf_header = asf_header_new (asf_header_buffer, asf_header_len); free (asf_header_buffer); if (!this->asf_header) return 0; } lprintf("asf header parsing ok\n"); this->packet_size = this->asf_header->file->packet_size; this->packet_count = this->asf_header->file->data_packet_count; /* compute stream duration */ this->length = (this->asf_header->file->send_duration - this->asf_header->file->preroll) / 10000; if (this->length < 0) this->length = 0; /* compute average byterate (needed for seeking) */ if (this->asf_header->file->max_bitrate) this->rate = this->asf_header->file->max_bitrate >> 3; else if (this->length) this->rate = (int64_t) this->input->get_length(this->input) * 1000 / this->length; _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->asf_header->file->max_bitrate); for (i = 0; i < this->asf_header->stream_count; i++) { asf_stream_t *asf_stream = this->asf_header->streams[i]; asf_demux_stream_t *demux_stream = &this->streams[i]; if (!asf_stream) { if (this->mode != ASF_MODE_NO_CONTENT) { xine_log(this->stream->xine, XINE_LOG_MSG, _("demux_asf: warning: A stream appears to be missing.\n")); _x_message(this->stream, XINE_MSG_READ_ERROR, _("Media stream missing?"), NULL); this->mode = ASF_MODE_NO_CONTENT; } return 0; } if (asf_stream->encrypted_flag) { if (this->mode != ASF_MODE_ENCRYPTED_CONTENT) { xine_log(this->stream->xine, XINE_LOG_MSG, _("demux_asf: warning: The stream id=%d is encrypted.\n"), asf_stream->stream_number); _x_message(this->stream, XINE_MSG_ENCRYPTED_SOURCE, _("Media stream scrambled/encrypted"), NULL); this->mode = ASF_MODE_ENCRYPTED_CONTENT; } } switch (asf_stream->stream_type) { case GUID_ASF_AUDIO_MEDIA: { xine_waveformatex *fx = (xine_waveformatex *)asf_stream->private_data; if (!fx || (asf_stream->private_data_length < sizeof (*fx))) break; _x_waveformatex_le2me (fx); demux_stream->buf_type = _x_formattag_to_buf_audio (fx->wFormatTag); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: audio stream #%d: [0x%0x] %dbps %dch %dHz %dbit\n", (int)asf_stream->stream_number, (unsigned int)fx->wFormatTag, (int)this->asf_header->bitrates[i], (int)fx->nChannels, (int)fx->nSamplesPerSec, (int)fx->wBitsPerSample); if (!demux_stream->buf_type) { demux_stream->buf_type = BUF_AUDIO_UNKNOWN; _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, fx->wFormatTag); } if ((asf_stream->error_correction_type == GUID_ASF_AUDIO_SPREAD) && asf_stream->error_correction_data && (asf_stream->error_correction_data_length >= 5)) { this->reorder_h = asf_stream->error_correction_data[0]; this->reorder_w = _X_LE_16 (asf_stream->error_correction_data + 1); this->reorder_b = _X_LE_16 (asf_stream->error_correction_data + 3); if (!this->reorder_b) this->reorder_b = 1; this->reorder_w /= this->reorder_b; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: audio conceal interleave detected (%d x %d x %d)\n", this->reorder_w, this->reorder_h, this->reorder_b); } else { this->reorder_b = this->reorder_h = this->reorder_w = 1; } _x_meta_info_set(this->stream, XINE_META_INFO_AUDIOCODEC, _x_buf_audio_name(demux_stream->buf_type)); this->streams[i].fifo = this->audio_fifo; this->streams[i].frag_offset = 0; this->streams[i].seq = 0; if (this->reorder_h > 1 && this->reorder_w > 1 ) { if( !this->streams[i].buffer ) this->streams[i].buffer = malloc( DEFRAG_BUFSIZE ); this->streams[i].defrag = 1; } else this->streams[i].defrag = 0; } break; case GUID_ASF_VIDEO_MEDIA: { /* video private data * 11 bytes : header * 40 bytes : bmiheader * XX bytes : optional palette */ uint32_t width, height; /*uint16_t bmiheader_size;*/ xine_bmiheader *bmiheader; if (!asf_stream->private_data || (asf_stream->private_data_length < 11 + sizeof (*bmiheader))) break; width = _X_LE_32(asf_stream->private_data); height = _X_LE_32(asf_stream->private_data + 4); /* there is one unknown byte between height and the bmiheader size */ /*bmiheader_size = _X_LE_16(asf_stream->private_data + 9);*/ /* FIXME: bmiheader_size must be >= sizeof(xine_bmiheader) */ bmiheader = (xine_bmiheader *) (asf_stream->private_data + 11); _x_bmiheader_le2me(bmiheader); /* FIXME: check if (bmi_header_size == bmiheader->biSize) ? */ demux_stream->buf_type = _x_fourcc_to_buf_video(bmiheader->biCompression); { uint8_t sf[20]; _x_tag32_me2str (sf, bmiheader->biCompression); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: video stream #%d: [%s] %dbps %d x %d\n", (int)asf_stream->stream_number, sf, (int)this->asf_header->bitrates[i], (int)width, (int)height); } if( !demux_stream->buf_type ) { demux_stream->buf_type = BUF_VIDEO_UNKNOWN; _x_report_video_fourcc (this->stream->xine, LOG_MODULE, bmiheader->biCompression); } _x_meta_info_set(this->stream, XINE_META_INFO_VIDEOCODEC, _x_buf_video_name(demux_stream->buf_type)); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); this->streams[i].fifo = this->video_fifo; this->streams[i].frag_offset = 0; this->streams[i].defrag = 0; /* load the palette, if there is one */ demux_stream->palette_count = bmiheader->biClrUsed; lprintf ("palette_count: %d\n", demux_stream->palette_count); if (demux_stream->palette_count > 256) { lprintf ("number of colours exceeded 256 (%d)", demux_stream->palette_count); demux_stream->palette_count = 256; } if (((int)(asf_stream->private_data_length) - (int)sizeof (xine_bmiheader) - 11) >= (demux_stream->palette_count * 4)) { int j; uint8_t *palette; /* according to msdn the palette is located here : */ palette = (uint8_t *)bmiheader + bmiheader->biSize; /* load the palette */ for (j = 0; j < demux_stream->palette_count; j++) { demux_stream->palette[j].b = *(palette + j * 4 + 0); demux_stream->palette[j].g = *(palette + j * 4 + 1); demux_stream->palette[j].r = *(palette + j * 4 + 2); } } else { int j; /* generate a greyscale palette */ demux_stream->palette_count = 256; for (j = 0; j < demux_stream->palette_count; j++) { demux_stream->palette[j].r = j; demux_stream->palette[j].g = j; demux_stream->palette[j].b = j; } } } break; default: ; } } { uint8_t b1[16 + 10]; uint8_t b2[40]; unsigned int n; if (this->input->read (this->input, b1, 16 + 10) != 16 + 10) { asf_header_delete (this->asf_header); this->asf_header = NULL; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_asf: no data chunk.\n"); return 0; } this->first_packet_pos = this->input->get_current_pos (this->input); asf_guid_2_str (b2, b1); n = _X_LE_32 (b1 + 16); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: data chunk %s @%" PRId64 ", %u packets of %u bytes each.\n", b2, (int64_t)this->first_packet_pos - 16 - 10, n, this->packet_size); if ((memcmp (b1, this->asf_header->file->file_id, 16)) || (n != (unsigned int)this->packet_count)) { asf_guid_2_str (b2, this->asf_header->file->file_id); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: warning: announced was %s, %u packets.\n", b2, (unsigned int)this->packet_count); } } this->packet_size_left = 0; return 1; } static int demux_asf_send_headers_common (demux_asf_t *this) { /* will get overridden later */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); /* * initialize asf engine */ this->audio_stream = -1; this->video_stream = -1; this->packet_size = 0; this->seqno = 0; if (!asf_read_header (this)) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_read_header failed.\n"); this->status = DEMUX_FINISHED; return 1; } else { /* * send start buffer */ _x_demux_control_start(this->stream); if (this->asf_header->content) { _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->asf_header->content->title); _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->asf_header->content->author); _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, this->asf_header->content->description); } /* Choose the best audio and the best video stream. * Use the bitrate to do the choice. */ asf_header_choose_streams(this->asf_header, -1, &this->video_stream, &this->audio_stream); this->audio_id = this->audio_stream == -1 ? -1 : this->asf_header->streams[this->audio_stream]->stream_number; this->video_id = this->video_stream == -1 ? -1 : this->asf_header->streams[this->video_stream]->stream_number; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: video stream_id: %d, audio stream_id: %d\n", this->video_id, this->audio_id); if (this->audio_stream != -1) { asf_stream_t *s = this->asf_header->streams[this->audio_stream]; if ((s->error_correction_type == GUID_ASF_AUDIO_SPREAD) && s->error_correction_data && (s->error_correction_data_length >= 5)) { this->reorder_h = s->error_correction_data[0]; this->reorder_w = _X_LE_16 (s->error_correction_data + 1); this->reorder_b = _X_LE_16 (s->error_correction_data + 3); if (!this->reorder_b) this->reorder_b = 1; this->reorder_w /= this->reorder_b; } else { this->reorder_b = this->reorder_h = this->reorder_w = 1; } free (this->reorder_temp); this->reorder_temp = NULL; if ((this->reorder_w > 1) || (this->reorder_h > 1)) this->reorder_temp = malloc (this->reorder_w * this->reorder_h * this->reorder_b); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); asf_send_audio_header(this, this->audio_stream); } if (this->video_stream != -1) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); asf_send_video_header(this, this->video_stream); } } return 0; } static void asf_reorder (demux_asf_t *this, uint8_t *src, int len) { if (this->reorder_temp) { int bsize = this->reorder_h * this->reorder_w * this->reorder_b; uint8_t *s2 = src; int n = len / bsize, x, y; while (n--) { uint8_t *t = this->reorder_temp; for (x = 0; x < this->reorder_w; x++) { for (y = 0; y < this->reorder_h; y++) { memcpy (t, s2 + (y * this->reorder_w + x) * this->reorder_b, this->reorder_b); t += this->reorder_b; } } memcpy (s2, this->reorder_temp, bsize); s2 += bsize; } } } /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) static void check_newpts (demux_asf_t *this, int64_t pts, int video, int frame_end) { int64_t diff; (void)frame_end; /* FIXME: use */ diff = pts - this->last_pts[video]; #ifdef LOG if (pts) { if (video) { printf ("demux_asf: VIDEO: pts = %8"PRId64", diff = %8"PRId64"\n", pts, pts - this->last_pts[video]); } else { printf ("demux_asf: AUDIO: pts = %8"PRId64", diff = %8"PRId64"\n", pts, pts - this->last_pts[video]); } } #endif if (pts && (this->send_newpts || (this->last_pts[video] && abs(diff) > WRAP_THRESHOLD))) { lprintf ("sending newpts %"PRId64" (video = %d diff = %"PRId64")\n", pts, video, diff); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; this->last_pts[1 - video] = 0; } if (pts) this->last_pts[video] = pts; } static void asf_send_buffer_nodefrag (demux_asf_t *this, asf_demux_stream_t *stream, int frag_offset, int64_t timestamp, int frag_len) { int package_done; lprintf ("pts=%"PRId64", off=%d, len=%d, total=%d\n", timestamp * 90, frag_offset, frag_len, stream->payload_size); if (frag_offset == 0) { /* new packet */ stream->frag_offset = 0; lprintf("new packet\n"); } else { if (frag_offset == stream->frag_offset) { /* continuing packet */ lprintf("continuing packet: offset=%d\n", frag_offset); } else { /* cannot continue current packet: free it */ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_send_buffer_nodefrag: stream offset: %d, invalid offset: %d\n", stream->frag_offset, frag_offset); this->input->seek (this->input, frag_len, SEEK_CUR); return ; } } while (frag_len) { buf_element_t *buf; int bsize; buf = stream->fifo->buffer_pool_size_alloc (stream->fifo, frag_len); bsize = frag_len < buf->max_size ? frag_len : buf->max_size; if (this->input->read (this->input, buf->content, bsize) != bsize) { buf->free_buffer (buf); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: input buffer starved\n"); return ; } lprintf ("data: %d %d %d %d\n", buf->content[0], buf->content[1], buf->content[2], buf->content[3]); if (this->input->get_length (this->input) > 0) buf->extra_info->input_normpos = (int)((double)this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input)); buf->extra_info->input_time = timestamp; lprintf ("input normpos is %d, input time is %d, rate %d\n", buf->extra_info->input_normpos, buf->extra_info->input_time, this->rate); buf->pts = timestamp * 90; buf->type = stream->buf_type; buf->size = bsize; timestamp = 0; if (stream->frag_offset == 0) buf->decoder_flags |= BUF_FLAG_FRAME_START; stream->frag_offset += bsize; frag_len -= bsize; package_done = (stream->frag_offset >= stream->payload_size); if ((buf->type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE) check_newpts (this, buf->pts, PTS_VIDEO, package_done); else check_newpts (this, buf->pts, PTS_AUDIO, package_done); /* test if whole packet read */ if (package_done) { buf->decoder_flags |= BUF_FLAG_FRAME_END; lprintf("packet done: offset=%d, payload=%d\n", stream->frag_offset, stream->payload_size); } lprintf ("buffer type %08x %8d bytes, %8" PRId64 " pts\n", buf->type, buf->size, buf->pts); stream->fifo->put (stream->fifo, buf); } } static void asf_send_buffer_defrag (demux_asf_t *this, asf_demux_stream_t *stream, int frag_offset, int64_t timestamp, int frag_len) { int package_done; /* printf("asf_send_buffer seq=%d frag_offset=%d frag_len=%d\n", seq, frag_offset, frag_len ); */ lprintf ("asf_send_buffer_defrag: timestamp=%"PRId64", pts=%"PRId64"\n", timestamp, timestamp * 90); if (frag_offset == 0) { /* new packet */ lprintf("new packet\n"); stream->frag_offset = 0; stream->timestamp = timestamp; } else { if (frag_offset == stream->frag_offset) { /* continuing packet */ lprintf("continuing packet: offset=%d\n", frag_offset); } else { /* cannot continue current packet: free it */ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_send_buffer_defrag: invalid offset\n"); this->input->seek (this->input, frag_len, SEEK_CUR); return ; } } if( stream->frag_offset + frag_len > DEFRAG_BUFSIZE ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: buffer overflow on defrag!\n"); } else { if (this->input->read (this->input, &stream->buffer[stream->frag_offset], frag_len) != frag_len) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: input buffer starved\n"); return ; } stream->frag_offset += frag_len; } package_done = (stream->frag_offset >= stream->payload_size); if (package_done) { uint8_t *p; lprintf("packet done: offset=%d, payload=%d\n", stream->frag_offset, stream->payload_size); if (stream->fifo == this->audio_fifo && this->reorder_h > 1 && this->reorder_w > 1 ) { asf_reorder(this,stream->buffer,stream->frag_offset); } p = stream->buffer; while (stream->frag_offset) { buf_element_t *buf; int bsize; buf = stream->fifo->buffer_pool_size_alloc (stream->fifo, stream->frag_offset); bsize = stream->frag_offset < buf->max_size ? stream->frag_offset : buf->max_size; xine_fast_memcpy (buf->content, p, bsize); if (this->input->get_length (this->input) > 0) buf->extra_info->input_normpos = (int)((double)this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input)); buf->extra_info->input_time = stream->timestamp; /* send the same pts for the entire frame */ buf->pts = stream->timestamp * 90; buf->type = stream->buf_type; buf->size = bsize; lprintf ("buffer type %08x %8d bytes, %8" PRId64 " pts\n", buf->type, buf->size, buf->pts); stream->frag_offset -= bsize; p += bsize; if ((buf->type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE) check_newpts (this, buf->pts, PTS_VIDEO, !stream->frag_offset); else check_newpts (this, buf->pts, PTS_AUDIO, !stream->frag_offset); /* test if whole packet read */ if (!stream->frag_offset) buf->decoder_flags |= BUF_FLAG_FRAME_END; stream->fifo->put (stream->fifo, buf); } } } /* return 0 if ok */ static asf_error_t asf_parse_packet_align (demux_asf_t *this) { uint64_t current_pos, packet_pos; uint32_t mod; uint64_t packet_num; current_pos = this->input->get_current_pos (this->input); /* seek to the beginning of the next packet */ mod = (current_pos - this->first_packet_pos) % this->packet_size; this->packet_size_left = mod ? this->packet_size - mod : 0; packet_pos = current_pos + this->packet_size_left; if (this->packet_size_left) { lprintf("last packet is not finished, %d bytes\n", this->packet_size_left); current_pos = this->input->seek (this->input, packet_pos, SEEK_SET); if (current_pos != packet_pos) { return ASF_SEEK_ERROR; } } this->packet_size_left = 0; /* check packet_count */ packet_num = (packet_pos - this->first_packet_pos) / this->packet_size; lprintf("packet_num=%"PRId64", packet_count=%"PRId64"\n", packet_num, this->packet_count); if (packet_num >= this->packet_count) { /* end of payload data */ current_pos = this->input->get_current_pos (this->input); lprintf("end of payload data, current_pos=%"PRId64"\n", current_pos); { /* check new asf header */ if (get_guid(this) == GUID_ASF_HEADER) { lprintf("new asf header detected\n"); _x_demux_control_end(this->stream, 0); if (demux_asf_send_headers_common(this)) return ASF_NEW_STREAM; } else { lprintf("not an ASF stream or end of stream\n"); return ASF_EOS; } } } return ASF_OK; } /* return 0 if ok */ static asf_error_t asf_parse_packet_ecd (demux_asf_t *this, uint32_t *p_hdr_size) { while (1) { uint8_t buf[16]; /* ecd_flags: * bit 7: ecd_present * bit 6~5: ecd_len_type * bit 4: ecd_opaque * bit 3~0: ecd_len */ if (this->input->read (this->input, buf, 1) != 1) return ASF_EOF; *p_hdr_size = 1; if ((buf[0] & 0xf0) == 0x80) { /* skip ecd */ int size = buf[0] & 0x0f; if (this->input->read (this->input, buf + 1, size) != size) return ASF_EOF; *p_hdr_size += size; return ASF_OK; } else { /* check if it's a new stream */ if (this->input->read (this->input, buf + 1, 15) != 15) return ASF_EOF; *p_hdr_size += 15; if (get_guid_id (this, buf) == GUID_ASF_HEADER) { lprintf ("new asf header detected\n"); _x_demux_control_end (this->stream, 0); if (demux_asf_send_headers_common (this)) return ASF_NEW_STREAM; } else { /* skip invalid packet */ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: skip invalid packet: 0x%02x\n", (unsigned int)buf[0]); this->input->seek (this->input, this->packet_size - *p_hdr_size, SEEK_CUR); } } } } /* return 0 if ok */ static asf_error_t asf_parse_packet_payload_header (demux_asf_t *this, uint32_t p_hdr_size) { #ifdef LOG unsigned int timestamp; unsigned int duration; #endif static const uint8_t sn[128] = { 0,1, 1,2, 2,3, 4,5, 1,2, 2,3, 3,4, 5, 6, 2,3, 3,4, 4,5, 6, 7, 4,5, 5, 6, 6, 7, 8, 9, 1,2, 2,3, 3,4, 5,6, 2,3, 3,4, 4,5, 6, 7, 3,4, 4,5, 5,6, 7, 8, 5,6, 6, 7, 7, 8, 9,10, 2,3, 3,4, 4,5, 6,7, 3,4, 4,5, 5,6, 7, 8, 4,5, 5,6, 6,7, 8, 9, 6,7, 7, 8, 8, 9, 10,11, 4,5, 5,6, 6,7, 8,9, 5,6, 6,7, 7,8, 9,10, 6,7, 7,8, 8,9, 10,11, 8,9, 9,10, 10,11, 12,13 }; uint8_t b[24], *p = b; int need; if (this->input->read (this->input, b, 2) != 2) return ASF_EOF; this->packet_len_flags = b[0]; this->packet_prop_flags = b[1]; p += 2; /* static const int s[4] = {0, 1, 2, 4}; * need = s[(b[0] >> 5) & 3] + s[(b[0] >> 1) & 3] + s[(b[0] >> 3) & 3] + 6 + (b[0] & 1); */ need = sn[b[0] & 0x7f] + 6; if (this->input->read (this->input, p, need) != need) return ASF_EOF; /* packet size */ switch ((b[0] >> 5) & 3) { case 1: this->data_size = *p++; break; case 2: this->data_size = (uint16_t)_X_LE_16 (p); p += 2; break; case 3: this->data_size = (uint32_t)_X_LE_32 (p); p += 4; break; default: this->data_size = 0; } /* sequence */ switch ((b[0] >> 1) & 3) { case 1: p += 1; break; case 2: p += 2; break; case 3: p += 4; break; default: ; } /* padding size */ switch ((b[0] >> 3) & 3) { case 1: this->packet_padsize = *p++; break; case 2: this->packet_padsize = (uint16_t)_X_LE_16 (p); p += 2; break; case 3: this->packet_padsize = (uint32_t)_X_LE_32 (p); p += 4; break; default: this->packet_padsize = 0; } #ifdef LOG timestamp = _X_LE_32 (p); p += 4; duration = _X_LE_16 (p); p += 2; lprintf ("timestamp=%u, duration=%u\n", timestamp, duration); #else /* skip the above bytes */ p += 6; #endif if ((b[0] >> 5) & 3) { /* absolute data size */ lprintf ("absolute data size\n"); this->packet_padsize = this->packet_size - this->data_size; /* not used */ } else { /* relative data size */ lprintf ("relative data size\n"); this->data_size = this->packet_size - this->packet_padsize; } if (this->packet_padsize > this->packet_size) /* skip packet */ return ASF_INVALID_PAD_SIZE; /* Multiple frames */ if (b[0] & 0x01) { this->frame_flag = *p++; this->nb_frames = (this->frame_flag & 0x3F); lprintf ("multiple frames %d\n", this->nb_frames); } else { this->frame_flag = 0; this->nb_frames = 1; } p_hdr_size += p - b; /* this->packet_size_left = this->packet_size - p_hdr_size; */ this->packet_size_left = this->data_size - p_hdr_size; lprintf ("new packet, size = %d, size_left = %d, flags = 0x%02x, padsize = %d, this->packet_size = %d\n", this->data_size, this->packet_size_left, this->packet_len_flags, this->packet_padsize, this->packet_size); return ASF_OK; } /* return 0 if ok */ static asf_error_t asf_parse_packet_payload_common (demux_asf_t *this, uint8_t raw_id, asf_demux_stream_t **stream, uint32_t *frag_offset, uint32_t *rlen) { uint8_t stream_id; uint32_t seq = 0; uint32_t next_seq = 0; static const uint8_t sn[64] = { 0,1,2,4, 1,2,3,5, 2,3,4,6, 4,5,6, 8, 1,2,3,5, 2,3,4,6, 3,4,5, 7, 5,6, 7, 9, 2,3,4,6, 3,4,5,7, 4,5,6,8, 6,7,8,10, 4,5,6,8, 5,6,7,9, 6,7,8,10, 8,9,10,12 }; uint8_t b[20], *p = b; int need; need = sn[this->packet_prop_flags & 0x3f]; if (this->input->read (this->input, b, need) != need) return ASF_EOF; stream_id = raw_id & 0x7f; lprintf ("got raw_id=%d, stream_id=%d\n", raw_id, stream_id); { unsigned int i; for (i = 0; i < sizeof (this->seen_streams); i++) { if (stream_id == this->seen_streams[i]) break; if (255 == this->seen_streams[i]) { this->seen_streams[i] = stream_id; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: seen stream #%d.\n", stream_id); break; } } } *stream = NULL; if (stream_id == this->audio_id) *stream = &this->streams[this->audio_stream]; else if (stream_id == this->video_id) *stream = &this->streams[this->video_stream]; if (*stream) { switch ((this->packet_prop_flags >> 4) & 3) { case 1: seq = *p++; (*stream)->seq = (*stream)->seq & 0xff; next_seq = ((*stream)->seq + 1) & 0xff; break; case 2: seq = _X_LE_16 (p); p += 2; (*stream)->seq = (*stream)->seq & 0xffff; next_seq = ((*stream)->seq + 1) & 0xffff; break; case 3: seq = _X_LE_32 (p); p += 4; next_seq = (*stream)->seq + 1; break; default: lprintf ("seq=0\n"); seq = 0; } /* check seq number */ lprintf ("stream_id = %d, seq = %d\n", stream_id, seq); if ((*stream)->first_seq || (*stream)->skip) { next_seq = seq; (*stream)->first_seq = 0; } if ((seq != (uint32_t)((*stream)->seq)) && (seq != next_seq)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: bad seq: seq = %d, next_seq = %d, stream seq = %d!\n", seq, next_seq, (*stream)->seq); /* the stream is corrupted, reset the decoder and restart at a new keyframe */ if ((*stream)->fifo) { buf_element_t *buf = (*stream)->fifo->buffer_pool_alloc ((*stream)->fifo); buf->type = BUF_CONTROL_RESET_DECODER; (*stream)->fifo->put((*stream)->fifo, buf); } if (stream_id == this->video_id) { lprintf ("bad seq: waiting for keyframe\n"); (*stream)->resync = 1; (*stream)->skip = 1; this->keyframe_found = 0; } } (*stream)->seq = seq; } else { p += sn[(this->packet_prop_flags >> 4) & 3]; } switch ((this->packet_prop_flags >> 2) & 3) { case 1: *frag_offset = *p++; break; case 2: *frag_offset = _X_LE_16 (p); p += 2; break; case 3: *frag_offset = _X_LE_32 (p); p += 4; break; default: lprintf ("frag_offset=0\n"); *frag_offset = 0; } switch (this->packet_prop_flags & 3) { case 1: *rlen = *p++; break; case 2: *rlen = _X_LE_16 (p); p += 2; break; case 3: *rlen = _X_LE_32 (p); p += 4; break; default: *rlen = 0; } if (*rlen > (uint32_t)this->packet_size_left) /* skip packet */ return ASF_INVALID_RLEN; lprintf ("segment header, stream id %02x, frag_offset %d, flags : %02x\n", stream_id, *frag_offset, *rlen); this->packet_size_left -= p - b; return ASF_OK; } /* return 0 if ok */ static asf_error_t asf_parse_packet_compressed_payload (demux_asf_t *this, asf_demux_stream_t *stream, uint8_t raw_id, uint32_t frag_offset, int64_t *timestamp) { uint32_t s_hdr_size = 0; uint32_t data_length = 0; uint32_t data_sent = 0; *timestamp = frag_offset; if (*timestamp) *timestamp -= this->asf_header->file->preroll; frag_offset = 0; if (this->packet_len_flags & 0x01) { /* multiple frames */ static const int s[4] = {2, 1, 2, 4}; int need = 1 + s[(this->frame_flag >> 6) & 3]; uint8_t b[8]; if (this->input->read (this->input, b + 3, need) != need) return ASF_EOF; s_hdr_size += need; switch ((this->frame_flag >> 6) & 3) { case 1: data_length = b[4]; break; default: lprintf ("invalid frame_flag %d\n", this->frame_flag); /* fall through */ case 2: data_length = _X_LE_16 (b + 4); break; case 3: data_length = _X_LE_32 (b + 4); break; } lprintf ("reading multiple payload, size = %d\n", data_length); } else { uint8_t b[1]; if (this->input->read (this->input, b, 1) != 1) return ASF_EOF; s_hdr_size += 1; data_length = this->packet_size_left - s_hdr_size; lprintf ("reading single payload, size = %d\n", data_length); } if (data_length > (uint32_t)this->packet_size_left) /* skip packet */ return ASF_INVALID_DATA_LENGTH; this->packet_size_left -= s_hdr_size; while (data_sent < data_length) { int object_length; { uint8_t b[1]; if (this->input->read (this->input, b, 1) != 1) return ASF_EOF; object_length = b[0]; } lprintf ("sending grouped object, len = %d\n", object_length); if (stream && stream->fifo) { stream->payload_size = object_length; /* keyframe detection for non-seekable input plugins */ if (stream->skip && (raw_id & 0x80) && !this->keyframe_found) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: keyframe detected\n"); this->keyframe_ts = *timestamp; this->keyframe_found = 1; } if (stream->resync && (this->keyframe_found) && (*timestamp >= this->keyframe_ts)) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: stream resynced\n"); stream->resync = 0; stream->skip = 0; } if (!stream->skip) { lprintf ("sending buffer of type %08x\n", stream->buf_type); if (stream->defrag) asf_send_buffer_defrag (this, stream, 0, *timestamp, object_length); else asf_send_buffer_nodefrag (this, stream, 0, *timestamp, object_length); } else { lprintf ("skip object\n"); this->input->seek (this->input, object_length, SEEK_CUR); } stream->seq++; } else { lprintf ("unhandled stream type\n"); this->input->seek (this->input, object_length, SEEK_CUR); } data_sent += object_length + 1; this->packet_size_left -= object_length + 1; *timestamp = 0; } *timestamp = frag_offset; return ASF_OK; } /* return 0 if ok */ static asf_error_t asf_parse_packet_payload (demux_asf_t *this, asf_demux_stream_t *stream, uint8_t raw_id, uint32_t frag_offset, uint32_t rlen, int64_t *timestamp) { uint32_t s_hdr_size = 0; uint32_t frag_len; uint32_t payload_size = 0; *timestamp = 0; if (rlen >= 8) { uint8_t b[8]; if (this->input->read (this->input, b, 8) != 8) return ASF_EOF; payload_size = _X_LE_32 (b); *timestamp = _X_LE_32 (b + 4); if (*timestamp) *timestamp -= this->asf_header->file->preroll; if (stream) stream->payload_size = payload_size; s_hdr_size += 8; rlen -= 8; } s_hdr_size += rlen; if (rlen) this->input->seek (this->input, rlen, SEEK_CUR); if (this->packet_len_flags & 0x01) { static const int s[4] = {2, 1, 2, 4}; int need = s[(this->frame_flag >> 6) & 3]; uint8_t b[4]; if (this->input->read (this->input, b, need) != need) return ASF_EOF; s_hdr_size += need; switch ((this->frame_flag >> 6) & 3) { case 1: frag_len = b[0]; break; default: lprintf ("invalid frame_flag %d\n", this->frame_flag); /* fall through */ case 2: frag_len = _X_LE_16 (b); break; case 3: frag_len = _X_LE_32 (b); break; } lprintf ("reading multiple payload, payload_size=%d, frag_len=%d\n", payload_size, frag_len); } else { frag_len = this->packet_size_left - s_hdr_size; lprintf ("reading single payload, payload_size=%d, frag_len = %d\n", payload_size, frag_len); } if (frag_len > (uint32_t)this->packet_size_left) /* skip packet */ return ASF_INVALID_FRAGMENT_LENGTH; this->packet_size_left -= s_hdr_size; if (stream && stream->fifo) { if (!frag_offset) { /* keyframe detection for non-seekable input plugins */ if (stream->skip && (raw_id & 0x80) && !this->keyframe_found) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: keyframe detected\n"); this->keyframe_found = 1; this->keyframe_ts = *timestamp; } if (stream->resync && this->keyframe_found && (*timestamp >= this->keyframe_ts) && !frag_offset) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: stream resynced\n"); stream->resync = 0; stream->skip = 0; } } if (!stream->skip) { lprintf ("sending buffer of type %08x\n", stream->buf_type); if (stream->defrag) asf_send_buffer_defrag (this, stream, frag_offset, *timestamp, frag_len); else asf_send_buffer_nodefrag (this, stream, frag_offset, *timestamp, frag_len); } else { lprintf ("skip fragment\n"); this->input->seek (this->input, frag_len, SEEK_CUR); } } else { lprintf ("unhandled stream type\n"); this->input->seek (this->input, frag_len, SEEK_CUR); } this->packet_size_left -= frag_len; return ASF_OK; } static size_t demux_asf_read_file(demux_asf_t *this, char **pbuf) { char *buf = NULL; size_t buf_size = 0; size_t buf_used = 0; int len; /* read file to memory. * warning: dumb code, but hopefuly ok since reference file is small */ do { void *tmp; buf_size += 1024; tmp = realloc(buf, buf_size+1); if (!tmp) break; buf = tmp; len = this->input->read(this->input, &buf[buf_used], buf_size-buf_used); if( len > 0 ) buf_used += len; /* 50k of reference file? no way. something must be wrong */ if( buf_used > 50*1024 ) break; } while( len > 0 ); if (buf) buf[buf_used] = '\0'; *pbuf = buf; return buf_used; } /* * parse a m$ http reference * format : * [Reference] * Ref1=http://www.blabla.com/blabla */ static int demux_asf_parse_http_references( demux_asf_t *this) { char *buf = NULL; char *ptr, *end; char *href = NULL; int free_href = 0; demux_asf_read_file(this, &buf); ptr = buf; if (ptr && !strncmp(ptr, "[Reference]", 11)) { const char *const mrl = this->input->get_mrl(this->input); if (!strncmp(mrl, "http", 4)) { /* never trust a ms server, reopen the same mrl with the mms input plugin * some servers are badly configured and return a incorrect reference. */ href = strdup(mrl); free_href = 1; } else { ptr += 11; if (*ptr == '\r') ptr ++; if (*ptr == '\n') ptr ++; href = strchr(ptr, '='); if (!href) goto failure; href++; end = strchr(href, '\r'); if (!end) goto failure; *end = '\0'; } /* replace http by mmsh */ if (!strncmp(href, "http", 4)) { memcpy(href, "mmsh", 4); } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: http ref: %s\n", href); _x_demux_send_mrl_reference (this->stream, 0, href, NULL, 0, 0); if (free_href) free(href); } failure: free (buf); this->status = DEMUX_FINISHED; return this->status; } /* * parse a stupid ASF reference in an asx file * format : "ASF http://www.blabla.com/blabla" */ static int demux_asf_parse_asf_references( demux_asf_t *this) { char *buf = NULL; size_t i; demux_asf_read_file(this, &buf); if (buf && !strncmp(buf, "ASF ", 4)) { /* find the end of the string */ for (i = 4; buf[i]; i++) { if ((buf[i] == ' ') || (buf[i] == '\r') || (buf[i] == '\n')) { buf[i] = '\0'; break; } } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf ref: %s\n", buf + 4); _x_demux_send_mrl_reference (this->stream, 0, buf + 4, NULL, 0, 0); } free (buf); this->status = DEMUX_FINISHED; return this->status; } /* .asx playlist parser helper functions */ static uint32_t asx_get_time_value (const xml_node_t *node) { const char *value = xml_parser_get_property (node, "VALUE"); if (value) { int hours, minutes; double seconds; if (sscanf (value, "%d:%d:%lf", &hours, &minutes, &seconds) == 3) return hours * 3600000 + minutes * 60000 + seconds * 1000; if (sscanf (value, "%d:%lf", &minutes, &seconds) == 3) return minutes * 60000 + seconds * 1000; /* FIXME: single element is minutes or seconds? */ } return 0; /* value not found */ } /* * parse .asx playlist files */ static int demux_asf_parse_asx_references( demux_asf_t *this) { char *buf = NULL; size_t buf_used; xml_node_t *xml_tree, *asx_entry, *asx_ref; xml_parser_t *xml_parser; int result; buf_used = demux_asf_read_file(this, &buf); if (!buf || buf_used < 1) goto failure; xml_parser = xml_parser_init_r(buf, buf_used, XML_PARSER_CASE_INSENSITIVE); if((result = xml_parser_build_tree_r(xml_parser, &xml_tree)) != XML_PARSER_OK) { xml_parser_finalize_r(xml_parser); goto failure; } xml_parser_finalize_r(xml_parser); if(!strcasecmp(xml_tree->name, "ASX")) { /* Attributes: VERSION, PREVIEWMODE, BANNERBAR * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION, ENTRY, ENTRYREF, MOREINFO, PARAM, REPEAT, TITLE */ /*const char *base_href = NULL;*/ for (asx_entry = xml_tree->child; asx_entry; asx_entry = asx_entry->next) { /*const char *ref_base_href = base_href;*/ if (!strcasecmp (asx_entry->name, "ENTRY")) { /* Attributes: CLIENTSKIP, SKIPIFREF * Child elements: ABSTRACT, AUTHOR, BASE, COPYRIGHT, DURATION, ENDMARKER, MOREINFO, PARAM, REF, STARTMARKER, STARTTIME, TITLE */ const char *href = NULL; const char *title = NULL; uint32_t start_time = ~0u; uint32_t duration = ~0u; for (asx_ref = asx_entry->child; asx_ref; asx_ref = asx_ref->next) { if (!strcasecmp(asx_ref->name, "REF")) { xml_node_t *asx_sub; /* Attributes: HREF * Child elements: DURATION, ENDMARKER, STARTMARKER, STARTTIME */ /* FIXME: multiple REFs => alternative streams * (and per-ref start times and durations?). * Just the one title, though. */ href = xml_parser_get_property (asx_ref, "HREF"); for (asx_sub = asx_ref->child; asx_sub; asx_sub = asx_sub->next) { if (!strcasecmp (asx_sub->name, "STARTTIME")) start_time = asx_get_time_value (asx_sub); else if (!strcasecmp (asx_sub->name, "DURATION")) duration = asx_get_time_value (asx_sub); } } else if (!strcasecmp (asx_ref->name, "TITLE")) { if (!title) title = asx_ref->data; } else if (!strcasecmp (asx_ref->name, "STARTTIME")) { if (start_time == ~0u) start_time = asx_get_time_value (asx_ref); } else if (!strcasecmp (asx_ref->name, "DURATION")) { if (duration == ~0u) duration = asx_get_time_value (asx_ref); } #if 0 else if (!strcasecmp (asx_ref->name, "BASE")) /* Attributes: HREF */ ref_base_href = xml_parser_get_property (asx_entry, "HREF"); #endif } /* FIXME: prepend ref_base_href to href */ if (href && *href) _x_demux_send_mrl_reference (this->stream, 0, href, title, start_time == ~0u ? 0 : start_time, duration == ~0u ? ~0u : duration); } else if (!strcasecmp (asx_entry->name, "ENTRYREF")) { /* Attributes: HREF, CLIENTBIND */ const char *href = xml_parser_get_property (asx_entry, "HREF"); if (href && *href) _x_demux_send_mrl_reference (this->stream, 0, href, NULL, 0, -1); } #if 0 else if (!strcasecmp (asx_entry->name, "BASE")) /* Attributes: HREF */ base_href = xml_parser_get_property (asx_entry, "HREF"); #endif } } else xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: Unsupported XML type: '%s'.\n", xml_tree->name); xml_parser_free_tree(xml_tree); failure: free(buf); this->status = DEMUX_FINISHED; return this->status; } /* * xine specific functions start here */ static int demux_asf_send_chunk (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; switch (this->mode) { case ASF_MODE_ASX_REF: return demux_asf_parse_asx_references(this); case ASF_MODE_HTTP_REF: return demux_asf_parse_http_references(this); case ASF_MODE_ASF_REF: return demux_asf_parse_asf_references(this); case ASF_MODE_ENCRYPTED_CONTENT: case ASF_MODE_NO_CONTENT: this->status = DEMUX_FINISHED; return this->status; default: { asf_error_t e; uint32_t header_size = 0; e = asf_parse_packet_align (this); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_align: %s.\n", error_strings[e]); this->status = DEMUX_FINISHED; return this->status; } e = asf_parse_packet_ecd (this, &header_size); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_ecd: %s.\n", error_strings[e]); this->status = DEMUX_FINISHED; return this->status; } e = asf_parse_packet_payload_header (this, header_size); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_payload_header: %s.\n", error_strings[e]); this->status = DEMUX_FINISHED; return this->status; } for (this->frame = 0; this->frame < (this->nb_frames & 0x3f); this->frame++) { asf_demux_stream_t *stream = NULL; int64_t ts = 0; uint32_t rlen = 0; uint32_t frag_offset = 0; uint8_t raw_id; { uint8_t b[1]; if (this->input->read (this->input, b, 1) != 1) break; raw_id = b[0]; } this->packet_size_left -= 1; e = asf_parse_packet_payload_common (this, raw_id, &stream, &frag_offset, &rlen); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_payload_common: %s.\n", error_strings[e]); break; } if (rlen == 1) { e = asf_parse_packet_compressed_payload (this, stream, raw_id, frag_offset, &ts); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_compressed_payload: %s.\n", error_strings[e]); break; } } else { e = asf_parse_packet_payload (this, stream, raw_id, frag_offset, rlen, &ts); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_payload: %s.\n", error_strings[e]); break; } } } return this->status; } } } static void demux_asf_dispose (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; if (this->asf_header) { int i; for (i=0; iasf_header->stream_count; i++) { asf_demux_stream_t *asf_stream; asf_stream = &this->streams[i]; if (asf_stream->buffer) { free (asf_stream->buffer); asf_stream->buffer = NULL; } } asf_header_delete (this->asf_header); } free (this->reorder_temp); free (this); } static int demux_asf_get_status (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; return this->status; } static void demux_asf_send_headers (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; asf_guid_t guid; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->last_pts[0] = 0; this->last_pts[1] = 0; this->status = DEMUX_OK; if (this->input->get_capabilities (this->input) & INPUT_CAP_SEEKABLE) this->input->seek (this->input, 0, SEEK_SET); if ((this->mode == ASF_MODE_ASX_REF) || (this->mode == ASF_MODE_HTTP_REF) || (this->mode == ASF_MODE_ASF_REF)) { _x_demux_control_start(this->stream); return; } guid = get_guid(this); if (guid != GUID_ASF_HEADER) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: file doesn't start with an asf header\n"); this->status = DEMUX_FINISHED; return; } demux_asf_send_headers_common(this); lprintf ("send header done\n"); } static int demux_asf_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_asf_t *this = (demux_asf_t *) this_gen; int i; lprintf ("demux_asf_seek: start_pos=%"PRId64", start_time=%d\n", start_pos, start_time); this->status = DEMUX_OK; if (this->mode != ASF_MODE_NORMAL) { return this->status; } /* * seek to start position */ for(i = 0; i < this->asf_header->stream_count; i++) { this->streams[i].frag_offset = 0; this->streams[i].first_seq = 1; this->streams[i].seq = 0; this->streams[i].timestamp = 0; } this->last_pts[PTS_VIDEO] = 0; this->last_pts[PTS_AUDIO] = 0; this->keyframe_ts = 0; this->keyframe_found = 0; /* engine sync stuff */ this->send_newpts = 1; this->buf_flag_seek = 1; if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) { int state; _x_demux_flush_engine(this->stream); start_time /= 1000; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); if ( (!start_pos) && (start_time)) start_pos = start_time * this->rate; if (start_pos < this->first_packet_pos) start_pos = this->first_packet_pos; /* * Find the previous keyframe * * states : 0 start, search a video keyframe * 1 video keyframe found, search an audio packet * 2 no video stream, search an audio packet * 5 end */ state = 0; /* no video stream */ if (this->video_stream == -1) { if (this->audio_stream == -1) { lprintf ("demux_asf_seek: no video stream, no audio stream\n"); return this->status; } else { lprintf ("demux_asf_seek: no video stream\n"); state = 2; } } /* force the demuxer to not send data to decoders */ if (this->video_stream >= 0) { this->streams[this->video_stream].skip = 1; this->streams[this->video_stream].resync = 0; } if (this->audio_stream >= 0) { this->streams[this->audio_stream].skip = 1; this->streams[this->audio_stream].resync = 0; } start_pos -= (start_pos - this->first_packet_pos) % this->packet_size; while ((start_pos >= this->first_packet_pos) && (state != 5)) { asf_error_t e; uint32_t header_size; /* seek to the beginning of the previous packet */ lprintf ("demux_asf_seek: seek back\n"); if (this->input->seek (this->input, start_pos, SEEK_SET) != start_pos) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: demux_asf_seek: seek failed\n"); goto error; } header_size = 0; e = asf_parse_packet_ecd (this, &header_size); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_ecd: %s.\n", error_strings[e]); this->status = DEMUX_FINISHED; return this->status; } e = asf_parse_packet_payload_header (this, header_size); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_payload_header: %s.\n", error_strings[e]); this->status = DEMUX_FINISHED; return this->status; } for (this->frame = 0; this->frame < (this->nb_frames & 0x3f); this->frame++) { asf_demux_stream_t *stream = NULL; int64_t ts; uint32_t rlen = 0; uint32_t frag_offset = 0; uint8_t raw_id, stream_id; { uint8_t b[1]; if (this->input->read (this->input, b, 1) != 1) break; raw_id = b[0]; } this->packet_size_left -= 1; lprintf ("demux_asf_seek: raw_id = %d\n", (int)raw_id); stream_id = raw_id & 0x7f; e = asf_parse_packet_payload_common (this, raw_id, &stream, &frag_offset, &rlen); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_payload_common: %s.\n", error_strings[e]); break; } if (rlen == 1) { e = asf_parse_packet_compressed_payload (this, stream, raw_id, frag_offset, &ts); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_compressed_payload: %s.\n", error_strings[e]); break; } } else { e = asf_parse_packet_payload (this, stream, raw_id, frag_offset, rlen, &ts); if (e) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: asf_parse_packet_payload: %s.\n", error_strings[e]); break; } } if (state == 0) { if (this->keyframe_found) { if (this->audio_stream == -1) { lprintf ("demux_asf_seek: no audio stream\n"); state = 5; } state = 1; /* search an audio packet with pts < this->keyframe_pts */ lprintf ("demux_asf_seek: keyframe found at %"PRId64", timestamp = %"PRId64"\n", start_pos, ts); check_newpts (this, ts * 90, 1, 0); } } else if (state == 1) { if ((stream_id == this->audio_id) && ts && (ts <= this->keyframe_ts)) { lprintf ("demux_asf_seek: audio packet found at %"PRId64", ts = %"PRId64"\n", start_pos, ts); state = 5; /* end */ break; } } else if (state == 2) { if ((stream_id == this->audio_id) && !frag_offset) { this->keyframe_found = 1; this->keyframe_ts = ts; state = 5; /* end */ lprintf ("demux_asf_seek: audio packet found at %"PRId64", timestamp = %"PRId64"\n", start_pos, ts); check_newpts (this, ts * 90, 0, 0); } } } start_pos -= this->packet_size; } if (state != 5) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: demux_asf_seek: beginning of the stream\n"); this->input->seek (this->input, this->first_packet_pos, SEEK_SET); this->keyframe_found = 1; } else { this->input->seek (this->input, start_pos + this->packet_size, SEEK_SET); } lprintf ("demux_asf_seek: keyframe_found=%d, keyframe_ts=%"PRId64"\n", this->keyframe_found, this->keyframe_ts); if (this->video_stream >= 0) { this->streams[this->video_stream].resync = 1; this->streams[this->video_stream].skip = 1; } if (this->audio_stream >= 0) { this->streams[this->audio_stream].resync = 1; this->streams[this->audio_stream].skip = 1; } } else if (!playing && this->input->seek_time != NULL) { if (start_pos && !start_time) start_time = this->length * start_pos / 65535; this->input->seek_time (this->input, start_time, SEEK_SET); this->keyframe_ts = 0; this->keyframe_found = 0; /* means next keyframe */ if (this->video_stream >= 0) { this->streams[this->video_stream].resync = 1; this->streams[this->video_stream].skip = 1; } if (this->audio_stream >= 0) { this->streams[this->audio_stream].resync = 0; this->streams[this->audio_stream].skip = 0; } } else { /* "streaming" mode */ this->keyframe_ts = 0; this->keyframe_found = 0; /* means next keyframe */ if (this->video_stream >= 0) { this->streams[this->video_stream].resync = 1; this->streams[this->video_stream].skip = 1; } if (this->audio_stream >= 0) { this->streams[this->audio_stream].resync = 0; this->streams[this->audio_stream].skip = 0; } } return this->status; error: this->status = DEMUX_FINISHED; return this->status; } static int demux_asf_get_stream_length (demux_plugin_t *this_gen) { demux_asf_t *this = (demux_asf_t *) this_gen; return this->length; } static uint32_t demux_asf_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_asf_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_asf_t *this; uint8_t buf[MAX_PREVIEW_SIZE+1]; int len; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: /* * try to get a preview of the data */ len = _x_demux_read_header (input, buf, MAX_PREVIEW_SIZE); if (len < 16) return NULL; if (asf_guid_2_num (buf) != GUID_ASF_HEADER) { buf[len] = '\0'; if( !strstr(buf,"asx") && !strstr(buf,"ASX") && strncmp(buf,"[Reference]", 11) && strncmp(buf,"ASF ", 4) && memcmp(buf, "\x30\x26\xB2\x75", 4) ) return NULL; } lprintf ("file starts with an asf header\n"); break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "demux_asf: warning, unknown method %d\n", stream->content_detection_method); return NULL; } this = calloc (1, sizeof (demux_asf_t)); if (!this) return NULL; this->reorder_temp = NULL; this->stream = stream; this->input = input; this->audio_id = -1; this->video_id = -1; memset (this->seen_streams, 255, sizeof (this->seen_streams)); /* * check for reference stream */ this->mode = ASF_MODE_NORMAL; len = input->get_optional_data (input, buf, INPUT_OPTIONAL_DATA_PREVIEW); if ( (len == INPUT_OPTIONAL_UNSUPPORTED) && (input->get_capabilities (input) & INPUT_CAP_SEEKABLE) ) { input->seek (input, 0, SEEK_SET); len=input->read (input, buf, 1024); } if(len > 0) { buf[len] = '\0'; if( strstr((char*)buf,"asx") || strstr((char*)buf,"ASX") ) this->mode = ASF_MODE_ASX_REF; if( strstr((char*)buf,"[Reference]") ) this->mode = ASF_MODE_HTTP_REF; if( strstr((char*)buf,"ASF ") ) this->mode = ASF_MODE_ASF_REF; } this->demux_plugin.send_headers = demux_asf_send_headers; this->demux_plugin.send_chunk = demux_asf_send_chunk; this->demux_plugin.seek = demux_asf_seek; this->demux_plugin.dispose = demux_asf_dispose; this->demux_plugin.get_status = demux_asf_get_status; this->demux_plugin.get_stream_length = demux_asf_get_stream_length; this->demux_plugin.get_capabilities = demux_asf_get_capabilities; this->demux_plugin.get_optional_data = demux_asf_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } static void *init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_asf_class = { .open_plugin = open_plugin, .description = N_("ASF demux plugin"), .identifier = "ASF", .mimetypes = "video/x-ms-asf: asf: ASF stream;" "video/x-ms-wmv: wmv: Windows Media Video;" "audio/x-ms-wma: wma: Windows Media Audio;" "application/vnd.ms-asf: asf: ASF stream;" "application/x-mplayer2: asf,asx,asp: mplayer2;" "video/x-ms-asf-plugin: asf,asx,asp: mms animation;" "video/x-ms-wvx: wvx: wmv metafile;" "video/x-ms-wax: wva: wma metafile;", /* asx, wvx, wax are metafile or playlist */ .extensions = "asf wmv wma asx wvx wax", .dispose = NULL, }; return (void *)&demux_asf_class; } /* * exported plugin catalog entry */ static const demuxer_info_t demux_info_asf = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "asf", XINE_VERSION_CODE, &demux_info_asf, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_pva.c0000644000175000017500000003174214647725152015452 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * TechnoTrend PVA File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the PVA file format, refer to this PDF: * http://www.technotrend.de/download/av_format_v1.pdf */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include /********** logging **********/ #define LOG_MODULE "demux_pva" /* #define LOG_VERBOSE */ /* #define LOG */ #include #include #include #include #include "bswap.h" #define PVA_PREAMBLE_SIZE 8 #define WRAP_THRESHOLD 120000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int send_newpts; int64_t last_pts[2]; off_t data_size; } demux_pva_t; /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) static void check_newpts( demux_pva_t *this, int64_t pts, int video ){ int64_t diff; diff = pts - this->last_pts[video]; if( pts && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { _x_demux_control_newpts(this->stream, pts, 0); this->send_newpts = 0; this->last_pts[1-video] = 0; } if( pts ) this->last_pts[video] = pts; } /* returns 1 if the PVA file was opened successfully, 0 otherwise */ static int probe_pva_file(input_plugin_t *input) { unsigned char preamble[PVA_PREAMBLE_SIZE]; if (input->seek(input, 0, SEEK_SET) != 0) return 0; if (input->read(input, preamble, PVA_PREAMBLE_SIZE) != PVA_PREAMBLE_SIZE) return 0; /* PVA file must start with signature "AV" */ if ((preamble[0] != 'A') || (preamble[1] != 'V')) return 0; /* enforce the rule that stream ID must be either 1 or 2 */ if ((preamble[2] != 1) && (preamble[2] != 2)) return 0; /* counter on the first packet should be 0 */ if (preamble[3] != 0) return 0; return 1; } static int demux_pva_send_chunk(demux_plugin_t *this_gen) { demux_pva_t *this = (demux_pva_t *) this_gen; buf_element_t *buf; int chunk_size; unsigned char preamble[PVA_PREAMBLE_SIZE]; unsigned char pts_buf[4]; off_t current_file_pos; int64_t pts; unsigned int flags, header_len; if (this->input->read(this->input, preamble, PVA_PREAMBLE_SIZE) != PVA_PREAMBLE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } /* make sure the signature is there */ if ((preamble[0] != 'A') || (preamble[1] != 'V')) { this->status = DEMUX_FINISHED; return this->status; } chunk_size = _X_BE_16(&preamble[6]); current_file_pos = this->input->get_current_pos(this->input); if (preamble[2] == 1) { /* video */ /* load the pts if it is the first thing in the chunk */ if (preamble[5] & 0x10) { if (this->input->read(this->input, pts_buf, 4) != 4) { this->status = DEMUX_FINISHED; return this->status; } chunk_size -= 4; pts = _X_BE_32(&pts_buf[0]); check_newpts( this, pts, PTS_VIDEO ); } else pts = 0; while (chunk_size) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_MPEG; buf->pts = pts; pts = 0; if( this->data_size ) buf->extra_info->input_normpos = (int) ((double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = buf->pts / 90; if (chunk_size > buf->max_size) buf->size = buf->max_size; else buf->size = chunk_size; chunk_size -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!chunk_size) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put (this->video_fifo, buf); } } else if (preamble[2] == 2) { /* audio */ if(!this->audio_fifo) { if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; } return this->status; } /* mostly cribbed from demux_pes.c */ /* validate start of packet */ if (this->input->read(this->input, preamble, 6) != 6) { this->status = DEMUX_FINISHED; return this->status; } if (_X_BE_32(&preamble[0]) != 0x000001C0) { this->status = DEMUX_FINISHED; return this->status; } chunk_size = _X_BE_16(&preamble[4]); /* get next 3 header bytes */ if (this->input->read(this->input, preamble, 3) != 3) { this->status = DEMUX_FINISHED; return this->status; } flags = preamble[1]; header_len = preamble[2]; chunk_size -= header_len + 3; pts = 0; if ((flags & 0x80) == 0x80) { if (this->input->read(this->input, preamble, 5) != 5) { this->status = DEMUX_FINISHED; return this->status; } pts = (int64_t)(preamble[0] & 0x0e) << 29 ; pts |= (_X_BE_16(&preamble[1]) & 0xFFFE) << 14; pts |= (_X_BE_16(&preamble[3]) & 0xFFFE) >> 1; header_len -= 5 ; check_newpts( this, pts, PTS_AUDIO ); } /* skip rest of header */ if (this->input->seek (this->input, header_len, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; return this->status; } buf = this->input->read_block (this->input, this->audio_fifo, chunk_size); if (buf == NULL) { this->status = DEMUX_FINISHED; return this->status; } buf->type = BUF_AUDIO_MPEG; buf->pts = pts; if( this->data_size ) buf->extra_info->input_normpos = (int) ((double) this->input->get_current_pos(this->input) * 65535 / this->data_size); this->audio_fifo->put (this->audio_fifo, buf); } else { /* unknown, skip it */ if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) { this->status = DEMUX_FINISHED; return this->status; } } return this->status; } static void demux_pva_send_headers(demux_plugin_t *this_gen) { demux_pva_t *this = (demux_pva_t *) this_gen; buf_element_t *buf; int n; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to video decoder (cribbed from demux_elem.c) */ buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; n = this->input->read (this->input, buf->mem, 2048); if (n<=0) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } buf->size = n; buf->pts = 0; if( this->data_size ) buf->extra_info->input_normpos = (int) ((double) this->input->get_current_pos(this->input) * 65535 / this->data_size); buf->type = BUF_VIDEO_MPEG; buf->decoder_flags = BUF_FLAG_PREVIEW; this->video_fifo->put(this->video_fifo, buf); /* send init info to the audio decoder */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; n = this->input->read (this->input, buf->mem, 2048); if (n<=0) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } buf->size = n; buf->pts = 0; if( this->data_size ) buf->extra_info->input_normpos = (int) ((double) this->input->get_current_pos(this->input) * 65535 / this->data_size); buf->type = BUF_AUDIO_MPEG; buf->decoder_flags = BUF_FLAG_PREVIEW; this->video_fifo->put(this->audio_fifo, buf); } } #define SEEK_BUFFER_SIZE 1024 static int demux_pva_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_pva_t *this = (demux_pva_t *) this_gen; unsigned char seek_buffer[SEEK_BUFFER_SIZE]; int found = 0; int i; (void)start_time; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); /* start from the start_pos */ this->input->seek(this->input, start_pos, SEEK_SET); /* find the start of the next packet by searching for an 'A' followed * by a 'V' followed by either a 1 or a 2 */ while (!found) { if (this->input->read(this->input, seek_buffer, SEEK_BUFFER_SIZE) != SEEK_BUFFER_SIZE) { this->status = DEMUX_FINISHED; return this->status; } for (i = 0; i < SEEK_BUFFER_SIZE - 3; i++) { if ((seek_buffer[i + 0] == 'A') && (seek_buffer[i + 1] == 'V') && ((seek_buffer[i + 2] == 1) || (seek_buffer[i + 2] == 2))) { found = 1; break; } } /* rewind 3 bytes since the 3-byte marker may very well be split * across the boundary */ if (!found) this->input->seek(this->input, -3, SEEK_CUR); } /* reposition file at new offset */ this->input->seek(this->input, -(SEEK_BUFFER_SIZE - i), SEEK_CUR); /* if thread is not running, initialize demuxer */ if( !playing ) { this->send_newpts = 1; this->status = DEMUX_OK; } else _x_demux_flush_engine(this->stream); return this->status; } static int demux_pva_get_status (demux_plugin_t *this_gen) { demux_pva_t *this = (demux_pva_t *) this_gen; return this->status; } static int demux_pva_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_pva_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_pva_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_pva_t *this; if (!INPUT_IS_SEEKABLE(input)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input not seekable, can not handle!\n"); return NULL; } switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_pva_file(input)) { return NULL; } break; default: return NULL; } this = calloc(1, sizeof(demux_pva_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_pva_send_headers; this->demux_plugin.send_chunk = demux_pva_send_chunk; this->demux_plugin.seek = demux_pva_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_pva_get_status; this->demux_plugin.get_stream_length = demux_pva_get_stream_length; this->demux_plugin.get_capabilities = demux_pva_get_capabilities; this->demux_plugin.get_optional_data = demux_pva_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; this->data_size = input->get_length(this->input); return &this->demux_plugin; } static void *init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_pva_class = { .open_plugin = open_plugin, .description = N_("TechnoTrend PVA demux plugin"), .identifier = "TechnoTrend PVA", .mimetypes = NULL, .extensions = "pva", .dispose = NULL, }; return (void *)&demux_pva_class; } /* * exported plugin catalog entry */ static const demuxer_info_t demux_info_pva = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "pva", XINE_VERSION_CODE, &demux_info_pva, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_shn.c0000644000175000017500000001404514647725152015451 0ustar meme/* * Copyright (C) 2005-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #define LOG_MODULE "demux_shn" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_audio.h" typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; } demux_shn_t; static int probe_shn_file(input_plugin_t *input) { uint8_t peak[4]; if (_x_demux_read_header(input, peak, 4) != 4) return 0; if ((peak[0] != 'a') || (peak[1] != 'j') || (peak[2] != 'k') || (peak[3] != 'g')) { return 0; } return 1; } static int demux_shn_send_chunk(demux_plugin_t *this_gen) { demux_shn_t *this = (demux_shn_t *) this_gen; int bytes_read; buf_element_t *buf = NULL; /* just load an entire buffer from wherever the audio happens to be */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_SHORTEN; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); buf->pts = 0; bytes_read = this->input->read(this->input, buf->content, buf->max_size); if (bytes_read <= 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return this->status; } else buf->size = bytes_read; /* each buffer stands on its own */ buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); return this->status; } static void demux_shn_send_headers(demux_plugin_t *this_gen) { demux_shn_t *this = (demux_shn_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_SHORTEN; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; /* this is a guess at the correct parameters */ buf->decoder_info[1] = 44100; buf->decoder_info[2] = 16; buf->decoder_info[3] = 2; buf->content = NULL; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_shn_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_shn_t *this = (demux_shn_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static int demux_shn_get_status (demux_plugin_t *this_gen) { demux_shn_t *this = (demux_shn_t *) this_gen; return this->status; } static int demux_shn_get_stream_length (demux_plugin_t *this_gen) { // demux_shn_t *this = (demux_shn_t *) this_gen; (void)this_gen; return 0; } static uint32_t demux_shn_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_shn_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_shn_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_shn_file(input)) { return NULL; } break; default: return NULL; } this = calloc(1, sizeof(demux_shn_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_shn_send_headers; this->demux_plugin.send_chunk = demux_shn_send_chunk; this->demux_plugin.seek = demux_shn_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_shn_get_status; this->demux_plugin.get_stream_length = demux_shn_get_stream_length; this->demux_plugin.get_capabilities = demux_shn_get_capabilities; this->demux_plugin.get_optional_data = demux_shn_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } void *demux_shn_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_shn_class = { .open_plugin = open_plugin, .description = N_("Shorten demux plugin"), .identifier = "Shorten", .mimetypes = NULL, .extensions = "shn", .dispose = NULL, }; return (void *)&demux_shn_class; } xine-lib-1.2/src/demuxers/demux_real_common.h0000644000175000017500000000377614647725152017172 0ustar meme/* * Copyright (C) 2008-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ static inline void demux_real_sipro_swap (char buffer[], int bs) { /* bs = nybbles per subpacket */ static const unsigned char sipr_swaps[38][2] = { {0, 63}, {1, 22}, {2, 44}, {3, 90}, {5, 81}, {7, 31}, {8, 86}, {9, 58}, {10, 36}, {12, 68}, {13, 39}, {14, 73}, {15, 53}, {16, 69}, {17, 57}, {19, 88}, {20, 34}, {21, 71}, {24, 46}, {25, 94}, {26, 54}, {28, 75}, {29, 50}, {32, 70}, {33, 92}, {35, 74}, {38, 85}, {40, 56}, {42, 87}, {43, 65}, {45, 59}, {48, 79}, {49, 93}, {51, 89}, {55, 95}, {61, 76}, {67, 83}, {77, 80} }; int n; for (n = 0; n < 38; ++n) { int j; int i = bs * sipr_swaps[n][0]; int o = bs * sipr_swaps[n][1]; /* swap nibbles of block 'i' with 'o' TODO: optimize */ for (j = 0; j < bs; ++j) { int x = (i & 1) ? (buffer[i >> 1] >> 4) : (buffer[i >> 1] & 0x0F); int y = (o & 1) ? (buffer[o >> 1] >> 4) : (buffer[o >> 1] & 0x0F); if (o & 1) buffer[o >> 1] = (buffer[o >> 1] & 0x0F) | (x << 4); else buffer[o >> 1] = (buffer[o >> 1] & 0xF0) | x; if (i & 1) buffer[i >> 1] = (buffer[i >> 1] & 0x0F) | (y << 4); else buffer[i >> 1] = (buffer[i >> 1] & 0xF0) | y; ++i; ++o; } } } xine-lib-1.2/src/demuxers/demux_aac.c0000644000175000017500000004412714647725152015411 0ustar meme/* * Copyright (C) 2001-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Raw AAC File Demuxer by Mike Melanson (melanson@pcisys.net) * This demuxer detects ADIF and ADTS headers in AAC files. * Then it shovels buffer-sized chunks over to the AAC decoder. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #define LOG_MODULE "demux_aac" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_audio.h" #include "id3.h" typedef enum { DEMUX_AAC_ADTS = 0, DEMUX_AAC_ADIF } demux_aac_mode_t; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; demux_aac_mode_t mode; int status; int id3v2_tag_size; int last_read_res; int pts_offs; /* this is set when a seek just occurred */ int seek_flag; /* time of last config change */ int64_t base_pts; /* frames since that */ uint32_t frame_num; /* frames in current sync */ uint32_t frame_count; /* current config. in sbr mode, these really are to be doubled, but we just want the ratio ;-) */ uint32_t samples_per_frame; uint32_t samples_per_second; /* maximum ADTS frame size is 13 bits (8191). */ uint32_t bgot, bdelivered; uint8_t buf[9 << 10]; } demux_aac_t; static int probe_aac_file (xine_stream_t *stream, input_plugin_t *input, demux_aac_mode_t *mode) { uint8_t buf[MAX_PREVIEW_SIZE]; uint16_t syncword = 0; int data_start = -1, bsize, i; /* Check if there's an ID3v2 tag at the start */ data_start = xine_parse_id3v2_tag (stream, input); lprintf("Getting a buffer of size %zu\n", sizeof (buf)); bsize = _x_demux_read_stream_header (stream, input, buf, sizeof (buf)); if (bsize < 10) return -1; /* Check for an ADIF header - should be at the start of the file */ if (_x_is_fourcc (buf, "ADIF")) { lprintf("found ADIF header\n"); *mode = DEMUX_AAC_ADIF; return data_start; } /* Look for an ADTS header - might not be at the start of the file */ for (i = 0; i < bsize; i++) { if ((syncword & 0xfff6) == 0xfff0) break; syncword = (syncword << 8) | buf[i]; } /* did we really find the ADTS header? */ if (i == bsize) return -1; /* No, we didn't */ data_start += i - 2; *mode = DEMUX_AAC_ADTS; lprintf ("found ADTS header at offset %d\n", i - 2); /* Look for second ADTS header to confirm it's really aac */ if (data_start + 5 < bsize) { int frame_size = (_X_BE_32 (buf + data_start + 2) >> 5) & 0x1fff; lprintf("first frame size %d\n", frame_size); if ((frame_size > 0) && (data_start + frame_size + 4 <= bsize) && /* first 28 bits must be identical */ !((_X_BE_32 (buf + data_start) ^ _X_BE_32 (buf + data_start + frame_size)) & 0xfffffff0)) { lprintf("found second ADTS header\n"); if (input->seek (input, data_start, SEEK_SET) < 0) input->seek (input, data_start + frame_size, SEEK_SET); return data_start; } } return -1; } /* FIXME: both ADTS and ADIF allow the first 4 AAC object types only, * and have no short frame bit like in a regular config bitstream. * for now, just assume always 1024 frame samples. */ static uint32_t demux_aac_samples_per_frame (uint32_t object_type) { (void)object_type; return 1024; } static const uint32_t demux_aac_sample_rates[16] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 0, 0, 0, 0 }; static void demux_aac_apply_adts (demux_aac_t *this, const uint8_t *buf) { uint32_t samples_per_frame, samples_per_second = 48000, object_type; uint32_t word = _X_BE_32 (buf); object_type = ((word >> 14) & 3) + 1; samples_per_frame = demux_aac_samples_per_frame (object_type); samples_per_second = demux_aac_sample_rates[(word >> 10) & 15]; if (!samples_per_second) return; this->frame_count = (buf[6] & 3) + 1; if ((this->samples_per_frame ^ samples_per_frame) | (this->samples_per_second ^ samples_per_second)) { if (this->samples_per_second) this->base_pts += (int64_t)this->frame_num * 90000 * (int64_t)this->samples_per_frame / (int64_t)this->samples_per_second; this->frame_num = 0; this->samples_per_frame = samples_per_frame; this->samples_per_second = samples_per_second; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": ADTS frame duration %u/%u.\n", (unsigned int)this->samples_per_frame, (unsigned int)this->samples_per_second); } } static uint32_t demux_aac_get_bits (const uint8_t *buf, uint32_t bitpos, uint32_t bits) { uint32_t word = _X_BE_32 (buf + (bitpos >> 3)); return (word << (bitpos & 7)) >> (32 - bits); } #undef _FULL_ADIF static void demux_aac_apply_adif (demux_aac_t *this, const uint8_t *buf) { uint32_t samples_per_frame, samples_per_second = 48000; uint32_t word, bitpos = 0; uint32_t object_type, sf_index, bitstream_type; #ifdef _FULL_ADIF uint32_t num_program_config_elements, u; uint32_t num_front_channel_elements, num_side_channel_elements; uint32_t num_back_channel_elements, num_lfe_channel_elements; uint32_t num_assoc_data_elements, num_valid_cc_elements; #endif bitpos += 32; /* "AIDF" */ word = demux_aac_get_bits (buf, bitpos, 1); bitpos += 1; /* copyright */ if (word) bitpos += 72; /* copyright_string */ bitpos += 2; /* original_copy:1, home:1 */ bitstream_type = demux_aac_get_bits (buf, bitpos, 1); bitpos += 1; bitpos += 23; /* bitrate:23 */ #ifdef _FULL_ADIF num_program_config_elements = demux_aac_get_bits (buf, bitpos, 4) + 1; #endif bitpos += 4; #ifdef _FULL_ADIF for (u = 0; u < num_program_config_elements; u++) #endif { if (!bitstream_type) bitpos += 20; /* buffer_fullness:20 */ bitpos += 4; /* element_instance_tag:4 */ object_type = demux_aac_get_bits (buf, bitpos, 2) + 1; bitpos += 2; sf_index = demux_aac_get_bits (buf, bitpos, 4); bitpos += 4; #ifdef _FULL_ADIF num_front_channel_elements = demux_aac_get_bits (buf, bitpos, 4); bitpos += 4; num_side_channel_elements = demux_aac_get_bits (buf, bitpos, 4); bitpos += 4; num_back_channel_elements = demux_aac_get_bits (buf, bitpos, 4); bitpos += 4; num_lfe_channel_elements = demux_aac_get_bits (buf, bitpos, 2); bitpos += 2; num_assoc_data_elements = demux_aac_get_bits (buf, bitpos, 3); bitpos += 3; num_valid_cc_elements = demux_aac_get_bits (buf, bitpos, 4); bitpos += 4; word = demux_aac_get_bits (buf, bitpos, 1); bitpos += 1; /* mono_mixdown_present:1 */ if (word) bitpos += 4; /* mono_mixdown_element_number:4 */ word = demux_aac_get_bits (buf, bitpos, 1); bitpos += 1; /* stereo_mixdown_present:1 */ if (word) bitpos += 4; /* stereo_mixdown_element_number:4 */ word = demux_aac_get_bits (buf, bitpos, 1); bitpos += 1; /* matrix_mixdown_idx_present:1 */ if (word) bitpos += 3; /* matrix_mixdown_idx:2, pseudo_surround_enable:1 */ bitpos += num_front_channel_elements * 5; /* front_element_is_cpe[i]:1, front_element_tag_select[i]:4 */ bitpos += num_side_channel_elements * 5; /* side_element_is_cpe[i]:1, side_element_tag_select[i]:4 */ bitpos += num_back_channel_elements * 5; /* back_element_is_cpe[i]:1, back_element_tag_select[i]:4 */ bitpos += num_lfe_channel_elements * 4; /* lfe_element_tag_select[i]:4 */ bitpos += num_assoc_data_elements * 4; /* assoc_data_element_tag_select[i]:4 */ bitpos += num_valid_cc_elements * 5; /* cc_element_is_ind_sw[i]:1, valid_cc_element_tag_select[i]:4 */ bitpos = (bitpos + 7) & ~7; /* byte align */ word = buf[bitpos >> 3]; /* comment_field_bytes */ bitpos += word << 3; /* comment_field_data[i] */ #endif } samples_per_frame = demux_aac_samples_per_frame (object_type); samples_per_second = demux_aac_sample_rates[sf_index]; if (!samples_per_second) return; #ifdef _FULL_ADIF this->frame_count = num_program_config_elements; #else this->frame_count = 1; #endif if ((this->samples_per_frame ^ samples_per_frame) | (this->samples_per_second ^ samples_per_second)) { if (this->samples_per_second) this->base_pts += (int64_t)this->frame_num * 90000 * (int64_t)this->samples_per_frame / (int64_t)this->samples_per_second; this->frame_num = 0; this->samples_per_frame = samples_per_frame; this->samples_per_second = samples_per_second; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": AIDF frame duration %u/%u.\n", (unsigned int)this->samples_per_frame, (unsigned int)this->samples_per_second); } } static int demux_aac_next (demux_aac_t *this, uint8_t *buf) { if (this->mode == DEMUX_AAC_ADTS) { uint32_t u = this->bdelivered + 7, word = 0; while (1) { if (u < this->bgot) { uint32_t size = (_X_BE_32 (this->buf + this->bdelivered + 2) >> 5) & 0x1fff; do { word = (word << 8) + this->buf[u++]; if ((word & 0xfff6) == 0xfff0) break; } while (u < this->bgot); if ((word & 0xfff6) == 0xfff0) { if (this->bdelivered + size <= u - 2) break; continue; } } if (u > sizeof (this->buf) - 512) { uint32_t l = this->bgot - this->bdelivered; if (this->bdelivered < 512) /* a single frame of 8 kbyte ?? */ l = 4; if (this->bdelivered >= l) memcpy (this->buf, this->buf + this->bdelivered, l); else memmove (this->buf, this->buf + this->bdelivered, l); u -= this->bdelivered; this->bdelivered = 0; this->bgot = l; } this->last_read_res = this->input->read (this->input, this->buf + this->bgot, 512); if (this->last_read_res <= 0) break; this->bgot += this->last_read_res; } if ((word & 0xfff6) == 0xfff0) { demux_aac_apply_adts (this, this->buf + this->bdelivered); u -= 2 + this->bdelivered; memcpy (buf, this->buf + this->bdelivered, u); this->bdelivered += u; return u; } } else { /* DEMUX_AAC_ADIF */ /* SIGH. ADIF is merely a single head plus a sequence of raw frames. * This can hardly do more than play from the beginning. * nobody seems to use that anymore, and even ffmpeg doer not support all that. * lets not repeat half the decoders work here just to count frames, * and let decoder and engine add time info. */ int r = this->input->read (this->input, buf, 2048); if (r > 0) { if ((r > 4) && !memcmp (buf, "ADIF", 4)) demux_aac_apply_adif (this, buf); } this->frame_count = 0; return r; } { uint32_t l = this->bgot - this->bdelivered; if (l) memcpy (buf, this->buf + this->bdelivered, l); this->bgot = 0; this->bdelivered = 0; return l; } } static int demux_aac_send_chunk(demux_plugin_t *this_gen) { demux_aac_t *this = (demux_aac_t *) this_gen; off_t current_pos = this->input->get_current_pos (this->input) + this->bdelivered - this->bgot; off_t length = this->input->get_length (this->input); int bitrate = _x_stream_info_get (this->stream, XINE_STREAM_INFO_AUDIO_BITRATE); buf_element_t *buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); if (this->seek_flag) { this->seek_flag = 0; _x_demux_control_newpts (this->stream, this->base_pts, BUF_FLAG_SEEK); } buf->type = BUF_AUDIO_AAC; buf->decoder_flags |= BUF_FLAG_FRAME_END; buf->size = demux_aac_next (this, buf->content); if (buf->size > 0) { if (!this->frame_count) { buf->pts = this->base_pts; buf->extra_info->input_time = -1; } else if (this->samples_per_second) { buf->pts = this->base_pts + this->pts_offs + (int64_t)this->frame_num * 90000 * (int64_t)this->samples_per_frame / (int64_t)this->samples_per_second; buf->extra_info->input_time = buf->pts / 90; } else if (bitrate > 0) { buf->pts = this->base_pts; buf->extra_info->input_time = 8000 * current_pos / bitrate; } if (length > 0) buf->extra_info->input_normpos = (int)((double)current_pos * 65535 / length); this->audio_fifo->put (this->audio_fifo, buf); this->frame_num += this->frame_count; } else { buf->free_buffer (buf); this->status = DEMUX_FINISHED; } return this->status; } static void demux_aac_send_headers(demux_plugin_t *this_gen) { demux_aac_t *this = (demux_aac_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->pts_offs = this->input->get_optional_data (this->input, NULL, INPUT_OPTIONAL_DATA_PTSOFFS); this->status = DEMUX_OK; /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_AAC; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END; buf->content = NULL; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_aac_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_aac_t *this = (demux_aac_t *) this_gen; if (playing) { int ntime = 0; off_t pos = -1; uint32_t input_caps = this->input->get_capabilities (this->input); this->pts_offs = this->input->get_optional_data (this->input, NULL, INPUT_OPTIONAL_DATA_PTSOFFS); if (input_caps & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_TIME_SEEKABLE)) { /* this container has neither frame num nor pts. maybe input can help? */ if ((input_caps & INPUT_CAP_TIME_SEEKABLE) && start_time) { pos = this->input->seek_time (this->input, start_time, SEEK_SET); if (pos >= 0) ntime = this->input->get_current_time ? this->input->get_current_time (this->input) : 0; } else { off_t len = this->input->get_length (this->input); int br = _x_stream_info_get (this->stream, XINE_STREAM_INFO_AUDIO_BITRATE); if (len > 0) { pos = this->input->seek (this->input, (int64_t)len * start_pos / (int)0xffff, SEEK_SET); if (pos >= 0) ntime = br > 0 ? (int64_t)pos * 8000 / br : 0; } } if (pos >= 0) { this->base_pts = (int64_t)ntime * 90; this->frame_num = 0; this->bdelivered = 0; this->bgot = 0; this->seek_flag = 1; this->status = DEMUX_OK; } } } else { /* if thread is not running, initialize demuxer */ /* send new pts */ _x_demux_control_newpts (this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static int demux_aac_get_status (demux_plugin_t *this_gen) { demux_aac_t *this = (demux_aac_t *) this_gen; return this->status; } static int demux_aac_get_stream_length (demux_plugin_t *this_gen) { // demux_aac_t *this = (demux_aac_t *) this_gen; (void)this_gen; return 0; } static uint32_t demux_aac_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_aac_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_aac_t *this; demux_aac_mode_t mode; int id3v2_tag_size; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if ((id3v2_tag_size = probe_aac_file (stream, input, &mode)) < 0) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_aac_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->seek_flag = 0; this->pts_offs = 0; this->base_pts = 0; this->frame_num = 0; this->samples_per_frame = 0; this->samples_per_second = 0; this->bdelivered = 0; this->bgot = 0; #endif this->frame_count = 1; this->last_read_res = 1; this->stream = stream; this->input = input; this->mode = mode; this->id3v2_tag_size = id3v2_tag_size; this->demux_plugin.send_headers = demux_aac_send_headers; this->demux_plugin.send_chunk = demux_aac_send_chunk; this->demux_plugin.seek = demux_aac_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_aac_get_status; this->demux_plugin.get_stream_length = demux_aac_get_stream_length; this->demux_plugin.get_capabilities = demux_aac_get_capabilities; this->demux_plugin.get_optional_data = demux_aac_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; /* _x_stream_info_set(stream, XINE_STREAM_INFO_HAS_VIDEO, 0); */ _x_stream_info_set(stream, XINE_STREAM_INFO_HAS_AUDIO, 1); return &this->demux_plugin; } void *demux_aac_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_aac_class = { .open_plugin = open_plugin, .description = N_("ADIF/ADTS AAC demux plugin"), .identifier = "AAC", .mimetypes = NULL, .extensions = "aac", .dispose = NULL, }; return (void*)&demux_aac_class; } xine-lib-1.2/src/demuxers/demux_elem.c0000644000175000017500000001570614647725152015610 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demultiplexer for elementary mpeg streams */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_elem" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #include #define NUM_PREVIEW_BUFFERS 50 #define SCRATCH_SIZE 256 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; uint32_t blocksize; } demux_mpeg_elem_t ; static int demux_mpeg_elem_next (demux_mpeg_elem_t *this, int preview_mode) { buf_element_t *buf; uint32_t blocksize; off_t done; lprintf ("next piece\n"); buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); blocksize = (this->blocksize ? this->blocksize : (uint32_t)buf->max_size); done = this->input->read(this->input, buf->mem, blocksize); lprintf ("read size = %"PRId64"\n", done); if (done <= 0) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return 0; } buf->size = done; buf->content = buf->mem; buf->pts = 0; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); buf->type = BUF_VIDEO_MPEG; if (preview_mode) buf->decoder_flags = BUF_FLAG_PREVIEW; this->video_fifo->put(this->video_fifo, buf); return 1; } static int demux_mpeg_elem_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; if (!demux_mpeg_elem_next(this, 0)) this->status = DEMUX_FINISHED; return this->status; } static int demux_mpeg_elem_get_status (demux_plugin_t *this_gen) { demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; return this->status; } static void demux_mpeg_elem_send_headers (demux_plugin_t *this_gen) { demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->blocksize = this->input->get_blocksize(this->input); _x_demux_control_start(this->stream); if (INPUT_IS_SEEKABLE(this->input)) { int num_buffers = NUM_PREVIEW_BUFFERS; if (this->input->seek (this->input, 0, SEEK_SET) != 0) return; this->status = DEMUX_OK ; while ((num_buffers > 0) && (this->status == DEMUX_OK)) { demux_mpeg_elem_next(this, 1); num_buffers--; } } this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); } static int demux_mpeg_elem_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mpeg_elem_t *this = (demux_mpeg_elem_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); (void)start_time; this->status = DEMUX_OK; if (playing) _x_demux_flush_engine(this->stream); if (INPUT_IS_SEEKABLE(this->input)) { /* FIXME: implement time seek */ if (start_pos != this->input->seek (this->input, start_pos, SEEK_SET)) { this->status = DEMUX_FINISHED; return this->status; } lprintf ("seeking to %"PRId64"\n", start_pos); } /* * now start demuxing */ this->status = DEMUX_OK; return this->status; } static int demux_mpeg_elem_get_stream_length(demux_plugin_t *this_gen) { (void)this_gen; return 0 ; /*FIXME: implement */ } static uint32_t demux_mpeg_elem_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mpeg_elem_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_mpeg_elem_t *this; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint8_t scratch[SCRATCH_SIZE]; int i, read, found; read = _x_demux_read_header(input, scratch, SCRATCH_SIZE); if (!read) return NULL; found = 0; for (i = 0; i < read - 4; i++) { lprintf ("%02x %02x %02x %02x\n", scratch[i], scratch[i+1], scratch[i+2], scratch[i+3]); if ((scratch[i] == 0x00) && (scratch[i+1] == 0x00) && (scratch[i+2] == 0x01)) { if (scratch[i+3] == 0xb3) { found = 1; lprintf ("found header at offset 0x%x\n", i); break; } else return NULL; } } if (found == 0) return NULL; lprintf ("input accepted.\n"); } break; case METHOD_BY_MRL: break; case METHOD_EXPLICIT: break; default: return NULL; } this = calloc(1, sizeof(demux_mpeg_elem_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_mpeg_elem_send_headers; this->demux_plugin.send_chunk = demux_mpeg_elem_send_chunk; this->demux_plugin.seek = demux_mpeg_elem_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_mpeg_elem_get_status; this->demux_plugin.get_stream_length = demux_mpeg_elem_get_stream_length; this->demux_plugin.get_capabilities = demux_mpeg_elem_get_capabilities; this->demux_plugin.get_optional_data = demux_mpeg_elem_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } void *demux_elem_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_mpeg_elem_class = { .open_plugin = open_plugin, .description = N_("Elementary MPEG stream demux plugin"), .identifier = "MPEG_ELEM", .mimetypes = NULL, .extensions = "mpv", .dispose = NULL, }; return (void*)&demux_mpeg_elem_class; } xine-lib-1.2/src/demuxers/demux_matroska-chapters.c0000644000175000017500000002630014647725152020306 0ustar meme/* * Copyright (C) 2009-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for matroska streams: chapter handling * * TODO: * - nested chapters * * Authors: * Nicos Gollan */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "demux_matroska_chapters" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "ebml.h" #include "matroska.h" #include "demux_matroska.h" /* TODO: this only handles one single (title, language, country) tuple. * See the header for information. */ static int parse_chapter_display(demux_matroska_t *this, matroska_chapter_t *chap, int level) { ebml_parser_t *ebml = this->ebml; int next_level = level+1; char* tmp_name = NULL; char* tmp_lang = NULL; char* tmp_country = NULL; while (next_level == level+1) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CH_STRING: tmp_name = ebml_alloc_read_ascii(ebml, &elem); break; case MATROSKA_ID_CH_LANGUAGE: tmp_lang = ebml_alloc_read_ascii(ebml, &elem); break; case MATROSKA_ID_CH_COUNTRY: tmp_country = ebml_alloc_read_ascii(ebml, &elem); break; default: lprintf("Unhandled ID (inside ChapterDisplay): 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } if (NULL != chap->title) { chap->title = tmp_name; free(chap->language); chap->language = tmp_lang; free(chap->country); chap->country = tmp_country; } else if (tmp_lang != NULL && !strcmp("eng", tmp_lang) && (chap->language == NULL || strcmp("eng", chap->language))) { free(chap->title); chap->title = tmp_name; free(chap->language); chap->language = tmp_lang; free(chap->country); chap->country = tmp_country; } else { free(tmp_name); free(tmp_lang); free(tmp_country); } return 1; } static int parse_chapter_atom(demux_matroska_t *this, matroska_chapter_t *chap, int level) { ebml_parser_t *ebml = this->ebml; int next_level = level+1; uint64_t num; chap->time_start = 0; chap->time_end = 0; chap->hidden = 0; chap->enabled = 1; while (next_level == level+1) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) { lprintf("invalid head\n"); return 0; } switch (elem.id) { case MATROSKA_ID_CH_UID: if (!ebml_read_uint(ebml, &elem, &chap->uid)) { lprintf("invalid UID\n"); return 0; } break; case MATROSKA_ID_CH_TIMESTART: if (!ebml_read_uint(ebml, &elem, &chap->time_start)) { lprintf("invalid start time\n"); return 0; } /* convert to xine timing: Matroska timestamps are in nanoseconds, * xine's PTS are in 1/90,000s */ chap->time_start /= 100000; chap->time_start *= 9; break; case MATROSKA_ID_CH_TIMEEND: if (!ebml_read_uint(ebml, &elem, &chap->time_end)) { lprintf("invalid end time\n"); return 0; } /* convert to xine timing */ chap->time_end /= 100000; chap->time_end *= 9; break; case MATROSKA_ID_CH_DISPLAY: if (!ebml_read_master(ebml, &elem)) return 0; lprintf("ChapterDisplay\n"); if(!parse_chapter_display(this, chap, level+1)) { lprintf("invalid display information\n"); return 0; } break; case MATROSKA_ID_CH_HIDDEN: if (!ebml_read_uint(ebml, &elem, &num)) return 0; chap->hidden = (int)num; break; case MATROSKA_ID_CH_ENABLED: if (!ebml_read_uint(ebml, &elem, &num)) return 0; chap->enabled = (int)num; break; case MATROSKA_ID_CH_ATOM: /* TODO */ xprintf(this->stream->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": Warning: Nested chapters are not supported, playback may suffer!\n"); if (!ebml_skip(ebml, &elem)) return 0; break; case MATROSKA_ID_CH_TRACK: /* TODO */ xprintf(this->stream->xine, XINE_VERBOSITY_NONE, LOG_MODULE ": Warning: Specific track information in chapters is not supported, playback may suffer!\n"); if (!ebml_skip(ebml, &elem)) return 0; break; default: lprintf("Unhandled ID (inside ChapterAtom): 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } /* fallback information */ /* FIXME: check allocations! */ if (NULL == chap->title) { chap->title = strdup("No title"); } if (NULL == chap->language) { chap->language = strdup("unk"); } if (NULL == chap->country) { chap->country = strdup("XX"); } lprintf( "Chapter 0x%" PRIx64 ": %" PRIu64 "-%" PRIu64 "(pts), %s (%s). %shidden, %senabled.\n", chap->uid, chap->time_start, chap->time_end, chap->title, chap->language, (chap->hidden ? "" : "not "), (chap->enabled ? "" : "not ")); return 1; } static void free_chapter(matroska_chapter_t *chap) { free(chap->title); free(chap->language); free(chap->country); free(chap); } static int parse_edition_entry(demux_matroska_t *this, matroska_edition_t *ed) { ebml_parser_t *ebml = this->ebml; int next_level = 3; uint64_t num; int i; ed->hidden = 0; ed->is_default = 0; ed->ordered = 0; while (next_level == 3) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CH_ED_UID: if (!ebml_read_uint(ebml, &elem, &ed->uid)) return 0; break; case MATROSKA_ID_CH_ED_HIDDEN: if (!ebml_read_uint(ebml, &elem, &num)) return 0; ed->hidden = (int)num; break; case MATROSKA_ID_CH_ED_DEFAULT: if (!ebml_read_uint(ebml, &elem, &num)) return 0; ed->is_default = (int)num; break; case MATROSKA_ID_CH_ED_ORDERED: if (!ebml_read_uint(ebml, &elem, &num)) return 0; ed->ordered = (int)num; break; case MATROSKA_ID_CH_ATOM: { matroska_chapter_t *chapter = calloc(1, sizeof(matroska_chapter_t)); if (NULL == chapter) return 0; lprintf("ChapterAtom\n"); if (!ebml_read_master(ebml, &elem)) { free_chapter(chapter); return 0; } if (!parse_chapter_atom(this, chapter, next_level)) { free_chapter(chapter); return 0; } /* resize chapters array if necessary */ if (ed->num_chapters >= ed->cap_chapters) { matroska_chapter_t** old_chapters = ed->chapters; ed->cap_chapters += 10; ed->chapters = realloc(ed->chapters, ed->cap_chapters * sizeof(matroska_chapter_t*)); if (NULL == ed->chapters) { ed->chapters = old_chapters; ed->cap_chapters -= 10; free_chapter(chapter); return 0; } } ed->chapters[ed->num_chapters] = chapter; ++ed->num_chapters; break; } default: lprintf("Unhandled ID (inside EditionEntry): 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } xprintf( this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Edition 0x%" PRIx64 ": %shidden, %sdefault, %sordered. %d chapters:\n", ed->uid, (ed->hidden ? "" : "not "), (ed->is_default ? "" : "not "), (ed->ordered ? "" : "not "), ed->num_chapters ); for (i=0; inum_chapters; ++i) { matroska_chapter_t* chap = ed->chapters[i]; xprintf( this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Chapter %d: %" PRIu64 "-%" PRIu64 "(pts), %s (%s). %shidden, %senabled.\n", i+1, chap->time_start, chap->time_end, chap->title, chap->language, (chap->hidden ? "" : "not "), (chap->enabled ? "" : "not ")); } return 1; } static void free_edition(matroska_edition_t *ed) { int i; for(i=0; inum_chapters; ++i) { free_chapter(ed->chapters[i]); } free(ed->chapters); free(ed); } int matroska_parse_chapters(demux_matroska_t *this) { ebml_parser_t *ebml = this->ebml; int next_level = 2; while (next_level == 2) { ebml_elem_t elem; if (!ebml_read_elem_head(ebml, &elem)) return 0; switch (elem.id) { case MATROSKA_ID_CH_EDITIONENTRY: { matroska_edition_t *edition = calloc(1, sizeof(matroska_edition_t)); if (NULL == edition) return 0; lprintf("EditionEntry\n"); if (!ebml_read_master(ebml, &elem)) { free_edition(edition); return 0; } if (!parse_edition_entry(this, edition)) { free_edition(edition); return 0; } /* resize editions array if necessary */ if (this->num_editions >= this->cap_editions) { matroska_edition_t** old_editions = this->editions; this->cap_editions += 10; this->editions = realloc(this->editions, this->cap_editions * sizeof(matroska_edition_t*)); if (NULL == this->editions) { this->editions = old_editions; this->cap_editions -= 10; free_edition(edition); return 0; } } this->editions[this->num_editions] = edition; ++this->num_editions; break; } default: lprintf("Unhandled ID: 0x%x\n", elem.id); if (!ebml_skip(ebml, &elem)) return 0; } next_level = ebml_get_next_level(ebml, &elem); } return 1; } void matroska_free_editions(demux_matroska_t *this) { int i; for(i=0; inum_editions; ++i) { free_edition(this->editions[i]); } free(this->editions); this->num_editions = 0; this->cap_editions = 0; } int matroska_get_chapter(demux_matroska_t *this, uint64_t tc, matroska_edition_t** ed) { uint64_t block_pts = (tc * this->timecode_scale) / 100000 * 9; int chapter_idx = 0; if (this->num_editions < 1) return -1; while (chapter_idx < (*ed)->num_chapters && block_pts > (*ed)->chapters[chapter_idx]->time_start) ++chapter_idx; if (chapter_idx > 0) --chapter_idx; return chapter_idx; } xine-lib-1.2/src/demuxers/demux_str.c0000644000175000017500000005031314647725152015467 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * STR File Demuxer by Mike Melanson (melanson@pcisys.net) * and Stuart Caie (kyzer@4u.net) * This demuxer handles either raw STR files (which are just a concatenation * of raw compact disc sectors) or STR files with RIFF headers. */ /* * CD-XA format: * * - the format is a series of 2352 byte CD sectors * - 0x000: 12 bytes: sync header (00 FF FF FF FF FF FF FF FF FF FF 00) * - 0x00C: 4 bytes: timecode (mm ss ff 02; BCD, not decimal!) * - 0x010: 4 bytes: sector parameters * - 0x10 file_num * - 0x11 channel_num * - 0x12 subcode * - 0x13 coding_info * - 0x014: 4 bytes: copy of parameters (should be identical) * - 0x018: 2324 bytes: sector data * - 0x92C: 4 bytes: EDC error correction code * - 0x930: SIZEOF * * - file_num is purely to distinguish where a 'file' ends and a new * 'file' begins among the sectors. It's usually 1. * - channel_num is a sub-channel in this 'file'. Video, audio and data * sectors can be mixed into the same channel or can be on seperate * channels. Usually used for multiple audio tracks (e.g. 5 different * songs in the same 'file', on channels 0, 1, 2, 3 and 4) * - subcode is a set of bits * - bit 7: eof_marker -- 0, or 1 if this sector is the end of the 'file' * - bit 6: real_time -- unimportant (always set in PSX STR streams) * - bit 5: form -- unimportant * - bit 4: trigger -- for use by reader application (unimportant) * - bit 3: DATA -- set to 1 to indicate DATA sector, otherwise 0 * - bit 2: AUDIO -- set to 1 to indicate AUDIO sector, otherwise 0 * - bit 1: VIDEO -- set to 1 to indicate VIDEO sector, otherwise 0 * - bit 0: end_audio -- end of audio frame (never set in PSX STR streams) * - bits 1, 2 and 3 are mutually exclusive * - coding_info is a set of bits, interpretation is dependant on the * DATA/AUDIO/VIDEO bits setting of subcode. * - For AUDIO: * - bit 7: reserved -- should always be 0 * - bit 6: emphasis -- boost audio volume (ignored by us) * - bit 5: bitssamp -- must always be 0 * - bit 4: bitssamp -- 0 for mode B/C (4 bits/sample, 8 sound sectors) * 1 for mode A (8 bits/sample, 4 sound sectors) * - bit 3: samprate -- must always be 0 * - bit 2: samprate -- 0 for 37.8kHz playback, 1 for 18.9kHz playback * - bit 1: stereo -- must always be 0 * - bit 0: stereo -- 0 for mono sound, 1 for stereo sound * - For DATA or VIDEO: * - always seems to be 0 in PSX STR files * * Format of sector data in AUDIO sectors: * - 18 "sound groups" of 128 byte structures * - 20 unused bytes * - we pass these 18*128 bytes to the XA_ADPCM audio decoder * * Format of sector data in DATA or VIDEO sectors: * - all values are little-endian * - 0x00: 32 bits; unknown -- usually 0x80010160 for a video frame. * according to PSX hardware guide, this value is written * to mdec0 register: * - bit 27: 1 for 16-bit colour, 0 for 24-bit colour depth * - bit 24: if 16-bit colour, 1/0=set/clear transparency bit * - all other bits unknown * - if not set to this value, it's not a video sector. * - 0x04: 16 bits; 'chunk number' of this video frame (0 to numchunks-1) * - 0x06: 16 bits; number of chunks in this frame * - 0x08: 32 bits; frame number (1 to ...) * - 0x0C: 32 bits; seemingly random number. frame duration? * - 0x10: 16 bits; width of frame in pixels * - 0x12: 16 bits; height of frame in pixels * - remainder of data (up to 2304 bytes): compressed MDEC stream * - 32 bits: (0x3800 << 16) | size of data (in bytes) following this header * - any number of macroblocks (which each represent a 16x16 pixel area) * - a macroblock is 6 blocks (Cb, Cr, Y0, Y1, Y2 and Y3) * - a block is a DCT setting then an RLE data stream * - 16 bits: DCT (bits 15-10: quantisation factor (unsigned) * bits 9-0: Direct Current reference (signed)) * - then follows 16-bit RLE data until the EOD * - RLE format: bits 15-10: # of 0s preceding this value (unsigned) * bits 9-0: this value (signed) * - e.g. 3 bytes (2,10)(0,20)(3,30) -> 0 0 10 20 0 0 0 30 * - 16 bits: EOD (0xFE00) * - 16 bits: 0xFE00 end-of-data footer */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_str" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" /* There may be a RIFF/CDXA header at the beginning of the file, which * accounts for 0x2C bytes. We need at most 0x30 bytes of the sector to * verify whether it's a CDXA/MDEC file */ #define STR_CHECK_BYTES (0x2C + 0x30) #define CD_RAW_SECTOR_SIZE 2352 #define STR_MAGIC "\x60\x01\x01\x80" #define STR_MAX_CHANNELS 32 #define CDXA_TYPE_MASK 0x0E #define CDXA_TYPE_DATA 0x08 #define CDXA_TYPE_AUDIO 0x04 #define CDXA_TYPE_VIDEO 0x02 #define CDXA_SUBMODE_EOF 0x80 /* set if EOF */ /* FIXME */ #define FRAME_DURATION 45000 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_start; off_t data_size; off_t current_pos; xine_bmiheader bih[STR_MAX_CHANNELS]; unsigned char audio_info[STR_MAX_CHANNELS]; unsigned char channel_type[STR_MAX_CHANNELS]; int64_t audio_pts[STR_MAX_CHANNELS]; int seek_flag; int default_video_channel; } demux_str_t; /* returns 1 if the STR file was opened successfully, 0 otherwise */ static int open_str_file(demux_str_t *this) { unsigned char check_bytes[STR_CHECK_BYTES]; int local_offset, sector, channel; memset(this->channel_type, 0, sizeof(this->channel_type)); if (this->input->seek(this->input, 0, SEEK_SET) != 0) return 0; if (this->input->read(this->input, check_bytes, STR_CHECK_BYTES) != STR_CHECK_BYTES) { lprintf("read error\n"); return 0; } /* check for STR with a RIFF header */ if ( _x_is_fourcc(&check_bytes[0], "RIFF") && _x_is_fourcc(&check_bytes[8], "CDXA") ) local_offset = 0x2C; else local_offset = 0; this->data_start = (off_t) local_offset; /* we need to check up to 32 sectors for up to 32 audio/video channels */ for (sector = 0; sector < STR_MAX_CHANNELS; sector++) { lprintf("file=%d channel=%-2d submode=%02x coding_info=%02x\n", check_bytes[local_offset + 0x10], check_bytes[local_offset + 0x11], check_bytes[local_offset + 0x12], check_bytes[local_offset + 0x13]); /* check for 12-byte sync marker */ static const uint8_t sync_marker[12] = { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0X00 }; if ( memcmp(&check_bytes[local_offset], sync_marker, sizeof(sync_marker)) != 0 ) { lprintf("sector %d sync error\n", sector); return 0; } /* the 32 bits starting at 0x10 and at 0x14 should be the same */ if (memcmp(&check_bytes[local_offset + 0x10], &check_bytes[local_offset + 0x14], 4) != 0) { lprintf("sector %d control bits copy error\n", sector); return 0; } /* channel should be from 0 to 31 */ channel = check_bytes[local_offset + 0x11]; if (channel >= STR_MAX_CHANNELS) { lprintf("sector %d channel %d error\n", sector, channel); return 0; } /* switch on the sector type */ switch(check_bytes[local_offset + 0x12] & CDXA_TYPE_MASK) { case CDXA_TYPE_DATA: case CDXA_TYPE_VIDEO: /* first time we have seen video/data in this channel? */ if ((!(this->channel_type[channel] & CDXA_TYPE_DATA)) && (_x_is_fourcc(&check_bytes[local_offset + 0x18], STR_MAGIC))) { /* mark this channel as having video data */ this->channel_type[channel] |= CDXA_TYPE_VIDEO; this->bih[channel].biWidth = _X_LE_16(&check_bytes[local_offset + 0x18 + 0x10]); this->bih[channel].biHeight = _X_LE_16(&check_bytes[local_offset + 0x18 + 0x12]); } break; case CDXA_TYPE_AUDIO: /* first time we have seen audio in this channel? */ if (!(this->channel_type[channel] & CDXA_TYPE_AUDIO)) { /* mark this channel as having audio data */ this->channel_type[channel] |= CDXA_TYPE_AUDIO; this->audio_info[channel] = check_bytes[local_offset + 0x13]; } break; default: lprintf("sector %d channel %d unknown type error\n", sector, channel); /* several films (e.g. 37xa16.xap in Strider 1) have empty * sectors with 0 as the type, despite having plenty of * video/audio sectors */ /*return 0*/; } /* seek to the next sector and read in the header */ local_offset = 0; if (this->input->seek(this->input, this->data_start + ((sector+1) * CD_RAW_SECTOR_SIZE), SEEK_SET) < 0) { lprintf("sector %d seek error\n", sector); return 0; } if (this->input->read(this->input, check_bytes, 0x30) != 0x30) { lprintf("sector %d read error\n", sector); return 0; } } if(this->channel_type[0] == 0) return 0; /* acceptable STR file */ this->data_size = this->input->get_length(this->input) - this->data_start; #ifdef LOG for (channel = 0; channel < STR_MAX_CHANNELS; channel++) { char vidinfo[22]; /* "Video (XXXXX x XXXXX)" */ char audinfo[33]; /* "Audio (XX.XkHz XXXXXX, mode XXX)" */ if (this->channel_type[channel]) { if (this->channel_type[channel] & CDXA_TYPE_VIDEO) { snprintf(vidinfo, 22, "Video (%d x %d)", this->bih[channel].biWidth, this->bih[channel].biHeight); } else { strcpy(vidinfo, "No video"); } if (this->channel_type[channel] & CDXA_TYPE_AUDIO) { snprintf(audinfo, 33, "Audio (%skHz %s, mode %s)", this->audio_info[channel] & 0x04 ? "18.9" : "37.8", this->audio_info[channel] & 0x01 ? "stereo" : "mono", this->audio_info[channel] & 0x10 ? "A" : "B/C"); } else { strcpy(audinfo, "No audio"); } lprintf("channel %-2d %-22s%s\n", channel, vidinfo, audinfo); } } #endif return 1; } static int demux_str_send_chunk(demux_plugin_t *this_gen) { demux_str_t *this = (demux_str_t *) this_gen; unsigned char sector[CD_RAW_SECTOR_SIZE], channel; uint32_t frame_number; buf_element_t *buf; off_t current_pos; current_pos = this->current_pos; this->current_pos += CD_RAW_SECTOR_SIZE; if (this->input->read(this->input, sector, CD_RAW_SECTOR_SIZE) != CD_RAW_SECTOR_SIZE) { this->status = DEMUX_FINISHED; return this->status; } channel = sector[0x11]; if (channel >= STR_MAX_CHANNELS) return 0; switch (sector[0x12] & CDXA_TYPE_MASK) { case CDXA_TYPE_VIDEO: case CDXA_TYPE_DATA: /* video chunk */ if (!_x_is_fourcc(§or[0x18], STR_MAGIC) || channel != this->default_video_channel) { return 0; } frame_number = _X_LE_32(§or[0x18 + 0x08]); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->pts = frame_number * FRAME_DURATION; if (this->seek_flag) { _x_demux_control_newpts(this->stream, buf->pts, BUF_FLAG_SEEK); this->seek_flag = 0; } /* first chunk of frame? sync forthcoming audio packets */ /* FIXME */ /*if (_X_LE_16(§or[0x18+0x04]) == 0) { * int i; * for (i = 0; i < STR_MAX_CHANNELS; i++) this->audio_pts[i] = buf->pts; *} */ if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_pos * 65535 / this->data_size ); buf->extra_info->input_time = (current_pos*1000)/(CD_RAW_SECTOR_SIZE*75); /* constant size chunk */ buf->size = 2304; xine_fast_memcpy(buf->content, §or[0x18+0x14], 2304); /* entirely intracoded */ buf->decoder_flags |= BUF_FLAG_KEYFRAME; /* if the current chunk is 1 less than the chunk count, this is the * last chunk of the frame */ if ((_X_LE_16(§or[0x18+0x04]) + 1) == _X_LE_16(§or[0x18+0x06])) buf->decoder_flags |= BUF_FLAG_FRAME_END; buf->type = BUF_VIDEO_PSX_MDEC | channel; this->video_fifo->put(this->video_fifo, buf); break; case CDXA_TYPE_AUDIO: /* audio frame */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->pts = this->audio_pts[channel]; this->audio_pts[channel] += (((sector[0x13] & 0x10) ? 2016 : 4032) * ((sector[0x13] & 0x01) ? 45000 : 90000)) / ((sector[0x13] & 0x04) ? 18900 : 37800); if (this->seek_flag) { _x_demux_control_newpts(this->stream, buf->pts, BUF_FLAG_SEEK); this->seek_flag = 0; } if( this->data_size ) buf->extra_info->input_normpos = (int)( (double) current_pos * 65535 / this->data_size ); buf->extra_info->input_time = (current_pos*1000)/(CD_RAW_SECTOR_SIZE*75); buf->size = 2304; xine_fast_memcpy(buf->content, §or[0x18], 2304); buf->type = BUF_AUDIO_XA_ADPCM | channel; buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put (this->audio_fifo, buf); } break; } return this->status; } static void demux_str_send_headers(demux_plugin_t *this_gen) { demux_str_t *this = (demux_str_t *) this_gen; buf_element_t *buf; char audio_info; int channel, video_channel = -1; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* send start buffers */ _x_demux_control_start(this->stream); /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_SEEKABLE, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); for (channel = 0; channel < STR_MAX_CHANNELS; channel++) { if (this->channel_type[channel] & CDXA_TYPE_VIDEO) { if (video_channel == -1) { /* FIXME: until I figure out how to comfortably let the user * pick a video channel, just pick a single video channel */ video_channel = this->default_video_channel = channel; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih[channel].biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih[channel].biHeight); /* send init info to video decoder */ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = FRAME_DURATION; /* initial video_step */ buf->size = sizeof(xine_bmiheader); memcpy(buf->content, &this->bih[channel], buf->size); buf->type = BUF_VIDEO_PSX_MDEC; this->video_fifo->put (this->video_fifo, buf); } } if (this->channel_type[channel] & CDXA_TYPE_AUDIO) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); audio_info = this->audio_info[channel]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, (audio_info & 0x01) ? 2 : 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, (audio_info & 0x04) ? 18900 : 37800); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, 16); /* send init info to the audio decoder */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_XA_ADPCM | channel; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = (audio_info & 0x04) ? 18900 : 37800; buf->decoder_info[2] = (audio_info & 0x10) ? 1 : 0; buf->decoder_info[3] = (audio_info & 0x01) ? 2 : 1; this->audio_fifo->put (this->audio_fifo, buf); this->audio_pts[channel] = 0; } } } } static int demux_str_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_str_t *this = (demux_str_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); (void)start_time; (void)playing; _x_demux_flush_engine (this->stream); /* round to ensure we start on a sector */ start_pos /= CD_RAW_SECTOR_SIZE; lprintf("seeking to sector %d (%02d:%02d)\n", (int)start_pos, (int)start_pos / (60*75), ((int)start_pos / 75)%60); /* reposition at the chosen sector */ this->current_pos = start_pos * CD_RAW_SECTOR_SIZE; this->input->seek(this->input, this->data_start+this->current_pos, SEEK_SET); this->seek_flag = 1; this->status = DEMUX_OK; return this->status; } static int demux_str_get_status (demux_plugin_t *this_gen) { demux_str_t *this = (demux_str_t *) this_gen; return this->status; } static int demux_str_get_stream_length (demux_plugin_t *this_gen) { demux_str_t *this = (demux_str_t *) this_gen; return (int)((int64_t) this->input->get_length(this->input) * 1000 / (CD_RAW_SECTOR_SIZE * 75)); } static uint32_t demux_str_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_str_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_str_t *this; if (!INPUT_IS_SEEKABLE(input)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input not seekable, can not handle!\n"); return NULL; } this = calloc(1, sizeof(demux_str_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_str_send_headers; this->demux_plugin.send_chunk = demux_str_send_chunk; this->demux_plugin.seek = demux_str_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_str_get_status; this->demux_plugin.get_stream_length = demux_str_get_stream_length; this->demux_plugin.get_capabilities = demux_str_get_capabilities; this->demux_plugin.get_optional_data = demux_str_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_str_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_str_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_str_class = { .open_plugin = open_plugin, .description = N_("Sony Playstation STR file demux plugin"), .identifier = "PSX STR", .mimetypes = NULL, .extensions = "str iki ik2 dps dat xa xa1 xa2 xas xap", .dispose = NULL, }; return (void *)&demux_str_class; } xine-lib-1.2/src/demuxers/demux_yuv4mpeg2.c0000644000175000017500000003312414647725152016522 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * YUV4MPEG2 File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the YUV4MPEG2 file format and associated * tools, visit: * http://mjpeg.sourceforge.net/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #define LOG_MODULE "demux_yuv4mpeg2" #include "group_video.h" #include #include #include #include #include "bswap.h" #define Y4M_SIGNATURE_SIZE 9 #define Y4M_SIGNATURE "YUV4MPEG2" #define Y4M_FRAME_SIGNATURE_SIZE 6 #define Y4M_FRAME_SIGNATURE "FRAME\x0A" /* number of header bytes is completely arbitrary */ #define Y4M_HEADER_BYTES 100 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t data_start; off_t data_size; xine_bmiheader bih; int fps_n; int fps_d; int aspect_n; int aspect_d; int progressive; int top_field_first; int color_matrix; unsigned int frame_pts_inc; unsigned int frame_size; int seek_flag; } demux_yuv4mpeg2_t; /* returns 1 if the YUV4MPEG2 file was opened successfully, 0 otherwise */ static int open_yuv4mpeg2_file(demux_yuv4mpeg2_t *this) { char header[Y4M_HEADER_BYTES+1]; char *header_ptr, *header_endptr, *header_end; this->bih.biWidth = this->bih.biHeight = this->fps_n = this->fps_d = this->aspect_n = this->aspect_d = this->progressive = this->top_field_first = this->data_start = 0; this->color_matrix = 4; /* undefined, mpeg range */ if (_x_demux_read_header(this->input, header, Y4M_HEADER_BYTES) != Y4M_HEADER_BYTES) return 0; /* check for the Y4M signature */ if (memcmp(header, Y4M_SIGNATURE, Y4M_SIGNATURE_SIZE) != 0) return 0; /* null terminate the read data */ header[Y4M_HEADER_BYTES] = '\0'; /* check for stream header terminator */ if ((header_end = strchr(header, '\n')) == NULL) return 0; /* read tagged fields in stream header */ header_ptr = &header[Y4M_SIGNATURE_SIZE]; while (header_ptr < header_end) { /* tagged fields should all start with a space */ if(*header_ptr != ' ') break; else header_ptr++; switch (*header_ptr) { case 'W': /* read the width */ this->bih.biWidth = strtol(header_ptr + 1, &header_endptr, 10); if(header_endptr == header_ptr + 1) return 0; else header_ptr = header_endptr; break; case 'H': /* read the height */ this->bih.biHeight = strtol(header_ptr + 1, &header_endptr, 10); if (header_endptr == header_ptr + 1) return 0; else header_ptr = header_endptr; break; case 'I': /* read interlacing spec */ switch (*(header_ptr + 1)) { case 'p': this->progressive = 1; break; case 't': this->top_field_first = 1; break; case 'b': case '?': default: break; } header_ptr += 2; break; case 'F': /* read frame rate - stored as a ratio * numberator */ this->fps_n = strtol(header_ptr + 1, &header_endptr, 10); if ((header_endptr == header_ptr + 1) || (*header_endptr != ':')) return 0; else header_ptr = header_endptr; /* denominator */ this->fps_d = strtol(header_ptr + 1, &header_endptr, 10); if (header_endptr == header_ptr + 1) return 0; else header_ptr = header_endptr; break; case 'A': /* read aspect ratio - stored as a ratio(!) * numerator */ this->aspect_n = strtol(header_ptr + 1, &header_endptr, 10); if ((header_endptr == header_ptr + 1) || (*header_endptr != ':')) return 0; else header_ptr = header_endptr; /* denominator */ this->aspect_d = strtol(header_ptr + 1, &header_endptr, 10); if (header_endptr == header_ptr + 1) return 0; else header_ptr = header_endptr; break; case 'X': /* private extra info */ if (!strncasecmp (header_ptr + 1, "XINE_CM=", 8)) { int i = strtol(header_ptr + 9, &header_endptr, 10); if (header_endptr > header_ptr + 9) { this->color_matrix = i; header_ptr = header_endptr; break; } } /* fall through */ default: /* skip whatever this is */ while ((*header_ptr != ' ') && (header_ptr < header_end)) header_ptr++; } } /* make sure all the data was found */ if (!this->bih.biWidth || !this->bih.biHeight || !this->fps_n || !this->fps_d) return 0; /* compute the size of an individual frame */ this->frame_size = this->bih.biWidth * this->bih.biHeight * 3 / 2; /* pts difference between frames */ this->frame_pts_inc = (90000 * this->fps_d) / this->fps_n; /* finally, look for the first frame */ size_t left = (size_t)Y4M_HEADER_BYTES - (size_t)(header_ptr - header); char *data_start_ptr = memmem(header_ptr, left, "FRAME", 5); /* make sure the first frame was found */ if ( !data_start_ptr ) { return 0; } this->data_start = data_start_ptr - header; /* compute size of all frames */ if (INPUT_IS_SEEKABLE(this->input)) { this->data_size = this->input->get_length(this->input) - this->data_start; } /* file is qualified; seek to first frame */ if (this->input->seek(this->input, this->data_start, SEEK_SET) != this->data_start) return 0; return 1; } static int demux_yuv4mpeg2_send_chunk(demux_plugin_t *this_gen) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; /* validate that this is an actual frame boundary */ { uint8_t preamble[Y4M_FRAME_SIGNATURE_SIZE]; if (this->input->read(this->input, preamble, Y4M_FRAME_SIGNATURE_SIZE) != Y4M_FRAME_SIGNATURE_SIZE) { this->status = DEMUX_FINISHED; return this->status; } if (memcmp(preamble, Y4M_FRAME_SIGNATURE, Y4M_FRAME_SIGNATURE_SIZE) != 0) { this->status = DEMUX_FINISHED; return this->status; } } /* load and dispatch the raw frame */ int bytes_remaining = this->frame_size; off_t current_file_pos = this->input->get_current_pos(this->input) - this->data_start; int64_t pts = current_file_pos; pts /= (this->frame_size + Y4M_FRAME_SIGNATURE_SIZE); pts *= this->frame_pts_inc; /* reset the pts after a seek */ if (this->seek_flag) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->seek_flag = 0; } while(bytes_remaining) { buf_element_t *buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, bytes_remaining); buf->type = BUF_VIDEO_I420; if( this->data_size ) buf->extra_info->input_normpos = (int)((double) current_file_pos * 65535 / this->data_size); buf->extra_info->input_time = pts / 90; buf->pts = pts; buf->decoder_flags |= BUF_FLAG_COLOR_MATRIX; buf->decoder_info[4] = this->color_matrix; buf->size = MIN(bytes_remaining, buf->max_size); bytes_remaining -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!bytes_remaining) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->video_fifo->put(this->video_fifo, buf); } return this->status; } static void demux_yuv4mpeg2_send_headers(demux_plugin_t *this_gen) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ buf_element_t *buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->frame_pts_inc; /* initial video step */ if(this->aspect_n && this->aspect_d) { buf->decoder_flags |= BUF_FLAG_ASPECT; buf->decoder_info[1] = this->bih.biWidth * this->aspect_n; buf->decoder_info[2] = this->bih.biHeight * this->aspect_d; } buf->decoder_info[3] = this->progressive; buf->decoder_info[4] = this->top_field_first; memcpy(buf->content, &this->bih, sizeof(this->bih)); buf->size = sizeof(this->bih); buf->type = BUF_VIDEO_I420; this->video_fifo->put (this->video_fifo, buf); } static int demux_yuv4mpeg2_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; start_time /= 1000; start_pos = (off_t) ( (double) start_pos / 65535 * this->data_size ); if (INPUT_IS_SEEKABLE(this->input)) { /* YUV4MPEG2 files are essentially constant bit-rate video. Seek along * the calculated frame boundaries. Divide the requested seek offset * by the frame size integer-wise to obtain the desired frame number * and then multiply the frame number by the frame size to get the * starting offset. Add the data_start offset to obtain the final * offset. */ start_pos /= (this->frame_size + Y4M_FRAME_SIGNATURE_SIZE); start_pos *= (this->frame_size + Y4M_FRAME_SIGNATURE_SIZE); start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); } this->seek_flag = 1; this->status = DEMUX_OK; _x_demux_flush_engine (this->stream); /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static int demux_yuv4mpeg2_get_status (demux_plugin_t *this_gen) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; return this->status; } static int demux_yuv4mpeg2_get_stream_length (demux_plugin_t *this_gen) { demux_yuv4mpeg2_t *this = (demux_yuv4mpeg2_t *) this_gen; return (int)(((int64_t) this->data_size * 1000 * this->fps_d) / ((this->frame_size + Y4M_FRAME_SIGNATURE_SIZE) * this->fps_n)); } static uint32_t demux_yuv4mpeg2_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_yuv4mpeg2_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_yuv4mpeg2_t *this; this = calloc(1, sizeof(demux_yuv4mpeg2_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_yuv4mpeg2_send_headers; this->demux_plugin.send_chunk = demux_yuv4mpeg2_send_chunk; this->demux_plugin.seek = demux_yuv4mpeg2_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_yuv4mpeg2_get_status; this->demux_plugin.get_stream_length = demux_yuv4mpeg2_get_stream_length; this->demux_plugin.get_capabilities = demux_yuv4mpeg2_get_capabilities; this->demux_plugin.get_optional_data = demux_yuv4mpeg2_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_yuv4mpeg2_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_yuv4mpeg2_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_yuv4mpeg2_class = { .open_plugin = open_plugin, .description = N_("YUV4MPEG2 file demux plugin"), .identifier = "YUV4MPEG2", .mimetypes = NULL, .extensions = "y4m", .dispose = NULL, }; return (void *)&demux_yuv4mpeg2_class; } xine-lib-1.2/src/demuxers/demux_mpeg_block.c0000644000175000017500000013327514647725152016772 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for mpeg 1/2 program streams * used with fixed blocksize devices (like dvd/vcd) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_mpeg_block" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #define NUM_PREVIEW_BUFFERS 250 #define DISC_TRESHOLD 90000 #define WRAP_THRESHOLD 120000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) typedef struct demux_mpeg_block_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int blocksize; int rate; int64_t nav_last_end_pts; int64_t nav_last_start_pts; int64_t last_pts[2]; int send_newpts; int preview_mode; int buf_flag_seek; int64_t scr; uint32_t packet_len; int64_t pts; int64_t dts; uint32_t stream_id; int32_t mpeg1; int64_t last_cell_time; off_t last_cell_pos; int last_begin_time; } demux_mpeg_block_t ; static int32_t parse_video_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_audio_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_ancillary_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_system_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_private_stream_2(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_map(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_padding_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_ecm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_emm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_dsmcc_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_emm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_iec_13522_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeA_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeB_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeC_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeD_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_h222_typeE_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_directory(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); static int32_t parse_program_stream_pack_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf); /* OK, i think demux_mpeg_block discontinuity handling demands some explanation: - The preferred discontinuity handling/detection for DVD is based on NAV packets information. Most of the time it will provide us very accurate and reliable information. - Has been shown that sometimes a DVD discontinuity may happen before a new NAV packet arrives (seeking?). To avoid sending wrong PTS to decoders we _used_ to check for SCR discontinuities. Unfortunately some VCDs have very broken SCR values causing false triggering. - To fix the above problem (also note that VCDs don't have NAV packets) we fallback to the same PTS-based wrap detection as used in demux_mpeg. The only trick is to not send discontinuity information if NAV packets have already done the job. [Miguel 02-05-2002] */ static void check_newpts( demux_mpeg_block_t *this, int64_t pts, int video ) { int64_t diff; diff = pts - this->last_pts[video]; if( pts && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { /* check if pts is outside nav pts range. any stream without nav must enter here. */ if( pts > this->nav_last_end_pts || pts < this->nav_last_start_pts ) { lprintf("discontinuity detected by pts wrap\n"); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; } else { lprintf("no wrap detected\n" ); } this->last_pts[1-video] = 0; } if( pts ) this->last_pts[video] = pts; } static void demux_mpeg_block_parse_pack (demux_mpeg_block_t *this, int preview_mode) { buf_element_t *buf = NULL; uint8_t *p; int32_t result; this->scr = 0; this->preview_mode = preview_mode; lprintf ("read_block\n"); buf = this->input->read_block (this->input, this->video_fifo, this->blocksize); if (buf==NULL) { this->status = DEMUX_FINISHED; return ; } /* If this is not a block for the demuxer, pass it straight through to who might need it. */ if (buf->type != BUF_DEMUX_BLOCK) { uint32_t stype = buf->type & BUF_MAJOR_MASK; lprintf ("type %08x != BUF_DEMUX_BLOCK\n", buf->type); if (stype == BUF_CONTROL_BASE) { stype = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); if (stype == BUF_CONTROL_SPU_CHANNEL) stype = 1; else if (stype == BUF_CONTROL_AUDIO_CHANNEL) stype = 2; else stype = 3; } else if (stype == BUF_AUDIO_BASE) { stype = 2; } else { /* (stype = BUF_VIDEO_BASE) || (stype == BUF_SPU_BASE) */ stype = 1; } switch (stype) { case 2: if (this->audio_fifo) this->audio_fifo->put (this->audio_fifo, buf); else buf->free_buffer (buf); break; case 3: if (this->audio_fifo) { /* duplicate goes to audio fifo */ buf_element_t *abuf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); memcpy (abuf->decoder_info, buf->decoder_info, sizeof (buf->decoder_info)); memcpy (abuf->decoder_info_ptr, buf->decoder_info_ptr, sizeof (buf->decoder_info_ptr)); abuf->type = buf->type; abuf->decoder_flags = buf->decoder_flags; this->audio_fifo->put (this->audio_fifo, abuf); } /* fall through */ case 1: this->video_fifo->put (this->video_fifo, buf); } return; } p = buf->content; /* len = this->blocksize; */ if (preview_mode) buf->decoder_flags = BUF_FLAG_PREVIEW; else buf->decoder_flags = 0; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); while(p < (buf->content + this->blocksize)) { if (p[0] || p[1] || (p[2] != 1)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_mpeg_block: error! %02x %02x %02x (should be 0x000001)\n", p[0], p[1], p[2]); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_mpeg_block: bad block. skipping.\n"); /* FIXME: We should find some way for the input plugin to inform us of: - * 1) Normal sector read. * 2) Sector error read due to bad crc etc. * Because we would like to handle these two cases differently. */ buf->free_buffer (buf); return; } this->stream_id = p[3]; if (this->stream_id == 0xBA) { result = parse_program_stream_pack_header(this, p, buf); } else if (this->stream_id == 0xBB) { result = parse_program_stream_system_header(this, p, buf); } else if (this->stream_id == 0xBC) { result = parse_program_stream_map(this, p, buf); } else if (this->stream_id == 0xBD) { result = parse_private_stream_1(this, p, buf); } else if (this->stream_id == 0xBE) { result = parse_padding_stream(this, p, buf); } else if (this->stream_id == 0xBF) { result = parse_private_stream_2(this, p, buf); } else if ((this->stream_id >= 0xC0) && (this->stream_id < 0xDF)) { result = parse_audio_stream(this, p, buf); } else if ((this->stream_id >= 0xE0) && (this->stream_id < 0xEF)) { result = parse_video_stream(this, p, buf); } else if (this->stream_id == 0xF0) { result = parse_ecm_stream(this, p, buf); } else if (this->stream_id == 0xF1) { result = parse_emm_stream(this, p, buf); } else if (this->stream_id == 0xF2) { result = parse_dsmcc_stream(this, p, buf); } else if (this->stream_id == 0xF3) { result = parse_iec_13522_stream(this, p, buf); } else if (this->stream_id == 0xF4) { result = parse_h222_typeA_stream(this, p, buf); } else if (this->stream_id == 0xF5) { result = parse_h222_typeB_stream(this, p, buf); } else if (this->stream_id == 0xF6) { result = parse_h222_typeC_stream(this, p, buf); } else if (this->stream_id == 0xF7) { result = parse_h222_typeD_stream(this, p, buf); } else if (this->stream_id == 0xF8) { result = parse_h222_typeE_stream(this, p, buf); } else if (this->stream_id == 0xF9) { result = parse_ancillary_stream(this, p, buf); } else if (this->stream_id == 0xFA) { result = parse_IEC14496_SL_packetized_stream(this, p, buf); } else if (this->stream_id == 0xFB) { result = parse_IEC14496_FlexMux_stream(this, p, buf); /* 0xFC, 0xFD, 0xFE reserved */ } else if (this->stream_id == 0xFF) { result = parse_program_stream_directory(this, p, buf); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("xine-lib:demux_mpeg_block: " "Unrecognised stream_id 0x%02x. Please report this to xine developers.\n"), this->stream_id); buf->free_buffer (buf); return; } if (result < 0) { return; } p+=result; } xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("demux_mpeg_block: error! freeing. Please report this to xine developers.\n")); buf->free_buffer (buf); return ; } static int32_t parse_padding_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* Just skip padding. */ (void)this; (void)p; buf->free_buffer (buf); return -1; } static int32_t parse_program_stream_map(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x.\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_ecm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_emm_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_dsmcc_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_iec_13522_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeA_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeB_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeC_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeD_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_h222_typeE_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_IEC14496_SL_packetized_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_IEC14496_FlexMux_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_program_stream_directory(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_ancillary_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* FIXME: Implement */ (void)p; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "xine-lib:demux_mpeg_block: Unhandled stream_id 0x%02x\n", this->stream_id); buf->free_buffer (buf); return -1; } static int32_t parse_program_stream_pack_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* program stream pack header */ (void)buf; this->mpeg1 = (p[4] & 0x40) == 0; if (this->mpeg1) { /* system_clock_reference */ this->scr = (int64_t)(p[4] & 0x02) << 30; this->scr |= (p[5] & 0xFF) << 22; this->scr |= (p[6] & 0xFE) << 14; this->scr |= (p[7] & 0xFF) << 7; this->scr |= (p[8] & 0xFE) >> 1; /* buf->scr = scr; */ /* mux_rate */ if (!this->rate) { this->rate = (p[9] & 0x7F) << 15; this->rate |= (p[10] << 7); this->rate |= (p[11] >> 1); } return 12; } else { /* mpeg2 */ int num_stuffing_bytes; /* system_clock_reference */ this->scr = (int64_t)(p[4] & 0x08) << 27 ; this->scr |= (p[4] & 0x03) << 28 ; this->scr |= p[5] << 20; this->scr |= (p[6] & 0xF8) << 12 ; this->scr |= (p[6] & 0x03) << 13 ; this->scr |= p[7] << 5; this->scr |= (p[8] & 0xF8) >> 3; /* optional - decode extension: this->scr *=300; this->scr += ( (p[8] & 0x03 << 7) | (p[9] & 0xFE >> 1) ); */ lprintf ("SCR=%"PRId64"\n", this->scr); /* mux_rate */ if (!this->rate) { this->rate = (p[0xA] << 14); this->rate |= (p[0xB] << 6); this->rate |= (p[0xC] >> 2); } num_stuffing_bytes = p[0xD] & 0x07; return 14 + num_stuffing_bytes; } } static int32_t parse_program_stream_system_header(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { /* program stream system header */ int32_t header_len; (void)this; (void)buf; header_len = (p[4] << 8) | p[5]; return 6 + header_len; } static int32_t parse_private_stream_2(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { int64_t start_pts, end_pts; /* NAV Packet */ this->packet_len = p[4] << 8 | p[5]; start_pts = ((int64_t)p[7+12] << 24); start_pts |= (p[7+13] << 16); start_pts |= (p[7+14] << 8); start_pts |= p[7+15]; end_pts = ((int64_t)p[7+16] << 24); end_pts |= (p[7+17] << 16); end_pts |= (p[7+18] << 8); end_pts |= p[7+19]; /* some input plugins like DVD can have better timing information and have * already set the input_time, so we can use the cell elapsed time from * the NAV packet for a much more accurate timing */ if (buf->extra_info->input_time) { int64_t cell_time, frames; cell_time = (p[7+0x18] >> 4 ) * 10 * 60 * 60 * 1000; cell_time += (p[7+0x18] & 0x0f) * 60 * 60 * 1000; cell_time += (p[7+0x19] >> 4 ) * 10 * 60 * 1000; cell_time += (p[7+0x19] & 0x0f) * 60 * 1000; cell_time += (p[7+0x1a] >> 4 ) * 10 * 1000; cell_time += (p[7+0x1a] & 0x0f) * 1000; frames = ((p[7+0x1b] & 0x30) >> 4) * 10; frames += ((p[7+0x1b] & 0x0f) ) ; if (p[7+0x1b] & 0x80) cell_time += (frames * 1000)/25; else cell_time += (frames * 1000)/30; this->last_cell_time = cell_time; this->last_cell_pos = this->input->get_current_pos (this->input); this->last_begin_time = buf->extra_info->input_time; } lprintf ("NAV packet, start pts = %"PRId64", end_pts = %"PRId64"\n", start_pts, end_pts); if (this->nav_last_end_pts != start_pts && !this->preview_mode) { lprintf("discontinuity detected by nav packet\n" ); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, start_pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, start_pts, 0); } } this->nav_last_end_pts = end_pts; this->nav_last_start_pts = start_pts; this->send_newpts = 0; this->last_pts[PTS_AUDIO] = this->last_pts[PTS_VIDEO] = 0; buf->content = p; buf->size = this->packet_len; buf->type = BUF_SPU_DVD; buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_NAV; buf->pts = 0; /* NAV packets do not have PES values */ this->video_fifo->put (this->video_fifo, buf); return -1; } /* FIXME: Extension data is not parsed, and is also not skipped. */ static int32_t parse_pes_for_pts(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { int32_t header_len; this->packet_len = p[4] << 8 | p[5]; /* some input plugins like DVD can have better timing information and have * already set the total_time, so we can derive our datarate from this */ if (buf->extra_info->total_time) this->rate = (int)((int64_t)this->input->get_length (this->input) * 1000 / (buf->extra_info->total_time * 50)); if (this->rate && this->last_cell_time) { if( this->last_begin_time == buf->extra_info->input_time ) buf->extra_info->input_time = this->last_cell_time + buf->extra_info->input_time + ((this->input->get_current_pos (this->input) - this->last_cell_pos) * 1000 / (this->rate * 50)); } if (this->rate && !buf->extra_info->input_time) buf->extra_info->input_time = (int)((int64_t)this->input->get_current_pos (this->input) * 1000 / (this->rate * 50)); if (this->mpeg1) { header_len = 6; p += 6; /* packet_len -= 6; */ while ((p[0] & 0x80) == 0x80) { p++; header_len++; this->packet_len--; /* printf ("stuffing\n");*/ } if ((p[0] & 0xc0) == 0x40) { /* STD_buffer_scale, STD_buffer_size */ p += 2; header_len += 2; this->packet_len -= 2; } this->pts = 0; this->dts = 0; if ((p[0] & 0xf0) == 0x20) { this->pts = (int64_t)(p[ 0] & 0x0E) << 29 ; this->pts |= p[ 1] << 22 ; this->pts |= (p[ 2] & 0xFE) << 14 ; this->pts |= p[ 3] << 7 ; this->pts |= (p[ 4] & 0xFE) >> 1 ; p += 5; header_len+= 5; this->packet_len -=5; return header_len; } else if ((p[0] & 0xf0) == 0x30) { this->pts = (int64_t)(p[ 0] & 0x0E) << 29 ; this->pts |= p[ 1] << 22 ; this->pts |= (p[ 2] & 0xFE) << 14 ; this->pts |= p[ 3] << 7 ; this->pts |= (p[ 4] & 0xFE) >> 1 ; this->dts = (int64_t)(p[ 5] & 0x0E) << 29 ; this->dts |= p[ 6] << 22 ; this->dts |= (p[ 7] & 0xFE) << 14 ; this->dts |= p[ 8] << 7 ; this->dts |= (p[ 9] & 0xFE) >> 1 ; p += 10; header_len += 10; this->packet_len -= 10; return header_len; } else { p++; header_len++; this->packet_len--; return header_len; } } else { /* mpeg 2 */ if ((p[6] & 0xC0) != 0x80) { xine_log (this->stream->xine, XINE_LOG_MSG, _("demux_mpeg_block: warning: PES header reserved 10 bits not found\n")); buf->free_buffer(buf); return -1; } /* check PES scrambling_control */ if ((p[6] & 0x30) != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("demux_mpeg_block: warning: PES header indicates that this stream " "may be encrypted (encryption mode %d)\n"), (p[6] & 0x30) >> 4); _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "Media stream scrambled/encrypted", NULL); this->status = DEMUX_FINISHED; buf->free_buffer(buf); return -1; } if (p[7] & 0x80) { /* pts avail */ this->pts = (int64_t)(p[ 9] & 0x0E) << 29 ; this->pts |= p[10] << 22 ; this->pts |= (p[11] & 0xFE) << 14 ; this->pts |= p[12] << 7 ; this->pts |= (p[13] & 0xFE) >> 1 ; lprintf ("pts = %"PRId64"\n", this->pts); } else this->pts = 0; if (p[7] & 0x40) { /* dts avail */ this->dts = (int64_t)(p[14] & 0x0E) << 29 ; this->dts |= p[15] << 22 ; this->dts |= (p[16] & 0xFE) << 14 ; this->dts |= p[17] << 7 ; this->dts |= (p[18] & 0xFE) >> 1 ; } else this->dts = 0; header_len = p[8]; this->packet_len -= header_len + 3; return header_len + 9; } return 0; } static int32_t parse_private_stream_1(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { int track, spu_id; int32_t result; result = parse_pes_for_pts(this, p, buf); if (result < 0) return -1; p += result; /* printf("demux_mpeg_block: private_stream_1: p[0] = 0x%02X\n", p[0]); */ if((p[0] & 0xE0) == 0x20) { spu_id = (p[0] & 0x1f); buf->content = p+1; buf->size = this->packet_len-1; buf->type = BUF_SPU_DVD + spu_id; buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; buf->pts = this->pts; this->video_fifo->put (this->video_fifo, buf); lprintf ("SPU PACK put on fifo\n"); return -1; } /* SVCD OGT subtitles in stream 0x70 */ if(p[0] == 0x70 && (p[1] & 0xFC) == 0x00) { spu_id = p[1]; buf->content = p+1; buf->size = this->packet_len-1; buf->type = BUF_SPU_SVCD + spu_id; buf->pts = this->pts; /* this is probably wrong: if( !preview_mode ) check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); lprintf ("SPU SVCD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return -1; } /* SVCD CVD subtitles in streams 0x00-0x03 */ if((p[0] & 0xFC) == 0x00) { spu_id = (p[0] & 0x03); buf->content = p+1; buf->size = this->packet_len-1; buf->type = BUF_SPU_CVD + spu_id; buf->pts = this->pts; /* this is probably wrong: if( !preview_mode ) check_newpts( this, this->pts, PTS_VIDEO ); */ this->video_fifo->put (this->video_fifo, buf); lprintf ("SPU CVD PACK (%"PRId64", %d) put on fifo\n", this->pts, spu_id); return -1; } if ((p[0]&0xF0) == 0x80) { track = p[0] & 0x0F; /* hack : ac3 track */ /* Number of frame headers * * Describes the number of a52 frame headers that start in this pack (One pack per DVD sector). * * Likely values: 1 or 2. */ buf->decoder_info[1] = p[1]; /* First access unit pointer. * * Describes the byte offset within this pack to the beginning of the first A52 frame header. * The PTS from this pack applies to the beginning of the first A52 frame that starts in this pack. * Any bytes before this offset should be considered to belong to the previous A52 frame. * and therefore be tagged with a PTS value derived from the previous pack. * * Likely values: Anything from 1 to the size of an A52 frame. */ buf->decoder_info[2] = p[2] << 8 | p[3]; /* Summary: If the first pack contains the beginning of 2 A52 frames( decoder_info[1]=2), * the PTS value applies to the first A52 frame. * The second A52 frame will have no PTS value. * The start of the next pack will contain the rest of the second A52 frame and thus, no PTS value. * The third A52 frame will have the PTS value from the second pack. * * If the first pack contains the beginning of 1 frame( decoder_info[1]=1 ), * this first pack must then contain a certain amount of the previous A52 frame. * the PTS value will not apply to this previous A52 frame, * the PTS value will apply to the beginning of the frame that begins in this pack. * * LPCM note: The first_access_unit_pointer will point to * the PCM sample within the pack at which the PTS values applies. * * Example to values in a real stream, each line is a pack (dvd sector): - * decoder_info[1], decoder_info[2], PTS * 2 5 125640 * 1 1061 131400 * 1 581 134280 * 2 101 137160 * 1 1157 142920 * 1 677 145800 * 2 197 148680 * 1 1253 154440 * 1 773 157320 * 2 293 160200 * 1 1349 165960 * 1 869 168840 * 2 389 171720 * 1 1445 177480 * 1 965 180360 * 1 485 183240 * 2 5 186120 * 1 1061 191880 * 1 581 194760 * 2 101 197640 * 1 1157 203400 * 1 677 206280 * 2 197 209160 * Notice the repeating pattern of both decoder_info[1] and decoder_info[2]. * The resulting A52 frames will have these PTS values: - * PTS * 125640 * 0 * 131400 * 134280 * 137160 * 0 * 142920 * 145800 * 148680 * 0 * 154440 * 157320 * 160200 * 0 * 165960 * 168840 * 171720 * 0 * 177480 * 180360 * 183240 * 186120 * 0 * 191880 * 194760 * 197640 * 0 * 203400 * 206280 * 209160 * 0 (Partial A52 frame.) */ buf->content = p+4; buf->size = this->packet_len-4; if (track & 0x8) { buf->type = BUF_AUDIO_DTS + (track & 0x07); /* DVDs only have 8 tracks */ } else { buf->type = BUF_AUDIO_A52 + track; } buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("A52 PACK put on fifo\n"); return -1; } else { buf->free_buffer(buf); return -1; } } else if ((p[0]&0xf0) == 0xa0) { int pcm_offset; #if 0 int number_of_frame_headers; int first_access_unit_pointer; int audio_frame_number; int bits_per_sample; int sample_rate; int num_channels; int dynamic_range; #endif /* * found in http://members.freemail.absa.co.za/ginggs/dvd/mpeg2_lpcm.txt * appears to be correct. */ track = p[0] & 0x0F; #if 0 number_of_frame_headers = p[1]; /* unknown = p[2]; */ first_access_unit_pointer = p[3]; audio_frame_number = p[4]; /* * 000 => mono * 001 => stereo * 010 => 3 channel * ... * 111 => 8 channel */ num_channels = (p[5] & 0x7) + 1; sample_rate = p[5] & 0x10 ? 96000 : 48000; switch ((p[5]>>6) & 3) { case 3: /* illegal, use 16-bits? */ default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "illegal lpcm sample format (%d), assume 16-bit samples\n", (p[5]>>6) & 3 ); case 0: bits_per_sample = 16; break; case 1: bits_per_sample = 20; break; case 2: bits_per_sample = 24; break; } dynamic_range = p[6]; #endif /* send lpcm config byte */ buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG; buf->decoder_info[2] = p[5]; pcm_offset = 7; buf->content = p+pcm_offset; buf->size = this->packet_len-pcm_offset; buf->type = BUF_AUDIO_LPCM_BE + track; buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("LPCM PACK put on fifo\n"); return -1; } else { buf->free_buffer(buf); return -1; } } /* Some new streams have been encountered. 1) DVD+RW disc recorded with a Philips DVD recorder: - new unknown sub-stream id of 0xff */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "demux_mpeg_block:Unrecognised private stream 1 0x%02x. Please report this to xine developers.\n", p[0]); buf->free_buffer(buf); return -1; } static int32_t parse_video_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { int32_t result; result = parse_pes_for_pts(this, p, buf); if (result < 0) return -1; p += result; buf->content = p; buf->size = this->packet_len; buf->type = BUF_VIDEO_MPEG; buf->pts = this->pts; buf->decoder_info[0] = this->pts - this->dts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_VIDEO ); this->video_fifo->put (this->video_fifo, buf); lprintf ("MPEG Video PACK put on fifo\n"); return -1; } static int32_t parse_audio_stream(demux_mpeg_block_t *this, uint8_t *p, buf_element_t *buf) { int track; int32_t result; result = parse_pes_for_pts(this, p, buf); if (result < 0) return -1; p += result; track = this->stream_id & 0x1f; buf->content = p; buf->size = this->packet_len; buf->type = BUF_AUDIO_MPEG + track; buf->pts = this->pts; if( !this->preview_mode ) check_newpts( this, this->pts, PTS_AUDIO ); if(this->audio_fifo) { this->audio_fifo->put (this->audio_fifo, buf); lprintf ("MPEG Audio PACK put on fifo\n"); } else { buf->free_buffer(buf); } return -1; } static int demux_mpeg_block_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; demux_mpeg_block_parse_pack(this, 0); return this->status; } #ifdef ESTIMATE_RATE_FIXED /*! Estimate bitrate by looking inside the MPEG file for presentation time stamps (PTS) and computing how far apart these are in bytes and in time. On failure return 0. This might be used after deciding that mux_rate in a stream is faulty. */ /* How many *sucessful* PTS samples do we take? */ #define MAX_SAMPLES 5 /* How many times we read blocks before giving up. */ #define MAX_READS 30 /* TRUNCATE x to the nearest multiple of y. */ #define TRUNC(x,y) (((x) / (y)) * (y)) static int demux_mpeg_block_estimate_rate (demux_mpeg_block_t *this) { buf_element_t *buf = NULL; unsigned char *p; int is_mpeg1=0; off_t pos, last_pos=0; off_t step, mpeg_length; off_t blocksize = this->blocksize; int64_t pts, last_pts=0; int reads=0 /* Number of blocks read so far */; int count=0; /* Number of sucessful PTS found so far */ int rate=0; /* The return rate value */ int stream_id; /* We can't estimate by sampling if we don't thave the ability to randomly access the and more importantly reset after accessessing. */ if (!(this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE)) return 0; mpeg_length= this->input->get_length (this->input); step = TRUNC((mpeg_length/MAX_SAMPLES), blocksize); if (step <= 0) step = blocksize; /* avoid endless loop for tiny files */ pos = step; /* At this point "pos", and "step" are a multiple of blocksize and they should continue to be so throughout. */ if (this->input->seek (this->input, pos, SEEK_SET) != pos) return 0; while ( (buf = this->input->read_block (this->input, this->video_fifo, blocksize)) && count < MAX_SAMPLES && reads++ < MAX_READS ) { p = buf->content; /* len = this->mnBlocksize; */ if (p[3] == 0xBA) { /* program stream pack header */ is_mpeg1 = (p[4] & 0x40) == 0; if (is_mpeg1) p += 12; else p += 14 + (p[0xD] & 0x07); } if (p[3] == 0xbb) /* program stream system header */ p += 6 + ((p[4] << 8) | p[5]); /* we should now have a PES packet here */ if (p[0] || p[1] || (p[2] != 1)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_mpeg_block: error %02x %02x %02x (should be 0x000001) \n", p[0], p[1], p[2]); buf->free_buffer (buf); return rate; } stream_id = p[3]; pts = 0; if ((stream_id < 0xbc) || ((stream_id & 0xf0) != 0xe0)) { pos += (off_t) blocksize; buf->free_buffer (buf); buf = NULL; continue; /* only use video packets */ } if (is_mpeg1) { if (p[3] != 0xBF) { /* stream_id */ p += 6; /* packet_len -= 6; */ while ((p[0] & 0x80) == 0x80) { p++; /* stuffing */ } if ((p[0] & 0xc0) == 0x40) { /* STD_buffer_scale, STD_buffer_size */ p += 2; } if ( ((p[0] & 0xf0) == 0x20) || ((p[0] & 0xf0) == 0x30) ) { pts = (int64_t)(p[ 0] & 0x0E) << 29 ; pts |= p[ 1] << 22 ; pts |= (p[ 2] & 0xFE) << 14 ; pts |= p[ 3] << 7 ; pts |= (p[ 4] & 0xFE) >> 1 ; } } } else { /* mpeg 2 */ if (p[7] & 0x80) { /* pts avail */ pts = (int64_t)(p[ 9] & 0x0E) << 29 ; pts |= p[10] << 22 ; pts |= (p[11] & 0xFE) << 14 ; pts |= p[12] << 7 ; pts |= (p[13] & 0xFE) >> 1 ; } else pts = 0; } if (pts) { if ( (pos>last_pos) && (pts>last_pts) ) { int cur_rate; cur_rate = ((pos - last_pos)*90000) / ((pts - last_pts) * 50); rate = (count * rate + cur_rate) / (count+1); count ++; /* printf ("demux_mpeg_block: stream_id %02x, pos: %"PRId64", pts: %d, cur_rate = %d, overall rate : %d\n", stream_id, pos, pts, cur_rate, rate); */ } last_pos = pos; last_pts = pts; pos += step; } else pos += blocksize; buf->free_buffer (buf); buf = NULL; if (pos > mpeg_length || this->input->seek (this->input, pos, SEEK_SET) == (off_t)-1) break; } if( buf ) buf->free_buffer (buf); } lprintf("est_rate=%d\n",rate); return rate; } #endif /*ESTIMATE_RATE_FIXED*/ static void demux_mpeg_block_dispose (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; free (this); } static int demux_mpeg_block_get_status (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; return this->status; } static int demux_mpeg_detect_blocksize(input_plugin_t *input) { uint8_t scratch[4]; if (input->seek(input, 2048, SEEK_SET) != 2048) return 0; if (input->read(input, scratch, 4) != 4) return 0; if (scratch[0] || scratch[1] || (scratch[2] != 0x01) || (scratch[3] != 0xba)) { if (input->seek(input, 2324, SEEK_SET) != 2324) return 0; if (input->read(input, scratch, 4) != 4) return 0; if (scratch[0] || scratch[1] || (scratch[2] != 0x01) || (scratch[3] != 0xba)) return 0; return 2324; } else return 2048; } static void demux_mpeg_block_send_headers (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; if ((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { if (!this->blocksize) this->blocksize = demux_mpeg_detect_blocksize( this->input ); if (!this->blocksize) return; } /* * send start buffer */ _x_demux_control_start(this->stream); #ifdef USE_ILL_ADVISED_ESTIMATE_RATE_INITIALLY if (!this->rate) this->rate = demux_mpeg_block_estimate_rate (this); #else /* Set to Use rate given in by stream initially. */ this->rate = 0; #endif if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { int num_buffers = NUM_PREVIEW_BUFFERS; if (this->input->seek (this->input, 0, SEEK_SET) != 0) return; this->status = DEMUX_OK ; while ( (num_buffers>0) && (this->status == DEMUX_OK) ) { demux_mpeg_block_parse_pack(this, 1); num_buffers --; } } /* else FIXME: implement preview generation from PREVIEW data */ this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->rate * 50 * 8); } static int demux_mpeg_block_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); if((this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) != 0) { if (start_pos) { start_pos /= (off_t) this->blocksize; start_pos *= (off_t) this->blocksize; this->input->seek (this->input, start_pos, SEEK_SET); } else if (start_time) { if( this->input->seek_time ) { this->input->seek_time (this->input, start_time, SEEK_SET); } else { start_time /= 1000; if (this->last_cell_time) { start_pos = start_time - (this->last_cell_time + this->last_begin_time)/1000; start_pos *= this->rate; start_pos *= 50; start_pos += this->last_cell_pos; } else { start_pos = start_time; start_pos *= this->rate; start_pos *= 50; } start_pos /= (off_t) this->blocksize; start_pos *= (off_t) this->blocksize; this->input->seek (this->input, start_pos, SEEK_SET); } } else this->input->seek (this->input, 0, SEEK_SET); } /* * now start demuxing */ this->last_cell_time = 0; this->send_newpts = 1; if( !playing ) { this->buf_flag_seek = 0; this->nav_last_end_pts = this->nav_last_start_pts = 0; this->status = DEMUX_OK ; this->last_pts[0] = 0; this->last_pts[1] = 0; } else { this->buf_flag_seek = 1; this->nav_last_end_pts = this->nav_last_start_pts = 0; _x_demux_flush_engine(this->stream); } return this->status; } static int demux_mpeg_block_get_stream_length (demux_plugin_t *this_gen) { demux_mpeg_block_t *this = (demux_mpeg_block_t *) this_gen; /* * find input plugin */ if (this->rate) return (int)((int64_t) 1000 * this->input->get_length (this->input) / (this->rate * 50)); else return 0; } static uint32_t demux_mpeg_block_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_mpeg_block_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input_gen) { input_plugin_t *input = (input_plugin_t *) input_gen; demux_mpeg_block_t *this; int blocksize; lprintf ("open_plugin:detection_method=%d\n", stream->content_detection_method); switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint8_t scratch[8]; int bs; int caps = input->get_capabilities (input); /* use demux_mpeg for non-block devices */ if (!(caps & INPUT_CAP_BLOCK)) return NULL; blocksize = bs = input->get_blocksize (input); lprintf ("open_plugin:blocksize=%d\n", blocksize); if ((blocksize <= 0) && (caps & INPUT_CAP_SEEKABLE)) { blocksize = demux_mpeg_detect_blocksize (input); if (blocksize <= 0) return NULL; } /* Avoid plugin loader probing us again after all others, especially after that still unstable avformat. */ if (input->input_class && input->input_class->identifier && !strcmp (input->input_class->identifier, "DVD")) break; /* Try fallback for alternative input plugin */ if (!(caps & INPUT_CAP_SEEKABLE)) return NULL; if (input->seek (input, 0, SEEK_SET) != 0) return NULL; /* result of input->read() won't matter */ memset (scratch, 0xff, 8); if (input->read (input, scratch, 5) <= 0) return NULL; lprintf ("open_plugin:read worked\n"); if (scratch[0] || scratch[1] || (scratch[2] != 0x01) || (scratch[3] != 0xba)) { lprintf ("open_plugin:scratch failed\n"); return NULL; } /* if it's a file then make sure it's mpeg-2 */ if ((bs <= 0) && ((scratch[4] >> 4) != 4)) return NULL; if (input->seek (input, 0, SEEK_SET) != 0) return NULL; lprintf ("open_plugin:Accepting detection_method XINE_DEMUX_CONTENT_STRATEGY blocksize=%d\n", blocksize); } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: { blocksize = input->get_blocksize (input); lprintf ("open_plugin:blocksize=%d\n", blocksize); if ((blocksize <= 0) && (input->get_capabilities (input) & INPUT_CAP_SEEKABLE)) { blocksize = demux_mpeg_detect_blocksize (input); if (blocksize <= 0) return NULL; } } break; default: return NULL; } this = calloc (1, sizeof (*this)); if (!this) return NULL; this->blocksize = blocksize; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_mpeg_block_send_headers; this->demux_plugin.send_chunk = demux_mpeg_block_send_chunk; this->demux_plugin.seek = demux_mpeg_block_seek; this->demux_plugin.dispose = demux_mpeg_block_dispose; this->demux_plugin.get_status = demux_mpeg_block_get_status; this->demux_plugin.get_stream_length = demux_mpeg_block_get_stream_length; this->demux_plugin.get_capabilities = demux_mpeg_block_get_capabilities; this->demux_plugin.get_optional_data = demux_mpeg_block_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } void *demux_mpeg_block_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_mpeg_block_class = { .open_plugin = open_plugin, .description = N_("DVD/VOB demux plugin"), .identifier = "MPEG_BLOCK", .mimetypes = NULL, .extensions = "vob vcd:/ dvd:/ pvr:/", .dispose = NULL, }; return (void *)&demux_mpeg_block_class; } xine-lib-1.2/src/demuxers/demux_wav.c0000644000175000017500000003175214647725152015462 0ustar meme/* * Copyright (C) 2001-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * MS WAV File Demuxer by Mike Melanson (melanson@pcisys.net) * based on WAV specs that are available far and wide */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "group_audio.h" #define WAV_SIGNATURE_SIZE 12 /* this is the hex value for 'data' */ #define data_TAG 0x61746164 /* this is the hex value for 'fmt ' */ #define fmt_TAG 0x20746D66 #define PCM_BLOCK_ALIGN 1024 #define PREFERED_BLOCK_SIZE 4096 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; xine_waveformatex *wave; int wave_size; unsigned int audio_type; off_t data_start; off_t data_size; int seek_align; int chunk_size; int send_newpts; int seek_flag; /* this is set when a seek just occurred */ } demux_wav_t; static int demux_wav_get_stream_length (demux_plugin_t *this_gen); /* searches for the chunk with the given tag from the beginning of WAV file * returns 1 if chunk was found, 0 otherwise, * fills chunk_size and chunk_pos if chunk was found * NOTE: chunk_pos is set to the position of the first byte of chunk data */ static int find_chunk_by_tag(demux_wav_t *this, const uint32_t given_chunk_tag, uint32_t *found_chunk_size, off_t *found_chunk_pos) { uint32_t chunk_tag; uint32_t chunk_size; uint8_t chunk_preamble[8]; /* search for the chunks from the start of the WAV file */ if (this->input->seek(this->input, WAV_SIGNATURE_SIZE, SEEK_SET) != WAV_SIGNATURE_SIZE) return 0; while (1) { if (this->input->read(this->input, chunk_preamble, 8) != 8) { return 0; } chunk_tag = _X_LE_32(&chunk_preamble[0]); chunk_size = _X_LE_32(&chunk_preamble[4]); if (chunk_tag == given_chunk_tag) { if (found_chunk_size) *found_chunk_size = _X_LE_32(&chunk_preamble[4]); if (found_chunk_pos) *found_chunk_pos = this->input->get_current_pos(this->input); return 1; } else { if (this->input->seek(this->input, chunk_size, SEEK_CUR) < 0) return 0; } } } static int probe_wav_file(input_plugin_t *input) { uint8_t signature[WAV_SIGNATURE_SIZE]; /* check the signature */ if (_x_demux_read_header(input, signature, WAV_SIGNATURE_SIZE) != WAV_SIGNATURE_SIZE) return 0; if (memcmp(signature, "RIFF", 4) || memcmp(&signature[8], "WAVE", 4) ) return 0; return 1; } /* returns 1 if the WAV file was opened successfully, 0 otherwise */ static int open_wav_file(demux_wav_t *this) { off_t wave_pos; uint32_t wave_size; /* search for the 'fmt ' chunk first */ wave_pos = 0; if (find_chunk_by_tag(this, fmt_TAG, &wave_size, &wave_pos)==0) return 0; this->wave_size = wave_size; if (this->input->seek(this->input, wave_pos, SEEK_SET) != wave_pos) return 0; this->wave = malloc( this->wave_size ); if (!this->wave) return 0; if (this->input->read(this->input, (void *)this->wave, this->wave_size) != this->wave_size) { return 0; } _x_waveformatex_le2me(this->wave); this->audio_type = _x_formattag_to_buf_audio(this->wave->wFormatTag); if(!this->audio_type) { this->audio_type = BUF_AUDIO_UNKNOWN; } if (this->wave->nChannels <= 0) { return 0; } /* search for the 'data' chunk */ this->data_start = this->data_size = 0; if (find_chunk_by_tag (this, data_TAG, NULL, &this->data_start) == 0) return 0; /* Get the data length from the file itself, instead of the data TAG, for broken files */ if (this->input->seek (this->input, this->data_start, SEEK_SET) != this->data_start) return 0; /* XXX */ if (this->wave->nBlockAlign <= 0) this->wave->nBlockAlign = 4; this->seek_align = this->wave->nBlockAlign; this->chunk_size = (this->wave->nBlockAlign < PREFERED_BLOCK_SIZE) ? PREFERED_BLOCK_SIZE / this->wave->nBlockAlign * this->wave->nBlockAlign : this->wave->nBlockAlign; this->data_size = this->input->get_length (this->input); return 1; } static int demux_wav_send_chunk(demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; buf_element_t *buf = NULL; unsigned int remaining_sample_bytes; off_t current_file_pos; int64_t current_pts; /* just load data chunks from wherever the stream happens to be * pointing; issue a DEMUX_FINISHED status if EOF is reached */ remaining_sample_bytes = this->chunk_size; current_file_pos = this->input->get_current_pos(this->input) - this->data_start; current_pts = current_file_pos; current_pts *= 90000; current_pts /= this->wave->nAvgBytesPerSec; if (this->send_newpts) { _x_demux_control_newpts(this->stream, current_pts, this->seek_flag); this->send_newpts = this->seek_flag = 0; } while (remaining_sample_bytes) { if(!this->audio_fifo){ this->status = DEMUX_FINISHED; break; } buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); do { if (this->data_size <= 0) break; /* file being written right now? */ if (current_file_pos > this->data_size) { this->data_size = this->input->get_length (this->input); if (this->data_size <= 0) break; } buf->extra_info->input_normpos = (int)((double)current_file_pos * 65535 / this->data_size); } while (0); buf->extra_info->input_time = current_pts / 90; buf->extra_info->total_time = (int64_t) this->data_size * 1000 / this->wave->nAvgBytesPerSec; buf->pts = current_pts; if ((int)remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; off_t read; if ((read = this->input->read(this->input, buf->content, buf->size)) != buf->size) { if (read == 0) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } else { buf->size = read; } } #if 0 for(n=0;n<20;n++) { printf("%x ",buf->content[n]); } printf("\n"); #endif #if 0 for(n=0;n<20;n++) { printf("%x ",buf->content[n]); } printf("\n"); #endif if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; buf->type = this->audio_type; this->audio_fifo->put (this->audio_fifo, buf); } return this->status; } static void demux_wav_send_headers(demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->wave->nChannels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->wave->nSamplesPerSec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->wave->wBitsPerSample); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo && this->audio_type) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->audio_type; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->wave->nSamplesPerSec; buf->decoder_info[2] = this->wave->wBitsPerSample; buf->decoder_info[3] = this->wave->nChannels; buf->content = (void *)this->wave; buf->size = this->wave_size; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_wav_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_wav_t *this = (demux_wav_t *) this_gen; start_pos = this->data_size > 0 ? (off_t)((double)start_pos * this->data_size / 65535) : 0; this->status = DEMUX_OK; /* if input is non-seekable, do not proceed with the rest of this * seek function */ if (!(this->input->get_capabilities (this->input) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE))) return this->status; this->send_newpts = 1; if (playing) { this->seek_flag = BUF_FLAG_SEEK; _x_demux_flush_engine (this->stream); } /* time-based seeking, the start_pos code will then align the blocks * if necessary */ if (start_time != 0) { int length = demux_wav_get_stream_length (this_gen); if (length != 0) { start_pos = start_time * this->data_size / length; } } /* check the boundary offsets */ if (start_pos <= 0) this->input->seek(this->input, this->data_start, SEEK_SET); else if (start_pos >= this->data_size) { this->status = DEMUX_FINISHED; return this->status; } else { /* This function must seek along the block alignment. The start_pos * is in reference to the start of the data. Divide the start_pos by * the block alignment integer-wise, and multiply the quotient by the * block alignment to get the new aligned offset. Add the data start * offset and seek to the new position. */ start_pos /= this->seek_align; start_pos *= this->seek_align; start_pos += this->data_start; this->input->seek(this->input, start_pos, SEEK_SET); } return this->status; } static void demux_wav_dispose (demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; _x_freep(&this->wave); free(this); } static int demux_wav_get_status (demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_wav_get_stream_length (demux_plugin_t *this_gen) { demux_wav_t *this = (demux_wav_t *) this_gen; return (int)((int64_t) this->data_size * 1000 / this->wave->nAvgBytesPerSec); } static uint32_t demux_wav_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_wav_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_wav_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!probe_wav_file(input)) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_wav_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_wav_send_headers; this->demux_plugin.send_chunk = demux_wav_send_chunk; this->demux_plugin.seek = demux_wav_seek; this->demux_plugin.dispose = demux_wav_dispose; this->demux_plugin.get_status = demux_wav_get_status; this->demux_plugin.get_stream_length = demux_wav_get_stream_length; this->demux_plugin.get_capabilities = demux_wav_get_capabilities; this->demux_plugin.get_optional_data = demux_wav_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; if (!open_wav_file(this)) { demux_wav_dispose(&this->demux_plugin); return NULL; } return &this->demux_plugin; } void *demux_wav_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_wav_class = { .open_plugin = open_plugin, .description = N_("WAV file demux plugin"), .identifier = "WAV", .mimetypes = "audio/x-wav: wav: WAV audio;" "audio/wav: wav: WAV audio;" "audio/x-pn-wav: wav: WAV audio;" "audio/x-pn-windows-acm: wav: WAV audio;", .extensions = "wav", .dispose = NULL, }; return (void *)&demux_wav_class; } xine-lib-1.2/src/demuxers/asfheader.h0000644000175000017500000001440414647725152015405 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for asf streams * * based on ffmpeg's * ASF compatible encoder and decoder. * Copyright (c) 2000, 2001 Gerard Lantau. * * GUID list from avifile * some other ideas from MPlayer */ #ifndef ASFHEADER_H #define ASFHEADER_H #include /* * define asf GUIDs (list from avifile) */ typedef enum { GUID_ERROR = 0, /* base ASF objects */ GUID_ASF_HEADER, GUID_ASF_DATA, GUID_ASF_SIMPLE_INDEX, GUID_INDEX, GUID_MEDIA_OBJECT_INDEX, GUID_TIMECODE_INDEX, /* header ASF objects */ GUID_ASF_FILE_PROPERTIES, GUID_ASF_STREAM_PROPERTIES, GUID_ASF_HEADER_EXTENSION, GUID_ASF_CODEC_LIST, GUID_ASF_SCRIPT_COMMAND, GUID_ASF_MARKER, GUID_ASF_BITRATE_MUTUAL_EXCLUSION, GUID_ASF_ERROR_CORRECTION, GUID_ASF_CONTENT_DESCRIPTION, GUID_ASF_EXTENDED_CONTENT_DESCRIPTION, GUID_ASF_STREAM_BITRATE_PROPERTIES, GUID_ASF_EXTENDED_CONTENT_ENCRYPTION, GUID_ASF_PADDING, /* stream properties object stream type */ GUID_ASF_AUDIO_MEDIA, GUID_ASF_VIDEO_MEDIA, GUID_ASF_COMMAND_MEDIA, GUID_ASF_JFIF_MEDIA, GUID_ASF_DEGRADABLE_JPEG_MEDIA, GUID_ASF_FILE_TRANSFER_MEDIA, GUID_ASF_BINARY_MEDIA, /* stream properties object error correction type */ GUID_ASF_NO_ERROR_CORRECTION, GUID_ASF_AUDIO_SPREAD, /* mutual exclusion object exlusion type */ GUID_ASF_MUTEX_BITRATE, GUID_ASF_MUTEX_UKNOWN, /* header extension */ GUID_ASF_RESERVED_1, /* script command */ GUID_ASF_RESERVED_SCRIPT_COMMNAND, /* marker object */ GUID_ASF_RESERVED_MARKER, /* various */ GUID_ASF_AUDIO_CONCEAL_NONE, GUID_ASF_CODEC_COMMENT1_HEADER, GUID_ASF_2_0_HEADER, GUID_EXTENDED_STREAM_PROPERTIES, GUID_ADVANCED_MUTUAL_EXCLUSION, GUID_GROUP_MUTUAL_EXCLUSION, GUID_STREAM_PRIORITIZATION, GUID_BANDWIDTH_SHARING, GUID_LANGUAGE_LIST, GUID_METADATA, GUID_METADATA_LIBRARY, GUID_INDEX_PARAMETERS, GUID_MEDIA_OBJECT_INDEX_PARAMETERS, GUID_TIMECODE_INDEX_PARAMETERS, GUID_ADVANCED_CONTENT_ENCRYPTION, GUID_COMPATIBILITY, GUID_END } asf_guid_t; #if 0 /* asf stream types. currently using asf_guid_t instead. */ typedef enum { ASF_STREAM_TYPE_UNKNOWN = 0, ASF_STREAM_TYPE_AUDIO, ASF_STREAM_TYPE_VIDEO, ASF_STREAM_TYPE_CONTROL, ASF_STREAM_TYPE_JFIF, ASF_STREAM_TYPE_DEGRADABLE_JPEG, ASF_STREAM_TYPE_FILE_TRANSFER, ASF_STREAM_TYPE_BINARY } asf_stream_type_t; #endif #define ASF_MAX_NUM_STREAMS 23 /* TJ. Globally Unique IDentifiction (GUID) is originally defined as * uint32_t Data1; uint16_t Data2; uint16_t Data3; uint8_t Data4[8]; * stored in little endian byte order. * This is fine with x86 but inefficient at big endian machines. * We only compare GUIDs against hard-coded constants here, * so lets use plain uint8_t[16] instead. */ typedef struct asf_header_s asf_header_t; typedef struct asf_file_s asf_file_t; typedef struct asf_content_s asf_content_t; typedef struct asf_stream_s asf_stream_t; typedef struct asf_stream_extension_s asf_stream_extension_t; struct asf_header_s { asf_file_t *file; asf_content_t *content; int stream_count; asf_stream_t *streams[ASF_MAX_NUM_STREAMS]; asf_stream_extension_t *stream_extensions[ASF_MAX_NUM_STREAMS]; uint32_t bitrates[ASF_MAX_NUM_STREAMS]; struct { uint32_t x, y; } aspect_ratios[ASF_MAX_NUM_STREAMS]; }; struct asf_file_s { uint8_t file_id[16]; uint64_t file_size; /* in bytes */ uint64_t data_packet_count; uint64_t play_duration; /* in 100 nanoseconds unit */ uint64_t send_duration; /* in 100 nanoseconds unit */ uint64_t preroll; /* in 100 nanoseconds unit */ uint32_t packet_size; uint32_t max_bitrate; uint8_t broadcast_flag; uint8_t seekable_flag; }; /* ms unicode strings */ struct asf_content_s { char *title; char *author; char *copyright; char *description; char *rating; }; struct asf_stream_s { uint16_t stream_number; asf_guid_t stream_type; asf_guid_t error_correction_type; uint64_t time_offset; uint32_t private_data_length; uint8_t *private_data; uint32_t error_correction_data_length; uint8_t *error_correction_data; uint8_t encrypted_flag; }; struct asf_stream_extension_s { uint64_t start_time; uint64_t end_time; uint32_t data_bitrate; uint32_t buffer_size; uint32_t initial_buffer_fullness; uint32_t alternate_data_bitrate; uint32_t alternate_buffer_size; uint32_t alternate_initial_buffer_fullness; uint32_t max_object_size; uint8_t reliable_flag; uint8_t seekable_flag; uint8_t no_cleanpoints_flag; uint8_t resend_live_cleanpoints_flag; uint16_t language_id; uint64_t average_time_per_frame; uint16_t stream_name_count; uint16_t payload_extension_system_count; char **stream_names; }; asf_guid_t asf_guid_2_num (const uint8_t *guid); void asf_guid_2_str (uint8_t *str, const uint8_t *guid); const char *asf_guid_name (asf_guid_t num); asf_header_t *asf_header_new (uint8_t *buffer, int buffer_len) XINE_MALLOC; void asf_header_choose_streams (asf_header_t *header, uint32_t bandwidth, int *video_id, int *audio_id); void asf_header_disable_streams (asf_header_t *header, int video_id, int audio_id); void asf_header_delete (asf_header_t *header); #endif xine-lib-1.2/src/demuxers/demux_playlist.c0000644000175000017500000004660714647725152016533 0ustar meme/* * Copyright (C) 2007-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * * Playlist parser/demuxer by * Claudio Ciccani (klan@users.sourceforge.net) * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #define LOG_MODULE "demux_playlist" #define LOG_VERBOSE /* #define LOG */ #include #include #include "bswap.h" #include typedef enum { XINE_PLT_NONE = 0, XINE_PLT_REF = ME_FOURCC('R','E','F',0), XINE_PLT_M3U = ME_FOURCC('M','3','U',0), XINE_PLT_RAM = ME_FOURCC('R','A','M',0), XINE_PLT_PLS = ME_FOURCC('P','L','S',0), XINE_PLT_ASX = ME_FOURCC('A','S','X',0), XINE_PLT_SMI = ME_FOURCC('S','M','I',0), XINE_PLT_QTL = ME_FOURCC('Q','T','L',0), XINE_PLT_XSPF = ME_FOURCC('X','S','P',0), XINE_PLT_RSS = ME_FOURCC('R','S','S',0) } playlist_t; typedef struct { demux_plugin_t demux_plugin; xine_t *xine; xine_stream_t *stream; input_plugin_t *input; playlist_t playlist; int status; } demux_playlist_t; static playlist_t detect_by_extension (input_plugin_t *input) { char *ext; ext = strrchr (input->get_mrl (input), '.'); if (!ext) return XINE_PLT_NONE; if (!strcasecmp (ext, ".m3u")) return XINE_PLT_M3U; if (!strcasecmp (ext, ".ram")) return XINE_PLT_RAM; if (!strcasecmp (ext, ".pls")) return XINE_PLT_PLS; if (!strcasecmp (ext, ".wax") || !strcasecmp (ext, ".wvx") || !strcasecmp (ext, ".asx")) return XINE_PLT_ASX; if (!strcasecmp (ext, ".smi") || !strcasecmp (ext, ".smil")) return XINE_PLT_SMI; if (!strcasecmp (ext, ".qtl")) return XINE_PLT_QTL; if (!strcasecmp (ext, ".xspf")) return XINE_PLT_XSPF; if (!strcasecmp (ext, ".rss")) return XINE_PLT_RSS; return XINE_PLT_NONE; } static playlist_t detect_by_content (input_plugin_t *input) { char buf[MAX_PREVIEW_SIZE], *tmp; int len; len = _x_demux_read_header (input, buf, sizeof(buf)-1); if (len <= 0) return XINE_PLT_NONE; buf[len] = '\0'; tmp = buf; while (*tmp && isspace(*tmp)) tmp++; if (!strncmp (tmp, "[Reference]", 11) || !strncmp (tmp, "Ref1=", 5)) return XINE_PLT_REF; if (!strncmp (tmp, "#EXTM3U", 7)) return XINE_PLT_M3U; if (!strncmp (tmp, "file://", 7) || !strncmp (tmp, "http://", 7) || !strncmp (tmp, "rtsp://", 7) || !strncmp (tmp, "pnm://", 6)) return XINE_PLT_RAM; if (!strncmp (tmp, "[Playlist]", 10 )) return XINE_PLT_PLS; if (!strncasecmp (tmp, " s && isspace(*e)) *e-- = '\0'; return s; } static int parse_time (const char *s) { int t = 0; int i; if (!s) return 0; if (!strncmp (s, "npt=", 4)) s += 4; else if (!strncmp (s, "smpte=", 6)) s += 6; for (i = 0; i < 3; i++) { t *= 60; t += atoi(s); s = strchr (s, ':'); if (!s) break; s++; } return t*1000; } static void parse_ref (demux_playlist_t *this, char *data, int length) { char *src = data; char *end; int alt = 0; (void)length; /* FIXME: test */ while (src && *src) { end = strchr (src, '\n'); if (end) *end = '\0'; src = trim (src); if (!strncmp (src, "Ref", 3)) { src = strchr (src, '='); if (src && *(src+1)) { lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, alt++, src+1, NULL, 0, 0); } } src = end; if (src) src++; } } static void parse_m3u (demux_playlist_t *this, char *data, int length) { char *src = data; char *end; char *title = NULL; (void)length; /* FIXME: test */ while (src && *src) { end = strchr (src, '\n'); if (end) *end = '\0'; src = trim (src); if (*src == '#') { if (!strncmp (src+1, "EXTINF:", 7)) { title = strchr (src+8, ','); if (title) title++; } } else if (*src) { lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, 0, src, title, 0, 0); } src = end; if (src) src++; } } static void parse_ram (demux_playlist_t *this, char *data, int length) { char *src = data; char *end; (void)length; /* FIXME: test */ while (src && *src) { end = strchr (src, '\n'); if (end) *end = '\0'; src = trim (src); if (!strcmp (src, "--stop--")) break; if (*src && *src != '#') { char *title = NULL; if (!strncmp (src, "rtsp://", 7) || !strncmp (src, "pnm://", 7)) { char *tmp = strrchr (src, '?'); if (tmp) { *tmp = '\0'; title = strstr (tmp+1, "title="); if (title) { title += 6; tmp = strchr (title, '&'); if (tmp) *tmp = '\0'; } } } lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, 0, src, title, 0, 0); } src = end; if (src) src++; } } static void parse_pls (demux_playlist_t *this, char *data, int length) { char *src = data; char *end; (void)length; /* FIXME: test */ while (src && *src) { end = strchr (src, '\n'); if (end) *end = '\0'; src = trim (src); if (!strncmp (src, "File", 4)) { src = strchr (src+4, '='); if (src && *(src+1)) { lprintf ("mrl:'%s'\n", src+1); _x_demux_send_mrl_reference (this->stream, 0, src+1, NULL, 0, 0); } } src = end; if (src) src++; } } static void parse_asx (demux_playlist_t *this, char *data, int length) { xml_node_t *root, *node, *tmp; int is_asx = 0; xml_parser_t *parser; parser = xml_parser_init_r (data, length, XML_PARSER_CASE_INSENSITIVE); if (!parser) { return; } if (xml_parser_build_tree_r (parser, &root) >= 0) { if (!strcasecmp (root->name, "asx")) { is_asx = 1; for (node = root->child; node; node = node->next) { if (!strcasecmp (node->name, "entry")) { const char *title = NULL; const char *src = NULL; const char *start = NULL; const char *duration = NULL; for (tmp = node->child; tmp; tmp = tmp->next) { if (!strcasecmp (tmp->name, "title")) { title = tmp->data; } else if (!strcasecmp (tmp->name, "ref")) { src = xml_parser_get_property (tmp, "href"); } else if (!strcasecmp (tmp->name, "starttime")) { start = xml_parser_get_property (tmp, "value"); } else if (!strcasecmp (tmp->name, "duration")) { duration = xml_parser_get_property (tmp, "value"); } } if (src) { lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, 0, src, title, parse_time(start), parse_time(duration)); } } } } xml_parser_free_tree (root); } xml_parser_finalize_r (parser); if (!is_asx) { /* No tags found? Might be a references list. */ parse_ref (this, data, length); } } static void parse_smi (demux_playlist_t *this, char *data, int length) { xml_node_t *root, *node, *tmp; int is_smi = 0; xml_parser_t *parser; parser = xml_parser_init_r (data, length, XML_PARSER_CASE_SENSITIVE); if (!parser) { return; } if (xml_parser_build_tree_r (parser, &root) >= 0) { for (node = root; node; node = node->next) { if (!strcmp (node->name, "smil")) break; } if (node) { is_smi = 1; for (node = node->child; node; node = node->next) { if (!strcmp (node->name, "body")) { for (tmp = node->child; tmp; tmp = tmp->next) { if (!strcmp (tmp->name, "audio") || !strcmp (tmp->name, "video")) { const char *src, *title, *starts, *ends; int start, end; src = xml_parser_get_property (tmp, "src"); title = xml_parser_get_property (tmp, "title"); starts = xml_parser_get_property (tmp, "clipBegin"); if (!starts) starts = xml_parser_get_property (tmp, "clip-begin"); ends = xml_parser_get_property (tmp, "clipEnd"); if (!ends) ends = xml_parser_get_property (tmp, "clip-end"); start = parse_time (starts); end = parse_time (ends); if (src) { lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, 0, src, title, start, end ? (end-start) : 0); } } } } } } xml_parser_free_tree (root); } xml_parser_finalize_r (parser); if (!is_smi) { /* No tags found? Might be a RAM playlist. */ parse_ram (this, data, length); } } static void parse_qtl (demux_playlist_t *this, char *data, int length) { xml_node_t *root, *node; xml_parser_t *parser; parser = xml_parser_init_r (data, length, XML_PARSER_CASE_SENSITIVE); if (!parser) { return; } if (xml_parser_build_tree_r (parser, &root) >= 0) { for (node = root; node; node = node->next) { if (!strcmp (node->name, "embed")) { const char *src; src = xml_parser_get_property (node, "src"); if (src) { lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, 0, src, NULL, 0, 0); } } } xml_parser_free_tree (root); } xml_parser_finalize_r (parser); } static void parse_xspf (demux_playlist_t *this, char *data, int length) { xml_node_t *root, *node, *tmp; xml_parser_t *parser; parser = xml_parser_init_r (data, length, XML_PARSER_CASE_SENSITIVE); if (!parser) { return; } if (xml_parser_build_tree_r (parser, &root) >= 0) { for (node = root; node; node = node->next) { if (!strcmp (node->name, "playlist")) break; } if (node) { for (node = node->child; node; node = node->next) { if (!strcmp (node->name, "trackList")) break; } } if (node) { for (node = node->child; node; node = node->next) { if (!strcmp (node->name, "track")) { char *src = NULL; char *title = NULL; for (tmp = node->child; tmp; tmp = tmp->next) { if (!strcmp (tmp->name, "location")) { src = trim((char*)tmp->data); } else if (!strcmp (tmp->name, "title")) { title = trim((char*)tmp->data); } } if (src) { lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, 0, src, title, 0, 0); } } } } xml_parser_free_tree (root); } xml_parser_finalize_r (parser); } static void parse_rss (demux_playlist_t *this, char *data, int length) { xml_node_t *root, *node, *item, *tmp; xml_parser_t *parser; parser = xml_parser_init_r (data, length, XML_PARSER_CASE_SENSITIVE); if (!parser) { return; } if (xml_parser_build_tree_r (parser, &root) >= 0) { for (node = root; node; node = node->next) { if (!strcmp (node->name, "rss")) break; } if (node) { for (node = node->child; node; node = node->next) { if (strcmp (node->name, "channel")) continue; for (item = node->child; item; item = item->next) { if (!strcmp (item->name, "item")) { const char *title = NULL; const char *src = NULL; for (tmp = item->child; tmp; tmp = tmp->next) { if (!strcmp (tmp->name, "title")) { title = tmp->data; } else if (!strcmp (tmp->name, "enclosure")) { src = xml_parser_get_property (tmp, "url"); } } if (src) { lprintf ("mrl:'%s'\n", src); _x_demux_send_mrl_reference (this->stream, 0, src, title, 0, 0); } } } } } xml_parser_free_tree (root); } xml_parser_finalize_r (parser); } static void demux_playlist_send_headers (demux_plugin_t *this_gen) { demux_playlist_t *this = (demux_playlist_t *) this_gen; this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 0); _x_demux_control_start (this->stream); if (this->input->seek (this->input, 0, SEEK_SET) != 0) this->status = DEMUX_FINISHED; } static int demux_playlist_send_chunk (demux_plugin_t *this_gen) { demux_playlist_t *this = (demux_playlist_t *) this_gen; char *data = NULL; int length; length = this->input->get_length (this->input); if (length > 0) { data = malloc (length + 1); if (data) { length = this->input->read (this->input, data, length); if (length < 0) length = 0; data[length] = '\0'; } } else { char buf[1024]; int len; length = 0; while ((len = this->input->read (this->input, buf, sizeof(buf))) > 0) { void *tmp = realloc (data, length+len+1); if (!tmp) break; data = tmp; memcpy (data+length, buf, len); length += len; data[length] = '\0'; } } lprintf ("data:%p length:%d\n", data, length); if (data) { switch (this->playlist) { case XINE_PLT_REF: parse_ref (this, data, length); break; case XINE_PLT_M3U: parse_m3u (this, data, length); break; case XINE_PLT_RAM: parse_ram (this, data, length); break; case XINE_PLT_PLS: parse_pls (this, data, length); break; case XINE_PLT_ASX: parse_asx (this, data, length); break; case XINE_PLT_SMI: parse_smi (this, data, length); break; case XINE_PLT_QTL: parse_qtl (this, data, length); break; case XINE_PLT_XSPF: parse_xspf (this, data, length); break; case XINE_PLT_RSS: parse_rss (this, data, length); break; default: lprintf ("unexpected playlist type 0x%08x\n", this->playlist); break; } free (data); } this->status = DEMUX_FINISHED; return DEMUX_FINISHED; } static int demux_playlist_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { (void)this_gen; (void)start_pos; (void)start_time; (void)playing; return DEMUX_OK; } static int demux_playlist_get_status (demux_plugin_t *this_gen) { demux_playlist_t *this = (demux_playlist_t *) this_gen; return this->status; } static int demux_playlist_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_playlist_get_capabilities (demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_playlist_get_optional_data (demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_playlist_t *this; playlist_t playlist; switch (stream->content_detection_method) { case METHOD_BY_MRL: lprintf ("detect by extension\n"); playlist = detect_by_extension (input); break; case METHOD_BY_CONTENT: case METHOD_EXPLICIT: lprintf ("detect by content\n"); playlist = detect_by_content (input); break; default: return NULL; } if (playlist == XINE_PLT_NONE) return NULL; this = calloc (1, sizeof (demux_playlist_t)); if (!this) return NULL; this->xine = stream->xine; this->stream = stream; this->input = input; this->playlist = playlist; this->demux_plugin.send_headers = demux_playlist_send_headers; this->demux_plugin.send_chunk = demux_playlist_send_chunk; this->demux_plugin.seek = demux_playlist_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_playlist_get_status; this->demux_plugin.get_stream_length = demux_playlist_get_stream_length; this->demux_plugin.get_capabilities = demux_playlist_get_capabilities; this->demux_plugin.get_optional_data = demux_playlist_get_optional_data; this->demux_plugin.demux_class = class_gen; lprintf ("playlist:0x%08x (%s)\n", this->playlist, (char*)&this->playlist); return &this->demux_plugin; } static void *init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_playlist_class = { .open_plugin = open_plugin, .description = N_("Playlist demux plugin"), .identifier = "playlist", .mimetypes = "audio/mpegurl: m3u: M3U playlist;" "audio/x-mpegurl: m3u: M3U playlist;" //"audio/x-pn-realaudio: ram: RAM playlist;" //"audio/vnd.rn-realaudio: ram: RAM playlist;" "audio/x-scpls: pls: Winamp playlist;" "audio/x-ms-wax: wax, asx: WAX playlist;" "audio/x-ms-wvx: wvx, asx: WVX playlist;" "application/smil: smi, smil: SMIL playlist;" "application/x-quicktimeplayer: qtl: Quicktime playlist;" "application/xspf+xml: xspf: XSPF playlist;", .extensions = "m3u ram pls asx wax wvx smi smil qtl xspf rss", .dispose = NULL, }; return (void *)&demux_playlist_class; } /* * exported plugin catalog entry */ static const demuxer_info_t demux_info_playlist = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "playlist", XINE_VERSION_CODE, &demux_info_playlist, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/ebml.h0000644000175000017500000000605514647725152014405 0ustar meme/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * EBML parser * a lot of ideas from the gstreamer parser */ #ifndef EBML_H #define EBML_H #define EBML_STACK_SIZE 10 #define EBML_VERSION 1 /* EBML IDs */ #define EBML_ID_EBML 0x1A45DFA3 #define EBML_ID_EBMLVERSION 0x4286 #define EBML_ID_EBMLREADVERSION 0x42F7 #define EBML_ID_EBMLMAXIDLENGTH 0x42F2 #define EBML_ID_EBMLMAXSIZELENGTH 0x42F3 #define EBML_ID_DOCTYPE 0x4282 #define EBML_ID_DOCTYPEVERSION 0x4287 #define EBML_ID_DOCTYPEREADVERSION 0x4285 typedef struct ebml_elem_s { uint32_t id; off_t start; uint64_t len; } ebml_elem_t; typedef struct ebml_parser_s { /* xine stuff */ xine_t *xine; input_plugin_t *input; /* EBML Parser Stack Management */ ebml_elem_t elem_stack[EBML_STACK_SIZE]; int level; /* EBML Header Infos */ uint64_t version; uint64_t read_version; uint64_t max_id_len; uint64_t max_size_len; char *doctype; uint64_t doctype_version; uint64_t doctype_read_version; } ebml_parser_t; ebml_parser_t *new_ebml_parser (xine_t *xine, input_plugin_t *input) XINE_MALLOC; void dispose_ebml_parser (ebml_parser_t *ebml); /* check EBML header */ int ebml_check_header(ebml_parser_t *read); /* Element Header */ int ebml_read_elem_head(ebml_parser_t *ebml, ebml_elem_t *elem); uint32_t ebml_get_next_level(ebml_parser_t *ebml, ebml_elem_t *elem); int ebml_skip(ebml_parser_t *ebml, ebml_elem_t *elem); /* EBML types */ int ebml_read_uint(ebml_parser_t *ebml, ebml_elem_t *elem, uint64_t *val); #if 0 int ebml_read_sint(ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *val); #endif int ebml_read_float(ebml_parser_t *ebml, ebml_elem_t *elem, double *val); int ebml_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem, char *str); #if 0 int ebml_read_utf8(ebml_parser_t *ebml, ebml_elem_t *elem, char *str); #endif char *ebml_alloc_read_ascii(ebml_parser_t *ebml, ebml_elem_t *elem); #if 0 int ebml_read_date(ebml_parser_t *ebml, ebml_elem_t *elem, int64_t *date); #endif int ebml_read_master(ebml_parser_t *ebml, ebml_elem_t *elem); int ebml_read_binary(ebml_parser_t *ebml, ebml_elem_t *elem, void *binary); #endif /* EBML_H */ xine-lib-1.2/src/demuxers/demux_idcin.c0000644000175000017500000004312014647725152015743 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * CIN File Demuxer by Mike Melanson (melanson@pcisys.net) * For more information regarding the Id CIN file format, visit: * http://www.csse.monash.edu.au/~timf/ * * CIN is a somewhat quirky and ill-defined format. Here are some notes * for anyone trying to understand the technical details of this format: * * The format has no definite file signature. This is problematic for a * general-purpose media player that wants to automatically detect file * types. However, a CIN file does start with 5 32-bit numbers that * specify audio and video parameters. This demuxer gets around the lack * of file signature by performing sanity checks on those parameters. * Probabalistically, this is a reasonable solution since the number of * valid combinations of the 5 parameters is a very small subset of the * total 160-bit number space. * * Refer to the function demux_idcin_open() for the precise A/V parameters * that this demuxer allows. * * Next, each audio and video frame has a duration of 1/14 sec. If the * audio sample rate is a multiple of the common frequency 22050 Hz it will * divide evenly by 14. However, if the sample rate is 11025 Hz: * 11025 (samples/sec) / 14 (frames/sec) = 787.5 (samples/frame) * The way the CIN stores audio in this case is by storing 787 sample * frames in the first audio frame and 788 sample frames in the second * audio frame. Therefore, the total number of bytes in an audio frame * is given as: * audio frame #0: 787 * (bytes/sample) * (# channels) bytes in frame * audio frame #1: 788 * (bytes/sample) * (# channels) bytes in frame * audio frame #2: 787 * (bytes/sample) * (# channels) bytes in frame * audio frame #3: 788 * (bytes/sample) * (# channels) bytes in frame * * Finally, not all Id CIN creation tools agree on the resolution of the * color palette, apparently. Some creation tools specify red, green, and * blue palette components in terms of 6-bit VGA color DAC values which * range from 0..63. Other tools specify the RGB components as full 8-bit * values that range from 0..255. Since there are no markers in the file to * differentiate between the two variants, this demuxer uses the following * heuristic: * - load the 768 palette bytes from disk * - assume that they will need to be shifted left by 2 bits to * transform them from 6-bit values to 8-bit values * - scan through all 768 palette bytes * - if any bytes exceed 63, do not shift the bytes at all before * transmitting them to the video decoder */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_idcin" #define LOG_VERBOSE /* define LOG to output information about the A/V chunks that the * demuxer is dispatching to the engine */ /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_games.h" #define IDCIN_HEADER_SIZE 20 #define HUFFMAN_TABLE_SIZE 65536 #define IDCIN_FRAME_PTS_INC (90000 / 14) #define PALETTE_SIZE 256 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; off_t filesize; xine_bmiheader bih; unsigned char huffman_table[HUFFMAN_TABLE_SIZE]; xine_waveformatex wave; int audio_chunk_size1; int audio_chunk_size2; int current_audio_chunk; uint64_t pts_counter; } demux_idcin_t; static int demux_idcin_send_chunk(demux_plugin_t *this_gen) { demux_idcin_t *this = (demux_idcin_t *) this_gen; buf_element_t *buf = NULL; unsigned int command; unsigned char preamble[8]; unsigned char disk_palette[PALETTE_SIZE * 3]; palette_entry_t palette[PALETTE_SIZE]; int i; int remaining_sample_bytes; int scale_bits; /* figure out what the next data is */ if (this->input->read(this->input, (unsigned char *)&command, 4) != 4) { this->status = DEMUX_FINISHED; return this->status; } command = le2me_32(command); lprintf("command %d: ", command); if (command == 2) { lprintf("demux finished\n"); this->status = DEMUX_FINISHED; return this->status; } else { if (command == 1) { lprintf("load palette\n"); /* load a 768-byte palette and pass it to the demuxer */ if (this->input->read(this->input, disk_palette, PALETTE_SIZE * 3) != PALETTE_SIZE * 3) { this->status = DEMUX_FINISHED; return this->status; } /* scan the palette to figure out if it's 6- or 8-bit; * assume 6-bit palette until a value > 63 is seen */ scale_bits = 2; for (i = 0; i < PALETTE_SIZE * 3; i++) if (disk_palette[i] > 63) { scale_bits = 0; break; } /* convert palette to internal structure */ for (i = 0; i < PALETTE_SIZE; i++) { /* these are VGA color DAC values, which means they only range * from 0..63; adjust as appropriate */ palette[i].r = disk_palette[i * 3 + 0] << scale_bits; palette[i].g = disk_palette[i * 3 + 1] << scale_bits; palette[i].b = disk_palette[i * 3 + 2] << scale_bits; } buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_SPECIAL|BUF_FLAG_HEADER; buf->decoder_info[1] = BUF_SPECIAL_PALETTE; buf->decoder_info[2] = PALETTE_SIZE; buf->decoder_info_ptr[2] = &palette; buf->size = 0; buf->type = BUF_VIDEO_IDCIN; this->video_fifo->put (this->video_fifo, buf); } else lprintf("load video and audio\n"); } /* load the video frame */ if (this->input->read(this->input, preamble, 8) != 8) { this->status = DEMUX_FINISHED; return this->status; } remaining_sample_bytes = _X_LE_32(&preamble[0]) - 4; lprintf("dispatching %d video bytes\n", remaining_sample_bytes); while (remaining_sample_bytes) { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = BUF_VIDEO_IDCIN; if( this->filesize ) buf->extra_info->input_normpos = (int)( (double) (this->input->get_current_pos (this->input) - IDCIN_HEADER_SIZE - HUFFMAN_TABLE_SIZE) * 65535 / this->filesize ); buf->extra_info->input_time = this->pts_counter / 90; buf->pts = this->pts_counter; if (remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } /* all frames are intra-coded */ buf->decoder_flags |= BUF_FLAG_KEYFRAME; if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; lprintf("sending video buf with %d bytes, %"PRId64" pts\n", buf->size, buf->pts); this->video_fifo->put(this->video_fifo, buf); } /* load the audio frame */ if (this->audio_fifo && this->wave.nSamplesPerSec) { if (this->current_audio_chunk == 1) { remaining_sample_bytes = this->audio_chunk_size1; this->current_audio_chunk = 2; } else { remaining_sample_bytes = this->audio_chunk_size2; this->current_audio_chunk = 1; } lprintf("dispatching %d audio bytes\n", remaining_sample_bytes); while (remaining_sample_bytes) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_LE; if( this->filesize ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->filesize ); buf->extra_info->input_time = this->pts_counter / 90; buf->pts = this->pts_counter; if (remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read(this->input, buf->content, buf->size) != buf->size) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; break; } if (!remaining_sample_bytes) buf->decoder_flags |= BUF_FLAG_FRAME_END; lprintf("sending audio buf with %d bytes, %"PRId64" pts\n", buf->size, buf->pts); this->audio_fifo->put(this->audio_fifo, buf); } } this->pts_counter += IDCIN_FRAME_PTS_INC; return this->status; } /* returns 1 if the CIN file was opened successfully, 0 otherwise */ static int open_idcin_file(demux_idcin_t *this) { unsigned char header[IDCIN_HEADER_SIZE]; xine_bmiheader *bih = &this->bih; if (_x_demux_read_header(this->input, header, IDCIN_HEADER_SIZE) != IDCIN_HEADER_SIZE) return 0; /* * This is what you could call a "probabilistic" file check: Id CIN * files don't have a definite file signature. In lieu of such a marker, * perform sanity checks on the 5 header fields: * width, height: greater than 0, less than or equal to 1024 * audio sample rate: greater than or equal to 8000, less than or * equal to 48000, or 0 for no audio * audio sample width (bytes/sample): 0 for no audio, or 1 or 2 * audio channels: 0 for no audio, or 1 or 2 */ /* check the width */ bih->biWidth = _X_LE_32(&header[0]); if ((bih->biWidth == 0) || (bih->biWidth > 1024)) return 0; /* check the height */ bih->biHeight = _X_LE_32(&header[4]); if ((bih->biHeight == 0) || (bih->biHeight > 1024)) return 0; /* check the audio sample rate */ this->wave.nSamplesPerSec = _X_LE_32(&header[8]); if ((this->wave.nSamplesPerSec != 0) && ((this->wave.nSamplesPerSec < 8000) || (this->wave.nSamplesPerSec > 48000))) return 0; /* check the audio bytes/sample */ this->wave.wBitsPerSample = _X_LE_32(&header[12]) * 8; if (this->wave.wBitsPerSample > 16) return 0; /* check the audio channels */ this->wave.nChannels = _X_LE_32(&header[16]); if (this->wave.nChannels > 2) return 0; /* if execution got this far, qualify it as a valid Id CIN file * and continue loading */ lprintf("%dx%d video, %d Hz, %d channels, %d bit PCM audio\n", bih->biWidth, bih->biHeight, this->wave.nSamplesPerSec, this->wave.nChannels, this->wave.wBitsPerSample); /* file is qualified; skip over the signature bytes in the stream */ if (this->input->seek(this->input, IDCIN_HEADER_SIZE, SEEK_SET) != IDCIN_HEADER_SIZE) return 0; /* read the Huffman table */ if (this->input->read(this->input, this->huffman_table, HUFFMAN_TABLE_SIZE) != HUFFMAN_TABLE_SIZE) return 0; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, (this->wave.nChannels) ? 1 : 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, bih->biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, bih->biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->wave.nChannels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->wave.nSamplesPerSec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->wave.wBitsPerSample); this->filesize = this->input->get_length(this->input) - IDCIN_HEADER_SIZE - HUFFMAN_TABLE_SIZE; return 1; } static void demux_idcin_send_headers(demux_plugin_t *this_gen) { demux_idcin_t *this = (demux_idcin_t *) this_gen; buf_element_t *buf; uint32_t i; int size; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ this->bih.biSize = sizeof(xine_bmiheader) + HUFFMAN_TABLE_SIZE; size = this->bih.biSize; i = 0; do { buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_info[0] = IDCIN_FRAME_PTS_INC; /* initial video_step */ if (size > buf->max_size) { buf->size = buf->max_size; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER| BUF_FLAG_FRAMERATE; } else { buf->size = size; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER| BUF_FLAG_FRAMERATE|BUF_FLAG_FRAME_END; } if (i == 0) { memcpy(buf->content, &this->bih, sizeof(xine_bmiheader)); memcpy(buf->content + sizeof(xine_bmiheader), this->huffman_table, buf->size - sizeof(xine_bmiheader)); } else { memcpy(buf->content, this->huffman_table + i - sizeof(xine_bmiheader), buf->size); } buf->type = BUF_VIDEO_IDCIN; this->video_fifo->put (this->video_fifo, buf); size -= buf->size; i += buf->size; } while (size); if (this->audio_fifo && this->wave.nChannels) { /* initialize the chunk sizes */ if (this->wave.nSamplesPerSec % 14 != 0) { this->audio_chunk_size1 = (this->wave.nSamplesPerSec / 14) * this->wave.wBitsPerSample / 8 * this->wave.nChannels; this->audio_chunk_size2 = (this->wave.nSamplesPerSec / 14 + 1) * this->wave.wBitsPerSample / 8 * this->wave.nChannels; } else { this->audio_chunk_size1 = this->audio_chunk_size2 = (this->wave.nSamplesPerSec / 14) * this->wave.wBitsPerSample / 8 * this->wave.nChannels; } lprintf("audio_chunk_size[1,2] = %d, %d\n", this->audio_chunk_size1, this->audio_chunk_size2); buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_LE; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->wave.nSamplesPerSec; buf->decoder_info[2] = this->wave.wBitsPerSample; buf->decoder_info[3] = this->wave.nChannels; buf->size = sizeof(this->wave); memcpy(buf->content, &this->wave, buf->size); this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_idcin_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_idcin_t *this = (demux_idcin_t *) this_gen; (void)start_pos; (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; /* reposition stream past the Huffman tables */ this->input->seek(this->input, IDCIN_HEADER_SIZE + HUFFMAN_TABLE_SIZE, SEEK_SET); this->pts_counter = 0; this->current_audio_chunk = 1; } return this->status; } static int demux_idcin_get_status (demux_plugin_t *this_gen) { demux_idcin_t *this = (demux_idcin_t *) this_gen; return this->status; } static int demux_idcin_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_idcin_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_idcin_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_idcin_t *this; this = calloc(1, sizeof(demux_idcin_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_idcin_send_headers; this->demux_plugin.send_chunk = demux_idcin_send_chunk; this->demux_plugin.seek = demux_idcin_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_idcin_get_status; this->demux_plugin.get_stream_length = demux_idcin_get_stream_length; this->demux_plugin.get_capabilities = demux_idcin_get_capabilities; this->demux_plugin.get_optional_data = demux_idcin_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_idcin_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_idcin_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_idcin_class = { .open_plugin = open_plugin, .description = N_("Id Quake II Cinematic file demux plugin"), .identifier = "Id CIN", .mimetypes = NULL, .extensions = "cin", .dispose = NULL, }; return (void *)&demux_idcin_class; } xine-lib-1.2/src/demuxers/demux_slave.c0000644000175000017500000002730414647725152015775 0ustar meme/* * Copyright (C) 2000-2018 the xine project * May 2003 - Miguel Freitas * This plugin was sponsored by 1Control * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demuxer for slave "protocol" * master xine must be started with XINE_PARAM_BROADCASTER_PORT set, that is, * 'xine --broadcast-port ' */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_slave" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #define SCRATCH_SIZE 1024 #define CHECK_VPTS_INTERVAL 2*90000 #define NETWORK_PREBUFFER 90000 typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int64_t last_vpts; int send_newpts; /* additional decoder flags and other dec-spec. stuff */ uint32_t decoder_info[BUF_NUM_DEC_INFO]; /* pointers to dec-spec. stuff */ void *decoder_info_ptr[BUF_NUM_DEC_INFO]; xine_list_t *dec_infos; /* dec-spec. stuff */ uint8_t scratch[SCRATCH_SIZE+1]; int scratch_used; } demux_slave_t ; #define MAX_COMMAND_SIZE 20 static int demux_slave_next (demux_slave_t *this) { buf_element_t *buf; int n, i; char fifo_name[11]; uint8_t *p, *s; int64_t curvpts; /* fill the scratch buffer */ n = this->input->read(this->input, &this->scratch[this->scratch_used], SCRATCH_SIZE - this->scratch_used); if (n <= 0) { lprintf("connection closed\n"); this->status = DEMUX_FINISHED; return 0; } this->scratch_used += n; this->scratch[this->scratch_used] = '\0'; p = strchr(this->scratch,'\n'); s = strchr(this->scratch,' '); if( !s || s > p ) s = p; if( !p || !s || (s-this->scratch+1) > MAX_COMMAND_SIZE ) { lprintf("protocol error\n"); this->status = DEMUX_FINISHED; return 0; } *s++ = '\0'; p++; if( !strcmp(this->scratch,"buffer") ) { int32_t size ; /* size of _content_ */ uint32_t type; int64_t pts; /* presentation time stamp, used for a/v sync */ int64_t disc_off; /* discontinuity offset */ uint32_t decoder_flags; /* stuff like keyframe, is_header ... see below */ if( sscanf(s,"fifo=%10s size=%" SCNd32 " type=%" SCNu32 " pts=%" SCNd64 " disc=%" SCNd64 " flags=%" SCNu32, fifo_name, &size, &type, &pts, &disc_off, &decoder_flags) != 6 ) { lprintf("'buffer' command error\n"); this->status = DEMUX_FINISHED; return 0; } if( type == BUF_CONTROL_NEWPTS ) { this->send_newpts = 0; this->last_vpts = 0; } /* if we join an already existing broadcaster we must take care * of the initial pts. */ if( pts && this->send_newpts ) { _x_demux_control_newpts( this->stream, pts, 0 ); this->send_newpts = 0; } /* check if we are not late on playback. * that might happen if user hits "pause" on the master, for example. */ if( pts && (curvpts = this->stream->xine->clock->get_current_time(this->stream->xine->clock)) > (this->last_vpts + CHECK_VPTS_INTERVAL) ) { if( this->last_vpts && pts - (NETWORK_PREBUFFER/2) + this->stream->metronom->get_option(this->stream->metronom, METRONOM_VPTS_OFFSET) < curvpts ) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "we are running late, forcing newpts.\n"); _x_demux_control_newpts( this->stream, pts - NETWORK_PREBUFFER, 0 ); } this->last_vpts = curvpts; } if( !strcmp(fifo_name,"video") || !this->audio_fifo ) buf = this->video_fifo->buffer_pool_alloc(this->video_fifo); else buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); /* copy data to buf, either from stratch or network */ n = this->scratch_used - (p-this->scratch); if( n > size ) n = size; if( n ) memcpy(buf->content, p, n); if( n < size ) { if (this->input->read(this->input, &buf->content[n], size-n) != (size-n)) { buf->free_buffer(buf); this->status = DEMUX_FINISHED; return 0; } } p += n; n = this->scratch_used - (p-this->scratch); if( n ) memmove(this->scratch, p, n); this->scratch_used = n; /* populate our buf */ buf->size = size; buf->type = type; buf->pts = pts; buf->disc_off = disc_off; buf->decoder_flags = decoder_flags; /* set decoder info */ memcpy(buf->decoder_info, this->decoder_info, sizeof(this->decoder_info)); memcpy(buf->decoder_info_ptr, this->decoder_info_ptr, sizeof(this->decoder_info)); memset(this->decoder_info, 0, sizeof(this->decoder_info)); memset(this->decoder_info_ptr, 0, sizeof(this->decoder_info_ptr)); if( !strcmp(fifo_name,"video") ) this->video_fifo->put(this->video_fifo, buf); else if (this->audio_fifo) this->audio_fifo->put(this->audio_fifo, buf); else buf->free_buffer(buf); } else if( !strcmp(this->scratch,"decoder_info") ) { uint32_t decoder_info; int has_data; int size; if( sscanf(s,"index=%d decoder_info=%u has_data=%d", &i, &decoder_info, &has_data) != 3 || i < 0 || i >= BUF_NUM_DEC_INFO) { lprintf("'decoder_info' command error\n"); this->status = DEMUX_FINISHED; return 0; } this->decoder_info[i] = decoder_info; size = (has_data) ? decoder_info : 0; if( size ) { this->decoder_info_ptr[i] = malloc(size); xine_list_push_back(this->dec_infos, this->decoder_info_ptr[i]); } n = this->scratch_used - (p-this->scratch); if( n > size ) n = size; if( n ) memcpy(this->decoder_info_ptr[i], p, n); if( n < size ) { if (this->input->read(this->input, (char *)this->decoder_info_ptr[i]+n, size-n) != (size-n)) { this->status = DEMUX_FINISHED; return 0; } } p += n; n = this->scratch_used - (p-this->scratch); if( n ) memmove(this->scratch, p, n); this->scratch_used = n; } else if( !strcmp(this->scratch,"flush_engine") ) { _x_demux_flush_engine( this->stream ); n = this->scratch_used - (p-this->scratch); if( n ) memmove(this->scratch, p, n); this->scratch_used = n; } else { lprintf("unknown command '%s'\n", this->scratch); n = this->scratch_used - (p-this->scratch); if( n ) memmove(this->scratch, p, n); this->scratch_used = n; } return 1; } static int demux_slave_send_chunk (demux_plugin_t *this_gen) { demux_slave_t *this = (demux_slave_t *) this_gen; demux_slave_next(this); return this->status; } static int demux_slave_get_status (demux_plugin_t *this_gen) { demux_slave_t *this = (demux_slave_t *) this_gen; return this->status; } static void demux_slave_send_headers (demux_plugin_t *this_gen) { demux_slave_t *this = (demux_slave_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; _x_demux_control_start(this->stream); this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); this->last_vpts = 0; this->send_newpts = 1; } static int demux_slave_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_slave_t *this = (demux_slave_t *) this_gen; (void)this_gen; (void)start_pos; (void)start_time; (void)playing; return this->status; } static void demux_slave_dispose (demux_plugin_t *this_gen) { demux_slave_t *this = (demux_slave_t *) this_gen; void *data; xine_list_iterator_t ite; /* free all decoder information */ ite = NULL; while ((data = xine_list_next_value (this->dec_infos, &ite))) free(data); xine_list_delete(this->dec_infos); free (this); } static int demux_slave_get_stream_length(demux_plugin_t *this_gen) { (void)this_gen; return 0 ; /*FIXME: implement */ } static uint32_t demux_slave_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_slave_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { static const char slave_id_str[] = "master xine v1\n"; const size_t slave_id_str_len = strlen(slave_id_str); demux_slave_t *this; char scratch[sizeof(slave_id_str)]; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: if (_x_demux_read_header (input, scratch, slave_id_str_len) != (int)slave_id_str_len) return NULL; if (memcmp(scratch, slave_id_str, slave_id_str_len)) return NULL; break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } if (input->seek (input, slave_id_str_len, SEEK_SET) != (int)slave_id_str_len) return NULL; this = calloc(1, sizeof(demux_slave_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->dec_infos = xine_list_new(); this->demux_plugin.send_headers = demux_slave_send_headers; this->demux_plugin.send_chunk = demux_slave_send_chunk; this->demux_plugin.seek = demux_slave_seek; this->demux_plugin.dispose = demux_slave_dispose; this->demux_plugin.get_status = demux_slave_get_status; this->demux_plugin.get_stream_length = demux_slave_get_stream_length; this->demux_plugin.get_capabilities = demux_slave_get_capabilities; this->demux_plugin.get_optional_data = demux_slave_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; this->scratch_used = 0; memset(this->decoder_info, 0, sizeof(this->decoder_info)); memset(this->decoder_info_ptr, 0, sizeof(this->decoder_info_ptr)); return &this->demux_plugin; } static void *init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_slave_class = { .open_plugin = open_plugin, .description = "", .identifier = "slave", .mimetypes = NULL, .extensions = "slave://", .dispose = NULL, }; return (void *)&demux_slave_class; } /* * exported plugin catalog entry */ static const demuxer_info_t demux_info_slave = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "slave", XINE_VERSION_CODE, &demux_info_slave, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_matroska.h0000644000175000017500000000740414647725152016510 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * demultiplexer for matroska streams: shared header */ #ifndef _DEMUX_MATROSKA_H_ #define _DEMUX_MATROSKA_H_ #include #include #include #include #include #include #include #include #include #include #include "bswap.h" #include "ebml.h" #include "matroska.h" #define NUM_PREVIEW_BUFFERS 10 #define MAX_STREAMS 128 #define MAX_FRAMES 128 #define WRAP_THRESHOLD 90000 typedef struct { int track_num; off_t *pos; uint64_t *timecode; int num_entries; } matroska_index_t; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; input_plugin_t *input; int status; ebml_parser_t *ebml; /* segment element */ ebml_elem_t segment; uint64_t timecode_scale; int duration; /* in millis */ int preview_sent; int preview_mode; char *title; /* meta seek info */ int has_seekhead; int seekhead_handled; /* seek info */ matroska_index_t *indexes; int num_indexes; int first_cluster_found; int skip_to_timecode; int skip_for_track; /* tracks */ int num_tracks; int num_video_tracks; int num_audio_tracks; int num_sub_tracks; matroska_track_t *tracks[MAX_STREAMS]; size_t compress_maxlen; /* maintain editions, number and capacity */ int num_editions, cap_editions; matroska_edition_t **editions; /* block */ uint8_t *block_data; size_t block_data_size; /* current tracks */ matroska_track_t *video_track; /* to remove */ matroska_track_t *audio_track; /* to remove */ matroska_track_t *sub_track; /* to remove */ uint64_t last_timecode; int send_newpts; int buf_flag_seek; /* seekhead parsing */ int top_level_list_size; int top_level_list_max_size; off_t *top_level_list; /* event handling (chapter navigation) */ xine_event_queue_t *event_queue; } demux_matroska_t ; /* "entry points" for chapter handling. * The parser descends into "Chapters" elements at the _parse_ function, * and editions care about cleanup internally. */ int matroska_parse_chapters(demux_matroska_t*); void matroska_free_editions(demux_matroska_t*); /* Search an edition for the chapter matching a given timecode. * * Return: chapter index, or -1 if none is found. * * TODO: does not handle chapter end times yet. */ int matroska_get_chapter(demux_matroska_t*, uint64_t, matroska_edition_t**); #endif /* _DEMUX_MATROSKA_H_ */ xine-lib-1.2/src/demuxers/group_games.c0000644000175000017500000000454014647725152015766 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * This file contains plugin entries for several demuxers used in games */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include "group_games.h" /* * exported plugin catalog entries */ static const demuxer_info_t demux_info_plus_10 = { .priority = 10 }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "wve", XINE_VERSION_CODE, &demux_info_plus_10, demux_eawve_init_plugin}, { PLUGIN_DEMUX, 27, "idcin", XINE_VERSION_CODE, &demux_info_plus_10, demux_idcin_init_plugin }, { PLUGIN_DEMUX, 27, "ipmovie", XINE_VERSION_CODE, &demux_info_plus_10, demux_ipmovie_init_plugin }, { PLUGIN_DEMUX, 27, "vqa", XINE_VERSION_CODE, &demux_info_plus_10, demux_vqa_init_plugin }, { PLUGIN_DEMUX, 27, "wc3movie", XINE_VERSION_CODE, &demux_info_plus_10, demux_wc3movie_init_plugin }, { PLUGIN_DEMUX, 27, "roq", XINE_VERSION_CODE, &demux_info_plus_10, demux_roq_init_plugin }, { PLUGIN_DEMUX, 27, "str", XINE_VERSION_CODE, &demux_info_plus_10, demux_str_init_plugin }, { PLUGIN_DEMUX, 27, "film", XINE_VERSION_CODE, &demux_info_plus_10, demux_film_init_plugin }, { PLUGIN_DEMUX, 27, "smjpeg", XINE_VERSION_CODE, &demux_info_plus_10, demux_smjpeg_init_plugin }, { PLUGIN_DEMUX, 27, "fourxm", XINE_VERSION_CODE, &demux_info_plus_10, demux_fourxm_init_plugin }, { PLUGIN_DEMUX, 27, "vmd", XINE_VERSION_CODE, &demux_info_plus_10, demux_vmd_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/demuxers/demux_yuv_frames.c0000644000175000017500000001502614647725152017041 0ustar meme/* * Copyright (C) 2003-2018 the xine project * Copyright (C) 2003 Jeroen Asselman * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * dummy demultiplexer for raw yuv frames (delivered by v4l) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_yuv_frames" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #define WRAP_THRESHOLD 20000 typedef struct demux_yuv_frames_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int seek_flag; int64_t last_pts; } demux_yuv_frames_t ; static int demux_yuv_frames_get_status (demux_plugin_t *this_gen) { demux_yuv_frames_t *this = (demux_yuv_frames_t *) this_gen; return this->status; } static int switch_buf(demux_yuv_frames_t *this , buf_element_t *buf){ if (!buf) return 0; if (this->seek_flag) { this->seek_flag = 0; _x_demux_control_newpts(this->stream, buf->pts, BUF_FLAG_SEEK); } else if (llabs(this->last_pts - buf->pts) > WRAP_THRESHOLD) { _x_demux_control_newpts(this->stream, buf->pts, 0); } this->last_pts = buf->pts; switch (buf->type) { case BUF_VIDEO_I420: case BUF_VIDEO_YUY2: this->video_fifo->put(this->video_fifo, buf); return 1; /* 1, we still should read audio */ case BUF_AUDIO_LPCM_LE: if (!_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO)) _x_demux_control_newpts(this->stream, buf->pts, 0); this->audio_fifo->put(this->audio_fifo, buf); break; default: lprintf ("dhelp, unknown buffer type %08x\n", buf->type); buf->free_buffer(buf); } return 0; } static int demux_yuv_frames_send_chunk (demux_plugin_t *this_gen){ demux_yuv_frames_t *this = (demux_yuv_frames_t *) this_gen; buf_element_t *buf; do { if ( _x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO) ) buf = this->input->read_block (this->input, this->video_fifo, 0); else buf = this->input->read_block (this->input, this->audio_fifo, 0); } while (switch_buf(this, buf)); return this->status; } static void demux_yuv_frames_send_headers (demux_plugin_t *this_gen){ demux_yuv_frames_t *this = (demux_yuv_frames_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; _x_demux_control_start(this->stream); if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_AUDIO)) { buf = this->input->read_block(this->input, this->audio_fifo, 0); if (buf) this->audio_fifo->put(this->audio_fifo, buf); else this->status = DEMUX_FINISHED; } if(_x_stream_info_get(this->stream, XINE_STREAM_INFO_HAS_VIDEO)) { buf = this->input->read_block(this->input, this->video_fifo, 0); if (buf) this->video_fifo->put(this->video_fifo, buf); else this->status = DEMUX_FINISHED; } this->status = DEMUX_OK; } static int demux_yuv_frames_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_yuv_frames_t *this = (demux_yuv_frames_t *) this_gen; (void)start_pos; (void)start_time; (void)playing; this->seek_flag = 1; this->last_pts = 0; return this->status; } static int demux_yuv_frames_get_stream_length (demux_plugin_t *this_gen) { /* demux_yuv_frames_t *this = (demux_yuv_frames_t *) this_gen; */ (void)this_gen; return 0; } static uint32_t demux_yuv_frames_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_yuv_frames_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_yuv_frames_t *this; switch (stream->content_detection_method) { case METHOD_BY_CONTENT: return NULL; break; case METHOD_BY_MRL: { const char *const mrl = input->get_mrl (input); if (strncmp (mrl, "v4l:/", 5)) return NULL; } break; case METHOD_EXPLICIT: break; default: return NULL; } lprintf ("input accepted.\n"); /* * if we reach this point, the input has been accepted. */ this = calloc(1, sizeof(demux_yuv_frames_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_yuv_frames_send_headers; this->demux_plugin.send_chunk = demux_yuv_frames_send_chunk; this->demux_plugin.seek = demux_yuv_frames_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_yuv_frames_get_status; this->demux_plugin.get_stream_length = demux_yuv_frames_get_stream_length; this->demux_plugin.get_capabilities = demux_yuv_frames_get_capabilities; this->demux_plugin.get_optional_data = demux_yuv_frames_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } /* * demuxer class */ void *demux_yuv_frames_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_yuv_frames_class = { .open_plugin = open_plugin, .description = N_("YUV frames dummy demux plugin"), .identifier = "YUV_FRAMES", .mimetypes = NULL, .extensions = NULL, .dispose = NULL, }; return (void *)&demux_yuv_frames_class; } /* * vim:sw=3:sts=3: */ xine-lib-1.2/src/demuxers/demux_mpeg.c0000644000175000017500000011374614647725152015621 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demultiplexer for mpeg 1/2 program streams * reads streams of variable blocksizes */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "demux_mpeg" #define LOG_VERBOSE /* #define LOG */ #include "group_video.h" #include #include #include #define NUM_PREVIEW_BUFFERS 150 #define SCRATCH_SIZE 256 #define WRAP_THRESHOLD 120000 #define PTS_AUDIO 0 #define PTS_VIDEO 1 typedef struct demux_mpeg_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int preview_mode; int rate; int64_t last_pts[2]; int send_newpts; int buf_flag_seek; int has_pts; int num_audio; uint8_t audio_dvd[16]; uint8_t audio_lpcm[16]; uint8_t audio_mpeg[32]; int num_spu; uint8_t spu_dvd[32]; uint8_t spu_svcd[4]; uint8_t spu_cvd[4]; uint8_t tbuf[4096]; } demux_mpeg_t; /* code never reached, is it still usefull ?? */ /* * borrow a little knowledge from the Quicktime demuxer */ #include "bswap.h" #define QT_ATOM BE_FOURCC /* these are the known top-level QT atoms */ #define FREE_ATOM QT_ATOM('f', 'r', 'e', 'e') #define JUNK_ATOM QT_ATOM('j', 'u', 'n', 'k') #define MDAT_ATOM QT_ATOM('m', 'd', 'a', 't') #define MOOV_ATOM QT_ATOM('m', 'o', 'o', 'v') #define PNOT_ATOM QT_ATOM('p', 'n', 'o', 't') #define SKIP_ATOM QT_ATOM('s', 'k', 'i', 'p') #define WIDE_ATOM QT_ATOM('w', 'i', 'd', 'e') #define ATOM_PREAMBLE_SIZE 8 /* a little something for dealing with RIFF headers */ #define FOURCC_TAG BE_FOURCC #define RIFF_TAG FOURCC_TAG('R', 'I', 'F', 'F') #define WAVE_TAG FOURCC_TAG('W', 'A', 'V', 'E') #define AVI_TAG FOURCC_TAG('A', 'V', 'I', ' ') #define FOURXM_TAG FOURCC_TAG('4', 'X', 'M', 'V') /* arbitrary number of initial file bytes to check for an MPEG marker */ #define RIFF_CHECK_KILOBYTES 1024 #define MPEG_MARKER FOURCC_TAG( 0x00, 0x00, 0x01, 0xBA ) /* * This function traverses a file and looks for a mdat atom. Upon exit: * *mdat_offset contains the file offset of the beginning of the mdat * atom (that means the offset * of the 4-byte length preceding the * characters 'mdat') * *mdat_size contains the 4-byte size preceding the mdat characters in * the atom. Note that this will be 1 in the case of a 64-bit atom. * Both mdat_offset and mdat_size are set to -1 if not mdat atom was * found. * * Note: Do not count on the input stream being positioned anywhere in * particular when this function is finished. */ static void find_mdat_atom(input_plugin_t *input, off_t *mdat_offset, int64_t *mdat_size) { off_t atom_size; unsigned int atom; unsigned char atom_preamble[ATOM_PREAMBLE_SIZE]; /* init the passed variables */ *mdat_offset = *mdat_size = -1; /* take it from the top */ if (input->seek(input, 0, SEEK_SET) != 0) return; /* traverse through the input */ while (*mdat_offset == -1) { if (input->read(input, atom_preamble, ATOM_PREAMBLE_SIZE) != ATOM_PREAMBLE_SIZE) break; atom_size = _X_BE_32(&atom_preamble[0]); atom = _X_BE_32(&atom_preamble[4]); if (atom == MDAT_ATOM) { *mdat_offset = input->get_current_pos(input) - ATOM_PREAMBLE_SIZE; *mdat_size = atom_size; break; } /* make sure the atom checks out as some other top-level atom before * proceeding */ if ((atom != FREE_ATOM) && (atom != JUNK_ATOM) && (atom != MOOV_ATOM) && (atom != PNOT_ATOM) && (atom != SKIP_ATOM) && (atom != WIDE_ATOM)) break; /* 64-bit length special case */ if (atom_size == 1) { if (input->read(input, atom_preamble, ATOM_PREAMBLE_SIZE) != ATOM_PREAMBLE_SIZE) break; atom_size = _X_BE_32(&atom_preamble[0]); atom_size <<= 32; atom_size |= _X_BE_32(&atom_preamble[4]); atom_size -= ATOM_PREAMBLE_SIZE * 2; } else atom_size -= ATOM_PREAMBLE_SIZE; input->seek(input, atom_size, SEEK_CUR); } } static void reset_track_map (fifo_buffer_t *fifo) { if (fifo) { #if 0 /* not needed yet */ buf_element_t *buf = fifo->buffer_pool_alloc (fifo); buf->type = BUF_CONTROL_RESET_TRACK_MAP; buf->decoder_info[1] = -1; fifo->put (fifo, buf); #endif ; } } static uint32_t read_bytes (demux_mpeg_t *this, uint32_t n) { uint32_t res; uint32_t i; unsigned char buf[8]; _x_assert(n > 0); _x_assert(n <= 4); i = this->input->read (this->input, buf, n); if (i != n) { this->status = DEMUX_FINISHED; return 0; } switch (n) { case 1: res = buf[0]; break; case 2: res = (buf[0]<<8) | buf[1]; break; case 3: res = (buf[0]<<16) | (buf[1]<<8) | buf[2]; break; case 4: default: /* calm down gcc */ res = (buf[2]<<8) | buf[3] | (buf[1]<<16) | (buf[0] << 24); break; } return res; } /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) static void check_newpts( demux_mpeg_t *this, int64_t pts, int video ) { int64_t diff; diff = pts - this->last_pts[video]; if( !this->preview_mode && pts && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; this->last_pts[1-video] = 0; } if( !this->preview_mode && pts ) this->last_pts[video] = pts; } static int mpeg1_read_pts (demux_mpeg_t *this, int64_t *pts, uint32_t leadbyte) { union { uint32_t w; uint8_t b[4]; } tbuf; int64_t v; uint32_t w; if (this->input->read (this->input, &tbuf.b[0], 4) != 4) { this->status = DEMUX_FINISHED; return 1; } v = (uint64_t)(leadbyte & 0x0e) << 29; w = tbuf.w; #ifndef WORDS_BIGENDIAN /* gcc sees __builtin_bswap32 () here. */ w = (w >> 24) | ((w & 0xff0000) >> 8) | ((w & 0xff00) << 8) | (w << 24); #endif v |= (w >> 2) & 0x3fff8000; v |= (w >> 1) & 0x7fff; *pts = v; return 0; } static int mpeg2_read_pts (demux_mpeg_t *this, int64_t *pts) { union { uint32_t w[2]; uint8_t b[8]; } tbuf; int64_t v; uint32_t w; if (this->input->read (this->input, &tbuf.b[3], 5) != 5) { this->status = DEMUX_FINISHED; return 1; } v = (uint64_t)(tbuf.b[3] & 0x0e) << 29; w = tbuf.w[1]; #ifndef WORDS_BIGENDIAN /* gcc sees __builtin_bswap32 () here. */ w = (w >> 24) | ((w & 0xff0000) >> 8) | ((w & 0xff00) << 8) | (w << 24); #endif v |= (w >> 2) & 0x3fff8000; v |= (w >> 1) & 0x7fff; *pts = v; return 0; } static int64_t mpeg_get_pts (const uint8_t *p) { int64_t v = (uint64_t)(p[0] & 0x0e) << 29; uint32_t w = _X_BE_32 (p + 1); v |= (w >> 2) & 0x3fff8000; v |= (w >> 1) & 0x7fff; return v; } static void parse_mpeg2_packet (demux_mpeg_t *this, int stream_id, int64_t scr) { int normpos, itime; int64_t pts, dts; { off_t ilen = this->input->get_length (this->input); off_t ipos = this->input->get_current_pos (this->input); normpos = ilen > 0 ? (int64_t)ipos * 65535 / ilen : 0; itime = this->rate ? (int64_t)ipos * 20 / this->rate : 0; } (void)scr; //printf( "parse_mpeg2_packet: stream_id=%X\n", stream_id); if (stream_id==0xbd) { uint32_t len, flags, header_len; uint8_t *p = this->tbuf; if (this->input->read (this->input, p, 5) != 5) { this->status = DEMUX_FINISHED; return; } flags = p[3]; header_len = p[4]; len = (flags & 0x80) ? 5 : 0; if (header_len < len) header_len = len; len = _X_BE_16 (p); p += 5; if (this->input->read (this->input, p, header_len + 1) != (int)header_len + 1) { this->status = DEMUX_FINISHED; return; } pts = 0; if (flags & 0x80) pts = mpeg_get_pts (p); p += header_len; len -= header_len + 3; /* DVD spu/subtitles */ if ((p[0] & 0xe0) == 0x20) { int track = p[0] & 0x1f; len -= 1; /* register */ if (this->spu_dvd[track] == 255) { this->spu_dvd[track] = this->num_spu++; reset_track_map (this->video_fifo); } if (!this->video_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = BUF_FLAG_SPECIAL | (this->preview_mode ? BUF_FLAG_PREVIEW : 0); int type = BUF_SPU_DVD + this->spu_dvd[track]; while (len > 0) { buf_element_t *buf; int part; buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len); part = buf->max_size < (int)len ? buf->max_size : (int)len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = type; buf->decoder_flags = bufflags; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_PACKAGE; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->video_fifo->put (this->video_fifo, buf); pts = 0; } } return; } /* SVCD OGT subtitles are in stream 0x70 */ if (p[0] == 0x70) { len -= 1; if (!this->video_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { /* FIXME: previous code did use p[1] for track number without reading it first. * Assume that byte to be sent to decoder as well. */ int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0; int type = -1; while (len > 0) { buf_element_t *buf; int part; buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len); part = buf->max_size < (int)len ? buf->max_size : (int)len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; if (type < 0) { int track = buf->content[0] & 0x03; /* register */ if (this->spu_svcd[track] == 255) { this->spu_svcd[track] = this->num_spu++; reset_track_map (this->video_fifo); } type = BUF_SPU_SVCD + this->spu_svcd[track]; } buf->type = type; buf->decoder_flags = bufflags; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->video_fifo->put (this->video_fifo, buf); pts = 0; } lprintf ("SPU SVCD PACK (pts: %"PRId64", spu id: %d) put on FIFO\n", pts, type & 3); } /* There is a bug in WinSubMux doesn't redo PACK headers in the private stream 1. This might cause the below to mess up. if( !preview_mode ) check_newpts( this, this->pts, PTS_VIDEO ); */ return; } /* CVD subtitles are in stream 0x00-0x03 */ if ((p[0] & 0xfc) == 0x00) { int track = p[0] & 0x03; /* register */ if (this->spu_cvd[track] == 255) { this->spu_cvd[track] = this->num_spu++; reset_track_map (this->video_fifo); } len -= 1; if (!this->video_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0; while (len > 0) { buf_element_t *buf; int part; buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len); part = buf->max_size < (int)len ? buf->max_size : (int)len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = BUF_SPU_CVD + this->spu_cvd[track]; buf->decoder_flags = bufflags; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->video_fifo->put (this->video_fifo, buf); pts = 0; } } return; } if ((p[0] & 0xf0) == 0x80) { int track = p[0] & 0x0f; /* read rest of header - AC3 */ if (this->input->read (this->input, p + 1, 3) != 3) { this->status = DEMUX_FINISHED; return; } len -= 4; /* register */ if (this->audio_dvd[track] == 255) { this->audio_dvd[track] = this->num_audio++; reset_track_map (this->audio_fifo); } /* contents */ if (!this->audio_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0; /* DVDs only have 8 tracks */ int type = ((track & 0x8) ? BUF_AUDIO_DTS : BUF_AUDIO_A52) + this->audio_dvd[track]; check_newpts (this, pts, PTS_AUDIO); while (len > 0) { buf_element_t *buf; int part; buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len); part = buf->max_size < (int)len ? buf->max_size : (int)len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = type; buf->decoder_flags = bufflags; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->audio_fifo->put (this->audio_fifo, buf); pts = 0; } } return; } else if ((p[0] & 0xf0) == 0xa0) { int track = p[0] & 0x0f; if (this->input->read (this->input, p + 1, 6) != 6) { this->status = DEMUX_FINISHED; return; } len -= 7; /* register */ if (this->audio_lpcm[track] == 255) { this->audio_lpcm[track] = this->num_audio++; reset_track_map (this->audio_fifo); } if (!this->audio_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = BUF_FLAG_SPECIAL | (this->preview_mode ? BUF_FLAG_PREVIEW : 0); check_newpts (this, pts, PTS_AUDIO); while (len > 0) { buf_element_t *buf; int part; buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len); part = buf->max_size < (int)len ? buf->max_size : (int)len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = BUF_AUDIO_LPCM_BE + this->audio_lpcm[track]; buf->decoder_flags = bufflags; buf->decoder_info[1] = BUF_SPECIAL_LPCM_CONFIG; buf->decoder_info[2] = p[5]; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->audio_fifo->put (this->audio_fifo, buf); pts = 0; } } return; } else { this->input->seek (this->input, len - 1, SEEK_CUR); } } else if ((stream_id & 0xe0) == 0xc0) { int track = stream_id & 0x1f; uint32_t len, flags, header_len; uint8_t *p = this->tbuf; if (this->input->read (this->input, p, 5) != 5) { this->status = DEMUX_FINISHED; return; } flags = p[3]; header_len = p[4]; len = (flags & 0x80) ? 5 : 0; if (header_len < len) header_len = len; len = _X_BE_16 (p); p += 5; if (this->input->read (this->input, p, header_len) != (int)header_len) { this->status = DEMUX_FINISHED; return; } pts = 0; if (flags & 0x80) pts = mpeg_get_pts (p); len -= header_len + 3; /* register */ if (this->audio_mpeg[track] == 255) { this->audio_mpeg[track] = this->num_audio++; reset_track_map (this->audio_fifo); } if (!this->audio_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0; check_newpts (this, pts, PTS_AUDIO); while (len > 0) { buf_element_t *buf; int part; buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len); part = buf->max_size < (int)len ? buf->max_size : (int)len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = BUF_AUDIO_MPEG + this->audio_mpeg[track]; buf->decoder_flags = bufflags; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->audio_fifo->put (this->audio_fifo, buf); pts = 0; } } } else if ( ((stream_id >= 0xbc) && ((stream_id & 0xf0) == 0xe0)) || stream_id==0xfd ) { uint32_t len, flags, header_len; uint8_t *p = this->tbuf; if (this->input->read (this->input, p, 5) != 5) { this->status = DEMUX_FINISHED; return; } flags = p[3]; header_len = p[4]; len = ((flags & 0x80) ? 5 : 0) + ((flags & 0x40) ? 5 : 0); if (header_len < len) header_len = len; len = _X_BE_16 (p); p += 5; if (this->input->read (this->input, p, header_len) != (int)header_len) { this->status = DEMUX_FINISHED; return; } pts = 0; if (flags & 0x80) { pts = mpeg_get_pts (p); p += 5; } dts = 0; if (flags & 0x40) { dts = mpeg_get_pts (p); } len -= header_len + 3; /* contents */ if (!this->video_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0; check_newpts (this, pts, PTS_VIDEO); while (len > 0) { buf_element_t *buf; int part; buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len); part = buf->max_size < (int)len ? buf->max_size : (int)len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = (stream_id == 0xfd) ? BUF_VIDEO_VC1 : BUF_VIDEO_MPEG; buf->decoder_flags = bufflags; buf->decoder_info[0] = pts - dts; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->video_fifo->put (this->video_fifo, buf); pts = 0; } } } else { uint32_t len; uint8_t *p = this->tbuf; if (this->input->read (this->input, p, 2) != 2) { this->status = DEMUX_FINISHED; return; } len = _X_BE_16 (p); this->input->seek (this->input, len, SEEK_CUR); } } static void parse_mpeg1_packet (demux_mpeg_t *this, int stream_id, int64_t scr) { int len; uint32_t w; int normpos, itime; int64_t pts, dts; { off_t ilen = this->input->get_length (this->input); off_t ipos = this->input->get_current_pos (this->input); normpos = ilen > 0 ? (int64_t)ipos * 65535 / ilen : 0; itime = this->rate ? (int64_t)ipos * 20 / this->rate : 0; } len = read_bytes(this, 2); pts=0; dts=0; if (stream_id != 0xbf) { w = read_bytes(this, 1); len--; while ((w & 0x80) == 0x80) { if (this->status != DEMUX_OK) return; /* stuffing bytes */ w = read_bytes(this, 1); len--; } if ((w & 0xC0) == 0x40) { if (this->status != DEMUX_OK) return; /* buffer_scale, buffer size */ w = read_bytes(this, 1); len--; w = read_bytes(this, 1); len--; } if ((w & 0xF0) == 0x20) { if (this->status != DEMUX_OK) return; if (mpeg1_read_pts (this, &pts, w)) return; len -= 4; /* pts = 0; */ } else if ((w & 0xF0) == 0x30) { if (this->status != DEMUX_OK) return; if (mpeg1_read_pts (this, &pts, w)) return; len -= 4; if (mpeg2_read_pts (this, &dts)) return; len -= 5; } else { /* if (w != 0x0f) lprintf("ERROR w (%02x) != 0x0F ",w); */ } } if (pts && !this->has_pts) { lprintf("this stream has pts\n"); this->has_pts = 1; } else if (scr && !this->has_pts) { lprintf("use scr\n"); pts = scr; } if ((stream_id & 0xe0) == 0xc0) { int track = stream_id & 0x1f; /* register */ if (this->audio_mpeg[track] == 255) { this->audio_mpeg[track] = this->num_audio++; reset_track_map (this->audio_fifo); } if (!this->audio_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0; check_newpts (this, pts, PTS_AUDIO); while (len > 0) { buf_element_t *buf; int part; buf = this->audio_fifo->buffer_pool_size_alloc (this->audio_fifo, len); part = buf->max_size < len ? buf->max_size : len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = BUF_AUDIO_MPEG + this->audio_mpeg[track]; buf->decoder_flags = bufflags; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->audio_fifo->put (this->audio_fifo, buf); pts = 0; } } } else if ((stream_id & 0xf0) == 0xe0) { if (!this->video_fifo) { this->input->seek (this->input, len, SEEK_CUR); } else { int bufflags = this->preview_mode ? BUF_FLAG_PREVIEW : 0; check_newpts (this, pts, PTS_VIDEO); while (len > 0) { buf_element_t *buf; int part; buf = this->video_fifo->buffer_pool_size_alloc (this->video_fifo, len); part = buf->max_size < len ? buf->max_size : len; buf->size = this->input->read (this->input, buf->content, part); if (buf->size != part) { buf->free_buffer (buf); this->status = DEMUX_FINISHED; return; } len -= buf->size; if (len <= 0) bufflags |= BUF_FLAG_FRAME_END; buf->type = BUF_VIDEO_MPEG; buf->decoder_flags = bufflags; buf->decoder_info[0] = pts - dts; buf->pts = pts; buf->extra_info->input_normpos = normpos; buf->extra_info->input_time = itime; this->video_fifo->put (this->video_fifo, buf); pts = 0; } } } else if (stream_id == 0xbd) { this->input->seek (this->input, len, SEEK_CUR); } else { this->input->seek (this->input, len, SEEK_CUR); } } static uint32_t parse_pack(demux_mpeg_t *this) { uint32_t buf ; int mpeg_version; int64_t scr; uint8_t tbuf[20]; if (this->input->read (this->input, &tbuf[0], 12) != 12) { this->status = DEMUX_FINISHED; return 0; } if ((tbuf[0] >> 6) == 0x01) { int stuffing; mpeg_version = 2; /* system_clock_reference */ scr = (uint64_t)(tbuf[0] & 0x38) << 27; scr |= (uint32_t)(tbuf[0] & 0x03) << 28; scr |= (uint32_t) tbuf[1] << 20; scr |= (uint32_t)(tbuf[2] & 0xF8) << 12; scr |= (uint32_t)(tbuf[2] & 0x03) << 13; scr |= (uint32_t) tbuf[3] << 5; scr |= (uint32_t)(tbuf[4] & 0xF8) >> 3; /* tbuf[5] == extension */ /* mux_rate */ if (!this->rate) { this->rate = (uint32_t)tbuf[6] << 14; this->rate |= (uint32_t)tbuf[7] << 6; this->rate |= (uint32_t)tbuf[8] >> 2; } /* stuffing bytes */ stuffing = tbuf[9] & 0x03; if (this->input->read (this->input, &tbuf[12], 2 + stuffing) != 2 + stuffing) { this->status = DEMUX_FINISHED; return 0; } /* system header */ buf = _X_BE_32 (tbuf + 10 + stuffing); } else { mpeg_version = 1; /* system_clock_reference */ scr = (uint32_t)(tbuf[0] & 0x2) << 29; scr |= (uint32_t) tbuf[1] << 22; scr |= (uint32_t)(tbuf[2] & 0xfe) << 14; scr |= (uint32_t) tbuf[3] << 7; scr |= (uint32_t) tbuf[4] >> 1; /* mux_rate */ if (!this->rate) { this->rate = (uint32_t)(tbuf[5] & 0x7f) << 15; this->rate |= (uint32_t) tbuf[6] << 7; this->rate |= (uint32_t) tbuf[7] >> 1; lprintf ("mux_rate = %d\n",this->rate); } /* system header */ buf = _X_BE_32 (tbuf + 8); } /* lprintf("code = %08x\n",buf);*/ if (buf == 0x000001bb) { buf = read_bytes (this, 2); this->input->seek (this->input, buf, SEEK_CUR); buf = read_bytes (this, 4) ; } /* lprintf("code = %08x\n",buf); */ while ( ((buf & 0xFFFFFF00) == 0x00000100) && ((buf & 0xff) != 0xba) ) { if (this->status != DEMUX_OK) return buf; if (mpeg_version == 1) parse_mpeg1_packet (this, buf & 0xFF, scr); else parse_mpeg2_packet (this, buf & 0xFF, scr); buf = read_bytes (this, 4); } return buf; } static uint32_t parse_pack_preview (demux_mpeg_t *this, int *num_buffers) { uint32_t buf ; int mpeg_version; uint8_t tbuf[20]; if (this->input->read (this->input, &tbuf[0], 12) != 12) { this->status = DEMUX_FINISHED; return 0; } if ((tbuf[0] >> 6) == 0x01) { int stuffing; mpeg_version = 2; /* mux_rate */ if (!this->rate) { this->rate = (uint32_t)tbuf[6] << 14; this->rate |= (uint32_t)tbuf[7] << 6; this->rate |= (uint32_t)tbuf[8] >> 2; } /* stuffing bytes */ stuffing = tbuf[9] & 0x03; if (this->input->read (this->input, &tbuf[12], 2 + stuffing) != 2 + stuffing) { this->status = DEMUX_FINISHED; return 0; } /* system header */ buf = _X_BE_32 (tbuf + 10 + stuffing); } else { mpeg_version = 1; /* mux_rate */ if (!this->rate) { this->rate = (uint32_t)(tbuf[5] & 0x7f) << 15; this->rate |= (uint32_t) tbuf[6] << 7; this->rate |= (uint32_t) tbuf[7] >> 1; lprintf ("mux_rate = %d\n",this->rate); } /* system header */ buf = _X_BE_32 (tbuf + 8); } if (buf == 0x000001bb) { buf = read_bytes (this, 2); this->input->seek (this->input, buf, SEEK_CUR); buf = read_bytes (this, 4) ; } while ( ((buf & 0xFFFFFF00) == 0x00000100) && ((buf & 0xff) != 0xba) && (*num_buffers > 0)) { if (this->status != DEMUX_OK) return buf; if (mpeg_version == 1) parse_mpeg1_packet (this, buf & 0xFF, 0); else parse_mpeg2_packet (this, buf & 0xFF, 0); buf = read_bytes (this, 4); *num_buffers = *num_buffers - 1; } return buf; } static void demux_mpeg_resync (demux_mpeg_t *this, uint32_t buf) { if (INPUT_IS_SEEKABLE(this->input)) { off_t len, pos; /* fast resync, read 4K block at once */ pos = 0; len = 0; while ((buf != 0x000001ba) && (this->status == DEMUX_OK)) { if (pos == len) { len = this->input->read (this->input, this->tbuf, 4096); pos = 0; if (len <= 0) { this->status = DEMUX_FINISHED; break; } } buf = (buf << 8) | this->tbuf[pos]; pos++; } /* seek back to the pos of the 0x00001ba tag */ this->input->seek(this->input, pos-len, SEEK_CUR); } else { /* slow resync */ while ((buf !=0x000001ba) && (this->status == DEMUX_OK)) { buf = (buf << 8) | read_bytes (this, 1); } } } static int demux_mpeg_send_chunk (demux_plugin_t *this_gen) { demux_mpeg_t *this = (demux_mpeg_t *) this_gen; uint32_t w=0; w = parse_pack (this); if (w != 0x000001ba) demux_mpeg_resync (this, w); return this->status; } static int demux_mpeg_get_status (demux_plugin_t *this_gen) { demux_mpeg_t *this = (demux_mpeg_t *) this_gen; return this->status; } static void demux_mpeg_send_headers (demux_plugin_t *this_gen) { demux_mpeg_t *this = (demux_mpeg_t *) this_gen; uint32_t w; int num_buffers = NUM_PREVIEW_BUFFERS; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->rate = 0; /* fixme */ this->last_pts[0] = 0; this->last_pts[1] = 0; _x_demux_control_start(this->stream); /* * send preview buffers for stream/meta_info */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); this->preview_mode = 1; this->input->seek (this->input, 4, SEEK_SET); this->status = DEMUX_OK ; do { w = parse_pack_preview (this, &num_buffers); if (w != 0x000001ba) demux_mpeg_resync (this, w); num_buffers --; } while ( (this->status == DEMUX_OK) && (num_buffers > 0)); this->status = DEMUX_OK ; _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, this->rate * 50 * 8); } static int demux_mpeg_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_mpeg_t *this = (demux_mpeg_t *) this_gen; start_time /= 1000; start_pos = (off_t) ( ((int64_t)start_pos * this->input->get_length (this->input)) / 65535); if (INPUT_IS_SEEKABLE(this->input)) { if ( (!start_pos) && (start_time)) { start_pos = start_time; start_pos *= this->rate; start_pos *= 50; } this->input->seek (this->input, start_pos+4, SEEK_SET); if( start_pos ) demux_mpeg_resync (this, read_bytes(this, 4) ); } else read_bytes(this, 4); this->send_newpts = 1; this->status = DEMUX_OK ; if( !playing ) { this->preview_mode = 0; this->buf_flag_seek = 0; } else { this->buf_flag_seek = 1; _x_demux_flush_engine(this->stream); } return this->status; } static int demux_mpeg_get_stream_length (demux_plugin_t *this_gen) { demux_mpeg_t *this = (demux_mpeg_t *) this_gen; if (this->rate) return (int)((int64_t) 1000 * this->input->get_length (this->input) / (this->rate * 50)); else return 0; } static uint32_t demux_mpeg_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_AUDIOLANG | DEMUX_CAP_SPULANG; } static int demux_mpeg_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { demux_mpeg_t *this = (demux_mpeg_t *)this_gen; /* be a bit paranoid */ if (this == NULL || this->stream == NULL) return DEMUX_OPTIONAL_UNSUPPORTED; switch (data_type) { case DEMUX_OPTIONAL_DATA_AUDIOLANG: { char *str = data; int channel = *((int *)data); if ((channel < 0) || (channel >= this->num_audio)) { strcpy (str, "none"); } else { strcpy (str, "und"); return DEMUX_OPTIONAL_SUCCESS; } } break; case DEMUX_OPTIONAL_DATA_SPULANG: { char *str = data; int channel = *((int *)data); if ((channel < 0) || (channel >= this->num_spu)) { strcpy (str, "none"); } else { strcpy (str, "und"); return DEMUX_OPTIONAL_SUCCESS; } } break; default: ; } return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { /* Test our support first. */ switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { off_t mdat_atom_offset = -1; int64_t mdat_atom_size = -1; unsigned int fourcc_tag; int i, j, read; int ok = 0; uint8_t buf[SCRATCH_SIZE]; /* use demux_mpeg_block for block devices */ if (input->get_capabilities(input) & INPUT_CAP_BLOCK) return NULL; /* look for mpeg header */ read = _x_demux_read_header(input, buf, SCRATCH_SIZE); if (!read) return NULL; for (i = 0; i < read - 4; i++) { lprintf ("%02x %02x %02x %02x\n", buf[i], buf[i+1], buf[i+2], buf[i+3]); if (!buf[i] && !buf[i+1] && (buf[i+2] == 0x01) && (buf[i+3] == 0xba)) /* if so, take it */ { ok = 1; break; } } if (ok == 1) break; /* the special cases need seeking */ if (!INPUT_IS_SEEKABLE (input)) return NULL; /* special case for MPEG streams hidden inside QT files; check * is there is an mdat atom */ find_mdat_atom(input, &mdat_atom_offset, &mdat_atom_size); if (mdat_atom_offset != -1) { /* seek to the start of the mdat data, which might be in different * depending on the size type of the atom */ if (mdat_atom_size == 1) input->seek(input, mdat_atom_offset + 16, SEEK_SET); else input->seek(input, mdat_atom_offset + 8, SEEK_SET); /* go through the same MPEG detection song and dance */ if (input->read(input, buf, 4) == 4) { if (!buf[0] && !buf[1] && (buf[2] == 0x01) && (buf[3] == 0xba)) /* if so, take it */ break; } return NULL; } /* reset position for next check */ if (input->seek (input, 0, SEEK_SET) != 0) return NULL; /* special case for MPEG streams with a RIFF header */ fourcc_tag = _X_BE_32(&buf[0]); if (fourcc_tag == RIFF_TAG) { uint8_t large_buf[1024]; if (input->read (input, large_buf, 12) != 12) return NULL; fourcc_tag = _X_BE_32(&large_buf[8]); /* disregard the RIFF file if it is certainly a better known * format like AVI or WAVE */ if ((fourcc_tag == WAVE_TAG) || (fourcc_tag == AVI_TAG) || (fourcc_tag == FOURXM_TAG)) return NULL; /* Iterate through first n kilobytes of RIFF file searching for * MPEG video marker. No, it's not a very efficient approach, but * if execution has reached this special case, this is currently * the best chance for detecting the file automatically. Also, * be extra lazy and do not bother skipping over the data * header. */ for (i = 0; i < RIFF_CHECK_KILOBYTES && !ok; i++) { if (input->read(input, large_buf, 1024) != 1024) break; for (j = 0; j < 1024 - 4; j++) { if (_X_BE_32(&large_buf[j]) == MPEG_MARKER) { ok = 1; break; } } } if (ok) break; } return NULL; } case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; } /* OK now set up instance. */ { demux_mpeg_t *this = calloc (1, sizeof (demux_mpeg_t)); if (!this) return NULL; this->has_pts = 0; this->num_audio = 0; this->num_spu = 0; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_mpeg_send_headers; this->demux_plugin.send_chunk = demux_mpeg_send_chunk; this->demux_plugin.seek = demux_mpeg_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_mpeg_get_status; this->demux_plugin.get_stream_length = demux_mpeg_get_stream_length; this->demux_plugin.get_capabilities = demux_mpeg_get_capabilities; this->demux_plugin.get_optional_data = demux_mpeg_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; memset (this->audio_dvd, 255, sizeof (this->audio_dvd)); memset (this->audio_lpcm, 255, sizeof (this->audio_lpcm)); memset (this->audio_mpeg, 255, sizeof (this->audio_mpeg)); memset (this->spu_dvd, 255, sizeof (this->spu_dvd)); memset (this->spu_svcd, 255, sizeof (this->spu_svcd)); memset (this->spu_cvd, 255, sizeof (this->spu_cvd)); return &this->demux_plugin; } } void *demux_mpeg_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_mpeg_class = { .open_plugin = open_plugin, .description = N_("MPEG program stream demux plugin"), .identifier = "MPEG", .mimetypes = "video/mpeg: mpeg, mpg, mpe: MPEG animation;" "video/x-mpeg: mpeg, mpg, mpe: MPEG animation;", .extensions = "mpg mpeg", .dispose = NULL, }; return (void *)&demux_mpeg_class; } xine-lib-1.2/src/demuxers/demux_cdda.c0000644000175000017500000001664214647725152015561 0ustar meme/* * Copyright (C) 2001-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * CDDA "Demuxer" by Mike Melanson (melanson@pcisys.net) * All this demuxer does is read raw CD frames and shovel them to the * linear PCM "decoder" (which in turn sends them directly to the audio * output target; this is a really fancy CD-playing architecture). */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include /********** logging **********/ #define LOG_MODULE "demux_cdda" /* #define LOG_VERBOSE */ /* #define LOG */ #include #include #include #include #include "bswap.h" #include "group_audio.h" /* 44100 samples/sec * 2 bytes/samples * 2 channels */ #define CD_BYTES_PER_SECOND (44100 * 2 * 2) typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *video_fifo; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int send_newpts; int seek_flag; /* this is set when a seek just occurred */ } demux_cdda_t; static int demux_cdda_send_chunk (demux_plugin_t *this_gen) { demux_cdda_t *this = (demux_cdda_t *) this_gen; buf_element_t *buf = NULL; uint32_t blocksize; off_t len, pos; pos = this->input->get_current_pos (this->input); len = this->input->get_length (this->input); blocksize = this->input->get_blocksize(this->input); if (!blocksize) blocksize = 3 * 2352; buf = this->input->read_block(this->input, this->audio_fifo, blocksize); if (!buf) { this->status = DEMUX_FINISHED; return this->status; } buf->type = BUF_AUDIO_LPCM_LE; if (len > 0) { buf->extra_info->total_time = (int64_t)len * 1000 / CD_BYTES_PER_SECOND; buf->extra_info->input_normpos = (int)((double)pos * 65535 / len); } buf->pts = pos; buf->pts *= 90000; buf->pts /= CD_BYTES_PER_SECOND; buf->extra_info->input_time = buf->pts / 90; buf->decoder_flags |= BUF_FLAG_FRAME_END; if (this->send_newpts) { _x_demux_control_newpts(this->stream, buf->pts, this->seek_flag); this->send_newpts = this->seek_flag = 0; } this->audio_fifo->put (this->audio_fifo, buf); return this->status; } static void demux_cdda_send_headers(demux_plugin_t *this_gen) { demux_cdda_t *this = (demux_cdda_t *) this_gen; buf_element_t *buf; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_SEEKABLE, INPUT_IS_SEEKABLE(this->input)); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, 2); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, 44100); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, 16); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to decoders */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_LPCM_LE; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = 44100; buf->decoder_info[2] = 16; buf->decoder_info[3] = 2; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_cdda_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_cdda_t *this = (demux_cdda_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); start_time /= 1000; if (start_pos) this->input->seek(this->input, start_pos & ~3, SEEK_SET); else this->input->seek(this->input, start_time * CD_BYTES_PER_SECOND, SEEK_SET); this->status = DEMUX_OK; this->send_newpts = 1; if (playing) { this->seek_flag = BUF_FLAG_SEEK; _x_demux_flush_engine (this->stream); } return this->status; } static int demux_cdda_get_status (demux_plugin_t *this_gen) { demux_cdda_t *this = (demux_cdda_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_cdda_get_stream_length (demux_plugin_t *this_gen) { demux_cdda_t *this = (demux_cdda_t *) this_gen; return (int)((int64_t) this->input->get_length(this->input) * 1000 / CD_BYTES_PER_SECOND); } static uint32_t demux_cdda_get_capabilities(demux_plugin_t *this_gen){ (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_cdda_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type){ (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_cdda_t *this; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_EXPLICIT: break; case METHOD_BY_CONTENT: /* Avoid plugin loader probing us again after all others, especially after that still unstable avformat. */ if (input && input->input_class && input->input_class->identifier && !strcmp (input->input_class->identifier, "cdda")) break; /* fall through */ default: return NULL; } this = calloc(1, sizeof(demux_cdda_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_cdda_send_headers; this->demux_plugin.send_chunk = demux_cdda_send_chunk; this->demux_plugin.seek = demux_cdda_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_cdda_get_status; this->demux_plugin.get_stream_length = demux_cdda_get_stream_length; this->demux_plugin.get_capabilities = demux_cdda_get_capabilities; this->demux_plugin.get_optional_data = demux_cdda_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; return &this->demux_plugin; } void *demux_cdda_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const demux_class_t demux_cdda_class = { .open_plugin = open_plugin, .description = N_("CD Digital Audio demux plugin"), .identifier = "CDDA", .mimetypes = NULL, .extensions = "cdda:/", .dispose = NULL, }; return (void *)&demux_cdda_class; } xine-lib-1.2/src/input/0000755000175000017500000000000014647725152012612 5ustar memexine-lib-1.2/src/input/input_gnome_vfs.c0000644000175000017500000002242514647725152016165 0ustar meme/* * Copyright (C) 2000-2019 the xine project * 2002 Bastien Nocera * * This file is part of totem, * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "net_buf_ctrl.h" #include #ifdef __GNUC__ #define D(...) #else #define D(__VA_ARGS__) #endif /* #define D(...) g_message (__VA_ARGS__) */ /* #define LOG */ typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; nbc_t *nbc; /* File */ GnomeVFSHandle *fh; off_t curpos; char *mrl; GnomeVFSURI *uri; } gnomevfs_input_t; static off_t gnomevfs_plugin_get_current_pos (input_plugin_t *this_gen); static uint32_t gnomevfs_plugin_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_SEEKABLE | INPUT_CAP_SPULANG; } #define SSH_BUFFER_SIZE 256 * 1024 static off_t gnomevfs_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { char *buf = (char *)buf_gen; gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; off_t n, num_bytes; D("gnomevfs_plugin_read: %ld", (long int) len); num_bytes = 0; while (num_bytes < len) { GnomeVFSResult res; res = gnome_vfs_read (this->fh, &buf[num_bytes], (GnomeVFSFileSize) MIN (len - num_bytes, SSH_BUFFER_SIZE), (GnomeVFSFileSize *)&n); D("gnomevfs_plugin_read: read %ld from gnome-vfs", (long int) n); if (res != GNOME_VFS_OK && res != GNOME_VFS_ERROR_EOF) { D("gnomevfs_plugin_read: gnome_vfs_read returns %s", gnome_vfs_result_to_string (res)); return -1; } else if (res == GNOME_VFS_ERROR_EOF) { D("gnomevfs_plugin_read: GNOME_VFS_ERROR_EOF"); return num_bytes; } if (n <= 0) { g_warning ("input_gnomevfs: read error"); } num_bytes += n; this->curpos += n; } return num_bytes; } static buf_element_t* gnomevfs_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { off_t total_bytes; buf_element_t *buf = fifo->buffer_pool_alloc (fifo); if (todo > buf->max_size) todo = buf->max_size; if (todo < 0) { buf->free_buffer (buf); return NULL; } buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; total_bytes = gnomevfs_plugin_read (this_gen, buf->content, todo); if (total_bytes == todo) buf->size = todo; else { buf->free_buffer (buf); buf = NULL; } return buf; } static off_t gnomevfs_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; if (gnome_vfs_seek (this->fh, origin, offset) == GNOME_VFS_OK) { D ("gnomevfs_plugin_seek: %d", (int) (origin + offset)); return (off_t) (origin + offset); } else return (off_t) gnomevfs_plugin_get_current_pos (this_gen); } static off_t gnomevfs_plugin_get_current_pos (input_plugin_t *this_gen) { gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; GnomeVFSFileSize offset; if (this->fh == NULL) { D ("gnomevfs_plugin_get_current_pos: (this->fh == NULL)"); return 0; } if (gnome_vfs_tell (this->fh, &offset) == GNOME_VFS_OK) { D ("gnomevfs_plugin_get_current_pos: %d", (int) offset); return (off_t) offset; } else return 0; } static off_t gnomevfs_plugin_get_length (input_plugin_t *this_gen) { gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; GnomeVFSFileInfo *info; off_t length; if (this->fh == NULL) { D ("gnomevfs_plugin_get_length: (this->fh == NULL)"); return 0; } info = gnome_vfs_file_info_new (); if (gnome_vfs_get_file_info (this->mrl, info, GNOME_VFS_FILE_INFO_DEFAULT) == GNOME_VFS_OK) { length = info->size; gnome_vfs_file_info_unref (info); D ("gnomevfs_plugin_get_length: %lld", length); return length; } gnome_vfs_file_info_unref (info); return 0; } static uint32_t gnomevfs_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return 8 * 1024; } static const char* gnomevfs_plugin_get_mrl (input_plugin_t *this_gen) { gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; return this->mrl; } static int gnomevfs_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { D ("input_gnomevfs: get optional data, type %08x\n", data_type); (void)this_gen; (void)data; (void)data_type; return INPUT_OPTIONAL_UNSUPPORTED; } static void gnomevfs_plugin_dispose (input_plugin_t *this_gen ) { gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } if (this->fh) gnome_vfs_close (this->fh); _x_freep (&this->mrl); /* can't be null */ gnome_vfs_uri_unref (this->uri); free (this); } static int gnomevfs_plugin_open (input_plugin_t *this_gen ) { gnomevfs_input_t *this = (gnomevfs_input_t *) this_gen; GnomeVFSResult res; D("gnomevfs_klass_open: opening '%s'", this->mrl); res = gnome_vfs_open_uri (&this->fh, this->uri, GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_RANDOM); if (res != GNOME_VFS_OK) { int err; D("gnomevfs_klass_open: failed to open '%s': %s (%d)", this->mrl, gnome_vfs_result_to_string (res), res); switch (res) { case GNOME_VFS_ERROR_HOST_NOT_FOUND: err = XINE_MSG_UNKNOWN_HOST; break; case GNOME_VFS_ERROR_NOT_FOUND: err = XINE_MSG_FILE_NOT_FOUND; break; case GNOME_VFS_ERROR_ACCESS_DENIED: err = XINE_MSG_PERMISSION_ERROR; break; default: err = XINE_MSG_NO_ERROR; } if (err != XINE_MSG_NO_ERROR) { D("gnomevfs_klass_open: sending error %d", err); _x_message(this->stream, err, this->mrl, NULL); } return 0; } if (gnomevfs_plugin_get_length (this_gen) == 0) { _x_message(this->stream, XINE_MSG_FILE_EMPTY, this->mrl, NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_file: File empty: >%s<\n"), this->mrl); return 0; } return 1; } static const char ignore_scheme[][8] = { "cdda:", "file:", "ftp:", "ftpes:", "http:", "https:", "test:", "hls:"}; static input_plugin_t * gnomevfs_klass_get_instance (input_class_t *klass_gen, xine_stream_t *stream, const char *mrl) { gnomevfs_input_t *this; GnomeVFSURI *uri; unsigned i; if (mrl == NULL) return NULL; else if (strstr (mrl, "://") == NULL) return NULL; D("gnomevfs_klass_get_instance: %s", mrl); for (i = 0; i < G_N_ELEMENTS (ignore_scheme); i++) { if (strncmp (ignore_scheme[i], mrl, strlen (ignore_scheme[i])) == 0) return NULL; } uri = gnome_vfs_uri_new (mrl); if (uri == NULL) return NULL; D("Creating the structure for stream '%s'", mrl); this = calloc(1, sizeof(gnomevfs_input_t)); if (!this) { gnome_vfs_uri_unref(uri); return NULL; } this->stream = stream; this->fh = NULL; this->mrl = strdup (mrl); this->uri = uri; this->nbc = nbc_init (this->stream); this->input_plugin.open = gnomevfs_plugin_open; this->input_plugin.get_capabilities = gnomevfs_plugin_get_capabilities; this->input_plugin.read = gnomevfs_plugin_read; this->input_plugin.read_block = gnomevfs_plugin_read_block; this->input_plugin.seek = gnomevfs_plugin_seek; this->input_plugin.get_current_pos = gnomevfs_plugin_get_current_pos; this->input_plugin.get_length = gnomevfs_plugin_get_length; this->input_plugin.get_blocksize = gnomevfs_plugin_get_blocksize; this->input_plugin.get_mrl = gnomevfs_plugin_get_mrl; this->input_plugin.get_optional_data = gnomevfs_plugin_get_optional_data; this->input_plugin.dispose = gnomevfs_plugin_dispose; this->input_plugin.input_class = klass_gen; return &this->input_plugin; } static void *init_input_class (xine_t *xine, const void *data) { static const input_class_t input_gnomevfs_class = { .get_instance = gnomevfs_klass_get_instance, .identifier = "gnomevfs", .description = N_("gnome-vfs input plugin as shipped with xine"), .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, }; (void)data; xprintf (xine, XINE_VERBOSITY_DEBUG, "gnome_vfs init_input_class\n"); /* Don't initialise gnome-vfs, only gnome-vfs enabled applications * should be using it */ if (gnome_vfs_initialized () == FALSE) { xprintf (xine, XINE_VERBOSITY_DEBUG, "gnome-vfs not initialised\n"); return NULL; } #if !GLIB_CHECK_VERSION(2,32,0) if (!g_thread_supported ()) g_thread_init (NULL); #endif return (void *)&input_gnomevfs_class; } static const input_info_t input_info_gnomevfs = { .priority = 100, }; const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_INPUT | PLUGIN_NO_UNLOAD, 18, "gnomevfs", XINE_VERSION_CODE, &input_info_gnomevfs, init_input_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/input/input_ftp.c0000644000175000017500000005345014647725152014775 0ustar meme/* * Copyright (C) 2000-2021 the xine project * Copyright (C) 2018 Petri Hintukainen * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #define LOG_MODULE "input_ftp" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "group_network.h" #include "http_helper.h" #include "input_helper.h" #include "net_buf_ctrl.h" #include "tls/xine_tls.h" #define DEFAULT_FTP_PORT 21 typedef struct { input_plugin_t input_plugin; xine_t *xine; xine_stream_t *stream; nbc_t *nbc; char *mrl; char *mrl_private; char *uri; off_t curpos; off_t file_size; int cap_rest; xine_tls_t *tls; int fd_data; char buf[1024]; off_t preview_size; char preview[MAX_PREVIEW_SIZE]; } ftp_input_plugin_t; typedef struct { input_class_t input_class; xine_t *xine; xine_mrl_t **mrls; } ftp_input_class_t; /* * FTP protocol */ static int _read_response(ftp_input_plugin_t *this) { int rc; do { rc = _x_tls_read_line(this->tls, this->buf, sizeof(this->buf)); if (rc < 4) return -1; lprintf("<<< '%s'\n", this->buf); } while (this->buf[3] == '-'); rc = -1; if (this->buf[3] == ' ') { rc = atoi(this->buf); } return rc; } static int _write_command(ftp_input_plugin_t *this, const char *cmd) { size_t len; int rc = -1; lprintf(">>> %s\n", cmd); this->buf[0] = 0; len = strlen(cmd); rc = _x_tls_write(this->tls, cmd, len); if ((size_t)rc != len) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "send failed\n"); return -1; } rc = _x_tls_write(this->tls, "\r\n", 2); if (rc != 2) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "send CRLF failed\n"); return -1; } return 0; } static int _send_command(ftp_input_plugin_t *this, const char *cmd) { int rc; rc = _write_command(this, cmd); if (rc < 0) return rc; rc = _read_response(this); return rc; } static int _auth_tls(ftp_input_plugin_t *this, const char *host) { int rc; rc = _send_command(this, "AUTH TLS"); if (rc < 0 || (rc/100) > 3) { return -1; } rc = _x_tls_handshake(this->tls, host, -1); return rc; } static int _connect(ftp_input_plugin_t *this, int *fd, const char *host, int port) { _x_assert(*fd < 0); if (!port) port = DEFAULT_FTP_PORT; *fd = _x_io_tcp_connect (this->stream, host, port); if (*fd < 0) { return -1; } do { int rc = _x_io_tcp_connect_finish(this->stream, *fd, 1000); if (rc == XIO_READY) break; if (rc != XIO_TIMEOUT) return -1; } while (1); return 0; } static int _login(ftp_input_plugin_t *this, const char *user, const char *pass) { char *s; int rc; s = _x_asprintf("USER %s", user); if (!s) return -1; rc = _send_command(this, s); free(s); if (rc / 100 == 2) { return 0; } if (rc / 100 != 3) { return -1; } s = _x_asprintf("PASS %s", pass); if (!s) return -1; rc = _send_command(this, s); _x_freep_wipe_string(&s); if (rc / 100 == 2) { return 0; } return -1; } static int _ftp_connect(ftp_input_plugin_t *this, xine_url_t *url) { const char *user, *pass; int rc, fd = -1; rc = _connect(this, &fd, url->host, url->port); if (rc < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Connect to %s failed\n", this->mrl); if (fd >= 0) _x_io_tcp_close(this->stream, fd); return -1; } this->tls = _x_tls_init(this->xine, this->stream, fd); if (!this->tls) { if (fd >= 0) _x_io_tcp_close(this->stream, fd); return -1; } /* check prompt */ rc = _read_response(this); if (rc / 100 != 2) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "FTP connect failed: %s\n", this->buf); return -1; } if (!strcasecmp(url->proto, "ftpes")) { if (_auth_tls(this, url->host) < 0) { const char *help = NULL; if (_x_tls_get_verify_tls_cert(this->xine->config)) { help = "Disabling \'media.network.verify_tls_certificate\' may help."; } _x_message(this->stream, XINE_MSG_SECURITY, this->mrl, "TLS handshake failed. ", help, NULL); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "TLS handshake failed but TLS was requested for '%s'. %s\n", this->mrl, help ? help : ""); return -1; } xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "AUTH TLS succeed. Control connection is now encrypted.\n"); } if (!url->user) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "No username in mrl, logging in as anonymous\n"); } user = url->user ? url->user : "anonymous"; pass = url->password ? url->password : "anonymous@anonymous.org"; rc = _login(this, user, pass); if (rc < 0) { if (!url->user || !url->password) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Authentication required for '%s'\n", this->mrl); } else { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Authentication by password failed: %s\n", this->buf); } if (this->stream) _x_message(this->stream, XINE_MSG_AUTHENTICATION_NEEDED, this->mrl, "Authentication required", NULL); return -1; } /* check passive mode support */ rc = _send_command(this, "PASV"); if (rc / 100 != 2) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to set passive mode: %s\n", this->buf); return -1; } return 0; } static int _connect_data(ftp_input_plugin_t *this, char type) { char ip[16]; char *pt, *cmd; unsigned a1, a2, a3, a4, p1, p2; int rc; _x_assert(this->fd_data < 0); /* request passive mode */ rc = _send_command(this, "PASV"); if (rc / 100 != 2) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to set passive mode: %s\n", this->buf); return -1; } /* parse address */ pt = strchr(this->buf, '('); if (!pt) { return -1; } rc = sscanf(pt, "(%u,%u,%u,%u,%u,%u", &a1, &a2, &a3, &a4, &p1, &p2); if (rc != 6 || a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255 || p1 > 255 || p2 > 255) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Address parsing failed (%s)\n", this->buf); return -1; } sprintf(ip, "%u.%u.%u.%u", a1, a2, a3, a4); /* set transfer type */ cmd = _x_asprintf("TYPE %c", type); if (!cmd) return -1; rc = _send_command(this, cmd); free(cmd); if (rc / 100 != 2) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to set '%c' mode: %s\n", type, this->buf); return -1; } /* connect data stream */ rc = _connect(this, &this->fd_data, ip, (p1 << 8) | p2); if (rc < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to connect data stream.\n"); return -1; } return 0; } static int _cwd(ftp_input_plugin_t *this, const char *dir) { int rc; char *cmd; cmd = _x_asprintf("CWD %s", dir); if (!cmd) return -1; rc = _send_command(this, cmd); free(cmd); if (rc / 100 != 2) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error changing current directory to %s: %s\n", dir, this->buf); return -1; } return 0; } static int _list(ftp_input_plugin_t *this) { int rc; rc = _connect_data(this, 'A'); if (rc < 0) return -1; rc = _send_command(this, "LIST"); if (rc / 100 != 1) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Error listing files in verbose mode: %s\n", this->buf); rc = _send_command(this, "NLST"); if (rc / 100 != 1) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to list files: %s\n", this->buf); return -1; } } return 0; } static off_t _parse_off_t(const char *pt) { off_t off = 0; while (*pt >= '0' && *pt <= '9') { off = 10 * off + (*pt - '0'); pt++; } return off; } static int _ftp_size(ftp_input_plugin_t *this, const char *uri) { int rc; char *cmd; cmd = _x_asprintf("SIZE %s", uri); if (!cmd) return -1; rc = _send_command(this, cmd); free(cmd); if (rc / 100 != 2) return -1; this->file_size = _parse_off_t(this->buf + 4); xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "File size is %" PRId64 " bytes\n", (int64_t)this->file_size); return 0; } static int _abor(ftp_input_plugin_t *this) { int rc; rc = _write_command(this, "ABOR"); if (rc < 0) return rc; if (this->fd_data >= 0) { _x_io_tcp_close(this->stream, this->fd_data); this->fd_data = -1; /* this should return response code for initial RETR (426 or 226) if transferring */ rc = _read_response(this); } if (rc >= 0) { /* read ABRT response code */ rc = _read_response(this); } return rc; } static int _rest(ftp_input_plugin_t *this, off_t offset) { char *cmd; int rc; cmd = _x_asprintf("REST %" PRIu64, (uint64_t)offset); if (!cmd) return -1; rc = _send_command(this, cmd); free(cmd); if (rc < 0 || (rc/100) > 3) { return -1; } this->curpos = offset; this->cap_rest = 1; return 0; } static int _retr(ftp_input_plugin_t *this, const char *uri, off_t offset) { int rc; char *cmd; /* issue REST command even if starting from offset 0. * (to test REST support) */ _rest(this, offset); rc = _connect_data(this, 'I'); if (rc < 0) return -1; cmd = _x_asprintf("RETR %s", uri); if (!cmd) return -1; rc = _send_command(this, cmd); free(cmd); if (rc / 100 != 1) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to retrieve file %s: %s\n", uri, this->buf); return -1; } /* if SIZE failed, try to parse it from reply */ if (this->file_size < 1) { char *pt = strrchr(this->buf, '('); if (pt) { this->file_size = _parse_off_t(pt + 1); } } return 0; } /* * xine plugin */ static off_t _ftp_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { ftp_input_plugin_t *this = (ftp_input_plugin_t *) this_gen; uint8_t *buf = buf_gen; off_t got = 0; int rc; /* read from preview ? */ if (this->curpos < this->preview_size) { if (len > (this->preview_size - this->curpos)) got = this->preview_size - this->curpos; else got = len; memcpy (buf, &this->preview[this->curpos], got); } while (got < len) { rc = _x_io_tcp_read(this->stream, this->fd_data, buf + got, len - got); if (rc <= 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "FTP read failed\n"); if (got) break; return rc; } got += rc; if (_x_action_pending(this->stream)) { errno = EINTR; if (got) break; return -1; } } this->curpos += got; return got; } static off_t _ftp_get_length (input_plugin_t *this_gen) { ftp_input_plugin_t *this = (ftp_input_plugin_t *) this_gen; return this->file_size; } static off_t _ftp_get_current_pos (input_plugin_t *this_gen) { ftp_input_plugin_t *this = (ftp_input_plugin_t *) this_gen; return this->curpos; } static off_t _ftp_seek (input_plugin_t *this_gen, off_t offset, int origin) { ftp_input_plugin_t *this = (ftp_input_plugin_t *) this_gen; off_t r = _x_input_seek_preview(this_gen, offset, origin, &this->curpos, this->file_size, this->preview_size); if (r < 0 && this->cap_rest) { offset = _x_input_translate_seek(offset, origin, this->curpos, this->file_size); if (offset < 0) return -1; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "restarting transfer (seek from %" PRIu64 " to %" PRIu64 "\n", (uint64_t)this->curpos, (uint64_t)offset); if (_abor(this) < 0) return -1; if (_retr(this, this->uri, offset) < 0) return 0; this->preview_size = 0; return this->curpos; } return r; } static const char *_ftp_get_mrl (input_plugin_t *this_gen) { ftp_input_plugin_t *this = (ftp_input_plugin_t *) this_gen; return this->mrl; } static int _ftp_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { ftp_input_plugin_t *this = (ftp_input_plugin_t *)this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: if (!data || (this->preview_size <= 0)) break; memcpy (data, this->preview, this->preview_size); return this->preview_size; case INPUT_OPTIONAL_DATA_SIZED_PREVIEW: if (!data || (this->preview_size <= 0)) break; { int want; memcpy (&want, data, sizeof (want)); want = want < 0 ? 0 : want > this->preview_size ? this->preview_size : want; memcpy (data, this->preview, want); return want; } } return INPUT_OPTIONAL_UNSUPPORTED; } static void _ftp_dispose (input_plugin_t *this_gen) { ftp_input_plugin_t *this = (ftp_input_plugin_t *) this_gen; if (this->fd_data >= 0) { _x_io_tcp_close(this->stream, this->fd_data); this->fd_data = -1; } _x_tls_close(&this->tls); if (this->nbc) { nbc_close(this->nbc); this->nbc = NULL; } _x_freep (&this->mrl); _x_freep (&this->uri); _x_freep_wipe_string(&this->mrl_private); free (this_gen); } static int _fill_preview(ftp_input_plugin_t *this) { off_t got; got = _ftp_read (&this->input_plugin, this->preview, sizeof(this->preview)); if (got < 1 || got > (off_t)sizeof (this->preview)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unable to read preview data\n"); return -1; } this->preview_size = got; return 0; } static int _ftp_open (input_plugin_t *this_gen) { ftp_input_plugin_t *this = (ftp_input_plugin_t *)this_gen; xine_url_t url; int rc, result = 0; /* parse mrl */ rc = _x_url_parse2(this->mrl_private, &url); _x_freep_wipe_string(&this->mrl_private); if (!rc) { _x_message(this->stream, XINE_MSG_GENERAL_WARNING, "malformed url", NULL); return 0; } this->curpos = 0; rc = _ftp_connect(this, &url); if (rc < 0) goto out; _ftp_size(this, url.uri); rc = _retr(this, url.uri, 0); if (rc < 0) goto out; rc = _fill_preview(this); if (rc < 0) goto out; /* save URI for seeking (= ABRT + REST + RETR) */ this->uri = strdup(url.uri); if (!this->uri) goto out; result = 1; out: _x_url_cleanup(&url); return result; } static uint32_t _ftp_get_capabilities (input_plugin_t *this_gen) { ftp_input_plugin_t *this = (ftp_input_plugin_t *)this_gen; return INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW | (this->cap_rest ? INPUT_CAP_SLOW_SEEKABLE : 0); } static input_plugin_t *_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { ftp_input_class_t *class = (ftp_input_class_t *)cls_gen; ftp_input_plugin_t *this; if (strncasecmp (mrl, "ftp://", 6) && strncasecmp (mrl, "ftpes://", 8)) { return NULL; } this = calloc(1, sizeof(*this)); if (!this) { return NULL; } this->mrl_private = strdup(mrl); this->mrl = _x_mrl_remove_auth(mrl); this->stream = stream; this->xine = class->xine; this->curpos = 0; this->tls = NULL; this->fd_data = -1; this->input_plugin.open = _ftp_open; this->input_plugin.get_capabilities = _ftp_get_capabilities; this->input_plugin.read = _ftp_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = _ftp_seek; this->input_plugin.get_current_pos = _ftp_get_current_pos; this->input_plugin.get_length = _ftp_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = _ftp_get_mrl; this->input_plugin.get_optional_data = _ftp_get_optional_data; this->input_plugin.dispose = _ftp_dispose; this->input_plugin.input_class = cls_gen; if (stream) { /* not needed for directory browsing */ this->nbc = nbc_init (stream); } return &this->input_plugin; } /* * plugin class */ static xine_mrl_t **_get_files(ftp_input_plugin_t *this, const char *uri, int *nFiles) { xine_mrl_t **mrls; size_t n = 0, mrls_size = 64; int show_hidden_files; int rc; /* change working directory */ if (uri[0] && (uri[0] != '/' || uri[1])) { rc = _cwd(this, uri[0] == '/' ? uri+1 : uri); if (rc < 0) return NULL; } /* open directory */ if (_list(this) < 0) return NULL; mrls = _x_input_alloc_mrls(mrls_size); if (!mrls) return NULL; /* add ".." entry */ mrls[n]->type = mrl_net | mrl_file | mrl_file_directory; mrls[n]->origin = strdup(this->mrl); mrls[n]->mrl = _x_asprintf("%s/..", this->mrl); n++; show_hidden_files = _x_input_get_show_hidden_files(this->xine->config); while (1) { char buf[1024], *file; int is_dir = 0; rc = _x_io_tcp_read_line(this->stream, this->fd_data, buf, sizeof(buf)); if (rc <= 0) { if (rc < 0) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "FTP directory read failed\n"); break; } lprintf("<<< '%s'\n", buf); /* strip file info, try to detect directories */ file = strrchr(buf, ' '); if (!file) { file = buf; } else { *file++ = 0; if (buf[0] == 'd' || strstr(buf, "")) is_dir = 1; } if (!show_hidden_files && file[0] == '.') continue; if (n >= mrls_size) { mrls_size = mrls_size ? 2*mrls_size : 100; if (!(_x_input_realloc_mrls(&mrls, mrls_size))) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "out of memory while listing directory '%s'\n", uri); break; } } if (is_dir) mrls[n]->type = mrl_net | mrl_file | mrl_file_directory; else mrls[n]->type = mrl_net | mrl_file | mrl_file_normal; mrls[n]->origin = _x_asprintf("%s/", this->mrl); mrls[n]->mrl = _x_asprintf("%s/%s", this->mrl, file); n++; } if (n > 2) _x_input_sort_mrls(mrls + 1, n - 1); *nFiles = n; return mrls; } static xine_mrl_t **_get_dir_common (input_class_t *this_gen, const char *filename, int *nFiles) { ftp_input_class_t *this = (ftp_input_class_t *) this_gen; ftp_input_plugin_t *input; xine_url_t url; _x_assert(filename != NULL); if (!_x_url_parse2(filename, &url)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "malformed url '%s'", filename); return NULL; } input = (ftp_input_plugin_t *)_get_instance(this_gen, NULL, filename); if (!input) goto out; if (_ftp_connect(input, &url) < 0) goto out; this->mrls = _get_files(input, url.uri, nFiles); out: _x_url_cleanup(&url); if (input) input->input_plugin.dispose(&input->input_plugin); return this->mrls; } static xine_mrl_t **_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { ftp_input_class_t *this = (ftp_input_class_t *) this_gen; *nFiles = 0; _x_input_free_mrls(&this->mrls); if (!filename || !strcmp(filename, "ftp:/") || !strcmp(filename, "ftp://")) { this->mrls = _x_input_get_default_server_mrls(this->xine->config, "ftp:/", nFiles); return this->mrls; } return _get_dir_common(this_gen, filename, nFiles); } static xine_mrl_t **_get_dir_es (input_class_t *this_gen, const char *filename, int *nFiles) { ftp_input_class_t *this = (ftp_input_class_t *) this_gen; *nFiles = 0; _x_input_free_mrls(&this->mrls); if (!filename || !strcmp(filename, "ftpes:/") || !strcmp(filename, "ftpes://")) { this->mrls = _x_input_get_default_server_mrls(this->xine->config, "ftpes:/", nFiles); return this->mrls; } return _get_dir_common(this_gen, filename, nFiles); } static void _dispose_class (input_class_t *this_gen) { ftp_input_class_t *this = (ftp_input_class_t *)this_gen; _x_input_free_mrls(&this->mrls); free(this_gen); } void *input_ftp_init_class(xine_t *xine, const void *data) { ftp_input_class_t *this; (void)data; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->xine = xine; this->input_class.get_instance = _get_instance; this->input_class.description = N_("FTP input plugin"); this->input_class.identifier = "FTP"; this->input_class.get_dir = _get_dir; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = _dispose_class; this->input_class.eject_media = NULL; _x_input_register_show_hidden_files(xine->config); _x_input_register_default_servers(xine->config); return this; } void *input_ftpes_init_class(xine_t *xine, const void *data) { ftp_input_class_t *this; this = input_ftp_init_class(xine, data); if (this) { this->input_class.description = N_("FTPES input plugin"); this->input_class.identifier = "FTPES"; this->input_class.get_dir = _get_dir_es; } return this; } xine-lib-1.2/src/input/pnm.c0000644000175000017500000005311314647725152013553 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * pnm protocol implementation * based upon code from joschka */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #define LOG_MODULE "pnm" #define LOG_VERBOSE /* #define LOG */ #include "pnm.h" #include "libreal/rmff.h" #include "bswap.h" #include #include #include #define BUF_SIZE 4096 #define HEADER_SIZE 4096 struct pnm_s { xine_stream_t *stream; int s; char *host; int port; char *path; char *url; /* scratch buffer */ char buffer[BUF_SIZE]; /* receive buffer */ uint8_t recv[BUF_SIZE]; int recv_size; int recv_read; uint8_t header[HEADER_SIZE]; int header_len; int header_read; unsigned int seq_num[4]; /* two streams with two indices */ unsigned int seq_current[2]; /* seqs of last stream chunk read */ uint32_t ts_current; /* timestamp of current chunk */ uint32_t ts_last[2]; /* timestamps of last chunks */ unsigned int packet; /* number of last recieved packet */ }; /* sizes */ #define PREAMBLE_SIZE 8 #define CHECKSUM_SIZE 3 /* * data to construct header for real demuxer */ /* header of rm files */ #define RM_HEADER_SIZE 0x12 static const unsigned char rm_header[]={ 0x2e, 0x52, 0x4d, 0x46, /* object_id ".RMF" */ 0x00, 0x00, 0x00, 0x12, /* header_size 0x12 */ 0x00, 0x00, /* object_version 0x00 */ 0x00, 0x00, 0x00, 0x00, /* file_version 0x00 */ 0x00, 0x00, 0x00, 0x06 /* num_headers 0x06 */ }; /* data chunk header */ #define PNM_DATA_HEADER_SIZE 18 static const unsigned char pnm_data_header[]={ 'D','A','T','A', 0,0,0,0, /* data chunk size */ 0,0, /* object version */ 0,0,0,0, /* num packets */ 0,0,0,0}; /* next data header */ /* * data to be transmitted during stream request */ /* pnm request chunk ids */ #define PNA_CLIENT_CAPS 0x03 #define PNA_CLIENT_CHALLANGE 0x04 #define PNA_BANDWIDTH 0x05 #define PNA_GUID 0x13 #define PNA_TIMESTAMP 0x17 #define PNA_TWENTYFOUR 0x18 #define PNA_CLIENT_STRING 0x63 #define PNA_PATH_REQUEST 0x52 static const char pnm_challenge[] = "0990f6b4508b51e801bd6da011ad7b56"; static const char pnm_timestamp[] = "[15/06/1999:22:22:49 00:00]"; static const char pnm_guid[] = "3eac2411-83d5-11d2-f3ea-d7c3a51aa8b0"; static const char pnm_response[] = "97715a899cbe41cee00dd434851535bf"; static const char client_string[] = "WinNT_9.0_6.0.6.45_plus32_MP60_en-US_686l"; #define PNM_HEADER_SIZE 11 static const unsigned char pnm_header[] = { 'P','N','A', 0x00, 0x0a, 0x00, 0x14, 0x00, 0x02, 0x00, 0x01 }; #define PNM_CLIENT_CAPS_SIZE 126 static const unsigned char pnm_client_caps[] = { 0x07, 0x8a, 'p','n','r','v', 0, 0x90, 'p','n','r','v', 0, 0x64, 'd','n','e','t', 0, 0x46, 'p','n','r','v', 0, 0x32, 'd','n','e','t', 0, 0x2b, 'p','n','r','v', 0, 0x28, 'd','n','e','t', 0, 0x24, 'p','n','r','v', 0, 0x19, 'd','n','e','t', 0, 0x18, 'p','n','r','v', 0, 0x14, 's','i','p','r', 0, 0x14, 'd','n','e','t', 0, 0x24, '2','8','_','8', 0, 0x12, 'p','n','r','v', 0, 0x0f, 'd','n','e','t', 0, 0x0a, 's','i','p','r', 0, 0x0a, 'd','n','e','t', 0, 0x08, 's','i','p','r', 0, 0x06, 's','i','p','r', 0, 0x12, 'l','p','c','J', 0, 0x07, '0','5','_','6' }; static const uint32_t pnm_default_bandwidth=10485800; static const uint32_t pnm_available_bandwidths[]={14400,19200,28800,33600,34430,57600, 115200,262200,393216,524300,1544000,10485800}; #define PNM_TWENTYFOUR_SIZE 16 static const unsigned char pnm_twentyfour[]={ 0xd5, 0x42, 0xa3, 0x1b, 0xef, 0x1f, 0x70, 0x24, 0x85, 0x29, 0xb3, 0x8d, 0xba, 0x11, 0xf3, 0xd6 }; /* now other data follows. marked with 0x0000 at the beginning */ static const int after_chunks_length=6; static const unsigned char after_chunks[]={ 0x00, 0x00, /* mark */ 0x50, 0x84, /* seems to be fixated */ 0x1f, 0x3a /* varies on each request (checksum ?)*/ }; /* * pnm_get_chunk gets a chunk from stream * and returns number of bytes read, chunk_type, data and * a flag indicating whether the server want a response. * * following chunk format is expected (all in big endian!): * uint32_t chunk_type | * uint32_t chunk_size | <- preamble * uint8_t data[chunk_size-PREAMBLE_SIZE] * * a few exceptions have to be handeled: * if we read 0x72 as the first byte, we ignore CHECKSUM_SIZE bytes. * if we have an PNA_TAG, we need a different parsing; see below. */ static unsigned int pnm_get_chunk(pnm_t *p, unsigned int max, unsigned int *chunk_type, char *data, int *need_response) { unsigned int chunk_size; unsigned int n; char *ptr; if( max < PREAMBLE_SIZE ) return -1; /* get first PREAMBLE_SIZE bytes and ignore checksum */ if (_x_io_tcp_read (p->stream, p->s, data, CHECKSUM_SIZE) != CHECKSUM_SIZE) return -1; if (data[0] == 0x72) { if (_x_io_tcp_read (p->stream, p->s, data, PREAMBLE_SIZE) != PREAMBLE_SIZE) return -1; } else { const int sz = PREAMBLE_SIZE - CHECKSUM_SIZE; if (_x_io_tcp_read (p->stream, p->s, data+CHECKSUM_SIZE, sz) != sz) return -1; } max -= PREAMBLE_SIZE; *chunk_type = _X_BE_32(data); chunk_size = _X_BE_32(data + 4); switch (*chunk_type) { case PNA_TAG: *need_response=0; ptr=data+PREAMBLE_SIZE; if( max < 1 ) return -1; if (_x_io_tcp_read (p->stream, p->s, ptr++, 1) != 1) return -1; max -= 1; while(1) { /* The pna chunk is devided into subchunks. * expecting following chunk format (in big endian): * 0x4f * uint8_t chunk_size * uint8_t data[chunk_size] * * if first byte is 'X', we got a message from server * if first byte is 'F', we got an error */ if( max < 2 ) return -1; if (_x_io_tcp_read (p->stream, p->s, ptr, 2) != 2) return -1; max -= 2; if (*ptr == 'X') /* checking for server message */ { xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: got a message from server:\n"); if( max < 1 ) return -1; if (_x_io_tcp_read (p->stream, p->s, ptr+2, 1) != 1) return -1; max -= 1; /* two bytes of message length*/ n = _X_BE_16(ptr + 1); /* message itself */ if( max < n ) return -1; if (_x_io_tcp_read (p->stream, p->s, ptr+3, n) != n) return -1; max -= n; if( max < 1 ) return -1; ptr[3+n]=0; xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "%s\n", ptr+3); return -1; } if (*ptr == 'F') /* checking for server error */ { /* some error codes after 'F' were ignored */ xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: server error.\n"); return -1; } if (*ptr == 'i') /* the server want a response from us. it will be sent after these headers */ { ptr+=2; *need_response=1; continue; } if (*ptr != 0x4f) break; n=ptr[1]; if( max < n ) return -1; if (_x_io_tcp_read (p->stream, p->s, ptr+2, n) != n) return -1; ptr+=(n+2); max-=n; } /* the checksum of the next chunk is ignored here */ if( max < 1 ) return -1; if (_x_io_tcp_read (p->stream, p->s, ptr+2, 1) != 1) return -1; ptr+=3; chunk_size=ptr-data; break; case RMF_TAG: case DATA_TAG: case PROP_TAG: case MDPR_TAG: case CONT_TAG: if (chunk_size > max || chunk_size < PREAMBLE_SIZE) { xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "error: max chunk size exeeded (max was 0x%04x)\n", max); #ifdef LOG /* reading some bytes for debugging */ n=_x_io_tcp_read (p->stream, p->s, &data[PREAMBLE_SIZE], 0x100 - PREAMBLE_SIZE); xine_hexdump(data,n+PREAMBLE_SIZE); #endif return -1; } if (_x_io_tcp_read (p->stream, p->s, &data[PREAMBLE_SIZE], chunk_size-PREAMBLE_SIZE) != chunk_size-PREAMBLE_SIZE) return -1; break; default: *chunk_type = 0; chunk_size = PREAMBLE_SIZE; break; } return chunk_size; } /* * writes a chunk to a buffer, returns number of bytes written * chunk format (big endian): * uint16_t chunk_id * uint16_t length * uint8_t data[length] */ static int pnm_write_chunk(uint16_t chunk_id, uint16_t length, const char *chunk, char *data) { uint16_t be_id, be_len; be_id=be2me_16(chunk_id); be_len=be2me_16(length); memcpy(data , &be_id , 2); memcpy(data+2, &be_len, 2); memcpy(data+4, chunk , length); return length+4; } /* * constructs a request and sends it */ static int pnm_send_request(pnm_t *p, uint32_t bandwidth) { uint16_t i16; int c=PNM_HEADER_SIZE; char fixme[]={0,1}; (void)bandwidth; memcpy(p->buffer,pnm_header,PNM_HEADER_SIZE); c+=pnm_write_chunk(PNA_CLIENT_CHALLANGE,strlen(pnm_challenge), pnm_challenge,&p->buffer[c]); c+=pnm_write_chunk(PNA_CLIENT_CAPS,PNM_CLIENT_CAPS_SIZE, pnm_client_caps,&p->buffer[c]); c+=pnm_write_chunk(0x0a,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x0c,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x0d,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x16,2,fixme,&p->buffer[c]); c+=pnm_write_chunk(PNA_TIMESTAMP,strlen(pnm_timestamp), pnm_timestamp,&p->buffer[c]); c+=pnm_write_chunk(PNA_BANDWIDTH,4, (const char *)&pnm_default_bandwidth,&p->buffer[c]); c+=pnm_write_chunk(0x08,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x0e,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x0f,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x11,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x10,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x15,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(0x12,0,NULL,&p->buffer[c]); c+=pnm_write_chunk(PNA_GUID,strlen(pnm_guid), pnm_guid,&p->buffer[c]); c+=pnm_write_chunk(PNA_TWENTYFOUR,PNM_TWENTYFOUR_SIZE, pnm_twentyfour,&p->buffer[c]); /* data after chunks */ memcpy(&p->buffer[c],after_chunks,after_chunks_length); c+=after_chunks_length; /* client id string */ p->buffer[c]=PNA_CLIENT_STRING; i16=be2me_16(strlen(client_string)-1); /* dont know why do we have -1 here */ memcpy(&p->buffer[c+1],&i16,2); memcpy(&p->buffer[c+3],client_string,strlen(client_string)+1); c=c+3+strlen(client_string)+1; /* file path */ p->buffer[c]=0; p->buffer[c+1]=PNA_PATH_REQUEST; i16=be2me_16(strlen(p->path)); memcpy(&p->buffer[c+2],&i16,2); memcpy(&p->buffer[c+4],p->path,strlen(p->path)); c=c+4+strlen(p->path); /* some trailing bytes */ p->buffer[c]='y'; p->buffer[c+1]='B'; if (_x_io_tcp_write(p->stream,p->s,p->buffer,c+2) != c+2) return 0; return 1; } /* * pnm_send_response sends a response of a challenge */ static int pnm_send_response(pnm_t *p, const char *response) { /** @TODO should check that sze is always < 256 */ size_t size=strlen(response); p->buffer[0]=0x23; p->buffer[1]=0; p->buffer[2]=(unsigned char) size; memcpy(&p->buffer[3], response, size); if ((size_t)_x_io_tcp_write (p->stream, p->s, p->buffer, size + 3) != size + 3) return 0; return 1; } /* * get headers and challenge and fix headers * write headers to p->header * write challenge to p->buffer * * return 0 on error. != 0 on success */ static int pnm_get_headers(pnm_t *p, int *need_response) { uint32_t chunk_type; char *ptr=(char*)p->header; char *prop_hdr=NULL; int chunk_size,size=0; int nr =0; /* rmff_header_t *h; */ *need_response=0; while(1) { if (HEADER_SIZE-size<=0) { xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: header buffer overflow. exiting\n"); return 0; } chunk_size=pnm_get_chunk(p,HEADER_SIZE-size,&chunk_type,ptr,&nr); if (chunk_size < 0) return 0; if (chunk_type == 0) break; if (chunk_type == PNA_TAG) { memcpy(ptr, rm_header, RM_HEADER_SIZE); chunk_size=RM_HEADER_SIZE; *need_response=nr; } if (chunk_type == DATA_TAG) chunk_size=0; if (chunk_type == RMF_TAG) chunk_size=0; if (chunk_type == PROP_TAG) prop_hdr=ptr; size+=chunk_size; ptr+=chunk_size; } if (!prop_hdr) { xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: error while parsing headers.\n"); return 0; } /* set data offset */ { uint32_t be_size; be_size = be2me_32(size-1); memcpy(prop_hdr+42, &be_size, 4); } /* read challenge */ memcpy (p->buffer, ptr, PREAMBLE_SIZE); if (_x_io_tcp_read (p->stream, p->s, &p->buffer[PREAMBLE_SIZE], 64) != 64) return 0; /* now write a data header */ memcpy(ptr, pnm_data_header, PNM_DATA_HEADER_SIZE); size+=PNM_DATA_HEADER_SIZE; /* h=rmff_scan_header(p->header); rmff_fix_header(h); p->header_len=rmff_get_header_size(h); rmff_dump_header(h, p->header, HEADER_SIZE); */ p->header_len=size; return 1; } /* * determine correct stream number by looking at indices * FIXME: this doesn't work with all streams! There must be * another way to determine correct stream numbers! */ static int pnm_calc_stream(pnm_t *p) { uint8_t str0, str1; str0=0; str1=0; /* looking at the first index to * find possible stream types */ if (p->seq_current[0]==p->seq_num[0]) str0=1; if (p->seq_current[0]==p->seq_num[2]) str1=1; switch (str0+str1) { case 1: /* one is possible, good. */ if (str0) { p->seq_num[0]++; p->seq_num[1]=p->seq_current[1]+1; return 0; } else { p->seq_num[2]++; p->seq_num[3]=p->seq_current[1]+1; return 1; } break; case 0: case 2: /* both types or none possible, not so good */ /* try to figure out by second index */ if ( (p->seq_current[1] == p->seq_num[1]) &&(p->seq_current[1] != p->seq_num[3])) { /* ok, only stream0 matches */ p->seq_num[0]=p->seq_current[0]+1; p->seq_num[1]++; return 0; } if ( (p->seq_current[1] == p->seq_num[3]) &&(p->seq_current[1] != p->seq_num[1])) { /* ok, only stream1 matches */ p->seq_num[2]=p->seq_current[0]+1; p->seq_num[3]++; return 1; } /* wow, both streams match, or not. */ /* now we try to decide by timestamps */ if (p->ts_current < p->ts_last[1]) return 0; if (p->ts_current < p->ts_last[0]) return 1; /* does not help, we guess type 0 */ lprintf("guessing stream# 0\n"); p->seq_num[0]=p->seq_current[0]+1; p->seq_num[1]=p->seq_current[1]+1; return 0; break; } xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: wow, something very nasty happened in pnm_calc_stream\n"); return 2; } /* * gets a stream chunk and writes it to a recieve buffer */ static int pnm_get_stream_chunk(pnm_t *p) { unsigned int n; char keepalive='!'; unsigned int fof1, fof2, stream; /* send a keepalive */ /* realplayer seems to do that every 43th package */ if ((p->packet%43) == 42) { if (_x_io_tcp_write(p->stream,p->s,&keepalive,1) != 1) return 0; } /* data chunks begin with: 'Z' 'Z' * where is the offset to next stream chunk, * is a 16 bit index (big endian) * is a 8 bit index which counts from 0x10 to somewhere */ n = _x_io_tcp_read (p->stream, p->s, p->buffer, 8); if (n<8) return 0; /* skip 8 bytes if 0x62 is read */ if (p->buffer[0] == 0x62) { n = _x_io_tcp_read (p->stream, p->s, p->buffer, 8); if (n<8) return 0; lprintf("had to seek 8 bytes on 0x62\n"); } /* a server message */ if (p->buffer[0] == 'X') { int size=_X_BE_16 (&p->buffer[1]); if (size < 5) return 0; if (size + 3 >= BUF_SIZE) return 0; if (_x_io_tcp_read (p->stream, p->s, &p->buffer[8], size-5) != size-5) return 0; p->buffer[size+3]=0; xprintf(p->stream->xine, XINE_VERBOSITY_LOG, _("input_pnm: got message from server while reading stream:\n%s\n"), &p->buffer[3]); return 0; } if (p->buffer[0] == 'F') { xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: server error.\n"); return 0; } /* skip bytewise to next chunk. * seems, that we dont need that, if we send enough * keepalives */ n=0; while (p->buffer[0] != 0x5a) { memmove(p->buffer, &p->buffer[1], 8); if (_x_io_tcp_read (p->stream, p->s, &p->buffer[7], 1) != 1) return 0; n++; } #ifdef LOG if (n) printf("input_pnm: had to seek %i bytes to next chunk\n", n); #endif /* check for 'Z's */ if ((p->buffer[0] != 0x5a)||(p->buffer[7] != 0x5a)) { xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: bad boundaries\n"); #ifdef LOG xine_hexdump(p->buffer, 8); #endif return 0; } /* check offsets */ fof1=_X_BE_16 (&p->buffer[1]); fof2=_X_BE_16 (&p->buffer[3]); if (fof1 != fof2) { xprintf(p->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: frame offsets are different: 0x%04x 0x%04x\n", fof1, fof2); return 0; } /* get first index */ p->seq_current[0]=_X_BE_16 (&p->buffer[5]); /* now read the rest of stream chunk */ n = _x_io_tcp_read (p->stream, p->s, (char*)&p->recv[5], fof1-5); if (n<(fof1-5)) return 0; /* get second index */ p->seq_current[1]=p->recv[5]; /* get timestamp */ p->ts_current=_X_BE_32 (&p->recv[6]); /* get stream number */ stream=pnm_calc_stream(p); /* saving timestamp */ p->ts_last[stream]=p->ts_current; /* constructing a data packet header */ p->recv[0]=0; /* object version */ p->recv[1]=0; fof2=be2me_16(fof2); memcpy(&p->recv[2], &fof2, 2); /*p->recv[2]=(fof2>>8)%0xff;*/ /* length */ /*p->recv[3]=(fof2)%0xff;*/ p->recv[4]=0; /* stream number */ p->recv[5]=stream; p->recv[10]=p->recv[10] & 0xfe; /* streambox seems to do that... */ p->packet++; p->recv_size=fof1; return fof1; } pnm_t *pnm_connect(xine_stream_t *stream, const char *mrl) { const char *mrl_ptr, *slash, *colon; size_t pathbegin, hostend; pnm_t *p; int fd; int need_response=0; if (strncmp(mrl, "pnm://", 6)) { return NULL; } mrl_ptr = mrl + 6; p = calloc(1, sizeof(pnm_t)); if (!p) { return NULL; } p->stream = stream; p->port=7070; p->url=strdup(mrl); p->packet=0; p->s = -1; slash=strchr(mrl_ptr,'/'); colon=strchr(mrl_ptr,':'); if(!slash) slash=mrl_ptr+strlen(mrl_ptr)+1; if(!colon) colon=slash; if(colon > slash) colon=slash; pathbegin=slash-mrl_ptr; hostend=colon-mrl_ptr; p->host = strndup(mrl_ptr, hostend); if (pathbegin < strlen(mrl_ptr)) p->path=strdup(mrl_ptr+pathbegin+1); if (colon != slash) { strncpy(p->buffer,mrl_ptr+hostend+1, pathbegin-hostend-1); p->buffer[pathbegin-hostend-1]=0; p->port=atoi(p->buffer); } lprintf("got mrl: %s %i %s\n",p->host,p->port,p->path); fd = _x_io_tcp_connect (stream, p->host, p->port); if (fd == -1) { xprintf (p->stream->xine, XINE_VERBOSITY_LOG, _("input_pnm: failed to connect '%s'\n"), p->host); goto fail; } p->s=fd; if (!pnm_send_request(p,pnm_available_bandwidths[10])) goto fail; if (!pnm_get_headers(p, &need_response)) goto fail; if (need_response) if (!pnm_send_response(p, pnm_response)) goto fail; p->ts_last[0]=0; p->ts_last[1]=0; /* copy header to recv */ memcpy(p->recv, p->header, p->header_len); p->recv_size = p->header_len; p->recv_read = 0; return p; fail: xprintf (p->stream->xine, XINE_VERBOSITY_LOG, _("input_pnm: failed to set up stream\n")); pnm_close(p); return NULL; } int pnm_read (pnm_t *this, char *data, int len) { int to_copy=len; char *dest=data; char *source=(char*)(this->recv + this->recv_read); int fill=this->recv_size - this->recv_read; if (len < 0) return 0; while (to_copy > fill) { memcpy(dest, source, fill); to_copy -= fill; dest += fill; this->recv_read=0; if (!pnm_get_stream_chunk (this)) { lprintf ("%d of %d bytes provided\n", len-to_copy, len); return len-to_copy; } source = (char*)this->recv; fill = this->recv_size - this->recv_read; } memcpy(dest, source, to_copy); this->recv_read += to_copy; lprintf ("%d bytes provided\n", len); return len; } int pnm_peek_header (pnm_t *this, char *data, int maxsize) { int len; len = (this->header_len < maxsize) ? this->header_len : maxsize; memcpy(data, this->header, len); return len; } void pnm_close(pnm_t *p) { if (p->s >= 0) _x_io_tcp_close(p->stream, p->s); free(p->path); free(p->host); free(p->url); free(p); } xine-lib-1.2/src/input/input_dvb.c0000644000175000017500000031340514647725152014756 0ustar meme/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * Input plugin for Digital TV (Digital Video Broadcast - DVB) devices, * e.g. Hauppauge WinTV Nova supported by DVB drivers from Convergence. * * * MODIFICATION HISTORY * * Date Author * ---- ------ * * 01-Feb-2005 Pekka Jääskeläinen * * - This history log started. * - Disabled the automatic EPG updater thread until EPG demuxer * is done (it caused pausing of video stream), now EPG is * updated only on demand when the EPG OSD is displayed and * no data is in cache. * - Tried to stabilize the EPG updater thread. * - Fixed a tuning problem I had with Linux 2.6.11-rc2. * - Now tuning to an erroneous channel shouldn't hang but stop * the playback and output a log describing the error. * - Style cleanups here and there. * * 06-Apr-2006 Jack Steven Kelliher * - Add ATSC support * * TODO/Wishlist: (not in any order) * - Parse all Administrative PIDs - NIT,SDT,CAT etc * - As per James' suggestion, we need a way for the demuxer * to request PIDs from the input plugin. * - Timeshift ability. * - Pipe teletext infomation to a named fifo so programs such as * Alevtd can read it. * - Allow the user to view one set of PIDs (channel) while * recording another on the same transponder - this will require either remuxing or * perhaps bypassing the TS demuxer completely - we could easily have access to the * individual audio/video streams via seperate read calls, so send them to the decoders * and save the TS output to disk instead of passing it to the demuxer. * This also gives us full control over the streams being played..hmm..control... * - Parse and use full EIT for programming info. * - Allow the user to find and tune new stations from within xine, and * do away with the need for dvbscan & channels.conf file. * - Enable use of Conditional Access devices for scrambled content. * - if multiple cards are available, optionally use these to record/gather si info, * and leave primary card for viewing. * - allow for handing off of EPG data to specialised frontends, instead of displaying via * OSD - this will allow for filtering/searching of epg data - useful for automatic recording :) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* pthread.h must be included first so rest of the headers are imported thread safely (on some systems). However, including it before config.h causes problems with asprintf not being declared (glibc 2.3.6) */ #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #include #include #include #include #ifdef __sun #include #endif #include #include #ifdef HAVE_DIRENT_H #include #endif #include /* XDG */ #include #ifdef HAVE_DEV_DTV_DTVIO_H #include #else #include #include #endif #define LOG_MODULE "input_dvb" #define LOG_VERBOSE /* #define LOG #define LOG_READS */ #include #include #include #include "net_buf_ctrl.h" #include "input_helper.h" #define BUFSIZE 16384 #define DVB_NOPID 0xffff /* define stream types * administrative/system PIDs first */ #define INTERNAL_FILTER 0 #define PATFILTER 1 #define PMTFILTER 2 #define EITFILTER 3 #define PCRFILTER 4 #define VIDFILTER 5 #define AUDFILTER 6 #define AC3FILTER 7 #define TXTFILTER 8 #define MAX_FILTERS 9 #define MAX_AUTOCHANNELS 200 #define MAX_SUBTITLES 4 /* define for alternate non-buffered mode */ /* #define DVB_NO_BUFFERING */ /* Mouse button codes. */ #define MOUSE_BUTTON_LEFT 1 #define MOUSE_BUTTON_MIDDLE 2 #define MOUSE_BUTTON_RIGHT 3 #define MOUSE_WHEEL_UP 4 #define MOUSE_WHEEL_DOWN 5 /* The "thumb button" of my Intellimouse. */ #define MOUSE_SIDE_LEFT 6 #define MOUSE_SIDE_RIGHT 7 /* EPG settings. */ /* define to have EPG come up on left mouse click */ /* #define LEFT_MOUSE_DOES_EPG */ /* define to make EPG data updated in background in a separate thread */ /*#define EPG_UPDATE_IN_BACKGROUND */ /* Delay between EPG data updates in the EPG updater thread in seconds. */ #define EPG_UPDATE_DELAY 60 /* Width of the EPG OSD area. */ #define EPG_WIDTH 520 /* Height of the EPG OSD area. */ #define EPG_HEIGHT 620 /* Minimum top margin of the EPG in the video window. */ #define EPG_TOP 50 /* Font size of the channel name text. */ #define EPG_CHANNEL_FONT_SIZE 32 /* Font size of the clock. */ #define EPG_CLOCK_FONT_SIZE 18 /* Font size of the header text (duration and program name). */ #define EPG_TITLE_FONT_SIZE 24 /* Font size of the content type and rating text. */ #define EPG_CONTENT_FONT_SIZE 18 /* Font size of the program description text. */ #define EPG_DESCRIPTION_FONT_SIZE 18 #define EPG_PIXELS_BETWEEN_TEXT_ROWS 2 #define EPG_PIXELS_BETWEEN_PROGRAM_ENTRIES 2 /* How many pixels the background of the OSD is bigger than the text area? The margin is for each side of the background box. */ #define EPG_BACKGROUND_MARGIN 5 #define MAX_EPG_PROGRAM_NAME_LENGTH 255 #define MAX_EPG_PROGRAM_DESCRIPTION_LENGTH 255 #define MAX_EPG_CONTENT_TYPE_LENGTH 20 #define MAX_EPG_ENTRIES_PER_CHANNEL 10 /* How many seconds an EPG entry with the running flag on can be "late" according to the system time before discarding it as an old program? This margin is needed because in channel list OSD some EPG entries of some channels may be updated a very long ago (if user has watched another channel in different mux) so we have to resort to system clock for figuring out the current program. */ #define MAX_EPG_ENTRY_LATENESS 5*60.0 /* #define DEBUG_EPG */ /* Channel selector OSD settings. */ #define CHSEL_WIDTH 600 #define CHSEL_HEIGHT 400 #define CHSEL_CHANNEL_FONT_SIZE 26 #define CHSEL_PROGRAM_NAME_FONT_SIZE 12 #define bcdtoint(i) ((((i & 0xf0) >> 4) * 10) + (i & 0x0f)) typedef struct { int fd_frontend; int fd_pidfilter[MAX_FILTERS]; int fd_subfilter[MAX_SUBTITLES]; struct dvb_frontend_info feinfo; int adapter_num; char *dvr_device; char *demux_device; struct dmx_pes_filter_params pesFilterParams[MAX_FILTERS]; struct dmx_pes_filter_params subFilterParams[MAX_SUBTITLES]; struct dmx_sct_filter_params sectFilterParams[MAX_FILTERS]; xine_t *xine; } tuner_t; /* EPG entry. */ typedef struct { /* Program's name. */ char *progname; /* Textual description of the program. */ char *description; /* The content type string. */ char *content; /* Age recommendation. 0 if not available. */ short int rating; time_t starttime; /* Program's duration in hours + minutes. */ char duration_hours; char duration_minutes; /* Is this program running currently according to EPG data? */ char running; } epg_entry_t; typedef struct { char *name; struct dvb_frontend_parameters front_param; int pid[MAX_FILTERS]; int subpid[MAX_SUBTITLES]; int service_id; int sat_no; int tone; int pol; int pmtpid; int epg_count; epg_entry_t *epg[MAX_EPG_ENTRIES_PER_CHANNEL]; } channel_t; typedef struct { input_class_t input_class; xine_t *xine; int numchannels; char *autoplaylist[MAX_AUTOCHANNELS]; } dvb_input_class_t; typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; char *mrl; off_t curpos; nbc_t *nbc; tuner_t *tuner; channel_t *channels; int fd; /* Is channel tuned in correctly, i.e., can we read program stream? */ int tuned_in; int num_channels; int channel; pthread_mutex_t channel_change_mutex; osd_object_t *osd; osd_object_t *rec_osd; osd_object_t *name_osd; osd_object_t *paused_osd; osd_object_t *proginfo_osd; osd_object_t *channel_osd; osd_object_t *background; xine_event_queue_t *event_queue; /* Is the GUI enabled at all? */ int dvb_gui_enabled; /* simple vcr-like functionality */ int record_fd; int record_paused; /* centre cutout zoom */ int zoom_ok; /* Is EPG displaying? */ int epg_displaying; /* This is set to non-zero if the updater thread is wanted to stop. */ int epg_updater_stop; pthread_t epg_updater_thread; /* buffer for EIT data */ /*char *eitbuffer;*/ int num_streams_in_this_ts; /* number of timedout reads in plugin_read */ int read_failcount; #ifdef DVB_NO_BUFFERING int newchannel; #endif } dvb_input_plugin_t; typedef struct { char name[23]; uint8_t value; } Param; static const Param inversion_list [] = { { "INVERSION_OFF", INVERSION_OFF }, { "INVERSION_ON", INVERSION_ON }, { "INVERSION_AUTO", INVERSION_AUTO }, }; static const Param bw_list [] = { { "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ }, { "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ }, { "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ }, { "BANDWIDTH_AUTO", BANDWIDTH_AUTO }, }; static const Param fec_list [] = { { "FEC_1_2", FEC_1_2 }, { "FEC_2_3", FEC_2_3 }, { "FEC_3_4", FEC_3_4 }, { "FEC_4_5", FEC_4_5 }, { "FEC_5_6", FEC_5_6 }, { "FEC_6_7", FEC_6_7 }, { "FEC_7_8", FEC_7_8 }, { "FEC_8_9", FEC_8_9 }, { "FEC_AUTO", FEC_AUTO }, { "FEC_NONE", FEC_NONE }, }; static const Param guard_list [] = { {"GUARD_INTERVAL_1_16", GUARD_INTERVAL_1_16}, {"GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32}, {"GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4}, {"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8}, {"GUARD_INTERVAL_AUTO", GUARD_INTERVAL_AUTO}, }; static const Param hierarchy_list [] = { { "HIERARCHY_1", HIERARCHY_1 }, { "HIERARCHY_2", HIERARCHY_2 }, { "HIERARCHY_4", HIERARCHY_4 }, { "HIERARCHY_NONE", HIERARCHY_NONE }, { "HIERARCHY_AUTO", HIERARCHY_AUTO }, }; static const Param atsc_list [] = { { "8VSB", VSB_8 }, { "QAM_256", QAM_256 }, { "QAM_64", QAM_64 }, { "QAM", QAM_AUTO }, }; static const Param qam_list [] = { { "QPSK", QPSK }, { "QAM_128", QAM_128 }, { "QAM_16", QAM_16 }, { "QAM_256", QAM_256 }, { "QAM_32", QAM_32 }, { "QAM_64", QAM_64 }, { "QAM_AUTO", QAM_AUTO }, }; static const Param transmissionmode_list [] = { { "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K }, { "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K }, { "TRANSMISSION_MODE_AUTO", TRANSMISSION_MODE_AUTO }, }; static time_t dvb_mjdtime (uint8_t *buf); static void load_epg_data(dvb_input_plugin_t *this); static void show_eit(dvb_input_plugin_t *this); /* Utility Functions */ static void print_error(const char* estring) { printf("input_dvb: ERROR: %s\n", estring); } #ifdef DEBUG_EPG static void print_info(const char* estring) { printf("input_dvb: %s\n", estring); } #endif static unsigned int getbits(unsigned char *buffer, unsigned int bitpos, unsigned int bitcount) { unsigned int i; unsigned int val = 0; for (i = bitpos; i < bitcount + bitpos; i++) { val = val << 1; val = val + ((buffer[i >> 3] & (0x80 >> (i & 7))) ? 1 : 0); } return val; } static int find_descriptor(uint8_t tag, const unsigned char *buf, int descriptors_loop_len, const unsigned char **desc, int *desc_len) { while (descriptors_loop_len > 0) { unsigned char descriptor_tag = buf[0]; unsigned char descriptor_len = buf[1] + 2; if (!descriptor_len) { break; } if (tag == descriptor_tag) { if (desc) *desc = buf; if (desc_len) *desc_len = descriptor_len; return 1; } buf += descriptor_len; descriptors_loop_len -= descriptor_len; } return 0; } /* Extract UTC time and date encoded in modified julian date format and return it as a time_t. */ static time_t dvb_mjdtime (uint8_t *buf) { int i; unsigned int year, month, day, hour, min, sec; unsigned long int mjd; struct tm *tma = calloc(1, sizeof(struct tm)); time_t t; _x_assert(tma != NULL); mjd = (unsigned int)(buf[0] & 0xff) << 8; mjd +=(unsigned int)(buf[1] & 0xff); hour =(unsigned char)bcdtoint(buf[2] & 0xff); min = (unsigned char)bcdtoint(buf[3] & 0xff); sec = (unsigned char)bcdtoint(buf[4] & 0xff); year =(unsigned long)((mjd - 15078.2)/365.25); month=(unsigned long)((mjd - 14956.1 - (unsigned long)(year * 365.25))/30.6001); day = mjd - 14956 - (unsigned long)(year * 365.25) - (unsigned long)(month * 30.6001); if (month == 14 || month == 15) i = 1; else i = 0; year += i; month = month - 1 - i * 12; tma->tm_sec=sec; tma->tm_min=min; tma->tm_hour=hour; tma->tm_mday=day; tma->tm_mon=month-1; tma->tm_year=year; t = timegm(tma); free(tma); return t; } static void tuner_dispose(tuner_t * this) { int x; if (this->fd_frontend >= 0) close(this->fd_frontend); /* close all pid filter filedescriptors */ for (x = 0; x < MAX_FILTERS; x++) if (this->fd_pidfilter[x] >= 0) close(this->fd_pidfilter[x]); /* close all pid filter filedescriptors */ for (x = 0; x < MAX_SUBTITLES; x++) if (this->fd_subfilter[x] >= 0) close(this->fd_subfilter[x]); _x_freep(&this->dvr_device); _x_freep(&this->demux_device); free(this); } static tuner_t *XINE_MALLOC tuner_init(xine_t * xine, int adapter) { tuner_t *this; int x; int test_video; char *video_device = NULL; char *frontend_device = NULL; this = calloc(1, sizeof(tuner_t)); if (!this) { return NULL; } xprintf(this->xine, XINE_VERBOSITY_DEBUG, "tuner_init adapter=%d\n", adapter); this->fd_frontend = -1; memset(this->fd_pidfilter, 0, sizeof(this->fd_pidfilter)); this->xine = xine; this->adapter_num = adapter; this->demux_device = _x_asprintf("/dev/dvb/adapter%i/demux0",this->adapter_num); this->dvr_device = _x_asprintf("/dev/dvb/adapter%i/dvr0",this->adapter_num); video_device = _x_asprintf("/dev/dvb/adapter%i/video0",this->adapter_num); frontend_device = _x_asprintf("/dev/dvb/adapter%i/frontend0",this->adapter_num); if ((this->fd_frontend = xine_open_cloexec(frontend_device, O_RDWR)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "FRONTEND DEVICE: %s\n", strerror(errno)); tuner_dispose(this); this = NULL; goto exit; } _x_freep(&frontend_device); if ((ioctl(this->fd_frontend, FE_GET_INFO, &this->feinfo)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "FE_GET_INFO: %s\n", strerror(errno)); tuner_dispose(this); this = NULL; goto exit; } for (x = 0; x < MAX_FILTERS; x++) { this->fd_pidfilter[x] = xine_open_cloexec(this->demux_device, O_RDWR); if (this->fd_pidfilter[x] < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "DEMUX DEVICE PIDfilter: %s\n", strerror(errno)); tuner_dispose(this); this = NULL; goto exit; } } for (x = 0; x < MAX_SUBTITLES; x++) { this->fd_subfilter[x] = xine_open_cloexec(this->demux_device, O_RDWR); if (this->fd_subfilter[x] < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "DEMUX DEVICE Subtitle filter: %s\n", strerror(errno)); } } /* open EIT with NONBLOCK */ if(fcntl(this->fd_pidfilter[EITFILTER], F_SETFL, O_NONBLOCK)<0) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"input_dvb: couldn't set EIT to nonblock: %s\n",strerror(errno)); /* and the internal filter used for PAT & PMT */ if(fcntl(this->fd_pidfilter[INTERNAL_FILTER], F_SETFL, O_NONBLOCK)<0) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"input_dvb: couldn't set INTERNAL to nonblock: %s\n",strerror(errno)); /* and the frontend */ fcntl(this->fd_frontend, F_SETFL, O_NONBLOCK); xprintf(this->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Frontend is <%s> ",this->feinfo.name); if(this->feinfo.type==FE_QPSK) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"SAT Card\n"); if(this->feinfo.type==FE_QAM) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"CAB Card\n"); if(this->feinfo.type==FE_OFDM) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"TER Card\n"); if(this->feinfo.type==FE_ATSC) xprintf(this->xine,XINE_VERBOSITY_DEBUG,"US Card\n"); if ((test_video=xine_open_cloexec(video_device, O_RDWR)) < 0) { xprintf(this->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Card has no hardware decoder\n"); }else{ xprintf(this->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Card HAS HARDWARE DECODER\n"); close(test_video); } exit: free(video_device); free(frontend_device); return this; } static int dvb_set_pidfilter(dvb_input_plugin_t * this, int filter, ushort pid, int pidtype, int taptype) { tuner_t *tuner = this->tuner; if(this->channels[this->channel].pid [filter] !=DVB_NOPID) { ioctl(tuner->fd_pidfilter[filter], DMX_STOP); } this->channels[this->channel].pid [filter] = pid; tuner->pesFilterParams[filter].pid = pid; tuner->pesFilterParams[filter].input = DMX_IN_FRONTEND; tuner->pesFilterParams[filter].output = taptype; tuner->pesFilterParams[filter].pes_type = pidtype; tuner->pesFilterParams[filter].flags = DMX_IMMEDIATE_START; if (ioctl(tuner->fd_pidfilter[filter], DMX_SET_PES_FILTER, &tuner->pesFilterParams[filter]) < 0) { xprintf(tuner->xine, XINE_VERBOSITY_DEBUG, "input_dvb: set_pid: %s\n", strerror(errno)); return 0; } return 1; } static int dvb_set_sectfilter(dvb_input_plugin_t * this, int filter, ushort pid, int pidtype, uint8_t table, uint8_t mask) { tuner_t *tuner = this->tuner; (void)pidtype; if(this->channels[this->channel].pid [filter] !=DVB_NOPID) { ioctl(tuner->fd_pidfilter[filter], DMX_STOP); } this->channels[this->channel].pid [filter] = pid; tuner->sectFilterParams[filter].pid = pid; memset(&tuner->sectFilterParams[filter].filter.filter,0,DMX_FILTER_SIZE); memset(&tuner->sectFilterParams[filter].filter.mask,0,DMX_FILTER_SIZE); tuner->sectFilterParams[filter].timeout = 0; tuner->sectFilterParams[filter].filter.filter[0] = table; tuner->sectFilterParams[filter].filter.mask[0] = mask; tuner->sectFilterParams[filter].flags = DMX_IMMEDIATE_START; if (ioctl(tuner->fd_pidfilter[filter], DMX_SET_FILTER, &tuner->sectFilterParams[filter]) < 0){ xprintf(tuner->xine, XINE_VERBOSITY_DEBUG, "input_dvb: set_sectionfilter: %s\n", strerror(errno)); return 0; } return 1; } static int find_param_0(const Param *list, size_t list_size, const char *name) { size_t i; for (i = 0; i < list_size; i++) if (!strncmp(list[i].name, name, sizeof(list[0].name))) return list[i].value; return 0; } #define find_param(list, name) \ find_param_0(list, sizeof(list)/sizeof(list[0]), name) static int extract_channel_from_string_internal(channel_t * channel,char * str,fe_type_t fe_type) { /* try to extract channel data from a string in the following format (DVBS) QPSK: :::::: (DVBC) QAM: ::::::: (DVBT) OFDM: ::: :::: :::: (DVBA) ATSC: :::: = any string not containing ':' = unsigned long = 'v' or 'h' = unsigned long, usually 0 :D = symbol rate in MSyms/sec = INVERSION_ON | INVERSION_OFF | INVERSION_AUTO = FEC_1_2, FEC_2_3, FEC_3_4 .... FEC_AUTO ... FEC_NONE = QPSK, QAM_128, QAM_16, ATSC ... = BANDWIDTH_6_MHZ, BANDWIDTH_7_MHZ, BANDWIDTH_8_MHZ = = = TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K = video program id = audio program id */ unsigned long freq; char *field, *tmp; tmp = str; /* find the channel name */ if(!(field = strsep(&tmp,":")))return -1; channel->name = strdup(field); /* find the frequency */ if(!(field = strsep(&tmp, ":")))return -1; freq = strtoul(field,NULL,0); switch(fe_type) { case FE_QPSK: if(freq > 11700) { channel->front_param.frequency = (freq - 10600)*1000; channel->tone = 1; } else { channel->front_param.frequency = (freq - 9750)*1000; channel->tone = 0; } channel->front_param.inversion = INVERSION_AUTO; /* find out the polarisation */ if(!(field = strsep(&tmp, ":")))return -1; channel->pol = (field[0] == 'h' ? 0 : 1); /* satellite number */ if(!(field = strsep(&tmp, ":")))return -1; channel->sat_no = strtoul(field, NULL, 0); /* symbol rate */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.qpsk.symbol_rate = strtoul(field, NULL, 0) * 1000; channel->front_param.u.qpsk.fec_inner = FEC_AUTO; break; case FE_QAM: channel->front_param.frequency = freq; /* find out the inversion */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.inversion = find_param(inversion_list, field); /* find out the symbol rate */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.qam.symbol_rate = strtoul(field, NULL, 0); /* find out the fec */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.qam.fec_inner = find_param(fec_list, field); /* find out the qam */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.qam.modulation = find_param(qam_list, field); break; case FE_OFDM: /* DVB-T frequency is in kHz - workaround broken channels.confs */ if (freq < 1000000) freq*=1000; channel->front_param.frequency = freq; /* find out the inversion */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.inversion = find_param(inversion_list, field); /* find out the bandwidth */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.ofdm.bandwidth = find_param(bw_list, field); /* find out the fec_hp */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.ofdm.code_rate_HP = find_param(fec_list, field); /* find out the fec_lp */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.ofdm.code_rate_LP = find_param(fec_list, field); /* find out the qam */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.ofdm.constellation = find_param(qam_list, field); /* find out the transmission mode */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.ofdm.transmission_mode = find_param(transmissionmode_list, field); /* guard list */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.ofdm.guard_interval = find_param(guard_list, field); if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.ofdm.hierarchy_information = find_param(hierarchy_list, field); break; case FE_ATSC: channel->front_param.frequency = freq; /* find out the qam */ if(!(field = strsep(&tmp, ":")))return -1; channel->front_param.u.vsb.modulation = find_param(atsc_list, field); break; } /* Video PID - not used but we'll take it anyway */ if (!(field = strsep(&tmp, ":"))) return -1; channel->pid[VIDFILTER] = strtoul(field, NULL, 0); /* Audio PID - it's only for mpegaudio so we don't use it anymore */ if (!(field = strsep(&tmp, ":"))) return -1; channel->pid[AUDFILTER] = strtoul(field, NULL, 0); /* service ID */ if (!(field = strsep(&tmp, ":"))) return -1; channel->service_id = strtoul(field, NULL, 0); /* some channel.conf files are generated with the service ID 1 to the right this needs investigation */ if ((field = strsep(&tmp, ":"))) if(strtoul(field,NULL,0)>0) channel->service_id = strtoul(field, NULL, 0); return 0; } static int extract_channel_from_string(channel_t *channel, char *str, fe_type_t fe_type) { channel->name = NULL; if (!extract_channel_from_string_internal(channel, str, fe_type)) return 0; _x_freep (&channel->name); /* without this, we have a possible memleak */ return -1; } static channel_t *load_channels(xine_t *xine, xine_stream_t *stream, int *num_ch, fe_type_t fe_type) { FILE *f; char str[BUFSIZE]; char filename[BUFSIZE]; channel_t *channels = NULL; int num_channels = 0; int num_alloc = 0; struct stat st; snprintf_buf(filename, "%s/"PACKAGE"/channels.conf", xdgConfigHome(&xine->basedir_handle)); f = fopen(filename, "r"); if (!f) { xprintf(xine, XINE_VERBOSITY_LOG, _("input_dvb: failed to open dvb channel file '%s': %s\n"), filename, strerror (errno)); if (!f && stream) _x_message(stream, XINE_MSG_FILE_NOT_FOUND, filename, "Please run the dvbscan utility.", NULL); return NULL; } if (fstat(fileno(f), &st) || !S_ISREG (st.st_mode)) { xprintf(xine, XINE_VERBOSITY_LOG, _("input_dvb: dvb channel file '%s' is not a plain file\n"), filename); fclose(f); return NULL; } /* * load channel list */ while ( fgets (str, BUFSIZE, f)) { channel_t channel = {.name = NULL}; /* lose trailing spaces & control characters */ size_t i = strlen (str); while (i && str[i - 1] <= ' ') --i; if (i == 0) continue; str[i] = 0; if (extract_channel_from_string(&channel,str,fe_type) < 0) continue; if (num_channels >= num_alloc) { channel_t *new_channels = calloc((num_alloc += 32), sizeof (channel_t)); _x_assert(new_channels != NULL); memcpy(new_channels, channels, num_channels * sizeof (channel_t)); free(channels); channels = new_channels; } channels[num_channels] = channel; /* Initially there's no EPG data in the EPG structs. */ channels[num_channels].epg_count = 0; memset(channels[num_channels].epg, 0, sizeof(channels[num_channels].epg)); num_channels++; } fclose(f); /* free any trailing unused entries */ channels = realloc (channels, num_channels * sizeof (channel_t)); if(num_channels > 0) xprintf (xine, XINE_VERBOSITY_DEBUG, "input_dvb: found %d channels...\n", num_channels); else { xprintf (xine, XINE_VERBOSITY_DEBUG, "input_dvb: no channels found in the file: giving up.\n"); free(channels); return NULL; } *num_ch = num_channels; return channels; } static void free_channel_list (channel_t *channels, int num_channels) { if (channels) while (--num_channels >= 0) _x_freep(&channels[num_channels].name); free(channels); } static int tuner_set_diseqc(tuner_t *this, channel_t *c) { struct dvb_diseqc_master_cmd cmd = {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}; cmd.msg[3] = 0xf0 | ((c->sat_no * 4) & 0x0f) | (c->tone ? 1 : 0) | (c->pol ? 0 : 2); if (ioctl(this->fd_frontend, FE_SET_TONE, SEC_TONE_OFF) < 0) return 0; if (ioctl(this->fd_frontend, FE_SET_VOLTAGE, c->pol ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18) < 0) return 0; usleep(15000); if (ioctl(this->fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd) < 0) return 0; usleep(15000); if (ioctl(this->fd_frontend, FE_DISEQC_SEND_BURST, (c->sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A) < 0) return 0; usleep(15000); if (ioctl(this->fd_frontend, FE_SET_TONE, c->tone ? SEC_TONE_ON : SEC_TONE_OFF) < 0) return 0; return 1; } /* Tune to the requested freq. etc, wait for frontend to lock for a few seconds. * if frontend can't lock, retire. */ static int tuner_tune_it (tuner_t *this, struct dvb_frontend_parameters *front_param) { fe_status_t status = 0; /* fe_status_t festatus; */ struct dvb_frontend_event event; unsigned int strength; struct pollfd pfd[1]; xine_cfg_entry_t config_tuning_timeout; struct timeval time_now; struct timeval tuning_timeout; /* discard stale events */ while (ioctl(this->fd_frontend, FE_GET_EVENT, &event) != -1); if (ioctl(this->fd_frontend, FE_SET_FRONTEND, front_param) <0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "input_dvb: setfront front: %s\n", strerror(errno)); return 0; } pfd[0].fd = this->fd_frontend; pfd[0].events = POLLIN; if (poll(pfd,1,3000)){ if (pfd[0].revents & POLLIN){ #ifdef EOVERFLOW if (ioctl(this->fd_frontend, FE_GET_EVENT, &event) == -EOVERFLOW) { print_error("EOVERFLOW"); #else if (ioctl(this->fd_frontend, FE_GET_EVENT, &event) == -EINVAL) { print_error("EINVAL"); #endif return 0; } if (event.parameters.frequency <= 0) return 0; } } if (!xine_config_lookup_entry(this->xine, "media.dvb.tuning_timeout", &config_tuning_timeout)) config_tuning_timeout.num_value = 0; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "input_dvb: media.dvb.tuning_timeout is %d\n", config_tuning_timeout.num_value ); if( config_tuning_timeout.num_value != 0 ) { gettimeofday( &tuning_timeout, NULL ); if( config_tuning_timeout.num_value < 5 ) tuning_timeout.tv_sec += 5; else tuning_timeout.tv_sec += config_tuning_timeout.num_value; } xprintf(this->xine, XINE_VERBOSITY_DEBUG, "input_dvb: tuner_tune_it - waiting for lock...\n" ); do { status = 0; if (ioctl(this->fd_frontend, FE_READ_STATUS, &status) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "input_dvb: fe get event: %s\n", strerror(errno)); return 0; } xprintf(this->xine, XINE_VERBOSITY_DEBUG, "input_dvb: status: %x\n", status); if (status & FE_HAS_LOCK) { break; } /* FE_TIMEDOUT does not happen in a no signal condition. * Use the tuning_timeout config to prevent a hang in this loop */ if( config_tuning_timeout.num_value != 0 ) { gettimeofday( &time_now, NULL ); if( time_now.tv_sec > tuning_timeout.tv_sec ) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "input_dvb: No FE_HAS_LOCK before timeout\n"); break; } } usleep(10000); xprintf(this->xine, XINE_VERBOSITY_DEBUG, "Trying to get lock..."); } while (!(status & FE_TIMEDOUT)); /* inform the user of frontend status */ xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Tuner status: "); /* if (ioctl(this->fd_frontend, FE_READ_STATUS, &status) >= 0){ */ if (status & FE_HAS_SIGNAL) xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_SIGNAL"); if (status & FE_TIMEDOUT) xprintf(this->xine,XINE_VERBOSITY_LOG," FE_TIMEDOUT"); if (status & FE_HAS_LOCK) xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_LOCK"); if (status & FE_HAS_CARRIER) xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_CARRIER"); if (status & FE_HAS_VITERBI) xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_VITERBI"); if (status & FE_HAS_SYNC) xprintf(this->xine,XINE_VERBOSITY_LOG," FE_HAS_SYNC"); /* } */ xprintf(this->xine,XINE_VERBOSITY_LOG,"\n"); strength=0; if(ioctl(this->fd_frontend,FE_READ_BER,&strength) >= 0) xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Bit error rate: %i\n",strength); strength=0; if(ioctl(this->fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength) >= 0) xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Signal strength: %u\n",strength); strength=0; if(ioctl(this->fd_frontend,FE_READ_SNR,&strength) >= 0) xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Signal/Noise Ratio: %u\n",strength); if (status & FE_HAS_LOCK && !(status & FE_TIMEDOUT)) { xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Lock achieved at %lu Hz\n",(unsigned long)front_param->frequency); return 1; } else { xprintf(this->xine,XINE_VERBOSITY_LOG,"input_dvb: Unable to achieve lock at %lu Hz\n",(unsigned long)front_param->frequency); return 0; } } /* Parse the PMT, and add filters for all stream types associated with * the 'channel'. We leave it to the demuxer to sort out which PIDs to * use. to simplify things slightly, (and because the demuxer can't handle it) * allow only one of each media type */ static void parse_pmt(dvb_input_plugin_t *this, const unsigned char *buf, int section_length) { int program_info_len; int pcr_pid; int has_video=0; int has_audio=0; int has_ac3=0; int has_subs=0; int has_text=0; dvb_set_pidfilter(this, PMTFILTER, this->channels[this->channel].pmtpid, DMX_PES_OTHER,DMX_OUT_TS_TAP); dvb_set_pidfilter(this, PATFILTER, 0, DMX_PES_OTHER,DMX_OUT_TS_TAP); pcr_pid = ((buf[0] & 0x1f) << 8) | buf[1]; if(pcr_pid!=0x1FFF) /* don't waste time if the PCR is invalid */ dvb_set_pidfilter(this, PCRFILTER, pcr_pid, DMX_PES_PCR,DMX_OUT_TS_TAP); program_info_len = ((buf[2] & 0x0f) << 8) | buf[3]; buf += program_info_len + 4; section_length -= program_info_len + 4; while (section_length >= 5) { int elementary_pid = ((buf[1] & 0x1f) << 8) | buf[2]; int descriptor_len = ((buf[3] & 0x0f) << 8) | buf[4]; switch (buf[0]) { case 0x01: case 0x02: case 0x10: case 0x1b: if(!has_video) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding VIDEO : PID 0x%04x\n", elementary_pid); dvb_set_pidfilter(this, VIDFILTER, elementary_pid, DMX_PES_VIDEO, DMX_OUT_TS_TAP); has_video=1; } break; case 0x03: case 0x04: case 0x0f: case 0x11: if(!has_audio) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AUDIO : PID 0x%04x\n", elementary_pid); dvb_set_pidfilter(this, AUDFILTER, elementary_pid, DMX_PES_AUDIO, DMX_OUT_TS_TAP); has_audio=1; } break; case 0x06: if (find_descriptor(0x56, buf + 5, descriptor_len, NULL, NULL)) { if(!has_text) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding TELETEXT : PID 0x%04x\n", elementary_pid); dvb_set_pidfilter(this,TXTFILTER, elementary_pid, DMX_PES_OTHER,DMX_OUT_TS_TAP); has_text=1; } break; } else if (find_descriptor (0x59, buf + 5, descriptor_len, NULL, NULL)) { /* Note: The subtitling descriptor can also signal * teletext subtitling, but then the teletext descriptor * will also be present; so we can be quite confident * that we catch DVB subtitling streams only here, w/o * parsing the descriptor. */ if(has_subs <= MAX_SUBTITLES) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding SUBTITLES: PID 0x%04x\n", elementary_pid); if(this->channels[this->channel].subpid [has_subs] !=DVB_NOPID) { ioctl(this->tuner->fd_subfilter[has_subs], DMX_STOP); } this->channels[this->channel].subpid [has_subs] = elementary_pid; this->tuner->subFilterParams[has_subs].pid = elementary_pid; this->tuner->subFilterParams[has_subs].input = DMX_IN_FRONTEND; this->tuner->subFilterParams[has_subs].output = DMX_OUT_TS_TAP; this->tuner->subFilterParams[has_subs].pes_type = DMX_PES_OTHER; this->tuner->subFilterParams[has_subs].flags = DMX_IMMEDIATE_START; if (ioctl(this->tuner->fd_subfilter[has_subs], DMX_SET_PES_FILTER, &this->tuner->subFilterParams[has_subs]) < 0) { xprintf(this->tuner->xine, XINE_VERBOSITY_DEBUG, "input_dvb: set_pid: %s\n", strerror(errno)); break; } has_subs++; } break; } else if (find_descriptor (0x6a, buf + 5, descriptor_len, NULL, NULL)) { if(!has_ac3) { dvb_set_pidfilter(this, AC3FILTER, elementary_pid, DMX_PES_OTHER,DMX_OUT_TS_TAP); xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AC3 : PID 0x%04x\n", elementary_pid); has_ac3=1; } break; } break; case 0x81: /* AC3 audio */ if(!has_audio) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Adding AUDIO : PID 0x%04x\n", elementary_pid); dvb_set_pidfilter(this, AUDFILTER, elementary_pid, DMX_PES_AUDIO, DMX_OUT_TS_TAP); has_audio=1; } break; }; buf += descriptor_len + 5; section_length -= descriptor_len + 5; }; } static void dvb_parse_si(dvb_input_plugin_t *this) { uint8_t *tmpbuffer; uint8_t *bufptr; int service_id; int result; int section_len; int x; struct pollfd pfd; tuner_t *tuner = this->tuner; tmpbuffer = calloc(1, 8192); _x_assert(tmpbuffer != NULL); bufptr = tmpbuffer; pfd.fd=tuner->fd_pidfilter[INTERNAL_FILTER]; pfd.events = POLLPRI; xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Setting up Internal PAT filter\n"); xine_usec_sleep(500000); /* first - the PAT. retrieve the entire section...*/ dvb_set_sectfilter(this, INTERNAL_FILTER, 0, DMX_PES_OTHER, 0, 0xff); /* wait for up to 15 seconds */ if(poll(&pfd,1,12000)<1) /* PAT timed out - weird, but we'll default to using channels.conf info */ { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: Error setting up Internal PAT filter - reverting to rc6 hehaviour\n"); dvb_set_pidfilter (this,VIDFILTER,this->channels[this->channel].pid[VIDFILTER], DMX_PES_OTHER, DMX_OUT_TS_TAP); dvb_set_pidfilter (this,AUDFILTER,this->channels[this->channel].pid[AUDFILTER], DMX_PES_OTHER, DMX_OUT_TS_TAP); goto done; } result = read (tuner->fd_pidfilter[INTERNAL_FILTER], tmpbuffer, 3); if(result!=3) xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: error reading PAT table - no data!\n"); section_len = getbits(tmpbuffer,12,12); result = read (tuner->fd_pidfilter[INTERNAL_FILTER], tmpbuffer+5,section_len); if(result!=section_len) xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: error reading in the PAT table\n"); ioctl(tuner->fd_pidfilter[INTERNAL_FILTER], DMX_STOP); bufptr+=10; this->num_streams_in_this_ts=0; section_len-=5; while(section_len>4){ service_id = getbits (bufptr,0,16); for (x=0;xnum_channels;x++){ if(this->channels[x].service_id==service_id) { this->channels[x].pmtpid = getbits (bufptr, 19, 13); } } section_len-=4; bufptr+=4; if(service_id>0) /* ignore NIT table for now */ this->num_streams_in_this_ts++; } bufptr = tmpbuffer; /* next - the PMT */ xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Setting up Internal PMT filter for pid %x\n",this->channels[this->channel].pmtpid); dvb_set_sectfilter(this, INTERNAL_FILTER, this->channels[this->channel].pmtpid, DMX_PES_OTHER, 2, 0xff); if((poll(&pfd,1,15000)<1) || this->channels[this->channel].pmtpid==0) /* PMT timed out or couldn't be found - default to using channels.conf info */ { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"input_dvb: PMT scan timed out. Using video & audio PID info from channels.conf.\n"); dvb_set_pidfilter (this,VIDFILTER,this->channels[this->channel].pid[VIDFILTER], DMX_PES_OTHER, DMX_OUT_TS_TAP); dvb_set_pidfilter (this,AUDFILTER,this->channels[this->channel].pid[AUDFILTER], DMX_PES_OTHER, DMX_OUT_TS_TAP); goto done; } result = read(tuner->fd_pidfilter[INTERNAL_FILTER],tmpbuffer,3); section_len = getbits (bufptr, 12, 12); result = read(tuner->fd_pidfilter[INTERNAL_FILTER],tmpbuffer+3,section_len); ioctl(tuner->fd_pidfilter[INTERNAL_FILTER], DMX_STOP); parse_pmt(this,tmpbuffer+8,section_len); /* dvb_set_pidfilter(this, TSDTFILTER, 0x02,DMX_PES_OTHER,DMX_OUT_TS_TAP); dvb_set_pidfilter(this, RSTFILTER, 0x13,DMX_PES_OTHER,DMX_OUT_TS_TAP); dvb_set_pidfilter(this, TDTFILTER, 0x14,DMX_PES_OTHER,DMX_OUT_TS_TAP); dvb_set_pidfilter(this, DITFILTER, 0x1e,DMX_PES_OTHER,DMX_OUT_TS_TAP); dvb_set_pidfilter(this, CATFILTER, 0x01,DMX_PES_OTHER,DMX_OUT_TS_TAP); dvb_set_pidfilter(this, NITFILTER, 0x10,DMX_PES_OTHER,DMX_OUT_TS_TAP); dvb_set_pidfilter(this, SDTFILTER, 0x11, DMX_PES_OTHER, DMX_OUT_TS_TAP); */ /* we use the section filter for EIT because we are guarenteed a complete section */ if(ioctl(tuner->fd_pidfilter[EITFILTER],DMX_SET_BUFFER_SIZE,8192*this->num_streams_in_this_ts)<0) xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: couldn't increase buffer size for EIT: %s \n",strerror(errno)); dvb_set_sectfilter(this, EITFILTER, 0x12,DMX_PES_OTHER,0x4e, 0xff); xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"input_dvb: Setup of PID filters complete\n"); done: free(tmpbuffer); } /* Helper function for finding the channel index in the channels struct given the service_id. If channel is not found, -1 is returned. */ static int channel_index(dvb_input_plugin_t* this, int service_id) { int n; for (n=0; n < this->num_channels; n++) if (this->channels[n].service_id == service_id) return n; return -1; } static int compare_epg_by_starttime(const void* a, const void* b) { const epg_entry_t * const *epg_a; const epg_entry_t * const *epg_b; epg_a = (const epg_entry_t* const *)a; epg_b = (const epg_entry_t* const *)b; if ((*epg_a)->starttime < (*epg_b)->starttime) { return -1; } else if ((*epg_a)->starttime > (*epg_b)->starttime) { return 1; } return 0; } /* Finds the index of EPG entry with given starting time. If not found, returns -1. */ static int epg_with_starttime(channel_t* channel, time_t starttime) { int i; for (i = 0; i < channel->epg_count; i++) { if (channel->epg[i]->starttime == starttime) return i; } return -1; } #ifdef EPG_UPDATE_IN_BACKGROUND /* Sleep routine for pthread (hackish). */ static void pthread_sleep(int seconds) { pthread_mutex_t dummy_mutex; static pthread_cond_t dummy_cond = PTHREAD_COND_INITIALIZER; struct timespec timeout; /* Create a dummy mutex which doesn't unlock for sure while waiting. */ pthread_mutex_init(&dummy_mutex, NULL); pthread_mutex_lock(&dummy_mutex); /* Create a dummy condition variable. */ /* pthread_cond_init(&dummy_cond, NULL); */ timeout.tv_sec = time(NULL) + seconds; timeout.tv_nsec = 0; pthread_cond_timedwait(&dummy_cond, &dummy_mutex, &timeout); /* pthread_cond_destroy(&dummy_cond); */ pthread_mutex_unlock(&dummy_mutex); pthread_mutex_destroy(&dummy_mutex); } /* Thread routine that updates the EPG data periodically. */ static void* epg_data_updater(void *t) { dvb_input_plugin_t* this = (dvb_input_plugin_t*)t; while (!this->epg_updater_stop) { #ifdef DEBUG_EPG print_info("EPG epg_data_updater() updating..."); #endif load_epg_data(this); /* Update the EPG OSD if it's visible. */ if (this->epg_displaying) { this->epg_displaying = 0; show_eit(this); } pthread_sleep(EPG_UPDATE_DELAY); } #ifdef DEBUG_EPG print_info("EPG epg_data_updater() returning..."); #endif return NULL; } #endif /* This function parses the EIT table and saves the data used in EPG OSD of all channels found in the currently tuned stream. */ static void load_epg_data(dvb_input_plugin_t *this) { /*int table_id;*/ char skip_byte; int descriptor_id; int section_len = 0; unsigned int service_id=-1; int n; uint8_t *eit = NULL; uint8_t *foo = NULL; char *seen_channels = NULL; int text_len; struct pollfd fd; int loops; int current_channel_index; epg_entry_t* current_epg = NULL; channel_t* current_channel = NULL; int i; pthread_mutex_lock(&this->channel_change_mutex); /* seen_channels array is used to store information of channels that were already "found" in the stream. This information is used to initialize the channel's EPG structs when the EPG information for the channel is seen in the stream the first time. */ seen_channels = calloc(this->num_channels, sizeof(char)); _x_assert(seen_channels != NULL); foo = calloc(1, 8192); _x_assert(foo != NULL); fd.fd = this->tuner->fd_pidfilter[EITFILTER]; fd.events = POLLPRI; for (loops = 0; loops <= this->num_streams_in_this_ts*2; loops++) { eit = foo; if (poll(&fd,1,2000)<1) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"(Timeout in EPG loop!! Quitting\n"); pthread_mutex_unlock(&this->channel_change_mutex); free(seen_channels); free(foo); return; } n = read(this->tuner->fd_pidfilter[EITFILTER], eit, 3); if (n != 3) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"Error reading EPG section length\n"); break; } /*table_id = getbits(eit, 0, 8); */ section_len = (unsigned int)getbits(eit, 12, 12); n = read(this->tuner->fd_pidfilter[EITFILTER], eit + 3, section_len); if (n != section_len) { xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"Error reading EPG section data\n"); break; } service_id = (unsigned int)getbits(eit, 24, 16); if ((current_channel_index = channel_index(this, service_id)) == -1) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG,"input_dvb: load_epg_data(): unknown service_id: %d!\n", service_id); continue; } if (section_len > 15) { current_channel = &this->channels[current_channel_index]; /* Reset the EPG struct if this channel is seen the first time in the stream. */ if (!seen_channels[current_channel_index]) { current_channel->epg_count = 0; seen_channels[current_channel_index] = 1; } if (current_channel->epg_count >= MAX_EPG_ENTRIES_PER_CHANNEL) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvb: load_epg_data(): MAX_EPG_ENTRIES_PER_CHANNEL reached!\n"); continue; } /* Initialize the EPG struct if there's not one we can reuse. Allocate space for the strings. */ if (current_channel->epg[current_channel->epg_count] == NULL) { current_channel->epg[current_channel->epg_count] = calloc(1, sizeof(epg_entry_t)); _x_assert(current_channel->epg[current_channel->epg_count] != NULL); current_channel->epg[current_channel->epg_count]->progname = malloc(MAX_EPG_PROGRAM_NAME_LENGTH + 1); _x_assert(current_channel->epg[current_channel->epg_count]->progname != NULL); current_channel->epg[current_channel->epg_count]->description = malloc(MAX_EPG_PROGRAM_DESCRIPTION_LENGTH + 1); _x_assert(current_channel->epg[current_channel->epg_count]->description != NULL); current_channel->epg[current_channel->epg_count]->content = malloc(MAX_EPG_CONTENT_TYPE_LENGTH + 1); _x_assert(current_channel->epg[current_channel->epg_count]->content != NULL); current_channel->epg[current_channel->epg_count]->running = 0; } current_epg = current_channel->epg[current_channel->epg_count]; current_epg->starttime = dvb_mjdtime(eit+16); /* running_status: 0 undefined 1 not running 2 starts in a few seconds 3 pausing 4 running */ if (getbits(foo,192,3) == 4){ current_epg->running = 1; } else { current_epg->running = 0; } if (epg_with_starttime(current_channel, current_epg->starttime) != -1) { /* Found already an entry with this starttime, let's not add it! */ continue; } current_epg->duration_hours = (char)bcdtoint(eit[21] & 0xff); current_epg->duration_minutes = (char)bcdtoint(eit[22] & 0xff); descriptor_id = eit[26]; eit += 27; section_len -= 27; /* run the descriptor loop for the length of section_len */ while (section_len > 1) { switch(descriptor_id) { case 0x4D: { /* simple program info descriptor */ int name_len; /*int desc_len;*/ xine_cfg_entry_t language; /*desc_len = getbits(eit, 0, 8); */ /* Let's get the EPG data only in the wanted language. */ if (xine_config_lookup_entry( this->stream->xine, "media.dvd.language", &language) && language.str_value && strlen(language.str_value) >= 2 && strncasecmp(language.str_value, &eit[1], 2)) { #ifdef DEBUG_EPG printf("input_dvb: EPG Skipping language: %C%C%C\n", eit[1],eit[2],eit[3]); printf("input_dvb: EPG language.str_value: %s\n", language.str_value); #endif break; } /* program name */ name_len = (unsigned char)eit[4]; if (name_len == 0) { current_epg->progname[0] = '\0'; break; } /* the first char of the string contains sometimes the character encoding information, which should not be copied to the string. (FIXME - we ought to be using this byte to change charsets)*/ if (!isalnum(*(eit + 5))) skip_byte = 1; else skip_byte = 0; memcpy(current_epg->progname, eit + 5 + skip_byte, name_len - skip_byte); current_epg->progname[name_len - skip_byte] = '\0'; /* detailed program information (max 256 chars)*/ text_len = (unsigned char)eit[5 + name_len]; if (text_len == 0) { current_epg->description[0] = '\0'; break; } if (!isalnum(*(eit + 6 + name_len))) skip_byte = 1; else skip_byte = 0; memcpy(current_epg->description, eit + 6 + name_len + skip_byte, text_len - skip_byte); current_epg->description[text_len - skip_byte] = '\0'; } break; case 0x54: { /* Content Descriptor, riveting stuff */ int content_bits = getbits(eit, 8, 4); static const char *const content[] = { "UNKNOWN","MOVIE","NEWS","ENTERTAINMENT","SPORT", "CHILDRENS","MUSIC","ARTS/CULTURE","CURRENT AFFAIRS", "EDUCATIONAL","INFOTAINMENT","SPECIAL","COMEDY","DRAMA", "DOCUMENTARY","UNK"}; snprintf(current_epg->content, MAX_EPG_CONTENT_TYPE_LENGTH, "%s", content[content_bits]); } break; case 0x55: { /* Parental Rating descriptor describes minimum recommened age -3 */ /* A rating value of 0 means that there is no rating defined. Ratings greater than 0xF are "defined by broadcaster", which is not supported for now. */ if (eit[4] > 0 && eit[4] <= 0xF) current_epg->rating = eit[4] + 3; else current_epg->rating = 0; } break; default: break; } section_len -= getbits(eit, 0, 8) + 2; eit += getbits(eit, 0, 8); descriptor_id = eit[1]; eit += 2; } /* Store the entry if we got enough data. */ if (current_epg->progname && strlen(current_epg->progname)) current_channel->epg_count++; } } /* Sort the EPG arrays by starttime. */ for (i = 0; i < this->num_channels; ++i) { if (!seen_channels[i]) continue; qsort(this->channels[i].epg, this->channels[i].epg_count, sizeof(epg_entry_t*), compare_epg_by_starttime); } free(seen_channels); free(foo); pthread_mutex_unlock(&this->channel_change_mutex); } /* Prints text to an area, tries to cut the lines in between words. */ static void render_text_area(osd_renderer_t* renderer, osd_object_t* osd, const char* text, int x, int y, int row_space, int max_x, int max_y, int* height, int color_base) { /* The position of the text to be printed. */ const char* cursor = text; const char *const text_end = text + strlen(text); /* The line to be printed next. */ char text_line[512]; int text_width, text_height; size_t old_line_length, line_cursor; const char* bound, *old_bound; *height = 0; while (cursor < text_end) { bound = cursor; line_cursor = 0; text_line[0] = '\0'; /* Find out how much fits in a row. */ do { /* Find out the next word boundary. */ old_bound = bound; old_line_length = strlen(text_line); line_cursor = old_line_length; /* Strip leading white space. */ while (isspace(*bound)) bound++; /* Copy text to the text_line until end of word or end of string. */ while (!isspace(*bound) && *bound != '\0') { text_line[line_cursor] = *bound; bound++; line_cursor++; } text_line[line_cursor++] = ' '; text_line[line_cursor] = '\0'; /* Try if the line with a new word still fits to the given area. */ renderer->get_text_size(osd, text_line, &text_width, &text_height); if (x + text_width > max_x) { /* It didn't fit, restore the old line and stop trying to fit more.*/ text_line[old_line_length] = '\0'; /* If no words did fit to the line, fit as many characters as possible in it. */ if (old_line_length == 0) { text_width = 0; bound = bound - line_cursor + 1; /* rewind to the beginning of the word */ line_cursor = 0; while (!isspace(*bound) && *bound != '\0') { text_line[line_cursor++] = *bound++; text_line[line_cursor] = '\0'; renderer->get_text_size(osd, text_line, &text_width, &text_height); /* The last character did not fit. */ if (x + text_width >= max_x) { text_line[line_cursor - 1] = '\0'; bound--; break; } } /* The line is now filled with chars from the word. */ break; } bound = old_bound; break; } /* OK, it did fit, let's try to fit some more. */ } while (bound < text_end); if (y + text_height + row_space > max_y) { break; } renderer->render_text(osd, x, y, text_line, color_base); *height += text_height + row_space; y += text_height + row_space; cursor = bound; } } /* Finds the EPG of the ith next program. 0 means the current program, 1 next. If not found, returns NULL. All these functions expect the EPG entries are sorted by starting time. */ static epg_entry_t* ith_next_epg(channel_t* channel, int count) { time_t current_time = time(NULL); int counter = 0; /* Discard the entries of past programs. */ while (counter + 1 < channel->epg_count && difftime(channel->epg[counter + 1]->starttime, current_time) < 0.0) counter++; /* Check whether the previous program has still the running bit on, and if it's not more late than the given margin, assume it's still running. */ if (counter >= 1 && channel->epg[counter - 1]->running && difftime(current_time, channel->epg[counter]->starttime) < MAX_EPG_ENTRY_LATENESS) { counter--; } counter += count; if (counter >= channel->epg_count) return NULL; /* Check if the EPG to be returned is the last program in the EPG list and its duration info says that it should have ended more than n minutes ago. In that case do not return any EPG. This fixes the "very last program of the day sticking until morning" bug. */ if (counter == channel->epg_count - 1) { if (difftime(current_time, channel->epg[counter]->starttime + channel->epg[counter]->duration_hours*60*60 + channel->epg[counter]->duration_minutes*60) > MAX_EPG_ENTRY_LATENESS) { return NULL; } } return channel->epg[counter]; } /* Finds the EPG of the current program. If not found, returns NULL. */ static epg_entry_t* current_epg(channel_t* channel) { epg_entry_t* next = ith_next_epg(channel, 0); #ifdef DEBUG_EPG if (next != NULL) printf("input_dvb: EPG current: %s (%d)\n", next->progname, next->running); #endif return next; } /* Finds the EPG of the next program. If not found, returns NULL. */ static epg_entry_t* next_epg(channel_t* channel) { epg_entry_t* next = ith_next_epg(channel, 1); #ifdef DEBUG_EPG if (next != NULL) printf("input_dvb: EPG next: %s (%d)\n", next->progname, next->running); #endif return next; } /* Displays the program info of an EPG entry in OSD. x,y The upper left coordinates of the program information area. max_x, max_y The maximum right coordinate of the program information area. last_y The position of y after printing the entry. data The EPG entry to display. Returns the height of the entry in the OSD in pixels. */ static void show_program_info(int x, int y, int max_x, int max_y, int* last_y, epg_entry_t* epg_data, osd_renderer_t* renderer, osd_object_t* osd) { char* buffer; int time_width, text_width, dummy; int content_width = 0; int text_height = 0; int time_height = 0; struct tm* starttime = NULL; *last_y = y; if (epg_data == NULL || epg_data->progname == NULL) return; buffer = calloc(1, 512); _x_assert(buffer != NULL); if (!renderer->set_font(osd, "sans", EPG_TITLE_FONT_SIZE)) { print_error("Setting title font failed."); } starttime = localtime(&epg_data->starttime); strftime(buffer, 7, "%H:%M ", starttime); /* Print the starting time. */ renderer->render_text(osd, x, y, buffer, OSD_TEXT3); renderer->get_text_size(osd, buffer, &time_width, &time_height); /*Content type and rating, if any. */ if (strlen(epg_data->content) > 3) { strncpy(buffer, epg_data->content, 94-1); if (epg_data->rating > 0) { snprintf(buffer + strlen(buffer), 11, " (%i+)", epg_data->rating); } if (!renderer->set_font(osd, "sans", EPG_CONTENT_FONT_SIZE)) { print_error("Setting content type font failed."); } renderer->get_text_size(osd, buffer, &content_width, &dummy); renderer->render_text(osd, max_x - 2 - content_width, y, buffer, OSD_TEXT3); } text_width = max_x - x - time_width - content_width - 2; renderer->set_font(osd, "sans", EPG_TITLE_FONT_SIZE); render_text_area(renderer, osd, epg_data->progname, x + time_width, y, EPG_PIXELS_BETWEEN_TEXT_ROWS, x + text_width + time_width, max_y, &text_height, OSD_TEXT4); if (text_height == 0) *last_y = y + time_height; else *last_y = y + text_height; /* Print the description. */ if (epg_data->description && strlen(epg_data->description) > 0) { renderer->set_font(osd, "sans", EPG_DESCRIPTION_FONT_SIZE); strcpy(buffer, epg_data->description); /* If the description is not complete (i.e., there is no comma at the end), add "..." to the end. In my locale they often seem to send incomplete description texts :( */ if (buffer[strlen(buffer)-1] != '.' && buffer[strlen(buffer)-1] != '?' && buffer[strlen(buffer)-1] != '!') { strcat(buffer, "..."); } /* If duration_hours is zero, do not print them. */ if (epg_data->duration_hours > 0) sprintf(buffer + strlen(buffer), " (%dh%02dmin)", epg_data->duration_hours, epg_data->duration_minutes); else if (epg_data->duration_minutes > 0) sprintf(buffer + strlen(buffer), " (%dmin)", epg_data->duration_minutes); render_text_area(renderer, osd, buffer, x + time_width, *last_y + EPG_PIXELS_BETWEEN_TEXT_ROWS, EPG_PIXELS_BETWEEN_TEXT_ROWS, max_x, max_y, &text_height, OSD_TEXT3); *last_y += EPG_PIXELS_BETWEEN_TEXT_ROWS + text_height; } free(buffer); } /* Shows the EPG listing for the current channel. */ static void show_eit(dvb_input_plugin_t *this) { int y; int centered_x, centered_y; int y_pos = 0; int window_width, window_height, stream_width, stream_height; int temp1, temp2; time_t ct; char clock[6]; if (!this->epg_displaying) { #ifndef EPG_UPDATE_IN_BACKGROUND if (current_epg(&this->channels[this->channel]) == NULL || next_epg(&this->channels[this->channel]) == NULL) { load_epg_data(this); } #endif this->epg_displaying = 1; this->stream->osd_renderer->hide(this->proginfo_osd, 0); this->stream->osd_renderer->clear(this->proginfo_osd); /* Channel Name */ if (!this->stream->osd_renderer->set_font( this->proginfo_osd, "sans", EPG_CHANNEL_FONT_SIZE)) { print_error("Error setting channel name font."); } this->stream->osd_renderer->render_text( this->proginfo_osd, 0, 0, this->channels[this->channel].name, OSD_TEXT4); time(&ct); strftime(clock, sizeof(clock), "%H:%M", localtime(&ct)); clock[5] = '\0'; /* Clock - align it to right. */ if (!this->stream->osd_renderer->set_font( this->proginfo_osd, "sans", EPG_CLOCK_FONT_SIZE)) { print_error("Error setting clock font."); } this->stream->osd_renderer->get_text_size( this->proginfo_osd, this->channels[this->channel].name, &temp1, &temp2); this->stream->osd_renderer->render_text( this->proginfo_osd, EPG_WIDTH - 45, EPG_CHANNEL_FONT_SIZE - EPG_CLOCK_FONT_SIZE, clock, OSD_TEXT4); show_program_info(0, EPG_CHANNEL_FONT_SIZE + 2, EPG_WIDTH, EPG_HEIGHT, &y_pos, current_epg(&this->channels[this->channel]), this->stream->osd_renderer, this->proginfo_osd); y = y_pos; show_program_info(0, y, EPG_WIDTH, EPG_HEIGHT, &y_pos, next_epg(&this->channels[this->channel]), this->stream->osd_renderer, this->proginfo_osd); y = y_pos; window_width = xine_get_param(this->stream, XINE_PARAM_VO_WINDOW_WIDTH); window_height = xine_get_param(this->stream, XINE_PARAM_VO_WINDOW_HEIGHT); stream_width = xine_get_stream_info(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH); stream_height = xine_get_stream_info(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT); /* Resize the background to be the size of the OSD texts + margins. */ this->stream->osd_renderer->clear(this->background); this->stream->osd_renderer->set_font(this->background, "cetus", 32); this->stream->osd_renderer->set_encoding(this->background, NULL); this->stream->osd_renderer->set_text_palette( this->background, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT3); this->stream->osd_renderer->filled_rect( this->background, 0, 0, EPG_WIDTH + EPG_BACKGROUND_MARGIN*2, y + EPG_BACKGROUND_MARGIN*2, 4); /* In case video is downscaled and the EPG fits, show it unscaled to make it appear bigger thus more readable. NOT FULLY TESTED. */ if (stream_width > window_width && window_width > EPG_WIDTH) { centered_x = (window_width - EPG_WIDTH) / 2; centered_x = (centered_x > 0)?(centered_x):(0); centered_y = (window_height - y) / 3; centered_y = (centered_y > 0)?(centered_y):(EPG_TOP); this->stream->osd_renderer->set_position( this->proginfo_osd, centered_x + EPG_BACKGROUND_MARGIN, centered_y + EPG_BACKGROUND_MARGIN); this->stream->osd_renderer->set_position(this->background, centered_x, centered_y); this->stream->osd_renderer->show_unscaled(this->background, 0); this->stream->osd_renderer->show_unscaled(this->proginfo_osd, 0); } else { /* Otherwise make it scaled. */ centered_x = (stream_width - EPG_WIDTH) / 2; centered_x = (centered_x > 0)?(centered_x):(0); centered_y = (stream_height - y) / 3; centered_y = (centered_y > 0)?(centered_y):(EPG_TOP); /* Center the OSD to stream. */ this->stream->osd_renderer->set_position( this->proginfo_osd, centered_x + EPG_BACKGROUND_MARGIN, centered_y + EPG_BACKGROUND_MARGIN); this->stream->osd_renderer->set_position(this->background, centered_x, centered_y); this->stream->osd_renderer->show(this->background, 0); this->stream->osd_renderer->show(this->proginfo_osd, 0); } } else { this->epg_displaying = 0; this->stream->osd_renderer->hide (this->proginfo_osd,0); this->stream->osd_renderer->hide (this->background,0); } return; } static int tuner_set_channel (dvb_input_plugin_t *this, channel_t *c) { tuner_t *tuner=this->tuner; xine_cfg_entry_t lastchannel; config_values_t *config = this->stream->xine->config; if (tuner->feinfo.type==FE_QPSK) { if(!(tuner->feinfo.caps & FE_CAN_INVERSION_AUTO)) c->front_param.inversion = INVERSION_OFF; if (!tuner_set_diseqc(tuner, c)) return 0; } if (!tuner_tune_it (tuner, &c->front_param)){ return 0; } if (xine_config_lookup_entry(this->stream->xine, "media.dvb.remember_channel", &lastchannel)) if (lastchannel.num_value){ /* Remember last watched channel. never show this entry*/ config->update_num(config, "media.dvb.last_channel", this->channel+1); } #ifdef DVB_NO_BUFFERING this->newchannel=1; #endif return 1; /* fixme: error handling */ } static void osd_show_channel (dvb_input_plugin_t *this, int channel) { int i, channel_to_print, temp; epg_entry_t* current_program = NULL; this->stream->osd_renderer->clear(this->channel_osd); this->stream->osd_renderer->filled_rect (this->channel_osd, 0, 0, CHSEL_WIDTH, CHSEL_HEIGHT, 2); channel_to_print = channel - 5; for (i=0; i<11; i++) { if ((channel_to_print >= 0) && (channel_to_print < this->num_channels)) { this->stream->osd_renderer->set_font(this->channel_osd, "cetus", CHSEL_CHANNEL_FONT_SIZE); this->stream->osd_renderer->set_text_palette( this->channel_osd, XINE_TEXTPALETTE_WHITE_NONE_TRANSLUCID, OSD_TEXT3); this->stream->osd_renderer->set_text_palette( this->channel_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT4); this->stream->osd_renderer->render_text( this->channel_osd, 110, 10+i*35, this->channels[channel_to_print].name, (channel_to_print == channel)?(OSD_TEXT4):(OSD_TEXT3)); if ((current_program = current_epg(&this->channels[channel_to_print])) && current_program->progname && strlen(current_program->progname) > 0) { this->stream->osd_renderer->set_font(this->channel_osd, "sans", 16); render_text_area(this->stream->osd_renderer, this->channel_osd, current_program->progname, 400, 10+i*35, -5, CHSEL_WIDTH, 10+i*35+CHSEL_CHANNEL_FONT_SIZE+2, &temp, (channel_to_print == channel)?(OSD_TEXT4):(OSD_TEXT3)); } } channel_to_print++; } this->stream->osd_renderer->line (this->channel_osd, 105, 183, 390, 183, 10); this->stream->osd_renderer->line (this->channel_osd, 105, 183, 105, 219, 10); this->stream->osd_renderer->line (this->channel_osd, 105, 219, 390, 219, 10); this->stream->osd_renderer->line (this->channel_osd, 390, 183, 390, 219, 10); this->stream->osd_renderer->show (this->channel_osd, 0); /* hide eit if showing */ if (this->epg_displaying==1) { this->stream->osd_renderer->hide (this->proginfo_osd,0); this->stream->osd_renderer->hide (this->background,0); } } static int switch_channel(dvb_input_plugin_t *this, int channel) { int x; xine_event_t event; xine_pids_data_t data; xine_ui_data_t ui_data; /* control_nop appears to stop an occasional (quite long) pause between channel-changes, which the user may see as a lockup. */ _x_demux_control_nop(this->stream, BUF_FLAG_END_STREAM); _x_demux_flush_engine(this->stream); pthread_mutex_lock (&this->channel_change_mutex); close (this->fd); this->tuned_in = 0; for (x = 0; x < MAX_FILTERS; x++) { close(this->tuner->fd_pidfilter[x]); this->tuner->fd_pidfilter[x] = xine_open_cloexec(this->tuner->demux_device, O_RDWR); } if (!tuner_set_channel (this, &this->channels[channel])) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: tuner_set_channel failed\n")); pthread_mutex_unlock (&this->channel_change_mutex); return 0; } event.type = XINE_EVENT_PIDS_CHANGE; data.vpid = this->channels[channel].pid[VIDFILTER]; data.apid = this->channels[channel].pid[AUDFILTER]; event.data = &data; event.data_length = sizeof (xine_pids_data_t); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvb: sending event\n"); xine_event_send (this->stream, &event); strlcpy (ui_data.str, this->channels[channel].name, sizeof(ui_data.str)); ui_data.str_len = strlen (ui_data.str); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, ui_data.str); event.type = XINE_EVENT_UI_SET_TITLE; event.stream = this->stream; event.data = &ui_data; event.data_length = sizeof(ui_data); xine_event_send(this->stream, &event); xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"ui title event sent\n"); this->channel = channel; this->fd = xine_open_cloexec(this->tuner->dvr_device, O_RDONLY | O_NONBLOCK); this->tuned_in = 1; pthread_mutex_unlock (&this->channel_change_mutex); /* now read the pat, find all accociated PIDs and add them to the stream */ dvb_parse_si(this); this->stream->osd_renderer->hide(this->channel_osd, 0); /* if there is no EPG data, start loading it immediately. */ if (current_epg(&this->channels[channel]) == NULL) load_epg_data(this); /* show eit for this channel if necessary */ if (this->epg_displaying==1){ this->epg_displaying=0; show_eit(this); } return 1; } static void do_record (dvb_input_plugin_t *this) { struct tm *tma; time_t *t; char filename [256]; char dates[64]; int x=0; xine_cfg_entry_t savedir; DIR *dir; if (this->record_fd > -1) { /* stop recording */ close (this->record_fd); this->record_fd = -1; this->stream->osd_renderer->hide (this->rec_osd, 0); this->stream->osd_renderer->hide (this->paused_osd, 0); this->record_paused=0; } else { t=calloc(1, sizeof(time_t)); _x_assert(t != NULL); time(t); tma=localtime(t); _x_freep(&t); strftime(dates,63,"%Y-%m-%d_%H%M",tma); if (xine_config_lookup_entry(this->stream->xine, "media.capture.save_dir", &savedir) && strlen(savedir.str_value) > 1) { if((dir = opendir(savedir.str_value))==NULL){ snprintf_buf (filename, "%s/%s_%s.ts",xine_get_homedir(),this->channels[this->channel].name, dates); xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"savedir is wrong... saving to home directory\n"); } else { closedir(dir); snprintf_buf(filename, "%s/%s_%s.ts",savedir.str_value,this->channels[this->channel].name, dates); xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"saving to savedir\n"); } } else { snprintf_buf(filename, "%s/%s_%s.ts",xine_get_homedir(),this->channels[this->channel].name, dates); xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"Saving to HomeDir\n"); } /* remove spaces from name */ while((filename[x]!=0) && x<255){ if(filename[x]==' ') filename[x]='_'; x++; } /* start recording */ this->record_fd = xine_create_cloexec(filename, O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); this->stream->osd_renderer->clear (this->rec_osd); this->stream->osd_renderer->render_text (this->rec_osd, 10, 10, "Recording to:", OSD_TEXT3); this->stream->osd_renderer->render_text (this->rec_osd, 160, 10, filename, OSD_TEXT3); this->stream->osd_renderer->show_unscaled (this->rec_osd, 0); } } static void dvb_event_handler (dvb_input_plugin_t *this) { xine_event_t *event; static int channel_menu_visible = 0; static int next_channel = -1; while ((event = xine_event_get (this->event_queue))) { xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"got event %08x\n", event->type); if (this->fd < 0) { xine_event_free (event); return; } switch (event->type) { case XINE_EVENT_INPUT_MOUSE_BUTTON: { xine_input_data_t *input = (xine_input_data_t*)event->data; switch (input->button) { case MOUSE_BUTTON_LEFT: if (channel_menu_visible) { channel_menu_visible = 0; if (next_channel != this->channel){ this->channel = next_channel; switch_channel (this, next_channel); } else this->stream->osd_renderer->hide(this->channel_osd, 0); } #ifdef LEFT_MOUSE_DOES_EPG else { /* show EPG on left click of videowindow */ show_eit(this); } #endif break; case MOUSE_WHEEL_UP: if (!channel_menu_visible) next_channel = this->channel; if (next_channel > 0) next_channel--; channel_menu_visible = 1; osd_show_channel(this, next_channel); break; case MOUSE_WHEEL_DOWN: if (!channel_menu_visible) next_channel = this->channel; if (next_channel < (this->num_channels-1)) next_channel++; channel_menu_visible = 1; osd_show_channel(this, next_channel); break; case MOUSE_SIDE_LEFT: if (this->channel > 0) { this->channel--; channel_menu_visible = 0; switch_channel(this, this->channel); } break; case MOUSE_SIDE_RIGHT: if (this->channel < (this->num_channels-1)) { this->channel++; channel_menu_visible = 0; switch_channel (this, this->channel); } break; default: /* Unused mouse event. */ break; } break; } case XINE_EVENT_INPUT_DOWN: if (!channel_menu_visible) next_channel = this->channel; if (next_channel < (this->num_channels-1)) next_channel++; channel_menu_visible = 1; osd_show_channel(this, next_channel); break; case XINE_EVENT_INPUT_UP: if (!channel_menu_visible) next_channel = this->channel; if (next_channel > 0) next_channel--; channel_menu_visible = 1; osd_show_channel(this, next_channel); break; case XINE_EVENT_INPUT_NEXT: if (this->channel < (this->num_channels-1)) { channel_menu_visible = 0; switch_channel (this, this->channel + 1); } break; case XINE_EVENT_INPUT_SELECT: channel_menu_visible = 0; if (next_channel != this->channel){ switch_channel (this, next_channel); this->channel = next_channel; } else this->stream->osd_renderer->hide(this->channel_osd, 0); break; case XINE_EVENT_INPUT_PREVIOUS: if (this->channel>0) { channel_menu_visible = 0; switch_channel (this, this->channel - 1); } break; case XINE_EVENT_INPUT_MENU1: if (this->osd != NULL) this->stream->osd_renderer->hide (this->osd, 0); channel_menu_visible = 0; break; case XINE_EVENT_INPUT_MENU2: do_record (this); break; case XINE_EVENT_INPUT_MENU3: /* zoom for cropped 4:3 in a 16:9 window */ if (!this->zoom_ok) { this->zoom_ok = 1; xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 133); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, 133); } else { this->zoom_ok=0; xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 100); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, 100); } break; case XINE_EVENT_INPUT_MENU4: /* Pause recording.. */ if ((this->record_fd>-1) && (!this->record_paused)) { this->record_paused = 1; this->stream->osd_renderer->render_text (this->paused_osd, 15, 10, "Recording Paused",OSD_TEXT3); this->stream->osd_renderer->show_unscaled (this->paused_osd, 0); } else { this->record_paused=0; this->stream->osd_renderer->hide (this->paused_osd, 0); } break; case XINE_EVENT_INPUT_MENU7: channel_menu_visible = 0; show_eit(this); break; #if 0 default: printf ("input_dvb: got an event, type 0x%08x\n", event->type); #endif } xine_event_free (event); } } /* parse TS and re-write PAT to contain only our pmt */ static void ts_rewrite_packets (dvb_input_plugin_t *this, unsigned char * originalPkt, int len) { #define PKT_SIZE 188 #define BODY_SIZE (188-4) unsigned int sync_byte; unsigned int data_offset; unsigned int data_len; unsigned int pid; while(len>0){ sync_byte = originalPkt[0]; pid = ((originalPkt[1] << 8) | originalPkt[2]) & 0x1fff; /* * Discard packets that are obviously bad. */ data_offset = 4; originalPkt+=data_offset; if (pid == 0 && sync_byte==0x47) { unsigned long crc; originalPkt[3]=13; /* section length including CRC - first 3 bytes */ originalPkt[2]=0x80; originalPkt[7]=0; /* section number */ originalPkt[8]=0; /* last section number */ originalPkt[9]=(this->channels[this->channel].service_id >> 8) & 0xff; originalPkt[10]=this->channels[this->channel].service_id & 0xff; originalPkt[11]=(this->channels[this->channel].pmtpid >> 8) & 0xff; originalPkt[12]=this->channels[this->channel].pmtpid & 0xff; crc = xine_crc32_ieee(0xffffffff, originalPkt+1, 12); originalPkt[13]=(crc ) & 0xff; originalPkt[14]=(crc>> 8) & 0xff; originalPkt[15]=(crc>>16) & 0xff; originalPkt[16]=(crc>>24) & 0xff; memset(originalPkt+17,0xFF,PKT_SIZE-21); /* stuff the remainder */ } data_len = PKT_SIZE - data_offset; originalPkt+=data_len; len-=data_len; } } static off_t dvb_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; uint8_t *buf = buf_gen; off_t n=0, total=0; struct pollfd pfd; if (!this->tuned_in) return 0; if (this->dvb_gui_enabled) dvb_event_handler (this); #ifdef LOG_READS xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG, "input_dvb: reading %" PRIdMAX " bytes...\n", (intmax_t)len); #endif /* protect against channel changes */ pthread_mutex_lock(&this->channel_change_mutex); total=0; while (totalfd; pfd.events = POLLPRI | POLLIN | POLLERR; pfd.revents = 0; if (!this->tuned_in) { pthread_mutex_unlock( &this->channel_change_mutex ); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_dvb: Channel \"%s\" could not be tuned in. " "Possibly erroneous settings in channels.conf " "(frequency changed?).\n", this->channels[this->channel].name); return 0; } if (poll(&pfd, 1, 1500) < 1) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_dvb: No data available. Signal Lost?? \n"); _x_demux_control_end(this->stream, BUF_FLAG_END_USER); this->read_failcount++; break; } if (this->read_failcount) { /* signal/stream regained after loss - kick the net_buf_control layer. */ this->read_failcount=0; xprintf(this->stream->xine,XINE_VERBOSITY_LOG, "input_dvb: Data resumed...\n"); _x_demux_control_start(this->stream); } if (pfd.revents & POLLPRI || pfd.revents & POLLIN) { n = read (this->fd, &buf[total], len-total); } else if (pfd.revents & POLLERR) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_dvb: No data available. Signal Lost?? \n"); _x_demux_control_end(this->stream, BUF_FLAG_END_USER); this->read_failcount++; break; } #ifdef LOG_READS xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG, "input_dvb: got %" PRIdMAX " bytes (%" PRIdMAX "/%" PRIdMAX " bytes read)\n", (intmax_t)n, (intmax_t)total, (intmax_t)len); #endif if (n > 0){ this->curpos += n; total += n; } else if (n < 0 && errno == EOVERFLOW) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_dvb: EOVERFLOW returned. Not reading fast/often enough? \n"); } else if (n < 0 && errno!=EAGAIN) { break; } } ts_rewrite_packets (this, buf,total); if ((this->record_fd > -1) && (!this->record_paused)) if (write (this->record_fd, buf, total) != total) { do_record(this); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_dvb: Recording failed\n"); } pthread_mutex_unlock( &this->channel_change_mutex ); /* no data for several seconds - tell the user a possible reason */ if(this->read_failcount==5){ _x_message(this->stream,1,"DVB Signal Lost. Please check connections.", NULL); } #ifdef DVB_NO_BUFFERING if(this->newchannel){ this->newchannel = 0; xine_usec_sleep(1200000); } #endif return total; } static off_t dvb_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; xprintf(this->stream->xine,XINE_VERBOSITY_DEBUG,"seek %" PRIdMAX " bytes, origin %d\n", (intmax_t)offset, origin); return _x_input_seek_preview(this_gen, offset, origin, &this->curpos, -1, -1); } static off_t dvb_plugin_get_current_pos (input_plugin_t *this_gen){ dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; return this->curpos; } static void dvb_plugin_dispose (input_plugin_t *this_gen) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; int i, j; if (this->fd != -1) { close(this->fd); this->fd = -1; } if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } if (this->event_queue) xine_event_dispose_queue (this->event_queue); _x_freep (&this->mrl); /* Free the EPG data. */ for (i = 0; i < this->num_channels; ++i) { for (j = 0; j < MAX_EPG_ENTRIES_PER_CHANNEL && this->channels[i].epg[j]; ++j) { _x_freep(&this->channels[i].epg[j]->description); _x_freep(&this->channels[i].epg[j]->progname); _x_freep(&this->channels[i].epg[j]->content); _x_freep(&this->channels[i].epg[j]); } } if (this->channels) free_channel_list (this->channels, this->num_channels); /* Make the EPG updater thread return. */ this->epg_updater_stop = 1; if (this->tuner) tuner_dispose (this->tuner); if(this->proginfo_osd) this->stream->osd_renderer->hide (this->proginfo_osd,0); if(this->background) this->stream->osd_renderer->hide (this->background,0); /* free all memory associated with our OSD */ if(this->rec_osd) this->stream->osd_renderer->free_object(this->rec_osd); if(this->channel_osd) this->stream->osd_renderer->free_object(this->channel_osd); if(this->name_osd) this->stream->osd_renderer->free_object(this->name_osd); if(this->paused_osd) this->stream->osd_renderer->free_object(this->paused_osd); if(this->proginfo_osd) this->stream->osd_renderer->free_object(this->proginfo_osd); if(this->background) this->stream->osd_renderer->free_object(this->background); free (this); } static const char* dvb_plugin_get_mrl (input_plugin_t *this_gen) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; return this->mrl; } /* allow center cutout zoom for dvb content */ static void dvb_zoom_cb (void *this_gen, xine_cfg_entry_t *cfg) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; int factor = 100; if (!this) return; this->zoom_ok = cfg->num_value; if (this->zoom_ok) { factor = 133; } xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, factor); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, factor); } static int dvb_plugin_open(input_plugin_t * this_gen) { dvb_input_plugin_t *this = (dvb_input_plugin_t *) this_gen; tuner_t *tuner; channel_t *channels; int num_channels = 0; config_values_t *config = this->stream->xine->config; char str[256]; char *ptr; int x; char dummy=0; xine_cfg_entry_t zoomdvb; xine_cfg_entry_t adapter; xine_cfg_entry_t lastchannel; xine_cfg_entry_t gui_enabled; if (xine_config_lookup_entry(this->stream->xine, "media.dvb.gui_enabled", &gui_enabled)) this->dvb_gui_enabled = gui_enabled.num_value; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: DVB GUI %s\n"), this->dvb_gui_enabled ? "enabled" : "disabled"); if (!xine_config_lookup_entry(this->stream->xine, "media.dvb.adapter", &adapter)) adapter.num_value = 0; if (!(tuner = tuner_init(this->stream->xine,adapter.num_value))) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: cannot open dvb device\n")); return 0; } if (strncasecmp(this->mrl, "dvb://", 6) == 0) { /* * This is either dvb:// * or the "magic" dvb:// * We load the channels from ~/.xine/channels.conf * and assume that its format is valid for our tuner type */ if (!(channels = load_channels(this->stream->xine, this->stream, &num_channels, tuner->feinfo.type))) { /* failed to load the channels */ tuner_dispose(tuner); return 0; } if ((sscanf(this->mrl, "dvb://%d%1c", &this->channel, &dummy) >0 ) && ((isalpha(dummy)==0) && (isspace(dummy)==0))) { /* dvb:// format: load channels from ~/.xine/channels.conf */ if (this->channel >= num_channels) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: channel %d out of range, defaulting to 0\n"), this->channel); this->channel = 0; } } else { /* dvb:// format ? */ char *channame = this->mrl + 6; if (*channame) { /* try to find the specified channel */ int idx = 0; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: searching for channel %s\n"), channame); while (idx < num_channels) { if (strcasecmp(channels[idx].name, channame) == 0) break; idx++; } if (idx < num_channels) { this->channel = idx; } else { /* * try a partial match too * be smart and compare starting from the first char, then from * the second etc.. * Yes, this is expensive, but it happens really often * that the channels have really ugly names, sometimes prefixed * by numbers... */ size_t chanlen = strlen(channame); size_t offset = 0; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: exact match for %s not found: trying partial matches\n"), channame); do { idx = 0; while (idx < num_channels) { if (strlen(channels[idx].name) > offset) { if (strncasecmp(channels[idx].name + offset, channame, chanlen) == 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: found matching channel %s\n"), channels[idx].name); break; } } idx++; } offset++; xprintf(this->stream->xine,XINE_VERBOSITY_LOG,"%zd,%d,%d\n", offset, idx, num_channels); } while ((offset < 6) && (idx == num_channels)); if (idx < num_channels) { this->channel = idx; } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: channel %s not found in channels.conf, defaulting.\n"), channame); this->channel = 0; } } } else { /* just default to channel 0 */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: invalid channel specification, defaulting to last viewed channel.\n")); if (xine_config_lookup_entry(this->stream->xine, "media.dvb.remember_channel", &lastchannel)) { if (lastchannel.num_value) { if (xine_config_lookup_entry(this->stream->xine, "media.dvb.last_channel", &lastchannel)){ this->channel = lastchannel.num_value -1; if (this->channel < 0 || this->channel >= num_channels) this->channel = 0; /* out of range? default */ }else{ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: invalid channel specification, defaulting to channel 0\n")); this->channel = 0; } } } } } } else if (strncasecmp(this->mrl, "dvbs://", 7) == 0) { /* * This is dvbs://: */ if (tuner->feinfo.type != FE_QPSK) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: dvbs mrl specified but the tuner doesn't appear to be QPSK (DVB-S)\n")); tuner_dispose(tuner); return 0; } ptr = this->mrl; ptr += 7; channels = calloc(1, sizeof(channel_t)); _x_assert(channels != NULL); if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) { free(channels); tuner_dispose(tuner); return 0; } this->channel = 0; } else if (strncasecmp(this->mrl, "dvbt://", 7) == 0) { /* * This is dvbt://: */ if (tuner->feinfo.type != FE_OFDM) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: dvbt mrl specified but the tuner doesn't appear to be OFDM (DVB-T)\n")); tuner_dispose(tuner); return 0; } ptr = this->mrl; ptr += 7; channels = calloc(1, sizeof(channel_t)); _x_assert(channels != NULL); if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) { free(channels); tuner_dispose(tuner); return 0; } this->channel = 0; } else if (strncasecmp(this->mrl, "dvbc://", 7) == 0) { /* * This is dvbc://: */ if (tuner->feinfo.type != FE_QAM) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: dvbc mrl specified but the tuner doesn't appear to be QAM (DVB-C)\n")); tuner_dispose(tuner); return 0; } ptr = this->mrl; ptr += 7; channels = calloc(1, sizeof(channel_t)); _x_assert(channels != NULL); if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) { free(channels); tuner_dispose(tuner); return 0; } this->channel = 0; } else if (strncasecmp(this->mrl, "dvba://", 7) == 0) { /* * This is dvba://: */ if (tuner->feinfo.type != FE_ATSC) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: dvba mrl specified but the tuner doesn't appear to be ATSC (DVB-A)\n")); tuner_dispose(tuner); return 0; } ptr = this->mrl; ptr += 7; channels = calloc(1, sizeof(channel_t)); _x_assert(channels != NULL); if (extract_channel_from_string(channels, ptr, tuner->feinfo.type) < 0) { free(channels); tuner_dispose(tuner); return 0; } this->channel = 0; }else { /* not our mrl */ tuner_dispose(tuner); return 0; } this->tuner = tuner; this->channels = channels; this->num_channels = num_channels; if (!tuner_set_channel(this, &this->channels[this->channel])) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: tuner_set_channel failed\n")); return 0; } if ((this->fd = xine_open_cloexec(this->tuner->dvr_device, O_RDONLY |O_NONBLOCK)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: cannot open dvr device '%s'\n"), this->tuner->dvr_device); return 0; } this->tuned_in = 1; /* now read the pat, find all accociated PIDs and add them to the stream */ dvb_parse_si(this); this->curpos = 0; this->osd = NULL; pthread_mutex_init(&this->channel_change_mutex, NULL); this->event_queue = xine_event_new_queue(this->stream); #ifdef EPG_UPDATE_IN_BACKGROUND if (this->dvb_gui_enabled) { /* Start the EPG updater thread. */ this->epg_updater_stop = 0; if (pthread_create(&this->epg_updater_thread, NULL, epg_data_updater, this) != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvb: cannot create EPG updater thread\n")); return 0; } } #endif /* * this osd is used to draw the "recording" sign */ this->rec_osd = this->stream->osd_renderer->new_object(this->stream->osd_renderer, 900, 61); this->stream->osd_renderer->set_position(this->rec_osd, 20, 10); this->stream->osd_renderer->set_font(this->rec_osd, "cetus", 26); this->stream->osd_renderer->set_encoding(this->rec_osd, NULL); this->stream->osd_renderer->set_text_palette(this->rec_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT3); /* * this osd is used to draw the channel switching OSD */ this->channel_osd = this->stream->osd_renderer->new_object( this->stream->osd_renderer, CHSEL_WIDTH, CHSEL_HEIGHT); this->stream->osd_renderer->set_position(this->channel_osd, 20, 10); this->stream->osd_renderer->set_encoding(this->channel_osd, NULL); /* * this osd is for displaying currently shown channel name */ this->name_osd = this->stream->osd_renderer->new_object(this->stream->osd_renderer, 301, 61); this->stream->osd_renderer->set_position(this->name_osd, 20, 10); this->stream->osd_renderer->set_font(this->name_osd, "cetus", 40); this->stream->osd_renderer->set_encoding(this->name_osd, NULL); this->stream->osd_renderer->set_text_palette(this->name_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT3); /* * this osd is for displaying Recording Paused */ this->paused_osd = this->stream->osd_renderer->new_object(this->stream->osd_renderer, 301, 161); this->stream->osd_renderer->set_position(this->paused_osd, 10, 50); this->stream->osd_renderer->set_font(this->paused_osd, "cetus", 40); this->stream->osd_renderer->set_encoding(this->paused_osd, NULL); this->stream->osd_renderer->set_text_palette(this->paused_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT3); /* * This osd is for displaying Program Information (EIT), i.e., EPG. */ this->proginfo_osd = this->stream->osd_renderer->new_object( this->stream->osd_renderer, EPG_WIDTH, EPG_HEIGHT); this->stream->osd_renderer->set_font(this->proginfo_osd, "sans", 24); this->stream->osd_renderer->set_encoding(this->proginfo_osd, NULL); this->stream->osd_renderer->set_text_palette(this->proginfo_osd, XINE_TEXTPALETTE_WHITE_NONE_TRANSLUCID, OSD_TEXT3); this->stream->osd_renderer->set_text_palette(this->proginfo_osd, XINE_TEXTPALETTE_YELLOW_BLACK_TRANSPARENT, OSD_TEXT4); this->background = this->stream->osd_renderer->new_object( this->stream->osd_renderer, EPG_WIDTH + EPG_BACKGROUND_MARGIN*2, EPG_HEIGHT + EPG_BACKGROUND_MARGIN*2); this->epg_displaying = 0; /* zoom for 4:3 in a 16:9 window */ config->register_bool(config, "media.dvb.zoom", 0, _("use DVB 'center cutout' (zoom)"), _("This will allow fullscreen " "playback of 4:3 content " "transmitted in a 16:9 frame."), 0, &dvb_zoom_cb, (void *) this); if (xine_config_lookup_entry(this->stream->xine, "media.dvb.zoom", &zoomdvb)) dvb_zoom_cb((input_plugin_t *) this, &zoomdvb); if (xine_config_lookup_entry(this->stream->xine, "media.dvb.remember_channel", &lastchannel)) if (lastchannel.num_value){ /* Remember last watched channel. never show this entry*/ config->update_num(config, "media.dvb.last_channel", this->channel+1); } /* * init metadata (channel title) */ snprintf_buf(str, "%s", this->channels[this->channel].name); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, str); /* Clear all pids, the pmt will tell us which to use */ for (x = 0; x < MAX_FILTERS; x++){ this->channels[this->channel].pid[x] = DVB_NOPID; } return 1; } static int dvb_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_DEMUXER: if (data) *(const char **)data = "mpeg-ts"; return INPUT_OPTIONAL_SUCCESS; default: return INPUT_OPTIONAL_UNSUPPORTED; } return INPUT_OPTIONAL_UNSUPPORTED; } static input_plugin_t *dvb_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *data) { dvb_input_plugin_t *this; const char *mrl = data; if(strncasecmp (mrl, "dvb://",6)) if(strncasecmp(mrl,"dvbs://",7)) if(strncasecmp(mrl,"dvbt://",7)) if(strncasecmp(mrl,"dvbc://",7)) if(strncasecmp(mrl,"dvba://",7)) return NULL; this = calloc(1, sizeof(dvb_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->mrl = strdup(mrl); this->tuner = NULL; this->channels = NULL; this->fd = -1; this->tuned_in = 0; #ifndef DVB_NO_BUFFERING this->nbc = nbc_init (this->stream); #else this->nbc = NULL; #endif this->osd = NULL; this->event_queue = NULL; this->record_fd = -1; this->read_failcount = 0; this->epg_updater_stop = 0; this->input_plugin.open = dvb_plugin_open; this->input_plugin.read = dvb_plugin_read; this->input_plugin.seek = dvb_plugin_seek; this->input_plugin.get_current_pos = dvb_plugin_get_current_pos; this->input_plugin.get_mrl = dvb_plugin_get_mrl; this->input_plugin.get_capabilities = _x_input_get_capabilities_none; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.get_length = _x_input_default_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_optional_data = dvb_plugin_get_optional_data; this->input_plugin.dispose = dvb_plugin_dispose; this->input_plugin.input_class = class_gen; return &this->input_plugin; } /* * dvb input plugin class stuff */ static void dvb_class_dispose(input_class_t * this_gen) { dvb_input_class_t *class = (dvb_input_class_t *) this_gen; int x; for(x=0;xnumchannels;x++) _x_freep(&class->autoplaylist[x]); free(class); } static int dvb_class_eject_media (input_class_t *this_gen) { (void)this_gen; return 1; } static const char * const *dvb_class_get_autoplay_list(input_class_t * this_gen, int *num_files) { dvb_input_class_t *class = (dvb_input_class_t *) this_gen; channel_t *channels=NULL; int ch, apch, num_channels = 0; int default_channel = -1; xine_cfg_entry_t lastchannel_enable = {.num_value = 0}; xine_cfg_entry_t lastchannel; /* need to probe card here to get fe_type to read in channels.conf */ tuner_t *tuner; xine_cfg_entry_t adapter; if (!xine_config_lookup_entry(class->xine, "media.dvb.adapter", &adapter)) adapter.num_value = 0; if (!(tuner = tuner_init(class->xine,adapter.num_value))) { static const char * const mrls[] = {"Sorry, No DVB input device found.", NULL}; xprintf(class->xine, XINE_VERBOSITY_LOG, _("input_dvb: cannot open dvb device\n")); *num_files=1; return mrls; } if (!(channels = load_channels(class->xine, NULL, &num_channels, tuner->feinfo.type))) { /* channels.conf not found in .xine */ static const char * const mrls[] = { "Sorry, No valid channels.conf found", "for the selected DVB device.", "Please run the dvbscan utility", "from the dvb drivers apps package", "and place the file in ~/.xine/", NULL }; *num_files=5; tuner_dispose(tuner); return mrls; } tuner_dispose(tuner); if (xine_config_lookup_entry(class->xine, "media.dvb.remember_channel", &lastchannel_enable) && lastchannel_enable.num_value && xine_config_lookup_entry(class->xine, "media.dvb.last_channel", &lastchannel)) { default_channel = lastchannel.num_value - 1; if (default_channel < 0 || default_channel >= num_channels) default_channel = -1; } for (ch = 0, apch = !!lastchannel_enable.num_value; ch < num_channels && ch < MAX_AUTOCHANNELS; ++ch, ++apch) { free(class->autoplaylist[apch]); class->autoplaylist[apch] = _x_asprintf("dvb://%s", channels[ch].name); _x_assert(class->autoplaylist[apch] != NULL); } if (lastchannel_enable.num_value){ free(class->autoplaylist[0]); if (default_channel != -1) /* plugin has been used before - channel is valid */ class->autoplaylist[0] = _x_asprintf("dvb://%s", channels[default_channel].name); else /* set a reasonable default - the first channel */ class->autoplaylist[0] = _x_asprintf("dvb://%s", num_channels ? channels[0].name : "0"); } free_channel_list(channels, num_channels); *num_files = num_channels + lastchannel_enable.num_value; class->numchannels = *num_files; return (const char * const *)class->autoplaylist; } static void *init_class (xine_t *xine, const void *data) { dvb_input_class_t *this; config_values_t *config = xine->config; (void)data; this = calloc(1, sizeof (dvb_input_class_t)); if (!this) return NULL; this->xine = xine; this->input_class.get_instance = dvb_class_get_instance; this->input_class.identifier = "dvb"; this->input_class.description = N_("DVB (Digital TV) input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = dvb_class_get_autoplay_list; this->input_class.dispose = dvb_class_dispose; this->input_class.eject_media = dvb_class_eject_media; xprintf(this->xine,XINE_VERBOSITY_DEBUG,"init class succeeded\n"); /* Enable remembering of last watched channel */ config->register_bool(config, "media.dvb.remember_channel", 1, _("Remember last DVB channel watched"), _("On autoplay, xine will remember and " "switch to the channel indicated in media.dvb.last_channel. "), 0, NULL, NULL); /* Enable remembering of last watched channel never show this entry*/ config->register_num(config, "media.dvb.last_channel", -1, _("Last DVB channel viewed"), _("If enabled xine will remember and switch to this channel. "), 21, NULL, NULL); config->register_num(config, "media.dvb.tuning_timeout", 0, _("Number of seconds until tuning times out."), _("Leave at 0 means try forever. " "Greater than 0 means wait that many seconds to get a lock. Minimum is 5 seconds."), 0, NULL, NULL); /* set to 0 to turn off the GUI built into this input plugin */ config->register_bool(config, "media.dvb.gui_enabled", 1, _("Enable the DVB GUI"), _("Enable the DVB GUI, mouse controlled recording and channel switching."), 21, NULL, NULL); config->register_num(config, "media.dvb.adapter", 0, _("Number of dvb card to use."), _("Leave this at zero unless you " "really have more than 1 card " "in your system."), 0, NULL, NULL); return this; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "DVB", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/input/pnm.h0000644000175000017500000000231014647725152013551 0ustar meme/* * Copyright (C) 2002-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * pnm util functions header by joschka */ #ifndef HAVE_PNM_H #define HAVE_PNM_H #ifndef __CYGWIN__ #include #endif #include typedef struct pnm_s pnm_t; pnm_t* pnm_connect (xine_stream_t *stream, const char *url); int pnm_read (pnm_t *this, char *data, int len); void pnm_close (pnm_t *this); int pnm_peek_header (pnm_t *this, char *data, int maxsize); #endif xine-lib-1.2/src/input/group_network.c0000644000175000017500000000444114647725152015666 0ustar meme/* * Copyright (C) 2017-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * simple network input plugins */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "group_network.h" #include /* * exported plugin catalog entry */ static const input_info_t input_hls_info = { /* need to try high level protocol before plain file or http(s). */ .priority = 1 }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 18, "tcp", XINE_VERSION_CODE, NULL, input_net_init_class }, { PLUGIN_INPUT, 18, "tls", XINE_VERSION_CODE, NULL, input_tls_init_class }, { PLUGIN_INPUT, 18, "gopher", XINE_VERSION_CODE, NULL, input_gopher_init_class }, { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "http", XINE_VERSION_CODE, NULL, input_http_init_class }, { PLUGIN_INPUT, 18, "rtsp", XINE_VERSION_CODE, NULL, input_rtsp_init_class }, { PLUGIN_INPUT, 18, "pnm", XINE_VERSION_CODE, NULL, input_pnm_init_class }, { PLUGIN_INPUT, 18, "ftp", XINE_VERSION_CODE, NULL, input_ftp_init_class }, { PLUGIN_INPUT, 18, "ftpes", XINE_VERSION_CODE, NULL, input_ftpes_init_class }, { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "hls", XINE_VERSION_CODE, &input_hls_info, input_hls_init_class }, { PLUGIN_INPUT, 18, "mpegdash", XINE_VERSION_CODE, &input_hls_info, input_mpegdash_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/input/http_helper.h0000644000175000017500000000615014647725152015303 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * URL helper functions */ #ifndef HTTP_HELPER_H #define HTTP_HELPER_H #include #include /* * user agent finder, using modified protcol names * {proto}://... * e.g. "qthttp://example.com/foo.mov" → "QuickTime" * * return: * NULL or user agent prefix */ const char *_x_url_user_agent (const char *url); /* * url parser * {proto}://{user}:{password}@{host}:{port}{uri} * {proto}://{user}:{password}@{[host]}:{port}{uri} * * return: * 0 invalid url * 1 valid url */ typedef struct { const char *proto; const char *host; int port; const char *path; const char *args; const char *uri; /* [?] */ const char *user; const char *password; char *buf; } xine_url_t; void _x_url_init (xine_url_t *url); int _x_url_parse2 (const char *mrl, xine_url_t *url); void _x_url_cleanup (xine_url_t *); /** @brief merge a new, possibly relative mrl with a given base. result will always be 0 terminated. * @param dest the buffer to write the result to. may be NULL. * @param dsize the size of *dest in bytes. * @param base_mrl the base to fill missing parts with. may be the same as dest, or NULL. * @param new_mrl the new mrl. may be NULL. * @return the string length of result. will be >= dsize when truncated. */ size_t _x_merge_mrl (char *dest, size_t dsize, const char *base_mrl, const char *new_mrl); /* * canonicalise url, given base * base must be valid according to _x_parse_url * url may only contain "://" if it's absolute * * return: * the canonicalised URL (caller must free() it) * NULL if error */ static inline XINE_MALLOC char *_x_canonicalise_url (const char *base, const char *url) { size_t base_length; char *cut; if ((cut = strstr (url, "://"))) return strdup (url); cut = strstr (base, "://"); _x_assert(cut); /* base is required to be valid according to _x_parse_url */ if (url[0] == '/') { /* absolute - base up to first '/' after "://", then url */ cut = cut ? strchr (cut + 3, '/') : NULL; } else { /* relative - base up to & inc. last '/', then url */ cut = cut ? strrchr (cut, '/') : NULL; if (cut) ++cut; } base_length = cut ? (size_t)(cut - base) : strlen (base); return _x_asprintf ("%.*s%s", (int)base_length, base, url); } #endif /* HTTP_HELPER_H */ xine-lib-1.2/src/input/net_buf_ctrl.h0000644000175000017500000000216014647725152015430 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * network buffering control */ #ifndef HAVE_NET_BUF_CTRL_H #define HAVE_NET_BUF_CTRL_H #ifdef __cplusplus extern "C" { #endif #include #define nbc_t xine_nbc_t #define nbc_init(s) xine_nbc_init (s) #define nbc_close(nbc) xine_nbc_close (nbc) #ifdef __cplusplus } #endif #endif /* HAVE_NET_BUF_CTRL_H */ xine-lib-1.2/src/input/input_rtp.c0000644000175000017500000005114714647725152015012 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Xine input plugin for multicast video streams. * * This is something of an experiment - it doesn't work well yet. Originally * the intent was to read an rtp stream, from, for example, Cisco IP * Tv. That's still a long term goal but RTP doesn't fit well in an input * plugin because typically video is carried on one multicast group and audio * in another - i.e it's already demultiplexed and an input plugin would * actually have to reassemble the content. Now that demultiplexers are * becomming separate loadable objects the right thing to do is to write an * RTP demux plugin and a playlist plugin that handles SDP. * * * In the meantime some experience with multicast video was wanted. Not * having hardware available to construct a stream on the fly a server was * written to multicast the contents of an mpeg program stream - it just * reads a pack then transmits it at the appropriate time as follows. * * fd is open for read on mpeg stream, sock for write on a multicast socket. * * while (1) { * \/\* read pack *\/ * read(fd, buf, 2048) * \/\* end of stream *\/ * if (buf[3] == 0xb9) * return 0; * * \/\* extract the system reference clock, srcb, from the pack *\/ * * send_at = srcb/90000.0; * while (time_now < send_at) { * wait; * } * r = write(sock, buf, 2048); * } * * One problem is that a stream from a DVD needs each pack sending * at approx 2.5ms intervals which is a shorter interval than the * standard linux clock. The RTC can be used for more finely grained * timing. * * If you live in a non multicast friendly environment then the stream * can be unicast. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #include #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #include #include #include #include #include #include #if defined (__SVR4) && defined (__sun) # include #endif #define LOG_MODULE "input_rtp" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "net_buf_ctrl.h" #include "input_helper.h" #ifdef __GNUC__ #define LOG_MSG(xine, message, args...) { \ xine_log(xine, XINE_LOG_MSG, message, ##args); \ lprintf(message, ##args); \ } #else #define LOG_MSG(xine, ...) { \ xine_log(xine, XINE_LOG_MSG, __VA_ARGS__); \ lprintf(__VA_ARGS__); \ } #endif #define BUFFER_SIZE (1024*1024) typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; char *mrl; config_values_t *config; const char *address; int port; const char *interface; /* For multicast, eth0, eth1 etc */ int is_rtp; int fh; unsigned char *buffer; /* circular buffer */ unsigned char *buffer_get_ptr; /* get pointer used by reader */ unsigned char *buffer_put_ptr; /* put pointer used by writer */ long buffer_count; /* number of bytes in the buffer */ unsigned char packet_buffer[65536]; int last_input_error; int input_eof; pthread_t reader_thread; off_t curpos; int rtp_running; char preview[MAX_PREVIEW_SIZE]; int preview_size; int preview_read_done; /* boolean true after attempt to read input stream for preview */ nbc_t *nbc; pthread_mutex_t buffer_ring_mut; pthread_cond_t writer_cond; pthread_cond_t reader_cond; } rtp_input_plugin_t; /* ***************************************************************** */ /* Private functions */ /* ***************************************************************** */ /* * */ static int host_connect_attempt(struct in_addr ia, int port, const char *interface, xine_t *xine) { int s = xine_socket_cloexec(PF_INET, SOCK_DGRAM, IPPROTO_UDP); union { struct sockaddr_in in; struct sockaddr sa; } saddr, saddr2; int optval; int multicast = 0; /* boolean, assume unicast */ if(s == -1) { LOG_MSG(xine, _("xine_socket_cloexec(): %s.\n"), strerror(errno)); return -1; } saddr.in.sin_family = AF_INET; saddr.in.sin_addr = ia; saddr.in.sin_port = htons(port); /* Is it a multicast address? */ if ((ntohl(saddr.in.sin_addr.s_addr) >> 28) == 0xe) { LOG_MSG(xine, _("IP address specified is multicast\n")); multicast = 1; /* boolean true */ } /* Try to increase receive buffer to 1MB to avoid dropping packets */ optval = BUFFER_SIZE; if ((setsockopt(s, SOL_SOCKET, SO_RCVBUF, &optval, sizeof(optval))) < 0) { LOG_MSG(xine, _("setsockopt(SO_RCVBUF): %s.\n"), strerror(errno)); close(s); return -1; } /* If multicast we allow multiple readers to open the same address */ if (multicast) { if ((setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &saddr.in, sizeof(saddr.in))) < 0) { LOG_MSG(xine, _("setsockopt(SO_REUSEADDR): %s.\n"), strerror(errno)); close(s); return -1; } } /* datagram socket */ if (bind(s, &saddr.sa, sizeof(saddr.in))) { LOG_MSG(xine, _("bind(): %s.\n"), strerror(errno)); close(s); return -1; } /* multicast ? */ if (multicast) { struct ip_mreq mreq; struct ifreq ifreq; /* If the user specified an adapter we have to * look up the interface address to use it. * Ref: UNIX Network Programming 2nd edition * Section 19.6 * W. Richard Stevens */ if (interface != NULL) { memset(&ifreq, 0, sizeof(ifreq)); strncpy(ifreq.ifr_name, interface, IFNAMSIZ - 1); if (ioctl(s, SIOCGIFADDR, &ifreq) < 0) { LOG_MSG(xine, _("Can't find address for iface %s:%s\n"), interface, strerror(errno)); interface = NULL; } } /* struct ip_mreq mreq; */ mreq.imr_multiaddr.s_addr = saddr.in.sin_addr.s_addr; if (interface == NULL) { mreq.imr_interface.s_addr = htonl(INADDR_ANY); } else { saddr2.sa = ifreq.ifr_addr; mreq.imr_interface.s_addr = saddr2.in.sin_addr.s_addr; } if (setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq))) { LOG_MSG(xine, _("setsockopt(IP_ADD_MEMBERSHIP) failed (multicast kernel?): %s.\n"), strerror(errno)); close(s); return -1; } } return s; } /* * */ static int host_connect(const char *host, int port, const char *interface, xine_t *xine) { struct hostent *h; int i; int s; h=gethostbyname(host); if(h==NULL) { LOG_MSG(xine, _("unable to resolve '%s'.\n"), host); return -1; } for(i=0; h->h_addr_list[i]; i++) { struct in_addr ia; memcpy(&ia, h->h_addr_list[i],4); s = host_connect_attempt(ia, port, interface, xine); if (s != -1) return s; } LOG_MSG(xine, _("unable to bind to '%s'.\n"), host); return -1; } /* * */ static void * input_plugin_read_loop(void *arg) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) arg; unsigned char *data; long length; fd_set read_fds; while (1) { /* System calls are not a thread cancellation point in Linux * pthreads. However, the RT signal sent to cancel the thread * will cause recv() to return with EINTR, and we can manually * check cancellation. */ pthread_testcancel(); { struct timeval recv_timeout; int rc; recv_timeout.tv_sec = 2; recv_timeout.tv_usec = 0; FD_ZERO( &read_fds ); FD_SET( this->fh, &read_fds ); /* wait for a packet to arrive - but do not hang! */ rc = select( this->fh+1, &read_fds, NULL, NULL, &recv_timeout ); if( rc > 0 ) { length = recv(this->fh, this->packet_buffer, sizeof(this->packet_buffer), 0); } else if( rc == 0 ) length = 0; else length = -1; } pthread_testcancel(); if (length < 0) { if (errno != EINTR) { LOG_MSG(this->stream->xine, _("recv(): %s.\n"), strerror(errno)); return NULL; } } else { data = this->packet_buffer; if (this->is_rtp) { int pad, ext; int csrc; /* Do minimal RTP parsing to extract payload. See * http://www.faqs.org/rfcs/rfc1889.html for header format. * * WARNING: wholly untested code. I don't have any RTP sender. */ if (length < 12) continue; pad = data[0] & 0x20; ext = data[0] & 0x10; csrc = data[0] & 0x0f; data += 12 + csrc * 4; length -= 12 + csrc * 4; if (ext) { long hlen; if (length < 4) continue; hlen = (data[2] << 8) | data[3]; data += hlen; length -= hlen; } if (pad) { if (length < 1) continue; /* FIXME: is the pad length byte included in the * length value or not? We assume it is not. */ length -= data[length - 1] + 1; } } /* insert data into cyclic buffer */ if (length > 0) { /* * if the buffer is full, wait for the reader * to signal */ pthread_mutex_lock(&this->buffer_ring_mut); /* wait for enough space to write the whole of the recv'ed data */ while( (BUFFER_SIZE - this->buffer_count) < length ) { struct timeval tv; struct timespec timeout; gettimeofday(&tv, NULL); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + 2; if( pthread_cond_timedwait(&this->writer_cond, &this->buffer_ring_mut, &timeout) != 0 ) { fprintf( stdout, "input_rtp: buffer ring not read within 2 seconds!\n" ); } } /* Now there's enough space to write some bytes into the buffer * determine how many bytes can be written. If the buffer wraps * around, write in two pieces: from the head pointer to the * end of the buffer and from the base to the remaining number * of bytes. */ { long buffer_space_remaining = BUFFER_SIZE - (this->buffer_put_ptr - this->buffer); if( buffer_space_remaining >= length ) { /* data fits inside the buffer */ memcpy(this->buffer_put_ptr, data, length); this->buffer_put_ptr += length; } else { /* data wrapped around the end of the buffer */ memcpy(this->buffer_put_ptr, data, buffer_space_remaining); memcpy(this->buffer, &data[buffer_space_remaining], length - buffer_space_remaining); this->buffer_put_ptr = &this->buffer[ length - buffer_space_remaining ]; } } this->buffer_count += length; /* signal the reader that there is new data */ pthread_cond_signal(&this->reader_cond); pthread_mutex_unlock(&this->buffer_ring_mut); } } } } /* ***************************************************************** */ /* END OF PRIVATES */ /* ***************************************************************** */ static off_t rtp_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t length) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; struct timeval tv; struct timespec timeout; off_t copied = 0; if (length < 0) return -1; while(length > 0) { off_t n; pthread_mutex_lock(&this->buffer_ring_mut); /* * if nothing in the buffer, wait for data for 5 seconds. If * no data is received within this timeout, return the number * of bytes already received (which is likely to be 0) */ if(this->buffer_count == 0) { gettimeofday(&tv, NULL); timeout.tv_nsec = tv.tv_usec * 1000; timeout.tv_sec = tv.tv_sec + 5; if(pthread_cond_timedwait(&this->reader_cond, &this->buffer_ring_mut, &timeout) != 0) { /* we timed out, no data available */ pthread_mutex_unlock(&this->buffer_ring_mut); return copied; } } /* Now determine how many bytes can be read. If the buffer * will wrap the buffer is read in two pieces, first read * to the end of the buffer, wrap the tail pointer and * update the buffer count. Finally read the second piece * from the base to the remaining count */ if(length > this->buffer_count) { n = this->buffer_count; } else { n = length; } if(((this->buffer_get_ptr - this->buffer) + n) > BUFFER_SIZE) { n = BUFFER_SIZE - (this->buffer_get_ptr - this->buffer); } /* the actual read */ memcpy(buf, this->buffer_get_ptr, n); buf += n; copied += n; length -= n; /* update the tail pointer, watch for wrap arounds */ this->buffer_get_ptr += n; if(this->buffer_get_ptr - this->buffer >= BUFFER_SIZE) this->buffer_get_ptr = this->buffer; this->buffer_count -= n; /* signal the writer that there's space in the buffer again */ pthread_cond_signal(&this->writer_cond); pthread_mutex_unlock(&this->buffer_ring_mut); } this->curpos += copied; return copied; } /* * */ static off_t rtp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; return _x_input_seek_preview(this_gen, offset, origin, &this->curpos, -1, -1); } /* * */ static off_t rtp_plugin_get_length (input_plugin_t *this_gen) { (void)this_gen; return -1; } /* * */ static off_t rtp_plugin_get_current_pos (input_plugin_t *this_gen){ rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; return this->curpos; } /* * */ static const char* rtp_plugin_get_mrl (input_plugin_t *this_gen) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; return this->mrl; } /* * */ static int rtp_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; /* Since this input plugin deals with stream data, we * are not going to worry about retaining the data packet * retrieved for review purposes. Hence, the first non-preview * packet read made will return the 2nd packet from the UDP/RTP stream. * The first packet is only used for the preview. */ if (data_type == INPUT_OPTIONAL_DATA_PREVIEW) { if (!this->preview_read_done) { this->preview_size = rtp_plugin_read(this_gen, this->preview, MAX_PREVIEW_SIZE); if (this->preview_size < 0) this->preview_size = 0; lprintf("Preview data length = %d\n", this->preview_size); this->preview_read_done = 1; } if (this->preview_size) memcpy(data, this->preview, this->preview_size); return this->preview_size; } else { return INPUT_OPTIONAL_UNSUPPORTED; } } static void rtp_plugin_dispose (input_plugin_t *this_gen ) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; if (this->nbc) nbc_close(this->nbc); if (this->rtp_running) { LOG_MSG(this->stream->xine, _("RTP: stopping reading thread...\n")); pthread_cancel(this->reader_thread); pthread_join(this->reader_thread, NULL); LOG_MSG(this->stream->xine, _("RTP: reading thread terminated\n")); } if (this->fh != -1) close(this->fh); pthread_mutex_destroy(&this->buffer_ring_mut); pthread_cond_destroy(&this->reader_cond); pthread_cond_destroy(&this->writer_cond); _x_freep(&this->buffer); _x_freep(&this->mrl); free(this); } static int rtp_plugin_open (input_plugin_t *this_gen ) { rtp_input_plugin_t *this = (rtp_input_plugin_t *) this_gen; int err; _x_assert(this->fh == -1); _x_assert(this->rtp_running == 0); LOG_MSG(this->stream->xine, _("Opening >address:%s port:%d interface:%s<\n"), this->address, this->port, this->interface); this->fh = host_connect(this->address, this->port, this->interface, this->stream->xine); if (this->fh == -1) return 0; this->last_input_error = 0; this->input_eof = 0; this->curpos = 0; this->rtp_running = 1; if ((err = pthread_create(&this->reader_thread, NULL, input_plugin_read_loop, (void *)this)) != 0) { LOG_MSG(this->stream->xine, _("input_rtp: can't create new thread (%s)\n"), strerror(err)); close(this->fh); this->fh = -1; this->rtp_running = 0; return 0; } return 1; } static input_plugin_t *rtp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { rtp_input_plugin_t *this; char *address = NULL; char *pptr; char *iptr; char *mrl; int is_rtp = 0; int port = 7658; mrl = strdup(data); if (!mrl) return NULL; if (!strncasecmp (mrl, "rtp://", 6)) { address = &mrl[6]; is_rtp = 1; } else if (!strncasecmp (mrl, "udp://", 6)) { address = &mrl[6]; is_rtp = 0; } if (address == NULL || strlen(address) == 0) { free(mrl); return NULL; } /* Locate the port number */ pptr = strchr(address, ':'); iptr = NULL; if (pptr) { *pptr++ = '\0'; sscanf(pptr, "%d", &port); /* Locate the interface name for multicast IP, eth0, eth1 etc * The mrl will be udp://
:?iface=eth0 */ if (*pptr != '\0') { if ( (pptr=strstr(pptr, "?iface=")) != NULL) { pptr += 7; if (*pptr != '\0') { iptr = pptr; // Ok ... user defined an interface } } } } this = calloc(1, sizeof(rtp_input_plugin_t)); if (!this) { free(mrl); return NULL; } this->stream = stream; this->mrl = mrl; this->address = address; this->port = port; this->is_rtp = is_rtp; this->fh = -1; this->rtp_running = 0; this->preview_size = 0; this->interface = iptr; pthread_mutex_init(&this->buffer_ring_mut, NULL); pthread_cond_init(&this->reader_cond, NULL); pthread_cond_init(&this->writer_cond, NULL); this->buffer = malloc(BUFFER_SIZE); this->buffer_put_ptr = this->buffer; this->buffer_get_ptr = this->buffer; this->buffer_count = 0; this->curpos = 0; this->input_plugin.open = rtp_plugin_open; this->input_plugin.get_capabilities = _x_input_get_capabilities_preview; this->input_plugin.read = rtp_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = rtp_plugin_seek; this->input_plugin.get_current_pos = rtp_plugin_get_current_pos; this->input_plugin.get_length = rtp_plugin_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = rtp_plugin_get_mrl; this->input_plugin.get_optional_data = rtp_plugin_get_optional_data; this->input_plugin.dispose = rtp_plugin_dispose; this->input_plugin.input_class = cls_gen; this->nbc = NULL; this->nbc = nbc_init(this->stream); if (!this->buffer) { rtp_plugin_dispose(&this->input_plugin); } return &this->input_plugin; } /* * net plugin class */ static void *init_class (xine_t *xine, const void *data) { static const input_class_t input_rtp_class = { .get_instance = rtp_class_get_instance, .description = N_("RTP and UDP input plugin as shipped with xine"), .identifier = "RTP/UDP", .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)xine; (void)data; return (void *)&input_rtp_class; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 18, "rtp", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/input/mmsh.h0000644000175000017500000000266614647725152013741 0ustar meme/* * Copyright (C) 2002-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * libmmsh public header */ #ifndef HAVE_MMSH_H #define HAVE_MMSH_H #include #include typedef struct mmsh_s mmsh_t; char* mmsh_connect_common(int *s ,int *port, char *url, char **host, char **path, char **file); mmsh_t* mmsh_connect (xine_stream_t *stream, const char *url_, int bandwidth); int mmsh_read (mmsh_t *this, char *data, int len); uint32_t mmsh_get_length (mmsh_t *this); void mmsh_close (mmsh_t *this); size_t mmsh_peek_header (mmsh_t *this, char *data, size_t maxsize); off_t mmsh_get_current_pos (mmsh_t *this); void mmsh_set_start_time (mmsh_t *this, int time_offset); #endif xine-lib-1.2/src/input/media_helper.c0000644000175000017500000000710714647725152015401 0ustar meme/* * Copyright (C) 2000-2011 the xine project, * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ /* Standard includes */ #include "config.h" #include #include #include #include #include #ifndef WIN32 #include #include #endif #include #include #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD_kernel__) #include /* CDIOCALLOW etc... */ #elif defined(HAVE_LINUX_CDROM_H) #include #elif defined(HAVE_SYS_CDIO_H) #include #elif WIN32 #else #warning "This might not compile due to missing cdrom ioctls" #endif #include "media_helper.h" #define LOG_MEDIA_EJECT #ifndef WIN32 static int media_umount_media(const char *device) { pid_t pid; int status; pid=fork(); if (pid == 0) { execl("/bin/umount", "umount", device, NULL); exit(127); } do { if(waitpid(pid, &status, 0) == -1) { if (errno != EINTR) return -1; } else { return WEXITSTATUS(status); } } while(1); return -1; } #endif int media_eject_media (xine_t *xine, const char *device) { #if defined (__sun) if (fork() == 0) { execl("/usr/bin/eject", "eject", device, NULL); _exit(EXIT_FAILURE); } return 1; #elif defined (WIN32) return 0; #else int fd; /* printf("input_dvd: Eject Device %s current device %s opened=%d handle=%p trying...\n",device, this->current_dvd_device, this->opened, this->dvdnav); */ media_umount_media(device); /* printf("input_dvd: umount result: %s\n", strerror(errno)); */ if ((fd = xine_open_cloexec(device, O_RDONLY|O_NONBLOCK)) > -1) { #if defined (__linux__) int ret, status; if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) { switch(status) { case CDS_TRAY_OPEN: if((ret = ioctl(fd, CDROMCLOSETRAY)) != 0) { #ifdef LOG_MEDIA_EJECT printf("input_dvd: CDROMCLOSETRAY failed: %s\n", strerror(errno)); #endif } break; case CDS_DISC_OK: if((ret = ioctl(fd, CDROMEJECT)) != 0) { #ifdef LOG_MEDIA_EJECT printf("input_dvd: CDROMEJECT failed: %s\n", strerror(errno)); #endif } break; } } else { #ifdef LOG_MEDIA_EJECT printf("input_dvd: CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)); #endif close(fd); return 0; } #elif defined (__NetBSD__) || defined (__OpenBSD__) || defined (__FreeBSD_kernel__) if (ioctl(fd, CDIOCALLOW) == -1) { xprintf(xine, XINE_VERBOSITY_DEBUG, "ioctl(cdromallow): %s\n", strerror(errno)); } else { if (ioctl(fd, CDIOCEJECT) == -1) { xprintf(xine, XINE_VERBOSITY_DEBUG, "ioctl(cdromeject): %s\n", strerror(errno)); } } #endif close(fd); } else { xprintf(xine, XINE_VERBOSITY_LOG, _("input_dvd: Device %s failed to open during eject calls\n"), device); } return 1; #endif } xine-lib-1.2/src/input/input_hls.c0000644000175000017500000014152214647725152014770 0ustar meme/* * Copyright (C) 2020-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #define LOG_MODULE "input_hls" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include #include #include "http_helper.h" #include "input_helper.h" #include "group_network.h" #include "multirate_pref.c" typedef enum { HLS_A_none = 0, HLS_A_AUDIO, HLS_A_AUTOSELECT, HLS_A_AVERAGE_BANDWIDTH, HLS_A_BANDWIDTH, HLS_A_BYTERANGE, HLS_A_CODECS, HLS_A_DEFAULT, HLS_A_FRAME_RATE, HLS_A_GROUP_ID, HLS_A_LANGUAGE, HLS_A_NAME, HLS_A_RESOLUTION, HLS_A_TYPE, HLS_A_URI, HLS_A_VIDEO_RANGE, HLS_A_last } hls_arg_type_t; typedef struct { input_class_t input_class; xine_t *xine; multirate_pref_t pref; } hls_input_class_t; typedef struct { uint64_t offs; uint32_t len; } hls_byterange_t; typedef struct hls_input_plugin_s { input_plugin_t input_plugin; xine_stream_t *stream; xine_nbc_t *nbc; input_plugin_t *in1; uint32_t caps1; int last_err; struct hls_input_plugin_s *main_input; unsigned int side_index; /** << 0 .. 3 */ unsigned int num_sides; struct { pthread_mutex_t mutex; time_t avail_start, play_start; /** << seconds since 1970 */ struct timespec play_systime; int lag; /** pts */ uint32_t type; int init; int refs; } sync; /** set by main input, used by sides */ struct { /** The intelligent seek manager. */ xine_mfrag_list_t *list; /** TJ. A mrl may contain multiple fragments. * I have seen .m3u8 that merely index a single fragment .mp4 file. * In theory, this may also skip and reorder fragments like a edit list, * so we need to store the given offsets here * (cannot assume 0 or or the list generated values). */ uint64_t *input_offs; /** << bytes + 1, or 0 if unset */ uint32_t *mrl_offs; /** << offs into list_buf */ off_t pos; off_t size; int64_t pts; uint32_t num; #define HLS_NO_FRAGMENT (~0u) uint32_t current; /** << 1..n or 0 (init fragment if there) */ } frag; off_t pos; char *list_buf; uint32_t list_bsize; enum { LIST_VOD, LIST_LIVE_BUMP, LIST_LIVE_REGET } list_type; uint32_t list_seq; uint32_t prev_size1; /** << the actual preview bytes, for INPUT_OPTIONAL_DATA_[SIZED]_PREVIEW. */ uint32_t prev_size2; /** << for read (), 0 after leaving that range. */ struct timespec frag_dur; /** << != 0 if fixed duration live frags */ struct timespec next_stop; /** << live timeline emulation */ int rewind; /** << seconds */ #define HLS_MAX_ITEMS 20 struct { uint32_t num; uint32_t mrl[HLS_MAX_ITEMS]; uint32_t group[HLS_MAX_ITEMS]; uint32_t ref[HLS_MAX_ITEMS]; multirate_pref_t pref[HLS_MAX_ITEMS]; } items; const char *list_strtype; const char *list_strseq; hls_byterange_t list_rangeinit; #define HLS_MAX_MRL 4096 char list_mrl[HLS_MAX_MRL]; char item_mrl[HLS_MAX_MRL]; char prev_item_mrl[HLS_MAX_MRL]; char side_mrl[1][HLS_MAX_MRL]; size_t bump_pos; size_t bump_size; uint32_t bump_seq; char pad1[4]; char bump1[HLS_MAX_MRL]; char pad2[4]; char bump2[HLS_MAX_MRL]; char preview[32 << 10]; } hls_input_plugin_t; #ifdef HAVE_POSIX_TIMERS # define xine_gettime(t) clock_gettime (CLOCK_REALTIME, t) #else static inline int xine_gettime (struct timespec *ts) { struct timeval tv; int r; r = gettimeofday (&tv, NULL); if (!r) { ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; } return r; } #endif static int hls_get_duration (hls_input_plugin_t *this) { int64_t d = 0; if (!xine_mfrag_get_index_start (this->frag.list, this->frag.num + 1, &d, NULL)) return 0; return d / 1000; } static off_t hls_get_size (hls_input_plugin_t *this) { int64_t s = 0; xine_mfrag_get_index_start (this->frag.list, this->frag.num + 1, NULL, &s); if (this->pos > s) s = this->pos; return s; } static uint32_t hls_frag_start (hls_input_plugin_t *this) { int64_t s1, s2; this->frag.pos = this->pos; /* known size */ xine_mfrag_get_index_frag (this->frag.list, this->frag.current, NULL, &s1); /* seen size */ s2 = this->in1->get_length (this->in1); /* subfragment? */ if (this->frag.input_offs[this->frag.current]) { this->frag.size = s1; if (s1 > 0) return s1; s2 -= this->frag.input_offs[this->frag.current] - 1; } /* update size */ this->frag.size = s2; if (s2 > 0) { if ((s1 > 0) && (s1 != s2)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: WTF: fragment #%u changed size from %" PRId64 " to %" PRId64 " bytes!!\n", this->side_index, (unsigned int)this->frag.current, s1, s2); } xine_mfrag_set_index_frag (this->frag.list, this->frag.current, -1, s2); return s2; } return s2; } static void hls_frag_end (hls_input_plugin_t *this) { int64_t s; s = this->pos - this->frag.pos; xine_mfrag_set_index_frag (this->frag.list, this->frag.current, -1, s); } static int hls_bump_find (hls_input_plugin_t *this, const char *item1, const char *seq) { size_t len1, len2; uint8_t *p1, *ps, s; const uint8_t *p2; if (!seq) return 0; p2 = (const uint8_t *)seq; { uint32_t v = 0; uint8_t z; while ((z = *p2++ ^ '0') <= 9) v = 10u * v + z; this->bump_seq = v; } len2 = p2 - (const uint8_t *)seq; if (len2 == 0) return 0; len1 = strlcpy (this->bump1, item1, sizeof (this->bump1)); p1 = (uint8_t *)this->bump1 + len1; if (len1 < len2) return 0; ps = p1 - len1 - 1; s = ps[0]; ps[0] = p1[-1]; while (1) { while (*--p1 != p2[-1]) ; p1++; if ((const uint8_t *)p1 <= ps) break; if (!memcmp (p1 - len1, seq, len1)) { this->bump_pos = p1 - (uint8_t *)this->bump1; ps[0] = s; return 1; } } return 0; } static int hls_bump_guess (hls_input_plugin_t *this, const char *item1, const char *item2) { size_t len1 = strlcpy (this->bump1, item1, sizeof (this->bump1)); uint8_t *p1 = (uint8_t *)this->bump1 + len1; size_t len2 = strlcpy (this->bump2, item2, sizeof (this->bump2)); uint8_t *p2 = (uint8_t *)this->bump2 + len2; this->bump_size = len1; while (1) { uint8_t *e1; /* find end of num string */ this->pad1[3] = '0'; this->pad2[3] = '0'; while (((*--p1) ^ '0') > 9) ; e1 = p1; if (p1 < (uint8_t *)this->bump1) return 0; while (((*--p2) ^ '0') > 9) ; if (p2 < (uint8_t *)this->bump2) return 0; /* find start there of */ this->pad1[3] = ' '; this->pad2[3] = ' '; while (((*--p1) ^ '0') <= 9) ; p1++; while (((*--p2) ^ '0') <= 9) ; p2++; /* evaluate nums */ { uint32_t v1, v2; const uint8_t *q; uint8_t z; v1 = 0, q = p1; while ((z = *q++ ^ '0') <= 9) v1 = 10u * v1 + z; v2 = 0, q = p2; while ((z = *q++ ^ '0') <= 9) v2 = 10u * v2 + z; if (v2 == v1 + 1) { this->bump_seq = v1; this->bump_pos = e1 - (uint8_t *)this->bump1 + 1; return 1; } } } return 0; } static void hls_bump_inc (hls_input_plugin_t *this) { uint8_t *p1 = (uint8_t *)this->bump1 + this->bump_pos; this->pad1[3] = ' '; while (1) { uint8_t z = *--p1 ^ '0'; if (z < 9) break; if (z > 9) { size_t l; l = this->bump_pos + 1; if (l > sizeof (this->bump1) - 1) l = sizeof (this->bump1) - 1; this->bump_pos = l; l = this->bump_size + 1; if (l > sizeof (this->bump1) - 1) l = sizeof (this->bump1) - 1; this->bump_size = l; p1++; l -= p1 - (uint8_t *)this->bump1; memmove (p1 + 1, p1, l); *p1 = '0'; break; } *p1 = '0'; } *p1 += 1; this->bump_seq += 1; } static int hls_input_switch_mrl (hls_input_plugin_t *this) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: %s.\n", this->side_index, this->item_mrl); if (this->in1) { if (this->in1->get_capabilities (this->in1) & INPUT_CAP_NEW_MRL) { if (this->in1->get_optional_data (this->in1, this->item_mrl, INPUT_OPTIONAL_DATA_NEW_MRL) == INPUT_OPTIONAL_SUCCESS) { if (this->in1->open (this->in1) > 0) return 1; } } _x_free_input_plugin (this->stream, this->in1); } this->in1 = _x_find_input_plugin (this->stream, this->item_mrl); if (!this->in1) return 0; if (this->in1->open (this->in1) <= 0) return 0; return 1; } static int hls_input_open_bump (hls_input_plugin_t *this) { /* bump mode */ _x_merge_mrl (this->item_mrl, HLS_MAX_MRL, this->list_mrl, this->bump1); if (!hls_input_switch_mrl (this)) return 0; this->caps1 = this->in1->get_capabilities (this->in1); hls_frag_start (this); return 1; } static int hls_input_open_item (hls_input_plugin_t *this, uint32_t n) { /* valid index ? */ if (n > this->frag.num) return 0; if (!n && !this->list_rangeinit.len) return 0; strcpy (this->prev_item_mrl, this->item_mrl); /* get fragment mrl */ _x_merge_mrl (this->item_mrl, HLS_MAX_MRL, this->list_mrl, this->list_buf + this->frag.mrl_offs[n]); /* get input */ if (strcmp (this->prev_item_mrl, this->item_mrl)) { this->caps1 = 0; if (!hls_input_switch_mrl (this)) return 0; } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: reuse %s for fragment #%u.\n", this->side_index, (const char *)this->item_mrl, (unsigned int)n); } this->caps1 = this->in1->get_capabilities (this->in1); /* input offset */ do { int64_t old_pos = this->in1->get_current_pos (this->in1), new_pos; if (old_pos < 0) break; if (!this->frag.input_offs[n]) break; new_pos = this->frag.input_offs[n] - 1; if (old_pos == new_pos) break; if (this->caps1 & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: seek into fragment @ %" PRId64 ".\n", this->side_index, new_pos); old_pos = this->in1->seek (this->in1, new_pos, SEEK_SET); if (old_pos == new_pos) break; } xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ".%u: sub input seek failed.\n", this->side_index); } while (0); this->frag.current = n; /* update size info */ hls_frag_start (this); this->bump_seq = this->list_seq + n - 1; return 1; } static int hls_input_get_mrl_ext (const char *mrl, const char **ext) { const char *p1, *p2; for (p2 = mrl; *p2 && (*p2 != '?'); p2++) ; for (p1 = p2; (p1 > mrl) && (p1[-1] != '.'); p1--) ; *ext = p1; return p2 - p1; } static int hls_input_is_hls (const char *mrl) { const char *ext; int n = hls_input_get_mrl_ext (mrl, &ext); if ((n == 2) && !strncasecmp (ext, "ts", 2)) return 1; if ((n == 3) && !strncasecmp (ext, "m2t", 3)) return 1; if ((n == 4) && !strncasecmp (ext, "m3u8", 4)) return 2; if ((n == 3) && !strncasecmp (ext, "hls", 3)) return 2; return 0; } static const uint8_t hls_tab_char[256] = { ['\t'] = 1, [' '] = 1, ['\r'] = 2, ['\n'] = 2, ['"'] = 4, ['\''] = 8, [','] = 16, ['='] = 32, [0] = 128 }; static void hls_skip_spc (char **s) { uint8_t *p = (uint8_t *)*s; while (hls_tab_char[*p] & 1) p++; *s = (char *)p; } static void hls_skip_newline_spc (char **s) { uint8_t *p = (uint8_t *)*s; while (hls_tab_char[*p] & (1 | 2)) p++; *s = (char *)p; } static void hls_skip_line (char **s) { uint8_t *p = (uint8_t *)*s; while (!(hls_tab_char[*p] & (2 | 128))) p++; *s = (char *)p; } static void hls_reset_args (char **a) { uint32_t u; for (u = 0; u < HLS_A_last; u++) a[u] = NULL; } static int hls_parse_args (char **a, char **s) { uint8_t *p = (uint8_t *)*s; int n = 0; while (*p) { uint8_t *key, *value = NULL; uint32_t klen; while (hls_tab_char[*p] & 1) /* spc */ p++; key = p; while (!(hls_tab_char[*p] & (1 | 16 | 32 | 128))) /* spc, ",", "=", end */ *p |= 0x20, p++; klen = p - key; while (hls_tab_char[*p] & 1) /* spc */ p++; if (*p != '=') { if (*p) p++; continue; } p++; while (hls_tab_char[*p] & 1) /* spc */ p++; if (*p == '"') { value = ++p; while (!(hls_tab_char[*p] & (4 | 128))) /* """, end */ p++; } else if (*p == '\'') { value = ++p; while (!(hls_tab_char[*p] & (8 | 128))) /* "'", end */ p++; } else if (*p) { value = p; while (!(hls_tab_char[*p] & (16 | 128))) /* ",", end */ p++; } if (*p) *p++ = 0; switch (klen) { case 3: if (!memcmp (key, "uri", 3)) a[HLS_A_URI] = value, n++; break; case 4: if (!memcmp (key, "name", 4)) a[HLS_A_NAME] = value, n++; else if (!memcmp (key, "type", 4)) a[HLS_A_TYPE] = value, n++; break; case 5: if (!memcmp (key, "audio", 5)) a[HLS_A_AUDIO] = value, n++; break; case 6: if (!memcmp (key, "codecs", 6)) a[HLS_A_CODECS] = value, n++; break; case 7: if (!memcmp (key, "default", 7)) a[HLS_A_DEFAULT] = value, n++; break; case 8: if (!memcmp (key, "group-id", 8)) a[HLS_A_GROUP_ID] = value, n++; else if (!memcmp (key, "language", 8)) a[HLS_A_LANGUAGE] = value, n++; break; case 9: if (!memcmp (key, "bandwidth", 9)) a[HLS_A_BANDWIDTH] = value, n++; else if (!memcmp (key, "byterange", 9)) a[HLS_A_BYTERANGE] = value, n++; break; case 10: if (!memcmp (key, "autoselct", 10)) a[HLS_A_AUTOSELECT] = value, n++; else if (!memcmp (key, "frame-rate", 10)) a[HLS_A_FRAME_RATE] = value, n++; else if (!memcmp (key, "resolution", 10)) a[HLS_A_RESOLUTION] = value, n++; break; case 11: if (!memcmp (key, "video-range", 11)) a[HLS_A_VIDEO_RANGE] = value, n++; break; case 17: if (!memcmp (key, "average-bandwidth", 17)) a[HLS_A_AVERAGE_BANDWIDTH] = value, n++; break; default: ; } } *s = (char *)p; return n; } static uint32_t str2uint32 (char **s) { uint8_t *p = (uint8_t *)*s; uint32_t v = 0; uint8_t z; while ((z = *p ^ '0') < 10) { v = v * 10u + z; p++; } *s = (char *)p; return v; } static uint64_t str2uint64 (char **s) { uint8_t *p = (uint8_t *)*s; uint64_t v = 0; uint8_t z; while ((z = *p ^ '0') < 10) { v = (v << 3) + (v << 1) + z; p++; } *s = (char *)p; return v; } static uint32_t str2usec (char **s) { uint8_t *p = (uint8_t *)*s; uint32_t v = 0; uint8_t z; while ((z = *p ^ '0') < 10) { v = v * 10u + z; p++; } v *= 1000000; do { if (z != ('.' ^ '0')) break; p++; if ((z = *p ^ '0') >= 10) break; v += 100000u * z; p++; if ((z = *p ^ '0') >= 10) break; v += 10000u * z; p++; if ((z = *p ^ '0') >= 10) break; v += 1000u * z; p++; if ((z = *p ^ '0') >= 10) break; v += 100u * z; p++; if ((z = *p ^ '0') >= 10) break; v += 10u * z; p++; if ((z = *p ^ '0') >= 10) break; v += z; p++; } while (0); *s = (char *)p; return v; } static void hls_parse_byterange (hls_byterange_t *r, char **s) { hls_skip_spc (s); r->len = str2uint32 (s); if (**s == '@') { (*s)++; r->offs = str2uint64 (s); } } static int hls_input_load_list (hls_input_plugin_t *this) { ssize_t size; char *line, *lend; uint32_t frag_duration, fixed_duration; char *args[HLS_A_last]; this->frag.mrl_offs = NULL; _x_freep (&this->frag.input_offs); xine_mfrag_list_close (&this->frag.list); this->frag.num = 0; this->items.num = 0; { off_t s = this->in1->get_length (this->in1); if (s > (32 << 20)) return 0; size = s; } if (size > 0) { /* size known, get at once. */ if (this->in1->seek (this->in1, 0, SEEK_SET) != 0) return 0; if ((uint32_t)size + 8 > this->list_bsize) { char *nbuf = realloc (this->list_buf, (uint32_t)size * 5 / 4 + 8); if (!nbuf) return 0; this->list_buf = nbuf; this->list_bsize = (uint32_t)size * 5 / 4 + 8; } if (this->in1->read (this->in1, this->list_buf + 4, size) != size) return 0; } else { /* chunked/deflated */ uint32_t have; if (!this->list_buf) { this->list_buf = malloc (32 << 10); if (!this->list_buf) return 0; this->list_bsize = 32 << 10; } have = 0; while (1) { int32_t r = this->in1->read (this->in1, this->list_buf + 4 + have, this->list_bsize - have - 8); if (r <= 0) break; have += r; if (have == this->list_bsize - 8) { char *nbuf; if (this->list_bsize >= (32 << 20)) break; nbuf = realloc (this->list_buf, this->list_bsize + (32 << 10)); if (!nbuf) return 0; this->list_buf = nbuf; this->list_bsize += 32 << 10; } } size = have; } memset (this->list_buf, 0, 4); memset (this->list_buf + 4 + size, 0, 4); this->list_seq = 1; this->list_strseq = ""; this->list_strtype = ""; fixed_duration = 0; frag_duration = 0; lend = this->list_buf + 4; hls_reset_args (args); if (strstr (lend, "#EXTINF:")) { uint32_t fragsize = ~0u; /* fragment list */ { union { uint64_t *u64; uint32_t *u32; } mem; uint32_t n = 0; while (1) { hls_skip_newline_spc (&lend); if (lend[0] == 0) break; if (lend[0] != '#') n++; hls_skip_line (&lend); } if (n == 0) return 0; mem.u64 = malloc ((n + 3) * (sizeof (*this->frag.input_offs) + sizeof (this->frag.mrl_offs))); if (!mem.u64) return 0; this->frag.input_offs = mem.u64; mem.u64 += n + 3; this->frag.mrl_offs = mem.u32; } this->frag.mrl_offs[0] = 0; this->frag.mrl_offs[1] = 0; this->frag.input_offs[0] = 0; this->frag.input_offs[1] = 0; xine_mfrag_list_open (&this->frag.list); xine_mfrag_set_index_frag (this->frag.list, 0, 1000000, 0); lend = this->list_buf + 4; while (1) { size_t llen; /* find next line */ hls_skip_newline_spc (&lend); if (lend[0] == 0) break; line = lend; hls_skip_line (&lend); llen = lend - line; if (lend[0] != 0) *lend++ = 0; if ((llen >=4) && !strncasecmp (line, "#EXT", 4)) { /* control tag */ if ((llen > 8) && !strncasecmp (line + 4, "INF:", 4)) { line += 8; frag_duration = str2usec (&line); if (fixed_duration == 0) fixed_duration = frag_duration; else if (fixed_duration != frag_duration) fixed_duration = ~0u; } else if ((llen > 17) && !strncasecmp (line + 4, "-X-BYTERANGE:", 13)) { line += 17; hls_skip_spc (&line); fragsize = str2uint32 (&line); hls_skip_spc (&line); if (*line == '@') { line++; hls_skip_spc (&line); this->frag.input_offs[this->frag.num + 1] = str2uint64 (&line) + 1; } else { this->frag.input_offs[this->frag.num + 1] = 1; } } else if ((llen > 7) && !strncasecmp (line + 4, "-X-MAP:", 7)) { /* hls-ng extension: #EXT-X-MAP:URI="foo.mp4",BYTERANGE="854@0" */ line += 11; hls_parse_args (args, &line); if (args[HLS_A_URI]) this->frag.mrl_offs[0] = args[HLS_A_URI] - this->list_buf; if (args[HLS_A_BYTERANGE]) hls_parse_byterange (&this->list_rangeinit, &args[HLS_A_BYTERANGE]); if (this->frag.mrl_offs[0]) { this->frag.input_offs[0] = this->list_rangeinit.offs + 1; xine_mfrag_set_index_frag (this->frag.list, 0, -1, this->list_rangeinit.len); } else { this->list_rangeinit.len = 0; } } else if ((llen > 22) && !strncasecmp (line + 4, "-X-MEDIA-SEQUENCE:", 18)) { line += 22; hls_skip_spc (&line); this->list_strseq = line; if (line[0]) this->list_seq = str2uint32 (&line); } else if ((llen > 21) && !strncasecmp (line + 4, "-X-PLAYLIST-TYPE:", 17)) { line += 21; hls_skip_spc (&line); this->list_strtype = line; } } else if ((llen >= 1) && (line[0] != '#')) { /* mrl */ this->frag.mrl_offs[this->frag.num + 1] = line - this->list_buf; this->frag.num += 1; this->frag.mrl_offs[this->frag.num + 1] = 0; this->frag.input_offs[this->frag.num + 1] = 0; xine_mfrag_set_index_frag (this->frag.list, this->frag.num, frag_duration, fragsize != ~0u ? (int64_t)fragsize : -1); } } if ((fixed_duration != 0) && (fixed_duration != ~0u)) { this->frag_dur.tv_sec = fixed_duration / 1000000; this->frag_dur.tv_nsec = (fixed_duration % 1000000) * 1000; } return 1; } if (strstr (lend, "#EXT-X-STREAM-INF:")) { uint32_t n = 0; /* item list */ while (1) { size_t llen; /* find next line */ while (((lend[0] & 0xe0) == 0) && (lend[0] != 0)) lend++; if (lend[0] == 0) break; line = lend; while ((lend[0] & 0xe0) != 0) lend++; llen = lend - line; *lend++ = 0; if ((llen >=4) && !strncasecmp (line, "#EXT", 4)) { /* control tag */ if ((llen > 18) && !strncasecmp (line + 4, "-X-STREAM-INF:", 14)) { if (n < HLS_MAX_ITEMS) { line += 18; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: item #%u: %s.\n", this->side_index, (unsigned int)n, line); this->items.pref[n].bitrate = 0; this->items.pref[n].video_width = 0; this->items.pref[n].video_height = 0; this->items.pref[n].lang[0] = 0; hls_reset_args (args); hls_parse_args (args, &line); this->items.ref[n] = args[HLS_A_AUDIO] ? args[HLS_A_AUDIO] - this->list_buf : 0; if (args[HLS_A_BANDWIDTH]) this->items.pref[n].bitrate = str2uint32 (&args[HLS_A_BANDWIDTH]); if (args[HLS_A_RESOLUTION]) { line = args[HLS_A_RESOLUTION]; this->items.pref[n].video_width = str2uint32 (&line); if ((*line & 0xdf) == 'X') { line += 1; this->items.pref[n].video_height = str2uint32 (&line); } } if (args[HLS_A_LANGUAGE]) { line = args[HLS_A_LANGUAGE]; if ((this->items.pref[n].lang[0] = line[0])) { if ((this->items.pref[n].lang[1] = line[1])) { if ((this->items.pref[n].lang[2] = line[2])) this->items.pref[n].lang[3] = 0; } } } } } else if ((llen > 13) && !strncasecmp (line + 4, "-X-MEDIA:", 9)) { line += 13; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: item #%u: %s.\n", this->side_index, (unsigned int)n, line); hls_reset_args (args); hls_parse_args (args, &line); if (args[HLS_A_URI] && (n < HLS_MAX_ITEMS)) { this->items.mrl[n] = args[HLS_A_URI] - this->list_buf; this->items.group[n] = args[HLS_A_GROUP_ID] ? args[HLS_A_GROUP_ID] - this->list_buf : 0; this->items.pref[n].bitrate = args[HLS_A_BANDWIDTH] ? str2uint32 (&args[HLS_A_BANDWIDTH]) : 0; if (args[HLS_A_RESOLUTION]) { line = args[HLS_A_RESOLUTION]; this->items.pref[n].video_width = str2uint32 (&line); if ((*line & 0xdf) == 'X') { line += 1; this->items.pref[n].video_height = str2uint32 (&line); } } else { this->items.pref[n].video_width = 0; this->items.pref[n].video_height = 0; } if (args[HLS_A_LANGUAGE]) { line = args[HLS_A_LANGUAGE]; if ((this->items.pref[n].lang[0] = line[0])) { if ((this->items.pref[n].lang[1] = line[1])) { if ((this->items.pref[n].lang[2] = line[2])) this->items.pref[n].lang[3] = 0; } } } else { this->items.pref[n].lang[0] = 0; } n++; } } } else if ((llen >= 1) && (line[0] != '#')) { /* mrl */ if (n < HLS_MAX_ITEMS) this->items.mrl[n++] = line - this->list_buf; } } this->items.num = n; return 2; } return 0; } static uint32_t hls_input_get_capabilities (input_plugin_t *this_gen) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; uint32_t flags; if (!this) return 0; if (this->list_type == LIST_VOD) { if (this->in1) this->caps1 = this->in1->get_capabilities (this->in1); flags = (this->caps1 & INPUT_CAP_SEEKABLE) | INPUT_CAP_TIME_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW; } else { flags = INPUT_CAP_LIVE | INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW; } return flags; } static void hls_live_start (hls_input_plugin_t *this) { if (!this->in1 || (this->list_type == LIST_VOD)) return; xine_gettime (&this->next_stop); this->frag.pts = xine_nbc_get_pos_pts (this->nbc); } static int hls_live_wait (hls_input_plugin_t *this) { struct timespec now = {0, 0}; int64_t pts; int d; if (!this->in1 || (this->frag_dur.tv_sec == 0)) return 1; pts = xine_nbc_get_pos_pts (this->nbc); if (this->next_stop.tv_sec == 0) { /* paranoia */ xine_gettime (&this->next_stop); this->next_stop.tv_sec -= 2; this->frag.pts = pts; } d = pts - this->frag.pts; if ((d > 0) && (d < 100 * 900000)) { this->frag_dur.tv_sec = d / 90000; this->frag_dur.tv_nsec = (d % 90000) * (1000000000 / 90000); } this->frag.pts = pts; this->next_stop.tv_sec += this->frag_dur.tv_sec; this->next_stop.tv_nsec += this->frag_dur.tv_nsec; if (this->next_stop.tv_nsec >= 1000000000) { this->next_stop.tv_nsec -= 1000000000; this->next_stop.tv_sec += 1; } xine_gettime (&now); d = (this->next_stop.tv_sec - now.tv_sec) * 1000; d += ((int)this->next_stop.tv_nsec - (int)now.tv_nsec) / 1000000; if ((d <= 0) || (d >= 100000)) return 1; this->caps1 = this->in1->get_capabilities (this->in1); if (this->caps1 & INPUT_CAP_NEW_MRL) { this->item_mrl[0] = 0; this->in1->get_optional_data (this->in1, this->item_mrl, INPUT_OPTIONAL_DATA_NEW_MRL); } if (_x_io_select (this->stream, -1, 0, d) != XIO_TIMEOUT) return 0; return 1; } static off_t hls_input_read (input_plugin_t *this_gen, void *buf, off_t len) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; uint8_t *b = (uint8_t *)buf; size_t left; if (!this || !b) return 0; if (len < 0) return 0; left = len; if (this->pos <= (off_t)this->prev_size2) { size_t l = this->prev_size2 - this->pos; if (l > 0) { if (l > left) l = left; memcpy (b, this->preview + this->pos, l); b += l; this->pos += l; left -= l; } if (left > 0) this->prev_size2 = 0; } while (left > 0) { int reget = 0; /* read, safe with unknown size. */ if (this->frag.current == HLS_NO_FRAGMENT) break; { ssize_t r = 0; size_t fragleft = left; if (this->frag.size > 0) { int64_t fl2 = this->frag.pos + this->frag.size - this->pos; if (fl2 <= 0) { fragleft = 0; } else if ((int64_t)fragleft > fl2) { fragleft = fl2; } } left -= fragleft; while (fragleft > 0) { r = this->in1->read (this->in1, (void *)b, fragleft); if (r <= 0) break; this->pos += r; b += r; fragleft -= r; } left += fragleft; if (left == 0) break; if (r <= 0) { if (r < 0) { this->last_err = errno; if (!this->last_err) this->last_err = EINVAL; break; } } } /* EOF */ hls_frag_end (this); /* bump */ if (this->list_type != LIST_LIVE_BUMP) { uint32_t n = this->frag.current + 1; if (n > this->frag.num + 1) { if (this->list_type != LIST_LIVE_REGET) break; reget = 1; } else { if (!hls_input_open_item (this, n)) break; } } else { hls_bump_inc (this); this->frag.current += 1; if (!hls_live_wait (this)) break; if (!hls_input_open_bump (this)) { this->list_type = LIST_LIVE_REGET; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: LIVE bump error, falling back to reget mode.\n", this->side_index); reget = 1; } } if (reget) { int32_t n; strcpy (this->item_mrl, this->list_mrl); if (!hls_input_switch_mrl (this)) break; if (hls_input_load_list (this) != 1) break; this->bump_seq += 1; n = this->bump_seq - this->list_seq; if ((n < 0) || (n >= (int32_t)this->frag.num)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: LIVE seq discontinuity %u -> %u.\n", this->side_index, (unsigned int)this->bump_seq, (unsigned int)this->list_seq); this->bump_seq = this->list_seq; n = 0; } if (!hls_input_open_item (this, n + 1)) break; } } { size_t done = b - (uint8_t *)buf; if (done > 0) return done; } if (!this->last_err) return 0; errno = this->last_err; this->last_err = 0; return -1; } static buf_element_t *hls_input_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { (void)this_gen; (void)fifo; (void)todo; return NULL; } static off_t hls_input_time_seek (input_plugin_t *this_gen, int time_offs, int origin) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; uint32_t new_time, d; int idx; if (!this) return 0; this->last_err = 0; if (this->list_type != LIST_VOD) return this->pos; if (!this->frag.list) return this->pos; d = hls_get_duration (this); switch (origin) { case SEEK_SET: new_time = 0; break; case SEEK_CUR: { int64_t t1, t2, p1, p2; xine_mfrag_get_index_start (this->frag.list, this->frag.current, &t1, &p1); xine_mfrag_get_index_start (this->frag.list, this->frag.current + 1, &t2, &p2); t1 /= 1000; t2 /= 1000; new_time = p2 - p1; new_time = new_time ? (uint32_t)t1 + (uint64_t)(t2 - t1) * (uint32_t)(this->pos - this->frag.pos) / new_time : (uint32_t)t1; } break; case SEEK_END: new_time = d; break; default: errno = EINVAL; return (off_t)-1; } new_time += time_offs; if (new_time > d) { errno = EINVAL; return (off_t)-1; } idx = xine_mfrag_find_time (this->frag.list, new_time * (uint64_t)1000); if (idx < 1) return (off_t)-1; { int64_t p; xine_mfrag_get_index_start (this->frag.list, idx, NULL, &p); if ((idx == 1) && (this->frag.current == 1) && (this->pos <= (off_t)this->prev_size2) && (p <= (int64_t)this->prev_size2)) { this->pos = p; } else { this->frag.current = idx; this->pos = p; this->prev_size2 = 0; if (!hls_input_open_item (this, idx)) return (off_t)-1; } } return this->pos; } static off_t hls_input_seek (input_plugin_t *this_gen, off_t offset, int origin) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; off_t new_offs, l; int idx; if (!this) return 0; this->last_err = 0; l = hls_get_size (this); switch (origin) { case SEEK_SET: new_offs = 0; break; case SEEK_CUR: new_offs = this->pos; break; case SEEK_END: new_offs = l; break; default: errno = EINVAL; return (off_t)-1; } new_offs += offset; if (new_offs < 0) { errno = EINVAL; return (off_t)-1; } /* always seek within preview. */ if ((new_offs <= (off_t)this->prev_size2) && (this->pos <= (off_t)this->prev_size2)) { this->pos = new_offs; return this->pos; } this->prev_size2 = 0; if (this->list_type != LIST_VOD) return this->pos; if (new_offs > l) { errno = EINVAL; return (off_t)-1; } idx = xine_mfrag_find_pos (this->frag.list, new_offs); if (idx < 1) { errno = EINVAL; return (off_t)-1; } if (((uint32_t)idx != this->frag.current) || (new_offs < this->pos)) { int64_t p1, p2; /* HACK: offsets around this fragment may be guessed ones, * and the fragment itself may turn out to be smaller than expected. * however, demux expects a seek to land at the exact byte offs. * lets try to meet that, even if it is still wrong. */ xine_mfrag_get_index_start (this->frag.list, idx, NULL, &p1); this->pos = p1; if (!hls_input_open_item (this, idx)) return (off_t)-1; xine_mfrag_get_index_start (this->frag.list, idx + 1, NULL, &p2); while (new_offs >= p2) { p1 = p2; this->pos = p1; idx += 1; if (!hls_input_open_item (this, idx)) return (off_t)-1; xine_mfrag_get_index_start (this->frag.list, idx + 1, NULL, &p2); } } new_offs -= this->frag.pos; if (new_offs > 0) { off_t subpos = new_offs; if (this->frag.input_offs[this->frag.current]) subpos += this->frag.input_offs[this->frag.current] - 1; if (this->in1->seek (this->in1, subpos, SEEK_SET) == subpos) { this->pos = this->frag.pos + new_offs; } else { this->in1->seek (this->in1, 0, SEEK_SET); this->pos = this->frag.pos; } } return this->pos; } static off_t hls_input_get_current_pos (input_plugin_t *this_gen) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; if (!this) return 0; return this->pos; } static off_t hls_input_get_length (input_plugin_t *this_gen) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; if (!this) return 0; return hls_get_size (this); } static const char *hls_input_get_mrl (input_plugin_t *this_gen) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; if (!this) return NULL; return this->list_mrl; } static void hls_input_dispose (input_plugin_t *this_gen) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; if (!this) return; if (this->in1) { _x_free_input_plugin (this->stream, this->in1); this->in1 = NULL; } if (this->nbc) { xine_nbc_close (this->nbc); this->nbc = NULL; } xine_mfrag_list_close (&this->frag.list); _x_freep (&this->list_buf); this->frag.mrl_offs = NULL; _x_freep (&this->frag.input_offs); if (this->side_index) { hls_input_plugin_t *main_input = this->main_input; this->sync.refs = 0; free (this); this = main_input; } if (this->sync.init) { pthread_mutex_lock (&this->sync.mutex); if (--this->sync.refs == 0) { pthread_mutex_unlock (&this->sync.mutex); pthread_mutex_destroy (&this->sync.mutex); free (this); } else { pthread_mutex_unlock (&this->sync.mutex); } } else { if (--this->sync.refs == 0) free (this); } } static int hls_input_open (input_plugin_t *this_gen) { static const char * const type_names[3] = { [LIST_VOD] = "seekable VOD", [LIST_LIVE_BUMP] = "non seekable LIVE bump", [LIST_LIVE_REGET] = "non seekable LIVE reget" }; hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; hls_input_class_t *cls = (hls_input_class_t *)this->input_plugin.input_class; int try; if (this->side_index > 0) { strcpy (this->list_mrl, this->side_mrl[this->side_index - 1]); strcpy (this->item_mrl, this->side_mrl[this->side_index - 1]); if (!hls_input_switch_mrl (this)) return 0; } for (try = 8; try > 0; try--) { int n; n = hls_input_load_list (this); if (n == 1) break; if (n != 2) return 0; n = multirate_autoselect (&cls->pref, this->items.pref, this->items.num); if (n < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: no auto selected item.\n", this->side_index); return 0; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: auto selected item #%d.\n", this->side_index, n); _x_merge_mrl (this->item_mrl, HLS_MAX_MRL, this->list_mrl, this->list_buf + this->items.mrl[n]); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: trying %s.\n", this->side_index, this->item_mrl); if (!hls_input_switch_mrl (this)) return 0; strcpy (this->list_mrl, this->item_mrl); if ((this->side_index == 0) && this->items.ref[n] && (this->num_sides < 2)) { int all, group; uint32_t l; all = multirate_audio_autoselect (&cls->pref, this->items.pref, this->items.num); /* hide sound of wrong group from multirate_audio_autoselect (). */ for (l = 0; l < this->items.num; l++) { if ((this->items.pref[l].video_width | this->items.pref[l].video_height)) continue; if (this->items.group[l] && strcmp (this->list_buf + this->items.ref[n], this->list_buf + this->items.group[l])) this->items.pref[l].video_width = 1; } group = multirate_audio_autoselect (&cls->pref, this->items.pref, this->items.num); if (group < 0) group = all; if (group >= 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: auto selected separate audio #%d.\n", this->side_index, group); _x_merge_mrl (this->side_mrl[this->num_sides - 1], HLS_MAX_MRL, this->list_mrl, this->list_buf + this->items.mrl[group]); this->num_sides++; } } } if ((this->num_sides > 1) && !this->sync.init) { pthread_mutex_init (&this->sync.mutex, NULL); this->sync.init = 1; } if (try <= 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: too many redirections, giving up.\n", this->side_index); return 0; } { unsigned int d = hls_get_duration (this); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: got %u fragments for %u.%03u seconds.\n", this->side_index, (unsigned int)this->frag.num, d / 1000u, d % 1000u); } if (!strncasecmp (this->list_strtype, "VOD", 3) || ((this->frag.num >= 8) && (this->list_seq == 1))) { this->list_type = LIST_VOD; } else { if ((this->frag.num > 1) && hls_bump_guess (this, this->list_buf + this->frag.mrl_offs[1], this->list_buf + this->frag.mrl_offs[2])) { this->list_type = LIST_LIVE_BUMP; } else if ((this->frag.num > 0) && hls_bump_find (this, this->list_buf + this->frag.mrl_offs[1], this->list_strseq)) { this->list_type = LIST_LIVE_BUMP; } else { this->list_type = LIST_LIVE_REGET; } } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: %s mode @ seq %s.\n", this->side_index, type_names[this->list_type], this->list_strseq); do { if (this->list_rangeinit.len) { if (hls_input_open_item (this, 0)) break; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ".%u: WARNING: cannot get init fragment %s.\n", this->side_index, this->item_mrl); } if (this->list_type == LIST_LIVE_BUMP) { this->frag.current = 1; if (!hls_input_open_bump (this)) return 0; } else { if (!hls_input_open_item (this, 1)) return 0; } } while (0); hls_live_start (this); try = hls_input_read (&this->input_plugin, this->preview, sizeof (this->preview)); if (try > 0) { this->prev_size1 = this->prev_size2 = try; hls_input_seek (&this->input_plugin, 0, SEEK_SET); } return 1; } static input_plugin_t *hls_get_side (hls_input_plugin_t *this, int side_index) { hls_input_plugin_t *side_input; if (this->side_index) return NULL; if ((side_index < 1) || (side_index >= (int)this->num_sides)) return NULL; side_input = malloc (sizeof (*side_input)); if (!side_input) return NULL; /* clone everything */ *side_input = *this; /* sync */ if (this->sync.init) { pthread_mutex_lock (&this->sync.mutex); this->sync.refs++; pthread_mutex_unlock (&this->sync.mutex); } else { this->sync.refs++; } memset (&side_input->sync.mutex, 0, sizeof (side_input->sync.mutex)); side_input->sync.init = 0; side_input->sync.refs = 1; /* detach */ side_input->side_index = side_index; side_input->in1 = NULL; side_input->caps1 = 0; side_input->list_buf = NULL; side_input->list_bsize = 0; side_input->frag.input_offs = NULL; side_input->frag.mrl_offs = NULL; side_input->frag.pos = 0; side_input->frag.size = 0; side_input->frag.pts = 0; side_input->frag.num = 0; side_input->frag.current = 0; side_input->frag.list = NULL; xine_mfrag_list_open (&side_input->frag.list); side_input->pos = 0; side_input->list_seq = 1; side_input->prev_size1 = 0; side_input->prev_size2 = 0; side_input->items.num = 0; side_input->list_strtype = NULL; side_input->list_strseq = NULL; side_input->list_mrl[0] = 0; side_input->item_mrl[0] = 0; side_input->prev_item_mrl[0] = 0; side_input->stream = xine_get_side_stream (this->stream, side_index); if (!side_input->stream) { free (side_input->list_buf); free (side_input); return NULL; } side_input->nbc = xine_nbc_init (side_input->stream); return &side_input->input_plugin; } static int hls_input_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { hls_input_plugin_t *this = (hls_input_plugin_t *)this_gen; if (!this) return INPUT_OPTIONAL_UNSUPPORTED; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; { uint32_t s = this->prev_size1; if (s > MAX_PREVIEW_SIZE) s = MAX_PREVIEW_SIZE; if (!s) { if (this->in1) return this->in1->get_optional_data (this->in1, data, data_type); else return INPUT_OPTIONAL_UNSUPPORTED; } memcpy (data, this->preview, s); return s; } case INPUT_OPTIONAL_DATA_SIZED_PREVIEW: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; { int s; memcpy (&s, data, sizeof (s)); if (s < 0) return INPUT_OPTIONAL_UNSUPPORTED; if (s > (int)this->prev_size1) s = this->prev_size1; if (!s) { if (this->in1) return this->in1->get_optional_data (this->in1, data, data_type); else return INPUT_OPTIONAL_UNSUPPORTED; } memcpy (data, this->preview, s); return s; } case INPUT_OPTIONAL_DATA_DURATION: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; { int d = hls_get_duration (this); memcpy (data, &d, sizeof (d)); return INPUT_OPTIONAL_SUCCESS; } case INPUT_OPTIONAL_DATA_SIDE: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; { int side_index; input_plugin_t *side_input; memcpy (&side_index, data, sizeof (side_index)); side_input = hls_get_side (this, side_index); if (!side_input) return INPUT_OPTIONAL_UNSUPPORTED; memcpy (data, &side_input, sizeof (side_input)); } return INPUT_OPTIONAL_SUCCESS; case INPUT_OPTIONAL_DATA_FRAGLIST: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; { xine_mfrag_list_t *n = NULL; memcpy (data, this->list_type == LIST_VOD ? &this->frag.list : &n, sizeof (this->frag.list)); } return INPUT_OPTIONAL_SUCCESS; case INPUT_OPTIONAL_DATA_REWIND: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; memcpy (&this->rewind, data, sizeof (this->rewind)); return INPUT_OPTIONAL_SUCCESS; default: return INPUT_OPTIONAL_UNSUPPORTED; } } static input_plugin_t *hls_input_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { hls_input_class_t *cls = (hls_input_class_t *)cls_gen; hls_input_plugin_t *this; input_plugin_t *in1; char hbuf[8]; int n; lprintf("hls_input_get_instance\n"); do { n = 0; in1 = NULL; if (!strncasecmp (mrl, "hls:/", 5)) { n = 5; in1 = _x_find_input_plugin (stream, mrl + 5); } else if (hls_input_is_hls (mrl) == 2) in1 = _x_find_input_plugin (stream, mrl); if (in1) { if (in1->open (in1) > 0) { if (_x_demux_read_header (in1, hbuf, 8) == 8) { if (!strncmp (hbuf, "#EXTM3U", 7)) { this = calloc (1, sizeof (*this)); if (this) break; } } } _x_free_input_plugin (stream, in1); } return NULL; } while (0); #ifndef HAVE_ZERO_SAFE_MEM this->side_index = 0; this->sync.lag = 0; this->sync.type = 0; this->sync.init = 0; this->caps1 = 0; this->last_err = 0; this->frag.list = NULL; this->frag.input_offs = NULL; this->frag.size = 0; this->frag.mrl_offs = NULL; this->frag.num = 0; this->list_buf = NULL; this->list_bsize = 0; this->items.num = 0; this->prev_size1 = 0; this->prev_size2 = 0; this->frag_dur.tv_sec = 0; this->frag_dur.tv_nsec = 0; this->next_stop.tv_sec = 0; this->next_stop.tv_nsec = 0; this->rewind = 0; this->prev_item_mrl[0] = 0; this->side_mrl[0][0] = 0; #endif this->stream = stream; this->in1 = in1; this->main_input = this; this->num_sides = 1; this->frag.current = HLS_NO_FRAGMENT; /* TJ. yes input_http already does this, but i want to test offline * with a file based service. */ this->nbc = xine_nbc_init (this->stream); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ".%u: %s.\n", this->side_index, mrl + n); strlcpy (this->list_mrl, mrl + n, HLS_MAX_MRL); this->input_plugin.open = hls_input_open; this->input_plugin.get_capabilities = hls_input_get_capabilities; this->input_plugin.read = hls_input_read; this->input_plugin.read_block = hls_input_read_block; this->input_plugin.seek = hls_input_seek; this->input_plugin.seek_time = hls_input_time_seek; this->input_plugin.get_current_pos = hls_input_get_current_pos; this->input_plugin.get_length = hls_input_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = hls_input_get_mrl; this->input_plugin.get_optional_data = hls_input_get_optional_data; this->input_plugin.dispose = hls_input_dispose; this->input_plugin.input_class = &cls->input_class; return &this->input_plugin; } /* * plugin class functions */ static void hls_input_class_dispose (input_class_t *this_gen) { hls_input_class_t *this = (hls_input_class_t *)this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free (this); } void *input_hls_init_class (xine_t *xine, const void *data) { hls_input_class_t *this; (void)data; this = calloc (1, sizeof (*this)); if (!this) return NULL; this->xine = xine; multirate_pref_get (xine->config, &this->pref); this->input_class.get_instance = hls_input_get_instance; this->input_class.identifier = "hls"; this->input_class.description = N_("HTTP live streaming input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = hls_input_class_dispose; this->input_class.eject_media = NULL; return this; } xine-lib-1.2/src/input/Makefile.am0000644000175000017500000001766114647725152014661 0ustar memeAUTOMAKE_OPTIONS = subdir-objects include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common # REVISIT: This second line here bothers me more than just a little bit AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) ## # IMPORTANT: # --------- # All of xine input plugins should be named like the scheme "xineplug_inp_" # SUBDIRS = if !WITH_EXTERNAL_DVDNAV SUBDIRS += libdvdnav endif # # helper libs # noinst_LTLIBRARIES = \ http_helper.la \ input_helper.la \ media_helper.la \ xine_tls.la http_helper_la_SOURCES = http_helper.c http_helper.h http_helper_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) input_helper_la_SOURCES = input_helper.c input_helper.h input_helper_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) media_helper_la_SOURCES = media_helper.c media_helper.h media_helper_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xine_tls_la_SOURCES = tls/xine_tls.c tls/xine_tls.h tls/xine_tls_plugin.h xine_tls_la_CFLAGS = $(AM_CFLAGS) xine_tls_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) # # # noinst_LTLIBRARIES += \ librtsp.la \ libreal.la noinst_HEADERS = net_buf_ctrl.h EXTRA_DIST = multirate_pref.c librtsp_la_SOURCES = \ librtsp/rtsp.c \ librtsp/rtsp.h \ librtsp/rtsp_session.c \ librtsp/rtsp_session.h librtsp_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/input/libreal -I$(top_srcdir)/src/input/librtsp libreal_la_SOURCES = \ libreal/real.h \ libreal/real.c \ libreal/asmrp.h \ libreal/asmrp.c \ libreal/rmff.h \ libreal/rmff.c \ libreal/sdpplin.h \ libreal/sdpplin.c libreal_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/input/librtsp -I$(top_srcdir)/src/input/libreal # # external libs # ASFHEADER_LIB = $(top_builddir)/src/demuxers/libasfheader.la $(ASFHEADER_LIB): $(MAKE) -C $(top_builddir)/src/demuxers libasfheader.la # # plugins # if !ENABLE_LIBXINE_BUILTINS in_builtins = xineplug_inp_file.la xineplug_inp_stdin_fifo.la xineplug_inp_test.la endif if ENABLE_DVB in_dvb = xineplug_inp_dvb.la endif if ENABLE_VCD in_vcd = xineplug_inp_vcd.la endif if ENABLE_VCDO in_vcdo = xineplug_inp_vcdo.la endif if ENABLE_V4L in_v4l = xineplug_inp_v4l.la endif if ENABLE_V4L2 in_v4l2 = xineplug_inp_v4l2.la in_pvr = xineplug_inp_pvr.la endif if ENABLE_GNOME_VFS in_gnome_vfs = xineplug_inp_gnome_vfs.la endif if ENABLE_LIBSMBCLIENT in_smb = xineplug_inp_smb.la endif if ENABLE_SSH in_ssh = xineplug_inp_ssh.la endif if ENABLE_NFS in_nfs = xineplug_inp_nfs.la endif if ENABLE_DVD in_dvd = xineplug_inp_dvd.la endif if ENABLE_MMS in_mms = xineplug_inp_mms.la endif if ENABLE_CRYPTO in_crypto = xineplug_inp_crypto.la endif if WITH_EXTERNAL_DVDNAV DVD_CFLAGS = $(DVDNAV_CFLAGS) $(DVDREAD_CFLAGS) link_dvdnav = $(DVDNAV_LIBS) $(DVDREAD_LIBS) else DVD_CFLAGS = -I$(top_srcdir)/src/input/libdvdnav link_dvdnav = libdvdnav/libdvdnav.la $(link_dvdnav): $(MAKE) -C libdvdnav libdvdnav.la endif # not ported to native Windows if !WIN32 in_rtp = xineplug_inp_rtp.la endif if ENABLE_BLURAY in_bluray = xineplug_inp_bluray.la endif if ENABLE_GNUTLS in_tls_gnutls = xineplug_tls_gnutls.la endif if ENABLE_OPENSSL in_tls_openssl = xineplug_tls_openssl.la endif xineplug_LTLIBRARIES = \ $(in_builtins) \ $(in_tls_gnutls) \ $(in_tls_openssl) \ $(in_dvd) \ $(in_vcd) \ $(in_vcdo) \ $(in_v4l) \ $(in_v4l2) \ $(in_gnome_vfs) \ $(in_nfs) \ $(in_smb) \ $(in_ssh) \ $(in_mms) \ $(in_rtp) \ xineplug_inp_network.la \ $(in_pvr) \ $(in_dvb) \ $(in_bluray) \ $(in_crypto) \ xineplug_inp_cdda.la xineplug_inp_file_la_SOURCES = input_file.c xineplug_inp_file_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) input_helper.la xineplug_inp_test_la_SOURCES = input_test.c xineplug_inp_test_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) input_helper.la xineplug_inp_dvd_la_SOURCES = input_dvd.c xineplug_inp_dvd_la_LIBADD = $(XINE_LIB) $(link_dvdnav) $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) media_helper.la xineplug_inp_dvd_la_CFLAGS = $(AM_CFLAGS) $(DVD_CFLAGS) xineplug_inp_network_la_SOURCES = \ group_network.c \ group_network.h \ input_ftp.c \ input_http.c \ input_net.c \ input_pnm.c \ input_rtsp.c \ input_hls.c \ input_mpegdash.c \ pnm.c \ pnm.h xineplug_inp_network_la_CPPFLAGS = $(AM_CPPFLAGS) $(ZLIB_CPPFLAGS) xineplug_inp_network_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(LTLIBINTL) $(ZLIB_LIBS) \ libreal.la librtsp.la http_helper.la input_helper.la xine_tls.la xineplug_inp_rtp_la_SOURCES = input_rtp.c xineplug_inp_rtp_la_LIBADD = $(XINE_LIB) $(NET_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) input_helper.la xineplug_inp_mms_la_SOURCES = input_mms.c mms.c mms.h mmsh.c mmsh.h xineplug_inp_mms_la_LIBADD = $(XINE_LIB) $(LTLIBICONV) $(LTLIBINTL) $(ASFHEADER_LIB) http_helper.la input_helper.la xineplug_inp_vcd_la_SOURCES = vcd/xineplug_inp_vcd.c vcd/vcdplayer.c vcd/vcdplayer.h vcd/vcdio.c vcd/vcdio.h xineplug_inp_vcd_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(LIBCDIO_LIBS) $(LIBVCD_LIBS) $(LIBVCDINFO_LIBS) $(LIBISO9660_LIBS) -lm xineplug_inp_vcd_la_DEPENDENCIES = $(LIBCDIO_DEPS) $(LIBVCD_DEPS) $(LIBVCDINFO_DEPS) $(LIBISO9660_DEPS) xineplug_inp_vcd_la_CFLAGS = $(AM_CFLAGS) $(LIBCDIO_CFLAGS) $(LIBVCD_CFLAGS) xineplug_inp_vcdo_la_SOURCES = input_vcd.c xineplug_inp_vcdo_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) media_helper.la input_helper.la xineplug_inp_stdin_fifo_la_SOURCES = input_stdin_fifo.c xineplug_inp_stdin_fifo_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) input_helper.la xineplug_inp_dvb_la_SOURCES = input_dvb.c xineplug_inp_dvb_la_DEPS = $(XDG_BASEDIR_DEPS) xineplug_inp_dvb_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) $(XDG_BASEDIR_LIBS) input_helper.la xineplug_inp_dvb_la_CPPFLAGS = $(AM_CPPFLAGS) $(XDG_BASEDIR_CPPFLAGS) xineplug_inp_cdda_la_SOURCES = input_cdda.c xineplug_inp_cdda_la_DEPS = $(XDG_BASEDIR_DEPS) xineplug_inp_cdda_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(XDG_BASEDIR_LIBS) $(PTHREAD_LIBS) media_helper.la xineplug_inp_cdda_la_CPPFLAGS = $(AM_CPPFLAGS) $(XDG_BASEDIR_CPPFLAGS) xineplug_inp_v4l_la_SOURCES = input_v4l.c xineplug_inp_v4l_la_LIBADD = $(XINE_LIB) $(ALSA_LIBS) $(LTLIBINTL) xineplug_inp_v4l_la_CFLAGS = $(AM_CFLAGS) $(ALSA_CFLAGS) xineplug_inp_v4l2_la_SOURCES = input_v4l2.c xineplug_inp_v4l2_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(V4L2_LIBS) xineplug_inp_v4l2_la_CFLAGS = $(AM_CFLAGS) $(V4L2_CFLAGS) xineplug_inp_gnome_vfs_la_SOURCES = input_gnome_vfs.c xineplug_inp_gnome_vfs_la_LIBADD = $(XINE_LIB) $(GNOME_VFS_LIBS) $(LTLIBINTL) xineplug_inp_gnome_vfs_la_CFLAGS = $(AM_CFLAGS) $(GNOME_VFS_CFLAGS) xineplug_inp_smb_la_SOURCES = input_smb.c xineplug_inp_smb_la_LIBADD = $(XINE_LIB) $(LIBSMBCLIENT_LIBS) $(LTLIBINTL) xineplug_inp_smb_la_CFLAGS = $(AM_CFLAGS) $(LIBSMBCLIENT_CFLAGS) xineplug_inp_pvr_la_SOURCES = input_pvr.c xineplug_inp_pvr_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_inp_bluray_la_SOURCES = input_bluray.c xineplug_inp_bluray_la_LIBADD = $(XINE_LIB) $(LIBBLURAY_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) media_helper.la input_helper.la xineplug_inp_bluray_la_CFLAGS = $(AM_CFLAGS) $(LIBBLURAY_CFLAGS) xineplug_inp_nfs_la_SOURCES = input_nfs.c xineplug_inp_nfs_la_LIBADD = $(XINE_LIB) $(LIBNFS_LIBS) $(LTLIBINTL) input_helper.la xineplug_inp_nfs_la_CFLAGS = $(AM_CFLAGS) $(LIBNFS_CFLAGS) xineplug_inp_ssh_la_SOURCES = input_ssh.c xineplug_inp_ssh_la_LIBADD = $(XINE_LIB) $(LIBSSH2_LIBS) $(LTLIBINTL) http_helper.la input_helper.la xineplug_inp_ssh_la_CFLAGS = $(AM_CFLAGS) $(LIBSSH2_CFLAGS) xineplug_inp_crypto_la_SOURCES = input_crypto.c xineplug_inp_crypto_la_LIBADD = $(XINE_LIB) $(GCRYPT_LIBS) $(LTLIBINTL) input_helper.la xineplug_inp_crypto_la_CFLAGS = $(AM_CFLAGS) $(GCRYPT_CFLAGS) # TLS provider plugins xineplug_tls_gnutls_la_SOURCES = tls/tls_gnutls.c tls/xine_tls_plugin.h xineplug_tls_gnutls_la_CFLAGS = $(AM_CFLAGS) $(GNUTLS_CFLAGS) xineplug_tls_gnutls_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(GNUTLS_LIBS) xineplug_tls_openssl_la_SOURCES = tls/tls_openssl.c tls/xine_tls_plugin.h xineplug_tls_openssl_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) xineplug_tls_openssl_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(OPENSSL_LIBS) xine-lib-1.2/src/input/input_cdda.c0000644000175000017500000023611214647725152015075 0ustar meme/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Compact Disc Digital Audio (CDDA) Input Plugin * by Mike Melanson (melanson@pcisys.net) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_DIRENT_H #include #endif #include #include #include #ifdef HAVE_ALLOCA_H # include #endif #ifdef HAVE_SYS_IOCTL_H # include #endif #ifdef WIN32 # include # include # include #endif #ifdef HAVE_NETDB_H #include #endif #include #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #include #define LOG_MODULE "input_cdda" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "../xine-engine/bswap.h" #include "media_helper.h" #if defined(__sun) #define DEFAULT_CDDA_DEVICE "/vol/dev/aliases/cdrom0" #elif defined(WIN32) #define DEFAULT_CDDA_DEVICE "d:\\" #elif defined(__OpenBSD__) #define DEFAULT_CDDA_DEVICE "/dev/rcd0c" #else #define DEFAULT_CDDA_DEVICE "/dev/cdrom" #endif #define CDDB_SERVER "gnudb.gnudb.org" #define CDDB_PORT 8880 #define CDDB_PROTOCOL 6 #define CDDB_TIMEOUT 5000 /* CD-relevant defines and data structures */ #define CD_SECONDS_PER_MINUTE 60 #define CD_FRAMES_PER_SECOND 75 #define CD_RAW_FRAME_SIZE 2352 #define CD_LEADOUT_TRACK 0xAA #define CD_BLOCK_OFFSET 150 typedef struct { int track_mode; int first_frame; int first_frame_minute; int first_frame_second; int first_frame_frame; int total_frames; } cdrom_toc_entry_t; typedef struct { int first_track; int last_track; int total_tracks; int ignore_last_track; /* really: first_track, ... , last_track, leadout_track. */ cdrom_toc_entry_t toc_entries[1]; } cdrom_toc_t; /* * Quick and dirty sha160 implementation. * We only will hash a few bytes per disc, so there is * no need for high end optimization. */ #define sha160_digest_len 20 typedef struct { uint8_t buf[64]; uint32_t state[5]; uint32_t n; } sha160_t; static void sha160_init (sha160_t *s) { s->state[0] = 0x67452301; s->state[1] = 0xefcdab89; s->state[2] = 0x98badcfe; s->state[3] = 0x10325476; s->state[4] = 0xc3d2e1f0; s->n = 0; } static void sha160_trans (sha160_t *s) { uint32_t l[80], a, b, c, d, e, i; a = s->state[0]; b = s->state[1]; c = s->state[2]; d = s->state[3]; e = s->state[4]; for (i = 0; i < 16; i++) { uint32_t t; l[i] = t = _X_BE_32 (s->buf + i * 4); t += e + ((a << 5) | (a >> 27)); t += ((b & (c ^ d)) ^ d) + 0x5a827999; e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = t; } for (; i < 20; i++) { uint32_t t; t = l[i - 3] ^ l[i - 8] ^ l[i - 14] ^ l[i - 16]; l[i] = t = (t << 1) | (t >> 31); t += e + ((a << 5) | (a >> 27)); t += ((b & (c ^ d)) ^ d) + 0x5a827999; e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = t; } for (; i < 40; i++) { uint32_t t; t = l[i - 3] ^ l[i - 8] ^ l[i - 14] ^ l[i - 16]; l[i] = t = (t << 1) | (t >> 31); t += e + ((a << 5) | (a >> 27)); t += (b ^ c ^ d) + 0x6ed9eba1; e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = t; } for (; i < 60; i++) { uint32_t t; t = l[i - 3] ^ l[i - 8] ^ l[i - 14] ^ l[i - 16]; l[i] = t = (t << 1) | (t >> 31); t += e + ((a << 5) | (a >> 27)); t += (((b | c) & d) | (b & c)) + 0x8f1bbcdc; e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = t; } for (; i < 80; i++) { uint32_t t; t = l[i - 3] ^ l[i - 8] ^ l[i - 14] ^ l[i - 16]; l[i] = t = (t << 1) | (t >> 31); t += e + ((a << 5) | (a >> 27)); t += (b ^ c ^ d) + 0xca62c1d6; e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = t; } s->state[0] += a; s->state[1] += b; s->state[2] += c; s->state[3] += d; s->state[4] += e; } static void sha160_update (sha160_t *s, const uint8_t *data, size_t len) { while (len) { size_t part = 64 - (s->n & 63); if (part > len) part = len; memcpy (s->buf + (s->n & 63), data, part); data += part; s->n += part; if (!(s->n & 63)) sha160_trans (s); len -= part; } } static void sha160_final (sha160_t *s, uint8_t *dest) { uint32_t p = s->n & 63; s->buf[p++] = 128; if (p == 64) { sha160_trans (s); p = 0; } memset (s->buf + p, 0, 64 - p); if (p >= 57) { sha160_trans (s); p = 0; memset (s->buf, 0, 64); } p = s->n << 3; s->buf[60] = p >> 24; s->buf[61] = p >> 16; s->buf[62] = p >> 8; s->buf[63] = p; sha160_trans (s); for (p = 0; p < 5; p++) { uint32_t v = s->state[p]; dest[4 * p] = v >> 24; dest[4 * p + 1] = v >> 16; dest[4 * p + 2] = v >> 8; dest[4 * p + 3] = v; } } /************************************************************************** * xine interface functions *************************************************************************/ #define MAX_TRACKS 99 #define CACHED_FRAMES 90 /* be a multiple of 3, see read_block () */ typedef struct { int start; char *title; } trackinfo_t; typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; struct { char *cdiscid; char *disc_title; char *disc_year; char *disc_artist; char *disc_category; int fd; uint32_t disc_id; int disc_length; trackinfo_t *track; int num_tracks; int have_cddb_info; } cddb; int fd; int net_fd; int track; char *mrl; int first_frame; int current_frame; int last_frame; char *device; unsigned char cache[CACHED_FRAMES][CD_RAW_FRAME_SIZE]; int cache_first; int cache_last; int tripple; time_t last_read_time; #ifdef WIN32 HANDLE h_device_handle; /* vcd device descriptor */ HMODULE hASPI; /* wnaspi32.dll */ short i_sid; long (*lpSendCommand)( void* ); #endif } cdda_input_plugin_t; typedef struct { input_class_t input_class; xine_t *xine; config_values_t *config; pthread_mutex_t mutex; time_t last_read_time; cdrom_toc_t *last_toc; const char *cdda_device; int speed; const char *cddb_server; int cddb_port; int cddb_error; int cddb_enable; char **autoplaylist; } cdda_input_class_t; #ifdef WIN32 /* size of a CD sector */ #define CD_SECTOR_SIZE 2048 /* Win32 DeviceIoControl specifics */ typedef struct _TRACK_DATA { UCHAR Reserved; UCHAR Control : 4; UCHAR Adr : 4; UCHAR TrackNumber; UCHAR Reserved1; UCHAR Address[4]; } TRACK_DATA, *PTRACK_DATA; typedef struct _CDROM_TOC { UCHAR Length[2]; UCHAR FirstTrack; UCHAR LastTrack; TRACK_DATA TrackData[MAX_TRACKS+1]; } CDROM_TOC, *PCDROM_TOC; typedef enum _TRACK_MODE_TYPE { YellowMode2, XAForm2, CDDA } TRACK_MODE_TYPE, *PTRACK_MODE_TYPE; typedef struct __RAW_READ_INFO { LARGE_INTEGER DiskOffset; ULONG SectorCount; TRACK_MODE_TYPE TrackMode; } RAW_READ_INFO, *PRAW_READ_INFO; #ifndef IOCTL_CDROM_BASE # define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM #endif #ifndef IOCTL_CDROM_READ_TOC # define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, \ METHOD_BUFFERED, FILE_READ_ACCESS) #endif #ifndef IOCTL_CDROM_RAW_READ #define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, \ METHOD_OUT_DIRECT, FILE_READ_ACCESS) #endif /* Win32 aspi specific */ #define WIN_NT ( GetVersion() < 0x80000000 ) #define ASPI_HAID 0 #define ASPI_TARGET 0 #define DTYPE_CDROM 0x05 #define SENSE_LEN 0x0E #define SC_GET_DEV_TYPE 0x01 #define SC_EXEC_SCSI_CMD 0x02 #define SC_GET_DISK_INFO 0x06 #define SS_COMP 0x01 #define SS_PENDING 0x00 #define SS_NO_ADAPTERS 0xE8 #define SRB_DIR_IN 0x08 #define SRB_DIR_OUT 0x10 #define SRB_EVENT_NOTIFY 0x40 #define READ_CD 0xbe #define SECTOR_TYPE_MODE2 0x14 #define READ_CD_USERDATA_MODE2 0x10 #define READ_TOC 0x43 #define READ_TOC_FORMAT_TOC 0x0 #pragma pack(1) struct SRB_GetDiskInfo { unsigned char SRB_Cmd; unsigned char SRB_Status; unsigned char SRB_HaId; unsigned char SRB_Flags; unsigned long SRB_Hdr_Rsvd; unsigned char SRB_Target; unsigned char SRB_Lun; unsigned char SRB_DriveFlags; unsigned char SRB_Int13HDriveInfo; unsigned char SRB_Heads; unsigned char SRB_Sectors; unsigned char SRB_Rsvd1[22]; }; struct SRB_GDEVBlock { unsigned char SRB_Cmd; unsigned char SRB_Status; unsigned char SRB_HaId; unsigned char SRB_Flags; unsigned long SRB_Hdr_Rsvd; unsigned char SRB_Target; unsigned char SRB_Lun; unsigned char SRB_DeviceType; unsigned char SRB_Rsvd1; }; struct SRB_ExecSCSICmd { unsigned char SRB_Cmd; unsigned char SRB_Status; unsigned char SRB_HaId; unsigned char SRB_Flags; unsigned long SRB_Hdr_Rsvd; unsigned char SRB_Target; unsigned char SRB_Lun; unsigned short SRB_Rsvd1; unsigned long SRB_BufLen; unsigned char *SRB_BufPointer; unsigned char SRB_SenseLen; unsigned char SRB_CDBLen; unsigned char SRB_HaStat; unsigned char SRB_TargStat; unsigned long *SRB_PostProc; unsigned char SRB_Rsvd2[20]; unsigned char CDBByte[16]; unsigned char SenseArea[SENSE_LEN+2]; }; #pragma pack() #endif /* WIN32 */ static void print_cdrom_toc (xine_t *xine, cdrom_toc_t *toc) { cdrom_toc_entry_t *e; if (xine->verbosity < XINE_VERBOSITY_DEBUG) return; e = &toc->toc_entries[0]; xprintf (xine, XINE_VERBOSITY_DEBUG, "input_cdda: toc: first_track = %d, last_track = %d, total_tracks = %d.\n", toc->first_track, toc->last_track, toc->total_tracks); /* fetch each toc entry */ if (toc->first_track > 0) { int i; xprintf (xine, XINE_VERBOSITY_DEBUG, "input_cdda: track mode MSF time first_frame\n"); for (i = 0; i < toc->total_tracks; i++) { int time1, time2, timediff; time1 = e[i].first_frame_minute * 60 + e[i].first_frame_second; time2 = e[i + 1].first_frame_minute * 60 + e[i + 1].first_frame_second; timediff = time2 - time1; xprintf (xine, XINE_VERBOSITY_DEBUG, "input_cdda: %5d %4d %02d:%02d:%02d %02d:%02d %11d\n", toc->first_track + i, e[i].track_mode, e[i].first_frame_minute, e[i].first_frame_second, e[i].first_frame_frame, timediff / 60, timediff % 60, e[i].first_frame); } xprintf (xine, XINE_VERBOSITY_DEBUG, "input_cdda: leadout%4d %02d:%02d:%02d %11d\n", e[i].track_mode, e[i].first_frame_minute, e[i].first_frame_second, e[i].first_frame_frame, e[i].first_frame); } } static void free_cdrom_toc(cdrom_toc_t *toc) { free (toc); } #if defined (__linux__) #include static cdrom_toc_t *read_cdrom_toc (int fd) { cdrom_toc_t *toc; struct cdrom_tochdr tochdr; struct cdrom_tocentry tocentry; struct cdrom_multisession ms; int i, first_track, last_track, total_tracks, ignore_last_track; /* fetch the table of contents */ if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1) { perror("CDROMREADTOCHDR"); return NULL; } ms.addr_format = CDROM_LBA; if (ioctl(fd, CDROMMULTISESSION, &ms) == -1) { perror("CDROMMULTISESSION"); return NULL; } first_track = tochdr.cdth_trk0; last_track = tochdr.cdth_trk1; if (last_track > first_track + MAX_TRACKS - 1) last_track = first_track + MAX_TRACKS - 1; total_tracks = last_track - first_track + 1; ignore_last_track = ms.xa_flag ? 1 : 0; /* allocate space for the toc entries */ toc = calloc (1, sizeof (cdrom_toc_t) + total_tracks * sizeof (cdrom_toc_entry_t)); if (!toc) { perror("calloc"); return NULL; } toc->first_track = first_track; toc->last_track = last_track; toc->total_tracks = total_tracks; toc->ignore_last_track = ignore_last_track; /* fetch each toc entry */ for (i = 0; i < toc->total_tracks; i++) { memset(&tocentry, 0, sizeof(tocentry)); tocentry.cdte_track = toc->first_track + i; tocentry.cdte_format = CDROM_MSF; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) == -1) { perror("CDROMREADTOCENTRY"); break; } toc->toc_entries[i].track_mode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.cdte_addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.cdte_addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.cdte_addr.msf.frame; toc->toc_entries[i].first_frame = (tocentry.cdte_addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.cdte_addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.cdte_addr.msf.frame; } /* fetch the leadout as well */ memset(&tocentry, 0, sizeof(tocentry)); tocentry.cdte_track = CD_LEADOUT_TRACK; tocentry.cdte_format = CDROM_MSF; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) == -1) { perror("CDROMREADTOCENTRY"); free (toc); return NULL; } #define XA_INTERVAL ((60 + 90 + 2) * CD_FRAMES) toc->toc_entries[i].track_mode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.cdte_addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.cdte_addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.cdte_addr.msf.frame; if (!ms.xa_flag) { toc->toc_entries[i].first_frame = (tocentry.cdte_addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.cdte_addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.cdte_addr.msf.frame; } else { toc->toc_entries[i].first_frame = ms.addr.lba - XA_INTERVAL + 150; } return toc; } static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { int fd = this_gen->fd; struct cdrom_msf msf; while( num_frames ) { /* read from starting frame... */ msf.cdmsf_min0 = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND; msf.cdmsf_sec0 = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE; msf.cdmsf_frame0 = frame % CD_FRAMES_PER_SECOND; /* read until ending track (starting frame + 1)... */ msf.cdmsf_min1 = (frame + 1) / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND; msf.cdmsf_sec1 = ((frame + 1) / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE; msf.cdmsf_frame1 = (frame + 1) % CD_FRAMES_PER_SECOND; /* MSF structure is the input to the ioctl */ memcpy(data, &msf, sizeof(msf)); /* read a frame */ if(ioctl(fd, CDROMREADRAW, data, data) < 0) { perror("CDROMREADRAW"); return -1; } data += CD_RAW_FRAME_SIZE; frame++; num_frames--; } return 0; } #elif defined(__sun) #include static cdrom_toc_t *read_cdrom_toc (int fd) { cdrom_toc_t *toc; struct cdrom_tochdr tochdr; struct cdrom_tocentry tocentry; int i, first_track, last_track, total_tracks; /* fetch the table of contents */ if (ioctl(fd, CDROMREADTOCHDR, &tochdr) == -1) { perror("CDROMREADTOCHDR"); return NULL; } first_track = tochdr.cdth_trk0; last_track = tochdr.cdth_trk1; if (last_track > first_track + MAX_TRACKS - 1) last_track = first_track + MAX_TRACKS - 1; total_tracks = last_track - first_track + 1; /* allocate space for the toc entries */ toc = calloc (1, sizeof (cdrom_toc_t) + total_tracks * sizeof (cdrom_toc_entry_t)); if (!toc) { perror("calloc"); return NULL; } toc->first_track = first_track; toc->last_track = last_track; toc->total_tracks = total_tracks; /* fetch each toc entry */ for (i = 0; i < toc->total_tracks; i++) { memset(&tocentry, 0, sizeof(tocentry)); tocentry.cdte_track = toc->first_track + i; tocentry.cdte_format = CDROM_MSF; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) == -1) { perror("CDROMREADTOCENTRY"); free (toc); return NULL; } toc->toc_entries[i].track_mode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.cdte_addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.cdte_addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.cdte_addr.msf.frame; toc->toc_entries[i].first_frame = (tocentry.cdte_addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.cdte_addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.cdte_addr.msf.frame; } if (tocentry.cdte_ctrl & CDROM_DATA_TRACK) { toc->ignore_last_track = 1; } else { toc->ignore_last_track = 0; } /* fetch the leadout as well */ memset(&tocentry, 0, sizeof(tocentry)); tocentry.cdte_track = CD_LEADOUT_TRACK; tocentry.cdte_format = CDROM_MSF; if (ioctl(fd, CDROMREADTOCENTRY, &tocentry) == -1) { perror("CDROMREADTOCENTRY"); free (toc); return NULL; } toc->toc_entries[i].track_mode = (tocentry.cdte_ctrl & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.cdte_addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.cdte_addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.cdte_addr.msf.frame; toc->toc_entries[i].first_frame = (tocentry.cdte_addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.cdte_addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.cdte_addr.msf.frame; return toc; } static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { int fd = this_gen->fd; struct cdrom_cdda cdda; while( num_frames ) { cdda.cdda_addr = frame - 2 * CD_FRAMES_PER_SECOND; cdda.cdda_length = 1; cdda.cdda_data = data; cdda.cdda_subcode = CDROM_DA_NO_SUBCODE; /* read a frame */ if(ioctl(fd, CDROMCDDA, &cdda) < 0) { perror("CDROMCDDA"); return -1; } data += CD_RAW_FRAME_SIZE; frame++; num_frames--; } return 0; } #elif defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) #include #ifdef HAVE_SYS_SCSIIO_H #include #endif static cdrom_toc_t *read_cdrom_toc (int fd) { cdrom_toc_t *toc; struct ioc_toc_header tochdr; #if defined(__FreeBSD_kernel__) struct ioc_read_toc_single_entry tocentry; #elif defined(__NetBSD__) || defined(__OpenBSD__) struct ioc_read_toc_entry tocentry; struct cd_toc_entry data; #endif int i, first_track, last_track, total_tracks; /* fetch the table of contents */ if (ioctl(fd, CDIOREADTOCHEADER, &tochdr) == -1) { perror("CDIOREADTOCHEADER"); return NULL; } first_track = tochdr.starting_track; last_track = tochdr.ending_track; if (last_track > first_track + MAX_TRACKS - 1) last_track = first_track + MAX_TRACKS - 1; total_tracks = last_track - first_track + 1; /* allocate space for the toc entries */ toc = calloc (1, sizeof (cdrom_toc_t) + total_tracks * sizeof (cdrom_toc_entry_t)); if (!toc) { perror("calloc"); return NULL; } toc->first_track = first_track; toc->last_track = last_track; toc->total_tracks = total_tracks; /* fetch each toc entry */ for (i = 0; i < toc->total_tracks; i++) { memset(&tocentry, 0, sizeof(tocentry)); #if defined(__FreeBSD_kernel__) tocentry.track = toc->first_track + i; tocentry.address_format = CD_MSF_FORMAT; if (ioctl(fd, CDIOREADTOCENTRY, &tocentry) == -1) { perror("CDIOREADTOCENTRY"); free (toc); return NULL; } #elif defined(__NetBSD__) || defined(__OpenBSD__) memset(&data, 0, sizeof(data)); tocentry.data_len = sizeof(data); tocentry.data = &data; tocentry.starting_track = toc->first_track + i; tocentry.address_format = CD_MSF_FORMAT; if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) { perror("CDIOREADTOCENTRYS"); free (toc); return NULL; } #endif #if defined(__FreeBSD_kernel__) toc->toc_entries[i].track_mode = (tocentry.entry.control & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.entry.addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.entry.addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.entry.addr.msf.frame; toc->toc_entries[i].first_frame = (tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.entry.addr.msf.frame; #elif defined(__NetBSD__) || defined(__OpenBSD__) toc->toc_entries[i].track_mode = (tocentry.data->control & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.data->addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.data->addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.data->addr.msf.frame; toc->toc_entries[i].first_frame = (tocentry.data->addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.data->addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.data->addr.msf.frame - CD_BLOCK_OFFSET; #endif } /* fetch the leadout as well */ memset(&tocentry, 0, sizeof(tocentry)); #if defined(__FreeBSD_kernel__) tocentry.track = CD_LEADOUT_TRACK; tocentry.address_format = CD_MSF_FORMAT; if (ioctl(fd, CDIOREADTOCENTRY, &tocentry) == -1) { perror("CDIOREADTOCENTRY"); free (toc); return NULL; } #elif defined(__NetBSD__) || defined(__OpenBSD__) memset(&data, 0, sizeof(data)); tocentry.data_len = sizeof(data); tocentry.data = &data; tocentry.starting_track = CD_LEADOUT_TRACK; tocentry.address_format = CD_MSF_FORMAT; if (ioctl(fd, CDIOREADTOCENTRYS, &tocentry) == -1) { perror("CDIOREADTOCENTRYS"); free (toc); return NULL; } #endif #if defined(__FreeBSD_kernel__) toc->toc_entries[i].track_mode = (tocentry.entry.control & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.entry.addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.entry.addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.entry.addr.msf.frame; toc->toc_entries[i].first_frame = (tocentry.entry.addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.entry.addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.entry.addr.msf.frame; #elif defined(__NetBSD__) || defined(__OpenBSD__) toc->toc_entries[i].track_mode = (tocentry.data->control & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = tocentry.data->addr.msf.minute; toc->toc_entries[i].first_frame_second = tocentry.data->addr.msf.second; toc->toc_entries[i].first_frame_frame = tocentry.data->addr.msf.frame; toc->toc_entries[i].first_frame = (tocentry.data->addr.msf.minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (tocentry.data->addr.msf.second * CD_FRAMES_PER_SECOND) + tocentry.data->addr.msf.frame - CD_BLOCK_OFFSET; #endif return toc; } static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { int fd = this_gen->fd; while( num_frames ) { #if defined(__FreeBSD_kernel__) #if __FreeBSD_kernel_version < 501106 struct ioc_read_audio cdda; cdda.address_format = CD_MSF_FORMAT; cdda.address.msf.minute = frame / CD_SECONDS_PER_MINUTE / CD_FRAMES_PER_SECOND; cdda.address.msf.second = (frame / CD_FRAMES_PER_SECOND) % CD_SECONDS_PER_MINUTE; cdda.address.msf.frame = frame % CD_FRAMES_PER_SECOND; cdda.nframes = 1; cdda.buffer = data; /* read a frame */ if (ioctl(fd, CDIOCREADAUDIO, &cdda) < 0) #else if (pread (fd, data, CD_RAW_FRAME_SIZE, frame * CD_RAW_FRAME_SIZE) != CD_RAW_FRAME_SIZE) #endif { perror("CDIOCREADAUDIO"); return -1; } #elif defined(__NetBSD__) || defined(__OpenBSD__) scsireq_t req; int nblocks = 1; memset(&req, 0, sizeof(req)); req.cmd[0] = 0xbe; req.cmd[1] = 0; req.cmd[2] = (frame >> 24) & 0xff; req.cmd[3] = (frame >> 16) & 0xff; req.cmd[4] = (frame >> 8) & 0xff; req.cmd[5] = (frame >> 0) & 0xff; req.cmd[6] = (nblocks >> 16) & 0xff; req.cmd[7] = (nblocks >> 8) & 0xff; req.cmd[8] = (nblocks >> 0) & 0xff; req.cmd[9] = 0x78; req.cmdlen = 10; req.datalen = nblocks * CD_RAW_FRAME_SIZE; req.databuf = data; req.timeout = 10000; req.flags = SCCMD_READ; if(ioctl(fd, SCIOCCOMMAND, &req) < 0) { perror("SCIOCCOMMAND"); return -1; } #endif data += CD_RAW_FRAME_SIZE; frame++; num_frames--; } return 0; } #elif defined(WIN32) static cdrom_toc_t *read_cdrom_toc (cdda_input_plugin_t *this_gen) { if( this_gen->hASPI ) { /* This is for ASPI which obviously isn't supported! */ lprintf("Windows ASPI support is not complete yet!\n"); return NULL; } cdrom_toc_t *toc; DWORD dwBytesReturned; CDROM_TOC cdrom_toc; int i, first_track, last_track, total_tracks; if( DeviceIoControl( this_gen->h_device_handle, IOCTL_CDROM_READ_TOC, NULL, 0, &cdrom_toc, sizeof(CDROM_TOC), &dwBytesReturned, NULL ) == 0 ) { #ifdef LOG DWORD dw; printf( "input_cdda: could not read TOCHDR\n" ); dw = GetLastError(); printf("GetLastError returned %u\n", dw); #endif return NULL; } first_track = cdrom_toc.FirstTrack; last_track = cdrom_toc.LastTrack; if (last_track > first_track + MAX_TRACKS - 1) last_track = first_track + MAX_TRACKS - 1; total_tracks = last_track - first_track + 1; /* allocate space for the toc entries */ toc = calloc (1, sizeof (cdrom_toc_t) + total_tracks * sizeof (cdrom_toc_entry_t)); if (!toc) { perror("calloc"); return NULL; } toc->first_track = first_track; toc->last_track = last_track; toc->total_tracks = total_tracks; /* fetch each toc entry */ /* Grab the leadout track too! (I think that this is correct?) */ for (i = 0; i <= toc->total_tracks; i++) { toc->toc_entries[i].track_mode = (cdrom_toc.TrackData[i].Control & 0x04) ? 1 : 0; toc->toc_entries[i].first_frame_minute = cdrom_toc.TrackData[i].Address[1]; toc->toc_entries[i].first_frame_second = cdrom_toc.TrackData[i].Address[2]; toc->toc_entries[i].first_frame_frame = cdrom_toc.TrackData[i].Address[3]; toc->toc_entries[i].first_frame = (toc->toc_entries[i].first_frame_minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (toc->toc_entries[i].first_frame_second * CD_FRAMES_PER_SECOND) + toc->toc_entries[i].first_frame_frame; } return toc; } static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { DWORD dwBytesReturned; RAW_READ_INFO raw_read_info; if( this_gen->hASPI ) { /* This is for ASPI which obviously isn't supported! */ lprintf("Windows ASPI support is not complete yet!\n"); return -1; } else { memset(data, 0, CD_RAW_FRAME_SIZE * num_frames); while( num_frames ) { #ifdef LOG /*printf("\t Raw read frame %d\n", frame);*/ #endif raw_read_info.DiskOffset.QuadPart = frame * CD_SECTOR_SIZE; raw_read_info.SectorCount = 1; raw_read_info.TrackMode = CDDA; /* read a frame */ if( DeviceIoControl( this_gen->h_device_handle, IOCTL_CDROM_RAW_READ, &raw_read_info, sizeof(RAW_READ_INFO), data, CD_RAW_FRAME_SIZE, &dwBytesReturned, NULL ) == 0 ) { #ifdef LOG DWORD dw; printf( "input_cdda: could not read frame\n" ); dw = GetLastError(); printf("GetLastError returned %u\n", dw); #endif return -1; } data += CD_RAW_FRAME_SIZE; frame++; num_frames--; } } return 0; } #else static cdrom_toc_t *read_cdrom_toc (int fd) { /* read_cdrom_toc is not supported on other platforms */ return NULL; } static int read_cdrom_frames(cdda_input_plugin_t *this_gen, int frame, int num_frames, unsigned char *data) { return -1; } #endif /************************************************************************** * network support functions. plays audio cd over the network. * see xine-lib/misc/cdda_server.c for the server application *************************************************************************/ #define _BUFSIZ 300 #ifndef WIN32 static int parse_url (char *urlbuf, char** host, int *port) { char *start = NULL; char *portcolon = NULL; if (host != NULL) *host = NULL; if (port != NULL) *port = 0; start = strstr(urlbuf, "://"); if (start != NULL) start += 3; else start = urlbuf; while( *start == '/' ) start++; portcolon = strchr(start, ':'); if (host != NULL) *host = start; if (portcolon != NULL) { *portcolon = '\0'; if (port != NULL) *port = atoi(portcolon + 1); } return 0; } #endif static int XINE_FORMAT_PRINTF(4, 5) network_command( xine_stream_t *stream, int socket, void *data_buf, const char *msg, ...) { char buf[_BUFSIZ]; va_list args; int ret, n; va_start(args, msg); vsnprintf(buf, _BUFSIZ - 1, msg, args); va_end(args); /* Each line sent is '\n' terminated */ if( buf[strlen(buf) - 1] != '\n' ) strcat(buf, "\n"); if( _x_io_tcp_write(stream, socket, buf, strlen(buf)) < (int)strlen(buf) ) { if (stream) xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error writing to socket.\n"); return -1; } if (_x_io_tcp_read_line(stream, socket, buf, _BUFSIZ) <= 0) { if (stream) xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error reading from socket.\n"); return -1; } sscanf(buf, "%d %d", &ret, &n ); if( n ) { if( !data_buf ) { if (stream) xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: protocol error, data returned but no buffer provided.\n"); return -1; } if ( _x_io_tcp_read(stream, socket, data_buf, n) < n ) return -1; } else if ( data_buf ) { strcpy( data_buf, buf ); } return ret; } #ifndef WIN32 static int network_connect(xine_stream_t *stream, const char *got_url ) { char *host = NULL; int port; int fd; char *url = strdup(got_url); if (url) parse_url(url, &host, &port); if( !host || !strlen(host) || !port ) { free(url); return -1; } fd = _x_io_tcp_connect(stream, host, port); lprintf("TTTcosket=%d\n", fd); free(url); if( fd != -1 ) { if( network_command(stream, fd, NULL, "cdda_open") < 0 ) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error opening remote drive.\n"); close(fd); return -1; } } return fd; } static cdrom_toc_t *network_read_cdrom_toc (xine_stream_t *stream, int fd) { char buf[_BUFSIZ]; cdrom_toc_t *toc; int i, first_track, last_track, total_tracks; /* fetch the table of contents */ if( network_command(stream, fd, buf, "cdda_tochdr" ) == -1) { if (stream) xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: network CDROMREADTOCHDR error.\n"); return NULL; } sscanf (buf,"%*s %*s %d %d", &first_track, &last_track); if (last_track > first_track + MAX_TRACKS - 1) last_track = first_track + MAX_TRACKS - 1; total_tracks = last_track - first_track + 1; /* allocate space for the toc entries */ toc = calloc (1, sizeof (cdrom_toc_t) + total_tracks * sizeof (cdrom_toc_entry_t)); if (!toc) { perror("calloc"); return NULL; } toc->first_track = first_track; toc->last_track = last_track; toc->total_tracks = total_tracks; /* fetch each toc entry */ for (i = 0; i < toc->total_tracks; i++) { /* fetch the table of contents */ if (network_command (stream, fd, buf, "cdda_tocentry %d", toc->first_track + i) == -1) { if (stream) xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: network CDROMREADTOCENTRY error.\n"); free (toc); return NULL; } sscanf (buf, "%*s %*s %d %d %d %d", &toc->toc_entries[i].track_mode, &toc->toc_entries[i].first_frame_minute, &toc->toc_entries[i].first_frame_second, &toc->toc_entries[i].first_frame_frame); toc->toc_entries[i].first_frame = (toc->toc_entries[i].first_frame_minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (toc->toc_entries[i].first_frame_second * CD_FRAMES_PER_SECOND) + toc->toc_entries[i].first_frame_frame; } /* fetch the leadout as well */ if( network_command( stream, fd, buf, "cdda_tocentry %d", CD_LEADOUT_TRACK ) == -1) { if (stream) xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: network CDROMREADTOCENTRY error.\n"); free (toc); return NULL; } sscanf (buf, "%*s %*s %d %d %d %d", &toc->toc_entries[i].track_mode, &toc->toc_entries[i].first_frame_minute, &toc->toc_entries[i].first_frame_second, &toc->toc_entries[i].first_frame_frame); toc->toc_entries[i].first_frame = (toc->toc_entries[i].first_frame_minute * CD_SECONDS_PER_MINUTE * CD_FRAMES_PER_SECOND) + (toc->toc_entries[i].first_frame_second * CD_FRAMES_PER_SECOND) + toc->toc_entries[i].first_frame_frame; return toc; } #endif /* WIN32 */ static int network_read_cdrom_frames(xine_stream_t *stream, int fd, int first_frame, int num_frames, unsigned char data[CD_RAW_FRAME_SIZE]) { return network_command( stream, fd, data, "cdda_read %d %d", first_frame, num_frames ); } /* * **************** CDDB ********************* */ /* * Config callbacks */ static void cdda_device_cb (void *data, xine_cfg_entry_t *cfg) { cdda_input_class_t *class = (cdda_input_class_t *)data; pthread_mutex_lock (&class->mutex); class->cdda_device = cfg->str_value; pthread_mutex_unlock (&class->mutex); } static void enable_cddb_changed_cb (void *data, xine_cfg_entry_t *cfg) { cdda_input_class_t *class = (cdda_input_class_t *)data; pthread_mutex_lock (&class->mutex); if (class->cddb_enable != cfg->num_value) { class->cddb_enable = cfg->num_value; class->cddb_error = 0; } pthread_mutex_unlock (&class->mutex); } static void server_changed_cb (void *data, xine_cfg_entry_t *cfg) { cdda_input_class_t *class = (cdda_input_class_t *)data; pthread_mutex_lock (&class->mutex); if (!class->cddb_server || (strcmp (class->cddb_server, cfg->str_value) != 0)) { class->cddb_server = cfg->str_value; class->cddb_error = 0; } pthread_mutex_unlock (&class->mutex); } static void port_changed_cb (void *data, xine_cfg_entry_t *cfg) { cdda_input_class_t *class = (cdda_input_class_t *)data; pthread_mutex_lock (&class->mutex); if (class->cddb_port != cfg->num_value) { class->cddb_port = cfg->num_value; class->cddb_error = 0; } pthread_mutex_unlock (&class->mutex); } #ifdef CDROM_SELECT_SPEED static void speed_changed_cb (void *data, xine_cfg_entry_t *cfg) { cdda_input_class_t *class = (cdda_input_class_t *)data; pthread_mutex_lock (&class->mutex); class->speed = cfg->num_value; pthread_mutex_unlock (&class->mutex); } #endif /* * Return 1 if CD has been changed, 0 of not, -1 on error. */ static int _cdda_is_cd_changed(cdda_input_plugin_t *this) { #ifdef CDROM_MEDIA_CHANGED int err, cd_changed=0; if(this == NULL || this->fd < 0) return -1; if ((err = ioctl(this->fd, CDROM_MEDIA_CHANGED, cd_changed)) < 0) { int e = errno; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: ioctl(CDROM_MEDIA_CHANGED) failed: %s.\n", strerror(e)); return -1; } switch(err) { case 1: return 1; break; default: return 0; break; } return -1; #else /* * At least on solaris, CDROM_MEDIA_CHANGED does not exist. Just return an * error for now */ return -1; #endif } /* * create a directory, in safe mode */ static void _cdda_mkdir_safe(xine_t *xine, char *path) { if(path == NULL) return; #ifndef WIN32 { struct stat pstat; if((stat(path, &pstat)) < 0) { /* file or directory no exist, create it */ if(mkdir(path, 0755) < 0) { int e = errno; xprintf (xine, XINE_VERBOSITY_DEBUG, "input_cdda: mkdir(%s) failed: %s.\n", path, strerror(e)); return; } } else { /* Check of found file is a directory file */ if(!S_ISDIR(pstat.st_mode)) { xprintf(xine, XINE_VERBOSITY_DEBUG, "input_cdda: %s is not a directory.\n", path); } } } #else { HANDLE hList; TCHAR szDir[MAX_PATH+3]; WIN32_FIND_DATA FileData; // Get the proper directory path snprintf_buf(szDir, "%s\\*", path); // Get the first file hList = FindFirstFile(szDir, &FileData); if (hList == INVALID_HANDLE_VALUE) { if(mkdir(path, 0) != 0) { xprintf(xine, XINE_VERBOSITY_DEBUG, "input_cdda: mkdir(%s) failed.\n", path); return; } } FindClose(hList); } #endif /* WIN32 */ } /* * Make recursive directory creation (given an absolute pathname) */ static void _cdda_mkdir_recursive_safe (xine_t *xine, char *path) { if (!path) return; char buf[strlen (path) + 1]; strcpy (buf, path); char *p = strchr (buf, '/'); if (!p) p = buf; do { while (*p++ == '/') /**/; p = strchr (p, '/'); if (p) *p = 0; _cdda_mkdir_safe (xine, buf); if (p) *p = '/'; } while (p); } /* * Read from socket, fill char *s, return size length. */ static int _cdda_cddb_socket_read(cdda_input_plugin_t *this, char *str, int size) { int ret; ret = _x_io_tcp_read_line(this->stream, this->cddb.fd, str, size); xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "<<< %s\n", str); return ret; } /* * Send a command to socket */ static int _cdda_cddb_send_command(cdda_input_plugin_t *this, char *cmd) { if((this == NULL) || (this->cddb.fd < 0) || (cmd == NULL)) return -1; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, ">>> %s\n", cmd); return (int)_x_io_tcp_write(this->stream, this->cddb.fd, cmd, strlen(cmd)); } /* * Handle return code od a command result. */ static int _cdda_cddb_handle_code(char *buf) { int rcode, fdig, sdig, /*tdig,*/ err; err = -999; if (sscanf(buf, "%d", &rcode) == 1) { fdig = rcode / 100; sdig = (rcode - (fdig * 100)) / 10; /*tdig = (rcode - (fdig * 100) - (sdig * 10));*/ /* printf(" %d--\n", fdig); printf(" -%d-\n", sdig); printf(" --%d\n", tdig); */ err = rcode; switch (fdig) { case 1: /* printf("Informative message\n"); */ break; case 2: /* printf("Command OK\n"); */ break; case 3: /* printf("Command OK so far, continue\n"); */ break; case 4: /* printf("Command OK, but cannot be performed for some specified reasons\n"); */ err = 0 - rcode; break; case 5: /* printf("Command unimplemented, incorrect, or program error\n"); */ err = 0 - rcode; break; default: /* printf("Unhandled case %d\n", fdig); */ err = 0 - rcode; break; } switch (sdig) { case 0: /* printf("Ready for further commands\n"); */ break; case 1: /* printf("More server-to-client output follows (until terminating marker)\n"); */ break; case 2: /* printf("More client-to-server input follows (until terminating marker)\n"); */ break; case 3: /* printf("Connection will close\n"); */ err = 0 - rcode; break; default: /* printf("Unhandled case %d\n", sdig); */ err = 0 - rcode; break; } } return err; } static inline char *_cdda_append (/*const*/ char *first, const char *second) { if (!first) return strdup (second); char *result = (char *) realloc (first, strlen (first) + strlen (second) + 1); strcat (result, second); return result; } static void _cdda_parse_cddb_info (cdda_input_plugin_t *this, char *buffer, char **dtitle) { /* buffer should be no more than 2048 bytes... */ char buf[2048]; int track_no; if (sscanf (buffer, "DTITLE=%s", &buf[0]) == 1) { char *pt = strchr (buffer, '='); if (pt) { ++pt; *dtitle = _cdda_append (*dtitle, pt); pt = strdup (*dtitle); char *title = strstr (pt, " / "); if (title) { *title = 0; title += 3; free (this->cddb.disc_artist); this->cddb.disc_artist = strdup (pt); } else title = pt; free (this->cddb.disc_title); this->cddb.disc_title = strdup (title); free (pt); } } else if (sscanf (buffer, "DYEAR=%s", &buf[0]) == 1) { char *pt = strchr (buffer, '='); if (pt && strlen (pt) == 5) this->cddb.disc_year = strdup (pt + 1); } else if(sscanf(buffer, "DGENRE=%s", &buf[0]) == 1) { char *pt = strchr(buffer, '='); if (pt) this->cddb.disc_category = strdup (pt + 1); } else if (sscanf (buffer, "TTITLE%d=%s", &track_no, &buf[0]) == 2) { if (track_no >= 0 && track_no < this->cddb.num_tracks) { char *pt = strchr(buffer, '='); this->cddb.track[track_no].title = _cdda_append (this->cddb.track[track_no].title, pt + 1); } } else if (!strncmp (buffer, "EXTD=", 5)) { if (!this->cddb.disc_year) { int nyear; char *y = strstr (buffer, "YEAR:"); if (y && sscanf (y + 5, "%4d", &nyear) == 1) this->cddb.disc_year = _x_asprintf ("%d", nyear); } } } /* * Try to load cached cddb infos */ static int _cdda_load_cached_cddb_infos(cdda_input_plugin_t *this) { DIR *dir; const char *const xdg_cache_home = xdgCacheHome(&this->stream->xine->basedir_handle); const size_t cdir_size = strlen(xdg_cache_home) + sizeof("/"PACKAGE"/cddb") + 10 + 1; char *const cdir = alloca(cdir_size); sprintf(cdir, "%s/" PACKAGE "/cddb", xdg_cache_home); if((dir = opendir(cdir)) != NULL) { struct dirent *pdir; while((pdir = readdir(dir)) != NULL) { char discid[9]; snprintf_buf(discid, "%08" PRIx32, this->cddb.disc_id); if(!strcasecmp(pdir->d_name, discid)) { FILE *fd; snprintf(cdir + cdir_size - 12, 10, "/%s", discid); if ((fd = fopen(cdir, "r")) == NULL) { int e = errno; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: fopen(%s) failed: %s.\n", cdir, strerror (e)); closedir (dir); return 0; } else { char buffer[2048], *ln; char *dtitle = NULL; while ((ln = fgets(buffer, sizeof (buffer) - 1, fd)) != NULL) { int length = strlen (buffer); if (length && buffer[length - 1] == '\n') buffer[length - 1] = '\0'; _cdda_parse_cddb_info (this, buffer, &dtitle); } fclose(fd); free(dtitle); } closedir(dir); return 1; } } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: cached entry for disc ID %08" PRIx32 " not found.\n", this->cddb.disc_id); closedir(dir); } return 0; } /* * Save cddb grabbed infos. */ static void _cdda_save_cached_cddb_infos(cdda_input_plugin_t *this, char *filecontent) { FILE *fd; char *cfile; const char *const xdg_cache_home = xdgCacheHome(&this->stream->xine->basedir_handle); if (filecontent == NULL) return; /* the filename is always 8 characters */ cfile = alloca(strlen(xdg_cache_home) + sizeof("/"PACKAGE"/cddb") + 9); strcpy(cfile, xdg_cache_home); strcat(cfile, "/"PACKAGE"/cddb"); /* Ensure the cache directory exists */ _cdda_mkdir_recursive_safe(this->stream->xine, cfile); sprintf(cfile + strlen(cfile), "/%08" PRIx32, this->cddb.disc_id); if ((fd = fopen(cfile, "w")) == NULL) { int e = errno; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: fopen(%s) failed: %s.\n", cfile, strerror (e)); return; } else { fprintf(fd, "%s", filecontent); fclose(fd); } } /* * Open a socket. */ static int _cdda_cddb_socket_open(cdda_input_plugin_t *this) { cdda_input_class_t *class = (cdda_input_class_t *)this->input_plugin.input_class; int sock; #ifdef LOG printf("Conecting..."); fflush(stdout); #endif { char server[2048]; int port; pthread_mutex_lock (&class->mutex); strlcpy (server, class->cddb_server, sizeof(server)); port = class->cddb_port; pthread_mutex_unlock (&class->mutex); sock = _x_io_tcp_connect (this->stream, server, port); if (sock == -1 || _x_io_tcp_connect_finish (this->stream, sock, CDDB_TIMEOUT) != XIO_READY) { xine_log (this->stream->xine, XINE_LOG_MSG, _("%s: can't connect to %s:%d\n"), LOG_MODULE, server, port); lprintf ("failed\n"); return -1; } } lprintf ("done, sock = %d\n", sock); return sock; } /* * Close the socket */ static void _cdda_cddb_socket_close(cdda_input_plugin_t *this) { if((this == NULL) || (this->cddb.fd < 0)) return; _x_io_tcp_close(this->stream, this->cddb.fd); this->cddb.fd = -1; } /* * Try to talk with CDDB server (to retrieve disc/tracks titles). */ static int _cdda_cddb_retrieve(cdda_input_plugin_t *this) { cdda_input_class_t *class = (cdda_input_class_t *)this->input_plugin.input_class; char buffer[2048], buffercache[32768], *m, *p; char *dtitle = NULL; int err, i; if(_cdda_load_cached_cddb_infos(this)) { this->cddb.have_cddb_info = 1; return 1; } if (!class->cddb_enable || class->cddb_error) { this->cddb.have_cddb_info = 0; return 0; } else { class->cddb_error = 1; this->cddb.fd = _cdda_cddb_socket_open(this); if(this->cddb.fd >= 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("input_cdda: successfully connected to cddb server '%s:%d'.\n"), class->cddb_server, class->cddb_port); } else { int e = errno; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("input_cdda: failed to connect to cddb server '%s:%d' (%s).\n"), class->cddb_server, class->cddb_port, strerror (e)); this->cddb.have_cddb_info = 0; return 0; } /* Read welcome message */ memset(&buffer, 0, sizeof(buffer)); err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); if (err < 0 || (err = _cdda_cddb_handle_code(buffer)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error while reading cddb welcome message.\n"); _cdda_cddb_socket_close(this); return 0; } /* Send hello command */ /* We don't send current user/host name to prevent spam. * Software that sends this is considered spyware * that most people don't like. */ memset(&buffer, 0, sizeof(buffer)); snprintf_buf(buffer, "cddb hello unknown localhost xine %s\n", VERSION); if ((err = _cdda_cddb_send_command(this, buffer)) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error while sending cddb hello command.\n"); _cdda_cddb_socket_close(this); return 0; } memset(&buffer, 0, sizeof(buffer)); err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); if (err < 0 || (err = _cdda_cddb_handle_code(buffer)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: cddb hello command returned error code '%03d'.\n", err); _cdda_cddb_socket_close(this); return 0; } /* Send server protocol number */ /* For UTF-8 support - use protocol 6 */ memset(&buffer, 0, sizeof(buffer)); snprintf_buf(buffer, "proto %d\n", CDDB_PROTOCOL); if ((err = _cdda_cddb_send_command(this, buffer)) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error while sending cddb protocol command.\n"); _cdda_cddb_socket_close(this); return 0; } memset(&buffer, 0, sizeof(buffer)); err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); if (err < 0 || (err = _cdda_cddb_handle_code(buffer)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: cddb protocol command returned error code '%03d'.\n", err); _cdda_cddb_socket_close(this); return 0; } /* Send query command */ memset(&buffer, 0, sizeof(buffer)); size_t size = sprintf(buffer, "cddb query %08" PRIx32 " %d ", this->cddb.disc_id, this->cddb.num_tracks); for (i = 0; i < this->cddb.num_tracks; i++) { size += snprintf(buffer + size, sizeof(buffer) - size, "%d ", this->cddb.track[i].start); } snprintf(buffer + strlen(buffer), sizeof(buffer) - size, "%d\n", this->cddb.disc_length); if ((err = _cdda_cddb_send_command(this, buffer)) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error while sending cddb query command.\n"); _cdda_cddb_socket_close(this); return 0; } memset(&buffer, 0, sizeof(buffer)); err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); if (err < 0 || (((err = _cdda_cddb_handle_code(buffer)) != 200) && (err != 210) && (err != 211))) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: cddb query command returned error code '%03d'.\n", err); _cdda_cddb_socket_close(this); return 0; } if (err == 200) { p = buffer; i = 0; while ((i <= 2) && ((m = xine_strsep(&p, " ")) != NULL)) { if (i == 1) { this->cddb.disc_category = strdup(m); } else if(i == 2) { this->cddb.cdiscid = strdup(m); } i++; } } if ((err == 210) || (err == 211)) { memset(&buffer, 0, sizeof(buffer)); err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); if (err < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: cddb query command returned error code '%03d'.\n", err); _cdda_cddb_socket_close(this); return 0; } p = buffer; i = 0; while ((i <= 1) && ((m = xine_strsep(&p, " ")) != NULL)) { if (i == 0) { this->cddb.disc_category = strdup(m); } else if(i == 1) { this->cddb.cdiscid = strdup(m); } i++; } while (strcmp(buffer, ".")) { memset(&buffer, 0, sizeof(buffer)); err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); if (err < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: cddb query command returned error code '%03d'.\n", err); _cdda_cddb_socket_close(this); return 0; } } } /* Send read command */ memset(&buffer, 0, sizeof(buffer)); snprintf_buf(buffer, "cddb read %s %s\n", this->cddb.disc_category, this->cddb.cdiscid); if ((err = _cdda_cddb_send_command(this, buffer)) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: error while sending cddb read command.\n"); _cdda_cddb_socket_close(this); return 0; } memset(&buffer, 0, sizeof(buffer)); err = _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); if (err < 0 || (err = _cdda_cddb_handle_code(buffer)) != 210) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_cdda: cddb read command returned error code '%03d'.\n", err); _cdda_cddb_socket_close(this); return 0; } this->cddb.have_cddb_info = 1; memset(&buffercache, 0, sizeof(buffercache)); while (strcmp(buffer, ".")) { size_t bufsize = strlen(buffercache); memset(&buffer, 0, sizeof(buffer)); _cdda_cddb_socket_read(this, buffer, sizeof(buffer) - 1); snprintf(buffercache + bufsize, sizeof(buffercache) - bufsize, "%s\n", buffer); _cdda_parse_cddb_info (this, buffer, &dtitle); } free(dtitle); /* Save cddb info and close socket */ _cdda_save_cached_cddb_infos(this, buffercache); _cdda_cddb_socket_close(this); } /* success */ class->cddb_error = 0; return 1; } /* * Compute cddb disc compliant id */ static unsigned int _cdda_cddb_sum(int n) { unsigned int ret = 0; while(n > 0) { ret += (n % 10); n /= 10; } return ret; } static uint32_t _cdda_calc_cddb_id(cdda_input_plugin_t *this) { int i, tsum = 0; if(this == NULL || (this->cddb.num_tracks <= 0)) return 0; for(i = 0; i < this->cddb.num_tracks; i++) tsum += _cdda_cddb_sum((this->cddb.track[i].start / CD_FRAMES_PER_SECOND)); return ((tsum % 0xff) << 24 | (this->cddb.disc_length - (this->cddb.track[0].start / CD_FRAMES_PER_SECOND)) << 8 | this->cddb.num_tracks); } /* * Compute Musicbrainz CDIndex ID */ static void _cdda_cdindex(cdda_input_plugin_t *this, cdrom_toc_t *toc) { sha160_t sha; unsigned char temp[40], digest[24]; int i; sha160_init (&sha); snprintf_buf (temp, "%02X%02X%08X", toc->first_track, toc->last_track - toc->ignore_last_track, toc->toc_entries[toc->total_tracks].first_frame); /* + 150 */ sha160_update (&sha, temp, 12); for (i = toc->first_track; i <= toc->last_track - toc->ignore_last_track; i++) { snprintf_buf (temp, "%08X", toc->toc_entries[i - 1].first_frame); sha160_update (&sha, temp, 8); } for (i = toc->last_track - toc->ignore_last_track + 1; i < 100; i++) { sha160_update (&sha, temp, 8); } sha160_final (&sha, digest); xine_base64_encode (digest, temp, 20); _x_meta_info_set_utf8 (this->stream, XINE_META_INFO_CDINDEX_DISCID, temp); } /* * return cbbd disc id. */ static uint32_t _cdda_get_cddb_id(cdda_input_plugin_t *this) { if(this == NULL || (this->cddb.num_tracks <= 0)) return 0; return _cdda_calc_cddb_id(this); } /* * Free allocated memory for CDDB informations */ static void _cdda_free_cddb_info(cdda_input_plugin_t *this) { if(this->cddb.track) { int t; for(t = 0; t < this->cddb.num_tracks; t++) { _x_freep(&this->cddb.track[t].title); } _x_freep(&this->cddb.track); _x_freep(&this->cddb.cdiscid); _x_freep(&this->cddb.disc_title); _x_freep(&this->cddb.disc_artist); _x_freep(&this->cddb.disc_category); _x_freep(&this->cddb.disc_year); } this->cddb.num_tracks = 0; } /* * ********** END OF CDDB *************** */ static int cdda_open (cdda_input_plugin_t *this_gen, const char *cdda_device, int *fdd) { #ifndef WIN32 int fd = -1; if ( !cdda_device ) return -1; *fdd = -1; this_gen->fd = -1; /* We use O_NONBLOCK for when /proc/sys/dev/cdrom/check_media is at 1 on * Linux systems */ fd = xine_open_cloexec(cdda_device, O_RDONLY | O_NONBLOCK); if (fd == -1) { return -1; } this_gen->fd = fd; #ifdef CDROM_SELECT_SPEED { cdda_input_class_t *class = (cdda_input_class_t *)this_gen->input_plugin.input_class; int speed = class->speed; if (speed && ioctl (fd, CDROM_SELECT_SPEED, speed) != 0) xprintf (class->xine, XINE_VERBOSITY_DEBUG, "input_cdda: setting drive speed to %d failed\n", speed); } #endif *fdd = fd; return 0; #else /* WIN32 */ if ( !cdda_device ) return -1; *fdd = -1; this_gen->fd = -1; this_gen->h_device_handle = NULL; this_gen->i_sid = 0; this_gen->hASPI = NULL; this_gen->lpSendCommand = NULL; /* We are going to assume that we are opening a * device and not a file! */ if( WIN_NT ) { char psz_win32_drive[7]; lprintf( "using winNT/2K/XP ioctl layer" ); sprintf( psz_win32_drive, "\\\\.\\%c:", cdda_device[0] ); this_gen->h_device_handle = CreateFile( psz_win32_drive, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS, NULL ); return (this_gen->h_device_handle == NULL) ? -1 : 0; } else { HMODULE hASPI = NULL; long (*lpGetSupport)( void ) = NULL; long (*lpSendCommand)( void* ) = NULL; DWORD dwSupportInfo; int i, j, i_hostadapters; char c_drive = cdda_device[0]; hASPI = LoadLibrary( "wnaspi32.dll" ); if( hASPI != NULL ) { lpGetSupport = (long (*)(void))GetProcAddress( hASPI, "GetASPI32SupportInfo" ); lpSendCommand = (long (*)(void*))GetProcAddress( hASPI, "SendASPI32Command" ); } if( hASPI == NULL || lpGetSupport == NULL || lpSendCommand == NULL ) { lprintf( "unable to load aspi or get aspi function pointers" ); if( hASPI ) FreeLibrary( hASPI ); return -1; } /* ASPI support seems to be there */ dwSupportInfo = lpGetSupport(); if( HIBYTE( LOWORD ( dwSupportInfo ) ) == SS_NO_ADAPTERS ) { lprintf( "no host adapters found (aspi)" ); FreeLibrary( hASPI ); return -1; } if( HIBYTE( LOWORD ( dwSupportInfo ) ) != SS_COMP ) { lprintf( "unable to initalize aspi layer" ); FreeLibrary( hASPI ); return -1; } i_hostadapters = LOBYTE( LOWORD( dwSupportInfo ) ); if( i_hostadapters == 0 ) { FreeLibrary( hASPI ); return -1; } c_drive = c_drive > 'Z' ? c_drive - 'a' : c_drive - 'A'; for( i = 0; i < i_hostadapters; i++ ) { for( j = 0; j < 15; j++ ) { struct SRB_GetDiskInfo srbDiskInfo; srbDiskInfo.SRB_Cmd = SC_GET_DISK_INFO; srbDiskInfo.SRB_HaId = i; srbDiskInfo.SRB_Flags = 0; srbDiskInfo.SRB_Hdr_Rsvd = 0; srbDiskInfo.SRB_Target = j; srbDiskInfo.SRB_Lun = 0; lpSendCommand( (void*) &srbDiskInfo ); if( (srbDiskInfo.SRB_Status == SS_COMP) && (srbDiskInfo.SRB_Int13HDriveInfo == c_drive) ) { /* Make sure this is a cdrom device */ struct SRB_GDEVBlock srbGDEVBlock; memset( &srbGDEVBlock, 0, sizeof(struct SRB_GDEVBlock) ); srbGDEVBlock.SRB_Cmd = SC_GET_DEV_TYPE; srbGDEVBlock.SRB_HaId = i; srbGDEVBlock.SRB_Target = j; lpSendCommand( (void*) &srbGDEVBlock ); if( ( srbGDEVBlock.SRB_Status == SS_COMP ) && ( srbGDEVBlock.SRB_DeviceType == DTYPE_CDROM ) ) { this_gen->i_sid = MAKEWORD( i, j ); this_gen->hASPI = hASPI; this_gen->lpSendCommand = lpSendCommand; lprintf( "using aspi layer" ); return 0; } else { FreeLibrary( hASPI ); lprintf( "%c: is not a cdrom drive", cdda_device[0] ); return -1; } } } } FreeLibrary( hASPI ); lprintf( "unable to get haid and target (aspi)" ); } #endif /* WIN32 */ return -1; } static int cdda_close(cdda_input_plugin_t *this_gen) { if (!this_gen) return 0; if( this_gen->fd != -1 ) { #ifdef CDROM_SELECT_SPEED cdda_input_class_t *class = (cdda_input_class_t *)this_gen->input_plugin.input_class; int speed = class->speed; if (speed && ioctl (this_gen->fd, CDROM_SELECT_SPEED, 0) != 0) xprintf (class->xine, XINE_VERBOSITY_DEBUG, "input_cdda: setting drive speed to normal failed\n"); #endif close(this_gen->fd); } this_gen->fd = -1; if (this_gen->net_fd != -1) close(this_gen->net_fd); this_gen->net_fd = -1; #ifdef WIN32 if( this_gen->h_device_handle ) CloseHandle( this_gen->h_device_handle ); this_gen->h_device_handle = NULL; if( this_gen->hASPI ) FreeLibrary( this_gen->hASPI ); this_gen->hASPI = NULL; #endif /* WIN32 */ return 0; } static uint32_t cdda_plugin_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_SEEKABLE; } static off_t cdda_plugin_read (input_plugin_t *this_gen, void *buf, off_t len) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; uint32_t want, have; /* Allow reading full raw frames only. This will also short circuit _x_demux_read_header (). */ if ((len < 0) || ((uint64_t)len > 0xffffffff)) return 0; want = (uint64_t)len; want /= (uint32_t)CD_RAW_FRAME_SIZE; have = want * CD_RAW_FRAME_SIZE; if (have != (uint32_t)len) return 0; if (this->current_frame > this->last_frame) return 0; /* populate frame cache */ if (this->cache_first == -1 || this->current_frame < this->cache_first || this->current_frame > this->cache_last) { int len, err = -1; if (this->tripple) { len = CACHED_FRAMES / 10; this->tripple--; } else { len = CACHED_FRAMES; } this->cache_first = this->current_frame; this->cache_last = this->current_frame + len - 1; if( this->cache_last > this->last_frame ) this->cache_last = this->last_frame; #ifndef WIN32 if (this->fd != -1) #else if (this->h_device_handle) #endif /* WIN32 */ err = read_cdrom_frames(this, this->cache_first, this->cache_last - this->cache_first + 1, this->cache[0]); else if (this->net_fd != -1) err = network_read_cdrom_frames(this->stream, this->net_fd, this->cache_first, this->cache_last - this->cache_first + 1, this->cache[0]); if (err < 0) return 0; this->last_read_time = time (NULL); } have = this->cache_last + 1 - this->current_frame; if (want > have) want = have; have = want * CD_RAW_FRAME_SIZE; memcpy (buf, this->cache [this->current_frame - this->cache_first], have); this->current_frame += want; return have; } static buf_element_t *cdda_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t nlen) { buf_element_t *buf; buf = fifo->buffer_pool_size_alloc (fifo, 8 << 10); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; /* Standard bufs are 8kbyte and can hold 3 raw frames. */ if (nlen > buf->max_size) nlen = buf->max_size; buf->size = cdda_plugin_read(this_gen, buf->content, nlen); if (buf->size == 0) { buf->free_buffer(buf); buf = NULL; } return buf; } static off_t cdda_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; int seek_to_frame; /* compute the proposed frame and check if it is within bounds */ seek_to_frame = offset / CD_RAW_FRAME_SIZE; if (origin == SEEK_SET) seek_to_frame += this->first_frame; else if (origin == SEEK_CUR) seek_to_frame += this->current_frame; else seek_to_frame += this->last_frame + 1; if ((seek_to_frame >= this->first_frame) && (seek_to_frame <= this->last_frame + 1)) { if ((seek_to_frame < this->cache_first) || (seek_to_frame > this->cache_last + 1)) { time_t now = time (NULL); /* read in small steps first to give faster seek response. */ if (now <= this->last_read_time + 5) this->tripple = 10; } this->current_frame = seek_to_frame; } return (this->current_frame - this->first_frame) * CD_RAW_FRAME_SIZE; } static off_t cdda_plugin_get_current_pos (input_plugin_t *this_gen){ cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; return (this->current_frame - this->first_frame) * CD_RAW_FRAME_SIZE; } static off_t cdda_plugin_get_length (input_plugin_t *this_gen) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; return (this->last_frame - this->first_frame + 1) * CD_RAW_FRAME_SIZE; } static uint32_t cdda_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return 0; } static const char* cdda_plugin_get_mrl (input_plugin_t *this_gen) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; return this->mrl; } static int cdda_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return 0; } static void cdda_plugin_dispose (input_plugin_t *this_gen ) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; cdda_input_class_t *class = (cdda_input_class_t *) this->input_plugin.input_class; class->last_read_time = this->last_read_time; _cdda_free_cddb_info(this); cdda_close(this); free(this); } static int cdda_plugin_open (input_plugin_t *this_gen ) { cdda_input_plugin_t *this = (cdda_input_plugin_t *) this_gen; cdda_input_class_t *class = (cdda_input_class_t *) this_gen->input_class; cdrom_toc_t *toc = NULL; int fd = -1; char sbuf[2048]; const char *cdda_device; lprintf("cdda_plugin_open\n"); /* get the CD TOC */ cdda_device = this->device; if (!cdda_device) { pthread_mutex_lock (&class->mutex); strlcpy (sbuf, class->cdda_device, 2048); pthread_mutex_unlock (&class->mutex); cdda_device = sbuf; } #ifndef WIN32 if (strchr (cdda_device,':')) { fd = network_connect (this->stream, cdda_device); if (fd != -1) { this->net_fd = fd; toc = network_read_cdrom_toc (this->stream, this->net_fd); } } #endif if (this->net_fd == -1) { if (cdda_open (this, cdda_device, &fd) == -1) return 0; #ifndef WIN32 toc = read_cdrom_toc (this->fd); #else toc = read_cdrom_toc (this); #endif } if (!toc) { cdda_close (this); return 0; } print_cdrom_toc (class->xine, toc); if (this->track >= 0) { if ((toc->first_track > (this->track + 1)) || (toc->last_track < (this->track + 1))) { free_cdrom_toc (toc); cdda_close (this); return 0; } /* set up the frame boundaries for this particular track */ this->first_frame = this->current_frame = toc->toc_entries[this->track].first_frame; this->last_frame = toc->toc_entries[this->track + 1].first_frame - 1; } else { /* no track given = all audio tracks */ this->first_frame = this->current_frame = toc->toc_entries[0].first_frame; this->last_frame = toc->toc_entries[toc->last_track - toc->first_track + 1].first_frame - 1; } /* if the last read was just recently, assume the drive still up and spinning, * and use tripple mode for start as well. */ { time_t now; this->last_read_time = class->last_read_time; now = time (NULL); if (now <= this->last_read_time + 5) this->tripple = 10; } /* invalidate cache */ this->cache_first = this->cache_last = -1; /* get the Musicbrainz CDIndex */ _cdda_cdindex (this, toc); /* * CDDB */ _cdda_free_cddb_info(this); if (toc->total_tracks) { int t; this->cddb.track = (trackinfo_t *) calloc(toc->total_tracks, sizeof(trackinfo_t)); if (this->cddb.track) this->cddb.num_tracks = toc->total_tracks; for(t = 0; t < this->cddb.num_tracks; t++) { int length = (toc->toc_entries[t].first_frame_minute * CD_SECONDS_PER_MINUTE + toc->toc_entries[t].first_frame_second); this->cddb.track[t].start = (length * CD_FRAMES_PER_SECOND + toc->toc_entries[t].first_frame_frame); this->cddb.track[t].title = NULL; } } this->cddb.disc_length = (toc->toc_entries[toc->total_tracks].first_frame_minute * CD_SECONDS_PER_MINUTE + toc->toc_entries[toc->total_tracks].first_frame_second); this->cddb.disc_id = _cdda_get_cddb_id(this); if((this->cddb.have_cddb_info == 0) || (_cdda_is_cd_changed(this) == 1)) _cdda_cddb_retrieve(this); if(this->cddb.disc_title) { lprintf("Disc Title: %s\n", this->cddb.disc_title); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ALBUM, this->cddb.disc_title); } if ((this->track >= 0) && (this->track < this->cddb.num_tracks) && this->cddb.track[this->track].title) { /* Check for track 'titles' of the form / . */ char *pt; pt = strstr(this->cddb.track[this->track].title, " / "); if (pt != NULL) { char *track_artist; track_artist = strdup(this->cddb.track[this->track].title); track_artist[pt - this->cddb.track[this->track].title] = 0; lprintf("Track %d Artist: %s\n", this->track+1, track_artist); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, track_artist); free(track_artist); pt += 3; } else { if(this->cddb.disc_artist) { lprintf("Disc Artist: %s\n", this->cddb.disc_artist); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_ARTIST, this->cddb.disc_artist); } pt = this->cddb.track[this->track].title; } lprintf("Track %d Title: %s\n", this->track+1, pt); char tracknum[16]; snprintf_buf(tracknum, "%d", this->track+1); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TRACK_NUMBER, tracknum); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_TITLE, pt); } if(this->cddb.disc_category) { lprintf("Disc Category: %s\n", this->cddb.disc_category); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_GENRE, this->cddb.disc_category); } if(this->cddb.disc_year) { lprintf("Disc Year: %s\n", this->cddb.disc_year); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_YEAR, this->cddb.disc_year); } pthread_mutex_lock (&class->mutex); free_cdrom_toc (class->last_toc); class->last_toc = toc; pthread_mutex_unlock (&class->mutex); return 1; } static void free_autoplay_list(cdda_input_class_t *this) { /* free old playlist */ _x_freep (&this->autoplaylist); } static const char * const * cdda_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { cdda_input_class_t *this = (cdda_input_class_t *)this_gen; cdrom_toc_t *toc = NULL; char dname[2048]; lprintf("cdda_class_get_autoplay_list for >%s<\n", this->cdda_device); pthread_mutex_lock (&this->mutex); strlcpy (dname, this->cdda_device, 2048); pthread_mutex_unlock (&this->mutex); free_autoplay_list(this); /* get the CD TOC */ /* we need an instance pointer to store all the details about the * device we are going to open; let's create a minimal temporary instance. */ { int fd = -1; cdda_input_plugin_t *inst = calloc (1, sizeof (*inst)); if (!inst) return NULL; inst->input_plugin.input_class = this_gen; inst->stream = NULL; inst->fd = -1; inst->net_fd = -1; #ifndef WIN32 if (strchr (dname,':')) { fd = network_connect (NULL, dname); if (fd != -1) { inst->net_fd = fd; toc = network_read_cdrom_toc (NULL, fd); } } #endif if (fd == -1) { if (cdda_open (inst, dname, &fd) == -1) { #ifdef LOG int e = errno; lprintf ("cdda_class_get_autoplay_list: opening >%s< failed %s\n", dname, strerror (e)); #endif free (inst); return NULL; } #ifndef WIN32 toc = read_cdrom_toc (fd); #else toc = read_cdrom_toc (inst); #endif /* WIN32 */ } cdda_close (inst); free (inst); } if (!toc) return NULL; print_cdrom_toc (this->xine, toc); { int num_tracks = toc->last_track - toc->first_track + (toc->ignore_last_track ? 0 : 1); size_t size = (num_tracks + 1) * sizeof (char *) + num_tracks * 9; char **list = malloc (size); this->autoplaylist = list; if (list) { int n, t = toc->first_track; char *s = (char *)(list + num_tracks + 1); *num_files = num_tracks; n = 10 - t; if (n > 0) { if (n > num_tracks) n = num_tracks; num_tracks -= n; while ((n--) > 0) { *list++ = s; memcpy (s, "cdda:/", 6); s[6] = t + '0'; s[7] = 0; s += 8; t++; } } n = num_tracks; while ((n--) > 0) { *list++ = s; memcpy (s, "cdda:/", 6); s[7] = (t % 10) + '0'; s[6] = ((t / 10) & 15) + '0'; s[8] = 0; s += 9; t++; } *list = NULL; pthread_mutex_lock (&this->mutex); free_cdrom_toc (this->last_toc); this->last_toc = toc; pthread_mutex_unlock (&this->mutex); return (const char * const *)this->autoplaylist; } } *num_files = 0; free_cdrom_toc (toc); return NULL; } static input_plugin_t *cdda_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { cdda_input_plugin_t *this; size_t mlen; const uint8_t *p; unsigned int d, t; lprintf ("cdda_class_get_instance: >%s<\n", mrl); if (strncasecmp (mrl, "cdda:/", 6)) return NULL; /* parse "cdda:/[/foo/bar][/35]" */ t = 0; d = 1; mlen = strlen (mrl + 5); p = (const uint8_t *)mrl + mlen + 5; while (1) { uint8_t z = *--p; if (z == '/') break; z ^= '0'; if (z > 9) break; t += d * z; d *= 10u; } if (*p != '/') { p = (const uint8_t *)mrl + mlen + 5; t = 0; } this = calloc (1, sizeof (*this) + 2 * (mlen + 6)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->cddb.cdiscid = NULL; this->cddb.disc_title = NULL; this->cddb.disc_year = NULL; this->cddb.disc_artist = NULL; this->cddb.disc_category = NULL; this->cddb.disc_length = 0; this->cddb.track = NULL; this->cddb.num_tracks = 0; this->cddb.have_cddb_info = 0; this->device = NULL; this->first_frame = 0; this->current_frame = 0; this->last_frame = 0; this->cache_first = 0; this->cache_last = 0; this->tripple = 0; this->last_read_time = 0; # ifdef WIN32 this->h_device_handle = 0; this->hASPI = 0; this->i_sid = 0; this->lpSendCommand = NULL; # endif #endif /* CD tracks start from 1; internal data structure indexes from 0 */ this->track = (int)t - 1; { char *q = (char *)this + sizeof (*this); this->mrl = q; memcpy (q, mrl, mlen + 6); q += mlen + 6; mlen = p - (const uint8_t *)mrl - 5; if (mlen > 1) { mlen--; this->device = q; memcpy (q, mrl + 6, mlen); q[mlen] = 0; } } this->stream = stream; this->fd = -1; this->net_fd = -1; this->input_plugin.open = cdda_plugin_open; this->input_plugin.get_capabilities = cdda_plugin_get_capabilities; this->input_plugin.read = cdda_plugin_read; this->input_plugin.read_block = cdda_plugin_read_block; this->input_plugin.seek = cdda_plugin_seek; this->input_plugin.get_current_pos = cdda_plugin_get_current_pos; this->input_plugin.get_length = cdda_plugin_get_length; this->input_plugin.get_blocksize = cdda_plugin_get_blocksize; this->input_plugin.get_mrl = cdda_plugin_get_mrl; this->input_plugin.get_optional_data = cdda_plugin_get_optional_data; this->input_plugin.dispose = cdda_plugin_dispose; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } static void cdda_class_dispose (input_class_t *this_gen) { cdda_input_class_t *this = (cdda_input_class_t *) this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free_autoplay_list(this); free_cdrom_toc (this->last_toc); pthread_mutex_destroy (&this->mutex); free (this); } static int cdda_class_eject_media (input_class_t *this_gen) { cdda_input_class_t *this = (cdda_input_class_t *) this_gen; int r; pthread_mutex_lock (&this->mutex); r = media_eject_media (this->xine, this->cdda_device); pthread_mutex_unlock (&this->mutex); return r; } static void *init_plugin (xine_t *xine, const void *data) { cdda_input_class_t *this; config_values_t *config; (void)data; this = calloc(1, sizeof (cdda_input_class_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->cddb_error = 0; this->input_class.get_dir = NULL; this->last_read_time = 0; this->last_toc = NULL; this->autoplaylist = NULL; #endif this->xine = xine; this->config = xine->config; config = xine->config; this->input_class.get_instance = cdda_class_get_instance; this->input_class.identifier = "cdda"; this->input_class.description = N_("CD Digital Audio (aka. CDDA)"); /* this->input_class.get_dir = cdda_class_get_dir; */ this->input_class.get_autoplay_list = cdda_class_get_autoplay_list; this->input_class.dispose = cdda_class_dispose; this->input_class.eject_media = cdda_class_eject_media; this->cdda_device = config->register_filename (config, "media.audio_cd.device", DEFAULT_CDDA_DEVICE, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for CD audio"), _("The path to the device, usually a CD or DVD drive, which you intend to use " "for playing audio CDs."), 10, cdda_device_cb, this); this->cddb_enable = config->register_bool (config, "media.audio_cd.use_cddb", 1, _("query CDDB"), _("Enables CDDB queries, which will give you convenient title and track names " "for your audio CDs.\n" "Keep in mind that, unless you use your own private CDDB, this information is retrieved " "from an internet server which might collect a profile of your listening habits."), 10, enable_cddb_changed_cb, this); this->cddb_server = config->register_string (config, "media.audio_cd.cddb_server", CDDB_SERVER, _("CDDB server name"), _("The CDDB server used to retrieve the title and track information from.\n" "This setting is security critical, because the sever will receive information " "about your listening habits and could answer the queries with malicious replies. " "Be sure to enter a server you can trust."), XINE_CONFIG_SECURITY, server_changed_cb, this); this->cddb_port = config->register_num (config, "media.audio_cd.cddb_port", CDDB_PORT, _("CDDB server port"), _("The server port used to retrieve the title and track information from."), XINE_CONFIG_SECURITY, port_changed_cb, this); #ifdef CDROM_SELECT_SPEED this->speed = config->register_num (config, "media.audio_cd.drive_slowdown", 4, _("slow down disc drive to this speed factor"), _("Since some CD or DVD drives make some really loud noises because of the " "fast disc rotation, xine will try to slow them down. With standard " "CD or DVD playback, the high datarates that require the fast rotation are " "not needed, so the slowdown should not affect playback performance.\n" "A value of zero here will disable the slowdown."), 10, speed_changed_cb, this); #endif pthread_mutex_init (&this->mutex, NULL); return this; } const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "CD", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/multirate_pref.c�������������������������������������������������������������0000644�0001750�0001750�00000010676�14647725152�016012� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2019-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ typedef struct { uint32_t video_width; uint32_t video_height; uint32_t bitrate; char lang[4]; } multirate_pref_t; static const char * const multirate_video_size_labels[] = { "Audio only", "Small", "SD", "HD", "Full HD", "4K", NULL }; static void multirate_set_video_size (multirate_pref_t *pref, int n) { static const uint32_t w[] = { 0, 360, 720, 1280, 1920, 3840 }; static const uint32_t h[] = { 0, 240, 576, 720, 1080, 2160 }; if ((n >= 0) && (n < (int)(sizeof (w) / sizeof (w[0])))) { pref->video_width = w[n]; pref->video_height = h[n]; } } static void multirate_cb_video_size (void *pref_gen, xine_cfg_entry_t *entry) { multirate_pref_t *pref = (multirate_pref_t *)pref_gen; multirate_set_video_size (pref, entry->num_value); } static void multirate_set_lang (multirate_pref_t *pref, const char *lang) { if (lang) strlcpy (pref->lang, lang, sizeof (pref->lang)); } static void multirate_cb_lang (void *pref_gen, xine_cfg_entry_t *entry) { multirate_pref_t *pref = (multirate_pref_t *)pref_gen; multirate_set_lang (pref, entry->str_value); } static void multirate_cb_bitrate (void *pref_gen, xine_cfg_entry_t *entry) { multirate_pref_t *pref = (multirate_pref_t *)pref_gen; pref->bitrate = entry->num_value; } static void multirate_pref_get (config_values_t *config, multirate_pref_t *pref) { multirate_set_video_size (pref, config->register_enum (config, "media.multirate.preferred_video_size", 3, (char **)multirate_video_size_labels, _("Preferred video size"), _("What size of video to play when there are multiple versions."), 10, multirate_cb_video_size, pref)); multirate_set_lang (pref, config->register_string (config, "media.multirate.preferred_language", "", _("Preferred language"), _("What language to play when there are multiple versions."), 10, multirate_cb_lang, pref)); pref->bitrate = config->register_num (config, "media.multirate.preferred_bitrate", 2000000, _("Preferred bitrate"), _("What bitrate to play when there are multiple versions of same size."), 10, multirate_cb_bitrate, pref); } static int multirate_autoselect (multirate_pref_t *pref, multirate_pref_t *list, int list_size) { multirate_pref_t *item; int w, h, n, best_n, best_s, best_b; if (list_size <= 0) return -1; if (list_size == 1) return 0; w = pref->video_width > 0 ? pref->video_width : 1; h = pref->video_height > 0 ? pref->video_height : 1; best_n = 0; best_s = 0x7fffffff; best_b = 0x7fffffff; item = list; for (n = 0; n < list_size; n++) { int dw, dh, s, b; b = item->bitrate - pref->bitrate; b = b < 0 ? -b : b; dw = item->video_width - w; dh = item->video_height - h; dw = dw < 0 ? -dw : dw; dh = dh < 0 ? -dh : dh; s = (dw << 10) / w + (dh << 10) / h; if (s < best_s) { best_b = b; best_n = n; best_s = s; } else if (s == best_s) { if (b < best_b) { best_n = n; best_b = b; } } item++; } return best_n; } static inline int multirate_audio_autoselect (multirate_pref_t *pref, multirate_pref_t *list, int list_size) { multirate_pref_t *item; int n, best_n, best_b; if (list_size <= 0) return -1; if (list_size == 1) return 0; best_n = -1; best_b = 0x7fffffff; for (item = list, n = 0; n < list_size; item++, n++) { int b; if ((item->video_width | item->video_height)) continue; b = item->bitrate - pref->bitrate; b = b < 0 ? -b : b; if (item->lang[0] && pref->lang[0] && strcasecmp (item->lang, pref->lang)) b += 0x40000000; if (b < best_b) { best_n = n; best_b = b; } } return best_n; } ������������������������������������������������������������������xine-lib-1.2/src/input/input_test.c�����������������������������������������������������������������0000644�0001750�0001750�00000054572�14647725152�015171� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2012-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* Torsten Jager <t.jager@gmx.de> The idea is: present a virtual directory filled with images. Create on demand in memory what the user actually tries to access. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #include <errno.h> #define LOG_MODULE "input_test" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/input_plugin.h> #include <xine/video_out.h> #include "input_helper.h" /* describe tests here */ static const char * const test_names[] = { "test://", "test://color_circle.bmp", "test://rgb_levels.bmp", "test://saturation_levels.bmp", "test://uv_square.bmp", "test://y_resolution.bmp", "test://color_circle.y4m", "test://rgb_levels.y4m", "test://saturation_levels.y4m", "test://uv_square.y4m", "test://y_resolution.y4m", "test://rgb_levels_fullrange.y4m", NULL }; static const char test_type[] = {2, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 2}; static const char test_is_yuv[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1}; static const char test_is_mpeg_range[] = {0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0}; #define TEST_FILES ((sizeof (test_names) / sizeof (char *)) - 1) typedef struct { input_class_t input_class; xine_t *xine; xine_mrl_t *mrls[TEST_FILES], m[TEST_FILES]; } test_input_class_t; typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; unsigned char *buf, *bmp_head, *y4m_head, *y4m_frame; off_t filesize, filepos, headsize, framesize; int bufsize, index; } test_input_plugin_t; /* TJ. the generator code - actually a cut down version of my "testvideo" project */ /* It also reminisces good old Amiga coding style - strictly integer math, no */ /* unnecessary memory allocations ... */ static void put32le (unsigned int v, unsigned char *p) { p[0] = v; p[1] = v >> 8; p[2] = v >> 16; p[3] = v >> 24; } /* square root */ static unsigned int isqr (unsigned int v) { unsigned int a, b = v, c = 0, e = 0; if (v == 0) return (0); while (b) {b >>= 2; c++;} a = 1 << (c - 1); c = 1 << c; while (a + 1 < c) { b = (a + c) >> 1; e = b * b; if (e <= v) a = b; else c = b; } return (a + (c * c - v < v - e ? 1 : 0)); } /* arcus tangens 0..24*255 */ static int iatan (int x, int y) { int a, b, v = 0; if ((x == 0) && (y == 0)) return (0); /* mirror to first half quadrant */ if (y < 0) {v = -24 * 255; y = -y;} if (x < 0) {v = -12 * 255 - v; x = -x;} if (x < y) {v = -6 * 255 - v; a = x; b = y;} else {a = y; b = x;} /* cubic interpolation within 32 bit */ v += (1027072 * a / b - 718 * a * a / b * 255 / b - 237 * a * a / b * a / b * 255 / b) >> 10; return (v < 0 ? -v : v); } /* absolute angle difference 0..180*255 */ static int adiff (int a, int b) { int d = a > b ? a - b : b - a; return (d < 12 * 255 ? d : 24 * 255 - d); } /* gimmick #2588: the XINE logo ;-) */ static void render_parallelogram (unsigned char *buf, int buf_width, int buf_height, unsigned int gray, int x, int y, int width, int height, int slant, int sc) { int i, o; int pitch = (3 * buf_width + 3) & ~3; if (height < 2) return; /* slant compensation */ if (sc) { i = (width * slant + height / 2) / height; width = isqr (width * width + i * i); } /* 3 bytes per pixel */ width *= 3; /* OK now render */ height--; for (i = 0; i <= height; i++) { o = (buf_height - 1 - y - i) * pitch + 3 * (x + (slant * i + height / 2) / height); memset (buf + o, gray, width); } } static void render_turn (unsigned char *buf, int buf_width, int buf_height, unsigned int gray, int x, int y, int size, int quad) { int cx = quad & 1 ? 0 : size; int cy = quad & 2 ? 0 : size; int i, j, d, e; int _min = size * size, _max = 4 * _min; unsigned char *p; int pitch = (3 * buf_width + 3) & ~3; for (i = 0; i < size; i++) { for (j = 0; j < size; j++) { d = 2 * (i - cy) + 1; d *= d; e = 2 * (j - cx) + 1; e *= e; d += e; if ((d < _min) || (d > _max)) continue; p = buf + (buf_height - 1 - y - i) * pitch + 3 * (x + j); *p++ = gray; *p++ = gray; *p = gray; } } } static void render_xine_logo (unsigned char *buf, int buf_width, int buf_height, unsigned int gray) { int height = buf_height / 30 >= 10 ? buf_height / 30 : 10; int width = height / 4; int top = buf_height - 2 * height; int left = buf_width - 4 * height - 3 * width; /* safety */ if ((top < 0) || (left < 0)) return; /* X */ render_parallelogram (buf, buf_width, buf_height, gray, left, top, width, height, height - width, 1); render_parallelogram (buf, buf_width, buf_height, gray, left + height - width, top, width, height, width - height, 1); left += height + width / 2; /* I */ render_parallelogram (buf, buf_width, buf_height, gray, left, top, width, height, 0, 0); left += 3 * width / 2; /* N */ render_parallelogram (buf, buf_width, buf_height, gray, left, top, width, height, 0, 0); render_parallelogram (buf, buf_width, buf_height, gray, left + width, top, height - 3 * width, width, 0, 0); render_turn (buf, buf_width, buf_height, gray, left + height - 2 * width, top, 2 * width, 1); render_parallelogram (buf, buf_width, buf_height, gray, left + height - width, top + 2 * width, width, height - 2 * width, 0, 0); left += height + width / 2; /* E */ render_turn (buf, buf_width, buf_height, gray, left, top, 2 * width, 0); render_parallelogram (buf, buf_width, buf_height, gray, left + 2 * width, top, height - 2 * width, width, 0, 0); render_parallelogram (buf, buf_width, buf_height, gray, left, top + 2 * width, width, height - 4 * width, 0, 0); render_parallelogram (buf, buf_width, buf_height, gray, left + width, top + (height - width) / 2, height - width, width, 0, 0); render_turn (buf, buf_width, buf_height, gray, left, top + height - 2 * width, 2 * width, 2); render_parallelogram (buf, buf_width, buf_height, gray, left + 2 * width, top + height - width, height - 2 * width, width, 0, 0); } static int test_make (test_input_plugin_t * this) { int width, height, x, y, cx, cy, d, r, dx, dy, a, red, green, blue; int type, yuv, mpeg; int pad, pitch; int angle = 0, hdtv = 0, gray = 0; unsigned char *p; /* mode */ type = test_type[this->index]; yuv = test_is_yuv[this->index]; mpeg = test_is_mpeg_range[this->index]; /* dimensions */ width = 320; if (this->stream && this->stream->video_out) { if (_x_lock_port_rewiring(this->stream->xine, 0)) { if (this->stream->video_out) { x = this->stream->video_out->get_property (this->stream->video_out, VO_PROP_WINDOW_WIDTH); if (x > width) width = x; } _x_unlock_port_rewiring(this->stream->xine); } } if (width > 1920) width = 1920; width &= ~1; height = width * 9 / 16; height &= ~1; /* BMP rows must be n * 4 bytes long */ pitch = (width * 3 + 3) & ~3; pad = pitch - width * 3; /* (re)allocate buffer */ a = 54 + pitch * height; if (yuv) { if (height >= 720) hdtv = 1; a += 88 + width * height * 3 / 2; } if (this->buf && (a != this->bufsize)) { free (this->buf); this->buf = NULL; } if (!this->buf) { this->buf = malloc (a); if (!this->buf) return (1); this->bufsize = a; } /* make file heads */ p = this->buf; this->bmp_head = p; this->filesize = 54 + pitch * height; if (yuv) { p += 54 + pitch * height; this->y4m_head = p; /* use inofficial extension to announce color matrix here ;-) */ this->headsize = sprintf (p, "YUV4MPEG2 W%d H%d F25:1 Ip A0:0 C420mpeg2 XYSCSS=420MPEG2 XXINE_CM=%d\n", width, height, (hdtv ? 2 : 10) | !mpeg); p += 82; this->y4m_frame = p; memcpy (p, "FRAME\n", 6); this->framesize = 6 + width * height * 3 / 2; this->filesize = this->headsize + 10 * 25 * this->framesize; } this->filepos = 0; p = this->bmp_head; memset (p, 0, 54); p[0] = 'B'; p[1] = 'M'; put32le (54 + pitch * height, p + 2); /* file size */ put32le (54, p + 10); /* header size */ put32le (40, p + 14); /* ?? */ put32le (width, p + 18); put32le (height, p + 22); p[26] = 1; /* ?? */ p[28] = 24; /* depth */ put32le (pitch * height, p + 34); /* bitmap size */ put32le (2835, p + 38); /* ?? */ put32le (2835, p + 42); /* ?? */ p += 54; /* generate RGB image */ switch (type) { case 1: /* color circle test */ cx = width >> 1; cy = height >> 1; r = width < height ? (width * 98) / 100 : (height * 98) / 100; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { dx = ((x - cx) << 1) + 1; dy = ((y - cy) << 1) + 1; d = isqr (dx * dx + dy * dy); if (d > r) red = green = blue = 128; else { a = (iatan (dx, dy) + angle) % (24 * 255); red = 8 * 255 - adiff (a, 0); red = red < 0 ? 0 : (red > 4 * 255 ? 4 * 255 : red); red = red * d / (4 * r); green = 8 * 255 - adiff (a, 8 * 255); green = green < 0 ? 0 : (green > 4 * 255 ? 4 * 255 : green); green = green * d / (4 * r); blue = 8 * 255 - adiff (a, 16 * 255); blue = blue < 0 ? 0 : (blue > 4 * 255 ? 4 * 255 : blue); blue = blue * d / (4 * r); } *p++ = blue; *p++ = green; *p++ = red; } for (x = pad; x; x--) *p++ = 0; } break; case 2: /* sweep bars */ dx = (((width + 9) / 18) + 1) & ~1; dy = (((height + 10) / 20) + 1) & ~1; cx = (width / 2 - 8 * dx) & ~1; cy = (height / 2 - 8 * dy) & ~1; /* bottom gray */ d = cy * pitch; memset (p, 127, d); p += d; /* color bars */ for (y = 0; y < 16; y++) { /* make 1 line */ unsigned char *q = p; for (x = 0; x < width; x++) { d = x - cx; if ((d < 0) || (d >= 16 * dx)) red = green = blue = 127; else { a = (y + 1) & 2 ? 17 * (15 - d / dx) : 255 - 16 * d / dx; red = y & 4 ? a : 0; green = y & 8 ? a : 0; blue = y & 2 ? a : 0; } *p++ = blue; *p++ = green; *p++ = red; } for (x = pad; x; x--) *p++ = 0; /* duplicate it further */ for (d = 1; d < dy; d++) { memcpy (p, q, pitch); p += pitch; } } /* top gray */ memset (p, 127, (height - cy - 16 * dy) * pitch); break; case 3: { /* sweep bars, saturation */ int g[] = {0, 29, 76, 105, 150, 179, 226, 255, 0, 18, 54, 73, 182, 201, 237, 255}; dx = (((width + 9) / 18) + 1) & ~1; dy = (((height + 10) / 20) + 1) & ~1; cx = (width / 2 - 8 * dx) & ~1; cy = (height / 2 - 8 * dy) & ~1; /* bottom gray */ d = cy * pitch; memset (p, 127, d); p += d; /* color bars */ for (y = 0; y < 16; y++) { /* make 1 line */ unsigned char *q = p; for (x = 0; x < width; x++) { d = x - cx; if ((d < 0) || (d >= 16 * dx)) red = green = blue = 127; else { a = (y + 1) & 2 ? 17 * (15 - d / dx) : 255 - 16 * d / dx; r = (255 - a) * g[y / 2 + 8 * hdtv]; red = ((y & 4 ? 255 : 0) * a + r) / 255; green = ((y & 8 ? 255 : 0) * a + r) / 255; blue = ((y & 2 ? 255 : 0) * a + r) / 255; } *p++ = blue; *p++ = green; *p++ = red; } for (x = pad; x; x--) *p++ = 0; /* duplicate it further */ for (d = 1; d < dy; d++) { memcpy (p, q, pitch); p += pitch; } } /* top gray */ memset (p, 127, (height - cy - 16 * dy) * pitch); } break; case 4: { /* UV square */ int m1 = hdtv ? 51603 : 45941; int m2 = hdtv ? -6138 : -11277; int m3 = hdtv ? -15339 : -23401; int m4 = hdtv ? 60804 : 58065; r = width < height ? width : height; r = (49 << 9) * r / 100; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { int min, max, u, v; u = (x << 1) - width + 1; v = (y << 1) - height + 1; min = max = red = m1 * v; green = m2 * u + m3 * v; if (green < min) min = green; else if (green > max) max = green; blue = m4 * u; if (blue < min) min = blue; else if (blue > max) max = blue; d = (256 * r + (r >> 1)) + min - max - 1; if (d < 0) red = green = blue = 127; else { if (gray == 255) min -= d - (r >> 1); else min -= d / 255 * gray - (r >> 1); red = (red - min) / r; green = (green - min) / r; blue = (blue - min) / r; } *p++ = blue; *p++ = green; *p++ = red; } for (x = pad; x; x--) *p++ = 0; } } break; case 5: /* resolution pattern */ dx = (width / 10); dy = (height / 7); for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { if ((x < dx) || (x >= 9 * dx)) red = 127; else { d = x / dx; switch (y / dy) { case 1: red = ((x / d) ^ (y / d)) & 1 ? 0 : 255; break; case 3: red = (x / d) & 1 ? 0 : 255; break; case 5: red = (y / d) & 1 ? 0 : 255; break; default: red = 127; } } *p++ = red; *p++ = red; *p++ = red; } for (x = pad; x; x--) *p++ = 0; } break; } /* add logo */ render_xine_logo (this->bmp_head + 54, width, height, 150); /* convert to YUV */ if (yuv) { int fb, fr, yb, yr, yg, yo, ubvr, vb, ur, ug, vg; int i, _yb[256], _yr[256], _yg[256]; int _ubvr[1024], _vb[1024], _ur[1024], _ug[1024], _vg[1024]; unsigned char *p2, *q, *q2; #define SSHIFT 17 #define SFACTOR (1 << SSHIFT) fb = hdtv ? 722 : 1140; fr = hdtv ? 2126 : 2990; if (mpeg) { yg = (SFACTOR * 219 + 127) / 255; yo = SFACTOR * 16 + SFACTOR / 2; ubvr = (SFACTOR * 112 + 127) / 255; } else { yg = SFACTOR; yo = SFACTOR / 2; ubvr = (SFACTOR * 127 + 127) / 255; } yb = (yg * fb + 5000) / 10000; yr = (yg * fr + 5000) / 10000; yg -= yb + yr; for (i = 0; i < 256; i++) { _yb[i] = yb * i; _yr[i] = yr * i; _yg[i] = yg * i + yo; } ur = (ubvr * fr + fb / 2 - 5000) / (fb - 10000); ug = -ur - ubvr; vb = (ubvr * fb + fr / 2 - 5000) / (fr - 10000); vg = -vb - ubvr; for (i = 0; i < 1024; i++) { _ubvr[i] = ubvr * i + 4 * (SFACTOR * 128 + SFACTOR / 2); _ur[i] = ur * i; _ug[i] = ug * i; _vb[i] = vb * i; _vg[i] = vg * i; } q = this->y4m_frame + 6; for (y = height - 1; y >= 0; y--) { p = this->bmp_head + 54 + y * pitch; for (x = width; x; x--) { *q++ = (_yb[p[0]] + _yg[p[1]] + _yr[p[2]]) >> SSHIFT; p += 3; } } q2 = q + width * height / 4; for (y = height - 2; y >= 0; y -= 2) { p = this->bmp_head + 54 + y * pitch; p2 = p + pitch; for (x = width / 2; x; x--) { blue = (unsigned int)*p++ + *p2++; green = (unsigned int)*p++ + *p2++; red = (unsigned int)*p++ + *p2++; blue += (unsigned int)*p++ + *p2++; green += (unsigned int)*p++ + *p2++; red += (unsigned int)*p++ + *p2++; *q++ = (_ubvr[blue] + _ug[green] + _ur[red]) >> (SSHIFT + 2); *q2++ = (_ubvr[red] + _vg[green] + _vb[blue]) >> (SSHIFT + 2); } } } /* add readable title */ { const char *test_titles[5] = { _("Colour Circle"), _("RGB Levels"), _("Saturation Levels"), _("UV Square"), _("Luminance Resolution") }; char *temp; temp = _x_asprintf ("%s [%s%s]", test_titles[type - 1], yuv ? (mpeg ? "" : "full swing ") : "", yuv ? (hdtv ? "ITU-R 709 YUV" : " ITU-R 601 YUV") : "RGB"); _x_meta_info_set (this->stream, XINE_META_INFO_TITLE, temp); free(temp); } return (1); } /* instance functions */ static off_t test_plugin_read (input_plugin_t *this_gen, void *buf, off_t len) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; if (!this->buf || (len < 0) || !buf) return -1; if (len > this->filesize - this->filepos) len = this->filesize - this->filepos; if (test_is_yuv[this->index]) { unsigned char *p = this->y4m_frame, *q = buf; off_t l = len, d; d = this->headsize - this->filepos; if (d > 0) { xine_fast_memcpy (q, this->y4m_head + this->filepos, d); q += d; this->filepos += d; l -= d; d = this->framesize; } else { d = (this->filepos - this->headsize) % this->framesize; p += d; d = this->framesize - d; } while (l > 0) { if (d > l) d = l; xine_fast_memcpy (q, p, d); p = this->y4m_frame; q += d; this->filepos += d; l -= d; d = this->framesize; } } else { xine_fast_memcpy (buf, this->bmp_head + this->filepos, len); this->filepos += len; } return len; } static off_t test_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; offset = _x_input_translate_seek(offset, origin, this->filepos, this->filesize); if (offset >= 0) { this->filepos = offset; } return offset; } static off_t test_plugin_get_current_pos (input_plugin_t *this_gen) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; return this->filepos; } static off_t test_plugin_get_length (input_plugin_t *this_gen) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; return this->filesize; } static const char *test_plugin_get_mrl (input_plugin_t *this_gen) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; return test_names[this->index]; } static void test_plugin_dispose (input_plugin_t *this_gen ) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; if (this->buf) free (this->buf); free (this); } static int test_plugin_open (input_plugin_t *this_gen ) { test_input_plugin_t *this = (test_input_plugin_t *) this_gen; return test_make (this); } static input_plugin_t *test_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { test_input_plugin_t *this; unsigned int i; for (i = 0; i < TEST_FILES; i++) { if (!strcasecmp (data, test_names[i])) break; } if (i == TEST_FILES) return NULL; this = (test_input_plugin_t *) calloc(1, sizeof (test_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->index = i; this->input_plugin.open = test_plugin_open; this->input_plugin.get_capabilities = _x_input_get_capabilities_seekable; this->input_plugin.read = test_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = test_plugin_seek; this->input_plugin.get_current_pos = test_plugin_get_current_pos; this->input_plugin.get_length = test_plugin_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = test_plugin_get_mrl; this->input_plugin.get_optional_data = _x_input_default_get_optional_data; this->input_plugin.dispose = test_plugin_dispose; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * plugin class functions */ static const char * const * test_get_autoplay_list (input_class_t *this_gen, int *num_files) { (void)this_gen; if (num_files) *num_files = TEST_FILES - 1; return test_names + 1; } static xine_mrl_t **test_class_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { test_input_class_t *this = (test_input_class_t *) this_gen; unsigned int i; xine_mrl_t *m; (void)filename; if (!this->mrls[0]) { for (i = 0; i < TEST_FILES - 1; i++) { m = &this->m[i]; this->mrls[i] = m; m->origin = (char *)test_names[0]; m->mrl = (char *)test_names[i + 1]; m->link = NULL; m->type = mrl_file | mrl_file_normal; m->size = 54 + 1024 * 576 * 3; /* for true size, call test_plugin_get_length () */ } this->mrls[i] = NULL; } if (nFiles) *nFiles = TEST_FILES - 1; return this->mrls; } static void test_class_dispose (input_class_t *this_gen) { free (this_gen); } static void *test_init_plugin (xine_t *xine, const void *data) { test_input_class_t *this; (void)data; this = (test_input_class_t *) calloc(1, sizeof (test_input_class_t)); if (!this) return NULL; this->xine = xine; this->input_class.get_instance = test_class_get_instance; this->input_class.identifier = "test"; this->input_class.description = N_("test card input plugin"); this->input_class.get_dir = test_class_get_dir; this->input_class.get_autoplay_list = test_get_autoplay_list; this->input_class.dispose = test_class_dispose; this->input_class.eject_media = NULL; return this; } static const input_info_t input_info_test = { .priority = 110 }; /* * exported plugin catalog entry */ #define INPUT_TEST_CATALOG { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "TEST", XINE_VERSION_CODE, &input_info_test, test_init_plugin } #ifndef XINE_MAKE_BUILTINS const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ INPUT_TEST_CATALOG, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif ��������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_file.c�����������������������������������������������������������������0000644�0001750�0001750�00000071455�14647725152�015130� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #ifdef HAVE_DIRENT_H #include <dirent.h> #endif #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <time.h> #include <errno.h> #ifdef HAVE_MMAP #include <sys/mman.h> #endif #define LOG_MODULE "input_file" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/input_plugin.h> #include "input_helper.h" #define MAXFILES 65535 #ifndef WIN32 /* MS needs O_BINARY to open files, for everyone else, * make sure it doesn't get in the way */ # define O_BINARY 0 #endif typedef struct { input_class_t input_class; xine_t *xine; const char *origin_path; int mrls_allocated_entries; xine_mrl_t **mrls; } file_input_class_t; typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; int fh; enum { FILE_STATIC = 0, FILE_PROGRESSIVE, FILE_DONE } state; off_t size; #ifdef HAVE_MMAP int mmap_on; uint8_t *mmap_base; uint8_t *mmap_curr; off_t mmap_len; #endif char *mrl; } file_input_plugin_t; static void file_input_size (file_input_plugin_t *this, const struct stat *sbuf) { if ((sbuf->st_size != this->size) && #ifdef HAVE_MMAP !this->mmap_on && #endif (this->state != FILE_PROGRESSIVE) && S_ISREG (sbuf->st_mode)) { this->state = FILE_PROGRESSIVE; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": \"%s\" changed size, will wait for possible updates.\n", this->mrl); } this->size = sbuf->st_size; } static uint32_t file_input_get_capabilities (input_plugin_t *this_gen) { struct stat buf ; file_input_plugin_t *this = (file_input_plugin_t *) this_gen; if (this->fh <0) return 0; #ifdef _MSC_VER /*return INPUT_CAP_SEEKABLE | INPUT_CAP_GET_DIR;*/ return INPUT_CAP_CLONE | INPUT_CAP_SEEKABLE; #else if (fstat (this->fh, &buf) == 0) { file_input_size (this, &buf); if (S_ISREG(buf.st_mode)) return INPUT_CAP_CLONE | INPUT_CAP_SEEKABLE; else return 0; } else { int e = errno; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": fstat (): %s.\n", strerror (e)); } return 0; #endif /* _MSC_VER */ } #ifdef HAVE_MMAP /** * @brief Check if the file can be read through mmap(). * @param this The instance of the input plugin to check * with * @return 1 if the file can still be mmapped, 0 if the file * changed size */ static int file_input_check_mmap (file_input_plugin_t *this) { struct stat sbuf; if ( ! this->mmap_on ) return 0; if ( fstat (this->fh, &sbuf) != 0 ) { return 0; } /* If the file grew, we're most likely dealing with a timeshifting recording * so switch to normal access. */ if ( this->mmap_len != sbuf.st_size ) { this->mmap_on = 0; lseek(this->fh, this->mmap_curr - this->mmap_base, SEEK_SET); return 0; } file_input_size (this, &sbuf); return 1; } #endif static off_t file_input_read (input_plugin_t *this_gen, void *buf, off_t len) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; uint8_t *b; ssize_t r, left; int try; if (len < 0) return -1; #ifdef HAVE_MMAP if ( file_input_check_mmap(this) ) { off_t l = len; if ( (this->mmap_curr + len) > (this->mmap_base + this->mmap_len) ) l = (this->mmap_base + this->mmap_len) - this->mmap_curr; memcpy(buf, this->mmap_curr, l); this->mmap_curr += l; return l; } #endif b = (uint8_t *)buf; left = len; r = 0; while (left > 0) { r = read (this->fh, b, left); if (r <= 0) break; b += r; left -= r; } if (r < 0) return r; r = b - (uint8_t *)buf; if (r == len) return len; /* poll for updates only when playing, dont delay plain xine_open (). */ if (this->state != FILE_PROGRESSIVE) return r; if (!_x_demux_called_from (this->stream)) return r; try = 2 - 1; while (left > 0) { /* _x_io_select (, this->fh, ) tends to return XIO_READY immediately. */ if (_x_io_select (this->stream, -1, XIO_READ_READY, 1000) == XIO_ABORTED) break; r = read (this->fh, b, left); if (r > 0) { try = 2 - 1; b += r; left -= r; } else if (r < 0) { return r; } else if (--try < 0) { break; } } r = b - (uint8_t *)buf; if (r != len) { this->state = FILE_DONE; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": \"%s\": no update, assuming real EOF.\n", this->mrl); } return r; } static buf_element_t *file_input_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { #ifdef HAVE_MMAP file_input_plugin_t *this = (file_input_plugin_t *) this_gen; if ( file_input_check_mmap(this) ) { buf_element_t *buf = fifo->buffer_pool_alloc (fifo); off_t len = todo; if (todo > buf->max_size) todo = buf->max_size; if (todo < 0) { buf->free_buffer (buf); return NULL; } buf->type = BUF_DEMUX_BLOCK; if ( (this->mmap_curr + len) > (this->mmap_base + this->mmap_len) ) len = (this->mmap_base + this->mmap_len) - this->mmap_curr; /* We use the still-mmapped file rather than copying it */ buf->size = len; buf->content = this->mmap_curr; /* FIXME: it's completely illegal to free buffer->mem here * - buffer->mem has not been allocated by malloc * - demuxers expect buffer->mem != NULL */ /* free(buf->mem); buf->mem = NULL; */ this->mmap_curr += len; return buf; } #endif return _x_input_default_read_block(this_gen, fifo, todo); } static off_t file_input_seek (input_plugin_t *this_gen, off_t offset, int origin) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; #ifdef HAVE_MMAP /* Simulate f*() library calls */ if ( file_input_check_mmap(this) ) { uint8_t *new_point = this->mmap_curr; switch(origin) { case SEEK_SET: new_point = this->mmap_base + offset; break; case SEEK_CUR: new_point = this->mmap_curr + offset; break; case SEEK_END: new_point = this->mmap_base + this->mmap_len + offset; break; default: errno = EINVAL; return (off_t)-1; } if ( new_point < this->mmap_base || new_point > (this->mmap_base + this->mmap_len) ) { errno = EINVAL; return (off_t)-1; } this->mmap_curr = new_point; return (this->mmap_curr - this->mmap_base); } #endif return lseek (this->fh, offset, origin); } static off_t file_input_get_current_pos (input_plugin_t *this_gen){ file_input_plugin_t *this = (file_input_plugin_t *) this_gen; if (this->fh <0) return 0; #ifdef HAVE_MMAP if ( file_input_check_mmap(this) ) return (this->mmap_curr - this->mmap_base); #endif return lseek (this->fh, 0, SEEK_CUR); } static off_t file_input_get_length (input_plugin_t *this_gen) { struct stat buf ; file_input_plugin_t *this = (file_input_plugin_t *) this_gen; if (this->fh <0) return 0; #ifdef HAVE_MMAP if ( file_input_check_mmap(this) ) return this->mmap_len; #endif if (fstat (this->fh, &buf) == 0) { file_input_size (this, &buf); return buf.st_size; } else perror ("system call fstat"); return 0; } /* * Return 1 if filepathname is a directory, otherwise 0 */ static int file_input_is_dir (const char *filepathname) { struct stat pstat; if (stat(filepathname, &pstat) < 0) return 0; return (S_ISDIR(pstat.st_mode)); } static const char* file_input_get_mrl (input_plugin_t *this_gen) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; return this->mrl; } static void file_input_dispose (input_plugin_t *this_gen ) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; #ifdef HAVE_MMAP /* Check for mmap_base rather than mmap_on because the file might have * started as a mmap() and now might be changed to descriptor-based * access */ if ( this->mmap_base ) munmap(this->mmap_base, this->mmap_len); #endif if (this->fh != -1) close(this->fh); _x_freep (&this->mrl); free (this); } static char *file_input_decode_uri (char *uri) { uri = strdup(uri); if (uri) _x_mrl_unescape (uri); return uri; } static int file_input_open (input_plugin_t *this_gen ) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; char *filename; struct stat sbuf; int sres; lprintf("file_input_open\n"); if (strncasecmp (this->mrl, "file:/", 6) == 0) { if (strncasecmp (this->mrl, "file://localhost/", 16) == 0) filename = file_input_decode_uri(&(this->mrl[16])); else if (strncasecmp (this->mrl, "file://127.0.0.1/", 16) == 0) filename = file_input_decode_uri(&(this->mrl[16])); else filename = file_input_decode_uri(&(this->mrl[5])); } else filename = strdup(this->mrl); /* NEVER unescape plain file names! */ if (!filename) return -1; this->fh = xine_open_cloexec (filename, O_RDONLY | O_BINARY); _x_freep (&filename); if (this->fh == -1) { if (errno == EACCES) { _x_message(this->stream, XINE_MSG_PERMISSION_ERROR, this->mrl, NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_file: Permission denied: >%s<\n"), this->mrl); } else if (errno == ENOENT) { _x_message(this->stream, XINE_MSG_FILE_NOT_FOUND, this->mrl, NULL); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_file: File not found: >%s<\n"), this->mrl); } return -1; } sres = fstat (this->fh, &sbuf); if (!sres) { this->size = sbuf.st_size; if (S_ISREG (sbuf.st_mode)) { time_t now = time (NULL); if ((sbuf.st_mtime <= now) && (sbuf.st_mtime + 10 >= now)) { this->state = FILE_PROGRESSIVE; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": \"%s\" is quite recent, will wait for possible updates.\n", this->mrl); } } } #ifdef HAVE_MMAP this->mmap_on = 0; this->mmap_base = NULL; this->mmap_curr = NULL; this->mmap_len = 0; #endif /* don't check length of fifo or character device node */ if (!sres && !S_ISREG (sbuf.st_mode)) return 1; #ifdef HAVE_MMAP this->mmap_base = NULL; do { uint8_t *mmap_base; size_t tmp_size; /* may cause truncation - if it does, DON'T mmap! */ tmp_size = (size_t)sbuf.st_size; if ((off_t)tmp_size != sbuf.st_size) break; mmap_base = mmap (NULL, tmp_size, PROT_READ, MAP_SHARED, this->fh, 0); if (mmap_base == (void*)-1) break; /* paranoia */ sres = fstat (this->fh, &sbuf); if (sres || (off_t)tmp_size != sbuf.st_size) { munmap (mmap_base, tmp_size); break; } this->mmap_on = 1; this->mmap_base = this->mmap_curr = mmap_base; this->mmap_len = sbuf.st_size; } while (0); #endif if (file_input_get_length (this_gen) == 0) { _x_message(this->stream, XINE_MSG_FILE_EMPTY, this->mrl, NULL); close (this->fh); this->fh = -1; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_file: File empty: >%s<\n"), this->mrl); return -1; } return 1; } static int file_input_get_optional_data (input_plugin_t *this_gen, void *data, int data_type); static input_plugin_t *file_input_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { /* file_input_class_t *cls = (file_input_class_t *) cls_gen; */ file_input_plugin_t *this; lprintf("file_input_get_instance\n"); if ((strncasecmp (mrl, "file:", 5)) && strstr (mrl, ":/") && (strstr (mrl, ":/") < strchr(mrl, '/'))) { return NULL; } this = (file_input_plugin_t *) calloc(1, sizeof (file_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->mrl = strdup(mrl); this->fh = -1; this->state = FILE_STATIC; this->size = 0; this->input_plugin.open = file_input_open; this->input_plugin.get_capabilities = file_input_get_capabilities; this->input_plugin.read = file_input_read; this->input_plugin.read_block = file_input_read_block; this->input_plugin.seek = file_input_seek; this->input_plugin.get_current_pos = file_input_get_current_pos; this->input_plugin.get_length = file_input_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = file_input_get_mrl; this->input_plugin.get_optional_data = file_input_get_optional_data; this->input_plugin.dispose = file_input_dispose; this->input_plugin.input_class = cls_gen; if (!this->mrl) { free(this); return NULL; } return &this->input_plugin; } static int file_input_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { if ((data_type == INPUT_OPTIONAL_DATA_CLONE) && data) { file_input_plugin_t *this = (file_input_plugin_t *) this_gen; input_plugin_t *new = file_input_get_instance (this->input_plugin.input_class, this->stream, this->mrl); if (new) { if (new->open (new) < 0) { new->dispose (new); } else { input_plugin_t **q = data; *q = new; return INPUT_OPTIONAL_SUCCESS; } } } return INPUT_OPTIONAL_UNSUPPORTED; } /* * plugin class functions */ #ifndef S_ISLNK #define S_ISLNK(mode) 0 #endif #ifndef S_ISFIFO #define S_ISFIFO(mode) 0 #endif #ifndef S_ISSOCK #define S_ISSOCK(mode) 0 #endif #ifndef S_ISCHR #define S_ISCHR(mode) 0 #endif #ifndef S_ISBLK #define S_ISBLK(mode) 0 #endif #ifndef S_ISREG #define S_ISREG(mode) 0 #endif #if !S_IXUGO #define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) #endif /* * Callback for config changes. */ static void file_input_origin_change_cb (void *data, xine_cfg_entry_t *cfg) { file_input_class_t *this = (file_input_class_t *) data; this->origin_path = cfg->str_value; } /* * Sorting function, it comes from GNU fileutils package. */ #define S_N 0x0 #define S_I 0x4 #define S_F 0x8 #define S_Z 0xC #define CMP 2 #define LEN 3 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) static int file_input_strverscmp (const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; unsigned char c1, c2; int state; int diff; static const unsigned int next_state[] = { S_N, S_I, S_Z, S_N, S_N, S_I, S_I, S_I, S_N, S_F, S_F, S_F, S_N, S_F, S_Z, S_Z }; static const int result_type[] = { CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, -1, -1, CMP, 1, LEN, LEN, CMP, 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 1, 1, CMP, -1, CMP, CMP, CMP, -1, CMP, CMP, CMP }; if(p1 == p2) return 0; c1 = *p1++; c2 = *p2++; state = S_N | ((c1 == '0') + (ISDIGIT(c1) != 0)); while((diff = c1 - c2) == 0 && c1 != '\0') { state = next_state[state]; c1 = *p1++; c2 = *p2++; state |= (c1 == '0') + (ISDIGIT(c1) != 0); } state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT(c2) != 0))]; switch(state) { case CMP: return diff; case LEN: while(ISDIGIT(*p1++)) if(!ISDIGIT(*p2++)) return 1; return ISDIGIT(*p2) ? -1 : diff; default: return state; } } /* * Wrapper to file_input_strverscmp() for qsort() calls, which sort mrl_t type array. */ static int file_input_sortfiles_default (const xine_mrl_t *s1, const xine_mrl_t *s2) { return(file_input_strverscmp(s1->mrl, s2->mrl)); } /* * Return the type (OR'ed) of the given file *fully named* */ static uint32_t file_input_get_file_type (char *filepathname, char *origin, xine_t *xine) { struct stat pstat; int mode; uint32_t file_type = 0; char buf[XINE_PATH_MAX + XINE_NAME_MAX + 1]; (void)xine; if((lstat(filepathname, &pstat)) < 0) { snprintf_buf(buf, "%s/%s", origin, filepathname); if((lstat(buf, &pstat)) < 0) { lprintf ("lstat failed for %s{%s}\n", filepathname, origin); file_type |= mrl_unknown; return file_type; } } file_type |= mrl_file; mode = pstat.st_mode; if(S_ISLNK(mode)) file_type |= mrl_file_symlink; else if(S_ISDIR(mode)) file_type |= mrl_file_directory; else if(S_ISCHR(mode)) file_type |= mrl_file_chardev; else if(S_ISBLK(mode)) file_type |= mrl_file_blockdev; else if(S_ISFIFO(mode)) file_type |= mrl_file_fifo; else if(S_ISSOCK(mode)) file_type |= mrl_file_sock; else { if(S_ISREG(mode)) { file_type |= mrl_file_normal; } if(mode & S_IXUGO) file_type |= mrl_file_exec; } if(filepathname[strlen(filepathname) - 1] == '~') file_type |= mrl_file_backup; return file_type; } /* * Return the file size of the given file *fully named* */ static off_t file_input_get_file_size (const char *filepathname, const char *origin) { struct stat pstat; char buf[XINE_PATH_MAX * 2 + XINE_NAME_MAX + 3]; if((lstat(filepathname, &pstat)) < 0) { snprintf_buf(buf, "%s/%s", origin, filepathname); if((lstat(buf, &pstat)) < 0) return (off_t) 0; } return pstat.st_size; } static xine_mrl_t **file_input_class_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { /* FIXME: this code needs cleanup badly */ file_input_class_t *this = (file_input_class_t *) this_gen; struct dirent *pdirent; DIR *pdir; xine_mrl_t *hide_files, *dir_files, *norm_files; char current_dir[XINE_PATH_MAX + 1]; char current_dir_slashed[XINE_PATH_MAX + 2]; char fullfilename[XINE_PATH_MAX + XINE_NAME_MAX + 2]; int num_hide_files = 0; int num_dir_files = 0; int num_norm_files = 0; int num_files = -1; int (*func) () = file_input_sortfiles_default; int already_tried = 0; int show_hidden_files; *nFiles = 0; memset(current_dir, 0, sizeof(current_dir)); show_hidden_files = _x_input_get_show_hidden_files(this->xine->config); /* * No origin location, so got the content of the current directory */ if(!filename) { snprintf_buf(current_dir, "%s", this->origin_path); } else { snprintf_buf(current_dir, "%s", filename); /* Remove exceed '/' */ while((current_dir[strlen(current_dir) - 1] == '/') && strlen(current_dir) > 1) current_dir[strlen(current_dir) - 1] = '\0'; } /* Store new origin path */ try_again_from_home: this->xine->config->update_string(this->xine->config, "media.files.origin_path", current_dir); if(strcasecmp(current_dir, "/")) snprintf_buf(current_dir_slashed, "%s/", current_dir); else strcpy(current_dir_slashed, "/"); /* * Ooch! */ if((pdir = opendir(current_dir)) == NULL) { if(!already_tried) { /* Try one more time with user homedir */ snprintf_buf(current_dir, "%s", xine_get_homedir()); already_tried++; goto try_again_from_home; } return NULL; } dir_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t)); hide_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t)); norm_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t)); if (dir_files && hide_files && norm_files) while((pdirent = readdir(pdir)) != NULL) { memset(fullfilename, 0, sizeof(fullfilename)); snprintf_buf(fullfilename, "%s/%s", current_dir, pdirent->d_name); if(file_input_is_dir(fullfilename)) { /* if user don't want to see hidden files, ignore them */ if (show_hidden_files == 0 && ((strlen(pdirent->d_name) > 1) && (pdirent->d_name[0] == '.' && pdirent->d_name[1] != '.'))) { ; } else { dir_files[num_dir_files].origin = strdup(current_dir); dir_files[num_dir_files].mrl = _x_asprintf("%s%s", current_dir_slashed, pdirent->d_name); dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = file_input_get_file_type(fullfilename, current_dir, this->xine); dir_files[num_dir_files].size = file_input_get_file_size(fullfilename, current_dir); /* The file is a link, follow it */ if(dir_files[num_dir_files].type & mrl_file_symlink) { char linkbuf[XINE_PATH_MAX + XINE_NAME_MAX + 1]; int linksize; memset(linkbuf, 0, sizeof(linkbuf)); linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX); if(linksize < 0) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_file: readlink() failed: %s\n", strerror(errno)); else { dir_files[num_dir_files].link = strndup(linkbuf, linksize); dir_files[num_dir_files].type |= file_input_get_file_type(dir_files[num_dir_files].link, current_dir, this->xine); } } num_dir_files++; } } /* Hmmmm, an hidden file ? */ else if((strlen(pdirent->d_name) > 1) && (pdirent->d_name[0] == '.' && pdirent->d_name[1] != '.')) { /* if user don't want to see hidden files, ignore them */ if (show_hidden_files) { hide_files[num_hide_files].origin = strdup(current_dir); hide_files[num_hide_files].mrl = _x_asprintf("%s%s", current_dir_slashed, pdirent->d_name); hide_files[num_hide_files].link = NULL; hide_files[num_hide_files].type = file_input_get_file_type(fullfilename, current_dir, this->xine); hide_files[num_hide_files].size = file_input_get_file_size(fullfilename, current_dir); /* The file is a link, follow it */ if(hide_files[num_hide_files].type & mrl_file_symlink) { char linkbuf[XINE_PATH_MAX + XINE_NAME_MAX + 1]; int linksize; memset(linkbuf, 0, sizeof(linkbuf)); linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX); if(linksize < 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_file: readlink() failed: %s\n", strerror(errno)); } else { hide_files[num_hide_files].link = strndup(linkbuf, linksize); hide_files[num_hide_files].type |= file_input_get_file_type(hide_files[num_hide_files].link, current_dir, this->xine); } } num_hide_files++; } } /* So a *normal* one. */ else { norm_files[num_norm_files].origin = strdup(current_dir); norm_files[num_norm_files].mrl = _x_asprintf("%s%s", current_dir_slashed, pdirent->d_name); norm_files[num_norm_files].link = NULL; norm_files[num_norm_files].type = file_input_get_file_type(fullfilename, current_dir, this->xine); norm_files[num_norm_files].size = file_input_get_file_size(fullfilename, current_dir); /* The file is a link, follow it */ if(norm_files[num_norm_files].type & mrl_file_symlink) { char linkbuf[XINE_PATH_MAX + XINE_NAME_MAX + 1]; int linksize; memset(linkbuf, 0, sizeof(linkbuf)); linksize = readlink(fullfilename, linkbuf, XINE_PATH_MAX + XINE_NAME_MAX); if(linksize < 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_file: readlink() failed: %s\n", strerror(errno)); } else { norm_files[num_norm_files].link = strndup(linkbuf, linksize); norm_files[num_norm_files].type |= file_input_get_file_type(norm_files[num_norm_files].link, current_dir, this->xine); } } num_norm_files++; } num_files++; } closedir(pdir); /* * Ok, there are some files here, so sort * them then store them into global mrls array. */ if(num_files > 0) { int i; num_files = 0; /* * Sort arrays */ if(num_dir_files) qsort(dir_files, num_dir_files, sizeof(xine_mrl_t), func); if(num_hide_files) qsort(hide_files, num_hide_files, sizeof(xine_mrl_t), func); if(num_norm_files) qsort(norm_files, num_norm_files, sizeof(xine_mrl_t), func); /* * Add directories entries */ for(i = 0; i < num_dir_files; i++) { if(num_files >= this->mrls_allocated_entries) { ++this->mrls_allocated_entries; this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*)); this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t)); } else MRL_ZERO(this->mrls[num_files]); *(this->mrls[num_files]) = dir_files[i]; num_files++; } /* * Add hidden files entries */ for(i = 0; i < num_hide_files; i++) { if(num_files >= this->mrls_allocated_entries) { ++this->mrls_allocated_entries; this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*)); this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t)); } else MRL_ZERO(this->mrls[num_files]); *(this->mrls[num_files]) = hide_files[i]; num_files++; } /* * Add other files entries */ for(i = 0; i < num_norm_files; i++) { if(num_files >= this->mrls_allocated_entries) { ++this->mrls_allocated_entries; this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*)); this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t)); } else MRL_ZERO(this->mrls[num_files]); *(this->mrls[num_files]) = norm_files[i]; num_files++; } /* Some cleanups before leaving */ free(dir_files); free(hide_files); free(norm_files); } else { free(hide_files); free(dir_files); free(norm_files); return NULL; } /* * Inform caller about files found number. */ *nFiles = num_files; /* * Freeing exceeded mrls if exists. */ while(this->mrls_allocated_entries > num_files) { this->mrls_allocated_entries--; MRL_ZERO(this->mrls[this->mrls_allocated_entries]); _x_freep(&this->mrls[this->mrls_allocated_entries]); } /* * This is useful to let UI know where it should stops ;-). */ this->mrls[num_files] = NULL; /* * Some debugging info */ /* { int j = 0; while(this->mrls[j]) { printf("mrl[%d] = '%s'\n", j, this->mrls[j]->mrl); j++; } } */ return this->mrls; } static void file_input_class_dispose (input_class_t *this_gen) { file_input_class_t *this = (file_input_class_t *) this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); while(this->mrls_allocated_entries) { this->mrls_allocated_entries--; MRL_ZERO(this->mrls[this->mrls_allocated_entries]); _x_freep(&this->mrls[this->mrls_allocated_entries]); } _x_freep (&this->mrls); free (this); } static void *file_input_init_plugin (xine_t *xine, const void *data) { file_input_class_t *this; config_values_t *config; (void)data; this = (file_input_class_t *) calloc(1, sizeof (file_input_class_t)); if (!this) return NULL; this->xine = xine; config = xine->config; this->input_class.get_instance = file_input_get_instance; this->input_class.identifier = "file"; this->input_class.description = N_("file input plugin"); this->input_class.get_dir = file_input_class_get_dir; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = file_input_class_dispose; this->input_class.eject_media = NULL; this->mrls = (xine_mrl_t **) calloc(1, sizeof(xine_mrl_t*)); this->mrls_allocated_entries = 0; { char current_dir[XINE_PATH_MAX + 1]; if(getcwd(current_dir, sizeof(current_dir)) == NULL) strcpy(current_dir, "."); this->origin_path = config->register_filename(config, "media.files.origin_path", current_dir, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("file browsing start location"), _("The browser to select the file to play will " "start at this location."), 0, file_input_origin_change_cb, (void *) this); } _x_input_register_show_hidden_files(config); return this; } /* * exported plugin catalog entry */ #define INPUT_FILE_CATALOG { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "FILE", XINE_VERSION_CODE, NULL, file_input_init_plugin } #ifndef XINE_MAKE_BUILTINS const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ INPUT_FILE_CATALOG, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_mpegdash.c�������������������������������������������������������������0000644�0001750�0001750�00000126442�14647725152�015776� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2021-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <pthread.h> #define LOG_MODULE "input_mpegdash" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/input_plugin.h> #include <xine/stree.h> #include <xine/mfrag.h> #include <xine/io_helper.h> #include "http_helper.h" #include "input_helper.h" #include "group_network.h" #include "multirate_pref.c" typedef struct { input_class_t input_class; xine_t *xine; multirate_pref_t pref; } mpd_input_class_t; typedef struct { uint32_t mime, sfile, init, media, id; /** << offs into stree buf */ #define MPD_TYPE_AUDIO 1 #define MPD_TYPE_VIDEO 2 #define MPD_TYPE_SUBT 4 uint32_t type; uint32_t index_p, index_as, index_r; /** << xine_stree_t units */ uint32_t timebase; /** << units/second */ uint32_t bitrate; /** << bits/second */ uint32_t samplerate; /** << audio_samples/second */ uint32_t w, h; /** << video pixels */ uint32_t frag_start; /** << frag number offset */ uint32_t frag_duration; /** << timebase units */ uint32_t frag_count; /** << 0 in live mode */ xine_rats_t fd; /** << shortened frag_duration / timebase */ } mpd_stream_info_t; typedef enum { MPD_LIVE = 0, MPD_SINGLE_LIVE, MPD_INIT_LIVE, MPD_VOD, MPD_SINGLE_VOD, MPD_INIT_VOD, MPD_MODE_LAST } mpd_mode_t; #define MPD_IS_LIVE(this) ((this->mode == MPD_LIVE) || (this->mode == MPD_SINGLE_LIVE) || (this->mode == MPD_INIT_LIVE)) static const char *mpd_mode_names[MPD_MODE_LAST] = { [MPD_LIVE] = "non seekable live mode", [MPD_SINGLE_LIVE] = "non seekable single file live mode", [MPD_INIT_LIVE] = "non seekable live mode with init fragment", [MPD_VOD] = "seekable VOD mode", [MPD_SINGLE_VOD] = "seekable single file VOD mode", [MPD_INIT_VOD] = "seekable VOD mode with init fragment" }; typedef struct mpd_input_plugin_s { input_plugin_t input_plugin; xine_stream_t *stream; xine_nbc_t *nbc; struct mpd_input_plugin_s *main_input; input_plugin_t *in1; uint32_t caps1; uint32_t side_index; /** << 0..3 */ uint32_t num_sides; struct { pthread_mutex_t mutex; struct timespec avail_start, play_start; /** << from stream, since 1970 */ struct timespec sys_lag; /** << sys_time_at_play_start - play_start */ int lag; /** pts */ uint32_t type; int init; int refs; } sync; /** set by main input, used by sides */ int lag; /** pts */ int rewind; /** seconds */ xine_stree_t *tree; char *list_buf; xine_stree_mode_t tmode; uint32_t base_url, seg_base_url, time_url; /** << offs into stree buf */ int64_t frag_num; /** << derived from manifest */ uint32_t frag_index; /** << 0 (init), 1...n (real frags) */ uint32_t frag_mrl_1; /** << [foo/bar_]12345.mp4 */ uint32_t frag_mrl_2; /** << foo/bar_[12345].mp4 */ uint32_t frag_mrl_3; /** << foo/ber_12345[.mp4] */ #define MPD_MAX_SIDES 4 #define MPD_MAX_REPR 16 uint8_t side_have_streams[MPD_MAX_SIDES][MPD_MAX_REPR]; #define MPD_MAX_STREAMS 32 uint32_t num_streams, used_stream; mpd_stream_info_t info; mpd_stream_info_t streams[MPD_MAX_STREAMS]; multirate_pref_t items[MPD_MAX_STREAMS]; xine_mfrag_list_t *fraglist; off_t pos, frag_pos, all_size; uint32_t frag_size; uint32_t prev_size1; /** << the actual preview bytes, for INPUT_OPTIONAL_DATA_[SIZED]_PREVIEW. */ uint32_t prev_size2; /** << for read (), 0 after leaving that range. */ uint32_t list_bsize; uint32_t duration; mpd_mode_t mode; #define MPD_MAX_MRL 4096 char manifest_mrl[MPD_MAX_MRL]; char list_mrl[MPD_MAX_MRL]; char item_mrl[MPD_MAX_MRL]; #define MPD_PREVIEW_SIZE (32 << 10) char preview[MPD_PREVIEW_SIZE]; } mpd_input_plugin_t; #ifdef HAVE_POSIX_TIMERS # define xine_gettime(t) clock_gettime (CLOCK_REALTIME, t) #else static inline int xine_gettime (struct timespec *ts) { struct timeval tv; int r; r = gettimeofday (&tv, NULL); if (!r) { ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; } return r; } #endif static uint32_t str2uint32 (char **s) { uint8_t *p = (uint8_t *)*s; uint32_t v = 0; uint8_t z; while ((z = *p ^ '0') < 10) { v = v * 10u + z; p++; } *s = (char *)p; return v; } static char *mpd_strcasestr (const char *haystack, const char *needle) { const char *n; size_t ln; char z; if (!haystack) return NULL; if (!needle) return (char *)haystack; if (!needle[0]) return (char *)haystack; n = haystack; needle++; ln = strlen (needle); z = needle[-1] | 0x20; if ((z >= 'a') && (z <= 'z')) { while ((n = strchr (n, z))) { if (!strncasecmp (n + 1, needle, ln)) return (char *)n; n++; } z &= 0xdf; n = haystack; } else { z = needle[-1]; } while ((n = strchr (n, z))) { if (!strncasecmp (n + 1, needle, ln)) return (char *)n; n++; } return NULL; } static int mpd_build_mrl (mpd_input_plugin_t *this, const char *name) { const char *p, *b; char *q, *e; _x_merge_mrl (this->item_mrl, MPD_MAX_MRL, this->list_buf + this->base_url, name); q = this->list_mrl; e = q + MPD_MAX_MRL; p = this->item_mrl; while ((b = mpd_strcasestr (p, "$RepresentationId$"))) { size_t l = b - p; if (l >= (size_t)(e - q)) return 0; if (l) { memcpy (q, p, l); q += l; } p = b + strlen ("$RepresentationId$"); q += strlcpy (q, this->list_buf + this->info.id, e - q); if (q >= e) return 0; } q += strlcpy (q, p, e - q); if (q >= e) return 0; _x_merge_mrl (this->item_mrl, MPD_MAX_MRL, this->manifest_mrl, this->list_mrl); return 1; } static void mpd_prepare_fragnum (mpd_input_plugin_t *this) { const char *b = mpd_strcasestr (this->item_mrl, "$Number$"); if (b) { this->frag_mrl_1 = b - (const char *)this->item_mrl; this->frag_mrl_2 = strlen ("$Number$"); this->frag_mrl_3 = strlen (b + this->frag_mrl_2); } else { this->frag_mrl_1 = strlen (this->item_mrl); this->frag_mrl_2 = 0; this->frag_mrl_3 = 0; } } static void mpd_apply_fragnum (mpd_input_plugin_t *this) { if (this->frag_mrl_2) { char buf[32]; uint32_t l_2 = sprintf (buf, "%" PRId64, this->frag_num); if (l_2 != this->frag_mrl_2) { memmove (this->item_mrl + this->frag_mrl_1 + l_2, this->item_mrl + this->frag_mrl_1 + this->frag_mrl_2, this->frag_mrl_3 + 1); this->frag_mrl_2 = l_2; } memcpy (this->item_mrl + this->frag_mrl_1, buf, l_2); } } static int mpd_input_switch_mrl (mpd_input_plugin_t *this) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: %s.\n", (int)this->side_index, this->item_mrl); if (this->in1) { if (this->in1->get_capabilities (this->in1) & INPUT_CAP_NEW_MRL) { if (this->in1->get_optional_data (this->in1, this->item_mrl, INPUT_OPTIONAL_DATA_NEW_MRL) == INPUT_OPTIONAL_SUCCESS) { if (this->in1->open (this->in1) > 0) return 1; } } _x_free_input_plugin (this->stream, this->in1); } this->in1 = _x_find_input_plugin (this->stream, this->item_mrl); if (!this->in1) return 0; if (this->in1->open (this->in1) <= 0) return 0; return 1; } static int mpd_set_start_time (mpd_input_plugin_t *this) { if (!MPD_IS_LIVE (this)) { if (!mpd_build_mrl (this, this->list_buf + this->info.media)) return 0; this->frag_index = 1; this->frag_num = this->info.frag_start; mpd_prepare_fragnum (this); return 2; } if (!this->side_index) { /* main */ char buf[256]; struct timespec play_start, sys_start = {0, 0}; int64_t slag1; int slag2; xine_rats_t fd; int l; if (this->sync.avail_start.tv_sec == (time_t)-1) return 0; if (!this->info.timebase || !this->info.frag_duration) return 0; if (!mpd_build_mrl (this, this->list_buf + this->time_url)) return 0; if (!mpd_input_switch_mrl (this)) return 0; l = this->in1->read (this->in1, buf, sizeof (buf) - 1); if (l <= 0) return 0; buf[l] = 0; xine_gettime (&sys_start); play_start = sys_start; xine_ts_from_string (&play_start, buf); xine_ts_sub (&sys_start, &play_start); this->frag_index = 1; slag1 = xine_ts_to_timebase (&sys_start, 1000); slag2 = slag1 % 1000; slag1 /= 1000; slag2 = slag2 < 0 ? -slag2 : slag2; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: local system clock off by %" PRId64 ".%03d s.\n", (int)this->side_index, slag1, slag2); /* heavy magic ;-) */ { int64_t diff; struct timespec ts = play_start; xine_ts_sub (&ts, &this->sync.avail_start); ts.tv_sec -= this->rewind; fd.num = this->info.frag_duration; fd.den = this->info.timebase; xine_rats_shorten (&fd); diff = xine_ts_to_timebase (&ts, fd.den); this->frag_num = diff / fd.num + this->info.frag_start; this->lag = (diff % fd.num) * 90000 / fd.den; } if (this->sync.init) { pthread_mutex_lock (&this->sync.mutex); this->info.fd = fd; this->sync.play_start = play_start; this->sync.sys_lag = sys_start; this->sync.lag = this->lag; this->sync.type = this->info.type; pthread_mutex_unlock (&this->sync.mutex); } else { this->info.fd = fd; this->sync.play_start = play_start; this->sync.sys_lag = sys_start; this->sync.lag = this->lag; this->sync.type = this->info.type; } } else { mpd_input_plugin_t *main_input = this->main_input; if (!this->info.timebase || !this->info.frag_duration) return 0; if (main_input->sync.init) { pthread_mutex_lock (&this->sync.mutex); this->sync.avail_start = main_input->sync.avail_start; this->sync.play_start = main_input->sync.play_start; this->sync.sys_lag = main_input->sync.sys_lag; this->sync.lag = main_input->sync.lag; this->sync.type = main_input->sync.type; pthread_mutex_unlock (&this->sync.mutex); } else { this->sync.avail_start = main_input->sync.avail_start; this->sync.play_start = main_input->sync.play_start; this->sync.sys_lag = main_input->sync.sys_lag; this->sync.lag = main_input->sync.lag; this->sync.type = main_input->sync.type; } if (this->sync.avail_start.tv_sec == (time_t)-1) return 0; this->frag_index = 1; /* heavy magic ;-) */ { int64_t diff; xine_rats_t fd; struct timespec ts = this->sync.play_start; xine_ts_sub (&ts, &this->sync.avail_start); ts.tv_sec -= this->rewind; fd.num = this->info.frag_duration; fd.den = this->info.timebase; xine_rats_shorten (&fd); diff = xine_ts_to_timebase (&ts, fd.den); this->frag_num = diff / fd.num + this->info.frag_start; this->lag = (diff % fd.num) * 90000 / fd.den; } } if (!mpd_build_mrl (this, this->list_buf + this->info.media)) return 0; mpd_prepare_fragnum (this); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: live start @ fragment #%" PRId64 ", lag %d pts.\n", (int)this->side_index, this->frag_num, this->lag); return 1; } static int mpd_set_frag_index (mpd_input_plugin_t *this, uint32_t index, int wait) { if (!MPD_IS_LIVE (this)) { this->frag_num = this->info.frag_start + index - 1; this->frag_index = index; mpd_apply_fragnum (this); } else { int32_t d = index - this->frag_index; this->frag_num += d; this->frag_index = index; mpd_apply_fragnum (this); if (!wait) return 2; if (d > 0) { int64_t diff; int32_t ms; struct timespec now = {0, 0}, next; xine_gettime (&now); diff = (int64_t)(index - 1) * this->info.fd.num * 1000 / this->info.fd.den; next.tv_sec = diff / 1000; next.tv_nsec = (diff % 1000) * 1000000; xine_ts_add (&next, &this->sync.play_start); xine_ts_add (&next, &this->sync.sys_lag); xine_ts_sub (&next, &now); ms = xine_ts_to_timebase (&next, 1000); if ((ms > 0) && (ms < 100000)) { /* save server load and hang up before wait. */ if (this->in1) { if (this->in1->get_capabilities (this->in1) & INPUT_CAP_NEW_MRL) { char no_mrl[] = ""; this->in1->get_optional_data (this->in1, no_mrl, INPUT_OPTIONAL_DATA_NEW_MRL); } } if (_x_io_select (this->stream, -1, 0, ms) != XIO_TIMEOUT) return 0; } } } return mpd_input_switch_mrl (this); } static void mpd_frag_seen (mpd_input_plugin_t *this) { this->frag_pos = this->pos; if (this->in1) { int64_t l = this->in1->get_length (this->in1); if (l > 0) { this->frag_size = l; xine_mfrag_set_index_frag (this->fraglist, this->frag_index, (this->frag_index && this->info.frag_duration) ? (int64_t)this->info.frag_duration : -1, l); } else if (xine_mfrag_get_index_frag (this->fraglist, this->frag_index, NULL, &l) && (l > 0)) { this->frag_size = l; } else { this->frag_size = 0; } } else { this->frag_size = 0; } } static void mpd_frag_end (mpd_input_plugin_t *this) { int64_t l = this->pos - this->frag_pos; if (l > (int64_t)this->frag_size) { this->frag_size = l; xine_mfrag_set_index_frag (this->fraglist, this->frag_index, -1, l); } } static ssize_t mpd_read_int (mpd_input_plugin_t *this, void *buf, size_t len, int wait) { char *q = (char *)buf; if (len == 0) return 0; if (this->pos <= (off_t)this->prev_size2) { size_t n = this->prev_size2 - this->pos; if (n > 0) { if (n > len) n = len; memcpy (q, this->preview + this->pos, n); q += n; this->pos += n; len -= n; } if (len > 0) this->prev_size2 = 0; } if (len == 0) return q - (char *)buf; if (this->frag_index == 0) { if (this->list_buf[this->info.init]) { int r; if (this->pos == 0) { if (!mpd_build_mrl (this, this->list_buf + this->info.init)) return -1; if (!mpd_input_switch_mrl (this)) return -1; mpd_frag_seen (this); } r = this->in1->read (this->in1, q, len); if (r < 0) return -1; q += r; this->pos += r; len -= r; if (len == 0) return q - (char *)buf; } mpd_frag_end (this); if (!mpd_set_start_time (this)) return q - (char *)buf; mpd_apply_fragnum (this); if (!mpd_input_switch_mrl (this)) return q - (char *)buf; mpd_frag_seen (this); } while (len > 0) { int r = this->in1->read (this->in1, q, len); if (r < 0) return q > (char *)buf ? q - (char *)buf : -1; q += r; this->pos += r; len -= r; if (len == 0) break; if (r == 0) { if ((this->mode == MPD_SINGLE_LIVE) || (this->mode == MPD_SINGLE_VOD)) break; mpd_frag_end (this); if (mpd_set_frag_index (this, this->frag_index + 1, wait) != 1) break; mpd_frag_seen (this); } } return q - (char *)buf; } static int mpd_input_get_mrl_ext (const char *mrl, const char **ext) { const char *p1, *p2; for (p2 = mrl; *p2 && (*p2 != '?'); p2++) ; for (p1 = p2; (p1 > mrl) && (p1[-1] != '.'); p1--) ; *ext = p1; return p2 - p1; } static int mpd_input_is_mpd (const char *mrl) { const char *ext; int n = mpd_input_get_mrl_ext (mrl, &ext); if ((n == 3) && !strncasecmp (ext, "mpd", 3)) return 1; return 0; } /* static uint32_t str2msec (char **s) { uint8_t *p = (uint8_t *)*s; uint32_t v = 0; uint8_t z; while ((z = *p ^ '0') < 10) { v = v * 10u + z; p++; } v *= 1000u; if (z == ('.' ^ '0')) { p++; if ((z = *p ^ '0') < 10) { v += 100u * z; p++; if ((z = *p ^ '0') < 10) { v += 10u * z; p++; if ((z = *p ^ '0') < 10) { v += z; p++; } } } } *s = (char *)p; return v; } */ static uint32_t mpd_stree_find (mpd_input_plugin_t *this, const char *path, uint32_t base) { return 4 + this->tree[xine_stree_find (this->tree, this->list_buf + 4, path, base, 0)].value; } static int mpd_input_load_manifest (mpd_input_plugin_t *this) { ssize_t size; uint32_t tree_mpd; { off_t s = this->in1->get_length (this->in1); if (s > (32 << 20)) return 0; size = s; } if (size > 0) { /* size known, get at once. */ if (this->in1->seek (this->in1, 0, SEEK_SET) != 0) return 0; if ((uint32_t)size + 8 > this->list_bsize) { char *nbuf = realloc (this->list_buf, (uint32_t)size * 5 / 4 + 8); if (!nbuf) return 0; this->list_buf = nbuf; this->list_bsize = (uint32_t)size * 5 / 4 + 8; } if (this->in1->read (this->in1, this->list_buf + 4, size) != size) return 0; } else { /* chunked/deflated */ uint32_t have; if (!this->list_buf) { this->list_buf = malloc (32 << 10); if (!this->list_buf) return 0; this->list_bsize = 32 << 10; } have = 0; while (1) { int32_t r = this->in1->read (this->in1, this->list_buf + 4 + have, this->list_bsize - have - 8); if (r <= 0) break; have += r; if (have == this->list_bsize - 8) { char *nbuf; if (this->list_bsize >= (32 << 20)) break; nbuf = realloc (this->list_buf, this->list_bsize + (32 << 10)); if (!nbuf) return 0; this->list_buf = nbuf; this->list_bsize += 32 << 10; } } size = have; } memset (this->list_buf, 0, 4); memset (this->list_buf + 4 + size, 0, 4); this->tmode = XINE_STREE_AUTO; this->tree = xine_stree_load (this->list_buf + 4, &this->tmode); if (!this->tree) { this->list_bsize = 0; _x_freep (&this->list_buf); return 0; } tree_mpd = xine_stree_find (this->tree, this->list_buf + 4, "mpd", 0, 0); if (!tree_mpd) { tree_mpd = xine_stree_find (this->tree, this->list_buf + 4, "?xml.mpd", 0, 0); if (!tree_mpd) { xine_stree_delete (&this->tree); this->list_bsize = 0; _x_freep (&this->list_buf); return 0; } } this->base_url = mpd_stree_find (this, "BaseURL", tree_mpd); this->seg_base_url = mpd_stree_find (this, "SegmentBase", tree_mpd); if (!this->list_buf[this->seg_base_url]) this->seg_base_url = this->base_url; this->time_url = mpd_stree_find (this, "UTCTiming.value", tree_mpd); { struct timespec ts = {0, 0}; char *s = this->list_buf + mpd_stree_find (this, "availabilityStartTime", tree_mpd); xine_ts_from_string (&ts, s); this->sync.avail_start = ts; } { char path_p[] = "Period[ ]"; uint32_t period, index_p; this->num_streams = 0; for (period = 0; this->num_streams < MPD_MAX_STREAMS; period++) { char path_as[] = "AdaptationSet[ ]"; uint32_t adaptationset, index_as, max_as; path_p[7] = period < 10 ? ' ' : '0' + period / 10u; path_p[8] = '0' + period % 10u; index_p = xine_stree_find (this->tree, this->list_buf + 4, path_p, tree_mpd, 0); if (!index_p) break; max_as = MPD_MAX_STREAMS - this->num_streams; if (max_as > MPD_MAX_SIDES) max_as = MPD_MAX_SIDES; for (adaptationset = 0; adaptationset < max_as; adaptationset++) { char path_r[] = "Representation[ ]"; uint32_t representation, max_r; mpd_stream_info_t *info; char *s; path_as[14] = adaptationset < 10 ? ' ' : '0' + adaptationset / 10; path_as[15] = '0' + adaptationset % 10; index_as = xine_stree_find (this->tree, this->list_buf + 4, path_as, index_p, 0); if (!index_as) break; info = this->streams + this->num_streams; s = this->list_buf + mpd_stree_find (this, "contentType", index_as); info->type = 0; if (mpd_strcasestr (s, "audio")) info->type |= MPD_TYPE_AUDIO; if (mpd_strcasestr (s, "video")) info->type |= MPD_TYPE_VIDEO; if (mpd_strcasestr (s, "subtitle")) info->type |= MPD_TYPE_SUBT; info->mime = mpd_stree_find (this, "mimeType", index_as); info->index_p = index_p; info->index_as = index_as; info->index_r = 0; s = this->list_buf + mpd_stree_find (this, "SegmentTemplate.timescale", index_as); info->timebase = str2uint32 (&s); s = this->list_buf + mpd_stree_find (this, "audioSamplingRate", index_as); info->samplerate = str2uint32 (&s); info->init = mpd_stree_find (this, "SegmentTemplate.initialization", index_as); info->media = mpd_stree_find (this, "SegmentTemplate.media", index_as); s = this->list_buf + mpd_stree_find (this, "width", index_as); info->w = str2uint32 (&s); s = this->list_buf + mpd_stree_find (this, "height", index_as); info->h = str2uint32 (&s); /* this seems to default to 1. */ s = this->list_buf + mpd_stree_find (this, "SegmentTemplate.startNumber", index_as); info->frag_start = s[0] ? str2uint32 (&s) : 1; s = this->list_buf + mpd_stree_find (this, "SegmentTemplate.duration", index_as); info->frag_duration = str2uint32 (&s); info->id = 0; info->bitrate = 0; max_r = MPD_MAX_STREAMS - this->num_streams; if (max_r > MPD_MAX_REPR - 1) max_r = MPD_MAX_REPR - 1; for (representation = 0; representation < max_r; representation++) { uint32_t index_r; path_r[15] = representation < 10 ? ' ' : '0' + representation / 10; path_r[16] = '0' + representation % 10; index_r = xine_stree_find (this->tree, this->list_buf + 4, path_r, index_as, 0); if (!index_r) break; if (representation) info[0] = info[-1]; info->index_r = index_r; info->id = mpd_stree_find (this, "id", index_r); info->sfile = mpd_stree_find (this, "BaseURL", index_r); s = this->list_buf + mpd_stree_find (this, "SegmentBase.timescale", index_r); if (s[0]) info->timebase = str2uint32 (&s); s = this->list_buf + mpd_stree_find (this, "audioSamplingRate", index_r); if (s[0]) info->samplerate = str2uint32 (&s); s = this->list_buf + mpd_stree_find (this, "bandwidth", index_r); info->bitrate = str2uint32 (&s); s = this->list_buf + mpd_stree_find (this, "width", index_r); info->w = str2uint32 (&s); s = this->list_buf + mpd_stree_find (this, "height", index_r); info->h = str2uint32 (&s); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: stream[%2u]: %s %ux%u %uHz %ubps.\n", (int)this->side_index, (unsigned int)this->num_streams, this->list_buf + info->mime, (unsigned int)info->w, (unsigned int)info->h, (unsigned int)info->samplerate, (unsigned int)info->bitrate); info++; this->side_have_streams[adaptationset][representation] = this->num_streams; this->num_streams += 1; } if (!representation) { /* FIXME: empty adaptationset?? */ info->sfile = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: stream[%2u]: %s %ux%u %uHz %ubps.\n", (int)this->side_index, (unsigned int)this->num_streams, this->list_buf + info->mime, (unsigned int)info->w, (unsigned int)info->h, (unsigned int)info->samplerate, (unsigned int)info->bitrate); this->side_have_streams[adaptationset][representation] = this->num_streams; this->num_streams += 1; } this->side_have_streams[adaptationset][representation] = 255; } this->num_sides = adaptationset; } } { uint32_t u; for (u = 0; u < this->num_streams; u++) { mpd_stream_info_t *info = this->streams + u; if (!this->list_buf[info->media]) info->media = info->sfile; } } return 1; } static uint32_t mpd_input_get_capabilities (input_plugin_t *this_gen) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return 0; if (MPD_IS_LIVE (this)) return INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW | INPUT_CAP_LIVE; if (this->fraglist) return INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_TIME_SEEKABLE; if (this->in1) { this->caps1 = this->in1->get_capabilities (this->in1); return INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW | (this->caps1 & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)); } return INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW; } static off_t mpd_input_read (input_plugin_t *this_gen, void *buf, off_t len) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return 0; return mpd_read_int (this, buf, len, 1); } static buf_element_t *mpd_input_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { (void)this_gen; (void)fifo; (void)todo; return NULL; } static off_t mpd_input_time_seek (input_plugin_t *this_gen, int time_offs, int origin) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return 0; do { xine_mfrag_index_t idx; int64_t frag_time1, frag_time2; uint32_t new_time; if (!this->fraglist) return this->pos; switch (origin) { case SEEK_SET: new_time = 0; break; case SEEK_CUR: if (xine_mfrag_get_index_start (this->fraglist, this->frag_index, &frag_time1, NULL) && xine_mfrag_get_index_start (this->fraglist, this->frag_index + 1, &frag_time2, NULL)) { new_time = frag_time1 * 1000 / this->info.timebase; if (this->frag_size) new_time += ((frag_time2 - frag_time1) * 1000 / this->info.timebase) * (this->pos - this->frag_pos) / this->frag_size; } else { new_time = 0; } break; case SEEK_END: if (xine_mfrag_get_index_start (this->fraglist, xine_mfrag_get_frag_count (this->fraglist) + 1, &frag_time1, NULL)) { new_time = frag_time1 * 1000 / this->info.timebase; } else { new_time = 0; } break; default: errno = EINVAL; return (off_t)-1; } new_time += time_offs; frag_time1 = (int64_t)new_time * this->info.timebase / 1000; idx = xine_mfrag_find_time (this->fraglist, frag_time1); if (idx < 1) break; if (!xine_mfrag_get_index_start (this->fraglist, idx, NULL, &frag_time1)) break; if ((uint32_t)idx != this->frag_index) { if (!mpd_set_frag_index (this, idx, 1)) break; } this->prev_size2 = 0; this->pos = frag_time1; mpd_frag_seen (this); return this->pos; } while (0); errno = EINVAL; return (off_t)-1; } static off_t mpd_input_seek (input_plugin_t *this_gen, off_t offset, int origin) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; off_t new_offs; if (!this) return 0; switch (origin) { case SEEK_SET: new_offs = offset; break; case SEEK_CUR: new_offs = this->pos + offset; break; case SEEK_END: if (MPD_IS_LIVE (this)) return this->pos; if (this->fraglist) { int n; int64_t l; n = xine_mfrag_get_frag_count (this->fraglist); if (n < 1) return this->pos; this->info.frag_count = n; if (!xine_mfrag_get_index_start (this->fraglist, n + 1, NULL, &l)) return this->pos; if (l <= 0) return this->pos; this->all_size = l; new_offs = l + offset; break; } if (this->in1) { off_t l = this->in1->get_length (this->in1); if (l > 0) { this->all_size = l; new_offs = l + offset; break; } } /* fall through */ default: return this->pos; } /* always seek within the preview. */ if ((this->pos <= (int)this->prev_size2) && (new_offs >= 0) && (new_offs <= (int)this->prev_size2)) { this->pos = new_offs; return this->pos; } this->prev_size2 = 0; if (this->fraglist) { int64_t frag_pos; xine_mfrag_index_t idx = xine_mfrag_find_pos (this->fraglist, new_offs); if (idx < 1) return this->pos; /* HACK: offsets around this fragment may be guessed ones, * and the fragment itself may turn out to be smaller than expected. * however, demux expects a seek to land at the exact byte offs. * lets try to meet that, even if it is still wrong. */ idx -= 1; do { idx += 1; if (!xine_mfrag_get_index_start (this->fraglist, idx, NULL, &frag_pos)) return this->pos; if ((uint32_t)idx != this->frag_index) { mpd_frag_end (this); if (!mpd_set_frag_index (this, idx, 1)) return this->pos; this->pos = frag_pos; mpd_frag_seen (this); } } while (new_offs >= this->pos + this->frag_size); } this->caps1 = this->in1->get_capabilities (this->in1); if (this->caps1 & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE)) { off_t r = this->in1->seek (this->in1, new_offs - this->frag_pos, SEEK_SET); if (r >= 0) this->pos = this->frag_pos + r; return this->pos; } new_offs -= this->pos; if (new_offs < 0) return this->pos; { while (new_offs > 0) { char buf[2048]; size_t l = new_offs > (int)sizeof (buf) ? sizeof (buf) : (size_t)new_offs; ssize_t r = mpd_read_int (this, buf, l, 1); if (r <= 0) break; new_offs -= r; } } return this->pos; } static off_t mpd_input_get_current_pos (input_plugin_t *this_gen) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return 0; return this->pos; } static off_t mpd_input_get_length (input_plugin_t *this_gen) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return 0; if (MPD_IS_LIVE (this)) { if (this->pos > this->all_size) this->all_size = this->pos; } else if (this->fraglist) { int n; int64_t l; n = xine_mfrag_get_frag_count (this->fraglist); if (n >= 1) { this->info.frag_count = n; if (xine_mfrag_get_index_start (this->fraglist, n + 1, NULL, &l) && (l > 0)) this->all_size = l; } } else if (this->in1) { off_t l = this->in1->get_length (this->in1); if (l > 0) this->all_size = l; } return this->all_size; } static const char *mpd_input_get_mrl (input_plugin_t *this_gen) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return NULL; return this->manifest_mrl; } static void mpd_input_dispose (input_plugin_t *this_gen) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return; if (this->nbc) { xine_nbc_close (this->nbc); this->nbc = NULL; } if (this->in1) { _x_free_input_plugin (this->stream, this->in1); this->in1 = NULL; } xine_mfrag_list_close (&this->fraglist); xine_stree_delete (&this->tree); _x_freep (&this->list_buf); if (this->side_index) { mpd_input_plugin_t *main_input = this->main_input; this->sync.refs = 0; free (this); this = main_input; } if (this->sync.init) { pthread_mutex_lock (&this->sync.mutex); if (--this->sync.refs == 0) { pthread_mutex_unlock (&this->sync.mutex); pthread_mutex_destroy (&this->sync.mutex); free (this); } else { pthread_mutex_unlock (&this->sync.mutex); } } else { if (--this->sync.refs == 0) free (this); } } static int mpd_input_open (input_plugin_t *this_gen) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; mpd_input_class_t *cls = (mpd_input_class_t *)this->input_plugin.input_class; int n; if (!this->side_index) { uint32_t u; if (!mpd_input_load_manifest (this)) return 0; if (!this->num_streams) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: no streams.\n", (int)this->side_index); return 0; } /* video decoding usually is much slower than audio. * if there is video, make it the main stream. * this way, its effective lag will be 0, and the * engine need not drop video frames. */ for (u = 0; u < this->num_sides; u++) { uint32_t v = this->side_have_streams[u][0]; if ((v != 255) && (this->streams[v].type & MPD_TYPE_VIDEO)) break; } if ((u > 0) && (u < this->num_sides)) { uint8_t t[MPD_MAX_REPR]; memcpy (t, this->side_have_streams[0], sizeof (t)); memcpy (this->side_have_streams[0], this->side_have_streams[u], sizeof (t)); memcpy (this->side_have_streams[u], t, sizeof (t)); } if ((this->num_sides > 1) && !this->sync.init) { pthread_mutex_init (&this->sync.mutex, NULL); this->sync.init = 1; } } { multirate_pref_t *item = this->items; uint32_t u, i; for (u = 0; (i = this->side_have_streams[this->side_index][u]) != 255; u++) { mpd_stream_info_t *info = this->streams + i; item->video_width = info->w; item->video_height = info->h; item->bitrate = info->bitrate; item->lang[0] = 0; item++; } n = multirate_autoselect (&cls->pref, this->items, u); } if (n < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: no auto selected item.\n", (int)this->side_index); return 0; } this->used_stream = n = this->side_have_streams[this->side_index][n]; this->info = this->streams[n]; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: auto selected stream #%d.\n", (int)this->side_index, n); this->mode = this->list_buf[this->time_url] ? (this->list_buf[this->info.init] ? MPD_INIT_LIVE : mpd_strcasestr (this->list_buf + this->info.media, "$Number$") ? MPD_LIVE : MPD_SINGLE_LIVE) : (this->list_buf[this->info.init] ? MPD_INIT_VOD : mpd_strcasestr (this->list_buf + this->info.media, "$Number$") ? MPD_VOD : MPD_SINGLE_VOD); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: %s.\n", (int)this->side_index, mpd_mode_names[this->mode]); if ((this->mode == MPD_INIT_VOD) || (this->mode == MPD_VOD)) { xine_mfrag_list_open (&this->fraglist); xine_mfrag_set_index_frag (this->fraglist, 0, this->info.timebase, 0); } this->frag_index = 0; this->prev_size1 = 0; this->prev_size2 = 0; this->pos = 0; n = mpd_read_int (this, this->preview, sizeof (this->preview), 0); if (n <= 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "input_mpegdash.%d: failed to read preview.\n", (int)this->side_index); return 0; } this->prev_size1 = n; this->prev_size2 = n; this->pos = 0; /* xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: got %u fragments for %u.%03u seconds.\n", (int)this->side_index, (unsigned int)this->frag_have, (unsigned int)(this->frags[this->frag_have].start_msec / 1000u), (unsigned int)(this->frags[this->frag_have].start_msec % 1000u)); */ return 1; } static input_plugin_t *mpd_get_side (mpd_input_plugin_t *this, int side_index) { mpd_input_plugin_t *side_input; if (this->side_index) return NULL; if ((side_index < 1) || (side_index >= (int)this->num_sides)) return NULL; side_input = malloc (sizeof (*side_input)); if (!side_input) return NULL; /* clone everything */ *side_input = *this; /* sync */ if (this->sync.init) { pthread_mutex_lock (&this->sync.mutex); this->sync.refs++; pthread_mutex_unlock (&this->sync.mutex); } else { this->sync.refs++; } memset (&side_input->sync.mutex, 0, sizeof (side_input->sync.mutex)); side_input->sync.init = 0; side_input->sync.refs = 1; /* detach */ side_input->side_index = side_index; side_input->in1 = NULL; side_input->caps1 = 0; side_input->tree = NULL; side_input->fraglist = NULL; side_input->list_buf = malloc (this->list_bsize); if (!side_input->list_buf) { free (side_input); return NULL; } memcpy (side_input->list_buf, this->list_buf, this->list_bsize); side_input->stream = xine_get_side_stream (this->stream, side_index); if (!side_input->stream) { free (side_input->list_buf); free (side_input); return NULL; } side_input->nbc = xine_nbc_init (side_input->stream); return &side_input->input_plugin; } static int mpd_input_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { mpd_input_plugin_t *this = (mpd_input_plugin_t *)this_gen; if (!this) return INPUT_OPTIONAL_UNSUPPORTED; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: if (!data || (this->prev_size1 <= 0)) return INPUT_OPTIONAL_UNSUPPORTED; { uint32_t l = this->prev_size1 > MAX_PREVIEW_SIZE ? MAX_PREVIEW_SIZE : this->prev_size1; memcpy (data, this->preview, l); return l; } case INPUT_OPTIONAL_DATA_SIZED_PREVIEW: if (!data || (this->prev_size1 <= 0)) return INPUT_OPTIONAL_UNSUPPORTED; { int want; memcpy (&want, data, sizeof (want)); want = want < 0 ? 0 : want > (int)this->prev_size1 ? (int)this->prev_size1 : want; memcpy (data, this->preview, want); return want; } case INPUT_OPTIONAL_DATA_DURATION: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; if (this->fraglist) { int64_t d; int n = xine_mfrag_get_frag_count (this->fraglist); if (n > 0) { if (xine_mfrag_get_index_start (this->fraglist, n + 1, &d, NULL)) this->duration = d * 1000 / this->info.timebase; } } else { this->duration = (int64_t)this->info.frag_count * this->info.frag_duration * 1000 / this->info.timebase; } memcpy (data, &this->duration, sizeof (this->duration)); return INPUT_OPTIONAL_SUCCESS; case INPUT_OPTIONAL_DATA_FRAGLIST: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; memcpy (data, &this->fraglist, sizeof (this->fraglist)); return INPUT_OPTIONAL_SUCCESS; case INPUT_OPTIONAL_DATA_SIDE: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; { int side_index; input_plugin_t *side_input; memcpy (&side_index, data, sizeof (side_index)); side_input = mpd_get_side (this, side_index); if (!side_input) return INPUT_OPTIONAL_UNSUPPORTED; memcpy (data, &side_input, sizeof (side_input)); return INPUT_OPTIONAL_SUCCESS; } case INPUT_OPTIONAL_DATA_PTSOFFS: return this->sync.lag - this->lag; case INPUT_OPTIONAL_DATA_REWIND: if (!data) return INPUT_OPTIONAL_UNSUPPORTED; memcpy (&this->rewind, data, sizeof (this->rewind)); return INPUT_OPTIONAL_SUCCESS; default: return INPUT_OPTIONAL_UNSUPPORTED; } } static input_plugin_t *mpd_input_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { mpd_input_class_t *cls = (mpd_input_class_t *)cls_gen; mpd_input_plugin_t *this; input_plugin_t *in1; char hbuf[2048]; int n; if (!cls || !mrl) return NULL; lprintf("mpd_input_get_instance\n"); do { n = !strncasecmp (mrl, "mpegdash:/", 10) ? 10 : 0; in1 = _x_find_input_plugin (stream, mrl + n); if (in1) { if (in1->open (in1) > 0) { int l; if (mpd_input_is_mpd (mrl)) break; l = _x_demux_read_header (in1, hbuf, sizeof (hbuf) - 1); if (l > 5) { char *p = hbuf; p[l] = 0; while ((p = strchr (p, '<'))) { p++; if (!strncasecmp (p, "mpd ", 4)) break; } } } _x_free_input_plugin (stream, in1); } return NULL; } while (0); this = calloc (1, sizeof (*this)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->side_index = 0; this->caps1 = 0; this->fraglist = NULL; this->list_buf = NULL; this->list_bsize = 0; this->duration = 0; this->all_size = 0; this->sync.lag = 0; this->sync.type = 0; this->sync.init = 0; this->lag = 0; this->rewind = 0; #endif this->main_input = this; this->stream = stream; this->in1 = in1; this->num_sides = 0; this->sync.avail_start.tv_sec = this->sync.play_start.tv_sec = (time_t)-1; this->sync.refs = 1; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_mpegdash.%d: %s.\n", (int)this->side_index, mrl + n); strlcpy (this->manifest_mrl, mrl + n, MPD_MAX_MRL); this->input_plugin.open = mpd_input_open; this->input_plugin.get_capabilities = mpd_input_get_capabilities; this->input_plugin.read = mpd_input_read; this->input_plugin.read_block = mpd_input_read_block; this->input_plugin.seek = mpd_input_seek; this->input_plugin.seek_time = mpd_input_time_seek; this->input_plugin.get_current_pos = mpd_input_get_current_pos; this->input_plugin.get_length = mpd_input_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = mpd_input_get_mrl; this->input_plugin.get_optional_data = mpd_input_get_optional_data; this->input_plugin.dispose = mpd_input_dispose; this->input_plugin.input_class = &cls->input_class; this->nbc = xine_nbc_init (stream); return &this->input_plugin; } /* * plugin class functions */ static void mpd_input_class_dispose (input_class_t *this_gen) { mpd_input_class_t *this = (mpd_input_class_t *)this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free (this); } void *input_mpegdash_init_class (xine_t *xine, const void *data) { mpd_input_class_t *this; (void)data; this = calloc (1, sizeof (*this)); if (!this) return NULL; this->xine = xine; multirate_pref_get (xine->config, &this->pref); this->input_class.get_instance = mpd_input_get_instance; this->input_class.identifier = "mpegdash"; this->input_class.description = N_("MPEG Dynamic Adaptive Streaming over Http input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = mpd_input_class_dispose; this->input_class.eject_media = NULL; return this; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_helper.h���������������������������������������������������������������0000644�0001750�0001750�00000010731�14647725152�015463� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * input plugin helper functions */ #ifndef XINE_INPUT_HELPER_H #define XINE_INPUT_HELPER_H #ifdef __cplusplus extern "C" { #endif #include <errno.h> #include <sys/types.h> #include <xine/attributes.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> /* * mrl array alloc / free helpers */ void _x_input_free_mrls(xine_mrl_t ***p); xine_mrl_t **_x_input_alloc_mrls(size_t n); xine_mrl_t **_x_input_realloc_mrls(xine_mrl_t ***p, size_t n); void _x_input_sort_mrls(xine_mrl_t **mrls, ssize_t cnt /* optional, may be -1 */); /* * config helpers */ void _x_input_register_show_hidden_files(config_values_t *config); int _x_input_get_show_hidden_files(config_values_t *config); void _x_input_register_default_servers(config_values_t *config); xine_mrl_t **_x_input_get_default_server_mrls(config_values_t *config, const char *type, int *nFiles); /* * default read_block function. * uses read() to fill the block. */ buf_element_t *_x_input_default_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo); static inline uint32_t _x_input_get_capabilities_preview (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_PREVIEW; } static inline uint32_t _x_input_get_capabilities_seekable (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_SEEKABLE; } static inline uint32_t _x_input_get_capabilities_none (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_NOCAP; } static inline uint32_t _x_input_default_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return 0; } static inline off_t _x_input_default_get_length (input_plugin_t *this_gen) { (void)this_gen; return 0; } static inline int _x_input_default_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return INPUT_OPTIONAL_UNSUPPORTED; } /* * translate (offset, origin) to absolute position */ static inline off_t _x_input_translate_seek(off_t offset, int origin, off_t curpos, off_t length) { switch (origin) { case SEEK_SET: break; case SEEK_CUR: offset += curpos; break; case SEEK_END: offset = (length <= 0) ? (-1) : (offset + length); break; default: offset = -1; break; } if (offset < 0 || (length > 0 && offset > length)) { errno = EINVAL; return (off_t)-1; } return offset; } /* * seek forward by skipping data */ #define MAX_SKIP_BYTES (10*1024*1024) // 10 MB static inline int _x_input_read_skip(input_plugin_t *input, off_t bytes) { char buf[1024]; const off_t max = sizeof(buf); _x_assert(bytes >= 0); if (bytes > MAX_SKIP_BYTES) { /* seeking forward gigabytes would take long time ... */ return -1; } while (bytes > 0) { off_t got = input->read(input, buf, (bytes > max) ? max : bytes); if (got <= 0) return -1; bytes -= got; } _x_assert(bytes == 0); return 0; } /* * generic seek function for non-seekable input plugins */ static inline off_t _x_input_seek_preview(input_plugin_t *input, off_t offset, int origin, off_t *curpos, off_t length, off_t preview_size) { offset = _x_input_translate_seek(offset, origin, *curpos, length); if (offset < 0) goto fail; /* seek inside preview */ if (offset <= preview_size && *curpos <= preview_size) { *curpos = offset; return offset; } /* can't seek back */ if (offset < *curpos) goto fail; if (_x_input_read_skip(input, offset - *curpos) < 0) return -1; _x_assert(offset == *curpos); return offset; fail: errno = EINVAL; return (off_t)-1; } #ifdef __cplusplus } #endif #endif /* XINE_INPUT_HELPER_H */ ���������������������������������������xine-lib-1.2/src/input/input_dvd.c������������������������������������������������������������������0000644�0001750�0001750�00000164561�14647725152�014767� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project, * Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* This file was origninally part of the xine-dvdnav project * at http://dvd.sf.net/. */ /* TODO: * * - Proper internationalisation of strings. * - Failure dialogue. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Standard includes */ #include <stdio.h> #include <stdlib.h> #include <stddef.h> #ifndef WIN32 #include <sys/param.h> #endif /* WIN32 */ #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <pthread.h> #include <fcntl.h> #include <time.h> #include <string.h> #include <errno.h> #include <dlfcn.h> #ifndef WIN32 #if ! defined(__GNU__) #include <sys/mount.h> #endif #include <sys/wait.h> #include <sys/poll.h> #include <sys/ioctl.h> #endif /* WIN32 */ #if defined(HAVE_LINUX_CDROM_H) #include <linux/cdrom.h> #elif defined(HAVE_SYS_DVDIO_H) #include <sys/dvdio.h> #include <sys/cdio.h> /* CDIOCALLOW etc... */ #elif defined(HAVE_SYS_CDIO_H) #include <sys/cdio.h> #elif defined(WIN32) #include <io.h> /* read() */ #else #warning "This might not compile due to missing cdrom ioctls" #endif /* DVDNAV includes */ #ifdef HAVE_DVDNAV # include <dvdnav/dvdnav.h> # ifdef HAVE_DVDNAV_NAVTYPES_H # include <dvdnav/nav_types.h> # include <dvdnav/nav_read.h> # else # include <dvdread/nav_types.h> # include <dvdread/nav_read.h> # endif #else # define DVDNAV_COMPILE # include "libdvdnav/dvdnav.h" # include "libdvdnav/nav_read.h" #endif #define LOG_MODULE "input_http" #define LOG_VERBOSE /* #define LOG */ /* Xine includes */ #include <xine/xineutils.h> #include <xine/buffer.h> #include <xine/xine_internal.h> #include "media_helper.h" /* Print debug messages? */ /* #define INPUT_DEBUG */ /* Current play mode (title only or menus?) */ #define MODE_FAIL 0 #define MODE_NAVIGATE 1 #define MODE_TITLE 2 /* Is seeking enabled? 1 - Yes, 0 - No */ #define CAN_SEEK 1 /* The default DVD device on Solaris is not /dev/dvd */ #if defined(__sun) #define DVD_PATH "/vol/dev/aliases/cdrom0" #define RDVD_PATH "" #elif WIN32 /* There really isn't a default on Windows! */ #define DVD_PATH "d:\\" #define RDVD_PATH "d:\\" #elif defined(__OpenBSD__) #define DVD_PATH "/dev/rcd0c" #define RDVD_PATH "/dev/rcd0c" #else #define DVD_PATH "/dev/dvd" #define RDVD_PATH "/dev/rdvd" #endif /* Some misc. defines */ #ifdef DVD_VIDEO_LB_LEN # define DVD_BLOCK_SIZE DVD_VIDEO_LB_LEN #else # define DVD_BLOCK_SIZE 2048 #endif #if defined (__FreeBSD__) # define off64_t off_t # define lseek64 lseek #endif static const char *const dvdnav_menu_table[] = { NULL, NULL, "Title", "Root", "Subpicture", "Audio", "Angle", "Part" }; typedef struct dvd_input_plugin_s dvd_input_plugin_t; typedef union dvd_input_saved_buf_u { union dvd_input_saved_buf_u *free_next; struct { dvd_input_plugin_t *this; unsigned char *block; void *source; void (*free_buffer) (buf_element_t *); } used; } dvd_input_saved_buf_t; struct dvd_input_plugin_s { input_plugin_t input_plugin; /* Parent input plugin type */ xine_stream_t *stream; xine_event_queue_t *event_queue; int pause_timer; /* Cell still-time timer */ int pause_counter; time_t pause_end_time; int64_t pg_length; int64_t pgc_length; int64_t cell_start; int64_t pg_start; int32_t buttonN; int typed_buttonN;/* for XINE_EVENT_INPUT_NUMBER_* */ int32_t mouse_buttonN; int mouse_in; /* Flags */ int opened; /* 1 if the DVD device is already open */ int seekable; /* are we seekable? */ int mode; /* MODE_NAVIGATE / MODE_TITLE */ int tt, pr; /* title / chapter */ /* xine specific variables */ char *mrl; /* Current MRL */ dvdnav_t *dvdnav; /* Handle for libdvdnav */ const char *dvd_name; /* parsed mrl */ char *device; /* DVD device currently open */ int title; int part; /* special buffer handling for libdvdnav caching */ pthread_mutex_t buf_mutex; dvd_input_saved_buf_t *saved_bufs; dvd_input_saved_buf_t *saved_free; unsigned int saved_used; unsigned int saved_size; uint32_t user_conf_version; int32_t user_read_ahead; int32_t user_seek_mode; int32_t user_region; char user_lang4[4]; int freeing; }; typedef struct { input_class_t input_class; xine_t *xine; const char *dvd_device; /* default DVD device */ char *eject_device; /* the device last opened is remembered for eject */ uint32_t user_conf_version; int32_t user_read_ahead; int32_t user_seek_mode; int32_t user_region; char user_lang4[4]; int32_t user_play_single_chapter; int32_t user_skip_mode; } dvd_input_class_t; static int dvd_input_saved_new (dvd_input_plugin_t *this) { unsigned int n; dvd_input_saved_buf_t *s = malloc (1024 * sizeof (*s)); if (!s) return 1; this->saved_bufs = this->saved_free = s; for (n = 1024 - 1; n; n--) { s++; s[-1].free_next = s; } s[0].free_next = NULL; this->saved_used = 0; this->saved_size = 1024; return 0; } static void dvd_input_saved_delete (dvd_input_plugin_t *this) { _x_freep (&this->saved_bufs); } /* Get this->buf_mutex for the next 2. */ static dvd_input_saved_buf_t *dvd_input_saved_acquire (dvd_input_plugin_t *this) { dvd_input_saved_buf_t *s = this->saved_free; if (s) { this->saved_free = s->free_next; this->saved_used++; s->used.this = this; } return s; } static int dvd_input_saved_release (dvd_input_plugin_t *this, dvd_input_saved_buf_t *s) { s->free_next = this->saved_free; this->saved_free = s; this->saved_used--; return this->saved_used; } static void dvd_handle_events(dvd_input_plugin_t *this); static void xine_dvd_send_button_update(dvd_input_plugin_t *this, int mode); /* Callback on device name change */ static void device_change_cb(void *data, xine_cfg_entry_t *cfg) { dvd_input_class_t *class = (dvd_input_class_t *) data; class->dvd_device = cfg->str_value; } static uint32_t dvd_plugin_get_capabilities (input_plugin_t *this_gen) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; lprintf("Called\n"); return INPUT_CAP_BLOCK | /* TODO: figure out if there is any "allow copying" flag on DVD. * maybe set INPUT_CAP_RIP_FORBIDDEN only for encrypted media? */ INPUT_CAP_RIP_FORBIDDEN | #if CAN_SEEK (this->seekable ? INPUT_CAP_SEEKABLE : 0) | #endif INPUT_CAP_AUDIOLANG | INPUT_CAP_SPULANG | INPUT_CAP_CHAPTERS; } static void apply_cfg (dvd_input_plugin_t *this) { dvd_input_class_t *class = (dvd_input_class_t*)this->input_plugin.input_class; this->user_conf_version = class->user_conf_version; this->user_read_ahead = class->user_read_ahead; this->user_seek_mode = class->user_seek_mode; this->user_region = class->user_region; memcpy (this->user_lang4, class->user_lang4, 4); dvdnav_set_readahead_flag (this->dvdnav, this->user_read_ahead); dvdnav_set_PGC_positioning_flag (this->dvdnav, !this->user_seek_mode); dvdnav_set_region_mask (this->dvdnav, 1 << (this->user_region - 1)); dvdnav_menu_language_select (this->dvdnav, this->user_lang4); dvdnav_audio_language_select (this->dvdnav, this->user_lang4); dvdnav_spu_language_select (this->dvdnav, this->user_lang4); } static void update_cfg (dvd_input_plugin_t *this) { dvd_input_class_t *class = (dvd_input_class_t*)this->input_plugin.input_class; if (class->user_read_ahead != this->user_read_ahead) { this->user_read_ahead = class->user_read_ahead; dvdnav_set_readahead_flag (this->dvdnav, this->user_read_ahead); } if (class->user_seek_mode != this->user_seek_mode) { this->user_seek_mode = class->user_seek_mode; dvdnav_set_PGC_positioning_flag (this->dvdnav, !this->user_seek_mode); } if (class->user_region != this->user_region) { this->user_region = class->user_region; dvdnav_set_region_mask (this->dvdnav, 1 << (this->user_region - 1)); } if (memcmp (class->user_lang4, this->user_lang4, 4)) { memcpy (this->user_lang4, class->user_lang4, 4); dvdnav_menu_language_select (this->dvdnav, this->user_lang4); dvdnav_audio_language_select (this->dvdnav, this->user_lang4); dvdnav_spu_language_select (this->dvdnav, this->user_lang4); } } static void read_ahead_cb(void *this_gen, xine_cfg_entry_t *entry) { dvd_input_class_t *class = (dvd_input_class_t*)this_gen; if (class) { class->user_conf_version += 1; class->user_read_ahead = entry->num_value; } } static void seek_mode_cb(void *this_gen, xine_cfg_entry_t *entry) { dvd_input_class_t *class = (dvd_input_class_t*)this_gen; if (class) { class->user_conf_version += 1; class->user_seek_mode = entry->num_value; } } static void region_changed_cb (void *this_gen, xine_cfg_entry_t *entry) { dvd_input_class_t *class = (dvd_input_class_t*)this_gen; if (class && (entry->num_value >= 1) && (entry->num_value <= 8)) { class->user_conf_version += 1; class->user_region = entry->num_value; } } static void language_changed_cb(void *this_gen, xine_cfg_entry_t *entry) { dvd_input_class_t *class = (dvd_input_class_t*)this_gen; if (class && entry->str_value) { class->user_conf_version += 1; strlcpy (class->user_lang4, entry->str_value, 4); } } static void play_single_chapter_cb(void *this_gen, xine_cfg_entry_t *entry) { dvd_input_class_t *class = (dvd_input_class_t*)this_gen; if(!class) return; class->user_play_single_chapter = entry->num_value; } static void skip_changed_cb (void *this_gen, xine_cfg_entry_t *entry) { dvd_input_class_t *class = (dvd_input_class_t*)this_gen; if (class) class->user_skip_mode = entry->num_value; } static void send_mouse_enter_leave_event(dvd_input_plugin_t *this, int direction) { if(direction && this->mouse_in) this->mouse_in = !this->mouse_in; if(direction != this->mouse_in) { xine_spu_button_t spu_event = { .direction = direction, .button = this->mouse_buttonN }; xine_event_t event; event.type = XINE_EVENT_SPU_BUTTON; event.stream = this->stream; event.data = &spu_event; event.data_length = sizeof(spu_event); xine_event_send(this->stream, &event); this->mouse_in = direction; } if(!direction) this->mouse_buttonN = -1; } static int update_title_display(dvd_input_plugin_t *this) { xine_ui_data_t data; xine_event_t uevent = { .type = XINE_EVENT_UI_SET_TITLE, .stream = this->stream, .data = &data, .data_length = sizeof(data) }; int tt=-1, pr=-1; int num_tt = 0; /* Set title/chapter display */ dvdnav_current_title_info(this->dvdnav, &tt, &pr); if( this->mode == MODE_TITLE ) { if( (((dvd_input_class_t *)this->input_plugin.input_class)->user_play_single_chapter ) ) { if( (this->tt && this->tt != tt) || (this->pr && this->pr != pr) ) return 0; } this->tt = tt; this->pr = pr; } dvdnav_get_number_of_titles(this->dvdnav, &num_tt ); if(tt >= 1) { int num_angle = 0, cur_angle = 0; int num_part = 0; /* no menu here */ /* Reflect angle info if appropriate */ dvdnav_get_number_of_parts(this->dvdnav, tt, &num_part); dvdnav_get_angle_info(this->dvdnav, &cur_angle, &num_angle); if(num_angle > 1) { data.str_len = snprintf(data.str, sizeof(data.str), "Title %i, Chapter %i, Angle %i of %i", tt,pr,cur_angle, num_angle); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,cur_angle); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,num_angle); } else { data.str_len = snprintf(data.str, sizeof(data.str), "Title %i, Chapter %i", tt,pr); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0); } _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER,tt); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_COUNT,num_tt); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,pr); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_COUNT,num_part); } else if (tt == 0 && dvdnav_menu_table[pr]) { data.str_len = snprintf(data.str, sizeof(data.str), "DVD %s Menu", dvdnav_menu_table[pr]); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER,tt); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_COUNT,num_tt); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_COUNT,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0); } else { strcpy(data.str, "DVD Menu"); data.str_len = strlen(data.str); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_NUMBER,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_TITLE_COUNT,num_tt); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_NUMBER,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_CHAPTER_COUNT,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_NUMBER,0); _x_stream_info_set(this->stream,XINE_STREAM_INFO_DVD_ANGLE_COUNT,0); } if (this->dvd_name && this->dvd_name[0] && (data.str_len + strlen(this->dvd_name) < sizeof(data.str))) { data.str_len += snprintf(data.str+data.str_len, sizeof(data.str) - data.str_len, ", %s", this->dvd_name); } #ifdef INPUT_DEBUG printf("input_dvd: Changing title to read '%s'\n", data.str); #endif xine_event_send(this->stream, &uevent); return 1; } static void dvd_plugin_dispose (input_plugin_t *this_gen) { dvd_input_plugin_t *this = (dvd_input_plugin_t *)this_gen; lprintf("Called\n"); if (this->event_queue) xine_event_dispose_queue (this->event_queue); pthread_mutex_lock (&this->buf_mutex); if (this->saved_used) { /* raise the freeing flag, so that the plugin will be freed as soon * as all buffers have returned to the libdvdnav read ahead cache */ this->freeing = 1; pthread_mutex_unlock (&this->buf_mutex); } else { pthread_mutex_unlock (&this->buf_mutex); pthread_mutex_destroy (&this->buf_mutex); if (this->dvdnav) { dvdnav_close (this->dvdnav); this->dvdnav = NULL; } dvd_input_saved_delete (this); _x_freep (&this->device); _x_freep (&this->mrl); free (this); } } /* Align pointer |p| to alignment |align| */ #define PTR_ALIGN(p, align) ((void*)(((uintptr_t)(p) + (align) - 1) & ~((uintptr_t)(align)-1))) /* FIXME */ #if 0 static void dvd_build_mrl_list(dvd_input_plugin_t *this) { int num_titles, *num_parts; /* skip DVD if already open */ if (this->opened) return; if (this->class->mrls) { free(this->class->mrls); this->class->mrls = NULL; this->class->num_mrls = 0; } if (dvdnav_open(&(this->dvdnav), this->dvd_device) == DVDNAV_STATUS_ERR) { return; } this->current_dvd_device = this->dvd_device; this->opened = 1; dvdnav_get_number_of_titles(this->dvdnav, &num_titles); if ((num_parts = (int *) calloc(num_titles, sizeof(int)))) { struct xine_mrl_align_s { char dummy; xine_mrl_t mrl; }; int xine_mrl_alignment = offsetof(struct xine_mrl_align_s, mrl); int num_mrls = 1, i; /* for each title, count the number of parts */ for (i = 1; i <= num_titles; i++) { num_parts[i-1] = 0; /* dvdnav_title_play(this->dvdnav, i); */ dvdnav_get_number_of_parts(this->dvdnav, i, &num_parts[i-1]); num_mrls += num_parts[i-1]; /* num_mrls = total number of programs */ } /* allocate enough memory for: * - a list of pointers to mrls sizeof(xine_mrl_t *) * (num_mrls+1) * - possible alignment of the mrl array * - an array of mrl structures sizeof(xine_mrl_t) * num_mrls * - enough chars for every filename sizeof(char)*25 * num_mrls * - "dvd:/000000.000000\0" = 25 chars */ if ((this->mrls = (xine_mrl_t **) malloc(sizeof(xine_mrl_t *) + num_mrls * (sizeof(xine_mrl_t*) + sizeof(xine_mrl_t) + 25*sizeof(char)) + xine_mrl_alignment))) { /* the first mrl struct comes after the pointer list */ xine_mrl_t *mrl = PTR_ALIGN(&this->mrls[num_mrls+1], xine_mrl_alignment); /* the chars for filenames come after the mrl structs */ char *name = (char *) &mrl[num_mrls]; int pos = 0, j; this->num_mrls = num_mrls; for (i = 1; i <= num_titles; i++) { for (j = (i == 1 ? 0 : 1); j <= num_parts[i-1]; j++) { this->class->mrls[pos++] = mrl; mrl->origin = NULL; mrl->mrl = name; mrl->link = NULL; mrl->type = mrl_dvd; mrl->size = 0; snprintf(name, 25, (j == 0) ? "dvd:/" : (j == 1) ? "dvd:/%d" : "dvd:/%d.%d", i, j); name = &name[25]; mrl++; } } this->class->mrls[pos] = NULL; /* terminate list */ } free(num_parts); } } #endif static void dvd_plugin_free_buffer (buf_element_t *buf) { dvd_input_saved_buf_t *s = buf->source; dvd_input_plugin_t *this = s->used.this; unsigned int n; pthread_mutex_lock (&this->buf_mutex); /* reconstruct the original xine buffer */ buf->free_buffer = s->used.free_buffer; buf->source = s->used.source; /* give this buffer back to libdvdnav */ dvdnav_free_cache_block (this->dvdnav, s->used.block); s->used.block = NULL; /* free saved entry */ n = dvd_input_saved_release (this, s); pthread_mutex_unlock (&this->buf_mutex); /* give this buffer back to xine's pool */ buf->free_buffer (buf); if (this->freeing && !n) { /* all buffers returned, we can free the plugin now */ pthread_mutex_destroy (&this->buf_mutex); if (this->dvdnav) { dvdnav_close (this->dvdnav); this->dvdnav = NULL; } dvd_input_saved_delete (this); _x_freep (&this->device); _x_freep (&this->mrl); free (this); } } static buf_element_t *dvd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t nlen) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; buf_element_t *buf; dvdnav_status_t result; int event, len; int finished = 0; unsigned char *block; (void)nlen; if(fifo == NULL) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvd: values of \\beta will give rise to dom!\n")); return NULL; } if (this->dvdnav) { dvd_input_class_t *class = (dvd_input_class_t *)this->input_plugin.input_class; if (this->user_conf_version < class->user_conf_version) { this->user_conf_version = class->user_conf_version; update_cfg (this); } } /* Read buffer */ buf = fifo->buffer_pool_alloc (fifo); block = buf->mem; while(!finished) { dvd_handle_events(this); if (block != buf->mem) { /* if we already have a dvdnav cache block, give it back first */ dvdnav_free_cache_block(this->dvdnav, block); block = buf->mem; } result = dvdnav_get_next_cache_block (this->dvdnav, &block, &event, &len); if(result == DVDNAV_STATUS_ERR) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvd: Error getting next block from DVD (%s)\n"), dvdnav_err_to_string(this->dvdnav)); _x_message(this->stream, XINE_MSG_READ_ERROR, dvdnav_err_to_string(this->dvdnav), NULL); if (block != buf->mem) dvdnav_free_cache_block(this->dvdnav, block); buf->free_buffer(buf); return NULL; } switch(event) { case DVDNAV_BLOCK_OK: { buf->content = block; buf->type = BUF_DEMUX_BLOCK; /* Make sure we don't think we are still paused */ this->pause_timer = 0; /* we got a block, so we might be seekable here */ this->seekable = 1; finished = 1; } break; case DVDNAV_NOP: break; case DVDNAV_STILL_FRAME: { dvdnav_still_event_t *still_event = (dvdnav_still_event_t*)block; buf->type = BUF_CONTROL_NOP; finished = 1; /* stills are not seekable */ this->seekable = 0; /* Xine's method of doing still-frames */ if (this->pause_timer == 0) { #ifdef INPUT_DEBUG printf("input_dvd: Stillframe! (pause time = 0x%02x)\n", still_event->length); #endif this->pause_timer = still_event->length; this->pause_end_time = time(NULL) + this->pause_timer; this->pause_counter = 0; break; } if(this->pause_timer == 0xff) { this->pause_counter++; xine_usec_sleep(50000); break; } if ((this->pause_timer != 0xff) && (time(NULL) >= this->pause_end_time)) { this->pause_timer = 0; this->pause_end_time = 0; dvdnav_still_skip(this->dvdnav); break; } if(this->pause_timer) { this->pause_counter++; #ifdef INPUT_DEBUG printf("input_dvd: Stillframe! (pause_timer = 0x%02x) counter=%d\n", still_event->length, this->pause_counter); #endif xine_usec_sleep(50000); break; } } break; case DVDNAV_SPU_STREAM_CHANGE: { dvdnav_spu_stream_change_event_t *stream_event = (dvdnav_spu_stream_change_event_t*) (block); buf->content = block; buf->type = BUF_CONTROL_SPU_CHANNEL; buf->decoder_info[0] = stream_event->physical_wide; buf->decoder_info[1] = stream_event->physical_letterbox; buf->decoder_info[2] = stream_event->physical_pan_scan; #ifdef INPUT_DEBUG printf("input_dvd: SPU stream wide %d, letterbox %d, pan&scan %d\n", stream_event->physical_wide, stream_event->physical_letterbox, stream_event->physical_pan_scan); #endif finished = 1; } break; case DVDNAV_AUDIO_STREAM_CHANGE: { dvdnav_audio_stream_change_event_t *stream_event = (dvdnav_audio_stream_change_event_t*) (block); buf->content = block; buf->type = BUF_CONTROL_AUDIO_CHANNEL; buf->decoder_info[0] = stream_event->physical; #ifdef INPUT_DEBUG printf("input_dvd: AUDIO stream %d\n", stream_event->physical); #endif finished = 1; } break; case DVDNAV_HIGHLIGHT: xine_dvd_send_button_update(this, 0); break; case DVDNAV_VTS_CHANGE: { int aspect, permission; #ifdef INPUT_DEBUG printf("input_dvd: VTS change\n"); #endif /* Check for video aspect change and scaling permissions */ aspect = dvdnav_get_video_aspect(this->dvdnav); permission = dvdnav_get_video_scale_permission(this->dvdnav); buf->type = BUF_VIDEO_MPEG; buf->decoder_flags = BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_ASPECT; buf->decoder_info[2] = aspect; buf->decoder_info[3] = permission; finished = 1; } break; case DVDNAV_CELL_CHANGE: { dvdnav_cell_change_event_t *cell_event = (dvdnav_cell_change_event_t*) (block); /* Tell xine to update the UI */ xine_event_t event = { .type = XINE_EVENT_UI_CHANNELS_CHANGED, .stream = this->stream, .data = NULL, .data_length = 0 }; xine_event_send(this->stream, &event); if( !update_title_display(this) ) { if (buf->mem != block) dvdnav_free_cache_block(this->dvdnav, block); buf->free_buffer(buf); /* return NULL to indicate end of stream */ return NULL; } this->pg_length = cell_event->pg_length; this->pgc_length = cell_event->pgc_length; this->cell_start = cell_event->cell_start; this->pg_start = cell_event->pg_start; } break; case DVDNAV_HOP_CHANNEL: _x_demux_flush_engine(this->stream); break; case DVDNAV_NAV_PACKET: { buf->content = block; buf->type = BUF_DEMUX_BLOCK; finished = 1; } break; case DVDNAV_SPU_CLUT_CHANGE: { buf->content = block; buf->type = BUF_SPU_DVD; buf->decoder_flags |= BUF_FLAG_SPECIAL; buf->decoder_info[1] = BUF_SPECIAL_SPU_DVD_SUBTYPE; buf->decoder_info[2] = SPU_DVD_SUBTYPE_CLUT; finished = 1; } break; case DVDNAV_STOP: { if (buf->mem != block) dvdnav_free_cache_block(this->dvdnav, block); buf->free_buffer(buf); /* return NULL to indicate end of stream */ return NULL; } case DVDNAV_WAIT: { int buffers = this->stream->video_fifo->size(this->stream->video_fifo); if (this->stream->audio_fifo) buffers += this->stream->audio_fifo->size(this->stream->audio_fifo); /* we wait until the fifos are empty, ... well, we allow one remaining buffer, * because a flush might be in progress. */ if (buffers <= 1) dvdnav_wait_skip(this->dvdnav); else xine_usec_sleep(50000); } break; default: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: FIXME: Unknown event (%i)\n", event); break; } } if (block != buf->mem) { /* we have received a buffer from the libdvdnav cache, store all * necessary values to reconstruct xine's buffer and modify it according to * our needs. */ dvd_input_saved_buf_t *s; pthread_mutex_lock (&this->buf_mutex); s = dvd_input_saved_acquire (this); if (s) { s->used.block = block; s->used.free_buffer = buf->free_buffer; s->used.source = buf->source; buf->free_buffer = dvd_plugin_free_buffer; buf->source = s; } else { /* the stack for storing the memory chunks from xine is full, we cannot * modify the buffer, because we would not be able to reconstruct it. * Therefore we copy the data and give the buffer back. */ memcpy(buf->mem, block, DVD_BLOCK_SIZE); dvdnav_free_cache_block(this->dvdnav, block); buf->content = buf->mem; } pthread_mutex_unlock(&this->buf_mutex); } if (this->pg_length && this->pgc_length) { switch (this->user_seek_mode) { case 0: /* PGC based seeking */ buf->extra_info->total_time = this->pgc_length / 90; buf->extra_info->input_time = this->cell_start / 90; break; case 1: /* PG based seeking */ buf->extra_info->total_time = this->pg_length / 90; buf->extra_info->input_time = (this->cell_start - this->pg_start) / 90; break; } } return buf; } static off_t dvd_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { /* dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; */ uint8_t *buf = buf_gen; (void)this_gen; if (len < 4) return -1; /* FIXME: Tricking the demux_mpeg_block plugin */ buf[0] = 0; buf[1] = 0; buf[2] = 0x01; buf[3] = 0xba; return 1; } static off_t dvd_plugin_get_current_pos (input_plugin_t *this_gen){ dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; uint32_t pos=0; uint32_t length=1; /*dvdnav_status_t result;*/ lprintf("Called\n"); if (!this->dvdnav) { return 0; } /*result =*/ dvdnav_get_position(this->dvdnav, &pos, &length); return (off_t)pos * (off_t)DVD_BLOCK_SIZE; } static off_t dvd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; lprintf("Called\n"); if (!this->dvdnav) { return -1; } dvdnav_sector_search(this->dvdnav, offset / DVD_BLOCK_SIZE , origin); return dvd_plugin_get_current_pos(this_gen); } static off_t dvd_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; lprintf("Called\n"); if (!this->dvdnav || origin != SEEK_SET) { return -1; } dvdnav_time_search(this->dvdnav, time_offset * 90); return dvd_plugin_get_current_pos(this_gen); } static off_t dvd_plugin_get_length (input_plugin_t *this_gen) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; uint32_t pos=0; uint32_t length=1; /*dvdnav_status_t result;*/ lprintf("Called\n"); if (!this->dvdnav) { return 0; } /*result =*/ dvdnav_get_position(this->dvdnav, &pos, &length); return (off_t)length * (off_t)DVD_BLOCK_SIZE; } static uint32_t dvd_plugin_get_blocksize (input_plugin_t *this_gen) { lprintf("Called\n"); (void)this_gen; return DVD_BLOCK_SIZE; } static const char* dvd_plugin_get_mrl (input_plugin_t *this_gen) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; lprintf("Called\n"); return this->mrl; } static void xine_dvd_send_button_update(dvd_input_plugin_t *this, int mode) { int32_t button; int32_t show; if (_x_stream_info_get(this->stream, XINE_STREAM_INFO_IGNORE_SPU)) return; if (!this->stream->spu_decoder_plugin || this->stream->spu_decoder_streamtype != ((BUF_SPU_DVD >> 16) & 0xFF)) { /* the proper SPU decoder has not been initialized yet, * so we send a dummy buffer to trigger this */ buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo); buf->size = 0; buf->type = BUF_SPU_DVD; this->stream->video_fifo->insert(this->stream->video_fifo, buf); while (!this->stream->spu_decoder_plugin || this->stream->spu_decoder_streamtype != ((BUF_SPU_DVD >> 16) & 0xFF)) xine_usec_sleep(50000); } dvdnav_get_current_highlight(this->dvdnav, &button); if (button == this->buttonN && (mode == 0) ) return; this->buttonN = button; /* Avoid duplicate sending of button info */ #ifdef INPUT_DEBUG printf("input_dvd: sending_button_update button=%d mode=%d\n", button, mode); #endif /* Do we want to show or hide the button? */ /* libspudec will control hiding */ show = mode + 1; /* mode=0 select, 1 activate. */ this->stream->spu_decoder_plugin->set_button (this->stream->spu_decoder_plugin, button, show); } static void dvd_handle_events(dvd_input_plugin_t *this) { dvd_input_class_t *class = (dvd_input_class_t*)this->input_plugin.input_class; xine_event_t *event; while ((event = xine_event_get(this->event_queue))) { if(!this->dvdnav) { xine_event_free(event); return; } switch(event->type) { case XINE_EVENT_INPUT_MENU1: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: MENU1 key hit.\n"); dvdnav_menu_call(this->dvdnav, DVD_MENU_Escape); break; case XINE_EVENT_INPUT_MENU2: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: MENU2 key hit.\n"); dvdnav_menu_call(this->dvdnav, DVD_MENU_Title); break; case XINE_EVENT_INPUT_MENU3: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: MENU3 key hit.\n"); if (dvdnav_menu_call(this->dvdnav, DVD_MENU_Root) == DVDNAV_STATUS_ERR) dvdnav_menu_call(this->dvdnav, DVD_MENU_Title); break; case XINE_EVENT_INPUT_MENU4: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: MENU4 key hit.\n"); dvdnav_menu_call(this->dvdnav, DVD_MENU_Subpicture); break; case XINE_EVENT_INPUT_MENU5: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: MENU5 key hit.\n"); dvdnav_menu_call(this->dvdnav, DVD_MENU_Audio); break; case XINE_EVENT_INPUT_MENU6: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: MENU6 key hit.\n"); dvdnav_menu_call(this->dvdnav, DVD_MENU_Angle); break; case XINE_EVENT_INPUT_MENU7: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: MENU7 key hit.\n"); dvdnav_menu_call(this->dvdnav, DVD_MENU_Part); break; case XINE_EVENT_INPUT_NEXT: { int title = 0, part = 0; switch (class->user_skip_mode) { case 0: /* skip by program */ dvdnav_next_pg_search(this->dvdnav); break; case 1: /* skip by part */ if (dvdnav_current_title_info(this->dvdnav, &title, &part) && title > 0) dvdnav_part_play(this->dvdnav, title, ++part); break; case 2: /* skip by title */ if (dvdnav_current_title_info(this->dvdnav, &title, &part) && title > 0) dvdnav_part_play(this->dvdnav, ++title, 1); break; } } break; case XINE_EVENT_INPUT_PREVIOUS: { int title = 0, part = 0; switch (class->user_skip_mode) { case 0: /* skip by program */ dvdnav_prev_pg_search(this->dvdnav); break; case 1: /* skip by part */ if (dvdnav_current_title_info(this->dvdnav, &title, &part) && title > 0) dvdnav_part_play(this->dvdnav, title, --part); break; case 2: /* skip by title */ if (dvdnav_current_title_info(this->dvdnav, &title, &part) && title > 0) dvdnav_part_play(this->dvdnav, --title, 1); break; } } break; case XINE_EVENT_INPUT_ANGLE_NEXT: { int num = 0, current = 0; dvdnav_get_angle_info(this->dvdnav, ¤t, &num); if(num != 0) { current ++; if(current > num) current = 1; } dvdnav_angle_change(this->dvdnav, current); #ifdef INPUT_DEBUG printf("input_dvd: Changing to angle %i\n", current); #endif update_title_display(this); } break; case XINE_EVENT_INPUT_ANGLE_PREVIOUS: { int num = 0, current = 0; dvdnav_get_angle_info(this->dvdnav, ¤t, &num); if(num != 0) { current --; if(current <= 0) current = num; } dvdnav_angle_change(this->dvdnav, current); #ifdef INPUT_DEBUG printf("input_dvd: Changing to angle %i\n", current); #endif update_title_display(this); } break; case XINE_EVENT_INPUT_SELECT: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) { return; } if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { if (dvdnav_button_activate(this->dvdnav, &nav_pci) == DVDNAV_STATUS_OK) xine_dvd_send_button_update(this, 1); } } break; case XINE_EVENT_INPUT_MOUSE_BUTTON: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) { return; } if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { xine_input_data_t *input = event->data; if((input->button == 1) && dvdnav_mouse_activate(this->dvdnav, &nav_pci, input->x, input->y) == DVDNAV_STATUS_OK) { xine_dvd_send_button_update(this, 1); if(this->mouse_in) send_mouse_enter_leave_event(this, 0); this->mouse_buttonN = -1; } } } break; case XINE_EVENT_INPUT_BUTTON_FORCE: /* For libspudec to feedback forced button select from NAV PCI packets. */ { pci_t nav_pci; int *but = event->data; #ifdef INPUT_DEBUG printf("input_dvd: BUTTON_FORCE %d\n", *but); #endif if (!this->stream->spu_decoder_plugin) return; if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) dvdnav_button_select(this->dvdnav, &nav_pci, *but); } break; case XINE_EVENT_INPUT_MOUSE_MOVE: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) return; if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { xine_input_data_t *input = event->data; /* printf("input_dvd: Mouse move (x,y) = (%i,%i)\n", input->x, input->y); */ if(dvdnav_mouse_select(this->dvdnav, &nav_pci, input->x, input->y) == DVDNAV_STATUS_OK) { int32_t button; dvdnav_get_current_highlight(this->dvdnav, &button); if(this->mouse_buttonN != button) { this->mouse_buttonN = button; send_mouse_enter_leave_event(this, 1); } } else { if(this->mouse_in) send_mouse_enter_leave_event(this, 0); } } } break; case XINE_EVENT_INPUT_UP: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) return; if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { dvdnav_upper_button_select(this->dvdnav, &nav_pci); if(this->mouse_in) send_mouse_enter_leave_event(this, 0); } break; } case XINE_EVENT_INPUT_DOWN: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) return; if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { dvdnav_lower_button_select(this->dvdnav, &nav_pci); if(this->mouse_in) send_mouse_enter_leave_event(this, 0); } break; } case XINE_EVENT_INPUT_LEFT: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) return; if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { dvdnav_left_button_select(this->dvdnav, &nav_pci); if(this->mouse_in) send_mouse_enter_leave_event(this, 0); } break; } case XINE_EVENT_INPUT_RIGHT: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) return; if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { dvdnav_right_button_select(this->dvdnav, &nav_pci); if(this->mouse_in) send_mouse_enter_leave_event(this, 0); } break; } case XINE_EVENT_INPUT_NUMBER_9: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_8: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_7: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_6: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_5: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_4: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_3: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_2: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_1: this->typed_buttonN++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_0: { pci_t nav_pci; if (!this->stream->spu_decoder_plugin) return; if (this->stream->spu_decoder_plugin->get_interact_info(this->stream->spu_decoder_plugin, &nav_pci) ) { if (dvdnav_button_select_and_activate(this->dvdnav, &nav_pci, this->typed_buttonN) == DVDNAV_STATUS_OK) { xine_dvd_send_button_update(this, 1); if(this->mouse_in) send_mouse_enter_leave_event(this, 0); } this->typed_buttonN = 0; } break; } case XINE_EVENT_INPUT_NUMBER_10_ADD: this->typed_buttonN += 10; } xine_event_free(event); } return; } static int dvd_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { dvd_input_plugin_t *this = (dvd_input_plugin_t *) this_gen; switch(data_type) { case INPUT_OPTIONAL_DATA_AUDIOLANG: { uint16_t lang; int channel; int8_t dvd_channel; memcpy(&channel, data, sizeof(channel)); /* Be paranoid */ if(this && this->stream && this->dvdnav) { if(!(dvdnav_is_domain_vts(this->dvdnav))) { strcpy(data, "menu"); if (channel <= 0) return INPUT_OPTIONAL_SUCCESS; else return INPUT_OPTIONAL_UNSUPPORTED; } if (channel == -1) dvd_channel = dvdnav_get_audio_logical_stream(this->dvdnav, this->stream->audio_channel_auto); else dvd_channel = dvdnav_get_audio_logical_stream(this->dvdnav, channel); if(dvd_channel != -1) { lang = dvdnav_audio_stream_to_lang(this->dvdnav, dvd_channel); if(lang != 0xffff) sprintf(data, " %c%c", lang >> 8, lang & 0xff); /* TODO: provide long version in XINE_META_INFO_FULL_LANG */ else strcpy(data, " ??"); return INPUT_OPTIONAL_SUCCESS; } else { if (channel == -1) { strcpy(data, "none"); return INPUT_OPTIONAL_SUCCESS; } } } return INPUT_OPTIONAL_UNSUPPORTED; } break; case INPUT_OPTIONAL_DATA_SPULANG: { uint16_t lang; int channel; int8_t dvd_channel; memcpy(&channel, data, sizeof(channel)); /* Be paranoid */ if(this && this->stream && this->dvdnav) { if(!(dvdnav_is_domain_vts(this->dvdnav))) { strcpy(data, "menu"); if (channel <= 0) return INPUT_OPTIONAL_SUCCESS; else return INPUT_OPTIONAL_UNSUPPORTED; } if(channel == -1) dvd_channel = dvdnav_get_spu_logical_stream(this->dvdnav, this->stream->spu_channel_auto); else dvd_channel = dvdnav_get_spu_logical_stream(this->dvdnav, channel); if(dvd_channel != -1) { lang = dvdnav_spu_stream_to_lang(this->dvdnav, dvd_channel); if(lang != 0xffff) sprintf(data, " %c%c", lang >> 8, lang & 0xff); /* TODO: provide long version in XINE_META_INFO_FULL_LANG */ else sprintf(data, " %c%c", '?', '?'); return INPUT_OPTIONAL_SUCCESS; } else { if(channel == -1) { strcpy(data, "none"); return INPUT_OPTIONAL_SUCCESS; } } } return INPUT_OPTIONAL_UNSUPPORTED; } break; } return INPUT_OPTIONAL_UNSUPPORTED; } #ifdef __sun /* * Check the environment, if we're running under sun's * vold/rmmount control. */ static void check_solaris_vold_device(dvd_input_class_t *this) { char *volume_device; char *volume_name; char *volume_action; char *device; struct stat stb; if ((volume_device = getenv("VOLUME_DEVICE")) != NULL && (volume_name = getenv("VOLUME_NAME")) != NULL && (volume_action = getenv("VOLUME_ACTION")) != NULL && strcmp(volume_action, "insert") == 0) { device = _x_asprintf("%s/%s", volume_device, volume_name); if (!device || stat(device, &stb) != 0 || !S_ISCHR(stb.st_mode)) { free(device); return; } this->dvd_device = device; } } #endif static int dvd_parse_try_open(dvd_input_plugin_t *this, const char *locator) { const char *intended_dvd_device; /* FIXME: we temporarily special-case "dvd:/" for compatibility; * actually "dvd:/" should play a DVD image stored in /, but for * now we have it use the default device */ #if 0 if (strlen(locator)) #else if (strlen(locator) && !(locator[0] == '/' && locator[1] == '\0')) #endif { /* we have an alternative dvd_path */ intended_dvd_device = locator; /* do not use the raw device for the alternative */ /*xine_setenv("DVDCSS_RAW_DEVICE", "", 1);*/ } else { /* use default DVD device */ dvd_input_class_t *class = (dvd_input_class_t*)this->input_plugin.input_class; /* xine_cfg_entry_t raw_device; if (xine_config_lookup_entry(this->stream->xine, "media.dvd.raw_device", &raw_device)) xine_setenv("DVDCSS_RAW_DEVICE", raw_device.str_value, 1); */ intended_dvd_device = class->dvd_device; } /* attempt to open DVD */ if (this->opened) { if (this->device && !strcmp (intended_dvd_device, this->device)) { /* Already open, so skip opening */ dvdnav_reset(this->dvdnav); } else { /* Changing DVD device */ dvdnav_close(this->dvdnav); this->dvdnav = NULL; this->opened = 0; _x_freep (&this->device); } } if (!this->opened) { if (dvdnav_open(&this->dvdnav, intended_dvd_device) == DVDNAV_STATUS_OK) { this->opened = 1; this->device = strdup (intended_dvd_device); } } return this->opened; } static int dvd_parse_mrl (dvd_input_plugin_t *this) { /* we already checked the "dvd:/" MRL before */ size_t mlen = strlen (this->mrl + 4); char *b = malloc (mlen + 5); if (!b) return MODE_FAIL; memset (b, 0, 4); memcpy (b + 4, this->mrl + 4, mlen); b[4 + mlen] = 0; this->title = -1; this->part = -1; do { uint8_t *p; _x_mrl_unescape (b + 4); if (dvd_parse_try_open (this, b + 4)) { free (b); return MODE_NAVIGATE; } /* opening failed, but we can still try cutting off <title>.<part> */ mlen = strlen (b + 4); p = (uint8_t *)b + 4 + mlen - 1; { uint32_t v = 0, f = 1; while (1) { uint32_t z = *p ^ '0'; if (z > 9) break; v += f * z; f *= 10u; p--; } this->title = v; } if (*p == '.') { uint32_t v = 0, f = 1; this->part = this->title; p--; while (1) { uint32_t z = *p ^ '0'; if (z > 9) break; v += f * z; f *= 10u; p--; } this->title = v; } if (p == (uint8_t *)b + 4 + mlen - 1) break; /* never delete the very first slash, since this will turn an * absolute into a relative URL and overthrow further opening */ if ((*p != '/') || (p <= (uint8_t *)b + 4)) p++; *p = 0; if (dvd_parse_try_open (this, b + 4)) { free (b); return this->title >= 0 ? MODE_TITLE : MODE_NAVIGATE; } } while (0); free (b); return MODE_FAIL; } static int dvd_plugin_open (input_plugin_t *this_gen) { dvd_input_plugin_t *this = (dvd_input_plugin_t*)this_gen; dvd_input_class_t *class = (dvd_input_class_t*)this_gen->input_class; lprintf("Called\n"); this->mode = dvd_parse_mrl (this); if (this->mode == MODE_FAIL) { /* opening failed and we have nothing left to try */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_dvd: Error opening DVD device\n")); _x_message(this->stream, XINE_MSG_READ_ERROR, /* FIXME: see FIXME in dvd_parse_try_open() */ (this->mrl[0] && !(this->mrl[0] == '/' && this->mrl[1] == '\0')) ? this->mrl : class->dvd_device, NULL); return 0; } dvdnav_get_title_string(this->dvdnav, &this->dvd_name); if(this->dvd_name) _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->dvd_name); apply_cfg (this); if (this->mode == MODE_TITLE) { int titles, parts; /* a <title>.<part> was specified -> resume parsing */ dvdnav_get_number_of_titles(this->dvdnav, &titles); if (this->title > titles) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: Title %i is out of range (1 to %i).\n", this->title, titles); dvdnav_close(this->dvdnav); this->dvdnav = NULL; return 0; } /* If there was a part specified, get that too. */ if (this->part >= 0) { dvdnav_get_number_of_parts (this->dvdnav, this->title, &parts); if (this->part > parts) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_dvd: Part %i is out of range (1 to %i).\n", this->part, parts); dvdnav_close(this->dvdnav); this->dvdnav = NULL; return 0; } } #ifdef INPUT_DEBUG printf ("input_dvd: Jumping to TT >%i<, PTT >%i<\n", this->title, this->part); #endif if (this->title > 0) { if (this->part > 0) dvdnav_part_play (this->dvdnav, this->title, this->part); else dvdnav_title_play (this->dvdnav, this->title); } else this->mode = MODE_NAVIGATE; } #ifdef INPUT_DEBUG printf("input_dvd: DVD device successfully opened.\n"); #endif /* remember the last successfully opened device for ejecting */ free(class->eject_device); class->eject_device = strdup (this->device); { /* Tell Xine to update the UI */ const xine_event_t event = { .type = XINE_EVENT_UI_CHANNELS_CHANGED, .stream = this->stream, .data = NULL, .data_length = 0 }; xine_event_send(this->stream, &event); } update_title_display(this); return 1; } /* dvdnav CLASS functions */ /* * Opens the DVD plugin. The MRL takes the following form: * * dvd:[dvd_path]/[vts[.program]] * * e.g. * dvd:/ - Play (navigate) * dvd:/1 - Play Title 1 * dvd:/1.3 - Play Title 1, program 3 * dvd:/dev/dvd2/ - Play (navigate) from /dev/dvd2 * dvd:/dev/dvd2/1.3 - Play Title 1, program 3 from /dev/dvd2 */ static input_plugin_t *dvd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *data) { dvd_input_plugin_t *this; static const char handled_mrl[] = "dvd:/"; lprintf("Called\n"); /* Check we can handle this MRL */ if (strncasecmp (data, handled_mrl, sizeof(handled_mrl)-1 ) != 0) return NULL; this = calloc(1, sizeof (dvd_input_plugin_t)); if (!this) { return NULL; } #ifndef HAVE_ZERO_SAFE_MEM this->dvdnav = NULL; this->opened = 0; this->seekable = 0; this->buttonN = 0; this->mouse_in = 0; this->typed_buttonN = 0; this->pause_timer = 0; this->pg_length = 0; this->pgc_length = 0; this->dvd_name = NULL; this->device = NULL; this->freeing = 0; #endif if (dvd_input_saved_new (this)) { free(this); return NULL; } this->input_plugin.open = dvd_plugin_open; this->input_plugin.get_capabilities = dvd_plugin_get_capabilities; this->input_plugin.read = dvd_plugin_read; this->input_plugin.read_block = dvd_plugin_read_block; this->input_plugin.seek = dvd_plugin_seek; this->input_plugin.seek_time = dvd_plugin_seek_time; this->input_plugin.get_current_pos = dvd_plugin_get_current_pos; this->input_plugin.get_length = dvd_plugin_get_length; this->input_plugin.get_blocksize = dvd_plugin_get_blocksize; this->input_plugin.get_mrl = dvd_plugin_get_mrl; this->input_plugin.get_optional_data = dvd_plugin_get_optional_data; this->input_plugin.dispose = dvd_plugin_dispose; this->input_plugin.input_class = class_gen; this->user_conf_version = 0; this->stream = stream; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL, 1); this->mouse_buttonN = -1; this->mrl = strdup(data); pthread_mutex_init(&this->buf_mutex, NULL); this->event_queue = xine_event_new_queue (this->stream); return &this->input_plugin; } /* FIXME: adapt to new api. */ #if 0 static xine_mrl_t **dvd_class_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { dvd_input_class_t *this = (dvd_input_class_t*)this_gen; lprintf("Called\n"); if (filename) { *nFiles = 0; return NULL; } /* dvd_build_mrl_list(this); *nFiles = this->num_mrls; return this->mrls; */ *nFiles = 0; return NULL; } #endif static const char * const *dvd_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { static const char * const filelist[] = {"dvd:/", NULL}; lprintf("get_autoplay_list entered\n"); (void)this_gen; *num_files = 1; return filelist; } static void dvd_class_dispose(input_class_t *this_gen) { dvd_input_class_t *this = (dvd_input_class_t*)this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); _x_freep(&this->eject_device); free(this); } static int dvd_class_eject_media (input_class_t *this_gen) { dvd_input_class_t *this = (dvd_input_class_t*)this_gen; return media_eject_media (this->xine, this->eject_device); } static void *init_class (xine_t *xine, const void *data) { dvd_input_class_t *this; config_values_t *config = xine->config; void *dvdcss; static const char *const skip_modes[] = {"skip program", "skip part", "skip title", NULL}; static const char *const seek_modes[] = {"seek in program chain", "seek in program", NULL}; static const char *const play_single_chapter_modes[] = {"entire dvd", "one chapter", NULL}; lprintf("Called\n"); #ifdef INPUT_DEBUG printf("input_dvd.c: init_class called.\n"); printf("input_dvd.c: config = %p\n", config); #endif (void)data; this = (dvd_input_class_t *) calloc(1, sizeof (dvd_input_class_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->input_class.get_dir = NULL; #endif this->input_class.get_instance = dvd_class_get_instance; this->input_class.identifier = "DVD"; this->input_class.description = N_("DVD Navigator"); /* this->input_class.get_dir = dvd_class_get_dir; */ this->input_class.get_autoplay_list = dvd_class_get_autoplay_list; this->input_class.dispose = dvd_class_dispose; this->input_class.eject_media = dvd_class_eject_media; this->xine = xine; this->dvd_device = config->register_filename(config, "media.dvd.device", DVD_PATH, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for DVD playback"), _("The path to the device, usually a " "DVD drive, which you intend to use for playing DVDs."), 10, device_change_cb, (void *)this); #ifdef HOST_OS_DARWIN if ((dvdcss = dlopen("libdvdcss.2.dylib", RTLD_LAZY)) != NULL) #else if ((dvdcss = dlopen("libdvdcss.so.2", RTLD_LAZY)) != NULL) #endif { /* we have found libdvdcss, enable the specific config options */ /* char *raw_device; */ static const char *const decrypt_modes[] = { "key", "disc", "title", NULL }; int mode; /* raw_device = config->register_filename(config, "media.dvd.raw_device", RDVD_PATH, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("raw device set up for DVD access"), _("If this points to a raw device connected to your " "DVD device, xine will use the raw device for playback. " "This has the advantage of being slightly faster and " "of bypassing the block device cache, which avoids " "throwing away important cache content by keeping DVD " "data cached. Using the block device cache for DVDs " "is useless, because almost all DVD data will be used " "only once.\nSee the documentation on raw device setup " "(man raw) for further information."), 10, NULL, NULL); if (raw_device) xine_setenv("DVDCSS_RAW_DEVICE", raw_device, 0); */ mode = config->register_enum(config, "media.dvd.css_decryption_method", 0, (char **)decrypt_modes, _("CSS decryption method"), _("Selects the decryption method libdvdcss will use to descramble " "copy protected DVDs. Try the various methods, if you have problems " "playing scrambled DVDs."), 20, NULL, NULL); xine_setenv("DVDCSS_METHOD", decrypt_modes[mode], 0); if(xine->verbosity > XINE_VERBOSITY_NONE) xine_setenv("DVDCSS_VERBOSE", "2", 0); else xine_setenv("DVDCSS_VERBOSE", "0", 0); dlclose(dvdcss); } this->user_conf_version = 1; this->user_region = config->register_num (config, "media.dvd.region", 1, _("region the DVD player claims to be in (1 to 8)"), _("This only needs to be changed if your DVD jumps to a screen " "complaining about a wrong region code. It has nothing to do with " "the region code set in DVD drives, this is purely software."), 0, region_changed_cb, this); if ((this->user_region < 1) || (this->user_region > 8)) this->user_region = 1; { const char *lang = config->register_string (config, "media.dvd.language", "en", _("default language for DVD playback"), _("xine tries to use this language as a default for DVD playback. " "As far as the DVD supports it, menus and audio tracks will be presented " "in this language.\nThe value must be a two character ISO639 language code."), 0, language_changed_cb, this); if (lang) strlcpy (this->user_lang4, lang, 4); } this->user_read_ahead = config->register_bool (config, "media.dvd.readahead", 1, _("read-ahead caching"), _("xine can use a read ahead cache for DVD drive access.\n" "This may lead to jerky playback on slow drives, but it improves the impact " "of the DVD layer change on faster drives."), 10, read_ahead_cb, this); this->user_skip_mode = config->register_enum (config, "media.dvd.skip_behaviour", 0, (char **)skip_modes, _("unit for the skip action"), _("You can configure the behaviour when issuing a skip command (using the skip " "buttons for example). The individual values mean:\n\n" "skip program\n" "will skip a DVD program, which is a navigational unit similar to the " "index marks on an audio CD; this is the normal behaviour for DVD players\n\n" "skip part\n" "will skip a DVD part, which is a structural unit similar to the " "track marks on an audio CD; parts usually coincide with programs, but parts " "can be larger than programs\n\n" "skip title\n" "will skip a DVD title, which is a structural unit representing entire " "features on the DVD"), 20, skip_changed_cb, this); this->user_seek_mode = config->register_enum (config, "media.dvd.seek_behaviour", 0, (char **)seek_modes, _("unit for seeking"), _("You can configure the domain spanned by the seek slider. The individual values mean:\n\n" "seek in program chain\n" "seeking will span an entire DVD program chain, which is a navigational " "unit representing the entire video stream of the current feature\n\n" "seek in program\n" "seeking will span a DVD program, which is a navigational unit representing " "a chapter of the current feature"), 20, seek_mode_cb, this); this->user_play_single_chapter = config->register_enum (config, "media.dvd.play_single_chapter", 0, (char **)play_single_chapter_modes, _("play mode when title/chapter is given"), _("You can configure the behaviour when playing a dvd from a given " "title/chapter (eg. using MRL 'dvd:/1.2'). The individual values mean:\n\n" "entire dvd\n" "play the entire dvd starting on the specified position.\n\n" "one chapter\n" "play just the specified title/chapter and then stop"), 20, play_single_chapter_cb, this); #ifdef __sun check_solaris_vold_device(this); #endif #ifdef INPUT_DEBUG printf("input_dvd.c: init_class finished.\n"); #endif return this; } const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "DVD", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_stdin_fifo.c�����������������������������������������������������������0000644�0001750�0001750�00000034622�14647725152�016330� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <errno.h> #define LOG_MODULE "input_stdin_fifo" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "input_helper.h" #define BUFSIZE 1024 #if defined(WIN32) || defined(__CYGWIN__) # define FILE_FLAGS (O_RDONLY | O_BINARY) #else # define FILE_FLAGS O_RDONLY #endif typedef struct { input_plugin_t input_plugin; xine_t *xine; xine_stream_t *stream; xine_nbc_t *nbc; char *mrl; int fh; off_t curpos; int num_reads, num_fd_reads, num_fd_waits; long int old_mode, mode; int nonblock; int timeout, requery_timeout; #define RING_LD 15 #define RING_SIZE (1 << RING_LD) #define RING_MASK (RING_SIZE - 1) int ring_write; int ring_read; uint8_t *ring_buf; off_t preview_size; char preview[MAX_PREVIEW_SIZE]; } stdin_input_plugin_t; static off_t stdin_plugin_get_current_pos (input_plugin_t *this_gen); static int stdin_plugin_wait (stdin_input_plugin_t *this) { int ret; if (this->requery_timeout <= 0) { this->requery_timeout = 1 << 20; this->timeout = _x_query_network_timeout (this->xine) * 1000; } this->num_fd_waits += 1; ret = _x_io_select (this->stream, this->fh, XIO_READ_READY, this->timeout); if (ret != XIO_READY) { if (ret == XIO_ABORTED) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": interrupting for pending demux action.\n"); } else { if (ret == XIO_TIMEOUT) xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": wait timeout.\n"); else xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": wait error.\n"); _x_message (this->stream, XINE_MSG_READ_ERROR, this->mrl, NULL); } } return ret; } static off_t stdin_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; long int n, rest = len, done; int e; lprintf ("reading %"PRId64" bytes...\n", len); if (rest <= 0) return 0; this->num_reads ++; done = 0; if (this->preview_size > this->curpos) { n = this->preview_size - this->curpos; if (n >= rest) { lprintf ("%ld bytes from preview (which has %"PRId64" bytes)\n", rest, this->preview_size); memcpy (buf, this->preview + this->curpos, rest); this->curpos += rest; return rest; } lprintf ("%ld bytes from preview (which has %"PRId64" bytes)\n", n, this->preview_size); memcpy (buf, this->preview + this->curpos, n); this->curpos += n; done = n; rest -= n; } if (this->nonblock) { if (this->ring_buf) { while (1) { e = 0; n = 1; /* Get from buf. */ { int part = this->ring_write - this->ring_read; if (part < 0) { part = RING_SIZE - this->ring_read; if (part <= rest) { rest -= part; xine_fast_memcpy (buf + done, this->ring_buf + this->ring_read, part); this->ring_read = 0; this->curpos += part; done += part; part = this->ring_write; } } if (part > rest) part = rest; if (part > 0) { xine_fast_memcpy (buf + done, this->ring_buf + this->ring_read, part); this->ring_read += part; this->curpos += part; done += part; rest -= part; } } /* Are we done already? */ if (rest <= 0) { if (this->requery_timeout > 0) this->requery_timeout -= n; return done; } /* Always try an immediate buf refill. Dont fill up all as that would look like buf empty later. */ do { int part = this->ring_read - this->ring_write; if (part <= 0) { int room = RING_SIZE + part - 32; if (room <= 0) break; part = RING_SIZE - this->ring_write; if (part > room) part = room; this->num_fd_reads += 1; n = read (this->fh, this->ring_buf + this->ring_write, part); if (n <= 0) break; this->ring_write = (this->ring_write + n) & RING_MASK; if (this->ring_write > 0) break; part = this->ring_read; } part -= 32; if (part <= 0) break; this->num_fd_reads += 1; n = read (this->fh, this->ring_buf + this->ring_write, part); if (n >= 0) this->ring_write += n; } while (0); if (n < 0) e = errno; /* Continue / Wait / Bail out. */ if (n == 0) return done; if (n < 0) { if (e != EAGAIN) break; if (stdin_plugin_wait (this) != XIO_READY) return done; } } } else { /* Let input_cache handle the demux_len <= done <= cache_fill_len case without wait */ while (1) { this->num_fd_reads += 1; n = read (this->fh, buf + done, rest); if (n >= 0) { this->curpos += n; done += n; lprintf ("got %ld bytes (%ld/%"PRId64" bytes read)\n", n, done, len); if (this->requery_timeout > 0) this->requery_timeout -= n; return done; } e = errno; if (e != EAGAIN) break; if (stdin_plugin_wait (this) != XIO_READY) return done; } } } else { if (stdin_plugin_wait (this) != XIO_READY) return done; this->num_fd_reads += 1; n = read (this->fh, buf + done, rest); if (n >= 0) { this->curpos += n; done += n; lprintf ("got %ld bytes (%ld/%"PRId64" bytes read)\n", n, done, len); if (this->requery_timeout > 0) this->requery_timeout -= n; return done; } e = errno; } { const char *m = strerror (e); if (e == EACCES) _x_message (this->stream, XINE_MSG_PERMISSION_ERROR, this->mrl, NULL); else if (e == ENOENT) _x_message (this->stream, XINE_MSG_FILE_NOT_FOUND, this->mrl, NULL); else _x_message (this->stream, XINE_MSG_READ_ERROR, this->mrl, m, NULL); xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s: %s (%d).\n", this->mrl, m, e); } return done; } /* forward reference */ static off_t stdin_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; lprintf ("seek %"PRId64" offset, %d origin...\n", offset, origin); return _x_input_seek_preview (this_gen, offset, origin, &this->curpos, -1, this->preview_size); } static off_t stdin_plugin_get_length(input_plugin_t *this_gen) { (void)this_gen; return 0; } static off_t stdin_plugin_get_current_pos (input_plugin_t *this_gen){ stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; return this->curpos; } static const char* stdin_plugin_get_mrl (input_plugin_t *this_gen) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; return this->mrl; } static void stdin_plugin_dispose (input_plugin_t *this_gen ) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": %d reads, %d fd reads, %d fd waits.\n", this->num_reads, this->num_fd_reads, this->num_fd_waits); free (this->ring_buf); if (this->nbc) xine_nbc_close (this->nbc); if (this->fh >= 0) { if (this->fh != STDIN_FILENO) { close (this->fh); } else { #ifndef WIN32 if (this->old_mode != -1) fcntl (this->fh, F_SETFL, this->old_mode); #endif } } free (this->mrl); free (this); } static uint32_t stdin_plugin_get_capabilities (input_plugin_t *this_gen) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; return INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW | ((this && this->ring_buf) ? INPUT_CAP_NO_CACHE : 0); } static int stdin_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: if (!data || (this->preview_size <= 0)) break; memcpy (data, this->preview, this->preview_size); return this->preview_size; case INPUT_OPTIONAL_DATA_SIZED_PREVIEW: if (!data || (this->preview_size <= 0)) break; { int want; memcpy (&want, data, sizeof (want)); want = want < 0 ? 0 : want > this->preview_size ? this->preview_size : want; memcpy (data, this->preview, want); return want; } } return INPUT_OPTIONAL_UNSUPPORTED; } static int stdin_plugin_open (input_plugin_t *this_gen ) { stdin_input_plugin_t *this = (stdin_input_plugin_t *) this_gen; lprintf ("trying to open '%s'...\n", this->mrl); /* POSIX manpage: "If O_NONBLOCK is clear, an open() for reading-only shall block * the calling thread until a thread opens the file for writing." * This seems to include the case when that pipe already is open for write, * as may result from a race with Kaffeine live DVB when user zaps channels quickly. * Try to avoid this with an early O_NONBLOCK. */ if (this->fh == -1) { const char *filename; filename = (const char *) &this->mrl[5]; this->fh = xine_open_cloexec (filename, FILE_FLAGS | O_NONBLOCK); lprintf("filename '%s'\n", filename); if (this->fh == -1) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("stdin: failed to open '%s'\n"), filename); return 0; } } this->num_reads = 0; this->num_fd_reads = 0; this->num_fd_waits = 0; this->ring_write = 0; this->ring_read = 0; _x_freep (&this->ring_buf); this->mode = 0; #ifdef WIN32 setmode (this->fh, FILE_FLAGS | O_NONBLOCK); #else this->old_mode = fcntl (this->fh, F_GETFL); if (this->old_mode != -1) { if (!(this->old_mode & O_NONBLOCK)) { fcntl (this->fh, F_SETFL, this->old_mode | O_NONBLOCK); this->mode = fcntl (this->fh, F_GETFL); } else { this->mode = this->old_mode; } } this->nonblock = !!(this->mode & O_NONBLOCK); if (this->nonblock) this->ring_buf = malloc (RING_SIZE); #endif /* mrl accepted and opened successfully at this point */ /* * fill preview buffer */ this->preview_size = stdin_plugin_read (&this->input_plugin, this->preview, MAX_PREVIEW_SIZE); if (this->preview_size < 0) this->preview_size = 0; this->curpos = 0; return 1; } static input_plugin_t *stdin_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *data) { stdin_input_plugin_t *this; int fh; if (!strncasecmp (data, "stdin:/", 7) || !strncmp (data, "-", 1) || !strncmp (data, "fd://0", 6)) { fh = STDIN_FILENO; } else if (!strncasecmp (data, "fifo:/", 6)) { fh = -1; lprintf("filename '%s'\n", data + 5); } else { return NULL; } /* * mrl accepted and opened successfully at this point * * => create plugin instance */ this = calloc (1, sizeof (*this)); if (!this) return NULL; /* * buffering control */ this->nbc = xine_nbc_init (stream); if (!this->nbc) { free (this); return NULL; } #ifndef HAVE_ZERO_SAFE_MEM this->num_reads = 0; this->num_fd_reads = 0; this->num_fd_waits = 0; this->ring_write = 0; this->ring_read = 0; this->ring_buf = NULL; this->curpos = 0; this->requery_timeout = 0; #endif this->stream = stream; this->mrl = strdup (data); this->fh = fh; this->xine = stream->xine; this->timeout = 30000; this->input_plugin.open = stdin_plugin_open; this->input_plugin.get_capabilities = stdin_plugin_get_capabilities; this->input_plugin.read = stdin_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = stdin_plugin_seek; this->input_plugin.get_current_pos = stdin_plugin_get_current_pos; this->input_plugin.get_length = stdin_plugin_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = stdin_plugin_get_mrl; this->input_plugin.dispose = stdin_plugin_dispose; this->input_plugin.get_optional_data = stdin_plugin_get_optional_data; this->input_plugin.input_class = class_gen; return &this->input_plugin; } /* * stdin input plugin class stuff */ static void *stdin_plugin_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const input_class_t input_stdin_class = { .get_instance = stdin_class_get_instance, .identifier = "stdin_fifo", .description = N_("stdin streaming input plugin"), .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; return (void *)&input_stdin_class; } /* * exported plugin catalog entry */ #define INPUT_STDIN_CATALOG { PLUGIN_INPUT, 18, "stdin", XINE_VERSION_CODE, NULL, stdin_plugin_init_class } #ifndef XINE_MAKE_BUILTINS const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ INPUT_STDIN_CATALOG, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif ��������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/mmsh.c�����������������������������������������������������������������������0000644�0001750�0001750�00000054004�14647725152�013725� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * MMS over HTTP protocol * written by Thibaut Mattern * based on mms.c and specs from avifile * (http://avifile.sourceforge.net/asf-1.0.htm) * * TODO: * error messages * http support cleanup, find a way to share code with input_http.c (http.h|c) * http proxy support */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <string.h> #include <sys/types.h> #include <stdlib.h> #define LOG_MODULE "mmsh" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include "bswap.h" #include "http_helper.h" #include "mmsh.h" #include "../demuxers/asfheader.h" /* #define USERAGENT "User-Agent: NSPlayer/7.1.0.3055\r\n" */ #define USERAGENT "User-Agent: NSPlayer/4.1.0.3856\r\n" #define CLIENTGUID "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}\r\n" #define MMSH_PORT 80 #define MMSH_UNKNOWN 0 #define MMSH_SEEKABLE 1 #define MMSH_LIVE 2 #define CHUNK_HEADER_LENGTH 4 #define EXT_HEADER_LENGTH 8 #define CHUNK_TYPE_RESET 0x4324 #define CHUNK_TYPE_DATA 0x4424 #define CHUNK_TYPE_END 0x4524 #define CHUNK_TYPE_ASF_HEADER 0x4824 #define CHUNK_SIZE 65536 /* max chunk size */ #define ASF_HEADER_SIZE 8192 /* max header size */ #define SCRATCH_SIZE 1024 #define mmsh_FirstRequest \ "GET %s HTTP/1.0\r\n" \ "Accept: */*\r\n" \ USERAGENT \ "Host: %s:%d\r\n" \ "Pragma: no-cache,rate=1.000000,stream-time=0,stream-offset=0:0,request-context=%u,max-duration=0\r\n" \ CLIENTGUID \ "Connection: Close\r\n\r\n" #define mmsh_SeekableRequest \ "GET %s HTTP/1.0\r\n" \ "Accept: */*\r\n" \ USERAGENT \ "Host: %s:%d\r\n" \ "Pragma: no-cache,rate=1.000000,stream-time=%u,stream-offset=%u:%u,request-context=%u,max-duration=%u\r\n" \ CLIENTGUID \ "Pragma: xPlayStrm=1\r\n" \ "Pragma: stream-switch-count=%d\r\n" \ "Pragma: stream-switch-entry=%s\r\n" /* ffff:1:0 ffff:2:0 */ \ "Connection: Close\r\n\r\n" #define mmsh_LiveRequest \ "GET %s HTTP/1.0\r\n" \ "Accept: */*\r\n" \ USERAGENT \ "Host: %s:%d\r\n" \ "Pragma: no-cache,rate=1.000000,request-context=%u\r\n" \ "Pragma: xPlayStrm=1\r\n" \ CLIENTGUID \ "Pragma: stream-switch-count=%d\r\n" \ "Pragma: stream-switch-entry=%s\r\n" \ "Connection: Close\r\n\r\n" /* Unused requests */ #if 0 #define mmsh_PostRequest \ "POST %s HTTP/1.0\r\n" \ "Accept: */*\r\n" \ USERAGENT \ "Host: %s\r\n" \ "Pragma: client-id=%u\r\n" \ /* "Pragma: log-line=no-cache,rate=1.000000,stream-time=%u,stream-offset=%u:%u,request-context=2,max-duration=%u\r\n" */ \ "Pragma: Content-Length: 0\r\n" \ CLIENTGUID \ "\r\n" #define mmsh_RangeRequest \ "GET %s HTTP/1.0\r\n" \ "Accept: */*\r\n" \ USERAGENT \ "Host: %s:%d\r\n" \ "Range: bytes=%Lu-\r\n" \ CLIENTGUID \ "Connection: Close\r\n\r\n" #endif /* * mmsh specific types */ struct mmsh_s { xine_stream_t *stream; int s; /* url parsing */ xine_url_t url; char str[SCRATCH_SIZE]; /* scratch buffer to built strings */ asf_header_t *asf_header; int stream_type; /* receive buffer */ /* chunk */ uint16_t chunk_type; uint16_t chunk_length; uint16_t chunk_seq_number; uint8_t buf[CHUNK_SIZE]; int buf_size; int buf_read; uint8_t asf_header_buffer[ASF_HEADER_SIZE]; uint32_t asf_header_len; uint32_t asf_header_read; int seq_num; int video_stream; int audio_stream; off_t current_pos; int user_bandwidth; int playing; unsigned int start_time; }; static int send_command (mmsh_t *this, char *cmd) { lprintf ("send_command:\n%s\n", cmd); const size_t length = strlen(cmd); if ((size_t)_x_io_tcp_write (this->stream, this->s, cmd, length) != length) { xprintf (this->stream->xine, XINE_LOG_MSG, _("libmmsh: send error\n")); return 0; } return 1; } static int get_answer (mmsh_t *this) { int done, len, linenum; char *features; lprintf ("get_answer\n"); done = 0; len = 0; linenum = 0; this->stream_type = MMSH_UNKNOWN; while (!done) { if (_x_io_tcp_read(this->stream, this->s, (char*)&(this->buf[len]), 1) != 1) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: alert: end of stream\n"); return 0; } if (this->buf[len] == '\012') { this->buf[len] = '\0'; len--; if ((len >= 0) && (this->buf[len] == '\015')) { this->buf[len] = '\0'; len--; } linenum++; lprintf ("answer: >%s<\n", this->buf); if (linenum == 1) { int httpver, httpsub, httpcode; char httpstatus[51]; if (sscanf((char*)this->buf, "HTTP/%d.%d %d %50[^\015\012]", &httpver, &httpsub, &httpcode, httpstatus) != 4) { xine_log (this->stream->xine, XINE_LOG_MSG, _("libmmsh: bad response format\n")); return 0; } if (httpcode >= 300 && httpcode < 400) { xine_log (this->stream->xine, XINE_LOG_MSG, _("libmmsh: 3xx redirection not implemented: >%d %s<\n"), httpcode, httpstatus); return 0; } if (httpcode < 200 || httpcode >= 300) { xine_log (this->stream->xine, XINE_LOG_MSG, _("libmmsh: http status not 2xx: >%d %s<\n"), httpcode, httpstatus); return 0; } } else { if (!strncasecmp((char*)this->buf, "Location: ", 10)) { xine_log (this->stream->xine, XINE_LOG_MSG, _("libmmsh: Location redirection not implemented\n")); return 0; } if (!strncasecmp((char*)this->buf, "Pragma:", 7)) { features = strstr((char*)(this->buf + 7), "features="); if (features) { if (strstr(features, "seekable")) { lprintf("seekable stream\n"); this->stream_type = MMSH_SEEKABLE; } else { if (strstr(features, "broadcast")) { lprintf("live stream\n"); this->stream_type = MMSH_LIVE; } } } } } if (len == -1) { done = 1; } else { len = 0; } } else { len ++; } } if (this->stream_type == MMSH_UNKNOWN) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: unknown stream type\n"); this->stream_type = MMSH_SEEKABLE; /* FIXME ? */ } return 1; } static int get_chunk_header (mmsh_t *this) { uint8_t chunk_header[CHUNK_HEADER_LENGTH]; uint8_t ext_header[EXT_HEADER_LENGTH]; int read_len; int ext_header_len; lprintf ("get_chunk_header\n"); /* read chunk header */ read_len = _x_io_tcp_read(this->stream, this->s, (char*)chunk_header, CHUNK_HEADER_LENGTH); if (read_len != CHUNK_HEADER_LENGTH) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: chunk header read failed, %d != %d\n", read_len, CHUNK_HEADER_LENGTH); return 0; } this->chunk_type = _X_LE_16 (&chunk_header[0]); this->chunk_length = _X_LE_16 (&chunk_header[2]); switch (this->chunk_type) { case CHUNK_TYPE_DATA: ext_header_len = 8; break; case CHUNK_TYPE_END: ext_header_len = 4; break; case CHUNK_TYPE_ASF_HEADER: ext_header_len = 8; break; case CHUNK_TYPE_RESET: ext_header_len = 4; break; default: ext_header_len = 0; } /* read extended header */ if (ext_header_len > 0) { read_len = _x_io_tcp_read(this->stream, this->s, (char*)ext_header, ext_header_len); if (read_len != ext_header_len) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "extended header read failed, %d != %d\n", read_len, ext_header_len); return 0; } } switch (this->chunk_type) { case CHUNK_TYPE_DATA: this->chunk_seq_number = _X_LE_32 (&ext_header[0]); lprintf ("chunk type: CHUNK_TYPE_DATA\n"); lprintf ("chunk length: %d\n", this->chunk_length); lprintf ("chunk seq: %d\n", this->chunk_seq_number); lprintf ("unknown: %d\n", ext_header[4]); lprintf ("mmsh seq: %d\n", ext_header[5]); lprintf ("len2: %d\n", _X_LE_16(&ext_header[6])); break; case CHUNK_TYPE_END: this->chunk_seq_number = _X_LE_32 (&ext_header[0]); lprintf ("chunk type: CHUNK_TYPE_END\n"); lprintf ("continue: %d\n", this->chunk_seq_number); break; case CHUNK_TYPE_ASF_HEADER: lprintf ("chunk type: CHUNK_TYPE_ASF_HEADER\n"); lprintf ("chunk length: %d\n", this->chunk_length); lprintf ("unknown: %2X %2X %2X %2X %2X %2X\n", ext_header[0], ext_header[1], ext_header[2], ext_header[3], ext_header[4], ext_header[5]); lprintf ("len2: %d\n", _X_LE_16(&ext_header[6])); break; case CHUNK_TYPE_RESET: lprintf ("chunk type: CHUNK_TYPE_RESET\n"); lprintf ("chunk seq: %d\n", this->chunk_seq_number); lprintf ("unknown: %2X %2X %2X %2X\n", ext_header[0], ext_header[1], ext_header[2], ext_header[3]); break; default: lprintf ("unknown chunk: %4X\n", this->chunk_type); } this->chunk_length -= ext_header_len; return 1; } static int get_header (mmsh_t *this) { int len = 0; lprintf("get_header\n"); this->asf_header_len = 0; /* read chunk */ while (1) { if (get_chunk_header(this)) { if (this->chunk_type == CHUNK_TYPE_ASF_HEADER) { if ((this->asf_header_len + this->chunk_length) > ASF_HEADER_SIZE) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: the asf header exceed %d bytes\n", ASF_HEADER_SIZE); return 0; } else { len = _x_io_tcp_read(this->stream, this->s, (char*)(this->asf_header_buffer + this->asf_header_len), this->chunk_length); this->asf_header_len += len; if (len != this->chunk_length) { return 0; } } } else { break; } } else { lprintf("get_chunk_header failed\n"); return 0; } } if (this->chunk_type == CHUNK_TYPE_DATA) { /* read the first data chunk */ len = _x_io_tcp_read(this->stream, this->s, (char*)this->buf, this->chunk_length); if (len != this->chunk_length) { return 0; } else { return 1; } } else { /* unexpected packet type */ return 0; } } static int interp_header (mmsh_t *this) { lprintf ("interp_header, header_len=%d\n", this->asf_header_len); /* delete previous header */ if (this->asf_header) { asf_header_delete(this->asf_header); } /* the header starts with : * byte 0-15: header guid * byte 16-23: header length */ this->asf_header = asf_header_new(this->asf_header_buffer + 24, this->asf_header_len - 24); if (!this->asf_header) return 0; this->buf_size = this->asf_header->file->packet_size; return 1; } static const char mmsh_proto_s[][8] = { "mms", "mmsh", "" }; static int mmsh_valid_proto (const char *proto) { int i = 0; lprintf("mmsh_valid_proto\n"); if (!proto) return 0; while(*(mmsh_proto_s[i])) { if (!strcasecmp(proto, mmsh_proto_s[i])) { return 1; } i++; } return 0; } static void report_progress (xine_stream_t *stream, int p) { xine_event_t event; xine_progress_data_t prg; prg.description = _("Connecting MMS server (over http)..."); prg.percent = p; event.type = XINE_EVENT_PROGRESS; event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (stream, &event); } /* * returns 1 on error */ static int mmsh_tcp_connect(mmsh_t *this) { int progress, res; if (!this->url.port) this->url.port = MMSH_PORT; /* * try to connect */ lprintf("try to connect to %s on port %d \n", this->url.host, this->url.port); this->s = _x_io_tcp_connect (this->stream, this->url.host, this->url.port); if (this->s < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: failed to connect '%s'\n", this->url.host); return 1; } /* connection timeout 15s */ progress = 0; do { report_progress(this->stream, progress); res = _x_io_select (this->stream, this->s, XIO_WRITE_READY, 500); progress += 1; } while ((res == XIO_TIMEOUT) && (progress < 30)); if (res != XIO_READY) { return 1; } lprintf ("connected\n"); return 0; } /* * firts http request */ static int mmsh_connect_int(mmsh_t *this, int bandwidth) { /* * let the negotiations begin... */ /* first request */ lprintf("first http request\n"); snprintf (this->str, SCRATCH_SIZE, mmsh_FirstRequest, this->url.uri, this->url.host, this->url.port, 1); if (!send_command (this, this->str)) return 0; if (!get_answer (this)) return 0; get_header (this); /* FIXME: it returns 0 */ if (!interp_header (this)) return 0; _x_io_tcp_close (this->stream, this->s); this->s = -1; report_progress (this->stream, 20); asf_header_choose_streams (this->asf_header, bandwidth, &this->video_stream, &this->audio_stream); lprintf("audio stream %d, video stream %d\n", this->audio_stream, this->video_stream); asf_header_disable_streams (this->asf_header, this->video_stream, this->audio_stream); if (mmsh_tcp_connect(this)) return 0; return 1; } /* * second http request */ static int mmsh_connect_int2(mmsh_t *this, int bandwidth) { int i; char stream_selection[10 * ASF_MAX_NUM_STREAMS]; /* 10 chars per stream */ int offset; /* second request */ lprintf("second http request\n"); (void)bandwidth; /* stream selection string */ /* The same selection is done with mmst */ /* 0 means selected */ /* 2 means disabled */ offset = 0; for (i = 0; i < this->asf_header->stream_count; i++) { int size; if ((i == this->audio_stream) || (i == this->video_stream)) { size = snprintf(stream_selection + offset, sizeof(stream_selection) - offset, "ffff:%d:0 ", this->asf_header->streams[i]->stream_number); } else { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "disabling stream %d\n", this->asf_header->streams[i]->stream_number); size = snprintf(stream_selection + offset, sizeof(stream_selection) - offset, "ffff:%d:2 ", this->asf_header->streams[i]->stream_number); } if (size < 0) return 0; offset += size; } switch (this->stream_type) { case MMSH_SEEKABLE: snprintf (this->str, SCRATCH_SIZE, mmsh_SeekableRequest, this->url.uri, this->url.host, this->url.port, this->start_time, 0, 0, 2, 0, this->asf_header->stream_count, stream_selection); break; case MMSH_LIVE: snprintf (this->str, SCRATCH_SIZE, mmsh_LiveRequest, this->url.uri, this->url.host, this->url.port, 2, this->asf_header->stream_count, stream_selection); break; } if (!send_command (this, this->str)) return 0; lprintf("before read \n"); if (!get_answer (this)) return 0; if (!get_header (this)) return 0; #if 0 if (!interp_header (this)) return 0; asf_header_disable_streams (this->asf_header, this->video_stream, this->audio_stream); #endif return 1; } mmsh_t *mmsh_connect (xine_stream_t *stream, const char *url, int bandwidth) { mmsh_t *this; if (!url) return NULL; report_progress (stream, 0); this = calloc(1, sizeof (mmsh_t)); if (!this) return NULL; this->stream = stream; //this->url = strdup(url); this->s = -1; this->asf_header_len = 0; this->asf_header_read = 0; this->buf_size = 0; this->buf_read = 0; this->current_pos = 0; this->user_bandwidth = bandwidth; report_progress (stream, 0); if (!_x_url_parse2 (url, &this->url)) { xine_log (this->stream->xine, XINE_LOG_MSG, _("invalid url\n")); goto fail; } if (!mmsh_valid_proto(this->url.proto)) { xine_log (this->stream->xine, XINE_LOG_MSG, _("unsupported protocol\n")); goto fail; } if (mmsh_tcp_connect(this)) goto fail; report_progress (stream, 30); if (!mmsh_connect_int(this, this->user_bandwidth)) goto fail; report_progress (stream, 100); lprintf("mmsh_connect: passed\n" ); return this; fail: lprintf("mmsh_connect: failed\n" ); if (this->s != -1) _x_io_tcp_close(this->stream, this->s); _x_url_cleanup(&this->url); free(this); lprintf("mmsh_connect: failed return\n" ); return NULL; } /* * returned value: * 0: error * 1: data packet read * 2: new header read */ static int get_media_packet (mmsh_t *this) { int len = 0; lprintf("get_media_packet: this->packet_length: %d\n", this->asf_header->file->packet_size); if (get_chunk_header(this)) { switch (this->chunk_type) { case CHUNK_TYPE_END: /* this->chunk_seq_number: * 0: stop * 1: a new stream follows */ if (this->chunk_seq_number == 0) return 0; _x_io_tcp_close(this->stream, this->s); this->s = -1; if (mmsh_tcp_connect(this)) return 0; if (!mmsh_connect_int(this, this->user_bandwidth)) return 0; this->playing = 0; /* mmsh_connect_int reads the first data packet */ /* this->buf_size is set by mmsh_connect_int */ return 2; case CHUNK_TYPE_DATA: /* nothing to do */ break; case CHUNK_TYPE_RESET: /* next chunk is an ASF header */ if (this->chunk_length != 0) { /* that's strange, don't know what to do */ return 0; } if (!get_header(this)) return 0; interp_header(this); return 2; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: unexpected chunk type\n"); return 0; } len = _x_io_tcp_read (this->stream, this->s, (char*)this->buf, this->chunk_length); if (len == this->chunk_length) { /* explicit padding with 0 */ if (this->chunk_length > this->asf_header->file->packet_size) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: chunk_length(%d) > packet_length(%d)\n", this->chunk_length, this->asf_header->file->packet_size); return 0; } memset(this->buf + this->chunk_length, 0, this->asf_header->file->packet_size - this->chunk_length); return 1; } else { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: read error, %d != %d\n", len, this->chunk_length); return 0; } } else { return 0; } } size_t mmsh_peek_header (mmsh_t *this, char *data, size_t maxsize) { size_t len; lprintf("mmsh_peek_header\n"); len = (this->asf_header_len < maxsize) ? this->asf_header_len : maxsize; memcpy(data, this->asf_header_buffer, len); return len; } int mmsh_read (mmsh_t *this, char *data, int len) { int total; total = 0; lprintf ("mmsh_read: len: %d\n", len); while (total < len) { if (this->asf_header_read < this->asf_header_len) { int n, bytes_left ; bytes_left = this->asf_header_len - this->asf_header_read; if ((len-total) < bytes_left) n = len-total; else n = bytes_left; xine_fast_memcpy (&data[total], &this->asf_header_buffer[this->asf_header_read], n); this->asf_header_read += n; total += n; this->current_pos += n; if (this->asf_header_read == this->asf_header_len) break; } else { int n, bytes_left ; if (!this->playing) { if (!mmsh_connect_int2 (this, this->user_bandwidth)) break; this->playing = 1; } bytes_left = this->buf_size - this->buf_read; if (bytes_left == 0) { int packet_type; this->buf_read = 0; packet_type = get_media_packet (this); if (packet_type == 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmmsh: get_media_packet failed\n"); return total; } else if (packet_type == 2) { continue; } bytes_left = this->buf_size; } if ((len - total) < bytes_left) n = len - total; else n = bytes_left; xine_fast_memcpy (&data[total], &this->buf[this->buf_read], n); this->buf_read += n; total += n; this->current_pos += n; } } return total; } void mmsh_close (mmsh_t *this) { lprintf("mmsh_close\n"); if (this->s != -1) _x_io_tcp_close(this->stream, this->s); if (this->asf_header) asf_header_delete(this->asf_header); _x_url_cleanup(&this->url); free(this); } uint32_t mmsh_get_length (mmsh_t *this) { return this->asf_header->file->file_size; } off_t mmsh_get_current_pos (mmsh_t *this) { return this->current_pos; } void mmsh_set_start_time (mmsh_t *this, int time_offset) { if (time_offset >= 0) this->start_time = time_offset; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_ssh.c������������������������������������������������������������������0000644�0001750�0001750�00000053640�14647725152�015002� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <libssh2.h> #include <libssh2_sftp.h> #define LOG_MODULE "input_ssh" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "net_buf_ctrl.h" #include "http_helper.h" #include "input_helper.h" #define DEFAULT_SSH_PORT 22 typedef struct { input_plugin_t input_plugin; xine_t *xine; xine_stream_t *stream; char *mrl; /* mrl without credentials */ char *mrl_private; off_t curpos; off_t file_size; nbc_t *nbc; /* ssh */ int fd; LIBSSH2_SESSION *session; /* sftp */ LIBSSH2_SFTP *sftp_session; LIBSSH2_SFTP_HANDLE *sftp_handle; /* scp */ LIBSSH2_CHANNEL *scp_channel; size_t preview_size; char preview[MAX_PREVIEW_SIZE]; } ssh_input_plugin_t; /* * helper functions */ static int _wait_socket(ssh_input_plugin_t *this) { int flags = 0; int dir; dir = libssh2_session_block_directions(this->session); if (dir & LIBSSH2_SESSION_BLOCK_INBOUND) flags |= XIO_READ_READY; if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND) flags |= XIO_WRITE_READY; return _x_io_select(this->stream, this->fd, flags, 500); } static void _emit_authentication_request(ssh_input_plugin_t *this) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Authentication required for '%s'\n", this->mrl); if (this->stream) _x_message(this->stream, XINE_MSG_AUTHENTICATION_NEEDED, this->mrl, "Authentication required", NULL); } static int _ssh_connect(ssh_input_plugin_t *this, const xine_url_t *url) { int port = url->port; int rc; /* check parameters */ if (!port) port = DEFAULT_SSH_PORT; if (!url->user) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "No username in mrl '%s'\n", this->mrl); _emit_authentication_request(this); return -1; } /* connect to remote host */ this->fd = _x_io_tcp_connect (this->stream, url->host, port); if (this->fd < 0) { return -1; } do { rc = _x_io_tcp_connect_finish(this->stream, this->fd, 1000); if (rc == XIO_READY) break; if (rc != XIO_TIMEOUT) return -1; } while (1); /* init ssh session */ this->session = libssh2_session_init(); if (!this->session) { return -1; } /* enable non-blocking mode (allow stopping if network is stuck) */ libssh2_session_set_blocking(this->session, 0); do { rc = libssh2_session_handshake(this->session, this->fd); if (this->stream && _x_action_pending(this->stream)) return -1; } while (rc == LIBSSH2_ERROR_EAGAIN); if (rc) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to establish SSH session: %d\n", rc); return -1; } /* authenticate */ if (url->password && url->password[0]) { /* password */ do { rc = libssh2_userauth_password(this->session, url->user, url->password); if (this->stream && _x_action_pending(this->stream)) return -1; } while (rc == LIBSSH2_ERROR_EAGAIN); if (rc) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Authentication by password failed.\n"); _emit_authentication_request(this); return -1; } } else { /* public key */ const char *home = xine_get_homedir(); char *pub = _x_asprintf("%s/.ssh/id_rsa.pub", home); char *priv = _x_asprintf("%s/.ssh/id_rsa", home); if (pub && priv) do { rc = libssh2_userauth_publickey_fromfile(this->session, url->user, pub, priv, url->password); if (this->stream && _x_action_pending(this->stream)) { free(pub); free(priv); return -1; } } while (rc == LIBSSH2_ERROR_EAGAIN); free(pub); free(priv); if (rc) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Authentication by public key failed\n"); _emit_authentication_request(this); return -1; } } return 0; } static int _sftp_session_init(ssh_input_plugin_t *this) { int rc; do { this->sftp_session = libssh2_sftp_init(this->session); if (!this->sftp_session) { rc = libssh2_session_last_errno(this->session); if (rc != LIBSSH2_ERROR_EAGAIN) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unable to init SFTP session\n"); return -1; } _wait_socket(this); if (this->stream && _x_action_pending(this->stream)) return -1; } } while (!this->sftp_session); return 0; } static int _scp_channel_init(ssh_input_plugin_t *this, const char *uri) { #if LIBSSH2_VERSION_NUM < 0x010800 struct stat sb; #else libssh2_struct_stat sb; #endif int rc; /* Request a file via SCP */ do { #if LIBSSH2_VERSION_NUM < 0x010800 this->scp_channel = libssh2_scp_recv(this->session, uri, &sb); #else this->scp_channel = libssh2_scp_recv2(this->session, uri, &sb); #endif if (!this->scp_channel) { rc = libssh2_session_last_errno(this->session); if (rc != LIBSSH2_ERROR_EAGAIN) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unable to init SCP channel for '%s'\n", uri); return -1; } _wait_socket(this); if (_x_action_pending(this->stream)) return -1; } } while (!this->scp_channel); this->file_size = sb.st_size; return 0; } static int _sftp_open(ssh_input_plugin_t *this, const char *uri) { int rc; /* Request a file via SFTP */ do { this->sftp_handle = libssh2_sftp_open(this->sftp_session, uri, LIBSSH2_FXF_READ, 0); if (!this->sftp_handle) { rc = libssh2_session_last_errno(this->session); if (rc != LIBSSH2_ERROR_EAGAIN) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unable to open SFTP file '%s'\n", uri); return -1; } _wait_socket(this); if (_x_action_pending(this->stream)) return -1; } } while (!this->sftp_handle); return 0; } /* * plugin interface */ static off_t _scp_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; uint8_t *buf = buf_gen; off_t got = 0; int rc; /* handle preview chunk */ if (this->curpos < (off_t)this->preview_size) { size_t n = this->preview_size - this->curpos; if ((off_t)n > len) n = len; memcpy (buf, this->preview + this->curpos, n); this->curpos += n; got += n; } /* handle actual read */ while (got < len) { /* check for EOF */ if (this->curpos + got >= this->file_size) { goto out; } while ((rc = libssh2_channel_read(this->scp_channel, buf + got, len - got)) == LIBSSH2_ERROR_EAGAIN) { if (libssh2_channel_eof(this->scp_channel)) { goto out; } _wait_socket(this); if (_x_action_pending(this->stream)) { errno = EINTR; if (got) goto out; return -1; } } if (rc <= 0) { if (rc < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "SCP read failed: %d\n", rc); if (got) goto out; return -1; } if (libssh2_channel_eof(this->scp_channel)) { goto out; } } got += rc; } out: this->curpos += got; return got; } static off_t _sftp_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; uint8_t *buf = buf_gen; off_t got = 0; int rc; if (this->curpos + len >= this->file_size) { /* check if file growed */ this->file_size = 0; this_gen->get_length(this_gen); if (this->curpos >= this->file_size) { return 0; } } while (got < len) { while ((rc = libssh2_sftp_read(this->sftp_handle, buf + got, len - got)) == LIBSSH2_ERROR_EAGAIN) { _wait_socket(this); if (_x_action_pending(this->stream)) { errno = EINTR; if (got) goto out; return -1; } } if (rc <= 0) { if (rc < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "SCP read failed: %d\n", rc); if (got) goto out; return -1; } goto out; } got += rc; } out: this->curpos += got; return got; } static off_t _scp_get_length (input_plugin_t *this_gen) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; return this->file_size; } static off_t _sftp_get_length (input_plugin_t *this_gen) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; LIBSSH2_SFTP_ATTRIBUTES attrs; int rc; if (this->file_size) return this->file_size; memset(&attrs, 0, sizeof(attrs)); while ((rc = libssh2_sftp_fstat_ex(this->sftp_handle, &attrs, 0)) == LIBSSH2_ERROR_EAGAIN) { if (_x_action_pending(this->stream)) return 0; } if (rc) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "SFTP stat failed: %d\n", rc); return 0; } this->file_size = attrs.filesize; return this->file_size; } static off_t _get_current_pos (input_plugin_t *this_gen) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; return this->curpos; } static off_t _scp_seek (input_plugin_t *this_gen, off_t offset, int origin) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; return _x_input_seek_preview(this_gen, offset, origin, &this->curpos, this->file_size, this->preview_size); } static off_t _sftp_seek (input_plugin_t *this_gen, off_t offset, int origin) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; switch (origin) { case SEEK_CUR: offset = this->curpos + offset; break; case SEEK_END: offset = this->file_size + offset; break; case SEEK_SET: break; default: return -1; } if (offset < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "SFTP seek failed: position %" PRId64 " outside of file.\n", (int64_t)offset); return -1; } this->curpos = offset; libssh2_sftp_seek64(this->sftp_handle, offset); return this->curpos; } static const char *_get_mrl (input_plugin_t *this_gen) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; return this->mrl; } static int _get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: if (this->preview_size > 0) { memcpy (data, this->preview, this->preview_size); return this->preview_size; } } return INPUT_OPTIONAL_UNSUPPORTED; } static void _dispose (input_plugin_t *this_gen) { ssh_input_plugin_t *this = (ssh_input_plugin_t *) this_gen; if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } if (this->sftp_handle) { while (libssh2_sftp_close(this->sftp_handle) == LIBSSH2_ERROR_EAGAIN); this->sftp_handle = NULL; } if (this->scp_channel) { while (libssh2_channel_free(this->scp_channel) == LIBSSH2_ERROR_EAGAIN); this->scp_channel = NULL; } if (this->sftp_session) { while (libssh2_sftp_shutdown(this->sftp_session) == LIBSSH2_ERROR_EAGAIN); this->sftp_session = NULL; } if (this->session) { while (libssh2_session_disconnect(this->session, "close") == LIBSSH2_ERROR_EAGAIN); while (libssh2_session_free(this->session) == LIBSSH2_ERROR_EAGAIN); this->session = NULL; } if (this->fd != -1) { _x_io_tcp_close(this->stream, this->fd); this->fd = -1; } _x_freep (&this->mrl); _x_freep_wipe_string(&this->mrl_private); free (this_gen); libssh2_exit(); } static int _scp_fill_preview(ssh_input_plugin_t *this) { off_t got; got = _scp_read (&this->input_plugin, this->preview, sizeof(this->preview)); if (got < 1 || got > (off_t)sizeof(this->preview)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unable to read preview data\n"); return -1; } this->preview_size = got; return 0; } static int _open_plugin (input_plugin_t *this_gen) { ssh_input_plugin_t *this = (ssh_input_plugin_t *)this_gen; xine_url_t url; int result = 0, rc; int is_scp; this->curpos = 0; /* parse mrl */ rc = _x_url_parse2(this->mrl_private, &url); _x_freep_wipe_string(&this->mrl_private); if (!rc) { _x_message(this->stream, XINE_MSG_GENERAL_WARNING, "malformed url", NULL); return 0; } /* set up ssh connection */ result = _ssh_connect(this, &url); if (result < 0) goto out; is_scp = !strncasecmp (url.proto, "scp", 3); if (is_scp) { /* Request a file via SCP */ if (_scp_channel_init(this, url.uri) < 0) goto out; if (_scp_fill_preview(this) < 0) goto out; } else { /* Request a file via SFTP */ if (_sftp_session_init(this) < 0) goto out; if (_sftp_open(this, url.uri) < 0) goto out; _sftp_get_length(this_gen); } /* succeed */ result = 1; out: _x_url_cleanup(&url); return result; } /* * plugin class */ static input_plugin_t *_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { ssh_input_plugin_t *this; int sftp, scp, rc; /* check mrl type */ sftp = !strncasecmp (mrl, "sftp://", 7); scp = !strncasecmp (mrl, "scp://", 6); if (!sftp && !scp) return NULL; /* initialize libssh2 */ rc = libssh2_init(0); if (rc) { xprintf(stream ? stream->xine : NULL, XINE_VERBOSITY_LOG, LOG_MODULE ": " "libssh2 initialization failed (%d)\n", rc); return NULL; } /* initialize plugin */ this = calloc(1, sizeof(*this)); if (!this) return NULL; this->mrl_private = strdup(mrl); this->mrl = _x_mrl_remove_auth(mrl); if (!this->mrl || !this->mrl_private) { _dispose(&this->input_plugin); return NULL; } this->stream = stream; this->fd = -1; this->xine = stream ? stream->xine : NULL; if (stream) { /* not needed for directory browsing */ this->nbc = nbc_init (stream); } this->input_plugin.open = _open_plugin; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_optional_data = _get_optional_data; this->input_plugin.get_current_pos = _get_current_pos; this->input_plugin.get_mrl = _get_mrl; this->input_plugin.dispose = _dispose; if (scp) { this->input_plugin.get_capabilities = _x_input_get_capabilities_preview; this->input_plugin.read = _scp_read; this->input_plugin.seek = _scp_seek; this->input_plugin.get_length = _scp_get_length; } else { this->input_plugin.get_capabilities = _x_input_get_capabilities_seekable; this->input_plugin.read = _sftp_read; this->input_plugin.seek = _sftp_seek; this->input_plugin.get_length = _sftp_get_length; } this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * SCP class */ static void *scp_init_class(xine_t *xine, const void *data) { static const input_class_t input_scp_class = { .get_instance = _get_instance, .description = N_("SCP input plugin"), .identifier = "SCP", .dispose = NULL, }; (void)xine; (void)data; return (void *)&input_scp_class; } /* * SFTP class */ typedef struct { input_class_t input_class; xine_t *xine; /* browser */ xine_mrl_t **mrls; } sftp_input_class_t; static ssh_input_plugin_t *_open_input(sftp_input_class_t *this, xine_url_t *url, const char *mrl) { ssh_input_plugin_t *input; input = (ssh_input_plugin_t *)this->input_class.get_instance(&this->input_class, NULL, mrl); if (!input) return NULL; input->xine = this->xine; if (_ssh_connect(input, url)) goto fail; if (_sftp_session_init(input)) goto fail; libssh2_session_set_blocking(input->session, 1); return input; fail: input->input_plugin.dispose(&input->input_plugin); return NULL; } static int _read_dir(sftp_input_class_t *this, ssh_input_plugin_t *input, const char *mrl, const char *uri, int *nFiles) { LIBSSH2_SFTP_ATTRIBUTES attr; LIBSSH2_SFTP_HANDLE *dir; xine_mrl_t **mrls = NULL; size_t mrls_size = 0; size_t n = 0; char file[1024]; int show_hidden_files; int rc; rc = libssh2_sftp_stat(input->sftp_session, uri, &attr); if (rc) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "remote stat failed for '%s': %d\n", uri, rc); return -1; } if (!LIBSSH2_SFTP_S_ISDIR(attr.permissions)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "'%s' is not a directory\n", uri); this->mrls = _x_input_alloc_mrls(1); if (this->mrls) { this->mrls[0]->type = mrl_net | mrl_file | mrl_file_normal; this->mrls[0]->mrl = strdup(mrl); *nFiles = 1; } return 0; } dir = libssh2_sftp_opendir(input->sftp_session, uri); if (!dir) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "error opening directory '%s': %d\n", uri, rc); return -1; } show_hidden_files = _x_input_get_show_hidden_files(this->xine->config); /* add link to back */ mrls_size += 64; mrls = _x_input_alloc_mrls(mrls_size); if (!mrls) goto fail; mrls[n]->type = mrl_net | mrl_file | mrl_file_directory; mrls[n]->origin = strdup(mrl); mrls[n]->mrl = _x_asprintf("%s/..", mrl); n++; /* read directory */ while ( 0 != (rc = libssh2_sftp_readdir(dir, file, sizeof(file), &attr))) { if (rc < 0 ) { if (rc == LIBSSH2_ERROR_BUFFER_TOO_SMALL) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "ignoring too long file name"); continue; } if (rc == LIBSSH2_ERROR_EAGAIN) continue; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "directory '%s' read failed: %d", uri, rc); break; } if (!show_hidden_files && file[0] == '.') continue; if (!strcmp(file, ".") || !strcmp(file, "..")) continue; if (n >= mrls_size) { mrls_size += 64; if (!_x_input_realloc_mrls(&mrls, mrls_size)) break; } int type = LIBSSH2_SFTP_S_ISDIR( attr.permissions ) ? mrl_file_directory : mrl_file_normal; mrls[n]->type = type | mrl_net | mrl_file; mrls[n]->origin = strdup(mrl); mrls[n]->mrl = _x_asprintf("%s/%s", mrl, file); mrls[n]->size = attr.filesize; n++; } fail: if (n > 2) _x_input_sort_mrls(mrls + 1, n - 1); if (dir) libssh2_sftp_close(dir); *nFiles = n; this->mrls = mrls; return 0; } static xine_mrl_t **_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { sftp_input_class_t *this = (sftp_input_class_t *) this_gen; ssh_input_plugin_t *input = NULL; xine_url_t url; _x_input_free_mrls(&this->mrls); *nFiles = 0; if (!filename || !strcmp(filename, "sftp:/") || !strcmp(filename, "sftp://")) { this->mrls = _x_input_get_default_server_mrls(this->xine->config, "sftp://", nFiles); if (!this->mrls) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "missing sftp mrl\n"); return this->mrls; } if (!_x_url_parse2(filename, &url)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "malformed url '%s'", filename); return NULL; } input = _open_input(this, &url, filename); if (!input) goto out; _read_dir(this, input, filename, url.uri, nFiles); out: _x_url_cleanup(&url); if (input) { input->input_plugin.dispose(&input->input_plugin); } return this->mrls; } static void _dispose_class_sftp(input_class_t *this_gen) { sftp_input_class_t *this = (sftp_input_class_t *) this_gen; _x_input_free_mrls(&this->mrls); free(this_gen); } static void *sftp_init_class(xine_t *xine, const void *data) { sftp_input_class_t *this; (void)data; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->input_class.get_instance = _get_instance; this->input_class.description = N_("SFTP input plugin"); this->input_class.identifier = "SFTP"; this->input_class.get_dir = _get_dir; this->input_class.dispose = _dispose_class_sftp; this->xine = xine; _x_input_register_show_hidden_files(xine->config); _x_input_register_default_servers(xine->config); return this; } /* * exported plugin catalog entry */ const input_info_t input_info_sftp = { .priority = 100, }; const input_info_t input_info_scp = { .priority = 100, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 18, "SFTP", XINE_VERSION_CODE, &input_info_sftp, sftp_init_class }, { PLUGIN_INPUT, 18, "SCP", XINE_VERSION_CODE, &input_info_scp, scp_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_v4l.c������������������������������������������������������������������0000644�0001750�0001750�00000160373�14647725152�014714� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2003-2020 the xine project * Copyright (C) 2003 J.Asselman <j.asselman@itsec-ps.nl> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * v4l input plugin */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <unistd.h> #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> /* From GStreamer's v4l plugin: * Because of some really cool feature in video4linux1, also known as * 'not including sys/types.h and sys/time.h', we had to include it * ourselves. In all their intelligence, these people decided to fix * this in the next version (video4linux2) in such a cool way that it * breaks all compilations of old stuff... * The real problem is actually that linux/time.h doesn't use proper * macro checks before defining types like struct timeval. The proper * fix here is to either fuck the kernel header (which is what we do * by defining _LINUX_TIME_H, an innocent little hack) or by fixing it * upstream, which I'll consider doing later on. If you get compiler * errors here, check your linux/time.h && sys/time.h header setup. */ #define _LINUX_TIME_H #include <linux/videodev.h> #include <sys/ioctl.h> #include <sys/mman.h> #include <errno.h> /* Used to capture the audio data */ #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #ifdef HAVE_ALSA #include <alsa/asoundlib.h> #endif #define XINE_ENABLE_EXPERIMENTAL_FEATURES /********** logging **********/ /* #define LOG_MODULE "input_v4l" */ #define LOG_VERBOSE /* #define LOG */ #ifdef LOG #define LOG_MODULE log_line_prefix() static char *log_line_prefix() { static int print_timestamp = 1; struct timeval now; struct tm now_tm; char buffer[64]; if( print_timestamp ) { gettimeofday( &now, NULL ); localtime_r( &now.tv_sec, &now_tm ); strftime( buffer, sizeof( buffer ), "%Y-%m-%d %H:%M:%S", &now_tm ); printf( "%s.%6.6ld: ", buffer, now.tv_usec ); } return "input_v4l"; } #endif #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #define NUM_FRAMES 15 /* Our CPU can't handle de-interlacing at 768. */ #define MAX_RES 640 typedef struct { int width; int height; } resolution_t; static const resolution_t resolutions[] = { { 768, 576 }, { 640, 480 }, { 384, 288 }, { 320, 240 }, { 160, 120 } }; #define NUM_RESOLUTIONS (sizeof(resolutions)/sizeof(resolutions[0])) #define RADIO_DEV "/dev/radio0" #define VIDEO_DEV "/dev/video0" #ifdef HAVE_ALSA #define AUDIO_DEV "plughw:0,0" #endif static const char *const tv_standard_names[] = { "AUTO", "PAL", "NTSC", "SECAM", "OLD", NULL }; static const int tv_standard_values[] = { VIDEO_MODE_AUTO, VIDEO_MODE_PAL, VIDEO_MODE_NTSC, VIDEO_MODE_SECAM, -1 }; #if !defined(NDELAY) && defined(O_NDELAY) #define FNDELAY O_NDELAY #endif typedef struct pvrscr_s pvrscr_t; typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; char *mrl; off_t curpos; int old_interlace; int old_zoomx; int old_zoomy; int audio_only; buf_element_t *frames_base; void *audio_content_base; void *video_content_base; /* Audio */ buf_element_t *aud_frames; pthread_mutex_t aud_frames_lock; pthread_cond_t aud_frame_freed; #ifdef HAVE_ALSA /* Handle for the PCM device */ snd_pcm_t *pcm_handle; /* Record stream (via line 1) */ snd_pcm_stream_t pcm_stream; /* Information and configuration for the PCM stream */ snd_pcm_hw_params_t *pcm_hwparams; /* Name of the PCM device, plughw:0,0?=>soundcard,device*/ char *pcm_name; /* Use alsa to capture the sound (for a/v sync) */ char audio_capture; int exact_rate; /* Actual sample rate sndpcm_hw_params_set_rate_near */ int dir; /* exact rate == rate --> dir = 0 exact rate < rate --> dir = -1 exact rate > rate --> dir = 1 */ unsigned char *pcm_data; int64_t pts_aud_start; #endif int audio_header_sent; int rate; /* Sample rate */ int periods; /* Number of periods */ int periodsize; /* Periodsize in bytes */ int bits; /* Video */ buf_element_t *vid_frames; pthread_mutex_t vid_frames_lock; pthread_cond_t vid_frame_freed; int video_fd; int radio_fd; int input; int tuner; unsigned long frequency; unsigned long calc_frequency; char *tuner_name; int radio; /* ask for a radio channel */ int channel; /* channel number */ struct video_channel video_channel; struct video_tuner video_tuner; struct video_capability video_cap; struct video_audio audio; struct video_audio audio_saved; struct video_mbuf gb_buffers; int video_header_sent; int frame_format; const resolution_t *resolution; int frame_size; int use_mmap; uint8_t *video_buf; int gb_frame; struct video_mmap gb_buf; int64_t start_time; xine_event_queue_t *event_queue; pvrscr_t *scr; int scr_tuning; } v4l_input_plugin_t; /* * *************************************************** * unix System Clock Reference + fine tuning * * This code is copied and paste from the input_pvr.c * * the fine tuning option is used to change play * speed in order to regulate fifo usage, that is, * trying to match the rate of generated data. * * OBS: use with audio.synchronization.av_sync_method=resample * *************************************************** */ #define SCR_PAUSED -2 #define SCR_FW -3 #define SCR_SKIP -4 struct pvrscr_s { scr_plugin_t scr; struct timeval cur_time; int64_t cur_pts; int xine_speed; double speed_factor; double speed_tuning; pthread_mutex_t lock; }; static int pvrscr_get_priority(scr_plugin_t *scr) { (void)scr; return 10; /* high priority */ } /* Only call this when already mutex locked */ static void pvrscr_set_pivot(pvrscr_t *this) { struct timeval tv; int64_t pts; double pts_calc; xine_monotonic_clock(&tv, NULL); pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; /* This next part introduces a one off inaccuracy * to the scr due to rounding tv to pts. */ this->cur_time.tv_sec = tv.tv_sec; this->cur_time.tv_usec = tv.tv_usec; this->cur_pts = pts; return; } static int pvrscr_set_fine_speed (scr_plugin_t *scr, int speed) { pvrscr_t *this = (pvrscr_t*) scr; pthread_mutex_lock (&this->lock); pvrscr_set_pivot( this ); this->xine_speed = speed; this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL * this->speed_tuning; pthread_mutex_unlock (&this->lock); return speed; } static void pvrscr_speed_tuning (pvrscr_t *this, double factor) { pthread_mutex_lock (&this->lock); pvrscr_set_pivot( this ); this->speed_tuning = factor; this->speed_factor = (double) this->xine_speed * 90000.0 / XINE_FINE_SPEED_NORMAL * this->speed_tuning; pthread_mutex_unlock (&this->lock); } static void pvrscr_adjust (scr_plugin_t *scr, int64_t vpts) { pvrscr_t *this = (pvrscr_t*) scr; struct timeval tv; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&tv, NULL); this->cur_time.tv_sec = tv.tv_sec; this->cur_time.tv_usec = tv.tv_usec; this->cur_pts = vpts; pthread_mutex_unlock (&this->lock); } static void pvrscr_start (scr_plugin_t *scr, int64_t start_vpts) { pvrscr_t *this = (pvrscr_t*) scr; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&this->cur_time, NULL); this->cur_pts = start_vpts; pthread_mutex_unlock (&this->lock); pvrscr_set_fine_speed (&this->scr, XINE_FINE_SPEED_NORMAL); } static int64_t pvrscr_get_current (scr_plugin_t *scr) { pvrscr_t *this = (pvrscr_t*) scr; struct timeval tv; int64_t pts; double pts_calc; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&tv, NULL); pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; pthread_mutex_unlock (&this->lock); /*printf("returning pts %lld\n", pts);*/ return pts; } static void pvrscr_exit (scr_plugin_t *scr) { pvrscr_t *this = (pvrscr_t*) scr; pthread_mutex_destroy (&this->lock); free(this); } static pvrscr_t *XINE_MALLOC pvrscr_init (void) { pvrscr_t *this; this = calloc(1, sizeof(pvrscr_t)); this->scr.interface_version = 3; this->scr.get_priority = pvrscr_get_priority; this->scr.set_fine_speed = pvrscr_set_fine_speed; this->scr.adjust = pvrscr_adjust; this->scr.start = pvrscr_start; this->scr.get_current = pvrscr_get_current; this->scr.exit = pvrscr_exit; pthread_mutex_init (&this->lock, NULL); pvrscr_speed_tuning(this, 1.0 ); pvrscr_set_fine_speed (&this->scr, XINE_SPEED_PAUSE); #ifdef SCRLOG printf("input_v4l: scr init complete\n"); #endif return this; } /*** END COPY AND PASTE from PVR**************************/ /*** The following is copy and past from net_buf_ctrl ****/ static void report_progress (xine_stream_t *stream, int p) { xine_event_t event; xine_progress_data_t prg; if (p == SCR_PAUSED) { prg.description = _("Buffer underrun..."); p = 0; } else if (p == SCR_FW) { prg.description = _("Buffer overrun..."); p = 100; } else prg.description = _("Adjusting..."); prg.percent = (p>100)?100:p; event.type = XINE_EVENT_PROGRESS; event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (stream, &event); } /**** END COPY AND PASTE from net_buf_ctrl ***************/ static int search_by_tuner(v4l_input_plugin_t *this, char *input_source); static int search_by_channel(v4l_input_plugin_t *this, char *input_source); static void v4l_event_handler(v4l_input_plugin_t *this); /** * Allocate an audio frame. */ inline static buf_element_t *alloc_aud_frame (v4l_input_plugin_t *this) { buf_element_t *frame; lprintf("alloc_aud_frame. trying to get lock...\n"); pthread_mutex_lock (&this->aud_frames_lock) ; lprintf("got the lock\n"); while (!this->aud_frames) { lprintf("no audio frame available...\n"); pthread_cond_wait (&this->aud_frame_freed, &this->aud_frames_lock); } frame = this->aud_frames; this->aud_frames = this->aud_frames->next; pthread_mutex_unlock (&this->aud_frames_lock); lprintf("alloc_aud_frame done\n"); return frame; } /** * Stores an audio frame. */ static void store_aud_frame (buf_element_t *frame) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) frame->source; lprintf("store_aud_frame\n"); pthread_mutex_lock (&this->aud_frames_lock) ; frame->next = this->aud_frames; this->aud_frames = frame; pthread_cond_signal (&this->aud_frame_freed); pthread_mutex_unlock (&this->aud_frames_lock); } /** * Allocate a video frame. */ inline static buf_element_t *alloc_vid_frame (v4l_input_plugin_t *this) { buf_element_t *frame; lprintf("alloc_vid_frame. trying to get lock...\n"); pthread_mutex_lock (&this->vid_frames_lock) ; lprintf("got the lock\n"); while (!this->vid_frames) { lprintf("no video frame available...\n"); pthread_cond_wait (&this->vid_frame_freed, &this->vid_frames_lock); } frame = this->vid_frames; this->vid_frames = this->vid_frames->next; pthread_mutex_unlock (&this->vid_frames_lock); lprintf("alloc_vid_frame done\n"); return frame; } /** * Stores a video frame. */ static void store_vid_frame (buf_element_t *frame) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) frame->source; lprintf("store_vid_frame\n"); pthread_mutex_lock (&this->vid_frames_lock) ; frame->next = this->vid_frames; this->vid_frames = frame; pthread_cond_signal (&this->vid_frame_freed); pthread_mutex_unlock (&this->vid_frames_lock); } static int extract_mrl(v4l_input_plugin_t *this, const char *mrl) { char *tuner_name = NULL; int frequency = 0; const char *locator = NULL; const char *begin = NULL; if (mrl == NULL) { lprintf("Someone passed an empty mrl\n"); return 0; } for (locator = mrl; *locator != '\0' && *locator != '/' ; locator++); /* Get tuner name */ if (*locator == '/') { begin = ++locator; for (; *locator != '\0' && *locator != '/' ; locator++); tuner_name = (char *) strndup(begin, locator - begin); /* Get frequency, if available */ sscanf(locator, "/%d", &frequency); /* cannot use xprintf to log in this routine */ lprintf("input_v4l: Tuner name: %s frequency %d\n", tuner_name, frequency ); } this->frequency = frequency; this->tuner_name = tuner_name; return 1; } static int set_frequency(v4l_input_plugin_t *this, unsigned long frequency) { int ret = 0; int fd; if (this->video_fd > 0) fd = this->video_fd; else fd = this->radio_fd; if (frequency != 0) { /* FIXME: Don't assume tuner 0 ? */ this->tuner = 0; ret = ioctl(fd, VIDIOCSTUNER, &this->tuner); lprintf("(%d) Response on set tuner to %d\n", ret, this->tuner); this->video_tuner.tuner = this->tuner; if (this->video_tuner.flags & VIDEO_TUNER_LOW) { this->calc_frequency = frequency * 16; } else { this->calc_frequency = (frequency * 16) / 1000; } ret = ioctl(fd, VIDIOCSFREQ, &this->calc_frequency); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: set frequency (%ld) returned: %d\n", frequency, ret); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: No frequency given. Expected syntax: v4l:/tuner/frequency\n" "input_v4l: Using currently tuned settings\n"); } this->frequency = frequency; if (ret < 0) return ret; else return 1; } static int set_input_source(v4l_input_plugin_t *this, char *input_source) { int ret = 0; if ((ret = search_by_channel(this, input_source)) != 1) { ret = search_by_tuner(this, input_source); } return ret; } static int search_by_tuner(v4l_input_plugin_t *this, char *input_source) { int ret = 0; int fd = 0; int cur_tuner = 0; if (this->video_fd > 0) fd = this->video_fd; else fd = this->radio_fd; this->video_tuner.tuner = cur_tuner; ioctl(fd, VIDIOCGCAP, &this->video_cap); lprintf("This device has %d channel(s)\n", this->video_cap.channels); for (ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner); ret == 0 && this->video_cap.channels > cur_tuner && strstr(this->video_tuner.name, input_source) == NULL; cur_tuner++) { this->video_tuner.tuner = cur_tuner; lprintf("(%d) V4L device currently set to: \n", ret); lprintf("Tuner: %d\n", this->video_tuner.tuner); lprintf("Name: %s\n", this->video_tuner.name); if (this->video_tuner.flags & VIDEO_TUNER_LOW) { lprintf("Range: %ld - %ld\n", this->video_tuner.rangelow / 16, this->video_tuner.rangehigh * 16); } else { lprintf("Range: %ld - %ld\n", this->video_tuner.rangelow * 1000 / 16, this->video_tuner.rangehigh * 1000 / 16); } } lprintf("(%d) V4L device final: \n", ret); lprintf("Tuner: %d\n", this->video_tuner.tuner); lprintf("Name: %s\n", this->video_tuner.name); if (this->video_tuner.flags & VIDEO_TUNER_LOW) { lprintf("Range: %ld - %ld\n", this->video_tuner.rangelow / 16, this->video_tuner.rangehigh * 16); } else { lprintf("Range: %ld - %ld\n", this->video_tuner.rangelow * 1000 / 16, this->video_tuner.rangehigh * 1000 / 16); } if (strstr(this->video_tuner.name, input_source) == NULL) return -1; return 1; } static int search_by_channel(v4l_input_plugin_t *this, char *input_source) { int ret = 0; int fd = 0; cfg_entry_t *tv_standard_entry; lprintf("input_source: %s\n", input_source); this->input = 0; if (this->video_fd > 0) fd = this->video_fd; else fd = this->radio_fd; /* Tune into channel */ if (strlen(input_source) > 0) { for( this->video_channel.channel = 0; ioctl(fd, VIDIOCGCHAN, &this->video_channel) == 0; this->video_channel.channel++ ) { lprintf("V4L device currently set to:\n"); lprintf("Channel: %d\n", this->video_channel.channel); lprintf("Name: %s\n", this->video_channel.name); lprintf("Tuners: %d\n", this->video_channel.tuners); lprintf("Flags: %d\n", this->video_channel.flags); lprintf("Type: %d\n", this->video_channel.type); lprintf("Norm: %d\n", this->video_channel.norm); if (strstr(this->video_channel.name, input_source) != NULL) { this->input = this->video_channel.channel; break; } } if (strstr(this->video_channel.name, input_source) == NULL) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("Tuner name not found\n")); return -1; } tv_standard_entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "media.video4linux.tv_standard"); this->tuner_name = input_source; if (tv_standard_entry->num_value != 0) { this->video_channel.norm = tv_standard_values[ tv_standard_entry->num_value ]; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: TV Standard configured as STD %s (%d)\n", tv_standard_names[ tv_standard_entry->num_value ], this->video_channel.norm ); ret = ioctl(fd, VIDIOCSCHAN, &this->video_channel); } else ret = ioctl(fd, VIDIOCSCHAN, &this->input); lprintf("(%d) Set channel to %d\n", ret, this->input); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Not setting video source. No source given\n"); } ret = ioctl(fd, VIDIOCGTUNER, &this->video_tuner); lprintf("(%d) Flags %d\n", ret, this->video_tuner.flags); lprintf("VIDEO_TUNER_PAL %s set\n", this->video_tuner.flags & VIDEO_TUNER_PAL ? "" : "not"); lprintf("VIDEO_TUNER_NTSC %s set\n", this->video_tuner.flags & VIDEO_TUNER_NTSC ? "" : "not"); lprintf("VIDEO_TUNER_SECAM %s set\n", this->video_tuner.flags & VIDEO_TUNER_SECAM ? "" : "not"); lprintf("VIDEO_TUNER_LOW %s set\n", this->video_tuner.flags & VIDEO_TUNER_LOW ? "" : "not"); lprintf("VIDEO_TUNER_NORM %s set\n", this->video_tuner.flags & VIDEO_TUNER_NORM ? "" : "not"); lprintf("VIDEO_TUNER_STEREO_ON %s set\n", this->video_tuner.flags & VIDEO_TUNER_STEREO_ON ? "" : "not"); lprintf("VIDEO_TUNER_RDS_ON %s set\n", this->video_tuner.flags & VIDEO_TUNER_RDS_ON ? "" : "not"); lprintf("VIDEO_TUNER_MBS_ON %s set\n", this->video_tuner.flags & VIDEO_TUNER_MBS_ON ? "" : "not"); switch (this->video_tuner.mode) { case VIDEO_MODE_PAL: lprintf("The tuner is in PAL mode\n"); break; case VIDEO_MODE_NTSC: lprintf("The tuner is in NTSC mode\n"); break; case VIDEO_MODE_SECAM: lprintf("The tuner is in SECAM mode\n"); break; case VIDEO_MODE_AUTO: lprintf("The tuner is in AUTO mode\n"); break; } return 1; } static void allocate_frames(v4l_input_plugin_t *this, unsigned dovideo) { const size_t framescount = dovideo ? 2*NUM_FRAMES : NUM_FRAMES; /* Allocate a single memory area for both audio and video frames */ buf_element_t *frames = this->frames_base = calloc(framescount, sizeof(buf_element_t)); extra_info_t *infos = calloc(framescount, sizeof(extra_info_t)); int i; uint8_t *audio_content = this->audio_content_base = calloc(NUM_FRAMES, this->periodsize); /* Set up audio frames */ for (i = 0; i < NUM_FRAMES; i++) { /* Audio frame */ frames[i].content = audio_content; frames[i].type = BUF_AUDIO_LPCM_LE; frames[i].source = this; frames[i].free_buffer = store_aud_frame; frames[i].extra_info = &infos[i]; audio_content += this->periodsize; store_aud_frame(&frames[i]); } if ( dovideo ) { uint8_t *video_content = this->video_content_base = calloc(NUM_FRAMES, this->frame_size); /* Set up video frames */ for (i = NUM_FRAMES; i < 2*NUM_FRAMES; i++) { /* Video frame */ frames[i].content = video_content; frames[i].type = this->frame_format; frames[i].source = this; frames[i].free_buffer = store_vid_frame; frames[i].extra_info = &infos[i]; video_content += this->frame_size; store_vid_frame(&frames[i]); } } } static void unmute_audio(v4l_input_plugin_t *this) { int fd; lprintf("unmute_audio\n"); if (this->video_fd > 0) fd = this->video_fd; else fd = this->radio_fd; ioctl(fd, VIDIOCGAUDIO, &this->audio); memcpy(&this->audio_saved, &this->audio, sizeof(this->audio)); this->audio.flags &= ~VIDEO_AUDIO_MUTE; this->audio.volume = 0xD000; ioctl(fd, VIDIOCSAUDIO, &this->audio); } static int open_radio_capture_device(v4l_input_plugin_t *this) { int tuner_found = 0; cfg_entry_t *entry; lprintf("open_radio_capture_device\n"); entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "media.video4linux.radio_device"); if((this->radio_fd = xine_open_cloexec(entry->str_value, O_RDWR)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: error opening v4l device (%s): %s\n", entry->str_value, strerror(errno)); return 0; } lprintf("Device opened, radio %d\n", this->radio_fd); if (set_input_source(this, this->tuner_name) > 0) tuner_found = 1; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); /* Pre-allocate some frames for audio so it doesn't have to be done during * capture */ allocate_frames(this, 0); this->audio_only = 1; /* Unmute audio off video capture device */ unmute_audio(this); set_frequency(this, this->frequency); if (tuner_found) return 1; else return 2; } /** * Open the video capture device. * * This opens the video capture device and if given, selects a tuner from * which the signal should be grabbed. * @return 1 on success, 0 on failure. */ static int open_video_capture_device(v4l_input_plugin_t *this) { int found = 0; int tuner_found = 0; int ret; unsigned int j; cfg_entry_t *entry; lprintf("open_video_capture_device\n"); entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "media.video4linux.video_device"); /* Try to open the video device */ if((this->video_fd = xine_open_cloexec(entry->str_value, O_RDWR)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: error opening v4l device (%s): %s\n", entry->str_value, strerror(errno)); return 0; } lprintf("Device opened, tv %d\n", this->video_fd); /* figure out the resolution */ for (j = 0; j < NUM_RESOLUTIONS; j++) { if (resolutions[j].width <= this->video_cap.maxwidth && resolutions[j].height <= this->video_cap.maxheight && resolutions[j].width <= MAX_RES) { found = 1; break; } } if (found == 0 || resolutions[j].width < this->video_cap.minwidth || resolutions[j].height < this->video_cap.minheight) { /* Looks like the device does not support one of the preset resolutions */ lprintf("Grab device does not support any preset resolutions"); return 0; } this->resolution = &resolutions[j]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); /* Pre-allocate some frames for audio and video so it doesn't have to be * done during capture */ allocate_frames(this, 1); /* Unmute audio off video capture device */ unmute_audio(this); if (strlen(this->tuner_name) > 0) { /* Tune into source and given frequency */ if (set_input_source(this, this->tuner_name) <= 0) return 0; else tuner_found = 1; } set_frequency(this, this->frequency); /* Test for mmap video access */ ret = ioctl(this->video_fd,VIDIOCGMBUF, &this->gb_buffers); if (ret < 0) { /* Device driver does not support mmap */ /* try to use read based access */ struct video_picture pict; int val; ioctl(this->video_fd, VIDIOCGPICT, &pict); /* try to choose a suitable video format */ pict.palette = VIDEO_PALETTE_YUV420P; ret = ioctl(this->video_fd, VIDIOCSPICT, &pict); if (ret < 0) { pict.palette = VIDEO_PALETTE_YUV422; ret = ioctl(this->video_fd, VIDIOCSPICT, &pict); if (ret < 0) { close (this->video_fd); this->video_fd = -1; lprintf("Grab: no colour space format found\n"); return 0; } else lprintf("Grab: format YUV 4:2:2\n"); } else lprintf("Grab: format YUV 4:2:0\n"); this->frame_format = pict.palette; val = 1; ioctl(this->video_fd, VIDIOCCAPTURE, &val); this->use_mmap = 0; } else { /* Good, device driver support mmap. Mmap the memory */ lprintf("using mmap, size %d\n", this->gb_buffers.size); this->video_buf = mmap(0, this->gb_buffers.size, PROT_READ|PROT_WRITE, MAP_SHARED, this->video_fd,0); if ((unsigned char*)-1 == this->video_buf) { /* mmap failed. */; perror("mmap"); close (this->video_fd); return 0; } this->gb_frame = 0; /* start to grab the first frame */ this->gb_buf.frame = (this->gb_frame + 1) % this->gb_buffers.frames; this->gb_buf.height = resolutions[j].height; this->gb_buf.width = resolutions[j].width; this->gb_buf.format = VIDEO_PALETTE_YUV420P; ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); if (ret < 0 && errno != EAGAIN) { /* try YUV422 */ this->gb_buf.format = VIDEO_PALETTE_YUV422; ret = ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf); } else lprintf("(%d) YUV420 should work\n", ret); if (ret < 0) { if (errno != EAGAIN) { lprintf("grab device does not support suitable format\n"); } else { lprintf("grab device does not receive any video signal\n"); } close (this->video_fd); return 0; } this->frame_format = this->gb_buf.format; this->use_mmap = 1; } switch(this->frame_format) { case VIDEO_PALETTE_YUV420P: this->frame_format = BUF_VIDEO_I420; this->frame_size = (resolutions[j].width * resolutions[j].height * 3) / 2; break; case VIDEO_PALETTE_YUV422: this->frame_format = BUF_VIDEO_YUY2; this->frame_size = resolutions[j].width * resolutions[j].height * 2; break; } /* Strip the vbi / sync signal from the image by zooming in */ this->old_zoomx = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_X); this->old_zoomy = xine_get_param(this->stream, XINE_PARAM_VO_ZOOM_Y); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, 103); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, 103); /* Pre-allocate some frames for audio and video so it doesn't have to be * done during capture */ allocate_frames(this, 1); /* If we made it here, everything went ok */ this->audio_only = 0; if (tuner_found) return 1; else /* Not a real error, appart that the tuner name is unknown to us */ return 2; } /** * Open audio capture device. * * This function opens an alsa capture device. This will be used to capture * audio data from. */ static int open_audio_capture_device(v4l_input_plugin_t *this) { #ifdef HAVE_ALSA int mode = 0; snd_pcm_uframes_t buf_size = (this->periodsize * this->periods) >> 2; lprintf("open_audio_capture_device\n"); /* Allocate the snd_pcm_hw_params_t structure on the stack. */ snd_pcm_hw_params_alloca(&this->pcm_hwparams); /* If we are not capturing video, open the sound device in blocking mode, * otherwise xine gets too many NULL bufs and doesn't seem to handle them * correctly. If we are capturing video, open the sound device in non- * blocking mode, otherwise we will loose video frames while waiting */ if(!this->audio_only) mode = SND_PCM_NONBLOCK; /* Open the PCM device. */ if(snd_pcm_open(&this->pcm_handle, this->pcm_name, this->pcm_stream, mode) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error opening PCM device: %s\n", this->pcm_name); this->audio_capture = 0; } /* Get parameters */ if (this->audio_capture && (snd_pcm_hw_params_any(this->pcm_handle, this->pcm_hwparams) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Broken configuration for PCM device: No configurations available\n"); this->audio_capture = 0; } /* Set access type */ if (this->audio_capture && (snd_pcm_hw_params_set_access(this->pcm_handle, this->pcm_hwparams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting SND_PCM_ACCESS_RW_INTERLEAVED\n"); this->audio_capture = 0; } /* Set sample format */ if (this->audio_capture && (snd_pcm_hw_params_set_format(this->pcm_handle, this->pcm_hwparams, SND_PCM_FORMAT_S16_LE) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting SND_PCM_FORMAT_S16_LE\n"); this->audio_capture = 0; } /* Set sample rate */ this->exact_rate = this->rate; if (this->audio_capture && (snd_pcm_hw_params_set_rate_near(this->pcm_handle, this->pcm_hwparams, &this->exact_rate, &this->dir) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting samplerate\n"); this->audio_capture = 0; } if (this->audio_capture && this->dir != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Samplerate %d Hz is not supported by your hardware\n", this->rate); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Using %d instead\n", this->exact_rate); } /* Set number of channels */ if (this->audio_capture && (snd_pcm_hw_params_set_channels(this->pcm_handle, this->pcm_hwparams, 2) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting PCM channels\n"); this->audio_capture = 0; } if (this->audio_capture && (snd_pcm_hw_params_set_periods(this->pcm_handle, this->pcm_hwparams, this->periods, 0) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting PCM periods\n"); this->audio_capture = 0; } /* Set buffersize */ if (this->audio_capture && (snd_pcm_hw_params_set_buffer_size_near(this->pcm_handle, this->pcm_hwparams, &buf_size) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error setting PCM buffer size to %d\n", (int)buf_size ); this->audio_capture = 0; } /* Apply HW parameter settings */ if (this->audio_capture && (snd_pcm_hw_params(this->pcm_handle, this->pcm_hwparams) < 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error Setting PCM HW params\n"); this->audio_capture = 0; } if (this->audio_capture) { lprintf("Allocating memory for PCM capture :%d\n", this->periodsize); this->pcm_data = (unsigned char*) malloc(this->periodsize); } else this->pcm_data = NULL; lprintf("Audio device succesfully configured\n"); #endif return 0; } /** * Adjust realtime speed * * If xine is playing at normal speed, tries to adjust xines playing speed to * avoid buffer overrun and buffer underrun */ static int v4l_adjust_realtime_speed(v4l_input_plugin_t *this, fifo_buffer_t *fifo, int speed) { int num_used, num_free; int scr_tuning = this->scr_tuning; if (fifo == NULL) return 0; num_used = fifo->size(fifo); num_free = NUM_FRAMES - num_used; if (!this->audio_only && num_used == 0 && scr_tuning != SCR_PAUSED) { /* Buffer is empty, and we did not pause playback */ report_progress(this->stream, SCR_PAUSED); xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_v4l: Buffer empty, pausing playback (used: %d, num_free: %d)\n", num_used, num_free); _x_set_speed(this->stream, XINE_SPEED_PAUSE); this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 0); this->scr_tuning = SCR_PAUSED; /* pvrscr_speed_tuning(this->scr, 0.0); */ } else if (num_free <= 1 && scr_tuning != SCR_SKIP) { this->scr_tuning = SCR_SKIP; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_v4l: Buffer full, skipping (used: %d, free: %d)\n", num_used, num_free); return 0; } else if (scr_tuning == SCR_PAUSED) { if (2 * num_used > num_free) { /* Playback was paused, but we have normal buffer usage again */ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_v4l: Resuming from paused (used: %d, free: %d)\n", num_used, num_free); this->scr_tuning = 0; pvrscr_speed_tuning(this->scr, 1.0); _x_set_speed(this->stream, XINE_SPEED_NORMAL); this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1); } } else if (scr_tuning == SCR_SKIP) { if (num_used < 2 * num_free) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_v4l: Resuming from skipping (used: %d, free %d)\n", num_used, num_free); this->scr_tuning = 0; } else { return 0; } } else if (speed == XINE_SPEED_NORMAL) { if (num_used > 2 * num_free) /* buffer used > 2/3. Increase playback speed to avoid buffer * overrun */ scr_tuning = +1; else if (num_free > 2 * num_used) /* Buffer used < 1/3. Decrease playback speed to avoid buffer * underrun */ scr_tuning = -1; else if ((scr_tuning > 0 && num_free > num_used) || (scr_tuning < 0 && num_used > num_free)) /* Buffer usage is ok again. Set playback speed to normal */ scr_tuning = 0; /* Check if speed adjustment should be changed */ if (scr_tuning != this->scr_tuning) { this->scr_tuning = scr_tuning; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_v4l: scr tuning = %d (used: %d, free: %d)\n", scr_tuning, num_used, num_free); pvrscr_speed_tuning(this->scr, 1.0 + (0.01 * scr_tuning)); } } else if (this->scr_tuning) { /* Currently speed adjustment is on. But xine is not playing at normal * speed, so there is no reason why we should try to adjust our playback * speed */ this->scr_tuning = 0; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_v4l: scr tuning resetting (used: %d, free: %d\n", num_used, num_free); pvrscr_speed_tuning(this->scr, 1.0); } return 1; } /** * Plugin read. * This function is not supported by the plugin. */ static off_t v4l_plugin_read (input_plugin_t *this_gen, void *buf, off_t len) { lprintf("Read not supported\n"); (void)this_gen; (void)buf; (void)len; return 0; } /** * Get time. * Gets a pts time value. */ inline static int64_t get_time(void) { struct timeval tv; xine_monotonic_clock(&tv,NULL); return (int64_t) tv.tv_sec * 90000 + (int64_t) tv.tv_usec * 9 / 100; } /** * Plugin read block * Reads one data block. This is either an audio frame or an video frame */ static buf_element_t *v4l_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; buf_element_t *buf = NULL; uint8_t *ptr; static char video = 0; int speed = _x_get_speed(this->stream); #ifndef LOG (void)todo; #endif v4l_event_handler(this); #ifdef HAVE_ALSA if (!this->audio_header_sent) { lprintf("sending audio header\n"); buf = alloc_aud_frame (this); buf->size = 0; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->exact_rate; buf->decoder_info[2] = this->bits; buf->decoder_info[3] = 2; this->audio_header_sent = 1; return buf; } #endif if (!this->audio_only && !this->video_header_sent) { xine_bmiheader bih; lprintf("sending video header"); memset(&bih, 0, sizeof(bih)); bih.biSize = sizeof(xine_bmiheader); bih.biWidth = this->resolution->width; bih.biHeight = this->resolution->height; buf = alloc_vid_frame (this); buf->size = sizeof(xine_bmiheader); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; memcpy(buf->content, &bih, sizeof(xine_bmiheader)); this->video_header_sent = 1; return buf; } if (!this->audio_only) { if (!v4l_adjust_realtime_speed(this, fifo, speed)) { return NULL; } } if (!this->audio_only) video = !video; else video = 0; lprintf("%lld bytes...\n", todo); if (this->start_time == 0) /* Create a start pts value */ this->start_time = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ if (video) { /* Capture video */ buf = alloc_vid_frame (this); buf->decoder_flags = BUF_FLAG_FRAME_START|BUF_FLAG_FRAME_END; this->gb_buf.frame = this->gb_frame; lprintf("VIDIOCMCAPTURE\n"); while (ioctl(this->video_fd, VIDIOCMCAPTURE, &this->gb_buf) < 0) { lprintf("Upper while loop\n"); if (errno == EAGAIN) { lprintf("Cannot sync\n"); continue; } else { perror("VIDIOCMCAPTURE"); buf->free_buffer(buf); return NULL; } } this->gb_frame = (this->gb_frame + 1) % this->gb_buffers.frames; while (ioctl(this->video_fd, VIDIOCSYNC, &this->gb_frame) < 0 && (errno == EAGAIN || errno == EINTR)) { lprintf("Waiting for videosync\n"); } /* printf ("grabbing frame #%d\n", frame_num); */ ptr = this->video_buf + this->gb_buffers.offsets[this->gb_frame]; buf->pts = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ xine_fast_memcpy (buf->content, ptr, this->frame_size); } #ifdef HAVE_ALSA else if (this->audio_capture) { /* Record audio */ int pcmreturn; if ((pcmreturn = snd_pcm_readi(this->pcm_handle, this->pcm_data, (this->periodsize)>> 2)) < 0) { switch (pcmreturn) { case -EAGAIN: /* No data available at the moment */ break; case -EBADFD: /* PCM device in wrong state */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: PCM is not in the right state\n"); break; case -EPIPE: /* Buffer overrun */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: PCM buffer Overrun (lost some samples)\n"); /* On buffer overrun we need to re prepare the capturing pcm device */ snd_pcm_prepare(this->pcm_handle); break; case -ESTRPIPE: /* Suspend event */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: PCM suspend event occured\n"); break; default: /* Unknown */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Unknown PCM error code: %d\n", pcmreturn); snd_pcm_prepare(this->pcm_handle); } } else { /* Succesfully read audio data */ if (this->pts_aud_start) { buf = alloc_aud_frame (this); buf->decoder_flags = 0; } /* We want the pts on the start of the sample. As the soundcard starts * sampling a new sample as soon as the read function returned with a * success we will save the current pts and assign the current pts to * that sample when we read it */ /* Assign start pts to sample */ if (buf) buf->pts = this->pts_aud_start; /* Save start pts */ this->pts_aud_start = get_time(); /* this->stream->xine->clock->get_current_time(this->stream->xine->clock); */ if (!buf) /* Skip first sample as we don't have a good pts for this one */ return NULL; lprintf("Audio: Data read: %d [%d, %d]. Pos: %d\n", pcmreturn, (int) (*this->pcm_data), (int) (*(this->pcm_data + this->periodsize - 3)), (int) this->curpos); /* Tell decoder the number of bytes we have read */ buf->size = pcmreturn<<2; this->curpos++; xine_fast_memcpy(buf->content, this->pcm_data, buf->size); } } #endif lprintf("read block done\n"); return buf; } /** * Plugin seek. * Not supported by the plugin. */ static off_t v4l_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; (void)this_gen; #ifndef LOG (void)offset; (void)origin; #endif lprintf("seek %lld bytes, origin %d\n", offset, origin); return this->curpos; } /** * Plugin get length. * This is a live stream, and as such does not have an known end. */ static off_t v4l_plugin_get_length (input_plugin_t *this_gen) { /* v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; off_t length; */ (void)this_gen; return -1; } /** * Plugin get capabilitiets. * This plugin does not support any special capabilities. */ static uint32_t v4l_plugin_get_capabilities (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; if (this->audio_only) return 0x10; else return 0; /* 0x10: Has audio only. */ } /** * Plugin get block size. * Unsupported by the plugin. */ static uint32_t v4l_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return 0; } /** * Plugin get current pos. * Unsupported by the plugin. */ static off_t v4l_plugin_get_current_pos (input_plugin_t *this_gen){ v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; /* printf ("current pos is %lld\n", this->curpos); */ return this->curpos; } /** * Event handler. * * Processes events from a frontend. This way frequencies can be changed * without closing the v4l plugin. */ static void v4l_event_handler (v4l_input_plugin_t *this) { xine_event_t *event; while ((event = xine_event_get (this->event_queue))) { xine_set_v4l2_data_t *v4l2_data = event->data; switch (event->type) { case XINE_EVENT_SET_V4L2: if( v4l2_data->input != this->input || v4l2_data->channel != this->channel || v4l2_data->frequency != this->frequency ) { this->input = v4l2_data->input; this->channel = v4l2_data->channel; this->frequency = v4l2_data->frequency; lprintf("Switching to input:%d chan:%d freq:%.2f\n", v4l2_data->input, v4l2_data->channel, (float)v4l2_data->frequency); set_frequency(this, this->frequency); _x_demux_flush_engine(this->stream); } break; /* default: lprintf("Got an event, type 0x%08x\n", event->type); */ } xine_event_free (event); } } /** * Dispose plugin. * * Closes the plugin, restore the V4L device in the initial state (volume) and * frees the allocated memory */ static void v4l_plugin_dispose (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; _x_freep(&this->mrl); if (this->scr) { this->stream->xine->clock->unregister_scr(this->stream->xine->clock, &this->scr->scr); this->scr->scr.exit(&this->scr->scr); } /* Close and free video device */ _x_freep(&this->tuner_name); /* Close video device only if device was opened */ if (this->video_fd > 0) { /* Restore v4l audio volume */ lprintf("Restoring v4l audio volume %d\n", ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved)); ioctl(this->video_fd, VIDIOCSAUDIO, &this->audio_saved); /* Unmap memory */ if (this->video_buf != NULL && munmap(this->video_buf, this->gb_buffers.size) != 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Could not unmap video memory: %s\n", strerror(errno)); } else lprintf("Succesfully unmapped video memory (size %d)\n", this->gb_buffers.size); lprintf("Closing video filehandler %d\n", this->video_fd); /* Now close the video device */ if (close(this->video_fd) != 0) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: Error while closing video file handler: %s\n", strerror(errno)); else lprintf("Video device succesfully closed\n"); /* Restore zoom setting */ xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_X, this->old_zoomx); xine_set_param(this->stream, XINE_PARAM_VO_ZOOM_Y, this->old_zoomy); } if (this->radio_fd > 0) { close(this->radio_fd); } #ifdef HAVE_ALSA /* Close audio device */ if (this->pcm_handle) { snd_pcm_drop(this->pcm_handle); snd_pcm_close(this->pcm_handle); } _x_freep(&this->pcm_data); _x_freep(&this->pcm_name); #endif if (this->event_queue) xine_event_dispose_queue (this->event_queue); /* All the frames, both video and audio, are allocated in a single memory area pointed by the frames_base pointer. The content of the frames is divided in two areas, one pointed by audio_content_base and the other by video_content_base. The extra_info structures are all allocated in the first frame data. */ _x_freep(&this->audio_content_base); _x_freep(&this->video_content_base); if (this->frames_base) _x_freep(&this->frames_base->extra_info); _x_freep(&this->frames_base); #ifdef LOG printf("\n"); #endif free (this); lprintf("plugin Bye bye! \n"); } /** * Get MRL. * * Get the current MRL used by the plugin. */ static const char* v4l_plugin_get_mrl (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; return this->mrl; } static int v4l_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { /* v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; */ (void)this_gen; (void)data; (void)data_type; return INPUT_OPTIONAL_UNSUPPORTED; } static int v4l_plugin_radio_open (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; if(open_radio_capture_device(this) != 1) return 0; open_audio_capture_device(this); #ifdef HAVE_ALSA this->start_time = 0; this->pts_aud_start = 0; this->curpos = 0; this->event_queue = xine_event_new_queue (this->stream); #endif return 1; } static int v4l_plugin_video_open (input_plugin_t *this_gen) { v4l_input_plugin_t *this = (v4l_input_plugin_t *) this_gen; int64_t time; if(!open_video_capture_device(this)) return 0; open_audio_capture_device(this); #ifdef HAVE_ALSA this->pts_aud_start = 0; #endif this->start_time = 0; this->curpos = 0; /* Register our own scr provider */ time = this->stream->xine->clock->get_current_time(this->stream->xine->clock); this->scr = pvrscr_init(); this->scr->scr.start(&this->scr->scr, time); this->stream->xine->clock->register_scr(this->stream->xine->clock, &this->scr->scr); this->scr_tuning = 0; /* enable resample method */ this->stream->xine->config->update_num(this->stream->xine->config, "audio.synchronization.av_sync_method", 1); this->event_queue = xine_event_new_queue (this->stream); return 1; } /** * Create a new instance. * * Creates a new instance of the plugin. Doesn't initialise the V4L device, * does initialise the structure. */ static input_plugin_t *v4l_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { /* v4l_input_class_t *cls = (v4l_input_class_t *) cls_gen; */ v4l_input_plugin_t *this; #ifdef HAVE_ALSA cfg_entry_t *entry; #endif /* Example mrl: v4l:/Television/62500 */ if(!data || strncasecmp(data, "v4l:/", 5)) { return NULL; } this = calloc(1, sizeof (v4l_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->mrl = strdup(data); if (!this->mrl) { free(this); return NULL; } this->video_buf = NULL; this->video_fd = -1; this->radio_fd = -1; this->event_queue = NULL; this->scr = NULL; #ifdef HAVE_ALSA this->pcm_data = NULL; this->pcm_hwparams = NULL; extract_mrl(this, this->mrl); /* Audio */ this->pcm_stream = SND_PCM_STREAM_CAPTURE; entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "media.video4linux.audio_device"); this->pcm_name = strdup (entry->str_value); this->audio_capture = 1; if (!this->pcm_name) { v4l_plugin_dispose(&this->input_plugin); return NULL; } #endif this->rate = 44100; this->periods = 2; this->periodsize = 2 * 8192; this->bits = 16; pthread_mutex_init (&this->aud_frames_lock, NULL); pthread_cond_init (&this->aud_frame_freed, NULL); pthread_mutex_init (&this->vid_frames_lock, NULL); pthread_cond_init (&this->vid_frame_freed, NULL); this->input_plugin.get_capabilities = v4l_plugin_get_capabilities; this->input_plugin.read = v4l_plugin_read; this->input_plugin.read_block = v4l_plugin_read_block; this->input_plugin.seek = v4l_plugin_seek; this->input_plugin.get_current_pos = v4l_plugin_get_current_pos; this->input_plugin.get_length = v4l_plugin_get_length; this->input_plugin.get_blocksize = v4l_plugin_get_blocksize; this->input_plugin.get_mrl = v4l_plugin_get_mrl; this->input_plugin.dispose = v4l_plugin_dispose; this->input_plugin.get_optional_data = v4l_plugin_get_optional_data; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } static input_plugin_t *v4l_class_get_video_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { v4l_input_plugin_t *this = NULL; int is_ok = 1; cfg_entry_t *entry; this = (v4l_input_plugin_t *) v4l_class_get_instance (cls_gen, stream, data); if (this) this->input_plugin.open = v4l_plugin_video_open; else return NULL; entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "media.video4linux.video_device"); /* Try to open the video device */ if((this->video_fd = xine_open_cloexec(entry->str_value, O_RDWR)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: error opening v4l device (%s): %s\n", entry->str_value, strerror(errno)); is_ok = 0; } else lprintf("Device opened, tv %d\n", this->video_fd); /* Get capabilities */ if (is_ok && ioctl(this->video_fd, VIDIOCGCAP, &this->video_cap) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: v4l card doesn't support some features needed by xine\n"); is_ok = 0;; } if (is_ok && !(this->video_cap.type & VID_TYPE_CAPTURE)) { /* Capture is not supported by the device. This is a must though! */ xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: v4l card doesn't support frame grabbing\n"); is_ok = 0; } if (is_ok && set_input_source(this, this->tuner_name) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: unable to locate the tuner name (%s) on your v4l card\n", this->tuner_name); is_ok = 0; } if (this->video_fd > 0) { close(this->video_fd); this->video_fd = -1; } if (!is_ok) { v4l_plugin_dispose((input_plugin_t *) this); return NULL; } return &this->input_plugin; } static input_plugin_t *v4l_class_get_radio_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { v4l_input_plugin_t *this = NULL; int is_ok = 1; cfg_entry_t *entry; if (strstr(data, "Radio") == NULL) return NULL; this = (v4l_input_plugin_t *) v4l_class_get_instance (cls_gen, stream, data); if (this) this->input_plugin.open = v4l_plugin_radio_open; else return NULL; entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "media.video4linux.radio_device"); if((this->radio_fd = xine_open_cloexec(entry->str_value, O_RDWR)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: error opening v4l device (%s): %s\n", entry->str_value, strerror(errno)); is_ok = 0; } else lprintf("Device opened, radio %d\n", this->radio_fd); if (is_ok && set_input_source(this, this->tuner_name) <= 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_v4l: unable to locate the tuner name (%s) on your v4l card\n", this->tuner_name); is_ok = 0; } if (this->radio_fd > 0) { close(this->radio_fd); this->radio_fd = -1; } if (!is_ok) { v4l_plugin_dispose((input_plugin_t *) this); return NULL; } return &this->input_plugin; } /* * v4l input plugin class stuff */ static void *init_video_class (xine_t *xine, const void *data) { static const input_class_t v4l_video_input_class = { .get_instance = v4l_class_get_video_instance, .identifier = "v4l", .description = N_("v4l tv input plugin"), .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; config_values_t *config = xine->config; config->register_filename (config, "media.video4linux.video_device", VIDEO_DEV, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("v4l video device"), _("The path to your Video4Linux video device."), 10, NULL, NULL); #ifdef HAVE_ALSA config->register_filename (config, "media.video4linux.audio_device", AUDIO_DEV, 0, _("v4l ALSA audio input device"), _("The name of the audio device which corresponds " "to your Video4Linux video device."), 10, NULL, NULL); #endif config->register_enum (config, "media.video4linux.tv_standard", 0 /* auto */, (char **)tv_standard_names, _("v4l TV standard"), _("Selects the TV standard of the input signals. " "Either: AUTO, PAL, NTSC or SECAM. "), 20, NULL, NULL); (void)data; return (void *)&v4l_video_input_class; } static void *init_radio_class (xine_t *xine, const void *data) { static const input_class_t v4l_radio_input_class = { .get_instance = v4l_class_get_radio_instance, .identifier = "v4l", .description = N_("v4l radio input plugin"), .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; config_values_t *config = xine->config; config->register_filename (config, "media.video4linux.radio_device", RADIO_DEV, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("v4l radio device"), _("The path to your Video4Linux radio device."), 10, NULL, NULL); (void)data; return (void *)&v4l_radio_input_class; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "v4l_radio", XINE_VERSION_CODE, NULL, init_radio_class }, { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "v4l_tv", XINE_VERSION_CODE, NULL, init_video_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; /* * vim:sw=3:sts=3: */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/mms.c������������������������������������������������������������������������0000644�0001750�0001750�00000077337�14647725152�013573� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * MMS over TCP protocol * based on work from major mms * utility functions to handle communication with an mms server * * TODO: * error messages * enable seeking ! */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <string.h> #include <sys/types.h> #include <stdlib.h> #include <time.h> #if defined(HAVE_ICONV) && defined(HAVE_NL_LANGINFO) #define USE_ICONV #include <iconv.h> #include <locale.h> #include <langinfo.h> #else # ifndef ICONV_CONST # define ICONV_CONST const # endif #endif /********** logging **********/ #define LOG_MODULE "mms" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include "bswap.h" #include "http_helper.h" #include "mms.h" #include "../demuxers/asfheader.h" /* * mms specific types */ #define MMST_PORT 1755 #define BUF_SIZE 102400 #define CMD_HEADER_LEN 40 #define CMD_PREFIX_LEN 8 #define CMD_BODY_LEN 1024 #define ASF_HEADER_LEN 8192 #define MMS_PACKET_ERR 0 #define MMS_PACKET_COMMAND 1 #define MMS_PACKET_ASF_HEADER 2 #define MMS_PACKET_ASF_PACKET 3 #define ASF_HEADER_PACKET_ID_TYPE 2 #define ASF_MEDIA_PACKET_ID_TYPE 4 typedef struct mms_buffer_s mms_buffer_t; struct mms_buffer_s { uint8_t *buffer; int pos; }; typedef struct mms_packet_header_s mms_packet_header_t; struct mms_packet_header_s { uint32_t packet_len; uint8_t flags; uint8_t packet_id_type; uint32_t packet_seq; }; struct mms_s { xine_stream_t *stream; int s; /* url parsing */ xine_url_t url; /* command to send */ char scmd[CMD_HEADER_LEN + CMD_BODY_LEN]; char *scmd_body; /* pointer to &scmd[CMD_HEADER_LEN] */ int scmd_len; /* num bytes written in header */ /* receive buffer */ uint8_t buf[BUF_SIZE]; int buf_size; int buf_read; asf_header_t *asf_header; uint8_t asf_header_buffer[ASF_HEADER_LEN]; uint32_t asf_header_len; uint32_t asf_header_read; int seq_num; char guid[37]; int bandwidth; off_t current_pos; int eos; uint8_t live_flag; uint8_t playing; double start_time; }; #define D2Q(d) ({\ union { double db; long long qw; } _tmp;\ _tmp.db = d;\ _tmp.qw;\ })\ static void mms_buffer_init (mms_buffer_t *mms_buffer, char *buffer) { mms_buffer->buffer = (uint8_t*)buffer; mms_buffer->pos = 0; } static void mms_buffer_put_8 (mms_buffer_t *mms_buffer, uint8_t value) { mms_buffer->buffer[mms_buffer->pos] = value & 0xff; mms_buffer->pos += 1; } #if 0 static void mms_buffer_put_16 (mms_buffer_t *mms_buffer, uint16_t value) { mms_buffer->buffer[mms_buffer->pos] = value & 0xff; mms_buffer->buffer[mms_buffer->pos + 1] = (value >> 8) & 0xff; mms_buffer->pos += 2; } #endif static void mms_buffer_put_32 (mms_buffer_t *mms_buffer, uint32_t value) { mms_buffer->buffer[mms_buffer->pos] = value & 0xff; mms_buffer->buffer[mms_buffer->pos + 1] = (value >> 8) & 0xff; mms_buffer->buffer[mms_buffer->pos + 2] = (value >> 16) & 0xff; mms_buffer->buffer[mms_buffer->pos + 3] = (value >> 24) & 0xff; mms_buffer->pos += 4; } static void mms_buffer_put_64 (mms_buffer_t *mms_buffer, uint64_t value) { mms_buffer->buffer[mms_buffer->pos] = value & 0xff; mms_buffer->buffer[mms_buffer->pos + 1] = (value >> 8) & 0xff; mms_buffer->buffer[mms_buffer->pos + 2] = (value >> 16) & 0xff; mms_buffer->buffer[mms_buffer->pos + 3] = (value >> 24) & 0xff; mms_buffer->buffer[mms_buffer->pos + 4] = (value >> 32) & 0xff; mms_buffer->buffer[mms_buffer->pos + 5] = (value >> 40) & 0xff; mms_buffer->buffer[mms_buffer->pos + 6] = (value >> 48) & 0xff; mms_buffer->buffer[mms_buffer->pos + 7] = (value >> 56) & 0xff; mms_buffer->pos += 8; } #ifdef LOG static void print_command (char *data, int len) { int i; int dir = _X_LE_32 (data + 36) >> 16; int comm = _X_LE_32 (data + 36) & 0xFFFF; printf ("----------------------------------------------\n"); if (dir == 3) { printf ("send command 0x%02x, %d bytes\n", comm, len); } else { printf ("receive command 0x%02x, %d bytes\n", comm, len); } printf (" start sequence %08x\n", _X_LE_32 (data + 0)); printf (" command id %08x\n", _X_LE_32 (data + 4)); printf (" length %8x \n", _X_LE_32 (data + 8)); printf (" protocol %08x\n", _X_LE_32 (data + 12)); printf (" len8 %8x \n", _X_LE_32 (data + 16)); printf (" sequence # %08x\n", _X_LE_32 (data + 20)); printf (" len8 (II) %8x \n", _X_LE_32 (data + 32)); printf (" dir | comm %08x\n", _X_LE_32 (data + 36)); if (len >= 4) printf (" prefix1 %08x\n", _X_LE_32 (data + 40)); if (len >= 8) printf (" prefix2 %08x\n", _X_LE_32 (data + 44)); for (i = (CMD_HEADER_LEN + CMD_PREFIX_LEN); i < (CMD_HEADER_LEN + CMD_PREFIX_LEN + len); i += 1) { unsigned char c = data[i]; if ((c >= 32) && (c < 128)) printf ("%c", c); else printf (" %02x ", c); } if (len > CMD_HEADER_LEN) printf ("\n"); printf ("----------------------------------------------\n"); } #else # define print_command(data, len) #endif static int send_command (mms_t *this, int command, uint32_t prefix1, uint32_t prefix2, int length) { int len8; off_t n; mms_buffer_t command_buffer; len8 = (length + 7) / 8; this->scmd_len = 0; mms_buffer_init(&command_buffer, this->scmd); mms_buffer_put_32 (&command_buffer, 0x00000001); /* start sequence */ mms_buffer_put_32 (&command_buffer, 0xB00BFACE); /* #-)) */ mms_buffer_put_32 (&command_buffer, len8 * 8 + 32); mms_buffer_put_32 (&command_buffer, 0x20534d4d); /* protocol type "MMS " */ mms_buffer_put_32 (&command_buffer, len8 + 4); mms_buffer_put_32 (&command_buffer, this->seq_num); this->seq_num++; mms_buffer_put_32 (&command_buffer, 0x0); /* timestamp */ mms_buffer_put_32 (&command_buffer, 0x0); mms_buffer_put_32 (&command_buffer, len8 + 2); mms_buffer_put_32 (&command_buffer, 0x00030000 | command); /* dir | command */ /* end of the 40 byte command header */ mms_buffer_put_32 (&command_buffer, prefix1); mms_buffer_put_32 (&command_buffer, prefix2); if (length & 7) memset(this->scmd + length + CMD_HEADER_LEN + CMD_PREFIX_LEN, 0, 8 - (length & 7)); n = _x_io_tcp_write (this->stream, this->s, this->scmd, len8 * 8 + CMD_HEADER_LEN + CMD_PREFIX_LEN); if (n != (len8 * 8 + CMD_HEADER_LEN + CMD_PREFIX_LEN)) { return 0; } print_command (this->scmd, length); return 1; } #ifdef USE_ICONV static iconv_t string_utf16_open() { return iconv_open("UTF-16LE", "UTF-8"); } static void string_utf16_close(iconv_t url_conv) { if (url_conv != (iconv_t)-1) { iconv_close(url_conv); } } static void string_utf16(iconv_t url_conv, char *dest, ICONV_CONST char *src, int len) { memset(dest, 0, 1000); if (url_conv == (iconv_t)-1) { int i; for (i = 0; i < len; i++) { dest[i * 2] = src[i]; dest[i * 2 + 1] = 0; } dest[i * 2] = 0; dest[i * 2 + 1] = 0; } else { size_t len1, len2; ICONV_CONST char *ip; char *op; len1 = len; len2 = 1000; ip = src; op = dest; iconv(url_conv, &ip, &len1, &op, &len2); } } #else static void string_utf16(int unused, char *dest, const char *src, int len) { int i; memset (dest, 0, 1000); for (i = 0; i < len; i++) { dest[i * 2] = src[i]; dest[i * 2 + 1] = 0; } dest[i * 2] = 0; dest[i * 2 + 1] = 0; } #endif /* * return packet type */ static int get_packet_header (mms_t *this, mms_packet_header_t *header) { size_t len; int packet_type; header->packet_len = 0; header->packet_seq = 0; header->flags = 0; header->packet_id_type = 0; len = _x_io_tcp_read (this->stream, this->s, (char*)this->buf, 8); if (len != 8) goto error; if (_X_LE_32(this->buf + 4) == 0xb00bface) { /* command packet */ header->flags = this->buf[3]; len = _x_io_tcp_read (this->stream, this->s, (char*)(this->buf + 8), 4); if (len != 4) goto error; header->packet_len = _X_LE_32(this->buf + 8) + 4; if (header->packet_len > BUF_SIZE - 12) { header->packet_len = 0; goto error; } lprintf("mms command\n"); packet_type = MMS_PACKET_COMMAND; } else { header->packet_seq = _X_LE_32(this->buf); header->packet_id_type = this->buf[4]; header->flags = this->buf[5]; header->packet_len = (_X_LE_16(this->buf + 6) - 8) & 0xffff; if (header->packet_id_type == ASF_HEADER_PACKET_ID_TYPE) { lprintf("asf header\n"); packet_type = MMS_PACKET_ASF_HEADER; } else { lprintf("asf packet\n"); packet_type = MMS_PACKET_ASF_PACKET; } } return packet_type; error: lprintf("read error, len=%zd\n", len); return MMS_PACKET_ERR; } static int get_packet_command (mms_t *this, uint32_t packet_len) { int command = 0; size_t len; /* always enter this loop */ lprintf("packet_len: %d bytes\n", packet_len); len = _x_io_tcp_read (this->stream, this->s, (char*)(this->buf + 12), packet_len) ; if (len != packet_len) { return 0; } print_command ((char*)this->buf, len); /* check protocol type ("MMS ") */ if (_X_LE_32(this->buf + 12) != 0x20534D4D) { lprintf("unknown protocol type: %c%c%c%c (0x%08X)\n", this->buf[12], this->buf[13], this->buf[14], this->buf[15], _X_LE_32(this->buf + 12)); return 0; } command = _X_LE_32 (this->buf + 36) & 0xFFFF; lprintf("command = 0x%2x\n", command); return command; } static int get_answer (mms_t *this) { int command = 0; mms_packet_header_t header; switch (get_packet_header (this, &header)) { case MMS_PACKET_ERR: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to read mms packet header\n"); break; case MMS_PACKET_COMMAND: command = get_packet_command (this, header.packet_len); if (command == 0x1b) { if (!send_command (this, 0x1b, 0, 0, 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command\n"); return 0; } /* FIXME: limit recursion */ command = get_answer (this); } break; case MMS_PACKET_ASF_HEADER: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected asf header packet\n"); break; case MMS_PACKET_ASF_PACKET: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected asf packet\n"); break; } return command; } static int get_asf_header (mms_t *this) { off_t len; int stop = 0; this->asf_header_read = 0; this->asf_header_len = 0; while (!stop) { mms_packet_header_t header; int command; switch (get_packet_header (this, &header)) { case MMS_PACKET_ERR: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to read mms packet header\n"); return 0; break; case MMS_PACKET_COMMAND: command = get_packet_command (this, header.packet_len); if (command == 0x1b) { if (!send_command (this, 0x1b, 0, 0, 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command\n"); return 0; } command = get_answer (this); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected command packet\n"); } break; case MMS_PACKET_ASF_HEADER: case MMS_PACKET_ASF_PACKET: if (header.packet_len + this->asf_header_len > ASF_HEADER_LEN) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: asf packet too large\n"); return 0; } len = _x_io_tcp_read (this->stream, this->s, (char*)(this->asf_header_buffer + this->asf_header_len), header.packet_len); if (len != header.packet_len) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: get_header failed\n"); return 0; } this->asf_header_len += header.packet_len; lprintf("header flags: %d\n", header.flags); if ((header.flags == 0X08) || (header.flags == 0X0C)) stop = 1; break; } } lprintf ("get header packet succ\n"); return 1; } static int interp_asf_header (mms_t *this) { /* delete previous header */ if (this->asf_header) { asf_header_delete(this->asf_header); } /* the header starts with : * byte 0-15: header guid * byte 16-23: header length */ this->asf_header = asf_header_new(this->asf_header_buffer + 24, this->asf_header_len - 24); if (!this->asf_header) return 0; return 1; } static const char mmst_proto_s[][8] = { "mms", "mmst", "" }; static int mmst_valid_proto (const char *proto) { int i = 0; lprintf("mmst_valid_proto\n"); if (!proto) return 0; while(*(mmst_proto_s[i])) { if (!strcasecmp(proto, mmst_proto_s[i])) { return 1; } i++; } return 0; } static void report_progress (xine_stream_t *stream, int p) { xine_event_t event; xine_progress_data_t prg; prg.description = _("Connecting MMS server (over tcp)..."); prg.percent = p; event.type = XINE_EVENT_PROGRESS; event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (stream, &event); } /* * returns 1 on error */ static int mms_tcp_connect(mms_t *this) { int progress, res; if (!this->url.port) this->url.port = MMST_PORT; /* * try to connect */ lprintf("try to connect to %s on port %d \n", this->url.host, this->url.port); this->s = _x_io_tcp_connect (this->stream, this->url.host, this->url.port); if (this->s < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "failed to connect '%s'\n", this->url.host); return 1; } /* connection timeout 15s */ progress = 0; do { report_progress(this->stream, progress); res = _x_io_select (this->stream, this->s, XIO_WRITE_READY, 500); progress += 1; } while ((res == XIO_TIMEOUT) && (progress < 30)); if (res != XIO_READY) { return 1; } lprintf ("connected\n"); return 0; } static void mms_gen_guid(char guid[]) { static const char digit[16] = "0123456789ABCDEF"; int i = 0; srand(time(NULL)); for (i = 0; i < 36; i++) { guid[i] = digit[(int) ((16.0*rand())/(RAND_MAX+1.0))]; } guid[8] = '-'; guid[13] = '-'; guid[18] = '-'; guid[23] = '-'; guid[36] = '\0'; } /* * return 0 on error */ static int mms_choose_best_streams(mms_t *this) { int i; int video_stream = 0; int audio_stream = 0; int res; /* choose the best quality for the audio stream */ asf_header_choose_streams (this->asf_header, this->bandwidth, &video_stream, &audio_stream); lprintf("selected streams: audio %d, video %d\n", audio_stream, video_stream); lprintf("disabling other streams\n"); memset (this->scmd_body, 0, 40); for (i = 1; i < this->asf_header->stream_count; i++) { this->scmd_body [ (i - 1) * 6 + 2 ] = 0xFF; this->scmd_body [ (i - 1) * 6 + 3 ] = 0xFF; this->scmd_body [ (i - 1) * 6 + 4 ] = this->asf_header->streams[i]->stream_number; this->scmd_body [ (i - 1) * 6 + 5 ] = this->asf_header->streams[i]->stream_number >> 8; if ((i == audio_stream) || (i == video_stream)) { this->scmd_body [ (i - 1) * 6 + 6 ] = 0x00; this->scmd_body [ (i - 1) * 6 + 7 ] = 0x00; } else { lprintf("disabling stream %d\n", this->asf_header->streams[i]->stream_number); this->scmd_body [ (i - 1) * 6 + 6 ] = 0x02; this->scmd_body [ (i - 1) * 6 + 7 ] = 0x00; } } /* command 0x33 */ if (!send_command (this, 0x33, this->asf_header->stream_count, 0xFFFF | this->asf_header->streams[0]->stream_number << 16, this->asf_header->stream_count * 6 + 2)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: mms_choose_best_streams failed\n"); return 0; } if ((res = get_answer (this)) != 0x21) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected response: %02x (0x21)\n", res); } return 1; } /* * TODO: error messages * network timing request */ mms_t *mms_connect (xine_stream_t *stream, const char *url, int bandwidth) { #ifdef USE_ICONV iconv_t url_conv = (iconv_t)-1; #else int url_conv = 0; #endif mms_t *this; char str[1024]; int res; if (!url) return NULL; this = calloc(1, sizeof (mms_t)); if (!this) return NULL; this->stream = stream; this->s = -1; this->seq_num = 0; this->scmd_body = this->scmd + CMD_HEADER_LEN + CMD_PREFIX_LEN; this->asf_header_len = 0; this->asf_header_read = 0; this->buf_size = 0; this->buf_read = 0; this->bandwidth = bandwidth; this->current_pos = 0; this->eos = 0; report_progress (stream, 0); if (!_x_url_parse2 (url, &this->url)) { lprintf ("invalid url\n"); goto fail; } if (!mmst_valid_proto(this->url.proto)) { lprintf ("unsupported protocol\n"); goto fail; } if (mms_tcp_connect(this)) { goto fail; } report_progress (stream, 30); #ifdef USE_ICONV url_conv = string_utf16_open(); #endif /* * let the negotiations begin... */ /* command 0x1 */ lprintf("send command 0x01\n"); mms_gen_guid(this->guid); snprintf (str, sizeof(str), "\x1c\x03NSPlayer/7.0.0.1956; {%s}; Host: %s", this->guid, this->url.host); string_utf16 (url_conv, this->scmd_body, str, strlen(str) + 2); if (!send_command (this, 1, 0, 0x0004000b, strlen(str) * 2 + 8)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command 0x01\n"); goto fail; } if ((res = get_answer (this)) != 0x01) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected response: %02x (0x01)\n", res); goto fail; } report_progress (stream, 40); /* TODO: insert network timing request here */ /* command 0x2 */ lprintf("send command 0x02\n"); string_utf16 (url_conv, &this->scmd_body[8], (ICONV_CONST char*)"\002\000\\\\192.168.0.129\\TCP\\1037\0000", 28); memset (this->scmd_body, 0, 8); if (!send_command (this, 2, 0, 0, 28 * 2 + 8)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command 0x02\n"); goto fail; } switch (res = get_answer (this)) { case 0x02: /* protocol accepted */ break; case 0x03: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: protocol failed\n"); goto fail; break; default: lprintf("unexpected response: %02x (0x02 or 0x03)\n", res); goto fail; } report_progress (stream, 50); /* command 0x5 */ { mms_buffer_t command_buffer; char *path, *unescaped; size_t pathlen; unescaped = strdup (this->url.uri); if (!unescaped) goto fail; _x_mrl_unescape (unescaped); /* remove the first '/' */ path = unescaped; pathlen = strlen (path); if (pathlen > 1) { path++; pathlen--; } lprintf("send command 0x05\n"); mms_buffer_init(&command_buffer, this->scmd_body); mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ string_utf16 (url_conv, this->scmd_body + command_buffer.pos, path, pathlen); free (unescaped); if (!send_command (this, 5, 1, 0xffffffff, pathlen * 2 + 12)) goto fail; } switch (res = get_answer (this)) { case 0x06: { int xx, yy; /* no authentication required */ /* Warning: sdp is not right here */ xx = this->buf[62]; yy = this->buf[63]; this->live_flag = ((xx == 0) && ((yy & 0xf) == 2)); lprintf("live: live_flag=%d, xx=%d, yy=%d\n", this->live_flag, xx, yy); } break; case 0x1A: /* authentication request, not yet supported */ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: authentication request, not yet supported\n"); goto fail; break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected response: %02x (0x06 or 0x1A)\n", res); goto fail; } report_progress (stream, 60); /* command 0x15 */ lprintf("send command 0x15\n"); { mms_buffer_t command_buffer; mms_buffer_init(&command_buffer, this->scmd_body); mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ mms_buffer_put_32 (&command_buffer, 0x00800000); /* ?? */ mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ mms_buffer_put_32 (&command_buffer, 0x40AC2000); /* ?? */ mms_buffer_put_32 (&command_buffer, ASF_HEADER_PACKET_ID_TYPE); /* Header Packet ID type */ mms_buffer_put_32 (&command_buffer, 0x00000000); /* ?? */ if (!send_command (this, 0x15, 1, 0, command_buffer.pos)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command 0x15\n"); goto fail; } } if ((res = get_answer (this)) != 0x11) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected response: %02x (0x11)\n", res); goto fail; } if (!get_asf_header (this)) goto fail; interp_asf_header (this); report_progress (stream, 70); if (!mms_choose_best_streams(this)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: mms_choose_best_streams failed"); goto fail; } report_progress (stream, 80); /* command 0x07 */ /* moved to mms_read() */ #if 0 { mms_buffer_t command_buffer; mms_buffer_init(&command_buffer, this->scmd_body); mms_buffer_put_32 (&command_buffer, 0x00000000); /* 64 byte float timestamp */ mms_buffer_put_32 (&command_buffer, 0x00000000); mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ mms_buffer_put_8 (&command_buffer, 0xFF); mms_buffer_put_8 (&command_buffer, 0xFF); mms_buffer_put_8 (&command_buffer, 0x00); /* stream time limit flag */ mms_buffer_put_32 (&command_buffer, ASF_MEDIA_PACKET_ID_TYPE); /* asf media packet id type */ if (!send_command (this, 0x07, 1, 0x0001FFFF, command_buffer.pos)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command 0x07\n"); goto fail; } } #endif report_progress (stream, 100); #ifdef USE_ICONV string_utf16_close(url_conv); #endif lprintf("mms_connect: passed\n" ); return this; fail: #ifdef USE_ICONV string_utf16_close(url_conv); #endif if (this->s != -1) _x_io_tcp_close (this->stream, this->s); _x_url_cleanup(&this->url); free (this); return NULL; } static int get_media_packet (mms_t *this) { mms_packet_header_t header; off_t len; switch (get_packet_header (this, &header)) { case MMS_PACKET_ERR: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to read mms packet header\n"); return 0; break; case MMS_PACKET_COMMAND: { int command; command = get_packet_command (this, header.packet_len); switch (command) { case 0x1e: { uint32_t error_code; /* Warning: sdp is incomplete. Do not stop if error_code==1 */ error_code = _X_LE_32(this->buf + CMD_HEADER_LEN); lprintf ("End of the current stream. Continue=%d\n", error_code); if (error_code == 0) { this->eos = 1; return 0; } } break; case 0x20: { lprintf ("new stream.\n"); /* asf header */ if (!get_asf_header (this)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "failed to read new ASF header\n"); return 0; } interp_asf_header (this); if (!mms_choose_best_streams(this)) return 0; /* send command 0x07 */ /* TODO: ugly */ /* command 0x07 */ { mms_buffer_t command_buffer; mms_buffer_init(&command_buffer, this->scmd_body); mms_buffer_put_32 (&command_buffer, 0x00000000); /* 64 byte float timestamp */ mms_buffer_put_32 (&command_buffer, 0x00000000); mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ mms_buffer_put_8 (&command_buffer, 0xFF); mms_buffer_put_8 (&command_buffer, 0xFF); mms_buffer_put_8 (&command_buffer, 0x00); /* stream time limit flag */ mms_buffer_put_32 (&command_buffer, ASF_MEDIA_PACKET_ID_TYPE); /* asf media packet id type */ if (!send_command (this, 0x07, 1, 0x0001FFFF, command_buffer.pos)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command 0x07\n"); return 0; } } /* this->current_pos = 0; */ } break; case 0x1b: { if (!send_command (this, 0x1b, 0, 0, 0)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command\n"); return 0; } } break; case 0x05: break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "unexpected mms command %02x\n", command); } this->buf_size = 0; } break; case MMS_PACKET_ASF_HEADER: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libmms: unexpected asf header packet\n"); this->buf_size = 0; break; case MMS_PACKET_ASF_PACKET: { /* media packet */ lprintf ("asf media packet detected, packet_len=%d, packet_seq=%d\n", header.packet_len, header.packet_seq); if (header.packet_len > this->asf_header->file->packet_size) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: invalid asf packet len: %d bytes\n", header.packet_len); return 0; } len = _x_io_tcp_read (this->stream, this->s, (char*)this->buf, header.packet_len); if (len != header.packet_len) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: read failed\n"); return 0; } /* explicit padding with 0 */ lprintf("padding: %d bytes\n", this->asf_header->file->packet_size - header.packet_len); memset(this->buf + header.packet_len, 0, this->asf_header->file->packet_size - header.packet_len); this->buf_size = this->asf_header->file->packet_size; } break; } lprintf ("get media packet succ\n"); return 1; } size_t mms_peek_header (mms_t *this, char *data, size_t maxsize) { size_t len; len = (this->asf_header_len < maxsize) ? this->asf_header_len : maxsize; memcpy(data, this->asf_header_buffer, len); return len; } int mms_read (mms_t *this, char *data, int len) { int total; total = 0; while (total < len && !this->eos) { if (this->asf_header_read < this->asf_header_len) { int n, bytes_left ; bytes_left = this->asf_header_len - this->asf_header_read ; if ((len - total) < bytes_left) n = len-total; else n = bytes_left; xine_fast_memcpy (&data[total], &this->asf_header_buffer[this->asf_header_read], n); this->asf_header_read += n; total += n; this->current_pos += n; if (this->asf_header_read == this->asf_header_len) break; } else { int n, bytes_left ; if (!this->playing) { /* send command 0x07 with initial timestamp */ mms_buffer_t command_buffer; mms_buffer_init(&command_buffer, this->scmd_body); mms_buffer_put_64 (&command_buffer, D2Q(this->start_time)); /* 64 byte float timestamp */ mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* ?? */ mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF); /* first packet sequence */ mms_buffer_put_8 (&command_buffer, 0xFF); /* max stream time limit (3 bytes) */ mms_buffer_put_8 (&command_buffer, 0xFF); mms_buffer_put_8 (&command_buffer, 0xFF); mms_buffer_put_8 (&command_buffer, 0x00); /* stream time limit flag */ mms_buffer_put_32 (&command_buffer, ASF_MEDIA_PACKET_ID_TYPE); /* asf media packet id type */ if (!send_command (this, 0x07, 1, 0x0001FFFF, command_buffer.pos)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: failed to send command 0x07\n"); this->eos = 1; break; } this->playing = 1; } bytes_left = this->buf_size - this->buf_read; if (bytes_left == 0) { this->buf_size = this->buf_read = 0; if (!get_media_packet (this)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "libmms: get_media_packet failed\n"); return total; } bytes_left = this->buf_size; } if ((len - total) < bytes_left) n = len - total; else n = bytes_left; xine_fast_memcpy (&data[total], &this->buf[this->buf_read], n); this->buf_read += n; total += n; this->current_pos += n; } } return total; } void mms_close (mms_t *this) { if (this->s != -1) _x_io_tcp_close (this->stream, this->s); _x_url_cleanup(&this->url); if (this->asf_header) asf_header_delete(this->asf_header); free (this); } uint32_t mms_get_length (mms_t *this) { return this->asf_header->file->file_size; } off_t mms_get_current_pos (mms_t *this) { return this->current_pos; } void mms_set_start_time (mms_t *this, int time_offset) { if (time_offset >= 0) this->start_time = (double) time_offset / 1000.0; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_crypto.c���������������������������������������������������������������0000644�0001750�0001750�00000032563�14647725152�015526� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Transparent decryption of input data * * AES * Key bits: 128, 192 or 256. * CBC (iv given), ECB (no iv) * * Examples: * xine crypto:key=xxx:file://path/to/file.ts * xine crypto:key=xxx:http://www.example.org/file.ts * xine crypto:key=xxx:iv=yyy:file:/path/file.ext * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <gcrypt.h> #define LOG_MODULE "input_crypto" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "input_helper.h" #define CRYPTO_BLOCK_SIZE 4096 #define CHECK(x) //#define CHECK(x) _x_assert(x) typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; char *mrl; input_plugin_t *in0; gcry_cipher_hd_t gcry_h; off_t curpos; off_t block_start; off_t block_size; uint8_t block[CRYPTO_BLOCK_SIZE]; int eof; size_t iv_len; uint8_t iv[16]; size_t key_len; uint8_t key[32]; } crypto_input_plugin_t; static void _fill(crypto_input_plugin_t *this) { unsigned have = 0, had = 0; gcry_error_t err; if (this->eof) return; CHECK(this->block_start + this->block_size == this->in0->get_current_pos(this->in0)); /* keep unread part of current buffer (we need to overread for EOF padding detection) */ if (this->curpos >= this->block_start && this->curpos < this->block_start + this->block_size) { have = had = this->block_start + this->block_size - this->curpos; memmove(this->block, this->block + this->block_size - had, had); } this->block_start += this->block_size - had; /* read */ while (have < sizeof(this->block)) { off_t got = this->in0->read(this->in0, this->block + have, sizeof(this->block) - have); if (got <= 0) { if (got == 0) this->eof = 1; break; } have += got; } this->block_size = have; /* decrypt */ if (have > had) { err = gcry_cipher_decrypt(this->gcry_h, this->block + had, this->block_size - had, NULL, 0); if (err) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error decrypting data: %d\n", err); } /* Drop possible PKCS7 padding at the end */ if (this->eof && this->block_size > 0) this->block_size -= this->block[this->block_size - 1]; lprintf("filled: block_start %" PRId64 ", size %u, in0_pos %" PRId64 "\n", (int64_t)this->block_start, (unsigned)this->block_size, (int64_t)this->in0->get_current_pos(this->in0)); } static off_t crypto_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); off_t have = 0, block_pos, chunk_size; CHECK(this->curpos >= this->block_start); while (have < len) { /* refill cache ? */ if (this->curpos >= this->block_start + this->block_size - 16 /* keep one block for padding check */) { _fill(this); if (this->curpos >= this->block_start + this->block_size) break; } block_pos = this->curpos - this->block_start; chunk_size = MIN(len - have, this->block_size - block_pos); if (!this->eof && chunk_size > 16) chunk_size -= 16; /* delay last block to detect padding */ memcpy((uint8_t *)buf_gen + have, this->block + block_pos, chunk_size); have += chunk_size; this->curpos += chunk_size; } return have; } static uint32_t crypto_plugin_get_blocksize (input_plugin_t *this_gen) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); return this->in0->get_blocksize(this->in0); } static off_t crypto_plugin_get_current_pos (input_plugin_t *this_gen) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); return this->curpos; } static off_t crypto_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); off_t res, in0_length = this->in0->get_length(this->in0); unsigned to_skip; res = _x_input_translate_seek(offset, origin, this->curpos, in0_length); if (res < 0) return res; /* check if seeking inside internal buffer */ if (offset >= this->block_start && offset < this->block_start + this->block_size) { this->curpos = offset; return offset; } /* invalidate cache */ this->block_size = 0; this->eof = 0; /* align to block boundary */ to_skip = offset & 0x0f; if (this->iv_len) { /* need to set or generate iv, read also previous block */ if (offset < 16) { gcry_error_t err; err = gcry_cipher_setiv(this->gcry_h, this->iv, this->iv_len); if (err) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error setting cipher iv: %d\n", err); } else { /* resync iv by reading and decrypting prev block */ to_skip += 16; } } lprintf("seek to %ld, skip=%u\n", (int64_t)(offset - to_skip), to_skip); /* seek to block boundary */ res = this->in0->seek(this->in0, offset - to_skip, SEEK_SET); if (res < 0) { return res; } this->block_start = offset - to_skip; this->curpos = offset; /* re-gen iv: refill cache and drop first (broken) block from cache */ if (to_skip > 16) { _fill(this); if (this->block_size >= 16) { memmove(this->block, this->block + 16, this->block_size - 16); this->block_size -= 16; this->block_start += 16; } } return this->curpos; } static uint32_t crypto_plugin_get_capabilities (input_plugin_t *this_gen) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); return this->in0->get_capabilities(this->in0) | INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW; } static off_t crypto_plugin_get_length (input_plugin_t *this_gen) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); return this->in0->get_length(this->in0); } static const char* crypto_plugin_get_mrl (input_plugin_t *this_gen) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); return this->mrl; } static int crypto_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); int result = INPUT_OPTIONAL_UNSUPPORTED; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: crypto_plugin_seek(this_gen, 0, SEEK_SET); result = this->block_size < MAX_PREVIEW_SIZE ? this->block_size : MAX_PREVIEW_SIZE; memcpy (data, this->block, result); break; case INPUT_OPTIONAL_DATA_SIZED_PREVIEW: crypto_plugin_seek(this_gen, 0, SEEK_SET); memcpy (&result, data, sizeof (result)); if (result <= 0) return INPUT_OPTIONAL_UNSUPPORTED; if (result > (int)this->block_size) result = this->block_size; memcpy (data, this->block, result); return result; case INPUT_OPTIONAL_DATA_NEW_MRL: case INPUT_OPTIONAL_DATA_CLONE: return INPUT_OPTIONAL_UNSUPPORTED; default: break; } return this->in0->get_optional_data(this->in0, data, data_type); } static void crypto_plugin_dispose (input_plugin_t *this_gen ) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); gcry_cipher_close(this->gcry_h); _x_free_input_plugin (this->stream, this->in0); _x_freep (&this->mrl); free (this_gen); } static int crypto_plugin_open (input_plugin_t *this_gen) { crypto_input_plugin_t *this = xine_container_of(this_gen, crypto_input_plugin_t, input_plugin); gcry_error_t err; if (!this->in0->open (this->in0)) return 0; if (this->iv_len) err = gcry_cipher_open(&this->gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0); else err = gcry_cipher_open(&this->gcry_h, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); if (err) goto error; err = gcry_cipher_setkey(this->gcry_h, this->key, this->key_len); if (err) goto error; if (this->iv_len) { err = gcry_cipher_setiv(this->gcry_h, this->iv, this->iv_len); if (err) goto error; } this->curpos = 0; return 1; error: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error setting cipher: %d\n", err); return 0; } static unsigned _hexval(const char *c) { return ((unsigned)(*c -'0') <= 9) ? (unsigned)(*c - '0') : ((unsigned)((*c | 0x20) - 'a') < 6) ? (unsigned)((*c | 0x20) - 'a') + 10 : (unsigned)-1; } static int _get_hex(const char *src, uint8_t *dst) { unsigned v = (_hexval(src) << 4) | _hexval(src + 1); *dst = v; return - (v >> 8); } static size_t _get_key(const char *src, uint8_t *dst, size_t dst_size) { size_t len; for (len = 0; src[2*len] && len < dst_size; len++) if (_get_hex(src + 2*len, dst + len) < 0) break; return src[2*len] == ':' ? len : 0; } static input_plugin_t *crypto_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { crypto_input_plugin_t *this; input_plugin_t *in0; const char *sub_mrl, *key = NULL, *iv = NULL, *p; size_t key_len, iv_len; uint8_t aes_key[32], aes_iv[16]; if (strncasecmp (mrl, "crypto:", 7)) return NULL; /* get sub-mrl */ sub_mrl = strstr(mrl, ":/"); if (!sub_mrl) return 0; while (sub_mrl > mrl && sub_mrl[-1] != ':') /* rewind protocol part */ sub_mrl--; /* parse key */ for (p = strchr(mrl, ':') + 1; p < sub_mrl; p = strchr(p, ':') + 1) { if (!strncmp(p, "key=", 4)) { key = p + 4; } else if (!strncmp(p, "iv=", 3)) { iv = p + 3; } else { xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Unknown option at %s\n", p); return NULL; } } if (!key) { xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": No key privided in mrl\n"); return NULL; } key_len = _get_key(key, aes_key, sizeof(aes_key)); if (key_len != 16 && key_len != 24 && key_len != 32) { xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unsupported key (length %zu)\n", key_len); return NULL; } iv_len = iv ? _get_key(iv, aes_iv, sizeof(aes_iv)) : 0; if (iv_len != 0 && iv_len != 16) { xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unsupported IV (length %zu)\n", iv_len); return NULL; } /* find real input */ in0 = _x_find_input_plugin (stream, sub_mrl); if (!in0) return NULL; this = calloc(1, sizeof(crypto_input_plugin_t)); if (!this) { _x_free_input_plugin (stream, in0); return NULL; } this->mrl = strdup(sub_mrl); this->stream = stream; this->curpos = 0; this->in0 = in0; this->key_len = key_len; this->iv_len = iv_len; memcpy(this->key, aes_key, key_len); if (iv_len) { memcpy(this->iv, aes_iv, iv_len); } if (!this->mrl) { _x_free_input_plugin (stream, in0); free(this); return NULL; } this->input_plugin.open = crypto_plugin_open; this->input_plugin.get_capabilities = crypto_plugin_get_capabilities; this->input_plugin.read = crypto_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = crypto_plugin_seek; this->input_plugin.get_current_pos = crypto_plugin_get_current_pos; this->input_plugin.get_length = crypto_plugin_get_length; this->input_plugin.get_blocksize = crypto_plugin_get_blocksize; this->input_plugin.get_mrl = crypto_plugin_get_mrl; this->input_plugin.get_optional_data = crypto_plugin_get_optional_data; this->input_plugin.dispose = crypto_plugin_dispose; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * plugin class */ static void *input_crypto_init_class (xine_t *xine, const void *data) { static const input_class_t input_crypto_class = { .get_instance = crypto_class_get_instance, .description = N_("crypto input plugin wrapper"), .identifier = "crypto", .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)xine; (void)data; return (void *)&input_crypto_class; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 18, "crypto", XINE_VERSION_CODE, NULL, input_crypto_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_helper.c���������������������������������������������������������������0000644�0001750�0001750�00000016000�14647725152�015451� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * input plugin helper functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <xine/xine_internal.h> #include "input_helper.h" /* * mrl array alloc / free helpers */ void _x_input_free_mrls(xine_mrl_t ***p) { if (*p) { xine_mrl_t **mrls; for (mrls = *p; *mrls; mrls++) { MRL_ZERO(*mrls); } _x_freep(p); } } xine_mrl_t **_x_input_alloc_mrls(size_t n) { const size_t align = offsetof(struct { char dummy; xine_mrl_t mrl; }, mrl); xine_mrl_t **mrls; void *mem; size_t size = (n + 1) * (sizeof(*mrls) + sizeof(**mrls)); size_t i; mrls = mem = calloc(1, size); if (!mem) { return NULL; } mem = (uint8_t*)mem + (n + 1) * sizeof(*mrls); /* skip pointer array (including terminating NULL) */ mem = (void *)((intptr_t)mem + (align - 1) % align); /* align */ for (i = 0; i < n; i++) { mrls[i] = (xine_mrl_t *)((intptr_t)mem + i * sizeof(xine_mrl_t)); } return mrls; } xine_mrl_t **_x_input_realloc_mrls(xine_mrl_t ***p, size_t n) { xine_mrl_t **old_m = *p; xine_mrl_t **new_m; size_t old_n; if (!old_m) { *p = _x_input_alloc_mrls(n); return *p; } /* count old entries */ for (old_n = 0; old_m[old_n]; old_n++) { } /* does not grow ? */ if (old_n >= n) return *p; /* alloc new array */ new_m = _x_input_alloc_mrls(n); if (!new_m) return NULL; /* copy old entries */ for (n = 0; old_m[n]; n++) { *(new_m[n]) = *(old_m[n]); } /* store result */ free(*p); *p = new_m; return *p; } /* * Sorting function, it comes from GNU fileutils package. */ #define S_N 0x0 #define S_I 0x4 #define S_F 0x8 #define S_Z 0xC #define CMP 2 #define LEN 3 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) static int _input_strverscmp (const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; unsigned char c1, c2; int state; int diff; static const unsigned int next_state[] = { S_N, S_I, S_Z, S_N, S_N, S_I, S_I, S_I, S_N, S_F, S_F, S_F, S_N, S_F, S_Z, S_Z }; static const int result_type[] = { CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, -1, -1, CMP, 1, LEN, LEN, CMP, 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 1, 1, CMP, -1, CMP, CMP, CMP, -1, CMP, CMP, CMP }; if(p1 == p2) return 0; c1 = *p1++; c2 = *p2++; state = S_N | ((c1 == '0') + (ISDIGIT(c1) != 0)); while((diff = c1 - c2) == 0 && c1 != '\0') { state = next_state[state]; c1 = *p1++; c2 = *p2++; state |= (c1 == '0') + (ISDIGIT(c1) != 0); } state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT(c2) != 0))]; switch(state) { case CMP: return diff; case LEN: while(ISDIGIT(*p1++)) if(!ISDIGIT(*p2++)) return 1; return ISDIGIT(*p2) ? -1 : diff; default: return state; } } static int _mrl_cmp (const void *p1, const void *p2) { const xine_mrl_t * const *m1 = p1; const xine_mrl_t * const *m2 = p2; int dir = ((*m2)->type & mrl_file_directory) - ((*m1)->type & mrl_file_directory); if (dir) { return dir; } return _input_strverscmp((*m1)->mrl, (*m2)->mrl); } void _x_input_sort_mrls(xine_mrl_t **mrls, ssize_t cnt) { _x_assert(mrls); /* count entries */ if (cnt < 0) for (cnt = 0; mrls[cnt]; cnt++) ; if (cnt < 2) return; qsort(mrls, cnt, sizeof(xine_mrl_t *), _mrl_cmp); } /* * config helpers */ void _x_input_register_show_hidden_files(config_values_t *config) { config->register_bool(config, "media.files.show_hidden_files", 0, _("list hidden files"), _("If enabled, the browser to select the file to " "play will also show hidden files."), 10, NULL, NULL); } int _x_input_get_show_hidden_files(config_values_t *config) { cfg_entry_t *entry; entry = config->lookup_entry(config, "media.files.show_hidden_files"); if (entry) { return entry->num_value; } return 1; } void _x_input_register_default_servers(config_values_t *config) { config->register_string(config, "media.servers", "", _("Default servers"), _("List of space-separated server urls for media browser. " "(ex. \"ftp://ftp3.itu.int sftp://user:pass@host.com\")" ), 10, NULL, NULL); } xine_mrl_t **_x_input_get_default_server_mrls(config_values_t *config, const char *type, int *nFiles) { xine_mrl_t **mrls; cfg_entry_t *entry; char *svrs, *pt; size_t n, type_len; *nFiles = 0; entry = config->lookup_entry(config, "media.servers"); if (!entry || !entry->str_value) return NULL; svrs = strdup(entry->str_value); type_len = strlen(type); /* count entries */ for (n = 1, pt = svrs; pt; pt = strchr(pt + 1, ' '), n++) { } mrls = _x_input_alloc_mrls(n); if (!mrls) { free(svrs); return NULL; } for (n = 0, pt = svrs; pt; ) { char *svr = pt; pt = strchr(pt, ' '); if (pt) *(pt++) = 0; if (!strncmp(svr, type, type_len)) { mrls[n]->type = mrl_net | mrl_file | mrl_file_directory; mrls[n]->origin = strdup(type); mrls[n]->mrl = strdup(svr); n++; } } if (n > 1) _x_input_sort_mrls(mrls, n); *nFiles = n; free(svrs); return mrls; } /* * default read_block function. * uses read() to fill the block. */ buf_element_t *_x_input_default_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { buf_element_t *buf; off_t total_bytes; if (todo < 0) return NULL; buf = fifo->buffer_pool_size_alloc (fifo, todo); if (todo > buf->max_size) todo = buf->max_size; buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; total_bytes = this_gen->read (this_gen, buf->content, todo); if (total_bytes != todo) { buf->free_buffer (buf); return NULL; } buf->size = total_bytes; return buf; } xine-lib-1.2/src/input/input_bluray.c���������������������������������������������������������������0000644�0001750�0001750�00000160267�14647725152�015507� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * Copyright (C) 2009-2011 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Input plugin for BluRay discs / images * * Requires libbluray 0.2.1 or later: * http://www.videolan.org/developers/libbluray.html * git://git.videolan.org/libbluray.git * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <pthread.h> /* libbluray */ #include <libbluray/bluray.h> #include <libbluray/bluray-version.h> #include <libbluray/keys.h> #include <libbluray/overlay.h> #include <libbluray/meta_data.h> /* xine */ #define LOG_MODULE "input_bluray" #define LOG_VERBOSE /*#define LOG*/ #define LOGMSG(x...) xine_log (this->stream->xine, XINE_LOG_MSG, "input_bluray: " x); #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "media_helper.h" #include "input_helper.h" /* */ #ifndef MIN # define MIN(a,b) ((a)<(b)?(a):(b)) #endif #ifndef MAX # define MAX(a,b) ((a)>(b)?(a):(b)) #endif #define ALIGNED_UNIT_SIZE 6144 #define PKT_SIZE 192 #define TICKS_IN_MS 45 #define MIN_TITLE_LENGTH 180 #define BLURAY_MNT_PATH "/mnt/bluray" #if defined(__sun) #define BLURAY_PATH "/vol/dev/aliases/cdrom0" #elif defined(__OpenBSD__) #define BLURAY_PATH "/dev/rcd0c" #else #define BLURAY_PATH "/dev/dvd" #endif /* */ typedef struct { input_class_t input_class; xine_t *xine; xine_mrl_t **xine_playlist; int xine_playlist_size; /* config */ const char *mountpoint; const char *device; const char *language; const char *country; int region; int parental; int skip_mode; } bluray_input_class_t; #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) typedef struct { BD_ARGB_BUFFER buf; pthread_mutex_t buf_lock; } XINE_BD_ARGB_BUFFER; static void osd_buf_lock(BD_ARGB_BUFFER *buf_gen) { XINE_BD_ARGB_BUFFER *buf = (XINE_BD_ARGB_BUFFER*)buf_gen; pthread_mutex_lock(&buf->buf_lock); } static void osd_buf_unlock(BD_ARGB_BUFFER *buf_gen) { XINE_BD_ARGB_BUFFER *buf = (XINE_BD_ARGB_BUFFER*)buf_gen; pthread_mutex_unlock(&buf->buf_lock); } static void osd_buf_init(XINE_BD_ARGB_BUFFER *buf) { buf->buf.lock = osd_buf_lock; buf->buf.unlock = osd_buf_unlock; pthread_mutex_init(&buf->buf_lock, NULL); } static void osd_buf_destroy(XINE_BD_ARGB_BUFFER *buf) { if (buf->buf.lock) { buf->buf.lock = NULL; buf->buf.unlock = NULL; pthread_mutex_destroy(&buf->buf_lock); } } #endif /* BLURAY_VERSION >= 0.2.4 */ typedef struct { input_plugin_t input_plugin; bluray_input_class_t *class; xine_stream_t *stream; xine_event_queue_t *event_queue; xine_osd_t *osd[2]; #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) XINE_BD_ARGB_BUFFER osd_buf; #endif char *mrl; char *disc_root; char *disc_name; BLURAY *bdh; const BLURAY_DISC_INFO *disc_info; const META_DL *meta_dl; /* disc library meta data */ int num_title_idx; /* number of relevant playlists */ int current_title_idx; int num_titles; /* navigation mode, number of titles in disc index */ int current_title; /* navigation mode, title from disc index */ BLURAY_TITLE_INFO *title_info; pthread_mutex_t title_info_mutex; /* lock this when accessing title_info outside of input/demux thread */ unsigned int current_clip; time_t still_end_time; int pg_stream; uint8_t nav_mode : 1; uint8_t error : 1; uint8_t menu_open : 1; uint8_t stream_flushed : 1; uint8_t stream_reset_done : 1; uint8_t demux_action_req : 1; uint8_t end_of_title : 1; uint8_t pg_enable : 1; uint8_t has_video : 1; int mouse_inside_button; } bluray_input_plugin_t; static void queue_black_frame(bluray_input_plugin_t *this) { vo_frame_t *img = NULL; if (!_x_lock_port_rewiring(this->class->xine, 0)) { return; } img = this->stream->video_out->get_frame(this->stream->video_out, 1920, 1080, 16.0/9.0, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); if (img) { if (img->format == XINE_IMGFMT_YV12 && img->base[0] && img->base[1] && img->base[2]) { memset(img->base[0], 0x00, img->pitches[0] * img->height); memset(img->base[1], 0x80, img->pitches[1] * img->height / 2); memset(img->base[2], 0x80, img->pitches[2] * img->height / 2); img->duration = 0; img->pts = 0; img->bad_frame = 0; img->draw(img, this->stream); this->has_video = 1; } img->free(img); } _x_unlock_port_rewiring(this->class->xine); } /* * overlay */ #define PALETTE_INDEX_BACKGROUND 0xff static void send_num_buttons(bluray_input_plugin_t *this, int n) { xine_event_t event; xine_ui_data_t data; event.type = XINE_EVENT_UI_NUM_BUTTONS; event.data = &data; event.data_length = sizeof(data); data.num_buttons = n; xine_event_send(this->stream, &event); } static void clear_overlay(xine_osd_t *osd) { /* palette entry 0xff is background --> can't use xine_osd_clear(). */ memset(osd->osd.area, PALETTE_INDEX_BACKGROUND, osd->osd.width * osd->osd.height); osd->osd.x1 = osd->osd.width; osd->osd.y1 = osd->osd.height; osd->osd.x2 = 0; osd->osd.y2 = 0; osd->osd.area_touched = 0; } static xine_osd_t *get_overlay(bluray_input_plugin_t *this, int plane) { if (!this->pg_enable) { _x_select_spu_channel(this->stream, -1); } this->stream->video_out->enable_ovl(this->stream->video_out, 1); return this->osd[plane]; } static void close_overlay(bluray_input_plugin_t *this, int plane) { if (plane < 0) { close_overlay(this, 0); close_overlay(this, 1); return; } lprintf("close_overlay(#%d)\n", plane); if (plane < 2 && this->osd[plane]) { #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) osd_buf_lock(&this->osd_buf.buf); #endif xine_osd_free(this->osd[plane]); this->osd[plane] = NULL; #if BLURAY_VERSION < BLURAY_VERSION_CODE(0, 2, 2) if (plane == 1) { send_num_buttons(this, 0); this->menu_open = 0; } #endif #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) free(this->osd_buf.buf.buf[plane]); this->osd_buf.buf.buf[plane] = NULL; osd_buf_unlock(&this->osd_buf.buf); #endif } } static void open_overlay(bluray_input_plugin_t *this, int plane, uint16_t x, uint16_t y, uint16_t w, uint16_t h) { lprintf("open_overlay(#%d,%d,%d)\n", plane, w, h); if (this->osd[plane]) { close_overlay(this, plane); } this->osd[plane] = xine_osd_new(this->stream, x, y, w, h); xine_osd_set_extent(this->osd[plane], w, h); clear_overlay(this->osd[plane]); } static void draw_bitmap(xine_osd_t *osd, const BD_OVERLAY * const ov) { size_t i; /* convert and set palette */ if (ov->palette) { uint32_t color[256]; uint8_t trans[256]; for(i = 0; i < 256; i++) { trans[i] = ov->palette[i].T; color[i] = (ov->palette[i].Y << 16) | (ov->palette[i].Cr << 8) | ov->palette[i].Cb; } xine_osd_set_palette(osd, color, trans); } #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 3, 0) if (ov->palette_update_flag) return; #endif /* uncompress and draw bitmap */ if (ov->img && ov->w > 0 && ov->h > 0) { const BD_PG_RLE_ELEM *rlep = ov->img; size_t pixels = (size_t)ov->w * ov->h; uint8_t *img = malloc(pixels); if (img) { for (i = 0; i < pixels; i += rlep->len, rlep++) { memset(img + i, rlep->color, rlep->len); } xine_osd_draw_bitmap(osd, img, ov->x, ov->y, ov->w, ov->h, NULL); free(img); } } } static void overlay_proc(void *this_gen, const BD_OVERLAY * const ov) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; xine_osd_t *osd; int64_t vpts = 0; if (!this) { return; } if (!ov) { /* hide OSD */ close_overlay(this, -1); return; } if (ov->plane > 1) { return; } switch (ov->cmd) { case BD_OVERLAY_INIT: open_overlay(this, ov->plane, ov->x, ov->y, ov->w, ov->h); return; case BD_OVERLAY_CLOSE: close_overlay(this, ov->plane); return; } osd = get_overlay(this, ov->plane); if (!osd) { LOGMSG("overlay_proc(): overlay not open (cmd=%d)\n", ov->cmd); return; } if (ov->pts > 0) { vpts = ov->pts + this->stream->metronom->get_option(this->stream->metronom, METRONOM_VPTS_OFFSET); } switch (ov->cmd) { case BD_OVERLAY_DRAW: draw_bitmap(osd, ov); return; case BD_OVERLAY_WIPE: xine_osd_draw_rect(osd, ov->x, ov->y, ov->x + ov->w - 1, ov->y + ov->h - 1, PALETTE_INDEX_BACKGROUND, 1); return; case BD_OVERLAY_CLEAR: clear_overlay(osd); return; #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 3, 0) case BD_OVERLAY_HIDE: osd->osd.area_touched = 0; /* will be hiden at next commit time */ break; #endif case BD_OVERLAY_FLUSH: if (!osd->osd.area_touched) { xine_osd_hide(osd, vpts); } else { xine_osd_show(osd, vpts); } #if BLURAY_VERSION < BLURAY_VERSION_CODE(0, 2, 2) if (ov->plane == 1) { this->menu_open = !!osd->osd.area_touched; send_num_buttons(this, !!osd->osd.area_touched); } #endif return; default: lprintf("unknown overlay command %d\n", ov->cmd); return; } } #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) static void open_argb_overlay(bluray_input_plugin_t *this, int plane, uint16_t x, uint16_t y, uint16_t w, uint16_t h) { lprintf("open_argb_overlay(#%d,%d,%d)\n", plane, w, h); open_overlay(this, plane, x, y, w, h); if (xine_osd_get_capabilities(this->osd[plane]) & XINE_OSD_CAP_ARGB_LAYER) { this->osd_buf.buf.width = w; this->osd_buf.buf.height = h; this->osd_buf.buf.buf[plane] = calloc(sizeof(uint32_t), (size_t)w * h); } else { LOGMSG("open_argb_overlay() failed: video driver does not support ARGB overlays.\n"); } } static xine_osd_t *get_argb_overlay(bluray_input_plugin_t *this, int plane) { if (!this->osd_buf.buf.buf[plane]) { return NULL; } return get_overlay(this, plane); } static void argb_overlay_proc(void *this_gen, const BD_ARGB_OVERLAY * const ov) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; xine_osd_t *osd; int64_t vpts = 0; if (!this) { return; } if (!ov) { /* hide OSD */ close_overlay(this, -1); return; } if (ov->pts > 0) { vpts = ov->pts + this->stream->metronom->get_option(this->stream->metronom, METRONOM_VPTS_OFFSET); } switch (ov->cmd) { case BD_ARGB_OVERLAY_INIT: open_argb_overlay(this, ov->plane, 0, 0, ov->w, ov->h); return; case BD_ARGB_OVERLAY_CLOSE: close_overlay(this, ov->plane); return; } osd = get_argb_overlay(this, ov->plane); if (!osd) { LOGMSG("argb_overlay_proc(): ARGB overlay not open (cmd=%d)\n", ov->cmd); return; } switch (ov->cmd) { case BD_ARGB_OVERLAY_FLUSH: osd_buf_lock(&this->osd_buf.buf); xine_osd_set_argb_buffer(osd, this->osd_buf.buf.buf[ov->plane], this->osd_buf.buf.dirty[ov->plane].x0, this->osd_buf.buf.dirty[ov->plane].y0, this->osd_buf.buf.dirty[ov->plane].x1 - this->osd_buf.buf.dirty[ov->plane].x0 + 1, this->osd_buf.buf.dirty[ov->plane].y1 - this->osd_buf.buf.dirty[ov->plane].y0 + 1); xine_osd_show(osd, vpts); osd_buf_unlock(&this->osd_buf.buf); return; case BD_ARGB_OVERLAY_DRAW: /* nothing to do, DRI in use */ break; default: lprintf("unknown ARGB overlay command %d\n", ov->cmd); return; } } #endif /* BLURAY_VERSION >= 0.2.4 */ /* * stream info */ static void update_stream_info(bluray_input_plugin_t *this) { if (this->title_info) { /* set stream info */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_COUNT, this->title_info->angle_count); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_NUMBER, bd_get_current_angle(this->bdh)); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_CHAPTERS, this->title_info->chapter_count > 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_COUNT, this->title_info->chapter_count); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_NUMBER, bd_get_current_chapter(this->bdh) + 1); } } static void update_title_name(bluray_input_plugin_t *this) { char title_name[64] = ""; xine_ui_data_t udata; xine_event_t uevent = { .type = XINE_EVENT_UI_SET_TITLE, .stream = this->stream, .data = &udata, .data_length = sizeof(udata) }; /* check disc library metadata */ if (this->meta_dl) { unsigned i; for (i = 0; i < this->meta_dl->toc_count; i++) if (this->meta_dl->toc_entries[i].title_number == (unsigned)this->current_title) if (this->meta_dl->toc_entries[i].title_name) if (strlen(this->meta_dl->toc_entries[i].title_name) > 2) { strlcpy(title_name, this->meta_dl->toc_entries[i].title_name, sizeof(title_name)); } } /* title name */ if (title_name[0]) { } else if (this->current_title == BLURAY_TITLE_TOP_MENU) { strcpy(title_name, "Top Menu"); } else if (this->current_title == BLURAY_TITLE_FIRST_PLAY) { strcpy(title_name, "First Play"); } else if (this->nav_mode) { snprintf(title_name, sizeof(title_name), "Title %d/%d", this->current_title, this->num_titles); } else { snprintf(title_name, sizeof(title_name), "Title %d/%d", this->current_title_idx + 1, this->num_title_idx); } /* disc name */ if (this->disc_name && this->disc_name[0]) { udata.str_len = snprintf(udata.str, sizeof(udata.str), "%s, %s", this->disc_name, title_name); } else { udata.str_len = snprintf(udata.str, sizeof(udata.str), "%s", title_name); } _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, udata.str); xine_event_send(this->stream, &uevent); } static void update_title_info(bluray_input_plugin_t *this, int playlist_id) { /* update title_info */ pthread_mutex_lock(&this->title_info_mutex); if (this->title_info) bd_free_title_info(this->title_info); if (playlist_id < 0) this->title_info = bd_get_title_info(this->bdh, this->current_title_idx, 0); else this->title_info = bd_get_playlist_info(this->bdh, playlist_id, 0); pthread_mutex_unlock(&this->title_info_mutex); if (!this->title_info) { LOGMSG("bd_get_title_info(%d) failed\n", this->current_title_idx); return; } /* calculate and set stream rate */ uint64_t rate = bd_get_title_size(this->bdh) * UINT64_C(8) // bits * INT64_C(90000) / (uint64_t)(this->title_info->duration); _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, rate); /* set stream info */ if (this->nav_mode) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_TITLE_COUNT, this->num_titles); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_TITLE_NUMBER, this->current_title); } else { _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_TITLE_COUNT, this->num_title_idx); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_TITLE_NUMBER, this->current_title_idx + 1); } update_stream_info(this); /* set title name */ update_title_name(this); } /* * libbluray event handling */ static void fifos_wait(bluray_input_plugin_t *this) { if (!this->stream) return; if (this->stream->video_fifo) { buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo); if (buf) { buf->type = BUF_CONTROL_FLUSH_DECODER; this->stream->video_fifo->put(this->stream->video_fifo, buf); } } time_t start = time(NULL); while (1) { int vb = -1, ab = -1, vf = -1, af = -1; _x_query_buffer_usage(this->stream, &vb, &ab, &vf, &af); if (vb <= 0 && ab <= 0 && vf <= 0 && af <= 0) break; xine_usec_sleep(5000); if (time(NULL) > start + 10) { LOGMSG("fifos_wait timeout"); break; } } } static void stream_flush(bluray_input_plugin_t *this) { if (!this || this->stream_flushed || !this->stream) return; lprintf("Stream flush\n"); this->stream_flushed = 1; xine_event_t event = { .type = XINE_EVENT_END_OF_CLIP, .stream = this->stream, .data = NULL, .data_length = 0, }; xine_event_send (this->stream, &event); this->demux_action_req = 1; } static void stream_reset(bluray_input_plugin_t *this) { if (!this || this->stream_reset_done || !this->stream) return; lprintf("Stream reset\n"); xine_event_t event = { .type = XINE_EVENT_PIDS_CHANGE, .stream = this->stream, .data = NULL, .data_length = 0, }; if (!this->end_of_title) { _x_demux_flush_engine(this->stream); } xine_event_send (this->stream, &event); this->demux_action_req = 1; this->stream_reset_done = 1; } static void wait_secs(bluray_input_plugin_t *this, unsigned seconds) { stream_flush(this); if (this->still_end_time) { if (time(NULL) >= this->still_end_time) { lprintf("pause end\n"); this->still_end_time = 0; bd_read_skip_still(this->bdh); stream_reset(this); return; } } else if (seconds) { if (seconds > 300) { seconds = 300; } lprintf("still image, pause for %d seconds\n", seconds); this->still_end_time = time(NULL) + seconds; } xine_usec_sleep(40*1000); } static void update_spu_channel(bluray_input_plugin_t *this, int channel) { if (this->stream->video_fifo) { buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc(this->stream->video_fifo); buf->type = BUF_CONTROL_SPU_CHANNEL; buf->decoder_info[0] = channel; buf->decoder_info[1] = channel; buf->decoder_info[2] = channel; this->stream->video_fifo->put(this->stream->video_fifo, buf); } } static void update_audio_channel(bluray_input_plugin_t *this, int channel) { if (this->stream->audio_fifo) { buf_element_t *buf = this->stream->audio_fifo->buffer_pool_alloc(this->stream->audio_fifo); buf->type = BUF_CONTROL_AUDIO_CHANNEL; buf->decoder_info[0] = channel; this->stream->audio_fifo->put(this->stream->audio_fifo, buf); } } static void handle_libbluray_event(bluray_input_plugin_t *this, BD_EVENT ev) { switch ((bd_event_e)ev.event) { case BD_EVENT_NONE: break; case BD_EVENT_ERROR: lprintf("BD_EVENT_ERROR\n"); _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "Error playing BluRay disc", NULL); this->error = 1; return; case BD_EVENT_READ_ERROR: LOGMSG("BD_EVENT_READ_ERROR\n"); return; case BD_EVENT_ENCRYPTED: lprintf("BD_EVENT_ENCRYPTED\n"); _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "Media stream scrambled/encrypted", NULL); this->error = 1; return; /* sound effects */ #if BLURAY_VERSION >= 202 case BD_EVENT_SOUND_EFFECT: lprintf("BD_EVENT_SOUND_EFFECT %d\n", ev.param); break; #endif /* playback control */ case BD_EVENT_SEEK: lprintf("BD_EVENT_SEEK\n"); this->still_end_time = 0; stream_reset(this); break; case BD_EVENT_STILL_TIME: wait_secs(this, ev.param); break; case BD_EVENT_STILL: lprintf("BD_EVENT_STILL %d\n", ev.param); unsigned int paused = _x_get_fine_speed(this->stream) == XINE_SPEED_PAUSE; if (paused != ev.param) { _x_set_fine_speed(this->stream, ev.param ? XINE_SPEED_PAUSE : XINE_SPEED_NORMAL); } break; #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 3, 0) case BD_EVENT_IDLE: xine_usec_sleep(10000); break; #endif /* playback position */ case BD_EVENT_ANGLE: lprintf("BD_EVENT_ANGLE_NUMBER %d\n", ev.param); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_NUMBER, ev.param); break; case BD_EVENT_END_OF_TITLE: lprintf("BD_EVENT_END_OF_TITLE\n"); stream_flush(this); fifos_wait(this); this->end_of_title = 1; break; case BD_EVENT_TITLE: if (this->nav_mode) { lprintf("BD_EVENT_TITLE %d\n", ev.param); this->current_title = ev.param; } break; case BD_EVENT_PLAYLIST: lprintf("BD_EVENT_PLAYLIST %d\n", ev.param); if (!this->nav_mode) { this->current_title_idx = bd_get_current_title(this->bdh); } this->current_clip = 0; update_title_info(this, ev.param); stream_reset(this); this->end_of_title = 0; break; case BD_EVENT_PLAYITEM: lprintf("BD_EVENT_PLAYITEM %d\n", ev.param); this->current_clip = ev.param; this->still_end_time = 0; break; case BD_EVENT_CHAPTER: lprintf("BD_EVENT_CHAPTER %d\n", ev.param); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_NUMBER, ev.param); break; /* stream selection */ case BD_EVENT_AUDIO_STREAM: lprintf("BD_EVENT_AUDIO_STREAM %d\n", ev.param); if (ev.param < 32) { update_audio_channel(this, ev.param - 1); } else { update_audio_channel(this, 0); } break; case BD_EVENT_PG_TEXTST: lprintf("BD_EVENT_PG_TEXTST %s\n", ev.param ? "ON" : "OFF"); this->pg_enable = !!ev.param; update_spu_channel(this, this->pg_enable ? this->pg_stream : -1); break; case BD_EVENT_PG_TEXTST_STREAM: lprintf("BD_EVENT_PG_TEXTST_STREAM %d\n", ev.param); if (ev.param < 64) { this->pg_stream = ev.param - 1; } else { this->pg_stream = -1; } if (this->pg_enable) { update_spu_channel(this, this->pg_stream); } break; #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 2) case BD_EVENT_POPUP: lprintf("BD_EVENT_POPUP %d\n", ev.param); break; case BD_EVENT_MENU: this->menu_open = !!ev.param; send_num_buttons(this, ev.param); break; #endif default: lprintf("unhandled libbluray event %d [param %d]\n", ev.event, ev.param); break; } } static void handle_libbluray_events(bluray_input_plugin_t *this) { BD_EVENT ev; while (bd_get_event(this->bdh, &ev)) { handle_libbluray_event(this, ev); if (this->error || ev.event == BD_EVENT_NONE || ev.event == BD_EVENT_ERROR) break; } } /* * xine event handling */ static int open_title (bluray_input_plugin_t *this, int title_idx) { if (bd_select_title(this->bdh, title_idx) <= 0) { LOGMSG("bd_select_title(%d) failed\n", title_idx); return 0; } this->current_title_idx = title_idx; update_title_info(this, -1); #ifdef LOG int ms = this->title_info->duration / INT64_C(90); lprintf("Opened title %d. Length %"PRId64" bytes / %02d:%02d:%02d.%03d\n", this->current_title_idx, bd_get_title_size(this->bdh), ms / 3600000, (ms % 3600000 / 60000), (ms % 60000) / 1000, ms % 1000); #endif return 1; } static void send_mouse_enter_leave_event(bluray_input_plugin_t *this, int direction) { if (direction != this->mouse_inside_button) { xine_event_t event; xine_spu_button_t spu_event; spu_event.direction = direction; spu_event.button = 1; event.type = XINE_EVENT_SPU_BUTTON; event.stream = this->stream; event.data = &spu_event; event.data_length = sizeof(spu_event); xine_event_send(this->stream, &event); this->mouse_inside_button = direction; } } static void handle_events(bluray_input_plugin_t *this) { xine_event_t *event; if (!this->event_queue) return; while (NULL != (event = xine_event_get(this->event_queue))) { if (!this->bdh || !this->title_info) { xine_event_free(event); return; } int64_t pts = xine_get_current_vpts(this->stream) - this->stream->metronom->get_option(this->stream->metronom, METRONOM_VPTS_OFFSET); if (this->menu_open) { switch (event->type) { case XINE_EVENT_INPUT_LEFT: bd_user_input(this->bdh, pts, BD_VK_LEFT); break; case XINE_EVENT_INPUT_RIGHT: bd_user_input(this->bdh, pts, BD_VK_RIGHT); break; } } else { switch (event->type) { case XINE_EVENT_INPUT_LEFT: lprintf("XINE_EVENT_INPUT_LEFT: previous title\n"); if (!this->nav_mode) { open_title(this, MAX(0, this->current_title_idx - 1)); } else { bd_play_title(this->bdh, MAX(1, this->current_title - 1)); } stream_reset(this); break; case XINE_EVENT_INPUT_RIGHT: lprintf("XINE_EVENT_INPUT_RIGHT: next title\n"); if (!this->nav_mode) { open_title(this, MIN(this->num_title_idx - 1, this->current_title_idx + 1)); } else { bd_play_title(this->bdh, MIN(this->num_titles, this->current_title + 1)); } stream_reset(this); break; } } switch (event->type) { case XINE_EVENT_INPUT_MOUSE_BUTTON: { xine_input_data_t *input = event->data; lprintf("mouse click: button %d at (%d,%d)\n", input->button, input->x, input->y); if (input->button == 1) { bd_mouse_select(this->bdh, pts, input->x, input->y); bd_user_input(this->bdh, pts, BD_VK_MOUSE_ACTIVATE); send_mouse_enter_leave_event(this, 0); } break; } case XINE_EVENT_INPUT_MOUSE_MOVE: { xine_input_data_t *input = event->data; if (bd_mouse_select(this->bdh, pts, input->x, input->y) > 0) { send_mouse_enter_leave_event(this, 1); } else { send_mouse_enter_leave_event(this, 0); } break; } case XINE_EVENT_INPUT_MENU1: if (!this->disc_info->top_menu_supported) { _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "Can't open Top Menu", "Top Menu title not supported", NULL); } bd_menu_call(this->bdh, pts); break; case XINE_EVENT_INPUT_MENU2: bd_user_input(this->bdh, pts, BD_VK_POPUP); break; case XINE_EVENT_INPUT_UP: bd_user_input(this->bdh, pts, BD_VK_UP); break; case XINE_EVENT_INPUT_DOWN: bd_user_input(this->bdh, pts, BD_VK_DOWN); break; case XINE_EVENT_INPUT_SELECT: bd_user_input(this->bdh, pts, BD_VK_ENTER); break; case XINE_EVENT_INPUT_NUMBER_0: bd_user_input(this->bdh, pts, BD_VK_0); break; case XINE_EVENT_INPUT_NUMBER_1: bd_user_input(this->bdh, pts, BD_VK_1); break; case XINE_EVENT_INPUT_NUMBER_2: bd_user_input(this->bdh, pts, BD_VK_2); break; case XINE_EVENT_INPUT_NUMBER_3: bd_user_input(this->bdh, pts, BD_VK_3); break; case XINE_EVENT_INPUT_NUMBER_4: bd_user_input(this->bdh, pts, BD_VK_4); break; case XINE_EVENT_INPUT_NUMBER_5: bd_user_input(this->bdh, pts, BD_VK_5); break; case XINE_EVENT_INPUT_NUMBER_6: bd_user_input(this->bdh, pts, BD_VK_6); break; case XINE_EVENT_INPUT_NUMBER_7: bd_user_input(this->bdh, pts, BD_VK_7); break; case XINE_EVENT_INPUT_NUMBER_8: bd_user_input(this->bdh, pts, BD_VK_8); break; case XINE_EVENT_INPUT_NUMBER_9: bd_user_input(this->bdh, pts, BD_VK_9); break; case XINE_EVENT_INPUT_NEXT: { switch (this->class->skip_mode) { case 0: /* skip by chapter */ bd_seek_chapter(this->bdh, bd_get_current_chapter(this->bdh) + 1); update_stream_info(this); break; case 1: /* skip by title */ if (!this->nav_mode) { open_title(this, MIN(this->num_title_idx - 1, this->current_title_idx + 1)); } else { bd_play_title(this->bdh, MIN(this->num_titles, this->current_title + 1)); } break; } stream_reset(this); break; } case XINE_EVENT_INPUT_PREVIOUS: { switch (this->class->skip_mode) { case 0: /* skip by chapter */ bd_seek_chapter(this->bdh, MAX(0, ((int)bd_get_current_chapter(this->bdh)) - 1)); update_stream_info(this); break; case 1: /* skip by title */ if (!this->nav_mode) { open_title(this, MAX(0, this->current_title_idx - 1)); } else { bd_play_title(this->bdh, MAX(1, this->current_title - 1)); } break; } stream_reset(this); break; } case XINE_EVENT_INPUT_ANGLE_NEXT: { unsigned curr_angle = bd_get_current_angle(this->bdh); unsigned angle = MIN(8, curr_angle + 1); lprintf("XINE_EVENT_INPUT_ANGLE_NEXT: set angle %d --> %d\n", curr_angle, angle); bd_seamless_angle_change(this->bdh, angle); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_NUMBER, bd_get_current_angle(this->bdh)); break; } case XINE_EVENT_INPUT_ANGLE_PREVIOUS: { unsigned curr_angle = bd_get_current_angle(this->bdh); unsigned angle = curr_angle ? curr_angle - 1 : 0; lprintf("XINE_EVENT_INPUT_ANGLE_PREVIOUS: set angle %d --> %d\n", curr_angle, angle); bd_seamless_angle_change(this->bdh, angle); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_ANGLE_NUMBER, bd_get_current_angle(this->bdh)); break; } } xine_event_free(event); } } /* * xine plugin interface */ static uint32_t bluray_plugin_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_SEEKABLE | INPUT_CAP_TIME_SEEKABLE | INPUT_CAP_BLOCK | INPUT_CAP_AUDIOLANG | INPUT_CAP_SPULANG | INPUT_CAP_CHAPTERS; } #define CHECK_READ_INTERRUPT \ do { \ if (this->demux_action_req) { \ this->demux_action_req = 0; \ errno = EAGAIN; \ return -1; \ } \ if (_x_action_pending(this->stream)) { \ errno = EINTR; \ return -1; \ } \ } while (0) static off_t bluray_plugin_read (input_plugin_t *this_gen, void *buf, off_t len) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; off_t result; if (!this || !this->bdh || len < 0 || this->error) return -1; if (!this->has_video) { queue_black_frame(this); } handle_events(this); CHECK_READ_INTERRUPT; if (this->nav_mode) { do { BD_EVENT ev; result = bd_read_ext (this->bdh, (unsigned char *)buf, len, &ev); handle_libbluray_event(this, ev); CHECK_READ_INTERRUPT; if (result == 0) { handle_events(this); CHECK_READ_INTERRUPT; #if 0 if (ev.event == BD_EVENT_NONE) { if (_x_action_pending(this->stream)) { break; } } #endif } } while (!this->error && result == 0); } else { result = bd_read (this->bdh, (unsigned char *)buf, len); handle_libbluray_events(this); } if (result < 0) { LOGMSG("bd_read() failed: %s (%d of %d)\n", strerror(errno), (int)result, (int)len); } if (result > 0) { this->stream_flushed = 0; this->stream_reset_done = 0; } return result; } static buf_element_t *bluray_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { buf_element_t *buf; if (todo > ALIGNED_UNIT_SIZE) todo = ALIGNED_UNIT_SIZE; buf = fifo->buffer_pool_size_alloc (fifo, todo); if (todo > (off_t)buf->max_size) todo = buf->max_size; if (todo > 0) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; buf->size = bluray_plugin_read(this_gen, (char*)buf->mem, todo); buf->type = BUF_DEMUX_BLOCK; if (buf->size > 0) { buf->extra_info->total_time = this->title_info->duration / 90; return buf; } } buf->free_buffer (buf); return NULL; } static off_t bluray_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; if (!this || !this->bdh) return -1; if (this->still_end_time) return offset; /* convert relative seeks to absolute */ if (origin == SEEK_CUR) { offset = bd_tell(this->bdh) + offset; } else if (origin == SEEK_END) { if (offset < (off_t)bd_get_title_size(this->bdh)) offset = bd_get_title_size(this->bdh) - offset; else offset = 0; } lprintf("bluray_plugin_seek() seeking to %lld\n", (long long)offset); return bd_seek (this->bdh, offset); } static off_t bluray_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; if (!this || !this->bdh) return -1; if (this->still_end_time) return bd_tell(this->bdh); /* convert relative seeks to absolute */ if (origin == SEEK_CUR) { time_offset += this_gen->get_current_time(this_gen); } else if (origin == SEEK_END) { pthread_mutex_lock(&this->title_info_mutex); if (!this->title_info) { pthread_mutex_unlock(&this->title_info_mutex); return -1; } int duration = this->title_info->duration / 90; if (time_offset < duration) time_offset = duration - time_offset; else time_offset = 0; pthread_mutex_unlock(&this->title_info_mutex); } lprintf("bluray_plugin_seek_time() seeking to %d.%03ds\n", time_offset / 1000, time_offset % 1000); return bd_seek_time(this->bdh, time_offset * INT64_C(90)); } static off_t bluray_plugin_get_current_pos (input_plugin_t *this_gen) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; return this->bdh ? bd_tell(this->bdh) : 0; } static int bluray_plugin_get_current_time (input_plugin_t *this_gen) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; return this->bdh ? (int)(bd_tell_time(this->bdh) / UINT64_C(90)) : -1; } static off_t bluray_plugin_get_length (input_plugin_t *this_gen) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; return this->bdh ? (off_t)bd_get_title_size(this->bdh) : (off_t)-1; } static uint32_t bluray_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return ALIGNED_UNIT_SIZE; } static const char* bluray_plugin_get_mrl (input_plugin_t *this_gen) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; return this->mrl; } static int get_audio_lang (bluray_input_plugin_t *this, void *data) { /* * audio track language: * - channel number can be mpeg-ts PID (0x1100 ... 0x11ff) */ unsigned int current_clip = this->current_clip; /* can change any time */ if (this->title_info && current_clip < this->title_info->clip_count) { BLURAY_CLIP_INFO *clip = &this->title_info->clips[current_clip]; int channel; memcpy(&channel, data, sizeof(channel)); if (channel >= 0 && channel < clip->audio_stream_count) { memcpy(data, clip->audio_streams[channel].lang, 4); return INPUT_OPTIONAL_SUCCESS; } /* search by pid */ int i; for (i = 0; i < clip->audio_stream_count; i++) { if (channel == clip->audio_streams[i].pid) { memcpy(data, clip->audio_streams[i].lang, 4); return INPUT_OPTIONAL_SUCCESS; } } } return INPUT_OPTIONAL_UNSUPPORTED; } static int get_spu_lang (bluray_input_plugin_t *this, void *data) { /* * SPU track language: * - channel number can be mpeg-ts PID (0x1200 ... 0x12ff) */ unsigned int current_clip = this->current_clip; /* can change any time */ if (this->title_info && current_clip < this->title_info->clip_count) { BLURAY_CLIP_INFO *clip = &this->title_info->clips[current_clip]; int channel; memcpy(&channel, data, sizeof(channel)); if (channel >= 0 && channel < clip->pg_stream_count) { memcpy(data, clip->pg_streams[channel].lang, 4); return INPUT_OPTIONAL_SUCCESS; } /* search by pid */ int i; for (i = 0; i < clip->pg_stream_count; i++) { if (channel == clip->pg_streams[i].pid) { memcpy(data, clip->pg_streams[i].lang, 4); return INPUT_OPTIONAL_SUCCESS; } } } return INPUT_OPTIONAL_UNSUPPORTED; } static int get_optional_data_impl (bluray_input_plugin_t *this, void *data, int data_type) { int r; switch (data_type) { case INPUT_OPTIONAL_DATA_DEMUXER: if (data) *(const char **)data = "mpeg-ts"; return INPUT_OPTIONAL_SUCCESS; case INPUT_OPTIONAL_DATA_AUDIOLANG: r = get_audio_lang(this, data); return r; case INPUT_OPTIONAL_DATA_SPULANG: r = get_spu_lang(this, data); return r; case INPUT_OPTIONAL_DATA_DURATION: if (data && this->title_info) { uint32_t duration = (uint32_t)(this->title_info->duration / UINT64_C(90)); memcpy (data, &duration, sizeof (duration)); return INPUT_OPTIONAL_SUCCESS; } return INPUT_OPTIONAL_UNSUPPORTED; default: return INPUT_OPTIONAL_UNSUPPORTED; } return INPUT_OPTIONAL_UNSUPPORTED; } static int bluray_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; int r = INPUT_OPTIONAL_UNSUPPORTED; if (this && this->stream && data) { pthread_mutex_lock(&this->title_info_mutex); r = get_optional_data_impl(this, data, data_type); pthread_mutex_unlock(&this->title_info_mutex); } return r; } static void bluray_plugin_dispose (input_plugin_t *this_gen) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; if (this->bdh) { #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) bd_register_argb_overlay_proc(this->bdh, NULL, NULL, NULL); #endif bd_register_overlay_proc(this->bdh, NULL, NULL); } close_overlay(this, -1); if (this->event_queue) xine_event_dispose_queue(this->event_queue); pthread_mutex_lock(&this->title_info_mutex); if (this->title_info) bd_free_title_info(this->title_info); this->title_info = NULL; pthread_mutex_unlock(&this->title_info_mutex); pthread_mutex_destroy(&this->title_info_mutex); if (this->bdh) bd_close(this->bdh); #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) osd_buf_destroy(&this->osd_buf); #endif _x_freep (&this->mrl); _x_freep (&this->disc_root); _x_freep (&this->disc_name); free (this); } static int parse_mrl(const char *mrl_in, char **path, int *title, int *chapter) { int skip = 0; if (!strncasecmp(mrl_in, "bluray:", 7)) skip = 7; else if (!strncasecmp(mrl_in, "bd:", 3)) skip = 3; else return -1; char *mrl = strdup(mrl_in + skip); if (!mrl) return 0; /* title[.chapter] given ? parse and drop it */ if (title && mrl[0] && mrl[strlen(mrl)-1] != '/') { char *end = strrchr(mrl, '/'); int tail_len = 0; if (end && end[1]) { if (sscanf(end, "/%d.%d%n", title, chapter, &tail_len) < 1) *title = -1; else if (end[tail_len]) *title = -1; else *end = 0; } lprintf(" -> title %d, chapter %d, mrl \'%s\'\n", *title, *chapter, mrl); } if ((mrl[0] == 0) || !strcmp(mrl, "/") || !strcmp(mrl, "//") || !strcmp(mrl, "///")) { /* default device */ *path = NULL; } else if (*mrl == '/') { /* strip extra slashes */ char *start = mrl; while (start[0] == '/' && start[1] == '/') start++; *path = strdup(start); _x_mrl_unescape(*path); lprintf("non-defaut mount point \'%s\'\n", *path); } else { lprintf("invalid mrl \'%s\'\n", mrl_in); free(mrl); return 0; } free(mrl); return 1; } static int get_disc_info(bluray_input_plugin_t *this) { const BLURAY_DISC_INFO *disc_info; disc_info = bd_get_disc_info(this->bdh); if (!disc_info) { LOGMSG("bd_get_disc_info() failed\n"); return -1; } if (!disc_info->bluray_detected) { LOGMSG("bd_get_disc_info(): BluRay not detected\n"); this->nav_mode = 0; return 0; } if (disc_info->aacs_detected && !disc_info->aacs_handled) { if (!disc_info->libaacs_detected) _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "Media stream scrambled/encrypted with AACS", "libaacs not installed", NULL); else _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "Media stream scrambled/encrypted with AACS", NULL); return -1; } if (disc_info->bdplus_detected && !disc_info->bdplus_handled) { if (!disc_info->libbdplus_detected) _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "Media scrambled/encrypted with BD+", "libbdplus not installed.", NULL); else _x_message (this->stream, XINE_MSG_ENCRYPTED_SOURCE, "Media stream scrambled/encrypted with BD+", NULL); return -1; } if (this->nav_mode && !disc_info->first_play_supported) { _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "Can't play disc using menus", "First Play title not supported", NULL); this->nav_mode = 0; } if (this->nav_mode && disc_info->num_unsupported_titles > 0) { _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "Unsupported titles found", "Some titles can't be played in navigation mode", NULL); } if (this->nav_mode && disc_info->num_bdj_titles > 0) { if (!(this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_ARGB_LAYER_OVERLAY)) { _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "BD-J titles found. Current video driver does not support ARGB graphics.", "Try another video driver (ex. --video opengl2) or play this disc without menus.", NULL); } } this->num_titles = disc_info->num_hdmv_titles + disc_info->num_bdj_titles; this->disc_info = disc_info; return 1; } static char *get_disc_name(const char *path) { const char *name_start; char *file_name = NULL; int len; name_start = path + strlen(path) - 1; /* skip trailing '/' */ while (name_start > path && name_start[0] == '/') name_start--; /* find prev '/' */ while (name_start > path && name_start[-1] != '/') name_start--; file_name = strdup(name_start); len = strlen(file_name); /* trim trailing '/' */ while (len > 0 && file_name[len - 1] == '/') file_name[--len] = 0; /* trim trailing ".iso" */ if (len > 3 && !strcasecmp(file_name + len - 4, ".iso")) file_name[len - 4] = 0; /* '_' --> ' ' */ for (len = 0; file_name[len]; ++len) if (file_name[len] == '_') file_name[len] = ' '; lprintf("disc name: %s\n", file_name); return file_name; } static int is_iso_image(const char *mrl) { if (mrl) { const char *pos = strrchr(mrl, '.'); return pos && !strcasecmp(pos + 1, "iso"); } return 0; } static int bluray_plugin_open (input_plugin_t *this_gen) { bluray_input_plugin_t *this = (bluray_input_plugin_t *) this_gen; int title = -1; int chapter = 0; int major, minor, micro; lprintf("bluray_plugin_open '%s'\n",this->mrl); /* validate and parse mrl */ if (!parse_mrl(this->mrl, &this->disc_root, &title, &chapter)) return -1; if (!strncasecmp(this->mrl, "bd:", 3)) this->nav_mode = 1; if (!this->disc_root) this->disc_root = strdup(this->class->mountpoint); bd_get_version(&major, &minor, µ); if (BLURAY_VERSION_CODE(major, minor, micro) < BLURAY_VERSION_CODE(0, 8, 0)) { if (is_iso_image(this->disc_root)) { _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "Can't play BluRay .iso image. Update libbluray.", "", NULL); return -1; } } /* open libbluray */ if (! (this->bdh = bd_open (this->disc_root, NULL))) { LOGMSG("bd_open(\'%s\') failed: %s\n", this->disc_root, strerror(errno)); return -1; } lprintf("bd_open(\'%s\') OK\n", this->disc_root); if (get_disc_info(this) < 0) { return -1; } /* load title list */ if (!this->nav_mode) { this->num_title_idx = bd_get_titles(this->bdh, TITLES_RELEVANT, MIN_TITLE_LENGTH); LOGMSG("%d titles\n", this->num_title_idx); if (this->num_title_idx < 1) return -1; /* if title was not in mrl, guess the main title */ #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 5, 0) if (title < 0) { title = bd_get_main_title(this->bdh); LOGMSG("main title: %d\n", title); } #endif if (title < 0) { uint64_t duration = 0; int i, playlist = 99999; for (i = 0; i < this->num_title_idx; i++) { BLURAY_TITLE_INFO *info = bd_get_title_info(this->bdh, i, 0); if (info->duration > duration) { title = i; duration = info->duration; playlist = info->playlist; } bd_free_title_info(info); } LOGMSG("main title: %d (%05d.mpls)\n", title, playlist); } } else { LOGMSG("%d titles\n", this->num_titles); } /* update player settings */ bd_set_player_setting (this->bdh, BLURAY_PLAYER_SETTING_REGION_CODE, this->class->region); bd_set_player_setting (this->bdh, BLURAY_PLAYER_SETTING_PARENTAL, this->class->parental); bd_set_player_setting_str(this->bdh, BLURAY_PLAYER_SETTING_AUDIO_LANG, this->class->language); bd_set_player_setting_str(this->bdh, BLURAY_PLAYER_SETTING_PG_LANG, this->class->language); bd_set_player_setting_str(this->bdh, BLURAY_PLAYER_SETTING_MENU_LANG, this->class->language); bd_set_player_setting_str(this->bdh, BLURAY_PLAYER_SETTING_COUNTRY_CODE, this->class->country); /* init event queue */ bd_get_event(this->bdh, NULL); /* get disc name */ this->meta_dl = bd_get_meta(this->bdh); if (this->meta_dl && this->meta_dl->di_name && strlen(this->meta_dl->di_name) > 1) { this->disc_name = strdup(this->meta_dl->di_name); } else if (strcmp(this->disc_root, this->class->mountpoint)) { this->disc_name = get_disc_name(this->disc_root); } /* register overlay (graphics) handler */ #if BLURAY_VERSION >= BLURAY_VERSION_CODE(0, 2, 4) if (this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_ARGB_LAYER_OVERLAY) { osd_buf_init(&this->osd_buf); bd_register_argb_overlay_proc(this->bdh, this, argb_overlay_proc, &this->osd_buf.buf); } #endif bd_register_overlay_proc(this->bdh, this, overlay_proc); /* open */ this->current_title = -1; this->current_title_idx = -1; if (this->nav_mode) { if (bd_play(this->bdh) <= 0) { LOGMSG("bd_play() failed\n"); return -1; } } else { if (open_title(this, title) <= 0 && open_title(this, 0) <= 0) return -1; } /* jump to chapter */ if (chapter > 0) { chapter = MAX(0, MIN((int)this->title_info->chapter_count, chapter) - 1); bd_seek_chapter(this->bdh, chapter); _x_stream_info_set(this->stream, XINE_STREAM_INFO_DVD_CHAPTER_NUMBER, chapter + 1); } return 1; } static input_plugin_t *bluray_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { bluray_input_plugin_t *this; if (strncasecmp(mrl, "bluray:", 7) && strncasecmp(mrl, "bd:", 3)) return NULL; this = calloc(1, sizeof (bluray_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->class = (bluray_input_class_t*)cls_gen; this->mrl = strdup(mrl); if (!this->mrl) { free(this); return NULL; } this->input_plugin.open = bluray_plugin_open; this->input_plugin.get_capabilities = bluray_plugin_get_capabilities; this->input_plugin.read = bluray_plugin_read; this->input_plugin.read_block = bluray_plugin_read_block; this->input_plugin.seek = bluray_plugin_seek; this->input_plugin.seek_time = bluray_plugin_seek_time; this->input_plugin.get_current_pos = bluray_plugin_get_current_pos; this->input_plugin.get_current_time = bluray_plugin_get_current_time; this->input_plugin.get_length = bluray_plugin_get_length; this->input_plugin.get_blocksize = bluray_plugin_get_blocksize; this->input_plugin.get_mrl = bluray_plugin_get_mrl; this->input_plugin.get_optional_data = bluray_plugin_get_optional_data; this->input_plugin.dispose = bluray_plugin_dispose; this->input_plugin.input_class = cls_gen; this->event_queue = xine_event_new_queue (this->stream); pthread_mutex_init(&this->title_info_mutex, NULL); this->pg_stream = -1; return &this->input_plugin; } /* * plugin class */ static void mountpoint_change_cb(void *data, xine_cfg_entry_t *cfg) { bluray_input_class_t *class = (bluray_input_class_t *) data; class->mountpoint = cfg->str_value; } static void device_change_cb(void *data, xine_cfg_entry_t *cfg) { bluray_input_class_t *class = (bluray_input_class_t *) data; class->device = cfg->str_value; } static void language_change_cb(void *data, xine_cfg_entry_t *cfg) { bluray_input_class_t *class = (bluray_input_class_t *) data; class->language = cfg->str_value; } static void country_change_cb(void *data, xine_cfg_entry_t *cfg) { bluray_input_class_t *class = (bluray_input_class_t *) data; class->country = cfg->str_value; } static void region_change_cb(void *data, xine_cfg_entry_t *cfg) { bluray_input_class_t *class = (bluray_input_class_t *) data; class->region = cfg->num_value; } static void parental_change_cb(void *data, xine_cfg_entry_t *cfg) { bluray_input_class_t *class = (bluray_input_class_t *) data; class->parental = cfg->num_value; } static void skip_mode_change_cb (void *data, xine_cfg_entry_t *cfg) { bluray_input_class_t *class = (bluray_input_class_t *) data; class->skip_mode = cfg->num_value; } static const char * const *bluray_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { static const char * const autoplay_list[] = { "bluray:/", NULL }; (void)this_gen; *num_files = 1; return autoplay_list; } static xine_mrl_t **bluray_class_get_dir(input_class_t *this_gen, const char *filename, int *nFiles) { bluray_input_class_t *this = (bluray_input_class_t*) this_gen; char *path = NULL; int title = -1, chapter = -1, i, num_pl; BLURAY *bdh; lprintf("bluray_class_get_dir(%s)\n", filename); _x_input_free_mrls(&this->xine_playlist); *nFiles = 0; if (filename) parse_mrl(filename, &path, &title, &chapter); bdh = bd_open(path ? path : this->mountpoint, NULL); if (!bdh) goto out; num_pl = bd_get_titles(bdh, TITLES_RELEVANT, MIN_TITLE_LENGTH); if (num_pl < 1) goto out; this->xine_playlist = _x_input_alloc_mrls(num_pl); if (!this->xine_playlist) goto out; for (i = 0; i < num_pl; i++) { this->xine_playlist[i]->origin = _x_asprintf("bluray:/%s", path ? path : ""); this->xine_playlist[i]->mrl = _x_asprintf("bluray:/%s/%d", path ? path : "", i); this->xine_playlist[i]->type = mrl_dvd; } *nFiles = num_pl; out: if (bdh) bd_close(bdh); free(path); return this->xine_playlist; } static int bluray_class_eject_media (input_class_t *this_gen) { bluray_input_class_t *this = (bluray_input_class_t*) this_gen; return media_eject_media (this->xine, this->device); } static void bluray_class_dispose (input_class_t *this_gen) { bluray_input_class_t *this = (bluray_input_class_t *) this_gen; config_values_t *config = this->xine->config; _x_input_free_mrls(&this->xine_playlist); config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free (this); } static void *bluray_init_plugin (xine_t *xine, const void *data) { static const char * const skip_modes[] = {"skip chapter", "skip title", NULL}; config_values_t *config = xine->config; bluray_input_class_t *this = (bluray_input_class_t *) calloc(1, sizeof (bluray_input_class_t)); if (!this) return NULL; (void)data; this->xine = xine; this->input_class.get_instance = bluray_class_get_instance; this->input_class.get_dir = bluray_class_get_dir; this->input_class.get_autoplay_list = bluray_class_get_autoplay_list; this->input_class.dispose = bluray_class_dispose; this->input_class.eject_media = bluray_class_eject_media; this->input_class.identifier = "bluray"; this->input_class.description = _("BluRay input plugin"); this->mountpoint = config->register_filename (config, "media.bluray.mountpoint", BLURAY_MNT_PATH, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("BluRay mount point"), _("Default mount location for BluRay discs."), 0, mountpoint_change_cb, (void *) this); this->device = config->register_filename (config, "media.bluray.device", BLURAY_PATH, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for BluRay playback"), _("The path to the device which you intend to use for playing BluRay discs."), 0, device_change_cb, (void *) this); /* Player settings */ this->language = config->register_string (config, "media.bluray.language", "eng", _("default language for BluRay playback"), _("xine tries to use this language as a default for BluRay playback. " "As far as the BluRay supports it, menus and audio tracks will be presented in this language.\n" "The value must be a three characterISO639-2 language code."), 0, language_change_cb, this); this->country = config->register_string (config, "media.bluray.country", "en", _("BluRay player country code"), _("The value must be a two character ISO3166-1 country code."), 0, country_change_cb, this); this->region = config->register_num (config, "media.bluray.region", 7, _("BluRay player region code (1=A, 2=B, 4=C)"), _("This only needs to be changed if your BluRay jumps to a screen " "complaining about a wrong region code. It has nothing to do with " "the region code set in BluRay drives, this is purely software."), 0, region_change_cb, this); this->parental = config->register_num (config, "media.bluray.parental", 99, _("parental control age limit (1-99)"), _("Prevents playback of BluRay titles where parental control age limit " "is higher than this limit"), 0, parental_change_cb, this); this->skip_mode = config->register_enum (config, "media.bluray.skip_behaviour", 0, (char **)skip_modes, _("unit for the skip action"), _("You can configure the behaviour when issuing a skip command (using the skip " "buttons for example)."), 20, skip_mode_change_cb, this); return this; } static const char * const *bd_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { static const char * const autoplay_list[] = { "bd:/", NULL }; (void)this_gen; *num_files = 1; return autoplay_list; } static void *bd_init_plugin (xine_t *xine, const void *data) { bluray_input_class_t *this = bluray_init_plugin(xine, data); if (this) { this->input_class.identifier = "bluray"; this->input_class.description = _("BluRay input plugin (using menus)"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = bd_class_get_autoplay_list; } return this; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 18, "BLURAY", XINE_VERSION_CODE, NULL, bluray_init_plugin }, { PLUGIN_INPUT, 18, "BD", XINE_VERSION_CODE, NULL, bd_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/mms.h������������������������������������������������������������������������0000644�0001750�0001750�00000002644�14647725152�013565� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * libmms public header */ #ifndef HAVE_MMS_H #define HAVE_MMS_H #include <inttypes.h> #include <xine/xine_internal.h> typedef struct mms_s mms_t; char* mms_connect_common(int *s ,int *port, char *url, char **host, char **path, char **file); mms_t* mms_connect (xine_stream_t *stream, const char *url_, int bandwidth); int mms_read (mms_t *this, char *data, int len); uint32_t mms_get_length (mms_t *this); void mms_close (mms_t *this); size_t mms_peek_header (mms_t *this, char *data, size_t maxsize); off_t mms_get_current_pos (mms_t *this); void mms_set_start_time (mms_t *this, int time_offset); #endif ��������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_net.c������������������������������������������������������������������0000644�0001750�0001750�00000022344�14647725152�014770� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Read from a tcp network stream over a lan (put a tweaked mp1e encoder the * other end and you can watch tv anywhere in the house ..) * * how to set up mp1e for use with this plugin: * * use mp1 to capture the live stream, e.g. * mp1e -b 1200 -R 4,32 -a 0 -B 160 -v >live.mpg * * add an extra service "xine" to /etc/services and /etc/inetd.conf, e.g.: * /etc/services: * xine 1025/tcp * /etc/inetd.conf: * xine stream tcp nowait bartscgr /usr/sbin/tcpd /usr/bin/tail -f /home/bartscgr/Projects/inf.misc/live.mpg * * now restart inetd and you can use xine to watch the live stream, e.g.: * xine tcp://192.168.0.43:1025.mpg */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #define LOG_MODULE "input_net" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "tls/xine_tls.h" #include "net_buf_ctrl.h" #include "group_network.h" #include "input_helper.h" #include "http_helper.h" #define NET_BS_LEN 2324 typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; xine_tls_t *tls; char *mrl; off_t curpos; nbc_t *nbc; off_t preview_size; char preview[MAX_PREVIEW_SIZE]; } net_input_plugin_t; /* **************************************************************** */ /* Private functions */ /* **************************************************************** */ static off_t net_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; off_t n, total; lprintf("reading %" PRIdMAX " bytes...\n", (intmax_t)len); if (len < 0) return -1; total=0; if (this->curpos < this->preview_size) { n = this->preview_size - this->curpos; if (n > (len - total)) n = len - total; lprintf("%" PRIdMAX " bytes from preview (which has %" PRIdMAX " bytes)\n", (intmax_t)n, (intmax_t)this->preview_size); memcpy (&buf[total], &this->preview[this->curpos], n); this->curpos += n; total += n; } if( (len-total) > 0 ) { n = _x_tls_read (this->tls, &buf[total], len-total); xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_net: got %" PRIdMAX " bytes (%" PRIdMAX "/%" PRIdMAX " bytes read)\n", (intmax_t)n, (intmax_t)total, (intmax_t)len); if (n < 0) { _x_message(this->stream, XINE_MSG_READ_ERROR, this->mrl, NULL); return 0; } this->curpos += n; total += n; } return total; } static uint32_t net_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return NET_BS_LEN; } static off_t net_plugin_get_current_pos (input_plugin_t *this_gen){ net_input_plugin_t *this = (net_input_plugin_t *) this_gen; return this->curpos; } static off_t net_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; return _x_input_seek_preview(this_gen, offset, origin, &this->curpos, -1, this->preview_size); } static const char* net_plugin_get_mrl (input_plugin_t *this_gen) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; return this->mrl; } static int net_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: memcpy (data, this->preview, this->preview_size); return this->preview_size; break; } return INPUT_OPTIONAL_UNSUPPORTED; } static void net_plugin_dispose (input_plugin_t *this_gen ) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; _x_tls_close (&this->tls); _x_freep (&this->mrl); if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } free (this_gen); } static int net_plugin_open (input_plugin_t *this_gen ) { net_input_plugin_t *this = (net_input_plugin_t *) this_gen; xine_url_t url; int gopher = !strncasecmp(this->mrl, "gopher", 6); int toread = MAX_PREVIEW_SIZE; int trycount = 0; _x_url_init (&url); if (!_x_url_parse2 (this->mrl, &url)) goto fail; if (!url.host) goto fail; url.port = url.port ? url.port : (gopher ? 70 : 7658); this->curpos = 0; this->tls = _x_tls_connect(this->stream->xine, this->stream, url.host, url.port); if (!this->tls) goto fail; if (!strncasecmp(this->mrl, "tls", 3)) { if (_x_tls_handshake(this->tls, url.host, -1) < 0) goto fail; } if (gopher) { if (url.path) { ssize_t len = strlen(url.path); if (len != _x_tls_write (this->tls, url.path, len)) goto fail; } if (2 != _x_tls_write (this->tls, "\r\n", 2)) goto fail; } _x_url_cleanup (&url); /* * fill preview buffer */ while ((toread > 0) && (trycount < 10)) { int got = _x_tls_read (this->tls, this->preview + this->preview_size, toread); if (got < 0) break; this->preview_size += got; trycount++; toread = MAX_PREVIEW_SIZE - this->preview_size; } this->curpos = 0; return 1; fail: _x_url_cleanup (&url); return 0; } static input_plugin_t *net_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { /* net_input_plugin_t *this = (net_input_plugin_t *) this_gen; */ net_input_plugin_t *this; nbc_t *nbc = NULL; const char *filename; if (!strncasecmp (mrl, "tcp://", 6) || !strncasecmp (mrl, "gopher://", 9) || !strncasecmp (mrl, "tls://", 6)) { nbc = nbc_init (stream); } else if (!strncasecmp (mrl, "slave://", 8)) { /* the only difference for slave:// is that network buffering control * is not used. otherwise, dvd still menus are not displayed (it freezes * with "buffering..." all the time) */ } else { return NULL; } filename = strchr(mrl, '/') + 2; if (!filename[0]) { return NULL; } this = calloc(1, sizeof(net_input_plugin_t)); if (!this) return NULL; this->mrl = strdup(mrl); this->stream = stream; this->tls = NULL; this->curpos = 0; this->nbc = nbc; this->preview_size = 0; if (!this->mrl) { free(this); return NULL; } this->input_plugin.open = net_plugin_open; this->input_plugin.get_capabilities = _x_input_get_capabilities_preview; this->input_plugin.read = net_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = net_plugin_seek; this->input_plugin.get_current_pos = net_plugin_get_current_pos; this->input_plugin.get_length = _x_input_default_get_length; this->input_plugin.get_blocksize = net_plugin_get_blocksize; this->input_plugin.get_mrl = net_plugin_get_mrl; this->input_plugin.get_optional_data = net_plugin_get_optional_data; this->input_plugin.dispose = net_plugin_dispose; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * net plugin class */ void *input_net_init_class (xine_t *xine, const void *data) { static const input_class_t input_net_class = { .get_instance = net_class_get_instance, .description = N_("net input plugin as shipped with xine"), .identifier = "TCP", .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)xine; (void)data; return (void *)&input_net_class; } void *input_tls_init_class (xine_t *xine, const void *data) { static const input_class_t input_tls_class = { .get_instance = net_class_get_instance, .description = N_("tls input plugin"), .identifier = "TLS", .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)xine; (void)data; return (void *)&input_tls_class; } void *input_gopher_init_class (xine_t *xine, const void *data) { static const input_class_t input_gopher_class = { .get_instance = net_class_get_instance, .description = N_("gopher input plugin"), .identifier = "gopher", .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)xine; (void)data; return (void *)&input_gopher_class; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/tls/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013414� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/tls/xine_tls_plugin.h��������������������������������������������������������0000644�0001750�0001750�00000004501�14647725152�016770� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * Copyright (C) 2019 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine TLS provider plugin interface */ #ifndef _XINE_TLS_PLUGIN_H_ #define _XINE_TLS_PLUGIN_H_ #include <sys/types.h> #include <xine/xine_module.h> #define TLS_PLUGIN_TYPE "tls_v1" typedef struct { xine_t *xine; xine_stream_t *stream; int fd; } tls_plugin_params_t; typedef struct tls_plugin_s tls_plugin_t; struct tls_plugin_s { xine_module_t module; int (*handshake)(tls_plugin_t *, const char *host, int verify); void (*shutdown)(tls_plugin_t *); ssize_t (*read)(tls_plugin_t *, void *buf, size_t len); ssize_t (*write)(tls_plugin_t *, const void *buf, size_t len); ssize_t (*part_read)(tls_plugin_t *, void *buf, size_t min, size_t max); }; /* * config helpers */ #include <xine/configfile.h> #define TLS_VERIFY_CERT_KEY "media.network.verify_tls_certificate" static inline void tls_register_config_keys(config_values_t *config) { config->register_bool(config, TLS_VERIFY_CERT_KEY, 1, _("Verify server TLS certificate"), _("If enabled, server TLS certificate is always checked. " "If check fails, connections to server are not allowed."), 10, NULL, NULL); } static inline int tls_get_verify_tls_cert(config_values_t *config) { cfg_entry_t *entry; entry = config->lookup_entry(config, TLS_VERIFY_CERT_KEY); if (entry) { return entry->num_value; } return 1; } #endif /* _XINE_TLS_PLUGIN_H_ */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/tls/xine_tls.h���������������������������������������������������������������0000644�0001750�0001750�00000005165�14647725152�015421� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * input plugin TLS helpers */ #ifndef XINE_INPUT_TLS_H #define XINE_INPUT_TLS_H /* * xine_tls layer is a simple wrapper for _x_io_tcp_*() functions. * _x_io_*() functions can be simply replaced with _x_tls_*() functions. * * Connection is unencrypted until _x_tls_handshake() is called. * Unencrypted TCP connection can be used even if TLS support was not compiled in. */ #include <xine/xine_internal.h> typedef struct xine_tls xine_tls_t; /* * TCP connection */ int _x_tls_available(xine_t *xine); /* open/close by host and port. */ xine_tls_t *_x_tls_connect(xine_t *xine, xine_stream_t *stream, const char *host, int port); /* also close fd. */ void _x_tls_close (xine_tls_t **tlsp); /* same thing on an existing user file handle. * This is useful when doing _x_io_tcp_handshake_connect () and/or SOCKS4. */ xine_tls_t *_x_tls_init (xine_t *xine, xine_stream_t *stream, int fd); /* do NOT close fd. */ void _x_tls_deinit (xine_tls_t **tlsp); ssize_t _x_tls_part_read(xine_tls_t *, void *data, size_t min, size_t max); ssize_t _x_tls_read(xine_tls_t *, void *data, size_t len); ssize_t _x_tls_write(xine_tls_t *, const void *data, size_t len); ssize_t _x_tls_read_line(xine_tls_t *, char *buf, size_t buf_size); /* * TLS */ /** * Initialize TLS * * @param host Host name to check certificate against (may be NULL ex. if numeric address). * @param verify verify certificate. 0 - no, 1 - yes, < 0 - fetch value from xine config. * @return < 0 on error. */ int _x_tls_handshake(xine_tls_t *, const char *host, int verify); /** * Shutdown TLS (stop encryption). * * Underlying socket remains open. */ void _x_tls_shutdown(xine_tls_t *); /* * config helpers */ int _x_tls_get_verify_tls_cert(config_values_t *); #endif /* XINE_INPUT_TLS_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/tls/xine_tls.c���������������������������������������������������������������0000644�0001750�0001750�00000011557�14647725152�015416� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "input_tls" #include "xine_tls.h" #include <stdlib.h> #include <errno.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/io_helper.h> #include "xine_tls_plugin.h" struct xine_tls { xine_t *xine; xine_stream_t *stream; tls_plugin_t *tls; int fd; int enabled; }; /* * loader wrappers */ static inline tls_plugin_t *_x_find_tls_plugin(xine_t *xine, tls_plugin_params_t *params) { return (tls_plugin_t *)_x_find_module(xine, "tls_v1", NULL, 0, params); } static inline void _x_free_tls_plugin(xine_t *xine, tls_plugin_t **tls) { xine_module_t **m = (xine_module_t **)tls; _x_free_module(xine, m); } /* * */ ssize_t _x_tls_write(xine_tls_t *t, const void *buf, size_t len) { if (t->tls && t->enabled) return t->tls->write(t->tls, buf, len); return _x_io_tcp_write(t->stream, t->fd, buf, len); } ssize_t _x_tls_part_read(xine_tls_t *t, void *buf, size_t min, size_t max) { if (t->tls && t->enabled) return t->tls->part_read(t->tls, buf, min, max); return _x_io_tcp_part_read(t->stream, t->fd, buf, min, max); } ssize_t _x_tls_read(xine_tls_t *t, void *buf, size_t len) { if (t->tls && t->enabled) return t->tls->read(t->tls, buf, len); return _x_io_tcp_read(t->stream, t->fd, buf, len); } ssize_t _x_tls_read_line(xine_tls_t *t, char *buf, size_t buf_size) { if (t->enabled) { unsigned int i = 0; ssize_t r; char c; if (buf_size <= 0) return 0; while ((r = _x_tls_read(t, &c, 1)) == 1) { if (c == '\r' || c == '\n') break; if (i+1 == buf_size) break; buf[i] = c; i++; } if (r == 1 && c == '\r') r = _x_tls_read(t, &c, 1); buf[i] = '\0'; return (r >= 0) ? (ssize_t)i : r; } return _x_io_tcp_read_line(t->stream, t->fd, buf, buf_size); } /* * open / close */ void _x_tls_shutdown(xine_tls_t *t) { if (!t->enabled) return; t->enabled = 0; if (t->tls) t->tls->shutdown(t->tls); } void _x_tls_close (xine_tls_t **pt) { xine_tls_t *tls = *pt; if (!tls) return; _x_tls_shutdown (tls); if (tls->tls) _x_free_tls_plugin (tls->xine, &tls->tls); if (tls->fd >= 0) { _x_io_tcp_close (tls->stream, tls->fd); tls->fd = -1; } _x_freep (pt); } void _x_tls_deinit (xine_tls_t **pt) { xine_tls_t *tls = *pt; if (!tls) return; _x_tls_shutdown (tls); if (tls->tls) _x_free_tls_plugin (tls->xine, &tls->tls); tls->fd = -1; _x_freep (pt); } xine_tls_t *_x_tls_init (xine_t *xine, xine_stream_t *stream, int fd) { xine_tls_t *tls; if (fd < 0) return NULL; tls = calloc (1, sizeof (*tls)); if (!tls) return NULL; tls->stream = stream; tls->xine = xine; tls->fd = fd; return tls; } xine_tls_t *_x_tls_connect (xine_t *xine, xine_stream_t *stream, const char *host, int port) { xine_tls_t *tls; int fh; fh = _x_io_tcp_connect (stream, host, port); if (fh < 0) return NULL; tls = calloc (1, sizeof (*tls)); if (!tls) { _x_io_tcp_close (stream, fh); return NULL; } tls->stream = stream; tls->xine = xine; tls->fd = fh; return tls; } int _x_tls_handshake(xine_tls_t *t, const char *host, int verify) { int ret; if (!t->tls) { tls_plugin_params_t params = { .xine = t->xine, .stream = t->stream, .fd = t->fd, }; t->tls = _x_find_tls_plugin(t->xine, ¶ms); if (!t->tls) { xprintf(t->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "TLS plugin not found\n"); return -1; } } ret = t->tls->handshake(t->tls, host, verify); if (ret < 0) return ret; t->enabled = 1; return 0; } int _x_tls_get_verify_tls_cert(config_values_t *config) { return tls_get_verify_tls_cert(config); } int _x_tls_available(xine_t *xine) { tls_plugin_params_t p = { .xine = xine, .fd = -1, }; tls_plugin_t *tls = _x_find_tls_plugin(xine, &p); if (!tls) return 0; _x_free_tls_plugin(xine, &tls); return 1; } �������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/tls/tls_openssl.c������������������������������������������������������������0000644�0001750�0001750�00000021554�14647725152�016134� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ /* * xine TLS provider plugin (using openssl) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <pthread.h> #include <openssl/bio.h> #include <openssl/ssl.h> #include <openssl/err.h> #define LOG_MODULE "openssl" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/io_helper.h> #include <xine/xine_plugin.h> #include "xine_tls_plugin.h" typedef struct { tls_plugin_t tls_plugin; xine_stream_t *stream; xine_t *xine; int fd; SSL_CTX *ctx; SSL *ssl; #if OPENSSL_VERSION_NUMBER >= 0x1010000fL BIO_METHOD *bio_method; #endif } tls_openssl_t; typedef struct { xine_module_class_t module_class; pthread_mutex_t lock; int inited; } openssl_class_t; /* * openssl I/O callbacks */ static int _bio_read(BIO *b, char *buf, int len) { #if OPENSSL_VERSION_NUMBER >= 0x1010000fL tls_openssl_t *this = BIO_get_data(b); #else tls_openssl_t *this = b->ptr; #endif return _x_io_tcp_read(this->stream, this->fd, buf, len); } static int _bio_write(BIO *b, const char *buf, int len) { #if OPENSSL_VERSION_NUMBER >= 0x1010000fL tls_openssl_t *this = BIO_get_data(b); #else tls_openssl_t *this = b->ptr; #endif return _x_io_tcp_write(this->stream, this->fd, buf, len); } static int _bio_puts(BIO *b, const char *str) { return _bio_write(b, str, strlen(str)); } static long _bio_ctrl(BIO *b, int cmd, long num, void *ptr) { (void)b; (void)num; (void)ptr; if (cmd == BIO_CTRL_FLUSH) return 1; return 0; } static int _bio_create(BIO *b) { #if OPENSSL_VERSION_NUMBER >= 0x1010000fL BIO_set_init(b, 1); BIO_set_app_data(b, NULL); BIO_set_flags(b, 0); #else b->init = 1; b->ptr = NULL; b->flags = 0; #endif return 1; } static int _bio_destroy(BIO *b) { (void)b; return 1; } static BIO *_bio_new(tls_openssl_t *this) { BIO *b; #if OPENSSL_VERSION_NUMBER < 0x1010000fL static BIO_METHOD bio_method = { .type = BIO_TYPE_SOURCE_SINK, .name = "xine bio", .bwrite = _bio_write, .bread = _bio_read, .bputs = _bio_puts, .bgets = NULL, .ctrl = _bio_ctrl, .create = _bio_create, .destroy = _bio_destroy, }; b = BIO_new(&bio_method); b->ptr = this; #else _x_assert(this->bio_method == NULL); this->bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK, "xine bio"); BIO_meth_set_write (this->bio_method, _bio_write); BIO_meth_set_read (this->bio_method, _bio_read); BIO_meth_set_puts (this->bio_method, _bio_puts); BIO_meth_set_ctrl (this->bio_method, _bio_ctrl); BIO_meth_set_create (this->bio_method, _bio_create); BIO_meth_set_destroy(this->bio_method, _bio_destroy); b = BIO_new(this->bio_method); BIO_set_data(b, this); #endif return b; } /* * xine TLS API */ static ssize_t _openssl_write(tls_plugin_t *this_gen, const void *buf, size_t len) { tls_openssl_t *this = (tls_openssl_t *)this_gen; int ret; if (!this->ssl) return -1; ret = SSL_write(this->ssl, buf, len); if (ret < 0) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "OpenSSL write failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); return ret; } static ssize_t _openssl_read(tls_plugin_t *this_gen, void *buf, size_t len) { tls_openssl_t *this = (tls_openssl_t *)this_gen; int ret; if (!this->ssl) return -1; ret = SSL_read(this->ssl, buf, len); if (ret < 0) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "OpenSSL read failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); return ret; } static ssize_t _openssl_part_read(tls_plugin_t *this_gen, void *buf, size_t min, size_t max) { tls_openssl_t *this = (tls_openssl_t *)this_gen; int ret; (void)min; if (!this->ssl) return -1; ret = SSL_read(this->ssl, buf, max); if (ret < 0) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "OpenSSL read failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); return ret; } static void _openssl_shutdown(tls_plugin_t *this_gen) { tls_openssl_t *this = (tls_openssl_t *)this_gen; if (this->ssl) { SSL_shutdown(this->ssl); SSL_free(this->ssl); this->ssl = NULL; } if (this->ctx) { SSL_CTX_free(this->ctx); this->ctx = NULL; } #if OPENSSL_VERSION_NUMBER >= 0x1010000fL if (this->bio_method) { BIO_meth_free(this->bio_method); this->bio_method = NULL; } #endif } static int _openssl_handshake(tls_plugin_t *this_gen, const char *host, int verify) { tls_openssl_t *this = (tls_openssl_t *)this_gen; BIO *bio; int ret; _x_assert(this->ssl == NULL); this->ctx = SSL_CTX_new(SSLv23_client_method()); if (!this->ctx) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "SSL context init failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); return -1; } /* disable deprecated and insecure SSLv2 and SSLv3 */ SSL_CTX_set_options(this->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); if (verify < 0 && this->xine) verify = tls_get_verify_tls_cert(this->xine->config); if (verify) SSL_CTX_set_verify(this->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); this->ssl = SSL_new(this->ctx); if (!this->ssl) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "SSL init failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); _openssl_shutdown(&this->tls_plugin); return -1; } bio = _bio_new(this); SSL_set_bio(this->ssl, bio, bio); SSL_set_tlsext_host_name(this->ssl, host); ret = SSL_connect(this->ssl); if (ret <= 0) { if (ret == 0) xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unable to negotiate TLS/SSL session\n"); else xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "OpenSSL handshake failed: %s\n", ERR_error_string(ERR_get_error(), NULL)); _openssl_shutdown(&this->tls_plugin); return -1; } return 0; } static void _openssl_dispose(xine_module_t *this_gen) { _openssl_shutdown((tls_plugin_t*)this_gen); free(this_gen); } static xine_module_t *_openssl_get_instance(xine_module_class_t *cls_gen, const void *params_gen) { openssl_class_t *cls = (openssl_class_t *)cls_gen; const tls_plugin_params_t *p = params_gen; tls_openssl_t *this; pthread_mutex_lock(&cls->lock); if (!cls->inited) { SSL_library_init(); SSL_load_error_strings(); cls->inited = 1; } pthread_mutex_unlock(&cls->lock); this = calloc(1, sizeof(*this)); if (!this) { return NULL; } this->tls_plugin.module.dispose = _openssl_dispose; this->tls_plugin.handshake = _openssl_handshake; this->tls_plugin.shutdown = _openssl_shutdown; this->tls_plugin.part_read = _openssl_part_read; this->tls_plugin.read = _openssl_read; this->tls_plugin.write = _openssl_write; this->xine = p->xine; this->fd = p->fd; this->stream = p->stream; return &this->tls_plugin.module; } static void _openssl_class_dispose(xine_module_class_t *cls_gen) { openssl_class_t *cls = (openssl_class_t *)cls_gen; pthread_mutex_destroy(&cls->lock); free(cls_gen); } static void *_openssl_init_class(xine_t *xine, const void *data) { openssl_class_t *this; (void)data; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->module_class.get_instance = _openssl_get_instance; this->module_class.description = N_("TLS provider (openssl)"); this->module_class.identifier = "openssl"; this->module_class.dispose = _openssl_class_dispose; pthread_mutex_init(&this->lock, NULL); tls_register_config_keys(xine->config); return this; } /* * exported plugin catalog entry */ static const xine_module_info_t module_info_openssl = { .priority = 5, .type = "tls_v1", }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "openssl", XINE_VERSION_CODE, &module_info_openssl, _openssl_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/tls/tls_gnutls.c�������������������������������������������������������������0000644�0001750�0001750�00000035532�14647725152�015766� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ /* * xine TLS provider plugin (using gnutls) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <errno.h> #include <gnutls/gnutls.h> #include <gnutls/x509.h> #if defined (GNUTLS_VERSION_NUMBER) && (GNUTLS_VERSION_NUMBER >= 0x030000) # define XINE_GNUTLS_3 # define XINE_GNUTLS_INIT_FLAGS GNUTLS_CLIENT | GNUTLS_NONBLOCK #else # define XINE_GNUTLS_INIT_FLAGS GNUTLS_CLIENT #endif #ifndef XINE_GNUTLS_3 # ifdef HAVE_MALLOC_H # include <malloc.h> # endif # include <string.h> # include <sys/stat.h> # include <dirent.h> #endif #define LOG_MODULE "gnutls" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/io_helper.h> #include <xine/xine_plugin.h> #include "xine_tls_plugin.h" typedef struct { tls_plugin_t tls_plugin; xine_stream_t *stream; xine_t *xine; int fd; int need_shutdown; gnutls_session_t session; gnutls_certificate_credentials_t cred; size_t buf_got, buf_delivered; uint8_t buf[32 << 10]; } tls_gnutls_t; /* * gnutls I/O callbacks */ static ssize_t gnutls_tcp_pull(gnutls_transport_ptr_t tp, void *buf, size_t len) { /* gnutls always reads small block head (5 bytes), gets payload size, * and reads the rest of block before it does anything else. */ tls_gnutls_t *this = (tls_gnutls_t *)tp; size_t l = this->buf_got - this->buf_delivered; if (l) { /* get from buf */ if (l > len) { xine_fast_memcpy (buf, this->buf + this->buf_delivered, len); this->buf_delivered += len; return len; } xine_fast_memcpy (buf, this->buf + this->buf_delivered, l); this->buf_got = this->buf_delivered = 0; return l; } /* buf is empty */ if (len < 17) { /* head only, read ahead ;-) */ ssize_t r = _x_io_tcp_part_read (this->stream, this->fd, this->buf, len, sizeof (this->buf)); if (r <= 0) return r; if ((size_t)r > len) { xine_small_memcpy (buf, this->buf, len); this->buf_got = r; this->buf_delivered = len; return len; } xine_small_memcpy (buf, this->buf, r); return r; } /* get directly */ return _x_io_tcp_read (this->stream, this->fd, buf, len); } static ssize_t gnutls_tcp_push(gnutls_transport_ptr_t tp, const void *buf, size_t len) { tls_gnutls_t *this = (tls_gnutls_t *)tp; return _x_io_tcp_write(this->stream, this->fd, buf, len); } /* * */ #if 0 static int handle_gnutls_error(tls_gnutls_t *this, int err) { switch (err) { case GNUTLS_E_AGAIN: errno = EAGAIN; return -1; default: xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s\n", gnutls_strerror(err)); break; } errno = EIO; return -1; } #endif /* * */ static ssize_t _gnutls_write(tls_plugin_t *this_gen, const void *buf, size_t len) { tls_gnutls_t *this = (tls_gnutls_t *)this_gen; const uint8_t *b = (const uint8_t *)buf; size_t have = 0; if (!this->session) return -1; while (have < len) { ssize_t ret = gnutls_record_send (this->session, b + have, len - have); if (ret > 0) { have += ret; } else if (ret == 0) { break; } else if (ret == GNUTLS_E_AGAIN) { ret = _x_io_select (this->stream, this->fd, gnutls_record_get_direction (this->session) ? XIO_WRITE_READY : XIO_READ_READY, _x_query_network_timeout (this->xine) * 1000); if (ret != XIO_READY) return -1; } else { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s (%d).\n", gnutls_strerror (ret), (int)ret); errno = EIO; return -1; } } return have; } static ssize_t _gnutls_read(tls_plugin_t *this_gen, void *buf, size_t len) { tls_gnutls_t *this = (tls_gnutls_t *)this_gen; uint8_t *b = (uint8_t *)buf; size_t have = 0; if (!this->session) return -1; while (have < len) { ssize_t ret = gnutls_record_recv (this->session, b + have, len - have); if (ret > 0) { have += ret; } else if (ret == 0) { break; } else if (ret == GNUTLS_E_AGAIN) { ret = _x_io_select (this->stream, this->fd, gnutls_record_get_direction (this->session) ? XIO_WRITE_READY : XIO_READ_READY, _x_query_network_timeout (this->xine) * 1000); if (ret != XIO_READY) return -1; } else { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s (%d).\n", gnutls_strerror (ret), (int)ret); errno = EIO; return -1; } } return have; } static ssize_t _gnutls_part_read (tls_plugin_t *this_gen, void *buf, size_t min, size_t max) { tls_gnutls_t *this = (tls_gnutls_t *)this_gen; uint8_t *b = (uint8_t *)buf; size_t have = 0; if (!this->session) return -1; while (have < min) { ssize_t ret = gnutls_record_recv (this->session, b + have, max - have); if (ret > 0) { have += ret; } else if (ret == 0) { break; } else if (ret == GNUTLS_E_AGAIN) { ret = _x_io_select (this->stream, this->fd, gnutls_record_get_direction (this->session) ? XIO_WRITE_READY : XIO_READ_READY, _x_query_network_timeout (this->xine) * 1000); if (ret != XIO_READY) return -1; } else { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s (%d).\n", gnutls_strerror (ret), (int)ret); errno = EIO; return -1; } } return have; } #ifndef XINE_GNUTLS_3 static int _gnutls_load_certs (tls_gnutls_t *this, const char *dirname) { DIR *dir; dir = opendir (dirname); if (!dir) { int e = errno; xprintf (this->xine, XINE_VERBOSITY_LOG, "tls_gnutls: %s: %s (%d).\n", dirname, strerror (e), e); return 1; } { #if _FILE_OFFSET_BITS == 64 # define list_t uint64_t #else # define list_t uint32_t #endif unsigned int have_num, certs, files, dupl; struct dirent *item; list_t *have_list; uint8_t tempbuf[2048], *nadd = tempbuf; nadd += strlcpy ((char *)tempbuf, dirname, sizeof (tempbuf) - 2); if (nadd > tempbuf + sizeof (tempbuf) - 2) nadd = tempbuf + sizeof (tempbuf) - 2; *nadd++ = '/'; have_list = malloc (512 * sizeof (list_t)); if (!have_list) { closedir (dir); return 2; } have_list[0] = ~(list_t)0; have_num = 0; certs = 0; files = 0; dupl = 0; while ((item = readdir (dir)) != NULL) { struct stat s; int n; if (!item->d_name) continue; strlcpy ((char *)nadd, item->d_name, sizeof (tempbuf) - (nadd - tempbuf)); if (stat ((const char *)tempbuf, &s)) continue; if (!S_ISREG (s.st_mode)) continue; files++; /* Simple avoid duplicates by inode #. What about symbolic links? */ { list_t *here, i = s.st_ino; unsigned int a = 0, l, m = ~0, e = have_num + 1; while (1) { l = m; m = (a + e) >> 1; if (l == m) break; if (i < have_list[m]) e = m; else if (i > have_list[m]) a = m; else break; } here = have_list + m; if (i == *here) { dupl++; continue; } do { if ((have_num & 511) == 511) { here = realloc (have_list, (have_num + 1 + 512) * sizeof (list_t)); if (!here) break; have_list = here; here += m; } memmove (here + 1, here, (have_num - m + 1) * sizeof (list_t)); *here = i; have_num++; } while (0); } n = gnutls_certificate_set_x509_trust_file (this->cred, (const char *)tempbuf, GNUTLS_X509_FMT_PEM); if (n < 0) xprintf (this->xine, XINE_VERBOSITY_LOG, "tls_gnutls: %s: %s (%d).\n", (const char *)tempbuf, gnutls_strerror (n), n); else certs += n; } #undef list_t free (have_list); closedir (dir); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "tls_gnutls: %s: got %u files, %u duplicates.\n", dirname, files, dupl); if (!certs) xprintf (this->xine, XINE_VERBOSITY_LOG, "tls_gnutls: %s: no trust certificates found.\n", dirname); else xprintf (this->xine, XINE_VERBOSITY_DEBUG, "tls_gnutls: loaded %u trust certificates.\n", certs); } return 0; } #endif static void _gnutls_shutdown(tls_plugin_t *this_gen) { tls_gnutls_t *this = (tls_gnutls_t *)this_gen; if (this->need_shutdown) { this->need_shutdown = 0; while (1) { int ret = gnutls_bye (this->session, GNUTLS_SHUT_WR); if (ret != GNUTLS_E_AGAIN) break; ret = _x_io_select (this->stream, this->fd, gnutls_record_get_direction (this->session) ? XIO_WRITE_READY : XIO_READ_READY, _x_query_network_timeout (this->xine) * 1000); if (ret != XIO_READY) break; } } if (this->session) { gnutls_deinit(this->session); this->session = NULL; } if (this->cred) { gnutls_certificate_free_credentials(this->cred); this->cred = NULL; } } static int _gnutls_handshake(tls_plugin_t *this_gen, const char *host, int verify) { tls_gnutls_t *this = (tls_gnutls_t *)this_gen; int ret; _x_assert(this->session == NULL); gnutls_init (&this->session, XINE_GNUTLS_INIT_FLAGS); if (host) { gnutls_server_name_set(this->session, GNUTLS_NAME_DNS, host, strlen(host)); } gnutls_certificate_allocate_credentials(&this->cred); #ifdef XINE_GNUTLS_3 gnutls_certificate_set_x509_system_trust(this->cred); #else _gnutls_load_certs (this, "/etc/ssl/certs"); #endif gnutls_certificate_set_verify_flags(this->cred, verify ? GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT : 0); gnutls_credentials_set(this->session, GNUTLS_CRD_CERTIFICATE, this->cred); gnutls_transport_set_pull_function(this->session, gnutls_tcp_pull); gnutls_transport_set_push_function(this->session, gnutls_tcp_push); gnutls_transport_set_ptr(this->session, this); #ifndef XINE_GNUTLS_3 gnutls_transport_set_lowat (this->session, 0); #endif gnutls_priority_set_direct(this->session, "NORMAL", NULL); while (1) { ret = gnutls_handshake (this->session); if (ret != GNUTLS_E_AGAIN) break; ret = _x_io_select (this->stream, this->fd, gnutls_record_get_direction (this->session) ? XIO_WRITE_READY : XIO_READ_READY, _x_query_network_timeout (this->xine) * 1000); if (ret != XIO_READY) return -1; } if (ret) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "TLS handshake failed: %s (%d)\n", gnutls_strerror (ret), ret); return -1; } this->need_shutdown = 1; if (verify < 0 && this->xine) verify = tls_get_verify_tls_cert(this->xine->config); if (verify) { unsigned int status; while (1) { ret = gnutls_certificate_verify_peers2 (this->session, &status); if (ret != GNUTLS_E_AGAIN) break; ret = _x_io_select (this->stream, this->fd, gnutls_record_get_direction (this->session) ? XIO_WRITE_READY : XIO_READ_READY, _x_query_network_timeout (this->xine) * 1000); if (ret != XIO_READY) return -2; } if (ret < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unable to verify peer certificate: %s (%d)\n", gnutls_strerror(ret), ret); return -2; } if (status & GNUTLS_CERT_INVALID) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Peer certificate failed verification\n"); return -2; } if (gnutls_certificate_type_get(this->session) != GNUTLS_CRT_X509) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unsupported certificate type\n"); return -2; } if (host) { unsigned int cert_list_size; gnutls_x509_crt_t cert; const gnutls_datum_t *cert_list; gnutls_x509_crt_init(&cert); cert_list = gnutls_certificate_get_peers(this->session, &cert_list_size); gnutls_x509_crt_import(cert, cert_list, GNUTLS_X509_FMT_DER); ret = gnutls_x509_crt_check_hostname(cert, host); gnutls_x509_crt_deinit(cert); if (!ret) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "The certificate does not match hostname %s\n", host); return -3; } } } return 0; } static void _gnutls_dispose(xine_module_t *this_gen) { _gnutls_shutdown((tls_plugin_t*)this_gen); gnutls_global_deinit(); free(this_gen); } static xine_module_t *gnutls_get_instance(xine_module_class_t *cls_gen, const void *params_gen) { const tls_plugin_params_t *p = params_gen; tls_gnutls_t *this; int ret; (void)cls_gen; ret = gnutls_global_init(); if (ret) { xprintf(p->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "gnutls_global_init() failed: %s (%d)\n", gnutls_strerror(ret), ret); return NULL; } this = calloc(1, sizeof(*this)); if (!this) { gnutls_global_deinit(); return NULL; } this->tls_plugin.module.dispose = _gnutls_dispose; this->tls_plugin.handshake = _gnutls_handshake; this->tls_plugin.shutdown = _gnutls_shutdown; this->tls_plugin.read = _gnutls_read; this->tls_plugin.part_read = _gnutls_part_read; this->tls_plugin.write = _gnutls_write; this->xine = p->xine; this->fd = p->fd; this->stream = p->stream; this->buf_got = 0; this->buf_delivered = 0; return &this->tls_plugin.module; } static void *gnutls_init_class(xine_t *xine, const void *data) { static const xine_module_class_t tls_gnutls_class = { .get_instance = gnutls_get_instance, .description = N_("TLS provider (gnutls)"), .identifier = "gnutls", .dispose = NULL, }; (void)xine; (void)data; tls_register_config_keys(xine->config); return (void *)&tls_gnutls_class; } /* * exported plugin catalog entry */ static const xine_module_info_t module_info_gnutls = { .priority = 10, .type = "tls_v1", }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_XINE_MODULE, 1, "gnutls", XINE_VERSION_CODE, &module_info_gnutls, gnutls_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_smb.c������������������������������������������������������������������0000644�0001750�0001750�00000035316�14647725152�014766� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2008-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/input_plugin.h> #include <libsmbclient.h> #include <sys/types.h> #include <errno.h> #ifdef HAVE_SETLOCALE #include <locale.h> #endif #define MAXFILES 65535 typedef struct { input_class_t input_class; xine_t *xine; int mrls_allocated_entries; xine_mrl_t **mrls; } smb_input_class_t; typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; /* File */ char *mrl; int fd; } smb_input_t; static uint32_t smb_plugin_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_SEEKABLE; // | INPUT_CAP_SPULANG; } static off_t smb_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { smb_input_t *this = (smb_input_t *) this_gen; char *buf = (char *)buf_gen; off_t n, num_bytes; if (len < 0) return -1; num_bytes = 0; while (num_bytes < len) { n = smbc_read( this->fd, buf+num_bytes, len-num_bytes ); if (n<0) return -1; if (!n) return num_bytes; num_bytes += n; } return num_bytes; } static buf_element_t* smb_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { off_t total_bytes; buf_element_t *buf = fifo->buffer_pool_alloc (fifo); if (todo > buf->max_size) todo = buf->max_size; if (todo < 0) { buf->free_buffer (buf); return NULL; } buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; total_bytes = smb_plugin_read (this_gen, (char*)buf->content, todo); if (total_bytes == todo) buf->size = todo; else { buf->free_buffer (buf); buf = NULL; } return buf; } static off_t smb_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { smb_input_t *this = (smb_input_t *) this_gen; if (this->fd<0) return 0; return smbc_lseek(this->fd,offset,origin); } static off_t smb_plugin_get_current_pos (input_plugin_t *this_gen) { smb_input_t *this = (smb_input_t *) this_gen; if (this->fd<0) return 0; return smbc_lseek(this->fd,0,SEEK_CUR); } static off_t smb_plugin_get_length (input_plugin_t *this_gen) { smb_input_t *this = (smb_input_t *) this_gen; int e; struct stat st; if (this->fd>=0) e = smbc_fstat(this->fd,&st); else e = smbc_stat(this->mrl,&st); if (e) return 0; return st.st_size; } static const char* smb_plugin_get_mrl (input_plugin_t *this_gen) { smb_input_t *this = (smb_input_t *) this_gen; return this->mrl; } static uint32_t smb_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return 0; } /* * Sorting function, it comes from GNU fileutils package. */ #define S_N 0x0 #define S_I 0x4 #define S_F 0x8 #define S_Z 0xC #define CMP 2 #define LEN 3 #define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) static int _strverscmp(const char *s1, const char *s2) { const unsigned char *p1 = (const unsigned char *) s1; const unsigned char *p2 = (const unsigned char *) s2; unsigned char c1, c2; int state; int diff; static const unsigned int next_state[] = { S_N, S_I, S_Z, S_N, S_N, S_I, S_I, S_I, S_N, S_F, S_F, S_F, S_N, S_F, S_Z, S_Z }; static const int result_type[] = { CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, -1, -1, CMP, 1, LEN, LEN, CMP, 1, LEN, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, LEN, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, CMP, 1, 1, CMP, -1, CMP, CMP, CMP, -1, CMP, CMP, CMP }; if(p1 == p2) return 0; c1 = *p1++; c2 = *p2++; state = S_N | ((c1 == '0') + (ISDIGIT(c1) != 0)); while((diff = c1 - c2) == 0 && c1 != '\0') { state = next_state[state]; c1 = *p1++; c2 = *p2++; state |= (c1 == '0') + (ISDIGIT(c1) != 0); } state = result_type[state << 2 | ((c2 == '0') + (ISDIGIT(c2) != 0))]; switch(state) { case CMP: return diff; case LEN: while(ISDIGIT(*p1++)) if(!ISDIGIT(*p2++)) return 1; return ISDIGIT(*p2) ? -1 : diff; default: return state; } } /* * Wrapper to _strverscmp() for qsort() calls, which sort mrl_t type array. */ static int _sortfiles_default(const xine_mrl_t *s1, const xine_mrl_t *s2) { return(_strverscmp(s1->mrl, s2->mrl)); } static xine_mrl_t **smb_class_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { smb_input_class_t *this = (smb_input_class_t *) this_gen; int (*func) () = _sortfiles_default; int dir; int i; struct smbc_dirent *pdirent; char current_path [XINE_PATH_MAX + 1]; char current_path_smb [XINE_PATH_MAX + 2]; int num_files=0; if (filename != NULL && strlen(filename)>6){ snprintf_buf(current_path, "%s",filename); snprintf_buf(current_path_smb, "%s/",current_path); }else{ strcpy(current_path, "smb:/"); strcpy(current_path_smb, "smb://"); } if ((dir = smbc_opendir(current_path_smb)) >= 0){ xine_mrl_t *dir_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t)); xine_mrl_t *norm_files = (xine_mrl_t *) calloc(MAXFILES, sizeof(xine_mrl_t)); int num_dir_files=0; int num_norm_files=0; if (!dir_files || !norm_files) { free(dir_files); free(norm_files); smbc_closedir(dir); *nFiles = 0; return NULL; } while ((pdirent = smbc_readdir(dir)) != NULL){ if (pdirent->smbc_type == SMBC_WORKGROUP){ dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); dir_files[num_dir_files].mrl = _x_asprintf("%s/%s", current_path, pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; }else if (pdirent->smbc_type == SMBC_SERVER){ if (num_dir_files == 0) { dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup("smb:/"); dir_files[num_dir_files].mrl = strdup("smb://.."); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; } dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup("smb:/"); dir_files[num_dir_files].mrl = _x_asprintf("smb://%s", pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; } else if (pdirent->smbc_type == SMBC_FILE_SHARE){ if (num_dir_files == 0) { dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); dir_files[num_dir_files].mrl = _x_asprintf("%s/..", current_path); dir_files[num_dir_files].type |= mrl_file_directory; dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; } if (pdirent->name[strlen(pdirent->name)-1]!='$'){ dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); dir_files[num_dir_files].mrl = _x_asprintf("%s/%s", current_path, pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; } } else if (pdirent->smbc_type == SMBC_DIR){ dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].origin = strdup(current_path); dir_files[num_dir_files].mrl = _x_asprintf("%s/%s", current_path, pdirent->name); dir_files[num_dir_files].size = pdirent->dirlen; num_dir_files ++; }else if (pdirent->smbc_type == SMBC_FILE){ norm_files[num_norm_files].link = NULL; norm_files[num_norm_files].type = mrl_file | mrl_file_normal; norm_files[num_norm_files].origin = strdup(current_path); norm_files[num_norm_files].mrl = _x_asprintf("%s/%s", current_path, pdirent->name); norm_files[num_norm_files].size = pdirent->dirlen; num_norm_files ++; } } smbc_closedir(dir); if (num_dir_files == 0) { dir_files[num_dir_files].link = NULL; dir_files[num_dir_files].origin = strdup(current_path); dir_files[num_dir_files].mrl = _x_asprintf("%s/..", current_path); dir_files[num_dir_files].type = mrl_file | mrl_file_directory; dir_files[num_dir_files].size = 0; num_dir_files ++; } /* * Sort arrays */ if(num_dir_files) qsort(dir_files, num_dir_files, sizeof(xine_mrl_t), func); if(num_norm_files) qsort(norm_files, num_norm_files, sizeof(xine_mrl_t), func); /* * Add directories entries */ for(i = 0; i < num_dir_files; i++) { if (num_files >= this->mrls_allocated_entries) { ++this->mrls_allocated_entries; this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*)); this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t)); }else MRL_ZERO(this->mrls[num_files]); *(this->mrls[num_files]) = dir_files[i]; num_files++; } /* * Add other files entries */ for(i = 0; i < num_norm_files; i++) { if(num_files >= this->mrls_allocated_entries) { ++this->mrls_allocated_entries; this->mrls = realloc(this->mrls, (this->mrls_allocated_entries+1) * sizeof(xine_mrl_t*)); this->mrls[num_files] = calloc(1, sizeof(xine_mrl_t)); }else MRL_ZERO(this->mrls[num_files]); *(this->mrls[num_files]) = norm_files[i]; num_files++; } /* Some cleanups before leaving */ free(dir_files); free(norm_files); }else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_smb: smbc_opendir(\"%s\") failed: %d - %s\n", current_path, errno, strerror(errno)); *nFiles = 0; return NULL; } /* * Inform caller about files found number. */ *nFiles = num_files; /* * Freeing exceeded mrls if exists. */ while(this->mrls_allocated_entries > num_files) { this->mrls_allocated_entries--; MRL_ZERO(this->mrls[this->mrls_allocated_entries]); _x_freep(&this->mrls[this->mrls_allocated_entries]); } /* * This is useful to let UI know where it should stops ;-). */ this->mrls[num_files] = NULL; return this->mrls; } static int smb_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return INPUT_OPTIONAL_UNSUPPORTED; } static void smb_plugin_dispose (input_plugin_t *this_gen ) { smb_input_t *this = (smb_input_t *) this_gen; if (this->fd>=0) smbc_close(this->fd); if (this->mrl) free (this->mrl); free (this); } static int smb_plugin_open (input_plugin_t *this_gen ) { smb_input_t *this = (smb_input_t *) this_gen; smb_input_class_t *class = (smb_input_class_t *) this_gen->input_class; this->fd = smbc_open(this->mrl,O_RDONLY,0); xprintf(class->xine, XINE_VERBOSITY_DEBUG, "input_smb: open failed for %s: %s\n", this->mrl, strerror(errno)); if (this->fd<0) return 0; return 1; } static void smb_class_dispose (input_class_t *this_gen) { smb_input_class_t *this = (smb_input_class_t *) this_gen; while(this->mrls_allocated_entries) { this->mrls_allocated_entries--; MRL_ZERO(this->mrls[this->mrls_allocated_entries]); _x_freep(&this->mrls[this->mrls_allocated_entries]); } _x_freep(&this->mrls); free (this); } static input_plugin_t * smb_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *mrl) { smb_input_t *this; if (mrl == NULL) return NULL; if (strncmp (mrl, "smb://",6)) return NULL; this = calloc(1, sizeof(smb_input_t)); if (!this) return NULL; this->stream = stream; this->mrl = strdup (mrl); this->fd = -1; this->input_plugin.open = smb_plugin_open; this->input_plugin.get_capabilities = smb_plugin_get_capabilities; this->input_plugin.read = smb_plugin_read; this->input_plugin.read_block = smb_plugin_read_block; this->input_plugin.seek = smb_plugin_seek; this->input_plugin.get_current_pos = smb_plugin_get_current_pos; this->input_plugin.get_length = smb_plugin_get_length; this->input_plugin.get_blocksize = smb_plugin_get_blocksize; this->input_plugin.get_mrl = smb_plugin_get_mrl; this->input_plugin.get_optional_data = smb_plugin_get_optional_data; this->input_plugin.dispose = smb_plugin_dispose; this->input_plugin.input_class = class_gen; return &this->input_plugin; } static void smb_auth(const char *srv, const char *shr, char *wg, int wglen, char *un, int unlen, char *pw, int pwlen) { //wglen = unlen = pwlen = 0; (void)srv; (void)shr; (void)wg; (void)wglen; (void)un; (void)unlen; (void)pw; (void)pwlen; } static void *init_input_class (xine_t *xine, const void *data) { smb_input_class_t *this = NULL; /* libsmbclient seems to mess up with locale. Workaround: save and restore locale */ #ifdef HAVE_SETLOCALE char *lcl = strdup(setlocale(LC_MESSAGES, NULL)); #endif (void)data; if (smbc_init(smb_auth,(xine->verbosity >= XINE_VERBOSITY_DEBUG))) goto _exit_error; this = calloc(1, sizeof(smb_input_class_t)); if (this) { this->xine = xine; this->input_class.get_instance = smb_class_get_instance; this->input_class.identifier = "smb"; this->input_class.description = N_("CIFS/SMB input plugin based on libsmbclient"); this->input_class.get_dir = smb_class_get_dir; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = smb_class_dispose; this->input_class.eject_media = NULL; } _exit_error: #ifdef HAVE_SETLOCALE setlocale(LC_MESSAGES, lcl); free(lcl); #endif return (input_class_t *) this; } static const input_info_t input_info_smb = { .priority = 0, }; const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_INPUT, 18, "smb", XINE_VERSION_CODE, &input_info_smb, init_input_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_rtsp.c�����������������������������������������������������������������0000644�0001750�0001750�00000015047�14647725152�015174� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * rtsp input plugin */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <unistd.h> #include <stdio.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define LOG_MODULE "input_rtsp" #define LOG_VERBOSE /* #define LOG */ #include "bswap.h" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "librtsp/rtsp_session.h" #include "net_buf_ctrl.h" #include "input_helper.h" #include "group_network.h" #define BUFSIZE 1025 typedef struct { input_plugin_t input_plugin; rtsp_session_t *rtsp; xine_stream_t *stream; char *mrl; char *public_mrl; off_t curpos; nbc_t *nbc; char scratch[BUFSIZE]; } rtsp_input_plugin_t; static off_t rtsp_plugin_read (input_plugin_t *this_gen, void *buf, off_t len) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; off_t n; lprintf ("rtsp_plugin_read: %"PRId64" bytes ...\n", len); n = rtsp_session_read (this->rtsp, buf, len); if (n > 0) this->curpos += n; return n; } static off_t rtsp_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; lprintf ("seek %"PRId64" bytes, origin %d\n", offset, origin); /* only realtive forward-seeking is implemented */ return _x_input_seek_preview(this_gen, offset, origin, &this->curpos, -1, -1); } static off_t rtsp_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; lprintf ("seek_time %d msec, origin %d\n", time_offset, origin); if (origin == SEEK_SET) rtsp_session_set_start_time (this->rtsp, time_offset); return this->curpos; } static off_t rtsp_plugin_get_length (input_plugin_t *this_gen) { /* rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; off_t length; */ (void)this_gen; return -1; } static uint32_t rtsp_plugin_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_PREVIEW | INPUT_CAP_RIP_FORBIDDEN; } static off_t rtsp_plugin_get_current_pos (input_plugin_t *this_gen){ rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; /* printf ("current pos is %"PRId64"\n", this->curpos); */ return this->curpos; } static void rtsp_plugin_dispose (input_plugin_t *this_gen) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; if (this->rtsp) { rtsp_session_end (this->rtsp); this->rtsp = NULL; } if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } _x_freep(&this->mrl); _x_freep(&this->public_mrl); free (this); } static const char* rtsp_plugin_get_mrl (input_plugin_t *this_gen) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; return this->public_mrl; } static int rtsp_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: return rtsp_session_peek_header(this->rtsp, data, MAX_PREVIEW_SIZE); break; } return INPUT_OPTIONAL_UNSUPPORTED; } static int rtsp_plugin_open (input_plugin_t *this_gen) { rtsp_input_plugin_t *this = (rtsp_input_plugin_t *) this_gen; rtsp_session_t *rtsp; lprintf ("trying to open '%s'\n", this->mrl); rtsp = rtsp_session_start(this->stream, this->mrl); if (!rtsp) { lprintf ("returning null.\n"); return 0; } this->rtsp = rtsp; return 1; } static input_plugin_t *rtsp_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { /* rtsp_input_class_t *cls = (rtsp_input_class_t *) cls_gen; */ rtsp_input_plugin_t *this; if (strncasecmp (mrl, "rtsp://", 6)) return NULL; this = calloc(1, sizeof (rtsp_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->rtsp = NULL; this->mrl = strdup (mrl); /* since we handle only real streams yet, we can savely add * an .rm extention to force handling by demux_real. */ this->public_mrl = _x_asprintf("%s.rm", this->mrl); this->nbc = nbc_init (stream); this->input_plugin.open = rtsp_plugin_open; this->input_plugin.get_capabilities = rtsp_plugin_get_capabilities; this->input_plugin.read = rtsp_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = rtsp_plugin_seek; this->input_plugin.seek_time = rtsp_plugin_seek_time; this->input_plugin.get_current_pos = rtsp_plugin_get_current_pos; this->input_plugin.get_length = rtsp_plugin_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = rtsp_plugin_get_mrl; this->input_plugin.dispose = rtsp_plugin_dispose; this->input_plugin.get_optional_data = rtsp_plugin_get_optional_data; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * rtsp input plugin class stuff */ void *input_rtsp_init_class (xine_t *xine, const void *data) { static const input_class_t input_rtsp_class = { .get_instance = rtsp_class_get_instance, .identifier = "rtsp", .description = N_("rtsp streaming input plugin"), .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)xine; (void)data; return (void *)&input_rtsp_class; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/group_network.h��������������������������������������������������������������0000644�0001750�0001750�00000002732�14647725152�015674� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * simple network input plugins */ #include <xine/xine_internal.h> void *input_net_init_class (xine_t *xine, const void *data); void *input_tls_init_class (xine_t *xine, const void *data); void *input_gopher_init_class(xine_t *xine, const void *data); void *input_http_init_class (xine_t *xine, const void *data); void *input_rtsp_init_class (xine_t *xine, const void *data); void *input_pnm_init_class (xine_t *xine, const void *data); void *input_ftp_init_class (xine_t *xine, const void *data); void *input_ftpes_init_class(xine_t *xine, const void *data); void *input_hls_init_class (xine_t *xine, const void *data); void *input_mpegdash_init_class (xine_t *xine, const void *data); ��������������������������������������xine-lib-1.2/src/input/input_pvr.c������������������������������������������������������������������0000644�0001750�0001750�00000134604�14647725152�015014� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * March 2003 - Miguel Freitas * This plugin was sponsored by 1Control * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * pvr input plugin for WinTV-PVR 250/350 pci cards using driver from: * http://ivtv.sf.net * * features: * - play live mpeg2 stream (realtime mode) while recording * - can pause, play slow, fast and seek back into the recorded stream * - switches back to realtime mode if played until the end * - may erase files as they get old * * requires: * - audio.synchronization.av_sync_method=resample * - ivtv driver (01 Jul 2003 cvs is known to work) * * MRL: * pvr:/<prefix_to_tmp_files>!<prefix_to_saved_files>!<max_page_age> * * usage: * xine pvr:/<prefix_to_tmp_files>\!<prefix_to_saved_files>\!<max_page_age> */ /************************************************************************** Programmer's note (or how to write your PVR frontend): - in order to use live pause functionality you must capture data to disk. this is done using XINE_EVENT_SET_V4L2 event. it is important to set the inputs/channel/frequency you want to capture data from. comments: 1) session_id must be set: it is used to create the temporary filenames. 2) if session_id = -1 no data will be recorded to disk (no pause/replay) 3) if session_id is the same as previous value it will just set the "sync point". sync point (show_page) may be used by the PVR frontend to tell that a new show has began. of course, the PVR frontend should be aware of TV guide and stuff. - when user wants to start recording (that is: temporary data will be made permanent) it should issue a XINE_EVENT_PVR_SAVE. mode can be one of the following: -1 = do nothing, just set the name (see below) 0 = truncate current session and save from now on 1 = save from last sync point 2 = save everything on current session saving actually means just marking the current pages as not temporary. when a session is finished, instead of erasing the files they will be renamed using the save file prefix. - the permanent name can be set in two ways: 1) passing a name with the XINE_EVENT_PVR_SAVE before closing the current session. (id = -1) 2) when a saved session is closed without setting the name, it will be given a stardard name based on channel number and time. an event XINE_EVENT_PVR_REPORT_NAME is sent to report the name and a unique identifier. frontend may then ask the user the name he wants and may pass back a XINE_EVENT_PVR_SAVE with id set. pvr plugin will rename the files again. ***************************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <string.h> #include <errno.h> #include <time.h> #include <pthread.h> #include <sys/ioctl.h> #ifdef HAVE_SYS_VIDEOIO_H # include <sys/videoio.h> #elif defined(HAVE_SYS_VIDEODEV2_H) # include <sys/videodev2.h> #else # include <linux/videodev2.h> #endif #define XINE_ENABLE_EXPERIMENTAL_FEATURES #define LOG_MODULE "input_pvr" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/input_plugin.h> #define PVR_DEVICE "/dev/video0" #define PVR_BLOCK_SIZE 2048 /* pvr works with dvd-like data */ #define BLOCKS_PER_PAGE 102400 /* 200MB per page. each session can have several pages */ #define MAX_PAGES 10000 /* maximum number of pages to keep track */ #define NUM_PREVIEW_BUFFERS 250 /* used in mpeg_block demuxer */ /* #define SCRLOG 1 */ /* external API borrowed from ivtv.h */ #define IVTV_IOC_G_CODEC 0xFFEE7703 #define IVTV_IOC_S_CODEC 0xFFEE7704 /* Stream types */ #define IVTV_STREAM_PS 0 #define IVTV_STREAM_TS 1 #define IVTV_STREAM_MPEG1 2 #define IVTV_STREAM_PES_AV 3 #define IVTV_STREAM_PES_V 5 #define IVTV_STREAM_PES_A 7 #define IVTV_STREAM_DVD 10 /* For use with IVTV_IOC_G_CODEC and IVTV_IOC_S_CODEC */ struct ivtv_ioctl_codec { uint32_t aspect; uint32_t audio_bitmask; uint32_t bframes; uint32_t bitrate_mode; uint32_t bitrate; uint32_t bitrate_peak; uint32_t dnr_mode; uint32_t dnr_spatial; uint32_t dnr_temporal; uint32_t dnr_type; uint32_t framerate; uint32_t framespergop; uint32_t gop_closure; uint32_t pulldown; uint32_t stream_type; }; typedef struct pvrscr_s pvrscr_t; typedef struct { input_plugin_t input_plugin; char *devname; xine_stream_t *stream; xine_event_queue_t *event_queue; pvrscr_t *scr; int scr_tunning; int speed_before_pause; uint32_t session; /* session number used to identify the pvr file */ int new_session; /* force going to realtime for new sessions */ int dev_fd; /* fd of the mpeg2 encoder device */ int rec_fd; /* fd of the current recording file (session/page) */ int play_fd; /* fd of the current playback (-1 when realtime) */ uint32_t rec_blk; /* next block to record */ uint32_t rec_page; /* page of current rec_fd file */ uint32_t play_blk; /* next block to play */ uint32_t play_page; /* page of current play_fd file */ uint32_t first_page; /* first page available (not erased yet) */ uint32_t max_page_age; /* max age to retire (erase) pages */ uint32_t show_page; /* first page of current show */ uint32_t save_page; /* first page to save */ uint32_t page_block[MAX_PAGES]; /* first block of each page */ char *mrl; char *tmp_prefix; char *save_prefix; char *save_name; xine_list_t *saved_shows; int saved_id; time_t start_time; /* time when recording started */ time_t show_time; /* time when current show started */ /* buffer to pass data from pvr thread to xine */ uint8_t data[PVR_BLOCK_SIZE]; int valid_data; int want_data; pthread_mutex_t lock; pthread_mutex_t dev_lock; pthread_cond_t has_valid_data; pthread_cond_t wake_pvr; pthread_t pvr_thread; int pvr_running; int pvr_playing; int pvr_play_paused; int preview_buffers; /* device properties */ int input; int channel; uint32_t frequency; } pvr_input_plugin_t; typedef struct { int id; char *base_name; int pages; } saved_show_t; /* * *************************************************** * unix System Clock Reference + fine tunning * * on an ideal world we would be using scr from mpeg2 * encoder just like dxr3 does. * unfortunately it is not supported by ivtv driver, * and perhaps not even possible with wintv cards. * * the fine tunning option is used to change play * speed in order to regulate fifo usage, that is, * trying to match the rate of generated data. * * OBS: use with audio.synchronization.av_sync_method=resample * *************************************************** */ struct pvrscr_s { scr_plugin_t scr; struct timeval cur_time; int64_t cur_pts; int xine_speed; double speed_factor; double speed_tunning; pthread_mutex_t lock; }; static int pvrscr_get_priority (scr_plugin_t *scr) { (void)scr; return 10; /* high priority */ } /* Only call this when already mutex locked */ static void pvrscr_set_pivot (pvrscr_t *this) { struct timeval tv; int64_t pts; double pts_calc; xine_monotonic_clock(&tv, NULL); pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; /* This next part introduces a one off inaccuracy * to the scr due to rounding tv to pts. */ this->cur_time.tv_sec=tv.tv_sec; this->cur_time.tv_usec=tv.tv_usec; this->cur_pts=pts; return ; } static int pvrscr_set_speed (scr_plugin_t *scr, int speed) { pvrscr_t *this = (pvrscr_t*) scr; pthread_mutex_lock (&this->lock); pvrscr_set_pivot( this ); this->xine_speed = speed; this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL * this->speed_tunning; pthread_mutex_unlock (&this->lock); return speed; } static void pvrscr_speed_tunning (pvrscr_t *this, double factor) { pthread_mutex_lock (&this->lock); pvrscr_set_pivot( this ); this->speed_tunning = factor; this->speed_factor = (double) this->xine_speed * 90000.0 / XINE_FINE_SPEED_NORMAL * this->speed_tunning; pthread_mutex_unlock (&this->lock); } static void pvrscr_adjust (scr_plugin_t *scr, int64_t vpts) { pvrscr_t *this = (pvrscr_t*) scr; struct timeval tv; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&tv, NULL); this->cur_time.tv_sec=tv.tv_sec; this->cur_time.tv_usec=tv.tv_usec; this->cur_pts = vpts; pthread_mutex_unlock (&this->lock); } static void pvrscr_start (scr_plugin_t *scr, int64_t start_vpts) { pvrscr_t *this = (pvrscr_t*) scr; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&this->cur_time, NULL); this->cur_pts = start_vpts; pthread_mutex_unlock (&this->lock); pvrscr_set_speed (&this->scr, XINE_FINE_SPEED_NORMAL); } static int64_t pvrscr_get_current (scr_plugin_t *scr) { pvrscr_t *this = (pvrscr_t*) scr; struct timeval tv; int64_t pts; double pts_calc; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&tv, NULL); pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; pthread_mutex_unlock (&this->lock); return pts; } static void pvrscr_exit (scr_plugin_t *scr) { pvrscr_t *this = (pvrscr_t*) scr; pthread_mutex_destroy (&this->lock); free(this); } static pvrscr_t *XINE_MALLOC pvrscr_init (void) { pvrscr_t *this; this = calloc(1, sizeof(pvrscr_t)); if (!this) return NULL; this->scr.interface_version = 3; this->scr.get_priority = pvrscr_get_priority; this->scr.set_fine_speed = pvrscr_set_speed; this->scr.adjust = pvrscr_adjust; this->scr.start = pvrscr_start; this->scr.get_current = pvrscr_get_current; this->scr.exit = pvrscr_exit; pthread_mutex_init (&this->lock, NULL); pvrscr_speed_tunning(this, 1.0 ); pvrscr_set_speed (&this->scr, XINE_SPEED_PAUSE); #ifdef SCRLOG printf("input_pvr: scr init complete\n"); #endif return this; } /*****************************************************/ static uint32_t block_to_page(pvr_input_plugin_t *this, uint32_t block) { uint32_t page; for( page = 0; page < this->rec_page; page++ ) { if( block < this->page_block[page+1] ) break; } return page; } static uint32_t pvr_plugin_get_capabilities (input_plugin_t *this_gen) { /* pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; */ (void)this_gen; return INPUT_CAP_BLOCK | INPUT_CAP_SEEKABLE; } static off_t pvr_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { /*pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen;*/ uint8_t *buf = buf_gen; (void)this_gen; if (len < 4) return -1; /* FIXME: Tricking the demux_mpeg_block plugin */ buf[0] = 0; buf[1] = 0; buf[2] = 0x01; buf[3] = 0xba; return 4; } /* * this function will adjust playback speed to control buffer utilization. * we must avoid: * - overflow: buffer runs full. no data is read from the mpeg2 card so it will discard * mpeg2 packets and get out of sync with the block size. * - underrun: buffer gets empty. playback will suffer a pausing effect, also discarding * video frames. * * OBS: use with audio.synchronization.av_sync_method=resample */ static void pvr_adjust_realtime_speed(pvr_input_plugin_t *this, fifo_buffer_t *fifo, int speed ) { int num_used, num_free; int scr_tunning = this->scr_tunning; num_used = fifo->size(fifo); num_free = fifo->num_free(fifo); if( num_used == 0 && scr_tunning != -2 ) { /* buffer is empty. pause it for a while */ this->scr_tunning = -2; /* marked as paused */ pvrscr_speed_tunning(this->scr, 1.0); this->speed_before_pause = speed; _x_set_speed(this->stream, XINE_SPEED_PAUSE); #ifdef SCRLOG printf("input_pvr: buffer empty, pausing playback\n" ); #endif } else if( scr_tunning == -2 ) { /* currently paused, revert to normal if 1/3 full */ if( 2*num_used > num_free ) { this->scr_tunning = 0; pvrscr_speed_tunning(this->scr, 1.0 ); _x_set_speed(this->stream, this->speed_before_pause); #ifdef SCRLOG printf("input_pvr: resuming playback\n" ); #endif } } else if( speed == XINE_SPEED_NORMAL && this->play_fd == -1 ) { /* when playing realtime, adjust the scr to make xine buffers half full */ if( num_used > 2*num_free ) scr_tunning = +1; /* play faster */ else if( num_free > 2*num_used ) scr_tunning = -1; /* play slower */ else if( (scr_tunning > 0 && num_free > num_used) || (scr_tunning < 0 && num_used > num_free) ) scr_tunning = 0; if( scr_tunning != this->scr_tunning ) { this->scr_tunning = scr_tunning; #ifdef SCRLOG printf("input_pvr: scr_tunning = %d (used: %d free: %d)\n", scr_tunning, num_used, num_free ); #endif /* make it play .5% faster or slower */ pvrscr_speed_tunning(this->scr, 1.0 + (0.005 * scr_tunning) ); } } else if( this->scr_tunning ) { this->scr_tunning = 0; pvrscr_speed_tunning(this->scr, 1.0 ); } } #define PVR_FILENAME "%s%08d_%08d.vob" static char *make_temp_name(pvr_input_plugin_t *this, int page) { return _x_asprintf(PVR_FILENAME, this->tmp_prefix, this->session, page); } #define SAVE_BASE_FILENAME "ch%03d %02d-%02d-%04d %02d:%02d:%02d" static char *make_base_save_name(int channel, time_t tm) { struct tm rec_time; localtime_r(&tm, &rec_time); return _x_asprintf(SAVE_BASE_FILENAME, channel, rec_time.tm_mon+1, rec_time.tm_mday, rec_time.tm_year+1900, rec_time.tm_hour, rec_time.tm_min, rec_time.tm_sec); } #define SAVE_FILENAME "%s%s_%04d.vob" static char *make_save_name(pvr_input_plugin_t *this, char *base, int page) { return _x_asprintf(SAVE_FILENAME, this->save_prefix, base, page); } /* * send event to frontend about realtime status */ static void pvr_report_realtime (pvr_input_plugin_t *this, int mode) { xine_event_t event; xine_pvr_realtime_t data; event.type = XINE_EVENT_PVR_REALTIME; event.stream = this->stream; event.data = &data; event.data_length = sizeof(data); gettimeofday(&event.tv, NULL); data.mode = mode; xine_event_send(this->stream, &event); } /* * close current recording page and open a new one */ static int pvr_break_rec_page (pvr_input_plugin_t *this) { char *filename; if( this->session == (unsigned)-1 ) /* not recording */ return 1; if( this->rec_fd != -1 && this->rec_fd != this->play_fd ) { close(this->rec_fd); } if( this->rec_fd == -1 ) this->rec_page = 0; else this->rec_page++; this->page_block[this->rec_page] = this->rec_blk; filename = make_temp_name(this, this->rec_page); lprintf("opening pvr file for writing (%s)\n", filename); this->rec_fd = xine_create_cloexec(filename, O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if( this->rec_fd == -1 ) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: error creating pvr file (%s)\n"), filename); free(filename); return 0; } free(filename); /* erase first_page if old and not to be saved */ if( this->max_page_age != (unsigned)-1 && this->rec_page - this->max_page_age == this->first_page && (this->save_page == (unsigned)-1 || this->first_page < this->save_page) ) { filename = make_temp_name(this, this->first_page); lprintf("erasing old pvr file (%s)\n", filename); this->first_page++; if(this->play_fd != -1 && this->play_page < this->first_page) { this->play_blk = this->page_block[this->first_page]; close(this->play_fd); this->play_fd = -1; } if (remove(filename) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_pvr: error removing pvr file (%s)\n", filename); } free(filename); } return 1; } /* * check the status of recording file, open new one as needed and write the current data. */ static int pvr_rec_file(pvr_input_plugin_t *this) { off_t pos; if( this->session == (unsigned)-1 ) /* not recording */ return 1; /* check if it's time to change page/file */ if( this->rec_fd == -1 || (this->rec_blk - this->page_block[this->rec_page]) >= BLOCKS_PER_PAGE ) { if( !pvr_break_rec_page(this) ) return 0; } pos = (off_t)(this->rec_blk - this->page_block[this->rec_page]) * PVR_BLOCK_SIZE; if( this->rec_fd != -1 ) { if( lseek (this->rec_fd, pos, SEEK_SET) != pos ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: error setting position for writing %" PRIdMAX "\n", (intmax_t)pos); return 0; } if( write(this->rec_fd, this->data, PVR_BLOCK_SIZE) < PVR_BLOCK_SIZE ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: short write to pvr file (out of disk space?)\n"); return 0; } this->rec_blk++; } return 1; } /* * check for playback mode, switching realtime <-> non-realtime. * gets data from file in non-realtime mode. */ static int pvr_play_file(pvr_input_plugin_t *this, fifo_buffer_t *fifo, uint8_t *buffer, int speed) { off_t pos; /* check for realtime. don't switch back unless enough buffers are * free to not block the pvr thread */ if( this->new_session || (this->play_blk+1 >= this->rec_blk && speed >= XINE_SPEED_NORMAL && (this->play_fd == -1 || fifo->size(fifo) < fifo->num_free(fifo))) ) { this->play_blk = (this->rec_blk) ? (this->rec_blk-1) : 0; if( speed > XINE_SPEED_NORMAL ) _x_set_speed(this->stream, XINE_SPEED_NORMAL); if( this->play_fd != -1 ) { if(this->play_fd != this->rec_fd ) close(this->play_fd); this->play_fd = -1; lprintf("switching back to realtime\n"); pvr_report_realtime(this,1); } else if (this->new_session) { lprintf("starting new session in realtime\n"); pvr_report_realtime(this,1); } this->want_data = 1; this->new_session = 0; } else { if( this->rec_fd == -1 ) return 1; if(speed != XINE_SPEED_PAUSE) { /* cannot run faster than the writing thread */ while( this->play_blk+1 >= this->rec_blk ) { if( this->valid_data ) { this->valid_data = 0; pthread_cond_signal (&this->wake_pvr); } pthread_cond_wait (&this->has_valid_data, &this->lock); } } if( this->play_fd == -1 || ((this->play_blk - this->page_block[this->play_page]) >= BLOCKS_PER_PAGE) || (this->rec_page > this->play_page && this->play_blk >= this->page_block[this->play_page+1]) ) { if(this->play_fd == -1) { lprintf("switching to non-realtime\n"); pvr_report_realtime(this,0); } if( this->play_fd != -1 && this->play_fd != this->rec_fd ) { close(this->play_fd); } if( this->play_fd == -1 ) this->play_page = block_to_page(this, this->play_blk); else this->play_page++; if( this->play_page < this->first_page ) { this->play_page = this->first_page; this->play_blk = this->page_block[this->play_page]; } /* should be impossible */ if( this->play_page > this->rec_page || this->play_blk > this->rec_blk ) { this->play_page = this->rec_page; this->play_blk = this->rec_blk; } /* check if we can reuse the same handle */ if( this->play_page == this->rec_page ) { this->play_fd = this->rec_fd; } else { char *filename; filename = make_temp_name(this, this->play_page); lprintf("opening pvr file for reading (%s)\n", filename); this->play_fd = xine_open_cloexec(filename, O_RDONLY); if( this->play_fd == -1 ) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: error opening pvr file (%s)\n"), filename); free(filename); return 0; } free(filename); } this->want_data = 0; pthread_cond_signal (&this->wake_pvr); } if(speed != XINE_SPEED_PAUSE) { pos = (off_t)(this->play_blk - this->page_block[this->play_page]) * PVR_BLOCK_SIZE; if( lseek (this->play_fd, pos, SEEK_SET) != pos ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: error setting position for reading %" PRIdMAX "\n", (intmax_t)pos); return 0; } if( read(this->play_fd, buffer, PVR_BLOCK_SIZE) < PVR_BLOCK_SIZE ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: short read from pvr file\n"); return 0; } this->play_blk++; } } /* now we are done on input/demuxer thread, engine may be paused safely */ if( this->pvr_play_paused ) { _x_set_speed (this->stream, XINE_SPEED_PAUSE); this->pvr_play_paused = 0; } return 1; } static int pvr_mpeg_resync (int fd) { uint32_t seq = 0; uint8_t c; while (seq != 0x000001ba) { if( read(fd, &c, 1) < 1 ) return 0; seq = (seq << 8) | c; } return 1; } /* * captures data from mpeg2 encoder card to disk. * may wait xine to get data when in realtime mode. */ static void *pvr_loop (void *this_gen) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; off_t num_bytes, total_bytes; int lost_sync; while( this->pvr_running ) { pthread_mutex_lock(&this->lock); this->valid_data = 0; pthread_mutex_unlock(&this->lock); total_bytes = 0; do { lost_sync = 0; pthread_mutex_lock(&this->dev_lock); while (total_bytes < PVR_BLOCK_SIZE) { num_bytes = read (this->dev_fd, this->data + total_bytes, PVR_BLOCK_SIZE-total_bytes); if (num_bytes <= 0) { if (num_bytes < 0) xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: read error (%s)\n"), strerror(errno)); this->pvr_running = 0; break; } total_bytes += num_bytes; } if( this->data[0] || this->data[1] || this->data[2] != 1 || this->data[3] != 0xba ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "resyncing mpeg stream\n"); if( !pvr_mpeg_resync(this->dev_fd) ) { this->pvr_running = 0; } else { lost_sync = 1; this->data[0] = 0; this->data[1] = 0; this->data[2] = 1; this->data[3] = 0xba; total_bytes = 4; } } pthread_mutex_unlock(&this->dev_lock); } while( lost_sync ); pthread_mutex_lock(&this->lock); if( !pvr_rec_file(this) ) { this->pvr_running = 0; } this->valid_data = 1; pthread_cond_signal (&this->has_valid_data); while(this->valid_data && this->play_fd == -1 && this->want_data && this->pvr_playing) { pthread_cond_wait (&this->wake_pvr, &this->lock); } pthread_mutex_unlock(&this->lock); } pthread_exit(NULL); } /* * finishes the current recording. * checks this->save_page if the recording should be saved or removed. * moves files to a permanent diretory (save_path) using a given show * name (save_name) or a default one using channel and time. */ static void pvr_finish_recording (pvr_input_plugin_t *this) { char *src_filename; char *save_base; char *dst_filename; uint32_t i; lprintf("finish_recording\n"); if( this->rec_fd != -1 ) { close(this->rec_fd); if( this->play_fd != -1 && this->play_fd != this->rec_fd ) close(this->play_fd); this->rec_fd = this->play_fd = -1; if( this->save_page == this->show_page ) save_base = make_base_save_name(this->channel, this->show_time); else save_base = make_base_save_name(this->channel, this->start_time); for( i = this->first_page; i <= this->rec_page; i++ ) { src_filename = make_temp_name(this, i); if( this->save_page == (unsigned)-1 || i < this->save_page ) { lprintf("erasing old pvr file (%s)\n", src_filename); if (remove(src_filename) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_pvr: error removing pvr file (%s)\n", src_filename); } } else { if( !this->save_name || !strlen(this->save_name) ) dst_filename = make_save_name(this, save_base, i-this->save_page+1); else dst_filename = make_save_name(this, this->save_name, i-this->save_page+1); lprintf("moving (%s) to (%s)\n", src_filename, dst_filename); if (rename(src_filename, dst_filename) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_pvr: error renaming pvr file (%s->%s)\n", src_filename, dst_filename); } free(dst_filename); } free(src_filename); } if( this->save_page != (unsigned)-1 && (!this->save_name || !strlen(this->save_name)) ) { saved_show_t *show = malloc(sizeof(saved_show_t)); xine_event_t event; xine_pvr_save_data_t data; show->base_name = save_base; show->id = ++this->saved_id; show->pages = this->rec_page - this->save_page + 1; xine_list_push_back (this->saved_shows, show); lprintf("sending event with base name [%s]\n", show->base_name); /* tell frontend the name of the saved show */ event.type = XINE_EVENT_PVR_REPORT_NAME; event.stream = this->stream; event.data = &data; event.data_length = sizeof(data); gettimeofday(&event.tv, NULL); data.mode = 0; data.id = show->id; strlcpy(data.name, show->base_name, sizeof(data.name)); xine_event_send(this->stream, &event); } else { free(save_base); } } this->first_page = 0; this->show_page = 0; this->save_page = -1; this->play_blk = this->rec_blk = 0; this->play_page = this->rec_page = 0; if( this->save_name ) free( this->save_name ); this->save_name = NULL; this->valid_data = 0; pthread_cond_signal (&this->wake_pvr); } /* * event handler: process external pvr commands * may switch channel, inputs, start/stop recording * set flag to save current session permanently */ static void pvr_event_handler (pvr_input_plugin_t *this) { xine_event_t *event; while ((event = xine_event_get (this->event_queue))) { xine_set_v4l2_data_t *v4l2_data = event->data; xine_pvr_save_data_t *save_data = event->data; xine_pvr_pause_t *pause_data = event->data; xine_set_mpeg_data_t *mpeg_data = event->data; switch (event->type) { case XINE_EVENT_SET_V4L2: /* make sure we are not paused */ _x_set_speed(this->stream, XINE_SPEED_NORMAL); if (v4l2_data->session_id != -1) { if (v4l2_data->session_id != (int)this->session) { /* if session changes -> closes the old one */ pthread_mutex_lock(&this->lock); pvr_finish_recording(this); time(&this->start_time); this->show_time = this->start_time; this->session = v4l2_data->session_id; this->new_session = 1; this->pvr_play_paused = 0; this->scr_tunning = 0; pvrscr_speed_tunning(this->scr, 1.0 ); pvr_break_rec_page(this); pthread_mutex_unlock(&this->lock); _x_demux_flush_engine (this->stream); } else { /* no session change, break the page and store a new show_time */ pthread_mutex_lock(&this->lock); pvr_break_rec_page(this); this->show_page = this->rec_page; pthread_mutex_unlock(&this->lock); time(&this->show_time); } } pthread_mutex_lock(&this->dev_lock); /* change input */ if (v4l2_data->input != -1 && v4l2_data->input != this->input) { this->input = v4l2_data->input; /* as of ivtv 0.10.6: must close and reopen to set input */ if (this->dev_fd >= 0) close(this->dev_fd); this->dev_fd = xine_open_cloexec(this->devname, O_RDWR); if (this->dev_fd < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: error opening device %s\n", this->devname ); } else { if( ioctl(this->dev_fd, VIDIOC_S_INPUT, &this->input) == 0 ) { lprintf("Tuner Input set to:%d\n", v4l2_data->input); } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: error setting v4l2 input\n"); } } } /* change channel */ if (v4l2_data->channel != -1 && v4l2_data->channel != this->channel) { lprintf("change channel to:%d\n", v4l2_data->channel); this->channel = v4l2_data->channel; } /* change frequency */ if (v4l2_data->frequency != (uint32_t)-1 && v4l2_data->frequency != this->frequency) { double freq = (double)v4l2_data->frequency / 1000.0; struct v4l2_frequency vf; struct v4l2_tuner vt; double fac = 16; memset(&vf, 0, sizeof(vf)); memset(&vt, 0, sizeof(vt)); this->frequency = v4l2_data->frequency; if (ioctl(this->dev_fd, VIDIOC_G_TUNER, &vt) == 0) { fac = (vt.capability & V4L2_TUNER_CAP_LOW) ? 16000 : 16; } vf.tuner = 0; vf.type = vt.type; vf.frequency = (uint32_t)(freq * fac); if (ioctl(this->dev_fd, VIDIOC_S_FREQUENCY, &vf) == 0) { lprintf("Tuner Frequency set to %d (%f.3 MHz)\n", vf.frequency, vf.frequency / fac); } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: error setting v4l2 frequency\n"); } } pthread_mutex_unlock(&this->dev_lock); /* FIXME: also flush the device */ /* _x_demux_flush_engine(this->stream); */ break; case XINE_EVENT_PVR_SAVE: if (this->session != (uint32_t)-1) { switch( save_data->mode ) { case 0: lprintf("saving from this point\n"); pthread_mutex_lock(&this->lock); pvr_break_rec_page(this); this->save_page = this->rec_page; time(&this->start_time); pthread_mutex_unlock(&this->lock); break; case 1: lprintf("saving from show start\n"); pthread_mutex_lock(&this->lock); this->save_page = this->show_page; pthread_mutex_unlock(&this->lock); break; case 2: lprintf("saving everything so far\n"); pthread_mutex_lock(&this->lock); this->save_page = this->first_page; pthread_mutex_unlock(&this->lock); break; } } if( strlen(save_data->name) ) { if( this->save_name ) free( this->save_name ); this->save_name = NULL; if( save_data->id < 0 ) { /* no id: set name for current recording */ this->save_name = strdup(save_data->name); } else { /* search for the ID of saved shows and rename it * to the given name. */ char *src_filename; char *dst_filename; saved_show_t *show; xine_list_iterator_t ite; pthread_mutex_lock(&this->lock); ite = xine_list_front (this->saved_shows); while (ite) { show = xine_list_get_value(this->saved_shows, ite); if( show->id == save_data->id ) { int i; for( i = 0; i < show->pages; i++ ) { src_filename = make_save_name(this, show->base_name, i+1); dst_filename = make_save_name(this, save_data->name, i+1); lprintf("moving (%s) to (%s)\n", src_filename, dst_filename); if (rename(src_filename, dst_filename) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "input_pvr: error renaming pvr file (%s->%s)\n", src_filename, dst_filename); } free(dst_filename); free(src_filename); } xine_list_remove (this->saved_shows, ite); free (show->base_name); free (show); break; } ite = xine_list_next (this->saved_shows, ite); } pthread_mutex_unlock(&this->lock); } } break; case XINE_EVENT_PVR_PAUSE: /* ignore event if trying to pause, but already paused */ if(_x_get_speed(this->stream) != XINE_SPEED_PAUSE || !pause_data->mode) this->pvr_play_paused = pause_data->mode; break; case XINE_EVENT_SET_MPEG_DATA: { struct ivtv_ioctl_codec codec; pthread_mutex_lock(&this->dev_lock); /* how lame. we must close and reopen to change bitrate. */ if (this->dev_fd >= 0) close(this->dev_fd); this->dev_fd = xine_open_cloexec(this->devname, O_RDWR); if (this->dev_fd == -1) { pthread_mutex_unlock(&this->dev_lock); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: error opening device %s\n"), this->devname ); return; } if (ioctl(this->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n")); } else { codec.bitrate = mpeg_data->bitrate_mean; codec.bitrate_peak = mpeg_data->bitrate_peak; codec.stream_type = IVTV_STREAM_DVD; if (ioctl(this->dev_fd, IVTV_IOC_S_CODEC, &codec) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n")); } } pthread_mutex_unlock(&this->dev_lock); } break; #if 0 default: printf ("input_pvr: got an event, type 0x%08x\n", event->type); #endif } xine_event_free (event); } } /* * pvr read_block function. * - adjust playing speed to keep buffers half-full * - check current playback mode * - get data from file (non-realtime) or the pvr thread (realtime) */ static buf_element_t *pvr_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; buf_element_t *buf; int speed = _x_get_speed(this->stream); if( !this->pvr_running ) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pvr: thread died, aborting\n"); return NULL; } buf = fifo->buffer_pool_alloc (fifo); if (todo > buf->max_size) todo = buf->max_size; if (todo < 0) { buf->free_buffer(buf); return NULL; } if( this->scr_tunning == -2 ) speed = this->speed_before_pause; if( this->pvr_play_paused ) speed = XINE_SPEED_PAUSE; if( this->pvr_playing && _x_stream_info_get(this->stream, XINE_STREAM_INFO_IGNORE_VIDEO) ) { /* video decoding has being disabled. avoid tweaking the clock */ this->pvr_playing = 0; this->scr_tunning = 0; pvrscr_speed_tunning(this->scr, 1.0 ); this->want_data = 0; pthread_cond_signal (&this->wake_pvr); } else if ( !this->pvr_playing && !_x_stream_info_get(this->stream,XINE_STREAM_INFO_IGNORE_VIDEO) ) { this->pvr_playing = 1; this->play_blk = this->rec_blk; } if( this->pvr_playing ) pvr_adjust_realtime_speed(this, fifo, speed); pvr_event_handler(this); buf->content = buf->mem; pthread_mutex_lock(&this->lock); if( this->pvr_playing ) if( !pvr_play_file(this, fifo, buf->content, speed) ) { buf->free_buffer(buf); pthread_mutex_unlock(&this->lock); return NULL; } if( todo == PVR_BLOCK_SIZE && speed != XINE_SPEED_PAUSE && this->pvr_playing ) { buf->type = BUF_DEMUX_BLOCK; buf->size = PVR_BLOCK_SIZE; if(this->play_fd == -1) { /* realtime mode: wait for valid data from pvr thread */ this->want_data = 1; while(!this->valid_data && this->pvr_running) pthread_cond_wait (&this->has_valid_data, &this->lock); this->play_blk = this->rec_blk; xine_fast_memcpy(buf->content, this->data, PVR_BLOCK_SIZE); this->valid_data = 0; pthread_cond_signal (&this->wake_pvr); } pthread_mutex_unlock(&this->lock); } else { pthread_mutex_unlock(&this->lock); buf->type = BUF_CONTROL_NOP; buf->size = 0; if(this->preview_buffers) this->preview_buffers--; else xine_usec_sleep (20000); } return buf; } static off_t pvr_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; pthread_mutex_lock(&this->lock); switch( origin ) { case SEEK_SET: this->play_blk = (offset / PVR_BLOCK_SIZE) + this->page_block[this->first_page]; break; case SEEK_CUR: this->play_blk += offset / PVR_BLOCK_SIZE; break; case SEEK_END: this->play_blk = this->rec_blk + (offset / PVR_BLOCK_SIZE); break; } /* invalidate the fd if needed */ if( this->play_fd != -1 && block_to_page(this,this->play_blk) != this->play_page ) { if( this->play_fd != this->rec_fd ) close(this->play_fd); this->play_fd = -1; if( this->play_blk >= this->rec_blk ) pvr_report_realtime(this,1); } pthread_mutex_unlock(&this->lock); return (off_t) (this->play_blk - this->page_block[this->first_page]) * PVR_BLOCK_SIZE; } static off_t pvr_plugin_get_current_pos (input_plugin_t *this_gen){ pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; return (off_t) (this->play_blk - this->page_block[this->first_page]) * PVR_BLOCK_SIZE; } static off_t pvr_plugin_get_length (input_plugin_t *this_gen) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; return (off_t) (this->rec_blk - this->page_block[this->first_page]) * PVR_BLOCK_SIZE; } static uint32_t pvr_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return PVR_BLOCK_SIZE; } static const char* pvr_plugin_get_mrl (input_plugin_t *this_gen) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; return this->mrl; } static int pvr_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return INPUT_OPTIONAL_UNSUPPORTED; } static void pvr_plugin_dispose (input_plugin_t *this_gen ) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; void *p; saved_show_t *show; xine_list_iterator_t ite; if( this->pvr_running ) { lprintf("finishing pvr thread\n"); pthread_mutex_lock(&this->lock); this->pvr_running = 0; this->want_data = 0; pthread_cond_signal (&this->wake_pvr); pthread_mutex_unlock(&this->lock); pthread_join (this->pvr_thread, &p); lprintf("pvr thread joined\n"); } if (this->scr) { this->stream->xine->clock->unregister_scr(this->stream->xine->clock, &this->scr->scr); this->scr->scr.exit(&this->scr->scr); } if (this->event_queue) xine_event_dispose_queue (this->event_queue); if (this->dev_fd != -1) close(this->dev_fd); pvr_finish_recording(this); _x_freep (&this->mrl); _x_freep (&this->tmp_prefix); _x_freep (&this->save_prefix); _x_freep (&this->devname); ite = xine_list_front (this->saved_shows); while (ite) { show = xine_list_get_value(this->saved_shows, ite); free (show->base_name); free (show); ite = xine_list_next (this->saved_shows, ite); } xine_list_delete(this->saved_shows); free (this); } static int pvr_plugin_open (input_plugin_t *this_gen ) { pvr_input_plugin_t *this = (pvr_input_plugin_t *) this_gen; int64_t time; int err; struct ivtv_ioctl_codec codec; _x_assert(this->dev_fd == -1); _x_assert(this->pvr_running == 0); this->session = 0; this->rec_fd = -1; this->play_fd = -1; this->first_page = 0; this->show_page = 0; this->save_page = -1; this->input = -1; this->channel = -1; this->pvr_playing = 1; this->preview_buffers = NUM_PREVIEW_BUFFERS; this->saved_id = 0; this->dev_fd = xine_open_cloexec(this->devname, O_RDWR); if (this->dev_fd == -1) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: error opening device %s\n"), this->devname ); return 0; } if (ioctl(this->dev_fd, IVTV_IOC_G_CODEC, &codec) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: IVTV_IOC_G_CODEC failed, maybe API changed?\n")); } else { codec.bitrate_mode = 0; codec.bitrate = 6000000; codec.bitrate_peak = 9000000; codec.stream_type = IVTV_STREAM_DVD; if (ioctl(this->dev_fd, IVTV_IOC_S_CODEC, &codec) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("input_pvr: IVTV_IOC_S_CODEC failed, maybe API changed?\n")); } } /* register our own scr provider */ _x_assert(this->scr == NULL); time = this->stream->xine->clock->get_current_time(this->stream->xine->clock); this->scr = pvrscr_init(); if (!this->scr) return 0; this->scr->scr.start(&this->scr->scr, time); this->stream->xine->clock->register_scr(this->stream->xine->clock, &this->scr->scr); this->scr_tunning = 0; _x_assert(this->event_queue == NULL); this->event_queue = xine_event_new_queue (this->stream); if (!this->event_queue) return 0; /* enable resample method */ this->stream->xine->config->update_num(this->stream->xine->config,"audio.synchronization.av_sync_method",1); this->pvr_running = 1; if ((err = pthread_create (&this->pvr_thread, NULL, pvr_loop, this)) != 0) { xprintf (this->stream->xine, XINE_VERBOSITY_NONE, "input_pvr: can't create new thread (%s)\n", strerror(err)); this->pvr_running = 0; close(this->dev_fd); this->dev_fd = -1; return 0; } return 1; } static input_plugin_t *pvr_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { pvr_input_plugin_t *this; char *aux; if (strncasecmp (data, "pvr:/", 5)) return NULL; this = calloc(1, sizeof (pvr_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->dev_fd = -1; this->mrl = strdup(data); this->max_page_age = 3; aux = &this->mrl[5]; /* decode configuration options from mrl */ if( strlen(aux) ) { this->tmp_prefix = strdup(aux); aux = strchr(this->tmp_prefix,'!'); if( aux ) { aux[0] = '\0'; this->save_prefix = strdup(aux+1); aux = strchr(this->save_prefix, '!'); if( aux ) { aux[0] = '\0'; if( atoi(aux+1) ) this->max_page_age = atoi(aux+1); } } else { this->save_prefix=strdup(this->tmp_prefix); } } else { this->tmp_prefix=strdup("./"); this->save_prefix=strdup("./"); } lprintf("tmp_prefix=%s\n", this->tmp_prefix); lprintf("save_prefix=%s\n", this->save_prefix); lprintf("max_page_age=%d\n", this->max_page_age); this->input_plugin.open = pvr_plugin_open; this->input_plugin.get_capabilities = pvr_plugin_get_capabilities; this->input_plugin.read = pvr_plugin_read; this->input_plugin.read_block = pvr_plugin_read_block; this->input_plugin.seek = pvr_plugin_seek; this->input_plugin.get_current_pos = pvr_plugin_get_current_pos; this->input_plugin.get_length = pvr_plugin_get_length; this->input_plugin.get_blocksize = pvr_plugin_get_blocksize; this->input_plugin.get_mrl = pvr_plugin_get_mrl; this->input_plugin.get_optional_data = pvr_plugin_get_optional_data; this->input_plugin.dispose = pvr_plugin_dispose; this->input_plugin.input_class = cls_gen; this->scr = NULL; this->event_queue = NULL; this->save_name = NULL; this->saved_shows = xine_list_new(); pthread_mutex_init (&this->lock, NULL); pthread_mutex_init (&this->dev_lock, NULL); pthread_cond_init (&this->has_valid_data,NULL); pthread_cond_init (&this->wake_pvr,NULL); { xine_cfg_entry_t dev; if (xine_config_lookup_entry(stream->xine, "media.wintv_pvr.device", &dev) && dev.str_value && strlen(dev.str_value) > 0) { this->devname = strdup(dev.str_value); } else { this->devname = strdup(PVR_DEVICE); } } return &this->input_plugin; } /* * plugin class functions */ static void *init_plugin (xine_t *xine, const void *data) { static const input_class_t input_pvr_class = { .get_instance = pvr_class_get_instance, .identifier = "pvr", .description = N_("WinTV-PVR 250/350 input plugin"), .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)data; xine->config->register_filename(xine->config, "media.wintv_pvr.device", PVR_DEVICE, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for WinTV-PVR 250/350 (pvr plugin)"), _("The path to the device of your WinTV card."), 10, NULL, NULL); return (void *)&input_pvr_class; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "pvr", XINE_VERSION_CODE, NULL, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/vcd/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013366� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/vcd/vcdio.c������������������������������������������������������������������0000644�0001750�0001750�00000017312�14647725152�014642� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: vcdio.c,v 1.9 2007/03/23 21:47:31 dsalt Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Standard includes */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> #include <time.h> #include <string.h> #ifdef HAVE_STRINGS_H #include <strings.h> #endif #include <errno.h> #ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> #endif #ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> #endif #ifdef HAVE_VCDNAV #include <libvcd/types.h> #include <libvcd/files.h> #include <cdio/iso9660.h> #else #include "libvcd/types.h" #include "libvcd/files.h" #include "cdio/iso9660.h" #endif #include "vcdplayer.h" #include "vcdio.h" #define LOG_ERR(p_vcdplayer, s, args...) \ if (p_vcdplayer->log_err) \ p_vcdplayer->log_err (p_vcdplayer->user_data, ~0, "%s: "s, __func__ , ##args) #define dbg_print(p_vcdplayer, mask, s, args...) \ if (p_vcdplayer->log_msg) \ p_vcdplayer->log_msg (p_vcdplayer->user_data, mask, "%s: "s, __func__ , ##args) #define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL; /*! Closes VCD device specified via "this", and also wipes memory of it from it inside "this". */ int vcdio_close(vcdplayer_t *p_vcdplayer) { p_vcdplayer->b_opened = false; FREE_AND_NULL(p_vcdplayer->psz_source); FREE_AND_NULL(p_vcdplayer->track); FREE_AND_NULL(p_vcdplayer->segment); FREE_AND_NULL(p_vcdplayer->entry); return vcdinfo_close(p_vcdplayer->vcd); } /*! Opens VCD device and initializes things. - do nothing if the device had already been open and is the same device. - if the device had been open and is a different, close it before trying to open new device. */ bool vcdio_open(vcdplayer_t *p_vcdplayer, char *intended_vcd_device) { vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; unsigned int i; dbg_print(p_vcdplayer, INPUT_DBG_CALL, "called with %s\n", intended_vcd_device); if ( p_vcdplayer->b_opened ) { if ( strcmp(intended_vcd_device, p_vcdplayer->psz_source)==0 ) { /* Already open and the same device, so do nothing */ return true; } else { /* Changing VCD device */ vcdio_close(p_vcdplayer); } } switch ( vcdinfo_open(&p_vcdplayer->vcd, &intended_vcd_device, DRIVER_UNKNOWN, NULL)) { case VCDINFO_OPEN_ERROR: /* Failed to open the device => return failure */ return false; case VCDINFO_OPEN_VCD: /* Opened the device, and it's a VCD => proceed */ break; default: /* Opened the device, but it's not a VCD => is closed, return failure */ return false; } p_vcdinfo = p_vcdplayer->vcd; p_vcdplayer->psz_source = strdup(intended_vcd_device); p_vcdplayer->b_opened = true; p_vcdplayer->i_lids = vcdinfo_get_num_LIDs(p_vcdinfo); p_vcdplayer->vcd_format = vcdinfo_get_format_version(p_vcdinfo); p_vcdplayer->i_still = 0; if (vcdinfo_read_psd (p_vcdinfo)) { vcdinfo_visit_lot (p_vcdinfo, false); if (VCD_TYPE_VCD2 == p_vcdplayer->vcd_format && vcdinfo_get_psd_x_size(p_vcdinfo)) { vcdinfo_visit_lot (p_vcdinfo, true); } } /* Save summary info on tracks, segments and entries... */ if ( 0 < (p_vcdplayer->i_tracks = vcdinfo_get_num_tracks(p_vcdinfo)) ) { p_vcdplayer->track = (vcdplayer_play_item_info_t *) calloc(p_vcdplayer->i_tracks, sizeof(vcdplayer_play_item_info_t)); if (p_vcdplayer->track) for (i=0; i<p_vcdplayer->i_tracks; i++) { track_t i_track=i+1; p_vcdplayer->track[i].size = vcdinfo_get_track_sect_count(p_vcdinfo, i_track); p_vcdplayer->track[i].start_LSN = vcdinfo_get_track_lsn(p_vcdinfo, i_track); } } else p_vcdplayer->track = NULL; if ( 0 < (p_vcdplayer->i_entries = vcdinfo_get_num_entries(p_vcdinfo)) ) { p_vcdplayer->entry = (vcdplayer_play_item_info_t *) calloc(p_vcdplayer->i_entries, sizeof(vcdplayer_play_item_info_t)); if (p_vcdplayer->entry) for (i=0; i<p_vcdplayer->i_entries; i++) { p_vcdplayer->entry[i].size = vcdinfo_get_entry_sect_count(p_vcdinfo, i); p_vcdplayer->entry[i].start_LSN = vcdinfo_get_entry_lsn(p_vcdinfo, i); } } else p_vcdplayer->entry = NULL; if ( 0 < (p_vcdplayer->i_segments = vcdinfo_get_num_segments(p_vcdinfo)) ) { p_vcdplayer->segment = (vcdplayer_play_item_info_t *) calloc(p_vcdplayer->i_segments, sizeof(vcdplayer_play_item_info_t)); if (p_vcdplayer->segment) for (i=0; i<p_vcdplayer->i_segments; i++) { p_vcdplayer->segment[i].size = vcdinfo_get_seg_sector_count(p_vcdinfo, i); p_vcdplayer->segment[i].start_LSN = vcdinfo_get_seg_lsn(p_vcdinfo, i); } } else p_vcdplayer->segment = NULL; return true; } /*! seek position, return new position if seeking failed, -1 is returned */ off_t vcdio_seek (vcdplayer_t *p_vcdplayer, off_t offset, int origin) { switch (origin) { case SEEK_SET: { lsn_t old_lsn = p_vcdplayer->i_lsn; p_vcdplayer->i_lsn = p_vcdplayer->origin_lsn + (offset / M2F2_SECTOR_SIZE); dbg_print (p_vcdplayer, INPUT_DBG_SEEK_SET, "seek_set to %ld => %u (start is %u)\n", (long int) offset, p_vcdplayer->i_lsn, p_vcdplayer->origin_lsn); /* Seek was successful. Invalidate entry location by setting entry number back to 1. Over time it will adjust upward to the correct value. */ if ( !vcdplayer_pbc_is_on(p_vcdplayer) && p_vcdplayer->play_item.type != VCDINFO_ITEM_TYPE_TRACK && p_vcdplayer->i_lsn < old_lsn) { dbg_print (p_vcdplayer, INPUT_DBG_SEEK_SET, "seek_set entry backwards\n"); p_vcdplayer->next_entry = 1; } break; } case SEEK_CUR: { off_t diff; if (offset) { LOG_ERR(p_vcdplayer, "%s: %d\n", _("SEEK_CUR not implemented for non-zero offset"), (int) offset); return (off_t) -1; } if (p_vcdplayer->slider_length == VCDPLAYER_SLIDER_LENGTH_TRACK) { diff = p_vcdplayer->i_lsn - p_vcdplayer->track_lsn; dbg_print (p_vcdplayer, INPUT_DBG_SEEK_CUR, "current pos: %u, track diff %ld\n", p_vcdplayer->i_lsn, (long int) diff); } else { diff = p_vcdplayer->i_lsn - p_vcdplayer->origin_lsn; dbg_print (p_vcdplayer, INPUT_DBG_SEEK_CUR, "current pos: %u, entry diff %ld\n", p_vcdplayer->i_lsn, (long int) diff); } if (diff < 0) { dbg_print (p_vcdplayer, INPUT_DBG_SEEK_CUR, "Error: diff < 0\n"); return (off_t) 0; } else { return (off_t)diff * M2F2_SECTOR_SIZE; } break; } case SEEK_END: LOG_ERR(p_vcdplayer, "%s\n", _("SEEK_END not implemented yet.")); return (off_t) -1; default: LOG_ERR(p_vcdplayer, "%s %d\n", _("seek not implemented yet for"), origin); return (off_t) -1; } return offset ; /* FIXME */ } /* * Local variables: * c-file-style: "gnu" * tab-width: 8 * indent-tabs-mode: nil * End: */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/vcd/vcdio.h������������������������������������������������������������������0000644�0001750�0001750�00000003414�14647725152�014645� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: vcdio.h,v 1.3 2005/01/08 15:12:42 rockyb Exp $ Copyright (C) 2002, 2004, 2005 Rocky Bernstein <rocky@panix.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef _VCDIO_H_ #define _VCDIO_H_ /*! From xine plugin spec: read nlen bytes, return number of bytes read. */ off_t vcdio_read (vcdplayer_t *p_vcdplayer, char *psz_buf, const off_t nlen); /*! Opens VCD device and initializes things. - do nothing if the device had already been open and is the same device. - if the device had been open and is a different, close it before trying to open new device. */ bool vcdio_open(vcdplayer_t *p_vcdplayer, char *psz_device); /*! Closes VCD device specified via "this", and also wipes memory of it from it inside "this". */ /* FIXME Move player stuff to player. */ int vcdio_close(vcdplayer_t *p_vcdplayer); /*! From xine plugin spec: seek position, return new position if seeking failed, -1 is returned */ off_t vcdio_seek (vcdplayer_t *p_vcdplayer, off_t offset, int origin); #endif /* _VCDIO_H_ */ /* * Local variables: * c-file-style: "gnu" * tab-width: 8 * indent-tabs-mode: nil * End: */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/vcd/xineplug_inp_vcd.c�������������������������������������������������������0000644�0001750�0001750�00000206213�14647725152�017073� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* These are plugin routines called by the xine engine. See Chapter 4. Extending xine's input http://www.xine-project.org/hackersguide#INPUT and the comments in input_plugin.h This is what is referred to below a "the xine plugin spec" Please don't add any OS-specific code in here - #if defined(__sun) or or #if defined(__linux__) are harbingers of such stuff. It took a great deal of effort to get it *out* of here (or most of it); If you feel the need to do so, you are doing something wrong and breaking modularity. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Standard includes */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <ctype.h> #define SHORT_PLUGIN_NAME "VCD" #define MRL_PREFIX "vcd://" #define MRL_PREFIX_LEN (sizeof(MRL_PREFIX) - 1) #define MAX_DEVICE_LEN 1024 #define xine_config_entry_t xine_cfg_entry_t /* Xine includes */ #include <xine/xineutils.h> #include <xine/input_plugin.h> #include <xine/xine_internal.h> #ifdef HAVE_VCDNAV #include <cdio/logging.h> #include <cdio/iso9660.h> #include <cdio/cd_types.h> #include <cdio/version.h> /* libvcd includes */ #include <libvcd/files.h> #include <libvcd/logging.h> #else #include "cdio/logging.h" #include "cdio/iso9660.h" #include "cdio/cd_types.h" /* libvcd includes */ #include "libvcd/files.h" #include "libvcd/logging.h" #endif #include "vcdplayer.h" #include "vcdio.h" /* A xine define. */ #ifndef BUF_DEMUX_BLOCK #define BUF_DEMUX_BLOCK 0x05000000 #endif /* Convert an autoplay enumeration into an vcdinfo itemtype enumeration. See definitions in vcdplayer.h and vcdinfo.h to get the below correct. */ static const vcdinfo_item_enum_t autoplay2itemtype[]={ VCDINFO_ITEM_TYPE_TRACK, /* VCDPLAYER_AUTOPLAY_TRACK */ VCDINFO_ITEM_TYPE_ENTRY, /* VCDPLAYER_AUTOPLAY_ENTRY */ VCDINFO_ITEM_TYPE_SEGMENT, /* VCDPLAYER_AUTOPLAY_SEGMENT */ VCDINFO_ITEM_TYPE_LID /* VCDPLAYER_AUTOPLAY_PBC */ }; typedef struct vcd_config_s { char *title_format; /* Format string of GUI display title */ char *comment_format; /* Format string of stream comment meta */ } vcd_config_t; typedef struct vcd_input_plugin_s vcd_input_plugin_t; typedef struct vcd_input_class_s { input_class_t input_class; xine_t *xine; config_values_t *config; /* Pointer to XineRC config file. */ vcd_input_plugin_t *ip; int inuse; vcd_config_t v_config; /* config stuff passed to child */ xine_mrl_t **mrls; /* list of mrl entries for medium */ int num_mrls; /* count of above */ char *vcd_device;/* Device name to use when none specified in MRL */ /*-------------------------------------------------------------- Media resource locator (MRL) info. For the below offsets, use play_item + mrl_xxx_offset to get index into "mrls" array ---------------------------------------------------------------*/ int mrl_track_offset; /* perhaps -1 for tracks staring with 1*/ int mrl_entry_offset; /* i_tracks for entries starting with 0 */ int mrl_play_offset; /* i_tracks for entries starting with 0 */ int mrl_segment_offset; /* i_tracks + i_entries if segs start 1*/ /* What type to use on autoplay */ vcdplayer_autoplay_t default_autoplay; /* When hitting end of entry or track do we advance automatically to next entry/track or stop? Only valid if PBC is off. */ bool autoadvance; /* Do next/prev wrap around? Only valid if PBC is off. */ bool wrap_next_prev; /* Show and be able to select rejected LIDs? */ bool show_rejected; /* Whether GUI slider is track size or entry size. */ vcdplayer_slider_length_t slider_length; unsigned int vcdplayer_debug; } vcd_input_class_t; struct vcd_input_plugin_s { input_plugin_t input_plugin; /* input plugin interface as defined by by player. For xine it contains a structure of functions that need to be implemented. */ xine_stream_t *stream; xine_event_queue_t *event_queue; time_t pause_end_time; int i_old_still; /* Value of player-i_still before next read. See also i_still in vcdplayer structure. */ int i_old_deinterlace; /* value of deinterlace before entering a still. */ vcd_input_class_t *class; vcd_config_t v_config; /* Config stuff initially inherited */ char *mrl; int32_t i_mouse_button; /* The "button" number associated with the region that the mouse is currently located in. If the mouse is not in any "button" region then this has value -1. */ bool b_mouse_in; /* True if mouse is inside a "button" region; false otherwise */ vcdplayer_t player ; char *player_device; }; /* Prototype definitions */ static bool vcd_handle_events (vcd_input_plugin_t *this); static void vcd_close(vcd_input_class_t *class); #if LIBVCD_VERSION_NUM >= 23 static void send_mouse_enter_leave_event(vcd_input_plugin_t *p_this, bool b_mouse_in); #endif #define msg_print(class, fmt, args...) {\ xprintf ((class)->xine, XINE_VERBOSITY_LOG, "input_vcd: %s: "fmt"\n", __func__, ##args);\ } #define dbg_print(class, mask, fmt, args...) {\ if ((class)->vcdplayer_debug & mask) {\ xprintf ((class)->xine, XINE_VERBOSITY_DEBUG, "input_vcd: %s: "fmt"\n", __func__, ##args);\ }\ } #define error_print(class, fmt, args...) {\ xprintf ((class)->xine, XINE_VERBOSITY_LOG, "input_vcd: %s error: "fmt"\n", __func__, ##args);\ } static int XINE_FORMAT_PRINTF (3, 4) vcd_log_msg (void *user_data, unsigned int mask, const char *fmt, ...) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)user_data; va_list args; if (!(this->player.i_debug & mask)) return 0; va_start (args, fmt); xine_vlog (this->class->xine, XINE_VERBOSITY_DEBUG, fmt, args); va_end (args); return 0; } static int XINE_FORMAT_PRINTF (3, 4) vcd_log_err (void *user_data, unsigned int mask, const char *fmt, ...) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)user_data; va_list args; if (!(this->player.i_debug & mask)) return 0; va_start (args, fmt); xine_vlog (this->class->xine, XINE_VERBOSITY_LOG, fmt, args); va_end (args); return 0; } static void vcd_free_mrls (vcd_input_class_t *class) { if (class->mrls) { int i; for (i = 0; i < class->num_mrls; i++) { if (class->mrls[i]) { free (class->mrls[i]->mrl); free (class->mrls[i]); } } free (class->mrls); class->mrls = NULL; } class->num_mrls = 0; } /* If class->vcd_device is NULL or the empty string, Use libcdio to find a CD drive with a VCD in it. */ static bool vcd_get_default_device(vcd_input_class_t *class, bool log_msg_if_fail) { dbg_print (class, INPUT_DBG_CALL, "Called with %s\n", log_msg_if_fail ? "True" : "False"); if (NULL == class->vcd_device || strlen(class->vcd_device)==0) { char **cd_drives=NULL; cd_drives = cdio_get_devices_with_cap(NULL, (CDIO_FS_ANAL_SVCD|CDIO_FS_ANAL_CVD|CDIO_FS_ANAL_VIDEOCD|CDIO_FS_UNKNOWN), true); if (NULL == cd_drives || NULL == cd_drives[0]) { msg_print (class, "%s", _("failed to find a device with a VCD")); return false; } class->vcd_device = strdup(cd_drives[0]); cdio_free_device_list(cd_drives); #if LIBCDIO_VERSION_NUM <= 72 free(cd_drives); #endif } return true; } static void meta_info_assign (vcd_input_plugin_t *this, int field, xine_stream_t *stream, const char * info) { if (NULL != info) { dbg_print (this->class, INPUT_DBG_META, "meta[%d]: %s\n", field, info); _x_meta_info_set(stream, field, info); } } #define stream_info_assign(field, stream, info) \ _x_stream_info_set(stream, field, info); /* Set stream information. */ static void vcd_set_meta_info (vcd_input_plugin_t *this) { char *tmp; vcdinfo_obj_t *p_vcdinfo= this->player.vcd; if (!this->stream) return; meta_info_assign (this, XINE_META_INFO_ALBUM, this->stream, vcdinfo_get_album_id(p_vcdinfo)); meta_info_assign (this, XINE_META_INFO_ARTIST, this->stream, vcdinfo_get_preparer_id (p_vcdinfo)); tmp = vcdplayer_format_str (&this->player, this->v_config.comment_format); meta_info_assign (this, XINE_META_INFO_COMMENT, this->stream, tmp); free(tmp); meta_info_assign (this, XINE_META_INFO_GENRE, this->stream, vcdinfo_get_format_version_str (p_vcdinfo)); } static void vcd_force_redisplay (void *user_data) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)user_data; if (!this->stream) return; #if 1 this->stream->xine->clock->adjust_clock (this->stream->xine->clock, this->stream->xine->clock->get_current_time (this->stream->xine->clock) + 30 * 90000); #else /* Alternate method that causes too much disruption... */ xine_set_param (this->stream, XINE_PARAM_VO_ASPECT_RATIO, xine_get_param (this->stream, XINE_PARAM_VO_ASPECT_RATIO)); #endif } static void vcd_set_aspect_ratio (void *user_data, int i_aspect_ratio) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)user_data; if (!this->stream) return; /* Alternate method that causes too much disruption... */ xine_set_param (this->stream, XINE_PARAM_VO_ASPECT_RATIO, i_aspect_ratio); } /*! Add another MRL to the MRL list inside "class" to be displayed. mrl is the string name to add; size is the size of the entry in bytes. The number of mrls in "this" is incremented. */ static void vcd_add_mrl_slot(vcd_input_class_t *class, const char *mrl, off_t size, unsigned int *i) { dbg_print (class, INPUT_DBG_MRL, "called to add slot %d: %s, size %u\n", *i, mrl, (unsigned int) size); class->mrls[*i] = malloc(sizeof(xine_mrl_t)); if (NULL==class->mrls[*i]) { error_print (class, "Can't malloc %zu bytes for MRL slot %u (%s)", sizeof(xine_mrl_t), *i, mrl); return; } class->mrls[*i]->link = NULL; class->mrls[*i]->origin = NULL; class->mrls[*i]->type = mrl_vcd; class->mrls[*i]->size = size * M2F2_SECTOR_SIZE; class->mrls[*i]->mrl = strdup(mrl); if (NULL==class->mrls[*i]->mrl) { error_print (class, "Can't strndup %zu bytes for MRL name %s", strlen(mrl), mrl); } (*i)++; } /*! Return the associated mrl_offset for the given type. */ static int vcd_get_mrl_type_offset(vcd_input_plugin_t *inp, vcdinfo_item_enum_t type, int *size) { switch (type) { case VCDINFO_ITEM_TYPE_ENTRY: *size = inp->class->mrl_play_offset - inp->class->mrl_entry_offset + 1; return inp->class->mrl_entry_offset; break; case VCDINFO_ITEM_TYPE_SEGMENT: *size = inp->class->num_mrls - inp->class->mrl_segment_offset - 1; return inp->class->mrl_segment_offset; case VCDINFO_ITEM_TYPE_TRACK: *size = inp->class->mrl_entry_offset; return inp->class->mrl_track_offset; case VCDINFO_ITEM_TYPE_LID: /* Play list number (LID) */ *size = (inp->player.i_lids > 0) ? 1 : 0; return inp->class->mrl_play_offset; case VCDINFO_ITEM_TYPE_NOTFOUND: case VCDINFO_ITEM_TYPE_SPAREID2: default: return -2; } } /*! Create a MRL list inside "class". Any existing MRL list is freed. */ static bool vcd_build_mrl_list(vcd_input_class_t *class, char *vcd_device) { char mrl[MRL_PREFIX_LEN+MAX_DEVICE_LEN+(sizeof("@E")-1)+12]; vcdplayer_t *vcdplayer; unsigned int n, i=0; unsigned int i_entries; vcdinfo_obj_t *p_vcdinfo; int was_open; if (NULL == class) { printf ("vcd_build_mrl_list %s\n", _("was passed a null class parameter")); return false; } vcdplayer = &(class->ip->player); /* If VCD already open, we gotta close and stop it. */ if ((was_open = vcdplayer->b_opened)) { vcd_close(class); } if (NULL == vcd_device) { if (!vcd_get_default_device(class, true)) return false; vcd_device = class->vcd_device; } if (!vcdio_open(vcdplayer, vcd_device)) { /* Error should have been logged in vcdio_open. If not do the below: LOG_ERR(vcdplayer, "%s: %s.\n", _("unable to open"), class->vcd_device, strerror(errno)); */ return false; } free (class->ip->player_device); class->ip->player_device = strdup (vcd_device); p_vcdinfo = vcdplayer->vcd; i_entries = vcdplayer->i_entries; class->mrl_track_offset = -1; vcd_free_mrls (class); /* Figure out number of MRLs. Calculation would be real simple if didn't have to possibly remove rejected LIDs from list done in the loop below. */ class->num_mrls = vcdplayer->i_tracks + vcdplayer->i_entries + vcdplayer->i_segments + vcdplayer->i_lids; if (!vcdplayer->show_rejected && vcdinfo_get_lot(vcdplayer->vcd)) { /* Remove rejected LIDs from count. */ for (n=0; n<vcdplayer->i_lids; n++) { if ( vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n) == PSD_OFS_DISABLED ) class->num_mrls--; } } class->mrls = calloc(class->num_mrls, sizeof(xine_mrl_t *)); if (NULL == class->mrls) { error_print (class, "Can't calloc %d MRL entries", class->num_mrls); class->num_mrls = 0; if (!was_open) vcdio_close(vcdplayer); return false; } /* Record MRL's for tracks */ for (n=1; n<=vcdplayer->i_tracks; n++) { memset(&mrl, 0, sizeof (mrl)); snprintf(mrl, sizeof(mrl), "%s%s@T%u", MRL_PREFIX, vcd_device, n); vcd_add_mrl_slot(class, mrl, vcdplayer->track[n-1].size, &i); } class->mrl_entry_offset = vcdplayer->i_tracks; class->mrl_play_offset = class->mrl_entry_offset + i_entries - 1; /* Record MRL's for entries */ if (i_entries > 0) { for (n=0; n<i_entries; n++) { memset(&mrl, 0, sizeof (mrl)); snprintf(mrl, sizeof(mrl), "%s%s@E%u", MRL_PREFIX, vcd_device, n); vcd_add_mrl_slot(class, mrl, vcdplayer->entry[n].size, &i); } } /* Record MRL's for LID entries or selection entries*/ class->mrl_segment_offset = class->mrl_play_offset; if (vcdinfo_get_lot(vcdplayer->vcd)) { for (n=0; n<vcdplayer->i_lids; n++) { uint16_t ofs = vcdinf_get_lot_offset(vcdinfo_get_lot(vcdplayer->vcd), n); if (ofs != PSD_OFS_DISABLED || vcdplayer->show_rejected) { memset(&mrl, 0, sizeof (mrl)); snprintf(mrl, sizeof(mrl), "%s%s@P%u%s", MRL_PREFIX, vcd_device, n+1, ofs == PSD_OFS_DISABLED ? "*" : ""); vcd_add_mrl_slot(class, mrl, 0, &i); class->mrl_segment_offset++; } } } /* Record MRL's for segments */ { segnum_t i_segments = vcdplayer->i_segments; for (n=0; n<i_segments; n++) { vcdinfo_video_segment_type_t segtype = vcdinfo_get_video_type(p_vcdinfo, n); char c='S'; switch (segtype) { { case VCDINFO_FILES_VIDEO_NTSC_STILL: case VCDINFO_FILES_VIDEO_NTSC_STILL2: case VCDINFO_FILES_VIDEO_NTSC_MOTION: c='s'; break; case VCDINFO_FILES_VIDEO_PAL_STILL: case VCDINFO_FILES_VIDEO_PAL_STILL2: case VCDINFO_FILES_VIDEO_PAL_MOTION: c='S'; break; default: ; } } memset(&mrl, 0, sizeof (mrl)); snprintf(mrl, sizeof(mrl), "%s%s@%c%u", MRL_PREFIX, vcd_device, c, n); vcd_add_mrl_slot(class, mrl, vcdplayer->segment[n].size, &i); } } dbg_print (class, INPUT_DBG_MRL, "offsets are track: %d, entry: %d, play: %d seg: %d\n", class->mrl_track_offset, class->mrl_entry_offset, class->mrl_play_offset, class->mrl_segment_offset); return true; } /*! parses a MRL which has the format vcd://[vcd_path][@[EPTS]?number]\*? Examples vcd:// - Play (navigate) default device: /dev/cdrom vcd://@ - same as above vcd:///dev/cdrom - probably same as above vcd:///dev/cdrom2 - Play (navigate) /dev/cdrom2 vcd:///dev/cdrom2@ - same as above vcd:///dev/cdrom2@T1 - Play Track 1 from /dev/cdrom2 vcd:///dev/cdrom@S1 - Play selection id 1 from /dev/cdrom vcd://dev/cdrom@E0 - Play Entry id 0 from default device vcd://@P1 - probably same as above. If there is no playback control, MRL will get converted into vcd://@E0 vcd://@P1* - probably same as above. vcd://@S0 - Play segment 0 from default device vcd://@3 - Play track 3 from default device vcd:///dev/cdrom2@1 - Play track 1 from /dev/cdrom2 vcd:///tmp/ntsc.bin@ - Play default item from /tmp/ntsc.bin vcd:///tmp/ntsc.bin/@E0 - Play entry 0 of /tmp/ntsc.bin parameters: mrl : mrl to parse default_vcd_device: name of device to use when none given auto_type : type of selection (entry, track, LID) when none given used_default : true iff auto_type was used. */ static bool vcd_parse_mrl(/*in*/ vcd_input_class_t *class, /*in*/ const char *default_vcd_device, /*in*/ const char *mrl, /*out*/ char *device_str, /*out*/ vcdinfo_itemid_t *itemid, /*in */ vcdplayer_autoplay_t auto_type, /*out*/ bool *used_default) { char type_str[2]; int count; const char *p; unsigned int num = 0; dbg_print (class, INPUT_DBG_CALL, "called mrl %s\n", mrl); type_str[0] ='\0'; itemid->type = (vcdinfo_item_enum_t) auto_type; *used_default = false; if ( NULL == mrl || strncasecmp(mrl, MRL_PREFIX, MRL_PREFIX_LEN) ) return false; p = &mrl[MRL_PREFIX_LEN - 2]; while (*p == '/') ++p; device_str[0] = '/'; device_str[1] = 0; count = sscanf (p, "%1023[^@]@%1[EePpSsTt]%u", device_str + 1, type_str, &num); itemid->num = num; switch (count) { case 1: /* Matched device, but nothing beyond that */ if (strlen(device_str)!=0 && device_str[0] != ':') { /* See if we have old-style MRL with no type specifier. If so, we assume "track". */ count = sscanf (p, "%u", &num); itemid->num = num; if (1==count) { type_str[0] = 'T'; if (default_vcd_device) strncpy(device_str, default_vcd_device, MAX_DEVICE_LEN); else *device_str = 0; } else _x_mrl_unescape (device_str); break; } case 2 ... 9: _x_mrl_unescape (device_str); case 0: case EOF: { /* No device/file given, so use the default device and try again. */ if (NULL == default_vcd_device) return false; strncpy(device_str, default_vcd_device, MAX_DEVICE_LEN); if (p[0] == '@') p++; count = sscanf (p, "%1[EePpSsTt]%u", type_str, &num); type_str[0] = toupper(type_str[0]); itemid->num = num; switch (count) { case EOF: /* Default PBC navigation. */ return true; case 0: /* See if we have old-style MRL with no type specifier. If so, we assume "track". */ count = sscanf (p, "%u", &num); if (1==count) { type_str[0] = 'T'; break; } /* Default PBC navigation. */ return true; case 1: /* Type given, but no number. Entries start at 0, other things start at 1 */ if (type_str[0] == 'P' || type_str[0] == 'T') itemid->num = 1; } } } /* We have some sort of track/selection/entry number */ switch (type_str[0]) { case 'E': itemid->type = VCDINFO_ITEM_TYPE_ENTRY; break; case '\0': /* None specified, use config value. */ itemid->type = (vcdinfo_item_enum_t) auto_type; *used_default = true; break; case 'P': itemid->type = VCDINFO_ITEM_TYPE_LID; break; case 'S': itemid->type = VCDINFO_ITEM_TYPE_SEGMENT; break; case 'T': itemid->type = VCDINFO_ITEM_TYPE_TRACK; break; default: ; } if ( 0==itemid->num && ( (VCDINFO_ITEM_TYPE_LID == itemid->type) || (VCDINFO_ITEM_TYPE_TRACK == itemid->type) ) ) itemid->num = 1; return true; } /*! From xine plugin spec: return capabilities of input source */ static uint32_t vcd_plugin_get_capabilities (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; uint32_t ret = INPUT_CAP_AUDIOLANG | INPUT_CAP_BLOCK | INPUT_CAP_CHAPTERS | INPUT_CAP_PREVIEW | (this->player.i_still ? 0: INPUT_CAP_SEEKABLE) | INPUT_CAP_SPULANG; dbg_print (this->class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "returning %d\n", ret); vcd_handle_events (this); return ret; } # if READAHEAD_FINISHED /* If needed, will fill out later... */ static void vcd_read_ahead_cb(void *this_gen, xine_cfg_entry_t *entry) { return; } #endif static void vcd_flush_buffers (void *user_data) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)user_data; if (!this->stream) return; _x_demux_flush_engine (this->stream); } /*! From xine plugin spec: read nlen bytes, return number of bytes read. */ static off_t vcd_plugin_read (input_plugin_t *this_gen, void *vbuf, const off_t nlen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; uint8_t *buf = vbuf; dbg_print (this->class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "Called with nlen %u\n", (unsigned int) nlen); /* FIXME: Tricking the demux_mpeg_block plugin */ buf[0] = 0; buf[1] = 0; buf[2] = 0x01; buf[3] = 0xba; return (off_t) 1; } /* Allocate and return a no-op buffer. This signals the outside to do nothing, but in contrast to returning NULL, it doesn't mean the stream has ended. We use this say for still frames. */ #define RETURN_NOOP_BUF \ p_buf = fifo->buffer_pool_alloc (fifo); \ p_buf->type = BUF_CONTROL_NOP; \ return p_buf /* Handle keyboard events and if there were non which might affect playback, then sleep a little bit and return; */ #define SLEEP_AND_HANDLE_EVENTS \ xine_usec_sleep(50000); \ if (vcd_handle_events (this)) goto read_block; \ RETURN_NOOP_BUF /*! From xine plugin spec: read one block, return newly allocated block (or NULL on failure) for blocked input sources len must be == blocksize the fifo parameter is only used to get access to the buffer_pool_alloc function */ static buf_element_t * vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, const off_t i_len) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; vcdplayer_t *p_vcdplayer = &this->player; buf_element_t *p_buf; uint8_t data[M2F2_SECTOR_SIZE] = {0}; if (fifo == NULL) { dbg_print (this->class, INPUT_DBG_CALL, "NULL fifo"); return NULL; } dbg_print (this->class, INPUT_DBG_CALL, "Called with i_len %u\n", (unsigned int) i_len); /* Should we change this to <= instead of !=? */ if (i_len != M2F2_SECTOR_SIZE) return NULL; /* If VCD isn't open, we need to open it now. */ if (!p_vcdplayer->b_opened) { if (!vcdio_open(p_vcdplayer, this->player_device)) { return NULL; } } if (vcd_handle_events (this)) goto read_block; if (p_vcdplayer->i_still > 0) { if ( time(NULL) >= this->pause_end_time ) { if (STILL_INDEFINITE_WAIT == p_vcdplayer->i_still) { dbg_print (this->class, INPUT_DBG_STILL, "Continuing still indefinite wait time\n"); this->pause_end_time = time(NULL) + p_vcdplayer->i_still; SLEEP_AND_HANDLE_EVENTS; } else { dbg_print (this->class, INPUT_DBG_STILL, "Still time ended\n"); p_vcdplayer->i_still = 0; } } else { SLEEP_AND_HANDLE_EVENTS; } } read_block: switch (vcdplayer_read(p_vcdplayer, data, i_len)) { case READ_END: /* End reached. Return NULL to indicated this. */ return NULL; case READ_ERROR: /* Some sort of error. */ return NULL; case READ_STILL_FRAME: { dbg_print (this->class, INPUT_DBG_STILL, "Handled still event wait time %u\n", p_vcdplayer->i_still); this->pause_end_time = time(NULL) + p_vcdplayer->i_still; RETURN_NOOP_BUF; } default: case READ_BLOCK: /* Read buffer */ p_buf = fifo->buffer_pool_alloc (fifo); p_buf->type = BUF_DEMUX_BLOCK; } p_buf->content = p_buf->mem; if (STILL_READING == p_vcdplayer->i_still && 0 == this->i_old_still) { this->i_old_deinterlace = xine_get_param (this->stream, XINE_PARAM_VO_DEINTERLACE); xine_set_param (this->stream, XINE_PARAM_VO_DEINTERLACE, 0); dbg_print (this->class, INPUT_DBG_STILL, "going into still, saving deinterlace %d\n", this->i_old_deinterlace); } else if (0 == p_vcdplayer->i_still && 0 != this->i_old_still) { dbg_print (this->class, INPUT_DBG_STILL, "going out of still, restoring deinterlace\n"); xine_set_param (this->stream, XINE_PARAM_VO_DEINTERLACE, this->i_old_deinterlace); } this->i_old_still = p_vcdplayer->i_still; /* Ideally this should probably be i_len. */ memcpy (p_buf->mem, data, M2F2_SECTOR_SIZE); return p_buf; } /*! From xine plugin spec: seek position, return new position if seeking failed, -1 is returned */ static off_t vcd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; return vcdio_seek (&this->player, offset, origin); } /*! From xine plugin spec: return length of input (-1 => unlimited, e.g. stream) length size is bytes. */ static vcdinfo_itemid_t old_play_item = {VCDINFO_ITEM_TYPE_NOTFOUND, 0}; static off_t old_get_length = 0; static vcdplayer_slider_length_t old_slider_length; /* This routine is called a bit. Make reasonably fast. */ static off_t vcd_plugin_get_length (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; vcdplayer_t *vcdplayer = &(this->player); int n = vcdplayer->play_item.num; if (vcdplayer->play_item.num == old_play_item.num && vcdplayer->play_item.type == old_play_item.type && vcdplayer->slider_length == old_slider_length) return old_get_length; old_slider_length = vcdplayer->slider_length; old_play_item = vcdplayer->play_item; switch (vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: switch (vcdplayer->slider_length) { case VCDPLAYER_SLIDER_LENGTH_AUTO: case VCDPLAYER_SLIDER_LENGTH_ENTRY: n += this->class->mrl_entry_offset; break; case VCDPLAYER_SLIDER_LENGTH_TRACK: n = vcdinfo_get_track(vcdplayer->vcd, n) + this->class->mrl_track_offset; break; default: /* FIXME? */ return -1; } break; case VCDINFO_ITEM_TYPE_TRACK: n += this->class->mrl_track_offset; break; case VCDINFO_ITEM_TYPE_SEGMENT: n += this->class->mrl_segment_offset; break; case VCDINFO_ITEM_TYPE_LID: /* This is the only situation where the size of the current play item is not static. It depends what the current play-item is. */ old_get_length = (vcdplayer->end_lsn - vcdplayer->origin_lsn) * M2F2_SECTOR_SIZE; return old_get_length; break; case VCDINFO_ITEM_TYPE_NOTFOUND: case VCDINFO_ITEM_TYPE_SPAREID2: default: /* FIXME? */ return -1; } if (n >= 0 && n < this->class->num_mrls) { old_get_length = this->class->mrls[n]->size; dbg_print (this->class, INPUT_DBG_MRL, "item: %u, slot %u, size %ld\n", vcdplayer->play_item.num, (unsigned int) n, (long int) old_get_length); } return old_get_length; } /*! * From xine plugin spec: * get current position in stream. * */ static off_t vcd_plugin_get_current_pos (input_plugin_t *this_gen){ // trace_print("Called\n"); return (vcd_plugin_seek (this_gen, 0, SEEK_CUR)); } /*! * From xine plugin spec: * return block size of input source (if supported, 0 otherwise) */ static uint32_t vcd_plugin_get_blocksize (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; dbg_print (this->class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); return M2F2_SECTOR_SIZE; } /*! From xine plugin spec: ls function return value: NULL => filename is a file, **char=> filename is a dir -- This list returned forms the entries of the GUI MRL "browser". */ static xine_mrl_t ** vcd_class_get_dir (input_class_t *this_gen, const char *filename, int *num_files) { char intended_vcd_device[MAX_DEVICE_LEN+1]= { '\0', }; vcdinfo_itemid_t itemid; vcd_input_class_t *class = (vcd_input_class_t *) this_gen; vcdplayer_t *vcdplayer; bool used_default; if (!class->ip) { if (!this_gen->get_instance (this_gen, NULL, MRL_PREFIX) || !class->ip) { *num_files = 0; return NULL; } } vcdplayer = &class->ip->player; if (filename == NULL) { dbg_print (class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called with NULL\n"); if ( class->mrls != NULL && NULL != class->mrls[0] ) goto have_mrls; if ( !vcd_build_mrl_list(class, vcdplayer->psz_source) ) { goto no_mrls; } } else { char *mrl; dbg_print (class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called with %s\n", filename); if (!vcd_get_default_device(class, true)) goto no_mrls; mrl = strdup(filename); if (!vcd_parse_mrl(class, class->vcd_device, mrl, intended_vcd_device, &itemid, vcdplayer->default_autoplay, &used_default)) { free (mrl); goto no_mrls; } free (mrl); } have_mrls: *num_files = class->num_mrls; return class->mrls; no_mrls: *num_files = 0; return NULL; } #define FREE_AND_NULL(ptr) if (NULL != ptr) free(ptr); ptr = NULL; static void vcd_close(vcd_input_class_t *class) { vcd_free_mrls (class); if (class->ip) { FREE_AND_NULL (class->ip->mrl); if (class->ip->player.b_opened) vcdio_close (&class->ip->player); } } /*! * From plugin xine spec: * eject/load the media (if it's possible) * * returns 0 for temporary failures */ static int vcd_class_eject_media (input_class_t *this_gen) { vcd_input_class_t *class = (vcd_input_class_t *)this_gen; int ret; CdIo_t *cdio; if (!class->ip) { this_gen->get_instance (this_gen, NULL, MRL_PREFIX); if (!class->ip) return 0; } cdio = vcdinfo_get_cd_image (class->ip->player.vcd); dbg_print (class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); if (NULL == cdio) return 0; ret = cdio_eject_media(&cdio); if ((ret == 0) || (ret == 2)) { if (class->ip->player.b_opened) vcdio_close(&class->ip->player); return 1; } else return 0; } /*! * From spec: * return current MRL */ static const char * vcd_plugin_get_mrl (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; vcdplayer_t *vcdplayer = &this->player; int n; int size; /* need something to feed get_mrl_type_offset */ int offset; if (vcdplayer_pbc_is_on(vcdplayer)) { n = vcdplayer->i_lid; offset = vcd_get_mrl_type_offset(this, VCDINFO_ITEM_TYPE_LID, &size); } else { n = vcdplayer->play_item.num; offset = vcd_get_mrl_type_offset(this, vcdplayer->play_item.type, &size); } if (-2 == offset) { /* Bad type. */ error_print (this->class, "%s %d", _("Invalid current entry type"), vcdplayer->play_item.type); return ""; } else { n += offset; if (n < this->class->num_mrls) { dbg_print (this->class, INPUT_DBG_CALL, "Called, returning %s\n", this->class->mrls[n]->mrl); return this->class->mrls[n]->mrl; } else { return ""; } } } /* Handle all queued keyboard/mouse events. Return TRUE if this causes a change in the play item. */ static bool vcd_handle_events (vcd_input_plugin_t *this) { vcdplayer_t *p_vcdplayer = &this->player; xine_event_t *p_event; int digit_entered=0; /* What you add to the last input number entry. It accumulates all of the 10_ADD keypresses */ static unsigned int number_addend = 0; if (!this->event_queue) return false; while ((p_event = xine_event_get (this->event_queue))) { dbg_print (this->class, (INPUT_DBG_CALL), "processing %d\n", p_event->type ); digit_entered=0; switch(p_event->type) { case XINE_EVENT_INPUT_NUMBER_10_ADD: number_addend += 10; dbg_print (this->class, INPUT_DBG_EVENT, "10 added to number. Is now: %d\n", number_addend); break; /* The method used below is oblivious to XINE_EVENT_INPUT encodings In particular, it does not assume XINE_EVENT_INPUT_NUMBE_9 = XINE_EVENT_INPUT_NUMBER_0 + 9. */ case XINE_EVENT_INPUT_NUMBER_9: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_8: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_7: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_6: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_5: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_4: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_3: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_2: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_1: digit_entered++; /* fall through */ case XINE_EVENT_INPUT_NUMBER_0: { number_addend *= 10; number_addend += digit_entered; dbg_print (this->class, INPUT_DBG_EVENT, "digit added number is now: %d\n", number_addend); break; } case XINE_EVENT_INPUT_MENU3: dbg_print (this->class, INPUT_DBG_EVENT, "menu3 setting debug: %d\n", number_addend); this->class->vcdplayer_debug = this->player.i_debug = number_addend; number_addend = 0; break; case XINE_EVENT_INPUT_MENU1: case XINE_EVENT_INPUT_MENU2: case XINE_EVENT_INPUT_NEXT: case XINE_EVENT_INPUT_PREVIOUS: if (this->stream) { int num = number_addend; vcdinfo_itemid_t itemid; number_addend = 0; /* If no number was given it's really the same as 1, not 0. */ if (num == 0) num++; dbg_print (this->class, INPUT_DBG_EVENT, "RETURN/NEXT/PREV/DEFAULT (%d) iteration count %d\n", p_event->type, num); for ( ; num > 0; num--) { itemid = p_vcdplayer->play_item; switch (p_event->type) { case XINE_EVENT_INPUT_MENU1: if (p_vcdplayer->return_entry == VCDINFO_INVALID_ENTRY) { msg_print (this->class, "%s\n", _("selection has no RETURN entry")); return false; } itemid.num = p_vcdplayer->return_entry; dbg_print (this->class, (INPUT_DBG_PBC|INPUT_DBG_EVENT), "RETURN to %d\n", itemid.num); /* Don't loop around -- doesn't make sense to loop a return*/ num = 0; break; case XINE_EVENT_INPUT_MENU2: if (vcdplayer_pbc_is_on(p_vcdplayer)) { lid_t lid=vcdinfo_get_multi_default_lid(p_vcdplayer->vcd, p_vcdplayer->i_lid, p_vcdplayer->i_lsn); if (VCDINFO_INVALID_LID != lid) { itemid.num = lid; dbg_print (this->class, (INPUT_DBG_PBC|INPUT_DBG_EVENT), "DEFAULT to %d\n", itemid.num); } else { dbg_print (this->class, (INPUT_DBG_PBC|INPUT_DBG_EVENT), "no DEFAULT for LID %d\n", p_vcdplayer->i_lid); } /* Don't loop around -- doesn't make sense to loop a return*/ num = 0; } else { /* PBC is not on. "default" selection beginning of current selection . Alternative: */ msg_print (this->class, "%s\n", _("DEFAULT selected, but PBC is not on.")); } break; case XINE_EVENT_INPUT_NEXT: if (p_vcdplayer->next_entry == VCDINFO_INVALID_ENTRY) { msg_print (this->class, "%s\n", _("selection has no NEXT entry")); return false; } itemid.num = p_vcdplayer->next_entry; dbg_print (this->class, INPUT_DBG_PBC, "NEXT to %d\n", itemid.num); break; case XINE_EVENT_INPUT_PREVIOUS: if (p_vcdplayer->prev_entry == VCDINFO_INVALID_ENTRY) { msg_print (this->class, "%s\n", _("selection has no PREVIOUS entry")); return false; } itemid.num = p_vcdplayer->prev_entry; dbg_print (this->class, INPUT_DBG_PBC, "PREVIOUS to %d\n", itemid.num); break; default: msg_print (this->class, "%s %d\n", _("Unknown event type: "), p_event->type); } _x_demux_flush_engine (this->stream); vcdplayer_play(p_vcdplayer, itemid); return true; } } break; case XINE_EVENT_INPUT_SELECT: if (this->stream) { /* In the future will have to test to see if we are in a menu selection. But if not... */ vcdinfo_itemid_t itemid = p_vcdplayer->play_item; itemid.num = number_addend; number_addend = 0; if (vcdplayer_pbc_is_on(p_vcdplayer)) { lid_t i_next=vcdinfo_selection_get_lid(p_vcdplayer->vcd, p_vcdplayer->i_lid, itemid.num); if (VCDINFO_INVALID_LID != i_next) { itemid.num = i_next; _x_demux_flush_engine (this->stream); vcdplayer_play(p_vcdplayer, itemid); return true; } } } break; case XINE_EVENT_INPUT_MOUSE_BUTTON: if (this->stream) { xine_input_data_t *p_input = p_event->data; if (p_input->button == 1) { #if LIBVCD_VERSION_NUM >= 23 int i_selection; #endif dbg_print (this->class, INPUT_DBG_EVENT, "Button to x: %d, y: %d, scaled x: %d, scaled y %d\n", p_input->x, p_input->y, p_input->x * 255 / p_vcdplayer->max_x, p_input->y * 255 / p_vcdplayer->max_y); #if LIBVCD_VERSION_NUM >= 23 /* xine_dvd_send_button_update(this, 1); */ if (this->b_mouse_in) send_mouse_enter_leave_event (this, false); i_selection = vcdinfo_get_area_selection(p_vcdplayer->vcd, p_vcdplayer->i_lid, p_input->x, p_input->y, p_vcdplayer->max_x, p_vcdplayer->max_y); dbg_print (this->class, INPUT_DBG_EVENT, "Selection is: %d\n", i_selection); if (vcdplayer_pbc_is_on(p_vcdplayer)) { vcdinfo_itemid_t itemid = p_vcdplayer->play_item; lid_t i_next=vcdinfo_selection_get_lid(p_vcdplayer->vcd, p_vcdplayer->i_lid, i_selection); if (VCDINFO_INVALID_LID != i_next) { itemid.num = i_next; _x_demux_flush_engine (this->stream); vcdplayer_play(p_vcdplayer, itemid); return true; } } #endif } } break; case XINE_EVENT_INPUT_BUTTON_FORCE: break; case XINE_EVENT_INPUT_MOUSE_MOVE: if (this->stream) { xine_input_data_t *p_input = p_event->data; #if LIBVCD_VERSION_NUM >= 23 int32_t i_selection = vcdinfo_get_area_selection(p_vcdplayer->vcd, p_vcdplayer->i_lid, p_input->x, p_input->y, p_vcdplayer->max_x, p_vcdplayer->max_y); dbg_print (this->class, INPUT_DBG_EVENT, "Move to x: %d, y: %d\n", p_input->x, p_input->y); if (this->i_mouse_button != i_selection) { dbg_print (this->class, INPUT_DBG_EVENT, "Old selection: %d, selection: %d\n", this->i_mouse_button, i_selection); this->i_mouse_button = i_selection; if (i_selection < 0) send_mouse_enter_leave_event (this, false); else send_mouse_enter_leave_event (this, true); } #else dbg_print (this->class, INPUT_DBG_EVENT, "Move to x: %d, y: %d\n", p_input->x, p_input->y); #endif } break; case XINE_EVENT_INPUT_UP: dbg_print (this->class, INPUT_DBG_EVENT, "Called with up\n"); vcdplayer_send_button_update(p_vcdplayer, 0); break; case XINE_EVENT_INPUT_DOWN: dbg_print (this->class, INPUT_DBG_EVENT, "Called with down\n"); vcdplayer_send_button_update(p_vcdplayer, 0); break; case XINE_EVENT_INPUT_LEFT: dbg_print (this->class, INPUT_DBG_EVENT, "Called with left\n"); vcdplayer_send_button_update(p_vcdplayer, 0); break; case XINE_EVENT_INPUT_RIGHT: dbg_print (this->class, INPUT_DBG_EVENT, "Called with right\n"); vcdplayer_send_button_update(p_vcdplayer, 0); break; } } return false; } /*! From xine plugin spec: request optional data from input plugin. */ static int vcd_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; dbg_print (this->class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called with %d\n", data_type); if (NULL == this->stream) return INPUT_OPTIONAL_UNSUPPORTED; /* Fill this out more fully... */ switch(data_type) { case INPUT_OPTIONAL_DATA_AUDIOLANG: { uint8_t channel; channel = _x_get_audio_channel(this->stream); dbg_print (this->class, INPUT_DBG_EXT, "AUDIO CHANNEL = %d\n", channel); if (channel == (uint8_t)-1) { strcpy(data, "auto"); } else { const vcdinfo_obj_t *p_vcdinfo= this->player.vcd; unsigned int audio_type; unsigned int num_channels; unsigned int track_num = this->player.i_track; audio_type = vcdinfo_get_track_audio_type(p_vcdinfo, track_num); num_channels = vcdinfo_audio_type_num_channels(p_vcdinfo, audio_type); if (channel >= num_channels) { sprintf(data, "%d ERR", channel); } else { sprintf(data, "%1d", channel); } } return INPUT_OPTIONAL_SUCCESS; } case INPUT_OPTIONAL_DATA_SPULANG: { /*uint16_t lang;*/ int8_t channel; channel = (int8_t) _x_get_spu_channel(this->stream); dbg_print (this->class, INPUT_DBG_EXT, "SPU CHANNEL = %d\n", channel); if (-1 == channel) { strcpy(data, "auto"); } else { sprintf(data, "%1d", channel); } } default: ; } return INPUT_OPTIONAL_UNSUPPORTED; } /* Array to hold MRLs returned by get_autoplay_list */ #define MAX_DIR_ENTRIES 250 /*! From xine plugin spec: generate autoplay list return value: list of MRLs -- The list of MRLs returned goes into the playlist. This is called when the SHORT_PLUGIN_NAME button is pressed. */ static const char * const * vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { vcd_input_class_t *class = (vcd_input_class_t *) this_gen; static char *filelist[MAX_DIR_ENTRIES]; dbg_print (class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); if (!class->ip) { if (!this_gen->get_instance (this_gen, NULL, MRL_PREFIX) || !class->ip) { *num_files = 0; return NULL; } } if ( !vcd_build_mrl_list(class, class->ip->player.psz_source) ) { *num_files = 0; return NULL; } else { int i; int size = 0; vcdinfo_item_enum_t itemtype = autoplay2itemtype[class->ip->player.default_autoplay]; int offset = vcd_get_mrl_type_offset(class->ip, itemtype, &size); /* A VCD is not required to have PBC or LID's, default to entry if this is the case... */ if (VCDINFO_ITEM_TYPE_LID == itemtype && size==0) { itemtype=VCDINFO_ITEM_TYPE_ENTRY; offset = vcd_get_mrl_type_offset(class->ip, itemtype, &size); } /* This is because entries start at 0 while other playable units start at 1. Can remove the below when everything has the same origin. */ if (VCDINFO_ITEM_TYPE_ENTRY != itemtype) offset++; for (i=0; i<size; i++) { if (class->mrls[offset+i] != NULL) { filelist[i] = class->mrls[offset+i]->mrl; dbg_print (class, (INPUT_DBG_MRL), "filelist[%d]: %s\n", i, filelist[i]); } else { filelist[i] = NULL; dbg_print (class, (INPUT_DBG_MRL), "filelist[%d]: NULL\n", i); } } *num_files = i; return (const char * const *)filelist; } } /*! Things that need to be done when a stream is closed. */ static void vcd_plugin_dispose (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; dbg_print (this->class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); this->stream = NULL; if (this->player.b_opened) vcdio_close(&this->player); free (this->player_device); this->player_device = NULL; this->class->inuse = 0; } /* Pointer to vcdimager default log handler. Set by init_input_plugin routine. Perhaps can remove. */ static vcd_log_handler_t gl_default_vcd_log_handler = NULL; static cdio_log_handler_t gl_default_cdio_log_handler = NULL; /*! This routine is called by libvcd routines on error. Setup is done by init_input_plugin. */ static void vcd_log_handler (vcd_log_level_t level, const char message[]) { const char *kind; switch (level) { case VCD_LOG_DEBUG: kind = "debug"; break; case VCD_LOG_INFO: kind = "info"; break; case VCD_LOG_WARN: kind = "warning"; break; case VCD_LOG_ERROR: kind = "error"; break; case VCD_LOG_ASSERT: kind = "assert"; break; default: kind = "(unknown level)"; } printf ("input_vcd: vcd_log_handler: %s: %s\n", kind, message); } /*! This routine is called by libcdio routines on error. Setup is done by init_input_plugin. */ static void cdio_log_handler (cdio_log_level_t level, const char message[]) { const char *kind; switch (level) { case VCD_LOG_DEBUG: kind = "debug"; break; case VCD_LOG_INFO: kind = "info"; break; case VCD_LOG_WARN: kind = "warning"; break; case VCD_LOG_ERROR: kind = "error"; break; case VCD_LOG_ASSERT: kind = "assert"; break; default: kind = "(unknown level)"; } printf ("input_vcd: cdio_log_handler: %s: %s\n", kind, message); } /*! This routine is when xine is not around. Setup is done by vcd_class_dispose. */ static void uninit_log_handler (vcd_log_level_t level, const char message[]) { const char *kind; switch (level) { case VCD_LOG_DEBUG: kind = "debug"; break; case VCD_LOG_INFO: kind = "info"; break; case VCD_LOG_WARN: kind = "warning"; break; case VCD_LOG_ERROR: kind = "error"; break; case VCD_LOG_ASSERT: kind = "assert"; break; default: kind = "(unknown level)"; } printf ("input_vcd: uninit_log_handler: %s: %s\n", kind, message); } /*! Things that need to be done the vcd plugin is closed. */ static void vcd_class_dispose (input_class_t *this_gen) { vcd_input_class_t *class = (vcd_input_class_t *) this_gen; config_values_t *config = class->xine->config; config->unregister_callback(config, "media.vcd.autoplay"); config->unregister_callback(config, "media.vcd.device"); config->unregister_callback(config, "media.vcd.length_reporting"); config->unregister_callback(config, "media.vcd.autoadvance"); config->unregister_callback(config, "media.vcd.show_rejected"); config->unregister_callback(config, "media.vcd.title_format"); config->unregister_callback(config, "media.vcd.comment_format"); config->unregister_callback(config, "media.vcd.debug"); gl_default_vcd_log_handler = vcd_log_set_handler (uninit_log_handler); gl_default_cdio_log_handler = cdio_log_set_handler ((cdio_log_handler_t) uninit_log_handler); dbg_print (class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called\n"); vcd_close(class); if (class->ip) { vcd_input_plugin_t *this = class->ip; this->stream = NULL; free (this->player_device); class->ip = NULL; free (this); } class->inuse = 0; free(class->vcd_device); free(class->v_config.title_format); free(class->v_config.comment_format); free(class); } /* Update the xine player title text. */ static void vcd_update_title_display (void *user_data) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)user_data; xine_event_t uevent; xine_ui_data_t data; char *title_str, *tmp; if (!this->stream) return; title_str = vcdplayer_format_str (&this->player, this->v_config.title_format); meta_info_assign (this, XINE_META_INFO_TITLE, this->stream, title_str); tmp = vcdplayer_format_str (&this->player, this->class->v_config.comment_format); meta_info_assign (this, XINE_META_INFO_COMMENT, this->stream, tmp); free(tmp); stream_info_assign (XINE_STREAM_INFO_VIDEO_HAS_STILL, this->stream, this->player.i_still); /* Set_str title/chapter display */ dbg_print (this->class, (INPUT_DBG_MRL|INPUT_DBG_CALL), "Changing title to read '%s'\n", title_str); uevent.type = XINE_EVENT_UI_SET_TITLE; uevent.stream = this->stream; uevent.data = &data; uevent.data_length = sizeof(data); memcpy(data.str, title_str, strlen(title_str) + 1); data.str_len = strlen(title_str) + 1; xine_event_send (this->stream, &uevent); free(title_str); } #if LIBVCD_VERSION_NUM >= 23 static void send_mouse_enter_leave_event(vcd_input_plugin_t *p_this, bool b_mouse_in) { if (b_mouse_in && p_this->b_mouse_in) { /* Set up to enter the following "if" statement. */ p_this->b_mouse_in = false; } if (b_mouse_in != p_this->b_mouse_in) { xine_event_t event; xine_spu_button_t spu_event; spu_event.direction = b_mouse_in ? 1 : 0; spu_event.button = p_this->i_mouse_button; event.type = XINE_EVENT_SPU_BUTTON; event.stream = p_this->stream; event.data = &spu_event; event.data_length = sizeof(spu_event); xine_event_send(p_this->stream, &event); p_this->b_mouse_in = b_mouse_in; } if (!b_mouse_in) p_this->i_mouse_button = -1; } #endif /* Not much special initialization needed here. All of the initialization is either done in the class or when we have an actual MRL we want to deal with. */ static int vcd_plugin_open (input_plugin_t *this_gen ) { vcd_input_plugin_t *this = (vcd_input_plugin_t *)this_gen; vcd_input_class_t *class = (vcd_input_class_t *) this_gen->input_class; gl_default_vcd_log_handler = vcd_log_set_handler (vcd_log_handler); gl_default_cdio_log_handler = cdio_log_set_handler (cdio_log_handler); /* actually, this is also done by class initialization. But just in case... */ class->ip = this; this->i_old_still = 0; return 1; } /*! This basically sets up stream specified by MRL for playing. After this routine is called, xine-lib can read blocks from the thing specified by the MRL, set the position of the thing specified by the MRL, get its size or read its current position... See vcdplayer_parses_mrl for the for the format that a valid MRL can take. Return values: pointer to input plugin NULL on failure */ static input_plugin_t * vcd_class_get_instance (input_class_t *class_gen, xine_stream_t *stream, const char *mrl) { vcd_input_class_t *class = (vcd_input_class_t *) class_gen; vcd_input_plugin_t *this; vcdinfo_itemid_t itemid; bool used_default; dbg_print (class, (INPUT_DBG_CALL|INPUT_DBG_EXT), "called with %s\n", mrl); if (!mrl) mrl = MRL_PREFIX; if (strncasecmp (mrl, MRL_PREFIX, MRL_PREFIX_LEN)) return NULL; if (class->ip) { if (class->inuse) return NULL; this = class->ip; this->stream = NULL; if (this->player.b_opened) vcdio_close (&this->player); free (this->player_device); this->player_device = NULL; } else { this = calloc (1, sizeof (*this)); if (!this) return NULL; } /*------------------------------------------------------------------ Callback functions. ---------------------------------------------------------------------*/ this->player.user_data = this; this->player.flush_buffers = &vcd_flush_buffers; this->player.update_title = &vcd_update_title_display; this->player.log_err = (debug_fn) &vcd_log_err; this->player.log_msg = (debug_fn) &vcd_log_msg; this->player.force_redisplay = &vcd_force_redisplay; this->player.set_aspect_ratio = &vcd_set_aspect_ratio; /*------------------------------------------------------------- Playback control-specific fields --------------------------------------------------------------*/ this->player.i_lid = VCDINFO_INVALID_ENTRY; this->player.end_lsn = VCDINFO_NULL_LSN; this->player.pdi = -1; this->player.pxd.psd = NULL; /*----------------------------------- Navigation fields ------------------------------------*/ this->player.next_entry = -1; this->player.prev_entry = -1; this->player.return_entry = -1; this->player.default_entry = -1; /*----------------------------------- Config items ------------------------------------*/ this->player.default_autoplay = class->default_autoplay; this->player.autoadvance = class->autoadvance; this->player.wrap_next_prev = class->wrap_next_prev; this->player.show_rejected = class->show_rejected; this->player.slider_length = class->slider_length; this->v_config = class->v_config; this->player.i_debug = class->vcdplayer_debug; this->input_plugin.open = vcd_plugin_open; this->input_plugin.get_capabilities = vcd_plugin_get_capabilities; this->input_plugin.read = vcd_plugin_read; this->input_plugin.read_block = vcd_plugin_read_block; this->input_plugin.seek = vcd_plugin_seek; this->input_plugin.get_current_pos = vcd_plugin_get_current_pos; this->input_plugin.get_length = vcd_plugin_get_length; this->input_plugin.get_blocksize = vcd_plugin_get_blocksize; this->input_plugin.get_mrl = vcd_plugin_get_mrl; this->input_plugin.get_optional_data = vcd_get_optional_data; this->input_plugin.dispose = vcd_plugin_dispose; this->input_plugin.input_class = (input_class_t *) class; if (stream == XINE_ANON_STREAM) stream = NULL; this->stream = stream; this->class = class; this->i_mouse_button = -1; this->b_mouse_in = false; this->player.psz_source = NULL; this->player.b_opened = false; this->player.play_item.num = VCDINFO_INVALID_ENTRY; this->player.play_item.type = VCDINFO_ITEM_TYPE_ENTRY; this->player_device = NULL; vcd_get_default_device(class, false); { char intended_vcd_device[MAX_DEVICE_LEN+1] = { '\0', }; if (!vcd_parse_mrl (class, class->vcd_device, mrl, intended_vcd_device, &itemid, this->player.default_autoplay, &used_default)) { dbg_print (class, INPUT_DBG_MRL, "parsing MRL %s failed\n", mrl); return NULL; } free (this->mrl); this->mrl = strdup (mrl); if (this->stream) this->event_queue = xine_event_new_queue (stream); class->ip = this; if (!vcd_build_mrl_list (class, intended_vcd_device)) return NULL; } /* Do we set PBC (via LID) on? */ this->player.i_lid = ( VCDINFO_ITEM_TYPE_LID == itemid.type && this->player.i_lids > itemid.num ) ? itemid.num : VCDINFO_INVALID_ENTRY; if ( VCDINFO_ITEM_TYPE_LID == itemid.type && used_default) { /* LID was selected automatically but we don't have PBC for this VCD. So silently change LID to track and continue. */ itemid.type=VCDINFO_ITEM_TYPE_TRACK; } if ( 0==itemid.num && ( (VCDINFO_ITEM_TYPE_LID == itemid.type) || (VCDINFO_ITEM_TYPE_TRACK == itemid.type) ) ) itemid.num = 1; dbg_print (class, INPUT_DBG_PBC, "Jumping to NUM >%i<, type >%i<\n", itemid.num, itemid.type); vcd_set_meta_info (this); vcdplayer_play(&this->player, itemid); dbg_print (class, INPUT_DBG_MRL, "Successfully opened MRL %s.\n", this->mrl); if (this->stream) class->inuse = 1; return &(this->input_plugin); } #define VCD_NUM_CALLBACK(fn_name, var) \ static void fn_name (void *this_gen, xine_cfg_entry_t *entry) {\ vcd_input_class_t *class = (vcd_input_class_t *)this_gen;\ dbg_print (class, INPUT_DBG_CALL, "Called setting %d\n", entry->num_value);\ class->var = entry->num_value;\ } #define VCD_ENUM_CALLBACK(fn_name, enum_type, var) \ static void fn_name (void *this_gen, xine_cfg_entry_t *entry) {\ vcd_input_class_t *class = (vcd_input_class_t *)this_gen;\ dbg_print (class, INPUT_DBG_CALL, "Called setting %d\n", entry->num_value);\ class->var = (enum_type)entry->num_value;\ } #define VCD_STR_CALLBACK(fn_name, var) \ static void fn_name (void *this_gen, xine_cfg_entry_t *entry) {\ vcd_input_class_t *class = (vcd_input_class_t *)this_gen;\ dbg_print (class, INPUT_DBG_CALL, "Called setting %s\n", entry->str_value);\ if (NULL == entry->str_value) return;\ free (class->var);\ class->var = strdup (entry->str_value);\ } VCD_STR_CALLBACK (vcd_default_dev_changed_cb, vcd_device) VCD_STR_CALLBACK (vcd_title_format_changed_cb, v_config.title_format) VCD_STR_CALLBACK (vcd_comment_format_changed_cb, v_config.comment_format) VCD_NUM_CALLBACK (vcd_show_rejected_cb, show_rejected) VCD_NUM_CALLBACK (vcd_autoadvance_cb, autoadvance) VCD_ENUM_CALLBACK (vcd_slider_length_cb, vcdplayer_slider_length_t, slider_length) VCD_ENUM_CALLBACK (vcd_default_autoplay_cb, vcdinfo_item_enum_t, default_autoplay) VCD_NUM_CALLBACK (vcd_debug_cb, vcdplayer_debug) static void * vcd_init (xine_t *xine, const void *data) { vcd_input_class_t *class; config_values_t *config; xprintf (xine, XINE_VERBOSITY_DEBUG, "input_vcd: init class\n"); (void)data; class = calloc (1, sizeof (vcd_input_class_t)); if (!class) return NULL; class->xine = xine; class->config = config = xine->config; class->mrls = NULL; class->input_class.get_instance = vcd_class_get_instance; class->input_class.identifier = SHORT_PLUGIN_NAME; class->input_class.description = N_("Video CD plugin with PBC and support for: (X)VCD, (X)SVCD, HQVCD, CVD ... "); class->input_class.get_dir = vcd_class_get_dir; class->input_class.get_autoplay_list = vcd_class_get_autoplay_list; class->input_class.dispose = vcd_class_dispose; class->input_class.eject_media = vcd_class_eject_media; /*-------------------------------------------------------------- Configuration variables ---------------------------------------------------------------*/ { /*Note: these labels have to be listed in the same order as the enumeration vcdplayer_autoplay_t in vcdplayer.h. */ static const char *const autoplay_modes[] = { "MPEG track", "entry", "segment", "playback-control item", NULL }; /*Note: these labels have to be listed in the same order as the enumeration vcdplayer_slider_length_t in vcdplayer.h. */ static const char *const length_reporting_modes[] = { "auto", "track", "entry", NULL }; class->default_autoplay = config->register_enum(config, "media.vcd.autoplay", VCDPLAYER_AUTOPLAY_PBC, (char **) autoplay_modes, _("VCD default type to use on autoplay"), _("The VCD play unit to use when none is specified in an MRL, e.g. " "vcd:// or vcd:///dev/dvd:"), 10, vcd_default_autoplay_cb, class); class->vcd_device = strdup (config->register_filename(config, "media.vcd.device", "", XINE_CONFIG_STRING_IS_DEVICE_NAME, _("CD-ROM drive used for VCD when none given"), _("What to use if no drive specified. If the setting is empty, xine will scan for CD drives."), 20, vcd_default_dev_changed_cb, class)); class->slider_length = config->register_enum(config, "media.vcd.length_reporting", VCDPLAYER_SLIDER_LENGTH_AUTO, (char **) length_reporting_modes, _("VCD position slider range"), _("range that the stream playback position slider represents playing a VCD."), 10, vcd_slider_length_cb, class); #if READAHEAD_FINISHED class->readahead = config->register_bool(config, "vcd.use_readahead", (int) false, _("VCD read-ahead caching?"), _("May lead to jerky playback on low-end machines."), vcd_read_ahead_cb, class); #endif class->autoadvance = config->register_bool(config, "media.vcd.autoadvance", (int) true, _("automatically advance VCD track/entry"), _("If enabled, we should automatically advance to the next entry or track. Used only when playback control (PBC) is disabled."), 10, vcd_autoadvance_cb, class); class->show_rejected = config->register_bool(config, "media.vcd.show_rejected", (int) false, _("show 'rejected' VCD LIDs"), _("Some playback list IDs (LIDs) are marked not showable, " "but you can see them in the MRL list if this is set. Rejected entries " "are marked with an asterisk (*) appended to the MRL."), 10, vcd_show_rejected_cb, class); class->v_config.title_format = strdup(config->register_string(config, "media.vcd.title_format", "%F - %I %N%L%S, disk %c of %C - %v %A", _("VCD format string for display banner"), _("VCD format used in the GUI Title. Similar to the Unix date " "command. Format specifiers start with a percent sign. Specifiers are:\n" " %A : The album information\n" " %C : The VCD volume count - the number of CD's in the collection.\n" " %c : The VCD volume num - the number of the CD in the collection.\n" " %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD\n" " %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, ...\n" " %L : The playlist ID prefixed with \" LID\" if it exists\n" " %N : The current number of the above - a decimal number\n" " %P : The publisher ID\n" " %p : The preparer ID\n" " %S : If we are in a segment (menu), the kind of segment\n" " %T : The track number\n" " %V : The volume set ID\n" " %v : The volume ID\n" " A number between 1 and the volume count.\n" " %% : a %\n"), 20, vcd_title_format_changed_cb, class)); class->v_config.comment_format = strdup(config->register_string(config, "media.vcd.comment_format", "%P - Track %T", _("VCD format string for stream comment field"), _("VCD format used in the GUI Title. Similar to the Unix date " "command. Format specifiers start with a percent sign. Specifiers are " "%A, %C, %c, %F, %I, %L, %N, %P, %p, %S, %T, %V, %v, and %%.\n" "See the help for the title_format for the meanings of these."), 20, vcd_comment_format_changed_cb, class)); class->vcdplayer_debug = config->register_num(config, "media.vcd.debug", 0, _("VCD debug flag mask"), _("For tracking down bugs in the VCD plugin. Mask values are:\n" " 1: Meta information\n" " 2: input (keyboard/mouse) events\n" " 4: MRL parsing\n" " 8: Calls from external routines\n" " 16: routine calls\n" " 32: LSN changes\n" " 64: Playback control\n" " 128: Debugging from CDIO\n" " 256: Seeks to set location\n" " 512: Seeks to find current location\n" "1024: Still-frame\n" "2048: Debugging from VCDINFO\n" ), 20, vcd_debug_cb, class); } gl_default_vcd_log_handler = vcd_log_set_handler (uninit_log_handler); gl_default_cdio_log_handler = cdio_log_set_handler ((cdio_log_handler_t) uninit_log_handler); return class; } /* Exported plugin catalog entries. All plugins listing only the current API number break when the API number is increased. This is by design. Sometimes in the rush to get out a buggy release, the API number is increased without communication let alone a concern for whether it is necessary or how many plugins it might break. And that is precisely when what happened between API release 12 and API 13. Input plugin API numbers 12 and 13 are functionally identical. Because of problems like this, we'll just put in a future API release. If the number was increased for a reason that doesn't affect us (such as for nor reason at all), then this plugin will work unmodified that future APIs. If on the other hand there was incompatible change, we are no worse off than if we hadn't entered the next API number since in both cases the plugin is broken. */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, SHORT_PLUGIN_NAME, XINE_VERSION_CODE, NULL, vcd_init }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; /* * Local variables: * c-file-style: "gnu" * tab-width: 8 * indent-tabs-mode: nil * End: */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/vcd/vcdplayer.h��������������������������������������������������������������0000644�0001750�0001750�00000025763�14647725152�015545� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: vcdplayer.h,v 1.12 2006/06/10 17:38:47 dgp85 Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef _VCDPLAYER_H_ #define _VCDPLAYER_H_ #ifdef HAVE_VCDNAV #include <libvcd/info.h> #include <libvcd/version.h> #else #include "libvcd/info.h" #endif #ifndef _ #ifdef ENABLE_NLS #include <locale.h> # include <libintl.h> # define _(String) dgettext (XINE_TEXTDOMAIN, String) #else /* Stubs that do something close enough. */ # define _(String) (String) #endif #endif /*------------------------------------------------------------------ DEBUGGING ---------------------------------------------------------------------*/ /* Print *any* debug messages? */ #define INPUT_DEBUG 1 /* Debugging masks */ #define INPUT_DBG_META 1 /* Meta information */ #define INPUT_DBG_EVENT 2 /* input (keyboard/mouse) events */ #define INPUT_DBG_MRL 4 /* MRL parsing */ #define INPUT_DBG_EXT 8 /* Calls from external routines */ #define INPUT_DBG_CALL 16 /* routine calls */ #define INPUT_DBG_LSN 32 /* LSN changes */ #define INPUT_DBG_PBC 64 /* Playback control */ #define INPUT_DBG_CDIO 128 /* Debugging from CDIO */ #define INPUT_DBG_SEEK_SET 256 /* Seeks to set location */ #define INPUT_DBG_SEEK_CUR 512 /* Seeks to find current location */ #define INPUT_DBG_STILL 1024 /* Still-frame */ #define INPUT_DBG_VCDINFO 2048 /* Debugging from VCDINFO */ /*------------------------------------------------------------------ General definitions and structures. ---------------------------------------------------------------------*/ #define VCDPLAYER_IN_STILL 65535 /* Some configuration enumerations. */ typedef enum { VCDPLAYER_SLIDER_LENGTH_AUTO, VCDPLAYER_SLIDER_LENGTH_TRACK, VCDPLAYER_SLIDER_LENGTH_ENTRY, } vcdplayer_slider_length_t; typedef enum { VCDPLAYER_AUTOPLAY_TRACK = VCDINFO_ITEM_TYPE_TRACK, VCDPLAYER_AUTOPLAY_ENTRY = VCDINFO_ITEM_TYPE_ENTRY, VCDPLAYER_AUTOPLAY_SEGMENT = VCDINFO_ITEM_TYPE_SEGMENT, VCDPLAYER_AUTOPLAY_PBC = VCDINFO_ITEM_TYPE_LID, } vcdplayer_autoplay_t; typedef struct { lsn_t start_LSN; /* LSN where play item starts */ size_t size; /* size in sector units of play item. */ } vcdplayer_play_item_info_t; typedef int (*debug_fn) (void *user_data, unsigned int mask, const char *fmt, ...); /* The maximim wait time that can be encoded in a VCD still frame is 2,000 seconds (33.33 minutes). We'll use a number larger than this to signal indefinite wait. */ #define STILL_INDEFINITE_WAIT 3000 /* Value when we have yet to finish reading blocks of a frame. */ #define STILL_READING -5 typedef struct vcdplayer_s { void *user_data; /* environment. Passed to called routines. */ vcdinfo_obj_t *vcd; /* Pointer to libvcd structures. */ /*------------------------------------------------------------------ User-settable options --------------------------------------------------------------*/ unsigned int i_debug; /* Debugging mask */ unsigned int i_blocks_per_read; /* number of blocks per read */ /*------------------------------------------------------------------ Callback functions - players and higher-level routines can use this to customize their behavior when using this player-independent code. ---------------------------------------------------------------------*/ debug_fn log_msg; /* function to log a message in the player */ debug_fn log_err; /* function to log an error in the player */ /* Function to flush any audio or video buffers */ void (*flush_buffers) (void *user_data); /* Function to force a redisplay. */ void (*force_redisplay) (void *user_data); /* Function to set aspect ratio. */ void (*set_aspect_ratio) (void *user_data, int ratio); /* Function to update title of selection. */ void (*update_title) (void *user_data); /*------------------------------------------------------------- Playback control fields --------------------------------------------------------------*/ int i_still; /* 0 if not in still, STILL_INDEFINITE_WAIT if indefinite time, STILL_READING if don't have full picture, else number of seconds yet to wait */ int i_lid; /* LID that play item is in. Implies PBC is. on. VCDPLAYER_BAD_ENTRY if not none or not in PBC */ PsdListDescriptor pxd; /* If PBC is on, the relevant PSD/PLD */ int pdi; /* current pld index of pxd. -1 if no index*/ vcdinfo_itemid_t play_item; /* play-item, VCDPLAYER_BAD_ENTRY if none */ vcdinfo_itemid_t loop_item; /* Where do we loop back to? Meaningful only in a selection list */ int i_loop; /* # of times play-item has been played. Meaningful only in a selection list. */ track_t i_track; /* current track number */ /*----------------------------------- Navigation and location fields ------------------------------------*/ uint16_t next_entry; /* where to go if next is pressed, VCDPLAYER_BAD_ENTRY if none */ uint16_t prev_entry; /* where to fo if prev is pressed, VCDPLAYER_BAD_ENTRY if none */ uint16_t return_entry; /* Entry index to use if return is pressed */ uint16_t default_entry; /* Default selection entry. */ lsn_t i_lsn; /* LSN of where we are right now */ lsn_t end_lsn; /* LSN of end of current entry/segment/track. entry/segment/track. This block can be read (and is not one after the "end"). */ lsn_t origin_lsn; /* LSN of start of seek/slider position. */ lsn_t track_lsn; /* LSN of start track origin of track we are in. */ lsn_t track_end_lsn; /* LSN of end of current track (if entry). */ uint16_t max_x; /* Largest screen x coordinate */ uint16_t max_y; /* Largest screen y coordinate */ /*-------------------------------------------------------------- (S)VCD Medium information ---------------------------------------------------------------*/ char *psz_source; /* VCD device currently open */ bool b_opened; /* true if initialized */ vcd_type_t vcd_format; /* VCD 2.0, 1,1, SVCD, HQVCD? */ track_t i_tracks; /* # of playable MPEG tracks. This is generally one less than the number of CD tracks as the first CD track is an ISO-9660 track and is not playable. */ segnum_t i_segments; /* Number of segments in medium */ unsigned int i_entries; /* Number of entries in medium */ lid_t i_lids; /* Number of LIDs in medium */ /* Tracks, segment, and entry information. The number of entries for each is given by the corresponding i_* field above. */ vcdplayer_play_item_info_t *track; vcdplayer_play_item_info_t *segment; vcdplayer_play_item_info_t *entry; /*-------------------------------------------------------------- Configuration variables ---------------------------------------------------------------*/ /* What type to use on autoplay */ vcdplayer_autoplay_t default_autoplay; /* When hitting end of entry or track do we advance automatically to next entry/track or stop? Only valid if PBC is off. */ bool autoadvance; /* Do next/prev wrap around? Only valid if PBC is off. */ bool wrap_next_prev; /* Show and be able to select rejected LIDs? */ bool show_rejected; /* Whether GUI slider is track size or entry size. */ vcdplayer_slider_length_t slider_length; } vcdplayer_t; /* vcdplayer_read return status */ typedef enum { READ_BLOCK, READ_STILL_FRAME, READ_ERROR, READ_END, } vcdplayer_read_status_t; /* ---------------------------------------------------------------------- Function Prototypes -----------------------------------------------------------------------*/ /*! Return true if playback control (PBC) is on */ bool vcdplayer_pbc_is_on(const vcdplayer_t *p_vcdplayer); /*! Take a format string and expand escape sequences, that is sequences that begin with %, with information from the current VCD. The expanded string is returned. Here is a list of escape sequences: %A : The album information %C : The VCD volume count - the number of CD's in the collection. %c : The VCD volume num - the number of the CD in the collection. %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT... %L : The playlist ID prefixed with " LID" if it exists %N : The current number of the above - a decimal number %P : The publisher ID %p : The preparer ID %V : The volume set ID %v : The volume ID A number between 1 and the volume count. %% : a % */ char * vcdplayer_format_str(vcdplayer_t *p_vcdplayer, const char format_str[]); /*! Update next/prev/return/default navigation buttons. */ void vcdplayer_update_nav(vcdplayer_t *p_vcdplayer); /*! Update the player title text. */ void vcdplayer_update_title_display(vcdplayer_t *p_vcdplayer); /*! Play title part. If part is -1, use the first title. */ void vcdplayer_play(vcdplayer_t *p_vcdplayer, vcdinfo_itemid_t itemid); bool vcdplayer_open(vcdplayer_t *p_vcdplayer, char *intended_vcd_device); /*! Read nlen bytes into buf and return the status back. */ vcdplayer_read_status_t vcdplayer_read (vcdplayer_t *p_vcdplayer, uint8_t *p_buf, const off_t nlen); /*! seek position, return new position if seeking failed, -1 is returned */ off_t vcdplayer_seek (vcdplayer_t *p_vcdplayer, off_t offset, int origin); /*! Get the number of tracks or titles of the VCD. The result is stored in "titles". */ void vcdplayer_send_button_update(vcdplayer_t *p_vcdplayer, int mode); #endif /* _VCDPLAYER_H_ */ /* * Local variables: * c-file-style: "gnu" * tab-width: 8 * indent-tabs-mode: nil * End: */ �������������xine-lib-1.2/src/input/vcd/vcdplayer.c��������������������������������������������������������������0000644�0001750�0001750�00000074366�14647725152�015543� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* $Id: vcdplayer.c,v 1.20 2007/02/21 23:17:14 dgp85 Exp $ Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein <rocky@panix.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* Standard includes */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> #include <time.h> #include <string.h> #ifdef HAVE_STRINGS_H #include <strings.h> #endif #include <errno.h> #ifdef HAVE_VCDNAV #include <libvcd/files.h> #include <cdio/iso9660.h> #else #include "libvcd/files.h" #include "cdio/iso9660.h" #endif #include "vcdplayer.h" #include "vcdio.h" /* This function is _not_ exported by libvcd, its usage should be avoided, most * likely. */ void vcdinfo_get_seg_resolution(const vcdinfo_obj_t *p_vcdinfo, segnum_t i_seg, /*out*/ uint16_t *max_x, /*out*/ uint16_t *max_y); #define LOG_ERR(p_vcdplayer, s, args...) \ if (p_vcdplayer->log_err) \ p_vcdplayer->log_err (p_vcdplayer->user_data, ~0, "input_vcd: %s: "s, __func__ , ##args) #define dbg_print(p_vcdplayer, mask, s, args...) \ if (p_vcdplayer->log_msg) \ p_vcdplayer->log_msg (p_vcdplayer->user_data, mask, "input_vcd: %s: "s, __func__ , ##args) static void _vcdplayer_set_origin(vcdplayer_t *p_vcdplayer); /*! Return true if playback control (PBC) is on */ bool vcdplayer_pbc_is_on(const vcdplayer_t *p_vcdplayer) { return VCDINFO_INVALID_ENTRY != p_vcdplayer->i_lid; } /* Given an itemid, return the size for the object (via information previously stored when opening the vcd). */ static size_t _vcdplayer_get_item_size(vcdplayer_t *p_vcdplayer, vcdinfo_itemid_t itemid) { switch (itemid.type) { case VCDINFO_ITEM_TYPE_ENTRY: return p_vcdplayer->entry[itemid.num].size; break; case VCDINFO_ITEM_TYPE_SEGMENT: return p_vcdplayer->segment[itemid.num].size; break; case VCDINFO_ITEM_TYPE_TRACK: return p_vcdplayer->track[itemid.num-1].size; break; case VCDINFO_ITEM_TYPE_LID: /* Play list number (LID) */ return 0; break; case VCDINFO_ITEM_TYPE_NOTFOUND: case VCDINFO_ITEM_TYPE_SPAREID2: default: LOG_ERR(p_vcdplayer, "%s %d\n", _("bad item type"), itemid.type); return 0; } } #define add_format_str_info(val) \ { \ const char *str = val; \ unsigned int len; \ if (val != NULL) { \ len=strlen(str); \ if (len != 0) { \ strncat(tp, str, TEMP_STR_LEN-(tp-temp_str)); \ tp += len; \ } \ saw_control_prefix = false; \ } \ } #define add_format_num_info(val, fmt) \ { \ char num_str[10]; \ unsigned int len; \ snprintf(num_str, sizeof(num_str), fmt, val); \ len=strlen(num_str); \ if (len != 0) { \ strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); \ tp += len; \ } \ saw_control_prefix = false; \ } /*! Take a format string and expand escape sequences, that is sequences that begin with %, with information from the current VCD. The expanded string is returned. Here is a list of escape sequences: %A : The album information %C : The VCD volume count - the number of CD's in the collection. %c : The VCD volume num - the number of the CD in the collection. %F : The VCD Format, e.g. VCD 1.0, VCD 1.1, VCD 2.0, or SVCD %I : The current entry/segment/playback type, e.g. ENTRY, TRACK, SEGMENT... %L : The playlist ID prefixed with " LID" if it exists %N : The current number of the above - a decimal number %P : The publisher ID %p : The preparer ID %S : If we are in a segment (menu), the kind of segment %T : The track number %V : The volume set ID %v : The volume ID A number between 1 and the volume count. %% : a % */ char * vcdplayer_format_str(vcdplayer_t *p_vcdplayer, const char format_str[]) { #define TEMP_STR_SIZE 256 #define TEMP_STR_LEN (TEMP_STR_SIZE-1) static char temp_str[TEMP_STR_SIZE]; size_t i; char * tp = temp_str; bool saw_control_prefix = false; size_t format_len = strlen(format_str); vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; memset(temp_str, 0, TEMP_STR_SIZE); for (i=0; i<format_len; i++) { if (!saw_control_prefix && format_str[i] != '%') { *tp++ = format_str[i]; saw_control_prefix = false; continue; } switch(format_str[i]) { case '%': if (saw_control_prefix) { *tp++ = '%'; } saw_control_prefix = !saw_control_prefix; break; case 'A': add_format_str_info(vcdinfo_strip_trail(vcdinfo_get_album_id(p_vcdinfo), MAX_ALBUM_LEN)); break; case 'c': add_format_num_info(vcdinfo_get_volume_num(p_vcdinfo), "%d"); break; case 'C': add_format_num_info(vcdinfo_get_volume_count(p_vcdinfo), "%d"); break; case 'F': add_format_str_info(vcdinfo_get_format_version_str(p_vcdinfo)); break; case 'I': { switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_TRACK: strncat(tp, "Track", TEMP_STR_LEN-(tp-temp_str)); tp += strlen("Track"); break; case VCDINFO_ITEM_TYPE_ENTRY: strncat(tp, "Entry", TEMP_STR_LEN-(tp-temp_str)); tp += strlen("Entry"); break; case VCDINFO_ITEM_TYPE_SEGMENT: strncat(tp, "Segment", TEMP_STR_LEN-(tp-temp_str)); tp += strlen("Segment"); break; case VCDINFO_ITEM_TYPE_LID: strncat(tp, "List ID", TEMP_STR_LEN-(tp-temp_str)); tp += strlen("List ID"); break; case VCDINFO_ITEM_TYPE_SPAREID2: strncat(tp, "Navigation", TEMP_STR_LEN-(tp-temp_str)); tp += strlen("Navigation"); break; default: /* What to do? */ ; } saw_control_prefix = false; } break; case 'L': if (vcdplayer_pbc_is_on(p_vcdplayer)) { char num_str[20]; snprintf(num_str, sizeof(num_str), " List ID %d", p_vcdplayer->i_lid); strncat(tp, num_str, TEMP_STR_LEN-(tp-temp_str)); tp += strlen(num_str); } saw_control_prefix = false; break; case 'N': add_format_num_info(p_vcdplayer->play_item.num, "%d"); break; case 'p': add_format_str_info(vcdinfo_get_preparer_id(p_vcdinfo)); break; case 'P': add_format_str_info(vcdinfo_get_publisher_id(p_vcdinfo)); break; case 'S': if ( VCDINFO_ITEM_TYPE_SEGMENT==p_vcdplayer->play_item.type ) { char seg_type_str[30]; snprintf(seg_type_str, sizeof(seg_type_str), " %s", vcdinfo_video_type2str(p_vcdinfo, p_vcdplayer->play_item.num)); strncat(tp, seg_type_str, TEMP_STR_LEN-(tp-temp_str)); tp += strlen(seg_type_str); } saw_control_prefix = false; break; case 'T': add_format_num_info(p_vcdplayer->i_track, "%d"); break; case 'V': add_format_str_info(vcdinfo_get_volumeset_id(p_vcdinfo)); break; case 'v': add_format_str_info(vcdinfo_get_volume_id(p_vcdinfo)); break; default: *tp++ = '%'; *tp++ = format_str[i]; saw_control_prefix = false; } } return strdup(temp_str); } static void _vcdplayer_update_entry(vcdinfo_obj_t *p_vcdinfo, uint16_t ofs, uint16_t *entry, const char *label) { (void)label; if ( ofs == VCDINFO_INVALID_OFFSET ) { *entry = VCDINFO_INVALID_ENTRY; } else { vcdinfo_offset_t *off = vcdinfo_get_offset_t(p_vcdinfo, ofs); if (off != NULL) { *entry = off->lid; /* dbg_print (p_vcdplayer, INPUT_DBG_PBC, "%s: LID %d\n", label, off->lid); */ } else *entry = VCDINFO_INVALID_ENTRY; } } /*! Update next/prev/return/default navigation buttons (via p_vcdplayer->i_lid). Update size of play-item (via p_vcdplayer->play_item). */ void vcdplayer_update_nav(vcdplayer_t *p_vcdplayer) { int play_item = p_vcdplayer->play_item.num; vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; int min_entry = 1; int max_entry = 0; if (vcdplayer_pbc_is_on(p_vcdplayer)) { vcdinfo_lid_get_pxd(p_vcdinfo, &(p_vcdplayer->pxd), p_vcdplayer->i_lid); switch (p_vcdplayer->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: if (p_vcdplayer->pxd.psd == NULL) return; _vcdplayer_update_entry(p_vcdinfo, vcdinf_psd_get_prev_offset(p_vcdplayer->pxd.psd), &(p_vcdplayer->prev_entry), "prev"); _vcdplayer_update_entry(p_vcdinfo, vcdinf_psd_get_next_offset(p_vcdplayer->pxd.psd), &(p_vcdplayer->next_entry), "next"); _vcdplayer_update_entry(p_vcdinfo, vcdinf_psd_get_return_offset(p_vcdplayer->pxd.psd), &(p_vcdplayer->return_entry), "return"); _vcdplayer_update_entry(p_vcdinfo, vcdinfo_get_default_offset(p_vcdinfo, p_vcdplayer->i_lid), &(p_vcdplayer->default_entry), "default"); break; case PSD_TYPE_PLAY_LIST: if (p_vcdplayer->pxd.pld == NULL) return; _vcdplayer_update_entry(p_vcdinfo, vcdinf_pld_get_prev_offset(p_vcdplayer->pxd.pld), &(p_vcdplayer->prev_entry), "prev"); _vcdplayer_update_entry(p_vcdinfo, vcdinf_pld_get_next_offset(p_vcdplayer->pxd.pld), &(p_vcdplayer->next_entry), "next"); _vcdplayer_update_entry(p_vcdinfo, vcdinf_pld_get_return_offset(p_vcdplayer->pxd.pld), &(p_vcdplayer->return_entry), "return"); p_vcdplayer->default_entry = VCDINFO_INVALID_ENTRY; break; case PSD_TYPE_END_LIST: p_vcdplayer->origin_lsn = p_vcdplayer->i_lsn = p_vcdplayer->end_lsn = VCDINFO_NULL_LSN; /* Fall through */ case PSD_TYPE_COMMAND_LIST: p_vcdplayer->next_entry = p_vcdplayer->prev_entry = p_vcdplayer->return_entry = VCDINFO_INVALID_ENTRY; p_vcdplayer->default_entry = VCDINFO_INVALID_ENTRY; break; } if (p_vcdplayer->update_title) p_vcdplayer->update_title(p_vcdplayer->user_data); return; } /* PBC is not on. Set up for simplified next, prev, and return. */ switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: case VCDINFO_ITEM_TYPE_SEGMENT: case VCDINFO_ITEM_TYPE_TRACK: switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_ENTRY: max_entry = p_vcdplayer->i_entries; min_entry = 0; /* Can remove when Entries start at 1. */ p_vcdplayer->i_track = vcdinfo_get_track(p_vcdinfo, play_item); p_vcdplayer->track_lsn = vcdinfo_get_track_lsn(p_vcdinfo, p_vcdplayer->i_track); break; case VCDINFO_ITEM_TYPE_SEGMENT: max_entry = p_vcdplayer->i_segments; p_vcdplayer->i_track = VCDINFO_INVALID_TRACK; break; case VCDINFO_ITEM_TYPE_TRACK: max_entry = p_vcdplayer->i_tracks; p_vcdplayer->i_track = p_vcdplayer->play_item.num; p_vcdplayer->track_lsn = vcdinfo_get_track_lsn(p_vcdinfo, p_vcdplayer->i_track); break; default: ; /* Handle exceptional cases below */ } _vcdplayer_set_origin(p_vcdplayer); /* Set next, prev, return and default to simple and hopefully useful values. */ if (play_item+1 >= max_entry) p_vcdplayer->next_entry = VCDINFO_INVALID_ENTRY; else p_vcdplayer->next_entry = play_item+1; if (play_item-1 >= min_entry) p_vcdplayer->prev_entry = play_item-1; else p_vcdplayer->prev_entry = VCDINFO_INVALID_ENTRY; p_vcdplayer->default_entry = play_item; p_vcdplayer->return_entry = min_entry; break; case VCDINFO_ITEM_TYPE_LID: { /* Should have handled above. */ break; } default: ; } p_vcdplayer->update_title(p_vcdplayer->user_data); } /*! Set reading to play an entire track. */ static void _vcdplayer_set_track(vcdplayer_t *p_vcdplayer, unsigned int i_track) { if (i_track < 1 || i_track > p_vcdplayer->i_tracks) return; else { vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; vcdinfo_itemid_t itemid; itemid.num = i_track; itemid.type = VCDINFO_ITEM_TYPE_TRACK; p_vcdplayer->i_still = 0; p_vcdplayer->i_lsn = vcdinfo_get_track_lsn(p_vcdinfo, i_track); p_vcdplayer->play_item = itemid; p_vcdplayer->i_track = i_track; p_vcdplayer->track_lsn = p_vcdplayer->i_lsn; _vcdplayer_set_origin(p_vcdplayer); dbg_print (p_vcdplayer, INPUT_DBG_LSN, "LSN: %u\n", p_vcdplayer->i_lsn); } } /*! Set reading to play an entry */ static void _vcdplayer_set_entry(vcdplayer_t *p_vcdplayer, unsigned int num) { vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; const unsigned int i_entries = vcdinfo_get_num_entries(p_vcdinfo); if (num >= i_entries) { LOG_ERR(p_vcdplayer, "%s %d\n", _("bad entry number"), num); return; } else { vcdinfo_itemid_t itemid; itemid.num = num; itemid.type = VCDINFO_ITEM_TYPE_ENTRY; p_vcdplayer->i_still = 0; p_vcdplayer->i_lsn = vcdinfo_get_entry_lsn(p_vcdinfo, num); p_vcdplayer->play_item = itemid; p_vcdplayer->i_track = vcdinfo_get_track(p_vcdinfo, num); p_vcdplayer->track_lsn = vcdinfo_get_track_lsn(p_vcdinfo, p_vcdplayer->i_track); p_vcdplayer->track_end_lsn = p_vcdplayer->track_lsn + p_vcdplayer->track[p_vcdplayer->i_track-1].size; _vcdplayer_set_origin(p_vcdplayer); dbg_print (p_vcdplayer, (INPUT_DBG_LSN|INPUT_DBG_PBC), "LSN: %u, track_end LSN: %u\n", p_vcdplayer->i_lsn, p_vcdplayer->track_end_lsn); } } /*! Set reading to play an segment (e.g. still frame) */ static void _vcdplayer_set_segment(vcdplayer_t *p_vcdplayer, unsigned int num) { vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; segnum_t i_segs = vcdinfo_get_num_segments(p_vcdinfo); if (num >= i_segs) { LOG_ERR(p_vcdplayer, "%s %d\n", _("bad segment number"), num); return; } else { vcdinfo_itemid_t itemid; p_vcdplayer->i_lsn = vcdinfo_get_seg_lsn(p_vcdinfo, num); p_vcdplayer->i_track = 0; if (VCDINFO_NULL_LSN==p_vcdplayer->i_lsn) { LOG_ERR(p_vcdplayer, "%s %d\n", _("Error in getting current segment number"), num); return; } itemid.num = num; itemid.type = VCDINFO_ITEM_TYPE_SEGMENT; p_vcdplayer->play_item = itemid; _vcdplayer_set_origin(p_vcdplayer); dbg_print (p_vcdplayer, INPUT_DBG_LSN, "LSN: %u\n", p_vcdplayer->i_lsn); } } /* Play entry. */ /* Play a single item. */ static void vcdplayer_play_single_item(vcdplayer_t *p_vcdplayer, vcdinfo_itemid_t itemid) { vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; dbg_print (p_vcdplayer, INPUT_DBG_CALL, "called itemid.num: %d, itemid.type: %d\n", itemid.num, itemid.type); p_vcdplayer->i_still = 0; switch (itemid.type) { case VCDINFO_ITEM_TYPE_SEGMENT: { vcdinfo_video_segment_type_t segtype = vcdinfo_get_video_type(p_vcdinfo, itemid.num); segnum_t i_segs = vcdinfo_get_num_segments(p_vcdinfo); dbg_print (p_vcdplayer, INPUT_DBG_PBC, "%s (%d), itemid.num: %d\n", vcdinfo_video_type2str(p_vcdinfo, itemid.num), (int) segtype, itemid.num); if (itemid.num >= i_segs) return; _vcdplayer_set_segment(p_vcdplayer, itemid.num); vcdinfo_get_seg_resolution(p_vcdinfo, itemid.num, &(p_vcdplayer->max_x), &(p_vcdplayer->max_y)); switch (segtype) { case VCDINFO_FILES_VIDEO_NTSC_STILL: case VCDINFO_FILES_VIDEO_NTSC_STILL2: case VCDINFO_FILES_VIDEO_PAL_STILL: case VCDINFO_FILES_VIDEO_PAL_STILL2: /* Note that we are reading a still frame but haven't got to the end. */ p_vcdplayer->i_still = STILL_READING; break; default: /* */ switch (p_vcdplayer->vcd_format) { case VCD_TYPE_VCD: case VCD_TYPE_VCD11: case VCD_TYPE_VCD2: /* aspect ratio for VCD's is known to be 4:3 for any type of VCD's */ p_vcdplayer->set_aspect_ratio(p_vcdplayer->user_data, 1); break; default: ; } p_vcdplayer->i_still = 0; } break; } case VCDINFO_ITEM_TYPE_TRACK: dbg_print (p_vcdplayer, INPUT_DBG_PBC, "track %d\n", itemid.num); if (itemid.num < 1 || itemid.num > p_vcdplayer->i_tracks) return; _vcdplayer_set_track(p_vcdplayer, itemid.num); break; case VCDINFO_ITEM_TYPE_ENTRY: { unsigned int i_entries = vcdinfo_get_num_entries(p_vcdinfo); dbg_print (p_vcdplayer, INPUT_DBG_PBC, "entry %d\n", itemid.num); if (itemid.num >= i_entries) return; _vcdplayer_set_entry(p_vcdplayer, itemid.num); break; } case VCDINFO_ITEM_TYPE_LID: LOG_ERR(p_vcdplayer, "%s\n", _("Should have converted this above")); break; case VCDINFO_ITEM_TYPE_NOTFOUND: dbg_print (p_vcdplayer, INPUT_DBG_PBC, "play nothing\n"); p_vcdplayer->i_lsn = p_vcdplayer->end_lsn; return; default: LOG_ERR(p_vcdplayer, "item type %d not implemented.\n", itemid.type); return; } p_vcdplayer->play_item = itemid; vcdplayer_update_nav(p_vcdplayer); /* Some players like xine, have a fifo queue of audio and video buffers that need to be flushed when playing a new selection. */ /* if (p_vcdplayer->flush_buffers) p_vcdplayer->flush_buffers(p_vcdplayer->user_data); */ } /* Get the next play-item in the list given in the LIDs. Note play-item here refers to list of play-items for a single LID It shouldn't be confused with a user's list of favorite things to play or the "next" field of a LID which moves us to a different LID. */ static bool _vcdplayer_inc_play_item(vcdplayer_t *p_vcdplayer) { int noi; if ( NULL == p_vcdplayer || NULL == p_vcdplayer->pxd.pld ) return false; dbg_print (p_vcdplayer, INPUT_DBG_CALL, "called pli: %d\n", p_vcdplayer->pdi); noi = vcdinf_pld_get_noi(p_vcdplayer->pxd.pld); if ( noi <= 0 ) return false; /* Handle delays like autowait or wait here? */ p_vcdplayer->pdi++; if ( p_vcdplayer->pdi < 0 || p_vcdplayer->pdi >= noi ) return false; else { uint16_t trans_itemid_num=vcdinf_pld_get_play_item(p_vcdplayer->pxd.pld, p_vcdplayer->pdi); vcdinfo_itemid_t trans_itemid; if (VCDINFO_INVALID_ITEMID == trans_itemid_num) return false; vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); dbg_print (p_vcdplayer, INPUT_DBG_PBC, " play-item[%d]: %s\n", p_vcdplayer->pdi, vcdinfo_pin2str (trans_itemid_num)); vcdplayer_play_single_item(p_vcdplayer, trans_itemid); return true; } } void vcdplayer_play(vcdplayer_t *p_vcdplayer, vcdinfo_itemid_t itemid) { dbg_print (p_vcdplayer, INPUT_DBG_CALL, "called itemid.num: %d itemid.type: %d\n", itemid.num, itemid.type); if (!vcdplayer_pbc_is_on(p_vcdplayer)) { vcdplayer_play_single_item(p_vcdplayer, itemid); } else { /* PBC on - Itemid.num is LID. */ vcdinfo_obj_t *p_vcdinfo = p_vcdplayer->vcd; if (p_vcdinfo == NULL) return; p_vcdplayer->i_lid = itemid.num; vcdinfo_lid_get_pxd(p_vcdinfo, &(p_vcdplayer->pxd), itemid.num); switch (p_vcdplayer->pxd.descriptor_type) { case PSD_TYPE_SELECTION_LIST: case PSD_TYPE_EXT_SELECTION_LIST: { vcdinfo_itemid_t trans_itemid; uint16_t trans_itemid_num; if (p_vcdplayer->pxd.psd == NULL) return; trans_itemid_num = vcdinf_psd_get_itemid(p_vcdplayer->pxd.psd); vcdinfo_classify_itemid(trans_itemid_num, &trans_itemid); p_vcdplayer->i_loop = 1; p_vcdplayer->loop_item = trans_itemid; vcdplayer_play_single_item(p_vcdplayer, trans_itemid); break; } case PSD_TYPE_PLAY_LIST: { if (p_vcdplayer->pxd.pld == NULL) return; p_vcdplayer->pdi = -1; _vcdplayer_inc_play_item(p_vcdplayer); break; } case PSD_TYPE_END_LIST: case PSD_TYPE_COMMAND_LIST: default: ; } } } /* Set's start origin and size for subsequent seeks. input: p_vcdplayer->i_lsn, p_vcdplayer->play_item changed: p_vcdplayer->origin_lsn, p_vcdplayer->end_lsn */ static void _vcdplayer_set_origin(vcdplayer_t *p_vcdplayer) { size_t size = _vcdplayer_get_item_size(p_vcdplayer, p_vcdplayer->play_item); p_vcdplayer->end_lsn = p_vcdplayer->i_lsn + size; p_vcdplayer->origin_lsn = p_vcdplayer->i_lsn; dbg_print (p_vcdplayer, (INPUT_DBG_CALL|INPUT_DBG_LSN), "end LSN: %u\n", p_vcdplayer->end_lsn); } #define RETURN_NULL_STILL \ p_vcdplayer->i_still = 127; \ memset (p_buf, 0, M2F2_SECTOR_SIZE); \ p_buf[0] = 0; p_buf[1] = 0; p_buf[2] = 0x01; \ return READ_STILL_FRAME /* Handles PBC navigation when reaching the end of a play item. */ static vcdplayer_read_status_t vcdplayer_pbc_nav (vcdplayer_t *p_vcdplayer, uint8_t *p_buf) { /* We are in playback control. */ vcdinfo_itemid_t itemid; /* The end of an entry is really the end of the associated sequence (or track). */ if ( (VCDINFO_ITEM_TYPE_ENTRY == p_vcdplayer->play_item.type) && (p_vcdplayer->i_lsn < p_vcdplayer->track_end_lsn) ) { /* Set up to just continue to the next entry */ p_vcdplayer->play_item.num++; dbg_print (p_vcdplayer, (INPUT_DBG_LSN|INPUT_DBG_PBC), "continuing into next entry: %u\n", p_vcdplayer->play_item.num); vcdplayer_play_single_item(p_vcdplayer, p_vcdplayer->play_item); p_vcdplayer->update_title(p_vcdplayer->user_data); return READ_BLOCK; } switch ((unsigned)p_vcdplayer->pxd.descriptor_type) { case PSD_TYPE_END_LIST: return READ_END; break; case PSD_TYPE_PLAY_LIST: { int wait_time = vcdinf_get_wait_time(p_vcdplayer->pxd.pld); dbg_print (p_vcdplayer, INPUT_DBG_PBC, "playlist wait_time: %d\n", wait_time); if (_vcdplayer_inc_play_item(p_vcdplayer)) return READ_BLOCK; /* This needs to be improved in libvcdinfo when I get around to it. */ if (-1 == wait_time) wait_time = STILL_INDEFINITE_WAIT; /* Set caller to handle wait time given. */ if (STILL_READING == p_vcdplayer->i_still && wait_time > 0) { p_vcdplayer->i_still = wait_time; return READ_STILL_FRAME; } break; } case PSD_TYPE_SELECTION_LIST: /* Selection List (+Ext. for SVCD) */ case PSD_TYPE_EXT_SELECTION_LIST: /* Extended Selection List (VCD2.0) */ { int wait_time = vcdinf_get_timeout_time(p_vcdplayer->pxd.psd); uint16_t timeout_offs = vcdinf_get_timeout_offset(p_vcdplayer->pxd.psd); uint16_t max_loop = vcdinf_get_loop_count(p_vcdplayer->pxd.psd); vcdinfo_offset_t *offset_timeout_LID = vcdinfo_get_offset_t(p_vcdplayer->vcd, timeout_offs); dbg_print (p_vcdplayer, INPUT_DBG_PBC, "wait_time: %d, looped: %d, max_loop %d\n", wait_time, p_vcdplayer->i_loop, max_loop); /* Set caller to handle wait time given. */ if (STILL_READING == p_vcdplayer->i_still && wait_time > 0) { p_vcdplayer->i_still = wait_time; return READ_STILL_FRAME; } /* Handle any looping given. */ if ( max_loop == 0 || p_vcdplayer->i_loop < max_loop ) { p_vcdplayer->i_loop++; if (p_vcdplayer->i_loop == 0x7f) p_vcdplayer->i_loop = 0; vcdplayer_play_single_item(p_vcdplayer, p_vcdplayer->loop_item); if (p_vcdplayer->i_still) p_vcdplayer->force_redisplay(p_vcdplayer->user_data); return READ_BLOCK; } /* Looping finished and wait finished. Move to timeout entry or next entry, or handle still. */ if (NULL != offset_timeout_LID) { /* Handle timeout_LID */ itemid.num = offset_timeout_LID->lid; itemid.type = VCDINFO_ITEM_TYPE_LID; dbg_print (p_vcdplayer, INPUT_DBG_PBC, "timeout to: %d\n", itemid.num); vcdplayer_play(p_vcdplayer, itemid); return READ_BLOCK; } else { int i_selections = vcdinf_get_num_selections(p_vcdplayer->pxd.psd); if (i_selections > 0) { /* Pick a random selection. */ unsigned int bsn=vcdinf_get_bsn(p_vcdplayer->pxd.psd); int rand_selection=bsn + (int) ((i_selections+0.0)*rand()/(RAND_MAX+1.0)); lid_t rand_lid=vcdinfo_selection_get_lid(p_vcdplayer->vcd, p_vcdplayer->i_lid, rand_selection); itemid.num = rand_lid; itemid.type = VCDINFO_ITEM_TYPE_LID; dbg_print (p_vcdplayer, INPUT_DBG_PBC, "random selection %d, lid: %d\n", rand_selection - bsn, rand_lid); vcdplayer_play(p_vcdplayer, itemid); return READ_BLOCK; } else if (p_vcdplayer->i_still > 0) { /* Hack: Just go back and do still again */ RETURN_NULL_STILL ; } } break; } case VCDINFO_ITEM_TYPE_NOTFOUND: LOG_ERR(p_vcdplayer, "NOTFOUND in PBC -- not supposed to happen\n"); break; case VCDINFO_ITEM_TYPE_SPAREID2: LOG_ERR(p_vcdplayer, "SPAREID2 in PBC -- not supposed to happen\n"); break; case VCDINFO_ITEM_TYPE_LID: LOG_ERR(p_vcdplayer, "LID in PBC -- not supposed to happen\n"); break; default: ; } /* FIXME: Should handle autowait ... */ itemid.num = p_vcdplayer->next_entry; itemid.type = VCDINFO_ITEM_TYPE_LID; vcdplayer_play(p_vcdplayer, itemid); return READ_BLOCK; } /* Handles navigation when NOT in PBC reaching the end of a play item. The navigations rules here we are sort of made up, but the intent is to do something that's probably right or helpful. */ static vcdplayer_read_status_t vcdplayer_non_pbc_nav (vcdplayer_t *p_vcdplayer, uint8_t *p_buf) { /* Not in playback control. Do we advance automatically or stop? */ switch (p_vcdplayer->play_item.type) { case VCDINFO_ITEM_TYPE_TRACK: case VCDINFO_ITEM_TYPE_ENTRY: if (p_vcdplayer->autoadvance && p_vcdplayer->next_entry != VCDINFO_INVALID_ENTRY) { p_vcdplayer->play_item.num=p_vcdplayer->next_entry; vcdplayer_update_nav(p_vcdplayer); } else return READ_END; break; case VCDINFO_ITEM_TYPE_SPAREID2: RETURN_NULL_STILL ; case VCDINFO_ITEM_TYPE_NOTFOUND: LOG_ERR(p_vcdplayer, "NOTFOUND outside PBC -- not supposed to happen\n"); return READ_END; break; case VCDINFO_ITEM_TYPE_LID: LOG_ERR(p_vcdplayer, "LID outside PBC -- not supposed to happen\n"); return READ_END; break; case VCDINFO_ITEM_TYPE_SEGMENT: /* Hack: Just go back and do still again */ RETURN_NULL_STILL ; } return READ_BLOCK; } /*! Read i_len bytes into buf and return the status back. This routine is a bit complicated because on reaching the end of a track or entry we may automatically advance to the item, or interpret the next item in the playback-control list. */ vcdplayer_read_status_t vcdplayer_read (vcdplayer_t *p_vcdplayer, uint8_t *p_buf, const off_t i_len) { (void)i_len; if ( p_vcdplayer->i_lsn >= p_vcdplayer->end_lsn ) { vcdplayer_read_status_t read_status; /* We've run off of the end of this entry. Do we continue or stop? */ dbg_print (p_vcdplayer, (INPUT_DBG_LSN|INPUT_DBG_PBC), "end reached, cur: %u, end: %u\n", p_vcdplayer->i_lsn, p_vcdplayer->end_lsn); handle_item_continuation: read_status = vcdplayer_pbc_is_on(p_vcdplayer) ? vcdplayer_pbc_nav(p_vcdplayer, p_buf) : vcdplayer_non_pbc_nav(p_vcdplayer, p_buf); if (READ_STILL_FRAME == read_status) { *p_buf = p_vcdplayer->i_still; return READ_STILL_FRAME; } if (READ_BLOCK != read_status) return read_status; } /* Read the next block. Important note: we probably speed things up by removing "data" and the memcpy to it by extending vcd_image_source_read_mode2 to allow a mode to do what's below in addition to its "raw" and "block" mode. It also would probably improve the modularity a little bit as well. */ { CdIo_t *p_img = vcdinfo_get_cd_image(p_vcdplayer->vcd); typedef struct { uint8_t subheader [CDIO_CD_SUBHEADER_SIZE]; uint8_t data [M2F2_SECTOR_SIZE]; uint8_t spare [4]; } vcdsector_t; vcdsector_t vcd_sector; do { if (cdio_read_mode2_sector(p_img, &vcd_sector, p_vcdplayer->i_lsn, true)!=0) { dbg_print (p_vcdplayer, INPUT_DBG_LSN, "read error\n"); p_vcdplayer->i_lsn++; return READ_ERROR; } p_vcdplayer->i_lsn++; if ( p_vcdplayer->i_lsn >= p_vcdplayer->end_lsn ) { /* We've run off of the end of this entry. Do we continue or stop? */ dbg_print (p_vcdplayer, (INPUT_DBG_LSN|INPUT_DBG_PBC), "end reached in reading, cur: %u, end: %u\n", p_vcdplayer->i_lsn, p_vcdplayer->end_lsn); break; } /* Check header ID for a padding sector and simply discard these. It is alleged that VCD's put these in to keep the bitrate constant. */ } while((vcd_sector.subheader[2]&~0x01)==0x60); if ( p_vcdplayer->i_lsn >= p_vcdplayer->end_lsn ) /* We've run off of the end of this entry. Do we continue or stop? */ goto handle_item_continuation; memcpy (p_buf, vcd_sector.data, M2F2_SECTOR_SIZE); return READ_BLOCK; } } /* Do if needed */ void vcdplayer_send_button_update(vcdplayer_t *p_vcdplayer, const int mode) { /* dbg_print (p_vcdplayer, INPUT_DBG_CALL, "Called\n"); */ (void)p_vcdplayer; (void)mode; return; } /* * Local variables: * c-file-style: "gnu" * tab-width: 8 * indent-tabs-mode: nil * End: */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_http.c�����������������������������������������������������������������0000644�0001750�0001750�00000200751�14647725152�015161� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * input plugin for http network streams */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef HAVE_NETDB_H #include <netdb.h> #endif #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #include <ctype.h> #include <errno.h> #include <zlib.h> #ifdef WIN32 #include <winsock.h> #endif #define LOG_MODULE "input_http" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "tls/xine_tls.h" #include "group_network.h" #include "http_helper.h" #include "input_helper.h" #define BUFSIZE 1024 #define DEFAULT_HTTP_PORT 80 #define DEFAULT_HTTPS_PORT 443 static inline void uint64_2str (char **s, uint64_t v) { uint8_t b[44], *t = b + 21, *q = (uint8_t *)*s; uint32_t u; *t = 0; while (v & ((uint64_t)0xffffffff << 32)) { *--t = v % 10u + '0'; v /= 10u; } u = v; do { *--t = u % 10u + '0'; u /= 10u; } while (u); memcpy (q, t, 21); *s = (char *)(q + (b + 21 - t)); } static inline void uint32_2str (char **s, uint32_t u) { uint8_t b[24], *t = b + 12, *q = (uint8_t *)*s; *t = 0; do { *--t = u % 10u + '0'; u /= 10u; } while (u); memcpy (q, t, 12); *s = (char *)(q + (b + 12 - t)); } static inline uint64_t str2uint64 (uint8_t **s) { uint8_t *p = *s; uint64_t v = 0; uint8_t z; while ((z = *p ^ '0') < 10) v = (v << 3) + (v << 1) + z, p++; *s = p; return v; } static inline uint32_t str2uint32 (uint8_t **s) { uint8_t *p = *s, z; uint32_t v = 0; while ((z = *p ^ '0') < 10) v = v * 10u + z, p++; *s = p; return v; } static inline uint32_t hexstr2uint32 (uint8_t **s) { static const int8_t tab_unhex[256] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-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,-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,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,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,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; uint8_t *p = *s; uint32_t v = 0; int32_t z; while ((z = tab_unhex[*p]) >= 0) v = (v << 4) | z, p++; *s = p; return v; } typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; xine_t *xine; xine_nbc_t *nbc; off_t curpos; uint64_t contentlength; uint64_t bytes_left; uint64_t range_start; uint64_t range_end; uint64_t range_total; const char *user_agent; xine_url_t url; xine_url_t proxyurl; xine_tls_t *tls; FILE *head_dump_file; int use_proxy; int use_tls; int ret; int fh; uint32_t sgot; uint32_t sdelivered; uint32_t schunkleft; uint32_t zgot; uint32_t zdelivered; #define MODE_CHUNKED 0x0001 /* content sent portion-wise */ #define MODE_DEFLATED 0x0002 /* content needs inflating */ #define MODE_HAS_TYPE 0x0004 /* there is (at least the type of) content */ #define MODE_HAS_LENGTH 0x0008 /* content size is known */ #define MODE_AGAIN 0x0010 /* follow a redirection */ #define MODE_INFLATING 0x0020 /* zlib inflater is up */ #define MODE_DONE 0x0040 /* end of content reached */ #define MODE_HAVE_CHUNK 0x0100 /* there are content portions left */ #define MODE_HAVE_SBUF 0x0200 /* there are content bytes in sbuf */ #define MODE_HAVE_READ 0x0400 /* socket still has data to read */ #define MODE_SEEKABLE 0x1000 /* server supports byte ranges */ #define MODE_NSV 0x2000 /* we have a nullsoft stream */ #define MODE_LASTFM 0x4000 /* we have a last.fm stream */ #define MODE_SHOUTCAST 0x8000 /* content has info inserts */ uint32_t mode; uint32_t status; z_stream z_state; /* avoid annoying ui messages on fragment streams */ int num_msgs; /* ShoutCast */ uint32_t shoutcast_interval; uint32_t shoutcast_left; char *shoutcast_songtitle; char mime_type[128]; uint8_t zbuf[32 << 10]; uint8_t zbuf_pad[4]; uint8_t sbuf[32 << 10]; uint8_t sbuf_pad[4]; struct { off_t start; int32_t size; uint8_t buf[MAX_PREVIEW_SIZE]; } preview; char mrl[4096]; } http_input_plugin_t; typedef struct { input_class_t input_class; xine_t *xine; const char *proxyhost; int proxyport; int prot_version; const char *proxyuser; const char *proxypassword; const char *noproxylist; const char *head_dump_name; } http_input_class_t; static void sbuf_init (http_input_plugin_t *this) { this->zgot = 0; this->zdelivered = 0; this->sgot = 0; this->sdelivered = 0; this->schunkleft = 0; this->mode &= ~(MODE_HAVE_SBUF | MODE_INFLATING); } static void sbuf_reset (http_input_plugin_t *this) { this->zgot = 0; this->zdelivered = 0; this->sgot = 0; this->sdelivered = 0; this->schunkleft = 0; if (this->mode & MODE_INFLATING) { this->z_state.next_in = this->sbuf; this->z_state.avail_in = 0; this->z_state.next_out = this->sbuf; this->z_state.avail_out = 0; inflateEnd (&this->z_state); } this->mode &= ~(MODE_HAVE_SBUF | MODE_INFLATING); } static int32_t sbuf_get_string (http_input_plugin_t *this, uint8_t **buf) { uint8_t *p = *buf = this->sbuf + this->sdelivered; while (1) { /* find end of line or data */ { uint8_t *stop = this->sbuf + this->sgot; *stop = '\n'; while (*p != '\n') p++; /* found */ if (p != stop) { size_t n = p - *buf + 1; if (this->head_dump_file) fwrite (*buf, 1, n, this->head_dump_file); this->sdelivered += n; n--; if (n && (p[-1] == '\r')) p--, n--; *p = 0; return n; } } /* move to beginning of buffer */ if (this->sdelivered) { size_t n = this->sgot - this->sdelivered; if (n) { if (this->sdelivered < n) memmove (this->sbuf, this->sbuf + this->sdelivered, n); else memcpy (this->sbuf, this->sbuf + this->sdelivered, n); } *buf = p = this->sbuf; p += n; this->sgot = n; this->sdelivered = 0; } { int32_t r; uint32_t n = sizeof (this->sbuf) - this->sgot; if (n > this->bytes_left) n = this->bytes_left; /* buffer full or no more input */ if (n == 0) { this->sgot = 0; return -1; } /* refill fast buffer */ r = _x_tls_part_read (this->tls, p, 1, n); if (r <= 0) { this->mode &= ~MODE_HAVE_READ; this->bytes_left = 0; return -1; } this->sgot += r; this->bytes_left -= r; this->mode |= MODE_HAVE_SBUF | MODE_HAVE_READ; } } } /* zlib dislikes that common 1f 8b 08 00 00 00 00 00 00 00. * checksum 0 _is_ wrong but also flagged unset :-/ */ static int sbuf_skip_gzip_head (uint8_t *buf, uint32_t len) { uint8_t *b = buf, *stop = b + len; uint32_t flags; if (len < 10) return 0; if ((b[0] != 0x1f) || (b[1] != 0x8b)) return 0; if (b[2] != 0x08) return 0; flags = b[3]; b += 10; /* timestamp, XFL, OS */ if (flags & 4) { uint32_t len = ((uint32_t)b[1] << 8) | b[0]; b += 2 + len; if (b > stop) return 0; /* extra data */ } buf[len] = 0; if (flags & 8) { while (*b++) ; if (b > stop) return 0; /* file name */ } if (flags & 16) { while (*b++) ; if (b > stop) return 0; /* comment */ } if (flags & 2) { b += 2; if (b > stop) return 0; /* CRC16 */ } return b - buf; } static ssize_t sbuf_get_bytes (http_input_plugin_t *this, uint8_t *buf, size_t len) { uint8_t *q = buf; size_t left = len; switch (this->mode & (MODE_CHUNKED | MODE_DEFLATED)) { case 0: if (left == 0) break; /* get from fast buffer */ do { uint32_t fast = this->sgot - this->sdelivered; if (fast == 0) break; if (fast > left) { memcpy (q, this->sbuf + this->sdelivered, left); this->sdelivered += left; return left; } memcpy (q, this->sbuf + this->sdelivered, fast); q += fast; left -= fast; this->sgot = this->sdelivered = 0; } while (0); /* get the usual way */ if (left > this->bytes_left) left = this->bytes_left; if (left > 0) { ssize_t r = _x_tls_read (this->tls, q, left); if (r > 0) { q += r; this->bytes_left -= r; } else { this->mode &= ~MODE_HAVE_READ; this->bytes_left = 0; } } break; case MODE_CHUNKED + MODE_DEFLATED: /* sigh. chunk switches may appear in the middle of a deflate symbol. * we need to remove them before presenting the stream to zlib. */ if (this->mode & MODE_DONE) return 0; while (left > 0) { uint32_t have = this->zgot - this->zdelivered; /* refill zbuf */ if ((have < 128) && (this->mode & (MODE_HAVE_CHUNK | MODE_HAVE_SBUF | MODE_HAVE_READ))) { uint32_t want; /* align */ if (this->zdelivered >= 128) { if (have > 0) xine_small_memcpy (this->zbuf, this->zbuf + this->zdelivered, have); this->zgot = have; this->zdelivered = 0; } /* start new chunk */ if ((this->schunkleft == 0) && (this->mode & MODE_HAVE_CHUNK)) { uint8_t *p; int32_t n = sbuf_get_string (this, &p); if (n == 0) n = sbuf_get_string (this, &p); if (n > 0) { this->schunkleft = hexstr2uint32 (&p); if (this->schunkleft == 0) this->mode &= ~(MODE_HAVE_CHUNK | MODE_HAVE_READ); } else { this->mode &= ~(MODE_HAVE_CHUNK | MODE_HAVE_READ); } } /* refill zbuf from sbuf */ want = sizeof (this->zbuf) - this->zgot; if (want > this->schunkleft) want = this->schunkleft; if (this->mode & MODE_HAVE_SBUF) { uint32_t bytes = this->sgot - this->sdelivered; if (bytes > want) bytes = want; if (bytes > 0) { memcpy (this->zbuf + this->zgot, this->sbuf + this->sdelivered, bytes); this->zgot += bytes; this->sdelivered += bytes; this->schunkleft -= bytes; want -= bytes; } if (this->sgot <= this->sdelivered) { this->sgot = 0; this->sdelivered = 0; this->mode &= ~MODE_HAVE_SBUF; } } /* refill zbuf from stream */ if ((want > 0) && (this->mode & (MODE_HAVE_SBUF | MODE_HAVE_READ)) == MODE_HAVE_READ) { int32_t r = _x_tls_read (this->tls, this->zbuf + this->zgot, want); if (r > 0) { this->zgot += r; this->schunkleft -= r; } else this->mode &= ~MODE_HAVE_READ; } /* collect small chunks */ if ((this->schunkleft == 0) && (this->mode & MODE_HAVE_CHUNK)) continue; /* new size */ have = this->zgot - this->zdelivered; } /* init zlib */ if ((this->mode & MODE_INFLATING) == 0) { uint32_t head_len = sbuf_skip_gzip_head (this->zbuf, this->zgot); this->zdelivered += head_len; have -= head_len; this->z_state.next_in = this->zbuf + this->zdelivered; this->z_state.avail_in = have; this->z_state.next_out = q; this->z_state.avail_out = left; this->z_state.zalloc = NULL; this->z_state.zfree = NULL; this->z_state.opaque = NULL; if (inflateInit2 (&this->z_state, -15) != Z_OK) { this->mode |= MODE_DONE; break; } this->mode |= MODE_INFLATING; } /* deflate */ { int32_t bytes; int z_ret_code1; this->z_state.next_in = this->zbuf + this->zdelivered; this->z_state.avail_in = have; this->z_state.next_out = q; this->z_state.avail_out = left; z_ret_code1 = inflate (&this->z_state, Z_SYNC_FLUSH); if ((z_ret_code1 != Z_OK) && (z_ret_code1 != Z_STREAM_END)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_http: zlib error #%d.\n", z_ret_code1); this->mode |= MODE_DONE; break; } bytes = have - this->z_state.avail_in; if (bytes < 0) break; this->zdelivered += bytes; if (this->zdelivered > this->zgot) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_http: zbuf overrun??\n"); this->zdelivered = this->zgot = 0; } bytes = left - this->z_state.avail_out; if (bytes < 0) break; q += bytes; left -= bytes; if (z_ret_code1 == Z_STREAM_END) { this->mode |= MODE_DONE; break; } } } if ((this->mode & (MODE_DONE | MODE_INFLATING)) == (MODE_DONE | MODE_INFLATING)) { int bytes_out; bytes_out = this->z_state.avail_out; inflateEnd (&this->z_state); bytes_out -= this->z_state.avail_out; if (bytes_out > 0) q += bytes_out; this->mode &= ~MODE_INFLATING; } break; case MODE_CHUNKED: if (this->mode & MODE_DONE) return 0; while (left > 0) { uint32_t fast, chunkleft; if (this->schunkleft == 0) { uint8_t *p; int32_t n; if (this->mode & MODE_DONE) return 0; n = sbuf_get_string (this, &p); if (n == 0) n = sbuf_get_string (this, &p); if (n <= 0) break; this->schunkleft = hexstr2uint32 (&p); if (this->schunkleft == 0) { this->mode |= MODE_DONE; break; } } chunkleft = left < this->schunkleft ? left : this->schunkleft; fast = this->sgot - this->sdelivered; if (fast > chunkleft) fast = chunkleft; if (fast > 0) { /* get from fast buffer */ memcpy (q, this->sbuf + this->sdelivered, fast); q += fast; left -= fast; this->schunkleft -= fast; this->sdelivered += fast; if (this->sgot == this->sdelivered) this->sgot = this->sdelivered = 0; } else { /* get the usual way */ ssize_t r = _x_tls_read (this->tls, q, chunkleft); if (r <= 0) { this->mode |= MODE_DONE; break; } q += r; this->schunkleft -= r; left -= r; } } break; case MODE_DEFLATED: if (this->mode & MODE_DONE) return 0; while (left > 0) { uint32_t have = this->sgot - this->sdelivered; /* refill sbuf */ if ((have < 128) && (this->mode & MODE_HAVE_READ)) { uint32_t want; /* align */ if (this->sdelivered >= 128) { if (have > 0) xine_small_memcpy (this->sbuf, this->sbuf + this->sdelivered, have); this->sgot = have; this->sdelivered = 0; } /* refill */ want = sizeof (this->sbuf) - this->sgot; if (want > this->bytes_left) want = this->bytes_left; if (want == 0) { this->mode &= ~MODE_HAVE_READ; this->bytes_left = 0; } else { int32_t r = _x_tls_read (this->tls, this->sbuf + this->sgot, want); if (r > 0) { this->sgot += r; have += r; this->bytes_left -= r; } else { this->mode &= ~MODE_HAVE_READ; this->bytes_left = 0; } } } /* init zlib */ if (!(this->mode & MODE_INFLATING)) { uint32_t head_len = sbuf_skip_gzip_head (this->sbuf + this->sdelivered, have); this->sdelivered += head_len; have -= head_len; this->z_state.next_in = this->sbuf + this->sdelivered; this->z_state.avail_in = have; this->z_state.next_out = q; this->z_state.avail_out = left; this->z_state.zalloc = NULL; this->z_state.zfree = NULL; this->z_state.opaque = NULL; if (inflateInit2 (&this->z_state, -15) != Z_OK) { this->mode |= MODE_DONE; break; } this->mode |= MODE_INFLATING; } /* deflate */ { int z_ret_code1; int32_t bytes; this->z_state.next_in = this->sbuf + this->sdelivered; this->z_state.avail_in = have; this->z_state.next_out = q; this->z_state.avail_out = left; z_ret_code1 = inflate (&this->z_state, Z_SYNC_FLUSH); if ((z_ret_code1 != Z_OK) && (z_ret_code1 != Z_STREAM_END)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_http: zlib error #%d.\n", z_ret_code1); this->mode |= MODE_DONE; break; } bytes = have - this->z_state.avail_in; if (bytes < 0) break; this->sdelivered += bytes; bytes = left - this->z_state.avail_out; if (bytes < 0) break; q += bytes; left -= bytes; if (z_ret_code1 == Z_STREAM_END) { this->mode |= MODE_DONE; break; } } } if ((this->mode & (MODE_DONE | MODE_INFLATING)) == (MODE_DONE | MODE_INFLATING)) { int bytes_out; bytes_out = this->z_state.avail_out; inflateEnd (&this->z_state); bytes_out -= this->z_state.avail_out; if (bytes_out > 0) q += bytes_out; this->mode &= ~MODE_INFLATING; } break; } return q - buf; } static void proxy_host_change_cb (void *this_gen, xine_cfg_entry_t *cfg) { http_input_class_t *this = (http_input_class_t *)this_gen; this->proxyhost = cfg->str_value; } static void proxy_port_change_cb(void *this_gen, xine_cfg_entry_t *cfg) { http_input_class_t *this = (http_input_class_t *)this_gen; this->proxyport = cfg->num_value; } static void proxy_user_change_cb(void *this_gen, xine_cfg_entry_t *cfg) { http_input_class_t *this = (http_input_class_t *)this_gen; this->proxyuser = cfg->str_value; } static void proxy_password_change_cb(void *this_gen, xine_cfg_entry_t *cfg) { http_input_class_t *this = (http_input_class_t *)this_gen; this->proxypassword = cfg->str_value; } static void no_proxy_list_change_cb(void *this_gen, xine_cfg_entry_t *cfg) { http_input_class_t *this = (http_input_class_t *)this_gen; this->noproxylist = cfg->str_value; } static void prot_version_change_cb (void *this_gen, xine_cfg_entry_t *cfg) { http_input_class_t *this = (http_input_class_t *)this_gen; this->prot_version = cfg->num_value; } static void head_dump_name_change_cb (void *this_gen, xine_cfg_entry_t *cfg) { http_input_class_t *this = (http_input_class_t *)this_gen; this->head_dump_name = cfg->str_value; } /* * handle no-proxy list config option and returns, if use the proxy or not * if error occurred, is expected using the proxy */ static int _x_use_proxy(xine_t *xine, http_input_class_t *this, const char *host) { const char *target; char *no_proxy, *domain, *ptr = NULL; struct hostent *info; size_t i = 0, host_len, noprox_len; /* * get full host name */ if ((info = gethostbyname(host)) == NULL) { xine_log(xine, XINE_LOG_MSG, _("input_http: gethostbyname(%s) failed: %s\n"), host, hstrerror(h_errno)); return 1; } if (!info->h_name) return 1; if ( info->h_addr_list[0] ) { /* \177\0\0\1 is the *octal* representation of 127.0.0.1 */ if ( info->h_addrtype == AF_INET && !memcmp(info->h_addr_list[0], "\177\0\0\1", 4) ) { lprintf("host '%s' is localhost\n", host); return 0; } /* TODO: IPv6 check */ } target = info->h_name; host_len = strlen(target); no_proxy = strdup(this->noproxylist); domain = strtok_r(no_proxy, ",", &ptr); while (domain) { /* skip leading spaces */ while (isspace (*domain)) ++domain; /* only check for matches if we've not reached the end of the token */ if (*domain) { /* special-case domain beginning with '=' -> is a host name */ if (domain[0] == '=' && strcmp(target, domain + 1) == 0) { lprintf("host '%s' is in no-proxy domain '%s'\n", target, domain); free(no_proxy); return 0; } noprox_len = strlen(domain); /* special-case host==domain, avoiding dot checks */ if (host_len == noprox_len && strcmp(target, domain) == 0) { lprintf("host '%s' is in no-proxy domain '%s'\n", target, domain); free(no_proxy); return 0; } /* check for host in domain, and require that (if matched) the domain * name is preceded by a dot, either in the host or domain strings, * e.g. "a.foo.bar" is in "foo.bar" and ".foo.bar" but not "o.bar" */ if (host_len > noprox_len && (domain[0] == '.' || target[host_len - noprox_len - 1] == '.') && strcmp(target + host_len - noprox_len, domain) == 0) { lprintf("host '%s' is in no-proxy domain '%s'\n", target, domain); free(no_proxy); return 0; } lprintf("host '%s' isn't in no-proxy domain '%s'\n", target, domain); } domain = strtok_r(NULL, ",", &ptr); i++; } free(no_proxy); return 1; } static size_t http_plugin_basicauth (const char *user, const char *password, char* dest, size_t len) { size_t s1 = strlen (user); size_t s2 = password ? strlen (password) : 0; size_t s3 = (s1 + s2) * 4 / 3 + 16; if (s3 > len) return 0; xine_small_memcpy (dest + s3 - s2 - s1 - 1, user, s1); dest[s3 - s2 - 1] = ':'; if (s2) xine_small_memcpy (dest + s3 - s2, password, s2); return xine_base64_encode ((uint8_t *)dest + s3 - s2 - s1 - 1, dest, s1 + s2 + 1); } static int http_plugin_read_metainf (http_input_plugin_t *this) { char metadata_buf[256 * 16]; unsigned char len = 0; char *title_end; const char *songtitle; const char *radio; xine_event_t uevent; xine_ui_data_t data; /* get the length of the metadata */ if (sbuf_get_bytes (this, (uint8_t *)&len, 1) != 1) return 0; lprintf ("http_plugin_read_metainf: len=%d\n", len); if (len > 0) { if (sbuf_get_bytes (this, (uint8_t *)metadata_buf, len * 16) != (len * 16)) return 0; metadata_buf[len * 16] = '\0'; lprintf ("http_plugin_read_metainf: %s\n", metadata_buf); if (!this->stream) return 1; /* Extract the title of the current song */ if ((songtitle = strstr(metadata_buf, "StreamTitle="))) { char terminator[] = { ';', 0, 0 }; songtitle += 12; /* skip "StreamTitle=" */ if (*songtitle == '\'' || *songtitle == '"') { terminator[0] = *songtitle++; terminator[1] = ';'; } if ((title_end = strstr(songtitle, terminator))) { *title_end = '\0'; if ((!this->shoutcast_songtitle || (strcmp(songtitle, this->shoutcast_songtitle))) && (strlen(songtitle) > 0)) { lprintf ("http_plugin_read_metainf: songtitle: %s\n", songtitle); free(this->shoutcast_songtitle); this->shoutcast_songtitle = strdup(songtitle); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, songtitle); /* prepares the event */ radio = _x_meta_info_get(this->stream, XINE_META_INFO_ALBUM); if (radio) { snprintf (data.str, sizeof(data.str), "%s - %s", radio, songtitle); } else { strncpy(data.str, songtitle, sizeof(data.str)-1); } data.str[sizeof(data.str) - 1] = '\0'; data.str_len = strlen(data.str) + 1; /* sends the event */ uevent.type = XINE_EVENT_UI_SET_TITLE; uevent.stream = this->stream; uevent.data = &data; uevent.data_length = sizeof(data); xine_event_send(this->stream, &uevent); } } } } return 1; } /* * Handle shoutcast packets */ static ssize_t http_plugin_read_int (http_input_plugin_t *this, uint8_t *buf, size_t total) { size_t read_bytes = 0; lprintf("total=%"PRId64"\n", total); if (this->mode & MODE_SHOUTCAST) { /* shunt away info inserts */ while (total) { ssize_t r; if (total >= this->shoutcast_left) { r = sbuf_get_bytes (this, buf + read_bytes, this->shoutcast_left); if (r < 0) goto error; if (!http_plugin_read_metainf (this)) goto error; this->shoutcast_left = this->shoutcast_interval; } else { r = sbuf_get_bytes (this, buf + read_bytes, total); if (r < 0) goto error; this->shoutcast_left -= r; /* end of file */ if (r == 0) break; } read_bytes += r; total -= r; } } else { /* read as is */ ssize_t r = sbuf_get_bytes (this, buf, total); if (r < 0) goto error; read_bytes += r; } if (this->mode & MODE_LASTFM) { /* Identify SYNC string for last.fm, this is limited to last.fm * streaming servers to avoid hitting on tracks metadata for other servers. */ if (read_bytes && memmem (buf, read_bytes, "SYNC", 4) && this->stream) { /* Tell frontend to update the UI */ const xine_event_t event = { .type = XINE_EVENT_UI_CHANNELS_CHANGED, .stream = this->stream, .data = NULL, .data_length = 0 }; lprintf ("SYNC from last.fm server received\n"); xine_event_send (this->stream, &event); } } return read_bytes; error: if (this->stream && !_x_action_pending(this->stream)) _x_message (this->stream, XINE_MSG_READ_ERROR, this->url.host, NULL); xine_log (this->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno); return read_bytes; } static off_t http_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t nlen) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; off_t diff; size_t want, num_bytes; if (nlen < 0) return -1; want = nlen; if (want == 0) return 0; num_bytes = 0; diff = this->preview.start + this->preview.size - this->curpos; if (diff > 0) { uint32_t have = diff, start = this->curpos - this->preview.start; if (have > want) have = want; lprintf ("%u bytes from preview (which has %u bytes)\n", (unsigned int)have, (unsigned int)this->preview.size); memcpy (buf, this->preview.buf + start, have); num_bytes += have; want -= have; this->curpos += have; } if (want > 0) { ssize_t r = http_plugin_read_int (this, (uint8_t *)buf + num_bytes, want); if (r > 0) { num_bytes += r; this->curpos += r; } } return num_bytes; } static off_t http_plugin_get_length (input_plugin_t *this_gen) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; return this->contentlength; } static uint32_t http_plugin_get_capabilities (input_plugin_t *this_gen) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; uint32_t caps = INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW | INPUT_CAP_NEW_MRL; /* Nullsoft asked to not allow saving streaming nsv files */ if (this->mode & MODE_NSV) caps |= INPUT_CAP_RIP_FORBIDDEN; if (this->mode & MODE_SEEKABLE) { caps |= INPUT_CAP_SLOW_SEEKABLE; } else if (this->shoutcast_interval) { caps |= INPUT_CAP_LIVE; } return caps; } static off_t http_plugin_get_current_pos (input_plugin_t *this_gen){ http_input_plugin_t *this = (http_input_plugin_t *) this_gen; return this->curpos; } static void http_close(http_input_plugin_t * this) { _x_tls_deinit (&this->tls); if (this->fh >= 0) { _x_io_tcp_close (this->stream, this->fh); this->fh = -1; } _x_url_cleanup (&this->proxyurl); _x_url_cleanup (&this->url); } static int http_restart(http_input_plugin_t * this, off_t abs_offset) { /* save old stream */ xine_tls_t *old_tls = this->tls; off_t old_pos = this->curpos; int old_fh = this->fh; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": seek to %" PRId64 ": reconnecting ...\n", (int64_t)abs_offset); do { this->tls = NULL; this->fh = -1; _x_url_cleanup (&this->proxyurl); _x_url_cleanup (&this->url); this->curpos = abs_offset; if (this->input_plugin.open (&this->input_plugin) != 1) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": seek to %" PRId64 " failed (http request failed)\n", (int64_t)abs_offset); break; } if (this->curpos != abs_offset) { /* something went wrong ... */ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": seek to %" PRId64 " failed (server returned invalid range)\n", (int64_t)abs_offset); break; } /* close old connection */ _x_tls_deinit (&old_tls); if (old_fh >= 0) _x_io_tcp_close (this->stream, old_fh); return 0; } while (0); /* restore old stream */ _x_tls_deinit (&this->tls); if (this->fh >= 0) _x_io_tcp_close (this->stream, this->fh); this->tls = old_tls; this->curpos = old_pos; this->fh = old_fh; return -1; } static off_t http_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; off_t abs_offset; abs_offset = _x_input_seek_preview(this_gen, offset, origin, &this->curpos, this->contentlength, this->preview.size); if (abs_offset < 0 && (this->mode & MODE_SEEKABLE)) { abs_offset = _x_input_translate_seek(offset, origin, this->curpos, this->contentlength); if (abs_offset < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, "input_http: invalid seek request (%d, %" PRId64 ")\n", origin, (int64_t)offset); return -1; } if (http_restart(this, abs_offset) < 0) return -1; } return abs_offset; } static const char* http_plugin_get_mrl (input_plugin_t *this_gen) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; return this->mrl; } static void http_plugin_dispose (input_plugin_t *this_gen ) { http_input_plugin_t *this = (http_input_plugin_t *) this_gen; http_close(this); sbuf_reset (this); if (this->nbc) { xine_nbc_close (this->nbc); this->nbc = NULL; } if (this->head_dump_file) { fclose (this->head_dump_file); this->head_dump_file = NULL; } free (this); } static void report_progress (xine_stream_t *stream, int p) { xine_event_t event; xine_progress_data_t prg; if (!stream) return; prg.description = _("Connecting HTTP server..."); prg.percent = p; event.type = XINE_EVENT_PROGRESS; event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (stream, &event); } typedef enum { _K_NONE = 0, _K_content_length, _K_content_type, _K_content_encoding, _K_content_range, _K_transfer_encoding, _K_accept_ranges, _K_location, _K_server, _K_www_authenticate, _K_icy_name, _K_icy_genre, _K_icy_notice2, _K_icy_metaint, _K_LAST } _k_t; static _k_t http_key_num (const char *key, uint32_t klen) { switch (klen) { case 6: if (!memcmp (key, "server", 6)) return _K_server; break; case 8: if (!memcmp (key, "icy-name", 8)) return _K_icy_name; if (!memcmp (key, "location", 8)) return _K_location; break; case 9: if (!memcmp (key, "icy-genre", 9)) return _K_icy_genre; break; case 11: if (!memcmp (key, "icy-metaint", 11)) return _K_icy_metaint; if (!memcmp (key, "icy-notice2", 11)) return _K_icy_notice2; break; case 12: if (!memcmp (key, "content-type", 12)) return _K_content_type; break; case 13: if (!memcmp (key, "accept-ranges", 13)) return _K_accept_ranges; if (!memcmp (key, "content-range", 13)) return _K_content_range; break; case 14: if (!memcmp (key, "content-length", 14)) return _K_content_length; break; case 16: if (!memcmp (key, "content-encoding", 16)) return _K_content_encoding; if (!memcmp (key, "www-authenticate", 16)) return _K_www_authenticate; break; case 17: if (!memcmp (key, "transfer-encoding", 17)) return _K_transfer_encoding; break; default: ; } return _K_NONE; } static xio_handshake_status_t http_plugin_handshake (void *userdata, int fh) { static const uint8_t tab_tolower[256] = { 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, ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?', '@','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z','[','\\',']','^','_', '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~',127, 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,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 }; http_input_plugin_t *this = (http_input_plugin_t *)userdata; http_input_class_t *this_class = (http_input_class_t *) this->input_plugin.input_class; int res; int mpegurl_redirect = 0; char mime_type[128]; { char httpstatus[128]; httpstatus[0] = 0; mime_type[0] = 0; sbuf_reset (this); { uint32_t timeout, progress; timeout = _x_query_network_timeout (this->xine) * 1000; if (timeout == 0) timeout = 30000; progress = 0; do { if (this->num_msgs) { if (this->num_msgs > 0) this->num_msgs--; report_progress (this->stream, progress); } res = _x_io_select (this->stream, fh, XIO_WRITE_READY, 500); progress += (500 * 100000) / timeout; } while ((res == XIO_TIMEOUT) && (progress <= 100000) && !_x_action_pending (this->stream)); if (res != XIO_READY) { _x_message (this->stream, XINE_MSG_NETWORK_UNREACHABLE, this->mrl, NULL); this->ret = -3; return XIO_HANDSHAKE_TRY_NEXT; } } /* TLS */ _x_assert (this->tls == NULL); this->tls = _x_tls_init (this->xine, this->stream, fh); if (!this->tls) { this->ret = -2; return XIO_HANDSHAKE_INTR; } if (this->use_tls) { int r = _x_tls_handshake (this->tls, this->url.host, -1); if (r < 0) { _x_message (this->stream, XINE_MSG_CONNECTION_REFUSED, "TLS handshake failed", NULL); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": TLS handshake failed\n"); this->ret = -4; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_TRY_NEXT; } xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": TLS handshake succeed, connection is encrypted\n"); } /* Request */ { /* total size of string literals: tfi input_http.c -x 0 "ADDLIT%q(%22%r%22)" "%r" -k -L (or just count yourself ;-) */ #define SIZEOF_LITERALS 205 /* max size needed for numbers */ #define SIZEOF_NUMS (1 * 24) #define ADDLIT(s) { static const char ls[] = s; memcpy (q, s, sizeof (ls)); q += sizeof (ls) - 1; } #define ADDSTR(s) q += strlcpy (q, s, e - q); if (q > e) q = e char *q = (char *)this->sbuf, *e = q + sizeof (this->sbuf) - SIZEOF_LITERALS - SIZEOF_NUMS - 1; char strport[16]; int vers = this_class->prot_version; if (this->url.port != DEFAULT_HTTP_PORT) { char *t = strport; *t++ = ':'; uint32_2str (&t, this->url.port); } else { strport[0] = 0; } ADDLIT ("GET "); if (this->use_proxy) { ADDSTR (this->url.proto); ADDLIT ("://"); ADDSTR (this->url.host); ADDSTR (strport); } ADDSTR (this->url.uri); if (vers == 1) { ADDLIT (" HTTP/1.1\r\nHost: "); } else { ADDLIT (" HTTP/1.0\r\nHost: "); } ADDSTR (this->url.host); ADDSTR (strport); if (this->curpos > 0) { /* restart from offset */ ADDLIT ("\r\nRange: bytes="); uint64_2str (&q, this->curpos); ADDLIT ("-"); /* uint64_2str (&q, this->contentlength - 1); */ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_http: requesting restart from offset %" PRId64 "\n", (int64_t)this->curpos); } else if (vers == 1) { ADDLIT ("\r\nAccept-Encoding: gzip,deflate"); } if (this->use_proxy && this_class->proxyuser && this_class->proxyuser[0]) { ADDLIT ("\r\nProxy-Authorization: Basic "); q += http_plugin_basicauth (this_class->proxyuser, this_class->proxypassword, q, e - q); } if (this->url.user && this->url.user[0]) { ADDLIT ("\r\nAuthorization: Basic "); q += http_plugin_basicauth (this->url.user, this->url.password, q, e - q); } ADDLIT ("\r\nUser-Agent: "); if (this->user_agent) { ADDSTR (this->user_agent); ADDLIT (" "); } ADDLIT ("xine/" VERSION "\r\nAccept: */*\r\nIcy-MetaData: 1\r\n\r\n"); if (this->head_dump_file) fwrite (this->sbuf, 1, (uint8_t *)q - this->sbuf, this->head_dump_file); if (_x_tls_write (this->tls, this->sbuf, (uint8_t *)q - this->sbuf) != (uint8_t *)q - this->sbuf) { _x_message (this->stream, XINE_MSG_CONNECTION_REFUSED, "couldn't send request", NULL); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": couldn't send request\n"); this->ret = -4; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_TRY_NEXT; } lprintf ("request sent: >%s<\n", this->sbuf); #undef ADDSTR #undef ADDLIT #undef SIZEOF_LITERALS #undef SIZEOF_NUMS } this->mode &= ~(MODE_DONE | MODE_NSV | MODE_LASTFM | MODE_SHOUTCAST | MODE_AGAIN); /* Response */ do { this->mode &= ~(MODE_HAS_TYPE | MODE_HAS_LENGTH | MODE_DEFLATED | MODE_CHUNKED | MODE_HAVE_CHUNK | MODE_HAVE_SBUF); this->range_start = 0; this->range_end = 0; this->range_total = 0; /* get status */ { uint8_t *line, *p1, *p2; int32_t ok = 0, i = sbuf_get_string (this, &line); if ((i < 0) && (errno == EINTR)) { this->ret = -1; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_INTR; } do { if (i < 4) break; if ((memcmp (line, "HTTP", 4) && memcmp (line, "ICY ", 4))) break; p1 = line + i; *p1 = ' '; for (p2 = line + 4; *p2 != ' '; p2++) ; *p1 = 0; while (*p2 == ' ') p2++; this->status = str2uint32 (&p2); if (this->status == 0) break; while (*p2 == ' ') p2++; strlcpy (httpstatus, (char *)p2, sizeof (httpstatus)); ok = 1; } while (0); if (!ok) { _x_message (this->stream, XINE_MSG_CONNECTION_REFUSED, "invalid http answer", NULL); xine_log (this->xine, XINE_LOG_MSG, _("input_http: invalid http answer\n")); this->ret = -6; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_TRY_NEXT; } } /* get props */ while (1) { _k_t key; uint32_t klen; uint8_t *line, *p1, *p2; { int32_t i = sbuf_get_string (this, &line); if (i < 0) { /* "httpget.http: invalid HTTP response\n" */ this->ret = -1; _x_tls_deinit (&this->tls); return errno == EINTR ? XIO_HANDSHAKE_INTR : XIO_HANDSHAKE_TRY_NEXT; } /* an empty line marks the end of response head */ if (!i) break; p1 = line + i; } /* find value string */ *p1 = ':'; for (p2 = line; *p2 != ':'; p2++) *p2 = tab_tolower[*p2]; klen = p2 - line; *p1 = 0; if (p2 != p1) { *p2++ = 0; while (*p2 == ' ') p2++; } /* find key */ key = http_key_num (line, klen); switch (key) { case _K_content_length: if (!this->contentlength) this->contentlength = str2uint64 (&p2); this->mode |= MODE_HAS_LENGTH; break; case _K_content_type: strlcpy (mime_type, (char *)p2, sizeof (mime_type)); this->mode |= MODE_HAS_TYPE; if (!strncasecmp ((char *)p2, "audio/x-mpegurl", 15)) { lprintf ("Opening an audio/x-mpegurl file, late redirect."); mpegurl_redirect = 1; } else if (!strncasecmp ((char *)p2, "video/nsv", 9)) { lprintf ("shoutcast nsv detected\n"); this->mode |= MODE_NSV; } break; case _K_content_encoding: if ((!memcmp (p2, "gzip", 4)) || (!memcmp (p2, "deflate", 7))) this->mode |= MODE_DEFLATED; break; case _K_content_range: if (!memcmp (p2, "bytes", 5)) p2 += 5; while (*p2 == ' ') p2++; this->range_start = str2uint64 (&p2); if (*p2 == '-') { p2++; this->range_end = str2uint64 (&p2); } if (*p2 == '/') { p2++; this->range_total = str2uint64 (&p2); } break; case _K_transfer_encoding: if ((!memcmp (p2, "chunked", 7))) this->mode |= MODE_CHUNKED | MODE_HAVE_CHUNK; break; case _K_accept_ranges: if (strstr ((char *)line + 14, "bytes")) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_http: Server supports request ranges. Enabling seeking support.\n"); this->mode |= MODE_SEEKABLE; } else { xprintf (this->xine, XINE_VERBOSITY_LOG, "input_http: Unknown value in header \'%s\'\n", line + 14); this->mode &= ~MODE_SEEKABLE; } break; case _K_location: /* check redirection */ if ((this->status == 302) /* found */ || (this->status == 301) /* moved permanently */ || (this->status == 303) /* see other */ || (this->status == 307)) { /* temporary redirect */ lprintf ("trying to open target of redirection: >%s<\n", (char *)p2); _x_merge_mrl (this->mrl, sizeof (this->mrl), this->mrl, (char *)p2); } break; case _K_server: if (!strncasecmp ((char *)p2, "last.fm", 7)) { lprintf ("last.fm streaming server detected\n"); this->mode |= MODE_LASTFM; } break; case _K_www_authenticate: if (this->status == 401) _x_message (this->stream, XINE_MSG_AUTHENTICATION_NEEDED, this->mrl, (char *)p2, NULL); break; /* Icecast / ShoutCast Stuff */ case _K_icy_name: if (this->stream) { _x_meta_info_set (this->stream, XINE_META_INFO_ALBUM, (char *)p2); _x_meta_info_set (this->stream, XINE_META_INFO_TITLE, (char *)p2); } break; case _K_icy_genre: if (this->stream) _x_meta_info_set (this->stream, XINE_META_INFO_GENRE, (char *)p2); break; /* icy-notice1 is always the same */ case _K_icy_notice2: { char *end = strstr ((char *)p2, "<BR>"); if (end) *end = '\0'; if (this->stream) _x_meta_info_set (this->stream, XINE_META_INFO_COMMENT, (char *)p2); } break; case _K_icy_metaint: /* metadata interval (in byte) */ this->shoutcast_interval = this->shoutcast_left = str2uint32 (&p2); lprintf ("shoutcast_interval: %d\n", this->shoutcast_interval); if (this->shoutcast_interval) this->mode |= MODE_SHOUTCAST; break; default: ; } } if (this->sgot > this->sdelivered) this->mode |= MODE_HAVE_SBUF; /* skip non-document content */ if ((this->status != 200) && (this->status != 206)) while (this->contentlength > 0) { ssize_t s = sizeof (this->preview.buf); if ((uint64_t)s > this->contentlength) s = this->contentlength; s = sbuf_get_bytes (this, this->preview.buf, s); if (s <= 0) break; this->contentlength -= s; } /* indicate free content length */ if ((this->mode & (MODE_HAS_TYPE | MODE_HAS_LENGTH)) == MODE_HAS_TYPE) this->contentlength = ~(uint64_t)0; if (this->mode & MODE_CHUNKED) this->contentlength = ~(uint64_t)0; } while (this->status == 102); /* processing */ this->curpos = 0; switch (this->status / 100) { case 2: break; case 3: xine_log (this->xine, XINE_LOG_MSG, _("input_http: 3xx redirection: >%d %s<\n"), this->status, httpstatus); this->mode |= MODE_AGAIN; break; case 4: if (this->status == 404) { /* not found */ _x_message (this->stream, XINE_MSG_FILE_NOT_FOUND, this->mrl, NULL); xine_log (this->xine, XINE_LOG_MSG, _("input_http: http status not 2xx: >%d %s<\n"), this->status, httpstatus); this->ret = -7; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_INTR; } if (this->status == 401) { xine_log (this->xine, XINE_LOG_MSG, _("input_http: http status not 2xx: >%d %s<\n"), this->status, httpstatus); /* don't return - there may be a WWW-Authenticate header... */ break; } if (this->status == 403) { _x_message (this->stream, XINE_MSG_PERMISSION_ERROR, this->mrl, NULL); xine_log (this->xine, XINE_LOG_MSG, _("input_http: http status not 2xx: >%d %s<\n"), this->status, httpstatus); this->ret = -8; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_INTR; } /* fall through */ default: _x_message (this->stream, XINE_MSG_CONNECTION_REFUSED, "http status not 2xx: ", httpstatus, NULL); xine_log (this->xine, XINE_LOG_MSG, _("input_http: http status not 2xx: >%d %s<\n"), this->status, httpstatus); this->ret = -9; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_TRY_NEXT; } if (this->mode & MODE_HAS_LENGTH) xine_log (this->xine, XINE_LOG_MSG, _("input_http: content length = %" PRId64 " bytes\n"), (int64_t)this->contentlength); if (this->range_start) { this->curpos = this->range_start; if (this->contentlength != this->range_end + 1) { xprintf (this->xine, XINE_VERBOSITY_LOG, "input_http: Reveived invalid content range"); /* truncate - there won't be more data anyway */ this->contentlength = this->range_end + 1; } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_http: Stream starting at offset %" PRIu64 "\n.", this->range_start); } } #if 0 if ( len >= (int)sizeof(buf) ) { _x_message(this->stream, XINE_MSG_PERMISSION_ERROR, this->mrl, NULL); xine_log (this->xine, XINE_LOG_MSG, _("input_http: buffer exhausted after %zu bytes."), sizeof(buf)); this->ret = -10; _x_tls_deinit (&this->tls); return XIO_HANDSHAKE_TRY_NEXT; } #endif lprintf ("end of headers\n"); if (mpegurl_redirect) { ssize_t l = sbuf_get_bytes (this, this->preview.buf, sizeof (this->preview.buf) - 1); if (l > 0) { uint8_t *p = this->preview.buf; p[l] = 0; while (p[0] & 0xe0) p++; /* If the newline can't be found, either the 4K buffer is too small, or * more likely something is fuzzy. */ if (p < this->preview.buf + l) { *p = 0; lprintf ("mpegurl pointing to %s\n", (char *)this->preview.buf); _x_merge_mrl (this->mrl, sizeof (this->mrl), this->mrl, (char *)this->preview.buf); this->mode |= MODE_AGAIN; } } } } strcpy (this->mime_type, mime_type); return XIO_HANDSHAKE_OK; } static int http_plugin_open (input_plugin_t *this_gen) { http_input_plugin_t *this = (http_input_plugin_t *)this_gen; http_input_class_t *this_class = (http_input_class_t *) this->input_plugin.input_class; int redirections = 20; do { int proxyport, mrl_tls, proxy_tls; http_close (this); if (--redirections <= 0) { xprintf (this->xine, XINE_VERBOSITY_LOG, "input_http: too many redirections, giving up.\n"); return -1; } this->user_agent = _x_url_user_agent (this->mrl); if (!_x_url_parse2 (this->mrl, &this->url)) { _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "malformed url", NULL); return 0; } /* NOTE: mrl = http | https * proxy = http | https * all 4 combinations are valid! */ this->use_tls = mrl_tls = !strcasecmp (this->url.proto, "https"); if (this->url.port == 0) this->url.port = mrl_tls ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT; this->use_proxy = (this_class->proxyhost && this_class->proxyhost[0]); if (this->use_proxy && !_x_use_proxy (this->xine, this_class, this->url.host)) this->use_proxy = 0; if (this->use_proxy && !_x_url_parse2 (this_class->proxyhost, &this->proxyurl)) { _x_message (this->stream, XINE_MSG_GENERAL_WARNING, "malformed proxy url", NULL); this->use_proxy = 0; } proxyport = this_class->proxyport; if (this->use_proxy) { this->use_tls = proxy_tls = !strcasecmp (this->proxyurl.proto, "https"); if (proxyport == 0) proxyport = proxy_tls ? DEFAULT_HTTPS_PORT : DEFAULT_HTTP_PORT; } #ifdef LOG printf ("input_http: host : >%s<\n", this->url.host); printf ("input_http: port : >%d<\n", this->url.port); printf ("input_http: user : >%s<\n", this->url.user); printf ("input_http: password : >%s<\n", this->url.password); printf ("input_http: path : >%s<\n", this->url.uri); if (this->use_proxy) printf (" via proxy >%s:%d<", this_class->proxyhost, proxyport); printf ("\n"); #endif this->bytes_left = ~(uint64_t)0; this->ret = -2; if (this->use_proxy) this->fh = _x_io_tcp_handshake_connect (this->stream, this_class->proxyhost, proxyport, http_plugin_handshake, this); else this->fh = _x_io_tcp_handshake_connect (this->stream, this->url.host, this->url.port, http_plugin_handshake, this); if (this->fh < 0) return this->ret; } while (this->mode & MODE_AGAIN); if (this->contentlength != ~(uint64_t)0) this->bytes_left = this->contentlength - this->curpos - this->sgot + this->sdelivered; else this->contentlength = 0; if (this->mode & MODE_DEFLATED) this->contentlength = 0; if (this->head_dump_file) fflush (this->head_dump_file); if (this->curpos > 0) { /* restarting after seek */ this->preview.size = 0; return 1; } /* fill preview buffer */ this->preview.size = http_plugin_read_int (this, this->preview.buf, sizeof (this->preview.buf)); if (this->mode & MODE_NSV) { #define V_NSV (('N' << 24) | ('S' << 16) | ('V' << 8)) int32_t max_bytes = 1 << 20; uint32_t v = 0; uint8_t *p = this->preview.buf, *e = p + this->preview.size; lprintf ("resyncing NSV stream\n"); while (this->preview.size > 2) { if ((max_bytes -= this->preview.size) <= 0) break; while (p < e) { v = (v | *p++) << 8; if (v == V_NSV) break; } if (v == V_NSV) break; this->preview.buf[0] = e[-2]; this->preview.buf[1] = e[-1]; this->preview.size = http_plugin_read_int (this, this->preview.buf + 2, sizeof (this->preview.buf) - 2); p = this->preview.buf + 2; e = p + this->preview.size; } if (v != V_NSV) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "http: cannot resync NSV stream!\n"); _x_tls_deinit (&this->tls); _x_io_tcp_close (this->stream, this->fh); this->fh = -1; return -11; } this->preview.size = e - p + 3; if (p - 3 > this->preview.buf) memmove (this->preview.buf, p - 3, this->preview.size); if (this->preview.size < (int)sizeof (this->preview.buf)) { int32_t r = http_plugin_read_int (this, this->preview.buf + this->preview.size, sizeof (this->preview.buf) - this->preview.size); if (r > 0) this->preview.size += r; } lprintf ("NSV stream resynced\n"); } if (this->preview.size < 0) { this->preview.size = 0; xine_log (this->xine, XINE_LOG_MSG, _("input_http: read error %d\n"), errno); _x_tls_deinit (&this->tls); _x_io_tcp_close (this->stream, this->fh); this->fh = -1; return -12; } lprintf ("preview_size=%d\n", this->preview.size); this->curpos = 0; this->ret = 1; return 1; } static int http_can_handle (xine_stream_t *stream, const char *mrl) { if (!strncasecmp (mrl, "https://", 8)) { /* check for tls plugin here to allow trying another https plugin (avio) */ if (!_x_tls_available(stream->xine)) { xine_log (stream->xine, XINE_LOG_MSG, "input_http: TLS plugin not found\n"); return 0; } } else if (strncasecmp (mrl, "http://", 7) && strncasecmp (mrl, "unsv://", 7) && strncasecmp (mrl, "peercast://pls/", 15) && !_x_url_user_agent (mrl) /* user agent hacks */) { return 0; } return 1; } static int http_plugin_get_optional_data (input_plugin_t *this_gen, void *const data, int data_type) { void **const ptr = (void **const) data; http_input_plugin_t *this = (http_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: if (!data || (this->preview.size <= 0)) break; memcpy (data, this->preview.buf, this->preview.size); return this->preview.size; case INPUT_OPTIONAL_DATA_SIZED_PREVIEW: if (!data || (this->preview.size <= 0)) break; { int want; memcpy (&want, data, sizeof (want)); want = want < 0 ? 0 : want > this->preview.size ? this->preview.size : want; memcpy (data, this->preview.buf, want); return want; } case INPUT_OPTIONAL_DATA_NEW_PREVIEW: { uint32_t start = 0; off_t diff = this->curpos - this->preview.start; if (diff == 0) return INPUT_OPTIONAL_SUCCESS; if (diff > 0) { start = diff; diff = (off_t)this->preview.size - diff; if (diff > 0) { memmove (this->preview.buf, this->preview.buf + start, (uint32_t)diff); start = diff; } else { start = 0; } } this->preview.start = this->curpos; this->preview.size = 0; this->preview.size = start + http_plugin_read_int (this, this->preview.buf + start, sizeof (this->preview.buf) - start); } return INPUT_OPTIONAL_SUCCESS; case INPUT_OPTIONAL_DATA_MIME_TYPE: *ptr = this->mime_type; /* fall through */ case INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE: return *this->mime_type ? INPUT_OPTIONAL_SUCCESS : INPUT_OPTIONAL_UNSUPPORTED; case INPUT_OPTIONAL_DATA_NEW_MRL: if (!data) break; { const char *new_mrl = (const char *)data; if (new_mrl[0] && !http_can_handle (this->stream, data)) break; if (!new_mrl[0]) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_http: going standby.\n"); http_close (this); sbuf_reset (this); this->mrl[0] = 0; this->mime_type[0] = 0; _x_freep (&this->user_agent); _x_freep (&this->shoutcast_songtitle); this->curpos = 0; this->contentlength = 0; this->mode &= ~(MODE_DONE | MODE_SEEKABLE | MODE_NSV | MODE_LASTFM | MODE_SHOUTCAST); this->shoutcast_interval = 0; this->shoutcast_left = 0; this->preview.size = 0; if ((this->num_msgs < 0) || (this->num_msgs > 8)) this->num_msgs = 8; if (!new_mrl[0]) return INPUT_OPTIONAL_SUCCESS; if (!strncasecmp (new_mrl, "peercast://pls/", 15)) { char *w = this->mrl, *e = w + sizeof (this->mrl); w += strlcpy (w, "http://127.0.0.1:7144/stream/", e - w); strlcpy (w, new_mrl + 15, e - w); } else { strlcpy (this->mrl, new_mrl, sizeof (this->mrl)); } return INPUT_OPTIONAL_SUCCESS; } } return INPUT_OPTIONAL_UNSUPPORTED; } /* * http input plugin class */ static input_plugin_t *http_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { http_input_class_t *cls = (http_input_class_t *)cls_gen; http_input_plugin_t *this; if (!http_can_handle (stream, mrl)) return NULL; this = calloc(1, sizeof(http_input_plugin_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->curpos = 0; this->contentlength = 0; this->mime_type[0] = 0; this->user_agent = NULL; this->tls = NULL; this->mode = 0; this->shoutcast_interval = 0; this->shoutcast_left = 0; this->shoutcast_songtitle = NULL; this->preview.start = 0; this->preview.size = 0; this->url.proto = NULL; this->url.host = NULL; this->url.user = NULL; this->url.password = NULL; this->url.uri = NULL; this->proxyurl.proto = NULL; this->proxyurl.host = NULL; this->proxyurl.user = NULL; this->proxyurl.password = NULL; this->proxyurl.uri = NULL; this->head_dump_file = NULL; #endif if (!strncasecmp (mrl, "peercast://pls/", 15)) { char *w = this->mrl, *e = w + sizeof (this->mrl); w += strlcpy (w, "http://127.0.0.1:7144/stream/", e - w); strlcpy (w, mrl + 15, e - w); } else { strlcpy (this->mrl, mrl, sizeof (this->mrl)); } this->fh = -1; this->num_msgs = -1; this->stream = stream; this->xine = cls->xine; this->nbc = stream ? xine_nbc_init (stream) : NULL; sbuf_init (this); if (cls->head_dump_name && cls->head_dump_name[0]) { this->head_dump_file = fopen (cls->head_dump_name, "ab"); if (this->head_dump_file) fseek (this->head_dump_file, 0, SEEK_END); } this->input_plugin.open = http_plugin_open; this->input_plugin.get_capabilities = http_plugin_get_capabilities; this->input_plugin.read = http_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = http_plugin_seek; this->input_plugin.get_current_pos = http_plugin_get_current_pos; this->input_plugin.get_length = http_plugin_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = http_plugin_get_mrl; this->input_plugin.get_optional_data = http_plugin_get_optional_data; this->input_plugin.dispose = http_plugin_dispose; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } static void http_class_dispose (input_class_t *this_gen) { http_input_class_t *this = (http_input_class_t *) this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free (this); } void *input_http_init_class (xine_t *xine, const void *data) { http_input_class_t *this; config_values_t *config; char *proxy_env; char *proxyhost_env = NULL; int proxyport_env = DEFAULT_HTTP_PORT; (void)data; this = calloc(1, sizeof (http_input_class_t)); if (!this) return NULL; this->xine = xine; config = xine->config; this->input_class.get_instance = http_class_get_instance; this->input_class.identifier = "http"; this->input_class.description = N_("http/https input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = http_class_dispose; this->input_class.eject_media = NULL; /* * honour http_proxy envvar */ if((proxy_env = getenv("http_proxy")) && *proxy_env) { char *p; if(!strncmp(proxy_env, "http://", 7)) proxy_env += 7; proxyhost_env = strdup(proxy_env); if((p = strrchr(proxyhost_env, ':')) && (strlen(p) > 1)) { *p++ = '\0'; proxyport_env = (int) strtol(p, &p, 10); } } /* * proxy settings */ this->proxyhost = config->register_string (config, "media.network.http_proxy_host", proxyhost_env ? proxyhost_env : "", _("HTTP proxy host"), _("The hostname of the HTTP proxy."), 10, proxy_host_change_cb, (void *) this); this->proxyport = config->register_num (config, "media.network.http_proxy_port", proxyport_env, _("HTTP proxy port"), _("The port number of the HTTP proxy."), 10, proxy_port_change_cb, (void *) this); /* registered entries could be empty. Don't ignore envvar */ if(!strlen(this->proxyhost) && (proxyhost_env && strlen(proxyhost_env))) { config->update_string(config, "media.network.http_proxy_host", proxyhost_env); config->update_num(config, "media.network.http_proxy_port", proxyport_env); } _x_freep(&proxyhost_env); this->proxyuser = config->register_string (config, "media.network.http_proxy_user", "", _("HTTP proxy username"), _("The user name for the HTTP proxy."), 10, proxy_user_change_cb, (void *) this); this->proxypassword = config->register_string (config, "media.network.http_proxy_password", "", _("HTTP proxy password"), _("The password for the HTTP proxy."), 10, proxy_password_change_cb, (void *) this); this->noproxylist = config->register_string (config, "media.network.http_no_proxy", "", _("Domains for which to ignore the HTTP proxy"), _("A comma-separated list of domain names for which the proxy is to be ignored.\n" "If a domain name is prefixed with '=' then it is treated as a host name only " "(full match required)."), 10, no_proxy_list_change_cb, (void *) this); /* protocol version */ { static const char * const versions[] = {"http/1.0", "http/1.1", NULL}; this->prot_version = config->register_enum (config, "media.network.http_version", 0, (char **)versions, _("HTTP protocol version to use"), _("Try these when there are communication problems."), 10, prot_version_change_cb, this); } /* head dump file */ this->head_dump_name = config->register_string (config, "media.network.http_head_dump_file", "", _("Dump HTTP request and response heads to this file"), _("Set this for debugging."), 20, head_dump_name_change_cb, this); return this; } �����������������������xine-lib-1.2/src/input/http_helper.c����������������������������������������������������������������0000644�0001750�0001750�00000037727�14647725152�015314� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * URL helper functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #include <string.h> #include <stdint.h> #include <xine/xine_internal.h> #include "http_helper.h" static const int8_t tab_unhex[256] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-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,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,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,-1,-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 void unescape (char **d, const char *s, size_t len) { const uint8_t *r = (const uint8_t *)s, *e = r + len; uint8_t *w = (uint8_t *)*d; while (r < e) { if ((r[0] == '%') && (r + 3 <= e)) { int32_t v = ((int32_t)tab_unhex[r[1]] << 4) | (int32_t)tab_unhex[r[2]]; if (v >= 0) { *w++ = v; r += 3; continue; } } *w++ = *r++; } *d = (char *)w; } static const uint8_t tab_esclen[256] = { 1,1,1,1,1,1,1,1,1,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,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,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 tab_hex[16] = "0123456789abcdef"; static size_t esclen (const char *s, size_t len) { const uint8_t *r = (const uint8_t *)s, *e = r + len; size_t n = 0; while (r < e) n += tab_esclen[*r++]; return n; } static void escape (char **d, const char *s, size_t len) { const uint8_t *r = (const uint8_t *)s, *e = r + len; uint8_t *w = (uint8_t *)*d; while (r < e) { if (tab_esclen[*r] == 3) { *w++ = '%'; *w++ = tab_hex[(*r) >> 4]; *w++ = tab_hex[(*r) & 15]; r++; } else { *w++ = *r++; } } *d = (char *)w; } /* XXX: nullsoft paths start with a ';'. supporting this means: * no ';' in host names, and escaping ';' in user names and passwords :-/ * 0x01 : ; / [ @ ? # end * 0x02 ] end * 0x04 / ? # end * 0x08 ? # end * 0x10 # end * 0x20 end * 0x40 : ; / ? # end * 0x80 ; / ? # end */ static const uint8_t tab_type[256] = { 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, 0, 0, 0,0xdd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0xc5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x41,0xc1, 0, 0, 0,0xcd, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x01, 0,0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; typedef struct { uint32_t prot_start, prot_stop; uint32_t user_start, user_stop; uint32_t pass_start, pass_stop; uint32_t host_start, host_stop; uint32_t path_start, path_stop; uint32_t args_start, args_stop; uint32_t info_start, info_stop; uint32_t port; } mrlp_t; int _x_url_parse2 (const char *mrl, xine_url_t *url) { mrlp_t res; const uint8_t *r = (const uint8_t *)mrl, *b = r; if (!mrl || !url) return 0; do { const uint8_t *s = r; /* prot */ res.prot_start = res.prot_stop = 0; res.pass_start = 0; while (!(tab_type[*r] & 0x01)) r++; if ((r[0] == ':') && (r[1] == '/') && (r[2] == '/')) { res.prot_stop = r - b; r += 3; s = r; while (!(tab_type[*r] & 0x01)) r++; } /* user */ res.user_stop = r - b; if (r[0] == ':') { r++; res.pass_start = r - b; while (!(tab_type[*r] & 0x01)) r++; } if (r[0] == '@') { res.user_start = s - b; res.pass_stop = r - b; r++; if (res.pass_start == 0) res.user_stop = res.pass_start = res.pass_stop; } else { res.user_start = res.user_stop = 0; res.pass_start = res.pass_stop = 0; r = s; } } while (0); /* host */ if (r[0] == '[') { /* ip6 */ r++; res.host_start = r - b; while (!(tab_type[*r] & 0x02)) r++; res.host_stop = r - b; if (r[0] != ']') return 0; r++; } else { /* ip4 */ res.host_start = r - b; while (!(tab_type[*r] & 0x40)) r++; res.host_stop = r - b; } /* port */ /* res.port_start = r - b; */ if (r[0] == ':') { const uint8_t *s; uint32_t v = 0; uint8_t z; r++; s = r; /* res.port_start = r - b; */ while ((z = *r ^ '0') < 10) v = v * 10u + z, r++; res.port = v; /* port set but empty */ if (r == s) return 0; /* neither path, args, nor info follows */ if (!(tab_type[*r] & 0x80)) return 0; } else { res.port = 0; } /* res.port_stop = r - b; */ /* path */ res.path_start = r - b; while (!(tab_type[*r] & 0x08)) r++; res.path_stop = r - b; /* args */ res.args_start = r - b; if (r[0] == '?') { r++; res.args_start = r - b; while (!(tab_type[*r] & 0x10)) r++; } res.args_stop = r - b; /* info */ res.info_start = r - b; if (r[0] == '#') { r++; res.info_start = r - b; while (!(tab_type[*r] & 0x20)) r++; } res.info_stop = r - b; if (res.host_start == res.host_stop) { /* no host needs no prot as well */ if (res.prot_start != res.prot_stop) return 0; /* no host and no path?? */ if (res.path_start == res.path_stop) return 0; } url->port = res.port; { char *q; size_t pathlen = esclen ((const char *)b + res.path_start, res.path_stop - res.path_start); size_t argslen = esclen ((const char *)b + res.args_start, res.args_stop - res.args_start); size_t need = res.prot_stop - res.prot_start + 1 + res.host_stop - res.host_start + 1 + 2 * pathlen + argslen + 6 + res.args_stop - res.args_start + 1 + res.user_stop - res.user_start + 1 + res.pass_stop - res.pass_start + 1; url->buf = malloc (need); if (!url->buf) return 0; q = url->buf; url->proto = q; need = res.prot_stop - res.prot_start; if (need) { memcpy (q, b + res.prot_start, need); q += need; } *q++ = 0; url->host = q; need = res.host_stop - res.host_start; if (need) { memcpy (q, b + res.host_start, need); q += need; } *q++ = 0; url->path = q; need = res.path_stop - res.path_start; if (need) { /* yet another nullsoft HACK. */ if (b[res.path_start] == ';') *q++ = '/'; escape (&q, (const char *)b + res.path_start, need); } else { /* empty path default */ *q++ = '/'; } pathlen = q - url->path; *q++ = 0; url->uri = q; if (pathlen) { memcpy (q, url->path, pathlen); q += pathlen; } url->args = q; need = res.args_stop - res.args_start; if (need) { *q++ = '?'; escape (&q, (const char *)b + res.args_start, need); } *q++ = 0; /* input_ftp wants these NULL if unset. */ need = res.user_stop - res.user_start; if (need) { url->user = q; unescape (&q, (char *)b + res.user_start, need); *q++ = 0; } else { url->user = NULL; } need = res.pass_stop - res.pass_start; if (need) { url->password = q; unescape (&q, (char *)b + res.pass_start, need); *q++ = 0; } else { url->password = NULL; } } return 1; } void _x_url_init (xine_url_t *url) { if (!url) return; #ifdef HAVE_ZERO_SAFE_MEM memset (url, 0, sizeof (*url)); #else url->proto = NULL; url->host = NULL; url->port = 0; url->path = NULL; url->args = NULL; url->uri = NULL; url->user = NULL; url->password = NULL; url->buf = NULL; #endif } void _x_url_cleanup (xine_url_t *url) { if (!url) return; url->proto = NULL; url->host = NULL; url->port = 0; url->path = NULL; url->args = NULL; url->uri = NULL; url->user = NULL; if (url->buf && url->password) { size_t n = strlen (url->password); if (n) memset (url->buf + (url->password - (const char *)url->buf), 0, n); } url->password = NULL; free (url->buf); url->buf = NULL; } size_t _x_merge_mrl (char *dest, size_t dsize, const char *base_mrl, const char *new_mrl) { const uint8_t *b = (const uint8_t *)base_mrl; const uint8_t *n = (const uint8_t *)new_mrl; uint8_t *d; size_t base_len, new_len, ret; if (!(n && n[0])) { /* "old_stuff" + "" = "old_stuff" */ base_len = base_mrl ? strlen (base_mrl) : 0; new_len = 0; } else if (!(b && b[0])) { /* "" + "new_stuff" = "new_stuff" */ base_len = 0; new_len = strlen (new_mrl); } else { while (!(tab_type[*b] & 0x01)) b++; while (!(tab_type[*n] & 0x01)) n++; if ((n[0] == ':') && (n[1] == '/') && (n[2] == '/')) { base_len = 0; new_len = strlen (new_mrl); if (n == (const uint8_t *)new_mrl) { /* "https://host1/foo" + "://host2/bar" = "https://host2/bar" (no joke) */ if ((b[0] == ':') && (b[1] == '/') && (b[2] == '/')) base_len = b - (const uint8_t *)base_mrl; b = (const uint8_t *)base_mrl; } else { /* "old_stuff" + "new_stuff" = "new_stuff" */ n = (const uint8_t *)new_mrl; } } else { /* seek base to path */ if ((b[0] == ':') && (b[1] == '/') && (b[2] == '/')) b += 3; if (b[0] == '[') { while (!(tab_type[*b] & 0x02)) b++; } while (!(tab_type[*b] & 0x80)) b++; /* if new is relative path, seek further to last / */ n = (const uint8_t *)new_mrl; if ((n[0] != ';') && (n[0] != '/')) { const uint8_t *last_slash = b; while (b[0] == '/') { last_slash = b++; while (!(tab_type[*b] & 0x04)) b++; } b = last_slash; } else if (n[0] == '/') n++; if (b[0] == '/') b++; base_len = b - (const uint8_t *)base_mrl; new_len = strlen ((const char *)n); } } /* size paranoia */ ret = base_len + new_len; if (ret + 1 > dsize) { if (base_len + 1 > dsize) { base_len = dsize - 1; new_len = 0; } else { new_len = dsize - base_len - 1; } } /* no target, just tell size */ if (!dest || !dsize) return ret; d = (uint8_t *)dest; /* copy base part */ if (base_len && ((const char *)dest != base_mrl)) memcpy (d, base_mrl, base_len); d += base_len; /* copy new part */ if (new_len) memcpy (d, n, new_len); d += new_len; *d = 0; return ret; } const char *_x_url_user_agent (const char *url) { if (!strncasecmp (url, "qthttp://", 9)) return "QuickTime"; /* needed for Apple trailers */ return NULL; } #ifdef TEST_URL /* * url parser test program */ static int check_url (char *mrl, int ok) { xine_url_t url; int res; printf("--------------------------------\n"); printf ("url=%s\n", mrl); res = _x_url_parse2 (mrl, &url); if (res) { printf ("proto=%s, host=%s, port=%d, user=%s, password=%s, uri=%s\n", url.proto, url.host, url.port, url.user, url.password, url.uri); free (url.proto); free (url.host); free (url.user); free (url.password); free (url.uri); } else { printf("bad url\n"); } if (res == ok) { printf ("%s test OK\n", mrl); return 1; } else { printf ("%s test KO\n", mrl); return 0; } } static int check_paste(const char *base, const char *url, const char *ok) { char *res; int ret; printf("--------------------------------\n"); printf("base url=%s\n", base); printf(" new url=%s\n", url); res = _x_canonicalise_url (base, url); printf(" result=%s\n", res); ret = !strcmp (res, ok); free (res); puts (ret ? "test OK" : "test KO"); return ret; } int main(int argc, char** argv) { char *proto, host, port, user, password, uri; int res = 0; res += check_url("http://www.toto.com/test1.asx", 1); res += check_url("http://www.toto.com:8080/test2.asx", 1); res += check_url("http://titi:pass@www.toto.com:8080/test3.asx", 1); res += check_url("http://www.toto.com", 1); res += check_url("http://www.toto.com/", 1); res += check_url("http://www.toto.com:80", 1); res += check_url("http://www.toto.com:80/", 1); res += check_url("http://www.toto.com:", 0); res += check_url("http://www.toto.com:/", 0); res += check_url("http://www.toto.com:abc", 0); res += check_url("http://www.toto.com:abc/", 0); res += check_url("http://titi@www.toto.com:8080/test4.asx", 1); res += check_url("http://@www.toto.com:8080/test5.asx", 0); res += check_url("http://:@www.toto.com:8080/test6.asx", 0); res += check_url("http:///test6.asx", 0); res += check_url("http://:/test7.asx", 0); res += check_url("http://", 0); res += check_url("http://:", 0); res += check_url("http://@", 0); res += check_url("http://:@", 0); res += check_url("http://:/@", 0); res += check_url("http://www.toto.com:80a/", 0); res += check_url("http://[www.toto.com]", 1); res += check_url("http://[www.toto.com]/", 1); res += check_url("http://[www.toto.com]:80", 1); res += check_url("http://[www.toto.com]:80/", 1); res += check_url("http://[12:12]:80/", 1); res += check_url("http://user:pass@[12:12]:80/", 1); res += check_paste("http://www.toto.com/foo/test.asx", "http://www2.toto.com/www/foo/test1.asx", "http://www2.toto.com/www/foo/test1.asx"); res += check_paste("http://www.toto.com/foo/test.asx", "/bar/test2.asx", "http://www.toto.com/bar/test2.asx"); res += check_paste("http://www.toto.com/foo/test.asx", "test3.asx", "http://www.toto.com/foo/test3.asx"); printf("================================\n"); if (res != 31) { printf("result: KO\n"); } else { printf("result: OK\n"); } } #endif �����������������������������������������xine-lib-1.2/src/input/libreal/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014224� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/rmff.h���������������������������������������������������������������0000644�0001750�0001750�00000014153�14647725152�015333� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * some functions for real media file headers * adopted from joschkas real tools */ #include <sys/types.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #ifndef HAVE_RMFF_H #define HAVE_RMFF_H #include <xine/attributes.h> #define RMFF_HEADER_SIZE 0x12 #define RMFF_FILEHEADER_SIZE 18 #define RMFF_PROPHEADER_SIZE 50 #define RMFF_MDPRHEADER_SIZE 46 #define RMFF_CONTHEADER_SIZE 18 #define RMFF_DATAHEADER_SIZE 18 #define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \ (((long)(unsigned char)(ch3) ) | \ ( (long)(unsigned char)(ch2) << 8 ) | \ ( (long)(unsigned char)(ch1) << 16 ) | \ ( (long)(unsigned char)(ch0) << 24 ) ) #define RMF_TAG FOURCC_TAG('.', 'R', 'M', 'F') #define PROP_TAG FOURCC_TAG('P', 'R', 'O', 'P') #define MDPR_TAG FOURCC_TAG('M', 'D', 'P', 'R') #define CONT_TAG FOURCC_TAG('C', 'O', 'N', 'T') #define DATA_TAG FOURCC_TAG('D', 'A', 'T', 'A') #define INDX_TAG FOURCC_TAG('I', 'N', 'D', 'X') #define PNA_TAG FOURCC_TAG('P', 'N', 'A', 0 ) #define MLTI_TAG FOURCC_TAG('M', 'L', 'T', 'I') /* prop flags */ #define PN_SAVE_ENABLED 0x01 #define PN_PERFECT_PLAY_ENABLED 0x02 #define PN_LIVE_BROADCAST 0x04 /* * rm header data structs */ typedef struct { uint32_t object_id; uint32_t size; uint16_t object_version; uint32_t file_version; uint32_t num_headers; } rmff_fileheader_t; typedef struct { uint32_t object_id; uint32_t size; uint16_t object_version; uint32_t max_bit_rate; uint32_t avg_bit_rate; uint32_t max_packet_size; uint32_t avg_packet_size; uint32_t num_packets; uint32_t duration; uint32_t preroll; uint32_t index_offset; uint32_t data_offset; uint16_t num_streams; uint16_t flags; } rmff_prop_t; typedef struct { uint32_t object_id; uint32_t size; uint16_t object_version; uint16_t stream_number; uint32_t max_bit_rate; uint32_t avg_bit_rate; uint32_t max_packet_size; uint32_t avg_packet_size; uint32_t start_time; uint32_t preroll; uint32_t duration; uint8_t stream_name_size; char *stream_name; uint8_t mime_type_size; char *mime_type; uint32_t type_specific_len; char *type_specific_data; int mlti_data_size; char *mlti_data; } rmff_mdpr_t; typedef struct { uint32_t object_id; uint32_t size; uint16_t object_version; uint16_t title_len; char *title; uint16_t author_len; char *author; uint16_t copyright_len; char *copyright; uint16_t comment_len; char *comment; } rmff_cont_t; typedef struct { uint32_t object_id; uint32_t size; uint16_t object_version; uint32_t num_packets; uint32_t next_data_header; /* rarely used */ } rmff_data_t; typedef struct { rmff_fileheader_t *fileheader; rmff_prop_t *prop; rmff_mdpr_t **streams; rmff_cont_t *cont; rmff_data_t *data; } rmff_header_t; typedef struct { uint16_t object_version; uint16_t length; uint16_t stream_number; uint32_t timestamp; uint8_t reserved; uint8_t flags; } rmff_pheader_t; /* * constructors for header structs */ rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers); rmff_prop_t *rmff_new_prop ( uint32_t max_bit_rate, uint32_t avg_bit_rate, uint32_t max_packet_size, uint32_t avg_packet_size, uint32_t num_packets, uint32_t duration, uint32_t preroll, uint32_t index_offset, uint32_t data_offset, uint16_t num_streams, uint16_t flags ); rmff_mdpr_t *rmff_new_mdpr( uint16_t stream_number, uint32_t max_bit_rate, uint32_t avg_bit_rate, uint32_t max_packet_size, uint32_t avg_packet_size, uint32_t start_time, uint32_t preroll, uint32_t duration, const char *stream_name, const char *mime_type, uint32_t type_specific_len, const char *type_specific_data ); rmff_cont_t *rmff_new_cont( const char *title, const char *author, const char *copyright, const char *comment); rmff_data_t *rmff_new_dataheader( uint32_t num_packets, uint32_t next_data_header); #if 0 /* * reads header infos from data and returns a newly allocated header struct */ rmff_header_t *rmff_scan_header(const char *data) XINE_MALLOC; /* * scans a data packet header. Notice, that this function does not allocate * the header struct itself. */ void rmff_scan_pheader(rmff_pheader_t *h, char *data); /* * reads header infos from stream and returns a newly allocated header struct */ rmff_header_t *rmff_scan_header_stream(int fd) XINE_MALLOC; /* * prints header information in human readible form to stdout */ void rmff_print_header(rmff_header_t *h); #endif /* * does some checks and fixes header if possible */ void rmff_fix_header(rmff_header_t *h); #if 0 /* * returns the size of the header (incl. first data-header) */ int rmff_get_header_size(rmff_header_t *h); #endif /* * dumps the header <h> to <buffer>. <max> is the size of <buffer> */ int rmff_dump_header(rmff_header_t *h, void *buffer, int max); /* * dumps a packet header */ void rmff_dump_pheader(rmff_pheader_t *h, uint8_t *data); #if 0 /* * frees a header struct */ void rmff_free_header(rmff_header_t *h); #endif #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/rmff.c���������������������������������������������������������������0000644�0001750�0001750�00000064157�14647725152�015337� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * functions for real media file format * adopted from joschkas real tools */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "rmff" #define LOG_VERBOSE /* #define LOG */ #include <xine/xineutils.h> #include "bswap.h" #include "rmff.h" /* * writes header data to a buffer */ static int rmff_dump_fileheader(rmff_fileheader_t *fileheader, uint8_t *buffer, int bufsize) { if (!fileheader) return 0; if (bufsize < RMFF_FILEHEADER_SIZE) return -1; fileheader->object_id=_X_BE_32(&fileheader->object_id); fileheader->size=_X_BE_32(&fileheader->size); fileheader->object_version=_X_BE_16(&fileheader->object_version); fileheader->file_version=_X_BE_32(&fileheader->file_version); fileheader->num_headers=_X_BE_32(&fileheader->num_headers); memcpy(buffer, fileheader, 8); memcpy(&buffer[8], &fileheader->object_version, 2); memcpy(&buffer[10], &fileheader->file_version, 8); fileheader->size=_X_BE_32(&fileheader->size); fileheader->object_version=_X_BE_16(&fileheader->object_version); fileheader->file_version=_X_BE_32(&fileheader->file_version); fileheader->num_headers=_X_BE_32(&fileheader->num_headers); fileheader->object_id=_X_BE_32(&fileheader->object_id); return RMFF_FILEHEADER_SIZE; } static int rmff_dump_prop(rmff_prop_t *prop, uint8_t *buffer, int bufsize) { if (!prop) return 0; if (bufsize < RMFF_PROPHEADER_SIZE) return -1; prop->object_id=_X_BE_32(&prop->object_id); prop->size=_X_BE_32(&prop->size); prop->object_version=_X_BE_16(&prop->object_version); prop->max_bit_rate=_X_BE_32(&prop->max_bit_rate); prop->avg_bit_rate=_X_BE_32(&prop->avg_bit_rate); prop->max_packet_size=_X_BE_32(&prop->max_packet_size); prop->avg_packet_size=_X_BE_32(&prop->avg_packet_size); prop->num_packets=_X_BE_32(&prop->num_packets); prop->duration=_X_BE_32(&prop->duration); prop->preroll=_X_BE_32(&prop->preroll); prop->index_offset=_X_BE_32(&prop->index_offset); prop->data_offset=_X_BE_32(&prop->data_offset); prop->num_streams=_X_BE_16(&prop->num_streams); prop->flags=_X_BE_16(&prop->flags); memcpy(buffer, prop, 8); memcpy(&buffer[8], &prop->object_version, 2); memcpy(&buffer[10], &prop->max_bit_rate, 36); memcpy(&buffer[46], &prop->num_streams, 2); memcpy(&buffer[48], &prop->flags, 2); prop->size=_X_BE_32(&prop->size); prop->object_version=_X_BE_16(&prop->object_version); prop->max_bit_rate=_X_BE_32(&prop->max_bit_rate); prop->avg_bit_rate=_X_BE_32(&prop->avg_bit_rate); prop->max_packet_size=_X_BE_32(&prop->max_packet_size); prop->avg_packet_size=_X_BE_32(&prop->avg_packet_size); prop->num_packets=_X_BE_32(&prop->num_packets); prop->duration=_X_BE_32(&prop->duration); prop->preroll=_X_BE_32(&prop->preroll); prop->index_offset=_X_BE_32(&prop->index_offset); prop->data_offset=_X_BE_32(&prop->data_offset); prop->num_streams=_X_BE_16(&prop->num_streams); prop->flags=_X_BE_16(&prop->flags); prop->object_id=_X_BE_32(&prop->object_id); return RMFF_PROPHEADER_SIZE; } static int rmff_dump_mdpr(rmff_mdpr_t *mdpr, uint8_t *buffer, int bufsize) { int s1, s2, s3; if (!mdpr) return 0; if (mdpr->type_specific_len > 0x3fffffff) return -1; if (bufsize < RMFF_MDPRHEADER_SIZE + (int)mdpr->type_specific_len + mdpr->stream_name_size + mdpr->mime_type_size) return -1; mdpr->object_id=_X_BE_32(&mdpr->object_id); mdpr->size=_X_BE_32(&mdpr->size); mdpr->object_version=_X_BE_16(&mdpr->object_version); mdpr->stream_number=_X_BE_16(&mdpr->stream_number); mdpr->max_bit_rate=_X_BE_32(&mdpr->max_bit_rate); mdpr->avg_bit_rate=_X_BE_32(&mdpr->avg_bit_rate); mdpr->max_packet_size=_X_BE_32(&mdpr->max_packet_size); mdpr->avg_packet_size=_X_BE_32(&mdpr->avg_packet_size); mdpr->start_time=_X_BE_32(&mdpr->start_time); mdpr->preroll=_X_BE_32(&mdpr->preroll); mdpr->duration=_X_BE_32(&mdpr->duration); memcpy(buffer, mdpr, 8); memcpy(&buffer[8], &mdpr->object_version, 2); memcpy(&buffer[10], &mdpr->stream_number, 2); memcpy(&buffer[12], &mdpr->max_bit_rate, 28); memcpy(&buffer[40], &mdpr->stream_name_size, 1); s1=mdpr->stream_name_size; memcpy(&buffer[41], mdpr->stream_name, s1); memcpy(&buffer[41+s1], &mdpr->mime_type_size, 1); s2=mdpr->mime_type_size; memcpy(&buffer[42+s1], mdpr->mime_type, s2); mdpr->type_specific_len=_X_BE_32(&mdpr->type_specific_len); memcpy(&buffer[42+s1+s2], &mdpr->type_specific_len, 4); mdpr->type_specific_len=_X_BE_32(&mdpr->type_specific_len); s3=mdpr->type_specific_len; memcpy(&buffer[46+s1+s2], mdpr->type_specific_data, s3); mdpr->size=_X_BE_32(&mdpr->size); mdpr->stream_number=_X_BE_16(&mdpr->stream_number); mdpr->max_bit_rate=_X_BE_32(&mdpr->max_bit_rate); mdpr->avg_bit_rate=_X_BE_32(&mdpr->avg_bit_rate); mdpr->max_packet_size=_X_BE_32(&mdpr->max_packet_size); mdpr->avg_packet_size=_X_BE_32(&mdpr->avg_packet_size); mdpr->start_time=_X_BE_32(&mdpr->start_time); mdpr->preroll=_X_BE_32(&mdpr->preroll); mdpr->duration=_X_BE_32(&mdpr->duration); mdpr->object_id=_X_BE_32(&mdpr->object_id); return RMFF_MDPRHEADER_SIZE + s1 + s2 + s3; } static int rmff_dump_cont(rmff_cont_t *cont, uint8_t *buffer, int bufsize) { int p; if (!cont) return 0; if (bufsize < RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + cont->copyright_len + cont->comment_len) return -1; cont->object_id=_X_BE_32(&cont->object_id); cont->size=_X_BE_32(&cont->size); cont->object_version=_X_BE_16(&cont->object_version); memcpy(buffer, cont, 8); memcpy(&buffer[8], &cont->object_version, 2); cont->title_len=_X_BE_16(&cont->title_len); memcpy(&buffer[10], &cont->title_len, 2); cont->title_len=_X_BE_16(&cont->title_len); memcpy(&buffer[12], cont->title, cont->title_len); p=12+cont->title_len; cont->author_len=_X_BE_16(&cont->author_len); memcpy(&buffer[p], &cont->author_len, 2); cont->author_len=_X_BE_16(&cont->author_len); memcpy(&buffer[p+2], cont->author, cont->author_len); p+=2+cont->author_len; cont->copyright_len=_X_BE_16(&cont->copyright_len); memcpy(&buffer[p], &cont->copyright_len, 2); cont->copyright_len=_X_BE_16(&cont->copyright_len); memcpy(&buffer[p+2], cont->copyright, cont->copyright_len); p+=2+cont->copyright_len; cont->comment_len=_X_BE_16(&cont->comment_len); memcpy(&buffer[p], &cont->comment_len, 2); cont->comment_len=_X_BE_16(&cont->comment_len); memcpy(&buffer[p+2], cont->comment, cont->comment_len); cont->size=_X_BE_32(&cont->size); cont->object_version=_X_BE_16(&cont->object_version); cont->object_id=_X_BE_32(&cont->object_id); return RMFF_CONTHEADER_SIZE + cont->title_len + cont->author_len + cont->copyright_len + cont->comment_len; } static int rmff_dump_dataheader(rmff_data_t *data, uint8_t *buffer, int bufsize) { if (!data) return 0; if (bufsize < RMFF_DATAHEADER_SIZE) return -1; data->object_id=_X_BE_32(&data->object_id); data->size=_X_BE_32(&data->size); data->object_version=_X_BE_16(&data->object_version); data->num_packets=_X_BE_32(&data->num_packets); data->next_data_header=_X_BE_32(&data->next_data_header); memcpy(buffer, data, 8); memcpy(&buffer[8], &data->object_version, 2); memcpy(&buffer[10], &data->num_packets, 8); data->num_packets=_X_BE_32(&data->num_packets); data->next_data_header=_X_BE_32(&data->next_data_header); data->size=_X_BE_32(&data->size); data->object_version=_X_BE_16(&data->object_version); data->object_id=_X_BE_32(&data->object_id); return RMFF_DATAHEADER_SIZE; } int rmff_dump_header(rmff_header_t *h, void *buf_gen, int max) { uint8_t *buffer = buf_gen; int written=0, size; rmff_mdpr_t **stream=h->streams; if ((size=rmff_dump_fileheader(h->fileheader, &buffer[written], max)) < 0) return -1; written+=size; max -= size; if ((size=rmff_dump_prop(h->prop, &buffer[written], max)) < 0) return -1; written+=size; max -= size; if ((size=rmff_dump_cont(h->cont, &buffer[written], max)) < 0) return -1; written+=size; max -= size; if (stream) { while(*stream) { if ((size=rmff_dump_mdpr(*stream, &buffer[written], max)) < 0) return -1; written+=size; max -= size; stream++; } } if ((size=rmff_dump_dataheader(h->data, &buffer[written], max)) < 0) return -1; written+=size; return written; } void rmff_dump_pheader(rmff_pheader_t *h, uint8_t *data) { data[0]=(h->object_version>>8) & 0xff; data[1]=h->object_version & 0xff; data[2]=(h->length>>8) & 0xff; data[3]=h->length & 0xff; data[4]=(h->stream_number>>8) & 0xff; data[5]=h->stream_number & 0xff; data[6]=(h->timestamp>>24) & 0xff; data[7]=(h->timestamp>>16) & 0xff; data[8]=(h->timestamp>>8) & 0xff; data[9]=h->timestamp & 0xff; data[10]=h->reserved; data[11]=h->flags; } #if 0 static rmff_fileheader_t *rmff_scan_fileheader(const char *data) { rmff_fileheader_t *fileheader = malloc(sizeof(rmff_fileheader_t)); fileheader->object_id=_X_BE_32(data); fileheader->size=_X_BE_32(&data[4]); fileheader->object_version=_X_BE_16(&data[8]); if (fileheader->object_version != 0) { lprintf("warning: unknown object version in .RMF: 0x%04x\n", fileheader->object_version); } fileheader->file_version=_X_BE_32(&data[10]); fileheader->num_headers=_X_BE_32(&data[14]); return fileheader; } #endif #if 0 static rmff_prop_t *rmff_scan_prop(const char *data) { rmff_prop_t *prop = malloc(sizeof(rmff_prop_t)); prop->object_id=_X_BE_32(data); prop->size=_X_BE_32(&data[4]); prop->object_version=_X_BE_16(&data[8]); if (prop->object_version != 0) { lprintf("warning: unknown object version in PROP: 0x%04x\n", prop->object_version); } prop->max_bit_rate=_X_BE_32(&data[10]); prop->avg_bit_rate=_X_BE_32(&data[14]); prop->max_packet_size=_X_BE_32(&data[18]); prop->avg_packet_size=_X_BE_32(&data[22]); prop->num_packets=_X_BE_32(&data[26]); prop->duration=_X_BE_32(&data[30]); prop->preroll=_X_BE_32(&data[34]); prop->index_offset=_X_BE_32(&data[38]); prop->data_offset=_X_BE_32(&data[42]); prop->num_streams=_X_BE_16(&data[46]); prop->flags=_X_BE_16(&data[48]); return prop; } #endif #if 0 static rmff_mdpr_t *rmff_scan_mdpr(const char *data) { rmff_mdpr_t *mdpr = calloc(sizeof(rmff_mdpr_t), 1); if (!mdpr) return NULL; mdpr->object_id=_X_BE_32(data); mdpr->size=_X_BE_32(&data[4]); if (mdpr->size < 46) goto fail; mdpr->object_version=_X_BE_16(&data[8]); if (mdpr->object_version != 0) { lprintf("warning: unknown object version in MDPR: 0x%04x\n", mdpr->object_version); } mdpr->stream_number=_X_BE_16(&data[10]); mdpr->max_bit_rate=_X_BE_32(&data[12]); mdpr->avg_bit_rate=_X_BE_32(&data[16]); mdpr->max_packet_size=_X_BE_32(&data[20]); mdpr->avg_packet_size=_X_BE_32(&data[24]); mdpr->start_time=_X_BE_32(&data[28]); mdpr->preroll=_X_BE_32(&data[32]); mdpr->duration=_X_BE_32(&data[36]); mdpr->stream_name_size=data[40]; if (mdpr->size < 46 + (uint32_t)mdpr->stream_name_size) goto fail; mdpr->stream_name = xine_memdup0(&data[41], mdpr->stream_name_size); if (!mdpr->stream_name) goto fail; mdpr->mime_type_size=data[41+mdpr->stream_name_size]; if (mdpr->size < 46 + (uint32_t)mdpr->stream_name_size + (uint32_t)mdpr->mime_type_size) goto fail; mdpr->mime_type = xine_memdup0(&data[42+mdpr->stream_name_size], mdpr->mime_type_size); if (!mdpr->mime_type) goto fail; mdpr->type_specific_len=_X_BE_32(&data[42+mdpr->stream_name_size+mdpr->mime_type_size]); if (mdpr->size < 46 + mdpr->stream_name_size + mdpr->mime_type_size + mdpr->type_specific_len) goto fail; mdpr->type_specific_data = xine_memdup(&data[46+mdpr->stream_name_size+mdpr->mime_type_size], mdpr->type_specific_len); if (!mdpr->type_specific_data) goto fail; return mdpr; fail: free (mdpr->stream_name); free (mdpr->mime_type); free (mdpr->type_specific_data); free (mdpr); return NULL; } #endif #if 0 static rmff_cont_t *rmff_scan_cont(const char *data) { rmff_cont_t *cont = malloc(sizeof(rmff_cont_t)); int pos; cont->object_id=_X_BE_32(data); cont->size=_X_BE_32(&data[4]); cont->object_version=_X_BE_16(&data[8]); if (cont->object_version != 0) { lprintf("warning: unknown object version in CONT: 0x%04x\n", cont->object_version); } cont->title_len=_X_BE_16(&data[10]); cont->title = xine_memdup0(&data[12], cont->title_len); pos=cont->title_len+12; cont->author_len=_X_BE_16(&data[pos]); cont->author = xine_memdup0(&data[pos+2], cont->author_len); pos=pos+2+cont->author_len; cont->copyright_len=_X_BE_16(&data[pos]); cont->copyright = xine_memdup0(&data[pos+2], cont->copyright_len); cont->copyright[cont->copyright_len]=0; pos=pos+2+cont->copyright_len; cont->comment_len=_X_BE_16(&data[pos]); cont->comment = xine_memdup0(&data[pos+2], cont->comment_len); return cont; } #endif #if 0 static rmff_data_t *rmff_scan_dataheader(const char *data) { rmff_data_t *dh = malloc(sizeof(rmff_data_t)); dh->object_id=_X_BE_32(data); dh->size=_X_BE_32(&data[4]); dh->object_version=_X_BE_16(&data[8]); if (dh->object_version != 0) { lprintf("warning: unknown object version in DATA: 0x%04x\n", dh->object_version); } dh->num_packets=_X_BE_32(&data[10]); dh->next_data_header=_X_BE_32(&data[14]); return dh; } #endif #if 0 rmff_header_t *rmff_scan_header(const char *data) { rmff_header_t *header = malloc(sizeof(rmff_header_t)); rmff_mdpr_t *mdpr=NULL; int chunk_size; uint32_t chunk_type; const char *ptr=data; unsigned int i; if (!header) return NULL; header->fileheader=NULL; header->prop=NULL; header->cont=NULL; header->data=NULL; chunk_type = _X_BE_32(ptr); if (chunk_type != RMF_TAG) { lprintf("rmff: not an real media file header (.RMF tag not found).\n"); free(header); return NULL; } header->fileheader=rmff_scan_fileheader(ptr); ptr += header->fileheader->size; header->streams = calloc(header->fileheader->num_headers, sizeof(rmff_mdpr_t*)); for (i=1; i<header->fileheader->num_headers; i++) { chunk_type = _X_BE_32(ptr); if (ptr[0] == 0) { lprintf("rmff: warning: only %d of %d header found.\n", i, header->fileheader->num_headers); break; } chunk_size=1; switch (chunk_type) { case PROP_TAG: header->prop=rmff_scan_prop(ptr); chunk_size=header->prop->size; break; case MDPR_TAG: mdpr=rmff_scan_mdpr(ptr); if (mdpr) { chunk_size=mdpr->size; header->streams[mdpr->stream_number]=mdpr; } break; case CONT_TAG: header->cont=rmff_scan_cont(ptr); chunk_size=header->cont->size; break; case DATA_TAG: header->data=rmff_scan_dataheader(ptr); chunk_size=34; /* hard coded header size */ break; default: lprintf("unknown chunk\n"); #ifdef LOG xine_hexdump(ptr,10); #endif chunk_size=1; break; } ptr+=chunk_size; } return header; } #endif #if 0 rmff_header_t *rmff_scan_header_stream(int fd) { rmff_header_t *header; char *buf=xine_buffer_init(1024); int index=0; uint32_t chunk_type; uint32_t chunk_size; do { xine_buffer_ensure_size(buf, index+8); read(fd, buf+index, 8); chunk_type=_X_BE_32(buf+index); index+=4; chunk_size=_X_BE_32(buf+index); index+=4; switch (chunk_type) { case DATA_TAG: chunk_size=18; case MDPR_TAG: case CONT_TAG: case RMF_TAG: case PROP_TAG: xine_buffer_ensure_size(buf, index+chunk_size-8); read(fd, buf+index, (chunk_size-8)); index+=(chunk_size-8); break; default: lprintf("rmff_scan_header_stream: unknown chunk"); #ifdef LOG xine_hexdump(buf+index-8, 8); #endif chunk_type=DATA_TAG; } } while (chunk_type != DATA_TAG); header = rmff_scan_header(buf); xine_buffer_free(buf); return header; } void rmff_scan_pheader(rmff_pheader_t *h, char *data) { h->object_version=_X_BE_16(data); h->length=_X_BE_16(data+2); h->stream_number=_X_BE_16(data+4); h->timestamp=_X_BE_32(data+6); h->reserved=(uint8_t)data[10]; h->flags=(uint8_t)data[11]; } #endif rmff_fileheader_t *rmff_new_fileheader(uint32_t num_headers) { rmff_fileheader_t *fileheader = malloc(sizeof(rmff_fileheader_t)); fileheader->object_id=RMF_TAG; fileheader->size=18; fileheader->object_version=0; fileheader->file_version=0; fileheader->num_headers=num_headers; return fileheader; } rmff_prop_t *rmff_new_prop ( uint32_t max_bit_rate, uint32_t avg_bit_rate, uint32_t max_packet_size, uint32_t avg_packet_size, uint32_t num_packets, uint32_t duration, uint32_t preroll, uint32_t index_offset, uint32_t data_offset, uint16_t num_streams, uint16_t flags ) { rmff_prop_t *prop = malloc(sizeof(rmff_prop_t)); prop->object_id=PROP_TAG; prop->size=50; prop->object_version=0; prop->max_bit_rate=max_bit_rate; prop->avg_bit_rate=avg_bit_rate; prop->max_packet_size=max_packet_size; prop->avg_packet_size=avg_packet_size; prop->num_packets=num_packets; prop->duration=duration; prop->preroll=preroll; prop->index_offset=index_offset; prop->data_offset=data_offset; prop->num_streams=num_streams; prop->flags=flags; return prop; } rmff_mdpr_t *rmff_new_mdpr( uint16_t stream_number, uint32_t max_bit_rate, uint32_t avg_bit_rate, uint32_t max_packet_size, uint32_t avg_packet_size, uint32_t start_time, uint32_t preroll, uint32_t duration, const char *stream_name, const char *mime_type, uint32_t type_specific_len, const char *type_specific_data ) { rmff_mdpr_t *mdpr = malloc(sizeof(rmff_mdpr_t)); mdpr->object_id=MDPR_TAG; mdpr->object_version=0; mdpr->stream_number=stream_number; mdpr->max_bit_rate=max_bit_rate; mdpr->avg_bit_rate=avg_bit_rate; mdpr->max_packet_size=max_packet_size; mdpr->avg_packet_size=avg_packet_size; mdpr->start_time=start_time; mdpr->preroll=preroll; mdpr->duration=duration; mdpr->stream_name_size=0; if (stream_name) { mdpr->stream_name=strdup(stream_name); mdpr->stream_name_size=strlen(stream_name); } mdpr->mime_type_size=0; if (mime_type) { mdpr->mime_type=strdup(mime_type); mdpr->mime_type_size=strlen(mime_type); } mdpr->type_specific_len=type_specific_len; mdpr->type_specific_data = xine_memdup(type_specific_data,type_specific_len); mdpr->mlti_data=NULL; mdpr->size=mdpr->stream_name_size+mdpr->mime_type_size+mdpr->type_specific_len+46; return mdpr; } rmff_cont_t *rmff_new_cont(const char *title, const char *author, const char *copyright, const char *comment) { rmff_cont_t *cont = malloc(sizeof(rmff_cont_t)); cont->object_id=CONT_TAG; cont->object_version=0; cont->title=NULL; cont->author=NULL; cont->copyright=NULL; cont->comment=NULL; cont->title_len=0; cont->author_len=0; cont->copyright_len=0; cont->comment_len=0; if (title) { cont->title_len=strlen(title); cont->title=strdup(title); } if (author) { cont->author_len=strlen(author); cont->author=strdup(author); } if (copyright) { cont->copyright_len=strlen(copyright); cont->copyright=strdup(copyright); } if (comment) { cont->comment_len=strlen(comment); cont->comment=strdup(comment); } cont->size=cont->title_len+cont->author_len+cont->copyright_len+cont->comment_len+18; return cont; } rmff_data_t *rmff_new_dataheader(uint32_t num_packets, uint32_t next_data_header) { rmff_data_t *data = malloc(sizeof(rmff_data_t)); data->object_id=DATA_TAG; data->size=18; data->object_version=0; data->num_packets=num_packets; data->next_data_header=next_data_header; return data; } #if 0 void rmff_print_header(rmff_header_t *h) { rmff_mdpr_t **stream; if(!h) { printf("rmff_print_header: NULL given\n"); return; } if(h->fileheader) { printf("\nFILE:\n"); printf("file version : %d\n", h->fileheader->file_version); printf("number of headers : %d\n", h->fileheader->num_headers); } if(h->cont) { printf("\nCONTENT:\n"); printf("title : %s\n", h->cont->title); printf("author : %s\n", h->cont->author); printf("copyright : %s\n", h->cont->copyright); printf("comment : %s\n", h->cont->comment); } if(h->prop) { printf("\nSTREAM PROPERTIES:\n"); printf("bit rate (max/avg) : %i/%i\n", h->prop->max_bit_rate, h->prop->avg_bit_rate); printf("packet size (max/avg) : %i/%i bytes\n", h->prop->max_packet_size, h->prop->avg_packet_size); printf("packets : %i\n", h->prop->num_packets); printf("duration : %i ms\n", h->prop->duration); printf("pre-buffer : %i ms\n", h->prop->preroll); printf("index offset : %i bytes\n", h->prop->index_offset); printf("data offset : %i bytes\n", h->prop->data_offset); printf("media streams : %i\n", h->prop->num_streams); printf("flags : "); if (h->prop->flags & PN_SAVE_ENABLED) printf("save_enabled "); if (h->prop->flags & PN_PERFECT_PLAY_ENABLED) printf("perfect_play_enabled "); if (h->prop->flags & PN_LIVE_BROADCAST) printf("live_broadcast "); printf("\n"); } stream=h->streams; if(stream) { while (*stream) { printf("\nSTREAM %i:\n", (*stream)->stream_number); printf("stream name [mime type] : %s [%s]\n", (*stream)->stream_name, (*stream)->mime_type); printf("bit rate (max/avg) : %i/%i\n", (*stream)->max_bit_rate, (*stream)->avg_bit_rate); printf("packet size (max/avg) : %i/%i bytes\n", (*stream)->max_packet_size, (*stream)->avg_packet_size); printf("start time : %i\n", (*stream)->start_time); printf("pre-buffer : %i ms\n", (*stream)->preroll); printf("duration : %i ms\n", (*stream)->duration); printf("type specific data:\n"); #ifdef LOG xine_hexdump((*stream)->type_specific_data, (*stream)->type_specific_len); #endif stream++; } } if(h->data) { printf("\nDATA:\n"); printf("size : %i\n", h->data->size); printf("packets : %i\n", h->data->num_packets); printf("next DATA : 0x%08x\n", h->data->next_data_header); } } #endif void rmff_fix_header(rmff_header_t *h) { unsigned int num_headers=0; unsigned int header_size=0; rmff_mdpr_t **streams; int num_streams=0; if (!h) { lprintf("rmff_fix_header: fatal: no header given.\n"); return; } if (!h->streams) { lprintf("rmff_fix_header: warning: no MDPR chunks\n"); } else { streams=h->streams; while (*streams) { num_streams++; num_headers++; header_size+=(*streams)->size; streams++; } } if (h->prop) { if (h->prop->size != 50) { lprintf("rmff_fix_header: correcting prop.size from %i to %i\n", h->prop->size, 50); h->prop->size=50; } if (h->prop->num_streams != num_streams) { lprintf("rmff_fix_header: correcting prop.num_streams from %i to %i\n", h->prop->num_streams, num_streams); h->prop->num_streams=num_streams; } num_headers++; header_size+=50; } else lprintf("rmff_fix_header: warning: no PROP chunk.\n"); if (h->cont) { num_headers++; header_size+=h->cont->size; } else lprintf("rmff_fix_header: warning: no CONT chunk.\n"); if (!h->data) { lprintf("rmff_fix_header: no DATA chunk, creating one\n"); h->data = malloc(sizeof(rmff_data_t)); h->data->object_id=DATA_TAG; h->data->object_version=0; h->data->size=34; h->data->num_packets=0; h->data->next_data_header=0; } num_headers++; if (!h->fileheader) { lprintf("rmff_fix_header: no fileheader, creating one"); h->fileheader = malloc(sizeof(rmff_fileheader_t)); h->fileheader->object_id=RMF_TAG; h->fileheader->size=34; h->fileheader->object_version=0; h->fileheader->file_version=0; h->fileheader->num_headers=num_headers+1; } header_size+=h->fileheader->size; num_headers++; if(h->fileheader->num_headers != num_headers) { lprintf("rmff_fix_header: setting num_headers from %i to %i\n", h->fileheader->num_headers, num_headers); h->fileheader->num_headers=num_headers; } if(h->prop) { if (h->prop->data_offset != header_size) { lprintf("rmff_fix_header: setting prop.data_offset from %i to %i\n", h->prop->data_offset, header_size); h->prop->data_offset=header_size; } if (h->prop->num_packets == 0) { int p=(int)(h->prop->avg_bit_rate/8.0*(h->prop->duration/1000.0)/h->prop->avg_packet_size); lprintf("rmff_fix_header: assuming prop.num_packets=%i\n", p); h->prop->num_packets=p; } if (h->data->num_packets == 0) { lprintf("rmff_fix_header: assuming data.num_packets=%i\n", h->prop->num_packets); h->data->num_packets=h->prop->num_packets; } lprintf("rmff_fix_header: assuming data.size=%i\n", h->prop->num_packets*h->prop->avg_packet_size); h->data->size=h->prop->num_packets*h->prop->avg_packet_size; } } #if 0 int rmff_get_header_size(rmff_header_t *h) { if (!h) return 0; if (!h->prop) return -1; return h->prop->data_offset+18; } void rmff_free_header(rmff_header_t *h) { if (!h) return; if (h->fileheader) free(h->fileheader); if (h->prop) free(h->prop); if (h->data) free(h->data); if (h->cont) { free(h->cont->title); free(h->cont->author); free(h->cont->copyright); free(h->cont->comment); free(h->cont); } if (h->streams) { rmff_mdpr_t **s=h->streams; while(*s) { free((*s)->stream_name); free((*s)->mime_type); free((*s)->type_specific_data); free(*s); s++; } free(h->streams); } free(h); } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/asmrp.h��������������������������������������������������������������0000644�0001750�0001750�00000002464�14647725152�015525� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2007 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * a parser for real's asm rules * * grammar for these rules: * rule_book = { '#' rule ';'} rule = condition {',' assignment} assignment = id '=' const const = ( number | string ) condition = comp_expr { ( '&&' | '||' ) comp_expr } comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand } operand = ( '$' id | num | '(' condition ')' ) */ #ifndef HAVE_ASMRP_H #define HAVE_ASMRP_H int asmrp_match (const char *rules, int bandwidth, int *matches, int matchesizxe) ; #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/real.h���������������������������������������������������������������0000644�0001750�0001750�00000003006�14647725152�015317� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * special functions for real streams. * adopted from joschkas real tools. */ #ifndef HAVE_REAL_H #define HAVE_REAL_H #include "rmff.h" #include "rtsp.h" #ifdef __CYGWIN__ #define uint32_t unsigned int #define uint16_t unsigned short int #define uint8_t unsigned char #endif /* * calculates response and checksum of a given challenge * (RealChallenge1 in rtsp). See implementation for details. */ void real_calc_response_and_checksum (char *response, char *chksum, char *challenge); int real_get_rdt_chunk(rtsp_t *rtsp_session, unsigned char **buffer); rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth); rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/real.c���������������������������������������������������������������0000644�0001750�0001750�00000053453�14647725152�015325� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * special functions for real streams. * adopted from joschkas real tools. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <string.h> #define LOG_MODULE "real" #define LOG_VERBOSE /* #define LOG */ #include "real.h" #include "asmrp.h" #include "sdpplin.h" #include <xine/xineutils.h> #include <xine/xine_buffer.h> #include "bswap.h" #define XOR_TABLE_LEN 37 static const unsigned char xor_table[] = { 0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53, 0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70, 0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09, 0x63, 0x11, 0x03, 0x71, 0x08, 0x08, 0x70, 0x02, 0x10, 0x57, 0x05, 0x18, 0x54, 0x00, 0x00, 0x00 }; #define _X_BE_32C(x,y) \ do { \ uint32_t X = be2me_32((y)); \ memcpy((x), &X, sizeof(uint32_t)); \ } while(0) #define _X_LE_32C(x,y) \ do { \ uint32_t X = le2me_32((y)); \ memcpy((x), &X, sizeof(uint32_t)); \ } while(0) static void hash(uint8_t *field, const uint8_t *param) { uint32_t a, b, c, d; /* fill variables */ a = _X_LE_32(field); b = _X_LE_32(field+4); c = _X_LE_32(field+8); d = _X_LE_32(field+12); lprintf("hash input: %x %x %x %x\n", a, b, c, d); lprintf("hash parameter:\n"); #ifdef LOG xine_hexdump(param, 64); #endif a = ((b & c) | (~b & d)) + _X_LE_32((param+0x00)) + a - 0x28955B88; a = ((a << 0x07) | (a >> 0x19)) + b; d = ((a & b) | (~a & c)) + _X_LE_32((param+0x04)) + d - 0x173848AA; d = ((d << 0x0c) | (d >> 0x14)) + a; c = ((d & a) | (~d & b)) + _X_LE_32((param+0x08)) + c + 0x242070DB; c = ((c << 0x11) | (c >> 0x0f)) + d; b = ((c & d) | (~c & a)) + _X_LE_32((param+0x0c)) + b - 0x3E423112; b = ((b << 0x16) | (b >> 0x0a)) + c; a = ((b & c) | (~b & d)) + _X_LE_32((param+0x10)) + a - 0x0A83F051; a = ((a << 0x07) | (a >> 0x19)) + b; d = ((a & b) | (~a & c)) + _X_LE_32((param+0x14)) + d + 0x4787C62A; d = ((d << 0x0c) | (d >> 0x14)) + a; c = ((d & a) | (~d & b)) + _X_LE_32((param+0x18)) + c - 0x57CFB9ED; c = ((c << 0x11) | (c >> 0x0f)) + d; b = ((c & d) | (~c & a)) + _X_LE_32((param+0x1c)) + b - 0x02B96AFF; b = ((b << 0x16) | (b >> 0x0a)) + c; a = ((b & c) | (~b & d)) + _X_LE_32((param+0x20)) + a + 0x698098D8; a = ((a << 0x07) | (a >> 0x19)) + b; d = ((a & b) | (~a & c)) + _X_LE_32((param+0x24)) + d - 0x74BB0851; d = ((d << 0x0c) | (d >> 0x14)) + a; c = ((d & a) | (~d & b)) + _X_LE_32((param+0x28)) + c - 0x0000A44F; c = ((c << 0x11) | (c >> 0x0f)) + d; b = ((c & d) | (~c & a)) + _X_LE_32((param+0x2C)) + b - 0x76A32842; b = ((b << 0x16) | (b >> 0x0a)) + c; a = ((b & c) | (~b & d)) + _X_LE_32((param+0x30)) + a + 0x6B901122; a = ((a << 0x07) | (a >> 0x19)) + b; d = ((a & b) | (~a & c)) + _X_LE_32((param+0x34)) + d - 0x02678E6D; d = ((d << 0x0c) | (d >> 0x14)) + a; c = ((d & a) | (~d & b)) + _X_LE_32((param+0x38)) + c - 0x5986BC72; c = ((c << 0x11) | (c >> 0x0f)) + d; b = ((c & d) | (~c & a)) + _X_LE_32((param+0x3c)) + b + 0x49B40821; b = ((b << 0x16) | (b >> 0x0a)) + c; a = ((b & d) | (~d & c)) + _X_LE_32((param+0x04)) + a - 0x09E1DA9E; a = ((a << 0x05) | (a >> 0x1b)) + b; d = ((a & c) | (~c & b)) + _X_LE_32((param+0x18)) + d - 0x3FBF4CC0; d = ((d << 0x09) | (d >> 0x17)) + a; c = ((d & b) | (~b & a)) + _X_LE_32((param+0x2c)) + c + 0x265E5A51; c = ((c << 0x0e) | (c >> 0x12)) + d; b = ((c & a) | (~a & d)) + _X_LE_32((param+0x00)) + b - 0x16493856; b = ((b << 0x14) | (b >> 0x0c)) + c; a = ((b & d) | (~d & c)) + _X_LE_32((param+0x14)) + a - 0x29D0EFA3; a = ((a << 0x05) | (a >> 0x1b)) + b; d = ((a & c) | (~c & b)) + _X_LE_32((param+0x28)) + d + 0x02441453; d = ((d << 0x09) | (d >> 0x17)) + a; c = ((d & b) | (~b & a)) + _X_LE_32((param+0x3c)) + c - 0x275E197F; c = ((c << 0x0e) | (c >> 0x12)) + d; b = ((c & a) | (~a & d)) + _X_LE_32((param+0x10)) + b - 0x182C0438; b = ((b << 0x14) | (b >> 0x0c)) + c; a = ((b & d) | (~d & c)) + _X_LE_32((param+0x24)) + a + 0x21E1CDE6; a = ((a << 0x05) | (a >> 0x1b)) + b; d = ((a & c) | (~c & b)) + _X_LE_32((param+0x38)) + d - 0x3CC8F82A; d = ((d << 0x09) | (d >> 0x17)) + a; c = ((d & b) | (~b & a)) + _X_LE_32((param+0x0c)) + c - 0x0B2AF279; c = ((c << 0x0e) | (c >> 0x12)) + d; b = ((c & a) | (~a & d)) + _X_LE_32((param+0x20)) + b + 0x455A14ED; b = ((b << 0x14) | (b >> 0x0c)) + c; a = ((b & d) | (~d & c)) + _X_LE_32((param+0x34)) + a - 0x561C16FB; a = ((a << 0x05) | (a >> 0x1b)) + b; d = ((a & c) | (~c & b)) + _X_LE_32((param+0x08)) + d - 0x03105C08; d = ((d << 0x09) | (d >> 0x17)) + a; c = ((d & b) | (~b & a)) + _X_LE_32((param+0x1c)) + c + 0x676F02D9; c = ((c << 0x0e) | (c >> 0x12)) + d; b = ((c & a) | (~a & d)) + _X_LE_32((param+0x30)) + b - 0x72D5B376; b = ((b << 0x14) | (b >> 0x0c)) + c; a = (b ^ c ^ d) + _X_LE_32((param+0x14)) + a - 0x0005C6BE; a = ((a << 0x04) | (a >> 0x1c)) + b; d = (a ^ b ^ c) + _X_LE_32((param+0x20)) + d - 0x788E097F; d = ((d << 0x0b) | (d >> 0x15)) + a; c = (d ^ a ^ b) + _X_LE_32((param+0x2c)) + c + 0x6D9D6122; c = ((c << 0x10) | (c >> 0x10)) + d; b = (c ^ d ^ a) + _X_LE_32((param+0x38)) + b - 0x021AC7F4; b = ((b << 0x17) | (b >> 0x09)) + c; a = (b ^ c ^ d) + _X_LE_32((param+0x04)) + a - 0x5B4115BC; a = ((a << 0x04) | (a >> 0x1c)) + b; d = (a ^ b ^ c) + _X_LE_32((param+0x10)) + d + 0x4BDECFA9; d = ((d << 0x0b) | (d >> 0x15)) + a; c = (d ^ a ^ b) + _X_LE_32((param+0x1c)) + c - 0x0944B4A0; c = ((c << 0x10) | (c >> 0x10)) + d; b = (c ^ d ^ a) + _X_LE_32((param+0x28)) + b - 0x41404390; b = ((b << 0x17) | (b >> 0x09)) + c; a = (b ^ c ^ d) + _X_LE_32((param+0x34)) + a + 0x289B7EC6; a = ((a << 0x04) | (a >> 0x1c)) + b; d = (a ^ b ^ c) + _X_LE_32((param+0x00)) + d - 0x155ED806; d = ((d << 0x0b) | (d >> 0x15)) + a; c = (d ^ a ^ b) + _X_LE_32((param+0x0c)) + c - 0x2B10CF7B; c = ((c << 0x10) | (c >> 0x10)) + d; b = (c ^ d ^ a) + _X_LE_32((param+0x18)) + b + 0x04881D05; b = ((b << 0x17) | (b >> 0x09)) + c; a = (b ^ c ^ d) + _X_LE_32((param+0x24)) + a - 0x262B2FC7; a = ((a << 0x04) | (a >> 0x1c)) + b; d = (a ^ b ^ c) + _X_LE_32((param+0x30)) + d - 0x1924661B; d = ((d << 0x0b) | (d >> 0x15)) + a; c = (d ^ a ^ b) + _X_LE_32((param+0x3c)) + c + 0x1fa27cf8; c = ((c << 0x10) | (c >> 0x10)) + d; b = (c ^ d ^ a) + _X_LE_32((param+0x08)) + b - 0x3B53A99B; b = ((b << 0x17) | (b >> 0x09)) + c; a = ((~d | b) ^ c) + _X_LE_32((param+0x00)) + a - 0x0BD6DDBC; a = ((a << 0x06) | (a >> 0x1a)) + b; d = ((~c | a) ^ b) + _X_LE_32((param+0x1c)) + d + 0x432AFF97; d = ((d << 0x0a) | (d >> 0x16)) + a; c = ((~b | d) ^ a) + _X_LE_32((param+0x38)) + c - 0x546BDC59; c = ((c << 0x0f) | (c >> 0x11)) + d; b = ((~a | c) ^ d) + _X_LE_32((param+0x14)) + b - 0x036C5FC7; b = ((b << 0x15) | (b >> 0x0b)) + c; a = ((~d | b) ^ c) + _X_LE_32((param+0x30)) + a + 0x655B59C3; a = ((a << 0x06) | (a >> 0x1a)) + b; d = ((~c | a) ^ b) + _X_LE_32((param+0x0C)) + d - 0x70F3336E; d = ((d << 0x0a) | (d >> 0x16)) + a; c = ((~b | d) ^ a) + _X_LE_32((param+0x28)) + c - 0x00100B83; c = ((c << 0x0f) | (c >> 0x11)) + d; b = ((~a | c) ^ d) + _X_LE_32((param+0x04)) + b - 0x7A7BA22F; b = ((b << 0x15) | (b >> 0x0b)) + c; a = ((~d | b) ^ c) + _X_LE_32((param+0x20)) + a + 0x6FA87E4F; a = ((a << 0x06) | (a >> 0x1a)) + b; d = ((~c | a) ^ b) + _X_LE_32((param+0x3c)) + d - 0x01D31920; d = ((d << 0x0a) | (d >> 0x16)) + a; c = ((~b | d) ^ a) + _X_LE_32((param+0x18)) + c - 0x5CFEBCEC; c = ((c << 0x0f) | (c >> 0x11)) + d; b = ((~a | c) ^ d) + _X_LE_32((param+0x34)) + b + 0x4E0811A1; b = ((b << 0x15) | (b >> 0x0b)) + c; a = ((~d | b) ^ c) + _X_LE_32((param+0x10)) + a - 0x08AC817E; a = ((a << 0x06) | (a >> 0x1a)) + b; d = ((~c | a) ^ b) + _X_LE_32((param+0x2c)) + d - 0x42C50DCB; d = ((d << 0x0a) | (d >> 0x16)) + a; c = ((~b | d) ^ a) + _X_LE_32((param+0x08)) + c + 0x2AD7D2BB; c = ((c << 0x0f) | (c >> 0x11)) + d; b = ((~a | c) ^ d) + _X_LE_32((param+0x24)) + b - 0x14792C6F; b = ((b << 0x15) | (b >> 0x0b)) + c; lprintf("hash output: %x %x %x %x\n", a, b, c, d); a += _X_LE_32(field); b += _X_LE_32(field+4); c += _X_LE_32(field+8); d += _X_LE_32(field+12); _X_LE_32C(field, a); _X_LE_32C(field+4, b); _X_LE_32C(field+8, c); _X_LE_32C(field+12, d); } static void call_hash (uint8_t *key, const uint8_t *challenge, unsigned int len) { uint8_t *ptr1, *ptr2; uint32_t a, b, c, d, tmp; ptr1=(key+16); ptr2=(key+20); a = _X_LE_32(ptr1); b = (a >> 3) & 0x3f; a += len * 8; _X_LE_32C(ptr1, a); if (a < (len << 3)) { lprintf("not verified: (len << 3) > a true\n"); ptr2 += 4; } tmp = _X_LE_32(ptr2) + (len >> 0x1d); _X_LE_32C(ptr2, tmp); a = 64 - b; c = 0; if (a <= len) { memcpy(key+b+24, challenge, a); hash(key, key+24); c = a; d = c + 0x3f; while ( d < len ) { lprintf("not verified: while ( d < len )\n"); hash(key, challenge+d-0x3f); d += 64; c += 64; } b = 0; } memcpy(key+b+24, challenge+c, len-c); } static void calc_response (uint8_t *result, uint8_t *field) { uint8_t buf1[128]; uint8_t buf2[128]; unsigned int i; memset (buf1, 0, 64); *buf1 = 128; memcpy (buf2, field+16, 8); i = ( _X_LE_32((buf2)) >> 3 ) & 0x3f; if (i < 56) { i = 56 - i; } else { lprintf("not verified: ! (i < 56)\n"); i = 120 - i; } call_hash (field, buf1, i); call_hash (field, buf2, 8); memcpy (result, field, 16); } static void calc_response_string (char *result, const uint8_t *challenge) { uint8_t field[128] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t zres[20]; int i; /* calculate response */ call_hash(field, challenge, 64); calc_response(zres,field); /* convert zres to ascii string */ for (i=0; i<16; i++ ) { char a, b; a = (zres[i] >> 4) & 15; b = zres[i] & 15; result[i*2] = ((a<10) ? (a+48) : (a+87)) & 255; result[i*2+1] = ((b<10) ? (b+48) : (b+87)) & 255; } } void real_calc_response_and_checksum (char *response, char *chksum, char *challenge) { size_t ch_len, resp_len; int i; uint8_t *ptr; uint8_t buf[128] = { 0, }; /* initialize return values */ memset(response, 0, 64); memset(chksum, 0, 34); /* initialize buffer */ ptr=buf; _X_BE_32C(ptr, 0xa1e9149d); ptr+=4; _X_BE_32C(ptr, 0x0e6b3b59); ptr+=4; /* some (length) checks */ if (challenge != NULL) { ch_len = strlen (challenge); if (ch_len == 40) /* what a hack... */ { challenge[32]=0; ch_len=32; } if ( ch_len > 56 ) ch_len=56; /* copy challenge to buf */ memcpy(ptr, challenge, ch_len); } /* xor challenge bytewise with xor_table */ for (i=0; i<XOR_TABLE_LEN; i++) ptr[i] = ptr[i] ^ xor_table[i]; calc_response_string (response, buf); /* add tail */ strcat(response, "01d0a8e3"); /* calculate checksum */ resp_len = strlen (response); for (i=0; i<(int)(resp_len/4); i++) chksum[i] = response[i*4]; } /* * takes a MLTI-Chunk and a rule number got from match_asm_rule, * returns a pointer to selected data and number of bytes in that. */ static int select_mlti_data(const char *mlti_chunk, int mlti_size, int selection, char **out) { int numrules, codec, size; int i; /* MLTI chunk should begin with MLTI */ if ((mlti_chunk[0] != 'M') ||(mlti_chunk[1] != 'L') ||(mlti_chunk[2] != 'T') ||(mlti_chunk[3] != 'I')) { lprintf("MLTI tag not detected, copying data\n"); xine_buffer_copyin(*out, 0, mlti_chunk, mlti_size); return mlti_size; } mlti_chunk+=4; /* next 16 bits are the number of rules */ numrules=_X_BE_16(mlti_chunk); if (selection >= numrules) return 0; /* now <numrules> indices of codecs follows */ /* we skip to selection */ mlti_chunk+=(selection+1)*2; /* get our index */ codec=_X_BE_16(mlti_chunk); /* skip to number of codecs */ mlti_chunk+=(numrules-selection)*2; /* get number of codecs */ numrules=_X_BE_16(mlti_chunk); if (codec >= numrules) { lprintf("codec index >= number of codecs. %i %i\n", codec, numrules); return 0; } mlti_chunk+=2; /* now seek to selected codec */ for (i=0; i<codec; i++) { size=_X_BE_32(mlti_chunk); mlti_chunk+=size+4; } size=_X_BE_32(mlti_chunk); #ifdef LOG xine_hexdump(mlti_chunk+4, size); #endif xine_buffer_copyin(*out, 0, mlti_chunk+4, size); return size; } /* * looking at stream description. */ rmff_header_t *real_parse_sdp(char *data, char **stream_rules, uint32_t bandwidth) { sdpplin_t *desc; rmff_header_t *header; char *buf; int len, i; int max_bit_rate=0; int avg_bit_rate=0; int max_packet_size=0; int avg_packet_size=0; int duration=0; if (!data) return NULL; desc=sdpplin_parse(data); if (!desc) return NULL; buf=xine_buffer_init(2048); header = calloc(1, sizeof(rmff_header_t)); header->fileheader=rmff_new_fileheader(4+desc->stream_count); header->cont=rmff_new_cont( desc->title, desc->author, desc->copyright, desc->abstract); header->data=rmff_new_dataheader(0,0); header->streams = calloc((desc->stream_count+1), sizeof(rmff_mdpr_t*)); lprintf("number of streams: %u\n", desc->stream_count); for (i=0; i<desc->stream_count; i++) { int j=0; int n; char b[64]; int rulematches[16]; lprintf("calling asmrp_match with:\n%s\n%u\n", desc->stream[i]->asm_rule_book, bandwidth); n=asmrp_match(desc->stream[i]->asm_rule_book, bandwidth, rulematches, sizeof(rulematches)/sizeof(rulematches[0])); for (j=0; j<n; j++) { lprintf("asmrp rule match: %u for stream %u\n", rulematches[j], desc->stream[i]->stream_id); sprintf(b,"stream=%u;rule=%u,", desc->stream[i]->stream_id, rulematches[j]); xine_buffer_strcat(*stream_rules, b); } if (!desc->stream[i]->mlti_data) { len = 0; xine_buffer_free(buf); buf = NULL; } else len=select_mlti_data(desc->stream[i]->mlti_data, desc->stream[i]->mlti_data_size, rulematches[0], &buf); header->streams[i]=rmff_new_mdpr( desc->stream[i]->stream_id, desc->stream[i]->max_bit_rate, desc->stream[i]->avg_bit_rate, desc->stream[i]->max_packet_size, desc->stream[i]->avg_packet_size, desc->stream[i]->start_time, desc->stream[i]->preroll, desc->stream[i]->duration, desc->stream[i]->stream_name, desc->stream[i]->mime_type, len, buf); duration=MAX(duration,desc->stream[i]->duration); max_bit_rate+=desc->stream[i]->max_bit_rate; avg_bit_rate+=desc->stream[i]->avg_bit_rate; max_packet_size=MAX(max_packet_size, desc->stream[i]->max_packet_size); if (avg_packet_size) avg_packet_size=(avg_packet_size + desc->stream[i]->avg_packet_size) / 2; else avg_packet_size=desc->stream[i]->avg_packet_size; } if (*stream_rules && strlen(*stream_rules) && (*stream_rules)[strlen(*stream_rules)-1] == ',') (*stream_rules)[strlen(*stream_rules)-1]=0; /* delete last ',' in stream_rules */ header->prop=rmff_new_prop( max_bit_rate, avg_bit_rate, max_packet_size, avg_packet_size, 0, duration, 0, 0, 0, desc->stream_count, desc->flags); rmff_fix_header(header); if (buf) xine_buffer_free(buf); sdpplin_free(desc); return header; } int real_get_rdt_chunk(rtsp_t *rtsp_session, unsigned char **buffer) { int n=1; uint8_t header[8]; rmff_pheader_t ph; int size; int flags1; #ifdef LOG int unknown1; #endif uint32_t ts; n=rtsp_read_data(rtsp_session, header, 8); if (n<8) return 0; if (header[0] != 0x24) { lprintf("rdt chunk not recognized: got 0x%02x\n", header[0]); return 0; } size=(header[1]<<16)+(header[2]<<8)+(header[3]); flags1=header[4]; if ((flags1!=0x40)&&(flags1!=0x42)) { lprintf("got flags1: 0x%02x\n",flags1); if (header[6]==0x06) { lprintf("got end of stream packet\n"); return 0; } header[0]=header[5]; header[1]=header[6]; header[2]=header[7]; n=rtsp_read_data(rtsp_session, header+3, 5); if (n<5) return 0; lprintf("ignoring bytes:\n"); #ifdef LOG xine_hexdump(header, 8); #endif n=rtsp_read_data(rtsp_session, header+4, 4); if (n<4) return 0; flags1=header[4]; size-=9; } #ifdef LOG unknown1=(header[5]<<16)+(header[6]<<8)+(header[7]); #endif n=rtsp_read_data(rtsp_session, header, 6); if (n<6) return 0; ts=_X_BE_32(header); #ifdef LOG lprintf("ts: %u size: %u, flags: 0x%02x, unknown values: %u 0x%02x 0x%02x\n", ts, size, flags1, unknown1, header[4], header[5]); #endif size+=2; ph.object_version=0; ph.length=size; ph.stream_number=(flags1>>1)&1; ph.timestamp=ts; ph.reserved=0; ph.flags=0; /* TODO: determine keyframe flag and insert here? */ xine_buffer_ensure_size(*buffer, 12+size); rmff_dump_pheader(&ph, *buffer); size-=12; n=rtsp_read_data(rtsp_session, (*buffer)+12, size); return (n <= 0) ? 0 : n+12; } //! maximum size of the rtsp description, must be < INT_MAX #define MAX_DESC_BUF (20 * 1024 * 1024) rmff_header_t *real_setup_and_get_header(rtsp_t *rtsp_session, uint32_t bandwidth) { char *description=NULL; char *session_id=NULL; rmff_header_t *h = NULL; const char *tmp; char *challenge1 = NULL; char challenge2[64]; char checksum[34]; char *subscribe = NULL; char *buf=xine_buffer_init(256); char *mrl=rtsp_get_mrl(rtsp_session); unsigned int size; int status; /* get challenge */ tmp = rtsp_search_answers(rtsp_session,"RealChallenge1"); if (tmp) { challenge1 = strdup(tmp); lprintf("Challenge1: %s\n", challenge1); } /* request stream description */ rtsp_schedule_field(rtsp_session, "Accept: application/sdp"); sprintf(buf, "Bandwidth: %u", bandwidth); rtsp_schedule_field(rtsp_session, buf); rtsp_schedule_field(rtsp_session, "GUID: 00000000-0000-0000-0000-000000000000"); rtsp_schedule_field(rtsp_session, "RegionData: 0"); rtsp_schedule_field(rtsp_session, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); rtsp_schedule_field(rtsp_session, "SupportsMaximumASMBandwidth: 1"); rtsp_schedule_field(rtsp_session, "Language: en-US"); rtsp_schedule_field(rtsp_session, "Require: com.real.retain-entity-for-setup"); status=rtsp_request_describe(rtsp_session,NULL); if ( status<200 || status>299 ) { const char *alert=rtsp_search_answers(rtsp_session,"Alert"); if (alert) { lprintf("real: got message from server:\n%s\n", alert); } rtsp_send_ok(rtsp_session); goto out; } /* receive description */ size=0; if (!rtsp_search_answers(rtsp_session,"Content-length")) lprintf("real: got no Content-length!\n"); else size=atoi(rtsp_search_answers(rtsp_session,"Content-length")); if (size > MAX_DESC_BUF) { printf("real: Content-length for description too big (> %uMB)!\n", MAX_DESC_BUF/(1024*1024) ); goto out; } if (!rtsp_search_answers(rtsp_session,"ETag")) lprintf("real: got no ETag!\n"); else session_id=strdup(rtsp_search_answers(rtsp_session,"ETag")); lprintf("Stream description size: %i\n", size); description = malloc(size+1); if( rtsp_read_data(rtsp_session, description, size) <= 0) { goto out; } description[size]=0; /* parse sdp (sdpplin) and create a header and a subscribe string */ subscribe=xine_buffer_init(256); strcpy(subscribe, "Subscribe: "); h=real_parse_sdp(description, &subscribe, bandwidth); if (!h) { goto out; } rmff_fix_header(h); lprintf("Title: %s\nCopyright: %s\nAuthor: %s\nStreams: %i\n", h->cont->title, h->cont->copyright, h->cont->author, h->prop->num_streams); /* setup our streams */ if (challenge1) { real_calc_response_and_checksum (challenge2, checksum, challenge1); xine_buffer_ensure_size(buf, strlen(challenge2) + strlen(checksum) + 32); sprintf(buf, "RealChallenge2: %s, sd=%s", challenge2, checksum); rtsp_schedule_field(rtsp_session, buf); } xine_buffer_ensure_size(buf, strlen(session_id) + 32); sprintf(buf, "If-Match: %s", session_id); rtsp_schedule_field(rtsp_session, buf); rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); xine_buffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=0", mrl); rtsp_request_setup(rtsp_session,buf); if (h->prop->num_streams > 1) { rtsp_schedule_field(rtsp_session, "Transport: x-pn-tng/tcp;mode=play,rtp/avp/tcp;unicast;mode=play"); xine_buffer_ensure_size(buf, strlen(session_id) + 32); sprintf(buf, "If-Match: %s", session_id); rtsp_schedule_field(rtsp_session, buf); xine_buffer_ensure_size(buf, strlen(mrl) + 32); sprintf(buf, "%s/streamid=1", mrl); rtsp_request_setup(rtsp_session,buf); } /* set stream parameter (bandwidth) with our subscribe string */ rtsp_schedule_field(rtsp_session, subscribe); rtsp_request_setparameter(rtsp_session,NULL); out: free(description); free(challenge1); free(session_id); if (subscribe) xine_buffer_free(subscribe); xine_buffer_free(buf); return h; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/sdpplin.c������������������������������������������������������������0000644�0001750�0001750�00000020454�14647725152�016046� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * sdp/sdpplin parser. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "sdpplin" #define LOG_VERBOSE /* #define LOG */ #include "rmff.h" #include "rtsp.h" #include "sdpplin.h" #include <xine/xineutils.h> #include <xine/xine_buffer.h> static char *nl(char *data) { char *nlptr = (data) ? strchr(data,'\n') : NULL; return (nlptr) ? nlptr + 1 : NULL; } static int filter(const char *in, const char *filter, char **out) { size_t flen=strlen(filter); size_t len; if (!in) return 0; len = (strchr(in,'\n')) ? (size_t)(strchr(in,'\n')-in) : strlen(in); if (!strncmp(in,filter,flen)) { if(in[flen]=='"') flen++; if(in[len-1]==13) len--; if(in[len-1]=='"') len--; xine_buffer_copyin(*out, 0, in+flen, len-flen+1); (*out)[len-flen]=0; return len-flen; } return 0; } static void sdpplin_free_stream(sdpplin_stream_t **pp) { if (*pp) { sdpplin_stream_t *p = *pp; _x_freep(&p->id); _x_freep(&p->stream_name); _x_freep(&p->mime_type); _x_freep(&p->mlti_data); _x_freep(&p->asm_rule_book); _x_freep(pp); } } static sdpplin_stream_t *XINE_MALLOC sdpplin_parse_stream(char **data) { sdpplin_stream_t *desc; char *buf; int handled; desc = calloc(1, sizeof(sdpplin_stream_t)); if (!desc) return NULL; buf = xine_buffer_init(32); if (!buf) { free(desc); return NULL; } if (filter(*data, "m=", &buf)) { desc->id = strdup(buf); } else { lprintf("sdpplin: no m= found.\n"); free(desc); xine_buffer_free(buf); return NULL; } *data=nl(*data); while (*data && **data && *data[0]!='m') { int dlen; handled=0; if(filter(*data,"a=control:streamid=",&buf)) { /* This way negative values are mapped to unfeasibly high * values, and will be discarded afterward */ unsigned long tmp = strtoul(buf, NULL, 10); if ( tmp > UINT16_MAX ) lprintf("stream id out of bound: %lu\n", tmp); else desc->stream_id=tmp; handled=1; *data=nl(*data); } if(filter(*data,"a=MaxBitRate:integer;",&buf)) { desc->max_bit_rate=atoi(buf); if (!desc->avg_bit_rate) desc->avg_bit_rate=desc->max_bit_rate; handled=1; *data=nl(*data); } if(filter(*data,"a=MaxPacketSize:integer;",&buf)) { desc->max_packet_size=atoi(buf); if (!desc->avg_packet_size) desc->avg_packet_size=desc->max_packet_size; handled=1; *data=nl(*data); } if(filter(*data,"a=StartTime:integer;",&buf)) { desc->start_time=atoi(buf); handled=1; *data=nl(*data); } if(filter(*data,"a=Preroll:integer;",&buf)) { desc->preroll=atoi(buf); handled=1; *data=nl(*data); } if(filter(*data,"a=length:npt=",&buf)) { desc->duration=(uint32_t)(atof(buf)*1000); handled=1; *data=nl(*data); } if(filter(*data,"a=StreamName:string;",&buf)) { desc->stream_name=strdup(buf); desc->stream_name_size=strlen(desc->stream_name); handled=1; *data=nl(*data); } if(filter(*data,"a=mimetype:string;",&buf)) { desc->mime_type=strdup(buf); desc->mime_type_size=strlen(desc->mime_type); handled=1; *data=nl(*data); } if((dlen=filter(*data,"a=OpaqueData:buffer;",&buf))!=0) { desc->mlti_data = malloc((dlen + 2) * 3 / 4 + 4); desc->mlti_data_size = xine_base64_decode(buf, desc->mlti_data); desc->mlti_data[desc->mlti_data_size] = 0; if ( desc->mlti_data_size > 0 ) { handled=1; *data=nl(*data); lprintf("mlti_data_size: %i\n", desc->mlti_data_size); } else { free(desc->mlti_data); desc->mlti_data = NULL; } } if(filter(*data,"a=ASMRuleBook:string;",&buf)) { desc->asm_rule_book=strdup(buf); handled=1; *data=nl(*data); } if(!handled) { #ifdef LOG int len=strchr(*data,'\n')-(*data); xine_buffer_copyin(buf, 0, *data, len+1); buf[len]=0; printf("libreal: sdpplin: not handled: '%s'\n", buf); #endif *data=nl(*data); } } xine_buffer_free(buf); return desc; } sdpplin_t *sdpplin_parse(char *data) { sdpplin_t *desc; char *buf; int handled; int len; desc = calloc(1, sizeof(sdpplin_t)); if (!desc) return NULL; buf = xine_buffer_init(32); if (!buf) { free(desc); return NULL; } desc->stream = NULL; while (data && *data) { int dlen; handled=0; if (filter(data, "m=", &buf)) { sdpplin_stream_t *stream; if ( ! desc->stream ) { fprintf(stderr, "sdpplin.c: stream identifier found before stream count, skipping."); continue; } stream=sdpplin_parse_stream(&data); lprintf("got data for stream id %u\n", stream->stream_id); if ( stream->stream_id >= desc->stream_count ) { lprintf("stream id %u is greater than stream count %u\n", stream->stream_id, desc->stream_count); sdpplin_free_stream(&stream); } else { if (desc->stream[stream->stream_id]) sdpplin_free_stream(&desc->stream[stream->stream_id]); desc->stream[stream->stream_id]=stream; } continue; } if((dlen=filter(data,"a=Title:buffer;",&buf))!=0) { desc->title = malloc((dlen + 2) * 3 / 4 + 4); len = xine_base64_decode(buf, desc->title); desc->title[len] = 0; if ( len > 0 ) { handled=1; data=nl(data); } else { free(desc->title); desc->title = NULL; } } if((dlen=filter(data,"a=Author:buffer;",&buf))!=0) { desc->author = malloc((dlen + 2) * 3 / 4 + 4); len = xine_base64_decode(buf, desc->author); desc->author[len] = 0; if ( len > 0 ) { handled=1; data=nl(data); } else { free(desc->author); desc->author = NULL; } } if((dlen=filter(data,"a=Copyright:buffer;",&buf))!=0) { desc->copyright = malloc((dlen + 2) * 3 / 4 + 4); len = xine_base64_decode(buf, desc->copyright); desc->copyright[len] = 0; if ( len > 0 ) { handled=1; data=nl(data); } else { free(desc->copyright); desc->copyright = NULL; } } if((dlen=filter(data,"a=Abstract:buffer;",&buf))!=0) { desc->abstract = malloc ((dlen + 2) * 3 / 4 + 4); len = xine_base64_decode(buf, desc->abstract); desc->abstract[len] = 0; if ( len > 0 ) { handled=1; data=nl(data); } else { free(desc->abstract); desc->abstract = NULL; } } if(filter(data,"a=StreamCount:integer;",&buf)) { /* This way negative values are mapped to unfeasibly high * values, and will be discarded afterward */ unsigned long tmp = strtoul(buf, NULL, 10); if ( tmp > UINT16_MAX ) lprintf("stream count out of bound: %lu\n", tmp); else desc->stream_count = tmp; desc->stream = calloc(desc->stream_count, sizeof(sdpplin_stream_t*)); handled=1; data=nl(data); } if(filter(data,"a=Flags:integer;",&buf)) { desc->flags=atoi(buf); handled=1; data=nl(data); } if(!handled) { #ifdef LOG int len=strchr(data,'\n')-data; xine_buffer_copyin(buf, 0, data, len+1); buf[len]=0; printf("libreal: sdpplin: not handled: '%s'\n", buf); #endif data=nl(data); } } xine_buffer_free(buf); return desc; } void sdpplin_free(sdpplin_t *p) { if (p->stream) { unsigned i; for (i = 0; i < p->stream_count; i++) { sdpplin_free_stream(&p->stream[i]); } _x_freep(&p->stream); } _x_freep(&p->title); _x_freep(&p->author); _x_freep(&p->copyright); _x_freep(&p->abstract); free(p); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/sdpplin.h������������������������������������������������������������0000644�0001750�0001750�00000004534�14647725152�016054� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * sdp/sdpplin parser. */ #ifndef HAVE_SDPPLIN_H #define HAVE_SDPPLIN_H #include "rmff.h" #include "rtsp.h" #ifdef __CYGWIN__ #define uint32_t unsigned int #define uint16_t unsigned short int #define uint8_t unsigned char #endif typedef struct { char *id; //char *bandwidth; uint16_t stream_id; //char *range; //char *length; //char *rtpmap; //char *mimetype; //int min_switch_overlap; int start_time; //int end_one_rule_end_all; int avg_bit_rate; int max_bit_rate; int avg_packet_size; int max_packet_size; //int end_time; //int seek_greater_on_switch; int preroll; int duration; char *stream_name; int stream_name_size; char *mime_type; int mime_type_size; char *mlti_data; int mlti_data_size; //int rmff_flags_length; //char *rmff_flags; int asm_rule_book_length; char *asm_rule_book; } sdpplin_stream_t; typedef struct { //int sdp_version, sdpplin_version; //char *owner; //char *session_name; //char *session_info; //char *uri; //char *email; //char *phone; //char *connection; //char *bandwidth; int flags; //int is_real_data_type; uint16_t stream_count; char *title; char *author; char *copyright; //char *keywords; //int asm_rule_book_length; //char *asm_rule_book; char *abstract; //char *range; //int avg_bit_rate; //int max_bit_rate; //int avg_packet_size; //int max_packet_size; //int preroll; //int duration; sdpplin_stream_t **stream; } sdpplin_t; sdpplin_t *sdpplin_parse(char *data) XINE_MALLOC; void sdpplin_free(sdpplin_t *description); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libreal/asmrp.c��������������������������������������������������������������0000644�0001750�0001750�00000026463�14647725152�015525� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * a parser for real's asm rules * * grammar for these rules: * rule_book = { rule } rule = ( '#' condition { ',' assignment } | [ assignment {',' assignment} ]) ';' assignment = id '=' const const = ( number | string ) condition = comp_expr { ( '&&' | '||' ) comp_expr } comp_expr = operand { ( '<' | '<=' | '==' | '>=' | '>' ) operand } operand = ( '$' id | num | '(' condition ')' ) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <string.h> #define LOG_MODULE "asmrp" #define LOG_VERBOSE /* #define LOG */ #include "asmrp.h" #include <xine/xineutils.h> #define ASMRP_SYM_NONE 0 #define ASMRP_SYM_EOF 1 #define ASMRP_SYM_NUM 2 #define ASMRP_SYM_ID 3 #define ASMRP_SYM_STRING 4 #define ASMRP_SYM_HASH 10 #define ASMRP_SYM_SEMICOLON 11 #define ASMRP_SYM_COMMA 12 #define ASMRP_SYM_EQUALS 13 #define ASMRP_SYM_AND 14 #define ASMRP_SYM_OR 15 #define ASMRP_SYM_LESS 16 #define ASMRP_SYM_LEQ 17 #define ASMRP_SYM_GEQ 18 #define ASMRP_SYM_GREATER 19 #define ASMRP_SYM_DOLLAR 20 #define ASMRP_SYM_LPAREN 21 #define ASMRP_SYM_RPAREN 22 #define ASMRP_MAX_ID 1024 #define ASMRP_MAX_SYMTAB 10 typedef struct { char *id; int v; } asmrp_sym_t; typedef struct { /* public part */ int sym; int num; char str[ASMRP_MAX_ID]; /* private part */ char *buf; int pos; char ch; asmrp_sym_t sym_tab[ASMRP_MAX_SYMTAB]; int sym_tab_num; } asmrp_t; static asmrp_t *XINE_MALLOC asmrp_new () { asmrp_t *p; p = malloc (sizeof (asmrp_t)); p->sym_tab_num = 0; p->sym = ASMRP_SYM_NONE; return p; } static void asmrp_dispose (asmrp_t *p) { int i; for (i=0; i<p->sym_tab_num; i++) free (p->sym_tab[i].id); free (p); } static void asmrp_getch (asmrp_t *p) { p->ch = p->buf[p->pos]; p->pos++; lprintf ("%c\n", p->ch); } static void asmrp_init (asmrp_t *p, const char *str) { p->buf = strdup (str); p->pos = 0; asmrp_getch (p); } static void asmrp_number (asmrp_t *p) { int num; num = 0; while ( (p->ch>='0') && (p->ch<='9') ) { num = num*10 + (p->ch - '0'); asmrp_getch (p); } p->sym = ASMRP_SYM_NUM; p->num = num; } static void asmrp_string (asmrp_t *p) { int l; l = 0; while ( (p->ch!='"') && (p->ch>=32) ) { p->str[l] = p->ch; l++; asmrp_getch (p); } p->str[l]=0; if (p->ch=='"') asmrp_getch (p); p->sym = ASMRP_SYM_STRING; } static void asmrp_identifier (asmrp_t *p) { int l; l = 0; while ( ((p->ch>='A') && (p->ch<='z')) || ((p->ch>='0') && (p->ch<='9'))) { p->str[l] = p->ch; l++; asmrp_getch (p); } p->str[l]=0; p->sym = ASMRP_SYM_ID; } #ifdef LOG static void asmrp_print_sym (asmrp_t *p) { printf ("symbol: "); switch (p->sym) { case ASMRP_SYM_NONE: printf ("NONE\n"); break; case ASMRP_SYM_EOF: printf ("EOF\n"); break; case ASMRP_SYM_NUM: printf ("NUM %d\n", p->num); break; case ASMRP_SYM_ID: printf ("ID '%s'\n", p->str); break; case ASMRP_SYM_STRING: printf ("STRING \"%s\"\n", p->str); break; case ASMRP_SYM_HASH: printf ("#\n"); break; case ASMRP_SYM_SEMICOLON: printf (";\n"); break; case ASMRP_SYM_COMMA: printf (",\n"); break; case ASMRP_SYM_EQUALS: printf ("==\n"); break; case ASMRP_SYM_AND: printf ("&&\n"); break; case ASMRP_SYM_OR: printf ("||\n"); break; case ASMRP_SYM_LESS: printf ("<\n"); break; case ASMRP_SYM_LEQ: printf ("<=\n"); break; case ASMRP_SYM_GEQ: printf (">=\n"); break; case ASMRP_SYM_GREATER: printf (">\n"); break; case ASMRP_SYM_DOLLAR: printf ("$\n"); break; case ASMRP_SYM_LPAREN: printf ("(\n"); break; case ASMRP_SYM_RPAREN: printf (")\n"); break; default: printf ("unknown symbol %d\n", p->sym); } } #endif static void asmrp_get_sym (asmrp_t *p) { while (p->ch <= 32) { if (p->ch == 0) { p->sym = ASMRP_SYM_EOF; return; } asmrp_getch (p); } if (p->ch == '\\') asmrp_getch (p); switch (p->ch) { case '#': p->sym = ASMRP_SYM_HASH; asmrp_getch (p); break; case ';': p->sym = ASMRP_SYM_SEMICOLON; asmrp_getch (p); break; case ',': p->sym = ASMRP_SYM_COMMA; asmrp_getch (p); break; case '=': p->sym = ASMRP_SYM_EQUALS; asmrp_getch (p); if (p->ch=='=') asmrp_getch (p); break; case '&': p->sym = ASMRP_SYM_AND; asmrp_getch (p); if (p->ch=='&') asmrp_getch (p); break; case '|': p->sym = ASMRP_SYM_OR; asmrp_getch (p); if (p->ch=='|') asmrp_getch (p); break; case '<': p->sym = ASMRP_SYM_LESS; asmrp_getch (p); if (p->ch=='=') { p->sym = ASMRP_SYM_LEQ; asmrp_getch (p); } break; case '>': p->sym = ASMRP_SYM_GREATER; asmrp_getch (p); if (p->ch=='=') { p->sym = ASMRP_SYM_GEQ; asmrp_getch (p); } break; case '$': p->sym = ASMRP_SYM_DOLLAR; asmrp_getch (p); break; case '(': p->sym = ASMRP_SYM_LPAREN; asmrp_getch (p); break; case ')': p->sym = ASMRP_SYM_RPAREN; asmrp_getch (p); break; case '"': asmrp_getch (p); asmrp_string (p); break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': asmrp_number (p); break; default: asmrp_identifier (p); } #ifdef LOG asmrp_print_sym (p); #endif } static int asmrp_find_id (asmrp_t *p, const char *s) { int i; for (i=0; i<p->sym_tab_num; i++) { if (!strcmp (s, p->sym_tab[i].id)) return i; } return -1; } static int asmrp_set_id (asmrp_t *p, const char *s, int v) { int i; i = asmrp_find_id (p, s); if (i<0) { i = p->sym_tab_num; p->sym_tab_num++; p->sym_tab[i].id = strdup (s); lprintf ("new symbol '%s'\n", s); } p->sym_tab[i].v = v; lprintf ("symbol '%s' assigned %d\n", s, v); return i; } static int asmrp_condition (asmrp_t *p) ; static int asmrp_operand (asmrp_t *p) { int i, ret; lprintf ("operand\n"); ret = 0; switch (p->sym) { case ASMRP_SYM_DOLLAR: asmrp_get_sym (p); if (p->sym != ASMRP_SYM_ID) { fprintf (stderr, "asmrp error: identifier expected.\n"); //_x_abort(); return 0; } i = asmrp_find_id (p, p->str); if (i<0) { fprintf (stderr, "asmrp error: unknown identifier %s\n", p->str); ret = 0; break; } ret = p->sym_tab[i].v; asmrp_get_sym (p); break; case ASMRP_SYM_NUM: ret = p->num; asmrp_get_sym (p); break; case ASMRP_SYM_LPAREN: asmrp_get_sym (p); ret = asmrp_condition (p); if (p->sym != ASMRP_SYM_RPAREN) { fprintf (stderr, "asmrp error: ) expected.\n"); //_x_abort(); return 0; } asmrp_get_sym (p); break; default: fprintf (stderr, "asmrp syntax error, $ number or ( expected\n"); //_x_abort(); return 0; } lprintf ("operand done, =%d\n", ret); return ret; } static int asmrp_comp_expression (asmrp_t *p) { int a; lprintf ("comp_expression\n"); a = asmrp_operand (p); while ( (p->sym == ASMRP_SYM_LESS) || (p->sym == ASMRP_SYM_LEQ) || (p->sym == ASMRP_SYM_EQUALS) || (p->sym == ASMRP_SYM_GEQ) || (p->sym == ASMRP_SYM_GREATER) ) { int op = p->sym; int b; asmrp_get_sym (p); b = asmrp_operand (p); switch (op) { case ASMRP_SYM_LESS: a = a<b; break; case ASMRP_SYM_LEQ: a = a<=b; break; case ASMRP_SYM_EQUALS: a = a==b; break; case ASMRP_SYM_GEQ: a = a>=b; break; case ASMRP_SYM_GREATER: a = a>b; break; } } lprintf ("comp_expression done = %d\n", a); return a; } static int asmrp_condition (asmrp_t *p) { int a; lprintf ("condition\n"); a = asmrp_comp_expression (p); while ( (p->sym == ASMRP_SYM_AND) || (p->sym == ASMRP_SYM_OR) ) { int op, b; op = p->sym; asmrp_get_sym (p); b = asmrp_comp_expression (p); switch (op) { case ASMRP_SYM_AND: a = a & b; break; case ASMRP_SYM_OR: a = a | b; break; } } lprintf ("condition done = %d\n", a); return a; } static void asmrp_assignment (asmrp_t *p) { lprintf ("assignment\n"); if (p->sym == ASMRP_SYM_COMMA || p->sym == ASMRP_SYM_SEMICOLON) { lprintf ("empty assignment\n"); return; } if (p->sym != ASMRP_SYM_ID) { fprintf (stderr, "asmrp error: identifier expected\n"); //_x_abort (); return; } asmrp_get_sym (p); if (p->sym != ASMRP_SYM_EQUALS) { fprintf (stderr, "asmrp error: = expected\n"); //_x_abort (); return; } asmrp_get_sym (p); if ( (p->sym != ASMRP_SYM_NUM) && (p->sym != ASMRP_SYM_STRING) && (p->sym != ASMRP_SYM_ID)) { fprintf (stderr, "asmrp error: number or string expected\n"); //_x_abort (); return; } asmrp_get_sym (p); lprintf ("assignment done\n"); } static int asmrp_rule (asmrp_t *p) { int ret; lprintf ("rule\n"); ret = 1; if (p->sym == ASMRP_SYM_HASH) { asmrp_get_sym (p); ret = asmrp_condition (p); while (p->sym == ASMRP_SYM_COMMA) { asmrp_get_sym (p); asmrp_assignment (p); } } else if (p->sym != ASMRP_SYM_SEMICOLON) { asmrp_assignment (p); while (p->sym == ASMRP_SYM_COMMA) { asmrp_get_sym (p); asmrp_assignment (p); } } lprintf ("rule done = %d\n", ret); if (p->sym != ASMRP_SYM_SEMICOLON) { fprintf (stderr, "asmrp error: semicolon expected.\n"); //_x_abort (); return 0; } asmrp_get_sym (p); return ret; } static int asmrp_eval (asmrp_t *p, int *matches, int matchsize) { int rule_num, num_matches; lprintf ("eval\n"); asmrp_get_sym (p); rule_num = 0; num_matches = 0; while (p->sym != ASMRP_SYM_EOF && num_matches < matchsize - 1) { if (asmrp_rule (p)) { lprintf ("rule #%d is true\n", rule_num); matches[num_matches] = rule_num; num_matches++; } rule_num++; } matches[num_matches] = -1; return num_matches; } int asmrp_match (const char *rules, int bandwidth, int *matches, int matchsize) { asmrp_t *p; int num_matches; p = asmrp_new (); asmrp_init (p, rules); asmrp_set_id (p, "Bandwidth", bandwidth); asmrp_set_id (p, "OldPNMPlayer", 0); num_matches = asmrp_eval (p, matches, matchsize); asmrp_dispose (p); return num_matches; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_v4l2.c�����������������������������������������������������������������0000644�0001750�0001750�00000034731�14647725152�014774� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2010-2018 the xine project * Copyright (C) 2010 Trever Fischer <tdfischer@fedoraproject.org> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * v4l2 input plugin */ #define LOG_MODULE "v4l2" #ifdef HAVE_CONFIG_H #include "config.h" #endif /* #define LOG */ #include <xine/input_plugin.h> #include <xine/xine_plugin.h> #include <xine/xine_internal.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #ifdef HAVE_SYS_VIDEOIO_H # include <sys/videoio.h> #elif defined(HAVE_SYS_VIDEODEV2_H) # include <sys/videodev2.h> #else # include <linux/videodev2.h> #endif #include <sys/mman.h> #include <stdio.h> #include <errno.h> #ifdef HAVE_LIBV4L2_H # include <libv4l2.h> #else # include <unistd.h> # include <sys/ioctl.h> # define v4l2_open(f,d) open(f,d) # define v4l2_ioctl(f,c,a) ioctl(f,c,a) # define v4l2_mmap(p,l,d,m,f,o) mmap(p,l,d,m,f,o) # define v4l2_munmap(s,l) munmap(s,l) # define v4l2_close(f) close(f) #endif typedef struct { void *start; size_t length; } buffer_data; typedef struct { int width; int height; } resolution_t; typedef struct { buffer_data *buffers; int bufcount; resolution_t resolution; struct v4l2_buffer inbuf; off_t index; int headerSent; } v4l2_video_t; typedef struct { buffer_data *buffers; int bufcount; } v4l2_radio_t; typedef struct { input_plugin_t input_plugin; int fd; char* mrl; struct v4l2_capability cap; xine_stream_t *stream; xine_event_queue_t *events; v4l2_video_t* video; v4l2_radio_t* radio; } v4l2_input_plugin_t; static int v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx); static int v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *input); static int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this); static int v4l2_input_open(input_plugin_t *this_gen) { v4l2_input_plugin_t *this = (v4l2_input_plugin_t*) this_gen; int ret; lprintf("Opening %s\n", this->mrl); this->fd = v4l2_open(this->mrl, O_RDWR); if (this->fd) { /* TODO: Clean up this mess */ this->events = xine_event_new_queue(this->stream); ret = v4l2_ioctl(this->fd, VIDIOC_QUERYCAP, &(this->cap)); if (ret < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": capability query failed: %s\n", strerror (-ret)); return 0; } if (this->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { this->video = malloc(sizeof(v4l2_video_t)); this->video->headerSent = 0; this->video->bufcount = 0; } if (this->cap.capabilities & V4L2_CAP_STREAMING) { lprintf("Supports streaming. Allocating buffers...\n"); if (this->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) { if (v4l2_input_setup_video_streaming(this)) { lprintf("Video streaming ready.\n"); return 1; } else { /* TODO: Fallbacks */ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": video streaming setup failed\n"); return 0; } } else { /* TODO: Radio streaming */ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": sorry, only video is supported for now\n"); return 0; } } else { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": device doesn't support streaming - prod the author to support the other methods\n"); return 0; } } else { return 0; } } static int v4l2_input_setup_video_streaming(v4l2_input_plugin_t *this) { this->video->bufcount = 0; struct v4l2_requestbuffers reqbuf; unsigned int i; memset(&reqbuf, 0, sizeof(reqbuf)); reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_MMAP; reqbuf.count = 25; if (-1 == v4l2_ioctl(this->fd, VIDIOC_REQBUFS, &reqbuf)) { lprintf("Buffer request failed. Is streaming supported?\n"); return 0; } this->video->bufcount = reqbuf.count; lprintf("Got %i buffers for stremaing.\n", reqbuf.count); this->video->buffers = calloc(this->video->bufcount, sizeof(buffer_data)); _x_assert(this->video->buffers); for (i = 0; (int)i < this->video->bufcount; i++) { struct v4l2_buffer buffer; memset(&buffer, 0, sizeof(buffer)); buffer.type = reqbuf.type; buffer.memory = reqbuf.memory; buffer.index = i; if (-1 == v4l2_ioctl(this->fd, VIDIOC_QUERYBUF, &buffer)) { lprintf("Couldn't allocate buffer %i\n", i); return 0; } this->video->buffers[i].length = buffer.length; this->video->buffers[i].start = (void*)v4l2_mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, this->fd, buffer.m.offset); if (MAP_FAILED == this->video->buffers[i].start) { lprintf("Couldn't mmap buffer %i\n", i); unsigned int j; for(j = 0;j<i;j++) { v4l2_munmap(this->video->buffers[i].start, this->video->buffers[i].length); } free(this->video->buffers); this->video->bufcount = 0; return 0; } if (v4l2_input_enqueue_video_buffer(this, i) < 0) goto fail; } struct v4l2_format fmt; memset(&fmt, 0, sizeof(fmt)); fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* TODO: Other formats? MPEG support? */ fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; if (-1 == v4l2_ioctl(this->fd, VIDIOC_S_FMT, &fmt)) goto fail; this->video->resolution.width = fmt.fmt.pix.width; this->video->resolution.height = fmt.fmt.pix.height; if (-1 == v4l2_ioctl(this->fd, VIDIOC_STREAMON, &reqbuf.type)) goto fail; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); return 1; fail: lprintf("Couldn't start streaming: %s\n", strerror(errno)); return 0; } static buf_element_t* v4l2_input_read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t len) { lprintf("Reading block\n"); v4l2_input_plugin_t *this = (v4l2_input_plugin_t*)this_gen; (void)len; buf_element_t *buf = fifo->buffer_pool_alloc(fifo); if (!this->video->headerSent) { struct timeval tv; xine_monotonic_clock(&tv, NULL); buf->pts = (int64_t) tv.tv_sec * 90000 + (int64_t) tv.tv_usec * 9 / 100; lprintf("Sending video header\n"); xine_bmiheader bih; memset(&bih, 0, sizeof(bih)); bih.biSize = sizeof(xine_bmiheader); /* HACK: Why do I need to do this and why is it magic? */ bih.biWidth = this->video->resolution.width*2; bih.biHeight = this->video->resolution.height*2; lprintf("Getting size of %ix%i\n", this->video->resolution.width, this->video->resolution.height); buf->size = sizeof(xine_bmiheader); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_START; memcpy(buf->content, &bih, sizeof(xine_bmiheader)); this->video->headerSent = 1; this->video->index = 0; buf->type = BUF_VIDEO_YUY2; } else { lprintf("Sending video frame (sent %zd of %zd)\n", this->video->index, this->video->buffers[this->video->inbuf.index].length); /* TODO: Add audio support */ this->video->headerSent = v4l2_input_dequeue_video_buffer(this, buf); if (this->video->headerSent < 0) { buf->free_buffer (buf); buf = NULL; } } return buf; } static uint32_t v4l2_input_blocksize(input_plugin_t *this_gen) { /* HACK */ #if 0 v4l2_input_plugin_t *this = (v4l2_input_plugin_t*)this_gen; if (this->video->headerSent) { lprintf("Returning block size of %zu\n",this->video->buffers[0].length); return this->video->buffers[0].length; } else { lprintf("Returning block size of %zu\n",sizeof(xine_bmiheader)); return sizeof(xine_bmiheader); } #else (void)this_gen; return 0; #endif } static int v4l2_input_dequeue_video_buffer(v4l2_input_plugin_t *this, buf_element_t *output) { int ret; if (!this->video->index) { memset (&this->video->inbuf, 0, sizeof (this->video->inbuf)); this->video->inbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; this->video->inbuf.memory = V4L2_MEMORY_MMAP; ret = v4l2_ioctl(this->fd, VIDIOC_DQBUF, &this->video->inbuf); if (ret < 0) return -1; /* failure */ output->decoder_flags = BUF_FLAG_FRAME_START; } else output->decoder_flags = 0; output->content = output->mem; output->type = BUF_VIDEO_YUY2; output->size = this->video->buffers[this->video->inbuf.index].length - this->video->index; if (output->size > output->max_size) output->size = output->max_size; xine_fast_memcpy (output->content, (char *)this->video->buffers[this->video->inbuf.index].start + this->video->index, output->size); this->video->index += output->size; if (this->video->index == (off_t)this->video->buffers[this->video->inbuf.index].length) { output->decoder_flags |= BUF_FLAG_FRAME_END; ret = v4l2_input_enqueue_video_buffer(this, this->video->inbuf.index); return -(ret < 0); } return 1; } static int v4l2_input_enqueue_video_buffer(v4l2_input_plugin_t *this, int idx) { struct v4l2_buffer buf; memset(&buf, 0, sizeof(buf)); buf.index = idx; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; return v4l2_ioctl(this->fd, VIDIOC_QBUF, &buf); } static void v4l2_input_dispose(input_plugin_t *this_gen) { lprintf("Disposing of myself.\n"); v4l2_input_plugin_t* this = (v4l2_input_plugin_t*)this_gen; if (this->video != NULL) { int type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (-1 == v4l2_ioctl(this->fd, VIDIOC_STREAMOFF, &type)) { lprintf("Couldn't stop streaming. Uh oh.\n"); } if (this->video->bufcount > 0) { int i; for(i = 0;i<this->video->bufcount;i++) { v4l2_munmap(this->video->buffers[i].start, this->video->buffers[i].length); } free(this->video->buffers); } free(this->video); } v4l2_close(this->fd); free(this->mrl); free(this); } static off_t v4l2_input_read(input_plugin_t *this_gen, void *buf, off_t nlen) { /* Only block reads are supported. */ (void)this_gen; (void)buf; (void)nlen; return 0; } static uint32_t v4l2_input_get_capabilities(input_plugin_t* this_gen) { (void)this_gen; return INPUT_CAP_BLOCK; } static const char* v4l2_input_get_mrl(input_plugin_t* this_gen) { /*v4l2_input_plugin_t* this = (v4l2_input_plugin_t*)this_gen;*/ (void)this_gen; /* HACK HACK HACK HACK */ /* So far, the only way to get the yuv_frames demuxer to work with this */ return "v4l:/"; //return this->mrl; } static int v4l2_input_get_optional_data(input_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return INPUT_OPTIONAL_UNSUPPORTED; } /* Seeking not supported. */ static off_t v4l2_input_seek(input_plugin_t *this_gen, off_t offset, int origin) { (void)this_gen; (void)offset; (void)origin; return -1; } static off_t v4l2_input_pos(input_plugin_t *this_gen) { /* TODO */ (void)this_gen; return 0; } static off_t v4l2_input_length(input_plugin_t *this_gen) { (void)this_gen; return -1; } static input_plugin_t *v4l2_class_get_instance(input_class_t *gen_cls, xine_stream_t *stream, const char *mrl) { v4l2_input_plugin_t *this; if (strncasecmp (mrl, "v4l2:/", 6)) return NULL; mrl += 5; while (*++mrl == '/') /**/; --mrl; /* point at the last slash */ /* TODO: Radio devices */ /* FIXME: Don't require devices to be of /dev/videoXXX */ if (strncmp(mrl, "/dev/video", 10) != 0) return NULL; lprintf("We can handle %s!\n", mrl); this = calloc(1, sizeof(v4l2_input_plugin_t)); if (!this) return NULL; this->mrl = strdup(mrl); this->input_plugin.open = v4l2_input_open; this->input_plugin.get_capabilities = v4l2_input_get_capabilities; this->input_plugin.get_blocksize = v4l2_input_blocksize; this->input_plugin.get_mrl = v4l2_input_get_mrl; this->input_plugin.dispose = v4l2_input_dispose; this->input_plugin.read = v4l2_input_read; this->input_plugin.read_block = v4l2_input_read_block; this->input_plugin.seek = v4l2_input_seek; this->input_plugin.seek_time = NULL; this->input_plugin.get_current_pos = v4l2_input_pos; this->input_plugin.get_current_time = NULL; this->input_plugin.get_length = v4l2_input_length; this->input_plugin.get_optional_data = v4l2_input_get_optional_data; this->input_plugin.input_class = gen_cls; this->stream = stream; this->video = NULL; this->radio = NULL; lprintf("Ready to read!\n"); xprintf (this->stream->xine, XINE_VERBOSITY_NONE, LOG_MODULE": WARNING: this plugin is not of release quality\n"); return &this->input_plugin; } static void *v4l2_init_class(xine_t *xine, const void *data) { (void)xine; (void)data; static const input_class_t v4l2_input_class = { .get_instance = v4l2_class_get_instance, .description = N_("v4l2 input plugin"), .identifier = "v4l2", .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; return (void *)&v4l2_input_class; } const input_info_t input_info_v4l2 = { 4000 }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 18, "v4l2", XINE_VERSION_CODE, &input_info_v4l2, v4l2_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������xine-lib-1.2/src/input/libdvdnav/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014563� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvd_reader.h�������������������������������������������������������0000644�0001750�0001750�00000022753�14647725152�017044� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DVD_READER_H_INCLUDED #define DVD_READER_H_INCLUDED /* * Copyright (C) 2001, 2002 Billy Biggs <vektor@dumbterm.net>, * Håkan Hjort <d95hjort@dtek.chalmers.se>, * Björn Englund <d4bjorn@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef _MSC_VER #include <stdio.h> #include <stdlib.h> #endif #include <sys/types.h> #include <inttypes.h> /** * The DVD access interface. * * This file contains the functions that form the interface to to * reading files located on a DVD. */ /** * The current version. */ #define DVDREAD_VERSION 904 /** * The length of one Logical Block of a DVD. */ #define DVD_VIDEO_LB_LEN 2048 /** * Maximum length of filenames allowed in UDF. */ #define MAX_UDF_FILE_NAME_LEN 2048 #ifdef __cplusplus extern "C" { #endif /** * Opaque type that is used as a handle for one instance of an opened DVD. */ typedef struct dvd_reader_s dvd_reader_t; /** * Opaque type for a file read handle, much like a normal fd or FILE *. */ typedef struct dvd_file_s dvd_file_t; /** * Opens a block device of a DVD-ROM file, or an image file, or a directory * name for a mounted DVD or HD copy of a DVD. * * If the given file is a block device, or is the mountpoint for a block * device, then that device is used for CSS authentication using libdvdcss. * If no device is available, then no CSS authentication is performed, * and we hope that the image is decrypted. * * If the path given is a directory, then the files in that directory may be * in any one of these formats: * * path/VIDEO_TS/VTS_01_1.VOB * path/video_ts/vts_01_1.vob * path/VTS_01_1.VOB * path/vts_01_1.vob * * @param path Specifies the the device, file or directory to be used. * @return If successful a a read handle is returned. Otherwise 0 is returned. * * dvd = DVDOpen(path); */ dvd_reader_t *DVDOpen( const char * ); /** * Closes and cleans up the DVD reader object. * * You must close all open files before calling this function. * * @param dvd A read handle that should be closed. * * DVDClose(dvd); */ void DVDClose( dvd_reader_t * ); /** * */ typedef enum { DVD_READ_INFO_FILE, /**< VIDEO_TS.IFO or VTS_XX_0.IFO (title) */ DVD_READ_INFO_BACKUP_FILE, /**< VIDEO_TS.BUP or VTS_XX_0.BUP (title) */ DVD_READ_MENU_VOBS, /**< VIDEO_TS.VOB or VTS_XX_0.VOB (title) */ DVD_READ_TITLE_VOBS /**< VTS_XX_[1-9].VOB (title). All files in the title set are opened and read as a single file. */ } dvd_read_domain_t; /** * Opens a file on the DVD given the title number and domain. * * If the title number is 0, the video manager information is opened * (VIDEO_TS.[IFO,BUP,VOB]). Returns a file structure which may be * used for reads, or 0 if the file was not found. * * @param dvd A dvd read handle. * @param titlenum Which Video Title Set should be used, VIDEO_TS is 0. * @param domain Which domain. * @return If successful a a file read handle is returned, otherwise 0. * * dvd_file = DVDOpenFile(dvd, titlenum, domain); */ dvd_file_t *DVDOpenFile( dvd_reader_t *, int, dvd_read_domain_t ); /** * Closes a file and frees the associated structure. * * @param dvd_file The file read handle to be closed. * * DVDCloseFile(dvd_file); */ void DVDCloseFile( dvd_file_t * ); /** * Reads block_count number of blocks from the file at the given block offset. * Returns number of blocks read on success, -1 on error. This call is only * for reading VOB data, and should not be used when reading the IFO files. * When reading from an encrypted drive, blocks are decrypted using libdvdcss * where required. * * @param dvd_file A file read handle. * @param offset Block offset from the start of the file to start reading at. * @param block_count Number of block to read. * @param data Pointer to a buffer to write the data into. * @return Returns number of blocks read on success, -1 on error. * * blocks_read = DVDReadBlocks(dvd_file, offset, block_count, data); */ ssize_t DVDReadBlocks( dvd_file_t *, int, size_t, unsigned char * ); /** * Seek to the given position in the file. Returns the resulting position in * bytes from the beginning of the file. The seek position is only used for * byte reads from the file, the block read call always reads from the given * offset. * * @param dvd_file A file read handle. * @param seek_offset Byte offset from the start of the file to seek to. * @return The resulting position in bytes from the beginning of the file. * * offset_set = DVDFileSeek(dvd_file, seek_offset); */ int32_t DVDFileSeek( dvd_file_t *, int32_t ); int32_t DVDFileSeekForce( dvd_file_t *, int, int ); /** * Reads the given number of bytes from the file. This call can only be used * on the information files, and may not be used for reading from a VOB. This * reads from and increments the currrent seek position for the file. * * @param dvd_file A file read handle. * @param data Pointer to a buffer to write the data into. * @param bytes Number of bytes to read. * @return Returns number of bytes read on success, -1 on error. * * bytes_read = DVDReadBytes(dvd_file, data, bytes); */ ssize_t DVDReadBytes( dvd_file_t *, void *, size_t ); /** * Returns the file size in blocks. * * @param dvd_file A file read handle. * @return The size of the file in blocks, -1 on error. * * blocks = DVDFileSize(dvd_file); */ ssize_t DVDFileSize( dvd_file_t * ); /** * Get a unique 128 bit disc ID. * This is the MD5 sum of VIDEO_TS.IFO and the VTS_0?_0.IFO files * in title order (those that exist). * If you need a 'text' representation of the id, print it as a * hexadecimal number, using lowercase letters, discid[0] first. * I.e. the same format as the command-line 'md5sum' program uses. * * @param dvd A read handle to get the disc ID from * @param discid The buffer to put the disc ID into. The buffer must * have room for 128 bits (16 chars). * @return 0 on success, -1 on error. */ int DVDDiscID( dvd_reader_t *, unsigned char * ); /** * Get the UDF VolumeIdentifier and VolumeSetIdentifier * from the PrimaryVolumeDescriptor. * * @param dvd A read handle to get the disc ID from * @param volid The buffer to put the VolumeIdentifier into. * The VolumeIdentifier is latin-1 encoded (8bit unicode) * null terminated and max 32 bytes (including '\0') * @param volid_size No more than volid_size bytes will be copied to volid. * If the VolumeIdentifier is truncated because of this * it will still be null terminated. * @param volsetid The buffer to put the VolumeSetIdentifier into. * The VolumeIdentifier is 128 bytes as * stored in the UDF PrimaryVolumeDescriptor. * Note that this is not a null terminated string. * @param volsetid_size At most volsetid_size bytes will be copied to volsetid. * @return 0 on success, -1 on error. */ int DVDUDFVolumeInfo( dvd_reader_t *, char *, unsigned int, unsigned char *, unsigned int ); /** * Get the ISO9660 VolumeIdentifier and VolumeSetIdentifier * * * Only use this function as fallback if DVDUDFVolumeInfo returns 0 * * * this will happen on a disc mastered only with a iso9660 filesystem * * * All video DVD discs have UDF filesystem * * * @param dvd A read handle to get the disc ID from * @param volid The buffer to put the VolumeIdentifier into. * The VolumeIdentifier is coded with '0-9','A-Z','_' * null terminated and max 33 bytes (including '\0') * @param volid_size No more than volid_size bytes will be copied to volid. * If the VolumeIdentifier is truncated because of this * it will still be null terminated. * @param volsetid The buffer to put the VolumeSetIdentifier into. * The VolumeIdentifier is 128 bytes as * stored in the ISO9660 PrimaryVolumeDescriptor. * Note that this is not a null terminated string. * @param volsetid_size At most volsetid_size bytes will be copied to volsetid. * @return 0 on success, -1 on error. */ int DVDISOVolumeInfo( dvd_reader_t *, char *, unsigned int, unsigned char *, unsigned int ); /** * Sets the level of caching that is done when reading from a device * * @param dvd A read handle to get the disc ID from * @param level The level of caching wanted. * -1 - returns the current setting. * 0 - UDF Cache turned off. * 1 - (default level) Pointers to IFO files and some data from * PrimaryVolumeDescriptor are cached. * * @return The level of caching. */ int DVDUDFCacheLevel( dvd_reader_t *, int ); #ifdef __cplusplus }; #endif #endif /* DVD_READER_H_INCLUDED */ ���������������������xine-lib-1.2/src/input/libdvdnav/dvd_input.h��������������������������������������������������������0000644�0001750�0001750�00000003274�14647725152�016736� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DVD_INPUT_H_INCLUDED #define DVD_INPUT_H_INCLUDED /* * Copyright (C) 2001, 2002 Samuel Hocevar <sam@zoy.org>, * Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ /** * Defines and flags. Make sure they fit the libdvdcss API! */ #define DVDINPUT_NOFLAGS 0 #define DVDINPUT_READ_DECRYPT (1 << 0) typedef struct dvd_input_s *dvd_input_t; /** * Pointers which will be filled either the input methods functions. */ extern dvd_input_t (*dvdinput_open) (const char *); extern int (*dvdinput_close) (dvd_input_t); extern int (*dvdinput_seek) (dvd_input_t, int); extern int (*dvdinput_title) (dvd_input_t, int); extern int (*dvdinput_read) (dvd_input_t, void *, int, int); extern char * (*dvdinput_error) (dvd_input_t); extern int (*dvdinput_is_encrypted) (dvd_input_t); /** * Setup function accessed by dvd_reader.c. Returns 1 if there is CSS support. */ int dvdinput_setup(void); #endif /* DVD_INPUT_H_INCLUDED */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/vm.h���������������������������������������������������������������0000644�0001750�0001750�00000013140�14647725152�015355� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001 Håkan Hjort * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. It is modified * from a file originally part of the Ogle DVD player. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef VM_H_INCLUDED #define VM_H_INCLUDED #include "remap.h" #include "dvdnav_internal.h" /* DOMAIN enum */ typedef enum { FP_DOMAIN = 1, VTS_DOMAIN = 2, VMGM_DOMAIN = 4, VTSM_DOMAIN = 8 } domain_t; /** * State: SPRM, GPRM, Domain, pgc, pgN, cellN, ? */ typedef struct { registers_t registers; domain_t domain; int vtsN; /* 0 is vmgm? */ pgc_t *pgc; /* either this or 'int pgcN' is enough? */ int pgcN; /* but provide pgcN for quick lookup */ int pgN; /* is this needed? can allways fid pgN from cellN? */ int cellN; int32_t cell_restart; /* get cell to restart */ int blockN; /* Resume info */ int rsm_vtsN; int rsm_blockN; /* of nav_packet */ uint16_t rsm_regs[5]; /* system registers 4-8 */ int rsm_pgcN; int rsm_cellN; } dvd_state_t; typedef struct vm_position_s { int16_t button; /* Button highlighted */ int32_t vts; /* vts number to use */ domain_t domain; /* domain to use */ int32_t spu_channel; /* spu channel to use */ int32_t angle_channel; /* angle channel to use */ int32_t audio_channel; /* audio channel to use */ int32_t hop_channel; /* channel hopping. E.g menu button pressed */ #if 0 /* currently unused */ int32_t title; /* title number */ int32_t chapter; /* chapter number */ #endif int32_t cell; /* cell number */ int32_t cell_restart; /* get cell to restart */ int32_t cell_start; /* sector number of start of current cell in use */ int32_t still; /* is cell still */ int32_t block; /* block number within cell in use */ } vm_position_t; typedef struct { dvd_reader_t *dvd; ifo_handle_t *vmgi; ifo_handle_t *vtsi; dvd_state_t state; int32_t hop_channel; char dvd_name[50]; remap_t *map; int stopped; } vm_t; /* magic number for seeking hops */ #define HOP_SEEK 0x1000 /* Audio stream number */ #define AST_REG registers.SPRM[1] /* Subpicture stream number */ #define SPST_REG registers.SPRM[2] /* Angle number */ #define AGL_REG registers.SPRM[3] /* Title Track Number */ #define TTN_REG registers.SPRM[4] /* VTS Title Track Number */ #define VTS_TTN_REG registers.SPRM[5] /* PGC Number for this Title Track */ #define TT_PGCN_REG registers.SPRM[6] /* Current Part of Title (PTT) number for (One_Sequential_PGC_Title) */ #define PTTN_REG registers.SPRM[7] /* Highlighted Button Number (btn nr 1 == value 1024) */ #define HL_BTNN_REG registers.SPRM[8] /* Parental Level */ #define PTL_REG registers.SPRM[13] /* Initialisation & destruction */ vm_t *vm_new_vm(void); void vm_free_vm(vm_t *vm); /* IFO access */ ifo_handle_t *vm_get_vmgi(vm_t *vm); ifo_handle_t *vm_get_vtsi(vm_t *vm); /* Reader Access */ dvd_reader_t *vm_get_dvd_reader(vm_t *vm); /* Basic Handling */ int vm_start(vm_t *vm); void vm_stop(vm_t *vm); int vm_reset(vm_t *vm, const char *dvdroot); /* copying and merging - useful for try-running an operation */ vm_t *vm_new_copy(vm_t *vm); void vm_merge(vm_t *target, vm_t *source); void vm_free_copy(vm_t *vm); /* regular playback */ void vm_position_get(vm_t *vm, vm_position_t *position); void vm_get_next_cell(vm_t *vm); /* Jumping - all these return 1, if a hop has been performed */ int vm_jump_pg(vm_t *vm, int pg); int vm_jump_cell_block(vm_t *vm, int cell, int block); int vm_jump_title_part(vm_t *vm, int title, int part); int vm_jump_top_pg(vm_t *vm); int vm_jump_next_pg(vm_t *vm); int vm_jump_prev_pg(vm_t *vm); int vm_jump_up(vm_t *vm); int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid); int vm_jump_resume(vm_t *vm); int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd); /* getting information */ int vm_get_current_menu(vm_t *vm, int *menuid); int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result); int vm_get_audio_stream(vm_t *vm, int audioN); int vm_get_subp_stream(vm_t *vm, int subpN, int mode); int vm_get_audio_active_stream(vm_t *vm); int vm_get_subp_active_stream(vm_t *vm, int mode); void vm_get_angle_info(vm_t *vm, int *current, int *num_avail); #if 0 /* currently unused */ void vm_get_audio_info(vm_t *vm, int *current, int *num_avail); void vm_get_subp_info(vm_t *vm, int *current, int *num_avail); void vm_get_video_res(vm_t *vm, int *width, int *height); #endif int vm_get_video_aspect(vm_t *vm); int vm_get_video_scale_permission(vm_t *vm); video_attr_t vm_get_video_attr(vm_t *vm); audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN); subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN); #ifdef TRACE /* Debug */ void vm_position_print(vm_t *vm, vm_position_t *position); #endif #endif /* VM_HV_INCLUDED */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/vmcmd.h������������������������������������������������������������0000644�0001750�0001750�00000002122�14647725152�016037� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort * * This file is part of libdvdnav, a DVD navigation library. It is modified * from a file originally part of the Ogle DVD player. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef VMCMD_H_INCLUDED #define VMCMD_H_INCLUDED #include <inttypes.h> void vm_print_mnemonic(vm_cmd_t *command); void vm_print_cmd(int row, vm_cmd_t *command); #endif /* VMCMD_H_INCLUDED */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/read_cache.h�������������������������������������������������������0000644�0001750�0001750�00000003623�14647725152�016776� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef __DVDNAV_READ_CACHE_H #define __DVDNAV_READ_CACHE_H #include "dvdnav_internal.h" /* Opaque cache type -- defined in dvdnav_internal.h */ /* typedef struct read_cache_s read_cache_t; */ /* EXPERIMENTAL: Setting the following to 1 will use an experimental multi-threaded * read-ahead cache. */ #define _MULTITHREAD_ 0 /* Constructor/destructors */ read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self); void dvdnav_read_cache_free(read_cache_t* self); /* This function MUST be called whenever self->file changes. */ void dvdnav_read_cache_clear(read_cache_t *self); /* This function is called just after reading the NAV packet. */ void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count); /* This function will do the cache read. * The buffer handed in must be malloced to take one dvd block. * On a cache hit, a different buffer will be returned though. * Those buffers must _never_ be freed. */ int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf); #endif /* __DVDNAV_READ_CACHE_H */ �������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvd_udf.c����������������������������������������������������������0000644�0001750�0001750�00000063365�14647725152�016357� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * This code is based on dvdudf by: * Christian Wolff <scarabaeus@convergence.de>. * * Modifications by: * Billy Biggs <vektor@dumbterm.net>. * Björn Englund <d4bjorn@dtek.chalmers.se>. * * dvdudf: parse and read the UDF volume information of a DVD Video * Copyright (C) 1999 Christian Wolff for convergence integrated media * GmbH The author can be reached at scarabaeus@convergence.de, the * project's page is at http://linuxtv.org/dvd/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. Or, point your browser to * http://www.gnu.org/copyleft/gpl.html */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> #include <inttypes.h> #include "dvd_reader.h" #include "dvd_udf.h" /* Private but located in/shared with dvd_reader.c */ extern int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number, size_t block_count, unsigned char *data, int encrypted ); /* It's required to either fail or deliver all the blocks asked for. */ static int DVDReadLBUDF( dvd_reader_t *device, uint32_t lb_number, size_t block_count, unsigned char *data, int encrypted ) { int ret; size_t count = block_count; while(count > 0) { ret = UDFReadBlocksRaw(device, lb_number, count, data, encrypted); if(ret <= 0) { /* One of the reads failed or nothing more to read, too bad. * We won't even bother returning the reads that went ok. */ return ret; } count -= (size_t)ret; lb_number += (uint32_t)ret; } return block_count; } #ifndef NULL #define NULL ((void *)0) #endif struct Partition { int valid; char VolumeDesc[128]; uint16_t Flags; uint16_t Number; char Contents[32]; uint32_t AccessType; uint32_t Start; uint32_t Length; }; struct AD { uint32_t Location; uint32_t Length; uint8_t Flags; uint16_t Partition; }; struct extent_ad { uint32_t location; uint32_t length; }; struct avdp_t { struct extent_ad mvds; struct extent_ad rvds; }; struct pvd_t { uint8_t VolumeIdentifier[32]; uint8_t VolumeSetIdentifier[128]; }; struct lbudf { uint32_t lb; uint8_t *data; }; struct icbmap { uint32_t lbn; struct AD file; uint8_t filetype; }; struct udf_cache { int avdp_valid; struct avdp_t avdp; int pvd_valid; struct pvd_t pvd; int partition_valid; struct Partition partition; int rooticb_valid; struct AD rooticb; int lb_num; struct lbudf *lbs; int map_num; struct icbmap *maps; }; typedef enum { PartitionCache, RootICBCache, LBUDFCache, MapCache, AVDPCache, PVDCache } UDFCacheType; void FreeUDFCache(void *cache) { struct udf_cache *c = (struct udf_cache *)cache; if(c == NULL) { return; } if(c->lbs) { free(c->lbs); } if(c->maps) { free(c->maps); } free(c); } static int GetUDFCache(dvd_reader_t *device, UDFCacheType type, uint32_t nr, void *data) { int n; struct udf_cache *c; if(DVDUDFCacheLevel(device, -1) <= 0) { return 0; } c = (struct udf_cache *)GetUDFCacheHandle(device); if(c == NULL) { return 0; } switch(type) { case AVDPCache: if(c->avdp_valid) { *(struct avdp_t *)data = c->avdp; return 1; } break; case PVDCache: if(c->pvd_valid) { *(struct pvd_t *)data = c->pvd; return 1; } break; case PartitionCache: if(c->partition_valid) { *(struct Partition *)data = c->partition; return 1; } break; case RootICBCache: if(c->rooticb_valid) { *(struct AD *)data = c->rooticb; return 1; } break; case LBUDFCache: for(n = 0; n < c->lb_num; n++) { if(c->lbs[n].lb == nr) { *(uint8_t **)data = c->lbs[n].data; return 1; } } break; case MapCache: for(n = 0; n < c->map_num; n++) { if(c->maps[n].lbn == nr) { *(struct icbmap *)data = c->maps[n]; return 1; } } break; default: break; } return 0; } static int SetUDFCache(dvd_reader_t *device, UDFCacheType type, uint32_t nr, void *data) { int n; struct udf_cache *c; if(DVDUDFCacheLevel(device, -1) <= 0) { return 0; } c = (struct udf_cache *)GetUDFCacheHandle(device); if(c == NULL) { c = calloc(1, sizeof(struct udf_cache)); /* fprintf(stderr, "calloc: %d\n", sizeof(struct udf_cache)); */ if(c == NULL) { return 0; } SetUDFCacheHandle(device, c); } switch(type) { case AVDPCache: c->avdp = *(struct avdp_t *)data; c->avdp_valid = 1; break; case PVDCache: c->pvd = *(struct pvd_t *)data; c->pvd_valid = 1; break; case PartitionCache: c->partition = *(struct Partition *)data; c->partition_valid = 1; break; case RootICBCache: c->rooticb = *(struct AD *)data; c->rooticb_valid = 1; break; case LBUDFCache: for(n = 0; n < c->lb_num; n++) { if(c->lbs[n].lb == nr) { /* replace with new data */ c->lbs[n].data = *(uint8_t **)data; c->lbs[n].lb = nr; return 1; } } c->lb_num++; c->lbs = realloc(c->lbs, c->lb_num * sizeof(struct lbudf)); /* fprintf(stderr, "realloc lb: %d * %d = %d\n", c->lb_num, sizeof(struct lbudf), c->lb_num * sizeof(struct lbudf)); */ if(c->lbs == NULL) { c->lb_num = 0; return 0; } c->lbs[n].data = *(uint8_t **)data; c->lbs[n].lb = nr; break; case MapCache: for(n = 0; n < c->map_num; n++) { if(c->maps[n].lbn == nr) { /* replace with new data */ c->maps[n] = *(struct icbmap *)data; c->maps[n].lbn = nr; return 1; } } c->map_num++; c->maps = realloc(c->maps, c->map_num * sizeof(struct icbmap)); /* fprintf(stderr, "realloc maps: %d * %d = %d\n", c->map_num, sizeof(struct icbmap), c->map_num * sizeof(struct icbmap)); */ if(c->maps == NULL) { c->map_num = 0; return 0; } c->maps[n] = *(struct icbmap *)data; c->maps[n].lbn = nr; break; default: return 0; } return 1; } /* For direct data access, LSB first */ #define GETN1(p) ((uint8_t)data[p]) #define GETN2(p) ((uint16_t)data[p] | ((uint16_t)data[(p) + 1] << 8)) #define GETN3(p) ((uint32_t)data[p] | ((uint32_t)data[(p) + 1] << 8) \ | ((uint32_t)data[(p) + 2] << 16)) #define GETN4(p) ((uint32_t)data[p] \ | ((uint32_t)data[(p) + 1] << 8) \ | ((uint32_t)data[(p) + 2] << 16) \ | ((uint32_t)data[(p) + 3] << 24)) /* This is wrong with regard to endianess */ #define GETN(p, n, target) memcpy(target, &data[p], n) static int Unicodedecode( uint8_t *data, int len, char *target ) { int p = 1, i = 0; if( ( data[ 0 ] == 8 ) || ( data[ 0 ] == 16 ) ) do { if( data[ 0 ] == 16 ) p++; /* Ignore MSB of unicode16 */ if( p < len ) { target[ i++ ] = data[ p++ ]; } } while( p < len ); target[ i ] = '\0'; return 0; } static int UDFDescriptor( uint8_t *data, uint16_t *TagID ) { *TagID = GETN2(0); /* TODO: check CRC 'n stuff */ return 0; } static int UDFExtentAD( uint8_t *data, uint32_t *Length, uint32_t *Location ) { *Length = GETN4(0); *Location = GETN4(4); return 0; } static int UDFShortAD( uint8_t *data, struct AD *ad, struct Partition *partition ) { ad->Length = GETN4(0); ad->Flags = ad->Length >> 30; ad->Length &= 0x3FFFFFFF; ad->Location = GETN4(4); ad->Partition = partition->Number; /* use number of current partition */ return 0; } static int UDFLongAD( uint8_t *data, struct AD *ad ) { ad->Length = GETN4(0); ad->Flags = ad->Length >> 30; ad->Length &= 0x3FFFFFFF; ad->Location = GETN4(4); ad->Partition = GETN2(8); /* GETN(10, 6, Use); */ return 0; } static int UDFExtAD( uint8_t *data, struct AD *ad ) { ad->Length = GETN4(0); ad->Flags = ad->Length >> 30; ad->Length &= 0x3FFFFFFF; ad->Location = GETN4(12); ad->Partition = GETN2(16); /* GETN(10, 6, Use); */ return 0; } static int UDFICB( uint8_t *data, uint8_t *FileType, uint16_t *Flags ) { *FileType = GETN1(11); *Flags = GETN2(18); return 0; } static int UDFPartition( uint8_t *data, uint16_t *Flags, uint16_t *Number, char *Contents, uint32_t *Start, uint32_t *Length ) { *Flags = GETN2(20); *Number = GETN2(22); GETN(24, 32, Contents); *Start = GETN4(188); *Length = GETN4(192); return 0; } /** * Reads the volume descriptor and checks the parameters. Returns 0 on OK, 1 * on error. */ static int UDFLogVolume( uint8_t *data, char *VolumeDescriptor ) { uint32_t lbsize; #if 0 uint32_t MT_L, N_PM; #endif Unicodedecode(&data[84], 128, VolumeDescriptor); lbsize = GETN4(212); /* should be 2048 */ #if 0 MT_L = GETN4(264); /* should be 6 */ N_PM = GETN4(268); /* should be 1 */ #endif if (lbsize != DVD_VIDEO_LB_LEN) return 1; return 0; } static int UDFFileEntry( uint8_t *data, uint8_t *FileType, struct Partition *partition, struct AD *ad ) { uint16_t flags; uint32_t L_EA, L_AD; unsigned int p; UDFICB( &data[ 16 ], FileType, &flags ); /* Init ad for an empty file (i.e. there isn't a AD, L_AD == 0 ) */ ad->Length = GETN4( 60 ); /* Really 8 bytes a 56 */ ad->Flags = 0; ad->Location = 0; /* what should we put here? */ ad->Partition = partition->Number; /* use number of current partition */ L_EA = GETN4( 168 ); L_AD = GETN4( 172 ); p = 176 + L_EA; while( p < 176 + L_EA + L_AD ) { switch( flags & 0x0007 ) { case 0: UDFShortAD( &data[ p ], ad, partition ); p += 8; break; case 1: UDFLongAD( &data[ p ], ad ); p += 16; break; case 2: UDFExtAD( &data[ p ], ad ); p += 20; break; case 3: switch( L_AD ) { case 8: UDFShortAD( &data[ p ], ad, partition ); break; case 16: UDFLongAD( &data[ p ], ad ); break; case 20: UDFExtAD( &data[ p ], ad ); break; } p += L_AD; break; default: p += L_AD; break; } } return 0; } static int UDFFileIdentifier( uint8_t *data, uint8_t *FileCharacteristics, char *FileName, struct AD *FileICB ) { uint8_t L_FI; uint16_t L_IU; *FileCharacteristics = GETN1(18); L_FI = GETN1(19); UDFLongAD(&data[20], FileICB); L_IU = GETN2(36); if (L_FI) Unicodedecode(&data[38 + L_IU], L_FI, FileName); else FileName[0] = '\0'; return 4 * ((38 + L_FI + L_IU + 3) / 4); } /** * Maps ICB to FileAD * ICB: Location of ICB of directory to scan * FileType: Type of the file * File: Location of file the ICB is pointing to * return 1 on success, 0 on error; */ static int UDFMapICB( dvd_reader_t *device, struct AD ICB, uint8_t *FileType, struct Partition *partition, struct AD *File ) { uint8_t LogBlock_base[DVD_VIDEO_LB_LEN + 2048]; uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum; uint16_t TagID; struct icbmap tmpmap; lbnum = partition->Start + ICB.Location; tmpmap.lbn = lbnum; if(GetUDFCache(device, MapCache, lbnum, &tmpmap)) { *FileType = tmpmap.filetype; *File = tmpmap.file; return 1; } do { if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) { TagID = 0; } else { UDFDescriptor( LogBlock, &TagID ); } if( TagID == 261 ) { UDFFileEntry( LogBlock, FileType, partition, File ); tmpmap.file = *File; tmpmap.filetype = *FileType; SetUDFCache(device, MapCache, tmpmap.lbn, &tmpmap); return 1; }; } while( ( lbnum <= partition->Start + ICB.Location + ( ICB.Length - 1 ) / DVD_VIDEO_LB_LEN ) && ( TagID != 261 ) ); return 0; } /** * Dir: Location of directory to scan * FileName: Name of file to look for * FileICB: Location of ICB of the found file * return 1 on success, 0 on error; */ static int UDFScanDir( dvd_reader_t *device, struct AD Dir, char *FileName, struct Partition *partition, struct AD *FileICB, int cache_file_info) { char filename[ MAX_UDF_FILE_NAME_LEN ]; uint8_t directory_base[ 2 * DVD_VIDEO_LB_LEN + 2048]; uint8_t *directory = (uint8_t *)(((uintptr_t)directory_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum; uint16_t TagID; uint8_t filechar; unsigned int p; uint8_t *cached_dir_base = NULL, *cached_dir; uint32_t dir_lba; struct AD tmpICB; int found = 0; int in_cache = 0; /* Scan dir for ICB of file */ lbnum = partition->Start + Dir.Location; if(DVDUDFCacheLevel(device, -1) > 0) { /* caching */ if(!GetUDFCache(device, LBUDFCache, lbnum, &cached_dir)) { dir_lba = (Dir.Length + DVD_VIDEO_LB_LEN) / DVD_VIDEO_LB_LEN; if((cached_dir_base = malloc(dir_lba * DVD_VIDEO_LB_LEN + 2048)) == NULL) { return 0; } cached_dir = (uint8_t *)(((uintptr_t)cached_dir_base & ~((uintptr_t)2047)) + 2048); if( DVDReadLBUDF( device, lbnum, dir_lba, cached_dir, 0) <= 0 ) { free(cached_dir_base); cached_dir = NULL; } /* if(cached_dir) { fprintf(stderr, "malloc dir: %d\n", dir_lba * DVD_VIDEO_LB_LEN); } */ SetUDFCache(device, LBUDFCache, lbnum, &cached_dir); } else { in_cache = 1; } if(cached_dir == NULL) { return 0; } p = 0; while( p < Dir.Length ) { UDFDescriptor( &cached_dir[ p ], &TagID ); if( TagID == 257 ) { p += UDFFileIdentifier( &cached_dir[ p ], &filechar, filename, &tmpICB ); if(cache_file_info && !in_cache) { uint8_t tmpFiletype; struct AD tmpFile; if( !strcasecmp( FileName, filename ) ) { *FileICB = tmpICB; found = 1; } UDFMapICB(device, tmpICB, &tmpFiletype, partition, &tmpFile); } else { if( !strcasecmp( FileName, filename ) ) { *FileICB = tmpICB; return 1; } } } else { if(cache_file_info && (!in_cache) && found) { return 1; } return 0; } } if(cache_file_info && (!in_cache) && found) { return 1; } return 0; } if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) { return 0; } p = 0; while( p < Dir.Length ) { if( p > DVD_VIDEO_LB_LEN ) { ++lbnum; p -= DVD_VIDEO_LB_LEN; Dir.Length -= DVD_VIDEO_LB_LEN; if( DVDReadLBUDF( device, lbnum, 2, directory, 0 ) <= 0 ) { return 0; } } UDFDescriptor( &directory[ p ], &TagID ); if( TagID == 257 ) { p += UDFFileIdentifier( &directory[ p ], &filechar, filename, FileICB ); if( !strcasecmp( FileName, filename ) ) { return 1; } } else { return 0; } } return 0; } static int UDFGetAVDP( dvd_reader_t *device, struct avdp_t *avdp) { uint8_t Anchor_base[ DVD_VIDEO_LB_LEN + 2048 ]; uint8_t *Anchor = (uint8_t *)(((uintptr_t)Anchor_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum, MVDS_location, MVDS_length; uint16_t TagID; uint32_t lastsector; int terminate; struct avdp_t; if(GetUDFCache(device, AVDPCache, 0, avdp)) { return 1; } /* Find Anchor */ lastsector = 0; lbnum = 256; /* Try #1, prime anchor */ terminate = 0; for(;;) { if( DVDReadLBUDF( device, lbnum, 1, Anchor, 0 ) > 0 ) { UDFDescriptor( Anchor, &TagID ); } else { TagID = 0; } if (TagID != 2) { /* Not an anchor */ if( terminate ) return 0; /* Final try failed */ if( lastsector ) { /* We already found the last sector. Try #3, alternative * backup anchor. If that fails, don't try again. */ lbnum = lastsector; terminate = 1; } else { /* TODO: Find last sector of the disc (this is optional). */ if( lastsector ) { /* Try #2, backup anchor */ lbnum = lastsector - 256; } else { /* Unable to find last sector */ return 0; } } } else { /* It's an anchor! We can leave */ break; } } /* Main volume descriptor */ UDFExtentAD( &Anchor[ 16 ], &MVDS_length, &MVDS_location ); avdp->mvds.location = MVDS_location; avdp->mvds.length = MVDS_length; /* Backup volume descriptor */ UDFExtentAD( &Anchor[ 24 ], &MVDS_length, &MVDS_location ); avdp->rvds.location = MVDS_location; avdp->rvds.length = MVDS_length; SetUDFCache(device, AVDPCache, 0, avdp); return 1; } /** * Looks for partition on the disc. Returns 1 if partition found, 0 on error. * partnum: Number of the partition, starting at 0. * part: structure to fill with the partition information */ static int UDFFindPartition( dvd_reader_t *device, int partnum, struct Partition *part ) { uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ]; uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum, MVDS_location, MVDS_length; uint16_t TagID; int i, volvalid; struct avdp_t avdp; if(!UDFGetAVDP(device, &avdp)) { return 0; } /* Main volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; part->valid = 0; volvalid = 0; part->VolumeDesc[ 0 ] = '\0'; i = 1; do { /* Find Volume Descriptor */ lbnum = MVDS_location; do { if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) { TagID = 0; } else { UDFDescriptor( LogBlock, &TagID ); } if( ( TagID == 5 ) && ( !part->valid ) ) { /* Partition Descriptor */ UDFPartition( LogBlock, &part->Flags, &part->Number, part->Contents, &part->Start, &part->Length ); part->valid = ( partnum == part->Number ); } else if( ( TagID == 6 ) && ( !volvalid ) ) { /* Logical Volume Descriptor */ if( UDFLogVolume( LogBlock, part->VolumeDesc ) ) { /* TODO: sector size wrong! */ } else { volvalid = 1; } } } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) && ( ( !part->valid ) || ( !volvalid ) ) ); if( ( !part->valid) || ( !volvalid ) ) { /* Backup volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; } } while( i-- && ( ( !part->valid ) || ( !volvalid ) ) ); /* We only care for the partition, not the volume */ return part->valid; } uint32_t UDFFindFile( dvd_reader_t *device, char *filename, uint32_t *filesize ) { uint8_t LogBlock_base[ DVD_VIDEO_LB_LEN + 2048 ]; uint8_t *LogBlock = (uint8_t *)(((uintptr_t)LogBlock_base & ~((uintptr_t)2047)) + 2048); uint32_t lbnum; uint16_t TagID; struct Partition partition; struct AD RootICB, File, ICB = {0, 0, 0, 0}; char tokenline[ MAX_UDF_FILE_NAME_LEN ]; char *token; uint8_t filetype; *filesize = 0; tokenline[0] = '\0'; strcat( tokenline, filename ); if(!(GetUDFCache(device, PartitionCache, 0, &partition) && GetUDFCache(device, RootICBCache, 0, &RootICB))) { /* Find partition, 0 is the standard location for DVD Video.*/ if( !UDFFindPartition( device, 0, &partition ) ) return 0; SetUDFCache(device, PartitionCache, 0, &partition); /* Find root dir ICB */ lbnum = partition.Start; do { if( DVDReadLBUDF( device, lbnum++, 1, LogBlock, 0 ) <= 0 ) { TagID = 0; } else { UDFDescriptor( LogBlock, &TagID ); } /* File Set Descriptor */ if( TagID == 256 ) { /* File Set Descriptor */ UDFLongAD( &LogBlock[ 400 ], &RootICB ); } } while( ( lbnum < partition.Start + partition.Length ) && ( TagID != 8 ) && ( TagID != 256 ) ); /* Sanity checks. */ if( TagID != 256 ) return 0; if( RootICB.Partition != 0 ) return 0; SetUDFCache(device, RootICBCache, 0, &RootICB); } /* Find root dir */ if( !UDFMapICB( device, RootICB, &filetype, &partition, &File ) ) return 0; if( filetype != 4 ) return 0; /* Root dir should be dir */ { int cache_file_info = 0; /* Tokenize filepath */ token = strtok(tokenline, "/"); while( token != NULL ) { if( !UDFScanDir( device, File, token, &partition, &ICB, cache_file_info)) { return 0; } if( !UDFMapICB( device, ICB, &filetype, &partition, &File ) ) { return 0; } if(!strcmp(token, "VIDEO_TS")) { cache_file_info = 1; } token = strtok( NULL, "/" ); } } /* Sanity check. */ if( File.Partition != 0 ) return 0; *filesize = File.Length; /* Hack to not return partition.Start for empty files. */ if( !File.Location ) return 0; else return partition.Start + File.Location; } /** * Gets a Descriptor . * Returns 1 if descriptor found, 0 on error. * id, tagid of descriptor * bufsize, size of BlockBuf (must be >= DVD_VIDEO_LB_LEN). */ static int UDFGetDescriptor( dvd_reader_t *device, int id, uint8_t *descriptor, int bufsize) { uint32_t lbnum, MVDS_location, MVDS_length; struct avdp_t avdp; uint16_t TagID; #if 0 uint32_t lastsector = 0; int terminate = 0; #endif int i; int desc_found = 0; /* Find Anchor */ lbnum = 256; /* Try #1, prime anchor */ if(bufsize < DVD_VIDEO_LB_LEN) { return 0; } if(!UDFGetAVDP(device, &avdp)) { return 0; } /* Main volume descriptor */ MVDS_location = avdp.mvds.location; MVDS_length = avdp.mvds.length; i = 1; do { /* Find Descriptor */ lbnum = MVDS_location; do { if( DVDReadLBUDF( device, lbnum++, 1, descriptor, 0 ) <= 0 ) { TagID = 0; } else { UDFDescriptor( descriptor, &TagID ); } if( (TagID == id) && ( !desc_found ) ) { /* Descriptor */ desc_found = 1; } } while( ( lbnum <= MVDS_location + ( MVDS_length - 1 ) / DVD_VIDEO_LB_LEN ) && ( TagID != 8 ) && ( !desc_found) ); if( !desc_found ) { /* Backup volume descriptor */ MVDS_location = avdp.rvds.location; MVDS_length = avdp.rvds.length; } } while( i-- && ( !desc_found ) ); return desc_found; } static int UDFGetPVD(dvd_reader_t *device, struct pvd_t *pvd) { uint8_t pvd_buf_base[DVD_VIDEO_LB_LEN + 2048]; uint8_t *pvd_buf = (uint8_t *)(((uintptr_t)pvd_buf_base & ~((uintptr_t)2047)) + 2048); if(GetUDFCache(device, PVDCache, 0, pvd)) { return 1; } if(!UDFGetDescriptor( device, 1, pvd_buf, sizeof(pvd_buf))) { return 0; } memcpy(pvd->VolumeIdentifier, &pvd_buf[24], 32); memcpy(pvd->VolumeSetIdentifier, &pvd_buf[72], 128); SetUDFCache(device, PVDCache, 0, pvd); return 1; } /** * Gets the Volume Identifier string, in 8bit unicode (latin-1) * volid, place to put the string * volid_size, size of the buffer volid points to * returns the size of buffer needed for all data */ int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid, unsigned int volid_size) { struct pvd_t pvd; unsigned int volid_len; /* get primary volume descriptor */ if(!UDFGetPVD(device, &pvd)) { return 0; } volid_len = pvd.VolumeIdentifier[31]; if(volid_len > 31) { /* this field is only 32 bytes something is wrong */ volid_len = 31; } if(volid_size > volid_len) { volid_size = volid_len; } Unicodedecode(pvd.VolumeIdentifier, volid_size, volid); return volid_len; } /** * Gets the Volume Set Identifier, as a 128-byte dstring (not decoded) * WARNING This is not a null terminated string * volsetid, place to put the data * volsetid_size, size of the buffer volsetid points to * the buffer should be >=128 bytes to store the whole volumesetidentifier * returns the size of the available volsetid information (128) * or 0 on error */ int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid, unsigned int volsetid_size) { struct pvd_t pvd; /* get primary volume descriptor */ if(!UDFGetPVD(device, &pvd)) { return 0; } if(volsetid_size > 128) { volsetid_size = 128; } memcpy(volsetid, pvd.VolumeSetIdentifier, volsetid_size); return 128; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/highlight.c��������������������������������������������������������0000644�0001750�0001750�00000036552�14647725152�016711� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <assert.h> #include "nav_types.h" #include "dvdnav_internal.h" /* #define BUTTON_TESTING */ #ifdef BUTTON_TESTING #include "nav_print.h" static void print_time(dvd_time_t *dtime) { const char *rate; assert((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa); assert((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa); assert((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa); assert((dtime->frame_u&0xf) < 0xa); fprintf(MSG_OUT,"%02x:%02x:%02x.%02x", dtime->hour, dtime->minute, dtime->second, dtime->frame_u & 0x3f); switch((dtime->frame_u & 0xc0) >> 6) { case 1: rate = "25.00"; break; case 3: rate = "29.97"; break; default: rate = "(please send a bug report)"; break; } fprintf(MSG_OUT," @ %s fps", rate); } static void nav_print_PCI_GI(pci_gi_t *pci_gi) { int32_t i; fprintf(MSG_OUT,"libdvdnav: pci_gi:\n"); fprintf(MSG_OUT,"libdvdnav: nv_pck_lbn 0x%08x\n", pci_gi->nv_pck_lbn); fprintf(MSG_OUT,"libdvdnav: vobu_cat 0x%04x\n", pci_gi->vobu_cat); fprintf(MSG_OUT,"libdvdnav: vobu_uop_ctl 0x%08x\n", *(uint32_t*)&pci_gi->vobu_uop_ctl); fprintf(MSG_OUT,"libdvdnav: vobu_s_ptm 0x%08x\n", pci_gi->vobu_s_ptm); fprintf(MSG_OUT,"libdvdnav: vobu_e_ptm 0x%08x\n", pci_gi->vobu_e_ptm); fprintf(MSG_OUT,"libdvdnav: vobu_se_e_ptm 0x%08x\n", pci_gi->vobu_se_e_ptm); fprintf(MSG_OUT,"libdvdnav: e_eltm "); print_time(&pci_gi->e_eltm); fprintf(MSG_OUT,"\n"); fprintf(MSG_OUT,"libdvdnav: vobu_isrc \""); for(i = 0; i < 32; i++) { char c = pci_gi->vobu_isrc[i]; if((c >= ' ') && (c <= '~')) fprintf(MSG_OUT,"%c", c); else fprintf(MSG_OUT,"."); } fprintf(MSG_OUT,"\"\n"); } static void nav_print_NSML_AGLI(nsml_agli_t *nsml_agli) { int32_t i, j = 0; for(i = 0; i < 9; i++) j |= nsml_agli->nsml_agl_dsta[i]; if(j == 0) return; fprintf(MSG_OUT,"libdvdnav: nsml_agli:\n"); for(i = 0; i < 9; i++) if(nsml_agli->nsml_agl_dsta[i]) fprintf(MSG_OUT,"libdvdnav: nsml_agl_c%d_dsta 0x%08x\n", i + 1, nsml_agli->nsml_agl_dsta[i]); } static void nav_print_HL_GI(hl_gi_t *hl_gi, int32_t *btngr_ns, int32_t *btn_ns) { if((hl_gi->hli_ss & 0x03) == 0) return; fprintf(MSG_OUT,"libdvdnav: hl_gi:\n"); fprintf(MSG_OUT,"libdvdnav: hli_ss 0x%01x\n", hl_gi->hli_ss & 0x03); fprintf(MSG_OUT,"libdvdnav: hli_s_ptm 0x%08x\n", hl_gi->hli_s_ptm); fprintf(MSG_OUT,"libdvdnav: hli_e_ptm 0x%08x\n", hl_gi->hli_e_ptm); fprintf(MSG_OUT,"libdvdnav: btn_se_e_ptm 0x%08x\n", hl_gi->btn_se_e_ptm); *btngr_ns = hl_gi->btngr_ns; fprintf(MSG_OUT,"libdvdnav: btngr_ns %d\n", hl_gi->btngr_ns); fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 1, hl_gi->btngr1_dsp_ty); fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 2, hl_gi->btngr2_dsp_ty); fprintf(MSG_OUT,"libdvdnav: btngr%d_dsp_ty 0x%02x\n", 3, hl_gi->btngr3_dsp_ty); fprintf(MSG_OUT,"libdvdnav: btn_ofn %d\n", hl_gi->btn_ofn); *btn_ns = hl_gi->btn_ns; fprintf(MSG_OUT,"libdvdnav: btn_ns %d\n", hl_gi->btn_ns); fprintf(MSG_OUT,"libdvdnav: nsl_btn_ns %d\n", hl_gi->nsl_btn_ns); fprintf(MSG_OUT,"libdvdnav: fosl_btnn %d\n", hl_gi->fosl_btnn); fprintf(MSG_OUT,"libdvdnav: foac_btnn %d\n", hl_gi->foac_btnn); } static void nav_print_BTN_COLIT(btn_colit_t *btn_colit) { int32_t i, j; j = 0; for(i = 0; i < 6; i++) j |= btn_colit->btn_coli[i/2][i&1]; if(j == 0) return; fprintf(MSG_OUT,"libdvdnav: btn_colit:\n"); for(i = 0; i < 3; i++) for(j = 0; j < 2; j++) fprintf(MSG_OUT,"libdvdnav: btn_cqoli %d %s_coli: %08x\n", i, (j == 0) ? "sl" : "ac", btn_colit->btn_coli[i][j]); } static void nav_print_BTNIT(btni_t *btni_table, int32_t btngr_ns, int32_t btn_ns) { int32_t i, j, k; fprintf(MSG_OUT,"libdvdnav: btnit:\n"); fprintf(MSG_OUT,"libdvdnav: btngr_ns: %i\n", btngr_ns); fprintf(MSG_OUT,"libdvdnav: btn_ns: %i\n", btn_ns); if(btngr_ns == 0) return; for(i = 0; i < btngr_ns; i++) { for(j = 0; j < (36 / btngr_ns); j++) { if(j < btn_ns) { btni_t *btni = &btni_table[(36 / btngr_ns) * i + j]; fprintf(MSG_OUT,"libdvdnav: group %d btni %d: ", i+1, j+1); fprintf(MSG_OUT,"btn_coln %d, auto_action_mode %d\n", btni->btn_coln, btni->auto_action_mode); fprintf(MSG_OUT,"libdvdnav: coords (%d, %d) .. (%d, %d)\n", btni->x_start, btni->y_start, btni->x_end, btni->y_end); fprintf(MSG_OUT,"libdvdnav: up %d, ", btni->up); fprintf(MSG_OUT,"down %d, ", btni->down); fprintf(MSG_OUT,"left %d, ", btni->left); fprintf(MSG_OUT,"right %d\n", btni->right); for(k = 0; k < 8; k++) { fprintf(MSG_OUT, "libdvdnav: %02x ", btni->cmd.bytes[k]); } fprintf(MSG_OUT, "| "); #ifdef TRACE vm_print_mnemonic(&btni->cmd); #endif fprintf(MSG_OUT, "\n"); } } } } static void nav_print_HLI(hli_t *hli) { int32_t btngr_ns = 0, btn_ns = 0; fprintf(MSG_OUT,"libdvdnav: hli:\n"); nav_print_HL_GI(&hli->hl_gi, & btngr_ns, & btn_ns); nav_print_BTN_COLIT(&hli->btn_colit); nav_print_BTNIT(hli->btnit, btngr_ns, btn_ns); } void nav_print_PCI(pci_t *pci) { fprintf(MSG_OUT,"libdvdnav: pci packet:\n"); nav_print_PCI_GI(&pci->pci_gi); nav_print_NSML_AGLI(&pci->nsml_agli); nav_print_HLI(&pci->hli); } #endif /* Highlighting API calls */ dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *this, int32_t *button) { if(!this || !button) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } /* Simply return the appropriate value based on the SPRM */ if(((*button) = this->position_current.button) == -1) (*button) = this->vm->state.HL_BTNN_REG >> 10; return DVDNAV_STATUS_OK; } static btni_t *get_current_button(dvdnav_t *this, pci_t *pci) { int32_t button = 0; if(!this || !pci) { printerr("Passed a NULL pointer."); return NULL; } if(!pci->hli.hl_gi.hli_ss) { printerr("Not in a menu."); return NULL; } if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) { printerr("This NAV has already been left."); return NULL; } button = this->vm->state.HL_BTNN_REG >> 10; #ifdef BUTTON_TESTING nav_print_PCI(pci); #endif return &(pci->hli.btnit[button-1]); } static dvdnav_status_t button_auto_action(dvdnav_t *this, pci_t *pci) { if (get_current_button(this, pci)->auto_action_mode) return dvdnav_button_activate(this, pci); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!(button_ptr = get_current_button(this, pci))) return DVDNAV_STATUS_ERR; dvdnav_button_select(this, pci, button_ptr->up); return button_auto_action(this, pci); } dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!(button_ptr = get_current_button(this, pci))) return DVDNAV_STATUS_ERR; dvdnav_button_select(this, pci, button_ptr->down); return button_auto_action(this, pci); } dvdnav_status_t dvdnav_right_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!(button_ptr = get_current_button(this, pci))) return DVDNAV_STATUS_ERR; dvdnav_button_select(this, pci, button_ptr->right); return button_auto_action(this, pci); } dvdnav_status_t dvdnav_left_button_select(dvdnav_t *this, pci_t *pci) { btni_t *button_ptr; if(!(button_ptr = get_current_button(this, pci))) return DVDNAV_STATUS_ERR; dvdnav_button_select(this, pci, button_ptr->left); return button_auto_action(this, pci); } dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode, dvdnav_highlight_area_t *highlight) { btni_t *button_ptr; #ifdef BUTTON_TESTING fprintf(MSG_OUT, "libdvdnav: Button get_highlight_area %i\n", button); #endif if(!nav_pci->hli.hl_gi.hli_ss) return DVDNAV_STATUS_ERR; if((button <= 0) || (button > nav_pci->hli.hl_gi.btn_ns)) return DVDNAV_STATUS_ERR; button_ptr = &nav_pci->hli.btnit[button-1]; highlight->sx = button_ptr->x_start; highlight->sy = button_ptr->y_start; highlight->ex = button_ptr->x_end; highlight->ey = button_ptr->y_end; if(button_ptr->btn_coln != 0) { highlight->palette = nav_pci->hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode]; } else { highlight->palette = 0; } highlight->pts = nav_pci->hli.hl_gi.hli_s_ptm; highlight->buttonN = button; #ifdef BUTTON_TESTING fprintf(MSG_OUT, "libdvdnav: highlight: Highlight area is (%u,%u)-(%u,%u), display = %i, button = %u\n", button_ptr->x_start, button_ptr->y_start, button_ptr->x_end, button_ptr->y_end, 1, button); #endif return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_button_activate(dvdnav_t *this, pci_t *pci) { int32_t button; btni_t *button_ptr = NULL; if(!this || !pci) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } if(!pci->hli.hl_gi.hli_ss) { printerr("Not in a menu."); return DVDNAV_STATUS_ERR; } if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) { printerr("This NAV has already been left."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); button = this->vm->state.HL_BTNN_REG >> 10; if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) { /* Special code to handle still menus with no buttons. * The navigation is expected to report to the application that a STILL is * underway. In turn, the application is supposed to report to the user * that the playback is paused. The user is then expected to undo the pause, * ie: hit play. At that point, the navigation should release the still and * go to the next Cell. * Explanation by Mathieu Lacage <mathieu_lacage@realmagic.fr> * Code added by jcdutton. */ if (this->position_current.still != 0) { /* In still, but no buttons. */ vm_get_next_cell(this->vm); this->position_current.still = 0; this->sync_wait = 0; this->last_cmd_nav_lbn = pci->pci_gi.nv_pck_lbn; pthread_mutex_unlock(&this->vm_lock); /* clear error message */ printerr(""); return DVDNAV_STATUS_OK; } pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } button_ptr = get_current_button(this, pci); /* Finally, make the VM execute the appropriate code and probably * scedule a jump */ #ifdef BUTTON_TESTING fprintf(MSG_OUT, "libdvdnav: Evaluating Button Activation commands.\n"); #endif if(vm_exec_cmd(this->vm, &(button_ptr->cmd)) == 1) { /* Command caused a jump */ this->vm->hop_channel++; this->position_current.still = 0; this->last_cmd_nav_lbn = pci->pci_gi.nv_pck_lbn; } pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *this, int32_t button, vm_cmd_t *cmd) { if(!this || !cmd) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); /* make the VM execute the appropriate code and probably * schedule a jump */ #ifdef BUTTON_TESTING fprintf(MSG_OUT, "libdvdnav: dvdnav_button_activate_cmd: Evaluating Button Activation commands.\n"); #endif if(button > 0) { this->vm->state.HL_BTNN_REG = (button << 10); if(vm_exec_cmd(this->vm, cmd) == 1) { /* Command caused a jump */ this->vm->hop_channel++; } } /* Always remove still, because some still menus have no buttons. */ this->position_current.still = 0; this->sync_wait = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_button_select(dvdnav_t *this, pci_t *pci, int32_t button) { if(!this || !pci) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } if(!pci->hli.hl_gi.hli_ss) { printerr("Not in a menu."); return DVDNAV_STATUS_ERR; } if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) { printerr("This NAV has already been left."); return DVDNAV_STATUS_ERR; } #ifdef BUTTON_TESTING fprintf(MSG_OUT, "libdvdnav: Button select %i\n", button); #endif if((button <= 0) || (button > pci->hli.hl_gi.btn_ns)) { printerr("Button does not exist."); return DVDNAV_STATUS_ERR; } this->vm->state.HL_BTNN_REG = (button << 10); this->position_current.button = -1; /* Force Highligh change */ return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *this, pci_t *pci, int32_t button) { /* A trivial function */ if(dvdnav_button_select(this, pci, button) != DVDNAV_STATUS_ERR) return dvdnav_button_activate(this, pci); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_mouse_select(dvdnav_t *this, pci_t *pci, int32_t x, int32_t y) { int32_t button, cur_button; int32_t best,dist,d; int32_t mx,my,dx,dy; if(!this || !pci) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } if(!pci->hli.hl_gi.hli_ss) { printerr("Not in a menu."); return DVDNAV_STATUS_ERR; } if(this->last_cmd_nav_lbn == pci->pci_gi.nv_pck_lbn) { printerr("This NAV has already been left."); return DVDNAV_STATUS_ERR; } cur_button = this->vm->state.HL_BTNN_REG >> 10; best = 0; dist = 0x08000000; /* >> than (720*720)+(567*567); */ /* Loop through all buttons */ for(button = 1; button <= pci->hli.hl_gi.btn_ns; button++) { btni_t *button_ptr = &(pci->hli.btnit[button-1]); if((x >= button_ptr->x_start) && (x <= button_ptr->x_end) && (y >= button_ptr->y_start) && (y <= button_ptr->y_end)) { mx = (button_ptr->x_start + button_ptr->x_end)/2; my = (button_ptr->y_start + button_ptr->y_end)/2; dx = mx - x; dy = my - y; d = (dx*dx) + (dy*dy); /* If the mouse is within the button and the mouse is closer * to the center of this button then it is the best choice. */ if(d < dist) { dist = d; best = button; } } } /* As an efficiency measure, only re-select the button * if it is different to the previously selected one. */ if (best != 0 && best != cur_button) dvdnav_button_select(this, pci, best); /* return DVDNAV_STATUS_OK only if we actually found a matching button */ return best ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *this, pci_t *pci, int32_t x, int32_t y) { /* A trivial function */ if(dvdnav_mouse_select(this, pci, x,y) != DVDNAV_STATUS_ERR) return dvdnav_button_activate(this, pci); return DVDNAV_STATUS_ERR; } ������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/decoder.c����������������������������������������������������������0000644�0001750�0001750�00000060222�14647725152�016336� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort * 2002-2004 the dvdnav project * * This file is part of libdvdnav, a DVD navigation library. It is modified * from a file originally part of the Ogle DVD player. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include <string.h> /* For memset */ #include "ifo_types.h" /* vm_cmd_t */ #include "dvdnav_internal.h" #include <xine/xineutils.h> /* _x_assert() */ uint32_t vm_getbits(command_t *command, int32_t start, int32_t count) { uint64_t result = 0; uint64_t bit_mask = 0; uint64_t examining = 0; int32_t bits; if (count == 0) return 0; if ( ((start - count) < -1) || (count > 32) || (start > 63) || (count < 0) || (start < 0) ) { fprintf(MSG_OUT, "libdvdnav: Bad call to vm_getbits. Parameter out of range\n"); return 0; } /* all ones, please */ bit_mask = ~bit_mask; bit_mask >>= 63 - start; bits = start + 1 - count; examining = ((bit_mask >> bits) << bits ); command->examined |= examining; result = (command->instruction & bit_mask) >> bits; return (uint32_t) result; } static uint16_t get_GPRM(registers_t* registers, uint8_t reg) { if (registers->GPRM_mode[reg] & 0x01) { struct timeval current_time, time_offset; uint16_t result; /* Counter mode */ /* fprintf(MSG_OUT, "libdvdnav: Getting counter %d\n",reg);*/ gettimeofday(¤t_time, NULL); time_offset.tv_sec = current_time.tv_sec - registers->GPRM_time[reg].tv_sec; time_offset.tv_usec = current_time.tv_usec - registers->GPRM_time[reg].tv_usec; if (time_offset.tv_usec < 0) { time_offset.tv_sec--; time_offset.tv_usec += 1000000; } result = (uint16_t) (time_offset.tv_sec & 0xffff); registers->GPRM[reg]=result; return result; } else { /* Register mode */ return registers->GPRM[reg]; } } static void set_GPRM(registers_t* registers, uint8_t reg, uint16_t value) { if (registers->GPRM_mode[reg] & 0x01) { struct timeval current_time; /* Counter mode */ /* fprintf(MSG_OUT, "libdvdnav: Setting counter %d\n",reg); */ gettimeofday(¤t_time, NULL); registers->GPRM_time[reg] = current_time; registers->GPRM_time[reg].tv_sec -= value; } registers->GPRM[reg] = value; } /* Eval register code, can either be system or general register. SXXX_XXXX, where S is 1 if it is system register. */ static uint16_t eval_reg(command_t* command, uint8_t reg) { if(reg & 0x80) { if ((reg & 0x1f) == 20) { fprintf(MSG_OUT, "libdvdnav: Suspected RCE Region Protection!!!\n"); } return command->registers->SPRM[reg & 0x1f]; /* FIXME max 24 not 32 */ } else { return get_GPRM(command->registers, reg & 0x0f) ; } } /* Eval register or immediate data. AAAA_AAAA BBBB_BBBB, if immediate use all 16 bits for data else use lower eight bits for the system or general purpose register. */ static uint16_t eval_reg_or_data(command_t* command, int32_t imm, int32_t start) { if(imm) { /* immediate */ return vm_getbits(command, start, 16); } else { return eval_reg(command, vm_getbits(command, (start - 8), 8)); } } /* Eval register or immediate data. xBBB_BBBB, if immediate use all 7 bits for data else use lower four bits for the general purpose register number. */ /* Evaluates gprm or data depending on bit, data is in byte n */ static uint16_t eval_reg_or_data_2(command_t* command, int32_t imm, int32_t start) { if(imm) /* immediate */ return vm_getbits(command, (start - 1), 7); else return get_GPRM(command->registers, (vm_getbits(command, (start - 4), 4)) ); } /* Compare data using operation, return result from comparison. Helper function for the different if functions. */ static int32_t eval_compare(uint8_t operation, uint16_t data1, uint16_t data2) { switch(operation) { case 1: return data1 & data2; case 2: return data1 == data2; case 3: return data1 != data2; case 4: return data1 >= data2; case 5: return data1 > data2; case 6: return data1 <= data2; case 7: return data1 < data2; } fprintf(MSG_OUT, "libdvdnav: eval_compare: Invalid comparison code\n"); return 0; } /* Evaluate if version 1. Has comparison data in byte 3 and 4-5 (immediate or register) */ static int32_t eval_if_version_1(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { return eval_compare(op, eval_reg(command, vm_getbits(command, 39, 8)), eval_reg_or_data(command, vm_getbits(command, 55, 1), 31)); } return 1; } /* Evaluate if version 2. This version only compares register which are in byte 6 and 7 */ static int32_t eval_if_version_2(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { return eval_compare(op, eval_reg(command, vm_getbits(command, 15, 8)), eval_reg(command, vm_getbits(command, 7, 8))); } return 1; } /* Evaluate if version 3. Has comparison data in byte 2 and 6-7 (immediate or register) */ static int32_t eval_if_version_3(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { return eval_compare(op, eval_reg(command, vm_getbits(command, 47, 8)), eval_reg_or_data(command, vm_getbits(command, 55, 1), 15)); } return 1; } /* Evaluate if version 4. Has comparison data in byte 1 and 4-5 (immediate or register) The register in byte 1 is only the lowe nibble (4 bits) */ static int32_t eval_if_version_4(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { return eval_compare(op, eval_reg(command, vm_getbits(command, 51, 4)), eval_reg_or_data(command, vm_getbits(command, 55, 1), 31)); } return 1; } /* Evaluate special instruction.... returns the new row/line number, 0 if no new row and 256 if Break. */ static int32_t eval_special_instruction(command_t* command, int32_t cond) { int32_t line, level; switch(vm_getbits(command, 51, 4)) { case 0: /* NOP */ line = 0; return cond ? line : 0; case 1: /* Goto line */ line = vm_getbits(command, 7, 8); return cond ? line : 0; case 2: /* Break */ /* max number of rows < 256, so we will end this set */ line = 256; return cond ? 256 : 0; case 3: /* Set temporary parental level and goto */ line = vm_getbits(command, 7, 8); level = vm_getbits(command, 11, 4); if(cond) { /* This always succeeds now, if we want real parental protection */ /* we need to ask the user and have passwords and stuff. */ command->registers->SPRM[13] = level; } return cond ? line : 0; } return 0; } /* Evaluate link by subinstruction. Return 1 if link, or 0 if no link Actual link instruction is in return_values parameter */ static int32_t eval_link_subins(command_t* command, int32_t cond, link_t *return_values) { uint16_t button = vm_getbits(command, 15, 6); uint8_t linkop = vm_getbits(command, 4, 5); if(linkop > 0x10) return 0; /* Unknown Link by Sub-Instruction command */ /* Assumes that the link_cmd_t enum has the same values as the LinkSIns codes */ return_values->command = linkop; return_values->data1 = button; return cond; } /* Evaluate link instruction. Return 1 if link, or 0 if no link Actual link instruction is in return_values parameter */ static int32_t eval_link_instruction(command_t* command, int32_t cond, link_t *return_values) { uint8_t op = vm_getbits(command, 51, 4); switch(op) { case 1: return eval_link_subins(command, cond, return_values); case 4: return_values->command = LinkPGCN; return_values->data1 = vm_getbits(command, 14, 15); return cond; case 5: return_values->command = LinkPTTN; return_values->data1 = vm_getbits(command, 9, 10); return_values->data2 = vm_getbits(command, 15, 6); return cond; case 6: return_values->command = LinkPGN; return_values->data1 = vm_getbits(command, 6, 7); return_values->data2 = vm_getbits(command, 15, 6); return cond; case 7: return_values->command = LinkCN; return_values->data1 = vm_getbits(command, 7, 8); return_values->data2 = vm_getbits(command, 15, 6); return cond; } return 0; } /* Evaluate a jump instruction. returns 1 if jump or 0 if no jump actual jump instruction is in return_values parameter */ static int32_t eval_jump_instruction(command_t* command, int32_t cond, link_t *return_values) { switch(vm_getbits(command, 51, 4)) { case 1: return_values->command = Exit; return cond; case 2: return_values->command = JumpTT; return_values->data1 = vm_getbits(command, 22, 7); return cond; case 3: return_values->command = JumpVTS_TT; return_values->data1 = vm_getbits(command, 22, 7); return cond; case 5: return_values->command = JumpVTS_PTT; return_values->data1 = vm_getbits(command, 22, 7); return_values->data2 = vm_getbits(command, 41, 10); return cond; case 6: switch(vm_getbits(command, 23, 2)) { case 0: return_values->command = JumpSS_FP; return cond; case 1: return_values->command = JumpSS_VMGM_MENU; return_values->data1 = vm_getbits(command, 19, 4); return cond; case 2: return_values->command = JumpSS_VTSM; return_values->data1 = vm_getbits(command, 31, 8); return_values->data2 = vm_getbits(command, 39, 8); return_values->data3 = vm_getbits(command, 19, 4); return cond; case 3: return_values->command = JumpSS_VMGM_PGC; return_values->data1 = vm_getbits(command, 46, 15); return cond; } break; case 8: switch(vm_getbits(command, 23, 2)) { case 0: return_values->command = CallSS_FP; return_values->data1 = vm_getbits(command, 31, 8); return cond; case 1: return_values->command = CallSS_VMGM_MENU; return_values->data1 = vm_getbits(command, 19, 4); return_values->data2 = vm_getbits(command, 31, 8); return cond; case 2: return_values->command = CallSS_VTSM; return_values->data1 = vm_getbits(command, 19, 4); return_values->data2 = vm_getbits(command, 31, 8); return cond; case 3: return_values->command = CallSS_VMGM_PGC; return_values->data1 = vm_getbits(command, 46, 15); return_values->data2 = vm_getbits(command, 31, 8); return cond; } break; } return 0; } /* Evaluate a set sytem register instruction May contain a link so return the same as eval_link */ static int32_t eval_system_set(command_t* command, int32_t cond, link_t *return_values) { int32_t i; uint16_t data, data2; switch(vm_getbits(command, 59, 4)) { case 1: /* Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */ for(i = 1; i <= 3; i++) { if(vm_getbits(command, 63 - ((2 + i)*8), 1)) { data = eval_reg_or_data_2(command, vm_getbits(command, 60, 1), (47 - (i*8))); if(cond) { command->registers->SPRM[i] = data; } } } break; case 2: /* Set system reg 9 & 10 (Navigation timer, Title PGC number) */ data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47); data2 = vm_getbits(command, 23, 8); /* ?? size */ if(cond) { command->registers->SPRM[9] = data; /* time */ command->registers->SPRM[10] = data2; /* pgcN */ } break; case 3: /* Mode: Counter / Register + Set */ data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47); data2 = vm_getbits(command, 19, 4); if(vm_getbits(command, 23, 1)) { command->registers->GPRM_mode[data2] |= 1; /* Set bit 0 */ } else { command->registers->GPRM_mode[data2] &= ~ 0x01; /* Reset bit 0 */ } if(cond) { set_GPRM(command->registers, data2, data); } break; case 6: /* Set system reg 8 (Highlighted button) */ data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); /* Not system reg!! */ if(cond) { command->registers->SPRM[8] = data; } break; } if(vm_getbits(command, 51, 4)) { return eval_link_instruction(command, cond, return_values); } return 0; } /* Evaluate set operation Sets the register given to the value indicated by op and data. For the swap case the contents of reg is stored in reg2. */ static void eval_set_op(command_t* command, int32_t op, int32_t reg, int32_t reg2, int32_t data) { const int32_t shortmax = 0xffff; int32_t tmp; switch(op) { case 1: set_GPRM(command->registers, reg, data); break; case 2: /* SPECIAL CASE - SWAP! */ set_GPRM(command->registers, reg2, get_GPRM(command->registers, reg)); set_GPRM(command->registers, reg, data); break; case 3: tmp = get_GPRM(command->registers, reg) + data; if(tmp > shortmax) tmp = shortmax; set_GPRM(command->registers, reg, (uint16_t)tmp); break; case 4: tmp = get_GPRM(command->registers, reg) - data; if(tmp < 0) tmp = 0; set_GPRM(command->registers, reg, (uint16_t)tmp); break; case 5: tmp = get_GPRM(command->registers, reg) * data; if(tmp > shortmax) tmp = shortmax; set_GPRM(command->registers, reg, (uint16_t)tmp); break; case 6: if (data != 0) { set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) / data) ); } else { set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */ } break; case 7: if (data != 0) { set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) % data) ); } else { set_GPRM(command->registers, reg, 0xffff); /* Avoid that divide by zero! */ } break; case 8: /* SPECIAL CASE - RND! Return numbers between 1 and data. */ set_GPRM(command->registers, reg, 1 + ((uint16_t) ((float) data * rand()/(RAND_MAX+1.0))) ); break; case 9: set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) & data) ); break; case 10: set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) | data) ); break; case 11: set_GPRM(command->registers, reg, (get_GPRM(command->registers, reg) ^ data) ); break; } } /* Evaluate set instruction, combined with either Link or Compare. */ static void eval_set_version_1(command_t* command, int32_t cond) { uint8_t op = vm_getbits(command, 59, 4); uint8_t reg = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */ uint8_t reg2 = vm_getbits(command, 19, 4); uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 31); if(cond) { eval_set_op(command, op, reg, reg2, data); } } /* Evaluate set instruction, combined with both Link and Compare. */ static void eval_set_version_2(command_t* command, int32_t cond) { uint8_t op = vm_getbits(command, 59, 4); uint8_t reg = vm_getbits(command, 51, 4); uint8_t reg2 = vm_getbits(command, 35, 4); /* FIXME: This is different from vmcmd.c!!! */ uint16_t data = eval_reg_or_data(command, vm_getbits(command, 60, 1), 47); if(cond) { eval_set_op(command, op, reg, reg2, data); } } /* Evaluate a command returns row number of goto, 0 if no goto, -1 if link. Link command in return_values */ static int32_t eval_command(uint8_t *bytes, registers_t* registers, link_t *return_values) { int32_t cond, res = 0; command_t command; command.instruction =( (uint64_t) bytes[0] << 56 ) | ( (uint64_t) bytes[1] << 48 ) | ( (uint64_t) bytes[2] << 40 ) | ( (uint64_t) bytes[3] << 32 ) | ( (uint64_t) bytes[4] << 24 ) | ( (uint64_t) bytes[5] << 16 ) | ( (uint64_t) bytes[6] << 8 ) | (uint64_t) bytes[7] ; command.examined = 0; command.registers = registers; memset(return_values, 0, sizeof(link_t)); switch(vm_getbits(&command, 63, 3)) { /* three first old_bits */ case 0: /* Special instructions */ cond = eval_if_version_1(&command); res = eval_special_instruction(&command, cond); if(res == -1) { fprintf(MSG_OUT, "libdvdnav: Unknown Instruction!\n"); _x_assert(!"libdvdnav: Unknown Instruction!"); } break; case 1: /* Link/jump instructions */ if(vm_getbits(&command, 60, 1)) { cond = eval_if_version_2(&command); res = eval_jump_instruction(&command, cond, return_values); } else { cond = eval_if_version_1(&command); res = eval_link_instruction(&command, cond, return_values); } if(res) res = -1; break; case 2: /* System set instructions */ cond = eval_if_version_2(&command); res = eval_system_set(&command, cond, return_values); if(res) res = -1; break; case 3: /* Set instructions, either Compare or Link may be used */ cond = eval_if_version_3(&command); eval_set_version_1(&command, cond); if(vm_getbits(&command, 51, 4)) { res = eval_link_instruction(&command, cond, return_values); } if(res) res = -1; break; case 4: /* Set, Compare -> Link Sub-Instruction */ eval_set_version_2(&command, /*True*/ 1); cond = eval_if_version_4(&command); res = eval_link_subins(&command, cond, return_values); if(res) res = -1; break; case 5: /* Compare -> (Set and Link Sub-Instruction) */ /* FIXME: These are wrong. Need to be updated from vmcmd.c */ cond = eval_if_version_4(&command); eval_set_version_2(&command, cond); res = eval_link_subins(&command, cond, return_values); if(res) res = -1; break; case 6: /* Compare -> Set, allways Link Sub-Instruction */ /* FIXME: These are wrong. Need to be updated from vmcmd.c */ cond = eval_if_version_4(&command); eval_set_version_2(&command, cond); res = eval_link_subins(&command, /*True*/ 1, return_values); if(res) res = -1; break; default: /* Unknown command */ fprintf(MSG_OUT, "libdvdnav: WARNING: Unknown Command=%x\n", vm_getbits(&command, 63, 3)); } /* Check if there are bits not yet examined */ if(command.instruction & ~ command.examined) { fprintf(MSG_OUT, "libdvdnav: decoder.c: [WARNING, unknown bits:"); fprintf(MSG_OUT, " %08"PRIx64, (command.instruction & ~ command.examined) ); fprintf(MSG_OUT, "]\n"); } return res; } /* Evaluate a set of commands in the given register set (which is modified) */ int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, registers_t *registers, link_t *return_values) { int32_t i = 0; int32_t total = 0; #ifdef TRACE /* DEBUG */ fprintf(MSG_OUT, "libdvdnav: Registers before transaction\n"); vm_print_registers( registers ); fprintf(MSG_OUT, "libdvdnav: Full list of commands to execute\n"); for(i = 0; i < num_commands; i++) vm_print_cmd(i, &commands[i]); fprintf(MSG_OUT, "libdvdnav: --------------------------------------------\n"); fprintf(MSG_OUT, "libdvdnav: Single stepping commands\n"); #endif i = 0; while(i < num_commands && total < 100000) { int32_t line; #ifdef TRACE vm_print_cmd(i, &commands[i]); #endif line = eval_command(&commands[i].bytes[0], registers, return_values); if (line < 0) { /* Link command */ #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n"); vm_print_registers( registers ); fprintf(MSG_OUT, "libdvdnav: eval: Doing Link/Jump/Call\n"); #endif return 1; } if (line > 0) /* Goto command */ i = line - 1; else /* Just continue on the next line */ i++; total++; } memset(return_values, 0, sizeof(link_t)); #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Registers after transaction\n"); vm_print_registers( registers ); #endif return 0; } #ifdef TRACE static char *linkcmd2str(link_cmd_t cmd) { switch(cmd) { case LinkNoLink: return "LinkNoLink"; case LinkTopC: return "LinkTopC"; case LinkNextC: return "LinkNextC"; case LinkPrevC: return "LinkPrevC"; case LinkTopPG: return "LinkTopPG"; case LinkNextPG: return "LinkNextPG"; case LinkPrevPG: return "LinkPrevPG"; case LinkTopPGC: return "LinkTopPGC"; case LinkNextPGC: return "LinkNextPGC"; case LinkPrevPGC: return "LinkPrevPGC"; case LinkGoUpPGC: return "LinkGoUpPGC"; case LinkTailPGC: return "LinkTailPGC"; case LinkRSM: return "LinkRSM"; case LinkPGCN: return "LinkPGCN"; case LinkPTTN: return "LinkPTTN"; case LinkPGN: return "LinkPGN"; case LinkCN: return "LinkCN"; case Exit: return "Exit"; case JumpTT: return "JumpTT"; case JumpVTS_TT: return "JumpVTS_TT"; case JumpVTS_PTT: return "JumpVTS_PTT"; case JumpSS_FP: return "JumpSS_FP"; case JumpSS_VMGM_MENU: return "JumpSS_VMGM_MENU"; case JumpSS_VTSM: return "JumpSS_VTSM"; case JumpSS_VMGM_PGC: return "JumpSS_VMGM_PGC"; case CallSS_FP: return "CallSS_FP"; case CallSS_VMGM_MENU: return "CallSS_VMGM_MENU"; case CallSS_VTSM: return "CallSS_VTSM"; case CallSS_VMGM_PGC: return "CallSS_VMGM_PGC"; case PlayThis: return "PlayThis"; } return "*** (bug)"; } void vm_print_link(link_t value) { char *cmd = linkcmd2str(value.command); switch(value.command) { case LinkNoLink: case LinkTopC: case LinkNextC: case LinkPrevC: case LinkTopPG: case LinkNextPG: case LinkPrevPG: case LinkTopPGC: case LinkNextPGC: case LinkPrevPGC: case LinkGoUpPGC: case LinkTailPGC: case LinkRSM: fprintf(MSG_OUT, "libdvdnav: %s (button %d)\n", cmd, value.data1); break; case LinkPGCN: case JumpTT: case JumpVTS_TT: case JumpSS_VMGM_MENU: /* == 2 -> Title Menu */ case JumpSS_VMGM_PGC: fprintf(MSG_OUT, "libdvdnav: %s %d\n", cmd, value.data1); break; case LinkPTTN: case LinkPGN: case LinkCN: fprintf(MSG_OUT, "libdvdnav: %s %d (button %d)\n", cmd, value.data1, value.data2); break; case Exit: case JumpSS_FP: case PlayThis: /* Humm.. should we have this at all.. */ fprintf(MSG_OUT, "libdvdnav: %s\n", cmd); break; case JumpVTS_PTT: fprintf(MSG_OUT, "libdvdnav: %s %d:%d\n", cmd, value.data1, value.data2); break; case JumpSS_VTSM: fprintf(MSG_OUT, "libdvdnav: %s vts %d title %d menu %d\n", cmd, value.data1, value.data2, value.data3); break; case CallSS_FP: fprintf(MSG_OUT, "libdvdnav: %s resume cell %d\n", cmd, value.data1); break; case CallSS_VMGM_MENU: /* == 2 -> Title Menu */ case CallSS_VTSM: fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2); break; case CallSS_VMGM_PGC: fprintf(MSG_OUT, "libdvdnav: %s %d resume cell %d\n", cmd, value.data1, value.data2); break; } } void vm_print_registers( registers_t *registers ) { int32_t i; fprintf(MSG_OUT, "libdvdnav: # "); for(i = 0; i < 24; i++) fprintf(MSG_OUT, " %2d |", i); fprintf(MSG_OUT, "\nlibdvdnav: SRPMS: "); for(i = 0; i < 24; i++) fprintf(MSG_OUT, "%04x|", registers->SPRM[i]); fprintf(MSG_OUT, "\nlibdvdnav: GRPMS: "); for(i = 0; i < 16; i++) fprintf(MSG_OUT, "%04x|", get_GPRM(registers, i) ); fprintf(MSG_OUT, "\nlibdvdnav: Gmode: "); for(i = 0; i < 16; i++) fprintf(MSG_OUT, "%04x|", registers->GPRM_mode[i]); fprintf(MSG_OUT, "\nlibdvdnav: Gtime: "); for(i = 0; i < 16; i++) fprintf(MSG_OUT, "%04lx|", registers->GPRM_time[i].tv_sec & 0xffff); fprintf(MSG_OUT, "\n"); } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvdnav.c�����������������������������������������������������������0000644�0001750�0001750�00000077467�14647725152�016236� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* #define LOG_DEBUG */ #include "dvdnav_internal.h" #include "read_cache.h" #include "nav_read.h" #include <stdlib.h> #include <stdio.h> #include <sys/time.h> #include "remap.h" static dvdnav_status_t dvdnav_clear(dvdnav_t * this) { /* clear everything except file, vm, mutex, readahead */ if (this->file) DVDCloseFile(this->file); this->file = NULL; memset(&this->pci,0,sizeof(this->pci)); memset(&this->dsi,0,sizeof(this->dsi)); this->last_cmd_nav_lbn = SRI_END_OF_CELL; /* Set initial values of flags */ this->position_current.still = 0; this->skip_still = 0; this->sync_wait = 0; this->sync_wait_skip = 0; this->spu_clut_changed = 0; this->started = 0; dvdnav_read_cache_clear(this->cache); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_open(dvdnav_t** dest, const char *path) { dvdnav_t *this; struct timeval time; /* Create a new structure */ fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://xine.sf.net\n", VERSION); (*dest) = NULL; this = (dvdnav_t*)malloc(sizeof(dvdnav_t)); if(!this) return DVDNAV_STATUS_ERR; memset(this, 0, (sizeof(dvdnav_t) ) ); /* Make sure this structure is clean */ pthread_mutex_init(&this->vm_lock, NULL); /* Initialise the error string */ printerr(""); /* Initialise the VM */ this->vm = vm_new_vm(); if(!this->vm) { printerr("Error initialising the DVD VM."); pthread_mutex_destroy(&this->vm_lock); free(this); return DVDNAV_STATUS_ERR; } if(!vm_reset(this->vm, path)) { printerr("Error starting the VM / opening the DVD device."); pthread_mutex_destroy(&this->vm_lock); vm_free_vm(this->vm); free(this); return DVDNAV_STATUS_ERR; } /* Set the path. FIXME: Is a deep copy 'right' */ strncpy(this->path, path, MAX_PATH_LEN); /* Pre-open and close a file so that the CSS-keys are cached. */ this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), 0, DVD_READ_MENU_VOBS); /* Start the read-ahead cache. */ this->cache = dvdnav_read_cache_new(this); /* Seed the random numbers. So that the DVD VM Command rand() * gives a different start value each time a DVD is played. */ gettimeofday(&time, NULL); srand(time.tv_usec); dvdnav_clear(this); (*dest) = this; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_close(dvdnav_t *this) { #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: close:called\n"); #endif if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } if (this->file) { DVDCloseFile(this->file); #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: close:file closing\n"); #endif this->file = NULL; } /* Free the VM */ if(this->vm) vm_free_vm(this->vm); pthread_mutex_destroy(&this->vm_lock); /* We leave the final freeing of the entire structure to the cache, * because we don't know, if there are still buffers out in the wild, * that must return first. */ if(this->cache) dvdnav_read_cache_free(this->cache); else free(this); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_reset(dvdnav_t *this) { dvdnav_status_t result; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: reset:called\n"); #endif if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: reseting vm\n"); #endif if(!vm_reset(this->vm, NULL)) { printerr("Error restarting the VM."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: clearing dvdnav\n"); #endif result = dvdnav_clear(this); pthread_mutex_unlock(&this->vm_lock); return result; } dvdnav_status_t dvdnav_path(dvdnav_t *this, const char** path) { if(!this || !path) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } (*path) = this->path; return DVDNAV_STATUS_OK; } const char* dvdnav_err_to_string(dvdnav_t *this) { if(!this) return "Hey! You gave me a NULL pointer you naughty person!"; return this->err_str; } /* converts a dvd_time_t to PTS ticks */ int64_t dvdnav_convert_time(dvd_time_t *time) { int64_t result; int64_t frames; result = (time->hour >> 4 ) * 10 * 60 * 60 * 90000; result += (time->hour & 0x0f) * 60 * 60 * 90000; result += (time->minute >> 4 ) * 10 * 60 * 90000; result += (time->minute & 0x0f) * 60 * 90000; result += (time->second >> 4 ) * 10 * 90000; result += (time->second & 0x0f) * 90000; frames = ((time->frame_u & 0x30) >> 4) * 10; frames += ((time->frame_u & 0x0f) ) ; if (time->frame_u & 0x80) result += frames * 3000; else result += frames * 3600; return result; } /* * Returns 1 if block contains NAV packet, 0 otherwise. * Processes said NAV packet if present. * * Most of the code in here is copied from xine's MPEG demuxer * so any bugs which are found in that should be corrected here also. */ static int32_t dvdnav_decode_packet(dvdnav_t *this, uint8_t *p, dsi_t *nav_dsi, pci_t *nav_pci) { int32_t bMpeg1 = 0; uint32_t nHeaderLen; uint32_t nPacketLen; uint32_t nStreamID; (void)this; if (p[3] == 0xBA) { /* program stream pack header */ int32_t nStuffingBytes; bMpeg1 = (p[4] & 0x40) == 0; if (bMpeg1) { p += 12; } else { /* mpeg2 */ nStuffingBytes = p[0xD] & 0x07; p += 14 + nStuffingBytes; } } if (p[3] == 0xbb) { /* program stream system header */ nHeaderLen = (p[4] << 8) | p[5]; p += 6 + nHeaderLen; } /* we should now have a PES packet here */ if (p[0] || p[1] || (p[2] != 1)) { fprintf(MSG_OUT, "libdvdnav: demux error! %02x %02x %02x (should be 0x000001) \n",p[0],p[1],p[2]); return 0; } nPacketLen = p[4] << 8 | p[5]; nStreamID = p[3]; nHeaderLen = 6; p += nHeaderLen; if (nStreamID == 0xbf) { /* Private stream 2 */ #if 0 int32_t i; fprintf(MSG_OUT, "libdvdnav: nav packet=%u\n",p-p_start-6); for(i=0;i<80;i++) fprintf(MSG_OUT, "%02x ",p[i-6]); fprintf(MSG_OUT, "\n"); #endif if(p[0] == 0x00) { navRead_PCI(nav_pci, p+1); } p += nPacketLen; /* We should now have a DSI packet. */ if(p[6] == 0x01) { nPacketLen = p[4] << 8 | p[5]; p += 6; navRead_DSI(nav_dsi, p+1); } return 1; } return 0; } /* DSI is used for most angle stuff. * PCI is used for only non-seemless angle stuff */ static int32_t dvdnav_get_vobu(dvdnav_t *this, dsi_t *nav_dsi, pci_t *nav_pci, dvdnav_vobu_t *vobu) { uint32_t next; int32_t angle, num_angle; vobu->vobu_start = nav_dsi->dsi_gi.nv_pck_lbn; /* Absolute offset from start of disk */ vobu->vobu_length = nav_dsi->dsi_gi.vobu_ea; /* Relative offset from vobu_start */ /* * If we're not at the end of this cell, we can determine the next * VOBU to display using the VOBU_SRI information section of the * DSI. Using this value correctly follows the current angle, * avoiding the doubled scenes in The Matrix, and makes our life * really happy. * * vobu_next is an offset value, 0x3fffffff = SRI_END_OF_CELL * DVDs are about 6 Gigs, which is only up to 0x300000 blocks * Should really assert if bit 31 != 1 */ #if 0 /* Old code -- may still be useful one day */ if(nav_dsi->vobu_sri.next_vobu != SRI_END_OF_CELL ) { vobu->vobu_next = ( nav_dsi->vobu_sri.next_vobu & 0x3fffffff ); } else { vobu->vobu_next = vobu->vobu_length; } #else /* Relative offset from vobu_start */ vobu->vobu_next = ( nav_dsi->vobu_sri.next_vobu & 0x3fffffff ); #endif vm_get_angle_info(this->vm, &angle, &num_angle); /* FIMXE: The angle reset doesn't work for some reason for the moment */ #if 0 if((num_angle < angle) && (angle != 1)) { fprintf(MSG_OUT, "libdvdnav: angle ends!\n"); /* This is to switch back to angle one when we * finish with angles. */ dvdnav_angle_change(this, 1); } #endif if(num_angle != 0) { if((next = nav_pci->nsml_agli.nsml_agl_dsta[angle-1]) != 0) { if((next & 0x3fffffff) != 0) { if(next & 0x80000000) vobu->vobu_next = - (int32_t)(next & 0x3fffffff); else vobu->vobu_next = + (int32_t)(next & 0x3fffffff); } } else if((next = nav_dsi->sml_agli.data[angle-1].address) != 0) { vobu->vobu_length = nav_dsi->sml_pbi.ilvu_ea; if((next & 0x80000000) && (next != 0x7fffffff)) vobu->vobu_next = - (int32_t)(next & 0x3fffffff); else vobu->vobu_next = + (int32_t)(next & 0x3fffffff); } } return 1; } /* * These are the main get_next_block function which actually get the media stream video and audio etc. * * There are two versions: The second one is using the zero-copy read ahead cache and therefore * hands out pointers targetting directly into the cache. * The first one uses a memcopy to fill this cache block into the application provided memory. * The benefit of this first one is that no special memory management is needed. The application is * the only one responsible of allocating and freeing the memory associated with the pointer. * The drawback is the additional memcopy. */ dvdnav_status_t dvdnav_get_next_block(dvdnav_t *this, uint8_t *buf, int32_t *event, int32_t *len) { unsigned char *block; dvdnav_status_t status; block = buf; status = dvdnav_get_next_cache_block(this, &block, event, len); if (status == DVDNAV_STATUS_OK && block != buf) { /* we received a block from the cache, copy it, so we can give it back */ memcpy(buf, block, DVD_VIDEO_LB_LEN); dvdnav_free_cache_block(this, block); } return status; } dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *this, uint8_t **buf, int32_t *event, int32_t *len) { dvd_state_t *state; int32_t result; if(!this || !event || !len || !buf || !*buf) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); if(!this->started) { /* Start the VM */ if (!vm_start(this->vm)) { printerr("Encrypted or faulty DVD"); return DVDNAV_STATUS_ERR; } this->started = 1; } state = &(this->vm->state); (*event) = DVDNAV_NOP; (*len) = 0; /* Check the STOP flag */ if(this->vm->stopped) { vm_stop(this->vm); (*event) = DVDNAV_STOP; this->started = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } vm_position_get(this->vm, &this->position_next); #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: POS-NEXT "); vm_position_print(this->vm, &this->position_next); fprintf(MSG_OUT, "libdvdnav: POS-CUR "); vm_position_print(this->vm, &this->position_current); #endif /* did we hop? */ if(this->position_current.hop_channel != this->position_next.hop_channel) { (*event) = DVDNAV_HOP_CHANNEL; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: HOP_CHANNEL\n"); #endif if (this->position_next.hop_channel - this->position_current.hop_channel >= HOP_SEEK) { int32_t num_angles = 0, current; /* we seeked -> check for multiple angles */ vm_get_angle_info(this->vm, ¤t, &num_angles); if (num_angles > 1) { int32_t result, block; /* we have to skip the first VOBU when seeking in a multiangle feature, * because it might belong to the wrong angle */ block = this->position_next.cell_start + this->position_next.block; result = dvdnav_read_cache_block(this->cache, block, 1, buf); if(result <= 0) { printerr("Error reading NAV packet."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* Decode nav into pci and dsi. Then get next VOBU info. */ if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) { printerr("Expected NAV packet but none found."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } dvdnav_get_vobu(this, &this->dsi, &this->pci, &this->vobu); /* skip to next, if there is a next */ if (this->vobu.vobu_next != SRI_END_OF_CELL) { this->vobu.vobu_start += this->vobu.vobu_next; this->vobu.vobu_next = 0; } /* update VM state */ this->vm->state.blockN = this->vobu.vobu_start - this->position_next.cell_start; } } this->position_current.hop_channel = this->position_next.hop_channel; /* update VOBU info */ this->vobu.vobu_start = this->position_next.cell_start + this->position_next.block; this->vobu.vobu_next = 0; /* Make blockN == vobu_length to do expected_nav */ this->vobu.vobu_length = 0; this->vobu.blockN = 0; this->sync_wait = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Check the HIGHLIGHT flag */ if(this->position_current.button != this->position_next.button) { dvdnav_highlight_event_t *hevent = (dvdnav_highlight_event_t *)*buf; (*event) = DVDNAV_HIGHLIGHT; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: HIGHLIGHT\n"); #endif (*len) = sizeof(dvdnav_highlight_event_t); hevent->display = 1; hevent->buttonN = this->position_next.button; this->position_current.button = this->position_next.button; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Check the WAIT flag */ if(this->sync_wait) { (*event) = DVDNAV_WAIT; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: WAIT\n"); #endif (*len) = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Check to see if we need to change the currently opened VOB */ if((this->position_current.vts != this->position_next.vts) || (this->position_current.domain != this->position_next.domain)) { dvd_read_domain_t domain; int32_t vtsN; dvdnav_vts_change_event_t *vts_event = (dvdnav_vts_change_event_t *)*buf; if(this->file) { DVDCloseFile(this->file); this->file = NULL; } vts_event->old_vtsN = this->position_current.vts; vts_event->old_domain = this->position_current.domain; /* Use the DOMAIN to find whether to open menu or title VOBs */ switch(this->position_next.domain) { case FP_DOMAIN: case VMGM_DOMAIN: domain = DVD_READ_MENU_VOBS; vtsN = 0; break; case VTSM_DOMAIN: domain = DVD_READ_MENU_VOBS; vtsN = this->position_next.vts; break; case VTS_DOMAIN: domain = DVD_READ_TITLE_VOBS; vtsN = this->position_next.vts; break; default: printerr("Unknown domain when changing VTS."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } this->position_current.vts = this->position_next.vts; this->position_current.domain = this->position_next.domain; dvdnav_read_cache_clear(this->cache); this->file = DVDOpenFile(vm_get_dvd_reader(this->vm), vtsN, domain); vts_event->new_vtsN = this->position_next.vts; vts_event->new_domain = this->position_next.domain; /* If couldn't open the file for some reason, moan */ if(this->file == NULL) { printerrf("Error opening vtsN=%i, domain=%i.", vtsN, domain); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* File opened successfully so return a VTS change event */ (*event) = DVDNAV_VTS_CHANGE; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: VTS_CHANGE\n"); #endif (*len) = sizeof(dvdnav_vts_change_event_t); this->spu_clut_changed = 1; this->position_current.cell = -1; /* Force an update */ this->position_current.spu_channel = -1; /* Force an update */ this->position_current.audio_channel = -1; /* Force an update */; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Check if the cell changed */ if( (this->position_current.cell != this->position_next.cell) || (this->position_current.cell_restart != this->position_next.cell_restart) || (this->position_current.cell_start != this->position_next.cell_start) ) { dvdnav_cell_change_event_t *cell_event = (dvdnav_cell_change_event_t *)*buf; int32_t first_cell_nr, last_cell_nr, i; dvd_state_t *state = &this->vm->state; (*event) = DVDNAV_CELL_CHANGE; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: CELL_CHANGE\n"); #endif (*len) = sizeof(dvdnav_cell_change_event_t); cell_event->cellN = state->cellN; cell_event->pgN = state->pgN; cell_event->cell_length = dvdnav_convert_time(&state->pgc->cell_playback[state->cellN-1].playback_time); cell_event->pg_length = 0; /* Find start cell of program. */ first_cell_nr = state->pgc->program_map[state->pgN-1]; /* Find end cell of program */ if(state->pgN < state->pgc->nr_of_programs) last_cell_nr = state->pgc->program_map[state->pgN] - 1; else last_cell_nr = state->pgc->nr_of_cells; for (i = first_cell_nr; i <= last_cell_nr; i++) cell_event->pg_length += dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time); cell_event->pgc_length = dvdnav_convert_time(&state->pgc->playback_time); cell_event->cell_start = 0; for (i = 1; i < state->cellN; i++) cell_event->cell_start += dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time); cell_event->pg_start = 0; for (i = 1; i < state->pgc->program_map[state->pgN-1]; i++) cell_event->pg_start += dvdnav_convert_time(&state->pgc->cell_playback[i - 1].playback_time); this->position_current.cell = this->position_next.cell; this->position_current.cell_restart = this->position_next.cell_restart; this->position_current.cell_start = this->position_next.cell_start; this->position_current.block = this->position_next.block; /* vobu info is used for mid cell resumes */ this->vobu.vobu_start = this->position_next.cell_start + this->position_next.block; this->vobu.vobu_next = 0; /* Make blockN == vobu_length to do expected_nav */ this->vobu.vobu_length = 0; this->vobu.blockN = 0; /* update the spu palette at least on PGC changes */ this->spu_clut_changed = 1; this->position_current.spu_channel = -1; /* Force an update */ this->position_current.audio_channel = -1; /* Force an update */ pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* has the CLUT changed? */ if(this->spu_clut_changed) { (*event) = DVDNAV_SPU_CLUT_CHANGE; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: SPU_CLUT_CHANGE\n"); #endif (*len) = 16 * sizeof(uint32_t); memcpy(*buf, &(state->pgc->palette), 16 * sizeof(uint32_t)); this->spu_clut_changed = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* has the SPU channel changed? */ if(this->position_current.spu_channel != this->position_next.spu_channel) { dvdnav_spu_stream_change_event_t *stream_change = (dvdnav_spu_stream_change_event_t *)*buf; (*event) = DVDNAV_SPU_STREAM_CHANGE; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE\n"); #endif (*len) = sizeof(dvdnav_spu_stream_change_event_t); stream_change->physical_wide = vm_get_subp_active_stream(this->vm, 0); stream_change->physical_letterbox = vm_get_subp_active_stream(this->vm, 1); stream_change->physical_pan_scan = vm_get_subp_active_stream(this->vm, 2); this->position_current.spu_channel = this->position_next.spu_channel; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_wide=%d\n",stream_change->physical_wide); fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_letterbox=%d\n",stream_change->physical_letterbox); fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE stream_id_pan_scan=%d\n",stream_change->physical_pan_scan); fprintf(MSG_OUT, "libdvdnav: SPU_STREAM_CHANGE returning DVDNAV_STATUS_OK\n"); #endif pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* has the audio channel changed? */ if(this->position_current.audio_channel != this->position_next.audio_channel) { dvdnav_audio_stream_change_event_t *stream_change = (dvdnav_audio_stream_change_event_t *)*buf; (*event) = DVDNAV_AUDIO_STREAM_CHANGE; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: AUDIO_STREAM_CHANGE\n"); #endif (*len) = sizeof(dvdnav_audio_stream_change_event_t); stream_change->physical = vm_get_audio_active_stream( this->vm ); this->position_current.audio_channel = this->position_next.audio_channel; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: AUDIO_STREAM_CHANGE stream_id=%d returning DVDNAV_STATUS_OK\n",stream_change->physical); #endif pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Check the STILLFRAME flag */ if(this->position_current.still != 0) { dvdnav_still_event_t *still_event = (dvdnav_still_event_t *)*buf; (*event) = DVDNAV_STILL_FRAME; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: STILL_FRAME\n"); #endif (*len) = sizeof(dvdnav_still_event_t); still_event->length = this->position_current.still; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Have we reached the end of a VOBU? */ if (this->vobu.blockN >= this->vobu.vobu_length) { /* Have we reached the end of a cell? */ if(this->vobu.vobu_next == SRI_END_OF_CELL) { /* End of Cell from NAV DSI info */ #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: Still set to %x\n", this->position_next.still); #endif this->position_current.still = this->position_next.still; /* we are about to leave a cell, so a lot of state changes could occur; * under certain conditions, the application should get in sync with us before this, * otherwise it might show stills or menus too shortly */ if ((this->position_current.still || this->pci.hli.hl_gi.hli_ss) && !this->sync_wait_skip) { this->sync_wait = 1; } else { if( this->position_current.still == 0 || this->skip_still ) { /* no active cell still -> get us to the next cell */ vm_get_next_cell(this->vm); this->position_current.still = 0; /* still gets activated at end of cell */ this->skip_still = 0; this->sync_wait_skip = 0; } } /* handle related state changes in next iteration */ (*event) = DVDNAV_NOP; (*len) = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* Perform remapping jump if necessary (this is always a * VOBU boundary). */ if (this->vm->map) { this->vobu.vobu_next = remap_block( this->vm->map, this->vm->state.domain, this->vm->state.TTN_REG, this->vm->state.pgN, this->vobu.vobu_start, this->vobu.vobu_next); } /* at the start of the next VOBU -> expecting NAV packet */ result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.vobu_next, 1, buf); if(result <= 0) { printerr("Error reading NAV packet."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* Decode nav into pci and dsi. Then get next VOBU info. */ if(!dvdnav_decode_packet(this, *buf, &this->dsi, &this->pci)) { printerr("Expected NAV packet but none found."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* We need to update the vm state->blockN with which VOBU we are in. * This is so RSM resumes to the VOBU level and not just the CELL level. */ this->vm->state.blockN = this->vobu.vobu_start - this->position_current.cell_start; dvdnav_get_vobu(this, &this->dsi, &this->pci, &this->vobu); this->vobu.blockN = 0; /* Give the cache a hint about the size of next VOBU. * This improves pre-caching, because the VOBU will almost certainly be read entirely. */ dvdnav_pre_cache_blocks(this->cache, this->vobu.vobu_start+1, this->vobu.vobu_length+1); /* release NAV menu filter, when we reach the same NAV packet again */ if (this->last_cmd_nav_lbn == this->pci.pci_gi.nv_pck_lbn) this->last_cmd_nav_lbn = SRI_END_OF_CELL; /* Successfully got a NAV packet */ (*event) = DVDNAV_NAV_PACKET; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: NAV_PACKET\n"); #endif (*len) = 2048; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } /* If we've got here, it must just be a normal block. */ if(!this->file) { printerr("Attempting to read without opening file."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } this->vobu.blockN++; result = dvdnav_read_cache_block(this->cache, this->vobu.vobu_start + this->vobu.blockN, 1, buf); if(result <= 0) { printerr("Error reading from DVD."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } (*event) = DVDNAV_BLOCK_OK; (*len) = 2048; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_get_title_string(dvdnav_t *this, const char **title_str) { if(!this || !title_str) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } (*title_str) = this->vm->dvd_name; return DVDNAV_STATUS_OK; } uint8_t dvdnav_get_video_aspect(dvdnav_t *this) { uint8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); retval = (uint8_t)vm_get_video_aspect(this->vm); pthread_mutex_unlock(&this->vm_lock); return retval; } uint8_t dvdnav_get_video_scale_permission(dvdnav_t *this) { uint8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); retval = (uint8_t)vm_get_video_scale_permission(this->vm); pthread_mutex_unlock(&this->vm_lock); return retval; } uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *this, uint8_t stream) { audio_attr_t attr; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); attr = vm_get_audio_attr(this->vm, stream); pthread_mutex_unlock(&this->vm_lock); if(attr.lang_type != 1) return 0xffff; return attr.lang_code; } uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *this, uint8_t stream) { subp_attr_t attr; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); attr = vm_get_subp_attr(this->vm, stream); pthread_mutex_unlock(&this->vm_lock); if(attr.type != 1) return 0xffff; return attr.lang_code; } int8_t dvdnav_get_audio_logical_stream(dvdnav_t *this, uint8_t audio_num) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_audio_stream(this->vm, audio_num); pthread_mutex_unlock(&this->vm_lock); return retval; } int8_t dvdnav_get_spu_logical_stream(dvdnav_t *this, uint8_t subp_num) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_subp_stream(this->vm, subp_num, 0); pthread_mutex_unlock(&this->vm_lock); return retval; } int8_t dvdnav_get_active_audio_stream(dvdnav_t *this) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_audio_active_stream(this->vm); pthread_mutex_unlock(&this->vm_lock); return retval; } int8_t dvdnav_get_active_spu_stream(dvdnav_t *this) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return -1; } retval = vm_get_subp_active_stream(this->vm, 0); pthread_mutex_unlock(&this->vm_lock); return retval; } static int8_t dvdnav_is_domain(dvdnav_t *this, domain_t domain) { int8_t retval; if(!this) { printerr("Passed a NULL pointer."); return -1; } if(!this->started) { printerr("Virtual DVD machine not started."); return -1; } pthread_mutex_lock(&this->vm_lock); retval = (this->vm->state.domain == domain); pthread_mutex_unlock(&this->vm_lock); return retval; } /* First Play domain. (Menu) */ int8_t dvdnav_is_domain_fp(dvdnav_t *this) { return dvdnav_is_domain(this, FP_DOMAIN); } /* Video management Menu domain. (Menu) */ int8_t dvdnav_is_domain_vmgm(dvdnav_t *this) { return dvdnav_is_domain(this, VMGM_DOMAIN); } /* Video Title Menu domain (Menu) */ int8_t dvdnav_is_domain_vtsm(dvdnav_t *this) { return dvdnav_is_domain(this, VTSM_DOMAIN); } /* Video Title domain (playing movie). */ int8_t dvdnav_is_domain_vts(dvdnav_t *this) { return dvdnav_is_domain(this, VTS_DOMAIN); } /* Generally delegate angle information handling to VM */ dvdnav_status_t dvdnav_angle_change(dvdnav_t *this, int32_t angle) { int32_t num, current; if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); vm_get_angle_info(this->vm, ¤t, &num); /* Set angle SPRM if valid */ if((angle > 0) && (angle <= num)) { this->vm->state.AGL_REG = angle; } else { printerr("Passed an invalid angle number."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *this, int32_t *current_angle, int32_t *number_of_angles) { if(!this || !current_angle || !number_of_angles) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); vm_get_angle_info(this->vm, current_angle, number_of_angles); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } pci_t* dvdnav_get_current_nav_pci(dvdnav_t *this) { if(!this) return 0; return &this->pci; } dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *this) { if(!this) return 0; return &this->dsi; } uint32_t dvdnav_get_next_still_flag(dvdnav_t *this) { if(!this) return -1; return this->position_next.still; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/ifo_read.c���������������������������������������������������������0000644�0001750�0001750�00000157667�14647725152�016525� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001, 2002, 2003 * Björn Englund <d4bjorn@dtek.chalmers.se>, * Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include <string.h> #include "bswap.h" #include "ifo_types.h" #include "ifo_read.h" #include "dvd_reader.h" #include "dvdread_internal.h" #ifndef DVD_BLOCK_LEN #define DVD_BLOCK_LEN 2048 #endif #ifndef NDEBUG #define CHECK_ZERO0(arg) \ if(arg != 0) { \ fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x%x\n", \ __FILE__, __LINE__, # arg, arg); \ } #define CHECK_ZERO(arg) \ if(memcmp(my_friendly_zeros, &arg, sizeof(arg))) { \ unsigned int i_CZ; \ fprintf(stderr, "*** Zero check failed in %s:%i\n for %s = 0x", \ __FILE__, __LINE__, # arg ); \ for(i_CZ = 0; i_CZ < sizeof(arg); i_CZ++) \ fprintf(stderr, "%02x", *((uint8_t *)&arg + i_CZ)); \ fprintf(stderr, "\n"); \ } static const uint8_t my_friendly_zeros[2048]; #else #define CHECK_ZERO0(arg) (void)(arg) #define CHECK_ZERO(arg) (void)(arg) #endif /* Prototypes for internal functions */ static int ifoRead_VMG(ifo_handle_t *ifofile); static int ifoRead_VTS(ifo_handle_t *ifofile); static int ifoRead_PGC(ifo_handle_t *ifofile, pgc_t *pgc, unsigned int offset); static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile, pgc_command_tbl_t *cmd_tbl, unsigned int offset); static int ifoRead_PGC_PROGRAM_MAP(ifo_handle_t *ifofile, pgc_program_map_t *program_map, unsigned int nr, unsigned int offset); static int ifoRead_CELL_PLAYBACK_TBL(ifo_handle_t *ifofile, cell_playback_t *cell_playback, unsigned int nr, unsigned int offset); static int ifoRead_CELL_POSITION_TBL(ifo_handle_t *ifofile, cell_position_t *cell_position, unsigned int nr, unsigned int offset); static int ifoRead_VTS_ATTRIBUTES(ifo_handle_t *ifofile, vts_attributes_t *vts_attributes, unsigned int offset); static int ifoRead_C_ADT_internal(ifo_handle_t *ifofile, c_adt_t *c_adt, unsigned int sector); static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile, vobu_admap_t *vobu_admap, unsigned int sector); static int ifoRead_PGCIT_internal(ifo_handle_t *ifofile, pgcit_t *pgcit, unsigned int offset); static void ifoFree_PGC(pgc_t *pgc); static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl); static void ifoFree_PGCIT_internal(pgcit_t *pgcit); static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) { return (DVDFileSeek(dvd_file, (int)offset) == (int)offset); } static inline int32_t DVDFileSeekForce_( dvd_file_t *dvd_file, uint32_t offset, int force_size ) { return (DVDFileSeekForce(dvd_file, (int)offset, force_size) == (int)offset); } ifo_handle_t *ifoOpen(dvd_reader_t *dvd, int title) { ifo_handle_t *ifofile; ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t)); if(!ifofile) return 0; memset(ifofile, 0, sizeof(ifo_handle_t)); ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE); if(!ifofile->file) /* Should really catch any error and try to fallback */ ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE); if(!ifofile->file) { if(title) { fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title); } else { fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n"); } free(ifofile); return 0; } /* First check if this is a VMGI file. */ if(ifoRead_VMG(ifofile)) { /* These are both mandatory. */ if(!ifoRead_FP_PGC(ifofile) || !ifoRead_TT_SRPT(ifofile)) { fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO).\n"); ifoClose(ifofile); return 0; } ifoRead_PGCI_UT(ifofile); ifoRead_PTL_MAIT(ifofile); /* This is also mandatory. */ if(!ifoRead_VTS_ATRT(ifofile)) { fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO).\n"); ifoClose(ifofile); return 0; } ifoRead_TXTDT_MGI(ifofile); ifoRead_C_ADT(ifofile); ifoRead_VOBU_ADMAP(ifofile); return ifofile; } if(ifoRead_VTS(ifofile)) { if(!ifoRead_VTS_PTT_SRPT(ifofile) || !ifoRead_PGCIT(ifofile)) { fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n", title); ifoClose(ifofile); return 0; } ifoRead_PGCI_UT(ifofile); ifoRead_VTS_TMAPT(ifofile); ifoRead_C_ADT(ifofile); ifoRead_VOBU_ADMAP(ifofile); if(!ifoRead_TITLE_C_ADT(ifofile) || !ifoRead_TITLE_VOBU_ADMAP(ifofile)) { fprintf(stderr, "libdvdread: Invalid title IFO (VTS_%02d_0.IFO).\n", title); ifoClose(ifofile); return 0; } return ifofile; } if(title) { fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.IFO).\n", title, title); } else { fprintf(stderr, "libdvdread: Invalid IFO for VMGM (VIDEO_TS.IFO).\n"); } ifoClose(ifofile); return 0; } ifo_handle_t *ifoOpenVMGI(dvd_reader_t *dvd) { ifo_handle_t *ifofile; ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t)); if(!ifofile) return 0; memset(ifofile, 0, sizeof(ifo_handle_t)); ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_FILE); if(!ifofile->file) /* Should really catch any error and try to fallback */ ifofile->file = DVDOpenFile(dvd, 0, DVD_READ_INFO_BACKUP_FILE); if(!ifofile->file) { fprintf(stderr, "libdvdread: Can't open file VIDEO_TS.IFO.\n"); free(ifofile); return 0; } if(ifoRead_VMG(ifofile)) return ifofile; fprintf(stderr, "libdvdread: Invalid main menu IFO (VIDEO_TS.IFO).\n"); ifoClose(ifofile); return 0; } ifo_handle_t *ifoOpenVTSI(dvd_reader_t *dvd, int title) { ifo_handle_t *ifofile; ifofile = (ifo_handle_t *)malloc(sizeof(ifo_handle_t)); if(!ifofile) return 0; memset(ifofile, 0, sizeof(ifo_handle_t)); if(title <= 0 || title > 99) { fprintf(stderr, "libdvdread: ifoOpenVTSI invalid title (%d).\n", title); free(ifofile); return 0; } ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_FILE); if(!ifofile->file) /* Should really catch any error and try to fallback */ ifofile->file = DVDOpenFile(dvd, title, DVD_READ_INFO_BACKUP_FILE); if(!ifofile->file) { fprintf(stderr, "libdvdread: Can't open file VTS_%02d_0.IFO.\n", title); free(ifofile); return 0; } ifoRead_VTS(ifofile); if(ifofile->vtsi_mat) return ifofile; fprintf(stderr, "libdvdread: Invalid IFO for title %d (VTS_%02d_0.IFO).\n", title, title); ifoClose(ifofile); return 0; } void ifoClose(ifo_handle_t *ifofile) { if(!ifofile) return; ifoFree_VOBU_ADMAP(ifofile); ifoFree_TITLE_VOBU_ADMAP(ifofile); ifoFree_C_ADT(ifofile); ifoFree_TITLE_C_ADT(ifofile); ifoFree_TXTDT_MGI(ifofile); ifoFree_VTS_ATRT(ifofile); ifoFree_PTL_MAIT(ifofile); ifoFree_PGCI_UT(ifofile); ifoFree_TT_SRPT(ifofile); ifoFree_FP_PGC(ifofile); ifoFree_PGCIT(ifofile); ifoFree_VTS_PTT_SRPT(ifofile); if(ifofile->vmgi_mat) free(ifofile->vmgi_mat); if(ifofile->vtsi_mat) free(ifofile->vtsi_mat); DVDCloseFile(ifofile->file); ifofile->file = 0; free(ifofile); ifofile = 0; } static int ifoRead_VMG(ifo_handle_t *ifofile) { vmgi_mat_t *vmgi_mat; vmgi_mat = (vmgi_mat_t *)malloc(sizeof(vmgi_mat_t)); if(!vmgi_mat) return 0; ifofile->vmgi_mat = vmgi_mat; if(!DVDFileSeek_(ifofile->file, 0)) { free(ifofile->vmgi_mat); ifofile->vmgi_mat = 0; return 0; } if(!DVDReadBytes(ifofile->file, vmgi_mat, sizeof(vmgi_mat_t))) { free(ifofile->vmgi_mat); ifofile->vmgi_mat = 0; return 0; } if(strncmp("DVDVIDEO-VMG", vmgi_mat->vmg_identifier, 12) != 0) { free(ifofile->vmgi_mat); ifofile->vmgi_mat = 0; return 0; } B2N_32(vmgi_mat->vmg_last_sector); B2N_32(vmgi_mat->vmgi_last_sector); B2N_32(vmgi_mat->vmg_category); B2N_16(vmgi_mat->vmg_nr_of_volumes); B2N_16(vmgi_mat->vmg_this_volume_nr); B2N_16(vmgi_mat->vmg_nr_of_title_sets); B2N_64(vmgi_mat->vmg_pos_code); B2N_32(vmgi_mat->vmgi_last_byte); B2N_32(vmgi_mat->first_play_pgc); B2N_32(vmgi_mat->vmgm_vobs); B2N_32(vmgi_mat->tt_srpt); B2N_32(vmgi_mat->vmgm_pgci_ut); B2N_32(vmgi_mat->ptl_mait); B2N_32(vmgi_mat->vts_atrt); B2N_32(vmgi_mat->txtdt_mgi); B2N_32(vmgi_mat->vmgm_c_adt); B2N_32(vmgi_mat->vmgm_vobu_admap); B2N_16(vmgi_mat->vmgm_audio_attr.lang_code); B2N_16(vmgi_mat->vmgm_subp_attr.lang_code); CHECK_ZERO(vmgi_mat->zero_1); CHECK_ZERO(vmgi_mat->zero_2); CHECK_ZERO(vmgi_mat->zero_3); CHECK_ZERO(vmgi_mat->zero_4); CHECK_ZERO(vmgi_mat->zero_5); CHECK_ZERO(vmgi_mat->zero_6); CHECK_ZERO(vmgi_mat->zero_7); CHECK_ZERO(vmgi_mat->zero_8); CHECK_ZERO(vmgi_mat->zero_9); CHECK_ZERO(vmgi_mat->zero_10); CHECK_VALUE(vmgi_mat->vmg_last_sector != 0); CHECK_VALUE(vmgi_mat->vmgi_last_sector != 0); CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector); CHECK_VALUE(vmgi_mat->vmgi_last_sector * 2 <= vmgi_mat->vmg_last_sector); CHECK_VALUE(vmgi_mat->vmg_nr_of_volumes != 0); CHECK_VALUE(vmgi_mat->vmg_this_volume_nr != 0); CHECK_VALUE(vmgi_mat->vmg_this_volume_nr <= vmgi_mat->vmg_nr_of_volumes); CHECK_VALUE(vmgi_mat->disc_side == 1 || vmgi_mat->disc_side == 2); CHECK_VALUE(vmgi_mat->vmg_nr_of_title_sets != 0); CHECK_VALUE(vmgi_mat->vmgi_last_byte >= 341); CHECK_VALUE(vmgi_mat->vmgi_last_byte / DVD_BLOCK_LEN <= vmgi_mat->vmgi_last_sector); /* It seems that first_play_pgc is optional. */ CHECK_VALUE(vmgi_mat->first_play_pgc < vmgi_mat->vmgi_last_byte); CHECK_VALUE(vmgi_mat->vmgm_vobs == 0 || (vmgi_mat->vmgm_vobs > vmgi_mat->vmgi_last_sector && vmgi_mat->vmgm_vobs < vmgi_mat->vmg_last_sector)); CHECK_VALUE(vmgi_mat->tt_srpt <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vmgm_pgci_ut <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->ptl_mait <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vts_atrt <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->txtdt_mgi <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vmgm_c_adt <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->vmgm_vobu_admap <= vmgi_mat->vmgi_last_sector); CHECK_VALUE(vmgi_mat->nr_of_vmgm_audio_streams <= 1); CHECK_VALUE(vmgi_mat->nr_of_vmgm_subp_streams <= 1); return 1; } static int ifoRead_VTS(ifo_handle_t *ifofile) { vtsi_mat_t *vtsi_mat; int i; vtsi_mat = (vtsi_mat_t *)malloc(sizeof(vtsi_mat_t)); if(!vtsi_mat) return 0; ifofile->vtsi_mat = vtsi_mat; if(!DVDFileSeek_(ifofile->file, 0)) { free(ifofile->vtsi_mat); ifofile->vtsi_mat = 0; return 0; } if(!(DVDReadBytes(ifofile->file, vtsi_mat, sizeof(vtsi_mat_t)))) { free(ifofile->vtsi_mat); ifofile->vtsi_mat = 0; return 0; } if(strncmp("DVDVIDEO-VTS", vtsi_mat->vts_identifier, 12) != 0) { free(ifofile->vtsi_mat); ifofile->vtsi_mat = 0; return 0; } B2N_32(vtsi_mat->vts_last_sector); B2N_32(vtsi_mat->vtsi_last_sector); B2N_32(vtsi_mat->vts_category); B2N_32(vtsi_mat->vtsi_last_byte); B2N_32(vtsi_mat->vtsm_vobs); B2N_32(vtsi_mat->vtstt_vobs); B2N_32(vtsi_mat->vts_ptt_srpt); B2N_32(vtsi_mat->vts_pgcit); B2N_32(vtsi_mat->vtsm_pgci_ut); B2N_32(vtsi_mat->vts_tmapt); B2N_32(vtsi_mat->vtsm_c_adt); B2N_32(vtsi_mat->vtsm_vobu_admap); B2N_32(vtsi_mat->vts_c_adt); B2N_32(vtsi_mat->vts_vobu_admap); B2N_16(vtsi_mat->vtsm_audio_attr.lang_code); B2N_16(vtsi_mat->vtsm_subp_attr.lang_code); for(i = 0; i < 8; i++) B2N_16(vtsi_mat->vts_audio_attr[i].lang_code); for(i = 0; i < 32; i++) B2N_16(vtsi_mat->vts_subp_attr[i].lang_code); CHECK_ZERO(vtsi_mat->zero_1); CHECK_ZERO(vtsi_mat->zero_2); CHECK_ZERO(vtsi_mat->zero_3); CHECK_ZERO(vtsi_mat->zero_4); CHECK_ZERO(vtsi_mat->zero_5); CHECK_ZERO(vtsi_mat->zero_6); CHECK_ZERO(vtsi_mat->zero_7); CHECK_ZERO(vtsi_mat->zero_8); CHECK_ZERO(vtsi_mat->zero_9); CHECK_ZERO(vtsi_mat->zero_10); CHECK_ZERO(vtsi_mat->zero_11); CHECK_ZERO(vtsi_mat->zero_12); CHECK_ZERO(vtsi_mat->zero_13); CHECK_ZERO(vtsi_mat->zero_14); CHECK_ZERO(vtsi_mat->zero_15); CHECK_ZERO(vtsi_mat->zero_16); CHECK_ZERO(vtsi_mat->zero_17); CHECK_ZERO(vtsi_mat->zero_18); CHECK_ZERO(vtsi_mat->zero_19); CHECK_ZERO(vtsi_mat->zero_20); CHECK_ZERO(vtsi_mat->zero_21); CHECK_VALUE(vtsi_mat->vtsi_last_sector*2 <= vtsi_mat->vts_last_sector); CHECK_VALUE(vtsi_mat->vtsi_last_byte/DVD_BLOCK_LEN <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_vobs == 0 || (vtsi_mat->vtsm_vobs > vtsi_mat->vtsi_last_sector && vtsi_mat->vtsm_vobs < vtsi_mat->vts_last_sector)); CHECK_VALUE(vtsi_mat->vtstt_vobs == 0 || (vtsi_mat->vtstt_vobs > vtsi_mat->vtsi_last_sector && vtsi_mat->vtstt_vobs < vtsi_mat->vts_last_sector)); CHECK_VALUE(vtsi_mat->vts_ptt_srpt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_pgcit <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_pgci_ut <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_tmapt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_c_adt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vtsm_vobu_admap <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_c_adt <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->vts_vobu_admap <= vtsi_mat->vtsi_last_sector); CHECK_VALUE(vtsi_mat->nr_of_vtsm_audio_streams <= 1); CHECK_VALUE(vtsi_mat->nr_of_vtsm_subp_streams <= 1); CHECK_VALUE(vtsi_mat->nr_of_vts_audio_streams <= 8); for(i = vtsi_mat->nr_of_vts_audio_streams; i < 8; i++) CHECK_ZERO(vtsi_mat->vts_audio_attr[i]); CHECK_VALUE(vtsi_mat->nr_of_vts_subp_streams <= 32); for(i = vtsi_mat->nr_of_vts_subp_streams; i < 32; i++) CHECK_ZERO(vtsi_mat->vts_subp_attr[i]); for(i = 0; i < 8; i++) { CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero1); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero2); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero3); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero4); CHECK_ZERO0(vtsi_mat->vts_mu_audio_attr[i].zero5); CHECK_ZERO(vtsi_mat->vts_mu_audio_attr[i].zero6); } return 1; } static int ifoRead_PGC_COMMAND_TBL(ifo_handle_t *ifofile, pgc_command_tbl_t *cmd_tbl, unsigned int offset) { memset(cmd_tbl, 0, sizeof(pgc_command_tbl_t)); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, cmd_tbl, PGC_COMMAND_TBL_SIZE))) return 0; B2N_16(cmd_tbl->nr_of_pre); B2N_16(cmd_tbl->nr_of_post); B2N_16(cmd_tbl->nr_of_cell); CHECK_VALUE(cmd_tbl->nr_of_pre + cmd_tbl->nr_of_post + cmd_tbl->nr_of_cell<= 255); if(cmd_tbl->nr_of_pre != 0) { unsigned int pre_cmds_size = cmd_tbl->nr_of_pre * COMMAND_DATA_SIZE; cmd_tbl->pre_cmds = (vm_cmd_t *)malloc(pre_cmds_size); if(!cmd_tbl->pre_cmds) return 0; if(!(DVDReadBytes(ifofile->file, cmd_tbl->pre_cmds, pre_cmds_size))) { free(cmd_tbl->pre_cmds); return 0; } } if(cmd_tbl->nr_of_post != 0) { unsigned int post_cmds_size = cmd_tbl->nr_of_post * COMMAND_DATA_SIZE; cmd_tbl->post_cmds = (vm_cmd_t *)malloc(post_cmds_size); if(!cmd_tbl->post_cmds) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); return 0; } if(!(DVDReadBytes(ifofile->file, cmd_tbl->post_cmds, post_cmds_size))) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); free(cmd_tbl->post_cmds); return 0; } } if(cmd_tbl->nr_of_cell != 0) { unsigned int cell_cmds_size = cmd_tbl->nr_of_cell * COMMAND_DATA_SIZE; cmd_tbl->cell_cmds = (vm_cmd_t *)malloc(cell_cmds_size); if(!cmd_tbl->cell_cmds) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); if(cmd_tbl->post_cmds) free(cmd_tbl->post_cmds); return 0; } if(!(DVDReadBytes(ifofile->file, cmd_tbl->cell_cmds, cell_cmds_size))) { if(cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); if(cmd_tbl->post_cmds) free(cmd_tbl->post_cmds); free(cmd_tbl->cell_cmds); return 0; } } /* * Make a run over all the commands and see that we can interpret them all? */ return 1; } static void ifoFree_PGC_COMMAND_TBL(pgc_command_tbl_t *cmd_tbl) { if(cmd_tbl) { if(cmd_tbl->nr_of_pre && cmd_tbl->pre_cmds) free(cmd_tbl->pre_cmds); if(cmd_tbl->nr_of_post && cmd_tbl->post_cmds) free(cmd_tbl->post_cmds); if(cmd_tbl->nr_of_cell && cmd_tbl->cell_cmds) free(cmd_tbl->cell_cmds); free(cmd_tbl); } } static int ifoRead_PGC_PROGRAM_MAP(ifo_handle_t *ifofile, pgc_program_map_t *program_map, unsigned int nr, unsigned int offset) { unsigned int size = nr * sizeof(pgc_program_map_t); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, program_map, size))) return 0; return 1; } static int ifoRead_CELL_PLAYBACK_TBL(ifo_handle_t *ifofile, cell_playback_t *cell_playback, unsigned int nr, unsigned int offset) { unsigned int i; unsigned int size = nr * sizeof(cell_playback_t); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, cell_playback, size))) return 0; for(i = 0; i < nr; i++) { B2N_32(cell_playback[i].first_sector); B2N_32(cell_playback[i].first_ilvu_end_sector); B2N_32(cell_playback[i].last_vobu_start_sector); B2N_32(cell_playback[i].last_sector); /* Changed < to <= because this was false in the movie 'Pi'. */ CHECK_VALUE(cell_playback[i].last_vobu_start_sector <= cell_playback[i].last_sector); CHECK_VALUE(cell_playback[i].first_sector <= cell_playback[i].last_vobu_start_sector); } return 1; } static int ifoRead_CELL_POSITION_TBL(ifo_handle_t *ifofile, cell_position_t *cell_position, unsigned int nr, unsigned int offset) { unsigned int i; unsigned int size = nr * sizeof(cell_position_t); if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, cell_position, size))) return 0; for(i = 0; i < nr; i++) { B2N_16(cell_position[i].vob_id_nr); CHECK_ZERO(cell_position[i].zero_1); } return 1; } static int ifoRead_PGC(ifo_handle_t *ifofile, pgc_t *pgc, unsigned int offset) { unsigned int i; if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, pgc, PGC_SIZE))) return 0; B2N_16(pgc->next_pgc_nr); B2N_16(pgc->prev_pgc_nr); B2N_16(pgc->goup_pgc_nr); B2N_16(pgc->command_tbl_offset); B2N_16(pgc->program_map_offset); B2N_16(pgc->cell_playback_offset); B2N_16(pgc->cell_position_offset); for(i = 0; i < 8; i++) B2N_16(pgc->audio_control[i]); for(i = 0; i < 32; i++) B2N_32(pgc->subp_control[i]); for(i = 0; i < 16; i++) B2N_32(pgc->palette[i]); CHECK_ZERO(pgc->zero_1); CHECK_VALUE(pgc->nr_of_programs <= pgc->nr_of_cells); /* verify time (look at print_time) */ for(i = 0; i < 8; i++) if(!(pgc->audio_control[i] & 0x8000)) /* The 'is present' bit */ CHECK_ZERO(pgc->audio_control[i]); for(i = 0; i < 32; i++) if(!(pgc->subp_control[i] & 0x80000000)) /* The 'is present' bit */ CHECK_ZERO(pgc->subp_control[i]); /* Check that time is 0:0:0:0 also if nr_of_programs == 0 */ if(pgc->nr_of_programs == 0) { CHECK_ZERO(pgc->still_time); CHECK_ZERO(pgc->pg_playback_mode); /* ?? */ CHECK_VALUE(pgc->program_map_offset == 0); CHECK_VALUE(pgc->cell_playback_offset == 0); CHECK_VALUE(pgc->cell_position_offset == 0); } else { CHECK_VALUE(pgc->program_map_offset != 0); CHECK_VALUE(pgc->cell_playback_offset != 0); CHECK_VALUE(pgc->cell_position_offset != 0); } if(pgc->command_tbl_offset != 0) { pgc->command_tbl = malloc(sizeof(pgc_command_tbl_t)); if(!pgc->command_tbl) return 0; if(!ifoRead_PGC_COMMAND_TBL(ifofile, pgc->command_tbl, offset + pgc->command_tbl_offset)) { free(pgc->command_tbl); return 0; } } else { pgc->command_tbl = NULL; } if(pgc->program_map_offset != 0 && pgc->nr_of_programs>0) { pgc->program_map = malloc(pgc->nr_of_programs * sizeof(pgc_program_map_t)); if(!pgc->program_map) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); return 0; } if(!ifoRead_PGC_PROGRAM_MAP(ifofile, pgc->program_map,pgc->nr_of_programs, offset + pgc->program_map_offset)) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); free(pgc->program_map); return 0; } } else { pgc->program_map = NULL; } if(pgc->cell_playback_offset != 0 && pgc->nr_of_cells>0) { pgc->cell_playback = malloc(pgc->nr_of_cells * sizeof(cell_playback_t)); if(!pgc->cell_playback) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); if(pgc->program_map) free(pgc->program_map); return 0; } if(!ifoRead_CELL_PLAYBACK_TBL(ifofile, pgc->cell_playback, pgc->nr_of_cells, offset + pgc->cell_playback_offset)) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); if(pgc->program_map) free(pgc->program_map); free(pgc->cell_playback); return 0; } } else { pgc->cell_playback = NULL; } if(pgc->cell_position_offset != 0 && pgc->nr_of_cells>0) { pgc->cell_position = malloc(pgc->nr_of_cells * sizeof(cell_position_t)); if(!pgc->cell_position) { ifoFree_PGC(pgc); return 0; } if(!ifoRead_CELL_POSITION_TBL(ifofile, pgc->cell_position, pgc->nr_of_cells, offset + pgc->cell_position_offset)) { ifoFree_PGC(pgc); return 0; } } else { pgc->cell_position = NULL; } return 1; } int ifoRead_FP_PGC(ifo_handle_t *ifofile) { if(!ifofile) return 0; if(!ifofile->vmgi_mat) return 0; /* It seems that first_play_pgc is optional after all. */ ifofile->first_play_pgc = 0; if(ifofile->vmgi_mat->first_play_pgc == 0) return 1; ifofile->first_play_pgc = (pgc_t *)malloc(sizeof(pgc_t)); if(!ifofile->first_play_pgc) return 0; if(!ifoRead_PGC(ifofile, ifofile->first_play_pgc, ifofile->vmgi_mat->first_play_pgc)) { free(ifofile->first_play_pgc); ifofile->first_play_pgc = 0; return 0; } return 1; } static void ifoFree_PGC(pgc_t *pgc) { if(pgc) { ifoFree_PGC_COMMAND_TBL(pgc->command_tbl); if(pgc->program_map) free(pgc->program_map); if(pgc->cell_playback) free(pgc->cell_playback); if(pgc->cell_position) free(pgc->cell_position); } } void ifoFree_FP_PGC(ifo_handle_t *ifofile) { if(!ifofile) return; if(ifofile->first_play_pgc) { ifoFree_PGC(ifofile->first_play_pgc); free(ifofile->first_play_pgc); ifofile->first_play_pgc = 0; } } int ifoRead_TT_SRPT(ifo_handle_t *ifofile) { tt_srpt_t *tt_srpt; int i, info_length; if(!ifofile) return 0; if(!ifofile->vmgi_mat) return 0; if(ifofile->vmgi_mat->tt_srpt == 0) /* mandatory */ return 0; if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->tt_srpt * DVD_BLOCK_LEN)) return 0; tt_srpt = (tt_srpt_t *)malloc(sizeof(tt_srpt_t)); if(!tt_srpt) return 0; ifofile->tt_srpt = tt_srpt; if(!(DVDReadBytes(ifofile->file, tt_srpt, TT_SRPT_SIZE))) { fprintf(stderr, "libdvdread: Unable to read read TT_SRPT.\n"); free(tt_srpt); return 0; } B2N_16(tt_srpt->nr_of_srpts); B2N_32(tt_srpt->last_byte); info_length = tt_srpt->last_byte + 1 - TT_SRPT_SIZE; tt_srpt->title = (title_info_t *)malloc(info_length); if(!tt_srpt->title) { free(tt_srpt); ifofile->tt_srpt = 0; return 0; } if(!(DVDReadBytes(ifofile->file, tt_srpt->title, info_length))) { fprintf(stderr, "libdvdread: Unable to read read TT_SRPT.\n"); ifoFree_TT_SRPT(ifofile); return 0; } for(i = 0; i < tt_srpt->nr_of_srpts; i++) { B2N_16(tt_srpt->title[i].nr_of_ptts); B2N_16(tt_srpt->title[i].parental_id); B2N_32(tt_srpt->title[i].title_set_sector); } CHECK_ZERO(tt_srpt->zero_1); CHECK_VALUE(tt_srpt->nr_of_srpts != 0); CHECK_VALUE(tt_srpt->nr_of_srpts < 100); /* ?? */ CHECK_VALUE((int)tt_srpt->nr_of_srpts * (int)sizeof(title_info_t) <= info_length); for(i = 0; i < tt_srpt->nr_of_srpts; i++) { CHECK_VALUE(tt_srpt->title[i].pb_ty.zero_1 == 0); CHECK_VALUE(tt_srpt->title[i].nr_of_angles != 0); CHECK_VALUE(tt_srpt->title[i].nr_of_angles < 10); /* CHECK_VALUE(tt_srpt->title[i].nr_of_ptts != 0); */ /* XXX: this assertion breaks Ghostbusters: */ CHECK_VALUE(tt_srpt->title[i].nr_of_ptts < 1000); /* ?? */ CHECK_VALUE(tt_srpt->title[i].title_set_nr != 0); CHECK_VALUE(tt_srpt->title[i].title_set_nr < 100); /* ?? */ CHECK_VALUE(tt_srpt->title[i].vts_ttn != 0); CHECK_VALUE(tt_srpt->title[i].vts_ttn < 100); /* ?? */ /* CHECK_VALUE(tt_srpt->title[i].title_set_sector != 0); */ } /* Make this a function */ #if 0 if(memcmp((uint8_t *)tt_srpt->title + tt_srpt->nr_of_srpts * sizeof(title_info_t), my_friendly_zeros, info_length - tt_srpt->nr_of_srpts * sizeof(title_info_t))) { fprintf(stderr, "VMG_PTT_SRPT slack is != 0, "); hexdump((uint8_t *)tt_srpt->title + tt_srpt->nr_of_srpts * sizeof(title_info_t), info_length - tt_srpt->nr_of_srpts * sizeof(title_info_t)); } #endif return 1; } void ifoFree_TT_SRPT(ifo_handle_t *ifofile) { if(!ifofile) return; if(ifofile->tt_srpt) { free(ifofile->tt_srpt->title); free(ifofile->tt_srpt); ifofile->tt_srpt = 0; } } int ifoRead_VTS_PTT_SRPT(ifo_handle_t *ifofile) { vts_ptt_srpt_t *vts_ptt_srpt; int info_length, i, j; uint32_t *data; if(!ifofile) return 0; if(!ifofile->vtsi_mat) return 0; if(ifofile->vtsi_mat->vts_ptt_srpt == 0) /* mandatory */ return 0; if(!DVDFileSeek_(ifofile->file, ifofile->vtsi_mat->vts_ptt_srpt * DVD_BLOCK_LEN)) return 0; vts_ptt_srpt = (vts_ptt_srpt_t *)malloc(sizeof(vts_ptt_srpt_t)); if(!vts_ptt_srpt) return 0; ifofile->vts_ptt_srpt = vts_ptt_srpt; if(!(DVDReadBytes(ifofile->file, vts_ptt_srpt, VTS_PTT_SRPT_SIZE))) { fprintf(stderr, "libdvdread: Unable to read PTT search table.\n"); free(vts_ptt_srpt); return 0; } B2N_16(vts_ptt_srpt->nr_of_srpts); B2N_32(vts_ptt_srpt->last_byte); CHECK_ZERO(vts_ptt_srpt->zero_1); CHECK_VALUE(vts_ptt_srpt->nr_of_srpts != 0); CHECK_VALUE(vts_ptt_srpt->nr_of_srpts < 100); /* ?? */ info_length = vts_ptt_srpt->last_byte + 1 - VTS_PTT_SRPT_SIZE; data = (uint32_t *)malloc(info_length); if(!data) { free(vts_ptt_srpt); ifofile->vts_ptt_srpt = 0; return 0; } if(!(DVDReadBytes(ifofile->file, data, info_length))) { fprintf(stderr, "libdvdread: Unable to read PTT search table.\n"); free(vts_ptt_srpt); free(data); ifofile->vts_ptt_srpt = 0; return 0; } for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) { B2N_32(data[i]); /* assert(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1); Magic Knight Rayearth Daybreak is mastered very strange and has Titles with 0 PTTs. They all have a data[i] offsets beyond the end of of the vts_ptt_srpt structure. */ CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1 + 4); } vts_ptt_srpt->ttu_offset = data; vts_ptt_srpt->title = malloc(vts_ptt_srpt->nr_of_srpts * sizeof(ttu_t)); if(!vts_ptt_srpt->title) { free(vts_ptt_srpt); free(data); ifofile->vts_ptt_srpt = 0; return 0; } for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) { int n; if(i < vts_ptt_srpt->nr_of_srpts - 1) n = (data[i+1] - data[i]); else n = (vts_ptt_srpt->last_byte + 1 - data[i]); /* assert(n > 0 && (n % 4) == 0); Magic Knight Rayearth Daybreak is mastered very strange and has Titles with 0 PTTs. */ if(n < 0) n = 0; CHECK_VALUE(n % 4 == 0); vts_ptt_srpt->title[i].nr_of_ptts = n / 4; vts_ptt_srpt->title[i].ptt = malloc(n * sizeof(ptt_info_t)); if(!vts_ptt_srpt->title[i].ptt) { for(n = 0; n < i; n++) free(vts_ptt_srpt->title[n].ptt); free(vts_ptt_srpt); free(data); ifofile->vts_ptt_srpt = 0; return 0; } for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) { /* The assert placed here because of Magic Knight Rayearth Daybreak */ CHECK_VALUE(data[i] + sizeof(ptt_info_t) <= vts_ptt_srpt->last_byte + 1); vts_ptt_srpt->title[i].ptt[j].pgcn = *(uint16_t*)(((char *)data) + data[i] + 4*j - VTS_PTT_SRPT_SIZE); vts_ptt_srpt->title[i].ptt[j].pgn = *(uint16_t*)(((char *)data) + data[i] + 4*j + 2 - VTS_PTT_SRPT_SIZE); } } for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) { for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) { B2N_16(vts_ptt_srpt->title[i].ptt[j].pgcn); B2N_16(vts_ptt_srpt->title[i].ptt[j].pgn); } } for(i = 0; i < vts_ptt_srpt->nr_of_srpts; i++) { CHECK_VALUE(vts_ptt_srpt->title[i].nr_of_ptts < 1000); /* ?? */ for(j = 0; j < vts_ptt_srpt->title[i].nr_of_ptts; j++) { CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn != 0 ); CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgcn < 1000); /* ?? */ CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn != 0); CHECK_VALUE(vts_ptt_srpt->title[i].ptt[j].pgn < 100); /* ?? */ } } return 1; } void ifoFree_VTS_PTT_SRPT(ifo_handle_t *ifofile) { if(!ifofile) return; if(ifofile->vts_ptt_srpt) { int i; for(i = 0; i < ifofile->vts_ptt_srpt->nr_of_srpts; i++) free(ifofile->vts_ptt_srpt->title[i].ptt); free(ifofile->vts_ptt_srpt->ttu_offset); free(ifofile->vts_ptt_srpt->title); free(ifofile->vts_ptt_srpt); ifofile->vts_ptt_srpt = 0; } } int ifoRead_PTL_MAIT(ifo_handle_t *ifofile) { ptl_mait_t *ptl_mait; int info_length; unsigned int i, j; if(!ifofile) return 0; if(!ifofile->vmgi_mat) return 0; if(ifofile->vmgi_mat->ptl_mait == 0) return 1; if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN)) return 0; ptl_mait = (ptl_mait_t *)malloc(sizeof(ptl_mait_t)); if(!ptl_mait) return 0; ifofile->ptl_mait = ptl_mait; if(!(DVDReadBytes(ifofile->file, ptl_mait, PTL_MAIT_SIZE))) { free(ptl_mait); ifofile->ptl_mait = 0; return 0; } B2N_16(ptl_mait->nr_of_countries); B2N_16(ptl_mait->nr_of_vtss); B2N_32(ptl_mait->last_byte); CHECK_VALUE(ptl_mait->nr_of_countries != 0); CHECK_VALUE(ptl_mait->nr_of_countries < 100); /* ?? */ CHECK_VALUE(ptl_mait->nr_of_vtss != 0); CHECK_VALUE(ptl_mait->nr_of_vtss < 100); /* ?? */ CHECK_VALUE(ptl_mait->nr_of_countries * PTL_MAIT_COUNTRY_SIZE <= ptl_mait->last_byte + 1 - PTL_MAIT_SIZE); info_length = ptl_mait->nr_of_countries * sizeof(ptl_mait_country_t); ptl_mait->countries = (ptl_mait_country_t *)malloc(info_length); if(!ptl_mait->countries) { free(ptl_mait); ifofile->ptl_mait = 0; return 0; } for(i = 0; i < ptl_mait->nr_of_countries; i++) { if(!(DVDReadBytes(ifofile->file, &ptl_mait->countries[i], PTL_MAIT_COUNTRY_SIZE))) { fprintf(stderr, "libdvdread: Unable to read PTL_MAIT.\n"); free(ptl_mait->countries); free(ptl_mait); ifofile->ptl_mait = 0; return 0; } } for(i = 0; i < ptl_mait->nr_of_countries; i++) { B2N_16(ptl_mait->countries[i].country_code); B2N_16(ptl_mait->countries[i].pf_ptl_mai_start_byte); } for(i = 0; i < ptl_mait->nr_of_countries; i++) { CHECK_ZERO(ptl_mait->countries[i].zero_1); CHECK_ZERO(ptl_mait->countries[i].zero_2); CHECK_VALUE(ptl_mait->countries[i].pf_ptl_mai_start_byte + 8*2 * (ptl_mait->nr_of_vtss + 1) <= (int)ptl_mait->last_byte + 1); } for(i = 0; i < ptl_mait->nr_of_countries; i++) { uint16_t *pf_temp; if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->ptl_mait * DVD_BLOCK_LEN + ptl_mait->countries[i].pf_ptl_mai_start_byte)) { fprintf(stderr, "libdvdread: Unable to seak PTL_MAIT table.\n"); free(ptl_mait->countries); free(ptl_mait); return 0; } info_length = (ptl_mait->nr_of_vtss + 1) * sizeof(pf_level_t); pf_temp = (uint16_t *)malloc(info_length); if(!pf_temp) { for(j = 0; j < i ; j++) { free(ptl_mait->countries[j].pf_ptl_mai); } free(ptl_mait->countries); free(ptl_mait); return 0; } if(!(DVDReadBytes(ifofile->file, pf_temp, info_length))) { fprintf(stderr, "libdvdread: Unable to read PTL_MAIT table.\n"); free(pf_temp); for(j = 0; j < i ; j++) { free(ptl_mait->countries[j].pf_ptl_mai); } free(ptl_mait->countries); free(ptl_mait); return 0; } for (j = 0; (int)j < ((ptl_mait->nr_of_vtss + 1) * 8); j++) { B2N_16(pf_temp[j]); } ptl_mait->countries[i].pf_ptl_mai = (pf_level_t *)malloc(info_length); if(!ptl_mait->countries[i].pf_ptl_mai) { free(pf_temp); for(j = 0; j < i ; j++) { free(ptl_mait->countries[j].pf_ptl_mai); } free(ptl_mait->countries); free(ptl_mait); return 0; } { /* Transpose the array so we can use C indexing. */ int level, vts; for(level = 0; level < 8; level++) { for(vts = 0; vts <= ptl_mait->nr_of_vtss; vts++) { ptl_mait->countries[i].pf_ptl_mai[vts][level] = pf_temp[(7-level)*(ptl_mait->nr_of_vtss+1) + vts]; } } free(pf_temp); } } return 1; } void ifoFree_PTL_MAIT(ifo_handle_t *ifofile) { unsigned int i; if(!ifofile) return; if(ifofile->ptl_mait) { for(i = 0; i < ifofile->ptl_mait->nr_of_countries; i++) { free(ifofile->ptl_mait->countries[i].pf_ptl_mai); } free(ifofile->ptl_mait->countries); free(ifofile->ptl_mait); ifofile->ptl_mait = 0; } } int ifoRead_VTS_TMAPT(ifo_handle_t *ifofile) { vts_tmapt_t *vts_tmapt; uint32_t *vts_tmap_srp; unsigned int offset; int info_length; unsigned int i, j; if(!ifofile) return 0; if(!ifofile->vtsi_mat) return 0; if(ifofile->vtsi_mat->vts_tmapt == 0) { /* optional(?) */ ifofile->vts_tmapt = NULL; fprintf(stderr,"Please send bug report - no VTS_TMAPT ?? \n"); return 1; } offset = ifofile->vtsi_mat->vts_tmapt * DVD_BLOCK_LEN; if(!DVDFileSeek_(ifofile->file, offset)) return 0; vts_tmapt = (vts_tmapt_t *)malloc(sizeof(vts_tmapt_t)); if(!vts_tmapt) return 0; ifofile->vts_tmapt = vts_tmapt; if(!(DVDReadBytes(ifofile->file, vts_tmapt, VTS_TMAPT_SIZE))) { fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n"); free(vts_tmapt); ifofile->vts_tmapt = NULL; return 0; } B2N_16(vts_tmapt->nr_of_tmaps); B2N_32(vts_tmapt->last_byte); CHECK_ZERO(vts_tmapt->zero_1); info_length = vts_tmapt->nr_of_tmaps * 4; vts_tmap_srp = (uint32_t *)malloc(info_length); if(!vts_tmap_srp) { free(vts_tmapt); ifofile->vts_tmapt = NULL; return 0; } vts_tmapt->tmap_offset = vts_tmap_srp; if(!(DVDReadBytes(ifofile->file, vts_tmap_srp, info_length))) { fprintf(stderr, "libdvdread: Unable to read VTS_TMAPT.\n"); free(vts_tmap_srp); free(vts_tmapt); ifofile->vts_tmapt = NULL; return 0; } for (i = 0; i < vts_tmapt->nr_of_tmaps; i++) { B2N_32(vts_tmap_srp[i]); } info_length = vts_tmapt->nr_of_tmaps * sizeof(vts_tmap_t); vts_tmapt->tmap = (vts_tmap_t *)malloc(info_length); if(!vts_tmapt->tmap) { free(vts_tmap_srp); free(vts_tmapt); ifofile->vts_tmapt = NULL; return 0; } memset(vts_tmapt->tmap, 0, info_length); /* So ifoFree_VTS_TMAPT works. */ for(i = 0; i < vts_tmapt->nr_of_tmaps; i++) { if(!DVDFileSeek_(ifofile->file, offset + vts_tmap_srp[i])) { ifoFree_VTS_TMAPT(ifofile); return 0; } if(!(DVDReadBytes(ifofile->file, &vts_tmapt->tmap[i], VTS_TMAP_SIZE))) { fprintf(stderr, "libdvdread: Unable to read VTS_TMAP.\n"); ifoFree_VTS_TMAPT(ifofile); return 0; } B2N_16(vts_tmapt->tmap[i].nr_of_entries); CHECK_ZERO(vts_tmapt->tmap[i].zero_1); if(vts_tmapt->tmap[i].nr_of_entries == 0) { /* Early out if zero entries */ vts_tmapt->tmap[i].map_ent = NULL; continue; } info_length = vts_tmapt->tmap[i].nr_of_entries * sizeof(map_ent_t); vts_tmapt->tmap[i].map_ent = (map_ent_t *)malloc(info_length); if(!vts_tmapt->tmap[i].map_ent) { ifoFree_VTS_TMAPT(ifofile); return 0; } if(!(DVDReadBytes(ifofile->file, vts_tmapt->tmap[i].map_ent, info_length))) { fprintf(stderr, "libdvdread: Unable to read VTS_TMAP_ENT.\n"); ifoFree_VTS_TMAPT(ifofile); return 0; } for(j = 0; j < vts_tmapt->tmap[i].nr_of_entries; j++) B2N_32(vts_tmapt->tmap[i].map_ent[j]); } return 1; } void ifoFree_VTS_TMAPT(ifo_handle_t *ifofile) { unsigned int i; if(!ifofile) return; if(ifofile->vts_tmapt) { for(i = 0; i < ifofile->vts_tmapt->nr_of_tmaps; i++) if(ifofile->vts_tmapt->tmap[i].map_ent) free(ifofile->vts_tmapt->tmap[i].map_ent); free(ifofile->vts_tmapt->tmap); free(ifofile->vts_tmapt->tmap_offset); free(ifofile->vts_tmapt); ifofile->vts_tmapt = NULL; } } int ifoRead_TITLE_C_ADT(ifo_handle_t *ifofile) { if(!ifofile) return 0; if(!ifofile->vtsi_mat) return 0; if(ifofile->vtsi_mat->vts_c_adt == 0) /* mandatory */ return 0; ifofile->vts_c_adt = (c_adt_t *)malloc(sizeof(c_adt_t)); if(!ifofile->vts_c_adt) return 0; if(!ifoRead_C_ADT_internal(ifofile, ifofile->vts_c_adt, ifofile->vtsi_mat->vts_c_adt)) { free(ifofile->vts_c_adt); ifofile->vts_c_adt = 0; return 0; } return 1; } int ifoRead_C_ADT(ifo_handle_t *ifofile) { unsigned int sector; if(!ifofile) return 0; if(ifofile->vmgi_mat) { if(ifofile->vmgi_mat->vmgm_c_adt == 0) return 1; sector = ifofile->vmgi_mat->vmgm_c_adt; } else if(ifofile->vtsi_mat) { if(ifofile->vtsi_mat->vtsm_c_adt == 0) return 1; sector = ifofile->vtsi_mat->vtsm_c_adt; } else { return 0; } ifofile->menu_c_adt = (c_adt_t *)malloc(sizeof(c_adt_t)); if(!ifofile->menu_c_adt) return 0; if(!ifoRead_C_ADT_internal(ifofile, ifofile->menu_c_adt, sector)) { free(ifofile->menu_c_adt); ifofile->menu_c_adt = 0; return 0; } return 1; } static int ifoRead_C_ADT_internal(ifo_handle_t *ifofile, c_adt_t *c_adt, unsigned int sector) { int i, info_length; if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN)) return 0; if(!(DVDReadBytes(ifofile->file, c_adt, C_ADT_SIZE))) return 0; B2N_16(c_adt->nr_of_vobs); B2N_32(c_adt->last_byte); info_length = c_adt->last_byte + 1 - C_ADT_SIZE; CHECK_ZERO(c_adt->zero_1); /* assert(c_adt->nr_of_vobs > 0); Magic Knight Rayearth Daybreak is mastered very strange and has Titles with a VOBS that has no cells. */ CHECK_VALUE(info_length % sizeof(cell_adr_t) == 0); /* assert(info_length / sizeof(cell_adr_t) >= c_adt->nr_of_vobs); Enemy of the State region 2 (de) has Titles where nr_of_vobs field is to high, they high ones are never referenced though. */ if(info_length / sizeof(cell_adr_t) < c_adt->nr_of_vobs) { fprintf(stderr, "libdvdread: *C_ADT nr_of_vobs > avaiable info entries\n"); c_adt->nr_of_vobs = info_length / sizeof(cell_adr_t); } c_adt->cell_adr_table = (cell_adr_t *)malloc(info_length); if(!c_adt->cell_adr_table) return 0; if(info_length && !(DVDReadBytes(ifofile->file, c_adt->cell_adr_table, info_length))) { free(c_adt->cell_adr_table); return 0; } for(i = 0; i < info_length / (int)sizeof(cell_adr_t); i++) { B2N_16(c_adt->cell_adr_table[i].vob_id); B2N_32(c_adt->cell_adr_table[i].start_sector); B2N_32(c_adt->cell_adr_table[i].last_sector); CHECK_ZERO(c_adt->cell_adr_table[i].zero_1); CHECK_VALUE(c_adt->cell_adr_table[i].vob_id > 0); CHECK_VALUE(c_adt->cell_adr_table[i].vob_id <= c_adt->nr_of_vobs); CHECK_VALUE(c_adt->cell_adr_table[i].cell_id > 0); CHECK_VALUE(c_adt->cell_adr_table[i].start_sector < c_adt->cell_adr_table[i].last_sector); } return 1; } static void ifoFree_C_ADT_internal(c_adt_t *c_adt) { if(c_adt) { free(c_adt->cell_adr_table); free(c_adt); } } void ifoFree_C_ADT(ifo_handle_t *ifofile) { if(!ifofile) return; ifoFree_C_ADT_internal(ifofile->menu_c_adt); ifofile->menu_c_adt = 0; } void ifoFree_TITLE_C_ADT(ifo_handle_t *ifofile) { if(!ifofile) return; ifoFree_C_ADT_internal(ifofile->vts_c_adt); ifofile->vts_c_adt = 0; } int ifoRead_TITLE_VOBU_ADMAP(ifo_handle_t *ifofile) { if(!ifofile) return 0; if(!ifofile->vtsi_mat) return 0; if(ifofile->vtsi_mat->vts_vobu_admap == 0) /* mandatory */ return 0; ifofile->vts_vobu_admap = (vobu_admap_t *)malloc(sizeof(vobu_admap_t)); if(!ifofile->vts_vobu_admap) return 0; if(!ifoRead_VOBU_ADMAP_internal(ifofile, ifofile->vts_vobu_admap, ifofile->vtsi_mat->vts_vobu_admap)) { free(ifofile->vts_vobu_admap); ifofile->vts_vobu_admap = 0; return 0; } return 1; } int ifoRead_VOBU_ADMAP(ifo_handle_t *ifofile) { unsigned int sector; if(!ifofile) return 0; if(ifofile->vmgi_mat) { if(ifofile->vmgi_mat->vmgm_vobu_admap == 0) return 1; sector = ifofile->vmgi_mat->vmgm_vobu_admap; } else if(ifofile->vtsi_mat) { if(ifofile->vtsi_mat->vtsm_vobu_admap == 0) return 1; sector = ifofile->vtsi_mat->vtsm_vobu_admap; } else { return 0; } ifofile->menu_vobu_admap = (vobu_admap_t *)malloc(sizeof(vobu_admap_t)); if(!ifofile->menu_vobu_admap) return 0; if(!ifoRead_VOBU_ADMAP_internal(ifofile, ifofile->menu_vobu_admap, sector)) { free(ifofile->menu_vobu_admap); ifofile->menu_vobu_admap = 0; return 0; } return 1; } static int ifoRead_VOBU_ADMAP_internal(ifo_handle_t *ifofile, vobu_admap_t *vobu_admap, unsigned int sector) { unsigned int i; int info_length; if(!DVDFileSeekForce_(ifofile->file, sector * DVD_BLOCK_LEN, sector)) return 0; if(!(DVDReadBytes(ifofile->file, vobu_admap, VOBU_ADMAP_SIZE))) return 0; B2N_32(vobu_admap->last_byte); info_length = vobu_admap->last_byte + 1 - VOBU_ADMAP_SIZE; /* assert(info_length > 0); Magic Knight Rayearth Daybreak is mastered very strange and has Titles with a VOBS that has no VOBUs. */ CHECK_VALUE(info_length % sizeof(uint32_t) == 0); vobu_admap->vobu_start_sectors = (uint32_t *)malloc(info_length); if(!vobu_admap->vobu_start_sectors) { return 0; } if(info_length && !(DVDReadBytes(ifofile->file, vobu_admap->vobu_start_sectors, info_length))) { free(vobu_admap->vobu_start_sectors); return 0; } for(i = 0; i < info_length/sizeof(uint32_t); i++) B2N_32(vobu_admap->vobu_start_sectors[i]); return 1; } static void ifoFree_VOBU_ADMAP_internal(vobu_admap_t *vobu_admap) { if(vobu_admap) { free(vobu_admap->vobu_start_sectors); free(vobu_admap); } } void ifoFree_VOBU_ADMAP(ifo_handle_t *ifofile) { if(!ifofile) return; ifoFree_VOBU_ADMAP_internal(ifofile->menu_vobu_admap); ifofile->menu_vobu_admap = 0; } void ifoFree_TITLE_VOBU_ADMAP(ifo_handle_t *ifofile) { if(!ifofile) return; ifoFree_VOBU_ADMAP_internal(ifofile->vts_vobu_admap); ifofile->vts_vobu_admap = 0; } int ifoRead_PGCIT(ifo_handle_t *ifofile) { if(!ifofile) return 0; if(!ifofile->vtsi_mat) return 0; if(ifofile->vtsi_mat->vts_pgcit == 0) /* mandatory */ return 0; ifofile->vts_pgcit = (pgcit_t *)malloc(sizeof(pgcit_t)); if(!ifofile->vts_pgcit) return 0; if(!ifoRead_PGCIT_internal(ifofile, ifofile->vts_pgcit, ifofile->vtsi_mat->vts_pgcit * DVD_BLOCK_LEN)) { free(ifofile->vts_pgcit); ifofile->vts_pgcit = 0; return 0; } return 1; } static int ifoRead_PGCIT_internal(ifo_handle_t *ifofile, pgcit_t *pgcit, unsigned int offset) { int i, info_length; uint8_t *data, *ptr; if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, pgcit, PGCIT_SIZE))) return 0; B2N_16(pgcit->nr_of_pgci_srp); B2N_32(pgcit->last_byte); CHECK_ZERO(pgcit->zero_1); /* assert(pgcit->nr_of_pgci_srp != 0); Magic Knight Rayearth Daybreak is mastered very strange and has Titles with 0 PTTs. */ CHECK_VALUE(pgcit->nr_of_pgci_srp < 10000); /* ?? seen max of 1338 */ info_length = pgcit->nr_of_pgci_srp * PGCI_SRP_SIZE; data = malloc(info_length); if(!data) return 0; if(info_length && !(DVDReadBytes(ifofile->file, data, info_length))) { free(data); return 0; } pgcit->pgci_srp = malloc(pgcit->nr_of_pgci_srp * sizeof(pgci_srp_t)); if(!pgcit->pgci_srp) { free(data); return 0; } ptr = data; for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { memcpy(&pgcit->pgci_srp[i], ptr, PGCI_SRP_SIZE); ptr += PGCI_SRP_SIZE; B2N_16(pgcit->pgci_srp[i].ptl_id_mask); B2N_32(pgcit->pgci_srp[i].pgc_start_byte); CHECK_VALUE(pgcit->pgci_srp[i].unknown1 == 0); } free(data); for(i = 0; i < pgcit->nr_of_pgci_srp; i++) CHECK_VALUE(pgcit->pgci_srp[i].pgc_start_byte + PGC_SIZE <= pgcit->last_byte+1); for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { pgcit->pgci_srp[i].pgc = malloc(sizeof(pgc_t)); if(!pgcit->pgci_srp[i].pgc) { int j; for(j = 0; j < i; j++) { ifoFree_PGC(pgcit->pgci_srp[j].pgc); free(pgcit->pgci_srp[j].pgc); } return 0; } if(!ifoRead_PGC(ifofile, pgcit->pgci_srp[i].pgc, offset + pgcit->pgci_srp[i].pgc_start_byte)) { int j; for(j = 0; j < i; j++) { ifoFree_PGC(pgcit->pgci_srp[j].pgc); free(pgcit->pgci_srp[j].pgc); } free(pgcit->pgci_srp); return 0; } } return 1; } static void ifoFree_PGCIT_internal(pgcit_t *pgcit) { if(pgcit) { int i; for(i = 0; i < pgcit->nr_of_pgci_srp; i++) ifoFree_PGC(pgcit->pgci_srp[i].pgc); free(pgcit->pgci_srp); } } void ifoFree_PGCIT(ifo_handle_t *ifofile) { if(!ifofile) return; if(ifofile->vts_pgcit) { ifoFree_PGCIT_internal(ifofile->vts_pgcit); free(ifofile->vts_pgcit); ifofile->vts_pgcit = 0; } } int ifoRead_PGCI_UT(ifo_handle_t *ifofile) { pgci_ut_t *pgci_ut; unsigned int sector; unsigned int i; int info_length; uint8_t *data, *ptr; if(!ifofile) return 0; if(ifofile->vmgi_mat) { if(ifofile->vmgi_mat->vmgm_pgci_ut == 0) return 1; sector = ifofile->vmgi_mat->vmgm_pgci_ut; } else if(ifofile->vtsi_mat) { if(ifofile->vtsi_mat->vtsm_pgci_ut == 0) return 1; sector = ifofile->vtsi_mat->vtsm_pgci_ut; } else { return 0; } ifofile->pgci_ut = (pgci_ut_t *)malloc(sizeof(pgci_ut_t)); if(!ifofile->pgci_ut) return 0; if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN)) { free(ifofile->pgci_ut); ifofile->pgci_ut = 0; return 0; } if(!(DVDReadBytes(ifofile->file, ifofile->pgci_ut, PGCI_UT_SIZE))) { free(ifofile->pgci_ut); ifofile->pgci_ut = 0; return 0; } pgci_ut = ifofile->pgci_ut; B2N_16(pgci_ut->nr_of_lus); B2N_32(pgci_ut->last_byte); CHECK_ZERO(pgci_ut->zero_1); CHECK_VALUE(pgci_ut->nr_of_lus != 0); CHECK_VALUE(pgci_ut->nr_of_lus < 100); /* ?? 3-4 ? */ CHECK_VALUE((uint32_t)pgci_ut->nr_of_lus * PGCI_LU_SIZE < pgci_ut->last_byte); info_length = pgci_ut->nr_of_lus * PGCI_LU_SIZE; data = malloc(info_length); if(!data) { free(pgci_ut); ifofile->pgci_ut = 0; return 0; } if(!(DVDReadBytes(ifofile->file, data, info_length))) { free(data); free(pgci_ut); ifofile->pgci_ut = 0; return 0; } pgci_ut->lu = malloc(pgci_ut->nr_of_lus * sizeof(pgci_lu_t)); if(!pgci_ut->lu) { free(data); free(pgci_ut); ifofile->pgci_ut = 0; return 0; } ptr = data; for(i = 0; i < pgci_ut->nr_of_lus; i++) { memcpy(&pgci_ut->lu[i], ptr, PGCI_LU_SIZE); ptr += PGCI_LU_SIZE; B2N_16(pgci_ut->lu[i].lang_code); B2N_32(pgci_ut->lu[i].lang_start_byte); } free(data); for(i = 0; i < pgci_ut->nr_of_lus; i++) { /* Maybe this is only defined for v1.1 and later titles? */ /* If the bits in 'lu[i].exists' are enumerated abcd efgh then: VTS_x_yy.IFO VIDEO_TS.IFO a == 0x83 "Root" 0x82 "Title" b == 0x84 "Subpicture" c == 0x85 "Audio" d == 0x86 "Angle" e == 0x87 "PTT" */ CHECK_VALUE((pgci_ut->lu[i].exists & 0x07) == 0); } for(i = 0; i < pgci_ut->nr_of_lus; i++) { pgci_ut->lu[i].pgcit = malloc(sizeof(pgcit_t)); if(!pgci_ut->lu[i].pgcit) { unsigned int j; for(j = 0; j < i; j++) { ifoFree_PGCIT_internal(pgci_ut->lu[j].pgcit); free(pgci_ut->lu[j].pgcit); } free(pgci_ut->lu); free(pgci_ut); ifofile->pgci_ut = 0; return 0; } if(!ifoRead_PGCIT_internal(ifofile, pgci_ut->lu[i].pgcit, sector * DVD_BLOCK_LEN + pgci_ut->lu[i].lang_start_byte)) { unsigned int j; for(j = 0; j < i; j++) { ifoFree_PGCIT_internal(pgci_ut->lu[j].pgcit); free(pgci_ut->lu[j].pgcit); } free(pgci_ut->lu[i].pgcit); free(pgci_ut->lu); free(pgci_ut); ifofile->pgci_ut = 0; return 0; } /* * FIXME: Iterate and verify that all menus that should exists accordingly * to pgci_ut->lu[i].exists really do? */ } return 1; } void ifoFree_PGCI_UT(ifo_handle_t *ifofile) { unsigned int i; if(!ifofile) return; if(ifofile->pgci_ut) { for(i = 0; i < ifofile->pgci_ut->nr_of_lus; i++) { ifoFree_PGCIT_internal(ifofile->pgci_ut->lu[i].pgcit); free(ifofile->pgci_ut->lu[i].pgcit); } free(ifofile->pgci_ut->lu); free(ifofile->pgci_ut); ifofile->pgci_ut = 0; } } static int ifoRead_VTS_ATTRIBUTES(ifo_handle_t *ifofile, vts_attributes_t *vts_attributes, unsigned int offset) { unsigned int i; if(!DVDFileSeek_(ifofile->file, offset)) return 0; if(!(DVDReadBytes(ifofile->file, vts_attributes, sizeof(vts_attributes_t)))) return 0; B2N_32(vts_attributes->last_byte); B2N_32(vts_attributes->vts_cat); B2N_16(vts_attributes->vtsm_audio_attr.lang_code); B2N_16(vts_attributes->vtsm_subp_attr.lang_code); for(i = 0; i < 8; i++) B2N_16(vts_attributes->vtstt_audio_attr[i].lang_code); for(i = 0; i < 32; i++) B2N_16(vts_attributes->vtstt_subp_attr[i].lang_code); CHECK_ZERO(vts_attributes->zero_1); CHECK_ZERO(vts_attributes->zero_2); CHECK_ZERO(vts_attributes->zero_3); CHECK_ZERO(vts_attributes->zero_4); CHECK_ZERO(vts_attributes->zero_5); CHECK_ZERO(vts_attributes->zero_6); CHECK_ZERO(vts_attributes->zero_7); CHECK_VALUE(vts_attributes->nr_of_vtsm_audio_streams <= 1); CHECK_VALUE(vts_attributes->nr_of_vtsm_subp_streams <= 1); CHECK_VALUE(vts_attributes->nr_of_vtstt_audio_streams <= 8); for(i = vts_attributes->nr_of_vtstt_audio_streams; i < 8; i++) CHECK_ZERO(vts_attributes->vtstt_audio_attr[i]); CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= 32); { unsigned int nr_coded; CHECK_VALUE(vts_attributes->last_byte + 1 >= VTS_ATTRIBUTES_MIN_SIZE); nr_coded = (vts_attributes->last_byte + 1 - VTS_ATTRIBUTES_MIN_SIZE)/6; /* This is often nr_coded = 70, how do you know how many there really are? */ if(nr_coded > 32) { /* We haven't read more from disk/file anyway */ nr_coded = 32; } CHECK_VALUE(vts_attributes->nr_of_vtstt_subp_streams <= nr_coded); for(i = vts_attributes->nr_of_vtstt_subp_streams; i < nr_coded; i++) CHECK_ZERO(vts_attributes->vtstt_subp_attr[i]); } return 1; } int ifoRead_VTS_ATRT(ifo_handle_t *ifofile) { vts_atrt_t *vts_atrt; unsigned int i, info_length, sector; uint32_t *data; if(!ifofile) return 0; if(!ifofile->vmgi_mat) return 0; if(ifofile->vmgi_mat->vts_atrt == 0) /* mandatory */ return 0; sector = ifofile->vmgi_mat->vts_atrt; if(!DVDFileSeek_(ifofile->file, sector * DVD_BLOCK_LEN)) return 0; vts_atrt = (vts_atrt_t *)malloc(sizeof(vts_atrt_t)); if(!vts_atrt) return 0; ifofile->vts_atrt = vts_atrt; if(!(DVDReadBytes(ifofile->file, vts_atrt, VTS_ATRT_SIZE))) { free(vts_atrt); ifofile->vts_atrt = 0; return 0; } B2N_16(vts_atrt->nr_of_vtss); B2N_32(vts_atrt->last_byte); CHECK_ZERO(vts_atrt->zero_1); CHECK_VALUE(vts_atrt->nr_of_vtss != 0); CHECK_VALUE(vts_atrt->nr_of_vtss < 100); /* ?? */ CHECK_VALUE((uint32_t)vts_atrt->nr_of_vtss * (4 + VTS_ATTRIBUTES_MIN_SIZE) + VTS_ATRT_SIZE < vts_atrt->last_byte + 1); info_length = vts_atrt->nr_of_vtss * sizeof(uint32_t); data = (uint32_t *)malloc(info_length); if(!data) { free(vts_atrt); ifofile->vts_atrt = 0; return 0; } vts_atrt->vts_atrt_offsets = data; if(!(DVDReadBytes(ifofile->file, data, info_length))) { free(data); free(vts_atrt); ifofile->vts_atrt = 0; return 0; } for(i = 0; i < vts_atrt->nr_of_vtss; i++) { B2N_32(data[i]); CHECK_VALUE(data[i] + VTS_ATTRIBUTES_MIN_SIZE < vts_atrt->last_byte + 1); } info_length = vts_atrt->nr_of_vtss * sizeof(vts_attributes_t); vts_atrt->vts = (vts_attributes_t *)malloc(info_length); if(!vts_atrt->vts) { free(data); free(vts_atrt); ifofile->vts_atrt = 0; return 0; } for(i = 0; i < vts_atrt->nr_of_vtss; i++) { unsigned int offset = data[i]; if(!ifoRead_VTS_ATTRIBUTES(ifofile, &(vts_atrt->vts[i]), (sector * DVD_BLOCK_LEN) + offset)) { free(data); free(vts_atrt); ifofile->vts_atrt = 0; return 0; } /* This assert cant be in ifoRead_VTS_ATTRIBUTES */ CHECK_VALUE(offset + vts_atrt->vts[i].last_byte <= vts_atrt->last_byte + 1); /* Is this check correct? */ } return 1; } void ifoFree_VTS_ATRT(ifo_handle_t *ifofile) { if(!ifofile) return; if(ifofile->vts_atrt) { free(ifofile->vts_atrt->vts); free(ifofile->vts_atrt->vts_atrt_offsets); free(ifofile->vts_atrt); ifofile->vts_atrt = 0; } } int ifoRead_TXTDT_MGI(ifo_handle_t *ifofile) { txtdt_mgi_t *txtdt_mgi; if(!ifofile) return 0; if(!ifofile->vmgi_mat) return 0; /* Return successfully if there is nothing to read. */ if(ifofile->vmgi_mat->txtdt_mgi == 0) return 1; if(!DVDFileSeek_(ifofile->file, ifofile->vmgi_mat->txtdt_mgi * DVD_BLOCK_LEN)) return 0; txtdt_mgi = (txtdt_mgi_t *)malloc(sizeof(txtdt_mgi_t)); if(!txtdt_mgi) { return 0; } ifofile->txtdt_mgi = txtdt_mgi; if(!(DVDReadBytes(ifofile->file, txtdt_mgi, TXTDT_MGI_SIZE))) { fprintf(stderr, "libdvdread: Unable to read TXTDT_MGI.\n"); free(txtdt_mgi); ifofile->txtdt_mgi = 0; return 0; } /* fprintf(stderr, "-- Not done yet --\n"); */ return 1; } void ifoFree_TXTDT_MGI(ifo_handle_t *ifofile) { if(!ifofile) return; if(ifofile->txtdt_mgi) { free(ifofile->txtdt_mgi); ifofile->txtdt_mgi = 0; } } �������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/Makefile.am��������������������������������������������������������0000644�0001750�0001750�00000001442�14647725152�016620� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_CPPFLAGS += -DDVDNAV_COMPILE -DHAVE_DLFCN_H AM_LDFLAGS = $(xineplug_ldflags) noinst_LTLIBRARIES = libdvdnav.la libdvdnav_la_SOURCES = \ decoder.c \ dvdnav.c \ highlight.c \ navigation.c \ read_cache.c \ remap.c \ searching.c \ settings.c \ vm.c \ vmcmd.c \ ifo_read.c \ md5.c \ nav_print.c \ nav_read.c \ dvd_reader.c \ dvd_input.c \ dvd_udf.c libdvdnav_la_LIBADD = $(PTHREAD_LIBS) noinst_HEADERS = \ decoder.h \ dvdnav.h \ dvdnav_events.h \ dvdnav_internal.h \ dvdread_internal.h \ remap.h \ vm.h \ vmcmd.h \ read_cache.h \ dvd_types.h \ ifo_read.h \ ifo_types.h \ md5.h \ nav_print.h \ nav_read.h \ nav_types.h \ dvd_reader.h \ dvd_input.h \ dvd_udf.h \ bswap.h ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/bswap.h������������������������������������������������������������0000644�0001750�0001750�00000006536�14647725152�016062� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef BSWAP_H_INCLUDED #define BSWAP_H_INCLUDED /* * Copyright (C) 2000, 2001 Billy Biggs <vektor@dumbterm.net>, * Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #if defined(WORDS_BIGENDIAN) /* All bigendian systems are fine, just ignore the swaps. */ #define B2N_16(x) (void)(x) #define B2N_32(x) (void)(x) #define B2N_64(x) (void)(x) #else /* For __FreeBSD_version */ #if defined(HAVE_SYS_PARAM_H) #include <sys/param.h> #endif #if defined(__linux__) || defined(__GLIBC__) #include <byteswap.h> #define B2N_16(x) x = bswap_16(x) #define B2N_32(x) x = bswap_32(x) #define B2N_64(x) x = bswap_64(x) #elif defined(__SVR4) && defined(__sun) #include <sys/byteorder.h> #define B2N_16(x) x = BSWAP_16(x) #define B2N_32(x) x = BSWAP_32(x) #define B2N_64(x) x = BSWAP_64(x) #elif defined(__APPLE__) #include <libkern/OSByteOrder.h> #define B2N_16(x) x = OSSwapBigToHostInt16(x) #define B2N_32(x) x = OSSwapBigToHostInt32(x) #define B2N_64(x) x = OSSwapBigToHostInt64(x) #elif defined(__NetBSD__) #include <sys/endian.h> #define B2N_16(x) BE16TOH(x) #define B2N_32(x) BE32TOH(x) #define B2N_64(x) BE64TOH(x) #elif defined(__OpenBSD__) #include <sys/endian.h> #define B2N_16(x) x = swap16(x) #define B2N_32(x) x = swap32(x) #define B2N_64(x) x = swap64(x) #elif defined(__DragonFly__) || (defined(__FreeBSD__) && __FreeBSD_version >= 470000) #include <sys/endian.h> #define B2N_16(x) x = be16toh(x) #define B2N_32(x) x = be32toh(x) #define B2N_64(x) x = be64toh(x) /* This is a slow but portable implementation, it has multiple evaluation * problems so beware. * Old FreeBSD and Windows don't have <byteswap.h> or any other such * functionality! */ #elif defined(__FreeBSD__) || defined(__bsdi__) || defined(WIN32) || defined(__CYGWIN__) #define B2N_16(x) \ x = ((((x) & 0xff00) >> 8) | \ (((x) & 0x00ff) << 8)) #define B2N_32(x) \ x = ((((x) & 0xff000000) >> 24) | \ (((x) & 0x00ff0000) >> 8) | \ (((x) & 0x0000ff00) << 8) | \ (((x) & 0x000000ff) << 24)) #define B2N_64(x) \ x = ((((x) & 0xff00000000000000) >> 56) | \ (((x) & 0x00ff000000000000) >> 40) | \ (((x) & 0x0000ff0000000000) >> 24) | \ (((x) & 0x000000ff00000000) >> 8) | \ (((x) & 0x00000000ff000000) << 8) | \ (((x) & 0x0000000000ff0000) << 24) | \ (((x) & 0x000000000000ff00) << 40) | \ (((x) & 0x00000000000000ff) << 56)) #else /* If there isn't a header provided with your system with this functionality * add the relevant || define( ) to the portable implementation above. */ #error "You need to add endian swap macros for you're system" #endif #endif /* WORDS_BIGENDIAN */ #endif /* BSWAP_H_INCLUDED */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/settings.c���������������������������������������������������������0000644�0001750�0001750�00000006445�14647725152�016600� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "dvdnav_internal.h" /* Characteristics/setting API calls */ dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *this, int32_t *region) { if(!this || !region) { printerr("Passed a NULL this pointer."); return DVDNAV_STATUS_ERR; } (*region) = this->vm->state.registers.SPRM[20]; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *this, int32_t mask) { if(!this) { printerr("Passed a NULL this pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); this->vm->state.registers.SPRM[20] = (mask & 0xff); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *this, int32_t use_readahead) { if(!this) { printerr("Passed a NULL this pointer."); return DVDNAV_STATUS_ERR; } this->use_read_ahead = use_readahead; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *this, int32_t *flag) { if(!this || !flag) { printerr("Passed a NULL this pointer."); return DVDNAV_STATUS_ERR; } (*flag) = this->use_read_ahead; return DVDNAV_STATUS_OK; } static dvdnav_status_t set_language_register(dvdnav_t *this, char *code, int reg) { if(!this || !code) { printerr("Passed a NULL this pointer."); return DVDNAV_STATUS_ERR; } if(!code[0] || !code[1]) { printerr("Passed illegal language code."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); this->vm->state.registers.SPRM[reg] = (code[0] << 8) | code[1]; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *this, char *code) { return set_language_register(this, code, 0); } dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *this, char *code) { return set_language_register(this, code, 16); } dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *this, char *code) { return set_language_register(this, code, 18); } dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *this, int32_t pgc) { if(!this) { printerr("Passed a NULL this pointer."); return DVDNAV_STATUS_ERR; } this->pgc_based = pgc; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *this, int32_t *flag) { if(!this || !flag) { printerr("Passed a NULL this pointer."); return DVDNAV_STATUS_ERR; } (*flag) = this->pgc_based; return DVDNAV_STATUS_OK; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/remap.c������������������������������������������������������������0000644�0001750�0001750�00000013665�14647725152�016046� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include <stdlib.h> #include <string.h> #include <stdio.h> #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif #ifdef HAVE_SYS_FCNTL_H #include <sys/fcntl.h> #else #ifndef MAXPATHLEN #define MAXPATHLEN 255 #endif #endif /* HAVE fcntl.h */ #include <assert.h> #include "remap.h" #include "dvdnav_internal.h" struct block_s { int domain; int title; int program; unsigned long start_block; unsigned long end_block; }; struct remap_s { char *title; int maxblocks; int nblocks; int debug; struct block_s *blocks; }; static remap_t* remap_new( char *title) { remap_t *map = malloc( sizeof(remap_t)); map->title = strdup(title); map->maxblocks = 0; map->nblocks = 0; map->blocks = NULL; map->debug = 0; return map; } static int compare_block( block_t *a, block_t *b) { /* returns -1 if a precedes b, 1 if a follows b, and 0 if a and b overlap */ if (a->domain < b->domain) { return -1; } else if (a->domain > b->domain) { return 1; } if (a->title < b->title) { return -1; } else if (a->title > b->title) { return 1; } if (a->program < b->program) { return -1; } else if (a->program > b->program) { return 1; } if (a->end_block < b->start_block) { return -1; } else if (a->start_block > b->end_block) { /* * if a->start_block == b->end_block then the two regions * aren't strictly overlapping, but they should be merged * anyway since there are zero blocks between them */ return 1; } return 0; } static block_t *findblock( remap_t *map, block_t *key) { int lb = 0; int ub = map->nblocks - 1; int mid; int res; while (lb <= ub) { mid = lb + (ub - lb)/2; res = compare_block( key, &map->blocks[mid]); if (res < 0) { ub = mid-1; } else if (res > 0) { lb = mid+1; } else { return &map->blocks[mid]; } } return NULL; } static void mergeblock( block_t *b, block_t tmp) { if (tmp.start_block < b->start_block) b->start_block = tmp.start_block; if (tmp.end_block > b->end_block) b->end_block = tmp.end_block; } static void remap_add_node( remap_t *map, block_t block) { block_t *b; int n; b = findblock( map, &block); if (b) { /* overlaps an existing block */ mergeblock( b, block); } else { /* new block */ if (map->nblocks >= map->maxblocks) { map->maxblocks += 20; map->blocks = realloc( map->blocks, sizeof( block_t)*map->maxblocks); } n = map->nblocks++; while (n > 0 && compare_block( &block, &map->blocks[ n-1]) < 0) { map->blocks[ n] = map->blocks[ n-1]; n--; } map->blocks[ n] = block; } } static int parseblock(char *buf, int *dom, int *tt, int *pg, unsigned long *start, unsigned long *end) { long tmp; char *tok; char *epos; const char *marker[]={"domain", "title", "program", "start", "end"}; int st = 0; tok = strtok( buf, " "); while (st < 5) { if (strcmp(tok, marker[st])) return -st-1000; tok = strtok( NULL, " "); if (!tok) return -st-2000; tmp = strtol( tok, &epos, 0); if (*epos != 0 && *epos != ',') return -st-3000; switch (st) { case 0: *dom = (int)tmp; break; case 1: *tt = (int)tmp; break; case 2: *pg = (int)tmp; break; case 3: *start = tmp; break; case 4: *end = tmp; break; } st++; tok = strtok( NULL, " "); } return st; } remap_t* remap_loadmap( char *title) { char buf[160]; char fname[MAXPATHLEN]; char *home; int res; FILE *fp; block_t tmp = {0, 0, 0, 0, 0}; remap_t *map; /* Build the map filename */ home = getenv("HOME"); assert(home); snprintf (fname, sizeof(fname), "%s/.dvdnav/%s.map", home, title); /* Open the map file */ fp = fopen( fname, "r"); if (!fp) { fprintf(MSG_OUT, "libdvdnav: Unable to find map file '%s'\n", fname); return NULL; } /* Load the map file */ map = remap_new( title); while (fgets( buf, sizeof(buf), fp) != NULL) { if (buf[0] == '\n' || buf[0] == '#' || buf[0] == 0) continue; if (strncasecmp( buf, "debug", 5) == 0) { map->debug = 1; } else { res = parseblock( buf, &tmp.domain, &tmp.title, &tmp.program, &tmp.start_block, &tmp.end_block); if (res != 5) { fprintf(MSG_OUT, "libdvdnav: Ignoring map line (%d): %s\n", res, buf); continue; } remap_add_node( map, tmp); } } fclose (fp); /* ignoring errors... */ if (map->nblocks == 0 && map->debug == 0) return NULL; return map; } unsigned long remap_block( remap_t *map, int domain, int title, int program, unsigned long cblock, unsigned long offset) { block_t key; block_t *b; if (map->debug) { fprintf(MSG_OUT, "libdvdnav: %s: domain %d, title %d, program %d, start %lx, next %lx\n", map->title, domain, title, program, cblock, cblock+offset); } key.domain = domain; key.title = title; key.program = program; key.start_block = key.end_block = cblock + offset; b = findblock( map, &key); if (b) { if (map->debug) { fprintf(MSG_OUT, "libdvdnav: Redirected to %lx\n", b->end_block); } return b->end_block - cblock; } return offset; } ���������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/diff_against_cvs.patch���������������������������������������������0000644�0001750�0001750�00000031020�14647725152�021071� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������--- src/input/libdvdnav/dvdnav.c +++ src/input/libdvdnav/dvdnav.c @@ -67,7 +67,7 @@ struct timeval time; /* Create a new structure */ - fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://dvd.sf.net\n", VERSION); + fprintf(MSG_OUT, "libdvdnav: Using dvdnav version %s from http://xine.sf.net\n", VERSION); (*dest) = NULL; this = (dvdnav_t*)malloc(sizeof(dvdnav_t)); --- src/input/libdvdnav/dvd_reader.c +++ src/input/libdvdnav/dvd_reader.c @@ -61,6 +61,7 @@ #include <mntent.h> #endif +#include "compat.h" #include "dvd_udf.h" #include "dvd_input.h" #include "dvd_reader.h" @@ -409,7 +410,7 @@ if( cdir >= 0 ) { chdir( path_copy ); - new_path = getcwd( NULL, PATH_MAX ); + new_path = getcwd( NULL, XINE_PATH_MAX ); fchdir( cdir ); close( cdir ); if( new_path ) { @@ -595,7 +596,7 @@ static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename ) { - char video_path[ PATH_MAX + 1 ]; + char video_path[ XINE_PATH_MAX + 1 ]; const char *nodirfile; int ret; @@ -629,7 +630,7 @@ */ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ) { - char full_path[ PATH_MAX + 1 ]; + char full_path[ XINE_PATH_MAX + 1 ]; dvd_file_t *dvd_file; struct stat fileinfo; dvd_input_t dev; @@ -722,7 +723,7 @@ static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu ) { char filename[ MAX_UDF_FILE_NAME_LEN ]; - char full_path[ PATH_MAX + 1 ]; + char full_path[ XINE_PATH_MAX + 1 ]; struct stat fileinfo; dvd_file_t *dvd_file; int i; Index: dvd_input.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/dvd_input.c,v retrieving revision 1.6 diff -u -r1.6 dvd_input.c --- dvd_input.c 5 Apr 2004 18:01:09 -0000 1.6 +++ dvd_input.c 27 May 2006 16:11:09 -0000 @@ -35,6 +35,7 @@ int (*dvdinput_title) (dvd_input_t, int); int (*dvdinput_read) (dvd_input_t, void *, int, int); char * (*dvdinput_error) (dvd_input_t); +int (*dvdinput_is_encrypted) (dvd_input_t); #ifdef HAVE_DVDCSS_DVDCSS_H /* linking to libdvdcss */ @@ -55,6 +56,73 @@ #include "../../msvc/contrib/dlfcn.c" #endif +/* Copied from css.h */ +#define KEY_SIZE 5 + +typedef uint8_t dvd_key_t[KEY_SIZE]; + +typedef struct dvd_title_s +{ + int i_startlb; + dvd_key_t p_key; + struct dvd_title_s *p_next; +} dvd_title_t; + +typedef struct css_s +{ + int i_agid; /* Current Authenication Grant ID. */ + dvd_key_t p_bus_key; /* Current session key. */ + dvd_key_t p_disc_key; /* This DVD disc's key. */ + dvd_key_t p_title_key; /* Current title key. */ +} css_t; + +/* Copied from libdvdcss.h */ + +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif + +struct dvdcss_s +{ + /* File descriptor */ + char * psz_device; + int i_fd; + int i_read_fd; + int i_pos; + + /* File handling */ + void *pf_seek; + void *pf_read; + void *pf_readv; + + /* Decryption stuff */ + int i_method; + css_t css; + int b_ioctls; + int b_scrambled; + dvd_title_t *p_titles; + + /* Key cache directory and pointer to the filename */ + char psz_cachefile[PATH_MAX]; + char * psz_block; + + /* Error management */ + char * psz_error; + int b_errors; + int b_debug; + +#ifdef WIN32 + int b_file; + char * p_readv_buffer; + int i_readv_buf_size; +#endif + +#ifndef WIN32 + int i_raw_fd; +#endif +}; + + typedef struct dvdcss_s *dvdcss_handle; static dvdcss_handle (*DVDcss_open) (const char *); static int (*DVDcss_close) (dvdcss_handle); @@ -149,8 +217,13 @@ return 0; } - - +static int css_is_encrypted (dvd_input_t dev) +{ + if (dev->dvdcss == NULL) { + return 0; + } + return dev->dvdcss->b_scrambled; +} @@ -269,6 +342,10 @@ return 0; } +static int file_is_encrypted (dvd_input_t dev) +{ + return 0; +} /** * Setup read functions with either libdvdcss or minimal DVD access. @@ -347,6 +424,7 @@ dvdinput_title = css_title; dvdinput_read = css_read; dvdinput_error = css_error; + dvdinput_is_encrypted = css_is_encrypted; return 1; } else { @@ -359,6 +437,7 @@ dvdinput_title = file_title; dvdinput_read = file_read; dvdinput_error = file_error; + dvdinput_is_encrypted = file_is_encrypted; return 0; } } Index: dvd_input.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/dvd_input.h,v retrieving revision 1.1 diff -u -r1.1 dvd_input.h --- dvd_input.h 29 Apr 2003 15:58:29 -0000 1.1 +++ dvd_input.h 27 May 2006 16:11:09 -0000 @@ -38,6 +38,7 @@ extern int (*dvdinput_title) (dvd_input_t, int); extern int (*dvdinput_read) (dvd_input_t, void *, int, int); extern char * (*dvdinput_error) (dvd_input_t); +extern int (*dvdinput_is_encrypted) (dvd_input_t); /** * Setup function accessed by dvd_reader.c. Returns 1 if there is CSS support. Index: dvd_reader.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/dvd_reader.c,v retrieving revision 1.11 diff -u -r1.11 dvd_reader.c --- dvd_reader.c 20 Sep 2004 19:30:04 -0000 1.11 +++ dvd_reader.c 27 May 2006 16:11:09 -0000 @@ -480,6 +480,13 @@ me->mnt_fsname, me->mnt_dir ); auth_drive = DVDOpenImageFile( me->mnt_fsname, have_css ); + /* If the device is not encrypted, don't access the device + * directly as it would fail for non-UDF DVDs */ + if ( dvdinput_is_encrypted( auth_drive->dev ) == 0) { + DVDClose( auth_drive ); + auth_drive = NULL; + break; + } dev_name = strdup(me->mnt_fsname); break; } Index: src/input/libdvdnav/md5.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/md5.c,v retrieving revision 1.2 diff -u -r1.2 md5.c --- src/input/libdvdnav/md5.c 29 Apr 2003 21:46:05 -0000 1.2 +++ src/input/libdvdnav/md5.c 2 Jun 2006 19:14:50 -0000 @@ -26,14 +26,8 @@ #include <sys/types.h> -#if STDC_HEADERS || defined _LIBC -# include <stdlib.h> -# include <string.h> -#else -# ifndef HAVE_MEMCPY -# define memcpy(d, s, n) bcopy ((s), (d), (n)) -# endif -#endif +#include <stdlib.h> +#include <string.h> #include "md5.h" /* #include "unlocked-io.h" */ Index: src/input/libdvdnav/bswap.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/bswap.h,v retrieving revision 1.3 diff -u -p -u -r1.3 bswap.h --- src/input/libdvdnav/bswap.h 26 May 2003 23:11:44 -0000 1.3 +++ src/input/libdvdnav/bswap.h 17 Sep 2006 12:50:16 -0000 @@ -35,7 +35,7 @@ #include <sys/param.h> #endif -#if defined(__linux__) +#if defined(__linux__) || defined(__GLIBC__) #include <byteswap.h> #define B2N_16(x) x = bswap_16(x) #define B2N_32(x) x = bswap_32(x) @@ -41,6 +41,12 @@ #define B2N_32(x) x = bswap_32(x) #define B2N_64(x) x = bswap_64(x) +#elif defined(__APPLE__) +#include <libkern/OSByteOrder.h> +#define B2N_16(x) x = OSSwapBigToHostInt16(x) +#define B2N_32(x) x = OSSwapBigToHostInt32(x) +#define B2N_64(x) x = OSSwapBigToHostInt64(x) + #elif defined(__NetBSD__) #include <sys/endian.h> #define B2N_16(x) BE16TOH(x) Index: src/input/libdvdnav/dvd_reader.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/dvd_reader.c,v retrieving revision 1.13 diff -u -p -u -r1.13 dvd_reader.c --- src/input/libdvdnav/dvd_reader.c 15 Jun 2006 14:26:40 -0000 1.13 +++ src/input/libdvdnav/dvd_reader.c 17 Sep 2006 12:50:16 -0000 @@ -32,8 +32,13 @@ #include <limits.h> #include <dirent.h> -/* misc win32 helpers */ -#ifdef WIN32 +#ifndef HAVE_GETTIMEOFDAY +# ifdef WIN32 +# include <winsock.h> +struct timezone; +# else +# include <sys/time.h> +# endif /* replacement gettimeofday implementation */ #include <sys/timeb.h> static inline int _private_gettimeofday( struct timeval *tv, void *tz ) @@ -45,6 +50,10 @@ static inline int _private_gettimeofday( return 0; } #define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ)) +#endif + +/* misc win32 helpers */ +#ifdef WIN32 #include <io.h> /* read() */ #define lseek64 _lseeki64 #endif Index: src/input/libdvdnav/dvd_reader.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/dvd_reader.h,v retrieving revision 1.5 diff -u -p -u -r1.5 dvd_reader.h --- src/input/libdvdnav/dvd_reader.h 16 Mar 2004 11:43:38 -0000 1.5 +++ src/input/libdvdnav/dvd_reader.h 17 Sep 2006 12:50:16 -0000 @@ -21,9 +21,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef _MSC_VER +#ifdef HAVE_CONFIG_H #include "config.h" +#endif +#ifdef _MSC_VER #include <stdio.h> #include <stdlib.h> #endif Index: src/input/libdvdnav/dvdnav_internal.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/dvdnav_internal.h,v retrieving revision 1.15 diff -u -p -u -r1.15 dvdnav_internal.h --- src/input/libdvdnav/dvdnav_internal.h 20 Sep 2004 19:30:04 -0000 1.15 +++ src/input/libdvdnav/dvdnav_internal.h 17 Sep 2006 12:50:16 -0000 @@ -34,6 +34,34 @@ #include <limits.h> #include <string.h> +#ifndef HAVE_GETTIMEOFDAY +# ifdef WIN32 +# include <winsock.h> +struct timezone; +# else +# include <sys/time.h> +# endif +/* replacement gettimeofday implementation */ +#include <sys/timeb.h> +static inline int dvdnav_private_gettimeofday( struct timeval *tv, void *tz ) +{ + struct timeb t; + ftime( &t ); + tv->tv_sec = t.time; + tv->tv_usec = t.millitm * 1000; + return 0; +} +#define gettimeofday(TV, TZ) dvdnav_private_gettimeofday((TV), (TZ)) +#define HAVE_GETTIMEOFDAY 1 +#endif + +#ifndef HAVE_SNPRINTF +# ifdef HAVE__SNPRINTF +# define snprintf _snprintf +# define HAVE_SNPRINTF 1 +# endif +#endif + #ifdef WIN32 /* pthread_mutex_* wrapper for win32 */ @@ -45,17 +73,6 @@ typedef CRITICAL_SECTION pthread_mutex_t #define pthread_mutex_unlock(a) LeaveCriticalSection(a) #define pthread_mutex_destroy(a) -/* replacement gettimeofday implementation */ -#include <sys/timeb.h> -static inline int _private_gettimeofday( struct timeval *tv, void *tz ) -{ - struct timeb t; - ftime( &t ); - tv->tv_sec = t.time; - tv->tv_usec = t.millitm * 1000; - return 0; -} -#define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ)) #include <io.h> /* read() */ #define lseek64 _lseeki64 Index: src/input/libdvdnav/remap.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/remap.c,v retrieving revision 1.4 diff -u -p -u -r1.4 remap.c --- src/input/libdvdnav/remap.c 25 Aug 2003 21:51:40 -0000 1.4 +++ src/input/libdvdnav/remap.c 17 Sep 2006 12:50:16 -0000 @@ -22,14 +22,17 @@ #include <string.h> #include <stdio.h> -#ifndef _MSC_VER +#ifdef HAVE_SYS_PARAM_H #include <sys/param.h> +#endif + +#ifdef HAVE_SYS_FCNTL_H #include <sys/fcntl.h> #else #ifndef MAXPATHLEN #define MAXPATHLEN 255 #endif -#endif /* _MSC_VER */ +#endif /* HAVE fcntl.h */ #include <assert.h> #include "remap.h" Index: src/input/libdvdnav/searching.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/input/libdvdnav/searching.c,v retrieving revision 1.19 diff -u -p -u -r1.19 searching.c --- src/input/libdvdnav/searching.c 14 Oct 2005 21:02:16 -0000 1.19 +++ src/input/libdvdnav/searching.c 17 Sep 2006 12:50:16 -0000 @@ -105,7 +105,6 @@ dvdnav_status_t dvdnav_time_search(dvdna int32_t found; cell_playback_t *cell; dvd_state_t *state; - dvdnav_status_t result; if(this->position_current.still != 0) { printerr("Cannot seek in a still frame."); --- src/input/libdvdnav/ifo_types.h Tue Apr 10 13:13:59 2007 +0200 +++ src/input/libdvdnav/ifo_types.h Tue Apr 10 13:38:19 2007 +0200 @@ -23,2 +25,2 @@ #include <inttypes.h> #include "dvd_reader.h" +#include "config.h" + - -#undef ATTRIBUTE_PACKED -#undef PRAGMA_PACK_BEGIN -#undef PRAGMA_PACK_END - -#if defined(__GNUC__) -#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) -#define ATTRIBUTE_PACKED __attribute__ ((packed)) -#define PRAGMA_PACK 0 -#endif -#endif - -#if !defined(ATTRIBUTE_PACKED) -#define ATTRIBUTE_PACKED -#define PRAGMA_PACK 1 -#endif - -#if PRAGMA_PACK -#pragma pack(1) -#endif - +#define ATTRIBUTE_PACKED XINE_PACKED /** * Common ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvdread_internal.h�������������������������������������������������0000644�0001750�0001750�00000000551�14647725152�020242� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DVDREAD_INTERNAL_H #define DVDREAD_INTERNAL_H #ifdef _MSC_VER #include <unistd.h> #endif /* _MSC_VER */ #define CHECK_VALUE(arg) \ if(!(arg)) { \ fprintf(stderr, "\n*** libdvdread: CHECK_VALUE failed in %s:%i ***" \ "\n*** for %s ***\n\n", \ __FILE__, __LINE__, # arg ); \ } #endif /* DVDREAD_INTERNAL_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/WARNING_TO_DEVELOPERS����������������������������������������������0000644�0001750�0001750�00000001553�14647725152�017751� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������./xine-lib/src/input/libdvdnav. This part of the tree should never be modified directly. The entire libdvdnav directory is periodically updated from dvd.sf.net libdvdnav cvs. If any developers notice a bug in this code, please report it to the dvd-devel@lists.sourceforge.net mailing list. If any developers have any patches for this code, please report it to the dvd-devel@lists.sourceforge.net mailing list. The dvd.sf.net libdvdnav cvs will then be updated, and xine-lib will receive the update when the next periodic update from dvd.sf.net libdvdnav cvs happens. If one uses the following command in ./xine-lib directory, One can bypass this code, and force xine-lib to use the dvd.sf.net libdvdnav cvs code directly, thus simplifying the developers testing of bug fixes/new features in libdvdnav. ./configure --with-external-dvdnav Thank you for your understanding. �����������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvdnav.h�����������������������������������������������������������0000644�0001750�0001750�00000051506�14647725152�016225� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This is the main header file applications should include if they want * to access dvdnav functionality. */ #ifndef DVDNAV_H_INCLUDED #define DVDNAV_H_INCLUDED #ifdef __cplusplus extern "C" { #endif #ifdef DVDNAV_COMPILE # include "dvdnav_events.h" # include "dvd_types.h" # include "dvd_reader.h" # include "ifo_types.h" /* For vm_cmd_t */ #else # include <dvdnav/dvdnav_events.h> # include <dvdnav/dvd_types.h> # include <dvdnav/dvd_reader.h> # include <dvdnav/ifo_types.h> /* For vm_cmd_t */ #endif /********************************************************************* * dvdnav data types * *********************************************************************/ /* * Opaque data-type can be viewed as a 'DVD handle'. You should get * a pointer to a dvdnav_t from the dvdnav_open() function. * Never call free() on the pointer, you have to give it back with * dvdnav_close(). */ typedef struct dvdnav_s dvdnav_t; /* Status as reported by most of libdvdnav's functions */ typedef int32_t dvdnav_status_t; /* * Unless otherwise stated, all functions return DVDNAV_STATUS_OK if * they succeeded, otherwise DVDNAV_STATUS_ERR is returned and the error may * be obtained by calling dvdnav_err_to_string(). */ #define DVDNAV_STATUS_ERR 0 #define DVDNAV_STATUS_OK 1 /********************************************************************* * initialisation & housekeeping functions * *********************************************************************/ /* * These functions allow you to open a DVD device and associate it * with a dvdnav_t. */ /* * Attempts to open the DVD drive at the specified path and pre-cache * the CSS-keys. libdvdread is used to access the DVD, so any source * supported by libdvdread can be given with "path". Currently, * libdvdread can access: DVD drives, DVD image files, DVD file-by-file * copies. * * The resulting dvdnav_t handle will be written to *dest. */ dvdnav_status_t dvdnav_open(dvdnav_t **dest, const char *path); /* * Closes a dvdnav_t previously opened with dvdnav_open(), freeing any * memory associated with it. */ dvdnav_status_t dvdnav_close(dvdnav_t *self); /* * Resets the DVD virtual machine and cache buffers. */ dvdnav_status_t dvdnav_reset(dvdnav_t *self); /* * Fills a pointer with a value pointing to a string describing * the path associated with an open dvdnav_t. It assigns *path to NULL * on error. */ dvdnav_status_t dvdnav_path(dvdnav_t *self, const char **path); /* * Returns a human-readable string describing the last error. */ const char* dvdnav_err_to_string(dvdnav_t *self); /* converts a dvd_time_t to PTS ticks */ int64_t dvdnav_convert_time(dvd_time_t *time); /********************************************************************* * changing and reading DVD player characteristics * *********************************************************************/ /* * These functions allow you to manipulate the various global characteristics * of the DVD playback engine. */ /* * Sets the region mask (bit 0 set implies region 1, bit 1 set implies * region 2, etc) of the virtual machine. Generally you will only need to set * this if you are playing RCE discs which query the virtual machine as to its * region setting. * * This has _nothing_ to do with the region setting of the DVD drive. */ dvdnav_status_t dvdnav_set_region_mask(dvdnav_t *self, int32_t region_mask); /* * Returns the region mask (bit 0 set implies region 1, bit 1 set implies * region 2, etc) of the virtual machine. * * This has _nothing_ to do with the region setting of the DVD drive. */ dvdnav_status_t dvdnav_get_region_mask(dvdnav_t *self, int32_t *region_mask); /* * Specify whether read-ahead caching should be used. You may not want this if your * decoding engine does its own buffering. * * The default read-ahead cache does not use an additional thread for the reading * (see read_cache.c for a threaded cache, but note that this code is currently * unmaintained). It prebuffers on VOBU level by reading ahead several buffers * on every read request. The speed of this prebuffering has been optimized to * also work on slow DVD drives. * * If in addition you want to prevent memcpy's to improve performance, have a look * at dvdnav_get_next_cache_block(). */ dvdnav_status_t dvdnav_set_readahead_flag(dvdnav_t *self, int32_t read_ahead_flag); /* * Query whether read-ahead caching/buffering will be used. */ dvdnav_status_t dvdnav_get_readahead_flag(dvdnav_t *self, int32_t *read_ahead_flag); /* * Specify whether the positioning works PGC or PG based. * Programs (PGs) on DVDs are similar to Chapters and a program chain (PGC) * usually covers a whole feature. This affects the behaviour of the * functions dvdnav_get_position() and dvdnav_sector_search(). See there. * Default is PG based positioning. */ dvdnav_status_t dvdnav_set_PGC_positioning_flag(dvdnav_t *self, int32_t pgc_based_flag); /* * Query whether positioning is PG or PGC based. */ dvdnav_status_t dvdnav_get_PGC_positioning_flag(dvdnav_t *self, int32_t *pgc_based_flag); /********************************************************************* * reading data * *********************************************************************/ /* * These functions are used to poll the playback enginge and actually get data * off the DVD. */ /* * Attempts to get the next block off the DVD and copies it into the buffer 'buf'. * If there is any special actions that may need to be performed, the value * pointed to by 'event' gets set accordingly. * * If 'event' is DVDNAV_BLOCK_OK then 'buf' is filled with the next block * (note that means it has to be at /least/ 2048 bytes big). 'len' is * then set to 2048. * * Otherwise, buf is filled with an appropriate event structure and * len is set to the length of that structure. * * See the dvdnav_events.h header for information on the various events. */ dvdnav_status_t dvdnav_get_next_block(dvdnav_t *self, uint8_t *buf, int32_t *event, int32_t *len); /* * This basically does the same as dvdnav_get_next_block. The only difference is * that it avoids a memcopy, when the requested block was found in the cache. * I such a case (cache hit) this function will return a different pointer than * the one handed in, pointing directly into the relevant block in the cache. * Those pointers must _never_ be freed but instead returned to the library via * dvdnav_free_cache_block(). */ dvdnav_status_t dvdnav_get_next_cache_block(dvdnav_t *self, uint8_t **buf, int32_t *event, int32_t *len); /* * All buffers which came from the internal cache (when dvdnav_get_next_cache_block() * returned a buffer different from the one handed in) have to be freed with this * function. Although handing in other buffers not from the cache doesn't cause any harm. */ dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf); /* * If we are currently in a still-frame this function skips it. * * See also the DVDNAV_STILL_FRAME event. */ dvdnav_status_t dvdnav_still_skip(dvdnav_t *self); /* * If we are currently in WAIT state, that is: the application is required to * wait for its fifos to become empty, calling this signals libdvdnav that this * is achieved and that it can continue. * * See also the DVDNAV_WAIT event. */ dvdnav_status_t dvdnav_wait_skip(dvdnav_t *self); /* * Returns the still time from the currently playing cell. * The still time is given in seconds with 0xff meaning an indefinite still. * * This function can be used to detect still frames before they are reached. * Some players might need this to prepare for a frame to be shown for a * longer time than usual. */ uint32_t dvdnav_get_next_still_flag(dvdnav_t *self); /* * Stops playback. The next event obtained with one of the get_next_block * functions will be a DVDNAV_STOP event. * * It is not required to call this before dvdnav_close(). */ dvdnav_status_t dvdnav_stop(dvdnav_t *self); /********************************************************************* * title/part navigation * *********************************************************************/ /* * Returns the number of titles on the disk. */ dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *self, int32_t *titles); /* * Returns the number of parts within the given title. */ dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *self, int32_t title, int32_t *parts); /* * Plays the specified title of the DVD from its beginning (that is: part 1). */ dvdnav_status_t dvdnav_title_play(dvdnav_t *self, int32_t title); /* * Plays the specified title, starting from the specified part. */ dvdnav_status_t dvdnav_part_play(dvdnav_t *self, int32_t title, int32_t part); /* * Play the specified amount of parts of the specified title of * the DVD then STOP. * * Currently unimplemented! */ dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *self, int32_t title, int32_t part, int32_t parts_to_play); /* * Play the specified title starting from the specified time. * * Currently unimplemented! */ dvdnav_status_t dvdnav_time_play(dvdnav_t *self, int32_t title, uint64_t time); /* * Stop playing the current position and jump to the specified menu. * * See also DVDMenuID_t from libdvdread */ dvdnav_status_t dvdnav_menu_call(dvdnav_t *self, DVDMenuID_t menu); /* * Return the title number and part currently being played. * A title of 0 indicates, we are in a menu. In this case, part * is set to the current menu's ID. */ dvdnav_status_t dvdnav_current_title_info(dvdnav_t *self, int32_t *title, int32_t *part); /* * Return the current position (in blocks) within the current * title and the length (in blocks) of said title. * * Current implementation is wrong and likely to behave unpredictably! * Use is discouraged! */ dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *self, uint32_t *pos, uint32_t *len); /* * This function is only available for compatibility reasons. * * Stop playing the current position and start playback of the current title * from the specified part. */ dvdnav_status_t dvdnav_part_search(dvdnav_t *self, int32_t part); /********************************************************************* * program chain/program navigation * *********************************************************************/ /* * Stop playing the current position and start playback from the last * VOBU boundary before the given sector. The sector number is not * meant to be an absolute physical DVD sector, but a relative sector * in the current program. This function cannot leave the current * program and will fail, if asked to do so. * * If program chain based positioning is enabled * (see dvdnav_set_PGC_positioning_flag()), this will seek to the relative * sector inside the current program chain. * * 'origin' can be one of SEEK_SET, SEEK_CUR, SEEK_END as defined in * fcntl.h. */ dvdnav_status_t dvdnav_sector_search(dvdnav_t *self, uint64_t offset, int32_t origin); /* * Stop playing the current position and start playback of the title * from the specified timecode. * * Currently unimplemented! */ dvdnav_status_t dvdnav_time_search(dvdnav_t *self, uint64_t time); /* * Stop playing current position and play the "GoUp"-program chain. * (which generally leads to the title menu or a higer-level menu). */ dvdnav_status_t dvdnav_go_up(dvdnav_t *self); /* * Stop playing the current position and start playback at the * previous program (if it exists). */ dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *self); /* * Stop playing the current position and start playback at the * first program. */ dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *self); /* * Stop playing the current position and start playback at the * next program (if it exists). */ dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *self); /* * Return the current position (in blocks) within the current * program and the length (in blocks) of current program. * * If program chain based positioning is enabled * (see dvdnav_set_PGC_positioning_flag()), this will return the * relative position in and the length of the current program chain. */ dvdnav_status_t dvdnav_get_position(dvdnav_t *self, uint32_t *pos, uint32_t *len); /********************************************************************* * menu highlights * *********************************************************************/ /* * Most functions related to highlights take a NAV PCI packet as a parameter. * While you can get the such a packet from libdvdnav, for players with internal * FIFOs, this will result in errors, because due to the FIFO length, libdvdnav will * be ahead in the stream compared to what the user is seeing on screen. * Therefore, player applications who have a NAV packet available, which is * better in sync with the actual playback should always pass this one to these * functions. */ /* * Get the currently highlighted button * number (1..36) or 0 if no button is highlighted. */ dvdnav_status_t dvdnav_get_current_highlight(dvdnav_t *self, int32_t *button); /* * Returns the Presentation Control Information (PCI) structure associated * with the current position. * * Read the general notes above. * See also libdvdreads nav_types.h for definition of pci_t. */ pci_t* dvdnav_get_current_nav_pci(dvdnav_t *self); /* * Returns the DSI (data search information) structure associated * with the current position. * * Read the general notes above. * See also libdvdreads nav_types.h for definition of dsi_t. */ dsi_t* dvdnav_get_current_nav_dsi(dvdnav_t *self); /* * Get the area associated with a certain button. */ dvdnav_status_t dvdnav_get_highlight_area(pci_t *nav_pci , int32_t button, int32_t mode, dvdnav_highlight_area_t *highlight); /* * Move button highlight around as suggested by function name (e.g. with arrow keys). */ dvdnav_status_t dvdnav_upper_button_select(dvdnav_t *self, pci_t *pci); dvdnav_status_t dvdnav_lower_button_select(dvdnav_t *self, pci_t *pci); dvdnav_status_t dvdnav_right_button_select(dvdnav_t *self, pci_t *pci); dvdnav_status_t dvdnav_left_button_select(dvdnav_t *self, pci_t *pci); /* * Activate ("press") the currently highlighted button. */ dvdnav_status_t dvdnav_button_activate(dvdnav_t *self, pci_t *pci); /* * Highlight a specific button. */ dvdnav_status_t dvdnav_button_select(dvdnav_t *self, pci_t *pci, int32_t button); /* * Activate ("press") specified button. */ dvdnav_status_t dvdnav_button_select_and_activate(dvdnav_t *self, pci_t *pci, int32_t button); /* * Activate (press) a button and execute specified command. */ dvdnav_status_t dvdnav_button_activate_cmd(dvdnav_t *self, int32_t button, vm_cmd_t *cmd); /* * Select button at specified video frame coordinates. */ dvdnav_status_t dvdnav_mouse_select(dvdnav_t *self, pci_t *pci, int32_t x, int32_t y); /* * Activate ("press") button at specified video frame coordinates. */ dvdnav_status_t dvdnav_mouse_activate(dvdnav_t *self, pci_t *pci, int32_t x, int32_t y); /********************************************************************* * languages * *********************************************************************/ /* * The language codes expected by these functions are two character * codes as defined in ISO639. */ /* * Set which menu language we should use per default. */ dvdnav_status_t dvdnav_menu_language_select(dvdnav_t *self, char *code); /* * Set which audio language we should use per default. */ dvdnav_status_t dvdnav_audio_language_select(dvdnav_t *self, char *code); /* * Set which spu language we should use per default. */ dvdnav_status_t dvdnav_spu_language_select(dvdnav_t *self, char *code); /********************************************************************* * obtaining stream attributes * *********************************************************************/ /* * Return a string describing the title of the DVD. * This is an ID string encoded on the disc by the author. In many cases * this is a descriptive string such as `THE_MATRIX' but sometimes is sigularly * uninformative such as `PDVD-011421'. Some DVD authors even forget to set this, * so you may also read the default of the authoring software they used, like * `DVDVolume'. */ dvdnav_status_t dvdnav_get_title_string(dvdnav_t *self, const char **title_str); /* * Get video aspect code. * The aspect code does only change on VTS boundaries. * See the DVDNAV_VTS_CHANGE event. * * 0 -- 4:3, 2 -- 16:9 */ uint8_t dvdnav_get_video_aspect(dvdnav_t *self); /* * Get video scaling permissions. * The scaling permission does only change on VTS boundaries. * See the DVDNAV_VTS_CHANGE event. * * bit0 set = deny letterboxing, bit1 set = deny pan&scan */ uint8_t dvdnav_get_video_scale_permission(dvdnav_t *self); /* * Converts a *logical* audio stream id into language code * (returns 0xffff if no such stream). */ uint16_t dvdnav_audio_stream_to_lang(dvdnav_t *self, uint8_t stream); /* * Converts a *logical* subpicture stream id into country code * (returns 0xffff if no such stream). */ uint16_t dvdnav_spu_stream_to_lang(dvdnav_t *self, uint8_t stream); /* * Converts a *physical* (MPEG) audio stream id into a logical stream number. */ int8_t dvdnav_get_audio_logical_stream(dvdnav_t *self, uint8_t audio_num); /* * Converts a *physical* (MPEG) subpicture stream id into a logical stream number. */ int8_t dvdnav_get_spu_logical_stream(dvdnav_t *self, uint8_t subp_num); /* * Get active audio stream. */ int8_t dvdnav_get_active_audio_stream(dvdnav_t *self); /* * Get active spu stream. */ int8_t dvdnav_get_active_spu_stream(dvdnav_t *self); /********************************************************************* * multiple angles * *********************************************************************/ /* * The libdvdnav library abstracts away the difference between seamless and * non-seamless angles. From the point of view of the programmer you just set the * angle number and all is well in the world. You will always see only the * selected angle coming from the get_next_block functions. * * Note: * It is quite possible that some tremendously strange DVD feature might change the * angle number from under you. Generally you should always view the results from * dvdnav_get_angle_info() as definitive only up to the next time you call * dvdnav_get_next_block(). */ /* * Sets the current angle. If you try to follow a non existant angle * the call fails. */ dvdnav_status_t dvdnav_angle_change(dvdnav_t *self, int32_t angle); /* * Returns the current angle and number of angles present. */ dvdnav_status_t dvdnav_get_angle_info(dvdnav_t *self, int32_t *current_angle, int32_t *number_of_angles); /********************************************************************* * domain queries * *********************************************************************/ /* * Are we in the First Play domain? */ int8_t dvdnav_is_domain_fp(dvdnav_t *self); /* * Are we in the Video management Menu domain? */ int8_t dvdnav_is_domain_vmgm(dvdnav_t *self); /* * Are we in the Video Title Menu domain? */ int8_t dvdnav_is_domain_vtsm(dvdnav_t *self); /* * Are we in the Video Title Set domain? */ int8_t dvdnav_is_domain_vts(dvdnav_t *self); #ifdef __cplusplus } #endif #endif /* DVDNAV_H_INCLUDED */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/vmcmd.c������������������������������������������������������������0000644�0001750�0001750�00000037405�14647725152�016046� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort * 2002-2004 the dvdnav project * * This file is part of libdvdnav, a DVD navigation library. It is modified * from a file originally part of the Ogle DVD player. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <ctype.h> #include <inttypes.h> #include "dvdnav_internal.h" /* freebsd compatibility */ #ifndef PRIu8 #define PRIu8 "d" #endif /* freebsd compatibility */ #ifndef PRIu16 #define PRIu16 "d" #endif static const char *cmp_op_table[] = { NULL, "&", "==", "!=", ">=", ">", "<=", "<" }; static const char *set_op_table[] = { NULL, "=", "<->", "+=", "-=", "*=", "/=", "%=", "rnd", "&=", "|=", "^=" }; static const char *link_table[] = { "LinkNoLink", "LinkTopC", "LinkNextC", "LinkPrevC", NULL, "LinkTopPG", "LinkNextPG", "LinkPrevPG", NULL, "LinkTopPGC", "LinkNextPGC", "LinkPrevPGC", "LinkGoUpPGC", "LinkTailPGC", NULL, NULL, "RSM" }; static const char *system_reg_table[] = { "Menu Description Language Code", "Audio Stream Number", "Sub-picture Stream Number", "Angle Number", "Title Track Number", "VTS Title Track Number", "VTS PGC Number", "PTT Number for One_Sequential_PGC_Title", "Highlighted Button Number", "Navigation Timer", "Title PGC Number for Navigation Timer", "Audio Mixing Mode for Karaoke", "Country Code for Parental Management", "Parental Level", "Player Configurations for Video", "Player Configurations for Audio", "Initial Language Code for Audio", "Initial Language Code Extension for Audio", "Initial Language Code for Sub-picture", "Initial Language Code Extension for Sub-picture", "Player Regional Code", "Reserved 21", "Reserved 22", "Reserved 23" }; static const char *system_reg_abbr_table[] = { NULL, "ASTN", "SPSTN", "AGLN", "TTN", "VTS_TTN", "TT_PGCN", "PTTN", "HL_BTNN", "NVTMR", "NV_PGCN", NULL, "CC_PLT", "PLT", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; static void print_system_reg(uint16_t reg) { if(reg < sizeof(system_reg_abbr_table) / sizeof(char *)) fprintf(MSG_OUT, "%s (SRPM:%d)", system_reg_table[reg], reg); else fprintf(MSG_OUT, " WARNING: Unknown system register ( reg=%d ) ", reg); } static void print_g_reg(uint8_t reg) { if(reg < 16) fprintf(MSG_OUT, "g[%" PRIu8 "]", reg); else fprintf(MSG_OUT, " WARNING: Unknown general register "); } static void print_reg(uint8_t reg) { if(reg & 0x80) print_system_reg(reg & 0x7f); else print_g_reg(reg & 0x7f); } static void print_cmp_op(uint8_t op) { if(op < sizeof(cmp_op_table) / sizeof(char *) && cmp_op_table[op] != NULL) fprintf(MSG_OUT, " %s ", cmp_op_table[op]); else fprintf(MSG_OUT, " WARNING: Unknown compare op "); } static void print_set_op(uint8_t op) { if(op < sizeof(set_op_table) / sizeof(char *) && set_op_table[op] != NULL) fprintf(MSG_OUT, " %s ", set_op_table[op]); else fprintf(MSG_OUT, " WARNING: Unknown set op "); } static void print_reg_or_data(command_t* command, int immediate, int start) { if(immediate) { uint32_t i = vm_getbits(command, start, 16); fprintf(MSG_OUT, "0x%x", i); if(isprint(i & 0xff) && isprint((i>>8) & 0xff)) fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff)); } else { print_reg(vm_getbits(command, start - 8, 8)); } } static void print_reg_or_data_2(command_t* command, int immediate, int start) { if(immediate) fprintf(MSG_OUT, "0x%x", vm_getbits(command, start - 1, 7)); else fprintf(MSG_OUT, "g[%" PRIu8 "]", vm_getbits(command, start - 4, 4)); } static void print_reg_or_data_3(command_t* command, int immediate, int start) { if(immediate) { uint32_t i = vm_getbits(command, start, 16); fprintf(MSG_OUT, "0x%x", i); if(isprint(i & 0xff) && isprint((i>>8) & 0xff)) fprintf(MSG_OUT, " (\"%c%c\")", (char)((i>>8) & 0xff), (char)(i & 0xff)); } else { print_reg(vm_getbits(command, start, 8)); } } static void print_if_version_1(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { fprintf(MSG_OUT, "if ("); print_g_reg(vm_getbits(command,39,8)); print_cmp_op(op); print_reg_or_data(command, vm_getbits(command, 55,1), 31); fprintf(MSG_OUT, ") "); } } static void print_if_version_2(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { fprintf(MSG_OUT, "if ("); print_reg(vm_getbits(command, 15, 8)); print_cmp_op(op); print_reg(vm_getbits(command, 7, 8)); fprintf(MSG_OUT, ") "); } } static void print_if_version_3(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { fprintf(MSG_OUT, "if ("); print_g_reg(vm_getbits(command, 43, 4)); print_cmp_op(op); print_reg_or_data(command, vm_getbits(command, 55, 1), 15); fprintf(MSG_OUT, ") "); } } static void print_if_version_4(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); if(op) { fprintf(MSG_OUT, "if ("); print_g_reg(vm_getbits(command, 51, 4)); print_cmp_op(op); print_reg_or_data(command, vm_getbits(command, 55, 1), 31); fprintf(MSG_OUT, ") "); } } static void print_if_version_5(command_t* command) { uint8_t op = vm_getbits(command, 54, 3); int set_immediate = vm_getbits(command, 60, 1); if(op) { if (set_immediate) { fprintf(MSG_OUT, "if ("); print_g_reg(vm_getbits(command, 31, 8)); print_cmp_op(op); print_reg(vm_getbits(command, 23, 8)); fprintf(MSG_OUT, ") "); } else { fprintf(MSG_OUT, "if ("); print_g_reg(vm_getbits(command, 39, 8)); print_cmp_op(op); print_reg_or_data(command, vm_getbits(command, 55, 1), 31); fprintf(MSG_OUT, ") "); } } } static void print_special_instruction(command_t* command) { uint8_t op = vm_getbits(command, 51, 4); switch(op) { case 0: /* NOP */ fprintf(MSG_OUT, "Nop"); break; case 1: /* Goto line */ fprintf(MSG_OUT, "Goto %" PRIu8, vm_getbits(command, 7, 8)); break; case 2: /* Break */ fprintf(MSG_OUT, "Break"); break; case 3: /* Parental level */ fprintf(MSG_OUT, "SetTmpPML %" PRIu8 ", Goto %" PRIu8, vm_getbits(command, 11, 4), vm_getbits(command, 7, 8)); break; default: fprintf(MSG_OUT, "WARNING: Unknown special instruction (%i)", vm_getbits(command, 51, 4)); } } static void print_linksub_instruction(command_t* command) { uint32_t linkop = vm_getbits(command, 7, 8); uint32_t button = vm_getbits(command, 15, 6); if(linkop < sizeof(link_table)/sizeof(char *) && link_table[linkop] != NULL) fprintf(MSG_OUT, "%s (button %" PRIu8 ")", link_table[linkop], button); else fprintf(MSG_OUT, "WARNING: Unknown linksub instruction (%i)", linkop); } static void print_link_instruction(command_t* command, int optional) { uint8_t op = vm_getbits(command, 51, 4); if(optional && op) fprintf(MSG_OUT, ", "); switch(op) { case 0: if(!optional) fprintf(MSG_OUT, "WARNING: NOP (link)!"); break; case 1: print_linksub_instruction(command); break; case 4: fprintf(MSG_OUT, "LinkPGCN %" PRIu16, vm_getbits(command, 14, 15)); break; case 5: fprintf(MSG_OUT, "LinkPTT %" PRIu16 " (button %" PRIu8 ")", vm_getbits(command, 9, 10), vm_getbits(command, 15, 6)); break; case 6: fprintf(MSG_OUT, "LinkPGN %" PRIu8 " (button %" PRIu8 ")", vm_getbits(command, 6, 7), vm_getbits(command, 15, 6)); break; case 7: fprintf(MSG_OUT, "LinkCN %" PRIu8 " (button %" PRIu8 ")", vm_getbits(command, 7, 8), vm_getbits(command, 15, 6)); break; default: fprintf(MSG_OUT, "WARNING: Unknown link instruction"); } } static void print_jump_instruction(command_t* command) { switch(vm_getbits(command, 51, 4)) { case 1: fprintf(MSG_OUT, "Exit"); break; case 2: fprintf(MSG_OUT, "JumpTT %" PRIu8, vm_getbits(command, 22, 7)); break; case 3: fprintf(MSG_OUT, "JumpVTS_TT %" PRIu8, vm_getbits(command, 22, 7)); break; case 5: fprintf(MSG_OUT, "JumpVTS_PTT %" PRIu8 ":%" PRIu16, vm_getbits(command, 22, 7), vm_getbits(command, 41, 10)); break; case 6: switch(vm_getbits(command, 23, 2)) { case 0: fprintf(MSG_OUT, "JumpSS FP"); break; case 1: fprintf(MSG_OUT, "JumpSS VMGM (menu %" PRIu8 ")", vm_getbits(command, 19, 4)); break; case 2: fprintf(MSG_OUT, "JumpSS VTSM (vts %" PRIu8 ", title %" PRIu8 ", menu %" PRIu8 ")", vm_getbits(command, 30, 7), vm_getbits(command, 38, 7), vm_getbits(command, 19, 4)); break; case 3: fprintf(MSG_OUT, "JumpSS VMGM (pgc %" PRIu8 ")", vm_getbits(command, 46, 15)); break; } break; case 8: switch(vm_getbits(command, 23, 2)) { case 0: fprintf(MSG_OUT, "CallSS FP (rsm_cell %" PRIu8 ")", vm_getbits(command, 31, 8)); break; case 1: fprintf(MSG_OUT, "CallSS VMGM (menu %" PRIu8 ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8)); break; case 2: fprintf(MSG_OUT, "CallSS VTSM (menu %" PRIu8 ", rsm_cell %" PRIu8 ")", vm_getbits(command, 19, 4), vm_getbits(command, 31, 8)); break; case 3: fprintf(MSG_OUT, "CallSS VMGM (pgc %" PRIu8 ", rsm_cell %" PRIu8 ")", vm_getbits(command, 46, 15), vm_getbits(command, 31, 8)); break; } break; default: fprintf(MSG_OUT, "WARNING: Unknown Jump/Call instruction"); } } static void print_system_set(command_t* command) { int i; /* FIXME: What about SPRM11 ? Karaoke */ /* Surely there must be some system set command for that ? */ switch(vm_getbits(command, 59, 4)) { case 1: /* Set system reg 1 &| 2 &| 3 (Audio, Subp. Angle) */ for(i = 1; i <= 3; i++) { if(vm_getbits(command, 47 - (i*8), 1)) { print_system_reg(i); fprintf(MSG_OUT, " = "); print_reg_or_data_2(command, vm_getbits(command, 60, 1), 47 - (i*8) ); fprintf(MSG_OUT, " "); } } break; case 2: /* Set system reg 9 & 10 (Navigation timer, Title PGC number) */ print_system_reg(9); fprintf(MSG_OUT, " = "); print_reg_or_data(command, vm_getbits(command, 60, 1), 47); fprintf(MSG_OUT, " "); print_system_reg(10); fprintf(MSG_OUT, " = %" PRIu16, vm_getbits(command, 30, 15)); /* ?? */ break; case 3: /* Mode: Counter / Register + Set */ fprintf(MSG_OUT, "SetMode "); if(vm_getbits(command, 23, 1)) fprintf(MSG_OUT, "Counter "); else fprintf(MSG_OUT, "Register "); print_g_reg(vm_getbits(command, 19, 4)); print_set_op(0x1); /* '=' */ print_reg_or_data(command, vm_getbits(command, 60, 1), 47); break; case 6: /* Set system reg 8 (Highlighted button) */ print_system_reg(8); if(vm_getbits(command, 60, 1)) /* immediate */ fprintf(MSG_OUT, " = 0x%x (button no %d)", vm_getbits(command, 31, 16), vm_getbits(command, 31, 6)); else fprintf(MSG_OUT, " = g[%" PRIu8 "]", vm_getbits(command, 19, 4)); break; default: fprintf(MSG_OUT, "WARNING: Unknown system set instruction (%i)", vm_getbits(command, 59, 4)); } } static void print_set_version_1(command_t* command) { uint8_t set_op = vm_getbits(command, 59, 4); if(set_op) { print_g_reg(vm_getbits(command, 35, 4)); print_set_op(set_op); print_reg_or_data(command, vm_getbits(command, 60, 1), 31); } else { fprintf(MSG_OUT, "NOP"); } } static void print_set_version_2(command_t* command) { uint8_t set_op = vm_getbits(command, 59, 4); if(set_op) { print_g_reg(vm_getbits(command, 51, 4)); print_set_op(set_op); print_reg_or_data(command, vm_getbits(command, 60, 1), 47); } else { fprintf(MSG_OUT, "NOP"); } } static void print_set_version_3(command_t* command) { uint8_t set_op = vm_getbits(command, 59, 4); if(set_op) { print_g_reg(vm_getbits(command, 51, 4)); print_set_op(set_op); print_reg_or_data_3(command, vm_getbits(command, 60, 1), 47); } else { fprintf(MSG_OUT, "NOP"); } } void vm_print_mnemonic(vm_cmd_t *vm_command) { command_t command; command.instruction =( (uint64_t) vm_command->bytes[0] << 56 ) | ( (uint64_t) vm_command->bytes[1] << 48 ) | ( (uint64_t) vm_command->bytes[2] << 40 ) | ( (uint64_t) vm_command->bytes[3] << 32 ) | ( (uint64_t) vm_command->bytes[4] << 24 ) | ( (uint64_t) vm_command->bytes[5] << 16 ) | ( (uint64_t) vm_command->bytes[6] << 8 ) | (uint64_t) vm_command->bytes[7] ; command.examined = 0; switch(vm_getbits(&command,63,3)) { /* three first bits */ case 0: /* Special instructions */ print_if_version_1(&command); print_special_instruction(&command); break; case 1: /* Jump/Call or Link instructions */ if(vm_getbits(&command,60,1)) { print_if_version_2(&command); print_jump_instruction(&command); } else { print_if_version_1(&command); print_link_instruction(&command, 0); /* must be pressent */ } break; case 2: /* Set System Parameters instructions */ print_if_version_2(&command); print_system_set(&command); print_link_instruction(&command, 1); /* either 'if' or 'link' */ break; case 3: /* Set General Parameters instructions */ print_if_version_3(&command); print_set_version_1(&command); print_link_instruction(&command, 1); /* either 'if' or 'link' */ break; case 4: /* Set, Compare -> LinkSub instructions */ print_set_version_2(&command); fprintf(MSG_OUT, ", "); print_if_version_4(&command); print_linksub_instruction(&command); break; case 5: /* Compare -> (Set and LinkSub) instructions */ print_if_version_5(&command); fprintf(MSG_OUT, "{ "); print_set_version_3(&command); fprintf(MSG_OUT, ", "); print_linksub_instruction(&command); fprintf(MSG_OUT, " }"); break; case 6: /* Compare -> Set, always LinkSub instructions */ print_if_version_5(&command); fprintf(MSG_OUT, "{ "); print_set_version_3(&command); fprintf(MSG_OUT, " } "); print_linksub_instruction(&command); break; default: fprintf(MSG_OUT, "WARNING: Unknown instruction type (%i)", vm_getbits(&command, 63, 3)); } /* Check if there still are bits set that were not examined */ if(command.instruction & ~ command.examined) { fprintf(MSG_OUT, " libdvdnav: vmcmd.c: [WARNING, unknown bits:"); fprintf(MSG_OUT, " %08"PRIx64, (command.instruction & ~ command.examined) ); fprintf(MSG_OUT, "]"); } } void vm_print_cmd(int row, vm_cmd_t *vm_command) { int i; fprintf(MSG_OUT, "(%03d) ", row + 1); for(i = 0; i < 8; i++) fprintf(MSG_OUT, "%02x ", vm_command->bytes[i]); fprintf(MSG_OUT, "| "); vm_print_mnemonic(vm_command); fprintf(MSG_OUT, "\n"); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/ifo_types.h��������������������������������������������������������0000644�0001750�0001750�00000054672�14647725152�016753� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef IFO_TYPES_H_INCLUDED #define IFO_TYPES_H_INCLUDED /* * Copyright (C) 2000, 2001 Björn Englund <d4bjorn@dtek.chalmers.se>, * Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <inttypes.h> #include "dvd_reader.h" #include "config.h" #define ATTRIBUTE_PACKED XINE_PACKED /** * Common * * The following structures are used in both the VMGI and VTSI. */ /** * DVD Time Information. */ typedef struct { uint8_t hour; uint8_t minute; uint8_t second; uint8_t frame_u; /* The two high bits are the frame rate. */ } ATTRIBUTE_PACKED dvd_time_t; /** * Type to store per-command data. */ typedef struct { uint8_t bytes[8]; } ATTRIBUTE_PACKED vm_cmd_t; #define COMMAND_DATA_SIZE 8 /** * Video Attributes. */ typedef struct { #ifdef WORDS_BIGENDIAN unsigned char mpeg_version : 2; unsigned char video_format : 2; unsigned char display_aspect_ratio : 2; unsigned char permitted_df : 2; unsigned char line21_cc_1 : 1; unsigned char line21_cc_2 : 1; unsigned char unknown1 : 1; unsigned char bit_rate : 1; unsigned char picture_size : 2; unsigned char letterboxed : 1; unsigned char film_mode : 1; #else unsigned char permitted_df : 2; unsigned char display_aspect_ratio : 2; unsigned char video_format : 2; unsigned char mpeg_version : 2; unsigned char film_mode : 1; unsigned char letterboxed : 1; unsigned char picture_size : 2; unsigned char bit_rate : 1; unsigned char unknown1 : 1; unsigned char line21_cc_2 : 1; unsigned char line21_cc_1 : 1; #endif } ATTRIBUTE_PACKED video_attr_t; /** * Audio Attributes. */ typedef struct { #ifdef WORDS_BIGENDIAN unsigned char audio_format : 3; unsigned char multichannel_extension : 1; unsigned char lang_type : 2; unsigned char application_mode : 2; unsigned char quantization : 2; unsigned char sample_frequency : 2; unsigned char unknown1 : 1; unsigned char channels : 3; #else unsigned char application_mode : 2; unsigned char lang_type : 2; unsigned char multichannel_extension : 1; unsigned char audio_format : 3; unsigned char channels : 3; unsigned char unknown1 : 1; unsigned char sample_frequency : 2; unsigned char quantization : 2; #endif uint16_t lang_code; uint8_t lang_extension; uint8_t code_extension; uint8_t unknown3; union { struct ATTRIBUTE_PACKED { #ifdef WORDS_BIGENDIAN unsigned char unknown4 : 1; unsigned char channel_assignment : 3; unsigned char version : 2; unsigned char mc_intro : 1; /* probably 0: true, 1:false */ unsigned char mode : 1; /* Karaoke mode 0: solo 1: duet */ #else unsigned char mode : 1; unsigned char mc_intro : 1; unsigned char version : 2; unsigned char channel_assignment : 3; unsigned char unknown4 : 1; #endif } karaoke; struct ATTRIBUTE_PACKED { #ifdef WORDS_BIGENDIAN unsigned char unknown5 : 4; unsigned char dolby_encoded : 1; /* suitable for surround decoding */ unsigned char unknown6 : 3; #else unsigned char unknown6 : 3; unsigned char dolby_encoded : 1; unsigned char unknown5 : 4; #endif } surround; } app_info; } ATTRIBUTE_PACKED audio_attr_t; /** * MultiChannel Extension */ typedef struct { #ifdef WORDS_BIGENDIAN unsigned int zero1 : 7; unsigned int ach0_gme : 1; unsigned int zero2 : 7; unsigned int ach1_gme : 1; unsigned int zero3 : 4; unsigned int ach2_gv1e : 1; unsigned int ach2_gv2e : 1; unsigned int ach2_gm1e : 1; unsigned int ach2_gm2e : 1; unsigned int zero4 : 4; unsigned int ach3_gv1e : 1; unsigned int ach3_gv2e : 1; unsigned int ach3_gmAe : 1; unsigned int ach3_se2e : 1; unsigned int zero5 : 4; unsigned int ach4_gv1e : 1; unsigned int ach4_gv2e : 1; unsigned int ach4_gmBe : 1; unsigned int ach4_seBe : 1; #else unsigned char ach0_gme : 1; unsigned char zero1 : 7; unsigned char ach1_gme : 1; unsigned char zero2 : 7; unsigned char ach2_gm2e : 1; unsigned char ach2_gm1e : 1; unsigned char ach2_gv2e : 1; unsigned char ach2_gv1e : 1; unsigned char zero3 : 4; unsigned char ach3_se2e : 1; unsigned char ach3_gmAe : 1; unsigned char ach3_gv2e : 1; unsigned char ach3_gv1e : 1; unsigned char zero4 : 4; unsigned char ach4_seBe : 1; unsigned char ach4_gmBe : 1; unsigned char ach4_gv2e : 1; unsigned char ach4_gv1e : 1; unsigned char zero5 : 4; #endif uint8_t zero6[19]; } ATTRIBUTE_PACKED multichannel_ext_t; /** * Subpicture Attributes. */ typedef struct { /* * type: 0 not specified * 1 language * 2 other * coding mode: 0 run length * 1 extended * 2 other * language: indicates language if type == 1 * lang extension: if type == 1 contains the lang extension */ #ifdef WORDS_BIGENDIAN unsigned char code_mode : 3; unsigned char zero1 : 3; unsigned char type : 2; #else unsigned char type : 2; unsigned char zero1 : 3; unsigned char code_mode : 3; #endif uint8_t zero2; uint16_t lang_code; uint8_t lang_extension; uint8_t code_extension; } ATTRIBUTE_PACKED subp_attr_t; /** * PGC Command Table. */ typedef struct { uint16_t nr_of_pre; uint16_t nr_of_post; uint16_t nr_of_cell; uint16_t zero_1; vm_cmd_t *pre_cmds; vm_cmd_t *post_cmds; vm_cmd_t *cell_cmds; } ATTRIBUTE_PACKED pgc_command_tbl_t; #define PGC_COMMAND_TBL_SIZE 8 /** * PGC Program Map */ typedef uint8_t pgc_program_map_t; /** * Cell Playback Information. */ typedef struct { #ifdef WORDS_BIGENDIAN unsigned int block_mode : 2; unsigned int block_type : 2; unsigned int seamless_play : 1; unsigned int interleaved : 1; unsigned int stc_discontinuity: 1; unsigned int seamless_angle : 1; unsigned int playback_mode : 1; /**< When set, enter StillMode after each VOBU */ unsigned int restricted : 1; /**< ?? drop out of fastforward? */ unsigned int unknown2 : 6; #else unsigned char seamless_angle : 1; unsigned char stc_discontinuity: 1; unsigned char interleaved : 1; unsigned char seamless_play : 1; unsigned char block_type : 2; unsigned char block_mode : 2; unsigned char unknown2 : 6; unsigned char restricted : 1; unsigned char playback_mode : 1; #endif uint8_t still_time; uint8_t cell_cmd_nr; dvd_time_t playback_time; uint32_t first_sector; uint32_t first_ilvu_end_sector; uint32_t last_vobu_start_sector; uint32_t last_sector; } ATTRIBUTE_PACKED cell_playback_t; #define BLOCK_TYPE_NONE 0x0 #define BLOCK_TYPE_ANGLE_BLOCK 0x1 #define BLOCK_MODE_NOT_IN_BLOCK 0x0 #define BLOCK_MODE_FIRST_CELL 0x1 #define BLOCK_MODE_IN_BLOCK 0x2 #define BLOCK_MODE_LAST_CELL 0x3 /** * Cell Position Information. */ typedef struct { uint16_t vob_id_nr; uint8_t zero_1; uint8_t cell_nr; } ATTRIBUTE_PACKED cell_position_t; /** * User Operations. */ typedef struct { #ifdef WORDS_BIGENDIAN unsigned int zero : 7; /* 25-31 */ unsigned int video_pres_mode_change : 1; /* 24 */ unsigned int karaoke_audio_pres_mode_change : 1; /* 23 */ unsigned int angle_change : 1; unsigned int subpic_stream_change : 1; unsigned int audio_stream_change : 1; unsigned int pause_on : 1; unsigned int still_off : 1; unsigned int button_select_or_activate : 1; unsigned int resume : 1; /* 16 */ unsigned int chapter_menu_call : 1; /* 15 */ unsigned int angle_menu_call : 1; unsigned int audio_menu_call : 1; unsigned int subpic_menu_call : 1; unsigned int root_menu_call : 1; unsigned int title_menu_call : 1; unsigned int backward_scan : 1; unsigned int forward_scan : 1; /* 8 */ unsigned int next_pg_search : 1; /* 7 */ unsigned int prev_or_top_pg_search : 1; unsigned int time_or_chapter_search : 1; unsigned int go_up : 1; unsigned int stop : 1; unsigned int title_play : 1; unsigned int chapter_search_or_play : 1; unsigned int title_or_time_play : 1; /* 0 */ #else unsigned int video_pres_mode_change : 1; /* 24 */ unsigned int zero : 7; /* 25-31 */ unsigned int resume : 1; /* 16 */ unsigned int button_select_or_activate : 1; unsigned int still_off : 1; unsigned int pause_on : 1; unsigned int audio_stream_change : 1; unsigned int subpic_stream_change : 1; unsigned int angle_change : 1; unsigned int karaoke_audio_pres_mode_change : 1; /* 23 */ unsigned int forward_scan : 1; /* 8 */ unsigned int backward_scan : 1; unsigned int title_menu_call : 1; unsigned int root_menu_call : 1; unsigned int subpic_menu_call : 1; unsigned int audio_menu_call : 1; unsigned int angle_menu_call : 1; unsigned int chapter_menu_call : 1; /* 15 */ unsigned int title_or_time_play : 1; /* 0 */ unsigned int chapter_search_or_play : 1; unsigned int title_play : 1; unsigned int stop : 1; unsigned int go_up : 1; unsigned int time_or_chapter_search : 1; unsigned int prev_or_top_pg_search : 1; unsigned int next_pg_search : 1; /* 7 */ #endif } ATTRIBUTE_PACKED user_ops_t; /** * Program Chain Information. */ typedef struct { uint16_t zero_1; uint8_t nr_of_programs; uint8_t nr_of_cells; dvd_time_t playback_time; user_ops_t prohibited_ops; uint16_t audio_control[8]; /* New type? */ uint32_t subp_control[32]; /* New type? */ uint16_t next_pgc_nr; uint16_t prev_pgc_nr; uint16_t goup_pgc_nr; uint8_t still_time; uint8_t pg_playback_mode; uint32_t palette[16]; /* New type struct {zero_1, Y, Cr, Cb} ? */ uint16_t command_tbl_offset; uint16_t program_map_offset; uint16_t cell_playback_offset; uint16_t cell_position_offset; pgc_command_tbl_t *command_tbl; pgc_program_map_t *program_map; cell_playback_t *cell_playback; cell_position_t *cell_position; } ATTRIBUTE_PACKED pgc_t; #define PGC_SIZE 236 /** * Program Chain Information Search Pointer. */ typedef struct { uint8_t entry_id; #ifdef WORDS_BIGENDIAN unsigned int block_mode : 2; unsigned int block_type : 2; unsigned int unknown1 : 4; #else unsigned char unknown1 : 4; unsigned char block_type : 2; unsigned char block_mode : 2; #endif uint16_t ptl_id_mask; uint32_t pgc_start_byte; pgc_t *pgc; } ATTRIBUTE_PACKED pgci_srp_t; #define PGCI_SRP_SIZE 8 /** * Program Chain Information Table. */ typedef struct { uint16_t nr_of_pgci_srp; uint16_t zero_1; uint32_t last_byte; pgci_srp_t *pgci_srp; } ATTRIBUTE_PACKED pgcit_t; #define PGCIT_SIZE 8 /** * Menu PGCI Language Unit. */ typedef struct { uint16_t lang_code; uint8_t lang_extension; uint8_t exists; uint32_t lang_start_byte; pgcit_t *pgcit; } ATTRIBUTE_PACKED pgci_lu_t; #define PGCI_LU_SIZE 8 /** * Menu PGCI Unit Table. */ typedef struct { uint16_t nr_of_lus; uint16_t zero_1; uint32_t last_byte; pgci_lu_t *lu; } ATTRIBUTE_PACKED pgci_ut_t; #define PGCI_UT_SIZE 8 /** * Cell Address Information. */ typedef struct { uint16_t vob_id; uint8_t cell_id; uint8_t zero_1; uint32_t start_sector; uint32_t last_sector; } ATTRIBUTE_PACKED cell_adr_t; /** * Cell Address Table. */ typedef struct { uint16_t nr_of_vobs; /* VOBs */ uint16_t zero_1; uint32_t last_byte; cell_adr_t *cell_adr_table; /* No explicit size given. */ } ATTRIBUTE_PACKED c_adt_t; #define C_ADT_SIZE 8 /** * VOBU Address Map. */ typedef struct { uint32_t last_byte; uint32_t *vobu_start_sectors; } ATTRIBUTE_PACKED vobu_admap_t; #define VOBU_ADMAP_SIZE 4 /** * VMGI * * The following structures relate to the Video Manager. */ /** * Video Manager Information Management Table. */ typedef struct { char vmg_identifier[12]; uint32_t vmg_last_sector; uint8_t zero_1[12]; uint32_t vmgi_last_sector; uint8_t zero_2; uint8_t specification_version; uint32_t vmg_category; uint16_t vmg_nr_of_volumes; uint16_t vmg_this_volume_nr; uint8_t disc_side; uint8_t zero_3[19]; uint16_t vmg_nr_of_title_sets; /* Number of VTSs. */ char provider_identifier[32]; uint64_t vmg_pos_code; uint8_t zero_4[24]; uint32_t vmgi_last_byte; uint32_t first_play_pgc; uint8_t zero_5[56]; uint32_t vmgm_vobs; /* sector */ uint32_t tt_srpt; /* sector */ uint32_t vmgm_pgci_ut; /* sector */ uint32_t ptl_mait; /* sector */ uint32_t vts_atrt; /* sector */ uint32_t txtdt_mgi; /* sector */ uint32_t vmgm_c_adt; /* sector */ uint32_t vmgm_vobu_admap; /* sector */ uint8_t zero_6[32]; video_attr_t vmgm_video_attr; uint8_t zero_7; uint8_t nr_of_vmgm_audio_streams; /* should be 0 or 1 */ audio_attr_t vmgm_audio_attr; audio_attr_t zero_8[7]; uint8_t zero_9[17]; uint8_t nr_of_vmgm_subp_streams; /* should be 0 or 1 */ subp_attr_t vmgm_subp_attr; subp_attr_t zero_10[27]; /* XXX: how much 'padding' here? */ } ATTRIBUTE_PACKED vmgi_mat_t; typedef struct { #ifdef WORDS_BIGENDIAN unsigned int zero_1 : 1; unsigned int multi_or_random_pgc_title : 1; /* 0: one sequential pgc title */ unsigned int jlc_exists_in_cell_cmd : 1; unsigned int jlc_exists_in_prepost_cmd : 1; unsigned int jlc_exists_in_button_cmd : 1; unsigned int jlc_exists_in_tt_dom : 1; unsigned int chapter_search_or_play : 1; /* UOP 1 */ unsigned int title_or_time_play : 1; /* UOP 0 */ #else unsigned char title_or_time_play : 1; unsigned char chapter_search_or_play : 1; unsigned char jlc_exists_in_tt_dom : 1; unsigned char jlc_exists_in_button_cmd : 1; unsigned char jlc_exists_in_prepost_cmd : 1; unsigned char jlc_exists_in_cell_cmd : 1; unsigned char multi_or_random_pgc_title : 1; unsigned char zero_1 : 1; #endif } ATTRIBUTE_PACKED playback_type_t; /** * Title Information. */ typedef struct { playback_type_t pb_ty; uint8_t nr_of_angles; uint16_t nr_of_ptts; uint16_t parental_id; uint8_t title_set_nr; uint8_t vts_ttn; uint32_t title_set_sector; } ATTRIBUTE_PACKED title_info_t; /** * PartOfTitle Search Pointer Table. */ typedef struct { uint16_t nr_of_srpts; uint16_t zero_1; uint32_t last_byte; title_info_t *title; } ATTRIBUTE_PACKED tt_srpt_t; #define TT_SRPT_SIZE 8 /** * Parental Management Information Unit Table. * Level 1 (US: G), ..., 7 (US: NC-17), 8 */ typedef uint16_t pf_level_t[8]; /** * Parental Management Information Unit Table. */ typedef struct { uint16_t country_code; uint16_t zero_1; uint16_t pf_ptl_mai_start_byte; uint16_t zero_2; pf_level_t *pf_ptl_mai; /* table of (nr_of_vtss + 1), video_ts is first */ } ATTRIBUTE_PACKED ptl_mait_country_t; #define PTL_MAIT_COUNTRY_SIZE 8 /** * Parental Management Information Table. */ typedef struct { uint16_t nr_of_countries; uint16_t nr_of_vtss; uint32_t last_byte; ptl_mait_country_t *countries; } ATTRIBUTE_PACKED ptl_mait_t; #define PTL_MAIT_SIZE 8 /** * Video Title Set Attributes. */ typedef struct { uint32_t last_byte; uint32_t vts_cat; video_attr_t vtsm_vobs_attr; uint8_t zero_1; uint8_t nr_of_vtsm_audio_streams; /* should be 0 or 1 */ audio_attr_t vtsm_audio_attr; audio_attr_t zero_2[7]; uint8_t zero_3[16]; uint8_t zero_4; uint8_t nr_of_vtsm_subp_streams; /* should be 0 or 1 */ subp_attr_t vtsm_subp_attr; subp_attr_t zero_5[27]; uint8_t zero_6[2]; video_attr_t vtstt_vobs_video_attr; uint8_t zero_7; uint8_t nr_of_vtstt_audio_streams; audio_attr_t vtstt_audio_attr[8]; uint8_t zero_8[16]; uint8_t zero_9; uint8_t nr_of_vtstt_subp_streams; subp_attr_t vtstt_subp_attr[32]; } ATTRIBUTE_PACKED vts_attributes_t; #define VTS_ATTRIBUTES_SIZE 542 #define VTS_ATTRIBUTES_MIN_SIZE 356 /** * Video Title Set Attribute Table. */ typedef struct { uint16_t nr_of_vtss; uint16_t zero_1; uint32_t last_byte; vts_attributes_t *vts; uint32_t *vts_atrt_offsets; /* offsets table for each vts_attributes */ } ATTRIBUTE_PACKED vts_atrt_t; #define VTS_ATRT_SIZE 8 /** * Text Data. (Incomplete) */ typedef struct { uint32_t last_byte; /* offsets are relative here */ uint16_t offsets[100]; /* == nr_of_srpts + 1 (first is disc title) */ #if 0 uint16_t unknown; /* 0x48 ?? 0x48 words (16bit) info following */ uint16_t zero_1; uint8_t type_of_info; /* ?? 01 == disc, 02 == Title, 04 == Title part */ uint8_t unknown1; uint8_t unknown2; uint8_t unknown3; uint8_t unknown4; /* ?? allways 0x30 language?, text format? */ uint8_t unknown5; uint16_t offset; /* from first */ char text[12]; /* ended by 0x09 */ #endif } ATTRIBUTE_PACKED txtdt_t; /** * Text Data Language Unit. (Incomplete) */ typedef struct { uint16_t lang_code; uint16_t unknown; /* 0x0001, title 1? disc 1? side 1? */ uint32_t txtdt_start_byte; /* prt, rel start of vmg_txtdt_mgi */ txtdt_t *txtdt; } ATTRIBUTE_PACKED txtdt_lu_t; #define TXTDT_LU_SIZE 8 /** * Text Data Manager Information. (Incomplete) */ typedef struct { char disc_name[14]; /* how many bytes?? */ uint16_t nr_of_language_units; /* 32bit?? */ uint32_t last_byte; txtdt_lu_t *lu; } ATTRIBUTE_PACKED txtdt_mgi_t; #define TXTDT_MGI_SIZE 20 /** * VTS * * Structures relating to the Video Title Set (VTS). */ /** * Video Title Set Information Management Table. */ typedef struct { char vts_identifier[12]; uint32_t vts_last_sector; uint8_t zero_1[12]; uint32_t vtsi_last_sector; uint8_t zero_2; uint8_t specification_version; uint32_t vts_category; uint16_t zero_3; uint16_t zero_4; uint8_t zero_5; uint8_t zero_6[19]; uint16_t zero_7; uint8_t zero_8[32]; uint64_t zero_9; uint8_t zero_10[24]; uint32_t vtsi_last_byte; uint32_t zero_11; uint8_t zero_12[56]; uint32_t vtsm_vobs; /* sector */ uint32_t vtstt_vobs; /* sector */ uint32_t vts_ptt_srpt; /* sector */ uint32_t vts_pgcit; /* sector */ uint32_t vtsm_pgci_ut; /* sector */ uint32_t vts_tmapt; /* sector */ uint32_t vtsm_c_adt; /* sector */ uint32_t vtsm_vobu_admap; /* sector */ uint32_t vts_c_adt; /* sector */ uint32_t vts_vobu_admap; /* sector */ uint8_t zero_13[24]; video_attr_t vtsm_video_attr; uint8_t zero_14; uint8_t nr_of_vtsm_audio_streams; /* should be 0 or 1 */ audio_attr_t vtsm_audio_attr; audio_attr_t zero_15[7]; uint8_t zero_16[17]; uint8_t nr_of_vtsm_subp_streams; /* should be 0 or 1 */ subp_attr_t vtsm_subp_attr; subp_attr_t zero_17[27]; uint8_t zero_18[2]; video_attr_t vts_video_attr; uint8_t zero_19; uint8_t nr_of_vts_audio_streams; audio_attr_t vts_audio_attr[8]; uint8_t zero_20[17]; uint8_t nr_of_vts_subp_streams; subp_attr_t vts_subp_attr[32]; uint16_t zero_21; multichannel_ext_t vts_mu_audio_attr[8]; /* XXX: how much 'padding' here, if any? */ } ATTRIBUTE_PACKED vtsi_mat_t; /** * PartOfTitle Unit Information. */ typedef struct { uint16_t pgcn; uint16_t pgn; } ATTRIBUTE_PACKED ptt_info_t; /** * PartOfTitle Information. */ typedef struct { uint16_t nr_of_ptts; ptt_info_t *ptt; } ATTRIBUTE_PACKED ttu_t; /** * PartOfTitle Search Pointer Table. */ typedef struct { uint16_t nr_of_srpts; uint16_t zero_1; uint32_t last_byte; ttu_t *title; uint32_t *ttu_offset; /* offset table for each ttu */ } ATTRIBUTE_PACKED vts_ptt_srpt_t; #define VTS_PTT_SRPT_SIZE 8 /** * Time Map Entry. */ /* Should this be bit field at all or just the uint32_t? */ typedef uint32_t map_ent_t; /** * Time Map. */ typedef struct { uint8_t tmu; /* Time unit, in seconds */ uint8_t zero_1; uint16_t nr_of_entries; map_ent_t *map_ent; } ATTRIBUTE_PACKED vts_tmap_t; #define VTS_TMAP_SIZE 4 /** * Time Map Table. */ typedef struct { uint16_t nr_of_tmaps; uint16_t zero_1; uint32_t last_byte; vts_tmap_t *tmap; uint32_t *tmap_offset; /* offset table for each tmap */ } ATTRIBUTE_PACKED vts_tmapt_t; #define VTS_TMAPT_SIZE 8 #if PRAGMA_PACK #pragma pack() #endif /** * The following structure defines an IFO file. The structure is divided into * two parts, the VMGI, or Video Manager Information, which is read from the * VIDEO_TS.[IFO,BUP] file, and the VTSI, or Video Title Set Information, which * is read in from the VTS_XX_0.[IFO,BUP] files. */ typedef struct { dvd_file_t *file; /* VMGI */ vmgi_mat_t *vmgi_mat; tt_srpt_t *tt_srpt; pgc_t *first_play_pgc; ptl_mait_t *ptl_mait; vts_atrt_t *vts_atrt; txtdt_mgi_t *txtdt_mgi; /* Common */ pgci_ut_t *pgci_ut; c_adt_t *menu_c_adt; vobu_admap_t *menu_vobu_admap; /* VTSI */ vtsi_mat_t *vtsi_mat; vts_ptt_srpt_t *vts_ptt_srpt; pgcit_t *vts_pgcit; vts_tmapt_t *vts_tmapt; c_adt_t *vts_c_adt; vobu_admap_t *vts_vobu_admap; } ifo_handle_t; #endif /* IFO_TYPES_H_INCLUDED */ ����������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/nav_read.c���������������������������������������������������������0000644�0001750�0001750�00000033164�14647725152�016515� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001, 2002, 2003 Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include "bswap.h" #include "nav_types.h" #include "nav_read.h" #include "dvdread_internal.h" #include <xine/xineutils.h> /* _x_abort() */ typedef struct { uint8_t *start; uint32_t byte_position; uint32_t bit_position; uint8_t byte; } getbits_state_t; static int getbits_init(getbits_state_t *state, uint8_t *start) { _x_assert(state); _x_assert(start); if ((state == NULL) || (start == NULL)) return 0; state->start = start; state->bit_position = 0; state->byte_position = 0; state->byte = start[0]; return 1; } /* Non-optimized getbits. */ /* This can easily be optimized for particular platforms. */ static uint32_t getbits(getbits_state_t *state, uint32_t number_of_bits) { uint32_t result=0; uint8_t byte=0; if (number_of_bits > 32) { printf("Number of bits > 32 in getbits\n"); _x_assert(number_of_bits <= 32); } if ((state->bit_position) > 0) { /* Last getbits left us in the middle of a byte. */ if (number_of_bits > (8-state->bit_position)) { /* this getbits will span 2 or more bytes. */ byte = state->byte; byte = byte >> (state->bit_position); result = byte; number_of_bits -= (8-state->bit_position); state->bit_position = 0; state->byte_position++; state->byte = state->start[state->byte_position]; } else { byte=state->byte; state->byte = state->byte << number_of_bits; byte = byte >> (8 - number_of_bits); result = byte; state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 8 */ if (state->bit_position == 8) { state->bit_position = 0; state->byte_position++; state->byte = state->start[state->byte_position]; } number_of_bits = 0; } } if ((state->bit_position) == 0) { while (number_of_bits > 7) { result = (result << 8) + state->byte; state->byte_position++; state->byte = state->start[state->byte_position]; number_of_bits -= 8; } if (number_of_bits > 0) { /* number_of_bits < 8 */ byte = state->byte; state->byte = state->byte << number_of_bits; state->bit_position += number_of_bits; /* Here it is impossible for bit_position > 7 */ byte = byte >> (8 - number_of_bits); result = (result << number_of_bits) + byte; number_of_bits = 0; } } return result; } #if 0 /* TODO: optimized versions not yet used */ /* WARNING: This function can only be used on a byte boundary. No checks are made that we are in fact on a byte boundary. */ static uint16_t get16bits(getbits_state_t *state) { uint16_t result; state->byte_position++; result = (state->byte << 8) + state->start[state->byte_position++]; state->byte = state->start[state->byte_position]; return result; } /* WARNING: This function can only be used on a byte boundary. No checks are made that we are in fact on a byte boundary. */ static uint32_t get32bits(getbits_state_t *state) { uint32_t result; state->byte_position++; result = (state->byte << 8) + state->start[state->byte_position++]; result = (result << 8) + state->start[state->byte_position++]; result = (result << 8) + state->start[state->byte_position++]; state->byte = state->start[state->byte_position]; return result; } #endif void navRead_PCI(pci_t *pci, unsigned char *buffer) { int32_t i, j; getbits_state_t state; if (!getbits_init(&state, buffer)) return; /* Passed NULL pointers */ /* pci pci_gi */ pci->pci_gi.nv_pck_lbn = getbits(&state, 32 ); pci->pci_gi.vobu_cat = getbits(&state, 16 ); pci->pci_gi.zero1 = getbits(&state, 16 ); pci->pci_gi.vobu_uop_ctl.zero = getbits(&state, 7 ); pci->pci_gi.vobu_uop_ctl.video_pres_mode_change = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.karaoke_audio_pres_mode_change = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.angle_change = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.subpic_stream_change = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.audio_stream_change = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.pause_on = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.still_off = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.button_select_or_activate = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.resume = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.chapter_menu_call = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.angle_menu_call = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.audio_menu_call = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.subpic_menu_call = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.root_menu_call = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.title_menu_call = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.backward_scan = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.forward_scan = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.next_pg_search = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.prev_or_top_pg_search = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.time_or_chapter_search = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.go_up = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.stop = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.title_play = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.chapter_search_or_play = getbits(&state, 1 ); pci->pci_gi.vobu_uop_ctl.title_or_time_play = getbits(&state, 1 ); pci->pci_gi.vobu_s_ptm = getbits(&state, 32 ); pci->pci_gi.vobu_e_ptm = getbits(&state, 32 ); pci->pci_gi.vobu_se_e_ptm = getbits(&state, 32 ); pci->pci_gi.e_eltm.hour = getbits(&state, 8 ); pci->pci_gi.e_eltm.minute = getbits(&state, 8 ); pci->pci_gi.e_eltm.second = getbits(&state, 8 ); pci->pci_gi.e_eltm.frame_u = getbits(&state, 8 ); for(i = 0; i < 32; i++) pci->pci_gi.vobu_isrc[i] = getbits(&state, 8 ); /* pci nsml_agli */ for(i = 0; i < 9; i++) pci->nsml_agli.nsml_agl_dsta[i] = getbits(&state, 32 ); /* pci hli hli_gi */ pci->hli.hl_gi.hli_ss = getbits(&state, 16 ); pci->hli.hl_gi.hli_s_ptm = getbits(&state, 32 ); pci->hli.hl_gi.hli_e_ptm = getbits(&state, 32 ); pci->hli.hl_gi.btn_se_e_ptm = getbits(&state, 32 ); pci->hli.hl_gi.zero1 = getbits(&state, 2 ); pci->hli.hl_gi.btngr_ns = getbits(&state, 2 ); pci->hli.hl_gi.zero2 = getbits(&state, 1 ); pci->hli.hl_gi.btngr1_dsp_ty = getbits(&state, 3 ); pci->hli.hl_gi.zero3 = getbits(&state, 1 ); pci->hli.hl_gi.btngr2_dsp_ty = getbits(&state, 3 ); pci->hli.hl_gi.zero4 = getbits(&state, 1 ); pci->hli.hl_gi.btngr3_dsp_ty = getbits(&state, 3 ); pci->hli.hl_gi.btn_ofn = getbits(&state, 8 ); pci->hli.hl_gi.btn_ns = getbits(&state, 8 ); pci->hli.hl_gi.nsl_btn_ns = getbits(&state, 8 ); pci->hli.hl_gi.zero5 = getbits(&state, 8 ); pci->hli.hl_gi.fosl_btnn = getbits(&state, 8 ); pci->hli.hl_gi.foac_btnn = getbits(&state, 8 ); /* pci hli btn_colit */ for(i = 0; i < 3; i++) for(j = 0; j < 2; j++) pci->hli.btn_colit.btn_coli[i][j] = getbits(&state, 32 ); /* NOTE: I've had to change the structure from the disk layout to get * the packing to work with Sun's Forte C compiler. */ /* pci hli btni */ for(i = 0; i < 36; i++) { pci->hli.btnit[i].btn_coln = getbits(&state, 2 ); pci->hli.btnit[i].x_start = getbits(&state, 10 ); pci->hli.btnit[i].zero1 = getbits(&state, 2 ); pci->hli.btnit[i].x_end = getbits(&state, 10 ); pci->hli.btnit[i].auto_action_mode = getbits(&state, 2 ); pci->hli.btnit[i].y_start = getbits(&state, 10 ); pci->hli.btnit[i].zero2 = getbits(&state, 2 ); pci->hli.btnit[i].y_end = getbits(&state, 10 ); pci->hli.btnit[i].zero3 = getbits(&state, 2 ); pci->hli.btnit[i].up = getbits(&state, 6 ); pci->hli.btnit[i].zero4 = getbits(&state, 2 ); pci->hli.btnit[i].down = getbits(&state, 6 ); pci->hli.btnit[i].zero5 = getbits(&state, 2 ); pci->hli.btnit[i].left = getbits(&state, 6 ); pci->hli.btnit[i].zero6 = getbits(&state, 2 ); pci->hli.btnit[i].right = getbits(&state, 6 ); /* pci vm_cmd */ for(j = 0; j < 8; j++) pci->hli.btnit[i].cmd.bytes[j] = getbits(&state, 8 ); } #ifndef NDEBUG /* Asserts */ /* pci pci gi */ CHECK_VALUE(pci->pci_gi.zero1 == 0); /* pci hli hli_gi */ CHECK_VALUE(pci->hli.hl_gi.zero1 == 0); CHECK_VALUE(pci->hli.hl_gi.zero2 == 0); CHECK_VALUE(pci->hli.hl_gi.zero3 == 0); CHECK_VALUE(pci->hli.hl_gi.zero4 == 0); CHECK_VALUE(pci->hli.hl_gi.zero5 == 0); /* Are there buttons defined here? */ if((pci->hli.hl_gi.hli_ss & 0x03) != 0) { CHECK_VALUE(pci->hli.hl_gi.btn_ns != 0); CHECK_VALUE(pci->hli.hl_gi.btngr_ns != 0); } else { CHECK_VALUE((pci->hli.hl_gi.btn_ns != 0 && pci->hli.hl_gi.btngr_ns != 0) || (pci->hli.hl_gi.btn_ns == 0 && pci->hli.hl_gi.btngr_ns == 0)); } /* pci hli btnit */ for(i = 0; i < pci->hli.hl_gi.btngr_ns; i++) { for(j = 0; j < (36 / pci->hli.hl_gi.btngr_ns); j++) { int n = (36 / pci->hli.hl_gi.btngr_ns) * i + j; CHECK_VALUE(pci->hli.btnit[n].zero1 == 0); CHECK_VALUE(pci->hli.btnit[n].zero2 == 0); CHECK_VALUE(pci->hli.btnit[n].zero3 == 0); CHECK_VALUE(pci->hli.btnit[n].zero4 == 0); CHECK_VALUE(pci->hli.btnit[n].zero5 == 0); CHECK_VALUE(pci->hli.btnit[n].zero6 == 0); if (j < pci->hli.hl_gi.btn_ns) { CHECK_VALUE(pci->hli.btnit[n].x_start <= pci->hli.btnit[n].x_end); CHECK_VALUE(pci->hli.btnit[n].y_start <= pci->hli.btnit[n].y_end); CHECK_VALUE(pci->hli.btnit[n].up <= pci->hli.hl_gi.btn_ns); CHECK_VALUE(pci->hli.btnit[n].down <= pci->hli.hl_gi.btn_ns); CHECK_VALUE(pci->hli.btnit[n].left <= pci->hli.hl_gi.btn_ns); CHECK_VALUE(pci->hli.btnit[n].right <= pci->hli.hl_gi.btn_ns); /* vmcmd_verify(pci->hli.btnit[n].cmd); */ } else { int k; CHECK_VALUE(pci->hli.btnit[n].btn_coln == 0); CHECK_VALUE(pci->hli.btnit[n].auto_action_mode == 0); CHECK_VALUE(pci->hli.btnit[n].x_start == 0); CHECK_VALUE(pci->hli.btnit[n].y_start == 0); CHECK_VALUE(pci->hli.btnit[n].x_end == 0); CHECK_VALUE(pci->hli.btnit[n].y_end == 0); CHECK_VALUE(pci->hli.btnit[n].up == 0); CHECK_VALUE(pci->hli.btnit[n].down == 0); CHECK_VALUE(pci->hli.btnit[n].left == 0); CHECK_VALUE(pci->hli.btnit[n].right == 0); for (k = 0; k < 8; k++) CHECK_VALUE(pci->hli.btnit[n].cmd.bytes[k] == 0); /* CHECK_ZERO? */ } } } #endif /* !NDEBUG */ } void navRead_DSI(dsi_t *dsi, unsigned char *buffer) { int i; getbits_state_t state; if (!getbits_init(&state, buffer)) return; /* Passed NULL pointers */ /* dsi dsi gi */ dsi->dsi_gi.nv_pck_scr = getbits(&state, 32 ); dsi->dsi_gi.nv_pck_lbn = getbits(&state, 32 ); dsi->dsi_gi.vobu_ea = getbits(&state, 32 ); dsi->dsi_gi.vobu_1stref_ea = getbits(&state, 32 ); dsi->dsi_gi.vobu_2ndref_ea = getbits(&state, 32 ); dsi->dsi_gi.vobu_3rdref_ea = getbits(&state, 32 ); dsi->dsi_gi.vobu_vob_idn = getbits(&state, 16 ); dsi->dsi_gi.zero1 = getbits(&state, 8 ); dsi->dsi_gi.vobu_c_idn = getbits(&state, 8 ); dsi->dsi_gi.c_eltm.hour = getbits(&state, 8 ); dsi->dsi_gi.c_eltm.minute = getbits(&state, 8 ); dsi->dsi_gi.c_eltm.second = getbits(&state, 8 ); dsi->dsi_gi.c_eltm.frame_u = getbits(&state, 8 ); /* dsi sml pbi */ dsi->sml_pbi.category = getbits(&state, 16 ); dsi->sml_pbi.ilvu_ea = getbits(&state, 32 ); dsi->sml_pbi.ilvu_sa = getbits(&state, 32 ); dsi->sml_pbi.size = getbits(&state, 16 ); dsi->sml_pbi.vob_v_s_s_ptm = getbits(&state, 32 ); dsi->sml_pbi.vob_v_e_e_ptm = getbits(&state, 32 ); for(i = 0; i < 8; i++) { dsi->sml_pbi.vob_a[i].stp_ptm1 = getbits(&state, 32 ); dsi->sml_pbi.vob_a[i].stp_ptm2 = getbits(&state, 32 ); dsi->sml_pbi.vob_a[i].gap_len1 = getbits(&state, 32 ); dsi->sml_pbi.vob_a[i].gap_len2 = getbits(&state, 32 ); } /* dsi sml agli */ for(i = 0; i < 9; i++) { dsi->sml_agli.data[ i ].address = getbits(&state, 32 ); dsi->sml_agli.data[ i ].size = getbits(&state, 16 ); } /* dsi vobu sri */ dsi->vobu_sri.next_video = getbits(&state, 32 ); for(i = 0; i < 19; i++) dsi->vobu_sri.fwda[i] = getbits(&state, 32 ); dsi->vobu_sri.next_vobu = getbits(&state, 32 ); dsi->vobu_sri.prev_vobu = getbits(&state, 32 ); for(i = 0; i < 19; i++) dsi->vobu_sri.bwda[i] = getbits(&state, 32 ); dsi->vobu_sri.prev_video = getbits(&state, 32 ); /* dsi synci */ for(i = 0; i < 8; i++) dsi->synci.a_synca[i] = getbits(&state, 16 ); for(i = 0; i < 32; i++) dsi->synci.sp_synca[i] = getbits(&state, 32 ); /* Asserts */ /* dsi dsi gi */ CHECK_VALUE(dsi->dsi_gi.zero1 == 0); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/ifo_read.h���������������������������������������������������������0000644�0001750�0001750�00000017737�14647725152�016523� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef IFO_READ_H_INCLUDED #define IFO_READ_H_INCLUDED /* * Copyright (C) 2000, 2001, 2002 Björn Englund <d4bjorn@dtek.chalmers.se>, * Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "ifo_types.h" #include "dvd_reader.h" #ifdef __cplusplus extern "C" { #endif /** * handle = ifoOpen(dvd, title); * * Opens an IFO and reads in all the data for the IFO file corresponding to the * given title. If title 0 is given, the video manager IFO file is read. * Returns a handle to a completely parsed structure. */ ifo_handle_t *ifoOpen(dvd_reader_t *, int ); /** * handle = ifoOpenVMGI(dvd); * * Opens an IFO and reads in _only_ the vmgi_mat data. This call can be used * together with the calls below to read in each segment of the IFO file on * demand. */ ifo_handle_t *ifoOpenVMGI(dvd_reader_t *); /** * handle = ifoOpenVTSI(dvd, title); * * Opens an IFO and reads in _only_ the vtsi_mat data. This call can be used * together with the calls below to read in each segment of the IFO file on * demand. */ ifo_handle_t *ifoOpenVTSI(dvd_reader_t *, int); /** * ifoClose(ifofile); * Cleans up the IFO information. This will free all data allocated for the * substructures. */ void ifoClose(ifo_handle_t *); /** * The following functions are for reading only part of the VMGI/VTSI files. * Returns 1 if the data was successfully read and 0 on error. */ /** * okay = ifoRead_PLT_MAIT(ifofile); * * Read in the Parental Management Information table, filling the * ifofile->ptl_mait structure and its substructures. This data is only * located in the video manager information file. This fills the * ifofile->ptl_mait structure and all its substructures. */ int ifoRead_PTL_MAIT(ifo_handle_t *); /** * okay = ifoRead_VTS_ATRT(ifofile); * * Read in the attribute table for the main menu vob, filling the * ifofile->vts_atrt structure and its substructures. Only located in the * video manager information file. This fills in the ifofile->vts_atrt * structure and all its substructures. */ int ifoRead_VTS_ATRT(ifo_handle_t *); /** * okay = ifoRead_TT_SRPT(ifofile); * * Reads the title info for the main menu, filling the ifofile->tt_srpt * structure and its substructures. This data is only located in the video * manager information file. This structure is mandatory in the IFO file. */ int ifoRead_TT_SRPT(ifo_handle_t *); /** * okay = ifoRead_VTS_PTT_SRPT(ifofile); * * Reads in the part of title search pointer table, filling the * ifofile->vts_ptt_srpt structure and its substructures. This data is only * located in the video title set information file. This structure is * mandatory, and must be included in the VTSI file. */ int ifoRead_VTS_PTT_SRPT(ifo_handle_t *); /** * okay = ifoRead_FP_PGC(ifofile); * * Reads in the first play program chain data, filling the * ifofile->first_play_pgc structure. This data is only located in the video * manager information file (VMGI). This structure is optional. */ int ifoRead_FP_PGC(ifo_handle_t *); /** * okay = ifoRead_PGCIT(ifofile); * * Reads in the program chain information table for the video title set. Fills * in the ifofile->vts_pgcit structure and its substructures, which includes * the data for each program chain in the set. This data is only located in * the video title set information file. This structure is mandatory, and must * be included in the VTSI file. */ int ifoRead_PGCIT(ifo_handle_t *); /** * okay = ifoRead_PGCI_UT(ifofile); * * Reads in the menu PGCI unit table for the menu VOB. For the video manager, * this corresponds to the VIDEO_TS.VOB file, and for each title set, this * corresponds to the VTS_XX_0.VOB file. This data is located in both the * video manager and video title set information files. For VMGI files, this * fills the ifofile->vmgi_pgci_ut structure and all its substructures. For * VTSI files, this fills the ifofile->vtsm_pgci_ut structure. */ int ifoRead_PGCI_UT(ifo_handle_t *); /** * okay = ifoRead_VTS_TMAPT(ifofile); * * Reads in the VTS Time Map Table, this data is only located in the video * title set information file. This fills the ifofile->vts_tmapt structure * and all its substructures. When pressent enables VOBU level time-based * seeking for One_Sequential_PGC_Titles. */ int ifoRead_VTS_TMAPT(ifo_handle_t *); /** * okay = ifoRead_C_ADT(ifofile); * * Reads in the cell address table for the menu VOB. For the video manager, * this corresponds to the VIDEO_TS.VOB file, and for each title set, this * corresponds to the VTS_XX_0.VOB file. This data is located in both the * video manager and video title set information files. For VMGI files, this * fills the ifofile->vmgm_c_adt structure and all its substructures. For VTSI * files, this fills the ifofile->vtsm_c_adt structure. */ int ifoRead_C_ADT(ifo_handle_t *); /** * okay = ifoRead_TITLE_C_ADT(ifofile); * * Reads in the cell address table for the video title set corresponding to * this IFO file. This data is only located in the video title set information * file. This structure is mandatory, and must be included in the VTSI file. * This call fills the ifofile->vts_c_adt structure and its substructures. */ int ifoRead_TITLE_C_ADT(ifo_handle_t *); /** * okay = ifoRead_VOBU_ADMAP(ifofile); * * Reads in the VOBU address map for the menu VOB. For the video manager, this * corresponds to the VIDEO_TS.VOB file, and for each title set, this * corresponds to the VTS_XX_0.VOB file. This data is located in both the * video manager and video title set information files. For VMGI files, this * fills the ifofile->vmgm_vobu_admap structure and all its substructures. For * VTSI files, this fills the ifofile->vtsm_vobu_admap structure. */ int ifoRead_VOBU_ADMAP(ifo_handle_t *); /** * okay = ifoRead_TITLE_VOBU_ADMAP(ifofile); * * Reads in the VOBU address map for the associated video title set. This data * is only located in the video title set information file. This structure is * mandatory, and must be included in the VTSI file. Fills the * ifofile->vts_vobu_admap structure and its substructures. */ int ifoRead_TITLE_VOBU_ADMAP(ifo_handle_t *); /** * okay = ifoRead_TXTDT_MGI(ifofile); * * Reads in the text data strings for the DVD. Fills the ifofile->txtdt_mgi * structure and all its substructures. This data is only located in the video * manager information file. This structure is mandatory, and must be included * in the VMGI file. */ int ifoRead_TXTDT_MGI(ifo_handle_t *); /** * The following functions are used for freeing parsed sections of the * ifo_handle_t structure and the allocated substructures. The free calls * below are safe: they will not mind if you attempt to free part of an IFO * file which was not read in or which does not exist. */ void ifoFree_PTL_MAIT(ifo_handle_t *); void ifoFree_VTS_ATRT(ifo_handle_t *); void ifoFree_TT_SRPT(ifo_handle_t *); void ifoFree_VTS_PTT_SRPT(ifo_handle_t *); void ifoFree_FP_PGC(ifo_handle_t *); void ifoFree_PGCIT(ifo_handle_t *); void ifoFree_PGCI_UT(ifo_handle_t *); void ifoFree_VTS_TMAPT(ifo_handle_t *); void ifoFree_C_ADT(ifo_handle_t *); void ifoFree_TITLE_C_ADT(ifo_handle_t *); void ifoFree_VOBU_ADMAP(ifo_handle_t *); void ifoFree_TITLE_VOBU_ADMAP(ifo_handle_t *); void ifoFree_TXTDT_MGI(ifo_handle_t *); #ifdef __cplusplus }; #endif #endif /* IFO_READ_H_INCLUDED */ ���������������������������������xine-lib-1.2/src/input/libdvdnav/dvd_input.c��������������������������������������������������������0000644�0001750�0001750�00000026465�14647725152�016740� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002 Samuel Hocevar <sam@zoy.org>, * Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include "dvd_reader.h" #include "dvd_input.h" /* The function pointers that is the exported interface of this file. */ dvd_input_t (*dvdinput_open) (const char *); int (*dvdinput_close) (dvd_input_t); int (*dvdinput_seek) (dvd_input_t, int); int (*dvdinput_title) (dvd_input_t, int); int (*dvdinput_read) (dvd_input_t, void *, int, int); char * (*dvdinput_error) (dvd_input_t); int (*dvdinput_is_encrypted) (dvd_input_t); #ifdef HAVE_DVDCSS_DVDCSS_H /* linking to libdvdcss */ #include <dvdcss/dvdcss.h> #define DVDcss_open(a) dvdcss_open((char*)(a)) #define DVDcss_close dvdcss_close #define DVDcss_seek dvdcss_seek #define DVDcss_title dvdcss_title #define DVDcss_read dvdcss_read #define DVDcss_error dvdcss_error #else /* dlopening libdvdcss */ #ifdef HAVE_DLFCN_H #include <dlfcn.h> #else /* Only needed on MINGW at the moment */ #include "../../msvc/contrib/dlfcn.c" #endif #define DVDCSS_SEEK_KEY (1 << 1) /* Copied from css.h */ #define KEY_SIZE 5 typedef uint8_t dvd_key_t[KEY_SIZE]; typedef struct dvd_title_s { int i_startlb; dvd_key_t p_key; struct dvd_title_s *p_next; } dvd_title_t; typedef struct css_s { int i_agid; /* Current Authenication Grant ID. */ dvd_key_t p_bus_key; /* Current session key. */ dvd_key_t p_disc_key; /* This DVD disc's key. */ dvd_key_t p_title_key; /* Current title key. */ } css_t; /* Copied from libdvdcss.h */ #ifndef PATH_MAX #define PATH_MAX 4096 #endif struct dvdcss_s { /* File descriptor */ char * psz_device; int i_fd; int i_read_fd; int i_pos; /* File handling */ void *pf_seek; void *pf_read; void *pf_readv; /* Decryption stuff */ int i_method; css_t css; int b_ioctls; int b_scrambled; dvd_title_t *p_titles; /* Key cache directory and pointer to the filename */ char psz_cachefile[PATH_MAX]; char * psz_block; /* Error management */ char * psz_error; int b_errors; int b_debug; #ifdef WIN32 int b_file; char * p_readv_buffer; int i_readv_buf_size; #endif #ifndef WIN32 int i_raw_fd; #endif }; typedef struct dvdcss_s *dvdcss_handle; static dvdcss_handle (*DVDcss_open) (const char *); static int (*DVDcss_close) (dvdcss_handle); static int (*DVDcss_seek) (dvdcss_handle, int, int); static int (*DVDcss_title) (dvdcss_handle, int); static int (*DVDcss_read) (dvdcss_handle, void *, int, int); static char * (*DVDcss_error) (dvdcss_handle); static int (*DVDcss_is_scrambled) (dvdcss_handle); #endif /* The DVDinput handle, add stuff here for new input methods. */ struct dvd_input_s { /* libdvdcss handle */ dvdcss_handle dvdcss; /* dummy file input */ int fd; }; /** * initialize and open a DVD device or file. */ static dvd_input_t css_open(const char *target) { dvd_input_t dev; /* Allocate the handle structure */ dev = (dvd_input_t) malloc(sizeof(*dev)); if(dev == NULL) { fprintf(stderr, "libdvdread: Could not allocate memory.\n"); return NULL; } /* Really open it with libdvdcss */ dev->dvdcss = DVDcss_open(target); if(dev->dvdcss == 0) { fprintf(stderr, "libdvdread: Could not open %s with libdvdcss.\n", target); free(dev); return NULL; } return dev; } /** * return the last error message */ static char *css_error(dvd_input_t dev) { return DVDcss_error(dev->dvdcss); } /** * seek into the device. */ static int css_seek(dvd_input_t dev, int blocks) { /* DVDINPUT_NOFLAGS should match the DVDCSS_NOFLAGS value. */ return DVDcss_seek(dev->dvdcss, blocks, DVDINPUT_NOFLAGS); } /** * set the block for the begining of a new title (key). */ static int css_title(dvd_input_t dev, int block) { #ifndef HAVE_DVDCSS_DVDCSS_H /* DVDcss_title was removed in libdvdcss 1.3.0 */ if (!DVDcss_title) { return DVDcss_seek(dev->dvdcss, block, DVDCSS_SEEK_KEY); } #endif return DVDcss_title(dev->dvdcss, block); } /** * read data from the device. */ static int css_read(dvd_input_t dev, void *buffer, int blocks, int flags) { return DVDcss_read(dev->dvdcss, buffer, blocks, flags); } /** * close the DVD device and clean up the library. */ static int css_close(dvd_input_t dev) { int ret; ret = DVDcss_close(dev->dvdcss); if(ret < 0) return ret; free(dev); return 0; } static int css_is_encrypted (dvd_input_t dev) { if (dev->dvdcss == NULL) { return 0; } #ifndef HAVE_DVDCSS_DVDCSS_H if (DVDcss_is_scrambled) { return DVDcss_is_scrambled(dev->dvdcss); } #endif /* this won't work with recent libdvdcss versions ... */ return dev->dvdcss->b_scrambled; } /** * initialize and open a DVD device or file. */ static dvd_input_t file_open(const char *target) { dvd_input_t dev; /* Allocate the library structure */ dev = (dvd_input_t) malloc(sizeof(*dev)); if(dev == NULL) { fprintf(stderr, "libdvdread: Could not allocate memory.\n"); return NULL; } /* Open the device */ #ifndef WIN32 dev->fd = open(target, O_RDONLY); #else dev->fd = open(target, O_RDONLY | O_BINARY); #endif if(dev->fd < 0) { perror("libdvdread: Could not open input"); free(dev); return NULL; } return dev; } /** * return the last error message */ static char *file_error(dvd_input_t dev) { /* use strerror(errno)? */ (void)dev; return (char *)"unknown error"; } /** * seek into the device. */ static int file_seek(dvd_input_t dev, int blocks) { off_t pos; pos = lseek(dev->fd, (off_t)blocks * (off_t)DVD_VIDEO_LB_LEN, SEEK_SET); if(pos < 0) { return pos; } /* assert pos % DVD_VIDEO_LB_LEN == 0 */ return (int) (pos / DVD_VIDEO_LB_LEN); } /** * set the block for the begining of a new title (key). */ static int file_title(dvd_input_t dev, int block) { /* FIXME: implement */ (void)dev; (void)block; return -1; } /** * read data from the device. */ static int file_read(dvd_input_t dev, void *buffer, int blocks, int flags) { size_t len; ssize_t ret; char *q = buffer; (void)flags; len = (size_t)blocks * DVD_VIDEO_LB_LEN; while(len > 0) { ret = read(dev->fd, q, len); if(ret < 0) { /* One of the reads failed, too bad. We won't even bother * returning the reads that went ok, and as in the posix spec * the file postition is left unspecified after a failure. */ return ret; } if(ret == 0) { /* Nothing more to read. Return the whole blocks, if any, that we got. and adjust the file possition back to the previous block boundary. */ size_t bytes = (size_t)blocks * DVD_VIDEO_LB_LEN - len; off_t over_read = -(bytes % DVD_VIDEO_LB_LEN); /*off_t pos =*/ lseek(dev->fd, over_read, SEEK_CUR); /* should have pos % 2048 == 0 */ return (int) (bytes / DVD_VIDEO_LB_LEN); } q += ret; len -= ret; } return blocks; } /** * close the DVD device and clean up. */ static int file_close(dvd_input_t dev) { int ret; ret = close(dev->fd); if(ret < 0) return ret; free(dev); return 0; } static int file_is_encrypted (dvd_input_t dev) { /* FIXME: ?? */ (void)dev; return 0; } /** * Setup read functions with either libdvdcss or minimal DVD access. */ int dvdinput_setup(void) { void *dvdcss_library = NULL; char **dvdcss_version = NULL; #ifdef HAVE_DVDCSS_DVDCSS_H /* linking to libdvdcss */ dvdcss_library = &dvdcss_library; /* Give it some value != NULL */ /* the DVDcss_* functions have been #defined at the top */ dvdcss_version = &dvdcss_interface_2; #else /* dlopening libdvdcss */ #ifdef HOST_OS_DARWIN dvdcss_library = dlopen("libdvdcss.2.dylib", RTLD_LAZY); #elif defined(WIN32) dvdcss_library = dlopen("libdvdcss.dll", RTLD_LAZY); #else dvdcss_library = dlopen("libdvdcss.so.2", RTLD_LAZY); #endif if(dvdcss_library != NULL) { #if defined(__OpenBSD__) && !defined(__ELF__) #define U_S "_" #else #define U_S #endif DVDcss_open = (dvdcss_handle (*)(const char*)) dlsym(dvdcss_library, U_S "dvdcss_open"); DVDcss_close = (int (*)(dvdcss_handle)) dlsym(dvdcss_library, U_S "dvdcss_close"); DVDcss_title = (int (*)(dvdcss_handle, int)) dlsym(dvdcss_library, U_S "dvdcss_title"); DVDcss_seek = (int (*)(dvdcss_handle, int, int)) dlsym(dvdcss_library, U_S "dvdcss_seek"); DVDcss_read = (int (*)(dvdcss_handle, void*, int, int)) dlsym(dvdcss_library, U_S "dvdcss_read"); DVDcss_error = (char* (*)(dvdcss_handle)) dlsym(dvdcss_library, U_S "dvdcss_error"); DVDcss_is_scrambled = (int (*)(dvdcss_handle)) dlsym(dvdcss_library, U_S "dvdcss_is_scrambled"); dvdcss_version = (char **)dlsym(dvdcss_library, U_S "dvdcss_interface_2"); if(dlsym(dvdcss_library, U_S "dvdcss_crack")) { fprintf(stderr, "libdvdread: Old (pre-0.0.2) version of libdvdcss found.\n" "libdvdread: You should get the latest version from " "http://www.videolan.org/\n" ); dlclose(dvdcss_library); dvdcss_library = NULL; } else if(!DVDcss_open || !DVDcss_close || !DVDcss_seek || !DVDcss_read || !DVDcss_error) { fprintf(stderr, "libdvdread: Missing symbols in libdvdcss, " "this shouldn't happen !\n"); dlclose(dvdcss_library); dvdcss_library = NULL; } } #endif /* HAVE_DVDCSS_DVDCSS_H */ if(dvdcss_library != NULL) { /* char *psz_method = getenv( "DVDCSS_METHOD" ); char *psz_verbose = getenv( "DVDCSS_VERBOSE" ); fprintf(stderr, "DVDCSS_METHOD %s\n", psz_method); fprintf(stderr, "DVDCSS_VERBOSE %s\n", psz_verbose); */ fprintf(stderr, "libdvdread: Using libdvdcss version %s for DVD access\n", dvdcss_version ? *dvdcss_version : "?"); /* libdvdcss wrapper functions */ dvdinput_open = css_open; dvdinput_close = css_close; dvdinput_seek = css_seek; dvdinput_title = css_title; dvdinput_read = css_read; dvdinput_error = css_error; dvdinput_is_encrypted = css_is_encrypted; return 1; } else { fprintf(stderr, "libdvdread: Encrypted DVD support unavailable.\n"); /* libdvdcss replacement functions */ dvdinput_open = file_open; dvdinput_close = file_close; dvdinput_seek = file_seek; dvdinput_title = file_title; dvdinput_read = file_read; dvdinput_error = file_error; dvdinput_is_encrypted = file_is_encrypted; return 0; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/remap.h������������������������������������������������������������0000644�0001750�0001750�00000002055�14647725152�016042� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef __REMAP__H #define __REMAP__H typedef struct block_s block_t; typedef struct remap_s remap_t; remap_t* remap_loadmap( char *title); unsigned long remap_block( remap_t *map, int domain, int title, int program, unsigned long cblock, unsigned long offset); #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvdnav_internal.h��������������������������������������������������0000644�0001750�0001750�00000016040�14647725152�020113� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2004 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef DVDNAV_INTERNAL_H_INCLUDED #define DVDNAV_INTERNAL_H_INCLUDED #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <limits.h> #include <string.h> #ifndef HAVE_GETTIMEOFDAY # ifdef WIN32 # include <winsock.h> struct timezone; # else # include <sys/time.h> # endif /* replacement gettimeofday implementation */ #include <sys/timeb.h> static inline int dvdnav_private_gettimeofday( struct timeval *tv, void *tz ) { struct timeb t; ftime( &t ); tv->tv_sec = t.time; tv->tv_usec = t.millitm * 1000; return 0; } #define gettimeofday(TV, TZ) dvdnav_private_gettimeofday((TV), (TZ)) #define HAVE_GETTIMEOFDAY 1 #endif #ifndef HAVE_SNPRINTF # ifdef HAVE__SNPRINTF # define snprintf _snprintf # define HAVE_SNPRINTF 1 # endif #endif #ifdef WIN32 /* pthread_mutex_* wrapper for win32 */ #include <windows.h> #include <process.h> typedef CRITICAL_SECTION pthread_mutex_t; #define pthread_mutex_init(a, b) InitializeCriticalSection(a) #define pthread_mutex_lock(a) EnterCriticalSection(a) #define pthread_mutex_unlock(a) LeaveCriticalSection(a) #define pthread_mutex_destroy(a) #include <io.h> /* read() */ #define lseek64 _lseeki64 #else #include <pthread.h> #endif /* WIN32 */ /* Uncomment for VM command tracing */ /* #define TRACE */ #include "decoder.h" #include "dvdnav.h" #include "vm.h" #include "vmcmd.h" /* where should libdvdnav write its messages (stdout/stderr) */ #define MSG_OUT stdout /* Maximum length of an error string */ #define MAX_ERR_LEN 255 /* Use the POSIX PATH_MAX if available */ #ifdef PATH_MAX #define MAX_PATH_LEN PATH_MAX #else #define MAX_PATH_LEN 255 /* Arbitrary */ #endif #ifndef DVD_VIDEO_LB_LEN #define DVD_VIDEO_LB_LEN 2048 #endif typedef struct read_cache_s read_cache_t; /* * These are defined here because they are * not in ifo_types.h, they maybe one day */ #ifndef audio_status_t typedef struct { #ifdef WORDS_BIGENDIAN unsigned int available : 1; unsigned int zero1 : 4; unsigned int stream_number : 3; uint8_t zero2; #else uint8_t zero2; unsigned int stream_number : 3; unsigned int zero1 : 4; unsigned int available : 1; #endif } ATTRIBUTE_PACKED audio_status_t; #endif #ifndef spu_status_t typedef struct { #ifdef WORDS_BIGENDIAN unsigned int available : 1; unsigned int zero1 : 2; unsigned int stream_number_4_3 : 5; unsigned int zero2 : 3; unsigned int stream_number_wide : 5; unsigned int zero3 : 3; unsigned int stream_number_letterbox : 5; unsigned int zero4 : 3; unsigned int stream_number_pan_scan : 5; #else unsigned int stream_number_pan_scan : 5; unsigned int zero4 : 3; unsigned int stream_number_letterbox : 5; unsigned int zero3 : 3; unsigned int stream_number_wide : 5; unsigned int zero2 : 3; unsigned int stream_number_4_3 : 5; unsigned int zero1 : 2; unsigned int available : 1; #endif } ATTRIBUTE_PACKED spu_status_t; #endif typedef struct dvdnav_vobu_s { int32_t vobu_start; /* Logical Absolute. MAX needed is 0x300000 */ int32_t vobu_length; int32_t blockN; /* Relative offset */ int32_t vobu_next; /* Relative offset */ } dvdnav_vobu_t; /** The main DVDNAV type **/ struct dvdnav_s { /* General data */ char path[MAX_PATH_LEN]; /* Path to DVD device/dir */ dvd_file_t *file; /* Currently opened file */ /* Position data */ vm_position_t position_next; vm_position_t position_current; dvdnav_vobu_t vobu; /* NAV data */ pci_t pci; dsi_t dsi; uint32_t last_cmd_nav_lbn; /* detects when a command is issued on an already left NAV */ /* Flags */ int skip_still; /* Set when skipping a still */ int sync_wait; /* applications should wait till they are in sync with us */ int sync_wait_skip; /* Set when skipping wait state */ int spu_clut_changed; /* The SPU CLUT changed */ int started; /* vm_start has been called? */ int use_read_ahead; /* 1 - use read-ahead cache, 0 - don't */ int pgc_based; /* positioning works PGC based instead of PG based */ /* VM */ vm_t *vm; pthread_mutex_t vm_lock; /* Read-ahead cache */ read_cache_t *cache; /* Errors */ char err_str[MAX_ERR_LEN]; }; /** USEFUL MACROS **/ /* printerr*() are often called when this is NULL. Avoid segfaults by replacing these with * more common prints */ #ifdef __GNUC__ #define printerrf(format, args...) \ do { \ if ( ! this ) fprintf(stderr, "Missing 'this' pointer while erroring:" format "\n", ## args); \ else snprintf(this->err_str, MAX_ERR_LEN, format, ## args); \ } while(0); #else #ifdef _MSC_VER #define printerrf(str) snprintf(this->err_str, MAX_ERR_LEN, str); #else #define printerrf(...) \ do { \ if ( ! this ) { \ fprintf(stderr, "Missing 'this' pointer while erroring:"); \ fprintf(stderr, __VA_ARGS__); \ fprintf(stderr, "\n"); \ } else { \ snprintf(this->err_str, MAX_ERR_LEN, __VA_ARGS__); \ } \ } while(0); #endif /* WIN32 */ #endif #define printerr(str) \ do { \ if ( ! this ) { \ fprintf(stderr, "Missing 'this' pointer while erroring: %s\n", str); \ } else { \ strncpy(this->err_str, str, MAX_ERR_LEN); \ } \ } while(0); #endif /* DVDNAV_INTERNAL_H_INCLUDED */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/decoder.h����������������������������������������������������������0000644�0001750�0001750�00000005366�14647725152�016353� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001 Martin Norbäck, Håkan Hjort * * This file is part of libdvdnav, a DVD navigation library. It is modified * from a file originally part of the Ogle DVD player. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef DECODER_H_INCLUDED #define DECODER_H_INCLUDED #include <inttypes.h> #include <sys/time.h> #include "ifo_types.h" /* vm_cmd_t */ #include "dvdnav_internal.h" /* link command types */ typedef enum { LinkNoLink = 0, LinkTopC = 1, LinkNextC = 2, LinkPrevC = 3, LinkTopPG = 5, LinkNextPG = 6, LinkPrevPG = 7, LinkTopPGC = 9, LinkNextPGC = 10, LinkPrevPGC = 11, LinkGoUpPGC = 12, LinkTailPGC = 13, LinkRSM = 16, LinkPGCN, LinkPTTN, LinkPGN, LinkCN, Exit, JumpTT, /* 22 */ JumpVTS_TT, JumpVTS_PTT, JumpSS_FP, JumpSS_VMGM_MENU, JumpSS_VTSM, JumpSS_VMGM_PGC, CallSS_FP, /* 29 */ CallSS_VMGM_MENU, CallSS_VTSM, CallSS_VMGM_PGC, PlayThis } link_cmd_t; /* a link's data set */ typedef struct { link_cmd_t command; uint16_t data1; uint16_t data2; uint16_t data3; } link_t; /* the VM registers */ typedef struct { uint16_t SPRM[24]; uint16_t GPRM[16]; uint8_t GPRM_mode[16]; /* Need to have some thing to indicate normal/counter mode for every GPRM */ struct timeval GPRM_time[16]; /* For counter mode */ } registers_t; /* a VM command data set */ typedef struct { uint64_t instruction; uint64_t examined; registers_t *registers; } command_t; /* the big VM function, executing the given commands and writing * the link where to continue, the return value indicates if a jump * has been performed */ int32_t vmEval_CMD(vm_cmd_t commands[], int32_t num_commands, registers_t *registers, link_t *return_values); /* extracts some bits from the command */ uint32_t vm_getbits(command_t* command, int32_t start, int32_t count); #ifdef TRACE /* for debugging: prints a link in readable form */ void vm_print_link(link_t value); /* for debugging: dumps VM registers */ void vm_print_registers( registers_t *registers ); #endif #endif /* DECODER_H_INCLUDED */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvd_reader.c�������������������������������������������������������0000644�0001750�0001750�00000111447�14647725152�017036� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2004 Billy Biggs <vektor@dumbterm.net>, * Håkan Hjort <d95hjort@dtek.chalmers.se>, * Björn Englund <d4bjorn@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ #include "config.h" #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> /* For the timing of dvdcss_title crack. */ #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <limits.h> #ifdef HAVE_DIRENT_H #include <dirent.h> #endif #ifndef HAVE_GETTIMEOFDAY # ifdef WIN32 # include <winsock.h> struct timezone; # else # include <sys/time.h> # endif /* replacement gettimeofday implementation */ #include <sys/timeb.h> static inline int _private_gettimeofday( struct timeval *tv, void *tz ) { struct timeb t; ftime( &t ); tv->tv_sec = t.time; tv->tv_usec = t.millitm * 1000; return 0; } #define gettimeofday(TV, TZ) _private_gettimeofday((TV), (TZ)) #endif /* misc win32 helpers */ #ifdef WIN32 #include <io.h> /* read() */ #define lseek64 _lseeki64 #endif #if defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__bsdi__)|| defined(__DARWIN__) #define SYS_BSD 1 #endif #if defined(__sun) #include <sys/mnttab.h> #elif defined(SYS_BSD) #include <fstab.h> #elif defined(__linux__) #include <mntent.h> #endif #include <xine/compat.h> #include "dvd_udf.h" #include "dvd_input.h" #include "dvd_reader.h" #include "md5.h" #define DEFAULT_UDF_CACHE_LEVEL 1 struct dvd_reader_s { /* Basic information. */ int isImageFile; /* Hack for keeping track of the css status. * 0: no css, 1: perhaps (need init of keys), 2: have done init */ int css_state; int css_title; /* Last title that we have called dvdinpute_title for. */ /* Information required for an image file. */ dvd_input_t dev; /* Information required for a directory path drive. */ char *path_root; /* Filesystem cache */ int udfcache_level; /* 0 - turned off, 1 - on */ void *udfcache; }; struct dvd_file_s { /* Basic information. */ dvd_reader_t *dvd; /* Hack for selecting the right css title. */ int css_title; /* Information required for an image file. */ uint32_t lb_start; uint32_t seek_pos; /* Information required for a directory path drive. */ size_t title_sizes[ 9 ]; dvd_input_t title_devs[ 9 ]; /* Calculated at open-time, size in blocks. */ ssize_t filesize; }; int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number, size_t block_count, unsigned char *data, int encrypted ); /** * Set the level of caching on udf * level = 0 (no caching) * level = 1 (caching filesystem info) */ int DVDUDFCacheLevel(dvd_reader_t *device, int level) { struct dvd_reader_s *dev = (struct dvd_reader_s *)device; if(level > 0) { level = 1; } else if(level < 0) { return dev->udfcache_level; } dev->udfcache_level = level; return level; } void *GetUDFCacheHandle(dvd_reader_t *device) { struct dvd_reader_s *dev = (struct dvd_reader_s *)device; return dev->udfcache; } void SetUDFCacheHandle(dvd_reader_t *device, void *cache) { struct dvd_reader_s *dev = (struct dvd_reader_s *)device; dev->udfcache = cache; } /* Loop over all titles and call dvdcss_title to crack the keys. */ static int initAllCSSKeys( dvd_reader_t *dvd ) { struct timeval all_s, all_e; struct timeval t_s, t_e; char filename[ MAX_UDF_FILE_NAME_LEN ]; uint32_t start, len; int title; char *nokeys_str = getenv("DVDREAD_NOKEYS"); if(nokeys_str != NULL) return 0; fprintf( stderr, "\n" ); fprintf( stderr, "libdvdread: Attempting to retrieve all CSS keys\n" ); fprintf( stderr, "libdvdread: This can take a _long_ time, " "please be patient\n\n" ); gettimeofday(&all_s, NULL); for( title = 0; title < 100; title++ ) { gettimeofday( &t_s, NULL ); if( title == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 0 ); } start = UDFFindFile( dvd, filename, &len ); if( start != 0 && len != 0 ) { /* Perform CSS key cracking for this title. */ fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n", filename, start ); if( dvdinput_title( dvd->dev, (int)start ) < 0 ) { fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)\n", filename, start); } gettimeofday( &t_e, NULL ); fprintf( stderr, "libdvdread: Elapsed time %ld\n", (long int) t_e.tv_sec - t_s.tv_sec ); } if( title == 0 ) continue; gettimeofday( &t_s, NULL ); sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, 1 ); start = UDFFindFile( dvd, filename, &len ); if( start == 0 || len == 0 ) break; /* Perform CSS key cracking for this title. */ fprintf( stderr, "libdvdread: Get key for %s at 0x%08x\n", filename, start ); if( dvdinput_title( dvd->dev, (int)start ) < 0 ) { fprintf( stderr, "libdvdread: Error cracking CSS key for %s (0x%08x)!!\n", filename, start); } gettimeofday( &t_e, NULL ); fprintf( stderr, "libdvdread: Elapsed time %ld\n", (long int) t_e.tv_sec - t_s.tv_sec ); } title--; fprintf( stderr, "libdvdread: Found %d VTS's\n", title ); gettimeofday(&all_e, NULL); fprintf( stderr, "libdvdread: Elapsed time %ld\n", (long int) all_e.tv_sec - all_s.tv_sec ); return 0; } /** * Open a DVD image or block device file. */ static dvd_reader_t *DVDOpenImageFile( const char *location, int have_css ) { dvd_reader_t *dvd; dvd_input_t dev; dev = dvdinput_open( location ); if( !dev ) { fprintf( stderr, "libdvdread: Can't open %s for reading\n", location ); return 0; } dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) ); if( !dvd ) return 0; dvd->isImageFile = 1; dvd->dev = dev; dvd->path_root = 0; dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL; dvd->udfcache = NULL; if( have_css ) { /* Only if DVDCSS_METHOD = title, a bit if it's disc or if * DVDCSS_METHOD = key but region missmatch. Unfortunaly we * don't have that information. */ dvd->css_state = 1; /* Need key init. */ } dvd->css_title = 0; return dvd; } static dvd_reader_t *DVDOpenPath( const char *path_root ) { dvd_reader_t *dvd; dvd = (dvd_reader_t *) malloc( sizeof( dvd_reader_t ) ); if( !dvd ) return 0; dvd->isImageFile = 0; dvd->dev = 0; dvd->path_root = strdup( path_root ); dvd->udfcache_level = DEFAULT_UDF_CACHE_LEVEL; dvd->udfcache = NULL; dvd->css_state = 0; /* Only used in the UDF path */ dvd->css_title = 0; /* Only matters in the UDF path */ return dvd; } #if defined(__sun) /* /dev/rdsk/c0t6d0s0 (link to /devices/...) /vol/dev/rdsk/c0t6d0/?? /vol/rdsk/<name> */ static char *sun_block2char( const char *path ) { char *new_path; /* Must contain "/dsk/" */ if( !strstr( path, "/dsk/" ) ) return (char *) strdup( path ); /* Replace "/dsk/" with "/rdsk/" */ new_path = malloc( strlen(path) + 2 ); strcpy( new_path, path ); strcpy( strstr( new_path, "/dsk/" ), "" ); strcat( new_path, "/rdsk/" ); strcat( new_path, strstr( path, "/dsk/" ) + strlen( "/dsk/" ) ); return new_path; } #endif #if defined(SYS_BSD) /* FreeBSD /dev/(r)(a)cd0c (a is for atapi), recomended to _not_ use r OpenBSD /dev/rcd0c, it needs to be the raw device NetBSD /dev/rcd0[d|c|..] d for x86, c (for non x86), perhaps others Darwin /dev/rdisk0, it needs to be the raw device BSD/OS /dev/sr0c (if not mounted) or /dev/rsr0c ('c' any letter will do) */ static char *bsd_block2char( const char *path ) { char *new_path; /* If it doesn't start with "/dev/" or does start with "/dev/r" exit */ if( !strncmp( path, "/dev/", 5 ) || strncmp( path, "/dev/r", 6 ) ) return (char *) strdup( path ); /* Replace "/dev/" with "/dev/r" */ new_path = malloc( strlen(path) + 2 ); strcpy( new_path, "/dev/r" ); strcat( new_path, path + strlen( "/dev/" ) ); return new_path; } #endif dvd_reader_t *DVDOpen( const char *ppath ) { struct stat fileinfo; int ret; int have_css; dvd_reader_t *ret_val = NULL; char *dev_name = 0; char *path; #ifdef _MSC_VER int len; #endif if( ppath == NULL ) return 0; path = strdup(ppath); /* Try to open libdvdcss or fall back to standard functions */ have_css = dvdinput_setup(); #ifdef _MSC_VER /* Strip off the trailing \ if it is not a drive */ len = strlen(path); if ((len > 1) && (path[len - 1] == '\\') && (path[len - 2] != ':')) { path[len-1] = '\0'; } #endif ret = stat( path, &fileinfo ); if( ret < 0 ) { /* maybe "host:port" url? try opening it with acCeSS library */ if( strchr(path,':') ) { ret_val = DVDOpenImageFile( path, have_css ); free(path); return ret_val; } /* If we can't stat the file, give up */ fprintf( stderr, "libdvdread: Can't stat %s\n", path ); perror(""); free(path); return 0; } /* First check if this is a block/char device or a file*/ if( S_ISBLK( fileinfo.st_mode ) || S_ISCHR( fileinfo.st_mode ) || S_ISREG( fileinfo.st_mode ) ) { /** * Block devices and regular files are assumed to be DVD-Video images. */ #if defined(__sun) ret_val = DVDOpenImageFile( sun_block2char( path ), have_css ); #elif defined(SYS_BSD) ret_val = DVDOpenImageFile( bsd_block2char( path ), have_css ); #else ret_val = DVDOpenImageFile( path, have_css ); #endif free(path); return ret_val; } else if( S_ISDIR( fileinfo.st_mode ) ) { dvd_reader_t *auth_drive = 0; char *path_copy; #if defined(SYS_BSD) struct fstab* fe; #elif defined(__sun) || defined(__linux__) FILE *mntfile; #endif /* XXX: We should scream real loud here. */ if( !(path_copy = strdup( path ) ) ) { free(path); return 0; } #ifndef WIN32 /* don't have fchdir, and getcwd( NULL, ... ) is strange */ /* Also WIN32 does not have symlinks, so we don't need this bit of code. */ /* Resolve any symlinks and get the absolut dir name. */ { char *new_path; int cdir = open( ".", O_RDONLY ); if( cdir >= 0 ) { chdir( path_copy ); new_path = getcwd( NULL, XINE_PATH_MAX ); fchdir( cdir ); close( cdir ); if( new_path ) { free( path_copy ); path_copy = new_path; } } } #endif /** * If we're being asked to open a directory, check if that directory * is the mountpoint for a DVD-ROM which we can use instead. */ if( strlen( path_copy ) > 1 ) { if( path_copy[ strlen( path_copy ) - 1 ] == '/' ) path_copy[ strlen( path_copy ) - 1 ] = '\0'; } if( strlen( path_copy ) > 9 ) { if( !strcasecmp( &(path_copy[ strlen( path_copy ) - 9 ]), "/video_ts" ) ) { path_copy[ strlen( path_copy ) - 9 ] = '\0'; } } #if defined(SYS_BSD) if( ( fe = getfsfile( path_copy ) ) ) { dev_name = bsd_block2char( fe->fs_spec ); fprintf( stderr, "libdvdread: Attempting to use device %s" " mounted on %s for CSS authentication\n", dev_name, fe->fs_file ); auth_drive = DVDOpenImageFile( dev_name, have_css ); } #elif defined(__sun) mntfile = fopen( MNTTAB, "r" ); if( mntfile ) { struct mnttab mp; int res; while( ( res = getmntent( mntfile, &mp ) ) != -1 ) { if( res == 0 && !strcmp( mp.mnt_mountp, path_copy ) ) { dev_name = sun_block2char( mp.mnt_special ); fprintf( stderr, "libdvdread: Attempting to use device %s" " mounted on %s for CSS authentication\n", dev_name, mp.mnt_mountp ); auth_drive = DVDOpenImageFile( dev_name, have_css ); break; } } fclose( mntfile ); } #elif defined(__linux__) mntfile = fopen( MOUNTED, "r" ); if( mntfile ) { struct mntent *me; while( ( me = getmntent( mntfile ) ) ) { if( !strcmp( me->mnt_dir, path_copy ) ) { fprintf( stderr, "libdvdread: Attempting to use device %s" " mounted on %s for CSS authentication\n", me->mnt_fsname, me->mnt_dir ); auth_drive = DVDOpenImageFile( me->mnt_fsname, have_css ); /* If the device is not encrypted, don't access the device * directly as it would fail for non-UDF DVDs */ if ( auth_drive && dvdinput_is_encrypted( auth_drive->dev ) == 0) { DVDClose( auth_drive ); auth_drive = NULL; break; } dev_name = strdup(me->mnt_fsname); break; } } fclose( mntfile ); } #elif defined(_MSC_VER) auth_drive = DVDOpenImageFile( path, have_css ); #endif #ifndef _MSC_VER if( !dev_name ) { fprintf( stderr, "libdvdread: Couldn't find device name.\n" ); } else if( !auth_drive ) { fprintf( stderr, "libdvdread: Device %s inaccessible, " "CSS authentication not available.\n", dev_name ); } #else if( !auth_drive ) { fprintf( stderr, "libdvdread: Device %s inaccessible, " "CSS authentication not available.\n", dev_name ); } #endif free( dev_name ); free( path_copy ); /** * If we've opened a drive, just use that. */ if( auth_drive ) { free(path); return auth_drive; } /** * Otherwise, we now try to open the directory tree instead. */ ret_val = DVDOpenPath( path ); free( path ); return ret_val; } /* If it's none of the above, screw it. */ fprintf( stderr, "libdvdread: Could not open %s\n", path ); free( path ); return 0; } void DVDClose( dvd_reader_t *dvd ) { if( dvd ) { if( dvd->dev ) dvdinput_close( dvd->dev ); if( dvd->path_root ) free( dvd->path_root ); if( dvd->udfcache ) FreeUDFCache( dvd->udfcache ); free( dvd ); } } /** * Open an unencrypted file on a DVD image file. */ static dvd_file_t *DVDOpenFileUDF( dvd_reader_t *dvd, char *filename ) { uint32_t start, len; dvd_file_t *dvd_file; start = UDFFindFile( dvd, filename, &len ); if( !start ) { fprintf( stderr, "libdvdnav:DVDOpenFileUDF:UDFFindFile %s failed\n", filename ); return 0; } dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) { fprintf( stderr, "libdvdnav:DVDOpenFileUDF:malloc failed\n" ); return 0; } dvd_file->dvd = dvd; dvd_file->lb_start = start; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = len / DVD_VIDEO_LB_LEN; return dvd_file; } /** * Searches for <file> in directory <path>, ignoring case. * Returns 0 and full filename in <filename>. * or -1 on file not found. * or -2 on path not found. */ static int findDirFile( const char *path, const char *file, char *filename ) { DIR *dir; struct dirent *ent; dir = opendir( path ); if( !dir ) return -2; while( ( ent = readdir( dir ) ) != NULL ) { if( !strcasecmp( ent->d_name, file ) ) { sprintf( filename, "%s%s%s", path, ( ( path[ strlen( path ) - 1 ] == '/' ) ? "" : "/" ), ent->d_name ); closedir (dir); return 0; } } closedir (dir); return -1; } static int findDVDFile( dvd_reader_t *dvd, const char *file, char *filename ) { char video_path[ XINE_PATH_MAX + 1 ]; const char *nodirfile; int ret; /* Strip off the directory for our search */ if( !strncasecmp( "/VIDEO_TS/", file, 10 ) ) { nodirfile = &(file[ 10 ]); } else { nodirfile = file; } ret = findDirFile( dvd->path_root, nodirfile, filename ); if( ret < 0 ) { /* Try also with adding the path, just in case. */ sprintf( video_path, "%s/VIDEO_TS/", dvd->path_root ); ret = findDirFile( video_path, nodirfile, filename ); if( ret < 0 ) { /* Try with the path, but in lower case. */ sprintf( video_path, "%s/video_ts/", dvd->path_root ); ret = findDirFile( video_path, nodirfile, filename ); if( ret < 0 ) { return 0; } } } return 1; } /** * Open an unencrypted file from a DVD directory tree. */ static dvd_file_t *DVDOpenFilePath( dvd_reader_t *dvd, char *filename ) { char full_path[ XINE_PATH_MAX + 1 ]; dvd_file_t *dvd_file; struct stat fileinfo; dvd_input_t dev; /* Get the full path of the file. */ if( !findDVDFile( dvd, filename, full_path ) ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:findDVDFile %s failed\n", filename ); return 0; } dev = dvdinput_open( full_path ); if( !dev ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvdinput_open %s failed\n", full_path ); return 0; } dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) { fprintf( stderr, "libdvdnav:DVDOpenFilePath:dvd_file malloc failed\n" ); return 0; } dvd_file->dvd = dvd; dvd_file->lb_start = 0; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = 0; if( stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); free( dvd_file ); return 0; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ 0 ] = dev; dvd_file->filesize = dvd_file->title_sizes[ 0 ]; return dvd_file; } static dvd_file_t *DVDOpenVOBUDF( dvd_reader_t *dvd, int title, int menu ) { char filename[ MAX_UDF_FILE_NAME_LEN ]; uint32_t start, len; dvd_file_t *dvd_file; if( title == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.VOB" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, menu ? 0 : 1 ); } start = UDFFindFile( dvd, filename, &len ); if( start == 0 ) return 0; dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) return 0; dvd_file->dvd = dvd; /*Hack*/ dvd_file->css_title = title << 1 | menu; dvd_file->lb_start = start; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = len / DVD_VIDEO_LB_LEN; /* Calculate the complete file size for every file in the VOBS */ if( !menu ) { int cur; for( cur = 2; cur < 10; cur++ ) { sprintf( filename, "/VIDEO_TS/VTS_%02d_%d.VOB", title, cur ); if( !UDFFindFile( dvd, filename, &len ) ) break; dvd_file->filesize += len / DVD_VIDEO_LB_LEN; } } if( dvd->css_state == 1 /* Need key init */ ) { initAllCSSKeys( dvd ); dvd->css_state = 2; } /* if( dvdinput_title( dvd_file->dvd->dev, (int)start ) < 0 ) { fprintf( stderr, "libdvdread: Error cracking CSS key for %s\n", filename ); } */ return dvd_file; } static dvd_file_t *DVDOpenVOBPath( dvd_reader_t *dvd, int title, int menu ) { char filename[ MAX_UDF_FILE_NAME_LEN ]; char full_path[ XINE_PATH_MAX + 1 ]; struct stat fileinfo; dvd_file_t *dvd_file; int i; dvd_file = (dvd_file_t *) malloc( sizeof( dvd_file_t ) ); if( !dvd_file ) return 0; dvd_file->dvd = dvd; /*Hack*/ dvd_file->css_title = title << 1 | menu; dvd_file->lb_start = 0; dvd_file->seek_pos = 0; memset( dvd_file->title_sizes, 0, sizeof( dvd_file->title_sizes ) ); memset( dvd_file->title_devs, 0, sizeof( dvd_file->title_devs ) ); dvd_file->filesize = 0; if( menu ) { dvd_input_t dev; if( title == 0 ) { sprintf( filename, "VIDEO_TS.VOB" ); } else { sprintf( filename, "VTS_%02i_0.VOB", title ); } if( !findDVDFile( dvd, filename, full_path ) ) { free( dvd_file ); return 0; } dev = dvdinput_open( full_path ); if( dev == NULL ) { free( dvd_file ); return 0; } if( stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); free( dvd_file ); return 0; } dvd_file->title_sizes[ 0 ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ 0 ] = dev; dvdinput_title( dvd_file->title_devs[0], 0); dvd_file->filesize = dvd_file->title_sizes[ 0 ]; } else { for( i = 0; i < 9; ++i ) { sprintf( filename, "VTS_%02i_%i.VOB", title, i + 1 ); if( !findDVDFile( dvd, filename, full_path ) ) { break; } if( stat( full_path, &fileinfo ) < 0 ) { fprintf( stderr, "libdvdread: Can't stat() %s.\n", filename ); break; } dvd_file->title_sizes[ i ] = fileinfo.st_size / DVD_VIDEO_LB_LEN; dvd_file->title_devs[ i ] = dvdinput_open( full_path ); dvdinput_title( dvd_file->title_devs[ i ], 0 ); dvd_file->filesize += dvd_file->title_sizes[ i ]; } if( !dvd_file->title_devs[ 0 ] ) { free( dvd_file ); return 0; } } return dvd_file; } dvd_file_t *DVDOpenFile( dvd_reader_t *dvd, int titlenum, dvd_read_domain_t domain ) { char filename[ MAX_UDF_FILE_NAME_LEN ]; /* Check arguments. */ if( dvd == NULL || titlenum < 0 ) return NULL; switch( domain ) { case DVD_READ_INFO_FILE: if( titlenum == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.IFO" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02i_0.IFO", titlenum ); } break; case DVD_READ_INFO_BACKUP_FILE: if( titlenum == 0 ) { sprintf( filename, "/VIDEO_TS/VIDEO_TS.BUP" ); } else { sprintf( filename, "/VIDEO_TS/VTS_%02i_0.BUP", titlenum ); } break; case DVD_READ_MENU_VOBS: if( dvd->isImageFile ) { return DVDOpenVOBUDF( dvd, titlenum, 1 ); } else { return DVDOpenVOBPath( dvd, titlenum, 1 ); } break; case DVD_READ_TITLE_VOBS: if( titlenum == 0 ) return 0; if( dvd->isImageFile ) { return DVDOpenVOBUDF( dvd, titlenum, 0 ); } else { return DVDOpenVOBPath( dvd, titlenum, 0 ); } break; default: fprintf( stderr, "libdvdread: Invalid domain for file open.\n" ); return NULL; } if( dvd->isImageFile ) { return DVDOpenFileUDF( dvd, filename ); } else { return DVDOpenFilePath( dvd, filename ); } } void DVDCloseFile( dvd_file_t *dvd_file ) { int i; if( dvd_file ) { if( dvd_file->dvd->isImageFile ) { ; } else { for( i = 0; i < 9; ++i ) { if( dvd_file->title_devs[ i ] ) { dvdinput_close( dvd_file->title_devs[i] ); } } } free( dvd_file ); dvd_file = 0; } } /* Internal, but used from dvd_udf.c */ int UDFReadBlocksRaw( dvd_reader_t *device, uint32_t lb_number, size_t block_count, unsigned char *data, int encrypted ) { int ret; if( !device->dev ) { fprintf( stderr, "libdvdread: Fatal error in block read.\n" ); return 0; } ret = dvdinput_seek( device->dev, (int) lb_number ); if( ret != (int) lb_number ) { fprintf( stderr, "libdvdread: Can't seek to block %u\n", lb_number ); return 0; } ret = dvdinput_read( device->dev, (char *) data, (int) block_count, encrypted ); return ret; } /* This is using a single input and starting from 'dvd_file->lb_start' offset. * * Reads 'block_count' blocks from 'dvd_file' at block offset 'offset' * into the buffer located at 'data' and if 'encrypted' is set * descramble the data if it's encrypted. Returning either an * negative error or the number of blocks read. */ static int DVDReadBlocksUDF( dvd_file_t *dvd_file, uint32_t offset, size_t block_count, unsigned char *data, int encrypted ) { return UDFReadBlocksRaw( dvd_file->dvd, dvd_file->lb_start + offset, block_count, data, encrypted ); } /* This is using possibly several inputs and starting from an offset of '0'. * * Reads 'block_count' blocks from 'dvd_file' at block offset 'offset' * into the buffer located at 'data' and if 'encrypted' is set * descramble the data if it's encrypted. Returning either an * negative error or the number of blocks read. */ static int DVDReadBlocksPath( dvd_file_t *dvd_file, unsigned int offset, size_t block_count, unsigned char *data, int encrypted ) { int i; int ret, ret2, off; ret = 0; ret2 = 0; for( i = 0; i < 9; ++i ) { if( !dvd_file->title_sizes[ i ] ) return 0; /* Past end of file */ if( offset < dvd_file->title_sizes[ i ] ) { if( ( offset + block_count ) <= dvd_file->title_sizes[ i ] ) { off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset ); if( off < 0 || off != (int)offset ) { fprintf( stderr, "libdvdread: Can't seek to block %d\n", offset ); return off < 0 ? off : 0; } ret = dvdinput_read( dvd_file->title_devs[ i ], data, (int)block_count, encrypted ); break; } else { size_t part1_size = dvd_file->title_sizes[ i ] - offset; /* FIXME: Really needs to be a while loop. * (This is only true if you try and read >1GB at a time) */ /* Read part 1 */ off = dvdinput_seek( dvd_file->title_devs[ i ], (int)offset ); if( off < 0 || off != (int)offset ) { fprintf( stderr, "libdvdread: Can't seek to block %d\n", offset ); return off < 0 ? off : 0; } ret = dvdinput_read( dvd_file->title_devs[ i ], data, (int)part1_size, encrypted ); if( ret < 0 ) return ret; /* FIXME: This is wrong if i is the last file in the set. * also error from this read will not show in ret. */ /* Does the next part exist? If not then return now. */ if( !dvd_file->title_devs[ i + 1 ] ) return ret; /* Read part 2 */ off = dvdinput_seek( dvd_file->title_devs[ i + 1 ], 0 ); if( off < 0 || off != 0 ) { fprintf( stderr, "libdvdread: Can't seek to block %d\n", 0 ); return off < 0 ? off : 0; } ret2 = dvdinput_read( dvd_file->title_devs[ i + 1 ], data + ( part1_size * (int64_t)DVD_VIDEO_LB_LEN ), (int)(block_count - part1_size), encrypted ); if( ret2 < 0 ) return ret2; break; } } else { offset -= dvd_file->title_sizes[ i ]; } } return ret + ret2; } /* This is broken reading more than 2Gb at a time is ssize_t is 32-bit. */ ssize_t DVDReadBlocks( dvd_file_t *dvd_file, int offset, size_t block_count, unsigned char *data ) { int ret; /* Check arguments. */ if( dvd_file == NULL || offset < 0 || data == NULL ) return -1; /* Hack, and it will still fail for multiple opens in a threaded app ! */ if( dvd_file->dvd->css_title != dvd_file->css_title ) { dvd_file->dvd->css_title = dvd_file->css_title; if( dvd_file->dvd->isImageFile ) { dvdinput_title( dvd_file->dvd->dev, (int)dvd_file->lb_start ); } /* Here each vobu has it's own dvdcss handle, so no need to update else { dvdinput_title( dvd_file->title_devs[ 0 ], (int)dvd_file->lb_start ); }*/ } if( dvd_file->dvd->isImageFile ) { ret = DVDReadBlocksUDF( dvd_file, (uint32_t)offset, block_count, data, DVDINPUT_READ_DECRYPT ); } else { ret = DVDReadBlocksPath( dvd_file, (unsigned int)offset, block_count, data, DVDINPUT_READ_DECRYPT ); } return (ssize_t)ret; } int32_t DVDFileSeek( dvd_file_t *dvd_file, int32_t offset ) { /* Check arguments. */ if( dvd_file == NULL || offset < 0 ) return -1; if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) { return -1; } dvd_file->seek_pos = (uint32_t) offset; return offset; } int32_t DVDFileSeekForce( dvd_file_t *dvd_file, int offset, int force_size ) { /* Check arguments. */ if( dvd_file == NULL || offset < 0 ) return -1; if( dvd_file->dvd->isImageFile ) { if( force_size < 0 ) force_size = (offset - 1) / DVD_VIDEO_LB_LEN + 1; if( dvd_file->filesize < force_size) { dvd_file->filesize = force_size; fprintf(stderr, "libdvdread: Ignored UDF provided size of file.\n"); } } if( offset > dvd_file->filesize * DVD_VIDEO_LB_LEN ) { return -1; } dvd_file->seek_pos = (uint32_t) offset; return offset; } ssize_t DVDReadBytes( dvd_file_t *dvd_file, void *data, size_t byte_size ) { unsigned char *secbuf_base, *secbuf; unsigned int numsec, seek_sector, seek_byte; int ret; /* Check arguments. */ if( dvd_file == NULL || data == NULL ) return -1; seek_sector = dvd_file->seek_pos / DVD_VIDEO_LB_LEN; seek_byte = dvd_file->seek_pos % DVD_VIDEO_LB_LEN; numsec = ( ( seek_byte + byte_size ) / DVD_VIDEO_LB_LEN ) + ( ( ( seek_byte + byte_size ) % DVD_VIDEO_LB_LEN ) ? 1 : 0 ); secbuf_base = (unsigned char *) malloc( numsec * DVD_VIDEO_LB_LEN + 2048 ); secbuf = (unsigned char *)(((uintptr_t)secbuf_base & ~((uintptr_t)2047)) + 2048); if( !secbuf_base ) { fprintf( stderr, "libdvdread: Can't allocate memory " "for file read!\n" ); return 0; } if( dvd_file->dvd->isImageFile ) { ret = DVDReadBlocksUDF( dvd_file, (uint32_t) seek_sector, (size_t) numsec, secbuf, DVDINPUT_NOFLAGS ); } else { ret = DVDReadBlocksPath( dvd_file, seek_sector, (size_t) numsec, secbuf, DVDINPUT_NOFLAGS ); } if( ret != (int) numsec ) { free( secbuf_base ); return ret < 0 ? ret : 0; } memcpy( data, &(secbuf[ seek_byte ]), byte_size ); free( secbuf_base ); DVDFileSeekForce(dvd_file, dvd_file->seek_pos + byte_size, -1); return byte_size; } ssize_t DVDFileSize( dvd_file_t *dvd_file ) { /* Check arguments. */ if( dvd_file == NULL ) return -1; return dvd_file->filesize; } int DVDDiscID( dvd_reader_t *dvd, unsigned char *discid ) { struct md5_ctx ctx; int title; /* Check arguments. */ if( dvd == NULL || discid == NULL ) return 0; /* Go through the first 10 IFO:s, in order, * and md5sum them, i.e VIDEO_TS.IFO and VTS_0?_0.IFO */ md5_init_ctx( &ctx ); for( title = 0; title < 10; title++ ) { dvd_file_t *dvd_file = DVDOpenFile( dvd, title, DVD_READ_INFO_FILE ); if( dvd_file != NULL ) { ssize_t bytes_read; size_t file_size = dvd_file->filesize * DVD_VIDEO_LB_LEN; char *buffer_base = malloc( file_size + 2048 ); char *buffer = (unsigned char *)(((uintptr_t)buffer_base & ~((uintptr_t)2047)) + 2048); if( buffer_base == NULL ) { fprintf( stderr, "libdvdread: DVDDiscId, failed to " "allocate memory for file read!\n" ); return -1; } bytes_read = DVDReadBytes( dvd_file, buffer, file_size ); if( (size_t)bytes_read != file_size ) { fprintf( stderr, "libdvdread: DVDDiscId read returned %zd bytes" ", wanted %zd\n", bytes_read, file_size ); DVDCloseFile( dvd_file ); free( buffer_base ); return -1; } md5_process_bytes( buffer, file_size, &ctx ); DVDCloseFile( dvd_file ); free( buffer_base ); } } md5_finish_ctx( &ctx, discid ); return 0; } int DVDISOVolumeInfo( dvd_reader_t *dvd, char *volid, unsigned int volid_size, unsigned char *volsetid, unsigned int volsetid_size ) { unsigned char *buffer, *buffer_base; int ret; /* Check arguments. */ if( dvd == NULL ) return 0; if( dvd->dev == NULL ) { /* No block access, so no ISO... */ return -1; } buffer_base = malloc( DVD_VIDEO_LB_LEN + 2048 ); buffer = (unsigned char *)(((uintptr_t)buffer_base & ~((uintptr_t)2047)) + 2048); if( buffer_base == NULL ) { fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to " "allocate memory for file read!\n" ); return -1; } ret = UDFReadBlocksRaw( dvd, 16, 1, buffer, 0 ); if( ret != 1 ) { fprintf( stderr, "libdvdread: DVDISOVolumeInfo, failed to " "read ISO9660 Primary Volume Descriptor!\n" ); free( buffer_base ); return -1; } if( (volid != NULL) && (volid_size > 0) ) { unsigned int n; for(n = 0; n < 32; n++) { if(buffer[40+n] == 0x20) { break; } } if(volid_size > n+1) { volid_size = n+1; } memcpy(volid, &buffer[40], volid_size-1); volid[volid_size-1] = '\0'; } if( (volsetid != NULL) && (volsetid_size > 0) ) { if(volsetid_size > 128) { volsetid_size = 128; } memcpy(volsetid, &buffer[190], volsetid_size); } free( buffer_base ); return 0; } int DVDUDFVolumeInfo( dvd_reader_t *dvd, char *volid, unsigned int volid_size, unsigned char *volsetid, unsigned int volsetid_size ) { int ret; /* Check arguments. */ if( dvd == NULL ) return -1; if( dvd->dev == NULL ) { /* No block access, so no UDF VolumeSet Identifier */ return -1; } if( (volid != NULL) && (volid_size > 0) ) { ret = UDFGetVolumeIdentifier(dvd, volid, volid_size); if(!ret) { return -1; } } if( (volsetid != NULL) && (volsetid_size > 0) ) { ret = UDFGetVolumeSetIdentifier(dvd, volsetid, volsetid_size); if(!ret) { return -1; } } return 0; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/nav_types.h��������������������������������������������������������0000644�0001750�0001750�00000021463�14647725152�016752� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef NAV_TYPES_H_INCLUDED #define NAV_TYPES_H_INCLUDED /* * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort@dtek.chalmers.se> * * The data structures in this file should represent the layout of the * pci and dsi packets as they are stored in the stream. Information * found by reading the source to VOBDUMP is the base for the structure * and names of these data types. * * VOBDUMP: a program for examining DVD .VOB files. * Copyright 1998, 1999 Eric Smith <eric@brouhaha.com> * * VOBDUMP is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. Note that I am not * granting permission to redistribute or modify VOBDUMP under the terms * of any later version of the General Public License. * * This program is distributed in the hope that it will be useful (or at * least amusing), but WITHOUT ANY WARRANTY; without even the implied * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include <inttypes.h> #include "ifo_types.h" /* only dvd_time_t, vm_cmd_t and user_ops_t */ #undef ATTRIBUTE_PACKED #undef PRAGMA_PACK_BEGIN #undef PRAGMA_PACK_END #if defined(__GNUC__) #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) #define ATTRIBUTE_PACKED __attribute__ ((packed)) #define PRAGMA_PACK 0 #endif #endif #if !defined(ATTRIBUTE_PACKED) #define ATTRIBUTE_PACKED #define PRAGMA_PACK 1 #endif /* The length including the substream id byte. */ #define PCI_BYTES 0x3d4 #define DSI_BYTES 0x3fa #define PS2_PCI_SUBSTREAM_ID 0x00 #define PS2_DSI_SUBSTREAM_ID 0x01 /* Remove this */ #define DSI_START_BYTE 1031 #if PRAGMA_PACK #pragma pack(1) #endif /** * PCI General Information */ typedef struct { uint32_t nv_pck_lbn; /**< sector address of this nav pack */ uint16_t vobu_cat; /**< 'category' of vobu */ uint16_t zero1; /**< reserved */ user_ops_t vobu_uop_ctl; /**< UOP of vobu */ uint32_t vobu_s_ptm; /**< start presentation time of vobu */ uint32_t vobu_e_ptm; /**< end presentation time of vobu */ uint32_t vobu_se_e_ptm; /**< end ptm of sequence end in vobu */ dvd_time_t e_eltm; /**< Cell elapsed time */ char vobu_isrc[32]; } ATTRIBUTE_PACKED pci_gi_t; /** * Non Seamless Angle Information */ typedef struct { uint32_t nsml_agl_dsta[9]; /**< address of destination vobu in AGL_C#n */ } ATTRIBUTE_PACKED nsml_agli_t; /** * Highlight General Information * * For btngrX_dsp_ty the bits have the following meaning: * 000b: normal 4/3 only buttons * XX1b: wide (16/9) buttons * X1Xb: letterbox buttons * 1XXb: pan&scan buttons */ typedef struct { uint16_t hli_ss; /**< status, only low 2 bits 0: no buttons, 1: different 2: equal 3: eual except for button cmds */ uint32_t hli_s_ptm; /**< start ptm of hli */ uint32_t hli_e_ptm; /**< end ptm of hli */ uint32_t btn_se_e_ptm; /**< end ptm of button select */ unsigned int zero1 : 2; /**< reserved */ unsigned int btngr_ns : 2; /**< number of button groups 1, 2 or 3 with 36/18/12 buttons */ unsigned int zero2 : 1; /**< reserved */ unsigned int btngr1_dsp_ty : 3; /**< display type of subpic stream for button group 1 */ unsigned int zero3 : 1; /**< reserved */ unsigned int btngr2_dsp_ty : 3; /**< display type of subpic stream for button group 2 */ unsigned int zero4 : 1; /**< reserved */ unsigned int btngr3_dsp_ty : 3; /**< display type of subpic stream for button group 3 */ uint8_t btn_ofn; /**< button offset number range 0-255 */ uint8_t btn_ns; /**< number of valid buttons <= 36/18/12 (low 6 bits) */ uint8_t nsl_btn_ns; /**< number of buttons selectable by U_BTNNi (low 6 bits) nsl_btn_ns <= btn_ns */ uint8_t zero5; /**< reserved */ uint8_t fosl_btnn; /**< forcedly selected button (low 6 bits) */ uint8_t foac_btnn; /**< forcedly activated button (low 6 bits) */ } ATTRIBUTE_PACKED hl_gi_t; /** * Button Color Information Table * Each entry beeing a 32bit word that contains the color indexs and alpha * values to use. They are all represented by 4 bit number and stored * like this [Ci3, Ci2, Ci1, Ci0, A3, A2, A1, A0]. The actual palette * that the indexes reference is in the PGC. * @TODO split the uint32_t into a struct */ typedef struct { uint32_t btn_coli[3][2]; /**< [button color number-1][select:0/action:1] */ } ATTRIBUTE_PACKED btn_colit_t; /** * Button Information * * NOTE: I've had to change the structure from the disk layout to get * the packing to work with Sun's Forte C compiler. * The 4 and 7 bytes are 'rotated' was: ABC DEF GHIJ is: ABCG DEFH IJ */ typedef struct { unsigned int btn_coln : 2; /**< button color number */ unsigned int x_start : 10; /**< x start offset within the overlay */ unsigned int zero1 : 2; /**< reserved */ unsigned int x_end : 10; /**< x end offset within the overlay */ unsigned int auto_action_mode : 2; /**< 0: no, 1: activated if selected */ unsigned int y_start : 10; /**< y start offset within the overlay */ unsigned int zero2 : 2; /**< reserved */ unsigned int y_end : 10; /**< y end offset within the overlay */ unsigned int zero3 : 2; /**< reserved */ unsigned int up : 6; /**< button index when pressing up */ unsigned int zero4 : 2; /**< reserved */ unsigned int down : 6; /**< button index when pressing down */ unsigned int zero5 : 2; /**< reserved */ unsigned int left : 6; /**< button index when pressing left */ unsigned int zero6 : 2; /**< reserved */ unsigned int right : 6; /**< button index when pressing right */ vm_cmd_t cmd; } ATTRIBUTE_PACKED btni_t; /** * Highlight Information */ typedef struct { hl_gi_t hl_gi; btn_colit_t btn_colit; btni_t btnit[36]; } ATTRIBUTE_PACKED hli_t; /** * PCI packet */ typedef struct { pci_gi_t pci_gi; nsml_agli_t nsml_agli; hli_t hli; uint8_t zero1[189]; } ATTRIBUTE_PACKED pci_t; /** * DSI General Information */ typedef struct { uint32_t nv_pck_scr; uint32_t nv_pck_lbn; /**< sector address of this nav pack */ uint32_t vobu_ea; /**< end address of this VOBU */ uint32_t vobu_1stref_ea; /**< end address of the 1st reference image */ uint32_t vobu_2ndref_ea; /**< end address of the 2nd reference image */ uint32_t vobu_3rdref_ea; /**< end address of the 3rd reference image */ uint16_t vobu_vob_idn; /**< VOB Id number that this VOBU is part of */ uint8_t zero1; /**< reserved */ uint8_t vobu_c_idn; /**< Cell Id number that this VOBU is part of */ dvd_time_t c_eltm; /**< Cell elapsed time */ } ATTRIBUTE_PACKED dsi_gi_t; /** * Seamless Playback Information */ typedef struct { uint16_t category; /**< 'category' of seamless VOBU */ uint32_t ilvu_ea; /**< end address of interleaved Unit */ uint32_t ilvu_sa; /**< start address of next interleaved unit */ uint16_t size; /**< size of next interleaved unit */ uint32_t vob_v_s_s_ptm; /**< video start ptm in vob */ uint32_t vob_v_e_e_ptm; /**< video end ptm in vob */ struct { uint32_t stp_ptm1; uint32_t stp_ptm2; uint32_t gap_len1; uint32_t gap_len2; } vob_a[8]; } ATTRIBUTE_PACKED sml_pbi_t; /** * Seamless Angle Infromation for one angle */ typedef struct { uint32_t address; /**< offset to next ILVU, high bit is before/after */ uint16_t size; /**< byte size of the ILVU pointed to by address */ } ATTRIBUTE_PACKED sml_agl_data_t; /** * Seamless Angle Infromation */ typedef struct { sml_agl_data_t data[9]; } ATTRIBUTE_PACKED sml_agli_t; /** * VOBU Search Information */ typedef struct { uint32_t next_video; /**< Next vobu that contains video */ uint32_t fwda[19]; /**< Forwards, time */ uint32_t next_vobu; uint32_t prev_vobu; uint32_t bwda[19]; /**< Backwards, time */ uint32_t prev_video; } ATTRIBUTE_PACKED vobu_sri_t; #define SRI_END_OF_CELL 0x3fffffff /** * Synchronous Information */ typedef struct { uint16_t a_synca[8]; /**< offset to first audio packet for this VOBU */ uint32_t sp_synca[32]; /**< offset to first subpicture packet */ } ATTRIBUTE_PACKED synci_t; /** * DSI packet */ typedef struct { dsi_gi_t dsi_gi; sml_pbi_t sml_pbi; sml_agli_t sml_agli; vobu_sri_t vobu_sri; synci_t synci; uint8_t zero1[471]; } ATTRIBUTE_PACKED dsi_t; #if PRAGMA_PACK #pragma pack() #endif #endif /* NAV_TYPES_H_INCLUDED */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/nav_read.h���������������������������������������������������������0000644�0001750�0001750�00000002764�14647725152�016524� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef NAV_READ_H_INCLUDED #define NAV_READ_H_INCLUDED /* * Copyright (C) 2000, 2001, 2002 Håkan Hjort <d95hjort@dtek.chalmers.se>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "nav_types.h" /** * Parsing of NAV data, PCI and DSI parts. */ #ifdef __cplusplus extern "C" { #endif /** * Reads the PCI packet data pointed to into th pci struct. * * @param pci Pointer to the PCI data structure to be filled in. * @param bufffer Pointer to the buffer of the on disc PCI data. */ void navRead_PCI(pci_t *, unsigned char *); /** * Reads the DSI packet data pointed to into dsi struct. * * @param dsi Pointer to the DSI data structure to be filled in. * @param bufffer Pointer to the buffer of the on disc DSI data. */ void navRead_DSI(dsi_t *, unsigned char *); #ifdef __cplusplus }; #endif #endif /* NAV_READ_H_INCLUDED */ ������������xine-lib-1.2/src/input/libdvdnav/dvd_udf.h����������������������������������������������������������0000644�0001750�0001750�00000004312�14647725152�016347� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DVD_UDF_H_INCLUDED #define DVD_UDF_H_INCLUDED /* * This code is based on dvdudf by: * Christian Wolff <scarabaeus@convergence.de>. * * Modifications by: * Billy Biggs <vektor@dumbterm.net>. * Björn Englund <d4bjorn@dtek.chalmers.se>. * * dvdudf: parse and read the UDF volume information of a DVD Video * Copyright (C) 1999 Christian Wolff for convergence integrated media * GmbH The author can be reached at scarabaeus@convergence.de, the * project's page is at http://linuxtv.org/dvd/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02111-1307, USA. Or, point your browser to * http://www.gnu.org/copyleft/gpl.html */ #include <inttypes.h> #include "dvd_reader.h" #ifdef __cplusplus extern "C" { #endif /** * Looks for a file on the UDF disc/imagefile and returns the block number * where it begins, or 0 if it is not found. The filename should be an * absolute pathname on the UDF filesystem, starting with '/'. For example, * '/VIDEO_TS/VTS_01_1.IFO'. On success, filesize will be set to the size of * the file in bytes. */ uint32_t UDFFindFile( dvd_reader_t *device, char *filename, uint32_t *size ); void FreeUDFCache(void *cache); int UDFGetVolumeIdentifier(dvd_reader_t *device, char *volid, unsigned int volid_size); int UDFGetVolumeSetIdentifier(dvd_reader_t *device, uint8_t *volsetid, unsigned int volsetid_size); void *GetUDFCacheHandle(dvd_reader_t *device); void SetUDFCacheHandle(dvd_reader_t *device, void *cache); #ifdef __cplusplus }; #endif #endif /* DVD_UDF_H_INCLUDED */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/md5.c��������������������������������������������������������������0000644�0001750�0001750�00000032456�14647725152�015426� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* md5.c - Functions to compute MD5 message digest of files or memory blocks according to the definition of MD5 in RFC 1321 from April 1992. Copyright (C) 1995, 1996, 2001 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <sys/types.h> #include <stdlib.h> #include <string.h> #include "md5.h" /* #include "unlocked-io.h" */ #ifdef _LIBC # include <endian.h> # if __BYTE_ORDER == __BIG_ENDIAN # define WORDS_BIGENDIAN 1 # endif #endif #ifdef WORDS_BIGENDIAN # define SWAP(n) \ (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #else # define SWAP(n) (n) #endif /* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (RFC 1321, 3.1: Step 1) */ static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; /* Initialize structure containing state of computation. (RFC 1321, 3.3: Step 3) */ void md5_init_ctx (ctx) struct md5_ctx *ctx; { ctx->A = 0x67452301; ctx->B = 0xefcdab89; ctx->C = 0x98badcfe; ctx->D = 0x10325476; ctx->total[0] = ctx->total[1] = 0; ctx->buflen = 0; } /* Put result from CTX in first 16 bytes following RESBUF. The result must be in little endian byte order. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void * md5_read_ctx (ctx, resbuf) const struct md5_ctx *ctx; void *resbuf; { ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); return resbuf; } /* Process the remaining bytes in the internal buffer and the usual prolog according to the standard and write the result to RESBUF. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ void * md5_finish_ctx (ctx, resbuf) struct md5_ctx *ctx; void *resbuf; { /* Take yet unprocessed bytes into account. */ md5_uint32 bytes = ctx->buflen, temp; size_t pad; /* Now count remaining bytes. */ ctx->total[0] += bytes; if (ctx->total[0] < bytes) ++ctx->total[1]; pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; memcpy (&ctx->buffer[bytes], fillbuf, pad); /* Put the 64-bit file length in *bits* at the end of the buffer. */ temp = SWAP (ctx->total[0] << 3); memcpy (&ctx->buffer[bytes + pad], &temp, 4); temp = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); memcpy (&ctx->buffer[bytes + pad + 4], &temp, 4); /* Process last bytes. */ md5_process_block (ctx->buffer, bytes + pad + 8, ctx); return md5_read_ctx (ctx, resbuf); } /* Compute MD5 message digest for bytes read from STREAM. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ int md5_stream (stream, resblock) FILE *stream; void *resblock; { /* Important: BLOCKSIZE must be a multiple of 64. */ #define BLOCKSIZE 4096 struct md5_ctx ctx; char buffer[BLOCKSIZE + 72]; size_t sum; /* Initialize the computation context. */ md5_init_ctx (&ctx); /* Iterate over full file contents. */ while (1) { /* We read the file in blocks of BLOCKSIZE bytes. One call of the computation function processes the whole buffer so that with the next round of the loop another block can be read. */ size_t n; sum = 0; /* Read block. Take care for partial reads. */ do { n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); sum += n; } while (sum < BLOCKSIZE && n != 0); if (n == 0 && ferror (stream)) return 1; /* If end of file is reached, end the loop. */ if (n == 0) break; /* Process buffer with BLOCKSIZE bytes. Note that BLOCKSIZE % 64 == 0 */ md5_process_block (buffer, BLOCKSIZE, &ctx); } /* Add the last bytes if necessary. */ if (sum > 0) md5_process_bytes (buffer, sum, &ctx); /* Construct result in desired memory. */ md5_finish_ctx (&ctx, resblock); return 0; } /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ void * md5_buffer (buffer, len, resblock) const char *buffer; size_t len; void *resblock; { struct md5_ctx ctx; /* Initialize the computation context. */ md5_init_ctx (&ctx); /* Process whole buffer but last len % 64 bytes. */ md5_process_bytes (buffer, len, &ctx); /* Put result in desired memory area. */ return md5_finish_ctx (&ctx, resblock); } void md5_process_bytes (buffer, len, ctx) const void *buffer; size_t len; struct md5_ctx *ctx; { /* When we already have some bits in our internal buffer concatenate both inputs first. */ if (ctx->buflen != 0) { size_t left_over = ctx->buflen; size_t add = 128 - left_over > len ? len : 128 - left_over; memcpy (&ctx->buffer[left_over], buffer, add); ctx->buflen += add; if (left_over + add > 64) { md5_process_block (ctx->buffer, (left_over + add) & ~63, ctx); /* The regions in the following copy operation cannot overlap. */ memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], (left_over + add) & 63); ctx->buflen = (left_over + add) & 63; } buffer = (const char *) buffer + add; len -= add; } /* Process available complete blocks. */ if (len > 64) { md5_process_block (buffer, len & ~63, ctx); buffer = (const char *) buffer + (len & ~63); len &= 63; } /* Move remaining bytes in internal buffer. */ if (len > 0) { memcpy (ctx->buffer, buffer, len); ctx->buflen = len; } } /* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). */ /* #define FF(b, c, d) ((b & c) | (~b & d)) */ #define FF(b, c, d) (d ^ (b & (c ^ d))) #define FG(b, c, d) FF (d, b, c) #define FH(b, c, d) (b ^ c ^ d) #define FI(b, c, d) (c ^ (b | ~d)) /* Process LEN bytes of BUFFER, accumulating context into CTX. It is assumed that LEN % 64 == 0. */ void md5_process_block (buffer, len, ctx) const void *buffer; size_t len; struct md5_ctx *ctx; { md5_uint32 correct_words[16]; const md5_uint32 *words = buffer; size_t nwords = len / sizeof (md5_uint32); const md5_uint32 *endp = words + nwords; md5_uint32 A = ctx->A; md5_uint32 B = ctx->B; md5_uint32 C = ctx->C; md5_uint32 D = ctx->D; /* First increment the byte count. RFC 1321 specifies the possible length of the file up to 2^64 bits. Here we only compute the number of bytes. Do a double word increment. */ ctx->total[0] += len; if (ctx->total[0] < len) ++ctx->total[1]; /* Process all bytes in the buffer with 64 bytes in each round of the loop. */ while (words < endp) { md5_uint32 *cwp = correct_words; md5_uint32 A_save = A; md5_uint32 B_save = B; md5_uint32 C_save = C; md5_uint32 D_save = D; /* First round: using the given function, the context and a constant the next context is computed. Because the algorithms processing unit is a 32-bit word and it is determined to work on words in little endian byte order we perhaps have to change the byte order before the computation. To reduce the work for the next steps we store the swapped words in the array CORRECT_WORDS. */ #define OP(a, b, c, d, s, T) \ do \ { \ a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ ++words; \ a = rol (a, s); \ a += b; \ } \ while (0) /* Before we start, one word to the strange constants. They are defined in RFC 1321 as T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64, or perl -e 'foreach(1..64){printf "0x%08x\n", int (4294967296 * abs (sin $_))}' */ /* Round 1. */ OP (A, B, C, D, 7, 0xd76aa478); OP (D, A, B, C, 12, 0xe8c7b756); OP (C, D, A, B, 17, 0x242070db); OP (B, C, D, A, 22, 0xc1bdceee); OP (A, B, C, D, 7, 0xf57c0faf); OP (D, A, B, C, 12, 0x4787c62a); OP (C, D, A, B, 17, 0xa8304613); OP (B, C, D, A, 22, 0xfd469501); OP (A, B, C, D, 7, 0x698098d8); OP (D, A, B, C, 12, 0x8b44f7af); OP (C, D, A, B, 17, 0xffff5bb1); OP (B, C, D, A, 22, 0x895cd7be); OP (A, B, C, D, 7, 0x6b901122); OP (D, A, B, C, 12, 0xfd987193); OP (C, D, A, B, 17, 0xa679438e); OP (B, C, D, A, 22, 0x49b40821); /* For the second to fourth round we have the possibly swapped words in CORRECT_WORDS. Redefine the macro to take an additional first argument specifying the function to use. */ #undef OP #define OP(f, a, b, c, d, k, s, T) \ do \ { \ a += f (b, c, d) + correct_words[k] + T; \ a = rol (a, s); \ a += b; \ } \ while (0) /* Round 2. */ OP (FG, A, B, C, D, 1, 5, 0xf61e2562); OP (FG, D, A, B, C, 6, 9, 0xc040b340); OP (FG, C, D, A, B, 11, 14, 0x265e5a51); OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); OP (FG, A, B, C, D, 5, 5, 0xd62f105d); OP (FG, D, A, B, C, 10, 9, 0x02441453); OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); OP (FG, D, A, B, C, 14, 9, 0xc33707d6); OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); OP (FG, B, C, D, A, 8, 20, 0x455a14ed); OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); OP (FG, C, D, A, B, 7, 14, 0x676f02d9); OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); /* Round 3. */ OP (FH, A, B, C, D, 5, 4, 0xfffa3942); OP (FH, D, A, B, C, 8, 11, 0x8771f681); OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); OP (FH, B, C, D, A, 14, 23, 0xfde5380c); OP (FH, A, B, C, D, 1, 4, 0xa4beea44); OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); OP (FH, B, C, D, A, 6, 23, 0x04881d05); OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); /* Round 4. */ OP (FI, A, B, C, D, 0, 6, 0xf4292244); OP (FI, D, A, B, C, 7, 10, 0x432aff97); OP (FI, C, D, A, B, 14, 15, 0xab9423a7); OP (FI, B, C, D, A, 5, 21, 0xfc93a039); OP (FI, A, B, C, D, 12, 6, 0x655b59c3); OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); OP (FI, C, D, A, B, 10, 15, 0xffeff47d); OP (FI, B, C, D, A, 1, 21, 0x85845dd1); OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); OP (FI, C, D, A, B, 6, 15, 0xa3014314); OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); OP (FI, A, B, C, D, 4, 6, 0xf7537e82); OP (FI, D, A, B, C, 11, 10, 0xbd3af235); OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); OP (FI, B, C, D, A, 9, 21, 0xeb86d391); /* Add the starting values of the context. */ A += A_save; B += B_save; C += C_save; D += D_save; } /* Put checksum in context given as argument. */ ctx->A = A; ctx->B = B; ctx->C = C; ctx->D = D; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/nav_print.c��������������������������������������������������������0000644�0001750�0001750�00000020303�14647725152�016725� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001, 2002, 2003 Håkan Hjort <d95hjort@dtek.chalmers.se> * * Much of the contents in this file is based on VOBDUMP. * * VOBDUMP: a program for examining DVD .VOB filse * * Copyright 1998, 1999 Eric Smith <eric@brouhaha.com> * * VOBDUMP is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. Note that I am not * granting permission to redistribute or modify VOBDUMP under the * terms of any later version of the General Public License. * * This program is distributed in the hope that it will be useful (or * at least amusing), but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <stdio.h> #include <inttypes.h> #include "nav_types.h" #include "nav_print.h" #include "dvdread_internal.h" static void print_time(dvd_time_t *dtime) { const char *rate; CHECK_VALUE((dtime->hour>>4) < 0xa && (dtime->hour&0xf) < 0xa); CHECK_VALUE((dtime->minute>>4) < 0x7 && (dtime->minute&0xf) < 0xa); CHECK_VALUE((dtime->second>>4) < 0x7 && (dtime->second&0xf) < 0xa); CHECK_VALUE((dtime->frame_u&0xf) < 0xa); printf("%02x:%02x:%02x.%02x", dtime->hour, dtime->minute, dtime->second, dtime->frame_u & 0x3f); switch((dtime->frame_u & 0xc0) >> 6) { case 1: rate = "25.00"; break; case 3: rate = "29.97"; break; default: rate = "(please send a bug report)"; break; } printf(" @ %s fps", rate); } static void navPrint_PCI_GI(pci_gi_t *pci_gi) { int i; printf("pci_gi:\n"); printf("nv_pck_lbn 0x%08x\n", pci_gi->nv_pck_lbn); printf("vobu_cat 0x%04x\n", pci_gi->vobu_cat); /* This will break strict aliasing, better avoid as this seems to be useless printf("vobu_uop_ctl 0x%08x\n", *(uint32_t*)&pci_gi->vobu_uop_ctl); */ printf("vobu_s_ptm 0x%08x\n", pci_gi->vobu_s_ptm); printf("vobu_e_ptm 0x%08x\n", pci_gi->vobu_e_ptm); printf("vobu_se_e_ptm 0x%08x\n", pci_gi->vobu_se_e_ptm); printf("e_eltm "); print_time(&pci_gi->e_eltm); printf("\n"); printf("vobu_isrc \""); for(i = 0; i < 32; i++) { char c = pci_gi->vobu_isrc[i]; if((c >= ' ') && (c <= '~')) printf("%c", c); else printf("."); } printf("\"\n"); } static void navPrint_NSML_AGLI(nsml_agli_t *nsml_agli) { int i, j = 0; for(i = 0; i < 9; i++) j |= nsml_agli->nsml_agl_dsta[i]; if(j == 0) return; printf("nsml_agli:\n"); for(i = 0; i < 9; i++) if(nsml_agli->nsml_agl_dsta[i]) printf("nsml_agl_c%d_dsta 0x%08x\n", i + 1, nsml_agli->nsml_agl_dsta[i]); } static void navPrint_HL_GI(hl_gi_t *hl_gi, int *btngr_ns, int *btn_ns) { if((hl_gi->hli_ss & 0x03) == 0) return; printf("hl_gi:\n"); printf("hli_ss 0x%01x\n", hl_gi->hli_ss & 0x03); printf("hli_s_ptm 0x%08x\n", hl_gi->hli_s_ptm); printf("hli_e_ptm 0x%08x\n", hl_gi->hli_e_ptm); printf("btn_se_e_ptm 0x%08x\n", hl_gi->btn_se_e_ptm); *btngr_ns = hl_gi->btngr_ns; printf("btngr_ns %d\n", hl_gi->btngr_ns); printf("btngr%d_dsp_ty 0x%02x\n", 1, hl_gi->btngr1_dsp_ty); printf("btngr%d_dsp_ty 0x%02x\n", 2, hl_gi->btngr2_dsp_ty); printf("btngr%d_dsp_ty 0x%02x\n", 3, hl_gi->btngr3_dsp_ty); printf("btn_ofn %d\n", hl_gi->btn_ofn); *btn_ns = hl_gi->btn_ns; printf("btn_ns %d\n", hl_gi->btn_ns); printf("nsl_btn_ns %d\n", hl_gi->nsl_btn_ns); printf("fosl_btnn %d\n", hl_gi->fosl_btnn); printf("foac_btnn %d\n", hl_gi->foac_btnn); } static void navPrint_BTN_COLIT(btn_colit_t *btn_colit) { int i, j; j = 0; for(i = 0; i < 6; i++) j |= btn_colit->btn_coli[i/2][i&1]; if(j == 0) return; printf("btn_colit:\n"); for(i = 0; i < 3; i++) for(j = 0; j < 2; j++) printf("btn_cqoli %d %s_coli: %08x\n", i, (j == 0) ? "sl" : "ac", btn_colit->btn_coli[i][j]); } static void navPrint_BTNIT(btni_t *btni_table, int btngr_ns, int btn_ns) { int i, j; printf("btnit:\n"); printf("btngr_ns: %i\n", btngr_ns); printf("btn_ns: %i\n", btn_ns); if(btngr_ns == 0) return; for(i = 0; i < btngr_ns; i++) { for(j = 0; j < (36 / btngr_ns); j++) { if(j < btn_ns) { btni_t *btni = &btni_table[(36 / btngr_ns) * i + j]; printf("group %d btni %d: ", i+1, j+1); printf("btn_coln %d, auto_action_mode %d\n", btni->btn_coln, btni->auto_action_mode); printf("coords (%d, %d) .. (%d, %d)\n", btni->x_start, btni->y_start, btni->x_end, btni->y_end); printf("up %d, ", btni->up); printf("down %d, ", btni->down); printf("left %d, ", btni->left); printf("right %d\n", btni->right); /* ifoPrint_COMMAND(&btni->cmd); */ printf("\n"); } } } } static void navPrint_HLI(hli_t *hli) { int btngr_ns = 0, btn_ns = 0; printf("hli:\n"); navPrint_HL_GI(&hli->hl_gi, & btngr_ns, & btn_ns); navPrint_BTN_COLIT(&hli->btn_colit); navPrint_BTNIT(hli->btnit, btngr_ns, btn_ns); } void navPrint_PCI(pci_t *pci) { printf("pci packet:\n"); navPrint_PCI_GI(&pci->pci_gi); navPrint_NSML_AGLI(&pci->nsml_agli); navPrint_HLI(&pci->hli); } static void navPrint_DSI_GI(dsi_gi_t *dsi_gi) { printf("dsi_gi:\n"); printf("nv_pck_scr 0x%08x\n", dsi_gi->nv_pck_scr); printf("nv_pck_lbn 0x%08x\n", dsi_gi->nv_pck_lbn ); printf("vobu_ea 0x%08x\n", dsi_gi->vobu_ea); printf("vobu_1stref_ea 0x%08x\n", dsi_gi->vobu_1stref_ea); printf("vobu_2ndref_ea 0x%08x\n", dsi_gi->vobu_2ndref_ea); printf("vobu_3rdref_ea 0x%08x\n", dsi_gi->vobu_3rdref_ea); printf("vobu_vob_idn 0x%04x\n", dsi_gi->vobu_vob_idn); printf("vobu_c_idn 0x%02x\n", dsi_gi->vobu_c_idn); printf("c_eltm "); print_time(&dsi_gi->c_eltm); printf("\n"); } static void navPrint_SML_PBI(sml_pbi_t *sml_pbi) { printf("sml_pbi:\n"); printf("category 0x%04x\n", sml_pbi->category); if(sml_pbi->category & 0x8000) printf("VOBU is in preunit\n"); if(sml_pbi->category & 0x4000) printf("VOBU is in ILVU\n"); if(sml_pbi->category & 0x2000) printf("VOBU at the beginning of ILVU\n"); if(sml_pbi->category & 0x1000) printf("VOBU at end of PREU of ILVU\n"); printf("ilvu_ea 0x%08x\n", sml_pbi->ilvu_ea); printf("nxt_ilvu_sa 0x%08x\n", sml_pbi->ilvu_sa); printf("nxt_ilvu_size 0x%04x\n", sml_pbi->size); printf("vob_v_s_s_ptm 0x%08x\n", sml_pbi->vob_v_s_s_ptm); printf("vob_v_e_e_ptm 0x%08x\n", sml_pbi->vob_v_e_e_ptm); /* $$$ more code needed here */ } static void navPrint_SML_AGLI(sml_agli_t *sml_agli) { int i; printf("sml_agli:\n"); for(i = 0; i < 9; i++) { printf("agl_c%d address: 0x%08x size 0x%04x\n", i, sml_agli->data[i].address, sml_agli->data[i].size); } } static void navPrint_VOBU_SRI(vobu_sri_t *vobu_sri) { int i; int stime[19] = { 240, 120, 60, 20, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}; printf("vobu_sri:\n"); printf("Next VOBU with Video %08x\n", vobu_sri->next_video); for(i = 0; i < 19; i++) { printf("%3.1f %08x ", stime[i]/2.0, vobu_sri->fwda[i]); } printf("\n"); printf("Next VOBU %08x\n", vobu_sri->next_vobu); printf("--\n"); printf("Prev VOBU %08x\n", vobu_sri->prev_vobu); for(i = 0; i < 19; i++) { printf("%3.1f %08x ", stime[18 - i]/2.0, vobu_sri->bwda[i]); } printf("\n"); printf("Prev VOBU with Video %08x\n", vobu_sri->prev_video); } static void navPrint_SYNCI(synci_t *synci) { int i; printf("synci:\n"); /* $$$ more code needed here */ for(i = 0; i < 8; i++) printf("%04x ", synci->a_synca[i]); for(i = 0; i < 32; i++) printf("%08x ", synci->sp_synca[i]); } void navPrint_DSI(dsi_t *dsi) { printf("dsi packet:\n"); navPrint_DSI_GI(&dsi->dsi_gi); navPrint_SML_PBI(&dsi->sml_pbi); navPrint_SML_AGLI(&dsi->sml_agli); navPrint_VOBU_SRI(&dsi->vobu_sri); navPrint_SYNCI(&dsi->synci); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/searching.c��������������������������������������������������������0000644�0001750�0001750�00000037710�14647725152�016702� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <assert.h> #include "dvdnav_internal.h" #include "dvdnav.h" /* #define LOG_DEBUG */ /* Searching API calls */ /* Scan the ADMAP for a particular block number. */ /* Return placed in vobu. */ /* Returns error status */ /* FIXME: Maybe need to handle seeking outside current cell. */ static dvdnav_status_t dvdnav_scan_admap(dvdnav_t *this, int32_t domain, uint32_t seekto_block, uint32_t *vobu) { vobu_admap_t *admap = NULL; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: Seeking to target %u ...\n", seekto_block); #endif *vobu = -1; /* Search through the VOBU_ADMAP for the nearest VOBU * to the target block */ switch(domain) { case FP_DOMAIN: case VMGM_DOMAIN: admap = this->vm->vmgi->menu_vobu_admap; break; case VTSM_DOMAIN: admap = this->vm->vtsi->menu_vobu_admap; break; case VTS_DOMAIN: admap = this->vm->vtsi->vts_vobu_admap; break; default: fprintf(MSG_OUT, "libdvdnav: Error: Unknown domain for seeking.\n"); } if(admap) { uint32_t address = 0; uint32_t vobu_start, next_vobu; int32_t found = 0; /* Search through ADMAP for best sector */ vobu_start = SRI_END_OF_CELL; /* FIXME: Implement a faster search algorithm */ while((!found) && ((address<<2) < admap->last_byte)) { next_vobu = admap->vobu_start_sectors[address]; /* fprintf(MSG_OUT, "libdvdnav: Found block %u\n", next_vobu); */ if(vobu_start <= seekto_block && next_vobu > seekto_block) { found = 1; } else { vobu_start = next_vobu; } address ++; } if(found) { *vobu = vobu_start; return DVDNAV_STATUS_OK; } else { fprintf(MSG_OUT, "libdvdnav: Could not locate block\n"); return DVDNAV_STATUS_ERR; } } fprintf(MSG_OUT, "libdvdnav: admap not located\n"); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_time_search(dvdnav_t *this, uint64_t time) { uint64_t target = time; uint64_t length = 0; uint32_t first_cell_nr, last_cell_nr, cell_nr; int32_t found; cell_playback_t *cell; dvd_state_t *state; if(this->position_current.still != 0) { printerr("Cannot seek in a still frame."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); state = &(this->vm->state); if(!state->pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if (this->pgc_based) { first_cell_nr = 1; last_cell_nr = state->pgc->nr_of_cells; } else { /* Find start cell of program. */ first_cell_nr = state->pgc->program_map[state->pgN-1]; /* Find end cell of program */ if(state->pgN < state->pgc->nr_of_programs) last_cell_nr = state->pgc->program_map[state->pgN] - 1; else last_cell_nr = state->pgc->nr_of_cells; } found = 0; for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { cell = &(state->pgc->cell_playback[cell_nr-1]); length = dvdnav_convert_time(&cell->playback_time); if (target >= length) { target -= length; } else { /* FIXME: there must be a better way than interpolation */ target = target * (cell->last_sector - cell->first_sector + 1) / length; target += cell->first_sector; found = 1; break; } } if(found) { int32_t vobu; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n", cell_nr, first_cell_nr, last_cell_nr); #endif if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) { int32_t start = state->pgc->cell_playback[cell_nr-1].first_sector; if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) { #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , state->cellN, state->blockN, target, vobu, start); #endif this->vm->hop_channel += HOP_SEEK; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } } } fprintf(MSG_OUT, "libdvdnav: Error when seeking\n"); printerr("Error when seeking."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_sector_search(dvdnav_t *this, uint64_t offset, int32_t origin) { uint32_t target = 0; uint32_t length = 0; uint32_t first_cell_nr, last_cell_nr, cell_nr; int32_t found; cell_playback_t *cell; dvd_state_t *state; dvdnav_status_t result; if(this->position_current.still != 0) { printerr("Cannot seek in a still frame."); return DVDNAV_STATUS_ERR; } result = dvdnav_get_position(this, &target, &length); if(!result) { return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); state = &(this->vm->state); if(!state->pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: seeking to offset=%lu pos=%u length=%u\n", offset, target, length); fprintf(MSG_OUT, "libdvdnav: Before cellN=%u blockN=%u\n", state->cellN, state->blockN); #endif switch(origin) { case SEEK_SET: if(offset > length) { printerr("Request to seek behind end."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } target = offset; break; case SEEK_CUR: if(target + offset > length) { printerr("Request to seek behind end."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } target += offset; break; case SEEK_END: if (length < offset) { printerr("Request to seek before start."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } target = length - offset; break; default: /* Error occured */ printerr("Illegal seek mode."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if (this->pgc_based) { first_cell_nr = 1; last_cell_nr = state->pgc->nr_of_cells; } else { /* Find start cell of program. */ first_cell_nr = state->pgc->program_map[state->pgN-1]; /* Find end cell of program */ if(state->pgN < state->pgc->nr_of_programs) last_cell_nr = state->pgc->program_map[state->pgN] - 1; else last_cell_nr = state->pgc->nr_of_cells; } found = 0; for(cell_nr = first_cell_nr; (cell_nr <= last_cell_nr) && !found; cell_nr ++) { cell = &(state->pgc->cell_playback[cell_nr-1]); length = cell->last_sector - cell->first_sector + 1; if (target >= length) { target -= length; } else { /* convert the target sector from Cell-relative to absolute physical sector */ target += cell->first_sector; found = 1; break; } } if(found) { int32_t vobu; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: Seeking to cell %i from choice of %i to %i\n", cell_nr, first_cell_nr, last_cell_nr); #endif if (dvdnav_scan_admap(this, state->domain, target, &vobu) == DVDNAV_STATUS_OK) { int32_t start = state->pgc->cell_playback[cell_nr-1].first_sector; if (vm_jump_cell_block(this->vm, cell_nr, vobu - start)) { #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: After cellN=%u blockN=%u target=%x vobu=%x start=%x\n" , state->cellN, state->blockN, target, vobu, start); #endif this->vm->hop_channel += HOP_SEEK; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } } } fprintf(MSG_OUT, "libdvdnav: Error when seeking\n"); fprintf(MSG_OUT, "libdvdnav: FIXME: Implement seeking to location %u\n", target); printerr("Error when seeking."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_part_search(dvdnav_t *this, int32_t part) { int32_t title, old_part; if (dvdnav_current_title_info(this, &title, &old_part) == DVDNAV_STATUS_OK) return dvdnav_part_play(this, title, part); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_prev_pg_search(dvdnav_t *this) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); if(!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: previous chapter\n"); #endif if (!vm_jump_prev_pg(this->vm)) { fprintf(MSG_OUT, "libdvdnav: previous chapter failed.\n"); printerr("Skip to previous chapter failed."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } this->position_current.still = 0; this->vm->hop_channel++; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: previous chapter done\n"); #endif pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_top_pg_search(dvdnav_t *this) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); if(!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: top chapter\n"); #endif if (!vm_jump_top_pg(this->vm)) { fprintf(MSG_OUT, "libdvdnav: top chapter failed.\n"); printerr("Skip to top chapter failed."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } this->position_current.still = 0; this->vm->hop_channel++; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: top chapter done\n"); #endif pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_next_pg_search(dvdnav_t *this) { vm_t *try_vm; if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); if(!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: next chapter\n"); #endif /* make a copy of current VM and try to navigate the copy to the next PG */ try_vm = vm_new_copy(this->vm); if (!vm_jump_next_pg(try_vm) || try_vm->stopped) { vm_free_copy(try_vm); /* next_pg failed, try to jump at least to the next cell */ try_vm = vm_new_copy(this->vm); vm_get_next_cell(try_vm); if (try_vm->stopped) { vm_free_copy(try_vm); fprintf(MSG_OUT, "libdvdnav: next chapter failed.\n"); printerr("Skip to next chapter failed."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } } /* merge changes on success */ vm_merge(this->vm, try_vm); vm_free_copy(try_vm); this->position_current.still = 0; this->vm->hop_channel++; #ifdef LOG_DEBUG fprintf(MSG_OUT, "libdvdnav: next chapter done\n"); #endif pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_menu_call(dvdnav_t *this, DVDMenuID_t menu) { vm_t *try_vm; if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); if(!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* make a copy of current VM and try to navigate the copy to the menu */ try_vm = vm_new_copy(this->vm); if ( (menu == DVD_MENU_Escape) && (this->vm->state.domain != VTS_DOMAIN)) { /* Try resume */ if (vm_jump_resume(try_vm) && !try_vm->stopped) { /* merge changes on success */ vm_merge(this->vm, try_vm); vm_free_copy(try_vm); this->position_current.still = 0; this->vm->hop_channel++; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } } if (menu == DVD_MENU_Escape) menu = DVD_MENU_Root; if (vm_jump_menu(try_vm, menu) && !try_vm->stopped) { /* merge changes on success */ vm_merge(this->vm, try_vm); vm_free_copy(try_vm); this->position_current.still = 0; this->vm->hop_channel++; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } else { vm_free_copy(try_vm); printerr("No such menu or menu not reachable."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } } dvdnav_status_t dvdnav_get_position(dvdnav_t *this, uint32_t *pos, uint32_t *len) { uint32_t cur_sector; int32_t cell_nr, first_cell_nr, last_cell_nr; cell_playback_t *cell; dvd_state_t *state; if(!this || !pos || !len) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } if(!this->started) { printerr("Virtual DVD machine not started."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); state = &(this->vm->state); if(!state->pgc || this->vm->stopped) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if (this->position_current.hop_channel != this->vm->hop_channel || this->position_current.domain != state->domain || this->position_current.vts != state->vtsN || this->position_current.cell_restart != state->cell_restart) { printerr("New position not yet determined."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } /* Get current sector */ cur_sector = this->vobu.vobu_start + this->vobu.blockN; if (this->pgc_based) { first_cell_nr = 1; last_cell_nr = state->pgc->nr_of_cells; } else { /* Find start cell of program. */ first_cell_nr = state->pgc->program_map[state->pgN-1]; /* Find end cell of program */ if(state->pgN < state->pgc->nr_of_programs) last_cell_nr = state->pgc->program_map[state->pgN] - 1; else last_cell_nr = state->pgc->nr_of_cells; } *pos = -1; *len = 0; for (cell_nr = first_cell_nr; cell_nr <= last_cell_nr; cell_nr++) { cell = &(state->pgc->cell_playback[cell_nr-1]); if (cell_nr == state->cellN) { /* the current sector is in this cell, * pos is length of PG up to here + sector's offset in this cell */ *pos = *len + cur_sector - cell->first_sector; } *len += cell->last_sector - cell->first_sector + 1; } assert((signed)*pos != -1); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_get_position_in_title(dvdnav_t *this, uint32_t *pos, uint32_t *len) { uint32_t cur_sector; uint32_t first_cell_nr; uint32_t last_cell_nr; cell_playback_t *first_cell; cell_playback_t *last_cell; dvd_state_t *state; if(!this || !pos || !len) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } state = &(this->vm->state); if(!state->pgc) { printerr("No current PGC."); return DVDNAV_STATUS_ERR; } /* Get current sector */ cur_sector = this->vobu.vobu_start + this->vobu.blockN; /* Now find first and last cells in title. */ first_cell_nr = state->pgc->program_map[0]; first_cell = &(state->pgc->cell_playback[first_cell_nr-1]); last_cell_nr = state->pgc->nr_of_cells; last_cell = &(state->pgc->cell_playback[last_cell_nr-1]); *pos = cur_sector - first_cell->first_sector; *len = last_cell->last_sector - first_cell->first_sector; return DVDNAV_STATUS_OK; } ��������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/md5.h��������������������������������������������������������������0000644�0001750�0001750�00000012510�14647725152�015420� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* md5.h - Declaration of functions and data types used for MD5 sum computing library functions. Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc. NOTE: The canonical source of this file is maintained with the GNU C Library. Bugs can be reported to bug-glibc@prep.ai.mit.edu. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef _MD5_H #define _MD5_H 1 #include <stdio.h> #if defined HAVE_LIMITS_H || _LIBC # include <limits.h> #endif /* The following contortions are an attempt to use the C preprocessor to determine an unsigned integral type that is 32 bits wide. An alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but doing that would require that the configure script compile and *run* the resulting executable. Locally running cross-compiled executables is usually not possible. */ #ifdef _LIBC # include <sys/types.h> typedef u_int32_t md5_uint32; #else # if defined __STDC__ && __STDC__ # define UINT_MAX_32_BITS 4294967295U # else # define UINT_MAX_32_BITS 0xFFFFFFFF # endif /* If UINT_MAX isn't defined, assume it's a 32-bit type. This should be valid for all systems GNU cares about because that doesn't include 16-bit systems, and only modern systems (that certainly have <limits.h>) have 64+-bit integral types. */ # ifndef UINT_MAX # define UINT_MAX UINT_MAX_32_BITS # endif # if UINT_MAX == UINT_MAX_32_BITS typedef unsigned int md5_uint32; # else # if USHRT_MAX == UINT_MAX_32_BITS typedef unsigned short md5_uint32; # else # if ULONG_MAX == UINT_MAX_32_BITS typedef unsigned long md5_uint32; # else /* The following line is intended to evoke an error. Using #error is not portable enough. */ "Cannot determine unsigned 32-bit data type." # endif # endif # endif #endif #undef __P #if defined (__STDC__) && __STDC__ #define __P(x) x #else #define __P(x) () #endif /* Structure to save state of computation between the single steps. */ struct md5_ctx { md5_uint32 A; md5_uint32 B; md5_uint32 C; md5_uint32 D; md5_uint32 total[2]; md5_uint32 buflen; char buffer[128]; }; /* * The following three functions are build up the low level used in * the functions `md5_stream' and `md5_buffer'. */ /* Initialize structure containing state of computation. (RFC 1321, 3.3: Step 3) */ extern void md5_init_ctx __P ((struct md5_ctx *ctx)); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is necessary that LEN is a multiple of 64!!! */ extern void md5_process_block __P ((const void *buffer, size_t len, struct md5_ctx *ctx)); /* Starting with the result of former calls of this function (or the initialization function update the context for the next LEN bytes starting at BUFFER. It is NOT required that LEN is a multiple of 64. */ extern void md5_process_bytes __P ((const void *buffer, size_t len, struct md5_ctx *ctx)); /* Process the remaining bytes in the buffer and put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. IMPORTANT: On some systems it is required that RESBUF be correctly aligned for a 32 bits value. */ extern void *md5_finish_ctx __P ((struct md5_ctx *ctx, void *resbuf)); /* Put result from CTX in first 16 bytes following RESBUF. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. IMPORTANT: On some systems it is required that RESBUF is correctly aligned for a 32 bits value. */ extern void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf)); /* Compute MD5 message digest for bytes read from STREAM. The resulting message digest number will be written into the 16 bytes beginning at RESBLOCK. */ extern int md5_stream __P ((FILE *stream, void *resblock)); /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The result is always in little endian byte order, so that a byte-wise output yields to the wanted ASCII representation of the message digest. */ extern void *md5_buffer __P ((const char *buffer, size_t len, void *resblock)); /* The following is from gnupg-1.0.2's cipher/bithelp.h. */ /* Rotate a 32 bit integer by n bytes */ #if defined __GNUC__ && defined __i386__ static inline md5_uint32 rol(md5_uint32 x, int n) { __asm__("roll %%cl,%0" :"=r" (x) :"0" (x),"c" (n)); return x; } #else # define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) ) #endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvd_types.h��������������������������������������������������������0000644�0001750�0001750�00000020322�14647725152�016734� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001 Björn Englund, Håkan Hjort * * This file is part of libdvdnav, a DVD navigation library. It is a modified * file originally part of the Ogle DVD player project. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * Various useful structs and enums for DVDs. */ #ifndef DVD_H_INCLUDED #define DVD_H_INCLUDED #include <inttypes.h> /* * DVD Menu ID * (see dvdnav_menu_call()) */ typedef enum { /* When used in VTS domain, DVD_MENU_Escape behaves like DVD_MENU_Root, * but from within a menu domain, DVD_MENU_Escape resumes playback. */ DVD_MENU_Escape = 0, DVD_MENU_Title = 2, DVD_MENU_Root = 3, DVD_MENU_Subpicture = 4, DVD_MENU_Audio = 5, DVD_MENU_Angle = 6, DVD_MENU_Part = 7 } DVDMenuID_t; /* * Structure containing info on highlight areas * (see dvdnav_get_highlight_area()) */ typedef struct { uint32_t palette; /* The CLUT entries for the highlight palette (4-bits per entry -> 4 entries) */ uint16_t sx,sy,ex,ey; /* The start/end x,y positions */ uint32_t pts; /* Highlight PTS to match with SPU */ /* button number for the SPU decoder/overlaying engine */ uint32_t buttonN; } dvdnav_highlight_area_t; /* the following types are currently unused */ #if 0 /* Domain */ typedef enum { DVD_DOMAIN_FirstPlay, /* First Play Domain */ DVD_DOMAIN_VMG, /* Video Manager Domain */ DVD_DOMAIN_VTSMenu, /* Video Title Set Menu Domain */ DVD_DOMAIN_VTSTitle, /* Video Title Set Domain */ DVD_DOMAIN_Stop /* Stop Domain */ } DVDDomain_t; /* User operation permissions */ typedef enum { UOP_FLAG_TitleOrTimePlay = 0x00000001, UOP_FLAG_ChapterSearchOrPlay = 0x00000002, UOP_FLAG_TitlePlay = 0x00000004, UOP_FLAG_Stop = 0x00000008, UOP_FLAG_GoUp = 0x00000010, UOP_FLAG_TimeOrChapterSearch = 0x00000020, UOP_FLAG_PrevOrTopPGSearch = 0x00000040, UOP_FLAG_NextPGSearch = 0x00000080, UOP_FLAG_ForwardScan = 0x00000100, UOP_FLAG_BackwardScan = 0x00000200, UOP_FLAG_TitleMenuCall = 0x00000400, UOP_FLAG_RootMenuCall = 0x00000800, UOP_FLAG_SubPicMenuCall = 0x00001000, UOP_FLAG_AudioMenuCall = 0x00002000, UOP_FLAG_AngleMenuCall = 0x00004000, UOP_FLAG_ChapterMenuCall = 0x00008000, UOP_FLAG_Resume = 0x00010000, UOP_FLAG_ButtonSelectOrActivate = 0x00020000, UOP_FLAG_StillOff = 0x00040000, UOP_FLAG_PauseOn = 0x00080000, UOP_FLAG_AudioStreamChange = 0x00100000, UOP_FLAG_SubPicStreamChange = 0x00200000, UOP_FLAG_AngleChange = 0x00400000, UOP_FLAG_KaraokeAudioPresModeChange = 0x00800000, UOP_FLAG_VideoPresModeChange = 0x01000000 } DVDUOP_t; /* Parental Level */ typedef enum { DVD_PARENTAL_LEVEL_1 = 1, DVD_PARENTAL_LEVEL_2 = 2, DVD_PARENTAL_LEVEL_3 = 3, DVD_PARENTAL_LEVEL_4 = 4, DVD_PARENTAL_LEVEL_5 = 5, DVD_PARENTAL_LEVEL_6 = 6, DVD_PARENTAL_LEVEL_7 = 7, DVD_PARENTAL_LEVEL_8 = 8, DVD_PARENTAL_LEVEL_None = 15 } DVDParentalLevel_t; /* Language ID (ISO-639 language code) */ typedef uint16_t DVDLangID_t; /* Country ID (ISO-3166 country code) */ typedef uint16_t DVDCountryID_t; /* Register */ typedef uint16_t DVDRegister_t; typedef enum { DVDFalse = 0, DVDTrue = 1 } DVDBool_t; typedef DVDRegister_t DVDGPRMArray_t[16]; typedef DVDRegister_t DVDSPRMArray_t[24]; /* Navigation */ typedef int DVDStream_t; typedef int DVDPTT_t; typedef int DVDTitle_t; /* Angle number (1-9 or default?) */ typedef int DVDAngle_t; /* Timecode */ typedef struct { uint8_t Hours; uint8_t Minutes; uint8_t Seconds; uint8_t Frames; } DVDTimecode_t; /* Subpicture stream number (0-31,62,63) */ typedef int DVDSubpictureStream_t; /* Audio stream number (0-7, 15(none)) */ typedef int DVDAudioStream_t; /* The audio application mode */ typedef enum { DVD_AUDIO_APP_MODE_None = 0, DVD_AUDIO_APP_MODE_Karaoke = 1, DVD_AUDIO_APP_MODE_Surround = 2, DVD_AUDIO_APP_MODE_Other = 3 } DVDAudioAppMode_t; /* The audio format */ typedef enum { DVD_AUDIO_FORMAT_AC3 = 0, DVD_AUDIO_FORMAT_MPEG1 = 1, DVD_AUDIO_FORMAT_MPEG1_DRC = 2, DVD_AUDIO_FORMAT_MPEG2 = 3, DVD_AUDIO_FORMAT_MPEG2_DRC = 4, DVD_AUDIO_FORMAT_LPCM = 5, DVD_AUDIO_FORMAT_DTS = 6, DVD_AUDIO_FORMAT_SDDS = 7, DVD_AUDIO_FORMAT_Other = 8 } DVDAudioFormat_t; /* Audio language extension */ typedef enum { DVD_AUDIO_LANG_EXT_NotSpecified = 0, DVD_AUDIO_LANG_EXT_NormalCaptions = 1, DVD_AUDIO_LANG_EXT_VisuallyImpaired = 2, DVD_AUDIO_LANG_EXT_DirectorsComments1 = 3, DVD_AUDIO_LANG_EXT_DirectorsComments2 = 4 } DVDAudioLangExt_t; /* Subpicture language extension */ typedef enum { DVD_SUBPICTURE_LANG_EXT_NotSpecified = 0, DVD_SUBPICTURE_LANG_EXT_NormalCaptions = 1, DVD_SUBPICTURE_LANG_EXT_BigCaptions = 2, DVD_SUBPICTURE_LANG_EXT_ChildrensCaptions = 3, DVD_SUBPICTURE_LANG_EXT_NormalCC = 5, DVD_SUBPICTURE_LANG_EXT_BigCC = 6, DVD_SUBPICTURE_LANG_EXT_ChildrensCC = 7, DVD_SUBPICTURE_LANG_EXT_Forced = 9, DVD_SUBPICTURE_LANG_EXT_NormalDirectorsComments = 13, DVD_SUBPICTURE_LANG_EXT_BigDirectorsComments = 14, DVD_SUBPICTURE_LANG_EXT_ChildrensDirectorsComments = 15, } DVDSubpictureLangExt_t; /* Karaoke Downmix mode */ typedef enum { DVD_KARAOKE_DOWNMIX_0to0 = 0x0001, DVD_KARAOKE_DOWNMIX_1to0 = 0x0002, DVD_KARAOKE_DOWNMIX_2to0 = 0x0004, DVD_KARAOKE_DOWNMIX_3to0 = 0x0008, DVD_KARAOKE_DOWNMIX_4to0 = 0x0010, DVD_KARAOKE_DOWNMIX_Lto0 = 0x0020, DVD_KARAOKE_DOWNMIX_Rto0 = 0x0040, DVD_KARAOKE_DOWNMIX_0to1 = 0x0100, DVD_KARAOKE_DOWNMIX_1to1 = 0x0200, DVD_KARAOKE_DOWNMIX_2to1 = 0x0400, DVD_KARAOKE_DOWNMIX_3to1 = 0x0800, DVD_KARAOKE_DOWNMIX_4to1 = 0x1000, DVD_KARAOKE_DOWNMIX_Lto1 = 0x2000, DVD_KARAOKE_DOWNMIX_Rto1 = 0x4000 } DVDKaraokeDownmix_t; typedef int DVDKaraokeDownmixMask_t; /* Display mode */ typedef enum { DVD_DISPLAY_MODE_ContentDefault = 0, DVD_DISPLAY_MODE_16x9 = 1, DVD_DISPLAY_MODE_4x3PanScan = 2, DVD_DISPLAY_MODE_4x3Letterboxed = 3 } DVDDisplayMode_t; /* Audio attributes */ typedef struct { DVDAudioAppMode_t AppMode; DVDAudioFormat_t AudioFormat; DVDLangID_t Language; DVDAudioLangExt_t LanguageExtension; DVDBool_t HasMultichannelInfo; DVDAudioSampleFreq_t SampleFrequency; DVDAudioSampleQuant_t SampleQuantization; DVDChannelNumber_t NumberOfChannels; } DVDAudioAttributes_t; typedef int DVDAudioSampleFreq_t; typedef int DVDAudioSampleQuant_t; typedef int DVDChannelNumber_t; /* Subpicture attributes */ typedef enum { DVD_SUBPICTURE_TYPE_NotSpecified = 0, DVD_SUBPICTURE_TYPE_Language = 1, DVD_SUBPICTURE_TYPE_Other = 2 } DVDSubpictureType_t; typedef enum { DVD_SUBPICTURE_CODING_RunLength = 0, DVD_SUBPICTURE_CODING_Extended = 1, DVD_SUBPICTURE_CODING_Other = 2 } DVDSubpictureCoding_t; typedef struct { DVDSubpictureType_t Type; DVDSubpictureCoding_t CodingMode; DVDLangID_t Language; DVDSubpictureLangExt_t LanguageExtension; } DVDSubpictureAttributes_t; /* Video attributes */ typedef struct { DVDBool_t PanscanPermitted; DVDBool_t LetterboxPermitted; int AspectX; int AspectY; int FrameRate; int FrameHeight; DVDVideoCompression_t Compression; DVDBool_t Line21Field1InGop; DVDBool_t Line21Field2InGop; int more_to_come; } DVDVideoAttributes_t; typedef int DVDVideoCompression_t; #endif #endif /* DVD_H_INCLUDED */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/navigation.c�������������������������������������������������������0000644�0001750�0001750�00000014315�14647725152�017072� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "dvdnav_internal.h" /* Navigation API calls */ dvdnav_status_t dvdnav_still_skip(dvdnav_t *this) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } this->position_current.still = 0; this->skip_still = 1; this->sync_wait = 0; this->sync_wait_skip = 1; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_wait_skip(dvdnav_t *this) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } this->sync_wait = 0; this->sync_wait_skip = 1; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_get_number_of_titles(dvdnav_t *this, int32_t *titles) { if(!this || !titles) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } if (!this->vm->vmgi) { printerr("Bad VM state."); return DVDNAV_STATUS_ERR; } (*titles) = vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_get_number_of_parts(dvdnav_t *this, int32_t title, int32_t *parts) { if(!this || !parts) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } if (!this->vm->vmgi) { printerr("Bad VM state."); return DVDNAV_STATUS_ERR; } if ((title < 1) || (title > vm_get_vmgi(this->vm)->tt_srpt->nr_of_srpts) ) { printerr("Passed a title number out of range."); return DVDNAV_STATUS_ERR; } (*parts) = vm_get_vmgi(this->vm)->tt_srpt->title[title-1].nr_of_ptts; return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_current_title_info(dvdnav_t *this, int32_t *title, int32_t *part) { int32_t retval; if(!this || !title || !part) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->vtsi || !this->vm->vmgi) { printerr("Bad VM state."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if (!this->started) { printerr("Virtual DVD machine not started."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if ( (this->vm->state.domain == VTSM_DOMAIN) || (this->vm->state.domain == VMGM_DOMAIN) ) { /* Get current Menu ID: into *part. */ vm_get_current_menu(this->vm, part); if (*part > -1) { *title = 0; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } } if (this->vm->state.domain == VTS_DOMAIN) { retval = vm_get_current_title_part(this->vm, title, part); pthread_mutex_unlock(&this->vm_lock); return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR; } printerr("Not in a title or menu."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_title_play(dvdnav_t *this, int32_t title) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } return dvdnav_part_play(this, title, 1); } dvdnav_status_t dvdnav_part_play(dvdnav_t *this, int32_t title, int32_t part) { int32_t retval; if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); if (!this->vm->vmgi) { printerr("Bad VM state."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if (!this->started) { /* don't report an error but be nice */ vm_start(this->vm); this->started = 1; } if (!this->vm->state.pgc) { printerr("No current PGC."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if((title < 1) || (title > this->vm->vmgi->tt_srpt->nr_of_srpts)) { printerr("Title out of range."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } if((part < 1) || (part > this->vm->vmgi->tt_srpt->title[title-1].nr_of_ptts)) { printerr("Part out of range."); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_ERR; } retval = vm_jump_title_part(this->vm, title, part); if (retval) this->vm->hop_channel++; pthread_mutex_unlock(&this->vm_lock); return retval ? DVDNAV_STATUS_OK : DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_part_play_auto_stop(dvdnav_t *this, int32_t title, int32_t part, int32_t parts_to_play) { /* FIXME: Implement auto-stop */ (void)parts_to_play; if (dvdnav_part_play(this, title, part) == DVDNAV_STATUS_OK) printerr("Not implemented yet."); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_time_play(dvdnav_t *this, int32_t title, uint64_t time) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } /* FIXME: Implement */ (void)title; (void)time; printerr("Not implemented yet."); return DVDNAV_STATUS_ERR; } dvdnav_status_t dvdnav_stop(dvdnav_t *this) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } pthread_mutex_lock(&this->vm_lock); this->vm->stopped = 1; pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } dvdnav_status_t dvdnav_go_up(dvdnav_t *this) { if(!this) { printerr("Passed a NULL pointer."); return DVDNAV_STATUS_ERR; } /* A nice easy function... delegate to the VM */ pthread_mutex_lock(&this->vm_lock); vm_jump_up(this->vm); pthread_mutex_unlock(&this->vm_lock); return DVDNAV_STATUS_OK; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/nav_print.h��������������������������������������������������������0000644�0001750�0001750�00000002621�14647725152�016735� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef NAV_PRINT_H_INCLUDED #define NAV_PRINT_H_INCLUDED /* * Copyright (C) 2001, 2002 Billy Biggs <vektor@dumbterm.net>, * Håkan Hjort <d95hjort@dtek.chalmers.se> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "nav_types.h" /** * Pretty printing of the NAV packets, PCI and DSI structs. */ #ifdef __cplusplus extern "C" { #endif /** * Prints information contained in the PCI to stdout. * * @param pci Pointer to the PCI data structure to be printed. */ void navPrint_PCI(pci_t *); /** * Prints information contained in the DSI to stdout. * * @param dsi Pointer to the DSI data structure to be printed. */ void navPrint_DSI(dsi_t *); #ifdef __cplusplus }; #endif #endif /* NAV_PRINT_H_INCLUDED */ ���������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/vm.c���������������������������������������������������������������0000644�0001750�0001750�00000156260�14647725152�015363� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000, 2001 Håkan Hjort * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net> * 2002-2004 the dvdnav project * * This file is part of libdvdnav, a DVD navigation library. It is modified * from a file originally part of the Ogle DVD player. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <inttypes.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include "ifo_types.h" #include "ifo_read.h" #include "dvdnav_internal.h" #ifdef _MSC_VER #include <io.h> /* read() */ #endif /* _MSC_VER */ /* #define STRICT */ /* Local prototypes */ /* get_XYZ returns a value. * set_XYZ sets state using passed parameters. * returns success/failure. */ /* Play */ static link_t play_PGC(vm_t *vm); static link_t play_PGC_PG(vm_t *vm, int pgN); static link_t play_PGC_post(vm_t *vm); static link_t play_PG(vm_t *vm); static link_t play_Cell(vm_t *vm); static link_t play_Cell_post(vm_t *vm); /* Process link - returns 1 if a hop has been performed */ static int process_command(vm_t *vm,link_t link_values); /* Set */ static int set_TT(vm_t *vm, int tt); static int set_PTT(vm_t *vm, int tt, int ptt); static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn); static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part); static int set_FP_PGC(vm_t *vm); static int set_MENU(vm_t *vm, int menu); static int set_PGCN(vm_t *vm, int pgcN); static int set_PGN(vm_t *vm); /* Set PGN based on (vm->state).CellN */ static void set_RSMinfo(vm_t *vm, int cellN, int blockN); /* Get */ static int get_TT(vm_t *vm, int vtsN, int vts_ttn); static int get_ID(vm_t *vm, int id); static int get_PGCN(vm_t *vm); static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang); static pgcit_t* get_PGCIT(vm_t *vm); /* Helper functions */ #ifdef TRACE static void vm_print_current_domain_state(vm_t *vm) { switch((vm->state).domain) { case VTS_DOMAIN: fprintf(MSG_OUT, "libdvdnav: Video Title Domain: -\n"); break; case VTSM_DOMAIN: fprintf(MSG_OUT, "libdvdnav: Video Title Menu Domain: -\n"); break; case VMGM_DOMAIN: fprintf(MSG_OUT, "libdvdnav: Video Manager Menu Domain: -\n"); break; case FP_DOMAIN: fprintf(MSG_OUT, "libdvdnav: First Play Domain: -\n"); break; default: fprintf(MSG_OUT, "libdvdnav: Unknown Domain: -\n"); break; } fprintf(MSG_OUT, "libdvdnav: VTS:%d PGC:%d PG:%u CELL:%u BLOCK:%u VTS_TTN:%u TTN:%u TT_PGCN:%u\n", (vm->state).vtsN, get_PGCN(vm), (vm->state).pgN, (vm->state).cellN, (vm->state).blockN, (vm->state).VTS_TTN_REG, (vm->state).TTN_REG, (vm->state).TT_PGCN_REG); } #endif static void dvd_read_name(char *name, const char *device) { /* Because we are compiling with _FILE_OFFSET_BITS=64 * all off_t are 64bit. */ off_t off; int fd, i; uint8_t data[DVD_VIDEO_LB_LEN]; /* Read DVD name */ fd = open(device, O_RDONLY); if (fd > 0) { off = lseek( fd, 32 * (off_t) DVD_VIDEO_LB_LEN, SEEK_SET ); if( off == ( 32 * (off_t) DVD_VIDEO_LB_LEN ) ) { off = read( fd, data, DVD_VIDEO_LB_LEN ); close(fd); if (off == ( (off_t) DVD_VIDEO_LB_LEN )) { fprintf(MSG_OUT, "libdvdnav: DVD Title: "); for(i=25; i < 73; i++ ) { if((data[i] == 0)) break; if((data[i] > 32) && (data[i] < 127)) { fprintf(MSG_OUT, "%c", data[i]); } else { fprintf(MSG_OUT, " "); } } strncpy(name, &data[25], 48); name[48] = 0; fprintf(MSG_OUT, "\nlibdvdnav: DVD Serial Number: "); for(i=73; i < 89; i++ ) { if((data[i] == 0)) break; if((data[i] > 32) && (data[i] < 127)) { fprintf(MSG_OUT, "%c", data[i]); } else { fprintf(MSG_OUT, " "); } } fprintf(MSG_OUT, "\nlibdvdnav: DVD Title (Alternative): "); for(i=89; i < 128; i++ ) { if((data[i] == 0)) break; if((data[i] > 32) && (data[i] < 127)) { fprintf(MSG_OUT, "%c", data[i]); } else { fprintf(MSG_OUT, " "); } } fprintf(MSG_OUT, "\n"); } else { fprintf(MSG_OUT, "libdvdnav: Can't read name block. Probably not a DVD-ROM device.\n"); } } else { fprintf(MSG_OUT, "libdvdnav: Can't seek to block %u\n", 32 ); } close(fd); } else { fprintf(MSG_OUT, "NAME OPEN FAILED\n"); } } static int ifoOpenNewVTSI(vm_t *vm, dvd_reader_t *dvd, int vtsN) { if((vm->state).vtsN == vtsN) { return 1; /* We alread have it */ } if(vm->vtsi != NULL) ifoClose(vm->vtsi); vm->vtsi = ifoOpenVTSI(dvd, vtsN); if(vm->vtsi == NULL) { fprintf(MSG_OUT, "libdvdnav: ifoOpenVTSI failed\n"); return 0; } if(!ifoRead_VTS_PTT_SRPT(vm->vtsi)) { fprintf(MSG_OUT, "libdvdnav: ifoRead_VTS_PTT_SRPT failed\n"); return 0; } if(!ifoRead_PGCIT(vm->vtsi)) { fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCIT failed\n"); return 0; } if(!ifoRead_PGCI_UT(vm->vtsi)) { fprintf(MSG_OUT, "libdvdnav: ifoRead_PGCI_UT failed\n"); return 0; } if(!ifoRead_VOBU_ADMAP(vm->vtsi)) { fprintf(MSG_OUT, "libdvdnav: ifoRead_VOBU_ADMAP vtsi failed\n"); return 0; } if(!ifoRead_TITLE_VOBU_ADMAP(vm->vtsi)) { fprintf(MSG_OUT, "libdvdnav: ifoRead_TITLE_VOBU_ADMAP vtsi failed\n"); return 0; } (vm->state).vtsN = vtsN; return 1; } /* Initialisation & Destruction */ vm_t* vm_new_vm() { return (vm_t*)calloc(sizeof(vm_t), sizeof(char)); } void vm_free_vm(vm_t *vm) { vm_stop(vm); free(vm); } /* IFO Access */ ifo_handle_t *vm_get_vmgi(vm_t *vm) { return vm->vmgi; } ifo_handle_t *vm_get_vtsi(vm_t *vm) { return vm->vtsi; } /* Reader Access */ dvd_reader_t *vm_get_dvd_reader(vm_t *vm) { return vm->dvd; } /* Basic Handling */ int vm_start(vm_t *vm) { /* Set pgc to FP (First Play) pgc */ set_FP_PGC(vm); process_command(vm, play_PGC(vm)); return !vm->stopped; } void vm_stop(vm_t *vm) { if(vm->vmgi) { ifoClose(vm->vmgi); vm->vmgi=NULL; } if(vm->vtsi) { ifoClose(vm->vtsi); vm->vtsi=NULL; } if(vm->dvd) { DVDClose(vm->dvd); vm->dvd=NULL; } vm->stopped = 1; } int vm_reset(vm_t *vm, const char *dvdroot) { /* Setup State */ memset((vm->state).registers.SPRM, 0, sizeof((vm->state).registers.SPRM)); memset((vm->state).registers.GPRM, 0, sizeof((vm->state).registers.GPRM)); memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode)); memset((vm->state).registers.GPRM_mode, 0, sizeof((vm->state).registers.GPRM_mode)); memset((vm->state).registers.GPRM_time, 0, sizeof((vm->state).registers.GPRM_time)); (vm->state).registers.SPRM[0] = ('e'<<8)|'n'; /* Player Menu Languange code */ (vm->state).AST_REG = 15; /* 15 why? */ (vm->state).SPST_REG = 62; /* 62 why? */ (vm->state).AGL_REG = 1; (vm->state).TTN_REG = 1; (vm->state).VTS_TTN_REG = 1; /* (vm->state).TT_PGCN_REG = 0 */ (vm->state).PTTN_REG = 1; (vm->state).HL_BTNN_REG = 1 << 10; (vm->state).PTL_REG = 15; /* Parental Level */ (vm->state).registers.SPRM[12] = ('U'<<8)|'S'; /* Parental Management Country Code */ (vm->state).registers.SPRM[16] = ('e'<<8)|'n'; /* Initial Language Code for Audio */ (vm->state).registers.SPRM[18] = ('e'<<8)|'n'; /* Initial Language Code for Spu */ (vm->state).registers.SPRM[20] = 0x1; /* Player Regional Code Mask. Region free! */ (vm->state).registers.SPRM[14] = 0x100; /* Try Pan&Scan */ (vm->state).pgN = 0; (vm->state).cellN = 0; (vm->state).cell_restart = 0; (vm->state).domain = FP_DOMAIN; (vm->state).rsm_vtsN = 0; (vm->state).rsm_cellN = 0; (vm->state).rsm_blockN = 0; (vm->state).vtsN = -1; if (vm->dvd && dvdroot) { /* a new dvd device has been requested */ vm_stop(vm); } if (!vm->dvd) { vm->dvd = DVDOpen(dvdroot); if(!vm->dvd) { fprintf(MSG_OUT, "libdvdnav: vm: faild to open/read the DVD\n"); return 0; } dvd_read_name(vm->dvd_name, dvdroot); vm->map = remap_loadmap(vm->dvd_name); vm->vmgi = ifoOpenVMGI(vm->dvd); if(!vm->vmgi) { fprintf(MSG_OUT, "libdvdnav: vm: faild to read VIDEO_TS.IFO\n"); return 0; } if(!ifoRead_FP_PGC(vm->vmgi)) { fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_FP_PGC failed\n"); return 0; } if(!ifoRead_TT_SRPT(vm->vmgi)) { fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_TT_SRPT failed\n"); return 0; } if(!ifoRead_PGCI_UT(vm->vmgi)) { fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_PGCI_UT failed\n"); return 0; } if(!ifoRead_PTL_MAIT(vm->vmgi)) { fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_PTL_MAIT failed\n"); /* return 0; Not really used for now.. */ } if(!ifoRead_VTS_ATRT(vm->vmgi)) { fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_VTS_ATRT failed\n"); /* return 0; Not really used for now.. */ } if(!ifoRead_VOBU_ADMAP(vm->vmgi)) { fprintf(MSG_OUT, "libdvdnav: vm: ifoRead_VOBU_ADMAP vgmi failed\n"); /* return 0; Not really used for now.. */ } /* ifoRead_TXTDT_MGI(vmgi); Not implemented yet */ } if (vm->vmgi) { int i, mask; fprintf(MSG_OUT, "libdvdnav: DVD disk reports itself with Region mask 0x%08x. Regions:", vm->vmgi->vmgi_mat->vmg_category); for (i = 1, mask = 1; i <= 8; i++, mask <<= 1) if (((vm->vmgi->vmgi_mat->vmg_category >> 16) & mask) == 0) fprintf(MSG_OUT, " %d", i); fprintf(MSG_OUT, "\n"); } return 1; } /* copying and merging */ vm_t *vm_new_copy(vm_t *source) { vm_t *target = vm_new_vm(); int vtsN; int pgcN = get_PGCN(source); int pgN = (source->state).pgN; assert(pgcN); memcpy(target, source, sizeof(vm_t)); /* open a new vtsi handle, because the copy might switch to another VTS */ target->vtsi = NULL; vtsN = (target->state).vtsN; if (vtsN > 0) { (target->state).vtsN = 0; if (!ifoOpenNewVTSI(target, target->dvd, vtsN)) assert(0); /* restore pgc pointer into the new vtsi */ if (!set_PGCN(target, pgcN)) assert(0); (target->state).pgN = pgN; } return target; } void vm_merge(vm_t *target, vm_t *source) { if(target->vtsi) ifoClose(target->vtsi); memcpy(target, source, sizeof(vm_t)); memset(source, 0, sizeof(vm_t)); } void vm_free_copy(vm_t *vm) { if(vm->vtsi) ifoClose(vm->vtsi); free(vm); } /* regular playback */ void vm_position_get(vm_t *vm, vm_position_t *position) { position->button = (vm->state).HL_BTNN_REG >> 10; position->vts = (vm->state).vtsN; position->domain = (vm->state).domain; position->spu_channel = (vm->state).SPST_REG; position->audio_channel = (vm->state).AST_REG; position->angle_channel = (vm->state).AGL_REG; position->hop_channel = vm->hop_channel; /* Increases by one on each hop */ position->cell = (vm->state).cellN; position->cell_restart = (vm->state).cell_restart; position->cell_start = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector; position->still = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].still_time; position->block = (vm->state).blockN; /* handle PGC stills at PGC end */ if ((vm->state).cellN == (vm->state).pgc->nr_of_cells) position->still += (vm->state).pgc->still_time; /* still already determined */ if (position->still) return; /* This is a rough fix for some strange still situations on some strange DVDs. * There are discs (like the German "Back to the Future" RC2) where the only * indication of a still is a cell playback time higher than the time the frames * in this cell actually take to play (like 1 frame with 1 minute playback time). * On the said BTTF disc, for these cells last_sector and last_vobu_start_sector * are equal and the cells are very short, so we abuse these conditions to * detect such discs. I consider these discs broken, so the fix is somewhat * broken, too. */ if (((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector == (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_vobu_start_sector) && ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector - (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector < 1024)) { int time; int size = (vm->state).pgc->cell_playback[(vm->state).cellN - 1].last_sector - (vm->state).pgc->cell_playback[(vm->state).cellN - 1].first_sector; time = ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour >> 4 ) * 36000; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.hour & 0x0f) * 3600; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute >> 4 ) * 600; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.minute & 0x0f) * 60; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second >> 4 ) * 10; time += ((vm->state).pgc->cell_playback[(vm->state).cellN - 1].playback_time.second & 0x0f) * 1; if (!time || size / time > 30) /* datarate is too high, it might be a very short, but regular cell */ return; if (time > 0xff) time = 0xff; position->still = time; } } void vm_get_next_cell(vm_t *vm) { process_command(vm, play_Cell_post(vm)); } /* Jumping */ int vm_jump_pg(vm_t *vm, int pg) { (vm->state).pgN = pg; process_command(vm, play_PG(vm)); return 1; } int vm_jump_cell_block(vm_t *vm, int cell, int block) { (vm->state).cellN = cell; process_command(vm, play_Cell(vm)); /* play_Cell can jump to a different cell in case of angles */ if ((vm->state).cellN == cell) (vm->state).blockN = block; return 1; } int vm_jump_title_part(vm_t *vm, int title, int part) { link_t link; if(!set_PTT(vm, title, part)) return 0; /* Some DVDs do not want us to jump directly into a title and have * PGC pre commands taking us back to some menu. Since we do not like that, * we do not execute PGC pre commands that would do a jump. */ /* process_command(vm, play_PGC_PG(vm, (vm->state).pgN)); */ link = play_PGC_PG(vm, (vm->state).pgN); if (link.command != PlayThis) /* jump occured -> ignore it and play the PG anyway */ process_command(vm, play_PG(vm)); else process_command(vm, link); return 1; } int vm_jump_top_pg(vm_t *vm) { process_command(vm, play_PG(vm)); return 1; } int vm_jump_next_pg(vm_t *vm) { if((vm->state).pgN >= (vm->state).pgc->nr_of_programs) { /* last program -> move to TailPGC */ process_command(vm, play_PGC_post(vm)); return 1; } else { vm_jump_pg(vm, (vm->state).pgN + 1); return 1; } } int vm_jump_prev_pg(vm_t *vm) { if ((vm->state).pgN <= 1) { /* first program -> move to last program of previous PGC */ if ((vm->state).pgc->prev_pgc_nr && set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) { process_command(vm, play_PGC(vm)); vm_jump_pg(vm, (vm->state).pgc->nr_of_programs); return 1; } return 0; } else { vm_jump_pg(vm, (vm->state).pgN - 1); return 1; } } int vm_jump_up(vm_t *vm) { if((vm->state).pgc->goup_pgc_nr && set_PGCN(vm, (vm->state).pgc->goup_pgc_nr)) { process_command(vm, play_PGC(vm)); return 1; } return 0; } int vm_jump_menu(vm_t *vm, DVDMenuID_t menuid) { domain_t old_domain = (vm->state).domain; switch ((vm->state).domain) { case VTS_DOMAIN: set_RSMinfo(vm, 0, (vm->state).blockN); /* FALL THROUGH */ case VTSM_DOMAIN: case VMGM_DOMAIN: switch(menuid) { case DVD_MENU_Title: case DVD_MENU_Escape: (vm->state).domain = VMGM_DOMAIN; break; case DVD_MENU_Root: case DVD_MENU_Subpicture: case DVD_MENU_Audio: case DVD_MENU_Angle: case DVD_MENU_Part: (vm->state).domain = VTSM_DOMAIN; break; } if(get_PGCIT(vm) && set_MENU(vm, menuid)) { process_command(vm, play_PGC(vm)); return 1; /* Jump */ } else { (vm->state).domain = old_domain; } break; case FP_DOMAIN: /* FIXME XXX $$$ What should we do here? */ break; } return 0; } int vm_jump_resume(vm_t *vm) { link_t link_values = { LinkRSM, 0, 0, 0 }; if (!(vm->state).rsm_vtsN) /* Do we have resume info? */ return 0; if (!process_command(vm, link_values)) return 0; return 1; } int vm_exec_cmd(vm_t *vm, vm_cmd_t *cmd) { link_t link_values; if(vmEval_CMD(cmd, 1, &(vm->state).registers, &link_values)) return process_command(vm, link_values); else return 0; /* It updated some state thats all... */ } /* getting information */ int vm_get_current_menu(vm_t *vm, int *menuid) { pgcit_t* pgcit; int pgcn; pgcn = (vm->state).pgcN; pgcit = get_PGCIT(vm); if (!pgcit) return 0; *menuid = pgcit->pgci_srp[pgcn - 1].entry_id & 0xf ; return 1; } int vm_get_current_title_part(vm_t *vm, int *title_result, int *part_result) { vts_ptt_srpt_t *vts_ptt_srpt; int title, part = 0, vts_ttn; int found; int16_t pgcN, pgN; vts_ptt_srpt = vm->vtsi->vts_ptt_srpt; pgcN = get_PGCN(vm); pgN = vm->state.pgN; found = 0; for (vts_ttn = 0; (vts_ttn < vts_ptt_srpt->nr_of_srpts) && !found; vts_ttn++) { for (part = 0; (part < vts_ptt_srpt->title[vts_ttn].nr_of_ptts) && !found; part++) { if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgcn == pgcN) { if (vts_ptt_srpt->title[vts_ttn].ptt[part].pgn == pgN) { found = 1; break; } if (part > 0 && vts_ptt_srpt->title[vts_ttn].ptt[part].pgn > pgN && vts_ptt_srpt->title[vts_ttn].ptt[part - 1].pgn < pgN) { part--; found = 1; break; } } } if (found) break; } vts_ttn++; part++; if (!found) { fprintf(MSG_OUT, "libdvdnav: chapter NOT FOUND!\n"); return 0; } title = get_TT(vm, vm->state.vtsN, vts_ttn); #ifdef TRACE if (title) { fprintf(MSG_OUT, "libdvdnav: ************ this chapter FOUND!\n"); fprintf(MSG_OUT, "libdvdnav: VTS_PTT_SRPT - Title %3i part %3i: PGC: %3i PG: %3i\n", title, part, vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgcn , vts_ptt_srpt->title[vts_ttn-1].ptt[part-1].pgn ); } #endif *title_result = title; *part_result = part; return 1; } /* Return the substream id for 'logical' audio stream audioN. * 0 <= audioN < 8 */ int vm_get_audio_stream(vm_t *vm, int audioN) { int streamN = -1; if((vm->state).domain != VTS_DOMAIN) audioN = 0; if(audioN < 8) { /* Is there any control info for this logical stream */ if((vm->state).pgc->audio_control[audioN] & (1<<15)) { streamN = ((vm->state).pgc->audio_control[audioN] >> 8) & 0x07; } } if((vm->state).domain != VTS_DOMAIN && streamN == -1) streamN = 0; /* FIXME: Should also check in vtsi/vmgi status what kind of stream * it is (ac3/lpcm/dts/sdds...) to find the right (sub)stream id */ return streamN; } /* Return the substream id for 'logical' subpicture stream subpN and given mode. * 0 <= subpN < 32 * mode == 0 - widescreen * mode == 1 - letterbox * mode == 2 - pan&scan */ int vm_get_subp_stream(vm_t *vm, int subpN, int mode) { int streamN = -1; int source_aspect = vm_get_video_aspect(vm); if((vm->state).domain != VTS_DOMAIN) subpN = 0; if(subpN < 32) { /* a valid logical stream */ /* Is this logical stream present */ if((vm->state).pgc->subp_control[subpN] & (1<<31)) { if(source_aspect == 0) /* 4:3 */ streamN = ((vm->state).pgc->subp_control[subpN] >> 24) & 0x1f; if(source_aspect == 3) /* 16:9 */ switch (mode) { case 0: streamN = ((vm->state).pgc->subp_control[subpN] >> 16) & 0x1f; break; case 1: streamN = ((vm->state).pgc->subp_control[subpN] >> 8) & 0x1f; break; case 2: streamN = (vm->state).pgc->subp_control[subpN] & 0x1f; } } } if((vm->state).domain != VTS_DOMAIN && streamN == -1) streamN = 0; /* FIXME: Should also check in vtsi/vmgi status what kind of stream it is. */ return streamN; } int vm_get_audio_active_stream(vm_t *vm) { int audioN; int streamN; audioN = (vm->state).AST_REG ; streamN = vm_get_audio_stream(vm, audioN); /* If no such stream, then select the first one that exists. */ if(streamN == -1) { for(audioN = 0; audioN < 8; audioN++) { if((vm->state).pgc->audio_control[audioN] & (1<<15)) { if ((streamN = vm_get_audio_stream(vm, audioN)) >= 0) break; } } } return streamN; } int vm_get_subp_active_stream(vm_t *vm, int mode) { int subpN; int streamN; subpN = (vm->state).SPST_REG & ~0x40; streamN = vm_get_subp_stream(vm, subpN, mode); /* If no such stream, then select the first one that exists. */ if(streamN == -1) { for(subpN = 0; subpN < 32; subpN++) { if((vm->state).pgc->subp_control[subpN] & (1<<31)) { if ((streamN = vm_get_subp_stream(vm, subpN, mode)) >= 0) break; } } } if((vm->state).domain == VTS_DOMAIN && !((vm->state).SPST_REG & 0x40)) /* Bit 7 set means hide, and only let Forced display show */ return (streamN | 0x80); else return streamN; } void vm_get_angle_info(vm_t *vm, int *current, int *num_avail) { *num_avail = 1; *current = 1; if((vm->state).domain == VTS_DOMAIN) { title_info_t *title; /* TTN_REG does not allways point to the correct title.. */ if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts) return; title = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1]; if(title->title_set_nr != (vm->state).vtsN || title->vts_ttn != (vm->state).VTS_TTN_REG) return; *num_avail = title->nr_of_angles; *current = (vm->state).AGL_REG; } } #if 0 /* currently unused */ void vm_get_audio_info(vm_t *vm, int *current, int *num_avail) { switch ((vm->state).domain) { case VTS_DOMAIN: *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_audio_streams; *current = (vm->state).AST_REG; break; case VTSM_DOMAIN: *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_audio_streams; /* 1 */ *current = 1; break; case VMGM_DOMAIN: case FP_DOMAIN: *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_audio_streams; /* 1 */ *current = 1; break; } } /* currently unused */ void vm_get_subp_info(vm_t *vm, int *current, int *num_avail) { switch ((vm->state).domain) { case VTS_DOMAIN: *num_avail = vm->vtsi->vtsi_mat->nr_of_vts_subp_streams; *current = (vm->state).SPST_REG; break; case VTSM_DOMAIN: *num_avail = vm->vtsi->vtsi_mat->nr_of_vtsm_subp_streams; /* 1 */ *current = 0x41; break; case VMGM_DOMAIN: case FP_DOMAIN: *num_avail = vm->vmgi->vmgi_mat->nr_of_vmgm_subp_streams; /* 1 */ *current = 0x41; break; } } /* currently unused */ void vm_get_video_res(vm_t *vm, int *width, int *height) { video_attr_t attr = vm_get_video_attr(vm); if(attr.video_format != 0) *height = 576; else *height = 480; switch(attr.picture_size) { case 0: *width = 720; break; case 1: *width = 704; break; case 2: *width = 352; break; case 3: *width = 352; *height /= 2; break; } } #endif int vm_get_video_aspect(vm_t *vm) { int aspect = vm_get_video_attr(vm).display_aspect_ratio; assert(aspect == 0 || aspect == 3); (vm->state).registers.SPRM[14] &= ~(0x3 << 10); (vm->state).registers.SPRM[14] |= aspect << 10; return aspect; } int vm_get_video_scale_permission(vm_t *vm) { return vm_get_video_attr(vm).permitted_df; } video_attr_t vm_get_video_attr(vm_t *vm) { switch ((vm->state).domain) { case VTSM_DOMAIN: return vm->vtsi->vtsi_mat->vtsm_video_attr; case VMGM_DOMAIN: case FP_DOMAIN: return vm->vmgi->vmgi_mat->vmgm_video_attr; default: assert(!"vm_get_video_attr(): unknown domain"); /* fall through */ case VTS_DOMAIN: return vm->vtsi->vtsi_mat->vts_video_attr; } } audio_attr_t vm_get_audio_attr(vm_t *vm, int streamN) { switch ((vm->state).domain) { case VTSM_DOMAIN: return vm->vtsi->vtsi_mat->vtsm_audio_attr; case VMGM_DOMAIN: case FP_DOMAIN: return vm->vmgi->vmgi_mat->vmgm_audio_attr; default: assert(!"vm_get_audio_attr(): invalid domain"); /* fall through */ case VTS_DOMAIN: return vm->vtsi->vtsi_mat->vts_audio_attr[streamN]; } } subp_attr_t vm_get_subp_attr(vm_t *vm, int streamN) { switch ((vm->state).domain) { case VTSM_DOMAIN: return vm->vtsi->vtsi_mat->vtsm_subp_attr; case VMGM_DOMAIN: case FP_DOMAIN: return vm->vmgi->vmgi_mat->vmgm_subp_attr; default: assert(!"vm_get_subp_attr(): invalid domain"); /* fall through */ case VTS_DOMAIN: return vm->vtsi->vtsi_mat->vts_subp_attr[streamN]; } } /* Playback control */ static link_t play_PGC(vm_t *vm) { link_t link_values; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: play_PGC:"); if((vm->state).domain != FP_DOMAIN) { fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); } else { fprintf(MSG_OUT, " first_play_pgc\n"); } #endif /* This must be set before the pre-commands are executed because they * might contain a CallSS that will save resume state */ /* FIXME: This may be only a temporary fix for something... */ (vm->state).pgN = 1; (vm->state).cellN = 0; (vm->state).blockN = 0; /* eval -> updates the state and returns either - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN) - just play video i.e first PG (This is what happens if you fall of the end of the pre_cmds) - or an error (are there more cases?) */ if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) { if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds, (vm->state).pgc->command_tbl->nr_of_pre, &(vm->state).registers, &link_values)) { /* link_values contains the 'jump' return value */ return link_values; } else { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n"); #endif } } return play_PG(vm); } static link_t play_PGC_PG(vm_t *vm, int pgN) { link_t link_values; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: play_PGC_PG:"); if((vm->state).domain != FP_DOMAIN) { fprintf(MSG_OUT, " (vm->state).pgcN (%i)\n", get_PGCN(vm)); } else { fprintf(MSG_OUT, " first_play_pgc\n"); } #endif /* This must be set before the pre-commands are executed because they * might contain a CallSS that will save resume state */ /* FIXME: This may be only a temporary fix for something... */ (vm->state).pgN = pgN; (vm->state).cellN = 0; (vm->state).blockN = 0; /* eval -> updates the state and returns either - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN) - just play video i.e first PG (This is what happens if you fall of the end of the pre_cmds) - or an error (are there more cases?) */ if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_pre) { if(vmEval_CMD((vm->state).pgc->command_tbl->pre_cmds, (vm->state).pgc->command_tbl->nr_of_pre, &(vm->state).registers, &link_values)) { /* link_values contains the 'jump' return value */ return link_values; } else { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: PGC pre commands didn't do a Jump, Link or Call\n"); #endif } } return play_PG(vm); } static link_t play_PGC_post(vm_t *vm) { link_t link_values; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: play_PGC_post:\n"); #endif /* eval -> updates the state and returns either - some kind of jump (Jump(TT/SS/VTS_TTN/CallSS/link C/PG/PGC/PTTN) - just go to next PGC (This is what happens if you fall of the end of the post_cmds) - or an error (are there more cases?) */ if((vm->state).pgc->command_tbl && (vm->state).pgc->command_tbl->nr_of_post && vmEval_CMD((vm->state).pgc->command_tbl->post_cmds, (vm->state).pgc->command_tbl->nr_of_post, &(vm->state).registers, &link_values)) { return link_values; } #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: ** Fell of the end of the pgc, continuing in NextPGC\n"); #endif /* Should end up in the STOP_DOMAIN if next_pgc is 0. */ if(!set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) { link_values.command = Exit; return link_values; } return play_PGC(vm); } static link_t play_PG(vm_t *vm) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i)\n", (vm->state).pgN); #endif assert((vm->state).pgN > 0); if((vm->state).pgN > (vm->state).pgc->nr_of_programs) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: play_PG: (vm->state).pgN (%i) > pgc->nr_of_programs (%i)\n", (vm->state).pgN, (vm->state).pgc->nr_of_programs ); #endif assert((vm->state).pgN == (vm->state).pgc->nr_of_programs + 1); return play_PGC_post(vm); } (vm->state).cellN = (vm->state).pgc->program_map[(vm->state).pgN - 1]; return play_Cell(vm); } static link_t play_Cell(vm_t *vm) { static const link_t play_this = {PlayThis, /* Block in Cell */ 0, 0, 0}; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: play_Cell: (vm->state).cellN (%i)\n", (vm->state).cellN); #endif assert((vm->state).cellN > 0); if((vm->state).cellN > (vm->state).pgc->nr_of_cells) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: (vm->state).cellN (%i) > pgc->nr_of_cells (%i)\n", (vm->state).cellN, (vm->state).pgc->nr_of_cells ); #endif assert((vm->state).cellN == (vm->state).pgc->nr_of_cells + 1); return play_PGC_post(vm); } /* Multi angle/Interleaved */ switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) { case 0: /* Normal */ assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0); break; case 1: /* The first cell in the block */ switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) { case 0: /* Not part of a block */ assert(0); break; case 1: /* Angle block */ /* Loop and check each cell instead? So we don't get outside the block? */ (vm->state).cellN += (vm->state).AGL_REG - 1; #ifdef STRICT assert((vm->state).cellN <= (vm->state).pgc->nr_of_cells); assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0); assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1); #else if (!((vm->state).cellN <= (vm->state).pgc->nr_of_cells) || !((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode != 0) || !((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 1)) { fprintf(MSG_OUT, "libdvdnav: Invalid angle block\n"); (vm->state).cellN -= (vm->state).AGL_REG - 1; } #endif break; case 2: /* ?? */ case 3: /* ?? */ default: fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n", (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode, (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type); assert(0); } break; case 2: /* Cell in the block */ case 3: /* Last cell in the block */ /* These might perhaps happen for RSM or LinkC commands? */ default: fprintf(MSG_OUT, "libdvdnav: Cell is in block but did not enter at first cell!\n"); } /* Updates (vm->state).pgN and PTTN_REG */ if(!set_PGN(vm)) { /* Should not happen */ assert(0); return play_PGC_post(vm); } (vm->state).cell_restart++; (vm->state).blockN = 0; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Cell should restart here\n"); #endif return play_this; } static link_t play_Cell_post(vm_t *vm) { cell_playback_t *cell; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: play_Cell_post: (vm->state).cellN (%i)\n", (vm->state).cellN); #endif cell = &(vm->state).pgc->cell_playback[(vm->state).cellN - 1]; /* Still time is already taken care of before we get called. */ /* Deal with a Cell command, if any */ if(cell->cell_cmd_nr != 0) { link_t link_values; /* These asserts are now not needed. * Some DVDs have no cell commands listed in the PGC, * but the Cell itself points to a cell command that does not exist. * For this situation, just ignore the cell command and continue. * * assert((vm->state).pgc->command_tbl != NULL); * assert((vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr); */ if ((vm->state).pgc->command_tbl != NULL && (vm->state).pgc->command_tbl->nr_of_cell >= cell->cell_cmd_nr) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Cell command present, executing\n"); #endif if(vmEval_CMD(&(vm->state).pgc->command_tbl->cell_cmds[cell->cell_cmd_nr - 1], 1, &(vm->state).registers, &link_values)) { return link_values; } else { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Cell command didn't do a Jump, Link or Call\n"); #endif } } else { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Invalid Cell command\n"); #endif } } /* Where to continue after playing the cell... */ /* Multi angle/Interleaved */ switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode) { case 0: /* Normal */ assert((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type == 0); (vm->state).cellN++; break; case 1: /* The first cell in the block */ case 2: /* A cell in the block */ case 3: /* The last cell in the block */ default: switch((vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type) { case 0: /* Not part of a block */ assert(0); break; case 1: /* Angle block */ /* Skip the 'other' angles */ (vm->state).cellN++; while((vm->state).cellN <= (vm->state).pgc->nr_of_cells && (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode >= 2) { (vm->state).cellN++; } break; case 2: /* ?? */ case 3: /* ?? */ default: fprintf(MSG_OUT, "libdvdnav: Invalid? Cell block_mode (%d), block_type (%d)\n", (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_mode, (vm->state).pgc->cell_playback[(vm->state).cellN - 1].block_type); assert(0); } break; } /* Figure out the correct pgN for the new cell */ if(!set_PGN(vm)) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: last cell in this PGC\n"); #endif return play_PGC_post(vm); } return play_Cell(vm); } /* link processing */ static int process_command(vm_t *vm, link_t link_values) { while(link_values.command != PlayThis) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Before printout starts:\n"); vm_print_link(link_values); fprintf(MSG_OUT, "libdvdnav: Link values %i %i %i %i\n", link_values.command, link_values.data1, link_values.data2, link_values.data3); vm_print_current_domain_state(vm); fprintf(MSG_OUT, "libdvdnav: Before printout ends.\n"); #endif switch(link_values.command) { case LinkNoLink: /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; return 0; /* no actual jump */ case LinkTopC: /* Restart playing from the beginning of the current Cell. */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; link_values = play_Cell(vm); break; case LinkNextC: /* Link to Next Cell */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; (vm->state).cellN += 1; link_values = play_Cell(vm); break; case LinkPrevC: /* Link to Previous Cell */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; assert((vm->state).cellN > 1); (vm->state).cellN -= 1; link_values = play_Cell(vm); break; case LinkTopPG: /* Link to Top of current Program */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; link_values = play_PG(vm); break; case LinkNextPG: /* Link to Next Program */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; (vm->state).pgN += 1; link_values = play_PG(vm); break; case LinkPrevPG: /* Link to Previous Program */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; assert((vm->state).pgN > 1); (vm->state).pgN -= 1; link_values = play_PG(vm); break; case LinkTopPGC: /* Restart playing from beginning of current Program Chain */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; link_values = play_PGC(vm); break; case LinkNextPGC: /* Link to Next Program Chain */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; assert((vm->state).pgc->next_pgc_nr != 0); if(set_PGCN(vm, (vm->state).pgc->next_pgc_nr)) link_values = play_PGC(vm); else link_values.command = Exit; break; case LinkPrevPGC: /* Link to Previous Program Chain */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; assert((vm->state).pgc->prev_pgc_nr != 0); if(set_PGCN(vm, (vm->state).pgc->prev_pgc_nr)) link_values = play_PGC(vm); else link_values.command = Exit; break; case LinkGoUpPGC: /* Link to GoUp Program Chain */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; assert((vm->state).pgc->goup_pgc_nr != 0); if(set_PGCN(vm, (vm->state).pgc->goup_pgc_nr)) link_values = play_PGC(vm); else link_values.command = Exit; break; case LinkTailPGC: /* Link to Tail of Program Chain */ /* BUTTON number:data1 */ if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; link_values = play_PGC_post(vm); break; case LinkRSM: { /* Link to Resume point */ int i; /* Check and see if there is any rsm info!! */ if (!(vm->state).rsm_vtsN) { fprintf(MSG_OUT, "libdvdnav: trying to resume without any resume info set\n"); link_values.command = Exit; break; } (vm->state).domain = VTS_DOMAIN; if (!ifoOpenNewVTSI(vm, vm->dvd, (vm->state).rsm_vtsN)) assert(0); set_PGCN(vm, (vm->state).rsm_pgcN); /* These should never be set in SystemSpace and/or MenuSpace */ /* (vm->state).TTN_REG = rsm_tt; ?? */ /* (vm->state).TT_PGCN_REG = (vm->state).rsm_pgcN; ?? */ for(i = 0; i < 5; i++) { (vm->state).registers.SPRM[4 + i] = (vm->state).rsm_regs[i]; } if(link_values.data1 != 0) (vm->state).HL_BTNN_REG = link_values.data1 << 10; if((vm->state).rsm_cellN == 0) { assert((vm->state).cellN); /* Checking if this ever happens */ (vm->state).pgN = 1; link_values = play_PG(vm); } else { /* (vm->state).pgN = ?? this gets the right value in set_PGN() below */ (vm->state).cellN = (vm->state).rsm_cellN; link_values.command = PlayThis; link_values.data1 = (vm->state).rsm_blockN & 0xffff; link_values.data2 = (vm->state).rsm_blockN >> 16; if(!set_PGN(vm)) { /* Were at the end of the PGC, should not happen for a RSM */ assert(0); link_values.command = LinkTailPGC; link_values.data1 = 0; /* No button */ } } } break; case LinkPGCN: /* Link to Program Chain Number:data1 */ if(!set_PGCN(vm, link_values.data1)) assert(0); link_values = play_PGC(vm); break; case LinkPTTN: /* Link to Part of current Title Number:data1 */ /* BUTTON number:data2 */ /* PGC Pre-Commands are not executed */ assert((vm->state).domain == VTS_DOMAIN); if(link_values.data2 != 0) (vm->state).HL_BTNN_REG = link_values.data2 << 10; if(!set_VTS_PTT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG, link_values.data1)) assert(0); link_values = play_PG(vm); break; case LinkPGN: /* Link to Program Number:data1 */ /* BUTTON number:data2 */ if(link_values.data2 != 0) (vm->state).HL_BTNN_REG = link_values.data2 << 10; /* Update any other state, PTTN perhaps? */ (vm->state).pgN = link_values.data1; link_values = play_PG(vm); break; case LinkCN: /* Link to Cell Number:data1 */ /* BUTTON number:data2 */ if(link_values.data2 != 0) (vm->state).HL_BTNN_REG = link_values.data2 << 10; /* Update any other state, pgN, PTTN perhaps? */ (vm->state).cellN = link_values.data1; link_values = play_Cell(vm); break; case Exit: vm->stopped = 1; return 0; case JumpTT: /* Jump to VTS Title Domain */ /* Only allowed from the First Play domain(PGC) */ /* or the Video Manager domain (VMG) */ /* Stop SPRM9 Timer */ /* Set SPRM1 and SPRM2 */ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */ if(set_TT(vm, link_values.data1)) link_values = play_PGC(vm); else link_values.command = Exit; break; case JumpVTS_TT: /* Jump to Title:data1 in same VTS Title Domain */ /* Only allowed from the VTS Menu Domain(VTSM) */ /* or the Video Title Set Domain(VTS) */ /* Stop SPRM9 Timer */ /* Set SPRM1 and SPRM2 */ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */ if(!set_VTS_TT(vm, (vm->state).vtsN, link_values.data1)) assert(0); link_values = play_PGC(vm); break; case JumpVTS_PTT: /* Jump to Part:data2 of Title:data1 in same VTS Title Domain */ /* Only allowed from the VTS Menu Domain(VTSM) */ /* or the Video Title Set Domain(VTS) */ /* Stop SPRM9 Timer */ /* Set SPRM1 and SPRM2 */ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VTS_DOMAIN); /* ?? */ if(!set_VTS_PTT(vm, (vm->state).vtsN, link_values.data1, link_values.data2)) assert(0); link_values = play_PGC_PG(vm, (vm->state).pgN); break; case JumpSS_FP: /* Jump to First Play Domain */ /* Only allowed from the VTS Menu Domain(VTSM) */ /* or the Video Manager domain (VMG) */ /* Stop SPRM9 Timer and any GPRM counters */ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN); /* ?? */ if (!set_FP_PGC(vm)) assert(0); link_values = play_PGC(vm); break; case JumpSS_VMGM_MENU: /* Jump to Video Manger domain - Title Menu:data1 or any PGC in VMG */ /* Allowed from anywhere except the VTS Title domain */ /* Stop SPRM9 Timer and any GPRM counters */ assert((vm->state).domain != VTS_DOMAIN); /* ?? */ (vm->state).domain = VMGM_DOMAIN; if(!set_MENU(vm, link_values.data1)) assert(0); link_values = play_PGC(vm); break; case JumpSS_VTSM: /* Jump to a menu in Video Title domain, */ /* or to a Menu is the current VTS */ /* Stop SPRM9 Timer and any GPRM counters */ /* ifoOpenNewVTSI:data1 */ /* VTS_TTN_REG:data2 */ /* get_MENU:data3 */ if(link_values.data1 != 0) { if (link_values.data1 != (vm->state).vtsN) { /* the normal case */ assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */ (vm->state).domain = VTSM_DOMAIN; if (!ifoOpenNewVTSI(vm, vm->dvd, link_values.data1)) /* Also sets (vm->state).vtsN */ assert(0); } else { /* This happens on some discs like "Captain Scarlet & the Mysterons" or * the German RC2 of "Anatomie" in VTSM. */ assert((vm->state).domain == VTSM_DOMAIN || (vm->state).domain == VMGM_DOMAIN || (vm->state).domain == FP_DOMAIN); /* ?? */ (vm->state).domain = VTSM_DOMAIN; } } else { /* This happens on 'The Fifth Element' region 2. */ assert((vm->state).domain == VTSM_DOMAIN); } /* I don't know what title is supposed to be used for. */ /* Alien or Aliens has this != 1, I think. */ /* assert(link_values.data2 == 1); */ (vm->state).VTS_TTN_REG = link_values.data2; /* TTN_REG (SPRM4), VTS_TTN_REG (SPRM5), TT_PGCN_REG (SPRM6) are linked, */ /* so if one changes, the others must change to match it. */ (vm->state).TTN_REG = get_TT(vm, (vm->state).vtsN, (vm->state).VTS_TTN_REG); if(!set_MENU(vm, link_values.data3)) assert(0); link_values = play_PGC(vm); break; case JumpSS_VMGM_PGC: /* set_PGCN:data1 */ /* Stop SPRM9 Timer and any GPRM counters */ assert((vm->state).domain != VTS_DOMAIN); /* ?? */ (vm->state).domain = VMGM_DOMAIN; if(!set_PGCN(vm, link_values.data1)) assert(0); link_values = play_PGC(vm); break; case CallSS_FP: /* set_RSMinfo:data1 */ assert((vm->state).domain == VTS_DOMAIN); /* ?? */ /* Must be called before domain is changed */ set_RSMinfo(vm, link_values.data1, /* We dont have block info */ 0); set_FP_PGC(vm); link_values = play_PGC(vm); break; case CallSS_VMGM_MENU: /* set_MENU:data1 */ /* set_RSMinfo:data2 */ assert((vm->state).domain == VTS_DOMAIN); /* ?? */ /* Must be called before domain is changed */ set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0); (vm->state).domain = VMGM_DOMAIN; if(!set_MENU(vm, link_values.data1)) assert(0); link_values = play_PGC(vm); break; case CallSS_VTSM: /* set_MENU:data1 */ /* set_RSMinfo:data2 */ assert((vm->state).domain == VTS_DOMAIN); /* ?? */ /* Must be called before domain is changed */ set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0); (vm->state).domain = VTSM_DOMAIN; if(!set_MENU(vm, link_values.data1)) assert(0); link_values = play_PGC(vm); break; case CallSS_VMGM_PGC: /* set_PGC:data1 */ /* set_RSMinfo:data2 */ assert((vm->state).domain == VTS_DOMAIN); /* ?? */ /* Must be called before domain is changed */ set_RSMinfo(vm, link_values.data2, /* We dont have block info */ 0); (vm->state).domain = VMGM_DOMAIN; if(!set_PGCN(vm, link_values.data1)) assert(0); link_values = play_PGC(vm); break; case PlayThis: /* Should never happen. */ assert(0); break; } #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: After printout starts:\n"); vm_print_current_domain_state(vm); fprintf(MSG_OUT, "libdvdnav: After printout ends.\n"); #endif } (vm->state).blockN = link_values.data1 | (link_values.data2 << 16); return 1; } /* Set functions */ static int set_TT(vm_t *vm, int tt) { return set_PTT(vm, tt, 1); } static int set_PTT(vm_t *vm, int tt, int ptt) { assert(tt <= vm->vmgi->tt_srpt->nr_of_srpts); return set_VTS_PTT(vm, vm->vmgi->tt_srpt->title[tt - 1].title_set_nr, vm->vmgi->tt_srpt->title[tt - 1].vts_ttn, ptt); } static int set_VTS_TT(vm_t *vm, int vtsN, int vts_ttn) { return set_VTS_PTT(vm, vtsN, vts_ttn, 1); } static int set_VTS_PTT(vm_t *vm, int vtsN, int vts_ttn, int part) { int pgcN, pgN, res; (vm->state).domain = VTS_DOMAIN; if (vtsN != (vm->state).vtsN) if (!ifoOpenNewVTSI(vm, vm->dvd, vtsN)) /* Also sets (vm->state).vtsN */ return 0; if ((vts_ttn < 1) || (vts_ttn > vm->vtsi->vts_ptt_srpt->nr_of_srpts) || (part < 1) || (part > vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].nr_of_ptts) ) { return 0; } pgcN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgcn; pgN = vm->vtsi->vts_ptt_srpt->title[vts_ttn - 1].ptt[part - 1].pgn; (vm->state).TT_PGCN_REG = pgcN; (vm->state).PTTN_REG = part; (vm->state).TTN_REG = get_TT(vm, vtsN, vts_ttn); assert( (vm->state.TTN_REG) != 0 ); (vm->state).VTS_TTN_REG = vts_ttn; (vm->state).vtsN = vtsN; /* Not sure about this one. We can get to it easily from TTN_REG */ /* Any other registers? */ res = set_PGCN(vm, pgcN); /* This clobber's state.pgN (sets it to 1), but we don't want clobbering here. */ (vm->state).pgN = pgN; return res; } static int set_FP_PGC(vm_t *vm) { (vm->state).domain = FP_DOMAIN; if (!vm->vmgi->first_play_pgc) { return set_PGCN(vm, 1); } (vm->state).pgc = vm->vmgi->first_play_pgc; (vm->state).pgcN = vm->vmgi->vmgi_mat->first_play_pgc; return 1; } static int set_MENU(vm_t *vm, int menu) { assert((vm->state).domain == VMGM_DOMAIN || (vm->state).domain == VTSM_DOMAIN); return set_PGCN(vm, get_ID(vm, menu)); } static int set_PGCN(vm_t *vm, int pgcN) { pgcit_t *pgcit; pgcit = get_PGCIT(vm); assert(pgcit != NULL); /* ?? Make this return -1 instead */ if (!pgcit) return 0; if(pgcN < 1 || pgcN > pgcit->nr_of_pgci_srp) { #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: ** No such pgcN = %d\n", pgcN); #endif return 0; } (vm->state).pgc = pgcit->pgci_srp[pgcN - 1].pgc; (vm->state).pgcN = pgcN; (vm->state).pgN = 1; if((vm->state).domain == VTS_DOMAIN) (vm->state).TT_PGCN_REG = pgcN; return 1; } /* Figure out the correct pgN from the cell and update (vm->state). */ static int set_PGN(vm_t *vm) { int new_pgN = 0; while(new_pgN < (vm->state).pgc->nr_of_programs && (vm->state).cellN >= (vm->state).pgc->program_map[new_pgN]) new_pgN++; if(new_pgN == (vm->state).pgc->nr_of_programs) /* We are at the last program */ if((vm->state).cellN > (vm->state).pgc->nr_of_cells) return 0; /* We are past the last cell */ (vm->state).pgN = new_pgN; if((vm->state).domain == VTS_DOMAIN) { playback_type_t *pb_ty; if((vm->state).TTN_REG > vm->vmgi->tt_srpt->nr_of_srpts) return 0; /* ?? */ pb_ty = &vm->vmgi->tt_srpt->title[(vm->state).TTN_REG - 1].pb_ty; if(pb_ty->multi_or_random_pgc_title == /* One_Sequential_PGC_Title */ 0) { int dummy, part; vm_get_current_title_part(vm, &dummy, &part); (vm->state).PTTN_REG = part; } else { /* FIXME: Handle RANDOM or SHUFFLE titles. */ fprintf(MSG_OUT, "libdvdnav: RANDOM or SHUFFLE titles are NOT handled yet.\n"); } } return 1; } /* Must be called before domain is changed (set_PGCN()) */ static void set_RSMinfo(vm_t *vm, int cellN, int blockN) { int i; if(cellN) { (vm->state).rsm_cellN = cellN; (vm->state).rsm_blockN = blockN; } else { (vm->state).rsm_cellN = (vm->state).cellN; (vm->state).rsm_blockN = blockN; } (vm->state).rsm_vtsN = (vm->state).vtsN; (vm->state).rsm_pgcN = get_PGCN(vm); /* assert((vm->state).rsm_pgcN == (vm->state).TT_PGCN_REG); for VTS_DOMAIN */ for(i = 0; i < 5; i++) { (vm->state).rsm_regs[i] = (vm->state).registers.SPRM[4 + i]; } } /* Get functions */ /* Searches the TT tables, to find the current TT. * returns the current TT. * returns 0 if not found. */ static int get_TT(vm_t *vm, int vtsN, int vts_ttn) { int i; int tt=0; for(i = 1; i <= vm->vmgi->tt_srpt->nr_of_srpts; i++) { if( vm->vmgi->tt_srpt->title[i - 1].title_set_nr == vtsN && vm->vmgi->tt_srpt->title[i - 1].vts_ttn == vts_ttn) { tt=i; break; } } return tt; } /* Search for entry_id match of the PGC Category in the current VTS PGCIT table. * Return pgcN based on entry_id match. */ static int get_ID(vm_t *vm, int id) { int pgcN, i; pgcit_t *pgcit; /* Relies on state to get the correct pgcit. */ pgcit = get_PGCIT(vm); assert(pgcit != NULL); if (!pgcit) return 0; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: ** Searching for menu (0x%x) entry PGC\n", id); #endif /* Force high bit set. */ id |=0x80; /* Get menu/title */ for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { if( (pgcit->pgci_srp[i].entry_id) == id) { pgcN = i + 1; #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: Found menu.\n"); #endif return pgcN; } } #ifdef TRACE fprintf(MSG_OUT, "libdvdnav: ** No such id/menu (0x%02x) entry PGC\n", id & 0x7f); for(i = 0; i < pgcit->nr_of_pgci_srp; i++) { if ( (pgcit->pgci_srp[i].entry_id & 0x80) == 0x80) { fprintf(MSG_OUT, "libdvdnav: Available menus: 0x%x\n", pgcit->pgci_srp[i].entry_id & 0x7f); } } #endif return 0; /* error */ } /* FIXME: we have a pgcN member in the vm's state now, so this should be obsolete */ static int get_PGCN(vm_t *vm) { pgcit_t *pgcit; int pgcN = 1; pgcit = get_PGCIT(vm); if (pgcit) { while(pgcN <= pgcit->nr_of_pgci_srp) { if(pgcit->pgci_srp[pgcN - 1].pgc == (vm->state).pgc) { assert((vm->state).pgcN == pgcN); return pgcN; } pgcN++; } } fprintf(MSG_OUT, "libdvdnav: get_PGCN failed. Was trying to find pgcN in domain %d\n", (vm->state).domain); return 0; /* error */ } static pgcit_t* get_MENU_PGCIT(vm_t *vm, ifo_handle_t *h, uint16_t lang) { int i; (void)vm; if(h == NULL || h->pgci_ut == NULL) { fprintf(MSG_OUT, "libdvdnav: *** pgci_ut handle is NULL ***\n"); return NULL; /* error? */ } i = 0; while(i < h->pgci_ut->nr_of_lus && h->pgci_ut->lu[i].lang_code != lang) i++; if(i == h->pgci_ut->nr_of_lus) { fprintf(MSG_OUT, "libdvdnav: Language '%c%c' not found, using '%c%c' instead\n", (char)(lang >> 8), (char)(lang & 0xff), (char)(h->pgci_ut->lu[0].lang_code >> 8), (char)(h->pgci_ut->lu[0].lang_code & 0xff)); fprintf(MSG_OUT, "libdvdnav: Menu Languages available: "); for(i = 0; i < h->pgci_ut->nr_of_lus; i++) { fprintf(MSG_OUT, "%c%c ", (char)(h->pgci_ut->lu[i].lang_code >> 8), (char)(h->pgci_ut->lu[i].lang_code & 0xff)); } fprintf(MSG_OUT, "\n"); i = 0; /* error? */ } return h->pgci_ut->lu[i].pgcit; } /* Uses state to decide what to return */ static pgcit_t* get_PGCIT(vm_t *vm) { pgcit_t *pgcit; switch ((vm->state).domain) { case VTS_DOMAIN: pgcit = vm->vtsi->vts_pgcit; break; case VTSM_DOMAIN: pgcit = get_MENU_PGCIT(vm, vm->vtsi, (vm->state).registers.SPRM[0]); break; case VMGM_DOMAIN: case FP_DOMAIN: pgcit = get_MENU_PGCIT(vm, vm->vmgi, (vm->state).registers.SPRM[0]); break; default: pgcit = NULL; assert(!"get_PGCIT(): invalid domain"); } return pgcit; } /* Debug functions */ #ifdef TRACE void vm_position_print(vm_t *vm, vm_position_t *position) { fprintf(MSG_OUT, "libdvdnav: But=%x Spu=%x Aud=%x Ang=%x Hop=%x vts=%x dom=%x cell=%x cell_restart=%x cell_start=%x still=%x block=%x\n", position->button, position->spu_channel, position->audio_channel, position->angle_channel, position->hop_channel, position->vts, position->domain, position->cell, position->cell_restart, position->cell_start, position->still, position->block); } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/libdvdnav/dvdnav_events.h����������������������������������������������������0000644�0001750�0001750�00000016730�14647725152�017611� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001 Rich Wareham <richwareham@users.sourceforge.net> * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * This header defines events and event types */ #ifndef DVDNAV_EVENTS_H_INCLUDED #define DVDNAV_EVENTS_H_INCLUDED #include "ifo_types.h" #include "dvd_reader.h" #include "nav_types.h" /* * DVDNAV_BLOCK_OK * * A regular data block from the DVD has been returned. * This one should be demuxed and decoded for playback. */ #define DVDNAV_BLOCK_OK 0 /* * DVDNAV_NOP * * Just ignore this. */ #define DVDNAV_NOP 1 /* * DVDNAV_STILL_FRAME * * We have reached a still frame. The player application should wait * the amount of time specified by the still's length while still handling * user input to make menus and other interactive stills work. * The last delivered frame should be kept showing. * Once the still has timed out, call dvdnav_skip_still(). * A length of 0xff means an infinite still which has to be skipped * indirectly by some user interaction. */ #define DVDNAV_STILL_FRAME 2 typedef struct { /* The length (in seconds) the still frame should be displayed for, * or 0xff if infinite. */ int length; } dvdnav_still_event_t; /* * DVDNAV_SPU_STREAM_CHANGE * * Inform the SPU decoding/overlaying engine to switch SPU channels. */ #define DVDNAV_SPU_STREAM_CHANGE 3 typedef struct { /* The physical (MPEG) stream number for widescreen SPU display. * Use this, if you blend the SPU on an anamorphic image before * unsqueezing it. */ int physical_wide; /* The physical (MPEG) stream number for letterboxed display. * Use this, if you blend the SPU on an anamorphic image after * unsqueezing it. */ int physical_letterbox; /* The physical (MPEG) stream number for pan&scan display. * Use this, if you blend the SPU on an anamorphic image after * unsqueezing it the pan&scan way. */ int physical_pan_scan; /* The logical (DVD) stream number. */ int logical; } dvdnav_spu_stream_change_event_t; /* * DVDNAV_AUDIO_STREAM_CHANGE * * Inform the audio decoder to switch channels. */ #define DVDNAV_AUDIO_STREAM_CHANGE 4 typedef struct { /* The physical (MPEG) stream number. */ int physical; /* The logical (DVD) stream number. */ int logical; } dvdnav_audio_stream_change_event_t; /* * DVDNAV_VTS_CHANGE * * Some status information like video aspect and video scale permissions do * not change inside a VTS. Therefore this event can be used to query such * information only when necessary and update the decoding/displaying * accordingly. */ #define DVDNAV_VTS_CHANGE 5 typedef struct { int old_vtsN; /* the old VTS number */ dvd_read_domain_t old_domain; /* the old domain */ int new_vtsN; /* the new VTS number */ dvd_read_domain_t new_domain; /* the new domain */ } dvdnav_vts_change_event_t; /* * DVDNAV_CELL_CHANGE * * Some status information like the current Title and Part numbers do not * change inside a cell. Therefore this event can be used to query such * information only when necessary and update the decoding/displaying * accordingly. * Some useful information for accurate time display is also reported * together with this event. */ #define DVDNAV_CELL_CHANGE 6 typedef struct { int cellN; /* the new cell number */ int pgN; /* the current program number */ int64_t cell_length; /* the length of the current cell in PTS ticks */ int64_t pg_length; /* the length of the current program in PTS ticks */ int64_t pgc_length; /* the length of the current program chain in PTS ticks */ int64_t cell_start; /* the start time of the current cell relatively to the PGC in PTS ticks */ int64_t pg_start; /* the start time of the current PG relatively to the PGC in PTS ticks */ } dvdnav_cell_change_event_t; /* * DVDNAV_NAV_PACKET * * NAV packets are useful for various purposes. They define the button * highlight areas and VM commands of DVD menus, so they should in any * case be sent to the SPU decoder/overlaying engine for the menus to work. * NAV packets also provide a way to detect PTS discontinuities, because * they carry the start and end PTS values for the current VOBU. * (pci.vobu_s_ptm and pci.vobu_e_ptm) Whenever the start PTS of the * current NAV does not match the end PTS of the previous NAV, a PTS * discontinuity has occured. * NAV packets can also be used for time display, because they are * timestamped relatively to the current Cell. */ #define DVDNAV_NAV_PACKET 7 /* * DVDNAV_STOP * * Applications should end playback here. A subsequent dvdnav_get_next_block() * call will restart the VM from the beginning of the DVD. */ #define DVDNAV_STOP 8 /* * DVDNAV_HIGHLIGHT * * The current button highlight changed. Inform the overlaying engine to * highlight a different button. Please note, that at the moment only mode 1 * highlights are reported this way. That means, when the button highlight * has been moved around by some function call, you will receive an event * telling you the new button. But when a button gets activated, you have * to handle the mode 2 highlighting (that is some different colour the * button turns to on activation) in your application. */ #define DVDNAV_HIGHLIGHT 9 typedef struct { /* highlight mode: 0 - hide, 1 - show, 2 - activate, currently always 1 */ int display; /* FIXME: these fields are currently not set */ uint32_t palette; /* The CLUT entries for the highlight palette (4-bits per entry -> 4 entries) */ uint16_t sx,sy,ex,ey; /* The start/end x,y positions */ uint32_t pts; /* Highlight PTS to match with SPU */ /* button number for the SPU decoder/overlaying engine */ uint32_t buttonN; } dvdnav_highlight_event_t; /* * DVDNAV_SPU_CLUT_CHANGE * * Inform the SPU decoder/overlaying engine to update its colour lookup table. * The CLUT is given as 16 uint32_t's in the buffer. */ #define DVDNAV_SPU_CLUT_CHANGE 10 /* * DVDNAV_HOP_CHANNEL * * A non-seamless operation has been performed. Applications can drop all * their internal fifo's content, which will speed up the response. */ #define DVDNAV_HOP_CHANNEL 12 /* * DVDNAV_WAIT * * We have reached a point in DVD playback, where timing is critical. * Player application with internal fifos can introduce state * inconsistencies, because libdvdnav is always the fifo's length * ahead in the stream compared to what the application sees. * Such applications should wait until their fifos are empty * when they receive this type of event. * Once this is achieved, call dvdnav_skip_wait(). */ #define DVDNAV_WAIT 13 #endif /* DVDNAV_EVENTS_H_INCLUDED */ ����������������������������������������xine-lib-1.2/src/input/libdvdnav/read_cache.c�������������������������������������������������������0000644�0001750�0001750�00000025733�14647725152�016777� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000 Rich Wareham <richwareham@users.sourceforge.net> * 2001-2004 the dvdnav project * * This file is part of libdvdnav, a DVD navigation library. * * libdvdnav is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libdvdnav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ /* * There was a multithreaded read ahead cache in here for some time, but * it had only been used for a short time. If you want to have a look at it, * search the CVS attic. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "dvdnav.h" #include "dvdnav_internal.h" #include "read_cache.h" #include <sys/time.h> #include <time.h> #define READ_CACHE_CHUNKS 10 /* all cache chunks must be memory aligned to allow use of raw devices */ #define ALIGNMENT 2048 #define READ_AHEAD_SIZE_MIN 4 #define READ_AHEAD_SIZE_MAX 512 typedef struct read_cache_chunk_s { uint8_t *cache_buffer; uint8_t *cache_buffer_base; /* used in malloc and free for alignment */ int32_t cache_start_sector; /* -1 means cache invalid */ int32_t cache_read_count; /* this many sectors are already read */ size_t cache_block_count; /* this many sectors will go in this chunk */ size_t cache_malloc_size; int cache_valid; int usage_count; /* counts how many buffers where issued from this chunk */ } read_cache_chunk_t; struct read_cache_s { read_cache_chunk_t chunk[READ_CACHE_CHUNKS]; int current; int freeing; /* is set to one when we are about to dispose the cache */ uint32_t read_ahead_size; int read_ahead_incr; int last_sector; pthread_mutex_t lock; /* Bit of strange cross-linking going on here :) -- Gotta love C :) */ dvdnav_t *dvd_self; }; /* #define READ_CACHE_TRACE 0 */ #ifdef __GNUC__ # if READ_CACHE_TRACE # define dprintf(fmt, args...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt, __func__ , ## args) # else # define dprintf(fmt, args...) /* Nowt */ # endif #else # if READ_CACHE_TRACE # define dprintf(fmt, ...) fprintf(MSG_OUT, "libdvdnav: %s: "fmt, __func__ , __VA_ARGS__) # else #ifdef _MSC_VER # define dprintf(fmt, str) /* Nowt */ #else # define dprintf(fmt, ...) /* Nowt */ #endif /* _MSC_VER */ # endif #endif read_cache_t *dvdnav_read_cache_new(dvdnav_t* dvd_self) { read_cache_t *self; int i; self = (read_cache_t *)malloc(sizeof(read_cache_t)); if(self) { self->current = 0; self->freeing = 0; self->dvd_self = dvd_self; self->last_sector = 0; self->read_ahead_size = READ_AHEAD_SIZE_MIN; self->read_ahead_incr = 0; pthread_mutex_init(&self->lock, NULL); dvdnav_read_cache_clear(self); for (i = 0; i < READ_CACHE_CHUNKS; i++) { self->chunk[i].cache_buffer = NULL; self->chunk[i].usage_count = 0; } } return self; } void dvdnav_read_cache_free(read_cache_t* self) { dvdnav_t *tmp; int i; pthread_mutex_lock(&self->lock); self->freeing = 1; for (i = 0; i < READ_CACHE_CHUNKS; i++) if (self->chunk[i].cache_buffer && self->chunk[i].usage_count == 0) { free(self->chunk[i].cache_buffer_base); self->chunk[i].cache_buffer = NULL; } pthread_mutex_unlock(&self->lock); for (i = 0; i < READ_CACHE_CHUNKS; i++) if (self->chunk[i].cache_buffer) return; /* all buffers returned, free everything */ tmp = self->dvd_self; pthread_mutex_destroy(&self->lock); free(self); free(tmp); } /* This function MUST be called whenever self->file changes. */ void dvdnav_read_cache_clear(read_cache_t *self) { int i; if(!self) return; pthread_mutex_lock(&self->lock); for (i = 0; i < READ_CACHE_CHUNKS; i++) self->chunk[i].cache_valid = 0; pthread_mutex_unlock(&self->lock); } /* This function is called just after reading the NAV packet. */ void dvdnav_pre_cache_blocks(read_cache_t *self, int sector, size_t block_count) { int i, use; if(!self) return; if(!self->dvd_self->use_read_ahead) return; pthread_mutex_lock(&self->lock); /* find a free cache chunk that best fits the required size */ use = -1; for (i = 0; i < READ_CACHE_CHUNKS; i++) if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer && self->chunk[i].cache_malloc_size >= block_count && (use == -1 || self->chunk[use].cache_malloc_size > self->chunk[i].cache_malloc_size)) use = i; if (use == -1) { /* we haven't found a cache chunk, so we try to reallocate an existing one */ for (i = 0; i < READ_CACHE_CHUNKS; i++) if (self->chunk[i].usage_count == 0 && self->chunk[i].cache_buffer && (use == -1 || self->chunk[use].cache_malloc_size < self->chunk[i].cache_malloc_size)) use = i; if (use >= 0) { self->chunk[use].cache_buffer_base = realloc(self->chunk[use].cache_buffer_base, block_count * DVD_VIDEO_LB_LEN + ALIGNMENT); self->chunk[use].cache_buffer = (uint8_t *)(((uintptr_t)self->chunk[use].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT); dprintf("pre_cache DVD read realloc happened\n"); self->chunk[use].cache_malloc_size = block_count; } else { /* we still haven't found a cache chunk, let's allocate a new one */ for (i = 0; i < READ_CACHE_CHUNKS; i++) if (!self->chunk[i].cache_buffer) { use = i; break; } if (use >= 0) { /* We start with a sensible figure for the first malloc of 500 blocks. * Some DVDs I have seen venture to 450 blocks. * This is so that fewer realloc's happen if at all. */ self->chunk[i].cache_buffer_base = malloc((block_count > 500 ? block_count : 500) * DVD_VIDEO_LB_LEN + ALIGNMENT); self->chunk[i].cache_buffer = (uint8_t *)(((uintptr_t)self->chunk[i].cache_buffer_base & ~((uintptr_t)(ALIGNMENT - 1))) + ALIGNMENT); self->chunk[i].cache_malloc_size = block_count > 500 ? block_count : 500; dprintf("pre_cache DVD read malloc %d blocks\n", (block_count > 500 ? block_count : 500 )); } } } if (use >= 0) { self->chunk[use].cache_start_sector = sector; self->chunk[use].cache_block_count = block_count; self->chunk[use].cache_read_count = 0; self->chunk[use].cache_valid = 1; self->current = use; } else { dprintf("pre_caching was impossible, no cache chunk available\n"); } pthread_mutex_unlock(&self->lock); } int dvdnav_read_cache_block(read_cache_t *self, int sector, size_t block_count, uint8_t **buf) { int i, use; int start; int size; int incr; uint8_t *read_ahead_buf; int32_t res; if(!self) return 0; use = -1; if(self->dvd_self->use_read_ahead) { /* first check, if sector is in current chunk */ read_cache_chunk_t cur = self->chunk[self->current]; if (cur.cache_valid && sector >= cur.cache_start_sector && sector <= (cur.cache_start_sector + cur.cache_read_count) && sector + block_count <= cur.cache_start_sector + cur.cache_block_count) use = self->current; else for (i = 0; i < READ_CACHE_CHUNKS; i++) if (self->chunk[i].cache_valid && sector >= self->chunk[i].cache_start_sector && sector <= (self->chunk[i].cache_start_sector + self->chunk[i].cache_read_count) && sector + block_count <= self->chunk[i].cache_start_sector + self->chunk[i].cache_block_count) use = i; } if (use >= 0) { read_cache_chunk_t *chunk; /* Increment read-ahead size if sector follows the last sector */ if (sector == (self->last_sector + 1)) { if (self->read_ahead_incr < READ_AHEAD_SIZE_MAX) self->read_ahead_incr++; } else { self->read_ahead_size = READ_AHEAD_SIZE_MIN; self->read_ahead_incr = 0; } self->last_sector = sector; /* The following resources need to be protected by a mutex : * self->chunk[*].cache_buffer * self->chunk[*].cache_malloc_size * self->chunk[*].usage_count */ pthread_mutex_lock(&self->lock); chunk = &self->chunk[use]; read_ahead_buf = chunk->cache_buffer + chunk->cache_read_count * DVD_VIDEO_LB_LEN; *buf = chunk->cache_buffer + (sector - chunk->cache_start_sector) * DVD_VIDEO_LB_LEN; chunk->usage_count++; pthread_mutex_unlock(&self->lock); dprintf("libdvdnav: sector=%d, start_sector=%d, last_sector=%d\n", sector, chunk->cache_start_sector, chunk->cache_start_sector + chunk->cache_block_count); /* read_ahead_size */ incr = self->read_ahead_incr >> 1; if ((self->read_ahead_size + incr) > READ_AHEAD_SIZE_MAX) { self->read_ahead_size = READ_AHEAD_SIZE_MAX; } else { self->read_ahead_size += incr; } /* real read size */ start = chunk->cache_start_sector + chunk->cache_read_count; if (chunk->cache_read_count + self->read_ahead_size > chunk->cache_block_count) { size = chunk->cache_block_count - chunk->cache_read_count; } else { size = self->read_ahead_size; /* ensure that the sector we want will be read */ if (sector >= chunk->cache_start_sector + chunk->cache_read_count + size) size = sector - chunk->cache_start_sector - chunk->cache_read_count; } dprintf("libdvdnav: read_ahead_size=%d, size=%d\n", self->read_ahead_size, size); if (size) chunk->cache_read_count += DVDReadBlocks(self->dvd_self->file, start, size, read_ahead_buf); res = DVD_VIDEO_LB_LEN * block_count; } else { if (self->dvd_self->use_read_ahead) { dprintf("cache miss on sector %d\n", sector); } res = DVDReadBlocks(self->dvd_self->file, sector, block_count, *buf) * DVD_VIDEO_LB_LEN; } return res; } dvdnav_status_t dvdnav_free_cache_block(dvdnav_t *self, unsigned char *buf) { read_cache_t *cache; int i; if (!self) return DVDNAV_STATUS_ERR; cache = self->cache; if (!cache) return DVDNAV_STATUS_ERR; pthread_mutex_lock(&cache->lock); for (i = 0; i < READ_CACHE_CHUNKS; i++) { if (cache->chunk[i].cache_buffer && buf >= cache->chunk[i].cache_buffer && buf < cache->chunk[i].cache_buffer + cache->chunk[i].cache_malloc_size * DVD_VIDEO_LB_LEN) { cache->chunk[i].usage_count--; } } pthread_mutex_unlock(&cache->lock); if (cache->freeing) /* when we want to dispose the cache, try freeing it now */ dvdnav_read_cache_free(cache); return DVDNAV_STATUS_OK; } �������������������������������������xine-lib-1.2/src/input/input_mms.c������������������������������������������������������������������0000644�0001750�0001750�00000027232�14647725152�014777� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mms input plugin based on work from major mms */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <unistd.h> #include <stdio.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define LOG_MODULE "input_mms" #define LOG_VERBOSE /* #define LOG */ #include "bswap.h" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "mms.h" #include "mmsh.h" #include "net_buf_ctrl.h" #include "input_helper.h" #define LOG_MODULE "input_mms" #define PROTOCOL_UNDEFINED 0 #define PROTOCOL_MMST 1 #define PROTOCOL_MMSH 2 /* network bandwidth */ static const uint32_t mms_bandwidths[]={14400,19200,28800,33600,34430,57600, 115200,262200,393216,524300,1544000,10485800}; #define NUM_BANDWIDTHS (sizeof (mms_bandwidths) / sizeof (mms_bandwidths[0])) static const char *const mms_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)", "28.8 Kbps (Modem)", "33.6 Kbps (Modem)", "34.4 Kbps (Modem)", "57.6 Kbps (Modem)", "115.2 Kbps (ISDN)", "262.2 Kbps (Cable/DSL)", "393.2 Kbps (Cable/DSL)","524.3 Kbps (Cable/DSL)", "1.5 Mbps (T1)", "10.5 Mbps (LAN)", NULL}; /* connection methods */ static const char *const mms_protocol_strs[]={"auto", "TCP", "HTTP", NULL}; typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; mms_t *mms; mmsh_t *mmsh; char *mrl; nbc_t *nbc; char scratch[1025]; int protocol; /* mmst or mmsh */ } mms_input_plugin_t; typedef struct { input_class_t input_class; int protocol; /* autoprobe, mmst or mmsh */ int bandwidth; xine_t *xine; } mms_input_class_t; static off_t mms_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; off_t n = 0; lprintf ("mms_plugin_read: %"PRId64" bytes ...\n", len); switch (this->protocol) { case PROTOCOL_MMST: n = mms_read (this->mms, buf, len); break; case PROTOCOL_MMSH: n = mmsh_read (this->mmsh, buf, len); break; } return n; } static off_t mms_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; off_t curpos = 0; lprintf ("mms_plugin_seek: %"PRId64" offset, %d origin...\n", offset, origin); switch (this->protocol) { case PROTOCOL_MMST: curpos = mms_get_current_pos (this->mms); break; case PROTOCOL_MMSH: curpos = mmsh_get_current_pos (this->mmsh); break; } return _x_input_seek_preview(this_gen, offset, origin, &curpos, -1, -1); } static off_t mms_plugin_seek_time (input_plugin_t *this_gen, int time_offset, int origin) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; off_t curpos = 0; lprintf ("seek_time %d msec, origin %d\n", time_offset, origin); switch (this->protocol) { case PROTOCOL_MMST: if (origin == SEEK_SET) mms_set_start_time (this->mms, time_offset); curpos = mms_get_current_pos (this->mms); break; case PROTOCOL_MMSH: if (origin == SEEK_SET) mmsh_set_start_time (this->mmsh, time_offset); curpos = mmsh_get_current_pos (this->mmsh); break; } return curpos; } static off_t mms_plugin_get_length (input_plugin_t *this_gen) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; off_t length = 0; if (!this->mms) return 0; switch (this->protocol) { case PROTOCOL_MMST: length = mms_get_length (this->mms); break; case PROTOCOL_MMSH: length = mmsh_get_length (this->mmsh); break; } lprintf ("length is %"PRId64"\n", length); return length; } static off_t mms_plugin_get_current_pos (input_plugin_t *this_gen){ mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; off_t curpos = 0; switch (this->protocol) { case PROTOCOL_MMST: curpos = mms_get_current_pos(this->mms); break; case PROTOCOL_MMSH: curpos = mmsh_get_current_pos(this->mmsh); break; } return curpos; } static void mms_plugin_dispose (input_plugin_t *this_gen) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; if (this->mms) mms_close (this->mms); if (this->mmsh) mmsh_close (this->mmsh); this->mms = NULL; this->mmsh = NULL; if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } free(this->mrl); free (this); } static const char* mms_plugin_get_mrl (input_plugin_t *this_gen) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; return this->mrl; } static int mms_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: switch (this->protocol) { case PROTOCOL_MMST: return mms_peek_header (this->mms, data, MAX_PREVIEW_SIZE); break; case PROTOCOL_MMSH: return mmsh_peek_header (this->mmsh, data, MAX_PREVIEW_SIZE); break; } break; default: return INPUT_OPTIONAL_UNSUPPORTED; break; } return INPUT_OPTIONAL_UNSUPPORTED; } static void bandwidth_changed_cb (void *this_gen, xine_cfg_entry_t *entry) { mms_input_class_t *class = (mms_input_class_t*) this_gen; lprintf ("bandwidth_changed_cb %d\n", entry->num_value); if (class && (entry->num_value >= 0) && (entry->num_value < (int)NUM_BANDWIDTHS)) class->bandwidth = mms_bandwidths[entry->num_value]; } static void protocol_changed_cb (void *this_gen, xine_cfg_entry_t *entry) { mms_input_class_t *class = (mms_input_class_t*) this_gen; lprintf ("protocol_changed_cb %d\n", entry->num_value); if (!class) return; class->protocol = entry->num_value; } static int mms_plugin_open (input_plugin_t *this_gen) { mms_input_plugin_t *this = (mms_input_plugin_t *) this_gen; mms_input_class_t *class = (mms_input_class_t *) this->input_plugin.input_class; mms_t *mms = NULL; mmsh_t *mmsh = NULL; switch (this->protocol) { case PROTOCOL_UNDEFINED: mms = mms_connect (this->stream, this->mrl, class->bandwidth); if (mms) { this->protocol = PROTOCOL_MMST; } else { mmsh = mmsh_connect (this->stream, this->mrl, class->bandwidth); this->protocol = PROTOCOL_MMSH; } break; case PROTOCOL_MMST: mms = mms_connect (this->stream, this->mrl, class->bandwidth); break; case PROTOCOL_MMSH: mmsh = mmsh_connect (this->stream, this->mrl, class->bandwidth); break; } if (!mms && !mmsh) { return 0; } this->mms = mms; this->mmsh = mmsh; return 1; } static input_plugin_t *mms_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { mms_input_class_t *cls = (mms_input_class_t *) cls_gen; mms_input_plugin_t *this; xine_cfg_entry_t bandwidth_entry; int protocol; lprintf ("trying to open '%s'\n", data); if (!strncasecmp (data, "mms://", 6)) { protocol = cls->protocol; } else if (!strncasecmp (data, "mmst://", 7)) { protocol = PROTOCOL_MMST; } else if (!strncasecmp (data, "mmsh://", 7)) { protocol = PROTOCOL_MMSH; } else { return NULL; } this = calloc(1, sizeof (mms_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->mms = NULL; this->mmsh = NULL; this->protocol = protocol; this->mrl = strdup(data); this->nbc = nbc_init (this->stream); if (xine_config_lookup_entry (stream->xine, "media.network.bandwidth", &bandwidth_entry)) { bandwidth_changed_cb(cls, &bandwidth_entry); } this->input_plugin.open = mms_plugin_open; this->input_plugin.get_capabilities = _x_input_get_capabilities_preview; this->input_plugin.read = mms_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = mms_plugin_seek; this->input_plugin.seek_time = mms_plugin_seek_time; this->input_plugin.get_current_pos = mms_plugin_get_current_pos; this->input_plugin.get_length = mms_plugin_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = mms_plugin_get_mrl; this->input_plugin.dispose = mms_plugin_dispose; this->input_plugin.get_optional_data = mms_plugin_get_optional_data; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * mms input plugin class stuff */ static void mms_class_dispose (input_class_t *this_gen) { mms_input_class_t *this = (mms_input_class_t *) this_gen; this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, this, sizeof (*this)); free (this); } static void *init_class (xine_t *xine, const void *data) { mms_input_class_t *this; int i; (void)data; this = calloc(1, sizeof (mms_input_class_t)); if (!this) return NULL; this->xine = xine; this->input_class.get_instance = mms_class_get_instance; this->input_class.identifier = "mms"; this->input_class.description = N_("mms streaming input plugin"); this->input_class.get_dir = NULL; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = mms_class_dispose; this->input_class.eject_media = NULL; i = xine->config->register_enum (xine->config, "media.network.bandwidth", 10, (char **)mms_bandwidth_strs, _("network bandwidth"), _("Specify the bandwidth of your internet connection here. " "This will be used when streaming servers offer different versions " "with different bandwidth requirements of the same stream."), 0, bandwidth_changed_cb, (void*) this); this->bandwidth = mms_bandwidths[((i >= 0) && (i < (int)NUM_BANDWIDTHS)) ? i : 10]; this->protocol = xine->config->register_enum (xine->config, "media.network.mms_protocol", 0, (char **)mms_protocol_strs, _("MMS protocol"), _("Select the protocol to encapsulate MMS.\nTCP is better but you may need HTTP behind a firewall."), 20, protocol_changed_cb, (void*)this); return this; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "mms", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_nfs.c������������������������������������������������������������������0000644�0001750�0001750�00000035246�14647725152�014775� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <errno.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <nfsc/libnfs.h> #include <nfsc/libnfs-raw-mount.h> #define LOG_MODULE "input_nfs" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "input_helper.h" typedef struct { input_plugin_t input_plugin; xine_t *xine; xine_stream_t *stream; char *mrl; off_t curpos; off_t file_size; struct nfs_context *nfs; struct nfs_url *url; struct nfsfh *nfsfh; } nfs_input_plugin_t; #define PLUGIN(ptr) xine_container_of(ptr, nfs_input_plugin_t, input_plugin) typedef struct { input_class_t input_class; xine_t *xine; xine_mrl_t **mrls; } nfs_input_class_t; #define CLASS(ptr) xine_container_of(ptr, nfs_input_class_t, input_class) /* * util */ static int _parse_url(nfs_input_plugin_t *this, int full) { if (!this->nfs) { this->nfs = nfs_init_context(); if (!this->nfs) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error initializing nfs context\n"); return -1; } } if (!this->url) { if (full) { this->url = nfs_parse_url_full(this->nfs, this->mrl); } else { this->url = nfs_parse_url_dir(this->nfs, this->mrl); if (!this->url) { this->url = nfs_parse_url_incomplete(this->nfs, this->mrl); } } if (!this->url) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "invalid nfs url '%s': %s\n", this->mrl, nfs_get_error(this->nfs)); return -1; } } return 0; } static int _mount(nfs_input_plugin_t *this) { if (_parse_url(this, 1) < 0) return -1; if (nfs_mount(this->nfs, this->url->server, this->url->path)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "mounting '%s:%s' failed: %s\n", this->url->server, this->url->path, nfs_get_error(this->nfs)); return -1; } return 0; } /* * xine plugin */ static off_t _read (input_plugin_t *this_gen, void *buf_gen, off_t len) { nfs_input_plugin_t *this = PLUGIN(this_gen); uint8_t *buf = buf_gen; off_t got = 0; int rc; while (got < len) { rc = nfs_read(this->nfs, this->nfsfh, len - got, buf + got); if (rc <= 0) { if (errno == EAGAIN || errno == EINTR) continue; xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "NFS read failed: %d: %s\n", rc, nfs_get_error(this->nfs)); if (got) break; return rc; } got += rc; if (_x_action_pending(this->stream)) { errno = EINTR; if (got) break; return -1; } } this->curpos += got; return got; } static off_t _get_length (input_plugin_t *this_gen) { nfs_input_plugin_t *this = PLUGIN(this_gen); struct nfs_stat_64 st; if (this->file_size) return this->file_size; if (nfs_stat64(this->nfs, this->url->file, &st)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "stat(%s) failed: %s\n", this->url->file, nfs_get_error(this->nfs)); return -1; } this->file_size = st.nfs_size; return this->file_size; } static off_t _get_current_pos (input_plugin_t *this_gen) { nfs_input_plugin_t *this = PLUGIN(this_gen); return this->curpos; } static off_t _seek (input_plugin_t *this_gen, off_t offset, int origin) { nfs_input_plugin_t *this = PLUGIN(this_gen); uint64_t pos = this->curpos; if (nfs_lseek(this->nfs, this->nfsfh, offset, origin, &pos) < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "seek failed: %s\n", nfs_get_error(this->nfs)); return -1; } this->curpos = pos; return this->curpos; } static const char *_get_mrl (input_plugin_t *this_gen) { nfs_input_plugin_t *this = PLUGIN(this_gen); return this->mrl; } static void _dispose (input_plugin_t *this_gen) { nfs_input_plugin_t *this = PLUGIN(this_gen); if (this->nfsfh) { nfs_close(this->nfs, this->nfsfh); } if (this->url) { nfs_destroy_url(this->url); } if (this->nfs) { nfs_destroy_context(this->nfs); } _x_freep (&this->mrl); free (this_gen); } static int _open (input_plugin_t *this_gen) { nfs_input_plugin_t *this = PLUGIN(this_gen); this->curpos = 0; if (_mount(this) < 0) return -1; if (nfs_open(this->nfs, this->url->file, O_RDONLY, &this->nfsfh)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error opening '%s': %s\n", this->mrl, nfs_get_error(this->nfs)); return -1; } return 1; } static input_plugin_t *_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { nfs_input_class_t *class = (nfs_input_class_t *)cls_gen; nfs_input_plugin_t *this; if (strncasecmp (mrl, "nfs://", 6)) { return NULL; } this = calloc(1, sizeof(*this)); if (!this) { return NULL; } this->mrl = strdup(mrl); if (!this->mrl) { free(this); return NULL; } this->stream = stream; this->xine = class->xine; this->curpos = 0; this->input_plugin.open = _open; this->input_plugin.get_capabilities = _x_input_get_capabilities_seekable; this->input_plugin.read = _read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = _seek; this->input_plugin.get_current_pos = _get_current_pos; this->input_plugin.get_length = _get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = _get_mrl; this->input_plugin.get_optional_data = _x_input_default_get_optional_data; this->input_plugin.dispose = _dispose; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * server discovery */ static xine_mrl_t **_get_servers(xine_t *xine, int *nFiles) { struct nfs_server_list *srvrs, *srv; xine_mrl_t **m, **mrls; size_t n; srvrs = nfs_find_local_servers(); /* count servers */ for (n = 0, srv = srvrs; srv; srv = srv->next, n++) {} m = mrls = _x_input_get_default_server_mrls(xine->config, "nfs://", nFiles); m = _x_input_realloc_mrls(&mrls, n + *nFiles); if (!m) goto out; m += *nFiles; n += *nFiles; for(srv = srvrs; srv; srv = srv->next) { (*m)->origin = strdup("nfs://"); (*m)->mrl = _x_asprintf("nfs://%s", srv->addr); (*m)->type = mrl_net | mrl_file | mrl_file_directory; xprintf(xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "found nfs server: '%s'\n", (*m)->mrl); m++; } *nFiles = n; if (!n) _x_input_free_mrls(&mrls); out: if (srvrs) free_nfs_srvr_list(srvrs); return mrls; } /* * exports listing */ static xine_mrl_t **_get_exports(xine_t *xine, const char *server, int *nFiles) { struct exportnode *exports, *export; xine_mrl_t **m, **mrls; size_t n; exports = mount_getexports(server); if (!exports) { xprintf(xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "error listing exports from '%s'\n", server); /* fall thru: return link to servers list ("..") */ } /* count exports */ for (n = 0, export = exports; export; export = export->ex_next, n++) {} m = mrls = _x_input_alloc_mrls(n + 1); if (!m) goto out; /* Add '..' entry */ (*m)->type = mrl_net | mrl_file | mrl_file_directory; (*m)->origin = _x_asprintf("nfs://%s", server); (*m)->mrl = _x_asprintf("nfs://%s/..", server); (*m)->link = strdup("nfs://"); m++; /* add exports */ for (export = exports; export; export = export->ex_next) { (*m)->origin = _x_asprintf("nfs://%s", server); (*m)->mrl = _x_asprintf("nfs://%s%s", server, export->ex_dir); (*m)->type = mrl_net | mrl_file | mrl_file_directory; xprintf(xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "found export: '%s'\n", (*m)->mrl); m++; } *nFiles = n + 1; out: if (exports) mount_free_export_list(exports); return mrls; } static int _is_export(const char *server, const char *path) { struct exportnode *exports, *export; exports = mount_getexports(server); if (exports) { for (export = exports; export; export = export->ex_next) { if (!strcmp(path, export->ex_dir)) { mount_free_export_list(exports); return 1; } } mount_free_export_list(exports); } return 0; } /* * directory listing */ static xine_mrl_t **_get_files(nfs_input_plugin_t *this, int *nFiles) { struct nfs_stat_64 st; struct nfsdir *dir = NULL; struct nfsdirent *nfsdirent; xine_mrl_t **mrls; size_t n = 0; size_t mrls_size = 64; int show_hidden_files; mrls = _x_input_alloc_mrls(mrls_size); if (!mrls) goto out; /* add link to previous level */ mrls[n]->type = mrl_net | mrl_file | mrl_file_directory; if (_is_export(this->url->server, this->url->path)) { /* export can be multiple directory levels. xine-ui doesn't handle this well: - it crashes if origin is longer than target mrl. - it can't handle multiple ..'s either. So, we create a fake mrl ... */ /* XXX: fix xine_mrl_t to allow "title" that will be shown instead of mrl-origin ? */ mrls[n]->origin = _x_asprintf("nfs://%s/up", this->url->server); mrls[n]->mrl = _x_asprintf("nfs://%s/up/..", this->url->server); } else { mrls[n]->origin = _x_asprintf("nfs://%s%s", this->url->server, this->url->path); mrls[n]->mrl = _x_asprintf("nfs://%s%s/..", this->url->server, this->url->path); } n++; if (_mount(this) < 0) { goto out; } if (nfs_opendir(this->nfs, "/", &dir)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "error opening directory '%s' from '%s:%s': %s\n", this->url->file, this->url->server, this->url->path, nfs_get_error(this->nfs)); goto out; } show_hidden_files = _x_input_get_show_hidden_files(this->xine->config); /* read directory */ while ((nfsdirent = nfs_readdir(this->nfs, dir)) != NULL) { if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) continue; if (!show_hidden_files && nfsdirent->name[0] == '.') continue; if (nfs_stat64(this->nfs, nfsdirent->name, &st)) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "stat '%s' from '%s:%s' failed: %s\n", nfsdirent->name, this->url->server, this->url->path, nfs_get_error(this->nfs)); continue; } if (n >= mrls_size) { mrls_size = mrls_size ? 2*mrls_size : 100; if (!(_x_input_realloc_mrls(&mrls, mrls_size))) { xprintf(this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "out of memory while listing directory '%s' from '%s:%s\n", this->url->file, this->url->server, this->url->path); goto out; } } switch (st.nfs_mode & S_IFMT) { case S_IFREG: mrls[n]->type = mrl_net | mrl_file | mrl_file_normal; break; case S_IFLNK: mrls[n]->type = mrl_net | mrl_file | mrl_file_symlink; break; case S_IFDIR: mrls[n]->type = mrl_net | mrl_file | mrl_file_directory; break; case S_IFCHR: mrls[n]->type = mrl_net | mrl_file | mrl_file_chardev; break; case S_IFBLK: mrls[n]->type = mrl_net | mrl_file | mrl_file_blockdev; break; default: mrls[n]->type = mrl_net; break; } mrls[n]->origin = _x_asprintf("nfs://%s%s", this->url->server, this->url->path); mrls[n]->mrl = _x_asprintf("nfs://%s%s/%s", this->url->server, this->url->path, nfsdirent->name); n++; } out: if (dir) { nfs_closedir(this->nfs, dir); } *nFiles = n; return mrls; } /* * plugin class */ static xine_mrl_t **_get_dir (input_class_t *this_gen, const char *filename, int *nFiles) { nfs_input_class_t *this = CLASS(this_gen); input_plugin_t *input_gen; nfs_input_plugin_t *input = NULL; *nFiles = 0; _x_input_free_mrls(&this->mrls); if (!filename || !strcmp(filename, "nfs:/")) { this->mrls = _get_servers(this->xine, nFiles); goto out; } input_gen = _get_instance(this_gen, NULL, filename); if (!input_gen) { goto fail; } input = PLUGIN(input_gen); if (_parse_url(input, 0) < 0) { goto fail; } if (!input->url->server) { this->mrls = _get_servers(this->xine, nFiles); } else if (!input->url->path) { this->mrls = _get_exports(this->xine, input->url->server, nFiles); } else { this->mrls = _get_files(input, nFiles); } out: if (*nFiles > 2) _x_input_sort_mrls(this->mrls + 1, *nFiles - 1); fail: if (input) input->input_plugin.dispose(&input->input_plugin); return this->mrls; } static void _dispose_class (input_class_t *this_gen) { nfs_input_class_t *this = CLASS(this_gen); _x_input_free_mrls(&this->mrls); free(this_gen); } static void *nfs_init_class(xine_t *xine, const void *data) { nfs_input_class_t *this; (void)data; this = calloc(1, sizeof(*this)); if (!this) return NULL; this->xine = xine; this->input_class.get_instance = _get_instance; this->input_class.description = N_("Network File System (NFS) input plugin"); this->input_class.identifier = "NFS"; this->input_class.get_dir = _get_dir; this->input_class.get_autoplay_list = NULL; this->input_class.dispose = _dispose_class; this->input_class.eject_media = NULL; _x_input_register_show_hidden_files(xine->config); return this; } /* * exported plugin catalog entry */ static const input_info_t input_info_nfs = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT, 18, "NFS", XINE_VERSION_CODE, &input_info_nfs, nfs_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_pnm.c������������������������������������������������������������������0000644�0001750�0001750�00000014016�14647725152�014771� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * pnm input plugin by joschka */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <unistd.h> #include <stdio.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #define LOG_MODULE "input_pnm" #define LOG_VERBOSE /* #define LOG */ #include "bswap.h" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "pnm.h" #include "net_buf_ctrl.h" #include "input_helper.h" #include "group_network.h" #define BUFSIZE 4096 typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; pnm_t *pnm; char *mrl; off_t curpos; nbc_t *nbc; char scratch[BUFSIZE]; } pnm_input_plugin_t; static off_t pnm_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; off_t n; lprintf ("pnm_plugin_read: %"PRId64" bytes ...\n", len); n = pnm_read (this->pnm, buf, len); if (n >= 0) this->curpos += n; return n; } static off_t pnm_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_pnm: seek %" PRIdMAX " bytes, origin %d\n", (intmax_t)offset, origin); /* only realtive forward-seeking is implemented */ return _x_input_seek_preview(this_gen, offset, origin, &this->curpos, -1, -1); } static off_t pnm_plugin_get_length (input_plugin_t *this_gen) { /* pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; off_t length; */ (void)this_gen; return -1; } static uint32_t pnm_plugin_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_PREVIEW | INPUT_CAP_RIP_FORBIDDEN; } static off_t pnm_plugin_get_current_pos (input_plugin_t *this_gen){ pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; /* printf ("current pos is %"PRId64"\n", this->curpos); */ return this->curpos; } static void pnm_plugin_dispose (input_plugin_t *this_gen) { pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; if (this->pnm) { pnm_close (this->pnm); this->pnm = NULL; } if (this->nbc) { nbc_close (this->nbc); this->nbc = NULL; } if(this->mrl) free(this->mrl); free (this); } static const char* pnm_plugin_get_mrl (input_plugin_t *this_gen) { pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; return this->mrl; } static int pnm_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: return pnm_peek_header(this->pnm, data, MAX_PREVIEW_SIZE); break; } return INPUT_OPTIONAL_UNSUPPORTED; } static int pnm_plugin_open (input_plugin_t *this_gen) { pnm_input_plugin_t *this = (pnm_input_plugin_t *) this_gen; pnm_t *pnm; lprintf ("trying to open '%s'\n", this->mrl); pnm = pnm_connect (this->stream, this->mrl); if (!pnm) { return 0; } this->pnm = pnm; return 1; } static input_plugin_t *pnm_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *data) { /* pnm_input_class_t *cls = (pnm_input_class_t *) cls_gen; */ pnm_input_plugin_t *this; char *mrl = strdup(data); if (strncasecmp (mrl, "pnm://", 6)) { free (mrl); return NULL; } this = calloc(1, sizeof (pnm_input_plugin_t)); if (!this) { free(mrl); return NULL; } this->stream = stream; this->pnm = NULL; this->mrl = mrl; this->nbc = nbc_init (this->stream); this->input_plugin.open = pnm_plugin_open; this->input_plugin.get_capabilities = pnm_plugin_get_capabilities; this->input_plugin.read = pnm_plugin_read; this->input_plugin.read_block = _x_input_default_read_block; this->input_plugin.seek = pnm_plugin_seek; this->input_plugin.get_current_pos = pnm_plugin_get_current_pos; this->input_plugin.get_length = pnm_plugin_get_length; this->input_plugin.get_blocksize = _x_input_default_get_blocksize; this->input_plugin.get_mrl = pnm_plugin_get_mrl; this->input_plugin.dispose = pnm_plugin_dispose; this->input_plugin.get_optional_data = pnm_plugin_get_optional_data; this->input_plugin.input_class = cls_gen; return &this->input_plugin; } /* * pnm input plugin class stuff */ void *input_pnm_init_class (xine_t *xine, const void *data) { static const input_class_t input_pnm_class = { .get_instance = pnm_class_get_instance, .identifier = "pnm", .description = N_("pnm streaming input plugin"), .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL, }; (void)xine; (void)data; return (void *)&input_pnm_class; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/librtsp/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014271� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/librtsp/rtsp.c���������������������������������������������������������������0000644�0001750�0001750�00000033734�14647725152�015437� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * a minimalistic implementation of rtsp protocol, * *not* RFC 2326 compilant yet. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include <sys/types.h> #define LOG_MODULE "rtsp" #define LOG_VERBOSE /* #define LOG */ #include "rtsp.h" #include <xine/io_helper.h> #include <xine/xineutils.h> #define BUF_SIZE 4096 #define HEADER_SIZE 1024 #define MAX_FIELDS 256 struct rtsp_s { xine_stream_t *stream; int s; char *host; int port; char *path; char *mrl; char *user_agent; char *server; uint32_t server_caps; unsigned int cseq; char *session; char *auth; char *answers[MAX_FIELDS]; /* data of last message */ char *scheduled[MAX_FIELDS]; /* will be sent with next message */ }; /* * constants */ static const char rtsp_protocol_version[]="RTSP/1.0"; /* server states */ #define RTSP_CONNECTED 1 #define RTSP_INIT 2 #define RTSP_READY 4 #define RTSP_PLAYING 8 #define RTSP_RECORDING 16 /* server capabilities */ #define RTSP_OPTIONS 0x001 #define RTSP_DESCRIBE 0x002 #define RTSP_ANNOUNCE 0x004 #define RTSP_SETUP 0x008 #define RTSP_GET_PARAMETER 0x010 #define RTSP_SET_PARAMETER 0x020 #define RTSP_TEARDOWN 0x040 #define RTSP_PLAY 0x080 #define RTSP_RECORD 0x100 /* * rtsp_get gets a line from stream * and returns a null terminated string (must be freed). */ static char *rtsp_get(rtsp_t *s) { char buffer[BUF_SIZE]; char *string = NULL; if ( _x_io_tcp_read_line(s->stream, s->s, buffer, BUF_SIZE) >= 0 ) { lprintf("<< '%s'\n", buffer); string = strdup( buffer ); } return string; } /* * rtsp_put puts a line on stream */ static int rtsp_put(rtsp_t *s, const char *string) { int ret; size_t len=strlen(string); char *buf = malloc(sizeof(char)*len+2); lprintf(">> '%s'", string); if (!buf) return -1; memcpy(buf,string,len); buf[len]=0x0d; buf[len+1]=0x0a; ret = _x_io_tcp_write (s->stream, s->s, buf, len + 2); free(buf); lprintf("done.\n"); return ret; } /* * extract server status code */ static int rtsp_get_code(rtsp_t *s, const char *string) { char buf[4]; int code=0; if (!strncmp(string, rtsp_protocol_version, strlen(rtsp_protocol_version))) { memcpy(buf, string+strlen(rtsp_protocol_version)+1, 3); buf[3]=0; code=atoi(buf); } else if (!strncmp(string, "SET_PARAMETER",8)) { return RTSP_STATUS_SET_PARAMETER; } if(code != 200) xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG, "librtsp: server responds: '%s'\n", string); if (code == 401) _x_message(s->stream, XINE_MSG_AUTHENTICATION_NEEDED, s->mrl, NULL, NULL); return code; } /* * send a request */ static void rtsp_send_request(rtsp_t *s, const char *type, const char *what) { char **payload=s->scheduled; char *buf; buf = _x_asprintf("%s %s %s",type, what, rtsp_protocol_version); if (buf) { rtsp_put (s, buf); free (buf); if (s->auth) rtsp_put (s, s->auth); if (payload) { while (*payload) { rtsp_put (s, *payload); payload++; } } } rtsp_put(s,""); rtsp_unschedule_all(s); } /* * schedule standard fields */ static void rtsp_schedule_standard(rtsp_t *s) { char tmp[17]; sprintf(tmp, "Cseq: %u", s->cseq); rtsp_schedule_field(s, tmp); if (s->session) { char *buf; buf = _x_asprintf("Session: %s", s->session); rtsp_schedule_field(s, buf); free(buf); } } /* * get the answers, if server responses with something != 200, return NULL */ static int rtsp_get_answers(rtsp_t *s) { char *answer=NULL; unsigned int answer_seq; char **answer_ptr=s->answers; int code; int ans_count = 0; answer=rtsp_get(s); if (!answer) return 0; code=rtsp_get_code(s, answer); free(answer); rtsp_free_answers(s); do { /* while we get answer lines */ answer=rtsp_get(s); if (!answer) return 0; if (!strncasecmp(answer,"Cseq: ",6)) { sscanf(answer+6,"%u",&answer_seq); if (s->cseq != answer_seq) { lprintf("warning: Cseq mismatch. got %u, assumed %u", answer_seq, s->cseq); s->cseq=answer_seq; } } if (!strncasecmp(answer,"Server: ",8)) { free(s->server); s->server = strdup(answer + 8); } if (!strncasecmp(answer,"Session: ",9)) { char *tmp = answer + 9; if (s->session) { if (strcmp(tmp, s->session)) { xprintf(s->stream->xine, XINE_VERBOSITY_DEBUG, "rtsp: warning: setting NEW session: %s\n", tmp); free(s->session); s->session=strdup(tmp); } } else { lprintf("setting session id to: %s\n", tmp); s->session=strdup(tmp); } } *answer_ptr=answer; answer_ptr++; } while ((strlen(answer)!=0) && (++ans_count < MAX_FIELDS-1)); s->cseq++; *answer_ptr=NULL; rtsp_schedule_standard(s); return code; } /* * send an ok message */ int rtsp_send_ok(rtsp_t *s) { char cseq[16]; rtsp_put(s, "RTSP/1.0 200 OK"); sprintf(cseq,"CSeq: %u", s->cseq); rtsp_put(s, cseq); rtsp_put(s, ""); return 0; } /* * implementation of must-have rtsp requests; functions return * server status code. */ int rtsp_request_options(rtsp_t *s, const char *what) { char *buf; if (what) { buf=strdup(what); } else { buf = _x_asprintf("rtsp://%s:%i", s->host, s->port); } rtsp_send_request(s,"OPTIONS",buf); free(buf); return rtsp_get_answers(s); } int rtsp_request_describe(rtsp_t *s, const char *what) { char *buf; if (what) { buf=strdup(what); } else { buf = _x_asprintf("rtsp://%s:%i/%s", s->host, s->port, s->path); } rtsp_send_request(s,"DESCRIBE",buf); free(buf); return rtsp_get_answers(s); } int rtsp_request_setup(rtsp_t *s, const char *what) { rtsp_send_request(s,"SETUP",what); return rtsp_get_answers(s); } int rtsp_request_setparameter(rtsp_t *s, const char *what) { char *buf; if (what) { buf=strdup(what); } else { buf = _x_asprintf("rtsp://%s:%i/%s", s->host, s->port, s->path); } rtsp_send_request(s,"SET_PARAMETER",buf); free(buf); return rtsp_get_answers(s); } int rtsp_request_play(rtsp_t *s, const char *what) { char *buf; if (what) { buf=strdup(what); } else { buf = _x_asprintf("rtsp://%s:%i/%s", s->host, s->port, s->path); } rtsp_send_request(s,"PLAY",buf); free(buf); return rtsp_get_answers(s); } #if 0 int rtsp_request_tearoff(rtsp_t *s, const char *what) { rtsp_send_request(s,"TEAROFF",what); return rtsp_get_answers(s); } #endif /* * read opaque data from stream */ int rtsp_read_data(rtsp_t *s, void *buffer_gen, unsigned int size) { uint8_t *buffer = buffer_gen; int i,seq; if (size>=4) { i=_x_io_tcp_read(s->stream, s->s, buffer, 4); if (i<4) return i; if ((buffer[0]=='S')&&(buffer[1]=='E')&&(buffer[2]=='T')&&(buffer[3]=='_')) { char *rest=rtsp_get(s); if (!rest) return -1; seq=-1; do { free(rest); rest=rtsp_get(s); if (!rest) return -1; if (!strncasecmp(rest,"Cseq:",5)) sscanf(rest,"%*s %u",&seq); } while (strlen(rest)!=0); free(rest); if (seq<0) { lprintf("warning: cseq not recognized!\n"); seq=1; } /* lets make the server happy */ rtsp_put(s, "RTSP/1.0 451 Parameter Not Understood"); rest = _x_asprintf("CSeq: %u", seq); rtsp_put(s, rest); free(rest); rtsp_put(s, ""); i=_x_io_tcp_read(s->stream, s->s, buffer, size); } else { i=_x_io_tcp_read(s->stream, s->s, buffer+4, size-4); i+=4; } } else i=_x_io_tcp_read(s->stream, s->s, buffer, size); lprintf("<< %d of %d bytes\n", i, size); return i; } /* * connect to a rtsp server */ static void rtsp_basicauth (const char *user, const char *password, char** dest) { const size_t totlen = strlen(user) + (password ? strlen(password) : 0) + 1; const size_t enclen = ((totlen + 2) * 4 ) / 3 + 12; char tmp[totlen + 4]; snprintf(tmp, totlen + 1, "%s:%s", user, password ? password : ""); *dest = malloc(enclen); xine_base64_encode ((unsigned char *)tmp, *dest, totlen); } rtsp_t *rtsp_connect(xine_stream_t *stream, const char *mrl, const char *user_agent) { rtsp_t *s = calloc(1, sizeof(rtsp_t)); const char *mrl_ptr = mrl; const char *slash, *colon, *amp; int hostend, i; size_t pathbegin; if (!s) return NULL; if (strncmp(mrl,"rtsp://",7)) { xprintf(stream->xine, XINE_VERBOSITY_LOG, _("rtsp: bad mrl: %s\n"), mrl); free(s); return NULL; } mrl_ptr+=7; for (i=0; i<MAX_FIELDS; i++) { s->answers[i]=NULL; s->scheduled[i]=NULL; } s->stream=stream; s->host=NULL; s->port=554; /* rtsp standard port */ s->path=NULL; s->mrl=NULL; s->mrl=strdup(mrl); s->server=NULL; s->s = -1; s->server_caps=0; s->cseq=0; s->session=NULL; if (user_agent) s->user_agent=strdup(user_agent); else s->user_agent=strdup("User-Agent: RealMedia Player Version 6.0.9.1235 (linux-2.0-libc6-i386-gcc2.95)"); amp =strchr(mrl_ptr,'@'); slash=strchr(mrl_ptr,'/'); colon=strchr(mrl_ptr,':'); if (amp && (!slash || amp < slash)) { char *username = NULL, *password = NULL; /* xxx@host:port/ */ if (colon && colon < amp) { /* xxx:yyy@host:port/ */ username = strndup(mrl_ptr, colon - mrl_ptr); password = strndup(colon + 1, amp - colon - 1); } else { username = strndup(mrl_ptr, amp - mrl_ptr); } mrl_ptr = amp + 1; slash = strchr(mrl_ptr, '/'); colon = strchr(mrl_ptr, ':'); if (username) { char *auth; rtsp_basicauth(username, password, &auth); s->auth = _x_asprintf("Authorization: Basic %s", auth); free(auth); } free(username); free(password); } if(!slash) slash=mrl_ptr+strlen(mrl_ptr)+1; if(!colon) colon=slash; if(colon > slash) colon=slash; pathbegin=slash-mrl_ptr; hostend=colon-mrl_ptr; s->host = strndup(mrl_ptr, hostend); if (pathbegin < strlen(mrl_ptr)) s->path=strdup(mrl_ptr+pathbegin+1); if (colon != slash) { char buffer[pathbegin-hostend]; strncpy(buffer,mrl_ptr+hostend+1, pathbegin-hostend-1); buffer[pathbegin-hostend-1]=0; s->port=atoi(buffer); if (s->port < 0 || s->port > 65535) s->port = 554; /* rtsp standard port */ } lprintf("got mrl: %s %i %s\n",s->host,s->port,s->path); s->s = _x_io_tcp_connect (stream, s->host, s->port); if (s->s < 0) { xprintf (stream->xine, XINE_VERBOSITY_LOG, _("rtsp: failed to connect to '%s'\n"), s->host); rtsp_close(s); return NULL; } /* now lets send an options request. */ rtsp_schedule_field(s, "CSeq: 1"); rtsp_schedule_field(s, s->user_agent); rtsp_schedule_field(s, "ClientChallenge: 9e26d33f2984236010ef6253fb1887f7"); rtsp_schedule_field(s, "PlayerStarttime: [28/03/2003:22:50:23 00:00]"); rtsp_schedule_field(s, "CompanyID: KnKV4M4I/B2FjJ1TToLycw=="); rtsp_schedule_field(s, "GUID: 00000000-0000-0000-0000-000000000000"); rtsp_schedule_field(s, "RegionData: 0"); rtsp_schedule_field(s, "ClientID: Linux_2.4_6.0.9.1235_play32_RN01_EN_586"); /*rtsp_schedule_field(s, "Pragma: initiate-session");*/ rtsp_request_options(s, NULL); return s; } /* * closes an rtsp connection */ void rtsp_close(rtsp_t *s) { if (s->s >= 0) _x_io_tcp_close(s->stream, s->s); /* TODO: send a TEAROFF */ free(s->path); free(s->host); free(s->mrl); free(s->session); free(s->user_agent); free(s->auth); rtsp_free_answers(s); rtsp_unschedule_all(s); free(s); } /* * search in answers for tags. returns a pointer to the content * after the first matched tag. returns NULL if no match found. */ const char *rtsp_search_answers(rtsp_t *s, const char *tag) { char **answer; char *ptr; answer=s->answers; while (*answer) { if (!strncasecmp(*answer,tag,strlen(tag))) { ptr=strchr(*answer,':'); if (!ptr) return NULL; ptr++; while(*ptr==' ') ptr++; return ptr; } answer++; } return NULL; } #if 0 /* * session id management */ void rtsp_set_session(rtsp_t *s, const char *id) { free(s->session); s->session=strdup(id); } char *rtsp_get_session(rtsp_t *s) { return s->session; } #endif char *rtsp_get_mrl(rtsp_t *s) { return s->mrl; } /* * schedules a field for transmission */ void rtsp_schedule_field(rtsp_t *s, const char *string) { int i=0; if (!string) return; while(s->scheduled[i]) { i++; } s->scheduled[i]=strdup(string); } #if 0 /* * removes the first scheduled field which prefix matches string. */ void rtsp_unschedule_field(rtsp_t *s, const char *string) { char **ptr=s->scheduled; if (!string) return; while(*ptr) { if (!strncmp(*ptr, string, strlen(string))) break; } if (*ptr) free(*ptr); ptr++; do { *(ptr-1)=*ptr; } while(*ptr); } #endif /* * unschedule all fields */ void rtsp_unschedule_all(rtsp_t *s) { char **ptr; ptr=s->scheduled; while (*ptr) { free(*ptr); *ptr=NULL; ptr++; } } /* * free answers */ void rtsp_free_answers(rtsp_t *s) { char **answer; answer=s->answers; while (*answer) { free(*answer); *answer=NULL; answer++; } } ������������������������������������xine-lib-1.2/src/input/librtsp/rtsp_session.h�������������������������������������������������������0000644�0001750�0001750�00000002446�14647725152�017203� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * high level interface to rtsp servers. */ #ifndef HAVE_RTSP_SESSION_H #define HAVE_RTSP_SESSION_H typedef struct rtsp_session_s rtsp_session_t; rtsp_session_t *rtsp_session_start(xine_stream_t *stream, const char *mrl) XINE_MALLOC; void rtsp_session_set_start_time(rtsp_session_t *this, int start_time); int rtsp_session_read(rtsp_session_t *session, char *data, int len); int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize); void rtsp_session_end(rtsp_session_t *session); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/librtsp/rtsp.h���������������������������������������������������������������0000644�0001750�0001750�00000004612�14647725152�015435� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * a minimalistic implementation of rtsp protocol, * *not* RFC 2326 compilant yet. */ #ifndef HAVE_RTSP_H #define HAVE_RTSP_H /*#include <inttypes.h> */ #include <xine/xine_internal.h> #ifdef __CYGWIN__ #define uint32_t unsigned int #define uint16_t unsigned short int #define uint8_t unsigned char #endif /* some codes returned by rtsp_request_* functions */ #define RTSP_STATUS_SET_PARAMETER 10 #define RTSP_STATUS_OK 200 typedef struct rtsp_s rtsp_t; rtsp_t* rtsp_connect (xine_stream_t *stream, const char *mrl, const char *user_agent) XINE_MALLOC; int rtsp_request_options(rtsp_t *s, const char *what); int rtsp_request_describe(rtsp_t *s, const char *what); int rtsp_request_setup(rtsp_t *s, const char *what); int rtsp_request_setparameter(rtsp_t *s, const char *what); int rtsp_request_play(rtsp_t *s, const char *what); #if 0 int rtsp_request_tearoff(rtsp_t *s, const char *what); #endif int rtsp_send_ok(rtsp_t *s); int rtsp_read_data(rtsp_t *s, void *buffer, unsigned int size); const char* rtsp_search_answers(rtsp_t *s, const char *tag); void rtsp_add_to_payload(char **payload, const char *string); void rtsp_free_answers(rtsp_t *this); int rtsp_read (rtsp_t *this, char *data, int len); void rtsp_close (rtsp_t *this); #if 0 void rtsp_set_session(rtsp_t *s, const char *id); char *rtsp_get_session(rtsp_t *s); #endif char *rtsp_get_mrl(rtsp_t *s); /*int rtsp_peek_header (rtsp_t *this, char *data); */ void rtsp_schedule_field(rtsp_t *s, const char *string); #if 0 void rtsp_unschedule_field(rtsp_t *s, const char *string); #endif void rtsp_unschedule_all(rtsp_t *s); #endif ����������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/librtsp/rtsp_session.c�������������������������������������������������������0000644�0001750�0001750�00000015413�14647725152�017174� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * high level interface to rtsp servers. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <sys/types.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif #include <unistd.h> #include <stdio.h> #include <fcntl.h> #include <stdlib.h> #include <string.h> #define LOG_MODULE "rtsp_session" #define LOG_VERBOSE /* #define LOG */ #include "rtsp.h" #include "rtsp_session.h" #include "real.h" #include "rmff.h" #include "asmrp.h" #include <xine/xine_internal.h> #include <xine/xine_buffer.h> #define BUF_SIZE 4096 #define HEADER_SIZE 4096 struct rtsp_session_s { rtsp_t *s; /* receive buffer */ uint8_t *recv; int recv_size; int recv_read; /* header buffer */ uint8_t header[HEADER_SIZE]; int header_len; int header_left; int playing; int start_time; }; /* network bandwidth */ static const uint32_t rtsp_bandwidths[]={14400,19200,28800,33600,34430,57600, 115200,262200,393216,524300,1544000,10485800}; static const char *const rtsp_bandwidth_strs[]={"14.4 Kbps (Modem)", "19.2 Kbps (Modem)", "28.8 Kbps (Modem)", "33.6 Kbps (Modem)", "34.4 Kbps (Modem)", "57.6 Kbps (Modem)", "115.2 Kbps (ISDN)", "262.2 Kbps (Cable/DSL)", "393.2 Kbps (Cable/DSL)","524.3 Kbps (Cable/DSL)", "1.5 Mbps (T1)", "10.5 Mbps (LAN)", NULL}; rtsp_session_t *rtsp_session_start(xine_stream_t *stream, const char *mrl) { rtsp_session_t *rtsp_session = calloc(1, sizeof(rtsp_session_t)); xine_t *xine = stream->xine; const char *server; rmff_header_t *h; int bandwidth_id; uint32_t bandwidth; if (!rtsp_session) return NULL; bandwidth_id = xine->config->register_enum(xine->config, "media.network.bandwidth", 10, (char **)rtsp_bandwidth_strs, _("network bandwidth"), _("Specify the bandwidth of your internet connection here. " "This will be used when streaming servers offer different versions " "with different bandwidth requirements of the same stream."), 0, NULL, NULL); bandwidth = rtsp_bandwidths[bandwidth_id]; rtsp_session->recv = xine_buffer_init(BUF_SIZE); connect: /* connect to server */ rtsp_session->s=rtsp_connect(stream, mrl, NULL); if (!rtsp_session->s) { xprintf(stream->xine, XINE_VERBOSITY_LOG, _("rtsp_session: failed to connect to server %s\n"), mrl); xine_buffer_free(rtsp_session->recv); free(rtsp_session); return NULL; } /* looking for server type */ server = rtsp_search_answers(rtsp_session->s,"Server"); if (!server) { if (rtsp_search_answers(rtsp_session->s,"RealChallenge1")) server = "Real"; else server = "unknown"; } if (strstr(server,"Real") || strstr(server,"Helix")) { /* we are talking to a real server ... */ h=real_setup_and_get_header(rtsp_session->s, bandwidth); if (!h) { /* got an redirect? */ const char *location = rtsp_search_answers(rtsp_session->s, "Location"); rtsp_close(rtsp_session->s); if (location) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "rtsp_session: redirected to %s\n", location); goto connect; /* *shudder* i made a design mistake somewhere */ } else { xprintf(stream->xine, XINE_VERBOSITY_LOG, _("rtsp_session: session can not be established.\n")); xine_buffer_free(rtsp_session->recv); free(rtsp_session); return NULL; } } rtsp_session->header_left = rtsp_session->header_len = rmff_dump_header(h,rtsp_session->header,HEADER_SIZE); if (rtsp_session->header_len < 0) { xprintf (stream->xine, XINE_VERBOSITY_LOG, _("rtsp_session: rtsp server returned overly-large headers, session can not be established.\n")); goto session_abort; } xine_buffer_copyin(rtsp_session->recv, 0, rtsp_session->header, rtsp_session->header_len); rtsp_session->recv_size = rtsp_session->header_len; rtsp_session->recv_read = 0; } else { xprintf(stream->xine, XINE_VERBOSITY_LOG, _("rtsp_session: rtsp server type '%s' not supported yet. sorry.\n"), server); session_abort: rtsp_close(rtsp_session->s); xine_buffer_free(rtsp_session->recv); free(rtsp_session); return NULL; } return rtsp_session; } void rtsp_session_set_start_time (rtsp_session_t *this, int start_time) { if (start_time >= 0) this->start_time = start_time; } static void rtsp_session_play (rtsp_session_t *this) { char buf[256]; snprintf (buf, sizeof(buf), "Range: npt=%d.%03d-", this->start_time/1000, this->start_time%1000); rtsp_schedule_field (this->s, buf); rtsp_request_play (this->s,NULL); } int rtsp_session_read (rtsp_session_t *this, char *data, int len) { int to_copy; char *dest=data; uint8_t *source=this->recv + this->recv_read; int fill=this->recv_size - this->recv_read; if (len < 0) return 0; if (this->header_left) { if (len > this->header_left) len = this->header_left; this->header_left -= len; } to_copy = len; while (to_copy > fill) { if (!this->playing) { rtsp_session_play (this); this->playing = 1; } memcpy(dest, source, fill); to_copy -= fill; dest += fill; this->recv_read = 0; this->recv_size = real_get_rdt_chunk (this->s, &this->recv); source = this->recv; fill = this->recv_size; if (this->recv_size == 0) { lprintf ("%d of %d bytes provided\n", len-to_copy, len); return len-to_copy; } } memcpy(dest, source, to_copy); this->recv_read += to_copy; lprintf ("%d bytes provided\n", len); return len; } int rtsp_session_peek_header(rtsp_session_t *this, char *buf, int maxsize) { int len; len = (this->header_len < maxsize) ? this->header_len : maxsize; memcpy(buf, this->header, len); return len; } void rtsp_session_end(rtsp_session_t *session) { rtsp_close(session->s); xine_buffer_free(session->recv); free(session); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/input_vcd.c������������������������������������������������������������������0000644�0001750�0001750�00000073042�14647725152�014757� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <unistd.h> #include <errno.h> #include <fcntl.h> #include <sys/ioctl.h> #include <sys/param.h> #include <string.h> #include <netinet/in.h> #ifdef HAVE_LINUX_CDROM_H # include <linux/cdrom.h> #endif #ifdef HAVE_SYS_CDIO_H # include <sys/cdio.h> /* TODO: not clean yet */ # if defined (__FreeBSD_kernel__) # include <sys/cdrio.h> # endif #endif #if ! defined (HAVE_LINUX_CDROM_H) && ! defined (HAVE_SYS_CDIO_H) #error "you need to add cdrom / VCD support for your platform to input_vcd and configure.in" #endif #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "media_helper.h" #include "input_helper.h" #if defined(__sun) #define CDROM "/vol/dev/aliases/cdrom0" #elif defined(__OpenBSD__) #define CDROM "/dev/rcd0c" #else /* for FreeBSD make a link to the right devnode, like /dev/acd0c */ #define CDROM "/dev/cdrom" #endif #define VCDSECTORSIZE 2324 #if defined (__sun) struct cdrom_msf0 { unsigned char minute; unsigned char second; unsigned char frame; }; #endif typedef struct { uint8_t sync [12]; uint8_t header [4]; uint8_t subheader [8]; uint8_t data [2324]; uint8_t spare [4]; } cdsector_t; typedef struct { input_class_t input_class; xine_t *xine; /* FIXME: add thread/mutex stuff to protect against multiple instantiation */ const char *device; char **filelist; xine_mrl_t **mrls; #if defined (__linux__) || defined(__sun) struct cdrom_tochdr tochdr; struct cdrom_tocentry tocent[100]; #elif defined (__FreeBSD_kernel__) || (defined(BSD) && BSD >= 199306) struct ioc_toc_header tochdr; struct cd_toc_entry *tocent; off_t cur_sec; #endif int total_tracks; } vcd_input_class_t; typedef struct { input_plugin_t input_plugin; vcd_input_class_t *cls; xine_stream_t *stream; char *mrl; config_values_t *config; int fd; int cur_track; #if defined (__linux__) || defined(__sun) || defined (__FreeBSD_kernel__) || (defined(BSD) && BSD >= 199306) uint8_t cur_min, cur_sec, cur_frame; #endif #if defined(__sun) int controller_type; #endif } vcd_input_plugin_t; /* ***************************************************************** */ /* Private functions */ /* ***************************************************************** */ /* * Callback for configuratoin changes. */ static void device_change_cb (void *data, xine_cfg_entry_t *cfg) { vcd_input_class_t *this = (vcd_input_class_t *) data; this->device = cfg->str_value; } #if defined (__linux__) || defined(__sun) static int input_vcd_read_toc (vcd_input_class_t *this, int fd) { int i; /* read TOC header */ if ( ioctl(fd, CDROMREADTOCHDR, &this->tochdr) == -1 ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_vcd : error in ioctl CDROMREADTOCHDR\n"); return -1; } /* read individual tracks */ for (i=this->tochdr.cdth_trk0; i<=this->tochdr.cdth_trk1; i++) { this->tocent[i-1].cdte_track = i; this->tocent[i-1].cdte_format = CDROM_MSF; if ( ioctl(fd, CDROMREADTOCENTRY, &this->tocent[i-1]) == -1 ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error in ioctl CDROMREADTOCENTRY for track %d\n", i); return -1; } } /* read the lead-out track */ this->tocent[this->tochdr.cdth_trk1].cdte_track = CDROM_LEADOUT; this->tocent[this->tochdr.cdth_trk1].cdte_format = CDROM_MSF; if (ioctl(fd, CDROMREADTOCENTRY, &this->tocent[this->tochdr.cdth_trk1]) == -1 ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error in ioctl CDROMREADTOCENTRY for lead-out\n"); return -1; } this->total_tracks = this->tochdr.cdth_trk1; return 0; } #elif defined (__FreeBSD_kernel__) || (defined(BSD) && BSD >= 199306) static int input_vcd_read_toc (vcd_input_class_t *this, int fd) { struct ioc_read_toc_entry te; int ntracks; /* read TOC header */ if ( ioctl(fd, CDIOREADTOCHEADER, &this->tochdr) == -1 ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_vcd : error in ioctl CDROMREADTOCHDR\n"); return -1; } ntracks = this->tochdr.ending_track - this->tochdr.starting_track + 2; this->tocent = (struct cd_toc_entry *) xine_xmalloc(sizeof(*this->tocent) * ntracks); te.address_format = CD_LBA_FORMAT; te.starting_track = 0; te.data_len = ntracks * sizeof(struct cd_toc_entry); te.data = this->tocent; if ( ioctl(fd, CDIOREADTOCENTRYS, &te) == -1 ){ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error in ioctl CDROMREADTOCENTRY\n"); return -1; } this->total_tracks = this->tochdr.ending_track - this->tochdr.starting_track +1; return 0; } #endif #if defined(__sun) #include <sys/dkio.h> #include <sys/scsi/generic/commands.h> #include <sys/scsi/impl/uscsi.h> #define SUN_CTRL_SCSI 1 #define SUN_CTRL_ATAPI 2 static int sun_vcd_read(vcd_input_plugin_t *this, long lba, cdsector_t *data) { struct dk_cinfo cinfo; /* * CDROMCDXA/CDROMREADMODE2 are broken on IDE/ATAPI devices. * Try to send MMC3 SCSI commands via the uscsi interface on * ATAPI devices. */ if (this->controller_type == 0) { if ( ioctl(this->fd, DKIOCINFO, &cinfo) == 0 && ((strcmp(cinfo.dki_cname, "ide") == 0) || (strncmp(cinfo.dki_cname, "pci", 3) == 0)) ) this->controller_type = SUN_CTRL_ATAPI; else this->controller_type = SUN_CTRL_SCSI; } switch (this->controller_type) { case SUN_CTRL_SCSI: #if 0 { struct cdrom_cdxa cdxa; cdxa.cdxa_addr = lba; cdxa.cdxa_length = 1; cdxa.cdxa_data = data->subheader; cdxa.cdxa_format = CDROM_XA_SECTOR_DATA; if(ioctl(this->fd,CDROMCDXA,&cdxa)==-1) { xprintf(this->cls->xine, XINE_VERBOSITY_DEBUG, "CDROMCDXA: %s\n", strerror(errno)); return -1; } } #else { struct cdrom_read cdread; cdread.cdread_lba = 4*lba; cdread.cdread_bufaddr = (caddr_t)data->subheader; cdread.cdread_buflen = 2336; if(ioctl(this->fd,CDROMREADMODE2,&cdread)==-1) { xprintf(this->cls->xine, XINE_VERBOSITY_DEBUG, "CDROMREADMODE2: %s\n", strerror(errno)); return -1; } } #endif break; case SUN_CTRL_ATAPI: { struct uscsi_cmd sc; union scsi_cdb cdb; int blocks = 1; int sector_type; int sync, header_code, user_data, edc_ecc, error_field; int sub_channel; sector_type = 0; /* all types */ /*sector_type = 1;*/ /* CD-DA */ /*sector_type = 2;*/ /* mode1 */ /*sector_type = 3;*/ /* mode2 */ /*sector_type = 4;*/ /* mode2/form1 */ /*sector_type = 5;*/ /* mode2/form2 */ sync = 0; header_code = 2; user_data = 1; edc_ecc = 0; error_field = 0; sub_channel = 0; memset(data, 0xaa, sizeof(cdsector_t)); memset(&cdb, 0, sizeof(cdb)); memset(&sc, 0, sizeof(sc)); cdb.scc_cmd = 0xBE; cdb.cdb_opaque[1] = (sector_type) << 2; cdb.cdb_opaque[2] = (lba >> 24) & 0xff; cdb.cdb_opaque[3] = (lba >> 16) & 0xff; cdb.cdb_opaque[4] = (lba >> 8) & 0xff; cdb.cdb_opaque[5] = lba & 0xff; cdb.cdb_opaque[6] = (blocks >> 16) & 0xff; cdb.cdb_opaque[7] = (blocks >> 8) & 0xff; cdb.cdb_opaque[8] = blocks & 0xff; cdb.cdb_opaque[9] = (sync << 7) | (header_code << 5) | (user_data << 4) | (edc_ecc << 3) | (error_field << 1); cdb.cdb_opaque[10] = sub_channel; sc.uscsi_cdb = (caddr_t)&cdb; sc.uscsi_cdblen = 12; sc.uscsi_bufaddr = (caddr_t)data->subheader; sc.uscsi_buflen = 2340; sc.uscsi_flags = USCSI_ISOLATE | USCSI_READ; sc.uscsi_timeout = 20; if (ioctl(this->fd, USCSICMD, &sc)) { xprintf(this->cls->xine, XINE_VERBOSITY_DEBUG, "USCSICMD: READ CD: %s\n", strerror(errno)); return -1; } if (sc.uscsi_status) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "scsi command failed with status %d\n", sc.uscsi_status); return -1; } } break; } return 1; } #endif /*__sun*/ /* ***************************************************************** */ /* END OF PRIVATES */ /* ***************************************************************** */ #if defined (__linux__) static off_t vcd_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t nlen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; static struct cdrom_msf msf ; static cdsector_t data; struct cdrom_msf0 *end_msf; if (nlen != VCDSECTORSIZE) return 0; do { end_msf = (struct cdrom_msf0 *) &this->cls->tocent[this->cur_track+1].cdte_addr.msf; /* printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n", this->cur_min, this->cur_sec, this->cur_frame, end_msf->minute, end_msf->second, end_msf->frame); */ if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second) && (this->cur_frame>=end_msf->frame)) return 0; msf.cdmsf_min0 = this->cur_min; msf.cdmsf_sec0 = this->cur_sec; msf.cdmsf_frame0 = this->cur_frame; memcpy (&data, &msf, sizeof (msf)); if (ioctl (this->fd, CDROMREADRAW, &data) == -1) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error in CDROMREADRAW\n"); return 0; } this->cur_frame++; if (this->cur_frame>=75) { this->cur_frame = 0; this->cur_sec++; if (this->cur_sec>=60) { this->cur_sec = 0; this->cur_min++; } } /* Header ID check for padding sector. VCD uses this to keep constant bitrate so the CD doesn't stop/start */ } while((data.subheader[2]&~0x01)==0x60); memcpy (buf, data.data, VCDSECTORSIZE); /* FIXME */ return VCDSECTORSIZE; } #elif defined (__FreeBSD_kernel__) || (defined(BSD) && BSD >= 199306) static off_t vcd_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t nlen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; static cdsector_t data; int bsize = 2352; if (nlen != VCDSECTORSIZE) return 0; do { if (lseek (this->fd, this->cur_sec * bsize, SEEK_SET) == -1) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: seek error %d\n", errno); return 0; } if (read (this->fd, &data, bsize) == -1) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: read error %d\n", errno); return 0; } this->cur_sec++; } while ((data.subheader[2]&~0x01)==0x60); memcpy (buf, data.data, VCDSECTORSIZE); return VCDSECTORSIZE; } #elif defined (__sun) static off_t vcd_plugin_read (input_plugin_t *this_gen, void *buf_gen, off_t nlen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; static cdsector_t data; struct cdrom_msf0 *end_msf; long lba; if (nlen != VCDSECTORSIZE) return 0; do { end_msf = (struct cdrom_msf0 *) &this->cls->tocent[this->cur_track+1].cdte_addr.msf; /* printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n", this->cur_min, this->cur_sec, this->cur_frame, end_msf->minute, end_msf->second, end_msf->frame); */ if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second) && (this->cur_frame>=end_msf->frame)) return 0; lba = (this->cur_min * 60 + this->cur_sec) * 75L + this->cur_frame; if (sun_vcd_read(this, lba, &data) < 0) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: read data failed\n"); return 0; } this->cur_frame++; if (this->cur_frame>=75) { this->cur_frame = 0; this->cur_sec++; if (this->cur_sec>=60) { this->cur_sec = 0; this->cur_min++; } } /* Header ID check for padding sector. VCD uses this to keep constant bitrate so the CD doesn't stop/start */ } while((data.subheader[2]&~0x01)==0x60); memcpy (buf, data.data, VCDSECTORSIZE); /* FIXME */ return VCDSECTORSIZE; } #endif #if defined (__linux__) static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t nlen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; buf_element_t *buf; static struct cdrom_msf msf ; static cdsector_t data; struct cdrom_msf0 *end_msf; if (nlen != VCDSECTORSIZE) return NULL; do { end_msf = &this->cls->tocent[this->cur_track+1].cdte_addr.msf; /* printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n", this->cur_min, this->cur_sec, this->cur_frame, end_msf->minute, end_msf->second, end_msf->frame); */ if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second) && (this->cur_frame>=end_msf->frame)) return NULL; msf.cdmsf_min0 = this->cur_min; msf.cdmsf_sec0 = this->cur_sec; msf.cdmsf_frame0 = this->cur_frame; memcpy (&data, &msf, sizeof (msf)); if (ioctl (this->fd, CDROMREADRAW, &data) == -1) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error in CDROMREADRAW\n"); return NULL; } this->cur_frame++; if (this->cur_frame>=75) { this->cur_frame = 0; this->cur_sec++; if (this->cur_sec>=60) { this->cur_sec = 0; this->cur_min++; } } /* Header ID check for padding sector. VCD uses this to keep constant bitrate so the CD doesn't stop/start */ } while((data.subheader[2]&~0x01)==0x60); buf = fifo->buffer_pool_alloc (fifo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; memcpy (buf->mem, data.data, VCDSECTORSIZE); /* FIXME */ return buf; } #elif defined (__FreeBSD_kernel__) || (defined(BSD) && BSD >= 199306) static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t nlen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; buf_element_t *buf; static cdsector_t data; int bsize = 2352; if (nlen != VCDSECTORSIZE) return NULL; do { if (lseek (this->fd, this->cur_sec * bsize, SEEK_SET) == -1) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: seek error %d\n", errno); return NULL; } if (read (this->fd, &data, bsize) == -1) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: read error %d\n", errno); return NULL; } this->cur_sec++; } while ((data.subheader[2]&~0x01)==0x60); buf = fifo->buffer_pool_alloc (fifo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; memcpy (buf->mem, data.data, VCDSECTORSIZE); return buf; } #elif defined(__sun) static buf_element_t *vcd_plugin_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t nlen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; buf_element_t *buf; static cdsector_t data; struct cdrom_msf0 *end_msf; long lba; if (nlen != VCDSECTORSIZE) return NULL; do { end_msf = (struct cdrom_msf0 *) &this->cls->tocent[this->cur_track+1].cdte_addr.msf; /* printf ("cur: %02d:%02d:%02d end: %02d:%02d:%02d\n", this->cur_min, this->cur_sec, this->cur_frame, end_msf->minute, end_msf->second, end_msf->frame); */ if ( (this->cur_min>=end_msf->minute) && (this->cur_sec>=end_msf->second) && (this->cur_frame>=end_msf->frame)) return NULL; lba = (this->cur_min * 60 + this->cur_sec) * 75L + this->cur_frame; if (sun_vcd_read (this, lba, &data) < 0) { xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: read data failed\n"); return NULL; } this->cur_frame++; if (this->cur_frame>=75) { this->cur_frame = 0; this->cur_sec++; if (this->cur_sec>=60) { this->cur_sec = 0; this->cur_min++; } } /* Header ID check for padding sector. VCD uses this to keep constant bitrate so the CD doesn't stop/start */ } while((data.subheader[2]&~0x01)==0x60); buf = fifo->buffer_pool_alloc (fifo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; memcpy (buf->mem, data.data, VCDSECTORSIZE); /* FIXME */ return buf; } #endif #if defined (__linux__) || defined(__sun) || defined(HOST_OS_DARWIN) static off_t vcd_time_to_offset (int min, int sec, int frame) { return min * 60 * 75 + sec * 75 + frame; } static void vcd_offset_to_time (off_t offset, uint8_t *min, uint8_t *sec, uint8_t *frame) { *min = offset / (60*75); offset %= (60*75); *sec = offset / 75; *frame = offset % 75; } static off_t vcd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; struct cdrom_msf0 *start_msf; off_t sector_pos; start_msf = (struct cdrom_msf0 *) &this->cls->tocent[this->cur_track].cdte_addr.msf; switch (origin) { case SEEK_SET: sector_pos = (offset / VCDSECTORSIZE) + vcd_time_to_offset (start_msf->minute, start_msf->second, start_msf->frame); vcd_offset_to_time (sector_pos, &this->cur_min, &this->cur_sec, &this->cur_frame); /* printf ("input_vcd: seek to %lld => %02d:%02d:%02d (start is %02d:%02d:%02d)\n", offset, this->cur_min, this->cur_sec, this->cur_frame, start_msf->minute, start_msf->second, start_msf->frame); */ break; case SEEK_CUR: if (offset) xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: SEEK_CUR not implemented for offset != 0\n"); /* printf ("input_vcd: current pos: %02d:%02d:%02d\n", this->cur_min, this->cur_sec, this->cur_frame); */ sector_pos = vcd_time_to_offset (this->cur_min, this->cur_sec, this->cur_frame) - vcd_time_to_offset (start_msf->minute, start_msf->second, start_msf->frame); return sector_pos * VCDSECTORSIZE; break; default: xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error seek to origin %d not implemented!\n", origin); return 0; } return offset ; /* FIXME */ } #elif defined (__FreeBSD_kernel__) || (defined(BSD) && BSD >= 199306) static off_t vcd_plugin_seek (input_plugin_t *this_gen, off_t offset, int origin) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; u_long start; uint32_t dist ; off_t sector_pos; start = ntohl(this->cls->tocent [this->cur_track+1 - this->cls->tochdr.starting_track].addr.lba); /* printf("seek: start sector:%lu, origin: %d, offset:%qu\n", start, origin, offset); */ switch (origin) { case SEEK_SET: dist = offset / VCDSECTORSIZE; this->cur_sec = start + dist; break; case SEEK_CUR: if (offset) xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: SEEK_CUR not implemented for offset != 0\n"); sector_pos = this->cur_sec; return sector_pos * VCDSECTORSIZE; break; default: xprintf (this->cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error seek to origin %d not implemented!\n", origin); return 0; } return offset ; /* FIXME */ } #endif #if defined (__linux__) || defined(__sun) static off_t vcd_plugin_get_length (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; struct cdrom_msf0 *end_msf, *start_msf; off_t len ; if(this->cls->total_tracks) { start_msf = (struct cdrom_msf0 *) &this->cls->tocent[this->cur_track].cdte_addr.msf; end_msf = (struct cdrom_msf0 *) &this->cls->tocent[this->cur_track+1].cdte_addr.msf; len = 75 - start_msf->frame; if (start_msf->second<60) len += (59 - start_msf->second) * 75; if (end_msf->minute > start_msf->minute) { len += (end_msf->minute - start_msf->minute-1) * 60 * 75; len += end_msf->second * 60; len += end_msf->frame ; } return len * VCDSECTORSIZE; } return (off_t) 0; } #elif defined (__FreeBSD_kernel__) || (defined(BSD) && BSD >= 199306) static off_t vcd_plugin_get_length (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; off_t len ; len = ntohl(this->cls->tocent [this->cur_track+2 - this->cls->tochdr.starting_track].addr.lba) - ntohl(this->cls->tocent [this->cur_track+1 - this->cls->tochdr.starting_track].addr.lba); return len * 2352; /*VCDSECTORSIZE;*/ } #endif static off_t vcd_plugin_get_current_pos (input_plugin_t *this_gen){ return (vcd_plugin_seek (this_gen, 0, SEEK_CUR)); } static uint32_t vcd_plugin_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_SEEKABLE | INPUT_CAP_BLOCK ; } static uint32_t vcd_plugin_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return VCDSECTORSIZE; } static void vcd_plugin_dispose (input_plugin_t *this_gen ) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; if (this->fd != -1) close(this->fd); free (this->mrl); free (this); } static const char* vcd_plugin_get_mrl (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; return this->mrl; } static int vcd_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return INPUT_OPTIONAL_UNSUPPORTED; } static int vcd_plugin_open (input_plugin_t *this_gen) { vcd_input_plugin_t *this = (vcd_input_plugin_t *) this_gen; vcd_input_class_t *cls = this->cls; char *filename; int fd; fd = xine_open_cloexec(cls->device, O_RDONLY|O_EXCL); if (fd == -1) { return 0; } this->fd = fd; if (input_vcd_read_toc (this->cls, this->fd)) { return 0; } filename = (char *) &this->mrl[5]; while (*filename == '/') filename++; if (sscanf (filename, "%d", &this->cur_track) != 1) { xprintf (cls->xine, XINE_VERBOSITY_LOG, _("input_vcd: malformed MRL. Use vcdo:/<track #>\n")); return 0; } if (this->cur_track>=this->cls->total_tracks) { xprintf (cls->xine, XINE_VERBOSITY_LOG, _("input_vcd: invalid track %d (valid range: 0 .. %d)\n"), this->cur_track, this->cls->total_tracks-1); return 0; } #if defined (__linux__) || defined(__sun) this->cur_min = this->cls->tocent[this->cur_track].cdte_addr.msf.minute; this->cur_sec = this->cls->tocent[this->cur_track].cdte_addr.msf.second; this->cur_frame = this->cls->tocent[this->cur_track].cdte_addr.msf.frame; #elif defined (__OpenBSD__) || defined(__NetBSD__) this->cur_min = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.minute; this->cur_sec = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.second; this->cur_frame = this->cls->tocent[this->cur_track + 1 - this->cls->tochdr.starting_track].addr.msf.frame; #elif defined (__FreeBSD_kernel__) { int bsize = 2352; if (ioctl (this->fd, CDRIOCSETBLOCKSIZE, &bsize) == -1) { xprintf (cls->xine, XINE_VERBOSITY_DEBUG, "input_vcd: error in CDRIOCSETBLOCKSIZE %d\n", errno); return 0; } this->cur_sec = ntohl(this->cls->tocent [this->cur_track+1 - this->cls->tochdr.starting_track].addr.lba); } #endif return 1; } static input_plugin_t *vcd_class_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { vcd_input_class_t *cls = (vcd_input_class_t *) cls_gen; vcd_input_plugin_t *this; if (strncasecmp (mrl, "vcdo:/",6)) { return 0; } this = calloc(1, sizeof(vcd_input_plugin_t)); if (!this) return NULL; this->stream = stream; this->mrl = strdup(mrl); this->fd = -1; if (!this->mrl) { free(this); return NULL; } this->input_plugin.open = vcd_plugin_open; this->input_plugin.get_capabilities = vcd_plugin_get_capabilities; this->input_plugin.read = vcd_plugin_read; this->input_plugin.read_block = vcd_plugin_read_block; this->input_plugin.seek = vcd_plugin_seek; this->input_plugin.get_current_pos = vcd_plugin_get_current_pos; this->input_plugin.get_length = vcd_plugin_get_length; this->input_plugin.get_blocksize = vcd_plugin_get_blocksize; this->input_plugin.get_mrl = vcd_plugin_get_mrl; this->input_plugin.get_optional_data = vcd_plugin_get_optional_data; this->input_plugin.dispose = vcd_plugin_dispose; this->input_plugin.input_class = cls_gen; this->cls = cls; return &this->input_plugin; } /* * vcd input plugin class stuff */ static void vcd_filelist_dispose(vcd_input_class_t *this) { if ( this->filelist == NULL ) return; char **entry = this->filelist; while(*(entry)) { free(*(entry++)); } _x_freep(&this->filelist); } static void vcd_class_dispose (input_class_t *this_gen) { vcd_input_class_t *this = (vcd_input_class_t *) this_gen; config_values_t *config = this->xine->config; config->unregister_callback(config, "media.vcd.device"); vcd_filelist_dispose(this); _x_input_free_mrls(&this->mrls); free (this); } static int vcd_class_eject_media (input_class_t *this_gen) { vcd_input_class_t *this = (vcd_input_class_t *) this_gen; return media_eject_media (this->xine, this->device); } static xine_mrl_t **vcd_class_get_dir (input_class_t *this_gen, const char *filename, int *num_files) { vcd_input_class_t *this = (vcd_input_class_t *) this_gen; int i, fd; *num_files = 0; _x_input_free_mrls(&this->mrls); if (filename) return NULL; fd = xine_open_cloexec(this->device, O_RDONLY|O_EXCL); if (fd == -1) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("unable to open %s: %s.\n"), this->device, strerror(errno)); return NULL; } if (input_vcd_read_toc (this, fd)) { close (fd); fd = -1; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "vcd_read_toc failed\n"); return NULL; } close (fd); fd = -1; if (this->total_tracks < 2) return NULL; this->mrls = _x_input_alloc_mrls(this->total_tracks - 1); if (!this->mrls) return NULL; *num_files = this->total_tracks - 1; /* printf ("%d tracks\n", this->total_tracks); */ for (i=1; i<this->total_tracks; i++) { /* FIXME: check if track 0 contains valid data */ this->mrls[i-1]->mrl = _x_asprintf("vcdo:/%d", i); this->mrls[i-1]->type = mrl_vcd; /* hack */ this->mrls[i-1]->size = vcd_plugin_get_length ((input_plugin_t *) this); } return this->mrls; } static const char * const * vcd_class_get_autoplay_list (input_class_t *this_gen, int *num_files) { vcd_input_class_t *this = (vcd_input_class_t *) this_gen; int i, fd; fd = xine_open_cloexec(this->device, O_RDONLY|O_EXCL); if (fd == -1) { xprintf (this->xine, XINE_VERBOSITY_LOG, _("input_vcd: unable to open %s: %s.\n"), this->device, strerror(errno)); return NULL; } if (input_vcd_read_toc (this, fd)) { close (fd); fd = -1; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "input_vcd: vcd_read_toc failed\n"); return NULL; } close (fd); fd = -1; *num_files = this->total_tracks - 1; vcd_filelist_dispose(this); this->filelist = calloc(this->total_tracks+1, sizeof(char*)); if (!this->filelist) return NULL; /* FIXME: check if track 0 contains valid data */ for (i = 1; i < this->total_tracks; i++) this->filelist[i-1] = _x_asprintf("vcdo:/%d", i); /* printf ("%d tracks\n", this->total_tracks); */ return (const char * const *)this->filelist; } static void *init_class (xine_t *xine, const void *data) { vcd_input_class_t *this; config_values_t *config = xine->config; (void)data; this = calloc(1, sizeof (vcd_input_class_t)); if (!this) return NULL; this->xine = xine; this->input_class.get_instance = vcd_class_get_instance; this->input_class.identifier = "vcdo"; this->input_class.description = N_("Video CD input plugin"); this->input_class.get_dir = vcd_class_get_dir; this->input_class.get_autoplay_list = vcd_class_get_autoplay_list; this->input_class.dispose = vcd_class_dispose; this->input_class.eject_media = vcd_class_eject_media; this->device = config->register_filename (config, "media.vcd.device", CDROM, XINE_CONFIG_STRING_IS_DEVICE_NAME, _("device used for VCD playback"), _("The path to the device, usually a CD or DVD drive, " "you intend to play your VideoCDs with."), 10, device_change_cb, (void *)this); return this; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_INPUT | PLUGIN_MUST_PRELOAD, 18, "VCDO", XINE_VERSION_CODE, NULL, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/input/media_helper.h���������������������������������������������������������������0000644�0001750�0001750�00000001705�14647725152�015404� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2007 the xine project, * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifndef HAVE_MEDIA_HELPER_H #define HAVE_MEDIA_HELPER_H #include <xine/xine_internal.h> int media_eject_media (xine_t *xine, const char *device); #endif �����������������������������������������������������������xine-lib-1.2/src/xine-utils/������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013554� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/yuv2rgb_mmx.c�����������������������������������������������������������0000644�0001750�0001750�00000104262�14647725152�016206� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * yuv2rgb_mmx.c * * Copyright (C) 2001-2018 the xine project * This file is part of xine, a free video player. * * based on work from mpeg2dec: * * Copyright (C) 2000-2001 Silicon Integrated System Corp. * All Rights Reserved. * * Author: Olie Lho <ollie@sis.com.tw> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #include "config.h" #if defined(ARCH_X86) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include <xine/xineutils.h> #include "xine_mmx.h" #include "yuv2rgb_private.h" #define CPU_MMXEXT 0 #define CPU_MMX 1 /* CPU_MMXEXT/CPU_MMX adaptation layer */ #define movntq(src,dest) \ do { \ if (cpu == CPU_MMXEXT) \ movntq_r2m (src, dest); \ else \ movq_r2m (src, dest); \ } while (0) typedef struct mmx_csc_s mmx_csc_t; struct mmx_csc_s { mmx_t x00ffw; mmx_t x0080w; mmx_t addYw; mmx_t U_green; mmx_t U_blue; mmx_t V_red; mmx_t V_green; mmx_t Y_coeff; }; extern const int32_t Inverse_Table_6_9[8][4]; void mmx_yuv2rgb_set_csc_levels(yuv2rgb_factory_t *this_gen, int brightness, int contrast, int saturation, int colormatrix) { yuv2rgb_factory_impl_t *this = (yuv2rgb_factory_impl_t*)this_gen; int i, cty; int yoffset = -16; int ygain = ((1 << 16) * 255) / 219; int cm = (colormatrix >> 1) & 7; int crv = Inverse_Table_6_9[cm][0]; int cbu = Inverse_Table_6_9[cm][1]; int cgu = Inverse_Table_6_9[cm][2]; int cgv = Inverse_Table_6_9[cm][3]; mmx_csc_t *csc; /* 'table_mmx' is 64bit aligned for better performance */ if (this->table_mmx == NULL) { this->table_mmx = xine_mallocz_aligned(sizeof(mmx_csc_t)); } /* full range mode */ if (colormatrix & 1) { yoffset = 0; ygain = (1 << 16); crv = (crv * 112 + 63) / 127; cbu = (cbu * 112 + 63) / 127; cgu = (cgu * 112 + 63) / 127; cgv = (cgv * 112 + 63) / 127; } yoffset += brightness; /* TV set behaviour: contrast affects color difference as well */ saturation = (contrast * saturation + 64) >> 7; csc = (mmx_csc_t *) this->table_mmx; crv = (crv * saturation + 512) / 1024; cbu = (cbu * saturation + 512) / 1024; cbu = (cbu > 32767) ? 32767 : cbu; cgu = (cgu * saturation + 512) / 1024; cgv = (cgv * saturation + 512) / 1024; cty = (ygain * contrast + 512) / 1024; /* the 8 is "+0,5" for later rounding */ yoffset = ((cty * (yoffset << 7)) >> 16) + 8; for (i=0; i < 4; i++) { csc->U_green.w[i] = -cgu; csc->U_blue.w[i] = cbu; csc->V_red.w[i] = crv; csc->V_green.w[i] = -cgv; csc->Y_coeff.w[i] = cty; csc->addYw.w[i] = yoffset; csc->x0080w.w[i] = 128; csc->x00ffw.w[i] = 0xff; } } static inline void mmx_yuv2rgb (const uint8_t * py, const uint8_t * pu, const uint8_t * pv, const mmx_csc_t *csc) { /* OK what we're doing here is y = ((cty * (y << 7)) >> 16) + yoffset; u = (u - 128) << 7; v = (v - 128) << 7; r = (y + ((crv * v) >> 16)) >> 4; g = (y + ((cgu * u) >> 16) + ((cgv * v) >> 16)) >> 4; b = (y + ((cbu * u) >> 16)) >> 4; */ movq_m2r (*py, mm6); // mm6 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 pxor_r2r (mm4, mm4); // mm4 = 0 movd_m2r (*pu, mm0); // mm0 = 00 00 00 00 u3 u2 u1 u0 movq_r2r (mm6, mm7); // mm7 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 pand_m2r (csc->x00ffw, mm6); // mm6 = Y6 Y4 Y2 Y0 psrlw_i2r (8, mm7); // mm7 = Y7 Y5 Y3 Y1 psllw_i2r (7, mm6); // promote precision movd_m2r (*pv, mm1); // mm1 = 00 00 00 00 v3 v2 v1 v0 pmulhw_m2r (csc->Y_coeff, mm6); // mm6 = luma_rgb even psllw_i2r (7, mm7); // promote precision punpcklbw_r2r (mm4, mm0); // mm0 = u3 u2 u1 u0 paddsw_m2r (csc->addYw, mm6); // += yoffset psubsw_m2r (csc->x0080w, mm0); // u -= 128 punpcklbw_r2r (mm4, mm1); // mm1 = v3 v2 v1 v0 pmulhw_m2r (csc->Y_coeff, mm7); // mm7 = luma_rgb odd psllw_i2r (7, mm0); // promote precision psubsw_m2r (csc->x0080w, mm1); // v -= 128 movq_r2r (mm0, mm2); // mm2 = u3 u2 u1 u0 psllw_i2r (7, mm1); // promote precision movq_r2r (mm1, mm4); // mm4 = v3 v2 v1 v0 paddsw_m2r (csc->addYw, mm7); // += yoffset pmulhw_m2r (csc->U_blue, mm0); // mm0 = chroma_b pmulhw_m2r (csc->V_red, mm1); // mm1 = chroma_r movq_r2r (mm0, mm3); // mm3 = chroma_b paddsw_r2r (mm6, mm0); // mm0 = B6 B4 B2 B0 paddsw_r2r (mm7, mm3); // mm3 = B7 B5 B3 B1 psraw_i2r (4, mm0); // div round pmulhw_m2r (csc->U_green, mm2); // mm2 = u * u_green psraw_i2r (4, mm3); // div round packuswb_r2r (mm0, mm0); // saturate to 0-255 packuswb_r2r (mm3, mm3); // saturate to 0-255 pmulhw_m2r (csc->V_green, mm4); // mm4 = v * v_green punpcklbw_r2r (mm3, mm0); // mm0 = B7 B6 B5 B4 B3 B2 B1 B0 paddsw_r2r (mm4, mm2); // mm2 = chroma_g movq_r2r (mm1, mm4); // mm4 = chroma_r movq_r2r (mm2, mm5); // mm5 = chroma_g paddsw_r2r (mm6, mm2); // mm2 = G6 G4 G2 G0 psraw_i2r (4, mm2); // div round paddsw_r2r (mm6, mm1); // mm1 = R6 R4 R2 R0 packuswb_r2r (mm2, mm2); // saturate to 0-255 psraw_i2r (4, mm1); // div round paddsw_r2r (mm7, mm4); // mm4 = R7 R5 R3 R1 packuswb_r2r (mm1, mm1); // saturate to 0-255 psraw_i2r (4, mm4); // div round paddsw_r2r (mm7, mm5); // mm5 = G7 G5 G3 G1 packuswb_r2r (mm4, mm4); // saturate to 0-255 psraw_i2r (4, mm5); // div round punpcklbw_r2r (mm4, mm1); // mm1 = R7 R6 R5 R4 R3 R2 R1 R0 packuswb_r2r (mm5, mm5); // saturate to 0-255 punpcklbw_r2r (mm5, mm2); // mm2 = G7 G6 G5 G4 G3 G2 G1 G0 } // basic opt static inline void mmx_unpack_16rgb (uint8_t * image, int cpu) { static mmx_t mmx_bluemask = {0xf8f8f8f8f8f8f8f8ULL}; static mmx_t mmx_greenmask = {0xfcfcfcfcfcfcfcfcULL}; static mmx_t mmx_redmask = {0xf8f8f8f8f8f8f8f8ULL}; /* * convert RGB plane to RGB 16 bits * mm0 -> B, mm1 -> R, mm2 -> G * mm4 -> GB, mm5 -> AR pixel 4-7 * mm6 -> GB, mm7 -> AR pixel 0-3 */ pand_m2r (mmx_bluemask, mm0); // mm0 = b7b6b5b4b3______ pxor_r2r (mm4, mm4); // mm4 = 0 pand_m2r (mmx_greenmask, mm2); // mm2 = g7g6g5g4g3g2____ psrlq_i2r (3, mm0); // mm0 = ______b7b6b5b4b3 movq_r2r (mm2, mm7); // mm7 = g7g6g5g4g3g2____ movq_r2r (mm0, mm5); // mm5 = ______b7b6b5b4b3 pand_m2r (mmx_redmask, mm1); // mm1 = r7r6r5r4r3______ punpcklbw_r2r (mm4, mm2); punpcklbw_r2r (mm1, mm0); psllq_i2r (3, mm2); punpckhbw_r2r (mm4, mm7); por_r2r (mm2, mm0); psllq_i2r (3, mm7); movntq (mm0, *image); punpckhbw_r2r (mm1, mm5); por_r2r (mm7, mm5); // U // V movntq (mm5, *(image+8)); } static inline void mmx_unpack_15rgb (uint8_t * image, int cpu) { static mmx_t mmx_bluemask = {0xf8f8f8f8f8f8f8f8ULL}; static mmx_t mmx_greenmask = {0xf8f8f8f8f8f8f8f8ULL}; static mmx_t mmx_redmask = {0xf8f8f8f8f8f8f8f8ULL}; /* * convert RGB plane to RGB 15 bits * mm0 -> B, mm1 -> R, mm2 -> G * mm4 -> GB, mm5 -> AR pixel 4-7 * mm6 -> GB, mm7 -> AR pixel 0-3 */ pand_m2r (mmx_bluemask, mm0); // mm0 = b7b6b5b4b3______ pxor_r2r (mm4, mm4); // mm4 = 0 pand_m2r (mmx_greenmask, mm2); // mm2 = g7g6g5g4g3g2____ psrlq_i2r (3, mm0); // mm0 = ______b7b6b5b4b3 movq_r2r (mm2, mm7); // mm7 = g7g6g5g4g3g2____ movq_r2r (mm0, mm5); // mm5 = ______b7b6b5b4b3 pand_m2r (mmx_redmask, mm1); // mm1 = r7r6r5r4r3______ punpcklbw_r2r (mm4, mm2); psrlq_i2r (1, mm1); punpcklbw_r2r (mm1, mm0); psllq_i2r (2, mm2); punpckhbw_r2r (mm4, mm7); por_r2r (mm2, mm0); psllq_i2r (2, mm7); movntq (mm0, *image); punpckhbw_r2r (mm1, mm5); por_r2r (mm7, mm5); // U // V movntq (mm5, *(image+8)); } static inline void mmx_unpack_32rgb (uint8_t * image, int cpu) { /* * convert RGB plane to RGB packed format, * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0, * mm4 -> GB, mm5 -> AR pixel 4-7, * mm6 -> GB, mm7 -> AR pixel 0-3 */ pxor_r2r (mm3, mm3); movq_r2r (mm0, mm6); punpcklbw_r2r (mm2, mm6); movq_r2r (mm1, mm7); punpcklbw_r2r (mm3, mm7); movq_r2r (mm0, mm4); punpcklwd_r2r (mm7, mm6); movq_r2r (mm1, mm5); /* scheduling: this is hopeless */ movntq (mm6, *image); movq_r2r (mm0, mm6); punpcklbw_r2r (mm2, mm6); punpckhwd_r2r (mm7, mm6); movntq (mm6, *(image+8)); punpckhbw_r2r (mm2, mm4); punpckhbw_r2r (mm3, mm5); punpcklwd_r2r (mm5, mm4); movntq (mm4, *(image+16)); movq_r2r (mm0, mm4); punpckhbw_r2r (mm2, mm4); punpckhwd_r2r (mm5, mm4); movntq (mm4, *(image+24)); } static inline void mmx_unpack_32bgr (uint8_t * image, int cpu) { /* * convert RGB plane to RGB packed format, * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0, * mm4 -> GB, mm5 -> AR pixel 4-7, * mm6 -> GB, mm7 -> AR pixel 0-3 */ pxor_r2r (mm3, mm3); movq_r2r (mm1, mm6); punpcklbw_r2r (mm2, mm6); movq_r2r (mm0, mm7); punpcklbw_r2r (mm3, mm7); movq_r2r (mm1, mm4); punpcklwd_r2r (mm7, mm6); movq_r2r (mm0, mm5); /* scheduling: this is hopeless */ movntq (mm6, *image); movq_r2r (mm1, mm6); punpcklbw_r2r (mm2, mm6); punpckhwd_r2r (mm7, mm6); movntq (mm6, *(image+8)); punpckhbw_r2r (mm2, mm4); punpckhbw_r2r (mm3, mm5); punpcklwd_r2r (mm5, mm4); movntq (mm4, *(image+16)); movq_r2r (mm1, mm4); punpckhbw_r2r (mm2, mm4); punpckhwd_r2r (mm5, mm4); movntq (mm4, *(image+24)); } static inline void mmx_unpack_24rgb (uint8_t * image, int cpu) { static mmx_t mmx_hirgb = {0x00ffffff00000000ULL}; static mmx_t mmx_lorgb = {0x0000000000ffffffULL}; /* * convert RGB plane to RGB packed format, * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0, * mm4 -> GB, mm5 -> AR pixel 4-7, * mm6 -> GB, mm7 -> AR pixel 0-3 */ movq_r2r (mm1, mm6); punpcklbw_r2r (mm2, mm6); movq_r2r (mm0, mm7); punpcklbw_r2r (mm7, mm7); punpcklwd_r2r (mm7, mm6); movq_r2r (mm6, mm5); pand_m2r (mmx_hirgb, mm5); pand_m2r (mmx_lorgb, mm6); psrlq_i2r (8, mm5); por_r2r(mm6, mm5); /* mm5 = 0x0000B1G1R1B0G0R0 */ movq_r2r (mm1, mm6); punpcklbw_r2r (mm2, mm6); punpckhwd_r2r (mm7, mm6); /* mm6 = 0x??B3G3R3??B2G2R2 */ movq_r2r (mm6, mm4); psllq_i2r (48, mm4); por_r2r(mm4, mm5); /* mm5 = 0xG2R2B1G1R1B0G0R0 */ movntq (mm5, *image); movq_r2r (mm6, mm3); pand_m2r (mmx_hirgb, mm3); pand_m2r (mmx_lorgb, mm6); psrlq_i2r (8, mm3); por_r2r(mm6, mm3); /* mm3 = 0x0000B3G3R3B2G2R2 */ psrlq_i2r (16, mm3); /* mm3 = 0x00000000B3G3R3B2 */ movq_r2r (mm1, mm4); punpckhbw_r2r (mm2, mm4); movq_r2r (mm0, mm5); punpckhbw_r2r (mm3, mm5); punpcklwd_r2r (mm5, mm4); movq_r2r (mm4, mm6); pand_m2r (mmx_hirgb, mm6); pand_m2r (mmx_lorgb, mm4); psrlq_i2r (8, mm6); por_r2r(mm4, mm6); /* mm6 = 0x0000B5G5R5B4G4R4 */ movq_r2r (mm6, mm4); psllq_i2r (32, mm4); /* mm4 = 0xR5B4G4R400000000 */ por_r2r(mm4, mm3); /* mm4 = 0xR5B4G4R4B3G3R3B2 */ movntq (mm3, *(image+8)); psrlq_i2r (32, mm6); /* mm6 = 0x000000000000B5G5 */ movq_r2r (mm1, mm4); punpckhbw_r2r (mm2, mm4); punpckhwd_r2r (mm5, mm4); movq_r2r (mm4, mm3); pand_m2r (mmx_hirgb, mm3); pand_m2r (mmx_lorgb, mm4); psrlq_i2r (8, mm3); por_r2r (mm4, mm3); /* mm3 = 0x0000B7G7R7B6G6R6 */ psllq_i2r (16, mm3); /* mm3 = 0xB7G7R7B6G6R60000 */ por_r2r (mm3, mm6); /* mm6 = 0xB7G7R7B6G6R6B5G5 */ movntq (mm6, *(image+16)); } static inline void mmx_unpack_24bgr (uint8_t * image, int cpu) { static mmx_t mmx_hirgb = {0x00ffffff00000000ULL}; static mmx_t mmx_lorgb = {0x0000000000ffffffULL}; /* * convert RGB plane to RGB packed format, * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0, * mm4 -> GB, mm5 -> AR pixel 4-7, * mm6 -> GB, mm7 -> AR pixel 0-3 */ movq_r2r (mm0, mm6); punpcklbw_r2r (mm2, mm6); movq_r2r (mm1, mm7); punpcklbw_r2r (mm7, mm7); punpcklwd_r2r (mm7, mm6); movq_r2r (mm6, mm5); pand_m2r (mmx_hirgb, mm5); pand_m2r (mmx_lorgb, mm6); psrlq_i2r (8, mm5); por_r2r(mm6, mm5); /* mm5 = 0x0000R1G1B1R0G0B0 */ movq_r2r (mm0, mm6); punpcklbw_r2r (mm2, mm6); punpckhwd_r2r (mm7, mm6); /* mm6 = 0x??R3G3B3??R2G2B2 */ movq_r2r (mm6, mm4); psllq_i2r (48, mm4); por_r2r(mm4, mm5); /* mm5 = 0xG2B2R1G1B1R0G0B0 */ movntq (mm5, *image); movq_r2r (mm6, mm3); pand_m2r (mmx_hirgb, mm3); pand_m2r (mmx_lorgb, mm6); psrlq_i2r (8, mm3); por_r2r(mm6, mm3); /* mm3 = 0x0000R3G3B3R2G2B2 */ psrlq_i2r (16, mm3); /* mm3 = 0x00000000R3G3B3R2 */ movq_r2r (mm0, mm4); punpckhbw_r2r (mm2, mm4); movq_r2r (mm1, mm5); punpckhbw_r2r (mm3, mm5); punpcklwd_r2r (mm5, mm4); movq_r2r (mm4, mm6); pand_m2r (mmx_hirgb, mm6); pand_m2r (mmx_lorgb, mm4); psrlq_i2r (8, mm6); por_r2r(mm4, mm6); /* mm6 = 0x0000R5G5B5R4G4B4 */ movq_r2r (mm6, mm4); psllq_i2r (32, mm4); /* mm4 = 0xB5R4G4B400000000 */ por_r2r(mm4, mm3); /* mm4 = 0xB5R4G4B4R3G3B3R2 */ movntq (mm3, *(image+8)); psrlq_i2r (32, mm6); /* mm6 = 0x000000000000R5G5 */ movq_r2r (mm0, mm4); punpckhbw_r2r (mm2, mm4); punpckhwd_r2r (mm5, mm4); movq_r2r (mm4, mm3); pand_m2r (mmx_hirgb, mm3); pand_m2r (mmx_lorgb, mm4); psrlq_i2r (8, mm3); por_r2r (mm4, mm3); /* mm3 = 0x0000R7G7B7R6G6B6 */ psllq_i2r (16, mm3); /* mm3 = 0xR7G7B7R6G6B60000 */ por_r2r (mm3, mm6); /* mm6 = 0xR7G7B7R6G6B6R5G5 */ movntq (mm6, *(image+16)); } static inline void yuv420_rgb16 (yuv2rgb_t *this_gen, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv, int cpu) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int i, height, dst_height; int rgb_stride = this->rgb_stride; int y_stride = this->y_stride; int uv_stride = this->uv_stride; int width = this->source_width; uint8_t *img; width >>= 3; if (!this->do_scale) { height = this_gen->next_slice (this_gen, &image); y_stride -= 8 * width; uv_stride -= 4 * width; do { i = width; img = image; do { mmx_yuv2rgb (py, pu, pv, this->table_mmx); mmx_unpack_16rgb (img, cpu); py += 8; pu += 4; pv += 4; img += 16; } while (--i); py += y_stride; image += rgb_stride; if (height & 1) { pu += uv_stride; pv += uv_stride; } else { pu -= 4 * width; pv -= 4 * width; } } while (--height); } else { scale_line_func_t scale_line = this->scale_line; uint8_t *y_buf, *u_buf, *v_buf; int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (py, this->y_buffer, this->dest_width, this->step_dx); dst_height = this_gen->next_slice (this_gen, &image); for (height = 0;; ) { y_buf = this->y_buffer; u_buf = this->u_buffer; v_buf = this->v_buffer; i = this->dest_width >> 3; img = image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf, this->table_mmx); mmx_unpack_16rgb (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; img += 16; } while (--i); dy += this->step_dy; image += rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (image, image-rgb_stride, this->dest_width*2); dy += this->step_dy; image += rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; py += y_stride; scale_line (py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { pu += uv_stride; pv += uv_stride; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768); } } } static inline void yuv420_rgb15 (yuv2rgb_t *this_gen, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv, int cpu) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int i, height, dst_height; int rgb_stride = this->rgb_stride; int y_stride = this->y_stride; int uv_stride = this->uv_stride; int width = this->source_width; uint8_t *img; width >>= 3; if (!this->do_scale) { height = this_gen->next_slice (this_gen, &image); y_stride -= 8 * width; uv_stride -= 4 * width; do { i = width; img = image; do { mmx_yuv2rgb (py, pu, pv, this->table_mmx); mmx_unpack_15rgb (img, cpu); py += 8; pu += 4; pv += 4; img += 16; } while (--i); py += y_stride; image += rgb_stride; if (height & 1) { pu += uv_stride; pv += uv_stride; } else { pu -= 4 * width; pv -= 4 * width; } } while (--height); } else { scale_line_func_t scale_line = this->scale_line; uint8_t *y_buf, *u_buf, *v_buf; int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (py, this->y_buffer, this->dest_width, this->step_dx); dst_height = this_gen->next_slice (this_gen, &image); for (height = 0;; ) { y_buf = this->y_buffer; u_buf = this->u_buffer; v_buf = this->v_buffer; i = this->dest_width >> 3; img = image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf, this->table_mmx); mmx_unpack_15rgb (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; img += 16; } while (--i); dy += this->step_dy; image += rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (image, image-rgb_stride, this->dest_width*2); dy += this->step_dy; image += rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; py += y_stride; scale_line (py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { pu += uv_stride; pv += uv_stride; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } } static inline void yuv420_rgb24 (yuv2rgb_t *this_gen, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv, int cpu) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int i, height, dst_height; int rgb_stride = this->rgb_stride; int y_stride = this->y_stride; int uv_stride = this->uv_stride; int width = this->source_width; uint8_t *img; /* rgb_stride -= 4 * this->dest_width; */ width >>= 3; if (!this->do_scale) { height = this_gen->next_slice (this_gen, &image); y_stride -= 8 * width; uv_stride -= 4 * width; do { i = width; img = image; do { mmx_yuv2rgb (py, pu, pv, this->table_mmx); mmx_unpack_24rgb (img, cpu); py += 8; pu += 4; pv += 4; img += 24; } while (--i); py += y_stride; image += rgb_stride; if (height & 1) { pu += uv_stride; pv += uv_stride; } else { pu -= 4 * width; pv -= 4 * width; } } while (--height); } else { scale_line_func_t scale_line = this->scale_line; uint8_t *y_buf, *u_buf, *v_buf; int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (py, this->y_buffer, this->dest_width, this->step_dx); dst_height = this_gen->next_slice (this_gen, &image); for (height = 0;; ) { y_buf = this->y_buffer; u_buf = this->u_buffer; v_buf = this->v_buffer; i = this->dest_width >> 3; img=image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf, this->table_mmx); mmx_unpack_24rgb (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; img += 24; } while (--i); dy += this->step_dy; image += rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (image, image-rgb_stride, this->dest_width*3); dy += this->step_dy; image += rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; py += y_stride; scale_line (py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { pu += uv_stride; pv += uv_stride; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } } static inline void yuv420_bgr24 (yuv2rgb_t *this_gen, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv, int cpu) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int i, height, dst_height; int rgb_stride = this->rgb_stride; int y_stride = this->y_stride; int uv_stride = this->uv_stride; int width = this->source_width; uint8_t *img; /* rgb_stride -= 4 * this->dest_width; */ width >>= 3; if (!this->do_scale) { height = this_gen->next_slice (this_gen, &image); y_stride -= 8 * width; uv_stride -= 4 * width; do { i = width; img = image; do { mmx_yuv2rgb (py, pu, pv, this->table_mmx); mmx_unpack_24bgr (img, cpu); py += 8; pu += 4; pv += 4; img += 24; } while (--i); py += y_stride; image += rgb_stride; if (height & 1) { pu += uv_stride; pv += uv_stride; } else { pu -= 4 * width; pv -= 4 * width; } } while (--height); } else { scale_line_func_t scale_line = this->scale_line; uint8_t *y_buf, *u_buf, *v_buf; int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (py, this->y_buffer, this->dest_width, this->step_dx); dst_height = this_gen->next_slice (this_gen, &image); for (height = 0;; ) { y_buf = this->y_buffer; u_buf = this->u_buffer; v_buf = this->v_buffer; i = this->dest_width >> 3; img=image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf, this->table_mmx); mmx_unpack_24bgr (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; img += 24; } while (--i); dy += this->step_dy; image += rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (image, image-rgb_stride, this->dest_width*3); dy += this->step_dy; image += rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; py += y_stride; scale_line (py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { pu += uv_stride; pv += uv_stride; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } } static inline void yuv420_argb32 (yuv2rgb_t *this_gen, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv, int cpu) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int i, height, dst_height; int rgb_stride = this->rgb_stride; int y_stride = this->y_stride; int uv_stride = this->uv_stride; int width = this->source_width; uint8_t *img; /* rgb_stride -= 4 * this->dest_width; */ width >>= 3; if (!this->do_scale) { height = this_gen->next_slice (this_gen, &image); y_stride -= 8 * width; uv_stride -= 4 * width; do { i = width; img = image; do { mmx_yuv2rgb (py, pu, pv, this->table_mmx); mmx_unpack_32rgb (img, cpu); py += 8; pu += 4; pv += 4; img += 32; } while (--i); py += y_stride; image += rgb_stride; if (height & 1) { pu += uv_stride; pv += uv_stride; } else { pu -= 4 * width; pv -= 4 * width; } } while (--height); } else { scale_line_func_t scale_line = this->scale_line; uint8_t *y_buf, *u_buf, *v_buf; int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (py, this->y_buffer, this->dest_width, this->step_dx); dst_height = this_gen->next_slice (this_gen, &image); for (height = 0;; ) { y_buf = this->y_buffer; u_buf = this->u_buffer; v_buf = this->v_buffer; i = this->dest_width >> 3; img=image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf, this->table_mmx); mmx_unpack_32rgb (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; img += 32; } while (--i); dy += this->step_dy; image += rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (image, image-rgb_stride, this->dest_width*4); dy += this->step_dy; image += rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; py += y_stride; scale_line (py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { pu += uv_stride; pv += uv_stride; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } } static inline void yuv420_abgr32 (yuv2rgb_t *this_gen, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv, int cpu) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int i, height, dst_height; int rgb_stride = this->rgb_stride; int y_stride = this->y_stride; int uv_stride = this->uv_stride; int width = this->source_width; uint8_t *img; /* rgb_stride -= 4 * this->dest_width; */ width >>= 3; if (!this->do_scale) { height = this_gen->next_slice (this_gen, &image); y_stride -= 8 * width; uv_stride -= 4 * width; do { i = width; img = image; do { mmx_yuv2rgb (py, pu, pv, this->table_mmx); mmx_unpack_32bgr (img, cpu); py += 8; pu += 4; pv += 4; img += 32; } while (--i); py += y_stride; image += rgb_stride; if (height & 1) { pu += uv_stride; pv += uv_stride; } else { pu -= 4 * width; pv -= 4 * width; } } while (--height); } else { scale_line_func_t scale_line = this->scale_line; uint8_t *y_buf, *u_buf, *v_buf; int dy = 0; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (py, this->y_buffer, this->dest_width, this->step_dx); dst_height = this_gen->next_slice (this_gen, &image); for (height = 0;; ) { y_buf = this->y_buffer; u_buf = this->u_buffer; v_buf = this->v_buffer; i = this->dest_width >> 3; img=image; do { /* printf ("i : %d\n",i); */ mmx_yuv2rgb (y_buf, u_buf, v_buf, this->table_mmx); mmx_unpack_32bgr (img, cpu); y_buf += 8; u_buf += 4; v_buf += 4; img += 32; } while (--i); dy += this->step_dy; image += rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (image, image-rgb_stride, this->dest_width*4); dy += this->step_dy; image += rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; py += y_stride; scale_line (py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { pu += uv_stride; pv += uv_stride; scale_line (pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } } static void mmxext_rgb15 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_rgb15 (this, image, py, pu, pv, CPU_MMXEXT); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmxext_rgb16 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_rgb16 (this, image, py, pu, pv, CPU_MMXEXT); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmxext_rgb24 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_rgb24 (this, image, py, pu, pv, CPU_MMXEXT); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmxext_argb32 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_argb32 (this, image, py, pu, pv, CPU_MMXEXT); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmxext_abgr32 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_abgr32 (this, image, py, pu, pv, CPU_MMXEXT); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmx_rgb15 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_rgb15 (this, image, py, pu, pv, CPU_MMX); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmx_rgb16 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_rgb16 (this, image, py, pu, pv, CPU_MMX); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmx_rgb24 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_rgb24 (this, image, py, pu, pv, CPU_MMX); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmx_bgr24 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_bgr24 (this, image, py, pu, pv, CPU_MMX); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmx_argb32 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_argb32 (this, image, py, pu, pv, CPU_MMX); emms(); /* re-initialize x86 FPU after MMX use */ } static void mmx_abgr32 (yuv2rgb_t *this, uint8_t * image, const uint8_t * py, const uint8_t * pu, const uint8_t * pv) { yuv420_abgr32 (this, image, py, pu, pv, CPU_MMX); emms(); /* re-initialize x86 FPU after MMX use */ } void yuv2rgb_init_mmxext (yuv2rgb_factory_impl_t *this) { if (this->swapped) return; /*no swapped pixel output upto now*/ switch (this->mode) { case MODE_15_RGB: this->yuv2rgb_fun = mmxext_rgb15; break; case MODE_16_RGB: this->yuv2rgb_fun = mmxext_rgb16; break; case MODE_24_RGB: this->yuv2rgb_fun = mmxext_rgb24; break; case MODE_32_RGB: this->yuv2rgb_fun = mmxext_argb32; break; case MODE_32_BGR: this->yuv2rgb_fun = mmxext_abgr32; break; } } void yuv2rgb_init_mmx (yuv2rgb_factory_impl_t *this) { if (this->swapped) switch (this->mode) { case MODE_24_RGB: this->yuv2rgb_fun = mmx_bgr24; return; case MODE_24_BGR: this->yuv2rgb_fun = mmx_rgb24; return; default: return; /* other swapped formats yet unsupported */ } switch (this->mode) { case MODE_15_RGB: this->yuv2rgb_fun = mmx_rgb15; break; case MODE_16_RGB: this->yuv2rgb_fun = mmx_rgb16; break; case MODE_24_RGB: this->yuv2rgb_fun = mmx_rgb24; break; case MODE_24_BGR: this->yuv2rgb_fun = mmx_bgr24; break; case MODE_32_RGB: this->yuv2rgb_fun = mmx_argb32; break; case MODE_32_BGR: this->yuv2rgb_fun = mmx_abgr32; break; } } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/sorted_array.c����������������������������������������������������������0000644�0001750�0001750�00000031463�14647725152�016425� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * rewritten by Torsten Jager <t.jager@gmx.de> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <xine/attributes.h> #include <xine/sorted_array.h> #include <xine/os_types.h> #define MIN_CHUNK_SIZE 64 /* Array internal struct */ struct xine_sarray_s { void **chunk; size_t chunk_size; size_t size; xine_sarray_comparator_t comparator; int (*find) (xine_sarray_t *sarray, void *key); unsigned int mode; unsigned int last_add[2]; unsigned int first_test; unsigned int same_dir; unsigned int unique_test; unsigned int add_here; struct { int *table; xine_sarray_hash_func_t user_get; void (*get) (xine_sarray_t *sarray, void *item); unsigned int size; unsigned int start; unsigned int stop; unsigned int last_value; unsigned int value; } hash; void *default_chunk[1]; }; static void _xine_sarray_hash_get (xine_sarray_t *sarray, void *item) { unsigned int value = sarray->hash.user_get (item); if (value > sarray->hash.size - 1) value = sarray->hash.size - 1; sarray->hash.value = value; sarray->hash.start = sarray->hash.table[value]; sarray->hash.stop = sarray->hash.table[value + 1]; } static void _xine_sarray_hash_none (xine_sarray_t *sarray, void *item) { (void)item; sarray->hash.value = 0; sarray->hash.start = 0; sarray->hash.stop = sarray->size; } static void _xine_sarray_hash_insert (xine_sarray_t *sarray) { if (sarray->hash.table) { unsigned int u; for (u = sarray->hash.value + 1; u <= sarray->hash.size; u++) sarray->hash.table[u] += 1; sarray->hash.last_value = sarray->hash.value; } } static void _xine_sarray_hash_remove (xine_sarray_t *sarray, void *item) { if (sarray->hash.table) { unsigned int u; sarray->hash.get (sarray, item); for (u = sarray->hash.value + 1; u <= sarray->hash.size; u++) sarray->hash.table[u] -= 1; } } static int _xine_sarray_find_default (xine_sarray_t *sarray, void *key) { unsigned int b = sarray->hash.start, e = sarray->hash.stop, m = sarray->first_test; while (b != e) { int d = sarray->comparator (key, sarray->chunk[m]); if (d == 0) { sarray->add_here = m; return m; /* found */ } if (d < 0) e = m; else b = m + 1; m = (b + e) >> 1; } sarray->add_here = m; return ~m; /* not found */ } static int _xine_sarray_find_first (xine_sarray_t *sarray, void *key) { unsigned int b = sarray->hash.start, e = sarray->hash.stop, m = sarray->first_test; while (b != e) { int d = sarray->comparator (key, sarray->chunk[m]); if (d == 0) break; if (d < 0) e = m; else b = m + 1; m = (b + e) >> 1; } sarray->add_here = m; if (b == e) return ~m; e = m; m = (b + e) >> 1; while (b != e) { int d = sarray->comparator (key, sarray->chunk[m]); if (d <= 0) e = m; else b = m + 1; m = (b + e) >> 1; } sarray->add_here = b; return b; } static int _xine_sarray_find_last (xine_sarray_t *sarray, void *key) { unsigned int b = sarray->hash.start, e = sarray->hash.stop, m = sarray->first_test; while (b != e) { int d = sarray->comparator (key, sarray->chunk[m]); if (d == 0) break; if (d < 0) e = m; else b = m + 1; m = (b + e) >> 1; } sarray->add_here = m; if (b == e) return ~m; b = m + 1; m = (b + e) >> 1; while (b != e) { int d = sarray->comparator (key, sarray->chunk[m]); if (d < 0) e = m; else b = m + 1; m = (b + e) >> 1; } sarray->add_here = b; return b - 1; } int xine_sarray_binary_search (xine_sarray_t *sarray, void *key) { if (!sarray) return ~0; /* not found */ sarray->hash.get (sarray, key); sarray->first_test = (sarray->hash.start + sarray->hash.stop) >> 1; return sarray->find (sarray, key); } static int _xine_sarray_dummy_comp (void *item1, void *item2) { intptr_t d = (intptr_t)item1, e = (intptr_t)item2; return d < e ? -1 : d > e ? 1 : 0; } /* Constructor */ xine_sarray_t *xine_sarray_new (size_t initial_size, xine_sarray_comparator_t comparator) { xine_sarray_t *new_sarray; if (!comparator) comparator = _xine_sarray_dummy_comp; if (initial_size < MIN_CHUNK_SIZE) initial_size = MIN_CHUNK_SIZE; new_sarray = malloc (sizeof (*new_sarray) + initial_size * sizeof (void *)); if (!new_sarray) return NULL; new_sarray->size = 0; new_sarray->last_add[0] = 0; new_sarray->last_add[1] = 0; new_sarray->same_dir = 0; new_sarray->hash.table = NULL; new_sarray->hash.user_get = NULL; new_sarray->hash.start = 0; new_sarray->hash.stop = 0; new_sarray->hash.value = 0; new_sarray->hash.last_value = 0; new_sarray->chunk_size = initial_size; new_sarray->comparator = comparator; new_sarray->find = _xine_sarray_find_default; new_sarray->chunk = &new_sarray->default_chunk[0]; new_sarray->mode = XINE_SARRAY_MODE_DEFAULT; new_sarray->hash.get = _xine_sarray_hash_none; new_sarray->hash.size = 1; new_sarray->unique_test = 0; new_sarray->add_here = 0; return new_sarray; } /* Destructor */ void xine_sarray_delete (xine_sarray_t *sarray) { if (sarray) { if (sarray->chunk != &sarray->default_chunk[0]) free (sarray->chunk); free (sarray->hash.table); free (sarray); } } void xine_sarray_set_hash (xine_sarray_t *sarray, xine_sarray_hash_func_t hash_func, unsigned int hash_size) { if (!sarray) return; if (sarray->hash.user_get == hash_func) return; free (sarray->hash.table); sarray->hash.table = NULL; sarray->hash.user_get = NULL; sarray->hash.get = _xine_sarray_hash_none; sarray->hash.size = 1; if (hash_func && (hash_size > 1) && (hash_size <= 4096) && ((sarray->hash.table = calloc (1, (hash_size + 1) * sizeof (*sarray->hash.table))))) { sarray->hash.user_get = hash_func; sarray->hash.get = _xine_sarray_hash_get; sarray->hash.size = hash_size; } } size_t xine_sarray_size (const xine_sarray_t *sarray) { return sarray ? sarray->size : 0; } void xine_sarray_set_mode (xine_sarray_t *sarray, unsigned int mode) { if (sarray) { sarray->mode = mode; sarray->find = (mode & XINE_SARRAY_MODE_FIRST) ? _xine_sarray_find_first : (mode & XINE_SARRAY_MODE_LAST) ? _xine_sarray_find_last : _xine_sarray_find_default; sarray->unique_test = (mode & XINE_SARRAY_MODE_UNIQUE) ? 1 << (sizeof (sarray->unique_test) * 8 - 1) : 0; } } void *xine_sarray_get (xine_sarray_t *sarray, unsigned int position) { if (sarray) { if (position < sarray->size) return sarray->chunk[position]; } return NULL; } void xine_sarray_clear (xine_sarray_t *sarray) { if (sarray) { sarray->size = 0; sarray->last_add[0] = 0; sarray->last_add[1] = 0; sarray->same_dir = 0; if (sarray->hash.table) { unsigned int u; for (u = 0; u <= sarray->hash.size; u++) sarray->hash.table[u] = 0; } } } void xine_sarray_move_location (xine_sarray_t *sarray, void *new_ptr, unsigned int position) { if (sarray && (position < sarray->size)) { if (new_ptr) { sarray->chunk[position] = new_ptr; } else { void **here = sarray->chunk + position; unsigned int u = sarray->size - position - 1; while (u--) { here[0] = here[1]; here++; } sarray->size--; sarray->last_add[0] = 0; sarray->last_add[1] = 0; sarray->same_dir = 0; } } } void *xine_sarray_remove (xine_sarray_t *sarray, unsigned int position) { void *item = NULL; if (sarray) { if (position < sarray->size) { void **here = sarray->chunk + position; unsigned int u = sarray->size - position - 1; item = *here; while (u--) { here[0] = here[1]; here++; } sarray->size--; sarray->last_add[0] = 0; sarray->last_add[1] = 0; sarray->same_dir = 0; _xine_sarray_hash_remove (sarray, item); } } return item; } int xine_sarray_remove_ptr (xine_sarray_t *sarray, void *ptr) { if (sarray) { int ret; void **here = sarray->chunk, **end = here + sarray->size; *end = ptr; while (*here != ptr) here++; if (here >= end) return ~0; ret = here - sarray->chunk; end--; while (here < end) { here[0] = here[1]; here++; } sarray->size--; sarray->last_add[0] = 0; sarray->last_add[1] = 0; sarray->same_dir = 0; _xine_sarray_hash_remove (sarray, ptr); return ret; } return ~0; } static void _xine_sarray_insert (xine_sarray_t *sarray, void *value) { unsigned int pos = sarray->add_here; if (sarray->size + 1 > sarray->chunk_size) { size_t new_size; void **new_chunk; new_size = 2 * (sarray->size + 1); if (new_size < MIN_CHUNK_SIZE) new_size = MIN_CHUNK_SIZE; if (sarray->chunk == &sarray->default_chunk[0]) { new_chunk = malloc ((new_size + 1) * sizeof (void *)); if (!new_chunk) return; memcpy (new_chunk, sarray->chunk, sarray->size * sizeof (void *)); } else { new_chunk = realloc (sarray->chunk, (new_size + 1) * sizeof (void *)); if (!new_chunk) return; } sarray->chunk = new_chunk; sarray->chunk_size = new_size; } /* this database is often built from already sorted items. optimize for that. */ { int d = ((int)sarray->last_add[1] - (int)sarray->last_add[0]) ^ ((int)sarray->last_add[0] - (int)pos); sarray->same_dir = d < 0 ? 0 : sarray->same_dir + 1; } sarray->last_add[1] = sarray->last_add[0]; sarray->last_add[0] = pos; { unsigned int u = sarray->size - pos; if (!u) { sarray->chunk[sarray->size++] = value; } else { void **here = sarray->chunk + sarray->size; do { here[0] = here[-1]; here--; } while (--u); here[0] = value; sarray->size++; } } _xine_sarray_hash_insert (sarray); } int xine_sarray_add (xine_sarray_t *sarray, void *value) { if (sarray) { unsigned int pos2; sarray->hash.get (sarray, value); if ((sarray->same_dir >= 2) && (sarray->hash.value == sarray->hash.last_value)) sarray->first_test = sarray->last_add[0]; else sarray->first_test = (sarray->hash.start + sarray->hash.stop) >> 1; pos2 = ~sarray->find (sarray, value); if (pos2 & sarray->unique_test) return pos2; _xine_sarray_insert (sarray, value); return sarray->add_here; } return 0; } unsigned int xine_sarray_hash_quality (xine_sarray_t *sarray) { unsigned int mine, maxe, sum, u /*, v */; /* NOTE: rational math with denominator == hash_size. */ if (!sarray) return 0; if (!sarray->hash.table || !sarray->hash.size) return 0; if (sarray->hash.size == 1) return 1000; u = sarray->size % sarray->hash.size; /* v = sarray->size / sarray->hash.size; */ /* a perfect fill would be u * (v + 1) + (hash_size - u) * v. * this makes a minimum error of: mine = u * ((v + 1) * sarray->hash.size - sarray->size) + (sarray->hash.size - u) * (sarray->size - v * sarray->hash.size); */ mine = u * (sarray->hash.size - u) * 2; /* the worst result would be all entries jamming the same hash value: maxe = 1 * (sarray->size * sarray->hash.size - sarray->size) + (sarray->hash.size - 1) * sarray->size; */ maxe = (sarray->hash.size - 1) * sarray->size * 2; /* get the total error. */ sum = 0; for (u = 0; u < sarray->hash.size; u++) { unsigned int fill = (sarray->hash.table[u + 1] - sarray->hash.table[u]) * sarray->hash.size; int diff = (int)sarray->size - (int)fill; sum += (diff < 0) ? -diff : diff; } if (sum <= mine) /** << also gets (sarray->size == 0). */ return 1000; if (sum >= maxe) /** << also gets (mine >= maxe). */ return 0; sum = maxe - sum; maxe -= mine; return (sum * 1000u + (maxe >> 1)) / maxe; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/utils.c�����������������������������������������������������������������0000644�0001750�0001750�00000213602�14647725152�015064� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #define _POSIX_PTHREAD_SEMANTICS 1 /* for 5-arg getpwuid_r on solaris */ /* #define LOG */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xineutils.h> #include <xine/xineintl.h> #ifdef _MSC_VER #include <xine/xine_internal.h> #endif #include "xine_private.h" #include "../xine-engine/bswap.h" #include <errno.h> #ifdef HAVE_PWD_H #include <pwd.h> #endif #include <sys/types.h> #include <sys/time.h> #include <time.h> #include <unistd.h> #include <fcntl.h> #include <ctype.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #if HAVE_EXECINFO_H #include <execinfo.h> #endif #if HAVE_UCONTEXT_H #include <ucontext.h> #endif #ifdef HAVE_NL_LANGINFO #include <langinfo.h> #endif #if defined(WIN32) #include <windows.h> #include <shlobj.h> #endif #ifndef O_CLOEXEC # define O_CLOEXEC 0 #endif typedef struct { const char language[16]; /* name of the locale */ const char encoding[16]; /* typical encoding */ const char spu_encoding[16]; /* default spu encoding */ const char modifier[8]; } lang_locale_t; /* * information about locales used in xine */ static const lang_locale_t lang_locales[] = { { "af_ZA", "iso-8859-1", "iso-8859-1", "" }, { "ar_AE", "iso-8859-6", "iso-8859-6", "" }, { "ar_BH", "iso-8859-6", "iso-8859-6", "" }, { "ar_DZ", "iso-8859-6", "iso-8859-6", "" }, { "ar_EG", "iso-8859-6", "iso-8859-6", "" }, { "ar_IN", "utf-8", "utf-8", "" }, { "ar_IQ", "iso-8859-6", "iso-8859-6", "" }, { "ar_JO", "iso-8859-6", "iso-8859-6", "" }, { "ar_KW", "iso-8859-6", "iso-8859-6", "" }, { "ar_LB", "iso-8859-6", "iso-8859-6", "" }, { "ar_LY", "iso-8859-6", "iso-8859-6", "" }, { "ar_MA", "iso-8859-6", "iso-8859-6", "" }, { "ar_OM", "iso-8859-6", "iso-8859-6", "" }, { "ar_QA", "iso-8859-6", "iso-8859-6", "" }, { "ar_SA", "iso-8859-6", "iso-8859-6", "" }, { "ar_SD", "iso-8859-6", "iso-8859-6", "" }, { "ar_SY", "iso-8859-6", "iso-8859-6", "" }, { "ar_TN", "iso-8859-6", "iso-8859-6", "" }, { "ar_YE", "iso-8859-6", "iso-8859-6", "" }, { "be_BY", "cp1251", "cp1251", "" }, { "bg_BG", "cp1251", "cp1251", "" }, { "br_FR", "iso-8859-1", "iso-88591", "" }, { "bs_BA", "iso-8859-2", "cp1250", "" }, { "ca_ES", "iso-8859-1", "iso-88591", "" }, { "ca_ES", "iso-8859-15", "iso-8859-15", "euro" }, { "cs_CZ", "iso-8859-2", "cp1250", "" }, { "cy_GB", "iso-8859-14", "iso-8859-14", "" }, { "da_DK", "iso-8859-1", "iso-8859-1", "" }, { "de_AT", "iso-8859-1", "iso-8859-1", "" }, { "de_AT", "iso-8859-15", "iso-8859-15", "euro" }, { "de_BE", "iso-8859-1", "iso-8859-1", "" }, { "de_BE", "iso-8859-15", "iso-8859-15", "euro" }, { "de_CH", "iso-8859-1", "iso-8859-1", "" }, { "de_DE", "iso-8859-1", "iso-8859-1", "" }, { "de_DE", "iso-8859-15", "iso-8859-15", "euro" }, { "de_LU", "iso-8859-1", "iso-8859-1", "" }, { "de_LU", "iso-8859-15", "iso-8859-15", "euro" }, { "el_GR", "iso-8859-7", "iso-8859-7", "" }, { "en_AU", "iso-8859-1", "iso-8859-1", "" }, { "en_BW", "iso-8859-1", "iso-8859-1", "" }, { "en_CA", "iso-8859-1", "iso-8859-1", "" }, { "en_DK", "iso-8859-1", "iso-8859-1", "" }, { "en_GB", "iso-8859-1", "iso-8859-1", "" }, { "en_HK", "iso-8859-1", "iso-8859-1", "" }, { "en_IE", "iso-8859-1", "iso-8859-1", "" }, { "en_IE", "iso-8859-15", "iso-8859-15", "euro" }, { "en_IN", "utf-8", "utf-8", "" }, { "en_NZ", "iso-8859-1", "iso-8859-1", "" }, { "en_PH", "iso-8859-1", "iso-8859-1", "" }, { "en_SG", "iso-8859-1", "iso-8859-1", "" }, { "en_US", "iso-8859-1", "iso-8859-1", "" }, { "en_ZA", "iso-8859-1", "iso-8859-1", "" }, { "en_ZW", "iso-8859-1", "iso-8859-1", "" }, { "es_AR", "iso-8859-1", "iso-8859-1", "" }, { "es_BO", "iso-8859-1", "iso-8859-1", "" }, { "es_CL", "iso-8859-1", "iso-8859-1", "" }, { "es_CO", "iso-8859-1", "iso-8859-1", "" }, { "es_CR", "iso-8859-1", "iso-8859-1", "" }, { "es_DO", "iso-8859-1", "iso-8859-1", "" }, { "es_EC", "iso-8859-1", "iso-8859-1", "" }, { "es_ES", "iso-8859-1", "iso-8859-1", "" }, { "es_ES", "iso-8859-15", "iso-8859-15", "euro" }, { "es_GT", "iso-8859-1", "iso-8859-1", "" }, { "es_HN", "iso-8859-1", "iso-8859-1", "" }, { "es_MX", "iso-8859-1", "iso-8859-1", "" }, { "es_NI", "iso-8859-1", "iso-8859-1", "" }, { "es_PA", "iso-8859-1", "iso-8859-1", "" }, { "es_PE", "iso-8859-1", "iso-8859-1", "" }, { "es_PR", "iso-8859-1", "iso-8859-1", "" }, { "es_PY", "iso-8859-1", "iso-8859-1", "" }, { "es_SV", "iso-8859-1", "iso-8859-1", "" }, { "es_US", "iso-8859-1", "iso-8859-1", "" }, { "es_UY", "iso-8859-1", "iso-8859-1", "" }, { "es_VE", "iso-8859-1", "iso-8859-1", "" }, { "et_EE", "iso-8859-1", "iso-8859-1", "" }, { "eu_ES", "iso-8859-1", "iso-8859-1", "" }, { "eu_ES", "iso-8859-15", "iso-8859-15", "euro" }, { "fa_IR", "utf-8", "utf-8", "" }, { "fi_FI", "iso-8859-1", "iso-8859-1", "" }, { "fi_FI", "iso-8859-15", "iso-8859-15", "euro" }, { "fo_FO", "iso-8859-1", "iso-8859-1", "" }, { "fr_BE", "iso-8859-1", "iso-8859-1", "" }, { "fr_BE", "iso-8859-15", "iso-8859-15", "euro" }, { "fr_CA", "iso-8859-1", "iso-8859-1", "" }, { "fr_CH", "iso-8859-1", "iso-8859-1", "" }, { "fr_FR", "iso-8859-1", "iso-8859-1", "" }, { "fr_FR", "iso-8859-15", "iso-8859-15", "euro" }, { "fr_LU", "iso-8859-1", "iso-8859-1", "" }, { "fr_LU", "iso-8859-15", "iso-8859-15", "euro" }, { "ga_IE", "iso-8859-1", "iso-8859-1", "" }, { "ga_IE", "iso-8859-15", "iso-8859-15", "euro" }, { "gl_ES", "iso-8859-1", "iso-8859-1", "" }, { "gl_ES", "iso-8859-15", "iso-8859-15", "euro" }, { "gv_GB", "iso-8859-1", "iso-8859-1", "" }, { "he_IL", "iso-8859-8", "iso-8859-8", "" }, { "hi_IN", "utf-8", "utf-8", "" }, { "hr_HR", "iso-8859-2", "cp1250", "" }, { "hu_HU", "iso-8859-2", "cp1250", "" }, { "id_ID", "iso-8859-1", "iso-8859-1", "" }, { "is_IS", "iso-8859-1", "iso-8859-1", "" }, { "it_CH", "iso-8859-1", "iso-8859-1", "" }, { "it_IT", "iso-8859-1", "iso-8859-1", "" }, { "it_IT", "iso-8859-15", "iso-8859-15", "euro" }, { "iw_IL", "iso-8859-8", "iso-8859-8", "" }, { "ja_JP", "euc-jp", "euc-jp", "" }, { "ja_JP", "ujis", "ujis", "" }, { "japanese", "euc", "euc", "" }, { "ka_GE", "georgian-ps", "georgian-ps", "" }, { "kl_GL", "iso-8859-1", "iso-8859-1", "" }, { "ko_KR", "euc-kr", "euc-kr", "" }, { "ko_KR", "utf-8", "utf-8", "" }, { "korean", "euc", "euc", "" }, { "kw_GB", "iso-8859-1", "iso-8859-1", "" }, { "lt_LT", "iso-8859-13", "iso-8859-13", "" }, { "lv_LV", "iso-8859-13", "iso-8859-13", "" }, { "mi_NZ", "iso-8859-13", "iso-8859-13", "" }, { "mk_MK", "iso-8859-5", "cp1251", "" }, { "mr_IN", "utf-8", "utf-8", "" }, { "ms_MY", "iso-8859-1", "iso-8859-1", "" }, { "mt_MT", "iso-8859-3", "iso-8859-3", "" }, { "nb_NO", "ISO-8859-1", "ISO-8859-1", "" }, { "nl_BE", "iso-8859-1", "iso-8859-1", "" }, { "nl_BE", "iso-8859-15", "iso-8859-15", "euro" }, { "nl_NL", "iso-8859-1", "iso-8859-1", "" }, { "nl_NL", "iso-8859-15", "iso-8859-15", "euro" }, { "nn_NO", "iso-8859-1", "iso-8859-1", "" }, { "no_NO", "iso-8859-1", "iso-8859-1", "" }, { "oc_FR", "iso-8859-1", "iso-8859-1", "" }, { "pl_PL", "iso-8859-2", "cp1250", "" }, { "pt_BR", "iso-8859-1", "iso-8859-1", "" }, { "pt_PT", "iso-8859-1", "iso-8859-1", "" }, { "pt_PT", "iso-8859-15", "iso-8859-15", "euro" }, { "ro_RO", "iso-8859-2", "cp1250", "" }, { "ru_RU", "iso-8859-5", "cp1251", "" }, { "ru_RU", "koi8-r", "cp1251", "" }, { "ru_UA", "koi8-u", "cp1251", "" }, { "se_NO", "utf-8", "utf-8", "" }, { "sk_SK", "iso-8859-2", "cp1250", "" }, { "sl_SI", "iso-8859-2", "cp1250", "" }, { "sq_AL", "iso-8859-1", "iso-8859-1", "" }, { "sr_YU", "iso-8859-2", "cp1250", "" }, { "sr_YU", "iso-8859-5", "cp1251", "cyrillic" }, { "sv_FI", "iso-8859-1", "iso-8859-1", "" }, { "sv_FI", "iso-8859-15", "iso-8859-15", "euro" }, { "sv_SE", "iso-8859-1", "iso-8859-1", "" }, { "ta_IN", "utf-8", "utf-8", "" }, { "te_IN", "utf-8", "utf-8", "" }, { "tg_TJ", "koi8-t", "cp1251", "" }, { "th_TH", "tis-620", "tis-620", "" }, { "tl_PH", "iso-8859-1", "iso-8859-1", "" }, { "tr_TR", "iso-8859-9", "iso-8859-9", "" }, { "uk_UA", "koi8-u", "cp1251", "" }, { "ur_PK", "utf-8", "utf-8", "" }, { "uz_UZ", "iso-8859-1", "iso-8859-1", "" }, { "vi_VN", "tcvn", "tcvn", "" }, { "vi_VN", "utf-8", "utf-8", "" }, { "wa_BE", "iso-8859-1", "iso-8859-1", "" }, { "wa_BE", "iso-8859-15", "iso-8859-15", "euro" }, { "yi_US", "cp1255", "cp1255", "" }, { "zh_CN", "gb18030", "gb18030", "" }, { "zh_CN", "gb2312", "gb2312", "" }, { "zh_CN", "gbk", "gbk", "" }, { "zh_HK", "big5-hkscs", "big5-hkscs", "" }, { "zh_TW", "big-5", "big-5", "" }, { "zh_TW", "euc-tw", "euc-tw", "" }, }; /** * @brief Allocate and clean memory size_t 'size', then return the * pointer to the allocated memory. * @param size Size of the memory area to allocate. * * @return A pointer to the allocated memory area, or NULL in case of * error. * * The behaviour of this function differs from standard malloc() as * xine_xmalloc(0) will not return a NULL pointer, but rather a * pointer to a memory area of size 1 byte. * * The NULL value is only ever returned in case of an error in * malloc(), and is reported to stderr stream. * * @deprecated This function has been deprecated, as the behaviour of * allocating a 1 byte memory area on zero size is almost * never desired, and the function is thus mostly misused. */ void *xine_xmalloc(size_t size) { void *ptr; /* prevent xine_xmalloc(0) of possibly returning NULL */ if( !size ) size++; if((ptr = calloc(1, size)) == NULL) { fprintf(stderr, "%s: malloc() failed: %s.\n", __XINE_FUNCTION__, strerror(errno)); return NULL; } return ptr; } /** * @brief Wrapper around calloc() function. * @param nmemb Number of elements to allocate * @param size Size of each element to allocate * * This is a simple wrapper around calloc(), the only thing * it does more than calloc() is outputting an error if * the calloc fails (returning NULL). */ void *xine_xcalloc(size_t nmemb, size_t size) { void *ptr; if((ptr = calloc(nmemb, size)) == NULL) { fprintf(stderr, "%s: calloc() failed: %s.\n", __XINE_FUNCTION__, strerror(errno)); return NULL; } return ptr; } void *xine_memdup (const void *src, size_t length) { void *dst = malloc (length); if (!dst) { return NULL; } return xine_fast_memcpy (dst, src, length); } void *xine_memdup0 (const void *src, size_t length) { char *dst = malloc (length + 1); if (!dst) { return NULL; } dst[length] = 0; return xine_fast_memcpy (dst, src, length); } #ifdef __CYGWIN__ /* * Parse command line with Windows XP syntax and copy the command (argv[0]). */ static size_t xine_strcpy_command(const char *cmdline, char *cmd, size_t maxlen) { size_t i, j; i = 0; j = 0; while (cmdline[i] && isspace(cmdline[i])) i++; while (cmdline[i] && !isspace(cmdline[i]) && j + 2 < maxlen) { switch (cmdline[i]) { case '\"': i++; while (cmdline[i] && cmdline[i] != '\"') { if (cmdline[i] == '\\') { i++; if (cmdline[i] == '\"') cmd[j++] = '\"'; else { cmd[j++] = '\\'; cmd[j++] = cmdline[i]; } } else cmd[j++] = cmdline[i]; if (cmdline[i]) i++; } break; case '\\': i++; if (cmdline[i] == '\"') cmd[j++] = '\"'; else { cmd[j++] = '\\'; i--; } break; default: cmd[j++] = cmdline[i]; } i++; } cmd[j] = '\0'; return j; } #endif #ifndef BUFSIZ #define BUFSIZ 256 #endif const char *xine_get_homedir(void) { #if defined(__CYGWIN__) static char homedir[1024] = {0, }; char *s; xine_strcpy_command(GetCommandLine(), homedir, sizeof(homedir)); s = strdup(homedir); GetFullPathName(s, sizeof(homedir), homedir, NULL); free(s); if ((s = strrchr(homedir, '\\'))) *s = '\0'; return homedir; #elif defined (WIN32) static char homedir[MAX_PATH] = {0, }; wchar_t wdir[MAX_PATH]; /* Get the "Application Data" folder for the user */ if (!homedir[0]) { if (S_OK == SHGetFolderPathW(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, wdir)) { WideCharToMultiByte (CP_UTF8, 0, wdir, -1, homedir, MAX_PATH, NULL, NULL); } else { fprintf(stderr, "Can't find user configuration directory !\n"); } } return homedir; #else /* __CYGWIN__ , WIN32 */ struct passwd pwd, *pw = NULL; static char homedir[BUFSIZ] = {0,}; #ifdef HAVE_GETPWUID_R if(getpwuid_r(getuid(), &pwd, homedir, sizeof(homedir), &pw) != 0 || pw == NULL) #else if((pw = getpwuid(getuid())) == NULL) #endif { char *tmp = getenv("HOME"); if(tmp) { strncpy(homedir, tmp, sizeof(homedir)); homedir[sizeof(homedir) - 1] = '\0'; } } else { char *s = strdup(pw->pw_dir); strncpy(homedir, s, sizeof(homedir)); homedir[sizeof(homedir) - 1] = '\0'; free(s); } if(!homedir[0]) { printf("xine_get_homedir: Unable to get home directory, set it to /tmp.\n"); strcpy(homedir, "/tmp"); } return homedir; #endif /* __CYGWIN__ , WIN32 */ } #if defined(WIN32) || defined(__CYGWIN__) static void xine_get_rootdir(char *rootdir, size_t maxlen) { # if defined(__CYGWIN__) char *s; strncpy(rootdir, xine_get_homedir(), maxlen - 1); rootdir[maxlen - 1] = '\0'; if ((s = strrchr(rootdir, XINE_DIRECTORY_SEPARATOR_CHAR))) *s = '\0'; # else /* WIN32 */ /* use location of libxine.dll */ static char marker; HMODULE hModule; wchar_t wpath[MAX_PATH]; rootdir[0] = 0; if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCTSTR)&marker, &hModule)) { DWORD dw = GetModuleFileNameW(hModule, wpath, MAX_PATH); if (dw > 0 && dw < MAX_PATH) { WideCharToMultiByte(CP_UTF8, 0, wpath, -1, rootdir, maxlen, NULL, NULL); /* cut library name from path */ char *p = strrchr(rootdir, '\\'); if (p) { *p = 0; } lprintf("xine library dir is %s\n", rootdir); return; } } fprintf(stderr, "Can't determine libxine.dll install path\n"); # endif } const char *xine_get_pluginroot(void) { static char pluginroot[1024] = {0, }; if (!pluginroot[0]) { xine_get_rootdir(pluginroot, sizeof(pluginroot) - strlen(XINE_REL_PLUGINROOT) - 1); strcat(pluginroot, XINE_DIRECTORY_SEPARATOR_STRING XINE_REL_PLUGINROOT); } return pluginroot; } const char *xine_get_plugindir(void) { static char plugindir[1024] = {0, }; if (!plugindir[0]) { xine_get_rootdir(plugindir, sizeof(plugindir) - strlen(XINE_REL_PLUGINDIR) - 1); strcat(plugindir, XINE_DIRECTORY_SEPARATOR_STRING XINE_REL_PLUGINDIR); } return plugindir; } const char *xine_get_fontdir(void) { static char fontdir[1024] = {0, }; if (!fontdir[0]) { xine_get_rootdir(fontdir, sizeof(fontdir) - strlen(XINE_REL_FONTDIR) - 1); strcat(fontdir, XINE_DIRECTORY_SEPARATOR_STRING XINE_REL_FONTDIR); } return fontdir; } const char *xine_get_localedir(void) { static char localedir[1024] = {0, }; if (!localedir[0]) { xine_get_rootdir(localedir, sizeof(localedir) - strlen(XINE_REL_LOCALEDIR) - 1); strcat(localedir, XINE_DIRECTORY_SEPARATOR_STRING XINE_REL_LOCALEDIR); } return localedir; } #endif /* _WIN32 || __CYGWIN__ */ char *xine_chomp(char *str) { char *pbuf; pbuf = str; while(*pbuf != '\0') pbuf++; while(pbuf > str) { if(*pbuf == '\r' || *pbuf == '\n' || *pbuf == '"') *pbuf = '\0'; pbuf--; } while(*pbuf == '=') pbuf++; return pbuf; } /* * a thread-safe usecond sleep */ void xine_usec_sleep(unsigned usec) { #ifdef WIN32 /* select does not work on win32 */ Sleep(usec / 1000); #else # if 0 # if HAVE_NANOSLEEP /* nanosleep is prefered on solaris, because it's mt-safe */ struct timespec ts, remaining; ts.tv_sec = usec / 1000000; ts.tv_nsec = (usec % 1000000) * 1000; while (nanosleep (&ts, &remaining) == -1 && errno == EINTR) ts = remaining; # else usleep(usec); # endif # else if (usec < 10000) { usec = 10000; } struct timeval tm; tm.tv_sec = usec / 1000000; tm.tv_usec = usec % 1000000; select(0, 0, 0, 0, &tm); /* FIXME: EINTR? */ # endif #endif } /* print a hexdump of length bytes from the data given in buf */ void xine_hexdump (const void *buf_gen, int length) { static const char separator[70] = "---------------------------------------------------------------------"; const uint8_t *const buf = (const uint8_t*)buf_gen; int j = 0; /* printf ("Hexdump: %i Bytes\n", length);*/ puts(separator); while(j<length) { int i; const int imax = (j+16 < length) ? (j+16) : length; printf ("%04X ",j); for (i=j; i<j+16; i++) { if( i<length ) printf ("%02X ", buf[i]); else printf(" "); } for (i=j; i < imax; i++) { fputc ((buf[i] >= 32 && buf[i] <= 126) ? buf[i] : '.', stdout); } j=i; fputc('\n', stdout); } puts(separator); } static const lang_locale_t *_get_first_lang_locale(const char *lcal) { size_t lang_len; size_t i; char *mod; if(lcal && *lcal) { if ((mod = strchr(lcal, '@'))) lang_len = mod++ - lcal; else lang_len = strlen(lcal); for (i = 0; i < sizeof(lang_locales)/sizeof(lang_locales[0]); i++) { if(!strncmp(lcal, lang_locales[i].language, lang_len)) { if ((!mod && !lang_locales[i].modifier[0]) || (mod && lang_locales[i].modifier[0] && !strcmp(mod, lang_locales[i].modifier))) return &lang_locales[i]; } } } return NULL; } static char *_get_lang(void) { char *lang; if(!(lang = getenv("LC_ALL"))) if(!(lang = getenv("LC_MESSAGES"))) lang = getenv("LANG"); return lang; } /* * get encoding of current locale */ char *xine_get_system_encoding(void) { char *codeset = NULL; #ifdef HAVE_NL_LANGINFO setlocale(LC_CTYPE, ""); codeset = nl_langinfo(CODESET); #endif /* * guess locale codeset according to shell variables * when nl_langinfo(CODESET) isn't available or workig */ if (!codeset || strstr(codeset, "ANSI") != 0) { char *lang = _get_lang(); codeset = NULL; if(lang) { char *lg, *enc, *mod; lg = strdup(lang); if((enc = strchr(lg, '.')) && (strlen(enc) > 1)) { enc++; if((mod = strchr(enc, '@'))) *mod = '\0'; codeset = strdup(enc); } else { const lang_locale_t *llocale = _get_first_lang_locale(lg); if(llocale) codeset = strdup(llocale->encoding); } free(lg); } } else codeset = strdup(codeset); return codeset; } /* * guess default encoding of subtitles */ const char *xine_guess_spu_encoding(void) { char *lang = _get_lang(); if (lang) { const lang_locale_t *llocale; char *lg, *enc; lg = strdup(lang); if ((enc = strchr(lg, '.'))) *enc = '\0'; llocale = _get_first_lang_locale(lg); free(lg); if (llocale) return llocale->spu_encoding; } return "iso-8859-1"; } #ifdef _MSC_VER void xine_xprintf(xine_t *xine, int verbose, const char *fmt, ...) { char message[256]; va_list ap; if (xine && xine->verbosity >= verbose) { va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); xine_log(xine, XINE_LOG_TRACE, "%s", message); } } #endif int xine_monotonic_clock(struct timeval *tv, struct timezone *tz) { #if _POSIX_TIMERS > 0 && defined(_POSIX_MONOTONIC_CLOCK) && defined(HAVE_POSIX_TIMERS) static int xmc_mode = 0; do { struct timespec ts; if (xmc_mode > 1) { if (clock_gettime (CLOCK_MONOTONIC, &ts)) break; tv->tv_sec = ts.tv_sec; tv->tv_usec = ts.tv_nsec / 1000; return 0; } if (xmc_mode == 1) break; xmc_mode = 1; if (clock_getres (CLOCK_MONOTONIC, &ts)) { lprintf ("get resolution of monotonic clock failed\n"); break; } /* require at least milisecond resolution */ if ((ts.tv_sec > 0) || (ts.tv_nsec > 1000000)) { lprintf ("monotonic clock resolution (%d:%d) too bad\n", (int)ts.tv_sec, (int)ts.tv_nsec); break; } if (clock_gettime (CLOCK_MONOTONIC, &ts)) { lprintf ("get monotonic clock failed\n"); break; } lprintf ("using monotonic clock\n"); xmc_mode = 2; tv->tv_sec = ts.tv_sec; tv->tv_usec = ts.tv_nsec / 1000; return 0; } while (0); #endif return gettimeofday (tv, tz); } char *xine_strcat_realloc (char **dest, const char *append) { char *newstr = realloc (*dest, (*dest ? strlen (*dest) : 0) + strlen (append) + 1); if (newstr) strcat (*dest = newstr, append); return newstr; } char *_x_asprintf(const char *format, ...) { va_list ap; char *buf = NULL; va_start (ap, format); if (vasprintf (&buf, format, ap) < 0) buf = NULL; va_end (ap); return buf; } int _x_set_file_close_on_exec(int fd) { #ifndef WIN32 return fcntl(fd, F_SETFD, FD_CLOEXEC); #else return SetHandleInformation((HANDLE)_get_osfhandle(fd), HANDLE_FLAG_INHERIT, 0) ? 0 : -1; #endif } int _x_set_socket_close_on_exec(int s) { #ifndef WIN32 return fcntl(s, F_SETFD, FD_CLOEXEC); #else return SetHandleInformation((HANDLE)(intptr_t)s, HANDLE_FLAG_INHERIT, 0) ? 0 : -1; #endif } int xine_open_cloexec(const char *name, int flags) { int fd = open(name, (flags | O_CLOEXEC)); if (fd >= 0) { _x_set_file_close_on_exec(fd); } return fd; } int xine_create_cloexec(const char *name, int flags, mode_t mode) { int fd = open(name, (flags | O_CREAT | O_CLOEXEC), mode); if (fd >= 0) { _x_set_file_close_on_exec(fd); } return fd; } int xine_socket_cloexec(int domain, int type, int protocol) { int s = socket(domain, type, protocol); if (s >= 0) { _x_set_socket_close_on_exec(s); } return s; } /* get/resize/free aligned memory */ #ifndef XINE_MEM_ALIGN # define XINE_MEM_ALIGN 32 #endif #define XINE_MEM_ADD (sizeof (size_t) + XINE_MEM_ALIGN) #define XINE_MEM_MASK ((uintptr_t)XINE_MEM_ALIGN - 1) void *xine_mallocz_aligned (size_t size) { uint8_t *new; size_t *sp; new = calloc (1, size + XINE_MEM_ADD); if (!new) return NULL; sp = (size_t *)new; *sp = size; new = (uint8_t *)(((uintptr_t)new + XINE_MEM_ADD) & ~XINE_MEM_MASK); new[-1] = new - (uint8_t *)sp; return new; } void *xine_malloc_aligned (size_t size) { uint8_t *new; size_t *sp; new = malloc (size + XINE_MEM_ADD); if (!new) return NULL; sp = (size_t *)new; *sp = size; new = (uint8_t *)(((uintptr_t)new + XINE_MEM_ADD) & ~XINE_MEM_MASK); new[-1] = new - (uint8_t *)sp; return new; } void xine_free_aligned (void *ptr) { uint8_t *old = (uint8_t *)ptr; if (!old) return; old -= old[-1]; free (old); } void *xine_realloc_aligned (void *ptr, size_t size) { uint8_t *old = (uint8_t *)ptr, *new; size_t *sp, s; if (!size) { if (old) free (old - old[-1]); return NULL; } new = malloc (size + XINE_MEM_ADD); if (!new) return NULL; sp = (size_t *)new; *sp = size; new = (uint8_t *)(((uintptr_t)new + XINE_MEM_ADD) & ~XINE_MEM_MASK); new[-1] = new - (uint8_t *)sp; /* realloc () may break the alignment, requiring a slow memmove () afterwards */ if (old) { sp = (size_t *)(old - old[-1]); s = *sp; if (size < s) s = size; xine_fast_memcpy (new, old, s); free (sp); } return new; } /* Base64 transcoder, adapted from TJtools. */ size_t xine_base64_encode (uint8_t *from, char *to, size_t size) { static const uint8_t tab[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; const uint8_t *p = from; uint8_t *q = (uint8_t *)to; int l = size; from[size] = 0; from[size+1] = 0; while (l > 0) { uint32_t v = _X_BE_24 (p); p += 3; *q++ = tab[v >> 18]; *q++ = tab[(v >> 12) & 63]; *q++ = tab[(v >> 6) & 63]; *q++ = tab[v & 63]; l -= 3; } if (l < 0) { q[-1] = '='; if (l == -2) q[-2] = '='; } *q = 0; return q - (uint8_t *)to; } size_t xine_base64_decode (const char *from, uint8_t *to) { /* certain peopble use - _ instead of + /, lets support both ;-) */ #define rr 128 /* repeat */ #define ss 64 /* stop */ static const uint8_t tab_unbase64[256] = { ss,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr, rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr,rr, rr,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,62,ss,62,ss,63, 52,53,54,55,56,57,58,59,60,61,ss,ss,ss,ss,ss,ss, ss, 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,ss,ss,ss,ss,63, ss,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50,51,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss, ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss,ss }; const uint8_t *p = (const uint8_t *)from; uint8_t *q = to; while (1) { uint32_t v, b; do b = tab_unbase64[*p++]; while (b & rr); if (b & ss) break; v = b << 18; do b = tab_unbase64[*p++]; while (b & rr); if (b & ss) break; v |= b << 12; *q++ = v >> 16; do b = tab_unbase64[*p++]; while (b & rr); if (b & ss) break; v |= b << 6; *q++ = v >> 8; do b = tab_unbase64[*p++]; while (b & rr); if (b & ss) break; v |= b; *q++ = v; } #undef rr #undef ss return q - to; } /* XXX precalculate 5k instead? */ static uint32_t tab_crc32_ieee[1280] = {0, 0,}; static uint16_t tab_crc16_ansi[768] = {0, 0,}; /* gcc -O3 recognizes this as bswap32 () */ #define rev32(n) (((n) << 24) | (((n) << 8) & 0xff0000) | (((n) >> 8) & 0xff00) | ((n) >> 24)) #define rev16(n) ((((n) << 8) | ((n) >> 8)) & 0xffff) uint32_t xine_crc32_ieee (uint32_t crc, const uint8_t *data, size_t len) { uint32_t *t = tab_crc32_ieee; if (!t[1]) { uint32_t i; for (i = 0; i < 256; i++) { uint32_t j, u = i << 24; for (j = 0; j < 8; j++) u = (u << 1) ^ (((int32_t)u >> 31) & 0x4c11db7); t[i] = rev32 (u); } for (i = 0; i < 256; i++) { uint32_t v = t[i]; #ifdef WORDS_BIGENDIAN t[i + 256] = rev32 (v); v = (v >> 8) ^ t[v & 255]; t[i + 512] = rev32 (v); v = (v >> 8) ^ t[v & 255]; t[i + 768] = rev32 (v); v = (v >> 8) ^ t[v & 255]; t[i + 1024] = rev32 (v); #else t[i + 256] = v = (v >> 8) ^ t[v & 255]; t[i + 512] = v = (v >> 8) ^ t[v & 255]; t[i + 768] = (v >> 8) ^ t[v & 255]; #endif } } { size_t u; const uint32_t *d32; u = (~(uintptr_t)3 - (uintptr_t)data) & 3; if (u > len) u = len; len -= u; while (u) { crc = t[(uint8_t)crc ^ *data] ^ (crc >> 8); data++; u--; } d32 = (const uint32_t *)data; u = len / 4; #ifdef WORDS_BIGENDIAN crc = rev32 (crc); while (u) { crc ^= *d32++; crc = t[(crc >> 24) + 1024] ^ t[((crc >> 16) & 0xff) + 768] ^ t[((crc >> 8) & 0xff) + 512] ^ t[(crc & 0xff) + 256]; u--; } crc = rev32 (crc); #else while (u) { crc ^= *d32++; crc = t[(crc & 0xff) + 768] ^ t[((crc >> 8) & 0xff) + 512] ^ t[((crc >> 16) & 0xff) + 256] ^ t[crc >> 24]; u--; } #endif data = (const uint8_t *)d32; u = len & 3; while (u) { crc = t[(uint8_t)crc ^ *data] ^ (crc >> 8); data++; u--; } return crc; } } uint32_t xine_crc16_ansi (uint32_t crc, const uint8_t *data, size_t len) { uint16_t *t = tab_crc16_ansi; if (!t[1]) { uint32_t i; for (i = 0; i < 256; i++) { uint32_t j, u = i << 24; for (j = 0; j < 8; j++) u = (u << 1) ^ (((int32_t)u >> 31) & 0x80050000); t[i] = ((u >> 8) & 0xff00) | (u >> 24); } for (i = 0; i < 256; i++) { uint16_t v = t[i]; #ifdef WORDS_BIGENDIAN t[i + 256] = rev16 (v); v = (v >> 8) ^ t[v & 255]; t[i + 512] = rev16 (v); #else t[i + 256] = (v >> 8) ^ t[v & 255]; #endif } } { size_t u; const uint32_t *d32; crc &= 0xffff; u = (~(uintptr_t)3 - (uintptr_t)data) & 3; if (u > len) u = len; len -= u; while (u) { crc = t[(uint8_t)crc ^ *data] ^ (crc >> 8); data++; u--; } d32 = (const uint32_t *)data; u = len / 4; #ifdef WORDS_BIGENDIAN crc = rev16 (crc); while (u) { uint32_t v = *d32++; crc ^= v >> 16; crc = t[(crc >> 8) + 512] ^ t[(crc & 0xff) + 256]; crc ^= v & 0xffff; crc = t[(crc >> 8) + 512] ^ t[(crc & 0xff) + 256]; u--; } crc = rev16 (crc); #else while (u) { uint32_t v = *d32++; crc ^= v & 0xffff; crc = t[(crc & 255) + 256] ^ t[crc >> 8]; crc ^= v >> 16; crc = t[(crc & 255) + 256] ^ t[crc >> 8]; u--; } #endif data = (const uint8_t *)d32; u = len & 3; while (u) { crc = t[(uint8_t)crc ^ *data] ^ (crc >> 8); data++; u--; } return crc; } } /* fast string layout [uint32_t] (char): * <alignment> * [main_offs] * [max_strlen | (application supplied ? 0x80000000 : 0)] * [strlen] * fast_string_ptr -> * (string) (0x00) (0x00) */ #define XFST_ALIGN (16) #define XFST_MIN_SIZE ((XFST_ALIGN + 2 + XFST_ALIGN - 1) & ~(XFST_ALIGN - 1)) static const union { uint8_t z[4]; uint32_t v; } _xine_fast_string_mask[8] = { {{0xff, 0xff, 0xff, 0xff}}, {{0x00, 0xff, 0xff, 0xff}}, {{0x00, 0x00, 0xff, 0xff}}, {{0x00, 0x00, 0x00, 0xff}}, {{0x00, 0x00, 0x00, 0x00}}, {{0xff, 0x00, 0x00, 0x00}}, {{0xff, 0xff, 0x00, 0x00}}, {{0xff, 0xff, 0xff, 0x00}} }; size_t xine_fast_string_need (size_t max_strlen) { /* should be <= max_strlen + 32. */ return XFST_ALIGN - 1 + 3 * 4 + ((max_strlen + 2 + 3) & ~3); } char *xine_fast_string_init (char *buf, size_t bsize) { union { char *b; uint32_t *u; } u; uint32_t *fs; if (!buf || (bsize < XFST_MIN_SIZE)) return NULL; u.b = (char *)(((uintptr_t)buf + 3 * 4 + XFST_ALIGN - 1) & ~(XFST_ALIGN - 1)); fs = u.u; fs[-3] = (char *)fs - buf; fs[-2] = (bsize - fs[-3] - 2) | 0x80000000; fs[-1] = 0; fs[0] = 0; return (char *)fs; } size_t xine_fast_string_max (char *fast_string) { const union { char *b; uint32_t *u; } u = { fast_string }; uint32_t *fs = u.u; return fs ? (fs[-2] & 0x7fffffff) : 0; } char *xine_fast_string_set (char *fast_string, const char *text, size_t tsize) { const union { char *b; uint32_t *u; } u = { fast_string }; uint32_t *fs = u.u; if (fs) { if (fs[-2] & 0x80000000) { /* application supplied */ if (tsize > (fs[-2] & 0x7fffffff)) tsize = fs[-2] & 0x7fffffff; } else { /* auto reuse */ if (tsize > fs[-2]) { /* realloc */ size_t asize = (XFST_ALIGN + tsize + 2 + XFST_ALIGN - 1) & ~(XFST_ALIGN - 1); uint32_t *nfs = realloc (fs - (XFST_ALIGN >> 2), asize); if (nfs) { fs = nfs + (XFST_ALIGN >> 2); fs[-2] = asize - XFST_ALIGN - 2; } else { if (tsize > fs[-2]) tsize = fs[-2]; } } } } else { /* auto new */ size_t asize = (XFST_ALIGN + tsize + 2 + XFST_ALIGN - 1) & ~(XFST_ALIGN - 1); fs = malloc (asize); if (!fs) return NULL; fs += XFST_ALIGN >> 2; fs[-3] = XFST_ALIGN >> 2; fs[-2] = asize - XFST_ALIGN - 2; } fs[-1] = tsize; if (text) memcpy (fs, text, tsize); fs[tsize >> 2] &= _xine_fast_string_mask[4 + (tsize & 3)].v; tsize++; fs[tsize >> 2] &= _xine_fast_string_mask[4 + (tsize & 3)].v; return (char *)fs; } int xine_fast_string_cmp (char *fast_string1, char *fast_string2) { const union { char *b; uint32_t *u; } u1 = { fast_string1 }, u2 = { fast_string2 }; const union { uint32_t v; char *is_little; } endian = {1}; uint32_t *fs1 = u1.u, *fs2 = u2.u, *test1 = fs1, *test2 = fs2; uint32_t end = fs1[-1] + 1, v1, v2; fs1[end >> 2] |= _xine_fast_string_mask[end & 3].v; while (*test1 == *test2) test1++, test2++; fs1[end >> 2] &= _xine_fast_string_mask[4 + (end & 3)].v; v1 = *test1; v2 = *test2; if (endian.is_little) { v1 = (v1 >> 24) | ((v1 & 0x00ff0000) >> 8) | ((v1 & 0x0000ff00) << 8) | (v1 << 24); v2 = (v2 >> 24) | ((v2 & 0x00ff0000) >> 8) | ((v2 & 0x0000ff00) << 8) | (v2 << 24); } return v1 < v2 ? -1 : v1 > v2 ? 1 : 0; } void xine_fast_string_free (char **fast_string) { union { char *b; uint32_t *u; } u; uint32_t *fs; if (!fast_string) return; u.b = *fast_string; fs = u.u; if (!fs) return; *fast_string = NULL; if (fs[-2] & 0x80000000) return; free ((char *)fs - fs[-3]); } /* The fast text feature. */ struct xine_fast_text_s { uint32_t scan_here; uint32_t line_start; uint32_t text_len; uint32_t flags; uint32_t dummy[3]; }; xine_fast_text_t *xine_fast_text_load (const char *filename, size_t max_size) { size_t filesize; FILE *f; xine_fast_text_t *xft; uint32_t *w; if (!filename) { errno = EINVAL; return NULL; } if (!filename[0]) { errno = EINVAL; return NULL; } f = fopen (filename, "rb"); if (!f) return NULL; if (fseek (f, 0, SEEK_END)) { fclose(f); return NULL; } filesize = ftell (f); if (fseek (f, 0, SEEK_SET)) { fclose(f); return NULL; } if (filesize > max_size) filesize = max_size; xft = malloc (sizeof (*xft) + ((filesize + 3) & ~3)); if (!xft) { fclose (f); errno = ENOMEM; return NULL; } xft->scan_here = 0; xft->line_start = 0; xft->flags = 0; xft->dummy[0] = 0; w = &xft->dummy[1]; w[filesize >> 2] = 0x0a0a0a0a; w[(filesize >> 2) + 1] = 0x0a0a0a0a; xft->text_len = fread (&xft->dummy[1], 1, filesize, f); fclose (f); return xft; } char *xine_fast_text_line (xine_fast_text_t *xft, size_t *linesize) { const union { uint8_t b[4]; uint32_t w; } b0 = {{0x80, 0, 0, 0}}, b1 = {{0, 0x80, 0, 0}}, b2 = {{0, 0, 0x80, 0}}; uint32_t v; uint8_t *b, *e; if (xft->line_start >= xft->text_len) { *linesize = 0; return NULL; } e = (uint8_t *)&xft->dummy[1] + xft->scan_here; v = xft->flags; switch (xft->scan_here & 3) { case 0: { uint32_t *w = &xft->dummy[1] + (xft->scan_here >> 2); /* == (uint8_t *)e */ do { v = *w++ ^ ~0x0a0a0a0a; v = ((v & 0x7f7f7f7f) + 0x01010101) & v & 0x80808080; } while (!v); e = (uint8_t *)(w - 1); } if (v & b0.w) { v &= ~b0.w; xft->scan_here = e - (uint8_t *)&xft->dummy[1] + (v ? 1 : 4); break; } e++; /* fall through */ case 1: if (v & b1.w) { v &= ~b1.w; xft->scan_here = e - (uint8_t *)&xft->dummy[1] + (v ? 1 : 3); break; } e++; /* fall through */ case 2: if (v & b2.w) { v &= ~b2.w; xft->scan_here = e - (uint8_t *)&xft->dummy[1] + (v ? 1 : 2); break; } e++; /* fall through */ case 3: /* v & b3.w always true */ v = 0; xft->scan_here = e - (uint8_t *)&xft->dummy[1] + 1; break; } xft->flags = v; b = (uint8_t *)&xft->dummy[1] + xft->line_start; xft->line_start = e - (uint8_t *)&xft->dummy[1] + 1; e[0] = 0; if (e[-1] == 0x0d) *--e = 0; *linesize = e - b; return (char *)b; } void xine_fast_text_unload (xine_fast_text_t **xft) { if (xft) { free (*xft); *xft = NULL; } } typedef struct { uint32_t refs; uint32_t len; uint32_t magic; } _xine_ref_string_head_t; static _xine_ref_string_head_t *_xine_ref_string_head (char *s) { union { char *b; _xine_ref_string_head_t *r; } u; const union { uint8_t b[4]; uint32_t v; } _magic = {{'x', 'r', 's', 'h'}}; _xine_ref_string_head_t *h; if (((uintptr_t)s & 7) != 4) return NULL; u.b = s; h = u.r - 1; if (h->magic != _magic.v) return NULL; return h; } char *xine_ref_string_ref (const char *s, int len) { const union { uint8_t b[4]; uint32_t v; } _magic = {{'x', 'r', 's', 'h'}}; uint32_t _len; char *_s = (char *)s; _xine_ref_string_head_t *h = _xine_ref_string_head (_s); if (h) { h->refs += 1; return _s; } if (!s) return NULL; _len = len < 0 ? strlen (s) : (size_t)len; _s = malloc (sizeof (_xine_ref_string_head_t) + _len + 1); if (!_s) return NULL; h = (_xine_ref_string_head_t *)_s; _s += sizeof (_xine_ref_string_head_t); h->refs = 1; h->len = _len; h->magic = _magic.v; memcpy (_s, s, _len + 1); return _s; } size_t xine_ref_string_len (const char *s) { _xine_ref_string_head_t *h = _xine_ref_string_head ((char *)s); return h ? h->len : s ? strlen (s) : 0; } int xine_ref_string_unref (char **s) { _xine_ref_string_head_t *h; if (!s) return 0; h = _xine_ref_string_head (*s); if (!h) { free (*s); *s = NULL; return 0; } if (h->refs == 1) { free (h); *s = NULL; return 0; } return --h->refs; } #define XPQ_BACKLOG_LD 3 #define XPQ_BACKLOG_SIZE (1 << XPQ_BACKLOG_LD) #define XPQ_BACKLOG_MASK (XPQ_BACKLOG_SIZE - 1) typedef enum { XPQ_A_NONE = 0, XPQ_A_STALL, XPQ_A_PUT, XPQ_A_READY, XPQ_A_GET } xine_pts_queue_action_t; struct xine_pts_queue_s { struct { int64_t last_pts; uint64_t pos; struct { int64_t pts; uint64_t pos; } backlog[XPQ_BACKLOG_SIZE]; uint32_t ring_pos; } put; struct { uint64_t pos; uint32_t bytes; uint32_t num; } get; xine_pts_queue_action_t last_action; }; xine_pts_queue_t *xine_pts_queue_new (void) { xine_pts_queue_t *q = calloc (1, sizeof (*q)); return q; } void xine_pts_queue_reset (xine_pts_queue_t *q) { if (!q) return; memset (q, 0, sizeof (*q)); } void xine_pts_queue_put (xine_pts_queue_t *q, size_t bytes, int64_t pts) { xine_pts_queue_action_t a = bytes ? XPQ_A_PUT : XPQ_A_READY; if (!q) return; if (pts && (pts != q->put.last_pts)) { uint32_t u = q->put.ring_pos; q->put.last_pts = pts; if (q->last_action != XPQ_A_STALL) { u = (u + 1) & XPQ_BACKLOG_MASK; } else { a = XPQ_A_STALL; q->get.pos = q->put.backlog[u].pos; } q->put.ring_pos = u; if (q->put.backlog[u].pts) { /* backlog overrun. parser seems be dropping data. */ q->get.pos = q->put.backlog[u].pos; memset (q->put.backlog, 0, sizeof (q->put.backlog)); a = XPQ_A_STALL; } q->put.backlog[u].pts = pts; q->put.backlog[u].pos = q->put.pos; } q->put.pos += bytes; q->last_action = a; } int64_t xine_pts_queue_get (xine_pts_queue_t *q, size_t bytes) { int64_t pts = 0; uint32_t u; if (!q) return 0; /* TODO: parser dropped data. */ /* find suitable pts, or 0. */ u = q->put.ring_pos; do { if (q->put.backlog[u].pos <= q->get.pos) break; u = (u + XPQ_BACKLOG_SIZE - 1) & XPQ_BACKLOG_MASK; } while (u != q->put.ring_pos); if (q->put.backlog[u].pos <= q->get.pos) { pts = q->put.backlog[u].pts; /* bytes == 0: just peek. bytes != 0: consume. */ if (bytes) { q->put.backlog[u].pos = 0; q->put.backlog[u].pts = 0; } } /* advance. */ q->get.pos += bytes; /* parser returned more than it has (filler frames, generated heads). */ if (q->get.pos > q->put.pos) q->get.pos = q->put.pos; /* frame size stats. */ q->get.bytes += bytes; q->get.num++; if ((q->get.bytes | q->get.num) & 0x80000000) { q->get.bytes >>= 1; q->get.num >>= 1; } q->last_action = XPQ_A_GET; return pts; } void xine_pts_queue_delete (xine_pts_queue_t **q) { if (q && *q) { free (*q); *q = NULL; } } /** xine timespec magic, taken from TJtools. */ int xine_ts_from_string (struct timespec *ts, const char *s) { # define _DC_DIGIT 1 # define _DC_SPACE 2 # define _DC_Tt 4 # define _DC_Zz 8 # define _DC_PLUS 16 # define _DC_MINUS 32 # define _DC_DOT 64 # define _DC_END 128 static const uint8_t tab_char[256] = { ['0'] = _DC_DIGIT, ['1'] = _DC_DIGIT, ['2'] = _DC_DIGIT, ['3'] = _DC_DIGIT, ['4'] = _DC_DIGIT, ['5'] = _DC_DIGIT, ['6'] = _DC_DIGIT, ['7'] = _DC_DIGIT, ['8'] = _DC_DIGIT, ['9'] = _DC_DIGIT, ['\t'] = _DC_SPACE, ['\r'] = _DC_SPACE, ['\n'] = _DC_SPACE, [' '] = _DC_SPACE, ['T'] = _DC_Tt, ['t'] = _DC_Tt, ['Z'] = _DC_Zz, ['z'] = _DC_Zz, ['+'] = _DC_PLUS, ['-'] = _DC_MINUS, ['.'] = _DC_DOT, [0] = _DC_END }; enum { _DV_YEAR = 0, /* 1900- */ _DV_MONTH, /* 1-12 */ _DV_DAY, /* 1-31 */ _DV_WEEKDAY, /* 0-6 */ _DV_AM, /* 0 (24h), 1 (12-11 before noon), 2 (12-11 after noon) */ _DV_HOUR, /* 0-23 */ _DV_MINUTE, /* 0-59 */ _DV_SECOND, /* 0-59 */ _DV_FRAC, /* 0-999999999 */ _DV_OFFS, /* in seconds */ _DV_LAST }; static const struct { char s[11]; uint8_t type; int value; } strings [] = { {"am ", _DV_AM, 1}, {"april ", _DV_MONTH, 4}, {"august ", _DV_MONTH, 8}, {"cdt ", _DV_OFFS, -18000}, {"cst ", _DV_OFFS, -21600}, {"december ", _DV_MONTH, 12}, {"edt ", _DV_OFFS, -14400}, {"est ", _DV_OFFS, -18000}, {"february ", _DV_MONTH, 2}, {"friday ", _DV_WEEKDAY, 5}, {"gmt ", _DV_OFFS, 0}, {"january ", _DV_MONTH, 1}, {"july ", _DV_MONTH, 7}, {"june ", _DV_MONTH, 6}, {"march ", _DV_MONTH, 3}, {"may ", _DV_MONTH, 5}, {"mdt ", _DV_OFFS, -21600}, {"monday ", _DV_WEEKDAY, 1}, {"mst ", _DV_OFFS, -25200}, {"november ", _DV_MONTH, 11}, {"october ", _DV_MONTH, 10}, {"pdt ", _DV_OFFS, -25200}, {"pm ", _DV_AM, 2}, {"pst ", _DV_OFFS, -28800}, {"saturday ", _DV_WEEKDAY, 6}, {"september ", _DV_MONTH, 9}, {"sunday ", _DV_WEEKDAY, 0}, {"thursday ", _DV_WEEKDAY, 4}, {"tuesday ", _DV_WEEKDAY, 2}, {"utc ", _DV_OFFS, 0}, {"wednesday ", _DV_WEEKDAY, 3}, }; time_t res; int value[_DV_LAST] = { [_DV_YEAR] = 1970, [_DV_MONTH] = 1, [_DV_DAY] = 1 }; #define _DV_HAVE_DATE 1 #define _DV_HAVE_TIME 2 #define _DV_HAVE_ZONE 4 #define _DV_HAVE_JTIME 16 static const uint32_t word_have[_DV_LAST] = { [_DV_OFFS] = _DV_HAVE_ZONE }; static const uint32_t frac[] = { 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; uint64_t jtime = 0; uint32_t have = 0; const uint8_t *p; if (!ts) return EINVAL; if (!s) return 0; p = (const uint8_t *)s; if (((p[0] | 0x20) == 'p') && ((p[1] | 0x20) == 't')) { /* PT5H30M55S */ uint32_t _sec = 0, _frac = 0; p += 2; while (1) { uint32_t v = 0, f = 0, z; while ((z = p[0] ^ '0') < 10u) v = v * 10u + z, p++; if (p[0] == '.') { uint32_t u = 0; p++; while (((z = p[0] ^ '0') < 10u) && (u < 9)) f += frac[u++] * z, p++; while ((z = p[0] ^ '0') < 10u) p++; } z = p[0] | 0x20; if (z == 'h') _sec += 3600u * v; else if (z == 'm') _sec += 60u * v; else if (z == 's') _sec += v, _frac = f; else break; p++; } ts->tv_sec = _sec; ts->tv_nsec = _frac; return 0; } do { const uint8_t *b; uint8_t buf[12], type; uint32_t len, digits = 0; /* skip whitespace */ while (tab_char[*p] & _DC_SPACE) p++; /* get word */ type = tab_char[*p]; if (type & _DC_Tt) type = tab_char[*++p]; b = p; if (type & _DC_Zz) { type = tab_char[*++p]; if (type & (_DC_PLUS + _DC_MINUS)) { b = p; type = tab_char[*++p]; } } if (type & (_DC_PLUS + _DC_MINUS + _DC_DOT)) p++; while (1) { while (!((type = tab_char[*p]) & (_DC_SPACE + _DC_Tt + _DC_Zz + _DC_PLUS + _DC_MINUS + _DC_DOT + _DC_END))) digits += type & _DC_DIGIT, p++; len = p - b; if (type & (_DC_SPACE + _DC_PLUS + _DC_DOT + _DC_END)) break; if ((type & (_DC_Tt + _DC_Zz)) && digits) break; if ((type & _DC_MINUS) && !(((len == 4) && (digits == 4)) || ((len == 7) && (digits == 6)))) break; p++; } /* evaluate */ if ((len > 5) && (digits == len)) { uint64_t v = 0; uint32_t u; for (u = 0; u < len; u++) v = v * 10u + (b[u] ^ '0'); jtime = v; have |= _DV_HAVE_JTIME; } else if ((len > 1) && (digits + 1 == len) && (b[0] == '@')) { uint64_t v = 0; uint32_t u; for (u = 1; u < len; u++) v = v * 10u + (b[u] ^ '0'); jtime = v; have |= _DV_HAVE_JTIME; } else if ((digits + 1 == len) && (b[0] == '.')) { uint32_t u; b++; len--; if (len > 9) len = 9; value[_DV_FRAC] = 0; for (u = 0; u < len; u++) value[_DV_FRAC] += frac[u] * (b[u] ^ '0'); } else if ((len == 2) && (digits == 2)) { /* DD */ value[_DV_DAY] = (b[0] ^ '0') * 10u + (b[1] ^ '0'); } else if ((len == 4) && (digits >= 3)) { if ((digits == 3) && (b[1] == ':')) { /* h:mm */ value[_DV_HOUR] = b[0] ^ '0'; value[_DV_MINUTE] = (b[2] ^ '0') * 10u + (b[3] ^ '0'); value[_DV_SECOND] = 0; have |= _DV_HAVE_TIME; } else if (digits == 4) { /* YYYY */ value[_DV_YEAR] = (b[0] ^ '0') * 1000u + (b[1] ^ '0') * 100u + (b[2] ^ '0') * 10u + (b[3] ^ '0'); have |= _DV_HAVE_DATE; } } else if ((len == 5) && (digits == 4)) { if (b[2] == ':') { /* hh:mm */ value[_DV_HOUR] = (b[0] ^ '0') * 10u + (b[1] ^ '0'); value[_DV_MINUTE] = (b[3] ^ '0') * 10u + (b[4] ^ '0'); value[_DV_SECOND] = 0; have |= _DV_HAVE_TIME; } else if (tab_char[b[0]] & (_DC_Zz + _DC_PLUS + _DC_MINUS)) { /* [Zz+-]ohom */ value[_DV_OFFS] = (b[1] ^ '0') * 36000u + (b[2] ^ '0') * 3600u + (b[3] ^ '0') * 600u + (b[4] ^ '0') * 60u; if (b[0] == '-') value[_DV_OFFS] = -value[_DV_OFFS]; have |= _DV_HAVE_ZONE; } } else if ((len == 7) && (digits == 5) && (b[1] == ':') && (b[4] == ':')) { /* h:mm:ss */ value[_DV_HOUR] = b[0] ^ '0'; value[_DV_MINUTE] = (b[2] ^ '0') * 10u + (b[3] ^ '0'); value[_DV_SECOND] = (b[5] ^ '0') * 10u + (b[6] ^ '0'); have |= _DV_HAVE_TIME; } else if ((len == 6) && (digits == 4) && (tab_char[b[0]] & (_DC_Zz + _DC_PLUS + _DC_MINUS)) && (b[3] == ':')) { /* [Zz+-]oh:om */ value[_DV_OFFS] = (b[1] ^ '0') * 36000u + (b[2] ^ '0') * 3600u + (b[4] ^ '0') * 600u + (b[5] ^ '0') * 60u; if (b[0] == '-') value[_DV_OFFS] = -value[_DV_OFFS]; have |= _DV_HAVE_ZONE; } else if ((len == 8) && (digits == 6)) { if ((b[2] == ':') && (b[5] == ':')) { /* hh:mm:ss */ value[_DV_HOUR] = (b[0] ^ '0') * 10u + (b[1] ^ '0'); value[_DV_MINUTE] = (b[3] ^ '0') * 10u + (b[4] ^ '0'); value[_DV_SECOND] = (b[6] ^ '0') * 10u + (b[7] ^ '0'); have |= _DV_HAVE_TIME; } else if ((b[2] == '/') && (b[5] == '/')) { /* MM/DD/YY */ value[_DV_MONTH] = (b[0] ^ '0') * 10u + (b[1] ^ '0'); value[_DV_DAY] = (b[3] ^ '0') * 10u + (b[4] ^ '0'); value[_DV_YEAR] = (b[6] ^ '0') * 10u + (b[7] ^ '0'); value[_DV_YEAR] += (value[_DV_YEAR] < 70) ? 2000 : 1900; have |= _DV_HAVE_DATE; } } else if ((len == 10) && (digits == 8)) { if ((b[2] == '/') && (b[5] == '/')) { /* MM/DD/YYYY */ value[_DV_MONTH] = (b[0] ^ '0') * 10u + (b[1] ^ '0'); value[_DV_DAY] = (b[3] ^ '0') * 10u + (b[4] ^ '0'); value[_DV_YEAR] = (b[6] ^ '0') * 1000u + (b[7] ^ '0') * 100u + (b[8] ^ '0') * 10u + (b[9] ^ '0'); have |= _DV_HAVE_DATE; } else if ((b[4] == '-') && (b[7] == '-')) { /* YYYY-MM-DD */ value[_DV_YEAR] = (b[0] ^ '0') * 1000u + (b[1] ^ '0') * 100u + (b[2] ^ '0') * 10u + (b[3] ^ '0'); value[_DV_MONTH] = (b[5] ^ '0') * 10u + (b[6] ^ '0'); value[_DV_DAY] = (b[8] ^ '0') * 10u + (b[9] ^ '0'); have |= _DV_HAVE_DATE; } } else if ((len > 0) && (len < sizeof (buf))) { uint32_t _b = 0, _m, _e = sizeof (strings) / sizeof (strings[0]); int _d; /* known word */ memset (buf, ' ', sizeof (buf)); for (_m = 0; _m < len; _m++) buf[_m] |= b[_m]; do { _m = (_b + _e) >> 1; _d = memcmp (buf, strings[_m].s, sizeof (buf) - 1); if (_d < 0) { _e = _m; } else if (_d > 0) { _b = _m + 1; } else { break; } } while (_b < _e); if (!_d) { value[strings[_m].type] = strings[_m].value; have |= word_have[strings[_m].type]; } } } while (*p); if (value[_DV_AM]) { if ((value[_DV_AM] == 1) && (value[_DV_HOUR] >= 12)) value[_DV_HOUR] -= 12; else if ((value[_DV_AM] == 2) && (value[_DV_HOUR] < 12)) value[_DV_HOUR] += 12; } /* relative time */ if ((have & (_DV_HAVE_DATE + _DV_HAVE_TIME)) == 0) { if (have & _DV_HAVE_JTIME) { ts->tv_sec = jtime; ts->tv_nsec = value[_DV_FRAC]; } return 0; } if ((have & _DV_HAVE_DATE) == 0) { ts->tv_sec = ts->tv_sec / (24 * 60 * 60) * (24 * 60 * 60) + value[_DV_HOUR] * 3600 + value[_DV_MINUTE] * 60 + value[_DV_SECOND] - value[_DV_OFFS]; ts->tv_nsec = value[_DV_FRAC]; return 0; } /* with date */ { struct tm tm = { .tm_sec = value[_DV_SECOND], .tm_min = value[_DV_MINUTE], .tm_hour = value[_DV_HOUR], .tm_mday = value[_DV_DAY], .tm_mon = value[_DV_MONTH] - 1, .tm_year = value[_DV_YEAR] - 1900, .tm_wday = value[_DV_WEEKDAY], .tm_isdst = 0 }; const char *tz = getenv ("TZ"); if (tz) { if (tz[0]) { char *_tz = strdup (tz); setenv ("TZ", "", 1); tzset (); res = mktime (&tm); setenv ("TZ", _tz, 1); free (_tz); tzset (); } else { tzset (); res = mktime (&tm); } } else { setenv ("TZ", "", 1); tzset (); res = mktime (&tm); unsetenv ("TZ"); tzset (); } } if (res == -1) return errno; res -= value[_DV_OFFS]; ts->tv_sec = res; ts->tv_nsec = value[_DV_FRAC]; return 0; } void xine_ts_add (struct timespec *a, const struct timespec *b) { if (!a || !b) return; a->tv_sec += b->tv_sec; a->tv_nsec += b->tv_nsec; if (a->tv_nsec >= 1000000000) { a->tv_nsec -= 1000000000; a->tv_sec += 1; } } void xine_ts_sub (struct timespec *a, const struct timespec *b) { if (!a || !b) return; a->tv_sec -= b->tv_sec; a->tv_nsec -= b->tv_nsec; if (a->tv_nsec < 0) { a->tv_nsec += 1000000000; a->tv_sec -= 1; } } int64_t xine_ts_to_timebase (const struct timespec *ts, uint32_t timebase) { uint32_t fracbase; int64_t res; if (!ts || !timebase) return 0; fracbase = (1000000000u + (timebase >> 1)) / timebase; res = (int64_t)ts->tv_sec * (int32_t)timebase; if (fracbase) res += ((uint32_t)ts->tv_nsec + (fracbase >> 1)) / fracbase; return res; } /** xine rational numbers, taken from TJtools. */ void xine_rats_shorten (xine_rats_t *value) { static const unsigned char primediffs[] = { /* just say 'erat -d 75 3 32768' ;-) */ 3, 2, 2, 4, 2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2, 6, 4, 6, 8, 4, 2, 4, 2, 4, 14, 4, 6, 2, 10, 2, 6, 6, 4, 6, 6, 2, 10, 2, 4, 2, 12, 12, 4, 2, 4, 6, 2, 10, 6, 6, 6, 2, 6, 4, 2, 10, 14, 4, 2, 4, 14, 6, 10, 2, 4, 6, 8, 6, 6, 4, 6, 8, 4, 8, 10, 2, 10, 2, 6, 4, 6, 8, 4, 2, 4, 12, 8, 4, 8, 4, 6, 12, 2, 18, 6, 10, 6, 6, 2, 6, 10, 6, 6, 2, 6, 6, 4, 2, 12, 10, 2, 4, 6, 6, 2, 12, 4, 6, 8, 10, 8, 10, 8, 6, 6, 4, 8, 6, 4, 8, 4, 14, 10, 12, 2, 10, 2, 4, 2, 10, 14, 4, 2, 4, 14, 4, 2, 4, 20, 4, 8, 10, 8, 4, 6, 6, 14, 4, 6, 6, 8, 6, 12, 4, 6, 2, 10, 2, 6, 10, 2, 10, 2, 6, 18, 4, 2, 4, 6, 6, 8, 6, 6, 22, 2, 10, 8, 10, 6, 6, 8, 12, 4, 6, 6, 2, 6, 12, 10, 18, 2, 4, 6, 2, 6, 4, 2, 4, 12, 2, 6, 34, 6, 6, 8, 18, 10, 14, 4, 2, 4, 6, 8, 4, 2, 6, 12, 10, 2, 4, 2, 4, 6, 12, 12, 8, 12, 6, 4, 6, 8, 4, 8, 4, 14, 4, 6, 2, 4, 6, 2, 6, 10, 20, 6, 4, 2, 24, 4, 2, 10, 12, 2, 10, 8, 6, 6, 6, 18, 6, 4, 2, 12, 10, 12, 8, 16, 14, 6, 4, 2, 4, 2, 10, 12, 6, 6, 18, 2, 16, 2, 22, 6, 8, 6, 4, 2, 4, 8, 6, 10, 2, 10, 14, 10, 6, 12, 2, 4, 2, 10, 12, 2, 16, 2, 6, 4, 2, 10, 8, 18, 24, 4, 6, 8, 16, 2, 4, 8, 16, 2, 4, 8, 6, 6, 4, 12, 2, 22, 6, 2, 6, 4, 6, 14, 6, 4, 2, 6, 4, 6, 12, 6, 6, 14, 4, 6, 12, 8, 6, 4, 26, 18, 10, 8, 4, 6, 2, 6, 22, 12, 2, 16, 8, 4, 12, 14, 10, 2, 4, 8, 6, 6, 4, 2, 4, 6, 8, 4, 2, 6, 10, 2, 10, 8, 4, 14, 10, 12, 2, 6, 4, 2, 16, 14, 4, 6, 8, 6, 4, 18, 8, 10, 6, 6, 8, 10, 12, 14, 4, 6, 6, 2, 28, 2, 10, 8, 4, 14, 4, 8, 12, 6, 12, 4, 6, 20, 10, 2, 16, 26, 4, 2, 12, 6, 4, 12, 6, 8, 4, 8, 22, 2, 4, 2, 12, 28, 2, 6, 6, 6, 4, 6, 2, 12, 4, 12, 2, 10, 2, 16, 2, 16, 6, 20, 16, 8, 4, 2, 4, 2, 22, 8, 12, 6, 10, 2, 4, 6, 2, 6, 10, 2, 12, 10, 2, 10, 14, 6, 4, 6, 8, 6, 6, 16, 12, 2, 4, 14, 6, 4, 8, 10, 8, 6, 6, 22, 6, 2, 10, 14, 4, 6, 18, 2, 10, 14, 4, 2, 10, 14, 4, 8, 18, 4, 6, 2, 4, 6, 2, 12, 4, 20, 22, 12, 2, 4, 6, 6, 2, 6, 22, 2, 6, 16, 6, 12, 2, 6, 12, 16, 2, 4, 6, 14, 4, 2, 18, 24, 10, 6, 2, 10, 2, 10, 2, 10, 6, 2, 10, 2, 10, 6, 8, 30, 10, 2, 10, 8, 6, 10, 18, 6, 12, 12, 2, 18, 6, 4, 6, 6, 18, 2, 10, 14, 6, 4, 2, 4, 24, 2, 12, 6, 16, 8, 6, 6, 18, 16, 2, 4, 6, 2, 6, 6, 10, 6, 12, 12, 18, 2, 6, 4, 18, 8, 24, 4, 2, 4, 6, 2, 12, 4, 14, 30, 10, 6, 12, 14, 6, 10, 12, 2, 4, 6, 8, 6, 10, 2, 4, 14, 6, 6, 4, 6, 2, 10, 2, 16, 12, 8, 18, 4, 6, 12, 2, 6, 6, 6, 28, 6, 14, 4, 8, 10, 8, 12, 18, 4, 2, 4, 24, 12, 6, 2, 16, 6, 6, 14, 10, 14, 4, 30, 6, 6, 6, 8, 6, 4, 2, 12, 6, 4, 2, 6, 22, 6, 2, 4, 18, 2, 4, 12, 2, 6, 4, 26, 6, 6, 4, 8, 10, 32, 16, 2, 6, 4, 2, 4, 2, 10, 14, 6, 4, 8, 10, 6, 20, 4, 2, 6, 30, 4, 8, 10, 6, 6, 8, 6, 12, 4, 6, 2, 6, 4, 6, 2, 10, 2, 16, 6, 20, 4, 12, 14, 28, 6, 20, 4, 18, 8, 6, 4, 6, 14, 6, 6, 10, 2, 10, 12, 8, 10, 2, 10, 8, 12, 10, 24, 2, 4, 8, 6, 4, 8, 18, 10, 6, 6, 2, 6, 10, 12, 2, 10, 6, 6, 6, 8, 6, 10, 6, 2, 6, 6, 6, 10, 8, 24, 6, 22, 2, 18, 4, 8, 10, 30, 8, 18, 4, 2, 10, 6, 2, 6, 4, 18, 8, 12, 18, 16, 6, 2, 12, 6, 10, 2, 10, 2, 6, 10, 14, 4, 24, 2, 16, 2, 10, 2, 10, 20, 4, 2, 4, 8, 16, 6, 6, 2, 12, 16, 8, 4, 6, 30, 2, 10, 2, 6, 4, 6, 6, 8, 6, 4, 12, 6, 8, 12, 4, 14, 12, 10, 24, 6, 12, 6, 2, 22, 8, 18, 10, 6, 14, 4, 2, 6, 10, 8, 6, 4, 6, 30, 14, 10, 2, 12, 10, 2, 16, 2, 18, 24, 18, 6, 16, 18, 6, 2, 18, 4, 6, 2, 10, 8, 10, 6, 6, 8, 4, 6, 2, 10, 2, 12, 4, 6, 6, 2, 12, 4, 14, 18, 4, 6, 20, 4, 8, 6, 4, 8, 4, 14, 6, 4, 14, 12, 4, 2, 30, 4, 24, 6, 6, 12, 12, 14, 6, 4, 2, 4, 18, 6, 12, 8, 6, 4, 12, 2, 12, 30, 16, 2, 6, 22, 14, 6, 10, 12, 6, 2, 4, 8, 10, 6, 6, 24, 14, 6, 4, 8, 12, 18, 10, 2, 10, 2, 4, 6, 20, 6, 4, 14, 4, 2, 4, 14, 6, 12, 24, 10, 6, 8, 10, 2, 30, 4, 6, 2, 12, 4, 14, 6, 34, 12, 8, 6, 10, 2, 4, 20, 10, 8, 16, 2, 10, 14, 4, 2, 12, 6, 16, 6, 8, 4, 8, 4, 6, 8, 6, 6, 12, 6, 4, 6, 6, 8, 18, 4, 20, 4, 12, 2, 10, 6, 2, 10, 12, 2, 4, 20, 6, 30, 6, 4, 8, 10, 12, 6, 2, 28, 2, 6, 4, 2, 16, 12, 2, 6, 10, 8, 24, 12, 6, 18, 6, 4, 14, 6, 4, 12, 8, 6, 12, 4, 6, 12, 6, 12, 2, 16, 20, 4, 2, 10, 18, 8, 4, 14, 4, 2, 6, 22, 6, 14, 6, 6, 10, 6, 2, 10, 2, 4, 2, 22, 2, 4, 6, 6, 12, 6, 14, 10, 12, 6, 8, 4, 36, 14, 12, 6, 4, 6, 2, 12, 6, 12, 16, 2, 10, 8, 22, 2, 12, 6, 4, 6, 18, 2, 12, 6, 4, 12, 8, 6, 12, 4, 6, 12, 6, 2, 12, 12, 4, 14, 6, 16, 6, 2, 10, 8, 18, 6, 34, 2, 28, 2, 22, 6, 2, 10, 12, 2, 6, 4, 8, 22, 6, 2, 10, 8, 4, 6, 8, 4, 12, 18, 12, 20, 4, 6, 6, 8, 4, 2, 16, 12, 2, 10, 8, 10, 2, 4, 6, 14, 12, 22, 8, 28, 2, 4, 20, 4, 2, 4, 14, 10, 12, 2, 12, 16, 2, 28, 8, 22, 8, 4, 6, 6, 14, 4, 8, 12, 6, 6, 4, 20, 4, 18, 2, 12, 6, 4, 6, 14, 18, 10, 8, 10, 32, 6, 10, 6, 6, 2, 6, 16, 6, 2, 12, 6, 28, 2, 10, 8, 16, 6, 8, 6, 10, 24, 20, 10, 2, 10, 2, 12, 4, 6, 20, 4, 2, 12, 18, 10, 2, 10, 2, 4, 20, 16, 26, 4, 8, 6, 4, 12, 6, 8, 12, 12, 6, 4, 8, 22, 2, 16, 14, 10, 6, 12, 12, 14, 6, 4, 20, 4, 12, 6, 2, 6, 6, 16, 8, 22, 2, 28, 8, 6, 4, 20, 4, 12, 24, 20, 4, 8, 10, 2, 16, 2, 12, 12, 34, 2, 4, 6, 12, 6, 6, 8, 6, 4, 2, 6, 24, 4, 20, 10, 6, 6, 14, 4, 6, 6, 2, 12, 6, 10, 2, 10, 6, 20, 4, 26, 4, 2, 6, 22, 2, 24, 4, 6, 2, 4, 6, 24, 6, 8, 4, 2, 34, 6, 8, 16, 12, 2, 10, 2, 10, 6, 8, 4, 8, 12, 22, 6, 14, 4, 26, 4, 2, 12, 10, 8, 4, 8, 12, 4, 14, 6, 16, 6, 8, 4, 6, 6, 8, 6, 10, 12, 2, 6, 6, 16, 8, 6, 6, 12, 10, 2, 6, 18, 4, 6, 6, 6, 12, 18, 8, 6, 10, 8, 18, 4, 14, 6, 18, 10, 8, 10, 12, 2, 6, 12, 12, 36, 4, 6, 8, 4, 6, 2, 4, 18, 12, 6, 8, 6, 6, 4, 18, 2, 4, 2, 24, 4, 6, 6, 14, 30, 6, 4, 6, 12, 6, 20, 4, 8, 4, 8, 6, 6, 4, 30, 2, 10, 12, 8, 10, 8, 24, 6, 12, 4, 14, 4, 6, 2, 28, 14, 16, 2, 12, 6, 4, 20, 10, 6, 6, 6, 8, 10, 12, 14, 10, 14, 16, 14, 10, 14, 6, 16, 6, 8, 6, 16, 20, 10, 2, 6, 4, 2, 4, 12, 2, 10, 2, 6, 22, 6, 2, 4, 18, 8, 10, 8, 22, 2, 10, 18, 14, 4, 2, 4, 18, 2, 4, 6, 8, 10, 2, 30, 4, 30, 2, 10, 2, 18, 4, 18, 6, 14, 10, 2, 4, 20, 36, 6, 4, 6, 14, 4, 20, 10, 14, 22, 6, 2, 30, 12, 10, 18, 2, 4, 14, 6, 22, 18, 2, 12, 6, 4, 8, 4, 8, 6, 10, 2, 12, 18, 10, 14, 16, 14, 4, 6, 6, 2, 6, 4, 2, 28, 2, 28, 6, 2, 4, 6, 14, 4, 12, 14, 16, 14, 4, 6, 8, 6, 4, 6, 6, 6, 8, 4, 8, 4, 14, 16, 8, 6, 4, 12, 8, 16, 2, 10, 8, 4, 6, 26, 6, 10, 8, 4, 6, 12, 14, 30, 4, 14, 22, 8, 12, 4, 6, 8, 10, 6, 14, 10, 6, 2, 10, 12, 12, 14, 6, 6, 18, 10, 6, 8, 18, 4, 6, 2, 6, 10, 2, 10, 8, 6, 6, 10, 2, 18, 10, 2, 12, 4, 6, 8, 10, 12, 14, 12, 4, 8, 10, 6, 6, 20, 4, 14, 16, 14, 10, 8, 10, 12, 2, 18, 6, 12, 10, 12, 2, 4, 2, 12, 6, 4, 8, 4, 44, 4, 2, 4, 2, 10, 12, 6, 6, 14, 4, 6, 6, 6, 8, 6, 36, 18, 4, 6, 2, 12, 6, 6, 6, 4, 14, 22, 12, 2, 18, 10, 6, 26, 24, 4, 2, 4, 2, 4, 14, 4, 6, 6, 8, 16, 12, 2, 42, 4, 2, 4, 24, 6, 6, 2, 18, 4, 14, 6, 28, 18, 14, 6, 10, 12, 2, 6, 12, 30, 6, 4, 6, 6, 14, 4, 2, 24, 4, 6, 6, 26, 10, 18, 6, 8, 6, 6, 30, 4, 12, 12, 2, 16, 2, 6, 4, 12, 18, 2, 6, 4, 26, 12, 6, 12, 4, 24, 24, 12, 6, 2, 12, 28, 8, 4, 6, 12, 2, 18, 6, 4, 6, 6, 20, 16, 2, 6, 6, 18, 10, 6, 2, 4, 8, 6, 6, 24, 16, 6, 8, 10, 6, 14, 22, 8, 16, 6, 2, 12, 4, 2, 22, 8, 18, 34, 2, 6, 18, 4, 6, 6, 8, 10, 8, 18, 6, 4, 2, 4, 8, 16, 2, 12, 12, 6, 18, 4, 6, 6, 6, 2, 6, 12, 10, 20, 12, 18, 4, 6, 2, 16, 2, 10, 14, 4, 30, 2, 10, 12, 2, 24, 6, 16, 8, 10, 2, 12, 22, 6, 2, 16, 20, 10, 2, 12, 12, 18, 10, 12, 6, 2, 10, 2, 6, 10, 18, 2, 12, 6, 4, 6, 2, 24, 28, 2, 4, 2, 10, 2, 16, 12, 8, 22, 2, 6, 4, 2, 10, 6, 20, 12, 10, 8, 12, 6, 6, 6, 4, 18, 2, 4, 12, 18, 2, 12, 6, 4, 2, 16, 12, 12, 14, 4, 8, 18, 4, 12, 14, 6, 6, 4, 8, 6, 4, 20, 12, 10, 14, 4, 2, 16, 2, 12, 30, 4, 6, 24, 20, 24, 10, 8, 12, 10, 12, 6, 12, 12, 6, 8, 16, 14, 6, 4, 6, 36, 20, 10, 30, 12, 2, 4, 2, 28, 12, 14, 6, 22, 8, 4, 18, 6, 14, 18, 4, 6, 2, 6, 34, 18, 2, 16, 6, 18, 2, 24, 4, 2, 6, 12, 6, 12, 10, 8, 6, 16, 12, 8, 10, 14, 40, 6, 2, 6, 4, 12, 14, 4, 2, 4, 2, 4, 8, 6, 10, 6, 6, 2, 6, 6, 6, 12, 6, 24, 10, 2, 10, 6, 12, 6, 6, 14, 6, 6, 52, 20, 6, 10, 2, 10, 8, 10, 12, 12, 2, 6, 4, 14, 16, 8, 12, 6, 22, 2, 10, 8, 6, 22, 2, 22, 6, 8, 10, 12, 12, 2, 10, 6, 12, 2, 4, 14, 10, 2, 6, 18, 4, 12, 8, 18, 12, 6, 6, 4, 6, 6, 14, 4, 2, 12, 12, 4, 6, 18, 18, 12, 2, 16, 12, 8, 18, 10, 26, 4, 6, 8, 6, 6, 4, 2, 10, 20, 4, 6, 8, 4, 20, 10, 2, 34, 2, 4, 24, 2, 12, 12, 10, 6, 2, 12, 30, 6, 12, 16, 12, 2, 22, 18, 12, 14, 10, 2, 12, 12, 4, 2, 4, 6, 12, 2, 16, 18, 2, 40, 8, 16, 6, 8, 10, 2, 4, 18, 8, 10, 8, 12, 4, 18, 2, 18, 10, 2, 4, 2, 4, 8, 28, 2, 6, 22, 12, 6, 14, 18, 4, 6, 8, 6, 6, 10, 8, 4, 2, 18, 10, 6, 20, 22, 8, 6, 30, 4, 2, 4, 18, 6, 30, 2, 4, 8, 6, 4, 6, 12, 14, 34, 14, 6, 4, 2, 6, 4, 14, 4, 2, 6, 28, 2, 4, 6, 8, 10, 2, 10, 2, 10, 2, 4, 30, 2, 12, 12, 10, 18, 12, 14, 10, 2, 12, 6, 10, 6, 14, 12, 4, 14, 4, 18, 2, 10, 8, 4, 8, 10, 12, 18, 18, 8, 6, 18, 16, 14, 6, 6, 10, 14, 4, 6, 2, 12, 12, 4, 6, 6, 12, 2, 16, 2, 12, 6, 4, 14, 6, 4, 2, 12, 18, 4, 36, 18, 12, 12, 2, 4, 2, 4, 8, 12, 4, 36, 6, 18, 2, 12, 10, 6, 12, 24, 8, 6, 6, 16, 12, 2, 18, 10, 20, 10, 2, 6, 18, 4, 2, 40, 6, 2, 16, 2, 4, 8, 18, 10, 12, 6, 2, 10, 8, 4, 6, 12, 2, 10, 18, 8, 6, 4, 20, 4, 6, 36, 6, 2, 10, 6, 24, 6, 14, 16, 6, 18, 2, 10, 20, 10, 8, 6, 4, 6, 2, 10, 2, 12, 4, 2, 4, 8, 10, 6, 12, 18, 14, 12, 16, 8, 6, 16, 8, 4, 2, 6, 18, 24, 18, 10, 12, 2, 4, 14, 10, 6, 6, 6, 18, 12, 2, 28, 18, 14, 16, 12, 14, 24, 12, 22, 6, 2, 10, 8, 4, 2, 4, 14, 12, 6, 4, 6, 14, 4, 2, 4, 30, 6, 2, 6, 10, 2, 30, 22, 2, 4, 6, 8, 6, 6, 16, 12, 12, 6, 8, 4, 2, 24, 12, 4, 6, 8, 6, 6, 10, 2, 6, 12, 28, 14, 6, 4, 12, 8, 6, 12, 4, 6, 14, 6, 12, 10, 6, 6, 8, 6, 6, 4, 2, 4, 8, 12, 4, 14, 18, 10, 2, 16, 6, 20, 6, 10, 8, 4, 30, 36, 12, 8, 22, 12, 2, 6, 12, 16, 6, 6, 2, 18, 4, 26, 4, 8, 18, 10, 8, 10, 6, 14, 4, 20, 22, 18, 12, 8, 28, 12, 6, 6, 8, 6, 12, 24, 16, 14, 4, 14, 12, 6, 10, 12, 20, 6, 4, 8, 18, 12, 18, 10, 2, 4, 20, 10, 14, 4, 6, 2, 10, 24, 18, 2, 4, 20, 16, 14, 10, 14, 6, 4, 6, 20, 6, 10, 6, 2, 12, 6, 30, 10, 8, 6, 4, 6, 8, 40, 2, 4, 2, 12, 18, 4, 6, 8, 10, 6, 18, 18, 2, 12, 16, 8, 6, 4, 6, 6, 2, 52, 14, 4, 20, 16, 2, 4, 6, 12, 2, 6, 12, 12, 6, 4, 14, 10, 6, 6, 14, 10, 14, 16, 8, 6, 12, 4, 8, 22, 6, 2, 18, 22, 6, 2, 18, 6, 16, 14, 10, 6, 12, 2, 6, 4, 8, 18, 12, 16, 2, 4, 14, 4, 8, 12, 12, 30, 16, 8, 4, 2, 6, 22, 12, 8, 10, 6, 6, 6, 14, 6, 18, 10, 12, 2, 10, 2, 4, 26, 4, 12, 8, 4, 18, 8, 10, 14, 16, 6, 6, 8, 10, 6, 8, 6, 12, 10, 20, 10, 8, 4, 12, 26, 18, 4, 12, 18, 6, 30, 6, 8, 6, 22, 12, 2, 4, 6, 6, 2, 10, 2, 4, 6, 6, 2, 6, 22, 18, 6, 18, 12, 8, 12, 6, 10, 12, 2, 16, 2, 10, 2, 10, 18, 6, 20, 4, 2, 6, 22, 6, 6, 18, 6, 14, 12, 16, 2, 6, 6, 4, 14, 12, 4, 2, 18, 16, 36, 12, 6, 14, 28, 2, 12, 6, 12, 6, 4, 2, 16, 30, 8, 24, 6, 30, 10, 2, 18, 4, 6, 12, 8, 22, 2, 6, 22, 18, 2, 10, 2, 10, 30, 2, 28, 6, 14, 16, 6, 20, 16, 2, 6, 4, 32, 4, 2, 4, 6, 2, 12, 4, 6, 6, 12, 2, 6, 4, 6, 8, 6, 4, 20, 4, 32, 10, 8, 16, 2, 22, 2, 4, 6, 8, 6, 16, 14, 4, 18, 8, 4, 20, 6, 12, 12, 6, 10, 2, 10, 2, 12, 28, 12, 18, 2, 18, 10, 8, 10, 48, 2, 4, 6, 8, 10, 2, 10, 30, 2, 36, 6, 10, 6, 2, 18, 4, 6, 8, 16, 14, 16, 6, 14, 4, 20, 4, 6, 2, 10, 12, 2, 6, 12, 6, 6, 4, 12, 2, 6, 4, 12, 6, 8, 4, 2, 6, 18, 10, 6, 8, 12, 6, 22, 2, 6, 12, 18, 4, 14, 6, 4, 20, 6, 16, 8, 4, 8, 22, 8, 12, 6, 6, 16, 12, 18, 30, 8, 4, 2, 4, 6, 26, 4, 14, 24, 22, 6, 2, 6, 10, 6, 14, 6, 6, 12, 10, 6, 2, 12, 10, 12, 8, 18, 18, 10, 6, 8, 16, 6, 6, 8, 16, 20, 4, 2, 10, 2, 10, 12, 6, 8, 6, 10, 20, 10, 18, 26, 4, 6, 30, 2, 4, 8, 6, 12, 12, 18, 4, 8, 22, 6, 2, 12, 34, 6, 18, 12, 6, 2, 28, 14, 16, 14, 4, 14, 12, 4, 6, 6, 2, 36, 4, 6, 20, 12, 24, 6, 22, 2, 16, 18, 12, 12, 18, 2, 6, 6, 6, 4, 6, 14, 4, 2, 22, 8, 12, 6, 10, 6, 8, 12, 18, 12, 6, 10, 2, 22, 14, 6, 6, 4, 18, 6, 20, 22, 2, 12, 24, 4, 18, 18, 2, 22, 2, 4, 12, 8, 12, 10, 14, 4, 2, 18, 16, 38, 6, 6, 6, 12, 10, 6, 12, 8, 6, 4, 6, 14, 30, 6, 10, 8, 22, 6, 8, 12, 10, 2, 10, 2, 6, 10, 2, 10, 12, 18, 20, 6, 4, 8, 22, 6, 6, 30, 6, 14, 6, 12, 12, 6, 10, 2, 10, 30, 2, 16, 8, 4, 2, 6, 18, 4, 2, 6, 4, 26, 4, 8, 6, 10, 2, 4, 6, 8, 4, 6, 30, 12, 2, 6, 6, 4, 20, 22, 8, 4, 2, 4, 72, 8, 4, 8, 22, 2, 4, 14, 10, 2, 4, 20, 6, 10, 18, 6, 20, 16, 6, 8, 6, 4, 20, 12, 22, 2, 4, 2, 12, 10, 18, 2, 22, 6, 18, 30, 2, 10, 14, 10, 8, 16, 50, 6, 10, 8, 10, 12, 6, 18, 2, 22, 6, 2, 4, 6, 8, 6, 6, 10, 18, 2, 22, 2, 16, 14, 10, 6, 2, 12, 10, 20, 4, 14, 6, 4, 36, 2, 4, 6, 12, 2, 4, 14, 12, 6, 4, 6, 2, 6, 4, 20, 10, 2, 10, 6, 12, 2, 24, 12, 12, 6, 6, 4, 24, 2, 4, 24, 2, 6, 4, 6, 8, 16, 6, 2, 10, 12, 14, 6, 34, 6, 14, 6, 4, 2, 30, 0 }; int64_t num, den, left, min, max; if (!value) return; if ((value->num == 0) || (value->den == 0)) { value->den = 1; return; } if (value->den < 0) value->num = -value->num, value->den = -value->den; num = value->num; den = value->den; min = num < 0 ? -num : num; if (min < den) { max = den; } else { max = min; min = den; } left = 1; /* prime 2, simple and fast */ while (!((min | max) & 1)) { min >>= 1; max >>= 1; } while (!(min & 1)) { min >>= 1; left += left; } /* now, the remaining primes */ { int prime = 0; const unsigned char *p = primediffs; while (*p) { prime += *p++; if (min < prime * prime) break; while (min % prime == 0) { min /= prime; if (max % prime != 0) { left *= prime; break; } max /= prime; } while (min % prime == 0) { min /= prime; left *= prime; } } } /* after stripping all prime factors up to sqrt (min), the rest _is_ prime */ if (max % min == 0) { max /= min; min = 1; } min *= left; if (num < 0) { if (-num < den) { value->num = -min; value->den = max; } else { value->num = -max; value->den = min; } } else { if (num < den) { value->num = min; value->den = max; } else { value->num = max; value->den = min; } } } ������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/xmlparser.c�������������������������������������������������������������0000644�0001750�0001750�00000061247�14647725152�015747� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2021 the xine project * * This file is part of xine, a free video player. * * The xine-lib XML parser is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The xine-lib XML parser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdarg.h> #include <ctype.h> #ifdef _MSC_VER #define snprintf sprintf_s #define strcasecmp stricmp #endif #define LOG_MODULE "xmlparser" #define LOG_VERBOSE /* #define LOG */ #ifdef XINE_COMPILE #include <xine/xineutils.h> #else #define lprintf(...) #define XINE_MALLOC #endif #include <xine/xmllexer.h> #include <xine/xmlparser.h> #define TOKEN_SIZE 4 * 1024 #define DATA_SIZE 4 * 1024 #define MAX_RECURSION 10 /* private global variables */ xml_parser_t * static_xml_parser; /* private functions */ static char * strtoupper(char * str) { int i = 0; while (str[i] != '\0') { str[i] = (char)toupper((int)str[i]); i++; } return str; } static xml_node_t *XINE_MALLOC new_xml_node(void) { xml_node_t * new_node; new_node = (xml_node_t*) calloc(1, sizeof(xml_node_t)); return new_node; } static const char cdata[] = CDATA_MARKER; static void free_xml_node(xml_node_t * node) { if (node->name != cdata) _x_freep (&node->name); _x_freep (&node->data); free(node); } static xml_property_t *XINE_MALLOC new_xml_property(void) { xml_property_t * new_property; new_property = (xml_property_t*) calloc(1, sizeof(xml_property_t)); return new_property; } static void free_xml_property(xml_property_t * property) { _x_freep (&property->name); _x_freep (&property->value); free(property); } /* for ABI compatibility */ void xml_parser_init(const char * buf, int size, int mode) { if (static_xml_parser) { xml_parser_finalize_r(static_xml_parser); } static_xml_parser = xml_parser_init_r(buf, size, mode); } xml_parser_t *xml_parser_init_r(const char * buf, int size, int mode) { xml_parser_t *xml_parser = malloc(sizeof(*xml_parser)); if (!xml_parser) { return NULL; } xml_parser->lexer = lexer_init_r(buf, size); if (!xml_parser->lexer) { free(xml_parser); return NULL; } xml_parser->mode = mode; return xml_parser; } void xml_parser_finalize_r(xml_parser_t *xml_parser) { lexer_finalize_r(xml_parser->lexer); free(xml_parser); } static void xml_parser_free_props(xml_property_t *current_property) { while (current_property) { xml_property_t *next = current_property->next; free_xml_property(current_property); current_property = next; } } static void xml_parser_free_tree_rec(xml_node_t *current_node, int free_next) { lprintf("xml_parser_free_tree_rec: %s\n", current_node ? current_node->name : "(null)"); if (current_node) { /* properties */ if (current_node->props) { xml_parser_free_props(current_node->props); } /* child nodes */ if (current_node->child) { lprintf("xml_parser_free_tree_rec: child\n"); xml_parser_free_tree_rec(current_node->child, 1); } /* next nodes */ if (free_next) { xml_node_t *next_node = current_node->next; xml_node_t *next_next_node; while (next_node) { next_next_node = next_node->next; lprintf("xml_parser_free_tree_rec: next\n"); xml_parser_free_tree_rec(next_node, 0); next_node = next_next_node; } } free_xml_node(current_node); } } void xml_parser_free_tree(xml_node_t *current_node) { lprintf("xml_parser_free_tree\n"); xml_parser_free_tree_rec(current_node, 1); } typedef enum { /*0*/ STATE_IDLE, /* <foo ...> */ STATE_NODE, STATE_ATTRIBUTE, STATE_NODE_CLOSE, STATE_TAG_TERM, STATE_ATTRIBUTE_EQUALS, STATE_STRING, STATE_TAG_TERM_IGNORE, /* <?foo ...?> */ STATE_Q_NODE, STATE_Q_ATTRIBUTE, STATE_Q_NODE_CLOSE, STATE_Q_TAG_TERM, STATE_Q_ATTRIBUTE_EQUALS, STATE_Q_STRING, /* Others */ STATE_COMMENT, STATE_DOCTYPE, STATE_CDATA, } parser_state_t; static xml_node_t *xml_parser_append_text (xml_node_t *node, xml_node_t *subnode, const char *text, int flags) { if (!text || !*text) return subnode; /* empty string -> nothing to do */ if ((flags & XML_PARSER_MULTI_TEXT) && subnode) { /* we have a subtree, so we can't use node->data */ if (subnode->name == cdata) { /* most recent node is CDATA - append to it */ char *newtext; if (asprintf (&newtext, "%s%s", subnode->data, text) < 0) newtext = NULL; free (subnode->data); subnode->data = newtext; } else { /* most recent node is not CDATA - add a sibling */ subnode->next = new_xml_node (); subnode->next->name = (char *)cdata; subnode->next->data = strdup (text); subnode = subnode->next; } } else if (node->data) { /* "no" subtree, but we have existing text - append to it */ char *newtext; if (asprintf (&newtext, "%s%s", node->data, text) < 0) newtext = NULL; free (node->data); node->data = newtext; } else { /* no text, "no" subtree - duplicate & assign */ while (isspace (*text)) ++text; if (*text) node->data = strdup (text); } return subnode; } #define Q_STATE(CURRENT,NEW) (STATE_##NEW + state - STATE_##CURRENT) static int xml_parser_get_node_internal (xml_parser_t *xml_parser, char ** token_buffer, int * token_buffer_size, char ** pname_buffer, int * pname_buffer_size, char ** nname_buffer, int * nname_buffer_size, xml_node_t *current_node, char *root_names[], int rec, int flags) { char *tok = *token_buffer; char *property_name = *pname_buffer; char *node_name = *nname_buffer; parser_state_t state = STATE_IDLE; int res = 0; int parse_res; int bypass_get_token = 0; int retval = 0; /* used when state==4; non-0 if there are missing </...> */ xml_node_t *current_subtree = NULL; xml_property_t *current_property = NULL; xml_property_t *properties = NULL; if (rec < MAX_RECURSION) { memset (tok, 0, *token_buffer_size); while ((bypass_get_token) || (res = lexer_get_token_d_r(xml_parser->lexer, token_buffer, token_buffer_size, 0)) != T_ERROR) { tok = *token_buffer; bypass_get_token = 0; lprintf("info: %d - %d : '%s'\n", state, res, tok); switch (state) { case STATE_IDLE: switch (res) { case (T_EOL): case (T_SEPAR): /* do nothing */ break; case (T_EOF): xml_parser_free_props(properties); return retval; /* normal end */ break; case (T_M_START_1): state = STATE_NODE; break; case (T_M_START_2): state = STATE_NODE_CLOSE; break; case (T_C_START): state = STATE_COMMENT; break; case (T_TI_START): state = STATE_Q_NODE; break; case (T_DOCTYPE_START): state = STATE_DOCTYPE; break; case (T_CDATA_START): state = STATE_CDATA; break; case (T_DATA): /* current data */ { char *decoded = lexer_decode_entities (tok); current_subtree = xml_parser_append_text (current_node, current_subtree, decoded, flags); free (decoded); } lprintf("info: node data : %s\n", current_node->data); break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; case STATE_NODE: case STATE_Q_NODE: switch (res) { case (T_IDENT): xml_parser_free_props(properties); properties = NULL; current_property = NULL; /* save node name */ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) { strtoupper(tok); } if (state == STATE_Q_NODE) { if (asprintf (&node_name, "?%s", tok) < 0) node_name = NULL; free (*nname_buffer); *nname_buffer = node_name; *nname_buffer_size = strlen (node_name) + 1; state = STATE_Q_ATTRIBUTE; } else { free (*nname_buffer); *nname_buffer = node_name = strdup (tok); *nname_buffer_size = strlen (node_name) + 1; state = STATE_ATTRIBUTE; } lprintf("info: current node name \"%s\"\n", node_name); break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; case STATE_ATTRIBUTE: switch (res) { case (T_EOL): case (T_SEPAR): /* nothing */ break; case (T_M_STOP_1): { xml_node_t *subtree; /* new subtree */ subtree = new_xml_node(); /* set node name */ subtree->name = strdup(node_name); /* set node propertys */ subtree->props = properties; properties = NULL; lprintf("info: rec %d new subtree %s\n", rec, node_name); root_names[rec + 1] = strdup (node_name); parse_res = xml_parser_get_node_internal (xml_parser, token_buffer, token_buffer_size, pname_buffer, pname_buffer_size, nname_buffer, nname_buffer_size, subtree, root_names, rec + 1, flags); tok = *token_buffer; free (root_names[rec + 1]); if (parse_res == -1 || parse_res > 0) { xml_parser_free_tree_rec(subtree, 1); return parse_res; } if (current_subtree == NULL) { _x_assert(current_node->child == NULL); current_node->child = subtree; current_subtree = subtree; } else { _x_assert(current_subtree->next == NULL); current_subtree->next = subtree; current_subtree = subtree; } if (parse_res < -1) { /* badly-formed XML (missing close tag) */ return parse_res + 1 + (parse_res == -2); } state = STATE_IDLE; break; } case (T_M_STOP_2): { /* new leaf */ /* new subtree */ xml_node_t *subtree; new_leaf: subtree = new_xml_node(); /* set node name */ subtree->name = strdup (node_name); /* set node propertys */ subtree->props = properties; properties = NULL; lprintf("info: rec %d new subtree %s\n", rec, node_name); if (current_subtree == NULL) { _x_assert(current_node->child == NULL); current_node->child = subtree; current_subtree = subtree; } else { _x_assert(current_subtree->next == NULL); current_subtree->next = subtree; current_subtree = subtree; } state = STATE_IDLE; break; } case (T_IDENT): /* save property name */ new_prop: if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) { strtoupper(tok); } /* make sure the buffer for the property name is big enough */ if (*token_buffer_size > *pname_buffer_size) { char *tmp_prop; *pname_buffer_size = *token_buffer_size; tmp_prop = realloc (*pname_buffer, *pname_buffer_size); if (!tmp_prop) return -1; *pname_buffer = tmp_prop; property_name = tmp_prop; } else { property_name = *pname_buffer; } strcpy(property_name, tok); state = Q_STATE(ATTRIBUTE, ATTRIBUTE_EQUALS); lprintf("info: current property name \"%s\"\n", property_name); break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; case STATE_Q_ATTRIBUTE: switch (res) { case (T_EOL): case (T_SEPAR): /* nothing */ break; case (T_TI_STOP): goto new_leaf; case (T_IDENT): goto new_prop; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; case STATE_NODE_CLOSE: switch (res) { case (T_IDENT): /* must be equal to root_name */ if (xml_parser->mode == XML_PARSER_CASE_INSENSITIVE) { strtoupper(tok); } if (strcmp(tok, root_names[rec]) == 0) { state = STATE_TAG_TERM; } else if (flags & XML_PARSER_RELAXED) { int r = rec; while (--r >= 0) if (strcmp(tok, root_names[r]) == 0) { lprintf("warning: wanted %s, got %s - assuming missing close tags\n", root_names[rec], tok); retval = r - rec - 1; /* -1 - (no. of implied close tags) */ state = STATE_TAG_TERM; break; } /* relaxed parsing, ignoring extra close tag (but we don't handle out-of-order) */ if (r < 0) { lprintf("warning: extra close tag %s - ignoring\n", tok); state = STATE_TAG_TERM_IGNORE; } } else { lprintf("error: xml struct, tok=%s, waited_tok=%s\n", tok, root_names[rec]); xml_parser_free_props(properties); return -1; } break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; /* > expected */ case STATE_TAG_TERM: switch (res) { case (T_M_STOP_1): return retval; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; /* = or > or ident or separator expected */ case STATE_ATTRIBUTE_EQUALS: switch (res) { case (T_EOL): case (T_SEPAR): /* do nothing */ break; case (T_EQUAL): state = STATE_STRING; break; case (T_IDENT): bypass_get_token = 1; /* jump to state 2 without get a new token */ state = STATE_ATTRIBUTE; break; case (T_M_STOP_1): /* add a new property without value */ if (current_property == NULL) { properties = new_xml_property(); current_property = properties; } else { current_property->next = new_xml_property(); current_property = current_property->next; } current_property->name = strdup (property_name); lprintf("info: new property %s\n", current_property->name); bypass_get_token = 1; /* jump to state 2 without get a new token */ state = STATE_ATTRIBUTE; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; /* = or ?> or ident or separator expected */ case STATE_Q_ATTRIBUTE_EQUALS: switch (res) { case (T_EOL): case (T_SEPAR): /* do nothing */ break; case (T_EQUAL): state = STATE_Q_STRING; break; case (T_IDENT): bypass_get_token = 1; /* jump to state 2 without get a new token */ state = STATE_Q_ATTRIBUTE; break; case (T_TI_STOP): /* add a new property without value */ if (current_property == NULL) { properties = new_xml_property(); current_property = properties; } else { current_property->next = new_xml_property(); current_property = current_property->next; } current_property->name = strdup (property_name); lprintf("info: new property %s\n", current_property->name); bypass_get_token = 1; /* jump to state 2 without get a new token */ state = STATE_Q_ATTRIBUTE; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; /* string or ident or separator expected */ case STATE_STRING: case STATE_Q_STRING: switch (res) { case (T_EOL): case (T_SEPAR): /* do nothing */ break; case (T_STRING): case (T_IDENT): /* add a new property */ if (current_property == NULL) { properties = new_xml_property(); current_property = properties; } else { current_property->next = new_xml_property(); current_property = current_property->next; } current_property->name = strdup(property_name); current_property->value = lexer_decode_entities(tok); lprintf("info: new property %s=%s\n", current_property->name, current_property->value); state = Q_STATE(STRING, ATTRIBUTE); break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; /* --> expected */ case STATE_COMMENT: switch (res) { case (T_C_STOP): state = STATE_IDLE; break; case (T_EOF): lprintf("error: unterminated comment, state %d\n", state); xml_parser_free_props(properties); return -1; default: break; } break; /* > expected */ case STATE_DOCTYPE: switch (res) { case (T_M_STOP_1): state = 0; break; default: break; } break; /* ]]> expected */ case STATE_CDATA: switch (res) { case (T_CDATA_STOP): current_subtree = xml_parser_append_text (current_node, current_subtree, tok, flags); lprintf("info: node cdata : %s\n", tok); state = STATE_IDLE; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; /* > expected (following unmatched "</...") */ case STATE_TAG_TERM_IGNORE: switch (res) { case (T_M_STOP_1): state = STATE_IDLE; break; default: lprintf("error: unexpected token \"%s\", state %d\n", tok, state); xml_parser_free_props(properties); return -1; break; } break; default: lprintf("error: unknown parser state, state=%d\n", state); xml_parser_free_props(properties); return -1; } } /* lex error */ lprintf("error: lexer error\n"); xml_parser_free_props(properties); return -1; } else { /* max recursion */ lprintf("error: max recursion\n"); xml_parser_free_props(properties); return -1; } } static int xml_parser_get_node (xml_parser_t *xml_parser, xml_node_t *current_node, int flags) { int res = 0; int token_buffer_size = TOKEN_SIZE; int pname_buffer_size = TOKEN_SIZE; int nname_buffer_size = TOKEN_SIZE; char *token_buffer = calloc(1, token_buffer_size); char *pname_buffer = calloc(1, pname_buffer_size); char *nname_buffer = calloc(1, nname_buffer_size); char *root_names[MAX_RECURSION + 1]; char tmp_name[] = ""; root_names[0] = tmp_name; res = xml_parser_get_node_internal (xml_parser, &token_buffer, &token_buffer_size, &pname_buffer, &pname_buffer_size, &nname_buffer, &nname_buffer_size, current_node, root_names, 0, flags); free (token_buffer); free (pname_buffer); free (nname_buffer); return res; } /* for ABI compatibility */ int xml_parser_build_tree_with_options(xml_node_t **root_node, int flags) { return xml_parser_build_tree_with_options_r(static_xml_parser, root_node, flags); } int xml_parser_build_tree_with_options_r(xml_parser_t *xml_parser, xml_node_t **root_node, int flags) { xml_node_t *tmp_node, *pri_node, *q_node; int res; tmp_node = new_xml_node(); res = xml_parser_get_node(xml_parser, tmp_node, flags); /* delete any top-level [CDATA] nodes */; pri_node = tmp_node->child; q_node = NULL; while (pri_node) { if (pri_node->name == cdata) { xml_node_t *old = pri_node; if (q_node) q_node->next = pri_node->next; else q_node = pri_node; pri_node = pri_node->next; free_xml_node (old); } else { q_node = pri_node; pri_node = pri_node->next; } } /* find first non-<?...?> node */; for (pri_node = tmp_node->child, q_node = NULL; pri_node && pri_node->name[0] == '?'; pri_node = pri_node->next) q_node = pri_node; /* last <?...?> node (eventually), or NULL */ if (pri_node && !pri_node->next) { /* move the tail to the head (for compatibility reasons) */ if (q_node) { pri_node->next = tmp_node->child; q_node->next = NULL; } *root_node = pri_node; free_xml_node(tmp_node); res = 0; } else { lprintf("error: xml struct\n"); xml_parser_free_tree(tmp_node); res = -1; } return res; } /* for ABI compatibility */ int xml_parser_build_tree(xml_node_t **root_node) { return xml_parser_build_tree_with_options_r (static_xml_parser, root_node, 0); } int xml_parser_build_tree_r(xml_parser_t *xml_parser, xml_node_t **root_node) { return xml_parser_build_tree_with_options_r(xml_parser, root_node, 0); } const char *xml_parser_get_property (const xml_node_t *node, const char *name) { xml_property_t *prop; prop = node->props; while (prop) { lprintf ("looking for %s in %s\n", name, prop->name); if (!strcasecmp (prop->name, name)) { lprintf ("found it. value=%s\n", prop->value); return prop->value; } prop = prop->next; } return NULL; } int xml_parser_get_property_int (const xml_node_t *node, const char *name, int def_value) { const char *v; int ret; v = xml_parser_get_property (node, name); if (!v) return def_value; if (sscanf (v, "%d", &ret) != 1) return def_value; else return ret; } int xml_parser_get_property_bool (const xml_node_t *node, const char *name, int def_value) { const char *v; v = xml_parser_get_property (node, name); if (!v) return def_value; return !strcasecmp (v, "true"); } static int xml_escape_string_internal (char *buf, const char *s, xml_escape_quote_t quote_type) { int c, length = 0; int sl = buf ? 8 : 0; /* calculate max required buffer size */ while ((c = *s++ & 0xFF)) switch (c) { case '"': if (quote_type != XML_ESCAPE_DOUBLE_QUOTE) goto literal; length += snprintf (buf + length, sl, """); break; case '\'': if (quote_type != XML_ESCAPE_SINGLE_QUOTE) goto literal; length += snprintf (buf + length, sl, "'"); break; case '&': length += snprintf (buf + length, sl, "&"); break; case '<': length += snprintf (buf + length, sl, "<"); break; case '>': length += snprintf (buf + length, sl, ">"); break; case 127: length += snprintf (buf + length, sl, ""); break; case '\t': case '\n': literal: if (buf) buf[length] = c; ++length; break; default: if (c >= ' ') goto literal; length += snprintf (buf + length, sl, "&#%d;", c); break; } if (buf) buf[length] = 0; return length + 1; } char *xml_escape_string (const char *s, xml_escape_quote_t quote_type) { char *buf = calloc (1, xml_escape_string_internal (NULL, s, quote_type)); return buf ? (xml_escape_string_internal (buf, s, quote_type), buf) : NULL; } static void xml_parser_dump_node (const xml_node_t *node, int indent) { size_t l; xml_property_t *p; xml_node_t *n; printf ("%*s<%s ", indent, "", node->name); l = strlen (node->name); p = node->props; while (p) { if (p->value) { char *value = xml_escape_string (p->value, XML_ESCAPE_SINGLE_QUOTE); printf ("%s='%s'", p->name, value); free (value); } else { printf ("%s", p->name); } p = p->next; if (p) { printf ("\n%*s", indent+2+(int)l, ""); } } printf (">\n"); if (node->data) { char *value = xml_escape_string (node->data, XML_ESCAPE_SINGLE_QUOTE); printf ("%*s\"%s\"\n", indent + 2, "", value); free(value); } n = node->child; while (n) { xml_parser_dump_node (n, indent+2); n = n->next; } printf ("%*s</%s>\n", indent, "", node->name); } void xml_parser_dump_tree (const xml_node_t *node) { do { xml_parser_dump_node (node, 0); node = node->next; } while (node); } #ifdef XINE_XML_PARSER_TEST #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main (int argc, char **argv) { xml_parser_t *parser; int i, ret = 0; (void)argc; for (i = 1; argv[i]; ++i) { xml_node_t *tree; int fd; void *buf; struct stat st; if (stat (argv[i], &st)) { perror (argv[i]); ret = 1; continue; } if (!S_ISREG (st.st_mode)) { printf ("%s: not a file\n", argv[i]); ret = 1; continue; } fd = open (argv[i], O_RDONLY); if (!fd) { perror (argv[i]); ret = 1; continue; } buf = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (!buf) { perror (argv[i]); if (close (fd)) perror (argv[i]); ret = 1; continue; } parser = xml_parser_init_r (buf, st.st_size, 0); if (parser && !xml_parser_build_tree_r (parser, &tree)) { puts (argv[i]); xml_parser_dump_tree (tree); xml_parser_free_tree (tree); } else printf ("%s: parser failure\n", argv[i]); if (parser) xml_parser_finalize_r(parser); if (close (fd)) { perror (argv[i]); ret = 1; } } return ret; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/array.c�����������������������������������������������������������������0000644�0001750�0001750�00000006432�14647725152�015043� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <xine/attributes.h> #include <xine/xineutils.h> #include <xine/array.h> #define MIN_CHUNK_SIZE 32 /* Array internal struct */ struct xine_array_s { void **chunk; size_t chunk_size; size_t size; }; static void xine_array_ensure_chunk_size(xine_array_t *array, size_t size) { if (size > array->chunk_size) { /* realloc */ size_t new_size = 2 * array->chunk_size; array->chunk = (void**)realloc(array->chunk, sizeof(void *) * new_size); array->chunk_size = new_size; } } /* Constructor */ xine_array_t *xine_array_new(size_t initial_size) { xine_array_t *new_array; new_array = (xine_array_t *)malloc(sizeof(xine_array_t)); if (!new_array) return NULL; if (initial_size < MIN_CHUNK_SIZE) initial_size = MIN_CHUNK_SIZE; new_array->chunk = (void**)calloc(initial_size, sizeof(void*)); if (!new_array->chunk) { free(new_array); return NULL; } new_array->chunk_size = initial_size; new_array->size = 0; return new_array; } /* Destructor */ void xine_array_delete(xine_array_t *array) { _x_freep(&array->chunk); free(array); } size_t xine_array_size(const xine_array_t *array) { return array->size; } void xine_array_clear(xine_array_t *array) { array->size = 0; } void xine_array_add(xine_array_t *array, void *value) { xine_array_ensure_chunk_size(array, array->size + 1); array->chunk[array->size] = value; array->size++; } void xine_array_insert(xine_array_t *array, unsigned int position, void *value) { if (position < array->size) { xine_array_ensure_chunk_size(array, array->size + 1); memmove(&array->chunk[position + 1], &array->chunk[position], sizeof(void *) * (array->size - position)); array->chunk[position] = value; array->size++; } else { xine_array_add(array, value); } } void xine_array_remove(xine_array_t *array, unsigned int position) { if (array->size > 0) { if (position < array->size) { memmove(&array->chunk[position], &array->chunk[position + 1], sizeof(void *) * (array->size - (position + 1))); } array->size--; } } void *xine_array_get(const xine_array_t *array, unsigned int position) { if (position < array->size) return array->chunk[position]; else return NULL; } void xine_array_set(xine_array_t *array, unsigned int position, void *value) { if (position < array->size) array->chunk[position] = value; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/pool.c������������������������������������������������������������������0000644�0001750�0001750�00000012626�14647725152�014700� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/attributes.h> #include <xine/pool.h> #include <xine/xineutils.h> #include <xine/array.h> #define MIN_CHUNK_SIZE 32 #define MAX_CHUNK_SIZE 65536 /* chunk of objects */ typedef struct xine_pool_chunk_s xine_pool_chunk_t; struct xine_pool_chunk_s { void *mem_base; /* the allocated elements */ int count; /* object count in the chunk */ int current_id; /* next free object in the chunk */ }; struct xine_pool_s { size_t object_size; /* callbacks */ void (*create_object)(void *object); void (*prepare_object)(void *object); void (*return_object)(void *object); void (*delete_object)(void *object); /* chunks */ xine_array_t *chunk_list; xine_array_t *free_list; }; /* Allocates a new chunk of n elements * One malloc call is used to allocate the struct and the elements. */ static xine_pool_chunk_t *XINE_MALLOC xine_pool_alloc_chunk(size_t object_size, size_t object_count) { xine_pool_chunk_t *new_chunk; size_t chunk_mem_size;; _x_assert(object_size > 0); _x_assert(object_count > 0); chunk_mem_size = sizeof(xine_pool_chunk_t); chunk_mem_size += object_size * object_count; new_chunk = (xine_pool_chunk_t *)malloc(chunk_mem_size); if (!new_chunk) { return NULL; } new_chunk->mem_base = (xine_pool_chunk_t*)(new_chunk + 1); new_chunk->current_id = 0; new_chunk->count = object_count; return new_chunk; } /* Delete a chunk */ static void xine_pool_delete_chunk(xine_pool_chunk_t *chunk) { _x_assert(chunk); free(chunk); } xine_pool_t *xine_pool_new(size_t object_size, void (*create_object)(void *object), void (*prepare_object)(void *object), void (*return_object)(void *object), void (*delete_object)(void *object)) { xine_pool_t *new_pool; _x_assert(object_size > 0); new_pool = malloc(sizeof(xine_pool_t)); if (!new_pool) { return NULL; } new_pool->object_size = object_size; new_pool->create_object = create_object; new_pool->prepare_object = prepare_object; new_pool->return_object = return_object; new_pool->delete_object = delete_object; new_pool->chunk_list = xine_array_new(0); new_pool->free_list = xine_array_new(MIN_CHUNK_SIZE); xine_array_add(new_pool->chunk_list, xine_pool_alloc_chunk (object_size, MIN_CHUNK_SIZE)); return new_pool; } void xine_pool_delete(xine_pool_t *pool) { int list_id, list_size; _x_assert(pool); list_size = xine_array_size(pool->chunk_list); for (list_id = 0; list_id < list_size; list_id++) { xine_pool_chunk_t *chunk = xine_array_get(pool->chunk_list, list_id); /* delete each created object */ if (pool->delete_object) { int i; for (i = 0; i < chunk->current_id; i++) { void *object = ((uint8_t*)(chunk->mem_base)) + i * pool->object_size; pool->delete_object(object); } } xine_pool_delete_chunk(chunk); } free (pool); } void *xine_pool_get(xine_pool_t *pool) { void *object = NULL; int free_count; _x_assert(pool); /* check the free list */ free_count = xine_array_size(pool->free_list); if (free_count > 0) { object = xine_array_get(pool->free_list, free_count - 1); xine_array_remove(pool->free_list, free_count - 1); } else { /* check the current chunk */ int chunk_count = xine_array_size(pool->chunk_list); xine_pool_chunk_t *current_chunk = xine_array_get(pool->chunk_list, chunk_count - 1); if (current_chunk->current_id < current_chunk->count) { /* take the next entry of the chunk */ object = ((uint8_t*)(current_chunk->mem_base)) + current_chunk->current_id * pool->object_size; current_chunk->current_id++; } else { /* create a new chunk */ xine_pool_chunk_t *new_chunk; int new_chunk_count = current_chunk->count * 2; if (new_chunk_count > MAX_CHUNK_SIZE) { new_chunk_count = MAX_CHUNK_SIZE; } new_chunk = xine_pool_alloc_chunk (pool->object_size, new_chunk_count); if (!new_chunk) { return NULL; } xine_array_add(pool->chunk_list, new_chunk); object = new_chunk->mem_base; new_chunk->current_id = 1; } if (pool->create_object) { pool->create_object(object); } } if (pool->prepare_object) { pool->prepare_object(object); } return object; } void xine_pool_put(xine_pool_t *pool, void *object) { _x_assert(pool); _x_assert(object); if (pool->return_object) { pool->return_object(object); } xine_array_add(pool->free_list, object); } ����������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/ring_buffer.c�����������������������������������������������������������0000644�0001750�0001750�00000027453�14647725152�016223� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <pthread.h> #include <stdlib.h> #include <inttypes.h> #include <stdio.h> #include <string.h> #include <xine/attributes.h> #include <xine/xineutils.h> #include <xine/pool.h> #include <xine/list.h> #include <xine/ring_buffer.h> #define RING_BUFFER_EXTRA_BUFFER_SIZE (1024 * 8) /* internal memory chunk struct */ typedef struct xine_ring_buffer_chunk_s xine_ring_buffer_chunk_t; struct xine_ring_buffer_chunk_s { uint8_t *mem; size_t size; }; /* init */ static void xine_ring_buffer_chunk_create(void *object) { xine_ring_buffer_chunk_t *chunk = (xine_ring_buffer_chunk_t *)object; chunk->mem = NULL; chunk->size = 0; } /* cleanup */ static void xine_ring_buffer_chunk_return(void *object) { xine_ring_buffer_chunk_t *chunk = (xine_ring_buffer_chunk_t *)object; chunk->mem = NULL; chunk->size = 0; } /* ring buffer internal struct */ struct xine_ring_buffer_s { uint8_t *head; uint8_t *head_alloc; uint8_t *tail; uint8_t *tail_release; uint8_t *buffer; size_t buffer_size; /* size of the allocated buffer */ uint8_t *buffer_end; size_t free_size; /* size of the free zone */ size_t full_size; /* size of the full zone */ pthread_cond_t free_size_cond; pthread_cond_t full_size_cond; int free_size_needed; int full_size_needed; xine_pool_t *chunk_pool; xine_list_t *alloc_list; xine_list_t *get_list; uint8_t *extra_buffer; size_t extra_buffer_size; pthread_mutex_t lock; int EOS; }; /* Constructor */ xine_ring_buffer_t *xine_ring_buffer_new(size_t size) { xine_ring_buffer_t *new_ring_buffer = malloc(sizeof(xine_ring_buffer_t)); if (!new_ring_buffer) { return NULL; } new_ring_buffer->buffer = malloc(size); if (!new_ring_buffer->buffer) { free(new_ring_buffer); return NULL; } new_ring_buffer->buffer_size = size; new_ring_buffer->alloc_list = xine_list_new(); new_ring_buffer->get_list = xine_list_new(); new_ring_buffer->chunk_pool = xine_pool_new(sizeof(xine_ring_buffer_chunk_t), xine_ring_buffer_chunk_create, NULL, xine_ring_buffer_chunk_return, NULL); new_ring_buffer->head = new_ring_buffer->buffer; new_ring_buffer->head_alloc = new_ring_buffer->buffer; new_ring_buffer->tail = new_ring_buffer->buffer; new_ring_buffer->tail_release = new_ring_buffer->buffer; new_ring_buffer->free_size = size; pthread_cond_init(&new_ring_buffer->free_size_cond, NULL); new_ring_buffer->free_size_needed = 0; new_ring_buffer->full_size = 0; pthread_cond_init(&new_ring_buffer->full_size_cond, NULL); new_ring_buffer->full_size_needed = 0; pthread_mutex_init(&new_ring_buffer->lock, NULL); new_ring_buffer->buffer_end = new_ring_buffer->buffer + size; new_ring_buffer->extra_buffer = malloc(RING_BUFFER_EXTRA_BUFFER_SIZE); new_ring_buffer->extra_buffer_size = RING_BUFFER_EXTRA_BUFFER_SIZE; new_ring_buffer->EOS = 0; return new_ring_buffer; } /* Destructor */ void xine_ring_buffer_delete(xine_ring_buffer_t *ring_buffer) { xine_list_delete(ring_buffer->alloc_list); xine_list_delete(ring_buffer->get_list); xine_pool_delete(ring_buffer->chunk_pool); pthread_mutex_destroy(&ring_buffer->lock); _x_freep (&ring_buffer->buffer); free (ring_buffer); } static void xine_ring_buffer_display_stat(const xine_ring_buffer_t *ring_buffer) { #if DEBUG_RING_BUFFER size_t free_size, full_size; printf("alloc: free_size1=%d full_size1=%d\n", ring_buffer->free_size, ring_buffer->full_size); if (ring_buffer->tail_release > ring_buffer->head_alloc) { free_size = ring_buffer->tail_release-ring_buffer->head_alloc; } else { free_size = ring_buffer->tail_release + (ring_buffer->buffer_end - ring_buffer->buffer) - ring_buffer->head_alloc; } if (ring_buffer->head > ring_buffer->tail) { full_size = ring_buffer->head - ring_buffer->tail; } else { full_size = ring_buffer->head + (ring_buffer->buffer_end - ring_buffer->buffer) - ring_buffer->tail; } printf("alloc: free_size2=%d full_size2=%d\n", free_size, full_size); printf("alloc: head_alloc=%d, head=%d, tail=%d, tail_release=%d\n", ring_buffer->head_alloc - ring_buffer->buffer, ring_buffer->head - ring_buffer->buffer, ring_buffer->tail_release - ring_buffer->buffer, ring_buffer->tail - ring_buffer->buffer); #else (void)ring_buffer; #endif } void *xine_ring_buffer_alloc(xine_ring_buffer_t *ring_buffer, size_t size) { int ok = 0; xine_ring_buffer_chunk_t *chunk; _x_assert(ring_buffer); pthread_mutex_lock(&ring_buffer->lock); xine_ring_buffer_display_stat(ring_buffer); do { while (size > ring_buffer->free_size) { /* we need more free room */ ring_buffer->free_size_needed++; pthread_cond_wait (&ring_buffer->free_size_cond, &ring_buffer->lock); ring_buffer->free_size_needed--; } if ((ring_buffer->head_alloc + size) > (ring_buffer->buffer + ring_buffer->buffer_size)) { /* we can't get a continuous buffer of this size from the ring buffer, define the end of the buffer here and go back to the beginning */ ring_buffer->buffer_end = ring_buffer->head_alloc; ring_buffer->head_alloc = ring_buffer->buffer; ring_buffer->free_size -= (ring_buffer->buffer + ring_buffer->buffer_size) - ring_buffer->buffer_end; } else { ok = 1; } } while (!ok); /* create a new chunk and add it to the allocated list */ chunk = xine_pool_get(ring_buffer->chunk_pool); chunk->mem = ring_buffer->head_alloc; chunk->size = size; xine_list_push_back(ring_buffer->alloc_list, chunk); ring_buffer->head_alloc += size; ring_buffer->free_size -= size; pthread_mutex_unlock(&ring_buffer->lock); return chunk->mem; } void xine_ring_buffer_put(xine_ring_buffer_t *ring_buffer, void *buffer) { xine_list_iterator_t ite; xine_ring_buffer_chunk_t *chunk = NULL; xine_ring_buffer_chunk_t *prev_chunk = NULL; /* at this point, the chunk contains data */ /* find the chunk in the allocated list */ pthread_mutex_lock(&ring_buffer->lock); for (ite = xine_list_front(ring_buffer->alloc_list); ite; ite = xine_list_next(ring_buffer->alloc_list, ite)) { chunk = xine_list_get_value(ring_buffer->alloc_list, ite); if (chunk->mem == buffer) break; prev_chunk = chunk; } _x_assert(ite); _x_assert(chunk); /* found associated chunk, is it the first in the list ? */ if (!prev_chunk) { if (ring_buffer->head == ring_buffer->buffer_end) { ring_buffer->head = ring_buffer->buffer; } /* increment ring_buffer head, and full_size */ ring_buffer->head += chunk->size; ring_buffer->full_size += chunk->size; /* notify */ if (ring_buffer->full_size_needed) { pthread_cond_broadcast(&ring_buffer->full_size_cond); } } else { /* merge with previous chunk */ prev_chunk->size += chunk->size; } xine_list_remove(ring_buffer->alloc_list, ite); xine_pool_put(ring_buffer->chunk_pool, chunk); pthread_mutex_unlock(&ring_buffer->lock); } void *xine_ring_buffer_get(xine_ring_buffer_t *ring_buffer, size_t size, size_t *rsize) { xine_ring_buffer_chunk_t *chunk; size_t continuous_size; uint8_t *mem_chunk; _x_assert(ring_buffer); _x_assert(rsize); pthread_mutex_lock(&ring_buffer->lock); while ((size > ring_buffer->full_size) && !ring_buffer->EOS) { /* we need more free room */ ring_buffer->full_size_needed++; pthread_cond_wait (&ring_buffer->full_size_cond, &ring_buffer->lock); ring_buffer->full_size_needed--; } if (size > ring_buffer->full_size) { size = ring_buffer->full_size; } continuous_size = ring_buffer->buffer_end - ring_buffer->tail; if (size > continuous_size) { /* we can't get a continuous buffer of this size from the ring buffer, we accumulate the ringbuffer content into the extra buffer */ if (ring_buffer->extra_buffer_size < size) { ring_buffer->extra_buffer = realloc(ring_buffer->extra_buffer, size); ring_buffer->extra_buffer_size = size; } memcpy(ring_buffer->extra_buffer, ring_buffer->tail, continuous_size); memcpy(ring_buffer->extra_buffer + continuous_size, ring_buffer->buffer, size - continuous_size); mem_chunk = ring_buffer->extra_buffer; ring_buffer->tail = ring_buffer->buffer + size - continuous_size; } else { mem_chunk = ring_buffer->tail; ring_buffer->tail += size; } /* create a new chunk and add it to the allocated list */ chunk = xine_pool_get(ring_buffer->chunk_pool); chunk->mem = mem_chunk; chunk->size = size; xine_list_push_back(ring_buffer->get_list, chunk); *rsize = size; ring_buffer->full_size -= size; pthread_mutex_unlock(&ring_buffer->lock); return chunk->mem; } void xine_ring_buffer_release(xine_ring_buffer_t *ring_buffer, void *buffer) { xine_list_iterator_t ite; xine_ring_buffer_chunk_t *chunk = NULL; xine_ring_buffer_chunk_t *prev_chunk = NULL; /* the chunk can be reused */ /* find the chunk in the get list */ pthread_mutex_lock(&ring_buffer->lock); for (ite = xine_list_front(ring_buffer->get_list); ite; ite = xine_list_next(ring_buffer->get_list, ite)) { chunk = xine_list_get_value(ring_buffer->get_list, ite); if (chunk->mem == buffer) break; prev_chunk = chunk; } _x_assert(ite); _x_assert(chunk); /* found associated chunk, is it the first in the list ? */ if (!prev_chunk) { size_t continuous_size; /* increment ringbuffer tail_release and free_size */ continuous_size = ring_buffer->buffer_end - ring_buffer->tail_release; if (chunk->size > continuous_size) { ring_buffer->tail_release = ring_buffer->buffer + chunk->size - continuous_size; /* place the buffer_end back to the end */ ring_buffer->free_size += (ring_buffer->buffer + ring_buffer->buffer_size) - ring_buffer->buffer_end; ring_buffer->buffer_end = ring_buffer->buffer + ring_buffer->buffer_size; } else { ring_buffer->tail_release += chunk->size; } ring_buffer->free_size += chunk->size; /* notify */ if (ring_buffer->free_size_needed) { pthread_cond_broadcast(&ring_buffer->free_size_cond); } } else { /* merge with previous chunk */ prev_chunk->size += chunk->size; } xine_list_remove(ring_buffer->get_list, ite); xine_pool_put(ring_buffer->chunk_pool, chunk); pthread_mutex_unlock(&ring_buffer->lock); } void xine_ring_buffer_close(xine_ring_buffer_t *ring_buffer) { pthread_mutex_lock(&ring_buffer->lock); ring_buffer->EOS = 1; /* notify */ if (ring_buffer->full_size_needed) { pthread_cond_broadcast(&ring_buffer->full_size_cond); } pthread_mutex_unlock(&ring_buffer->lock); } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/yuv2rgb.c���������������������������������������������������������������0000644�0001750�0001750�00000256146�14647725152�015336� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * yuv2rgb.c * * Copyright (C) 2003-2018 the xine project * This file is part of xine, a free video player. * * based on work from mpeg2dec: * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include "yuv2rgb_private.h" #define LOG_MODULE "yuv2rgb" #define LOG_VERBOSE /* #define LOG */ #include <xine/xineutils.h> static int prof_scale_line = -1; static scale_line_func_t find_scale_line_func(int step); const int32_t Inverse_Table_6_9[8][4] = { {117504, 138453, 13954, 34903}, /* no sequence_display_extension */ {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */ {104597, 132201, 25675, 53279}, /* unspecified */ {104597, 132201, 25675, 53279}, /* reserved */ {104448, 132798, 24759, 53109}, /* FCC */ {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */ {104597, 132201, 25675, 53279}, /* SMPTE 170M */ {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ }; static int yuv2rgb_next_slice (yuv2rgb_impl_t *this, uint8_t *restrict *dest) { int y0, y1; if (dest == NULL) { this->slice_offset = 0; this->slice_height = 16; return 0; } if (this->slice_height == this->source_height) { return this->dest_height; } y0 = (this->slice_offset * this->dest_height) / this->source_height; y1 = ((this->slice_offset + this->slice_height) * this->dest_height) / this->source_height; *dest += (this->rgb_stride * y0); if ((this->slice_offset + this->slice_height) >= this->source_height) { this->slice_offset = 0; return (this->dest_height - y0); } else { this->slice_offset += this->slice_height; return (y1 - y0); } } static int yuv2rgb_next_slice_intf (yuv2rgb_t *this_gen, uint8_t **dest) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t *)this_gen; return yuv2rgb_next_slice (this, dest); } static void yuv2rgb_dispose (yuv2rgb_t *this_gen) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t *)this_gen; xine_free_aligned (this->y_buffer); xine_free_aligned (this->u_buffer); xine_free_aligned (this->v_buffer); #ifdef HAVE_MLIB xine_free_aligned (this->mlib_buffer); xine_free_aligned (this->mlib_resize_buffer); #endif free (this); } static int yuv2rgb_configure (yuv2rgb_t *this_gen, int source_width, int source_height, int y_stride, int uv_stride, int dest_width, int dest_height, int rgb_stride) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t *)this_gen; /* printf ("yuv2rgb setup (%d x %d => %d x %d)\n", source_width, source_height, dest_width, dest_height); */ if (prof_scale_line == -1) prof_scale_line = xine_profiler_allocate_slot("xshm scale line"); this->source_width = source_width; this->source_height = source_height; this->y_stride = y_stride; this->uv_stride = uv_stride; this->dest_width = dest_width; this->dest_height = dest_height; this->rgb_stride = rgb_stride; this->slice_height = source_height; this->slice_offset = 0; xine_freep_aligned (&this->y_buffer); xine_freep_aligned (&this->u_buffer); xine_freep_aligned (&this->v_buffer); #ifdef HAVE_MLIB xine_freep_aligned (&this->mlib_buffer); xine_freep_aligned (&this->mlib_resize_buffer); #endif this->step_dx = source_width * 32768 / dest_width; this->step_dy = source_height * 32768 / dest_height; /* printf("yuv2rgb config: src_ht=%i, dst_ht=%i\n",source_height, dest_height); printf("yuv2rgb config: step_dy=%i %f\n",this->step_dy, (float)this->step_dy / 32768.0); */ this->scale_line = find_scale_line_func(this->step_dx); if ((source_width == dest_width) && (source_height == dest_height)) { this->do_scale = 0; /* * space for two y-lines (for yuv2rgb_mlib) * u,v subsampled 2:1 */ this->y_buffer = xine_malloc_aligned (2 * dest_width); if (!this->y_buffer) return 0; this->u_buffer = xine_malloc_aligned ((dest_width + 1) / 2); if (!this->u_buffer) return 0; this->v_buffer = xine_malloc_aligned ((dest_width + 1) / 2); if (!this->v_buffer) return 0; } else { this->do_scale = 1; /* * space for two y-lines (for yuv2rgb_mlib) * u,v subsampled 2:1 */ this->y_buffer = xine_malloc_aligned (2 * dest_width); if (!this->y_buffer) return 0; this->u_buffer = xine_malloc_aligned ((dest_width + 1) / 2); if (!this->u_buffer) return 0; this->v_buffer = xine_malloc_aligned ((dest_width + 1) / 2); if (!this->v_buffer) return 0; #ifdef HAVE_MLIB /* Only need these if we are resizing and in mlib code */ this->mlib_buffer = xine_malloc_aligned (source_width * source_height * 4); if (!this->mlib_buffer) return 0; /* Only need this one if we are 24 bit */ if((rgb_stride / dest_width) == 3) { this->mlib_resize_buffer = xine_malloc_aligned (dest_width * dest_height * 4); if (!this->mlib_resize_buffer) return 0; } #endif } return 1; } static void scale_line_gen (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { /* * scales a yuv source row to a dest row, with interpolation * (good quality, but slow) */ int p1; int p2; int dx; xine_profiler_start_count(prof_scale_line); p1 = *source++; p2 = *source++; dx = 0; /* * the following code has been optimized by Scott Smith <ssmith@akamai.com>: * * ok now I have a meaningful optimization for yuv2rgb.c:scale_line_gen. * it removes the loop from within the while() loop by separating it out * into 3 cases: where you are enlarging the line (<32768), where you are * between 50% and 100% of the original line (<=65536), and where you are * shrinking it by a lot. anyways, I went from 200 delivered / 100+ * skipped to 200 delivered / 80 skipped for the enlarging case. I * noticed when looking at the assembly that the compiler was able to * unroll these while(width) loops, whereas before it was trying to * unroll the while(dx>32768) loops. so the compiler is better able to * deal with this code. */ if (step < 32768) { while (width) { *dest = p1 + (((p2-p1) * dx)>>15); dx += step; if (dx > 32768) { dx -= 32768; p1 = p2; p2 = *source++; } dest ++; width --; } } else if (step <= 65536) { while (width) { *dest = p1 + (((p2-p1) * dx)>>15); dx += step; if (dx > 65536) { dx -= 65536; p1 = *source++; p2 = *source++; } else { dx -= 32768; p1 = p2; p2 = *source++; } dest ++; width --; } } else { while (width) { int offs; *dest = p1 + (((p2-p1) * dx)>>15); dx += step; offs=((dx-1)>>15); dx-=offs<<15; source+=offs-2; p1=*source++; p2=*source++; dest ++; width --; } } xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 16 output pixels from 15 source pixels using shifts. * Useful for scaling a PAL mpeg2 dvd input source to 4:3 format on * a monitor using square pixels. * (720 x 576 ==> 768 x 576) */ static void scale_line_15_16 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 16) >= 0) { p1 = source[0]; dest[0] = p1; p2 = source[1]; dest[1] = (1*p1 + 7*p2) >> 3; p1 = source[2]; dest[2] = (1*p2 + 7*p1) >> 3; p2 = source[3]; dest[3] = (1*p1 + 3*p2) >> 2; p1 = source[4]; dest[4] = (1*p2 + 3*p1) >> 2; p2 = source[5]; dest[5] = (3*p1 + 5*p2) >> 3; p1 = source[6]; dest[6] = (3*p2 + 5*p1) >> 3; p2 = source[7]; dest[7] = (1*p1 + 1*p1) >> 1; p1 = source[8]; dest[8] = (1*p2 + 1*p1) >> 1; p2 = source[9]; dest[9] = (5*p1 + 3*p2) >> 3; p1 = source[10]; dest[10] = (5*p2 + 3*p1) >> 3; p2 = source[11]; dest[11] = (3*p1 + 1*p2) >> 2; p1 = source[12]; dest[12] = (3*p2 + 1*p1) >> 2; p2 = source[13]; dest[13] = (7*p1 + 1*p2) >> 3; p1 = source[14]; dest[14] = (7*p2 + 1*p1) >> 3; dest[15] = p1; source += 15; dest += 16; } if ((width += 16) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (1*source[0] + 7*source[1]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[1] + 7*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[2] + 3*source[3]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[3] + 3*source[4]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[4] + 5*source[5]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[5] + 5*source[6]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[6] + 1*source[7]) >> 1; if (--width <= 0) goto done; *dest++ = (1*source[7] + 1*source[8]) >> 1; if (--width <= 0) goto done; *dest++ = (5*source[8] + 3*source[9]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[9] + 3*source[10]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[10] + 1*source[11]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[11] + 1*source[12]) >> 2; if (--width <= 0) goto done; *dest++ = (7*source[12] + 1*source[13]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[13] + 1*source[14]) >> 3; done: xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 53 output pixels from 45 source pixels using shifts. * Useful for scaling a NTSC mpeg2 dvd input source to 16:9 display * resulution * fullscreen resolution, or to 16:9 format on a monitor using square * pixels. * (720 x 480 ==> 848 x 480) */ static void scale_line_45_53 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 53) >= 0) { p1 = source[0]; p2 = source[1]; dest[0] = p1; dest[1] = (1*p1 + 7*p2) >> 3; p1 = source[2]; dest[2] = (1*p2 + 3*p1) >> 2; p2 = source[3]; dest[3] = (1*p1 + 1*p2) >> 1; p1 = source[4]; dest[4] = (5*p2 + 3*p1) >> 3; p2 = source[5]; dest[5] = (3*p1 + 1*p2) >> 2; p1 = source[6]; dest[6] = (7*p2 + 1*p1) >> 3; dest[7] = p1; p2 = source[7]; dest[8] = (1*p1 + 3*p2) >> 2; p1 = source[8]; dest[9] = (3*p2 + 5*p1) >> 3; p2 = source[9]; dest[10] = (1*p1 + 1*p2) >> 1; p1 = source[10]; dest[11] = (5*p2 + 3*p1) >> 3; p2 = source[11]; dest[12] = (3*p1 + 1*p2) >> 2; p1 = source[12]; dest[13] = p2; dest[14] = (1*p2 + 7*p1) >> 3; p2 = source[13]; dest[15] = (1*p1 + 3*p2) >> 2; p1 = source[14]; dest[16] = (3*p2 + 5*p1) >> 3; p2 = source[15]; dest[17] = (5*p1 + 3*p2) >> 3; p1 = source[16]; dest[18] = (3*p2 + 1*p1) >> 2; p2 = source[17]; dest[19] = (7*p1 + 1*p2) >> 3; dest[20] = p2; p1 = source[18]; dest[21] = (1*p2 + 7*p1) >> 3; p2 = source[19]; dest[22] = (3*p1 + 5*p2) >> 3; p1 = source[20]; dest[23] = (1*p2 + 1*p1) >> 1; p2 = source[21]; dest[24] = (5*p1 + 3*p2) >> 3; p1 = source[22]; dest[25] = (3*p2 + 1*p1) >> 2; p2 = source[23]; dest[26] = (7*p1 + 1*p2) >> 3; dest[27] = (1*p1 + 7*p2) >> 3; p1 = source[24]; dest[28] = (1*p2 + 3*p1) >> 2; p2 = source[25]; dest[29] = (3*p1 + 5*p2) >> 3; p1 = source[26]; dest[30] = (1*p2 + 1*p1) >> 1; p2 = source[27]; dest[31] = (5*p1 + 3*p2) >> 3; p1 = source[28]; dest[32] = (7*p2 + 1*p1) >> 3; p2 = source[29]; dest[33] = p1; dest[34] = (1*p1 + 7*p2) >> 3; p1 = source[30]; dest[35] = (1*p2 + 3*p1) >> 2; p2 = source[31]; dest[36] = (3*p1 + 5*p2) >> 3; p1 = source[32]; dest[37] = (5*p2 + 3*p1) >> 3; p2 = source[33]; dest[38] = (3*p1 + 1*p2) >> 2; p1 = source[34]; dest[39] = (7*p2 + 1*p1) >> 3; dest[40] = p1; p2 = source[35]; dest[41] = (1*p1 + 3*p2) >> 2; p1 = source[36]; dest[42] = (3*p2 + 5*p1) >> 3; p2 = source[37]; dest[43] = (1*p1 + 1*p2) >> 1; p1 = source[38]; dest[44] = (5*p2 + 3*p1) >> 3; p2 = source[39]; dest[45] = (3*p1 + 1*p2) >> 2; p1 = source[40]; dest[46] = p2; dest[47] = (1*p2 + 7*p1) >> 3; p2 = source[41]; dest[48] = (1*p1 + 3*p2) >> 2; p1 = source[42]; dest[49] = (3*p2 + 5*p1) >> 3; p2 = source[43]; dest[50] = (1*p1 + 1*p2) >> 1; p1 = source[44]; dest[51] = (3*p2 + 1*p1) >> 2; p2 = source[45]; dest[52] = (7*p1 + 1*p2) >> 3; source += 45; dest += 53; } if ((width += 53) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (1*source[0] + 7*source[1]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[1] + 3*source[2]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[2] + 1*source[3]) >> 1; if (--width <= 0) goto done; *dest++ = (5*source[3] + 3*source[4]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[4] + 1*source[5]) >> 2; if (--width <= 0) goto done; *dest++ = (7*source[5] + 1*source[6]) >> 3; if (--width <= 0) goto done; *dest++ = source[6]; if (--width <= 0) goto done; *dest++ = (1*source[6] + 3*source[7]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[7] + 5*source[8]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[8] + 1*source[9]) >> 1; if (--width <= 0) goto done; *dest++ = (5*source[9] + 3*source[10]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[10] + 1*source[11]) >> 2; if (--width <= 0) goto done; *dest++ = source[11]; if (--width <= 0) goto done; *dest++ = (1*source[11] + 7*source[12]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[12] + 3*source[13]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[13] + 5*source[14]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[14] + 3*source[15]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[15] + 1*source[16]) >> 2; if (--width <= 0) goto done; *dest++ = (7*source[16] + 1*source[17]) >> 3; if (--width <= 0) goto done; *dest++ = source[17]; if (--width <= 0) goto done; *dest++ = (1*source[17] + 7*source[18]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[18] + 5*source[19]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[19] + 1*source[20]) >> 1; if (--width <= 0) goto done; *dest++ = (5*source[20] + 3*source[21]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[21] + 1*source[22]) >> 2; if (--width <= 0) goto done; *dest++ = (7*source[22] + 1*source[23]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[22] + 7*source[23]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[23] + 3*source[24]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[24] + 5*source[25]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[25] + 1*source[26]) >> 1; if (--width <= 0) goto done; *dest++ = (5*source[26] + 3*source[27]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[27] + 1*source[28]) >> 3; if (--width <= 0) goto done; *dest++ = source[28]; if (--width <= 0) goto done; *dest++ = (1*source[28] + 7*source[29]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[29] + 3*source[30]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[30] + 5*source[31]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[31] + 3*source[32]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[32] + 1*source[33]) >> 2; if (--width <= 0) goto done; *dest++ = (7*source[33] + 1*source[34]) >> 3; if (--width <= 0) goto done; *dest++ = source[34]; if (--width <= 0) goto done; *dest++ = (1*source[34] + 3*source[35]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[35] + 5*source[36]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[36] + 1*source[37]) >> 1; if (--width <= 0) goto done; *dest++ = (5*source[37] + 3*source[38]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[38] + 1*source[39]) >> 2; if (--width <= 0) goto done; *dest++ = source[39]; if (--width <= 0) goto done; *dest++ = (1*source[39] + 7*source[40]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[40] + 3*source[41]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[41] + 5*source[42]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[42] + 1*source[43]) >> 1; if (--width <= 0) goto done; *dest++ = (3*source[43] + 1*source[44]) >> 2; done: xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 64 output pixels from 45 source pixels using shifts. * Useful for scaling a PAL mpeg2 dvd input source to 1024x768 * fullscreen resolution, or to 16:9 format on a monitor using square * pixels. * (720 x 576 ==> 1024 x 576) */ static void scale_line_45_64 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 64) >= 0) { p1 = source[0]; p2 = source[1]; dest[0] = p1; dest[1] = (1*p1 + 3*p2) >> 2; p1 = source[2]; dest[2] = (5*p2 + 3*p1) >> 3; p2 = source[3]; dest[3] = (7*p1 + 1*p2) >> 3; dest[4] = (1*p1 + 3*p2) >> 2; p1 = source[4]; dest[5] = (1*p2 + 1*p1) >> 1; p2 = source[5]; dest[6] = (3*p1 + 1*p2) >> 2; dest[7] = (1*p1 + 7*p2) >> 3; p1 = source[6]; dest[8] = (3*p2 + 5*p1) >> 3; p2 = source[7]; dest[9] = (5*p1 + 3*p2) >> 3; p1 = source[8]; dest[10] = p2; dest[11] = (1*p2 + 3*p1) >> 2; p2 = source[9]; dest[12] = (5*p1 + 3*p2) >> 3; p1 = source[10]; dest[13] = (7*p2 + 1*p1) >> 3; dest[14] = (1*p2 + 7*p1) >> 3; p2 = source[11]; dest[15] = (1*p1 + 1*p2) >> 1; p1 = source[12]; dest[16] = (3*p2 + 1*p1) >> 2; dest[17] = p1; p2 = source[13]; dest[18] = (3*p1 + 5*p2) >> 3; p1 = source[14]; dest[19] = (5*p2 + 3*p1) >> 3; p2 = source[15]; dest[20] = p1; dest[21] = (1*p1 + 3*p2) >> 2; p1 = source[16]; dest[22] = (1*p2 + 1*p1) >> 1; p2 = source[17]; dest[23] = (7*p1 + 1*p2) >> 3; dest[24] = (1*p1 + 7*p2) >> 3; p1 = source[18]; dest[25] = (3*p2 + 5*p1) >> 3; p2 = source[19]; dest[26] = (3*p1 + 1*p2) >> 2; dest[27] = p2; p1 = source[20]; dest[28] = (3*p2 + 5*p1) >> 3; p2 = source[21]; dest[29] = (5*p1 + 3*p2) >> 3; p1 = source[22]; dest[30] = (7*p2 + 1*p1) >> 3; dest[31] = (1*p2 + 3*p1) >> 2; p2 = source[23]; dest[32] = (1*p1 + 1*p2) >> 1; p1 = source[24]; dest[33] = (3*p2 + 1*p1) >> 2; dest[34] = (1*p2 + 7*p1) >> 3; p2 = source[25]; dest[35] = (3*p1 + 5*p2) >> 3; p1 = source[26]; dest[36] = (3*p2 + 1*p1) >> 2; p2 = source[27]; dest[37] = p1; dest[38] = (1*p1 + 3*p2) >> 2; p1 = source[28]; dest[39] = (5*p2 + 3*p1) >> 3; p2 = source[29]; dest[40] = (7*p1 + 1*p2) >> 3; dest[41] = (1*p1 + 7*p2) >> 3; p1 = source[30]; dest[42] = (1*p2 + 1*p1) >> 1; p2 = source[31]; dest[43] = (3*p1 + 1*p2) >> 2; dest[44] = (1*p1 + 7*p2) >> 3; p1 = source[32]; dest[45] = (3*p2 + 5*p1) >> 3; p2 = source[33]; dest[46] = (5*p1 + 3*p2) >> 3; p1 = source[34]; dest[47] = p2; dest[48] = (1*p2 + 3*p1) >> 2; p2 = source[35]; dest[49] = (1*p1 + 1*p2) >> 1; p1 = source[36]; dest[50] = (7*p2 + 1*p1) >> 3; dest[51] = (1*p2 + 7*p1) >> 3; p2 = source[37]; dest[52] = (1*p1 + 1*p2) >> 1; p1 = source[38]; dest[53] = (3*p2 + 1*p1) >> 2; dest[54] = p1; p2 = source[39]; dest[55] = (3*p1 + 5*p2) >> 3; p1 = source[40]; dest[56] = (5*p2 + 3*p1) >> 3; p2 = source[41]; dest[57] = (7*p1 + 1*p2) >> 3; dest[58] = (1*p1 + 3*p2) >> 2; p1 = source[42]; dest[59] = (1*p2 + 1*p1) >> 1; p2 = source[43]; dest[60] = (7*p1 + 1*p2) >> 3; dest[61] = (1*p1 + 7*p2) >> 3; p1 = source[44]; dest[62] = (3*p2 + 5*p1) >> 3; p2 = source[45]; dest[63] = (3*p1 + 1*p2) >> 2; source += 45; dest += 64; } if ((width += 64) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (1*source[0] + 3*source[1]) >> 2; if (--width <= 0) goto done; *dest++ = (5*source[1] + 3*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[2] + 1*source[3]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[2] + 3*source[3]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[3] + 1*source[4]) >> 1; if (--width <= 0) goto done; *dest++ = (3*source[4] + 1*source[5]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[4] + 7*source[5]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[5] + 5*source[6]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[6] + 3*source[7]) >> 3; if (--width <= 0) goto done; *dest++ = source[7]; if (--width <= 0) goto done; *dest++ = (1*source[7] + 3*source[8]) >> 2; if (--width <= 0) goto done; *dest++ = (5*source[8] + 3*source[9]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[9] + 1*source[10]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[9] + 7*source[10]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[10] + 1*source[11]) >> 1; if (--width <= 0) goto done; *dest++ = (3*source[11] + 1*source[12]) >> 2; if (--width <= 0) goto done; *dest++ = source[12]; if (--width <= 0) goto done; *dest++ = (3*source[12] + 5*source[13]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[13] + 3*source[14]) >> 3; if (--width <= 0) goto done; *dest++ = source[14]; if (--width <= 0) goto done; *dest++ = (1*source[14] + 3*source[15]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[15] + 1*source[16]) >> 1; if (--width <= 0) goto done; *dest++ = (7*source[16] + 1*source[17]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[16] + 7*source[17]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[17] + 5*source[18]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[18] + 1*source[19]) >> 2; if (--width <= 0) goto done; *dest++ = source[19]; if (--width <= 0) goto done; *dest++ = (3*source[19] + 5*source[20]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[20] + 3*source[21]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[21] + 1*source[22]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[21] + 3*source[22]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[22] + 1*source[23]) >> 1; if (--width <= 0) goto done; *dest++ = (3*source[23] + 1*source[24]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[23] + 7*source[24]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[24] + 5*source[25]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[25] + 1*source[26]) >> 2; if (--width <= 0) goto done; *dest++ = source[26]; if (--width <= 0) goto done; *dest++ = (1*source[26] + 3*source[27]) >> 2; if (--width <= 0) goto done; *dest++ = (5*source[27] + 3*source[28]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[28] + 1*source[29]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[28] + 7*source[29]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[29] + 1*source[30]) >> 1; if (--width <= 0) goto done; *dest++ = (3*source[30] + 1*source[31]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[30] + 7*source[31]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[31] + 5*source[32]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[32] + 3*source[33]) >> 3; if (--width <= 0) goto done; *dest++ = source[33]; if (--width <= 0) goto done; *dest++ = (1*source[33] + 3*source[34]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[34] + 1*source[35]) >> 1; if (--width <= 0) goto done; *dest++ = (7*source[35] + 1*source[36]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[35] + 7*source[36]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[36] + 1*source[37]) >> 1; if (--width <= 0) goto done; *dest++ = (3*source[37] + 1*source[38]) >> 2; if (--width <= 0) goto done; *dest++ = source[38]; if (--width <= 0) goto done; *dest++ = (3*source[38] + 5*source[39]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[39] + 3*source[40]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[40] + 1*source[41]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[40] + 3*source[41]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[41] + 1*source[42]) >> 1; if (--width <= 0) goto done; *dest++ = (7*source[42] + 1*source[43]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[42] + 7*source[43]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[43] + 5*source[44]) >> 3; done: xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 16 output pixels from 9 source pixels using shifts. * Useful for scaling a PAL mpeg2 dvd input source to 1280x1024 fullscreen * (720 x 576 ==> 1280 x XXX) */ static void scale_line_9_16 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 16) >= 0) { p1 = source[0]; p2 = source[1]; dest[0] = p1; dest[1] = (1*p1 + 1*p2) >> 1; p1 = source[2]; dest[2] = (7*p2 + 1*p1) >> 3; dest[3] = (3*p2 + 5*p1) >> 3; p2 = source[3]; dest[4] = (3*p1 + 1*p2) >> 2; dest[5] = (1*p1 + 3*p2) >> 2; p1 = source[4]; dest[6] = (5*p2 + 3*p1) >> 3; dest[7] = (1*p2 + 7*p1) >> 3; p2 = source[5]; dest[8] = (1*p1 + 1*p2) >> 1; p1 = source[6]; dest[9] = p2; dest[10] = (3*p2 + 5*p1) >> 3; p2 = source[7]; dest[11] = (7*p1 + 1*p2) >> 3; dest[12] = (1*p1 + 3*p2) >> 2; p1 = source[8]; dest[13] = (3*p2 + 1*p1) >> 2; dest[14] = (1*p2 + 7*p1) >> 3; p2 = source[9]; dest[15] = (5*p1 + 3*p2) >> 3; source += 9; dest += 16; } if ((width += 16) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (1*source[0] + 1*source[1]) >> 1; if (--width <= 0) goto done; *dest++ = (7*source[1] + 1*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[1] + 5*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[2] + 1*source[3]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[2] + 3*source[3]) >> 2; if (--width <= 0) goto done; *dest++ = (5*source[3] + 3*source[4]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[3] + 7*source[4]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[4] + 1*source[5]) >> 1; if (--width <= 0) goto done; *dest++ = source[5]; if (--width <= 0) goto done; *dest++ = (3*source[5] + 5*source[6]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[6] + 1*source[7]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[6] + 3*source[7]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[7] + 1*source[8]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[7] + 7*source[8]) >> 3; done: xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 12 output pixels from 11 source pixels using shifts. * Useful for scaling a PAL vcd input source to 4:3 display format. */ static void scale_line_11_12 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 12) >= 0) { p1 = source[0]; p2 = source[1]; dest[0] = p1; dest[1] = (1*p1 + 7*p2) >> 3; p1 = source[2]; dest[2] = (1*p2 + 7*p1) >> 3; p2 = source[3]; dest[3] = (1*p1 + 3*p2) >> 2; p1 = source[4]; dest[4] = (3*p2 + 5*p1) >> 3; p2 = source[5]; dest[5] = (3*p1 + 5*p2) >> 3; p1 = source[6]; dest[6] = (1*p2 + 1*p1) >> 1; p2 = source[7]; dest[7] = (5*p1 + 3*p2) >> 3; p1 = source[8]; dest[8] = (5*p2 + 3*p1) >> 3; p2 = source[9]; dest[9] = (3*p1 + 1*p2) >> 2; p1 = source[10]; dest[10] = (7*p2 + 1*p1) >> 3; p2 = source[11]; dest[11] = (7*p1 + 1*p2) >> 3; source += 11; dest += 12; } if ((width += 12) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (1*source[0] + 7*source[1]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[1] + 7*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[2] + 3*source[3]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[3] + 5*source[4]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[4] + 5*source[5]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[5] + 1*source[6]) >> 1; if (--width <= 0) goto done; *dest++ = (5*source[6] + 3*source[7]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[7] + 3*source[8]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[8] + 1*source[9]) >> 2; if (--width <= 0) goto done; *dest++ = (7*source[9] + 1*source[10]) >> 3; done: xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 24 output pixels from 11 source pixels using shifts. * Useful for scaling a PAL vcd input source to 4:3 display format * at 2*zoom. */ static void scale_line_11_24 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 24) >= 0) { p1 = source[0]; p2 = source[1]; dest[0] = p1; dest[1] = (1*p1 + 1*p2) >> 1; dest[2] = (1*p1 + 7*p2) >> 3; p1 = source[2]; dest[3] = (5*p2 + 3*p1) >> 3; dest[4] = (1*p2 + 7*p1) >> 3; p2 = source[3]; dest[5] = (3*p1 + 1*p2) >> 2; dest[6] = (1*p1 + 3*p2) >> 2; p1 = source[4]; dest[7] = (3*p2 + 1*p1) >> 2; dest[8] = (3*p2 + 5*p1) >> 3; p2 = source[5]; dest[9] = (7*p1 + 1*p2) >> 3; dest[10] = (3*p1 + 5*p2) >> 3; p1 = source[6]; dest[11] = p2; dest[12] = (1*p2 + 1*p1) >> 1; dest[13] = p1; p2 = source[7]; dest[14] = (5*p1 + 3*p2) >> 3; dest[15] = (1*p1 + 7*p2) >> 3; p1 = source[8]; dest[16] = (5*p2 + 3*p1) >> 3; dest[17] = (1*p2 + 3*p1) >> 2; p2 = source[9]; dest[18] = (3*p1 + 1*p2) >> 2; dest[19] = (1*p1 + 3*p2) >> 2; p1 = source[10]; dest[20] = (7*p2 + 1*p1) >> 3; dest[21] = (3*p2 + 5*p1) >> 3; p2 = source[11]; dest[22] = (7*p1 + 1*p2) >> 3; dest[23] = (1*p1 + 1*p2) >> 1; source += 11; dest += 24; } if ((width += 24) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (1*source[0] + 1*source[1]) >> 1; if (--width <= 0) goto done; *dest++ = (1*source[0] + 7*source[1]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[1] + 3*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[1] + 7*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[2] + 1*source[3]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[2] + 3*source[3]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[3] + 1*source[4]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[3] + 5*source[4]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[4] + 1*source[5]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[4] + 5*source[5]) >> 3; if (--width <= 0) goto done; *dest++ = source[5]; if (--width <= 0) goto done; *dest++ = (1*source[5] + 1*source[6]) >> 1; if (--width <= 0) goto done; *dest++ = source[6]; if (--width <= 0) goto done; *dest++ = (5*source[6] + 3*source[7]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[6] + 7*source[7]) >> 3; if (--width <= 0) goto done; *dest++ = (5*source[7] + 3*source[8]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[7] + 3*source[8]) >> 2; if (--width <= 0) goto done; *dest++ = (3*source[8] + 1*source[9]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[8] + 3*source[9]) >> 2; if (--width <= 0) goto done; *dest++ = (7*source[9] + 1*source[10]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[9] + 5*source[10]) >> 3; if (--width <= 0) goto done; *dest++ = (7*source[10] + 1*source[11]) >> 3; done: xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 8 output pixels from 5 source pixels using shifts. * Useful for scaling a PAL svcd input source to 4:3 display format. */ static void scale_line_5_8 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 8) >= 0) { p1 = source[0]; p2 = source[1]; dest[0] = p1; dest[1] = (3*p1 + 5*p2) >> 3; p1 = source[2]; dest[2] = (3*p2 + 1*p1) >> 2; dest[3] = (1*p2 + 7*p1) >> 3; p2 = source[3]; dest[4] = (1*p1 + 1*p2) >> 1; p1 = source[4]; dest[5] = (7*p2 + 1*p1) >> 3; dest[6] = (1*p2 + 3*p1) >> 2; p2 = source[5]; dest[7] = (5*p1 + 3*p2) >> 3; source += 5; dest += 8; } if ((width += 8) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (3*source[0] + 5*source[1]) >> 3; if (--width <= 0) goto done; *dest++ = (3*source[1] + 1*source[2]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[1] + 7*source[2]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[2] + 1*source[3]) >> 1; if (--width <= 0) goto done; *dest++ = (7*source[3] + 1*source[4]) >> 3; if (--width <= 0) goto done; *dest++ = (1*source[3] + 3*source[4]) >> 2; done: xine_profiler_stop_count(prof_scale_line); } /* * Interpolates 4 output pixels from 3 source pixels using shifts. * Useful for scaling a NTSC svcd input source to 4:3 display format. */ static void scale_line_3_4 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 4) >= 0) { p1 = source[0]; p2 = source[1]; dest[0] = p1; dest[1] = (1*p1 + 3*p2) >> 2; p1 = source[2]; dest[2] = (1*p2 + 1*p1) >> 1; p2 = source[3]; dest[3] = (3*p1 + 1*p2) >> 2; source += 3; dest += 4; } if ((width += 4) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (1*source[0] + 3*source[1]) >> 2; if (--width <= 0) goto done; *dest++ = (1*source[1] + 1*source[2]) >> 1; done: xine_profiler_stop_count(prof_scale_line); } /* Interpolate 2 output pixels from one source pixel. */ static void scale_line_1_2 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2; (void)step; xine_profiler_start_count(prof_scale_line); p1 = *source; while ((width -= 4) >= 0) { *dest++ = p1; p2 = *++source; *dest++ = (p1 + p2) >> 1; *dest++ = p2; p1 = *++source; *dest++ = (p2 + p1) >> 1; } if ((width += 4) <= 0) goto done; *dest++ = source[0]; if (--width <= 0) goto done; *dest++ = (source[0] + source[1]) >> 1; if (--width <= 0) goto done; *dest++ = source[1]; done: xine_profiler_stop_count(prof_scale_line); } /* Interpolate 4 output pixels from 5 source pixels (1280x720 -> 1024x576). */ /* * * * * * */ /* * * * * */ static void scale_line_5_4 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2, p3, p4, p5; (void)step; xine_profiler_start_count(prof_scale_line); while ((width -= 4) >= 0) { *dest++ = *source++; p1 = *source++; p2 = *source++; *dest++ = p1 + ((p2 - p1) >> 2); p3 = *source++; p4 = *source++; /* the middle pixel loses most sharpness, so do that one cubic */ p5 = (9 * (p2 + p3) - p1 - p4) >> 4; *dest++ = p5 & 0x100 ? ~(p5 >> 9) : p5; *dest++ = p4 + ((p3 - p4) >> 2); } if ((width += 4) <= 0) goto done; *dest++ = *source++; if (--width <= 0) goto done; p1 = *source++; p2 = *source++; *dest++ = p1 + ((p2 - p1) >> 2); if (--width <= 0) goto done; p1 = *source; *dest++ = (p1 + p2) >> 1; done: xine_profiler_stop_count(prof_scale_line); } /* Interpolate 3 output pixels from 2 source pixels (1280x720 -> 1920x1080). */ /* * * * */ /* * * * * */ static void scale_line_2_3 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1, p2, p3, p4, p5; (void)step; xine_profiler_start_count(prof_scale_line); p4 = p1 = *source++; p2 = *source; while ((width -= 6) >= 0) { *dest++ = p1; p3 = *source++; p5 = (5 * p1 + 12 * p2 - p3) >> 4; *dest++ = p5 & 0x100 ? ~(p5 >> 9) : p5; p4 = *source++; p5 = (12 * p2 + 5 * p3 - p1) >> 4; *dest++ = p5 & 0x100 ? ~(p5 >> 9) : p5; *dest++ = p3; p1 = *source++; p5 = (5 * p3 + 12 * p4 - p1) >> 4; *dest++ = p5 & 0x100 ? ~(p5 >> 9) : p5; p2 = *source++; p5 = (12 * p4 + 5 * p1 - p3) >> 4; *dest++ = p5 & 0x100 ? ~(p5 >> 9) : p5; } if ((width += 6) <= 0) goto done; *dest++ = p1; if (--width <= 0) goto done; *dest++ = (11 * p1 + 21 * p2) >> 5; if (--width <= 0) goto done; p3 = *source++; *dest++ = (21 * p2 + 11 * p3) >> 5; if (--width <= 0) goto done; *dest++ = p3; if (--width <= 0) goto done; p4 = *source++; *dest++ = (11 * p3 + 21 * p4) >> 5; done: xine_profiler_stop_count(prof_scale_line); } /* * Scale line with no horizontal scaling. For NTSC mpeg2 dvd input in * 4:3 output format (720x480 -> 720x540) */ static void scale_line_1_1 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { (void)step; xine_profiler_start_count(prof_scale_line); xine_fast_memcpy(dest, source, width); xine_profiler_stop_count(prof_scale_line); } static scale_line_func_t find_scale_line_func(int step) { static struct { int src_step; int dest_step; scale_line_func_t func; const char *desc; /* FIXME: consider moving this to a char[] to avoid reloc */ } scale_line[] = { { 15, 16, scale_line_15_16, "dvd 4:3(pal)" }, { 45, 64, scale_line_45_64, "dvd 16:9(pal), fullscreen(1024x768)" }, { 9, 16, scale_line_9_16, "dvd fullscreen(1280x1024)" }, { 45, 53, scale_line_45_53, "dvd 16:9(ntsc)" }, { 11, 12, scale_line_11_12, "vcd 4:3(pal)" }, { 11, 24, scale_line_11_24, "vcd 4:3(pal) 2*zoom" }, { 5, 8, scale_line_5_8, "svcd 4:3(pal)" }, { 3, 4, scale_line_3_4, "svcd 4:3(ntsc)" }, { 1, 2, scale_line_1_2, "2*zoom" }, { 1, 1, scale_line_1_1, "non-scaled" }, { 5, 4, scale_line_5_4, "hd720p, fullscreen(1024x576)" }, { 2, 3, scale_line_2_3, "hd720p, fullscreen(1920x1080)" } }; size_t i; #ifdef LOG /* to filter out multiple messages about the scale_line variant we're using */ static int reported_for_step; #endif for (i = 0; i < sizeof(scale_line)/sizeof(scale_line[0]); i++) { if (step == scale_line[i].src_step*32768/scale_line[i].dest_step) { #ifdef LOG if (step != reported_for_step) printf("yuv2rgb: using %s optimized scale_line\n", scale_line[i].desc); reported_for_step = step; #endif return scale_line[i].func; } } #ifdef LOG if (step != reported_for_step) printf("yuv2rgb: using generic scale_line with interpolation\n"); reported_for_step = step; #endif return scale_line_gen; } static void scale_line_2 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1; int p2; int dx; p1 = *source; source+=2; p2 = *source; source+=2; dx = 0; while (width) { *dest = (p1 * (32768 - dx) + p2 * dx) / 32768; dx += step; while (dx > 32768) { dx -= 32768; p1 = p2; p2 = *source; source+=2; } dest ++; width --; } } static void scale_line_4 (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step) { int p1; int p2; int dx; p1 = *source; source+=4; p2 = *source; source+=4; dx = 0; while (width) { *dest = (p1 * (32768 - dx) + p2 * dx) / 32768; dx += step; while (dx > 32768) { dx -= 32768; p1 = p2; p2 = *source; source+=4; } dest ++; width --; } } #define X_RGB(i) \ U = pu[i]; \ V = pv[i]; \ r = this->table_rV[V]; \ g = (void *) (((uint8_t *)this->table_gU[U]) + this->table_gV[V]); \ b = this->table_bU[U]; #define DST1(i) \ Y = py_1[2*i]; \ dst_1[2*i] = r[Y] + g[Y] + b[Y]; \ Y = py_1[2*i+1]; \ dst_1[2*i+1] = r[Y] + g[Y] + b[Y]; #define DST2(i) \ Y = py_2[2*i]; \ dst_2[2*i] = r[Y] + g[Y] + b[Y]; \ Y = py_2[2*i+1]; \ dst_2[2*i+1] = r[Y] + g[Y] + b[Y]; #define DST1RGB(i) \ Y = py_1[2*i]; \ dst_1[6*i] = r[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = b[Y]; \ Y = py_1[2*i+1]; \ dst_1[6*i+3] = r[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = b[Y]; #define DST2RGB(i) \ Y = py_2[2*i]; \ dst_2[6*i] = r[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = b[Y]; \ Y = py_2[2*i+1]; \ dst_2[6*i+3] = r[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = b[Y]; #define DST1BGR(i) \ Y = py_1[2*i]; \ dst_1[6*i] = b[Y]; dst_1[6*i+1] = g[Y]; dst_1[6*i+2] = r[Y]; \ Y = py_1[2*i+1]; \ dst_1[6*i+3] = b[Y]; dst_1[6*i+4] = g[Y]; dst_1[6*i+5] = r[Y]; #define DST2BGR(i) \ Y = py_2[2*i]; \ dst_2[6*i] = b[Y]; dst_2[6*i+1] = g[Y]; dst_2[6*i+2] = r[Y]; \ Y = py_2[2*i+1]; \ dst_2[6*i+3] = b[Y]; dst_2[6*i+4] = g[Y]; dst_2[6*i+5] = r[Y]; #define DST1CMAP(i) \ Y = py_1[2*i]; \ dst_1[2*i] = this->cmap[r[Y] + g[Y] + b[Y]]; \ Y = py_1[2*i+1]; \ dst_1[2*i+1] = this->cmap[r[Y] + g[Y] + b[Y]]; #define DST2CMAP(i) \ Y = py_2[2*i]; \ dst_2[2*i] = this->cmap[r[Y] + g[Y] + b[Y]]; \ Y = py_2[2*i+1]; \ dst_2[2*i+1] = this->cmap[r[Y] + g[Y] + b[Y]]; static void yuv2rgb_c_32 (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _py, const uint8_t *restrict _pu, const uint8_t *restrict _pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * py_2, * pu, * pv; const uint32_t * r, * g, * b; uint32_t * dst_1, * dst_2; int width, height, dst_height; int dy; if (this->do_scale) { scale_line_func_t scale_line = this->scale_line; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); dy = 0; dst_height = yuv2rgb_next_slice (this, &_dst); for (height = 0;; ) { dst_1 = (uint32_t*)_dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1(0); X_RGB(1); DST1(1); X_RGB(2); DST1(2); X_RGB(3); DST1(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*4); dy += this->step_dy; _dst += this->rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; _py += this->y_stride; scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { _pu += this->uv_stride; _pv += this->uv_stride; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768); } } else { height = yuv2rgb_next_slice (this, &_dst) >> 1; do { dst_1 = (uint32_t*)_dst; dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride ); py_1 = _py; py_2 = _py + this->y_stride; pu = _pu; pv = _pv; width = this->source_width >> 3; do { X_RGB(0); DST1(0); DST2(0); X_RGB(1); DST2(1); DST1(1); X_RGB(2); DST1(2); DST2(2); X_RGB(3); DST2(3); DST1(3); pu += 4; pv += 4; py_1 += 8; py_2 += 8; dst_1 += 8; dst_2 += 8; } while (--width); _dst += 2 * this->rgb_stride; _py += 2 * this->y_stride; _pu += this->uv_stride; _pv += this->uv_stride; } while (--height); } } /* This is very near from the yuv2rgb_c_32 code */ static void yuv2rgb_c_24_rgb (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _py, const uint8_t *restrict _pu, const uint8_t *restrict _pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * py_2, * pu, * pv; const uint8_t * r, * g, * b; uint8_t * dst_1, * dst_2; int width, height, dst_height; int dy; if (this->do_scale) { scale_line_func_t scale_line = this->scale_line; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); dy = 0; dst_height = yuv2rgb_next_slice (this, &_dst); for (height = 0;; ) { dst_1 = _dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1RGB(0); X_RGB(1); DST1RGB(1); X_RGB(2); DST1RGB(2); X_RGB(3); DST1RGB(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 24; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (_dst, _dst-this->rgb_stride, this->dest_width*3); dy += this->step_dy; _dst += this->rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; _py += this->y_stride; scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { _pu += this->uv_stride; _pv += this->uv_stride; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while (dy>=32768); } } else { height = yuv2rgb_next_slice (this, &_dst) >> 1; do { dst_1 = _dst; dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride ); py_1 = _py; py_2 = _py + this->y_stride; pu = _pu; pv = _pv; width = this->source_width >> 3; do { X_RGB(0); DST1RGB(0); DST2RGB(0); X_RGB(1); DST2RGB(1); DST1RGB(1); X_RGB(2); DST1RGB(2); DST2RGB(2); X_RGB(3); DST2RGB(3); DST1RGB(3); pu += 4; pv += 4; py_1 += 8; py_2 += 8; dst_1 += 24; dst_2 += 24; } while (--width); _dst += 2 * this->rgb_stride; _py += 2 * this->y_stride; _pu += this->uv_stride; _pv += this->uv_stride; } while (--height); } } /* only trivial mods from yuv2rgb_c_24_rgb */ static void yuv2rgb_c_24_bgr (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _py, const uint8_t *restrict _pu, const uint8_t *restrict _pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * py_2, * pu, * pv; const uint8_t * r, * g, * b; uint8_t * dst_1, * dst_2; int width, height, dst_height; int dy; if (this->do_scale) { scale_line_func_t scale_line = this->scale_line; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); dy = 0; dst_height = yuv2rgb_next_slice (this, &_dst); for (height = 0;; ) { dst_1 = _dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1BGR(0); X_RGB(1); DST1BGR(1); X_RGB(2); DST1BGR(2); X_RGB(3); DST1BGR(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 24; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (_dst, _dst-this->rgb_stride, this->dest_width*3); dy += this->step_dy; _dst += this->rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; _py += this->y_stride; scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { _pu += this->uv_stride; _pv += this->uv_stride; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } else { height = yuv2rgb_next_slice (this, &_dst) >> 1; do { dst_1 = _dst; dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride ); py_1 = _py; py_2 = _py + this->y_stride; pu = _pu; pv = _pv; width = this->source_width >> 3; do { X_RGB(0); DST1BGR(0); DST2BGR(0); X_RGB(1); DST2BGR(1); DST1BGR(1); X_RGB(2); DST1BGR(2); DST2BGR(2); X_RGB(3); DST2BGR(3); DST1BGR(3); pu += 4; pv += 4; py_1 += 8; py_2 += 8; dst_1 += 24; dst_2 += 24; } while (--width); _dst += 2 * this->rgb_stride; _py += 2 * this->y_stride; _pu += this->uv_stride; _pv += this->uv_stride; } while (--height); } } /* This is exactly the same code as yuv2rgb_c_32 except for the types of */ /* r, g, b, dst_1, dst_2 */ static void yuv2rgb_c_16 (yuv2rgb_t *this_gen, uint8_t * _dst, const uint8_t *restrict _py, const uint8_t *restrict _pu, const uint8_t *restrict _pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * py_2, * pu, * pv; const uint16_t * r, * g, * b; uint16_t * dst_1, * dst_2; int width, height, dst_height; int dy; if (this->do_scale) { scale_line_func_t scale_line = this->scale_line; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); dy = 0; dst_height = yuv2rgb_next_slice (this, &_dst); for (height = 0;; ) { dst_1 = (uint16_t*)_dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1(0); X_RGB(1); DST1(1); X_RGB(2); DST1(2); X_RGB(3); DST1(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*2); dy += this->step_dy; _dst += this->rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; _py += this->y_stride; scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { _pu += this->uv_stride; _pv += this->uv_stride; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768); } } else { height = yuv2rgb_next_slice (this, &_dst) >> 1; do { dst_1 = (uint16_t*)_dst; dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride ); py_1 = _py; py_2 = _py + this->y_stride; pu = _pu; pv = _pv; width = this->source_width >> 3; do { X_RGB(0); DST1(0); DST2(0); X_RGB(1); DST2(1); DST1(1); X_RGB(2); DST1(2); DST2(2); X_RGB(3); DST2(3); DST1(3); pu += 4; pv += 4; py_1 += 8; py_2 += 8; dst_1 += 8; dst_2 += 8; } while (--width); _dst += 2 * this->rgb_stride; _py += 2 * this->y_stride; _pu += this->uv_stride; _pv += this->uv_stride; } while (--height); } } /* This is exactly the same code as yuv2rgb_c_32 except for the types of */ /* r, g, b, dst_1, dst_2 */ static void yuv2rgb_c_8 (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _py, const uint8_t *restrict _pu, const uint8_t *restrict _pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * py_2, * pu, * pv; const uint8_t * r, * g, * b; uint8_t * dst_1, * dst_2; int width, height, dst_height; int dy; if (this->do_scale) { scale_line_func_t scale_line = this->scale_line; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); dy = 0; dst_height = yuv2rgb_next_slice (this, &_dst); for (height = 0;; ) { dst_1 = (uint8_t*)_dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1(0); X_RGB(1); DST1(1); X_RGB(2); DST1(2); X_RGB(3); DST1(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width); dy += this->step_dy; _dst += this->rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; _py += this->y_stride; scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { _pu += this->uv_stride; _pv += this->uv_stride; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } else { height = yuv2rgb_next_slice (this, &_dst) >> 1; do { dst_1 = (uint8_t*)_dst; dst_2 = (void*)( (uint8_t *)_dst + this->rgb_stride ); py_1 = _py; py_2 = _py + this->y_stride; pu = _pu; pv = _pv; width = this->source_width >> 3; do { X_RGB(0); DST1(0); DST2(0); X_RGB(1); DST2(1); DST1(1); X_RGB(2); DST1(2); DST2(2); X_RGB(3); DST2(3); DST1(3); pu += 4; pv += 4; py_1 += 8; py_2 += 8; dst_1 += 8; dst_2 += 8; } while (--width); _dst += 2 * this->rgb_stride; _py += 2 * this->y_stride; _pu += this->uv_stride; _pv += this->uv_stride; } while (--height); } } /* now for something different: 256 grayscale mode */ static void yuv2rgb_c_gray (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _py, const uint8_t *restrict _pu, const uint8_t *restrict _pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int height, dst_height; int dy; (void)_pu; (void)_pv; if (this->do_scale) { scale_line_func_t scale_line = this->scale_line; dy = 0; dst_height = yuv2rgb_next_slice (this, &_dst); for (;;) { scale_line (_py, _dst, this->dest_width, this->step_dx); dy += this->step_dy; _dst += this->rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width); dy += this->step_dy; _dst += this->rgb_stride; } if (dst_height <= 0) break; _py += this->y_stride*(dy>>15); dy &= 32767; /* dy -= 32768; _py += this->y_stride; */ } } else { for (height = yuv2rgb_next_slice (this, &_dst); --height >= 0; ) { xine_fast_memcpy(_dst, _py, this->dest_width); _dst += this->rgb_stride; _py += this->y_stride; } } } /* now for something different: 256 color mode */ static void yuv2rgb_c_palette (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _py, const uint8_t *restrict _pu, const uint8_t *restrict _pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * py_2, * pu, * pv; const uint16_t * r, * g, * b; uint8_t * dst_1, * dst_2; int width, height, dst_height; int dy; if (this->do_scale) { scale_line_func_t scale_line = this->scale_line; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); dy = 0; dst_height = yuv2rgb_next_slice (this, &_dst); for (height = 0;; ) { dst_1 = _dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1CMAP(0); X_RGB(1); DST1CMAP(1); X_RGB(2); DST1CMAP(2); X_RGB(3); DST1CMAP(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--dst_height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width); dy += this->step_dy; _dst += this->rgb_stride; } if (dst_height <= 0) break; do { dy -= 32768; _py += this->y_stride; scale_line (_py, this->y_buffer, this->dest_width, this->step_dx); if (height & 1) { _pu += this->uv_stride; _pv += this->uv_stride; scale_line (_pu, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line (_pv, this->v_buffer, this->dest_width >> 1, this->step_dx); } height++; } while( dy>=32768 ); } } else { height = yuv2rgb_next_slice (this, &_dst) >> 1; do { dst_1 = _dst; dst_2 = _dst + this->rgb_stride; py_1 = _py; py_2 = _py + this->y_stride; pu = _pu; pv = _pv; width = this->source_width >> 3; do { X_RGB(0); DST1CMAP(0); DST2CMAP(0); X_RGB(1); DST2CMAP(1); DST1CMAP(1); X_RGB(2); DST1CMAP(2); DST2CMAP(2); X_RGB(3); DST2CMAP(3); DST1CMAP(3); pu += 4; pv += 4; py_1 += 8; py_2 += 8; dst_1 += 8; dst_2 += 8; } while (--width); _dst += 2 * this->rgb_stride; _py += 2 * this->y_stride; _pu += this->uv_stride; _pv += this->uv_stride; } while (--height); } } static int div_round (int dividend, int divisor) { if (dividend > 0) return (dividend + (divisor>>1)) / divisor; else return -((-dividend + (divisor>>1)) / divisor); } static int _yuv2rgb_set_csc_levels (yuv2rgb_factory_t *this_gen, int brightness, int contrast, int saturation, int colormatrix) { yuv2rgb_factory_impl_t *this = (yuv2rgb_factory_impl_t*)this_gen; int i; uint8_t table_Y[1024]; uint32_t * table_32 = 0; uint16_t * table_16 = 0; uint8_t * table_8 = 0; int entry_size = 0; void *table_r = 0, *table_g = 0, *table_b = 0; int shift_r = 0, shift_g = 0, shift_b = 0; int yoffset = -16; int ygain = (1 << 16) * 255 / 219; int cm = (colormatrix >> 1) & 7; int crv = Inverse_Table_6_9[cm][0]; int cbu = Inverse_Table_6_9[cm][1]; int cgu = -Inverse_Table_6_9[cm][2]; int cgv = -Inverse_Table_6_9[cm][3]; int mode = this->mode; int swapped = this->swapped; /* nasty workaround for xine-ui not sending exact defaults */ if (brightness == -1) brightness = 0; if (contrast == 127) contrast = 128; if (saturation == 127) saturation = 128; /* full range mode */ if (colormatrix & 1) { yoffset = 0; ygain = (1 << 16); crv = (crv * 112 + 63) / 127; cbu = (cbu * 112 + 63) / 127; cgu = (cgu * 112 + 63) / 127; cgv = (cgv * 112 + 63) / 127; } yoffset += brightness; for (i = 0; i < 1024; i++) { int j; j = (ygain * (i - 384 + yoffset) + 32768) >> 16; j = (j < 0) ? 0 : ((j > 255) ? 255 : j); table_Y[i] = j; } switch (mode) { case MODE_32_RGB: case MODE_32_BGR: if (this->table_base == NULL) { this->table_base = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint32_t)); if (!this->table_base) return -1; } table_32 = this->table_base; entry_size = sizeof (uint32_t); table_r = table_32 + 197; table_b = table_32 + 197 + 685; table_g = table_32 + 197 + 2*682; if (swapped) { switch (mode) { case MODE_32_RGB: shift_r = 8; shift_g = 16; shift_b = 24; break; case MODE_32_BGR: shift_r = 24; shift_g = 16; shift_b = 8; break; } } else { switch (mode) { case MODE_32_RGB: shift_r = 16; shift_g = 8; shift_b = 0; break; case MODE_32_BGR: shift_r = 0; shift_g = 8; shift_b = 16; break; } } for (i = -197; i < 256+197; i++) ((uint32_t *) table_r)[i] = table_Y[i+384] << shift_r; for (i = -132; i < 256+132; i++) ((uint32_t *) table_g)[i] = table_Y[i+384] << shift_g; for (i = -232; i < 256+232; i++) ((uint32_t *) table_b)[i] = table_Y[i+384] << shift_b; break; case MODE_24_RGB: case MODE_24_BGR: if (this->table_base == NULL) { this->table_base = malloc ((256 + 2*232) * sizeof (uint8_t)); if (!this->table_base) return -1; } table_8 = this->table_base; entry_size = sizeof (uint8_t); table_r = table_g = table_b = table_8 + 232; for (i = -232; i < 256+232; i++) ((uint8_t * )table_b)[i] = table_Y[i+384]; break; case MODE_15_BGR: case MODE_16_BGR: case MODE_15_RGB: case MODE_16_RGB: if (this->table_base == NULL) { this->table_base = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint16_t)); if (!this->table_base) return -1; } table_16 = this->table_base; entry_size = sizeof (uint16_t); table_r = table_16 + 197; table_b = table_16 + 197 + 685; table_g = table_16 + 197 + 2*682; if (swapped) { switch (mode) { case MODE_15_BGR: shift_r = 8; shift_g = 5; shift_b = 2; break; case MODE_16_BGR: shift_r = 8; shift_g = 5; shift_b = 3; break; case MODE_15_RGB: shift_r = 2; shift_g = 5; shift_b = 8; break; case MODE_16_RGB: shift_r = 3; shift_g = 5; shift_b = 8; break; } } else { switch (mode) { case MODE_15_BGR: shift_r = 0; shift_g = 5; shift_b = 10; break; case MODE_16_BGR: shift_r = 0; shift_g = 5; shift_b = 11; break; case MODE_15_RGB: shift_r = 10; shift_g = 5; shift_b = 0; break; case MODE_16_RGB: shift_r = 11; shift_g = 5; shift_b = 0; break; } } for (i = -197; i < 256+197; i++) ((uint16_t *)table_r)[i] = (table_Y[i+384] >> 3) << shift_r; for (i = -132; i < 256+132; i++) { int j = table_Y[i+384] >> (((mode==MODE_16_RGB) || (mode==MODE_16_BGR)) ? 2 : 3); if (swapped) ((uint16_t *)table_g)[i] = (j&7) << 13 | (j>>3); else ((uint16_t *)table_g)[i] = j << 5; } for (i = -232; i < 256+232; i++) ((uint16_t *)table_b)[i] = (table_Y[i+384] >> 3) << shift_b; break; case MODE_8_RGB: case MODE_8_BGR: if (this->table_base == NULL) { this->table_base = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint8_t)); if (!this->table_base) return -1; } table_8 = this->table_base; entry_size = sizeof (uint8_t); table_r = table_8 + 197; table_b = table_8 + 197 + 685; table_g = table_8 + 197 + 2*682; switch (mode) { case MODE_8_RGB: shift_r = 5; shift_g = 2; shift_b = 0; break; case MODE_8_BGR: shift_r = 0; shift_g = 3; shift_b = 6; break; } for (i = -197; i < 256+197; i++) ((uint8_t *) table_r)[i] = (table_Y[i+384] >> 5) << shift_r; for (i = -132; i < 256+132; i++) ((uint8_t *) table_g)[i] = (table_Y[i+384] >> 5) << shift_g; for (i = -232; i < 256+232; i++) ((uint8_t *) table_b)[i] = (table_Y[i+384] >> 6) << shift_b; break; case MODE_8_GRAY: return 0; case MODE_PALETTE: if (this->table_base == NULL) { this->table_base = malloc ((197 + 2*682 + 256 + 132) * sizeof (uint16_t)); if (!this->table_base) return -1; } table_16 = this->table_base; entry_size = sizeof (uint16_t); table_r = table_16 + 197; table_b = table_16 + 197 + 685; table_g = table_16 + 197 + 2*682; shift_r = 10; shift_g = 5; shift_b = 0; for (i = -197; i < 256+197; i++) ((uint16_t *)table_r)[i] = (table_Y[i+384] >> 3) << 10; for (i = -132; i < 256+132; i++) ((uint16_t *)table_g)[i] = (table_Y[i+384] >> 3) << 5; for (i = -232; i < 256+232; i++) ((uint16_t *)table_b)[i] = (table_Y[i+384] >> 3) << 0; break; default: lprintf ("mode %d not supported by yuv2rgb\n", mode); return -1; } for (i = 0; i < 256; i++) { this->table_rV[i] = (((uint8_t *) table_r) + entry_size * div_round (crv * (i-128), ygain)); this->table_gU[i] = (((uint8_t *) table_g) + entry_size * div_round (cgu * (i-128), ygain)); this->table_gV[i] = entry_size * div_round (cgv * (i-128), ygain); this->table_bU[i] = (((uint8_t *)table_b) + entry_size * div_round (cbu * (i-128), ygain)); } #if defined(ARCH_X86) mmx_yuv2rgb_set_csc_levels (this_gen, brightness, contrast, saturation, colormatrix); #endif return 0; } static void yuv2rgb_set_csc_levels (yuv2rgb_factory_t *this_gen, int brightness, int contrast, int saturation, int colormatrix) { /* ignore error code (errors were checked in init) */ _yuv2rgb_set_csc_levels (this_gen, brightness, contrast, saturation, colormatrix); } static uint32_t yuv2rgb_single_pixel_32 (yuv2rgb_t *this_gen, uint8_t y, uint8_t u, uint8_t v) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; const uint32_t * r, * g, * b; r = this->table_rV[v]; g = (void *) (((uint8_t *)this->table_gU[u]) + this->table_gV[v]); b = this->table_bU[u]; return r[y] + g[y] + b[y]; } static uint32_t yuv2rgb_single_pixel_24_rgb (yuv2rgb_t *this_gen, uint8_t y, uint8_t u, uint8_t v) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; const uint8_t * r, * g, * b; r = this->table_rV[v]; g = (void *) (((uint8_t *)this->table_gU[u]) + this->table_gV[v]); b = this->table_bU[u]; return (uint32_t) r[y] + ((uint32_t) g[y] << 8) + ((uint32_t) b[y] << 16); } static uint32_t yuv2rgb_single_pixel_24_bgr (yuv2rgb_t *this_gen, uint8_t y, uint8_t u, uint8_t v) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; const uint8_t * r, * g, * b; r = this->table_rV[v]; g = (void *) (((uint8_t *)this->table_gU[u]) + this->table_gV[v]); b = this->table_bU[u]; return (uint32_t) b[y] + ((uint32_t) g[y] << 8) + ((uint32_t) r[y] << 16); } static uint32_t yuv2rgb_single_pixel_16 (yuv2rgb_t *this_gen, uint8_t y, uint8_t u, uint8_t v) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; const uint16_t * r, * g, * b; r = this->table_rV[v]; g = (void *) (((uint8_t *)this->table_gU[u]) + this->table_gV[v]); b = this->table_bU[u]; return r[y] + g[y] + b[y]; } static uint32_t yuv2rgb_single_pixel_8 (yuv2rgb_t *this_gen, uint8_t y, uint8_t u, uint8_t v) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; const uint8_t * r, * g, * b; r = this->table_rV[v]; g = (void *) (((uint8_t *)this->table_gU[u]) + this->table_gV[v]); b = this->table_bU[u]; return r[y] + g[y] + b[y]; } static uint32_t yuv2rgb_single_pixel_gray (yuv2rgb_t *this_gen, uint8_t y, uint8_t u, uint8_t v) { (void)this_gen; (void)u; (void)v; return y; } static uint32_t yuv2rgb_single_pixel_palette (yuv2rgb_t *this_gen, uint8_t y, uint8_t u, uint8_t v) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; const uint16_t * r, * g, * b; r = this->table_rV[v]; g = (void *) (((uint8_t *)this->table_gU[u]) + this->table_gV[v]); b = this->table_bU[u]; return this->cmap[r[y] + g[y] + b[y]]; } static int yuv2rgb_c_init (yuv2rgb_factory_impl_t *this) { switch (this->mode) { case MODE_32_RGB: case MODE_32_BGR: this->yuv2rgb_fun = yuv2rgb_c_32; break; case MODE_24_RGB: case MODE_24_BGR: this->yuv2rgb_fun = (this->mode==MODE_24_RGB && !this->swapped) || (this->mode==MODE_24_BGR && this->swapped) ? yuv2rgb_c_24_rgb : yuv2rgb_c_24_bgr; break; case MODE_15_BGR: case MODE_16_BGR: case MODE_15_RGB: case MODE_16_RGB: this->yuv2rgb_fun = yuv2rgb_c_16; break; case MODE_8_RGB: case MODE_8_BGR: this->yuv2rgb_fun = yuv2rgb_c_8; break; case MODE_8_GRAY: this->yuv2rgb_fun = yuv2rgb_c_gray; break; case MODE_PALETTE: this->yuv2rgb_fun = yuv2rgb_c_palette; break; default: lprintf ("mode %d not supported by yuv2rgb\n", this->mode); return -1; } return 0; } static int yuv2rgb_single_pixel_init (yuv2rgb_factory_impl_t *this) { switch (this->mode) { case MODE_32_RGB: case MODE_32_BGR: this->yuv2rgb_single_pixel_fun = yuv2rgb_single_pixel_32; break; case MODE_24_RGB: case MODE_24_BGR: this->yuv2rgb_single_pixel_fun = (this->mode==MODE_24_RGB && !this->swapped) || (this->mode==MODE_24_BGR && this->swapped) ? yuv2rgb_single_pixel_24_rgb : yuv2rgb_single_pixel_24_bgr; break; case MODE_15_BGR: case MODE_16_BGR: case MODE_15_RGB: case MODE_16_RGB: this->yuv2rgb_single_pixel_fun = yuv2rgb_single_pixel_16; break; case MODE_8_RGB: case MODE_8_BGR: this->yuv2rgb_single_pixel_fun = yuv2rgb_single_pixel_8; break; case MODE_8_GRAY: this->yuv2rgb_single_pixel_fun = yuv2rgb_single_pixel_gray; break; case MODE_PALETTE: this->yuv2rgb_single_pixel_fun = yuv2rgb_single_pixel_palette; break; default: lprintf ("mode %d not supported by yuv2rgb\n", this->mode); return -1; } return 0; } /* * yuy2 stuff */ static void yuy22rgb_c_32 (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _p) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * pu, * pv; const uint32_t * r, * g, * b; uint32_t * dst_1; int width, height; int dy; /* FIXME: implement unscaled version */ scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); dy = 0; height = yuv2rgb_next_slice (this, &_dst); for (;;) { dst_1 = (uint32_t*)_dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1(0); X_RGB(1); DST1(1); X_RGB(2); DST1(2); X_RGB(3); DST1(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*4); dy += this->step_dy; _dst += this->rgb_stride; } if (height <= 0) break; _p += this->y_stride*(dy>>15); dy &= 32767; /* dy -= 32768; _p += this->y_stride*2; */ scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); } } static void yuy22rgb_c_24_rgb (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _p) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * pu, * pv; const uint8_t * r, * g, * b; uint8_t * dst_1; int width, height; int dy; /* FIXME: implement unscaled version */ scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); dy = 0; height = yuv2rgb_next_slice (this, &_dst); for (;;) { dst_1 = _dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1RGB(0); X_RGB(1); DST1RGB(1); X_RGB(2); DST1RGB(2); X_RGB(3); DST1RGB(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 24; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*3); dy += this->step_dy; _dst += this->rgb_stride; } if (height <= 0) break; _p += this->y_stride*(dy>>15); dy &= 32767; /* dy -= 32768; _p += this->y_stride*2; */ scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); } } static void yuy22rgb_c_24_bgr (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _p) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * pu, * pv; const uint8_t * r, * g, * b; uint8_t * dst_1; int width, height; int dy; /* FIXME: implement unscaled version */ scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); dy = 0; height = yuv2rgb_next_slice (this, &_dst); for (;;) { dst_1 = _dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1BGR(0); X_RGB(1); DST1BGR(1); X_RGB(2); DST1BGR(2); X_RGB(3); DST1BGR(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 24; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*3); dy += this->step_dy; _dst += this->rgb_stride; } if (height <= 0) break; _p += this->y_stride*(dy>>15); dy &= 32767; scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); } } static void yuy22rgb_c_16 (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _p) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * pu, * pv; const uint16_t * r, * g, * b; uint16_t * dst_1; int width, height; int dy; /* FIXME: implement unscaled version */ scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); dy = 0; height = yuv2rgb_next_slice (this, &_dst); for (;;) { dst_1 = (uint16_t*)_dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1(0); X_RGB(1); DST1(1); X_RGB(2); DST1(2); X_RGB(3); DST1(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width*2); dy += this->step_dy; _dst += this->rgb_stride; } if (height <= 0) break; _p += this->y_stride*(dy>>15); dy &= 32767; scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); } } static void yuy22rgb_c_8 (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _p) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * pu, * pv; const uint8_t * r, * g, * b; uint8_t * dst_1; int width, height; int dy; /* FIXME: implement unscaled version */ scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); dy = 0; height = yuv2rgb_next_slice (this, &_dst); for (;;) { dst_1 = _dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1(0); X_RGB(1); DST1(1); X_RGB(2); DST1(2); X_RGB(3); DST1(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width); dy += this->step_dy; _dst += this->rgb_stride; } if (height <= 0) break; _p += this->y_stride*(dy>>15); dy &= 32767; scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); } } static void yuy22rgb_c_gray (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _p) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int width, height; int dy; uint8_t * dst; const uint8_t * y; if (this->do_scale) { dy = 0; height = yuv2rgb_next_slice (this, &_dst); for (;;) { scale_line_2 (_p, _dst, this->dest_width, this->step_dx); dy += this->step_dy; _dst += this->rgb_stride; while (--height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width); dy += this->step_dy; _dst += this->rgb_stride; } if (height <= 0) break; _p += this->y_stride*(dy>>15); dy &= 32767; } } else { for (height = yuv2rgb_next_slice (this, &_dst); --height >= 0; ) { dst = _dst; y = _p; for (width = this->source_width; --width >= 0; ) { *dst++ = *y; y += 2; } _dst += this->rgb_stride; _p += this->y_stride; } } } static void yuy22rgb_c_palette (yuv2rgb_t *this_gen, uint8_t *restrict _dst, const uint8_t *restrict _p) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t*)this_gen; int U, V, Y; const uint8_t * py_1, * pu, * pv; const uint16_t * r, * g, * b; uint8_t * dst_1; int width, height; int dy; scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); dy = 0; height = yuv2rgb_next_slice (this, &_dst); for (;;) { dst_1 = _dst; py_1 = this->y_buffer; pu = this->u_buffer; pv = this->v_buffer; width = this->dest_width >> 3; do { X_RGB(0); DST1CMAP(0); X_RGB(1); DST1CMAP(1); X_RGB(2); DST1CMAP(2); X_RGB(3); DST1CMAP(3); pu += 4; pv += 4; py_1 += 8; dst_1 += 8; } while (--width); dy += this->step_dy; _dst += this->rgb_stride; while (--height > 0 && dy < 32768) { xine_fast_memcpy (_dst, (uint8_t*)_dst-this->rgb_stride, this->dest_width); dy += this->step_dy; _dst += this->rgb_stride; } if (height <= 0) break; _p += this->y_stride*(dy>>15); dy &= 32767; scale_line_4 (_p+1, this->u_buffer, this->dest_width >> 1, this->step_dx); scale_line_4 (_p+3, this->v_buffer, this->dest_width >> 1, this->step_dx); scale_line_2 (_p, this->y_buffer, this->dest_width, this->step_dx); } } static int yuy22rgb_c_init (yuv2rgb_factory_impl_t *this) { switch (this->mode) { case MODE_32_RGB: case MODE_32_BGR: this->yuy22rgb_fun = yuy22rgb_c_32; break; case MODE_24_RGB: case MODE_24_BGR: this->yuy22rgb_fun = (this->mode==MODE_24_RGB && !this->swapped) || (this->mode==MODE_24_BGR && this->swapped) ? yuy22rgb_c_24_rgb : yuy22rgb_c_24_bgr; break; case MODE_15_BGR: case MODE_16_BGR: case MODE_15_RGB: case MODE_16_RGB: this->yuy22rgb_fun = yuy22rgb_c_16; break; case MODE_8_RGB: case MODE_8_BGR: this->yuy22rgb_fun = yuy22rgb_c_8; break; case MODE_8_GRAY: this->yuy22rgb_fun = yuy22rgb_c_gray; break; case MODE_PALETTE: this->yuy22rgb_fun = yuy22rgb_c_palette; break; default: lprintf ("mode %d not supported for yuy2\n", this->mode); return -1; } return 0; } static yuv2rgb_t *yuv2rgb_create_converter (yuv2rgb_factory_t *this_gen) { yuv2rgb_factory_impl_t *factory = (yuv2rgb_factory_impl_t*)this_gen; yuv2rgb_impl_t *this; yuv2rgb_t *intf; this = calloc (1, sizeof (*this)); if (!this) return NULL; intf = &this->intf; intf->configure = yuv2rgb_configure; intf->next_slice = yuv2rgb_next_slice_intf; intf->dispose = yuv2rgb_dispose; intf->yuv2rgb_fun = factory->yuv2rgb_fun; intf->yuy22rgb_fun = factory->yuy22rgb_fun; intf->yuv2rgb_single_pixel_fun = factory->yuv2rgb_single_pixel_fun; this->swapped = factory->swapped; this->cmap = factory->cmap; this->y_buffer = NULL; this->u_buffer = NULL; this->v_buffer = NULL; #ifdef HAVE_MLIB this->mlib_buffer = NULL; this->mlib_resize_buffer = NULL; this->mlib_filter_type = MLIB_BILINEAR; #endif this->table_rV = factory->table_rV; this->table_gU = factory->table_gU; this->table_gV = factory->table_gV; this->table_bU = factory->table_bU; this->table_mmx = factory->table_mmx; return intf; } /* * factory functions */ static void yuv2rgb_factory_dispose (yuv2rgb_factory_t *this_gen) { yuv2rgb_factory_impl_t *this = (yuv2rgb_factory_impl_t*)this_gen; _x_freep (&this->table_base); xine_freep_aligned(&this->table_mmx); free (this); } yuv2rgb_factory_t* yuv2rgb_factory_init (int mode, int swapped, const uint8_t *cmap) { yuv2rgb_factory_impl_t *this; yuv2rgb_factory_t *intf; #if defined(ARCH_X86) || defined(HAVE_MLIB) uint32_t mm = xine_mm_accel(); #endif this = malloc (sizeof (*this)); if (!this) return NULL; intf = &this->intf; intf->create_converter = yuv2rgb_create_converter; intf->set_csc_levels = yuv2rgb_set_csc_levels; intf->dispose = yuv2rgb_factory_dispose; this->mode = mode; this->swapped = swapped; this->cmap = cmap; this->table_base = NULL; this->table_mmx = NULL; if (_yuv2rgb_set_csc_levels (intf, 0, 128, 128, CM_DEFAULT) < 0) { goto failed; } /* * auto-probe for the best yuv2rgb function */ this->yuv2rgb_fun = NULL; #if defined(ARCH_X86) if ((this->yuv2rgb_fun == NULL) && (mm & MM_ACCEL_X86_MMXEXT)) { yuv2rgb_init_mmxext (this); #ifdef LOG if (this->yuv2rgb_fun != NULL) printf ("yuv2rgb: using MMXEXT for colour space transform\n"); #endif } if ((this->yuv2rgb_fun == NULL) && (mm & MM_ACCEL_X86_MMX)) { yuv2rgb_init_mmx (this); #ifdef LOG if (this->yuv2rgb_fun != NULL) printf ("yuv2rgb: using MMX for colour space transform\n"); #endif } #endif #ifdef HAVE_MLIB if ((this->yuv2rgb_fun == NULL) && (mm & MM_ACCEL_MLIB)) { yuv2rgb_init_mlib (this); #ifdef LOG if (this->yuv2rgb_fun != NULL) printf ("yuv2rgb: using medialib for colour space transform\n"); #endif } #endif if (this->yuv2rgb_fun == NULL) { lprintf ("no accelerated colour space conversion found\n"); if (yuv2rgb_c_init (this) < 0) { goto failed; } } /* * auto-probe for the best yuy22rgb function */ /* FIXME: implement mmx/mlib functions */ if (yuy22rgb_c_init (this) < 0) { goto failed; } /* * set up single pixel function */ if (yuv2rgb_single_pixel_init (this) < 0) { goto failed; } return intf; failed: yuv2rgb_factory_dispose(&this->intf); return NULL; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/Makefile.am�������������������������������������������������������������0000644�0001750�0001750�00000002057�14647725152�015614� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(X_CFLAGS) $(VISIBILITY_FLAG) AM_CPPFLAGS += -DXINE_LIBRARY_COMPILE EXTRA_DIST = ppcasm_string.S ppc_asm.tmpl noinst_HEADERS = ppcasm_string.h mangle.h xine_mmx.h yuv2rgb.h yuv2rgb_private.h noinst_LTLIBRARIES = libxineutils.la if ARCH_PPC if !HOST_OS_DARWIN pppc_files = ppcasm_string.S endif endif noinst_LTLIBRARIES += libyuv2rgb.la libyuv2rgb_la_SOURCES = yuv2rgb.c yuv2rgb_mmx.c yuv2rgb_mlib.c libyuv2rgb_la_CFLAGS = $(AM_CFLAGS) $(MLIB_CFLAGS) libyuv2rgb_la_LIBADD = $(MLIB_LIBS) YUV_LIB = libyuv2rgb.la libxineutils_la_SOURCES = $(pppc_files) \ array.c \ cpu_accel.c \ color.c \ copy.c \ list.c \ memcpy.c \ mfrag.c \ monitor.c \ pool.c \ ring_buffer.c \ sorted_array.c \ stree.c \ utils.c \ xine_buffer.c \ xine_check.c \ xine_mutex.c \ xmllexer.c \ xmlparser.c libxineutils_la_LIBADD = $(DYNAMIC_LD_LIBS) $(YUV_LIB) if !WIN32 noinst_PROGRAMS = xmltest xmltest_SOURCES = xmllexer.c xmlparser.c xmltest_CFLAGS = -DLOG -DXINE_XML_PARSER_TEST $(AM_CFLAGS) endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/color.c�����������������������������������������������������������������0000644�0001750�0001750�00000251757�14647725152�015057� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Color Conversion Utility Functions * * Overview: xine's video output modules only accept YUV images from * video decoder modules. A video decoder can either send a planar (YV12) * image or a packed (YUY2) image to a video output module. However, many * older video codecs are RGB-based. Either each pixel is an index * to an RGB value in a palette table, or each pixel is encoded with * red, green, and blue values. In the latter case, typically either * 15, 16, 24, or 32 bits are used to represent a single pixel. * The facilities in this file are designed to ease the pain of converting * RGB -> YUV. * * If you want to use these facilities in your decoder, include the * xineutils.h header file. Then declare a yuv_planes_t structure. This * structure represents 3 non-subsampled YUV planes. "Non-subsampled" * means that there is a Y, U, and V sample for each pixel in the RGB * image, whereas YUV formats are usually subsampled so that the U and * V samples correspond to more than 1 pixel in the output image. When * you need to convert RGB values to Y, U, and V, values, use the * COMPUTE_Y(r, g, b), COMPUTE_U(r, g, b), COMPUTE_V(r, g, b) macros found * in xineutils.h * * The yuv_planes_t structure has 2 other fields: row_width and row_count * which are equivalent to the frame width and height, respectively. * * When an image has been fully decoded into the yuv_planes_t structure, * call yuv444_to_yuy2() with the structure and the final (pre-allocated) * YUY2 buffer. xine will have already chosen the best conversion * function to use based on the CPU type. The YUY2 buffer will then be * ready to pass to the video output module. * * If your decoder is rendering an image based on an RGB palette, a good * strategy is to maintain a YUV palette rather than an RGB palette and * render the image directly in YUV. * * Some utility macros that you may find useful in your decoder are * UNPACK_RGB15, UNPACK_RGB16, UNPACK_BGR15, and UNPACK_BGR16. All are * located in xineutils.h. All of them take a packed pixel, either in * RGB or BGR format depending on the macro, and unpack them into the * component red, green, and blue bytes. If a CPU has special instructions * to facilitate these operations (such as the PPC AltiVec pixel-unpacking * instructions), these macros will automatically map to those special * instructions. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include "xine_mmx.h" #define ALIGN4(ptr) ((uintptr_t)(ptr) & ~(uintptr_t)3) /* * Precalculate all of the YUV tables since it requires only 8 kilobytes to store them * (plus 2 for backwards compatibility). */ int y_r_table[256]; int y_g_table[256]; int y_b_table[256]; int uv_br_table[256]; int u_r_table[256]; int u_g_table[256]; int v_b_table[256]; int v_g_table[256]; int u_b_table[256]; int v_r_table[256]; void (*yuv444_to_yuy2) (const yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int pitch); void (*yuv9_to_yv12) (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, const unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, int width, int height); void (*yuv411_to_yv12) (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dest, int y_dest_pitch, const unsigned char *u_src, int u_src_pitch, unsigned char *u_dest, int u_dest_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *v_dest, int v_dest_pitch, int width, int height); void (*yv12_to_yuy2) (const unsigned char *y_src, int y_src_pitch, const unsigned char *u_src, int u_src_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, int width, int height, int progressive); void (*yuy2_to_yv12) (const unsigned char *yuy2_map, int yuy2_pitch, unsigned char *y_dst, int y_dst_pitch, unsigned char *u_dst, int u_dst_pitch, unsigned char *v_dst, int v_dst_pitch, int width, int height); /* * init_yuv_planes * * This function initializes a yuv_planes_t structure based on the width * and height passed to it. The width must be divisible by 2. */ void init_yuv_planes(yuv_planes_t *yuv_planes, int width, int height) { size_t plane_size = width * height; memset (yuv_planes, 0, sizeof (*yuv_planes)); yuv_planes->row_width = width; yuv_planes->row_count = height; yuv_planes->y = xine_mallocz_aligned(plane_size); yuv_planes->u = xine_mallocz_aligned(plane_size); yuv_planes->v = xine_mallocz_aligned(plane_size); } /* * free_yuv_planes * * This frees the memory used by the YUV planes. */ void free_yuv_planes(yuv_planes_t *yuv_planes) { xine_freep_aligned(&yuv_planes->y); xine_freep_aligned(&yuv_planes->u); xine_freep_aligned(&yuv_planes->v); } /* * yuv444_to_yuy2_c * * This is the simple, portable C version of the yuv444_to_yuy2() function. * It is not especially accurate in its method. But it is fast. * * yuv_planes contains the 3 non-subsampled planes that represent Y, U, * and V samples for every pixel in the image. For each pair of pixels, * use both Y samples but use the first pixel's U value and the second * pixel's V value. * * Y plane: Y0 Y1 Y2 Y3 ... * U plane: U0 U1 U2 U3 ... * V plane: V0 V1 V2 V3 ... * * YUY2 map: Y0 U0 Y1 V1 Y2 U2 Y3 V3 */ static void yuv444_to_yuy2_c(const yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int pitch) { const uint8_t *restrict y = yuv_planes->y; const uint8_t *restrict u = yuv_planes->u; const uint8_t *restrict v = yuv_planes->v; uint8_t *restrict yuy2 = yuy2_map; unsigned int row_ptr, pixel_ptr; int yuy2_index; /* copy the Y samples */ yuy2_index = 0; for (row_ptr = 0; row_ptr < yuv_planes->row_width * yuv_planes->row_count; row_ptr += yuv_planes->row_width) { for (pixel_ptr = 0; pixel_ptr < yuv_planes->row_width; pixel_ptr++, yuy2_index += 2) yuy2[yuy2_index] = y[row_ptr + pixel_ptr]; yuy2_index += (pitch - 2*yuv_planes->row_width); } /* copy the C samples */ yuy2_index = 1; for (row_ptr = 0; row_ptr < yuv_planes->row_width * yuv_planes->row_count; row_ptr += yuv_planes->row_width) { for (pixel_ptr = 0; pixel_ptr < yuv_planes->row_width;) { yuy2[yuy2_index] = u[row_ptr + pixel_ptr]; pixel_ptr++; yuy2_index += 2; yuy2[yuy2_index] = v[row_ptr + pixel_ptr]; pixel_ptr++; yuy2_index += 2; } yuy2_index += (pitch - 2*yuv_planes->row_width); } } /* * yuv444_to_yuy2_mmx * * This is the proper, filtering version of the yuv444_to_yuy2() function * optimized with basic Intel MMX instructions. * * yuv_planes contains the 3 non-subsampled planes that represent Y, U, * and V samples for every pixel in the image. The goal is to convert the * 3 planes to a single packed YUY2 byte stream. Dealing with the Y * samples is easy because every Y sample is used in the final image. * This can still be sped up using MMX instructions. Initialize mm0 to 0. * Then load blocks of 8 Y samples into mm1: * * in memory: Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 * in mm1: Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 * * Use the punpck*bw instructions to interleave the Y samples with zeros. * For example, executing punpcklbw_r2r(mm0, mm1) will result in: * * mm1: 00 Y3 00 Y2 00 Y1 00 Y0 * * which will be written back to memory (in the YUY2 map) as: * * in memory: Y0 00 Y1 00 Y2 00 Y3 00 * * Do the same with the top 4 samples and soon all of the Y samples are * split apart and ready to have the U and V values interleaved. * * The C planes (U and V) must be filtered. The filter looks like this: * * (1 * C1 + 3 * C2 + 3 * C3 + 1 * C4) / 8 * * This filter slides across each row of each color plane. In the end, all * of the samples are filtered and the converter only uses every other * one. Since half of the filtered samples will not be used, their * calculations can safely be skipped. * * This implementation of the converter uses the MMX pmaddwd instruction * which performs 4 16x16 multiplications and 2 additions in parallel. * * First, initialize mm0 to 0 and mm7 to the filter coefficients: * mm0 = 0 * mm7 = 0001 0003 0003 0001 * * For each C plane, init the YUY2 map pointer to either 1 (for the U * plane) or 3 (for the V plane). For each set of 8 C samples, compute * 3 final C samples: 1 for [C0..C3], 1 for [C2..C5], and 1 for [C4..C7]. * Load 8 samples: * mm1 = C7 C6 .. C1 C0 (opposite order than in memory) * * Interleave zeros with the first 4 C samples: * mm2 = 00 C3 00 C2 00 C1 00 C0 * * Use pmaddwd to multiply and add: * mm2 = [C0 * 1 + C1 * 3] [C2 * 3 + C3 * 1] * * Copy mm2 to mm3, shift the high 32 bits in mm3 down, do the final * accumulation, and then divide by 8 (shift right by 3): * mm3 = mm2 * mm3 >>= 32 * mm2 += mm3 * mm2 >>= 3 * * At this point, the lower 8 bits of mm2 contain a filtered C sample. * Move it out to the YUY2 map and advance the map pointer by 4. Toss out * 2 of the samples in mm1 (C0 and C1) and loop twice more, once for * [C2..C5] and once for [C4..C7]. After computing 3 filtered samples, * increment the plane pointer by 6 and repeat the whole process. * * There is a special case when the filter hits the end of the line since * it is always necessary to rely on phantom samples beyond the end of the * line in order to compute the final 1-3 C samples of a line. This function * rewinds the C sample stream by a few bytes and reuses a few samples in * order to compute the final samples. This is not strictly correct; a * better approach would be to mirror the final samples before computing * the filter. But this reuse method is fast and apparently accurate * enough. * */ #if defined(ARCH_X86) static void yuv444_to_yuy2_mmx(const yuv_planes_t *yuv_planes, unsigned char *yuy2_map, int pitch) { unsigned int i; int h, j, k; int width_div_8 = yuv_planes->row_width / 8; int width_mod_8 = yuv_planes->row_width % 8; unsigned char *source_plane; unsigned char *dest_plane; static const mmx_t filter = { .ub = { 0x01, 0x00, 0x03, 0x00, 0x03, 0x00, 0x01, 0x00, } }; unsigned char shifter[] = {0, 0, 0, 0, 0, 0, 0, 0}; unsigned char vector[8]; int block_loops = yuv_planes->row_width / 6; int filter_loops; int residual_filter_loops; int row_inc = (pitch - 2 * yuv_planes->row_width); residual_filter_loops = (yuv_planes->row_width % 6) / 2; shifter[0] = residual_filter_loops * 8; /* if the width is divisible by 6, apply 3 residual filters and perform * one less primary loop */ if (!residual_filter_loops) { residual_filter_loops = 3; block_loops--; } /* set up some MMX registers: * mm0 = 0, mm7 = color filter */ pxor_r2r(mm0, mm0); movq_m2r(filter, mm7); /* copy the Y samples */ source_plane = yuv_planes->y; dest_plane = yuy2_map; for (i = 0; i < yuv_planes->row_count; i++) { /* iterate through blocks of 8 Y samples */ for (j = 0; j < width_div_8; j++) { movq_m2r(*source_plane, mm1); /* load 8 Y samples */ source_plane += 8; movq_r2r(mm1, mm2); /* mm2 = mm1 */ punpcklbw_r2r(mm0, mm1); /* interleave lower 4 samples with zeros */ movq_r2m(mm1, *dest_plane); dest_plane += 8; punpckhbw_r2r(mm0, mm2); /* interleave upper 4 samples with zeros */ movq_r2m(mm2, *dest_plane); dest_plane += 8; } /* iterate through residual samples in row if row is not divisible by 8 */ for (j = 0; j < width_mod_8; j++) { *dest_plane = *source_plane; dest_plane += 2; source_plane++; } dest_plane += row_inc; } /* figure out the C samples */ for (h = 0; h < 2; h++) { /* select the color plane for this iteration */ if (h == 0) { source_plane = yuv_planes->u; dest_plane = yuy2_map + 1; } else { source_plane = yuv_planes->v; dest_plane = yuy2_map + 3; } for (i = 0; i < yuv_planes->row_count; i++) { filter_loops = 3; /* iterate through blocks of 6 samples */ for (j = 0; j <= block_loops; j++) { if (j == block_loops) { /* special case for end-of-line residual */ filter_loops = residual_filter_loops; source_plane -= (8 - residual_filter_loops * 2); movq_m2r(*source_plane, mm1); /* load 8 C samples */ source_plane += 8; psrlq_m2r(*shifter, mm1); /* toss out samples before starting */ } else { /* normal case */ movq_m2r(*source_plane, mm1); /* load 8 C samples */ source_plane += 6; } for (k = 0; k < filter_loops; k++) { movq_r2r(mm1, mm2); /* make a copy */ punpcklbw_r2r(mm0, mm2); /* interleave lower 4 samples with zeros */ pmaddwd_r2r(mm7, mm2); /* apply the filter */ movq_r2r(mm2, mm3); /* copy result to mm3 */ psrlq_i2r(32, mm3); /* move the upper sum down */ paddd_r2r(mm3, mm2); /* mm2 += mm3 */ psrlq_i2r(3, mm2); /* divide by 8 */ #if 0 /* load the destination address into ebx */ __asm__ __volatile__ ("mov %0, %%ebx" : /* nothing */ : "X" (dest_plane) : "ebx" /* clobber list */); /* move the lower 32 bits of mm2 into eax */ __asm__ __volatile__ ("movd %%mm2, %%eax" : /* nothing */ : /* nothing */ : "eax" /* clobber list */ ); /* move al (the final filtered sample) to its spot it memory */ __asm__ __volatile__ ("mov %%al, (%%ebx)" : /* nothing */ : /* nothing */ ); #else movq_r2m(mm2, *vector); dest_plane[0] = vector[0]; #endif dest_plane += 4; psrlq_i2r(16, mm1); /* toss out 2 C samples and loop again */ } } dest_plane += row_inc; } } /* be a good MMX citizen and empty MMX state */ emms(); } #endif static void hscale_chroma_line (uint8_t *restrict dst, const uint8_t *restrict src, int src_width) { /* s1 s2 s3 s4 ... * d1 d2 d3 d4 d5 d6 d7 d8 ... */ int32_t n1, n2, n3, v; int x = src_width; if (x <= 0) return; n1 = *src++; *dst++ = n1; *dst++ = n1; if (--x <= 0) return; n2 = *src++; while (--x > 1) { n3 = *src++; v = (2 * n1 + 7 * n2 - n3) >> 3; *dst++ = (v & 0xffffff00) ? ~(v >> 31) : v; v = (-n1 + 7 * n2 + 2 * n3) >> 3; *dst++ = (v & 0xffffff00) ? ~(v >> 31) : v; n1 = n2; n2 = n3; } if (x > 0) { *dst++ = (n1 + 3 * n2) >> 2; *dst++ = n2; } } static void vscale_chroma_line (uint8_t *restrict dst, int pitch, const uint8_t *restrict src1, const uint8_t *restrict src2, int width) { /* The purpose of pitches is to align lines. * We align again here just to kill cast-align warnings. */ const uint32_t *p1, *p2; uint32_t *q1, *q2; uint32_t t1, t2; uint32_t n1, n2, n3, n4; int x; p1 = (const uint32_t *)ALIGN4(src1); p2 = (const uint32_t *)ALIGN4(src2); q1 = (uint32_t *)ALIGN4(dst); q2 = q1 + (pitch >> 2); /* process blocks of 4 pixels */ for (x = (width >> 2); x > 0; x--) { n1 = *p1++; n2 = *p2++; n3 = (n1 & 0xFF00FF00) >> 8; n4 = (n2 & 0xFF00FF00) >> 8; n1 &= 0x00FF00FF; n2 &= 0x00FF00FF; t1 = (2*n1 + 2*n2 + 0x20002); t2 = (n1 - n2); n1 = (t1 + t2); n2 = (t1 - t2); t1 = (2*n3 + 2*n4 + 0x20002); t2 = (n3 - n4); n3 = (t1 + t2); n4 = (t1 - t2); *q1++ = ((n1 >> 2) & 0x00FF00FF) | ((n3 << 6) & 0xFF00FF00); *q2++ = ((n2 >> 2) & 0x00FF00FF) | ((n4 << 6) & 0xFF00FF00); } /* process remaining pixels */ if (width & 3) { src1 += width & ~3; src2 += width & ~3; dst += width & ~3; for (x = width & 3; x > 0; x--) { n1 = src1[x]; n2 = src2[x]; dst[x] = (3 * n1 + n2 + 2) >> 2; dst[x + pitch] = (n1 + 3 * n2 + 2) >> 2; } } } static void upsample_c_plane_c(const uint8_t *src, int src_width, int src_height, uint8_t *dest, unsigned int src_pitch, unsigned int dest_pitch) { unsigned char *cr1; unsigned char *cr2; unsigned char *tmp; int y; cr1 = &dest[dest_pitch * (src_height * 2 - 2)]; cr2 = &dest[dest_pitch * (src_height * 2 - 3)]; /* horizontally upscale first line */ hscale_chroma_line (cr1, src, src_width); src += src_pitch; /* store first line */ memcpy (dest, cr1, src_width * 2); dest += dest_pitch; for (y = 0; y < (src_height - 1); y++) { hscale_chroma_line (cr2, src, src_width); src += src_pitch; /* interpolate and store two lines */ vscale_chroma_line (dest, dest_pitch, cr1, cr2, src_width * 2); dest += 2 * dest_pitch; /* swap buffers */ tmp = cr2; cr2 = cr1; cr1 = tmp; } /* horizontally upscale and store last line */ src -= src_pitch; hscale_chroma_line (dest, src, src_width); } /* * yuv9_to_yv12_c * */ static void yuv9_to_yv12_c (const uint8_t *restrict y_src, int y_src_pitch, uint8_t *restrict y_dest, int y_dest_pitch, const uint8_t *restrict u_src, int u_src_pitch, uint8_t *restrict u_dest, int u_dest_pitch, const uint8_t *restrict v_src, int v_src_pitch, uint8_t *restrict v_dest, int v_dest_pitch, int width, int height) { int y; /* Y plane */ for (y=0; y < height; y++) { xine_fast_memcpy (y_dest, y_src, width); y_src += y_src_pitch; y_dest += y_dest_pitch; } /* U plane */ upsample_c_plane_c(u_src, width / 4, height / 4, u_dest, u_src_pitch, u_dest_pitch); /* V plane */ upsample_c_plane_c(v_src, width / 4, height / 4, v_dest, v_src_pitch, v_dest_pitch); } /* * yuv411_to_yv12_c * */ static void yuv411_to_yv12_c (const uint8_t *restrict y_src, int y_src_pitch, uint8_t *restrict y_dest, int y_dest_pitch, const uint8_t *restrict u_src, int u_src_pitch, uint8_t *restrict u_dest, int u_dest_pitch, const uint8_t *restrict v_src, int v_src_pitch, uint8_t *restrict v_dest, int v_dest_pitch, int width, int height) { int y; int c_src_row, c_src_pixel; int c_dest_row, c_dest_pixel; unsigned char c_sample; /* Y plane */ for (y=0; y < height; y++) { xine_fast_memcpy (y_dest, y_src, width); y_src += y_src_pitch; y_dest += y_dest_pitch; } /* naive approach: downsample vertically, upsample horizontally */ /* U plane */ for (c_src_row = 0, c_dest_row = 0; c_src_row < u_src_pitch * height; c_src_row += u_src_pitch * 2, c_dest_row += u_dest_pitch) { for (c_src_pixel = c_src_row, c_dest_pixel = c_dest_row; c_dest_pixel < c_dest_row + u_dest_pitch; c_src_pixel++) { /* downsample by averaging the samples from 2 rows */ c_sample = (u_src[c_src_pixel] + u_src[c_src_pixel + u_src_pitch] + 1) / 2; /* upsample by outputting the sample twice on the YV12 row */ u_dest[c_dest_pixel++] = c_sample; u_dest[c_dest_pixel++] = c_sample; } } /* V plane */ for (c_src_row = 0, c_dest_row = 0; c_src_row < v_src_pitch * height; c_src_row += v_src_pitch * 2, c_dest_row += v_dest_pitch) { for (c_src_pixel = c_src_row, c_dest_pixel = c_dest_row; c_dest_pixel < c_dest_row + v_dest_pitch; c_src_pixel++) { /* downsample by averaging the samples from 2 rows */ c_sample = (v_src[c_src_pixel] + v_src[c_src_pixel + v_src_pitch] + 1 ) / 2; /* upsample by outputting the sample twice on the YV12 row */ v_dest[c_dest_pixel++] = c_sample; v_dest[c_dest_pixel++] = c_sample; } } } #define C_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ utmp = 3 * *p_u++; \ vtmp = 3 * *p_v++; \ *p_line1++ = *p_y1++; *p_line2++ = *p_y2++; \ *p_line1++ = (*p_ut++ + utmp) >> 2; *p_line2++ = (utmp + *p_ub++) >> 2; \ *p_line1++ = *p_y1++; *p_line2++ = *p_y2++; \ *p_line1++ = (*p_vt++ + vtmp) >> 2; *p_line2++ = (vtmp + *p_vb++) >> 2; \ #define C_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ *p_line1++ = *p_y1++; *p_line2++ = *p_y2++; \ *p_line1++ = (*p_ut++ + *p_u * 7) >> 3; *p_line2++ = (*p_u++ * 5 + *p_ub++ * 3) >> 3; \ *p_line1++ = *p_y1++; *p_line2++ = *p_y2++; \ *p_line1++ = (*p_vt++ + *p_v * 7) >> 3; *p_line2++ = (*p_v++ * 5 + *p_vb++ * 3) >> 3; \ /***************************************************************************** * I420_YUY2: planar YUV 4:2:0 to packed YUYV 4:2:2 * original conversion routine from Videolan project * changed to support interlaced frames and do correct chroma upsampling with * correct weighting factors and no chroma shift. *****************************************************************************/ static void yv12_to_yuy2_c (const uint8_t *restrict y_src, int y_src_pitch, const uint8_t *restrict u_src, int u_src_pitch, const uint8_t *restrict v_src, int v_src_pitch, uint8_t *restrict yuy2_map, int yuy2_pitch, int width, int height, int progressive) { uint8_t *p_line1, *p_line2 = yuy2_map; const uint8_t *p_y1, *p_y2 = y_src; const uint8_t *p_u = u_src; const uint8_t *p_v = v_src; const uint8_t *p_ub, *p_vb; const uint8_t *p_ut = u_src; const uint8_t *p_vt = v_src; int i_x, i_y; int utmp, vtmp; const int i_source_margin = y_src_pitch - width; const int i_source_u_margin = u_src_pitch - width/2; const int i_source_v_margin = v_src_pitch - width/2; const int i_dest_margin = yuy2_pitch - width*2; if( progressive ) { for( i_y = height / 2 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += yuy2_pitch; p_y1 = p_y2; p_y2 += y_src_pitch; if( i_y > 1 ) { p_ub = p_u + u_src_pitch; p_vb = p_v + v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } for( i_x = width / 2 ; i_x-- ; ) { C_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut = p_u - u_src_pitch; p_vt = p_v - v_src_pitch; p_line2 += i_dest_margin; } } else { for( i_y = height / 4 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += 2 * yuy2_pitch; p_y1 = p_y2; p_y2 += 2 * y_src_pitch; if( i_y > 1 ) { p_ub = p_u + 2 * u_src_pitch; p_vb = p_v + 2 * v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } for( i_x = width / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y2 += i_source_margin + y_src_pitch; p_u += i_source_u_margin + u_src_pitch; p_v += i_source_v_margin + v_src_pitch; p_ut = p_u - 2 * u_src_pitch; p_vt = p_v - 2 * v_src_pitch; p_line2 += i_dest_margin + yuy2_pitch; } p_line2 = yuy2_map + yuy2_pitch; p_y2 = y_src + y_src_pitch; p_u = u_src + u_src_pitch; p_v = v_src + v_src_pitch; p_ut = p_u; p_vt = p_v; for( i_y = height / 4 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += 2 * yuy2_pitch; p_y1 = p_y2; p_y2 += 2 * y_src_pitch; if( i_y > 1 ) { p_ub = p_u + 2 * u_src_pitch; p_vb = p_v + 2 * v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } /* swap arguments for even lines */ for( i_x = width / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y2,p_y1,p_u,p_ub,p_ut,p_v,p_vb,p_vt,p_line2,p_line1); } p_y2 += i_source_margin + y_src_pitch; p_u += i_source_u_margin + u_src_pitch; p_v += i_source_v_margin + v_src_pitch; p_ut = p_u - 2 * u_src_pitch; p_vt = p_v - 2 * v_src_pitch; p_line2 += i_dest_margin + yuy2_pitch; } } } #if defined(ARCH_X86) static const int64_t __attribute__((__used__)) byte_one = 0x0101010101010101ll; #define MMX_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ do { \ __asm__ __volatile__( \ "movq (%0), %%mm0 \n\t" /* Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 */ \ "movd (%1), %%mm1 \n\t" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \ "movd (%2), %%mm2 \n\t" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \ "pxor %%mm7, %%mm7 \n\t" /* 00 00 00 00 00 00 00 00 */ \ "punpcklbw %%mm7, %%mm1 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "punpcklbw %%mm7, %%mm2 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "movq %%mm1, %%mm3 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "movq %%mm2, %%mm4 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "psllw $1, %%mm3 \n\t" /* Cb * 2 */ \ "psllw $1, %%mm4 \n\t" /* Cr * 2 */ \ "paddw %%mm3, %%mm1 \n\t" /* Cb * 3 */ \ "paddw %%mm4, %%mm2 \n\t" /* Cr * 3 */ \ : \ : "r" (p_y1), "r" (p_u), "r" (p_v) ); \ __asm__ __volatile__( \ "movd (%0), %%mm3 \n\t" /* Load 4 Cbt 00 00 00 00 u3 u2 u1 u0 */ \ "movd (%1), %%mm4 \n\t" /* Load 4 Crt 00 00 00 00 v3 v2 v1 v0 */ \ "movd (%2), %%mm5 \n\t" /* Load 4 Cbb 00 00 00 00 u3 u2 u1 u0 */ \ "movd (%3), %%mm6 \n\t" /* Load 4 Crb 00 00 00 00 v3 v2 v1 v0 */ \ "punpcklbw %%mm7, %%mm3 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "punpcklbw %%mm7, %%mm4 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "punpcklbw %%mm7, %%mm5 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "punpcklbw %%mm7, %%mm6 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "paddw %%mm1, %%mm3 \n\t" /* Cb1 = Cbt + 3*Cb */ \ "paddw %%mm2, %%mm4 \n\t" /* Cr1 = Crt + 3*Cr */ \ "paddw %%mm5, %%mm1 \n\t" /* Cb2 = Cbb + 3*Cb */ \ "paddw %%mm6, %%mm2 \n\t" /* Cr2 = Crb + 3*Cr */ \ "psrlw $2, %%mm3 \n\t" /* Cb1 = (Cbt + 3*Cb) / 4 */ \ /* either the shifts by 2 and 8 or mask off bits and shift by 6 */ \ "psrlw $2, %%mm4 \n\t" /* Cr1 = (Crt + 3*Cr) / 4 */ \ "psllw $8, %%mm4 \n\t" \ "por %%mm4, %%mm3 \n\t" /* Cr1 Cb1 interl v3 u3 v2 u2 v1 u1 v0 u0 */ \ "psrlw $2, %%mm1 \n\t" /* Cb2 = (Cbb + 3*Cb) / 4 */ \ "psrlw $2, %%mm2 \n\t" /* Cr2 = (Cbb + 3*Cb) / 4 */ \ "psllw $8, %%mm2 \n\t" \ "por %%mm1, %%mm2 \n\t" /* Cr2 Cb2 interl v3 u3 v2 u2 v1 u1 v0 u0 */ \ "movq %%mm0, %%mm1 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%mm3, %%mm1 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ : \ : "r" (p_ut), "r" (p_vt), "r" (p_ub), "r" (p_vb) ); \ __asm__ __volatile__( \ "movq %%mm1, (%0) \n\t" /* Store low YUYV1 */ \ "punpckhbw %%mm3, %%mm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movq %%mm0, 8(%0) \n\t" /* Store high YUYV1 */ \ "movq (%2), %%mm0 \n\t" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "movq %%mm0, %%mm1 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%mm2, %%mm1 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ \ "movq %%mm1, (%1) \n\t" /* Store low YUYV2 */ \ "punpckhbw %%mm2, %%mm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ \ "movq %%mm0, 8(%1) \n\t" /* Store high YUYV2 */ \ : \ : "r" (p_line1), "r" (p_line2), "r" (p_y2) ); \ p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ p_ub += 4; p_vb += 4; p_ut += 4; p_vt += 4; \ } while(0) #define MMXEXT_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ do { \ __asm__ __volatile__( \ "movd %0, %%mm1 \n\t" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \ "movd %1, %%mm2 \n\t" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \ "movd %2, %%mm3 \n\t" /* Load 4 Cbt 00 00 00 00 u3 u2 u1 u0 */ \ "movd %3, %%mm4 \n\t" /* Load 4 Crt 00 00 00 00 v3 v2 v1 v0 */ \ "punpcklbw %%mm2, %%mm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ : \ : "m" (*p_u), "m" (*p_v), "m" (*p_ut), "m" (*p_vt) ); \ __asm__ __volatile__( \ "movq (%0), %%mm0 \n\t" /* Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%mm4, %%mm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb1 = 1/2(CrCbt + CrCb) */ \ /* for correct rounding */ \ "psubusb %%mm7, %%mm3 \n\t" \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb1 = 1/2(1/2(CrCbt + CrCb) + CrCb) */ \ "movq %%mm0, %%mm2 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%mm3, %%mm2 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movntq %%mm2, (%1) \n\t" /* Store low YUYV1 */ \ "punpckhbw %%mm3, %%mm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movntq %%mm0, 8(%1) \n\t" /* Store high YUYV1 */ \ : \ : "r" (p_y1), "r" (p_line1) ); \ __asm__ __volatile__( \ "movd %1, %%mm3 \n\t" /* Load 4 Cbb 00 00 00 00 u3 u2 u1 u0 */ \ "movd %2, %%mm4 \n\t" /* Load 4 Crb 00 00 00 00 v3 v2 v1 v0 */ \ "movq (%0), %%mm0 \n\t" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%mm4, %%mm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb2 = 1/2(CrCbb + CrCb) */ \ /* for correct rounding */ \ "psubusb %%mm7, %%mm3 \n\t" \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb2 = 1/2(1/2(CrCbb + CrCb) + CrCb) */ \ "movq %%mm0, %%mm2 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%mm3, %%mm2 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ \ "movntq %%mm2, (%3) \n\t" /* Store low YUYV2 */ \ "punpckhbw %%mm3, %%mm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ \ "movntq %%mm0, 8(%3) \n\t" /* Store high YUYV2 */ \ : \ : "r" (p_y2), "m" (*p_ub), "m" (*p_vb), "r" (p_line2) ); \ p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ p_ub += 4; p_vb += 4; p_ut += 4; p_vt += 4; \ } while(0) #define SSE2_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ do { \ __asm__ __volatile__( \ "movq %0, %%xmm1 \n\t" /* Load 8 Cb 00 00 00 00 u3 u2 u1 u0 */ \ "movq %1, %%xmm2 \n\t" /* Load 8 Cr 00 00 00 00 v3 v2 v1 v0 */ \ "movq %2, %%xmm3 \n\t" /* Load 8 Cbt 00 00 00 00 u3 u2 u1 u0 */ \ "movq %3, %%xmm4 \n\t" /* Load 8 Crt 00 00 00 00 v3 v2 v1 v0 */ \ "punpcklbw %%xmm2, %%xmm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ : \ : "m" (*p_u), "m" (*p_v), "m" (*p_ut), "m" (*p_vt) ); \ __asm__ __volatile__( \ "movdqa (%0), %%xmm0 \n\t" /* Load 16 Y y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%xmm4, %%xmm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb1 = 1/2(CrCbt + CrCb) */ \ /* for correct rounding */ \ "psubusb %%xmm7, %%xmm3 \n\t" \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb1 = 1/2(1/2(CrCbt + CrCb) + CrCb) */ \ "movdqa %%xmm0, %%xmm2 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%xmm3, %%xmm2 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movntdq %%xmm2, (%1) \n\t" /* Store low YUYV1 */ \ "punpckhbw %%xmm3, %%xmm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movntdq %%xmm0, 16(%1) \n\t" /* Store high YUYV1 */ \ : \ : "r" (p_y1), "r" (p_line1) ); \ __asm__ __volatile__( \ "movq %1, %%xmm3 \n\t" /* Load 8 Cbb 00 00 00 00 u3 u2 u1 u0 */ \ "movq %2, %%xmm4 \n\t" /* Load 8 Crb 00 00 00 00 v3 v2 v1 v0 */ \ "movdqa (%0), %%xmm0 \n\t" /* Load 16 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%xmm4, %%xmm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb2 = 1/2(CrCbb + CrCb) */ \ /* for correct rounding */ \ "psubusb %%xmm7, %%xmm3 \n\t" \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb2 = 1/2(1/2(CrCbb + CrCb) + CrCb) */ \ "movdqa %%xmm0, %%xmm2 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%xmm3, %%xmm2 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ \ "movntdq %%xmm2, (%3) \n\t" /* Store low YUYV2 */ \ "punpckhbw %%xmm3, %%xmm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ \ "movntdq %%xmm0, 16(%3) \n\t" /* Store high YUYV2 */ \ : \ : "r" (p_y2), "m" (*p_ub), "m" (*p_vb), "r" (p_line2) ); \ p_line1 += 32; p_line2 += 32; p_y1 += 16; p_y2 += 16; p_u += 8; p_v += 8; \ p_ub += 8; p_vb += 8; p_ut += 8; p_vt += 8; \ } while(0) #define MMX_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ do { \ __asm__ __volatile__( \ "movd (%0), %%mm1 \n\t" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \ "movd (%1), %%mm2 \n\t" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \ "pxor %%mm7, %%mm7 \n\t" /* 00 00 00 00 00 00 00 00 */ \ "punpcklbw %%mm7, %%mm1 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "punpcklbw %%mm7, %%mm2 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "movq %%mm1, %%mm3 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "movq %%mm2, %%mm4 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "psllw $2, %%mm3 \n\t" /* Cb * 4 */ \ "psllw $2, %%mm4 \n\t" /* Cr * 4 */ \ "paddw %%mm3, %%mm1 \n\t" /* Cb * 5 */ \ "paddw %%mm4, %%mm2 \n\t" /* Cr * 5 */ \ "psrlw $1, %%mm3 \n\t" /* Cb * 2 */ \ "psrlw $1, %%mm4 \n\t" /* Cr * 2 */ \ "paddw %%mm1, %%mm3 \n\t" /* Cb * 7 */ \ "paddw %%mm2, %%mm4 \n\t" /* Cr * 7 */ \ : \ : "r" (p_u), "r" (p_v) ); \ __asm__ __volatile__( \ "movd (%1), %%mm5 \n\t" /* Load 4 Cbt 00 00 00 00 u3 u2 u1 u0 */ \ "movd (%2), %%mm6 \n\t" /* Load 4 Crt 00 00 00 00 v3 v2 v1 v0 */ \ "movq (%0), %%mm0 \n\t" /* Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%mm7, %%mm5 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "punpcklbw %%mm7, %%mm6 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "paddw %%mm3, %%mm5 \n\t" /* Cb1 = Cbt + 7*Cb */ \ "paddw %%mm4, %%mm6 \n\t" /* Cr1 = Crt + 7*Cr */ \ "psrlw $3, %%mm5 \n\t" /* Cb1 = (Cbt + 7*Cb) / 8 */ \ /* either the shifts by 3 and 8 or mask off bits and shift by 5 */ \ "psrlw $3, %%mm6 \n\t" /* Cr1 = (Crt + 7*Cr) / 8 */ \ "psllw $8, %%mm6 \n\t" \ "por %%mm5, %%mm6 \n\t" /* Cr1 Cb1 interl v3 u3 v2 u2 v1 u1 v0 u0 */ \ "movq %%mm0, %%mm3 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%mm6, %%mm3 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movq %%mm3, (%3) \n\t" /* Store low YUYV1 */ \ "punpckhbw %%mm6, %%mm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movq %%mm0, 8(%3) \n\t" /* Store high YUYV1 */ \ : \ : "r" (p_y1), "r" (p_ut), "r" (p_vt), "r" (p_line1) ); \ __asm__ __volatile__( \ "movd (%1), %%mm3 \n\t" /* Load 4 Cbb 00 00 00 00 u3 u2 u1 u0 */ \ "movd (%2), %%mm4 \n\t" /* Load 4 Crb 00 00 00 00 v3 v2 v1 v0 */ \ "movq (%0), %%mm0 \n\t" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%mm7, %%mm3 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "punpcklbw %%mm7, %%mm4 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "movq %%mm3, %%mm5 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "movq %%mm4, %%mm6 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "psllw $1, %%mm5 \n\t" /* Cbb * 2 */ \ "psllw $1, %%mm6 \n\t" /* Crb * 2 */ \ "paddw %%mm5, %%mm3 \n\t" /* Cbb * 3 */ \ "paddw %%mm6, %%mm4 \n\t" /* Crb * 3 */ \ "paddw %%mm3, %%mm1 \n\t" /* Cb2 = 3*Cbb + 5*Cb */ \ "paddw %%mm4, %%mm2 \n\t" /* Cr2 = 3*Crb + 5*Cr */ \ "psrlw $3, %%mm1 \n\t" /* Cb2 = (3*Cbb + 5*Cb) / 8 */ \ /* either the shifts by 3 and 8 or mask off bits and shift by 5 */ \ "psrlw $3, %%mm2 \n\t" /* Cr2 = (3*Crb + 5*Cr) / 8 */ \ "psllw $8, %%mm2 \n\t" \ "por %%mm1, %%mm2 \n\t" /* Cr2 Cb2 interl v3 u3 v2 u2 v1 u1 v0 u0 */ \ "movq %%mm0, %%mm1 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%mm2, %%mm1 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ \ "movq %%mm1, (%3) \n\t" /* Store low YUYV2 */ \ "punpckhbw %%mm2, %%mm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ \ "movq %%mm0, 8(%3) \n\t" /* Store high YUYV2 */ \ : \ : "r" (p_y2), "r" (p_ub), "r" (p_vb), "r" (p_line2) ); \ p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ p_ub += 4; p_vb += 4; p_ut += 4; p_vt += 4; \ } while(0) #define MMXEXT_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ do { \ __asm__ __volatile__( \ "movd %0, %%mm1 \n\t" /* Load 4 Cb 00 00 00 00 u3 u2 u1 u0 */ \ "movd %1, %%mm2 \n\t" /* Load 4 Cr 00 00 00 00 v3 v2 v1 v0 */ \ "movd %2, %%mm3 \n\t" /* Load 4 Cbt 00 00 00 00 u3 u2 u1 u0 */ \ "movd %3, %%mm4 \n\t" /* Load 4 Crt 00 00 00 00 v3 v2 v1 v0 */ \ "punpcklbw %%mm2, %%mm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ : \ : "m" (*p_u), "m" (*p_v), "m" (*p_ut), "m" (*p_vt) ); \ __asm__ __volatile__( \ "movq (%0), %%mm0 \n\t" /* Load 8 Y y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%mm4, %%mm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb1 = 1/2(CrCbt + CrCb) */ \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb1 = 1/2(1/2(CrCbt + CrCb) + CrCb) */ \ /* for correct rounding */ \ "psubusb %%mm7, %%mm3 \n\t" \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb1 = 1/8CrCbt + 7/8CrCb */ \ "movq %%mm0, %%mm2 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%mm3, %%mm2 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movntq %%mm2, (%1) \n\t" /* Store low YUYV1 */ \ "punpckhbw %%mm3, %%mm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movntq %%mm0, 8(%1) \n\t" /* Store high YUYV1 */ \ : \ : "r" (p_y1), "r" (p_line1) ); \ __asm__ __volatile__( \ "movd %1, %%mm3 \n\t" /* Load 4 Cbb 00 00 00 00 u3 u2 u1 u0 */ \ "movd %2, %%mm4 \n\t" /* Load 4 Crb 00 00 00 00 v3 v2 v1 v0 */ \ "movq (%0), %%mm0 \n\t" /* Load 8 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%mm4, %%mm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb2 = 1/2(CrCbb + CrCb) */ \ "pavgb %%mm3, %%mm1 \n\t" /* CrCb2 = 1/4CrCbb + 3/4CrCb */ \ /* other cases give error smaller than one with repeated pavgb but here we */ \ /* would get a max error of 1.125. Subtract one to compensate for repeated */ \ /* rounding up (which will give max error of 0.625 which isn't perfect */ \ /* rounding but good enough). */ \ "psubusb %%mm7, %%mm1 \n\t" \ "pavgb %%mm1, %%mm3 \n\t" /* CrCb2 = 3/8CrCbb + 5/8CrCb */ \ "movq %%mm0, %%mm2 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%mm3, %%mm2 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ \ "movntq %%mm2, (%3) \n\t" /* Store low YUYV2 */ \ "punpckhbw %%mm3, %%mm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ \ "movntq %%mm0, 8(%3) \n\t" /* Store high YUYV2 */ \ : \ : "r" (p_y2), "m" (*p_ub), "m" (*p_vb), "r" (p_line2) ); \ p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ p_ub += 4; p_vb += 4; p_ut += 4; p_vt += 4; \ } while(0) #define SSE2_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2) \ do { \ __asm__ __volatile__( \ "movq %0, %%xmm1 \n\t" /* Load 8 Cb 00 00 00 00 u3 u2 u1 u0 */ \ "movq %1, %%xmm2 \n\t" /* Load 8 Cr 00 00 00 00 v3 v2 v1 v0 */ \ "movq %2, %%xmm3 \n\t" /* Load 8 Cbt 00 00 00 00 u3 u2 u1 u0 */ \ "movq %3, %%xmm4 \n\t" /* Load 8 Crt 00 00 00 00 v3 v2 v1 v0 */ \ "punpcklbw %%xmm2, %%xmm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ : \ : "m" (*p_u), "m" (*p_v), "m" (*p_ut), "m" (*p_vt) ); \ __asm__ __volatile__( \ "movdqa (%0), %%xmm0 \n\t" /* Load 16 Y y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%xmm4, %%xmm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb1 = 1/2(CrCbt + CrCb) */ \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb1 = 1/2(1/2(CrCbt + CrCb) + CrCb) */ \ /* for correct rounding */ \ "psubusb %%xmm7, %%xmm3 \n\t" \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb1 = 1/8CrCbt + 7/8CrCb */ \ "movdqa %%xmm0, %%xmm2 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "punpcklbw %%xmm3, %%xmm2 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movntdq %%xmm2, (%1) \n\t" /* Store low YUYV1 */ \ "punpckhbw %%xmm3, %%xmm0 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movntdq %%xmm0, 16(%1) \n\t" /* Store high YUYV1 */ \ : \ : "r" (p_y1), "r" (p_line1) ); \ __asm__ __volatile__( \ "movq %1, %%xmm3 \n\t" /* Load 8 Cbb 00 00 00 00 u3 u2 u1 u0 */ \ "movq %2, %%xmm4 \n\t" /* Load 8 Crb 00 00 00 00 v3 v2 v1 v0 */ \ "movdqa (%0), %%xmm0 \n\t" /* Load 16 Y Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%xmm4, %%xmm3 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb2 = 1/2(CrCbb + CrCb) */ \ "pavgb %%xmm3, %%xmm1 \n\t" /* CrCb2 = 1/4CrCbb + 3/4CrCb */ \ /* other cases give error smaller than one with repeated pavgb but here we */ \ /* would get a max error of 1.125. Subtract one to compensate for repeated */ \ /* rounding up (which will give max error of 0.625 which isn't perfect */ \ /* rounding but good enough). */ \ "psubusb %%xmm7, %%xmm1 \n\t" \ "pavgb %%xmm1, %%xmm3 \n\t" /* CrCb2 = 3/8CrCbb + 5/8CrCb */ \ "movdqa %%xmm0, %%xmm2 \n\t" /* Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ \ "punpcklbw %%xmm3, %%xmm2 \n\t" /* v1 Y3 u1 Y2 v0 Y1 u0 Y0 */ \ "movntdq %%xmm2, (%3) \n\t" /* Store low YUYV2 */ \ "punpckhbw %%xmm3, %%xmm0 \n\t" /* v3 Y7 u3 Y6 v2 Y5 u2 Y4 */ \ "movntdq %%xmm0, 16(%3) \n\t" /* Store high YUYV2 */ \ : \ : "r" (p_y2), "m" (*p_ub), "m" (*p_vb), "r" (p_line2) ); \ p_line1 += 32; p_line2 += 32; p_y1 += 16; p_y2 += 16; p_u += 8; p_v += 8; \ p_ub += 8; p_vb += 8; p_ut += 8; p_vt += 8; \ } while(0) #endif #if defined(ARCH_X86) static void yv12_to_yuy2_mmxext (const unsigned char *y_src, int y_src_pitch, const unsigned char *u_src, int u_src_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, int width, int height, int progressive ) { uint8_t *p_line1, *p_line2 = yuy2_map; const uint8_t *p_y1, *p_y2 = y_src; const uint8_t *p_u = u_src; const uint8_t *p_v = v_src; const uint8_t *p_ub, *p_vb; const uint8_t *p_ut = u_src; const uint8_t *p_vt = v_src; int i_x, i_y; int utmp, vtmp; const int i_source_margin = y_src_pitch - width; const int i_source_u_margin = u_src_pitch - width/2; const int i_source_v_margin = v_src_pitch - width/2; const int i_dest_margin = yuy2_pitch - width*2; __asm__ __volatile__( "movq %0, %%mm7 \n\t" : : "m" (byte_one) ); if( progressive ) { for( i_y = height / 2; i_y-- ; ) { p_line1 = p_line2; p_line2 += yuy2_pitch; p_y1 = p_y2; p_y2 += y_src_pitch; if( i_y > 1 ) { p_ub = p_u + u_src_pitch; p_vb = p_v + v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } for( i_x = width / 8 ; i_x-- ; ) { MMXEXT_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } for( i_x = (width % 8) / 2 ; i_x-- ; ) { C_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut = p_u - u_src_pitch; p_vt = p_v - v_src_pitch; p_line2 += i_dest_margin; } } else { for( i_y = height / 4 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += 2 * yuy2_pitch; p_y1 = p_y2; p_y2 += 2 * y_src_pitch; if( i_y > 1 ) { p_ub = p_u + 2 * u_src_pitch; p_vb = p_v + 2 * v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } /* 2 odd lines */ for( i_x = width / 8 ; i_x-- ; ) { MMXEXT_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } for( i_x = (width % 8) / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y1 += i_source_margin; p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut += i_source_u_margin; p_vt += i_source_v_margin; p_ub += i_source_u_margin; p_vb += i_source_v_margin; p_line1 += i_dest_margin; p_line2 += i_dest_margin; /* 2 even lines - arguments need to be swapped */ for( i_x = width / 8 ; i_x-- ; ) { MMXEXT_YUV420_YUYV_INTERLACED(p_y2,p_y1,p_u,p_ub,p_ut,p_v,p_vb,p_vt,p_line2,p_line1); } for( i_x = (width % 8) / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y2,p_y1,p_u,p_ub,p_ut,p_v,p_vb,p_vt,p_line2,p_line1); } p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut = p_u - 2 * u_src_pitch; p_vt = p_v - 2 * v_src_pitch; p_line2 += i_dest_margin; } } sfence(); emms(); } #endif #if defined(ARCH_X86) static void yv12_to_yuy2_sse2 (const unsigned char *y_src, int y_src_pitch, const unsigned char *u_src, int u_src_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, int width, int height, int progressive ) { /* check alignment */ if (((uintptr_t)y_src | (uintptr_t)yuy2_map | yuy2_pitch | y_src_pitch) & 15) { yv12_to_yuy2_mmxext(y_src, y_src_pitch, u_src, u_src_pitch, v_src, v_src_pitch, yuy2_map, yuy2_pitch, width, height, progressive); return; } uint8_t *p_line1, *p_line2 = yuy2_map; const uint8_t *p_y1, *p_y2 = y_src; const uint8_t *p_u = u_src; const uint8_t *p_v = v_src; const uint8_t *p_ub, *p_vb; const uint8_t *p_ut = u_src; const uint8_t *p_vt = v_src; int i_x, i_y; int utmp, vtmp; const int i_source_margin = y_src_pitch - width; const int i_source_u_margin = u_src_pitch - width/2; const int i_source_v_margin = v_src_pitch - width/2; const int i_dest_margin = yuy2_pitch - width*2; static const sse_t qw_byte_one = { .uq = { 0x0101010101010101ll, 0x0101010101010101ll } }; __asm__ __volatile__( "movdqa %0, %%xmm7 \n\t" : : "m" (qw_byte_one) ); if( progressive ) { for( i_y = height / 2; i_y-- ; ) { p_line1 = p_line2; p_line2 += yuy2_pitch; p_y1 = p_y2; p_y2 += y_src_pitch; if( i_y > 1 ) { p_ub = p_u + u_src_pitch; p_vb = p_v + v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } for( i_x = width / 16 ; i_x-- ; ) { SSE2_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } for( i_x = (width % 16) / 2 ; i_x-- ; ) { C_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut = p_u - u_src_pitch; p_vt = p_v - v_src_pitch; p_line2 += i_dest_margin; } } else { for( i_y = height / 4 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += 2 * yuy2_pitch; p_y1 = p_y2; p_y2 += 2 * y_src_pitch; if( i_y > 1 ) { p_ub = p_u + 2 * u_src_pitch; p_vb = p_v + 2 * v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } /* 2 odd lines */ for( i_x = width / 16 ; i_x-- ; ) { SSE2_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } for( i_x = (width % 16) / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y1 += i_source_margin; p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut += i_source_u_margin; p_vt += i_source_v_margin; p_ub += i_source_u_margin; p_vb += i_source_v_margin; p_line1 += i_dest_margin; p_line2 += i_dest_margin; /* 2 even lines - arguments need to be swapped */ for( i_x = width / 16 ; i_x-- ; ) { SSE2_YUV420_YUYV_INTERLACED(p_y2,p_y1,p_u,p_ub,p_ut,p_v,p_vb,p_vt,p_line2,p_line1); } for( i_x = (width % 16) / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y2,p_y1,p_u,p_ub,p_ut,p_v,p_vb,p_vt,p_line2,p_line1); } p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut = p_u - 2 * u_src_pitch; p_vt = p_v - 2 * v_src_pitch; p_line2 += i_dest_margin; } } sfence(); } #endif /* identical to yv12_to_yuy2_c with the obvious exception... */ #if defined(ARCH_X86) static void yv12_to_yuy2_mmx (const unsigned char *y_src, int y_src_pitch, const unsigned char *u_src, int u_src_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *yuy2_map, int yuy2_pitch, int width, int height, int progressive ) { uint8_t *p_line1, *p_line2 = yuy2_map; const uint8_t *p_y1, *p_y2 = y_src; const uint8_t *p_u = u_src; const uint8_t *p_v = v_src; const uint8_t *p_ub, *p_vb; const uint8_t *p_ut = u_src; const uint8_t *p_vt = v_src; int i_x, i_y; int utmp, vtmp; const int i_source_margin = y_src_pitch - width; const int i_source_u_margin = u_src_pitch - width/2; const int i_source_v_margin = v_src_pitch - width/2; const int i_dest_margin = yuy2_pitch - width*2; if( progressive ) { for( i_y = height / 2; i_y-- ; ) { p_line1 = p_line2; p_line2 += yuy2_pitch; p_y1 = p_y2; p_y2 += y_src_pitch; if( i_y > 1 ) { p_ub = p_u + u_src_pitch; p_vb = p_v + v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } for( i_x = width / 8 ; i_x-- ; ) { MMX_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } for( i_x = (width % 8) / 2 ; i_x-- ; ) { C_YUV420_YUYV_PROGRESSIVE(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y2 += i_source_margin; p_u += i_source_u_margin; p_v += i_source_v_margin; p_ut = p_u - u_src_pitch; p_vt = p_v - v_src_pitch; p_line2 += i_dest_margin; } } else { for( i_y = height / 4 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += 2 * yuy2_pitch; p_y1 = p_y2; p_y2 += 2 * y_src_pitch; if( i_y > 1 ) { p_ub = p_u + 2 * u_src_pitch; p_vb = p_v + 2 * v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } for( i_x = width / 8 ; i_x-- ; ) { MMX_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } for( i_x = (width % 8) / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y1,p_y2,p_u,p_ut,p_ub,p_v,p_vt,p_vb,p_line1,p_line2); } p_y2 += i_source_margin + y_src_pitch; p_u += i_source_u_margin + u_src_pitch; p_v += i_source_v_margin + v_src_pitch; p_ut = p_u - 2 * u_src_pitch; p_vt = p_v - 2 * v_src_pitch; p_line2 += i_dest_margin + yuy2_pitch; } p_line2 = yuy2_map + yuy2_pitch; p_y2 = y_src + y_src_pitch; p_u = u_src + u_src_pitch; p_v = v_src + v_src_pitch; p_ut = p_u; p_vt = p_v; for( i_y = height / 4 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += 2 * yuy2_pitch; p_y1 = p_y2; p_y2 += 2 * y_src_pitch; if( i_y > 1 ) { p_ub = p_u + 2 * u_src_pitch; p_vb = p_v + 2 * v_src_pitch; } else { p_ub = p_u; p_vb = p_v; } /* swap arguments for even lines */ for( i_x = width / 8 ; i_x-- ; ) { MMX_YUV420_YUYV_INTERLACED(p_y2,p_y1,p_u,p_ub,p_ut,p_v,p_vb,p_vt,p_line2,p_line1); } for( i_x = (width % 8) / 2 ; i_x-- ; ) { C_YUV420_YUYV_INTERLACED(p_y2,p_y1,p_u,p_ub,p_ut,p_v,p_vb,p_vt,p_line2,p_line1); } p_y2 += i_source_margin + y_src_pitch; p_u += i_source_u_margin + u_src_pitch; p_v += i_source_v_margin + v_src_pitch; p_ut = p_u - 2 * u_src_pitch; p_vt = p_v - 2 * v_src_pitch; p_line2 += i_dest_margin + yuy2_pitch; } } sfence(); emms(); } #endif #define C_YUYV_YUV420( ) \ *p_y1++ = *p_line1++; *p_y2++ = *p_line2++; \ *p_u++ = (*p_line1++ + *p_line2++)>>1; \ *p_y1++ = *p_line1++; *p_y2++ = *p_line2++; \ *p_v++ = (*p_line1++ + *p_line2++)>>1; static void yuy2_to_yv12_c (const uint8_t *restrict yuy2_map, int yuy2_pitch, uint8_t *restrict y_dst, int y_dst_pitch, uint8_t *restrict u_dst, int u_dst_pitch, uint8_t *restrict v_dst, int v_dst_pitch, int width, int height) { const uint8_t *restrict p_line1; const uint8_t *restrict p_line2 = yuy2_map; uint8_t *restrict p_y1; uint8_t *restrict p_y2 = y_dst; uint8_t *restrict p_u = u_dst; uint8_t *restrict p_v = v_dst; int i_x, i_y; const int i_dest_margin = y_dst_pitch - width; const int i_dest_u_margin = u_dst_pitch - width/2; const int i_dest_v_margin = v_dst_pitch - width/2; const int i_source_margin = yuy2_pitch - width*2; for( i_y = height / 2 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += yuy2_pitch; p_y1 = p_y2; p_y2 += y_dst_pitch; for( i_x = width / 8 ; i_x-- ; ) { C_YUYV_YUV420( ); C_YUYV_YUV420( ); C_YUYV_YUV420( ); C_YUYV_YUV420( ); } p_y2 += i_dest_margin; p_u += i_dest_u_margin; p_v += i_dest_v_margin; p_line2 += i_source_margin; } } #if defined(ARCH_X86) /* yuy2->yv12 with subsampling (some ideas from mplayer's yuy2toyv12) */ #define MMXEXT_YUYV_YUV420( ) \ do { \ __asm__ __volatile__( \ "movq (%0), %%mm0 \n\t" /* Load v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movq 8(%0), %%mm1 \n\t" /* Load v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movq %%mm0, %%mm2 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movq %%mm1, %%mm3 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "psrlw $8, %%mm0 \n\t" /* 00 v1 00 u1 00 v0 00 u0 */ \ "psrlw $8, %%mm1 \n\t" /* 00 v3 00 u3 00 v2 00 u2 */ \ "pand %%mm7, %%mm2 \n\t" /* 00 y3 00 y2 00 y1 00 y0 */ \ "pand %%mm7, %%mm3 \n\t" /* 00 y7 00 y6 00 y5 00 y4 */ \ "packuswb %%mm1, %%mm0 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "packuswb %%mm3, %%mm2 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "movntq %%mm2, (%1) \n\t" /* Store YYYYYYYY line1 */ \ : \ : "r" (p_line1), "r" (p_y1) ); \ __asm__ __volatile__( \ "movq (%0), %%mm1 \n\t" /* Load v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movq 8(%0), %%mm2 \n\t" /* Load v3 y7 u3 y6 v2 y5 u2 y4 */ \ "movq %%mm1, %%mm3 \n\t" /* v1 y3 u1 y2 v0 y1 u0 y0 */ \ "movq %%mm2, %%mm4 \n\t" /* v3 y7 u3 y6 v2 y5 u2 y4 */ \ "psrlw $8, %%mm1 \n\t" /* 00 v1 00 u1 00 v0 00 u0 */ \ "psrlw $8, %%mm2 \n\t" /* 00 v3 00 u3 00 v2 00 u2 */ \ "pand %%mm7, %%mm3 \n\t" /* 00 y3 00 y2 00 y1 00 y0 */ \ "pand %%mm7, %%mm4 \n\t" /* 00 y7 00 y6 00 y5 00 y4 */ \ "packuswb %%mm2, %%mm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "packuswb %%mm4, %%mm3 \n\t" /* y7 y6 y5 y4 y3 y2 y1 y0 */ \ "movntq %%mm3, (%1) \n\t" /* Store YYYYYYYY line2 */ \ : \ : "r" (p_line2), "r" (p_y2) ); \ __asm__ __volatile__( \ "pavgb %%mm1, %%mm0 \n\t" /* (mean) v3 u3 v2 u2 v1 u1 v0 u0 */ \ "movq %%mm0, %%mm1 \n\t" /* v3 u3 v2 u2 v1 u1 v0 u0 */ \ "psrlw $8, %%mm0 \n\t" /* 00 v3 00 v2 00 v1 00 v0 */ \ "packuswb %%mm0, %%mm0 \n\t" /* v3 v2 v1 v0 */ \ "movd %%mm0, (%0) \n\t" /* Store VVVV */ \ "pand %%mm7, %%mm1 \n\t" /* 00 u3 00 u2 00 u1 00 u0 */ \ "packuswb %%mm1, %%mm1 \n\t" /* u3 u2 u1 u0 */ \ "movd %%mm1, (%1) \n\t" /* Store UUUU */ \ : \ : "r" (p_v), "r" (p_u) ); \ p_line1 += 16; p_line2 += 16; p_y1 += 8; p_y2 += 8; p_u += 4; p_v += 4; \ } while(0) #endif #if defined(ARCH_X86) static void yuy2_to_yv12_mmxext (const unsigned char *yuy2_map, int yuy2_pitch, unsigned char *y_dst, int y_dst_pitch, unsigned char *u_dst, int u_dst_pitch, unsigned char *v_dst, int v_dst_pitch, int width, int height) { const uint8_t *p_line1, *p_line2 = yuy2_map; uint8_t *p_y1, *p_y2 = y_dst; uint8_t *p_u = u_dst; uint8_t *p_v = v_dst; int i_x, i_y; const int i_dest_margin = y_dst_pitch - width; const int i_dest_u_margin = u_dst_pitch - width/2; const int i_dest_v_margin = v_dst_pitch - width/2; const int i_source_margin = yuy2_pitch - width*2; __asm__ __volatile__( "pcmpeqw %mm7, %mm7 \n\t" "psrlw $8, %mm7 \n\t" /* 00 ff 00 ff 00 ff 00 ff */ ); for( i_y = height / 2 ; i_y-- ; ) { p_line1 = p_line2; p_line2 += yuy2_pitch; p_y1 = p_y2; p_y2 += y_dst_pitch; for( i_x = width / 8 ; i_x-- ; ) { MMXEXT_YUYV_YUV420( ); } p_y2 += i_dest_margin; p_u += i_dest_u_margin; p_v += i_dest_v_margin; p_line2 += i_source_margin; } sfence(); emms(); } #endif /* * init_yuv_conversion * * This function precalculates all of the tables used for converting RGB * values to YUV values. This function also decides which conversion * functions to use. */ void init_yuv_conversion(void) { int i; #if defined(ARCH_X86) uint32_t accel; #endif /* ITU-R 601 */ #define KB 0.114 #define KR 0.299 #define YR (219.0/255.0)*KR*SCALEFACTOR #define YG (219.0/255.0)*(1.0-KB-KR)*SCALEFACTOR #define YB (219.0/255.0)*KB*SCALEFACTOR #define UR (112.0/255.0)*(KR/(KB-1.0))*SCALEFACTOR #define UG (112.0/255.0)*((1.0-KB-KR)/(KB-1.0))*SCALEFACTOR #define UB (112.0/255.0)*SCALEFACTOR #define VR (112.0/255.0)*SCALEFACTOR #define VG (112.0/255.0)*((1.0-KB-KR)/(KR-1.0))*SCALEFACTOR #define VB (112.0/255.0)*(KB/(KR-1.0))*SCALEFACTOR /* initialize the RGB -> YUV tables */ for (i = 0; i < 256; i++) { /* fast and correctly rounded */ y_r_table[i] = YR * i; y_g_table[i] = YG * i + 16 * SCALEFACTOR + SCALEFACTOR / 2; y_b_table[i] = YB * i; uv_br_table[i] = UB * i + CENTERSAMPLE * SCALEFACTOR + SCALEFACTOR / 2; u_r_table[i] = UR * i; u_g_table[i] = UG * i; v_g_table[i] = VG * i; v_b_table[i] = VB * i; /* keep supporting old binaries */ u_b_table[i] = UB * i; v_r_table[i] = VR * i; } /* determine best converters to use */ yuv444_to_yuy2 = yuv444_to_yuy2_c; yv12_to_yuy2 = yv12_to_yuy2_c; yuy2_to_yv12 = yuy2_to_yv12_c; yuv9_to_yv12 = yuv9_to_yv12_c; yuv411_to_yv12 = yuv411_to_yv12_c; #if defined(ARCH_X86) accel = xine_mm_accel(); if (accel & MM_ACCEL_X86_MMX) { yuv444_to_yuy2 = yuv444_to_yuy2_mmx; yv12_to_yuy2 = yv12_to_yuy2_mmx; } if (accel & MM_ACCEL_X86_MMXEXT) { yv12_to_yuy2 = yv12_to_yuy2_mmxext; yuy2_to_yv12 = yuy2_to_yv12_mmxext; } if (accel & MM_ACCEL_X86_SSE2) { yv12_to_yuy2 = yv12_to_yuy2_sse2; } #endif } /* TJ. direct sliced rgb -> yuy2 conversion */ struct rgb2yuy2_s { /* unused:1 u:21 v:21 y:21 */ uint64_t t0[256], t1[256], t2[256]; /* u:12 v:12 y:8 (rgb_pal8) */ /* native endian yuyv (other rgb_pal*) */ uint32_t p[272]; int cm, fmt, pfmt; }; typedef enum { rgb_bgr = 0, rgb_rgb, rgb_bgra, rgb_argb, rgb_rgba, rgb_rgb555le, rgb_rgb555be, rgb_rgb565le, rgb_rgb565be, rgb_bgra_clut, rgb_rgba_clut, rgb_pal8, rgb_pal4, rgb_pal2, rgb_pal1 } rgb_fmt_t; rgb2yuy2_t *rgb2yuy2_alloc (int color_matrix, const char *format) { rgb2yuy2_t *b; float kb, kr; float _ry, _gy, _by, _yoffs; float _bv, _bvoffset, _ru, _ruoffset, _gu, _guoffset, _gv, _gvoffset, _burv; int i = -1; const char *fmts[] = { "bgr", "rgb", "bgra", "argb", "rgba", "rgb555le", "rgb555be", "rgb565le", "rgb565be", "bgra_clut", "rgba_clut" }; if (format) for (i = 10; i >= 0; i--) if (!strcmp (format, fmts[i])) break; if (i < 0) return NULL; b = malloc (sizeof (*b)); if (!b) return b; b->pfmt = -1; b->fmt = i; b->cm = color_matrix; switch ((b->cm) >> 1) { case 1: kb = 0.0722; kr = 0.2126; break; /* ITU-R 709 */ case 4: kb = 0.1100; kr = 0.3000; break; /* FCC */ case 7: kb = 0.0870; kr = 0.2120; break; /* SMPTE 240 */ default: kb = 0.1140; kr = 0.2990; /* ITU-R 601 */ } if (b->cm & 1) { /* fullrange */ _ry = 8192.0 * kr; _gy = 8192.0 * (1.0 - kb - kr); _by = 8192.0 * kb; _yoffs = 8192.0 * 0.5; _burv = 4096.0 * (127.0 / 255.0); } else { /* mpeg range */ _ry = 8192.0 * (219.0 / 255.0) * kr; _gy = 8192.0 * (219.0 / 255.0) * (1.0 - kb - kr); _by = 8192.0 * (219.0 / 255.0) * kb; _yoffs = 8192.0 * 16.5; _burv = 4096.0 * (112.0 / 255.0); } _ru = _burv * (kr / (kb - 1.0)); _gu = _burv * ((1.0 - kb - kr) / (kb - 1.0)); _bv = _burv * (kb / (kr - 1.0)); _gv = _burv * ((1.0 - kb - kr) / (kr - 1.0)); switch (b->fmt) { case rgb_bgr: case rgb_rgb: case rgb_bgra: case rgb_argb: case rgb_rgba: case rgb_bgra_clut: case rgb_rgba_clut: { /* 24/32 bit */ uint64_t *rr, *gg, *bb; if ((b->fmt == rgb_bgr) || (b->fmt == rgb_bgra) || (b->fmt == rgb_bgra_clut)) { bb = b->t0; gg = b->t1; rr = b->t2; } else { rr = b->t0; gg = b->t1; bb = b->t2; } /* Split uv offsets to make all values non negative. This prevents carry between components. */ _ruoffset = -255.0 * _ru; _guoffset = 4096.0 * 128.5 - _ruoffset; _bvoffset = -255.0 * _bv; _gvoffset = 4096.0 * 128.5 - _bvoffset; for (i = 0; i < 256; i++) { rr[i] = ((uint64_t)(_ru * i + _ruoffset + 0.5) << 42) | ((uint64_t)(_burv * i + 0.5) << 21) | (uint64_t)(_ry * i + 0.5); gg[i] = ((uint64_t)(_gu * i + _guoffset + 0.5) << 42) | ((uint64_t)(_gv * i + _gvoffset + 0.5) << 21) | (uint64_t)(_gy * i + _yoffs + 0.5); bb[i] = ((uint64_t)(_burv * i + 0.5) << 42) | ((uint64_t)(_bv * i + _bvoffset + 0.5) << 21) | (uint64_t)(_by * i + 0.5); } } break; case rgb_rgb555le: case rgb_rgb555be: { /* 15 bit */ uint64_t *hi, *lo; float _uloffset, _uhoffset, _vloffset, _vhoffset; /* A little more preparation for Verrifast Plain Co. */ if (b->fmt == rgb_rgb555le) { lo = b->t0; hi = b->t1; } else { hi = b->t0; lo = b->t1; } /* gl <= 0x39, gh <= 0xc6 - see below */ _uloffset = -(float)0x39 * _gu; _uhoffset = 4096.0 * 128.5 - _uloffset; _vhoffset = -(float)0xc6 * _gv; _vloffset = 4096.0 * 128.5 - _vhoffset; for (i = 0; i < 256; i++) { int rr, gl, gh, bb; /* extract rgb parts from high byte */ rr = (i << 1) & 0xf8; gh = (i << 6) & 0xc0; /* and from low byte */ gl = (i >> 2) & 0x38; bb = (i << 3) & 0xf8; /* scale them to 8 bits */ rr |= rr >> 5; gl |= gl >> 5; gh |= gh >> 5; bb |= bb >> 5; /* setup low byte lookup */ lo[i] = ((uint64_t)(_burv * bb + _gu * gl + _uloffset + 0.5) << 42) | ((uint64_t)( _bv * bb + _gv * gl + _vloffset + 0.5) << 21) | (uint64_t)( _by * bb + _gy * gl + 0.5); /* and high byte */ hi[i] = ((uint64_t)( _ru * rr + _gu * gh + _uhoffset + 0.5) << 42) | ((uint64_t)(_burv * rr + _gv * gh + _vhoffset + 0.5) << 21) | (uint64_t)( _ry * rr + _gy * gh + _yoffs + 0.5); } } break; case rgb_rgb565le: case rgb_rgb565be: { /* 16 bit */ uint64_t *lo, *hi; float _uloffset, _uhoffset, _vloffset, _vhoffset; /* Much like 15 bit */ if (b->fmt == rgb_rgb565le) { lo = b->t0; hi = b->t1; } else { hi = b->t0; lo = b->t1; } /* gl <= 0x1c, gh <= 0xe3 - see below */ _uloffset = -(float)0x1c * _gu; _uhoffset = 4096.0 * 128.5 - _uloffset; _vhoffset = -(float)0xe3 * _gv; _vloffset = 4096.0 * 128.5 - _vhoffset; for (i = 0; i < 256; i++) { int rr, gl, gh, bb; /* extract rgb parts from high byte */ rr = i & 0xf8; gh = (i << 5) & 0xe0; /* and from low byte */ gl = (i >> 3) & 0x1c; bb = (i << 3) & 0xf8; /* scale them to 8 bits */ rr |= rr >> 5; gh |= gh >> 6; bb |= bb >> 5; /* setup low byte lookup */ lo[i] = ((uint64_t)(_burv * bb + _gu * gl + _uloffset + 0.5) << 42) | ((uint64_t)( _bv * bb + _gv * gl + _vloffset + 0.5) << 21) | (uint64_t)( _by * bb + _gy * gl + 0.5); /* and high byte */ hi[i] = ((uint64_t)( _ru * rr + _gu * gh + _uhoffset + 0.5) << 42) | ((uint64_t)(_burv * rr + _gv * gh + _vhoffset + 0.5) << 21) | (uint64_t)( _ry * rr + _gy * gh + _yoffs + 0.5); } } break; default: ; } return b; } void rgb2yuy2_free (rgb2yuy2_t *rgb2yuy2) { free (rgb2yuy2); } void rgb2yuy2_palette (rgb2yuy2_t *rgb2yuy2, const uint8_t *pal, int num_colors, int bits_per_pixel) { rgb2yuy2_t *b = rgb2yuy2; uint64_t v; uint32_t w, *p; int mode, i = 0, max_colors; if (!b || (num_colors < 2)) return; switch (bits_per_pixel) { case 8: mode = rgb_pal8; max_colors = 256; p = b->p; break; case 4: mode = rgb_pal4; max_colors = 16; p = b->p + 256; break; case 2: mode = rgb_pal2; max_colors = 4; p = b->p + 256; break; case 1: mode = rgb_pal1; max_colors = 2; p = b->p + 256; break; default: return; } if (num_colors > max_colors) num_colors = max_colors; /* fmt now refers to the format of the _palette_ */ if (b->pfmt == -1) b->pfmt = b->fmt; b->fmt = mode; /* default grays */ if (!pal) { for (i = 0; i < num_colors; i++) { w = (i * 255 + (num_colors - 1) / 2) / (num_colors - 1); v = b->t0[w] + b->t1[w] + b->t2[w]; p[i] = ((v >> 31) & 0xfff00000) | ((v >> 22) & 0xfff00) | ((v >> 13) & 0xff); } } else /* convert palette */ switch (b->pfmt) { case rgb_bgr: case rgb_rgb: for (i = 0; i < num_colors; i++) { v = b->t0[*pal++]; v += b->t1[*pal++]; v += b->t2[*pal++]; p[i] = ((v >> 31) & 0xfff00000) | ((v >> 22) & 0xfff00) | ((v >> 13) & 0xff); } break; case rgb_argb: pal++; /* fall through */ case rgb_bgra: case rgb_rgba: for (i = 0; i < num_colors; i++) { v = b->t0[*pal++]; v += b->t1[*pal++]; v += b->t2[*pal]; pal += 2; p[i] = ((v >> 31) & 0xfff00000) | ((v >> 22) & 0xfff00) | ((v >> 13) & 0xff); } break; default: ; } /* black pad rest of palette */ v = b->t0[0] + b->t1[0] + b->t2[0]; w = ((v >> 31) & 0xfff00000) | ((v >> 22) & 0xfff00) | ((v >> 13) & 0xff); for (; i < max_colors; i++) p[i] = w; /* more optimization ahead? */ if (mode != rgb_pal8) { union {uint8_t bytes[4]; uint32_t word;} tmp; switch (mode) { case rgb_pal4: for (i = 0; i < 256; i++) { w = p[i >> 4]; tmp.bytes[0] = w; /* y1 */ w &= ~255; w += p[i & 15]; tmp.bytes[1] = w >> 24; /* u */ tmp.bytes[2] = w; /* y2 */ tmp.bytes[3] = w >> 12; /* v */ b->p[i] = tmp.word; } break; case rgb_pal2: for (i = 0; i < 16; i++) { w = p[i >> 2]; tmp.bytes[0] = w; /* y1 */ w &= ~255; w += p[i & 3]; tmp.bytes[1] = w >> 24; /* u */ tmp.bytes[2] = w; /* y2 */ tmp.bytes[3] = w >> 12; /* v */ b->p[i] = tmp.word; } break; case rgb_pal1: for (i = 0; i < 4; i++) { w = p[i >> 1]; tmp.bytes[0] = w; /* y1 */ w &= ~255; w += p[i & 1]; tmp.bytes[1] = w >> 24; /* u */ tmp.bytes[2] = w; /* y2 */ tmp.bytes[3] = w >> 12; /* v */ b->p[i] = tmp.word; } break; default: ; } } } #ifdef ARCH_X86_32 /* gcc 4.5 appearantly does not see this optimization: * One half of value is eough to get all required bits. * Saves at least 1 register within 2 loops. * 27% faster!! */ # define GET_Y(v) ((uint32_t)(v) >> 13) # define GET_U(v) ((uint32_t)(v >> 32) >> 23) # define GET_V(v) ((uint32_t)(v >> 32) >> 2) #else # define GET_Y(v) ((v) >> 13) # define GET_U(v) ((v) >> 55) # define GET_V(v) ((v) >> 34) #endif void rgb2yuy2_slice (rgb2yuy2_t *rgb2yuy2, const uint8_t *restrict in, int ipitch, uint8_t *restrict out, int opitch, int width, int height) { rgb2yuy2_t *b = rgb2yuy2; uint64_t v; uint32_t w; int ipad, opad; int x, y; if (!b) return; width &= ~1; opad = opitch - 2 * width; switch (b->fmt) { case rgb_bgr: case rgb_rgb: ipad = ipitch - 3 * width; for (y = height; y; y--) { for (x = width / 2; x; x--) { v = b->t0[*in++]; v += b->t1[*in++]; v += b->t2[*in++]; *out++ = GET_Y(v); /* y1 */ v &= ~0x1fffffLL; v += b->t0[*in++]; v += b->t1[*in++]; v += b->t2[*in++]; *out++ = GET_U(v); /* u */ *out++ = GET_Y(v); /* y2 */ *out++ = GET_V(v); /* v */ } in += ipad; out += opad; } break; case rgb_argb: in++; /* fall through */ case rgb_bgra: case rgb_rgba: ipad = ipitch - 4 * width; for (y = height; y; y--) { for (x = width / 2; x; x--) { v = b->t0[*in++]; v += b->t1[*in++]; v += b->t2[*in]; in += 2; *out++ = GET_Y(v); /* y1 */ v &= ~0x1fffffLL; v += b->t0[*in++]; v += b->t1[*in++]; v += b->t2[*in]; in += 2; *out++ = GET_U(v); /* u */ *out++ = GET_Y(v); /* y2 */ *out++ = GET_V(v); /* v */ } in += ipad; out += opad; } break; case rgb_rgb555le: case rgb_rgb565le: case rgb_rgb555be: case rgb_rgb565be: ipad = ipitch - 2 * width; for (y = height; y; y--) { for (x = width / 2; x; x--) { v = b->t0[*in++]; v += b->t1[*in++]; *out++ = GET_Y(v); /* y1 */ v &= ~0x1fffffLL; v += b->t0[*in++]; v += b->t1[*in++]; *out++ = GET_U(v); /* u */ *out++ = GET_Y(v); /* y2 */ *out++ = GET_V(v); /* v */ } in += ipad; out += opad; } break; case rgb_pal8: ipad = ipitch - width; for (y = height; y; y--) { for (x = width / 2; x; x--) { w = b->p[*in++]; *out++ = w; /* y1 */ w &= ~0xffL; w += b->p[*in++]; *out++ = w >> 24; /* u */ *out++ = w; /* y2 */ *out++ = w >> 12; /* v */ } in += ipad; out += opad; } break; case rgb_pal4: ipad = ipitch - (width / 2); for (y = height; y; y--) { uint32_t *o2 = (uint32_t *)ALIGN4(out); for (x = width / 2; x; x--) *o2++ = b->p[*in++]; in += ipad; out += opitch; } break; case rgb_pal2: ipad = ipitch - (width / 4); for (y = height; y; y--) { uint32_t *o2 = (uint32_t *)ALIGN4(out); for (x = width / 4; x; x--) { *o2++ = b->p[(*in) >> 4]; *o2++ = b->p[(*in++) & 15]; } if (width & 3) *o2++ = b->p[(*in) >> 4]; in += ipad; out += opitch; } break; case rgb_pal1: ipad = ipitch - (width / 8); for (y = height; y; y--) { uint32_t *o2 = (uint32_t *)ALIGN4(out); for (x = width / 8; x; x--) { *o2++ = b->p[(*in) >> 6]; *o2++ = b->p[((*in) >> 4) & 3]; *o2++ = b->p[((*in) >> 2) & 3]; *o2++ = b->p[(*in++) & 3]; } x = width & 7; if (x) { *o2++ = b->p[(*in) >> 6]; if (x > 2) { *o2++ = b->p[((*in) >> 4) & 3]; if (x > 4) *o2++ = b->p[((*in) >> 2) & 3]; } } in += ipad; out += opitch; } break; case rgb_rgba_clut: case rgb_bgra_clut: ipad = ipitch - 4 * width; opad = opitch - 4 * width; for (y = height; y; y--) { for (x = width; x; x--) { v = b->t0[*in++]; v += b->t1[*in++]; v += b->t2[*in++]; *out++ = GET_U(v); /* u */ *out++ = GET_V(v); /* v */ *out++ = GET_Y(v); /* y */ *out++ = *in++; /* a */ } in += ipad; out += opad; } break; } } void rgb2yv12_slice (rgb2yuy2_t *rgb2yuy2, const uint8_t *src, int src_stride, uint8_t *y_dst, int y_pitch, uint8_t *u_dst, int u_pitch, uint8_t *v_dst, int v_pitch, int width, int height) { int y, h = 16; uint8_t *yuy2; yuy2 = xine_malloc_aligned(2 * 16 * y_pitch); if (!yuy2) return; for (y = 0; y < height; y += 16) { if (y + 16 > height) h = height & 15; rgb2yuy2_slice (rgb2yuy2, src + y * src_stride, src_stride, yuy2, 2 * y_pitch, width, h); yuy2_to_yv12(yuy2, 2 * y_pitch, y_dst + y * y_pitch, y_pitch, u_dst + y/2 * u_pitch, u_pitch, v_dst + y/2 * v_pitch, v_pitch, width, h); } xine_free_aligned(yuy2); } �����������������xine-lib-1.2/src/xine-utils/xine_mmx.h��������������������������������������������������������������0000644�0001750�0001750�00000050230�14647725152�015551� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef XINE_MMX_H #define XINE_MMX_H #if defined(ARCH_X86) #include <xine/attributes.h> #if !defined(ATTRIBUTE_ALIGNED_MAX) # warning ATTRIBUTE_ALIGNED_MAX undefined. Alignment of data structures does not work ! #elif ATTRIBUTE_ALIGNED_MAX < 16 # warning Compiler does not support proper alignment for SSE2 ! #endif typedef union { int64_t q; /* Quadword (64-bit) value */ uint64_t uq; /* Unsigned Quadword */ int d[2]; /* 2 Doubleword (32-bit) values */ unsigned int ud[2]; /* 2 Unsigned Doubleword */ short w[4]; /* 4 Word (16-bit) values */ unsigned short uw[4]; /* 4 Unsigned Word */ char b[8]; /* 8 Byte (8-bit) values */ unsigned char ub[8]; /* 8 Unsigned Byte */ float s[2]; /* Single-precision (32-bit) value */ } ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ #define mmx_i2r(op,imm,reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "i" (imm) ) #define mmx_m2r(op,mem,reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "m" (mem)) /* load dword from memory or gp register */ #define mmx_a2r(op,any,reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "g" (any)) #define mmx_r2m(op,reg,mem) \ __asm__ __volatile__ (#op " %%" #reg ", %0" \ : "=m" (mem) \ : /* nothing */ ) #define mmx_r2a(op,reg,any) \ __asm__ __volatile__ (#op " %%" #reg ", %0" \ : "=g" (any) \ : /* nothing */ ) #define mmx_r2r(op,regs,regd) \ __asm__ __volatile__ (#op " %" #regs ", %" #regd) #define emms() __asm__ __volatile__ ("emms") #define movd_m2r(var,reg) mmx_m2r (movd, var, reg) #define movd_r2m(reg,var) mmx_r2m (movd, reg, var) #define movd_r2r(regs,regd) mmx_r2r (movd, regs, regd) #define movd_a2r(any,reg) mmx_a2r (movd, any, reg) #define movd_r2a(reg,any) mmx_r2a (movd, reg, any) #define movq_m2r(var,reg) mmx_m2r (movq, var, reg) #define movq_r2m(reg,var) mmx_r2m (movq, reg, var) #define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) #define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) #define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) #define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) #define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) #define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) #define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) #define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) #define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) #define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) #define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) #define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) #define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) #define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) #define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) #define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) #define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) #define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) #define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) #define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) #define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) #define pand_m2r(var,reg) mmx_m2r (pand, var, reg) #define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) #define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) #define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) #define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) #define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) #define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) #define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) #define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) #define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) #define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) #define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) #define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) #define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) #define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) #define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) #define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) #define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) #define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) #define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) #define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) #define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) #define por_m2r(var,reg) mmx_m2r (por, var, reg) #define por_r2r(regs,regd) mmx_r2r (por, regs, regd) #define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) #define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) #define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) #define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) #define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) #define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) #define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) #define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) #define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) #define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) #define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) #define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) #define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) #define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) #define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) #define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) #define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) #define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) #define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) #define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) #define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) #define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) #define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) #define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) #define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) #define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) #define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) #define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) #define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) #define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) #define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) #define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) #define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) #define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) #define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) #define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) #define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) #define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) #define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) #define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) #define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) #define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) #define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) #define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) #define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) #define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) #define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) #define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) #define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) #define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) #define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) #define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) /* 3DNOW extensions */ #define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) #define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) /* AMD MMX extensions - also available in intel SSE */ #define mmx_m2ri(op,mem,reg,imm) \ __asm__ __volatile__ (#op " %1, %0, %%" #reg \ : /* nothing */ \ : "X" (mem), "X" (imm)) #define mmx_r2ri(op,regs,regd,imm) \ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ : /* nothing */ \ : "X" (imm) ) #define mmx_fetch(mem,hint) \ __asm__ __volatile__ ("prefetch" #hint " %0" \ : /* nothing */ \ : "X" (mem)) #define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) #define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) #define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) #define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) #define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) #define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) #define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) #define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) #define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) #define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) #define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) #define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) #define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) #define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) #define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) #define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) #define pmovmskb(mmreg,reg) \ __asm__ __volatile__ ("pmovmskb %" #mmreg ", %" #reg) #define pmovmskb_r2a(mmreg,regvar) \ __asm__ __volatile__ ("pmovmskb %%" #mmreg ", %0" : "=r" (regvar)) #define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) #define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) #define prefetcht0(mem) mmx_fetch (mem, t0) #define prefetcht1(mem) mmx_fetch (mem, t1) #define prefetcht2(mem) mmx_fetch (mem, t2) #define prefetchnta(mem) mmx_fetch (mem, nta) #define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) #define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) #define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) #define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) #define sfence() __asm__ __volatile__ ("sfence\n\t") typedef union { int64_t q[2]; /* Quadword (64-bit) value */ uint64_t uq[2]; /* Unsigned Quadword */ int32_t d[4]; /* Doubleword (32-bit) values */ uint32_t ud[4]; /* Unsigned Doubleword */ short w[8]; /* Word (16-bit) values */ unsigned short uw[8]; /* Unsigned Word */ char b[16]; /* Byte (8-bit) values */ unsigned char ub[16]; /* Unsigned Byte */ float sf[4]; /* Single-precision (32-bit) value */ } ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */ #define FILL_SSE_UW(w) {uw:{w,w,w,w,w,w,w,w}} #define sse_i2r(op, imm, reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "X" (imm) ) #define sse_m2r(op, mem, reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "X" (mem)) #define sse_r2m(op, reg, mem) \ __asm__ __volatile__ (#op " %%" #reg ", %0" \ : "=X" (mem) \ : /* nothing */ ) #define sse_r2r(op, regs, regd) \ __asm__ __volatile__ (#op " %" #regs ", %" #regd) #define sse_r2ri(op, regs, regd, imm) \ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ : /* nothing */ \ : "X" (imm) ) #define sse_m2ri(op, mem, reg, subop) \ __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \ : /* nothing */ \ : "X" (mem)) #define movaps_m2r(var, reg) sse_m2r(movaps, var, reg) #define movaps_r2m(reg, var) sse_r2m(movaps, reg, var) #define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd) #define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var) #define movups_m2r(var, reg) sse_m2r(movups, var, reg) #define movups_r2m(reg, var) sse_r2m(movups, reg, var) #define movups_r2r(regs, regd) sse_r2r(movups, regs, regd) #define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd) #define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd) #define movhps_m2r(var, reg) sse_m2r(movhps, var, reg) #define movhps_r2m(reg, var) sse_r2m(movhps, reg, var) #define movlps_m2r(var, reg) sse_m2r(movlps, var, reg) #define movlps_r2m(reg, var) sse_r2m(movlps, reg, var) #define movss_m2r(var, reg) sse_m2r(movss, var, reg) #define movss_r2m(reg, var) sse_r2m(movss, reg, var) #define movss_r2r(regs, regd) sse_r2r(movss, regs, regd) #define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index) #define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index) #define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg) #define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg) #define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg) #define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg) #define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg) #define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg) #define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg) #define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg) #define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) #define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) #define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) #define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) #define movmskps(xmmreg, reg) \ __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg) #define addps_m2r(var, reg) sse_m2r(addps, var, reg) #define addps_r2r(regs, regd) sse_r2r(addps, regs, regd) #define addss_m2r(var, reg) sse_m2r(addss, var, reg) #define addss_r2r(regs, regd) sse_r2r(addss, regs, regd) #define subps_m2r(var, reg) sse_m2r(subps, var, reg) #define subps_r2r(regs, regd) sse_r2r(subps, regs, regd) #define subss_m2r(var, reg) sse_m2r(subss, var, reg) #define subss_r2r(regs, regd) sse_r2r(subss, regs, regd) #define mulps_m2r(var, reg) sse_m2r(mulps, var, reg) #define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd) #define mulss_m2r(var, reg) sse_m2r(mulss, var, reg) #define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd) #define divps_m2r(var, reg) sse_m2r(divps, var, reg) #define divps_r2r(regs, regd) sse_r2r(divps, regs, regd) #define divss_m2r(var, reg) sse_m2r(divss, var, reg) #define divss_r2r(regs, regd) sse_r2r(divss, regs, regd) #define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg) #define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd) #define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg) #define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd) #define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg) #define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd) #define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg) #define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd) #define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg) #define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd) #define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg) #define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd) #define andps_m2r(var, reg) sse_m2r(andps, var, reg) #define andps_r2r(regs, regd) sse_r2r(andps, regs, regd) #define andnps_m2r(var, reg) sse_m2r(andnps, var, reg) #define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd) #define orps_m2r(var, reg) sse_m2r(orps, var, reg) #define orps_r2r(regs, regd) sse_r2r(orps, regs, regd) #define xorps_m2r(var, reg) sse_m2r(xorps, var, reg) #define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd) #define maxps_m2r(var, reg) sse_m2r(maxps, var, reg) #define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd) #define maxss_m2r(var, reg) sse_m2r(maxss, var, reg) #define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd) #define minps_m2r(var, reg) sse_m2r(minps, var, reg) #define minps_r2r(regs, regd) sse_r2r(minps, regs, regd) #define minss_m2r(var, reg) sse_m2r(minss, var, reg) #define minss_r2r(regs, regd) sse_r2r(minss, regs, regd) #define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op) #define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op) #define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0) #define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0) #define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1) #define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1) #define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2) #define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2) #define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3) #define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3) #define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4) #define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4) #define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5) #define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5) #define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6) #define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6) #define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7) #define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7) #define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op) #define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op) #define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0) #define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0) #define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1) #define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1) #define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2) #define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2) #define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3) #define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3) #define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4) #define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4) #define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5) #define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5) #define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6) #define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6) #define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7) #define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7) #define comiss_m2r(var, reg) sse_m2r(comiss, var, reg) #define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd) #define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg) #define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd) #define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg) #define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd) #define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg) #define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd) #define fxrstor(mem) \ __asm__ __volatile__ ("fxrstor %0" \ : /* nothing */ \ : "X" (mem)) #define fxsave(mem) \ __asm__ __volatile__ ("fxsave %0" \ : /* nothing */ \ : "X" (mem)) #define stmxcsr(mem) \ __asm__ __volatile__ ("stmxcsr %0" \ : /* nothing */ \ : "X" (mem)) #define ldmxcsr(mem) \ __asm__ __volatile__ ("ldmxcsr %0" \ : /* nothing */ \ : "X" (mem)) /* SSE2 */ #define movdqa_m2r(var, reg) mmx_m2r (movdqa, var, reg) #define movdqa_r2m(reg, var) mmx_r2m (movdqa, reg, var) #define movdqa_r2r(regs, regd) mmx_r2r (movdqa, regs, regd) #define movdqu_m2r(var, reg) mmx_m2r (movdqu, var, reg) #define movdqu_r2m(reg, var) mmx_r2m (movdqu, reg, var) #define pslldq_i2r(imm,reg) mmx_i2r (pslldq, imm, reg) #define psrldq_i2r(imm,reg) mmx_i2r (psrldq, imm, reg) #define pshufd_m2r(var, reg, imm) mmx_m2ri (pshufd, var, reg, imm) #define pshufd_r2r(regs, regd, imm) mmx_r2ri (pshufd, regs, regd, imm) #define pshuflw_m2r(var, reg, imm) mmx_m2ri (pshuflw, var, reg, imm) #define pshuflw_r2r(regs, regd, imm) mmx_r2ri (pshuflw, regs, regd, imm) /* SSSE3 */ #define pmaddubsw_r2r(regs, regd) mmx_r2r(pmaddubsw, regs, regd) #endif /*ARCH_X86 */ #endif /*XINE_MMX_H*/ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/xmllexer.c��������������������������������������������������������������0000644�0001750�0001750�00000035142�14647725152�015565� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2002-2021 the xine project * * This file is part of xine, a free video player. * * The xine-lib XML parser is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * The xine-lib XML parser is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with the Gnome Library; see the file COPYING.LIB. If not, * write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110, USA */ #define LOG_MODULE "xmllexer" #define LOG_VERBOSE /* #define LOG */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef XINE_COMPILE #include <xine/xineutils.h> #else #define lprintf(...) #endif #include <xine/xmllexer.h> #include <stdio.h> #include <ctype.h> #include <string.h> #include <stdlib.h> #ifdef HAVE_ICONV #include <iconv.h> #endif #include "bswap.h" #include "xine_private.h" /* private constants*/ /* private global variables */ struct lexer * static_lexer; enum utf { UTF32BE, UTF32LE, UTF16BE, UTF16LE }; static void lex_convert (struct lexer * lexer, const char * buf, int size, enum utf utf) { char *utf8 = malloc (size * (utf >= UTF16BE ? 3 : 6) + 1); char *bp = utf8; while (size > 0) { uint32_t c = 0; switch (utf) { case UTF32BE: c = _X_BE_32 (buf); buf += 4; break; case UTF32LE: c = _X_LE_32 (buf); buf += 4; break; case UTF16BE: c = _X_BE_16 (buf); buf += 2; break; case UTF16LE: c = _X_LE_16 (buf); buf += 2; break; } if (!c) break; /* embed a NUL, get a truncated string */ if (c < 128) *bp++ = c; else { int count = (c >= 0x04000000) ? 5 : (c >= 0x00200000) ? 4 : (c >= 0x00010000) ? 3 : (c >= 0x00000800) ? 2 : 1; *bp = (char)(0x1F80 >> count); count *= 6; *bp++ |= c >> count; while ((count -= 6) >= 0) *bp++ = 128 | ((c >> count) & 0x3F); } } *bp = 0; lexer->lexbuf_size = bp - utf8; lexer->lexbuf = lexer->lex_malloc = realloc (utf8, lexer->lexbuf_size + 1); } /* for ABI compatibility */ void lexer_init(const char * buf, int size) { if (static_lexer) { lexer_finalize_r(static_lexer); } static_lexer = lexer_init_r(buf, size); } enum { NORMAL, DATA, CDATA, }; struct lexer *lexer_init_r(const char * buf, int size) { static const uint8_t boms[] = { 0xFF, 0xFE, 0, 0, 0xFE, 0xFF }; static const uint8_t bom_utf8[] = { 0xEF, 0xBB, 0xBF }; struct lexer * lexer = calloc (1, sizeof (*lexer)); if (!lexer) { return NULL; } lexer->lexbuf = buf; lexer->lexbuf_size = size; if (size >= 4 && !memcmp (buf, boms + 2, 4)) lex_convert (lexer, buf + 4, size - 4, UTF32BE); else if (size >= 4 && !memcmp (buf, boms, 4)) lex_convert (lexer, buf + 4, size - 4, UTF32LE); else if (size >= 3 && !memcmp (buf, bom_utf8, 3)) { lexer->lexbuf += 3; lexer->lexbuf_size -= 3; } else if (size >= 2 && !memcmp (buf, boms + 4, 2)) lex_convert (lexer, buf + 2, size - 2, UTF16BE); else if (size >= 2 && !memcmp (buf, boms, 2)) lex_convert (lexer, buf + 2, size - 2, UTF16LE); lexer->lexbuf_pos = 0; lexer->lex_mode = NORMAL; lexer->in_comment = 0; lprintf("buffer length %d\n", size); return lexer; } void lexer_finalize_r(struct lexer * lexer) { _x_freep(&lexer->lex_malloc); free(lexer); } typedef enum { STATE_UNKNOWN = -1, STATE_IDLE, STATE_EOL, STATE_SEPAR, STATE_T_M_START, STATE_T_M_STOP_1, STATE_T_M_STOP_2, STATE_T_EQUAL, STATE_T_STRING_SINGLE, STATE_T_STRING_DOUBLE, STATE_T_COMMENT, STATE_T_TI_STOP, STATE_T_DASHDASH, STATE_T_C_STOP, STATE_IDENT /* must be last */ } lexer_state_t; /* for ABI compatibility */ int lexer_get_token_d(char ** _tok, int * _tok_size, int fixed) { return lexer_get_token_d_r(static_lexer, _tok, _tok_size, fixed); } int lexer_get_token_d_r(struct lexer * lexer, char ** _tok, int * _tok_size, int fixed) { char *tok = *_tok; int tok_size = *_tok_size; int tok_pos = 0; lexer_state_t state = STATE_IDLE; char c; if (tok) { while ((tok_pos + 8 < tok_size) && (lexer->lexbuf_pos < lexer->lexbuf_size)) { c = lexer->lexbuf[lexer->lexbuf_pos]; lprintf("c=%c, state=%d, in_comment=%d\n", c, state, lexer->in_comment); switch (lexer->lex_mode) { case NORMAL: switch (state) { /* init state */ case STATE_IDLE: switch (c) { case '\n': case '\r': state = STATE_EOL; tok[tok_pos] = c; tok_pos++; break; case ' ': case '\t': state = STATE_SEPAR; tok[tok_pos] = c; tok_pos++; break; case '<': state = STATE_T_M_START; tok[tok_pos] = c; tok_pos++; break; case '>': state = STATE_T_M_STOP_1; tok[tok_pos] = c; tok_pos++; break; case '/': if (!lexer->in_comment) state = STATE_T_M_STOP_2; tok[tok_pos] = c; tok_pos++; break; case '=': state = STATE_T_EQUAL; tok[tok_pos] = c; tok_pos++; break; case '\"': /* " */ state = STATE_T_STRING_DOUBLE; break; case '\'': /* " */ state = STATE_T_STRING_SINGLE; break; case '-': state = STATE_T_DASHDASH; tok[tok_pos] = c; tok_pos++; break; case '?': if (!lexer->in_comment) state = STATE_T_TI_STOP; tok[tok_pos] = c; tok_pos++; break; default: state = STATE_IDENT; tok[tok_pos] = c; tok_pos++; break; } lexer->lexbuf_pos++; break; /* end of line */ case STATE_EOL: if (c == '\n' || (c == '\r')) { tok[tok_pos] = c; lexer->lexbuf_pos++; tok_pos++; } else { tok[tok_pos] = '\0'; return T_EOL; } break; /* T_SEPAR */ case STATE_SEPAR: if (c == ' ' || (c == '\t')) { tok[tok_pos] = c; lexer->lexbuf_pos++; tok_pos++; } else { tok[tok_pos] = '\0'; return T_SEPAR; } break; /* T_M_START < or </ or <! or <? */ case STATE_T_M_START: switch (c) { case '/': tok[tok_pos] = c; lexer->lexbuf_pos++; tok_pos++; tok[tok_pos] = '\0'; return T_M_START_2; break; case '!': tok[tok_pos] = c; lexer->lexbuf_pos++; tok_pos++; state = STATE_T_COMMENT; break; case '?': tok[tok_pos] = c; lexer->lexbuf_pos++; tok_pos++; tok[tok_pos] = '\0'; return T_TI_START; break; default: tok[tok_pos] = '\0'; return T_M_START_1; } break; /* T_M_STOP_1 */ case STATE_T_M_STOP_1: tok[tok_pos] = '\0'; if (!lexer->in_comment) lexer->lex_mode = DATA; return T_M_STOP_1; break; /* T_M_STOP_2 */ case STATE_T_M_STOP_2: if (c == '>') { tok[tok_pos] = c; lexer->lexbuf_pos++; tok_pos++; tok[tok_pos] = '\0'; if (!lexer->in_comment) lexer->lex_mode = DATA; return T_M_STOP_2; } else { tok[tok_pos] = '\0'; return T_ERROR; } break; /* T_EQUAL */ case STATE_T_EQUAL: tok[tok_pos] = '\0'; return T_EQUAL; break; /* T_STRING */ case STATE_T_STRING_DOUBLE: tok[tok_pos] = c; lexer->lexbuf_pos++; if (c == '\"') { /* " */ tok[tok_pos] = '\0'; /* FIXME */ return T_STRING; } tok_pos++; break; /* T_C_START or T_DOCTYPE_START or T_CDATA_START */ case STATE_T_COMMENT: switch (c) { case '-': lexer->lexbuf_pos++; if (lexer->lexbuf[lexer->lexbuf_pos] == '-') { lexer->lexbuf_pos++; tok[tok_pos++] = '-'; tok[tok_pos++] = '-'; tok[tok_pos] = '\0'; lexer->in_comment = 1; return T_C_START; } break; case 'D': lexer->lexbuf_pos++; if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "OCTYPE", 6) == 0) { strcpy(tok + tok_pos, "DOCTYPE"); /* FIXME */ lexer->lexbuf_pos += 6; return T_DOCTYPE_START; } else { return T_ERROR; } break; case '[': lexer->lexbuf_pos++; if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "CDATA[", 6) == 0) { strcpy (tok + tok_pos, "[CDATA["); /* FIXME */ lexer->lexbuf_pos += 6; lexer->lex_mode = CDATA; return T_CDATA_START; } else{ return T_ERROR; } break; default: /* error */ return T_ERROR; } break; /* T_TI_STOP */ case STATE_T_TI_STOP: if (c == '>') { tok[tok_pos] = c; lexer->lexbuf_pos++; tok_pos++; tok[tok_pos] = '\0'; if (!lexer->in_comment) lexer->lex_mode = DATA; return T_TI_STOP; } else { tok[tok_pos] = '\0'; return T_ERROR; } break; /* -- */ case STATE_T_DASHDASH: switch (c) { case '-': tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; state = STATE_T_C_STOP; break; default: tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; state = STATE_IDENT; } break; /* --> */ case STATE_T_C_STOP: switch (c) { case '>': tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; tok[tok_pos] = '\0'; /* FIXME */ if (strlen(tok) != 3) { tok[tok_pos - 3] = '\0'; lexer->lexbuf_pos -= 3; return T_IDENT; } else { lexer->in_comment = 0; return T_C_STOP; } break; default: tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; state = STATE_IDENT; } break; /* T_STRING (single quotes) */ case STATE_T_STRING_SINGLE: tok[tok_pos] = c; lexer->lexbuf_pos++; if (c == '\'') { /* " */ tok[tok_pos] = '\0'; /* FIXME */ return T_STRING; } tok_pos++; break; /* IDENT */ case STATE_IDENT: switch (c) { case '<': case '>': case '\\': case '\"': /* " */ case ' ': case '\t': case '\n': case '\r': case '=': case '/': tok[tok_pos] = '\0'; return T_IDENT; break; case '?': tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; state = STATE_T_TI_STOP; break; case '-': tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; state = STATE_T_DASHDASH; break; default: tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; } break; default: lprintf("expected char \'%c\'\n", tok[tok_pos - 1]); /* FIX ME */ return T_ERROR; } break; case DATA: /* data mode, stop if char equal '<' */ switch (c) { case '<': tok[tok_pos] = '\0'; lexer->lex_mode = NORMAL; return T_DATA; default: tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; } break; case CDATA: /* cdata mode, stop if next token is "]]>" */ switch (c) { case ']': if (strncmp(lexer->lexbuf + lexer->lexbuf_pos, "]]>", 3) == 0) { lexer->lexbuf_pos += 3; lexer->lex_mode = DATA; tok[tok_pos] = '\0'; return T_CDATA_STOP; } else { tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; } break; default: tok[tok_pos] = c; tok_pos++; lexer->lexbuf_pos++; } break; } } lprintf ("loop done tok_pos = %d, tok_size=%d, lexbuf_pos=%d, lexbuf_size=%d\n", tok_pos, tok_size, lexer->lexbuf_pos, lexer->lexbuf_size); /* pb */ if (tok_pos + 8 >= tok_size) { char *tmp_tok; int new_size; if (fixed) return T_ERROR; new_size = *_tok_size * 2; tmp_tok = realloc (*_tok, new_size); lprintf("token buffer is too small (need %d)\n", tok_pos); lprintf("increasing buffer size to %d bytes\n", *_tok_size); if (tmp_tok) { *_tok = tmp_tok; memset (*_tok + tok_size, 0, new_size - tok_size); *_tok_size = new_size; return lexer_get_token_d_r (lexer, _tok, _tok_size, 0); } else { return T_ERROR; } } else { if (lexer->lexbuf_pos >= lexer->lexbuf_size) { /* Terminate the current token */ tok[tok_pos] = '\0'; switch (state) { case STATE_IDLE: case STATE_EOL: case STATE_SEPAR: return T_EOF; break; case STATE_T_M_START: return T_M_START_1; break; case STATE_T_M_STOP_1: return T_M_STOP_1; break; case STATE_T_M_STOP_2: return T_ERROR; break; case STATE_T_EQUAL: return T_EQUAL; break; case STATE_T_STRING_SINGLE: case STATE_T_STRING_DOUBLE: return T_STRING; break; case STATE_IDENT: return T_DATA; break; default: lprintf("unknown state, state=%d\n", state); } } else { lprintf("abnormal end of buffer, state=%d\n", state); } } return T_ERROR; } /* tok == null */ lprintf("token buffer is null\n"); return T_ERROR; } /* for ABI compatibility */ int lexer_get_token (char *tok, int tok_size) { return lexer_get_token_d_r (static_lexer, &tok, &tok_size, 1); } static struct { char code; unsigned char namelen; char name[6]; } lexer_entities[] = { { '"', 4, "quot" }, { '&', 3, "amp" }, { '\'', 4, "apos" }, { '<', 2, "lt" }, { '>', 2, "gt" }, { '\0', 0, "" } }; char *lexer_decode_entities (const char *tok) { char *buf = calloc (strlen (tok) + 1, sizeof(char)); char *bp = buf; char c; if (!buf) return NULL; while ((c = *tok++)) { if (c != '&') *bp++ = c; else { /* parse the character entity (on failure, treat it as literal text) */ const char *tp = tok; signed long i; for (i = 0; lexer_entities[i].code; ++i) if (!strncmp (lexer_entities[i].name, tok, lexer_entities[i].namelen) && tok[lexer_entities[i].namelen] == ';') break; if (lexer_entities[i].code) { tok += lexer_entities[i].namelen + 1; *bp++ = lexer_entities[i].code; continue; } if (*tp++ != '#') { /* not a recognised name and not numeric */ *bp++ = '&'; continue; } /* entity is a number * (note: strtol() allows "0x" prefix for hexadecimal, but we don't) */ char *end; if (*tp == 'x' && tp[1] && tp[2] != 'x') i = strtol (tp + 1, &end, 16); else i = strtol (tp, &end, 10); if (*end != ';' || i < 1) { /* out of range, or format error */ *bp++ = '&'; continue; } tok = end + 1; if (i < 128) /* ASCII - store as-is */ *bp++ = i; else { /* Non-ASCII, so convert to UTF-8 */ int count = (i >= 0x04000000) ? 5 : (i >= 0x00200000) ? 4 : (i >= 0x00010000) ? 3 : (i >= 0x00000800) ? 2 : 1; *bp = (char)(0x1F80 >> count); count *= 6; *bp++ |= i >> count; while ((count -= 6) >= 0) *bp++ = 128 | ((i >> count) & 0x3F); } } } *bp = 0; return buf; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/stree.c�����������������������������������������������������������������0000644�0001750�0001750�00000057533�14647725152�015057� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2021 the xine project * Copyright (C) 2021 Torsten Jager <t.jager@gmx.de> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Xine string tree library. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef TEST_THIS_FILE # include "../../include/xine/stree.h" #else # include <xine/stree.h> #endif /* 128: not a hex digit, 64: value separator, 32: -x placeholder */ static const uint8_t _tab_unhex[256] = { 128,128,128,128,128,128,128,128,128,192,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 192,128,128,128,128,128,128,128,128,128,128,128,128,192,128,128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,192,128,128,128,128,128, 128, 10, 11, 12, 13, 14, 15,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128, 10, 11, 12, 13, 14, 15,161,162,163,164,165,166,167,168,169, 170,171,172,173,174,175,176,177,178,179,180,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128, 128,128,128,128,128,128,128,128,128,128,128,128,128,128,128,128 }; size_t xine_string_unpercent (char *s) { const uint8_t *p = (const uint8_t *)s; uint8_t *q, v; /* optimization: skip identical write */ while (*p && (*p != '%')) p++; q = (uint8_t *)s + (p - (const uint8_t *)s); while ((v = *p)) { p++; if (v == '%') do { uint8_t z; z = _tab_unhex[*p]; if (z & 128) break; v = z; p++; z = _tab_unhex[*p]; if (z & 128) break; v = (v << 4) | z; p++; } while (0); *q++ = v; } *q = 0; return q - (uint8_t *)s; } size_t xine_string_unbackslash (char *s) { static const uint8_t _tab_unbackslash[128] = { 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, ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', 128,129,130,131,132,133,134,135,'8','9',':',';','<','=','>','?', '@', 7, 8,194,'D', 27, 12,'G','H','I','J','K','L','M', 10,'O', 'P','Q', 13,'S', 9,193, 11,'W',192,'Y','Z','[','\\',']','^','_', '`', 7, 8,194,'d', 27, 12,'g','h','i','j','k','l','m', 10,'o', 'p','q', 13,'s', 9,193, 11,'w',192,'y','z','{','|','}','~',127 }; const uint8_t *p = (const uint8_t *)s; uint8_t *q, z; while (*p && (*p != '\\')) p++; q = (uint8_t *)s + (p - (const uint8_t *)s); while ((z = *p)) { p++; do { if (z != '\\') break; z = *p; if (!z) break; p++; if (z & 128) break; z = _tab_unbackslash[z]; if (!(z & 128)) break; if (!(z & 0x78)) { /* oktal */ uint8_t d; z &= 7; d = *p ^ '0'; if (d & 0xf8) break; z = (z << 3) | d; p++; d = *p ^ '0'; if (d & 0xf8) break; z = (z << 3) | d; p++; break; } if (z == 192) { /* x */ uint8_t v; z = p[-1]; v = _tab_unhex[*p]; if (v & 128) break; z = v; p++; v = _tab_unhex[*p]; if (v & 128) break; z = (z << 4) | v; p++; break; } if (z == 193) { /* u */ uint32_t x = p[-1]; do { z = _tab_unhex[*p]; if (z & 128) break; x = z; p++; z = _tab_unhex[*p]; if (z & 128) break; x = (x << 4) | z; p++; z = _tab_unhex[*p]; if (z & 128) break; x = (x << 4) | z; p++; z = _tab_unhex[*p]; if (z & 128) break; x = (x << 4) | z; p++; } while (0); z = x; if (x & 0xff80) { /* utf8 */ if (x & 0xf800) { /* 1110xxxx 10xxxxxx 10xxxxxx */ *q++ = 0xe0 | (x >> 12); *q++ = 0x80 | ((x >> 6) & 0x3f); } else { /* 110xxxxx 10xxxxxx */ *q++ = 0xc0 | (x >> 6); } z &= 0x3f; z |= 0x80; } break; } /* (z == 194), c */ z = p[0] & 0x1f, p++; } while (0); *q++ = z; } *q = 0; return q - (uint8_t *)s; } size_t xine_string_unampersand (char *s) { static const uint8_t _tab_amp[256] = { ['&'] = 1, [';'] = 2, ['\0'] = 128 }; uint8_t *p = (uint8_t *)s, *q; while (!(_tab_amp[*p] & (1 | 128))) p++; if (!*p) return p - (uint8_t *)s; q = p; while (1) { /* *p == '&' */ uint8_t *e = p + 1; while (!(_tab_amp[*e] & (2 | 128))) e++; if (!*e) break; *e = 0; p++; if (!strcasecmp ((const char *)p, "amp")) { *q++ = '&'; p = e + 1; } else if (!strcasecmp ((const char *)p, "lt")) { *q++ = '<'; p = e + 1; } else if (!strcasecmp ((const char *)p, "gt")) { *q++ = '>'; p = e + 1; } else if (!strcasecmp ((const char *)p, "quot")) { *q++ = '"'; p = e + 1; } else if (*p == '#') { uint32_t v = 0; uint8_t z; p++; if ((*p | 0x20) == 'x') { p++; while (!((z =_tab_unhex[*p]) & 128)) v = (v << 4) | z, p++; } else if (*p == '0') { while ((z = *p ^ '0') < 8) v = v * 8u + z, p++; } else { while ((z = *p ^ '0') < 10) v = v * 10u + z, p++; } z = v; if (v & 0xff80) { /* utf8 */ if (v & 0xf800) { /* 1110xxxx 10xxxxxx 10xxxxxx */ *q++ = 0xe0 | (v >> 12); *q++ = 0x80 | ((v >> 6) & 0x3f); } else { /* 110xxxxx 10xxxxxx */ *q++ = 0xc0 | (v >> 6); } z &= 0x3f; z |= 0x80; } *q++ = z; p = e + 1; } else { *q++ = '&'; *e = ';'; } while (!(_tab_amp[*p] & (1 | 128))) *q++ = *p++; if (!*p) break; } while (*p) *q++ = *p++; *q = 0; return q - (uint8_t *)s; } static int _xine_stree_node_new (xine_stree_t **root, uint32_t *have, uint32_t *used, uint32_t parent) { xine_stree_t *p, *n; if (*used >= *have) { xine_stree_t *new = realloc (*root, (*have + 64) * sizeof (**root)); if (!new) return 0; *root = new; *have += 64; } p = *root + parent; n = *root + *used; n->key = 0; n->value = 0; n->level = p->level + 1; n->parent = parent; n->next = 0; n->first_child = 0; n->last_child = 0; n->num_children = 0; if (p->last_child) { n->prev = p->last_child; (*root)[p->last_child].next = *used; } else { p->first_child = *used; n->prev = 0; } p->last_child = *used; p->num_children += 1; *used += 1; return *used - 1; } static uint8_t *_xine_stree_get_string (uint8_t **p, uint8_t **q, const uint8_t *tab) { uint8_t *r = *q; if (**p == '\"') { (*p)++; while (!(tab[**p] & (2 | 128))) { while (!(tab[**p] & (2 | 64 | 128))) *(*q)++ = *(*p)++; if (**p == '\\') *(*q)++ = *(*p)++; } if (**p == '\"') (*p)++; } else if (**p == '\'') { (*p)++; while (!(tab[**p] & (4 | 128))) { while (!(tab[**p] & (4 | 64 | 128))) *(*q)++ = *(*p)++; if (**p == '\\') *(*q)++ = *(*p)++; } if (**p == '\'') (*p)++; } else { while (!(tab[**p] & (1 | 8 | 16 | 32 | 128))) { while (!(tab[**p] & (1 | 8 | 16 | 32 | 64 | 128))) *(*q)++ = *(*p)++; if (**p == '\\') *(*q)++ = *(*p)++; } } return r; } static const uint8_t _tab_xml[256] = { ['\r'] = 1, ['\n'] = 1, ['\t'] = 1, [' '] = 1, ['\"'] = 2, ['\''] = 4, ['<'] = 8, ['>'] = 16, ['='] = 32, ['\\'] = 64, [0] = 128 }; static xine_stree_t *_xine_stree_load_xml (char *buf) { xine_stree_t *root; uint32_t have, used, here, plain; uint8_t *p, *q, *e; have = 64; root = (xine_stree_t *)malloc (have * sizeof (*root)); if (!root) return NULL; here = 0; used = 1; root->next = root->prev = 0; root->first_child = root->last_child = root->parent = 0; root->num_children = root->level = root->index = 0; root->key = root->value = 0; plain = ~0u; e = p = (uint8_t *)buf; q = (uint8_t *)buf + 1; while (1) { while (_tab_xml[p[0]] & 1) p++; if (!*p) break; if (p[0] == '<') { p++; if (p[0] == '!') { /* <!comment ... /> */ p++; if (!strncmp ((const char *)p, "[CDATA[", 7)) { /* CDATA pseudo comment */ uint32_t new = _xine_stree_node_new (&root, &have, &used, here); if (!new) return root; p += 7; if (plain == ~0u) { plain = q - (uint8_t *)buf; memcpy (q, "[]", 2); q += 2; *e = 0; e = q++; } root[new].key = plain; root[new].value = q - (uint8_t *)buf; while (1) { while (!(_tab_xml[*p] & (16 | 128))) *q++ = *p++; if (!*p) break; if ((p[-1] == ']') && (p[-2] == ']') && (p[-3] != '\\')) { p++; q -= 2; break; } *q++ = *p++; } *e = 0; e = q++; } else { while (!(_tab_xml[*p] & (16 | 128))) p++; if (*p == '>') p++; } } else if (p[0] == '/') { /* </tag> */ uint8_t *v, z; p++; /* defer writing string end until that location is not read any more. */ *e = 0; v = _xine_stree_get_string (&p, &q, _tab_xml); e = q++; z = *e; *e = 0; if (*v) { /* _not_ just </> */ while (root[here].level) { if (!strcasecmp ((const char *)buf + root[here].key, (const char *)v)) break; here = root[here].parent; } } *e = z; here = root[here].parent; while (!(_tab_xml[*p] & (16 | 128))) p++; if (*p == '>') p++; } else { /* <reguler_tag ... */ uint32_t new = _xine_stree_node_new (&root, &have, &used, here); if (!new) return root; *e = 0; root[new].key = _xine_stree_get_string (&p, &q, _tab_xml) - (uint8_t *)buf; e = q++; here = new; } } else if (*p == '/') { /* ... /> */ p++; if (*p == '>') { p++; here = root[here].parent; } } else if (!(_tab_xml[*p] & (1 | 16 | 128))) { /* ... key=value ... */ uint32_t new = _xine_stree_node_new (&root, &have, &used, here); if (!new) return root; *e = 0; root[new].key = _xine_stree_get_string (&p, &q, _tab_xml) - (uint8_t *)buf; e = q++; if (*p == '=') p++; *e = 0; root[new].value = _xine_stree_get_string (&p, &q, _tab_xml) - (uint8_t *)buf; e = q++; } else if (*p == '>') { /* <tag_with_inner_text ...>here</... */ p++; /* trim leading spc */ while (_tab_xml[*p] & 1) p++; if (!(_tab_xml[*p] & (8 | 128))) { uint8_t *b; uint32_t new = _xine_stree_node_new (&root, &have, &used, here), value; if (!new) return root; /* generic key */ if (plain == ~0u) { plain = q - (uint8_t *)buf; memcpy (q, "[]", 2); q += 2; *e = 0; e = q++; } root[new].key = plain; /* main text */ b = q; value = q - (uint8_t *)buf; root[new].value = value; if (!root[here].value) root[here].value = value; /* trim trailing spc */ while (1) { while (!(_tab_xml[*p] & (1 | 8 | 128))) *q++ = *p++; while (_tab_xml[*p] & 1) p++; if (_tab_xml[*p] & (8 | 128)) break; *q++ = ' '; } { uint8_t z = *q; *q = 0; /* this will be just right in most cases :-) */ value = xine_string_unampersand ((char *)b); *q = z; } q = b + value; *e = 0; e = q++; } } else { p++; } } *e = 0; buf[0] = 0; return root; } static const uint8_t _tab_json1[256] = { ['\r'] = 1, ['\n'] = 1, ['\t'] = 1, [' '] = 1, ['\"'] = 2, ['\''] = 4, ['{'] = 8, ['['] = 8, [']'] = 16, ['}'] = 16, [','] = 32, [':'] = 32, ['\\'] = 64, [0] = 128 }; static const uint8_t _tab_json2[256] = { ['/'] = 1, ['*'] = 2, ['\n'] = 4, [0] = 128 }; static xine_stree_t *_xine_stree_load_json (char *buf) { xine_stree_t *root; uint32_t have, used, here; uint8_t *p, *q, *e; have = 64; root = (xine_stree_t *)malloc (have * sizeof (*root)); if (!root) return NULL; here = 0; used = 1; root->next = root->prev = 0; root->first_child = root->last_child = root->parent = 0; root->num_children = root->level = root->index = 0; root->key = root->value = 0; e = p = (uint8_t *)buf; q = (uint8_t *)buf + 1; if (_tab_json1[*p] & 8) /* {[ */ p++; while (*p) { /* skip whitespace */ while (_tab_json1[*p] & 1) p++; /* skip comment */ if (*p == '/') { if (p[1] == '*') { /* C comment */ p += 2; do { while (!(_tab_json2[*p] & (2 | 128))) p++; if (!*p) break; p++; } while (*p != '/'); if (*p == '/') p++; continue; } if (p[1] == '/') { /* C++ comment */ p += 2; while (!(_tab_json2[*p] & (4 | 128))) p++; if (*p == '\n') p++; continue; } } if (_tab_json1[*p] & 8) { /* {[ */ uint32_t new = root[here].last_child; p++; if (!new) { new = _xine_stree_node_new (&root, &have, &used, here); if (!new) break; } root[new].level &= ~0x80000000; here = new; continue; } if (_tab_json1[*p] & 32) { /* :, */ uint32_t item = root[here].last_child; root[item].level &= ~0x80000000; if (*p == ',') { item = _xine_stree_node_new (&root, &have, &used, here); if (!item) break; root[item].level |= 0x80000000; } p++; continue; } if (_tab_json1[*p] & 16) { /* ]} */ uint32_t item = root[here].last_child; if (item) root[item].level &= ~0x80000000; p++; if (!root[here].level) break; here = root[here].parent; continue; } { uint8_t *v; uint32_t item = root[here].last_child; if (!item) { item = _xine_stree_node_new (&root, &have, &used, here); if (!item) break; root[item].level |= 0x80000000; } v = _xine_stree_get_string (&p, &q, _tab_json1); if (v != q) { /* defer writing string end until that location is not read any more. */ *e = 0; e = q++; if (root[item].level & 0x80000000) { root[item].key = v - (uint8_t *)buf; } else { uint8_t z; root[item].value = v - (uint8_t *)buf; /* this will be just right in most cases :-) */ z = *e; *e = 0; xine_string_unbackslash ((char *)v); *e = z; } } } } *e = 0; buf[0] = 0; return root; } static const uint8_t _tab_url[256] = { ['?'] = 1, ['#'] = 2, ['&'] = 4, ['='] = 8, ['\\'] = 64, [0] = 128 }; static xine_stree_t *_xine_stree_load_url (char *buf) { xine_stree_t *root; uint32_t have, used, here, key; uint8_t *p, *e, dummy; have = 64; root = (xine_stree_t *)malloc (have * sizeof (*root)); if (!root) return NULL; used = 1; root->next = root->prev = 0; root->first_child = root->last_child = root->parent = 0; root->num_children = root->level = root->index = 0; root->key = root->value = 0; p = (uint8_t *)buf; /* skip [http://host/path?]key1=val1&key2=val2#extra */ while (1) { while (!(_tab_url[*p] & (1 | 64 | 128))) /* ? \\ \0 */ p++; if (*p != '\\') break; p++; } if (*p) p++; else p = (uint8_t *)buf; /* cut key1=val1&key2=val2[#extra] */ e = p; while (1) { while (!(_tab_url[*p] & (2 | 64 | 128))) /* # \\ \0 */ p++; if (*p != '\\') break; p++; } *p = 0; p = e; e = &dummy; here = 0; key = 1; while (*p) { uint8_t *r = p; if (key) { while (1) { while (!(_tab_url[*p] & (4 | 8 | 64 | 128))) /* & = \\ \0 */ p++; if (*p != '\\') break; p++; } } else { /* value may contain any number of equal signs. */ while (1) { while (!(_tab_url[*p] & (4 | 64 | 128))) /* & \\ \0 */ p++; if (*p != '\\') break; p++; } } if (!here) { here = _xine_stree_node_new (&root, &have, &used, 0); if (!here) break; /* NOTE: buf may start with a key, thus we cannot put a global empty string there. */ root[here].key = root[here].value = p - (uint8_t *)buf; } if (key) { root[here].key = r - (uint8_t *)buf; } else { uint8_t z; root[here].value = r - (uint8_t *)buf; /* this will be just right in most cases :-) */ z = *p; *p = 0; xine_string_unpercent ((char *)r); *p = z; } if (*p == '&') { *e = 0; e = p++; here = 0; key = 1; } else if (*p == '=') { *e = 0; e = p++; key = 0; } } *e = 0; root->key = root->value = p - (uint8_t *)buf; return root; } xine_stree_t *xine_stree_load (char *buf, xine_stree_mode_t *mode) { xine_stree_mode_t m2 = XINE_STREE_AUTO; if (!buf) return NULL; if (!mode) mode = &m2; if (*mode >= XINE_STREE_LAST) return NULL; if (*mode == XINE_STREE_AUTO) { const uint8_t *p = (const uint8_t *)buf; while (_tab_xml[*p] & 1) p++; if (*p == '<') { *mode = XINE_STREE_XML; } else if ((*p == '{') || (*p == '[')) { *mode = XINE_STREE_JSON; } else { *mode = XINE_STREE_URL; } } switch (*mode) { case XINE_STREE_XML: return _xine_stree_load_xml (buf); case XINE_STREE_JSON: return _xine_stree_load_json (buf); case XINE_STREE_URL: return _xine_stree_load_url (buf); default: return NULL; } } void xine_stree_dump (const xine_stree_t *tree, const char *buf, uint32_t base) { static const char spc[] = " "; const xine_stree_t *here, *stop; uint32_t index; if (!tree || !buf) return; here = tree + base; stop = base ? here : NULL; { const xine_stree_t *test; for (index = 0, test = here; test->prev; index += 1, test = tree + test->prev) ; } while (1) { printf ("%s[%d:%d] \"%s\" = \"%s\"\n", spc + (sizeof (spc) - 1) - 2 * (here->level > (sizeof (spc) - 1) / 2 ? sizeof (spc) - 1 : here->level), (int)here->level, (int)index, buf + here->key, buf + here->value); if (here->first_child) { /* down */ index = 0; here = tree + here->first_child; } else if (here == stop) { /* done */ break; } else if (here->next) { /* next */ index += 1; here = tree + here->next; } else { /* up */ const xine_stree_t *test; while (here->level) { here = tree + here->parent; if ((here == stop) || here->next) break; } if ((here == stop) || !here->next) break; for (index = 1, test = here; test->prev; index += 1, test = tree + test->prev) ; here = tree + here->next; } } } static const uint8_t _tab_key[256] = { ['.'] = 1, ['['] = 2, ['0'] = 4, ['1'] = 4, ['2'] = 4, ['3'] = 4, ['4'] = 4, ['5'] = 4, ['6'] = 4, ['7'] = 4, ['8'] = 4, ['9'] = 4, ['\t'] = 8, [' '] = 8, ['\0'] = 128 }; uint32_t xine_stree_find (const xine_stree_t *tree, const char *buf, const char *path, uint32_t base, int case_sens) { const xine_stree_t *here; const uint8_t *s; uint8_t part[512], *q, *e; if (!tree || !buf) return 0; if (!path) return base; here = tree + base; e = part + sizeof (part) - 1; s = (const uint8_t *)path; while (1) { uint32_t v; while (*s == '.') s++; if (!*s) return here - tree; if (!here->first_child) return 0; here = tree + here->first_child; q = part; while (1) { while (!(_tab_key[*s] & (1 | 2 | 128)) && (q < e)) *q++ = *s++; if (q >= e) return 0; if (*s != '[') break; if (_tab_key[s[1]] & (4 | 8)) break; *q++ = *s++; } if (q >= e) return 0; *q = 0; v = 0; if (*s == '[') { uint8_t z; s++; while (_tab_xml[*s] & 1) s++; while ((z = *s ^ '0') < 10) v = 10u * v + z, s++; while (_tab_xml[*s] & 1) s++; if (*s == ']') s++; } if (*part) { if (case_sens) { while (1) { if (!strcmp ((const char *)buf + here->key, (const char *)part)) { if (!v) break; v--; } if (!here->next) return 0; here = tree + here->next; } } else { while (1) { if (!strcasecmp ((const char *)buf + here->key, (const char *)part)) { if (!v) break; v--; } if (!here->next) return 0; here = tree + here->next; } } } else { while (v && here->next) v--, here = tree + here->next; if (v) return 0; } } } void xine_stree_delete (xine_stree_t **tree) { if (tree) { free (*tree); *tree = NULL; } } #ifdef TEST_THIS_FILE int main (int argc, char **argv) { (void)argc; do { FILE *f; size_t fsize; char *buf; xine_stree_t *tree; uint32_t here; xine_stree_mode_t mode; if (!argv[0]) break; if (!argv[1]) break; f = fopen (argv[1], "rb"); if (!f) break; fseek (f, 0, SEEK_END); fsize = ftell (f); fseek (f, 0, SEEK_SET); buf = malloc (fsize + 1); if (!buf) { fclose (f); break; } fread (buf, 1, fsize, f); fclose (f); buf[fsize] = 0; mode = XINE_STREE_AUTO; tree = xine_stree_load (buf, &mode); if (!tree) { free (buf); break; } here = xine_stree_find (tree, buf, argv[2], 0, mode == XINE_STREE_JSON); if (!argv[2] || here) xine_stree_dump (tree, buf, here); xine_stree_delete (&tree); free (buf); return 0; } while (0); { static const char helptext[] = "usage: stree <file> [<path>]\n" " path is a dot separated list of parts.\n" " part is a key, a zero based index number in square brackets, or both.\n" " the special key \"[]\" refers to xml tag content text.\n" " \"foo.[][0]\" will also be available as \"foo\".\n"; fwrite (helptext, 1, sizeof (helptext) - 1, stdout); } return 1; } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/yuv2rgb_mlib.c����������������������������������������������������������0000644�0001750�0001750�00000012342�14647725152�016325� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * yuv2rgb_mlib.c * * Copyright (C) 2001-2018 the xine project * This file is part of xine, a free video player. * * based on work from mpeg2dec: * Copyright (C) 2000-2001 Silicon Integrated System Corp. * All Rights Reserved. * * Author: Juergen Keil <jk@tools.de> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #include "config.h" #ifdef HAVE_MLIB #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include <mlib_algebra.h> #include <mlib_video.h> #include <xine/attributes.h> #include <xine/xineutils.h> #include "yuv2rgb_private.h" static void mlib_yuv420_rgb24(yuv2rgb_t *this_gen, uint8_t * image, uint8_t * py, uint8_t * pu, uint8_t * pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t *)this_gen; int src_height = MIN(this->slice_height, this->source_height-this->slice_offset) &~ 1; int dst_height; dst_height = this_gen->next_slice(this_gen, &image); if (this->do_scale) { mlib_u8 *resize_buffer = this->mlib_resize_buffer; mlib_s32 resize_stride = this->dest_width << 2; mlib_VideoColorYUV420seq_to_ARGBint((mlib_u32*)this->mlib_buffer, py, pu, pv, py, 0, this->source_width, src_height, this->source_width<<2, this->y_stride, this->uv_stride); mlib_VideoColorResizeABGR((mlib_u32*)resize_buffer, (mlib_u32*)this->mlib_buffer, this->dest_width,dst_height,resize_stride, this->source_width, src_height,this->source_width<<2, this->mlib_filter_type); while(dst_height--) { mlib_VideoColorABGR2RGB(image, resize_buffer, this->dest_width); image += this->rgb_stride; resize_buffer += resize_stride; } } else { mlib_VideoColorYUV2RGB420(image, py, pu, pv, this->source_width, dst_height, this->rgb_stride, this->y_stride, this->uv_stride); } } static void mlib_yuv420_argb32(yuv2rgb_t *this_gen, uint8_t * image, uint8_t * py, uint8_t * pu, uint8_t * pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t *)this_gen; int src_height = MIN(this->slice_height, this->source_height-this->slice_offset) &~ 1; int dst_height; dst_height = this_gen->next_slice(this_gen, &image); if (this->do_scale) { mlib_VideoColorYUV420seq_to_ARGBint((mlib_u32*)this->mlib_buffer, py, pu, pv, py, 0, this->source_width, src_height, this->source_width<<2, this->y_stride, this->uv_stride); mlib_VideoColorResizeABGR((mlib_u32*)image, (mlib_u32*)this->mlib_buffer, this->dest_width,dst_height,this->rgb_stride, this->source_width, src_height,this->source_width<<2, this->mlib_filter_type); } else { mlib_VideoColorYUV420seq_to_ARGBint((mlib_u32*)image, py, pu, pv, py, 0, this->source_width, dst_height, this->rgb_stride, this->y_stride, this->uv_stride); } if (this->swapped) { while (dst_height--) { mlib_VectorReverseByteOrder_U32((mlib_u32*)image, this->dest_width); image += this->rgb_stride; } } } static void mlib_yuv420_abgr32(yuv2rgb_t *this_gen, uint8_t * image, uint8_t * py, uint8_t * pu, uint8_t * pv) { yuv2rgb_impl_t *this = (yuv2rgb_impl_t *)this_gen; int src_height = MIN(this->slice_height, this->source_height-this->slice_offset) &~ 1; int dst_height; dst_height = this_gen->next_slice (this_gen, &image); if (this->do_scale) { mlib_VideoColorYUV420seq_to_ABGRint((mlib_u32*)this->mlib_buffer, py, pu, pv, py, 0, this->source_width, src_height, this->source_width<<2, this->y_stride, this->uv_stride); mlib_VideoColorResizeABGR((mlib_u32*)image, (mlib_u32*)this->mlib_buffer, this->dest_width,dst_height,this->rgb_stride, this->source_width, src_height, this->source_width<<2, this->mlib_filter_type); } else { mlib_VideoColorYUV420seq_to_ABGRint((mlib_u32*)image, py, pu, pv, py, 0, this->source_width, dst_height, this->rgb_stride, this->y_stride, this->uv_stride); } if (this->swapped) { while (dst_height--) { mlib_VectorReverseByteOrder_U32((mlib_u32*)image, this->dest_width); image += this->rgb_stride; } } } void yuv2rgb_init_mlib (yuv2rgb_factory_impl_t *this) { switch (this->mode) { case MODE_24_RGB: if (this->swapped) break; this->yuv2rgb_fun = mlib_yuv420_rgb24; break; case MODE_32_RGB: this->yuv2rgb_fun = mlib_yuv420_argb32; break; case MODE_32_BGR: this->yuv2rgb_fun = mlib_yuv420_abgr32; break; } } #endif /* HAVE_MLIB */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/copy.c������������������������������������������������������������������0000644�0001750�0001750�00000010677�14647725152�014705� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2004-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * $Id: * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xineutils.h> static void _copy_plane(uint8_t *restrict dst, const uint8_t *restrict src, int dst_pitch, int src_pitch, int width, int height) { if (src_pitch == dst_pitch) { xine_fast_memcpy(dst, src, src_pitch * height); } else { int y; for (y = 0; y < height; y++) { xine_fast_memcpy(dst, src, width); src += src_pitch; dst += dst_pitch; } } } void yv12_to_yv12 (const unsigned char *y_src, int y_src_pitch, unsigned char *y_dst, int y_dst_pitch, const unsigned char *u_src, int u_src_pitch, unsigned char *u_dst, int u_dst_pitch, const unsigned char *v_src, int v_src_pitch, unsigned char *v_dst, int v_dst_pitch, int width, int height) { _copy_plane(y_dst, y_src, y_dst_pitch, y_src_pitch, width, height); _copy_plane(u_dst, u_src, u_dst_pitch, u_src_pitch, width/2, height/2); _copy_plane(v_dst, v_src, v_dst_pitch, v_src_pitch, width/2, height/2); } void yuy2_to_yuy2 (const unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch, int width, int height) { _copy_plane(dst, src, dst_pitch, src_pitch, width*2, height); } void _x_nv12_to_yv12(const uint8_t *restrict y_src, int y_src_pitch, const uint8_t *restrict uv_src, int uv_src_pitch, uint8_t *restrict y_dst, int y_dst_pitch, uint8_t *restrict u_dst, int u_dst_pitch, uint8_t *restrict v_dst, int v_dst_pitch, int width, int height) { int y, x; _copy_plane(y_dst, y_src, y_dst_pitch, y_src_pitch, width, height); for (y = 0; y < height / 2; y++) { for (x = 0; x < width / 2; x++) { u_dst[x] = uv_src[2*x]; v_dst[x] = uv_src[2*x + 1]; } uv_src += uv_src_pitch; u_dst += u_dst_pitch; v_dst += v_dst_pitch; } } void _x_yv12_to_nv12(const uint8_t *y_src, int y_src_pitch, const uint8_t *u_src, int u_src_pitch, const uint8_t *v_src, int v_src_pitch, uint8_t *y_dst, int y_dst_pitch, uint8_t *uv_dst, int uv_dst_pitch, int width, int height) { int y, x; _copy_plane(y_dst, y_src, y_dst_pitch, y_src_pitch, width, height); /* Combine uv line to temporary (cached) buffer. Avoids fetching destination plane to cache. */ uint8_t *line = xine_malloc_aligned(width + 1); if (!line) return; for(y = 0; y < height / 2; y++) { for(x = 0; x < width / 2; x++) { line[2*x] = *(u_src + x); line[2*x + 1] = *(v_src + x); } xine_fast_memcpy(uv_dst, line, width); uv_dst += uv_dst_pitch; u_src += u_src_pitch; v_src += v_src_pitch; } xine_free_aligned(line); } void _x_yuy2_to_nv12(const uint8_t *src_yuy2_map, int yuy2_pitch, uint8_t *y_dst, int y_dst_pitch, uint8_t *uv_dst, int uv_dst_pitch, int width, int height) { int y, x; const uint8_t *yuy2_map = src_yuy2_map; for(y = 0; y < height; y++) { uint8_t *y_dst_tmp = y_dst; const uint8_t *yuy2_src_tmp = yuy2_map; for(x = 0; x < width / 2; x++) { *(y_dst_tmp++ ) = *(yuy2_src_tmp++); yuy2_src_tmp++; *(y_dst_tmp++ ) = *(yuy2_src_tmp++); yuy2_src_tmp++; } y_dst += y_dst_pitch; yuy2_map += yuy2_pitch; } yuy2_map = src_yuy2_map; for(y = 0; y < height; y += 2) { for(x = 0; x < width; x += 2) { *(uv_dst + x ) = *(yuy2_map + x*2 + 1); *(uv_dst + x + 1 ) = *(yuy2_map + x*2 + 3); } uv_dst += uv_dst_pitch; yuy2_map += yuy2_pitch * 2; } } �����������������������������������������������������������������xine-lib-1.2/src/xine-utils/xine_mutex.c������������������������������������������������������������0000644�0001750�0001750�00000004000�14647725152�016077� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <pthread.h> #include <xine/xineutils.h> /* #define DBG_MUTEX */ int xine_mutex_init (xine_mutex_t *mutex, const pthread_mutexattr_t *mutexattr, const char *id) { #ifdef DBG_MUTEX strncpy (mutex->id, id, sizeof (mutex->id)); mutex->id[sizeof (mutex->id) - 1] = 0; #else (void)id; #endif return pthread_mutex_init (&mutex->mutex, mutexattr); } int xine_mutex_lock (xine_mutex_t *mutex, const char *who) { #ifndef DBG_MUTEX (void)who; return pthread_mutex_lock (&mutex->mutex); #else if (pthread_mutex_trylock (&mutex->mutex)) { printf ("xine_mutex: BLOCK when %s tried to lock mutex %s because it is locked by %s. continue trying...)\n", who, mutex->id, mutex->locked_by); pthread_mutex_lock (&mutex->mutex); } printf ("xine_mutex: %s has now locked mutex %s\n", who, mutex->id); mutex->locked_by = who; return 1; #endif } int xine_mutex_unlock (xine_mutex_t *mutex, const char *who) { printf ("xine_mutex: mutex %s unlocked by %s\n", mutex->id, who); return pthread_mutex_unlock (&mutex->mutex); } int xine_mutex_destroy (xine_mutex_t *mutex) { return pthread_mutex_destroy (&mutex->mutex); } xine-lib-1.2/src/xine-utils/yuv2rgb_private.h�������������������������������������������������������0000644�0001750�0001750�00000006032�14647725152�017060� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * yuv2rgb_private.h * * Copyright (C) 2001-2018 the xine project * This file is part of xine, a free video player. * * based on work from mpeg2dec: * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef YUV2RGB_PRIVATE_H #define YUV2RGB_PRIVATE_H #include <inttypes.h> #ifdef HAVE_MLIB #include <mlib_video.h> #endif #include "yuv2rgb.h" typedef struct yuv2rgb_impl_s yuv2rgb_impl_t; typedef struct yuv2rgb_factory_impl_s yuv2rgb_factory_impl_t; typedef void (*scale_line_func_t) (const uint8_t *restrict source, uint8_t *restrict dest, int width, int step); struct yuv2rgb_impl_s { yuv2rgb_t intf; int source_width, source_height; int y_stride, uv_stride; int dest_width, dest_height; int rgb_stride; int slice_height, slice_offset; int step_dx, step_dy; int do_scale, swapped; uint8_t *y_buffer; uint8_t *u_buffer; uint8_t *v_buffer; void * const *table_rV; void * const *table_gU; const int *table_gV; void * const *table_bU; const void *table_mmx; const uint8_t *cmap; scale_line_func_t scale_line; #ifdef HAVE_MLIB uint8_t *mlib_buffer; uint8_t *mlib_resize_buffer; mlib_filter mlib_filter_type; #endif }; struct yuv2rgb_factory_impl_s { yuv2rgb_factory_t intf; int mode; int swapped; const uint8_t *cmap; void *table_base; void *table_rV[256]; void *table_gU[256]; int table_gV[256]; void *table_bU[256]; void *table_mmx; /* preselected functions for mode/swap/hardware */ yuv2rgb_fun_t yuv2rgb_fun; yuy22rgb_fun_t yuy22rgb_fun; yuv2rgb_single_pixel_fun_t yuv2rgb_single_pixel_fun; }; void mmx_yuv2rgb_set_csc_levels(yuv2rgb_factory_t *this, int brightness, int contrast, int saturation, int colormatrix); void yuv2rgb_init_mmxext (yuv2rgb_factory_impl_t *this); void yuv2rgb_init_mmx (yuv2rgb_factory_impl_t *this); void yuv2rgb_init_mlib (yuv2rgb_factory_impl_t *this); #endif /* YUV2RGB_PRIVATE_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/ppc_asm.tmpl������������������������������������������������������������0000644�0001750�0001750�00000003215�14647725152�016075� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* Condition Register Bit Fields */ #define cr0 0 #define cr1 1 #define cr2 2 #define cr3 3 #define cr4 4 #define cr5 5 #define cr6 6 #define cr7 7 /* General Purpose Registers (GPRs) */ #define r0 0 #define r1 1 #define r2 2 #define r3 3 #define r4 4 #define r5 5 #define r6 6 #define r7 7 #define r8 8 #define r9 9 #define r10 10 #define r11 11 #define r12 12 #define r13 13 #define r14 14 #define r15 15 #define r16 16 #define r17 17 #define r18 18 #define r19 19 #define r20 20 #define r21 21 #define r22 22 #define r23 23 #define r24 24 #define r25 25 #define r26 26 #define r27 27 #define r28 28 #define r29 29 #define r30 30 #define r31 31 /* Floating Point Registers (FPRs) */ #define fr0 0 #define fr1 1 #define fr2 2 #define fr3 3 #define fr4 4 #define fr5 5 #define fr6 6 #define fr7 7 #define fr8 8 #define fr9 9 #define fr10 10 #define fr11 11 #define fr12 12 #define fr13 13 #define fr14 14 #define fr15 15 #define fr16 16 #define fr17 17 #define fr18 18 #define fr19 19 #define fr20 20 #define fr21 21 #define fr22 22 #define fr23 23 #define fr24 24 #define fr25 25 #define fr26 26 #define fr27 27 #define fr28 28 #define fr29 29 #define fr30 30 #define fr31 31 #define vr0 0 #define vr1 1 #define vr2 2 #define vr3 3 #define vr4 4 #define vr5 5 #define vr6 6 #define vr7 7 #define vr8 8 #define vr9 9 #define vr10 10 #define vr11 11 #define vr12 12 #define vr13 13 #define vr14 14 #define vr15 15 #define vr16 16 #define vr17 17 #define vr18 18 #define vr19 19 #define vr20 20 #define vr21 21 #define vr22 22 #define vr23 23 #define vr24 24 #define vr25 25 #define vr26 26 #define vr27 27 #define vr28 28 #define vr29 29 #define vr30 30 #define vr31 31 �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/ppcasm_string.h���������������������������������������������������������0000644�0001750�0001750�00000000204�14647725152�016572� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <stdlib.h> void *ppcasm_cacheable_memcpy(void *, const void *, size_t); void *ppcasm_memcpy(void *, const void *, size_t); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/yuv2rgb.h���������������������������������������������������������������0000644�0001750�0001750�00000007424�14647725152�015334� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * yuv2rgb.h * * Copyright (C) 2001-2018 the xine project * This file is part of xine, a free video player. * * based on work from mpeg2dec: * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef XINE_YUV2RGB_H #define XINE_YUV2RGB_H #include <inttypes.h> #include <xine/attributes.h> typedef struct yuv2rgb_s yuv2rgb_t; typedef struct yuv2rgb_factory_s yuv2rgb_factory_t; /* * function types for functions which can be replaced * by hardware-accelerated versions */ typedef void (*yuv2rgb_fun_t) (yuv2rgb_t *this, uint8_t *restrict image, const uint8_t *restrict py, const uint8_t *restrict pu, const uint8_t *restrict pv); typedef void (*yuy22rgb_fun_t) (yuv2rgb_t *this, uint8_t *restrict image, const uint8_t *restrict p); typedef uint32_t (*yuv2rgb_single_pixel_fun_t) (yuv2rgb_t *this, uint8_t y, uint8_t u, uint8_t v); /* * modes supported - feel free to implement yours */ #define MODE_8_RGB 1 #define MODE_8_BGR 2 #define MODE_15_RGB 3 #define MODE_15_BGR 4 #define MODE_16_RGB 5 #define MODE_16_BGR 6 #define MODE_24_RGB 7 #define MODE_24_BGR 8 #define MODE_32_RGB 9 #define MODE_32_BGR 10 #define MODE_8_GRAY 11 #define MODE_PALETTE 12 /* * colormatrix values - (mpeg_matrix_index << 1) | fullrange */ #define CM_DEFAULT 10 #define CM_SD 10 #define CM_HD 2 #define CM_FULLRANGE 1 struct yuv2rgb_s { /* * configure converter for scaling factors */ int (*configure) (yuv2rgb_t *this, int source_width, int source_height, int y_stride, int uv_stride, int dest_width, int dest_height, int rgb_stride); /* * start a new field or frame if dest is NULL */ int (*next_slice) (yuv2rgb_t *this, uint8_t **dest); /* * free resources */ void (*dispose) (yuv2rgb_t *this); /* * this is the function to call for the yuv2rgb and scaling process */ yuv2rgb_fun_t yuv2rgb_fun; /* * this is the function to call for the yuy2->rgb and scaling process */ yuy22rgb_fun_t yuy22rgb_fun; /* * this is the function to call for the yuv2rgb for a single pixel * (used for converting clut colors) */ yuv2rgb_single_pixel_fun_t yuv2rgb_single_pixel_fun; }; /* * convenience class to easily create a lot of converters */ struct yuv2rgb_factory_s { yuv2rgb_t* (*create_converter) (yuv2rgb_factory_t *this); /* * set color space conversion levels * for all converters produced by this factory */ void (*set_csc_levels) (yuv2rgb_factory_t *this, int brightness, int contrast, int saturation, int colormatrix); /* * free resources */ void (*dispose) (yuv2rgb_factory_t *this); }; yuv2rgb_factory_t *yuv2rgb_factory_init (int mode, int swapped, const uint8_t *colormap) XINE_PROTECTED; #endif /* XINE_YUV2RGB_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/xine_check.c������������������������������������������������������������0000644�0001750�0001750�00000035626�14647725152�016034� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Xine Health Check: * * Overview: Checking the setup of the user's system is the task of * xine-check.sh for now. At present this is intended to replace * xine_check to provide a more robust way of informing users new * to xine of the setup of their system. * * Interface: The function xine_health_check is the starting point * to check the user's system. It is expected that the values for * hc->cdrom_dev and hc->dvd_dev will be defined. For example, * hc->cdrom_dev = /dev/cdrom and hc->/dev/dvd. If at any point a * step fails the function returns with a failed status, * XINE_HEALTH_CHECK_FAIL, and an error message contained in hc->msg. * * Author: Stephen Torri <storri@users.sourceforge.net> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdarg.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <xine/xineutils.h> #ifndef O_CLOEXEC # define O_CLOEXEC 0 #endif #if defined(__linux__) #include <dlfcn.h> #include <sys/stat.h> #include <sys/ioctl.h> #ifdef HAVE_SYS_SYSMACROS_H # include <sys/sysmacros.h> #endif #include <sys/utsname.h> #include <linux/major.h> #include <linux/hdreg.h> #ifdef HAVE_X11 # include <X11/Xlib.h> # ifdef HAVE_XV # include <X11/extensions/Xvlib.h> # endif #endif #ifndef SCSI_BLK_MAJOR #define SCSI_BLK_MAJOR(m) \ (((m) == SCSI_DISK0_MAJOR || \ ((m) >= SCSI_DISK1_MAJOR && (m) <= SCSI_DISK7_MAJOR)) || \ ((m) == SCSI_CDROM_MAJOR)) #endif #endif /* !__linux__ */ static void XINE_FORMAT_PRINTF(3, 4) set_hc_result(xine_health_check_t* hc, int state, const char *format, ...) { va_list args; char *buf = NULL; _x_assert (hc); _x_assert (format); va_start(args, format); if (vasprintf (&buf, format, args) < 0) buf = NULL; va_end(args); hc->msg = buf; hc->status = state; } #if defined(__linux__) static xine_health_check_t* _x_health_check_kernel (xine_health_check_t* hc) { struct utsname kernel; hc->title = "Check for kernel version"; hc->explanation = "Probably you're not running a Linux-Like system."; if (uname (&kernel) == 0) { fprintf (stdout," sysname: %s\n", kernel.sysname); fprintf (stdout," release: %s\n", kernel.release); fprintf (stdout," machine: %s\n", kernel.machine); hc->status = XINE_HEALTH_CHECK_OK; } else { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - Could not get kernel information."); } return hc; } #if defined(ARCH_X86) static xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) { FILE *fd; hc->title = "Check for MTRR support"; hc->explanation = "Make sure your kernel has MTRR support compiled in."; fd = fopen("/proc/mtrr", "r"); if (!fd) { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED: mtrr is not enabled."); } else { hc->status = XINE_HEALTH_CHECK_OK; fclose (fd); } return hc; } #else static xine_health_check_t* _x_health_check_mtrr (xine_health_check_t* hc) { hc->title = "Check for MTRR support"; hc->explanation = "Don't worry about this one"; set_hc_result (hc, XINE_HEALTH_CHECK_OK, "mtrr does not apply on this hw platform."); return hc; } #endif static xine_health_check_t* _x_health_check_cdrom (xine_health_check_t* hc) { struct stat cdrom_st; int fd; hc->title = "Check for CDROM drive"; hc->explanation = "Either create a symbolic link /dev/cdrom pointing to " "your cdrom device or set your cdrom device in the " "preferences dialog."; if (stat (hc->cdrom_dev,&cdrom_st) < 0) { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - could not access cdrom: %s\n", hc->cdrom_dev); return hc; } if ((cdrom_st.st_mode & S_IFMT) != S_IFBLK) { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s is not a block device.\n", hc->cdrom_dev); return hc; } if ( (fd = open(hc->cdrom_dev, O_RDWR | O_CLOEXEC)) < 0) { switch (errno) { case EACCES: set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s permissions are not sufficient\n.", hc->cdrom_dev); return hc; case ENXIO: case ENODEV: set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - there is no device behind %s\n.", hc->cdrom_dev); return hc; } } else close(fd); hc->status = XINE_HEALTH_CHECK_OK; return hc; } static xine_health_check_t* _x_health_check_dvdrom(xine_health_check_t* hc) { struct stat dvdrom_st; int fd; hc->title = "Check for DVD drive"; hc->explanation = "Either create a symbolic link /dev/dvd pointing to " "your cdrom device or set your cdrom device in the " "preferences dialog."; if (stat (hc->dvd_dev,&dvdrom_st) < 0) { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - could not access dvdrom: %s\n", hc->dvd_dev); return hc; } if ((dvdrom_st.st_mode & S_IFMT) != S_IFBLK) { set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s is not a block device.\n", hc->dvd_dev); return hc; } if ( (fd = open(hc->dvd_dev, O_RDWR | O_CLOEXEC)) < 0) { switch (errno) { case EACCES: set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - %s permissions are not sufficient\n.", hc->dvd_dev); return hc; case ENXIO: case ENODEV: set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - there is no device behind %s\n.", hc->dvd_dev); return hc; } } else close(fd); hc->status = XINE_HEALTH_CHECK_OK; return hc; } static xine_health_check_t* _x_health_check_dma (xine_health_check_t* hc) { int is_scsi_dev = 0; int fd = 0; static long param = 0; struct stat st; hc->title = "Check for DMA mode on DVD drive"; hc->explanation = "If you are using the ide-cd module ensure\n" "that you have the following entry in /etc/modules.conf:\n" "options ide-cd dma=1\n Reload ide-cd module.\n" "otherwise run hdparm -d 1 on your dvd-device."; /* If /dev/dvd points to /dev/scd0 but the drive is IDE (e.g. /dev/hdc) * and not scsi how do we detect the correct one */ if (stat (hc->dvd_dev, &st)) { set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - Could not read stats for %s.\n", hc->dvd_dev); return hc; } if (SCSI_BLK_MAJOR(major(st.st_rdev))) { is_scsi_dev = 1; set_hc_result(hc, XINE_HEALTH_CHECK_OK, "SKIPPED - Operation not supported on SCSI drives or drives that use the ide-scsi module."); return hc; } fd = open (hc->dvd_dev, O_RDONLY | O_NONBLOCK | O_CLOEXEC); if (fd < 0) { set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - Could not open %s.\n", hc->dvd_dev); return hc; } if (!is_scsi_dev) { if(ioctl (fd, HDIO_GET_DMA, ¶m)) { close (fd); set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - HDIO_GET_DMA failed. Ensure the permissions for %s are 0664.\n", hc->dvd_dev); return hc; } if (param != 1) { close (fd); set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "FAILED - DMA not turned on for %s.", hc->dvd_dev); return hc; } } close (fd); hc->status = XINE_HEALTH_CHECK_OK; return hc; } static xine_health_check_t* _x_health_check_x (xine_health_check_t* hc) { const char *env_display = getenv("DISPLAY"); hc->title = "Check for X11 environment"; hc->explanation = "Make sure you're running X11, if this is an ssh connection,\n" "make sure you have X11 forwarding enabled (ssh -X ...)"; if (!env_display || strlen (env_display) == 0) { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "FAILED - DISPLAY environment variable not set."); } else { hc->status = XINE_HEALTH_CHECK_OK; } return hc; } static xine_health_check_t* _x_health_check_xv (xine_health_check_t* hc) { #ifdef HAVE_X11 #ifdef HAVE_XV Display *dpy; unsigned int ver, rev, eventB, reqB, errorB; char *disname = NULL; void *x11_handle; void *xv_handle; Display *(*xopendisplay)(char*); char *(*xdisplayname)(char*); int (*xvqueryextension)(Display*, unsigned int*, unsigned int*, unsigned int*, unsigned int*, unsigned int*); int (*xvqueryadaptors)(Display*, Window, int*, XvAdaptorInfo**); XvImageFormatValues *(*xvlistimageformats)(Display*, XvPortID, int*); char *err = NULL; int formats, adaptors, i; XvImageFormatValues *img_formats; XvAdaptorInfo *adaptor_info; hc->title = "Check for MIT Xv extension"; hc->explanation = "You can improve performance by installing an X11\n" "driver that supports the Xv protocol extension."; /* Majority of thi code was taken from or inspired by the xvinfo.c file of XFree86 */ dlerror(); /* clear error code */ x11_handle = dlopen(LIBX11_SO, RTLD_LAZY); if(!x11_handle) { hc->msg = dlerror(); hc->status = XINE_HEALTH_CHECK_FAIL; return hc; } /* Get reference to XOpenDisplay */ xopendisplay = dlsym(x11_handle,"XOpenDisplay"); if((err = dlerror()) != NULL) { hc->msg = err; hc->status = XINE_HEALTH_CHECK_FAIL; dlclose(x11_handle); return hc; } /* Get reference to XDisplayName */ xdisplayname = dlsym(x11_handle,"XDisplayName"); if((err = dlerror()) != NULL) { hc->msg = err; hc->status = XINE_HEALTH_CHECK_FAIL; dlclose(x11_handle); return hc; } dlerror(); /* clear error code */ xv_handle = dlopen(LIBXV_SO, RTLD_LAZY); if(!xv_handle) { hc->msg = dlerror(); /* Xv might still work when linked statically into the output plugin, * so reporting FAIL would be wrong here */ hc->status = XINE_HEALTH_CHECK_UNSUPPORTED; dlclose(x11_handle); return hc; } /* Get reference to XvQueryExtension */ xvqueryextension = dlsym(xv_handle,"XvQueryExtension"); if((err = dlerror()) != NULL) { hc->msg = err; hc->status = XINE_HEALTH_CHECK_FAIL; dlclose(x11_handle); dlclose(xv_handle); return hc; } /* Get reference to XvQueryAdaptors */ xvqueryadaptors = dlsym(xv_handle,"XvQueryAdaptors"); if((err = dlerror()) != NULL) { hc->msg = err; hc->status = XINE_HEALTH_CHECK_FAIL; dlclose(x11_handle); dlclose(xv_handle); return hc; } /* Get reference to XvListImageFormats */ xvlistimageformats = dlsym(xv_handle,"XvListImageFormats"); if((err = dlerror()) != NULL) { hc->msg = err; hc->status = XINE_HEALTH_CHECK_FAIL; dlclose(x11_handle); dlclose(xv_handle); return hc; } if(!(dpy = (*xopendisplay)(disname))) { if (!disname) { disname = (*xdisplayname)(NULL); } set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "Unable to open display: %s\n", disname); dlclose(x11_handle); dlclose(xv_handle); return hc; } if((Success != xvqueryextension(dpy, &ver, &rev, &reqB, &eventB, &errorB))) { if (!disname) { disname = xdisplayname(NULL); } set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "Unable to open display: %s\n",disname); dlclose(x11_handle); dlclose(xv_handle); return hc; } else { printf("X-Video Extension version %d.%d\n", ver, rev); } /* * check adaptors, search for one that supports (at least) yuv12 */ if (Success != xvqueryadaptors(dpy,DefaultRootWindow(dpy), &adaptors,&adaptor_info)) { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "video_out_xv: XvQueryAdaptors failed.\n"); dlclose(x11_handle); dlclose(xv_handle); return hc; } if (!adaptor_info) { set_hc_result (hc, XINE_HEALTH_CHECK_FAIL, "video_out_xv: No adaptors found.\n"); dlclose(x11_handle); dlclose(xv_handle); return hc; } img_formats = xvlistimageformats (dpy, adaptor_info->base_id, &formats); for(i = 0; i < formats; i++) { printf ("video_out_xv: Xv image format: 0x%x (%4.4s) %s\n", img_formats[i].id, (char*)&img_formats[i].id, (img_formats[i].format == XvPacked) ? "packed" : "planar"); if (img_formats[i].id == XINE_IMGFMT_YV12) { printf("video_out_xv: this adaptor supports the yv12 format.\n"); set_hc_result (hc, XINE_HEALTH_CHECK_OK, "video_out_xv: this adaptor supports the yv12 format.\n"); } else if (img_formats[i].id == XINE_IMGFMT_YUY2) { printf("video_out_xv: this adaptor supports the yuy2 format.\n"); set_hc_result (hc, XINE_HEALTH_CHECK_OK, "video_out_xv: this adaptor supports the yuy2 format.\n"); } } dlclose(x11_handle); dlclose(xv_handle); return hc; #else hc->title = "Check for MIT Xv extension"; hc->explanation = "You can improve performance by installing an X11\n" "driver that supports the Xv protocol extension."; set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "No X-Video Extension was present at compile time"); return hc; #endif /* ! HAVE_HV */ #else hc->title = "Check for MIT Xv extension"; hc->explanation = "You can improve performance by installing an X11\n" "driver that supports the Xv protocol extension."; set_hc_result(hc, XINE_HEALTH_CHECK_FAIL, "No X11 windowing system was present at compile time"); return hc; #endif /* ! HAVE_X11 */ } xine_health_check_t* xine_health_check (xine_health_check_t* hc, int check_num) { if (!hc) { return NULL; } switch(check_num) { case CHECK_KERNEL: hc = _x_health_check_kernel (hc); break; case CHECK_MTRR: hc = _x_health_check_mtrr (hc); break; case CHECK_CDROM: hc = _x_health_check_cdrom (hc); break; case CHECK_DVDROM: hc = _x_health_check_dvdrom (hc); break; case CHECK_DMA: hc = _x_health_check_dma (hc); break; case CHECK_X: hc = _x_health_check_x (hc); break; case CHECK_XV: hc = _x_health_check_xv (hc); break; default: hc->status = XINE_HEALTH_CHECK_NO_SUCH_CHECK; } return hc; } #else /* !__linux__ */ xine_health_check_t* xine_health_check (xine_health_check_t* hc, int check_num) { hc->title = "xine health check not supported on this platform"; hc->explanation = "contact the xine-devel mailing list if you'd like to\n" "contribute code for your platform."; set_hc_result(hc, XINE_HEALTH_CHECK_NO_SUCH_CHECK, "xine health check not supported on the OS.\n"); return hc; } #endif /* !__linux__ */ ����������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/list.c������������������������������������������������������������������0000644�0001750�0001750�00000016076�14647725152�014705� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <xine/attributes.h> #include <xine/list.h> #include <xine/xineutils.h> /* dlist_*, dnode_* */ #define MIN_CHUNK_SIZE 32 #define MAX_CHUNK_SIZE 65536 typedef struct xine_list_elem_s xine_list_elem_t; typedef struct _xine_list_chunk_s _xine_list_chunk_t; /* typedef struct xine_list_s xine_list_t; */ struct xine_list_elem_s { dnode_t node; /*_xine_list_chunk_t *chunk;*/ void *value; }; struct _xine_list_chunk_s { _xine_list_chunk_t *next; /*_xine_list_t *list;*/ uint32_t max_elems; uint32_t first_unused; xine_list_elem_t elems[1]; }; struct xine_list_s { dlist_t used; dlist_t free; _xine_list_chunk_t *chunks; uint32_t size; _xine_list_chunk_t first_chunk; }; static _xine_list_chunk_t *XINE_MALLOC _xine_list_chunk_new (xine_list_t *list, uint32_t size) { _xine_list_chunk_t *chunk; chunk = malloc (sizeof (*chunk) + (size - 1) * sizeof (xine_list_elem_t)); if (!chunk) return NULL; /*chunk->list = list;*/ chunk->max_elems = size; chunk->first_unused = 0; chunk->next = list->chunks; list->chunks = chunk; return chunk; } xine_list_t *XINE_MALLOC xine_list_new (void) { xine_list_t *list; list = malloc (sizeof (*list) + (MIN_CHUNK_SIZE - 1) * sizeof (xine_list_elem_t)); if (!list) return NULL; DLIST_INIT (&list->used); DLIST_INIT (&list->free); list->size = 0; /*list->first_chunk.list = list;*/ list->first_chunk.max_elems = MIN_CHUNK_SIZE; list->first_chunk.first_unused = 0; list->first_chunk.next = NULL; list->chunks = &list->first_chunk; return list; } static void _xine_list_reset (xine_list_t *list) { _xine_list_chunk_t *chunk; chunk = list->chunks; while (chunk != &list->first_chunk) { _xine_list_chunk_t *next = chunk->next; free (chunk); chunk = next; } list->size = 0; list->first_chunk.first_unused = 0; DLIST_INIT (&list->used); DLIST_INIT (&list->free); list->chunks = &list->first_chunk; } void xine_list_clear (xine_list_t *list) { if (list) _xine_list_reset (list); } void xine_list_delete (xine_list_t *list) { if (list) { _xine_list_reset (list); free (list); } } static xine_list_elem_t *_xine_list_elem_new (xine_list_t *list) { xine_list_elem_t *elem; _xine_list_chunk_t *chunk; uint32_t n; if (!DLIST_IS_EMPTY (&list->free)) { elem = (xine_list_elem_t *)list->free.head; DLIST_REMOVE (&elem->node); return elem; } chunk = list->chunks; if (chunk->first_unused < chunk->max_elems) { elem = &chunk->elems[0] + chunk->first_unused; chunk->first_unused++; /*elem->chunk = chunk;*/ return elem; } n = chunk->max_elems * 2; if (n > MAX_CHUNK_SIZE) n = MAX_CHUNK_SIZE; chunk = _xine_list_chunk_new (list, n); if (!chunk) return NULL; elem = &chunk->elems[0]; chunk->first_unused = 1; /* elem->chunk = new_chunk;*/ return elem; } unsigned int xine_list_size (xine_list_t *list) { return list ? list->size : 0; } unsigned int xine_list_empty (xine_list_t *list) { return list ? (list->size == 0) : 1; } xine_list_iterator_t xine_list_front (xine_list_t *list) { return list && list->size ? (xine_list_elem_t *)list->used.head : NULL; } xine_list_iterator_t xine_list_back(xine_list_t *list) { return list && list->size ? (xine_list_elem_t *)list->used.tail : NULL; } void xine_list_push_back(xine_list_t *list, void *value) { xine_list_elem_t *new_elem; if (!list) return; new_elem = _xine_list_elem_new (list); if (!new_elem) return; new_elem->value = value; DLIST_ADD_TAIL (&new_elem->node, &list->used); list->size++; } void xine_list_push_front(xine_list_t *list, void *value) { xine_list_elem_t *new_elem; if (!list) return; new_elem = _xine_list_elem_new (list); if (!new_elem) return; new_elem->value = value; DLIST_ADD_HEAD (&new_elem->node, &list->used); list->size++; } xine_list_iterator_t xine_list_next (xine_list_t *list, xine_list_iterator_t ite) { xine_list_elem_t *elem = ite; elem = elem ? (xine_list_elem_t *)elem->node.next : (xine_list_elem_t *)list->used.head; return elem->node.next ? elem : NULL; } void *xine_list_next_value (xine_list_t *list, xine_list_iterator_t *ite) { xine_list_elem_t *elem = *ite; if (elem) { elem = (xine_list_elem_t *)elem->node.next; } else if (list) { elem = (xine_list_elem_t *)list->used.head; } else { *ite = NULL; return NULL; } if (!elem->node.next) { *ite = NULL; return NULL; } *ite = elem; return elem->value; } xine_list_iterator_t xine_list_prev (xine_list_t *list, xine_list_iterator_t ite) { xine_list_elem_t *elem = ite; elem = elem ? (xine_list_elem_t *)elem->node.prev : (xine_list_elem_t *)list->used.tail; return elem->node.prev ? elem : NULL; } void *xine_list_prev_value (xine_list_t *list, xine_list_iterator_t *ite) { xine_list_elem_t *elem = *ite; if (elem) { elem = (xine_list_elem_t *)elem->node.prev; } else if (list) { elem = (xine_list_elem_t *)list->used.tail; } else { *ite = NULL; return NULL; } if (!elem->node.prev) { *ite = NULL; return NULL; } *ite = elem; return elem->value; } void *xine_list_get_value (xine_list_t *list, xine_list_iterator_t ite) { xine_list_elem_t *elem = ite; (void)list; return elem ? elem->value : NULL; } void xine_list_remove (xine_list_t *list, xine_list_iterator_t position) { xine_list_elem_t *elem = position; if (list && elem) { DLIST_REMOVE (&elem->node); DLIST_ADD_TAIL (&elem->node, &list->free); list->size--; } } xine_list_iterator_t xine_list_insert (xine_list_t *list, xine_list_iterator_t position, void *value) { xine_list_elem_t *new_elem, *elem = position; if (!list) return NULL; new_elem = _xine_list_elem_new (list); if (!new_elem) return NULL; new_elem->value = value; if (!elem) { DLIST_ADD_TAIL (&new_elem->node, &list->used); } else { DLIST_INSERT (&new_elem->node, &elem->node); } list->size++; return new_elem; } xine_list_iterator_t xine_list_find (xine_list_t *list, void *value) { xine_list_elem_t *elem; if (!list) return NULL; for (elem = (xine_list_elem_t *)list->used.head; elem->node.next; elem = (xine_list_elem_t *)elem->node.next) { if (elem->value == value) return elem; } return NULL; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/xine_buffer.c�����������������������������������������������������������0000644�0001750�0001750�00000021051�14647725152�016213� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * generic dynamic buffer functions. The goals * of these functions are (in fact many of these points * are todos): * - dynamic allocation and reallocation depending * on the size of data written to it. * - fast and transparent access to the data. * The user sees only the raw data chunk as it is * returned by the well-known malloc function. * This is necessary since not all data-accessing * functions can be wrapped here. * - some additional health checks are made during * development (eg boundary checks after direct * access to a buffer). This can be turned off in * production state for higher performance. * - A lot of convenient string and memory manipulation * functions are implemented here, where the user * do not have to care about memory chunk sizes. * - Some garbage collention could be implemented as well; * i think of a global structure containing infos * about all allocated chunks. This must be implemented * in a thread-save way... * * Here are some drawbacks (aka policies): * - The user must not pass indexed buffers to xine_buffer_* * functions. * - The pointers passed to xine_buffer_* functions may change * (eg during reallocation). The user must respect that. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <string.h> #include <inttypes.h> #define LOG_MODULE "xine_buffer" #define LOG_VERBOSE /* #define LOG */ #include <xine/xineutils.h> #define CHECKS /* * private data structs */ typedef struct { uint32_t size; uint32_t chunk_size; uint8_t magic; } xine_buffer_header_t; #define XINE_BUFFER_HEADER_SIZE 9 #define XINE_BUFFER_MAGIC 42 /* * xine_buffer stores its additional info just in front of * the public data pointer: * * <header 8 bytes> <magic 1 byte> <data> * ^public pointer * * hopefully the magic value will prevent some segfaults, * if xine_buffer_* functions are called with user-malloced * data chunks... */ /* * some macros */ #define CHECK_MAGIC(x,r) \ do { \ _x_assert ( *(((const uint8_t *)x)-1)==XINE_BUFFER_MAGIC ); \ if (*(((const uint8_t *)x)-1) != XINE_BUFFER_MAGIC) { \ printf("xine_buffer: FATAL: xine_buffer_header not recognized!\n"); \ return r; \ } \ } while (0) #define GET_HEADER(x) ((xine_buffer_header_t*)(((uint8_t*)x)-XINE_BUFFER_HEADER_SIZE)) #define GET_HEADER_CONST(x) ((const xine_buffer_header_t *)(((const uint8_t *)x)-XINE_BUFFER_HEADER_SIZE)) /* reallocs buf, if smaller than size. */ #define GROW_TO(buf, to_size) \ if (GET_HEADER_CONST(buf)->size < (to_size)) { \ int new_size = (to_size) + GET_HEADER_CONST(buf)->chunk_size - \ ((to_size) % GET_HEADER_CONST(buf)->chunk_size);\ \ buf = ((uint8_t*)realloc(((uint8_t*)buf)-XINE_BUFFER_HEADER_SIZE, new_size+XINE_BUFFER_HEADER_SIZE)) + XINE_BUFFER_HEADER_SIZE;\ GET_HEADER(buf)->size=new_size; } /* * returns an initialized pointer to a buffer. * The buffer will be allocated in blocks of * chunk_size bytes. This will prevent permanent * reallocation on slow growing buffers. */ void *xine_buffer_init(int chunk_size) { uint8_t *data=calloc(1, chunk_size+XINE_BUFFER_HEADER_SIZE); xine_buffer_header_t *header=(xine_buffer_header_t*)data; if (!data) { return NULL; } header->size=chunk_size; header->chunk_size=chunk_size; header->magic=XINE_BUFFER_MAGIC; return data+XINE_BUFFER_HEADER_SIZE; } /* * frees a buffer, the macro ensures, that a freed * buffer pointer is set to NULL */ #define xine_buffer_free(buf) buf=_xine_buffer_free(buf) void *_xine_buffer_free(void *buf) { #ifdef CHECKS if (!buf) { lprintf("warning: got NULL pointer\n"); return NULL; } CHECK_MAGIC(buf, NULL); #endif free(((uint8_t*)buf)-XINE_BUFFER_HEADER_SIZE); return NULL; } /* * duplicates a buffer */ void *xine_buffer_dup(const void *buf) { uint8_t *new; #ifdef CHECKS if (!buf) { lprintf("warning: got NULL pointer\n"); return NULL; } CHECK_MAGIC(buf, NULL); #endif new = malloc(GET_HEADER_CONST(buf)->size+XINE_BUFFER_HEADER_SIZE); if (!new) { return NULL; } xine_fast_memcpy(new, ((const uint8_t*)buf)-XINE_BUFFER_HEADER_SIZE, GET_HEADER_CONST(buf)->size+XINE_BUFFER_HEADER_SIZE); return new+XINE_BUFFER_HEADER_SIZE; } /* * will copy len bytes of data into buf at position index. */ #define xine_buffer_copyin(buf,i,data,len) \ buf=_xine_buffer_copyin(buf,i,data,len) void *_xine_buffer_copyin(void *buf, int index, const void *data, int len) { #ifdef CHECKS if (!buf || !data) { lprintf("warning: got NULL pointer\n"); return NULL; } CHECK_MAGIC(buf, NULL); #endif GROW_TO(buf, (size_t)index+len); xine_fast_memcpy(((uint8_t*)buf)+index, data, len); return buf; } /* * will copy len bytes out of buf+index into data. * no checks are made in data. It is treated as an ordinary * user-malloced data chunk. */ void xine_buffer_copyout(const void *buf, int index, void *data, int len) { int hsize; #ifdef CHECKS if (!buf || !data) { lprintf("warning: got NULL pointer\n"); return; } CHECK_MAGIC(buf, ); #endif hsize = GET_HEADER_CONST(buf)->size; if (hsize < index + len) { lprintf("warning: attempt to read over boundary!\n"); if (hsize < index) return; len = hsize - index; } xine_fast_memcpy(data, ((const uint8_t*)buf)+index, len); } /* * set len bytes in buf+index to b. */ #define xine_buffer_set(buf,i,b,len) \ buf=_xine_buffer_set(buf,i,b,len) void *_xine_buffer_set(void *buf, int index, uint8_t b, int len) { #ifdef CHECKS if (!buf) { lprintf("warning: got NULL pointer\n"); return NULL; } CHECK_MAGIC(buf, NULL); #endif GROW_TO(buf, (size_t)(index + len)); memset(((uint8_t*)buf)+index, b, len); return buf; } /* * concatenates given buf (which should contain a null terminated string) * with another string. */ #define xine_buffer_strcat(buf,data) \ buf=_xine_buffer_strcat(buf,data) void *_xine_buffer_strcat(void *buf, const char *data) { return _xine_buffer_strcpy(buf, strlen(buf), data); } /* * copies given string to buf+index */ #define xine_buffer_strcpy(buf,index,data) \ buf=_xine_buffer_strcpy(buf,index,data) void *_xine_buffer_strcpy(void *buf, int index, const char *data) { #ifdef CHECKS if (!buf || !data) { lprintf("warning: got NULL pointer\n"); return NULL; } CHECK_MAGIC(buf, NULL); #endif GROW_TO(buf, index+strlen(data)+1); strcpy(((char*)buf)+index, data); return buf; } /* * returns a pointer to the first occurence of needle. * note, that the returned pointer cannot be used * in any other xine_buffer_* functions. */ char *xine_buffer_strchr(const void *buf, int ch) { #ifdef CHECKS if (!buf) { lprintf("warning: got NULL pointer\n"); return NULL; } CHECK_MAGIC(buf, NULL); #endif return strchr((const char *)buf, ch); } /* * get allocated memory size */ int xine_buffer_get_size(const void *buf) { #ifdef CHECKS if (!buf) { lprintf("warning: got NULL pointer\n"); return 0; } CHECK_MAGIC(buf, 0); #endif return GET_HEADER_CONST(buf)->size; } /* * ensures a specified buffer size if the user want to * write directly to the buffer. Normally the special * access functions defined here should be used. */ #define xine_buffer_ensure_size(buf,data) \ buf=_xine_buffer_ensure_size(buf,data) void *_xine_buffer_ensure_size(void *buf, int size) { #ifdef CHECKS if (!buf) { lprintf("warning: got NULL pointer\n"); return 0; } CHECK_MAGIC(buf, 0); #endif GROW_TO(buf, (size_t)size); return buf; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/mfrag.c�����������������������������������������������������������������0000644�0001750�0001750�00000016120�14647725152�015014� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2021 the xine project * Copyright (C) 2021 Torsten Jager <t.jager@gmx.de> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Xine media fragment list utility. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #define LOG_MODULE "mfrag" #define LOG_VERBOSE /* #define LOG */ #include <xine/mfrag.h> #define MFRAG_STEP 256 typedef struct { int64_t t, p; /** << start time, byte pos */ uint32_t d, l; /** << duration or 0, byte length or 0 if unknoen */ } xine_mfrag_frag_t; struct xine_mfrag_list_s { xine_mfrag_frag_t *frags; uint32_t refs; uint32_t have, used, known_nd, known_nl; /** << fragment counts */ uint32_t dirty_from; /** << rebuild start times/byte pos from here when needed */ uint32_t avg_d, avg_l; uint64_t known_d; /** << time sum */ uint64_t known_l; /** << byte length sum */ }; static void _xine_mfrag_fix (xine_mfrag_list_t *list, uint32_t last) { /** rebuild on demand only, for speed, and forward only, to avoid mass confusion. */ xine_mfrag_frag_t *frag, *end; uint64_t t, p; list->avg_d = list->known_nd ? list->known_d / list->known_nd : 0; list->avg_l = list->known_nl ? list->known_l / list->known_nl : 0; frag = list->frags + list->dirty_from; end = list->frags + last; if (frag == list->frags) { frag[0].t = frag[1].t = 0; frag[0].p = 0; frag[1].p = frag[0].l; frag += 1; } t = frag[0].t; p = frag[0].p; while (frag < end) { t += frag[0].d ? frag[0].d : list->avg_d; frag[1].t = t; p += frag[0].l ? frag[0].l : list->avg_l; frag[1].p = p; frag += 1; } list->dirty_from = last; } static void _xine_mfrag_test (xine_mfrag_list_t *list, uint32_t last) { if (list->dirty_from < last) _xine_mfrag_fix (list, last); } void xine_mfrag_list_open (xine_mfrag_list_t **plist) { xine_mfrag_list_t *list; xine_mfrag_frag_t *frag; if (!plist) return; list = *plist; if (list) { list->refs++; return; } list = malloc (sizeof (*list)); if (!list) return; list->refs = 1; list->have = MFRAG_STEP - 2; list->used = list->known_nd = list->known_nl = 0; list->dirty_from = 0; list->avg_d = list->avg_l = 0; list->known_d = list->known_l = 0; frag = malloc ((list->have + 2) * sizeof (*frag)); if (!frag) { free (list); return; } list->frags = frag; frag[0].d = 1; frag[0].l = 0; frag[0].t = frag[0].p = 0; frag[1].d = frag[1].l = 0; *plist = list; } int xine_mfrag_set_index_frag (xine_mfrag_list_t *list, xine_mfrag_index_t index, int64_t dur, off_t len) { xine_mfrag_frag_t *frag; uint32_t idx; if (!list) return 0; if (index < 0) return 0; if (index == 0) { if (dur >= 0) list->frags[0].d = dur; if ((len >= 0) && ((uint32_t)len != list->frags[0].l)) { list->frags[0].l = len; list->dirty_from = 0; } return 1; } idx = index; if (idx > list->used + 1) return 0; if (idx == list->used + 1) { if (list->used >= list->have) { frag = realloc (list->frags, (list->have + 2 + MFRAG_STEP) * sizeof (*frag)); if (!frag) return 0; list->frags = frag; list->have += MFRAG_STEP; } list->used += 1; if (idx < list->dirty_from) list->dirty_from = idx; frag = list->frags + idx; if (dur >= 0) { frag[0].d = dur; list->known_d += dur; list->known_nd += 1; } else { frag[0].d = 0; } if (len >= 0) { frag[0].l = len; list->known_l += len; list->known_nl += 1; } else { frag[0].l = 0; } frag[1].d = frag[1].l = 0; return 1; } frag = list->frags + idx; if ((dur >= 0) && ((uint32_t)dur != frag[0].d)) { if (!frag[0].d) { list->known_nd += 1; list->known_d += dur; } else if ((uint32_t)dur == 0) { list->known_nd -= 1; list->known_d -= frag[0].d; } else { list->known_d -= frag[0].d; list->known_d += dur; } frag[0].d = dur; if (idx < list->dirty_from) list->dirty_from = idx; } if ((len >= 0) && ((uint32_t)len != frag[0].l)) { if (!frag[0].l) { list->known_nl += 1; list->known_l += len; } else if ((uint32_t)len == 0) { list->known_nl -= 1; list->known_l -= frag[0].l; } else { list->known_l -= frag[0].l; list->known_l += len; } frag[0].l = len; if (idx < list->dirty_from) list->dirty_from = idx; } return 1; } int32_t xine_mfrag_get_frag_count (xine_mfrag_list_t *list) { if (!list) return 0; return list->used; } xine_mfrag_index_t xine_mfrag_find_time (xine_mfrag_list_t *list, int64_t timepos) { uint32_t b, m, l, e; if (!list) return -1; _xine_mfrag_test (list, list->used + 1); b = l = 1; e = list->used + 2; m = (b + e) >> 1; while (m != l) { int64_t d = timepos - list->frags[m].t; if (d < 0) e = m; else b = m; l = m; m = (b + e) >> 1; } return b; } xine_mfrag_index_t xine_mfrag_find_pos (xine_mfrag_list_t *list, off_t offs) { uint32_t b, l, m, e; if (!list) return -1; _xine_mfrag_test (list, list->used + 1); b = l = list->frags[0].l ? 0 : 1; e = list->used + 2; m = (b + e) >> 1; while (m != l) { int64_t d = offs - list->frags[m].p; if (d < 0) e = m; else b = m; l = m; m = (b + e) >> 1; } return b; } int xine_mfrag_get_index_frag (xine_mfrag_list_t *list, xine_mfrag_index_t index, int64_t *dur, off_t *len) { xine_mfrag_frag_t *frag; uint32_t idx; if (!list) return 0; if (index < 0) return 0; idx = index; if (idx > list->have) return 0; frag = list->frags + idx; if (dur) *dur = frag[0].d; if (len) *len = frag[0].l; return 1; } int xine_mfrag_get_index_start (xine_mfrag_list_t *list, xine_mfrag_index_t index, int64_t *timepos, off_t *offs) { xine_mfrag_frag_t *frag; uint32_t idx; if (!list) return 0; if (!list->frags || (index < 0)) return 0; idx = index; if (idx > list->have + 1) return 0; _xine_mfrag_test (list, idx); frag = list->frags + idx; if (timepos) *timepos = frag[0].t; if (offs) *offs = frag[0].p; return 1; } void xine_mfrag_list_close (xine_mfrag_list_t **plist) { if (plist && *plist) { xine_mfrag_list_t *list = *plist; if (--list->refs == 0) { free (list->frags); list->frags = NULL; free (list); *plist = NULL; } } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/mangle.h����������������������������������������������������������������0000644�0001750�0001750�00000003436�14647725152�015176� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at> * copyright (c) 2008-2010 the xine-project * * This file is part of FFmpeg. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /** * @file * * @brief MANGLE definition from FFmpeg project, until the code is ported * not to require this (considered an hack by the FFmpeg project. */ #ifndef _XINE_MANGLE_H #define _XINE_MANGLE_H #if defined(PIC) && ! defined(__PIC__) #define __PIC__ #endif // Use rip-relative addressing if compiling PIC code on x86-64. #if defined(__MINGW32__) || defined(__CYGWIN__) || defined(__DJGPP__) || \ defined(__OS2__) || (defined (__OpenBSD__) && !defined(__ELF__)) # if defined(__MINGW64__) # define EXTERN_PREFIX "" # else # define EXTERN_PREFIX "_" # endif # if defined(__x86_64__) && defined(__PIC__) # define MANGLE(a) EXTERN_PREFIX #a"(%%rip)" # else # define MANGLE(a) EXTERN_PREFIX #a # endif #else # if defined(__x86_64__) && defined(__PIC__) # define MANGLE(a) #a"(%%rip)" # elif defined(__APPLE__) # define MANGLE(a) "_" #a # else # define MANGLE(a) #a # endif #endif #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/cpu_accel.c�������������������������������������������������������������0000644�0001750�0001750�00000025746�14647725152�015654� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * cpu_accel.c * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #if defined(HAVE_MLIB) && defined(MLIB_LAZYLOAD) #include <dlfcn.h> #endif #if defined (__SVR4) && defined (__sun) #include <sys/systeminfo.h> #endif #define LOG_MODULE "cpu_accel" #define LOG_VERBOSE /* #define LOG */ #include <xine/xineutils.h> #if defined(PIC) && ! defined(__PIC__) #define __PIC__ #endif #if defined(__i386__) || defined(__x86_64__) #include <signal.h> #include <setjmp.h> /* TJ. x86 instructions are variable length byte strings. To save space, there is no generic length marker. A processor thus may throw an exception at _any_ byte of an unknown instruction. We use longjmp () to get back on track, although it is not thread safe with a static jmp_buf. */ static jmp_buf sigill_return; static void sigill_handler (int n) { (void)n; longjmp(sigill_return, 1); } static uint32_t arch_accel (void) { volatile uint32_t caps = 0; #ifndef __x86_64__ volatile uint32_t is_AMD; #endif #if defined(__x86_64__) || \ ( defined(__SSE__) && defined(__SSE2__) && defined(__MMX__) ) /* No need to test for this on AMD64, we know what the platform has. */ caps = MM_ACCEL_X86_MMX | MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT | MM_ACCEL_X86_SSE2 # if defined(__3dNOW__) | MM_ACCEL_X86_3DNOW # endif ; #endif #ifndef _MSC_VER void (*old_sigill_handler)(int); uint32_t eax, ebx, ecx, edx; #if defined(__x86_64__) #define cpuid(op,eax,ebx,ecx,edx) \ __asm__ ("push %%rbx\n\t" \ "cpuid\n\t" \ "movl %%ebx,%1\n\t" \ "pop %%rbx" \ : "=a" (eax), \ "=S" (ebx), \ "=c" (ecx), \ "=d" (edx) \ : "a" (op) \ : "cc") #elif !defined(__PIC__) #define cpuid(op,eax,ebx,ecx,edx) \ __asm__ ("cpuid" \ : "=a" (eax), \ "=b" (ebx), \ "=c" (ecx), \ "=d" (edx) \ : "a" (op) \ : "cc") #else /* PIC version : save ebx */ #define cpuid(op,eax,ebx,ecx,edx) \ __asm__ ("pushl %%ebx\n\t" \ "cpuid\n\t" \ "movl %%ebx,%1\n\t" \ "popl %%ebx" \ : "=a" (eax), \ "=S" (ebx), \ "=c" (ecx), \ "=d" (edx) \ : "a" (op) \ : "cc") #endif #ifndef __x86_64__ __asm__ ("pushfl\n\t" "pushfl\n\t" "popl %0\n\t" "movl %0,%1\n\t" "xorl $0x200000,%0\n\t" "pushl %0\n\t" "popfl\n\t" "pushfl\n\t" "popl %0\n\t" "popfl" : "=r" (eax), "=r" (ebx) : : "cc"); if (eax == ebx) { /* no cpuid */ return 0; } cpuid (0x00000000, eax, ebx, ecx, edx); if (!eax) { /* vendor string only */ return 0; } /* (little endian) "Auth" "enti" "cAMD" */ is_AMD = (ebx == 0x68747541) && (edx == 0x69746e65) && (ecx == 0x444d4163); #endif /* __x86_64__ */ cpuid (0x00000001, eax, ebx, ecx, edx); #ifndef __x86_64__ if (edx & 0x00800000) { /* MMX */ caps |= MM_ACCEL_X86_MMX; } if (edx & 0x02000000) { /* SSE - identical to AMD MMX extensions */ caps |= MM_ACCEL_X86_SSE | MM_ACCEL_X86_MMXEXT; } if (edx & 0x04000000) { /* SSE2 */ caps |= MM_ACCEL_X86_SSE2; } #endif /* __x86_64__ */ if (ecx & 0x00000001) { caps |= MM_ACCEL_X86_SSE3; } if (ecx & 0x00000200) { caps |= MM_ACCEL_X86_SSSE3; } if (ecx & 0x00080000) { caps |= MM_ACCEL_X86_SSE4; } if (ecx & 0x00100000) { caps |= MM_ACCEL_X86_SSE42; } /* Check OXSAVE and AVX bits */ if ((ecx & 0x18000000) == 0x18000000) { /* test OS support for AVX */ old_sigill_handler = signal (SIGILL, sigill_handler); if (setjmp(sigill_return)) { lprintf("OS doesn't support AVX instructions.\n"); } else { /* Get value of extended control register 0 */ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (0)); if ((eax & 0x6) == 0x6) { caps |= MM_ACCEL_X86_AVX; } } signal(SIGILL, old_sigill_handler); } #ifndef __x86_64__ cpuid (0x80000000, eax, ebx, ecx, edx); if (eax >= 0x80000001) { cpuid (0x80000001, eax, ebx, ecx, edx); if (edx & 0x80000000) { /* AMD 3DNow extensions */ caps |= MM_ACCEL_X86_3DNOW; } if (is_AMD && (edx & 0x00400000)) { /* AMD MMX extensions */ caps |= MM_ACCEL_X86_MMXEXT; } } #endif /* __x86_64__ */ #endif /* _MSC_VER */ #ifndef __x86_64__ /* test OS support for SSE */ if (caps & MM_ACCEL_X86_SSE) { old_sigill_handler = signal (SIGILL, sigill_handler); if (setjmp(sigill_return)) { lprintf("OS doesn't support SSE instructions.\n"); caps &= ~(MM_ACCEL_X86_SSE|MM_ACCEL_X86_SSE2| MM_ACCEL_X86_SSE3|MM_ACCEL_X86_SSSE3| MM_ACCEL_X86_SSE4|MM_ACCEL_X86_SSE42); } else { __asm__ volatile ("xorps %xmm0, %xmm0"); } signal(SIGILL, old_sigill_handler); } #endif /* x86_64 */ return caps; } #endif /* i386 or x86_64 */ #if defined(ARCH_PPC) && defined(ENABLE_ALTIVEC) #include <signal.h> #include <setjmp.h> static sigjmp_buf jmpbuf; static volatile sig_atomic_t canjump = 0; static void sigill_handler (int sig) { if (!canjump) { signal (sig, SIG_DFL); raise (sig); } canjump = 0; siglongjmp (jmpbuf, 1); } static uint32_t arch_accel (void) { /* FIXME: Autodetect cache line size via AUX ELF vector or otherwise */ uint32_t flags = 0; signal (SIGILL, sigill_handler); if (sigsetjmp (jmpbuf, 1)) { signal (SIGILL, SIG_DFL); return flags; } canjump = 1; #ifndef HOST_OS_DARWIN __asm__ volatile ("mtspr 256, %0\n\t" "vand %%v0, %%v0, %%v0" : : "r" (-1)); #else __asm__ volatile ("mtspr 256, r0\n\t" "vand v0, v0, v0" : : "r" (-1)); #endif signal (SIGILL, SIG_DFL); return flags|MM_ACCEL_PPC_ALTIVEC; } #endif /* ARCH_PPC */ #if defined(ARCH_SPARC) && defined(ENABLE_VIS) #if defined (__SVR4) && defined (__sun) static uint32_t arch_accel (void) { uint32_t flags = 0; long len; char isalist_[257], *isalist, *s1, *last, *token; len = sysinfo(SI_ISALIST, isalist_, 257); if (len > 257) { isalist = malloc(len); sysinfo(SI_ISALIST, isalist, len); } else { isalist = isalist_; } s1 = isalist; while (token = strtok_r(s1, " ", &last)) { if (strlen(token) > 4) { if (strcmp(token + (strlen(token) - 4), "+vis") == 0) { flags |= MM_ACCEL_SPARC_VIS; } } if (strlen(token) > 5) { if (strcmp(token + (strlen(token) - 5), "+vis2") == 0) { flags |= MM_ACCEL_SPARC_VIS2; } } s1 = NULL; } if (isalist != isalist_) { free(isalist); } return flags; } #else #include <signal.h> #include <setjmp.h> static sigjmp_buf jmpbuf; static volatile sig_atomic_t canjump = 0; static void sigill_handler (int sig) { if (!canjump) { signal(sig, SIG_DFL); raise(sig); } canjump = 0; siglongjmp(jmpbuf, 1); } static uint32_t arch_accel (void) { uint32_t flags = 0; signal(SIGILL, sigill_handler); if (sigsetjmp(jmpbuf, 1)) { signal(SIGILL, SIG_DFL); return flags; } canjump = 1; /* pdist %f0, %f0, %f0 */ __asm__ __volatile__(".word\t0x81b007c0"); canjump = 0; flags |= MM_ACCEL_SPARC_VIS; if (sigsetjmp(jmpbuf, 1)) { signal(SIGILL, SIG_DFL); return flags; } canjump = 1; /* edge8n %g0, %g0, %g0 */ __asm__ __volatile__(".word\t0x81b00020"); canjump = 0; flags |= MM_ACCEL_SPARC_VIS2; signal(SIGILL, SIG_DFL); return flags; } #endif #endif /* ARCH_SPARC */ uint32_t xine_mm_accel (void) { static int initialized = 0; static uint32_t accel = 0; if (!initialized) { #ifdef HAVE_MLIB #ifdef MLIB_LAZYLOAD void *hndl; if ((hndl = dlopen("libmlib.so.2", RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE)) != NULL) { dlclose(hndl); accel |= MM_ACCEL_MLIB; } #else accel |= MM_ACCEL_MLIB; #endif #endif #if defined(__i386__) || defined(__x86_64__) || (defined(ARCH_PPC) && defined(ENABLE_ALTIVEC)) || (defined(ARCH_SPARC) && defined(ENABLE_VIS)) accel |= arch_accel(); #endif if(getenv("XINE_NO_ACCEL")) { accel = 0; } initialized = 1; } return accel; } /* * xine_cpu_count() */ #ifdef HAVE_SCHED_GETAFFINITY # ifndef _GNU_SOURCE # define _GNU_SOURCE # endif # include <sched.h> #endif #ifdef _WIN32 # include <windows.h> #endif #ifdef HAVE_SYSCTL # ifdef HAVE_SYS_PARAM_H # include <sys/param.h> # endif # include <sys/types.h> # include <sys/sysctl.h> #endif #include <unistd.h> static int _cpu_count() { int cpu_count = 1; #if HAVE_SCHED_GETAFFINITY && defined(CPU_COUNT) cpu_set_t cpuset; CPU_ZERO(&cpuset); if (!sched_getaffinity(0, sizeof(cpuset), &cpuset)) cpu_count = CPU_COUNT(&cpuset); #elif defined(HAVE_SYSCTL) && defined(HW_NCPUONLINE) int mib[2] = { CTL_HW, HW_NCPUONLINE }; size_t len = sizeof(cpu_count); if (sysctl(mib, 2, &cpu_count, &len, NULL, 0) == -1) cpu_count = 1; #elif defined(HAVE_SYSCTL) && defined(HW_NCPU) int mib[2] = { CTL_HW, HW_NCPU }; size_t len = sizeof(cpu_count); if (sysctl(mib, 2, &cpu_count, &len, NULL, 0) == -1) cpu_count = 1; #elif defined(HAVE_SYSCONF) && defined(_SC_NPROC_ONLN) cpu_count = sysconf(_SC_NPROC_ONLN); #elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN) cpu_count = sysconf(_SC_NPROCESSORS_ONLN); #elif defined(_WIN32) SYSTEM_INFO sysinfo; GetNativeSystemInfo(&sysinfo); cpu_count = sysinfo.dwNumberOfProcessors; #else # warning CPU count detection missing ! #endif if (cpu_count < 1) cpu_count = 1; else if (cpu_count > 32) cpu_count = 32; return cpu_count; } int xine_cpu_count(void) { static volatile int cpu_count = -1; if (cpu_count < 0) { cpu_count = _cpu_count(); } return cpu_count; } ��������������������������xine-lib-1.2/src/xine-utils/monitor.c���������������������������������������������������������������0000644�0001750�0001750�00000010056�14647725152�015411� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * debug print and profiling functions - implementation */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <pthread.h> #include <sys/time.h> #include <xine/xineutils.h> #define MAX_ID 10 #ifndef NDEBUG typedef struct { uint64_t p_times; uint64_t p_start; long p_calls; const char *p_label; } xine_profiler_t; static xine_profiler_t profiler[MAX_ID]; static pthread_mutex_t profiler_lock = PTHREAD_MUTEX_INITIALIZER; void xine_profiler_init () { pthread_mutex_lock(&profiler_lock); memset(profiler, 0, sizeof(profiler)); pthread_mutex_unlock(&profiler_lock); } int xine_profiler_allocate_slot (const char *label) { int id; pthread_mutex_lock(&profiler_lock); for (id = 0; id < MAX_ID && profiler[id].p_label != NULL; id++) ; if (id >= MAX_ID) { pthread_mutex_unlock(&profiler_lock); return -1; } profiler[id].p_label = label; pthread_mutex_unlock(&profiler_lock); return id; } #if defined(ARCH_X86_32) static __inline__ uint64_t rdtsc(void) { unsigned long long int x; __asm__ volatile ("rdtsc\n\t" : "=A" (x)); return x; } #elif defined(ARCH_X86_X32) || defined(ARCH_X86_64) static __inline__ uint64_t rdtsc(void) { unsigned long long int a, d; __asm__ volatile ("rdtsc\n\t" : "=a" (a), "=d" (d)); return (d << 32) | (a & 0xffffffff); } #endif void xine_profiler_start_count (int id) { if ( id >= MAX_ID || id < 0 ) return; #if defined(ARCH_X86) profiler[id].p_start = rdtsc(); #endif } void xine_profiler_stop_count (int id) { if ( id >= MAX_ID || id < 0 ) return; #if defined(ARCH_X86) profiler[id].p_times += rdtsc() - profiler[id].p_start; #endif profiler[id].p_calls++; } void xine_profiler_print_results (void) { int i; #if defined(ARCH_X86) static uint64_t cpu_speed; /* cpu cyles/usec */ if (!cpu_speed) { uint64_t tsc_start, tsc_end; struct timeval tv_start, tv_end; tsc_start = rdtsc(); gettimeofday(&tv_start, NULL); xine_usec_sleep(100000); tsc_end = rdtsc(); gettimeofday(&tv_end, NULL); cpu_speed = (tsc_end - tsc_start) / ((tv_end.tv_sec - tv_start.tv_sec) * 1e6 + tv_end.tv_usec - tv_start.tv_usec); } #endif printf ("\n\nPerformance analysis:\n\n" "%-3s %-24.24s %12s %9s %12s %9s\n" "----------------------------------------------------------------------------\n", "ID", "name", "cpu cycles", "calls", "cycles/call", "usec/call"); for (i=0; i<MAX_ID; i++) { if (profiler[i].p_label) { printf ("%2d: %-24.24s %12" PRIu64 " %9ld", i, profiler[i].p_label, profiler[i].p_times, profiler[i].p_calls); if (profiler[i].p_calls) { printf(" %12" PRIu64, profiler[i].p_times / (uint64_t)profiler[i].p_calls); #if defined(ARCH_X86) printf(" %9" PRIu64, profiler[i].p_times / ((uint64_t)cpu_speed * profiler[i].p_calls)); #endif } printf ("\n"); } } } #else /* DEBUG */ #define NO_PROFILER_MSG {printf("xine's profiler is unavailable.\n");} /* Dummies */ void xine_profiler_init (void) { NO_PROFILER_MSG } int xine_profiler_allocate_slot (const char *label) { (void)label; return -1; } void xine_profiler_start_count (int id) { (void)id; } void xine_profiler_stop_count (int id) { (void)id; } void xine_profiler_print_results (void) { NO_PROFILER_MSG } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/ppcasm_string.S���������������������������������������������������������0000644�0001750�0001750�00000006317�14647725152�016560� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * BK Id: SCCS/s.string.S 1.9 10/25/01 10:08:51 trini */ /* * String handling functions for PowerPC. * * Copyright (C) 1996 Paul Mackerras. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ //#warning Be forewarned - using PowerPC assembly #include "ppc_asm.tmpl" #define N_FUN 36 #define N_SO 100 #define COPY_16_BYTES \ lwz r7,4(r4); \ lwz r8,8(r4); \ lwz r9,12(r4); \ lwzu r10,16(r4); \ stw r7,4(r6); \ stw r8,8(r6); \ stw r9,12(r6); \ stwu r10,16(r6) #define __stringify_1(x) #x #define __stringify(x) __stringify_1(x) #define _GLOBFN(n)\ .type n,@function; \ .globl n;\ .hidden n;\ n: #define _SIZE(n) \ .size n, .-n .text #warning FIXME: Get cache line sizes from /proc #define L1_CACHE_LINE_SIZE 32 CACHELINE_BYTES = 32 LG_CACHELINE_BYTES = 5 CACHELINE_MASK = (32 -1) /* * This version uses dcbz on the complete cache lines in the * destination area to reduce memory traffic. This requires that * the destination area is cacheable. * We only use this version if the source and dest don't overlap. * -- paulus. */ _GLOBFN(ppcasm_cacheable_memcpy) add r7,r3,r5 /* test if the src & dst overlap */ add r8,r4,r5 cmplw 0,r4,r7 cmplw 1,r3,r8 crand 0,0,4 /* cr0.lt &= cr1.lt */ blt 66f //ppcasm_memcpy /* if regions overlap */ addi r4,r4,-4 addi r6,r3,-4 neg r0,r3 andi. r0,r0,CACHELINE_MASK /* # bytes to start of cache line */ beq 58f cmplw 0,r5,r0 /* is this more than total to do? */ blt 63f /* if not much to do */ andi. r8,r0,3 /* get it word-aligned first */ subf r5,r0,r5 mtctr r8 beq+ 61f 70: lbz r9,4(r4) /* do some bytes */ stb r9,4(r6) addi r4,r4,1 addi r6,r6,1 bdnz 70b 61: srwi. r0,r0,2 mtctr r0 beq 58f 72: lwzu r9,4(r4) /* do some words */ stwu r9,4(r6) bdnz 72b 58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */ clrlwi r5,r5,32-LG_CACHELINE_BYTES li r11,4 mtctr r0 beq 63f 53: #if !defined(CONFIG_8xx) dcbz r11,r6 #endif COPY_16_BYTES #if L1_CACHE_LINE_SIZE >= 32 COPY_16_BYTES #if L1_CACHE_LINE_SIZE >= 64 COPY_16_BYTES COPY_16_BYTES #if L1_CACHE_LINE_SIZE >= 128 COPY_16_BYTES COPY_16_BYTES COPY_16_BYTES COPY_16_BYTES #endif #endif #endif bdnz 53b 63: srwi. r0,r5,2 mtctr r0 beq 64f 30: lwzu r0,4(r4) stwu r0,4(r6) bdnz 30b 64: andi. r0,r5,3 mtctr r0 beq+ 65f 40: lbz r0,4(r4) stb r0,4(r6) addi r4,r4,1 addi r6,r6,1 bdnz 40b 65: blr _SIZE(ppcasm_cacheable_memcpy) _GLOBFN(ppcasm_memcpy) 66: srwi. r7,r5,3 addi r6,r3,-4 addi r4,r4,-4 beq 2f /* if less than 8 bytes to do */ andi. r0,r6,3 /* get dest word aligned */ mtctr r7 bne 5f 1: lwz r7,4(r4) lwzu r8,8(r4) stw r7,4(r6) stwu r8,8(r6) bdnz 1b andi. r5,r5,7 2: cmplwi 0,r5,4 blt 3f lwzu r0,4(r4) addi r5,r5,-4 stwu r0,4(r6) 3: cmpwi 0,r5,0 beqlr mtctr r5 addi r4,r4,3 addi r6,r6,3 4: lbzu r0,1(r4) stbu r0,1(r6) bdnz 4b blr 5: subfic r0,r0,4 mtctr r0 6: lbz r7,4(r4) addi r4,r4,1 stb r7,4(r6) addi r6,r6,1 bdnz 6b subf r5,r0,r5 rlwinm. r7,r5,32-3,3,31 beq 2b mtctr r7 b 1b _SIZE(ppcasm_memcpy) �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-utils/memcpy.c����������������������������������������������������������������0000644�0001750�0001750�00000056267�14647725152�015232� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * These are the MMX/MMX2/SSE optimized versions of memcpy * * This code was adapted from Linux Kernel sources by Nick Kurshev to * the mplayer program. (http://mplayer.sourceforge.net) * * Miguel Freitas split the #ifdefs into several specialized functions that * are benchmarked at runtime by xine. Some original comments from Nick * have been preserved documenting some MMX/SSE oddities. * Also added kernel memcpy function that seems faster than libc one. * */ #define ARCH_WARN #ifdef HAVE_CONFIG_H #include "config.h" #endif #if defined (ARCH_PPC) && !defined (HOST_OS_DARWIN) #include "ppcasm_string.h" #endif #ifdef HAVE_SYS_TIMES_H #include <sys/times.h> #else #include <time.h> #endif #include <stdlib.h> #include <string.h> #include <time.h> /* clock_gettime */ #define LOG_MODULE "memcpy" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include "../xine-engine/xine_private.h" void *(* xine_fast_memcpy)(void *to, const void *from, size_t len) = NULL; /* Original comments from mplayer (file: aclib.c) This part of code was taken by me from Linux-2.4.3 and slightly modified for MMX, MMX2, SSE instruction set. I have done it since linux uses page aligned blocks but mplayer uses weakly ordered data and original sources can not speedup them. Only using PREFETCHNTA and MOVNTQ together have effect! >From IA-32 Intel Architecture Software Developer's Manual Volume 1, Order Number 245470: "10.4.6. Cacheability Control, Prefetch, and Memory Ordering Instructions" Data referenced by a program can be temporal (data will be used again) or non-temporal (data will be referenced once and not reused in the immediate future). To make efficient use of the processor's caches, it is generally desirable to cache temporal data and not cache non-temporal data. Overloading the processor's caches with non-temporal data is sometimes referred to as "polluting the caches". The non-temporal data is written to memory with Write-Combining semantics. The PREFETCHh instructions permits a program to load data into the processor at a suggested cache level, so that it is closer to the processors load and store unit when it is needed. If the data is already present in a level of the cache hierarchy that is closer to the processor, the PREFETCHh instruction will not result in any data movement. But we should you PREFETCHNTA: Non-temporal data fetch data into location close to the processor, minimizing cache pollution. The MOVNTQ (store quadword using non-temporal hint) instruction stores packed integer data from an MMX register to memory, using a non-temporal hint. The MOVNTPS (store packed single-precision floating-point values using non-temporal hint) instruction stores packed floating-point data from an XMM register to memory, using a non-temporal hint. The SFENCE (Store Fence) instruction controls write ordering by creating a fence for memory store operations. This instruction guarantees that the results of every store instruction that precedes the store fence in program order is globally visible before any store instruction that follows the fence. The SFENCE instruction provides an efficient way of ensuring ordering between procedures that produce weakly-ordered data and procedures that consume that data. If you have questions please contact with me: Nick Kurshev: nickols_k@mail.ru. */ /* mmx v.1 Note: Since we added alignment of destinition it speedups of memory copying on PentMMX, Celeron-1 and P2 upto 12% versus standard (non MMX-optimized) version. Note: on K6-2+ it speedups memory copying upto 25% and on K7 and P3 about 500% (5 times). */ /* Additional notes on gcc assembly and processors: [MF] prefetch is specific for AMD processors, the intel ones should be prefetch0, prefetch1, prefetch2 which are not recognized by my gcc. prefetchnta is supported both on athlon and pentium 3. therefore i will take off prefetchnta instructions from the mmx1 version to avoid problems on pentium mmx and k6-2. quote of the day: "Using prefetches efficiently is more of an art than a science" */ #if defined(ARCH_X86) #if defined(ARCH_X86_64) # define DOPTR(what,from,to) "\n\t"what"q\t"from", "to # define BUMPPTR(offs,num) "\n\tleaq\t"offs"(%"num"), %"num # define MEM1(reg) "(%"reg")" # define MEM2(offs,reg) offs"(%"reg")" #elif defined(ARCH_X86_X32) /* Mapping a pointer to a register yields a 32bit move, * which does extend to 64bit properly. Dereferencing as * 32bit (%esi) will work but takes an extra 1 byte prefix, * so lets use 64bit (%rsi) instead. * Inserting an extra letter into operand reference modifies * register size something like this: * "%2, %b2, %h2, %w2, %k2, %q2" -> "%edx, %dl, %dh, %dx, %edx, %rdx" * For some reason, "info gcc" 4.5 silences this useful feature. */ # define DOPTR(what,from,to) "\n\t"what"l\t"from", "to # define BUMPPTR(offs,num) "\n\tleaq\t"offs"(%q"num"), %q"num # define MEM1(reg) "(%q"reg")" # define MEM2(offs,reg) offs"(%q"reg")" #else # define DOPTR(what,from,to) "\n\t"what"l\t"from", "to # define BUMPPTR(offs,num) "\n\tleal\t"offs"(%"num"), %"num # define MEM1(reg) "(%"reg")" # define MEM2(offs,reg) offs"(%"reg")" #endif #ifndef _MSC_VER /* for small memory blocks (<256 bytes) this version is faster */ /* rep_movsb (void *, const void *, uintptr_t) */ #define rep_movsb(to,from,n)\ __asm__ __volatile__ (\ "cld\n\trep movsb"\ : "=D" (to), "=S" (from), "=c" (n)\ : "0" (to), "1" (from), "2" (n)\ : "cc", "memory"\ ) /* idea from linux kernel __memcpy (from: /include/asm/string.h) */ /* then, added target alignment and 64bit version. */ static __inline__ void *linux_kernel_memcpy_impl (void *to, const void *from, size_t n) { void *ret = to; uintptr_t s = n; if (s < 16) { if (s) rep_movsb (to, from, s); } else { uintptr_t d; __asm__ __volatile__ ( "cld" DOPTR("mov","%1","%3") "\n\ttestb\t$1, %b3" "\n\tje\t1f" "\n\tmovsb" DOPTR("sub","$1","%2") DOPTR("mov","%1","%3") "\n1:" "\n\ttestb\t$2, %b3" "\n\tje\t2f" "\n\tmovsw" DOPTR("sub","$2","%2") DOPTR("mov","%1","%3") "\n2:" #if defined(ARCH_X86_64) || defined(ARCH_X86_X32) "\n\ttestb\t$4, %b3" "\n\tje\t3f" "\n\tmovsl" DOPTR("sub","$4","%2") "\n3:" DOPTR("mov","%2","%3") DOPTR("shr","$3","%2") "\n\trep movsq" "\n\ttestb\t$4, %b3" "\n\tje\t4f" "\n\tmovsl" "\n4:" #else DOPTR("mov","%2","%3") DOPTR("shr","$2","%2") "\n\trep movsl" #endif "\n\ttestb\t$2, %b3" "\n\tje\t5f" "\n\tmovsw" "\n5:" "\n\ttestb\t$1, %b3" "\n\tje\t6f" "\n\tmovsb" "\n6:" : "=S" (from), "=D" (to), "=c" (s), "=&q" (d) : "0" (from), "1" (to), "2" (s) : "cc", "memory" ); } return ret; } #define MMX1_MIN_LEN 0x800 /* 2K blocks */ #define MIN_LEN 0x40 /* 64-byte blocks */ /* SSE note: i tried to move 128 bytes a time instead of 64 but it didn't make any measureable difference. i'm using 64 for the sake of simplicity. [MF] */ static void * sse_memcpy(void * to, const void * from, size_t len) { const uint8_t *pf; void *retval = to; /* PREFETCH has effect even for MOVSB instruction ;) */ pf = (const uint8_t *)((uintptr_t)from & ~(uintptr_t)31); __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "0") "\n\tprefetchnta\t"MEM2( "32","0") "\n\tprefetchnta\t"MEM2( "64","0") "\n\tprefetchnta\t"MEM2( "96","0") : : "r" (pf) ); if (len < 128) return linux_kernel_memcpy_impl (to, from, len); __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM2("128","0") "\n\tprefetchnta\t"MEM2("160","0") "\n\tprefetchnta\t"MEM2("192","0") "\n\tprefetchnta\t"MEM2("224","0") "\n\tprefetchnta\t"MEM2("256","0") "\n\tprefetchnta\t"MEM2("288","0") "\n\tprefetchnta\t"MEM2("320","0") "\n\tprefetchnta\t"MEM2("352","0") "\n\tprefetchnta\t"MEM2("384","0") "\n\tprefetchnta\t"MEM2("416","0") "\n\tprefetchnta\t"MEM2("448","0") "\n\tprefetchnta\t"MEM2("480","0") : : "r" (pf) ); pf += 512; { uintptr_t i; /* Align destinition to MMREG_SIZE -boundary */ i = (uintptr_t)to & 15; if (i) { i = 16 - i; len -= i; rep_movsb (to, from, i); } i = len >> 6; if(((uintptr_t)from) & 15) { /* if SRC is misaligned */ do { __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "2") "\n\tprefetchnta\t"MEM2("32","2") "\n\tmovups\t"MEM1( "0")", %%xmm0" "\n\tmovups\t"MEM2("16","0")", %%xmm1" BUMPPTR("64","2") "\n\tmovups\t"MEM2("32","0")", %%xmm2" "\n\tmovups\t"MEM2("48","0")", %%xmm3" "\n\tmovntps\t%%xmm0, "MEM1( "1") "\n\tmovntps\t%%xmm1, "MEM2("16","1") BUMPPTR("64","0") "\n\tmovntps\t%%xmm2, "MEM2("32","1") "\n\tmovntps\t%%xmm3, "MEM2("48","1") BUMPPTR("64","1") : "=r" (from), "=r" (to), "=r" (pf) : "0" (from), "1" (to), "2" (pf) : "memory" ); } while (--i); } else { /* Only if SRC is aligned on 16-byte boundary. It allows to use movaps instead of movups, which required data to be aligned or a general-protection exception (#GP) is generated. */ do { __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "2") "\n\tprefetchnta\t"MEM2("32","2") "\n\tmovaps\t"MEM1( "0")", %%xmm0" "\n\tmovaps\t"MEM2("16","0")", %%xmm1" BUMPPTR("64","2") "\n\tmovaps\t"MEM2("32","0")", %%xmm2" "\n\tmovaps\t"MEM2("48","0")", %%xmm3" "\n\tmovntps\t%%xmm0, "MEM1( "1") "\n\tmovntps\t%%xmm1, "MEM2("16","1") BUMPPTR("64","0") "\n\tmovntps\t%%xmm2, "MEM2("32","1") "\n\tmovntps\t%%xmm3, "MEM2("48","1") BUMPPTR("64","1") : "=r" (from), "=r" (to), "=r" (pf) : "0" (from), "1" (to), "2" (pf) : "memory" ); } while (--i); } /* since movntq is weakly-ordered, a "sfence" * is needed to become ordered again. */ __asm__ __volatile__ ("sfence":::"memory"); i = len & 63; if (i) rep_movsb (to, from, i); } return retval; } #ifdef HAVE_AVX static void * avx_memcpy(void * to, const void * from, size_t len) { void *retval = to; const uint8_t *pf; uintptr_t i; /* PREFETCH has effect even for MOVSB instruction ;) */ pf = (const uint8_t *)((uintptr_t)from & ~(uintptr_t)31); __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "0") "\n\tprefetchnta\t"MEM2( "32","0") "\n\tprefetchnta\t"MEM2( "64","0") "\n\tprefetchnta\t"MEM2( "96","0") "\n\tprefetchnta\t"MEM2("128","0") "\n\tprefetchnta\t"MEM2("160","0") "\n\tprefetchnta\t"MEM2("192","0") "\n\tprefetchnta\t"MEM2("224","0") "\n\tprefetchnta\t"MEM2("256","0") "\n\tprefetchnta\t"MEM2("288","0") : : "r" (pf)); pf += 320; if(len >= MIN_LEN) { /* Align destinition to MMREG_SIZE -boundary */ i = ((uintptr_t)to) & 31; if (i) { i = 32 - i; len -= i; rep_movsb (to, from, i); } i = len >> 7; /* len/128 */ if(((uintptr_t)from) & 31) /* if SRC is misaligned */ while (i--) { __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "2") "\n\tprefetchnta\t"MEM2("32","2") "\n\tprefetchnta\t"MEM2("64","2") "\n\tprefetchnta\t"MEM2("96","2") "\n\tvmovups\t"MEM1( "0")", %%ymm0" "\n\tvmovups\t"MEM2("32","0")", %%ymm1" BUMPPTR("128","2") "\n\tvmovups\t"MEM2("64","0")", %%ymm2" "\n\tvmovups\t"MEM2("96","0")", %%ymm3" "\n\tvmovntps\t%%ymm0, "MEM1( "1") "\n\tvmovntps\t%%ymm1, "MEM2("32","1") BUMPPTR("128","0") "\n\tvmovntps\t%%ymm2, "MEM2("64","1") "\n\tvmovntps\t%%ymm3, "MEM2("96","1") BUMPPTR("128","1") : "=r" (from), "=r" (to), "=r" (pf) : "0" (from), "1" (to), "2" (pf) : "memory"); } else /* Only if SRC is aligned on 32-byte boundary. It allows to use vmovaps instead of vmovups, which required data to be aligned or a general-protection exception (#GP) is generated. */ while (i--) { __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "2") "\n\tprefetchnta\t"MEM2("32","2") "\n\tprefetchnta\t"MEM2("64","2") "\n\tprefetchnta\t"MEM2("96","2") "\n\tvmovaps\t"MEM1( "0")", %%ymm0" "\n\tvmovaps\t"MEM2("32","0")", %%ymm1" BUMPPTR("128","2") "\n\tvmovaps\t"MEM2("64","0")", %%ymm2" "\n\tvmovaps\t"MEM2("96","0")", %%ymm3" "\n\tvmovntps\t%%ymm0, "MEM1( "1") "\n\tvmovntps\t%%ymm1, "MEM2("32","1") BUMPPTR("128","0") "\n\tvmovntps\t%%ymm2, "MEM2("64","1") "\n\tvmovntps\t%%ymm3, "MEM2("96","1") BUMPPTR("128","1") : "=r" (from), "=r" (to), "=r" (pf) : "0" (from), "1" (to), "2" (pf) : "memory"); } /* since movntq is weakly-ordered, a "sfence" * is needed to become ordered again. */ __asm__ __volatile__ ("sfence":::"memory"); __asm__ __volatile__ ("vzeroupper"); len &= 127; } /* * Now do the tail of the block */ i = len; if (i) rep_movsb (to, from, i); return retval; } #endif /* HAVE_AVX */ static void * mmx_memcpy(void * to, const void * from, size_t len) { void *retval = to; uintptr_t i; if(len >= MMX1_MIN_LEN) { /* Align destinition to MMREG_SIZE -boundary */ i = ((uintptr_t)to) & 7; if (i) { i = 8 - i; len -= i; rep_movsb (to, from, i); } i = len >> 6; /* len/64 */ while (i--) { __asm__ __volatile__ ( "\n\tmovq\t"MEM1( "0")", %%mm0" "\n\tmovq\t"MEM2( "8","0")", %%mm1" "\n\tmovq\t"MEM2("16","0")", %%mm2" "\n\tmovq\t"MEM2("24","0")", %%mm3" "\n\tmovq\t"MEM2("32","0")", %%mm4" "\n\tmovq\t"MEM2("40","0")", %%mm5" "\n\tmovq\t"MEM2("48","0")", %%mm6" "\n\tmovq\t"MEM2("56","0")", %%mm7" "\n\tmovq\t%%mm0, "MEM1( "1") "\n\tmovq\t%%mm1, "MEM2( "8","1") "\n\tmovq\t%%mm2, "MEM2("16","1") "\n\tmovq\t%%mm3, "MEM2("24","1") BUMPPTR("64","0") "\n\tmovq\t%%mm4, "MEM2("32","1") "\n\tmovq\t%%mm5, "MEM2("40","1") "\n\tmovq\t%%mm6, "MEM2("48","1") "\n\tmovq\t%%mm7, "MEM2("56","1") BUMPPTR("64","1") : "=r" (from), "=r" (to) : "0" (from), "1" (to) : "memory"); } __asm__ __volatile__ ("emms":::"memory"); len &= 63; } /* * Now do the tail of the block */ i = len; if (i) rep_movsb (to, from, i); return retval; } static void * mmx2_memcpy(void * to, const void * from, size_t len) { const uint8_t *pf; void *retval = to; uintptr_t i; /* PREFETCH has effect even for MOVSB instruction ;) */ pf = (const uint8_t *)((uintptr_t)from & ~(uintptr_t)31); __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "0") "\n\tprefetchnta\t"MEM2( "32","0") "\n\tprefetchnta\t"MEM2( "64","0") "\n\tprefetchnta\t"MEM2( "96","0") "\n\tprefetchnta\t"MEM2("128","0") "\n\tprefetchnta\t"MEM2("160","0") "\n\tprefetchnta\t"MEM2("192","0") "\n\tprefetchnta\t"MEM2("224","0") "\n\tprefetchnta\t"MEM2("256","0") "\n\tprefetchnta\t"MEM2("288","0") "\n\tprefetchnta\t"MEM2("320","0") "\n\tprefetchnta\t"MEM2("352","0") "\n\tprefetchnta\t"MEM2("384","0") "\n\tprefetchnta\t"MEM2("416","0") "\n\tprefetchnta\t"MEM2("448","0") "\n\tprefetchnta\t"MEM2("480","0") : : "r" (pf) ); pf += 512; if(len >= MIN_LEN) { /* Align destinition to MMREG_SIZE -boundary */ i = ((uintptr_t)to) & 7; if (i) { i = 8 - i; len -= i; rep_movsb (to, from, i); } i = len >> 6; /* len/64 */ while (i--) { __asm__ __volatile__ ( "\n\tprefetchnta\t"MEM1( "2") "\n\tprefetchnta\t"MEM2("32","2") "\n\tmovq\t"MEM1( "0")", %%mm0" "\n\tmovq\t"MEM2( "8","0")", %%mm1" "\n\tmovq\t"MEM2("16","0")", %%mm2" "\n\tmovq\t"MEM2("24","0")", %%mm3" BUMPPTR ("64", "2") "\n\tmovq\t"MEM2("32","0")", %%mm4" "\n\tmovq\t"MEM2("40","0")", %%mm5" "\n\tmovq\t"MEM2("48","0")", %%mm6" "\n\tmovq\t"MEM2("56","0")", %%mm7" "\n\tmovntq\t%%mm0, "MEM1( "1") "\n\tmovntq\t%%mm1, "MEM2( "8","1") "\n\tmovntq\t%%mm2, "MEM2("16","1") "\n\tmovntq\t%%mm3, "MEM2("24","1") BUMPPTR ("64", "0") "\n\tmovntq\t%%mm4, "MEM2("32","1") "\n\tmovntq\t%%mm5, "MEM2("40","1") "\n\tmovntq\t%%mm6, "MEM2("48","1") "\n\tmovntq\t%%mm7, "MEM2("56","1") BUMPPTR ("64", "1") : "=r" (from), "=r" (to), "=r" (pf) : "0" (from), "1" (to), "2" (pf) : "memory" ); } /* since movntq is weakly-ordered, a "sfence" * is needed to become ordered again. */ __asm__ __volatile__ ("sfence":::"memory"); __asm__ __volatile__ ("emms":::"memory"); len &= 63; } /* * Now do the tail of the block */ i = len; if (i) rep_movsb (to, from, i); return retval; } static void *linux_kernel_memcpy(void *to, const void *from, size_t len) { return linux_kernel_memcpy_impl(to,from,len); } #endif /* _MSC_VER */ #endif /* ARCH_X86 */ static const struct { const char name[16]; void *(*const function)(void *to, const void *from, size_t len); uint32_t cpu_require; } memcpy_method[] = { { "", NULL, 0 }, { "libc", memcpy, 0 }, #if defined(ARCH_X86) && !defined(_MSC_VER) { "linux kernel", linux_kernel_memcpy, 0 }, { "MMX ", mmx_memcpy, MM_MMX }, { "MMXEXT", mmx2_memcpy, MM_MMXEXT }, { "SSE", sse_memcpy, MM_MMXEXT|MM_SSE }, # ifdef HAVE_AVX { "AVX", avx_memcpy, MM_ACCEL_X86_AVX }, # endif /* HAVE_AVX */ #endif /* ARCH_X86 */ #if defined (ARCH_PPC) && !defined (HOST_OS_DARWIN) { "ppcasm", ppcasm_memcpy, 0 }, { "ppcasm_cached", ppcasm_cacheable_memcpy, MM_ACCEL_PPC_CACHE32 }, #endif /* ARCH_PPC && !HOST_OS_DARWIN */ { "", NULL, 0 } }; static uint64_t memcpy_timing[sizeof(memcpy_method)/sizeof(memcpy_method[0])] = { 0, }; #ifdef HAVE_POSIX_TIMERS /* Prefer clock_gettime() where available. */ # ifndef CLOCK_THREAD_CPUTIME_ID /* not defined in NetBSD (bug #535) */ # define CLOCK_THREAD_CPUTIME_ID CLOCK_MONOTONIC # endif static int64_t _x_gettime(void) { struct timespec tm; return (clock_gettime (CLOCK_THREAD_CPUTIME_ID, &tm) == -1) ? times (NULL) : (int64_t)tm.tv_sec * 1e9 + tm.tv_nsec; } # define rdtsc(x) _x_gettime() #elif defined(ARCH_X86) && defined(HAVE_SYS_TIMES_H) static int64_t rdtsc(int config_flags) { int64_t x; /* that should prevent us from trying cpuid with old cpus */ if( config_flags & MM_MMX ) { __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); return x; } else { struct tms tp; return times(&tp); } } #else static uint64_t rdtsc(int config_flags) { /* FIXME: implement an equivalent for using optimized memcpy on other architectures */ #ifdef HAVE_SYS_TIMES_H struct tms tp; return times(&tp); #else return clock(); #endif /* HAVE_SYS_TIMES_H */ } #endif static int xine_probe_fast_memcpy_int (xine_t *xine) { #define BUFSIZE 1024*1024 uint64_t t; char *buf1, *buf2; unsigned int i, j, best = 0; int config_flags = xine_mm_accel (); if ((buf1 = malloc (BUFSIZE)) == NULL) return 0; if ((buf2 = malloc (BUFSIZE)) == NULL) { free (buf1); return 0; } xprintf (xine, XINE_VERBOSITY_LOG, _("Benchmarking memcpy methods (smaller is better):\n")); /* make sure buffers are present on physical memory */ memset (buf1, 0, BUFSIZE); memset (buf2, 0, BUFSIZE); /* some initial activity to ensure that we're not running slowly :-) */ for (j = 0; j < 50; j++) { memcpy_method[1].function (buf2, buf1, BUFSIZE); memcpy_method[1].function (buf1, buf2, BUFSIZE); } for (i = 1; memcpy_method[i].name[0]; i++) { if ((config_flags & memcpy_method[i].cpu_require) != memcpy_method[i].cpu_require) continue; t = rdtsc (config_flags); for (j = 0; j < 50; j++) { memcpy_method[i].function (buf2, buf1, BUFSIZE); memcpy_method[i].function (buf1, buf2, BUFSIZE); } t = rdtsc (config_flags) - t; memcpy_timing[i] = t; xprintf (xine, XINE_VERBOSITY_LOG, "\t%s memcpy() : %" PRIu64 "\n", memcpy_method[i].name, t); if (best == 0 || t < memcpy_timing[best]) best = i; } free (buf1); free (buf2); return best; } static void update_fast_memcpy (void *user_data, xine_cfg_entry_t *entry) { int config_flags = xine_mm_accel (); xine_t *xine = (xine_t *)user_data; int method = entry->num_value; /* check if function is configured and valid for this machine */ if ((method > 0) && ((size_t)method < sizeof (memcpy_method) / sizeof (memcpy_method[0]) - 1) && ((config_flags & memcpy_method[method].cpu_require) == memcpy_method[method].cpu_require)) { xprintf (xine, XINE_VERBOSITY_DEBUG, "xine_fast_memcpy (): using \"%s\"\n", memcpy_method[method].name); xine_fast_memcpy = memcpy_method[method].function; return; } method = xine_probe_fast_memcpy_int (xine); if (method) { /* should not be an endless recursion as this method will pass the test above */ xine->config->update_num (xine->config, "engine.performance.memcpy_method", method); } } void xine_probe_fast_memcpy(xine_t *xine) { unsigned int method; static const char *const memcpy_methods[] = { "probe", "libc", #if defined(ARCH_X86) && !defined(_MSC_VER) "kernel", "mmx", "mmxext", "sse", # ifdef HAVE_AVX "avx", # endif /* HAVE_AVX */ #endif #if defined (ARCH_PPC) && !defined (HOST_OS_DARWIN) "ppcasm_memcpy", "ppcasm_cacheable_memcpy", #endif NULL }; method = xine->config->register_enum ( xine->config, "engine.performance.memcpy_method", 0, /* default to "probe" */ (char **)memcpy_methods, _("memcopy method used by xine"), _("The copying of large memory blocks is one of the most " "expensive operations on todays computers. Therefore xine " "provides various tuned methods to do this copying. " "Usually, the best method is detected automatically."), 20, update_fast_memcpy, xine ); /* an earlier xine engine instance has already set this */ if (xine_fast_memcpy) return; xine_fast_memcpy = memcpy; xine->config->update_num (xine->config, "engine.performance.memcpy_method", method); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/Makefile.am������������������������������������������������������������������������0000644�0001750�0001750�00000000423�14647725152�013506� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/misc/Makefile.common # Order is important be careful changing SUBDIRS SUBDIRS = \ xine-utils \ xine-engine \ audio_out \ audio_dec \ video_out \ video_dec \ spu_dec \ dxr3 \ input \ demuxers \ libw32dll \ libreal \ post \ combined \ vdr ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013251� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/common.c�����������������������������������������������������������������0000644�0001750�0001750�00000002427�14647725152�014712� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_DIRENT_H #include <dirent.h> #endif static const char *get_win32_codecs_path(config_values_t *cfg) { DIR *dir; const char *path, *cfgpath; const char * const listpath[] = { "", "/usr/lib/codecs", "/usr/local/lib/codecs", "/usr/lib/win32", "/usr/local/lib/win32", NULL }; int i = 0; cfgpath = cfg->register_filename (cfg, "decoder.external.win32_codecs_path", WIN32_PATH, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("path to Win32 codecs"), _("If you have the Windows or Apple Quicktime codec packs " "installed, specify the path the codec directory here. " "If xine can find the Windows or Apple Quicktime codecs, " "it will use them to decode various Windows Media and " "Quicktime streams for you. Consult the xine FAQ for " "more information on how to install the codecs."), 10, NULL, NULL); while (listpath[i]) { if (i == 0) path = cfgpath; else path = listpath[i]; if ((dir = opendir(path)) != NULL) { closedir(dir); return path; } i++; } return NULL; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/libwin32.h���������������������������������������������������������������0000644�0001750�0001750�00000015423�14647725152�015060� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __LIBWIN32_H #define __LIBWIN32_H #ifndef NOAVIFILE_HEADERS #error this header file should not be used without -DNOAVIFILE_HEADERS #endif // this file is only included when NOAVIFILE_HEADERS are defined // serves mainly for mplayer #define VFW_E_NOT_RUNNING 0x80040226 #include <inttypes.h> //#define FATAL(a) // you don't need exception - if you want - just fill more code #include "wine/mmreg.h" #include "wine/winreg.h" #include "wine/vfw.h" #include "wine/com.h" typedef uint32_t fourcc_t; /* typedef struct _FatalError { FatalError(); void PrintAll() {} }FatalError; */ typedef struct _CodecInfo { char* dll; GUID* guid; }CodecInfo; typedef struct _CImage // public your_libvo_mem { char* ptr; /*char* (*Data)(); { return 0; // pointer to memory block }*/ /*int (*Supported)(fourcc_t csp, int bits); { return true; // if you support such surface }*/ }CImage; #if 0 struct BitmapInfo : public BITMAPINFOHEADER { void SetBits(int b) { return; /*fixme*/ } void SetSpace(int b) { return; /*fixme*/ } }; #endif typedef struct _IAudioDecoder { WAVEFORMATEX in_fmt; CodecInfo record; /*(*IAudioDecoder)( CodecInfo * r, const WAVEFORMATEX* w); { memcpy(&this->record,r,sizeof(CodecInfo)); in_fmt = *w; }*/ }IAudioDecoder; /* struct IAudioEncoder { IAudioEncoder(const CodecInfo&, WAVEFORMATEX*) {} // you do not need this one... }; */ enum CAPS { CAP_NONE = 0, CAP_YUY2 = 1, CAP_YV12 = 2, CAP_IYUV = 4, CAP_UYVY = 8, CAP_YVYU = 16, CAP_I420 = 32, CAP_YVU9 = 64, CAP_IF09 = 128, }; enum DecodingMode { DIRECT = 0, REALTIME, REALTIME_QUALITY_AUTO, }; enum DecodingState { STOP = 0, START, }; typedef struct _BitmapInfo { long biSize; long biWidth; long biHeight; short biPlanes; short biBitCount; long biCompression; long biSizeImage; long biXPelsPerMeter; long biYPelsPerMeter; long biClrUsed; long biClrImportant; int colors[3]; } BitmapInfo; typedef struct _IVideoDecoder { int VBUFSIZE; int QMARKHI; int QMARKLO; int DMARKHI; int DMARKLO; /* IVideoDecoder(CodecInfo& info, const BITMAPINFOHEADER& format) : record(info) { // implement init part } virtual ~IVideoDecoder(); void Stop() { } void Start() { } */ const CodecInfo record; int m_Mode; // should we do precaching (or even change Quality on the fly) int m_State; int m_iDecpos; int m_iPlaypos; float m_fQuality; // quality for the progress bar 0..1(best) int m_bCapable16b; BITMAPINFOHEADER* m_bh; // format of input data (might be larger - e.g. huffyuv) BitmapInfo m_decoder; // format of decoder output BitmapInfo m_obh; // format of returned frames }IVideoDecoder; /* struct IRtConfig { }; */ // might be minimalized to contain just those which are needed by DS_VideoDecoder #ifndef mmioFOURCC #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ ( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \ ( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) ) #endif /* mmioFOURCC */ /* OpenDivX */ #define fccMP4S mmioFOURCC('M', 'P', '4', 'S') #define fccmp4s mmioFOURCC('m', 'p', '4', 's') #define fccDIVX mmioFOURCC('D', 'I', 'V', 'X') #define fccdivx mmioFOURCC('d', 'i', 'v', 'x') #define fccDIV1 mmioFOURCC('D', 'I', 'V', '1') #define fccdiv1 mmioFOURCC('d', 'i', 'v', '1') /* DivX codecs */ #define fccDIV2 mmioFOURCC('D', 'I', 'V', '2') #define fccdiv2 mmioFOURCC('d', 'i', 'v', '2') #define fccDIV3 mmioFOURCC('D', 'I', 'V', '3') #define fccdiv3 mmioFOURCC('d', 'i', 'v', '3') #define fccDIV4 mmioFOURCC('D', 'I', 'V', '4') #define fccdiv4 mmioFOURCC('d', 'i', 'v', '4') #define fccDIV5 mmioFOURCC('D', 'I', 'V', '5') #define fccdiv5 mmioFOURCC('d', 'i', 'v', '5') #define fccDIV6 mmioFOURCC('D', 'I', 'V', '6') #define fccdiv6 mmioFOURCC('d', 'i', 'v', '6') #define fccMP41 mmioFOURCC('M', 'P', '4', '1') #define fccmp41 mmioFOURCC('m', 'p', '4', '1') #define fccMP43 mmioFOURCC('M', 'P', '4', '3') #define fccmp43 mmioFOURCC('m', 'p', '4', '3') /* old ms mpeg-4 codecs */ #define fccMP42 mmioFOURCC('M', 'P', '4', '2') #define fccmp42 mmioFOURCC('m', 'p', '4', '2') #define fccMPG4 mmioFOURCC('M', 'P', 'G', '4') #define fccmpg4 mmioFOURCC('m', 'p', 'g', '4') /* Windows media codecs */ #define fccWMV1 mmioFOURCC('W', 'M', 'V', '1') #define fccwmv1 mmioFOURCC('w', 'm', 'v', '1') #define fccWMV2 mmioFOURCC('W', 'M', 'V', '2') #define fccwmv2 mmioFOURCC('w', 'm', 'v', '2') #define fccMWV1 mmioFOURCC('M', 'W', 'V', '1') /* Angel codecs */ #define fccAP41 mmioFOURCC('A', 'P', '4', '1') #define fccap41 mmioFOURCC('a', 'p', '4', '1') #define fccAP42 mmioFOURCC('A', 'P', '4', '2') #define fccap42 mmioFOURCC('a', 'p', '4', '2') /* other codecs */ #define fccIV31 mmioFOURCC('I', 'V', '3', '1') #define fcciv31 mmioFOURCC('i', 'v', '3', '1') #define fccIV32 mmioFOURCC('I', 'V', '3', '2') #define fcciv32 mmioFOURCC('i', 'v', '3', '2') #define fccIV41 mmioFOURCC('I', 'V', '4', '1') #define fcciv41 mmioFOURCC('i', 'v', '4', '1') #define fccIV50 mmioFOURCC('I', 'V', '5', '0') #define fcciv50 mmioFOURCC('i', 'v', '5', '0') #define fccI263 mmioFOURCC('I', '2', '6', '3') #define fcci263 mmioFOURCC('i', '2', '6', '3') #define fccMJPG mmioFOURCC('M', 'J', 'P', 'G') #define fccmjpg mmioFOURCC('m', 'j', 'p', 'g') #define fccHFYU mmioFOURCC('H', 'F', 'Y', 'U') #define fcccvid mmioFOURCC('c', 'v', 'i', 'd') #define fccdvsd mmioFOURCC('d', 'v', 's', 'd') /* Ati codecs */ #define fccVCR2 mmioFOURCC('V', 'C', 'R', '2') #define fccVCR1 mmioFOURCC('V', 'C', 'R', '1') #define fccVYUY mmioFOURCC('V', 'Y', 'U', 'Y') #define fccIYU9 mmioFOURCC('I', 'Y', 'U', '9') // it was defined as fccYVU9 /* Asus codecs */ #define fccASV1 mmioFOURCC('A', 'S', 'V', '1') #define fccASV2 mmioFOURCC('A', 'S', 'V', '2') /* Microsoft video */ #define fcccram mmioFOURCC('c', 'r', 'a', 'm') #define fccCRAM mmioFOURCC('C', 'R', 'A', 'M') #define fccMSVC mmioFOURCC('M', 'S', 'V', 'C') #define fccMSZH mmioFOURCC('M', 'S', 'Z', 'H') #define fccZLIB mmioFOURCC('Z', 'L', 'I', 'B') #define fccTM20 mmioFOURCC('T', 'M', '2', '0') #define fccYUV mmioFOURCC('Y', 'U', 'V', ' ') #define fccYUY2 mmioFOURCC('Y', 'U', 'Y', '2') #define fccYV12 mmioFOURCC('Y', 'V', '1', '2')/* Planar mode: Y + V + U (3 planes) */ #define fccI420 mmioFOURCC('I', '4', '2', '0') #define fccIYUV mmioFOURCC('I', 'Y', 'U', 'V')/* Planar mode: Y + U + V (3 planes) */ #define fccUYVY mmioFOURCC('U', 'Y', 'V', 'Y')/* Packed mode: U0+Y0+V0+Y1 (1 plane) */ #define fccYVYU mmioFOURCC('Y', 'V', 'Y', 'U')/* Packed mode: Y0+V0+Y1+U0 (1 plane) */ #define fccYVU9 mmioFOURCC('Y', 'V', 'U', '9')/* Planar 4:1:0 */ #define fccIF09 mmioFOURCC('I', 'F', '0', '9')/* Planar 4:1:0 + delta */ #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/Makefile.am��������������������������������������������������������������0000644�0001750�0001750�00000007054�14647725152�015313� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AUTOMAKE_OPTIONS = subdir-objects include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = noinst_LTLIBRARIES = xineplug_LTLIBRARIES = EXTRA_DIST = if ENABLE_W32DLL noinst_LTLIBRARIES += libdmo_filter.la libds_filter.la libwine.la xineplug_LTLIBRARIES += xineplug_decode_w32dll.la endif # # dmo # noinst_HEADERS += dmo/DMO_AudioDecoder.h dmo/dmo_guids.h dmo/dmo_interfaces.h dmo/DMO_Filter.h dmo/dmo.h dmo/DMO_VideoDecoder.h libdmo_filter_la_SOURCES = dmo/buffer.c dmo/DMO_AudioDecoder.c dmo/dmo.c dmo/dmo_guids.c dmo/DMO_VideoDecoder.c libdmo_filter_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir) -I$(srcdir)/dmo -I$(srcdir)/wine -DWIN32_PATH=\"$(w32_path)\" -DNOAVIFILE_HEADERS libdmo_filter_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing $(X_CFLAGS) -fno-omit-frame-pointer # # DirectShow # noinst_HEADERS += DirectShow/allocator.h DirectShow/cmediasample.h DirectShow/guids.h DirectShow/inputpin.h \ DirectShow/interfaces.h DirectShow/iunk.h DirectShow/outputpin.h DirectShow/DS_AudioDecoder.h \ DirectShow/DS_Filter.h DirectShow/DS_VideoDecoder.h libds_filter_la_SOURCES = DirectShow/allocator.c DirectShow/cmediasample.c DirectShow/guids.c DirectShow/inputpin.c \ DirectShow/outputpin.c DirectShow/DS_Filter.c DirectShow/DS_AudioDecoder.c DirectShow/DS_VideoDecoder.c libds_filter_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(srcdir) -I$(srcdir)/DirectShow -I$(srcdir)/wine \ -DWIN32_PATH=\"$(w32_path)\" -DNOAVIFILE_HEADERS libds_filter_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing $(X_CFLAGS) -fno-omit-frame-pointer # # wine # noinst_HEADERS += wine/avifmt.h wine/basetsd.h wine/com.h wine/debugtools.h wine/driver.h wine/elfdll.h wine/ext.h \ wine/heap.h wine/ldt.h wine/ldt_keeper.h wine/loader.h wine/mmreg.h wine/module.h wine/msacm.h \ wine/msacmdrv.h wine/ntdef.h wine/pe_image.h wine/poppack.h wine/pshpack1.h wine/pshpack2.h \ wine/pshpack4.h wine/pshpack8.h wine/registry.h wine/resource.h wine/vfw.h wine/win32.h wine/wineacm.h \ wine/winbase.h wine/windef.h wine/windows.h wine/winerror.h wine/winestring.h wine/winnt.h \ wine/winreg.h wine/winuser.h wine/wrapper.h libwine_la_SOURCES = wine/afl.c wine/driver.c wine/elfdll.c wine/ext.c wine/ldt_keeper.c wine/module.c \ wine/pe_image.c wine/pe_resource.c wine/resource.c wine/registry.c wine/vfl.c wine/win32.c \ wine/stubs.s wine/wrapper.S libwine_la_CPPFLAGS = $(AM_CPPFLAGS) $(XDG_BASEDIR_CPPFLAGS) -DWIN32_PATH=\"$(w32_path)\" -I$(srcdir) -I$(srcdir)/wine \ -D__WINE__ -Ddbg_printf=__vprintf -DTRACE=__vprintf -I$(top_srcdir)/src/xine-utils # disable -fomit-frame-pointer, -finline-functions, and -frename-registers # because they cause bad behavior of wine libwine_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing $(DEFAULT_OCFLAGS) $(X_CFLAGS) @W32_NO_OPTIMIZE@ \ -fno-omit-frame-pointer -fno-inline-functions -fno-rename-registers libwine_la_LIBADD = ${WINE_LIBS} -lm # # qtx # noinst_HEADERS += qtx/qtxsdk/components.h qtx/qtxsdk/select.h # # plugins # EXTRA_DIST += common.c noinst_HEADERS += group_w32.h libwin32.h w32codec.h xineplug_decode_w32dll_la_SOURCES = group_w32.c w32codec.c qt_decoder.c xineplug_decode_w32dll_la_DEPS = $(XDG_BASEDIR_DEPS) xineplug_decode_w32dll_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) -lm $(KSTAT_LIBS) $(XDG_BASEDIR_LIBS) \ libwine.la libds_filter.la libdmo_filter.la xineplug_decode_w32dll_la_CPPFLAGS = $(AM_CPPFLAGS) $(XDG_BASEDIR_CPPFLAGS) -I$(srcdir)/wine -DWIN32_PATH=\"$(w32_path)\" xineplug_decode_w32dll_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/group_w32.h��������������������������������������������������������������0000644�0001750�0001750�00000002145�14647725152�015253� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #include <xine/xine_internal.h> void *qtv_init_class (xine_t *xine, const void *data) XINE_PROTECTED; void *qta_init_class (xine_t *xine, const void *data) XINE_PROTECTED; void *w32v_init_class (xine_t *xine, const void *data) XINE_PROTECTED; void *w32a_init_class (xine_t *xine, const void *data) XINE_PROTECTED; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/w32codec.c���������������������������������������������������������������0000644�0001750�0001750�00000136223�14647725152�015035� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * routines for using w32 codecs * DirectShow support by Miguel Freitas (Nov/2001) * DMO support (Dez/2002) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <inttypes.h> #include <string.h> #include "wine/msacm.h" #include "wine/driver.h" #include "wine/avifmt.h" #include "wine/vfw.h" #include "wine/mmreg.h" #include "wine/ldt_keeper.h" #include "wine/win32.h" #include "wine/wineacm.h" #include "wine/loader.h" #define NOAVIFILE_HEADERS #include "DirectShow/guids.h" #include "DirectShow/DS_AudioDecoder.h" #include "DirectShow/DS_VideoDecoder.h" #include "dmo/DMO_AudioDecoder.h" #include "dmo/DMO_VideoDecoder.h" #define LOG_MODULE "w32codec" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "group_w32.h" #include "common.c" static GUID CLSID_Voxware = { 0x73f7a062, 0x8829, 0x11d1, { 0xb5, 0x50, 0x00, 0x60, 0x97, 0x24, 0x2d, 0x8d } }; static GUID CLSID_Acelp = { 0x4009f700, 0xaeba, 0x11d1, { 0x83, 0x44, 0x00, 0xc0, 0x4f, 0xb9, 0x2e, 0xb7 } }; static GUID wmv1_clsid = { 0x4facbba1, 0xffd8, 0x4cd7, {0x82, 0x28, 0x61, 0xe2, 0xf6, 0x5c, 0xb1, 0xae} }; static GUID wmv2_clsid = { 0x521fb373, 0x7654, 0x49f2, {0xbd, 0xb1, 0x0c, 0x6e, 0x66, 0x60, 0x71, 0x4f} }; static GUID wmv3_clsid = { 0x724bb6a4, 0xe526, 0x450f, {0xaf, 0xfa, 0xab, 0x9b, 0x45, 0x12, 0x91, 0x11} }; static GUID wmvdmo_clsid = { 0x82d353df, 0x90bd, 0x4382, {0x8b, 0xc2, 0x3f, 0x61, 0x92, 0xb7, 0x6e, 0x34} }; static GUID dvsd_clsid = { 0xB1B77C00, 0xC3E4, 0x11CF, {0xAF, 0x79, 0x00, 0xAA, 0x00, 0xB6, 0x7A, 0x42} }; static GUID msmpeg4_clsid = { 0x82CCd3E0, 0xF71A, 0x11D0, { 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xea, 0x66} }; static GUID mss1_clsid = { 0x3301a7c4, 0x0a8d, 0x11d4, { 0x91, 0x4d, 0x00, 0xc0, 0x4f, 0x61, 0x0d, 0x24 } }; static GUID wma3_clsid = { 0x27ca0808, 0x01f5, 0x4e7a, { 0x8b, 0x05, 0x87, 0xf8, 0x07, 0xa2, 0x33, 0xd1 } }; static GUID wmav_clsid = { 0x874131cb, 0x4ecc, 0x443b, { 0x89, 0x48, 0x74, 0x6b, 0x89, 0x59, 0x5d, 0x20 } }; /* some data is shared inside wine loader. * this mutex seems to avoid some segfaults */ static pthread_mutex_t win32_codec_mutex; static pthread_once_t once_control = PTHREAD_ONCE_INIT; static const char* win32_codec_name; #define VIDEOBUFSIZE 128*1024 #define DRIVER_STD 0 #define DRIVER_DS 1 #define DRIVER_DMO 2 typedef struct w32v_decoder_s { video_decoder_t video_decoder; xine_stream_t *stream; int64_t video_step; int decoder_ok; BITMAPINFOHEADER *bih, o_bih; double ratio; char scratch1[16]; /* some codecs overflow o_bih */ HIC hic; int yuv_supported ; int yuv_hack_needed ; int flipped ; unsigned char *buf; int bufsize; void *img_buffer; int size; long outfmt; int ex_functions; int driver_type; GUID *guid; DS_VideoDecoder *ds_dec; DMO_VideoDecoder *dmo_dec; int stream_id; int skipframes; ldt_fs_t *ldt_fs; } w32v_decoder_t; typedef struct w32a_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; int output_open; int decoder_ok; unsigned char *buf; int size; int64_t pts; /* these are used for pts estimation */ int64_t lastpts, sumpts, sumsize; double byterate; unsigned char *outbuf; int outsize; HACMSTREAM srcstream; int rec_audio_src_size; int max_audio_src_size; int num_channels; int rate; int driver_type; GUID *guid; DS_AudioDecoder *ds_dec; DMO_AudioDecoder *dmo_dec; ldt_fs_t *ldt_fs; } w32a_decoder_t; /* * RGB->YUY2 conversion, we need is for xine video-codec -> * video-output interface * * YCbCr is defined per CCIR 601-1, except that Cb and Cr are * normalized to the range 0..MAXSAMPLE rather than -0.5 .. 0.5. * The conversion equations to be implemented are therefore * Y = 0.29900 * R + 0.58700 * G + 0.11400 * B * Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERSAMPLE * Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERSAMPLE * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.) * * To avoid floating-point arithmetic, we represent the fractional * constants as integers scaled up by 2^16 (about 4 digits precision); * we have to divide the products by 2^16, with appropriate rounding, * to get the correct answer. * * FIXME: For the XShm video-out driver, this conversion is a huge * waste of time (converting from RGB->YUY2 here and converting back * from YUY2->RGB in the XShm driver). */ #define MAXSAMPLE 255 #define CENTERSAMPLE 128 #define SCALEBITS 16 #define FIX(x) ( (int32_t) ( (x) * (1<<SCALEBITS) + 0.5 ) ) #define ONE_HALF ( (int32_t) (1<< (SCALEBITS-1)) ) #define CBCR_OFFSET (CENTERSAMPLE << SCALEBITS) #define R_Y_OFF 0 /* offset to R => Y section */ #define G_Y_OFF (1*(MAXSAMPLE+1)) /* offset to G => Y section */ #define B_Y_OFF (2*(MAXSAMPLE+1)) /* etc. */ #define R_CB_OFF (3*(MAXSAMPLE+1)) #define G_CB_OFF (4*(MAXSAMPLE+1)) #define B_CB_OFF (5*(MAXSAMPLE+1)) #define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */ #define G_CR_OFF (6*(MAXSAMPLE+1)) #define B_CR_OFF (7*(MAXSAMPLE+1)) #define TABLE_SIZE (8*(MAXSAMPLE+1)) /* * HAS_SLOW_MULT: * 0: use integer multiplication in inner loop of rgb2yuv conversion * 1: use precomputed tables (avoids slow integer multiplication) * * (On a P-II/Athlon, the version using the precomputed tables is * slightly faster) */ #define HAS_SLOW_MULT 1 #if HAS_SLOW_MULT static int32_t *rgb_ycc_tab; #endif static void w32v_init_rgb_ycc(void) { #if HAS_SLOW_MULT /* * System has slow integer multiplication, so we precompute * the YCbCr constants times R,G,B for all possible values. */ int i; if (rgb_ycc_tab) return; rgb_ycc_tab = malloc(TABLE_SIZE * sizeof(int32_t)); for (i = 0; i <= MAXSAMPLE; i++) { rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i; rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i; rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF; rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i; rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i; /* * We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr. * This ensures that the maximum output will round to MAXJSAMPLE * not MAXJSAMPLE+1, and thus that we don't have to range-limit. */ rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; /* * B=>Cb and R=>Cr tables are the same rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1; */ rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i; rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i; } #endif } static int get_vids_codec_n_name(w32v_decoder_t *this, int buf_type) { (void)this; buf_type &= 0xffff0000; switch (buf_type) { case BUF_VIDEO_MSMPEG4_V1: case BUF_VIDEO_MSMPEG4_V2: case BUF_VIDEO_MSMPEG4_V3: case BUF_VIDEO_IV50: case BUF_VIDEO_IV41: case BUF_VIDEO_IV32: case BUF_VIDEO_IV31: case BUF_VIDEO_CINEPAK: case BUF_VIDEO_ATIVCR2: case BUF_VIDEO_I263: case BUF_VIDEO_MSVC: case BUF_VIDEO_DV: case BUF_VIDEO_VP31: case BUF_VIDEO_VP4: case BUF_VIDEO_VP5: case BUF_VIDEO_VP6: case BUF_VIDEO_MSS1: case BUF_VIDEO_TSCC: case BUF_VIDEO_UCOD: return 1; case BUF_VIDEO_WMV7: case BUF_VIDEO_WMV8: case BUF_VIDEO_WMV9: return 2; } return 0; } static const char * get_vids_codec_name(w32v_decoder_t *this, int buf_type, int n) { this->yuv_supported=0; this->yuv_hack_needed=0; this->flipped=0; this->driver_type = DRIVER_STD; this->ex_functions = 0; buf_type &= 0xffff0000; switch (buf_type) { case BUF_VIDEO_MSMPEG4_V1: case BUF_VIDEO_MSMPEG4_V2: /* Microsoft MPEG-4 v1/v2 */ /* old dll is disabled now due segfaults * (using directshow instead) this->yuv_supported=1; this->yuv_hack_needed=1; this->flipped=1; return "mpg4c32.dll"; */ this->yuv_supported=1; this->driver_type = DRIVER_DS; this->guid=&msmpeg4_clsid; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MS MPEG-4 V1/V2 (win32)"); return "mpg4ds32.ax"; case BUF_VIDEO_MSMPEG4_V3: /* Microsoft MPEG-4 v3 */ this->yuv_supported=1; this->yuv_hack_needed=1; this->flipped=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MS MPEG-4 V3 (win32)"); return "divxc32.dll"; case BUF_VIDEO_IV50: /* Video in Indeo Video 5 format */ this->yuv_supported=1; /* YUV pic is upside-down :( */ this->flipped=0; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Indeo Video 5 (win32)"); return "ir50_32.dll"; case BUF_VIDEO_IV41: /* Video in Indeo Video 4.1 format */ this->flipped=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Indeo Video 4.1 (win32)"); return "ir41_32.dll"; case BUF_VIDEO_IV32: /* Video in Indeo Video 3.2 format */ this->flipped=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Indeo Video 3.2 (win32)"); return "ir32_32.dll"; case BUF_VIDEO_IV31: /* Video in Indeo Video 3.1 format */ this->flipped=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Indeo Video 3.1 (win32)"); return "ir32_32.dll"; case BUF_VIDEO_CINEPAK: /* Video in Cinepak format */ this->flipped=1; this->yuv_supported=0; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Cinepak (win32)"); return "iccvid.dll"; /*** Only 16bit .DLL available (can't load under linux) *** case mmioFOURCC('V', 'C', 'R', '1'): printf("Video in ATI VCR1 format\n"); return "ativcr1.dll"; */ case BUF_VIDEO_ATIVCR2: /* Video in ATI VCR2 format */ this->yuv_supported=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "ATI VCR2 (win32)"); return "ativcr2.dll"; case BUF_VIDEO_I263: /* Video in I263 format */ this->flipped=1; this->yuv_supported=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "I263 (win32)"); return "i263_32.drv"; case BUF_VIDEO_MSVC: /* Video in Windows Video 1 */ /* note: can't play streams with 8bpp */ this->flipped=1; this->yuv_supported=0; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MS Windows Video 1 (win32)"); return "msvidc32.dll"; case BUF_VIDEO_DV: /* Sony DV Codec (not working yet) */ this->yuv_supported=1; this->driver_type = DRIVER_DS; this->guid=&dvsd_clsid; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Sony DV (win32)"); return "qdv.dll"; case BUF_VIDEO_WMV7: this->yuv_supported=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MS WMV 7 (win32)"); if (n == 2) { this->driver_type = DRIVER_DMO; this->guid=&wmvdmo_clsid; return "wmvdmod.dll"; } this->driver_type = DRIVER_DS; this->guid=&wmv1_clsid; return "wmvds32.ax"; case BUF_VIDEO_WMV8: this->yuv_supported=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MS WMV 8 (win32)"); if (n == 2) { this->driver_type = DRIVER_DMO; this->guid=&wmvdmo_clsid; return "wmvdmod.dll"; } this->driver_type = DRIVER_DS; this->guid=&wmv2_clsid; return "wmv8ds32.ax"; case BUF_VIDEO_WMV9: this->yuv_supported=1; this->driver_type = DRIVER_DMO; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MS WMV 9 (win32)"); if (n == 2) { this->guid=&wmvdmo_clsid; return "wmvdmod.dll"; } this->guid=&wmv3_clsid; return "wmv9dmod.dll"; case BUF_VIDEO_VP31: this->yuv_supported=1; this->ex_functions=1; this->flipped=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "On2 VP3.1 (win32)"); return "vp31vfw.dll"; case BUF_VIDEO_VP4: this->yuv_supported=1; this->ex_functions=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "On2 VP4 (win32)"); return "vp4vfw.dll"; case BUF_VIDEO_VP5: this->yuv_supported=1; this->ex_functions=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "On2 VP5 (win32)"); return "vp5vfw.dll"; case BUF_VIDEO_VP6: this->yuv_supported=1; this->ex_functions=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "On2 VP6 (win32)"); return "vp6vfw.dll"; case BUF_VIDEO_MSS1: this->driver_type = DRIVER_DS; this->guid=&mss1_clsid; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Windows Screen Video (win32)"); return "msscds32.ax"; case BUF_VIDEO_TSCC: this->flipped=1; this->yuv_supported=0; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "TechSmith Screen Capture Codec (win32)"); return "tsccvid.dll"; case BUF_VIDEO_UCOD: this->yuv_supported=1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "ClearVideo (win32)"); return "clrviddd.dll"; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: this didn't happen: unknown video buf type %08x\n", buf_type); return NULL; } #undef IMGFMT_YUY2 #undef IMGFMT_YV12 #define IMGFMT_YUY2 mmioFOURCC('Y','U','Y','2') #define IMGFMT_YV12 mmioFOURCC('Y','V','1','2') #define IMGFMT_32RGB mmioFOURCC( 32,'R','G','B') #define IMGFMT_24RGB mmioFOURCC( 24,'R','G','B') #define IMGFMT_16RGB mmioFOURCC( 16,'R','G','B') #define IMGFMT_15RGB mmioFOURCC( 15,'R','G','B') static void w32v_init_codec (w32v_decoder_t *this, int buf_type) { HRESULT ret; uint32_t vo_cap; int outfmt; lprintf ("init codec...\n"); (void)buf_type; memset(&this->o_bih, 0, sizeof(BITMAPINFOHEADER)); this->o_bih.biSize = sizeof(BITMAPINFOHEADER); this->ldt_fs = Setup_LDT_Keeper(); outfmt = IMGFMT_15RGB; if (this->yuv_supported) { vo_cap = this->stream->video_out->get_capabilities (this->stream->video_out); if (vo_cap & VO_CAP_YUY2) outfmt = IMGFMT_YUY2; } this->hic = ICOpen ((int)win32_codec_name, this->bih->biCompression, ICMODE_FASTDECOMPRESS); if(!this->hic){ xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: ICOpen failed! unknown codec %08lx / wrong parameters?\n"), this->bih->biCompression); this->decoder_ok = 0; return; } ret = ICDecompressGetFormat(this->hic, this->bih, &this->o_bih); if(ret){ xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: ICDecompressGetFormat (%.4s %08lx/%d) failed: Error %ld\n"), (char*)&this->o_bih.biCompression, this->bih->biCompression, this->bih->biBitCount, (long)ret); this->decoder_ok = 0; return; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: video output format: %.4s %08lx\n", (char*)&this->o_bih.biCompression, this->o_bih.biCompression); if(outfmt==IMGFMT_YUY2 || outfmt==IMGFMT_15RGB) this->o_bih.biBitCount=16; else this->o_bih.biBitCount=outfmt&0xFF; this->o_bih.biSizeImage = this->o_bih.biWidth * this->o_bih.biHeight * this->o_bih.biBitCount / 8; if (this->flipped) this->o_bih.biHeight=-this->bih->biHeight; if(outfmt==IMGFMT_YUY2 && !this->yuv_hack_needed) this->o_bih.biCompression = mmioFOURCC('Y','U','Y','2'); else this->o_bih.biCompression = 0; ret = (!this->ex_functions) ?ICDecompressQuery(this->hic, this->bih, &this->o_bih) :ICDecompressQueryEx(this->hic, this->bih, &this->o_bih); if(ret){ xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: ICDecompressQuery failed: Error %ld\n"), (long)ret); this->decoder_ok = 0; return; } ret = (!this->ex_functions) ?ICDecompressBegin(this->hic, this->bih, &this->o_bih) :ICDecompressBeginEx(this->hic, this->bih, &this->o_bih); if(ret){ xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: ICDecompressBegin failed: Error %ld\n"), (long)ret); this->decoder_ok = 0; return; } if (outfmt==IMGFMT_YUY2 && this->yuv_hack_needed) this->o_bih.biCompression = mmioFOURCC('Y','U','Y','2'); this->size = 0; if ( this->img_buffer ) free (this->img_buffer); this->img_buffer = malloc (this->o_bih.biSizeImage); if ( this->buf ) free (this->buf); this->bufsize = VIDEOBUFSIZE; this->buf = malloc(this->bufsize); (this->stream->video_out->open) (this->stream->video_out, this->stream); this->outfmt = outfmt; this->decoder_ok = 1; } static void w32v_init_ds_dmo_codec (w32v_decoder_t *this, int buf_type) { uint32_t vo_cap; int outfmt; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: init DirectShow/DMO video codec...\n"); memset(&this->o_bih, 0, sizeof(BITMAPINFOHEADER)); this->o_bih.biSize = sizeof(BITMAPINFOHEADER); this->ldt_fs = Setup_LDT_Keeper(); /* hack: dvsd is the only fourcc accepted by qdv.dll */ if( buf_type == BUF_VIDEO_DV ) this->bih->biCompression = mmioFOURCC('d','v','s','d'); if( this->driver_type == DRIVER_DS ) { this->ds_dec = DS_VideoDecoder_Open(win32_codec_name, this->guid, this->bih, this->flipped, 0); if(!this->ds_dec){ xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: DS_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n"), this->bih->biCompression); this->decoder_ok = 0; return; } } else { this->dmo_dec = DMO_VideoDecoder_Open(win32_codec_name, this->guid, this->bih, this->flipped, 0); if(!this->dmo_dec){ xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: DMO_VideoDecoder failed! unknown codec %08lx / wrong parameters?\n"), this->bih->biCompression); this->decoder_ok = 0; return; } } outfmt = IMGFMT_15RGB; if (this->yuv_supported) { vo_cap = this->stream->video_out->get_capabilities (this->stream->video_out); if (vo_cap & VO_CAP_YUY2) outfmt = IMGFMT_YUY2; } if(outfmt==IMGFMT_YUY2 || outfmt==IMGFMT_15RGB ) this->o_bih.biBitCount=16; else this->o_bih.biBitCount=outfmt&0xFF; this->o_bih.biWidth = this->bih->biWidth; this->o_bih.biHeight = this->bih->biHeight; this->o_bih.biSizeImage = this->o_bih.biWidth * this->o_bih.biHeight * this->o_bih.biBitCount / 8; if (this->flipped) this->o_bih.biHeight=-this->bih->biHeight; if(outfmt==IMGFMT_YUY2 && !this->yuv_hack_needed) this->o_bih.biCompression = mmioFOURCC('Y','U','Y','2'); else this->o_bih.biCompression = 0; if( this->driver_type == DRIVER_DS ) DS_VideoDecoder_SetDestFmt(this->ds_dec, this->o_bih.biBitCount, this->o_bih.biCompression); else DMO_VideoDecoder_SetDestFmt(this->dmo_dec, this->o_bih.biBitCount, this->o_bih.biCompression); if (outfmt==IMGFMT_YUY2 && this->yuv_hack_needed) this->o_bih.biCompression = mmioFOURCC('Y','U','Y','2'); if( this->driver_type == DRIVER_DS ) DS_VideoDecoder_StartInternal(this->ds_dec); else DMO_VideoDecoder_StartInternal(this->dmo_dec); this->size = 0; if ( this->img_buffer ) free (this->img_buffer); this->img_buffer = malloc (this->o_bih.biSizeImage); if ( this->buf ) free (this->buf); this->bufsize = VIDEOBUFSIZE; this->buf = malloc(this->bufsize); (this->stream->video_out->open) (this->stream->video_out, this->stream); this->outfmt = outfmt; this->decoder_ok = 1; } static void w32v_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { w32v_decoder_t *this = (w32v_decoder_t *) this_gen; lprintf ("processing packet type = %08x, buf->decoder_flags=%08x\n", buf->type, buf->decoder_flags); if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { this->video_step = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); lprintf ("video_step is %lld\n", this->video_step); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { int num_decoders; if ( buf->type & 0xff ) return; lprintf ("processing header ...\n"); /* init package containing bih */ if( this->bih ) free( this->bih ); this->bih = malloc(buf->size); memcpy ( this->bih, buf->content, buf->size ); this->ratio = (double)this->bih->biWidth/(double)this->bih->biHeight; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih->biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih->biHeight); pthread_mutex_lock(&win32_codec_mutex); num_decoders = get_vids_codec_n_name (this, buf->type); if (num_decoders != 0) { int i; for (i = 1; i <= num_decoders; i++) { win32_codec_name = get_vids_codec_name (this, buf->type, i); if( this->driver_type == DRIVER_STD ) w32v_init_codec (this, buf->type); else if( this->driver_type == DRIVER_DS || this->driver_type == DRIVER_DMO ) w32v_init_ds_dmo_codec (this, buf->type); if (this->decoder_ok) break; } } if( !this->decoder_ok ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: decoder failed to start. Is '%s' installed?\n"), win32_codec_name ); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); _x_message(this->stream, XINE_MSG_LIBRARY_LOAD_ERROR, win32_codec_name, NULL); } pthread_mutex_unlock(&win32_codec_mutex); this->stream_id = -1; this->skipframes = 0; } else if (this->decoder_ok) { lprintf ("processing packet ...\n"); if( (int) buf->size <= 0 ) return; if (this->stream_id < 0) this->stream_id = buf->type & 0xff; else if ((unsigned int)this->stream_id != (buf->type & 0xff)) return; if( this->size + buf->size > this->bufsize ) { this->bufsize = this->size + 2 * buf->size; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: increasing source buffer to %d to avoid overflow.\n", this->bufsize); this->buf = realloc( this->buf, this->bufsize ); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { HRESULT ret = 0; int flags; vo_frame_t *img; uint8_t *img_buffer = this->img_buffer; Check_FS_Segment(this->ldt_fs); /* decoder video frame */ this->bih->biSizeImage = this->size; img = this->stream->video_out->get_frame (this->stream->video_out, this->bih->biWidth, this->bih->biHeight, this->ratio, IMGFMT_YUY2, VO_BOTH_FIELDS); img->duration = this->video_step; lprintf ("frame duration is %lld\n", this->video_step); if (this->outfmt==IMGFMT_YUY2) img_buffer = img->base[0]; flags = 0; if( !(buf->decoder_flags & BUF_FLAG_KEYFRAME) ) flags |= ICDECOMPRESS_NOTKEYFRAME; if( this->skipframes ) flags |= ICDECOMPRESS_HURRYUP|ICDECOMPRESS_PREROL; if( this->skipframes && (buf->type & ~0xff) != BUF_VIDEO_IV32 ) img_buffer = NULL; pthread_mutex_lock(&win32_codec_mutex); if( this->driver_type == DRIVER_STD ) ret = (!this->ex_functions) ?ICDecompress(this->hic, flags, this->bih, this->buf, &this->o_bih, img_buffer) :ICDecompressEx(this->hic, flags, this->bih, this->buf, &this->o_bih, img_buffer); else if( this->driver_type == DRIVER_DS ) { ret = DS_VideoDecoder_DecodeInternal(this->ds_dec, this->buf, this->size, buf->decoder_flags & BUF_FLAG_KEYFRAME, img_buffer); } else if( this->driver_type == DRIVER_DMO ) { ret = DMO_VideoDecoder_DecodeInternal(this->dmo_dec, this->buf, this->size, 1, img_buffer); } pthread_mutex_unlock(&win32_codec_mutex); if (!this->skipframes) { if (this->outfmt==IMGFMT_YUY2) { /* already decoded into YUY2 format by DLL */ /* xine_fast_memcpy(img->base[0], this->img_buffer, this->bih.biHeight*this->bih.biWidth*2); */ } else { /* now, convert rgb to yuv */ int row, col; #if HAS_SLOW_MULT int32_t *ctab = rgb_ycc_tab; #endif for (row=0; row<this->bih->biHeight; row++) { uint16_t *pixel, *out; pixel = (uint16_t *) ( (uint8_t *)this->img_buffer + 2 * row * this->o_bih.biWidth ); out = (uint16_t *) (img->base[0] + row * img->pitches[0] ); for (col=0; col<this->o_bih.biWidth; col++, pixel++, out++) { uint8_t r,g,b; uint8_t y,u,v; b = (*pixel & 0x001F) << 3; g = (*pixel & 0x03E0) >> 5 << 3; r = (*pixel & 0x7C00) >> 10 << 3; #if HAS_SLOW_MULT y = (ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF]) >> SCALEBITS; if (!(col & 0x0001)) { /* even pixel, do u */ u = (ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF]) >> SCALEBITS; *out = ( (uint16_t) u << 8) | (uint16_t) y; } else { /* odd pixel, do v */ v = (ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF]) >> SCALEBITS; *out = ( (uint16_t) v << 8) | (uint16_t) y; } #else y = (FIX(0.299) * r + FIX(0.587) * g + FIX(0.114) * b + ONE_HALF) >> SCALEBITS; if (!(col & 0x0001)) { /* even pixel, do u */ u = (- FIX(0.16874) * r - FIX(0.33126) * g + FIX(0.5) * b + CBCR_OFFSET + ONE_HALF-1) >> SCALEBITS; *out = ( (uint16_t) u << 8) | (uint16_t) y; } else { /* odd pixel, do v */ v = (FIX(0.5) * r - FIX(0.41869) * g - FIX(0.08131) * b + CBCR_OFFSET + ONE_HALF-1) >> SCALEBITS; *out = ( (uint16_t) v << 8) | (uint16_t) y; } #endif //printf("r %02x g %02x b %02x y %02x u %02x v %02x\n",r,g,b,y,u,v); } } } } img->pts = buf->pts; if (ret || this->skipframes) { if (!this->skipframes) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: Error decompressing frame, err=%ld\n", (long)ret); img->bad_frame = 1; lprintf ("BAD FRAME, duration is %d\n", img->duration); } else { img->bad_frame = 0; lprintf ("GOOD FRAME, duration is %d\n\n", img->duration); } this->skipframes = img->draw(img, this->stream); lprintf ("skipframes is %d\n", this->skipframes); if (this->skipframes < 0) this->skipframes = 0; img->free(img); this->size = 0; } /* printf ("w32codec: processing packet done\n"); */ } } static void w32v_flush (video_decoder_t *this_gen) { (void)this_gen; } static void w32v_reset (video_decoder_t *this_gen) { w32v_decoder_t *this = (w32v_decoder_t *) this_gen; /* FIXME: need to improve this function. currently it doesn't avoid artifacts when seeking. */ pthread_mutex_lock(&win32_codec_mutex); if( this->driver_type == DRIVER_STD ) { if( this->hic ) { if (!this->ex_functions) ICDecompressBegin(this->hic, this->bih, &this->o_bih); else ICDecompressBeginEx(this->hic, this->bih, &this->o_bih); } } else if ( this->driver_type == DRIVER_DS ) { } this->size = 0; pthread_mutex_unlock(&win32_codec_mutex); } static void w32v_discontinuity (video_decoder_t *this_gen) { (void)this_gen; } static void w32v_dispose (video_decoder_t *this_gen) { w32v_decoder_t *this = (w32v_decoder_t *) this_gen; pthread_mutex_lock(&win32_codec_mutex); if ( this->driver_type == DRIVER_STD ) { if( this->hic ) { ICDecompressEnd(this->hic); ICClose(this->hic); } } else if ( this->driver_type == DRIVER_DS ) { if( this->ds_dec ) DS_VideoDecoder_Destroy(this->ds_dec); this->ds_dec = NULL; } else if ( this->driver_type == DRIVER_DMO ) { if( this->dmo_dec ) DMO_VideoDecoder_Destroy(this->dmo_dec); this->dmo_dec = NULL; } Restore_LDT_Keeper( this->ldt_fs ); pthread_mutex_unlock(&win32_codec_mutex); if ( this->img_buffer ) { free (this->img_buffer); this->img_buffer = NULL; } if ( this->buf ) { free (this->buf); this->buf = NULL; } if( this->bih ) { free (this->bih); this->bih = NULL; } if( this->decoder_ok ) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this); } /* * audio stuff */ static const char * get_auds_codec_name(w32a_decoder_t *this, int buf_type) { buf_type = buf_type & 0xFFFF0000; this->driver_type = DRIVER_STD; switch (buf_type) { case BUF_AUDIO_WMAV1: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Windows Media Audio v1 (win32)"); return "divxa32.acm"; case BUF_AUDIO_WMAV2: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Windows Media Audio v2 (win32)"); return "divxa32.acm"; case BUF_AUDIO_WMAPRO: this->driver_type = DRIVER_DMO; this->guid=&wma3_clsid; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Windows Media Audio Professional (win32)"); return "wma9dmod.dll"; case BUF_AUDIO_WMALL: this->driver_type = DRIVER_DMO; this->guid=&wma3_clsid; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Windows Media Audio Lossless (win32)"); return "wma9dmod.dll"; case BUF_AUDIO_WMAV: this->driver_type = DRIVER_DMO; this->guid=&wmav_clsid; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Windows Media Audio Voice (win32)"); return "wmspdmod.dll"; case BUF_AUDIO_MSADPCM: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "MS ADPCM (win32)"); return "msadp32.acm"; case BUF_AUDIO_MSIMAADPCM: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "MS IMA ADPCM (win32)"); return "imaadp32.acm"; case BUF_AUDIO_MSGSM: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "MS GSM (win32)"); return "msgsm32.acm"; case BUF_AUDIO_IMC: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Intel Music Coder (win32)"); return "imc32.acm"; case BUF_AUDIO_LH: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Lernout & Hauspie (win32)"); return "lhacm.acm"; case BUF_AUDIO_VOXWARE: this->driver_type = DRIVER_DS; this->guid=&CLSID_Voxware; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Voxware Metasound (win32)"); return "voxmsdec.ax"; case BUF_AUDIO_ACELPNET: this->driver_type = DRIVER_DS; this->guid=&CLSID_Acelp; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "ACELP.net (win32)"); return "acelpdec.ax"; case BUF_AUDIO_VIVOG723: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Vivo G.723/Siren Audio Codec (win32)"); return "vivog723.acm"; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: this didn't happen: unknown audio buf type %08x\n", buf_type); return NULL; } static void w32a_reset (audio_decoder_t *this_gen) { w32a_decoder_t *this = (w32a_decoder_t *) this_gen; this->size = 0; } static void w32a_discontinuity (audio_decoder_t *this_gen) { w32a_decoder_t *this = (w32a_decoder_t *) this_gen; this->pts = this->lastpts = this->sumpts = this->sumsize = 0; } static int w32a_init_audio (w32a_decoder_t *this, uint8_t *buf, int bufsize, int buftype) { HRESULT ret; WAVEFORMATEX wf; WAVEFORMATEX *in_fmt; unsigned long in_size; unsigned long out_size; audio_buffer_t *audio_buffer; int audio_buffer_mem_size; if (bufsize < (int)sizeof (WAVEFORMATEX)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: invalid codec init info.\n"); return 0; } in_fmt = (WAVEFORMATEX *)buf; in_size=in_fmt->nBlockAlign; this->srcstream = 0; this->num_channels = (in_fmt->nChannels >= 2)?2:1; this->rate = in_fmt->nSamplesPerSec; if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = (this->stream->audio_out->open) ( this->stream->audio_out, this->stream, 16, in_fmt->nSamplesPerSec, _x_ao_channels2mode(in_fmt->nChannels)); if (!this->output_open) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: (ACM_Decoder) Cannot open audio output device\n"); return 0; } audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); audio_buffer_mem_size = audio_buffer->mem_size; audio_buffer->num_frames = 0; audio_buffer->vpts = 0; this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); wf.nChannels = (in_fmt->nChannels >= 2)?2:1; wf.nSamplesPerSec = in_fmt->nSamplesPerSec; wf.nAvgBytesPerSec = 2*wf.nSamplesPerSec*wf.nChannels; wf.wFormatTag = WAVE_FORMAT_PCM; wf.nBlockAlign = 2*in_fmt->nChannels; wf.wBitsPerSample = 16; wf.cbSize = 0; this->ldt_fs = Setup_LDT_Keeper(); win32_codec_name = get_auds_codec_name (this, buftype); if( this->driver_type == DRIVER_STD ) { MSACM_RegisterDriver(win32_codec_name, in_fmt->wFormatTag, 0); ret=acmStreamOpen(&this->srcstream,(HACMDRIVER)NULL, in_fmt, &wf, NULL,0,0,0); if(ret){ if(ret==ACMERR_NOTPOSSIBLE) xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: (ACM_Decoder) Unappropriate audio format\n")); else xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: (ACM_Decoder) acmStreamOpen error %d\n"), (int) ret); this->srcstream = 0; return 0; } acmStreamSize(this->srcstream, in_size, &out_size, ACM_STREAMSIZEF_SOURCE); out_size*=2; if((int)out_size < audio_buffer_mem_size) out_size=audio_buffer_mem_size; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: Audio buffer min. size: %d\n",(int)out_size); acmStreamSize(this->srcstream, out_size, (LPDWORD) &this->rec_audio_src_size, ACM_STREAMSIZEF_DESTINATION); } else if( this->driver_type == DRIVER_DS ) { this->ds_dec=DS_AudioDecoder_Open(win32_codec_name,this->guid, in_fmt); if( this->ds_dec == NULL ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: Error initializing DirectShow Audio\n")); this->srcstream = 0; return 0; } out_size = audio_buffer_mem_size; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: output buffer size: %d\n",(int)out_size); this->rec_audio_src_size=DS_AudioDecoder_GetSrcSize(this->ds_dec,out_size); /* somehow DS_Filters seems to eat more than rec_audio_src_size if the output buffer is big enough. Doubling rec_audio_src_size should make this impossible */ this->rec_audio_src_size*=2; } else if( this->driver_type == DRIVER_DMO ) { this->dmo_dec=DMO_AudioDecoder_Open(win32_codec_name,this->guid, in_fmt, wf.nChannels); if( this->dmo_dec == NULL ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: Error initializing DMO Audio\n")); this->srcstream = 0; return 0; } out_size = audio_buffer_mem_size; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: output buffer size: %d\n",(int)out_size); this->rec_audio_src_size=DMO_AudioDecoder_GetSrcSize(this->dmo_dec,out_size); /* i don't know if DMO has the same problem as above. so, just in case... */ this->rec_audio_src_size*=2; } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: Recommended source buffer size: %d\n", this->rec_audio_src_size); if( this->rec_audio_src_size < in_fmt->nBlockAlign ) { this->rec_audio_src_size = in_fmt->nBlockAlign; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: adjusting source buffer size to %d\n", this->rec_audio_src_size); } if( this->buf ) free(this->buf); if( this->outbuf ) free(this->outbuf); this->max_audio_src_size = 2 * this->rec_audio_src_size; this->buf = malloc( this->max_audio_src_size ); out_size += 32768; this->outbuf = malloc( out_size ); this->outsize = out_size; this->size = 0; this->pts = this->lastpts = this->sumpts = this->sumsize = 0; return 1; } static void w32a_ensure_buffer_size(w32a_decoder_t *this, int size) { if( this->size + size > this->max_audio_src_size ) { this->max_audio_src_size = this->size + 2 * size; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: increasing source buffer to %d to avoid overflow.\n", this->max_audio_src_size); this->buf = realloc( this->buf, this->max_audio_src_size ); } } static void w32a_decode_audio (w32a_decoder_t *this, unsigned char *data, uint32_t size, int frame_end, int64_t pts) { static ACMSTREAMHEADER ash; HRESULT hr = 0; int size_read, size_written; int delay; /* DWORD srcsize=0; */ (void)frame_end; /* This code needs more testing */ /* bitrate computing (byterate: byte per pts) */ if (pts && (pts != this->lastpts)) { this->pts = pts; if (!this->lastpts) { this->byterate = 0.0; } else { this->sumpts = pts - this->lastpts; if (this->byterate == 0.0) { this->byterate = (double)this->sumsize / (double)this->sumpts; } else { /* smooth the bitrate */ this->byterate = (9 * this->byterate + (double)this->sumsize / (double)this->sumpts) / 10; } } this->lastpts = pts; this->sumsize = 0; } /* output_buf->pts = this->pts - delay */ if (this->byterate) delay = (int)((double)this->size / this->byterate); else delay = 0; this->sumsize += size; w32a_ensure_buffer_size(this, this->size + size); xine_fast_memcpy (&this->buf[this->size], data, size); lprintf("w32a_decode_audio: demux pts=%lld, this->size=%d, d=%d, rate=%lf\n", pts, this->size, delay, this->byterate); this->size += size; while (this->size >= this->rec_audio_src_size) { memset(&ash, 0, sizeof(ash)); ash.cbStruct=sizeof(ash); ash.fdwStatus=0; ash.dwUser=0; ash.pbSrc=this->buf; ash.cbSrcLength=this->rec_audio_src_size; ash.pbDst=this->outbuf; ash.cbDstLength=this->outsize; lprintf ("decoding %d of %d bytes (%02x %02x %02x %02x ... %02x %02x)\n", this->rec_audio_src_size, this->size, this->buf[0], this->buf[1], this->buf[2], this->buf[3], this->buf[this->rec_audio_src_size-2], this->buf[this->rec_audio_src_size-1]); pthread_mutex_lock(&win32_codec_mutex); if( this->driver_type == DRIVER_STD ) { hr=acmStreamPrepareHeader(this->srcstream,&ash,0); if(hr){ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: (ACM_Decoder) acmStreamPrepareHeader error %d\n",(int)hr); pthread_mutex_unlock(&win32_codec_mutex); return; } hr=acmStreamConvert(this->srcstream,&ash,0); } else if( this->driver_type == DRIVER_DS ){ hr=DS_AudioDecoder_Convert(this->ds_dec, ash.pbSrc, ash.cbSrcLength, ash.pbDst, ash.cbDstLength, &size_read, &size_written ); ash.cbSrcLengthUsed = size_read; ash.cbDstLengthUsed = size_written; } else if( this->driver_type == DRIVER_DMO ){ hr=DMO_AudioDecoder_Convert(this->dmo_dec, ash.pbSrc, ash.cbSrcLength, ash.pbDst, ash.cbDstLength, &size_read, &size_written ); ash.cbSrcLengthUsed = size_read; ash.cbDstLengthUsed = size_written; } pthread_mutex_unlock(&win32_codec_mutex); if(hr){ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: stream convert error %d, used %d bytes\n", (int)hr,(int)ash.cbSrcLengthUsed); this->size-=ash.cbSrcLength; } else { int DstLengthUsed, bufsize; audio_buffer_t *audio_buffer; char *p; lprintf ("acmStreamConvert worked, used %d bytes, generated %d bytes\n", ash.cbSrcLengthUsed, ash.cbDstLengthUsed); DstLengthUsed = ash.cbDstLengthUsed; p = this->outbuf; while( DstLengthUsed ) { audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); if( DstLengthUsed < audio_buffer->mem_size ) bufsize = DstLengthUsed; else bufsize = audio_buffer->mem_size; xine_fast_memcpy( audio_buffer->mem, p, bufsize ); audio_buffer->num_frames = bufsize / (this->num_channels*2); if (this->pts) audio_buffer->vpts = this->pts - delay; else audio_buffer->vpts = 0; lprintf("w32a_decode_audio: decoder pts=%lld\n", audio_buffer->vpts); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); this->pts = 0; DstLengthUsed -= bufsize; p += bufsize; } } if(ash.cbSrcLengthUsed>=(unsigned int)this->size){ this->size=0; } else { this->size-=ash.cbSrcLengthUsed; xine_fast_memcpy( this->buf, &this->buf [ash.cbSrcLengthUsed], this->size); } pthread_mutex_lock(&win32_codec_mutex); if( this->driver_type == DRIVER_STD ) { hr=acmStreamUnprepareHeader(this->srcstream,&ash,0); if(hr){ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "w32codec: (ACM_Decoder) acmStreamUnprepareHeader error %d\n",(int)hr); } } pthread_mutex_unlock(&win32_codec_mutex); } } static void w32a_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { w32a_decoder_t *this = (w32a_decoder_t *) this_gen; if (buf->decoder_flags & BUF_FLAG_PREVIEW) { lprintf ("preview data ignored.\n"); return; } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { lprintf ("got audio header\n"); /* accumulate init data */ w32a_ensure_buffer_size(this, this->size + buf->size); memcpy(this->buf + this->size, buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { pthread_mutex_lock(&win32_codec_mutex); this->decoder_ok = w32a_init_audio (this, this->buf, this->size, buf->type); if( !this->decoder_ok ) { xine_log (this->stream->xine, XINE_LOG_MSG, _("w32codec: decoder failed to start. Is '%s' installed?\n"), win32_codec_name ); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); } pthread_mutex_unlock(&win32_codec_mutex); } } else if (this->decoder_ok) { lprintf ("decoding %d data bytes...\n", buf->size); if( (int)buf->size <= 0 ) return; Check_FS_Segment(this->ldt_fs); w32a_decode_audio (this, buf->content, buf->size, buf->decoder_flags & BUF_FLAG_FRAME_END, buf->pts); } } static void w32a_dispose (audio_decoder_t *this_gen) { w32a_decoder_t *this = (w32a_decoder_t *) this_gen; pthread_mutex_lock(&win32_codec_mutex); if( this->driver_type == DRIVER_STD ) { if( this->srcstream ) { acmStreamClose(this->srcstream, 0); this->srcstream = 0; } } else if( this->driver_type == DRIVER_DS ) { if( this->ds_dec ) DS_AudioDecoder_Destroy(this->ds_dec); this->ds_dec = NULL; } else if( this->driver_type == DRIVER_DMO ) { if( this->dmo_dec ) DMO_AudioDecoder_Destroy(this->dmo_dec); this->dmo_dec = NULL; } Restore_LDT_Keeper(this->ldt_fs); pthread_mutex_unlock(&win32_codec_mutex); if( this->buf ) { free(this->buf); this->buf = NULL; } if( this->outbuf ) { free(this->outbuf); this->outbuf = NULL; } this->decoder_ok = 0; if (this->output_open) { this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; } free (this); } static video_decoder_t *open_video_decoder_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { w32v_decoder_t *this ; (void)class_gen; this = (w32v_decoder_t *) calloc(1, sizeof(w32v_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = w32v_decode_data; this->video_decoder.flush = w32v_flush; this->video_decoder.reset = w32v_reset; this->video_decoder.discontinuity = w32v_discontinuity; this->video_decoder.dispose = w32v_dispose; this->stream = stream; this->decoder_ok = 0; return &this->video_decoder; } /* * video decoder class */ static void init_routine(void) { pthread_mutex_init (&win32_codec_mutex, NULL); w32v_init_rgb_ycc(); } void *w32v_init_class (xine_t *xine, const void *data) { config_values_t *cfg; static const video_decoder_class_t this = { .open_plugin = open_video_decoder_plugin, .identifier = "w32v", .description = N_("win32 binary video codec plugin"), .dispose = NULL }; (void)data; cfg = xine->config; if ((win32_def_path = get_win32_codecs_path(cfg)) == NULL) return NULL; pthread_once (&once_control, init_routine); return (video_decoder_class_t *)&this; } /******************************************************** * audio part */ static audio_decoder_t *open_audio_decoder_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { w32a_decoder_t *this ; (void)class_gen; this = (w32a_decoder_t *) calloc(1, sizeof(w32a_decoder_t)); if (!this) return NULL; this->audio_decoder.decode_data = w32a_decode_data; this->audio_decoder.reset = w32a_reset; this->audio_decoder.discontinuity = w32a_discontinuity; this->audio_decoder.dispose = w32a_dispose; this->stream = stream; this->output_open = 0; this->decoder_ok = 0; this->buf = NULL; this->outbuf = NULL; return &this->audio_decoder; } /* * audio decoder plugin class */ void *w32a_init_class (xine_t *xine, const void *data) { config_values_t *cfg; static const audio_decoder_class_t this = { .open_plugin = open_audio_decoder_plugin, .identifier = "win32 audio", .description = N_("win32 binary audio codec plugin"), .dispose = NULL }; (void)data; cfg = xine->config; if ((win32_def_path = get_win32_codecs_path(cfg)) == NULL) return NULL; pthread_once (&once_control, init_routine); return (audio_decoder_class_t *)&this; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/group_w32.c��������������������������������������������������������������0000644�0001750�0001750�00000005510�14647725152�015245� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "group_w32.h" static const uint32_t qtv_supported_types[] = { BUF_VIDEO_SORENSON_V3, 0 }; static const decoder_info_t qtv_info = { .supported_types = qtv_supported_types, .priority = 1 }; static const uint32_t qta_supported_types[] = { BUF_AUDIO_QDESIGN1, BUF_AUDIO_QDESIGN2, BUF_AUDIO_QCLP, 0 }; static const decoder_info_t qta_info = { .supported_types = qta_supported_types, .priority = 1 }; static const uint32_t w32v_supported_types[] = { BUF_VIDEO_MSMPEG4_V1, BUF_VIDEO_MSMPEG4_V2, BUF_VIDEO_MSMPEG4_V3, BUF_VIDEO_IV50, BUF_VIDEO_IV41, BUF_VIDEO_IV32, BUF_VIDEO_IV31, BUF_VIDEO_CINEPAK, /* BUF_VIDEO_ATIVCR1, */ BUF_VIDEO_ATIVCR2, BUF_VIDEO_I263, BUF_VIDEO_MSVC, BUF_VIDEO_DV, BUF_VIDEO_WMV7, BUF_VIDEO_WMV8, BUF_VIDEO_WMV9, BUF_VIDEO_VP31, BUF_VIDEO_MSS1, BUF_VIDEO_TSCC, BUF_VIDEO_UCOD, BUF_VIDEO_VP4, BUF_VIDEO_VP5, BUF_VIDEO_VP6, 0 }; static const decoder_info_t w32v_info = { .supported_types = w32v_supported_types, .priority = 1 }; static const uint32_t w32a_supported_types[] = { BUF_AUDIO_WMAV1, BUF_AUDIO_WMAV2, BUF_AUDIO_WMAPRO, BUF_AUDIO_MSADPCM, BUF_AUDIO_MSIMAADPCM, BUF_AUDIO_MSGSM, BUF_AUDIO_IMC, BUF_AUDIO_LH, BUF_AUDIO_VOXWARE, BUF_AUDIO_ACELPNET, BUF_AUDIO_VIVOG723, BUF_AUDIO_WMAV, BUF_AUDIO_WMALL, 0 }; static const decoder_info_t w32a_info = { .supported_types = w32a_supported_types, .priority = 1 }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 19, "win32v", XINE_VERSION_CODE, &w32v_info, w32v_init_class }, { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 16, "win32a", XINE_VERSION_CODE, &w32a_info, w32a_init_class }, { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 19, "qtv", XINE_VERSION_CODE, &qtv_info, qtv_init_class }, { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 16, "qta", XINE_VERSION_CODE, &qta_info, qta_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/qt_decoder.c�������������������������������������������������������������0000644�0001750�0001750�00000103672�14647725152�015537� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * quicktime video/audio decoder plugin, using win32 dlls * most of this code comes directly from MPlayer * authors: A'rpi and Sascha Sommer * * rv40 support by Chris Rankin <cj.rankin@ntlworld.com> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #define LOG_MODULE "qt_decoder" #define LOG_VERBOSE /* #define LOG */ #include "bswap.h" #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include "group_w32.h" #include "qtx/qtxsdk/components.h" #include "wine/win32.h" #include "wine/windef.h" #include "wine/ldt_keeper.h" #include "common.c" /* * This version of the macro avoids compiler warnings about * multiple-character constants. It also does NOT assume * that an unsigned long is 32 bits wide. */ #ifdef FOUR_CHAR_CODE # undef FOUR_CHAR_CODE #endif #define FOUR_CHAR_CODE BE_FOURCC /* * * part 0: common wine stuff * ========================= * */ HMODULE WINAPI LoadLibraryA(LPCSTR); FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR); int WINAPI FreeLibrary(HMODULE); /* some data is shared inside wine loader. * this mutex seems to avoid some segfaults */ static pthread_once_t once_control = PTHREAD_ONCE_INIT; static pthread_mutex_t win32_codec_mutex; static void init_routine(void) { lprintf ("%s\n", __XINE_FUNCTION__); pthread_mutex_init (&win32_codec_mutex, NULL); lprintf ("%s completed\n", __XINE_FUNCTION__); } #define BUFSIZE 1024*1024 /* * * part 1: audio decoder * ===================== * */ typedef struct OpaqueSoundConverter* SoundConverter; typedef unsigned long UnsignedFixed; typedef uint8_t Byte; typedef struct SoundComponentData { long flags; OSType format; short numChannels; short sampleSize; UnsignedFixed sampleRate; long sampleCount; Byte * buffer; long reserved; }SoundComponentData; typedef int (__cdecl* LPFUNC1)(long flag); typedef int (__cdecl* LPFUNC2)(const SoundComponentData *, const SoundComponentData *, SoundConverter *); typedef int (__cdecl* LPFUNC3)(SoundConverter sc); typedef int (__cdecl* LPFUNC4)(void); typedef int (__cdecl* LPFUNC5)(SoundConverter sc, OSType selector,void * infoPtr); typedef int (__cdecl* LPFUNC6)(SoundConverter sc, unsigned long inputBytesTarget, unsigned long *inputFrames, unsigned long *inputBytes, unsigned long *outputBytes ); typedef int (__cdecl* LPFUNC7)(SoundConverter sc, const void *inputPtr, unsigned long inputFrames, void *outputPtr, unsigned long *outputFrames, unsigned long *outputBytes ); typedef int (__cdecl* LPFUNC8)(SoundConverter sc, void *outputPtr, unsigned long *outputFrames, unsigned long *outputBytes); typedef int (__cdecl* LPFUNC9)(SoundConverter sc) ; typedef struct qta_decoder_s { audio_decoder_t audio_decoder; int codec_initialized; int output_open; xine_stream_t *stream; HINSTANCE qtml_dll; xine_waveformatex wave; uint8_t out_buf[1000000]; LPFUNC1 InitializeQTML; LPFUNC2 SoundConverterOpen; LPFUNC3 SoundConverterClose; LPFUNC4 TerminateQTML; LPFUNC5 SoundConverterSetInfo; LPFUNC6 SoundConverterGetBufferSizes; LPFUNC7 SoundConverterConvertBuffer; LPFUNC8 SoundConverterEndConversion; LPFUNC9 SoundConverterBeginConversion; SoundConverter myConverter; SoundComponentData InputFormatInfo, OutputFormatInfo; int InFrameSize; int OutFrameSize; long FramesToGet; int frame_size; uint8_t data[BUFSIZE]; int data_len; int num_frames; ldt_fs_t *ldt_fs; } qta_decoder_t; #ifdef LOG static void qta_hexdump (char *buf, int length) { int i; printf ("qt_audio: ascii contents>"); for (i = 0; i < length; i++) { unsigned char c = buf[i]; if ((c >= 32) && (c <= 128)) printf ("%c", c); else printf ("."); } printf ("\n"); printf ("qt_audio: complete hexdump of package follows:\nqt_audio: 0x0000: "); for (i = 0; i < length; i++) { unsigned char c = buf[i]; printf ("%02x", c); if ((i % 16) == 15) printf ("\nqt_audio: 0x%04x: ", i+1); if ((i % 2) == 1) printf (" "); } printf ("\n"); } #endif static void qta_init_driver (qta_decoder_t *this, buf_element_t *buf) { int error; unsigned long InputBufferSize=0; /* size of the input buffer */ unsigned long OutputBufferSize=0; /* size of the output buffer */ unsigned long WantedBufferSize=0; /* the size you want your buffers to be */ int mode; this->FramesToGet = 0; lprintf ("audio: init_driver... (trying to lock mutex...)\n"); pthread_mutex_lock(&win32_codec_mutex); lprintf ("audio: init_driver... (mutex locked)\n"); this->ldt_fs = Setup_LDT_Keeper(); this->qtml_dll = LoadLibraryA("qtmlClient.dll"); if (this->qtml_dll == (HINSTANCE)NULL) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed to load dll\n" ); pthread_mutex_unlock(&win32_codec_mutex); _x_message(this->stream, XINE_MSG_LIBRARY_LOAD_ERROR, "qtmlClient.dll", NULL); return; } this->InitializeQTML = (LPFUNC1)GetProcAddress (this->qtml_dll, "InitializeQTML"); if ( this->InitializeQTML == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed geting proc address InitializeQTML\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->SoundConverterOpen = (LPFUNC2)GetProcAddress (this->qtml_dll, "SoundConverterOpen"); if ( this->SoundConverterOpen == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address SoundConverterOpen\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->SoundConverterClose = (LPFUNC3)GetProcAddress (this->qtml_dll, "SoundConverterClose"); if ( this->SoundConverterClose == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address SoundConverterClose\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->TerminateQTML = (LPFUNC4)GetProcAddress (this->qtml_dll, "TerminateQTML"); if ( this->TerminateQTML == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address TerminateQTML\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->SoundConverterSetInfo = (LPFUNC5)GetProcAddress (this->qtml_dll, "SoundConverterSetInfo"); if ( this->SoundConverterSetInfo == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address SoundConverterSetInfo\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->SoundConverterGetBufferSizes = (LPFUNC6)GetProcAddress (this->qtml_dll, "SoundConverterGetBufferSizes"); if ( this->SoundConverterGetBufferSizes == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address SoundConverterGetBufferSizes\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->SoundConverterConvertBuffer = (LPFUNC7)GetProcAddress (this->qtml_dll, "SoundConverterConvertBuffer"); if ( this->SoundConverterConvertBuffer == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address SoundConverterConvertBuffer1\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->SoundConverterEndConversion = (LPFUNC8)GetProcAddress (this->qtml_dll, "SoundConverterEndConversion"); if ( this->SoundConverterEndConversion == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address SoundConverterEndConversion\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } this->SoundConverterBeginConversion = (LPFUNC9)GetProcAddress (this->qtml_dll, "SoundConverterBeginConversion"); if ( this->SoundConverterBeginConversion == NULL ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: failed getting proc address SoundConverterBeginConversion\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } lprintf ("audio: Standard init done you may now call supported functions\n"); error = this->InitializeQTML(6+16); lprintf ("audio: InitializeQTML:%i\n",error); if (error) { pthread_mutex_unlock(&win32_codec_mutex); return; } this->OutputFormatInfo.flags = this->InputFormatInfo.flags = 0; this->OutputFormatInfo.sampleCount = this->InputFormatInfo.sampleCount = 0; this->OutputFormatInfo.buffer = this->InputFormatInfo.buffer = NULL; this->OutputFormatInfo.reserved = this->InputFormatInfo.reserved = 0; this->OutputFormatInfo.numChannels = this->InputFormatInfo.numChannels = this->wave.nChannels; this->InputFormatInfo.sampleSize = this->wave.wBitsPerSample; this->OutputFormatInfo.sampleSize = 16; this->OutputFormatInfo.sampleRate = this->InputFormatInfo.sampleRate = this->wave.nSamplesPerSec; switch (buf->type) { case BUF_AUDIO_QDESIGN1: this->InputFormatInfo.format = FOUR_CHAR_CODE('Q','D','M','C'); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "QDesign Music Codec v1 (QT DLL)"); break; case BUF_AUDIO_QDESIGN2: this->InputFormatInfo.format = FOUR_CHAR_CODE('Q','D','M','2'); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "QDesign Music Codec v2 (QT DLL)"); break; case BUF_AUDIO_QCLP: this->InputFormatInfo.format = FOUR_CHAR_CODE('Q','c','l','p'); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Qualcomm Purevoice Codec (QT DLL)"); break; default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_audio: fourcc for buftype %08x ?\n", buf->type); _x_abort (); } this->OutputFormatInfo.format = FOUR_CHAR_CODE('N','O','N','E'); #ifdef LOG printf ("qt_audio: input format:\n"); qta_hexdump (&this->InputFormatInfo, sizeof (SoundComponentData)); printf ("qt_audio: output format:\n"); qta_hexdump (&this->OutputFormatInfo, sizeof (SoundComponentData)); printf ("qt_audio: stsd atom: \n"); qta_hexdump ((unsigned char *)buf->decoder_info_ptr[2], buf->decoder_info[2]); #endif error = this->SoundConverterOpen (&this->InputFormatInfo, &this->OutputFormatInfo, &this->myConverter); lprintf ("audio: SoundConverterOpen:%i\n",error); if (error) { pthread_mutex_unlock(&win32_codec_mutex); return; } if ((buf->decoder_info[2] > 0x38) && (buf->decoder_info[2] != 0x64)) { error = this->SoundConverterSetInfo (this->myConverter, FOUR_CHAR_CODE('w','a','v','e'), ((unsigned char *)buf->decoder_info_ptr[2]) + 0x38); lprintf ("audio: SoundConverterSetInfo:%i\n",error); if (error) { pthread_mutex_unlock(&win32_codec_mutex); return; } } WantedBufferSize = this->OutputFormatInfo.numChannels*this->OutputFormatInfo.sampleRate*2; error = this->SoundConverterGetBufferSizes (this->myConverter, WantedBufferSize, &this->FramesToGet, &InputBufferSize, &OutputBufferSize); lprintf ("audio: SoundConverterGetBufferSizes:%i\n", error); lprintf ("audio: WantedBufferSize = %li\n", WantedBufferSize); lprintf ("audio: InputBufferSize = %li\n", InputBufferSize); lprintf ("audio: OutputBufferSize = %li\n", OutputBufferSize); lprintf ("audio: this->FramesToGet = %li\n", this->FramesToGet); this->InFrameSize = (InputBufferSize+this->FramesToGet-1)/this->FramesToGet; this->OutFrameSize = OutputBufferSize/this->FramesToGet; lprintf ("audio: FrameSize: %i -> %i\n", this->InFrameSize, this->OutFrameSize); error = this->SoundConverterBeginConversion (this->myConverter); lprintf ("audio: SoundConverterBeginConversion:%i\n",error); if (error) { pthread_mutex_unlock(&win32_codec_mutex); return; } lprintf ("audio: opening output.\n"); mode = _x_ao_channels2mode(this->wave.nChannels); this->frame_size = this->wave.nChannels * this->wave.wBitsPerSample / 8; this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, this->wave.wBitsPerSample, this->wave.nSamplesPerSec, mode) ; this->codec_initialized = 1; lprintf ("audio: mutex unlock\n"); pthread_mutex_unlock(&win32_codec_mutex); } static void qta_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { qta_decoder_t *this = (qta_decoder_t *) this_gen; lprintf ("audio: decode buf=%08x %d bytes flags=%08x pts=%lld\n", buf, buf->size, buf->decoder_flags, buf->pts); if (buf->decoder_flags & BUF_FLAG_STDHEADER) { if (buf->size >= (int)sizeof(xine_waveformatex)) memcpy (&this->wave, buf->content, sizeof (xine_waveformatex)); this->wave.nChannels = buf->decoder_info[3]; this->wave.wBitsPerSample = buf->decoder_info[2]; this->wave.nSamplesPerSec = buf->decoder_info[1]; lprintf ("audio: header copied\n"); } else if (buf->decoder_flags & BUF_FLAG_SPECIAL) { lprintf ("audio: special buffer\n"); if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM) { lprintf ("audio: got stsd atom -> init codec\n"); if (!this->codec_initialized) { qta_init_driver (this, buf); } if (!this->codec_initialized) _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); } } else if( this->codec_initialized ) { memcpy (&this->data[this->data_len], buf->content, buf->size); this->data_len += buf->size; if ((this->InFrameSize != 0) && (this->data_len > this->InFrameSize)) { int num_frames = this->data_len / this->InFrameSize; long out_frames, out_bytes; int error, frames_left, bytes_sent; Check_FS_Segment(this->ldt_fs); pthread_mutex_lock(&win32_codec_mutex); error = this->SoundConverterConvertBuffer (this->myConverter, this->data, num_frames, this->out_buf, &out_frames, &out_bytes); pthread_mutex_unlock(&win32_codec_mutex); lprintf ("audio: decoded %d frames => %d frames (error %d)\n", num_frames, out_frames, error); this->data_len -= this->InFrameSize * num_frames; if (this->data_len>0) memmove (this->data, this->data+num_frames*this->InFrameSize, this->data_len); frames_left = out_frames; bytes_sent = 0; while (frames_left>0) { audio_buffer_t *audio_buffer; int nframes; audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); nframes = audio_buffer->mem_size / this->frame_size; if (nframes > frames_left) nframes = frames_left; memcpy (audio_buffer->mem, this->out_buf+bytes_sent, nframes * this->frame_size); audio_buffer->vpts = buf->pts; buf->pts = 0; /* only the first buffer gets the real pts */ audio_buffer->num_frames = nframes; lprintf ("audio: sending %d frames, %d frames left\n", nframes, frames_left); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); bytes_sent += nframes*this->frame_size; frames_left -= nframes; } } } } static void qta_reset (audio_decoder_t *this_gen) { qta_decoder_t *this = (qta_decoder_t *) this_gen; this->data_len = 0; } static void qta_discontinuity (audio_decoder_t *this_gen) { (void)this_gen; } static void qta_dispose (audio_decoder_t *this_gen) { qta_decoder_t *this = (qta_decoder_t *) this_gen; int error; unsigned long ConvertedFrames=0; unsigned long ConvertedBytes=0; if( this->codec_initialized ) { error = this->SoundConverterEndConversion (this->myConverter,NULL, &ConvertedFrames,&ConvertedBytes); lprintf ("audio: SoundConverterEndConversion:%i\n",error); error = this->SoundConverterClose (this->myConverter); lprintf ("audio: SoundConverterClose:%i\n",error); Restore_LDT_Keeper(this->ldt_fs); this->ldt_fs = NULL; } if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; free (this); } static audio_decoder_t *qta_open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { qta_decoder_t *this = calloc (1, sizeof (*this)); if (!this) return NULL; this->audio_decoder.decode_data = qta_decode_data; this->audio_decoder.reset = qta_reset; this->audio_decoder.discontinuity = qta_discontinuity; this->audio_decoder.dispose = qta_dispose; this->stream = stream; #ifndef HAVE_ZERO_SAFE_MEM this->output_open = 0; #endif (void)class_gen; return &this->audio_decoder; } /* * qta plugin class */ void *qta_init_class (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = qta_open_plugin, .identifier = "qta", .description = N_("quicktime audio decoder plugin"), .dispose = NULL }; (void)data; if ((win32_def_path = get_win32_codecs_path (xine->config)) == NULL) return NULL; pthread_once (&once_control, init_routine); return (audio_decoder_class_t *)&this; } /* * * part 2: video decoder * ===================== * */ typedef struct qtv_decoder_s { video_decoder_t video_decoder; xine_stream_t *stream; HINSTANCE qtml_dll; xine_bmiheader bih; double ratio; int codec_initialized; uint8_t *plane; uint8_t data[BUFSIZE]; int data_len; /* ComponentDescription desc; */ /* for FindNextComponent() */ ComponentInstance ci; /* codec handle */ /* CodecInfo cinfo;*/ /* for ImageCodecGetCodecInfo() */ /* Component prev=NULL; */ /* ComponentResult cres; */ CodecCapabilities codeccap; /* for decpar */ CodecDecompressParams decpar; /* for ImageCodecPreDecompress() */ /* ImageSubCodecDecompressCapabilities icap; // for ImageCodecInitialize() */ Rect OutBufferRect; /* the dimensions of our GWorld */ GWorldPtr OutBufferGWorld; /* a GWorld is some kind of description for a drawing environment */ ImageDescriptionHandle framedescHandle; /* function pointers */ Component (*FindNextComponent) (Component prev, ComponentDescription* desc); OSErr (*GetComponentInfo) (Component prev, ComponentDescription* desc, Handle h1,Handle h2,Handle h3); long (*CountComponents) (ComponentDescription* desc); OSErr (*InitializeQTML) (long flags); OSErr (*EnterMovies) (void); ComponentInstance (*OpenComponent) (Component c); ComponentResult (*ImageCodecInitialize) (ComponentInstance ci, ImageSubCodecDecompressCapabilities * cap); ComponentResult (*ImageCodecBeginBand) (ComponentInstance ci, CodecDecompressParams * params, ImageSubCodecDecompressRecord * drp, long flags); ComponentResult (*ImageCodecDrawBand) (ComponentInstance ci, ImageSubCodecDecompressRecord * drp); ComponentResult (*ImageCodecEndBand) (ComponentInstance ci, ImageSubCodecDecompressRecord * drp, OSErr result, long flags); ComponentResult (*ImageCodecGetCodecInfo) (ComponentInstance ci, CodecInfo *info); ComponentResult (*ImageCodecPreDecompress)(ComponentInstance ci, CodecDecompressParams * params); ComponentResult (*ImageCodecBandDecompress)(ComponentInstance ci, CodecDecompressParams * params); PixMapHandle (*GetGWorldPixMap) (GWorldPtr offscreenGWorld); OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw, OSType pixelFormat, const Rect *boundsRect, CTabHandle cTable, /*GDHandle*/void* aGDevice, /*unused*/ GWorldFlags flags, void *baseAddr, long rowBytes); OSErr (*NewHandleClear)(Size byteCount); ldt_fs_t *ldt_fs; } qtv_decoder_t; #ifdef LOG static void qtv_hexdump (char *buf, int length) { int i; printf ("qt_video: ascii contents>"); for (i = 0; i < length; i++) { unsigned char c = buf[i]; if ((c >= 32) && (c <= 128)) printf ("%c", c); else printf ("."); } printf ("\n"); printf ("qt_video: complete hexdump of package follows:\nqt_video: 0x0000: "); for (i = 0; i < length; i++) { unsigned char c = buf[i]; printf ("%02x", c); if ((i % 16) == 15) printf ("\nqt_video: 0x%04x: ", i+1); if ((i % 2) == 1) printf (" "); } printf ("\n"); } #endif /* * qt codec loader */ static void qtv_init_driver (qtv_decoder_t *this, buf_element_t *buf) { long result = 1; ComponentResult cres; ComponentDescription desc; Component prev=NULL; CodecInfo cinfo; /* for ImageCodecGetCodecInfo() */ ImageSubCodecDecompressCapabilities icap; /* for ImageCodecInitialize() */ ImageDescription *id; lprintf ("video: init_driver... (trying to lock mutex...)\n"); pthread_mutex_lock(&win32_codec_mutex); lprintf ("video: mutex locked\n"); this->ldt_fs = Setup_LDT_Keeper(); this->qtml_dll = LoadLibraryA("qtmlClient.dll"); if (this->qtml_dll == (HINSTANCE)NULL) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_video: failed to load dll\n" ); pthread_mutex_unlock(&win32_codec_mutex); _x_message(this->stream, XINE_MSG_LIBRARY_LOAD_ERROR, "qtmlClient.dll", NULL); return; } this->InitializeQTML = (OSErr(*)(long))GetProcAddress(this->qtml_dll, "InitializeQTML"); this->EnterMovies = (OSErr(*)(void))GetProcAddress(this->qtml_dll, "EnterMovies"); this->FindNextComponent = (Component(*)(Component,ComponentDescription*))GetProcAddress(this->qtml_dll, "FindNextComponent"); this->CountComponents = (long(*)(ComponentDescription*))GetProcAddress(this->qtml_dll, "CountComponents"); this->GetComponentInfo = (OSErr(*)(Component,ComponentDescription*,Handle,Handle,Handle))GetProcAddress(this->qtml_dll, "GetComponentInfo"); this->OpenComponent = (ComponentInstance(*)(Component))GetProcAddress(this->qtml_dll, "OpenComponent"); this->ImageCodecInitialize = (ComponentResult(*)(ComponentInstance,ImageSubCodecDecompressCapabilities*))GetProcAddress(this->qtml_dll, "ImageCodecInitialize"); this->ImageCodecGetCodecInfo = (ComponentResult(*)(ComponentInstance,CodecInfo*))GetProcAddress(this->qtml_dll, "ImageCodecGetCodecInfo"); this->ImageCodecBeginBand = (ComponentResult(*)(ComponentInstance,CodecDecompressParams*,ImageSubCodecDecompressRecord*,long))GetProcAddress(this->qtml_dll, "ImageCodecBeginBand"); this->ImageCodecPreDecompress = (ComponentResult(*)(ComponentInstance,CodecDecompressParams*))GetProcAddress(this->qtml_dll, "ImageCodecPreDecompress"); this->ImageCodecBandDecompress = (ComponentResult(*)(ComponentInstance,CodecDecompressParams*))GetProcAddress(this->qtml_dll, "ImageCodecBandDecompress"); this->GetGWorldPixMap = (PixMapHandle(*)(GWorldPtr))GetProcAddress(this->qtml_dll, "GetGWorldPixMap"); this->QTNewGWorldFromPtr = (OSErr(*)(GWorldPtr*,OSType,const Rect*,CTabHandle,void*,GWorldFlags,void*,long))GetProcAddress(this->qtml_dll, "QTNewGWorldFromPtr"); this->NewHandleClear = (OSErr(*)(Size))GetProcAddress(this->qtml_dll, "NewHandleClear"); if (!this->InitializeQTML || !this->EnterMovies || !this->FindNextComponent || !this->ImageCodecBandDecompress){ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_video: invalid qt DLL!\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } lprintf ("video: calling InitializeQTML...\n"); result = this->InitializeQTML(6+16); /* result=InitializeQTML(0); */ lprintf("video: InitializeQTML returned %d\n",result); /* result=EnterMovies(); */ /* printf("EnterMovies->%d\n",result); */ memset(&desc,0,sizeof(desc)); desc.componentType = FOUR_CHAR_CODE('i','m','d','c'); desc.componentSubType = FOUR_CHAR_CODE('S','V','Q','3'); desc.componentManufacturer=0; desc.componentFlags=0; desc.componentFlagsMask=0; lprintf("video: Count = %d\n", this->CountComponents(&desc)); prev = this->FindNextComponent(NULL,&desc); if(!prev){ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "Cannot find requested component\n"); pthread_mutex_unlock(&win32_codec_mutex); return; } lprintf ("video: Found it! ID = 0x%X\n",prev); this->ci = this->OpenComponent(prev); lprintf ("video: this->ci=%p\n",this->ci); memset (&icap,0,sizeof(icap)); cres = this->ImageCodecInitialize (this->ci, &icap); lprintf ("video: ImageCodecInitialize->%p size=%d (%d)\n", cres,icap.recordSize,icap.decompressRecordSize); memset(&cinfo,0,sizeof(cinfo)); cres = this->ImageCodecGetCodecInfo (this->ci, &cinfo); lprintf ("video: Flags: compr: 0x%X decomp: 0x%X format: 0x%X\n", cinfo.compressFlags, cinfo.decompressFlags, cinfo.formatFlags); lprintf ("video: Codec name: %.*s\n", ((unsigned char*)&cinfo.typeName)[0], ((unsigned char*)&cinfo.typeName)+1); /* make a yuy2 gworld */ this->OutBufferRect.top = 0; this->OutBufferRect.left = 0; this->OutBufferRect.right = this->bih.biWidth; this->OutBufferRect.bottom = this->bih.biHeight; lprintf ("video: image size %d x %d\n", this->bih.biWidth, this->bih.biHeight); lprintf ("video: stsd (%d bytes):\n", buf->decoder_info[2]) ; #ifdef LOG qtv_hexdump ((unsigned char *)buf->decoder_info_ptr[2], buf->decoder_info[2]); #endif { uint8_t *stdata = ((unsigned char *)buf->decoder_info_ptr[2]); int stdata_len = buf->decoder_info[2]; id=malloc (8+stdata_len) ; /* trak->stdata_len); */ id->idSize = 4+stdata_len; id->cType = FOUR_CHAR_CODE('S','V','Q','3'); id->version = _X_BE_16 (stdata+0x08); id->revisionLevel = _X_BE_16 (stdata+0x0C); id->vendor = _X_BE_32 (stdata+0x10); id->temporalQuality = _X_BE_32 (stdata+0x14); id->spatialQuality = _X_BE_32 (stdata+0x18); id->width = _X_BE_16 (stdata+0x1C); id->height = _X_BE_16 (stdata+0x1E); id->hRes = _X_BE_32 (stdata+0x20); id->vRes = _X_BE_32 (stdata+0x24); id->dataSize = _X_BE_32 (stdata+0x28); id->frameCount = _X_BE_16 (stdata+0x2C); memcpy(&id->name,stdata+0x2D,32); id->depth = _X_BE_16 (stdata+0x4E); id->clutID = _X_BE_16 (stdata+0x50); if (stdata_len>0x56) memcpy (((char*)&id->clutID)+2, stdata+0x52, stdata_len-0x52); lprintf ("video: id (%d bytes)\n", stdata_len); #ifdef LOG qtv_hexdump (id, stdata_len); #endif } lprintf ("video: ImageDescription size: %d\n", id->idSize); #ifdef LOG qtv_hexdump (id, id->idSize); #endif this->framedescHandle = (ImageDescriptionHandle) this->NewHandleClear (id->idSize); lprintf ("video: framedescHandle = %x\n", this->framedescHandle); memcpy (*this->framedescHandle, id, id->idSize); free(id); /* * alloc video plane */ this->plane = malloc (this->bih.biWidth * this->bih.biHeight * 3); result = this->QTNewGWorldFromPtr(&this->OutBufferGWorld, kYUVSPixelFormat, /*pixel format of new GWorld==YUY2 */ &this->OutBufferRect, /*we should benchmark if yvu9 is faster for svq3, too */ 0, 0, 0, this->plane, this->bih.biWidth*2); lprintf ("video: NewGWorldFromPtr returned:%d\n", 65536-(result&0xffff)); this->decpar.imageDescription = this->framedescHandle; this->decpar.startLine = 0; this->decpar.stopLine = (**this->framedescHandle).height; this->decpar.frameNumber = 1; this->decpar.matrixFlags = 0; this->decpar.matrixType = 0; this->decpar.matrix = 0; this->decpar.capabilities = &this->codeccap; this->decpar.accuracy = codecNormalQuality; this->decpar.port = (CGrafPtr)this->OutBufferGWorld; this->decpar.srcRect = this->OutBufferRect; this->decpar.transferMode = srcCopy; this->decpar.dstPixMap = **this->GetGWorldPixMap (this->OutBufferGWorld);/*destPixmap; */ cres = this->ImageCodecPreDecompress (this->ci, &this->decpar); lprintf ("video: ImageCodecPreDecompress cres=0x%X\n", cres); this->data_len = 0; this->codec_initialized = 1; (this->stream->video_out->open) (this->stream->video_out, this->stream); pthread_mutex_unlock(&win32_codec_mutex); } static void qtv_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { qtv_decoder_t *this = (qtv_decoder_t *) this_gen; lprintf ("video: decode_data, flags=0x%08x, len=%d, pts=%lld ...\n", buf->decoder_flags, buf->size, buf->pts); if (buf->decoder_flags & BUF_FLAG_STDHEADER) { lprintf ("video: copying bih\n"); memcpy (&this->bih, buf->content, sizeof (xine_bmiheader)); this->ratio = (double)this->bih.biWidth / (double)this->bih.biHeight; /* video decoder only handles SVQ3 at this point */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Sorenson Video 3 (QT DLL)"); } else if (buf->decoder_flags & BUF_FLAG_SPECIAL) { lprintf ("video: special buffer\n"); if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM) { lprintf ("video: got stsd atom -> init codec\n"); if (!this->codec_initialized) { qtv_init_driver (this, buf); } if (!this->codec_initialized) _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); } } else if (this->codec_initialized) { lprintf ("video: actual image data\n"); memcpy (&this->data[this->data_len], buf->content, buf->size); this->data_len += buf->size; lprintf ("video: got %d bytes in buffer\n", this->data_len); if (buf->decoder_flags & BUF_FLAG_FRAME_END) { ComponentResult cres; vo_frame_t *img; Check_FS_Segment(this->ldt_fs); pthread_mutex_lock(&win32_codec_mutex); this->decpar.data = this->data; this->decpar.bufferSize = this->data_len; (**this->framedescHandle).dataSize=this->data_len; cres = this->ImageCodecBandDecompress (this->ci, &this->decpar); ++this->decpar.frameNumber; pthread_mutex_unlock(&win32_codec_mutex); if (cres&0xFFFF){ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "qt_video: ImageCodecBandDecompress cres=0x%lX (-0x%lX) %ld :(\n", cres,-cres,cres); } img = this->stream->video_out->get_frame (this->stream->video_out, this->bih.biWidth, this->bih.biHeight, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); img->pts = buf->pts; img->duration = buf->decoder_info[0]; img->bad_frame = 0; xine_fast_memcpy (img->base[0], this->plane, this->bih.biWidth*this->bih.biHeight*2); img->draw(img, this->stream); img->free(img); this->data_len = 0; } } lprintf ("video: decode_data...done\n"); } static void qtv_flush (video_decoder_t *this_gen) { /* qtv_decoder_t *this = (qtv_decoder_t *) this_gen; */ (void)this_gen; lprintf ("video: flush\n"); } static void qtv_reset (video_decoder_t *this_gen) { qtv_decoder_t *this = (qtv_decoder_t *) this_gen; this->data_len = 0; } static void qtv_discontinuity (video_decoder_t *this_gen) { /* qtv_decoder_t *this = (qtv_decoder_t *) this_gen; */ (void)this_gen; } static void qtv_dispose (video_decoder_t *this_gen) { qtv_decoder_t *this = (qtv_decoder_t *) this_gen; if (this->codec_initialized) { this->stream->video_out->close(this->stream->video_out, this->stream); this->codec_initialized = 0; Restore_LDT_Keeper(this->ldt_fs); this->ldt_fs = NULL; } lprintf ("video: dispose\n"); free (this); } static video_decoder_t *qtv_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { qtv_decoder_t *this = calloc (1, sizeof (*this)); if (!this) return NULL; this->video_decoder.decode_data = qtv_decode_data; this->video_decoder.flush = qtv_flush; this->video_decoder.reset = qtv_reset; this->video_decoder.discontinuity = qtv_discontinuity; this->video_decoder.dispose = qtv_dispose; this->stream = stream; (void)class_gen; return &this->video_decoder; } /* * qtv plugin class */ /* * some fake functions to make qt codecs happy */ #if 0 static void codec_path_cb (void *data, xine_cfg_entry_t *cfg) { qtv_class_t *this = (qt_class_t *) data; this->qt_codec_path = cfg->str_value; } #endif void *qtv_init_class (xine_t *xine, const void *data) { static const video_decoder_class_t this = { .open_plugin = qtv_open_plugin, .identifier = "qtvdec", .description = N_("quicktime binary-only codec based video decoder plugin"), .dispose = NULL }; lprintf ("%s...\n", __XINE_FUNCTION__); (void)data; if ((win32_def_path = get_win32_codecs_path (xine->config)) == NULL) return NULL; pthread_once (&once_control, init_routine); return (video_decoder_class_t *)&this; } ����������������������������������������������������������������������xine-lib-1.2/src/libw32dll/qtx/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014065� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/qtx/qtxsdk/��������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�015403� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/qtx/qtxsdk/select.h������������������������������������������������������0000644�0001750�0001750�00000007777�14647725152�017055� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� enum { kComponentOpenSelect = -1, /* ComponentInstance for this open */ kComponentCloseSelect = -2, /* ComponentInstance for this close */ kComponentCanDoSelect = -3, /* selector # being queried */ kComponentVersionSelect = -4, /* no params */ kComponentRegisterSelect = -5, /* no params */ kComponentTargetSelect = -6, /* ComponentInstance for top of call chain */ kComponentUnregisterSelect = -7, /* no params */ kComponentGetMPWorkFunctionSelect = -8, /* some params */ kComponentExecuteWiredActionSelect = -9, /* QTAtomContainer actionContainer, QTAtom actionAtom, QTCustomActionTargetPtr target, QTEventRecordPtr event */ kComponentGetPublicResourceSelect = -10 /* OSType resourceType, short resourceId, Handle *resource */ }; /* selectors for component calls */ enum { kImageCodecGetCodecInfoSelect = 0x0000, kImageCodecGetCompressionTimeSelect = 0x0001, kImageCodecGetMaxCompressionSizeSelect = 0x0002, kImageCodecPreCompressSelect = 0x0003, kImageCodecBandCompressSelect = 0x0004, kImageCodecPreDecompressSelect = 0x0005, kImageCodecBandDecompressSelect = 0x0006, kImageCodecBusySelect = 0x0007, kImageCodecGetCompressedImageSizeSelect = 0x0008, kImageCodecGetSimilaritySelect = 0x0009, kImageCodecTrimImageSelect = 0x000A, kImageCodecRequestSettingsSelect = 0x000B, kImageCodecGetSettingsSelect = 0x000C, kImageCodecSetSettingsSelect = 0x000D, kImageCodecFlushSelect = 0x000E, kImageCodecSetTimeCodeSelect = 0x000F, kImageCodecIsImageDescriptionEquivalentSelect = 0x0010, kImageCodecNewMemorySelect = 0x0011, kImageCodecDisposeMemorySelect = 0x0012, kImageCodecHitTestDataSelect = 0x0013, kImageCodecNewImageBufferMemorySelect = 0x0014, kImageCodecExtractAndCombineFieldsSelect = 0x0015, kImageCodecGetMaxCompressionSizeWithSourcesSelect = 0x0016, kImageCodecSetTimeBaseSelect = 0x0017, kImageCodecSourceChangedSelect = 0x0018, kImageCodecFlushFrameSelect = 0x0019, kImageCodecGetSettingsAsTextSelect = 0x001A, kImageCodecGetParameterListHandleSelect = 0x001B, kImageCodecGetParameterListSelect = 0x001C, kImageCodecCreateStandardParameterDialogSelect = 0x001D, kImageCodecIsStandardParameterDialogEventSelect = 0x001E, kImageCodecDismissStandardParameterDialogSelect = 0x001F, kImageCodecStandardParameterDialogDoActionSelect = 0x0020, kImageCodecNewImageGWorldSelect = 0x0021, kImageCodecDisposeImageGWorldSelect = 0x0022, kImageCodecHitTestDataWithFlagsSelect = 0x0023, kImageCodecValidateParametersSelect = 0x0024, kImageCodecGetBaseMPWorkFunctionSelect = 0x0025, kImageCodecRequestGammaLevelSelect = 0x0028, kImageCodecGetSourceDataGammaLevelSelect = 0x0029, kImageCodecGetDecompressLatencySelect = 0x002B, kImageCodecPreflightSelect = 0x0200, kImageCodecInitializeSelect = 0x0201, kImageCodecBeginBandSelect = 0x0202, kImageCodecDrawBandSelect = 0x0203, kImageCodecEndBandSelect = 0x0204, kImageCodecQueueStartingSelect = 0x0205, kImageCodecQueueStoppingSelect = 0x0206, kImageCodecDroppingFrameSelect = 0x0207, kImageCodecScheduleFrameSelect = 0x0208, kImageCodecCancelTriggerSelect = 0x0209 }; �xine-lib-1.2/src/libw32dll/qtx/qtxsdk/components.h��������������������������������������������������0000644�0001750�0001750�00000117041�14647725152�017745� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Basic types: typedef char * Ptr; typedef Ptr * Handle; typedef long Size; typedef unsigned char Boolean; typedef unsigned char Str31[32]; typedef long Fixed; typedef long OSErr; typedef int OSType; typedef long ComponentResult; typedef unsigned char UInt8; typedef signed char SInt8; typedef unsigned short UInt16; typedef signed short SInt16; typedef unsigned long UInt32; typedef signed long SInt32; #define FOUR_CHAR_CODE(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) // codec private shit: typedef void *GlobalsPtr; typedef void **Globals; //==================== COMPONENTS =========================== struct __attribute__((__packed__)) ComponentParameters { UInt8 flags; /* call modifiers: sync/async, deferred, immed, etc */ UInt8 paramSize; /* size in bytes of actual parameters passed to this call */ short what; /* routine selector, negative for Component management calls */ long params[1]; /* actual parameters for the indicated routine */ }; typedef struct ComponentParameters ComponentParameters; struct __attribute__((__packed__)) ComponentDescription { OSType componentType; /* A unique 4-byte code indentifying the command set */ OSType componentSubType; /* Particular flavor of this instance */ OSType componentManufacturer; /* Vendor indentification */ unsigned long componentFlags; /* 8 each for Component,Type,SubType,Manuf/revision */ unsigned long componentFlagsMask; /* Mask for specifying which flags to consider in search, zero during registration */ }; typedef struct ComponentDescription ComponentDescription; struct __attribute__((__packed__)) ResourceSpec { OSType resType; /* 4-byte code */ short resID; /* */ }; typedef struct ResourceSpec ResourceSpec; struct __attribute__((__packed__)) ComponentResource { ComponentDescription cd; /* Registration parameters */ ResourceSpec component; /* resource where Component code is found */ ResourceSpec componentName; /* name string resource */ ResourceSpec componentInfo; /* info string resource */ ResourceSpec componentIcon; /* icon resource */ }; typedef struct ComponentResource ComponentResource; typedef ComponentResource * ComponentResourcePtr; typedef ComponentResourcePtr * ComponentResourceHandle; struct __attribute__((__packed__)) ComponentRecord { long data[1]; }; typedef struct ComponentRecord ComponentRecord; typedef ComponentRecord * Component; struct __attribute__((__packed__)) ComponentInstanceRecord { long data[1]; }; typedef struct ComponentInstanceRecord ComponentInstanceRecord; typedef ComponentInstanceRecord * ComponentInstance; // ========================= QUICKDRAW ========================= struct __attribute__((__packed__)) Rect { short top; short left; short bottom; short right; }; typedef struct Rect Rect; typedef Rect * RectPtr; struct __attribute__((__packed__)) RGBColor { unsigned short red; /*magnitude of red component*/ unsigned short green; /*magnitude of green component*/ unsigned short blue; /*magnitude of blue component*/ }; typedef struct RGBColor RGBColor; typedef RGBColor * RGBColorPtr; typedef RGBColorPtr * RGBColorHdl; struct __attribute__((__packed__)) ColorSpec { short value; /*index or other value*/ RGBColor rgb; /*true color*/ }; typedef struct ColorSpec ColorSpec; typedef ColorSpec * ColorSpecPtr; typedef ColorSpec CSpecArray[1]; struct __attribute__((__packed__)) ColorTable { long ctSeed; /*unique identifier for table*/ short ctFlags; /*high bit: 0 = PixMap; 1 = device*/ short ctSize; /*number of entries in CTTable*/ CSpecArray ctTable; /*array [0..0] of ColorSpec*/ }; typedef struct ColorTable ColorTable; typedef ColorTable * CTabPtr; typedef CTabPtr * CTabHandle; struct __attribute__((__packed__)) MatrixRecord { Fixed matrix[3][3]; }; typedef struct MatrixRecord MatrixRecord; typedef MatrixRecord * MatrixRecordPtr; typedef long ImageSequence; typedef OSType CodecType; typedef unsigned short CodecFlags; typedef unsigned long CodecQ; struct __attribute__((__packed__)) ImageDescription { long idSize; /* total size of ImageDescription including extra data ( CLUTs and other per sequence data ) */ CodecType cType; /* what kind of codec compressed this data */ long resvd1; /* reserved for Apple use */ short resvd2; /* reserved for Apple use */ short dataRefIndex; /* set to zero */ short version; /* which version is this data */ short revisionLevel; /* what version of that codec did this */ long vendor; /* whose codec compressed this data */ CodecQ temporalQuality; /* what was the temporal quality factor */ CodecQ spatialQuality; /* what was the spatial quality factor */ short width; /* how many pixels wide is this data */ short height; /* how many pixels high is this data */ Fixed hRes; /* horizontal resolution */ Fixed vRes; /* vertical resolution */ long dataSize; /* if known, the size of data for this image descriptor */ short frameCount; /* number of frames this description applies to */ Str31 name; /* name of codec ( in case not installed ) */ short depth; /* what depth is this data (1-32) or ( 33-40 grayscale ) */ short clutID; /* clut id or if 0 clut follows or -1 if no clut */ }; typedef struct ImageDescription ImageDescription; typedef ImageDescription * ImageDescriptionPtr; typedef ImageDescriptionPtr * ImageDescriptionHandle; /* values for PixMap.pixelFormat*/ enum { k16LE555PixelFormat = FOUR_CHAR_CODE('L','5','5','5'), /* 16 bit LE rgb 555 (PC)*/ k16LE5551PixelFormat = FOUR_CHAR_CODE('5','5','5','1'), /* 16 bit LE rgb 5551*/ k16BE565PixelFormat = FOUR_CHAR_CODE('B','5','6','5'), /* 16 bit BE rgb 565*/ k16LE565PixelFormat = FOUR_CHAR_CODE('L','5','6','5'), /* 16 bit LE rgb 565*/ k24BGRPixelFormat = FOUR_CHAR_CODE('2','4','B','G'), /* 24 bit bgr */ k32BGRAPixelFormat = FOUR_CHAR_CODE('B','G','R','A'), /* 32 bit bgra (Matrox)*/ k32ABGRPixelFormat = FOUR_CHAR_CODE('A','B','G','R'), /* 32 bit abgr */ k32RGBAPixelFormat = FOUR_CHAR_CODE('R','G','B','A'), /* 32 bit rgba */ kYUVSPixelFormat = FOUR_CHAR_CODE('y','u','v','s'), /* YUV 4:2:2 byte ordering 16-unsigned = 'YUY2'*/ kYUVUPixelFormat = FOUR_CHAR_CODE('y','u','v','u'), /* YUV 4:2:2 byte ordering 16-signed*/ kYVU9PixelFormat = FOUR_CHAR_CODE('Y','V','U','9'), /* YVU9 Planar 9*/ kYUV411PixelFormat = FOUR_CHAR_CODE('Y','4','1','1'), /* YUV 4:1:1 Interleaved 16*/ kYVYU422PixelFormat = FOUR_CHAR_CODE('Y','V','Y','U'), /* YVYU 4:2:2 byte ordering 16*/ kUYVY422PixelFormat = FOUR_CHAR_CODE('U','Y','V','Y'), /* UYVY 4:2:2 byte ordering 16*/ kYUV211PixelFormat = FOUR_CHAR_CODE('Y','2','1','1'), /* YUV 2:1:1 Packed 8*/ k2vuyPixelFormat = FOUR_CHAR_CODE('2','v','u','y') /* UYVY 4:2:2 byte ordering 16*/ }; struct __attribute__((__packed__)) PixMapExtension { long extSize; /*size of struct, duh!*/ unsigned long pmBits; /*pixmap attributes bitfield*/ void * pmGD; /*this is a GDHandle*/ long pmSeed; Fixed gammaLevel; /*pixmap gammalevel*/ Fixed requestedGammaLevel; unsigned long reserved2; long longRowBytes; /*used when rowBytes > 16382*/ unsigned long signature; Handle baseAddrHandle; }; typedef struct PixMapExtension PixMapExtension; typedef PixMapExtension * PixMapExtPtr; typedef PixMapExtPtr * PixMapExtHandle; struct __attribute__((__packed__)) PixMap { Ptr baseAddr; /*pointer to pixels*/ short rowBytes; /*offset to next line*/ Rect bounds; /*encloses bitmap*/ short pmVersion; /*pixMap version number*/ short packType; /*defines packing format*/ long packSize; /*length of pixel data*/ Fixed hRes; /*horiz. resolution (ppi)*/ Fixed vRes; /*vert. resolution (ppi)*/ short pixelType; /*defines pixel type*/ short pixelSize; /*# bits in pixel*/ short cmpCount; /*# components in pixel*/ short cmpSize; /*# bits per component*/ OSType pixelFormat; /*fourCharCode representation*/ CTabHandle pmTable; /*color map for this pixMap*/ PixMapExtHandle pmExt; /*Handle to pixMap extension*/ }; typedef struct PixMap PixMap; typedef PixMap * PixMapPtr; typedef PixMapPtr * PixMapHandle; struct __attribute__((__packed__)) BitMap { Ptr baseAddr; short rowBytes; Rect bounds; }; typedef struct BitMap BitMap; typedef BitMap * BitMapPtr; typedef BitMapPtr * BitMapHandle; typedef struct OpaqueRgnHandle* RgnHandle; struct Pattern { UInt8 pat[8]; }; typedef struct Pattern Pattern; typedef unsigned char Style; typedef Style StyleField; struct __attribute__((__packed__)) Point { short v; short h; }; typedef struct Point Point; struct __attribute__((__packed__)) GrafPort { short device; BitMap portBits; Rect portRect; RgnHandle visRgn; RgnHandle clipRgn; Pattern bkPat; Pattern fillPat; Point pnLoc; Point pnSize; short pnMode; Pattern pnPat; short pnVis; short txFont; StyleField txFace; /*StyleField occupies 16-bits, but only first 8-bits are used*/ UInt8 txFlags; /* QuickTime uses second 8 bits of StyleField for txFlags */ short txMode; short txSize; Fixed spExtra; long fgColor; long bkColor; short colrBit; short patStretch; Handle picSave; Handle rgnSave; Handle polySave; /*QDProcsPtr*/void* grafProcs; }; typedef struct GrafPort GrafPort; typedef GrafPort *GWorldPtr; typedef GWorldPtr *GWorldHandle; #define anyCodec ((CodecComponent)0) enum { /* transfer modes */ srcCopy = 0, /*the 16 transfer modes*/ srcOr = 1, srcXor = 2, srcBic = 3, notSrcCopy = 4, notSrcOr = 5, notSrcXor = 6, notSrcBic = 7, patCopy = 8, patOr = 9, patXor = 10, patBic = 11, notPatCopy = 12, notPatOr = 13, notPatXor = 14, notPatBic = 15, /* Special Text Transfer Mode */ grayishTextOr = 49, hilitetransfermode = 50, hilite = 50, /* Arithmetic transfer modes */ blend = 32, addPin = 33, addOver = 34, subPin = 35, addMax = 37, adMax = 37, subOver = 38, adMin = 39, ditherCopy = 64, /* Transparent mode constant */ transparent = 36 }; typedef unsigned long GWorldFlags; // ============================== CODECS =========================== typedef Component CompressorComponent; typedef Component DecompressorComponent; typedef Component CodecComponent; enum { codecLosslessQuality = 0x00000400, codecMaxQuality = 0x000003FF, codecMinQuality = 0x00000000, codecLowQuality = 0x00000100, codecNormalQuality = 0x00000200, codecHighQuality = 0x00000300 }; // callbacks: typedef void* ImageCodecDrawBandCompleteUPP; typedef long long ICMProgressProcRecord; typedef long long ICMCompletionProcRecord; typedef long long ICMDataProcRecord; typedef void* ICMFrameTimePtr; typedef void* CDSequenceDataSourcePtr; typedef void* ICMFrameTimeInfoPtr; // graphics port typedef struct OpaqueGrafPtr* GrafPtr; typedef GrafPtr CGrafPtr; /* codec capabilities flags */ enum { codecCanScale = 1L << 0, // 1 codecCanMask = 1L << 1, // 2 codecCanMatte = 1L << 2, // 4 codecCanTransform = 1L << 3, // 8 codecCanTransferMode = 1L << 4, // 10 codecCanCopyPrev = 1L << 5, // 20 codecCanSpool = 1L << 6, // 40 codecCanClipVertical = 1L << 7, // 80 codecCanClipRectangular = 1L << 8, // 100 codecCanRemapColor = 1L << 9, // 200 codecCanFastDither = 1L << 10, // 400 codecCanSrcExtract = 1L << 11, // 800 codecCanCopyPrevComp = 1L << 12, // 1000 codecCanAsync = 1L << 13, // 2000 codecCanMakeMask = 1L << 14, // 4000 codecCanShift = 1L << 15, // 8000 codecCanAsyncWhen = 1L << 16, // 10000 codecCanShieldCursor = 1L << 17, // 20000 codecCanManagePrevBuffer = 1L << 18, // 40000 codecHasVolatileBuffer = 1L << 19, // 80000 /* codec requires redraw after window movement */ codecWantsRegionMask = 1L << 20, // 100000 codecImageBufferIsOnScreen = 1L << 21, // 200000 /* old def of codec using overlay surface, = ( codecIsDirectToScreenOnly | codecUsesOverlaySurface | codecImageBufferIsOverlaySurface | codecSrcMustBeImageBuffer ) */ codecWantsDestinationPixels = 1L << 22, // 400000 codecWantsSpecialScaling = 1L << 23, // 800000 codecHandlesInputs = 1L << 24, // 1000000 codecCanDoIndirectSurface = 1L << 25, /* codec can handle indirect surface (GDI) */ codecIsSequenceSensitive = 1L << 26, codecRequiresOffscreen = 1L << 27, codecRequiresMaskBits = 1L << 28, codecCanRemapResolution = 1L << 29, codecIsDirectToScreenOnly = 1L << 30, /* codec can only decompress data to the screen */ codecCanLockSurface = 1L << 31 /* codec can lock destination surface, icm doesn't lock for you */ }; /* codec capabilities flags2 */ enum { codecUsesOverlaySurface = 1L << 0, /* codec uses overlay surface */ codecImageBufferIsOverlaySurface = 1L << 1, /* codec image buffer is overlay surface, the bits in the buffer are on the screen */ codecSrcMustBeImageBuffer = 1L << 2, /* codec can only source data from an image buffer */ codecImageBufferIsInAGPMemory = 1L << 4, /* codec image buffer is in AGP space, byte writes are OK */ codecImageBufferIsInPCIMemory = 1L << 5 /* codec image buffer is across a PCI bus; byte writes are bad */ }; /* codec condition flags */ // FFD = 13 = 8+4+1 enum { codecConditionFirstBand = 1L << 0, // 1 codecConditionLastBand = 1L << 1, // 2 codecConditionFirstFrame = 1L << 2, // 4 codecConditionNewDepth = 1L << 3, // 8 codecConditionNewTransform = 1L << 4, // 10 codecConditionNewSrcRect = 1L << 5, // 20 codecConditionNewMask = 1L << 6, // 40 codecConditionNewMatte = 1L << 7, // 80 codecConditionNewTransferMode = 1L << 8, // 100 codecConditionNewClut = 1L << 9, // 200 codecConditionNewAccuracy = 1L << 10, // 400 codecConditionNewDestination = 1L << 11, // 800 codecConditionFirstScreen = 1L << 12, // 1000 codecConditionDoCursor = 1L << 13, // 2000 codecConditionCatchUpDiff = 1L << 14, // 4000 codecConditionMaskMayBeChanged = 1L << 15, // 8000 codecConditionToBuffer = 1L << 16, // 10000 codecConditionCodecChangedMask = 1L << 31 // 20000 }; struct __attribute__((__packed__)) CodecCapabilities { long flags; short wantedPixelSize; short extendWidth; short extendHeight; short bandMin; short bandInc; short pad; unsigned long time; long flags2; /* field new in QuickTime 4.0 */ }; typedef struct CodecCapabilities CodecCapabilities; struct __attribute__((__packed__)) CodecDecompressParams { ImageSequence sequenceID; /* predecompress,banddecompress */ ImageDescriptionHandle imageDescription; /* predecompress,banddecompress */ Ptr data; long bufferSize; long frameNumber; long startLine; long stopLine; long conditionFlags; CodecFlags callerFlags; // short CodecCapabilities * capabilities; /* predecompress,banddecompress */ ICMProgressProcRecord progressProcRecord; ICMCompletionProcRecord completionProcRecord; ICMDataProcRecord dataProcRecord; CGrafPtr port; /* predecompress,banddecompress */ PixMap dstPixMap; /* predecompress,banddecompress */ BitMapPtr maskBits; PixMapPtr mattePixMap; Rect srcRect; /* predecompress,banddecompress */ MatrixRecord * matrix; /* predecompress,banddecompress */ CodecQ accuracy; /* predecompress,banddecompress */ short transferMode; /* predecompress,banddecompress */ ICMFrameTimePtr frameTime; /* banddecompress */ long reserved[1]; /* The following fields only exist for QuickTime 2.0 and greater */ SInt8 matrixFlags; /* high bit set if 2x resize */ SInt8 matrixType; Rect dstRect; /* only valid for simple transforms */ /* The following fields only exist for QuickTime 2.1 and greater */ UInt16 majorSourceChangeSeed; UInt16 minorSourceChangeSeed; CDSequenceDataSourcePtr sourceData; RgnHandle maskRegion; /* The following fields only exist for QuickTime 2.5 and greater */ OSType ** wantedDestinationPixelTypes; /* Handle to 0-terminated list of OSTypes */ long screenFloodMethod; long screenFloodValue; short preferredOffscreenPixelSize; /* The following fields only exist for QuickTime 3.0 and greater */ ICMFrameTimeInfoPtr syncFrameTime; /* banddecompress */ Boolean needUpdateOnTimeChange; /* banddecompress */ Boolean enableBlackLining; Boolean needUpdateOnSourceChange; /* band decompress */ Boolean pad; long unused; CGrafPtr finalDestinationPort; long requestedBufferWidth; /* must set codecWantsSpecialScaling to indicate this field is valid*/ long requestedBufferHeight; /* must set codecWantsSpecialScaling to indicate this field is valid*/ /* The following fields only exist for QuickTime 4.0 and greater */ Rect displayableAreaOfRequestedBuffer; /* set in predecompress*/ Boolean requestedSingleField; Boolean needUpdateOnNextIdle; Boolean pad2[2]; Fixed bufferGammaLevel; /* The following fields only exist for QuickTime 5.0 and greater */ UInt32 taskWeight; /* preferred weight for MP tasks implementing this operation*/ OSType taskName; /* preferred name (type) for MP tasks implementing this operation*/ }; typedef struct CodecDecompressParams CodecDecompressParams; struct __attribute__((__packed__)) ImageSubCodecDecompressCapabilities { long recordSize; /* sizeof(ImageSubCodecDecompressCapabilities)*/ long decompressRecordSize; /* size of your codec's decompress record*/ Boolean canAsync; /* default true*/ UInt8 pad0; /* The following fields only exist for QuickTime 4.0 and greater */ UInt16 suggestedQueueSize; Boolean canProvideTrigger; /* The following fields only exist for QuickTime 5.0 and greater */ Boolean subCodecFlushesScreen; /* only used on Mac OS X*/ Boolean subCodecCallsDrawBandComplete; UInt8 pad2[1]; /* The following fields only exist for QuickTime 5.1 and greater */ Boolean isChildCodec; /* set by base codec before calling Initialize*/ UInt8 pad3[3]; }; typedef struct ImageSubCodecDecompressCapabilities ImageSubCodecDecompressCapabilities; struct __attribute__((__packed__)) ImageSubCodecDecompressRecord { Ptr baseAddr; long rowBytes; Ptr codecData; ICMProgressProcRecord progressProcRecord; ICMDataProcRecord dataProcRecord; void * userDecompressRecord; /* pointer to codec-specific per-band data*/ UInt8 frameType; Boolean inhibitMP; /* set this in BeginBand to tell the base decompressor not to call DrawBand from an MP task for this frame. (Only has any effect for MP-capable subcodecs. New in QuickTime 5.0.)*/ UInt8 pad[2]; long priv[2]; /* The following fields only exist for QuickTime 5.0 and greater */ ImageCodecDrawBandCompleteUPP drawBandCompleteUPP; /* only used if subcodec set subCodecCallsDrawBandComplete; if drawBandCompleteUPP is non-nil, codec must call it when a frame is finished, but may return from DrawBand before the frame is finished. */ void * drawBandCompleteRefCon; /* Note: do not call drawBandCompleteUPP directly from a hardware interrupt; instead, use DTInstall to run a function at deferred task time, and call drawBandCompleteUPP from that. */ }; typedef struct ImageSubCodecDecompressRecord ImageSubCodecDecompressRecord; /* These are the bits that are set in the Component flags, and also in the codecInfo struct. */ enum { codecInfoDoes1 = (1L << 0), /* codec can work with 1-bit pixels */ codecInfoDoes2 = (1L << 1), /* codec can work with 2-bit pixels */ codecInfoDoes4 = (1L << 2), /* codec can work with 4-bit pixels */ codecInfoDoes8 = (1L << 3), /* codec can work with 8-bit pixels */ codecInfoDoes16 = (1L << 4), /* codec can work with 16-bit pixels */ codecInfoDoes32 = (1L << 5), /* codec can work with 32-bit pixels */ codecInfoDoesDither = (1L << 6), /* codec can do ditherMode */ codecInfoDoesStretch = (1L << 7), /* codec can stretch to arbitrary sizes */ codecInfoDoesShrink = (1L << 8), /* codec can shrink to arbitrary sizes */ codecInfoDoesMask = (1L << 9), /* codec can mask to clipping regions */ codecInfoDoesTemporal = (1L << 10), /* codec can handle temporal redundancy */ codecInfoDoesDouble = (1L << 11), /* codec can stretch to double size exactly */ codecInfoDoesQuad = (1L << 12), /* codec can stretch to quadruple size exactly */ codecInfoDoesHalf = (1L << 13), /* codec can shrink to half size */ codecInfoDoesQuarter = (1L << 14), /* codec can shrink to quarter size */ codecInfoDoesRotate = (1L << 15), /* codec can rotate on decompress */ codecInfoDoesHorizFlip = (1L << 16), /* codec can flip horizontally on decompress */ codecInfoDoesVertFlip = (1L << 17), /* codec can flip vertically on decompress */ codecInfoHasEffectParameterList = (1L << 18), /* codec implements get effects parameter list call, once was codecInfoDoesSkew */ codecInfoDoesBlend = (1L << 19), /* codec can blend on decompress */ codecInfoDoesWarp = (1L << 20), /* codec can warp arbitrarily on decompress */ codecInfoDoesRecompress = (1L << 21), /* codec can recompress image without accumulating errors */ codecInfoDoesSpool = (1L << 22), /* codec can spool image data */ codecInfoDoesRateConstrain = (1L << 23) /* codec can data rate constrain */ }; enum { codecInfoDepth1 = (1L << 0), /* compressed data at 1 bpp depth available */ codecInfoDepth2 = (1L << 1), /* compressed data at 2 bpp depth available */ codecInfoDepth4 = (1L << 2), /* compressed data at 4 bpp depth available */ codecInfoDepth8 = (1L << 3), /* compressed data at 8 bpp depth available */ codecInfoDepth16 = (1L << 4), /* compressed data at 16 bpp depth available */ codecInfoDepth32 = (1L << 5), /* compressed data at 32 bpp depth available */ codecInfoDepth24 = (1L << 6), /* compressed data at 24 bpp depth available */ codecInfoDepth33 = (1L << 7), /* compressed data at 1 bpp monochrome depth available */ codecInfoDepth34 = (1L << 8), /* compressed data at 2 bpp grayscale depth available */ codecInfoDepth36 = (1L << 9), /* compressed data at 4 bpp grayscale depth available */ codecInfoDepth40 = (1L << 10), /* compressed data at 8 bpp grayscale depth available */ codecInfoStoresClut = (1L << 11), /* compressed data can have custom cluts */ codecInfoDoesLossless = (1L << 12), /* compressed data can be stored in lossless format */ codecInfoSequenceSensitive = (1L << 13) /* compressed data is sensitive to out of sequence decoding */ }; struct __attribute__((__packed__)) CodecInfo { Str31 typeName; /* name of the codec type i.e.: 'Apple Image Compression' */ short version; /* version of the codec data that this codec knows about */ short revisionLevel; /* revision level of this codec i.e: 0x00010001 (1.0.1) */ long vendor; /* Maker of this codec i.e: 'appl' */ long decompressFlags; /* codecInfo flags for decompression capabilities */ long compressFlags; /* codecInfo flags for compression capabilities */ long formatFlags; /* codecInfo flags for compression format details */ UInt8 compressionAccuracy; /* measure (1-255) of accuracy of this codec for compress (0 if unknown) */ UInt8 decompressionAccuracy; /* measure (1-255) of accuracy of this codec for decompress (0 if unknown) */ unsigned short compressionSpeed; /* ( millisecs for compressing 320x240 on base mac II) (0 if unknown) */ unsigned short decompressionSpeed; /* ( millisecs for decompressing 320x240 on mac II)(0 if unknown) */ UInt8 compressionLevel; /* measure (1-255) of compression level of this codec (0 if unknown) */ UInt8 resvd; /* pad */ short minimumHeight; /* minimum height of image (block size) */ short minimumWidth; /* minimum width of image (block size) */ short decompressPipelineLatency; /* in milliseconds ( for asynchronous codecs ) */ short compressPipelineLatency; /* in milliseconds ( for asynchronous codecs ) */ long privateData; }; typedef struct CodecInfo CodecInfo; static inline void dump_ImageDescription(void* xxx){ ImageDescription* id=(ImageDescription*)xxx; unsigned char* x; int i; for(i=0;i<id->idSize;i++){ printf(" %02X",((unsigned char*)id)[i]); if((i%16)==15) printf("\n"); } printf("\n"); printf("=============== ImageDescription at %p ==================\n",xxx); printf("idSize=0x%lX fourcc=0x%08X\n",id->idSize,id->cType); printf("ver=%d rev=%d vendor=0x%08lX\n",id->version,id->revisionLevel,id->vendor); printf("tempQ=%ld spatQ=%ld dim: %d x %d dpi: %ld x %ld depth: %d\n", id->temporalQuality,id->spatialQuality, id->width, id->height, id->hRes, id->vRes, id->depth); printf("dataSize=%ld frameCount=%d clutID=%d\n",id->dataSize, id->frameCount, id->clutID); printf("name='%.*s'\n",((char*)(&id->name))[0],((char*)(&id->name))+1); x=((char*)(&id->clutID))+2; if(id->idSize>(int)sizeof(ImageDescription)){ printf("%02X %02X %02X %02X | %02X %02X %02X %02X | %02X %02X %02X %02X | %02X %02X %02X %02X\n", x[0],x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15]); } printf("=========================================================\n"); } static inline void dump_Rect(const char* title,Rect *r){ printf("%s: %d;%d - %d;%d\n",title, (int)r->top,(int)r->left,(int)r->bottom,(int)r->right); } static inline void dump_MatrixRecord(const char* title, MatrixRecord *m){ printf("%s: [%ld %ld %ld][%ld %ld %ld][%ld %ld %ld]\n",title, m->matrix[0][0],m->matrix[0][1],m->matrix[0][2], m->matrix[1][0],m->matrix[1][1],m->matrix[1][2], m->matrix[2][0],m->matrix[2][1],m->matrix[2][2]); } static inline void dump_PixMap(void* xxx){ PixMap *p=xxx; printf("=============== PixMap at %p ==================\n",xxx); printf("base=%p stride=%d\n",p->baseAddr, p->rowBytes); dump_Rect("bounds",&p->bounds); printf("pmVersion=0x%X packType=0x%X\n packSize=0x%lX\n", p->pmVersion,p->packType, p->packSize); printf("hRes=0x%lX vRes=0x%lX pixelType=0x%X pixelSize=0x%X\n", p->hRes,p->vRes,p->pixelType,p->pixelSize); printf("cmpCount=0x%X cmpSize=0x%X pixelFormat=0x%X\n", p->cmpCount,p->cmpSize,p->pixelFormat); printf("pmTable=%p pmExt=%p\n",p->pmTable,p->pmExt); printf("=========================================================\n"); } static inline void dump_CodecCapabilities(void* xxx){ CodecCapabilities* cc=xxx; if(!xxx) return; printf("=============== CodecCapabilities at %p =================\n",xxx); printf("flags=0x%lX flags2=0x%lX\n",cc->flags,cc->flags2); printf("wantedPixelSize=%d extendWidth=%d extendHeight=%d band=%d+%d\n", cc->wantedPixelSize,cc->extendWidth,cc->extendHeight, cc->bandMin,cc->bandInc); printf("pad=0x%X time=0x%lX\n",cc->pad,cc->time); printf("=========================================================\n"); } static inline void dump_CodecDecompressParams(void* xxx){ CodecDecompressParams* cd=xxx; ImageDescription **idh; int i; if(!xxx) return; printf("=============== CodecDecompressParams at %p ==================\n",xxx); printf("sequenceID=%ld\n",cd->sequenceID); idh=cd->imageDescription; if(idh && idh[0]) dump_ImageDescription(idh[0]); for(i=0;i<(int)sizeof(CodecDecompressParams);i++){ printf(" %02X",((unsigned char*)cd)[i]); if((i%16)==15) printf("\n"); } printf("\n"); printf("data=%p size=%ld\n",cd->data,cd->bufferSize); printf("frameno=%ld lines: %ld .. %ld condflags=0x%lX callerflags=0x%X\n", cd->frameNumber, cd->startLine, cd->stopLine, cd->conditionFlags,cd->callerFlags); // printf("maskBits=%p mattePixMap=%p\n", // cd->maskBits,cd->mattePixMap); dump_PixMap(&cd->dstPixMap); // if(cd->mattePixMap) dump_PixMap(cd->mattePixMap); if(cd->matrix) dump_MatrixRecord("matrix",cd->matrix); if(cd->capabilities) dump_CodecCapabilities(cd->capabilities); printf("accuracy=%d transferMode=%d matrixFlags=0x%X matrixType=%d\n", (int)cd->accuracy, (int)cd->transferMode, (int)cd->matrixFlags, (int)cd->matrixType); printf("srcrect: %d;%d - %d;%d\n",cd->srcRect.top,cd->srcRect.left,cd->srcRect.bottom,cd->srcRect.right); printf("dstrect: %d;%d - %d;%d\n",cd->dstRect.top,cd->dstRect.left,cd->dstRect.bottom,cd->dstRect.right); printf("wantedDestinationPixelTypes=%p\n",cd->wantedDestinationPixelTypes); if(cd->wantedDestinationPixelTypes){ OSType **p=cd->wantedDestinationPixelTypes; while(p[0]){ printf(" 0x%p %d\n",p[0],*p[0]); ++p; } } printf("screenFloodMethod=%ld value=%ld preferredOffscreenPixelSize=%d\n", cd->screenFloodMethod, cd->screenFloodValue, cd->preferredOffscreenPixelSize); printf("callbacks: progress=0x%08llX compl=0x%08llX data=0x%08llX ftime=%p srcdata=%p sync=%p\n", cd->progressProcRecord, cd->completionProcRecord, cd->dataProcRecord, cd->frameTime, cd->sourceData, cd->syncFrameTime); // printf("\n"); printf("=========================================================\n"); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/���������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014030� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/dmo_guids.h����������������������������������������������������������0000644�0001750�0001750�00000001735�14647725152�016161� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DMO_GUIDS_H #define DMO_GUIDS_H #include "DirectShow/guids.h" extern const GUID IID_IMediaBuffer; extern const GUID IID_IMediaObject; extern const GUID IID_IEnumDMO; extern const GUID IID_IMediaObjectInPlace; extern const GUID IID_IDMOQualityControl; extern const GUID IID_IDMOVideoOutputOptimizations; /* to be removed extern const GUID DMOCATEGORY_AUDIO_DECODER; extern const GUID DMOCATEGORY_AUDIO_ENCODER; extern const GUID DMOCATEGORY_VIDEO_DECODER; extern const GUID DMOCATEGORY_VIDEO_ENCODER; extern const GUID DMOCATEGORY_AUDIO_EFFECT; extern const GUID DMOCATEGORY_VIDEO_EFFECT; extern const GUID DMOCATEGORY_AUDIO_CAPTURE_EFFECT; // Acoustic Echo Canceller // Matches KSNODETYPE_ACOUSTIC_ECHO_CANCEL extern const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL; // Noise Supression // Matches KSNODETYPE_AUDIO_NOISE_SUPPRESS extern const GUID DMOCATEGORY_AUDIO_NOISE_SUPPRESS; // Automatic Gain Control // Matches KSNODETYPE_AGC extern const GUID DMOCATEGORY_AGC; */ #endif �����������������������������������xine-lib-1.2/src/libw32dll/dmo/DMO_AudioDecoder.h���������������������������������������������������0000644�0001750�0001750�00000001274�14647725152�017233� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef AVIFILE_DMO_AUDIODECODER_H #define AVIFILE_DMO_AUDIODECODER_H typedef struct _DMO_AudioDecoder DMO_AudioDecoder; //DMO_AudioDecoder * DMO_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf); DMO_AudioDecoder * DMO_AudioDecoder_Open(const char* dllname, GUID* guid, WAVEFORMATEX* wf,int out_channels); void DMO_AudioDecoder_Destroy(DMO_AudioDecoder *this); int DMO_AudioDecoder_Convert(DMO_AudioDecoder *this, const void* in_data, unsigned int in_size, void* out_data, unsigned int out_size, unsigned int* size_read, unsigned int* size_written); int DMO_AudioDecoder_GetSrcSize(DMO_AudioDecoder *this, int dest_size); #endif // AVIFILE_DMO_AUDIODECODER_H ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/DMO_Filter.h���������������������������������������������������������0000644�0001750�0001750�00000002140�14647725152�016122� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DMO_FILTER_H #define DMO_FILTER_H #include "dmo_guids.h" #include "dmo_interfaces.h" #if defined(__cplusplus) extern "C" { #endif typedef struct _DMO_Filter { int m_iHandle; IDMOVideoOutputOptimizations* m_pOptim; IMediaObject* m_pMedia; IMediaObjectInPlace* m_pInPlace; AM_MEDIA_TYPE *m_pOurType, *m_pDestType; } DMO_Filter; typedef struct _CMediaBuffer CMediaBuffer; /** * Create DMO_Filter object - similar syntax as for DS_Filter */ DMO_Filter* DMO_FilterCreate(const char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt); /** * Destroy DMO_Filter object - release all allocated resources */ void DMO_Filter_Destroy(DMO_Filter* This); /** * Create IMediaBuffer object - to pass/receive data from DMO_Filter * * maxlen - maximum size for this buffer * mem - initial memory 0 - creates memory * len - initial size of used portion of the buffer * copy - make a local copy of data */ CMediaBuffer* CMediaBufferCreate(unsigned long maxlen, void* mem, unsigned long len, int copy); #if defined(__cplusplus) } #endif #endif /* DS_FILTER_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/dmo_guids.c����������������������������������������������������������0000644�0001750�0001750�00000003657�14647725152�016161� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "dmo_guids.h" int DMO_DEBUG = 0; const GUID IID_IMediaBuffer = { 0x59eff8b9, 0x938c, 0x4a26, { 0x82, 0xf2, 0x95, 0xcb, 0x84, 0xcd, 0xc8, 0x37}}; const GUID IID_IMediaObject = { 0xd8ad0f58, 0x5494, 0x4102, { 0x97, 0xc5, 0xec, 0x79, 0x8e, 0x59, 0xbc, 0xf4}}; const GUID IID_IEnumDMO = { 0x2c3cd98a, 0x2bfa, 0x4a53, { 0x9c, 0x27, 0x52, 0x49, 0xba, 0x64, 0xba, 0x0f}}; const GUID IID_IMediaObjectInPlace = { 0x651b9ad0, 0x0fc7, 0x4aa9, { 0x95, 0x38, 0xd8, 0x99, 0x31, 0x01, 0x07, 0x41}}; const GUID IID_IDMOQualityControl = { 0x65abea96, 0xcf36, 0x453f, { 0xaf, 0x8a, 0x70, 0x5e, 0x98, 0xf1, 0x62, 0x60}}; const GUID IID_IDMOVideoOutputOptimizations = { 0xbe8f4f4e, 0x5b16, 0x4d29, { 0xb3, 0x50, 0x7f, 0x6b, 0x5d, 0x92, 0x98, 0xac}}; const GUID DMOCATEGORY_AUDIO_DECODER = { 0x57f2db8b, 0xe6bb, 0x4513, { 0x9d, 0x43, 0xdc, 0xd2, 0xa6, 0x59, 0x31, 0x25}}; const GUID DMOCATEGORY_AUDIO_ENCODER = { 0x33d9a761, 0x90c8, 0x11d0, { 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86}}; const GUID DMOCATEGORY_VIDEO_DECODER = { 0x4a69b442, 0x28be, 0x4991, { 0x96, 0x9c, 0xb5, 0x00, 0xad, 0xf5, 0xd8, 0xa8}}; const GUID DMOCATEGORY_VIDEO_ENCODER = { 0x33d9a760, 0x90c8, 0x11d0, { 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86}}; const GUID DMOCATEGORY_AUDIO_EFFECT = { 0xf3602b3f, 0x0592, 0x48df, { 0xa4, 0xcd, 0x67, 0x47, 0x21, 0xe7, 0xeb, 0xeb}}; const GUID DMOCATEGORY_VIDEO_EFFECT = { 0xd990ee14, 0x776c, 0x4723, { 0xbe, 0x46, 0x3d, 0xa2, 0xf5, 0x6f, 0x10,0xb9}}; const GUID DMOCATEGORY_AUDIO_CAPTURE_EFFECT = { 0xf665aaba, 0x3e09, 0x4920, { 0xaa, 0x5f, 0x21, 0x98, 0x11, 0x14, 0x8f, 0x09}}; const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = { 0xBF963D80L, 0xC559, 0x11D0, { 0x8A, 0x2B, 0x00, 0xA0, 0xC9, 0x25, 0x5A, 0xC1}}; const GUID DMOCATEGORY_AUDIO_NOISE_SUPPRESS = { 0xe07f903f, 0x62fd, 0x4e60, { 0x8c, 0xdd, 0xde, 0xa7, 0x23, 0x66, 0x65, 0xb5}}; const GUID DMOCATEGORY_AGC = { 0xe88c9ba0l, 0xc557, 0x11d0, { 0x8a, 0x2b, 0x00, 0xa0, 0xc9, 0x25, 0x5a, 0xc1}}; ���������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/dmo_interfaces.h�����������������������������������������������������0000644�0001750�0001750�00000016177�14647725152�017177� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DMO_INTERFACE_H #define DMO_INTERFACE_H #include "dmo.h" /* * IMediaBuffer interface */ typedef struct _IMediaBuffer IMediaBuffer; typedef struct IMediaBuffer_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *SetLength )(IMediaBuffer* This, unsigned long cbLength); HRESULT STDCALL ( *GetMaxLength )(IMediaBuffer* This, /* [out] */ unsigned long *pcbMaxLength); HRESULT STDCALL ( *GetBufferAndLength )(IMediaBuffer* This, /* [out] */ char** ppBuffer, /* [out] */ unsigned long* pcbLength); } IMediaBuffer_vt; struct _IMediaBuffer { IMediaBuffer_vt* vt; }; typedef struct _DMO_OUTPUT_DATA_BUFFER { IMediaBuffer *pBuffer; unsigned long dwStatus; REFERENCE_TIME rtTimestamp; REFERENCE_TIME rtTimelength; } DMO_OUTPUT_DATA_BUFFER; /* * IMediaObject interface */ typedef struct _IMediaObject IMediaObject; typedef struct IMediaObject_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *GetStreamCount )(IMediaObject * This, /* [out] */ unsigned long *pcInputStreams, /* [out] */ unsigned long *pcOutputStreams); HRESULT STDCALL ( *GetInputStreamInfo )(IMediaObject * This, unsigned long dwInputStreamIndex, /* [out] */ unsigned long *pdwFlags); HRESULT STDCALL ( *GetOutputStreamInfo )(IMediaObject * This, unsigned long dwOutputStreamIndex, /* [out] */ unsigned long *pdwFlags); HRESULT STDCALL ( *GetInputType )(IMediaObject * This, unsigned long dwInputStreamIndex, unsigned long dwTypeIndex, /* [out] */ DMO_MEDIA_TYPE *pmt); HRESULT STDCALL ( *GetOutputType )(IMediaObject * This, unsigned long dwOutputStreamIndex, unsigned long dwTypeIndex, /* [out] */ DMO_MEDIA_TYPE *pmt); HRESULT STDCALL ( *SetInputType )(IMediaObject * This, unsigned long dwInputStreamIndex, /* [in] */ const DMO_MEDIA_TYPE *pmt, unsigned long dwFlags); HRESULT STDCALL ( *SetOutputType )(IMediaObject * This, unsigned long dwOutputStreamIndex, /* [in] */ const DMO_MEDIA_TYPE *pmt, unsigned long dwFlags); HRESULT STDCALL ( *GetInputCurrentType )(IMediaObject * This, unsigned long dwInputStreamIndex, /* [out] */ DMO_MEDIA_TYPE *pmt); HRESULT STDCALL ( *GetOutputCurrentType )(IMediaObject * This, unsigned long dwOutputStreamIndex, /* [out] */ DMO_MEDIA_TYPE *pmt); HRESULT STDCALL ( *GetInputSizeInfo )(IMediaObject * This, unsigned long dwInputStreamIndex, /* [out] */ unsigned long *pcbSize, /* [out] */ unsigned long *pcbMaxLookahead, /* [out] */ unsigned long *pcbAlignment); HRESULT STDCALL ( *GetOutputSizeInfo )(IMediaObject * This, unsigned long dwOutputStreamIndex, /* [out] */ unsigned long *pcbSize, /* [out] */ unsigned long *pcbAlignment); HRESULT STDCALL ( *GetInputMaxLatency )(IMediaObject * This, unsigned long dwInputStreamIndex, /* [out] */ REFERENCE_TIME *prtMaxLatency); HRESULT STDCALL ( *SetInputMaxLatency )(IMediaObject * This, unsigned long dwInputStreamIndex, REFERENCE_TIME rtMaxLatency); HRESULT STDCALL ( *Flush )(IMediaObject * This); HRESULT STDCALL ( *Discontinuity )(IMediaObject * This, unsigned long dwInputStreamIndex); HRESULT STDCALL ( *AllocateStreamingResources )(IMediaObject * This); HRESULT STDCALL ( *FreeStreamingResources )(IMediaObject * This); HRESULT STDCALL ( *GetInputStatus )(IMediaObject * This, unsigned long dwInputStreamIndex, /* [out] */ unsigned long *dwFlags); HRESULT STDCALL ( *ProcessInput )(IMediaObject * This, unsigned long dwInputStreamIndex, IMediaBuffer *pBuffer, unsigned long dwFlags, REFERENCE_TIME rtTimestamp, REFERENCE_TIME rtTimelength); HRESULT STDCALL ( *ProcessOutput )(IMediaObject * This, unsigned long dwFlags, unsigned long cOutputBufferCount, /* [size_is][out][in] */ DMO_OUTPUT_DATA_BUFFER *pOutputBuffers, /* [out] */ unsigned long *pdwStatus); HRESULT STDCALL ( *Lock )(IMediaObject * This, long bLock); } IMediaObject_vt; struct _IMediaObject { IMediaObject_vt* vt; }; /* * IEnumDMO interface */ typedef struct _IEnumDMO IEnumDMO; typedef struct IEnumDMO_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *Next )(IEnumDMO * This, unsigned long cItemsToFetch, /* [length_is][size_is][out] */ CLSID *pCLSID, /* [string][length_is][size_is][out] */ WCHAR **Names, /* [out] */ unsigned long *pcItemsFetched); HRESULT STDCALL ( *Skip )(IEnumDMO * This, unsigned long cItemsToSkip); HRESULT STDCALL ( *Reset )(IEnumDMO * This); HRESULT STDCALL ( *Clone )(IEnumDMO * This, /* [out] */ IEnumDMO **ppEnum); } IEnumDMO_vt; struct _IEnumDMO { IEnumDMO_vt* vt; }; /* * IMediaObjectInPlace interface */ typedef struct _IMediaObjectInPlace IMediaObjectInPlace; typedef struct IMediaObjectInPlace_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *Process )(IMediaObjectInPlace * This, /* [in] */ unsigned long ulSize, /* [size_is][out][in] */ BYTE *pData, /* [in] */ REFERENCE_TIME refTimeStart, /* [in] */ unsigned long dwFlags); HRESULT STDCALL ( *Clone )(IMediaObjectInPlace * This, /* [out] */ IMediaObjectInPlace **ppMediaObject); HRESULT STDCALL ( *GetLatency )(IMediaObjectInPlace * This, /* [out] */ REFERENCE_TIME *pLatencyTime); } IMediaObjectInPlace_vt; struct _IMediaObjectInPlace { IMediaObjectInPlace_vt* vt; }; /* * IDMOQualityControl interface */ typedef struct _IDMOQualityControl IDMOQualityControl; typedef struct IDMOQualityControl_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *SetNow )(IDMOQualityControl * This, /* [in] */ REFERENCE_TIME rtNow); HRESULT STDCALL ( *SetStatus )(IDMOQualityControl * This, /* [in] */ unsigned long dwFlags); HRESULT STDCALL ( *GetStatus )(IDMOQualityControl * This, /* [out] */ unsigned long *pdwFlags); } IDMOQualityControl_vt; struct _IDMOQualityControl { IDMOQualityControl_vt* vt; }; /* * IDMOVideoOutputOptimizations interface */ typedef struct _IDMOVideoOutputOptimizations IDMOVideoOutputOptimizations; typedef struct IDMOVideoOutputOptimizations_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *QueryOperationModePreferences )(IDMOVideoOutputOptimizations * This, unsigned long ulOutputStreamIndex, unsigned long *pdwRequestedCapabilities); HRESULT STDCALL ( *SetOperationMode )(IDMOVideoOutputOptimizations * This, unsigned long ulOutputStreamIndex, unsigned long dwEnabledFeatures); HRESULT STDCALL ( *GetCurrentOperationMode )(IDMOVideoOutputOptimizations * This, unsigned long ulOutputStreamIndex, unsigned long *pdwEnabledFeatures); HRESULT STDCALL ( *GetCurrentSampleRequirements )(IDMOVideoOutputOptimizations * This, unsigned long ulOutputStreamIndex, unsigned long *pdwRequestedFeatures); } IDMOVideoOutputOptimizations_vt; struct _IDMOVideoOutputOptimizations { IDMOVideoOutputOptimizations_vt* vt; }; #endif /* DMO_INTERFACE_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/dmo.c����������������������������������������������������������������0000644�0001750�0001750�00000010746�14647725152�014763� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "DMO_Filter.h" #include "driver.h" #include "com.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "win32.h" // printf macro void trapbug(); typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); void DMO_Filter_Destroy(DMO_Filter* This) { if (This->m_pOptim) This->m_pOptim->vt->Release((IUnknown*)This->m_pOptim); if (This->m_pInPlace) This->m_pInPlace->vt->Release((IUnknown*)This->m_pInPlace); if (This->m_pMedia) This->m_pMedia->vt->Release((IUnknown*)This->m_pMedia); free(This); CodecRelease(); } DMO_Filter* DMO_FilterCreate(const char* dllname, const GUID* id, DMO_MEDIA_TYPE* in_fmt, DMO_MEDIA_TYPE* out_fmt) { HRESULT hr = 0; const char* em = NULL; DMO_Filter* This = (DMO_Filter*) malloc(sizeof(DMO_Filter)); if (!This) return NULL; memset(This, 0, sizeof(DMO_Filter)); CodecAlloc(); //This->Start = DS_Filter_Start; //This->Stop = DS_Filter_Stop; for (;;) { GETCLASS func; struct IClassFactory* factory = NULL; struct IUnknown* object = NULL; unsigned int i; unsigned long inputs, outputs; This->m_iHandle = LoadLibraryA(dllname); if (!This->m_iHandle) { em = "could not open DMO DLL"; break; } func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject"); if (!func) { em = "illegal or corrupt DMO DLL"; break; } //trapbug(); hr = func(id, &IID_IClassFactory, (void**)&factory); if (hr || !factory) { em = "no such class object"; break; } hr = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); factory->vt->Release((IUnknown*)factory); if (hr || !object) { em = "class factory failure"; break; } hr = object->vt->QueryInterface(object, &IID_IMediaObject, (void**)&This->m_pMedia); if (hr == 0) { /* query for some extra available interface */ HRESULT r = object->vt->QueryInterface(object, &IID_IMediaObjectInPlace, (void**)&This->m_pInPlace); if (r == 0 && This->m_pInPlace) printf("DMO dll supports InPlace - PLEASE REPORT to developer\n"); r = object->vt->QueryInterface(object, &IID_IDMOVideoOutputOptimizations, (void**)&This->m_pOptim); if (r == 0 && This->m_pOptim) { unsigned long flags; r = This->m_pOptim->vt->QueryOperationModePreferences(This->m_pOptim, 0, &flags); printf("DMO dll supports VO Optimizations %ld %lx\n", r, flags); if (flags & DMO_VOSF_NEEDS_PREVIOUS_SAMPLE) printf("DMO dll might use previous sample when requested\n"); } } object->vt->Release((IUnknown*)object); if (hr || !This->m_pMedia) { em = "object does not provide IMediaObject interface"; break; } hr = This->m_pMedia->vt->SetInputType(This->m_pMedia, 0, in_fmt, 0); if (hr) { em = "input format not accepted"; break; } if (0) { DMO_MEDIA_TYPE dmo; /* VIDEOINFOHEADER* vi; -- not used */ memset(&dmo, 0, sizeof(dmo)); i = This->m_pMedia->vt->GetOutputType(This->m_pMedia, 0, 2, &dmo); printf("GetOutputType %x \n", i); printf("DMO 0x%x (%.4s) 0x%x (%.4s)\n" //printf("DMO 0x%x 0x%x\n" ":: fixszsamp:%d tempcomp:%d sampsz:%ld\n" ":: formtype: 0x%x\n" ":: unk %p cbform: %ld pbform:%p\n", dmo.majortype.f1, (const char*)&dmo.majortype.f1, dmo.subtype.f1, (const char*)&dmo.subtype.f1, dmo.bFixedSizeSamples, dmo.bTemporalCompression, dmo.lSampleSize, dmo.formattype.f1, dmo.pUnk, dmo.cbFormat, dmo.pbFormat ); /* vi = (VIDEOINFOHEADER*) dmo.pbFormat; vi = (VIDEOINFOHEADER*) out_fmt->pbFormat; for (i = 0; i < out_fmt->cbFormat; i++) printf("BYTE %d %02x %02x\n", i, ((uint8_t*)dmo.pbFormat)[i], ((uint8_t*)out_fmt->pbFormat)[i]); */ } hr = This->m_pMedia->vt->SetOutputType(This->m_pMedia, 0, out_fmt, 0); if (hr) { em = "output format no accepted"; break; } inputs = outputs = 0; hr = This->m_pMedia->vt->GetOutputSizeInfo(This->m_pMedia, 0, &inputs, &outputs); printf("GetOutput r=0x%lx size:%ld align:%ld\n", hr, inputs, outputs); // This->m_pMedia->vt->AllocateStreamingResources(This->m_pMedia); hr = This->m_pMedia->vt->GetStreamCount(This->m_pMedia, &inputs, &outputs); printf("StreamCount r=0x%lx %ld %ld\n", hr, inputs, outputs); break; } if (em) { DMO_Filter_Destroy(This); printf("IMediaObject ERROR: %p %s (0x%lx : %ld)\n", em, em ? em : "", hr, hr); This = 0; } return This; } ��������������������������xine-lib-1.2/src/libw32dll/dmo/DMO_VideoDecoder.c���������������������������������������������������0000644�0001750�0001750�00000041706�14647725152�017237� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************** DirectShow Video decoder implementation Copyright 2000 Eugene Kuznetsov (divx@euro.ru) *********************************************************/ #include "DirectShow/guids.h" #include "DirectShow/interfaces.h" #include "registry.h" #ifdef LDT_paranoia #include "../ldt_keeper.h" #endif #ifndef NOAVIFILE_HEADERS #include "videodecoder.h" #else #include "libwin32.h" #endif #include "DMO_Filter.h" #include "DMO_VideoDecoder.h" struct _DMO_VideoDecoder { IVideoDecoder iv; DMO_Filter* m_pDMO_Filter; AM_MEDIA_TYPE m_sOurType, m_sDestType; VIDEOINFOHEADER* m_sVhdr; VIDEOINFOHEADER* m_sVhdr2; int m_Caps;//CAPS m_Caps; // capabilities of DirectShow decoder int m_iLastQuality; // remember last quality as integer int m_iMinBuffers; int m_iMaxAuto; }; //#include "DMO_VideoDecoder.h" #include "../wine/winerror.h" #ifndef NOAVIFILE_HEADERS #define VFW_E_NOT_RUNNING 0x80040226 #include "fourcc.h" #include "except.h" #endif #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> // labs // strcmp((const char*)info.dll,...) is used instead of (... == ...) // so Arpi could use char* pointer in his simplified DMO_VideoDecoder class #define __MODULE__ "DirectShow_VideoDecoder" #define false 0 #define true 1 //int DMO_VideoDecoder_GetCapabilities(DMO_VideoDecoder *this){return this->m_Caps;} typedef struct _ct ct; struct _ct { fourcc_t fcc; unsigned int bits; const GUID* subtype; int cap; }; static ct check[] = { { fccI420, 12, &MEDIASUBTYPE_I420, CAP_I420 }, { fccYV12, 12, &MEDIASUBTYPE_YV12, CAP_YV12 }, { fccYUY2, 16, &MEDIASUBTYPE_YUY2, CAP_YUY2 }, { fccUYVY, 16, &MEDIASUBTYPE_UYVY, CAP_UYVY }, { fccYVYU, 16, &MEDIASUBTYPE_YVYU, CAP_YVYU }, { fccIYUV, 24, &MEDIASUBTYPE_IYUV, CAP_IYUV }, { 8, 8, &MEDIASUBTYPE_RGB8, CAP_NONE }, { 15, 16, &MEDIASUBTYPE_RGB555, CAP_NONE }, { 16, 16, &MEDIASUBTYPE_RGB565, CAP_NONE }, { 24, 24, &MEDIASUBTYPE_RGB24, CAP_NONE }, { 32, 32, &MEDIASUBTYPE_RGB32, CAP_NONE }, { 0, 0, NULL, 0 } }; DMO_VideoDecoder * DMO_VideoDecoder_Open(const char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto) { DMO_VideoDecoder *this; HRESULT result; ct* c; this = malloc(sizeof(DMO_VideoDecoder)); memset( this, 0, sizeof(DMO_VideoDecoder)); this->m_sVhdr2 = 0; this->m_iLastQuality = -1; this->m_iMaxAuto = maxauto; #ifdef LDT_paranoia Setup_LDT_Keeper(); #endif //memset(&m_obh, 0, sizeof(m_obh)); //m_obh.biSize = sizeof(m_obh); /*try*/ { unsigned int bihs; bihs = (format->biSize < (int) sizeof(BITMAPINFOHEADER)) ? (int)sizeof(BITMAPINFOHEADER) : format->biSize; this->iv.m_bh = (BITMAPINFOHEADER*)malloc(bihs); memcpy(this->iv.m_bh, format, bihs); this->iv.m_bh->biSize = bihs; this->iv.m_State = STOP; //this->iv.m_pFrame = 0; this->iv.m_Mode = DIRECT; this->iv.m_iDecpos = 0; this->iv.m_iPlaypos = -1; this->iv.m_fQuality = 0.0f; this->iv.m_bCapable16b = true; bihs += sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER); this->m_sVhdr = (VIDEOINFOHEADER*)malloc(bihs); memset(this->m_sVhdr, 0, bihs); memcpy(&this->m_sVhdr->bmiHeader, this->iv.m_bh, this->iv.m_bh->biSize); this->m_sVhdr->rcSource.left = this->m_sVhdr->rcSource.top = 0; this->m_sVhdr->rcSource.right = this->m_sVhdr->bmiHeader.biWidth; this->m_sVhdr->rcSource.bottom = this->m_sVhdr->bmiHeader.biHeight; //this->m_sVhdr->rcSource.right = 0; //this->m_sVhdr->rcSource.bottom = 0; this->m_sVhdr->rcTarget = this->m_sVhdr->rcSource; this->m_sOurType.majortype = MEDIATYPE_Video; this->m_sOurType.subtype = MEDIATYPE_Video; this->m_sOurType.subtype.f1 = this->m_sVhdr->bmiHeader.biCompression; this->m_sOurType.formattype = FORMAT_VideoInfo; this->m_sOurType.bFixedSizeSamples = false; this->m_sOurType.bTemporalCompression = true; this->m_sOurType.pUnk = 0; this->m_sOurType.cbFormat = bihs; this->m_sOurType.pbFormat = (char*)this->m_sVhdr; this->m_sVhdr2 = (VIDEOINFOHEADER*)(malloc(sizeof(VIDEOINFOHEADER)+12)); memcpy(this->m_sVhdr2, this->m_sVhdr, sizeof(VIDEOINFOHEADER)); memset((char*)this->m_sVhdr2 + sizeof(VIDEOINFOHEADER), 0, 12); this->m_sVhdr2->bmiHeader.biCompression = 0; this->m_sVhdr2->bmiHeader.biBitCount = 24; // memset((char*)this->m_sVhdr2, 0, sizeof(VIDEOINFOHEADER)+12); this->m_sVhdr2->rcTarget = this->m_sVhdr->rcTarget; // this->m_sVhdr2->rcSource = this->m_sVhdr->rcSource; memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); this->m_sDestType.majortype = MEDIATYPE_Video; this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; this->m_sDestType.formattype = FORMAT_VideoInfo; this->m_sDestType.bFixedSizeSamples = true; this->m_sDestType.bTemporalCompression = false; this->m_sDestType.lSampleSize = labs(this->m_sVhdr2->bmiHeader.biWidth*this->m_sVhdr2->bmiHeader.biHeight * ((this->m_sVhdr2->bmiHeader.biBitCount + 7) / 8)); this->m_sVhdr2->bmiHeader.biSizeImage = this->m_sDestType.lSampleSize; this->m_sDestType.pUnk = 0; this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); this->m_sDestType.pbFormat = (char*)this->m_sVhdr2; memset(&this->iv.m_obh, 0, sizeof(this->iv.m_obh)); memcpy(&this->iv.m_obh, this->iv.m_bh, sizeof(this->iv.m_obh) < (unsigned) this->iv.m_bh->biSize ? sizeof(this->iv.m_obh) : (unsigned) this->iv.m_bh->biSize); this->iv.m_obh.biBitCount=24; this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression = 0; //BI_RGB //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) * ((this->iv.m_obh.biBitCount + 7) / 8); this->m_pDMO_Filter = DMO_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); if (!this->m_pDMO_Filter) { printf("Failed to create DMO filter\n"); free(this->m_sVhdr); free(this->m_sVhdr2); free(this); return 0; } if (!flip) { this->iv.m_obh.biHeight *= -1; this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; // result = this->m_pDMO_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDMO_Filter->m_pOutputPin, &this->m_sDestType); result = this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, DMO_SET_TYPEF_TEST_ONLY); if (result) { printf("Decoder does not support upside-down RGB frames\n"); this->iv.m_obh.biHeight *= -1; this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; } } memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh) ); switch (this->iv.m_bh->biCompression) { #if 0 case fccDIV3: case fccDIV4: case fccDIV5: case fccDIV6: case fccMP42: case fccWMV2: //YV12 seems to be broken for DivX :-) codec // case fccIV50: //produces incorrect picture //m_Caps = (CAPS) (m_Caps & ~CAP_YV12); //m_Caps = CAP_UYVY;//CAP_YUY2; // | CAP_I420; //m_Caps = CAP_I420; this->m_Caps = (CAP_YUY2 | CAP_UYVY); break; #endif default: this->m_Caps = CAP_NONE; printf("Decoder supports the following YUV formats: "); for (c = check; c->bits; c++) { this->m_sVhdr2->bmiHeader.biBitCount = c->bits; this->m_sVhdr2->bmiHeader.biCompression = c->fcc; this->m_sDestType.subtype = *c->subtype; //result = this->m_pDMO_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDMO_Filter->m_pOutputPin, &this->m_sDestType); result = this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, DMO_SET_TYPEF_TEST_ONLY); if (!result) { this->m_Caps = (this->m_Caps | c->cap); printf("%.4s ", (char*) &c->fcc); } } printf("\n"); } if (this->m_Caps != CAP_NONE) printf("Decoder is capable of YUV output (flags 0x%x)\n", (int)this->m_Caps); this->m_sVhdr2->bmiHeader.biBitCount = 24; this->m_sVhdr2->bmiHeader.biCompression = 0; this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; this->m_iMinBuffers = this->iv.VBUFSIZE; } /*catch (FatalError& error) { delete[] m_sVhdr; delete[] m_sVhdr2; delete m_pDMO_Filter; throw; }*/ return this; } void DMO_VideoDecoder_Destroy(DMO_VideoDecoder *this) { DMO_VideoDecoder_StopInternal(this); this->iv.m_State = STOP; free(this->m_sVhdr); free(this->m_sVhdr2); DMO_Filter_Destroy(this->m_pDMO_Filter); } void DMO_VideoDecoder_StartInternal(DMO_VideoDecoder *this) { #if 0 ALLOCATOR_PROPERTIES props, props1; Debug printf("DMO_VideoDecoder_StartInternal\n"); //cout << "DSSTART" << endl; this->m_pDMO_Filter->Start(this->m_pDMO_Filter); props.cBuffers = 1; props.cbBuffer = this->m_sDestType.lSampleSize; //don't know how to do this correctly props.cbAlign = props.cbPrefix = 0; this->m_pDMO_Filter->m_pAll->vt->SetProperties(this->m_pDMO_Filter->m_pAll, &props, &props1); this->m_pDMO_Filter->m_pAll->vt->Commit(this->m_pDMO_Filter->m_pAll); #endif this->iv.m_State = START; } void DMO_VideoDecoder_StopInternal(DMO_VideoDecoder *this) { #if 0 this->m_pDMO_Filter->Stop(this->m_pDMO_Filter); //??? why was this here ??? m_pOurOutput->SetFramePointer(0); #else (void)this; #endif } int DMO_VideoDecoder_DecodeInternal(DMO_VideoDecoder *this, const void* src, int size, int is_keyframe, char* imdata) { // IMediaSample* sample = 0; int result; unsigned long status; // to be ignored by M$ specs DMO_OUTPUT_DATA_BUFFER db; CMediaBuffer* bufferin; //+ uint8_t* imdata = dest ? dest->Data() : 0; Debug printf("DMO_VideoDecoder_DecodeInternal(%p,%p,%d,%d,%p)\n",this,src,size,is_keyframe,imdata); // this->m_pDMO_Filter->m_pAll->vt->GetBuffer(this->m_pDMO_Filter->m_pAll, &sample, 0, 0, 0); // if (!sample) // { // Debug printf("ERROR: null sample\n"); // return -1; // } #ifdef LDT_paranoia Setup_FS_Segment(); #endif bufferin = CMediaBufferCreate(size, (void*)src, size, 0); result = this->m_pDMO_Filter->m_pMedia->vt->ProcessInput(this->m_pDMO_Filter->m_pMedia, 0, (IMediaBuffer*)bufferin, (is_keyframe) ? DMO_INPUT_DATA_BUFFERF_SYNCPOINT : 0, 0, 0); ((IMediaBuffer*)bufferin)->vt->Release((IUnknown*)bufferin); if (result != S_OK) { /* something for process */ if (result != S_FALSE) printf("ProcessInputError r:0x%x=%d (keyframe: %d)\n", result, result, is_keyframe); else printf("ProcessInputError FALSE ?? (keyframe: %d)\n", is_keyframe); return size; } db.rtTimestamp = 0; db.rtTimelength = 0; db.dwStatus = 0; db.pBuffer = (IMediaBuffer*) CMediaBufferCreate(this->m_sDestType.lSampleSize, imdata, 0, 0); result = this->m_pDMO_Filter->m_pMedia->vt->ProcessOutput(this->m_pDMO_Filter->m_pMedia, (imdata) ? 0 : DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER, 1, &db, &status); //m_pDMO_Filter->m_pMedia->vt->Lock(m_pDMO_Filter->m_pMedia, 0); if ((unsigned)result == DMO_E_NOTACCEPTING) printf("ProcessOutputError: Not accepting\n"); else if (result) printf("ProcessOutputError: r:0x%x=%d %ld stat:%ld\n", result, result, status, db.dwStatus); ((IMediaBuffer*)db.pBuffer)->vt->Release((IUnknown*)db.pBuffer); //int r = m_pDMO_Filter->m_pMedia->vt->Flush(m_pDMO_Filter->m_pMedia); //printf("FLUSH %d\n", r); return 0; } /* * bits == 0 - leave unchanged */ //int SetDestFmt(DMO_VideoDecoder * this, int bits = 24, fourcc_t csp = 0); int DMO_VideoDecoder_SetDestFmt(DMO_VideoDecoder *this, int bits, unsigned int csp) { HRESULT result; int should_test=1; Debug printf("DMO_VideoDecoder_SetDestFmt (%p, %d, %d)\n",this,bits,(int)csp); /* if (!CImage::Supported(csp, bits)) return -1; */ // BitmapInfo temp = m_obh; if (!csp) // RGB { int ok = true; switch (bits) { case 15: this->m_sDestType.subtype = MEDIASUBTYPE_RGB555; break; case 16: this->m_sDestType.subtype = MEDIASUBTYPE_RGB565; break; case 24: this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; break; case 32: this->m_sDestType.subtype = MEDIASUBTYPE_RGB32; break; default: ok = false; break; } if (ok) { this->iv.m_obh.biBitCount=bits; if( bits == 15 || bits == 16 ) { this->iv.m_obh.biSize=sizeof(BITMAPINFOHEADER)+12; this->iv.m_obh.biCompression=3;//BI_BITFIELDS this->iv.m_obh.biSizeImage=abs((int)(2*this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)); } if( bits == 16 ) { this->iv.m_obh.colors[0]=0xF800; this->iv.m_obh.colors[1]=0x07E0; this->iv.m_obh.colors[2]=0x001F; } else if ( bits == 15 ) { this->iv.m_obh.colors[0]=0x7C00; this->iv.m_obh.colors[1]=0x03E0; this->iv.m_obh.colors[2]=0x001F; } else { this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression = 0; //BI_RGB //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) * ((this->iv.m_obh.biBitCount + 7) / 8); } } //.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); } else { // YUV int ok = true; switch (csp) { case fccYUY2: this->m_sDestType.subtype = MEDIASUBTYPE_YUY2; break; case fccYV12: this->m_sDestType.subtype = MEDIASUBTYPE_YV12; break; case fccIYUV: this->m_sDestType.subtype = MEDIASUBTYPE_IYUV; break; case fccI420: this->m_sDestType.subtype = MEDIASUBTYPE_I420; break; case fccUYVY: this->m_sDestType.subtype = MEDIASUBTYPE_UYVY; break; case fccYVYU: this->m_sDestType.subtype = MEDIASUBTYPE_YVYU; break; case fccYVU9: this->m_sDestType.subtype = MEDIASUBTYPE_YVU9; default: ok = false; break; } if (ok) { if (csp != 0 && csp != 3 && this->iv.m_obh.biHeight > 0) this->iv.m_obh.biHeight *= -1; // YUV formats uses should have height < 0 this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression=csp; this->iv.m_obh.biBitCount=bits; this->iv.m_obh.biSizeImage=labs(this->iv.m_obh.biBitCount* this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)>>3; } } this->m_sDestType.lSampleSize = this->iv.m_obh.biSizeImage; memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_obh, sizeof(this->iv.m_obh)); this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if (this->m_sVhdr2->bmiHeader.biCompression == 3) this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; else this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); switch(csp) { case fccYUY2: if(!(this->m_Caps & CAP_YUY2)) should_test=false; break; case fccYV12: if(!(this->m_Caps & CAP_YV12)) should_test=false; break; case fccIYUV: if(!(this->m_Caps & CAP_IYUV)) should_test=false; break; case fccI420: if(!(this->m_Caps & CAP_I420)) should_test=false; break; case fccUYVY: if(!(this->m_Caps & CAP_UYVY)) should_test=false; break; case fccYVYU: if(!(this->m_Caps & CAP_YVYU)) should_test=false; break; case fccYVU9: if(!(this->m_Caps & CAP_YVU9)) should_test=false; break; } #ifdef LDT_paranoia Setup_FS_Segment(); #endif // if(should_test) // result = this->m_pDMO_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDMO_Filter->m_pOutputPin, &this->m_sDestType); // else // result = -1; // test accept if(!this->m_pDMO_Filter) return 0; result = this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, DMO_SET_TYPEF_TEST_ONLY); if (result != 0) { if (csp) printf("Warning: unsupported colour space\n"); else printf("Warning: unsupported bit depth\n"); this->m_sDestType.lSampleSize = this->iv.m_decoder.biSizeImage; memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_decoder, sizeof(this->iv.m_decoder)); this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if (this->m_sVhdr2->bmiHeader.biCompression == 3) this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; else this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); return -1; } memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh)); // m_obh=temp; // if(csp) // m_obh.biBitCount=BitmapInfo::BitCount(csp); this->iv.m_bh->biBitCount = bits; //DMO_VideoDecoder_Restart(this); this->m_pDMO_Filter->m_pMedia->vt->SetOutputType(this->m_pDMO_Filter->m_pMedia, 0, &this->m_sDestType, 0); return 0; } int DMO_VideoDecoder_SetDirection(DMO_VideoDecoder *this, int d) { this->iv.m_obh.biHeight = (d) ? this->iv.m_bh->biHeight : -this->iv.m_bh->biHeight; this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; return 0; } ����������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/DMO_VideoDecoder.h���������������������������������������������������0000644�0001750�0001750�00000001630�14647725152�017234� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef AVIFILE_DMO_VIDEODECODER_H #define AVIFILE_DMO_VIDEODECODER_H typedef struct _DMO_VideoDecoder DMO_VideoDecoder; int DMO_VideoDecoder_GetCapabilities(DMO_VideoDecoder *this); DMO_VideoDecoder * DMO_VideoDecoder_Open(const char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto); void DMO_VideoDecoder_Destroy(DMO_VideoDecoder *this); void DMO_VideoDecoder_StartInternal(DMO_VideoDecoder *this); void DMO_VideoDecoder_StopInternal(DMO_VideoDecoder *this); int DMO_VideoDecoder_DecodeInternal(DMO_VideoDecoder *this, const void* src, int size, int is_keyframe, char* pImage); /* * bits == 0 - leave unchanged */ //int SetDestFmt(DMO_VideoDecoder * this, int bits = 24, fourcc_t csp = 0); int DMO_VideoDecoder_SetDestFmt(DMO_VideoDecoder *this, int bits, unsigned int csp); int DMO_VideoDecoder_SetDirection(DMO_VideoDecoder *this, int d); #endif /* AVIFILE_DMO_VIDEODECODER_H */ ��������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/dmo.h����������������������������������������������������������������0000644�0001750�0001750�00000003415�14647725152�014763� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DMO_H #define DMO_H /* * * Definition of important DMO interfaces. * Created using freely-available DirectX 8.1 SDK * ( http://msdn.microsoft.com ) * */ #include "DirectShow/iunk.h" #include "DirectShow/guids.h" typedef AM_MEDIA_TYPE DMO_MEDIA_TYPE; enum _DMO_INPUT_DATA_BUFFER_FLAGS { DMO_INPUT_DATA_BUFFERF_SYNCPOINT = 0x1, DMO_INPUT_DATA_BUFFERF_TIME = 0x2, DMO_INPUT_DATA_BUFFERF_TIMELENGTH = 0x4 }; enum _DMO_OUTPUT_DATA_BUFFER_FLAGS { DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT = 0x1, DMO_OUTPUT_DATA_BUFFERF_TIME = 0x2, DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH = 0x4, DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE = 0x1000000 }; enum _DMO_INPUT_STATUS_FLAGS { DMO_INPUT_STATUSF_ACCEPT_DATA = 0x1 }; enum _DMO_INPUT_STREAM_INFO_FLAGS { DMO_INPUT_STREAMF_WHOLE_SAMPLES = 0x1, DMO_INPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER = 0x2, DMO_INPUT_STREAMF_FIXED_SAMPLE_SIZE = 0x4, DMO_INPUT_STREAMF_HOLDS_BUFFERS = 0x8 }; enum _DMO_OUTPUT_STREAM_INFO_FLAGS { DMO_OUTPUT_STREAMF_WHOLE_SAMPLES = 0x1, DMO_OUTPUT_STREAMF_SINGLE_SAMPLE_PER_BUFFER = 0x2, DMO_OUTPUT_STREAMF_FIXED_SAMPLE_SIZE = 0x4, DMO_OUTPUT_STREAMF_DISCARDABLE = 0x8, DMO_OUTPUT_STREAMF_OPTIONAL = 0x10 }; enum _DMO_SET_TYPE_FLAGS { DMO_SET_TYPEF_TEST_ONLY = 0x1, DMO_SET_TYPEF_CLEAR = 0x2 }; enum _DMO_PROCESS_OUTPUT_FLAGS { DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER = 0x1 }; enum _DMO_VIDEO_OUTPUT_STREAM_FLAGS { DMO_VOSF_NEEDS_PREVIOUS_SAMPLE = 0x1 }; /* MediaErr.h */ #define DMO_E_INVALIDSTREAMINDEX 0x80040201 #define DMO_E_INVALIDTYPE 0x80040202 #define DMO_E_TYPE_NOT_SET 0x80040203 #define DMO_E_NOTACCEPTING 0x80040204 #define DMO_E_TYPE_NOT_ACCEPTED 0x80040205 #define DMO_E_NO_MORE_ITEMS 0x80040206 #endif /* DMO_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/buffer.c�������������������������������������������������������������0000644�0001750�0001750�00000005625�14647725152�015455� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "DMO_Filter.h" #include "wine/winerror.h" #include "wine/windef.h" #include <stdio.h> #include <string.h> #include <stdlib.h> struct _CMediaBuffer { IMediaBuffer_vt* vt; DECLARE_IUNKNOWN(); GUID interfaces[2]; void* mem; unsigned long len; unsigned long maxlen; int freemem; }; static HRESULT STDCALL CMediaBuffer_SetLength(IMediaBuffer* This, unsigned long cbLength) { CMediaBuffer* cmb = (CMediaBuffer*) This; Debug printf("CMediaBuffer_SetLength(%p) called (%ld, %ld)\n", This, cbLength, cmb->maxlen); if (cbLength > cmb->maxlen) return E_INVALIDARG; cmb->len = cbLength; return S_OK; } static HRESULT STDCALL CMediaBuffer_GetMaxLength(IMediaBuffer* This, /* [out] */ unsigned long *pcbMaxLength) { CMediaBuffer* cmb = (CMediaBuffer*) This; Debug printf("CMediaBuffer_GetMaxLength(%p) called -> %ld\n", This, cmb->maxlen); if (!pcbMaxLength) return E_POINTER; *pcbMaxLength = cmb->maxlen; return S_OK; } static HRESULT STDCALL CMediaBuffer_GetBufferAndLength(IMediaBuffer* This, /* [out] */ char** ppBuffer, /* [out] */ unsigned long* pcbLength) { CMediaBuffer* cmb = (CMediaBuffer*) This; Debug printf("CMediaBuffer_GetBufferAndLength(%p) called -> %p %ld\n", This, cmb->mem, cmb->len); if (!ppBuffer && !pcbLength) return E_POINTER; if (ppBuffer) *ppBuffer = cmb->mem; if (pcbLength) *pcbLength = cmb->len; return S_OK; } static void CMediaBuffer_Destroy(CMediaBuffer* This) { Debug printf("CMediaBuffer_Destroy(%p) called\n", This); if (This->freemem) free(This->mem); free(This->vt); free(This); } IMPLEMENT_IUNKNOWN(CMediaBuffer) CMediaBuffer* CMediaBufferCreate(unsigned long maxlen, void* mem, unsigned long len, int copy) { CMediaBuffer* This = (CMediaBuffer*) malloc(sizeof(CMediaBuffer)); if (!This) return NULL; This->vt = (IMediaBuffer_vt*) malloc(sizeof(IMediaBuffer_vt)); if (!This->vt) { CMediaBuffer_Destroy(This); return NULL; } This->refcount = 1; This->len = len; This->maxlen = maxlen; This->freemem = 0; This->mem = mem; if (copy) /* make a private copy of data */ This->mem = 0; if (This->mem == NULL) { if (This->maxlen) { This->mem = malloc(This->maxlen); if (!This->mem) { CMediaBuffer_Destroy(This); return NULL; } This->freemem = 1; if (copy) memcpy(This->mem, mem, This->len); } } This->vt->QueryInterface = CMediaBuffer_QueryInterface; This->vt->AddRef = CMediaBuffer_AddRef; This->vt->Release = CMediaBuffer_Release; This->vt->SetLength = CMediaBuffer_SetLength; This->vt->GetMaxLength = CMediaBuffer_GetMaxLength; This->vt->GetBufferAndLength = CMediaBuffer_GetBufferAndLength; This->interfaces[0] = IID_IUnknown; This->interfaces[1] = IID_IMediaBuffer; return This; } �����������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/dmo/DMO_AudioDecoder.c���������������������������������������������������0000644�0001750�0001750�00000012536�14647725152�017231� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************** DirectShow audio decoder Copyright 2001 Eugene Kuznetsov (divx@euro.ru) *********************************************************/ #ifndef NOAVIFILE_HEADERS #include "audiodecoder.h" #include "except.h" #else #include "libwin32.h" #ifdef LDT_paranoia #include "ldt_keeper.h" #endif #endif #include "DMO_Filter.h" #include "DMO_AudioDecoder.h" struct _DMO_AudioDecoder { DMO_MEDIA_TYPE m_sOurType, m_sDestType; DMO_Filter* m_pDMO_Filter; char* m_sVhdr; char* m_sVhdr2; int m_iFlushed; }; #include "DMO_AudioDecoder.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #define __MODULE__ "DirectShow audio decoder" typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**); extern void print_wave_header(WAVEFORMATEX *h); DMO_AudioDecoder * DMO_AudioDecoder_Open(const char* dllname, GUID* guid, WAVEFORMATEX* wf,int out_channels) //DMO_AudioDecoder * DMO_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf) { DMO_AudioDecoder *this; int sz; WAVEFORMATEX* pWF; #ifdef LDT_paranoia Setup_LDT_Keeper(); Setup_FS_Segment(); #endif this = malloc(sizeof(DMO_AudioDecoder)); this->m_iFlushed=1; sz = 18 + wf->cbSize; this->m_sVhdr = malloc(sz); memcpy(this->m_sVhdr, wf, sz); this->m_sVhdr2 = malloc(18); memcpy(this->m_sVhdr2, this->m_sVhdr, 18); pWF = (WAVEFORMATEX*)this->m_sVhdr2; pWF->wFormatTag = 1; pWF->wBitsPerSample = 16; pWF->nChannels = out_channels; pWF->nBlockAlign = 2*pWF->nChannels; //pWF->nChannels * (pWF->wBitsPerSample + 7) / 8; pWF->nAvgBytesPerSec = pWF->nBlockAlign * pWF->nSamplesPerSec; pWF->cbSize = 0; memset(&this->m_sOurType, 0, sizeof(this->m_sOurType)); this->m_sOurType.majortype=MEDIATYPE_Audio; this->m_sOurType.subtype=MEDIASUBTYPE_PCM; this->m_sOurType.subtype.f1=wf->wFormatTag; this->m_sOurType.formattype=FORMAT_WaveFormatEx; this->m_sOurType.lSampleSize=wf->nBlockAlign; this->m_sOurType.bFixedSizeSamples=1; this->m_sOurType.bTemporalCompression=0; this->m_sOurType.cbFormat=sz; this->m_sOurType.pbFormat=this->m_sVhdr; memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); this->m_sDestType.majortype=MEDIATYPE_Audio; this->m_sDestType.subtype=MEDIASUBTYPE_PCM; this->m_sDestType.formattype=FORMAT_WaveFormatEx; this->m_sDestType.bFixedSizeSamples=1; this->m_sDestType.bTemporalCompression=0; this->m_sDestType.lSampleSize=pWF->nBlockAlign; this->m_sDestType.cbFormat=18; //pWF->cbSize; this->m_sDestType.pbFormat=this->m_sVhdr2; #if 0 print_wave_header((WAVEFORMATEX *)this->m_sVhdr); print_wave_header((WAVEFORMATEX *)this->m_sVhdr2); #endif this->m_pDMO_Filter = DMO_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); if( !this->m_pDMO_Filter ) { free(this->m_sVhdr); free(this->m_sVhdr2); free(this); return NULL; } return this; } void DMO_AudioDecoder_Destroy(DMO_AudioDecoder *this) { free(this->m_sVhdr); free(this->m_sVhdr2); DMO_Filter_Destroy(this->m_pDMO_Filter); free(this); } int DMO_AudioDecoder_Convert(DMO_AudioDecoder *this, const void* in_data, unsigned int in_size, void* out_data, unsigned int out_size, unsigned int* size_read, unsigned int* size_written) { DMO_OUTPUT_DATA_BUFFER db; CMediaBuffer* bufferin; unsigned long written = 0; unsigned long read = 0; int r = 0; if (!in_data || !out_data) return -1; #ifdef LDT_paranoia Setup_FS_Segment(); #endif //m_pDMO_Filter->m_pMedia->vt->Lock(m_pDMO_Filter->m_pMedia, 1); bufferin = CMediaBufferCreate(in_size, (void*)in_data, in_size, 1); r = this->m_pDMO_Filter->m_pMedia->vt->ProcessInput(this->m_pDMO_Filter->m_pMedia, 0, (IMediaBuffer*)bufferin, (this->m_iFlushed) ? DMO_INPUT_DATA_BUFFERF_SYNCPOINT : 0, 0, 0); if (r == 0){ ((IMediaBuffer*)bufferin)->vt->GetBufferAndLength((IMediaBuffer*)bufferin, 0, &read); this->m_iFlushed = 0; } ((IMediaBuffer*)bufferin)->vt->Release((IUnknown*)bufferin); //printf("RESULTA: %d 0x%x %ld %d %d\n", r, r, read, m_iFlushed, out_size); if (r == 0 || (unsigned)r == DMO_E_NOTACCEPTING){ unsigned long status = 0; /* something for process */ db.rtTimestamp = 0; db.rtTimelength = 0; db.dwStatus = 0; db.pBuffer = (IMediaBuffer*) CMediaBufferCreate(out_size, out_data, 0, 0); //printf("OUTSIZE %d\n", out_size); r = this->m_pDMO_Filter->m_pMedia->vt->ProcessOutput(this->m_pDMO_Filter->m_pMedia, 0, 1, &db, &status); ((IMediaBuffer*)db.pBuffer)->vt->GetBufferAndLength((IMediaBuffer*)db.pBuffer, 0, &written); ((IMediaBuffer*)db.pBuffer)->vt->Release((IUnknown*)db.pBuffer); //printf("RESULTB: %d 0x%x %ld\n", r, r, written); //printf("Converted %d -> %d\n", in_size, out_size); } else if (in_size > 0) printf("ProcessInputError r:0x%x=%d\n", r, r); if (size_read) *size_read = read; if (size_written) *size_written = written; return r; } int DMO_AudioDecoder_GetSrcSize(DMO_AudioDecoder *this, int dest_size) { (void)dest_size; // unsigned long inputs, outputs; // Setup_FS_Segment(); // this->m_pDMO_Filter->m_pMedia->vt->GetOutputSizeInfo(this->m_pDMO_Filter->m_pMedia, 0, &inputs, &outputs); return ((WAVEFORMATEX*)this->m_sVhdr)->nBlockAlign*4; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/��������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014213� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/basetsd.h�����������������������������������������������������������0000644�0001750�0001750�00000006310�14647725152�016011� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Compilers that uses ILP32, LP64 or P64 type models * for both Win32 and Win64 are supported by this file. */ #ifndef __WINE_BASETSD_H #define __WINE_BASETSD_H #ifdef __WINE__ #include "config.h" #endif /* defined(__WINE__) */ #ifdef __cplusplus extern "C" { #endif /* defined(__cplusplus) */ /* * Win32 was easy to implement under Unix since most (all?) 32-bit * Unices uses the same type model (ILP32) as Win32, where int, long * and pointer are 32-bit. * * Win64, however, will cause some problems when implemented under Unix. * Linux/{Alpha, Sparc64} and most (all?) other 64-bit Unices uses * the LP64 type model where int is 32-bit and long and pointer are * 64-bit. Win64 on the other hand uses the P64 (sometimes called LLP64) * type model where int and long are 32 bit and pointer is 64-bit. */ /* Type model indepent typedefs */ #ifndef __ICC typedef char __int8; typedef short __int16; typedef int __int32; typedef long long __int64; #endif typedef unsigned char __uint8; typedef unsigned short __uint16; typedef unsigned int __uint32; typedef unsigned long long __uint64; #if defined(_WIN64) typedef __uint32 __ptr32; typedef void *__ptr64; #else /* FIXME: defined(_WIN32) */ typedef void *__ptr32; typedef __uint64 __ptr64; #endif /* Always signed and 32 bit wide */ typedef __int32 LONG32; //typedef __int32 INT32; typedef LONG32 *PLONG32; //typedef INT32 *PINT32; /* Always unsigned and 32 bit wide */ typedef __uint32 ULONG32; typedef __uint32 DWORD32; typedef __uint32 UINT32; typedef ULONG32 *PULONG32; typedef DWORD32 *PDWORD32; typedef UINT32 *PUINT32; /* Always signed and 64 bit wide */ typedef __int64 LONG64; typedef __int64 INT64; typedef LONG64 *PLONG64; typedef INT64 *PINT64; /* Always unsigned and 64 bit wide */ typedef __uint64 ULONG64; typedef __uint64 DWORD64; typedef __uint64 UINT64; typedef ULONG64 *PULONG64; typedef DWORD64 *PDWORD64; typedef UINT64 *PUINT64; /* Win32 or Win64 dependent typedef/defines. */ #ifdef _WIN64 typedef __int64 INT_PTR, *PINT_PTR; typedef __uint64 UINT_PTR, *PUINT_PTR; #define MAXINT_PTR 0x7fffffffffffffff #define MININT_PTR 0x8000000000000000 #define MAXUINT_PTR 0xffffffffffffffff typedef __int32 HALF_PTR, *PHALF_PTR; typedef __int32 UHALF_PTR, *PUHALF_PTR; #define MAXHALF_PTR 0x7fffffff #define MINHALF_PTR 0x80000000 #define MAXUHALF_PTR 0xffffffff typedef __int64 LONG_PTR, *PLONG_PTR; typedef __uint64 ULONG_PTR, *PULONG_PTR; typedef __uint64 DWORD_PTR, *PDWORD_PTR; #else /* FIXME: defined(_WIN32) */ typedef __int32 INT_PTR, *PINT_PTR; typedef __uint32 UINT_PTR, *PUINT_PTR; #define MAXINT_PTR 0x7fffffff #define MININT_PTR 0x80000000 #define MAXUINT_PTR 0xffffffff typedef __int16 HALF_PTR, *PHALF_PTR; typedef __uint16 UHALF_PTR, *PUHALF_PTR; #define MAXUHALF_PTR 0xffff #define MAXHALF_PTR 0x7fff #define MINHALF_PTR 0x8000 typedef __int32 LONG_PTR, *PLONG_PTR; typedef __uint32 ULONG_PTR, *PULONG_PTR; typedef __uint32 DWORD_PTR, *PDWORD_PTR; #endif /* defined(_WIN64) || defined(_WIN32) */ typedef INT_PTR SSIZE_T, *PSSIZE_T; typedef UINT_PTR SIZE_T, *PSIZE_T; #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ #endif /* !defined(__WINE_BASETSD_H) */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/debugtools.h��������������������������������������������������������0000644�0001750�0001750�00000006041�14647725152�016534� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #ifndef __WINE_DEBUGTOOLS_H #define __WINE_DEBUGTOOLS_H //#ifdef __WINE__ /* Debugging interface is internal to Wine */ #include <stdarg.h> #include "config.h" #include "windef.h" #include <xine/compat.h> struct _GUID; #ifndef TRACE #ifdef LOG # define TRACE __vprintf #else # define TRACE(...) #endif #endif #ifndef dbg_printf #ifdef LOG # define dbg_printf __vprintf #else # define dbg_printf(...) #endif #endif /* Internal definitions (do not use these directly) */ enum __DEBUG_CLASS { __DBCL_FIXME, __DBCL_ERR, __DBCL_WARN, __DBCL_TRACE, __DBCL_COUNT }; #ifndef NO_TRACE_MSGS # define __GET_DEBUGGING_trace(dbch) ((dbch)[0] & (1 << __DBCL_TRACE)) #else # define __GET_DEBUGGING_trace(dbch) 0 #endif #ifndef NO_DEBUG_MSGS # define __GET_DEBUGGING_warn(dbch) ((dbch)[0] & (1 << __DBCL_WARN)) # define __GET_DEBUGGING_fixme(dbch) ((dbch)[0] & (1 << __DBCL_FIXME)) #else # define __GET_DEBUGGING_warn(dbch) 0 # define __GET_DEBUGGING_fixme(dbch) 0 #endif /* define error macro regardless of what is configured */ #define __GET_DEBUGGING_err(dbch) ((dbch)[0] & (1 << __DBCL_ERR)) #define __GET_DEBUGGING(dbcl,dbch) __GET_DEBUGGING_##dbcl(dbch) #define __SET_DEBUGGING(dbcl,dbch,on) \ ((on) ? ((dbch)[0] |= 1 << (dbcl)) : ((dbch)[0] &= ~(1 << (dbcl)))) #define __DPRINTF(dbcl,dbch) \ (!__GET_DEBUGGING(dbcl,(dbch)) || (dbg_header_##dbcl((dbch),__XINE_FUNCTION__),0)) ? \ (void)0 : (void)dbg_printf /* Exported definitions and macros */ /* These function return a printable version of a string, including quotes. The string will be valid for some time, but not indefinitely as strings are re-used. */ extern LPCSTR debugstr_an (LPCSTR s, int n); extern LPCSTR debugstr_wn (LPCWSTR s, int n); extern LPCSTR debugres_a (LPCSTR res); extern LPCSTR debugres_w (LPCWSTR res); extern LPCSTR debugstr_guid( const struct _GUID *id ); extern LPCSTR debugstr_hex_dump (const void *ptr, int len); extern int dbg_header_err( const char *dbg_channel, const char *func ); extern int dbg_header_warn( const char *dbg_channel, const char *func ); extern int dbg_header_fixme( const char *dbg_channel, const char *func ); extern int dbg_header_trace( const char *dbg_channel, const char *func ); extern int dbg_vprintf( const char *format, va_list args ); #if 0 /* causes undefined symbols */ static inline LPCSTR debugstr_a( LPCSTR s ) { return debugstr_an( s, 80 ); } static inline LPCSTR debugstr_w( LPCWSTR s ) { return debugstr_wn( s, 80 ); } #endif #if 0 /* dbg_printf already defined as a macro */ extern int dbg_printf(const char *format, ...) XINE_FORMAT_PRINTF(1,2); #endif #define TRACE_(X) TRACE #define WARN_(X) TRACE #define WARN TRACE #define ERR_(X) printf #define ERR printf #define FIXME_(X) TRACE #define FIXME TRACE #define TRACE_ON(X) 1 #define ERR_ON(X) 1 #define DECLARE_DEBUG_CHANNEL(ch) \ extern char dbch_##ch[]; #define DEFAULT_DEBUG_CHANNEL(ch) \ extern char dbch_##ch[]; static char * const __dbch_default = dbch_##ch; #define DPRINTF dbg_printf #define MESSAGE dbg_printf //#endif /* __WINE__ */ #endif /* __WINE_DEBUGTOOLS_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/resource.h����������������������������������������������������������0000644�0001750�0001750�00000000272�14647725152�016214� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef wine_resource_h #define wine_resource_h #include "winbase.h" extern INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen ); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/msacm.h�������������������������������������������������������������0000644�0001750�0001750�00000066265�14647725152�015503� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * msacm.h - Declarations for MSACM */ #ifndef __WINE_MSACM_H #define __WINE_MSACM_H #include "windef.h" #include "driver.h" #include "mmreg.h" #ifdef __cplusplus extern "C" { #endif /* defined(__cplusplus) */ //typedef WORD VERSION; /* major (high byte), minor (low byte) */ typedef UINT16 MMVERSION16; typedef UINT MMVERSION; typedef UINT16 MCIDEVICEID16; typedef UINT MCIDEVICEID; typedef UINT16 MMRESULT16; typedef UINT MMRESULT; typedef DWORD FOURCC; /* a four character code */ #define WAVE_FORMAT_PCM 1 /*********************************************************************** * Defines/Enums */ #define ACMERR_BASE 512 #define ACMERR_NOTPOSSIBLE (ACMERR_BASE + 0) #define ACMERR_BUSY (ACMERR_BASE + 1) #define ACMERR_UNPREPARED (ACMERR_BASE + 2) #define ACMERR_CANCELED (ACMERR_BASE + 3) #define MM_ACM_OPEN MM_STREAM_OPEN #define MM_ACM_CLOSE MM_STREAM_CLOSE #define MM_ACM_DONE MM_STREAM_DONE #define ACM_DRIVERADDF_FUNCTION 0x00000003L #define ACM_DRIVERADDF_NOTIFYHWND 0x00000004L #define ACM_DRIVERADDF_TYPEMASK 0x00000007L #define ACM_DRIVERADDF_LOCAL 0x00000000L #define ACM_DRIVERADDF_GLOBAL 0x00000008L #define ACMDRIVERDETAILS_SHORTNAME_CHARS 32 #define ACMDRIVERDETAILS_LONGNAME_CHARS 128 #define ACMDRIVERDETAILS_COPYRIGHT_CHARS 80 #define ACMDRIVERDETAILS_LICENSING_CHARS 128 #define ACMDRIVERDETAILS_FEATURES_CHARS 512 #define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC mmioFOURCC('a', 'u', 'd', 'c') #define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED mmioFOURCC('\0', '\0', '\0', '\0') #define ACMDRIVERDETAILS_SUPPORTF_CODEC 0x00000001L #define ACMDRIVERDETAILS_SUPPORTF_CONVERTER 0x00000002L #define ACMDRIVERDETAILS_SUPPORTF_FILTER 0x00000004L #define ACMDRIVERDETAILS_SUPPORTF_HARDWARE 0x00000008L #define ACMDRIVERDETAILS_SUPPORTF_ASYNC 0x00000010L #define ACMDRIVERDETAILS_SUPPORTF_LOCAL 0x40000000L #define ACMDRIVERDETAILS_SUPPORTF_DISABLED 0x80000000L #define ACM_DRIVERENUMF_NOLOCAL 0x40000000L #define ACM_DRIVERENUMF_DISABLED 0x80000000L #define ACM_DRIVERPRIORITYF_ENABLE 0x00000001L #define ACM_DRIVERPRIORITYF_DISABLE 0x00000002L #define ACM_DRIVERPRIORITYF_ABLEMASK 0x00000003L #define ACM_DRIVERPRIORITYF_BEGIN 0x00010000L #define ACM_DRIVERPRIORITYF_END 0x00020000L #define ACM_DRIVERPRIORITYF_DEFERMASK 0x00030000L #define MM_ACM_FILTERCHOOSE 0x8000 #define FILTERCHOOSE_MESSAGE 0 #define FILTERCHOOSE_FILTERTAG_VERIFY (FILTERCHOOSE_MESSAGE+0) #define FILTERCHOOSE_FILTER_VERIFY (FILTERCHOOSE_MESSAGE+1) #define FILTERCHOOSE_CUSTOM_VERIFY (FILTERCHOOSE_MESSAGE+2) #define ACMFILTERCHOOSE_STYLEF_SHOWHELP 0x00000004L #define ACMFILTERCHOOSE_STYLEF_ENABLEHOOK 0x00000008L #define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L #define ACMFILTERCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L #define ACMFILTERCHOOSE_STYLEF_INITTOFILTERSTRUCT 0x00000040L #define ACMFILTERCHOOSE_STYLEF_CONTEXTHELP 0x00000080L #define ACMFILTERDETAILS_FILTER_CHARS 128 #define ACM_FILTERDETAILSF_INDEX 0x00000000L #define ACM_FILTERDETAILSF_FILTER 0x00000001L #define ACM_FILTERDETAILSF_QUERYMASK 0x0000000FL #define ACMFILTERTAGDETAILS_FILTERTAG_CHARS 48 #define ACM_FILTERTAGDETAILSF_INDEX 0x00000000L #define ACM_FILTERTAGDETAILSF_FILTERTAG 0x00000001L #define ACM_FILTERTAGDETAILSF_LARGESTSIZE 0x00000002L #define ACM_FILTERTAGDETAILSF_QUERYMASK 0x0000000FL #define ACM_FILTERENUMF_DWFILTERTAG 0x00010000L #define ACMHELPMSGSTRINGA "acmchoose_help" #define ACMHELPMSGSTRINGW L"acmchoose_help" #define ACMHELPMSGSTRING16 "acmchoose_help" #define ACMHELPMSGCONTEXTMENUA "acmchoose_contextmenu" #define ACMHELPMSGCONTEXTMENUW L"acmchoose_contextmenu" #define ACMHELPMSGCONTEXTMENU16 "acmchoose_contextmenu" #define ACMHELPMSGCONTEXTHELPA "acmchoose_contexthelp" #define ACMHELPMSGCONTEXTHELPW L"acmchoose_contexthelp" #define ACMHELPMSGCONTEXTHELP16 "acmchoose_contexthelp" #define MM_ACM_FORMATCHOOSE 0x8000 #define FORMATCHOOSE_MESSAGE 0 #define FORMATCHOOSE_FORMATTAG_VERIFY (FORMATCHOOSE_MESSAGE+0) #define FORMATCHOOSE_FORMAT_VERIFY (FORMATCHOOSE_MESSAGE+1) #define FORMATCHOOSE_CUSTOM_VERIFY (FORMATCHOOSE_MESSAGE+2) #define ACMFORMATCHOOSE_STYLEF_SHOWHELP 0x00000004L #define ACMFORMATCHOOSE_STYLEF_ENABLEHOOK 0x00000008L #define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE 0x00000010L #define ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE 0x00000020L #define ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT 0x00000040L #define ACMFORMATCHOOSE_STYLEF_CONTEXTHELP 0x00000080L #define ACMFORMATDETAILS_FORMAT_CHARS 128 #define ACM_FORMATDETAILSF_INDEX 0x00000000L #define ACM_FORMATDETAILSF_FORMAT 0x00000001L #define ACM_FORMATDETAILSF_QUERYMASK 0x0000000FL #define ACM_FORMATENUMF_WFORMATTAG 0x00010000L #define ACM_FORMATENUMF_NCHANNELS 0x00020000L #define ACM_FORMATENUMF_NSAMPLESPERSEC 0x00040000L #define ACM_FORMATENUMF_WBITSPERSAMPLE 0x00080000L #define ACM_FORMATENUMF_CONVERT 0x00100000L #define ACM_FORMATENUMF_SUGGEST 0x00200000L #define ACM_FORMATENUMF_HARDWARE 0x00400000L #define ACM_FORMATENUMF_INPUT 0x00800000L #define ACM_FORMATENUMF_OUTPUT 0x01000000L #define ACM_FORMATSUGGESTF_WFORMATTAG 0x00010000L #define ACM_FORMATSUGGESTF_NCHANNELS 0x00020000L #define ACM_FORMATSUGGESTF_NSAMPLESPERSEC 0x00040000L #define ACM_FORMATSUGGESTF_WBITSPERSAMPLE 0x00080000L #define ACM_FORMATSUGGESTF_TYPEMASK 0x00FF0000L #define ACMFORMATTAGDETAILS_FORMATTAG_CHARS 48 #define ACM_FORMATTAGDETAILSF_INDEX 0x00000000L #define ACM_FORMATTAGDETAILSF_FORMATTAG 0x00000001L #define ACM_FORMATTAGDETAILSF_LARGESTSIZE 0x00000002L #define ACM_FORMATTAGDETAILSF_QUERYMASK 0x0000000FL #define ACM_METRIC_COUNT_DRIVERS 1 #define ACM_METRIC_COUNT_CODECS 2 #define ACM_METRIC_COUNT_CONVERTERS 3 #define ACM_METRIC_COUNT_FILTERS 4 #define ACM_METRIC_COUNT_DISABLED 5 #define ACM_METRIC_COUNT_HARDWARE 6 #define ACM_METRIC_COUNT_LOCAL_DRIVERS 20 #define ACM_METRIC_COUNT_LOCAL_CODECS 21 #define ACM_METRIC_COUNT_LOCAL_CONVERTERS 22 #define ACM_METRIC_COUNT_LOCAL_FILTERS 23 #define ACM_METRIC_COUNT_LOCAL_DISABLED 24 #define ACM_METRIC_HARDWARE_WAVE_INPUT 30 #define ACM_METRIC_HARDWARE_WAVE_OUTPUT 31 #define ACM_METRIC_MAX_SIZE_FORMAT 50 #define ACM_METRIC_MAX_SIZE_FILTER 51 #define ACM_METRIC_DRIVER_SUPPORT 100 #define ACM_METRIC_DRIVER_PRIORITY 101 #define ACM_STREAMCONVERTF_BLOCKALIGN 0x00000004 #define ACM_STREAMCONVERTF_START 0x00000010 #define ACM_STREAMCONVERTF_END 0x00000020 #define ACMSTREAMHEADER_STATUSF_DONE 0x00010000L #define ACMSTREAMHEADER_STATUSF_PREPARED 0x00020000L #define ACMSTREAMHEADER_STATUSF_INQUEUE 0x00100000L #define ACM_STREAMOPENF_QUERY 0x00000001 #define ACM_STREAMOPENF_ASYNC 0x00000002 #define ACM_STREAMOPENF_NONREALTIME 0x00000004 #define ACM_STREAMSIZEF_SOURCE 0x00000000L #define ACM_STREAMSIZEF_DESTINATION 0x00000001L #define ACM_STREAMSIZEF_QUERYMASK 0x0000000FL #define ACMDM_USER (DRV_USER + 0x0000) #define ACMDM_RESERVED_LOW (DRV_USER + 0x2000) #define ACMDM_RESERVED_HIGH (DRV_USER + 0x2FFF) #define ACMDM_BASE ACMDM_RESERVED_LOW #define ACMDM_DRIVER_ABOUT (ACMDM_BASE + 11) /*********************************************************************** * Callbacks */ typedef WIN_BOOL CALLBACK ( *ACMDRIVERENUMCB)( HACMDRIVERID hadid, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL16 CALLBACK ( *ACMDRIVERENUMCB16)( HACMDRIVERID16 hadid, DWORD dwInstance, DWORD fdwSupport ); typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROCA)( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROCW)( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); typedef UINT CALLBACK ( *ACMFILTERCHOOSEHOOKPROC16)( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); typedef UINT CALLBACK ( *ACMFORMATCHOOSEHOOKPROCA)( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); typedef UINT CALLBACK ( *ACMFORMATCHOOSEHOOKPROCW)( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); typedef UINT16 CALLBACK ( *ACMFORMATCHOOSEHOOKPROC16)( HWND16 hwnd, UINT16 uMsg, WPARAM16 wParam, LPARAM lParam ); /*********************************************************************** * Structures */ typedef struct _ACMDRIVERDETAILSA { DWORD cbStruct; FOURCC fccType; FOURCC fccComp; WORD wMid; WORD wPid; DWORD vdwACM; DWORD vdwDriver; DWORD fdwSupport; DWORD cFormatTags; DWORD cFilterTags; HICON hicon; CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]; CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]; CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]; CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]; CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]; } ACMDRIVERDETAILSA, *PACMDRIVERDETAILSA; typedef struct _ACMDRIVERDETAILSW { DWORD cbStruct; FOURCC fccType; FOURCC fccComp; WORD wMid; WORD wPid; DWORD vdwACM; DWORD vdwDriver; DWORD fdwSupport; DWORD cFormatTags; DWORD cFilterTags; HICON hicon; WCHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]; WCHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]; WCHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]; WCHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]; WCHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]; } ACMDRIVERDETAILSW, *PACMDRIVERDETAILSW; typedef struct _ACMDRIVERDETAILS16 { DWORD cbStruct; FOURCC fccType; FOURCC fccComp; WORD wMid; WORD wPid; DWORD vdwACM; DWORD vdwDriver; DWORD fdwSupport; DWORD cFormatTags; DWORD cFilterTags; HICON16 hicon; CHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]; CHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]; CHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]; CHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]; CHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]; } ACMDRIVERDETAILS16, *NPACMDRIVERDETAILS16, *LPACMDRIVERDETAILS16; typedef struct _ACMFILTERCHOOSEA { DWORD cbStruct; DWORD fdwStyle; HWND hwndOwner; PWAVEFILTER pwfltr; DWORD cbwfltr; LPCSTR pszTitle; CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; LPSTR pszName; DWORD cchName; DWORD fdwEnum; PWAVEFILTER pwfltrEnum; HINSTANCE hInstance; LPCSTR pszTemplateName; LPARAM lCustData; ACMFILTERCHOOSEHOOKPROCA pfnHook; } ACMFILTERCHOOSEA, *PACMFILTERCHOOSEA; typedef struct _ACMFILTERCHOOSEW { DWORD cbStruct; DWORD fdwStyle; HWND hwndOwner; PWAVEFILTER pwfltr; DWORD cbwfltr; LPCWSTR pszTitle; WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; LPWSTR pszName; DWORD cchName; DWORD fdwEnum; PWAVEFILTER pwfltrEnum; HINSTANCE hInstance; LPCWSTR pszTemplateName; LPARAM lCustData; ACMFILTERCHOOSEHOOKPROCW pfnHook; } ACMFILTERCHOOSEW, *PACMFILTERCHOOSEW; typedef struct _ACMFILTERCHOOSE16 { DWORD cbStruct; DWORD fdwStyle; HWND16 hwndOwner; LPWAVEFILTER pwfltr; DWORD cbwfltr; LPCSTR pszTitle; char szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; char szFilter[ACMFILTERDETAILS_FILTER_CHARS]; LPSTR pszName; DWORD cchName; DWORD fdwEnum; LPWAVEFILTER pwfltrEnum; HINSTANCE16 hInstance; LPCSTR pszTemplateName; LPARAM lCustData; ACMFILTERCHOOSEHOOKPROC16 pfnHook; } ACMFILTERCHOOSE16, *NPACMFILTERCHOOSE16, *LPACMFILTERCHOOSE16; typedef struct _ACMFILTERDETAILSA { DWORD cbStruct; DWORD dwFilterIndex; DWORD dwFilterTag; DWORD fdwSupport; PWAVEFILTER pwfltr; DWORD cbwfltr; CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; } ACMFILTERDETAILSA, *PACMFILTERDETAILSA; typedef struct _ACMFILTERDETAILSW { DWORD cbStruct; DWORD dwFilterIndex; DWORD dwFilterTag; DWORD fdwSupport; PWAVEFILTER pwfltr; DWORD cbwfltr; WCHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; } ACMFILTERDETAILSW, *PACMFILTERDETAILSW; typedef struct _ACMFILTERDETAILS16 { DWORD cbStruct; DWORD dwFilterIndex; DWORD dwFilterTag; DWORD fdwSupport; LPWAVEFILTER pwfltr; DWORD cbwfltr; CHAR szFilter[ACMFILTERDETAILS_FILTER_CHARS]; } ACMFILTERDETAILS16, *NPACMFILTERDETAILS16, *LPACMFILTERDETAILS16; typedef struct _ACMFILTERTAGDETAILSA { DWORD cbStruct; DWORD dwFilterTagIndex; DWORD dwFilterTag; DWORD cbFilterSize; DWORD fdwSupport; DWORD cStandardFilters; CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; } ACMFILTERTAGDETAILSA, *PACMFILTERTAGDETAILSA; typedef struct _ACMFILTERTAGDETAILSW { DWORD cbStruct; DWORD dwFilterTagIndex; DWORD dwFilterTag; DWORD cbFilterSize; DWORD fdwSupport; DWORD cStandardFilters; WCHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; } ACMFILTERTAGDETAILSW, *PACMFILTERTAGDETAILSW; typedef struct _ACMFILTERTAGDETAILS16 { DWORD cbStruct; DWORD dwFilterTagIndex; DWORD dwFilterTag; DWORD cbFilterSize; DWORD fdwSupport; DWORD cStandardFilters; CHAR szFilterTag[ACMFILTERTAGDETAILS_FILTERTAG_CHARS]; } ACMFILTERTAGDETAILS16, *NPACMFILTERTAGDETAILS16, *LPACMFILTERTAGDETAILS16; typedef struct _ACMFORMATCHOOSEA { DWORD cbStruct; DWORD fdwStyle; HWND hwndOwner; PWAVEFORMATEX pwfx; DWORD cbwfx; LPCSTR pszTitle; CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; LPSTR pszName; DWORD cchName; DWORD fdwEnum; PWAVEFORMATEX pwfxEnum; HINSTANCE hInstance; LPCSTR pszTemplateName; LPARAM lCustData; ACMFORMATCHOOSEHOOKPROCA pfnHook; } ACMFORMATCHOOSEA, *PACMFORMATCHOOSEA; typedef struct _ACMFORMATCHOOSEW { DWORD cbStruct; DWORD fdwStyle; HWND hwndOwner; PWAVEFORMATEX pwfx; DWORD cbwfx; LPCWSTR pszTitle; WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; LPWSTR pszName; DWORD cchName; DWORD fdwEnum; LPWAVEFORMATEX pwfxEnum; HINSTANCE hInstance; LPCWSTR pszTemplateName; LPARAM lCustData; ACMFORMATCHOOSEHOOKPROCW pfnHook; } ACMFORMATCHOOSEW, *PACMFORMATCHOOSEW; typedef struct _ACMFORMATCHOOSE16 { DWORD cbStruct; DWORD fdwStyle; HWND16 hwndOwner; LPWAVEFORMATEX pwfx; DWORD cbwfx; LPCSTR pszTitle; CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; LPSTR pszName; DWORD cchName; DWORD fdwEnum; LPWAVEFORMATEX pwfxEnum; HINSTANCE16 hInstance; LPCSTR pszTemplateName; LPARAM lCustData; ACMFORMATCHOOSEHOOKPROC16 pfnHook; } ACMFORMATCHOOSE16, *NPACMFORMATCHOOSE16, *LPACMFORMATCHOOSE16; typedef struct _ACMFORMATDETAILSA { DWORD cbStruct; DWORD dwFormatIndex; DWORD dwFormatTag; DWORD fdwSupport; PWAVEFORMATEX pwfx; DWORD cbwfx; CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; } ACMFORMATDETAILSA, *PACMFORMATDETAILSA; typedef struct _ACMFORMATDETAILSW { DWORD cbStruct; DWORD dwFormatIndex; DWORD dwFormatTag; DWORD fdwSupport; PWAVEFORMATEX pwfx; DWORD cbwfx; WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; } ACMFORMATDETAILSW, *PACMFORMATDETAILSW; typedef struct _ACMFORMATDETAILS16 { DWORD cbStruct; DWORD dwFormatIndex; DWORD dwFormatTag; DWORD fdwSupport; LPWAVEFORMATEX pwfx; DWORD cbwfx; CHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]; } ACMFORMATDETAILS16, *NPACMFORMATDETAILS16, *LPACMFORMATDETAILS16; typedef struct _ACMFORMATTAGDETAILSA { DWORD cbStruct; DWORD dwFormatTagIndex; DWORD dwFormatTag; DWORD cbFormatSize; DWORD fdwSupport; DWORD cStandardFormats; CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; } ACMFORMATTAGDETAILSA, *PACMFORMATTAGDETAILSA; typedef struct _ACMFORMATTAGDETAILSW { DWORD cbStruct; DWORD dwFormatTagIndex; DWORD dwFormatTag; DWORD cbFormatSize; DWORD fdwSupport; DWORD cStandardFormats; WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; } ACMFORMATTAGDETAILSW, *PACMFORMATTAGDETAILSW; typedef struct _ACMFORMATTAGDETAILS16 { DWORD cbStruct; DWORD dwFormatTagIndex; DWORD dwFormatTag; DWORD cbFormatSize; DWORD fdwSupport; DWORD cStandardFormats; CHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]; } ACMFORMATTAGDETAILS16, *NPACMFORMATTAGDETAILS16, *LPACMFORMATTAGDETAILS16; typedef struct _ACMSTREAMHEADER { DWORD cbStruct; DWORD fdwStatus; DWORD dwUser; LPBYTE pbSrc; DWORD cbSrcLength; DWORD cbSrcLengthUsed; DWORD dwSrcUser; LPBYTE pbDst; DWORD cbDstLength; DWORD cbDstLengthUsed; DWORD dwDstUser; DWORD dwReservedDriver[10]; } ACMSTREAMHEADER16, *NPACMSTREAMHEADER16, *LPACMSTREAMHEADER16, ACMSTREAMHEADER, *PACMSTREAMHEADER; /*********************************************************************** * Callbacks 2 */ typedef WIN_BOOL CALLBACK ( *ACMFILTERENUMCBA)( HACMDRIVERID hadid, PACMFILTERDETAILSA pafd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL CALLBACK ( *ACMFILTERENUMCBW)( HACMDRIVERID hadid, PACMFILTERDETAILSW pafd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL16 CALLBACK ( *ACMFILTERENUMCB16)( HACMDRIVERID16 hadid, LPACMFILTERDETAILS16 pafd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL CALLBACK ( *ACMFILTERTAGENUMCBA)( HACMDRIVERID hadid, PACMFILTERTAGDETAILSA paftd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL CALLBACK ( *ACMFILTERTAGENUMCBW)( HACMDRIVERID hadid, PACMFILTERTAGDETAILSW paftd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL16 CALLBACK ( *ACMFILTERTAGENUMCB16)( HACMDRIVERID16 hadid, LPACMFILTERTAGDETAILS16 paftd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL CALLBACK ( *ACMFORMATENUMCBA)( HACMDRIVERID hadid, PACMFORMATDETAILSA pafd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL CALLBACK ( *ACMFORMATENUMCBW)( HACMDRIVERID hadid, PACMFORMATDETAILSW pafd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL16 CALLBACK ( *ACMFORMATENUMCB16)( HACMDRIVERID16 hadid, LPACMFORMATDETAILS16 pafd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL CALLBACK ( *ACMFORMATTAGENUMCBA)( HACMDRIVERID hadid, PACMFORMATTAGDETAILSA paftd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL CALLBACK ( *ACMFORMATTAGENUMCBW)( HACMDRIVERID hadid, PACMFORMATTAGDETAILSW paftd, DWORD dwInstance, DWORD fdwSupport ); typedef WIN_BOOL16 CALLBACK ( *ACMFORMATTAGENUMCB16)( HACMDRIVERID16 hadid, LPACMFORMATTAGDETAILS16 paftd, DWORD dwInstance, DWORD fdwSupport ); /*********************************************************************** * Functions - Win16 */ DWORD WINAPI acmGetVersion16( ); MMRESULT16 WINAPI acmMetrics16( HACMOBJ16 hao, UINT16 uMetric, LPVOID pMetric ); MMRESULT16 WINAPI acmDriverEnum16( ACMDRIVERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT16 WINAPI acmDriverDetails16( HACMDRIVERID16 hadid, LPACMDRIVERDETAILS16 padd, DWORD fdwDetails ); MMRESULT16 WINAPI acmDriverAdd16( LPHACMDRIVERID16 phadid, HINSTANCE16 hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd ); MMRESULT16 WINAPI acmDriverRemove16( HACMDRIVERID16 hadid, DWORD fdwRemove ); MMRESULT16 WINAPI acmDriverOpen16( LPHACMDRIVER16 phad, HACMDRIVERID16 hadid, DWORD fdwOpen ); MMRESULT16 WINAPI acmDriverClose16( HACMDRIVER16 had, DWORD fdwClose ); LRESULT WINAPI acmDriverMessage16( HACMDRIVER16 had, UINT16 uMsg, LPARAM lParam1, LPARAM lParam2 ); MMRESULT16 WINAPI acmDriverID16( HACMOBJ16 hao, LPHACMDRIVERID16 phadid, DWORD fdwDriverID ); MMRESULT16 WINAPI acmDriverPriority16( HACMDRIVERID16 hadid, DWORD dwPriority, DWORD fdwPriority ); MMRESULT16 WINAPI acmFormatTagDetails16( HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd, DWORD fdwDetails ); MMRESULT16 WINAPI acmFormatTagEnum16( HACMDRIVER16 had, LPACMFORMATTAGDETAILS16 paftd, ACMFORMATTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT16 WINAPI acmFormatChoose16( LPACMFORMATCHOOSE16 pafmtc ); MMRESULT16 WINAPI acmFormatDetails16( HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd, DWORD fdwDetails ); MMRESULT16 WINAPI acmFormatEnum16( HACMDRIVER16 had, LPACMFORMATDETAILS16 pafd, ACMFORMATENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT16 WINAPI acmFormatSuggest16( HACMDRIVER16 had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest ); MMRESULT16 WINAPI acmFilterTagDetails16( HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd, DWORD fdwDetails ); MMRESULT16 WINAPI acmFilterTagEnum16( HACMDRIVER16 had, LPACMFILTERTAGDETAILS16 paftd, ACMFILTERTAGENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT16 WINAPI acmFilterChoose16( LPACMFILTERCHOOSE16 pafltrc ); MMRESULT16 WINAPI acmFilterDetails16( HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd, DWORD fdwDetails ); MMRESULT16 WINAPI acmFilterEnum16( HACMDRIVER16 had, LPACMFILTERDETAILS16 pafd, ACMFILTERENUMCB16 fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT16 WINAPI acmStreamOpen16( LPHACMSTREAM16 phas, HACMDRIVER16 had, LPWAVEFORMATEX pwfxSrc, LPWAVEFORMATEX pwfxDst, LPWAVEFILTER pwfltr, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen ); MMRESULT16 WINAPI acmStreamClose16( HACMSTREAM16 has, DWORD fdwClose ); MMRESULT16 WINAPI acmStreamSize16( HACMSTREAM16 has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize ); MMRESULT16 WINAPI acmStreamConvert16( HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwConvert ); MMRESULT16 WINAPI acmStreamReset16( HACMSTREAM16 has, DWORD fdwReset ); MMRESULT16 WINAPI acmStreamPrepareHeader16( HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwPrepare ); MMRESULT16 WINAPI acmStreamUnprepareHeader16( HACMSTREAM16 has, LPACMSTREAMHEADER16 pash, DWORD fdwUnprepare ); /*********************************************************************** * Functions - Win32 */ MMRESULT WINAPI acmDriverAddA( PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd ); MMRESULT WINAPI acmDriverAddW( PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd ); MMRESULT WINAPI acmDriverClose( HACMDRIVER had, DWORD fdwClose ); MMRESULT WINAPI acmDriverDetailsA( HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails ); MMRESULT WINAPI acmDriverDetailsW( HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails ); MMRESULT WINAPI acmDriverEnum( ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmDriverID( HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID ); LRESULT WINAPI acmDriverMessage( HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2 ); MMRESULT WINAPI acmDriverOpen( PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen ); MMRESULT WINAPI acmDriverPriority( HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority ); MMRESULT WINAPI acmDriverRemove( HACMDRIVERID hadid, DWORD fdwRemove ); MMRESULT WINAPI acmFilterChooseA( PACMFILTERCHOOSEA pafltrc ); MMRESULT WINAPI acmFilterChooseW( PACMFILTERCHOOSEW pafltrc ); MMRESULT WINAPI acmFilterDetailsA( HACMDRIVER had, PACMFILTERDETAILSA pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterDetailsW( HACMDRIVER had, PACMFILTERDETAILSW pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterEnumA( HACMDRIVER had, PACMFILTERDETAILSA pafd, ACMFILTERENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFilterEnumW( HACMDRIVER had, PACMFILTERDETAILSW pafd, ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFilterTagDetailsA( HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterTagDetailsW( HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterTagEnumA( HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFilterTagEnumW( HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatChooseA( PACMFORMATCHOOSEA pafmtc ); MMRESULT WINAPI acmFormatChooseW( PACMFORMATCHOOSEW pafmtc ); MMRESULT WINAPI acmFormatDetailsA( HACMDRIVER had, PACMFORMATDETAILSA pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatDetailsW( HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatEnumA( HACMDRIVER had, PACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatEnumW( HACMDRIVER had, PACMFORMATDETAILSW pafd, ACMFORMATENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatSuggest( HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest ); MMRESULT WINAPI acmFormatTagDetailsA( HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatTagDetailsW( HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatTagEnumA( HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatTagEnumW( HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); DWORD WINAPI acmGetVersion( ); MMRESULT WINAPI acmMetrics( HACMOBJ hao, UINT uMetric, LPVOID pMetric ); MMRESULT WINAPI acmStreamClose( HACMSTREAM has, DWORD fdwClose ); MMRESULT WINAPI acmStreamConvert( HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert ); MMRESULT WINAPI acmStreamMessage( HACMSTREAM has, UINT uMsg, LPARAM lParam1, LPARAM lParam2 ); MMRESULT WINAPI acmStreamOpen( PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen ); MMRESULT WINAPI acmStreamPrepareHeader( HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare ); MMRESULT WINAPI acmStreamReset( HACMSTREAM has, DWORD fdwReset ); MMRESULT WINAPI acmStreamSize( HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize ); MMRESULT WINAPI acmStreamUnprepareHeader( HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare ); void MSACM_RegisterAllDrivers(void); #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ #endif /* __WINE_MSACM_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/msacmdrv.h����������������������������������������������������������0000644�0001750�0001750�00000012111�14647725152�016174� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * msacmdrv.h - Declarations for MSACM driver */ #ifndef __WINE_MSACMDRV_H #define __WINE_MSACMDRV_H #include "windef.h" #include "msacm.h" /*********************************************************************** * Types */ /*********************************************************************** * Defines/Enums */ #define MAKE_ACM_VERSION(mjr, mnr, bld) \ (((long)(mjr)<<24) | ((long)(mnr)<<16) | ((long)bld)) #define ACMDRVOPENDESC_SECTIONNAME_CHARS #define ACMDM_DRIVER_NOTIFY (ACMDM_BASE + 1) #define ACMDM_DRIVER_DETAILS (ACMDM_BASE + 10) #define ACMDM_HARDWARE_WAVE_CAPS_INPUT (ACMDM_BASE + 20) #define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT (ACMDM_BASE + 21) #define ACMDM_FORMATTAG_DETAILS (ACMDM_BASE + 25) #define ACMDM_FORMAT_DETAILS (ACMDM_BASE + 26) #define ACMDM_FORMAT_SUGGEST (ACMDM_BASE + 27) #define ACMDM_FILTERTAG_DETAILS (ACMDM_BASE + 50) #define ACMDM_FILTER_DETAILS (ACMDM_BASE + 51) #define ACMDM_STREAM_OPEN (ACMDM_BASE + 76) #define ACMDM_STREAM_CLOSE (ACMDM_BASE + 77) #define ACMDM_STREAM_SIZE (ACMDM_BASE + 78) #define ACMDM_STREAM_CONVERT (ACMDM_BASE + 79) #define ACMDM_STREAM_RESET (ACMDM_BASE + 80) #define ACMDM_STREAM_PREPARE (ACMDM_BASE + 81) #define ACMDM_STREAM_UNPREPARE (ACMDM_BASE + 82) #define ACMDM_STREAM_UPDATE (ACMDM_BASE + 83) /*********************************************************************** * Structures */ typedef struct _ACMDRVOPENDESCA { DWORD cbStruct; FOURCC fccType; FOURCC fccComp; DWORD dwVersion; DWORD dwFlags; DWORD dwError; LPCSTR pszSectionName; LPCSTR pszAliasName; DWORD dnDevNode; } ACMDRVOPENDESCA, *PACMDRVOPENDESCA; typedef struct _ACMDRVOPENDESCW { DWORD cbStruct; FOURCC fccType; FOURCC fccComp; DWORD dwVersion; DWORD dwFlags; DWORD dwError; LPCWSTR pszSectionName; LPCWSTR pszAliasName; DWORD dnDevNode; } ACMDRVOPENDESCW, *PACMDRVOPENDESCW; typedef struct _ACMDRVOPENDESC16 { DWORD cbStruct; FOURCC fccType; FOURCC fccComp; DWORD dwVersion; DWORD dwFlags; DWORD dwError; LPCSTR pszSectionName; LPCSTR pszAliasName; DWORD dnDevNode; } ACMDRVOPENDESC16, *NPACMDRVOPENDESC16, *LPACMDRVOPENDESC16; typedef struct _ACMDRVSTREAMINSTANCE16 { DWORD cbStruct; LPWAVEFORMATEX pwfxSrc; LPWAVEFORMATEX pwfxDst; LPWAVEFILTER pwfltr; DWORD dwCallback; DWORD dwInstance; DWORD fdwOpen; DWORD fdwDriver; DWORD dwDriver; HACMSTREAM16 has; } ACMDRVSTREAMINSTANCE16, *NPACMDRVSTREAMINSTANCE16, *LPACMDRVSTREAMINSTANCE16; typedef struct _ACMDRVSTREAMINSTANCE { DWORD cbStruct; PWAVEFORMATEX pwfxSrc; PWAVEFORMATEX pwfxDst; PWAVEFILTER pwfltr; DWORD dwCallback; DWORD dwInstance; DWORD fdwOpen; DWORD fdwDriver; DWORD dwDriver; HACMSTREAM has; } ACMDRVSTREAMINSTANCE, *PACMDRVSTREAMINSTANCE; typedef struct _ACMDRVSTREAMHEADER16 *LPACMDRVSTREAMHEADER16; typedef struct _ACMDRVSTREAMHEADER16 { DWORD cbStruct; DWORD fdwStatus; DWORD dwUser; LPBYTE pbSrc; DWORD cbSrcLength; DWORD cbSrcLengthUsed; DWORD dwSrcUser; LPBYTE pbDst; DWORD cbDstLength; DWORD cbDstLengthUsed; DWORD dwDstUser; DWORD fdwConvert; LPACMDRVSTREAMHEADER16 *padshNext; DWORD fdwDriver; DWORD dwDriver; /* Internal fields for ACM */ DWORD fdwPrepared; DWORD dwPrepared; LPBYTE pbPreparedSrc; DWORD cbPreparedSrcLength; LPBYTE pbPreparedDst; DWORD cbPreparedDstLength; } ACMDRVSTREAMHEADER16, *NPACMDRVSTREAMHEADER16; typedef struct _ACMDRVSTREAMHEADER *PACMDRVSTREAMHEADER; typedef struct _ACMDRVSTREAMHEADER { DWORD cbStruct; DWORD fdwStatus; DWORD dwUser; LPBYTE pbSrc; DWORD cbSrcLength; DWORD cbSrcLengthUsed; DWORD dwSrcUser; LPBYTE pbDst; DWORD cbDstLength; DWORD cbDstLengthUsed; DWORD dwDstUser; DWORD fdwConvert; PACMDRVSTREAMHEADER *padshNext; DWORD fdwDriver; DWORD dwDriver; /* Internal fields for ACM */ DWORD fdwPrepared; DWORD dwPrepared; LPBYTE pbPreparedSrc; DWORD cbPreparedSrcLength; LPBYTE pbPreparedDst; DWORD cbPreparedDstLength; } ACMDRVSTREAMHEADER; typedef struct _ACMDRVSTREAMSIZE { DWORD cbStruct; DWORD fdwSize; DWORD cbSrcLength; DWORD cbDstLength; } ACMDRVSTREAMSIZE16, *NPACMDRVSTREAMSIZE16, *LPACMDRVSTREAMSIZE16, ACMDRVSTREAMSIZE, *PACMDRVSTREAMSIZE; typedef struct _ACMDRVFORMATSUGGEST16 { DWORD cbStruct; DWORD fdwSuggest; LPWAVEFORMATEX pwfxSrc; DWORD cbwfxSrc; LPWAVEFORMATEX pwfxDst; DWORD cbwfxDst; } ACMDRVFORMATSUGGEST16, *NPACMDRVFORMATSUGGEST, *LPACMDRVFORMATSUGGEST; typedef struct _ACMDRVFORMATSUGGEST { DWORD cbStruct; DWORD fdwSuggest; PWAVEFORMATEX pwfxSrc; DWORD cbwfxSrc; PWAVEFORMATEX pwfxDst; DWORD cbwfxDst; } ACMDRVFORMATSUGGEST, *PACMDRVFORMATSUGGEST; #endif /* __WINE_MSACMDRV_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/pe_image.h����������������������������������������������������������0000644�0001750�0001750�00000006601�14647725152�016135� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_PE_IMAGE_H #define __WINE_PE_IMAGE_H #include "windef.h" #include "winbase.h" #define PE_HEADER(module) \ ((IMAGE_NT_HEADERS*)((LPBYTE)(module) + \ (((IMAGE_DOS_HEADER*)(module))->e_lfanew))) #define PE_SECTIONS(module) \ ((IMAGE_SECTION_HEADER*)((LPBYTE)&PE_HEADER(module)->OptionalHeader + \ PE_HEADER(module)->FileHeader.SizeOfOptionalHeader)) #define RVA_PTR(module,field) ((LPBYTE)(module) + PE_HEADER(module)->field) /* modreference used for attached processes * all section are calculated here, relocations etc. */ typedef struct { PIMAGE_IMPORT_DESCRIPTOR pe_import; PIMAGE_EXPORT_DIRECTORY pe_export; PIMAGE_RESOURCE_DIRECTORY pe_resource; int tlsindex; } PE_MODREF; struct _wine_modref; extern int PE_unloadImage(HMODULE hModule); extern FARPROC PE_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName, WIN_BOOL snoop); extern WIN_BOOL PE_EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG); extern WIN_BOOL PE_EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG); extern WIN_BOOL PE_EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA,LONG); extern WIN_BOOL PE_EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW,LONG); extern WIN_BOOL PE_EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR,ENUMRESLANGPROCA,LONG); extern WIN_BOOL PE_EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR,ENUMRESLANGPROCW,LONG); extern HRSRC PE_FindResourceExW(struct _wine_modref*,LPCWSTR,LPCWSTR,WORD); extern DWORD PE_SizeofResource(HMODULE,HRSRC); extern struct _wine_modref *PE_LoadLibraryExA(LPCSTR, DWORD); extern void PE_UnloadLibrary(struct _wine_modref *); extern HGLOBAL PE_LoadResource(struct _wine_modref *wm,HRSRC); extern HMODULE PE_LoadImage( int hFile, LPCSTR filename, WORD *version ); extern struct _wine_modref *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, WIN_BOOL builtin ); extern WIN_BOOL PE_CreateProcess( HANDLE hFile, LPCSTR filename, LPCSTR cmd_line, LPCSTR env, LPSECURITY_ATTRIBUTES psa, LPSECURITY_ATTRIBUTES tsa, WIN_BOOL inherit, DWORD flags, LPSTARTUPINFOA startup, LPPROCESS_INFORMATION info ); extern void PE_InitTls(void); extern WIN_BOOL PE_InitDLL(struct _wine_modref *wm, DWORD type, LPVOID lpReserved); extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY,LPCSTR,DWORD,WIN_BOOL); extern PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY,LPCWSTR,DWORD,WIN_BOOL); typedef DWORD CALLBACK (*DLLENTRYPROC)(HMODULE,DWORD,LPVOID); typedef struct { WORD popl WINE_PACKED; /* 0x8f 0x05 */ DWORD addr_popped WINE_PACKED;/* ... */ BYTE pushl1; /* 0x68 */ DWORD newret WINE_PACKED; /* ... */ BYTE pushl2; /* 0x68 */ DWORD origfun WINE_PACKED; /* original function */ BYTE ret1; /* 0xc3 */ WORD addesp WINE_PACKED; /* 0x83 0xc4 */ BYTE nrofargs; /* nr of arguments to add esp, */ BYTE pushl3; /* 0x68 */ DWORD oldret WINE_PACKED; /* Filled out from popl above */ BYTE ret2; /* 0xc3 */ } ELF_STDCALL_STUB; typedef struct { void* dlhandle; ELF_STDCALL_STUB *stubs; } ELF_MODREF; extern struct _wine_modref *ELF_LoadLibraryExA( LPCSTR libname, DWORD flags); extern void ELF_UnloadLibrary(struct _wine_modref *); extern FARPROC ELF_FindExportedFunction(struct _wine_modref *wm, LPCSTR funcName); #endif /* __WINE_PE_IMAGE_H */ �������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/ext.c���������������������������������������������������������������0000644�0001750�0001750�00000034735�14647725152�015173� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************** * * * Stub functions for Wine module * * ********************************************************/ #include "config.h" #include <stdio.h> #include <stdlib.h> #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #include <unistd.h> #include <sys/mman.h> #include <errno.h> #include <fcntl.h> #include <string.h> #include <stdarg.h> #include <ctype.h> #include "windef.h" #include "winbase.h" #include "debugtools.h" #include "heap.h" #include "ext.h" #if 0 //REMOVE SIMPLIFY static void* mymalloc(unsigned int size) { printf("malloc %d\n", size); return malloc(size); } #undef malloc #define malloc mymalloc #endif int dbg_header_err( const char *dbg_channel, const char *func ) { (void)dbg_channel; (void)func; return 0; } int dbg_header_warn( const char *dbg_channel, const char *func ) { (void)dbg_channel; (void)func; return 0; } int dbg_header_fixme( const char *dbg_channel, const char *func ) { (void)dbg_channel; (void)func; return 0; } int dbg_header_trace( const char *dbg_channel, const char *func ) { (void)dbg_channel; (void)func; return 0; } int dbg_vprintf( const char *format, va_list args ) { (void)format; (void)args; return 0; } int __vprintf( const char *format, ... ) { #ifdef DETAILED_OUT va_list va; va_start(va, format); vprintf(format, va); va_end(va); #else (void)format; #endif return 0; } HANDLE WINAPI GetProcessHeap(void) { return 1; } LPVOID WINAPI HeapAlloc(HANDLE heap, DWORD flags, DWORD size) { //static int i = 5; void* m = (flags & 0x8) ? calloc(size, 1) : malloc(size); //printf("HeapAlloc %p %d (%d)\n", m, size, flags); //if (--i == 0) // abort(); (void)heap; return m; } WIN_BOOL WINAPI HeapFree(HANDLE heap, DWORD flags, LPVOID mem) { (void)heap; (void)flags; if (mem) free(mem); //printf("HeapFree %p\n", mem); //if (!mem) // abort(); return 1; } static int last_error; DWORD WINAPI GetLastError(void) { return last_error; } VOID WINAPI SetLastError(DWORD error) { last_error=error; } WIN_BOOL WINAPI ReadFile(HANDLE handle, LPVOID mem, DWORD size, LPDWORD result, LPOVERLAPPED flags) { (void)flags; *result=read(handle, mem, size); return *result; } INT WINAPI lstrcmpiA(LPCSTR c1, LPCSTR c2) { return strcasecmp(c1,c2); } LPSTR WINAPI lstrcpynA(LPSTR dest, LPCSTR src, INT num) { return strncpy(dest,src,num); } INT WINAPI lstrlenA(LPCSTR s) { return strlen(s); } INT WINAPI lstrlenW(LPCWSTR s) { int l; if(!s) return 0; l=0; while(s[l]) l++; return l; } LPSTR WINAPI lstrcpynWtoA(LPSTR dest, LPCWSTR src, INT count) { LPSTR result = dest; int moved=0; if((dest==0) || (src==0)) return 0; while(moved<count) { *dest=*src; moved++; if(*src==0) break; src++; dest++; } return result; } /* i stands here for ignore case! */ int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n) { /* if(s1==0) return; if(s2==0) return; */ while(n>0) { if (((*s1 | *s2) & 0xff00) || toupper((char)*s1) != toupper((char)*s2)) { if(*s1<*s2) return -1; else if(*s1>*s2) return 1; else if(*s1==0) return 0; } s1++; s2++; n--; } return 0; } WIN_BOOL WINAPI IsBadReadPtr(LPCVOID data, UINT size) { if(size==0) return 0; if(data==NULL) return 1; return 0; } LPSTR HEAP_strdupA(HANDLE heap, DWORD flags, LPCSTR string) { // return strdup(string); char* answ; (void)heap; (void)flags; answ=malloc(strlen(string)+1); if(answ==NULL) return NULL; strcpy(answ, string); return answ; } LPWSTR HEAP_strdupAtoW(HANDLE heap, DWORD flags, LPCSTR string) { int size, i; short* answer; (void)heap; (void)flags; if(string==0) return NULL; size=strlen(string); answer=malloc(2 * (size + 1)); if(answer==NULL) return NULL; for(i=0; i<=size; i++) answer[i]=(short)string[i]; return answer; } LPSTR HEAP_strdupWtoA(HANDLE heap, DWORD flags, LPCWSTR string) { int size, i; char* answer; (void)heap; (void)flags; if(string==0) return NULL; size=0; while(string[size]) size++; answer=malloc(size+2); if(answer==NULL) return NULL; for(i=0; i<=size; i++) answer[i]=(char)string[i]; return answer; } /*********************************************************************** * FILE_dommap */ //#define MAP_PRIVATE //#define MAP_SHARED #undef MAP_ANON LPVOID FILE_dommap( int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, int prot, int flags ) { int fd = -1; int pos; LPVOID ret; if (size_high || offset_high) printf("offsets larger than 4Gb not supported\n"); if (unix_handle == -1) { #ifdef MAP_ANON // printf("Anonymous\n"); flags |= MAP_ANON; #else static int fdzero = -1; if (fdzero == -1) { if ((fdzero = open( "/dev/zero", O_RDONLY )) == -1) { perror( "Cannot open /dev/zero for READ. Check permissions! error: " ); abort(); } } fd = fdzero; #endif /* MAP_ANON */ /* Linux EINVAL's on us if we don't pass MAP_PRIVATE to an anon mmap */ #ifdef MAP_SHARED flags &= ~MAP_SHARED; #endif #ifdef MAP_PRIVATE flags |= MAP_PRIVATE; #endif } else fd = unix_handle; // printf("fd %x, start %x, size %x, pos %x, prot %x\n",fd,start,size_low, offset_low, prot); // if ((ret = mmap( start, size_low, prot, // flags, fd, offset_low )) != (LPVOID)-1) if ((ret = mmap( start, size_low, prot, MAP_PRIVATE | MAP_FIXED, fd, offset_low )) != (LPVOID)-1) { // printf("address %08x\n", *(int*)ret); // printf("%x\n", ret); return ret; } // printf("mmap %d\n", errno); /* mmap() failed; if this is because the file offset is not */ /* page-aligned (EINVAL), or because the underlying filesystem */ /* does not support mmap() (ENOEXEC), we do it by hand. */ if (unix_handle == -1) return ret; if ((errno != ENOEXEC) && (errno != EINVAL)) return ret; if (prot & PROT_WRITE) { /* We cannot fake shared write mappings */ #ifdef MAP_SHARED if (flags & MAP_SHARED) return ret; #endif #ifdef MAP_PRIVATE if (!(flags & MAP_PRIVATE)) return ret; #endif } /* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/ /* Reserve the memory with an anonymous mmap */ ret = FILE_dommap( -1, start, size_high, size_low, 0, 0, PROT_READ | PROT_WRITE, flags ); if (ret == (LPVOID)-1) // { // perror( return ret; /* Now read in the file */ if ((pos = lseek( fd, offset_low, SEEK_SET )) == -1) { FILE_munmap( ret, size_high, size_low ); // printf("lseek\n"); return (LPVOID)-1; } read( fd, ret, size_low ); lseek( fd, pos, SEEK_SET ); /* Restore the file pointer */ mprotect( ret, size_low, prot ); /* Set the right protection */ // printf("address %08x\n", *(int*)ret); return ret; } /*********************************************************************** * FILE_munmap */ int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ) { if (size_high) printf("offsets larger than 4Gb not supported\n"); return munmap( start, size_low ); } //static int mapping_size=0; struct file_mapping_s; typedef struct file_mapping_s { int mapping_size; char* name; LPVOID handle; struct file_mapping_s* next; struct file_mapping_s* prev; }file_mapping; static file_mapping* fm=0; #define PAGE_NOACCESS 0x01 #define PAGE_READONLY 0x02 #define PAGE_READWRITE 0x04 #define PAGE_WRITECOPY 0x08 #define PAGE_EXECUTE 0x10 #define PAGE_EXECUTE_READ 0x20 #define PAGE_EXECUTE_READWRITE 0x40 #define PAGE_EXECUTE_WRITECOPY 0x80 #define PAGE_GUARD 0x100 #define PAGE_NOCACHE 0x200 HANDLE WINAPI CreateFileMappingA(HANDLE handle, LPSECURITY_ATTRIBUTES lpAttr, DWORD flProtect, DWORD dwMaxHigh, DWORD dwMaxLow, LPCSTR name) { int hFile = (int)handle; unsigned int len; LPVOID answer; int anon=0; int mmap_access=0; (void)lpAttr; (void)dwMaxHigh; if(hFile<0) { anon=1; hFile=open("/dev/zero", O_RDWR); if(hFile<0){ perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " ); return 0; } } if(!anon) { len=lseek(hFile, 0, SEEK_END); lseek(hFile, 0, SEEK_SET); } else len=dwMaxLow; if(flProtect & PAGE_READONLY) mmap_access |=PROT_READ; else mmap_access |=PROT_READ|PROT_WRITE; answer=mmap(NULL, len, mmap_access, MAP_PRIVATE, hFile, 0); if(anon) close(hFile); if(answer!=(LPVOID)-1) { if(fm==0) { fm=malloc(sizeof(file_mapping)); fm->prev=NULL; } else { fm->next=malloc(sizeof(file_mapping)); fm->next->prev=fm; fm=fm->next; } fm->next=NULL; fm->handle=answer; if(name) { fm->name=malloc(strlen(name)+1); strcpy(fm->name, name); } else fm->name=NULL; fm->mapping_size=len; if(anon) close(hFile); return (HANDLE)answer; } return (HANDLE)0; } WIN_BOOL WINAPI UnmapViewOfFile(LPVOID handle) { file_mapping* p; int result; if(fm==0) return 0; for(p=fm; p; p=p->next) { if(p->handle==handle) { result=munmap((void*)handle, p->mapping_size); if(p->next)p->next->prev=p->prev; if(p->prev)p->prev->next=p->next; if(p->name) free(p->name); if(p==fm) fm=p->prev; free(p); return result; } } return 0; } //static int va_size=0; struct virt_alloc_s; typedef struct virt_alloc_s { int mapping_size; char* address; struct virt_alloc_s* next; struct virt_alloc_s* prev; int state; }virt_alloc; static virt_alloc* vm=0; #define MEM_COMMIT 0x00001000 #define MEM_RESERVE 0x00002000 LPVOID WINAPI VirtualAlloc(LPVOID address, DWORD size, DWORD type, DWORD protection) { void* answer; int fd; long pgsz; (void)protection; if ((type&(MEM_RESERVE|MEM_COMMIT)) == 0) return NULL; fd=open("/dev/zero", O_RDWR); if(fd<0){ perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: " ); return NULL; } if (type&MEM_RESERVE && (void*)((unsigned long)address&0xffff)) { size += (unsigned long)address&0xffff; address = (LPVOID)((unsigned long)address & ~0xffff); } pgsz = sysconf(_SC_PAGESIZE); if (pgsz > 0) { unsigned long align = (unsigned long)address % (unsigned long)pgsz; if ((type & MEM_COMMIT) && align) { size += align; address = (LPVOID)((unsigned char *)address - align); } } if (type&MEM_RESERVE && size<0x10000) size = 0x10000; if (size%pgsz) size += pgsz - size%pgsz; if(address!=0) { //check whether we can allow to allocate this virt_alloc* str=vm; while(str) { if((void*)((unsigned long)address)>=(void*)((unsigned long)str->address+str->mapping_size)) { str=str->prev; continue; } if((void*)((unsigned long)address+size)<=(void*)((unsigned long)str->address)) { str=str->prev; continue; } if(str->state==0) { #warning FIXME if( (address >= (void*)(unsigned long)str->address) && ((void*)((unsigned long)address+size)<=(void*)((unsigned long)str->address+str->mapping_size)) && (type & MEM_COMMIT)) { close(fd); return address; //returning previously reserved memory } } close(fd); return NULL; } } answer=mmap(address, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); // answer=FILE_dommap(-1, address, 0, size, 0, 0, // PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); close(fd); if (answer != (void *)-1 && address && answer != address) { /* It is dangerous to try mmap() with MAP_FIXED since it does not always detect conflicts or non-allocation and chaos ensues after a successful call but an overlapping or non-allocated region. */ munmap(answer, size); answer = (void *) -1; errno = EINVAL; } if(answer==(void*)-1) { return NULL; } else { virt_alloc *new_vm=malloc(sizeof(virt_alloc)); new_vm->mapping_size=size; new_vm->address=answer; new_vm->prev=vm; if(type == MEM_RESERVE) new_vm->state=0; else new_vm->state=1; if(vm) vm->next=new_vm; vm=new_vm; vm->next=0; //if(va_size!=0) // printf("Multiple VirtualAlloc!\n"); //printf("answer=0x%08x\n", answer); return answer; } } WIN_BOOL WINAPI VirtualFree(LPVOID address, SIZE_T dwSize, DWORD dwFreeType)//not sure { virt_alloc* str=vm; int answer; (void)dwSize; (void)dwFreeType; while(str) { if(address!=str->address) { str=str->prev; continue; } //printf("VirtualFree(0x%08X, %d - %d)\n", str->address, dwSize, str->mapping_size); answer=munmap(str->address, str->mapping_size); if(str->next)str->next->prev=str->prev; if(str->prev)str->prev->next=str->next; if(vm==str)vm=str->prev; free(str); return 0; } return -1; } INT WINAPI WideCharToMultiByte(UINT codepage, DWORD flags, LPCWSTR src, INT srclen,LPSTR dest, INT destlen, LPCSTR defch, WIN_BOOL* used_defch) { int i; (void)codepage; (void)flags; (void)defch; if(src==0) return 0; if ((srclen==-1)&&(dest==0)) return 0; if(srclen==-1){srclen=0; while(src[srclen++]);} // for(i=0; i<srclen; i++) // printf("%c", src[i]); // printf("\n"); if(dest==0) { for(i=0; i<srclen; i++) { src++; if(*src==0) return i+1; } return srclen+1; } if(used_defch) *used_defch=0; for(i=0; i<min(srclen, destlen); i++) { *dest=(char)*src; dest++; src++; if(*src==0) return i+1; } return min(srclen, destlen); } INT WINAPI MultiByteToWideChar(UINT codepage,DWORD flags, LPCSTR src, INT srclen, LPWSTR dest, INT destlen) { (void)codepage; (void)flags; (void)src; (void)srclen; (void)dest; (void)destlen; return 0; } HANDLE WINAPI OpenFileMappingA(DWORD access, WIN_BOOL prot, LPCSTR name) { file_mapping* p; (void)access; (void)prot; if(fm==0) return (HANDLE)0; if(name==0) return (HANDLE)0; for(p=fm; p; p=p->prev) { if(p->name==0) continue; if(strcmp(p->name, name)==0) return (HANDLE)p->handle; } return 0; } �����������������������������������xine-lib-1.2/src/libw32dll/wine/mmreg.h�������������������������������������������������������������0000644�0001750�0001750�00000032471�14647725152�015502� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mmreg.h - Declarations for ??? */ #ifndef __WINE_MMREG_H #define __WINE_MMREG_H /*********************************************************************** * Defines/Enums */ #ifndef _ACM_WAVEFILTER #define _ACM_WAVEFILTER #include "windef.h" #define WAVE_FILTER_UNKNOWN 0x0000 #define WAVE_FILTER_DEVELOPMENT 0xFFFF typedef struct __attribute__((__packed__)) _WAVEFILTER { DWORD cbStruct; DWORD dwFilterTag; DWORD fdwFilter; DWORD dwReserved[5]; } WAVEFILTER, *PWAVEFILTER, *NPWAVEFILTER, *LPWAVEFILTER; #endif /* _ACM_WAVEFILTER */ #ifndef WAVE_FILTER_VOLUME #define WAVE_FILTER_VOLUME 0x0001 typedef struct __attribute__((__packed__)) _WAVEFILTER_VOLUME { WAVEFILTER wfltr; DWORD dwVolume; } VOLUMEWAVEFILTER, *PVOLUMEWAVEFILTER, *NPVOLUMEWAVEFILTER, *LPVOLUMEWAVEFILTER; #endif /* WAVE_FILTER_VOLUME */ #ifndef WAVE_FILTER_ECHO #define WAVE_FILTER_ECHO 0x0002 typedef struct __attribute__((__packed__)) WAVEFILTER_ECHO { WAVEFILTER wfltr; DWORD dwVolume; DWORD dwDelay; } ECHOWAVEFILTER, *PECHOWAVEFILTER, *NPECHOWAVEFILTER, *LPECHOWAVEFILTER; #endif /* WAVEFILTER_ECHO */ #ifndef _WAVEFORMATEX_ #define _WAVEFORMATEX_ typedef struct __attribute__((__packed__)) _WAVEFORMATEX { WORD wFormatTag; WORD nChannels; DWORD nSamplesPerSec; DWORD nAvgBytesPerSec; WORD nBlockAlign; WORD wBitsPerSample; WORD cbSize; } WAVEFORMATEX, *PWAVEFORMATEX, *NPWAVEFORMATEX, *LPWAVEFORMATEX; #endif /* _WAVEFORMATEX_ */ #ifndef GUID_TYPE #define GUID_TYPE typedef struct { unsigned long f1; unsigned short f2; unsigned short f3; unsigned char f4[8]; } GUID; #endif #ifndef _WAVEFORMATEXTENSIBLE_ #define _WAVEFORMATEXTENSIBLE_ typedef struct { WAVEFORMATEX Format; union { WORD wValidBitsPerSample; /* bits of precision */ WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */ WORD wReserved; /* If neither applies, set to zero. */ } Samples; DWORD dwChannelMask; /* which channels are */ /* present in stream */ GUID SubFormat; } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; #endif // !_WAVEFORMATEXTENSIBLE_ typedef struct mpeglayer3waveformat_tag { WORD wFormatTag WINE_PACKED; WORD nChannels WINE_PACKED; DWORD nSamplesPerSec WINE_PACKED; DWORD nAvgBytesPerSec WINE_PACKED; WORD nBlockAlign WINE_PACKED; WORD wBitsPerSample WINE_PACKED; WORD cbSize WINE_PACKED; WORD wID WINE_PACKED; DWORD fdwFlags WINE_PACKED; WORD nBlockSize WINE_PACKED; WORD nFramesPerBlock WINE_PACKED; WORD nCodecDelay WINE_PACKED; } MPEGLAYER3WAVEFORMAT; /* WAVE form wFormatTag IDs */ #define WAVE_FORMAT_UNKNOWN 0x0000 /* Microsoft Corporation */ #define WAVE_FORMAT_ADPCM 0x0002 /* Microsoft Corporation */ #define WAVE_FORMAT_IEEE_FLOAT 0x0003 /* Microsoft Corporation */ #define WAVE_FORMAT_VSELP 0x0004 /* Compaq Computer Corp. */ #define WAVE_FORMAT_IBM_CVSD 0x0005 /* IBM Corporation */ #define WAVE_FORMAT_ALAW 0x0006 /* Microsoft Corporation */ #define WAVE_FORMAT_MULAW 0x0007 /* Microsoft Corporation */ #define WAVE_FORMAT_DTS 0x0008 /* Microsoft Corporation */ #define WAVE_FORMAT_OKI_ADPCM 0x0010 /* OKI */ #define WAVE_FORMAT_DVI_ADPCM 0x0011 /* Intel Corporation */ #define WAVE_FORMAT_IMA_ADPCM (WAVE_FORMAT_DVI_ADPCM) /* Intel Corporation */ #define WAVE_FORMAT_MEDIASPACE_ADPCM 0x0012 /* Videologic */ #define WAVE_FORMAT_SIERRA_ADPCM 0x0013 /* Sierra Semiconductor Corp */ #define WAVE_FORMAT_G723_ADPCM 0x0014 /* Antex Electronics Corporation */ #define WAVE_FORMAT_DIGISTD 0x0015 /* DSP Solutions, Inc. */ #define WAVE_FORMAT_DIGIFIX 0x0016 /* DSP Solutions, Inc. */ #define WAVE_FORMAT_DIALOGIC_OKI_ADPCM 0x0017 /* Dialogic Corporation */ #define WAVE_FORMAT_MEDIAVISION_ADPCM 0x0018 /* Media Vision, Inc. */ #define WAVE_FORMAT_CU_CODEC 0x0019 /* Hewlett-Packard Company */ #define WAVE_FORMAT_YAMAHA_ADPCM 0x0020 /* Yamaha Corporation of America */ #define WAVE_FORMAT_SONARC 0x0021 /* Speech Compression */ #define WAVE_FORMAT_DSPGROUP_TRUESPEECH 0x0022 /* DSP Group, Inc */ #define WAVE_FORMAT_ECHOSC1 0x0023 /* Echo Speech Corporation */ #define WAVE_FORMAT_AUDIOFILE_AF36 0x0024 /* Virtual Music, Inc. */ #define WAVE_FORMAT_APTX 0x0025 /* Audio Processing Technology */ #define WAVE_FORMAT_AUDIOFILE_AF10 0x0026 /* Virtual Music, Inc. */ #define WAVE_FORMAT_PROSODY_1612 0x0027 /* Aculab plc */ #define WAVE_FORMAT_LRC 0x0028 /* Merging Technologies S.A. */ #define WAVE_FORMAT_DOLBY_AC2 0x0030 /* Dolby Laboratories */ #define WAVE_FORMAT_GSM610 0x0031 /* Microsoft Corporation */ #define WAVE_FORMAT_MSNAUDIO 0x0032 /* Microsoft Corporation */ #define WAVE_FORMAT_ANTEX_ADPCME 0x0033 /* Antex Electronics Corporation */ #define WAVE_FORMAT_CONTROL_RES_VQLPC 0x0034 /* Control Resources Limited */ #define WAVE_FORMAT_DIGIREAL 0x0035 /* DSP Solutions, Inc. */ #define WAVE_FORMAT_DIGIADPCM 0x0036 /* DSP Solutions, Inc. */ #define WAVE_FORMAT_CONTROL_RES_CR10 0x0037 /* Control Resources Limited */ #define WAVE_FORMAT_NMS_VBXADPCM 0x0038 /* Natural MicroSystems */ #define WAVE_FORMAT_CS_IMAADPCM 0x0039 /* Crystal Semiconductor IMA ADPCM */ #define WAVE_FORMAT_ECHOSC3 0x003A /* Echo Speech Corporation */ #define WAVE_FORMAT_ROCKWELL_ADPCM 0x003B /* Rockwell International */ #define WAVE_FORMAT_ROCKWELL_DIGITALK 0x003C /* Rockwell International */ #define WAVE_FORMAT_XEBEC 0x003D /* Xebec Multimedia Solutions Limited */ #define WAVE_FORMAT_G721_ADPCM 0x0040 /* Antex Electronics Corporation */ #define WAVE_FORMAT_G728_CELP 0x0041 /* Antex Electronics Corporation */ #define WAVE_FORMAT_MSG723 0x0042 /* Microsoft Corporation */ #define WAVE_FORMAT_MPEG 0x0050 /* Microsoft Corporation */ #define WAVE_FORMAT_RT24 0x0052 /* InSoft, Inc. */ #define WAVE_FORMAT_PAC 0x0053 /* InSoft, Inc. */ #define WAVE_FORMAT_MPEGLAYER3 0x0055 /* ISO/MPEG Layer3 Format Tag */ #define WAVE_FORMAT_LUCENT_G723 0x0059 /* Lucent Technologies */ #define WAVE_FORMAT_CIRRUS 0x0060 /* Cirrus Logic */ #define WAVE_FORMAT_ESPCM 0x0061 /* ESS Technology */ #define WAVE_FORMAT_VOXWARE 0x0062 /* Voxware Inc */ #define WAVE_FORMAT_CANOPUS_ATRAC 0x0063 /* Canopus, co., Ltd. */ #define WAVE_FORMAT_G726_ADPCM 0x0064 /* APICOM */ #define WAVE_FORMAT_G722_ADPCM 0x0065 /* APICOM */ #define WAVE_FORMAT_DSAT_DISPLAY 0x0067 /* Microsoft Corporation */ #define WAVE_FORMAT_VOXWARE_BYTE_ALIGNED 0x0069 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_AC8 0x0070 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_AC10 0x0071 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_AC16 0x0072 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_AC20 0x0073 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_RT24 0x0074 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_RT29 0x0075 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_RT29HW 0x0076 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_VR12 0x0077 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_VR18 0x0078 /* Voxware Inc */ #define WAVE_FORMAT_VOXWARE_TQ40 0x0079 /* Voxware Inc */ #define WAVE_FORMAT_SOFTSOUND 0x0080 /* Softsound, Ltd. */ #define WAVE_FORMAT_VOXWARE_TQ60 0x0081 /* Voxware Inc */ #define WAVE_FORMAT_MSRT24 0x0082 /* Microsoft Corporation */ #define WAVE_FORMAT_G729A 0x0083 /* AT&T Labs, Inc. */ #define WAVE_FORMAT_MVI_MVI2 0x0084 /* Motion Pixels */ #define WAVE_FORMAT_DF_G726 0x0085 /* DataFusion Systems (Pty) (Ltd) */ #define WAVE_FORMAT_DF_GSM610 0x0086 /* DataFusion Systems (Pty) (Ltd) */ #define WAVE_FORMAT_ISIAUDIO 0x0088 /* Iterated Systems, Inc. */ #define WAVE_FORMAT_ONLIVE 0x0089 /* OnLive! Technologies, Inc. */ #define WAVE_FORMAT_SBC24 0x0091 /* Siemens Business Communications Sys */ #define WAVE_FORMAT_DOLBY_AC3_SPDIF 0x0092 /* Sonic Foundry */ #define WAVE_FORMAT_MEDIASONIC_G723 0x0093 /* MediaSonic */ #define WAVE_FORMAT_PROSODY_8KBPS 0x0094 /* Aculab plc */ #define WAVE_FORMAT_ZYXEL_ADPCM 0x0097 /* ZyXEL Communications, Inc. */ #define WAVE_FORMAT_PHILIPS_LPCBB 0x0098 /* Philips Speech Processing */ #define WAVE_FORMAT_PACKED 0x0099 /* Studer Professional Audio AG */ #define WAVE_FORMAT_MALDEN_PHONYTALK 0x00A0 /* Malden Electronics Ltd. */ #define WAVE_FORMAT_RHETOREX_ADPCM 0x0100 /* Rhetorex Inc. */ #define WAVE_FORMAT_IRAT 0x0101 /* BeCubed Software Inc. */ #define WAVE_FORMAT_VIVO_G723 0x0111 /* Vivo Software */ #define WAVE_FORMAT_VIVO_SIREN 0x0112 /* Vivo Software */ #define WAVE_FORMAT_DIGITAL_G723 0x0123 /* Digital Equipment Corporation */ #define WAVE_FORMAT_SANYO_LD_ADPCM 0x0125 /* Sanyo Electric Co., Ltd. */ #define WAVE_FORMAT_SIPROLAB_ACEPLNET 0x0130 /* Sipro Lab Telecom Inc. */ #define WAVE_FORMAT_SIPROLAB_ACELP4800 0x0131 /* Sipro Lab Telecom Inc. */ #define WAVE_FORMAT_SIPROLAB_ACELP8V3 0x0132 /* Sipro Lab Telecom Inc. */ #define WAVE_FORMAT_SIPROLAB_G729 0x0133 /* Sipro Lab Telecom Inc. */ #define WAVE_FORMAT_SIPROLAB_G729A 0x0134 /* Sipro Lab Telecom Inc. */ #define WAVE_FORMAT_SIPROLAB_KELVIN 0x0135 /* Sipro Lab Telecom Inc. */ #define WAVE_FORMAT_G726ADPCM 0x0140 /* Dictaphone Corporation */ #define WAVE_FORMAT_QUALCOMM_PUREVOICE 0x0150 /* Qualcomm, Inc. */ #define WAVE_FORMAT_QUALCOMM_HALFRATE 0x0151 /* Qualcomm, Inc. */ #define WAVE_FORMAT_TUBGSM 0x0155 /* Ring Zero Systems, Inc. */ #define WAVE_FORMAT_MSAUDIO1 0x0160 /* Microsoft Corporation */ #define WAVE_FORMAT_CREATIVE_ADPCM 0x0200 /* Creative Labs, Inc */ #define WAVE_FORMAT_CREATIVE_FASTSPEECH8 0x0202 /* Creative Labs, Inc */ #define WAVE_FORMAT_CREATIVE_FASTSPEECH10 0x0203 /* Creative Labs, Inc */ #define WAVE_FORMAT_UHER_ADPCM 0x0210 /* UHER informatic GmbH */ #define WAVE_FORMAT_QUARTERDECK 0x0220 /* Quarterdeck Corporation */ #define WAVE_FORMAT_ILINK_VC 0x0230 /* I-link Worldwide */ #define WAVE_FORMAT_RAW_SPORT 0x0240 /* Aureal Semiconductor */ #define WAVE_FORMAT_IPI_HSX 0x0250 /* Interactive Products, Inc. */ #define WAVE_FORMAT_IPI_RPELP 0x0251 /* Interactive Products, Inc. */ #define WAVE_FORMAT_CS2 0x0260 /* Consistent Software */ #define WAVE_FORMAT_SONY_SCX 0x0270 /* Sony Corp. */ #define WAVE_FORMAT_FM_TOWNS_SND 0x0300 /* Fujitsu Corp. */ #define WAVE_FORMAT_BTV_DIGITAL 0x0400 /* Brooktree Corporation */ #define WAVE_FORMAT_QDESIGN_MUSIC 0x0450 /* QDesign Corporation */ #define WAVE_FORMAT_VME_VMPCM 0x0680 /* AT&T Labs, Inc. */ #define WAVE_FORMAT_TPC 0x0681 /* AT&T Labs, Inc. */ #define WAVE_FORMAT_OLIGSM 0x1000 /* Ing C. Olivetti & C., S.p.A. */ #define WAVE_FORMAT_OLIADPCM 0x1001 /* Ing C. Olivetti & C., S.p.A. */ #define WAVE_FORMAT_OLICELP 0x1002 /* Ing C. Olivetti & C., S.p.A. */ #define WAVE_FORMAT_OLISBC 0x1003 /* Ing C. Olivetti & C., S.p.A. */ #define WAVE_FORMAT_OLIOPR 0x1004 /* Ing C. Olivetti & C., S.p.A. */ #define WAVE_FORMAT_LH_CODEC 0x1100 /* Lernout & Hauspie */ #define WAVE_FORMAT_NORRIS 0x1400 /* Norris Communications, Inc. */ #define WAVE_FORMAT_SOUNDSPACE_MUSICOMPRESS 0x1500 /* AT&T Labs, Inc. */ #define WAVE_FORMAT_DVM 0x2000 /* FAST Multimedia AG */ #if !defined(WAVE_FORMAT_EXTENSIBLE) #define WAVE_FORMAT_EXTENSIBLE 0xFFFE /* Microsoft */ #endif // !defined(WAVE_FORMAT_EXTENSIBLE) // // the WAVE_FORMAT_DEVELOPMENT format tag can be used during the // development phase of a new wave format. Before shipping, you MUST // acquire an official format tag from Microsoft. // #define WAVE_FORMAT_DEVELOPMENT (0xFFFF) #endif /* __WINE_MMREG_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/resource.c����������������������������������������������������������0000644�0001750�0001750�00000030615�14647725152�016213� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Resources * * Copyright 1993 Robert J. Amstadt * Copyright 1995 Alexandre Julliard */ #include "config.h" #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include "winbase.h" #include "windef.h" #include "winuser.h" #include "heap.h" #include "module.h" #include "debugtools.h" #include "winerror.h" #include "loader.h" #include "ext.h" #define CP_ACP 0 WORD WINE_LanguageId=0x409;//english #define HRSRC_MAP_BLOCKSIZE 16 typedef struct _HRSRC_ELEM { HANDLE hRsrc; WORD type; } HRSRC_ELEM; typedef struct _HRSRC_MAP { int nAlloc; int nUsed; HRSRC_ELEM *elem; } HRSRC_MAP; static HRSRC RES_FindResource2( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang, int unicode) { HRSRC hRsrc = 0; LPWSTR typeStr, nameStr; WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); if(!wm) return 0; /* 32-bit PE module */ if ( HIWORD( type ) && (!unicode)) typeStr = HEAP_strdupAtoW( GetProcessHeap(), 0, type ); else typeStr = (LPWSTR)type; if ( HIWORD( name ) && (!unicode)) nameStr = HEAP_strdupAtoW( GetProcessHeap(), 0, name ); else nameStr = (LPWSTR)name; hRsrc = PE_FindResourceExW( wm, nameStr, typeStr, lang ); if ( HIWORD( type ) && (!unicode)) HeapFree( GetProcessHeap(), 0, typeStr ); if ( HIWORD( name ) && (!unicode)) HeapFree( GetProcessHeap(), 0, nameStr ); return hRsrc; } /********************************************************************** * RES_FindResource */ static HRSRC RES_FindResource( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang, int unicode ) { HRSRC hRsrc; // __TRY // { hRsrc = RES_FindResource2(hModule, type, name, lang, unicode); // } // __EXCEPT(page_fault) // { // WARN("page fault\n"); // SetLastError(ERROR_INVALID_PARAMETER); // return 0; // } // __ENDTRY return hRsrc; } /********************************************************************** * RES_SizeofResource */ static DWORD RES_SizeofResource( HMODULE hModule, HRSRC hRsrc) { DWORD size = 0; // HRSRC hRsrc32; // // HMODULE16 hMod16 = MapHModuleLS( hModule ); // NE_MODULE *pModule = NE_GetPtr( hMod16 ); // WINE_MODREF *wm = pModule && pModule->module32? // MODULE32_LookupHMODULE( pModule->module32 ) : NULL; // WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); if ( !hModule || !hRsrc ) return 0; /* 32-bit PE module */ /* If we got a 16-bit hRsrc, convert it */ // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); if(!HIWORD(hRsrc)) { printf("16-bit hRsrcs not supported\n"); return 0; } size = PE_SizeofResource( hModule, hRsrc ); return size; } /********************************************************************** * RES_AccessResource */ static HFILE RES_AccessResource( HMODULE hModule, HRSRC hRsrc ) { HFILE hFile = HFILE_ERROR; // WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); if ( !hModule || !hRsrc ) return HFILE_ERROR; /* 32-bit PE module */ FIXME("32-bit modules not yet supported.\n" ); hFile = HFILE_ERROR; return hFile; } /********************************************************************** * RES_LoadResource */ static HGLOBAL RES_LoadResource( HMODULE hModule, HRSRC hRsrc) { HGLOBAL hMem = 0; // HRSRC hRsrc32; WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); if ( !hModule || !hRsrc ) return 0; /* 32-bit PE module */ /* If we got a 16-bit hRsrc, convert it */ // hRsrc32 = HIWORD(hRsrc)? hRsrc : MapHRsrc16To32( pModule, hRsrc ); if(!HIWORD(hRsrc)) { printf("16-bit hRsrcs not supported\n"); return 0; } hMem = PE_LoadResource( wm, hRsrc ); return hMem; } /********************************************************************** * RES_LockResource */ static LPVOID RES_LockResource( HGLOBAL handle ) { LPVOID bits = NULL; TRACE("(%08x, %s)\n", handle, "PE" ); bits = (LPVOID)handle; return bits; } /********************************************************************** * RES_FreeResource */ static WIN_BOOL RES_FreeResource( HGLOBAL handle ) { HGLOBAL retv = handle; return (WIN_BOOL)retv; } /********************************************************************** * FindResourceA (KERNEL32.128) */ HANDLE WINAPI FindResourceA( HMODULE hModule, LPCSTR name, LPCSTR type ) { return RES_FindResource( hModule, type, name, WINE_LanguageId, 0); } HANDLE WINAPI FindResourceW( HMODULE hModule, LPCWSTR name, LPCWSTR type ) { return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, WINE_LanguageId, 1); } /********************************************************************** * FindResourceExA (KERNEL32.129) */ HANDLE WINAPI FindResourceExA( HMODULE hModule, LPCSTR type, LPCSTR name, WORD lang ) { return RES_FindResource( hModule, type, name, lang, 0 ); } HANDLE WINAPI FindResourceExW( HMODULE hModule, LPCWSTR type, LPCWSTR name, WORD lang ) { return RES_FindResource( hModule, (LPCSTR)type, (LPCSTR)name, lang, 1 ); } /********************************************************************** * LockResource (KERNEL32.384) */ LPVOID WINAPI LockResource( HGLOBAL handle ) { return RES_LockResource( handle ); } /********************************************************************** * FreeResource (KERNEL32.145) */ WIN_BOOL WINAPI FreeResource( HGLOBAL handle ) { return RES_FreeResource( handle ); } /********************************************************************** * AccessResource (KERNEL32.64) */ INT WINAPI AccessResource( HMODULE hModule, HRSRC hRsrc ) { return RES_AccessResource( hModule, hRsrc ); } /********************************************************************** * SizeofResource (KERNEL32.522) */ DWORD WINAPI SizeofResource( HINSTANCE hModule, HRSRC hRsrc ) { return RES_SizeofResource( hModule, hRsrc ); } INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen ); /********************************************************************** * LoadStringA (USER32.375) */ INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen ) { INT retval; INT wbuflen; INT abuflen; LPWSTR wbuf = NULL; LPSTR abuf = NULL; if ( buffer != NULL && buflen > 0 ) *buffer = 0; wbuflen = LoadStringW(instance,resource_id,NULL,0); if ( !wbuflen ) return 0; wbuflen ++; retval = 0; wbuf = HeapAlloc( GetProcessHeap(), 0, wbuflen * sizeof(WCHAR) ); wbuflen = LoadStringW(instance,resource_id,wbuf,wbuflen); if ( wbuflen > 0 ) { abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,NULL,0,NULL,NULL); if ( abuflen > 0 ) { if ( buffer == NULL || buflen == 0 ) retval = abuflen; else { abuf = HeapAlloc( GetProcessHeap(), 0, abuflen * sizeof(CHAR) ); abuflen = WideCharToMultiByte(CP_ACP,0,wbuf,wbuflen,abuf,abuflen,NULL,NULL); if ( abuflen > 0 ) { abuflen = min(abuflen,buflen - 1); memcpy( buffer, abuf, abuflen ); buffer[abuflen] = 0; retval = abuflen; } HeapFree( GetProcessHeap(), 0, abuf ); } } } HeapFree( GetProcessHeap(), 0, wbuf ); return retval; } /********************************************************************** * LoadStringW (USER32.376) */ INT WINAPI LoadStringW( HINSTANCE instance, UINT resource_id, LPWSTR buffer, INT buflen ) { HGLOBAL hmem; HRSRC hrsrc; WCHAR *p; int string_num; int i; if (HIWORD(resource_id)==0xFFFF) /* netscape 3 passes this */ resource_id = (UINT)(-((INT)resource_id)); TRACE("instance = %04x, id = %04x, buffer = %08x, " "length = %d\n", instance, (int)resource_id, (int) buffer, buflen); /* Use bits 4 - 19 (incremented by 1) as resourceid, mask out * 20 - 31. */ hrsrc = FindResourceW( instance, (LPCWSTR)(((resource_id>>4)&0xffff)+1), RT_STRINGW ); if (!hrsrc) return 0; hmem = LoadResource( instance, hrsrc ); if (!hmem) return 0; p = LockResource(hmem); string_num = resource_id & 0x000f; for (i = 0; i < string_num; i++) p += *p + 1; TRACE("strlen = %d\n", (int)*p ); if (buffer == NULL) return *p; i = min(buflen - 1, *p); if (i > 0) { memcpy(buffer, p + 1, i * sizeof (WCHAR)); buffer[i] = (WCHAR) 0; } else { if (buflen > 1) { buffer[0] = (WCHAR) 0; return 0; } #if 0 WARN("Dont know why caller give buflen=%d *p=%d trying to obtain string '%s'\n", buflen, *p, p + 1); #endif } TRACE("String loaded !\n"); return i; } /* Messages...used by FormatMessage32* (KERNEL32.something) * * They can be specified either directly or using a message ID and * loading them from the resource. * * The resourcedata has following format: * start: * 0: DWORD nrofentries * nrofentries * subentry: * 0: DWORD firstentry * 4: DWORD lastentry * 8: DWORD offset from start to the stringentries * * (lastentry-firstentry) * stringentry: * 0: WORD len (0 marks end) * 2: WORD flags * 4: CHAR[len-4] * (stringentry i of a subentry refers to the ID 'firstentry+i') * * Yes, ANSI strings in win32 resources. Go figure. */ /********************************************************************** * LoadMessageA (internal) */ INT WINAPI LoadMessageA( HMODULE instance, UINT id, WORD lang, LPSTR buffer, INT buflen ) { HGLOBAL hmem; HRSRC hrsrc; PMESSAGE_RESOURCE_DATA mrd; PMESSAGE_RESOURCE_BLOCK mrb; PMESSAGE_RESOURCE_ENTRY mre; int i,slen; TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen); /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/ hrsrc = FindResourceExW(instance,RT_MESSAGELISTW,(LPWSTR)1,lang); if (!hrsrc) return 0; hmem = LoadResource( instance, hrsrc ); if (!hmem) return 0; mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem); mre = NULL; mrb = &(mrd->Blocks[0]); for (i=mrd->NumberOfBlocks;i--;) { if ((id>=mrb->LowId) && (id<=mrb->HighId)) { mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries); id -= mrb->LowId; break; } mrb++; } if (!mre) return 0; for (i=id;i--;) { if (!mre->Length) return 0; mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+(mre->Length)); } slen=mre->Length; TRACE(" - strlen=%d\n",slen); i = min(buflen - 1, slen); if (buffer == NULL) return slen; if (i>0) { lstrcpynA(buffer,(char*)mre->Text,i); buffer[i]=0; } else { if (buflen>1) { buffer[0]=0; return 0; } } if (buffer) TRACE("'%s' copied !\n", buffer); return i; } /********************************************************************** * EnumResourceTypesA (KERNEL32.90) */ WIN_BOOL WINAPI EnumResourceTypesA( HMODULE hmodule,ENUMRESTYPEPROCA lpfun, LONG lParam) { /* FIXME: move WINE_MODREF stuff here */ return PE_EnumResourceTypesA(hmodule,lpfun,lParam); } /********************************************************************** * EnumResourceNamesA (KERNEL32.88) */ WIN_BOOL WINAPI EnumResourceNamesA( HMODULE hmodule, LPCSTR type, ENUMRESNAMEPROCA lpfun, LONG lParam ) { /* FIXME: move WINE_MODREF stuff here */ return PE_EnumResourceNamesA(hmodule,type,lpfun,lParam); } /********************************************************************** * EnumResourceLanguagesA (KERNEL32.86) */ WIN_BOOL WINAPI EnumResourceLanguagesA( HMODULE hmodule, LPCSTR type, LPCSTR name, ENUMRESLANGPROCA lpfun, LONG lParam) { /* FIXME: move WINE_MODREF stuff here */ return PE_EnumResourceLanguagesA(hmodule,type,name,lpfun,lParam); } /********************************************************************** * LoadResource (KERNEL32.370) */ HGLOBAL WINAPI LoadResource( HINSTANCE hModule, HRSRC hRsrc ) { return RES_LoadResource( hModule, hRsrc); } �������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/wrapper.h�����������������������������������������������������������0000644�0001750�0001750�00000000476�14647725152�016053� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _WRAPPER_H #define _WRAPPER_H #include <sys/types.h> #if defined(__sun) typedef uint32_t u_int32_t; #endif typedef struct { u_int32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; } reg386_t; extern void (*wrapper_target)(void); extern int wrapper(void); extern int null_call(void); #endif /* _WRAPPER_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/loader.h������������������������������������������������������������0000644�0001750�0001750�00000021350�14647725152�015633� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************** Win32 binary loader interface Copyright 2000 Eugene Kuznetsov (divx@euro.ru) Shamelessly stolen from Wine project *********************************************************/ #ifndef _LOADER_H #define _LOADER_H #include "windef.h" #include "driver.h" #include "mmreg.h" #include "vfw.h" #include "msacm.h" #ifdef __cplusplus extern "C" { #endif unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename); int _GetPrivateProfileStringA(const char* appname, const char* keyname, const char* def_val, char* dest, unsigned int len, const char* filename); int _WritePrivateProfileStringA(const char* appname, const char* keyname, const char* string, const char* filename); /********************************************** MS VFW ( Video For Windows ) interface **********************************************/ long VFWAPIV ICCompress( HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData, LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid, long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality, LPBITMAPINFOHEADER lpbiPrev,void* lpPrev ); long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits); WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo); LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb); HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode); HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler); LRESULT VFWAPI ICClose(HIC hic); LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2); HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags); int VFWAPI ICDoSomething(); #define ICCompressGetFormat(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic,ICM_COMPRESS_GET_FORMAT,(long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressGetFormatSize(hic,lpbi) ICCompressGetFormat(hic,lpbi,NULL) #define ICGetDefaultKeyFrameRate(hic,lpint) \ ICSendMessage( \ hic, ICM_GETDEFAULTKEYFRAMERATE, \ (long)(void*)(lpint), \ 0 ) #define ICGetDefaultQuality(hic,lpint) \ ICSendMessage( \ hic, ICM_GETDEFAULTQUALITY, \ (long)(void*)(lpint), \ 0 ) #define ICCompressBegin(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_COMPRESS_BEGIN, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressGetSize(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_COMPRESS_GET_SIZE, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressQuery(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_COMPRESS_QUERY, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressEnd(hic) ICSendMessage(hic, ICM_COMPRESS_END, 0, 0) #define ICDecompressBegin(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_DECOMPRESS_BEGIN, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICDecompressQuery(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic,ICM_DECOMPRESS_QUERY, (long)(void*)(lpbiInput), \ (long) (void*)(lpbiOutput) \ ) #define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput) \ ((long)ICSendMessage( \ hic,ICM_DECOMPRESS_GET_FORMAT, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ )) #define ICDecompressGetFormatSize(hic, lpbi) \ ICDecompressGetFormat(hic, lpbi, NULL) #define ICDecompressGetPalette(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_DECOMPRESS_GET_PALETTE, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICDecompressSetPalette(hic,lpbiPalette) \ ICSendMessage( \ hic,ICM_DECOMPRESS_SET_PALETTE, \ (long)(void*)(lpbiPalette),0 \ ) #define ICDecompressEnd(hic) ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0) /***************************************************** MS ACM ( Audio Compression Manager ) interface ******************************************************/ MMRESULT WINAPI acmDriverAddA( PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd ); MMRESULT WINAPI acmDriverAddW( PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd ); MMRESULT WINAPI acmDriverClose( HACMDRIVER had, DWORD fdwClose ); MMRESULT WINAPI acmDriverDetailsA( HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails ); MMRESULT WINAPI acmDriverDetailsW( HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails ); MMRESULT WINAPI acmDriverEnum( ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmDriverID( HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID ); LRESULT WINAPI acmDriverMessage( HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2 ); MMRESULT WINAPI acmDriverOpen( PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen ); MMRESULT WINAPI acmDriverPriority( HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority ); MMRESULT WINAPI acmDriverRemove( HACMDRIVERID hadid, DWORD fdwRemove ); MMRESULT WINAPI acmFilterChooseA( PACMFILTERCHOOSEA pafltrc ); MMRESULT WINAPI acmFilterChooseW( PACMFILTERCHOOSEW pafltrc ); MMRESULT WINAPI acmFilterDetailsA( HACMDRIVER had, PACMFILTERDETAILSA pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterDetailsW( HACMDRIVER had, PACMFILTERDETAILSW pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterEnumA( HACMDRIVER had, PACMFILTERDETAILSA pafd, ACMFILTERENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFilterEnumW( HACMDRIVER had, PACMFILTERDETAILSW pafd, ACMFILTERENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFilterTagDetailsA( HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterTagDetailsW( HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFilterTagEnumA( HACMDRIVER had, PACMFILTERTAGDETAILSA paftd, ACMFILTERTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFilterTagEnumW( HACMDRIVER had, PACMFILTERTAGDETAILSW paftd, ACMFILTERTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatChooseA( PACMFORMATCHOOSEA pafmtc ); MMRESULT WINAPI acmFormatChooseW( PACMFORMATCHOOSEW pafmtc ); MMRESULT WINAPI acmFormatDetailsA( HACMDRIVER had, PACMFORMATDETAILSA pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatDetailsW( HACMDRIVER had, PACMFORMATDETAILSW pafd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatEnumA( HACMDRIVER had, PACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatEnumW( HACMDRIVER had, PACMFORMATDETAILSW pafd, ACMFORMATENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatSuggest( HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, DWORD cbwfxDst, DWORD fdwSuggest ); MMRESULT WINAPI acmFormatTagDetailsA( HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatTagDetailsW( HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, DWORD fdwDetails ); MMRESULT WINAPI acmFormatTagEnumA( HACMDRIVER had, PACMFORMATTAGDETAILSA paftd, ACMFORMATTAGENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum ); MMRESULT WINAPI acmFormatTagEnumW( HACMDRIVER had, PACMFORMATTAGDETAILSW paftd, ACMFORMATTAGENUMCBW fnCallback, DWORD dwInstance, DWORD fdwEnum ); DWORD WINAPI acmGetVersion( ); MMRESULT WINAPI acmMetrics( HACMOBJ hao, UINT uMetric, LPVOID pMetric ); MMRESULT WINAPI acmStreamClose( HACMSTREAM has, DWORD fdwClose ); MMRESULT WINAPI acmStreamConvert( HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert ); MMRESULT WINAPI acmStreamMessage( HACMSTREAM has, UINT uMsg, LPARAM lParam1, LPARAM lParam2 ); MMRESULT WINAPI acmStreamOpen( PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen ); MMRESULT WINAPI acmStreamPrepareHeader( HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare ); MMRESULT WINAPI acmStreamReset( HACMSTREAM has, DWORD fdwReset ); MMRESULT WINAPI acmStreamSize( HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize ); MMRESULT WINAPI acmStreamUnprepareHeader( HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare ); void MSACM_RegisterAllDrivers(void); INT WINAPI LoadStringA( HINSTANCE instance, UINT resource_id, LPSTR buffer, INT buflen ); #ifdef __cplusplus } #endif #endif /* __LOADER_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/elfdll.c������������������������������������������������������������0000644�0001750�0001750�00000015057�14647725152�015631� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Elf-dll loader functions * * Copyright 1999 Bertho A. Stultiens */ #include "config.h" #ifdef HAVE_LIBDL #include "windef.h" #include "module.h" #include "heap.h" #include "elfdll.h" #include "debugtools.h" #include "winerror.h" #include "ext.h" //DEFAULT_DEBUG_CHANNEL(elfdll) #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <dlfcn.h> //WINE_MODREF *local_wm=NULL; extern modref_list* local_wm; /*------------------ HACKS -----------------*/ extern DWORD fixup_imports(WINE_MODREF *wm); extern void dump_exports(HMODULE hModule); /*---------------- END HACKS ---------------*/ //char *extra_ld_library_path = "/usr/lib/codecs"; struct elfdll_image { HMODULE pe_module_start; DWORD pe_module_size; }; /**************************************************************************** * ELFDLL_dlopen * * Wrapper for dlopen to search the EXTRA_LD_LIBRARY_PATH from wine.conf * manually because libdl.so caches the environment and does not accept our * changes. */ void *ELFDLL_dlopen(const char *libname, int flags) { char buffer[256]; int namelen; void *handle; char *ldpath; /* First try the default path search of dlopen() */ handle = dlopen(libname, flags); if(handle) return handle; /* Now try to construct searches through our extra search-path */ namelen = strlen(libname); ldpath = win32_def_path; while(ldpath && *ldpath) { int len; char *cptr; char *from; from = ldpath; cptr = strchr(ldpath, ':'); if(!cptr) { len = strlen(ldpath); ldpath = NULL; } else { len = cptr - ldpath; ldpath = cptr + 1; } if(len + namelen + 1 >= sizeof(buffer)) { ERR("Buffer overflow! Check EXTRA_LD_LIBRARY_PATH or increase buffer size.\n"); return NULL; } strncpy(buffer, from, len); if(len) { buffer[len] = '/'; strcpy(buffer + len + 1, libname); } else strcpy(buffer + len, libname); TRACE("Trying dlopen('%s', %d)\n", buffer, flags); handle = dlopen(buffer, flags); if(handle) return handle; } return NULL; } /**************************************************************************** * get_sobasename (internal) * */ static LPSTR get_sobasename(LPCSTR path, LPSTR name) { char *cptr; /* Strip the path from the library name */ if((cptr = strrchr(path, '/'))) { char *cp = strrchr(cptr+1, '\\'); if(cp && cp > cptr) cptr = cp; } else cptr = strrchr(path, '\\'); if(!cptr) cptr = (char *)path; /* No '/' nor '\\' in path */ else cptr++; strcpy(name, cptr); cptr = strrchr(name, '.'); if(cptr) *cptr = '\0'; /* Strip extension */ /* Convert to lower case. * This must be done manually because it is not sure that * other modules are accessible. */ for(cptr = name; *cptr; cptr++) *cptr = tolower(*cptr); return name; } /**************************************************************************** * ELFDLL_CreateModref (internal) * * INPUT * hModule - the header from the elf-dll's data-segment * path - requested path from original call * * OUTPUT * A WINE_MODREF pointer to the new object * * BUGS * - Does not handle errors due to dependencies correctly * - path can be wrong */ #define RVA(base, va) (((DWORD)base) + ((DWORD)va)) static WINE_MODREF *ELFDLL_CreateModref(HMODULE hModule, LPCSTR path) { // IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); IMAGE_DATA_DIRECTORY *dir; IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL; WINE_MODREF *wm; int len; HANDLE procheap = GetProcessHeap(); wm = (WINE_MODREF *)HeapAlloc(procheap, HEAP_ZERO_MEMORY, sizeof(*wm)); if(!wm) return NULL; wm->module = hModule; wm->type = MODULE32_ELF; /* FIXME */ // dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; // if(dir->Size) // wm->binfmt.pe.pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(hModule, dir->VirtualAddress); // dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT; // if(dir->Size) // pe_import = wm->binfmt.pe.pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(hModule, dir->VirtualAddress); // dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; // if(dir->Size) // wm->binfmt.pe.pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(hModule, dir->VirtualAddress); wm->filename = malloc(strlen(path)+1); strcpy(wm->filename, path); wm->modname = strrchr( wm->filename, '\\' ); if (!wm->modname) wm->modname = wm->filename; else wm->modname++; /* len = GetShortPathNameA( wm->filename, NULL, 0 ); wm->short_filename = (char *)HeapAlloc( procheap, 0, len+1 ); GetShortPathNameA( wm->filename, wm->short_filename, len+1 ); wm->short_modname = strrchr( wm->short_filename, '\\' ); if (!wm->short_modname) wm->short_modname = wm->short_filename; else wm->short_modname++; */ /* Link MODREF into process list */ // EnterCriticalSection( &PROCESS_Current()->crit_section ); if(local_wm) { local_wm->next=malloc(sizeof(modref_list)); local_wm->next->prev=local_wm; local_wm->next->next=NULL; local_wm->next->wm=wm; local_wm=local_wm->next; } else { local_wm=malloc(sizeof(modref_list)); local_wm->next=local_wm->prev=NULL; local_wm->wm=wm; } // LeaveCriticalSection( &PROCESS_Current()->crit_section ); return wm; } /**************************************************************************** * ELFDLL_LoadLibraryExA (internal) * * Implementation of elf-dll loading for PE modules */ WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR path, DWORD flags) { LPVOID dlhandle; struct elfdll_image *image; char name[129]; char soname[129]; WINE_MODREF *wm; get_sobasename(path, name); strcpy(soname, name); strcat(soname, ".so"); /* Try to open the elf-dll */ dlhandle = ELFDLL_dlopen(soname, RTLD_LAZY); if(!dlhandle) { WARN("Could not load %s (%s)\n", soname, dlerror()); SetLastError( ERROR_FILE_NOT_FOUND ); return NULL; } /* Get the 'dllname_elfdll_image' variable */ /* strcpy(soname, name); strcat(soname, "_elfdll_image"); image = (struct elfdll_image *)dlsym(dlhandle, soname); if(!image) { ERR("Could not get elfdll image descriptor %s (%s)\n", soname, dlerror()); dlclose(dlhandle); SetLastError( ERROR_BAD_FORMAT ); return NULL; } */ wm = ELFDLL_CreateModref((int)dlhandle, path); if(!wm) { ERR("Could not create WINE_MODREF for %s\n", path); dlclose(dlhandle); SetLastError( ERROR_OUTOFMEMORY ); return NULL; } return wm; } /**************************************************************************** * ELFDLL_UnloadLibrary (internal) * * Unload an elf-dll completely from memory and deallocate the modref */ void ELFDLL_UnloadLibrary(WINE_MODREF *wm) { } #endif /*HAVE_LIBDL*/ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/pshpack4.h����������������������������������������������������������0000644�0001750�0001750�00000000751�14647725152�016104� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_PSHPACK_H #define __WINE_PSHPACK_H 4 #if defined(__GNUC__) || defined(__SUNPRO_CC) || defined(__ICC) //#pragma pack(4) #elif defined(__SUNPRO_C) //#pragma pack() #elif !defined(RC_INVOKED) #error "4 as alignment isn't supported by the compiler" #endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ #else /* !defined(__WINE_PSHPACK_H) */ #error "Nested pushing of alignment isn't supported by the compiler" #endif /* !defined(__WINE_PSHPACK_H) */ �����������������������xine-lib-1.2/src/libw32dll/wine/module.c������������������������������������������������������������0000644�0001750�0001750�00000072726�14647725152�015662� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Modules * * Copyright 1995 Alexandre Julliard */ // define for quicktime calls debugging and/or MacOS-level emulation: #define EMU_QTX_API // define for quicktime debugging (verbose logging): //#define DEBUG_QTX_API #include "config.h" #include <assert.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/mman.h> #include <sys/types.h> #include "windef.h" #include "winerror.h" #include "heap.h" #include "module.h" #include "pe_image.h" #include "debugtools.h" #ifdef HAVE_LIBDL #include <dlfcn.h> #include "elfdll.h" #endif #include "win32.h" #include "driver.h" #include "ext.h" #ifdef EMU_QTX_API #include "wrapper.h" int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags); #endif //#undef TRACE //#define TRACE printf //WINE_MODREF *local_wm=NULL; modref_list* local_wm=NULL; HANDLE SegptrHeap; WINE_MODREF* MODULE_FindModule(LPCSTR m) { modref_list* list=local_wm; TRACE("FindModule: Module %s request\n", m); if(list==NULL) return NULL; // while(strcmp(m, list->wm->filename)) while(!strstr(list->wm->filename, m)) { TRACE("%s: %x\n", list->wm->filename, list->wm->module); list=list->prev; if(list==NULL) return NULL; } TRACE("Resolved to %s\n", list->wm->filename); return list->wm; } static void MODULE_RemoveFromList(WINE_MODREF *mod) { modref_list* list=local_wm; if(list==0) return; if(mod==0) return; if((list->prev==NULL)&&(list->next==NULL)) { free(list); local_wm=NULL; // uninstall_fs(); return; } for(;list;list=list->prev) { if(list->wm==mod) { if(list->prev) list->prev->next=list->next; if(list->next) list->next->prev=list->prev; if(list==local_wm) local_wm=list->prev; free(list); return; } } } WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m) { modref_list* list=local_wm; TRACE("LookupHMODULE: Module %X request\n", m); if(list==NULL) { TRACE("LookupHMODULE failed\n"); return NULL; } while(m!=list->wm->module) { // printf("Checking list %X wm %X module %X\n", // list, list->wm, list->wm->module); list=list->prev; if(list==NULL) { TRACE("LookupHMODULE failed\n"); return NULL; } } TRACE("LookupHMODULE hit %p\n", list->wm); return list->wm; } /************************************************************************* * MODULE_InitDll */ static WIN_BOOL MODULE_InitDll( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) { WIN_BOOL retv = TRUE; #ifdef LOG static LPCSTR typeName[] = { "PROCESS_DETACH", "PROCESS_ATTACH", "THREAD_ATTACH", "THREAD_DETACH" }; #endif assert( wm ); /* Skip calls for modules loaded with special load flags */ if ( ( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) || ( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) ) return TRUE; #ifdef LOG TRACE("(%s,%s,%p) - CALL\n", wm->modname, typeName[type], lpReserved ); #else TRACE("(%s,%p) - CALL\n", wm->modname, lpReserved ); #endif /* Call the initialization routine */ switch ( wm->type ) { case MODULE32_PE: retv = PE_InitDLL( wm, type, lpReserved ); break; case MODULE32_ELF: /* no need to do that, dlopen() already does */ break; default: ERR("wine_modref type %d not handled.\n", wm->type ); retv = FALSE; break; } /* The state of the module list may have changed due to the call to PE_InitDLL. We cannot assume that this module has not been deleted. */ #ifdef LOG TRACE("(%p,%s,%p) - RETURN %d\n", wm, typeName[type], lpReserved, retv ); #else TRACE("(%p,%p) - RETURN %d\n", wm, lpReserved, retv ); #endif return retv; } /************************************************************************* * MODULE_DllProcessAttach * * Send the process attach notification to all DLLs the given module * depends on (recursively). This is somewhat complicated due to the fact that * * - we have to respect the module dependencies, i.e. modules implicitly * referenced by another module have to be initialized before the module * itself can be initialized * * - the initialization routine of a DLL can itself call LoadLibrary, * thereby introducing a whole new set of dependencies (even involving * the 'old' modules) at any time during the whole process * * (Note that this routine can be recursively entered not only directly * from itself, but also via LoadLibrary from one of the called initialization * routines.) * * Furthermore, we need to rearrange the main WINE_MODREF list to allow * the process *detach* notifications to be sent in the correct order. * This must not only take into account module dependencies, but also * 'hidden' dependencies created by modules calling LoadLibrary in their * attach notification routine. * * The strategy is rather simple: we move a WINE_MODREF to the head of the * list after the attach notification has returned. This implies that the * detach notifications are called in the reverse of the sequence the attach * notifications *returned*. * * NOTE: Assumes that the process critical section is held! * */ static WIN_BOOL MODULE_DllProcessAttach( WINE_MODREF *wm, LPVOID lpReserved ) { WIN_BOOL retv = TRUE; /* int i; -- not used */ assert( wm ); /* prevent infinite recursion in case of cyclical dependencies */ if ( ( wm->flags & WINE_MODREF_MARKER ) || ( wm->flags & WINE_MODREF_PROCESS_ATTACHED ) ) return retv; TRACE("(%s,%p) - START\n", wm->modname, lpReserved ); /* Tag current MODREF to prevent recursive loop */ wm->flags |= WINE_MODREF_MARKER; /* Recursively attach all DLLs this one depends on */ /* for ( i = 0; retv && i < wm->nDeps; i++ ) if ( wm->deps[i] ) retv = MODULE_DllProcessAttach( wm->deps[i], lpReserved ); */ /* Call DLL entry point */ //local_wm=wm; if(local_wm) { local_wm->next = (modref_list*) malloc(sizeof(modref_list)); local_wm->next->prev=local_wm; local_wm->next->next=NULL; local_wm->next->wm=wm; local_wm=local_wm->next; } else { local_wm = (modref_list*)malloc(sizeof(modref_list)); local_wm->next=local_wm->prev=NULL; local_wm->wm=wm; } /* Remove recursion flag */ wm->flags &= ~WINE_MODREF_MARKER; if ( retv ) { retv = MODULE_InitDll( wm, DLL_PROCESS_ATTACH, lpReserved ); if ( retv ) wm->flags |= WINE_MODREF_PROCESS_ATTACHED; } TRACE("(%s,%p) - END\n", wm->modname, lpReserved ); return retv; } /************************************************************************* * MODULE_DllProcessDetach * * Send DLL process detach notifications. See the comment about calling * sequence at MODULE_DllProcessAttach. Unless the bForceDetach flag * is set, only DLLs with zero refcount are notified. */ static void MODULE_DllProcessDetach( WINE_MODREF* wm, WIN_BOOL bForceDetach, LPVOID lpReserved ) { (void)bForceDetach; // WINE_MODREF *wm=local_wm; /* modref_list* l = local_wm; -- not used */ wm->flags &= ~WINE_MODREF_PROCESS_ATTACHED; MODULE_InitDll( wm, DLL_PROCESS_DETACH, lpReserved ); /* while (l) { modref_list* f = l; l = l->next; free(f); } local_wm = 0;*/ } /*********************************************************************** * MODULE_LoadLibraryExA (internal) * * Load a PE style module according to the load order. * * The HFILE parameter is not used and marked reserved in the SDK. I can * only guess that it should force a file to be mapped, but I rather * ignore the parameter because it would be extremely difficult to * integrate this with different types of module represenations. * */ static WINE_MODREF *MODULE_LoadLibraryExA( LPCSTR libname, HFILE hfile, DWORD flags ) { DWORD err = GetLastError(); WINE_MODREF *pwm; /* int i; -- not used */ // module_loadorder_t *plo; (void)hfile; SetLastError( ERROR_FILE_NOT_FOUND ); TRACE("Trying native dll '%s'\n", libname); pwm = PE_LoadLibraryExA(libname, flags); #ifdef HAVE_LIBDL if(!pwm) { TRACE("Trying ELF dll '%s'\n", libname); pwm=(WINE_MODREF*)ELFDLL_LoadLibraryExA(libname, flags); } #endif // printf("0x%08x\n", pwm); // break; if(pwm) { /* Initialize DLL just loaded */ TRACE("Loaded module '%s' at 0x%08x, \n", libname, pwm->module); /* Set the refCount here so that an attach failure will */ /* decrement the dependencies through the MODULE_FreeLibrary call. */ pwm->refCount++; SetLastError( err ); /* restore last error */ return pwm; } WARN("Failed to load module '%s'; error=0x%08lx, \n", libname, GetLastError()); return NULL; } /*********************************************************************** * MODULE_FreeLibrary * * NOTE: Assumes that the process critical section is held! */ static WIN_BOOL MODULE_FreeLibrary( WINE_MODREF *wm ) { TRACE("(%s) - START\n", wm->modname ); #ifdef USE_MODULE_DecRefCount /* Recursively decrement reference counts */ MODULE_DecRefCount( wm ); #endif /* Call process detach notifications */ MODULE_DllProcessDetach( wm, FALSE, NULL ); PE_UnloadLibrary(wm); TRACE("END\n"); return TRUE; } /*********************************************************************** * LoadLibraryExA (KERNEL32) */ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) { WINE_MODREF *wm = 0; char path[512]; char checked[2000]; int i = -1; checked[0] = 0; if(!libname) { SetLastError(ERROR_INVALID_PARAMETER); return 0; } wm=MODULE_FindModule(libname); if(wm) return wm->module; // if(fs_installed==0) // install_fs(); for (i = 0; !wm && (i < 2); i++) { memset (&path, 0, sizeof (path)); if (i == 0) { /* check just original file name */ strncpy(path, libname, sizeof(path) - 1); } else { /* check default user path */ snprintf(path, sizeof(path), "%s/%s", win32_def_path, libname); } wm = MODULE_LoadLibraryExA( path, hfile, flags ); if (!wm) { if (checked[0]) strcat(checked, ", "); strcat(checked, path); checked[1500] = 0; } } if ( wm ) { if ( !MODULE_DllProcessAttach( wm, NULL ) ) { WARN_(module)("Attach failed for module '%s', \n", libname); MODULE_FreeLibrary(wm); SetLastError(ERROR_DLL_INIT_FAILED); MODULE_RemoveFromList(wm); wm = NULL; } } if (!wm) printf("wine/module: Win32 LoadLibrary failed to load: %s\n", checked); // remove a few divs in the VP codecs that make trouble if (strstr(libname,"vp5vfw.dll") && wm) { int i; if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10003930) { for (i=0;i<3;i++) ((char*)0x10004e86)[i]=0x90; for (i=0;i<3;i++) ((char*)0x10005a23)[i]=0x90; for (i=0;i<3;i++) ((char*)0x10005bff)[i]=0x90; } else { printf("wine/module: Unsupported VP5 version\n"); return 0; } } if (strstr(libname,"vp6vfw.dll") && wm) { int i; if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10003ef0) { // looks like VP 6.1.0.2 for (i=0;i<6;i++) ((char*)0x10007268)[i]=0x90; for (i=0;i<6;i++) ((char*)0x10007e83)[i]=0x90; for (i=0;i<6;i++) ((char*)0x1000806a)[i]=0x90; } else if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10004120) { // looks like VP 6.2.0.10 for (i=0;i<6;i++) ((char*)0x10007688)[i]=0x90; for (i=0;i<6;i++) ((char*)0x100082c3)[i]=0x90; for (i=0;i<6;i++) ((char*)0x100084aa)[i]=0x90; } else if (PE_FindExportedFunction(wm, "DriverProc", TRUE)==(void*)0x10003e70) { // looks like VP 6.0.7.3 for (i=0;i<6;i++) ((char*)0x10007559)[i]=0x90; for (i=0;i<6;i++) ((char*)0x100081c3)[i]=0x90; for (i=0;i<6;i++) ((char*)0x1000839e)[i]=0x90; } else { printf("wine/module: Unsupported VP6 version\n"); return 0; } } if (strstr(libname,"QuickTime.qts") && wm) { void** ptr; void *dispatch_addr; int i; // dispatch_addr = GetProcAddress(wm->module, "theQuickTimeDispatcher", TRUE); dispatch_addr = PE_FindExportedFunction(wm, "theQuickTimeDispatcher", TRUE); if (dispatch_addr == (void *)0x62924c30) { printf ("wine/module: QuickTime5 DLLs found\n"); ptr = (void **)0x62b75ca4; // dispatch_ptr for (i=0;i<5;i++) ((char*)0x6299e842)[i]=0x90; // make_new_region ? for (i=0;i<28;i++) ((char*)0x6299e86d)[i]=0x90; // call__call_CreateCompatibleDC ? for (i=0;i<5;i++) ((char*)0x6299e898)[i]=0x90; // jmp_to_call_loadbitmap ? for (i=0;i<9;i++) ((char*)0x6299e8ac)[i]=0x90; // call__calls_OLE_shit ? for (i=0;i<106;i++) ((char*)0x62a61b10)[i]=0x90; // disable threads #if 0 /* CreateThread callers */ for (i=0;i<5;i++) ((char*)0x629487c5)[i]=0x90; for (i=0;i<5;i++) ((char*)0x6294b275)[i]=0x90; for (i=0;i<5;i++) ((char*)0x629a24b1)[i]=0x90; for (i=0;i<5;i++) ((char*)0x629afc5a)[i]=0x90; for (i=0;i<5;i++) ((char*)0x62af799c)[i]=0x90; for (i=0;i<5;i++) ((char*)0x62af7efe)[i]=0x90; for (i=0;i<5;i++) ((char*)0x62afa33e)[i]=0x90; #endif #if 0 /* TerminateQTML fix */ for (i=0;i<47;i++) ((char*)0x62afa3b8)[i]=0x90; // terminate thread for (i=0;i<47;i++) ((char*)0x62af7f78)[i]=0x90; // terminate thread for (i=0;i<77;i++) ((char*)0x629a13d5)[i]=0x90; ((char *)0x6288e0ae)[0] = 0xc3; // font/dc remover for (i=0;i<24;i++) ((char*)0x6287a1ad)[i]=0x90; // destroy window #endif } else if (dispatch_addr == (void *)0x6693b330) { printf ("wine/module: QuickTime6 DLLs found\n"); ptr = (void **)0x66bb9524; // dispatcher_ptr for (i=0;i<5;i++) ((char *)0x66a730cc)[i]=0x90; // make_new_region for (i=0;i<28;i++) ((char *)0x66a730f7)[i]=0x90; // call__call_CreateCompatibleDC for (i=0;i<5;i++) ((char *)0x66a73122)[i]=0x90; // jmp_to_call_loadbitmap for (i=0;i<9;i++) ((char *)0x66a73131)[i]=0x90; // call__calls_OLE_shit for (i=0;i<96;i++) ((char *)0x66aac852)[i]=0x90; // disable threads } else if (dispatch_addr == (void *)0x6693c3e0) { printf ("wine/module: QuickTime6.3 DLLs found\n"); ptr = (void **)0x66bca01c; // dispatcher_ptr for (i=0;i<5;i++) ((char *)0x66a68f6c)[i]=0x90; // make_new_region for (i=0;i<28;i++) ((char *)0x66a68f97)[i]=0x90; // call__call_CreateCompatibleDC for (i=0;i<5;i++) ((char *)0x66a68fc2)[i]=0x90; // jmp_to_call_loadbitmap for (i=0;i<9;i++) ((char *)0x66a68fd1)[i]=0x90; // call__calls_OLE_shit for (i=0;i<96;i++) ((char *)0x66ab4722)[i]=0x90; // disable threads } else { printf ("wine/module: Unsupported QuickTime version (%p)\n", dispatch_addr); return 0; } printf ("wine/module: QuickTime.qts patched!!! old entry=%p\n",ptr[0]); #ifdef EMU_QTX_API wrapper_target=ptr[0]; ptr[0]=wrapper; #endif } return wm ? wm->module : 0; } /*********************************************************************** * LoadLibraryA (KERNEL32) */ HMODULE WINAPI LoadLibraryA(LPCSTR libname) { return LoadLibraryExA(libname,0,0); } /*********************************************************************** * FreeLibrary */ WIN_BOOL WINAPI FreeLibrary(HINSTANCE hLibModule) { WIN_BOOL retv = FALSE; WINE_MODREF *wm; wm=MODULE32_LookupHMODULE(hLibModule); if ( !wm || !hLibModule ) { SetLastError( ERROR_INVALID_HANDLE ); return 0; } else retv = MODULE_FreeLibrary( wm ); MODULE_RemoveFromList(wm); /* garbage... */ if (local_wm == NULL) my_garbagecollection(); return retv; } #ifdef USE_MODULE_DecRefCount /*********************************************************************** * MODULE_DecRefCount * * NOTE: Assumes that the process critical section is held! */ static void MODULE_DecRefCount( WINE_MODREF *wm ) { int i; if ( wm->flags & WINE_MODREF_MARKER ) return; if ( wm->refCount <= 0 ) return; --wm->refCount; TRACE("(%s) refCount: %d\n", wm->modname, wm->refCount ); if ( wm->refCount == 0 ) { wm->flags |= WINE_MODREF_MARKER; for ( i = 0; i < wm->nDeps; i++ ) if ( wm->deps[i] ) MODULE_DecRefCount( wm->deps[i] ); wm->flags &= ~WINE_MODREF_MARKER; } } #endif /*********************************************************************** * GetProcAddress (KERNEL32.257) */ FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function ) { return MODULE_GetProcAddress( hModule, function, TRUE ); } #ifdef DEBUG_QTX_API struct ComponentParameters { unsigned char flags; /* call modifiers: sync/async, deferred, immed, etc */ unsigned char paramSize; /* size in bytes of actual parameters passed to this call */ short what; /* routine selector, negative for Component management calls */ long params[1]; /* actual parameters for the indicated routine */ }; typedef struct ComponentParameters ComponentParameters; static char* component_func(int what){ switch(what){ case -1: return "kComponentOpenSelect"; case -2: return "kComponentCloseSelect"; case -3: return "kComponentCanDoSelect"; case -4: return "kComponentVersionSelect"; case -5: return "kComponentRegisterSelect"; case -6: return "kComponentTargetSelect"; case -7: return "kComponentUnregisterSelect"; } return "???"; } static char* component_func_type(int type,int what){ if(type==1) switch(what){ case 0: return "kImageCodecGetCodecInfoSelect"; case 1: return "kImageCodecGetCompressionTimeSelect"; case 5: return "kImageCodecPreDecompressSelect"; case 6: return "kImageCodecBandDecompressSelect"; case 0x12: return "kImageCodecDisposeMemorySelect"; case 0x10: return "kImageCodecIsImageDescriptionEquivalentSelect"; case 0x14: return "kImageCodecNewImageBufferMemorySelect"; case 0x28: return "kImageCodecRequestGammaLevelSelect"; } return "???"; } static int c_level=0; static int dump_component(char* name,int type,void* _orig, ComponentParameters *params,void** glob){ int ( *orig)(ComponentParameters *params, void** glob) = _orig; int ret,i; if(params->what<0) fprintf(stderr,"%*sComponentCall: %s flags=0x%X size=%d what=%d %s\n",3*c_level,"",name,params->flags, params->paramSize, params->what, component_func(params->what)); else fprintf(stderr,"%*sComponentCall: %s flags=0x%X size=%d what=0x%X %s\n",3*c_level,"",name,params->flags, params->paramSize, params->what, component_func_type(type,params->what)); for(i=0;i<params->paramSize/4;i++) fprintf(stderr,"%*s param[%d] = 0x%X\n",3*c_level,"",i,params->params[i]); ++c_level; ret=orig(params,glob); --c_level; if(ret>=0x1000) fprintf(stderr,"%*s return=0x%X\n",3*c_level,"",ret); else fprintf(stderr,"%*s return=%d\n",3*c_level,"",ret); return ret; } #define DECL_COMPONENT(sname,name,type) \ static void* real_ ## sname = NULL; \ static int fake_ ## sname(ComponentParameters *params,void** glob){ \ return dump_component(name,type,real_ ## sname, params, glob); \ } #include "qt_comp.h" #undef DECL_COMPONENT #include "qt_fv.h" #endif #ifdef EMU_QTX_API static u_int32_t ret_array[4096]; static int ret_i=0; int report_func(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) { #ifdef DEBUG_QTX_API int i; int* dptr; void* pwrapper=NULL; void* pptr=NULL; char* pname=NULL; int plen=-1; // find the code: dptr=0x62b67ae0;dptr+=2*((reg->eax>>16)&255); // printf("FUNC: flag=%d ptr=%p\n",dptr[0],dptr[1]); if(dptr[0]&255){ dptr=dptr[1];dptr+=4*(reg->eax&65535); // printf("FUNC: ptr2=%p eax=%p edx=%p\n",dptr[1],dptr[0],dptr[2]); pwrapper=dptr[1]; pptr=dptr[0]; plen=dptr[2]; } else { pwrapper=0x62924910; switch(dptr[1]){ case 0x629248d0: dptr=0x62b672c0;dptr+=2*(reg->eax&65535); // printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); pptr=dptr[0]; plen=dptr[1]; break; case 0x62924e40: dptr=0x62b67c70;dptr+=2*(reg->eax&65535); // printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); pptr=dptr[0]; plen=dptr[1]; break; case 0x62924e60: dptr=0x62b68108;if(reg->eax&0x8000) dptr+=2*(reg->eax|0xffff0000); else dptr+=2*(reg->eax&65535); // printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); pptr=dptr[0]; plen=dptr[1]; break; case 0x62924e80: dptr=0x62b68108;if(reg->eax&0x8000) dptr+=2*(reg->eax|0xffff0000); else dptr+=2*(reg->eax&65535); // printf("FUNC: ptr2=%p eax=%p edx=%p\n",0x62924910,dptr[0],dptr[1]); pptr=dptr[0]; plen=dptr[1]; break; default: printf("FUNC: unknown ptr & psize!\n"); pwrapper=dptr[1]; } } for(i=0;qt_fv_list[i].name;i++){ if(qt_fv_list[i].id==reg->eax){ pname=qt_fv_list[i].name; break; } } printf("FUNC[%X/%s]: wrapper=%p func=%p len=%d\n",reg->eax, pname?pname:"???",pwrapper,pptr,plen); printf("FUNC: caller=%p ebx=%p\n",((u_int32_t *)stack_base)[0],reg->ebx); if(pname) printf("%*sENTER(%d): %s(",ret_i*2,"",ret_i,pname); else printf("%*sENTER(%d): %X(",ret_i*2,"",ret_i,reg->eax); for (i=0;i<plen/4;i++){ unsigned int val=((u_int32_t *)stack_base)[1+i]; unsigned char* fcc=&val; printf("%s0x%X", i?", ":"",val); if(fcc[0]>=0x20 && fcc[0]<128 && fcc[1]>=0x20 && fcc[1]<128 && fcc[2]>=0x20 && fcc[2]<128 && fcc[3]>=0x20 && fcc[3]<128) printf("='%c%c%c%c'",fcc[3],fcc[2],fcc[1],fcc[0]); else if(val>=8 && val<65536) printf("=%d",val); } printf(")\n"); fflush(stdout); #else (void)reg; (void)stack_base; #endif #if 1 // emulate some functions: switch(reg->eax){ // memory management: case 0x150011: //NewPtrClear case 0x150012: //NewPtrSysClear reg->eax=(u_int32_t)malloc(((u_int32_t *)stack_base)[1]); memset((void *)reg->eax,0,((u_int32_t *)stack_base)[1]); #ifdef DEBUG_QTX_API printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); #endif return 1; case 0x15000F: //NewPtr case 0x150010: //NewPtrSys reg->eax=(u_int32_t)malloc(((u_int32_t *)stack_base)[1]); #ifdef DEBUG_QTX_API printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); #endif return 1; case 0x15002f: //DisposePtr if(((u_int32_t *)stack_base)[1]>=0x60000000) printf("WARNING! Invalid Ptr handle!\n"); else free((void *)(((u_int32_t *)stack_base)[1])); reg->eax=0; #ifdef DEBUG_QTX_API printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); #endif return 1; // mutexes: case 0x1d0033: //QTMLCreateMutex reg->eax=0xdeadbabe; #ifdef DEBUG_QTX_API printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); #endif return 1; case 0x1d0034: //QTMLDestroyMutex case 0x1d0035: //QTMLGrabMutex case 0x1d0036: //QTMLReturnMutex case 0x1d003d: //QTMLTryGrabMutex reg->eax=0; #ifdef DEBUG_QTX_API printf("%*sLEAVE(%d): EMULATED! 0x%X\n",ret_i*2,"",ret_i, reg->eax); #endif return 1; } #endif #if 0 switch(reg->eax){ // case 0x00010000: // printf("FUNC: ImageCodecInitialize/ImageCodecGetCodecInfo(ci=%p,&icap=%p)\n",((u_int32_t *)stack_base)[1],((u_int32_t *)stack_base)[4]); // break; case 0x00010003: printf("FUNC: CountComponents(&desc=%p)\n",((u_int32_t *)stack_base)[1]); break; case 0x00010004: printf("FUNC: FindNextComponent(prev=%p,&desc=%p)\n",((u_int32_t *)stack_base)[1],((u_int32_t *)stack_base)[2]); break; case 0x00010007: printf("FUNC: OpenComponent(prev=%p)\n",((u_int32_t *)stack_base)[1]); break; case 0x0003008b: printf("FUNC: QTNewGWorldFromPtr(&pts=%p,fourcc=%.4s,&rect=%p,x1=%p,x2=%p,x3=%p,plane=%p,stride=%d)\n", ((u_int32_t *)stack_base)[1], &(((u_int32_t *)stack_base)[2]), ((u_int32_t *)stack_base)[3], ((u_int32_t *)stack_base)[4], ((u_int32_t *)stack_base)[5], ((u_int32_t *)stack_base)[6], ((u_int32_t *)stack_base)[7], ((u_int32_t *)stack_base)[8]); break; case 0x001c0018: printf("FUNC: GetGWorldPixMap(gworld=%p)\n",((u_int32_t *)stack_base)[1]); break; case 0x00110001: printf("FUNC: Gestalt(fourcc=%.4s, &ret=%p)\n",&(((u_int32_t *)stack_base)[1]),((u_int32_t *)stack_base)[2]); break; default: { int i; for(i=0;qt_fv_list[i].name;i++){ if(qt_fv_list[i].id==reg->eax){ printf("FUNC: %s\n",qt_fv_list[i].name); break; } } } } // print stack/reg information printf("ENTER(%d) stack = %d bytes @ %p\n" "eax = 0x%08x edx = 0x%08x ebx = 0x%08x ecx = 0x%08x\n" "esp = 0x%08x ebp = 0x%08x esi = 0x%08x edi = 0x%08x\n" "flags = 0x%08x\n", ret_i, stack_size, stack_base, reg->eax, reg->edx, reg->ebx, reg->ecx, reg->esp, reg->ebp, reg->esi, reg->edi, *flags); #else (void)stack_size; (void)flags; #endif // save ret addr: ret_array[ret_i]=((u_int32_t *)stack_base)[0]; ++ret_i; #if 0 // print first 7 longs in the stack (return address, arg[1], arg[2] ... ) printf("stack[] = { "); for (i=0;i<7;i++) { printf("%08x ", ((u_int32_t *)stack_base)[i]); } printf("}\n\n"); #endif // // mess with function parameters // ((u_int32_t *)stack_base)[1] = 0x66554433; // // mess with return address... // reg->eax = 0x11223344; return 0; } int report_func_ret(void *stack_base, int stack_size, reg386_t *reg, u_int32_t *flags) { #ifdef DEBUG_QTX_API int i; short err; #endif // restore ret addr: --ret_i; ((u_int32_t *)stack_base)[0]=ret_array[ret_i]; #ifdef DEBUG_QTX_API # if 1 (void)stack_size; (void)flags; printf("%*sLEAVE(%d): 0x%X",ret_i*2,"",ret_i, reg->eax); err=reg->eax; if(err && (reg->eax>>16)==0) printf(" = %d",err); printf("\n"); fflush(stdout); # else // print stack/reg information printf("LEAVE(%d) stack = %d bytes @ %p\n" "eax = 0x%08x edx = 0x%08x ebx = 0x%08x ecx = 0x%08x\n" "esp = 0x%08x ebp = 0x%08x esi = 0x%08x edi = 0x%08x\n" "flags = 0x%08x\n", ret_i, stack_size, stack_base, reg->eax, reg->edx, reg->ebx, reg->ecx, reg->esp, reg->ebp, reg->esi, reg->edi, *flags); # endif # if 0 // print first 7 longs in the stack (return address, arg[1], arg[2] ... ) printf("stack[] = { "); for (i=0;i<7;i++) { printf("%08x ", ((u_int32_t *)stack_base)[i]); } printf("}\n\n"); # endif #else (void)stack_size; (void)reg; (void)flags; #endif // // mess with function parameters // ((u_int32_t *)stack_base)[1] = 0x66554433; // // mess with return address... // reg->eax = 0x11223344; return 0; } #endif /*********************************************************************** * MODULE_GetProcAddress (internal) */ FARPROC MODULE_GetProcAddress( HMODULE hModule, /* [in] current module handle */ LPCSTR function, /* [in] function to be looked up */ WIN_BOOL snoop ) { WINE_MODREF *wm = MODULE32_LookupHMODULE( hModule ); // WINE_MODREF *wm=local_wm; FARPROC retproc; #ifdef DEBUG_QTX_API if (HIWORD(function)) fprintf(stderr,"XXX GetProcAddress(%08lx,%s)\n",(DWORD)hModule,function); else fprintf(stderr,"XXX GetProcAddress(%08lx,%p)\n",(DWORD)hModule,function); #endif // TRACE_(win32)("(%08lx,%s)\n",(DWORD)hModule,function); // else // TRACE_(win32)("(%08lx,%p)\n",(DWORD)hModule,function); if (!wm) { SetLastError(ERROR_INVALID_HANDLE); return (FARPROC)0; } switch (wm->type) { case MODULE32_PE: retproc = PE_FindExportedFunction( wm, function, snoop ); if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); break; #ifdef HAVE_LIBDL case MODULE32_ELF: retproc = (FARPROC) dlsym( (void*) wm->module, function); if (!retproc) SetLastError(ERROR_PROC_NOT_FOUND); return retproc; #endif default: ERR("wine_modref type %d not handled.\n",wm->type); SetLastError(ERROR_INVALID_HANDLE); return (FARPROC)0; } #ifdef EMU_QTX_API if (HIWORD(function) && retproc){ #ifdef DEBUG_QTX_API #define DECL_COMPONENT(sname,name,type) \ if(!strcmp(function,name)){ \ fprintf(stderr,name "dispatcher caught -> %p\n",retproc); \ real_ ## sname = retproc; retproc = fake_ ## sname; \ } #include "qt_comp.h" #undef DECL_COMPONENT #endif if(!strcmp(function,"theQuickTimeDispatcher") // || !strcmp(function,"_CallComponentFunctionWithStorage") // || !strcmp(function,"_CallComponent") ){ fprintf(stderr,"theQuickTimeDispatcher caught -> %p\n",retproc); wrapper_target=(void *)retproc; retproc=(void *)wrapper; } } #endif return retproc; } static int acounter = 0; void CodecAlloc(void) { acounter++; //printf("**************CODEC ALLOC %d\n", acounter); } void CodecRelease(void) { acounter--; //printf("**************CODEC RELEASE %d\n", acounter); if (acounter == 0) { for (;;) { modref_list* list = local_wm; if (!local_wm) break; //printf("CODECRELEASE %p\n", list); MODULE_FreeLibrary(list->wm); MODULE_RemoveFromList(list->wm); if (local_wm == NULL) my_garbagecollection(); } } } ������������������������������������������xine-lib-1.2/src/libw32dll/wine/poppack.h�����������������������������������������������������������0000644�0001750�0001750�00000001046�14647725152�016022� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef __WINE_PSHPACK_H #undef __WINE_PSHPACK_H #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__ICC) #pragma pack() #elif defined(__SUNPRO_CC) #warning "Assumes default alignment is 4" #pragma pack(4) #elif !defined(RC_INVOKED) #error "Restoration of the previous alignment isn't supported by the compiler" #endif /* defined(__GNUC__) || defined(__SUNPRO_C) ; !defined(RC_INVOKED) */ #else /* defined(__WINE_PSHPACK_H) */ #error "Popping alignment isn't possible since no alignment has been pushed" #endif /* defined(__WINE_PSHPACK_H) */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/ldt.h���������������������������������������������������������������0000644�0001750�0001750�00000006753�14647725152�015162� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * LDT copy * * Copyright 1995 Alexandre Julliard */ #ifndef __WINE_LDT_H #define __WINE_LDT_H #include "windef.h" enum seg_type { SEGMENT_DATA = 0, SEGMENT_STACK = 1, SEGMENT_CODE = 2 }; /* This structure represents a real LDT entry. */ /* It is used by get_ldt_entry() and set_ldt_entry(). */ typedef struct { unsigned long base; /* base address */ unsigned long limit; /* segment limit (in pages or bytes) */ int seg_32bit; /* is segment 32-bit? */ int read_only; /* is segment read-only? */ int limit_in_pages; /* is the limit in pages or bytes? */ enum seg_type type; /* segment type */ } ldt_entry; #ifdef __cplusplus extern "C" { #endif extern void LDT_BytesToEntry( const unsigned long *buffer, ldt_entry *content); extern void LDT_EntryToBytes( unsigned long *buffer, const ldt_entry *content); extern int LDT_GetEntry( int entry, ldt_entry *content ); extern int LDT_SetEntry( int entry, const ldt_entry *content ); extern void LDT_Print( int start, int length ); /* This structure is used to build the local copy of the LDT. */ typedef struct { unsigned long base; /* base address or 0 if entry is free */ unsigned long limit; /* limit in bytes or 0 if entry is free */ } ldt_copy_entry; #define LDT_SIZE 8192 extern ldt_copy_entry ldt_copy[LDT_SIZE]; #define __AHSHIFT 3 /* don't change! */ #define __AHINCR (1 << __AHSHIFT) #define SELECTOR_TO_ENTRY(sel) (((int)(sel) & 0xffff) >> __AHSHIFT) #define ENTRY_TO_SELECTOR(i) ((i) ? (((int)(i) << __AHSHIFT) | 7) : 0) #define IS_LDT_ENTRY_FREE(i) (!(ldt_flags_copy[(i)] & LDT_FLAGS_ALLOCATED)) #define IS_SELECTOR_FREE(sel) (IS_LDT_ENTRY_FREE(SELECTOR_TO_ENTRY(sel))) #define GET_SEL_BASE(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].base) #define GET_SEL_LIMIT(sel) (ldt_copy[SELECTOR_TO_ENTRY(sel)].limit) /* Convert a segmented ptr (16:16) to a linear (32) pointer */ #define PTR_SEG_OFF_TO_LIN(seg,off) \ ((void*)(GET_SEL_BASE(seg) + (unsigned int)(off))) #define PTR_SEG_TO_LIN(ptr) \ PTR_SEG_OFF_TO_LIN(SELECTOROF(ptr),OFFSETOF(ptr)) #define PTR_SEG_OFF_TO_SEGPTR(seg,off) \ ((SEGPTR)MAKELONG(off,seg)) #define PTR_SEG_OFF_TO_HUGEPTR(seg,off) \ PTR_SEG_OFF_TO_SEGPTR( (seg) + (HIWORD(off) << __AHSHIFT), LOWORD(off) ) #define W32S_APPLICATION() (PROCESS_Current()->flags & PDB32_WIN32S_PROC) #define W32S_OFFSET 0x10000 #define W32S_APP2WINE(addr, offset) ((addr)? (DWORD)(addr) + (DWORD)(offset) : 0) #define W32S_WINE2APP(addr, offset) ((addr)? (DWORD)(addr) - (DWORD)(offset) : 0) extern unsigned char ldt_flags_copy[LDT_SIZE]; #define LDT_FLAGS_TYPE 0x03 /* Mask for segment type */ #define LDT_FLAGS_READONLY 0x04 /* Segment is read-only (data) */ #define LDT_FLAGS_EXECONLY 0x04 /* Segment is execute-only (code) */ #define LDT_FLAGS_32BIT 0x08 /* Segment is 32-bit (code or stack) */ #define LDT_FLAGS_BIG 0x10 /* Segment is big (limit is in pages) */ #define LDT_FLAGS_ALLOCATED 0x80 /* Segment is allocated (no longer free) */ #define GET_SEL_FLAGS(sel) (ldt_flags_copy[SELECTOR_TO_ENTRY(sel)]) #define FIRST_LDT_ENTRY_TO_ALLOC 17 /* Determine if sel is a system selector (i.e. not managed by Wine) */ #define IS_SELECTOR_SYSTEM(sel) \ (!((sel) & 4) || (SELECTOR_TO_ENTRY(sel) < FIRST_LDT_ENTRY_TO_ALLOC)) #define IS_SELECTOR_32BIT(sel) \ (IS_SELECTOR_SYSTEM(sel) || (GET_SEL_FLAGS(sel) & LDT_FLAGS_32BIT)) #ifdef __cplusplus } #endif #endif /* __WINE_LDT_H */ ���������������������xine-lib-1.2/src/libw32dll/wine/winreg.h������������������������������������������������������������0000644�0001750�0001750�00000002600�14647725152�015655� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Win32 registry defines (see also winnt.h) */ #ifndef __WINE_WINREG_H #define __WINE_WINREG_H #include "winbase.h" #include "winnt.h" #ifdef __cplusplus extern "C" { #endif /* defined(__cplusplus) */ /* #define SHELL_ERROR_SUCCESS 0L #define SHELL_ERROR_BADDB 1L #define SHELL_ERROR_BADKEY 2L #define SHELL_ERROR_CANTOPEN 3L #define SHELL_ERROR_CANTREAD 4L #define SHELL_ERROR_CANTWRITE 5L #define SHELL_ERROR_OUTOFMEMORY 6L #define SHELL_ERROR_INVALID_PARAMETER 7L #define SHELL_ERROR_ACCESS_DENIED 8L */ #define HKEY_CLASSES_ROOT ((HKEY) 0x80000000) #define HKEY_CURRENT_USER ((HKEY) 0x80000001) #define HKEY_LOCAL_MACHINE ((HKEY) 0x80000002) #define HKEY_USERS ((HKEY) 0x80000003) #define HKEY_PERFORMANCE_DATA ((HKEY) 0x80000004) #define HKEY_CURRENT_CONFIG ((HKEY) 0x80000005) #define HKEY_DYN_DATA ((HKEY) 0x80000006) /* * registry provider structs */ typedef struct value_entA { LPSTR ve_valuename; DWORD ve_valuelen; DWORD_PTR ve_valueptr; DWORD ve_type; } VALENTA, *PVALENTA; typedef struct value_entW { LPWSTR ve_valuename; DWORD ve_valuelen; DWORD_PTR ve_valueptr; DWORD ve_type; } VALENTW, *PVALENTW; typedef ACCESS_MASK REGSAM; #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ #endif /* __WINE_WINREG_H */ ��������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/registry.h����������������������������������������������������������0000644�0001750�0001750�00000002352�14647725152�016236� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef AVIFILE_REGISTRY_H #define AVIFILE_REGISTRY_H /******************************************************** * * Declaration of registry access functions * Copyright 2000 Eugene Kuznetsov (divx@euro.ru) * ********************************************************/ #ifdef __cplusplus extern "C" { #endif void free_registry(void); long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey); long RegCloseKey(long key); long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count); long RegCreateKeyExA(long key, const char* name, long reserved, void* classs, long options, long security, void* sec_attr, int* newkey, int* status); long RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size); #ifdef __WINE_WINERROR_H long RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, LPFILETIME lpftLastWriteTime); long RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count); #endif #ifdef __cplusplus }; #endif #endif // AVIFILE_REGISTRY_H ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/winuser.h�����������������������������������������������������������0000644�0001750�0001750�00000251137�14647725152�016071� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _WINUSER_ #define _WINUSER_ #ifndef RC_INVOKED #include <stdarg.h> #endif #ifdef __cplusplus extern "C" { #endif #include "pshpack1.h" /* flags for HIGHCONTRAST dwFlags field */ #define HCF_HIGHCONTRASTON 0x00000001 #define HCF_AVAILABLE 0x00000002 #define HCF_HOTKEYACTIVE 0x00000004 #define HCF_CONFIRMHOTKEY 0x00000008 #define HCF_HOTKEYSOUND 0x00000010 #define HCF_INDICATOR 0x00000020 #define HCF_HOTKEYAVAILABLE 0x00000040 typedef struct tagHIGHCONTRASTA { UINT cbSize; DWORD dwFlags; LPSTR lpszDefaultScheme; } HIGHCONTRASTA, *LPHIGHCONTRASTA; typedef struct tagHIGHCONTRASTW { UINT cbSize; DWORD dwFlags; LPWSTR lpszDefaultScheme; } HIGHCONTRASTW, *LPHIGHCONTRASTW; DECL_WINELIB_TYPE_AW(HIGHCONTRAST) DECL_WINELIB_TYPE_AW(LPHIGHCONTRAST) typedef struct { UINT message; UINT paramL; UINT paramH; DWORD time; HWND hwnd; } EVENTMSG, *LPEVENTMSG; /* Mouse hook structure */ typedef struct { POINT pt; HWND hwnd; UINT wHitTestCode; DWORD dwExtraInfo; } MOUSEHOOKSTRUCT, *PMOUSEHOOKSTRUCT, *LPMOUSEHOOKSTRUCT; /* Hardware hook structure */ typedef struct { HWND hWnd; UINT wMessage; WPARAM wParam; LPARAM lParam; } HARDWAREHOOKSTRUCT, *LPHARDWAREHOOKSTRUCT; /* Debug hook structure */ typedef struct { DWORD idThread; DWORD idThreadInstaller; LPARAM lParam; WPARAM wParam; INT code; } DEBUGHOOKINFO, *LPDEBUGHOOKINFO; #define HKL_PREV 0 #define HKL_NEXT 1 #define KLF_ACTIVATE 0x00000001 #define KLF_SUBSTITUTE_OK 0x00000002 #define KLF_UNLOADPREVIOUS 0x00000004 #define KLF_REORDER 0x00000008 #define KLF_REPLACELANG 0x00000010 #define KLF_NOTELLSHELL 0x00000080 #define KL_NAMELENGTH 9 /***** Dialogs *****/ #ifdef FSHIFT /* Gcc on Solaris has a version of this that we don't care about. */ #undef FSHIFT #endif #define FVIRTKEY TRUE /* Assumed to be == TRUE */ #define FNOINVERT 0x02 #define FSHIFT 0x04 #define FCONTROL 0x08 #define FALT 0x10 typedef struct tagANIMATIONINFO { UINT cbSize; INT iMinAnimate; } ANIMATIONINFO, *LPANIMATIONINFO; typedef struct tagNMHDR { HWND hwndFrom; UINT idFrom; UINT code; } NMHDR, *LPNMHDR; typedef struct { UINT cbSize; INT iTabLength; INT iLeftMargin; INT iRightMargin; UINT uiLengthDrawn; } DRAWTEXTPARAMS,*LPDRAWTEXTPARAMS; #define WM_USER 0x0400 #define DT_EDITCONTROL 0x00002000 #define DT_PATH_ELLIPSIS 0x00004000 #define DT_END_ELLIPSIS 0x00008000 #define DT_MODIFYSTRING 0x00010000 #define DT_RTLREADING 0x00020000 #define DT_WORD_ELLIPSIS 0x00040000 typedef struct { LPARAM lParam; WPARAM16 wParam; UINT16 message; HWND16 hwnd; } CWPSTRUCT16, *LPCWPSTRUCT16; typedef struct { LPARAM lParam; WPARAM wParam; UINT message; HWND hwnd; } CWPSTRUCT, *LPCWPSTRUCT; typedef struct { LRESULT lResult; LPARAM lParam; WPARAM16 wParam; DWORD message; HWND16 hwnd; } CWPRETSTRUCT16, *LPCWPRETSTRUCT16; typedef struct { LRESULT lResult; LPARAM lParam; WPARAM wParam; DWORD message; HWND hwnd; } CWPRETSTRUCT, *LPCWPRETSTRUCT; typedef struct { UINT length; UINT flags; UINT showCmd; POINT ptMinPosition WINE_PACKED; POINT ptMaxPosition WINE_PACKED; RECT rcNormalPosition WINE_PACKED; } WINDOWPLACEMENT, *LPWINDOWPLACEMENT; /* WINDOWPLACEMENT flags */ #define WPF_SETMINPOSITION 0x0001 #define WPF_RESTORETOMAXIMIZED 0x0002 /***** Dialogs *****/ /* cbWndExtra bytes for dialog class */ #define DLGWINDOWEXTRA 30 /* Button control styles */ #define BS_PUSHBUTTON 0x00000000L #define BS_DEFPUSHBUTTON 0x00000001L #define BS_CHECKBOX 0x00000002L #define BS_AUTOCHECKBOX 0x00000003L #define BS_RADIOBUTTON 0x00000004L #define BS_3STATE 0x00000005L #define BS_AUTO3STATE 0x00000006L #define BS_GROUPBOX 0x00000007L #define BS_USERBUTTON 0x00000008L #define BS_AUTORADIOBUTTON 0x00000009L #define BS_OWNERDRAW 0x0000000BL #define BS_LEFTTEXT 0x00000020L #define BS_TEXT 0x00000000L #define BS_ICON 0x00000040L #define BS_BITMAP 0x00000080L #define BS_LEFT 0x00000100L #define BS_RIGHT 0x00000200L #define BS_CENTER 0x00000300L #define BS_TOP 0x00000400L #define BS_BOTTOM 0x00000800L #define BS_VCENTER 0x00000C00L #define BS_PUSHLIKE 0x00001000L #define BS_MULTILINE 0x00002000L #define BS_NOTIFY 0x00004000L #define BS_FLAT 0x00008000L /* Dialog styles */ #define DS_ABSALIGN 0x0001 #define DS_SYSMODAL 0x0002 #define DS_3DLOOK 0x0004 /* win95 */ #define DS_FIXEDSYS 0x0008 /* win95 */ #define DS_NOFAILCREATE 0x0010 /* win95 */ #define DS_LOCALEDIT 0x0020 #define DS_SETFONT 0x0040 #define DS_MODALFRAME 0x0080 #define DS_NOIDLEMSG 0x0100 #define DS_SETFOREGROUND 0x0200 /* win95 */ #define DS_CONTROL 0x0400 /* win95 */ #define DS_CENTER 0x0800 /* win95 */ #define DS_CENTERMOUSE 0x1000 /* win95 */ #define DS_CONTEXTHELP 0x2000 /* win95 */ /* Dialog messages */ #define DM_GETDEFID (WM_USER+0) #define DM_SETDEFID (WM_USER+1) #define DC_HASDEFID 0x534b /* Owner draw control types */ #define ODT_MENU 1 #define ODT_LISTBOX 2 #define ODT_COMBOBOX 3 #define ODT_BUTTON 4 #define ODT_STATIC 5 /* Owner draw actions */ #define ODA_DRAWENTIRE 0x0001 #define ODA_SELECT 0x0002 #define ODA_FOCUS 0x0004 /* Owner draw state */ #define ODS_SELECTED 0x0001 #define ODS_GRAYED 0x0002 #define ODS_DISABLED 0x0004 #define ODS_CHECKED 0x0008 #define ODS_FOCUS 0x0010 #define ODS_COMBOBOXEDIT 0x1000 #define ODS_HOTLIGHT 0x0040 #define ODS_INACTIVE 0x0080 /* Edit control styles */ #define ES_LEFT 0x00000000 #define ES_CENTER 0x00000001 #define ES_RIGHT 0x00000002 #define ES_MULTILINE 0x00000004 #define ES_UPPERCASE 0x00000008 #define ES_LOWERCASE 0x00000010 #define ES_PASSWORD 0x00000020 #define ES_AUTOVSCROLL 0x00000040 #define ES_AUTOHSCROLL 0x00000080 #define ES_NOHIDESEL 0x00000100 #define ES_OEMCONVERT 0x00000400 #define ES_READONLY 0x00000800 #define ES_WANTRETURN 0x00001000 #define ES_NUMBER 0x00002000 /* OEM Resource Ordinal Numbers */ #define OBM_CLOSED 32731 #define OBM_RADIOCHECK 32732 #define OBM_TRTYPE 32733 #define OBM_LFARROWI 32734 #define OBM_RGARROWI 32735 #define OBM_DNARROWI 32736 #define OBM_UPARROWI 32737 #define OBM_COMBO 32738 #define OBM_MNARROW 32739 #define OBM_LFARROWD 32740 #define OBM_RGARROWD 32741 #define OBM_DNARROWD 32742 #define OBM_UPARROWD 32743 #define OBM_RESTORED 32744 #define OBM_ZOOMD 32745 #define OBM_REDUCED 32746 #define OBM_RESTORE 32747 #define OBM_ZOOM 32748 #define OBM_REDUCE 32749 #define OBM_LFARROW 32750 #define OBM_RGARROW 32751 #define OBM_DNARROW 32752 #define OBM_UPARROW 32753 #define OBM_CLOSE 32754 #define OBM_OLD_RESTORE 32755 #define OBM_OLD_ZOOM 32756 #define OBM_OLD_REDUCE 32757 #define OBM_BTNCORNERS 32758 #define OBM_CHECKBOXES 32759 #define OBM_CHECK 32760 #define OBM_BTSIZE 32761 #define OBM_OLD_LFARROW 32762 #define OBM_OLD_RGARROW 32763 #define OBM_OLD_DNARROW 32764 #define OBM_OLD_UPARROW 32765 #define OBM_SIZE 32766 #define OBM_OLD_CLOSE 32767 #define OCR_BUMMER 100 #define OCR_DRAGOBJECT 101 #define OCR_NORMAL 32512 #define OCR_IBEAM 32513 #define OCR_WAIT 32514 #define OCR_CROSS 32515 #define OCR_UP 32516 #define OCR_SIZE 32640 #define OCR_ICON 32641 #define OCR_SIZENWSE 32642 #define OCR_SIZENESW 32643 #define OCR_SIZEWE 32644 #define OCR_SIZENS 32645 #define OCR_SIZEALL 32646 #define OCR_ICOCUR 32647 #define OCR_NO 32648 #define OCR_APPSTARTING 32650 #define OCR_HELP 32651 /* only defined in wine */ #define OIC_SAMPLE 32512 #define OIC_HAND 32513 #define OIC_QUES 32514 #define OIC_BANG 32515 #define OIC_NOTE 32516 #define OIC_PORTRAIT 32517 #define OIC_LANDSCAPE 32518 #define OIC_WINEICON 32519 #define OIC_FOLDER 32520 #define OIC_FOLDER2 32521 #define OIC_FLOPPY 32522 #define OIC_CDROM 32523 #define OIC_HDISK 32524 #define OIC_NETWORK 32525 #define COLOR_SCROLLBAR 0 #define COLOR_BACKGROUND 1 #define COLOR_ACTIVECAPTION 2 #define COLOR_INACTIVECAPTION 3 #define COLOR_MENU 4 #define COLOR_WINDOW 5 #define COLOR_WINDOWFRAME 6 #define COLOR_MENUTEXT 7 #define COLOR_WINDOWTEXT 8 #define COLOR_CAPTIONTEXT 9 #define COLOR_ACTIVEBORDER 10 #define COLOR_INACTIVEBORDER 11 #define COLOR_APPWORKSPACE 12 #define COLOR_HIGHLIGHT 13 #define COLOR_HIGHLIGHTTEXT 14 #define COLOR_BTNFACE 15 #define COLOR_BTNSHADOW 16 #define COLOR_GRAYTEXT 17 #define COLOR_BTNTEXT 18 #define COLOR_INACTIVECAPTIONTEXT 19 #define COLOR_BTNHIGHLIGHT 20 /* win95 colors */ #define COLOR_3DDKSHADOW 21 #define COLOR_3DLIGHT 22 #define COLOR_INFOTEXT 23 #define COLOR_INFOBK 24 #define COLOR_DESKTOP COLOR_BACKGROUND #define COLOR_3DFACE COLOR_BTNFACE #define COLOR_3DSHADOW COLOR_BTNSHADOW #define COLOR_3DHIGHLIGHT COLOR_BTNHIGHLIGHT #define COLOR_3DHILIGHT COLOR_BTNHIGHLIGHT #define COLOR_BTNHILIGHT COLOR_BTNHIGHLIGHT /* win98 colors */ #define COLOR_ALTERNATEBTNFACE 25 /* undocumented, constant's name unknown */ #define COLOR_HOTLIGHT 26 #define COLOR_GRADIENTACTIVECAPTION 27 #define COLOR_GRADIENTINACTIVECAPTION 28 /* WM_CTLCOLOR values */ #define CTLCOLOR_MSGBOX 0 #define CTLCOLOR_EDIT 1 #define CTLCOLOR_LISTBOX 2 #define CTLCOLOR_BTN 3 #define CTLCOLOR_DLG 4 #define CTLCOLOR_SCROLLBAR 5 #define CTLCOLOR_STATIC 6 /* Edit control messages */ #define EM_GETSEL 0x00b0 #define EM_SETSEL 0x00b1 #define EM_GETRECT 0x00b2 #define EM_SETRECT 0x00b3 #define EM_SETRECTNP 0x00b4 #define EM_SCROLL 0x00b5 #define EM_LINESCROLL 0x00b6 #define EM_SCROLLCARET 0x00b7 #define EM_GETMODIFY 0x00b8 #define EM_SETMODIFY 0x00b9 #define EM_GETLINECOUNT 0x00ba #define EM_LINEINDEX 0x00bb #define EM_SETHANDLE 0x00bc #define EM_GETHANDLE 0x00bd #define EM_GETTHUMB 0x00be /* FIXME : missing from specs 0x00bf and 0x00c0 */ #define EM_LINELENGTH 0x00c1 #define EM_REPLACESEL 0x00c2 /* FIXME : missing from specs 0x00c3 */ #define EM_GETLINE 0x00c4 #define EM_LIMITTEXT 0x00c5 #define EM_CANUNDO 0x00c6 #define EM_UNDO 0x00c7 #define EM_FMTLINES 0x00c8 #define EM_LINEFROMCHAR 0x00c9 /* FIXME : missing from specs 0x00ca */ #define EM_SETTABSTOPS 0x00cb #define EM_SETPASSWORDCHAR 0x00cc #define EM_EMPTYUNDOBUFFER 0x00cd #define EM_GETFIRSTVISIBLELINE 0x00ce #define EM_SETREADONLY 0x00cf #define EM_SETWORDBREAKPROC 0x00d0 #define EM_GETWORDBREAKPROC 0x00d1 #define EM_GETPASSWORDCHAR 0x00d2 #define EM_SETMARGINS 0x00d3 #define EM_GETMARGINS 0x00d4 #define EM_GETLIMITTEXT 0x00d5 #define EM_POSFROMCHAR 0x00d6 #define EM_CHARFROMPOS 0x00d7 /* a name change since win95 */ #define EM_SETLIMITTEXT EM_LIMITTEXT /* EDITWORDBREAKPROC code values */ #define WB_LEFT 0 #define WB_RIGHT 1 #define WB_ISDELIMITER 2 /* Edit control notification codes */ #define EN_SETFOCUS 0x0100 #define EN_KILLFOCUS 0x0200 #define EN_CHANGE 0x0300 #define EN_UPDATE 0x0400 #define EN_ERRSPACE 0x0500 #define EN_MAXTEXT 0x0501 #define EN_HSCROLL 0x0601 #define EN_VSCROLL 0x0602 /* New since win95 : EM_SETMARGIN parameters */ #define EC_LEFTMARGIN 0x0001 #define EC_RIGHTMARGIN 0x0002 #define EC_USEFONTINFO 0xffff /* Messages */ /* WM_GETDLGCODE values */ #define WM_NULL 0x0000 #define WM_CREATE 0x0001 #define WM_DESTROY 0x0002 #define WM_MOVE 0x0003 #define WM_SIZEWAIT 0x0004 #define WM_SIZE 0x0005 #define WM_ACTIVATE 0x0006 #define WM_SETFOCUS 0x0007 #define WM_KILLFOCUS 0x0008 #define WM_SETVISIBLE 0x0009 #define WM_ENABLE 0x000a #define WM_SETREDRAW 0x000b #define WM_SETTEXT 0x000c #define WM_GETTEXT 0x000d #define WM_GETTEXTLENGTH 0x000e #define WM_PAINT 0x000f #define WM_CLOSE 0x0010 #define WM_QUERYENDSESSION 0x0011 #define WM_QUIT 0x0012 #define WM_QUERYOPEN 0x0013 #define WM_ERASEBKGND 0x0014 #define WM_SYSCOLORCHANGE 0x0015 #define WM_ENDSESSION 0x0016 #define WM_SYSTEMERROR 0x0017 #define WM_SHOWWINDOW 0x0018 #define WM_CTLCOLOR 0x0019 #define WM_WININICHANGE 0x001a #define WM_SETTINGCHANGE WM_WININICHANGE #define WM_DEVMODECHANGE 0x001b #define WM_ACTIVATEAPP 0x001c #define WM_FONTCHANGE 0x001d #define WM_TIMECHANGE 0x001e #define WM_CANCELMODE 0x001f #define WM_SETCURSOR 0x0020 #define WM_MOUSEACTIVATE 0x0021 #define WM_CHILDACTIVATE 0x0022 #define WM_QUEUESYNC 0x0023 #define WM_GETMINMAXINFO 0x0024 #define WM_PAINTICON 0x0026 #define WM_ICONERASEBKGND 0x0027 #define WM_NEXTDLGCTL 0x0028 #define WM_ALTTABACTIVE 0x0029 #define WM_SPOOLERSTATUS 0x002a #define WM_DRAWITEM 0x002b #define WM_MEASUREITEM 0x002c #define WM_DELETEITEM 0x002d #define WM_VKEYTOITEM 0x002e #define WM_CHARTOITEM 0x002f #define WM_SETFONT 0x0030 #define WM_GETFONT 0x0031 #define WM_SETHOTKEY 0x0032 #define WM_GETHOTKEY 0x0033 #define WM_FILESYSCHANGE 0x0034 #define WM_ISACTIVEICON 0x0035 #define WM_QUERYPARKICON 0x0036 #define WM_QUERYDRAGICON 0x0037 #define WM_QUERYSAVESTATE 0x0038 #define WM_COMPAREITEM 0x0039 #define WM_TESTING 0x003a #define WM_OTHERWINDOWCREATED 0x003c #define WM_OTHERWINDOWDESTROYED 0x003d #define WM_ACTIVATESHELLWINDOW 0x003e #define WM_COMPACTING 0x0041 #define WM_COMMNOTIFY 0x0044 #define WM_WINDOWPOSCHANGING 0x0046 #define WM_WINDOWPOSCHANGED 0x0047 #define WM_POWER 0x0048 /* Win32 4.0 messages */ #define WM_COPYDATA 0x004a #define WM_CANCELJOURNAL 0x004b #define WM_NOTIFY 0x004e #define WM_HELP 0x0053 #define WM_NOTIFYFORMAT 0x0055 #define WM_CONTEXTMENU 0x007b #define WM_STYLECHANGING 0x007c #define WM_STYLECHANGED 0x007d #define WM_DISPLAYCHANGE 0x007e #define WM_GETICON 0x007f #define WM_SETICON 0x0080 /* Non-client system messages */ #define WM_NCCREATE 0x0081 #define WM_NCDESTROY 0x0082 #define WM_NCCALCSIZE 0x0083 #define WM_NCHITTEST 0x0084 #define WM_NCPAINT 0x0085 #define WM_NCACTIVATE 0x0086 #define WM_GETDLGCODE 0x0087 #define WM_SYNCPAINT 0x0088 #define WM_SYNCTASK 0x0089 /* Non-client mouse messages */ #define WM_NCMOUSEMOVE 0x00a0 #define WM_NCLBUTTONDOWN 0x00a1 #define WM_NCLBUTTONUP 0x00a2 #define WM_NCLBUTTONDBLCLK 0x00a3 #define WM_NCRBUTTONDOWN 0x00a4 #define WM_NCRBUTTONUP 0x00a5 #define WM_NCRBUTTONDBLCLK 0x00a6 #define WM_NCMBUTTONDOWN 0x00a7 #define WM_NCMBUTTONUP 0x00a8 #define WM_NCMBUTTONDBLCLK 0x00a9 /* Keyboard messages */ #define WM_KEYDOWN 0x0100 #define WM_KEYUP 0x0101 #define WM_CHAR 0x0102 #define WM_DEADCHAR 0x0103 #define WM_SYSKEYDOWN 0x0104 #define WM_SYSKEYUP 0x0105 #define WM_SYSCHAR 0x0106 #define WM_SYSDEADCHAR 0x0107 #define WM_KEYFIRST WM_KEYDOWN #define WM_KEYLAST 0x0108 /* Win32 4.0 messages for IME */ #define WM_IME_STARTCOMPOSITION 0x010d #define WM_IME_ENDCOMPOSITION 0x010e #define WM_IME_COMPOSITION 0x010f #define WM_IME_KEYLAST 0x010f #define WM_INITDIALOG 0x0110 #define WM_COMMAND 0x0111 #define WM_SYSCOMMAND 0x0112 #define WM_TIMER 0x0113 #define WM_SYSTIMER 0x0118 /* scroll messages */ #define WM_HSCROLL 0x0114 #define WM_VSCROLL 0x0115 /* Menu messages */ #define WM_INITMENU 0x0116 #define WM_INITMENUPOPUP 0x0117 #define WM_MENUSELECT 0x011F #define WM_MENUCHAR 0x0120 #define WM_ENTERIDLE 0x0121 #define WM_LBTRACKPOINT 0x0131 /* Win32 CTLCOLOR messages */ #define WM_CTLCOLORMSGBOX 0x0132 #define WM_CTLCOLOREDIT 0x0133 #define WM_CTLCOLORLISTBOX 0x0134 #define WM_CTLCOLORBTN 0x0135 #define WM_CTLCOLORDLG 0x0136 #define WM_CTLCOLORSCROLLBAR 0x0137 #define WM_CTLCOLORSTATIC 0x0138 /* Mouse messages */ #define WM_MOUSEMOVE 0x0200 #define WM_LBUTTONDOWN 0x0201 #define WM_LBUTTONUP 0x0202 #define WM_LBUTTONDBLCLK 0x0203 #define WM_RBUTTONDOWN 0x0204 #define WM_RBUTTONUP 0x0205 #define WM_RBUTTONDBLCLK 0x0206 #define WM_MBUTTONDOWN 0x0207 #define WM_MBUTTONUP 0x0208 #define WM_MBUTTONDBLCLK 0x0209 #define WM_MOUSEWHEEL 0x020A #define WM_MOUSEFIRST WM_MOUSEMOVE #define WM_MOUSELAST WM_MOUSEWHEEL #define WHEEL_DELTA 120 #define WHEEL_PAGESCROLL (UINT_MAX) #define WM_PARENTNOTIFY 0x0210 #define WM_ENTERMENULOOP 0x0211 #define WM_EXITMENULOOP 0x0212 #define WM_NEXTMENU 0x0213 /* Win32 4.0 messages */ #define WM_SIZING 0x0214 #define WM_CAPTURECHANGED 0x0215 #define WM_MOVING 0x0216 /* MDI messages */ #define WM_MDICREATE 0x0220 #define WM_MDIDESTROY 0x0221 #define WM_MDIACTIVATE 0x0222 #define WM_MDIRESTORE 0x0223 #define WM_MDINEXT 0x0224 #define WM_MDIMAXIMIZE 0x0225 #define WM_MDITILE 0x0226 #define WM_MDICASCADE 0x0227 #define WM_MDIICONARRANGE 0x0228 #define WM_MDIGETACTIVE 0x0229 #define WM_MDIREFRESHMENU 0x0234 /* D&D messages */ #define WM_DROPOBJECT 0x022A #define WM_QUERYDROPOBJECT 0x022B #define WM_BEGINDRAG 0x022C #define WM_DRAGLOOP 0x022D #define WM_DRAGSELECT 0x022E #define WM_DRAGMOVE 0x022F #define WM_MDISETMENU 0x0230 #define WM_ENTERSIZEMOVE 0x0231 #define WM_EXITSIZEMOVE 0x0232 #define WM_DROPFILES 0x0233 /* Win32 4.0 messages for IME */ #define WM_IME_SETCONTEXT 0x0281 #define WM_IME_NOTIFY 0x0282 #define WM_IME_CONTROL 0x0283 #define WM_IME_COMPOSITIONFULL 0x0284 #define WM_IME_SELECT 0x0285 #define WM_IME_CHAR 0x0286 /* Win32 5.0 messages for IME */ #define WM_IME_REQUEST 0x0288 /* Win32 4.0 messages for IME */ #define WM_IME_KEYDOWN 0x0290 #define WM_IME_KEYUP 0x0291 /* Clipboard command messages */ #define WM_CUT 0x0300 #define WM_COPY 0x0301 #define WM_PASTE 0x0302 #define WM_CLEAR 0x0303 #define WM_UNDO 0x0304 /* Clipboard owner messages */ #define WM_RENDERFORMAT 0x0305 #define WM_RENDERALLFORMATS 0x0306 #define WM_DESTROYCLIPBOARD 0x0307 /* Clipboard viewer messages */ #define WM_DRAWCLIPBOARD 0x0308 #define WM_PAINTCLIPBOARD 0x0309 #define WM_VSCROLLCLIPBOARD 0x030A #define WM_SIZECLIPBOARD 0x030B #define WM_ASKCBFORMATNAME 0x030C #define WM_CHANGECBCHAIN 0x030D #define WM_HSCROLLCLIPBOARD 0x030E #define WM_QUERYNEWPALETTE 0x030F #define WM_PALETTEISCHANGING 0x0310 #define WM_PALETTECHANGED 0x0311 #define WM_HOTKEY 0x0312 #define WM_PRINT 0x0317 #define WM_PRINTCLIENT 0x0318 /* FIXME: This does not belong to any libwine interface header */ /* MFC messages [360-38f] */ #define WM_QUERYAFXWNDPROC 0x0360 #define WM_SIZEPARENT 0x0361 #define WM_SETMESSAGESTRING 0x0362 #define WM_IDLEUPDATECMDUI 0x0363 #define WM_INITIALUPDATE 0x0364 #define WM_COMMANDHELP 0x0365 #define WM_HELPHITTEST 0x0366 #define WM_EXITHELPMODE 0x0367 #define WM_RECALCPARENT 0x0368 #define WM_SIZECHILD 0x0369 #define WM_KICKIDLE 0x036A #define WM_QUERYCENTERWND 0x036B #define WM_DISABLEMODAL 0x036C #define WM_FLOATSTATUS 0x036D #define WM_ACTIVATETOPLEVEL 0x036E #define WM_QUERY3DCONTROLS 0x036F #define WM_SOCKET_NOTIFY 0x0373 #define WM_SOCKET_DEAD 0x0374 #define WM_POPMESSAGESTRING 0x0375 #define WM_OCC_LOADFROMSTREAM 0x0376 #define WM_OCC_LOADFROMSTORAGE 0x0377 #define WM_OCC_INITNEW 0x0378 #define WM_OCC_LOADFROMSTREAM_EX 0x037A #define WM_OCC_LOADFROMSTORAGE_EX 0x037B #define WM_QUEUE_SENTINEL 0x0379 #define WM_PENWINFIRST 0x0380 #define WM_PENWINLAST 0x038F /* end of MFC messages */ /* FIXME: The following two lines do not belong to any libwine interface header */ #define WM_COALESCE_FIRST 0x0390 #define WM_COALESCE_LAST 0x039F #define WM_APP 0x8000 #define DLGC_WANTARROWS 0x0001 #define DLGC_WANTTAB 0x0002 #define DLGC_WANTALLKEYS 0x0004 #define DLGC_WANTMESSAGE 0x0004 #define DLGC_HASSETSEL 0x0008 #define DLGC_DEFPUSHBUTTON 0x0010 #define DLGC_UNDEFPUSHBUTTON 0x0020 #define DLGC_RADIOBUTTON 0x0040 #define DLGC_WANTCHARS 0x0080 #define DLGC_STATIC 0x0100 #define DLGC_BUTTON 0x2000 /* Standard dialog button IDs */ #define IDOK 1 #define IDCANCEL 2 #define IDABORT 3 #define IDRETRY 4 #define IDIGNORE 5 #define IDYES 6 #define IDNO 7 #define IDCLOSE 8 #define IDHELP 9 /****** Window classes ******/ typedef struct tagCREATESTRUCTA { LPVOID lpCreateParams; HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; INT cy; INT cx; INT y; INT x; LONG style; LPCSTR lpszName; LPCSTR lpszClass; DWORD dwExStyle; } CREATESTRUCTA, *LPCREATESTRUCTA; typedef struct { LPVOID lpCreateParams; HINSTANCE hInstance; HMENU hMenu; HWND hwndParent; INT cy; INT cx; INT y; INT x; LONG style; LPCWSTR lpszName; LPCWSTR lpszClass; DWORD dwExStyle; } CREATESTRUCTW, *LPCREATESTRUCTW; DECL_WINELIB_TYPE_AW(CREATESTRUCT) DECL_WINELIB_TYPE_AW(LPCREATESTRUCT) typedef struct { HDC hdc; WIN_BOOL fErase; RECT rcPaint; WIN_BOOL fRestore; WIN_BOOL fIncUpdate; BYTE rgbReserved[32]; } PAINTSTRUCT, *PPAINTSTRUCT, *LPPAINTSTRUCT; typedef struct { HMENU hWindowMenu; UINT idFirstChild; } CLIENTCREATESTRUCT, *LPCLIENTCREATESTRUCT; typedef struct { LPCSTR szClass; LPCSTR szTitle; HINSTANCE hOwner; INT x; INT y; INT cx; INT cy; DWORD style; LPARAM lParam; } MDICREATESTRUCTA, *LPMDICREATESTRUCTA; typedef struct { LPCWSTR szClass; LPCWSTR szTitle; HINSTANCE hOwner; INT x; INT y; INT cx; INT cy; DWORD style; LPARAM lParam; } MDICREATESTRUCTW, *LPMDICREATESTRUCTW; DECL_WINELIB_TYPE_AW(MDICREATESTRUCT) DECL_WINELIB_TYPE_AW(LPMDICREATESTRUCT) #define MDITILE_VERTICAL 0x0000 #define MDITILE_HORIZONTAL 0x0001 #define MDITILE_SKIPDISABLED 0x0002 #define MDIS_ALLCHILDSTYLES 0x0001 typedef struct { DWORD styleOld; DWORD styleNew; } STYLESTRUCT, *LPSTYLESTRUCT; /* Offsets for GetWindowLong() and GetWindowWord() */ #define GWL_USERDATA (-21) #define GWL_EXSTYLE (-20) #define GWL_STYLE (-16) #define GWW_ID (-12) #define GWL_ID GWW_ID #define GWW_HWNDPARENT (-8) #define GWL_HWNDPARENT GWW_HWNDPARENT #define GWW_HINSTANCE (-6) #define GWL_HINSTANCE GWW_HINSTANCE #define GWL_WNDPROC (-4) #define DWL_MSGRESULT 0 #define DWL_DLGPROC 4 #define DWL_USER 8 /* GetWindow() constants */ #define GW_HWNDFIRST 0 #define GW_HWNDLAST 1 #define GW_HWNDNEXT 2 #define GW_HWNDPREV 3 #define GW_OWNER 4 #define GW_CHILD 5 /* WM_GETMINMAXINFO struct */ typedef struct { POINT ptReserved; POINT ptMaxSize; POINT ptMaxPosition; POINT ptMinTrackSize; POINT ptMaxTrackSize; } MINMAXINFO, *PMINMAXINFO, *LPMINMAXINFO; /* RedrawWindow() flags */ #define RDW_INVALIDATE 0x0001 #define RDW_INTERNALPAINT 0x0002 #define RDW_ERASE 0x0004 #define RDW_VALIDATE 0x0008 #define RDW_NOINTERNALPAINT 0x0010 #define RDW_NOERASE 0x0020 #define RDW_NOCHILDREN 0x0040 #define RDW_ALLCHILDREN 0x0080 #define RDW_UPDATENOW 0x0100 #define RDW_ERASENOW 0x0200 #define RDW_FRAME 0x0400 #define RDW_NOFRAME 0x0800 /* debug flags */ #define DBGFILL_ALLOC 0xfd #define DBGFILL_FREE 0xfb #define DBGFILL_BUFFER 0xf9 #define DBGFILL_STACK 0xf7 /* WM_WINDOWPOSCHANGING/CHANGED struct */ typedef struct tagWINDOWPOS { HWND hwnd; HWND hwndInsertAfter; INT x; INT y; INT cx; INT cy; UINT flags; } WINDOWPOS, *PWINDOWPOS, *LPWINDOWPOS; /* WM_MOUSEACTIVATE return values */ #define MA_ACTIVATE 1 #define MA_ACTIVATEANDEAT 2 #define MA_NOACTIVATE 3 #define MA_NOACTIVATEANDEAT 4 /* WM_ACTIVATE wParam values */ #define WA_INACTIVE 0 #define WA_ACTIVE 1 #define WA_CLICKACTIVE 2 /* WM_GETICON/WM_SETICON params values */ #define ICON_SMALL 0 #define ICON_BIG 1 /* WM_NCCALCSIZE parameter structure */ typedef struct { RECT rgrc[3]; WINDOWPOS *lppos; } NCCALCSIZE_PARAMS, *LPNCCALCSIZE_PARAMS; /* WM_NCCALCSIZE return flags */ #define WVR_ALIGNTOP 0x0010 #define WVR_ALIGNLEFT 0x0020 #define WVR_ALIGNBOTTOM 0x0040 #define WVR_ALIGNRIGHT 0x0080 #define WVR_HREDRAW 0x0100 #define WVR_VREDRAW 0x0200 #define WVR_REDRAW (WVR_HREDRAW | WVR_VREDRAW) #define WVR_VALIDRECTS 0x0400 /* WM_NCHITTEST return codes */ #define HTERROR (-2) #define HTTRANSPARENT (-1) #define HTNOWHERE 0 #define HTCLIENT 1 #define HTCAPTION 2 #define HTSYSMENU 3 #define HTSIZE 4 #define HTMENU 5 #define HTHSCROLL 6 #define HTVSCROLL 7 #define HTMINBUTTON 8 #define HTMAXBUTTON 9 #define HTLEFT 10 #define HTRIGHT 11 #define HTTOP 12 #define HTTOPLEFT 13 #define HTTOPRIGHT 14 #define HTBOTTOM 15 #define HTBOTTOMLEFT 16 #define HTBOTTOMRIGHT 17 #define HTBORDER 18 #define HTGROWBOX HTSIZE #define HTREDUCE HTMINBUTTON #define HTZOOM HTMAXBUTTON #define HTOBJECT 19 #define HTCLOSE 20 #define HTHELP 21 #define HTSIZEFIRST HTLEFT #define HTSIZELAST HTBOTTOMRIGHT /* WM_SYSCOMMAND parameters */ #ifdef SC_SIZE /* at least HP-UX: already defined in /usr/include/sys/signal.h */ #undef SC_SIZE #endif #define SC_SIZE 0xf000 #define SC_MOVE 0xf010 #define SC_MINIMIZE 0xf020 #define SC_MAXIMIZE 0xf030 #define SC_NEXTWINDOW 0xf040 #define SC_PREVWINDOW 0xf050 #define SC_CLOSE 0xf060 #define SC_VSCROLL 0xf070 #define SC_HSCROLL 0xf080 #define SC_MOUSEMENU 0xf090 #define SC_KEYMENU 0xf100 #define SC_ARRANGE 0xf110 #define SC_RESTORE 0xf120 #define SC_TASKLIST 0xf130 #define SC_SCREENSAVE 0xf140 #define SC_HOTKEY 0xf150 #define CS_VREDRAW 0x0001 #define CS_HREDRAW 0x0002 #define CS_KEYCVTWINDOW 0x0004 #define CS_DBLCLKS 0x0008 #define CS_OWNDC 0x0020 #define CS_CLASSDC 0x0040 #define CS_PARENTDC 0x0080 #define CS_NOKEYCVT 0x0100 #define CS_NOCLOSE 0x0200 #define CS_SAVEBITS 0x0800 #define CS_BYTEALIGNCLIENT 0x1000 #define CS_BYTEALIGNWINDOW 0x2000 #define CS_GLOBALCLASS 0x4000 #define CS_IME 0x00010000 #define PRF_CHECKVISIBLE 0x00000001L #define PRF_NONCLIENT 0x00000002L #define PRF_CLIENT 0x00000004L #define PRF_ERASEBKGND 0x00000008L #define PRF_CHILDREN 0x00000010L #define PRF_OWNED 0x00000020L /* Offsets for GetClassLong() and GetClassWord() */ #define GCL_MENUNAME (-8) #define GCW_HBRBACKGROUND (-10) #define GCL_HBRBACKGROUND GCW_HBRBACKGROUND #define GCW_HCURSOR (-12) #define GCL_HCURSOR GCW_HCURSOR #define GCW_HICON (-14) #define GCL_HICON GCW_HICON #define GCW_HMODULE (-16) #define GCL_HMODULE GCW_HMODULE #define GCW_CBWNDEXTRA (-18) #define GCL_CBWNDEXTRA GCW_CBWNDEXTRA #define GCW_CBCLSEXTRA (-20) #define GCL_CBCLSEXTRA GCW_CBCLSEXTRA #define GCL_WNDPROC (-24) #define GCW_STYLE (-26) #define GCL_STYLE GCW_STYLE #define GCW_ATOM (-32) #define GCW_HICONSM (-34) #define GCL_HICONSM GCW_HICONSM /***** Window hooks *****/ /* Hook values */ #define WH_MIN (-1) #define WH_MSGFILTER (-1) #define WH_JOURNALRECORD 0 #define WH_JOURNALPLAYBACK 1 #define WH_KEYBOARD 2 #define WH_GETMESSAGE 3 #define WH_CALLWNDPROC 4 #define WH_CBT 5 #define WH_SYSMSGFILTER 6 #define WH_MOUSE 7 #define WH_HARDWARE 8 #define WH_DEBUG 9 #define WH_SHELL 10 #define WH_FOREGROUNDIDLE 11 #define WH_CALLWNDPROCRET 12 #define WH_MAX 12 #define WH_MINHOOK WH_MIN #define WH_MAXHOOK WH_MAX #define WH_NB_HOOKS (WH_MAXHOOK-WH_MINHOOK+1) /* Hook action codes */ #define HC_ACTION 0 #define HC_GETNEXT 1 #define HC_SKIP 2 #define HC_NOREMOVE 3 #define HC_NOREM HC_NOREMOVE #define HC_SYSMODALON 4 #define HC_SYSMODALOFF 5 /* CallMsgFilter() values */ #define MSGF_DIALOGBOX 0 #define MSGF_MESSAGEBOX 1 #define MSGF_MENU 2 #define MSGF_MOVE 3 #define MSGF_SIZE 4 #define MSGF_SCROLLBAR 5 #define MSGF_NEXTWINDOW 6 #define MSGF_MAINLOOP 8 #define MSGF_USER 4096 typedef struct { UINT style; WNDPROC lpfnWndProc; INT cbClsExtra; INT cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCSTR lpszMenuName; LPCSTR lpszClassName; } WNDCLASSA, *LPWNDCLASSA; typedef struct { UINT style; WNDPROC lpfnWndProc; INT cbClsExtra; INT cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCWSTR lpszMenuName; LPCWSTR lpszClassName; } WNDCLASSW, *LPWNDCLASSW; DECL_WINELIB_TYPE_AW(WNDCLASS) DECL_WINELIB_TYPE_AW(LPWNDCLASS) typedef struct { DWORD dwData; DWORD cbData; LPVOID lpData; } COPYDATASTRUCT, *PCOPYDATASTRUCT, *LPCOPYDATASTRUCT; typedef struct { HMENU hmenuIn; HMENU hmenuNext; HWND hwndNext; } MDINEXTMENU, *PMDINEXTMENU, *LPMDINEXTMENU; /* WinHelp internal structure */ typedef struct { WORD size; WORD command; LONG data; LONG reserved; WORD ofsFilename; WORD ofsData; } WINHELP,*LPWINHELP; typedef struct { UINT16 mkSize; BYTE mkKeyList; BYTE szKeyphrase[1]; } MULTIKEYHELP, *LPMULTIKEYHELP; typedef struct { WORD wStructSize; WORD x; WORD y; WORD dx; WORD dy; WORD wMax; char rgchMember[2]; } HELPWININFO, *LPHELPWININFO; #define HELP_CONTEXT 0x0001 #define HELP_QUIT 0x0002 #define HELP_INDEX 0x0003 #define HELP_CONTENTS 0x0003 #define HELP_HELPONHELP 0x0004 #define HELP_SETINDEX 0x0005 #define HELP_SETCONTENTS 0x0005 #define HELP_CONTEXTPOPUP 0x0008 #define HELP_FORCEFILE 0x0009 #define HELP_KEY 0x0101 #define HELP_COMMAND 0x0102 #define HELP_PARTIALKEY 0x0105 #define HELP_MULTIKEY 0x0201 #define HELP_SETWINPOS 0x0203 #define HELP_CONTEXTMENU 0x000a #define HELP_FINDER 0x000b #define HELP_WM_HELP 0x000c #define HELP_SETPOPUP_POS 0x000d #define HELP_TCARD 0x8000 #define HELP_TCARD_DATA 0x0010 #define HELP_TCARD_OTHER_CALLER 0x0011 /* ChangeDisplaySettings return codes */ #define DISP_CHANGE_SUCCESSFUL 0 #define DISP_CHANGE_RESTART 1 #define DISP_CHANGE_FAILED (-1) #define DISP_CHANGE_BADMODE (-2) #define DISP_CHANGE_NOTUPDATED (-3) #define DISP_CHANGE_BADFLAGS (-4) #define DISP_CHANGE_BADPARAM (-5) /* ChangeDisplaySettings.dwFlags */ #define CDS_UPDATEREGISTRY 0x00000001 #define CDS_TEST 0x00000002 #define CDS_FULLSCREEN 0x00000004 #define CDS_GLOBAL 0x00000008 #define CDS_SET_PRIMARY 0x00000010 #define CDS_RESET 0x40000000 #define CDS_SETRECT 0x20000000 #define CDS_NORESET 0x10000000 /* flags to FormatMessage */ #define FORMAT_MESSAGE_ALLOCATE_BUFFER 0x00000100 #define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200 #define FORMAT_MESSAGE_FROM_STRING 0x00000400 #define FORMAT_MESSAGE_FROM_HMODULE 0x00000800 #define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000 #define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000 #define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF typedef struct { UINT cbSize; UINT style; WNDPROC lpfnWndProc; INT cbClsExtra; INT cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCSTR lpszMenuName; LPCSTR lpszClassName; HICON hIconSm; } WNDCLASSEXA, *LPWNDCLASSEXA; typedef struct { UINT cbSize; UINT style; WNDPROC lpfnWndProc; INT cbClsExtra; INT cbWndExtra; HINSTANCE hInstance; HICON hIcon; HCURSOR hCursor; HBRUSH hbrBackground; LPCWSTR lpszMenuName; LPCWSTR lpszClassName; HICON hIconSm; } WNDCLASSEXW, *LPWNDCLASSEXW; DECL_WINELIB_TYPE_AW(WNDCLASSEX) DECL_WINELIB_TYPE_AW(LPWNDCLASSEX) typedef struct tagMSG { HWND hwnd; UINT message; WPARAM wParam; LPARAM lParam; DWORD time; POINT pt; } MSG, *LPMSG; #define POINTSTOPOINT(pt, pts) \ { (pt).x = (LONG)(SHORT)LOWORD(*(LONG*)&pts); \ (pt).y = (LONG)(SHORT)HIWORD(*(LONG*)&pts); } #define POINTTOPOINTS(pt) (MAKELONG((short)((pt).x), (short)((pt).y))) /* Cursors / Icons */ typedef struct { WIN_BOOL fIcon; DWORD xHotspot; DWORD yHotspot; HBITMAP hbmMask; HBITMAP hbmColor; } ICONINFO,*LPICONINFO; /* this is the 6 byte accel struct used in Win32 when presented to the user */ typedef struct { BYTE fVirt; BYTE pad0; WORD key; WORD cmd; } ACCEL, *LPACCEL; /* this is the 8 byte accel struct used in Win32 resources (internal only) */ typedef struct { BYTE fVirt; BYTE pad0; WORD key; WORD cmd; WORD pad1; } PE_ACCEL, *LPPE_ACCEL; /* Flags for TrackPopupMenu */ #define TPM_LEFTBUTTON 0x0000 #define TPM_RIGHTBUTTON 0x0002 #define TPM_LEFTALIGN 0x0000 #define TPM_CENTERALIGN 0x0004 #define TPM_RIGHTALIGN 0x0008 #define TPM_TOPALIGN 0x0000 #define TPM_VCENTERALIGN 0x0010 #define TPM_BOTTOMALIGN 0x0020 #define TPM_HORIZONTAL 0x0000 #define TPM_VERTICAL 0x0040 #define TPM_NONOTIFY 0x0080 #define TPM_RETURNCMD 0x0100 typedef struct { UINT cbSize; RECT rcExclude; } TPMPARAMS, *LPTPMPARAMS; /* FIXME: not sure this one is correct */ typedef struct { UINT cbSize; UINT fMask; UINT fType; UINT fState; UINT wID; HMENU hSubMenu; HBITMAP hbmpChecked; HBITMAP hbmpUnchecked; DWORD dwItemData; LPSTR dwTypeData; UINT cch; HBITMAP hbmpItem; } MENUITEMINFOA, *LPMENUITEMINFOA; typedef struct { UINT cbSize; UINT fMask; UINT fType; UINT fState; UINT wID; HMENU hSubMenu; HBITMAP hbmpChecked; HBITMAP hbmpUnchecked; DWORD dwItemData; LPWSTR dwTypeData; UINT cch; HBITMAP hbmpItem; } MENUITEMINFOW, *LPMENUITEMINFOW; DECL_WINELIB_TYPE_AW(MENUITEMINFO) DECL_WINELIB_TYPE_AW(LPMENUITEMINFO) typedef struct { DWORD cbSize; DWORD fMask; DWORD dwStyle; UINT cyMax; HBRUSH hbrBack; DWORD dwContextHelpID; DWORD dwMenuData; } MENUINFO, *LPMENUINFO; typedef MENUINFO const * LPCMENUINFO; #define MIM_MAXHEIGHT 0x00000001 #define MIM_BACKGROUND 0x00000002 #define MIM_HELPID 0x00000004 #define MIM_MENUDATA 0x00000008 #define MIM_STYLE 0x00000010 #define MIM_APPLYTOSUBMENUS 0x80000000 typedef struct { WORD versionNumber; WORD offset; } MENUITEMTEMPLATEHEADER, *PMENUITEMTEMPLATEHEADER; typedef struct { WORD mtOption; WORD mtID; WCHAR mtString[1]; } MENUITEMTEMPLATE, *PMENUITEMTEMPLATE; typedef VOID MENUTEMPLATE; typedef PVOID *LPMENUTEMPLATE; /* Field specifiers for MENUITEMINFO[AW] type. */ #define MIIM_STATE 0x00000001 #define MIIM_ID 0x00000002 #define MIIM_SUBMENU 0x00000004 #define MIIM_CHECKMARKS 0x00000008 #define MIIM_TYPE 0x00000010 #define MIIM_DATA 0x00000020 #define MIIM_STRING 0x00000040 #define MIIM_BITMAP 0x00000080 #define MIIM_FTYPE 0x00000100 #define HBMMENU_CALLBACK ((HBITMAP) -1) #define HBMMENU_SYSTEM ((HBITMAP) 1) #define HBMMENU_MBAR_RESTORE ((HBITMAP) 2) #define HBMMENU_MBAR_MINIMIZE ((HBITMAP) 3) #define HBMMENU_MBAR_CLOSE ((HBITMAP) 5) #define HBMMENU_MBAR_CLOSE_D ((HBITMAP) 6) #define HBMMENU_MBAR_MINIMIZE_D ((HBITMAP) 7) #define HBMMENU_POPUP_CLOSE ((HBITMAP) 8) #define HBMMENU_POPUP_RESTORE ((HBITMAP) 9) #define HBMMENU_POPUP_MAXIMIZE ((HBITMAP) 10) #define HBMMENU_POPUP_MINIMIZE ((HBITMAP) 11) /* DrawState defines ... */ typedef WIN_BOOL CALLBACK (*DRAWSTATEPROC)(HDC,LPARAM,WPARAM,INT,INT); /* WM_H/VSCROLL commands */ #define SB_LINEUP 0 #define SB_LINELEFT 0 #define SB_LINEDOWN 1 #define SB_LINERIGHT 1 #define SB_PAGEUP 2 #define SB_PAGELEFT 2 #define SB_PAGEDOWN 3 #define SB_PAGERIGHT 3 #define SB_THUMBPOSITION 4 #define SB_THUMBTRACK 5 #define SB_TOP 6 #define SB_LEFT 6 #define SB_BOTTOM 7 #define SB_RIGHT 7 #define SB_ENDSCROLL 8 /* Scroll bar selection constants */ #define SB_HORZ 0 #define SB_VERT 1 #define SB_CTL 2 #define SB_BOTH 3 /* Scrollbar styles */ #define SBS_HORZ 0x0000L #define SBS_VERT 0x0001L #define SBS_TOPALIGN 0x0002L #define SBS_LEFTALIGN 0x0002L #define SBS_BOTTOMALIGN 0x0004L #define SBS_RIGHTALIGN 0x0004L #define SBS_SIZEBOXTOPLEFTALIGN 0x0002L #define SBS_SIZEBOXBOTTOMRIGHTALIGN 0x0004L #define SBS_SIZEBOX 0x0008L #define SBS_SIZEGRIP 0x0010L /* EnableScrollBar() flags */ #define ESB_ENABLE_BOTH 0x0000 #define ESB_DISABLE_BOTH 0x0003 #define ESB_DISABLE_LEFT 0x0001 #define ESB_DISABLE_RIGHT 0x0002 #define ESB_DISABLE_UP 0x0001 #define ESB_DISABLE_DOWN 0x0002 #define ESB_DISABLE_LTUP ESB_DISABLE_LEFT #define ESB_DISABLE_RTDN ESB_DISABLE_RIGHT /* Win32 button control messages */ #define BM_GETCHECK 0x00f0 #define BM_SETCHECK 0x00f1 #define BM_GETSTATE 0x00f2 #define BM_SETSTATE 0x00f3 #define BM_SETSTYLE 0x00f4 #define BM_CLICK 0x00f5 #define BM_GETIMAGE 0x00f6 #define BM_SETIMAGE 0x00f7 /* Winelib button control messages */ /* Button notification codes */ #define BN_CLICKED 0 #define BN_PAINT 1 #define BN_HILITE 2 #define BN_UNHILITE 3 #define BN_DISABLE 4 #define BN_DOUBLECLICKED 5 /* Button states */ #define BST_UNCHECKED 0x0000 #define BST_CHECKED 0x0001 #define BST_INDETERMINATE 0x0002 #define BST_PUSHED 0x0004 #define BST_FOCUS 0x0008 /* Static Control Styles */ #define SS_LEFT 0x00000000L #define SS_CENTER 0x00000001L #define SS_RIGHT 0x00000002L #define SS_ICON 0x00000003L #define SS_BLACKRECT 0x00000004L #define SS_GRAYRECT 0x00000005L #define SS_WHITERECT 0x00000006L #define SS_BLACKFRAME 0x00000007L #define SS_GRAYFRAME 0x00000008L #define SS_WHITEFRAME 0x00000009L #define SS_SIMPLE 0x0000000BL #define SS_LEFTNOWORDWRAP 0x0000000CL #define SS_OWNERDRAW 0x0000000DL #define SS_BITMAP 0x0000000EL #define SS_ENHMETAFILE 0x0000000FL #define SS_ETCHEDHORZ 0x00000010L #define SS_ETCHEDVERT 0x00000011L #define SS_ETCHEDFRAME 0x00000012L #define SS_TYPEMASK 0x0000001FL #define SS_NOPREFIX 0x00000080L #define SS_NOTIFY 0x00000100L #define SS_CENTERIMAGE 0x00000200L #define SS_RIGHTJUST 0x00000400L #define SS_REALSIZEIMAGE 0x00000800L #define SS_SUNKEN 0x00001000L /* Static Control Messages */ #define STM_SETICON 0x0170 #define STM_GETICON 0x0171 #define STM_SETIMAGE 0x0172 #define STM_GETIMAGE 0x0173 /* Scrollbar messages */ #define SBM_SETPOS 0x00e0 #define SBM_GETPOS 0x00e1 #define SBM_SETRANGE 0x00e2 #define SBM_GETRANGE 0x00e3 #define SBM_ENABLE_ARROWS 0x00e4 #define SBM_SETRANGEREDRAW 0x00e6 #define SBM_SETSCROLLINFO 0x00e9 #define SBM_GETSCROLLINFO 0x00ea /* Scrollbar info */ typedef struct { UINT cbSize; UINT fMask; INT nMin; INT nMax; UINT nPage; INT nPos; INT nTrackPos; } SCROLLINFO, *LPSCROLLINFO; /* GetScrollInfo() flags */ #define SIF_RANGE 0x0001 #define SIF_PAGE 0x0002 #define SIF_POS 0x0004 #define SIF_DISABLENOSCROLL 0x0008 #define SIF_TRACKPOS 0x0010 #define SIF_ALL (SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS) /* Listbox styles */ #define LBS_NOTIFY 0x0001 #define LBS_SORT 0x0002 #define LBS_NOREDRAW 0x0004 #define LBS_MULTIPLESEL 0x0008 #define LBS_OWNERDRAWFIXED 0x0010 #define LBS_OWNERDRAWVARIABLE 0x0020 #define LBS_HASSTRINGS 0x0040 #define LBS_USETABSTOPS 0x0080 #define LBS_NOINTEGRALHEIGHT 0x0100 #define LBS_MULTICOLUMN 0x0200 #define LBS_WANTKEYBOARDINPUT 0x0400 #define LBS_EXTENDEDSEL 0x0800 #define LBS_DISABLENOSCROLL 0x1000 #define LBS_NODATA 0x2000 #define LBS_NOSEL 0x4000 #define LBS_STANDARD (LBS_NOTIFY | LBS_SORT | WS_VSCROLL | WS_BORDER) /* Listbox messages */ #define LB_ADDSTRING 0x0180 #define LB_INSERTSTRING 0x0181 #define LB_DELETESTRING 0x0182 #define LB_SELITEMRANGEEX 0x0183 #define LB_RESETCONTENT 0x0184 #define LB_SETSEL 0x0185 #define LB_SETCURSEL 0x0186 #define LB_GETSEL 0x0187 #define LB_GETCURSEL 0x0188 #define LB_GETTEXT 0x0189 #define LB_GETTEXTLEN 0x018a #define LB_GETCOUNT 0x018b #define LB_SELECTSTRING 0x018c #define LB_DIR 0x018d #define LB_GETTOPINDEX 0x018e #define LB_FINDSTRING 0x018f #define LB_GETSELCOUNT 0x0190 #define LB_GETSELITEMS 0x0191 #define LB_SETTABSTOPS 0x0192 #define LB_GETHORIZONTALEXTENT 0x0193 #define LB_SETHORIZONTALEXTENT 0x0194 #define LB_SETCOLUMNWIDTH 0x0195 #define LB_ADDFILE 0x0196 #define LB_SETTOPINDEX 0x0197 #define LB_GETITEMRECT 0x0198 #define LB_GETITEMDATA 0x0199 #define LB_SETITEMDATA 0x019a #define LB_SELITEMRANGE 0x019b #define LB_SETANCHORINDEX 0x019c #define LB_GETANCHORINDEX 0x019d #define LB_SETCARETINDEX 0x019e #define LB_GETCARETINDEX 0x019f #define LB_SETITEMHEIGHT 0x01a0 #define LB_GETITEMHEIGHT 0x01a1 #define LB_FINDSTRINGEXACT 0x01a2 #define LB_CARETON 0x01a3 #define LB_CARETOFF 0x01a4 #define LB_SETLOCALE 0x01a5 #define LB_GETLOCALE 0x01a6 #define LB_SETCOUNT 0x01a7 #define LB_INITSTORAGE 0x01a8 #define LB_ITEMFROMPOINT 0x01a9 /* Listbox notification codes */ #define LBN_ERRSPACE (-2) #define LBN_SELCHANGE 1 #define LBN_DBLCLK 2 #define LBN_SELCANCEL 3 #define LBN_SETFOCUS 4 #define LBN_KILLFOCUS 5 /* Listbox message return values */ #define LB_OKAY 0 #define LB_ERR (-1) #define LB_ERRSPACE (-2) #define LB_CTLCODE 0L /* Combo box styles */ #define CBS_SIMPLE 0x0001L #define CBS_DROPDOWN 0x0002L #define CBS_DROPDOWNLIST 0x0003L #define CBS_OWNERDRAWFIXED 0x0010L #define CBS_OWNERDRAWVARIABLE 0x0020L #define CBS_AUTOHSCROLL 0x0040L #define CBS_OEMCONVERT 0x0080L #define CBS_SORT 0x0100L #define CBS_HASSTRINGS 0x0200L #define CBS_NOINTEGRALHEIGHT 0x0400L #define CBS_DISABLENOSCROLL 0x0800L #define CBS_UPPERCASE 0x2000L #define CBS_LOWERCASE 0x4000L /* Combo box messages */ #define CB_GETEDITSEL 0x0140 #define CB_LIMITTEXT 0x0141 #define CB_SETEDITSEL 0x0142 #define CB_ADDSTRING 0x0143 #define CB_DELETESTRING 0x0144 #define CB_DIR 0x0145 #define CB_GETCOUNT 0x0146 #define CB_GETCURSEL 0x0147 #define CB_GETLBTEXT 0x0148 #define CB_GETLBTEXTLEN 0x0149 #define CB_INSERTSTRING 0x014a #define CB_RESETCONTENT 0x014b #define CB_FINDSTRING 0x014c #define CB_SELECTSTRING 0x014d #define CB_SETCURSEL 0x014e #define CB_SHOWDROPDOWN 0x014f #define CB_GETITEMDATA 0x0150 #define CB_SETITEMDATA 0x0151 #define CB_GETDROPPEDCONTROLRECT 0x0152 #define CB_SETITEMHEIGHT 0x0153 #define CB_GETITEMHEIGHT 0x0154 #define CB_SETEXTENDEDUI 0x0155 #define CB_GETEXTENDEDUI 0x0156 #define CB_GETDROPPEDSTATE 0x0157 #define CB_FINDSTRINGEXACT 0x0158 #define CB_SETLOCALE 0x0159 #define CB_GETLOCALE 0x015a #define CB_GETTOPINDEX 0x015b #define CB_SETTOPINDEX 0x015c #define CB_GETHORIZONTALEXTENT 0x015d #define CB_SETHORIZONTALEXTENT 0x015e #define CB_GETDROPPEDWIDTH 0x015f #define CB_SETDROPPEDWIDTH 0x0160 #define CB_INITSTORAGE 0x0161 /* Combo box notification codes */ #define CBN_ERRSPACE (-1) #define CBN_SELCHANGE 1 #define CBN_DBLCLK 2 #define CBN_SETFOCUS 3 #define CBN_KILLFOCUS 4 #define CBN_EDITCHANGE 5 #define CBN_EDITUPDATE 6 #define CBN_DROPDOWN 7 #define CBN_CLOSEUP 8 #define CBN_SELENDOK 9 #define CBN_SELENDCANCEL 10 /* Combo box message return values */ #define CB_OKAY 0 #define CB_ERR (-1) #define CB_ERRSPACE (-2) #define MB_OK 0x00000000 #define MB_OKCANCEL 0x00000001 #define MB_ABORTRETRYIGNORE 0x00000002 #define MB_YESNOCANCEL 0x00000003 #define MB_YESNO 0x00000004 #define MB_RETRYCANCEL 0x00000005 #define MB_TYPEMASK 0x0000000F #define MB_ICONHAND 0x00000010 #define MB_ICONQUESTION 0x00000020 #define MB_ICONEXCLAMATION 0x00000030 #define MB_ICONASTERISK 0x00000040 #define MB_USERICON 0x00000080 #define MB_ICONMASK 0x000000F0 #define MB_ICONINFORMATION MB_ICONASTERISK #define MB_ICONSTOP MB_ICONHAND #define MB_ICONWARNING MB_ICONEXCLAMATION #define MB_ICONERROR MB_ICONHAND #define MB_DEFBUTTON1 0x00000000 #define MB_DEFBUTTON2 0x00000100 #define MB_DEFBUTTON3 0x00000200 #define MB_DEFBUTTON4 0x00000300 #define MB_DEFMASK 0x00000F00 #define MB_APPLMODAL 0x00000000 #define MB_SYSTEMMODAL 0x00001000 #define MB_TASKMODAL 0x00002000 #define MB_MODEMASK 0x00003000 #define MB_HELP 0x00004000 #define MB_NOFOCUS 0x00008000 #define MB_MISCMASK 0x0000C000 #define MB_SETFOREGROUND 0x00010000 #define MB_DEFAULT_DESKTOP_ONLY 0x00020000 #define MB_SERVICE_NOTIFICATION 0x00040000 #define MB_TOPMOST 0x00040000 #define MB_RIGHT 0x00080000 #define MB_RTLREADING 0x00100000 #define HELPINFO_WINDOW 0x0001 #define HELPINFO_MENUITEM 0x0002 /* Structure pointed to by lParam of WM_HELP */ typedef struct { UINT cbSize; /* Size in bytes of this struct */ INT iContextType; /* Either HELPINFO_WINDOW or HELPINFO_MENUITEM */ INT iCtrlId; /* Control Id or a Menu item Id. */ HANDLE hItemHandle; /* hWnd of control or hMenu. */ DWORD dwContextId; /* Context Id associated with this item */ POINT MousePos; /* Mouse Position in screen co-ordinates */ } HELPINFO,*LPHELPINFO; typedef void CALLBACK (*MSGBOXCALLBACK)(LPHELPINFO lpHelpInfo); typedef struct { UINT cbSize; HWND hwndOwner; HINSTANCE hInstance; LPCSTR lpszText; LPCSTR lpszCaption; DWORD dwStyle; LPCSTR lpszIcon; DWORD dwContextHelpId; MSGBOXCALLBACK lpfnMsgBoxCallback; DWORD dwLanguageId; } MSGBOXPARAMSA,*LPMSGBOXPARAMSA; typedef struct { UINT cbSize; HWND hwndOwner; HINSTANCE hInstance; LPCWSTR lpszText; LPCWSTR lpszCaption; DWORD dwStyle; LPCWSTR lpszIcon; DWORD dwContextHelpId; MSGBOXCALLBACK lpfnMsgBoxCallback; DWORD dwLanguageId; } MSGBOXPARAMSW,*LPMSGBOXPARAMSW; DECL_WINELIB_TYPE_AW(MSGBOXPARAMS) DECL_WINELIB_TYPE_AW(LPMSGBOXPARAMS) typedef struct _numberfmt32a { UINT NumDigits; UINT LeadingZero; UINT Grouping; LPCSTR lpDecimalSep; LPCSTR lpThousandSep; UINT NegativeOrder; } NUMBERFMTA; typedef struct _numberfmt32w { UINT NumDigits; UINT LeadingZero; UINT Grouping; LPCWSTR lpDecimalSep; LPCWSTR lpThousandSep; UINT NegativeOrder; } NUMBERFMTW; typedef struct _currencyfmt32a { UINT NumDigits; UINT LeadingZero; UINT Grouping; LPCSTR lpDecimalSep; LPCSTR lpThousandSep; UINT NegativeOrder; UINT PositiveOrder; LPCSTR lpCurrencySymbol; } CURRENCYFMTA; typedef struct _currencyfmt32w { UINT NumDigits; UINT LeadingZero; UINT Grouping; LPCWSTR lpDecimalSep; LPCWSTR lpThousandSep; UINT NegativeOrder; UINT PositiveOrder; LPCWSTR lpCurrencySymbol; } CURRENCYFMTW; #define MONITOR_DEFAULTTONULL 0x00000000 #define MONITOR_DEFAULTTOPRIMARY 0x00000001 #define MONITOR_DEFAULTTONEAREST 0x00000002 #define MONITORINFOF_PRIMARY 0x00000001 typedef struct tagMONITORINFO { DWORD cbSize; RECT rcMonitor; RECT rcWork; DWORD dwFlags; } MONITORINFO, *LPMONITORINFO; typedef WIN_BOOL CALLBACK (*MONITORENUMPROC)(HMONITOR,HDC,LPRECT,LPARAM); /* FIXME: use this instead of LPCVOID for CreateDialogIndirectParam and DialogBoxIndirectParam */ typedef struct tagDLGTEMPLATE { DWORD style; DWORD dwExtendedStyle; WORD cdit; short x; short y; short cx; short cy; } DLGTEMPLATE; typedef DLGTEMPLATE *LPDLGTEMPLATEA; typedef DLGTEMPLATE *LPDLGTEMPLATEW; #define LPDLGTEMPLATE WINELIB_NAME_AW(LPDLGTEMPLATE) typedef const DLGTEMPLATE *LPCDLGTEMPLATEA; typedef const DLGTEMPLATE *LPCDLGTEMPLATEW; #define LPCDLGTEMPLATE WINELIB_NAME_AW(LPCDLGTEMPLATE) typedef struct tagDLGITEMTEMPLATE { DWORD style; DWORD dwExtendedStyle; short x; short y; short cx; short cy; WORD id; } DLGITEMTEMPLATE; typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEA; typedef DLGITEMTEMPLATE *LPDLGITEMTEMPLATEW; #define LPDLGITEMTEMPLATE WINELIB_NAME_AW(LPDLGITEMTEMPLATE) typedef const DLGITEMTEMPLATE *LPCDLGITEMTEMPLATEA; typedef const DLGITEMTEMPLATE *LPCDLGITEMTEMPLATEW; #define LPCDLGITEMTEMPLATE WINELIB_NAME_AW(LPCDLGITEMTEMPLATE) /* CBT hook values */ #define HCBT_MOVESIZE 0 #define HCBT_MINMAX 1 #define HCBT_QS 2 #define HCBT_CREATEWND 3 #define HCBT_DESTROYWND 4 #define HCBT_ACTIVATE 5 #define HCBT_CLICKSKIPPED 6 #define HCBT_KEYSKIPPED 7 #define HCBT_SYSCOMMAND 8 #define HCBT_SETFOCUS 9 /* CBT hook structures */ typedef struct { CREATESTRUCTA *lpcs; HWND hwndInsertAfter; } CBT_CREATEWNDA, *LPCBT_CREATEWNDA; typedef struct { CREATESTRUCTW *lpcs; HWND hwndInsertAfter; } CBT_CREATEWNDW, *LPCBT_CREATEWNDW; DECL_WINELIB_TYPE_AW(CBT_CREATEWND) DECL_WINELIB_TYPE_AW(LPCBT_CREATEWND) typedef struct { WIN_BOOL fMouse; HWND hWndActive; } CBTACTIVATESTRUCT, *LPCBTACTIVATESTRUCT; /* modifiers for RegisterHotKey */ #define MOD_ALT 0x0001 #define MOD_CONTROL 0x0002 #define MOD_SHIFT 0x0004 #define MOD_WIN 0x0008 /* ids for RegisterHotKey */ #define IDHOT_SNAPWINDOW (-1) /* SHIFT-PRINTSCRN */ #define IDHOT_SNAPDESKTOP (-2) /* PRINTSCRN */ /* keybd_event flags */ #define KEYEVENTF_EXTENDEDKEY 0x0001 #define KEYEVENTF_KEYUP 0x0002 #define KEYEVENTF_WINE_FORCEEXTENDED 0x8000 /* mouse_event flags */ #define MOUSEEVENTF_MOVE 0x0001 #define MOUSEEVENTF_LEFTDOWN 0x0002 #define MOUSEEVENTF_LEFTUP 0x0004 #define MOUSEEVENTF_RIGHTDOWN 0x0008 #define MOUSEEVENTF_RIGHTUP 0x0010 #define MOUSEEVENTF_MIDDLEDOWN 0x0020 #define MOUSEEVENTF_MIDDLEUP 0x0040 #define MOUSEEVENTF_WHEEL 0x0800 #define MOUSEEVENTF_ABSOLUTE 0x8000 /* ExitWindows() flags */ #define EW_RESTARTWINDOWS 0x0042 #define EW_REBOOTSYSTEM 0x0043 #define EW_EXITANDEXECAPP 0x0044 /* ExitWindowsEx() flags */ #define EWX_LOGOFF 0 #define EWX_SHUTDOWN 1 #define EWX_REBOOT 2 #define EWX_FORCE 4 #define EWX_POWEROFF 8 /* SetLastErrorEx types */ #define SLE_ERROR 0x00000001 #define SLE_MINORERROR 0x00000002 #define SLE_WARNING 0x00000003 /* Predefined resources */ #define IDI_APPLICATIONA MAKEINTRESOURCEA(32512) #define IDI_APPLICATIONW MAKEINTRESOURCEW(32512) #define IDI_APPLICATION WINELIB_NAME_AW(IDI_APPLICATION) #define IDI_HANDA MAKEINTRESOURCEA(32513) #define IDI_HANDW MAKEINTRESOURCEW(32513) #define IDI_HAND WINELIB_NAME_AW(IDI_HAND) #define IDI_QUESTIONA MAKEINTRESOURCEA(32514) #define IDI_QUESTIONW MAKEINTRESOURCEW(32514) #define IDI_QUESTION WINELIB_NAME_AW(IDI_QUESTION) #define IDI_EXCLAMATIONA MAKEINTRESOURCEA(32515) #define IDI_EXCLAMATIONW MAKEINTRESOURCEW(32515) #define IDI_EXCLAMATION WINELIB_NAME_AW(IDI_EXCLAMATION) #define IDI_ASTERISKA MAKEINTRESOURCEA(32516) #define IDI_ASTERISKW MAKEINTRESOURCEW(32516) #define IDI_ASTERISK WINELIB_NAME_AW(IDI_ASTERISK) #define IDC_BUMMERA MAKEINTRESOURCEA(100) #define IDC_BUMMERW MAKEINTRESOURCEW(100) #define IDC_BUMMER WINELIB_NAME_AW(IDC_BUMMER) #define IDC_ARROWA MAKEINTRESOURCEA(32512) #define IDC_ARROWW MAKEINTRESOURCEW(32512) #define IDC_ARROW WINELIB_NAME_AW(IDC_ARROW) #define IDC_IBEAMA MAKEINTRESOURCEA(32513) #define IDC_IBEAMW MAKEINTRESOURCEW(32513) #define IDC_IBEAM WINELIB_NAME_AW(IDC_IBEAM) #define IDC_WAITA MAKEINTRESOURCEA(32514) #define IDC_WAITW MAKEINTRESOURCEW(32514) #define IDC_WAIT WINELIB_NAME_AW(IDC_WAIT) #define IDC_CROSSA MAKEINTRESOURCEA(32515) #define IDC_CROSSW MAKEINTRESOURCEW(32515) #define IDC_CROSS WINELIB_NAME_AW(IDC_CROSS) #define IDC_UPARROWA MAKEINTRESOURCEA(32516) #define IDC_UPARROWW MAKEINTRESOURCEW(32516) #define IDC_UPARROW WINELIB_NAME_AW(IDC_UPARROW) #define IDC_SIZEA MAKEINTRESOURCEA(32640) #define IDC_SIZEW MAKEINTRESOURCEW(32640) #define IDC_SIZE WINELIB_NAME_AW(IDC_SIZE) #define IDC_ICONA MAKEINTRESOURCEA(32641) #define IDC_ICONW MAKEINTRESOURCEW(32641) #define IDC_ICON WINELIB_NAME_AW(IDC_ICON) #define IDC_SIZENWSEA MAKEINTRESOURCEA(32642) #define IDC_SIZENWSEW MAKEINTRESOURCEW(32642) #define IDC_SIZENWSE WINELIB_NAME_AW(IDC_SIZENWSE) #define IDC_SIZENESWA MAKEINTRESOURCEA(32643) #define IDC_SIZENESWW MAKEINTRESOURCEW(32643) #define IDC_SIZENESW WINELIB_NAME_AW(IDC_SIZENESW) #define IDC_SIZEWEA MAKEINTRESOURCEA(32644) #define IDC_SIZEWEW MAKEINTRESOURCEW(32644) #define IDC_SIZEWE WINELIB_NAME_AW(IDC_SIZEWE) #define IDC_SIZENSA MAKEINTRESOURCEA(32645) #define IDC_SIZENSW MAKEINTRESOURCEW(32645) #define IDC_SIZENS WINELIB_NAME_AW(IDC_SIZENS) #define IDC_SIZEALLA MAKEINTRESOURCEA(32646) #define IDC_SIZEALLW MAKEINTRESOURCEW(32646) #define IDC_SIZEALL WINELIB_NAME_AW(IDC_SIZEALL) #define IDC_NOA MAKEINTRESOURCEA(32648) #define IDC_NOW MAKEINTRESOURCEW(32648) #define IDC_NO WINELIB_NAME_AW(IDC_NO) #define IDC_APPSTARTINGA MAKEINTRESOURCEA(32650) #define IDC_APPSTARTINGW MAKEINTRESOURCEW(32650) #define IDC_APPSTARTING WINELIB_NAME_AW(IDC_APPSTARTING) #define IDC_HELPA MAKEINTRESOURCEA(32651) #define IDC_HELPW MAKEINTRESOURCEW(32651) #define IDC_HELP WINELIB_NAME_AW(IDC_HELP) #define MNC_IGNORE 0 #define MNC_CLOSE 1 #define MNC_EXECUTE 2 #define MNC_SELECT 3 /* SystemParametersInfo */ /* defines below are for all win versions */ #define SPI_GETBEEP 1 #define SPI_SETBEEP 2 #define SPI_GETMOUSE 3 #define SPI_SETMOUSE 4 #define SPI_GETBORDER 5 #define SPI_SETBORDER 6 #define SPI_GETKEYBOARDSPEED 10 #define SPI_SETKEYBOARDSPEED 11 #define SPI_LANGDRIVER 12 #define SPI_ICONHORIZONTALSPACING 13 #define SPI_GETSCREENSAVETIMEOUT 14 #define SPI_SETSCREENSAVETIMEOUT 15 #define SPI_GETSCREENSAVEACTIVE 16 #define SPI_SETSCREENSAVEACTIVE 17 #define SPI_GETGRIDGRANULARITY 18 #define SPI_SETGRIDGRANULARITY 19 #define SPI_SETDESKWALLPAPER 20 #define SPI_SETDESKPATTERN 21 #define SPI_GETKEYBOARDDELAY 22 #define SPI_SETKEYBOARDDELAY 23 #define SPI_ICONVERTICALSPACING 24 #define SPI_GETICONTITLEWRAP 25 #define SPI_SETICONTITLEWRAP 26 #define SPI_GETMENUDROPALIGNMENT 27 #define SPI_SETMENUDROPALIGNMENT 28 #define SPI_SETDOUBLECLKWIDTH 29 #define SPI_SETDOUBLECLKHEIGHT 30 #define SPI_GETICONTITLELOGFONT 31 #define SPI_SETDOUBLECLICKTIME 32 #define SPI_SETMOUSEBUTTONSWAP 33 #define SPI_SETICONTITLELOGFONT 34 #define SPI_GETFASTTASKSWITCH 35 #define SPI_SETFASTTASKSWITCH 36 #define SPI_SETDRAGFULLWINDOWS 37 #define SPI_GETDRAGFULLWINDOWS 38 #define SPI_GETFILTERKEYS 50 #define SPI_SETFILTERKEYS 51 #define SPI_GETTOGGLEKEYS 52 #define SPI_SETTOGGLEKEYS 53 #define SPI_GETMOUSEKEYS 54 #define SPI_SETMOUSEKEYS 55 #define SPI_GETSHOWSOUNDS 56 #define SPI_SETSHOWSOUNDS 57 #define SPI_GETSTICKYKEYS 58 #define SPI_SETSTICKYKEYS 59 #define SPI_GETACCESSTIMEOUT 60 #define SPI_SETACCESSTIMEOUT 61 #define SPI_GETSOUNDSENTRY 64 #define SPI_SETSOUNDSENTRY 65 /* defines below are for all win versions WINVER >= 0x0400 */ #define SPI_SETDRAGFULLWINDOWS 37 #define SPI_GETDRAGFULLWINDOWS 38 #define SPI_GETNONCLIENTMETRICS 41 #define SPI_SETNONCLIENTMETRICS 42 #define SPI_GETMINIMIZEDMETRICS 43 #define SPI_SETMINIMIZEDMETRICS 44 #define SPI_GETICONMETRICS 45 #define SPI_SETICONMETRICS 46 #define SPI_SETWORKAREA 47 #define SPI_GETWORKAREA 48 #define SPI_SETPENWINDOWS 49 #define SPI_GETSERIALKEYS 62 #define SPI_SETSERIALKEYS 63 #define SPI_GETHIGHCONTRAST 66 #define SPI_SETHIGHCONTRAST 67 #define SPI_GETKEYBOARDPREF 68 #define SPI_SETKEYBOARDPREF 69 #define SPI_GETSCREENREADER 70 #define SPI_SETSCREENREADER 71 #define SPI_GETANIMATION 72 #define SPI_SETANIMATION 73 #define SPI_GETFONTSMOOTHING 74 #define SPI_SETFONTSMOOTHING 75 #define SPI_SETDRAGWIDTH 76 #define SPI_SETDRAGHEIGHT 77 #define SPI_SETHANDHELD 78 #define SPI_GETLOWPOWERTIMEOUT 79 #define SPI_GETPOWEROFFTIMEOUT 80 #define SPI_SETLOWPOWERTIMEOUT 81 #define SPI_SETPOWEROFFTIMEOUT 82 #define SPI_GETLOWPOWERACTIVE 83 #define SPI_GETPOWEROFFACTIVE 84 #define SPI_SETLOWPOWERACTIVE 85 #define SPI_SETPOWEROFFACTIVE 86 #define SPI_SETCURSORS 87 #define SPI_SETICONS 88 #define SPI_GETDEFAULTINPUTLANG 89 #define SPI_SETDEFAULTINPUTLANG 90 #define SPI_SETLANGTOGGLE 91 #define SPI_GETWINDOWSEXTENSION 92 #define SPI_SETMOUSETRAILS 93 #define SPI_GETMOUSETRAILS 94 #define SPI_SETSCREENSAVERRUNNING 97 #define SPI_SCREENSAVERRUNNING SPI_SETSCREENSAVERRUNNING /* defines below are for all win versions (_WIN32_WINNT >= 0x0400) || * (_WIN32_WINDOWS > 0x0400) */ #define SPI_GETMOUSEHOVERWIDTH 98 #define SPI_SETMOUSEHOVERWIDTH 99 #define SPI_GETMOUSEHOVERHEIGHT 100 #define SPI_SETMOUSEHOVERHEIGHT 101 #define SPI_GETMOUSEHOVERTIME 102 #define SPI_SETMOUSEHOVERTIME 103 #define SPI_GETWHEELSCROLLLINES 104 #define SPI_SETWHEELSCROLLLINES 105 #define SPI_GETSHOWIMEUI 110 #define SPI_SETSHOWIMEUI 111 /* defines below are for all win versions WINVER >= 0x0500 */ #define SPI_GETMOUSESPEED 112 #define SPI_SETMOUSESPEED 113 #define SPI_GETSCREENSAVERRUNNING 114 #define SPI_GETACTIVEWINDOWTRACKING 0x1000 #define SPI_SETACTIVEWINDOWTRACKING 0x1001 #define SPI_GETMENUANIMATION 0x1002 #define SPI_SETMENUANIMATION 0x1003 #define SPI_GETCOMBOBOXANIMATION 0x1004 #define SPI_SETCOMBOBOXANIMATION 0x1005 #define SPI_GETLISTBOXSMOOTHSCROLLING 0x1006 #define SPI_SETLISTBOXSMOOTHSCROLLING 0x1007 #define SPI_GETGRADIENTCAPTIONS 0x1008 #define SPI_SETGRADIENTCAPTIONS 0x1009 #define SPI_GETMENUUNDERLINES 0x100A #define SPI_SETMENUUNDERLINES 0x100B #define SPI_GETACTIVEWNDTRKZORDER 0x100C #define SPI_SETACTIVEWNDTRKZORDER 0x100D #define SPI_GETHOTTRACKING 0x100E #define SPI_SETHOTTRACKING 0x100F #define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 #define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 #define SPI_GETACTIVEWNDTRKTIMEOUT 0x2002 #define SPI_SETACTIVEWNDTRKTIMEOUT 0x2003 #define SPI_GETFOREGROUNDFLASHCOUNT 0x2004 #define SPI_SETFOREGROUNDFLASHCOUNT 0x2005 /* SystemParametersInfo flags */ #define SPIF_UPDATEINIFILE 1 #define SPIF_SENDWININICHANGE 2 #define SPIF_SENDCHANGE SPIF_SENDWININICHANGE /* Window Styles */ #define WS_OVERLAPPED 0x00000000L #define WS_POPUP 0x80000000L #define WS_CHILD 0x40000000L #define WS_MINIMIZE 0x20000000L #define WS_VISIBLE 0x10000000L #define WS_DISABLED 0x08000000L #define WS_CLIPSIBLINGS 0x04000000L #define WS_CLIPCHILDREN 0x02000000L #define WS_MAXIMIZE 0x01000000L #define WS_CAPTION 0x00C00000L #define WS_BORDER 0x00800000L #define WS_DLGFRAME 0x00400000L #define WS_VSCROLL 0x00200000L #define WS_HSCROLL 0x00100000L #define WS_SYSMENU 0x00080000L #define WS_THICKFRAME 0x00040000L #define WS_GROUP 0x00020000L #define WS_TABSTOP 0x00010000L #define WS_MINIMIZEBOX 0x00020000L #define WS_MAXIMIZEBOX 0x00010000L #define WS_TILED WS_OVERLAPPED #define WS_ICONIC WS_MINIMIZE #define WS_SIZEBOX WS_THICKFRAME #define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME| WS_MINIMIZEBOX | WS_MAXIMIZEBOX) #define WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU) #define WS_CHILDWINDOW (WS_CHILD) #define WS_TILEDWINDOW (WS_OVERLAPPEDWINDOW) /* Window extended styles */ #define WS_EX_DLGMODALFRAME 0x00000001L #define WS_EX_DRAGDETECT 0x00000002L #define WS_EX_NOPARENTNOTIFY 0x00000004L #define WS_EX_TOPMOST 0x00000008L #define WS_EX_ACCEPTFILES 0x00000010L #define WS_EX_TRANSPARENT 0x00000020L /* New Win95/WinNT4 styles */ #define WS_EX_MDICHILD 0x00000040L #define WS_EX_TOOLWINDOW 0x00000080L #define WS_EX_WINDOWEDGE 0x00000100L #define WS_EX_CLIENTEDGE 0x00000200L #define WS_EX_CONTEXTHELP 0x00000400L #define WS_EX_RIGHT 0x00001000L #define WS_EX_LEFT 0x00000000L #define WS_EX_RTLREADING 0x00002000L #define WS_EX_LTRREADING 0x00000000L #define WS_EX_LEFTSCROLLBAR 0x00004000L #define WS_EX_RIGHTSCROLLBAR 0x00000000L #define WS_EX_CONTROLPARENT 0x00010000L #define WS_EX_STATICEDGE 0x00020000L #define WS_EX_APPWINDOW 0x00040000L #define WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE|WS_EX_CLIENTEDGE) #define WS_EX_PALETTEWINDOW (WS_EX_WINDOWEDGE|WS_EX_TOOLWINDOW|WS_EX_TOPMOST) /* WINE internal... */ #define WS_EX_TRAYWINDOW 0x80000000L /* Window scrolling */ #define SW_SCROLLCHILDREN 0x0001 #define SW_INVALIDATE 0x0002 #define SW_ERASE 0x0004 /* CreateWindow() coordinates */ #define CW_USEDEFAULT ((INT)0x80000000) /* ChildWindowFromPointEx Flags */ #define CWP_ALL 0x0000 #define CWP_SKIPINVISIBLE 0x0001 #define CWP_SKIPDISABLED 0x0002 #define CWP_SKIPTRANSPARENT 0x0004 /* PeekMessage() options */ #define PM_NOREMOVE 0x0000 #define PM_REMOVE 0x0001 #define PM_NOYIELD 0x0002 /* WM_SHOWWINDOW wParam codes */ #define SW_PARENTCLOSING 1 #define SW_OTHERMAXIMIZED 2 #define SW_PARENTOPENING 3 #define SW_OTHERRESTORED 4 /* ShowWindow() codes */ #define SW_HIDE 0 #define SW_SHOWNORMAL 1 #define SW_NORMAL 1 #define SW_SHOWMINIMIZED 2 #define SW_SHOWMAXIMIZED 3 #define SW_MAXIMIZE 3 #define SW_SHOWNOACTIVATE 4 #define SW_SHOW 5 #define SW_MINIMIZE 6 #define SW_SHOWMINNOACTIVE 7 #define SW_SHOWNA 8 #define SW_RESTORE 9 #define SW_SHOWDEFAULT 10 #define SW_MAX 10 #define SW_NORMALNA 0xCC /* undoc. flag in MinMaximize */ /* WM_SIZE message wParam values */ #define SIZE_RESTORED 0 #define SIZE_MINIMIZED 1 #define SIZE_MAXIMIZED 2 #define SIZE_MAXSHOW 3 #define SIZE_MAXHIDE 4 #define SIZENORMAL SIZE_RESTORED #define SIZEICONIC SIZE_MINIMIZED #define SIZEFULLSCREEN SIZE_MAXIMIZED #define SIZEZOOMSHOW SIZE_MAXSHOW #define SIZEZOOMHIDE SIZE_MAXHIDE /* SetWindowPos() and WINDOWPOS flags */ #define SWP_NOSIZE 0x0001 #define SWP_NOMOVE 0x0002 #define SWP_NOZORDER 0x0004 #define SWP_NOREDRAW 0x0008 #define SWP_NOACTIVATE 0x0010 #define SWP_FRAMECHANGED 0x0020 /* The frame changed: send WM_NCCALCSIZE */ #define SWP_SHOWWINDOW 0x0040 #define SWP_HIDEWINDOW 0x0080 #define SWP_NOCOPYBITS 0x0100 #define SWP_NOOWNERZORDER 0x0200 /* Don't do owner Z ordering */ #define SWP_DRAWFRAME SWP_FRAMECHANGED #define SWP_NOREPOSITION SWP_NOOWNERZORDER #define SWP_NOSENDCHANGING 0x0400 #define SWP_DEFERERASE 0x2000 #define SWP_ASYNCWINDOWPOS 0x4000 #define HWND_DESKTOP ((HWND)0) #define HWND_BROADCAST ((HWND)0xffff) /* SetWindowPos() hwndInsertAfter field values */ #define HWND_TOP ((HWND)0) #define HWND_BOTTOM ((HWND)1) #define HWND_TOPMOST ((HWND)-1) #define HWND_NOTOPMOST ((HWND)-2) #define MF_INSERT 0x0000 #define MF_CHANGE 0x0080 #define MF_APPEND 0x0100 #define MF_DELETE 0x0200 #define MF_REMOVE 0x1000 #define MF_END 0x0080 #define MF_ENABLED 0x0000 #define MF_GRAYED 0x0001 #define MF_DISABLED 0x0002 #define MF_STRING 0x0000 #define MF_BITMAP 0x0004 #define MF_UNCHECKED 0x0000 #define MF_CHECKED 0x0008 #define MF_POPUP 0x0010 #define MF_MENUBARBREAK 0x0020 #define MF_MENUBREAK 0x0040 #define MF_UNHILITE 0x0000 #define MF_HILITE 0x0080 #define MF_OWNERDRAW 0x0100 #define MF_USECHECKBITMAPS 0x0200 #define MF_BYCOMMAND 0x0000 #define MF_BYPOSITION 0x0400 #define MF_SEPARATOR 0x0800 #define MF_DEFAULT 0x1000 #define MF_SYSMENU 0x2000 #define MF_HELP 0x4000 #define MF_RIGHTJUSTIFY 0x4000 #define MF_MOUSESELECT 0x8000 /* Flags for extended menu item types. */ #define MFT_STRING MF_STRING #define MFT_BITMAP MF_BITMAP #define MFT_MENUBARBREAK MF_MENUBARBREAK #define MFT_MENUBREAK MF_MENUBREAK #define MFT_OWNERDRAW MF_OWNERDRAW #define MFT_RADIOCHECK 0x00000200L #define MFT_SEPARATOR MF_SEPARATOR #define MFT_RIGHTORDER 0x00002000L #define MFT_RIGHTJUSTIFY MF_RIGHTJUSTIFY /* Flags for extended menu item states. */ #define MFS_GRAYED 0x00000003L #define MFS_DISABLED MFS_GRAYED #define MFS_CHECKED MF_CHECKED #define MFS_HILITE MF_HILITE #define MFS_ENABLED MF_ENABLED #define MFS_UNCHECKED MF_UNCHECKED #define MFS_UNHILITE MF_UNHILITE #define MFS_DEFAULT MF_DEFAULT #define MFS_MASK 0x0000108BL #define MFS_HOTTRACKDRAWN 0x10000000L #define MFS_CACHEDBMP 0x20000000L #define MFS_BOTTOMGAPDROP 0x40000000L #define MFS_TOPGAPDROP 0x80000000L #define MFS_GAPDROP 0xC0000000L /* for GetMenuDefaultItem */ #define GMDI_USEDISABLED 0x0001L #define GMDI_GOINTOPOPUPS 0x0002L #define DT_TOP 0 #define DT_LEFT 0 #define DT_CENTER 1 #define DT_RIGHT 2 #define DT_VCENTER 4 #define DT_BOTTOM 8 #define DT_WORDBREAK 16 #define DT_SINGLELINE 32 #define DT_EXPANDTABS 64 #define DT_TABSTOP 128 #define DT_NOCLIP 256 #define DT_EXTERNALLEADING 512 #define DT_CALCRECT 1024 #define DT_NOPREFIX 2048 #define DT_INTERNAL 4096 /* DrawCaption()/DrawCaptionTemp() flags */ #define DC_ACTIVE 0x0001 #define DC_SMALLCAP 0x0002 #define DC_ICON 0x0004 #define DC_TEXT 0x0008 #define DC_INBUTTON 0x0010 /* DrawEdge() flags */ #define BDR_RAISEDOUTER 0x0001 #define BDR_SUNKENOUTER 0x0002 #define BDR_RAISEDINNER 0x0004 #define BDR_SUNKENINNER 0x0008 #define BDR_OUTER 0x0003 #define BDR_INNER 0x000c #define BDR_RAISED 0x0005 #define BDR_SUNKEN 0x000a #define EDGE_RAISED (BDR_RAISEDOUTER | BDR_RAISEDINNER) #define EDGE_SUNKEN (BDR_SUNKENOUTER | BDR_SUNKENINNER) #define EDGE_ETCHED (BDR_SUNKENOUTER | BDR_RAISEDINNER) #define EDGE_BUMP (BDR_RAISEDOUTER | BDR_SUNKENINNER) /* border flags */ #define BF_LEFT 0x0001 #define BF_TOP 0x0002 #define BF_RIGHT 0x0004 #define BF_BOTTOM 0x0008 #define BF_DIAGONAL 0x0010 #define BF_MIDDLE 0x0800 /* Fill in the middle */ #define BF_SOFT 0x1000 /* For softer buttons */ #define BF_ADJUST 0x2000 /* Calculate the space left over */ #define BF_FLAT 0x4000 /* For flat rather than 3D borders */ #define BF_MONO 0x8000 /* For monochrome borders */ #define BF_TOPLEFT (BF_TOP | BF_LEFT) #define BF_TOPRIGHT (BF_TOP | BF_RIGHT) #define BF_BOTTOMLEFT (BF_BOTTOM | BF_LEFT) #define BF_BOTTOMRIGHT (BF_BOTTOM | BF_RIGHT) #define BF_RECT (BF_LEFT | BF_TOP | BF_RIGHT | BF_BOTTOM) #define BF_DIAGONAL_ENDTOPRIGHT (BF_DIAGONAL | BF_TOP | BF_RIGHT) #define BF_DIAGONAL_ENDTOPLEFT (BF_DIAGONAL | BF_TOP | BF_LEFT) #define BF_DIAGONAL_ENDBOTTOMLEFT (BF_DIAGONAL | BF_BOTTOM | BF_LEFT) #define BF_DIAGONAL_ENDBOTTOMRIGHT (BF_DIAGONAL | BF_BOTTOM | BF_RIGHT) /* DrawFrameControl() uType's */ #define DFC_CAPTION 1 #define DFC_MENU 2 #define DFC_SCROLL 3 #define DFC_BUTTON 4 /* uState's */ #define DFCS_CAPTIONCLOSE 0x0000 #define DFCS_CAPTIONMIN 0x0001 #define DFCS_CAPTIONMAX 0x0002 #define DFCS_CAPTIONRESTORE 0x0003 #define DFCS_CAPTIONHELP 0x0004 /* Windows 95 only */ #define DFCS_MENUARROW 0x0000 #define DFCS_MENUCHECK 0x0001 #define DFCS_MENUBULLET 0x0002 #define DFCS_MENUARROWRIGHT 0x0004 #define DFCS_SCROLLUP 0x0000 #define DFCS_SCROLLDOWN 0x0001 #define DFCS_SCROLLLEFT 0x0002 #define DFCS_SCROLLRIGHT 0x0003 #define DFCS_SCROLLCOMBOBOX 0x0005 #define DFCS_SCROLLSIZEGRIP 0x0008 #define DFCS_SCROLLSIZEGRIPRIGHT 0x0010 #define DFCS_BUTTONCHECK 0x0000 #define DFCS_BUTTONRADIOIMAGE 0x0001 #define DFCS_BUTTONRADIOMASK 0x0002 /* to draw nonsquare button */ #define DFCS_BUTTONRADIO 0x0004 #define DFCS_BUTTON3STATE 0x0008 #define DFCS_BUTTONPUSH 0x0010 /* additional state of the control */ #define DFCS_INACTIVE 0x0100 #define DFCS_PUSHED 0x0200 #define DFCS_CHECKED 0x0400 #define DFCS_ADJUSTRECT 0x2000 /* exclude surrounding edge */ #define DFCS_FLAT 0x4000 #define DFCS_MONO 0x8000 /* Image type */ #define DST_COMPLEX 0x0000 #define DST_TEXT 0x0001 #define DST_PREFIXTEXT 0x0002 #define DST_ICON 0x0003 #define DST_BITMAP 0x0004 /* State type */ #define DSS_NORMAL 0x0000 #define DSS_UNION 0x0010 /* Gray string appearance */ #define DSS_DISABLED 0x0020 #define DSS_DEFAULT 0x0040 /* Make it bold */ #define DSS_MONO 0x0080 #define DSS_RIGHT 0x8000 typedef struct { UINT CtlType; UINT CtlID; UINT itemID; UINT itemAction; UINT itemState; HWND hwndItem; HDC hDC; RECT rcItem WINE_PACKED; DWORD itemData WINE_PACKED; } DRAWITEMSTRUCT, *PDRAWITEMSTRUCT, *LPDRAWITEMSTRUCT; typedef struct { UINT CtlType; UINT CtlID; UINT itemID; UINT itemWidth; UINT itemHeight; DWORD itemData; } MEASUREITEMSTRUCT, *PMEASUREITEMSTRUCT, *LPMEASUREITEMSTRUCT; typedef struct { UINT CtlType; UINT CtlID; UINT itemID; HWND hwndItem; DWORD itemData; } DELETEITEMSTRUCT, *LPDELETEITEMSTRUCT; typedef struct { UINT CtlType; UINT CtlID; HWND hwndItem; UINT itemID1; DWORD itemData1; UINT itemID2; DWORD itemData2; DWORD dwLocaleId; } COMPAREITEMSTRUCT, *PCOMPAREITEMSTRUCT, *LPCOMPAREITEMSTRUCT; /* WM_KEYUP/DOWN/CHAR HIWORD(lParam) flags */ #define KF_EXTENDED 0x0100 #define KF_DLGMODE 0x0800 #define KF_MENUMODE 0x1000 #define KF_ALTDOWN 0x2000 #define KF_REPEAT 0x4000 #define KF_UP 0x8000 /* Virtual key codes */ #define VK_LBUTTON 0x01 #define VK_RBUTTON 0x02 #define VK_CANCEL 0x03 #define VK_MBUTTON 0x04 /* 0x05-0x07 Undefined */ #define VK_BACK 0x08 #define VK_TAB 0x09 /* 0x0A-0x0B Undefined */ #define VK_CLEAR 0x0C #define VK_RETURN 0x0D /* 0x0E-0x0F Undefined */ #define VK_SHIFT 0x10 #define VK_CONTROL 0x11 #define VK_MENU 0x12 #define VK_PAUSE 0x13 #define VK_CAPITAL 0x14 /* 0x15-0x19 Reserved for Kanji systems */ /* 0x1A Undefined */ #define VK_ESCAPE 0x1B /* 0x1C-0x1F Reserved for Kanji systems */ #define VK_SPACE 0x20 #define VK_PRIOR 0x21 #define VK_NEXT 0x22 #define VK_END 0x23 #define VK_HOME 0x24 #define VK_LEFT 0x25 #define VK_UP 0x26 #define VK_RIGHT 0x27 #define VK_DOWN 0x28 #define VK_SELECT 0x29 #define VK_PRINT 0x2A /* OEM specific in Windows 3.1 SDK */ #define VK_EXECUTE 0x2B #define VK_SNAPSHOT 0x2C #define VK_INSERT 0x2D #define VK_DELETE 0x2E #define VK_HELP 0x2F #define VK_0 0x30 #define VK_1 0x31 #define VK_2 0x32 #define VK_3 0x33 #define VK_4 0x34 #define VK_5 0x35 #define VK_6 0x36 #define VK_7 0x37 #define VK_8 0x38 #define VK_9 0x39 /* 0x3A-0x40 Undefined */ #define VK_A 0x41 #define VK_B 0x42 #define VK_C 0x43 #define VK_D 0x44 #define VK_E 0x45 #define VK_F 0x46 #define VK_G 0x47 #define VK_H 0x48 #define VK_I 0x49 #define VK_J 0x4A #define VK_K 0x4B #define VK_L 0x4C #define VK_M 0x4D #define VK_N 0x4E #define VK_O 0x4F #define VK_P 0x50 #define VK_Q 0x51 #define VK_R 0x52 #define VK_S 0x53 #define VK_T 0x54 #define VK_U 0x55 #define VK_V 0x56 #define VK_W 0x57 #define VK_X 0x58 #define VK_Y 0x59 #define VK_Z 0x5A #define VK_LWIN 0x5B #define VK_RWIN 0x5C #define VK_APPS 0x5D /* 0x5E-0x5F Unassigned */ #define VK_NUMPAD0 0x60 #define VK_NUMPAD1 0x61 #define VK_NUMPAD2 0x62 #define VK_NUMPAD3 0x63 #define VK_NUMPAD4 0x64 #define VK_NUMPAD5 0x65 #define VK_NUMPAD6 0x66 #define VK_NUMPAD7 0x67 #define VK_NUMPAD8 0x68 #define VK_NUMPAD9 0x69 #define VK_MULTIPLY 0x6A #define VK_ADD 0x6B #define VK_SEPARATOR 0x6C #define VK_SUBTRACT 0x6D #define VK_DECIMAL 0x6E #define VK_DIVIDE 0x6F #define VK_F1 0x70 #define VK_F2 0x71 #define VK_F3 0x72 #define VK_F4 0x73 #define VK_F5 0x74 #define VK_F6 0x75 #define VK_F7 0x76 #define VK_F8 0x77 #define VK_F9 0x78 #define VK_F10 0x79 #define VK_F11 0x7A #define VK_F12 0x7B #define VK_F13 0x7C #define VK_F14 0x7D #define VK_F15 0x7E #define VK_F16 0x7F #define VK_F17 0x80 #define VK_F18 0x81 #define VK_F19 0x82 #define VK_F20 0x83 #define VK_F21 0x84 #define VK_F22 0x85 #define VK_F23 0x86 #define VK_F24 0x87 /* 0x88-0x8F Unassigned */ #define VK_NUMLOCK 0x90 #define VK_SCROLL 0x91 /* 0x92-0x9F Unassigned */ /* * differencing between right and left shift/control/alt key. * Used only by GetAsyncKeyState() and GetKeyState(). */ #define VK_LSHIFT 0xA0 #define VK_RSHIFT 0xA1 #define VK_LCONTROL 0xA2 #define VK_RCONTROL 0xA3 #define VK_LMENU 0xA4 #define VK_RMENU 0xA5 /* 0xA6-0xB9 Unassigned */ #define VK_OEM_1 0xBA #define VK_OEM_PLUS 0xBB #define VK_OEM_COMMA 0xBC #define VK_OEM_MINUS 0xBD #define VK_OEM_PERIOD 0xBE #define VK_OEM_2 0xBF #define VK_OEM_3 0xC0 /* 0xC1-0xDA Unassigned */ #define VK_OEM_4 0xDB #define VK_OEM_5 0xDC #define VK_OEM_6 0xDD #define VK_OEM_7 0xDE /* 0xDF-0xE4 OEM specific */ #define VK_PROCESSKEY 0xE5 /* 0xE6 OEM specific */ /* 0xE7-0xE8 Unassigned */ /* 0xE9-0xF5 OEM specific */ #define VK_ATTN 0xF6 #define VK_CRSEL 0xF7 #define VK_EXSEL 0xF8 #define VK_EREOF 0xF9 #define VK_PLAY 0xFA #define VK_ZOOM 0xFB #define VK_NONAME 0xFC #define VK_PA1 0xFD #define VK_OEM_CLEAR 0xFE /* Key status flags for mouse events */ #define MK_LBUTTON 0x0001 #define MK_RBUTTON 0x0002 #define MK_SHIFT 0x0004 #define MK_CONTROL 0x0008 #define MK_MBUTTON 0x0010 /* Queue status flags */ #define QS_KEY 0x0001 #define QS_MOUSEMOVE 0x0002 #define QS_MOUSEBUTTON 0x0004 #define QS_MOUSE (QS_MOUSEMOVE | QS_MOUSEBUTTON) #define QS_POSTMESSAGE 0x0008 #define QS_TIMER 0x0010 #define QS_PAINT 0x0020 #define QS_SENDMESSAGE 0x0040 #define QS_HOTKEY 0x0080 #define QS_INPUT (QS_MOUSE | QS_KEY) #define QS_ALLEVENTS (QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY) #define QS_ALLINPUT (QS_ALLEVENTS | QS_SENDMESSAGE) #define DDL_READWRITE 0x0000 #define DDL_READONLY 0x0001 #define DDL_HIDDEN 0x0002 #define DDL_SYSTEM 0x0004 #define DDL_DIRECTORY 0x0010 #define DDL_ARCHIVE 0x0020 #define DDL_POSTMSGS 0x2000 #define DDL_DRIVES 0x4000 #define DDL_EXCLUSIVE 0x8000 /* Shell hook values */ #define HSHELL_WINDOWCREATED 1 #define HSHELL_WINDOWDESTROYED 2 #define HSHELL_ACTIVATESHELLWINDOW 3 /* Predefined Clipboard Formats */ #define CF_TEXT 1 #define CF_BITMAP 2 #define CF_METAFILEPICT 3 #define CF_SYLK 4 #define CF_DIF 5 #define CF_TIFF 6 #define CF_OEMTEXT 7 #define CF_DIB 8 #define CF_PALETTE 9 #define CF_PENDATA 10 #define CF_RIFF 11 #define CF_WAVE 12 #define CF_ENHMETAFILE 14 #define CF_HDROP 15 #define CF_LOCALE 16 #define CF_MAX 17 #define CF_OWNERDISPLAY 0x0080 #define CF_DSPTEXT 0x0081 #define CF_DSPBITMAP 0x0082 #define CF_DSPMETAFILEPICT 0x0083 /* "Private" formats don't get GlobalFree()'d */ #define CF_PRIVATEFIRST 0x0200 #define CF_PRIVATELAST 0x02FF /* "GDIOBJ" formats do get DeleteObject()'d */ #define CF_GDIOBJFIRST 0x0300 #define CF_GDIOBJLAST 0x03FF /* DragObject stuff */ typedef struct { HWND16 hWnd; HANDLE16 hScope; WORD wFlags; HANDLE16 hList; HANDLE16 hOfStruct; POINT16 pt WINE_PACKED; LONG l WINE_PACKED; } DRAGINFO, *LPDRAGINFO; #define DRAGOBJ_PROGRAM 0x0001 #define DRAGOBJ_DATA 0x0002 #define DRAGOBJ_DIRECTORY 0x0004 #define DRAGOBJ_MULTIPLE 0x0008 #define DRAGOBJ_EXTERNAL 0x8000 #define DRAG_PRINT 0x544E5250 #define DRAG_FILE 0x454C4946 /* types of LoadImage */ #define IMAGE_BITMAP 0 #define IMAGE_ICON 1 #define IMAGE_CURSOR 2 #define IMAGE_ENHMETAFILE 3 /* loadflags to LoadImage */ #define LR_DEFAULTCOLOR 0x0000 #define LR_MONOCHROME 0x0001 #define LR_COLOR 0x0002 #define LR_COPYRETURNORG 0x0004 #define LR_COPYDELETEORG 0x0008 #define LR_LOADFROMFILE 0x0010 #define LR_LOADTRANSPARENT 0x0020 #define LR_DEFAULTSIZE 0x0040 #define LR_VGA_COLOR 0x0080 #define LR_LOADMAP3DCOLORS 0x1000 #define LR_CREATEDIBSECTION 0x2000 #define LR_COPYFROMRESOURCE 0x4000 #define LR_SHARED 0x8000 /* Flags for DrawIconEx. */ #define DI_MASK 1 #define DI_IMAGE 2 #define DI_NORMAL (DI_MASK | DI_IMAGE) #define DI_COMPAT 4 #define DI_DEFAULTSIZE 8 /* misc messages */ #define WM_CPL_LAUNCH (WM_USER + 1000) #define WM_CPL_LAUNCHED (WM_USER + 1001) /* WM_NOTIFYFORMAT commands and return values */ #define NFR_ANSI 1 #define NFR_UNICODE 2 #define NF_QUERY 3 #define NF_REQUERY 4 #include "poppack.h" #define EnumTaskWindows(handle,proc,lparam) \ EnumThreadWindows(handle,proc,lparam) #define OemToAnsiA OemToCharA #define OemToAnsiW OemToCharW #define OemToAnsi WINELIB_NAME_AW(OemToAnsi) #define OemToAnsiBuffA OemToCharBuffA #define OemToAnsiBuffW OemToCharBuffW #define OemToAnsiBuff WINELIB_NAME_AW(OemToAnsiBuff) #define AnsiToOemA CharToOemA #define AnsiToOemW CharToOemW #define AnsiToOem WINELIB_NAME_AW(AnsiToOem) #define AnsiToOemBuffA CharToOemBuffA #define AnsiToOemBuffW CharToOemBuffW #define AnsiToOemBuff WINELIB_NAME_AW(AnsiToOemBuff) /* NOTE: This is SYSTEM.3, not USER.182, which is also named KillSystemTimer */ WORD WINAPI SYSTEM_KillSystemTimer( WORD ); /* Extra functions that don't exist in the Windows API */ HPEN WINAPI GetSysColorPen(INT); INT WINAPI LoadMessageA(HMODULE,UINT,WORD,LPSTR,INT); INT WINAPI LoadMessageW(HMODULE,UINT,WORD,LPWSTR,INT); VOID WINAPI ScreenSwitchEnable16(WORD); #define WC_DIALOG (LPSTR)((DWORD)((WORD)( 0x8002))) #ifdef __cplusplus } #endif #endif /* _WINUSER_ */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/winbase.h�����������������������������������������������������������0000644�0001750�0001750�00000215352�14647725152�016024� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_WINBASE_H #define __WINE_WINBASE_H #include "basetsd.h" #include "winnt.h" #include "winestring.h" #include "pshpack1.h" #ifdef __cplusplus extern "C" { #endif typedef struct tagCOORD { INT16 x; INT16 y; } COORD, *LPCOORD; /* Windows Exit Procedure flag values */ #define WEP_FREE_DLL 0 #define WEP_SYSTEM_EXIT 1 typedef DWORD CALLBACK (*LPTHREAD_START_ROUTINE)(LPVOID); #define EXCEPTION_DEBUG_EVENT 1 #define CREATE_THREAD_DEBUG_EVENT 2 #define CREATE_PROCESS_DEBUG_EVENT 3 #define EXIT_THREAD_DEBUG_EVENT 4 #define EXIT_PROCESS_DEBUG_EVENT 5 #define LOAD_DLL_DEBUG_EVENT 6 #define UNLOAD_DLL_DEBUG_EVENT 7 #define OUTPUT_DEBUG_STRING_EVENT 8 #define RIP_EVENT 9 typedef struct _EXCEPTION_DEBUG_INFO { EXCEPTION_RECORD ExceptionRecord; DWORD dwFirstChance; } EXCEPTION_DEBUG_INFO; typedef struct _CREATE_THREAD_DEBUG_INFO { HANDLE hThread; LPVOID lpThreadLocalBase; LPTHREAD_START_ROUTINE lpStartAddress; } CREATE_THREAD_DEBUG_INFO; typedef struct _CREATE_PROCESS_DEBUG_INFO { HANDLE hFile; HANDLE hProcess; HANDLE hThread; LPVOID lpBaseOfImage; DWORD dwDebugInfoFileOffset; DWORD nDebugInfoSize; LPVOID lpThreadLocalBase; LPTHREAD_START_ROUTINE lpStartAddress; LPVOID lpImageName; WORD fUnicode; } CREATE_PROCESS_DEBUG_INFO; typedef struct _EXIT_THREAD_DEBUG_INFO { DWORD dwExitCode; } EXIT_THREAD_DEBUG_INFO; typedef struct _EXIT_PROCESS_DEBUG_INFO { DWORD dwExitCode; } EXIT_PROCESS_DEBUG_INFO; typedef struct _LOAD_DLL_DEBUG_INFO { HANDLE hFile; LPVOID lpBaseOfDll; DWORD dwDebugInfoFileOffset; DWORD nDebugInfoSize; LPVOID lpImageName; WORD fUnicode; } LOAD_DLL_DEBUG_INFO; typedef struct _UNLOAD_DLL_DEBUG_INFO { LPVOID lpBaseOfDll; } UNLOAD_DLL_DEBUG_INFO; typedef struct _OUTPUT_DEBUG_STRING_INFO { LPSTR lpDebugStringData; WORD fUnicode; WORD nDebugStringLength; } OUTPUT_DEBUG_STRING_INFO; typedef struct _RIP_INFO { DWORD dwError; DWORD dwType; } RIP_INFO; typedef struct _DEBUG_EVENT { DWORD dwDebugEventCode; DWORD dwProcessId; DWORD dwThreadId; union { EXCEPTION_DEBUG_INFO Exception; CREATE_THREAD_DEBUG_INFO CreateThread; CREATE_PROCESS_DEBUG_INFO CreateProcessInfo; EXIT_THREAD_DEBUG_INFO ExitThread; EXIT_PROCESS_DEBUG_INFO ExitProcess; LOAD_DLL_DEBUG_INFO LoadDll; UNLOAD_DLL_DEBUG_INFO UnloadDll; OUTPUT_DEBUG_STRING_INFO DebugString; RIP_INFO RipInfo; } u; } DEBUG_EVENT, *LPDEBUG_EVENT; #define OFS_MAXPATHNAME 128 typedef struct { BYTE cBytes; BYTE fFixedDisk; WORD nErrCode; BYTE reserved[4]; BYTE szPathName[OFS_MAXPATHNAME]; } OFSTRUCT, *LPOFSTRUCT; #define OF_READ 0x0000 #define OF_WRITE 0x0001 #define OF_READWRITE 0x0002 #define OF_SHARE_COMPAT 0x0000 #define OF_SHARE_EXCLUSIVE 0x0010 #define OF_SHARE_DENY_WRITE 0x0020 #define OF_SHARE_DENY_READ 0x0030 #define OF_SHARE_DENY_NONE 0x0040 #define OF_PARSE 0x0100 #define OF_DELETE 0x0200 #define OF_VERIFY 0x0400 /* Used with OF_REOPEN */ #define OF_SEARCH 0x0400 /* Used without OF_REOPEN */ #define OF_CANCEL 0x0800 #define OF_CREATE 0x1000 #define OF_PROMPT 0x2000 #define OF_EXIST 0x4000 #define OF_REOPEN 0x8000 /* SetErrorMode values */ #define SEM_FAILCRITICALERRORS 0x0001 #define SEM_NOGPFAULTERRORBOX 0x0002 #define SEM_NOALIGNMENTFAULTEXCEPT 0x0004 #define SEM_NOOPENFILEERRORBOX 0x8000 /* CopyFileEx flags */ #define COPY_FILE_FAIL_IF_EXISTS 0x00000001 #define COPY_FILE_RESTARTABLE 0x00000002 #define COPY_FILE_OPEN_SOURCE_FOR_WRITE 0x00000004 /* GetTempFileName() Flags */ #define TF_FORCEDRIVE 0x80 #define DRIVE_CANNOTDETERMINE 0 #define DRIVE_DOESNOTEXIST 1 #define DRIVE_REMOVABLE 2 #define DRIVE_FIXED 3 #define DRIVE_REMOTE 4 /* Win32 additions */ #define DRIVE_CDROM 5 #define DRIVE_RAMDISK 6 /* The security attributes structure */ typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; LPVOID lpSecurityDescriptor; WIN_BOOL bInheritHandle; } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; #ifndef _FILETIME_ #define _FILETIME_ /* 64 bit number of 100 nanoseconds intervals since January 1, 1601 */ typedef struct { DWORD dwLowDateTime; DWORD dwHighDateTime; } FILETIME, *LPFILETIME; #endif /* _FILETIME_ */ /* Find* structures */ typedef struct { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD dwReserved0; DWORD dwReserved1; CHAR cFileName[260]; CHAR cAlternateFileName[14]; } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA; typedef struct { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD dwReserved0; DWORD dwReserved1; WCHAR cFileName[260]; WCHAR cAlternateFileName[14]; } WIN32_FIND_DATAW, *LPWIN32_FIND_DATAW; DECL_WINELIB_TYPE_AW(WIN32_FIND_DATA) DECL_WINELIB_TYPE_AW(LPWIN32_FIND_DATA) typedef struct { LPVOID lpData; DWORD cbData; BYTE cbOverhead; BYTE iRegionIndex; WORD wFlags; union { struct { HANDLE hMem; DWORD dwReserved[3]; } Block; struct { DWORD dwCommittedSize; DWORD dwUnCommittedSize; LPVOID lpFirstBlock; LPVOID lpLastBlock; } Region; } Foo; } PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY; #define PROCESS_HEAP_REGION 0x0001 #define PROCESS_HEAP_UNCOMMITTED_RANGE 0x0002 #define PROCESS_HEAP_ENTRY_BUSY 0x0004 #define PROCESS_HEAP_ENTRY_MOVEABLE 0x0010 #define PROCESS_HEAP_ENTRY_DDESHARE 0x0020 #define INVALID_HANDLE_VALUE16 ((HANDLE16) -1) #define INVALID_HANDLE_VALUE ((HANDLE) -1) #define TLS_OUT_OF_INDEXES ((DWORD)0xFFFFFFFF) /* comm */ #define CBR_110 0xFF10 #define CBR_300 0xFF11 #define CBR_600 0xFF12 #define CBR_1200 0xFF13 #define CBR_2400 0xFF14 #define CBR_4800 0xFF15 #define CBR_9600 0xFF16 #define CBR_14400 0xFF17 #define CBR_19200 0xFF18 #define CBR_38400 0xFF1B #define CBR_56000 0xFF1F #define CBR_128000 0xFF23 #define CBR_256000 0xFF27 #define NOPARITY 0 #define ODDPARITY 1 #define EVENPARITY 2 #define MARKPARITY 3 #define SPACEPARITY 4 #define ONESTOPBIT 0 #define ONE5STOPBITS 1 #define TWOSTOPBITS 2 #define IGNORE 0 #define INFINITE16 0xFFFF #define INFINITE 0xFFFFFFFF #define CE_RXOVER 0x0001 #define CE_OVERRUN 0x0002 #define CE_RXPARITY 0x0004 #define CE_FRAME 0x0008 #define CE_BREAK 0x0010 #define CE_CTSTO 0x0020 #define CE_DSRTO 0x0040 #define CE_RLSDTO 0x0080 #define CE_TXFULL 0x0100 #define CE_PTO 0x0200 #define CE_IOE 0x0400 #define CE_DNS 0x0800 #define CE_OOP 0x1000 #define CE_MODE 0x8000 #define IE_BADID -1 #define IE_OPEN -2 #define IE_NOPEN -3 #define IE_MEMORY -4 #define IE_DEFAULT -5 #define IE_HARDWARE -10 #define IE_BYTESIZE -11 #define IE_BAUDRATE -12 #define EV_RXCHAR 0x0001 #define EV_RXFLAG 0x0002 #define EV_TXEMPTY 0x0004 #define EV_CTS 0x0008 #define EV_DSR 0x0010 #define EV_RLSD 0x0020 #define EV_BREAK 0x0040 #define EV_ERR 0x0080 #define EV_RING 0x0100 #define EV_PERR 0x0200 #define EV_CTSS 0x0400 #define EV_DSRS 0x0800 #define EV_RLSDS 0x1000 #define EV_RINGTE 0x2000 #define EV_RingTe EV_RINGTE #define SETXOFF 1 #define SETXON 2 #define SETRTS 3 #define CLRRTS 4 #define SETDTR 5 #define CLRDTR 6 #define RESETDEV 7 #define SETBREAK 8 #define CLRBREAK 9 #define GETBASEIRQ 10 /* Purge functions for Comm Port */ #define PURGE_TXABORT 0x0001 /* Kill the pending/current writes to the comm port */ #define PURGE_RXABORT 0x0002 /*Kill the pending/current reads to the comm port */ #define PURGE_TXCLEAR 0x0004 /* Kill the transmit queue if there*/ #define PURGE_RXCLEAR 0x0008 /* Kill the typeahead buffer if there*/ /* Modem Status Flags */ #define MS_CTS_ON ((DWORD)0x0010) #define MS_DSR_ON ((DWORD)0x0020) #define MS_RING_ON ((DWORD)0x0040) #define MS_RLSD_ON ((DWORD)0x0080) #define RTS_CONTROL_DISABLE 0 #define RTS_CONTROL_ENABLE 1 #define RTS_CONTROL_HANDSHAKE 2 #define RTS_CONTROL_TOGGLE 3 #define DTR_CONTROL_DISABLE 0 #define DTR_CONTROL_ENABLE 1 #define DTR_CONTROL_HANDSHAKE 2 #define CSTF_CTSHOLD 0x01 #define CSTF_DSRHOLD 0x02 #define CSTF_RLSDHOLD 0x04 #define CSTF_XOFFHOLD 0x08 #define CSTF_XOFFSENT 0x10 #define CSTF_EOF 0x20 #define CSTF_TXIM 0x40 #define MAKEINTRESOURCEA(i) (LPSTR)((DWORD)((WORD)(i))) #define MAKEINTRESOURCEW(i) (LPWSTR)((DWORD)((WORD)(i))) #define MAKEINTRESOURCE WINELIB_NAME_AW(MAKEINTRESOURCE) /* Predefined resource types */ #define RT_CURSORA MAKEINTRESOURCEA(1) #define RT_CURSORW MAKEINTRESOURCEW(1) #define RT_CURSOR WINELIB_NAME_AW(RT_CURSOR) #define RT_BITMAPA MAKEINTRESOURCEA(2) #define RT_BITMAPW MAKEINTRESOURCEW(2) #define RT_BITMAP WINELIB_NAME_AW(RT_BITMAP) #define RT_ICONA MAKEINTRESOURCEA(3) #define RT_ICONW MAKEINTRESOURCEW(3) #define RT_ICON WINELIB_NAME_AW(RT_ICON) #define RT_MENUA MAKEINTRESOURCEA(4) #define RT_MENUW MAKEINTRESOURCEW(4) #define RT_MENU WINELIB_NAME_AW(RT_MENU) #define RT_DIALOGA MAKEINTRESOURCEA(5) #define RT_DIALOGW MAKEINTRESOURCEW(5) #define RT_DIALOG WINELIB_NAME_AW(RT_DIALOG) #define RT_STRINGA MAKEINTRESOURCEA(6) #define RT_STRINGW MAKEINTRESOURCEW(6) #define RT_STRING WINELIB_NAME_AW(RT_STRING) #define RT_FONTDIRA MAKEINTRESOURCEA(7) #define RT_FONTDIRW MAKEINTRESOURCEW(7) #define RT_FONTDIR WINELIB_NAME_AW(RT_FONTDIR) #define RT_FONTA MAKEINTRESOURCEA(8) #define RT_FONTW MAKEINTRESOURCEW(8) #define RT_FONT WINELIB_NAME_AW(RT_FONT) #define RT_ACCELERATORA MAKEINTRESOURCEA(9) #define RT_ACCELERATORW MAKEINTRESOURCEW(9) #define RT_ACCELERATOR WINELIB_NAME_AW(RT_ACCELERATOR) #define RT_RCDATAA MAKEINTRESOURCEA(10) #define RT_RCDATAW MAKEINTRESOURCEW(10) #define RT_RCDATA WINELIB_NAME_AW(RT_RCDATA) #define RT_MESSAGELISTA MAKEINTRESOURCEA(11) #define RT_MESSAGELISTW MAKEINTRESOURCEW(11) #define RT_MESSAGELIST WINELIB_NAME_AW(RT_MESSAGELIST) #define RT_GROUP_CURSORA MAKEINTRESOURCEA(12) #define RT_GROUP_CURSORW MAKEINTRESOURCEW(12) #define RT_GROUP_CURSOR WINELIB_NAME_AW(RT_GROUP_CURSOR) #define RT_GROUP_ICONA MAKEINTRESOURCEA(14) #define RT_GROUP_ICONW MAKEINTRESOURCEW(14) #define RT_GROUP_ICON WINELIB_NAME_AW(RT_GROUP_ICON) #define LMEM_FIXED 0 #define LMEM_MOVEABLE 0x0002 #define LMEM_NOCOMPACT 0x0010 #define LMEM_NODISCARD 0x0020 #define LMEM_ZEROINIT 0x0040 #define LMEM_MODIFY 0x0080 #define LMEM_DISCARDABLE 0x0F00 #define LMEM_DISCARDED 0x4000 #define LMEM_LOCKCOUNT 0x00FF #define LPTR (LMEM_FIXED | LMEM_ZEROINIT) #define GMEM_FIXED 0x0000 #define GMEM_MOVEABLE 0x0002 #define GMEM_NOCOMPACT 0x0010 #define GMEM_NODISCARD 0x0020 #define GMEM_ZEROINIT 0x0040 #define GMEM_MODIFY 0x0080 #define GMEM_DISCARDABLE 0x0100 #define GMEM_NOT_BANKED 0x1000 #define GMEM_SHARE 0x2000 #define GMEM_DDESHARE 0x2000 #define GMEM_NOTIFY 0x4000 #define GMEM_LOWER GMEM_NOT_BANKED #define GMEM_DISCARDED 0x4000 #define GMEM_LOCKCOUNT 0x00ff #define GMEM_INVALID_HANDLE 0x8000 #define GHND (GMEM_MOVEABLE | GMEM_ZEROINIT) #define GPTR (GMEM_FIXED | GMEM_ZEROINIT) typedef struct tagMEMORYSTATUS { DWORD dwLength; DWORD dwMemoryLoad; DWORD dwTotalPhys; DWORD dwAvailPhys; DWORD dwTotalPageFile; DWORD dwAvailPageFile; DWORD dwTotalVirtual; DWORD dwAvailVirtual; } MEMORYSTATUS, *LPMEMORYSTATUS; #ifndef NOLOGERROR /* LogParamError and LogError values */ /* Error modifier bits */ #define ERR_WARNING 0x8000 #define ERR_PARAM 0x4000 #define ERR_SIZE_MASK 0x3000 #define ERR_BYTE 0x1000 #define ERR_WORD 0x2000 #define ERR_DWORD 0x3000 /* LogParamError() values */ /* Generic parameter values */ #define ERR_BAD_VALUE 0x6001 #define ERR_BAD_FLAGS 0x6002 #define ERR_BAD_INDEX 0x6003 #define ERR_BAD_DVALUE 0x7004 #define ERR_BAD_DFLAGS 0x7005 #define ERR_BAD_DINDEX 0x7006 #define ERR_BAD_PTR 0x7007 #define ERR_BAD_FUNC_PTR 0x7008 #define ERR_BAD_SELECTOR 0x6009 #define ERR_BAD_STRING_PTR 0x700a #define ERR_BAD_HANDLE 0x600b /* KERNEL parameter errors */ #define ERR_BAD_HINSTANCE 0x6020 #define ERR_BAD_HMODULE 0x6021 #define ERR_BAD_GLOBAL_HANDLE 0x6022 #define ERR_BAD_LOCAL_HANDLE 0x6023 #define ERR_BAD_ATOM 0x6024 #define ERR_BAD_HFILE 0x6025 /* USER parameter errors */ #define ERR_BAD_HWND 0x6040 #define ERR_BAD_HMENU 0x6041 #define ERR_BAD_HCURSOR 0x6042 #define ERR_BAD_HICON 0x6043 #define ERR_BAD_HDWP 0x6044 #define ERR_BAD_CID 0x6045 #define ERR_BAD_HDRVR 0x6046 /* GDI parameter errors */ #define ERR_BAD_COORDS 0x7060 #define ERR_BAD_GDI_OBJECT 0x6061 #define ERR_BAD_HDC 0x6062 #define ERR_BAD_HPEN 0x6063 #define ERR_BAD_HFONT 0x6064 #define ERR_BAD_HBRUSH 0x6065 #define ERR_BAD_HBITMAP 0x6066 #define ERR_BAD_HRGN 0x6067 #define ERR_BAD_HPALETTE 0x6068 #define ERR_BAD_HMETAFILE 0x6069 /* LogError() values */ /* KERNEL errors */ #define ERR_GALLOC 0x0001 #define ERR_GREALLOC 0x0002 #define ERR_GLOCK 0x0003 #define ERR_LALLOC 0x0004 #define ERR_LREALLOC 0x0005 #define ERR_LLOCK 0x0006 #define ERR_ALLOCRES 0x0007 #define ERR_LOCKRES 0x0008 #define ERR_LOADMODULE 0x0009 /* USER errors */ #define ERR_CREATEDLG 0x0040 #define ERR_CREATEDLG2 0x0041 #define ERR_REGISTERCLASS 0x0042 #define ERR_DCBUSY 0x0043 #define ERR_CREATEWND 0x0044 #define ERR_STRUCEXTRA 0x0045 #define ERR_LOADSTR 0x0046 #define ERR_LOADMENU 0x0047 #define ERR_NESTEDBEGINPAINT 0x0048 #define ERR_BADINDEX 0x0049 #define ERR_CREATEMENU 0x004a /* GDI errors */ #define ERR_CREATEDC 0x0080 #define ERR_CREATEMETA 0x0081 #define ERR_DELOBJSELECTED 0x0082 #define ERR_SELBITMAP 0x0083 /* Debugging support (DEBUG SYSTEM ONLY) */ typedef struct { UINT16 flags; DWORD dwOptions WINE_PACKED; DWORD dwFilter WINE_PACKED; CHAR achAllocModule[8]; DWORD dwAllocBreak WINE_PACKED; DWORD dwAllocCount WINE_PACKED; } WINDEBUGINFO, *LPWINDEBUGINFO; /* WINDEBUGINFO flags values */ #define WDI_OPTIONS 0x0001 #define WDI_FILTER 0x0002 #define WDI_ALLOCBREAK 0x0004 /* dwOptions values */ #define DBO_CHECKHEAP 0x0001 #define DBO_BUFFERFILL 0x0004 #define DBO_DISABLEGPTRAPPING 0x0010 #define DBO_CHECKFREE 0x0020 #define DBO_SILENT 0x8000 #define DBO_TRACEBREAK 0x2000 #define DBO_WARNINGBREAK 0x1000 #define DBO_NOERRORBREAK 0x0800 #define DBO_NOFATALBREAK 0x0400 #define DBO_INT3BREAK 0x0100 /* DebugOutput flags values */ #define DBF_TRACE 0x0000 #define DBF_WARNING 0x4000 #define DBF_ERROR 0x8000 #define DBF_FATAL 0xc000 /* dwFilter values */ #define DBF_KERNEL 0x1000 #define DBF_KRN_MEMMAN 0x0001 #define DBF_KRN_LOADMODULE 0x0002 #define DBF_KRN_SEGMENTLOAD 0x0004 #define DBF_USER 0x0800 #define DBF_GDI 0x0400 #define DBF_MMSYSTEM 0x0040 #define DBF_PENWIN 0x0020 #define DBF_APPLICATION 0x0008 #define DBF_DRIVER 0x0010 #endif /* NOLOGERROR */ typedef struct { WORD wYear; WORD wMonth; WORD wDayOfWeek; WORD wDay; WORD wHour; WORD wMinute; WORD wSecond; WORD wMilliseconds; } SYSTEMTIME, *LPSYSTEMTIME; /* The 'overlapped' data structure used by async I/O functions. */ typedef struct { DWORD Internal; DWORD InternalHigh; DWORD Offset; DWORD OffsetHigh; HANDLE hEvent; } OVERLAPPED, *LPOVERLAPPED; /* Process startup information. */ /* STARTUPINFO.dwFlags */ #define STARTF_USESHOWWINDOW 0x00000001 #define STARTF_USESIZE 0x00000002 #define STARTF_USEPOSITION 0x00000004 #define STARTF_USECOUNTCHARS 0x00000008 #define STARTF_USEFILLATTRIBUTE 0x00000010 #define STARTF_RUNFULLSCREEN 0x00000020 #define STARTF_FORCEONFEEDBACK 0x00000040 #define STARTF_FORCEOFFFEEDBACK 0x00000080 #define STARTF_USESTDHANDLES 0x00000100 #define STARTF_USEHOTKEY 0x00000200 typedef struct { DWORD cb; /* 00: size of struct */ LPSTR lpReserved; /* 04: */ LPSTR lpDesktop; /* 08: */ LPSTR lpTitle; /* 0c: */ DWORD dwX; /* 10: */ DWORD dwY; /* 14: */ DWORD dwXSize; /* 18: */ DWORD dwYSize; /* 1c: */ DWORD dwXCountChars; /* 20: */ DWORD dwYCountChars; /* 24: */ DWORD dwFillAttribute; /* 28: */ DWORD dwFlags; /* 2c: */ WORD wShowWindow; /* 30: */ WORD cbReserved2; /* 32: */ BYTE *lpReserved2; /* 34: */ HANDLE hStdInput; /* 38: */ HANDLE hStdOutput; /* 3c: */ HANDLE hStdError; /* 40: */ } STARTUPINFOA, *LPSTARTUPINFOA; typedef struct { DWORD cb; LPWSTR lpReserved; LPWSTR lpDesktop; LPWSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars; DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; BYTE *lpReserved2; HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFOW, *LPSTARTUPINFOW; DECL_WINELIB_TYPE_AW(STARTUPINFO) DECL_WINELIB_TYPE_AW(LPSTARTUPINFO) typedef struct { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION,*LPPROCESS_INFORMATION; typedef struct { LONG Bias; WCHAR StandardName[32]; SYSTEMTIME StandardDate; LONG StandardBias; WCHAR DaylightName[32]; SYSTEMTIME DaylightDate; LONG DaylightBias; } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; #define TIME_ZONE_ID_UNKNOWN 0 #define TIME_ZONE_ID_STANDARD 1 #define TIME_ZONE_ID_DAYLIGHT 2 /* CreateProcess: dwCreationFlag values */ #define DEBUG_PROCESS 0x00000001 #define DEBUG_ONLY_THIS_PROCESS 0x00000002 #define CREATE_SUSPENDED 0x00000004 #define DETACHED_PROCESS 0x00000008 #define CREATE_NEW_CONSOLE 0x00000010 #define NORMAL_PRIORITY_CLASS 0x00000020 #define IDLE_PRIORITY_CLASS 0x00000040 #define HIGH_PRIORITY_CLASS 0x00000080 #define REALTIME_PRIORITY_CLASS 0x00000100 #define CREATE_NEW_PROCESS_GROUP 0x00000200 #define CREATE_UNICODE_ENVIRONMENT 0x00000400 #define CREATE_SEPARATE_WOW_VDM 0x00000800 #define CREATE_SHARED_WOW_VDM 0x00001000 #define CREATE_DEFAULT_ERROR_MODE 0x04000000 #define CREATE_NO_WINDOW 0x08000000 #define PROFILE_USER 0x10000000 #define PROFILE_KERNEL 0x20000000 #define PROFILE_SERVER 0x40000000 /* File object type definitions */ #define FILE_TYPE_UNKNOWN 0 #define FILE_TYPE_DISK 1 #define FILE_TYPE_CHAR 2 #define FILE_TYPE_PIPE 3 #define FILE_TYPE_REMOTE 32768 /* File creation flags */ #define FILE_FLAG_WRITE_THROUGH 0x80000000UL #define FILE_FLAG_OVERLAPPED 0x40000000L #define FILE_FLAG_NO_BUFFERING 0x20000000L #define FILE_FLAG_RANDOM_ACCESS 0x10000000L #define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000L #define FILE_FLAG_DELETE_ON_CLOSE 0x04000000L #define FILE_FLAG_BACKUP_SEMANTICS 0x02000000L #define FILE_FLAG_POSIX_SEMANTICS 0x01000000L #define CREATE_NEW 1 #define CREATE_ALWAYS 2 #define OPEN_EXISTING 3 #define OPEN_ALWAYS 4 #define TRUNCATE_EXISTING 5 /* Standard handle identifiers */ #define STD_INPUT_HANDLE ((DWORD) -10) #define STD_OUTPUT_HANDLE ((DWORD) -11) #define STD_ERROR_HANDLE ((DWORD) -12) typedef struct { int dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; int dwVolumeSerialNumber; int nFileSizeHigh; int nFileSizeLow; int nNumberOfLinks; int nFileIndexHigh; int nFileIndexLow; } BY_HANDLE_FILE_INFORMATION ; typedef struct _SYSTEM_POWER_STATUS { WIN_BOOL16 ACLineStatus; BYTE BatteryFlag; BYTE BatteryLifePercent; BYTE reserved; DWORD BatteryLifeTime; DWORD BatteryFullLifeTime; } SYSTEM_POWER_STATUS, *LPSYSTEM_POWER_STATUS; typedef struct _MEMORY_BASIC_INFORMATION { LPVOID BaseAddress; LPVOID AllocationBase; DWORD AllocationProtect; DWORD RegionSize; DWORD State; DWORD Protect; DWORD Type; } MEMORY_BASIC_INFORMATION,*LPMEMORY_BASIC_INFORMATION; typedef WIN_BOOL CALLBACK (*CODEPAGE_ENUMPROCA)(LPSTR); typedef WIN_BOOL CALLBACK (*CODEPAGE_ENUMPROCW)(LPWSTR); DECL_WINELIB_TYPE_AW(CODEPAGE_ENUMPROC) typedef WIN_BOOL CALLBACK (*LOCALE_ENUMPROCA)(LPSTR); typedef WIN_BOOL CALLBACK (*LOCALE_ENUMPROCW)(LPWSTR); DECL_WINELIB_TYPE_AW(LOCALE_ENUMPROC) typedef struct tagSYSTEM_INFO { union { DWORD dwOemId; /* Obsolete field - do not use */ struct { WORD wProcessorArchitecture; WORD wReserved; } DUMMYSTRUCTNAME; } DUMMYUNIONNAME; DWORD dwPageSize; LPVOID lpMinimumApplicationAddress; LPVOID lpMaximumApplicationAddress; DWORD dwActiveProcessorMask; DWORD dwNumberOfProcessors; DWORD dwProcessorType; DWORD dwAllocationGranularity; WORD wProcessorLevel; WORD wProcessorRevision; } SYSTEM_INFO, *LPSYSTEM_INFO; /* {G,S}etPriorityClass */ #define NORMAL_PRIORITY_CLASS 0x00000020 #define IDLE_PRIORITY_CLASS 0x00000040 #define HIGH_PRIORITY_CLASS 0x00000080 #define REALTIME_PRIORITY_CLASS 0x00000100 typedef WIN_BOOL CALLBACK (*ENUMRESTYPEPROCA)(HMODULE,LPSTR,LONG); typedef WIN_BOOL CALLBACK (*ENUMRESTYPEPROCW)(HMODULE,LPWSTR,LONG); typedef WIN_BOOL CALLBACK (*ENUMRESNAMEPROCA)(HMODULE,LPCSTR,LPSTR,LONG); typedef WIN_BOOL CALLBACK (*ENUMRESNAMEPROCW)(HMODULE,LPCWSTR,LPWSTR,LONG); typedef WIN_BOOL CALLBACK (*ENUMRESLANGPROCA)(HMODULE,LPCSTR,LPCSTR,WORD,LONG); typedef WIN_BOOL CALLBACK (*ENUMRESLANGPROCW)(HMODULE,LPCWSTR,LPCWSTR,WORD,LONG); DECL_WINELIB_TYPE_AW(ENUMRESTYPEPROC) DECL_WINELIB_TYPE_AW(ENUMRESNAMEPROC) DECL_WINELIB_TYPE_AW(ENUMRESLANGPROC) /* flags that can be passed to LoadLibraryEx */ #define DONT_RESOLVE_DLL_REFERENCES 0x00000001 #define LOAD_LIBRARY_AS_DATAFILE 0x00000002 #define LOAD_WITH_ALTERED_SEARCH_PATH 0x00000008 /* ifdef _x86_ ... */ typedef struct _LDT_ENTRY { WORD LimitLow; WORD BaseLow; union { struct { BYTE BaseMid; BYTE Flags1;/*Declare as bytes to avoid alignment problems */ BYTE Flags2; BYTE BaseHi; } Bytes; struct { unsigned BaseMid : 8; unsigned Type : 5; unsigned Dpl : 2; unsigned Pres : 1; unsigned LimitHi : 4; unsigned Sys : 1; unsigned Reserved_0 : 1; unsigned Default_Big : 1; unsigned Granularity : 1; unsigned BaseHi : 8; } Bits; } HighWord; } LDT_ENTRY, *LPLDT_ENTRY; typedef enum _GET_FILEEX_INFO_LEVELS { GetFileExInfoStandard } GET_FILEEX_INFO_LEVELS; typedef struct _WIN32_FILE_ATTRIBUTES_DATA { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; } WIN32_FILE_ATTRIBUTE_DATA, *LPWIN32_FILE_ATTRIBUTE_DATA; typedef struct _DllVersionInfo { DWORD cbSize; DWORD dwMajorVersion; DWORD dwMinorVersion; DWORD dwBuildNumber; DWORD dwPlatformID; } DLLVERSIONINFO; /* * This one seems to be a Win32 only definition. It also is defined with * WINAPI instead of CALLBACK in the windows headers. */ typedef DWORD WINAPI (*LPPROGRESS_ROUTINE)(LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, LARGE_INTEGER, DWORD, DWORD, HANDLE, HANDLE, LPVOID); #define WAIT_FAILED 0xffffffff #define WAIT_OBJECT_0 0 #define WAIT_ABANDONED STATUS_ABANDONED_WAIT_0 #define WAIT_ABANDONED_0 STATUS_ABANDONED_WAIT_0 #define WAIT_IO_COMPLETION STATUS_USER_APC #define WAIT_TIMEOUT STATUS_TIMEOUT #define STILL_ACTIVE STATUS_PENDING #define PAGE_NOACCESS 0x01 #define PAGE_READONLY 0x02 #define PAGE_READWRITE 0x04 #define PAGE_WRITECOPY 0x08 #define PAGE_EXECUTE 0x10 #define PAGE_EXECUTE_READ 0x20 #define PAGE_EXECUTE_READWRITE 0x40 #define PAGE_EXECUTE_WRITECOPY 0x80 #define PAGE_GUARD 0x100 #define PAGE_NOCACHE 0x200 #define MEM_COMMIT 0x00001000 #define MEM_RESERVE 0x00002000 #define MEM_DECOMMIT 0x00004000 #define MEM_RELEASE 0x00008000 #define MEM_FREE 0x00010000 #define MEM_PRIVATE 0x00020000 #define MEM_MAPPED 0x00040000 #define MEM_TOP_DOWN 0x00100000 #ifdef __WINE__ #define MEM_SYSTEM 0x80000000 #endif #define SEC_FILE 0x00800000 #define SEC_IMAGE 0x01000000 #define SEC_RESERVE 0x04000000 #define SEC_COMMIT 0x08000000 #define SEC_NOCACHE 0x10000000 #define FILE_BEGIN 0 #define FILE_CURRENT 1 #define FILE_END 2 #define FILE_CASE_SENSITIVE_SEARCH 0x00000001 #define FILE_CASE_PRESERVED_NAMES 0x00000002 #define FILE_UNICODE_ON_DISK 0x00000004 #define FILE_PERSISTENT_ACLS 0x00000008 #define FILE_MAP_COPY 0x00000001 #define FILE_MAP_WRITE 0x00000002 #define FILE_MAP_READ 0x00000004 #define FILE_MAP_ALL_ACCESS 0x000f001f #define MOVEFILE_REPLACE_EXISTING 0x00000001 #define MOVEFILE_COPY_ALLOWED 0x00000002 #define MOVEFILE_DELAY_UNTIL_REBOOT 0x00000004 #define FS_CASE_SENSITIVE FILE_CASE_SENSITIVE_SEARCH #define FS_CASE_IS_PRESERVED FILE_CASE_PRESERVED_NAMES #define FS_UNICODE_STORED_ON_DISK FILE_UNICODE_ON_DISK #define EXCEPTION_ACCESS_VIOLATION STATUS_ACCESS_VIOLATION #define EXCEPTION_DATATYPE_MISALIGNMENT STATUS_DATATYPE_MISALIGNMENT #define EXCEPTION_BREAKPOINT STATUS_BREAKPOINT #define EXCEPTION_SINGLE_STEP STATUS_SINGLE_STEP #define EXCEPTION_ARRAY_BOUNDS_EXCEEDED STATUS_ARRAY_BOUNDS_EXCEEDED #define EXCEPTION_FLT_DENORMAL_OPERAND STATUS_FLOAT_DENORMAL_OPERAND #define EXCEPTION_FLT_DIVIDE_BY_ZERO STATUS_FLOAT_DIVIDE_BY_ZERO #define EXCEPTION_FLT_INEXACT_RESULT STATUS_FLOAT_INEXACT_RESULT #define EXCEPTION_FLT_INVALID_OPERATION STATUS_FLOAT_INVALID_OPERATION #define EXCEPTION_FLT_OVERFLOW STATUS_FLOAT_OVERFLOW #define EXCEPTION_FLT_STACK_CHECK STATUS_FLOAT_STACK_CHECK #define EXCEPTION_FLT_UNDERFLOW STATUS_FLOAT_UNDERFLOW #define EXCEPTION_INT_DIVIDE_BY_ZERO STATUS_INTEGER_DIVIDE_BY_ZERO #define EXCEPTION_INT_OVERFLOW STATUS_INTEGER_OVERFLOW #define EXCEPTION_PRIV_INSTRUCTION STATUS_PRIVILEGED_INSTRUCTION #define EXCEPTION_IN_PAGE_ERROR STATUS_IN_PAGE_ERROR #define EXCEPTION_ILLEGAL_INSTRUCTION STATUS_ILLEGAL_INSTRUCTION #define EXCEPTION_NONCONTINUABLE_EXCEPTION STATUS_NONCONTINUABLE_EXCEPTION #define EXCEPTION_STACK_OVERFLOW STATUS_STACK_OVERFLOW #define EXCEPTION_INVALID_DISPOSITION STATUS_INVALID_DISPOSITION #define EXCEPTION_GUARD_PAGE STATUS_GUARD_PAGE_VIOLATION #define EXCEPTION_INVALID_HANDLE STATUS_INVALID_HANDLE #define CONTROL_C_EXIT STATUS_CONTROL_C_EXIT /* Wine extension; Windows doesn't have a name for this code */ #define EXCEPTION_CRITICAL_SECTION_WAIT 0xc0000194 #define DUPLICATE_CLOSE_SOURCE 0x00000001 #define DUPLICATE_SAME_ACCESS 0x00000002 #define HANDLE_FLAG_INHERIT 0x00000001 #define HANDLE_FLAG_PROTECT_FROM_CLOSE 0x00000002 #define HINSTANCE_ERROR 32 #define THREAD_PRIORITY_LOWEST THREAD_BASE_PRIORITY_MIN #define THREAD_PRIORITY_BELOW_NORMAL (THREAD_PRIORITY_LOWEST+1) #define THREAD_PRIORITY_NORMAL 0 #define THREAD_PRIORITY_HIGHEST THREAD_BASE_PRIORITY_MAX #define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST-1) #define THREAD_PRIORITY_ERROR_RETURN (0x7fffffff) #define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT #define THREAD_PRIORITY_IDLE THREAD_BASE_PRIORITY_IDLE /* Could this type be considered opaque? */ typedef struct { LPVOID DebugInfo; LONG LockCount; LONG RecursionCount; HANDLE OwningThread; HANDLE LockSemaphore; DWORD Reserved; }CRITICAL_SECTION; #ifdef __WINE__ #define CRITICAL_SECTION_INIT { 0, -1, 0, 0, 0, 0 } #endif typedef struct { DWORD dwOSVersionInfoSize; DWORD dwMajorVersion; DWORD dwMinorVersion; DWORD dwBuildNumber; DWORD dwPlatformId; CHAR szCSDVersion[128]; } OSVERSIONINFO16; typedef struct { DWORD dwOSVersionInfoSize; DWORD dwMajorVersion; DWORD dwMinorVersion; DWORD dwBuildNumber; DWORD dwPlatformId; CHAR szCSDVersion[128]; } OSVERSIONINFOA; typedef struct { DWORD dwOSVersionInfoSize; DWORD dwMajorVersion; DWORD dwMinorVersion; DWORD dwBuildNumber; DWORD dwPlatformId; WCHAR szCSDVersion[128]; } OSVERSIONINFOW; DECL_WINELIB_TYPE_AW(OSVERSIONINFO) #define VER_PLATFORM_WIN32s 0 #define VER_PLATFORM_WIN32_WINDOWS 1 #define VER_PLATFORM_WIN32_NT 2 typedef struct tagCOMSTAT { DWORD status; DWORD cbInQue; DWORD cbOutQue; } COMSTAT,*LPCOMSTAT; typedef struct tagDCB { DWORD DCBlength; DWORD BaudRate; unsigned fBinary :1; unsigned fParity :1; unsigned fOutxCtsFlow :1; unsigned fOutxDsrFlow :1; unsigned fDtrControl :2; unsigned fDsrSensitivity :1; unsigned fTXContinueOnXoff :1; unsigned fOutX :1; unsigned fInX :1; unsigned fErrorChar :1; unsigned fNull :1; unsigned fRtsControl :2; unsigned fAbortOnError :1; unsigned fDummy2 :17; WORD wReserved; WORD XonLim; WORD XoffLim; BYTE ByteSize; BYTE Parity; BYTE StopBits; char XonChar; char XoffChar; char ErrorChar; char EofChar; char EvtChar; } DCB, *LPDCB; typedef struct tagCOMMTIMEOUTS { DWORD ReadIntervalTimeout; DWORD ReadTotalTimeoutMultiplier; DWORD ReadTotalTimeoutConstant; DWORD WriteTotalTimeoutMultiplier; DWORD WriteTotalTimeoutConstant; } COMMTIMEOUTS,*LPCOMMTIMEOUTS; #include "poppack.h" typedef void CALLBACK (*PAPCFUNC)(ULONG_PTR); typedef void CALLBACK (*PTIMERAPCROUTINE)(LPVOID,DWORD,DWORD); WIN_BOOL WINAPI ClearCommError(INT,LPDWORD,LPCOMSTAT); WIN_BOOL WINAPI BuildCommDCBA(LPCSTR,LPDCB); WIN_BOOL WINAPI BuildCommDCBW(LPCWSTR,LPDCB); #define BuildCommDCB WINELIB_NAME_AW(BuildCommDCB) WIN_BOOL WINAPI BuildCommDCBAndTimeoutsA(LPCSTR,LPDCB,LPCOMMTIMEOUTS); WIN_BOOL WINAPI BuildCommDCBAndTimeoutsW(LPCWSTR,LPDCB,LPCOMMTIMEOUTS); #define BuildCommDCBAndTimeouts WINELIB_NAME_AW(BuildCommDCBAndTimeouts) WIN_BOOL WINAPI GetCommTimeouts(HANDLE,LPCOMMTIMEOUTS); WIN_BOOL WINAPI SetCommTimeouts(HANDLE,LPCOMMTIMEOUTS); WIN_BOOL WINAPI GetCommState(INT,LPDCB); WIN_BOOL WINAPI SetCommState(INT,LPDCB); WIN_BOOL WINAPI TransmitCommChar(INT,CHAR); WIN_BOOL WINAPI SetupComm(HANDLE, DWORD, DWORD); WIN_BOOL WINAPI GetCommProperties(HANDLE, LPDCB *); /*DWORD WINAPI GetVersion( void );*/ WIN_BOOL16 WINAPI GetVersionEx16(OSVERSIONINFO16*); WIN_BOOL WINAPI GetVersionExA(OSVERSIONINFOA*); WIN_BOOL WINAPI GetVersionExW(OSVERSIONINFOW*); #define GetVersionEx WINELIB_NAME_AW(GetVersionEx) /*int WinMain(HINSTANCE, HINSTANCE prev, char *cmd, int show);*/ void WINAPI DeleteCriticalSection(CRITICAL_SECTION *lpCrit); void WINAPI EnterCriticalSection(CRITICAL_SECTION *lpCrit); WIN_BOOL WINAPI TryEnterCriticalSection(CRITICAL_SECTION *lpCrit); void WINAPI InitializeCriticalSection(CRITICAL_SECTION *lpCrit); void WINAPI LeaveCriticalSection(CRITICAL_SECTION *lpCrit); void WINAPI MakeCriticalSectionGlobal(CRITICAL_SECTION *lpCrit); WIN_BOOL WINAPI GetProcessWorkingSetSize(HANDLE,LPDWORD,LPDWORD); DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,ULONG_PTR); void WINAPI RaiseException(DWORD,DWORD,DWORD,const LPDWORD); WIN_BOOL WINAPI SetProcessWorkingSetSize(HANDLE,DWORD,DWORD); WIN_BOOL WINAPI TerminateProcess(HANDLE,DWORD); WIN_BOOL WINAPI TerminateThread(HANDLE,DWORD); WIN_BOOL WINAPI GetExitCodeThread(HANDLE,LPDWORD); /* GetBinaryType return values. */ #define SCS_32BIT_BINARY 0 #define SCS_DOS_BINARY 1 #define SCS_WOW_BINARY 2 #define SCS_PIF_BINARY 3 #define SCS_POSIX_BINARY 4 #define SCS_OS216_BINARY 5 WIN_BOOL WINAPI GetBinaryTypeA( LPCSTR lpApplicationName, LPDWORD lpBinaryType ); WIN_BOOL WINAPI GetBinaryTypeW( LPCWSTR lpApplicationName, LPDWORD lpBinaryType ); #define GetBinaryType WINELIB_NAME_AW(GetBinaryType) WIN_BOOL16 WINAPI GetWinDebugInfo16(LPWINDEBUGINFO,UINT16); WIN_BOOL16 WINAPI SetWinDebugInfo16(LPWINDEBUGINFO); /* Declarations for functions that exist only in Win32 */ WIN_BOOL WINAPI AttachThreadInput(DWORD,DWORD,WIN_BOOL); WIN_BOOL WINAPI AccessCheck(PSECURITY_DESCRIPTOR,HANDLE,DWORD,PGENERIC_MAPPING,PPRIVILEGE_SET,LPDWORD,LPDWORD,LPWIN_BOOL); WIN_BOOL WINAPI AdjustTokenPrivileges(HANDLE,WIN_BOOL,LPVOID,DWORD,LPVOID,LPDWORD); WIN_BOOL WINAPI AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY,BYTE,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,DWORD,PSID *); WIN_BOOL WINAPI AllocateLocallyUniqueId(PLUID); WIN_BOOL WINAPI AllocConsole(void); WIN_BOOL WINAPI AreFileApisANSI(void); WIN_BOOL WINAPI BackupEventLogA(HANDLE,LPCSTR); WIN_BOOL WINAPI BackupEventLogW(HANDLE,LPCWSTR); #define BackupEventLog WINELIB_NAME_AW(BackupEventLog) WIN_BOOL WINAPI Beep(DWORD,DWORD); WIN_BOOL WINAPI CancelWaitableTimer(HANDLE); WIN_BOOL WINAPI ClearEventLogA(HANDLE,LPCSTR); WIN_BOOL WINAPI ClearEventLogW(HANDLE,LPCWSTR); #define ClearEventLog WINELIB_NAME_AW(ClearEventLog) WIN_BOOL WINAPI CloseEventLog(HANDLE); WIN_BOOL WINAPI CloseHandle(HANDLE); WIN_BOOL WINAPI ContinueDebugEvent(DWORD,DWORD,DWORD); HANDLE WINAPI ConvertToGlobalHandle(HANDLE hSrc); WIN_BOOL WINAPI CopyFileA(LPCSTR,LPCSTR,WIN_BOOL); WIN_BOOL WINAPI CopyFileW(LPCWSTR,LPCWSTR,WIN_BOOL); #define CopyFile WINELIB_NAME_AW(CopyFile) WIN_BOOL WINAPI CopyFileExA(LPCSTR, LPCSTR, LPPROGRESS_ROUTINE, LPVOID, LPWIN_BOOL, DWORD); WIN_BOOL WINAPI CopyFileExW(LPCWSTR, LPCWSTR, LPPROGRESS_ROUTINE, LPVOID, LPWIN_BOOL, DWORD); #define CopyFileEx WINELIB_NAME_AW(CopyFileEx) WIN_BOOL WINAPI CopySid(DWORD,PSID,PSID); INT WINAPI CompareFileTime(LPFILETIME,LPFILETIME); HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES,WIN_BOOL,WIN_BOOL,LPCSTR); HANDLE WINAPI CreateEventW(LPSECURITY_ATTRIBUTES,WIN_BOOL,WIN_BOOL,LPCWSTR); #define CreateEvent WINELIB_NAME_AW(CreateEvent) HANDLE WINAPI CreateFileA(LPCSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES, DWORD,DWORD,HANDLE); HANDLE WINAPI CreateFileW(LPCWSTR,DWORD,DWORD,LPSECURITY_ATTRIBUTES, DWORD,DWORD,HANDLE); #define CreateFile WINELIB_NAME_AW(CreateFile) HANDLE WINAPI CreateFileMappingA(HANDLE,LPSECURITY_ATTRIBUTES,DWORD, DWORD,DWORD,LPCSTR); HANDLE WINAPI CreateFileMappingW(HANDLE,LPSECURITY_ATTRIBUTES,DWORD, DWORD,DWORD,LPCWSTR); #define CreateFileMapping WINELIB_NAME_AW(CreateFileMapping) HANDLE WINAPI CreateMutexA(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCSTR); HANDLE WINAPI CreateMutexW(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCWSTR); #define CreateMutex WINELIB_NAME_AW(CreateMutex) WIN_BOOL WINAPI CreatePipe(PHANDLE,PHANDLE,LPSECURITY_ATTRIBUTES,DWORD); WIN_BOOL WINAPI CreateProcessA(LPCSTR,LPSTR,LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES,WIN_BOOL,DWORD,LPVOID,LPCSTR, LPSTARTUPINFOA,LPPROCESS_INFORMATION); WIN_BOOL WINAPI CreateProcessW(LPCWSTR,LPWSTR,LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES,WIN_BOOL,DWORD,LPVOID,LPCWSTR, LPSTARTUPINFOW,LPPROCESS_INFORMATION); #define CreateProcess WINELIB_NAME_AW(CreateProcess) HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR); HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR); #define CreateSemaphore WINELIB_NAME_AW(CreateSemaphore) HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD); HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCSTR); HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES,WIN_BOOL,LPCWSTR); #define CreateWaitableTimer WINELIB_NAME_AW(CreateWaitableTimer) WIN_BOOL WINAPI DebugActiveProcess(DWORD); void WINAPI DebugBreak(void); WIN_BOOL WINAPI DeregisterEventSource(HANDLE); WIN_BOOL WINAPI DisableThreadLibraryCalls(HMODULE); WIN_BOOL WINAPI DosDateTimeToFileTime(WORD,WORD,LPFILETIME); WIN_BOOL WINAPI DuplicateHandle(HANDLE,HANDLE,HANDLE,HANDLE*,DWORD,WIN_BOOL,DWORD); WIN_BOOL WINAPI EnumDateFormatsA(DATEFMT_ENUMPROCA lpDateFmtEnumProc, LCID Locale, DWORD dwFlags); WIN_BOOL WINAPI EnumDateFormatsW(DATEFMT_ENUMPROCW lpDateFmtEnumProc, LCID Locale, DWORD dwFlags); #define EnumDateFormats WINELIB_NAME_AW(EnumDateFormats) WIN_BOOL WINAPI EnumResourceLanguagesA(HMODULE,LPCSTR,LPCSTR, ENUMRESLANGPROCA,LONG); WIN_BOOL WINAPI EnumResourceLanguagesW(HMODULE,LPCWSTR,LPCWSTR, ENUMRESLANGPROCW,LONG); #define EnumResourceLanguages WINELIB_NAME_AW(EnumResourceLanguages) WIN_BOOL WINAPI EnumResourceNamesA(HMODULE,LPCSTR,ENUMRESNAMEPROCA, LONG); WIN_BOOL WINAPI EnumResourceNamesW(HMODULE,LPCWSTR,ENUMRESNAMEPROCW, LONG); #define EnumResourceNames WINELIB_NAME_AW(EnumResourceNames) WIN_BOOL WINAPI EnumResourceTypesA(HMODULE,ENUMRESTYPEPROCA,LONG); WIN_BOOL WINAPI EnumResourceTypesW(HMODULE,ENUMRESTYPEPROCW,LONG); #define EnumResourceTypes WINELIB_NAME_AW(EnumResourceTypes) WIN_BOOL WINAPI EnumSystemCodePagesA(CODEPAGE_ENUMPROCA,DWORD); WIN_BOOL WINAPI EnumSystemCodePagesW(CODEPAGE_ENUMPROCW,DWORD); #define EnumSystemCodePages WINELIB_NAME_AW(EnumSystemCodePages) WIN_BOOL WINAPI EnumSystemLocalesA(LOCALE_ENUMPROCA,DWORD); WIN_BOOL WINAPI EnumSystemLocalesW(LOCALE_ENUMPROCW,DWORD); #define EnumSystemLocales WINELIB_NAME_AW(EnumSystemLocales) WIN_BOOL WINAPI EnumTimeFormatsA(TIMEFMT_ENUMPROCA lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags); WIN_BOOL WINAPI EnumTimeFormatsW(TIMEFMT_ENUMPROCW lpTimeFmtEnumProc, LCID Locale, DWORD dwFlags); #define EnumTimeFormats WINELIB_NAME_AW(EnumTimeFormats) WIN_BOOL WINAPI EqualSid(PSID, PSID); WIN_BOOL WINAPI EqualPrefixSid(PSID,PSID); VOID WINAPI ExitProcess(DWORD) WINE_NORETURN; VOID WINAPI ExitThread(DWORD) WINE_NORETURN; DWORD WINAPI ExpandEnvironmentStringsA(LPCSTR,LPSTR,DWORD); DWORD WINAPI ExpandEnvironmentStringsW(LPCWSTR,LPWSTR,DWORD); #define ExpandEnvironmentStrings WINELIB_NAME_AW(ExpandEnvironmentStrings) WIN_BOOL WINAPI FileTimeToDosDateTime(const FILETIME*,LPWORD,LPWORD); WIN_BOOL WINAPI FileTimeToLocalFileTime(const FILETIME*,LPFILETIME); WIN_BOOL WINAPI FileTimeToSystemTime(const FILETIME*,LPSYSTEMTIME); HANDLE WINAPI FindFirstChangeNotificationA(LPCSTR,WIN_BOOL,DWORD); HANDLE WINAPI FindFirstChangeNotificationW(LPCWSTR,WIN_BOOL,DWORD); #define FindFirstChangeNotification WINELIB_NAME_AW(FindFirstChangeNotification) WIN_BOOL WINAPI FindNextChangeNotification(HANDLE); WIN_BOOL WINAPI FindCloseChangeNotification(HANDLE); HRSRC WINAPI FindResourceExA(HMODULE,LPCSTR,LPCSTR,WORD); HRSRC WINAPI FindResourceExW(HMODULE,LPCWSTR,LPCWSTR,WORD); #define FindResourceEx WINELIB_NAME_AW(FindResourceEx) WIN_BOOL WINAPI FlushConsoleInputBuffer(HANDLE); WIN_BOOL WINAPI FlushFileBuffers(HANDLE); WIN_BOOL WINAPI FlushViewOfFile(LPCVOID, DWORD); DWORD WINAPI FormatMessageA(DWORD,LPCVOID,DWORD,DWORD,LPSTR, DWORD,LPDWORD); DWORD WINAPI FormatMessageW(DWORD,LPCVOID,DWORD,DWORD,LPWSTR, DWORD,LPDWORD); #define FormatMessage WINELIB_NAME_AW(FormatMessage) WIN_BOOL WINAPI FreeConsole(void); WIN_BOOL WINAPI FreeEnvironmentStringsA(LPSTR); WIN_BOOL WINAPI FreeEnvironmentStringsW(LPWSTR); #define FreeEnvironmentStrings WINELIB_NAME_AW(FreeEnvironmentStrings) PVOID WINAPI FreeSid(PSID); UINT WINAPI GetACP(void); LPCSTR WINAPI GetCommandLineA(void); LPCWSTR WINAPI GetCommandLineW(void); #define GetCommandLine WINELIB_NAME_AW(GetCommandLine) WIN_BOOL WINAPI GetComputerNameA(LPSTR,LPDWORD); WIN_BOOL WINAPI GetComputerNameW(LPWSTR,LPDWORD); #define GetComputerName WINELIB_NAME_AW(GetComputerName) UINT WINAPI GetConsoleCP(void); WIN_BOOL WINAPI GetConsoleMode(HANDLE,LPDWORD); UINT WINAPI GetConsoleOutputCP(void); DWORD WINAPI GetConsoleTitleA(LPSTR,DWORD); DWORD WINAPI GetConsoleTitleW(LPWSTR,DWORD); #define GetConsoleTitle WINELIB_NAME_AW(GetConsoleTitle) WIN_BOOL WINAPI GetCommMask(HANDLE, LPDWORD); WIN_BOOL WINAPI GetCommModemStatus(HANDLE, LPDWORD); HANDLE WINAPI GetCurrentProcess(void); HANDLE WINAPI GetCurrentThread(void); INT WINAPI GetDateFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT); INT WINAPI GetDateFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT); #define GetDateFormat WINELIB_NAME_AW(GetDateFormat) LPSTR WINAPI GetEnvironmentStringsA(void); LPWSTR WINAPI GetEnvironmentStringsW(void); #define GetEnvironmentStrings WINELIB_NAME_AW(GetEnvironmentStrings) DWORD WINAPI GetEnvironmentVariableA(LPCSTR,LPSTR,DWORD); DWORD WINAPI GetEnvironmentVariableW(LPCWSTR,LPWSTR,DWORD); #define GetEnvironmentVariable WINELIB_NAME_AW(GetEnvironmentVariable) WIN_BOOL WINAPI GetFileAttributesExA(LPCSTR,GET_FILEEX_INFO_LEVELS,LPVOID); WIN_BOOL WINAPI GetFileAttributesExW(LPCWSTR,GET_FILEEX_INFO_LEVELS,LPVOID); #define GetFileattributesEx WINELIB_NAME_AW(GetFileAttributesEx) DWORD WINAPI GetFileInformationByHandle(HANDLE,BY_HANDLE_FILE_INFORMATION*); WIN_BOOL WINAPI GetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD); WIN_BOOL WINAPI GetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR,DWORD,LPDWORD); #define GetFileSecurity WINELIB_NAME_AW(GetFileSecurity) DWORD WINAPI GetFileSize(HANDLE,LPDWORD); WIN_BOOL WINAPI GetFileTime(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME); DWORD WINAPI GetFileType(HANDLE); DWORD WINAPI GetFullPathNameA(LPCSTR,DWORD,LPSTR,LPSTR*); DWORD WINAPI GetFullPathNameW(LPCWSTR,DWORD,LPWSTR,LPWSTR*); #define GetFullPathName WINELIB_NAME_AW(GetFullPathName) WIN_BOOL WINAPI GetHandleInformation(HANDLE,LPDWORD); COORD WINAPI GetLargestConsoleWindowSize(HANDLE); DWORD WINAPI GetLengthSid(PSID); VOID WINAPI GetLocalTime(LPSYSTEMTIME); DWORD WINAPI GetLogicalDrives(void); DWORD WINAPI GetLongPathNameA(LPCSTR,LPSTR,DWORD); DWORD WINAPI GetLongPathNameW(LPCWSTR,LPWSTR,DWORD); #define GetLongPathName WINELIB_NAME_AW(GetLongPathName) WIN_BOOL WINAPI GetNumberOfConsoleInputEvents(HANDLE,LPDWORD); WIN_BOOL WINAPI GetNumberOfConsoleMouseButtons(LPDWORD); WIN_BOOL WINAPI GetNumberOfEventLogRecords(HANDLE,PDWORD); UINT WINAPI GetOEMCP(void); WIN_BOOL WINAPI GetOldestEventLogRecord(HANDLE,PDWORD); DWORD WINAPI GetPriorityClass(HANDLE); DWORD WINAPI GetProcessVersion(DWORD); WIN_BOOL WINAPI GetSecurityDescriptorControl(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR_CONTROL,LPDWORD); WIN_BOOL WINAPI GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,LPWIN_BOOL,PACL *,LPWIN_BOOL); WIN_BOOL WINAPI GetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID *,LPWIN_BOOL); DWORD WINAPI GetSecurityDescriptorLength(PSECURITY_DESCRIPTOR); WIN_BOOL WINAPI GetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID *,LPWIN_BOOL); WIN_BOOL WINAPI GetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,LPWIN_BOOL,PACL *,LPWIN_BOOL); PSID_IDENTIFIER_AUTHORITY WINAPI GetSidIdentifierAuthority(PSID); DWORD WINAPI GetSidLengthRequired(BYTE); PDWORD WINAPI GetSidSubAuthority(PSID,DWORD); PUCHAR WINAPI GetSidSubAuthorityCount(PSID); DWORD WINAPI GetShortPathNameA(LPCSTR,LPSTR,DWORD); DWORD WINAPI GetShortPathNameW(LPCWSTR,LPWSTR,DWORD); #define GetShortPathName WINELIB_NAME_AW(GetShortPathName) HFILE WINAPI GetStdHandle(DWORD); WIN_BOOL WINAPI GetStringTypeExA(LCID,DWORD,LPCSTR,INT,LPWORD); WIN_BOOL WINAPI GetStringTypeExW(LCID,DWORD,LPCWSTR,INT,LPWORD); #define GetStringTypeEx WINELIB_NAME_AW(GetStringTypeEx) VOID WINAPI GetSystemInfo(LPSYSTEM_INFO); WIN_BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS); VOID WINAPI GetSystemTime(LPSYSTEMTIME); VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME); INT WINAPI GetTimeFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT); INT WINAPI GetTimeFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT); #define GetTimeFormat WINELIB_NAME_AW(GetTimeFormat) WIN_BOOL WINAPI GetThreadContext(HANDLE,CONTEXT *); LCID WINAPI GetThreadLocale(void); INT WINAPI GetThreadPriority(HANDLE); WIN_BOOL WINAPI GetThreadSelectorEntry(HANDLE,DWORD,LPLDT_ENTRY); WIN_BOOL WINAPI GetThreadTimes(HANDLE,LPFILETIME,LPFILETIME,LPFILETIME,LPFILETIME); WIN_BOOL WINAPI GetTokenInformation(HANDLE,TOKEN_INFORMATION_CLASS,LPVOID,DWORD,LPDWORD); WIN_BOOL WINAPI GetUserNameA(LPSTR,LPDWORD); WIN_BOOL WINAPI GetUserNameW(LPWSTR,LPDWORD); #define GetUserName WINELIB_NAME_AW(GetUserName) VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS); LPVOID WINAPI HeapAlloc(HANDLE,DWORD,DWORD); DWORD WINAPI HeapCompact(HANDLE,DWORD); HANDLE WINAPI HeapCreate(DWORD,DWORD,DWORD); WIN_BOOL WINAPI HeapDestroy(HANDLE); WIN_BOOL WINAPI HeapFree(HANDLE,DWORD,LPVOID); WIN_BOOL WINAPI HeapLock(HANDLE); LPVOID WINAPI HeapReAlloc(HANDLE,DWORD,LPVOID,DWORD); DWORD WINAPI HeapSize(HANDLE,DWORD,LPVOID); WIN_BOOL WINAPI HeapUnlock(HANDLE); WIN_BOOL WINAPI HeapValidate(HANDLE,DWORD,LPCVOID); WIN_BOOL WINAPI HeapWalk(HANDLE,LPPROCESS_HEAP_ENTRY); WIN_BOOL WINAPI InitializeSid(PSID,PSID_IDENTIFIER_AUTHORITY,BYTE); WIN_BOOL WINAPI IsValidSecurityDescriptor(PSECURITY_DESCRIPTOR); WIN_BOOL WINAPI IsValidSid(PSID); WIN_BOOL WINAPI ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL); WIN_BOOL WINAPI IsDBCSLeadByteEx(UINT,BYTE); WIN_BOOL WINAPI IsProcessorFeaturePresent(DWORD); WIN_BOOL WINAPI IsValidLocale(DWORD,DWORD); WIN_BOOL WINAPI LookupAccountSidA(LPCSTR,PSID,LPSTR,LPDWORD,LPSTR,LPDWORD,PSID_NAME_USE); WIN_BOOL WINAPI LookupAccountSidW(LPCWSTR,PSID,LPWSTR,LPDWORD,LPWSTR,LPDWORD,PSID_NAME_USE); #define LookupAccountSid WINELIB_NAME_AW(LookupAccountSidW) WIN_BOOL WINAPI LocalFileTimeToFileTime(const FILETIME*,LPFILETIME); WIN_BOOL WINAPI LockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); WIN_BOOL WINAPI LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED); WIN_BOOL WINAPI LookupPrivilegeValueA(LPCSTR,LPCSTR,LPVOID); WIN_BOOL WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,LPVOID); #define LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue) WIN_BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD); HMODULE WINAPI MapHModuleSL(HMODULE16); HMODULE16 WINAPI MapHModuleLS(HMODULE); SEGPTR WINAPI MapLS(LPVOID); LPVOID WINAPI MapSL(SEGPTR); LPVOID WINAPI MapViewOfFile(HANDLE,DWORD,DWORD,DWORD,DWORD); LPVOID WINAPI MapViewOfFileEx(HANDLE,DWORD,DWORD,DWORD,DWORD,LPVOID); WIN_BOOL WINAPI MoveFileA(LPCSTR,LPCSTR); WIN_BOOL WINAPI MoveFileW(LPCWSTR,LPCWSTR); #define MoveFile WINELIB_NAME_AW(MoveFile) WIN_BOOL WINAPI MoveFileExA(LPCSTR,LPCSTR,DWORD); WIN_BOOL WINAPI MoveFileExW(LPCWSTR,LPCWSTR,DWORD); #define MoveFileEx WINELIB_NAME_AW(MoveFileEx) INT WINAPI MultiByteToWideChar(UINT,DWORD,LPCSTR,INT,LPWSTR,INT); WIN_BOOL WINAPI NotifyChangeEventLog(HANDLE,HANDLE); INT WINAPI WideCharToMultiByte(UINT,DWORD,LPCWSTR,INT,LPSTR,INT,LPCSTR,WIN_BOOL*); HANDLE WINAPI OpenBackupEventLogA(LPCSTR,LPCSTR); HANDLE WINAPI OpenBackupEventLogW(LPCWSTR,LPCWSTR); #define OpenBackupEventLog WINELIB_NAME_AW(OpenBackupEventLog) HANDLE WINAPI OpenEventA(DWORD,WIN_BOOL,LPCSTR); HANDLE WINAPI OpenEventW(DWORD,WIN_BOOL,LPCWSTR); #define OpenEvent WINELIB_NAME_AW(OpenEvent) HANDLE WINAPI OpenEventLogA(LPCSTR,LPCSTR); HANDLE WINAPI OpenEventLogW(LPCWSTR,LPCWSTR); #define OpenEventLog WINELIB_NAME_AW(OpenEventLog) HANDLE WINAPI OpenFileMappingA(DWORD,WIN_BOOL,LPCSTR); HANDLE WINAPI OpenFileMappingW(DWORD,WIN_BOOL,LPCWSTR); #define OpenFileMapping WINELIB_NAME_AW(OpenFileMapping) HANDLE WINAPI OpenMutexA(DWORD,WIN_BOOL,LPCSTR); HANDLE WINAPI OpenMutexW(DWORD,WIN_BOOL,LPCWSTR); #define OpenMutex WINELIB_NAME_AW(OpenMutex) HANDLE WINAPI OpenProcess(DWORD,WIN_BOOL,DWORD); WIN_BOOL WINAPI OpenProcessToken(HANDLE,DWORD,PHANDLE); HANDLE WINAPI OpenSemaphoreA(DWORD,WIN_BOOL,LPCSTR); HANDLE WINAPI OpenSemaphoreW(DWORD,WIN_BOOL,LPCWSTR); #define OpenSemaphore WINELIB_NAME_AW(OpenSemaphore) WIN_BOOL WINAPI OpenThreadToken(HANDLE,DWORD,WIN_BOOL,PHANDLE); HANDLE WINAPI OpenWaitableTimerA(DWORD,WIN_BOOL,LPCSTR); HANDLE WINAPI OpenWaitableTimerW(DWORD,WIN_BOOL,LPCWSTR); #define OpenWaitableTimer WINELIB_NAME_AW(OpenWaitableTimer) WIN_BOOL WINAPI PulseEvent(HANDLE); WIN_BOOL WINAPI PurgeComm(HANDLE,DWORD); DWORD WINAPI QueryDosDeviceA(LPCSTR,LPSTR,DWORD); DWORD WINAPI QueryDosDeviceW(LPCWSTR,LPWSTR,DWORD); #define QueryDosDevice WINELIB_NAME_AW(QueryDosDevice) WIN_BOOL WINAPI QueryPerformanceCounter(PLARGE_INTEGER); WIN_BOOL WINAPI ReadConsoleA(HANDLE,LPVOID,DWORD,LPDWORD,LPVOID); WIN_BOOL WINAPI ReadConsoleW(HANDLE,LPVOID,DWORD,LPDWORD,LPVOID); #define ReadConsole WINELIB_NAME_AW(ReadConsole) WIN_BOOL WINAPI ReadConsoleOutputCharacterA(HANDLE,LPSTR,DWORD, COORD,LPDWORD); #define ReadConsoleOutputCharacter WINELIB_NAME_AW(ReadConsoleOutputCharacter) WIN_BOOL WINAPI ReadEventLogA(HANDLE,DWORD,DWORD,LPVOID,DWORD,DWORD *,DWORD *); WIN_BOOL WINAPI ReadEventLogW(HANDLE,DWORD,DWORD,LPVOID,DWORD,DWORD *,DWORD *); #define ReadEventLog WINELIB_NAME_AW(ReadEventLog) WIN_BOOL WINAPI ReadFile(HANDLE,LPVOID,DWORD,LPDWORD,LPOVERLAPPED); HANDLE WINAPI RegisterEventSourceA(LPCSTR,LPCSTR); HANDLE WINAPI RegisterEventSourceW(LPCWSTR,LPCWSTR); #define RegisterEventSource WINELIB_NAME_AW(RegisterEventSource) WIN_BOOL WINAPI ReleaseMutex(HANDLE); WIN_BOOL WINAPI ReleaseSemaphore(HANDLE,LONG,LPLONG); WIN_BOOL WINAPI ReportEventA(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCSTR *,LPVOID); WIN_BOOL WINAPI ReportEventW(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCWSTR *,LPVOID); #define ReportEvent WINELIB_NAME_AW(ReportEvent) WIN_BOOL WINAPI ResetEvent(HANDLE); DWORD WINAPI ResumeThread(HANDLE); WIN_BOOL WINAPI RevertToSelf(void); DWORD WINAPI SearchPathA(LPCSTR,LPCSTR,LPCSTR,DWORD,LPSTR,LPSTR*); DWORD WINAPI SearchPathW(LPCWSTR,LPCWSTR,LPCWSTR,DWORD,LPWSTR,LPWSTR*); #define SearchPath WINELIB_NAME_AW(SearchPath) WIN_BOOL WINAPI SetCommMask(INT,DWORD); WIN_BOOL WINAPI SetComputerNameA(LPCSTR); WIN_BOOL WINAPI SetComputerNameW(LPCWSTR); #define SetComputerName WINELIB_NAME_AW(SetComputerName) WIN_BOOL WINAPI SetConsoleCursorPosition(HANDLE,COORD); WIN_BOOL WINAPI SetConsoleMode(HANDLE,DWORD); WIN_BOOL WINAPI SetConsoleTitleA(LPCSTR); WIN_BOOL WINAPI SetConsoleTitleW(LPCWSTR); #define SetConsoleTitle WINELIB_NAME_AW(SetConsoleTitle) WIN_BOOL WINAPI SetEndOfFile(HANDLE); WIN_BOOL WINAPI SetEnvironmentVariableA(LPCSTR,LPCSTR); WIN_BOOL WINAPI SetEnvironmentVariableW(LPCWSTR,LPCWSTR); #define SetEnvironmentVariable WINELIB_NAME_AW(SetEnvironmentVariable) WIN_BOOL WINAPI SetEvent(HANDLE); VOID WINAPI SetFileApisToANSI(void); VOID WINAPI SetFileApisToOEM(void); DWORD WINAPI SetFilePointer(HANDLE,LONG,LPLONG,DWORD); WIN_BOOL WINAPI SetFileSecurityA(LPCSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); WIN_BOOL WINAPI SetFileSecurityW(LPCWSTR,SECURITY_INFORMATION,PSECURITY_DESCRIPTOR); #define SetFileSecurity WINELIB_NAME_AW(SetFileSecurity) WIN_BOOL WINAPI SetFileTime(HANDLE,const FILETIME*,const FILETIME*,const FILETIME*); WIN_BOOL WINAPI SetHandleInformation(HANDLE,DWORD,DWORD); WIN_BOOL WINAPI SetPriorityClass(HANDLE,DWORD); WIN_BOOL WINAPI SetLocalTime(const SYSTEMTIME*); WIN_BOOL WINAPI SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR,WIN_BOOL,PACL,WIN_BOOL); WIN_BOOL WINAPI SetSecurityDescriptorGroup(PSECURITY_DESCRIPTOR,PSID,WIN_BOOL); WIN_BOOL WINAPI SetSecurityDescriptorOwner(PSECURITY_DESCRIPTOR,PSID,WIN_BOOL); WIN_BOOL WINAPI SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR,WIN_BOOL,PACL,WIN_BOOL); WIN_BOOL WINAPI SetStdHandle(DWORD,HANDLE); WIN_BOOL WINAPI SetSystemPowerState(WIN_BOOL,WIN_BOOL); WIN_BOOL WINAPI SetSystemTime(const SYSTEMTIME*); DWORD WINAPI SetThreadAffinityMask(HANDLE,DWORD); WIN_BOOL WINAPI SetThreadContext(HANDLE,const CONTEXT *); WIN_BOOL WINAPI SetThreadLocale(LCID); WIN_BOOL WINAPI SetThreadPriority(HANDLE,INT); WIN_BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION); WIN_BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,WIN_BOOL); VOID WINAPI Sleep(DWORD); DWORD WINAPI SleepEx(DWORD,WIN_BOOL); DWORD WINAPI SuspendThread(HANDLE); WIN_BOOL WINAPI SystemTimeToFileTime(const SYSTEMTIME*,LPFILETIME); DWORD WINAPI TlsAlloc(void); WIN_BOOL WINAPI TlsFree(DWORD); LPVOID WINAPI TlsGetValue(DWORD); WIN_BOOL WINAPI TlsSetValue(DWORD,LPVOID); VOID WINAPI UnMapLS(SEGPTR); WIN_BOOL WINAPI UnlockFile(HANDLE,DWORD,DWORD,DWORD,DWORD); WIN_BOOL WINAPI UnmapViewOfFile(LPVOID); LPVOID WINAPI VirtualAlloc(LPVOID,DWORD,DWORD,DWORD); WIN_BOOL WINAPI VirtualFree(LPVOID,SIZE_T,DWORD); WIN_BOOL WINAPI VirtualLock(LPVOID,DWORD); WIN_BOOL WINAPI VirtualProtect(LPVOID,DWORD,DWORD,LPDWORD); WIN_BOOL WINAPI VirtualProtectEx(HANDLE,LPVOID,DWORD,DWORD,LPDWORD); DWORD WINAPI VirtualQuery(LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD); DWORD WINAPI VirtualQueryEx(HANDLE,LPCVOID,LPMEMORY_BASIC_INFORMATION,DWORD); WIN_BOOL WINAPI VirtualUnlock(LPVOID,DWORD); WIN_BOOL WINAPI WaitCommEvent(HANDLE,LPDWORD,LPOVERLAPPED); WIN_BOOL WINAPI WaitForDebugEvent(LPDEBUG_EVENT,DWORD); DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,WIN_BOOL,DWORD); DWORD WINAPI WaitForMultipleObjectsEx(DWORD,const HANDLE*,WIN_BOOL,DWORD,WIN_BOOL); DWORD WINAPI WaitForSingleObject(HANDLE,DWORD); DWORD WINAPI WaitForSingleObjectEx(HANDLE,DWORD,WIN_BOOL); WIN_BOOL WINAPI WriteConsoleA(HANDLE,LPCVOID,DWORD,LPDWORD,LPVOID); WIN_BOOL WINAPI WriteConsoleW(HANDLE,LPCVOID,DWORD,LPDWORD,LPVOID); #define WriteConsole WINELIB_NAME_AW(WriteConsole) WIN_BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED); LANGID WINAPI GetSystemDefaultLangID(void); LCID WINAPI GetSystemDefaultLCID(void); LANGID WINAPI GetUserDefaultLangID(void); LCID WINAPI GetUserDefaultLCID(void); ATOM WINAPI AddAtomA(LPCSTR); ATOM WINAPI AddAtomW(LPCWSTR); #define AddAtom WINELIB_NAME_AW(AddAtom) UINT WINAPI CompareStringA(DWORD,DWORD,LPCSTR,DWORD,LPCSTR,DWORD); UINT WINAPI CompareStringW(DWORD,DWORD,LPCWSTR,DWORD,LPCWSTR,DWORD); #define CompareString WINELIB_NAME_AW(CompareString) WIN_BOOL WINAPI CreateDirectoryA(LPCSTR,LPSECURITY_ATTRIBUTES); WIN_BOOL WINAPI CreateDirectoryW(LPCWSTR,LPSECURITY_ATTRIBUTES); #define CreateDirectory WINELIB_NAME_AW(CreateDirectory) WIN_BOOL WINAPI CreateDirectoryExA(LPCSTR,LPCSTR,LPSECURITY_ATTRIBUTES); WIN_BOOL WINAPI CreateDirectoryExW(LPCWSTR,LPCWSTR,LPSECURITY_ATTRIBUTES); #define CreateDirectoryEx WINELIB_NAME_AW(CreateDirectoryEx) WIN_BOOL WINAPI DefineDosDeviceA(DWORD,LPCSTR,LPCSTR); #define DefineHandleTable(w) ((w),TRUE) ATOM WINAPI DeleteAtom(ATOM); WIN_BOOL WINAPI DeleteFileA(LPCSTR); WIN_BOOL WINAPI DeleteFileW(LPCWSTR); #define DeleteFile WINELIB_NAME_AW(DeleteFile) void WINAPI FatalAppExitA(UINT,LPCSTR); void WINAPI FatalAppExitW(UINT,LPCWSTR); #define FatalAppExit WINELIB_NAME_AW(FatalAppExit) ATOM WINAPI FindAtomA(LPCSTR); ATOM WINAPI FindAtomW(LPCWSTR); #define FindAtom WINELIB_NAME_AW(FindAtom) WIN_BOOL WINAPI FindClose(HANDLE); HANDLE16 WINAPI FindFirstFile16(LPCSTR,LPWIN32_FIND_DATAA); HANDLE WINAPI FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA); HANDLE WINAPI FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW); #define FindFirstFile WINELIB_NAME_AW(FindFirstFile) WIN_BOOL16 WINAPI FindNextFile16(HANDLE16,LPWIN32_FIND_DATAA); WIN_BOOL WINAPI FindNextFileA(HANDLE,LPWIN32_FIND_DATAA); WIN_BOOL WINAPI FindNextFileW(HANDLE,LPWIN32_FIND_DATAW); #define FindNextFile WINELIB_NAME_AW(FindNextFile) HRSRC WINAPI FindResourceA(HMODULE,LPCSTR,LPCSTR); HRSRC WINAPI FindResourceW(HMODULE,LPCWSTR,LPCWSTR); #define FindResource WINELIB_NAME_AW(FindResource) VOID WINAPI FreeLibrary16(HINSTANCE16); WIN_BOOL WINAPI FreeLibrary(HMODULE); #define FreeModule(handle) FreeLibrary(handle) #define FreeProcInstance(proc) /*nothing*/ WIN_BOOL WINAPI FreeResource(HGLOBAL); UINT WINAPI GetAtomNameA(ATOM,LPSTR,INT); UINT WINAPI GetAtomNameW(ATOM,LPWSTR,INT); #define GetAtomName WINELIB_NAME_AW(GetAtomName) UINT WINAPI GetCurrentDirectoryA(UINT,LPSTR); UINT WINAPI GetCurrentDirectoryW(UINT,LPWSTR); #define GetCurrentDirectory WINELIB_NAME_AW(GetCurrentDirectory) WIN_BOOL WINAPI GetDiskFreeSpaceA(LPCSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD); WIN_BOOL WINAPI GetDiskFreeSpaceW(LPCWSTR,LPDWORD,LPDWORD,LPDWORD,LPDWORD); #define GetDiskFreeSpace WINELIB_NAME_AW(GetDiskFreeSpace) WIN_BOOL WINAPI GetDiskFreeSpaceExA(LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); WIN_BOOL WINAPI GetDiskFreeSpaceExW(LPCWSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER); #define GetDiskFreeSpaceEx WINELIB_NAME_AW(GetDiskFreeSpaceEx) UINT WINAPI GetDriveTypeA(LPCSTR); UINT WINAPI GetDriveTypeW(LPCWSTR); #define GetDriveType WINELIB_NAME_AW(GetDriveType) DWORD WINAPI GetFileAttributesA(LPCSTR); DWORD WINAPI GetFileAttributesW(LPCWSTR); #define GetFileAttributes WINELIB_NAME_AW(GetFileAttributes) #define GetFreeSpace(w) (0x100000L) UINT WINAPI GetLogicalDriveStringsA(UINT,LPSTR); UINT WINAPI GetLogicalDriveStringsW(UINT,LPWSTR); #define GetLogicalDriveStrings WINELIB_NAME_AW(GetLogicalDriveStrings) INT WINAPI GetLocaleInfoA(LCID,LCTYPE,LPSTR,INT); INT WINAPI GetLocaleInfoW(LCID,LCTYPE,LPWSTR,INT); #define GetLocaleInfo WINELIB_NAME_AW(GetLocaleInfo) DWORD WINAPI GetModuleFileNameA(HMODULE,LPSTR,DWORD); DWORD WINAPI GetModuleFileNameW(HMODULE,LPWSTR,DWORD); #define GetModuleFileName WINELIB_NAME_AW(GetModuleFileName) HMODULE WINAPI GetModuleHandleA(LPCSTR); HMODULE WINAPI GetModuleHandleW(LPCWSTR); #define GetModuleHandle WINELIB_NAME_AW(GetModuleHandle) WIN_BOOL WINAPI GetOverlappedResult(HANDLE,LPOVERLAPPED,LPDWORD,WIN_BOOL); UINT WINAPI GetPrivateProfileIntA(LPCSTR,LPCSTR,INT,LPCSTR); UINT WINAPI GetPrivateProfileIntW(LPCWSTR,LPCWSTR,INT,LPCWSTR); #define GetPrivateProfileInt WINELIB_NAME_AW(GetPrivateProfileInt) INT WINAPI GetPrivateProfileSectionA(LPCSTR,LPSTR,DWORD,LPCSTR); INT WINAPI GetPrivateProfileSectionW(LPCWSTR,LPWSTR,DWORD,LPCWSTR); #define GetPrivateProfileSection WINELIB_NAME_AW(GetPrivateProfileSection) DWORD WINAPI GetPrivateProfileSectionNamesA(LPSTR,DWORD,LPCSTR); DWORD WINAPI GetPrivateProfileSectionNamesW(LPWSTR,DWORD,LPCWSTR); #define GetPrivateProfileSectionNames WINELIB_NAME_AW(GetPrivateProfileSectionNames) INT WINAPI GetPrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT,LPCSTR); INT WINAPI GetPrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT,LPCWSTR); #define GetPrivateProfileString WINELIB_NAME_AW(GetPrivateProfileString) WIN_BOOL WINAPI GetPrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR); WIN_BOOL WINAPI GetPrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR); #define GetPrivateProfileStruct WINELIB_NAME_AW(GetPrivateProfileStruct) FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR); UINT WINAPI GetProfileIntA(LPCSTR,LPCSTR,INT); UINT WINAPI GetProfileIntW(LPCWSTR,LPCWSTR,INT); #define GetProfileInt WINELIB_NAME_AW(GetProfileInt) INT WINAPI GetProfileSectionA(LPCSTR,LPSTR,DWORD); INT WINAPI GetProfileSectionW(LPCWSTR,LPWSTR,DWORD); #define GetProfileSection WINELIB_NAME_AW(GetProfileSection) INT WINAPI GetProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,UINT); INT WINAPI GetProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPWSTR,UINT); #define GetProfileString WINELIB_NAME_AW(GetProfileString) VOID WINAPI GetStartupInfoA(LPSTARTUPINFOA); VOID WINAPI GetStartupInfoW(LPSTARTUPINFOW); #define GetStartupInfo WINELIB_NAME_AW(GetStartupInfo) WIN_BOOL WINAPI GetStringTypeA(LCID,DWORD,LPCSTR,INT,LPWORD); WIN_BOOL WINAPI GetStringTypeW(DWORD,LPCWSTR,INT,LPWORD); #define GetStringType WINELIB_NAME_AW(GetStringType) UINT WINAPI GetSystemDirectoryA(LPSTR,UINT); UINT WINAPI GetSystemDirectoryW(LPWSTR,UINT); #define GetSystemDirectory WINELIB_NAME_AW(GetSystemDirectory) UINT WINAPI GetTempFileNameA(LPCSTR,LPCSTR,UINT,LPSTR); UINT WINAPI GetTempFileNameW(LPCWSTR,LPCWSTR,UINT,LPWSTR); #define GetTempFileName WINELIB_NAME_AW(GetTempFileName) UINT WINAPI GetTempPathA(UINT,LPSTR); UINT WINAPI GetTempPathW(UINT,LPWSTR); #define GetTempPath WINELIB_NAME_AW(GetTempPath) LONG WINAPI GetVersion(void); WIN_BOOL WINAPI GetExitCodeProcess(HANDLE,LPDWORD); WIN_BOOL WINAPI GetVolumeInformationA(LPCSTR,LPSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPSTR,DWORD); WIN_BOOL WINAPI GetVolumeInformationW(LPCWSTR,LPWSTR,DWORD,LPDWORD,LPDWORD,LPDWORD,LPWSTR,DWORD); #define GetVolumeInformation WINELIB_NAME_AW(GetVolumeInformation) UINT WINAPI GetWindowsDirectoryA(LPSTR,UINT); UINT WINAPI GetWindowsDirectoryW(LPWSTR,UINT); #define GetWindowsDirectory WINELIB_NAME_AW(GetWindowsDirectory) HGLOBAL16 WINAPI GlobalAlloc16(UINT16,DWORD); HGLOBAL WINAPI GlobalAlloc(UINT,DWORD); DWORD WINAPI GlobalCompact(DWORD); UINT WINAPI GlobalFlags(HGLOBAL); HGLOBAL16 WINAPI GlobalFree16(HGLOBAL16); HGLOBAL WINAPI GlobalFree(HGLOBAL); HGLOBAL WINAPI GlobalHandle(LPCVOID); WORD WINAPI GlobalFix16(HGLOBAL16); VOID WINAPI GlobalFix(HGLOBAL); LPVOID WINAPI GlobalLock16(HGLOBAL16); LPVOID WINAPI GlobalLock(HGLOBAL); HGLOBAL WINAPI GlobalReAlloc(HGLOBAL,DWORD,UINT); DWORD WINAPI GlobalSize16(HGLOBAL16); DWORD WINAPI GlobalSize(HGLOBAL); VOID WINAPI GlobalUnfix16(HGLOBAL16); VOID WINAPI GlobalUnfix(HGLOBAL); WIN_BOOL16 WINAPI GlobalUnlock16(HGLOBAL16); WIN_BOOL WINAPI GlobalUnlock(HGLOBAL); WIN_BOOL16 WINAPI GlobalUnWire16(HGLOBAL16); WIN_BOOL WINAPI GlobalUnWire(HGLOBAL); SEGPTR WINAPI GlobalWire16(HGLOBAL16); LPVOID WINAPI GlobalWire(HGLOBAL); WIN_BOOL WINAPI InitAtomTable(DWORD); WIN_BOOL WINAPI IsBadCodePtr(FARPROC); WIN_BOOL WINAPI IsBadHugeReadPtr(LPCVOID,UINT); WIN_BOOL WINAPI IsBadHugeWritePtr(LPVOID,UINT); WIN_BOOL WINAPI IsBadReadPtr(LPCVOID,UINT); WIN_BOOL WINAPI IsBadStringPtrA(LPCSTR,UINT); WIN_BOOL WINAPI IsBadStringPtrW(LPCWSTR,UINT); #define IsBadStringPtr WINELIB_NAME_AW(IsBadStringPtr) WIN_BOOL WINAPI IsBadWritePtr(LPVOID,UINT); WIN_BOOL WINAPI IsDBCSLeadByte(BYTE); WIN_BOOL WINAPI IsDebuggerPresent(void); HINSTANCE16 WINAPI LoadLibrary16(LPCSTR); HMODULE WINAPI LoadLibraryA(LPCSTR); HMODULE WINAPI LoadLibraryW(LPCWSTR); #define LoadLibrary WINELIB_NAME_AW(LoadLibrary) HMODULE WINAPI LoadLibraryExA(LPCSTR,HANDLE,DWORD); HMODULE WINAPI LoadLibraryExW(LPCWSTR,HANDLE,DWORD); #define LoadLibraryEx WINELIB_NAME_AW(LoadLibraryEx) HINSTANCE16 WINAPI LoadModule16(LPCSTR,LPVOID); HINSTANCE WINAPI LoadModule(LPCSTR,LPVOID); HGLOBAL WINAPI LoadResource(HMODULE,HRSRC); HLOCAL WINAPI LocalAlloc(UINT,DWORD); UINT WINAPI LocalCompact(UINT); UINT WINAPI LocalFlags(HLOCAL); HLOCAL WINAPI LocalFree(HLOCAL); HLOCAL WINAPI LocalHandle(LPCVOID); LPVOID WINAPI LocalLock(HLOCAL); HLOCAL WINAPI LocalReAlloc(HLOCAL,DWORD,UINT); UINT WINAPI LocalShrink(HGLOBAL,UINT); UINT WINAPI LocalSize(HLOCAL); WIN_BOOL WINAPI LocalUnlock(HLOCAL); LPVOID WINAPI LockResource(HGLOBAL); #define LockSegment(handle) GlobalFix((HANDLE)(handle)) #define MakeProcInstance(proc,inst) (proc) HFILE16 WINAPI OpenFile16(LPCSTR,OFSTRUCT*,UINT16); HFILE WINAPI OpenFile(LPCSTR,OFSTRUCT*,UINT); VOID WINAPI OutputDebugStringA(LPCSTR); VOID WINAPI OutputDebugStringW(LPCWSTR); #define OutputDebugString WINELIB_NAME_AW(OutputDebugString) WIN_BOOL WINAPI ReadProcessMemory(HANDLE, LPCVOID, LPVOID, DWORD, LPDWORD); WIN_BOOL WINAPI RemoveDirectoryA(LPCSTR); WIN_BOOL WINAPI RemoveDirectoryW(LPCWSTR); #define RemoveDirectory WINELIB_NAME_AW(RemoveDirectory) WIN_BOOL WINAPI SetCurrentDirectoryA(LPCSTR); WIN_BOOL WINAPI SetCurrentDirectoryW(LPCWSTR); #define SetCurrentDirectory WINELIB_NAME_AW(SetCurrentDirectory) UINT WINAPI SetErrorMode(UINT); WIN_BOOL WINAPI SetFileAttributesA(LPCSTR,DWORD); WIN_BOOL WINAPI SetFileAttributesW(LPCWSTR,DWORD); #define SetFileAttributes WINELIB_NAME_AW(SetFileAttributes) UINT WINAPI SetHandleCount(UINT); #define SetSwapAreaSize(w) (w) WIN_BOOL WINAPI SetVolumeLabelA(LPCSTR,LPCSTR); WIN_BOOL WINAPI SetVolumeLabelW(LPCWSTR,LPCWSTR); #define SetVolumeLabel WINELIB_NAME_AW(SetVolumeLabel) DWORD WINAPI SizeofResource(HMODULE,HRSRC); #define UnlockSegment(handle) GlobalUnfix((HANDLE)(handle)) WIN_BOOL WINAPI WritePrivateProfileSectionA(LPCSTR,LPCSTR,LPCSTR); WIN_BOOL WINAPI WritePrivateProfileSectionW(LPCWSTR,LPCWSTR,LPCWSTR); #define WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection) WIN_BOOL WINAPI WritePrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPCSTR); WIN_BOOL WINAPI WritePrivateProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR,LPCWSTR); #define WritePrivateProfileString WINELIB_NAME_AW(WritePrivateProfileString) WIN_BOOL WINAPI WriteProfileSectionA(LPCSTR,LPCSTR); WIN_BOOL WINAPI WriteProfileSectionW(LPCWSTR,LPCWSTR); #define WritePrivateProfileSection WINELIB_NAME_AW(WritePrivateProfileSection) WIN_BOOL WINAPI WritePrivateProfileStructA(LPCSTR,LPCSTR,LPVOID,UINT,LPCSTR); WIN_BOOL WINAPI WritePrivateProfileStructW(LPCWSTR,LPCWSTR,LPVOID,UINT,LPCWSTR); #define WritePrivateProfileStruct WINELIB_NAME_AW(WritePrivateProfileStruct) WIN_BOOL WINAPI WriteProcessMemory(HANDLE, LPVOID, LPVOID, DWORD, LPDWORD); WIN_BOOL WINAPI WriteProfileStringA(LPCSTR,LPCSTR,LPCSTR); WIN_BOOL WINAPI WriteProfileStringW(LPCWSTR,LPCWSTR,LPCWSTR); #define WriteProfileString WINELIB_NAME_AW(WriteProfileString) #define Yield32() LPSTR WINAPI lstrcatA(LPSTR,LPCSTR); LPWSTR WINAPI lstrcatW(LPWSTR,LPCWSTR); #define lstrcat WINELIB_NAME_AW(lstrcat) LPSTR WINAPI lstrcpyA(LPSTR,LPCSTR); LPWSTR WINAPI lstrcpyW(LPWSTR,LPCWSTR); #define lstrcpy WINELIB_NAME_AW(lstrcpy) LPSTR WINAPI lstrcpynA(LPSTR,LPCSTR,INT); LPWSTR WINAPI lstrcpynW(LPWSTR,LPCWSTR,INT); #define lstrcpyn WINELIB_NAME_AW(lstrcpyn) INT WINAPI lstrlenA(LPCSTR); INT WINAPI lstrlenW(LPCWSTR); #define lstrlen WINELIB_NAME_AW(lstrlen) HINSTANCE WINAPI WinExec(LPCSTR,UINT); LONG WINAPI _hread(HFILE,LPVOID,LONG); LONG WINAPI _hwrite(HFILE,LPCSTR,LONG); HFILE WINAPI _lcreat(LPCSTR,INT); HFILE WINAPI _lclose(HFILE); LONG WINAPI _llseek(HFILE,LONG,INT); HFILE WINAPI _lopen(LPCSTR,INT); UINT WINAPI _lread(HFILE,LPVOID,UINT); UINT WINAPI _lwrite(HFILE,LPCSTR,UINT); SEGPTR WINAPI WIN16_GlobalLock16(HGLOBAL16); INT WINAPI lstrcmpA(LPCSTR,LPCSTR); INT WINAPI lstrcmpW(LPCWSTR,LPCWSTR); #define lstrcmp WINELIB_NAME_AW(lstrcmp) INT WINAPI lstrcmpiA(LPCSTR,LPCSTR); INT WINAPI lstrcmpiW(LPCWSTR,LPCWSTR); #define lstrcmpi WINELIB_NAME_AW(lstrcmpi) /* compatibility macros */ #define FillMemory RtlFillMemory #define MoveMemory RtlMoveMemory #define ZeroMemory RtlZeroMemory #define CopyMemory RtlCopyMemory DWORD WINAPI GetCurrentProcessId(void); DWORD WINAPI GetCurrentThreadId(void); DWORD WINAPI GetLastError(void); HANDLE WINAPI GetProcessHeap(void); PVOID WINAPI InterlockedCompareExchange(PVOID*,PVOID,PVOID); LONG WINAPI InterlockedDecrement(PLONG); LONG WINAPI InterlockedExchange(PLONG,LONG); LONG WINAPI InterlockedExchangeAdd(PLONG,LONG); LONG WINAPI InterlockedIncrement(PLONG); VOID WINAPI SetLastError(DWORD); #ifdef __WINE__ #define GetCurrentProcess() ((HANDLE)0xffffffff) #define GetCurrentThread() ((HANDLE)0xfffffffe) #endif #ifdef __cplusplus } #endif #endif /* __WINE_WINBASE_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/windef.h������������������������������������������������������������0000644�0001750�0001750�00000044206�14647725152�015646� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Basic types definitions * * Copyright 1996 Alexandre Julliard */ #ifndef __WINE_WINDEF_H #define __WINE_WINDEF_H #include "config.h" #ifdef __WINE__ # undef UNICODE #endif #ifdef _EGCS_ #define __stdcall #endif #ifdef __cplusplus extern "C" { #endif /* Misc. constants. */ #ifdef FALSE #undef FALSE #endif #define FALSE 0 #ifdef TRUE #undef TRUE #endif #define TRUE 1 #ifdef NULL #undef NULL #endif #define NULL 0 /* Macros to map Winelib names to the correct implementation name */ /* depending on __WINE__ and UNICODE macros. */ /* Note that Winelib is purely Win32. */ #ifdef __WINE__ # define WINELIB_NAME_AW(func) \ func##_must_be_suffixed_with_W_or_A_in_this_context \ func##_must_be_suffixed_with_W_or_A_in_this_context #else /* __WINE__ */ # ifdef UNICODE # define WINELIB_NAME_AW(func) func##W # else # define WINELIB_NAME_AW(func) func##A # endif /* UNICODE */ #endif /* __WINE__ */ #ifdef __WINE__ # define DECL_WINELIB_TYPE_AW(type) /* nothing */ #else /* __WINE__ */ # define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type; #endif /* __WINE__ */ #ifndef NONAMELESSSTRUCT # if defined(__WINE__) || !defined(_FORCENAMELESSSTRUCT) # define NONAMELESSSTRUCT # endif #endif /* !defined(NONAMELESSSTRUCT) */ #ifndef NONAMELESSUNION # if defined(__WINE__) || !defined(_FORCENAMELESSUNION) || !defined(__cplusplus) # define NONAMELESSUNION # endif #endif /* !defined(NONAMELESSUNION) */ #ifndef NONAMELESSSTRUCT #define DUMMYSTRUCTNAME #define DUMMYSTRUCTNAME1 #define DUMMYSTRUCTNAME2 #define DUMMYSTRUCTNAME3 #define DUMMYSTRUCTNAME4 #define DUMMYSTRUCTNAME5 #else /* !defined(NONAMELESSSTRUCT) */ #define DUMMYSTRUCTNAME s #define DUMMYSTRUCTNAME1 s1 #define DUMMYSTRUCTNAME2 s2 #define DUMMYSTRUCTNAME3 s3 #define DUMMYSTRUCTNAME4 s4 #define DUMMYSTRUCTNAME5 s5 #endif /* !defined(NONAMELESSSTRUCT) */ #ifndef NONAMELESSUNION #define DUMMYUNIONNAME #define DUMMYUNIONNAME1 #define DUMMYUNIONNAME2 #define DUMMYUNIONNAME3 #define DUMMYUNIONNAME4 #define DUMMYUNIONNAME5 #else /* !defined(NONAMELESSUNION) */ #define DUMMYUNIONNAME u #define DUMMYUNIONNAME1 u1 #define DUMMYUNIONNAME2 u2 #define DUMMYUNIONNAME3 u3 #define DUMMYUNIONNAME4 u4 #define DUMMYUNIONNAME5 u5 #endif /* !defined(NONAMELESSUNION) */ /* Calling conventions definitions */ #ifdef __i386__ # if defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 7))) # ifndef _EGCS_ #define __stdcall __attribute__((__stdcall__)) #define __cdecl __attribute__((__cdecl__)) # define __RESTORE_ES __asm__ __volatile__("pushl %ds\n\tpopl %es") # endif # else // # error You need gcc >= 2.7 to build Wine on a 386 # define __stdcall # define __cdecl # endif #else # define __stdcall # define __cdecl # define __RESTORE_ES #endif #define CALLBACK __stdcall #define WINAPI __stdcall #define APIPRIVATE __stdcall #define PASCAL __stdcall #define pascal __stdcall #define _pascal __stdcall #if !defined(__CYGWIN__) #define _stdcall __stdcall #endif #define _fastcall __stdcall #define __fastcall __stdcall #define __export __stdcall #define CDECL __cdecl #define _CDECL __cdecl #define cdecl __cdecl #if !defined(__CYGWIN__) #define _cdecl __cdecl #endif #define WINAPIV __cdecl #define APIENTRY WINAPI #if !defined(__CYGWIN__) #define __declspec(x) #endif #define dllimport #define dllexport #define CONST const /* Standard data types. These are the same for emulator and library. */ typedef void VOID; typedef int INT; typedef unsigned int UINT; typedef unsigned short WORD; typedef unsigned long DWORD; typedef unsigned long ULONG; typedef unsigned char BYTE; typedef long LONG; typedef short SHORT; typedef unsigned short USHORT; typedef char CHAR; typedef unsigned char UCHAR; typedef LONG SCODE; /* Some systems might have wchar_t, but we really need 16 bit characters */ typedef unsigned short WCHAR; typedef int WIN_BOOL; typedef double DATE; typedef double DOUBLE; typedef long long LONGLONG; typedef unsigned long long ULONGLONG; /* FIXME: Wine does not compile with strict on, therefore strict * handles are presently only usable on machines where sizeof(UINT) == * sizeof(void*). HANDLEs are supposed to be void* but a large amount * of WINE code operates on HANDLES as if they are UINTs. So to WINE * they exist as UINTs but to the Winelib user who turns on strict, * they exist as void*. If there is a size difference between UINT and * void* then things get ugly. */ #ifdef STRICT typedef VOID* HANDLE; #else typedef UINT HANDLE; #endif typedef HANDLE *LPHANDLE; /* Integer types. These are the same for emulator and library. */ typedef UINT WPARAM; typedef LONG LPARAM; typedef LONG HRESULT; typedef LONG LRESULT; typedef WORD ATOM; typedef WORD CATCHBUF[9]; typedef WORD *LPCATCHBUF; typedef HANDLE HHOOK; typedef HANDLE HMONITOR; typedef DWORD LCID; typedef WORD LANGID; typedef DWORD LCTYPE; typedef float FLOAT; /* Pointers types. These are the same for emulator and library. */ /* winnt types */ typedef VOID *PVOID; typedef const void *PCVOID; typedef CHAR *PCHAR; typedef UCHAR *PUCHAR; typedef BYTE *PBYTE; typedef WORD *PWORD; typedef USHORT *PUSHORT; typedef SHORT *PSHORT; typedef ULONG *PULONG; typedef LONG *PLONG; typedef DWORD *PDWORD; /* common win32 types */ typedef CHAR *LPSTR; typedef CHAR *PSTR; typedef const CHAR *LPCSTR; typedef const CHAR *PCSTR; typedef WCHAR *LPWSTR; typedef WCHAR *PWSTR; typedef const WCHAR *LPCWSTR; typedef const WCHAR *PCWSTR; typedef BYTE *LPBYTE; typedef WORD *LPWORD; typedef DWORD *LPDWORD; typedef LONG *LPLONG; typedef VOID *LPVOID; typedef const VOID *LPCVOID; typedef INT *PINT; typedef INT *LPINT; typedef UINT *PUINT; typedef UINT *LPUINT; typedef FLOAT *PFLOAT; typedef FLOAT *LPFLOAT; typedef WIN_BOOL *PWIN_BOOL; typedef WIN_BOOL *LPWIN_BOOL; /* Special case: a segmented pointer is just a pointer in the user's code. */ #ifdef __WINE__ typedef DWORD SEGPTR; #else typedef void* SEGPTR; #endif /* __WINE__ */ /* Handle types that exist both in Win16 and Win32. */ #ifdef STRICT #define DECLARE_HANDLE(a) \ typedef struct a##__ { int unused; } *a; \ typedef a *P##a; \ typedef a *LP##a #else /*STRICT*/ #define DECLARE_HANDLE(a) \ typedef HANDLE a; \ typedef a *P##a; \ typedef a *LP##a #endif /*STRICT*/ DECLARE_HANDLE(HACMDRIVERID); DECLARE_HANDLE(HACMDRIVER); DECLARE_HANDLE(HACMOBJ); DECLARE_HANDLE(HACMSTREAM); DECLARE_HANDLE(HMETAFILEPICT); DECLARE_HANDLE(HACCEL); DECLARE_HANDLE(HBITMAP); DECLARE_HANDLE(HBRUSH); DECLARE_HANDLE(HCOLORSPACE); DECLARE_HANDLE(HCURSOR); DECLARE_HANDLE(HDC); DECLARE_HANDLE(HDROP); DECLARE_HANDLE(HDRVR); DECLARE_HANDLE(HDWP); DECLARE_HANDLE(HENHMETAFILE); DECLARE_HANDLE(HFILE); DECLARE_HANDLE(HFONT); DECLARE_HANDLE(HICON); DECLARE_HANDLE(HINSTANCE); DECLARE_HANDLE(HKEY); DECLARE_HANDLE(HMENU); DECLARE_HANDLE(HMETAFILE); DECLARE_HANDLE(HMIDI); DECLARE_HANDLE(HMIDIIN); DECLARE_HANDLE(HMIDIOUT); DECLARE_HANDLE(HMIDISTRM); DECLARE_HANDLE(HMIXER); DECLARE_HANDLE(HMIXEROBJ); DECLARE_HANDLE(HMMIO); DECLARE_HANDLE(HPALETTE); DECLARE_HANDLE(HPEN); DECLARE_HANDLE(HQUEUE); DECLARE_HANDLE(HRGN); DECLARE_HANDLE(HRSRC); DECLARE_HANDLE(HTASK); DECLARE_HANDLE(HWAVE); DECLARE_HANDLE(HWAVEIN); DECLARE_HANDLE(HWAVEOUT); DECLARE_HANDLE(HWINSTA); DECLARE_HANDLE(HDESK); DECLARE_HANDLE(HWND); DECLARE_HANDLE(HKL); DECLARE_HANDLE(HIC); DECLARE_HANDLE(HRASCONN); /* Handle types that must remain interchangeable even with strict on */ typedef HINSTANCE HMODULE; typedef HANDLE HGDIOBJ; typedef HANDLE HGLOBAL; typedef HANDLE HLOCAL; typedef HANDLE GLOBALHANDLE; typedef HANDLE LOCALHANDLE; /* Callback function pointers types */ /*WIN_BOOL CALLBACK DATEFMT_ENUMPROCA(LPSTR); */ typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCA)(LPSTR); typedef WIN_BOOL CALLBACK (* DATEFMT_ENUMPROCW)(LPWSTR); DECL_WINELIB_TYPE_AW(DATEFMT_ENUMPROC) typedef WIN_BOOL CALLBACK (*DLGPROC)(HWND,UINT,WPARAM,LPARAM); typedef LRESULT CALLBACK (*DRIVERPROC)(DWORD,HDRVR,UINT,LPARAM,LPARAM); typedef INT CALLBACK (*EDITWORDBREAKPROCA)(LPSTR,INT,INT,INT); typedef INT CALLBACK (*EDITWORDBREAKPROCW)(LPWSTR,INT,INT,INT); DECL_WINELIB_TYPE_AW(EDITWORDBREAKPROC) typedef LRESULT CALLBACK (*FARPROC)(); typedef INT CALLBACK (*PROC)(); typedef WIN_BOOL CALLBACK (*GRAYSTRINGPROC)(HDC,LPARAM,INT); typedef LRESULT CALLBACK (*HOOKPROC)(INT,WPARAM,LPARAM); typedef WIN_BOOL CALLBACK (*PROPENUMPROCA)(HWND,LPCSTR,HANDLE); typedef WIN_BOOL CALLBACK (*PROPENUMPROCW)(HWND,LPCWSTR,HANDLE); DECL_WINELIB_TYPE_AW(PROPENUMPROC) typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXA)(HWND,LPCSTR,HANDLE,LPARAM); typedef WIN_BOOL CALLBACK (*PROPENUMPROCEXW)(HWND,LPCWSTR,HANDLE,LPARAM); DECL_WINELIB_TYPE_AW(PROPENUMPROCEX) typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCA)(LPSTR); typedef WIN_BOOL CALLBACK (* TIMEFMT_ENUMPROCW)(LPWSTR); DECL_WINELIB_TYPE_AW(TIMEFMT_ENUMPROC) typedef VOID CALLBACK (*TIMERPROC)(HWND,UINT,UINT,DWORD); typedef WIN_BOOL CALLBACK (*WNDENUMPROC)(HWND,LPARAM); typedef LRESULT CALLBACK (*WNDPROC)(HWND,UINT,WPARAM,LPARAM); /*---------------------------------------------------------------------------- ** FIXME: Better isolate Wine's reliance on the xxx16 type definitions. ** For now, we just isolate them to make the situation clear. **--------------------------------------------------------------------------*/ /* * Basic type definitions for 16 bit variations on Windows types. * These types are provided mostly to insure compatibility with * 16 bit windows code. */ #ifndef __WINE_WINDEF16_H #define __WINE_WINDEF16_H #include "windef.h" /* Standard data types */ typedef short INT16; typedef unsigned short UINT16; typedef unsigned short WIN_BOOL16; typedef UINT16 HANDLE16; typedef HANDLE16 *LPHANDLE16; typedef UINT16 WPARAM16; typedef INT16 *LPINT16; typedef UINT16 *LPUINT16; #define DECLARE_HANDLE16(a) \ typedef HANDLE16 a##16; \ typedef a##16 *P##a##16; \ typedef a##16 *NP##a##16; \ typedef a##16 *LP##a##16 DECLARE_HANDLE16(HACMDRIVERID); DECLARE_HANDLE16(HACMDRIVER); DECLARE_HANDLE16(HACMOBJ); DECLARE_HANDLE16(HACMSTREAM); DECLARE_HANDLE16(HMETAFILEPICT); DECLARE_HANDLE16(HACCEL); DECLARE_HANDLE16(HBITMAP); DECLARE_HANDLE16(HBRUSH); DECLARE_HANDLE16(HCOLORSPACE); DECLARE_HANDLE16(HCURSOR); DECLARE_HANDLE16(HDC); DECLARE_HANDLE16(HDROP); DECLARE_HANDLE16(HDRVR); DECLARE_HANDLE16(HDWP); DECLARE_HANDLE16(HENHMETAFILE); DECLARE_HANDLE16(HFILE); DECLARE_HANDLE16(HFONT); DECLARE_HANDLE16(HICON); DECLARE_HANDLE16(HINSTANCE); DECLARE_HANDLE16(HKEY); DECLARE_HANDLE16(HMENU); DECLARE_HANDLE16(HMETAFILE); DECLARE_HANDLE16(HMIDI); DECLARE_HANDLE16(HMIDIIN); DECLARE_HANDLE16(HMIDIOUT); DECLARE_HANDLE16(HMIDISTRM); DECLARE_HANDLE16(HMIXER); DECLARE_HANDLE16(HMIXEROBJ); DECLARE_HANDLE16(HMMIO); DECLARE_HANDLE16(HPALETTE); DECLARE_HANDLE16(HPEN); DECLARE_HANDLE16(HQUEUE); DECLARE_HANDLE16(HRGN); DECLARE_HANDLE16(HRSRC); DECLARE_HANDLE16(HTASK); DECLARE_HANDLE16(HWAVE); DECLARE_HANDLE16(HWAVEIN); DECLARE_HANDLE16(HWAVEOUT); DECLARE_HANDLE16(HWINSTA); DECLARE_HANDLE16(HDESK); DECLARE_HANDLE16(HWND); DECLARE_HANDLE16(HKL); DECLARE_HANDLE16(HIC); DECLARE_HANDLE16(HRASCONN); #undef DECLARE_HANDLE16 typedef HINSTANCE16 HMODULE16; typedef HANDLE16 HGDIOBJ16; typedef HANDLE16 HGLOBAL16; typedef HANDLE16 HLOCAL16; /* The SIZE structure */ typedef struct { INT16 cx; INT16 cy; } SIZE16, *PSIZE16, *LPSIZE16; /* The POINT structure */ typedef struct { INT16 x; INT16 y; } POINT16, *PPOINT16, *LPPOINT16; /* The RECT structure */ typedef struct { INT16 left; INT16 top; INT16 right; INT16 bottom; } RECT16, *LPRECT16; /* Callback function pointers types */ typedef LRESULT CALLBACK (*DRIVERPROC16)(DWORD,HDRVR16,UINT16,LPARAM,LPARAM); typedef WIN_BOOL16 CALLBACK (*DLGPROC16)(HWND16,UINT16,WPARAM16,LPARAM); typedef INT16 CALLBACK (*EDITWORDBREAKPROC16)(LPSTR,INT16,INT16,INT16); typedef LRESULT CALLBACK (*FARPROC16)(); typedef INT16 CALLBACK (*PROC16)(); typedef WIN_BOOL16 CALLBACK (*GRAYSTRINGPROC16)(HDC16,LPARAM,INT16); typedef LRESULT CALLBACK (*HOOKPROC16)(INT16,WPARAM16,LPARAM); typedef WIN_BOOL16 CALLBACK (*PROPENUMPROC16)(HWND16,SEGPTR,HANDLE16); typedef VOID CALLBACK (*TIMERPROC16)(HWND16,UINT16,UINT16,DWORD); typedef LRESULT CALLBACK (*WNDENUMPROC16)(HWND16,LPARAM); typedef LRESULT CALLBACK (*WNDPROC16)(HWND16,UINT16,WPARAM16,LPARAM); #endif /* __WINE_WINDEF16_H */ /* Define some empty macros for compatibility with Windows code. */ #ifndef __WINE__ #define NEAR #define FAR #define near #define far #define _near #define _far #define IN #define OUT #define OPTIONAL #endif /* __WINE__ */ /* Macro for structure packing. */ #define WINE_PACKED XINE_PACKED #if defined(__GNUC__) || defined(__ICC) #ifndef _EGCS_ #define WINE_UNUSED __attribute__((unused)) #define WINE_NORETURN __attribute__((noreturn)) #endif #else #define WINE_UNUSED /* nothing */ #define WINE_NORETURN /* nothing */ #endif /* Macros to split words and longs. */ #define LOBYTE(w) ((BYTE)(WORD)(w)) #define HIBYTE(w) ((BYTE)((WORD)(w) >> 8)) #define LOWORD(l) ((WORD)(DWORD)(l)) #define HIWORD(l) ((WORD)((DWORD)(l) >> 16)) #define SLOWORD(l) ((INT16)(LONG)(l)) #define SHIWORD(l) ((INT16)((LONG)(l) >> 16)) #define MAKEWORD(low,high) ((WORD)(((BYTE)(low)) | ((WORD)((BYTE)(high))) << 8)) #define MAKELONG(low,high) ((LONG)(((WORD)(low)) | (((DWORD)((WORD)(high))) << 16))) #define MAKELPARAM(low,high) ((LPARAM)MAKELONG(low,high)) #define MAKEWPARAM(low,high) ((WPARAM)MAKELONG(low,high)) #define MAKELRESULT(low,high) ((LRESULT)MAKELONG(low,high)) #define MAKEINTATOM(atom) ((LPCSTR)MAKELONG((atom),0)) #define SELECTOROF(ptr) (HIWORD(ptr)) #define OFFSETOF(ptr) (LOWORD(ptr)) #ifdef __WINE__ /* macros to set parts of a DWORD (not in the Windows API) */ #define SET_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD(val)) #define SET_LOBYTE(dw,val) ((dw) = ((dw) & 0xffffff00) | LOBYTE(val)) #define SET_HIBYTE(dw,val) ((dw) = ((dw) & 0xffff00ff) | (LOWORD(val) & 0xff00)) #define ADD_LOWORD(dw,val) ((dw) = ((dw) & 0xffff0000) | LOWORD((DWORD)(dw)+(val))) #endif /* Macros to access unaligned or wrong-endian WORDs and DWORDs. */ /* Note: These macros are semantically broken, at least for wrc. wrc spits out data in the platform's current binary format, *not* in little-endian format. These macros are used throughout the resource code to load and store data to the resources. Since it is unlikely that we'll ever be dealing with little-endian resource data, the byte-swapping nature of these macros has been disabled. Rather than remove the use of these macros from the resource loading code, the macros have simply been disabled. In the future, someone may want to reactivate these macros for other purposes. In that case, the resource code will have to be modified to use different macros. */ #if 1 #define PUT_WORD(ptr,w) (*(WORD *)(ptr) = (w)) #define GET_WORD(ptr) (*(WORD *)(ptr)) #define PUT_DWORD(ptr,dw) (*(DWORD *)(ptr) = (dw)) #define GET_DWORD(ptr) (*(DWORD *)(ptr)) #else #define PUT_WORD(ptr,w) (*(BYTE *)(ptr) = LOBYTE(w), \ *((BYTE *)(ptr) + 1) = HIBYTE(w)) #define GET_WORD(ptr) ((WORD)(*(BYTE *)(ptr) | \ (WORD)(*((BYTE *)(ptr)+1) << 8))) #define PUT_DWORD(ptr,dw) (PUT_WORD((ptr),LOWORD(dw)), \ PUT_WORD((WORD *)(ptr)+1,HIWORD(dw))) #define GET_DWORD(ptr) ((DWORD)(GET_WORD(ptr) | \ ((DWORD)GET_WORD((WORD *)(ptr)+1) << 16))) #endif /* 1 */ /* min and max macros */ #define __max(a,b) (((a) > (b)) ? (a) : (b)) #define __min(a,b) (((a) < (b)) ? (a) : (b)) #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #ifndef min #define min(a,b) (((a) < (b)) ? (a) : (b)) #endif #define _MAX_PATH 260 #define MAX_PATH 260 #define _MAX_DRIVE 3 #define _MAX_DIR 256 #define _MAX_FNAME 255 #define _MAX_EXT 256 #define HFILE_ERROR16 ((HFILE16)-1) #define HFILE_ERROR ((HFILE)-1) /* The SIZE structure */ typedef struct tagSIZE { INT cx; INT cy; } SIZE, *PSIZE, *LPSIZE; typedef SIZE SIZEL, *PSIZEL, *LPSIZEL; #define CONV_SIZE16TO32(s16,s32) \ ((s32)->cx = (INT)(s16)->cx, (s32)->cy = (INT)(s16)->cy) #define CONV_SIZE32TO16(s32,s16) \ ((s16)->cx = (INT16)(s32)->cx, (s16)->cy = (INT16)(s32)->cy) /* The POINT structure */ typedef struct tagPOINT { LONG x; LONG y; } POINT, *PPOINT, *LPPOINT; typedef struct _POINTL { LONG x; LONG y; } POINTL; #define CONV_POINT16TO32(p16,p32) \ ((p32)->x = (INT)(p16)->x, (p32)->y = (INT)(p16)->y) #define CONV_POINT32TO16(p32,p16) \ ((p16)->x = (INT16)(p32)->x, (p16)->y = (INT16)(p32)->y) #define MAKEPOINT16(l) (*((POINT16 *)&(l))) /* The POINTS structure */ typedef struct tagPOINTS { SHORT x; SHORT y; } POINTS, *PPOINTS, *LPPOINTS; #define MAKEPOINTS(l) (*((POINTS *)&(l))) /* The RECT structure */ typedef struct tagRECT { short left; short top; short right; short bottom; } RECT, *PRECT, *LPRECT; typedef const RECT *LPCRECT; typedef struct tagRECTL { LONG left; LONG top; LONG right; LONG bottom; } RECTL, *PRECTL, *LPRECTL; typedef const RECTL *LPCRECTL; #define CONV_RECT16TO32(r16,r32) \ ((r32)->left = (INT)(r16)->left, (r32)->top = (INT)(r16)->top, \ (r32)->right = (INT)(r16)->right, (r32)->bottom = (INT)(r16)->bottom) #define CONV_RECT32TO16(r32,r16) \ ((r16)->left = (INT16)(r32)->left, (r16)->top = (INT16)(r32)->top, \ (r16)->right = (INT16)(r32)->right, (r16)->bottom = (INT16)(r32)->bottom) #ifdef __cplusplus } #endif #endif /* __WINE_WINDEF_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/registry.c����������������������������������������������������������0000644�0001750�0001750�00000026232�14647725152�016234� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "config.h" #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <pwd.h> #include <sys/types.h> #include "winbase.h" #include "winreg.h" #include "winnt.h" #include "winerror.h" #include "ext.h" #include "registry.h" #include "debugtools.h" #ifdef XINE_MAJOR #include <xine/xineutils.h> #include <basedir.h> #endif #ifdef __DragonFly__ #include <sys/stat.h> #endif //#undef TRACE //#define TRACE printf extern char *get_path ( char * ); // ...can be set before init_registry() call char* regpathname = NULL; static char* localregpathname = NULL; typedef struct reg_handle_s { int handle; char* name; struct reg_handle_s* next; struct reg_handle_s* prev; } reg_handle_t; struct reg_value { int type; char* name; int len; char* value; }; static struct reg_value* regs = NULL; static int reg_size; static reg_handle_t* head = NULL; #define DIR -25 static void create_registry(void); static void open_registry(void); static void save_registry(void); static void init_registry(void); static void create_registry(void){ if(regs) { printf("Logic error: create_registry() called with existing registry\n"); save_registry(); return; } regs=(struct reg_value*)malloc(3*sizeof(struct reg_value)); regs[0].type=regs[1].type=DIR; regs[0].name=(char*)malloc(5); strcpy(regs[0].name, "HKLM"); regs[1].name=(char*)malloc(5); strcpy(regs[1].name, "HKCU"); regs[0].value=regs[1].value=NULL; regs[0].len=regs[1].len=0; reg_size=2; head = 0; save_registry(); } static void open_registry(void) { int fd; int i; unsigned int len; if(regs) { printf("Multiple open_registry(>\n"); return; } fd = xine_open_cloexec(localregpathname, O_RDONLY); if (fd == -1) { printf("Creating new registry\n"); create_registry(); return; } read(fd, ®_size, 4); regs=(struct reg_value*)malloc(reg_size*sizeof(struct reg_value)); head = 0; for(i=0; i<reg_size; i++) { read(fd,®s[i].type,4); read(fd,&len,4); regs[i].name=(char*)malloc(len+1); if(regs[i].name==0) { reg_size=i+1; goto error; } read(fd, regs[i].name, len); regs[i].name[len]=0; read(fd,®s[i].len,4); regs[i].value=(char*)malloc(regs[i].len+1); if(regs[i].value==0) { free(regs[i].name); reg_size=i+1; goto error; } read(fd, regs[i].value, regs[i].len); regs[i].value[regs[i].len]=0; } error: close(fd); return; } static void save_registry(void) { int fd, i; if (!regs) init_registry(); fd = xine_create_cloexec(localregpathname, O_WRONLY, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (fd == -1) { printf("Failed to open registry file '%s' for writing.\n", localregpathname); return; } write(fd, ®_size, 4); for(i=0; i<reg_size; i++) { unsigned len=strlen(regs[i].name); write(fd, ®s[i].type, 4); write(fd, &len, 4); write(fd, regs[i].name, len); write(fd, ®s[i].len, 4); write(fd, regs[i].value, regs[i].len); } close(fd); } void free_registry(void) { reg_handle_t* t = head; while (t) { reg_handle_t* f = t; if (t->name) free(t->name); t=t->prev; free(f); } head = 0; if (regs) { int i; for(i=0; i<reg_size; i++) { free(regs[i].name); free(regs[i].value); } free(regs); regs = 0; } if (localregpathname && localregpathname != regpathname) free(localregpathname); localregpathname = 0; } #if 0 static reg_handle_t* find_handle_by_name(const char* name) { reg_handle_t* t; for(t=head; t; t=t->prev) { if(!strcmp(t->name, name)) { return t; } } return 0; } #endif static struct reg_value* find_value_by_name(const char* name) { int i; for(i=0; i<reg_size; i++) if(!strcmp(regs[i].name, name)) return regs+i; return 0; } static reg_handle_t* find_handle(int handle) { reg_handle_t* t; for(t=head; t; t=t->prev) { if(t->handle==handle) { return t; } } return 0; } static int generate_handle() { static unsigned int zz=249; zz++; while((zz==HKEY_LOCAL_MACHINE) || (zz==HKEY_CURRENT_USER)) zz++; return zz; } static reg_handle_t* insert_handle(long handle, const char* name) { reg_handle_t* t; t=(reg_handle_t*)malloc(sizeof(reg_handle_t)); if(head==0) { t->prev=0; } else { head->next=t; t->prev=head; } t->next=0; t->name=(char*)malloc(strlen(name)+1); strcpy(t->name, name); t->handle=handle; head=t; return t; } static char* build_keyname(long key, const char* subkey) { char* full_name; reg_handle_t* t; if((t=find_handle(key))==0) { TRACE("Invalid key\n"); return NULL; } if(subkey==NULL) subkey="<default>"; full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); strcpy(full_name, t->name); strcat(full_name, "\\"); strcat(full_name, subkey); return full_name; } static struct reg_value* insert_reg_value(int handle, const char* name, int type, const void* value, int len) { /* reg_handle_t* t; -- unused */ struct reg_value* v; char* fullname; if((fullname=build_keyname(handle, name))==NULL) { TRACE("Invalid handle\n"); return NULL; } if((v=find_value_by_name(fullname))==0) //creating new value in registry { if(regs==0) create_registry(); regs=(struct reg_value*)realloc(regs, sizeof(struct reg_value)*(reg_size+1)); //regs=(struct reg_value*)my_realloc(regs, sizeof(struct reg_value)*(reg_size+1)); v=regs+reg_size; reg_size++; } else //replacing old one { free(v->value); free(v->name); } v->type=type; v->len=len; v->value=(char*)malloc(len); memcpy(v->value, value, len); v->name=(char*)malloc(strlen(fullname)+1); strcpy(v->name, fullname); free(fullname); save_registry(); return v; } static void init_registry(void) { xdgHandle tmph; xdgInitHandle(&tmph); const char *const xdg_cache_home = xdgCacheHome(&tmph); TRACE("Initializing registry\n"); // can't be free-ed - it's static and probably thread // unsafe structure which is stored in glibc localregpathname = malloc(strlen(xdg_cache_home) + sizeof("/"PACKAGE"/win32registry")); strcpy(localregpathname, xdg_cache_home); strcat(localregpathname, "/"PACKAGE"/win32registry"); open_registry(); insert_handle(HKEY_LOCAL_MACHINE, "HKLM"); insert_handle(HKEY_CURRENT_USER, "HKCU"); xdgWipeHandle(&tmph); } #if 0 /* UNUSED function */ static reg_handle_t* find_handle_2(long key, const char* subkey) { char* full_name; reg_handle_t* t; if((t=find_handle(key))==0) { TRACE("Invalid key\n"); return (reg_handle_t*)-1; } if(subkey==NULL) return t; full_name=(char*)malloc(strlen(t->name)+strlen(subkey)+10); strcpy(full_name, t->name); strcat(full_name, "\\"); strcat(full_name, subkey); t=find_handle_by_name(full_name); free(full_name); return t; } #endif long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) { char* full_name; reg_handle_t* t; struct reg_value* v; TRACE("Opening key %s\n", subkey); (void)reserved; (void)access; if(!regs) init_registry() ; /* t=find_handle_2(key, subkey); if(t==0) return -1; if(t==(reg_handle_t*)-1) return -1; */ full_name=build_keyname(key, subkey); if(!full_name) return -1; TRACE("Opening key Fullname %s\n", full_name); v=find_value_by_name(full_name); t=insert_handle(generate_handle(), full_name); *newkey=t->handle; free(full_name); return 0; } long RegCloseKey(long key) { reg_handle_t *handle; if (key == (long)HKEY_LOCAL_MACHINE) return 0; if (key == (long)HKEY_CURRENT_USER) return 0; handle=find_handle(key); if(handle==0) return 0; if(handle->prev) handle->prev->next=handle->next; if(handle->next) handle->next->prev=handle->prev; if(handle->name) free(handle->name); if(handle==head) head=head->prev; free(handle); return 1; } long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) { struct reg_value* t; char* c; TRACE("Querying value %s\n", value); (void)reserved; if(!regs) init_registry(); c=build_keyname(key, value); if (!c) return 1; t=find_value_by_name(c); free(c); if (t==0) return 2; if (type) *type=t->type; if (data) { memcpy(data, t->value, (t->len<*count)?t->len:*count); TRACE("returning %d bytes: %d\n", t->len, *(int*)data); } if(*count<t->len) { *count=t->len; return ERROR_MORE_DATA; } else { *count=t->len; } return 0; } long RegCreateKeyExA(long key, const char* name, long reserved, void* classs, long options, long security, void* sec_attr, int* newkey, int* status) { reg_handle_t* t; char* fullname; struct reg_value* v; // TRACE("Creating/Opening key %s\n", name); (void)reserved; (void)classs; (void)options; (void)security; (void)sec_attr; if(!regs) init_registry(); fullname=build_keyname(key, name); if (!fullname) return 1; TRACE("Creating/Opening key %s\n", fullname); v=find_value_by_name(fullname); if(v==0) { int qw=45708; v=insert_reg_value(key, name, DIR, &qw, 4); if (status) *status=REG_CREATED_NEW_KEY; // return 0; } t=insert_handle(generate_handle(), fullname); *newkey=t->handle; free(fullname); return 0; } /* LONG RegEnumValue( HKEY hKey, // handle to key to query DWORD dwIndex, // index of value to query LPTSTR lpValueName, // address of buffer for value string LPDWORD lpcbValueName, // address for size of value buffer LPDWORD lpReserved, // reserved LPDWORD lpType, // address of buffer for type code LPBYTE lpData, // address of buffer for value data LPDWORD lpcbData // address for size of data buffer ); */ long RegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) { // currenly just made to support MSZH & ZLIB //printf("Reg Enum 0x%x %d %s %d data: %p %d %d >%s<\n", hkey, index, // value, *val_count, data, *count, reg_size, data); reg_handle_t* t = find_handle(hkey); (void)value; (void)val_count; (void)reserved; if (t && index < 10) { struct reg_value* v=find_value_by_name(t->name); if (v) { DWORD vlen = v->len < 0 ? 0 : v->len; memcpy (data, v->value, (vlen < *count) ? vlen : *count); if (*count < vlen) *count = vlen; if (type) *type = v->type; //printf("Found handle %s\n", v->name); return 0; } } return ERROR_NO_MORE_ITEMS; } long RegSetValueExA(long key, const char* name, long v1, long v2, const void* data, long size) { /* struct reg_value* t; -- unused */ char* c; TRACE("Request to set value %s\n", name); (void)v1; if(!regs) init_registry(); c=build_keyname(key, name); if(c==NULL) return 1; insert_reg_value(key, name, v2, data, size); free(c); return 0; } long RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, LPFILETIME lpftLastWriteTime) { (void)hKey; (void)dwIndex; (void)lpName; (void)lpcbName; (void)lpReserved; (void)lpClass; (void)lpcbClass; (void)lpftLastWriteTime; return ERROR_NO_MORE_ITEMS; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/wrapper.S�����������������������������������������������������������0000644�0001750�0001750�00000004151�14647725152�016020� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������.section .data caller_return: .long 0 .global wrapper_target wrapper_target: .long null_call #undef __i686 /* gcc define gets in our way */ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits .globl __i686.get_pc_thunk.bx .hidden __i686.get_pc_thunk.bx .type __i686.get_pc_thunk.bx,@function __i686.get_pc_thunk.bx: movl (%esp), %ebx ret .section .text .globl null_call .type null_call, @function .balign 16,0x90 null_call: ret .globl wrapper .type wrapper, @function .balign 16,0x90 wrapper: pushl $0 pusha # store registers (EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI) pushf # store flags push %ebp # set up a stack frame movl %esp, %ebp call __i686.get_pc_thunk.bx addl $_GLOBAL_OFFSET_TABLE_, %ebx leal 4(%ebp), %eax # push flags addr push %eax leal 8(%ebp), %eax # push registers addr push %eax leal 44(%ebp), %edx movl (%ebp), %eax subl %edx, %eax push %eax push %edx call report_func@PLT # report entry test %eax, %eax jnz .Ldone movl 44(%ebp), %eax # switch return addresses movl %eax, caller_return@GOTOFF(%ebx) leal .Lwrapper_return@GOTOFF(%ebx), %eax movl %eax, 40(%ebp) movl wrapper_target@GOT(%ebx), %eax movl (%eax), %eax mov %eax, 40(%ebp) # wrapper_target should return at .Lwrapper_return leave # restore %esp, %ebp popf # restore flags popa # restore registers ret # fake 'return' to wrapper_target actually .balign 16, 0x90 .Lwrapper_return: pushl $0 pusha # more for reference sake here pushf push %ebp # set up a stack frame movl %esp, %ebp call __i686.get_pc_thunk.bx addl $_GLOBAL_OFFSET_TABLE_, %ebx movl caller_return@GOTOFF(%ebx), %eax movl %eax, 40(%ebp) # restore the original return address leal 4(%ebp), %eax # push flags addr push %eax leal 8(%ebp), %eax # push registers addr push %eax leal 40(%ebp), %edx # push stack top address (relative to our entry) movl (%ebp), %eax subl %edx, %eax # calculate difference between entry and previous frame push %eax push %edx call report_func_ret@PLT# report the return information (same args) .Ldone: leave popf popa ret .section .note.GNU-stack,"",@progbits �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/winnt.h�������������������������������������������������������������0000644�0001750�0001750�00000240053�14647725152�015527� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Win32 definitions for Windows NT * * Copyright 1996 Alexandre Julliard */ #ifndef __WINE_WINNT_H #define __WINE_WINNT_H #include "windef.h" #ifndef RC_INVOKED #include <string.h> #endif #include "pshpack1.h" /* Defines */ /* Argument 1 passed to the DllEntryProc. */ #define DLL_PROCESS_DETACH 0 /* detach process (unload library) */ #define DLL_PROCESS_ATTACH 1 /* attach process (load library) */ #define DLL_THREAD_ATTACH 2 /* attach new thread */ #define DLL_THREAD_DETACH 3 /* detach thread */ /* u.x.wProcessorArchitecture (NT) */ #define PROCESSOR_ARCHITECTURE_INTEL 0 #define PROCESSOR_ARCHITECTURE_MIPS 1 #define PROCESSOR_ARCHITECTURE_ALPHA 2 #define PROCESSOR_ARCHITECTURE_PPC 3 #define PROCESSOR_ARCHITECTURE_SHX 4 #define PROCESSOR_ARCHITECTURE_ARM 5 #define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF /* dwProcessorType */ #define PROCESSOR_INTEL_386 386 #define PROCESSOR_INTEL_486 486 #define PROCESSOR_INTEL_PENTIUM 586 #define PROCESSOR_INTEL_860 860 #define PROCESSOR_MIPS_R2000 2000 #define PROCESSOR_MIPS_R3000 3000 #define PROCESSOR_MIPS_R4000 4000 #define PROCESSOR_ALPHA_21064 21064 #define PROCESSOR_PPC_601 601 #define PROCESSOR_PPC_603 603 #define PROCESSOR_PPC_604 604 #define PROCESSOR_PPC_620 620 #define PROCESSOR_HITACHI_SH3 10003 #define PROCESSOR_HITACHI_SH3E 10004 #define PROCESSOR_HITACHI_SH4 10005 #define PROCESSOR_MOTOROLA_821 821 #define PROCESSOR_SHx_SH3 103 #define PROCESSOR_SHx_SH4 104 #define PROCESSOR_STRONGARM 2577 #define PROCESSOR_ARM720 1824 /* 0x720 */ #define PROCESSOR_ARM820 2080 /* 0x820 */ #define PROCESSOR_ARM920 2336 /* 0x920 */ #define PROCESSOR_ARM_7TDMI 70001 #define ANYSIZE_ARRAY 1 #define MINCHAR 0x80 #define MAXCHAR 0x7f #define MINSHORT 0x8000 #define MAXSHORT 0x7fff #define MINLONG 0x80000000 #define MAXLONG 0x7fffffff #define MAXBYTE 0xff #define MAXWORD 0xffff #define MAXDWORD 0xffffffff #define FIELD_OFFSET(type, field) \ ((LONG)(INT)&(((type *)0)->field)) #define CONTAINING_RECORD(address, type, field) \ ((type *)((PCHAR)(address) - (PCHAR)(&((type *)0)->field))) /* Types */ /* TCHAR data types definitions for Winelib. */ /* These types are _not_ defined for the emulator, because they */ /* depend on the UNICODE macro that only exists in user's code. */ //#ifndef __WINE__ # ifdef UNICODE typedef WCHAR TCHAR, *PTCHAR; typedef LPWSTR PTSTR, LPTSTR; typedef LPCWSTR PCTSTR, LPCTSTR; #define __TEXT(string) L##string /*probably wrong */ # else /* UNICODE */ typedef char TCHAR, *PTCHAR; typedef LPSTR PTSTR, LPTSTR; typedef LPCSTR PCTSTR, LPCTSTR; #define __TEXT(string) string # endif /* UNICODE */ //#endif /* __WINE__ */ #define TEXT(quote) __TEXT(quote) typedef BYTE BOOLEAN; typedef BOOLEAN *PBOOLEAN; typedef struct _LIST_ENTRY { struct _LIST_ENTRY *Flink; struct _LIST_ENTRY *Blink; } LIST_ENTRY, *PLIST_ENTRY; typedef struct _SINGLE_LIST_ENTRY { struct _SINGLE_LIST_ENTRY *Next; } SINGLE_LIST_ENTRY, *PSINGLE_LIST_ENTRY; /* Heap flags */ #define HEAP_NO_SERIALIZE 0x00000001 #define HEAP_GROWABLE 0x00000002 #define HEAP_GENERATE_EXCEPTIONS 0x00000004 #define HEAP_ZERO_MEMORY 0x00000008 #define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 #define HEAP_TAIL_CHECKING_ENABLED 0x00000020 #define HEAP_FREE_CHECKING_ENABLED 0x00000040 #define HEAP_DISABLE_COALESCE_ON_FREE 0x00000080 #define HEAP_CREATE_ALIGN_16 0x00010000 #define HEAP_CREATE_ENABLE_TRACING 0x00020000 #define HEAP_WINE_SEGPTR 0x01000000 /* Not a Win32 flag */ #define HEAP_WINE_CODESEG 0x02000000 /* Not a Win32 flag */ #define HEAP_WINE_CODE16SEG 0x04000000 /* Not a Win32 flag */ #define HEAP_WINE_SHARED 0x08000000 /* Not a Win32 flag */ /* Processor feature flags. */ #define PF_FLOATING_POINT_PRECISION_ERRATA 0 #define PF_FLOATING_POINT_EMULATED 1 #define PF_COMPARE_EXCHANGE_DOUBLE 2 #define PF_MMX_INSTRUCTIONS_AVAILABLE 3 #define PF_PPC_MOVEMEM_64BIT_OK 4 #define PF_ALPHA_BYTE_INSTRUCTIONS 5 /* based on wine-20010510 -- alex */ #define PF_XMMI_INSTRUCTIONS_AVAILABLE 6 #define PF_AMD3D_INSTRUCTIONS_AVAILABLE 7 #define PF_RDTSC_INSTRUCTION_AVAILABLE 8 /* The Win32 register context */ /* CONTEXT is the CPU-dependent context; it should be used */ /* wherever a platform-specific context is needed (e.g. exception */ /* handling, Win32 register functions). */ /* CONTEXT86 is the i386-specific context; it should be used */ /* wherever only a 386 context makes sense (e.g. DOS interrupts, */ /* Win16 register functions), so that this code can be compiled */ /* on all platforms. */ #define SIZE_OF_80387_REGISTERS 80 typedef struct _FLOATING_SAVE_AREA { DWORD ControlWord; DWORD StatusWord; DWORD TagWord; DWORD ErrorOffset; DWORD ErrorSelector; DWORD DataOffset; DWORD DataSelector; BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; DWORD Cr0NpxState; } FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; typedef struct _CONTEXT86 { DWORD ContextFlags; /* These are selected by CONTEXT_DEBUG_REGISTERS */ DWORD Dr0; DWORD Dr1; DWORD Dr2; DWORD Dr3; DWORD Dr6; DWORD Dr7; /* These are selected by CONTEXT_FLOATING_POINT */ FLOATING_SAVE_AREA FloatSave; /* These are selected by CONTEXT_SEGMENTS */ DWORD SegGs; DWORD SegFs; DWORD SegEs; DWORD SegDs; /* These are selected by CONTEXT_INTEGER */ DWORD Edi; DWORD Esi; DWORD Ebx; DWORD Edx; DWORD Ecx; DWORD Eax; /* These are selected by CONTEXT_CONTROL */ DWORD Ebp; DWORD Eip; DWORD SegCs; DWORD EFlags; DWORD Esp; DWORD SegSs; } CONTEXT86; #define CONTEXT_X86 0x00010000 #define CONTEXT_i386 CONTEXT_X86 #define CONTEXT_i486 CONTEXT_X86 #define CONTEXT86_CONTROL (CONTEXT_i386 | 0x0001) /* SS:SP, CS:IP, FLAGS, BP */ #define CONTEXT86_INTEGER (CONTEXT_i386 | 0x0002) /* AX, BX, CX, DX, SI, DI */ #define CONTEXT86_SEGMENTS (CONTEXT_i386 | 0x0004) /* DS, ES, FS, GS */ #define CONTEXT86_FLOATING_POINT (CONTEXT_i386 | 0x0008L) /* 387 state */ #define CONTEXT86_DEBUG_REGISTERS (CONTEXT_i386 | 0x0010L) /* DB 0-3,6,7 */ #define CONTEXT86_FULL (CONTEXT86_CONTROL | CONTEXT86_INTEGER | CONTEXT86_SEGMENTS) /* i386 context definitions */ #ifdef __i386__ #define CONTEXT_CONTROL CONTEXT86_CONTROL #define CONTEXT_INTEGER CONTEXT86_INTEGER #define CONTEXT_SEGMENTS CONTEXT86_SEGMENTS #define CONTEXT_FLOATING_POINT CONTEXT86_FLOATING_POINT #define CONTEXT_DEBUG_REGISTERS CONTEXT86_DEBUG_REGISTERS #define CONTEXT_FULL CONTEXT86_FULL typedef CONTEXT86 CONTEXT; #endif /* __i386__ */ /* Alpha context definitions */ #if defined(_ALPHA_) || defined(__alpha__) #define CONTEXT_ALPHA 0x00020000 #define CONTEXT_CONTROL (CONTEXT_ALPHA | 0x00000001L) #define CONTEXT_FLOATING_POINT (CONTEXT_ALPHA | 0x00000002L) #define CONTEXT_INTEGER (CONTEXT_ALPHA | 0x00000004L) #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) typedef struct _CONTEXT { /* selected by CONTEXT_FLOATING_POINT */ ULONGLONG FltF0; ULONGLONG FltF1; ULONGLONG FltF2; ULONGLONG FltF3; ULONGLONG FltF4; ULONGLONG FltF5; ULONGLONG FltF6; ULONGLONG FltF7; ULONGLONG FltF8; ULONGLONG FltF9; ULONGLONG FltF10; ULONGLONG FltF11; ULONGLONG FltF12; ULONGLONG FltF13; ULONGLONG FltF14; ULONGLONG FltF15; ULONGLONG FltF16; ULONGLONG FltF17; ULONGLONG FltF18; ULONGLONG FltF19; ULONGLONG FltF20; ULONGLONG FltF21; ULONGLONG FltF22; ULONGLONG FltF23; ULONGLONG FltF24; ULONGLONG FltF25; ULONGLONG FltF26; ULONGLONG FltF27; ULONGLONG FltF28; ULONGLONG FltF29; ULONGLONG FltF30; ULONGLONG FltF31; /* selected by CONTEXT_INTEGER */ ULONGLONG IntV0; ULONGLONG IntT0; ULONGLONG IntT1; ULONGLONG IntT2; ULONGLONG IntT3; ULONGLONG IntT4; ULONGLONG IntT5; ULONGLONG IntT6; ULONGLONG IntT7; ULONGLONG IntS0; ULONGLONG IntS1; ULONGLONG IntS2; ULONGLONG IntS3; ULONGLONG IntS4; ULONGLONG IntS5; ULONGLONG IntFp; ULONGLONG IntA0; ULONGLONG IntA1; ULONGLONG IntA2; ULONGLONG IntA3; ULONGLONG IntA4; ULONGLONG IntA5; ULONGLONG IntT8; ULONGLONG IntT9; ULONGLONG IntT10; ULONGLONG IntT11; ULONGLONG IntRa; ULONGLONG IntT12; ULONGLONG IntAt; ULONGLONG IntGp; ULONGLONG IntSp; ULONGLONG IntZero; /* selected by CONTEXT_FLOATING_POINT */ ULONGLONG Fpcr; ULONGLONG SoftFpcr; /* selected by CONTEXT_CONTROL */ ULONGLONG Fir; DWORD Psr; DWORD ContextFlags; DWORD Fill[4]; } CONTEXT; #define _QUAD_PSR_OFFSET HighSoftFpcr #define _QUAD_FLAGS_OFFSET HighFir #endif /* _ALPHA_ */ /* Mips context definitions */ #ifdef _MIPS_ #define CONTEXT_R4000 0x00010000 #define CONTEXT_CONTROL (CONTEXT_R4000 | 0x00000001) #define CONTEXT_FLOATING_POINT (CONTEXT_R4000 | 0x00000002) #define CONTEXT_INTEGER (CONTEXT_R4000 | 0x00000004) #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) typedef struct _CONTEXT { DWORD Argument[4]; /* These are selected by CONTEXT_FLOATING_POINT */ DWORD FltF0; DWORD FltF1; DWORD FltF2; DWORD FltF3; DWORD FltF4; DWORD FltF5; DWORD FltF6; DWORD FltF7; DWORD FltF8; DWORD FltF9; DWORD FltF10; DWORD FltF11; DWORD FltF12; DWORD FltF13; DWORD FltF14; DWORD FltF15; DWORD FltF16; DWORD FltF17; DWORD FltF18; DWORD FltF19; DWORD FltF20; DWORD FltF21; DWORD FltF22; DWORD FltF23; DWORD FltF24; DWORD FltF25; DWORD FltF26; DWORD FltF27; DWORD FltF28; DWORD FltF29; DWORD FltF30; DWORD FltF31; /* These are selected by CONTEXT_INTEGER */ DWORD IntZero; DWORD IntAt; DWORD IntV0; DWORD IntV1; DWORD IntA0; DWORD IntA1; DWORD IntA2; DWORD IntA3; DWORD IntT0; DWORD IntT1; DWORD IntT2; DWORD IntT3; DWORD IntT4; DWORD IntT5; DWORD IntT6; DWORD IntT7; DWORD IntS0; DWORD IntS1; DWORD IntS2; DWORD IntS3; DWORD IntS4; DWORD IntS5; DWORD IntS6; DWORD IntS7; DWORD IntT8; DWORD IntT9; DWORD IntK0; DWORD IntK1; DWORD IntGp; DWORD IntSp; DWORD IntS8; DWORD IntRa; DWORD IntLo; DWORD IntHi; /* These are selected by CONTEXT_FLOATING_POINT */ DWORD Fsr; /* These are selected by CONTEXT_CONTROL */ DWORD Fir; DWORD Psr; DWORD ContextFlags; DWORD Fill[2]; } CONTEXT; #endif /* _MIPS_ */ /* PowerPC context definitions */ #ifdef __PPC__ #define CONTEXT_CONTROL 0x0001 #define CONTEXT_FLOATING_POINT 0x0002 #define CONTEXT_INTEGER 0x0004 #define CONTEXT_DEBUG_REGISTERS 0x0008 #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) typedef struct { /* These are selected by CONTEXT_FLOATING_POINT */ double Fpr0; double Fpr1; double Fpr2; double Fpr3; double Fpr4; double Fpr5; double Fpr6; double Fpr7; double Fpr8; double Fpr9; double Fpr10; double Fpr11; double Fpr12; double Fpr13; double Fpr14; double Fpr15; double Fpr16; double Fpr17; double Fpr18; double Fpr19; double Fpr20; double Fpr21; double Fpr22; double Fpr23; double Fpr24; double Fpr25; double Fpr26; double Fpr27; double Fpr28; double Fpr29; double Fpr30; double Fpr31; double Fpscr; /* These are selected by CONTEXT_INTEGER */ DWORD Gpr0; DWORD Gpr1; DWORD Gpr2; DWORD Gpr3; DWORD Gpr4; DWORD Gpr5; DWORD Gpr6; DWORD Gpr7; DWORD Gpr8; DWORD Gpr9; DWORD Gpr10; DWORD Gpr11; DWORD Gpr12; DWORD Gpr13; DWORD Gpr14; DWORD Gpr15; DWORD Gpr16; DWORD Gpr17; DWORD Gpr18; DWORD Gpr19; DWORD Gpr20; DWORD Gpr21; DWORD Gpr22; DWORD Gpr23; DWORD Gpr24; DWORD Gpr25; DWORD Gpr26; DWORD Gpr27; DWORD Gpr28; DWORD Gpr29; DWORD Gpr30; DWORD Gpr31; DWORD Cr; DWORD Xer; /* These are selected by CONTEXT_CONTROL */ DWORD Msr; DWORD Iar; DWORD Lr; DWORD Ctr; DWORD ContextFlags; DWORD Fill[3]; /* These are selected by CONTEXT_DEBUG_REGISTERS */ DWORD Dr0; DWORD Dr1; DWORD Dr2; DWORD Dr3; DWORD Dr4; DWORD Dr5; DWORD Dr6; DWORD Dr7; } CONTEXT; typedef struct _STACK_FRAME_HEADER { DWORD BackChain; DWORD GlueSaved1; DWORD GlueSaved2; DWORD Reserved1; DWORD Spare1; DWORD Spare2; DWORD Parameter0; DWORD Parameter1; DWORD Parameter2; DWORD Parameter3; DWORD Parameter4; DWORD Parameter5; DWORD Parameter6; DWORD Parameter7; } STACK_FRAME_HEADER,*PSTACK_FRAME_HEADER; #endif /* __PPC__ */ #ifdef __sparc__ /* * FIXME: * * There is no official CONTEXT structure defined for the SPARC * architecture, so I just made one up. * * This structure is valid only for 32-bit SPARC architectures, * not for 64-bit SPARC. * * Note that this structure contains only the 'top-level' registers; * the rest of the register window chain is not visible. * * The layout follows the Solaris 'prgregset_t' structure. * */ #define CONTEXT_SPARC 0x10000000 #define CONTEXT_CONTROL (CONTEXT_SPARC | 0x00000001) #define CONTEXT_FLOATING_POINT (CONTEXT_SPARC | 0x00000002) #define CONTEXT_INTEGER (CONTEXT_SPARC | 0x00000004) #define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER) typedef struct _CONTEXT { DWORD ContextFlags; /* These are selected by CONTEXT_INTEGER */ DWORD g0; DWORD g1; DWORD g2; DWORD g3; DWORD g4; DWORD g5; DWORD g6; DWORD g7; DWORD o0; DWORD o1; DWORD o2; DWORD o3; DWORD o4; DWORD o5; DWORD o6; DWORD o7; DWORD l0; DWORD l1; DWORD l2; DWORD l3; DWORD l4; DWORD l5; DWORD l6; DWORD l7; DWORD i0; DWORD i1; DWORD i2; DWORD i3; DWORD i4; DWORD i5; DWORD i6; DWORD i7; /* These are selected by CONTEXT_CONTROL */ DWORD psr; DWORD pc; DWORD npc; DWORD y; DWORD wim; DWORD tbr; /* FIXME: floating point registers missing */ } CONTEXT; #endif /* __sparc__ */ #if !defined(CONTEXT_FULL) && !defined(RC_INVOKED) #error You need to define a CONTEXT for your CPU #endif typedef CONTEXT *PCONTEXT; typedef HANDLE *PHANDLE; #ifdef __WINE__ /* Macros for easier access to i386 context registers */ #define EAX_reg(context) ((context)->Eax) #define EBX_reg(context) ((context)->Ebx) #define ECX_reg(context) ((context)->Ecx) #define EDX_reg(context) ((context)->Edx) #define ESI_reg(context) ((context)->Esi) #define EDI_reg(context) ((context)->Edi) #define EBP_reg(context) ((context)->Ebp) #define CS_reg(context) ((context)->SegCs) #define DS_reg(context) ((context)->SegDs) #define ES_reg(context) ((context)->SegEs) #define FS_reg(context) ((context)->SegFs) #define GS_reg(context) ((context)->SegGs) #define SS_reg(context) ((context)->SegSs) #define EFL_reg(context) ((context)->EFlags) #define EIP_reg(context) ((context)->Eip) #define ESP_reg(context) ((context)->Esp) #define AX_reg(context) (*(WORD*)&EAX_reg(context)) #define BX_reg(context) (*(WORD*)&EBX_reg(context)) #define CX_reg(context) (*(WORD*)&ECX_reg(context)) #define DX_reg(context) (*(WORD*)&EDX_reg(context)) #define SI_reg(context) (*(WORD*)&ESI_reg(context)) #define DI_reg(context) (*(WORD*)&EDI_reg(context)) #define BP_reg(context) (*(WORD*)&EBP_reg(context)) #define AL_reg(context) (*(BYTE*)&EAX_reg(context)) #define AH_reg(context) (*((BYTE*)&EAX_reg(context)+1)) #define BL_reg(context) (*(BYTE*)&EBX_reg(context)) #define BH_reg(context) (*((BYTE*)&EBX_reg(context)+1)) #define CL_reg(context) (*(BYTE*)&ECX_reg(context)) #define CH_reg(context) (*((BYTE*)&ECX_reg(context)+1)) #define DL_reg(context) (*(BYTE*)&EDX_reg(context)) #define DH_reg(context) (*((BYTE*)&EDX_reg(context)+1)) #define SET_CFLAG(context) (EFL_reg(context) |= 0x0001) #define RESET_CFLAG(context) (EFL_reg(context) &= ~0x0001) #define SET_ZFLAG(context) (EFL_reg(context) |= 0x0040) #define RESET_ZFLAG(context) (EFL_reg(context) &= ~0x0040) #define ISV86(context) (EFL_reg(context) & 0x00020000) #define V86BASE(context) ((context)->Dr7) /* ugly */ /* Macros to retrieve the current context */ #ifdef __i386__ #ifdef NEED_UNDERSCORE_PREFIX # define __ASM_NAME(name) "_" name #else # define __ASM_NAME(name) name #endif #ifdef __GNUC__ # define __ASM_GLOBAL_FUNC(name,code) \ __asm__( ".align 4\n\t" \ ".globl " __ASM_NAME(#name) "\n\t" \ ".type " __ASM_NAME(#name) ",@function\n" \ __ASM_NAME(#name) ":\n\t" \ code ); #else /* __GNUC__ */ # define __ASM_GLOBAL_FUNC(name,code) \ void __asm_dummy_##name(void) { \ asm( ".align 4\n\t" \ ".globl " __ASM_NAME(#name) "\n\t" \ ".type " __ASM_NAME(#name) ",@function\n" \ __ASM_NAME(#name) ":\n\t" \ code ); \ } #endif /* __GNUC__ */ #define _DEFINE_REGS_ENTRYPOINT( name, fn, args ) \ __ASM_GLOBAL_FUNC( name, \ "call " __ASM_NAME("CALL32_Regs") "\n\t" \ ".long " __ASM_NAME(#fn) "\n\t" \ ".byte " #args ", " #args ) #define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \ _DEFINE_REGS_ENTRYPOINT( name, fn, 0 ) #define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \ _DEFINE_REGS_ENTRYPOINT( name, fn, 4 ) #define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \ _DEFINE_REGS_ENTRYPOINT( name, fn, 8 ) #define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \ _DEFINE_REGS_ENTRYPOINT( name, fn, 12 ) #define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \ _DEFINE_REGS_ENTRYPOINT( name, fn, 16 ) #endif /* __i386__ */ #ifdef __sparc__ /* FIXME: use getcontext() to retrieve full context */ #define _GET_CONTEXT \ CONTEXT context; \ do { memset(&context, 0, sizeof(CONTEXT)); \ context.ContextFlags = CONTEXT_CONTROL; \ context.pc = (DWORD)__builtin_return_address(0); \ } while (0) #define DEFINE_REGS_ENTRYPOINT_0( name, fn ) \ void WINAPI name ( void ) \ { _GET_CONTEXT; fn( &context ); } #define DEFINE_REGS_ENTRYPOINT_1( name, fn, t1 ) \ void WINAPI name ( t1 a1 ) \ { _GET_CONTEXT; fn( a1, &context ); } #define DEFINE_REGS_ENTRYPOINT_2( name, fn, t1, t2 ) \ void WINAPI name ( t1 a1, t2 a2 ) \ { _GET_CONTEXT; fn( a1, a2, &context ); } #define DEFINE_REGS_ENTRYPOINT_3( name, fn, t1, t2, t3 ) \ void WINAPI name ( t1 a1, t2 a2, t3 a3 ) \ { _GET_CONTEXT; fn( a1, a2, a3, &context ); } #define DEFINE_REGS_ENTRYPOINT_4( name, fn, t1, t2, t3, t4 ) \ void WINAPI name ( t1 a1, t2 a2, t3 a3, t4 a4 ) \ { _GET_CONTEXT; fn( a1, a2, a3, a4, &context ); } #endif /* __sparc__ */ #ifndef DEFINE_REGS_ENTRYPOINT_0 #error You need to define DEFINE_REGS_ENTRYPOINT macros for your CPU #endif #ifdef __i386__ # define GET_IP(context) ((LPVOID)(context)->Eip) #endif #ifdef __sparc__ # define GET_IP(context) ((LPVOID)(context)->pc) #endif #if !defined(GET_IP) && !defined(RC_INVOKED) # error You must define GET_IP for this CPU #endif #endif /* __WINE__ */ /* * Exception codes */ #define STATUS_SUCCESS 0x00000000 #define STATUS_WAIT_0 0x00000000 #define STATUS_ABANDONED_WAIT_0 0x00000080 #define STATUS_USER_APC 0x000000C0 #define STATUS_TIMEOUT 0x00000102 #define STATUS_PENDING 0x00000103 #define STATUS_GUARD_PAGE_VIOLATION 0x80000001 #define STATUS_DATATYPE_MISALIGNMENT 0x80000002 #define STATUS_BREAKPOINT 0x80000003 #define STATUS_SINGLE_STEP 0x80000004 #define STATUS_BUFFER_OVERFLOW 0x80000005 #define STATUS_NO_MORE_FILES 0x80000006 #define STATUS_WAKE_SYSTEM_DEBUGGER 0x80000007 #define STATUS_HANDLES_CLOSED 0x8000000A #define STATUS_NO_INHERITANCE 0x8000000B #define STATUS_GUID_SUBSTITUTION_MADE 0x8000000C #define STATUS_PARTIAL_COPY 0x8000000D #define STATUS_DEVICE_PAPER_EMPTY 0x8000000E #define STATUS_DEVICE_POWERED_OFF 0x8000000F #define STATUS_DEVICE_OFF_LINE 0x80000010 #define STATUS_DEVICE_BUSY 0x80000011 #define STATUS_NO_MORE_EAS 0x80000012 #define STATUS_INVALID_EA_NAME 0x80000013 #define STATUS_EA_LIST_INCONSISTENT 0x80000014 #define STATUS_INVALID_EA_FLAG 0x80000015 #define STATUS_VERIFY_REQUIRED 0x80000016 #define STATUS_EXTRANEOUS_INFORMATION 0x80000017 #define STATUS_RXACT_COMMIT_NECESSARY 0x80000018 #define STATUS_NO_MORE_ENTRIES 0x8000001A #define STATUS_FILEMARK_DETECTED 0x8000001B #define STATUS_MEDIA_CHANGED 0x8000001C #define STATUS_BUS_RESET 0x8000001D #define STATUS_END_OF_MEDIA 0x8000001E #define STATUS_BEGINNING_OF_MEDIA 0x8000001F #define STATUS_MEDIA_CHECK 0x80000020 #define STATUS_SETMARK_DETECTED 0x80000021 #define STATUS_NO_DATA_DETECTED 0x80000022 #define STATUS_REDIRECTOR_HAS_OPEN_HANDLES 0x80000023 #define STATUS_SERVER_HAS_OPEN_HANDLES 0x80000024 #define STATUS_ALREADY_DISCONNECTED 0x80000025 #define STATUS_LONGJUMP 0x80000026 #define STATUS_UNSUCCESSFUL 0xC0000001 #define STATUS_NOT_IMPLEMENTED 0xC0000002 #define STATUS_INVALID_INFO_CLASS 0xC0000003 #define STATUS_INFO_LENGTH_MISMATCH 0xC0000004 #define STATUS_ACCESS_VIOLATION 0xC0000005 #define STATUS_IN_PAGE_ERROR 0xC0000006 #define STATUS_PAGEFILE_QUOTA 0xC0000007 #define STATUS_INVALID_HANDLE 0xC0000008 #define STATUS_BAD_INITIAL_STACK 0xC0000009 #define STATUS_BAD_INITIAL_PC 0xC000000A #define STATUS_INVALID_CID 0xC000000B #define STATUS_TIMER_NOT_CANCELED 0xC000000C #define STATUS_INVALID_PARAMETER 0xC000000D #define STATUS_NO_SUCH_DEVICE 0xC000000E #define STATUS_NO_SUCH_FILE 0xC000000F #define STATUS_INVALID_DEVICE_REQUEST 0xC0000010 #define STATUS_END_OF_FILE 0xC0000011 #define STATUS_WRONG_VOLUME 0xC0000012 #define STATUS_NO_MEDIA_IN_DEVICE 0xC0000013 #define STATUS_UNRECOGNIZED_MEDIA 0xC0000014 #define STATUS_NONEXISTENT_SECTOR 0xC0000015 #define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016 #define STATUS_NO_MEMORY 0xC0000017 #define STATUS_CONFLICTING_ADDRESSES 0xC0000018 #define STATUS_NOT_MAPPED_VIEW 0xC0000019 #define STATUS_UNABLE_TO_FREE_VM 0xC000001A #define STATUS_UNABLE_TO_DELETE_SECTION 0xC000001B #define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C #define STATUS_ILLEGAL_INSTRUCTION 0xC000001D #define STATUS_INVALID_LOCK_SEQUENCE 0xC000001E #define STATUS_INVALID_VIEW_SIZE 0xC000001F #define STATUS_INVALID_FILE_FOR_SECTION 0xC0000020 #define STATUS_ALREADY_COMMITTED 0xC0000021 #define STATUS_ACCESS_DENIED 0xC0000022 #define STATUS_BUFFER_TOO_SMALL 0xC0000023 #define STATUS_OBJECT_TYPE_MISMATCH 0xC0000024 #define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025 #define STATUS_INVALID_DISPOSITION 0xC0000026 #define STATUS_UNWIND 0xC0000027 #define STATUS_BAD_STACK 0xC0000028 #define STATUS_INVALID_UNWIND_TARGET 0xC0000029 #define STATUS_NOT_LOCKED 0xC000002A #define STATUS_PARITY_ERROR 0xC000002B #define STATUS_UNABLE_TO_DECOMMIT_VM 0xC000002C #define STATUS_NOT_COMMITTED 0xC000002D #define STATUS_INVALID_PORT_ATTRIBUTES 0xC000002E #define STATUS_PORT_MESSAGE_TOO_LONG 0xC000002F #define STATUS_INVALID_PARAMETER_MIX 0xC0000030 #define STATUS_INVALID_QUOTA_LOWER 0xC0000031 #define STATUS_DISK_CORRUPT_ERROR 0xC0000032 #define STATUS_OBJECT_NAME_INVALID 0xC0000033 #define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034 #define STATUS_OBJECT_NAME_COLLISION 0xC0000035 #define STATUS_PORT_DISCONNECTED 0xC0000037 #define STATUS_DEVICE_ALREADY_ATTACHED 0xC0000038 #define STATUS_OBJECT_PATH_INVALID 0xC0000039 #define STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A #define STATUS_PATH_SYNTAX_BAD 0xC000003B #define STATUS_DATA_OVERRUN 0xC000003C #define STATUS_DATA_LATE_ERROR 0xC000003D #define STATUS_DATA_ERROR 0xC000003E #define STATUS_CRC_ERROR 0xC000003F #define STATUS_SECTION_TOO_BIG 0xC0000040 #define STATUS_PORT_CONNECTION_REFUSED 0xC0000041 #define STATUS_INVALID_PORT_HANDLE 0xC0000042 #define STATUS_SHARING_VIOLATION 0xC0000043 #define STATUS_QUOTA_EXCEEDED 0xC0000044 #define STATUS_INVALID_PAGE_PROTECTION 0xC0000045 #define STATUS_MUTANT_NOT_OWNED 0xC0000046 #define STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000047 #define STATUS_PORT_ALREADY_SET 0xC0000048 #define STATUS_SUSPEND_COUNT_EXCEEDED 0xC000004A #define STATUS_LOCK_NOT_GRANTED 0xC0000054 /* FIXME: not sure */ #define STATUS_FILE_LOCK_CONFLICT 0xC0000055 /* FIXME: not sure */ #define STATUS_UNKNOWN_REVISION 0xC0000058 #define STATUS_INVALID_SECURITY_DESCR 0xC0000079 #define STATUS_DISK_FULL 0xC000007F #define STATUS_SECTION_NOT_EXTENDED 0xC0000087 #define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C #define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D #define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E #define STATUS_FLOAT_INEXACT_RESULT 0xC000008F #define STATUS_FLOAT_INVALID_OPERATION 0xC0000090 #define STATUS_FLOAT_OVERFLOW 0xC0000091 #define STATUS_FLOAT_STACK_CHECK 0xC0000092 #define STATUS_FLOAT_UNDERFLOW 0xC0000093 #define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094 #define STATUS_INTEGER_OVERFLOW 0xC0000095 #define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096 #define STATUS_MEDIA_WRITE_PROTECTED 0XC00000A2 #define STATUS_INVALID_PARAMETER_2 0xC00000F0 #define STATUS_STACK_OVERFLOW 0xC00000FD #define STATUS_DIRECTORY_NOT_EMPTY 0xC0000101 #define STATUS_TOO_MANY_OPENED_FILES 0xC000011F #define STATUS_CONTROL_C_EXIT 0xC000013A #define STATUS_PIPE_BROKEN 0xC000014B #define STATUS_NOT_REGISTRY_FILE 0xC000015C #define STATUS_PARTITION_FAILURE 0xC0000172 #define STATUS_INVALID_BLOCK_LENGTH 0xC0000173 #define STATUS_DEVICE_NOT_PARTITIONED 0xC0000174 #define STATUS_UNABLE_TO_LOCK_MEDIA 0xC0000175 #define STATUS_UNABLE_TO_UNLOAD_MEDIA 0xC0000176 #define STATUS_EOM_OVERFLOW 0xC0000177 #define STATUS_NO_MEDIA 0xC0000178 #define STATUS_NO_SUCH_MEMBER 0xC000017A #define STATUS_INVALID_MEMBER 0xC000017B #define STATUS_KEY_DELETED 0xC000017C #define STATUS_NO_LOG_SPACE 0xC000017D #define STATUS_TOO_MANY_SIDS 0xC000017E #define STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC000017F #define STATUS_KEY_HAS_CHILDREN 0xC0000180 #define STATUS_CHILD_MUST_BE_VOLATILE 0xC0000181 #define STATUS_DEVICE_CONFIGURATION_ERROR0xC0000182 #define STATUS_DRIVER_INTERNAL_ERROR 0xC0000183 #define STATUS_INVALID_DEVICE_STATE 0xC0000184 #define STATUS_IO_DEVICE_ERROR 0xC0000185 #define STATUS_DEVICE_PROTOCOL_ERROR 0xC0000186 #define STATUS_BACKUP_CONTROLLER 0xC0000187 #define STATUS_LOG_FILE_FULL 0xC0000188 #define STATUS_TOO_LATE 0xC0000189 #define STATUS_NO_TRUST_LSA_SECRET 0xC000018A #define STATUS_NO_TRUST_SAM_ACCOUNT 0xC000018B #define STATUS_TRUSTED_DOMAIN_FAILURE 0xC000018C #define STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC000018D #define STATUS_EVENTLOG_FILE_CORRUPT 0xC000018E #define STATUS_EVENTLOG_CANT_START 0xC000018F #define STATUS_TRUST_FAILURE 0xC0000190 #define STATUS_MUTANT_LIMIT_EXCEEDED 0xC0000191 #define STATUS_NETLOGON_NOT_STARTED 0xC0000192 #define STATUS_ACCOUNT_EXPIRED 0xC0000193 #define STATUS_POSSIBLE_DEADLOCK 0xC0000194 #define STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000195 #define STATUS_REMOTE_SESSION_LIMIT 0xC0000196 #define STATUS_EVENTLOG_FILE_CHANGED 0xC0000197 #define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000198 #define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000199 #define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC000019A #define STATUS_DOMAIN_TRUST_INCONSISTENT 0xC000019B #define STATUS_FS_DRIVER_REQUIRED 0xC000019C #define STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000204 #define MAXIMUM_WAIT_OBJECTS 64 #define MAXIMUM_SUSPEND_COUNT 127 /* * Return values from the actual exception handlers */ #define ExceptionContinueExecution 0 #define ExceptionContinueSearch 1 #define ExceptionNestedException 2 #define ExceptionCollidedUnwind 3 /* * Return values from filters in except() and from UnhandledExceptionFilter */ #define EXCEPTION_EXECUTE_HANDLER 1 #define EXCEPTION_CONTINUE_SEARCH 0 #define EXCEPTION_CONTINUE_EXECUTION -1 /* * From OS/2 2.0 exception handling * Win32 seems to use the same flags as ExceptionFlags in an EXCEPTION_RECORD */ #define EH_NONCONTINUABLE 0x01 #define EH_UNWINDING 0x02 #define EH_EXIT_UNWIND 0x04 #define EH_STACK_INVALID 0x08 #define EH_NESTED_CALL 0x10 #define EXCEPTION_CONTINUABLE 0 #define EXCEPTION_NONCONTINUABLE EH_NONCONTINUABLE /* * The exception record used by Win32 to give additional information * about exception to exception handlers. */ #define EXCEPTION_MAXIMUM_PARAMETERS 15 typedef struct __EXCEPTION_RECORD { DWORD ExceptionCode; DWORD ExceptionFlags; struct __EXCEPTION_RECORD *ExceptionRecord; LPVOID ExceptionAddress; DWORD NumberParameters; DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; } EXCEPTION_RECORD, *PEXCEPTION_RECORD; /* * The exception pointers structure passed to exception filters * in except() and the UnhandledExceptionFilter(). */ typedef struct _EXCEPTION_POINTERS { PEXCEPTION_RECORD ExceptionRecord; PCONTEXT ContextRecord; } EXCEPTION_POINTERS, *PEXCEPTION_POINTERS; /* * The exception frame, used for registering exception handlers * Win32 cares only about this, but compilers generally emit * larger exception frames for their own use. */ struct __EXCEPTION_FRAME; typedef DWORD (*PEXCEPTION_HANDLER)(PEXCEPTION_RECORD,struct __EXCEPTION_FRAME*, PCONTEXT,struct __EXCEPTION_FRAME **); typedef struct __EXCEPTION_FRAME { struct __EXCEPTION_FRAME *Prev; PEXCEPTION_HANDLER Handler; } EXCEPTION_FRAME, *PEXCEPTION_FRAME; #include "poppack.h" /* * function pointer to a exception filter */ typedef LONG CALLBACK (*PTOP_LEVEL_EXCEPTION_FILTER)(PEXCEPTION_POINTERS ExceptionInfo); typedef PTOP_LEVEL_EXCEPTION_FILTER LPTOP_LEVEL_EXCEPTION_FILTER; DWORD WINAPI UnhandledExceptionFilter( PEXCEPTION_POINTERS epointers ); LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter( LPTOP_LEVEL_EXCEPTION_FILTER filter ); /* status values for ContinueDebugEvent */ #define DBG_CONTINUE 0x00010002 #define DBG_TERMINATE_THREAD 0x40010003 #define DBG_TERMINATE_PROCESS 0x40010004 #define DBG_CONTROL_C 0x40010005 #define DBG_CONTROL_BREAK 0x40010008 #define DBG_EXCEPTION_NOT_HANDLED 0x80010001 typedef struct _NT_TIB { struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; PVOID StackBase; PVOID StackLimit; PVOID SubSystemTib; union { PVOID FiberData; DWORD Version; } DUMMYUNIONNAME; PVOID ArbitraryUserPointer; struct _NT_TIB *Self; } NT_TIB, *PNT_TIB; struct _TEB; /* #if defined(__i386__) && defined(__GNUC__) extern inline struct _TEB * WINAPI NtCurrentTeb(void); extern inline struct _TEB * WINAPI NtCurrentTeb(void) { struct _TEB *teb; __asm__(".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb)); return teb; } #else extern struct _TEB * WINAPI NtCurrentTeb(void); #endif */ /* * File formats definitions */ typedef struct _IMAGE_DOS_HEADER { WORD e_magic; /* 00: MZ Header signature */ WORD e_cblp; /* 02: Bytes on last page of file */ WORD e_cp; /* 04: Pages in file */ WORD e_crlc; /* 06: Relocations */ WORD e_cparhdr; /* 08: Size of header in paragraphs */ WORD e_minalloc; /* 0a: Minimum extra paragraphs needed */ WORD e_maxalloc; /* 0c: Maximum extra paragraphs needed */ WORD e_ss; /* 0e: Initial (relative) SS value */ WORD e_sp; /* 10: Initial SP value */ WORD e_csum; /* 12: Checksum */ WORD e_ip; /* 14: Initial IP value */ WORD e_cs; /* 16: Initial (relative) CS value */ WORD e_lfarlc; /* 18: File address of relocation table */ WORD e_ovno; /* 1a: Overlay number */ WORD e_res[4]; /* 1c: Reserved words */ WORD e_oemid; /* 24: OEM identifier (for e_oeminfo) */ WORD e_oeminfo; /* 26: OEM information; e_oemid specific */ WORD e_res2[10]; /* 28: Reserved words */ DWORD e_lfanew; /* 3c: Offset to extended header */ } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; #define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */ #define IMAGE_OS2_SIGNATURE 0x454E /* NE */ #define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */ #define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */ #define IMAGE_VXD_SIGNATURE 0x454C /* LE */ #define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */ /* * This is the Windows executable (NE) header. * the name IMAGE_OS2_HEADER is misleading, but in the SDK this way. */ typedef struct { WORD ne_magic; /* 00 NE signature 'NE' */ BYTE ne_ver; /* 02 Linker version number */ BYTE ne_rev; /* 03 Linker revision number */ WORD ne_enttab; /* 04 Offset to entry table relative to NE */ WORD ne_cbenttab; /* 06 Length of entry table in bytes */ LONG ne_crc; /* 08 Checksum */ WORD ne_flags; /* 0c Flags about segments in this file */ WORD ne_autodata; /* 0e Automatic data segment number */ WORD ne_heap; /* 10 Initial size of local heap */ WORD ne_stack; /* 12 Initial size of stack */ DWORD ne_csip; /* 14 Initial CS:IP */ DWORD ne_sssp; /* 18 Initial SS:SP */ WORD ne_cseg; /* 1c # of entries in segment table */ WORD ne_cmod; /* 1e # of entries in module reference tab. */ WORD ne_cbnrestab; /* 20 Length of nonresident-name table */ WORD ne_segtab; /* 22 Offset to segment table */ WORD ne_rsrctab; /* 24 Offset to resource table */ WORD ne_restab; /* 26 Offset to resident-name table */ WORD ne_modtab; /* 28 Offset to module reference table */ WORD ne_imptab; /* 2a Offset to imported name table */ DWORD ne_nrestab; /* 2c Offset to nonresident-name table */ WORD ne_cmovent; /* 30 # of movable entry points */ WORD ne_align; /* 32 Logical sector alignment shift count */ WORD ne_cres; /* 34 # of resource segments */ BYTE ne_exetyp; /* 36 Flags indicating target OS */ BYTE ne_flagsothers; /* 37 Additional information flags */ WORD fastload_offset; /* 38 Offset to fast load area (should be ne_pretthunks)*/ WORD fastload_length; /* 3a Length of fast load area (should be ne_psegrefbytes) */ WORD ne_swaparea; /* 3c Reserved by Microsoft */ WORD ne_expver; /* 3e Expected Windows version number */ } IMAGE_OS2_HEADER,*PIMAGE_OS2_HEADER; typedef struct _IMAGE_VXD_HEADER { WORD e32_magic; BYTE e32_border; BYTE e32_worder; DWORD e32_level; WORD e32_cpu; WORD e32_os; DWORD e32_ver; DWORD e32_mflags; DWORD e32_mpages; DWORD e32_startobj; DWORD e32_eip; DWORD e32_stackobj; DWORD e32_esp; DWORD e32_pagesize; DWORD e32_lastpagesize; DWORD e32_fixupsize; DWORD e32_fixupsum; DWORD e32_ldrsize; DWORD e32_ldrsum; DWORD e32_objtab; DWORD e32_objcnt; DWORD e32_objmap; DWORD e32_itermap; DWORD e32_rsrctab; DWORD e32_rsrccnt; DWORD e32_restab; DWORD e32_enttab; DWORD e32_dirtab; DWORD e32_dircnt; DWORD e32_fpagetab; DWORD e32_frectab; DWORD e32_impmod; DWORD e32_impmodcnt; DWORD e32_impproc; DWORD e32_pagesum; DWORD e32_datapage; DWORD e32_preload; DWORD e32_nrestab; DWORD e32_cbnrestab; DWORD e32_nressum; DWORD e32_autodata; DWORD e32_debuginfo; DWORD e32_debuglen; DWORD e32_instpreload; DWORD e32_instdemand; DWORD e32_heapsize; BYTE e32_res3[12]; DWORD e32_winresoff; DWORD e32_winreslen; WORD e32_devid; WORD e32_ddkver; } IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER; /* These defines describe the meanings of the bits in the Characteristics field */ #define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */ #define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 #define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 #define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 #define IMAGE_FILE_16BIT_MACHINE 0x0040 #define IMAGE_FILE_BYTES_REVERSED_LO 0x0080 #define IMAGE_FILE_32BIT_MACHINE 0x0100 #define IMAGE_FILE_DEBUG_STRIPPED 0x0200 #define IMAGE_FILE_SYSTEM 0x1000 #define IMAGE_FILE_DLL 0x2000 #define IMAGE_FILE_BYTES_REVERSED_HI 0x8000 /* These are the settings of the Machine field. */ #define IMAGE_FILE_MACHINE_UNKNOWN 0 #define IMAGE_FILE_MACHINE_I860 0x14d #define IMAGE_FILE_MACHINE_I386 0x14c #define IMAGE_FILE_MACHINE_R3000 0x162 #define IMAGE_FILE_MACHINE_R4000 0x166 #define IMAGE_FILE_MACHINE_R10000 0x168 #define IMAGE_FILE_MACHINE_ALPHA 0x184 #define IMAGE_FILE_MACHINE_POWERPC 0x1F0 #define IMAGE_SIZEOF_FILE_HEADER 20 /* Possible Magic values */ #define IMAGE_NT_OPTIONAL_HDR_MAGIC 0x10b #define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107 /* These are indexes into the DataDirectory array */ #define IMAGE_FILE_EXPORT_DIRECTORY 0 #define IMAGE_FILE_IMPORT_DIRECTORY 1 #define IMAGE_FILE_RESOURCE_DIRECTORY 2 #define IMAGE_FILE_EXCEPTION_DIRECTORY 3 #define IMAGE_FILE_SECURITY_DIRECTORY 4 #define IMAGE_FILE_BASE_RELOCATION_TABLE 5 #define IMAGE_FILE_DEBUG_DIRECTORY 6 #define IMAGE_FILE_DESCRIPTION_STRING 7 #define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */ #define IMAGE_FILE_THREAD_LOCAL_STORAGE 9 #define IMAGE_FILE_CALLBACK_DIRECTORY 10 /* Directory Entries, indices into the DataDirectory array */ #define IMAGE_DIRECTORY_ENTRY_EXPORT 0 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */ #define IMAGE_DIRECTORY_ENTRY_TLS 9 #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 #define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */ #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 /* Subsystem Values */ #define IMAGE_SUBSYSTEM_UNKNOWN 0 #define IMAGE_SUBSYSTEM_NATIVE 1 #define IMAGE_SUBSYSTEM_WINDOWS_GUI 2 /* Windows GUI subsystem */ #define IMAGE_SUBSYSTEM_WINDOWS_CUI 3 /* Windows character subsystem*/ #define IMAGE_SUBSYSTEM_OS2_CUI 5 #define IMAGE_SUBSYSTEM_POSIX_CUI 7 typedef struct _IMAGE_FILE_HEADER { WORD Machine; WORD NumberOfSections; DWORD TimeDateStamp; DWORD PointerToSymbolTable; DWORD NumberOfSymbols; WORD SizeOfOptionalHeader; WORD Characteristics; } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; DWORD Size; } IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; #define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16 typedef struct _IMAGE_OPTIONAL_HEADER { /* Standard fields */ WORD Magic; BYTE MajorLinkerVersion; BYTE MinorLinkerVersion; DWORD SizeOfCode; DWORD SizeOfInitializedData; DWORD SizeOfUninitializedData; DWORD AddressOfEntryPoint; DWORD BaseOfCode; DWORD BaseOfData; /* NT additional fields */ DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Win32VersionValue; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; } IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; typedef struct _IMAGE_NT_HEADERS { DWORD Signature; IMAGE_FILE_HEADER FileHeader; IMAGE_OPTIONAL_HEADER OptionalHeader; } IMAGE_NT_HEADERS, *PIMAGE_NT_HEADERS; #define IMAGE_SIZEOF_SHORT_NAME 8 typedef struct _IMAGE_SECTION_HEADER { BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; union { DWORD PhysicalAddress; DWORD VirtualSize; } Misc; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; #define IMAGE_SIZEOF_SECTION_HEADER 40 #define IMAGE_FIRST_SECTION(ntheader) \ ((PIMAGE_SECTION_HEADER)((LPBYTE)&((PIMAGE_NT_HEADERS)(ntheader))->OptionalHeader + \ ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader)) /* These defines are for the Characteristics bitfield. */ /* #define IMAGE_SCN_TYPE_REG 0x00000000 - Reserved */ /* #define IMAGE_SCN_TYPE_DSECT 0x00000001 - Reserved */ /* #define IMAGE_SCN_TYPE_NOLOAD 0x00000002 - Reserved */ /* #define IMAGE_SCN_TYPE_GROUP 0x00000004 - Reserved */ /* #define IMAGE_SCN_TYPE_NO_PAD 0x00000008 - Reserved */ /* #define IMAGE_SCN_TYPE_COPY 0x00000010 - Reserved */ #define IMAGE_SCN_CNT_CODE 0x00000020 #define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040 #define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080 #define IMAGE_SCN_LNK_OTHER 0x00000100 #define IMAGE_SCN_LNK_INFO 0x00000200 /* #define IMAGE_SCN_TYPE_OVER 0x00000400 - Reserved */ #define IMAGE_SCN_LNK_REMOVE 0x00000800 #define IMAGE_SCN_LNK_COMDAT 0x00001000 /* 0x00002000 - Reserved */ /* #define IMAGE_SCN_MEM_PROTECTED 0x00004000 - Obsolete */ #define IMAGE_SCN_MEM_FARDATA 0x00008000 /* #define IMAGE_SCN_MEM_SYSHEAP 0x00010000 - Obsolete */ #define IMAGE_SCN_MEM_PURGEABLE 0x00020000 #define IMAGE_SCN_MEM_16BIT 0x00020000 #define IMAGE_SCN_MEM_LOCKED 0x00040000 #define IMAGE_SCN_MEM_PRELOAD 0x00080000 #define IMAGE_SCN_ALIGN_1BYTES 0x00100000 #define IMAGE_SCN_ALIGN_2BYTES 0x00200000 #define IMAGE_SCN_ALIGN_4BYTES 0x00300000 #define IMAGE_SCN_ALIGN_8BYTES 0x00400000 #define IMAGE_SCN_ALIGN_16BYTES 0x00500000 /* Default */ #define IMAGE_SCN_ALIGN_32BYTES 0x00600000 #define IMAGE_SCN_ALIGN_64BYTES 0x00700000 /* 0x00800000 - Unused */ #define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000 #define IMAGE_SCN_MEM_DISCARDABLE 0x02000000 #define IMAGE_SCN_MEM_NOT_CACHED 0x04000000 #define IMAGE_SCN_MEM_NOT_PAGED 0x08000000 #define IMAGE_SCN_MEM_SHARED 0x10000000 #define IMAGE_SCN_MEM_EXECUTE 0x20000000 #define IMAGE_SCN_MEM_READ 0x40000000 #define IMAGE_SCN_MEM_WRITE 0x80000000 #include "pshpack2.h" typedef struct _IMAGE_SYMBOL { union { BYTE ShortName[8]; struct { DWORD Short; DWORD Long; } Name; DWORD LongName[2]; } N; DWORD Value; SHORT SectionNumber; WORD Type; BYTE StorageClass; BYTE NumberOfAuxSymbols; } IMAGE_SYMBOL; typedef IMAGE_SYMBOL *PIMAGE_SYMBOL; #define IMAGE_SIZEOF_SYMBOL 18 typedef struct _IMAGE_LINENUMBER { union { DWORD SymbolTableIndex; DWORD VirtualAddress; } Type; WORD Linenumber; } IMAGE_LINENUMBER; typedef IMAGE_LINENUMBER *PIMAGE_LINENUMBER; #define IMAGE_SIZEOF_LINENUMBER 6 typedef union _IMAGE_AUX_SYMBOL { struct { DWORD TagIndex; union { struct { WORD Linenumber; WORD Size; } LnSz; DWORD TotalSize; } Misc; union { struct { DWORD PointerToLinenumber; DWORD PointerToNextFunction; } Function; struct { WORD Dimension[4]; } Array; } FcnAry; WORD TvIndex; } Sym; struct { BYTE Name[IMAGE_SIZEOF_SYMBOL]; } File; struct { DWORD Length; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD CheckSum; SHORT Number; BYTE Selection; } Section; } IMAGE_AUX_SYMBOL; typedef IMAGE_AUX_SYMBOL *PIMAGE_AUX_SYMBOL; #define IMAGE_SIZEOF_AUX_SYMBOL 18 #include "poppack.h" #define IMAGE_SYM_UNDEFINED (SHORT)0 #define IMAGE_SYM_ABSOLUTE (SHORT)-1 #define IMAGE_SYM_DEBUG (SHORT)-2 #define IMAGE_SYM_TYPE_NULL 0x0000 #define IMAGE_SYM_TYPE_VOID 0x0001 #define IMAGE_SYM_TYPE_CHAR 0x0002 #define IMAGE_SYM_TYPE_SHORT 0x0003 #define IMAGE_SYM_TYPE_INT 0x0004 #define IMAGE_SYM_TYPE_LONG 0x0005 #define IMAGE_SYM_TYPE_FLOAT 0x0006 #define IMAGE_SYM_TYPE_DOUBLE 0x0007 #define IMAGE_SYM_TYPE_STRUCT 0x0008 #define IMAGE_SYM_TYPE_UNION 0x0009 #define IMAGE_SYM_TYPE_ENUM 0x000A #define IMAGE_SYM_TYPE_MOE 0x000B #define IMAGE_SYM_TYPE_BYTE 0x000C #define IMAGE_SYM_TYPE_WORD 0x000D #define IMAGE_SYM_TYPE_UINT 0x000E #define IMAGE_SYM_TYPE_DWORD 0x000F #define IMAGE_SYM_TYPE_PCODE 0x8000 #define IMAGE_SYM_DTYPE_NULL 0 #define IMAGE_SYM_DTYPE_POINTER 1 #define IMAGE_SYM_DTYPE_FUNCTION 2 #define IMAGE_SYM_DTYPE_ARRAY 3 #define IMAGE_SYM_CLASS_END_OF_FUNCTION (BYTE )-1 #define IMAGE_SYM_CLASS_NULL 0x0000 #define IMAGE_SYM_CLASS_AUTOMATIC 0x0001 #define IMAGE_SYM_CLASS_EXTERNAL 0x0002 #define IMAGE_SYM_CLASS_STATIC 0x0003 #define IMAGE_SYM_CLASS_REGISTER 0x0004 #define IMAGE_SYM_CLASS_EXTERNAL_DEF 0x0005 #define IMAGE_SYM_CLASS_LABEL 0x0006 #define IMAGE_SYM_CLASS_UNDEFINED_LABEL 0x0007 #define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 0x0008 #define IMAGE_SYM_CLASS_ARGUMENT 0x0009 #define IMAGE_SYM_CLASS_STRUCT_TAG 0x000A #define IMAGE_SYM_CLASS_MEMBER_OF_UNION 0x000B #define IMAGE_SYM_CLASS_UNION_TAG 0x000C #define IMAGE_SYM_CLASS_TYPE_DEFINITION 0x000D #define IMAGE_SYM_CLASS_UNDEFINED_STATIC 0x000E #define IMAGE_SYM_CLASS_ENUM_TAG 0x000F #define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 0x0010 #define IMAGE_SYM_CLASS_REGISTER_PARAM 0x0011 #define IMAGE_SYM_CLASS_BIT_FIELD 0x0012 #define IMAGE_SYM_CLASS_FAR_EXTERNAL 0x0044 #define IMAGE_SYM_CLASS_BLOCK 0x0064 #define IMAGE_SYM_CLASS_FUNCTION 0x0065 #define IMAGE_SYM_CLASS_END_OF_STRUCT 0x0066 #define IMAGE_SYM_CLASS_FILE 0x0067 #define IMAGE_SYM_CLASS_SECTION 0x0068 #define IMAGE_SYM_CLASS_WEAK_EXTERNAL 0x0069 #define N_BTMASK 0x000F #define N_TMASK 0x0030 #define N_TMASK1 0x00C0 #define N_TMASK2 0x00F0 #define N_BTSHFT 4 #define N_TSHIFT 2 #define BTYPE(x) ((x) & N_BTMASK) #ifndef ISPTR #define ISPTR(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_POINTER << N_BTSHFT)) #endif #ifndef ISFCN #define ISFCN(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_FUNCTION << N_BTSHFT)) #endif #ifndef ISARY #define ISARY(x) (((x) & N_TMASK) == (IMAGE_SYM_DTYPE_ARRAY << N_BTSHFT)) #endif #ifndef ISTAG #define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG || (x)==IMAGE_SYM_CLASS_UNION_TAG || (x)==IMAGE_SYM_CLASS_ENUM_TAG) #endif #ifndef INCREF #define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK)) #endif #ifndef DECREF #define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK)) #endif #define IMAGE_COMDAT_SELECT_NODUPLICATES 1 #define IMAGE_COMDAT_SELECT_ANY 2 #define IMAGE_COMDAT_SELECT_SAME_SIZE 3 #define IMAGE_COMDAT_SELECT_EXACT_MATCH 4 #define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5 #define IMAGE_COMDAT_SELECT_LARGEST 6 #define IMAGE_COMDAT_SELECT_NEWEST 7 #define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1 #define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2 #define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3 /* Export module directory */ typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD Base; DWORD NumberOfFunctions; DWORD NumberOfNames; LPDWORD *AddressOfFunctions; LPDWORD *AddressOfNames; LPWORD *AddressOfNameOrdinals; } IMAGE_EXPORT_DIRECTORY,*PIMAGE_EXPORT_DIRECTORY; /* Import name entry */ typedef struct _IMAGE_IMPORT_BY_NAME { WORD Hint; BYTE Name[1]; } IMAGE_IMPORT_BY_NAME,*PIMAGE_IMPORT_BY_NAME; /* Import thunk */ typedef struct _IMAGE_THUNK_DATA { union { LPBYTE ForwarderString; FARPROC Function; DWORD Ordinal; PIMAGE_IMPORT_BY_NAME AddressOfData; } u1; } IMAGE_THUNK_DATA,*PIMAGE_THUNK_DATA; /* Import module directory */ typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; /* 0 for terminating null import descriptor */ PIMAGE_THUNK_DATA OriginalFirstThunk; /* RVA to original unbound IAT */ } u; DWORD TimeDateStamp; /* 0 if not bound, * -1 if bound, and real date\time stamp * in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT * (new BIND) * otherwise date/time stamp of DLL bound to * (Old BIND) */ DWORD ForwarderChain; /* -1 if no forwarders */ DWORD Name; /* RVA to IAT (if bound this IAT has actual addresses) */ PIMAGE_THUNK_DATA FirstThunk; } IMAGE_IMPORT_DESCRIPTOR,*PIMAGE_IMPORT_DESCRIPTOR; #define IMAGE_ORDINAL_FLAG 0x80000000 #define IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG) != 0) #define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff) typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR { DWORD TimeDateStamp; WORD OffsetModuleName; WORD NumberOfModuleForwarderRefs; /* Array of zero or more IMAGE_BOUND_FORWARDER_REF follows */ } IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR; typedef struct _IMAGE_BOUND_FORWARDER_REF { DWORD TimeDateStamp; WORD OffsetModuleName; WORD Reserved; } IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF; typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; WORD TypeOffset[1]; } IMAGE_BASE_RELOCATION,*PIMAGE_BASE_RELOCATION; typedef struct _IMAGE_RELOCATION { union { DWORD VirtualAddress; DWORD RelocCount; } u; DWORD SymbolTableIndex; WORD Type; } IMAGE_RELOCATION; typedef IMAGE_RELOCATION *PIMAGE_RELOCATION; #define IMAGE_SIZEOF_RELOCATION 10 /* generic relocation types */ #define IMAGE_REL_BASED_ABSOLUTE 0 #define IMAGE_REL_BASED_HIGH 1 #define IMAGE_REL_BASED_LOW 2 #define IMAGE_REL_BASED_HIGHLOW 3 #define IMAGE_REL_BASED_HIGHADJ 4 #define IMAGE_REL_BASED_MIPS_JMPADDR 5 #define IMAGE_REL_BASED_SECTION 6 #define IMAGE_REL_BASED_REL 7 #define IMAGE_REL_BASED_MIPS_JMPADDR16 9 #define IMAGE_REL_BASED_IA64_IMM64 9 /* yes, 9 too */ #define IMAGE_REL_BASED_DIR64 10 #define IMAGE_REL_BASED_HIGH3ADJ 11 /* I386 relocation types */ #define IMAGE_REL_I386_ABSOLUTE 0 #define IMAGE_REL_I386_DIR16 1 #define IMAGE_REL_I386_REL16 2 #define IMAGE_REL_I386_DIR32 6 #define IMAGE_REL_I386_DIR32NB 7 #define IMAGE_REL_I386_SEG12 9 #define IMAGE_REL_I386_SECTION 10 #define IMAGE_REL_I386_SECREL 11 #define IMAGE_REL_I386_REL32 20 /* MIPS relocation types */ #define IMAGE_REL_MIPS_ABSOLUTE 0x0000 #define IMAGE_REL_MIPS_REFHALF 0x0001 #define IMAGE_REL_MIPS_REFWORD 0x0002 #define IMAGE_REL_MIPS_JMPADDR 0x0003 #define IMAGE_REL_MIPS_REFHI 0x0004 #define IMAGE_REL_MIPS_REFLO 0x0005 #define IMAGE_REL_MIPS_GPREL 0x0006 #define IMAGE_REL_MIPS_LITERAL 0x0007 #define IMAGE_REL_MIPS_SECTION 0x000A #define IMAGE_REL_MIPS_SECREL 0x000B #define IMAGE_REL_MIPS_SECRELLO 0x000C #define IMAGE_REL_MIPS_SECRELHI 0x000D #define IMAGE_REL_MIPS_JMPADDR16 0x0010 #define IMAGE_REL_MIPS_REFWORDNB 0x0022 #define IMAGE_REL_MIPS_PAIR 0x0025 /* ALPHA relocation types */ #define IMAGE_REL_ALPHA_ABSOLUTE 0x0000 #define IMAGE_REL_ALPHA_REFLONG 0x0001 #define IMAGE_REL_ALPHA_REFQUAD 0x0002 #define IMAGE_REL_ALPHA_GPREL 0x0003 #define IMAGE_REL_ALPHA_LITERAL 0x0004 #define IMAGE_REL_ALPHA_LITUSE 0x0005 #define IMAGE_REL_ALPHA_GPDISP 0x0006 #define IMAGE_REL_ALPHA_BRADDR 0x0007 #define IMAGE_REL_ALPHA_HINT 0x0008 #define IMAGE_REL_ALPHA_INLINE_REFLONG 0x0009 #define IMAGE_REL_ALPHA_REFHI 0x000A #define IMAGE_REL_ALPHA_REFLO 0x000B #define IMAGE_REL_ALPHA_PAIR 0x000C #define IMAGE_REL_ALPHA_MATCH 0x000D #define IMAGE_REL_ALPHA_SECTION 0x000E #define IMAGE_REL_ALPHA_SECREL 0x000F #define IMAGE_REL_ALPHA_REFLONGNB 0x0010 #define IMAGE_REL_ALPHA_SECRELLO 0x0011 #define IMAGE_REL_ALPHA_SECRELHI 0x0012 #define IMAGE_REL_ALPHA_REFQ3 0x0013 #define IMAGE_REL_ALPHA_REFQ2 0x0014 #define IMAGE_REL_ALPHA_REFQ1 0x0015 #define IMAGE_REL_ALPHA_GPRELLO 0x0016 #define IMAGE_REL_ALPHA_GPRELHI 0x0017 /* PowerPC relocation types */ #define IMAGE_REL_PPC_ABSOLUTE 0x0000 #define IMAGE_REL_PPC_ADDR64 0x0001 #define IMAGE_REL_PPC_ADDR 0x0002 #define IMAGE_REL_PPC_ADDR24 0x0003 #define IMAGE_REL_PPC_ADDR16 0x0004 #define IMAGE_REL_PPC_ADDR14 0x0005 #define IMAGE_REL_PPC_REL24 0x0006 #define IMAGE_REL_PPC_REL14 0x0007 #define IMAGE_REL_PPC_TOCREL16 0x0008 #define IMAGE_REL_PPC_TOCREL14 0x0009 #define IMAGE_REL_PPC_ADDR32NB 0x000A #define IMAGE_REL_PPC_SECREL 0x000B #define IMAGE_REL_PPC_SECTION 0x000C #define IMAGE_REL_PPC_IFGLUE 0x000D #define IMAGE_REL_PPC_IMGLUE 0x000E #define IMAGE_REL_PPC_SECREL16 0x000F #define IMAGE_REL_PPC_REFHI 0x0010 #define IMAGE_REL_PPC_REFLO 0x0011 #define IMAGE_REL_PPC_PAIR 0x0012 #define IMAGE_REL_PPC_SECRELLO 0x0013 #define IMAGE_REL_PPC_SECRELHI 0x0014 #define IMAGE_REL_PPC_GPREL 0x0015 #define IMAGE_REL_PPC_TYPEMASK 0x00FF /* modifier bits */ #define IMAGE_REL_PPC_NEG 0x0100 #define IMAGE_REL_PPC_BRTAKEN 0x0200 #define IMAGE_REL_PPC_BRNTAKEN 0x0400 #define IMAGE_REL_PPC_TOCDEFN 0x0800 /* SH3 ? relocation type */ #define IMAGE_REL_SH3_ABSOLUTE 0x0000 #define IMAGE_REL_SH3_DIRECT16 0x0001 #define IMAGE_REL_SH3_DIRECT 0x0002 #define IMAGE_REL_SH3_DIRECT8 0x0003 #define IMAGE_REL_SH3_DIRECT8_WORD 0x0004 #define IMAGE_REL_SH3_DIRECT8_LONG 0x0005 #define IMAGE_REL_SH3_DIRECT4 0x0006 #define IMAGE_REL_SH3_DIRECT4_WORD 0x0007 #define IMAGE_REL_SH3_DIRECT4_LONG 0x0008 #define IMAGE_REL_SH3_PCREL8_WORD 0x0009 #define IMAGE_REL_SH3_PCREL8_LONG 0x000A #define IMAGE_REL_SH3_PCREL12_WORD 0x000B #define IMAGE_REL_SH3_STARTOF_SECTION 0x000C #define IMAGE_REL_SH3_SIZEOF_SECTION 0x000D #define IMAGE_REL_SH3_SECTION 0x000E #define IMAGE_REL_SH3_SECREL 0x000F #define IMAGE_REL_SH3_DIRECT32_NB 0x0010 /* ARM (Archimedes?) relocation types */ #define IMAGE_REL_ARM_ABSOLUTE 0x0000 #define IMAGE_REL_ARM_ADDR 0x0001 #define IMAGE_REL_ARM_ADDR32NB 0x0002 #define IMAGE_REL_ARM_BRANCH24 0x0003 #define IMAGE_REL_ARM_BRANCH11 0x0004 #define IMAGE_REL_ARM_SECTION 0x000E #define IMAGE_REL_ARM_SECREL 0x000F /* IA64 relocation types */ #define IMAGE_REL_IA64_ABSOLUTE 0x0000 #define IMAGE_REL_IA64_IMM14 0x0001 #define IMAGE_REL_IA64_IMM22 0x0002 #define IMAGE_REL_IA64_IMM64 0x0003 #define IMAGE_REL_IA64_DIR 0x0004 #define IMAGE_REL_IA64_DIR64 0x0005 #define IMAGE_REL_IA64_PCREL21B 0x0006 #define IMAGE_REL_IA64_PCREL21M 0x0007 #define IMAGE_REL_IA64_PCREL21F 0x0008 #define IMAGE_REL_IA64_GPREL22 0x0009 #define IMAGE_REL_IA64_LTOFF22 0x000A #define IMAGE_REL_IA64_SECTION 0x000B #define IMAGE_REL_IA64_SECREL22 0x000C #define IMAGE_REL_IA64_SECREL64I 0x000D #define IMAGE_REL_IA64_SECREL 0x000E #define IMAGE_REL_IA64_LTOFF64 0x000F #define IMAGE_REL_IA64_DIR32NB 0x0010 #define IMAGE_REL_IA64_RESERVED_11 0x0011 #define IMAGE_REL_IA64_RESERVED_12 0x0012 #define IMAGE_REL_IA64_RESERVED_13 0x0013 #define IMAGE_REL_IA64_RESERVED_14 0x0014 #define IMAGE_REL_IA64_RESERVED_15 0x0015 #define IMAGE_REL_IA64_RESERVED_16 0x0016 #define IMAGE_REL_IA64_ADDEND 0x001F /* archive format */ #define IMAGE_ARCHIVE_START_SIZE 8 #define IMAGE_ARCHIVE_START "!<arch>\n" #define IMAGE_ARCHIVE_END "`\n" #define IMAGE_ARCHIVE_PAD "\n" #define IMAGE_ARCHIVE_LINKER_MEMBER "/ " #define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// " typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER { BYTE Name[16]; BYTE Date[12]; BYTE UserID[6]; BYTE GroupID[6]; BYTE Mode[8]; BYTE Size[10]; BYTE EndHeader[2]; } IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER; #define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60 /* * Resource directory stuff */ typedef struct _IMAGE_RESOURCE_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries; /* IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[]; */ } IMAGE_RESOURCE_DIRECTORY,*PIMAGE_RESOURCE_DIRECTORY; #define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000 #define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000 typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY { union { struct { unsigned NameOffset:31; unsigned NameIsString:1; } s; DWORD Name; WORD Id; } u1; union { DWORD OffsetToData; struct { unsigned OffsetToDirectory:31; unsigned DataIsDirectory:1; } s; } u2; } IMAGE_RESOURCE_DIRECTORY_ENTRY,*PIMAGE_RESOURCE_DIRECTORY_ENTRY; typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING { WORD Length; CHAR NameString[ 1 ]; } IMAGE_RESOURCE_DIRECTORY_STRING,*PIMAGE_RESOURCE_DIRECTORY_STRING; typedef struct _IMAGE_RESOURCE_DIR_STRING_U { WORD Length; WCHAR NameString[ 1 ]; } IMAGE_RESOURCE_DIR_STRING_U,*PIMAGE_RESOURCE_DIR_STRING_U; typedef struct _IMAGE_RESOURCE_DATA_ENTRY { DWORD OffsetToData; DWORD Size; DWORD CodePage; DWORD ResourceHandle; } IMAGE_RESOURCE_DATA_ENTRY,*PIMAGE_RESOURCE_DATA_ENTRY; typedef VOID CALLBACK (*PIMAGE_TLS_CALLBACK)( LPVOID DllHandle,DWORD Reason,LPVOID Reserved ); typedef struct _IMAGE_TLS_DIRECTORY { DWORD StartAddressOfRawData; DWORD EndAddressOfRawData; LPDWORD AddressOfIndex; PIMAGE_TLS_CALLBACK *AddressOfCallBacks; DWORD SizeOfZeroFill; DWORD Characteristics; } IMAGE_TLS_DIRECTORY,*PIMAGE_TLS_DIRECTORY; typedef struct _IMAGE_DEBUG_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Type; DWORD SizeOfData; DWORD AddressOfRawData; DWORD PointerToRawData; } IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY; #define IMAGE_DEBUG_TYPE_UNKNOWN 0 #define IMAGE_DEBUG_TYPE_COFF 1 #define IMAGE_DEBUG_TYPE_CODEVIEW 2 #define IMAGE_DEBUG_TYPE_FPO 3 #define IMAGE_DEBUG_TYPE_MISC 4 #define IMAGE_DEBUG_TYPE_EXCEPTION 5 #define IMAGE_DEBUG_TYPE_FIXUP 6 #define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7 #define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8 #define IMAGE_DEBUG_TYPE_BORLAND 9 #define IMAGE_DEBUG_TYPE_RESERVED10 10 typedef struct _IMAGE_COFF_SYMBOLS_HEADER { DWORD NumberOfSymbols; DWORD LvaToFirstSymbol; DWORD NumberOfLinenumbers; DWORD LvaToFirstLinenumber; DWORD RvaToFirstByteOfCode; DWORD RvaToLastByteOfCode; DWORD RvaToFirstByteOfData; DWORD RvaToLastByteOfData; } IMAGE_COFF_SYMBOLS_HEADER, *PIMAGE_COFF_SYMBOLS_HEADER; #define FRAME_FPO 0 #define FRAME_TRAP 1 #define FRAME_TSS 2 #define FRAME_NONFPO 3 typedef struct _FPO_DATA { DWORD ulOffStart; DWORD cbProcSize; DWORD cdwLocals; WORD cdwParams; unsigned cbProlog : 8; unsigned cbRegs : 3; unsigned fHasSEH : 1; unsigned fUseBP : 1; unsigned reserved : 1; unsigned cbFrame : 2; } FPO_DATA, *PFPO_DATA; typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD GlobalFlagsClear; DWORD GlobalFlagsSet; DWORD CriticalSectionDefaultTimeout; DWORD DeCommitFreeBlockThreshold; DWORD DeCommitTotalFreeThreshold; PVOID LockPrefixTable; DWORD MaximumAllocationSize; DWORD VirtualMemoryThreshold; DWORD ProcessHeapFlags; DWORD ProcessAffinityMask; WORD CSDVersion; WORD Reserved1; PVOID EditList; DWORD Reserved[1]; } IMAGE_LOAD_CONFIG_DIRECTORY, *PIMAGE_LOAD_CONFIG_DIRECTORY; typedef struct _IMAGE_FUNCTION_ENTRY { DWORD StartingAddress; DWORD EndingAddress; DWORD EndOfPrologue; } IMAGE_FUNCTION_ENTRY, *PIMAGE_FUNCTION_ENTRY; /* This is the structure that appears at the very start of a .DBG file. */ typedef struct _IMAGE_SEPARATE_DEBUG_HEADER { WORD Signature; WORD Flags; WORD Machine; WORD Characteristics; DWORD TimeDateStamp; DWORD CheckSum; DWORD ImageBase; DWORD SizeOfImage; DWORD NumberOfSections; DWORD ExportedNamesSize; DWORD DebugDirectorySize; DWORD SectionAlignment; DWORD Reserved[ 2 ]; } IMAGE_SEPARATE_DEBUG_HEADER,*PIMAGE_SEPARATE_DEBUG_HEADER; #define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944 typedef struct tagMESSAGE_RESOURCE_ENTRY { WORD Length; WORD Flags; BYTE Text[1]; } MESSAGE_RESOURCE_ENTRY,*PMESSAGE_RESOURCE_ENTRY; #define MESSAGE_RESOURCE_UNICODE 0x0001 typedef struct tagMESSAGE_RESOURCE_BLOCK { DWORD LowId; DWORD HighId; DWORD OffsetToEntries; } MESSAGE_RESOURCE_BLOCK,*PMESSAGE_RESOURCE_BLOCK; typedef struct tagMESSAGE_RESOURCE_DATA { DWORD NumberOfBlocks; MESSAGE_RESOURCE_BLOCK Blocks[ 1 ]; } MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA; /* * Here follows typedefs for security and tokens. */ /* * First a constant for the following typdefs. */ #define ANYSIZE_ARRAY 1 /* FIXME: Orphan. What does it point to? */ typedef PVOID PACCESS_TOKEN; /* * TOKEN_INFORMATION_CLASS */ typedef enum _TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics } TOKEN_INFORMATION_CLASS; #ifndef _SECURITY_DEFINED #define _SECURITY_DEFINED #include "pshpack1.h" typedef DWORD ACCESS_MASK, *PACCESS_MASK; typedef struct _GENERIC_MAPPING { ACCESS_MASK GenericRead; ACCESS_MASK GenericWrite; ACCESS_MASK GenericExecute; ACCESS_MASK GenericAll; } GENERIC_MAPPING, *PGENERIC_MAPPING; #ifndef SID_IDENTIFIER_AUTHORITY_DEFINED #define SID_IDENTIFIER_AUTHORITY_DEFINED typedef struct { BYTE Value[6]; } SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY; #endif /* !defined(SID_IDENTIFIER_AUTHORITY_DEFINED) */ #ifndef SID_DEFINED #define SID_DEFINED typedef struct _SID { BYTE Revision; BYTE SubAuthorityCount; SID_IDENTIFIER_AUTHORITY IdentifierAuthority; DWORD SubAuthority[1]; } SID,*PSID; #endif /* !defined(SID_DEFINED) */ #define SID_REVISION (1) /* Current revision */ #define SID_MAX_SUB_AUTHORITIES (15) /* current max subauths */ #define SID_RECOMMENDED_SUB_AUTHORITIES (1) /* recommended subauths */ /* * ACL */ #define ACL_REVISION1 1 #define ACL_REVISION2 2 #define ACL_REVISION3 3 #define ACL_REVISION4 4 #define MIN_ACL_REVISION ACL_REVISION2 #define MAX_ACL_REVISION ACL_REVISION4 typedef struct _ACL { BYTE AclRevision; BYTE Sbz1; WORD AclSize; WORD AceCount; WORD Sbz2; } ACL, *PACL; /* SECURITY_DESCRIPTOR */ #define SECURITY_DESCRIPTOR_REVISION 1 #define SECURITY_DESCRIPTOR_REVISION1 1 #define SE_OWNER_DEFAULTED 0x0001 #define SE_GROUP_DEFAULTED 0x0002 #define SE_DACL_PRESENT 0x0004 #define SE_DACL_DEFAULTED 0x0008 #define SE_SACL_PRESENT 0x0010 #define SE_SACL_DEFAULTED 0x0020 #define SE_SELF_RELATIVE 0x8000 typedef DWORD SECURITY_INFORMATION, *PSECURITY_INFORMATION; typedef WORD SECURITY_DESCRIPTOR_CONTROL, *PSECURITY_DESCRIPTOR_CONTROL; /* The security descriptor structure */ typedef struct { BYTE Revision; BYTE Sbz1; SECURITY_DESCRIPTOR_CONTROL Control; DWORD Owner; DWORD Group; DWORD Sacl; DWORD Dacl; } SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE; typedef struct { BYTE Revision; BYTE Sbz1; SECURITY_DESCRIPTOR_CONTROL Control; PSID Owner; PSID Group; PACL Sacl; PACL Dacl; } SECURITY_DESCRIPTOR, *PSECURITY_DESCRIPTOR; #define SECURITY_DESCRIPTOR_MIN_LENGTH (sizeof(SECURITY_DESCRIPTOR)) #include "poppack.h" #endif /* _SECURITY_DEFINED */ #include "pshpack1.h" /* * SID_AND_ATTRIBUTES */ typedef struct _SID_AND_ATTRIBUTES { PSID Sid; DWORD Attributes; } SID_AND_ATTRIBUTES ; /* security entities */ #define SECURITY_NULL_RID (0x00000000L) #define SECURITY_WORLD_RID (0x00000000L) #define SECURITY_LOCAL_RID (0X00000000L) #define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0} /* S-1-1 */ #define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1} /* S-1-2 */ #define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2} /* S-1-3 */ #define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3} #define SECURITY_CREATOR_OWNER_RID (0x00000000L) #define SECURITY_CREATOR_GROUP_RID (0x00000001L) #define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L) #define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L) /* S-1-4 */ #define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4} /* S-1-5 */ #define SECURITY_NT_AUTHORITY {0,0,0,0,0,5} #define SECURITY_DIALUP_RID 0x00000001L #define SECURITY_NETWORK_RID 0x00000002L #define SECURITY_BATCH_RID 0x00000003L #define SECURITY_INTERACTIVE_RID 0x00000004L #define SECURITY_LOGON_IDS_RID 0x00000005L #define SECURITY_SERVICE_RID 0x00000006L #define SECURITY_ANONYMOUS_LOGON_RID 0x00000007L #define SECURITY_PROXY_RID 0x00000008L #define SECURITY_ENTERPRISE_CONTROLLERS_RID 0x00000009L #define SECURITY_PRINCIPAL_SELF_RID 0x0000000AL #define SECURITY_AUTHENTICATED_USER_RID 0x0000000BL #define SECURITY_RESTRICTED_CODE_RID 0x0000000CL #define SECURITY_TERMINAL_SERVER_RID 0x0000000DL #define SECURITY_LOCAL_SYSTEM_RID 0x00000012L #define SECURITY_NT_NON_UNIQUE 0x00000015L #define SECURITY_BUILTIN_DOMAIN_RID 0x00000020L #define DOMAIN_GROUP_RID_ADMINS 0x00000200L #define DOMAIN_GROUP_RID_USERS 0x00000201L #define DOMAIN_GROUP_RID_GUESTS 0x00000202L #define DOMAIN_ALIAS_RID_ADMINS 0x00000220L #define DOMAIN_ALIAS_RID_USERS 0x00000221L #define DOMAIN_ALIAS_RID_GUESTS 0x00000222L #define SECURITY_SERVER_LOGON_RID SECURITY_ENTERPRISE_CONTROLLERS_RID #define SECURITY_LOGON_IDS_RID_COUNT (3L) /* * TOKEN_USER */ typedef struct _TOKEN_USER { SID_AND_ATTRIBUTES User; } TOKEN_USER; /* * TOKEN_GROUPS */ typedef struct _TOKEN_GROUPS { DWORD GroupCount; SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; } TOKEN_GROUPS; /* * LUID_AND_ATTRIBUTES */ typedef union _LARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; } DUMMYSTRUCTNAME; LONGLONG QuadPart; } LARGE_INTEGER, *LPLARGE_INTEGER, *PLARGE_INTEGER; typedef union _ULARGE_INTEGER { struct { DWORD LowPart; LONG HighPart; } DUMMYSTRUCTNAME; LONGLONG QuadPart; } ULARGE_INTEGER, *LPULARGE_INTEGER, *PULARGE_INTEGER; /* * Locally Unique Identifier */ typedef LARGE_INTEGER LUID,*PLUID; typedef struct _LUID_AND_ATTRIBUTES { LUID Luid; DWORD Attributes; } LUID_AND_ATTRIBUTES; /* * PRIVILEGE_SET */ typedef struct _PRIVILEGE_SET { DWORD PrivilegeCount; DWORD Control; LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY]; } PRIVILEGE_SET, *PPRIVILEGE_SET; /* * TOKEN_PRIVILEGES */ typedef struct _TOKEN_PRIVILEGES { DWORD PrivilegeCount; LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; } TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES; /* * TOKEN_OWNER */ typedef struct _TOKEN_OWNER { PSID Owner; } TOKEN_OWNER; /* * TOKEN_PRIMARY_GROUP */ typedef struct _TOKEN_PRIMARY_GROUP { PSID PrimaryGroup; } TOKEN_PRIMARY_GROUP; /* * TOKEN_DEFAULT_DACL */ typedef struct _TOKEN_DEFAULT_DACL { PACL DefaultDacl; } TOKEN_DEFAULT_DACL; /* * TOKEN_SOURCEL */ typedef struct _TOKEN_SOURCE { char Sourcename[8]; LUID SourceIdentifier; } TOKEN_SOURCE; /* * TOKEN_TYPE */ typedef enum tagTOKEN_TYPE { TokenPrimary = 1, TokenImpersonation } TOKEN_TYPE; /* * SECURITY_IMPERSONATION_LEVEL */ typedef enum _SECURITY_IMPERSONATION_LEVEL { SecurityAnonymous, SecurityIdentification, SecurityImpersonation, SecurityDelegation } SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL; typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE, * PSECURITY_CONTEXT_TRACKING_MODE; /* * Quality of Service */ typedef struct _SECURITY_QUALITY_OF_SERVICE { DWORD Length; SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode; WIN_BOOL EffectiveOnly; } SECURITY_QUALITY_OF_SERVICE, *PSECURITY_QUALITY_OF_SERVICE; /* * TOKEN_STATISTICS */ typedef struct _TOKEN_STATISTICS { LUID TokenId; LUID AuthenticationId; LARGE_INTEGER ExpirationTime; TOKEN_TYPE TokenType; SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; DWORD DynamicCharged; DWORD DynamicAvailable; DWORD GroupCount; DWORD PrivilegeCount; LUID ModifiedId; } TOKEN_STATISTICS; /* * ACLs of NT */ #define ACL_REVISION 2 #define ACL_REVISION1 1 #define ACL_REVISION2 2 /* ACEs, directly starting after an ACL */ typedef struct _ACE_HEADER { BYTE AceType; BYTE AceFlags; WORD AceSize; } ACE_HEADER,*PACE_HEADER; /* AceType */ #define ACCESS_ALLOWED_ACE_TYPE 0 #define ACCESS_DENIED_ACE_TYPE 1 #define SYSTEM_AUDIT_ACE_TYPE 2 #define SYSTEM_ALARM_ACE_TYPE 3 /* inherit AceFlags */ #define OBJECT_INHERIT_ACE 0x01 #define CONTAINER_INHERIT_ACE 0x02 #define NO_PROPAGATE_INHERIT_ACE 0x04 #define INHERIT_ONLY_ACE 0x08 #define VALID_INHERIT_FLAGS 0x0F /* AceFlags mask for what events we (should) audit */ #define SUCCESSFUL_ACCESS_ACE_FLAG 0x40 #define FAILED_ACCESS_ACE_FLAG 0x80 /* different ACEs depending on AceType * SidStart marks the begin of a SID * so the thing finally looks like this: * 0: ACE_HEADER * 4: ACCESS_MASK * 8... : SID */ typedef struct _ACCESS_ALLOWED_ACE { ACE_HEADER Header; DWORD Mask; DWORD SidStart; } ACCESS_ALLOWED_ACE,*PACCESS_ALLOWED_ACE; typedef struct _ACCESS_DENIED_ACE { ACE_HEADER Header; DWORD Mask; DWORD SidStart; } ACCESS_DENIED_ACE,*PACCESS_DENIED_ACE; typedef struct _SYSTEM_AUDIT_ACE { ACE_HEADER Header; DWORD Mask; DWORD SidStart; } SYSTEM_AUDIT_ACE,*PSYSTEM_AUDIT_ACE; typedef struct _SYSTEM_ALARM_ACE { ACE_HEADER Header; DWORD Mask; DWORD SidStart; } SYSTEM_ALARM_ACE,*PSYSTEM_ALARM_ACE; typedef enum tagSID_NAME_USE { SidTypeUser = 1, SidTypeGroup, SidTypeDomain, SidTypeAlias, SidTypeWellKnownGroup, SidTypeDeletedAccount, SidTypeInvalid, SidTypeUnknown } SID_NAME_USE,*PSID_NAME_USE; /* Access rights */ #define DELETE 0x00010000 #define READ_CONTROL 0x00020000 #define WRITE_DAC 0x00040000 #define WRITE_OWNER 0x00080000 #define SYNCHRONIZE 0x00100000 #define STANDARD_RIGHTS_REQUIRED 0x000f0000 #define STANDARD_RIGHTS_READ READ_CONTROL #define STANDARD_RIGHTS_WRITE READ_CONTROL #define STANDARD_RIGHTS_EXECUTE READ_CONTROL #define STANDARD_RIGHTS_ALL 0x001f0000 #define SPECIFIC_RIGHTS_ALL 0x0000ffff #define GENERIC_READ 0x80000000 #define GENERIC_WRITE 0x40000000 #define GENERIC_EXECUTE 0x20000000 #define GENERIC_ALL 0x10000000 #define MAXIMUM_ALLOWED 0x02000000 #define ACCESS_SYSTEM_SECURITY 0x01000000 #define EVENT_MODIFY_STATE 0x0002 #define EVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) #define SEMAPHORE_MODIFY_STATE 0x0002 #define SEMAPHORE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3) #define MUTEX_MODIFY_STATE 0x0001 #define MUTEX_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1) #define PROCESS_TERMINATE 0x0001 #define PROCESS_CREATE_THREAD 0x0002 #define PROCESS_VM_OPERATION 0x0008 #define PROCESS_VM_READ 0x0010 #define PROCESS_VM_WRITE 0x0020 #define PROCESS_DUP_HANDLE 0x0040 #define PROCESS_CREATE_PROCESS 0x0080 #define PROCESS_SET_QUOTA 0x0100 #define PROCESS_SET_INFORMATION 0x0200 #define PROCESS_QUERY_INFORMATION 0x0400 #define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xfff) #define THREAD_TERMINATE 0x0001 #define THREAD_SUSPEND_RESUME 0x0002 #define THREAD_GET_CONTEXT 0x0008 #define THREAD_SET_CONTEXT 0x0010 #define THREAD_SET_INFORMATION 0x0020 #define THREAD_QUERY_INFORMATION 0x0040 #define THREAD_SET_THREAD_TOKEN 0x0080 #define THREAD_IMPERSONATE 0x0100 #define THREAD_DIRECT_IMPERSONATION 0x0200 #define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3ff) #define THREAD_BASE_PRIORITY_LOWRT 15 #define THREAD_BASE_PRIORITY_MAX 2 #define THREAD_BASE_PRIORITY_MIN -2 #define THREAD_BASE_PRIORITY_IDLE -15 #define FILE_READ_DATA 0x0001 /* file & pipe */ #define FILE_LIST_DIRECTORY 0x0001 /* directory */ #define FILE_WRITE_DATA 0x0002 /* file & pipe */ #define FILE_ADD_FILE 0x0002 /* directory */ #define FILE_APPEND_DATA 0x0004 /* file */ #define FILE_ADD_SUBDIRECTORY 0x0004 /* directory */ #define FILE_CREATE_PIPE_INSTANCE 0x0004 /* named pipe */ #define FILE_READ_EA 0x0008 /* file & directory */ #define FILE_READ_PROPERTIES FILE_READ_EA #define FILE_WRITE_EA 0x0010 /* file & directory */ #define FILE_WRITE_PROPERTIES FILE_WRITE_EA #define FILE_EXECUTE 0x0020 /* file */ #define FILE_TRAVERSE 0x0020 /* directory */ #define FILE_DELETE_CHILD 0x0040 /* directory */ #define FILE_READ_ATTRIBUTES 0x0080 /* all */ #define FILE_WRITE_ATTRIBUTES 0x0100 /* all */ #define FILE_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x1ff) #define FILE_GENERIC_READ (STANDARD_RIGHTS_READ | FILE_READ_DATA | \ FILE_READ_ATTRIBUTES | FILE_READ_EA | \ SYNCHRONIZE) #define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | \ FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | \ FILE_APPEND_DATA | SYNCHRONIZE) #define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE | FILE_EXECUTE | \ FILE_READ_ATTRIBUTES | SYNCHRONIZE) /* File attribute flags */ #define FILE_SHARE_READ 0x00000001L #define FILE_SHARE_WRITE 0x00000002L #define FILE_SHARE_DELETE 0x00000004L #define FILE_ATTRIBUTE_READONLY 0x00000001L #define FILE_ATTRIBUTE_HIDDEN 0x00000002L #define FILE_ATTRIBUTE_SYSTEM 0x00000004L #define FILE_ATTRIBUTE_LABEL 0x00000008L /* Not in Windows API */ #define FILE_ATTRIBUTE_DIRECTORY 0x00000010L #define FILE_ATTRIBUTE_ARCHIVE 0x00000020L #define FILE_ATTRIBUTE_NORMAL 0x00000080L #define FILE_ATTRIBUTE_TEMPORARY 0x00000100L #define FILE_ATTRIBUTE_ATOMIC_WRITE 0x00000200L #define FILE_ATTRIBUTE_XACTION_WRITE 0x00000400L #define FILE_ATTRIBUTE_COMPRESSED 0x00000800L #define FILE_ATTRIBUTE_OFFLINE 0x00001000L /* File alignments (NT) */ #define FILE_BYTE_ALIGNMENT 0x00000000 #define FILE_WORD_ALIGNMENT 0x00000001 #define FILE_LONG_ALIGNMENT 0x00000003 #define FILE_QUAD_ALIGNMENT 0x00000007 #define FILE_OCTA_ALIGNMENT 0x0000000f #define FILE_32_BYTE_ALIGNMENT 0x0000001f #define FILE_64_BYTE_ALIGNMENT 0x0000003f #define FILE_128_BYTE_ALIGNMENT 0x0000007f #define FILE_256_BYTE_ALIGNMENT 0x000000ff #define FILE_512_BYTE_ALIGNMENT 0x000001ff #define REG_NONE 0 /* no type */ #define REG_SZ 1 /* string type (ASCII) */ #define REG_EXPAND_SZ 2 /* string, includes %ENVVAR% (expanded by caller) (ASCII) */ #define REG_BINARY 3 /* binary format, callerspecific */ /* YES, REG_DWORD == REG_DWORD_LITTLE_ENDIAN */ #define REG_DWORD 4 /* DWORD in little endian format */ #define REG_DWORD_LITTLE_ENDIAN 4 /* DWORD in little endian format */ #define REG_DWORD_BIG_ENDIAN 5 /* DWORD in big endian format */ #define REG_LINK 6 /* symbolic link (UNICODE) */ #define REG_MULTI_SZ 7 /* multiple strings, delimited by \0, terminated by \0\0 (ASCII) */ #define REG_RESOURCE_LIST 8 /* resource list? huh? */ #define REG_FULL_RESOURCE_DESCRIPTOR 9 /* full resource descriptor? huh? */ #define REG_RESOURCE_REQUIREMENTS_LIST 10 /* ----------------------------- begin registry ----------------------------- */ /* Registry security values */ #define OWNER_SECURITY_INFORMATION 0x00000001 #define GROUP_SECURITY_INFORMATION 0x00000002 #define DACL_SECURITY_INFORMATION 0x00000004 #define SACL_SECURITY_INFORMATION 0x00000008 #define REG_OPTION_RESERVED 0x00000000 #define REG_OPTION_NON_VOLATILE 0x00000000 #define REG_OPTION_VOLATILE 0x00000001 #define REG_OPTION_CREATE_LINK 0x00000002 #define REG_OPTION_BACKUP_RESTORE 0x00000004 /* FIXME */ #define REG_OPTION_OPEN_LINK 0x00000008 #define REG_LEGAL_OPTION (REG_OPTION_RESERVED| \ REG_OPTION_NON_VOLATILE| \ REG_OPTION_VOLATILE| \ REG_OPTION_CREATE_LINK| \ REG_OPTION_BACKUP_RESTORE| \ REG_OPTION_OPEN_LINK) #define REG_CREATED_NEW_KEY 0x00000001 #define REG_OPENED_EXISTING_KEY 0x00000002 /* For RegNotifyChangeKeyValue */ #define REG_NOTIFY_CHANGE_NAME 0x1 #define KEY_QUERY_VALUE 0x00000001 #define KEY_SET_VALUE 0x00000002 #define KEY_CREATE_SUB_KEY 0x00000004 #define KEY_ENUMERATE_SUB_KEYS 0x00000008 #define KEY_NOTIFY 0x00000010 #define KEY_CREATE_LINK 0x00000020 #define KEY_READ ((STANDARD_RIGHTS_READ| \ KEY_QUERY_VALUE| \ KEY_ENUMERATE_SUB_KEYS| \ KEY_NOTIFY) \ & (~SYNCHRONIZE) \ ) #define KEY_WRITE ((STANDARD_RIGHTS_WRITE| \ KEY_SET_VALUE| \ KEY_CREATE_SUB_KEY) \ & (~SYNCHRONIZE) \ ) #define KEY_EXECUTE ((KEY_READ) \ & (~SYNCHRONIZE)) \ ) #define KEY_ALL_ACCESS ((STANDARD_RIGHTS_ALL| \ KEY_QUERY_VALUE| \ KEY_SET_VALUE| \ KEY_CREATE_SUB_KEY| \ KEY_ENUMERATE_SUB_KEYS| \ KEY_NOTIFY| \ KEY_CREATE_LINK) \ & (~SYNCHRONIZE) \ ) /* ------------------------------ end registry ------------------------------ */ #define RtlEqualMemory(Destination, Source, Length) (!memcmp((Destination),(Source),(Length))) #define RtlMoveMemory(Destination, Source, Length) memmove((Destination),(Source),(Length)) #define RtlCopyMemory(Destination, Source, Length) memcpy((Destination),(Source),(Length)) #define RtlFillMemory(Destination, Length, Fill) memset((Destination),(Fill),(Length)) #define RtlZeroMemory(Destination, Length) memset((Destination),0,(Length)) #include "poppack.h" #endif /* __WINE_WINNT_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/pshpack1.h����������������������������������������������������������0000644�0001750�0001750�00000000752�14647725152�016102� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_PSHPACK_H #define __WINE_PSHPACK_H 1 #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__ICC) #pragma pack(1) #elif !defined(RC_INVOKED) #error "1 as alignment isn't supported by the compiler" #endif /* defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ #else /* !defined(__WINE_PSHPACK_H) */ #error "Nested pushing of alignment isn't supported by the compiler" #endif /* !defined(__WINE_PSHPACK_H) */ ����������������������xine-lib-1.2/src/libw32dll/wine/pshpack2.h����������������������������������������������������������0000644�0001750�0001750�00000000722�14647725152�016100� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_PSHPACK_H #define __WINE_PSHPACK_H 2 #if defined(__GNUC__) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) || defined(__ICC) #pragma pack(2) #elif !defined(RC_INVOKED) #error "2 as alignment isn't supported by the compiler" #endif /* defined(__GNUC__) || defined(__SUNPRO_CC) ; !defined(RC_INVOKED) */ #else /* !defined(__WINE_PSHPACK_H) */ #error "Nested pushing of alignment isn't supported by the compiler" #endif /* !defined(__WINE_PSHPACK_H) */ ����������������������������������������������xine-lib-1.2/src/libw32dll/wine/pe_resource.c�������������������������������������������������������0000644�0001750�0001750�00000026077�14647725152�016706� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * PE (Portable Execute) File Resources * * Copyright 1995 Thomas Sandford * Copyright 1996 Martin von Loewis * * Based on the Win16 resource handling code in loader/resource.c * Copyright 1993 Robert J. Amstadt * Copyright 1995 Alexandre Julliard * Copyright 1997 Marcus Meissner */ #include "config.h" #include <stdlib.h> #include <sys/types.h> #include "winestring.h" #include "windef.h" #include "pe_image.h" #include "module.h" #include "heap.h" //#include "task.h" //#include "process.h" //#include "stackframe.h" #include "debugtools.h" #include <ext.h> /********************************************************************** * HMODULE32toPE_MODREF * * small helper function to get a PE_MODREF from a passed HMODULE32 */ static PE_MODREF* HMODULE32toPE_MODREF(HMODULE hmod) { WINE_MODREF *wm; wm = MODULE32_LookupHMODULE( hmod ); if (!wm || wm->type!=MODULE32_PE) return NULL; return &(wm->binfmt.pe); } /********************************************************************** * GetResDirEntryW * * Helper function - goes down one level of PE resource tree * */ PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr, LPCWSTR name,DWORD root, WIN_BOOL allowdefault) { int entrynum; PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable; int namelen; if (HIWORD(name)) { if (name[0]=='#') { char buf[10]; lstrcpynWtoA(buf,name+1,10); buf[9] = '\0'; return GetResDirEntryW(resdirptr,(LPCWSTR)atoi(buf),root,allowdefault); } entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( (BYTE *) resdirptr + sizeof(IMAGE_RESOURCE_DIRECTORY)); namelen = lstrlenW(name); for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++) { PIMAGE_RESOURCE_DIR_STRING_U str = (PIMAGE_RESOURCE_DIR_STRING_U) (root + entryTable[entrynum].u1.s.NameOffset); if(namelen != str->Length) continue; if(wcsnicmp(name,str->NameString,str->Length)==0) return (PIMAGE_RESOURCE_DIRECTORY) ( root + entryTable[entrynum].u2.s.OffsetToDirectory); } return NULL; } else { entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( (BYTE *) resdirptr + sizeof(IMAGE_RESOURCE_DIRECTORY) + resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)); for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++) if ((DWORD)entryTable[entrynum].u1.Name == (DWORD)name) return (PIMAGE_RESOURCE_DIRECTORY) ( root + entryTable[entrynum].u2.s.OffsetToDirectory); /* just use first entry if no default can be found */ if (allowdefault && !name && resdirptr->NumberOfIdEntries) return (PIMAGE_RESOURCE_DIRECTORY) ( root + entryTable[0].u2.s.OffsetToDirectory); return NULL; } } /********************************************************************** * GetResDirEntryA */ PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA( PIMAGE_RESOURCE_DIRECTORY resdirptr, LPCSTR name, DWORD root, WIN_BOOL allowdefault ) { PIMAGE_RESOURCE_DIRECTORY retv; LPWSTR nameW = HIWORD(name)? HEAP_strdupAtoW( GetProcessHeap(), 0, name ) : (LPWSTR)name; retv = GetResDirEntryW( resdirptr, nameW, root, allowdefault ); if ( HIWORD(name) ) HeapFree( GetProcessHeap(), 0, nameW ); return retv; } /********************************************************************** * PE_FindResourceEx32W */ HANDLE PE_FindResourceExW( WINE_MODREF *wm,LPCWSTR name,LPCWSTR type,WORD lang ) { PIMAGE_RESOURCE_DIRECTORY resdirptr; DWORD root; HANDLE result; PE_MODREF *pem = &(wm->binfmt.pe); if (!pem || !pem->pe_resource) return 0; resdirptr = pem->pe_resource; root = (DWORD) resdirptr; if ((resdirptr = GetResDirEntryW(resdirptr, type, root, FALSE)) == NULL) return 0; if ((resdirptr = GetResDirEntryW(resdirptr, name, root, FALSE)) == NULL) return 0; result = (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)(UINT)lang, root, FALSE); /* Try LANG_NEUTRAL, too */ if(!result) return (HANDLE)GetResDirEntryW(resdirptr, (LPCWSTR)0, root, TRUE); return result; } /********************************************************************** * PE_LoadResource32 */ HANDLE PE_LoadResource( WINE_MODREF *wm, HANDLE hRsrc ) { if (!hRsrc || !wm || wm->type!=MODULE32_PE) return 0; return (HANDLE) (wm->module + ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData); } /********************************************************************** * PE_SizeofResource32 */ DWORD PE_SizeofResource( HINSTANCE hModule, HANDLE hRsrc ) { /* we don't need hModule */ (void)hModule; if (!hRsrc) return 0; return ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->Size; } /********************************************************************** * PE_EnumResourceTypes32A */ WIN_BOOL PE_EnumResourceTypesA(HMODULE hmod,ENUMRESTYPEPROCA lpfun,LONG lparam) { PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); int i; PIMAGE_RESOURCE_DIRECTORY resdir; PIMAGE_RESOURCE_DIRECTORY_ENTRY et; WIN_BOOL ret; HANDLE heap = GetProcessHeap(); if (!pem || !pem->pe_resource) return FALSE; resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); ret = FALSE; for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { LPSTR name; if (et[i].u1.s.NameIsString) name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); else name = (LPSTR)(int)et[i].u1.Id; ret = lpfun(hmod,name,lparam); if (HIWORD(name)) HeapFree(heap,0,name); if (!ret) break; } return ret; } /********************************************************************** * PE_EnumResourceTypes32W */ WIN_BOOL PE_EnumResourceTypesW(HMODULE hmod,ENUMRESTYPEPROCW lpfun,LONG lparam) { PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); int i; PIMAGE_RESOURCE_DIRECTORY resdir; PIMAGE_RESOURCE_DIRECTORY_ENTRY et; WIN_BOOL ret; if (!pem || !pem->pe_resource) return FALSE; resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); ret = FALSE; for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { LPWSTR type; if (et[i].u1.s.NameIsString) type = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); else type = (LPWSTR)(int)et[i].u1.Id; ret = lpfun(hmod,type,lparam); if (!ret) break; } return ret; } /********************************************************************** * PE_EnumResourceNames32A */ WIN_BOOL PE_EnumResourceNamesA( HMODULE hmod,LPCSTR type,ENUMRESNAMEPROCA lpfun,LONG lparam ) { PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); int i; PIMAGE_RESOURCE_DIRECTORY resdir; PIMAGE_RESOURCE_DIRECTORY_ENTRY et; WIN_BOOL ret; HANDLE heap = GetProcessHeap(); LPWSTR typeW; if (!pem || !pem->pe_resource) return FALSE; resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; if (HIWORD(type)) typeW = HEAP_strdupAtoW(heap,0,type); else typeW = (LPWSTR)type; resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); if (HIWORD(type)) HeapFree(heap,0,typeW); if (!resdir) return FALSE; et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); ret = FALSE; for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { LPSTR name; if (et[i].u1.s.NameIsString) name = HEAP_strdupWtoA(heap,0,(LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset)); else name = (LPSTR)(int)et[i].u1.Id; ret = lpfun(hmod,type,name,lparam); if (HIWORD(name)) HeapFree(heap,0,name); if (!ret) break; } return ret; } /********************************************************************** * PE_EnumResourceNames32W */ WIN_BOOL PE_EnumResourceNamesW( HMODULE hmod,LPCWSTR type,ENUMRESNAMEPROCW lpfun,LONG lparam ) { PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); int i; PIMAGE_RESOURCE_DIRECTORY resdir; PIMAGE_RESOURCE_DIRECTORY_ENTRY et; WIN_BOOL ret; if (!pem || !pem->pe_resource) return FALSE; resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); if (!resdir) return FALSE; et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); ret = FALSE; for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { LPWSTR name; if (et[i].u1.s.NameIsString) name = (LPWSTR)((LPBYTE)pem->pe_resource+et[i].u1.s.NameOffset); else name = (LPWSTR)(int)et[i].u1.Id; ret = lpfun(hmod,type,name,lparam); if (!ret) break; } return ret; } /********************************************************************** * PE_EnumResourceNames32A */ WIN_BOOL PE_EnumResourceLanguagesA( HMODULE hmod,LPCSTR name,LPCSTR type,ENUMRESLANGPROCA lpfun, LONG lparam ) { PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); int i; PIMAGE_RESOURCE_DIRECTORY resdir; PIMAGE_RESOURCE_DIRECTORY_ENTRY et; WIN_BOOL ret; HANDLE heap = GetProcessHeap(); LPWSTR nameW,typeW; if (!pem || !pem->pe_resource) return FALSE; resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; if (HIWORD(name)) nameW = HEAP_strdupAtoW(heap,0,name); else nameW = (LPWSTR)name; resdir = GetResDirEntryW(resdir,nameW,(DWORD)pem->pe_resource,FALSE); if (HIWORD(nameW)) HeapFree(heap,0,nameW); if (!resdir) return FALSE; if (HIWORD(type)) typeW = HEAP_strdupAtoW(heap,0,type); else typeW = (LPWSTR)type; resdir = GetResDirEntryW(resdir,typeW,(DWORD)pem->pe_resource,FALSE); if (HIWORD(type)) HeapFree(heap,0,typeW); if (!resdir) return FALSE; et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); ret = FALSE; for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { /* languages are just ids... I hopem */ ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); if (!ret) break; } return ret; } /********************************************************************** * PE_EnumResourceLanguages32W */ WIN_BOOL PE_EnumResourceLanguagesW( HMODULE hmod,LPCWSTR name,LPCWSTR type,ENUMRESLANGPROCW lpfun, LONG lparam ) { PE_MODREF *pem = HMODULE32toPE_MODREF(hmod); int i; PIMAGE_RESOURCE_DIRECTORY resdir; PIMAGE_RESOURCE_DIRECTORY_ENTRY et; WIN_BOOL ret; if (!pem || !pem->pe_resource) return FALSE; resdir = (PIMAGE_RESOURCE_DIRECTORY)pem->pe_resource; resdir = GetResDirEntryW(resdir,name,(DWORD)pem->pe_resource,FALSE); if (!resdir) return FALSE; resdir = GetResDirEntryW(resdir,type,(DWORD)pem->pe_resource,FALSE); if (!resdir) return FALSE; et =(PIMAGE_RESOURCE_DIRECTORY_ENTRY)((LPBYTE)resdir+sizeof(IMAGE_RESOURCE_DIRECTORY)); ret = FALSE; for (i=0;i<resdir->NumberOfNamedEntries+resdir->NumberOfIdEntries;i++) { ret = lpfun(hmod,name,type,et[i].u1.Id,lparam); if (!ret) break; } return ret; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/wineacm.h�����������������������������������������������������������0000644�0001750�0001750�00000003553�14647725152�016015� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef WINEACM_H #define WINEACM_H /* -*- tab-width: 8; c-basic-offset: 4 -*- */ /*********************************************************************** * Wine specific - Win32 */ #include "msacmdrv.h" #ifdef __cplusplus extern "C" { #endif /* defined(__cplusplus) */ typedef struct _WINE_ACMDRIVERID *PWINE_ACMDRIVERID; typedef struct _WINE_ACMDRIVER *PWINE_ACMDRIVER; typedef struct _WINE_ACMOBJ { PWINE_ACMDRIVERID pACMDriverID; } WINE_ACMOBJ, *PWINE_ACMOBJ; typedef struct _WINE_ACMDRIVER { WINE_ACMOBJ obj; HDRVR hDrvr; DRIVERPROC pfnDriverProc; PWINE_ACMDRIVER pNextACMDriver; int iUsage; } WINE_ACMDRIVER; typedef struct _WINE_ACMSTREAM { WINE_ACMOBJ obj; PWINE_ACMDRIVER pDrv; ACMDRVSTREAMINSTANCE drvInst; HACMDRIVER hAcmDriver; } WINE_ACMSTREAM, *PWINE_ACMSTREAM; typedef struct _WINE_ACMDRIVERID { LPSTR pszFileName; WORD wFormatTag; HINSTANCE hInstModule; /* NULL if global */ DWORD dwProcessID; /* ID of process which installed a local driver */ WIN_BOOL bEnabled; PWINE_ACMDRIVER pACMDriverList; PWINE_ACMDRIVERID pNextACMDriverID; PWINE_ACMDRIVERID pPrevACMDriverID; } WINE_ACMDRIVERID; /* From internal.c */ extern HANDLE MSACM_hHeap; extern PWINE_ACMDRIVERID MSACM_pFirstACMDriverID; extern PWINE_ACMDRIVERID MSACM_pLastACMDriverID; PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName, WORD wFormatTag, HINSTANCE hinstModule); PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p); void MSACM_UnregisterAllDrivers(void); PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID); PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver); PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj); #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ #endif /* WINEACM_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/winerror.h����������������������������������������������������������0000644�0001750�0001750�00000301223�14647725152�016234� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_WINERROR_H #define __WINE_WINERROR_H extern int WIN32_LastError; #define FACILITY_NULL 0 #define FACILITY_RPC 1 #define FACILITY_DISPATCH 2 #define FACILITY_STORAGE 3 #define FACILITY_ITF 4 #define FACILITY_WIN32 7 #define FACILITY_WINDOWS 8 #define FACILITY_SSPI 9 #define FACILITY_CONTROL 10 #define FACILITY_CERT 11 #define FACILITY_INTERNET 12 #define SEVERITY_ERROR 1 #define MAKE_HRESULT(sev,fac,code) \ ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) #define MAKE_SCODE(sev,fac,code) \ ((SCODE) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) #define SUCCEEDED(stat) ((HRESULT)(stat)>=0) #define FAILED(stat) ((HRESULT)(stat)<0) #define HRESULT_CODE(hr) ((hr) & 0xFFFF) #define SCODE_CODE(sc) ((sc) & 0xFFFF) #define HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1FFF) #define SCODE_FACILITY(sc) (((sc) >> 16) & 0x1FFF) /* ERROR_UNKNOWN is a placeholder for error conditions which haven't * been tested yet so we're not exactly sure what will be returned. * All instances of ERROR_UNKNOWN should be tested under Win95/NT * and replaced. */ #define ERROR_UNKNOWN 99999 #define SEVERITY_SUCCESS 0 #define SEVERITY_ERROR 1 #define NO_ERROR 0 #define ERROR_SUCCESS 0 #define ERROR_INVALID_FUNCTION 1 #define ERROR_FILE_NOT_FOUND 2 #define ERROR_PATH_NOT_FOUND 3 #define ERROR_TOO_MANY_OPEN_FILES 4 #define ERROR_ACCESS_DENIED 5 #define ERROR_INVALID_HANDLE 6 #define ERROR_ARENA_TRASHED 7 #define ERROR_NOT_ENOUGH_MEMORY 8 #define ERROR_INVALID_BLOCK 9 #define ERROR_BAD_ENVIRONMENT 10 #define ERROR_BAD_FORMAT 11 #define ERROR_INVALID_ACCESS 12 #define ERROR_INVALID_DATA 13 #define ERROR_OUTOFMEMORY 14 #define ERROR_INVALID_DRIVE 15 #define ERROR_CURRENT_DIRECTORY 16 #define ERROR_NOT_SAME_DEVICE 17 #define ERROR_NO_MORE_FILES 18 #define ERROR_WRITE_PROTECT 19 #define ERROR_BAD_UNIT 20 #define ERROR_NOT_READY 21 #define ERROR_BAD_COMMAND 22 #define ERROR_CRC 23 #define ERROR_BAD_LENGTH 24 #define ERROR_SEEK 25 #define ERROR_NOT_DOS_DISK 26 #define ERROR_SECTOR_NOT_FOUND 27 #define ERROR_OUT_OF_PAPER 28 #define ERROR_WRITE_FAULT 29 #define ERROR_READ_FAULT 30 #define ERROR_GEN_FAILURE 31 #define ERROR_SHARING_VIOLATION 32 #define ERROR_LOCK_VIOLATION 33 #define ERROR_WRONG_DISK 34 #define ERROR_SHARING_BUFFER_EXCEEDED 36 #define ERROR_HANDLE_EOF 38 #define ERROR_HANDLE_DISK_FULL 39 #define ERROR_NOT_SUPPORTED 50 #define ERROR_REM_NOT_LIST 51 #define ERROR_DUP_NAME 52 #define ERROR_BAD_NETPATH 53 #define ERROR_NETWORK_BUSY 54 #define ERROR_DEV_NOT_EXIST 55 #define ERROR_TOO_MANY_CMDS 56 #define ERROR_ADAP_HDW_ERR 57 #define ERROR_BAD_NET_RESP 58 #define ERROR_UNEXP_NET_ERR 59 #define ERROR_BAD_REM_ADAP 60 #define ERROR_PRINTQ_FULL 61 #define ERROR_NO_SPOOL_SPACE 62 #define ERROR_PRINT_CANCELLED 63 #define ERROR_NETNAME_DELETED 64 #define ERROR_NETWORK_ACCESS_DENIED 65 #define ERROR_BAD_DEV_TYPE 66 #define ERROR_BAD_NET_NAME 67 #define ERROR_TOO_MANY_NAMES 68 #define ERROR_TOO_MANY_SESS 69 #define ERROR_SHARING_PAUSED 70 #define ERROR_REQ_NOT_ACCEP 71 #define ERROR_REDIR_PAUSED 72 #define ERROR_FILE_EXISTS 80 #define ERROR_CANNOT_MAKE 82 #define ERROR_FAIL_I24 83 #define ERROR_OUT_OF_STRUCTURES 84 #define ERROR_ALREADY_ASSIGNED 85 #define ERROR_INVALID_PASSWORD 86 #define ERROR_INVALID_PARAMETER 87 #define ERROR_NET_WRITE_FAULT 88 #define ERROR_NO_PROC_SLOTS 89 #define ERROR_TOO_MANY_SEMAPHORES 100 #define ERROR_EXCL_SEM_ALREADY_OWNED 101 #define ERROR_SEM_IS_SET 102 #define ERROR_TOO_MANY_SEM_REQUESTS 103 #define ERROR_INVALID_AT_INTERRUPT_TIME 104 #define ERROR_SEM_OWNER_DIED 105 #define ERROR_SEM_USER_LIMIT 106 #define ERROR_DISK_CHANGE 107 #define ERROR_DRIVE_LOCKED 108 #define ERROR_BROKEN_PIPE 109 #define ERROR_OPEN_FAILED 110 #define ERROR_BUFFER_OVERFLOW 111 #define ERROR_DISK_FULL 112 #define ERROR_NO_MORE_SEARCH_HANDLES 113 #define ERROR_INVALID_TARGET_HANDLE 114 #define ERROR_INVALID_CATEGORY 117 #define ERROR_INVALID_VERIFY_SWITCH 118 #define ERROR_BAD_DRIVER_LEVEL 119 #define ERROR_CALL_NOT_IMPLEMENTED 120 #define ERROR_SEM_TIMEOUT 121 #define ERROR_INSUFFICIENT_BUFFER 122 #define ERROR_INVALID_NAME 123 #define ERROR_INVALID_LEVEL 124 #define ERROR_NO_VOLUME_LABEL 125 #define ERROR_MOD_NOT_FOUND 126 #define ERROR_PROC_NOT_FOUND 127 #define ERROR_WAIT_NO_CHILDREN 128 #define ERROR_CHILD_NOT_COMPLETE 129 #define ERROR_DIRECT_ACCESS_HANDLE 130 #define ERROR_NEGATIVE_SEEK 131 #define ERROR_SEEK_ON_DEVICE 132 #define ERROR_IS_JOIN_TARGET 133 #define ERROR_IS_JOINED 134 #define ERROR_IS_SUBSTED 135 #define ERROR_NOT_JOINED 136 #define ERROR_NOT_SUBSTED 137 #define ERROR_JOIN_TO_JOIN 138 #define ERROR_SUBST_TO_SUBST 139 #define ERROR_JOIN_TO_SUBST 140 #define ERROR_SUBST_TO_JOIN 141 #define ERROR_BUSY_DRIVE 142 #define ERROR_SAME_DRIVE 143 #define ERROR_DIR_NOT_ROOT 144 #define ERROR_DIR_NOT_EMPTY 145 #define ERROR_IS_SUBST_PATH 146 #define ERROR_IS_JOIN_PATH 147 #define ERROR_PATH_BUSY 148 #define ERROR_IS_SUBST_TARGET 149 #define ERROR_SYSTEM_TRACE 150 #define ERROR_INVALID_EVENT_COUNT 151 #define ERROR_TOO_MANY_MUXWAITERS 152 #define ERROR_INVALID_LIST_FORMAT 153 #define ERROR_LABEL_TOO_LONG 154 #define ERROR_TOO_MANY_TCBS 155 #define ERROR_SIGNAL_REFUSED 156 #define ERROR_DISCARDED 157 #define ERROR_NOT_LOCKED 158 #define ERROR_BAD_THREADID_ADDR 159 #define ERROR_BAD_ARGUMENTS 160 #define ERROR_BAD_PATHNAME 161 #define ERROR_SIGNAL_PENDING 162 #define ERROR_MAX_THRDS_REACHED 164 #define ERROR_LOCK_FAILED 167 #define ERROR_BUSY 170 #define ERROR_CANCEL_VIOLATION 173 #define ERROR_ATOMIC_LOCKS_NOT_SUPPORTED 174 #define ERROR_INVALID_SEGMENT_NUMBER 180 #define ERROR_INVALID_ORDINAL 182 #define ERROR_ALREADY_EXISTS 183 #define ERROR_INVALID_FLAG_NUMBER 186 #define ERROR_SEM_NOT_FOUND 187 #define ERROR_INVALID_STARTING_CODESEG 188 #define ERROR_INVALID_STACKSEG 189 #define ERROR_INVALID_MODULETYPE 190 #define ERROR_INVALID_EXE_SIGNATURE 191 #define ERROR_EXE_MARKED_INVALID 192 #define ERROR_BAD_EXE_FORMAT 193 #define ERROR_ITERATED_DATA_EXCEEDS_64k 194 #define ERROR_INVALID_MINALLOCSIZE 195 #define ERROR_DYNLINK_FROM_INVALID_RING 196 #define ERROR_IOPL_NOT_ENABLED 197 #define ERROR_INVALID_SEGDPL 198 #define ERROR_AUTODATASEG_EXCEEDS_64k 199 #define ERROR_RING2SEG_MUST_BE_MOVABLE 200 #define ERROR_RELOC_CHAIN_XEEDS_SEGLIM 201 #define ERROR_INFLOOP_IN_RELOC_CHAIN 202 #define ERROR_ENVVAR_NOT_FOUND 203 #define ERROR_NO_SIGNAL_SENT 205 #define ERROR_FILENAME_EXCED_RANGE 206 #define ERROR_RING2_STACK_IN_USE 207 #define ERROR_META_EXPANSION_TOO_LONG 208 #define ERROR_INVALID_SIGNAL_NUMBER 209 #define ERROR_THREAD_1_INACTIVE 210 #define ERROR_LOCKED 212 #define ERROR_TOO_MANY_MODULES 214 #define ERROR_NESTING_NOT_ALLOWED 215 #define ERROR_EXE_MACHINE_TYPE_MISMATCH 216 #define ERROR_BAD_PIPE 230 #define ERROR_PIPE_BUSY 231 #define ERROR_NO_DATA 232 #define ERROR_PIPE_NOT_CONNECTED 233 #define ERROR_MORE_DATA 234 #define ERROR_VC_DISCONNECTED 240 #define ERROR_INVALID_EA_NAME 254 #define ERROR_EA_LIST_INCONSISTENT 255 #define ERROR_NO_MORE_ITEMS 259 #define ERROR_CANNOT_COPY 266 #define ERROR_DIRECTORY 267 #define ERROR_EAS_DIDNT_FIT 275 #define ERROR_EA_FILE_CORRUPT 276 #define ERROR_EA_TABLE_FULL 277 #define ERROR_INVALID_EA_HANDLE 278 #define ERROR_EAS_NOT_SUPPORTED 282 #define ERROR_NOT_OWNER 288 #define ERROR_TOO_MANY_POSTS 298 #define ERROR_PARTIAL_COPY 299 #define ERROR_OPLOCK_NOT_GRANTED 300 #define ERROR_INVALID_OPLOCK_PROTOCOL 301 #define ERROR_MR_MID_NOT_FOUND 317 #define ERROR_INVALID_ADDRESS 487 #define ERROR_ARITHMETIC_OVERFLOW 534 #define ERROR_PIPE_CONNECTED 535 #define ERROR_PIPE_LISTENING 536 #define ERROR_EA_ACCESS_DENIED 994 #define ERROR_OPERATION_ABORTED 995 #define ERROR_IO_INCOMPLETE 996 #define ERROR_IO_PENDING 997 #define ERROR_NOACCESS 998 #define ERROR_SWAPERROR 999 #define ERROR_STACK_OVERFLOW 1001 #define ERROR_INVALID_MESSAGE 1002 #define ERROR_CAN_NOT_COMPLETE 1003 #define ERROR_INVALID_FLAGS 1004 #define ERROR_UNRECOGNIZED_VOLUME 1005 #define ERROR_FILE_INVALID 1006 #define ERROR_FULLSCREEN_MODE 1007 #define ERROR_NO_TOKEN 1008 #define ERROR_BADDB 1009 #define ERROR_BADKEY 1010 #define ERROR_CANTOPEN 1011 #define ERROR_CANTREAD 1012 #define ERROR_CANTWRITE 1013 #define ERROR_REGISTRY_RECOVERED 1014 #define ERROR_REGISTRY_CORRUPT 1015 #define ERROR_REGISTRY_IO_FAILED 1016 #define ERROR_NOT_REGISTRY_FILE 1017 #define ERROR_KEY_DELETED 1018 #define ERROR_NO_LOG_SPACE 1019 #define ERROR_KEY_HAS_CHILDREN 1020 #define ERROR_CHILD_MUST_BE_VOLATILE 1021 #define ERROR_NOTIFY_ENUM_DIR 1022 #define ERROR_DEPENDENT_SERVICES_RUNNING 1051 #define ERROR_INVALID_SERVICE_CONTROL 1052 #define ERROR_SERVICE_REQUEST_TIMEOUT 1053 #define ERROR_SERVICE_NO_THREAD 1054 #define ERROR_SERVICE_DATABASE_LOCKED 1055 #define ERROR_SERVICE_ALREADY_RUNNING 1056 #define ERROR_INVALID_SERVICE_ACCOUNT 1057 #define ERROR_SERVICE_DISABLED 1058 #define ERROR_CIRCULAR_DEPENDENCY 1059 #define ERROR_SERVICE_DOES_NOT_EXIST 1060 #define ERROR_SERVICE_CANNOT_ACCEPT_CTRL 1061 #define ERROR_SERVICE_NOT_ACTIVE 1062 #define ERROR_FAILED_SERVICE_CONTROLLER_CONNECT 1063 #define ERROR_EXCEPTION_IN_SERVICE 1064 #define ERROR_DATABASE_DOES_NOT_EXIST 1065 #define ERROR_SERVICE_SPECIFIC_ERROR 1066 #define ERROR_PROCESS_ABORTED 1067 #define ERROR_SERVICE_DEPENDENCY_FAIL 1068 #define ERROR_SERVICE_LOGON_FAILED 1069 #define ERROR_SERVICE_START_HANG 1070 #define ERROR_INVALID_SERVICE_LOCK 1071 #define ERROR_SERVICE_MARKED_FOR_DELETE 1072 #define ERROR_SERVICE_EXISTS 1073 #define ERROR_ALREADY_RUNNING_LKG 1074 #define ERROR_SERVICE_DEPENDENCY_DELETED 1075 #define ERROR_BOOT_ALREADY_ACCEPTED 1076 #define ERROR_SERVICE_NEVER_STARTED 1077 #define ERROR_DUPLICATE_SERVICE_NAME 1078 #define ERROR_DIFFERENT_SERVICE_ACCOUNT 1079 #define ERROR_CANNOT_DETECT_DRIVER_FAILURE 1080 #define ERROR_CANNOT_DETECT_PROCESS_ABORT 1081 #define ERROR_NO_RECOVERY_PROGRAM 1082 #define ERROR_SERVICE_NOT_IN_EXE 1083 #define ERROR_END_OF_MEDIA 1100 #define ERROR_FILEMARK_DETECTED 1101 #define ERROR_BEGINNING_OF_MEDIA 1102 #define ERROR_SETMARK_DETECTED 1103 #define ERROR_NO_DATA_DETECTED 1104 #define ERROR_PARTITION_FAILURE 1105 #define ERROR_INVALID_BLOCK_LENGTH 1106 #define ERROR_DEVICE_NOT_PARTITIONED 1107 #define ERROR_UNABLE_TO_LOCK_MEDIA 1108 #define ERROR_UNABLE_TO_UNLOAD_MEDIA 1109 #define ERROR_MEDIA_CHANGED 1110 #define ERROR_BUS_RESET 1111 #define ERROR_NO_MEDIA_IN_DRIVE 1112 #define ERROR_NO_UNICODE_TRANSLATION 1113 #define ERROR_DLL_INIT_FAILED 1114 #define ERROR_SHUTDOWN_IN_PROGRESS 1115 #define ERROR_NO_SHUTDOWN_IN_PROGRESS 1116 #define ERROR_IO_DEVICE 1117 #define ERROR_SERIAL_NO_DEVICE 1118 #define ERROR_IRQ_BUSY 1119 #define ERROR_MORE_WRITES 1120 #define ERROR_COUNTER_TIMEOUT 1121 #define ERROR_FLOPPY_ID_MARK_NOT_FOUND 1122 #define ERROR_FLOPPY_WRONG_CYLINDER 1123 #define ERROR_FLOPPY_UNKNOWN_ERROR 1124 #define ERROR_FLOPPY_BAD_REGISTERS 1125 #define ERROR_DISK_RECALIBRATE_FAILED 1126 #define ERROR_DISK_OPERATION_FAILED 1127 #define ERROR_DISK_RESET_FAILED 1128 #define ERROR_EOM_OVERFLOW 1129 #define ERROR_NOT_ENOUGH_SERVER_MEMORY 1130 #define ERROR_POSSIBLE_DEADLOCK 1131 #define ERROR_MAPPED_ALIGNMENT 1132 #define ERROR_SET_POWER_STATE_VETOED 1140 #define ERROR_SET_POWER_STATE_FAILED 1141 #define ERROR_TOO_MANY_LINKS 1142 #define ERROR_OLD_WIN_VERSION 1150 #define ERROR_APP_WRONG_OS 1151 #define ERROR_SINGLE_INSTANCE_APP 1152 #define ERROR_RMODE_APP 1153 #define ERROR_INVALID_DLL 1154 #define ERROR_NO_ASSOCIATION 1155 #define ERROR_DDE_FAIL 1156 #define ERROR_DLL_NOT_FOUND 1157 #define ERROR_NO_MORE_USER_HANDLES 1158 #define ERROR_MESSAGE_SYNC_ONLY 1159 #define ERROR_SOURCE_ELEMENT_EMPTY 1160 #define ERROR_DESTINATION_ELEMENT_FULL 1161 #define ERROR_ILLEGAL_ELEMENT_ADDRESS 1162 #define ERROR_MAGAZINE_NOT_PRESENT 1163 #define ERROR_DEVICE_REINITIALIZATION_NEEDED 1164 #define ERROR_DEVICE_REQUIRES_CLEANING 1165 #define ERROR_DEVICE_DOOR_OPEN 1166 #define ERROR_DEVICE_NOT_CONNECTED 1167 #define ERROR_NOT_FOUND 1168 #define ERROR_NO_MATCH 1169 #define ERROR_SET_NOT_FOUND 1170 #define ERROR_POINT_NOT_FOUND 1171 #define ERROR_NO_TRACKING_SERVICE 1172 #define ERROR_NO_VOLUME_ID 1173 #define ERROR_UNABLE_TO_REMOVE_REPLACED 1175 #define ERROR_UNABLE_TO_MOVE_REPLACEMENT 1176 #define ERROR_UNABLE_TO_MOVE_REPLACEMENT_2 1177 #define ERROR_JOURNAL_DELETE_IN_PROGRESS 1178 #define ERROR_JOURNAL_NOT_ACTIVE 1179 #define ERROR_POTENTIAL_FILE_FOUND 1180 #define ERROR_JOURNAL_ENTRY_DELETED 1181 #define ERROR_BAD_DEVICE 1200 #define ERROR_CONNECTION_UNAVAIL 1201 #define ERROR_DEVICE_ALREADY_REMEMBERED 1202 #define ERROR_NO_NET_OR_BAD_PATH 1203 #define ERROR_BAD_PROVIDER 1204 #define ERROR_CANNOT_OPEN_PROFILE 1205 #define ERROR_BAD_PROFILE 1206 #define ERROR_NOT_CONTAINER 1207 #define ERROR_EXTENDED_ERROR 1208 #define ERROR_INVALID_GROUPNAME 1209 #define ERROR_INVALID_COMPUTERNAME 1210 #define ERROR_INVALID_EVENTNAME 1211 #define ERROR_INVALID_DOMAINNAME 1212 #define ERROR_INVALID_SERVICENAME 1213 #define ERROR_INVALID_NETNAME 1214 #define ERROR_INVALID_SHARENAME 1215 #define ERROR_INVALID_PASSWORDNAME 1216 #define ERROR_INVALID_MESSAGENAME 1217 #define ERROR_INVALID_MESSAGEDEST 1218 #define ERROR_SESSION_CREDENTIAL_CONFLICT 1219 #define ERROR_REMOTE_SESSION_LIMIT_EXCEEDED 1220 #define ERROR_DUP_DOMAINNAME 1221 #define ERROR_NO_NETWORK 1222 #define ERROR_CANCELLED 1223 #define ERROR_USER_MAPPED_FILE 1224 #define ERROR_CONNECTION_REFUSED 1225 #define ERROR_GRACEFUL_DISCONNECT 1226 #define ERROR_ADDRESS_ALREADY_ASSOCIATED 1227 #define ERROR_ADDRESS_NOT_ASSOCIATED 1228 #define ERROR_CONNECTION_INVALID 1229 #define ERROR_CONNECTION_ACTIVE 1230 #define ERROR_NETWORK_UNREACHABLE 1231 #define ERROR_HOST_UNREACHABLE 1232 #define ERROR_PROTOCOL_UNREACHABLE 1233 #define ERROR_PORT_UNREACHABLE 1234 #define ERROR_REQUEST_ABORTED 1235 #define ERROR_CONNECTION_ABORTED 1236 #define ERROR_RETRY 1237 #define ERROR_CONNECTION_COUNT_LIMIT 1238 #define ERROR_LOGIN_TIME_RESTRICTION 1239 #define ERROR_LOGIN_WKSTA_RESTRICTION 1240 #define ERROR_INCORRECT_ADDRESS 1241 #define ERROR_ALREADY_REGISTERED 1242 #define ERROR_SERVICE_NOT_FOUND 1243 #define ERROR_NOT_AUTHENTICATED 1244 #define ERROR_NOT_LOGGED_ON 1245 #define ERROR_CONTINUE 1246 #define ERROR_ALREADY_INITIALIZED 1247 #define ERROR_NO_MORE_DEVICES 1248 #define ERROR_NO_SUCH_SITE 1249 #define ERROR_DOMAIN_CONTROLLER_EXISTS 1250 #define ERROR_ONLY_IF_CONNECTED 1251 #define ERROR_OVERRIDE_NOCHANGES 1252 #define ERROR_BAD_USER_PROFILE 1253 #define ERROR_NOT_SUPPORTED_ON_SBS 1254 #define ERROR_NOT_ALL_ASSIGNED 1300 #define ERROR_SOME_NOT_MAPPED 1301 #define ERROR_NO_QUOTAS_FOR_ACCOUNT 1302 #define ERROR_LOCAL_USER_SESSION_KEY 1303 #define ERROR_NULL_LM_PASSWORD 1304 #define ERROR_UNKNOWN_REVISION 1305 #define ERROR_REVISION_MISMATCH 1306 #define ERROR_INVALID_OWNER 1307 #define ERROR_INVALID_PRIMARY_GROUP 1308 #define ERROR_NO_IMPERSONATION_TOKEN 1309 #define ERROR_CANT_DISABLE_MANDATORY 1310 #define ERROR_NO_LOGON_SERVERS 1311 #define ERROR_NO_SUCH_LOGON_SESSION 1312 #define ERROR_NO_SUCH_PRIVILEGE 1313 #define ERROR_PRIVILEGE_NOT_HELD 1314 #define ERROR_INVALID_ACCOUNT_NAME 1315 #define ERROR_USER_EXISTS 1316 #define ERROR_NO_SUCH_USER 1317 #define ERROR_GROUP_EXISTS 1318 #define ERROR_NO_SUCH_GROUP 1319 #define ERROR_MEMBER_IN_GROUP 1320 #define ERROR_MEMBER_NOT_IN_GROUP 1321 #define ERROR_LAST_ADMIN 1322 #define ERROR_WRONG_PASSWORD 1323 #define ERROR_ILL_FORMED_PASSWORD 1324 #define ERROR_PASSWORD_RESTRICTION 1325 #define ERROR_LOGON_FAILURE 1326 #define ERROR_ACCOUNT_RESTRICTION 1327 #define ERROR_INVALID_LOGON_HOURS 1328 #define ERROR_INVALID_WORKSTATION 1329 #define ERROR_PASSWORD_EXPIRED 1330 #define ERROR_ACCOUNT_DISABLED 1331 #define ERROR_NONE_MAPPED 1332 #define ERROR_TOO_MANY_LUIDS_REQUESTED 1333 #define ERROR_LUIDS_EXHAUSTED 1334 #define ERROR_INVALID_SUB_AUTHORITY 1335 #define ERROR_INVALID_ACL 1336 #define ERROR_INVALID_SID 1337 #define ERROR_INVALID_SECURITY_DESCR 1338 #define ERROR_BAD_INHERITANCE_ACL 1340 #define ERROR_SERVER_DISABLED 1341 #define ERROR_SERVER_NOT_DISABLED 1342 #define ERROR_INVALID_ID_AUTHORITY 1343 #define ERROR_ALLOTTED_SPACE_EXCEEDED 1344 #define ERROR_INVALID_GROUP_ATTRIBUTES 1345 #define ERROR_BAD_IMPERSONATION_LEVEL 1346 #define ERROR_CANT_OPEN_ANONYMOUS 1347 #define ERROR_BAD_VALIDATION_CLASS 1348 #define ERROR_BAD_TOKEN_TYPE 1349 #define ERROR_NO_SECURITY_ON_OBJECT 1350 #define ERROR_CANT_ACCESS_DOMAIN_INFO 1351 #define ERROR_INVALID_SERVER_STATE 1352 #define ERROR_INVALID_DOMAIN_STATE 1353 #define ERROR_INVALID_DOMAIN_ROLE 1354 #define ERROR_NO_SUCH_DOMAIN 1355 #define ERROR_DOMAIN_EXISTS 1356 #define ERROR_DOMAIN_LIMIT_EXCEEDED 1357 #define ERROR_INTERNAL_DB_CORRUPTION 1358 #define ERROR_INTERNAL_ERROR 1359 #define ERROR_GENERIC_NOT_MAPPED 1360 #define ERROR_BAD_DESCRIPTOR_FORMAT 1361 #define ERROR_NOT_LOGON_PROCESS 1362 #define ERROR_LOGON_SESSION_EXISTS 1363 #define ERROR_NO_SUCH_PACKAGE 1364 #define ERROR_BAD_LOGON_SESSION_STATE 1365 #define ERROR_LOGON_SESSION_COLLISION 1366 #define ERROR_INVALID_LOGON_TYPE 1367 #define ERROR_CANNOT_IMPERSONATE 1368 #define ERROR_RXACT_INVALID_STATE 1369 #define ERROR_RXACT_COMMIT_FAILURE 1370 #define ERROR_SPECIAL_ACCOUNT 1371 #define ERROR_SPECIAL_GROUP 1372 #define ERROR_SPECIAL_USER 1373 #define ERROR_MEMBERS_PRIMARY_GROUP 1374 #define ERROR_TOKEN_ALREADY_IN_USE 1375 #define ERROR_NO_SUCH_ALIAS 1376 #define ERROR_MEMBER_NOT_IN_ALIAS 1377 #define ERROR_MEMBER_IN_ALIAS 1378 #define ERROR_ALIAS_EXISTS 1379 #define ERROR_LOGON_NOT_GRANTED 1380 #define ERROR_TOO_MANY_SECRETS 1381 #define ERROR_SECRET_TOO_LONG 1382 #define ERROR_INTERNAL_DB_ERROR 1383 #define ERROR_TOO_MANY_CONTEXT_IDS 1384 #define ERROR_LOGON_TYPE_NOT_GRANTED 1385 #define ERROR_NT_CROSS_ENCRYPTION_REQUIRED 1386 #define ERROR_NO_SUCH_MEMBER 1387 #define ERROR_INVALID_MEMBER 1388 #define ERROR_TOO_MANY_SIDS 1389 #define ERROR_LM_CROSS_ENCRYPTION_REQUIRED 1390 #define ERROR_NO_INHERITANCE 1391 #define ERROR_FILE_CORRUPT 1392 #define ERROR_DISK_CORRUPT 1393 #define ERROR_NO_USER_SESSION_KEY 1394 #define ERROR_LICENSE_QUOTA_EXCEEDED 1395 #define ERROR_WRONG_TARGET_NAME 1396 #define ERROR_MUTUAL_AUTH_FAILED 1397 #define ERROR_TIME_SKEW 1398 #define ERROR_INVALID_WINDOW_HANDLE 1400 #define ERROR_INVALID_MENU_HANDLE 1401 #define ERROR_INVALID_CURSOR_HANDLE 1402 #define ERROR_INVALID_ACCEL_HANDLE 1403 #define ERROR_INVALID_HOOK_HANDLE 1404 #define ERROR_INVALID_DWP_HANDLE 1405 #define ERROR_TLW_WITH_WSCHILD 1406 #define ERROR_CANNOT_FIND_WND_CLASS 1407 #define ERROR_WINDOW_OF_OTHER_THREAD 1408 #define ERROR_HOTKEY_ALREADY_REGISTERED 1409 #define ERROR_CLASS_ALREADY_EXISTS 1410 #define ERROR_CLASS_DOES_NOT_EXIST 1411 #define ERROR_CLASS_HAS_WINDOWS 1412 #define ERROR_INVALID_INDEX 1413 #define ERROR_INVALID_ICON_HANDLE 1414 #define ERROR_PRIVATE_DIALOG_INDEX 1415 #define ERROR_LISTBOX_ID_NOT_FOUND 1416 #define ERROR_NO_WILDCARD_CHARACTERS 1417 #define ERROR_CLIPBOARD_NOT_OPEN 1418 #define ERROR_HOTKEY_NOT_REGISTERED 1419 #define ERROR_WINDOW_NOT_DIALOG 1420 #define ERROR_CONTROL_ID_NOT_FOUND 1421 #define ERROR_INVALID_COMBOBOX_MESSAGE 1422 #define ERROR_WINDOW_NOT_COMBOBOX 1423 #define ERROR_INVALID_EDIT_HEIGHT 1424 #define ERROR_DC_NOT_FOUND 1425 #define ERROR_INVALID_HOOK_FILTER 1426 #define ERROR_INVALID_FILTER_PROC 1427 #define ERROR_HOOK_NEEDS_HMOD 1428 #define ERROR_GLOBAL_ONLY_HOOK 1429 #define ERROR_JOURNAL_HOOK_SET 1430 #define ERROR_HOOK_NOT_INSTALLED 1431 #define ERROR_INVALID_LB_MESSAGE 1432 #define ERROR_SETCOUNT_ON_BAD_LB 1433 #define ERROR_LB_WITHOUT_TABSTOPS 1434 #define ERROR_DESTROY_OBJECT_OF_OTHER_THREAD 1435 #define ERROR_CHILD_WINDOW_MENU 1436 #define ERROR_NO_SYSTEM_MENU 1437 #define ERROR_INVALID_MSGBOX_STYLE 1438 #define ERROR_INVALID_SPI_VALUE 1439 #define ERROR_SCREEN_ALREADY_LOCKED 1440 #define ERROR_HWNDS_HAVE_DIFF_PARENT 1441 #define ERROR_NOT_CHILD_WINDOW 1442 #define ERROR_INVALID_GW_COMMAND 1443 #define ERROR_INVALID_THREAD_ID 1444 #define ERROR_NON_MDICHILD_WINDOW 1445 #define ERROR_POPUP_ALREADY_ACTIVE 1446 #define ERROR_NO_SCROLLBARS 1447 #define ERROR_INVALID_SCROLLBAR_RANGE 1448 #define ERROR_INVALID_SHOWWIN_COMMAND 1449 #define ERROR_NO_SYSTEM_RESOURCES 1450 #define ERROR_NONPAGED_SYSTEM_RESOURCES 1451 #define ERROR_PAGED_SYSTEM_RESOURCES 1452 #define ERROR_WORKING_SET_QUOTA 1453 #define ERROR_PAGEFILE_QUOTA 1454 #define ERROR_COMMITMENT_LIMIT 1455 #define ERROR_MENU_ITEM_NOT_FOUND 1456 #define ERROR_INVALID_KEYBOARD_HANDLE 1457 #define ERROR_HOOK_TYPE_NOT_ALLOWED 1458 #define ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION 1459 #define ERROR_TIMEOUT 1460 #define ERROR_INVALID_MONITOR_HANDLE 1461 #define ERROR_EVENTLOG_FILE_CORRUPT 1500 #define ERROR_EVENTLOG_CANT_START 1501 #define ERROR_LOG_FILE_FULL 1502 #define ERROR_EVENTLOG_FILE_CHANGED 1503 #define ERROR_INSTALL_SERVICE_FAILURE 1601 #define ERROR_INSTALL_USEREXIT 1602 #define ERROR_INSTALL_FAILURE 1603 #define ERROR_INSTALL_SUSPEND 1604 #define ERROR_UNKNOWN_PRODUCT 1605 #define ERROR_UNKNOWN_FEATURE 1606 #define ERROR_UNKNOWN_COMPONENT 1607 #define ERROR_UNKNOWN_PROPERTY 1608 #define ERROR_INVALID_HANDLE_STATE 1609 #define ERROR_BAD_CONFIGURATION 1610 #define ERROR_INDEX_ABSENT 1611 #define ERROR_INSTALL_SOURCE_ABSENT 1612 #define ERROR_INSTALL_PACKAGE_VERSION 1613 #define ERROR_PRODUCT_UNINSTALLED 1614 #define ERROR_BAD_QUERY_SYNTAX 1615 #define ERROR_INVALID_FIELD 1616 #define ERROR_DEVICE_REMOVED 1617 #define ERROR_INSTALL_ALREADY_RUNNING 1618 #define ERROR_INSTALL_PACKAGE_OPEN_FAILED 1619 #define ERROR_INSTALL_PACKAGE_INVALID 1620 #define ERROR_INSTALL_UI_FAILURE 1621 #define ERROR_INSTALL_LOG_FAILURE 1622 #define ERROR_INSTALL_LANGUAGE_UNSUPPORTED 1623 #define ERROR_INSTALL_TRANSFORM_FAILURE 1624 #define ERROR_INSTALL_PACKAGE_REJECTED 1625 #define ERROR_FUNCTION_NOT_CALLED 1626 #define ERROR_FUNCTION_FAILED 1627 #define ERROR_INVALID_TABLE 1628 #define ERROR_DATATYPE_MISMATCH 1629 #define ERROR_UNSUPPORTED_TYPE 1630 #define ERROR_CREATE_FAILED 1631 #define ERROR_INSTALL_TEMP_UNWRITABLE 1632 #define ERROR_INSTALL_PLATFORM_UNSUPPORTED 1633 #define ERROR_INSTALL_NOTUSED 1634 #define ERROR_PATCH_PACKAGE_OPEN_FAILED 1635 #define ERROR_PATCH_PACKAGE_INVALID 1636 #define ERROR_PATCH_PACKAGE_UNSUPPORTED 1637 #define ERROR_PRODUCT_VERSION 1638 #define ERROR_INVALID_COMMAND_LINE 1639 #define ERROR_INSTALL_REMOTE_DISALLOWED 1640 #define ERROR_SUCCESS_REBOOT_INITIATED 1641 #define RPC_S_INVALID_STRING_BINDING 1700 #define RPC_S_WRONG_KIND_OF_BINDING 1701 #define RPC_S_INVALID_BINDING 1702 #define RPC_S_PROTSEQ_NOT_SUPPORTED 1703 #define RPC_S_INVALID_RPC_PROTSEQ 1704 #define RPC_S_INVALID_STRING_UUID 1705 #define RPC_S_INVALID_ENDPOINT_FORMAT 1706 #define RPC_S_INVALID_NET_ADDR 1707 #define RPC_S_NO_ENDPOINT_FOUND 1708 #define RPC_S_INVALID_TIMEOUT 1709 #define RPC_S_OBJECT_NOT_FOUND 1710 #define RPC_S_ALREADY_REGISTERED 1711 #define RPC_S_TYPE_ALREADY_REGISTERED 1712 #define RPC_S_ALREADY_LISTENING 1713 #define RPC_S_NO_PROTSEQS_REGISTERED 1714 #define RPC_S_NOT_LISTENING 1715 #define RPC_S_UNKNOWN_MGR_TYPE 1716 #define RPC_S_UNKNOWN_IF 1717 #define RPC_S_NO_BINDINGS 1718 #define RPC_S_NO_PROTSEQS 1719 #define RPC_S_CANT_CREATE_ENDPOINT 1720 #define RPC_S_OUT_OF_RESOURCES 1721 #define RPC_S_SERVER_UNAVAILABLE 1722 #define RPC_S_SERVER_TOO_BUSY 1723 #define RPC_S_INVALID_NETWORK_OPTIONS 1724 #define RPC_S_NO_CALL_ACTIVE 1725 #define RPC_S_CALL_FAILED 1726 #define RPC_S_CALL_FAILED_DNE 1727 #define RPC_S_PROTOCOL_ERROR 1728 #define RPC_S_UNSUPPORTED_TRANS_SYN 1730 #define RPC_S_UNSUPPORTED_TYPE 1732 #define RPC_S_INVALID_TAG 1733 #define RPC_S_INVALID_BOUND 1734 #define RPC_S_NO_ENTRY_NAME 1735 #define RPC_S_INVALID_NAME_SYNTAX 1736 #define RPC_S_UNSUPPORTED_NAME_SYNTAX 1737 #define RPC_S_UUID_NO_ADDRESS 1739 #define RPC_S_DUPLICATE_ENDPOINT 1740 #define RPC_S_UNKNOWN_AUTHN_TYPE 1741 #define RPC_S_MAX_CALLS_TOO_SMALL 1742 #define RPC_S_STRING_TOO_LONG 1743 #define RPC_S_PROTSEQ_NOT_FOUND 1744 #define RPC_S_PROCNUM_OUT_OF_RANGE 1745 #define RPC_S_BINDING_HAS_NO_AUTH 1746 #define RPC_S_UNKNOWN_AUTHN_SERVICE 1747 #define RPC_S_UNKNOWN_AUTHN_LEVEL 1748 #define RPC_S_INVALID_AUTH_IDENTITY 1749 #define RPC_S_UNKNOWN_AUTHZ_SERVICE 1750 #define EPT_S_INVALID_ENTRY 1751 #define EPT_S_CANT_PERFORM_OP 1752 #define EPT_S_NOT_REGISTERED 1753 #define RPC_S_NOTHING_TO_EXPORT 1754 #define RPC_S_INCOMPLETE_NAME 1755 #define RPC_S_INVALID_VERS_OPTION 1756 #define RPC_S_NO_MORE_MEMBERS 1757 #define RPC_S_NOT_ALL_OBJS_UNEXPORTED 1758 #define RPC_S_INTERFACE_NOT_FOUND 1759 #define RPC_S_ENTRY_ALREADY_EXISTS 1760 #define RPC_S_ENTRY_NOT_FOUND 1761 #define RPC_S_NAME_SERVICE_UNAVAILABLE 1762 #define RPC_S_INVALID_NAF_ID 1763 #define RPC_S_CANNOT_SUPPORT 1764 #define RPC_S_NO_CONTEXT_AVAILABLE 1765 #define RPC_S_INTERNAL_ERROR 1766 #define RPC_S_ZERO_DIVIDE 1767 #define RPC_S_ADDRESS_ERROR 1768 #define RPC_S_FP_DIV_ZERO 1769 #define RPC_S_FP_UNDERFLOW 1770 #define RPC_S_FP_OVERFLOW 1771 #define RPC_X_NO_MORE_ENTRIES 1772 #define RPC_X_SS_CHAR_TRANS_OPEN_FAIL 1773 #define RPC_X_SS_CHAR_TRANS_SHORT_FILE 1774 #define RPC_X_SS_IN_NULL_CONTEXT 1775 #define RPC_X_SS_CONTEXT_DAMAGED 1777 #define RPC_X_SS_HANDLES_MISMATCH 1778 #define RPC_X_SS_CANNOT_GET_CALL_HANDLE 1779 #define RPC_X_NULL_REF_POINTER 1780 #define RPC_X_ENUM_VALUE_OUT_OF_RANGE 1781 #define RPC_X_BYTE_COUNT_TOO_SMALL 1782 #define RPC_X_BAD_STUB_DATA 1783 #define ERROR_INVALID_USER_BUFFER 1784 #define ERROR_UNRECOGNIZED_MEDIA 1785 #define ERROR_NO_TRUST_LSA_SECRET 1786 #define ERROR_NO_TRUST_SAM_ACCOUNT 1787 #define ERROR_TRUSTED_DOMAIN_FAILURE 1788 #define ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789 #define ERROR_TRUST_FAILURE 1790 #define RPC_S_CALL_IN_PROGRESS 1791 #define ERROR_NETLOGON_NOT_STARTED 1792 #define ERROR_ACCOUNT_EXPIRED 1793 #define ERROR_REDIRECTOR_HAS_OPEN_HANDLES 1794 #define ERROR_PRINTER_DRIVER_ALREADY_INSTALLED 1795 #define ERROR_UNKNOWN_PORT 1796 #define ERROR_UNKNOWN_PRINTER_DRIVER 1797 #define ERROR_UNKNOWN_PRINTPROCESSOR 1798 #define ERROR_INVALID_SEPARATOR_FILE 1799 #define ERROR_INVALID_PRIORITY 1800 #define ERROR_INVALID_PRINTER_NAME 1801 #define ERROR_PRINTER_ALREADY_EXISTS 1802 #define ERROR_INVALID_PRINTER_COMMAND 1803 #define ERROR_INVALID_DATATYPE 1804 #define ERROR_INVALID_ENVIRONMENT 1805 #define RPC_S_NO_MORE_BINDINGS 1806 #define ERROR_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 1807 #define ERROR_NOLOGON_WORKSTATION_TRUST_ACCOUNT 1808 #define ERROR_NOLOGON_SERVER_TRUST_ACCOUNT 1809 #define ERROR_DOMAIN_TRUST_INCONSISTENT 1810 #define ERROR_SERVER_HAS_OPEN_HANDLES 1811 #define ERROR_RESOURCE_DATA_NOT_FOUND 1812 #define ERROR_RESOURCE_TYPE_NOT_FOUND 1813 #define ERROR_RESOURCE_NAME_NOT_FOUND 1814 #define ERROR_RESOURCE_LANG_NOT_FOUND 1815 #define ERROR_NOT_ENOUGH_QUOTA 1816 #define RPC_S_NO_INTERFACES 1817 #define RPC_S_CALL_CANCELLED 1818 #define RPC_S_BINDING_INCOMPLETE 1819 #define RPC_S_COMM_FAILURE 1820 #define RPC_S_UNSUPPORTED_AUTHN_LEVEL 1821 #define RPC_S_NO_PRINC_NAME 1822 #define RPC_S_NOT_RPC_ERROR 1823 #define RPC_S_UUID_LOCAL_ONLY 1824 #define RPC_S_SEC_PKG_ERROR 1825 #define RPC_S_NOT_CANCELLED 1826 #define RPC_X_INVALID_ES_ACTION 1827 #define RPC_X_WRONG_ES_VERSION 1828 #define RPC_X_WRONG_STUB_VERSION 1829 #define RPC_X_INVALID_PIPE_OBJECT 1830 #define RPC_X_WRONG_PIPE_ORDER 1831 #define RPC_X_WRONG_PIPE_VERSION 1832 #define RPC_S_GROUP_MEMBER_NOT_FOUND 1898 #define EPT_S_CANT_CREATE 1899 #define RPC_S_INVALID_OBJECT 1900 #define ERROR_INVALID_TIME 1901 #define ERROR_INVALID_FORM_NAME 1902 #define ERROR_INVALID_FORM_SIZE 1903 #define ERROR_ALREADY_WAITING 1904 #define ERROR_PRINTER_DELETED 1905 #define ERROR_INVALID_PRINTER_STATE 1906 #define ERROR_PASSWORD_MUST_CHANGE 1907 #define ERROR_DOMAIN_CONTROLLER_NOT_FOUND 1908 #define ERROR_ACCOUNT_LOCKED_OUT 1909 #define OR_INVALID_OXID 1910 #define OR_INVALID_OID 1911 #define OR_INVALID_SET 1912 #define RPC_S_SEND_INCOMPLETE 1913 #define RPC_S_INVALID_ASYNC_HANDLE 1914 #define RPC_S_INVALID_ASYNC_CALL 1915 #define RPC_X_PIPE_CLOSED 1916 #define RPC_X_PIPE_DISCIPLINE_ERROR 1917 #define RPC_X_PIPE_EMPTY 1918 #define ERROR_NO_SITENAME 1919 #define ERROR_CANT_ACCESS_FILE 1920 #define ERROR_CANT_RESOLVE_FILENAME 1921 #define RPC_S_ENTRY_TYPE_MISMATCH 1922 #define RPC_S_NOT_ALL_OBJS_EXPORTED 1923 #define RPC_S_INTERFACE_NOT_EXPORTED 1924 #define RPC_S_PROFILE_NOT_ADDED 1925 #define RPC_S_PRF_ELT_NOT_ADDED 1926 #define RPC_S_PRF_ELT_NOT_REMOVED 1927 #define RPC_S_GRP_ELT_NOT_ADDED 1928 #define RPC_S_GRP_ELT_NOT_REMOVED 1929 #define ERROR_INVALID_PIXEL_FORMAT 2000 #define ERROR_BAD_DRIVER 2001 #define ERROR_INVALID_WINDOW_STYLE 2002 #define ERROR_METAFILE_NOT_SUPPORTED 2003 #define ERROR_TRANSFORM_NOT_SUPPORTED 2004 #define ERROR_CLIPPING_NOT_SUPPORTED 2005 #define ERROR_INVALID_CMM 2010 #define ERROR_INVALID_PROFILE 2011 #define ERROR_TAG_NOT_FOUND 2012 #define ERROR_TAG_NOT_PRESENT 2013 #define ERROR_DUPLICATE_TAG 2014 #define ERROR_PROFILE_NOT_ASSOCIATED_WITH_DEVICE 2015 #define ERROR_PROFILE_NOT_FOUND 2016 #define ERROR_INVALID_COLORSPACE 2017 #define ERROR_ICM_NOT_ENABLED 2018 #define ERROR_DELETING_ICM_XFORM 2019 #define ERROR_INVALID_TRANSFORM 2020 #define ERROR_COLORSPACE_MISMATCH 2021 #define ERROR_INVALID_COLORINDEX 2022 #define ERROR_CONNECTED_OTHER_PASSWORD 2108 #define ERROR_BAD_USERNAME 2202 #define ERROR_NOT_CONNECTED 2250 #define ERROR_OPEN_FILES 2401 #define ERROR_ACTIVE_CONNECTIONS 2402 #define ERROR_DEVICE_IN_USE 2404 #define ERROR_UNKNOWN_PRINT_MONITOR 3000 #define ERROR_PRINTER_DRIVER_IN_USE 3001 #define ERROR_SPOOL_FILE_NOT_FOUND 3002 #define ERROR_SPL_NO_STARTDOC 3003 #define ERROR_SPL_NO_ADDJOB 3004 #define ERROR_PRINT_PROCESSOR_ALREADY_INSTALLED 3005 #define ERROR_PRINT_MONITOR_ALREADY_INSTALLED 3006 #define ERROR_INVALID_PRINT_MONITOR 3007 #define ERROR_PRINT_MONITOR_IN_USE 3008 #define ERROR_PRINTER_HAS_JOBS_QUEUED 3009 #define ERROR_SUCCESS_REBOOT_REQUIRED 3010 #define ERROR_SUCCESS_RESTART_REQUIRED 3011 #define ERROR_PRINTER_NOT_FOUND 3012 #define ERROR_WINS_INTERNAL 4000 #define ERROR_CAN_NOT_DEL_LOCAL_WINS 4001 #define ERROR_STATIC_INIT 4002 #define ERROR_INC_BACKUP 4003 #define ERROR_FULL_BACKUP 4004 #define ERROR_REC_NON_EXISTENT 4005 #define ERROR_RPL_NOT_ALLOWED 4006 #define ERROR_DHCP_ADDRESS_CONFLICT 4100 #define ERROR_WMI_GUID_NOT_FOUND 4200 #define ERROR_WMI_INSTANCE_NOT_FOUND 4201 #define ERROR_WMI_ITEMID_NOT_FOUND 4202 #define ERROR_WMI_TRY_AGAIN 4203 #define ERROR_WMI_DP_NOT_FOUND 4204 #define ERROR_WMI_UNRESOLVED_INSTANCE_REF 4205 #define ERROR_WMI_ALREADY_ENABLED 4206 #define ERROR_WMI_GUID_DISCONNECTED 4207 #define ERROR_WMI_SERVER_UNAVAILABLE 4208 #define ERROR_WMI_DP_FAILED 4209 #define ERROR_WMI_INVALID_MOF 4210 #define ERROR_WMI_INVALID_REGINFO 4211 #define ERROR_WMI_ALREADY_DISABLED 4212 #define ERROR_WMI_READ_ONLY 4213 #define ERROR_WMI_SET_FAILURE 4214 #define ERROR_INVALID_MEDIA 4300 #define ERROR_INVALID_LIBRARY 4301 #define ERROR_INVALID_MEDIA_POOL 4302 #define ERROR_DRIVE_MEDIA_MISMATCH 4303 #define ERROR_MEDIA_OFFLINE 4304 #define ERROR_LIBRARY_OFFLINE 4305 #define ERROR_EMPTY 4306 #define ERROR_NOT_EMPTY 4307 #define ERROR_MEDIA_UNAVAILABLE 4308 #define ERROR_RESOURCE_DISABLED 4309 #define ERROR_INVALID_CLEANER 4310 #define ERROR_UNABLE_TO_CLEAN 4311 #define ERROR_OBJECT_NOT_FOUND 4312 #define ERROR_DATABASE_FAILURE 4313 #define ERROR_DATABASE_FULL 4314 #define ERROR_MEDIA_INCOMPATIBLE 4315 #define ERROR_RESOURCE_NOT_PRESENT 4316 #define ERROR_INVALID_OPERATION 4317 #define ERROR_MEDIA_NOT_AVAILABLE 4318 #define ERROR_DEVICE_NOT_AVAILABLE 4319 #define ERROR_REQUEST_REFUSED 4320 #define ERROR_INVALID_DRIVE_OBJECT 4321 #define ERROR_LIBRARY_FULL 4322 #define ERROR_MEDIUM_NOT_ACCESSIBLE 4323 #define ERROR_UNABLE_TO_LOAD_MEDIUM 4324 #define ERROR_UNABLE_TO_INVENTORY_DRIVE 4325 #define ERROR_UNABLE_TO_INVENTORY_SLOT 4326 #define ERROR_UNABLE_TO_INVENTORY_TRANSPORT 4327 #define ERROR_TRANSPORT_FULL 4328 #define ERROR_CONTROLLING_IEPORT 4329 #define ERROR_UNABLE_TO_EJECT_MOUNTED_MEDIA 4330 #define ERROR_CLEANER_SLOT_SET 4331 #define ERROR_CLEANER_SLOT_NOT_SET 4332 #define ERROR_CLEANER_CARTRIDGE_SPENT 4333 #define ERROR_UNEXPECTED_OMID 4334 #define ERROR_CANT_DELETE_LAST_ITEM 4335 #define ERROR_MESSAGE_EXCEEDS_MAX_SIZE 4336 #define ERROR_VOLUME_CONTAINS_SYS_FILES 4337 #define ERROR_INDIGENOUS_TYPE 4338 #define ERROR_NO_SUPPORTING_DRIVES 4339 #define ERROR_FILE_OFFLINE 4350 #define ERROR_REMOTE_STORAGE_NOT_ACTIVE 4351 #define ERROR_REMOTE_STORAGE_MEDIA_ERROR 4352 #define ERROR_NOT_A_REPARSE_POINT 4390 #define ERROR_REPARSE_ATTRIBUTE_CONFLICT 4391 #define ERROR_INVALID_REPARSE_DATA 4392 #define ERROR_REPARSE_TAG_INVALID 4393 #define ERROR_REPARSE_TAG_MISMATCH 4394 #define ERROR_VOLUME_NOT_SIS_ENABLED 4500 #define ERROR_DEPENDENT_RESOURCE_EXISTS 5001 #define ERROR_DEPENDENCY_NOT_FOUND 5002 #define ERROR_DEPENDENCY_ALREADY_EXISTS 5003 #define ERROR_RESOURCE_NOT_ONLINE 5004 #define ERROR_HOST_NODE_NOT_AVAILABLE 5005 #define ERROR_RESOURCE_NOT_AVAILABLE 5006 #define ERROR_RESOURCE_NOT_FOUND 5007 #define ERROR_SHUTDOWN_CLUSTER 5008 #define ERROR_CANT_EVICT_ACTIVE_NODE 5009 #define ERROR_OBJECT_ALREADY_EXISTS 5010 #define ERROR_OBJECT_IN_LIST 5011 #define ERROR_GROUP_NOT_AVAILABLE 5012 #define ERROR_GROUP_NOT_FOUND 5013 #define ERROR_GROUP_NOT_ONLINE 5014 #define ERROR_HOST_NODE_NOT_RESOURCE_OWNER 5015 #define ERROR_HOST_NODE_NOT_GROUP_OWNER 5016 #define ERROR_RESMON_CREATE_FAILED 5017 #define ERROR_RESMON_ONLINE_FAILED 5018 #define ERROR_RESOURCE_ONLINE 5019 #define ERROR_QUORUM_RESOURCE 5020 #define ERROR_NOT_QUORUM_CAPABLE 5021 #define ERROR_CLUSTER_SHUTTING_DOWN 5022 #define ERROR_INVALID_STATE 5023 #define ERROR_RESOURCE_PROPERTIES_STORED 5024 #define ERROR_NOT_QUORUM_CLASS 5025 #define ERROR_CORE_RESOURCE 5026 #define ERROR_QUORUM_RESOURCE_ONLINE_FAILED 5027 #define ERROR_QUORUMLOG_OPEN_FAILED 5028 #define ERROR_CLUSTERLOG_CORRUPT 5029 #define ERROR_CLUSTERLOG_RECORD_EXCEEDS_MAXSIZE 5030 #define ERROR_CLUSTERLOG_EXCEEDS_MAXSIZE 5031 #define ERROR_CLUSTERLOG_CHKPOINT_NOT_FOUND 5032 #define ERROR_CLUSTERLOG_NOT_ENOUGH_SPACE 5033 #define ERROR_QUORUM_OWNER_ALIVE 5034 #define ERROR_NETWORK_NOT_AVAILABLE 5035 #define ERROR_NODE_NOT_AVAILABLE 5036 #define ERROR_ALL_NODES_NOT_AVAILABLE 5037 #define ERROR_RESOURCE_FAILED 5038 #define ERROR_CLUSTER_INVALID_NODE 5039 #define ERROR_CLUSTER_NODE_EXISTS 5040 #define ERROR_CLUSTER_JOIN_IN_PROGRESS 5041 #define ERROR_CLUSTER_NODE_NOT_FOUND 5042 #define ERROR_CLUSTER_LOCAL_NODE_NOT_FOUND 5043 #define ERROR_CLUSTER_NETWORK_EXISTS 5044 #define ERROR_CLUSTER_NETWORK_NOT_FOUND 5045 #define ERROR_CLUSTER_NETINTERFACE_EXISTS 5046 #define ERROR_CLUSTER_NETINTERFACE_NOT_FOUND 5047 #define ERROR_CLUSTER_INVALID_REQUEST 5048 #define ERROR_CLUSTER_INVALID_NETWORK_PROVIDER 5049 #define ERROR_CLUSTER_NODE_DOWN 5050 #define ERROR_CLUSTER_NODE_UNREACHABLE 5051 #define ERROR_CLUSTER_NODE_NOT_MEMBER 5052 #define ERROR_CLUSTER_JOIN_NOT_IN_PROGRESS 5053 #define ERROR_CLUSTER_INVALID_NETWORK 5054 #define ERROR_CLUSTER_NODE_UP 5056 #define ERROR_CLUSTER_IPADDR_IN_USE 5057 #define ERROR_CLUSTER_NODE_NOT_PAUSED 5058 #define ERROR_CLUSTER_NO_SECURITY_CONTEXT 5059 #define ERROR_CLUSTER_NETWORK_NOT_INTERNAL 5060 #define ERROR_CLUSTER_NODE_ALREADY_UP 5061 #define ERROR_CLUSTER_NODE_ALREADY_DOWN 5062 #define ERROR_CLUSTER_NETWORK_ALREADY_ONLINE 5063 #define ERROR_CLUSTER_NETWORK_ALREADY_OFFLINE 5064 #define ERROR_CLUSTER_NODE_ALREADY_MEMBER 5065 #define ERROR_CLUSTER_LAST_INTERNAL_NETWORK 5066 #define ERROR_CLUSTER_NETWORK_HAS_DEPENDENTS 5067 #define ERROR_INVALID_OPERATION_ON_QUORUM 5068 #define ERROR_DEPENDENCY_NOT_ALLOWED 5069 #define ERROR_CLUSTER_NODE_PAUSED 5070 #define ERROR_NODE_CANT_HOST_RESOURCE 5071 #define ERROR_CLUSTER_NODE_NOT_READY 5072 #define ERROR_CLUSTER_NODE_SHUTTING_DOWN 5073 #define ERROR_CLUSTER_JOIN_ABORTED 5074 #define ERROR_CLUSTER_INCOMPATIBLE_VERSIONS 5075 #define ERROR_CLUSTER_MAXNUM_OF_RESOURCES_EXCEEDED 5076 #define ERROR_CLUSTER_SYSTEM_CONFIG_CHANGED 5077 #define ERROR_CLUSTER_RESOURCE_TYPE_NOT_FOUND 5078 #define ERROR_CLUSTER_RESTYPE_NOT_SUPPORTED 5079 #define ERROR_CLUSTER_RESNAME_NOT_FOUND 5080 #define ERROR_CLUSTER_NO_RPC_PACKAGES_REGISTERED 5081 #define ERROR_CLUSTER_OWNER_NOT_IN_PREFLIST 5082 #define ERROR_CLUSTER_DATABASE_SEQMISMATCH 5083 #define ERROR_RESMON_INVALID_STATE 5084 #define ERROR_CLUSTER_GUM_NOT_LOCKER 5085 #define ERROR_QUORUM_DISK_NOT_FOUND 5086 #define ERROR_DATABASE_BACKUP_CORRUPT 5087 #define ERROR_CLUSTER_NODE_ALREADY_HAS_DFS_ROOT 5088 #define ERROR_RESOURCE_PROPERTY_UNCHANGEABLE 5089 #define ERROR_ENCRYPTION_FAILED 6000 #define ERROR_DECRYPTION_FAILED 6001 #define ERROR_FILE_ENCRYPTED 6002 #define ERROR_NO_RECOVERY_POLICY 6003 #define ERROR_NO_EFS 6004 #define ERROR_WRONG_EFS 6005 #define ERROR_NO_USER_KEYS 6006 #define ERROR_FILE_NOT_ENCRYPTED 6007 #define ERROR_NOT_EXPORT_FORMAT 6008 #define ERROR_FILE_READ_ONLY 6009 #define ERROR_DIR_EFS_DISALLOWED 6010 #define ERROR_EFS_SERVER_NOT_TRUSTED 6011 #define ERROR_NO_BROWSER_SERVERS_FOUND 6118 #define SCHED_E_SERVICE_NOT_LOCALSYSTEM 6200 #define ERROR_CTX_WINSTATION_NAME_INVALID 7001 #define ERROR_CTX_INVALID_PD 7002 #define ERROR_CTX_PD_NOT_FOUND 7003 #define ERROR_CTX_WD_NOT_FOUND 7004 #define ERROR_CTX_CANNOT_MAKE_EVENTLOG_ENTRY 7005 #define ERROR_CTX_SERVICE_NAME_COLLISION 7006 #define ERROR_CTX_CLOSE_PENDING 7007 #define ERROR_CTX_NO_OUTBUF 7008 #define ERROR_CTX_MODEM_INF_NOT_FOUND 7009 #define ERROR_CTX_INVALID_MODEMNAME 7010 #define ERROR_CTX_MODEM_RESPONSE_ERROR 7011 #define ERROR_CTX_MODEM_RESPONSE_TIMEOUT 7012 #define ERROR_CTX_MODEM_RESPONSE_NO_CARRIER 7013 #define ERROR_CTX_MODEM_RESPONSE_NO_DIALTONE 7014 #define ERROR_CTX_MODEM_RESPONSE_BUSY 7015 #define ERROR_CTX_MODEM_RESPONSE_VOICE 7016 #define ERROR_CTX_TD_ERROR 7017 #define ERROR_CTX_WINSTATION_NOT_FOUND 7022 #define ERROR_CTX_WINSTATION_ALREADY_EXISTS 7023 #define ERROR_CTX_WINSTATION_BUSY 7024 #define ERROR_CTX_BAD_VIDEO_MODE 7025 #define ERROR_CTX_GRAPHICS_INVALID 7035 #define ERROR_CTX_LOGON_DISABLED 7037 #define ERROR_CTX_NOT_CONSOLE 7038 #define ERROR_CTX_CLIENT_QUERY_TIMEOUT 7040 #define ERROR_CTX_CONSOLE_DISCONNECT 7041 #define ERROR_CTX_CONSOLE_CONNECT 7042 #define ERROR_CTX_SHADOW_DENIED 7044 #define ERROR_CTX_WINSTATION_ACCESS_DENIED 7045 #define ERROR_CTX_INVALID_WD 7049 #define ERROR_CTX_SHADOW_INVALID 7050 #define ERROR_CTX_SHADOW_DISABLED 7051 #define ERROR_CTX_CLIENT_LICENSE_IN_USE 7052 #define ERROR_CTX_CLIENT_LICENSE_NOT_SET 7053 #define ERROR_CTX_LICENSE_NOT_AVAILABLE 7054 #define ERROR_CTX_LICENSE_CLIENT_INVALID 7055 #define ERROR_CTX_LICENSE_EXPIRED 7056 #define FRS_ERR_INVALID_API_SEQUENCE 8001 #define FRS_ERR_STARTING_SERVICE 8002 #define FRS_ERR_STOPPING_SERVICE 8003 #define FRS_ERR_INTERNAL_API 8004 #define FRS_ERR_INTERNAL 8005 #define FRS_ERR_SERVICE_COMM 8006 #define FRS_ERR_INSUFFICIENT_PRIV 8007 #define FRS_ERR_AUTHENTICATION 8008 #define FRS_ERR_PARENT_INSUFFICIENT_PRIV 8009 #define FRS_ERR_PARENT_AUTHENTICATION 8010 #define FRS_ERR_CHILD_TO_PARENT_COMM 8011 #define FRS_ERR_PARENT_TO_CHILD_COMM 8012 #define FRS_ERR_SYSVOL_POPULATE 8013 #define FRS_ERR_SYSVOL_POPULATE_TIMEOUT 8014 #define FRS_ERR_SYSVOL_IS_BUSY 8015 #define FRS_ERR_SYSVOL_DEMOTE 8016 #define FRS_ERR_INVALID_SERVICE_PARAMETER 8017 #define ERROR_DS_NOT_INSTALLED 8200 #define ERROR_DS_MEMBERSHIP_EVALUATED_LOCALLY 8201 #define ERROR_DS_NO_ATTRIBUTE_OR_VALUE 8202 #define ERROR_DS_INVALID_ATTRIBUTE_SYNTAX 8203 #define ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED 8204 #define ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS 8205 #define ERROR_DS_BUSY 8206 #define ERROR_DS_UNAVAILABLE 8207 #define ERROR_DS_NO_RIDS_ALLOCATED 8208 #define ERROR_DS_NO_MORE_RIDS 8209 #define ERROR_DS_INCORRECT_ROLE_OWNER 8210 #define ERROR_DS_RIDMGR_INIT_ERROR 8211 #define ERROR_DS_OBJ_CLASS_VIOLATION 8212 #define ERROR_DS_CANT_ON_NON_LEAF 8213 #define ERROR_DS_CANT_ON_RDN 8214 #define ERROR_DS_CANT_MOD_OBJ_CLASS 8215 #define ERROR_DS_CROSS_DOM_MOVE_ERROR 8216 #define ERROR_DS_GC_NOT_AVAILABLE 8217 #define ERROR_SHARED_POLICY 8218 #define ERROR_POLICY_OBJECT_NOT_FOUND 8219 #define ERROR_POLICY_ONLY_IN_DS 8220 #define ERROR_PROMOTION_ACTIVE 8221 #define ERROR_NO_PROMOTION_ACTIVE 8222 #define ERROR_DS_OPERATIONS_ERROR 8224 #define ERROR_DS_PROTOCOL_ERROR 8225 #define ERROR_DS_TIMELIMIT_EXCEEDED 8226 #define ERROR_DS_SIZELIMIT_EXCEEDED 8227 #define ERROR_DS_ADMIN_LIMIT_EXCEEDED 8228 #define ERROR_DS_COMPARE_FALSE 8229 #define ERROR_DS_COMPARE_TRUE 8230 #define ERROR_DS_AUTH_METHOD_NOT_SUPPORTED 8231 #define ERROR_DS_STRONG_AUTH_REQUIRED 8232 #define ERROR_DS_INAPPROPRIATE_AUTH 8233 #define ERROR_DS_AUTH_UNKNOWN 8234 #define ERROR_DS_REFERRAL 8235 #define ERROR_DS_UNAVAILABLE_CRIT_EXTENSION 8236 #define ERROR_DS_CONFIDENTIALITY_REQUIRED 8237 #define ERROR_DS_INAPPROPRIATE_MATCHING 8238 #define ERROR_DS_CONSTRAINT_VIOLATION 8239 #define ERROR_DS_NO_SUCH_OBJECT 8240 #define ERROR_DS_ALIAS_PROBLEM 8241 #define ERROR_DS_INVALID_DN_SYNTAX 8242 #define ERROR_DS_IS_LEAF 8243 #define ERROR_DS_ALIAS_DEREF_PROBLEM 8244 #define ERROR_DS_UNWILLING_TO_PERFORM 8245 #define ERROR_DS_LOOP_DETECT 8246 #define ERROR_DS_NAMING_VIOLATION 8247 #define ERROR_DS_OBJECT_RESULTS_TOO_LARGE 8248 #define ERROR_DS_AFFECTS_MULTIPLE_DSAS 8249 #define ERROR_DS_SERVER_DOWN 8250 #define ERROR_DS_LOCAL_ERROR 8251 #define ERROR_DS_ENCODING_ERROR 8252 #define ERROR_DS_DECODING_ERROR 8253 #define ERROR_DS_FILTER_UNKNOWN 8254 #define ERROR_DS_PARAM_ERROR 8255 #define ERROR_DS_NOT_SUPPORTED 8256 #define ERROR_DS_NO_RESULTS_RETURNED 8257 #define ERROR_DS_CONTROL_NOT_FOUND 8258 #define ERROR_DS_CLIENT_LOOP 8259 #define ERROR_DS_REFERRAL_LIMIT_EXCEEDED 8260 #define ERROR_DS_ROOT_MUST_BE_NC 8301 #define ERROR_DS_ADD_REPLICA_INHIBITED 8302 #define ERROR_DS_ATT_NOT_DEF_IN_SCHEMA 8303 #define ERROR_DS_MAX_OBJ_SIZE_EXCEEDED 8304 #define ERROR_DS_OBJ_STRING_NAME_EXISTS 8305 #define ERROR_DS_NO_RDN_DEFINED_IN_SCHEMA 8306 #define ERROR_DS_RDN_DOESNT_MATCH_SCHEMA 8307 #define ERROR_DS_NO_REQUESTED_ATTS_FOUND 8308 #define ERROR_DS_USER_BUFFER_TO_SMALL 8309 #define ERROR_DS_ATT_IS_NOT_ON_OBJ 8310 #define ERROR_DS_ILLEGAL_MOD_OPERATION 8311 #define ERROR_DS_OBJ_TOO_LARGE 8312 #define ERROR_DS_BAD_INSTANCE_TYPE 8313 #define ERROR_DS_MASTERDSA_REQUIRED 8314 #define ERROR_DS_OBJECT_CLASS_REQUIRED 8315 #define ERROR_DS_MISSING_REQUIRED_ATT 8316 #define ERROR_DS_ATT_NOT_DEF_FOR_CLASS 8317 #define ERROR_DS_ATT_ALREADY_EXISTS 8318 #define ERROR_DS_CANT_ADD_ATT_VALUES 8320 #define ERROR_DS_SINGLE_VALUE_CONSTRAINT 8321 #define ERROR_DS_RANGE_CONSTRAINT 8322 #define ERROR_DS_ATT_VAL_ALREADY_EXISTS 8323 #define ERROR_DS_CANT_REM_MISSING_ATT 8324 #define ERROR_DS_CANT_REM_MISSING_ATT_VAL 8325 #define ERROR_DS_ROOT_CANT_BE_SUBREF 8326 #define ERROR_DS_NO_CHAINING 8327 #define ERROR_DS_NO_CHAINED_EVAL 8328 #define ERROR_DS_NO_PARENT_OBJECT 8329 #define ERROR_DS_PARENT_IS_AN_ALIAS 8330 #define ERROR_DS_CANT_MIX_MASTER_AND_REPS 8331 #define ERROR_DS_CHILDREN_EXIST 8332 #define ERROR_DS_OBJ_NOT_FOUND 8333 #define ERROR_DS_ALIASED_OBJ_MISSING 8334 #define ERROR_DS_BAD_NAME_SYNTAX 8335 #define ERROR_DS_ALIAS_POINTS_TO_ALIAS 8336 #define ERROR_DS_CANT_DEREF_ALIAS 8337 #define ERROR_DS_OUT_OF_SCOPE 8338 #define ERROR_DS_CANT_DELETE_DSA_OBJ 8340 #define ERROR_DS_GENERIC_ERROR 8341 #define ERROR_DS_DSA_MUST_BE_INT_MASTER 8342 #define ERROR_DS_CLASS_NOT_DSA 8343 #define ERROR_DS_INSUFF_ACCESS_RIGHTS 8344 #define ERROR_DS_ILLEGAL_SUPERIOR 8345 #define ERROR_DS_ATTRIBUTE_OWNED_BY_SAM 8346 #define ERROR_DS_NAME_TOO_MANY_PARTS 8347 #define ERROR_DS_NAME_TOO_LONG 8348 #define ERROR_DS_NAME_VALUE_TOO_LONG 8349 #define ERROR_DS_NAME_UNPARSEABLE 8350 #define ERROR_DS_NAME_TYPE_UNKNOWN 8351 #define ERROR_DS_NOT_AN_OBJECT 8352 #define ERROR_DS_SEC_DESC_TOO_SHORT 8353 #define ERROR_DS_SEC_DESC_INVALID 8354 #define ERROR_DS_NO_DELETED_NAME 8355 #define ERROR_DS_SUBREF_MUST_HAVE_PARENT 8356 #define ERROR_DS_NCNAME_MUST_BE_NC 8357 #define ERROR_DS_CANT_ADD_SYSTEM_ONLY 8358 #define ERROR_DS_CLASS_MUST_BE_CONCRETE 8359 #define ERROR_DS_INVALID_DMD 8360 #define ERROR_DS_OBJ_GUID_EXISTS 8361 #define ERROR_DS_NOT_ON_BACKLINK 8362 #define ERROR_DS_NO_CROSSREF_FOR_NC 8363 #define ERROR_DS_SHUTTING_DOWN 8364 #define ERROR_DS_UNKNOWN_OPERATION 8365 #define ERROR_DS_INVALID_ROLE_OWNER 8366 #define ERROR_DS_COULDNT_CONTACT_FSMO 8367 #define ERROR_DS_CROSS_NC_DN_RENAME 8368 #define ERROR_DS_CANT_MOD_SYSTEM_ONLY 8369 #define ERROR_DS_REPLICATOR_ONLY 8370 #define ERROR_DS_OBJ_CLASS_NOT_DEFINED 8371 #define ERROR_DS_OBJ_CLASS_NOT_SUBCLASS 8372 #define ERROR_DS_NAME_REFERENCE_INVALID 8373 #define ERROR_DS_CROSS_REF_EXISTS 8374 #define ERROR_DS_CANT_DEL_MASTER_CROSSREF 8375 #define ERROR_DS_SUBTREE_NOTIFY_NOT_NC_HEAD 8376 #define ERROR_DS_NOTIFY_FILTER_TOO_COMPLEX 8377 #define ERROR_DS_DUP_RDN 8378 #define ERROR_DS_DUP_OID 8379 #define ERROR_DS_DUP_MAPI_ID 8380 #define ERROR_DS_DUP_SCHEMA_ID_GUID 8381 #define ERROR_DS_DUP_LDAP_DISPLAY_NAME 8382 #define ERROR_DS_SEMANTIC_ATT_TEST 8383 #define ERROR_DS_SYNTAX_MISMATCH 8384 #define ERROR_DS_EXISTS_IN_MUST_HAVE 8385 #define ERROR_DS_EXISTS_IN_MAY_HAVE 8386 #define ERROR_DS_NONEXISTENT_MAY_HAVE 8387 #define ERROR_DS_NONEXISTENT_MUST_HAVE 8388 #define ERROR_DS_AUX_CLS_TEST_FAIL 8389 #define ERROR_DS_NONEXISTENT_POSS_SUP 8390 #define ERROR_DS_SUB_CLS_TEST_FAIL 8391 #define ERROR_DS_BAD_RDN_ATT_ID_SYNTAX 8392 #define ERROR_DS_EXISTS_IN_AUX_CLS 8393 #define ERROR_DS_EXISTS_IN_SUB_CLS 8394 #define ERROR_DS_EXISTS_IN_POSS_SUP 8395 #define ERROR_DS_RECALCSCHEMA_FAILED 8396 #define ERROR_DS_TREE_DELETE_NOT_FINISHED 8397 #define ERROR_DS_CANT_DELETE 8398 #define ERROR_DS_ATT_SCHEMA_REQ_ID 8399 #define ERROR_DS_BAD_ATT_SCHEMA_SYNTAX 8400 #define ERROR_DS_CANT_CACHE_ATT 8401 #define ERROR_DS_CANT_CACHE_CLASS 8402 #define ERROR_DS_CANT_REMOVE_ATT_CACHE 8403 #define ERROR_DS_CANT_REMOVE_CLASS_CACHE 8404 #define ERROR_DS_CANT_RETRIEVE_DN 8405 #define ERROR_DS_MISSING_SUPREF 8406 #define ERROR_DS_CANT_RETRIEVE_INSTANCE 8407 #define ERROR_DS_CODE_INCONSISTENCY 8408 #define ERROR_DS_DATABASE_ERROR 8409 #define ERROR_DS_GOVERNSID_MISSING 8410 #define ERROR_DS_MISSING_EXPECTED_ATT 8411 #define ERROR_DS_NCNAME_MISSING_CR_REF 8412 #define ERROR_DS_SECURITY_CHECKING_ERROR 8413 #define ERROR_DS_SCHEMA_NOT_LOADED 8414 #define ERROR_DS_SCHEMA_ALLOC_FAILED 8415 #define ERROR_DS_ATT_SCHEMA_REQ_SYNTAX 8416 #define ERROR_DS_GCVERIFY_ERROR 8417 #define ERROR_DS_DRA_SCHEMA_MISMATCH 8418 #define ERROR_DS_CANT_FIND_DSA_OBJ 8419 #define ERROR_DS_CANT_FIND_EXPECTED_NC 8420 #define ERROR_DS_CANT_FIND_NC_IN_CACHE 8421 #define ERROR_DS_CANT_RETRIEVE_CHILD 8422 #define ERROR_DS_SECURITY_ILLEGAL_MODIFY 8423 #define ERROR_DS_CANT_REPLACE_HIDDEN_REC 8424 #define ERROR_DS_BAD_HIERARCHY_FILE 8425 #define ERROR_DS_BUILD_HIERARCHY_TABLE_FAILED 8426 #define ERROR_DS_CONFIG_PARAM_MISSING 8427 #define ERROR_DS_COUNTING_AB_INDICES_FAILED 8428 #define ERROR_DS_HIERARCHY_TABLE_MALLOC_FAILED 8429 #define ERROR_DS_INTERNAL_FAILURE 8430 #define ERROR_DS_UNKNOWN_ERROR 8431 #define ERROR_DS_ROOT_REQUIRES_CLASS_TOP 8432 #define ERROR_DS_REFUSING_FSMO_ROLES 8433 #define ERROR_DS_MISSING_FSMO_SETTINGS 8434 #define ERROR_DS_UNABLE_TO_SURRENDER_ROLES 8435 #define ERROR_DS_DRA_GENERIC 8436 #define ERROR_DS_DRA_INVALID_PARAMETER 8437 #define ERROR_DS_DRA_BUSY 8438 #define ERROR_DS_DRA_BAD_DN 8439 #define ERROR_DS_DRA_BAD_NC 8440 #define ERROR_DS_DRA_DN_EXISTS 8441 #define ERROR_DS_DRA_INTERNAL_ERROR 8442 #define ERROR_DS_DRA_INCONSISTENT_DIT 8443 #define ERROR_DS_DRA_CONNECTION_FAILED 8444 #define ERROR_DS_DRA_BAD_INSTANCE_TYPE 8445 #define ERROR_DS_DRA_OUT_OF_MEM 8446 #define ERROR_DS_DRA_MAIL_PROBLEM 8447 #define ERROR_DS_DRA_REF_ALREADY_EXISTS 8448 #define ERROR_DS_DRA_REF_NOT_FOUND 8449 #define ERROR_DS_DRA_OBJ_IS_REP_SOURCE 8450 #define ERROR_DS_DRA_DB_ERROR 8451 #define ERROR_DS_DRA_NO_REPLICA 8452 #define ERROR_DS_DRA_ACCESS_DENIED 8453 #define ERROR_DS_DRA_NOT_SUPPORTED 8454 #define ERROR_DS_DRA_RPC_CANCELLED 8455 #define ERROR_DS_DRA_SOURCE_DISABLED 8456 #define ERROR_DS_DRA_SINK_DISABLED 8457 #define ERROR_DS_DRA_NAME_COLLISION 8458 #define ERROR_DS_DRA_SOURCE_REINSTALLED 8459 #define ERROR_DS_DRA_MISSING_PARENT 8460 #define ERROR_DS_DRA_PREEMPTED 8461 #define ERROR_DS_DRA_ABANDON_SYNC 8462 #define ERROR_DS_DRA_SHUTDOWN 8463 #define ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET 8464 #define ERROR_DS_DRA_SOURCE_IS_PARTIAL_REPLICA 8465 #define ERROR_DS_DRA_EXTN_CONNECTION_FAILED 8466 #define ERROR_DS_INSTALL_SCHEMA_MISMATCH 8467 #define ERROR_DS_DUP_LINK_ID 8468 #define ERROR_DS_NAME_ERROR_RESOLVING 8469 #define ERROR_DS_NAME_ERROR_NOT_FOUND 8470 #define ERROR_DS_NAME_ERROR_NOT_UNIQUE 8471 #define ERROR_DS_NAME_ERROR_NO_MAPPING 8472 #define ERROR_DS_NAME_ERROR_DOMAIN_ONLY 8473 #define ERROR_DS_NAME_ERROR_NO_SYNTACTICAL_MAPPING 8474 #define ERROR_DS_CONSTRUCTED_ATT_MOD 8475 #define ERROR_DS_WRONG_OM_OBJ_CLASS 8476 #define ERROR_DS_DRA_REPL_PENDING 8477 #define ERROR_DS_DS_REQUIRED 8478 #define ERROR_DS_INVALID_LDAP_DISPLAY_NAME 8479 #define ERROR_DS_NON_BASE_SEARCH 8480 #define ERROR_DS_CANT_RETRIEVE_ATTS 8481 #define ERROR_DS_BACKLINK_WITHOUT_LINK 8482 #define ERROR_DS_EPOCH_MISMATCH 8483 #define ERROR_DS_SRC_NAME_MISMATCH 8484 #define ERROR_DS_SRC_AND_DST_NC_IDENTICAL 8485 #define ERROR_DS_DST_NC_MISMATCH 8486 #define ERROR_DS_NOT_AUTHORITIVE_FOR_DST_NC 8487 #define ERROR_DS_SRC_GUID_MISMATCH 8488 #define ERROR_DS_CANT_MOVE_DELETED_OBJECT 8489 #define ERROR_DS_PDC_OPERATION_IN_PROGRESS 8490 #define ERROR_DS_CROSS_DOMAIN_CLEANUP_REQD 8491 #define ERROR_DS_ILLEGAL_XDOM_MOVE_OPERATION 8492 #define ERROR_DS_CANT_WITH_ACCT_GROUP_MEMBERSHPS 8493 #define ERROR_DS_NC_MUST_HAVE_NC_PARENT 8494 #define ERROR_DS_CR_IMPOSSIBLE_TO_VALIDATE 8495 #define ERROR_DS_DST_DOMAIN_NOT_NATIVE 8496 #define ERROR_DS_MISSING_INFRASTRUCTURE_CONTAINER 8497 #define ERROR_DS_CANT_MOVE_ACCOUNT_GROUP 8498 #define ERROR_DS_CANT_MOVE_RESOURCE_GROUP 8499 #define ERROR_DS_INVALID_SEARCH_FLAG 8500 #define ERROR_DS_NO_TREE_DELETE_ABOVE_NC 8501 #define ERROR_DS_COULDNT_LOCK_TREE_FOR_DELETE 8502 #define ERROR_DS_COULDNT_IDENTIFY_OBJECTS_FOR_TREE_DELETE 8503 #define ERROR_DS_SAM_INIT_FAILURE 8504 #define ERROR_DS_SENSITIVE_GROUP_VIOLATION 8505 #define ERROR_DS_CANT_MOD_PRIMARYGROUPID 8506 #define ERROR_DS_ILLEGAL_BASE_SCHEMA_MOD 8507 #define ERROR_DS_NONSAFE_SCHEMA_CHANGE 8508 #define ERROR_DS_SCHEMA_UPDATE_DISALLOWED 8509 #define ERROR_DS_CANT_CREATE_UNDER_SCHEMA 8510 #define ERROR_DS_INSTALL_NO_SRC_SCH_VERSION 8511 #define ERROR_DS_INSTALL_NO_SCH_VERSION_IN_INIFILE 8512 #define ERROR_DS_INVALID_GROUP_TYPE 8513 #define ERROR_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN 8514 #define ERROR_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN 8515 #define ERROR_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 8516 #define ERROR_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER 8517 #define ERROR_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER 8518 #define ERROR_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER 8519 #define ERROR_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER 8520 #define ERROR_DS_HAVE_PRIMARY_MEMBERS 8521 #define ERROR_DS_STRING_SD_CONVERSION_FAILED 8522 #define ERROR_DS_NAMING_MASTER_GC 8523 #define ERROR_DS_LOOKUP_FAILURE 8524 #define ERROR_DS_COULDNT_UPDATE_SPNS 8525 #define ERROR_DS_CANT_RETRIEVE_SD 8526 #define ERROR_DS_KEY_NOT_UNIQUE 8527 #define ERROR_DS_WRONG_LINKED_ATT_SYNTAX 8528 #define ERROR_DS_SAM_NEED_BOOTKEY_PASSWORD 8529 #define ERROR_DS_SAM_NEED_BOOTKEY_FLOPPY 8530 #define ERROR_DS_CANT_START 8531 #define ERROR_DS_INIT_FAILURE 8532 #define ERROR_DS_NO_PKT_PRIVACY_ON_CONNECTION 8533 #define ERROR_DS_SOURCE_DOMAIN_IN_FOREST 8534 #define ERROR_DS_DESTINATION_DOMAIN_NOT_IN_FOREST 8535 #define ERROR_DS_DESTINATION_AUDITING_NOT_ENABLED 8536 #define ERROR_DS_CANT_FIND_DC_FOR_SRC_DOMAIN 8537 #define ERROR_DS_SRC_OBJ_NOT_GROUP_OR_USER 8538 #define ERROR_DS_SRC_SID_EXISTS_IN_FOREST 8539 #define ERROR_DS_SRC_AND_DST_OBJECT_CLASS_MISMATCH 8540 #define ERROR_SAM_INIT_FAILURE 8541 #define ERROR_DS_DRA_SCHEMA_INFO_SHIP 8542 #define ERROR_DS_DRA_SCHEMA_CONFLICT 8543 #define ERROR_DS_DRA_EARLIER_SCHEMA_CONLICT 8544 #define ERROR_DS_DRA_OBJ_NC_MISMATCH 8545 #define ERROR_DS_NC_STILL_HAS_DSAS 8546 #define ERROR_DS_GC_REQUIRED 8547 #define ERROR_DS_LOCAL_MEMBER_OF_LOCAL_ONLY 8548 #define ERROR_DS_NO_FPO_IN_UNIVERSAL_GROUPS 8549 #define ERROR_DS_CANT_ADD_TO_GC 8550 #define ERROR_DS_NO_CHECKPOINT_WITH_PDC 8551 #define ERROR_DS_SOURCE_AUDITING_NOT_ENABLED 8552 #define ERROR_DS_CANT_CREATE_IN_NONDOMAIN_NC 8553 #define ERROR_DS_INVALID_NAME_FOR_SPN 8554 #define ERROR_DS_FILTER_USES_CONTRUCTED_ATTRS 8555 #define ERROR_DS_UNICODEPWD_NOT_IN_QUOTES 8556 #define ERROR_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED 8557 #define ERROR_DS_MUST_BE_RUN_ON_DST_DC 8558 #define ERROR_DS_SRC_DC_MUST_BE_SP4_OR_GREATER 8559 #define ERROR_DS_CANT_TREE_DELETE_CRITICAL_OBJ 8560 #define DNS_ERROR_RCODE_FORMAT_ERROR 9001 #define DNS_ERROR_RCODE_SERVER_FAILURE 9002 #define DNS_ERROR_RCODE_NAME_ERROR 9003 #define DNS_ERROR_RCODE_NOT_IMPLEMENTED 9004 #define DNS_ERROR_RCODE_REFUSED 9005 #define DNS_ERROR_RCODE_YXDOMAIN 9006 #define DNS_ERROR_RCODE_YXRRSET 9007 #define DNS_ERROR_RCODE_NXRRSET 9008 #define DNS_ERROR_RCODE_NOTAUTH 9009 #define DNS_ERROR_RCODE_NOTZONE 9010 #define DNS_ERROR_RCODE_BADSIG 9016 #define DNS_ERROR_RCODE_BADKEY 9017 #define DNS_ERROR_RCODE_BADTIME 9018 #define DNS_INFO_NO_RECORDS 9501 #define DNS_ERROR_BAD_PACKET 9502 #define DNS_ERROR_NO_PACKET 9503 #define DNS_ERROR_RCODE 9504 #define DNS_ERROR_UNSECURE_PACKET 9505 #define DNS_ERROR_INVALID_TYPE 9551 #define DNS_ERROR_INVALID_IP_ADDRESS 9552 #define DNS_ERROR_INVALID_PROPERTY 9553 #define DNS_ERROR_TRY_AGAIN_LATER 9554 #define DNS_ERROR_NOT_UNIQUE 9555 #define DNS_ERROR_NON_RFC_NAME 9556 #define DNS_STATUS_FQDN 9557 #define DNS_STATUS_DOTTED_NAME 9558 #define DNS_STATUS_SINGLE_PART_NAME 9559 #define DNS_ERROR_INVALID_NAME_CHAR 9560 #define DNS_ERROR_NUMERIC_NAME 9561 #define DNS_ERROR_ZONE_DOES_NOT_EXIST 9601 #define DNS_ERROR_NO_ZONE_INFO 9602 #define DNS_ERROR_INVALID_ZONE_OPERATION 9603 #define DNS_ERROR_ZONE_CONFIGURATION_ERROR 9604 #define DNS_ERROR_ZONE_HAS_NO_SOA_RECORD 9605 #define DNS_ERROR_ZONE_HAS_NO_NS_RECORDS 9606 #define DNS_ERROR_ZONE_LOCKED 9607 #define DNS_ERROR_ZONE_CREATION_FAILED 9608 #define DNS_ERROR_ZONE_ALREADY_EXISTS 9609 #define DNS_ERROR_AUTOZONE_ALREADY_EXISTS 9610 #define DNS_ERROR_INVALID_ZONE_TYPE 9611 #define DNS_ERROR_SECONDARY_REQUIRES_MASTER_IP 9612 #define DNS_ERROR_ZONE_NOT_SECONDARY 9613 #define DNS_ERROR_NEED_SECONDARY_ADDRESSES 9614 #define DNS_ERROR_WINS_INIT_FAILED 9615 #define DNS_ERROR_NEED_WINS_SERVERS 9616 #define DNS_ERROR_NBSTAT_INIT_FAILED 9617 #define DNS_ERROR_SOA_DELETE_INVALID 9618 #define DNS_ERROR_PRIMARY_REQUIRES_DATAFILE 9651 #define DNS_ERROR_INVALID_DATAFILE_NAME 9652 #define DNS_ERROR_DATAFILE_OPEN_FAILURE 9653 #define DNS_ERROR_FILE_WRITEBACK_FAILED 9654 #define DNS_ERROR_DATAFILE_PARSING 9655 #define DNS_ERROR_RECORD_DOES_NOT_EXIST 9701 #define DNS_ERROR_RECORD_FORMAT 9702 #define DNS_ERROR_NODE_CREATION_FAILED 9703 #define DNS_ERROR_UNKNOWN_RECORD_TYPE 9704 #define DNS_ERROR_RECORD_TIMED_OUT 9705 #define DNS_ERROR_NAME_NOT_IN_ZONE 9706 #define DNS_ERROR_CNAME_LOOP 9707 #define DNS_ERROR_NODE_IS_CNAME 9708 #define DNS_ERROR_CNAME_COLLISION 9709 #define DNS_ERROR_RECORD_ONLY_AT_ZONE_ROOT 9710 #define DNS_ERROR_RECORD_ALREADY_EXISTS 9711 #define DNS_ERROR_SECONDARY_DATA 9712 #define DNS_ERROR_NO_CREATE_CACHE_DATA 9713 #define DNS_ERROR_NAME_DOES_NOT_EXIST 9714 #define DNS_WARNING_PTR_CREATE_FAILED 9715 #define DNS_WARNING_DOMAIN_UNDELETED 9716 #define DNS_ERROR_DS_UNAVAILABLE 9717 #define DNS_ERROR_DS_ZONE_ALREADY_EXISTS 9718 #define DNS_ERROR_NO_BOOTFILE_IF_DS_ZONE 9719 #define DNS_INFO_AXFR_COMPLETE 9751 #define DNS_ERROR_AXFR 9752 #define DNS_INFO_ADDED_LOCAL_WINS 9753 #define DNS_STATUS_CONTINUE_NEEDED 9801 #define DNS_ERROR_NO_TCPIP 9851 #define DNS_ERROR_NO_DNS_SERVERS 9852 /* HRESULT values for OLE, SHELL and other Interface stuff */ /* the codes 4000-40ff are reserved for OLE */ #define NOERROR 0L #define S_OK ((HRESULT)0L) #define S_FALSE ((HRESULT)1L) #define DISP_E_UNKNOWNINTERFACE 0x80020001L #define DISP_E_MEMBERNOTFOUND 0x80020003L #define DISP_E_PARAMNOTFOUND 0x80020004L #define DISP_E_TYPEMISMATCH 0x80020005L #define DISP_E_UNKNOWNNAME 0x80020006L #define DISP_E_NONAMEDARGS 0x80020007L #define DISP_E_BADVARTYPE 0x80020008L #define DISP_E_EXCEPTION 0x80020009L #define DISP_E_OVERFLOW 0x8002000AL #define DISP_E_BADINDEX 0x8002000BL #define DISP_E_UNKNOWNLCID 0x8002000CL #define DISP_E_ARRAYISLOCKED 0x8002000DL #define DISP_E_BADPARAMCOUNT 0x8002000EL #define DISP_E_PARAMNOTOPTIONAL 0x8002000FL #define TYPE_E_ELEMENTNOTFOUND 0x8002802BL #define TYPE_E_CANTLOADLIBRARY 0x80029C4AL /* OLE Clipboard */ #define CLIPBRD_E_FIRST 0x800401D0L #define CLIPBRD_E_LAST 0x800401DFL #define CLIPBRD_S_FIRST 0x000401D0L #define CLIPBRD_S_LAST 0x000401DFL #define CLIPBRD_E_CANT_OPEN 0x800401D0L #define CLIPBRD_E_CANT_EMPTY 0x800401D1L #define CLIPBRD_E_CANT_SET 0x800401D2L #define CLIPBRD_E_BAD_DATA 0x800401D3L #define CLIPBRD_E_CANT_CLOSE 0x800401D4L /* Drag and Drop */ #define DRAGDROP_S_DROP 0x00040100L #define DRAGDROP_S_CANCEL 0x00040101L #define DRAGDROP_E_NOTREGISTERED 0x80040100L #define DRAGDROP_E_ALREADYREGISTERED 0x80040101L #define DRAGDROP_S_USEDEFAULTCURSORS 0x00040102L #define E_UNEXPECTED 0x8000FFFF #define E_NOTIMPL 0x80004001 #define E_NOINTERFACE 0x80004002 #define E_POINTER 0x80004003 #define E_ABORT 0x80004004 #define E_FAIL 0x80004005 #define E_UNSPEC E_FAIL /* must to be defined (used by FileMoniker, IOleLink and DoDragDrop as a return value) */ /*#define CO_E_INIT_TLS 0x80004006 #define CO_E_INIT_SHARED_ALLOCATOR 0x80004007 #define CO_E_INIT_MEMORY_ALLOCATOR 0x80004008 #define CO_E_INIT_CLASS_CACHE 0x80004009 #define CO_E_INIT_RPC_CHANNEL 0x8000400A #define CO_E_INIT_TLS_SET_CHANNEL_CONTROL 0x8000400B #define CO_E_INIT_TLS_CHANNEL_CONTROL 0x8000400C #define CO_E_INIT_UNACCEPTED_USER_ALLOCATOR 0x8000400D #define CO_E_INIT_SCM_MUTEX_EXISTS 0x8000400E #define CO_E_INIT_SCM_FILE_MAPPING_EXISTS 0x8000400F #define CO_E_INIT_SCM_MAP_VIEW_OF_FILE 0x80004010 #define CO_E_INIT_SCM_EXEC_FAILURE 0x80004011 #define CO_E_INIT_ONLY_SINGLE_THREADED 0x80004012 */ #define CO_S_NOTALLINTERFACES 0x00080012 #define CO_E_NOTINITIALIZED 0x800401F0 #define CO_E_ERRORINDLL 0x800401F9 #define CO_E_OBJISREG 0x800401FB #define OLE_E_FIRST 0x80040000L #define OLE_E_LAST 0x800400FFL #define OLE_S_FIRST 0x00040000L #define OLE_S_LAST 0x000400FFL #define OLE_E_ENUM_NOMORE 0x80040002 #define OLE_E_ADVISENOTSUPPORTED 0x80040003 #define OLE_E_NOCONNECTION 0x80040004 #define OLE_E_NOTRUNNING 0x80040005 #define OLE_E_NOCACHE 0x80040006 #define OLE_E_BLANK 0x80040007 #define OLE_E_NOT_INPLACEACTIVE 0x80040010 #define OLE_E_STATIC 0x8004000B #define OLE_E_PROMPTSAVECANCELLED 0x8004000C #define OLE_S_USEREG 0x00040000 #define OLE_S_STATIC 0x00040001 #define DV_E_FORMATETC 0x80040064 #define DV_E_DVASPECT 0x8004006B #define DV_E_LINDEX 0x80040068 #define DV_E_TYMED 0x80040069 #define CLASS_E_NOAGGREGATION 0x80040110 #define CLASS_E_CLASSNOTAVAILABLE 0x80040111 #define DATA_S_SAMEFORMATETC 0x80040130 #define E_ACCESSDENIED 0x80070005 #define E_HANDLE 0x80070006 #define E_OUTOFMEMORY 0x8007000E #define E_INVALIDARG 0x80070057 /*#define OLE_E_FIRST 0x80040000L */ /*#define OLE_E_LAST 0x800400FFL */ /*#define OLE_S_FIRST 0x00040000L */ /*#define OLE_S_LAST 0x000400FFL */ #define MK_S_REDUCED_TO_SELF 0x000401E2 #define MK_S_ME 0x000401E4 #define MK_S_HIM 0x000401E5 #define MK_S_US 0x000401E6 #define MK_S_MONIKERALREADYREGISTERED 0x000401E7 #define MK_E_EXCEEDEDDEADLINE 0x800401E1 #define MK_E_NEEDGENERIC 0x800401E2 #define MK_E_UNAVAILABLE 0x800401E3 #define MK_E_SYNTAX 0x800401E4 #define MK_E_NOOBJECT 0x800401E5 #define MK_E_INVALIDEXTENSION 0x800401E6 #define MK_E_INTERMEDIATEINTERFACENOTSUPPORTED 0x800401E7 #define MK_E_NOTBINDABLE 0x800401E8 #define MK_E_NOTBOUND 0x800401E9 #define MK_E_CANTOPENFILE 0x800401EA #define MK_E_MIUSTBOTHERUSER 0x800401EB #define MK_E_NOINVERSE 0x800401EC #define MK_E_NOSTORAGE 0x800401ED #define MK_E_NOPREFIX 0x800401EE #define STG_E_INVALIDFUNCTION 0x80030001 #define STG_E_FILENOTFOUND 0x80030002 #define STG_E_PATHNOTFOUND 0x80030003 #define STG_E_TOOMANYOPENFILES 0x80030004 #define STG_E_ACCESSDENIED 0x80030005 #define STG_E_INVALIDHANDLE 0x80030006 #define STG_E_INSUFFICIENTMEMORY 0x80030008 #define STG_E_INVALIDPOINTER 0x80030009 #define STG_E_NOMOREFILES 0x80030012 #define STG_E_DISKISWRITEPROTECTED 0x80030013 #define STG_E_SEEKERROR 0x80030019 #define STG_E_WRITEFAULT 0x8003001D #define STG_E_READFAULT 0x8003001E #define STG_E_SHAREVIOLATION 0x80030020 #define STG_E_LOCKVIOLATION 0x80030021 #define STG_E_FILEALREADYEXISTS 0x80030050 #define STG_E_INVALIDPARAMETER 0x80030057 #define STG_E_MEDIUMFULL 0x80030070 #define STG_E_ABNORMALAPIEXIT 0x800300FA #define STG_E_INVALIDHEADER 0x800300FB #define STG_E_INVALIDNAME 0x800300FC #define STG_E_UNKNOWN 0x800300FD #define STG_E_UNIMPLEMENTEDFUNCTION 0x800300FE #define STG_E_INVALIDFLAG 0x800300FF #define STG_E_INUSE 0x80030100 #define STG_E_NOTCURRENT 0x80030101 #define STG_E_REVERTED 0x80030102 #define STG_E_CANTSAVE 0x80030103 #define STG_E_OLDFORMAT 0x80030104 #define STG_E_OLDDLL 0x80030105 #define STG_E_SHAREREQUIRED 0x80030106 #define STG_E_NOTFILEBASEDSTORAGE 0x80030107 #define STG_E_EXTANTMARSHALLINGS 0x80030108 #define CONVERT10_E_OLESTREAM_GET 0x800401C0 #define CONVERT10_E_OLESTREAM_PUT 0x800401C1 #define CONVERT10_E_OLESTREAM_FMT 0x800401C2 #define CONVERT10_E_OLESTREAM_BITMAP_TO_DIB 0x800401C3 #define CONVERT10_E_STG_FMT 0x800401C4 #define CONVERT10_E_STG_NO_STD_STREAM 0x800401C5 #define CONVERT10_E_STG_DIB_TO_BITMAP 0x800401C6 /* alten versionen #define E_NOTIMPL 0x80000001 #define E_OUTOFMEMORY 0x80000002 #define E_INVALIDARG 0x80000003 #define E_NOINTERFACE 0x80000004 #define E_POINTER 0x80000005 #define E_HANDLE 0x80000006 #define E_ABORT 0x80000007 #define E_FAIL 0x80000008 #define E_ACCESSDENIED 0x80000009 */ /* Obtained from lcc-win32 include files */ #define GDI_ERROR 0xffffffff /* registry errors */ #define REGDB_E_READREGDB 0x80040150 #define REGDB_E_CLASSNOTREG 0x80040154 #define INPLACE_E_NOTUNDOABLE 0x800401A0 #define INPLACE_E_NOTOOLSPACE 0x800401A1 #define DATA_E_FORMATETC DV_E_FORMATETC #define CLASSFACTORY_E_FIRST 0x80040110L #define CLASSFACTORY_E_LAST 0x8004011FL #define CLASSFACTORY_S_FIRST 0x80040110L #define CLASSFACTORY_S_LAST 0x8004011FL #define CLASS_E_NOTLICENSED (CLASSFACTORY_E_FIRST+2) #define CLASS_E_NOAGGREGATION 0x80040110 #define CLASS_E_CLASSNOTAVAILABLE 0x80040111 #define OLEOBJ_E_NOVERBS 0x00040180L #define OLEOBJ_E_INVALIDVERB 0x00040181L #define OLEOBJ_S_INVALIDVERB 0x00040180L #endif /* __WINE_WINERROR_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/winestring.h��������������������������������������������������������0000644�0001750�0001750�00000000545�14647725152�016561� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_WINE_WINESTRING_H #define __WINE_WINE_WINESTRING_H #include "windef.h" LPWSTR WINAPI lstrcpyAtoW(LPWSTR,LPCSTR); LPSTR WINAPI lstrcpyWtoA(LPSTR,LPCWSTR); LPWSTR WINAPI lstrcpynAtoW(LPWSTR,LPCSTR,INT); LPSTR WINAPI lstrcpynWtoA(LPSTR,LPCWSTR,INT); #define lstrncmpiA strncasecmp #endif /* __WINE_WINE_WINESTRING_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/ext.h���������������������������������������������������������������0000644�0001750�0001750�00000000761�14647725152�015170� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef loader_ext_h #define loader_ext_h #include "windef.h" #include <xine/attributes.h> extern LPVOID FILE_dommap( int unix_handle, LPVOID start, DWORD size_high, DWORD size_low, DWORD offset_high, DWORD offset_low, int prot, int flags ); extern int FILE_munmap( LPVOID start, DWORD size_high, DWORD size_low ); extern int wcsnicmp(const unsigned short* s1, const unsigned short* s2, int n); extern int XINE_FORMAT_PRINTF(1, 2) __vprintf( const char *format, ... ); #endif ���������������xine-lib-1.2/src/libw32dll/wine/heap.h��������������������������������������������������������������0000644�0001750�0001750�00000003603�14647725152�015303� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Win32 heap definitions * * Copyright 1996 Alexandre Julliard */ #ifndef __WINE_HEAP_H #define __WINE_HEAP_H #include "config.h" #include "winbase.h" extern HANDLE SystemHeap; extern HANDLE SegptrHeap; extern int HEAP_IsInsideHeap( HANDLE heap, DWORD flags, LPCVOID ptr ); extern SEGPTR HEAP_GetSegptr( HANDLE heap, DWORD flags, LPCVOID ptr ); extern LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str ); extern LPWSTR HEAP_strdupW( HANDLE heap, DWORD flags, LPCWSTR str ); extern LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str ); extern LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str ); /* SEGPTR helper macros */ #define SEGPTR_ALLOC(size) \ (HeapAlloc( SegptrHeap, 0, (size) )) #define SEGPTR_NEW(type) \ ((type *)HeapAlloc( SegptrHeap, 0, sizeof(type) )) #define SEGPTR_STRDUP(str) \ (HIWORD(str) ? HEAP_strdupA( SegptrHeap, 0, (str) ) : (LPSTR)(str)) #define SEGPTR_STRDUP_WtoA(str) \ (HIWORD(str) ? HEAP_strdupWtoA( SegptrHeap, 0, (str) ) : (LPSTR)(str)) #if 0 /* causes undefined symbols */ /* define an inline function, a macro won't do */ static inline SEGPTR WINE_UNUSED SEGPTR_Get(LPCVOID ptr) { return (HIWORD(ptr) ? HEAP_GetSegptr( SegptrHeap, 0, ptr ) : (SEGPTR)ptr); } #endif #define SEGPTR_GET(ptr) SEGPTR_Get(ptr) #define SEGPTR_FREE(ptr) \ (HIWORD(ptr) ? HeapFree( SegptrHeap, 0, (ptr) ) : 0) /* system heap private data */ /* you must lock the system heap before using this structure */ typedef struct { void *gdi; /* GDI heap */ void *user; /* USER handle table */ void *cursor; /* cursor information */ void *queue; /* message queues descriptor */ void *win; /* windows descriptor */ void *root; /* X11 root window */ } SYSTEM_HEAP_DESCR; extern SYSTEM_HEAP_DESCR *SystemHeapDescr; #endif /* __WINE_HEAP_H */ �����������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/driver.c������������������������������������������������������������0000644�0001750�0001750�00000010206�14647725152�015651� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "config.h" #include <stdio.h> #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #include <stdlib.h> #ifdef __FreeBSD__ #include <sys/time.h> #endif #include "win32.h" #include "driver.h" #include "pe_image.h" #include "winreg.h" #include "vfw.h" #include "registry.h" #include "ldt_keeper.h" #include "ext.h" #include "debugtools.h" #if 1 /* * STORE_ALL/REST_ALL seems like an attempt to workaround problems due to * WINAPI/no-WINAPI bustage. * * There should be no need for the STORE_ALL/REST_ALL hack once all * function definitions agree with their prototypes (WINAPI-wise) and * we make sure, that we do not call these functions without a proper * prototype in scope. */ #define STORE_ALL #define REST_ALL #else // this asm code is no longer needed #define STORE_ALL \ __asm__ __volatile__ ( \ "push %%ebx\n\t" \ "push %%ecx\n\t" \ "push %%edx\n\t" \ "push %%esi\n\t" \ "push %%edi\n\t"::) #define REST_ALL \ __asm__ __volatile__ ( \ "pop %%edi\n\t" \ "pop %%esi\n\t" \ "pop %%edx\n\t" \ "pop %%ecx\n\t" \ "pop %%ebx\n\t"::) #endif #if 0 static int needs_free=0; void SetCodecPath(const char* path) { if(needs_free)free(win32_def_path); if(path==0) { win32_def_path=WIN32_PATH; needs_free=0; return; } win32_def_path = (char*) malloc(strlen(path)+1); strcpy(win32_def_path, path); needs_free=1; } #endif static DWORD dwDrvID = 0; LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT message, LPARAM lParam1, LPARAM lParam2) { DRVR* module=(DRVR*)hDriver; int result; #ifndef __svr4__ char qw[300]; #endif #ifdef DETAILED_OUT printf("SendDriverMessage: driver %X, message %X, arg1 %X, arg2 %X\n", hDriver, message, lParam1, lParam2); #endif if (!module || !module->hDriverModule || !module->DriverProc) return -1; #ifndef __svr4__ __asm__ __volatile__ ("fsave (%0)\n\t": :"r"(&qw)); #endif #ifdef LDT_paranoia Setup_FS_Segment(); #endif STORE_ALL; result=module->DriverProc(module->dwDriverID, hDriver, message, lParam1, lParam2); REST_ALL; #ifndef __svr4__ __asm__ __volatile__ ("frstor (%0)\n\t": :"r"(&qw)); #endif #ifdef DETAILED_OUT printf("\t\tResult: %X\n", result); #endif return result; } void DrvClose(HDRVR hDriver) { if (hDriver) { DRVR* d = (DRVR*)hDriver; if (d->hDriverModule) { #ifdef LDT_paranoia Setup_FS_Segment(); #endif if (d->DriverProc) { SendDriverMessage(hDriver, DRV_CLOSE, 0, 0); d->dwDriverID = 0; SendDriverMessage(hDriver, DRV_FREE, 0, 0); } FreeLibrary(d->hDriverModule); } free(d); } CodecRelease(); } //DrvOpen(LPCSTR lpszDriverName, LPCSTR lpszSectionName, LPARAM lParam2) HDRVR DrvOpen(LPARAM lParam2) { NPDRVR hDriver; // int i; char unknown[0x124]; const char* filename = (const char*) ((ICOPEN*) lParam2)->pV1Reserved; #ifdef LDT_paranoia Setup_LDT_Keeper(); #endif printf("Loading codec DLL: '%s'\n",filename); hDriver = (NPDRVR) malloc(sizeof(DRVR)); if (!hDriver) return ((HDRVR) 0); memset((void*)hDriver, 0, sizeof(DRVR)); CodecAlloc(); #ifdef LDT_paranoia Setup_FS_Segment(); #endif hDriver->hDriverModule = LoadLibraryA(filename); if (!hDriver->hDriverModule) { printf("Can't open library %s\n", filename); DrvClose((HDRVR)hDriver); return ((HDRVR) 0); } hDriver->DriverProc = (DRIVERPROC) GetProcAddress(hDriver->hDriverModule, "DriverProc"); if (!hDriver->DriverProc) { printf("Library %s is not a valid VfW/ACM codec\n", filename); DrvClose((HDRVR)hDriver); return ((HDRVR) 0); } TRACE("DriverProc == %p\n", hDriver->DriverProc); SendDriverMessage((HDRVR)hDriver, DRV_LOAD, 0, 0); TRACE("DRV_LOAD Ok!\n"); SendDriverMessage((HDRVR)hDriver, DRV_ENABLE, 0, 0); TRACE("DRV_ENABLE Ok!\n"); hDriver->dwDriverID = ++dwDrvID; // generate new id // open driver and remmeber proper DriverID hDriver->dwDriverID = SendDriverMessage((HDRVR)hDriver, DRV_OPEN, (LPARAM) unknown, lParam2); TRACE("DRV_OPEN Ok!(%lX)\n", hDriver->dwDriverID); printf("Loaded DLL driver %s\n", filename); return (HDRVR)hDriver; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/avifmt.h������������������������������������������������������������0000644�0001750�0001750�00000016624�14647725152�015663� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/**************************************************************************** * * AVIFMT - AVI file format definitions * ****************************************************************************/ #ifndef AVIFMT #define AVIFMT #ifndef NOAVIFMT #ifndef __WINE_WINDEF_H #include "windef.h" #endif #ifndef __WINE_MMSYSTEM_H #ifndef __WINE_MSACM_H typedef DWORD FOURCC; #endif #endif #ifdef _MSC_VER #pragma warning(disable:4200) #endif /* The following is a short description of the AVI file format. Please * see the accompanying documentation for a full explanation. * * An AVI file is the following RIFF form: * * RIFF('AVI' * LIST('hdrl' * avih(<MainAVIHeader>) * LIST ('strl' * strh(<Stream header>) * strf(<Stream format>) * ... additional header data * LIST('movi' * { LIST('rec' * SubChunk... * ) * | SubChunk } .... * ) * [ <AVIIndex> ] * ) * * The main file header specifies how many streams are present. For * each one, there must be a stream header chunk and a stream format * chunk, enlosed in a 'strl' LIST chunk. The 'strf' chunk contains * type-specific format information; for a video stream, this should * be a BITMAPINFO structure, including palette. For an audio stream, * this should be a WAVEFORMAT (or PCMWAVEFORMAT) structure. * * The actual data is contained in subchunks within the 'movi' LIST * chunk. The first two characters of each data chunk are the * stream number with which that data is associated. * * Some defined chunk types: * Video Streams: * ##db: RGB DIB bits * ##dc: RLE8 compressed DIB bits * ##pc: Palette Change * * Audio Streams: * ##wb: waveform audio bytes * * The grouping into LIST 'rec' chunks implies only that the contents of * the chunk should be read into memory at the same time. This * grouping is used for files specifically intended to be played from * CD-ROM. * * The index chunk at the end of the file should contain one entry for * each data chunk in the file. * * Limitations for the current software: * Only one video stream and one audio stream are allowed. * The streams must start at the beginning of the file. * * * To register codec types please obtain a copy of the Multimedia * Developer Registration Kit from: * * Microsoft Corporation * Multimedia Systems Group * Product Marketing * One Microsoft Way * Redmond, WA 98052-6399 * */ #ifndef mmioFOURCC #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ ( (DWORD)(BYTE)(ch0) | ( (DWORD)(BYTE)(ch1) << 8 ) | \ ( (DWORD)(BYTE)(ch2) << 16 ) | ( (DWORD)(BYTE)(ch3) << 24 ) ) #endif /* Macro to make a TWOCC out of two characters */ #ifndef aviTWOCC #define aviTWOCC(ch0, ch1) ((WORD)(BYTE)(ch0) | ((WORD)(BYTE)(ch1) << 8)) #endif typedef WORD TWOCC; /* form types, list types, and chunk types */ #define formtypeAVI mmioFOURCC('A', 'V', 'I', ' ') #define listtypeAVIHEADER mmioFOURCC('h', 'd', 'r', 'l') #define ckidAVIMAINHDR mmioFOURCC('a', 'v', 'i', 'h') #define listtypeSTREAMHEADER mmioFOURCC('s', 't', 'r', 'l') #define ckidSTREAMHEADER mmioFOURCC('s', 't', 'r', 'h') #define ckidSTREAMFORMAT mmioFOURCC('s', 't', 'r', 'f') #define ckidSTREAMHANDLERDATA mmioFOURCC('s', 't', 'r', 'd') #define ckidSTREAMNAME mmioFOURCC('s', 't', 'r', 'n') #define listtypeAVIMOVIE mmioFOURCC('m', 'o', 'v', 'i') #define listtypeAVIRECORD mmioFOURCC('r', 'e', 'c', ' ') #define ckidAVINEWINDEX mmioFOURCC('i', 'd', 'x', '1') /* ** Stream types for the <fccType> field of the stream header. */ #define streamtypeVIDEO mmioFOURCC('v', 'i', 'd', 's') #define streamtypeAUDIO mmioFOURCC('a', 'u', 'd', 's') #define streamtypeMIDI mmioFOURCC('m', 'i', 'd', 's') #define streamtypeTEXT mmioFOURCC('t', 'x', 't', 's') /* Basic chunk types */ #define cktypeDIBbits aviTWOCC('d', 'b') #define cktypeDIBcompressed aviTWOCC('d', 'c') #define cktypePALchange aviTWOCC('p', 'c') #define cktypeWAVEbytes aviTWOCC('w', 'b') /* Chunk id to use for extra chunks for padding. */ #define ckidAVIPADDING mmioFOURCC('J', 'U', 'N', 'K') /* ** Useful macros ** ** Warning: These are nasty macro, and MS C 6.0 compiles some of them ** incorrectly if optimizations are on. Ack. */ /* Macro to get stream number out of a FOURCC ckid */ #define FromHex(n) (((n) >= 'A') ? ((n) + 10 - 'A') : ((n) - '0')) #define StreamFromFOURCC(fcc) ((WORD) ((FromHex(LOBYTE(LOWORD(fcc))) << 4) + \ (FromHex(HIBYTE(LOWORD(fcc)))))) /* Macro to get TWOCC chunk type out of a FOURCC ckid */ #define TWOCCFromFOURCC(fcc) HIWORD(fcc) /* Macro to make a ckid for a chunk out of a TWOCC and a stream number ** from 0-255. */ #define ToHex(n) ((BYTE) (((n) > 9) ? ((n) - 10 + 'A') : ((n) + '0'))) #define MAKEAVICKID(tcc, stream) \ MAKELONG((ToHex((stream) & 0x0f) << 8) | \ (ToHex(((stream) & 0xf0) >> 4)), tcc) /* ** Main AVI File Header */ /* flags for use in <dwFlags> in AVIFileHdr */ #define AVIF_HASINDEX 0x00000010 // Index at end of file? #define AVIF_MUSTUSEINDEX 0x00000020 #define AVIF_ISINTERLEAVED 0x00000100 #define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? #define AVIF_WASCAPTUREFILE 0x00010000 #define AVIF_COPYRIGHTED 0x00020000 /* The AVI File Header LIST chunk should be padded to this size */ #define AVI_HEADERSIZE 2048 // size of AVI header list typedef struct { DWORD dwMicroSecPerFrame; // frame display rate (or 0L) DWORD dwMaxBytesPerSec; // max. transfer rate DWORD dwPaddingGranularity; // pad to multiples of this // size; normally 2K. DWORD dwFlags; // the ever-present flags DWORD dwTotalFrames; // # frames in file DWORD dwInitialFrames; DWORD dwStreams; DWORD dwSuggestedBufferSize; DWORD dwWidth; DWORD dwHeight; DWORD dwReserved[4]; } MainAVIHeader; /* ** Stream header */ #define AVISF_DISABLED 0x00000001 #define AVISF_VIDEO_PALCHANGES 0x00010000 typedef struct { FOURCC fccType; FOURCC fccHandler; DWORD dwFlags; /* Contains AVITF_* flags */ WORD wPriority; WORD wLanguage; DWORD dwInitialFrames; DWORD dwScale; DWORD dwRate; /* dwRate / dwScale == samples/second */ DWORD dwStart; DWORD dwLength; /* In units above... */ DWORD dwSuggestedBufferSize; DWORD dwQuality; DWORD dwSampleSize; RECT rcFrame; } AVIStreamHeader; /* Flags for index */ #define AVIIF_LIST 0x00000001L // chunk is a 'LIST' #define AVIIF_KEYFRAME 0x00000010L // this frame is a key frame. #define AVIIF_NOTIME 0x00000100L // this frame doesn't take any time #define AVIIF_COMPUSE 0x0FFF0000L // these bits are for compressor use #define FOURCC_RIFF mmioFOURCC('R', 'I', 'F', 'F') #define FOURCC_LIST mmioFOURCC('L', 'I', 'S', 'T') typedef struct { DWORD ckid; DWORD dwFlags; DWORD dwChunkOffset; // Position of chunk DWORD dwChunkLength; // Length of chunk } AVIINDEXENTRY; #define AVISTREAMREAD_CONVENIENT (-1L) /* ** Palette change chunk ** ** Used in video streams. */ #endif /* NOAVIFMT */ #endif ������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/driver.h������������������������������������������������������������0000644�0001750�0001750�00000010546�14647725152�015665� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Drivers definitions */ #ifndef __WINE_DRIVER_H #define __WINE_DRIVER_H #include "windef.h" #define MMSYSERR_BASE 0 #define MMSYSERR_NOERROR 0 /* no error */ #define MMSYSERR_ERROR (MMSYSERR_BASE + 1) /* unspecified error */ #define MMSYSERR_BADDEVICEID (MMSYSERR_BASE + 2) /* device ID out of range */ #define MMSYSERR_NOTENABLED (MMSYSERR_BASE + 3) /* driver failed enable */ #define MMSYSERR_ALLOCATED (MMSYSERR_BASE + 4) /* device already allocated */ #define MMSYSERR_INVALHANDLE (MMSYSERR_BASE + 5) /* device handle is invalid */ #define MMSYSERR_NODRIVER (MMSYSERR_BASE + 6) /* no device driver present */ #define MMSYSERR_NOMEM (MMSYSERR_BASE + 7) /* memory allocation error */ #define MMSYSERR_NOTSUPPORTED (MMSYSERR_BASE + 8) /* function isn't supported */ #define MMSYSERR_BADERRNUM (MMSYSERR_BASE + 9) /* error value out of range */ #define MMSYSERR_INVALFLAG (MMSYSERR_BASE + 10) /* invalid flag passed */ #define MMSYSERR_INVALPARAM (MMSYSERR_BASE + 11) /* invalid parameter passed */ #define MMSYSERR_LASTERROR (MMSYSERR_BASE + 11) /* last error in range */ #define DRV_LOAD 0x0001 #define DRV_ENABLE 0x0002 #define DRV_OPEN 0x0003 #define DRV_CLOSE 0x0004 #define DRV_DISABLE 0x0005 #define DRV_FREE 0x0006 #define DRV_CONFIGURE 0x0007 #define DRV_QUERYCONFIGURE 0x0008 #define DRV_INSTALL 0x0009 #define DRV_REMOVE 0x000A #define DRV_EXITSESSION 0x000B #define DRV_EXITAPPLICATION 0x000C #define DRV_POWER 0x000F #define DRV_RESERVED 0x0800 #define DRV_USER 0x4000 #define DRVCNF_CANCEL 0x0000 #define DRVCNF_OK 0x0001 #define DRVCNF_RESTART 0x0002 #define DRVEA_NORMALEXIT 0x0001 #define DRVEA_ABNORMALEXIT 0x0002 #define DRV_SUCCESS 0x0001 #define DRV_FAILURE 0x0000 #define GND_FIRSTINSTANCEONLY 0x00000001 #define GND_FORWARD 0x00000000 #define GND_REVERSE 0x00000002 typedef struct { DWORD dwDCISize; LPCSTR lpszDCISectionName; LPCSTR lpszDCIAliasName; } DRVCONFIGINFO16, *LPDRVCONFIGINFO16; typedef struct { DWORD dwDCISize; LPCWSTR lpszDCISectionName; LPCWSTR lpszDCIAliasName; } DRVCONFIGINFO, *LPDRVCONFIGINFO; /* GetDriverInfo16 references this structure, so this a struct defined * in the Win16 API. * GetDriverInfo has been deprecated in Win32. */ typedef struct { UINT16 length; HDRVR16 hDriver; HINSTANCE16 hModule; CHAR szAliasName[128]; } DRIVERINFOSTRUCT16, *LPDRIVERINFOSTRUCT16; LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, LPARAM dwParam1, LPARAM dwParam2); LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hdrvr, UINT Msg, LPARAM lParam1, LPARAM lParam2); HDRVR16 WINAPI OpenDriver16(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2); HDRVR WINAPI OpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2); HDRVR WINAPI OpenDriverW(LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2); #define OpenDriver WINELIB_NAME_AW(OpenDriver) LRESULT WINAPI CloseDriver16(HDRVR16 hDriver, LPARAM lParam1, LPARAM lParam2); LRESULT WINAPI CloseDriver(HDRVR hDriver, LPARAM lParam1, LPARAM lParam2); LRESULT WINAPI SendDriverMessage16( HDRVR16 hDriver, UINT16 message, LPARAM lParam1, LPARAM lParam2 ); LRESULT WINAPI SendDriverMessage( HDRVR hDriver, UINT message, LPARAM lParam1, LPARAM lParam2 ); HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDriver); HMODULE WINAPI GetDriverModuleHandle(HDRVR hDriver); DWORD WINAPI GetDriverFlags( HDRVR hDriver ); #ifdef __WINE__ /* this call (GetDriverFlags) is not documented, nor the flags returned. * here are Wine only definitions */ #define WINE_GDF_EXIST 0x80000000 #define WINE_GDF_16BIT 0x10000000 #endif #ifdef __cplusplus extern "C" { #endif void CodecAlloc(void); void CodecRelease(void); #include "vfw.h" extern HDRVR VFWAPI DrvOpen(LPARAM lParam2); extern void DrvClose(HDRVR hdrvr); #ifdef __cplusplus } #endif #endif /* __WINE_DRIVER_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/win32.h�������������������������������������������������������������0000644�0001750�0001750�00000001354�14647725152�015331� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef loader_win32_h #define loader_win32_h #include <time.h> #include "windef.h" #include "winbase.h" #include "com.h" extern const char* win32_def_path; extern void my_garbagecollection(void); typedef struct { UINT uDriverSignature; HINSTANCE hDriverModule; DRIVERPROC DriverProc; DWORD dwDriverID; } DRVR; typedef DRVR *PDRVR; typedef DRVR *NPDRVR; typedef DRVR *LPDRVR; typedef struct tls_s tls_t; extern void* LookupExternal(const char* library, int ordinal); extern void* LookupExternalByName(const char* library, const char* name); extern int expRegisterClassA(const void/*WNDCLASSA*/ *wc); extern int expUnregisterClassA(const char *className, HINSTANCE hInstance); #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/module.h������������������������������������������������������������0000644�0001750�0001750�00000007036�14647725152�015657� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Module definitions * * Copyright 1995 Alexandre Julliard */ #ifndef __WINE_MODULE_H #define __WINE_MODULE_H #include "windef.h" #include "pe_image.h" typedef struct { BYTE type; BYTE flags; BYTE segnum; WORD offs WINE_PACKED; } ET_ENTRY; typedef struct { WORD first; /* ordinal */ WORD last; /* ordinal */ WORD next; /* bundle */ } ET_BUNDLE; /* In-memory segment table */ typedef struct { WORD filepos; /* Position in file, in sectors */ WORD size; /* Segment size on disk */ WORD flags; /* Segment flags */ WORD minsize; /* Min. size of segment in memory */ HANDLE16 hSeg; /* Selector or handle (selector - 1) */ /* of segment in memory */ } SEGTABLEENTRY; /* Self-loading modules contain this structure in their first segment */ #include "pshpack1.h" typedef struct { WORD version; /* Must be "A0" (0x3041) */ WORD reserved; FARPROC16 BootApp; /* startup procedure */ FARPROC16 LoadAppSeg; /* procedure to load a segment */ FARPROC16 reserved2; FARPROC16 MyAlloc; /* memory allocation procedure, * wine must write this field */ FARPROC16 EntryAddrProc; FARPROC16 ExitProc; /* exit procedure */ WORD reserved3[4]; FARPROC16 SetOwner; /* Set Owner procedure, exported by wine */ } SELFLOADHEADER; /* Parameters for LoadModule() */ typedef struct { HGLOBAL16 hEnvironment; /* Environment segment */ SEGPTR cmdLine WINE_PACKED; /* Command-line */ SEGPTR showCmd WINE_PACKED; /* Code for ShowWindow() */ SEGPTR reserved WINE_PACKED; } LOADPARAMS16; typedef struct { LPSTR lpEnvAddress; LPSTR lpCmdLine; UINT16 *lpCmdShow; DWORD dwReserved; } LOADPARAMS; #include "poppack.h" /* internal representation of 32bit modules. per process. */ typedef enum { MODULE32_PE = 1, MODULE32_ELF, MODULE32_ELFDLL } MODULE32_TYPE; typedef struct _wine_modref { struct _wine_modref *next; struct _wine_modref *prev; MODULE32_TYPE type; union { PE_MODREF pe; ELF_MODREF elf; } binfmt; HMODULE module; int nDeps; struct _wine_modref **deps; int flags; int refCount; char *filename; char *modname; char *short_filename; char *short_modname; } WINE_MODREF; #define WINE_MODREF_INTERNAL 0x00000001 #define WINE_MODREF_NO_DLL_CALLS 0x00000002 #define WINE_MODREF_PROCESS_ATTACHED 0x00000004 #define WINE_MODREF_LOAD_AS_DATAFILE 0x00000010 #define WINE_MODREF_DONT_RESOLVE_REFS 0x00000020 #define WINE_MODREF_MARKER 0x80000000 /* Resource types */ typedef struct resource_typeinfo_s NE_TYPEINFO; typedef struct resource_nameinfo_s NE_NAMEINFO; #define NE_SEG_TABLE(pModule) \ ((SEGTABLEENTRY *)((char *)(pModule) + (pModule)->seg_table)) #define NE_MODULE_TABLE(pModule) \ ((WORD *)((char *)(pModule) + (pModule)->modref_table)) #define NE_MODULE_NAME(pModule) \ (((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName) struct modref_list_t; typedef struct modref_list_t { WINE_MODREF* wm; struct modref_list_t *next; struct modref_list_t *prev; } modref_list; /* module.c */ extern FARPROC MODULE_GetProcAddress( HMODULE hModule, LPCSTR function, WIN_BOOL snoop ); extern WINE_MODREF *MODULE32_LookupHMODULE( HMODULE hModule ); extern WINE_MODREF *MODULE_FindModule( LPCSTR path ); /* resource.c */ extern INT WINAPI AccessResource(HMODULE,HRSRC); #endif /* __WINE_MODULE_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/pe_image.c����������������������������������������������������������0000644�0001750�0001750�00000077011�14647725152�016133� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 1994 Eric Youndale & Erik Bos * Copyright 1995 Martin von Löwis * Copyright 1996-98 Marcus Meissner * * based on Eric Youndale's pe-test and: * * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP * make that: * ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP */ /* Notes: * Before you start changing something in this file be aware of the following: * * - There are several functions called recursively. In a very subtle and * obscure way. DLLs can reference each other recursively etc. * - If you want to enhance, speed up or clean up something in here, think * twice WHY it is implemented in that strange way. There is usually a reason. * Though sometimes it might just be lazyness ;) * - In PE_MapImage, right before fixup_imports() all external and internal * state MUST be correct since this function can be called with the SAME image * AGAIN. (Thats recursion for you.) That means MODREF.module and * NE_MODULE.module32. * - Sometimes, we can't use Linux mmap() to mmap() the images directly. * * The problem is, that there is not direct 1:1 mapping from a diskimage and * a memoryimage. The headers at the start are mapped linear, but the sections * are not. Older x86 pe binaries are 512 byte aligned in file and 4096 byte * aligned in memory. Linux likes them 4096 byte aligned in memory (due to * x86 pagesize, this cannot be fixed without a rather large kernel rewrite) * and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM) * and other byte blocksizes, we can't always do this. We *can* do this for * newer pe binaries produced by MSVC 5 and later, since they are also aligned * to 4096 byte boundaries on disk. */ #include "config.h" #include <errno.h> #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> #endif #ifdef HAVE_ALLOCA_H #include <alloca.h> #endif #include "windef.h" #include "winbase.h" #include "winerror.h" #include "heap.h" #include "pe_image.h" #include "module.h" #include "debugtools.h" #include "ext.h" #include "win32.h" #define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x))) #define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta)) extern void* LookupExternal(const char* library, int ordinal); extern void* LookupExternalByName(const char* library, const char* name); static void dump_exports( HMODULE hModule ) { char *Module; unsigned int i; u_short *ordinal; u_long *function,*functions; u_char **name; unsigned int load_addr = hModule; DWORD rva_start = PE_HEADER(hModule)->OptionalHeader .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start); Module = (char*)RVA(pe_exports->Name); TRACE("*******EXPORT DATA*******\n"); TRACE("Module name is %s, %ld functions, %ld names\n", Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames); ordinal=(u_short*) RVA(pe_exports->AddressOfNameOrdinals); functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions); name=(u_char**) RVA(pe_exports->AddressOfNames); TRACE(" Ord RVA Addr Name\n" ); for (i=0;i<pe_exports->NumberOfFunctions;i++, function++) { if (!*function) continue; if (TRACE_ON(win32)) { unsigned int j; DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, RVA(*function) ); for (j = 0; j < pe_exports->NumberOfNames; j++) if (ordinal[j] == i) { DPRINTF( " %s", (char*)RVA(name[j]) ); break; } if ((*function >= rva_start) && (*function <= rva_end)) DPRINTF(" (forwarded -> %s)", (char *)RVA(*function)); DPRINTF("\n"); } } } /* Look up the specified function or ordinal in the exportlist: * If it is a string: * - look up the name in the Name list. * - look up the ordinal with that index. * - use the ordinal as offset into the functionlist * If it is a ordinal: * - use ordinal-pe_export->Base as offset into the functionlist */ FARPROC PE_FindExportedFunction( WINE_MODREF *wm, LPCSTR funcName, WIN_BOOL snoop ) { u_short * ordinals; u_long * function; u_char ** name, *ename = NULL; unsigned int ordinal; PE_MODREF *pem = &(wm->binfmt.pe); IMAGE_EXPORT_DIRECTORY *exports = pem->pe_export; unsigned int load_addr = wm->module; u_long rva_start, rva_end, addr; char * forward; if (HIWORD(funcName)) TRACE("(%s)\n",funcName); else TRACE("(%d)\n",(int)funcName); if (!exports) { /* Not a fatal problem, some apps do * GetProcAddress(0,"RegisterPenApp") which triggers this * case. */ WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,pem); return NULL; } ordinals= (u_short*) RVA(exports->AddressOfNameOrdinals); function= (u_long*) RVA(exports->AddressOfFunctions); name = (u_char **) RVA(exports->AddressOfNames); forward = NULL; rva_start = PE_HEADER(wm->module)->OptionalHeader .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader .DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; if (HIWORD(funcName)) { int min = 0, max = exports->NumberOfNames - 1; unsigned int i; while (min <= max) { int res, pos = (min + max) / 2; ename = RVA(name[pos]); if (!(res = strcmp( ename, funcName ))) { ordinal = ordinals[pos]; goto found; } if (res > 0) max = pos - 1; else min = pos + 1; } for (i = 0; i < exports->NumberOfNames; i++) { ename = RVA(name[i]); if (!strcmp( ename, funcName )) { ERR( "%s.%s required a linear search\n", wm->modname, funcName ); ordinal = ordinals[i]; goto found; } } return NULL; } else { ordinal = LOWORD(funcName) - exports->Base; if (snoop && name) { unsigned int i; for (i = 0; i < exports->NumberOfNames; i++) if (ordinals[i] == ordinal) { ename = RVA(name[i]); break; } } } found: if (ordinal >= exports->NumberOfFunctions) { TRACE(" ordinal %ld out of range!\n", ordinal + exports->Base ); return NULL; } addr = function[ordinal]; if (!addr) return NULL; if ((addr < rva_start) || (addr >= rva_end)) { FARPROC proc = RVA(addr); if (snoop) { // if (!ename) ename = "@"; // proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc); TRACE("SNOOP_GetProcAddress n/a\n"); } return proc; } else { WINE_MODREF *wm; char *forward = RVA(addr); char module[256]; char *end = strchr(forward, '.'); if (!end) return NULL; if (end - forward >= (int)sizeof(module)) return NULL; memcpy( module, forward, end - forward ); module[end-forward] = 0; if (!(wm = MODULE_FindModule( module ))) { ERR("module not found for forward '%s'\n", forward ); return NULL; } return MODULE_GetProcAddress( wm->module, end + 1, snoop ); } } static DWORD fixup_imports( WINE_MODREF *wm ) { IMAGE_IMPORT_DESCRIPTOR *pe_imp; PE_MODREF *pem; unsigned int load_addr = wm->module; int i,characteristics_detection=1; const char *modname; assert(wm->type==MODULE32_PE); pem = &(wm->binfmt.pe); if (pem->pe_export) modname = (char*) RVA(pem->pe_export->Name); else modname = "<unknown>"; TRACE("Dumping imports list\n"); pe_imp = pem->pe_import; if (!pe_imp) return 0; /* We assume that we have at least one import with !0 characteristics and * detect broken imports with all characteristsics 0 (notably Borland) and * switch the detection off for them. */ for (i = 0; pe_imp->Name ; pe_imp++) { if (!i && !pe_imp->u.Characteristics) characteristics_detection = 0; if (characteristics_detection && !pe_imp->u.Characteristics) break; i++; } if (!i) return 0; wm->nDeps = i; wm->deps = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) ); /* load the imported modules. They are automatically * added to the modref list of the process. */ for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) { /* WINE_MODREF *wmImp; -- unused */ IMAGE_IMPORT_BY_NAME *pe_name; PIMAGE_THUNK_DATA import_list,thunk_list; char *name = (char *) RVA(pe_imp->Name); if (characteristics_detection && !pe_imp->u.Characteristics) break; //#warning FIXME: here we should fill imports TRACE("Loading imports for %s.dll\n", name); if (pe_imp->u.OriginalFirstThunk != 0) { TRACE("Microsoft style imports used\n"); import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk); thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk); while (import_list->u1.Ordinal) { if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) { int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal); // TRACE("--- Ordinal %s,%d\n", name, ordinal); thunk_list->u1.Function=LookupExternal(name, ordinal); } else { pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData); // TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint); thunk_list->u1.Function=LookupExternalByName(name, pe_name->Name); } import_list++; thunk_list++; } } else { TRACE("Borland style imports used\n"); thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk); while (thunk_list->u1.Ordinal) { if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) { int ordinal = IMAGE_ORDINAL(thunk_list->u1.Ordinal); TRACE("--- Ordinal %s.%d\n",name,ordinal); thunk_list->u1.Function=LookupExternal( name, ordinal); } else { pe_name=(PIMAGE_IMPORT_BY_NAME) RVA(thunk_list->u1.AddressOfData); TRACE("--- %s %s.%d\n", pe_name->Name,name,pe_name->Hint); thunk_list->u1.Function=LookupExternalByName( name, pe_name->Name); } thunk_list++; } } } return 0; } static int calc_vma_size( HMODULE hModule ) { int i; DWORD vma_size = 0; IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hModule); TRACE("Dump of segment table\n"); TRACE(" Name VSz Vaddr SzRaw Fileadr *Reloc *Lineum #Reloc #Linum Char\n"); for (i = 0; i< PE_HEADER(hModule)->FileHeader.NumberOfSections; i++) { TRACE("%8s: %4.4lx %8.8lx %8.8lx %8.8lx %8.8lx %8.8lx %4.4x %4.4x %8.8lx\n", pe_seg->Name, pe_seg->Misc.VirtualSize, pe_seg->VirtualAddress, pe_seg->SizeOfRawData, pe_seg->PointerToRawData, pe_seg->PointerToRelocations, pe_seg->PointerToLinenumbers, pe_seg->NumberOfRelocations, pe_seg->NumberOfLinenumbers, pe_seg->Characteristics); vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->SizeOfRawData); vma_size=max(vma_size, pe_seg->VirtualAddress+pe_seg->Misc.VirtualSize); pe_seg++; } return vma_size; } static void do_relocations( unsigned int load_addr, IMAGE_BASE_RELOCATION *r ) { int delta = load_addr - PE_HEADER(load_addr)->OptionalHeader.ImageBase; int hdelta = (delta >> 16) & 0xFFFF; int ldelta = delta & 0xFFFF; if(delta == 0) return; while(r->VirtualAddress) { char *page = (char*) RVA(r->VirtualAddress); int count = (r->SizeOfBlock - 8)/2; int i; TRACE_(fixup)("%x relocations for page %lx\n", count, r->VirtualAddress); for(i=0;i<count;i++) { int offset = r->TypeOffset[i] & 0xFFF; int type = r->TypeOffset[i] >> 12; // TRACE_(fixup)("patching %x type %x\n", offset, type); switch(type) { case IMAGE_REL_BASED_ABSOLUTE: break; case IMAGE_REL_BASED_HIGH: *(short*)(page+offset) += hdelta; break; case IMAGE_REL_BASED_LOW: *(short*)(page+offset) += ldelta; break; case IMAGE_REL_BASED_HIGHLOW: *(int*)(page+offset) += delta; break; case IMAGE_REL_BASED_HIGHADJ: FIXME("Don't know what to do with IMAGE_REL_BASED_HIGHADJ\n"); break; case IMAGE_REL_BASED_MIPS_JMPADDR: FIXME("Is this a MIPS machine ???\n"); break; default: FIXME("Unknown fixup type\n"); break; } } r = (IMAGE_BASE_RELOCATION*)((char*)r + r->SizeOfBlock); } } /********************************************************************** * PE_LoadImage * Load one PE format DLL/EXE into memory * * Unluckily we can't just mmap the sections where we want them, for * (at least) Linux does only support offsets which are page-aligned. * * BUT we have to map the whole image anyway, for Win32 programs sometimes * want to access them. (HMODULE32 point to the start of it) */ HMODULE PE_LoadImage( int handle, LPCSTR filename, WORD *version ) { HMODULE hModule; HANDLE mapping; IMAGE_NT_HEADERS *nt; IMAGE_SECTION_HEADER *pe_sec; IMAGE_DATA_DIRECTORY *dir; /* BY_HANDLE_FILE_INFORMATION bhfi; -- unused */ int i, vma_size, file_size = 0; DWORD rawsize, lowest_va, load_addr = 0, aoep, reloc = 0; // struct get_read_fd_request *req = get_req_buffer(); int unix_handle = handle; int page_size = getpagesize(); // if ( GetFileInformationByHandle( hFile, &bhfi ) ) // file_size = bhfi.nFileSizeLow; file_size=lseek(handle, 0, SEEK_END); lseek(handle, 0, SEEK_SET); //#warning fix CreateFileMappingA mapping = CreateFileMappingA( handle, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL ); if (!mapping) { WARN("CreateFileMapping error %ld\n", GetLastError() ); return 0; } // hModule = (HMODULE)MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 0 ); hModule=(HMODULE)mapping; // CloseHandle( mapping ); if (!hModule) { WARN("MapViewOfFile error %ld\n", GetLastError() ); return 0; } if ( *(WORD*)hModule !=IMAGE_DOS_SIGNATURE) { WARN("%s image doesn't have DOS signature, but 0x%04x\n", filename,*(WORD*)hModule); goto error; } nt = PE_HEADER( hModule ); if ( nt->Signature != IMAGE_NT_SIGNATURE ) { WARN("%s image doesn't have PE signature, but 0x%08lx\n", filename, nt->Signature ); goto error; } if ( nt->FileHeader.Machine != IMAGE_FILE_MACHINE_I386 ) { MESSAGE("Trying to load PE image for unsupported architecture ("); switch (nt->FileHeader.Machine) { case IMAGE_FILE_MACHINE_UNKNOWN: MESSAGE("Unknown"); break; case IMAGE_FILE_MACHINE_I860: MESSAGE("I860"); break; case IMAGE_FILE_MACHINE_R3000: MESSAGE("R3000"); break; case IMAGE_FILE_MACHINE_R4000: MESSAGE("R4000"); break; case IMAGE_FILE_MACHINE_R10000: MESSAGE("R10000"); break; case IMAGE_FILE_MACHINE_ALPHA: MESSAGE("Alpha"); break; case IMAGE_FILE_MACHINE_POWERPC: MESSAGE("PowerPC"); break; default: MESSAGE("Unknown-%04x", nt->FileHeader.Machine); break; } MESSAGE(")\n"); goto error; } pe_sec = PE_SECTIONS( hModule ); rawsize = 0; lowest_va = 0x10000; for (i = 0; i < nt->FileHeader.NumberOfSections; i++) { if (lowest_va > pe_sec[i].VirtualAddress) lowest_va = pe_sec[i].VirtualAddress; if (pe_sec[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) continue; if (pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData > rawsize) rawsize = pe_sec[i].PointerToRawData+pe_sec[i].SizeOfRawData; } if ((file_size > 0) && ((DWORD)file_size < rawsize)) { ERR("PE module is too small (header: %u, filesize: %d), " "probably truncated download?\n", (unsigned int)rawsize, file_size ); goto error; } aoep = nt->OptionalHeader.AddressOfEntryPoint; if (aoep && (aoep < lowest_va)) FIXME("VIRUS WARNING: '%s' has an invalid entrypoint (0x%08lx) " "below the first virtual address (0x%08x) " "(possibly infected by Tchernobyl/SpaceFiller virus)!\n", filename, aoep, (unsigned int)lowest_va ); /* FIXME: Hack! While we don't really support shared sections yet, * this checks for those special cases where the whole DLL * consists only of shared sections and is mapped into the * shared address space > 2GB. In this case, we assume that * the module got mapped at its base address. Thus we simply * check whether the module has actually been mapped there * and use it, if so. This is needed to get Win95 USER32.DLL * to work (until we support shared sections properly). */ if ( nt->OptionalHeader.ImageBase & 0x80000000 ) { HMODULE sharedMod = (HMODULE)nt->OptionalHeader.ImageBase; IMAGE_NT_HEADERS *sharedNt = (PIMAGE_NT_HEADERS) ( (LPBYTE)sharedMod + ((LPBYTE)nt - (LPBYTE)hModule) ); /* Well, this check is not really comprehensive, but should be good enough for now ... */ if ( !IsBadReadPtr( (LPBYTE)sharedMod, sizeof(IMAGE_DOS_HEADER) ) && memcmp( (LPBYTE)sharedMod, (LPBYTE)hModule, sizeof(IMAGE_DOS_HEADER) ) == 0 && !IsBadReadPtr( sharedNt, sizeof(IMAGE_NT_HEADERS) ) && memcmp( sharedNt, nt, sizeof(IMAGE_NT_HEADERS) ) == 0 ) { UnmapViewOfFile( (LPVOID)hModule ); return sharedMod; } } load_addr = nt->OptionalHeader.ImageBase; vma_size = calc_vma_size( hModule ); load_addr = (DWORD)VirtualAlloc( (void*)load_addr, vma_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if (load_addr == 0) { FIXME("We need to perform base relocations for %s\n", filename); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BASERELOC; if (dir->Size) reloc = dir->VirtualAddress; else { FIXME( "FATAL: Need to relocate %s, but no relocation records present (%s). Try to run that file directly !\n", filename, (nt->FileHeader.Characteristics&IMAGE_FILE_RELOCS_STRIPPED)? "stripped during link" : "unknown reason" ); goto error; } /* FIXME: If we need to relocate a system DLL (base > 2GB) we should * really make sure that the *new* base address is also > 2GB. * Some DLLs really check the MSB of the module handle :-/ */ if ( nt->OptionalHeader.ImageBase & 0x80000000 ) ERR( "Forced to relocate system DLL (base > 2GB). This is not good.\n" ); load_addr = (DWORD)VirtualAlloc( NULL, vma_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if (!load_addr) { FIXME_(win32)( "FATAL: Couldn't load module %s (out of memory, %d needed)!\n", filename, vma_size); goto error; } } TRACE("Load addr is %lx (base %lx), range %x\n", load_addr, nt->OptionalHeader.ImageBase, vma_size ); TRACE_(segment)("Loading %s at %lx, range %x\n", filename, load_addr, vma_size ); #if 0 *(PIMAGE_DOS_HEADER)load_addr = *(PIMAGE_DOS_HEADER)hModule; *PE_HEADER( load_addr ) = *nt; memcpy( PE_SECTIONS(load_addr), PE_SECTIONS(hModule), sizeof(IMAGE_SECTION_HEADER) * nt->FileHeader.NumberOfSections ); memcpy( load_addr, hModule, lowest_fa ); #endif if ((void*)FILE_dommap( handle, (void *)load_addr, 0, nt->OptionalHeader.SizeOfHeaders, 0, 0, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_FIXED ) != (void*)load_addr) { ERR_(win32)( "Critical Error: failed to map PE header to necessary address.\n"); goto error; } pe_sec = PE_SECTIONS( hModule ); for (i = 0; i < nt->FileHeader.NumberOfSections; i++, pe_sec++) { if (!pe_sec->SizeOfRawData || !pe_sec->PointerToRawData) continue; TRACE("%s: mmaping section %s at %p off %lx size %lx/%lx\n", filename, pe_sec->Name, (void*)RVA(pe_sec->VirtualAddress), pe_sec->PointerToRawData, pe_sec->SizeOfRawData, pe_sec->Misc.VirtualSize ); if ((void*)FILE_dommap( unix_handle, (void*)RVA(pe_sec->VirtualAddress), 0, pe_sec->SizeOfRawData, 0, pe_sec->PointerToRawData, PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_FIXED ) != (void*)RVA(pe_sec->VirtualAddress)) { ERR_(win32)( "Critical Error: failed to map PE section to necessary address.\n"); goto error; } if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) && (pe_sec->SizeOfRawData & (page_size-1))) { DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size; if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize; TRACE("clearing %p - %p\n", (char *)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, (char *)RVA(pe_sec->VirtualAddress) + end ); memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0, end - pe_sec->SizeOfRawData ); } } if ( reloc ) do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) ); *version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | (nt->OptionalHeader.MinorSubsystemVersion & 0xff); UnmapViewOfFile( (LPVOID)hModule ); return (HMODULE)load_addr; error: if (unix_handle != -1) close( unix_handle ); if (load_addr) VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE ); UnmapViewOfFile( (LPVOID)hModule ); return 0; } /********************************************************************** * PE_CreateModule * * Create WINE_MODREF structure for loaded HMODULE32, link it into * process modref_list, and fixup all imports. * * Note: hModule must point to a correctly allocated PE image, * with base relocations applied; the 16-bit dummy module * associated to hModule must already exist. * * Note: This routine must always be called in the context of the * process that is to own the module to be created. */ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, WIN_BOOL builtin ) { DWORD load_addr = (DWORD)hModule; IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); IMAGE_DATA_DIRECTORY *dir; IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL; IMAGE_EXPORT_DIRECTORY *pe_export = NULL; IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL; WINE_MODREF *wm; /* int result; -- unused */ dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; if (dir->Size) pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT; if (dir->Size) pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; if (dir->Size) pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION; if (dir->Size) FIXME("Exception directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY; if (dir->Size) FIXME("Security directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG; if (dir->Size) TRACE("Debug directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT; if (dir->Size) FIXME("Copyright string ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR; if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG; if (dir->Size) FIXME("Load Configuration directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT; if (dir->Size) TRACE("Bound Import directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT; if (dir->Size) TRACE("Import Address Table directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT; if (dir->Size) { TRACE("Delayed import, stub calls LoadLibrary\n" ); /* * Nothing to do here. */ #ifdef ImgDelayDescr /* * This code is useful to observe what the heck is going on. */ { ImgDelayDescr *pe_delay = NULL; pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress); TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs); TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName); TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod); TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT); TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT); TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT); TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT); TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp); } #endif } dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR; if (dir->Size) FIXME("Unknown directory 14 ignored\n" ); dir = nt->OptionalHeader.DataDirectory+15; if (dir->Size) FIXME("Unknown directory 15 ignored\n" ); wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wm) ); wm->module = hModule; if ( builtin ) wm->flags |= WINE_MODREF_INTERNAL; if ( flags & DONT_RESOLVE_DLL_REFERENCES ) wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS; if ( flags & LOAD_LIBRARY_AS_DATAFILE ) wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE; wm->type = MODULE32_PE; wm->binfmt.pe.pe_export = pe_export; wm->binfmt.pe.pe_import = pe_import; wm->binfmt.pe.pe_resource = pe_resource; wm->binfmt.pe.tlsindex = -1; wm->filename = malloc(strlen(filename)+1); strcpy(wm->filename, filename ); wm->modname = strrchr( wm->filename, '\\' ); if (!wm->modname) wm->modname = wm->filename; else wm->modname++; if ( pe_export ) dump_exports( hModule ); /* Fixup Imports */ if ( pe_import && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) && fixup_imports( wm ) ) { /* remove entry from modref chain */ return NULL; } return wm; return wm; } /****************************************************************************** * The PE Library Loader frontend. * FIXME: handle the flags. */ WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags) { HMODULE hModule32; WINE_MODREF *wm; char filename[256]; int hFile; WORD version = 0; strncpy(filename, name, sizeof(filename)); hFile=open(filename, O_RDONLY); if(hFile==-1) return NULL; hModule32 = PE_LoadImage( hFile, filename, &version ); if (!hModule32) { SetLastError( ERROR_OUTOFMEMORY ); return NULL; } if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) ) { ERR( "can't load %s\n", filename ); SetLastError( ERROR_OUTOFMEMORY ); return NULL; } close(hFile); //printf("^^^^^^^^^^^^^^^^Alloc VM1 %p\n", wm); return wm; } /***************************************************************************** * PE_UnloadLibrary * * Unload the library unmapping the image and freeing the modref structure. */ void PE_UnloadLibrary(WINE_MODREF *wm) { TRACE(" unloading %s\n", wm->filename); if (wm->filename) free(wm->filename); if (wm->short_filename) free(wm->short_filename); HeapFree( GetProcessHeap(), 0, wm->deps ); VirtualFree( (LPVOID)wm->module, 0, MEM_RELEASE ); HeapFree( GetProcessHeap(), 0, wm ); //printf("^^^^^^^^^^^^^^^^Free VM1 %p\n", wm); } /***************************************************************************** * Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA * FIXME: this function should use PE_LoadLibraryExA, but currently can't * due to the PROCESS_Create stuff. */ /* * This is a dirty hack. * The win32 DLLs contain an alloca routine, that first probes the soon * to be allocated new memory *below* the current stack pointer in 4KByte * increments. After the mem probing below the current %esp, the stack * pointer is finally decremented to make room for the "alloca"ed memory. * Maybe the probing code is intended to extend the stack on a windows box. * Anyway, the linux kernel does *not* extend the stack by simply accessing * memory below %esp; it segfaults. * The extend_stack_for_dll_alloca() routine just preallocates a big chunk * of memory on the stack, for use by the DLLs alloca routine. */ static void extend_stack_for_dll_alloca(void) { #if !defined(__FreeBSD__) && !defined(__OpenBSD__) void* mem=alloca(0x20000); *(int*)mem=0x1234; #endif } /* Called if the library is loaded or freed. * NOTE: if a thread attaches a DLL, the current thread will only do * DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH * (SDK) */ WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ) { WIN_BOOL retv = TRUE; assert( wm->type == MODULE32_PE ); if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) && (PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint) ) { DLLENTRYPROC entry ; entry = (void*)PE_FindExportedFunction(wm, "DllMain", 0); if(entry==NULL) entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint ); TRACE_(relay)("CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n", entry, wm->module, type, lpReserved ); TRACE("Entering DllMain("); switch(type) { case DLL_PROCESS_DETACH: TRACE("DLL_PROCESS_DETACH) "); break; case DLL_PROCESS_ATTACH: TRACE("DLL_PROCESS_ATTACH) "); break; case DLL_THREAD_DETACH: TRACE("DLL_THREAD_DETACH) "); break; case DLL_THREAD_ATTACH: TRACE("DLL_THREAD_ATTACH) "); break; } TRACE("for %s\n", wm->filename); extend_stack_for_dll_alloca(); retv = entry( wm->module, type, lpReserved ); } return retv; } #if 0 static LPVOID _fixup_address(PIMAGE_OPTIONAL_HEADER opt,int delta,LPVOID addr) { if ( ((DWORD)addr>opt->ImageBase) && ((DWORD)addr<opt->ImageBase+opt->SizeOfImage) ) return (LPVOID)(((DWORD)addr)+delta); else return addr; } #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/win32.c�������������������������������������������������������������0000644�0001750�0001750�00000415077�14647725152�015337� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*********************************************************** Win32 emulation code. Functions that emulate responses from corresponding Win32 API calls. Since we are not going to be able to load virtually any DLL, we can only implement this much, adding needed functions with each new codec. Basic principle of implementation: it's not good for DLL to know too much about its environment. ************************************************************/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/attributes.h> #define QTX #ifdef QTX #define PSEUDO_SCREEN_WIDTH /*640*/800 #define PSEUDO_SCREEN_HEIGHT /*480*/600 #endif #include "winbase.h" #include "winreg.h" #include "winnt.h" #include "winerror.h" #include "debugtools.h" #include "module.h" #include "winuser.h" #include <stdio.h> #include "win32.h" #include "registry.h" #include "loader.h" #include "com.h" #include <stdlib.h> #include <assert.h> #include <stdarg.h> #include <ctype.h> #include <pthread.h> #include <errno.h> #ifdef HAVE_MALLOC_H #include <malloc.h> #endif #include <time.h> #include <math.h> #include <unistd.h> #include <fcntl.h> #include <sys/types.h> #include <dirent.h> #include <sys/time.h> #include <sys/timeb.h> #ifdef HAVE_KSTAT #include <kstat.h> #endif #if HAVE_VSSCANF # ifndef __sun /* * On solaris, remove the prototype for now; it's incompatible with the one * from solaris9 stdio.h */ int vsscanf( const char *str, const char *format, va_list ap); # endif #else /* system has no vsscanf. try to provide one */ static int vsscanf( const char *str, const char *format, va_list ap) { long p1 = va_arg(ap, long); long p2 = va_arg(ap, long); long p3 = va_arg(ap, long); long p4 = va_arg(ap, long); long p5 = va_arg(ap, long); return sscanf(str, format, p1, p2, p3, p4, p5); } #endif const char* win32_def_path = WIN32_PATH; static void do_cpuid(unsigned int ax, unsigned int *regs) { __asm__ __volatile__ ( "pushl %%ebx; pushl %%ecx; pushl %%edx;" ".byte 0x0f, 0xa2;" "movl %%eax, (%2);" "movl %%ebx, 4(%2);" "movl %%ecx, 8(%2);" "movl %%edx, 12(%2);" "popl %%edx; popl %%ecx; popl %%ebx;" : "=a" (ax) : "0" (ax), "S" (regs) ); } static unsigned int c_localcount_tsc() { int a; __asm__ __volatile__ ( "rdtsc\n\t" :"=a"(a) : :"edx" ); return a; } static void c_longcount_tsc(long long* z) { __asm__ __volatile__ ( "pushl %%ebx\n\t" "movl %%eax, %%ebx\n\t" "rdtsc\n\t" "movl %%eax, 0(%%ebx)\n\t" "movl %%edx, 4(%%ebx)\n\t" "popl %%ebx\n\t" ::"a"(z) ); } static unsigned int c_localcount_notsc() { struct timeval tv; unsigned limit=~0; limit/=1000000; gettimeofday(&tv, 0); return limit*tv.tv_usec; } static void c_longcount_notsc(long long* z) { struct timeval tv; unsigned long long result; unsigned limit=~0; if(!z)return; limit/=1000000; gettimeofday(&tv, 0); result=tv.tv_sec; result<<=32; result+=limit*tv.tv_usec; *z=result; } static unsigned int localcount_stub(void); static void longcount_stub(long long*); static unsigned int (*localcount)()=localcount_stub; static void (*longcount)(long long*)=longcount_stub; static pthread_mutex_t memmut; static unsigned int localcount_stub(void) { unsigned int regs[4]; do_cpuid(1, regs); if ((regs[3] & 0x00000010) != 0) { localcount=c_localcount_tsc; longcount=c_longcount_tsc; } else { localcount=c_localcount_notsc; longcount=c_longcount_notsc; } return localcount(); } static void longcount_stub(long long* z) { unsigned int regs[4]; do_cpuid(1, regs); if ((regs[3] & 0x00000010) != 0) { localcount=c_localcount_tsc; longcount=c_longcount_tsc; } else { localcount=c_localcount_notsc; longcount=c_longcount_notsc; } longcount(z); } int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT //#define DETAILED_OUT static inline void XINE_FORMAT_PRINTF(1, 2) dbgprintf(const char* fmt, ...) { #ifdef DETAILED_OUT if(LOADER_DEBUG) { FILE* f; va_list va; va_start(va, fmt); f=fopen("./log", "a"); vprintf(fmt, va); fflush(stdout); if(f) { vfprintf(f, fmt, va); fsync(fileno(f)); fclose(f); } va_end(va); } #else (void)fmt; #endif #undef MPLAYER #ifdef MPLAYER #include "../mp_msg.h" if (verbose > 2) { va_list va; va_start(va, fmt); // vprintf(fmt, va); mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va); va_end(va); } #endif } char export_names[300][32]={ "name1", //"name2", //"name3" }; //#define min(x,y) ((x)<(y)?(x):(y)) void destroy_event(void* event); struct th_list_t; typedef struct th_list_t{ int id; void* thread; struct th_list_t* next; struct th_list_t* prev; } th_list; // have to be cleared by GARBAGE COLLECTOR static tls_t* g_tls=NULL; static th_list* list=NULL; #undef MEMORY_DEBUG #ifdef MEMORY_DEBUG static unsigned char* heap=NULL; static int heap_counter=0; static void test_heap(void) { int offset=0; if(heap==0) return; while(offset<heap_counter) { if(*(int*)(heap+offset)!=0x433476) { printf("Heap corruption at address %d\n", offset); return; } offset+=8+*(int*)(heap+offset+4); } for(;offset<min(offset+1000, 20000000); offset++) if(heap[offset]!=0xCC) { printf("Free heap corruption at address %d\n", offset); } } static void* my_mreq(int size, int to_zero) { static int test=0; test++; if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter); // test_heap(); if(heap==NULL) { heap=malloc(20000000); memset(heap, 0xCC,20000000); } if(heap==0) { printf("No enough memory\n"); return 0; } if(heap_counter+size>20000000) { printf("No enough memory\n"); return 0; } *(int*)(heap+heap_counter)=0x433476; heap_counter+=4; *(int*)(heap+heap_counter)=size; heap_counter+=4; printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size); if(to_zero) memset(heap+heap_counter, 0, size); else memset(heap+heap_counter, 0xcc, size); // make crash reproducable heap_counter+=size; return heap+heap_counter-size; } static int my_release(char* memory) { // test_heap(); if(memory==NULL) { printf("ERROR: free(0)\n"); return 0; } if(*(int*)(memory-8)!=0x433476) { printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n"); return 0; } printf("Freed %d bytes of memory\n", *(int*)(memory-4)); // memset(memory-8, *(int*)(memory-4), 0xCC); return 0; } #else #define GARBAGE typedef struct alloc_header_t alloc_header; struct alloc_header_t { // let's keep allocated data 16 byte aligned alloc_header* prev; alloc_header* next; long deadbeef; long size; long type; long reserved1; long reserved2; long reserved3; }; #ifdef GARBAGE static alloc_header* last_alloc = NULL; static int alccnt = 0; #endif #define AREATYPE_CLIENT 0 #define AREATYPE_EVENT 1 #define AREATYPE_MUTEX 2 #define AREATYPE_COND 3 #define AREATYPE_CRITSECT 4 /* -- critical sections -- */ struct CRITSECT { pthread_t id; pthread_mutex_t mutex; int locked; long deadbeef; }; void* mreq_private(int size, int to_zero, int type); void* mreq_private(int size, int to_zero, int type) { int nsize = size + sizeof(alloc_header); alloc_header* header = (alloc_header* ) malloc(nsize); if (!header) return 0; if (to_zero) memset(header, 0, nsize); #ifdef GARBAGE if (!last_alloc) { pthread_mutex_init(&memmut, NULL); pthread_mutex_lock(&memmut); } else { pthread_mutex_lock(&memmut); last_alloc->next = header; /* set next */ } header->prev = last_alloc; header->next = 0; last_alloc = header; alccnt++; pthread_mutex_unlock(&memmut); #endif header->deadbeef = 0xdeadbeef; header->size = size; header->type = type; //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt); return header + 1; } static int my_release(void* memory) { alloc_header* header = (alloc_header*) memory - 1; #ifdef GARBAGE alloc_header* prevmem; alloc_header* nextmem; if (memory == 0) return 0; if (header->deadbeef != (long) 0xdeadbeef) { printf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt); return 0; } pthread_mutex_lock(&memmut); switch(header->type) { case AREATYPE_EVENT: destroy_event(memory); break; case AREATYPE_COND: pthread_cond_destroy((pthread_cond_t*)memory); break; case AREATYPE_MUTEX: pthread_mutex_destroy((pthread_mutex_t*)memory); break; case AREATYPE_CRITSECT: pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex); break; default: //memset(memory, 0xcc, header->size); ; } header->deadbeef = 0; prevmem = header->prev; nextmem = header->next; if (prevmem) prevmem->next = nextmem; if (nextmem) nextmem->prev = prevmem; if (header == last_alloc) last_alloc = prevmem; alccnt--; /* xine: mutex must be unlocked on entrance of pthread_mutex_destroy */ pthread_mutex_unlock(&memmut); if (!last_alloc) pthread_mutex_destroy(&memmut); //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt); #else if (memory == 0) return 0; #endif //memset(header + 1, 0xcc, header->size); free(header); return 0; } #endif static inline void* my_mreq(int size, int to_zero) { return mreq_private(size, to_zero, AREATYPE_CLIENT); } static int my_size(void* memory) { if(!memory) return 0; return ((alloc_header*)memory)[-1].size; } static void* my_realloc(void* memory, int size) { void *ans = memory; int osize; if (memory == NULL) return my_mreq(size, 0); osize = my_size(memory); if (osize < size) { ans = my_mreq(size, 0); memcpy(ans, memory, osize); my_release(memory); } return ans; } /* * * WINE API - native implementation for several win32 libraries * */ static int WINAPI ext_unknown() { printf("Unknown func called\n"); return 0; } static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count) { int result = (count == 0 || ptr != 0) ? 0 : 1; dbgprintf("IsBadWritePtr(%p, 0x%x) => %d\n", ptr, count, result); return result; } static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count) { int result = (count == 0 || ptr != 0) ? 0 : 1; dbgprintf("IsBadReadPtr(%p, 0x%x) => %d\n", ptr, count, result); return result; } static int WINAPI expDisableThreadLibraryCalls(int module) { dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module); return 0; } static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv) { HMODULE result; if (pdrv==NULL) result=0; else result=pdrv->hDriverModule; dbgprintf("GetDriverModuleHandle(%p) => %d\n", pdrv, result); return result; } #define MODULE_HANDLE_kernel32 ((HMODULE)0x120) #define MODULE_HANDLE_user32 ((HMODULE)0x121) #ifdef QTX #define MODULE_HANDLE_wininet ((HMODULE)0x122) #define MODULE_HANDLE_ddraw ((HMODULE)0x123) #define MODULE_HANDLE_advapi32 ((HMODULE)0x124) #endif static HMODULE WINAPI expGetModuleHandleA(const char* name) { WINE_MODREF* wm; HMODULE result; if(!name) #ifdef QTX result=1; #else result=0; #endif else { wm=MODULE_FindModule(name); if(wm==0)result=0; else result=(HMODULE)(wm->module); } if(!result) { if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll"))) result=MODULE_HANDLE_kernel32; #ifdef QTX if(name && strcasecmp(name, "user32")==0) result=MODULE_HANDLE_user32; #endif } dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result); return result; } static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddress, void* lpParameter, long dwFlags, long* dwThreadId) { pthread_t *pth; // printf("CreateThread:"); pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0); pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); if(dwFlags) printf( "WARNING: CreateThread flags not supported\n"); if(dwThreadId) *dwThreadId=(long)pth; if(list==NULL) { list=my_mreq(sizeof(th_list), 1); list->next=list->prev=NULL; } else { list->next=my_mreq(sizeof(th_list), 0); list->next->prev=list; list->next->next=NULL; list=list->next; } list->thread=pth; dbgprintf("CreateThread(%p, %ld, %p, %p, %ld, %p) => %p\n", pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth); return pth; } struct mutex_list_t; struct mutex_list_t { char type; pthread_mutex_t *pm; pthread_cond_t *pc; char state; char reset; char name[128]; int semaphore; struct mutex_list_t* next; struct mutex_list_t* prev; }; typedef struct mutex_list_t mutex_list; static mutex_list* mlist=NULL; void destroy_event(void* event) { mutex_list* pp=mlist; // printf("garbage collector: destroy_event(%x)\n", event); while(pp) { if(pp==(mutex_list*)event) { if(pp->next) pp->next->prev=pp->prev; if(pp->prev) pp->prev->next=pp->next; if(mlist==(mutex_list*)event) mlist=mlist->prev; /* pp=mlist; while(pp) { printf("%x => ", pp); pp=pp->prev; } printf("0\n"); */ return; } pp=pp->prev; } } static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, char bInitialState, const char* name) { pthread_mutex_t *pm; pthread_cond_t *pc; /* mutex_list* pp; pp=mlist; while(pp) { printf("%x => ", pp); pp=pp->prev; } printf("0\n"); */ if(mlist!=NULL) { mutex_list* pp=mlist; if(name!=NULL) do { if((strcmp(pp->name, name)==0) && (pp->type==0)) { dbgprintf("CreateEventA(%p, 0x%x, 0x%x, %p='%s') => %p\n", pSecAttr, bManualReset, bInitialState, name, name, pp->pm); return pp->pm; } }while((pp=pp->prev) != NULL); } pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX); pthread_mutex_init(pm, NULL); pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND); pthread_cond_init(pc, NULL); if(mlist==NULL) { mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); mlist->next=mlist->prev=NULL; } else { mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); mlist->next->prev=mlist; mlist->next->next=NULL; mlist=mlist->next; } mlist->type=0; /* Type Event */ mlist->pm=pm; mlist->pc=pc; mlist->state=bInitialState; mlist->reset=bManualReset; if(name) strncpy(mlist->name, name, 127); else mlist->name[0]=0; if(pm==NULL) dbgprintf("ERROR::: CreateEventA failure\n"); /* if(bInitialState) pthread_mutex_lock(pm); */ if(name) dbgprintf("CreateEventA(%p, 0x%x, 0x%x, %p='%s') => %p\n", pSecAttr, bManualReset, bInitialState, name, name, mlist); else dbgprintf("CreateEventA(%p, 0x%x, 0x%x, NULL) => %p\n", pSecAttr, bManualReset, bInitialState, mlist); return mlist; } static void* WINAPI expSetEvent(void* event) { mutex_list *ml = (mutex_list *)event; dbgprintf("SetEvent(%p) => 0x1\n", event); pthread_mutex_lock(ml->pm); if (ml->state == 0) { ml->state = 1; pthread_cond_signal(ml->pc); } pthread_mutex_unlock(ml->pm); return (void *)1; } static void* WINAPI expResetEvent(void* event) { mutex_list *ml = (mutex_list *)event; dbgprintf("ResetEvent(%p) => 0x1\n", event); pthread_mutex_lock(ml->pm); ml->state = 0; pthread_mutex_unlock(ml->pm); return (void *)1; } static void* WINAPI expWaitForSingleObject(void* object, int duration) { mutex_list *ml = (mutex_list *)object; // FIXME FIXME FIXME - this value is sometime unititialize !!! int ret = WAIT_FAILED; mutex_list* pp=mlist; if(object == (void*)0xcfcf9898) { /** From GetCurrentThread() documentation: A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudo handles are not inherited by child processes. This handle has the maximum possible access to the thread object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is THREAD_ALL_ACCESS. The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle function. **/ dbgprintf("WaitForSingleObject(thread_handle) called\n"); return (void*)WAIT_FAILED; } dbgprintf("WaitForSingleObject(%p, duration %d) =>\n", object, duration); // loop below was slightly fixed - its used just for checking if // this object really exists in our list if (!ml) return (void*) ret; while (pp && (pp->pm != ml->pm)) pp = pp->prev; if (!pp) { dbgprintf("WaitForSingleObject: NotFound\n"); return (void*)ret; } pthread_mutex_lock(ml->pm); switch(ml->type) { case 0: /* Event */ if (duration == 0) { /* Check Only */ if (ml->state == 1) ret = WAIT_FAILED; else ret = WAIT_OBJECT_0; } if (duration == -1) { /* INFINITE */ if (ml->state == 0) pthread_cond_wait(ml->pc,ml->pm); if (ml->reset) ml->state = 0; ret = WAIT_OBJECT_0; } if (duration > 0) { /* Timed Wait */ struct timespec abstime; struct timeval now; gettimeofday(&now, 0); abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000; abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000; if (ml->state == 0) ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime); if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT; else ret = WAIT_OBJECT_0; if (ml->reset) ml->state = 0; } break; case 1: /* Semaphore */ if (duration == 0) { if(ml->semaphore==0) ret = WAIT_FAILED; else { ml->semaphore++; ret = WAIT_OBJECT_0; } } if (duration == -1) { if (ml->semaphore==0) pthread_cond_wait(ml->pc,ml->pm); ml->semaphore--; } break; } pthread_mutex_unlock(ml->pm); dbgprintf("WaitForSingleObject(%p, %d): %p => 0x%x \n",object,duration,ml,ret); return (void *)ret; } #ifdef QTX static void* WINAPI expWaitForMultipleObjects(int count, const void** objects, int WaitAll, int duration) { int i; void *object; void *ret; dbgprintf("WaitForMultipleObjects(%d, %p, %d, duration %d) =>\n", count, objects, WaitAll, duration); for (i = 0; i < count; i++) { object = (void *) objects[i]; ret = expWaitForSingleObject(object, duration); if (WaitAll) dbgprintf("WaitAll flag not yet supported...\n"); else return ret; } return NULL; } static void WINAPI expExitThread(int retcode) { dbgprintf("ExitThread(%d)\n", retcode); pthread_exit(&retcode); } static HANDLE WINAPI expCreateMutexA(void *pSecAttr, char bInitialOwner, const char *name) { HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name); if (name) dbgprintf("CreateMutexA(%p, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist); else dbgprintf("CreateMutexA(%p, %d, NULL) => 0x%x\n", pSecAttr, bInitialOwner, mlist); #ifndef QTX /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject waits for ever, else it works ;) */ return mlist; #else return 0; #endif } static int WINAPI expReleaseMutex(HANDLE hMutex) { dbgprintf("ReleaseMutex(%x) => 1\n", hMutex); /* FIXME:XXX !! not yet implemented */ return 1; } #endif static int pf_set = 0; static BYTE PF[64] = {0,}; static void DumpSystemInfo(const SYSTEM_INFO* si) { dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture); dbgprintf(" Page size: %ld\n", si->dwPageSize); dbgprintf(" Minimum app address: %p\n", si->lpMinimumApplicationAddress); dbgprintf(" Maximum app address: %p\n", si->lpMaximumApplicationAddress); dbgprintf(" Active processor mask: 0x%lx\n", si->dwActiveProcessorMask); dbgprintf(" Number of processors: %ld\n", si->dwNumberOfProcessors); dbgprintf(" Processor type: 0x%lx\n", si->dwProcessorType); dbgprintf(" Allocation granularity: 0x%lx\n", si->dwAllocationGranularity); dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel); dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision); } static void WINAPI expGetSystemInfo(SYSTEM_INFO* si) { /* FIXME: better values for the two entries below... */ static int cache = 0; static SYSTEM_INFO cachedsi; #if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__svr4__) unsigned int regs[4]; #endif dbgprintf("GetSystemInfo(%p) =>\n", si); if (cache) { memcpy(si,&cachedsi,sizeof(*si)); DumpSystemInfo(si); return; } memset(PF,0,sizeof(PF)); pf_set = 1; cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; cachedsi.dwPageSize = getpagesize(); /* FIXME: better values for the two entries below... */ cachedsi.lpMinimumApplicationAddress = (void *)0x00000000; cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF; cachedsi.dwActiveProcessorMask = 1; cachedsi.dwNumberOfProcessors = 1; cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.dwAllocationGranularity = 0x10000; cachedsi.wProcessorLevel = 5; /* pentium */ cachedsi.wProcessorRevision = 0x0101; #ifdef MPLAYER /* mplayer's way to detect PF's */ { #include "../cpudetect.h" extern CpuCaps gCpuCaps; if (gCpuCaps.hasMMX) PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; if (gCpuCaps.hasSSE) PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; if (gCpuCaps.has3DNow) PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; switch(gCpuCaps.cpuType) { case CPUTYPE_I686: case CPUTYPE_I586: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel = 5; break; case CPUTYPE_I486: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel = 4; break; case CPUTYPE_I386: default: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel = 3; break; } cachedsi.wProcessorRevision = gCpuCaps.cpuStepping; cachedsi.dwNumberOfProcessors = 1; /* hardcoded */ } #endif /* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */ #ifndef MPLAYER #if defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__svr4__) do_cpuid(1, regs); switch ((regs[0] >> 8) & 0xf) { // cpu family case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel= 3; break; case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel= 4; break; case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; } cachedsi.wProcessorRevision = regs[0] & 0xf; // stepping if (regs[3] & (1 << 8)) PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; if (regs[3] & (1 << 23)) PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; if (regs[3] & (1 << 25)) PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; if (regs[3] & (1 << 31)) PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; cachedsi.dwNumberOfProcessors=1; #endif #endif /* MPLAYER */ /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking fdiv_bug and fpu emulation flags -- alex/MPlayer */ #ifdef __linux__ { char buf[20]; char line[200]; FILE *f = fopen ("/proc/cpuinfo", "r"); if (!f) return; while (fgets(line,200,f)!=NULL) { char *s,*value; /* NOTE: the ':' is the only character we can rely on */ if (!(value = strchr(line,':'))) continue; /* terminate the valuename */ *value++ = '\0'; /* skip any leading spaces */ while (*value==' ') value++; if ((s=strchr(value,'\n'))) *s='\0'; /* 2.1 method */ if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) { if (isdigit (value[0])) { switch (value[0] - '0') { case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel= 3; break; case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel= 4; break; case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; } } /* set the CPU type of the current processor */ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); continue; } /* old 2.0 method */ if (!lstrncmpiA(line, "cpu",strlen("cpu"))) { if ( isdigit (value[0]) && value[1] == '8' && value[2] == '6' && value[3] == 0 ) { switch (value[0] - '0') { case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; cachedsi.wProcessorLevel= 3; break; case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; cachedsi.wProcessorLevel= 4; break; case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; cachedsi.wProcessorLevel= 5; break; } } /* set the CPU type of the current processor */ sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); continue; } if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) { if (!lstrncmpiA(value,"yes",3)) PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE; continue; } if (!lstrncmpiA(line,"fpu",strlen("fpu"))) { if (!lstrncmpiA(value,"no",2)) PF[PF_FLOATING_POINT_EMULATED] = TRUE; continue; } if (!lstrncmpiA(line,"processor",strlen("processor"))) { /* processor number counts up...*/ unsigned int x; if (sscanf(value,"%d",&x)) if (x+1>cachedsi.dwNumberOfProcessors) cachedsi.dwNumberOfProcessors=x+1; /* Create a new processor subkey on a multiprocessor * system */ sprintf(buf,"%d",x); } if (!lstrncmpiA(line,"stepping",strlen("stepping"))) { int x; if (sscanf(value,"%d",&x)) cachedsi.wProcessorRevision = x; } if ( (!lstrncmpiA(line,"flags",strlen("flags"))) || (!lstrncmpiA(line,"features",strlen("features"))) ) { if (strstr(value,"cx8")) PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; if (strstr(value,"mmx")) PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; if (strstr(value,"tsc")) PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE; if (strstr(value,"xmm")) PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE; if (strstr(value,"3dnow")) PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE; } } fclose (f); /* * ad hoc fix for smp machines. * some problems on WaitForSingleObject,CreateEvent,SetEvent * CreateThread ...etc.. * */ cachedsi.dwNumberOfProcessors=1; } #endif /* __linux__ */ cache = 1; memcpy(si,&cachedsi,sizeof(*si)); DumpSystemInfo(si); } // avoid undefined expGetSystemInfo static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v) { WIN_BOOL result = 0; if (!pf_set) { SYSTEM_INFO si; expGetSystemInfo(&si); } if(v<64) result=PF[v]; dbgprintf("IsProcessorFeaturePresent(0x%lx) => 0x%x\n", v, result); return result; } static long WINAPI expGetVersion() { dbgprintf("GetVersion() => 0xC0000004\n"); return 0xC0000004;//Windows 95 } static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size) { // printf("HeapCreate:"); HANDLE result; if(init_size==0) result=(HANDLE)my_mreq(0x110000, 0); else result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0); dbgprintf("HeapCreate(flags 0x%lx, initial size %ld, maximum size %ld) => 0x%x\n", flags, init_size, max_size, result); return result; } // this is another dirty hack // VP31 is releasing one allocated Heap chunk twice // we will silently ignore this second call... static void* heapfreehack = 0; static int heapfreehackshown = 0; //extern void trapbug(void); static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size) { void* z; /** Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for HeapAlloc returns area larger than size argument :-/ actually according to M$ Doc HeapCreate size should be rounded to page boundaries thus we should simulate this **/ //if (size == 22276) trapbug(); z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY)); if(z==0) printf("HeapAlloc failure\n"); dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => %p\n", heap, flags, size, z); heapfreehack = 0; // reset return z; } static long WINAPI expHeapDestroy(void* heap) { dbgprintf("HeapDestroy(heap %p) => 1\n", heap); my_release(heap); return 1; } static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem) { dbgprintf("HeapFree(0x%x, 0x%lx, pointer %p) => 1\n", heap, dwFlags, lpMem); if (heapfreehack != lpMem && lpMem != (void*)0xffffffff && lpMem != (void*)0xbdbdbdbd) // 0xbdbdbdbd is for i263_drv.drv && libefence // it seems to be reading from relased memory // EF_PROTECT_FREE doens't show any probleme my_release(lpMem); else { if (!heapfreehackshown++) printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem); } heapfreehack = lpMem; return 1; } static long WINAPI expHeapSize(int heap, int flags, void* pointer) { long result=my_size(pointer); dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer %p) => %ld\n", heap, flags, pointer, result); return result; } static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size) { long orgsize = my_size(lpMem); dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size); (void)heap; (void)flags; return my_realloc(lpMem, size); } static long WINAPI expGetProcessHeap(void) { dbgprintf("GetProcessHeap() => 1\n"); return 1; } static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4) { void* z = VirtualAlloc(v1, v2, v3, v4); if(z==0) printf("VirtualAlloc failure\n"); dbgprintf("VirtualAlloc(%p, %ld, %ld, %ld) => %p\n",v1,v2,v3,v4, z); return z; } static int WINAPI expVirtualFree(void* v1, int v2, int v3) { int result = VirtualFree(v1,v2,v3); dbgprintf("VirtualFree(%p, %d, %d) => %d\n",v1,v2,v3, result); return result; } /* we're building a table of critical sections. cs_win pointer uses the DLL cs_unix is the real structure, we're using cs_win only to identifying cs_unix */ struct critsecs_list_t { CRITICAL_SECTION *cs_win; struct CRITSECT *cs_unix; }; /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */ #undef CRITSECS_NEWTYPE //#define CRITSECS_NEWTYPE 1 #ifdef CRITSECS_NEWTYPE /* increased due to ucod needs more than 32 entries */ /* and 64 should be enough for everything */ #define CRITSECS_LIST_MAX 64 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX]; static int critsecs_get_pos(CRITICAL_SECTION *cs_win) { int i; for (i=0; i < CRITSECS_LIST_MAX; i++) if (critsecs_list[i].cs_win == cs_win) return(i); return(-1); } static int critsecs_get_unused(void) { int i; for (i=0; i < CRITSECS_LIST_MAX; i++) if (critsecs_list[i].cs_win == NULL) return(i); return(-1); } struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win) { int i; for (i=0; i < CRITSECS_LIST_MAX; i++) if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix) return(critsecs_list[i].cs_unix); return(NULL); } #endif static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) { dbgprintf("InitializeCriticalSection(%p)\n", c); /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION)) { printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n", sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION)); return; }*/ /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */ #ifdef CRITSECS_NEWTYPE { struct CRITSECT *cs; int i = critsecs_get_unused(); if (i < 0) { printf("InitializeCriticalSection(%p) - no more space in list\n", c); return; } dbgprintf("got unused space at %d\n", i); cs = malloc(sizeof(struct CRITSECT)); if (!cs) { printf("InitializeCriticalSection(%p) - out of memory\n", c); return; } pthread_mutex_init(&cs->mutex, NULL); cs->locked = 0; critsecs_list[i].cs_win = c; critsecs_list[i].cs_unix = cs; dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n", i, c, cs); } #else { struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION), 0, AREATYPE_CRITSECT); pthread_mutex_init(&cs->mutex, NULL); cs->locked=0; cs->deadbeef = 0xdeadbeef; *(void**)c = cs; } #endif return; } static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c) { #ifdef CRITSECS_NEWTYPE struct CRITSECT* cs = critsecs_get_unix(c); #else struct CRITSECT* cs = (*(struct CRITSECT**)c); #endif dbgprintf("EnterCriticalSection(%p) %p\n",c, cs); if (!cs) { dbgprintf("entered uninitialized critisec!\n"); expInitializeCriticalSection(c); #ifdef CRITSECS_NEWTYPE cs=critsecs_get_unix(c); #else cs = (*(struct CRITSECT**)c); #endif printf("wine/win32: Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c); } if(cs->locked) /* xine: recursive locking */ if(cs->id==pthread_self()) { cs->locked++; return; } pthread_mutex_lock(&(cs->mutex)); cs->locked=1; cs->id=pthread_self(); return; } static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c) { #ifdef CRITSECS_NEWTYPE struct CRITSECT* cs = critsecs_get_unix(c); #else struct CRITSECT* cs = (*(struct CRITSECT**)c); #endif // struct CRITSECT* cs=(struct CRITSECT*)c; dbgprintf("LeaveCriticalSection(%p) %p\n",c, cs); if (!cs) { printf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c); return; } /* xine: recursive unlocking */ if( cs->locked ) { cs->locked--; if( !cs->locked ) pthread_mutex_unlock(&(cs->mutex)); } return; } static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c) { #ifdef CRITSECS_NEWTYPE struct CRITSECT* cs = critsecs_get_unix(c); #else struct CRITSECT* cs= (*(struct CRITSECT**)c); #endif // struct CRITSECT* cs=(struct CRITSECT*)c; dbgprintf("DeleteCriticalSection(%p)\n",c); #ifndef GARBAGE /* xine: mutex must be unlocked on entrance of pthread_mutex_destroy */ if( cs->locked ) pthread_mutex_unlock(&(cs->mutex)); pthread_mutex_destroy(&(cs->mutex)); // released by GarbageCollector in my_relase otherwise #endif my_release(cs); #ifdef CRITSECS_NEWTYPE { int i = critsecs_get_pos(c); if (i < 0) { printf("DeleteCriticalSection(%p) error (critsec not found)\n", c); return; } critsecs_list[i].cs_win = NULL; expfree(critsecs_list[i].cs_unix); critsecs_list[i].cs_unix = NULL; dbgprintf("DeleteCriticalSection -> itemno=%d\n", i); } #endif return; } static int WINAPI expGetCurrentThreadId() { dbgprintf("GetCurrentThreadId() => %ld\n", (long int)pthread_self()); return (int)pthread_self(); } static int WINAPI expGetCurrentProcess() { dbgprintf("GetCurrentProcess() => %d\n", getpid()); return getpid(); } #ifdef QTX // this version is required for Quicktime codecs (.qtx/.qts) to work. // (they assume some pointers at FS: segment) //static int tls_count; static int tls_use_map[64]; static void *tls_minus_one; static int WINAPI expTlsAlloc() { int i; for(i=0; i<64; i++) if(tls_use_map[i]==0) { tls_use_map[i]=1; dbgprintf("TlsAlloc() => %d\n",i); return i; } dbgprintf("TlsAlloc() => -1 (ERROR)\n"); return -1; } //static int WINAPI expTlsSetValue(DWORD index, void* value) static int WINAPI expTlsSetValue(int index, void* value) { dbgprintf("TlsSetValue(%d,%p) => 1\n",index,value); // if((index<0) || (index>64)) if((index>=64)) return 0; /* qt passes -1 here. probably a side effect of some bad patching */ if( index < 0 ) { tls_minus_one = value; return 1; } #if 0 *(void**)((char*)fs_seg+0x88+4*index) = value; #else /* does not require fs_seg memory, if everything is right * we can access FS:xxxx like any win32 code would do. */ index = 0x88+4*index; __asm__ __volatile__( "movl %0,%%fs:(%1)" :: "r" (value), "r" (index) ); #endif return 1; } static void* WINAPI expTlsGetValue(DWORD index) { void *ret; dbgprintf("TlsGetValue(%ld)\n",index); // if((index<0) || (index>64)) if((index>=64)) return NULL; /* qt passes -1 here. probably a side effect of some bad patching */ if (index & 0x80000000) { return tls_minus_one; } #if 0 return *(void**)((char*)fs_seg+0x88+4*index); #else /* does not require fs_seg memory, if everything is right * we can access FS:xxxx like any win32 code would do. */ index = 0x88+4*index; __asm__ __volatile__( "movl %%fs:(%1),%0" : "=r" (ret) : "r" (index) ); return ret; #endif } static int WINAPI expTlsFree(int idx) { int index = (int) idx; dbgprintf("TlsFree(%d)\n",index); if((index<0) || (index>=64)) return 0; tls_use_map[index]=0; return 1; } #else struct tls_s { void* value; int used; struct tls_s* prev; struct tls_s* next; }; static void* WINAPI expTlsAlloc() { if (g_tls == NULL) { g_tls=my_mreq(sizeof(tls_t), 0); g_tls->next=g_tls->prev=NULL; } else { g_tls->next=my_mreq(sizeof(tls_t), 0); g_tls->next->prev=g_tls; g_tls->next->next=NULL; g_tls=g_tls->next; } dbgprintf("TlsAlloc() => 0x%x\n", g_tls); if (g_tls) g_tls->value=0; /* XXX For Divx.dll */ return g_tls; } static int WINAPI expTlsSetValue(void* idx, void* value) { tls_t* index = (tls_t*) idx; int result; if(index==0) result=0; else { index->value=value; result=1; } dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result ); return result; } static void* WINAPI expTlsGetValue(void* idx) { tls_t* index = (tls_t*) idx; void* result; if(index==0) result=0; else result=index->value; dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result); return result; } static int WINAPI expTlsFree(void* idx) { tls_t* index = (tls_t*) idx; int result; if(index==0) result=0; else { if(index->next) index->next->prev=index->prev; if(index->prev) index->prev->next=index->next; if (g_tls == index) g_tls = index->prev; my_release((void*)index); result=1; } dbgprintf("TlsFree(index 0x%x) => %d\n", index, result); return result; } #endif static void* WINAPI expLocalAlloc(int flags, int size) { void* z = my_mreq(size, (flags & GMEM_ZEROINIT)); if (z == 0) printf("LocalAlloc() failed\n"); dbgprintf("LocalAlloc(%d, flags 0x%x) => %p\n", size, flags, z); return z; } static void* WINAPI expLocalReAlloc(int handle,int size, int flags) { void *newpointer; int oldsize; newpointer=NULL; if (flags & LMEM_MODIFY) { dbgprintf("LocalReAlloc MODIFY\n"); return (void *)handle; } oldsize = my_size((void *)handle); newpointer = my_realloc((void *)handle,size); dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => %p\n", handle,size,oldsize, flags,newpointer); return newpointer; } static void* WINAPI expLocalLock(void* z) { dbgprintf("LocalLock(%p) => %p\n", z, z); return z; } static void* WINAPI expGlobalAlloc(int flags, int size) { void* z; dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags); z=my_mreq(size, (flags & GMEM_ZEROINIT)); //z=calloc(size, 1); //z=malloc(size); if(z==0) printf("GlobalAlloc() failed\n"); dbgprintf("GlobalAlloc(%d, flags 0x%x) => %p\n", size, flags, z); return z; } static void* WINAPI expGlobalLock(void* z) { dbgprintf("GlobalLock(%p) => %p\n", z, z); return z; } // pvmjpg20 - but doesn't work anyway static int WINAPI expGlobalSize(void* amem) { int size = 100000; #ifdef GARBAGE alloc_header* header = last_alloc; alloc_header* mem = (alloc_header*) amem - 1; if (amem == 0) return 0; pthread_mutex_lock(&memmut); while (header) { if ((DWORD)header->deadbeef != 0xdeadbeef) { printf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt); break; } if (header == mem) { size = header->size; break; } header = header->prev; } pthread_mutex_unlock(&memmut); #endif dbgprintf("GlobalSize(%p)\n", amem); return size; } static int WINAPI expLoadStringA(long instance, long id, void* buf, long size) { int result=LoadStringA(instance, id, buf, size); // if(buf) dbgprintf("LoadStringA(instance 0x%lx, id 0x%lx, buffer %p, size %ld) => %d ( %s )\n", instance, id, buf, size, result, (char *)buf); // else // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n", // instance, id, buf, size, result); return result; } static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2) { // #warning FIXME int i; int result; if(s2==0) result=1; else { if(siz1>siz2/2)siz1=siz2/2; for(i=1; i<=siz1; i++) { *s2=*s1; if(!*s1)break; s2++; s1++; } result=i; } if(s1) dbgprintf("MultiByteToWideChar(codepage %ld, flags 0x%lx, string %p='%s'," "size %ld, dest buffer %p, dest size %d) => %d\n", v1, v2, s1, s1, siz1, s2, siz2, result); else dbgprintf("MultiByteToWideChar(codepage %ld, flags 0x%lx, string NULL," "size %ld, dest buffer %p, dest size %d) => %d\n", v1, v2, siz1, s2, siz2, result); return result; } static void wch_print(const short* str) { dbgprintf(" src: "); while(*str)dbgprintf("%c", *str++); dbgprintf("\n"); } static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1, char* s2, int siz2, char* c3, int* siz3) { int result; dbgprintf("WideCharToMultiByte(codepage %ld, flags 0x%lx, src %p, src size %ld, " "dest %p, dest size %d, defch %p, used_defch %p)", v1, v2, s1, siz1, s2, siz2, c3, siz3); result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3); dbgprintf("=> %d\n", result); //if(s1)wch_print(s1); if(s2)dbgprintf(" dest: %s\n", s2); return result; } static long WINAPI expGetVersionExA(OSVERSIONINFOA* c) { dbgprintf("GetVersionExA(%p) => 1\n", c); c->dwOSVersionInfoSize=sizeof(*c); c->dwMajorVersion=4; c->dwMinorVersion=0; c->dwBuildNumber=0x4000457; #if 1 // leave it here for testing win9x-only codecs c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS; strcpy(c->szCSDVersion, " B"); #else c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers strcpy(c->szCSDVersion, "Service Pack 3"); #endif dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n" " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n"); return 1; } static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, long max_count, char* name) { pthread_mutex_t *pm; pthread_cond_t *pc; /* mutex_list* pp; -- unused */ /* printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>")); pp=mlist; while(pp) { printf("%p => ", pp); pp=pp->prev; } printf("0\n"); */ if(mlist!=NULL) { mutex_list* pp=mlist; if(name!=NULL) do { if((strcmp(pp->name, name)==0) && (pp->type==1)) { dbgprintf("CreateSemaphoreA(%p, init_count %ld, max_count %ld, name %p='%s') => %p\n", v1, init_count, max_count, name, name, mlist); return (HANDLE)mlist; } }while((pp=pp->prev) != NULL); } pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX); pthread_mutex_init(pm, NULL); pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND); pthread_cond_init(pc, NULL); if(mlist==NULL) { mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); mlist->next=mlist->prev=NULL; } else { mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT); mlist->next->prev=mlist; mlist->next->next=NULL; mlist=mlist->next; // printf("new semaphore %p\n", mlist); } mlist->type=1; /* Type Semaphore */ mlist->pm=pm; mlist->pc=pc; mlist->state=0; mlist->reset=0; mlist->semaphore=init_count; if(name!=NULL) strncpy(mlist->name, name, 64); else mlist->name[0]=0; if(pm==NULL) dbgprintf("ERROR::: CreateSemaphoreA failure\n"); if(name) dbgprintf("CreateSemaphoreA(%p, init_count %ld, max_count %ld, name %p='%s') => %p\n", v1, init_count, max_count, name, name, mlist); else dbgprintf("CreateSemaphoreA(%p, init_count %ld, max_count %ld, name NULL) => %p\n", v1, init_count, max_count, mlist); return (HANDLE)mlist; } static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count) { // The state of a semaphore object is signaled when its count // is greater than zero and nonsignaled when its count is equal to zero // Each time a waiting thread is released because of the semaphore's signaled // state, the count of the semaphore is decreased by one. mutex_list *ml = (mutex_list *)hsem; pthread_mutex_lock(ml->pm); if (prev_count != 0) *prev_count = ml->semaphore; if (ml->semaphore == 0) pthread_cond_signal(ml->pc); ml->semaphore += increment; pthread_mutex_unlock(ml->pm); dbgprintf("ReleaseSemaphore(semaphore 0x%lx, increment %ld, prev_count %p) => 1\n", hsem, increment, prev_count); return 1; } static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) { long result=RegOpenKeyExA(key, subkey, reserved, access, newkey); dbgprintf("RegOpenKeyExA(key 0x%lx, subkey %s, reserved %ld, access 0x%lx, pnewkey %p) => %ld\n", key, subkey, reserved, access, newkey, result); if(newkey)dbgprintf(" New key: 0x%x\n", *newkey); return result; } static long WINAPI expRegCloseKey(long key) { long result=RegCloseKey(key); dbgprintf("RegCloseKey(0x%lx) => %ld\n", key, result); return result; } static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) { long result=RegQueryValueExA(key, value, reserved, type, data, count); dbgprintf("RegQueryValueExA(key 0x%lx, value %s, reserved %p, data %p, count %p)" " => 0x%lx\n", key, value, reserved, data, count, result); if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, (char *)data); /* FIXME? */ return result; } static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved, void* classs, long options, long security, void* sec_attr, int* newkey, int* status) { long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status); dbgprintf("RegCreateKeyExA(key 0x%lx, name %p='%s', reserved=0x%lx," " %p, 0x%lx, 0x%lx, %p, newkey=%p, status=%p) => %ld\n", key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result); if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey); if(!result && status) dbgprintf(" New key status: 0x%x\n", *status); return result; } static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size) { long result=RegSetValueExA(key, name, v1, v2, data, size); dbgprintf("RegSetValueExA(key 0x%lx, name '%s', 0x%lx, 0x%lx, data %p -> 0x%x '%s', size=%ld) => %ld", key, name, v1, v2, data, *(int*)data, (char *)data, size, result); return result; } static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult) { long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult); dbgprintf("RegOpenKeyExA(key 0x%lx, subkey '%s', %p) => %ld\n", hKey, lpSubKey, phkResult, result); if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult); return result; } static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count) { return RegEnumValueA(hkey, index, value, val_count, reserved, type, data, count); } static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName, LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass, LPFILETIME lpftLastWriteTime) { return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass, lpcbClass, lpftLastWriteTime); } static long WINAPI expQueryPerformanceCounter(long long* z) { longcount(z); dbgprintf("QueryPerformanceCounter(%p) => 1 ( %Ld )\n", z, *z); return 1; } /* * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo) */ static double linux_cpuinfo_freq() { double freq=-1; FILE *f; char line[200]; char *s,*value; f = fopen ("/proc/cpuinfo", "r"); if (f != NULL) { while (fgets(line,sizeof(line),f)!=NULL) { /* NOTE: the ':' is the only character we can rely on */ if (!(value = strchr(line,':'))) continue; /* terminate the valuename */ *value++ = '\0'; /* skip any leading spaces */ while (*value==' ') value++; if ((s=strchr(value,'\n'))) *s='\0'; if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz")) && sscanf(value, "%lf", &freq) == 1) { freq*=1000; break; } } fclose(f); } return freq; } static double solaris_kstat_freq() { #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32) /* * try to extract the CPU speed from the solaris kernel's kstat data */ kstat_ctl_t *kc; kstat_t *ksp; kstat_named_t *kdata; int mhz = 0; kc = kstat_open(); if (kc != NULL) { ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0"); /* kstat found and name/value pairs? */ if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED) { /* read the kstat data from the kernel */ if (kstat_read(kc, ksp, NULL) != -1) { /* * lookup desired "clock_MHz" entry, check the expected * data type */ kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz"); if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32) mhz = kdata->value.i32; } } kstat_close(kc); } if (mhz > 0) return mhz * 1000.; #endif /* HAVE_LIBKSTAT */ return -1; // kstat stuff is not available, CPU freq is unknown } /* * Measure CPU freq using the pentium's time stamp counter register (TSC) */ static double tsc_freq() { static double ofreq=0.0; int i; int x,y; i=time(NULL); if (ofreq != 0.0) return ofreq; while(i==time(NULL)); x=localcount(); i++; while(i==time(NULL)); y=localcount(); ofreq = (double)(y-x)/1000.; return ofreq; } static double CPU_Freq() { double freq; if ((freq = linux_cpuinfo_freq()) > 0) return freq; if ((freq = solaris_kstat_freq()) > 0) return freq; return tsc_freq(); } static long WINAPI expQueryPerformanceFrequency(long long* z) { *z=(long long)CPU_Freq(); dbgprintf("QueryPerformanceFrequency(%p) => 1 ( %Ld )\n", z, *z); return 1; } static long WINAPI exptimeGetTime() { struct timeval t; long result; gettimeofday(&t, 0); result=1000*t.tv_sec+t.tv_usec/1000; dbgprintf("timeGetTime() => %ld\n", result); return result; } static void* WINAPI expLocalHandle(void* v) { dbgprintf("LocalHandle(%p) => %p\n", v, v); return v; } static void* WINAPI expGlobalHandle(void* v) { dbgprintf("GlobalHandle(%p) => %p\n", v, v); return v; } static int WINAPI expGlobalUnlock(void* v) { dbgprintf("GlobalUnlock(%p) => 1\n", v); return 1; } static void* WINAPI expGlobalFree(void* v) { dbgprintf("GlobalFree(%p) => 0\n", v); my_release(v); //free(v); return 0; } static void* WINAPI expGlobalReAlloc(void* v, int size, int flags) { void* result=my_realloc(v, size); //void* result=realloc(v, size); dbgprintf("GlobalReAlloc(%p, size %d, flags 0x%x) => %p\n", v,size,flags,result); return result; } static int WINAPI expLocalUnlock(void* v) { dbgprintf("LocalUnlock(%p) => 1\n", v); return 1; } // static void* WINAPI expLocalFree(void* v) { dbgprintf("LocalFree(%p) => 0\n", v); my_release(v); return 0; } static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type) { HRSRC result; result=FindResourceA(module, name, type); dbgprintf("FindResourceA(module 0x%x, name %p(%s), type %p(%s)) => 0x%x\n", module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result); return result; } extern HRSRC WINAPI LoadResource(HMODULE, HRSRC); static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res) { HGLOBAL result=LoadResource(module, res); dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result); return result; } static void* WINAPI expLockResource(long res) { void* result=LockResource(res); dbgprintf("LockResource(0x%lx) => %p\n", res, result); return result; } static int WINAPI expFreeResource(long res) { int result=FreeResource(res); dbgprintf("FreeResource(0x%lx) => %d\n", res, result); return result; } //bool fun(HANDLE) //!0 on success static int WINAPI expCloseHandle(long v1) { dbgprintf("CloseHandle(0x%lx) => 1\n", v1); /* do not close stdin,stdout and stderr */ if (v1 > 2) if (!close(v1)) return 0; return 1; } static const char* WINAPI expGetCommandLineA() { dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n"); return "c:\\aviplay.exe"; } static LPWSTR WINAPI expGetEnvironmentStringsW() { dbgprintf("GetEnvironmentStringsW() => 0\n"); return 0; } static void * WINAPI expRtlZeroMemory(void *p, size_t len) { void* result=memset(p,0,len); dbgprintf("RtlZeroMemory(%p, len %d) => %p\n",p,len,result); return result; } static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len) { void* result=memmove(dst,src,len); dbgprintf("RtlMoveMemory (dest %p, src %p, len %d) => %p\n",dst,src,len,result); return result; } static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len) { void* result=memset(p,ch,len); dbgprintf("RtlFillMemory(%p, char 0x%x, len %d) => %p\n",p,ch,len,result); return result; } static int WINAPI expFreeEnvironmentStringsW(short* strings) { dbgprintf("FreeEnvironmentStringsW(%p) => 1\n", strings); return 1; } static int WINAPI expFreeEnvironmentStringsA(char* strings) { dbgprintf("FreeEnvironmentStringsA(%p) => 1\n", strings); return 1; } static const char ch_envs[]= "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n" "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n"; static LPCSTR WINAPI expGetEnvironmentStrings() { dbgprintf("GetEnvironmentStrings() => %p\n", ch_envs); return (LPCSTR)ch_envs; // dbgprintf("GetEnvironmentStrings() => 0\n"); // return 0; } static int WINAPI expGetStartupInfoA(STARTUPINFOA *s) { /* int i; -- unused */ dbgprintf("GetStartupInfoA(%p) => 1\n", s); memset(s, 0, sizeof(*s)); s->cb=sizeof(*s); // s->lpReserved="Reserved"; // s->lpDesktop="Desktop"; // s->lpTitle="Title"; // s->dwX=s->dwY=0; // s->dwXSize=s->dwYSize=200; s->dwFlags=s->wShowWindow=1; // s->hStdInput=s->hStdOutput=s->hStdError=0x1234; dbgprintf(" cb=%ld\n", s->cb); dbgprintf(" lpReserved='%s'\n", s->lpReserved); dbgprintf(" lpDesktop='%s'\n", s->lpDesktop); dbgprintf(" lpTitle='%s'\n", s->lpTitle); dbgprintf(" dwX=%ld dwY=%ld dwXSize=%ld dwYSize=%ld\n", s->dwX, s->dwY, s->dwXSize, s->dwYSize); dbgprintf(" dwXCountChars=%ld dwYCountChars=%ld dwFillAttribute=%ld\n", s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute); dbgprintf(" dwFlags=0x%lx wShowWindow=0x%x cbReserved2=0x%x\n", s->dwFlags, s->wShowWindow, s->cbReserved2); dbgprintf(" lpReserved2=%p hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n", s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError); return 1; } static int WINAPI expGetStdHandle(int z) { z += 0x1234; dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z, z); return z; } #ifdef QTX #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444) #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445) #endif static int WINAPI expGetFileType(int handle) { dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle); return 0x3; } #ifdef QTX static int WINAPI expGetFileAttributesA(char *filename) { dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename); if (strstr(filename, "QuickTime.qts")) return FILE_ATTRIBUTE_SYSTEM; return FILE_ATTRIBUTE_NORMAL; } #endif static int WINAPI expSetHandleCount(int count) { dbgprintf("SetHandleCount(0x%x) => 1\n", count); return 1; } static int WINAPI expGetACP(void) { dbgprintf("GetACP() => 0\n"); return 0; } extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m); static int WINAPI expGetModuleFileNameA(int module, char* s, int len) { WINE_MODREF *mr; int result; //printf("File name of module %X (%s) requested\n", module, s); if (module == 0 && len >= 12) { /* return caller program name */ strcpy(s, "aviplay.dll"); result=1; } else if(s==0) result=0; else if(len<35) result=0; else { result=1; strcpy(s, "c:\\windows\\system\\"); mr=MODULE32_LookupHMODULE(module); if(mr==0)//oops strcat(s, "aviplay.dll"); else if(strrchr(mr->filename, '/')==NULL) strcat(s, mr->filename); else strcat(s, strrchr(mr->filename, '/')+1); } if(!s) dbgprintf("GetModuleFileNameA(0x%x, NULL, %d) => %d\n", module, len, result); else dbgprintf("GetModuleFileNameA(0x%x, %p, %d) => %d ( '%s' )\n", module, s, len, result, s); return result; } static int WINAPI expSetUnhandledExceptionFilter(void* filter) { dbgprintf("SetUnhandledExceptionFilter(%p) => 1\n", filter); return 1;//unsupported and probably won't ever be supported } static int WINAPI expLoadLibraryA(char* name) { int result = 0; char* lastbc; /* int i; */ if (!name) return -1; // we skip to the last backslash // this is effectively eliminating weird characters in // the text output windows lastbc = strrchr(name, '\\'); if (lastbc) { int i; lastbc++; for (i = 0; 1 ;i++) { name[i] = *lastbc++; if (!name[i]) break; } } if(strncmp(name, "c:\\windows\\", 11)==0) name += 11; if(strncmp(name, ".\\", 2)==0) name += 2; dbgprintf("Entering LoadLibraryA(%s)\n", name); // PIMJ and VIVO audio are loading kernel32.dll if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0) return MODULE_HANDLE_kernel32; // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */ /* exported -> do not return failed! */ if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0) // return MODULE_HANDLE_kernel32; return MODULE_HANDLE_user32; #ifdef QTX if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0) return MODULE_HANDLE_wininet; if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0) return MODULE_HANDLE_ddraw; if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0) return MODULE_HANDLE_advapi32; #endif result=LoadLibraryA(name); dbgprintf("Returned LoadLibraryA(%p='%s'), def_path=%s => 0x%x\n", name, name, win32_def_path, result); return result; } static int WINAPI expFreeLibrary(int module) { #ifdef QTX int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */ #else int result=FreeLibrary(module); #endif dbgprintf("FreeLibrary(0x%x) => %d\n", module, result); return result; } static void* WINAPI expGetProcAddress(HMODULE mod, char* name) { void* result; switch(mod){ case MODULE_HANDLE_kernel32: result=LookupExternalByName("kernel32.dll", name); break; case MODULE_HANDLE_user32: result=LookupExternalByName("user32.dll", name); break; #ifdef QTX case MODULE_HANDLE_wininet: result=LookupExternalByName("wininet.dll", name); break; case MODULE_HANDLE_ddraw: result=LookupExternalByName("ddraw.dll", name); break; case MODULE_HANDLE_advapi32: result=LookupExternalByName("advapi32.dll", name); break; #endif default: result=GetProcAddress(mod, name); } dbgprintf("GetProcAddress(0x%x, '%s') => %p\n", mod, name, result); return result; } static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr, long flProtect, long dwMaxHigh, long dwMaxLow, const char* name) { long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name); if(!name) dbgprintf("CreateFileMappingA(file 0x%x, lpAttr %p," "flProtect 0x%lx, dwMaxHigh 0x%lx, dwMaxLow 0x%lx, name 0) => %ld\n", hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result); else dbgprintf("CreateFileMappingA(file 0x%x, lpAttr %p," "flProtect 0x%lx, dwMaxHigh 0x%lx, dwMaxLow 0x%lx, name %p='%s') => %ld\n", hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result); return result; } static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name) { long result=OpenFileMappingA(hFile, hz, name); if(!name) dbgprintf("OpenFileMappingA(0x%lx, 0x%lx, 0) => %ld\n", hFile, hz, result); else dbgprintf("OpenFileMappingA(0x%lx, 0x%lx, %p='%s') => %ld\n", hFile, hz, name, name, result); return result; } static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh, DWORD offLow, DWORD size) { dbgprintf("MapViewOfFile(0x%x, 0x%lx, 0x%lx, 0x%lx, size %ld) => %p\n", file,mode,offHigh,offLow,size,(char*)file+offLow); return (char*)file+offLow; } static void* WINAPI expUnmapViewOfFile(void* view) { dbgprintf("UnmapViewOfFile(%p) => 0\n", view); return 0; } static void* WINAPI expSleep(int time) { #if HAVE_NANOSLEEP /* solaris doesn't have thread safe usleep */ struct timespec tsp; tsp.tv_sec = time / 1000000; tsp.tv_nsec = (time % 1000000) * 1000; nanosleep(&tsp, NULL); #else usleep(time); #endif dbgprintf("Sleep(%d) => 0\n", time); return 0; } // why does IV32 codec want to call this? I don't know ... static int WINAPI expCreateCompatibleDC(int hdc) { int dc = 0;//0x81; //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc); dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc); return dc; } static int WINAPI expGetDeviceCaps(int hdc, int unk) { dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk); #ifdef QTX #define BITSPIXEL 12 #define PLANES 14 if (unk == BITSPIXEL) return 24; if (unk == PLANES) return 1; #endif return 1; } static WIN_BOOL WINAPI expDeleteDC(int hdc) { dbgprintf("DeleteDC(0x%x) => 0\n", hdc); if (hdc == 0x81) return 1; return 0; } static WIN_BOOL WINAPI expDeleteObject(int hdc) { dbgprintf("DeleteObject(0x%x) => 1\n", hdc); /* FIXME - implement code here */ return 1; } /* btvvc32.drv wants this one */ static void* WINAPI expGetWindowDC(int hdc) { dbgprintf("GetWindowDC(%d) => 0x0\n", hdc); return 0; } #ifdef QTX static int WINAPI expGetWindowRect(HWND win, RECT *r) { dbgprintf("GetWindowRect(0x%x, %p) => 1\n", win, r); /* (win == 0) => desktop */ r->right = PSEUDO_SCREEN_WIDTH; r->left = 0; r->bottom = PSEUDO_SCREEN_HEIGHT; r->top = 0; return 1; } static int WINAPI expMonitorFromWindow(HWND win, int flags) { dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags); return 0; } static int WINAPI expMonitorFromRect(RECT *r, int flags) { dbgprintf("MonitorFromRect(%p, 0x%x) => 0\n", r, flags); return 0; } static int WINAPI expMonitorFromPoint(void *p, int flags) { dbgprintf("MonitorFromPoint(%p, 0x%x) => 0\n", p, flags); return 0; } static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r, int WINAPI (*callback_proc)(), void *callback_param) { dbgprintf("EnumDisplayMonitors(%p, %p, %p, %p) => ?\n", dc, r, callback_proc, callback_param); return callback_proc(0, dc, r, callback_param); } #if 0 typedef struct tagMONITORINFO { DWORD cbSize; RECT rcMonitor; RECT rcWork; DWORD dwFlags; } MONITORINFO, *LPMONITORINFO; #endif #define CCHDEVICENAME 8 typedef struct tagMONITORINFOEX { DWORD cbSize; RECT rcMonitor; RECT rcWork; DWORD dwFlags; TCHAR szDevice[CCHDEVICENAME]; } MONITORINFOEX, *LPMONITORINFOEX; static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi) { dbgprintf("GetMonitorInfoA(%p, %p) => 1\n", mon, lpmi); lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH; lpmi->rcMonitor.left = lpmi->rcWork.left = 0; lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT; lpmi->rcMonitor.top = lpmi->rcWork.top = 0; lpmi->dwFlags = 1; /* primary monitor */ if (lpmi->cbSize == sizeof(MONITORINFOEX)) { LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi; dbgprintf("MONITORINFOEX!\n"); strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME); } return 1; } static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum, void *dispdev, int flags) { dbgprintf("EnumDisplayDevicesA(%p = %s, %d, %p, %x) => 1\n", device, device, devnum, dispdev, flags); return 1; } static int WINAPI expIsWindowVisible(HWND win) { dbgprintf("IsWindowVisible(0x%x) => 1\n", win); return 1; } static HWND WINAPI expGetActiveWindow(void) { dbgprintf("GetActiveWindow() => 0\n"); return (HWND)0; } static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount) { strncat(classname, "QuickTime", maxcount); dbgprintf("GetClassNameA(0x%x, %p, %d) => %d\n", win, classname, maxcount, strlen(classname)); return strlen(classname); } #define LPWNDCLASS void * static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass) { dbgprintf("GetClassInfoA(0x%x, %p = %s, %p) => 1\n", inst, classname, classname, wndclass); return 1; } static int WINAPI expGetWindowLongA(HWND win, int index) { dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index); return 1; } static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj) { dbgprintf("GetObjectA(0x%x, %d, %p) => %d\n", hobj, objsize, obj, objsize); return objsize; } static int WINAPI expCreateRectRgn(int x, int y, int width, int height) { dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height); return 0; } static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param) { int i, i2; dbgprintf("EnumWindows(%p, %p) => 1\n", callback_func, callback_param); i = callback_func(0, callback_param); i2 = callback_func(1, callback_param); return i && i2; } static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data) { int tid = (int)pthread_self(); dbgprintf("GetWindowThreadProcessId(0x%x, %p) => %d\n", win, pid_data, tid); if (pid_data) *pid_data = tid; return tid; } //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT, // INT,INT,HWND,HMENU,HINSTANCE,LPVOID); static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname, const char *winname, int style, int x, int y, int w, int h, HWND parent, HMENU menu, HINSTANCE inst, LPVOID param) { printf("CreateWindowEx() called\n"); dbgprintf("CreateWindowEx(%d, %p = %s, %p = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, %p) => 1\n", exstyle, classname, classname, winname, winname, style, x, y, w, h, parent, menu, inst, param); printf("CreateWindowEx() called okey\n"); return 1; } static int WINAPI expwaveOutGetNumDevs(void) { dbgprintf("waveOutGetNumDevs() => 0\n"); return 0; } #endif /* * Returns the number of milliseconds, modulo 2^32, since the start * of the wineserver. */ static int WINAPI expGetTickCount(void) { static int tcstart = 0; struct timeval t; int tc; gettimeofday( &t, NULL ); tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart; if (tcstart == 0) { tcstart = 0; tc = 0; } dbgprintf("GetTickCount() => %d\n", tc); return tc; } static int WINAPI expCreateFontA(void) { dbgprintf("CreateFontA() => 0x0\n"); return 1; } /* tried to get pvmjpg work in a different way - no success */ static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount, LPRECT lpRect, unsigned int uFormat) { dbgprintf("expDrawTextA(%d,...) => 8\n", hDC); (void)lpString; (void)nCount; (void)lpRect; (void)uFormat; return 8; } static int WINAPI expGetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename) { int size=255; char buffer[256]; char* fullname; int result; buffer[255]=0; if(!(appname && keyname && filename) ) { dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value ); return default_value; } fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); strcpy(fullname, "Software\\IniFileMapping\\"); strcat(fullname, appname); strcat(fullname, "\\"); strcat(fullname, keyname); strcat(fullname, "\\"); strcat(fullname, filename); result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size); if((size>=0)&&(size<256)) buffer[size]=0; // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer); free(fullname); if(result) result=default_value; else result=atoi(buffer); dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result); return result; } static int WINAPI expGetProfileIntA(const char* appname, const char* keyname, int default_value) { dbgprintf("GetProfileIntA -> "); return expGetPrivateProfileIntA(appname, keyname, default_value, "default"); } static int WINAPI expGetPrivateProfileStringA(const char* appname, const char* keyname, const char* def_val, char* dest, unsigned int len, const char* filename) { int result; int size; char* fullname; dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', %p, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename ); if(!(appname && keyname && filename) ) return 0; fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); strcpy(fullname, "Software\\IniFileMapping\\"); strcat(fullname, appname); strcat(fullname, "\\"); strcat(fullname, keyname); strcat(fullname, "\\"); strcat(fullname, filename); size=len; result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size); free(fullname); if(result) { int dsize = strlen (def_val); if (size < 0) size = 0; strncpy(dest, def_val, size); if (dsize < size) size = dsize; } dbgprintf(" => %d ( '%s' )\n", size, dest); return size; } static int WINAPI expWritePrivateProfileStringA(const char* appname, const char* keyname, const char* string, const char* filename) { /* int size=256; */ char* fullname; dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename ); if(!(appname && keyname && filename) ) { dbgprintf(" => -1\n"); return -1; } fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); strcpy(fullname, "Software\\IniFileMapping\\"); strcat(fullname, appname); strcat(fullname, "\\"); strcat(fullname, keyname); strcat(fullname, "\\"); strcat(fullname, filename); RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string)); // printf("RegSetValueExA(%s,%d)\n", string, strlen(string)); // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename ); free(fullname); dbgprintf(" => 0\n"); return 0; } unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename) { return expGetPrivateProfileIntA(appname, keyname, default_value, filename); } int _GetPrivateProfileStringA(const char* appname, const char* keyname, const char* def_val, char* dest, unsigned int len, const char* filename) { return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename); } int _WritePrivateProfileStringA(const char* appname, const char* keyname, const char* string, const char* filename) { return expWritePrivateProfileStringA(appname, keyname, string, filename); } static int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2) { dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private, id, msg, arg1, arg2); return 0; } static int WINAPI expSizeofResource(int v1, int v2) { int result=SizeofResource(v1, v2); dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result); return result; } static int WINAPI expGetLastError() { int result=GetLastError(); dbgprintf("GetLastError() => 0x%x\n", result); return result; } static void WINAPI expSetLastError(int error) { dbgprintf("SetLastError(0x%x)\n", error); SetLastError(error); } static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax) { int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", guid->f1, guid->f2, guid->f3, (unsigned char)guid->f4[0], (unsigned char)guid->f4[1], (unsigned char)guid->f4[2], (unsigned char)guid->f4[3], (unsigned char)guid->f4[4], (unsigned char)guid->f4[5], (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]); dbgprintf("StringFromGUID2(%p, %p='%s', %d) => %d\n", guid, str, str, cbMax, result); return result; } static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle) { dbgprintf("GetFileVersionInfoSizeA(%p='%s', %p) => 0\n", name, name, lpHandle); return 0; } static int WINAPI expIsBadStringPtrW(const short* string, int nchars) { int result; if(string==0)result=1; else result=0; dbgprintf("IsBadStringPtrW(%p, %d) => %d", string, nchars, result); if(string)wch_print(string); return result; } static int WINAPI expIsBadStringPtrA(const char* string, int nchars) { return expIsBadStringPtrW((const short*)string, nchars); } static long WINAPI expInterlockedExchangeAdd( long* dest, long incr ) { long ret; __asm__ __volatile__ ( "lock; xaddl %0,(%1)" : "=r" (ret) : "r" (dest), "0" (incr) : "memory" ); return ret; } static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand) { unsigned long retval = *dest; if(*dest == comperand) *dest = exchange; return retval; } static long WINAPI expInterlockedIncrement( long* dest ) { long result=expInterlockedExchangeAdd( dest, 1 ) + 1; dbgprintf("InterlockedIncrement(%p => %ld) => %ld\n", dest, *dest, result); return result; } static long WINAPI expInterlockedDecrement( long* dest ) { long result=expInterlockedExchangeAdd( dest, -1 ) - 1; dbgprintf("InterlockedDecrement(%p => %ld) => %ld\n", dest, *dest, result); return result; } static void WINAPI expOutputDebugStringA( const char* string ) { dbgprintf("OutputDebugStringA(%p='%s')\n", string, string); fprintf(stderr, "DEBUG: %s\n", string); } static int WINAPI expGetDC(int hwnd) { dbgprintf("GetDC(0x%x) => 1\n", hwnd); return 1; } static int WINAPI expReleaseDC(int hwnd, int hdc) { dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc); return 1; } static int WINAPI expGetDesktopWindow() { dbgprintf("GetDesktopWindow() => 0\n"); return 0; } static int cursor[100]; static int WINAPI expLoadCursorA(int handle,LPCSTR name) { dbgprintf("LoadCursorA(%d, %p='%s') => 0x%x\n", handle, name, name, (int)&cursor[0]); return (int)&cursor[0]; } static int WINAPI expSetCursor(void *cursor) { dbgprintf("SetCursor(%p) => %p\n", cursor, cursor); return (int)cursor; } static int WINAPI expGetCursorPos(void *cursor) { dbgprintf("GetCursorPos(%p) => 1\n", cursor); return 1; } #ifdef QTX static int show_cursor = 0; static int WINAPI expShowCursor(int show) { dbgprintf("ShowCursor(%d) => %d\n", show, show); if (show) show_cursor++; else show_cursor--; return show_cursor; } #endif static int WINAPI expRegisterWindowMessageA(char *message) { dbgprintf("RegisterWindowMessageA(%s)\n", message); return 1; } static int WINAPI expGetProcessVersion(int pid) { dbgprintf("GetProcessVersion(%d)\n", pid); return 1; } static int WINAPI expGetCurrentThread(void) { /* #warning FIXME! -- Worry about it later :) */ dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898); return 0xcfcf9898; } static int WINAPI expGetOEMCP(void) { dbgprintf("GetOEMCP()\n"); return 1; } static int WINAPI expGetCPInfo(int cp,void *info) { dbgprintf("GetCPInfo()\n"); (void)cp; (void)info; return 0; } #ifdef QTX #define SM_CXSCREEN 0 #define SM_CYSCREEN 1 #define SM_XVIRTUALSCREEN 76 #define SM_YVIRTUALSCREEN 77 #define SM_CXVIRTUALSCREEN 78 #define SM_CYVIRTUALSCREEN 79 #define SM_CMONITORS 80 #endif static int WINAPI expGetSystemMetrics(int index) { dbgprintf("GetSystemMetrics(%d)\n", index); #ifdef QTX switch(index) { case SM_XVIRTUALSCREEN: case SM_YVIRTUALSCREEN: return 0; case SM_CXSCREEN: case SM_CXVIRTUALSCREEN: return PSEUDO_SCREEN_WIDTH; case SM_CYSCREEN: case SM_CYVIRTUALSCREEN: return PSEUDO_SCREEN_HEIGHT; case SM_CMONITORS: return 1; } #endif return 1; } static int WINAPI expGetSysColor(int index) { dbgprintf("GetSysColor(%d) => 1\n", index); return 1; } static int WINAPI expGetSysColorBrush(int index) { dbgprintf("GetSysColorBrush(%d)\n", index); return 1; } static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe) { dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, %p) => 0\n", hdc, iStartIndex, nEntries, lppe); return 0; } /* typedef struct _TIME_ZONE_INFORMATION { long Bias; char StandardName[32]; SYSTEMTIME StandardDate; long StandardBias; char DaylightName[32]; SYSTEMTIME DaylightDate; long DaylightBias; } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; */ static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation) { static const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a', 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0}; static const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y', 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0}; dbgprintf("GetTimeZoneInformation(%p) => TIME_ZONE_ID_STANDARD\n", lpTimeZoneInformation); memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION)); lpTimeZoneInformation->Bias=360;//GMT-6 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name)); lpTimeZoneInformation->StandardDate.wMonth=10; lpTimeZoneInformation->StandardDate.wDay=5; lpTimeZoneInformation->StandardDate.wHour=2; lpTimeZoneInformation->StandardBias=0; memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname)); lpTimeZoneInformation->DaylightDate.wMonth=4; lpTimeZoneInformation->DaylightDate.wDay=1; lpTimeZoneInformation->DaylightDate.wHour=2; lpTimeZoneInformation->DaylightBias=-60; return TIME_ZONE_ID_STANDARD; } static void WINAPI expGetLocalTime(SYSTEMTIME* systime) { time_t local_time; struct tm *local_tm; struct timeval tv; dbgprintf("GetLocalTime(%p)\n", systime); gettimeofday(&tv, NULL); local_time=tv.tv_sec; local_tm=localtime(&local_time); systime->wYear = local_tm->tm_year + 1900; systime->wMonth = local_tm->tm_mon + 1; systime->wDayOfWeek = local_tm->tm_wday; systime->wDay = local_tm->tm_mday; systime->wHour = local_tm->tm_hour; systime->wMinute = local_tm->tm_min; systime->wSecond = local_tm->tm_sec; systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n" " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n" " Milliseconds: %d\n", systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); } static int WINAPI expGetSystemTime(SYSTEMTIME* systime) { time_t local_time; struct tm *local_tm; struct timeval tv; dbgprintf("GetSystemTime(%p)\n", systime); gettimeofday(&tv, NULL); local_time=tv.tv_sec; local_tm=gmtime(&local_time); systime->wYear = local_tm->tm_year + 1900; systime->wMonth = local_tm->tm_mon + 1; systime->wDayOfWeek = local_tm->tm_wday; systime->wDay = local_tm->tm_mday; systime->wHour = local_tm->tm_hour; systime->wMinute = local_tm->tm_min; systime->wSecond = local_tm->tm_sec; systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n" " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n" " Milliseconds: %d\n", systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); return 0; } #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL) static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime) { /* struct tm *local_tm; -- unused */ struct timeval tv; unsigned long long secs; dbgprintf("GetSystemTime(%p)\n", systime); gettimeofday(&tv, NULL); secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000; secs += tv.tv_usec * 10; systime->dwLowDateTime = secs & 0xffffffff; systime->dwHighDateTime = (secs >> 32); } static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size) { /* char *p; */ // printf("%s %x %x\n", name, field, size); if(field) field[0] = '\0'; /* p = getenv(name); if (p) strncpy(field,p,size); */ if (!field || size < (int)sizeof ("__GLOBAL_HEAP_SELECTED,1")) return 0; if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0) strcpy(field,"__GLOBAL_HEAP_SELECTED,1"); dbgprintf("GetEnvironmentVariableA(%p='%s', %p, %d) => %d\n", name, name, field, size, strlen(field)); return strlen(field); } static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value) { dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value); return 0; } static void* WINAPI expCoTaskMemAlloc(ULONG cb) { return my_mreq(cb, 0); } static void WINAPI expCoTaskMemFree(void* cb) { my_release(cb); } void* CoTaskMemAlloc(unsigned long cb) { return expCoTaskMemAlloc(cb); } void CoTaskMemFree(void* cb) { expCoTaskMemFree(cb); } struct COM_OBJECT_INFO { GUID clsid; long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv); }; static struct COM_OBJECT_INFO* com_object_table=0; static int com_object_size=0; int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs) { if(!clsid || !gcs) return -1; com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size)); com_object_table[com_object_size-1].clsid=*clsid; com_object_table[com_object_size-1].GetClassObject=gcs; return 0; } int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs) { int found = 0; int i = 0; if(!clsid || !gcs) return -1; if (com_object_table == 0) printf("Warning: UnregisterComClass() called without any registered class\n"); while (i < com_object_size) { if (found && i > 0) { memcpy(&com_object_table[i - 1].clsid, &com_object_table[i].clsid, sizeof(GUID)); com_object_table[i - 1].GetClassObject = com_object_table[i].GetClassObject; } else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0 && com_object_table[i].GetClassObject == gcs) { found++; } i++; } if (found) { if (--com_object_size == 0) { free(com_object_table); com_object_table = 0; } } return 0; } const GUID IID_IUnknown = { 0x00000000, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; const GUID IID_IClassFactory = { 0x00000001, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, long dwClsContext, const GUID* riid, void** ppv) { int i; struct COM_OBJECT_INFO* ci=0; (void)pUnkOuter; (void)dwClsContext; for(i=0; i<com_object_size; i++) if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID))) ci=&com_object_table[i]; if(!ci)return REGDB_E_CLASSNOTREG; // in 'real' world we should mess with IClassFactory here i=ci->GetClassObject(rclsid, riid, ppv); return i; } long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, long dwClsContext, const GUID* riid, void** ppv) { return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); } static int WINAPI expIsRectEmpty(CONST RECT *lprc) { int r = 0; int w,h; //trapbug(); if (lprc) { w = lprc->right - lprc->left; h = lprc->bottom - lprc->top; if (w <= 0 || h <= 0) r = 1; } else r = 1; dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE"); //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom); // return 0; // wmv9? return r; // TM20 } static int _adjust_fdiv=0; //what's this? - used to adjust division static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path) { dbgprintf("GetTempPathA(%d, %p)", len, path); if(len<5) { dbgprintf(" => 0\n"); return 0; } strcpy(path, "/tmp"); dbgprintf(" => 5 ( '/tmp' )\n"); return 5; } /* FYI: typedef struct { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD dwReserved0; DWORD dwReserved1; CHAR cFileName[260]; CHAR cAlternateFileName[14]; } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA; */ static DIR* qtx_dir=NULL; static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd) { #ifdef QTX dbgprintf("FindNextFileA(0x%x, %p) => 0\n", h, lpfd); if(h==FILE_HANDLE_quicktimeqtx){ struct dirent* d; if(!qtx_dir) return 0; while((d=readdir(qtx_dir))){ char* x=strrchr(d->d_name,'.'); if(!x) continue; if(strcmp(x,".qtx")) continue; strcpy(lpfd->cFileName,d->d_name); // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name); strcpy(lpfd->cAlternateFileName,"foobar.qtx"); printf("### FindNext: %s\n",lpfd->cFileName); return 1; } closedir(qtx_dir); qtx_dir=NULL; return 0; } #endif return 0; } static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd) { #ifdef QTX if(strstr(s, "*.QTX")){ dbgprintf("FindFirstFileA(%p='%s', %p) => QTX\n", s, s, lpfd); qtx_dir=opendir(win32_def_path); if(!qtx_dir) return (HANDLE)-1; memset(lpfd,0,sizeof(*lpfd)); if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd)) return FILE_HANDLE_quicktimeqtx; printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",win32_def_path); return (HANDLE)-1; } if(strstr(s, "QuickTime.qts")){ dbgprintf("FindFirstFileA(%p='%s', %p) => QTS\n", s, s, lpfd); // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX")) // return (HANDLE)-1; strcpy(lpfd->cFileName, "QuickTime.qts"); strcpy(lpfd->cAlternateFileName, "QuickT~1.qts"); return FILE_HANDLE_quicktimeqts; } #endif if(strstr(s, "*.vwp")){ // hack for VoxWare codec plugins: dbgprintf("FindFirstFileA(%p='%s', %p) => 0\n", s, s, lpfd); strcpy(lpfd->cFileName, "msms001.vwp"); strcpy(lpfd->cAlternateFileName, "msms001.vwp"); return (HANDLE)0; } return (HANDLE)-1; } static WIN_BOOL WINAPI expFindClose(HANDLE h) { dbgprintf("FindClose(0x%x) => 0\n", h); #ifdef QTX // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){ // closedir(qtx_dir); // qtx_dir=NULL; // } #endif return 0; } static UINT WINAPI expSetErrorMode(UINT i) { dbgprintf("SetErrorMode(%d) => 0\n", i); return 0; } static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c) { char windir[]="c:\\windows"; int result; strncpy(s, windir, c); result=1+((c<strlen(windir))?c:strlen(windir)); dbgprintf("GetWindowsDirectoryA(%p, %d) => %d\n", s, c, result); return result; } #ifdef QTX static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s) { char curdir[]="c:\\"; int result; strncpy(s, curdir, c); result=1+((c<strlen(curdir))?c:strlen(curdir)); dbgprintf("GetCurrentDirectoryA(%p, %d) => %d\n", s, c, result); return result; } static int WINAPI expSetCurrentDirectoryA(const char *pathname) { dbgprintf("SetCurrentDirectoryA(%p = %s) => 1\n", pathname, pathname); #if 0 if (strrchr(pathname, '\\')) chdir(strcat(strrchr(pathname, '\\')+1, '/')); else chdir(pathname); #endif return 1; } static int WINAPI expCreateDirectoryA(const char *pathname, void *sa) { dbgprintf("CreateDirectory(%p = %s, %p) => 1\n", pathname, pathname, sa); #if 0 p = strrchr(pathname, '\\')+1; strcpy(&buf[0], p); /* should be strncpy */ if (!strlen(p)) { buf[0] = '.'; buf[1] = 0; } #if 0 if (strrchr(pathname, '\\')) mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666); else mkdir(pathname, 666); #endif mkdir(&buf); #endif return 1; } #endif static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s) { dbgprintf("DeleteFileA(%p='%s') => 0\n", s, s); return 0; } static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf) { dbgprintf("FileTimeToLocalFileTime(%p, %p) => 0\n", cpf, pf); return 0; } static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps) { char mask[16]="/tmp/AP_XXXXXX"; int result; dbgprintf("GetTempFileNameA(%p='%s', %p='%s', %d, %p)", cs1, cs1, cs2, cs2, i, ps); if(i && i<10) { dbgprintf(" => -1\n"); return -1; } result=mkstemp(mask); sprintf(ps, "AP%d", result); dbgprintf(" => %d\n", strlen(ps)); return strlen(ps); } // // This func might need proper implementation if we want AngelPotion codec. // They try to open APmpeg4v1.apl with it. // DLL will close opened file with CloseHandle(). // static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2, LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5) { dbgprintf("CreateFileA(%p='%s', %ld, %ld, %p, %ld, %ld, 0x%x)\n", cs1, cs1, i1, i2, p1, i3, i4, i5); if((!cs1) || (strlen(cs1)<2))return -1; #ifdef QTX if(strstr(cs1, "QuickTime.qts")) { int result; char* tmp=(char*)malloc(strlen(win32_def_path)+50); strcpy(tmp, win32_def_path); strcat(tmp, "/"); strcat(tmp, "QuickTime.qts"); result=open(tmp, O_RDONLY); free(tmp); return result; } if(strstr(cs1, ".qtx")) { int result; char* x=strrchr(cs1,'\\'); char* tmp; asprintf(&tmp,"%s/%s",win32_def_path,x?(x+1):cs1); // printf("### Open: %s -> %s\n",cs1,tmp); result=open(tmp, O_RDONLY); free(tmp); return result; } #endif if(strncmp(cs1, "AP", 2) == 0) { int result; char* tmp=(char*)malloc(strlen(win32_def_path)+50); strcpy(tmp, win32_def_path); strcat(tmp, "/"); strcat(tmp, "APmpg4v1.apl"); result=open(tmp, O_RDONLY); free(tmp); return result; } if (strstr(cs1, "vp3")) { int r; int flg = 0; char* tmp=(char*)malloc(20 + strlen(cs1)); strcpy(tmp, "/tmp/"); strcat(tmp, cs1); r = 4; while (tmp[r]) { if (tmp[r] == ':' || tmp[r] == '\\') tmp[r] = '_'; r++; } if (GENERIC_READ & i1) flg |= O_RDONLY; else if (GENERIC_WRITE & i1) { flg |= O_WRONLY; printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg); } r=open(tmp, flg); free(tmp); return r; } #if 0 /* we need this for some virtualdub filters */ { int r; int flg = 0; if (GENERIC_READ & i1) flg |= O_RDONLY; else if (GENERIC_WRITE & i1) { flg |= O_WRONLY; printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg); } r=open(cs1, flg); return r; } #endif return atoi(cs1+2); } static UINT WINAPI expGetSystemDirectoryA( char* lpBuffer, // address of buffer for system directory UINT uSize // size of directory buffer ){ dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize); if (!lpBuffer || uSize < 2) return 0; strcpy(lpBuffer,"."); return 1; } /* static char sysdir[]="."; static LPCSTR WINAPI expGetSystemDirectoryA() { dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir); return sysdir; } */ static DWORD WINAPI expGetFullPathNameA ( LPCTSTR lpFileName, DWORD nBufferLength, LPTSTR lpBuffer, LPTSTR lpFilePart ){ if(!lpFileName) return 0; dbgprintf("GetFullPathNameA('%s',%ld,%p,%p)\n",lpFileName,nBufferLength, lpBuffer, lpFilePart); #if 0 #ifdef QTX strcpy(lpFilePart, "Quick123.qts"); #else strcpy(lpFilePart, lpFileName); #endif #else if (strrchr(lpFileName, '\\')) *lpFilePart = (int)strrchr(lpFileName, '\\'); else *lpFilePart = (int)lpFileName; #endif strcpy(lpBuffer, lpFileName); // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName); return strlen(lpBuffer); } static DWORD WINAPI expGetShortPathNameA ( LPCSTR longpath, LPSTR shortpath, DWORD shortlen ){ if(!longpath) return 0; dbgprintf("GetShortPathNameA('%s',%p,%ld)\n",longpath,shortpath,shortlen); strcpy(shortpath,longpath); return strlen(shortpath); } static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused) { int result; dbgprintf("ReadFile(%d, %p, %ld -> %p)\n", h, pv, size, rd); (void)unused; result=read(h, pv, size); if(rd)*rd=result; if(!result)return 0; return 1; } static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused) { int result; dbgprintf("WriteFile(%d, %p, %ld -> %p)\n", h, pv, size, wr); (void)unused; if(h==1234)h=1; result=write(h, pv, size); if(wr)*wr=result; if(!result)return 0; return 1; } static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence) { int wh; dbgprintf("SetFilePointer(%d, 0x%lx, %p = %ld, %ld)\n", h, val, ext, ext ? *ext : -1, whence); //why would DLL want temporary file with >2Gb size? switch(whence) { case FILE_BEGIN: wh=SEEK_SET;break; case FILE_END: wh=SEEK_END;break; case FILE_CURRENT: wh=SEEK_CUR;break; default: return -1; } #ifdef QTX if (val == 0 && ext != 0) val = val&(*ext); #endif return lseek(h, val, wh); } static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2) { dbgprintf("OpenDriverA(%p='%s', %p='%s', 0x%lx) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2); return -1; } static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2) { dbgprintf("OpenDriver(%p='%s', %p='%s', 0x%lx) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2); return -1; } static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess, LPDWORD lpProcessAffinityMask, LPDWORD lpSystemAffinityMask) { dbgprintf("GetProcessAffinityMask(0x%x, %p, %p) => 1\n", hProcess, lpProcessAffinityMask, lpSystemAffinityMask); if(lpProcessAffinityMask)*lpProcessAffinityMask=1; if(lpSystemAffinityMask)*lpSystemAffinityMask=1; return 1; } static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator) { static const long long max_int=0x7FFFFFFFLL; static const long long min_int=-0x80000000LL; long long tmp=(long long)nNumber*(long long)nNumerator; dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator); if(!nDenominator)return 1; tmp/=nDenominator; if(tmp<min_int) return 1; if(tmp>max_int) return 1; return (int)tmp; } static LONG WINAPI explstrcmpiA(const char* str1, const char* str2) { LONG result=strcasecmp(str1, str2); dbgprintf("strcmpi(%p='%s', %p='%s') => %ld\n", str1, str1, str2, str2, result); return result; } static LONG WINAPI explstrlenA(const char* str1) { LONG result=strlen(str1); dbgprintf("strlen(%p='%.50s') => %ld\n", str1, str1, result); return result; } static LONG WINAPI explstrcpyA(char* str1, const char* str2) { int result= (int) strcpy(str1, str2); dbgprintf("strcpy(%p, %p='%.50s') => %d\n", str1, str2, str2, result); return result; } static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len) { int result; if ((int)strlen (str2) > len) result = (int) strncpy(str1, str2,len); else result = (int) strcpy(str1,str2); dbgprintf("strncpy(%p, %p='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result); return result; } static LONG WINAPI explstrcatA(char* str1, const char* str2) { int result= (int) strcat(str1, str2); dbgprintf("strcat(%p, %p='%s') => %d\n", str1, str2, str2, result); return result; } static LONG WINAPI expInterlockedExchange(long *dest, long l) { long retval = *dest; *dest = l; return retval; } static void WINAPI expInitCommonControls(void) { dbgprintf("InitCommonControls called!\n"); return; } #ifdef QTX /* needed by QuickTime.qts */ static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy, HWND parent, INT id, HINSTANCE inst, HWND buddy, INT maxVal, INT minVal, INT curVal) { dbgprintf("CreateUpDownControl(...)\n"); (void)style; (void)x; (void)y; (void)cx; (void)cy; (void)parent; (void)id; (void)inst; (void)buddy; (void)maxVal; (void)minVal; (void)curVal; return 0; } #endif /* alex: implement this call! needed for 3ivx */ static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner) { dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n", pUnkOuter, ppUnkInner); // return 0; return ERROR_CALL_NOT_IMPLEMENTED; } static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process HANDLE hSourceHandle, // handle to duplicate HANDLE hTargetProcessHandle, // handle to target process HANDLE* lpTargetHandle, // duplicate handle DWORD dwDesiredAccess, // requested access int bInheritHandle, // handle inheritance option DWORD dwOptions // optional actions ) { dbgprintf("DuplicateHandle(0x%x, 0x%x, 0x%x, %p, 0x%lx, %d, %ld) called\n", hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions); *lpTargetHandle = hSourceHandle; return 1; } // required by PIM1 codec (used by win98 PCTV Studio capture sw) static HRESULT WINAPI expCoInitialize( LPVOID lpReserved /* [in] pointer to win32 malloc interface (obsolete, should be NULL) */ ) { /* * Just delegate to the newer method. */ (void)lpReserved; return 0; //CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED); } static DWORD WINAPI expSetThreadAffinityMask ( HANDLE hThread, DWORD dwThreadAffinityMask ){ (void)hThread; (void)dwThreadAffinityMask; return 0; }; /* * no WINAPI functions - CDECL */ static void* expmalloc(int size) { //printf("malloc"); // return malloc(size); void* result=my_mreq(size,0); dbgprintf("malloc(0x%x) => %p\n", size,result); if(result==0) printf("WARNING: malloc() failed\n"); return result; } static void expfree(void* mem) { // return free(mem); dbgprintf("free(%p)\n", mem); my_release(mem); } /* needed by atrac3.acm */ static void *expcalloc(int num, int size) { void* result=my_mreq(num*size,1); dbgprintf("calloc(%d,%d) => %p\n", num,size,result); if(result==0) printf("WARNING: calloc() failed\n"); return result; } static void* expnew(int size) { // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size)); // printf("%08x %08x %08x %08x\n", // size, *(1+(int*)&size), // *(2+(int*)&size),*(3+(int*)&size)); void* result; assert(size >= 0); result=my_mreq(size,0); dbgprintf("new(%d) => %p\n", size, result); if (result==0) printf("WARNING: new() failed\n"); return result; } static int expdelete(void* memory) { dbgprintf("delete(%p)\n", memory); my_release(memory); return 0; } /* * local definition - we need only the last two members at this point * otherwice we would have to introduce here GUIDs and some more types.. */ typedef struct __attribute__((__packed__)) { char hay[0x40]; unsigned long cbFormat; //0x40 char* pbFormat; //0x44 } MY_MEDIA_TYPE; static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src) { if (!dest || !src) return E_POINTER; memcpy(dest, src, sizeof(MY_MEDIA_TYPE)); if (dest->cbFormat) { dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0); if (!dest->pbFormat) return E_OUTOFMEMORY; memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat); } return S_OK; } static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat) { if (!dest) return E_POINTER; memset(dest, 0, sizeof(MY_MEDIA_TYPE)); if (cbFormat) { dest->pbFormat = (char*) my_mreq(cbFormat, 0); if (!dest->pbFormat) return E_OUTOFMEMORY; } return S_OK; } static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat) { if (!dest) return E_POINTER; *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0); return expMoInitMediaType(*dest, cbFormat); } static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src) { if (!dest) return E_POINTER; *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0); return expMoCopyMediaType(*dest, src); } static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest) { if (!dest) return E_POINTER; if (dest->pbFormat) { my_release(dest->pbFormat); dest->pbFormat = 0; dest->cbFormat = 0; } return S_OK; } static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest) { if (!dest) return E_POINTER; expMoFreeMediaType(dest); my_release(dest); return S_OK; } #if 0 static int exp_initterm(int v1, int v2) { dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); return 0; } #else /* merged from wine - 2002.04.21 */ typedef void (*_INITTERMFUNC)(); static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end) { dbgprintf("_initterm(%p, %p) %p\n", start, end, *start); while (start < end) { if (*start) { //printf("call _initfunc: from: %p %d\n", *start); // ok this trick with push/pop is necessary as otherwice // edi/esi registers are being trashed void* p = *start; __asm__ __volatile__ ( "pushl %%ebx \n\t" "pushl %%ecx \n\t" "pushl %%edx \n\t" "pushl %%edi \n\t" "pushl %%esi \n\t" "call *%%eax \n\t" "popl %%esi \n\t" "popl %%edi \n\t" "popl %%edx \n\t" "popl %%ecx \n\t" "popl %%ebx \n\t" : : "a"(p) : "memory" ); //printf("done %p %d:%d\n", end); } start++; } return 0; } #endif static void* exp__dllonexit() { // FIXME extract from WINE return NULL; } static int XINE_FORMAT_PRINTF(2, 3) expwsprintfA(char* string, char* format, ...) { va_list va; int result; va_start(va, format); result = vsprintf(string, format, va); dbgprintf("wsprintfA(%p, '%s', ...) => %d\n", string, format, result); va_end(va); return result; } static int XINE_FORMAT_PRINTF(2, 3) expsprintf(char* str, const char* format, ...) { va_list args; int r; dbgprintf("sprintf(%s, %s)\n", str, format); va_start(args, format); r = vsprintf(str, format, args); va_end(args); return r; } static int XINE_FORMAT_SCANF(2, 3) expsscanf(const char* str, const char* format, ...) { va_list args; int r; dbgprintf("sscanf(%s, %s)\n", str, format); va_start(args, format); r = vsscanf(str, format, args); va_end(args); return r; } static void* expfopen(const char* path, const char* mode) { printf("fopen: \"%s\" mode:%s\n", path, mode); //return fopen(path, mode); return fdopen(0, mode); // everything on screen } static int XINE_FORMAT_PRINTF(2, 3)expfprintf(void* stream, const char* format, ...) { va_list args; int r = 0; dbgprintf("fprintf(%p, %s, ...)\n", stream, format); #if 1 va_start(args, format); r = vfprintf((FILE*) stream, format, args); va_end(args); #endif return r; } static int XINE_FORMAT_PRINTF(1, 2) expprintf(const char* format, ...) { va_list args; int r; dbgprintf("printf(%s, ...)\n", format); va_start(args, format); r = vprintf(format, args); va_end(args); return r; } static char* expgetenv(const char* varname) { char* v = getenv(varname); dbgprintf("getenv(%s) => %s\n", varname, v); return v; } static void* expwcscpy(WCHAR* dst, const WCHAR* src) { WCHAR* p = dst; while ((*p++ = *src++)) ; return dst; } static char* expstrrchr(char* string, int value) { char* result=strrchr(string, value); if(result) dbgprintf("strrchr(%p='%s', %d) => %p='%s'", string, string, value, result, result); else dbgprintf("strrchr(%p='%s', %d) => 0", string, string, value); return result; } static char* expstrchr(char* string, int value) { char* result=strchr(string, value); if(result) dbgprintf("strchr(%p='%s', %d) => %p='%s'", string, string, value, result, result); else dbgprintf("strchr(%p='%s', %d) => 0", string, string, value); return result; } static int expstrlen(char* str) { int result=strlen(str); dbgprintf("strlen(%p='%s') => %d\n", str, str, result); return result; } static char* expstrcpy(char* str1, const char* str2) { char* result= strcpy(str1, str2); dbgprintf("strcpy(%p, %p='%s') => %p\n", str1, str2, str2, result); return result; } static int expstrcmp(const char* str1, const char* str2) { int result=strcmp(str1, str2); dbgprintf("strcmp(%p='%s', %p='%s') => %d\n", str1, str1, str2, str2, result); return result; } static int expstrncmp(const char* str1, const char* str2,int x) { int result=strncmp(str1, str2,x); dbgprintf("strcmp(%p='%s', %p='%s') => %d\n", str1, str1, str2, str2, result); return result; } static char* expstrcat(char* str1, const char* str2) { char* result = strcat(str1, str2); dbgprintf("strcat(%p='%s', %p='%s') => %p\n", str1, str1, str2, str2, result); return result; } static char* exp_strdup(const char* str1) { int l = strlen(str1); char* result = (char*) my_mreq(l + 1,0); if (result) strcpy(result, str1); dbgprintf("_strdup(%p='%s') => %p\n", str1, str1, result); return result; } static int expisalnum(int c) { int result= (int) isalnum(c); dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result); return result; } static int expisspace(int c) { int result= (int) isspace(c); dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result); return result; } static int expisalpha(int c) { int result= (int) isalpha(c); dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result); return result; } static int expisdigit(int c) { int result= (int) isdigit(c); dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result); return result; } static void* expmemmove(void* dest, void* src, int n) { void* result = memmove(dest, src, n); dbgprintf("memmove(%p, %p, %d) => %p\n", dest, src, n, result); return result; } static int expmemcmp(void* dest, void* src, int n) { int result = memcmp(dest, src, n); dbgprintf("memcmp(%p, %p, %d) => %d\n", dest, src, n, result); return result; } static void* expmemcpy(void* dest, void* src, int n) { void *result = memcpy(dest, src, n); dbgprintf("memcpy(%p, %p, %d) => %p\n", dest, src, n, result); return result; } static void* expmemset(void* dest, int c, size_t n) { void *result = memset(dest, c, n); dbgprintf("memset(%p, %d, %d) => %p\n", dest, c, n, result); return result; } static time_t exptime(time_t* t) { time_t result = time(t); dbgprintf("time(%p) => %ld\n", t, (long int)result); return result; } static int exprand(void) { return rand(); } static void expsrand(int seed) { srand(seed); } #if 1 // prefered compilation with -O2 -ffast-math ! static double explog10(double x) { /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/ return log10(x); } static double expcos(double x) { /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/ return cos(x); } #else /* doens't work */ static long exp_ftol_wrong(double x) { return (long) x; } static void explog10(void) { __asm__ __volatile__ ( "fldl 8(%esp) \n\t" "fldln2 \n\t" "fxch %st(1) \n\t" "fyl2x \n\t" ); } static void expcos(void) { __asm__ __volatile__ ( "fldl 8(%esp) \n\t" "fcos \n\t" ); } #endif // this seem to be the only how to make this function working properly // ok - I've spent tremendous amount of time (many many many hours // of debuging fixing & testing - it's almost unimaginable - kabi // _ftol - operated on the float value which is already on the FPU stack static void exp_ftol(void) { __asm__ __volatile__ ( "sub $12, %esp \n\t" "fstcw -2(%ebp) \n\t" "wait \n\t" "movw -2(%ebp), %ax \n\t" "orb $0x0C, %ah \n\t" "movw %ax, -4(%ebp) \n\t" "fldcw -4(%ebp) \n\t" "fistpl -12(%ebp) \n\t" "fldcw -2(%ebp) \n\t" "movl -12(%ebp), %eax \n\t" //Note: gcc 3.03 does not do the following op if it // knows that ebp=esp "movl %ebp, %esp \n\t" ); } #define FPU_DOUBLES(var1,var2) double var1,var2; \ __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \ __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : ) static double exp_CIpow(void) { FPU_DOUBLES(x,y); dbgprintf("_CIpow(%lf, %lf)\n", x, y); return pow(x, y); } static double exppow(double x, double y) { /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/ return pow(x, y); } static double expldexp(double x, int expo) { /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/ return ldexp(x, expo); } static double expfrexp(double x, int* expo) { /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/ return frexp(x, expo); } static int exp_stricmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } /* from declaration taken from Wine sources - this fountion seems to be * undocumented in any M$ doc */ static int exp_setjmp3(void* jmpbuf, int x) { #if 0 dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x); return 0; #else (void)x; __asm__ __volatile__ ( //"mov 4(%%esp), %%edx \n\t" "mov (%%esp), %%eax \n\t" "mov %%eax, (%%edx) \n\t" // store ebp //"mov %%ebp, (%%edx) \n\t" "mov %%ebx, 4(%%edx) \n\t" "mov %%edi, 8(%%edx) \n\t" "mov %%esi, 12(%%edx) \n\t" "mov %%esp, 16(%%edx) \n\t" "mov 4(%%esp), %%eax \n\t" "mov %%eax, 20(%%edx) \n\t" "movl $0x56433230, 32(%%edx) \n\t" // VC20 ?? "movl $0, 36(%%edx) \n\t" : // output : "d"(jmpbuf) // input : "eax" ); # if 1 __asm__ __volatile__ ( "mov %%fs:0, %%eax \n\t" // unsure "mov %%eax, 24(%%edx) \n\t" "cmp $0xffffffff, %%eax \n\t" "jnz l1 \n\t" "mov %%eax, 28(%%edx) \n\t" "l1: \n\t" : : : "eax" ); # endif #endif return 0; } static DWORD WINAPI expGetCurrentProcessId(void) { dbgprintf("GetCurrentProcessId(void) => %d\n", getpid()); return getpid(); //(DWORD)NtCurrentTeb()->pid; } typedef struct { UINT wPeriodMin; UINT wPeriodMax; } TIMECAPS, *LPTIMECAPS; static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize) { dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize); lpCaps->wPeriodMin = 1; lpCaps->wPeriodMax = 65535; return 0; } static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod) { dbgprintf("timeBeginPeriod(%u) !\n", wPeriod); if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO; return 0; } #ifdef QTX static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod) { dbgprintf("timeEndPeriod(%u) !\n", wPeriod); if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO; return 0; } #endif static void WINAPI expGlobalMemoryStatus( LPMEMORYSTATUS lpmem ) { static MEMORYSTATUS cached_memstatus; static int cache_lastchecked = 0; SYSTEM_INFO si; FILE *f; if (time(NULL)==cache_lastchecked) { memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS)); return; } #if 1 f = fopen( "/proc/meminfo", "r" ); if (f) { char buffer[256]; int total, used, free, shared, buffers, cached; lpmem->dwLength = sizeof(MEMORYSTATUS); lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0; lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0; while (fgets( buffer, sizeof(buffer), f )) { /* old style /proc/meminfo ... */ if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached )) { lpmem->dwTotalPhys += total; lpmem->dwAvailPhys += free + buffers + cached; } if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free )) { lpmem->dwTotalPageFile += total; lpmem->dwAvailPageFile += free; } /* new style /proc/meminfo ... */ if (sscanf(buffer, "MemTotal: %d", &total)) lpmem->dwTotalPhys = total*1024; if (sscanf(buffer, "MemFree: %d", &free)) lpmem->dwAvailPhys = free*1024; if (sscanf(buffer, "SwapTotal: %d", &total)) lpmem->dwTotalPageFile = total*1024; if (sscanf(buffer, "SwapFree: %d", &free)) lpmem->dwAvailPageFile = free*1024; if (sscanf(buffer, "Buffers: %d", &buffers)) lpmem->dwAvailPhys += buffers*1024; if (sscanf(buffer, "Cached: %d", &cached)) lpmem->dwAvailPhys += cached*1024; } fclose( f ); if (lpmem->dwTotalPhys) { DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile; DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile; lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical) / (TotalPhysical / 100); } } else #endif { /* FIXME: should do something for other systems */ lpmem->dwMemoryLoad = 0; lpmem->dwTotalPhys = 16*1024*1024; lpmem->dwAvailPhys = 16*1024*1024; lpmem->dwTotalPageFile = 16*1024*1024; lpmem->dwAvailPageFile = 16*1024*1024; } expGetSystemInfo(&si); lpmem->dwTotalVirtual = (char *)si.lpMaximumApplicationAddress-(char *)si.lpMinimumApplicationAddress; /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */ lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024; memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS)); cache_lastchecked = time(NULL); /* it appears some memory display programs want to divide by these values */ if(lpmem->dwTotalPageFile==0) lpmem->dwTotalPageFile++; if(lpmem->dwAvailPageFile==0) lpmem->dwAvailPageFile++; } /********************************************************************** * SetThreadPriority [KERNEL32.@] Sets priority for thread. * * RETURNS * Success: TRUE * Failure: FALSE */ static WIN_BOOL WINAPI expSetThreadPriority( HANDLE hthread, /* [in] Handle to thread */ INT priority) /* [in] Thread priority level */ { dbgprintf("SetThreadPriority(0x%x,%d)\n",hthread,priority); return TRUE; } static void WINAPI expExitProcess( DWORD status ) { printf("EXIT - code %d\n",(int)status); exit(status); } static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){ printf("MSGBOX '%s' '%s' (%d)\n",text,title,type); (void)hWnd; #ifdef QTX if (type == MB_ICONHAND && !strlen(text) && !strlen(title)) return IDIGNORE; #endif return IDOK; } /* these are needed for mss1 */ /* defined in stubs.s */ void exp_EH_prolog(void); #include <netinet/in.h> static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong) { // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong)); return htonl(hostlong); } static WINAPI inline unsigned long int expntohl(unsigned long int netlong) { // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong)); return ntohl(netlong); } static void WINAPI expVariantInit(void* p) { printf("InitCommonControls called!\n"); (void)p; return; } int expRegisterClassA(const void/*WNDCLASSA*/ *wc) { dbgprintf("RegisterClassA(%p) => random id\n", wc); return time(NULL); /* be precise ! */ } int expUnregisterClassA(const char *className, HINSTANCE hInstance) { dbgprintf("UnregisterClassA(%s, 0x%x) => 0\n", className, hInstance); return 0; } #ifdef QTX /* should be fixed bcs it's not fully strlen equivalent */ static int expSysStringByteLen(void *str) { dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str)); return strlen(str); } static int expDirectDrawCreate(void) { dbgprintf("DirectDrawCreate(...) => NULL\n"); return 0; } #if 1 typedef struct tagPALETTEENTRY { BYTE peRed; BYTE peGreen; BYTE peBlue; BYTE peFlags; } PALETTEENTRY; /* reversed the first 2 entries */ typedef struct tagLOGPALETTE { WORD palNumEntries; WORD palVersion; PALETTEENTRY palPalEntry[1]; } LOGPALETTE; static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl) { HPALETTE test; int i; dbgprintf("CreatePalette(%p) => NULL\n", lpgpl); i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY)); test = (HPALETTE)malloc(i); /* preventive expect bad values leading to overapping */ memmove((void *)test, lpgpl, i); return test; } #else static int expCreatePalette(void) { dbgprintf("CreatePalette(...) => NULL\n"); return NULL; } #endif static int WINAPI expGetClientRect(HWND win, RECT *r) { dbgprintf("GetClientRect(0x%x, %p) => 1\n", win, r); r->right = PSEUDO_SCREEN_WIDTH; r->left = 0; r->bottom = PSEUDO_SCREEN_HEIGHT; r->top = 0; return 1; } #if 0 typedef struct tagPOINT { LONG x; LONG y; } POINT, *PPOINT; #endif static int WINAPI expClientToScreen(HWND win, POINT *p) { dbgprintf("ClientToScreen(0x%x, %p = %ld,%ld) => 1\n", win, p, p->x, p->y); p->x = 0; p->y = 0; return 1; } #endif /* for m3jpeg */ static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc) { dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc); return 0; } static int WINAPI expMessageBeep(int type) { dbgprintf("MessageBeep(%d) => 1\n", type); return 1; } static int WINAPI expDialogBoxParamA(void *inst, const char *name, HWND parent, void *dialog_func, void *init_param) { dbgprintf("DialogBoxParamA(%p, %p = %s, 0x%x, %p, %p) => 0x42424242\n", inst, name, name, parent, dialog_func, init_param); return 0x42424242; } /* needed by imagepower mjpeg2k */ static void *exprealloc(void *ptr, size_t size) { dbgprintf("realloc(%p, %x)\n", ptr, size); if (!ptr) return my_mreq(size,0); else return my_realloc(ptr, size); } static double expfloor(double x) { dbgprintf("floor(%lf)\n", x); return floor(x); } #define FPU_DOUBLE(var) double var; \ __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : ) static double exp_CIcos(void) { FPU_DOUBLE(x); dbgprintf("_CIcos(%lf)\n", x); return cos(x); } static double exp_CIsin(void) { FPU_DOUBLE(x); dbgprintf("_CIsin(%lf)\n", x); return sin(x); } struct exports { char name[64]; int id; void* func; }; struct libs { char name[64]; int length; struct exports* exps; }; #define FF(X,Y) \ {#X, Y, (void*)exp##X}, struct exports exp_kernel32[]= { FF(IsBadWritePtr, 357) FF(IsBadReadPtr, 354) FF(IsBadStringPtrW, -1) FF(IsBadStringPtrA, -1) FF(DisableThreadLibraryCalls, -1) FF(CreateThread, -1) FF(CreateEventA, -1) FF(SetEvent, -1) FF(ResetEvent, -1) FF(WaitForSingleObject, -1) #ifdef QTX FF(WaitForMultipleObjects, -1) FF(ExitThread, -1) FF(CreateMutexA,-1) FF(ReleaseMutex,-1) #endif FF(GetSystemInfo, -1) FF(GetVersion, 332) FF(HeapCreate, 461) FF(HeapAlloc, -1) FF(HeapDestroy, -1) FF(HeapFree, -1) FF(HeapSize, -1) FF(HeapReAlloc,-1) FF(GetProcessHeap, -1) FF(VirtualAlloc, -1) FF(VirtualFree, -1) FF(InitializeCriticalSection, -1) FF(EnterCriticalSection, -1) FF(LeaveCriticalSection, -1) FF(DeleteCriticalSection, -1) FF(TlsAlloc, -1) FF(TlsFree, -1) FF(TlsGetValue, -1) FF(TlsSetValue, -1) FF(GetCurrentThreadId, -1) FF(GetCurrentProcess, -1) FF(LocalAlloc, -1) FF(LocalReAlloc,-1) FF(LocalLock, -1) FF(GlobalAlloc, -1) FF(GlobalReAlloc, -1) FF(GlobalLock, -1) FF(GlobalSize, -1) FF(MultiByteToWideChar, 427) FF(WideCharToMultiByte, -1) FF(GetVersionExA, -1) FF(CreateSemaphoreA, -1) FF(QueryPerformanceCounter, -1) FF(QueryPerformanceFrequency, -1) FF(LocalHandle, -1) FF(LocalUnlock, -1) FF(LocalFree, -1) FF(GlobalHandle, -1) FF(GlobalUnlock, -1) FF(GlobalFree, -1) FF(LoadResource, -1) FF(ReleaseSemaphore, -1) FF(FindResourceA, -1) FF(LockResource, -1) FF(FreeResource, -1) FF(SizeofResource, -1) FF(CloseHandle, -1) FF(GetCommandLineA, -1) FF(GetEnvironmentStringsW, -1) FF(FreeEnvironmentStringsW, -1) FF(FreeEnvironmentStringsA, -1) FF(GetEnvironmentStrings, -1) FF(GetStartupInfoA, -1) FF(GetStdHandle, -1) FF(GetFileType, -1) #ifdef QTX FF(GetFileAttributesA, -1) #endif FF(SetHandleCount, -1) FF(GetACP, -1) FF(GetModuleFileNameA, -1) FF(SetUnhandledExceptionFilter, -1) FF(LoadLibraryA, -1) FF(GetProcAddress, -1) FF(FreeLibrary, -1) FF(CreateFileMappingA, -1) FF(OpenFileMappingA, -1) FF(MapViewOfFile, -1) FF(UnmapViewOfFile, -1) FF(Sleep, -1) FF(GetModuleHandleA, -1) FF(GetProfileIntA, -1) FF(GetPrivateProfileIntA, -1) FF(GetPrivateProfileStringA, -1) FF(WritePrivateProfileStringA, -1) FF(GetLastError, -1) FF(SetLastError, -1) FF(InterlockedIncrement, -1) FF(InterlockedDecrement, -1) FF(GetTimeZoneInformation, -1) FF(OutputDebugStringA, -1) FF(GetLocalTime, -1) FF(GetSystemTime, -1) FF(GetSystemTimeAsFileTime, -1) FF(GetEnvironmentVariableA, -1) FF(SetEnvironmentVariableA, -1) FF(RtlZeroMemory,-1) FF(RtlMoveMemory,-1) FF(RtlFillMemory,-1) FF(GetTempPathA,-1) FF(FindFirstFileA,-1) FF(FindNextFileA,-1) FF(FindClose,-1) FF(FileTimeToLocalFileTime,-1) FF(DeleteFileA,-1) FF(ReadFile,-1) FF(WriteFile,-1) FF(SetFilePointer,-1) FF(GetTempFileNameA,-1) FF(CreateFileA,-1) FF(GetSystemDirectoryA,-1) FF(GetWindowsDirectoryA,-1) #ifdef QTX FF(GetCurrentDirectoryA,-1) FF(SetCurrentDirectoryA,-1) FF(CreateDirectoryA,-1) #endif FF(GetShortPathNameA,-1) FF(GetFullPathNameA,-1) FF(SetErrorMode, -1) FF(IsProcessorFeaturePresent, -1) FF(GetProcessAffinityMask, -1) FF(InterlockedExchange, -1) FF(InterlockedCompareExchange, -1) FF(MulDiv, -1) FF(lstrcmpiA, -1) FF(lstrlenA, -1) FF(lstrcpyA, -1) FF(lstrcatA, -1) FF(lstrcpynA,-1) FF(GetProcessVersion,-1) FF(GetCurrentThread,-1) FF(GetOEMCP,-1) FF(GetCPInfo,-1) FF(DuplicateHandle,-1) FF(GetTickCount, -1) FF(SetThreadAffinityMask,-1) FF(GetCurrentProcessId,-1) FF(GlobalMemoryStatus,-1) FF(SetThreadPriority,-1) FF(ExitProcess,-1) {"LoadLibraryExA", -1, (void*)&LoadLibraryExA}, FF(SetThreadIdealProcessor,-1) }; struct exports exp_msvcrt[]={ FF(malloc, -1) FF(_initterm, -1) FF(__dllonexit, -1) FF(free, -1) {"??3@YAXPAX@Z", -1, expdelete}, {"??2@YAPAXI@Z", -1, expnew}, {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, FF(strrchr, -1) FF(strchr, -1) FF(strlen, -1) FF(strcpy, -1) FF(wcscpy, -1) FF(strcmp, -1) FF(strncmp, -1) FF(strcat, -1) FF(_stricmp,-1) FF(_strdup,-1) FF(_setjmp3,-1) FF(isalnum, -1) FF(isspace, -1) FF(isalpha, -1) FF(isdigit, -1) FF(memmove, -1) FF(memcmp, -1) FF(memset, -1) FF(memcpy, -1) FF(time, -1) FF(rand, -1) FF(srand, -1) FF(log10, -1) FF(pow, -1) FF(cos, -1) FF(_ftol,-1) FF(_CIpow,-1) FF(_CIcos,-1) FF(_CIsin,-1) FF(ldexp,-1) FF(frexp,-1) FF(sprintf,-1) FF(sscanf,-1) FF(fopen,-1) FF(fprintf,-1) FF(printf,-1) FF(getenv,-1) FF(floor,-1) FF(_EH_prolog,-1) FF(calloc,-1) {"ceil",-1,(void*)&ceil}, /* needed by imagepower mjpeg2k */ {"clock",-1,(void*)&clock}, {"memchr",-1,(void*)&memchr}, {"vfprintf",-1,(void*)&vfprintf}, // {"realloc",-1,(void*)&realloc}, FF(realloc,-1) {"puts",-1,(void*)&puts} }; struct exports exp_winmm[]={ FF(GetDriverModuleHandle, -1) FF(timeGetTime, -1) FF(DefDriverProc, -1) FF(OpenDriverA, -1) FF(OpenDriver, -1) FF(timeGetDevCaps, -1) FF(timeBeginPeriod, -1) #ifdef QTX FF(timeEndPeriod, -1) FF(waveOutGetNumDevs, -1) #endif }; struct exports exp_user32[]={ FF(LoadStringA, -1) FF(wsprintfA, -1) FF(GetDC, -1) FF(GetDesktopWindow, -1) FF(ReleaseDC, -1) FF(IsRectEmpty, -1) FF(LoadCursorA,-1) FF(SetCursor,-1) FF(GetCursorPos,-1) #ifdef QTX FF(ShowCursor,-1) #endif FF(RegisterWindowMessageA,-1) FF(GetSystemMetrics,-1) FF(GetSysColor,-1) FF(GetSysColorBrush,-1) FF(GetWindowDC, -1) FF(DrawTextA, -1) FF(MessageBoxA, -1) FF(RegisterClassA, -1) FF(UnregisterClassA, -1) #ifdef QTX FF(GetWindowRect, -1) FF(MonitorFromWindow, -1) FF(MonitorFromRect, -1) FF(MonitorFromPoint, -1) FF(EnumDisplayMonitors, -1) FF(GetMonitorInfoA, -1) FF(EnumDisplayDevicesA, -1) FF(GetClientRect, -1) FF(ClientToScreen, -1) FF(IsWindowVisible, -1) FF(GetActiveWindow, -1) FF(GetClassNameA, -1) FF(GetClassInfoA, -1) FF(GetWindowLongA, -1) FF(EnumWindows, -1) FF(GetWindowThreadProcessId, -1) FF(CreateWindowExA, -1) #endif FF(MessageBeep, -1) FF(DialogBoxParamA, -1) }; struct exports exp_advapi32[]={ FF(RegCloseKey, -1) FF(RegCreateKeyExA, -1) FF(RegEnumKeyExA, -1) FF(RegEnumValueA, -1) FF(RegOpenKeyA, -1) FF(RegOpenKeyExA, -1) FF(RegQueryValueExA, -1) FF(RegSetValueExA, -1) }; struct exports exp_gdi32[]={ FF(CreateCompatibleDC, -1) FF(CreateFontA, -1) FF(DeleteDC, -1) FF(DeleteObject, -1) FF(GetDeviceCaps, -1) FF(GetSystemPaletteEntries, -1) #ifdef QTX FF(CreatePalette, -1) FF(GetObjectA, -1) FF(CreateRectRgn, -1) #endif }; struct exports exp_version[]={ FF(GetFileVersionInfoSizeA, -1) }; struct exports exp_ole32[]={ FF(CoCreateFreeThreadedMarshaler,-1) FF(CoCreateInstance, -1) FF(CoInitialize, -1) FF(CoTaskMemAlloc, -1) FF(CoTaskMemFree, -1) FF(StringFromGUID2, -1) }; // do we really need crtdll ??? // msvcrt is the correct place probably... struct exports exp_crtdll[]={ FF(memcpy, -1) FF(wcscpy, -1) }; struct exports exp_comctl32[]={ FF(StringFromGUID2, -1) FF(InitCommonControls, 17) #ifdef QTX FF(CreateUpDownControl, 16) #endif }; struct exports exp_wsock32[]={ FF(htonl,8) FF(ntohl,14) }; struct exports exp_msdmo[]={ FF(memcpy, -1) // just test FF(MoCopyMediaType, -1) FF(MoCreateMediaType, -1) FF(MoDeleteMediaType, -1) FF(MoDuplicateMediaType, -1) FF(MoFreeMediaType, -1) FF(MoInitMediaType, -1) }; struct exports exp_oleaut32[]={ FF(VariantInit, 8) #ifdef QTX FF(SysStringByteLen, 149) #endif }; /* realplayer8: DLL Name: PNCRT.dll vma: Hint/Ord Member-Name 22ff4 615 free 2302e 250 _ftol 22fea 666 malloc 2303e 609 fprintf 2305e 167 _adjust_fdiv 23052 280 _initterm 22ffc 176 _beginthreadex 23036 284 _iob 2300e 85 __CxxFrameHandler 23022 411 _purecall */ #ifdef REALPLAYER struct exports exp_pncrt[]={ FF(malloc, -1) // just test FF(free, -1) // just test FF(fprintf, -1) // just test {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, FF(_ftol,-1) FF(_initterm, -1) }; #endif #ifdef QTX struct exports exp_ddraw[]={ FF(DirectDrawCreate, -1) }; #endif #define LL(X) \ {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X}, struct libs libraries[]={ LL(kernel32) LL(msvcrt) LL(winmm) LL(user32) LL(advapi32) LL(gdi32) LL(version) LL(ole32) LL(oleaut32) LL(crtdll) LL(comctl32) LL(wsock32) LL(msdmo) #ifdef REALPLAYER LL(pncrt) #endif #ifdef QTX LL(ddraw) #endif }; #include "mangle.h" static void ext_stubs(void) { // expects: // ax position index // cx address of printf function #if 1 __asm__ __volatile__ ( "push %%edx \n\t" "movl $0xdeadbeef, %%eax \n\t" "movl $0xdeadbeef, %%edx \n\t" "shl $5, %%eax \n\t" // ax * 32 "addl $0xdeadbeef, %%eax \n\t" // overwrite export_names "pushl %%eax \n\t" "pushl $0xdeadbeef \n\t" // overwrite called_unk "call *%%edx \n\t" // printf (via dx) "addl $8, %%esp \n\t" "xorl %%eax, %%eax \n\t" "pop %%edx \n\t" : : : "eax" ); #else __asm__ __volatile__ ( "push %%edx \n\t" "movl $0, %%eax \n\t" "movl $0, %%edx \n\t" "shl $5, %%eax \n\t" // ax * 32 "addl %0, %%eax \n\t" "pushl %%eax \n\t" "pushl %1 \n\t" "call *%%edx \n\t" // printf (via dx) "addl $8, %%esp \n\t" "xorl %%eax, %%eax \n\t" "pop %%edx \n\t" ::"m"(*export_names), "m"(*called_unk) : "memory", "edx", "eax" ); #endif } //static void add_stub(int pos) extern int unk_exp1; static int pos=0; static char extcode[20000];// place for 200 unresolved exports static const char* called_unk = "Called unk_%s\n"; static void* add_stub(void) { // generated code in runtime! char* answ = (char*)extcode+pos*0x30; int i; /* xine: check if stub for this export was created before */ for(i = 0; i < pos; i++) { if(strcmp(export_names[pos], export_names[i])==0) return extcode+i*0x30; /* return existing stub */ } /* xine: side effect of the stub fix. we must not * allocate a stub for this function otherwise QT dll * will try to call it. */ if( strcmp(export_names[pos], "AllocateAndInitializeSid") == 0 ) { return 0; } #if 0 memcpy(answ, &unk_exp1, 0x64); *(int*)(answ+9)=pos; *(int*)(answ+47)-=((int)answ-(int)&unk_exp1); #endif memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size //answ[4] = 0xb8; // movl $0, eax (0xb8 0x00000000) *((int*) (answ + 5)) = pos; //answ[9] = 0xba; // movl $0, edx (0xba 0x00000000) *((long*) (answ + 10)) = (long)printf; //answ[17] = 0x05; // addl $0, eax (0x05 0x00000000) *((long*) (answ + 18)) = (long)export_names; //answ[23] = 0x68; // pushl $0 (0x68 0x00000000) *((long*) (answ + 24)) = (long)called_unk; /* xine: don't overflow the stub tables */ if ((pos < (int)(sizeof (extcode) / 0x30) - 1) && (pos < (int)(sizeof (export_names) / sizeof (export_names[0])) - 1)) { pos++; } else { strcpy(export_names[pos], "too many unresolved exports"); } return (void*)answ; } void* LookupExternal(const char* library, int ordinal) { int i,j; if(library==0) { printf("ERROR: library=0\n"); return (void*)ext_unknown; } // printf("%x %x\n", &unk_exp1, &unk_exp2); printf("External func %s:%d\n", library, ordinal); for (i = 0; i < (int)(sizeof (libraries) / sizeof (struct libs)); i++) { if(strcasecmp(library, libraries[i].name)) continue; for(j=0; j<libraries[i].length; j++) { if(ordinal!=libraries[i].exps[j].id) continue; //printf("Hit: %p\n", libraries[i].exps[j].func); return libraries[i].exps[j].func; } } #ifdef LOADLIB_TRY_NATIVE /* ok, this is a hack, and a big memory leak. should be fixed. - alex */ { int hand; WINE_MODREF *wm; void *func; hand = LoadLibraryA(library); if (!hand) goto no_dll; wm = MODULE32_LookupHMODULE(hand); if (!wm) { FreeLibrary(hand); goto no_dll; } func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0); if (!func) { printf("No such ordinal in external dll\n"); FreeLibrary((int)hand); goto no_dll; } printf("External dll loaded (offset: 0x%x, func: %p)\n", hand, func); return func; } no_dll: #endif /* xine: pos is now tested inside add_stub() if(pos>150)return 0; */ sprintf(export_names[pos], "%s:%d", library, ordinal); return add_stub(); } void* LookupExternalByName(const char* library, const char* name) { /* char* answ; -- unused */ int i,j; // return (void*)ext_unknown; if(library==0) { printf("ERROR: library=0\n"); return (void*)ext_unknown; } if(name==0) { printf("ERROR: name=0\n"); return (void*)ext_unknown; } dbgprintf("External func %s:%s\n", library, name); for (i = 0; i < (int)(sizeof (libraries) / sizeof (struct libs)); i++) { if(strcasecmp(library, libraries[i].name)) continue; for(j=0; j<libraries[i].length; j++) { if(strcmp(name, libraries[i].exps[j].name)) continue; // printf("Hit: 0x%08X\n", libraries[i].exps[j].func); return libraries[i].exps[j].func; } } /* xine: pos is now tested inside add_stub() if(pos>150)return 0;// to many symbols */ strcpy(export_names[pos], name); return add_stub(); } void my_garbagecollection(void) { #ifdef GARBAGE int unfree = 0, unfreecnt = 0; int max_fatal = 8; free_registry(); while (last_alloc) { alloc_header* mem = last_alloc + 1; unfree += my_size(mem); unfreecnt++; if (my_release(mem) != 0) // avoid endless loop when memory is trashed if (--max_fatal < 0) break; } printf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt); #endif g_tls = NULL; list = NULL; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/vfw.h���������������������������������������������������������������0000644�0001750�0001750�00000050157�14647725152�015176� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_VFW_H #define __WINE_VFW_H //#include "pshpack1.h" #ifdef __cplusplus extern "C" { #endif #ifndef __WINE_WINGDI_H typedef struct __attribute__((__packed__)) { short bfType; long bfSize; short bfReserved1; short bfReserved2; long bfOffBits; } BITMAPFILEHEADER; #ifndef _BITMAPINFOHEADER_ #define _BITMAPINFOHEADER_ typedef struct __attribute__((__packed__)) { long biSize; long biWidth; long biHeight; short biPlanes; short biBitCount; long biCompression; long biSizeImage; long biXPelsPerMeter; long biYPelsPerMeter; long biClrUsed; long biClrImportant; } BITMAPINFOHEADER, *PBITMAPINFOHEADER, *LPBITMAPINFOHEADER; typedef struct { BITMAPINFOHEADER bmiHeader; int bmiColors[1]; } BITMAPINFO, *LPBITMAPINFO; #endif #endif #define VFWAPI #define VFWAPIV #ifndef __WINE_WINDEF_H typedef long (__stdcall__ *DRIVERPROC)(long,HDRVR,unsigned int,long,long); #endif #ifndef mmioFOURCC #define mmioFOURCC( ch0, ch1, ch2, ch3 ) \ ( (long)(unsigned char)(ch0) | ( (long)(unsigned char)(ch1) << 8 ) | \ ( (long)(unsigned char)(ch2) << 16 ) | ( (long)(unsigned char)(ch3) << 24 ) ) #endif #ifndef aviTWOCC #define aviTWOCC(ch0, ch1) ((short)(unsigned char)(ch0) | ((short)(unsigned char)(ch1) << 8)) #endif #define ICTYPE_VIDEO mmioFOURCC('v', 'i', 'd', 'c') #define ICTYPE_AUDIO mmioFOURCC('a', 'u', 'd', 'c') /* Installable Compressor M? */ /* HIC struct (same layout as Win95 one) */ typedef struct tagWINE_HIC { long magic; /* 00: 'Smag' */ HANDLE curthread; /* 04: */ long type; /* 08: */ long handler; /* 0C: */ HDRVR hdrv; /* 10: */ long driverid; /* 14:(handled by SendDriverMessage)*/ DRIVERPROC driverproc; /* 18:(handled by SendDriverMessage)*/ long x1; /* 1c: name? */ short x2; /* 20: */ long x3; /* 22: */ /* 26: */ } WINE_HIC; /* error return codes */ #define ICERR_OK 0 #define ICERR_DONTDRAW 1 #define ICERR_NEWPALETTE 2 #define ICERR_GOTOKEYFRAME 3 #define ICERR_STOPDRAWING 4 #define ICERR_UNSUPPORTED -1 #define ICERR_BADFORMAT -2 #define ICERR_MEMORY -3 #define ICERR_INTERNAL -4 #define ICERR_BADFLAGS -5 #define ICERR_BADPARAM -6 #define ICERR_BADSIZE -7 #define ICERR_BADHANDLE -8 #define ICERR_CANTUPDATE -9 #define ICERR_ABORT -10 #define ICERR_ERROR -100 #define ICERR_BADBITDEPTH -200 #define ICERR_BADIMAGESIZE -201 #define ICERR_CUSTOM -400 /* ICM Messages */ #define ICM_USER (DRV_USER+0x0000) /* ICM driver message range */ #define ICM_RESERVED_LOW (DRV_USER+0x1000) #define ICM_RESERVED_HIGH (DRV_USER+0x2000) #define ICM_RESERVED ICM_RESERVED_LOW #define ICM_GETSTATE (ICM_RESERVED+0) #define ICM_SETSTATE (ICM_RESERVED+1) #define ICM_GETINFO (ICM_RESERVED+2) #define ICM_CONFIGURE (ICM_RESERVED+10) #define ICM_ABOUT (ICM_RESERVED+11) /* */ #define ICM_GETDEFAULTQUALITY (ICM_RESERVED+30) #define ICM_GETQUALITY (ICM_RESERVED+31) #define ICM_SETQUALITY (ICM_RESERVED+32) #define ICM_SET (ICM_RESERVED+40) #define ICM_GET (ICM_RESERVED+41) /* 2 constant FOURCC codes */ #define ICM_FRAMERATE mmioFOURCC('F','r','m','R') #define ICM_KEYFRAMERATE mmioFOURCC('K','e','y','R') #define ICM_COMPRESS_GET_FORMAT (ICM_USER+4) #define ICM_COMPRESS_GET_SIZE (ICM_USER+5) #define ICM_COMPRESS_QUERY (ICM_USER+6) #define ICM_COMPRESS_BEGIN (ICM_USER+7) #define ICM_COMPRESS (ICM_USER+8) #define ICM_COMPRESS_END (ICM_USER+9) #define ICM_DECOMPRESS_GET_FORMAT (ICM_USER+10) #define ICM_DECOMPRESS_QUERY (ICM_USER+11) #define ICM_DECOMPRESS_BEGIN (ICM_USER+12) #define ICM_DECOMPRESS (ICM_USER+13) #define ICM_DECOMPRESS_END (ICM_USER+14) #define ICM_DECOMPRESS_SET_PALETTE (ICM_USER+29) #define ICM_DECOMPRESS_GET_PALETTE (ICM_USER+30) #define ICM_DRAW_QUERY (ICM_USER+31) #define ICM_DRAW_BEGIN (ICM_USER+15) #define ICM_DRAW_GET_PALETTE (ICM_USER+16) #define ICM_DRAW_START (ICM_USER+18) #define ICM_DRAW_STOP (ICM_USER+19) #define ICM_DRAW_END (ICM_USER+21) #define ICM_DRAW_GETTIME (ICM_USER+32) #define ICM_DRAW (ICM_USER+33) #define ICM_DRAW_WINDOW (ICM_USER+34) #define ICM_DRAW_SETTIME (ICM_USER+35) #define ICM_DRAW_REALIZE (ICM_USER+36) #define ICM_DRAW_FLUSH (ICM_USER+37) #define ICM_DRAW_RENDERBUFFER (ICM_USER+38) #define ICM_DRAW_START_PLAY (ICM_USER+39) #define ICM_DRAW_STOP_PLAY (ICM_USER+40) #define ICM_DRAW_SUGGESTFORMAT (ICM_USER+50) #define ICM_DRAW_CHANGEPALETTE (ICM_USER+51) #define ICM_GETBUFFERSWANTED (ICM_USER+41) #define ICM_GETDEFAULTKEYFRAMERATE (ICM_USER+42) #define ICM_DECOMPRESSEX_BEGIN (ICM_USER+60) #define ICM_DECOMPRESSEX_QUERY (ICM_USER+61) #define ICM_DECOMPRESSEX (ICM_USER+62) #define ICM_DECOMPRESSEX_END (ICM_USER+63) #define ICM_COMPRESS_FRAMES_INFO (ICM_USER+70) #define ICM_SET_STATUS_PROC (ICM_USER+72) /* structs */ typedef struct { long dwSize; /* 00: size */ long fccType; /* 04: type 'vidc' usually */ long fccHandler; /* 08: */ long dwVersion; /* 0c: version of compman opening you */ long dwFlags; /* 10: LOshort is type specific */ LRESULT dwError; /* 14: */ void* pV1Reserved; /* 18: */ void* pV2Reserved; /* 1c: */ long dnDevNode; /* 20: */ /* 24: */ } ICOPEN,*LPICOPEN; #define ICCOMPRESS_KEYFRAME 0x00000001L typedef struct { long dwFlags; LPBITMAPINFOHEADER lpbiOutput; void* lpOutput; LPBITMAPINFOHEADER lpbiInput; const void* lpInput; long* lpckid; long* lpdwFlags; long lFrameNum; long dwFrameSize; long dwQuality; LPBITMAPINFOHEADER lpbiPrev; void* lpPrev; } ICCOMPRESS; long VFWAPIV ICCompress( HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData, LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid, long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality, LPBITMAPINFOHEADER lpbiPrev,void* lpPrev ); #define ICCompressGetFormat(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic,ICM_COMPRESS_GET_FORMAT,(long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressGetFormatSize(hic,lpbi) ICCompressGetFormat(hic,lpbi,NULL) #define ICGetDefaultKeyFrameRate(hic,lpint) \ ICSendMessage( \ hic, ICM_GETDEFAULTKEYFRAMERATE, \ (long)(void*)(lpint), \ 0 ) #define ICGetDefaultQuality(hic,lpint) \ ICSendMessage( \ hic, ICM_GETDEFAULTQUALITY, \ (long)(void*)(lpint), \ 0 ) #define ICCompressBegin(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_COMPRESS_BEGIN, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressGetSize(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_COMPRESS_GET_SIZE, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressQuery(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_COMPRESS_QUERY, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICCompressEnd(hic) ICSendMessage(hic, ICM_COMPRESS_END, 0, 0) /* ICCOMPRESSFRAMES.dwFlags */ #define ICCOMPRESSFRAMES_PADDING 0x00000001 typedef struct { long dwFlags; LPBITMAPINFOHEADER lpbiOutput; LPARAM lOutput; LPBITMAPINFOHEADER lpbiInput; LPARAM lInput; long lStartFrame; long lFrameCount; long lQuality; long lDataRate; long lKeyRate; long dwRate; long dwScale; long dwOverheadPerFrame; long dwReserved2; long CALLBACK (*GetData)(LPARAM lInput,long lFrame,void* lpBits,long len); long CALLBACK (*PutData)(LPARAM lOutput,long lFrame,void* lpBits,long len); } ICCOMPRESSFRAMES; /* Values for wMode of ICOpen() */ #define ICMODE_COMPRESS 1 #define ICMODE_DECOMPRESS 2 #define ICMODE_FASTDECOMPRESS 3 #define ICMODE_QUERY 4 #define ICMODE_FASTCOMPRESS 5 #define ICMODE_DRAW 8 /* quality flags */ #define ICQUALITY_LOW 0 #define ICQUALITY_HIGH 10000 #define ICQUALITY_DEFAULT -1 typedef struct { long dwSize; /* 00: */ long fccType; /* 04:compressor type 'vidc' 'audc' */ long fccHandler; /* 08:compressor sub-type 'rle ' 'jpeg' 'pcm '*/ long dwFlags; /* 0c:flags LOshort is type specific */ long dwVersion; /* 10:version of the driver */ long dwVersionICM; /* 14:version of the ICM used */ /* * under Win32, the driver always returns UNICODE strings. */ WCHAR szName[16]; /* 18:short name */ WCHAR szDescription[128]; /* 38:long name */ WCHAR szDriver[128]; /* 138:driver that contains compressor*/ /* 238: */ } ICINFO; /* ICINFO.dwFlags */ #define VIDCF_QUALITY 0x0001 /* supports quality */ #define VIDCF_CRUNCH 0x0002 /* supports crunching to a frame size */ #define VIDCF_TEMPORAL 0x0004 /* supports inter-frame compress */ #define VIDCF_COMPRESSFRAMES 0x0008 /* wants the compress all frames message */ #define VIDCF_DRAW 0x0010 /* supports drawing */ #define VIDCF_FASTTEMPORALC 0x0020 /* does not need prev frame on compress */ #define VIDCF_FASTTEMPORALD 0x0080 /* does not need prev frame on decompress */ #define VIDCF_QUALITYTIME 0x0040 /* supports temporal quality */ #define VIDCF_FASTTEMPORAL (VIDCF_FASTTEMPORALC|VIDCF_FASTTEMPORALD) /* function shortcuts */ /* ICM_ABOUT */ #define ICMF_ABOUT_QUERY 0x00000001 #define ICQueryAbout(hic) \ (ICSendMessage(hic,ICM_ABOUT,(long)-1,ICMF_ABOUT_QUERY)==ICERR_OK) #define ICAbout(hic, hwnd) ICSendMessage(hic,ICM_ABOUT,(long)(unsigned int)(hwnd),0) /* ICM_CONFIGURE */ #define ICMF_CONFIGURE_QUERY 0x00000001 #define ICQueryConfigure(hic) \ (ICSendMessage(hic,ICM_CONFIGURE,(long)-1,ICMF_CONFIGURE_QUERY)==ICERR_OK) #define ICConfigure(hic,hwnd) \ ICSendMessage(hic,ICM_CONFIGURE,(long)(unsigned int)(hwnd),0) /* Decompression stuff */ #define ICDECOMPRESS_HURRYUP 0x80000000 /* don't draw just buffer (hurry up!) */ #define ICDECOMPRESS_UPDATE 0x40000000 /* don't draw just update screen */ #define ICDECOMPRESS_PREROL 0x20000000 /* this frame is before real start */ #define ICDECOMPRESS_NULLFRAME 0x10000000 /* repeat last frame */ #define ICDECOMPRESS_NOTKEYFRAME 0x08000000 /* this frame is not a key frame */ typedef struct { long dwFlags; /* flags (from AVI index...) */ LPBITMAPINFOHEADER lpbiInput; /* BITMAPINFO of compressed data */ const void* lpInput; /* compressed data */ LPBITMAPINFOHEADER lpbiOutput; /* DIB to decompress to */ void* lpOutput; long ckid; /* ckid from AVI file */ } ICDECOMPRESS; typedef struct { long dwFlags; LPBITMAPINFOHEADER lpbiSrc; const void* lpSrc; LPBITMAPINFOHEADER lpbiDst; void* lpDst; /* changed for ICM_DECOMPRESSEX */ INT xDst; /* destination rectangle */ INT yDst; INT dxDst; INT dyDst; INT xSrc; /* source rectangle */ INT ySrc; INT dxSrc; INT dySrc; } ICDECOMPRESSEX; long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits); long VFWAPIV ICDecompressEx(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits); long VFWAPIV ICUniversalEx(HIC hic,int command,LPBITMAPINFOHEADER lpbiFormat,LPBITMAPINFOHEADER lpbi); #define ICDecompressBegin(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_DECOMPRESS_BEGIN, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICDecompressBeginEx(hic, lpbiInput, lpbiOutput) \ ICUniversalEx( \ hic, ICM_DECOMPRESSEX_BEGIN, (lpbiInput), \ (lpbiOutput) \ ) #define ICDecompressQuery(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic,ICM_DECOMPRESS_QUERY, (long)(void*)(lpbiInput), \ (long) (void*)(lpbiOutput) \ ) #define ICDecompressQueryEx(hic, lpbiInput, lpbiOutput) \ ICUniversalEx( \ hic,ICM_DECOMPRESSEX_QUERY, (lpbiInput), \ (lpbiOutput) \ ) #define ICDecompressGetFormat(hic, lpbiInput, lpbiOutput) \ ((long)ICSendMessage( \ hic,ICM_DECOMPRESS_GET_FORMAT, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ )) #define ICDecompressGetFormatSize(hic, lpbi) \ ICDecompressGetFormat(hic, lpbi, NULL) #define ICDecompressGetPalette(hic, lpbiInput, lpbiOutput) \ ICSendMessage( \ hic, ICM_DECOMPRESS_GET_PALETTE, (long)(void*)(lpbiInput), \ (long)(void*)(lpbiOutput) \ ) #define ICDecompressSetPalette(hic,lpbiPalette) \ ICSendMessage( \ hic,ICM_DECOMPRESS_SET_PALETTE, \ (long)(void*)(lpbiPalette),0 \ ) #define ICDecompressEnd(hic) ICSendMessage(hic, ICM_DECOMPRESS_END, 0, 0) #define ICDecompressEndEx(hic) ICSendMessage(hic,ICM_DECOMPRESSEX_END, 0, 0) #define ICDRAW_QUERY 0x00000001L /* test for support */ #define ICDRAW_FULLSCREEN 0x00000002L /* draw to full screen */ #define ICDRAW_HDC 0x00000004L /* draw to a HDC/HWND */ long VFWAPI VideoForWindowsVersion(void); WIN_BOOL VFWAPI ICInfo(long fccType, long fccHandler, ICINFO * lpicinfo); LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo, long cb); HIC VFWAPI ICOpen(long fccType, long fccHandler, UINT wMode); //HIC VFWAPI ICOpenFunction(long fccType, long fccHandler, unsigned int wMode, void* lpfnHandler); LRESULT VFWAPI ICClose(HIC hic); LRESULT VFWAPI ICSendMessage(HIC hic, unsigned int msg, long dw1, long dw2); //HIC VFWAPI ICLocate(long fccType, long fccHandler, LPBITMAPINFOHEADER lpbiIn, LPBITMAPINFOHEADER lpbiOut, short wFlags); int VFWAPI ICDoSomething(void); long VFWAPIV ICDrawBegin( HIC hic, long dwFlags,/* flags */ HPALETTE hpal, /* palette to draw with */ HWND hwnd, /* window to draw to */ HDC hdc, /* HDC to draw to */ INT xDst, /* destination rectangle */ INT yDst, INT dxDst, INT dyDst, LPBITMAPINFOHEADER lpbi, /* format of frame to draw */ INT xSrc, /* source rectangle */ INT ySrc, INT dxSrc, INT dySrc, long dwRate, /* frames/second = (dwRate/dwScale) */ long dwScale ); /* as passed to ICM_DRAW_BEGIN (FIXME: correct only for Win32?) */ typedef struct { long dwFlags; HPALETTE hpal; HWND hwnd; HDC hdc; INT xDst; INT yDst; INT dxDst; INT dyDst; LPBITMAPINFOHEADER lpbi; INT xSrc; INT ySrc; INT dxSrc; INT dySrc; long dwRate; long dwScale; } ICDRAWBEGIN; #define ICDRAW_HURRYUP 0x80000000L /* don't draw just buffer (hurry up!) */ #define ICDRAW_UPDATE 0x40000000L /* don't draw just update screen */ #define ICDRAW_PREROLL 0x20000000L /* this frame is before real start */ #define ICDRAW_NULLFRAME 0x10000000L /* repeat last frame */ #define ICDRAW_NOTKEYFRAME 0x08000000L /* this frame is not a key frame */ typedef struct { long dwFlags; void* lpFormat; void* lpData; long cbData; long lTime; } ICDRAW; long VFWAPIV ICDraw(HIC hic,long dwFlags,void* lpFormat,void* lpData,long cbData,long lTime); #define AVIGETFRAMEF_BESTDISPLAYFMT 1 typedef struct _AVISTREAMINFOA { long fccType; long fccHandler; long dwFlags; /* AVIIF_* */ long dwCaps; short wPriority; short wLanguage; long dwScale; long dwRate; /* dwRate / dwScale == samples/second */ long dwStart; long dwLength; /* In units above... */ long dwInitialFrames; long dwSuggestedBufferSize; long dwQuality; long dwSampleSize; RECT rcFrame; long dwEditCount; long dwFormatChangeCount; char szName[64]; } AVISTREAMINFOA, * LPAVISTREAMINFOA, *PAVISTREAMINFOA; typedef struct _AVISTREAMINFOW { long fccType; long fccHandler; long dwFlags; long dwCaps; short wPriority; short wLanguage; long dwScale; long dwRate; /* dwRate / dwScale == samples/second */ long dwStart; long dwLength; /* In units above... */ long dwInitialFrames; long dwSuggestedBufferSize; long dwQuality; long dwSampleSize; RECT rcFrame; long dwEditCount; long dwFormatChangeCount; short szName[64]; } AVISTREAMINFOW, * LPAVISTREAMINFOW, *PAVISTREAMINFOW; DECL_WINELIB_TYPE_AW(AVISTREAMINFO) DECL_WINELIB_TYPE_AW(LPAVISTREAMINFO) DECL_WINELIB_TYPE_AW(PAVISTREAMINFO) #define AVISTREAMINFO_DISABLED 0x00000001 #define AVISTREAMINFO_FORMATCHANGES 0x00010000 /* AVIFILEINFO.dwFlags */ #define AVIFILEINFO_HASINDEX 0x00000010 #define AVIFILEINFO_MUSTUSEINDEX 0x00000020 #define AVIFILEINFO_ISINTERLEAVED 0x00000100 #define AVIFILEINFO_WASCAPTUREFILE 0x00010000 #define AVIFILEINFO_COPYRIGHTED 0x00020000 /* AVIFILEINFO.dwCaps */ #define AVIFILECAPS_CANREAD 0x00000001 #define AVIFILECAPS_CANWRITE 0x00000002 #define AVIFILECAPS_ALLKEYFRAMES 0x00000010 #define AVIFILECAPS_NOCOMPRESSION 0x00000020 typedef struct _AVIFILEINFOW { long dwMaxBytesPerSec; long dwFlags; long dwCaps; long dwStreams; long dwSuggestedBufferSize; long dwWidth; long dwHeight; long dwScale; long dwRate; long dwLength; long dwEditCount; short szFileType[64]; } AVIFILEINFOW, * LPAVIFILEINFOW, *PAVIFILEINFOW; typedef struct _AVIFILEINFOA { long dwMaxBytesPerSec; long dwFlags; long dwCaps; long dwStreams; long dwSuggestedBufferSize; long dwWidth; long dwHeight; long dwScale; long dwRate; long dwLength; long dwEditCount; char szFileType[64]; } AVIFILEINFOA, * LPAVIFILEINFOA, *PAVIFILEINFOA; DECL_WINELIB_TYPE_AW(AVIFILEINFO) DECL_WINELIB_TYPE_AW(PAVIFILEINFO) DECL_WINELIB_TYPE_AW(LPAVIFILEINFO) /* AVICOMPRESSOPTIONS.dwFlags. determines presence of fields in below struct */ #define AVICOMPRESSF_INTERLEAVE 0x00000001 #define AVICOMPRESSF_DATARATE 0x00000002 #define AVICOMPRESSF_KEYFRAMES 0x00000004 #define AVICOMPRESSF_VALID 0x00000008 typedef struct { long fccType; /* stream type, for consistency */ long fccHandler; /* compressor */ long dwKeyFrameEvery; /* keyframe rate */ long dwQuality; /* compress quality 0-10,000 */ long dwBytesPerSecond; /* unsigned chars per second */ long dwFlags; /* flags... see below */ void* lpFormat; /* save format */ long cbFormat; void* lpParms; /* compressor options */ long cbParms; long dwInterleaveEvery; /* for non-video streams only */ } AVICOMPRESSOPTIONS, *LPAVICOMPRESSOPTIONS,*PAVICOMPRESSOPTIONS; typedef struct { long cbSize; // set to sizeof(COMPVARS) before // calling ICCompressorChoose long dwFlags; // see below... HIC hic; // HIC of chosen compressor long fccType; // basically ICTYPE_VIDEO long fccHandler; // handler of chosen compressor or // "" or "DIB " LPBITMAPINFO lpbiIn; // input format LPBITMAPINFO lpbiOut; // output format - will compress to this void* lpBitsOut; void* lpBitsPrev; long lFrame; long lKey; // key frames how often? long lDataRate; // desired data rate KB/Sec long lQ; // desired quality long lKeyCount; void* lpState; // state of compressor long cbState; // size of the state } COMPVARS, *PCOMPVARS; // FLAGS for dwFlags element of COMPVARS structure: #define AVIERR_OK 0 #define MAKE_AVIERR(error) MAKE_SCODE(SEVERITY_ERROR,FACILITY_ITF,0x4000+error) #define AVIERR_UNSUPPORTED MAKE_AVIERR(101) #define AVIERR_BADFORMAT MAKE_AVIERR(102) #define AVIERR_MEMORY MAKE_AVIERR(103) #define AVIERR_INTERNAL MAKE_AVIERR(104) #define AVIERR_BADFLAGS MAKE_AVIERR(105) #define AVIERR_BADPARAM MAKE_AVIERR(106) #define AVIERR_BADSIZE MAKE_AVIERR(107) #define AVIERR_BADHANDLE MAKE_AVIERR(108) #define AVIERR_FILEREAD MAKE_AVIERR(109) #define AVIERR_FILEWRITE MAKE_AVIERR(110) #define AVIERR_FILEOPEN MAKE_AVIERR(111) #define AVIERR_COMPRESSOR MAKE_AVIERR(112) #define AVIERR_NOCOMPRESSOR MAKE_AVIERR(113) #define AVIERR_READONLY MAKE_AVIERR(114) #define AVIERR_NODATA MAKE_AVIERR(115) #define AVIERR_BUFFERTOOSMALL MAKE_AVIERR(116) #define AVIERR_CANTCOMPRESS MAKE_AVIERR(117) #define AVIERR_USERABORT MAKE_AVIERR(198) #define AVIERR_ERROR MAKE_AVIERR(199) #ifdef __cplusplus } #endif #endif /* __WINE_VFW_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/windows.h�����������������������������������������������������������0000644�0001750�0001750�00000001237�14647725152�016061� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_WINDOWS_H #define __WINE_WINDOWS_H #ifdef __cplusplus extern "C" { #endif #include "windef.h" #include "winbase.h" #include "winuser.h" #include "shell.h" #include "winreg.h" #include "winnetwk.h" #include "winver.h" #include "lzexpand.h" #include "shellapi.h" #include "ole2.h" #include "winnls.h" #include "objbase.h" #include "winspool.h" #if 0 Where does this belong? Nobody uses this stuff anyway. typedef struct { BYTE i; /* much more .... */ } KANJISTRUCT; typedef KANJISTRUCT *LPKANJISTRUCT; typedef KANJISTRUCT *NPKANJISTRUCT; typedef KANJISTRUCT *PKANJISTRUCT; #endif /* 0 */ #ifdef __cplusplus } #endif #endif /* __WINE_WINDOWS_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/pshpack8.h����������������������������������������������������������0000644�0001750�0001750�00000000514�14647725152�016105� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_PSHPACK_H #define __WINE_PSHPACK_H 8 #if 0 //#pragma pack(8) #elif !defined(RC_INVOKED) #error "8 as alignment is not supported" #endif /* 0 ; !defined(RC_INVOKED) */ #else /* !defined(__WINE_PSHPACK_H) */ #error "Nested pushing of alignment isn't supported by the compiler" #endif /* !defined(__WINE_PSHPACK_H) */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/afl.c���������������������������������������������������������������0000644�0001750�0001750�00000053241�14647725152�015126� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/************************************************************************** This file will contain an interface to ACM drivers. Its content will be based mainly on wine/dlls/msacm32 actually, for audio decompression only the following functions are needed: acmStreamOpen ( takes formats of src and dest, returns stream handle ) acmStreamPrepareHeader ( takes stream handler and info on data ) acmStreamConvert ( the same as PrepareHeader ) acmStreamUnprepareHeader acmStreamClose acmStreamSize maybe acmStreamReset In future I'll also add functions for format enumeration, but not right now. ***************************************************************************/ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "winbase.h" #include "windef.h" #include "winuser.h" #include "vfw.h" #include "winestring.h" #include "driver.h" #include "winerror.h" #include "msacm.h" #include "msacmdrv.h" #include "wineacm.h" #include "ext.h" #include "debugtools.h" #include "driver.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #pragma pack(1) #define OpenDriverA DrvOpen #define CloseDriver DrvClose #pragma pack(1) static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has) { return (PWINE_ACMSTREAM)has; } /*********************************************************************** * acmDriverAddA (MSACM32.2) */ MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd) { if (!phadid) return MMSYSERR_INVALPARAM; /* Check if any unknown flags */ if (fdwAdd & ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND| ACM_DRIVERADDF_GLOBAL)) return MMSYSERR_INVALFLAG; /* Check if any incompatible flags */ if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) return MMSYSERR_INVALFLAG; /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a * LoadDriver on it, to be sure we can call SendDriverMessage on the * hDrvr handle. */ *phadid = (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, hinstModule); /* FIXME: lParam, dwPriority and fdwAdd ignored */ (void)lParam; (void)dwPriority; return MMSYSERR_NOERROR; } /*********************************************************************** * acmDriverClose (MSACM32.4) */ MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose) { PWINE_ACMDRIVER p; PWINE_ACMDRIVER* tp; if (fdwClose) return MMSYSERR_INVALFLAG; p = MSACM_GetDriver(had); if (!p) return MMSYSERR_INVALHANDLE; for (tp = &(p->obj.pACMDriverID->pACMDriverList); *tp; *tp = (*tp)->pNextACMDriver) { if (*tp == p) { *tp = (*tp)->pNextACMDriver; break; } } if (p->hDrvr && !p->obj.pACMDriverID->pACMDriverList) CloseDriver(p->hDrvr); HeapFree(MSACM_hHeap, 0, p); return MMSYSERR_NOERROR; } /*********************************************************************** * acmDriverEnum (MSACM32.7) */ MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum) { PWINE_ACMDRIVERID p; DWORD fdwSupport; if (!fnCallback) { return MMSYSERR_INVALPARAM; } if (fdwEnum && ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) { return MMSYSERR_INVALFLAG; } for (p = MSACM_pFirstACMDriverID; p; p = p->pNextACMDriverID) { fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; if (!p->bEnabled) { if (fdwEnum & ACM_DRIVERENUMF_DISABLED) fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; else continue; } (*fnCallback)((HACMDRIVERID) p, dwInstance, fdwSupport); } return MMSYSERR_NOERROR; } /*********************************************************************** * acmDriverID (MSACM32.8) */ MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID) { PWINE_ACMOBJ pao; pao = MSACM_GetObj(hao); if (!pao) return MMSYSERR_INVALHANDLE; if (!phadid) return MMSYSERR_INVALPARAM; if (fdwDriverID) return MMSYSERR_INVALFLAG; *phadid = (HACMDRIVERID) pao->pACMDriverID; return MMSYSERR_NOERROR; } /*********************************************************************** * acmDriverMessage (MSACM32.9) * FIXME * Not implemented */ LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2) { PWINE_ACMDRIVER pad = MSACM_GetDriver(had); if (!pad) return MMSYSERR_INVALPARAM; /* FIXME: Check if uMsg legal */ if (!SendDriverMessage(pad->hDrvr, uMsg, lParam1, lParam2)) return MMSYSERR_NOTSUPPORTED; return MMSYSERR_NOERROR; } /*********************************************************************** * acmDriverOpen (MSACM32.10) */ MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen) { PWINE_ACMDRIVERID padid; PWINE_ACMDRIVER pad; ICOPEN icopen; /* HDRVR hdrv; -- not used */ TRACE("(%p, %x, %08lu)\n", phad, hadid, fdwOpen); if (!phad) return MMSYSERR_INVALPARAM; padid = MSACM_GetDriverID(hadid); if (!padid) return MMSYSERR_INVALHANDLE; if (fdwOpen) return MMSYSERR_INVALFLAG; pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER)); if (!pad) return MMSYSERR_NOMEM; pad->obj.pACMDriverID = padid; icopen.fccType = mmioFOURCC('a', 'u', 'd', 'c'); icopen.fccHandler = (long)padid->pszFileName; icopen.dwSize = sizeof(ICOPEN); icopen.dwFlags = 0; icopen.pV1Reserved = padid->pszFileName; if (!padid->hInstModule) pad->hDrvr = OpenDriverA((long)&icopen); else pad->hDrvr = padid->hInstModule; if (!pad->hDrvr) { HeapFree(MSACM_hHeap, 0, pad); return MMSYSERR_ERROR; } pad->pfnDriverProc = GetProcAddress(pad->hDrvr, "DriverProc"); /* insert new pad at beg of list */ pad->pNextACMDriver = padid->pACMDriverList; padid->pACMDriverList = pad; /* FIXME: Create a WINE_ACMDRIVER32 */ *phad = (HACMDRIVER)pad; return MMSYSERR_NOERROR; } /*********************************************************************** * acmDriverRemove (MSACM32.12) */ MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove) { PWINE_ACMDRIVERID padid; padid = MSACM_GetDriverID(hadid); if (!padid) return MMSYSERR_INVALHANDLE; if (fdwRemove) return MMSYSERR_INVALFLAG; MSACM_UnregisterDriver(padid); return MMSYSERR_NOERROR; } /**********************************************************************/ HANDLE MSACM_hHeap = (HANDLE) NULL; PWINE_ACMDRIVERID MSACM_pFirstACMDriverID = NULL; PWINE_ACMDRIVERID MSACM_pLastACMDriverID = NULL; /*********************************************************************** * MSACM_RegisterDriver32() */ PWINE_ACMDRIVERID MSACM_RegisterDriver(const char* pszFileName, WORD wFormatTag, HINSTANCE hinstModule) { PWINE_ACMDRIVERID padid; TRACE("('%s', '%x', 0x%08x)\n", pszFileName, wFormatTag, hinstModule); padid = (PWINE_ACMDRIVERID) HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVERID)); padid->pszFileName = (char*)malloc(strlen(pszFileName)+1); strcpy(padid->pszFileName, pszFileName); // 1~strdup(pszDriverAlias); padid->wFormatTag = wFormatTag; padid->hInstModule = hinstModule; padid->bEnabled = TRUE; padid->pACMDriverList = NULL; padid->pNextACMDriverID = NULL; padid->pPrevACMDriverID = MSACM_pLastACMDriverID; if (MSACM_pLastACMDriverID) MSACM_pLastACMDriverID->pNextACMDriverID = padid; MSACM_pLastACMDriverID = padid; if (!MSACM_pFirstACMDriverID) MSACM_pFirstACMDriverID = padid; return padid; } /*********************************************************************** * MSACM_UnregisterDriver32() */ PWINE_ACMDRIVERID MSACM_UnregisterDriver(PWINE_ACMDRIVERID p) { PWINE_ACMDRIVERID pNextACMDriverID; while (p->pACMDriverList) acmDriverClose((HACMDRIVER) p->pACMDriverList, 0); if (p->pszFileName) free(p->pszFileName); if (p == MSACM_pFirstACMDriverID) MSACM_pFirstACMDriverID = p->pNextACMDriverID; if (p == MSACM_pLastACMDriverID) MSACM_pLastACMDriverID = p->pPrevACMDriverID; if (p->pPrevACMDriverID) p->pPrevACMDriverID->pNextACMDriverID = p->pNextACMDriverID; if (p->pNextACMDriverID) p->pNextACMDriverID->pPrevACMDriverID = p->pPrevACMDriverID; pNextACMDriverID = p->pNextACMDriverID; HeapFree(MSACM_hHeap, 0, p); return pNextACMDriverID; } /*********************************************************************** * MSACM_UnregisterAllDrivers32() * FIXME * Where should this function be called? */ void MSACM_UnregisterAllDrivers(void) { PWINE_ACMDRIVERID p; for (p = MSACM_pFirstACMDriverID; p; p = MSACM_UnregisterDriver(p)); } /*********************************************************************** * MSACM_GetDriverID32() */ PWINE_ACMDRIVERID MSACM_GetDriverID(HACMDRIVERID hDriverID) { return (PWINE_ACMDRIVERID)hDriverID; } /*********************************************************************** * MSACM_GetDriver32() */ PWINE_ACMDRIVER MSACM_GetDriver(HACMDRIVER hDriver) { return (PWINE_ACMDRIVER)hDriver; } /*********************************************************************** * MSACM_GetObj32() */ PWINE_ACMOBJ MSACM_GetObj(HACMOBJ hObj) { return (PWINE_ACMOBJ)hObj; } /*********************************************************************** * acmStreamOpen (MSACM32.40) */ MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pwfxSrc, PWAVEFORMATEX pwfxDst, PWAVEFILTER pwfltr, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen) { PWINE_ACMSTREAM was; PWINE_ACMDRIVER wad; MMRESULT ret; int wfxSrcSize; int wfxDstSize; TRACE("(%p, 0x%08x, %p, %p, %p, %ld, %ld, %ld)\n", phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen); TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec, pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize); TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n", pwfxDst->wFormatTag, pwfxDst->nChannels, pwfxDst->nSamplesPerSec, pwfxDst->nAvgBytesPerSec, pwfxDst->nBlockAlign, pwfxDst->wBitsPerSample, pwfxDst->cbSize); #define SIZEOF_WFX(wfx) (sizeof(WAVEFORMATEX) + ((wfx->wFormatTag == WAVE_FORMAT_PCM) ? 0 : wfx->cbSize)) wfxSrcSize = SIZEOF_WFX(pwfxSrc); wfxDstSize = SIZEOF_WFX(pwfxDst); #undef SIZEOF_WFX was = (PWINE_ACMSTREAM) HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize + ((pwfltr) ? sizeof(WAVEFILTER) : 0)); if (was == NULL) return MMSYSERR_NOMEM; was->drvInst.cbStruct = sizeof(was->drvInst); was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was)); memcpy(was->drvInst.pwfxSrc, pwfxSrc, wfxSrcSize); // LHACM is checking for 0x1 // but if this will not help // was->drvInst.pwfxSrc->wFormatTag = 1; was->drvInst.pwfxDst = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was) + wfxSrcSize); memcpy(was->drvInst.pwfxDst, pwfxDst, wfxDstSize); if (pwfltr) { was->drvInst.pwfltr = (PWAVEFILTER)((LPSTR)was + sizeof(*was) + wfxSrcSize + wfxDstSize); memcpy(was->drvInst.pwfltr, pwfltr, sizeof(WAVEFILTER)); } else { was->drvInst.pwfltr = NULL; } was->drvInst.dwCallback = dwCallback; was->drvInst.dwInstance = dwInstance; was->drvInst.fdwOpen = fdwOpen; was->drvInst.fdwDriver = 0L; was->drvInst.dwDriver = 0L; was->drvInst.has = (HACMSTREAM)was; if (had) { if (!(wad = MSACM_GetDriver(had))) { ret = MMSYSERR_INVALPARAM; goto errCleanUp; } was->obj.pACMDriverID = wad->obj.pACMDriverID; was->pDrv = wad; was->hAcmDriver = 0; /* not to close it in acmStreamClose */ ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); if (ret != MMSYSERR_NOERROR) goto errCleanUp; } else { PWINE_ACMDRIVERID wadi; /* short drv_tag; -- not used */ ret = ACMERR_NOTPOSSIBLE; /* if(pwfxSrc->wFormatTag==1)//compression drv_tag=pwfxDst->wFormatTag; else if(pwfxDst->wFormatTag==1)//decompression drv_tag=pwfxSrc->wFormatTag; else goto errCleanUp; ret=acmDriverOpen2(drv_tag); if (ret == MMSYSERR_NOERROR) { if ((wad = MSACM_GetDriver(had)) != 0) { was->obj.pACMDriverID = wad->obj.pACMDriverID; was->pDrv = wad; was->hAcmDriver = had; ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); if (ret == MMSYSERR_NOERROR) { if (fdwOpen & ACM_STREAMOPENF_QUERY) { acmDriverClose(had, 0L); } break; } } acmDriverClose(had, 0L);*/ //if(MSACM_pFirstACMDriverID==NULL) // MSACM_RegisterAllDrivers(); for (wadi = MSACM_pFirstACMDriverID; wadi; wadi = wadi->pNextACMDriverID) { /* Check Format */ if ((int)wadi->wFormatTag != (int)pwfxSrc->wFormatTag) continue; ret = acmDriverOpen(&had, (HACMDRIVERID)wadi, 0L); if (ret == MMSYSERR_NOERROR) { if ((wad = MSACM_GetDriver(had)) != 0) { was->obj.pACMDriverID = wad->obj.pACMDriverID; was->pDrv = wad; was->hAcmDriver = had; ret = SendDriverMessage(wad->hDrvr, ACMDM_STREAM_OPEN, (DWORD)&was->drvInst, 0L); //lhacm - crash printf("RETOPEN %d\n", ret); //ret = 0; if (ret == MMSYSERR_NOERROR) { if (fdwOpen & ACM_STREAMOPENF_QUERY) { acmDriverClose(had, 0L); } break; } } // no match, close this acm driver and try next one acmDriverClose(had, 0L); } } if (ret != MMSYSERR_NOERROR) { ret = ACMERR_NOTPOSSIBLE; goto errCleanUp; } } ret = MMSYSERR_NOERROR; if (!(fdwOpen & ACM_STREAMOPENF_QUERY)) { if (phas) *phas = (HACMSTREAM)was; TRACE("=> (%d)\n", ret); CodecAlloc(); return ret; } errCleanUp: if (phas) *phas = (HACMSTREAM)0; HeapFree(MSACM_hHeap, 0, was); TRACE("=> (%d)\n", ret); return ret; } MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose) { PWINE_ACMSTREAM was; MMRESULT ret; TRACE("(0x%08x, %ld)\n", has, fdwClose); if ((was = ACM_GetStream(has)) == NULL) { return MMSYSERR_INVALHANDLE; } ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0); if (ret == MMSYSERR_NOERROR) { if (was->hAcmDriver) acmDriverClose(was->hAcmDriver, 0L); HeapFree(MSACM_hHeap, 0, was); CodecRelease(); } TRACE("=> (%d)\n", ret); return ret; } /*********************************************************************** * acmStreamConvert (MSACM32.38) */ MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwConvert) { PWINE_ACMSTREAM was; MMRESULT ret = MMSYSERR_NOERROR; PACMDRVSTREAMHEADER padsh; TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwConvert); if ((was = ACM_GetStream(has)) == NULL) return MMSYSERR_INVALHANDLE; if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) return MMSYSERR_INVALPARAM; if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) return ACMERR_UNPREPARED; /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same * size. some fields are private to msacm internals, and are exposed * in ACMSTREAMHEADER in the dwReservedDriver array */ padsh = (PACMDRVSTREAMHEADER)pash; /* check that pointers have not been modified */ if (padsh->pbPreparedSrc != padsh->pbSrc || padsh->cbPreparedSrcLength < padsh->cbSrcLength || padsh->pbPreparedDst != padsh->pbDst || padsh->cbPreparedDstLength < padsh->cbDstLength) { return MMSYSERR_INVALPARAM; } padsh->fdwConvert = fdwConvert; ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CONVERT, (DWORD)&was->drvInst, (DWORD)padsh); if (ret == MMSYSERR_NOERROR) { padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE; } TRACE("=> (%d)\n", ret); return ret; } /*********************************************************************** * acmStreamPrepareHeader (MSACM32.41) */ MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwPrepare) { PWINE_ACMSTREAM was; MMRESULT ret = MMSYSERR_NOERROR; PACMDRVSTREAMHEADER padsh; TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwPrepare); if ((was = ACM_GetStream(has)) == NULL) return MMSYSERR_INVALHANDLE; if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) return MMSYSERR_INVALPARAM; if (fdwPrepare) ret = MMSYSERR_INVALFLAG; if (pash->fdwStatus & ACMSTREAMHEADER_STATUSF_DONE) return MMSYSERR_NOERROR; /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same * size. some fields are private to msacm internals, and are exposed * in ACMSTREAMHEADER in the dwReservedDriver array */ padsh = (PACMDRVSTREAMHEADER)pash; padsh->fdwConvert = fdwPrepare; padsh->padshNext = NULL; padsh->fdwDriver = padsh->dwDriver = 0L; padsh->fdwPrepared = 0; padsh->dwPrepared = 0; padsh->pbPreparedSrc = 0; padsh->cbPreparedSrcLength = 0; padsh->pbPreparedDst = 0; padsh->cbPreparedDstLength = 0; ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_PREPARE, (DWORD)&was->drvInst, (DWORD)padsh); if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { ret = MMSYSERR_NOERROR; padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE); padsh->fdwStatus |= ACMSTREAMHEADER_STATUSF_PREPARED; padsh->fdwPrepared = padsh->fdwStatus; padsh->dwPrepared = 0; padsh->pbPreparedSrc = padsh->pbSrc; padsh->cbPreparedSrcLength = padsh->cbSrcLength; padsh->pbPreparedDst = padsh->pbDst; padsh->cbPreparedDstLength = padsh->cbDstLength; } else { padsh->fdwPrepared = 0; padsh->dwPrepared = 0; padsh->pbPreparedSrc = 0; padsh->cbPreparedSrcLength = 0; padsh->pbPreparedDst = 0; padsh->cbPreparedDstLength = 0; } TRACE("=> (%d)\n", ret); return ret; } /*********************************************************************** * acmStreamReset (MSACM32.42) */ MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset) { PWINE_ACMSTREAM was; MMRESULT ret = MMSYSERR_NOERROR; TRACE("(0x%08x, %ld)\n", has, fdwReset); if (fdwReset) { ret = MMSYSERR_INVALFLAG; } else if ((was = ACM_GetStream(has)) == NULL) { return MMSYSERR_INVALHANDLE; } else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) { ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0); } TRACE("=> (%d)\n", ret); return ret; } /*********************************************************************** * acmStreamSize (MSACM32.43) */ MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize) { PWINE_ACMSTREAM was; ACMDRVSTREAMSIZE adss; MMRESULT ret; TRACE("(0x%08x, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize); if ((was = ACM_GetStream(has)) == NULL) { return MMSYSERR_INVALHANDLE; } if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) { return MMSYSERR_INVALFLAG; } *pdwOutputBytes = 0L; switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { case ACM_STREAMSIZEF_DESTINATION: adss.cbDstLength = cbInput; adss.cbSrcLength = 0; break; case ACM_STREAMSIZEF_SOURCE: adss.cbSrcLength = cbInput; adss.cbDstLength = 0; break; default: return MMSYSERR_INVALFLAG; } adss.cbStruct = sizeof(adss); adss.fdwSize = fdwSize; ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_SIZE, (DWORD)&was->drvInst, (DWORD)&adss); if (ret == MMSYSERR_NOERROR) { switch (fdwSize & ACM_STREAMSIZEF_QUERYMASK) { case ACM_STREAMSIZEF_DESTINATION: *pdwOutputBytes = adss.cbSrcLength; break; case ACM_STREAMSIZEF_SOURCE: *pdwOutputBytes = adss.cbDstLength; break; } } TRACE("=> (%d) [%lu]\n", ret, *pdwOutputBytes); return ret; } /*********************************************************************** * acmStreamUnprepareHeader (MSACM32.44) */ MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash, DWORD fdwUnprepare) { PWINE_ACMSTREAM was; MMRESULT ret = MMSYSERR_NOERROR; PACMDRVSTREAMHEADER padsh; TRACE("(0x%08x, %p, %ld)\n", has, pash, fdwUnprepare); if ((was = ACM_GetStream(has)) == NULL) return MMSYSERR_INVALHANDLE; if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) return MMSYSERR_INVALPARAM; if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) return ACMERR_UNPREPARED; /* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same * size. some fields are private to msacm internals, and are exposed * in ACMSTREAMHEADER in the dwReservedDriver array */ padsh = (PACMDRVSTREAMHEADER)pash; /* check that pointers have not been modified */ if (padsh->pbPreparedSrc != padsh->pbSrc || padsh->cbPreparedSrcLength < padsh->cbSrcLength || padsh->pbPreparedDst != padsh->pbDst || padsh->cbPreparedDstLength < padsh->cbDstLength) { return MMSYSERR_INVALPARAM; } padsh->fdwConvert = fdwUnprepare; ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_UNPREPARE, (DWORD)&was->drvInst, (DWORD)padsh); if (ret == MMSYSERR_NOERROR || ret == MMSYSERR_NOTSUPPORTED) { ret = MMSYSERR_NOERROR; padsh->fdwStatus &= ~(ACMSTREAMHEADER_STATUSF_DONE|ACMSTREAMHEADER_STATUSF_INQUEUE|ACMSTREAMHEADER_STATUSF_PREPARED); } TRACE("=> (%d)\n", ret); return ret; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/ntdef.h�������������������������������������������������������������0000644�0001750�0001750�00000003700�14647725152�015464� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_NTDEF_H #define __WINE_NTDEF_H #include "basetsd.h" #include "windef.h" #include "pshpack1.h" #ifdef __cplusplus extern "C" { #endif #define NTAPI __stdcall #ifndef IN #define IN #endif #ifndef OUT #define OUT #endif #ifndef OPTIONAL #define OPTIONAL #endif #ifndef VOID #define VOID void #endif typedef LONG NTSTATUS; typedef NTSTATUS *PNTSTATUS; typedef short CSHORT; typedef CSHORT *PCSHORT; typedef WCHAR * PWCHAR; /* NT lowlevel Strings (handled by Rtl* functions in NTDLL) * If they are zero terminated, Length does not include the terminating 0. */ typedef struct _STRING { USHORT Length; USHORT MaximumLength; PSTR Buffer; } STRING,*PSTRING,ANSI_STRING,*PANSI_STRING; typedef struct _CSTRING { USHORT Length; USHORT MaximumLength; PCSTR Buffer; } CSTRING,*PCSTRING; typedef struct _UNICODE_STRING { USHORT Length; /* bytes */ USHORT MaximumLength; /* bytes */ PWSTR Buffer; } UNICODE_STRING,*PUNICODE_STRING; /* Objects */ #define OBJ_INHERIT 0x00000002L #define OBJ_PERMANENT 0x00000010L #define OBJ_EXCLUSIVE 0x00000020L #define OBJ_CASE_INSENSITIVE 0x00000040L #define OBJ_OPENIF 0x00000080L #define OBJ_OPENLINK 0x00000100L #define OBJ_KERNEL_HANDLE 0x00000200L #define OBJ_VALID_ATTRIBUTES 0x000003F2L typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; /* type SECURITY_DESCRIPTOR */ PVOID SecurityQualityOfService; /* type SECURITY_QUALITY_OF_SERVICE */ } OBJECT_ATTRIBUTES; typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; #define InitializeObjectAttributes(p,n,a,r,s) \ { (p)->Length = sizeof(OBJECT_ATTRIBUTES); \ (p)->RootDirectory = r; \ (p)->Attributes = a; \ (p)->ObjectName = n; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ } #ifdef __cplusplus } #endif #include "poppack.h" #endif ����������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/elfdll.h������������������������������������������������������������0000644�0001750�0001750�00000000532�14647725152�015626� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef __WINE_ELFDLL_H #define __WINE_ELFDLL_H #include "module.h" #include "windef.h" WINE_MODREF *ELFDLL_LoadLibraryExA(LPCSTR libname, DWORD flags); HINSTANCE16 ELFDLL_LoadModule16(LPCSTR libname); void ELFDLL_UnloadLibrary(WINE_MODREF *wm); void *ELFDLL_dlopen(const char *libname, int flags); extern char *extra_ld_library_path; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/ldt_keeper.h��������������������������������������������������������0000644�0001750�0001750�00000000616�14647725152�016505� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef LDT_KEEPER_H #define LDT_KEEPER_H #ifdef __cplusplus extern "C" { #endif typedef struct { void* fs_seg; char* prev_struct; int fd; unsigned int teb_sel; } ldt_fs_t; void Setup_FS_Segment(ldt_fs_t *ldt_fs); ldt_fs_t* Setup_LDT_Keeper(void); void Check_FS_Segment(ldt_fs_t *ldt_fs); void Restore_LDT_Keeper(ldt_fs_t* ldt_fs); #ifdef __cplusplus } #endif #endif /* LDT_KEEPER_H */ ������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/com.h���������������������������������������������������������������0000644�0001750�0001750�00000003250�14647725152�015142� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef AVIFILE_COM_H #define AVIFILE_COM_H #include <inttypes.h> /** * Internal functions and structures for COM emulation code. */ #ifndef WIN32 #ifdef __cplusplus extern "C" { #endif void* CoTaskMemAlloc(unsigned long cb); void CoTaskMemFree(void* cb); #ifndef GUID_TYPE #define GUID_TYPE typedef struct { uint32_t f1; uint16_t f2; uint16_t f3; uint8_t f4[8]; } GUID; #endif extern const GUID IID_IUnknown; extern const GUID IID_IClassFactory; typedef long (*GETCLASSOBJECT) (GUID* clsid, const GUID* iid, void** ppv); int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs); int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs); #ifndef STDCALL #define STDCALL __attribute__((__stdcall__)) #endif struct IUnknown; struct IClassFactory; struct IUnknown_vt { long STDCALL (*QueryInterface)(struct IUnknown* _this, const GUID* iid, void** ppv); long STDCALL (*AddRef)(struct IUnknown* _this) ; long STDCALL (*Release)(struct IUnknown* _this) ; } ; typedef struct IUnknown { struct IUnknown_vt* vt; } IUnknown; struct IClassFactory_vt { long STDCALL (*QueryInterface)(struct IUnknown* _this, const GUID* iid, void** ppv); long STDCALL (*AddRef)(struct IUnknown* _this) ; long STDCALL (*Release)(struct IUnknown* _this) ; long STDCALL (*CreateInstance)(struct IClassFactory* _this, struct IUnknown* pUnkOuter, const GUID* riid, void** ppvObject); }; struct IClassFactory { struct IClassFactory_vt* vt; }; long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, long dwClsContext, const GUID* riid, void** ppv); #ifdef __cplusplus }; #endif /* __cplusplus */ #endif /* WIN32 */ #endif /* AVIFILE_COM_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/stubs.s�������������������������������������������������������������0000644�0001750�0001750�00000001100�14647725152�015527� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� .data .LC0: .string "Called unk_%s\n" .align 4 .globl unk_exp1 unk_exp1: pushl %ebp movl %esp,%ebp subl $4,%esp movl $1,-4(%ebp) movl -4(%ebp),%eax movl %eax,%ecx movl %ecx,%edx sall $4,%edx subl %eax,%edx leal 0(,%edx,2),%eax movl %eax,%edx addl $export_names,%edx pushl %edx pushl $.LC0 call printf addl $8,%esp xorl %eax,%eax leave ret .globl exp_EH_prolog exp_EH_prolog: pushl $0xff pushl %eax pushl %fs:0 movl %esp, %fs:0 movl 12(%esp), %eax movl %ebp, 12(%esp) leal 12(%esp), %ebp pushl %eax ret .section .note.GNU-stack,"",@progbits ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/ldt_keeper.c��������������������������������������������������������0000644�0001750�0001750�00000025462�14647725152�016506� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * * contents: * * Allocate an LDT entry for the TEB (thread environment block) * TEB is a the only thread specific structure provided to userspace * by MS Windows. * Any W32 dll may access the TEB through FS:0, so we must provide it. * * Additional notes: * aviplay used to use the same LDT/TEB/FS to all his threads and did it * by calling these functions before any threads have been created. this * is a ugly hack, as the main code includes a plugin function at its * initialization. * Also, IMHO, that was slightly wrong. The TEB is supposed to be unique * per W32 thread. The current xine implementation will allocate different * TEBs for the audio and video codecs. */ #ifdef __cplusplus # define EXTERN_C_START extern "C" { # define EXTERN_C_STOP } #else # define EXTERN_C_START # define EXTERN_C_STOP #endif /** * OLD AVIFILE COMMENT: * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * This file MUST be in main library because LDT must * be modified before program creates first thread * - avifile includes this file from C++ code * and initializes it at the start of player! * it might sound like a hack and it really is - but * as aviplay is deconding video with more than just one * thread currently it's necessary to do it this way * this might change in the future */ /* applied some modification to make make our xine friend more happy */ #include "ldt_keeper.h" #include "config.h" #include <string.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <sys/mman.h> #include <sys/types.h> #include <stdio.h> #include <unistd.h> #ifdef __linux__ #include <asm/unistd.h> #include <asm/ldt.h> /* 2.5.xx+ calls this user_desc: */ #include <linux/version.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,47) #define modify_ldt_ldt_s user_desc #endif /* prototype it here, so we won't depend on kernel headers */ EXTERN_C_START int modify_ldt(int func, void *ptr, unsigned long bytecount); EXTERN_C_STOP #else #if defined(__NetBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) #include <machine/segments.h> #include <machine/sysarch.h> #endif #ifdef __svr4__ #include <sys/segment.h> #include <sys/sysi86.h> /* solaris x86: add missing prototype for sysi86() */ #ifndef HAVE_SYSI86 EXTERN_C_START int sysi86(int, void*); EXTERN_C_STOP #endif #ifndef NUMSYSLDTS /* SunOS 2.5.1 does not define NUMSYSLDTS */ #define NUMSYSLDTS 6 /* Let's hope the SunOS 5.8 value is OK */ #endif #define TEB_SEL_IDX NUMSYSLDTS #endif #define LDT_ENTRIES 8192 #define LDT_ENTRY_SIZE 8 #pragma pack(4) struct modify_ldt_ldt_s { unsigned int entry_number; unsigned long base_addr; unsigned int limit; unsigned int seg_32bit:1; unsigned int contents:2; unsigned int read_exec_only:1; unsigned int limit_in_pages:1; unsigned int seg_not_present:1; unsigned int useable:1; }; #define MODIFY_LDT_CONTENTS_DATA 0 #define MODIFY_LDT_CONTENTS_STACK 1 #define MODIFY_LDT_CONTENTS_CODE 2 #endif /* user level (privilege level: 3) ldt (1<<2) segment selector */ #define LDT_SEL(idx) ((idx) << 3 | 1 << 2 | 3) /* * linuxthreads can use all LDT entries from 0 to PTHREAD_THREADS_MAX-1. * by default PTHREAD_THREADS_MAX = 1024, so unless one has recompiled * it's own glibc/linuxthreads this should be a safe value. */ #ifndef TEB_SEL_IDX #define TEB_SEL_IDX 1024 #endif static ldt_fs_t global_ldt_fs; static int global_usage_count = 0; EXTERN_C_START void Setup_FS_Segment(ldt_fs_t *ldt_fs) { __asm__ __volatile__( "movl %0,%%eax; movw %%ax, %%fs" : : "r" (ldt_fs->teb_sel) : "%eax" ); } void Check_FS_Segment(ldt_fs_t *ldt_fs) { #if defined(__FreeBSD_kernel__) && defined(LDT_AUTO_ALLOC) int fs; __asm__ __volatile__( "movw %%fs,%%ax; mov %%eax,%0" : "=r" (fs) :: "%eax" ); fs = fs & 0xffff; if( fs != ldt_fs->teb_sel ) { printf("ldt_keeper: FS segment is not set or has being lost!\n"); printf(" Please report this error to xine-devel@lists.sourceforge.net\n"); printf(" Aborting....\n"); abort(); } #else Setup_FS_Segment(ldt_fs); #endif } #if defined(__NetBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) { *buffer++ = ((content->base_addr & 0x0000ffff) << 16) | (content->limit & 0x0ffff); *buffer = (content->base_addr & 0xff000000) | ((content->base_addr & 0x00ff0000)>>16) | (content->limit & 0xf0000) | (content->contents << 10) | ((content->read_exec_only == 0) << 9) | ((content->seg_32bit != 0) << 22) | ((content->limit_in_pages != 0) << 23) | 0xf000; } #endif static int _modify_ldt(ldt_fs_t *ldt_fs, struct modify_ldt_ldt_s array) { int ret; ldt_fs->teb_sel = LDT_SEL(TEB_SEL_IDX); #ifdef __linux__ ret=modify_ldt(0x1, &array, sizeof(struct modify_ldt_ldt_s)); if(ret<0) { perror("install_fs"); printf("Couldn't install fs segment, expect segfault\n"); } #endif /*linux*/ #if defined(__NetBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) { unsigned long d[2]; LDT_EntryToBytes( d, &array ); #if defined(__FreeBSD_kernel__) && defined(LDT_AUTO_ALLOC) ret = i386_set_ldt(LDT_AUTO_ALLOC, (union descriptor *)d, 1); array.entry_number = ret; ldt_fs->teb_sel = LDT_SEL(ret); #else ret = i386_set_ldt(array.entry_number, (union descriptor *)d, 1); #endif if (ret < 0) { perror("install_fs"); printf("Couldn't install fs segment, expect segfault\n"); printf("Did you reconfigure the kernel with \"options USER_LDT\"?\n"); } printf("Set_LDT\n"); } #endif /* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */ #if defined(__svr4__) { struct ssd ssd; ssd.sel = ldt_fs->teb_sel; ssd.bo = array.base_addr; ssd.ls = array.limit; ssd.acc1 = ((array.read_exec_only == 0) << 1) | (array.contents << 2) | 0xf0; /* P(resent) | DPL3 | S */ ssd.acc2 = 0x4; /* byte limit, 32-bit segment */ if (sysi86(SI86DSCR, &ssd) < 0) { perror("sysi86(SI86DSCR)"); printf("Couldn't install fs segment, expect segfault\n"); } } #endif return ret; } ldt_fs_t* Setup_LDT_Keeper(void) { struct modify_ldt_ldt_s array; int ret; int ldt_already_set = 0; ldt_fs_t* ldt_fs = (ldt_fs_t*) malloc(sizeof(ldt_fs_t)); if (!ldt_fs) return NULL; #ifdef __linux__ /* * LDT might be shared by different threads, so we must * check it here to avoid filling the segment descriptor again. */ { unsigned char *ldt = malloc((TEB_SEL_IDX+1)*8); unsigned int limit; memset (ldt, 0, (TEB_SEL_IDX+1)*8); modify_ldt(0, ldt, (TEB_SEL_IDX+1)*8); /* printf("ldt_keeper: old LDT entry = [%x] [%x]\n", *(unsigned int *) (&ldt[TEB_SEL_IDX*8]), *(unsigned int *) (&ldt[TEB_SEL_IDX*8+4]) ); */ limit = ((*(unsigned int *) (&ldt[TEB_SEL_IDX*8])) & 0xffff) | ((*(unsigned int *) (&ldt[TEB_SEL_IDX*8+4])) & 0xf0000); if( limit ) { if (limit == (unsigned int)(getpagesize () - 1)) { ldt_already_set = 1; } else { #ifdef LOG printf("ldt_keeper: LDT entry seems to be used by someone else. [%x] [%x]\n", *(unsigned int *) (&ldt[TEB_SEL_IDX*8]), *(unsigned int *) (&ldt[TEB_SEL_IDX*8+4]) ); printf(" Please report this message to xine-devel@lists.sourceforge.net\n"); #endif } } free(ldt); } #endif /*linux*/ if( !ldt_already_set ) { #ifdef LOG printf("ldt_keeper: creating a new segment descriptor.\n"); #endif ldt_fs->fd = open("/dev/zero", O_RDWR); if(ldt_fs->fd<0){ perror( "Cannot open /dev/zero for READ+WRITE. Check permissions! error: "); free(ldt_fs); return NULL; } ldt_fs->fs_seg = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_PRIVATE, ldt_fs->fd, 0); if (ldt_fs->fs_seg == (void*)-1) { perror("ERROR: Couldn't allocate memory for fs segment"); close(ldt_fs->fd); free(ldt_fs); return NULL; } *(void**)((char*)ldt_fs->fs_seg+0x18) = ldt_fs->fs_seg; memset (&array, 0, sizeof (array)); array.base_addr=(int)ldt_fs->fs_seg; array.entry_number=TEB_SEL_IDX; array.limit=getpagesize()-1; array.seg_32bit=1; array.read_exec_only=0; array.seg_not_present=0; array.contents=MODIFY_LDT_CONTENTS_DATA; array.limit_in_pages=0; ret = _modify_ldt(ldt_fs, array); ldt_fs->prev_struct = (char*)malloc(sizeof(char) * 8); *(void**)array.base_addr = ldt_fs->prev_struct; memcpy( &global_ldt_fs, ldt_fs, sizeof(ldt_fs_t) ); } else { #ifdef LOG printf("ldt_keeper: LDT entry already set, reusing.\n"); #endif global_usage_count++; memcpy( ldt_fs, &global_ldt_fs, sizeof(ldt_fs_t) ); } Setup_FS_Segment(ldt_fs); return ldt_fs; } void Restore_LDT_Keeper(ldt_fs_t* ldt_fs) { struct modify_ldt_ldt_s array; if (ldt_fs == NULL || ldt_fs->fs_seg == 0) return; if( global_usage_count ) { #ifdef LOG printf("ldt_keeper: shared LDT, restore does nothing.\n"); #endif /* shared LDT. only the last user can free. */ global_usage_count--; } else { #ifdef LOG printf("ldt_keeper: freeing LDT entry.\n"); #endif if (ldt_fs->prev_struct) free(ldt_fs->prev_struct); munmap((char*)ldt_fs->fs_seg, getpagesize()); ldt_fs->fs_seg = 0; close(ldt_fs->fd); /* mark LDT entry as free again */ memset(&array, 0, sizeof(struct modify_ldt_ldt_s)); array.entry_number=TEB_SEL_IDX; _modify_ldt(ldt_fs, array); } free(ldt_fs); } EXTERN_C_STOP ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/wine/vfl.c���������������������������������������������������������������0000644�0001750�0001750�00000013033�14647725152�015146� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright 1998 Marcus Meissner */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "win32.h" #include "loader.h" #include "winbase.h" #include "windef.h" #include "winuser.h" #include "vfw.h" #include "winestring.h" #include "driver.h" #include "avifmt.h" #include "driver.h" #define FIXME_(X) printf #define FIXME printf #define OpenDriverA DrvOpen #define CloseDriver DrvClose /*********************************************************************** * VideoForWindowsVersion [MSVFW.2][MSVIDEO.2] * Returns the version in major.minor form. * In Windows95 this returns 0x040003b6 (4.950) */ long VFWAPI VideoForWindowsVersion(void) { return 0x040003B6; /* 4.950 */ } /* system.ini: [drivers] */ /*********************************************************************** * ICInfo [MSVFW.33] * Get information about an installable compressor. Return TRUE if there * is one. */ int VFWAPI ICInfo( long fccType, /* [in] type of compressor ('vidc') */ long fccHandler, /* [in] <n>th compressor */ ICINFO *lpicinfo /* [out] information about compressor */ ) { (void)fccHandler; /* does OpenDriver/CloseDriver */ lpicinfo->dwSize = sizeof(ICINFO); lpicinfo->fccType = fccType; lpicinfo->dwFlags = 0; return TRUE; } /*********************************************************************** * ICOpen [MSVFW.37] * Opens an installable compressor. Return special handle. */ HIC VFWAPI //ICOpen(long fccType,long fccHandler,unsigned int wMode) { ICOpen(long filename,long fccHandler,unsigned int wMode) { ICOPEN icopen; HDRVR hdrv; WINE_HIC *whic; /* Well, lParam2 is in fact a LPVIDEO_OPEN_PARMS, but it has the * same layout as ICOPEN */ icopen.fccType = 0x63646976; // "vidc" //fccType; icopen.fccHandler = fccHandler; icopen.dwSize = sizeof(ICOPEN); icopen.dwFlags = wMode; icopen.pV1Reserved = (void*)filename; /* FIXME: do we need to fill out the rest too? */ hdrv=OpenDriverA((long)&icopen); if (!hdrv) return 0; whic = (WINE_HIC*)malloc(sizeof(WINE_HIC)); whic->hdrv = hdrv; whic->driverproc= ((DRVR*)hdrv)->DriverProc; // whic->private = ICSendMessage((HIC)whic,DRV_OPEN,0,(long)&icopen); whic->driverid = ((DRVR*)hdrv)->dwDriverID; return (HIC)whic; } /*********************************************************************** * ICGetInfo [MSVFW.30] */ LRESULT VFWAPI ICGetInfo(HIC hic,ICINFO *picinfo,long cb) { LRESULT ret; ret = ICSendMessage(hic,ICM_GETINFO,(long)picinfo,cb); return ret; } /*********************************************************************** * ICCompress [MSVFW.23] */ long VFWAPIV ICCompress( HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiOutput,void* lpData, LPBITMAPINFOHEADER lpbiInput,void* lpBits,long* lpckid, long* lpdwFlags,long lFrameNum,long dwFrameSize,long dwQuality, LPBITMAPINFOHEADER lpbiPrev,void* lpPrev ) { ICCOMPRESS iccmp; iccmp.dwFlags = dwFlags; iccmp.lpbiOutput = lpbiOutput; iccmp.lpOutput = lpData; iccmp.lpbiInput = lpbiInput; iccmp.lpInput = lpBits; iccmp.lpckid = lpckid; iccmp.lpdwFlags = lpdwFlags; iccmp.lFrameNum = lFrameNum; iccmp.dwFrameSize = dwFrameSize; iccmp.dwQuality = dwQuality; iccmp.lpbiPrev = lpbiPrev; iccmp.lpPrev = lpPrev; return ICSendMessage(hic,ICM_COMPRESS,(long)&iccmp,sizeof(iccmp)); } /*********************************************************************** * ICDecompress [MSVFW.26] */ long VFWAPIV ICDecompress(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits) { ICDECOMPRESS icd; int result; icd.dwFlags = dwFlags; icd.lpbiInput = lpbiFormat; icd.lpInput = lpData; icd.lpbiOutput = lpbi; icd.lpOutput = lpBits; icd.ckid = 0; result=ICSendMessage(hic,ICM_DECOMPRESS,(long)&icd,sizeof(icd)); return result; } /*********************************************************************** * ICDecompressEx [MSVFW.26] */ long VFWAPIV ICDecompressEx(HIC hic,long dwFlags,LPBITMAPINFOHEADER lpbiFormat,void* lpData,LPBITMAPINFOHEADER lpbi,void* lpBits) { ICDECOMPRESSEX icd; int result; icd.dwFlags = dwFlags; icd.lpbiSrc = lpbiFormat; icd.lpSrc = lpData; icd.lpbiDst = lpbi; icd.lpDst = lpBits; icd.xSrc=icd.ySrc=0; icd.dxSrc=lpbiFormat->biWidth; icd.dySrc=abs(lpbiFormat->biHeight); icd.xDst=icd.yDst=0; icd.dxDst=lpbi->biWidth; icd.dyDst=abs(lpbi->biHeight); //icd.ckid = 0; result=ICSendMessage(hic,ICM_DECOMPRESSEX,(long)&icd,sizeof(icd)); return result; } long VFWAPIV ICUniversalEx(HIC hic,int command,LPBITMAPINFOHEADER lpbiFormat,LPBITMAPINFOHEADER lpbi) { ICDECOMPRESSEX icd; int result; icd.dwFlags = 0; icd.lpbiSrc = lpbiFormat; icd.lpSrc = 0; icd.lpbiDst = lpbi; icd.lpDst = 0; icd.xSrc=icd.ySrc=0; icd.dxSrc=lpbiFormat->biWidth; icd.dySrc=abs(lpbiFormat->biHeight); icd.xDst=icd.yDst=0; icd.dxDst=lpbi->biWidth; icd.dyDst=abs(lpbi->biHeight); //icd.ckid = 0; result=ICSendMessage(hic,command,(long)&icd,sizeof(icd)); return result; } /*********************************************************************** * ICSendMessage [MSVFW.40] */ LRESULT VFWAPI ICSendMessage(HIC hic,unsigned int msg,long lParam1,long lParam2) { WINE_HIC *whic = (WINE_HIC*)hic; return SendDriverMessage(whic->hdrv, msg, lParam1,lParam2); } /*********************************************************************** * ICClose [MSVFW.22] */ LRESULT VFWAPI ICClose(HIC hic) { WINE_HIC *whic = (WINE_HIC*)hic; /* FIXME: correct? */ // CloseDriver(whic->hdrv,0,0); DrvClose(whic->hdrv); //#warning FIXME: DrvClose free(whic); return 0; } int VFWAPI ICDoSomething() { return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/��������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�015324� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/DS_VideoDecoder.h���������������������������������������������0000644�0001750�0001750�00000002047�14647725152�020422� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef AVIFILE_DS_VIDEODECODER_H #define AVIFILE_DS_VIDEODECODER_H typedef struct _DS_VideoDecoder DS_VideoDecoder; int DS_VideoDecoder_GetCapabilities(DS_VideoDecoder *this); DS_VideoDecoder * DS_VideoDecoder_Open(const char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto); void DS_VideoDecoder_Destroy(DS_VideoDecoder *this); void DS_VideoDecoder_StartInternal(DS_VideoDecoder *this); void DS_VideoDecoder_StopInternal(DS_VideoDecoder *this); int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int size, int is_keyframe, char* pImage); /* * bits == 0 - leave unchanged */ //int SetDestFmt(DS_VideoDecoder * this, int bits = 24, fourcc_t csp = 0); int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder *this, int bits, unsigned int csp); int DS_VideoDecoder_SetDirection(DS_VideoDecoder *this, int d); int DS_VideoDecoder_GetValue(DS_VideoDecoder *this, const char* name, int* value); int DS_VideoDecoder_SetValue(DS_VideoDecoder *this, const char* name, int value); #endif /* AVIFILE_DS_VIDEODECODER_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/guids.c�������������������������������������������������������0000644�0001750�0001750�00000010137�14647725152�016605� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "guids.h" const GUID CLSID_DivxDecompressorCF={0x82CCd3E0, 0xF71A, 0x11D0, { 0x9f, 0xe5, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}}; const GUID IID_IDivxFilterInterface={0xd132ee97, 0x3e38, 0x4030, {0x8b, 0x17, 0x59, 0x16, 0x3b, 0x30, 0xa1, 0xf5}}; const GUID CLSID_IV50_Decoder={0x30355649, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID IID_IBaseFilter={0x56a86895, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID IID_IEnumPins={0x56a86892, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID IID_IEnumMediaTypes={0x89c31040, 0x846b, 0x11ce, {0x97, 0xd3, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; const GUID IID_IMemInputPin={0x56a8689d, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID IID_IMemAllocator={0x56a8689c, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID IID_IMediaSample={0x56a8689a, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIATYPE_Video={0x73646976, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID GUID_NULL={0x0, 0x0, 0x0, {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; const GUID FORMAT_VideoInfo={0x05589f80, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}}; const GUID MEDIASUBTYPE_RGB1={0xe436eb78, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB4={0xe436eb79, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB8={0xe436eb7a, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB565={0xe436eb7b, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB555={0xe436eb7c, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB24={0xe436eb7d, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_RGB32={0xe436eb7e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70}}; const GUID MEDIASUBTYPE_YUYV={0x56595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_IYUV={0x56555949, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_YVU9={0x39555659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_Y411={0x31313459, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_Y41P={0x50313459, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_YUY2={0x32595559, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_YVYU={0x55595659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_UYVY={0x59565955, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_Y211={0x31313259, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_YV12={0x32315659, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_I420={0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID MEDIASUBTYPE_IF09={0x39304649, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}}; const GUID CLSID_MemoryAllocator={0x1e651cc0, 0xb199, 0x11d0, {0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45}}; const GUID IID_DivxHidden={0x598eba01, 0xb49a, 0x11d2, {0xa1, 0xc1, 0x00, 0x60, 0x97, 0x78, 0xaa, 0xaa}}; const GUID IID_Iv50Hidden={0x665a4442, 0xd905, 0x11d0, {0xa3, 0x0e, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}}; const GUID FORMAT_WaveFormatEx = {0x05589f81, 0xc356, 0x11CE, {0xBF, 0x01, 0x00, 0xAA, 0x00, 0x55, 0x59, 0x5A}}; const GUID MEDIATYPE_Audio = {0x73647561, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}}; const GUID MEDIASUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}}; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/DS_AudioDecoder.c���������������������������������������������0000644�0001750�0001750�00000013522�14647725152�020410� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************** DirectShow audio decoder Copyright 2001 Eugene Kuznetsov (divx@euro.ru) *********************************************************/ #ifndef NOAVIFILE_HEADERS #include "audiodecoder.h" #include "except.h" #else #include "libwin32.h" #endif #include "DS_Filter.h" struct _DS_AudioDecoder { WAVEFORMATEX in_fmt; AM_MEDIA_TYPE m_sOurType, m_sDestType; DS_Filter* m_pDS_Filter; char* m_sVhdr; char* m_sVhdr2; }; #include "DS_AudioDecoder.h" #include <string.h> #include <stdio.h> #include <stdlib.h> #define __MODULE__ "DirectShow audio decoder" typedef long STDCALL (*GETCLASS) (GUID*, GUID*, void**); DS_AudioDecoder * DS_AudioDecoder_Open(const char* dllname, GUID* guid, WAVEFORMATEX* wf) //DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf) { DS_AudioDecoder *this; int sz; WAVEFORMATEX* pWF; #ifdef LDT_paranoia Setup_LDT_Keeper(); Setup_FS_Segment(); #endif this = malloc(sizeof(DS_AudioDecoder)); sz = 18 + wf->cbSize; this->m_sVhdr = malloc(sz); memcpy(this->m_sVhdr, wf, sz); this->m_sVhdr2 = malloc(18); memcpy(this->m_sVhdr2, this->m_sVhdr, 18); pWF = (WAVEFORMATEX*)this->m_sVhdr2; pWF->wFormatTag = 1; pWF->wBitsPerSample = 16; pWF->nBlockAlign = pWF->nChannels * (pWF->wBitsPerSample + 7) / 8; pWF->cbSize = 0; pWF->nAvgBytesPerSec = pWF->nBlockAlign * pWF->nSamplesPerSec; memcpy(&this->in_fmt,wf,sizeof(WAVEFORMATEX)); memset(&this->m_sOurType, 0, sizeof(this->m_sOurType)); this->m_sOurType.majortype=MEDIATYPE_Audio; this->m_sOurType.subtype=MEDIASUBTYPE_PCM; this->m_sOurType.subtype.f1=wf->wFormatTag; this->m_sOurType.formattype=FORMAT_WaveFormatEx; this->m_sOurType.lSampleSize=wf->nBlockAlign; this->m_sOurType.bFixedSizeSamples=1; this->m_sOurType.bTemporalCompression=0; this->m_sOurType.pUnk=0; this->m_sOurType.cbFormat=sz; this->m_sOurType.pbFormat=this->m_sVhdr; memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); this->m_sDestType.majortype=MEDIATYPE_Audio; this->m_sDestType.subtype=MEDIASUBTYPE_PCM; // this->m_sDestType.subtype.f1=pWF->wFormatTag; this->m_sDestType.formattype=FORMAT_WaveFormatEx; this->m_sDestType.bFixedSizeSamples=1; this->m_sDestType.bTemporalCompression=0; this->m_sDestType.lSampleSize=pWF->nBlockAlign; if (wf->wFormatTag == 0x130) // ACEL hack to prevent memory corruption // obviosly we are missing something here this->m_sDestType.lSampleSize *= 288; this->m_sDestType.pUnk=0; this->m_sDestType.cbFormat=18; //pWF->cbSize; this->m_sDestType.pbFormat=this->m_sVhdr2; #if 0 print_wave_header(this->m_sVhdr); print_wave_header(this->m_sVhdr2); #endif /*try*/ { ALLOCATOR_PROPERTIES props, props1; this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); if( !this->m_pDS_Filter ) { free(this->m_sVhdr); free(this->m_sVhdr2); free(this); return NULL; } this->m_pDS_Filter->Start(this->m_pDS_Filter); props.cBuffers=1; props.cbBuffer=this->m_sOurType.lSampleSize; props.cbAlign=props.cbPrefix=0; this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1); this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll); } /* catch (FatalError& e) { e.PrintAll(); delete[] m_sVhdr; delete[] m_sVhdr2; delete m_pDS_Filter; throw; } */ return this; } void DS_AudioDecoder_Destroy(DS_AudioDecoder *this) { free(this->m_sVhdr); free(this->m_sVhdr2); DS_Filter_Destroy(this->m_pDS_Filter); free(this); } int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, unsigned int in_size, void* out_data, unsigned int out_size, unsigned int* size_read, unsigned int* size_written) { unsigned int written = 0; unsigned int read = 0; if (!in_data || !out_data) return -1; #ifdef LDT_paranoia Setup_FS_Segment(); #endif in_size -= in_size%this->in_fmt.nBlockAlign; while (in_size>0) { unsigned int frame_size = 0; char* frame_pointer; IMediaSample* sample=0; char* ptr; int result; // this->m_pOurOutput->SetFramePointer(out_data+written); this->m_pDS_Filter->m_pOurOutput->SetFramePointer(this->m_pDS_Filter->m_pOurOutput,&frame_pointer); this->m_pDS_Filter->m_pOurOutput->SetFrameSizePointer(this->m_pDS_Filter->m_pOurOutput,(long*)&frame_size); this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0); if (!sample) { Debug printf("DS_AudioDecoder::Convert() Error: null sample\n"); break; } sample->vt->SetActualDataLength(sample, this->in_fmt.nBlockAlign); sample->vt->GetPointer(sample, (BYTE **)&ptr); memcpy(ptr, (const uint8_t*)in_data + read, this->in_fmt.nBlockAlign); sample->vt->SetSyncPoint(sample, 1); sample->vt->SetPreroll(sample, 0); result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample); if (result) Debug printf("DS_AudioDecoder::Convert() Error: putting data into input pin %x\n", result); if ((written + frame_size) > out_size) { sample->vt->Release((IUnknown*)sample); break; } memcpy((uint8_t*)out_data + written, frame_pointer, frame_size); sample->vt->Release((IUnknown*)sample); read+=this->in_fmt.nBlockAlign; written+=frame_size; break; } if (size_read) *size_read = read; if (size_written) *size_written = written; return 0; } int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size) { double efficiency =(double) this->in_fmt.nAvgBytesPerSec / (this->in_fmt.nSamplesPerSec*this->in_fmt.nBlockAlign); int frames = (int)(dest_size*efficiency);; if (frames < 1) frames = 1; return frames * this->in_fmt.nBlockAlign; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/guids.h�������������������������������������������������������0000644�0001750�0001750�00000005111�14647725152�016606� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_GUIDS_H #define DS_GUIDS_H #include "com.h" #include "../wine/module.h" #include "../wine/windef.h" #include "../wine/vfw.h" //#define Debug if(1) #define Debug if(0) typedef struct __attribute__((__packed__)) _MediaType { GUID majortype; //0x0 GUID subtype; //0x10 int bFixedSizeSamples; //0x20 int bTemporalCompression; //0x24 unsigned long lSampleSize; //0x28 GUID formattype; //0x2c IUnknown* pUnk; //0x3c unsigned long cbFormat; //0x40 char* pbFormat; //0x44 } AM_MEDIA_TYPE; typedef long long REFERENCE_TIME; typedef struct __attribute__((__packed__)) RECT32 { int left, top, right, bottom; } RECT32; typedef struct __attribute__((__packed__)) tagVIDEOINFOHEADER { RECT32 rcSource; // The bit we really want to use RECT32 rcTarget; // Where the video should go unsigned long dwBitRate; // Approximate bit data rate unsigned long dwBitErrorRate; // Bit error rate for this stream REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units) BITMAPINFOHEADER bmiHeader; //int reserved[3]; } VIDEOINFOHEADER; typedef GUID CLSID; typedef GUID IID; extern const GUID IID_IBaseFilter; extern const GUID IID_IEnumPins; extern const GUID IID_IEnumMediaTypes; extern const GUID IID_IMemInputPin; extern const GUID IID_IMemAllocator; extern const GUID IID_IMediaSample; extern const GUID IID_DivxHidden; extern const GUID IID_Iv50Hidden; extern const GUID CLSID_DivxDecompressorCF; extern const GUID IID_IDivxFilterInterface; extern const GUID CLSID_IV50_Decoder; extern const GUID CLSID_MemoryAllocator; extern const GUID MEDIATYPE_Video; extern const GUID GUID_NULL; extern const GUID FORMAT_VideoInfo; extern const GUID MEDIASUBTYPE_RGB1; extern const GUID MEDIASUBTYPE_RGB4; extern const GUID MEDIASUBTYPE_RGB8; extern const GUID MEDIASUBTYPE_RGB565; extern const GUID MEDIASUBTYPE_RGB555; extern const GUID MEDIASUBTYPE_RGB24; extern const GUID MEDIASUBTYPE_RGB32; extern const GUID MEDIASUBTYPE_YUYV; extern const GUID MEDIASUBTYPE_IYUV; extern const GUID MEDIASUBTYPE_YVU9; extern const GUID MEDIASUBTYPE_Y411; extern const GUID MEDIASUBTYPE_Y41P; extern const GUID MEDIASUBTYPE_YUY2; extern const GUID MEDIASUBTYPE_YVYU; extern const GUID MEDIASUBTYPE_UYVY; extern const GUID MEDIASUBTYPE_Y211; extern const GUID MEDIASUBTYPE_YV12; extern const GUID MEDIASUBTYPE_I420; extern const GUID MEDIASUBTYPE_IF09; extern const GUID FORMAT_WaveFormatEx; extern const GUID MEDIATYPE_Audio; extern const GUID MEDIASUBTYPE_PCM; #endif /* DS_GUIDS_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/inputpin.h����������������������������������������������������0000644�0001750�0001750�00000002477�14647725152�017355� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_INPUTPIN_H #define DS_INPUTPIN_H #include "interfaces.h" typedef struct _CBaseFilter2 CBaseFilter2; struct _CBaseFilter2 { IBaseFilter_vt* vt; DECLARE_IUNKNOWN(); IPin* pin; GUID interfaces[5]; IPin* ( *GetPin )(CBaseFilter2* This); }; CBaseFilter2* CBaseFilter2Create(void); typedef struct _CBaseFilter CBaseFilter; struct _CBaseFilter { IBaseFilter_vt* vt; DECLARE_IUNKNOWN(); // has to match CBaseFilter2 - INHERITANCE!! IPin* pin; IPin* unused_pin; GUID interfaces[2]; IPin* ( *GetPin )(CBaseFilter* This); IPin* ( *GetUnusedPin )(CBaseFilter* This); }; CBaseFilter* CBaseFilterCreate(const AM_MEDIA_TYPE* vhdr, CBaseFilter2* parent); typedef struct { IPin_vt* vt; DECLARE_IUNKNOWN(); CBaseFilter* parent; AM_MEDIA_TYPE type; GUID interfaces[1]; } CInputPin; CInputPin* CInputPinCreate(CBaseFilter* parent, const AM_MEDIA_TYPE* vhdr); typedef struct { IPin_vt* vt; DECLARE_IUNKNOWN(); CBaseFilter* parent; GUID interfaces[1]; IPin* remote_pin; } CRemotePin; CRemotePin* CRemotePinCreate(CBaseFilter* pt, IPin* rpin); typedef struct { IPin_vt* vt; DECLARE_IUNKNOWN(); CBaseFilter2* parent; GUID interfaces[1]; } CRemotePin2; CRemotePin2* CRemotePin2Create(CBaseFilter2* parent); #endif /* DS_INPUTPIN_H */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/cmediasample.h������������������������������������������������0000644�0001750�0001750�00000001426�14647725152�020124� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_CMEDIASAMPLE_H #define DS_CMEDIASAMPLE_H #include "interfaces.h" #include "guids.h" typedef struct _CMediaSample CMediaSample; struct _CMediaSample { IMediaSample_vt* vt; DECLARE_IUNKNOWN(); IMemAllocator* all; int size; int actual_size; char* block; char* own_block; int isPreroll; int isSyncPoint; int isDiscontinuity; LONGLONG time_start; LONGLONG time_end; AM_MEDIA_TYPE media_type; int type_valid; void ( *SetPointer) (CMediaSample* This, char* pointer); void ( *ResetPointer) (CMediaSample* This); // FIXME replace with Set & 0 }; CMediaSample* CMediaSampleCreate(IMemAllocator* allocator, int _size); // called from allocator void CMediaSample_Destroy(CMediaSample* This); #endif /* DS_CMEDIASAMPLE_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/inputpin.c����������������������������������������������������0000644�0001750�0001750�00000051005�14647725152�017337� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "inputpin.h" #include "../wine/winerror.h" #include <string.h> #include <stdio.h> #include <stdlib.h> static inline int unimplemented(const char* s, void* p) { Debug printf("%s(%p) called (UNIMPLEMENTED)", s, p); return E_NOTIMPL; } /*********** * EnumPins ***********/ typedef struct { IEnumPins_vt* vt; DECLARE_IUNKNOWN(); IPin* pin1; IPin* pin2; int counter; GUID interfaces[2]; } CEnumPins; static long STDCALL CEnumPins_Next(IEnumPins* This, /* [in] */ unsigned long cMediaTypes, /* [size_is][out] */ IPin** ppMediaTypes, /* [out] */ unsigned long* pcFetched) { CEnumPins* pin = (CEnumPins*)This; Debug printf("CEnumPins_Next(%p) called\n", This); if (!ppMediaTypes) return E_INVALIDARG; if (!pcFetched && (cMediaTypes!=1)) return E_INVALIDARG; if (cMediaTypes<=0) return 0; //lcounter = ((CEnumPins*)This)->counter; //lpin1 = ((CEnumPins*)This)->pin1; //lpin2 = ((CEnumPins*)This)->pin2; if (((pin->counter == 2) && pin->pin2) || ((pin->counter == 1) && !pin->pin2)) { if (pcFetched) *pcFetched=0; return 1; } if (pcFetched) *pcFetched=1; if (pin->counter==0) { *ppMediaTypes = pin->pin1; pin->pin1->vt->AddRef((IUnknown*)pin->pin1); } else { *ppMediaTypes = pin->pin2; pin->pin2->vt->AddRef((IUnknown*)pin->pin2); } pin->counter++; if (cMediaTypes == 1) return 0; return 1; } static long STDCALL CEnumPins_Skip(IEnumPins* This, /* [in] */ unsigned long cMediaTypes) { (void)cMediaTypes; Debug unimplemented("CEnumPins_Skip", This); return E_NOTIMPL; } static long STDCALL CEnumPins_Reset(IEnumPins* This) { Debug printf("CEnumPins_Reset(%p) called\n", This); ((CEnumPins*)This)->counter = 0; return 0; } static long STDCALL CEnumPins_Clone(IEnumPins* This, /* [out] */ IEnumPins** ppEnum) { (void)ppEnum; Debug unimplemented("CEnumPins_Clone", This); return E_NOTIMPL; } static void CEnumPins_Destroy(CEnumPins* This) { free(This->vt); free(This); } IMPLEMENT_IUNKNOWN(CEnumPins) static CEnumPins* CEnumPinsCreate(IPin* p, IPin* pp) { CEnumPins* This = (CEnumPins*) malloc(sizeof(CEnumPins)); if (!This) return NULL; This->refcount = 1; This->pin1 = p; This->pin2 = pp; This->counter = 0; This->vt = (IEnumPins_vt*) malloc(sizeof(IEnumPins_vt)); if (!This->vt) { free(This); return NULL; } This->vt->QueryInterface = CEnumPins_QueryInterface; This->vt->AddRef = CEnumPins_AddRef; This->vt->Release = CEnumPins_Release; This->vt->Next = CEnumPins_Next; This->vt->Skip = CEnumPins_Skip; This->vt->Reset = CEnumPins_Reset; This->vt->Clone = CEnumPins_Clone; This->interfaces[0] = IID_IUnknown; This->interfaces[1] = IID_IEnumPins; return This; } /*********** * InputPin ***********/ static long STDCALL CInputPin_Connect(IPin* This, /* [in] */ IPin* pReceivePin, /* [in] */ AM_MEDIA_TYPE* pmt) { (void)pReceivePin; (void)pmt; Debug unimplemented("CInputPin_Connect", This); return E_NOTIMPL; } static long STDCALL CInputPin_ReceiveConnection(IPin* This, /* [in] */ IPin* pConnector, /* [in] */ const AM_MEDIA_TYPE *pmt) { (void)pConnector; (void)pmt; Debug unimplemented("CInputPin_ReceiveConnection", This); return E_NOTIMPL; } static long STDCALL CInputPin_Disconnect(IPin* This) { Debug unimplemented("CInputPin_Disconnect", This); return E_NOTIMPL; } static long STDCALL CInputPin_ConnectedTo(IPin* This, /* [out] */ IPin** pPin) { (void)pPin; Debug unimplemented("CInputPin_ConnectedTo", This); return E_NOTIMPL; } static long STDCALL CInputPin_ConnectionMediaType(IPin* This, /* [out] */ AM_MEDIA_TYPE *pmt) { Debug printf("CInputPin_ConnectionMediaType(%p) called\n", This); if (!pmt) return E_INVALIDARG; *pmt=((CInputPin*)This)->type; if (pmt->cbFormat > 0) { pmt->pbFormat=(char *)CoTaskMemAlloc(pmt->cbFormat); memcpy(pmt->pbFormat, ((CInputPin*)This)->type.pbFormat, pmt->cbFormat); } return 0; } static long STDCALL CInputPin_QueryPinInfo(IPin* This, /* [out] */ PIN_INFO *pInfo) { CBaseFilter* lparent=((CInputPin*)This)->parent; Debug printf("CInputPin_QueryPinInfo(%p) called\n", This); pInfo->dir = PINDIR_OUTPUT; pInfo->pFilter = (IBaseFilter*) lparent; lparent->vt->AddRef((IUnknown*)lparent); pInfo->achName[0] = 0; return 0; } static long STDCALL CInputPin_QueryDirection(IPin* This, /* [out] */ PIN_DIRECTION *pPinDir) { *pPinDir = PINDIR_OUTPUT; Debug printf("CInputPin_QueryDirection(%p) called\n", This); return 0; } static long STDCALL CInputPin_QueryId(IPin* This, /* [out] */ unsigned short* *Id) { (void)Id; Debug unimplemented("CInputPin_QueryId", This); return E_NOTIMPL; } static long STDCALL CInputPin_QueryAccept(IPin* This, /* [in] */ const AM_MEDIA_TYPE* pmt) { (void)pmt; Debug unimplemented("CInputPin_QueryAccept", This); return E_NOTIMPL; } static long STDCALL CInputPin_EnumMediaTypes(IPin* This, /* [out] */ IEnumMediaTypes** ppEnum) { (void)ppEnum; Debug unimplemented("CInputPin_EnumMediaTypes", This); return E_NOTIMPL; } static long STDCALL CInputPin_QueryInternalConnections(IPin* This, /* [out] */ IPin** apPin, /* [out][in] */ unsigned long *nPin) { (void)apPin; (void)nPin; Debug unimplemented("CInputPin_QueryInternalConnections", This); return E_NOTIMPL; } static long STDCALL CInputPin_EndOfStream(IPin * This) { Debug unimplemented("CInputPin_EndOfStream", This); return E_NOTIMPL; } static long STDCALL CInputPin_BeginFlush(IPin * This) { Debug unimplemented("CInputPin_BeginFlush", This); return E_NOTIMPL; } static long STDCALL CInputPin_EndFlush(IPin* This) { Debug unimplemented("CInputPin_EndFlush", This); return E_NOTIMPL; } static long STDCALL CInputPin_NewSegment(IPin* This, /* [in] */ REFERENCE_TIME tStart, /* [in] */ REFERENCE_TIME tStop, /* [in] */ double dRate) { (void)tStart; (void)tStop; (void)dRate; Debug unimplemented("CInputPin_NewSegment", This); return E_NOTIMPL; } static void CInputPin_Destroy(CInputPin* This) { free(This->vt); free(This); } IMPLEMENT_IUNKNOWN(CInputPin) CInputPin* CInputPinCreate(CBaseFilter* p, const AM_MEDIA_TYPE* amt) { CInputPin* This = (CInputPin*) malloc(sizeof(CInputPin)); if (!This) return NULL; This->refcount = 1; This->parent = p; This->type = *amt; This->vt= (IPin_vt*) malloc(sizeof(IPin_vt)); if (!This->vt) { free(This); return NULL; } This->vt->QueryInterface = CInputPin_QueryInterface; This->vt->AddRef = CInputPin_AddRef; This->vt->Release = CInputPin_Release; This->vt->Connect = CInputPin_Connect; This->vt->ReceiveConnection = CInputPin_ReceiveConnection; This->vt->Disconnect = CInputPin_Disconnect; This->vt->ConnectedTo = CInputPin_ConnectedTo; This->vt->ConnectionMediaType = CInputPin_ConnectionMediaType; This->vt->QueryPinInfo = CInputPin_QueryPinInfo; This->vt->QueryDirection = CInputPin_QueryDirection; This->vt->QueryId = CInputPin_QueryId; This->vt->QueryAccept = CInputPin_QueryAccept; This->vt->EnumMediaTypes = CInputPin_EnumMediaTypes; This->vt->QueryInternalConnections = CInputPin_QueryInternalConnections; This->vt->EndOfStream = CInputPin_EndOfStream; This->vt->BeginFlush = CInputPin_BeginFlush; This->vt->EndFlush = CInputPin_EndFlush; This->vt->NewSegment = CInputPin_NewSegment; This->interfaces[0]=IID_IUnknown; return This; } /************* * BaseFilter *************/ static long STDCALL CBaseFilter_GetClassID(IBaseFilter * This, /* [out] */ CLSID *pClassID) { (void)pClassID; Debug unimplemented("CBaseFilter_GetClassID", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_Stop(IBaseFilter* This) { Debug unimplemented("CBaseFilter_Stop", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_Pause(IBaseFilter* This) { Debug unimplemented("CBaseFilter_Pause", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_Run(IBaseFilter* This, REFERENCE_TIME tStart) { (void)tStart; Debug unimplemented("CBaseFilter_Run", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_GetState(IBaseFilter* This, /* [in] */ unsigned long dwMilliSecsTimeout, // /* [out] */ FILTER_STATE *State) void* State) { (void)dwMilliSecsTimeout; (void)State; Debug unimplemented("CBaseFilter_GetState", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_SetSyncSource(IBaseFilter* This, /* [in] */ IReferenceClock *pClock) { (void)pClock; Debug unimplemented("CBaseFilter_SetSyncSource", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_GetSyncSource(IBaseFilter* This, /* [out] */ IReferenceClock **pClock) { (void)pClock; Debug unimplemented("CBaseFilter_GetSyncSource", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_EnumPins(IBaseFilter* This, /* [out] */ IEnumPins **ppEnum) { Debug printf("CBaseFilter_EnumPins(%p) called\n", This); *ppEnum = (IEnumPins*) CEnumPinsCreate(((CBaseFilter*)This)->pin, ((CBaseFilter*)This)->unused_pin); return 0; } static long STDCALL CBaseFilter_FindPin(IBaseFilter* This, /* [string][in] */ const unsigned short* Id, /* [out] */ IPin **ppPin) { (void)Id; (void)ppPin; Debug unimplemented("CBaseFilter_FindPin\n", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_QueryFilterInfo(IBaseFilter* This, // /* [out] */ FILTER_INFO *pInfo) void* pInfo) { (void)pInfo; Debug unimplemented("CBaseFilter_QueryFilterInfo", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_JoinFilterGraph(IBaseFilter* This, /* [in] */ IFilterGraph* pGraph, /* [string][in] */ const unsigned short* pName) { (void)pGraph; (void)pName; Debug unimplemented("CBaseFilter_JoinFilterGraph", This); return E_NOTIMPL; } static long STDCALL CBaseFilter_QueryVendorInfo(IBaseFilter* This, /* [string][out] */ unsigned short** pVendorInfo) { (void)pVendorInfo; Debug unimplemented("CBaseFilter_QueryVendorInfo", This); return E_NOTIMPL; } static IPin* CBaseFilter_GetPin(CBaseFilter* This) { return This->pin; } static IPin* CBaseFilter_GetUnusedPin(CBaseFilter* This) { return This->unused_pin; } static void CBaseFilter_Destroy(CBaseFilter* This) { if (This->vt) free(This->vt); if (This->pin) This->pin->vt->Release((IUnknown*)This->pin); if (This->unused_pin) This->unused_pin->vt->Release((IUnknown*)This->unused_pin); free(This); } IMPLEMENT_IUNKNOWN(CBaseFilter) CBaseFilter* CBaseFilterCreate(const AM_MEDIA_TYPE* type, CBaseFilter2* parent) { CBaseFilter* This = (CBaseFilter*) malloc(sizeof(CBaseFilter)); if (!This) return NULL; This->refcount = 1; This->pin = (IPin*) CInputPinCreate(This, type); This->unused_pin = (IPin*) CRemotePinCreate(This, parent->GetPin(parent)); This->vt = (IBaseFilter_vt*) malloc(sizeof(IBaseFilter_vt)); if (!This->vt || !This->pin || !This->unused_pin) { CBaseFilter_Destroy(This); return NULL; } This->vt->QueryInterface = CBaseFilter_QueryInterface; This->vt->AddRef = CBaseFilter_AddRef; This->vt->Release = CBaseFilter_Release; This->vt->GetClassID = CBaseFilter_GetClassID; This->vt->Stop = CBaseFilter_Stop; This->vt->Pause = CBaseFilter_Pause; This->vt->Run = CBaseFilter_Run; This->vt->GetState = CBaseFilter_GetState; This->vt->SetSyncSource = CBaseFilter_SetSyncSource; This->vt->GetSyncSource = CBaseFilter_GetSyncSource; This->vt->EnumPins = CBaseFilter_EnumPins; This->vt->FindPin = CBaseFilter_FindPin; This->vt->QueryFilterInfo = CBaseFilter_QueryFilterInfo; This->vt->JoinFilterGraph = CBaseFilter_JoinFilterGraph; This->vt->QueryVendorInfo = CBaseFilter_QueryVendorInfo; This->interfaces[0] = IID_IUnknown; This->interfaces[1] = IID_IBaseFilter; This->GetPin = CBaseFilter_GetPin; This->GetUnusedPin = CBaseFilter_GetUnusedPin; return This; } /************** * BaseFilter2 **************/ static long STDCALL CBaseFilter2_GetClassID(IBaseFilter* This, /* [out] */ CLSID* pClassID) { (void)pClassID; Debug unimplemented("CBaseFilter2_GetClassID", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_Stop(IBaseFilter* This) { Debug unimplemented("CBaseFilter2_Stop", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_Pause(IBaseFilter* This) { Debug unimplemented("CBaseFilter2_Pause", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_Run(IBaseFilter* This, REFERENCE_TIME tStart) { (void)tStart; Debug unimplemented("CBaseFilter2_Run", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_GetState(IBaseFilter* This, /* [in] */ unsigned long dwMilliSecsTimeout, // /* [out] */ FILTER_STATE *State) void* State) { (void)dwMilliSecsTimeout; (void)State; Debug unimplemented("CBaseFilter2_GetState", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_SetSyncSource(IBaseFilter* This, /* [in] */ IReferenceClock* pClock) { (void)pClock; Debug unimplemented("CBaseFilter2_SetSyncSource", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_GetSyncSource(IBaseFilter* This, /* [out] */ IReferenceClock** pClock) { (void)pClock; Debug unimplemented("CBaseFilter2_GetSyncSource", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_EnumPins(IBaseFilter* This, /* [out] */ IEnumPins** ppEnum) { Debug printf("CBaseFilter2_EnumPins(%p) called\n", This); *ppEnum = (IEnumPins*) CEnumPinsCreate(((CBaseFilter2*)This)->pin, 0); return 0; } static long STDCALL CBaseFilter2_FindPin(IBaseFilter* This, /* [string][in] */ const unsigned short* Id, /* [out] */ IPin** ppPin) { (void)Id; (void)ppPin; Debug unimplemented("CBaseFilter2_FindPin", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_QueryFilterInfo(IBaseFilter* This, // /* [out] */ FILTER_INFO *pInfo) void* pInfo) { (void)pInfo; Debug unimplemented("CBaseFilter2_QueryFilterInfo", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_JoinFilterGraph(IBaseFilter* This, /* [in] */ IFilterGraph* pGraph, /* [string][in] */ const unsigned short* pName) { (void)pGraph; (void)pName; Debug unimplemented("CBaseFilter2_JoinFilterGraph", This); return E_NOTIMPL; } static long STDCALL CBaseFilter2_QueryVendorInfo(IBaseFilter* This, /* [string][out] */ unsigned short** pVendorInfo) { (void)pVendorInfo; Debug unimplemented("CBaseFilter2_QueryVendorInfo", This); return E_NOTIMPL; } static IPin* CBaseFilter2_GetPin(CBaseFilter2* This) { return This->pin; } static void CBaseFilter2_Destroy(CBaseFilter2* This) { Debug printf("CBaseFilter2_Destroy(%p) called\n", This); if (This->pin) This->pin->vt->Release((IUnknown*) This->pin); if (This->vt) free(This->vt); free(This); } IMPLEMENT_IUNKNOWN(CBaseFilter2) static GUID CBaseFilter2_interf1 = {0x76c61a30, 0xebe1, 0x11cf, {0x89, 0xf9, 0x00, 0xa0, 0xc9, 0x03, 0x49, 0xcb}}; static GUID CBaseFilter2_interf2 = {0xaae7e4e2, 0x6388, 0x11d1, {0x8d, 0x93, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2}}; static GUID CBaseFilter2_interf3 = {0x02ef04dd, 0x7580, 0x11d1, {0xbe, 0xce, 0x00, 0xc0, 0x4f, 0xb6, 0xe9, 0x37}}; CBaseFilter2* CBaseFilter2Create() { CBaseFilter2* This = (CBaseFilter2*) malloc(sizeof(CBaseFilter2)); if (!This) return NULL; This->refcount = 1; This->pin = (IPin*) CRemotePin2Create(This); This->vt = (IBaseFilter_vt*) malloc(sizeof(IBaseFilter_vt)); if (!This->pin || !This->vt) { CBaseFilter2_Destroy(This); return NULL; } memset(This->vt, 0, sizeof(IBaseFilter_vt)); This->vt->QueryInterface = CBaseFilter2_QueryInterface; This->vt->AddRef = CBaseFilter2_AddRef; This->vt->Release = CBaseFilter2_Release; This->vt->GetClassID = CBaseFilter2_GetClassID; This->vt->Stop = CBaseFilter2_Stop; This->vt->Pause = CBaseFilter2_Pause; This->vt->Run = CBaseFilter2_Run; This->vt->GetState = CBaseFilter2_GetState; This->vt->SetSyncSource = CBaseFilter2_SetSyncSource; This->vt->GetSyncSource = CBaseFilter2_GetSyncSource; This->vt->EnumPins = CBaseFilter2_EnumPins; This->vt->FindPin = CBaseFilter2_FindPin; This->vt->QueryFilterInfo = CBaseFilter2_QueryFilterInfo; This->vt->JoinFilterGraph = CBaseFilter2_JoinFilterGraph; This->vt->QueryVendorInfo = CBaseFilter2_QueryVendorInfo; This->GetPin = CBaseFilter2_GetPin; This->interfaces[0] = IID_IUnknown; This->interfaces[1] = IID_IBaseFilter; This->interfaces[2] = CBaseFilter2_interf1; This->interfaces[3] = CBaseFilter2_interf2; This->interfaces[4] = CBaseFilter2_interf3; return This; } /************* * CRemotePin *************/ static long STDCALL CRemotePin_ConnectedTo(IPin* This, /* [out] */ IPin** pPin) { Debug printf("CRemotePin_ConnectedTo(%p) called\n", This); if (!pPin) return E_INVALIDARG; *pPin = ((CRemotePin*)This)->remote_pin; (*pPin)->vt->AddRef((IUnknown*)(*pPin)); return 0; } static long STDCALL CRemotePin_QueryDirection(IPin* This, /* [out] */ PIN_DIRECTION* pPinDir) { Debug printf("CRemotePin_QueryDirection(%p) called\n", This); if (!pPinDir) return E_INVALIDARG; *pPinDir=PINDIR_INPUT; return 0; } static long STDCALL CRemotePin_ConnectionMediaType(IPin* This, /* [out] */ AM_MEDIA_TYPE* pmt) { (void)pmt; Debug unimplemented("CRemotePin_ConnectionMediaType", This); return E_NOTIMPL; } static long STDCALL CRemotePin_QueryPinInfo(IPin* This, /* [out] */ PIN_INFO* pInfo) { CBaseFilter* lparent = ((CRemotePin*)This)->parent; Debug printf("CRemotePin_QueryPinInfo(%p) called\n", This); pInfo->dir= PINDIR_INPUT; pInfo->pFilter = (IBaseFilter*) lparent; lparent->vt->AddRef((IUnknown*)lparent); pInfo->achName[0]=0; return 0; } static void CRemotePin_Destroy(CRemotePin* This) { Debug printf("CRemotePin_Destroy(%p) called\n", This); free(This->vt); free(This); } IMPLEMENT_IUNKNOWN(CRemotePin) CRemotePin* CRemotePinCreate(CBaseFilter* pt, IPin* rpin) { CRemotePin* This = (CRemotePin*) malloc(sizeof(CRemotePin)); if (!This) return NULL; Debug printf("CRemotePinCreate() called -> %p\n", This); This->parent = pt; This->remote_pin = rpin; This->refcount = 1; This->vt = (IPin_vt*) malloc(sizeof(IPin_vt)); if (!This->vt) { free(This); return NULL; } memset(This->vt, 0, sizeof(IPin_vt)); This->vt->QueryInterface = CRemotePin_QueryInterface; This->vt->AddRef = CRemotePin_AddRef; This->vt->Release = CRemotePin_Release; This->vt->QueryDirection = CRemotePin_QueryDirection; This->vt->ConnectedTo = CRemotePin_ConnectedTo; This->vt->ConnectionMediaType = CRemotePin_ConnectionMediaType; This->vt->QueryPinInfo = CRemotePin_QueryPinInfo; This->interfaces[0] = IID_IUnknown; return This; } /************* * CRemotePin2 *************/ static long STDCALL CRemotePin2_QueryPinInfo(IPin* This, /* [out] */ PIN_INFO* pInfo) { CBaseFilter2* lparent=((CRemotePin2*)This)->parent; Debug printf("CRemotePin2_QueryPinInfo(%p) called\n", This); pInfo->pFilter=(IBaseFilter*)lparent; lparent->vt->AddRef((IUnknown*)lparent); pInfo->dir=PINDIR_OUTPUT; pInfo->achName[0]=0; return 0; } // FIXME - not being released! static void CRemotePin2_Destroy(CRemotePin2* This) { Debug printf("CRemotePin2_Destroy(%p) called\n", This); free(This->vt); free(This); } IMPLEMENT_IUNKNOWN(CRemotePin2) CRemotePin2* CRemotePin2Create(CBaseFilter2* p) { CRemotePin2* This = (CRemotePin2*) malloc(sizeof(CRemotePin2)); if (!This) return NULL; Debug printf("CRemotePin2Create() called -> %p\n", This); This->parent = p; This->refcount = 1; This->vt = (IPin_vt*) malloc(sizeof(IPin_vt)); if (!This->vt) { free(This); return NULL; } memset(This->vt, 0, sizeof(IPin_vt)); This->vt->QueryInterface = CRemotePin2_QueryInterface; This->vt->AddRef = CRemotePin2_AddRef; This->vt->Release = CRemotePin2_Release; This->vt->QueryPinInfo = CRemotePin2_QueryPinInfo; This->interfaces[0] = IID_IUnknown; return This; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/DS_AudioDecoder.h���������������������������������������������0000644�0001750�0001750�00000001234�14647725152�020412� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef AVIFILE_DS_AUDIODECODER_H #define AVIFILE_DS_AUDIODECODER_H typedef struct _DS_AudioDecoder DS_AudioDecoder; //DS_AudioDecoder * DS_AudioDecoder_Create(const CodecInfo * info, const WAVEFORMATEX* wf); DS_AudioDecoder * DS_AudioDecoder_Open(const char* dllname, GUID* guid, WAVEFORMATEX* wf); void DS_AudioDecoder_Destroy(DS_AudioDecoder *this); int DS_AudioDecoder_Convert(DS_AudioDecoder *this, const void* in_data, unsigned int in_size, void* out_data, unsigned int out_size, unsigned int* size_read, unsigned int* size_written); int DS_AudioDecoder_GetSrcSize(DS_AudioDecoder *this, int dest_size); #endif // AVIFILE_DS_AUDIODECODER_H ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/allocator.h���������������������������������������������������0000644�0001750�0001750�00000001135�14647725152�017455� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_ALLOCATOR_H #define DS_ALLOCATOR_H #include "interfaces.h" #include "cmediasample.h" typedef struct _avm_list_t avm_list_t; typedef struct _MemAllocator MemAllocator; struct _MemAllocator { IMemAllocator_vt* vt; DECLARE_IUNKNOWN(); ALLOCATOR_PROPERTIES props; avm_list_t* used_list; avm_list_t* free_list; char* new_pointer; CMediaSample* modified_sample; GUID interfaces[2]; void ( *SetPointer )(MemAllocator* This, char* pointer); void ( *ResetPointer )(MemAllocator* This); }; MemAllocator* MemAllocatorCreate(void); #endif /* DS_ALLOCATOR_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/cmediasample.c������������������������������������������������0000644�0001750�0001750�00000023731�14647725152�020122� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "cmediasample.h" #include "../wine/winerror.h" #include <stdio.h> #include <string.h> #include <stdlib.h> /* * currently hack to make some extra room for DS Acel codec which * seems to overwrite allocated memory - FIXME better later * check the buffer allocation */ static const int SAFETY_ACEL = 1024; static long STDCALL CMediaSample_QueryInterface(IUnknown* This, /* [in] */ const GUID* iid, /* [iid_is][out] */ void **ppv) { Debug printf("CMediaSample_QueryInterface(%p) called\n", This); if (!ppv) return E_INVALIDARG; if (memcmp(iid, &IID_IUnknown, sizeof(*iid)) == 0) { *ppv = (void*)This; ((IMediaSample*) This)->vt->AddRef(This); return 0; } if (memcmp(iid, &IID_IMediaSample, sizeof(*iid)) == 0) { *ppv = (void*)This; ((IMediaSample*) This)->vt->AddRef(This); return 0; } return E_NOINTERFACE; } static long STDCALL CMediaSample_AddRef(IUnknown* This) { Debug printf("CMediaSample_AddRef(%p) called\n", This); ((CMediaSample*)This)->refcount++; return 0; } void CMediaSample_Destroy(CMediaSample* This) { Debug printf("CMediaSample_Destroy(%p) called (ref:%d)\n", This, This->refcount); free(This->vt); free(This->own_block); if (This->media_type.pbFormat) CoTaskMemFree(This->media_type.pbFormat); free(This); } static long STDCALL CMediaSample_Release(IUnknown* This) { CMediaSample* parent = (CMediaSample*)This; Debug printf("CMediaSample_Release(%p) called (new ref:%d)\n", This, ((CMediaSample*)This)->refcount-1); if (--((CMediaSample*) This)->refcount == 0) { parent->all->vt->ReleaseBuffer((IMemAllocator*)(parent->all), (IMediaSample*)This); } return 0; } static HRESULT STDCALL CMediaSample_GetPointer(IMediaSample* This, /* [out] */ BYTE** ppBuffer) { Debug printf("CMediaSample_GetPointer(%p) called -> %p, size: %d %d\n", This, ((CMediaSample*) This)->block, ((CMediaSample*)This)->actual_size, ((CMediaSample*)This)->size); if (!ppBuffer) return E_INVALIDARG; *ppBuffer = (BYTE*) ((CMediaSample*) This)->block; return 0; } static long STDCALL CMediaSample_GetSize(IMediaSample * This) { Debug printf("CMediaSample_GetSize(%p) called -> %d\n", This, ((CMediaSample*) This)->size); return ((CMediaSample*) This)->size; } static HRESULT STDCALL CMediaSample_GetTime(IMediaSample * This, /* [out] */ REFERENCE_TIME *pTimeStart, /* [out] */ REFERENCE_TIME *pTimeEnd) { (void)pTimeStart; (void)pTimeEnd; Debug printf("CMediaSample_GetTime(%p) called (UNIMPLEMENTED)\n", This); return E_NOTIMPL; } static HRESULT STDCALL CMediaSample_SetTime(IMediaSample * This, /* [in] */ REFERENCE_TIME *pTimeStart, /* [in] */ REFERENCE_TIME *pTimeEnd) { (void)pTimeStart; (void)pTimeEnd; Debug printf("CMediaSample_SetTime(%p) called (UNIMPLEMENTED)\n", This); return E_NOTIMPL; } static HRESULT STDCALL CMediaSample_IsSyncPoint(IMediaSample * This) { Debug printf("CMediaSample_IsSyncPoint(%p) called\n", This); if (((CMediaSample*)This)->isSyncPoint) return 0; return 1; } static HRESULT STDCALL CMediaSample_SetSyncPoint(IMediaSample * This, long bIsSyncPoint) { Debug printf("CMediaSample_SetSyncPoint(%p) called\n", This); ((CMediaSample*)This)->isSyncPoint = bIsSyncPoint; return 0; } static HRESULT STDCALL CMediaSample_IsPreroll(IMediaSample * This) { Debug printf("CMediaSample_IsPreroll(%p) called\n", This); if (((CMediaSample*)This)->isPreroll) return 0;//S_OK return 1;//S_FALSE } static HRESULT STDCALL CMediaSample_SetPreroll(IMediaSample * This, long bIsPreroll) { Debug printf("CMediaSample_SetPreroll(%p) called\n", This); ((CMediaSample*)This)->isPreroll=bIsPreroll; return 0; } static long STDCALL CMediaSample_GetActualDataLength(IMediaSample* This) { Debug printf("CMediaSample_GetActualDataLength(%p) called -> %d\n", This, ((CMediaSample*)This)->actual_size); return ((CMediaSample*)This)->actual_size; } static HRESULT STDCALL CMediaSample_SetActualDataLength(IMediaSample* This, long __MIDL_0010) { CMediaSample* cms = (CMediaSample*)This; Debug printf("CMediaSample_SetActualDataLength(%p, %ld) called\n", This, __MIDL_0010); if (__MIDL_0010 > cms->size) { char* c = cms->own_block; Debug printf("CMediaSample - buffer overflow %ld %d %p %p\n", __MIDL_0010, ((CMediaSample*)This)->size, cms->own_block, cms->block); cms->own_block = (char*) realloc(cms->own_block, (size_t) __MIDL_0010 + SAFETY_ACEL); if (c == cms->block) cms->block = cms->own_block; cms->size = __MIDL_0010; } cms->actual_size = __MIDL_0010; return 0; } static HRESULT STDCALL CMediaSample_GetMediaType(IMediaSample* This, AM_MEDIA_TYPE** ppMediaType) { AM_MEDIA_TYPE* t; Debug printf("CMediaSample_GetMediaType(%p) called\n", This); if(!ppMediaType) return E_INVALIDARG; if(!((CMediaSample*)This)->type_valid) { *ppMediaType=0; return 1; } t = &((CMediaSample*)This)->media_type; // if(t.pbFormat)CoTaskMemFree(t.pbFormat); (*ppMediaType) = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); **ppMediaType = *t; (*ppMediaType)->pbFormat = (char*)CoTaskMemAlloc(t->cbFormat); memcpy((*ppMediaType)->pbFormat, t->pbFormat, t->cbFormat); // *ppMediaType=0; //media type was not changed return 0; } static HRESULT STDCALL CMediaSample_SetMediaType(IMediaSample * This, AM_MEDIA_TYPE *pMediaType) { AM_MEDIA_TYPE* t; Debug printf("CMediaSample_SetMediaType(%p) called\n", This); if (!pMediaType) return E_INVALIDARG; t = &((CMediaSample*)This)->media_type; if (t->pbFormat) CoTaskMemFree(t->pbFormat); t = pMediaType; if (t->cbFormat) { t->pbFormat = (char*)CoTaskMemAlloc(t->cbFormat); memcpy(t->pbFormat, pMediaType->pbFormat, t->cbFormat); } else t->pbFormat = 0; ((CMediaSample*) This)->type_valid=1; return 0; } static HRESULT STDCALL CMediaSample_IsDiscontinuity(IMediaSample * This) { Debug printf("CMediaSample_IsDiscontinuity(%p) called\n", This); return ((CMediaSample*) This)->isDiscontinuity; } static HRESULT STDCALL CMediaSample_SetDiscontinuity(IMediaSample * This, long bDiscontinuity) { Debug printf("CMediaSample_SetDiscontinuity(%p) called (%ld)\n", This, bDiscontinuity); ((CMediaSample*) This)->isDiscontinuity = bDiscontinuity; return 0; } static HRESULT STDCALL CMediaSample_GetMediaTime(IMediaSample * This, /* [out] */ LONGLONG *pTimeStart, /* [out] */ LONGLONG *pTimeEnd) { Debug printf("CMediaSample_GetMediaTime(%p) called\n", This); if (pTimeStart) *pTimeStart = ((CMediaSample*) This)->time_start; if (pTimeEnd) *pTimeEnd = ((CMediaSample*) This)->time_end; return 0; } static HRESULT STDCALL CMediaSample_SetMediaTime(IMediaSample * This, /* [in] */ LONGLONG *pTimeStart, /* [in] */ LONGLONG *pTimeEnd) { Debug printf("CMediaSample_SetMediaTime(%p) called\n", This); if (pTimeStart) ((CMediaSample*) This)->time_start = *pTimeStart; if (pTimeEnd) ((CMediaSample*) This)->time_end = *pTimeEnd; return 0; } // extension for direct memory write or decompressed data static void CMediaSample_SetPointer(CMediaSample* This, char* pointer) { Debug printf("CMediaSample_SetPointer(%p) called -> %p\n", This, pointer); if (pointer) This->block = pointer; else This->block = This->own_block; } static void CMediaSample_ResetPointer(CMediaSample* This) { Debug printf("CMediaSample_ResetPointer(%p) called\n", This); This->block = This->own_block; } CMediaSample* CMediaSampleCreate(IMemAllocator* allocator, int _size) { CMediaSample* This = (CMediaSample*) malloc(sizeof(CMediaSample)); if (!This) return NULL; // some hack here! // it looks like Acelp decoder is actually accessing // the allocated memory before it sets the new size for it ??? // -- maybe it's being initialized with wrong parameters // anyway this is fixes the problem somehow with some reserves // // using different trick for now - in DS_Audio modify sample size //if (_size < 0x1000) // _size = (_size + 0xfff) & ~0xfff; This->vt = (IMediaSample_vt*) malloc(sizeof(IMediaSample_vt)); This->own_block = (char*) malloc((size_t)_size + SAFETY_ACEL); This->media_type.pbFormat = 0; if (!This->vt || !This->own_block) { CMediaSample_Destroy(This); return NULL; } This->vt->QueryInterface = CMediaSample_QueryInterface; This->vt->AddRef = CMediaSample_AddRef; This->vt->Release = CMediaSample_Release; This->vt->GetPointer = CMediaSample_GetPointer; This->vt->GetSize = CMediaSample_GetSize; This->vt->GetTime = CMediaSample_GetTime; This->vt->SetTime = CMediaSample_SetTime; This->vt->IsSyncPoint = CMediaSample_IsSyncPoint; This->vt->SetSyncPoint = CMediaSample_SetSyncPoint; This->vt->IsPreroll = CMediaSample_IsPreroll; This->vt->SetPreroll = CMediaSample_SetPreroll; This->vt->GetActualDataLength = CMediaSample_GetActualDataLength; This->vt->SetActualDataLength = CMediaSample_SetActualDataLength; This->vt->GetMediaType = CMediaSample_GetMediaType; This->vt->SetMediaType = CMediaSample_SetMediaType; This->vt->IsDiscontinuity = CMediaSample_IsDiscontinuity; This->vt->SetDiscontinuity = CMediaSample_SetDiscontinuity; This->vt->GetMediaTime = CMediaSample_GetMediaTime; This->vt->SetMediaTime = CMediaSample_SetMediaTime; This->all = allocator; This->size = _size; This->refcount = 0; // increased by MemAllocator This->actual_size = 0; This->isPreroll = 0; This->isDiscontinuity = 1; This->time_start = 0; This->time_end = 0; This->type_valid = 0; This->block = This->own_block; This->SetPointer = CMediaSample_SetPointer; This->ResetPointer = CMediaSample_ResetPointer; Debug printf("CMediaSample_Create(%p) called - sample size %d, buffer %p\n", This, This->size, This->block); return This; } ���������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/interfaces.h��������������������������������������������������0000644�0001750�0001750�00000030703�14647725152�017623� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_INTERFACES_H #define DS_INTERFACES_H /* * Definition of important DirectShow interfaces. * Created using freely-available DirectX 8.0 SDK * ( http://msdn.microsoft.com ) */ #include "iunk.h" #include "com.h" /* Sh*t. MSVC++ and g++ use different methods of storing vtables. */ typedef struct _IReferenceClock IReferenceClock; typedef struct _IFilterGraph IFilterGraph; typedef struct _IBaseFilter IBaseFilter; typedef enum { PINDIR_INPUT = 0, PINDIR_OUTPUT } PIN_DIRECTION; typedef struct _PinInfo { IBaseFilter* pFilter; PIN_DIRECTION dir; unsigned short achName[128]; } PIN_INFO; typedef struct _AllocatorProperties { long cBuffers; long cbBuffer; long cbAlign; long cbPrefix; } ALLOCATOR_PROPERTIES; typedef struct _IEnumMediaTypes IEnumMediaTypes; typedef struct IEnumMediaTypes_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *Next )(IEnumMediaTypes* This, /* [in] */ unsigned long cMediaTypes, /* [size_is][out] */ AM_MEDIA_TYPE** ppMediaTypes, /* [out] */ unsigned long* pcFetched); HRESULT STDCALL ( *Skip )(IEnumMediaTypes* This, /* [in] */ unsigned long cMediaTypes); HRESULT STDCALL ( *Reset )(IEnumMediaTypes* This); HRESULT STDCALL ( *Clone )(IEnumMediaTypes* This, /* [out] */ IEnumMediaTypes** ppEnum); } IEnumMediaTypes_vt; struct _IEnumMediaTypes { IEnumMediaTypes_vt* vt; }; typedef struct _IPin IPin; typedef struct IPin_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *Connect )(IPin * This, /* [in] */ IPin *pReceivePin, /* [in] */ /*const*/ AM_MEDIA_TYPE *pmt); HRESULT STDCALL ( *ReceiveConnection )(IPin * This, /* [in] */ IPin *pConnector, /* [in] */ const AM_MEDIA_TYPE *pmt); HRESULT STDCALL ( *Disconnect )(IPin * This); HRESULT STDCALL ( *ConnectedTo )(IPin * This, /* [out] */ IPin **pPin); HRESULT STDCALL ( *ConnectionMediaType )(IPin * This, /* [out] */ AM_MEDIA_TYPE *pmt); HRESULT STDCALL ( *QueryPinInfo )(IPin * This, /* [out] */ PIN_INFO *pInfo); HRESULT STDCALL ( *QueryDirection )(IPin * This, /* [out] */ PIN_DIRECTION *pPinDir); HRESULT STDCALL ( *QueryId )(IPin * This, /* [out] */ unsigned short* *Id); HRESULT STDCALL ( *QueryAccept )(IPin * This, /* [in] */ const AM_MEDIA_TYPE *pmt); HRESULT STDCALL ( *EnumMediaTypes )(IPin * This, /* [out] */ IEnumMediaTypes **ppEnum); HRESULT STDCALL ( *QueryInternalConnections )(IPin * This, /* [out] */ IPin **apPin, /* [out][in] */ unsigned long *nPin); HRESULT STDCALL ( *EndOfStream )(IPin * This); HRESULT STDCALL ( *BeginFlush )(IPin * This); HRESULT STDCALL ( *EndFlush )(IPin * This); HRESULT STDCALL ( *NewSegment )(IPin * This, /* [in] */ REFERENCE_TIME tStart, /* [in] */ REFERENCE_TIME tStop, /* [in] */ double dRate); } IPin_vt; struct _IPin { IPin_vt *vt; }; typedef struct _IEnumPins IEnumPins; typedef struct IEnumPins_vt { INHERIT_IUNKNOWN(); // retrieves a specified number of pins in the enumeration sequence.. HRESULT STDCALL ( *Next )(IEnumPins* This, /* [in] */ unsigned long cPins, /* [size_is][out] */ IPin** ppPins, /* [out] */ unsigned long* pcFetched); // skips over a specified number of pins. HRESULT STDCALL ( *Skip )(IEnumPins* This, /* [in] */ unsigned long cPins); // resets the enumeration sequence to the beginning. HRESULT STDCALL ( *Reset )(IEnumPins* This); // makes a copy of the enumerator with the same enumeration state. HRESULT STDCALL ( *Clone )(IEnumPins* This, /* [out] */ IEnumPins** ppEnum); } IEnumPins_vt; struct _IEnumPins { struct IEnumPins_vt* vt; }; typedef struct _IMediaSample IMediaSample; typedef struct IMediaSample_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *GetPointer )(IMediaSample* This, /* [out] */ unsigned char** ppBuffer); LONG STDCALL ( *GetSize )(IMediaSample* This); HRESULT STDCALL ( *GetTime )(IMediaSample* This, /* [out] */ REFERENCE_TIME* pTimeStart, /* [out] */ REFERENCE_TIME* pTimeEnd); HRESULT STDCALL ( *SetTime )(IMediaSample* This, /* [in] */ REFERENCE_TIME* pTimeStart, /* [in] */ REFERENCE_TIME* pTimeEnd); // sync-point property. If true, then the beginning of this // sample is a sync-point. (note that if AM_MEDIA_TYPE.bTemporalCompression // is false then all samples are sync points). A filter can start // a stream at any sync point. S_FALSE if not sync-point, S_OK if true. HRESULT STDCALL ( *IsSyncPoint )(IMediaSample* This); HRESULT STDCALL ( *SetSyncPoint )(IMediaSample* This, long bIsSyncPoint); // preroll property. If true, this sample is for preroll only and // shouldn't be displayed. HRESULT STDCALL ( *IsPreroll )(IMediaSample* This); HRESULT STDCALL ( *SetPreroll )(IMediaSample* This, long bIsPreroll); LONG STDCALL ( *GetActualDataLength )(IMediaSample* This); HRESULT STDCALL ( *SetActualDataLength )(IMediaSample* This, long __MIDL_0010); // these allow for limited format changes in band - if no format change // has been made when you receive a sample GetMediaType will return S_FALSE HRESULT STDCALL ( *GetMediaType )(IMediaSample* This, AM_MEDIA_TYPE** ppMediaType); HRESULT STDCALL ( *SetMediaType )(IMediaSample* This, AM_MEDIA_TYPE* pMediaType); // returns S_OK if there is a discontinuity in the data (this frame is // not a continuation of the previous stream of data // - there has been a seek or some dropped samples). HRESULT STDCALL ( *IsDiscontinuity )(IMediaSample* This); HRESULT STDCALL ( *SetDiscontinuity )(IMediaSample* This, long bDiscontinuity); // get the media times for this sample HRESULT STDCALL ( *GetMediaTime )(IMediaSample* This, /* [out] */ long long* pTimeStart, /* [out] */ long long* pTimeEnd); // Set the media times for this sample // pTimeStart==pTimeEnd==NULL will invalidate the media time stamps in // this sample HRESULT STDCALL ( *SetMediaTime )(IMediaSample* This, /* [in] */ long long* pTimeStart, /* [in] */ long long* pTimeEnd); } IMediaSample_vt; struct _IMediaSample { struct IMediaSample_vt* vt; }; //typedef struct _IBaseFilter IBaseFilter; typedef struct IBaseFilter_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *GetClassID )(IBaseFilter * This, /* [out] */ CLSID *pClassID); HRESULT STDCALL ( *Stop )(IBaseFilter * This); HRESULT STDCALL ( *Pause )(IBaseFilter * This); HRESULT STDCALL ( *Run )(IBaseFilter * This, REFERENCE_TIME tStart); HRESULT STDCALL ( *GetState )(IBaseFilter * This, /* [in] */ unsigned long dwMilliSecsTimeout, ///* [out] */ FILTER_STATE *State); void* State); HRESULT STDCALL ( *SetSyncSource )(IBaseFilter* This, /* [in] */ IReferenceClock *pClock); HRESULT STDCALL ( *GetSyncSource )(IBaseFilter* This, /* [out] */ IReferenceClock **pClock); HRESULT STDCALL ( *EnumPins )(IBaseFilter* This, /* [out] */ IEnumPins **ppEnum); HRESULT STDCALL ( *FindPin )(IBaseFilter* This, /* [string][in] */ const unsigned short* Id, /* [out] */ IPin** ppPin); HRESULT STDCALL ( *QueryFilterInfo )(IBaseFilter* This, // /* [out] */ FILTER_INFO *pInfo); void* pInfo); HRESULT STDCALL ( *JoinFilterGraph )(IBaseFilter* This, /* [in] */ IFilterGraph* pGraph, /* [string][in] */ const unsigned short* pName); HRESULT STDCALL ( *QueryVendorInfo )(IBaseFilter* This, /* [string][out] */ unsigned short** pVendorInfo); } IBaseFilter_vt; struct _IBaseFilter { struct IBaseFilter_vt* vt; }; typedef struct _IMemAllocator IMemAllocator; typedef struct IMemAllocator_vt { INHERIT_IUNKNOWN(); // specifies the number of buffers to allocate and the size of each buffer. HRESULT STDCALL ( *SetProperties )(IMemAllocator* This, /* [in] */ ALLOCATOR_PROPERTIES *pRequest, /* [out] */ ALLOCATOR_PROPERTIES *pActual); // retrieves the number of buffers that the allocator will create, and the buffer properties. HRESULT STDCALL ( *GetProperties )(IMemAllocator* This, /* [out] */ ALLOCATOR_PROPERTIES *pProps); // allocates the buffer memory. HRESULT STDCALL ( *Commit )(IMemAllocator* This); // releases the memory for the buffers. HRESULT STDCALL ( *Decommit )(IMemAllocator* This); // retrieves a media sample that contains an empty buffer. HRESULT STDCALL ( *GetBuffer )(IMemAllocator* This, /* [out] */ IMediaSample** ppBuffer, /* [in] */ REFERENCE_TIME* pStartTime, /* [in] */ REFERENCE_TIME* pEndTime, /* [in] */ unsigned long dwFlags); // releases a media sample. HRESULT STDCALL ( *ReleaseBuffer )(IMemAllocator* This, /* [in] */ IMediaSample* pBuffer); } IMemAllocator_vt; struct _IMemAllocator { IMemAllocator_vt* vt; }; typedef struct _IMemInputPin IMemInputPin; typedef struct IMemInputPin_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *GetAllocator )(IMemInputPin * This, /* [out] */ IMemAllocator **ppAllocator); HRESULT STDCALL ( *NotifyAllocator )(IMemInputPin * This, /* [in] */ IMemAllocator *pAllocator, /* [in] */ int bReadOnly); HRESULT STDCALL ( *GetAllocatorRequirements )(IMemInputPin * This, /* [out] */ ALLOCATOR_PROPERTIES *pProps); HRESULT STDCALL ( *Receive )(IMemInputPin * This, /* [in] */ IMediaSample *pSample); HRESULT STDCALL ( *ReceiveMultiple )(IMemInputPin * This, /* [size_is][in] */ IMediaSample **pSamples, /* [in] */ long nSamples, /* [out] */ long *nSamplesProcessed); HRESULT STDCALL ( *ReceiveCanBlock )(IMemInputPin * This); } IMemInputPin_vt; struct _IMemInputPin { IMemInputPin_vt* vt; }; typedef struct _IHidden IHidden; typedef struct IHidden_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *GetSmth )(IHidden* This, int* pv); HRESULT STDCALL ( *SetSmth )(IHidden* This, int v1, int v2); HRESULT STDCALL ( *GetSmth2 )(IHidden* This, int* pv); HRESULT STDCALL ( *SetSmth2 )(IHidden* This, int v1, int v2); HRESULT STDCALL ( *GetSmth3 )(IHidden* This, int* pv); HRESULT STDCALL ( *SetSmth3 )(IHidden* This, int v1, int v2); HRESULT STDCALL ( *GetSmth4 )(IHidden* This, int* pv); HRESULT STDCALL ( *SetSmth4 )(IHidden* This, int v1, int v2); HRESULT STDCALL ( *GetSmth5 )(IHidden* This, int* pv); HRESULT STDCALL ( *SetSmth5 )(IHidden* This, int v1, int v2); HRESULT STDCALL ( *GetSmth6 )(IHidden* This, int* pv); } IHidden_vt; struct _IHidden { struct IHidden_vt* vt; }; typedef struct _IHidden2 IHidden2; typedef struct IHidden2_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *unk1 )(void); HRESULT STDCALL ( *unk2 )(void); HRESULT STDCALL ( *unk3 )(void); HRESULT STDCALL ( *DecodeGet )(IHidden2* This, int* region); HRESULT STDCALL ( *unk5 )(void); HRESULT STDCALL ( *DecodeSet )(IHidden2* This, int* region); HRESULT STDCALL ( *unk7 )(void); HRESULT STDCALL ( *unk8 )(void); } IHidden2_vt; struct _IHidden2 { struct IHidden2_vt* vt; }; // fixme typedef struct IDivxFilterInterface { struct IDivxFilterInterface_vt* vt; } IDivxFilterInterface; struct IDivxFilterInterface_vt { INHERIT_IUNKNOWN(); HRESULT STDCALL ( *get_PPLevel )(IDivxFilterInterface* This, int* PPLevel); // current postprocessing level HRESULT STDCALL ( *put_PPLevel )(IDivxFilterInterface* This, int PPLevel); // new postprocessing level HRESULT STDCALL ( *put_DefaultPPLevel )(IDivxFilterInterface* This); HRESULT STDCALL ( *put_MaxDelayAllowed )(IDivxFilterInterface* This, int maxdelayallowed); HRESULT STDCALL ( *put_Brightness )(IDivxFilterInterface* This, int brightness); HRESULT STDCALL ( *put_Contrast )(IDivxFilterInterface* This, int contrast); HRESULT STDCALL ( *put_Saturation )(IDivxFilterInterface* This, int saturation); HRESULT STDCALL ( *get_MaxDelayAllowed )(IDivxFilterInterface* This, int* maxdelayallowed); HRESULT STDCALL ( *get_Brightness)(IDivxFilterInterface* This, int* brightness); HRESULT STDCALL ( *get_Contrast)(IDivxFilterInterface* This, int* contrast); HRESULT STDCALL ( *get_Saturation )(IDivxFilterInterface* This, int* saturation); HRESULT STDCALL ( *put_AspectRatio )(IDivxFilterInterface* This, int x, IDivxFilterInterface* Thisit, int y); HRESULT STDCALL ( *get_AspectRatio )(IDivxFilterInterface* This, int* x, IDivxFilterInterface* Thisit, int* y); }; #endif /* DS_INTERFACES_H */ �������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/DS_Filter.c���������������������������������������������������0000644�0001750�0001750�00000014657�14647725152�017320� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "DS_Filter.h" #include "driver.h" #include "com.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include "win32.h" // printf macro typedef long STDCALL (*GETCLASS) (const GUID*, const GUID*, void**); //void trapbug(); static void DS_Filter_Start(DS_Filter* This) { HRESULT hr; if (This->m_pAll) return; //Debug printf("DS_Filter_Start(%p)\n", This); hr = This->m_pFilter->vt->Run(This->m_pFilter, (REFERENCE_TIME)0); if (hr != 0) { Debug printf("WARNING: m_Filter->Run() failed, error code %x\n", (int)hr); } hr = This->m_pImp->vt->GetAllocator(This->m_pImp, &This->m_pAll); if (hr || !This->m_pAll) { Debug printf("WARNING: error getting IMemAllocator interface %x\n", (int)hr); This->m_pImp->vt->Release((IUnknown*)This->m_pImp); return; } This->m_pImp->vt->NotifyAllocator(This->m_pImp, This->m_pAll, 0); } static void DS_Filter_Stop(DS_Filter* This) { if (This->m_pAll) { //Debug printf("DS_Filter_Stop(%p)\n", This); This->m_pFilter->vt->Stop(This->m_pFilter); // causes weird crash ??? FIXME This->m_pAll->vt->Release((IUnknown*)This->m_pAll); This->m_pAll = 0; } } void DS_Filter_Destroy(DS_Filter* This) { This->Stop(This); if (This->m_pOurInput) This->m_pOurInput->vt->Release((IUnknown*)This->m_pOurInput); if (This->m_pInputPin) This->m_pInputPin->vt->Disconnect(This->m_pInputPin); if (This->m_pOutputPin) This->m_pOutputPin->vt->Disconnect(This->m_pOutputPin); if (This->m_pFilter) This->m_pFilter->vt->Release((IUnknown*)This->m_pFilter); if (This->m_pOutputPin) This->m_pOutputPin->vt->Release((IUnknown*)This->m_pOutputPin); if (This->m_pInputPin) This->m_pInputPin->vt->Release((IUnknown*)This->m_pInputPin); if (This->m_pImp) This->m_pImp->vt->Release((IUnknown*)This->m_pImp); if (This->m_pOurOutput) This->m_pOurOutput->vt->Release((IUnknown*)This->m_pOurOutput); if (This->m_pParentFilter) This->m_pParentFilter->vt->Release((IUnknown*)This->m_pParentFilter); if (This->m_pSrcFilter) This->m_pSrcFilter->vt->Release((IUnknown*)This->m_pSrcFilter); // FIXME - we are still leaving few things allocated! if (This->m_iHandle) FreeLibrary((unsigned)This->m_iHandle); free(This); CodecRelease(); } DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt) { HRESULT result = 0; int init = 0; /* char eb[250]; -- unused */ const char* em = NULL; DS_Filter* This = (DS_Filter*) malloc(sizeof(DS_Filter)); if (!This) return NULL; CodecAlloc(); This->m_pFilter = NULL; This->m_pInputPin = NULL; This->m_pOutputPin = NULL; This->m_pSrcFilter = NULL; This->m_pParentFilter = NULL; This->m_pOurInput = NULL; This->m_pOurOutput = NULL; This->m_pAll = NULL; This->m_pImp = NULL; This->Start = DS_Filter_Start; This->Stop = DS_Filter_Stop; for (;;) { GETCLASS func; struct IClassFactory* factory = NULL; struct IUnknown* object = NULL; IEnumPins* enum_pins = 0; IPin* array[256]; ULONG fetched; unsigned int i; This->m_iHandle = LoadLibraryA(dllname); if (!This->m_iHandle) { em = "could not open DirectShow DLL"; break; } func = (GETCLASS)GetProcAddress((unsigned)This->m_iHandle, "DllGetClassObject"); if (!func) { em = "illegal or corrupt DirectShow DLL"; break; } result = func(id, &IID_IClassFactory, (void**)&factory); if (result || !factory) { em = "no such class object"; break; } result = factory->vt->CreateInstance(factory, 0, &IID_IUnknown, (void**)&object); factory->vt->Release((IUnknown*)factory); if (result || !object) { em = "class factory failure"; break; } result = object->vt->QueryInterface(object, &IID_IBaseFilter, (void**)&This->m_pFilter); object->vt->Release((IUnknown*)object); if (result || !This->m_pFilter) { em = "object does not provide IBaseFilter interface"; break; } // enumerate pins result = This->m_pFilter->vt->EnumPins(This->m_pFilter, &enum_pins); if (result || !enum_pins) { em = "could not enumerate pins"; break; } enum_pins->vt->Reset(enum_pins); result = enum_pins->vt->Next(enum_pins, (ULONG)256, (IPin**)array, &fetched); Debug printf("Pins enumeration returned %ld pins, error is %x\n", fetched, (int)result); for (i = 0; i < fetched; i++) { int direction = -1; array[i]->vt->QueryDirection(array[i], (PIN_DIRECTION*)&direction); if (!This->m_pInputPin && direction == 0) { This->m_pInputPin = array[i]; This->m_pInputPin->vt->AddRef((IUnknown*)This->m_pInputPin); } if (!This->m_pOutputPin && direction == 1) { This->m_pOutputPin = array[i]; This->m_pOutputPin->vt->AddRef((IUnknown*)This->m_pOutputPin); } array[i]->vt->Release((IUnknown*)(array[i])); } if (!This->m_pInputPin) { em = "could not find input pin"; break; } if (!This->m_pOutputPin) { em = "could not find output pin"; break; } result = This->m_pInputPin->vt->QueryInterface((IUnknown*)This->m_pInputPin, &IID_IMemInputPin, (void**)&This->m_pImp); if (result) { em = "could not get IMemInputPin interface"; break; } This->m_pOurType = in_fmt; This->m_pDestType = out_fmt; result = This->m_pInputPin->vt->QueryAccept(This->m_pInputPin, This->m_pOurType); if (result) { em = "source format is not accepted"; break; } This->m_pParentFilter = CBaseFilter2Create(); This->m_pSrcFilter = CBaseFilterCreate(This->m_pOurType, This->m_pParentFilter); This->m_pOurInput = This->m_pSrcFilter->GetPin(This->m_pSrcFilter); This->m_pOurInput->vt->AddRef((IUnknown*)This->m_pOurInput); result = This->m_pInputPin->vt->ReceiveConnection(This->m_pInputPin, This->m_pOurInput, This->m_pOurType); if (result) { em = "could not connect to input pin"; break; } This->m_pOurOutput = COutputPinCreate(This->m_pDestType); result = This->m_pOutputPin->vt->ReceiveConnection(This->m_pOutputPin, (IPin*) This->m_pOurOutput, This->m_pDestType); if (result) { em = "could not connect to output pin"; break; } printf("Using DirectShow codec: %s\n", dllname); init++; break; } if (!init) { DS_Filter_Destroy(This); printf("Warning: DS_Filter() %s. (DLL=%.200s, r=0x%x)\n", em, dllname, (unsigned)result); This = 0; } return This; } ���������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/outputpin.h���������������������������������������������������0000644�0001750�0001750�00000001233�14647725152�017543� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_OUTPUTPIN_H #define DS_OUTPUTPIN_H /* "output pin" - the one that connects to output of filter. */ #include "allocator.h" typedef struct _COutputMemPin COutputMemPin; typedef struct _COutputPin COutputPin; struct _COutputPin { IPin_vt* vt; DECLARE_IUNKNOWN(); COutputMemPin* mempin; AM_MEDIA_TYPE type; IPin* remote; void ( *SetFramePointer )(COutputPin*, char** z); void ( *SetPointer2 )(COutputPin*, char* p); void ( *SetFrameSizePointer )(COutputPin*, long* z); void ( *SetNewFormat )(COutputPin*, const AM_MEDIA_TYPE* a); }; COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* vhdr); #endif /* DS_OUTPUTPIN_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/DS_Filter.h���������������������������������������������������0000644�0001750�0001750�00000001577�14647725152�017322� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_FILTER_H #define DS_FILTER_H #include "inputpin.h" #include "outputpin.h" #if defined(__cplusplus) extern "C" { #endif /** User will allocate and fill format structures, call Create(), and then set up m_pAll. **/ typedef struct _DS_Filter DS_Filter; struct _DS_Filter { int m_iHandle; IBaseFilter* m_pFilter; IPin* m_pInputPin; IPin* m_pOutputPin; CBaseFilter* m_pSrcFilter; CBaseFilter2* m_pParentFilter; IPin* m_pOurInput; COutputPin* m_pOurOutput; AM_MEDIA_TYPE *m_pOurType, *m_pDestType; IMemAllocator* m_pAll; IMemInputPin* m_pImp; void ( *Start )(DS_Filter*); void ( *Stop )(DS_Filter*); }; DS_Filter* DS_FilterCreate(const char* dllname, const GUID* id, AM_MEDIA_TYPE* in_fmt, AM_MEDIA_TYPE* out_fmt); void DS_Filter_Destroy(DS_Filter* This); #if defined(__cplusplus) } #endif #endif /* DS_FILTER_H */ ���������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/DS_VideoDecoder.c���������������������������������������������0000644�0001750�0001750�00000064244�14647725152�020424� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/******************************************************** DirectShow Video decoder implementation Copyright 2000 Eugene Kuznetsov (divx@euro.ru) *********************************************************/ #include "guids.h" #include "interfaces.h" #ifndef NOAVIFILE_HEADERS #include "videodecoder.h" #else #include "libwin32.h" #endif #include "DS_Filter.h" struct _DS_VideoDecoder { IVideoDecoder iv; DS_Filter* m_pDS_Filter; AM_MEDIA_TYPE m_sOurType, m_sDestType; VIDEOINFOHEADER* m_sVhdr; VIDEOINFOHEADER* m_sVhdr2; int m_Caps;//CAPS m_Caps; // capabilities of DirectShow decoder int m_iLastQuality; // remember last quality as integer int m_iMinBuffers; int m_iMaxAuto; int m_bIsDivX; // for speed int m_bIsDivX4; // for speed }; #include "DS_VideoDecoder.h" #include "../wine/winerror.h" #ifndef NOAVIFILE_HEADERS #define VFW_E_NOT_RUNNING 0x80040226 #include "fourcc.h" #include "except.h" #endif #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <sys/types.h> #include <sys/mman.h> #include <stdio.h> #include <stdlib.h> // labs // strcmp((const char*)info.dll,...) is used instead of (... == ...) // so Arpi could use char* pointer in his simplified DS_VideoDecoder class #define __MODULE__ "DirectShow_VideoDecoder" #define false 0 #define true 1 int DS_VideoDecoder_GetCapabilities(DS_VideoDecoder *this) {return this->m_Caps;} typedef struct _ct ct; struct _ct { unsigned int bits; fourcc_t fcc; const GUID *subtype; int cap; }; static ct check[] = { {16, fccYUY2, &MEDIASUBTYPE_YUY2, CAP_YUY2}, {12, fccIYUV, &MEDIASUBTYPE_IYUV, CAP_IYUV}, {16, fccUYVY, &MEDIASUBTYPE_UYVY, CAP_UYVY}, {12, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12}, //{16, fccYV12, &MEDIASUBTYPE_YV12, CAP_YV12}, {16, fccYVYU, &MEDIASUBTYPE_YVYU, CAP_YVYU}, {12, fccI420, &MEDIASUBTYPE_I420, CAP_I420}, {9, fccYVU9, &MEDIASUBTYPE_YVU9, CAP_YVU9}, {0, 0, NULL, 0} }; DS_VideoDecoder * DS_VideoDecoder_Open(const char* dllname, GUID* guid, BITMAPINFOHEADER * format, int flip, int maxauto) { DS_VideoDecoder *this; HRESULT result; ct* c; this = malloc(sizeof(DS_VideoDecoder)); memset( this, 0, sizeof(DS_VideoDecoder)); this->m_sVhdr2 = 0; this->m_iLastQuality = -1; this->m_iMaxAuto = maxauto; #ifdef LDT_paranoia Setup_LDT_Keeper(); #endif //memset(&m_obh, 0, sizeof(m_obh)); //m_obh.biSize = sizeof(m_obh); /*try*/ { unsigned int bihs; bihs = (format->biSize < (int) sizeof(BITMAPINFOHEADER)) ? (int)sizeof(BITMAPINFOHEADER) : format->biSize; this->iv.m_bh = (BITMAPINFOHEADER*)malloc(bihs); memcpy(this->iv.m_bh, format, bihs); this->iv.m_bh->biSize = bihs; this->iv.m_State = STOP; //this->iv.m_pFrame = 0; this->iv.m_Mode = DIRECT; this->iv.m_iDecpos = 0; this->iv.m_iPlaypos = -1; this->iv.m_fQuality = 0.0f; this->iv.m_bCapable16b = true; bihs += sizeof(VIDEOINFOHEADER) - sizeof(BITMAPINFOHEADER); this->m_sVhdr = (VIDEOINFOHEADER*)malloc(bihs); memset(this->m_sVhdr, 0, bihs); memcpy(&this->m_sVhdr->bmiHeader, this->iv.m_bh, this->iv.m_bh->biSize); this->m_sVhdr->rcSource.left = this->m_sVhdr->rcSource.top = 0; this->m_sVhdr->rcSource.right = this->m_sVhdr->bmiHeader.biWidth; this->m_sVhdr->rcSource.bottom = this->m_sVhdr->bmiHeader.biHeight; //this->m_sVhdr->rcSource.right = 0; //this->m_sVhdr->rcSource.bottom = 0; this->m_sVhdr->rcTarget = this->m_sVhdr->rcSource; this->m_sOurType.majortype = MEDIATYPE_Video; this->m_sOurType.subtype = MEDIATYPE_Video; this->m_sOurType.subtype.f1 = this->m_sVhdr->bmiHeader.biCompression; this->m_sOurType.formattype = FORMAT_VideoInfo; this->m_sOurType.bFixedSizeSamples = false; this->m_sOurType.bTemporalCompression = true; this->m_sOurType.pUnk = 0; this->m_sOurType.cbFormat = bihs; this->m_sOurType.pbFormat = (char*)this->m_sVhdr; this->m_sVhdr2 = (VIDEOINFOHEADER*)(malloc(sizeof(VIDEOINFOHEADER)+12)); memcpy(this->m_sVhdr2, this->m_sVhdr, sizeof(VIDEOINFOHEADER)); memset((char*)this->m_sVhdr2 + sizeof(VIDEOINFOHEADER), 0, 12); this->m_sVhdr2->bmiHeader.biCompression = 0; this->m_sVhdr2->bmiHeader.biBitCount = 24; memset(&this->m_sDestType, 0, sizeof(this->m_sDestType)); this->m_sDestType.majortype = MEDIATYPE_Video; this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; this->m_sDestType.formattype = FORMAT_VideoInfo; this->m_sDestType.bFixedSizeSamples = true; this->m_sDestType.bTemporalCompression = false; this->m_sDestType.lSampleSize = labs(this->m_sVhdr2->bmiHeader.biWidth*this->m_sVhdr2->bmiHeader.biHeight * ((this->m_sVhdr2->bmiHeader.biBitCount + 7) / 8)); this->m_sVhdr2->bmiHeader.biSizeImage = this->m_sDestType.lSampleSize; this->m_sDestType.pUnk = 0; this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); this->m_sDestType.pbFormat = (char*)this->m_sVhdr2; memset(&this->iv.m_obh, 0, sizeof(this->iv.m_obh)); memcpy(&this->iv.m_obh, this->iv.m_bh, sizeof(this->iv.m_obh) < (unsigned) this->iv.m_bh->biSize ? sizeof(this->iv.m_obh) : (unsigned) this->iv.m_bh->biSize); this->iv.m_obh.biBitCount=24; this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression = 0; //BI_RGB //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) * ((this->iv.m_obh.biBitCount + 7) / 8); this->m_pDS_Filter = DS_FilterCreate(dllname, guid, &this->m_sOurType, &this->m_sDestType); if (!this->m_pDS_Filter) { printf("Failed to create DirectShow filter\n"); free(this->m_sVhdr); free(this->m_sVhdr2); free(this); return 0; } if (!flip) { this->iv.m_obh.biHeight *= -1; this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType); if (result) { printf("Decoder does not support upside-down RGB frames\n"); this->iv.m_obh.biHeight *= -1; this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; } } memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh) ); switch (this->iv.m_bh->biCompression) { #if 0 case fccDIV3: case fccDIV4: case fccDIV5: case fccDIV6: case fccMP42: case fccWMV2: //YV12 seems to be broken for DivX :-) codec // case fccIV50: //produces incorrect picture //m_Caps = (CAPS) (m_Caps & ~CAP_YV12); //m_Caps = CAP_UYVY;//CAP_YUY2; // | CAP_I420; //m_Caps = CAP_I420; this->m_Caps = (CAP_YUY2 | CAP_UYVY); break; #endif default: this->m_Caps = CAP_NONE; printf("Decoder supports the following YUV formats: "); for (c = check; c->bits; c++) { this->m_sVhdr2->bmiHeader.biBitCount = c->bits; this->m_sVhdr2->bmiHeader.biCompression = c->fcc; this->m_sDestType.subtype = *c->subtype; result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType); if (!result) { this->m_Caps = (this->m_Caps | c->cap); printf("%.4s ", (char *)&c->fcc); } } printf("\n"); } if (this->m_Caps != CAP_NONE) printf("Decoder is capable of YUV output (flags 0x%x)\n", (int)this->m_Caps); this->m_sVhdr2->bmiHeader.biBitCount = 24; this->m_sVhdr2->bmiHeader.biCompression = 0; this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; this->m_iMinBuffers = this->iv.VBUFSIZE; this->m_bIsDivX = (strcmp(dllname, "divxcvki.ax") == 0 || strcmp(dllname, "divx_c32.ax") == 0 || strcmp(dllname, "wmvds32.ax") == 0 || strcmp(dllname, "wmv8ds32.ax") == 0); this->m_bIsDivX4 = (strcmp(dllname, "divxdec.ax") == 0); if (this->m_bIsDivX) this->iv.VBUFSIZE += 7; else if (this->m_bIsDivX4) this->iv.VBUFSIZE += 9; } /*catch (FatalError& error) { delete[] m_sVhdr; delete[] m_sVhdr2; delete m_pDS_Filter; throw; }*/ return this; } void DS_VideoDecoder_Destroy(DS_VideoDecoder *this) { DS_VideoDecoder_StopInternal(this); this->iv.m_State = STOP; free(this->m_sVhdr); free(this->m_sVhdr2); DS_Filter_Destroy(this->m_pDS_Filter); } void DS_VideoDecoder_StartInternal(DS_VideoDecoder *this) { ALLOCATOR_PROPERTIES props, props1; Debug printf("DS_VideoDecoder_StartInternal\n"); //cout << "DSSTART" << endl; this->m_pDS_Filter->Start(this->m_pDS_Filter); props.cBuffers = 1; props.cbBuffer = this->m_sDestType.lSampleSize; //don't know how to do this correctly props.cbAlign = props.cbPrefix = 0; this->m_pDS_Filter->m_pAll->vt->SetProperties(this->m_pDS_Filter->m_pAll, &props, &props1); this->m_pDS_Filter->m_pAll->vt->Commit(this->m_pDS_Filter->m_pAll); this->iv.m_State = START; } void DS_VideoDecoder_StopInternal(DS_VideoDecoder *this) { this->m_pDS_Filter->Stop(this->m_pDS_Filter); //??? why was this here ??? m_pOurOutput->SetFramePointer(0); } int DS_VideoDecoder_DecodeInternal(DS_VideoDecoder *this, const void* src, int size, int is_keyframe, char* pImage) { IMediaSample* sample = 0; char* ptr; int result; Debug printf("DS_VideoDecoder_DecodeInternal(%p,%p,%d,%d,%p)\n",this,src,size,is_keyframe,pImage); this->m_pDS_Filter->m_pAll->vt->GetBuffer(this->m_pDS_Filter->m_pAll, &sample, 0, 0, 0); if (!sample) { Debug printf("ERROR: null sample\n"); return -1; } //cout << "DECODE " << (void*) pImage << " d: " << (void*) pImage->Data() << endl; if (pImage) { this->m_pDS_Filter->m_pOurOutput->SetPointer2(this->m_pDS_Filter->m_pOurOutput,pImage); } sample->vt->SetActualDataLength(sample, size); sample->vt->GetPointer(sample, (BYTE **)&ptr); memcpy(ptr, src, size); sample->vt->SetSyncPoint(sample, is_keyframe); sample->vt->SetPreroll(sample, pImage ? 0 : 1); // sample->vt->SetMediaType(sample, &m_sOurType); // FIXME: - crashing with YV12 at this place decoder will crash // while doing this call // %FS register was not setup for calling into win32 dll. Are all // crashes inside ...->Receive() fixed now? // // nope - but this is surely helpfull - I'll try some more experiments #ifdef LDT_paranoia Setup_FS_Segment(); #endif #if 0 if (!this->m_pDS_Filter || !this->m_pDS_Filter->m_pImp || !this->m_pDS_Filter->m_pImp->vt || !this->m_pDS_Filter->m_pImp->vt->Receive) printf("DecodeInternal ERROR???\n"); #endif result = this->m_pDS_Filter->m_pImp->vt->Receive(this->m_pDS_Filter->m_pImp, sample); if (result) { Debug printf("DS_VideoDecoder::DecodeInternal() error putting data into input pin %x\n", result); } sample->vt->Release((IUnknown*)sample); #if 0 if (this->m_bIsDivX) { int q; IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); // always check for actual value // this seems to be the only way to know the actual value hidden->vt->GetSmth2(hidden, &this->m_iLastQuality); if (this->m_iLastQuality > 9) this->m_iLastQuality -= 10; if (this->m_iLastQuality < 0) this->m_iLastQuality = 0; else if (this->m_iLastQuality > this->m_iMaxAuto) this->m_iLastQuality = this->m_iMaxAuto; //cout << " Qual: " << this->m_iLastQuality << endl; this->iv.m_fQuality = this->m_iLastQuality / 4.0; } else if (this->m_bIsDivX4) { // maybe access methods directly to safe some cpu cycles... DS_VideoDecoder_GetValue(this, "Postprocessing", this->m_iLastQuality); if (this->m_iLastQuality < 0) this->m_iLastQuality = 0; else if (this->m_iLastQuality > this->m_iMaxAuto) this->m_iLastQuality = this->m_iMaxAuto; //cout << " Qual: " << m_iLastQuality << endl; this->iv.m_fQuality = this->m_iLastQuality / 6.0; } if (this->iv.m_Mode == -1 ) // ???BUFFERED_QUALITY_AUTO) { // adjust Quality - depends on how many cached frames we have int buffered = this->iv.m_iDecpos - this->iv.m_iPlaypos; if (this->m_bIsDivX || this->m_bIsDivX4) { int to = buffered - this->m_iMinBuffers; if (to < 0) to = 0; if (to != this->m_iLastQuality) { if (to > this->m_iMaxAuto) to = this->m_iMaxAuto; if (this->m_iLastQuality != to) { if (this->m_bIsDivX) { IHidden* hidden=(IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); hidden->vt->SetSmth(hidden, to, 0); } else DS_VideoDecoder_SetValue(this, "Postprocessing", to); #ifndef QUIET //printf("Switching quality %d -> %d b:%d\n",m_iLastQuality, to, buffered); #endif } } } } #endif return 0; } /* * bits == 0 - leave unchanged */ //int SetDestFmt(DS_VideoDecoder * this, int bits = 24, fourcc_t csp = 0); int DS_VideoDecoder_SetDestFmt(DS_VideoDecoder *this, int bits, unsigned int csp) { HRESULT result; int should_test=1; int stoped = 0; Debug printf("DS_VideoDecoder_SetDestFmt (%p, %d, %d)\n",this,bits,(int)csp); /* if (!CImage::Supported(csp, bits)) return -1; */ // BitmapInfo temp = m_obh; if (!csp) // RGB { int ok = true; switch (bits) { case 15: this->m_sDestType.subtype = MEDIASUBTYPE_RGB555; break; case 16: this->m_sDestType.subtype = MEDIASUBTYPE_RGB565; break; case 24: this->m_sDestType.subtype = MEDIASUBTYPE_RGB24; break; case 32: this->m_sDestType.subtype = MEDIASUBTYPE_RGB32; break; default: ok = false; break; } if (ok) { this->iv.m_obh.biBitCount=bits; if( bits == 15 || bits == 16 ) { this->iv.m_obh.biSize=sizeof(BITMAPINFOHEADER)+12; this->iv.m_obh.biCompression=3;//BI_BITFIELDS this->iv.m_obh.biSizeImage=abs((int)(2*this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)); } if( bits == 16 ) { this->iv.m_obh.colors[0]=0xF800; this->iv.m_obh.colors[1]=0x07E0; this->iv.m_obh.colors[2]=0x001F; } else if ( bits == 15 ) { this->iv.m_obh.colors[0]=0x7C00; this->iv.m_obh.colors[1]=0x03E0; this->iv.m_obh.colors[2]=0x001F; } else { this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression = 0; //BI_RGB //this->iv.m_obh.biHeight = labs(this->iv.m_obh.biHeight); this->iv.m_obh.biSizeImage = labs(this->iv.m_obh.biWidth * this->iv.m_obh.biHeight) * ((this->iv.m_obh.biBitCount + 7) / 8); } } //.biSizeImage=abs(temp.biWidth*temp.biHeight*((temp.biBitCount+7)/8)); } else { // YUV int ok = true; switch (csp) { case fccYUY2: this->m_sDestType.subtype = MEDIASUBTYPE_YUY2; break; case fccYV12: this->m_sDestType.subtype = MEDIASUBTYPE_YV12; break; case fccIYUV: this->m_sDestType.subtype = MEDIASUBTYPE_IYUV; break; case fccI420: this->m_sDestType.subtype = MEDIASUBTYPE_I420; break; case fccUYVY: this->m_sDestType.subtype = MEDIASUBTYPE_UYVY; break; case fccYVYU: this->m_sDestType.subtype = MEDIASUBTYPE_YVYU; break; case fccYVU9: this->m_sDestType.subtype = MEDIASUBTYPE_YVU9; default: ok = false; break; } if (ok) { if (csp != 0 && csp != 3 && this->iv.m_obh.biHeight > 0) this->iv.m_obh.biHeight *= -1; // YUV formats uses should have height < 0 this->iv.m_obh.biSize = sizeof(BITMAPINFOHEADER); this->iv.m_obh.biCompression=csp; this->iv.m_obh.biBitCount=bits; this->iv.m_obh.biSizeImage=labs(this->iv.m_obh.biBitCount* this->iv.m_obh.biWidth*this->iv.m_obh.biHeight)>>3; } } this->m_sDestType.lSampleSize = this->iv.m_obh.biSizeImage; memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_obh, sizeof(this->iv.m_obh)); this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if (this->m_sVhdr2->bmiHeader.biCompression == 3) this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; else this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); switch(csp) { case fccYUY2: if(!(this->m_Caps & CAP_YUY2)) should_test=false; break; case fccYV12: if(!(this->m_Caps & CAP_YV12)) should_test=false; break; case fccIYUV: if(!(this->m_Caps & CAP_IYUV)) should_test=false; break; case fccI420: if(!(this->m_Caps & CAP_I420)) should_test=false; break; case fccUYVY: if(!(this->m_Caps & CAP_UYVY)) should_test=false; break; case fccYVYU: if(!(this->m_Caps & CAP_YVYU)) should_test=false; break; case fccYVU9: if(!(this->m_Caps & CAP_YVU9)) should_test=false; break; } if(should_test) result = this->m_pDS_Filter->m_pOutputPin->vt->QueryAccept(this->m_pDS_Filter->m_pOutputPin, &this->m_sDestType); else result = -1; if (result != 0) { if (csp) printf("Warning: unsupported colour space\n"); else printf("Warning: unsupported bit depth\n"); this->m_sDestType.lSampleSize = this->iv.m_decoder.biSizeImage; memcpy(&(this->m_sVhdr2->bmiHeader), &this->iv.m_decoder, sizeof(this->iv.m_decoder)); this->m_sVhdr2->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); if (this->m_sVhdr2->bmiHeader.biCompression == 3) this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER) + 12; else this->m_sDestType.cbFormat = sizeof(VIDEOINFOHEADER); return -1; } memcpy( &this->iv.m_decoder, &this->iv.m_obh, sizeof(this->iv.m_obh)); // m_obh=temp; // if(csp) // m_obh.biBitCount=BitmapInfo::BitCount(csp); this->iv.m_bh->biBitCount = bits; //DS_VideoDecoder_Restart(this); if (this->iv.m_State == START) { DS_VideoDecoder_StopInternal(this); this->iv.m_State = STOP; stoped = true; } this->m_pDS_Filter->m_pInputPin->vt->Disconnect(this->m_pDS_Filter->m_pInputPin); this->m_pDS_Filter->m_pOutputPin->vt->Disconnect(this->m_pDS_Filter->m_pOutputPin); this->m_pDS_Filter->m_pOurOutput->SetNewFormat(this->m_pDS_Filter->m_pOurOutput,&this->m_sDestType); result = this->m_pDS_Filter->m_pInputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pInputPin, this->m_pDS_Filter->m_pOurInput, &this->m_sOurType); if (result) { printf("Error reconnecting input pin 0x%x\n", (int)result); return -1; } result = this->m_pDS_Filter->m_pOutputPin->vt->ReceiveConnection(this->m_pDS_Filter->m_pOutputPin, (IPin *)this->m_pDS_Filter->m_pOurOutput, &this->m_sDestType); if (result) { printf("Error reconnecting output pin 0x%x\n", (int)result); return -1; } if (stoped) { DS_VideoDecoder_StartInternal(this); this->iv.m_State = START; } return 0; } int DS_VideoDecoder_SetDirection(DS_VideoDecoder *this, int d) { this->iv.m_obh.biHeight = (d) ? this->iv.m_bh->biHeight : -this->iv.m_bh->biHeight; this->m_sVhdr2->bmiHeader.biHeight = this->iv.m_obh.biHeight; return 0; } int DS_VideoDecoder_GetValue(DS_VideoDecoder *this, const char* name, int* value) { #if 0 if (m_bIsDivX4) { IDivxFilterInterface* pIDivx; if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx)) { Debug printf("No such interface\n"); return -1; } if (strcmp(name, "Postprocessing") == 0) { pIDivx->vt->get_PPLevel(pIDivx, &value); value /= 10; } else if (strcmp(name, "Brightness") == 0) pIDivx->vt->get_Brightness(pIDivx, &value); else if (strcmp(name, "Contrast") == 0) pIDivx->vt->get_Contrast(pIDivx, &value); else if (strcmp(name, "Saturation") == 0) pIDivx->vt->get_Saturation(pIDivx, &value); else if (strcmp(name, "MaxAuto") == 0) value = m_iMaxAuto; pIDivx->vt->Release((IUnknown*)pIDivx); return 0; } else if (m_bIsDivX) { if (m_State != START) return VFW_E_NOT_RUNNING; // brightness 87 // contrast 74 // hue 23 // saturation 20 // post process mode 0 // get1 0x01 // get2 10 // get3=set2 86 // get4=set3 73 // get5=set4 19 // get6=set5 23 IHidden* hidden=(IHidden*)((int)m_pDS_Filter->m_pFilter+0xb8); if (strcmp(name, "Quality") == 0) { #warning NOT SURE int r = hidden->vt->GetSmth2(hidden, &value); if (value >= 10) value -= 10; return 0; } if (strcmp(name, "Brightness") == 0) return hidden->vt->GetSmth3(hidden, &value); if (strcmp(name, "Contrast") == 0) return hidden->vt->GetSmth4(hidden, &value); if (strcmp(name, "Hue") == 0) return hidden->vt->GetSmth6(hidden, &value); if (strcmp(name, "Saturation") == 0) return hidden->vt->GetSmth5(hidden, &value); if (strcmp(name, "MaxAuto") == 0) { value = m_iMaxAuto; return 0; } } else if (strcmp((const char*)record.dll, "ir50_32.dll") == 0) { IHidden2* hidden = 0; if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden)) { Debug printf("No such interface\n"); return -1; } #warning FIXME int recordpar[30]; recordpar[0]=0x7c; recordpar[1]=fccIV50; recordpar[2]=0x10005; recordpar[3]=2; recordpar[4]=1; recordpar[5]=0x80000000; if (strcmp(name, "Brightness") == 0) recordpar[5]|=0x20; else if (strcmp(name, "Saturation") == 0) recordpar[5]|=0x40; else if (strcmp(name, "Contrast") == 0) recordpar[5]|=0x80; if (!recordpar[5]) { hidden->vt->Release((IUnknown*)hidden); return -1; } if (hidden->vt->DecodeSet(hidden, recordpar)) return -1; if (strcmp(name, "Brightness") == 0) value = recordpar[18]; else if (strcmp(name, "Saturation") == 0) value = recordpar[19]; else if (strcmp(name, "Contrast") == 0) value = recordpar[20]; hidden->vt->Release((IUnknown*)hidden); } #else (void)this; (void)name; (void)value; #endif return 0; } int DS_VideoDecoder_SetValue(DS_VideoDecoder *this, const char* name, int value) { if (this->m_bIsDivX4) { IDivxFilterInterface* pIDivx=NULL; // printf("DS_SetValue for DIVX4, name=%s value=%d\n",name,value); if (this->m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)this->m_pDS_Filter->m_pFilter, &IID_IDivxFilterInterface, (void**)&pIDivx)) { printf("No such interface\n"); return -1; } if (strcmp(name, "Postprocessing") == 0) pIDivx->vt->put_PPLevel(pIDivx, value * 10); else if (strcmp(name, "Brightness") == 0) pIDivx->vt->put_Brightness(pIDivx, value); else if (strcmp(name, "Contrast") == 0) pIDivx->vt->put_Contrast(pIDivx, value); else if (strcmp(name, "Saturation") == 0) pIDivx->vt->put_Saturation(pIDivx, value); else if (strcmp(name, "MaxAuto") == 0) this->m_iMaxAuto = value; pIDivx->vt->Release((IUnknown*)pIDivx); //printf("Set %s %d\n", name, value); return 0; } if (this->m_bIsDivX) { IHidden* hidden; if (this->iv.m_State != START) return VFW_E_NOT_RUNNING; //cout << "set value " << name << " " << value << endl; // brightness 87 // contrast 74 // hue 23 // saturation 20 // post process mode 0 // get1 0x01 // get2 10 // get3=set2 86 // get4=set3 73 // get5=set4 19 // get6=set5 23 hidden = (IHidden*)((int)this->m_pDS_Filter->m_pFilter + 0xb8); // printf("DS_SetValue for DIVX, name=%s value=%d\n",name,value); if (strcmp(name, "Quality") == 0) { this->m_iLastQuality = value; return hidden->vt->SetSmth(hidden, value, 0); } if (strcmp(name, "Brightness") == 0) return hidden->vt->SetSmth2(hidden, value, 0); if (strcmp(name, "Contrast") == 0) return hidden->vt->SetSmth3(hidden, value, 0); if (strcmp(name, "Saturation") == 0) return hidden->vt->SetSmth4(hidden, value, 0); if (strcmp(name, "Hue") == 0) return hidden->vt->SetSmth5(hidden, value, 0); if (strcmp(name, "MaxAuto") == 0) { this->m_iMaxAuto = value; } return 0; } #if 0 if (strcmp((const char*)record.dll, "ir50_32.dll") == 0) { IHidden2* hidden = 0; if (m_pDS_Filter->m_pFilter->vt->QueryInterface((IUnknown*)m_pDS_Filter->m_pFilter, &IID_Iv50Hidden, (void**)&hidden)) { Debug printf("No such interface\n"); return -1; } int recordpar[30]; recordpar[0]=0x7c; recordpar[1]=fccIV50; recordpar[2]=0x10005; recordpar[3]=2; recordpar[4]=1; recordpar[5]=0x80000000; if (strcmp(name, "Brightness") == 0) { recordpar[5]|=0x20; recordpar[18]=value; } else if (strcmp(name, "Saturation") == 0) { recordpar[5]|=0x40; recordpar[19]=value; } else if (strcmp(name, "Contrast") == 0) { recordpar[5]|=0x80; recordpar[20]=value; } if(!recordpar[5]) { hidden->vt->Release((IUnknown*)hidden); return -1; } HRESULT result = hidden->vt->DecodeSet(hidden, recordpar); hidden->vt->Release((IUnknown*)hidden); return result; } #endif // printf("DS_SetValue for ????, name=%s value=%d\n",name,value); return 0; } /* vim: vi* sux. hahaha */ #if 0 int DS_SetAttr_DivX(char* attribute, int value){ int result, status, newkey, count; if(strcmp(attribute, "Quality")==0){ char* keyname="SOFTWARE\\Microsoft\\Scrunch"; result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); if(result!=0) { printf("VideoDecoder::SetExtAttr: registry failure\n"); return -1; } result=RegSetValueExA(newkey, "Current Post Process Mode", 0, REG_DWORD, &value, 4); if(result!=0) { printf("VideoDecoder::SetExtAttr: error writing value\n"); return -1; } value=-1; result=RegSetValueExA(newkey, "Force Post Process Mode", 0, REG_DWORD, &value, 4); if(result!=0) { printf("VideoDecoder::SetExtAttr: error writing value\n"); return -1; } RegCloseKey(newkey); return 0; } if( (strcmp(attribute, "Saturation")==0) || (strcmp(attribute, "Hue")==0) || (strcmp(attribute, "Contrast")==0) || (strcmp(attribute, "Brightness")==0) ) { char* keyname="SOFTWARE\\Microsoft\\Scrunch\\Video"; result=RegCreateKeyExA(HKEY_CURRENT_USER, keyname, 0, 0, 0, 0, 0, &newkey, &status); if(result!=0) { printf("VideoDecoder::SetExtAttr: registry failure\n"); return -1; } result=RegSetValueExA(newkey, attribute, 0, REG_DWORD, &value, 4); if(result!=0) { printf("VideoDecoder::SetExtAttr: error writing value\n"); return -1; } RegCloseKey(newkey); return 0; } printf("Unknown attribute!\n"); return -200; } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/iunk.h��������������������������������������������������������0000644�0001750�0001750�00000003072�14647725152�016445� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef DS_IUNK_H #define DS_IUNK_H #include "guids.h" #define INHERIT_IUNKNOWN() \ long STDCALL ( *QueryInterface )(IUnknown * This, const GUID* riid, void **ppvObject); \ long STDCALL ( *AddRef )(IUnknown * This); \ long STDCALL ( *Release )(IUnknown * This); #define DECLARE_IUNKNOWN() \ int refcount; #define IMPLEMENT_IUNKNOWN(CLASSNAME) \ static long STDCALL CLASSNAME ## _QueryInterface(IUnknown * This, \ const GUID* riid, void **ppvObject) \ { \ CLASSNAME * me = (CLASSNAME *)This; \ const GUID* r; unsigned int i = 0; \ Debug printf(#CLASSNAME "_QueryInterface(%p) called\n", This);\ if (!ppvObject) return E_POINTER; \ for(r=me->interfaces; i<sizeof(me->interfaces)/sizeof(me->interfaces[0]); r++, i++) \ if(!memcmp(r, riid, sizeof(*r))) \ { \ me->vt->AddRef((IUnknown*)This); \ *ppvObject=This; \ return 0; \ } \ Debug printf("Query failed! (GUID: 0x%x)\n", *(const unsigned int*)riid); \ return E_NOINTERFACE; \ } \ \ static long STDCALL CLASSNAME ## _AddRef(IUnknown * This) \ { \ CLASSNAME * me=( CLASSNAME *)This; \ Debug printf(#CLASSNAME "_AddRef(%p) called (ref:%d)\n", This, me->refcount); \ return ++(me->refcount); \ } \ \ static long STDCALL CLASSNAME ## _Release(IUnknown * This) \ { \ CLASSNAME* me=( CLASSNAME *)This; \ Debug printf(#CLASSNAME "_Release(%p) called (new ref:%d)\n", This, me->refcount - 1); \ if(--(me->refcount) == 0) \ CLASSNAME ## _Destroy(me); \ return 0; \ } #endif /* DS_IUNK_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/allocator.c���������������������������������������������������0000644�0001750�0001750�00000021261�14647725152�017452� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "allocator.h" #include "com.h" #include "../wine/winerror.h" #include <stdio.h> #include <stdlib.h> static int AllocatorKeeper = 0; struct _avm_list_t { struct _avm_list_t* next; struct _avm_list_t* prev; void* member; }; static inline int avm_list_size(avm_list_t* head) { avm_list_t* it = head; int i = 0; if (it) { for (;;) { i++; it = it->next; if (it == head) break; } } return i; } static inline int avm_list_print(avm_list_t* head) { avm_list_t* it = head; int i = 0; printf("Head: %p\n", head); if (it) { for (;;) { i++; printf("%d: member: %p next: %p prev: %p\n", i, it->member, it->next, it->prev); it = it->next; if (it == head) break; } } return i; } static inline avm_list_t* avm_list_add_head(avm_list_t* head, void* member) { avm_list_t* n = (avm_list_t*) malloc(sizeof(avm_list_t)); n->member = member; if (!head) { head = n; head->prev = head; } n->prev = head->prev; head->prev = n; n->next = head; return n; } static inline avm_list_t* avm_list_add_tail(avm_list_t* head, void* member) { avm_list_t* n = avm_list_add_head(head, member); return (!head) ? n : head; } static inline avm_list_t* avm_list_del_head(avm_list_t* head) { avm_list_t* n = 0; if (head) { if (head->next != head) { n = head->next; head->prev->next = head->next; head->next->prev = head->prev; } free(head); } return n; } static inline avm_list_t* avm_list_find(avm_list_t* head, void* member) { avm_list_t* it = head; if (it) { for (;;) { if (it->member == member) return it; it = it->next; if (it == head) break; } } return NULL; } static long MemAllocator_CreateAllocator(GUID* clsid, const GUID* iid, void** ppv) { IMemAllocator* p; int result; if (!ppv) return -1; *ppv = 0; if (memcmp(clsid, &CLSID_MemoryAllocator, sizeof(GUID))) return -1; p = (IMemAllocator*) MemAllocatorCreate(); result = p->vt->QueryInterface((IUnknown*)p, iid, ppv); p->vt->Release((IUnknown*)p); return result; } static HRESULT STDCALL MemAllocator_SetProperties(IMemAllocator * This, /* [in] */ ALLOCATOR_PROPERTIES *pRequest, /* [out] */ ALLOCATOR_PROPERTIES *pActual) { MemAllocator* me = (MemAllocator*)This; Debug printf("MemAllocator_SetProperties(%p) called\n", This); if (!pRequest || !pActual) return E_INVALIDARG; if (pRequest->cBuffers<=0 || pRequest->cbBuffer<=0) return E_FAIL; if (me->used_list != 0 || me->free_list != 0) return E_FAIL; *pActual = *pRequest; //if (pActual->cbBuffer == 2) // pActual->cbBuffer = 576; me->props = *pActual; return 0; } static HRESULT STDCALL MemAllocator_GetProperties(IMemAllocator * This, /* [out] */ ALLOCATOR_PROPERTIES *pProps) { Debug printf("MemAllocator_GetProperties(%p) called\n", This); if (!pProps) return E_INVALIDARG; if (((MemAllocator*)This)->props.cbBuffer<0) return E_FAIL; *pProps=((MemAllocator*)This)->props; return 0; } static HRESULT STDCALL MemAllocator_Commit(IMemAllocator * This) { MemAllocator* me = (MemAllocator*)This; int i; Debug printf("MemAllocator_Commit(%p) called\n", This); if (((MemAllocator*)This)->props.cbBuffer < 0) return E_FAIL; if (me->used_list || me->free_list) return E_INVALIDARG; for (i = 0; i < me->props.cBuffers; i++) { CMediaSample* sample = CMediaSampleCreate((IMemAllocator*)me, me->props.cbBuffer); if (!sample) return E_OUTOFMEMORY; //printf("FREEEEEEEEEEEE ADDED %p\n", sample); me->free_list = avm_list_add_tail(me->free_list, sample); //avm_list_print(me->free_list); } //printf("Added mem %p: lsz: %d %d size: %d\n", me, avm_list_size(me->free_list), me->props.cBuffers, me->props.cbBuffer); return 0; } static HRESULT STDCALL MemAllocator_Decommit(IMemAllocator * This) { MemAllocator* me=(MemAllocator*)This; Debug printf("MemAllocator_Decommit(%p) called\n", This); //printf("Deleted mem %p: %d %d\n", me, me->free_list.size(), me->used_list.size()); while (me->used_list) { me->free_list = avm_list_add_tail(me->free_list, (CMediaSample*) me->used_list->member); me->used_list = avm_list_del_head(me->used_list); } while (me->free_list) { CMediaSample* sample = (CMediaSample*) me->free_list->member; //printf("****************** Decommiting FREE %p\n", sample); //sample->vt->Release((IUnknown*)sample); CMediaSample_Destroy((CMediaSample*)sample); me->free_list = avm_list_del_head(me->free_list); } return 0; } static HRESULT STDCALL MemAllocator_GetBuffer(IMemAllocator * This, /* [out] */ IMediaSample **ppBuffer, /* [in] */ REFERENCE_TIME *pStartTime, /* [in] */ REFERENCE_TIME *pEndTime, /* [in] */ DWORD dwFlags) { MemAllocator* me = (MemAllocator*)This; CMediaSample* sample; (void)pStartTime; (void)pEndTime; (void)dwFlags; Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, avm_list_size(me->used_list), avm_list_size(me->free_list)); if (!me->free_list) { Debug printf("No samples available\n"); return E_FAIL;//should block here if no samples are available } sample = (CMediaSample*) me->free_list->member; me->free_list = avm_list_del_head(me->free_list); me->used_list = avm_list_add_tail(me->used_list, sample); *ppBuffer = (IMediaSample*) sample; sample->vt->AddRef((IUnknown*) sample); if (me->new_pointer) { if (me->modified_sample) me->modified_sample->ResetPointer(me->modified_sample); sample->SetPointer(sample, me->new_pointer); me->modified_sample = sample; me->new_pointer = 0; } return 0; } static HRESULT STDCALL MemAllocator_ReleaseBuffer(IMemAllocator* This, /* [in] */ IMediaSample* pBuffer) { avm_list_t* l; MemAllocator* me = (MemAllocator*)This; Debug printf("MemAllocator_ReleaseBuffer(%p) called %d %d\n", This, avm_list_size(me->used_list), avm_list_size(me->free_list)); l = avm_list_find(me->used_list, pBuffer); if (l) { CMediaSample* sample = (CMediaSample*) l->member; if (me->modified_sample == sample) { me->modified_sample->ResetPointer(me->modified_sample); me->modified_sample = 0; } me->used_list = avm_list_del_head(me->used_list); me->free_list = avm_list_add_head(me->free_list, sample); //printf("****************** RELEASED OK %p %p\n", me->used_list, me->free_list); return 0; } Debug printf("MemAllocator_ReleaseBuffer(%p) releasing unknown buffer!!!! %p\n", This, pBuffer); return E_FAIL; } static void MemAllocator_SetPointer(MemAllocator* This, char* pointer) { This->new_pointer = pointer; } static void MemAllocator_ResetPointer(MemAllocator* This) { if (This->modified_sample) { This->modified_sample->ResetPointer(This->modified_sample); This->modified_sample = 0; } } static void MemAllocator_Destroy(MemAllocator* This) { Debug printf("MemAllocator_Destroy(%p) called (%d, %d)\n", This, This->refcount, AllocatorKeeper); if (--AllocatorKeeper == 0) UnregisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); free(This->vt); free(This); } IMPLEMENT_IUNKNOWN(MemAllocator) MemAllocator* MemAllocatorCreate() { MemAllocator* This = (MemAllocator*) malloc(sizeof(MemAllocator)); if (!This) return NULL; Debug printf("MemAllocatorCreate() called -> %p\n", This); This->refcount = 1; This->props.cBuffers = 1; This->props.cbBuffer = 65536; /* :/ */ This->props.cbAlign = This->props.cbPrefix = 0; This->vt = (IMemAllocator_vt*) malloc(sizeof(IMemAllocator_vt)); if (!This->vt) { free(This); return NULL; } This->vt->QueryInterface = MemAllocator_QueryInterface; This->vt->AddRef = MemAllocator_AddRef; This->vt->Release = MemAllocator_Release; This->vt->SetProperties = MemAllocator_SetProperties; This->vt->GetProperties = MemAllocator_GetProperties; This->vt->Commit = MemAllocator_Commit; This->vt->Decommit = MemAllocator_Decommit; This->vt->GetBuffer = MemAllocator_GetBuffer; This->vt->ReleaseBuffer = MemAllocator_ReleaseBuffer; This->SetPointer = MemAllocator_SetPointer; This->ResetPointer = MemAllocator_ResetPointer; This->modified_sample = 0; This->new_pointer = 0; This->used_list = 0; This->free_list = 0; This->interfaces[0]=IID_IUnknown; This->interfaces[1]=IID_IMemAllocator; if (AllocatorKeeper++ == 0) RegisterComClass(&CLSID_MemoryAllocator, MemAllocator_CreateAllocator); return This; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/DirectShow/outputpin.c���������������������������������������������������0000644�0001750�0001750�00000036620�14647725152�017546� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� #include "../wine/winerror.h" #include "../wine/windef.h" #include "outputpin.h" #include <stdio.h> #include <string.h> #include <stdlib.h> /* An object beyond interface IEnumMediaTypes. Returned by COutputPin through call IPin::EnumMediaTypes(). */ static inline int output_unimplemented(const char* s, void* p) { Debug printf("%s(%p) called (UNIMPLEMENTED)", s, p); return E_NOTIMPL; } typedef struct CEnumMediaTypes { IEnumMediaTypes_vt* vt; DECLARE_IUNKNOWN(); AM_MEDIA_TYPE type; GUID interfaces[2]; } CEnumMediaTypes; struct _COutputMemPin { IMemInputPin_vt* vt; DECLARE_IUNKNOWN(); char** frame_pointer; long* frame_size_pointer; MemAllocator* pAllocator; COutputPin* parent; }; static HRESULT STDCALL CEnumMediaTypes_Next(IEnumMediaTypes * This, /* [in] */ ULONG cMediaTypes, /* [size_is][out] */ AM_MEDIA_TYPE **ppMediaTypes, /* [out] */ ULONG *pcFetched) { AM_MEDIA_TYPE* type = &((CEnumMediaTypes*)This)->type; Debug printf("CEnumMediaTypes::Next(%p) called\n", This); if (!ppMediaTypes) return E_INVALIDARG; if (!pcFetched && (cMediaTypes!=1)) return E_INVALIDARG; if (cMediaTypes <= 0) return 0; if (pcFetched) *pcFetched=1; ppMediaTypes[0] = (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); // copy structures - C can handle this... **ppMediaTypes = *type; if (ppMediaTypes[0]->pbFormat) { ppMediaTypes[0]->pbFormat=(char *)CoTaskMemAlloc(ppMediaTypes[0]->cbFormat); memcpy(ppMediaTypes[0]->pbFormat, type->pbFormat, ppMediaTypes[0]->cbFormat); } if (cMediaTypes == 1) return 0; return 1; } /* I expect that these methods are unused. */ static HRESULT STDCALL CEnumMediaTypes_Skip(IEnumMediaTypes * This, /* [in] */ ULONG cMediaTypes) { (void)cMediaTypes; return output_unimplemented("CEnumMediaTypes::Skip", This); } static HRESULT STDCALL CEnumMediaTypes_Reset(IEnumMediaTypes * This) { Debug printf("CEnumMediaTypes::Reset(%p) called\n", This); return 0; } static HRESULT STDCALL CEnumMediaTypes_Clone(IEnumMediaTypes * This, /* [out] */ IEnumMediaTypes **ppEnum) { (void)ppEnum; Debug printf("CEnumMediaTypes::Clone(%p) called\n", This); return E_NOTIMPL; } static void CEnumMediaTypes_Destroy(CEnumMediaTypes* This) { free(This->vt); free(This); } // IPin->IUnknown methods IMPLEMENT_IUNKNOWN(CEnumMediaTypes) static CEnumMediaTypes* CEnumMediaTypesCreate(const AM_MEDIA_TYPE* amt) { CEnumMediaTypes *This = (CEnumMediaTypes*) malloc(sizeof(CEnumMediaTypes)) ; if (!This) return NULL; This->vt = (IEnumMediaTypes_vt*) malloc(sizeof(IEnumMediaTypes_vt)); if (!This->vt) { free(This); return NULL; } This->refcount = 1; This->type = *amt; This->vt->QueryInterface = CEnumMediaTypes_QueryInterface; This->vt->AddRef = CEnumMediaTypes_AddRef; This->vt->Release = CEnumMediaTypes_Release; This->vt->Next = CEnumMediaTypes_Next; This->vt->Skip = CEnumMediaTypes_Skip; This->vt->Reset = CEnumMediaTypes_Reset; This->vt->Clone = CEnumMediaTypes_Clone; This->interfaces[0] = IID_IUnknown; This->interfaces[1] = IID_IEnumMediaTypes; return This; } /************* * COutputPin *************/ static HRESULT STDCALL COutputPin_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) { COutputPin* p = (COutputPin*) This; Debug printf("COutputPin_QueryInterface(%p) called\n", This); if (!ppv) return E_INVALIDARG; if (memcmp(iid, &IID_IUnknown, 16) == 0) { *ppv = p; p->vt->AddRef(This); return 0; } if (memcmp(iid, &IID_IMemInputPin, 16) == 0) { *ppv = p->mempin; p->mempin->vt->AddRef((IUnknown*)*ppv); return 0; } Debug printf("Unknown interface : %08x-%04x-%04x-%02x%02x-" "%02x%02x%02x%02x%02x%02x\n", iid->f1, iid->f2, iid->f3, (unsigned char)iid->f4[1], (unsigned char)iid->f4[0], (unsigned char)iid->f4[2], (unsigned char)iid->f4[3], (unsigned char)iid->f4[4], (unsigned char)iid->f4[5], (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]); return E_NOINTERFACE; } // IPin methods static HRESULT STDCALL COutputPin_Connect(IPin * This, /* [in] */ IPin *pReceivePin, /* [in] */ /* const */ AM_MEDIA_TYPE *pmt) { Debug printf("COutputPin_Connect() called\n"); (void)pReceivePin; #if 0 *pmt=((COutputPin*)This)->type; if(pmt->cbFormat>0) { pmt->pbFormat=CoTaskMemAlloc(pmt->cbFormat); memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat); } #else (void)This; (void)pmt; #endif //return E_NOTIMPL; return 0;// XXXXXXXXXXXXX CHECKME XXXXXXXXXXXXXXX // if I put return 0; here, it crashes } static HRESULT STDCALL COutputPin_ReceiveConnection(IPin * This, /* [in] */ IPin *pConnector, /* [in] */ const AM_MEDIA_TYPE *pmt) { (void)pmt; Debug printf("COutputPin_ReceiveConnection(%p) called\n", This); ((COutputPin*)This)->remote = pConnector; return 0; } static HRESULT STDCALL COutputPin_Disconnect(IPin * This) { Debug printf("COutputPin_Disconnect(%p) called\n", This); return 1; } static HRESULT STDCALL COutputPin_ConnectedTo(IPin * This, /* [out] */ IPin **pPin) { Debug printf("COutputPin_ConnectedTo(%p) called\n", This); if (!pPin) return E_INVALIDARG; *pPin = ((COutputPin*)This)->remote; return 0; } static HRESULT STDCALL COutputPin_ConnectionMediaType(IPin * This, /* [out] */ AM_MEDIA_TYPE *pmt) { Debug printf("CInputPin::ConnectionMediaType() called\n"); if (!pmt) return E_INVALIDARG; *pmt = ((COutputPin*)This)->type; if (pmt->cbFormat>0) { pmt->pbFormat=(char *)CoTaskMemAlloc(pmt->cbFormat); memcpy(pmt->pbFormat, ((COutputPin*)This)->type.pbFormat, pmt->cbFormat); } return 0; } static HRESULT STDCALL COutputPin_QueryPinInfo(IPin * This, /* [out] */ PIN_INFO *pInfo) { (void)pInfo; return output_unimplemented("COutputPin_QueryPinInfo", This); } static HRESULT STDCALL COutputPin_QueryDirection(IPin * This, /* [out] */ PIN_DIRECTION *pPinDir) { Debug printf("COutputPin_QueryDirection(%p) called\n", This); if (!pPinDir) return E_INVALIDARG; *pPinDir = PINDIR_INPUT; return 0; } static HRESULT STDCALL COutputPin_QueryId(IPin * This, /* [out] */ LPWSTR *Id) { (void)Id; return output_unimplemented("COutputPin_QueryId", This); } static HRESULT STDCALL COutputPin_QueryAccept(IPin * This, /* [in] */ const AM_MEDIA_TYPE *pmt) { (void)pmt; return output_unimplemented("COutputPin_QueryAccept", This); } static HRESULT STDCALL COutputPin_EnumMediaTypes(IPin * This, /* [out] */ IEnumMediaTypes **ppEnum) { Debug printf("COutputPin_EnumMediaTypes() called\n"); if (!ppEnum) return E_INVALIDARG; *ppEnum = (IEnumMediaTypes*) CEnumMediaTypesCreate(&((COutputPin*)This)->type); return 0; } static HRESULT STDCALL COutputPin_QueryInternalConnections(IPin * This, /* [out] */ IPin **apPin, /* [out][in] */ ULONG *nPin) { (void)apPin; (void)nPin; return output_unimplemented("COutputPin_QueryInternalConnections", This); } static HRESULT STDCALL COutputPin_EndOfStream(IPin * This) { return output_unimplemented("COutputPin_EndOfStream", This); } static HRESULT STDCALL COutputPin_BeginFlush(IPin * This) { return output_unimplemented("COutputPin_BeginFlush", This); } static HRESULT STDCALL COutputPin_EndFlush(IPin * This) { return output_unimplemented("COutputPin_EndFlush", This); } static HRESULT STDCALL COutputPin_NewSegment(IPin * This, /* [in] */ REFERENCE_TIME tStart, /* [in] */ REFERENCE_TIME tStop, /* [in] */ double dRate) { (void)This; Debug printf("COutputPin_NewSegment(%Ld,%Ld,%f) called\n", tStart, tStop, dRate); return 0; } // IMemInputPin->IUnknown methods static HRESULT STDCALL COutputPin_M_QueryInterface(IUnknown* This, const GUID* iid, void** ppv) { COutputPin* p = (COutputPin*)This; Debug printf("COutputPin_M_QueryInterface(%p) called\n", This); if (!ppv) return E_INVALIDARG; if(!memcmp(iid, &IID_IUnknown, 16)) { *ppv = p; p->vt->AddRef(This); return 0; } /*if(!memcmp(iid, &IID_IPin, 16)) { COutputPin* ptr=(COutputPin*)(This-1); *ppv=(void*)ptr; AddRef((IUnknown*)ptr); return 0; }*/ if(!memcmp(iid, &IID_IMemInputPin, 16)) { *ppv = p->mempin; p->mempin->vt->AddRef(This); return 0; } Debug printf("Unknown interface : %08x-%04x-%04x-%02x%02x-" \ "%02x%02x%02x%02x%02x%02x\n", iid->f1, iid->f2, iid->f3, (unsigned char)iid->f4[1], (unsigned char)iid->f4[0], (unsigned char)iid->f4[2], (unsigned char)iid->f4[3], (unsigned char)iid->f4[4], (unsigned char)iid->f4[5], (unsigned char)iid->f4[6], (unsigned char)iid->f4[7]); return E_NOINTERFACE; } // IMemInputPin methods static HRESULT STDCALL COutputPin_GetAllocator(IMemInputPin* This, /* [out] */ IMemAllocator** ppAllocator) { Debug printf("COutputPin_GetAllocator(%p, %p) called\n", This->vt, ppAllocator); *ppAllocator = (IMemAllocator*) MemAllocatorCreate(); return 0; } static HRESULT STDCALL COutputPin_NotifyAllocator(IMemInputPin* This, /* [in] */ IMemAllocator* pAllocator, /* [in] */ int bReadOnly) { (void)bReadOnly; Debug printf("COutputPin_NotifyAllocator(%p, %p) called\n", This, pAllocator); ((COutputMemPin*)This)->pAllocator = (MemAllocator*) pAllocator; return 0; } static HRESULT STDCALL COutputPin_GetAllocatorRequirements(IMemInputPin* This, /* [out] */ ALLOCATOR_PROPERTIES* pProps) { (void)pProps; return output_unimplemented("COutputPin_GetAllocatorRequirements", This); } static HRESULT STDCALL COutputPin_Receive(IMemInputPin* This, /* [in] */ IMediaSample* pSample) { COutputMemPin* mp = (COutputMemPin*)This; char* pointer; int len; Debug printf("COutputPin_Receive(%p) called\n", This); if (!pSample) return E_INVALIDARG; if (pSample->vt->GetPointer(pSample, (BYTE**) &pointer)) return -1; len = pSample->vt->GetActualDataLength(pSample); if (len == 0) len = pSample->vt->GetSize(pSample);//for iv50 //if(me.frame_pointer)memcpy(me.frame_pointer, pointer, len); if (mp->frame_pointer) *(mp->frame_pointer) = pointer; if (mp->frame_size_pointer) *(mp->frame_size_pointer) = len; /* FILE* file=fopen("./uncompr.bmp", "wb"); char head[14]={0x42, 0x4D, 0x36, 0x10, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00}; *(int*)(&head[2])=len+0x36; fwrite(head, 14, 1, file); fwrite(&((VIDEOINFOHEADER*)me.type.pbFormat)->bmiHeader, sizeof(BITMAPINFOHEADER), 1, file); fwrite(pointer, len, 1, file); fclose(file); */ // pSample->vt->Release((IUnknown*)pSample); return 0; } static HRESULT STDCALL COutputPin_ReceiveMultiple(IMemInputPin * This, /* [size_is][in] */ IMediaSample **pSamples, /* [in] */ long nSamples, /* [out] */ long *nSamplesProcessed) { (void)pSamples; (void)nSamples; (void)nSamplesProcessed; return output_unimplemented("COutputPin_ReceiveMultiple", This); } static HRESULT STDCALL COutputPin_ReceiveCanBlock(IMemInputPin * This) { return output_unimplemented("COutputPin_ReceiveCanBlock", This); } static void COutputPin_SetFramePointer(COutputPin* This, char** z) { This->mempin->frame_pointer = z; } static void COutputPin_SetPointer2(COutputPin* This, char* p) { if (This->mempin->pAllocator) // fixme This->mempin->pAllocator->SetPointer(This->mempin->pAllocator, p); } static void COutputPin_SetFrameSizePointer(COutputPin* This, long* z) { This->mempin->frame_size_pointer = z; } static void COutputPin_SetNewFormat(COutputPin* This, const AM_MEDIA_TYPE* amt) { This->type = *amt; } static void COutputPin_Destroy(COutputPin* This) { if (This->mempin) { if (This->mempin->vt) free(This->mempin->vt); free(This->mempin); } if (This->vt) free(This->vt); free(This); } static HRESULT STDCALL COutputPin_AddRef(IUnknown* This) { Debug printf("COutputPin_AddRef(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); ((COutputPin*)This)->refcount++; return 0; } static HRESULT STDCALL COutputPin_Release(IUnknown* This) { Debug printf("COutputPin_Release(%p) called (%d)\n", This, ((COutputPin*)This)->refcount); if (--((COutputPin*)This)->refcount <= 0) COutputPin_Destroy((COutputPin*)This); return 0; } static HRESULT STDCALL COutputPin_M_AddRef(IUnknown* This) { COutputMemPin* p = (COutputMemPin*) This; Debug printf("COutputPin_MAddRef(%p) called (%p, %d)\n", p, p->parent, p->parent->refcount); p->parent->refcount++; return 0; } static HRESULT STDCALL COutputPin_M_Release(IUnknown* This) { COutputMemPin* p = (COutputMemPin*) This; Debug printf("COutputPin_MRelease(%p) called (%p, %d)\n", p, p->parent, p->parent->refcount); if (--p->parent->refcount <= 0) COutputPin_Destroy(p->parent); return 0; } COutputPin* COutputPinCreate(const AM_MEDIA_TYPE* amt) { COutputPin* This = (COutputPin*) malloc(sizeof(COutputPin)); IMemInputPin_vt* ivt; if (!This) return NULL; This->vt = (IPin_vt*) malloc(sizeof(IPin_vt)); This->mempin = (COutputMemPin*) malloc(sizeof(COutputMemPin)); ivt = (IMemInputPin_vt*) malloc(sizeof(IMemInputPin_vt)); if (!This->vt || !This->mempin || !ivt) { COutputPin_Destroy(This); free(ivt); return NULL; } This->mempin->vt = ivt; This->refcount = 1; This->remote = 0; This->type = *amt; This->vt->QueryInterface = COutputPin_QueryInterface; This->vt->AddRef = COutputPin_AddRef; This->vt->Release = COutputPin_Release; This->vt->Connect = COutputPin_Connect; This->vt->ReceiveConnection = COutputPin_ReceiveConnection; This->vt->Disconnect = COutputPin_Disconnect; This->vt->ConnectedTo = COutputPin_ConnectedTo; This->vt->ConnectionMediaType = COutputPin_ConnectionMediaType; This->vt->QueryPinInfo = COutputPin_QueryPinInfo; This->vt->QueryDirection = COutputPin_QueryDirection; This->vt->QueryId = COutputPin_QueryId; This->vt->QueryAccept = COutputPin_QueryAccept; This->vt->EnumMediaTypes = COutputPin_EnumMediaTypes; This->vt->QueryInternalConnections = COutputPin_QueryInternalConnections; This->vt->EndOfStream = COutputPin_EndOfStream; This->vt->BeginFlush = COutputPin_BeginFlush; This->vt->EndFlush = COutputPin_EndFlush; This->vt->NewSegment = COutputPin_NewSegment; This->mempin->vt->QueryInterface = COutputPin_M_QueryInterface; This->mempin->vt->AddRef = COutputPin_M_AddRef; This->mempin->vt->Release = COutputPin_M_Release; This->mempin->vt->GetAllocator = COutputPin_GetAllocator; This->mempin->vt->NotifyAllocator = COutputPin_NotifyAllocator; This->mempin->vt->GetAllocatorRequirements = COutputPin_GetAllocatorRequirements; This->mempin->vt->Receive = COutputPin_Receive; This->mempin->vt->ReceiveMultiple = COutputPin_ReceiveMultiple; This->mempin->vt->ReceiveCanBlock = COutputPin_ReceiveCanBlock; This->mempin->frame_size_pointer = 0; This->mempin->frame_pointer = 0; This->mempin->pAllocator = 0; This->mempin->refcount = 1; This->mempin->parent = This; This->SetPointer2 = COutputPin_SetPointer2; This->SetFramePointer = COutputPin_SetFramePointer; This->SetFrameSizePointer = COutputPin_SetFrameSizePointer; This->SetNewFormat = COutputPin_SetNewFormat; return This; } ����������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libw32dll/w32codec.h���������������������������������������������������������������0000644�0001750�0001750�00000002335�14647725152�015036� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * routines for using w32 codecs */ #include "wine/msacm.h" #include "wine/avifmt.h" #include "wine/vfw.h" int w32c_init_video(BITMAPINFOHEADER *bih) ; void w32c_decode_video (unsigned char *data, uint32_t nSize, int bFrameEnd, uint32_t nPTS); void w32c_close_video (); int w32c_init_audio (WAVEFORMATEX *in_fmt); void w32c_decode_audio (unsigned char *data, uint32_t nSize, int bFrameEnd, uint32_t nPTS) ; void w32c_close_audio (); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�012333� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/dxr3_scr.h��������������������������������������������������������������������0000644�0001750�0001750�00000002673�14647725152�014243� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #include <xine/xine_internal.h> /* plugin structure */ typedef struct dxr3_scr_s { scr_plugin_t scr_plugin; pthread_mutex_t mutex; xine_t *xine; int fd_control; /* to access the dxr3 control device */ int priority; int64_t offset; /* difference between real scr and internal dxr3 clock */ uint32_t last_pts; /* last known value of internal dxr3 clock to detect wrap around */ int scanning; /* are we in a scanning mode */ int sync; /* are we in sync mode */ } dxr3_scr_t; /* plugin initialization function */ dxr3_scr_t *dxr3_scr_init(xine_t *xine); ���������������������������������������������������������������������xine-lib-1.2/src/dxr3/dxr3.h������������������������������������������������������������������������0000644�0001750�0001750�00000002700�14647725152�013363� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_DXR3_H #define HAVE_DXR3_H #include "em8300.h" #include <xine/xine_internal.h> #ifndef LOG_VID #define LOG_VID 0 #endif /* data for the device name config entry */ #define CONF_KEY "dxr3.device_number" #define CONF_NAME _("DXR3 device number") #define CONF_HELP _("If you have more than one DXR3 in your computer, you can specify which one to use here.") /* image format used by dxr3_decoder to tag undecoded mpeg data */ #define XINE_IMGFMT_DXR3 (('3'<<24)|('R'<<16)|('X'<<8)|'D') /* name of the dxr3 video out plugin * (used by decoders to check for dxr3 presence) */ #define DXR3_VO_ID "dxr3" int dxr3_present(xine_stream_t *stream); #endif ����������������������������������������������������������������xine-lib-1.2/src/dxr3/group_dxr3.h������������������������������������������������������������������0000644�0001750�0001750�00000002262�14647725152�014602� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_GROUP_DXR3_H #define HAVE_GROUP_DXR3_H #include <xine/xine_internal.h> void *dxr3_spudec_init_plugin(xine_t *xine, const void* data); void *dxr3_video_init_plugin(xine_t *xine, const void *data); void *dxr3_aa_init_plugin(xine_t *xine, const void *visual_gen); #ifdef HAVE_X11 void *dxr3_x11_init_plugin(xine_t *xine, const void *visual_gen); #endif #endif /* HAVE_GROUP_DXR3_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/dxr3_spu_encoder.c������������������������������������������������������������0000644�0001750�0001750�00000042344�14647725152�015754� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <float.h> #define LOG_MODULE "dxr3_spu_encoder" /* #define LOG_VERBOSE */ /* #define LOG */ #include "video_out_dxr3.h" /* We use the following algorithm to reduce the given overlay palette * to a spu palette with only four distinct colours: * - create a histogram on the overlay palette * - the color with the maximum histogram value becomes one spu color * - modify the histogram so that the counts for colors very near to the * chosen one are lowered; this is done by multiplying with a penalty * function 1-1/(dist/DIST_COEFF + 1) where dist is the squared spatial * distance between current color and chosen spu color * - continue with the next maximum * The used histogram modification function from above looks like that: * ^ * 1 + ******** * | ****** * | **** * | ** * | * * 0 **--------------------> dist */ #define DIST_COEFF 1024.0 /* spu encoder function */ spu_encoder_t *dxr3_spu_encoder_init(void); void dxr3_spu_encode(spu_encoder_t *this); /* helper functions */ static void convert_palette(spu_encoder_t *this); static void create_histogram(spu_encoder_t *this); static void generate_clut(spu_encoder_t *this); static void map_colors(spu_encoder_t *this); static void convert_clut(spu_encoder_t *this); static void convert_overlay(spu_encoder_t *this); static void write_rle(spu_encoder_t *this, int *offset, int *higher_nibble, int length, int color); static void write_byte(spu_encoder_t *this, int *offset, uint8_t byte); static void write_nibble(spu_encoder_t *this, int *offset, int *higher_nibble, uint8_t nibble); spu_encoder_t *dxr3_spu_encoder_init(void) { spu_encoder_t *this; this = (spu_encoder_t *)malloc(sizeof(spu_encoder_t)); this->target = NULL; this->need_reencode = 0; this->malloc_size = 0; lprintf("initialized\n"); return this; } void dxr3_spu_encode(spu_encoder_t *this) { if (!this->need_reencode || !this->overlay) return; lprintf("overlay for encoding arrived.\n"); convert_palette(this); create_histogram(this); generate_clut(this); map_colors(this); convert_clut(this); convert_overlay(this); lprintf("overlay encoding completed\n"); } static void convert_palette(spu_encoder_t *this) { int i, y, cb, cr, r, g, b; if (!this->overlay->rgb_clut) { for (i = 0; i < OVL_PALETTE_SIZE; i++) { y = (this->overlay->color[i] >> 16) & 0xff; cr = (this->overlay->color[i] >> 8) & 0xff; cb = (this->overlay->color[i] ) & 0xff; r = 1.164 * y + 1.596 * (cr - 128); g = 1.164 * y - 0.813 * (cr - 128) - 0.392 * (cb - 128); b = 1.164 * y + 2.017 * (cb - 128); if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; if (r > 0xff) r = 0xff; if (g > 0xff) g = 0xff; if (b > 0xff) b = 0xff; this->overlay->color[i] = (r << 16) | (g << 8) | b; } this->overlay->rgb_clut = 1; } if (!this->overlay->hili_rgb_clut) { for (i = 0; i < OVL_PALETTE_SIZE; i++) { y = (this->overlay->hili_color[i] >> 16) & 0xff; cr = (this->overlay->hili_color[i] >> 8) & 0xff; cb = (this->overlay->hili_color[i] ) & 0xff; r = 1.164 * y + 1.596 * (cr - 128); g = 1.164 * y - 0.813 * (cr - 128) - 0.392 * (cb - 128); b = 1.164 * y + 2.017 * (cb - 128); if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; if (r > 0xff) r = 0xff; if (g > 0xff) g = 0xff; if (b > 0xff) b = 0xff; this->overlay->hili_color[i] = (r << 16) | (g << 8) | b; } this->overlay->hili_rgb_clut = 1; } } static void create_histogram(spu_encoder_t *this) { rle_elem_t *rle; int i, x, y, len, part; for (i = 0; i < OVL_PALETTE_SIZE; i++) this->map[i] = this->clip_map[i] = 0; x = y = 0; for (i = 0, rle = this->overlay->rle; i < this->overlay->num_rle; i++, rle++) { len = rle->len; if (y >= this->overlay->hili_top && y < this->overlay->hili_bottom) { if (x < this->overlay->hili_left) { part = (this->overlay->hili_left - x < len) ? (this->overlay->hili_left - x) : len; this->map[rle->color] += part; len -= part; x += part; } if (x >= this->overlay->hili_left && x < this->overlay->hili_right) { part = (this->overlay->hili_right - x < len) ? (this->overlay->hili_right - x) : len; this->clip_map[rle->color] += part; len -= part; x += part; } } this->map[rle->color] += len; x += len; if (x >= this->overlay->width) { x = 0; y++; } } #ifdef LOG for (i = 0; i < OVL_PALETTE_SIZE; i++) if (this->map[i]) lprintf("histogram: colour #%d 0x%.8x appears %d times\n", i, this->overlay->color[i], this->map[i]); for (i = 0; i < OVL_PALETTE_SIZE; i++) if (this->clip_map[i]) lprintf("histogram: clip colour #%d 0x%.8x appears %d times\n", i, this->overlay->hili_color[i], this->clip_map[i]); #endif } static void generate_clut(spu_encoder_t *this) { int i, max, spu_color; double dist, diff; /* find first maximum -> first spu color */ max = 0; for (i = 1; i < OVL_PALETTE_SIZE; i++) if (this->map[i] > this->map[max]) max = i; this->color[0] = this->overlay->color[max]; this->trans[0] = this->overlay->trans[max]; for (spu_color = 1; spu_color < 4; spu_color++) { /* modify histogram and find next maximum -> next spu color */ max = 0; for (i = 0; i < OVL_PALETTE_SIZE; i++) { /* subtract a correction based on the distance to the last spu color */ diff = ((this->overlay->color[i] ) & 0xff) - ((this->color[spu_color - 1] ) & 0xff); dist = diff * diff; diff = ((this->overlay->color[i] >> 8) & 0xff) - ((this->color[spu_color - 1] >> 8) & 0xff); dist += diff * diff; diff = ((this->overlay->color[i] >> 16) & 0xff) - ((this->color[spu_color - 1] >> 16) & 0xff); dist += diff * diff; diff = ((this->overlay->trans[i] ) ) - ((this->trans[spu_color - 1] ) ); dist += diff * diff; this->map[i] *= 1 - 1.0 / (dist / DIST_COEFF + 1.0); if (this->map[i] > this->map[max]) max = i; } this->color[spu_color] = this->overlay->color[max]; this->trans[spu_color] = this->overlay->trans[max]; } #ifdef LOG for (spu_color = 0; spu_color < 4; spu_color++) lprintf("spu colour %d: 0x%.8x, trans: %d\n", spu_color, this->color[spu_color], this->trans[spu_color]); #endif /* now the same stuff again, this time for the palette of the clipping area */ /* find first maximum -> first spu color */ max = 0; for (i = 1; i < OVL_PALETTE_SIZE; i++) if (this->clip_map[i] > this->clip_map[max]) max = i; this->hili_color[0] = this->overlay->hili_color[max]; this->hili_trans[0] = this->overlay->hili_trans[max]; for (spu_color = 1; spu_color < 4; spu_color++) { /* modify histogram and find next maximum -> next spu color */ max = 0; for (i = 0; i < OVL_PALETTE_SIZE; i++) { /* subtract a correction based on the distance to the last spu color */ diff = ((this->overlay->hili_color[i] ) & 0xff) - ((this->hili_color[spu_color - 1] ) & 0xff); dist = diff * diff; diff = ((this->overlay->hili_color[i] >> 8) & 0xff) - ((this->hili_color[spu_color - 1] >> 8) & 0xff); dist += diff * diff; diff = ((this->overlay->hili_color[i] >> 16) & 0xff) - ((this->hili_color[spu_color - 1] >> 16) & 0xff); dist += diff * diff; diff = ((this->overlay->hili_trans[i] ) ) - ((this->hili_trans[spu_color - 1] ) ); dist += diff * diff; this->clip_map[i] *= 1 - 1.0 / (dist / DIST_COEFF + 1.0); if (this->clip_map[i] > this->clip_map[max]) max = i; } this->hili_color[spu_color] = this->overlay->hili_color[max]; this->hili_trans[spu_color] = this->overlay->hili_trans[max]; } #ifdef LOG for (spu_color = 0; spu_color < 4; spu_color++) lprintf("spu clip colour %d: 0x%.8x, trans: %d\n", spu_color, this->hili_color[spu_color], this->hili_trans[spu_color]); #endif } static void map_colors(spu_encoder_t *this) { int i, min, spu_color; double dist, diff, min_dist; /* for all colors in overlay palette find closest spu color */ for (i = 0; i < OVL_PALETTE_SIZE; i++) { min = 0; min_dist = DBL_MAX; for (spu_color = 0; spu_color < 4; spu_color++) { diff = ((this->overlay->color[i] ) & 0xff) - ((this->color[spu_color] ) & 0xff); dist = diff * diff; diff = ((this->overlay->color[i] >> 8) & 0xff) - ((this->color[spu_color] >> 8) & 0xff); dist += diff * diff; diff = ((this->overlay->color[i] >> 16) & 0xff) - ((this->color[spu_color] >> 16) & 0xff); dist += diff * diff; diff = ((this->overlay->trans[i] ) ) - ((this->trans[spu_color] ) ); dist += diff * diff; if (dist < min_dist) { min_dist = dist; min = spu_color; } } this->map[i] = min; } /* for all colors in overlay clip palette find closest spu color */ for (i = 0; i < OVL_PALETTE_SIZE; i++) { min = 0; min_dist = DBL_MAX; for (spu_color = 0; spu_color < 4; spu_color++) { diff = ((this->overlay->hili_color[i] ) & 0xff) - ((this->hili_color[spu_color] ) & 0xff); dist = diff * diff; diff = ((this->overlay->hili_color[i] >> 8) & 0xff) - ((this->hili_color[spu_color] >> 8) & 0xff); dist += diff * diff; diff = ((this->overlay->hili_color[i] >> 16) & 0xff) - ((this->hili_color[spu_color] >> 16) & 0xff); dist += diff * diff; diff = ((this->overlay->hili_trans[i] ) ) - ((this->hili_trans[spu_color] ) ); dist += diff * diff; if (dist < min_dist) { min_dist = dist; min = spu_color; } } this->clip_map[i] = min; } } static void convert_clut(spu_encoder_t *this) { int i, r, g, b, y, cb, cr; for (i = 0; i < 4; i++) { r = (this->color[i] >> 16) & 0xff; g = (this->color[i] >> 8) & 0xff; b = (this->color[i] ) & 0xff; y = 0.257 * r + 0.504 * g + 0.098 * b; cr = 0.439 * r - 0.368 * g - 0.071 * b + 128; cb = -0.148 * r - 0.291 * g + 0.439 * b + 128; this->color[i] = (y << 16) | (cr << 8) | cb; } for (i = 4; i < 16; i++) this->color[i] = 0x00008080; for (i = 0; i < 4; i++) { r = (this->hili_color[i] >> 16) & 0xff; g = (this->hili_color[i] >> 8) & 0xff; b = (this->hili_color[i] ) & 0xff; y = 0.257 * r + 0.504 * g + 0.098 * b; cr = 0.439 * r - 0.368 * g - 0.071 * b + 128; cb = -0.148 * r - 0.291 * g + 0.439 * b + 128; this->hili_color[i] = (y << 16) | (cr << 8) | cb; } for (i = 4; i < 16; i++) this->hili_color[i] = 0x00008080; } static void convert_overlay(spu_encoder_t *this) { int offset = 0, field_start[2]; rle_elem_t *rle; int field, i, len, part, x, y, higher_nibble = 1; /* size will be determined later */ write_byte(this, &offset, 0x00); write_byte(this, &offset, 0x00); /* control sequence pointer will be determined later */ write_byte(this, &offset, 0x00); write_byte(this, &offset, 0x00); for (field = 0; field < 2; field++) { write_byte(this, &offset, 0x00); write_byte(this, &offset, 0x00); lprintf("encoding field %d\n", field); field_start[field] = offset; x = y = 0; for (i = 0, rle = this->overlay->rle; i < this->overlay->num_rle; i++, rle++) { len = rle->len; if ((y & 1) == field) { if (y >= this->overlay->hili_top && y < this->overlay->hili_bottom) { if (x < this->overlay->hili_left) { part = (this->overlay->hili_left - x < len) ? (this->overlay->hili_left - x) : len; write_rle(this, &offset, &higher_nibble, part, this->map[rle->color]); len -= part; x += part; } if (x >= this->overlay->hili_left && x < this->overlay->hili_right) { part = (this->overlay->hili_right - x < len) ? (this->overlay->hili_right - x) : len; write_rle(this, &offset, &higher_nibble, part, this->clip_map[rle->color]); len -= part; x += part; } } write_rle(this, &offset, &higher_nibble, len, this->map[rle->color]); } x += len; if (x >= this->overlay->width) { if ((y & 1) == field && !higher_nibble) write_nibble(this, &offset, &higher_nibble, 0); x = 0; y++; } } } /* we should be byte aligned here */ _x_assert(higher_nibble); /* control sequence starts here */ this->target[2] = offset >> 8; this->target[3] = offset & 0xff; write_byte(this, &offset, 0x00); write_byte(this, &offset, 0x00); /* write pointer to end sequence */ write_byte(this, &offset, this->target[2]); write_byte(this, &offset, this->target[3]); /* write control sequence */ write_byte(this, &offset, 0x00); /* clut indices */ write_byte(this, &offset, 0x03); write_byte(this, &offset, 0x32); write_byte(this, &offset, 0x10); /* alpha information */ write_byte(this, &offset, 0x04); write_nibble(this, &offset, &higher_nibble, this->trans[3] & 0xf); write_nibble(this, &offset, &higher_nibble, this->trans[2] & 0xf); write_nibble(this, &offset, &higher_nibble, this->trans[1] & 0xf); write_nibble(this, &offset, &higher_nibble, this->trans[0] & 0xf); /* on screen position */ lprintf("overlay position: x %d, y %d, width %d, height %d\n", this->overlay->x, this->overlay->y, this->overlay->width, this->overlay->height); write_byte(this, &offset, 0x05); write_byte(this, &offset, this->overlay->x >> 4); write_nibble(this, &offset, &higher_nibble, this->overlay->x & 0xf); write_nibble(this, &offset, &higher_nibble, (this->overlay->x + this->overlay->width - 1) >> 8); write_byte(this, &offset, (this->overlay->x + this->overlay->width - 1) & 0xff); write_byte(this, &offset, this->overlay->y >> 4); write_nibble(this, &offset, &higher_nibble, this->overlay->y & 0xf); write_nibble(this, &offset, &higher_nibble, (this->overlay->y + this->overlay->height - 1) >> 8); write_byte(this, &offset, (this->overlay->y + this->overlay->height - 1) & 0xff); /* field pointers */ write_byte(this, &offset, 0x06); write_byte(this, &offset, field_start[0] >> 8); write_byte(this, &offset, field_start[0] & 0xff); write_byte(this, &offset, field_start[1] >> 8); write_byte(this, &offset, field_start[1] & 0xff); /* end marker */ write_byte(this, &offset, 0xff); if (offset & 1) write_byte(this, &offset, 0xff); /* write size information */ this->size = offset; this->target[0] = offset >> 8; this->target[1] = offset & 0xff; } static void write_rle(spu_encoder_t *this, int *offset, int *higher_nibble, int length, int color) { if (!length) return; length <<= 2; while (length > 0x03fc) { write_nibble(this, offset, higher_nibble, 0x0); write_nibble(this, offset, higher_nibble, 0x3); write_nibble(this, offset, higher_nibble, 0xf); write_nibble(this, offset, higher_nibble, 0xc | color); length -= 0x03fc; } if ((length & ~0xc) == 0) { write_nibble(this, offset, higher_nibble, length | color); return; } if ((length & ~0x3c) == 0) { write_nibble(this, offset, higher_nibble, length >> 4); write_nibble(this, offset, higher_nibble, (length & 0xc) | color); return; } if ((length & ~0xfc) == 0) { write_nibble(this, offset, higher_nibble, 0x0); write_nibble(this, offset, higher_nibble, length >> 4); write_nibble(this, offset, higher_nibble, (length & 0xc) | color); return; } if ((length & ~0x3fc) == 0) { write_nibble(this, offset, higher_nibble, 0x0); write_nibble(this, offset, higher_nibble, length >> 8); write_nibble(this, offset, higher_nibble, (length >> 4) & 0xf); write_nibble(this, offset, higher_nibble, (length & 0xc) | color); return; } _x_assert(length == 0); } static void write_byte(spu_encoder_t *this, int *offset, uint8_t byte) { if (*offset >= this->malloc_size) this->target = realloc(this->target, this->malloc_size += 2048); this->target[(*offset)++] = byte; } static void write_nibble(spu_encoder_t *this, int *offset, int *higher_nibble, uint8_t nibble) { if (*offset >= this->malloc_size) this->target = realloc(this->target, this->malloc_size += 2048); if (*higher_nibble) { this->target[*offset] &= 0x0f; this->target[*offset] |= nibble << 4; *higher_nibble = 0; } else { this->target[*offset] &= 0xf0; this->target[(*offset)++] |= nibble; *higher_nibble = 1; } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/video_out_dxr3.c��������������������������������������������������������������0000644�0001750�0001750�00000156430�14647725152�015445� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* mpeg1 encoding video out plugin for the dxr3. * * modifications to the original dxr3 video out plugin by * Mike Lampard <mlampard at users.sourceforge.net> * this first standalone version by * Harm van der Heijden <hrm at users.sourceforge.net> */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #if defined(__sun) #include <sys/ioccom.h> #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <fcntl.h> #include <errno.h> #include <math.h> #ifdef HAVE_X11 # include <X11/Xlib.h> # include <X11/Xatom.h> # include <X11/Xutil.h> #endif #ifdef HAVE_XINERAMA # include <X11/extensions/Xinerama.h> #endif #define LOG_MODULE "video_out_dxr3" /* #define LOG_VERBOSE */ /* #define LOG */ #define LOG_VID 0 #define LOG_OVR 0 #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/video_out.h> #include "dxr3.h" #include "video_out_dxr3.h" #include "group_dxr3.h" #ifdef HAVE_FFMPEG_AVUTIL_H # include <mem.h> #else # include <libavutil/mem.h> #endif /* the amount of extra time we give the card for decoding */ #define DECODE_PIPE_PREBUFFER 10000 /* plugin class functions */ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const void *visual); /* plugin instance functions */ static uint32_t dxr3_get_capabilities(vo_driver_t *this_gen); static vo_frame_t *dxr3_alloc_frame(vo_driver_t *this_gen); static void dxr3_frame_proc_frame(vo_frame_t *frame_gen); static void dxr3_frame_proc_slice(vo_frame_t *frame_gen, uint8_t **src); static void dxr3_frame_field(vo_frame_t *vo_img, int which_field); static void dxr3_frame_dispose(vo_frame_t *frame_gen); static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags); static void dxr3_overlay_begin(vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed); static void dxr3_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay); static void dxr3_overlay_end(vo_driver_t *this_gen, vo_frame_t *frame_gen); static void dxr3_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen); static int dxr3_redraw_needed(vo_driver_t *this_gen); static int dxr3_get_property(vo_driver_t *this_gen, int property); static int dxr3_set_property(vo_driver_t *this_gen, int property, int value); static void dxr3_get_property_min_max(vo_driver_t *this_gen, int property, int *min, int *max); static int dxr3_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *data); static void dxr3_dispose(vo_driver_t *this_gen); /* overlay helper functions only called once during plugin init */ static void gather_screen_vars(dxr3_driver_t *this, const x11_visual_t *vis); static int dxr3_overlay_read_state(dxr3_overlay_t *this); static int dxr3_overlay_set_keycolor(dxr3_overlay_t *this); static int dxr3_overlay_set_attributes(dxr3_overlay_t *this); /* overlay helper functions */ static void dxr3_overlay_update(dxr3_driver_t *this); static void dxr3_zoomTV(dxr3_driver_t *this); /* config callbacks */ static void dxr3_update_add_bars(void *data, xine_cfg_entry_t *entry); static void dxr3_update_swap_fields(void *data, xine_cfg_entry_t *entry); static void dxr3_update_enhanced_mode(void *this_gen, xine_cfg_entry_t *entry); int dxr3_present(xine_stream_t *stream) { int present = 0; if (stream->video_driver) present = stream->video_driver->dispose == dxr3_dispose; llprintf(LOG_VID, "dxr3 %s\n", present ? "present" : "not present"); return present; } static dxr3_driver_class_t *dxr3_vo_init_plugin(xine_t *xine, const void *visual_gen) { dxr3_driver_class_t *this; (void)visual_gen; this = calloc(1, sizeof(dxr3_driver_class_t)); if (!this) return NULL; this->devnum = xine->config->register_num(xine->config, CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL); this->video_driver_class.open_plugin = dxr3_vo_open_plugin; this->video_driver_class.identifier = DXR3_VO_ID; this->video_driver_class.description = N_("video output plugin displaying images through your DXR3 decoder card"); this->video_driver_class.dispose = default_video_driver_class_dispose; this->xine = xine; this->instance = 0; return this; } #ifdef HAVE_X11 void *dxr3_x11_init_plugin(xine_t *xine, const void *visual_gen) { dxr3_driver_class_t *this = dxr3_vo_init_plugin(xine, visual_gen); if (!this) return NULL; this->visual_type = XINE_VISUAL_TYPE_X11; return &this->video_driver_class; } #endif void *dxr3_aa_init_plugin(xine_t *xine, const void *visual_gen) { dxr3_driver_class_t *this = dxr3_vo_init_plugin(xine, visual_gen); if (!this) return NULL; this->visual_type = XINE_VISUAL_TYPE_AA; return &this->video_driver_class; } static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const void *visual_gen) { dxr3_driver_t *this; dxr3_driver_class_t *class = (dxr3_driver_class_t *)class_gen; config_values_t *config = class->xine->config; char tmpstr[100]; const char *confstr; int encoder, confnum; static const char *available_encoders[SUPPORTED_ENCODER_COUNT + 2]; plugin_node_t *node = NULL; /* unused inside dxr3_lavc_init () anyway... */ int fd_control; static const char *const videoout_modes[] = { "letterboxed tv", "widescreen tv", #ifdef HAVE_X11 "letterboxed overlay", "widescreen overlay", #endif NULL }; static const char *const tv_modes[] = { "ntsc", "pal", "pal60" , "default", NULL }; /* int list_id, list_size; xine_sarray_t *plugin_list; */ if (class->instance) return NULL; snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300-%d", class->devnum); llprintf(LOG_VID, "Entering video init, devname = %s.\n", tmpstr); if ((fd_control = xine_open_cloexec(tmpstr, O_WRONLY)) < 0) { xprintf(class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: Failed to open control device %s (%s)\n"), tmpstr, strerror(errno)); return NULL; } this = calloc(1, sizeof(dxr3_driver_t)); if (!this) { close(fd_control); return NULL; } this->vo_driver.get_capabilities = dxr3_get_capabilities; this->vo_driver.alloc_frame = dxr3_alloc_frame; this->vo_driver.update_frame_format = dxr3_update_frame_format; this->vo_driver.overlay_begin = dxr3_overlay_begin; this->vo_driver.overlay_blend = dxr3_overlay_blend; this->vo_driver.overlay_end = dxr3_overlay_end; this->vo_driver.display_frame = dxr3_display_frame; this->vo_driver.redraw_needed = dxr3_redraw_needed; this->vo_driver.get_property = dxr3_get_property; this->vo_driver.set_property = dxr3_set_property; this->vo_driver.get_property_min_max = dxr3_get_property_min_max; this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange; this->vo_driver.dispose = dxr3_dispose; this->scr = dxr3_scr_init(class->xine); pthread_mutex_init(&this->video_device_lock, NULL); pthread_mutex_init(&this->spu_device_lock, NULL); _x_vo_scale_init(&this->scale, 0, 0, config); _x_alphablend_init(&this->alphablend_extra_data, class->xine); this->fd_control = fd_control; this->fd_spu = -1; this->class = class; this->swap_fields = config->register_bool(config, "dxr3.encoding.swap_fields", 0, _("swap odd and even lines"), _("Swaps the even and odd field of the image.\nEnable this option for " "non-MPEG material which produces a vertical jitter on screen."), 10, dxr3_update_swap_fields, this); this->add_bars = config->register_bool(config, "dxr3.encoding.add_bars", 1, _("add black bars to correct aspect ratio"), _("Adds black bars when the image has an aspect ratio the card cannot " "handle natively."), 20, dxr3_update_add_bars, this); this->enhanced_mode = config->register_bool(config, "dxr3.encoding.alt_play_mode", 1, _("use smooth play mode for mpeg encoder playback"), _("Enabling this option will utilise a smoother play mode for non-MPEG content."), 20, dxr3_update_enhanced_mode, this); snprintf (tmpstr, sizeof(tmpstr), "/dev/em8300_mv-%d", class->devnum); if ((this->fd_video = xine_open_cloexec(tmpstr, O_WRONLY | O_SYNC )) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: Failed to open video device %s (%s)\n"), tmpstr, strerror(errno)); dxr3_dispose(&this->vo_driver); return NULL; } /* close now and and let the decoder/encoder reopen if they want */ close(this->fd_video); this->fd_video = -1; /* which encoder to use? Whadda we got? */ encoder = 0; #if LOG_VID printf("video_out_dxr3: Supported mpeg encoders: "); #endif available_encoders[encoder++] = "libavcodec"; printf("libavcodec, "); #ifdef HAVE_LIBFAME available_encoders[encoder++] = "fame"; #if LOG_VID printf("fame, "); #endif #endif #ifdef HAVE_LIBRTE available_encoders[encoder++] = "rte"; #if LOG_VID printf("rte, "); #endif #endif available_encoders[encoder] = "none"; available_encoders[encoder + 1] = NULL; #if LOG_VID printf("none\n"); #endif if (encoder) { encoder = config->register_enum(config, "dxr3.encoding.encoder", 0, (char **) available_encoders, _("encoder for non mpeg content"), _("Content other than MPEG has to pass an additional reencoding stage, " "because the dxr3 handles only MPEG.\nDepending on what is supported by your xine, " "this setting can be \"fame\", \"rte\", \"libavcodec\" or \"none\".\n" "The \"libavcodec\" encoder makes use of the ffmpeg plugin that already ships with xine, " "so you do not need to install any additional library for that. Even better is that " "libavcodec also provides high quality with low CPU usage. Using \"libavcodec\" is " "therefore strongly suggested.\n\"fame\" and \"rte\" are still there, " "but xine support for them is outdated, so these might fail to work."), 0, NULL, NULL); if ((strcmp(available_encoders[encoder], "libavcodec") == 0) && !dxr3_lavc_init(this, node)) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: Mpeg encoder libavcodec failed to init.\n")); dxr3_dispose(&this->vo_driver); return NULL; } #ifdef HAVE_LIBRTE if ((strcmp(available_encoders[encoder], "rte") == 0) && !dxr3_rte_init(this)) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: Mpeg encoder rte failed to init.\n")); dxr3_dispose(&this->vo_driver); return NULL; } #endif #ifdef HAVE_LIBFAME if ((strcmp(available_encoders[encoder], "fame") == 0) && !dxr3_fame_init(this)) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: Mpeg encoder fame failed to init.\n")); dxr3_dispose(&this->vo_driver); return NULL; } #endif if (strcmp(available_encoders[encoder], "none") == 0) xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: Mpeg encoding disabled.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an encoder.\n")); } else xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: No mpeg encoder compiled in.\n" "video_out_dxr3: that's ok, you don't need it for mpeg video like DVDs, but\n" "video_out_dxr3: you will not be able to play non-mpeg content using this video out\n" "video_out_dxr3: driver. See the README.dxr3 for details on configuring an encoder.\n")); /* init aspect */ this->aspect = dxr3_set_property(&this->vo_driver, VO_PROP_ASPECT_RATIO, XINE_VO_ASPECT_4_3); /* init brightness/contrast/saturation */ dxr3_set_property(&this->vo_driver, VO_PROP_BRIGHTNESS, 500); dxr3_set_property(&this->vo_driver, VO_PROP_CONTRAST , 500); dxr3_set_property(&this->vo_driver, VO_PROP_SATURATION, 500); /* overlay or tvout? */ confnum = config->register_enum(config, "dxr3.output.mode", 0, (char **)videoout_modes, _("video output mode (TV or overlay)"), _("The way the DXR3 outputs the final video can be set here. The individual values are:\n\n" "letterboxed tv\n" "Send video to the TV out connector only. This is the mode used for the standard 4:3 " "television set. Anamorphic (16:9) video will be displayed letterboxed, pan&scan " "material will have the image cropped at the left and right side. This is the common " "setting for TV viewing and acts like a standalone DVD player.\n\n" "widescreen tv\n" "Send video to the tv out connector only. This mode is intended for 16:9 widescreen TV sets. " "Anamorphic and pan&scan content will fill the entire screen, but you have to set the " "TV's aspect ratio manually to 16:9 using your.\n\n" "letterboxed overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly switching " "to TV out by hiding the video window. The overlay will be displayed with black borders " "if it is anamorphic (16:9).\n" "This setting is only useful in the rare case of a DVD subtitle channel that would " "only display properly in letterbox mode. A good example for that are the animated " "commentator's silhouettes on \"Ghostbusters\".\n\n" "widescreen overlay\n" "Overlay Video output on the computer screen with the option of on-the-fly switching " "to TV out by hiding the video window. This is the common variant of DXR3 overlay."), 0, NULL, NULL); if (!(class->visual_type == XINE_VISUAL_TYPE_X11) && confnum > 1) /* no overlay modes when not using X11 -> switch to letterboxed tv */ confnum = 0; llprintf(LOG_VID, "videomode = %s\n", videoout_modes[confnum]); switch (confnum) { case 0: /* letterboxed tv mode */ this->overlay_enabled = 0; this->tv_switchable = 0; /* don't allow on-the-fly switching */ this->widescreen_enabled = 0; break; case 1: /* widescreen tv mode */ this->overlay_enabled = 0; this->tv_switchable = 0; /* don't allow on-the-fly switching */ this->widescreen_enabled = 1; break; #ifdef HAVE_X11 case 2: /* letterboxed overlay mode */ case 3: /* widescreen overlay mode */ llprintf(LOG_VID, "setting up overlay mode\n"); gather_screen_vars(this, visual_gen); this->overlay.xine = this->class->xine; if (dxr3_overlay_read_state(&this->overlay) == 0) { this->overlay_enabled = 1; this->tv_switchable = 1; this->widescreen_enabled = confnum - 2; confstr = config->register_string(config, "dxr3.output.keycolor", "0x80a040", _("overlay colour key value"), _("Hexadecimal RGB value of the key colour.\n" "You can try different values, if you experience windows becoming transparent " "when using DXR3 overlay mode."), 20, NULL, NULL); sscanf(confstr, "%x", &this->overlay.colorkey); confstr = config->register_string(config, "dxr3.output.keycolor_interval", "50.0", _("overlay colour key tolerance"), _("A greater value widens the tolerance for " "the overlay key colour.\nYou can try lower values, if you experience windows " "becoming transparent when using DXR3 overlay mode, but parts of the image borders may " "disappear when using a too low setting."), 20, NULL, NULL); sscanf(confstr, "%f", &this->overlay.color_interval); this->overlay.shrink = config->register_num(config, "dxr3.output.shrink_overlay_area", 0, _("crop the overlay area at top and bottom"), _("Removes one pixel line from the top and bottom of the overlay. Enable this, if " "you see green lines at the top or bottom of the overlay."), 10, NULL, NULL); } else { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: please run autocal, overlay disabled\n")); this->overlay_enabled = 0; this->tv_switchable = 0; this->widescreen_enabled = 0; } #endif } /* init tvmode */ confnum = config->register_enum(config, "dxr3.output.tvmode", 3, (char **)tv_modes, _("preferred tv mode"), _("Selects the TV mode to be used by the DXR3. The values mean:\n\n" "ntsc: NTSC at 60Hz\npal: PAL at 50Hz\npal60: PAL at 60Hz\ndefault: keep the card's setting"), 0, NULL, NULL); switch (confnum) { case 0: /* ntsc */ this->tv_mode = EM8300_VIDEOMODE_NTSC; llprintf(LOG_VID, "setting tv_mode to NTSC\n"); break; case 1: /* pal */ this->tv_mode = EM8300_VIDEOMODE_PAL; llprintf(LOG_VID, "setting tv_mode to PAL 50Hz\n"); break; case 2: /* pal60 */ this->tv_mode = EM8300_VIDEOMODE_PAL60; llprintf(LOG_VID, "setting tv_mode to PAL 60Hz\n"); break; default: this->tv_mode = EM8300_VIDEOMODE_DEFAULT; } if (this->tv_mode != EM8300_VIDEOMODE_DEFAULT) if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode)) xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: setting video mode failed.\n")); #ifdef HAVE_X11 /* initialize overlay */ if (this->overlay_enabled) { em8300_overlay_screen_t scr; int value; XColor dummy; this->overlay.fd_control = this->fd_control; /* allocate keycolor */ this->key.red = ((this->overlay.colorkey >> 16) & 0xff) * 256; this->key.green = ((this->overlay.colorkey >> 8) & 0xff) * 256; this->key.blue = ((this->overlay.colorkey ) & 0xff) * 256; XAllocColor(this->display, DefaultColormap(this->display, 0), &this->key); /* allocate black for output area borders */ XAllocNamedColor(this->display, DefaultColormap(this->display, 0), "black", &this->black, &dummy); /* set the screen */ scr.xsize = this->overlay.screen_xres; scr.ysize = this->overlay.screen_yres; if (ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETSCREEN, &scr)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting the overlay screen failed.\n"); if (dxr3_overlay_set_keycolor(&this->overlay) != 0) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting the overlay key colour failed.\n"); if (dxr3_overlay_set_attributes(&this->overlay) != 0) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting an overlay attribute failed.\n"); /* finally switch to overlay mode */ value = EM8300_OVERLAY_MODE_OVERLAY; if (ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &value) != 0) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: switching to overlay mode failed.\n"); } #endif return &this->vo_driver; } static uint32_t dxr3_get_capabilities(vo_driver_t *this_gen) { (void)this_gen; return VO_CAP_YV12 | VO_CAP_YUY2; } static vo_frame_t *dxr3_alloc_frame(vo_driver_t *this_gen) { dxr3_frame_t *frame; dxr3_driver_t *this = (dxr3_driver_t *)this_gen; frame = calloc(1, sizeof(dxr3_frame_t)); pthread_mutex_init(&frame->vo_frame.mutex, NULL); if (this->enc && this->enc->on_frame_copy) { frame->vo_frame.proc_frame = NULL; frame->vo_frame.proc_slice = dxr3_frame_proc_slice; } else { frame->vo_frame.proc_frame = dxr3_frame_proc_frame; frame->vo_frame.proc_slice = NULL; } frame->vo_frame.field = dxr3_frame_field; frame->vo_frame.dispose = dxr3_frame_dispose; frame->vo_frame.driver = this_gen; return &frame->vo_frame; } static void dxr3_frame_proc_frame(vo_frame_t *frame_gen) { /* we reduce the vpts to give the card some extra decoding time */ if (frame_gen->format != XINE_IMGFMT_DXR3 && !frame_gen->proc_called) frame_gen->vpts -= DECODE_PIPE_PREBUFFER; frame_gen->proc_called = 1; } static void dxr3_frame_proc_slice(vo_frame_t *frame_gen, uint8_t **src) { dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen; dxr3_driver_t *this = (dxr3_driver_t *)frame_gen->driver; /* we reduce the vpts to give the card some extra decoding time */ if (frame_gen->format != XINE_IMGFMT_DXR3 && !frame_gen->proc_called) frame_gen->vpts -= DECODE_PIPE_PREBUFFER; frame_gen->proc_called = 1; if (frame_gen->format != XINE_IMGFMT_DXR3 && this->enc && this->enc->on_frame_copy) this->enc->on_frame_copy(this, frame, src); } static void dxr3_frame_field(vo_frame_t *vo_img, int which_field) { /* dummy function */ (void)vo_img; (void)which_field; } static void dxr3_frame_dispose(vo_frame_t *frame_gen) { dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen; av_free(frame->mem); pthread_mutex_destroy(&frame_gen->mutex); free(frame); } static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen; uint32_t oheight; if (format == XINE_IMGFMT_DXR3) { /* talking to dxr3 decoder */ /* a bit of a hack. we must release the em8300_mv fd for * the dxr3 decoder plugin */ pthread_mutex_lock(&this->video_device_lock); if (this->fd_video >= 0) { metronom_clock_t *clock = this->class->xine->clock; clock->unregister_scr(clock, &this->scr->scr_plugin); close(this->fd_video); this->fd_video = -1; /* inform the encoder on next frame's arrival */ this->need_update = 1; } pthread_mutex_unlock(&this->video_device_lock); /* for mpeg source, we don't have to do much. */ this->video_width = 0; frame->vo_frame.width = width; frame->vo_frame.height = height; frame->vo_frame.ratio = ratio; frame->oheight = height; if (ratio < 1.5) frame->aspect = XINE_VO_ASPECT_4_3; else frame->aspect = XINE_VO_ASPECT_ANAMORPHIC; frame->pan_scan = flags & VO_PAN_SCAN_FLAG; av_freep(&frame->mem); frame->real_base[0] = frame->real_base[1] = frame->real_base[2] = NULL; frame_gen->base[0] = frame_gen->base[1] = frame_gen->base[2] = NULL; return; } /* the following is for the mpeg encoding part only */ if (!this->add_bars) /* don't add black bars; assume source is in 4:3 */ ratio = 4.0/3.0; frame->vo_frame.ratio = ratio; frame->pan_scan = 0; frame->aspect = this->video_aspect; oheight = this->video_oheight; pthread_mutex_lock(&this->video_device_lock); if (this->fd_video < 0) { /* decoder should have released it */ metronom_clock_t *clock = this->class->xine->clock; char tmpstr[128]; int64_t time; /* open the device for the encoder */ snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300_mv-%d", this->class->devnum); if ((this->fd_video = xine_open_cloexec(tmpstr, O_WRONLY)) < 0) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: Failed to open video device %s (%s)\n", tmpstr, strerror(errno)); /* start the scr plugin */ time = clock->get_current_time(clock); this->scr->scr_plugin.start(&this->scr->scr_plugin, time); clock->register_scr(clock, &this->scr->scr_plugin); this->scale.force_redraw = 1; } pthread_mutex_unlock(&this->video_device_lock); if ((this->video_width != width) || (this->video_iheight != height) || (fabs(this->video_ratio - ratio) > 0.01)) { /* try anamorphic */ frame->aspect = XINE_VO_ASPECT_ANAMORPHIC; oheight = (double)height * (ratio / (16.0 / 9.0)) + .5; if (oheight < height) { /* frame too high, try 4:3 */ frame->aspect = XINE_VO_ASPECT_4_3; oheight = (double)height * (ratio / (4.0 / 3.0)) + .5; } if (oheight < height) { /* still too high, use full height */ oheight = height; } /* use next multiple of 16 */ oheight = ((oheight - 1) | 15) + 1; /* Tell the viewers about the aspect ratio stuff. */ if (oheight - height > 0) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: adding %d black lines to get %s aspect ratio.\n", oheight - height, frame->aspect == XINE_VO_ASPECT_4_3 ? "4:3" : "16:9"); /* make top black bar multiple of 16, * so old and new macroblocks overlap */ this->top_bar = ((oheight - height) / 32) * 16; this->video_width = width; this->video_iheight = height; this->video_oheight = oheight; this->video_ratio = ratio; this->video_aspect = frame->aspect; this->scale.force_redraw = 1; this->need_update = 1; if (!this->enc) { /* no encoder plugin! Let's bug the user! */ xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: Need an mpeg encoder to play non-mpeg videos on dxr3\n" "video_out_dxr3: Read the README.dxr3 for details.\n")); } } /* if dimensions changed, we need to re-allocate frame memory */ if ((frame->vo_frame.width != (int)width) || (frame->vo_frame.height != (int)height) || (frame->oheight != oheight) || (frame->vo_frame.format != format)) { av_freep(&frame->mem); if (format == XINE_IMGFMT_YUY2) { int i, image_size; /* calculate pitch and size including black bars */ frame->vo_frame.pitches[0] = 32 * ((width + 15) / 16); image_size = frame->vo_frame.pitches[0] * oheight; /* planar format, only base[0] */ /* add one extra line for field swap stuff */ frame->real_base[0] = frame->mem = av_mallocz(image_size + frame->vo_frame.pitches[0]); /* don't use first line */ frame->real_base[0] += frame->vo_frame.pitches[0]; frame->real_base[1] = frame->real_base[2] = 0; /* fix offset, so the decoder does not see the top black bar */ frame->vo_frame.base[0] = frame->real_base[0] + frame->vo_frame.pitches[0] * this->top_bar; frame->vo_frame.base[1] = frame->vo_frame.base[2] = 0; /* fill with black (yuy2 16,128,16,128,...) */ memset(frame->real_base[0], 128, image_size); /* U and V */ for (i = 0; i < image_size; i += 2) /* Y */ *(frame->real_base[0] + i) = 16; } else { /* XINE_IMGFMT_YV12 */ int image_size_y, image_size_u, image_size_v; /* calculate pitches and sizes including black bars */ frame->vo_frame.pitches[0] = 16*((width + 15) / 16); frame->vo_frame.pitches[1] = 8*((width + 15) / 16); frame->vo_frame.pitches[2] = 8*((width + 15) / 16); image_size_y = frame->vo_frame.pitches[0] * oheight; image_size_u = frame->vo_frame.pitches[1] * ((oheight + 1) / 2); image_size_v = frame->vo_frame.pitches[2] * ((oheight + 1) / 2); /* add one extra line for field swap stuff */ frame->real_base[0] = frame->mem = av_mallocz(image_size_y + frame->vo_frame.pitches[0] + image_size_u + image_size_v); /* don't use first line */ frame->real_base[0] += frame->vo_frame.pitches[0]; frame->real_base[1] = frame->real_base[0] + image_size_y; frame->real_base[2] = frame->real_base[1] + image_size_u; /* fix offsets, so the decoder does not see the top black bar */ frame->vo_frame.base[0] = frame->real_base[0] + frame->vo_frame.pitches[0] * this->top_bar; frame->vo_frame.base[1] = frame->real_base[1] + frame->vo_frame.pitches[1] * this->top_bar / 2; frame->vo_frame.base[2] = frame->real_base[2] + frame->vo_frame.pitches[2] * this->top_bar / 2; /* fill with black (yuv 16,128,128) */ memset(frame->real_base[0], 16, image_size_y); memset(frame->real_base[1], 128, image_size_u); memset(frame->real_base[2], 128, image_size_v); } } if (this->swap_fields != frame->swap_fields) { if (this->swap_fields) frame->vo_frame.base[0] -= frame->vo_frame.pitches[0]; else frame->vo_frame.base[0] += frame->vo_frame.pitches[0]; } frame->vo_frame.width = width; frame->vo_frame.height = height; frame->oheight = oheight; frame->swap_fields = this->swap_fields; } static void dxr3_overlay_begin(vo_driver_t *this_gen, vo_frame_t *frame_gen, int changed) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; /* special treatment is only necessary for mpeg frames */ if (frame_gen->format != XINE_IMGFMT_DXR3) return; if (!this->spu_enc) this->spu_enc = dxr3_spu_encoder_init(); if (!changed) { this->spu_enc->need_reencode = 0; return; } this->spu_enc->need_reencode = 1; this->spu_enc->overlay = NULL; this->alphablend_extra_data.offset_x = frame_gen->overlay_offset_x; this->alphablend_extra_data.offset_y = frame_gen->overlay_offset_y; } static void dxr3_overlay_blend(vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; if (frame_gen->format != XINE_IMGFMT_DXR3) { dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen; if (overlay->rle) { if (frame_gen->format == XINE_IMGFMT_YV12) _x_blend_yuv(frame->vo_frame.base, overlay, frame->vo_frame.width, frame->vo_frame.height, frame->vo_frame.pitches, &this->alphablend_extra_data); else _x_blend_yuy2(frame->vo_frame.base[0], overlay, frame->vo_frame.width, frame->vo_frame.height, frame->vo_frame.pitches[0], &this->alphablend_extra_data); } } else { /* XINE_IMGFMT_DXR3 */ if (!this->spu_enc->need_reencode) return; /* FIXME: we only handle the last overlay because previous ones are simply overwritten */ this->spu_enc->overlay = overlay; } } static void dxr3_overlay_end(vo_driver_t *this_gen, vo_frame_t *frame_gen) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; em8300_button_t btn; char tmpstr[128]; ssize_t written; if (frame_gen->format != XINE_IMGFMT_DXR3) return; if (!this->spu_enc->need_reencode) return; dxr3_spu_encode(this->spu_enc); pthread_mutex_lock(&this->spu_device_lock); /* try to open the dxr3 spu device */ if (this->fd_spu < 0) { snprintf (tmpstr, sizeof(tmpstr), "/dev/em8300_sp-%d", this->class->devnum); if ((this->fd_spu = xine_open_cloexec(tmpstr, O_WRONLY)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: Failed to open spu device %s (%s)\n" "video_out_dxr3: Overlays are not available\n", tmpstr, strerror(errno)); pthread_mutex_unlock(&this->spu_device_lock); return; } } if (!this->spu_enc->overlay) { uint8_t empty_spu[] = { 0x00, 0x26, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x01, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x06, 0x00, 0x04, 0x00, 0x07, 0xFF, 0x00, 0x01, 0x00, 0x20, 0x02, 0xFF }; /* just clear any previous spu */ dxr3_spu_button(this->fd_spu, NULL); if (write(this->fd_spu, empty_spu, sizeof(empty_spu)) != sizeof(empty_spu)) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: spu device write failed (%s)\n", strerror(errno)); } pthread_mutex_unlock(&this->spu_device_lock); return; } /* copy clip palette */ this->spu_enc->color[4] = this->spu_enc->hili_color[0]; this->spu_enc->color[5] = this->spu_enc->hili_color[1]; this->spu_enc->color[6] = this->spu_enc->hili_color[2]; this->spu_enc->color[7] = this->spu_enc->hili_color[3]; /* set palette */ if (dxr3_spu_setpalette(this->fd_spu, this->spu_enc->color)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: failed to set CLUT (%s)\n", strerror(errno)); this->clut_cluttered = 1; /* write spu */ written = write(this->fd_spu, this->spu_enc->target, this->spu_enc->size); if (written < 0) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: spu device write failed (%s)\n", strerror(errno)); else if (written != this->spu_enc->size) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: Could only write %zd of %d spu bytes.\n", written, this->spu_enc->size); /* set clipping */ btn.color = 0x7654; btn.contrast = ((this->spu_enc->hili_trans[3] << 12) & 0xf000) | ((this->spu_enc->hili_trans[2] << 8) & 0x0f00) | ((this->spu_enc->hili_trans[1] << 4) & 0x00f0) | ((this->spu_enc->hili_trans[0] ) & 0x000f); btn.left = this->spu_enc->overlay->x + this->spu_enc->overlay->hili_left; btn.right = this->spu_enc->overlay->x + this->spu_enc->overlay->hili_right - 1; btn.top = this->spu_enc->overlay->y + this->spu_enc->overlay->hili_top; btn.bottom = this->spu_enc->overlay->y + this->spu_enc->overlay->hili_bottom - 2; if (dxr3_spu_button(this->fd_spu, &btn)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set spu button (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->spu_device_lock); } static void dxr3_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen; /* widescreen display does not need any aspect handling */ if (!this->widescreen_enabled) { if (frame->aspect != this->aspect) this->aspect = dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, frame->aspect); if (frame->pan_scan && !this->pan_scan) { #if 0 /* the real pan&scan mode does not work, since when placed here, it * arrives too late for stills */ em8300_register_t reg; reg.microcode_register = 1; reg.reg = 64; reg.val = 8; /* pan&scan mode */ if (!this->overlay_enabled) reg.val |= 1; /* interlaced :( */ ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, ®); #else /* the card needs a break before enabling zoom mode, otherwise it fails * sometimes (like in the initial menu of "Breakfast at Tiffany's" RC2) */ xine_usec_sleep(50000); dxr3_set_property(this_gen, VO_PROP_ZOOM_X, 1); #endif this->pan_scan = 1; } if (!frame->pan_scan && this->pan_scan) { this->pan_scan = 0; dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect); } } #ifdef HAVE_X11 if (this->overlay_enabled) { if (this->scale.force_redraw || this->scale.delivered_width != frame_gen->width || this->scale.delivered_height != (int)frame->oheight || this->scale.delivered_ratio != frame_gen->ratio || this->scale.user_ratio != (this->widescreen_enabled ? frame->aspect : XINE_VO_ASPECT_4_3)) { this->scale.delivered_width = frame_gen->width; this->scale.delivered_height = frame->oheight; this->scale.delivered_ratio = frame_gen->ratio; this->scale.user_ratio = (this->widescreen_enabled ? frame->aspect : XINE_VO_ASPECT_4_3); this->scale.force_redraw = 1; _x_vo_scale_compute_ideal_size(&this->scale); /* prepare the overlay window */ dxr3_overlay_update(this); } } #endif if (frame_gen->format != XINE_IMGFMT_DXR3 && this->enc && this->enc->on_display_frame) { pthread_mutex_lock(&this->video_device_lock); if (this->fd_video < 0) { /* no need to encode, when the device is already reserved for the decoder */ frame_gen->free(frame_gen); } else { uint32_t vpts32 = (uint32_t)(frame_gen->vpts + DECODE_PIPE_PREBUFFER); if (this->need_update) { /* we cannot do this earlier, because vo_frame.duration is only valid here */ if (this->enc && this->enc->on_update_format) { /* set the dxr3 playmode */ if (this->enc->on_update_format(this, frame) && this->enhanced_mode) { em8300_register_t reg; reg.microcode_register = 1; reg.reg = 0; reg.val = MVCOMMAND_SYNC; ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, ®); pthread_mutex_lock(&this->scr->mutex); this->scr->sync = 1; pthread_mutex_unlock(&this->scr->mutex); } } this->need_update = 0; } /* inform the card on the timing */ if (dxr3_video_setpts(this->fd_video, &vpts32)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: set video pts failed (%s)\n", strerror(errno)); /* for non-mpeg, the encoder plugin is responsible for calling * frame_gen->free(frame_gen) ! */ this->enc->on_display_frame(this, frame); } pthread_mutex_unlock(&this->video_device_lock); } else { if (this->need_update) { /* we do not need the mpeg encoders any more */ if (this->enc && this->enc->on_unneeded) this->enc->on_unneeded(this); this->need_update = 0; } frame_gen->free(frame_gen); } } static int dxr3_redraw_needed(vo_driver_t *this_gen) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; #ifdef HAVE_X11 if (this->overlay_enabled) dxr3_overlay_update(this); #endif return 0; } static int dxr3_get_property(vo_driver_t *this_gen, int property) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; switch (property) { case VO_PROP_SATURATION: return this->bcs.saturation; case VO_PROP_CONTRAST: return this->bcs.contrast; case VO_PROP_BRIGHTNESS: return this->bcs.brightness; case VO_PROP_ASPECT_RATIO: return this->aspect; case VO_PROP_COLORKEY: return this->overlay.colorkey; case VO_PROP_ZOOM_X: case VO_PROP_ZOOM_Y: case VO_PROP_TVMODE: return 0; case VO_PROP_WINDOW_WIDTH: return this->scale.gui_width; case VO_PROP_WINDOW_HEIGHT: return this->scale.gui_height; } xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: property %d not implemented.\n", property); return 0; } static int dxr3_set_property(vo_driver_t *this_gen, int property, int value) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; int val, bcs_changed = 0; switch (property) { case VO_PROP_SATURATION: this->bcs.saturation = value; bcs_changed = 1; break; case VO_PROP_CONTRAST: this->bcs.contrast = value; bcs_changed = 1; break; case VO_PROP_BRIGHTNESS: this->bcs.brightness = value; bcs_changed = 1; break; case VO_PROP_ASPECT_RATIO: /* xine-ui increments the value, so we make * just a two value "loop" */ if (this->pan_scan) break; if (this->widescreen_enabled) /* We should send an anamorphic hint to widescreen tvs, so they * can switch to 16:9 mode. But the dxr3 cannot do this. */ break; switch(value) { case XINE_VO_ASPECT_SQUARE: case XINE_VO_ASPECT_4_3: llprintf(LOG_VID, "setting aspect ratio to full\n"); val = EM8300_ASPECTRATIO_4_3; value = XINE_VO_ASPECT_4_3; break; case XINE_VO_ASPECT_ANAMORPHIC: case XINE_VO_ASPECT_DVB: llprintf(LOG_VID, "setting aspect ratio to anamorphic\n"); val = EM8300_ASPECTRATIO_16_9; value = XINE_VO_ASPECT_ANAMORPHIC; } if (ioctl(this->fd_control, EM8300_IOCTL_SET_ASPECTRATIO, &val)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: failed to set aspect ratio (%s)\n", strerror(errno)); this->scale.force_redraw = 1; break; case VO_PROP_COLORKEY: xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: VO_PROP_COLORKEY not implemented!"); this->overlay.colorkey = value; break; case VO_PROP_ZOOM_X: if (value == 1) { llprintf(LOG_VID, "enabling 16:9 zoom\n"); if (!this->widescreen_enabled) { dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, XINE_VO_ASPECT_4_3); if (!this->overlay_enabled) dxr3_zoomTV(this); } else { /* We should send an anamorphic hint to widescreen tvs, so they * can switch to 16:9 mode. But the dxr3 cannot do this. */ } } else if (value == -1) { llprintf(LOG_VID, "disabling 16:9 zoom\n"); dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect); } break; case VO_PROP_TVMODE: if (++this->tv_mode > EM8300_VIDEOMODE_LAST) this->tv_mode = EM8300_VIDEOMODE_PAL; #ifdef LOG switch (this->tv_mode) { case EM8300_VIDEOMODE_PAL: llprintf(LOG_VID, "Changing TVMode to PAL\n"); break; case EM8300_VIDEOMODE_PAL60: llprintf(LOG_VID, "Changing TVMode to PAL60\n"); break; case EM8300_VIDEOMODE_NTSC: llprintf(LOG_VID, "Changing TVMode to NTSC\n"); break; } #endif if (ioctl(this->fd_control, EM8300_IOCTL_SET_VIDEOMODE, &this->tv_mode)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting video mode failed (%s)\n", strerror(errno)); break; } if (bcs_changed) if (ioctl(this->fd_control, EM8300_IOCTL_SETBCS, &this->bcs)) xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: bcs set failed (%s)\n", strerror(errno)); return value; } static void dxr3_get_property_min_max(vo_driver_t *this_gen, int property, int *min, int *max) { (void)this_gen; switch (property) { case VO_PROP_SATURATION: case VO_PROP_CONTRAST: case VO_PROP_BRIGHTNESS: *min = 0; *max = 1000; break; default: *min = 0; *max = 0; } } static int dxr3_gui_data_exchange(vo_driver_t *this_gen, int data_type, void *data) { #ifdef HAVE_X11 dxr3_driver_t *this = (dxr3_driver_t *)this_gen; if (!this->overlay_enabled && !this->tv_switchable) return 0; switch (data_type) { case XINE_GUI_SEND_EXPOSE_EVENT: this->scale.force_redraw = 1; break; case XINE_GUI_SEND_DRAWABLE_CHANGED: this->win = (Drawable)data; XFreeGC(this->display, this->gc); this->gc = XCreateGC(this->display, this->win, 0, NULL); this->aspect = dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect); break; case XINE_GUI_SEND_TRANSLATE_GUI_TO_VIDEO: { int x1, y1, x2, y2; x11_rectangle_t *rect = data; _x_vo_scale_translate_gui2video(&this->scale, rect->x, rect->y, &x1, &y1); _x_vo_scale_translate_gui2video(&this->scale, rect->x + rect->w, rect->y + rect->h, &x2, &y2); rect->x = x1; rect->y = y1 - this->top_bar; rect->w = x2 - x1; rect->h = y2 - y1; if (this->overlay_enabled && this->pan_scan) { /* in this mode, the image is distorted, so we have to modify */ rect->x = rect->x * 3 / 4 + this->scale.delivered_width / 8; rect->w = rect->w * 3 / 4; } } break; case XINE_GUI_SEND_VIDEOWIN_VISIBLE: { long window_showing = (long)data; int val; if (!window_showing) { llprintf(LOG_VID, "Hiding video window and diverting video to TV\n"); val = EM8300_OVERLAY_MODE_OFF; this->overlay_enabled = 0; } else { llprintf(LOG_VID, "Using video window for overlaying video\n"); val = EM8300_OVERLAY_MODE_OVERLAY; this->overlay_enabled = 1; this->scale.force_redraw = 1; } ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &val); this->aspect = dxr3_set_property(this_gen, VO_PROP_ASPECT_RATIO, this->aspect); if (this->pan_scan) dxr3_set_property(this_gen, VO_PROP_ZOOM_X, 1); } break; default: return -1; } #endif return 0; } static void dxr3_dispose(vo_driver_t *this_gen) { dxr3_driver_t *this = (dxr3_driver_t *)this_gen; int val = EM8300_OVERLAY_MODE_OFF; llprintf(LOG_VID, "vo exit called\n"); if (this->enc && this->enc->on_close) this->enc->on_close(this); if(this->overlay_enabled) ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETMODE, &val); if (this->fd_control >= 0) close(this->fd_control); pthread_mutex_lock(&this->spu_device_lock); if (this->fd_spu >= 0) { static const uint8_t empty_spu[] = { 0x00, 0x26, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x01, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x06, 0x00, 0x04, 0x00, 0x07, 0xFF, 0x00, 0x01, 0x00, 0x20, 0x02, 0xFF }; /* clear any remaining spu */ dxr3_spu_button(this->fd_spu, NULL); if (write(this->fd_spu, empty_spu, sizeof(empty_spu)) != sizeof(empty_spu)) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: spu device write failed (%s)\n", strerror(errno)); } close(this->fd_spu); } pthread_mutex_unlock(&this->spu_device_lock); pthread_mutex_destroy(&this->video_device_lock); pthread_mutex_destroy(&this->spu_device_lock); _x_alphablend_free(&this->alphablend_extra_data); if (this->scr) this->scr->scr_plugin.exit(&this->scr->scr_plugin); free(this); } #ifdef HAVE_X11 static void gather_screen_vars(dxr3_driver_t *this, const x11_visual_t *vis) { int scrn; #ifdef HAVE_XINERAMA int screens; int dummy_a, dummy_b; XineramaScreenInfo *screeninfo = NULL; #endif this->win = vis->d; this->display = vis->display; this->scale.user_data = vis->user_data; this->gc = XCreateGC(this->display, this->win, 0, NULL); scrn = DefaultScreen(this->display); #ifdef HAVE_XINERAMA if (XineramaQueryExtension(this->display, &dummy_a, &dummy_b) && (screeninfo = XineramaQueryScreens(this->display, &screens)) && XineramaIsActive(this->display)) { this->overlay.screen_xres = screeninfo[0].width; this->overlay.screen_yres = screeninfo[0].height; } else #endif { this->overlay.screen_xres = DisplayWidth(this->display, scrn); this->overlay.screen_yres = DisplayHeight(this->display, scrn); } this->overlay.screen_depth = DisplayPlanes(this->display, scrn); this->scale.frame_output_cb = (void *)vis->frame_output_cb; llprintf(LOG_OVR, "xres: %d, yres: %d, depth: %d\n", this->overlay.screen_xres, this->overlay.screen_yres, this->overlay.screen_depth); } /* dxr3_overlay_read_state helper structure */ #define TYPE_INT 1 #define TYPE_XINT 2 #define TYPE_COEFF 3 #define TYPE_FLOAT 4 struct lut_entry { const char *name; int type; void *ptr; }; /* dxr3_overlay_read_state helper function */ static int lookup_parameter(struct lut_entry *lut, char *name, void **ptr, int *type) { int i; for (i = 0; lut[i].name; i++) if (strcmp(name, lut[i].name) == 0) { *ptr = lut[i].ptr; *type = lut[i].type; llprintf(LOG_OVR, "found parameter \"%s\"\n", name); return 1; } llprintf(LOG_OVR, "WARNING: unknown parameter \"%s\"\n", name); return 0; } static int dxr3_overlay_read_state(dxr3_overlay_t *this) { char *loc; char *fname, line[256]; FILE *fp; struct lut_entry lut[] = { {"xoffset", TYPE_INT, &this->xoffset}, {"yoffset", TYPE_INT, &this->yoffset}, {"xcorr", TYPE_INT, &this->xcorr}, {"jitter", TYPE_INT, &this->jitter}, {"stability", TYPE_INT, &this->stability}, {"keycolor", TYPE_XINT, &this->colorkey}, {"colcal_upper", TYPE_COEFF, &this->colcal_upper[0]}, {"colcal_lower", TYPE_COEFF, &this->colcal_lower[0]}, {"color_interval", TYPE_FLOAT, &this->color_interval}, {0,0,0} }; char *tok; void *ptr; int type; int j; /* store previous locale */ loc = setlocale(LC_NUMERIC, NULL); /* set C locale for floating point values * (used by .overlay/res file) */ setlocale(LC_NUMERIC, "C"); fname = _x_asprintf("%s/.overlay/res_%dx%dx%d", getenv("HOME"), this->screen_xres, this->screen_yres, this->screen_depth); llprintf(LOG_OVR, "attempting to open %s\n", fname); if (!(fp = fopen(fname, "r"))) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("video_out_dxr3: ERROR Reading overlay init file. Run autocal!\n")); free(fname); return -1; } free(fname); while (!feof(fp)) { if (!fgets(line, 256, fp)) break; tok = strtok(line, " "); if (lookup_parameter(lut, tok, &ptr, &type)) { tok = strtok(NULL, " \n"); switch(type) { case TYPE_INT: sscanf(tok, "%d", (int *)ptr); llprintf(LOG_OVR, "value \"%s\" = %d\n", tok, *(int *)ptr); break; case TYPE_XINT: sscanf(tok, "%x", (int *)ptr); llprintf(LOG_OVR, "value \"%s\" = %d\n", tok, *(int *)ptr); break; case TYPE_FLOAT: sscanf(tok, "%f", (float *)ptr); llprintf(LOG_OVR, "value \"%s\" = %f\n", tok, *(float *)ptr); break; case TYPE_COEFF: for(j = 0; j < 3; j++) { sscanf(tok, "%f", &((struct coeff *)ptr)[j].k); llprintf(LOG_OVR, "value (%d,k) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].k); tok = strtok(NULL, " \n"); sscanf(tok, "%f", &((struct coeff *)ptr)[j].m); llprintf(LOG_OVR, "value (%d,m) \"%s\" = %f\n", j, tok, ((struct coeff *)ptr)[j].m); tok = strtok(NULL, " \n"); } break; } } } fclose(fp); /* restore original locale */ setlocale(LC_NUMERIC, loc); return 0; } /* dxr3_overlay_set_keycolor helper function */ static int col_interp(float x, struct coeff c) { int y; y = rint(x * c.k + c.m); if (y > 255) y = 255; if (y < 0) y = 0; return y; } static int dxr3_overlay_set_keycolor(dxr3_overlay_t *this) { em8300_attribute_t attr; float r = (this->colorkey & 0xff0000) >> 16; float g = (this->colorkey & 0x00ff00) >> 8; float b = (this->colorkey & 0x0000ff); float interval = this->color_interval; int32_t overlay_limit; int ret; llprintf(LOG_OVR, "set_keycolor: r = %f, g = %f, b = %f, interval = %f\n", r, g, b, interval); overlay_limit = /* lower limit */ col_interp(r - interval, this->colcal_lower[0]) << 16 | col_interp(g - interval, this->colcal_lower[1]) << 8 | col_interp(b - interval, this->colcal_lower[2]); llprintf(LOG_OVR, "lower overlay_limit = %d\n", overlay_limit); attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_LOWER; attr.value = overlay_limit; if ((ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: WARNING: error setting overlay lower limit attribute\n"); return ret; } overlay_limit = /* upper limit */ col_interp(r + interval, this->colcal_upper[0]) << 16 | col_interp(g + interval, this->colcal_upper[1]) << 8 | col_interp(b + interval, this->colcal_upper[2]); llprintf(LOG_OVR, "upper overlay_limit = %d\n", overlay_limit); attr.attribute = EM9010_ATTRIBUTE_KEYCOLOR_UPPER; attr.value = overlay_limit; if ((ret = ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr)) < 0) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: WARNING: error setting overlay upper limit attribute\n"); return ret; } static int dxr3_overlay_set_attributes(dxr3_overlay_t *this) { em8300_attribute_t attr; attr.attribute = EM9010_ATTRIBUTE_XOFFSET; attr.value = this->xoffset; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_YOFFSET; attr.value = this->yoffset; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_XCORR; attr.value = this->xcorr; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_STABILITY; attr.value = this->stability; if(ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr) == -1) return -1; attr.attribute = EM9010_ATTRIBUTE_JITTER; attr.value = this->jitter; return ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE, &attr); } static void dxr3_overlay_update(dxr3_driver_t *this) { if (_x_vo_scale_redraw_needed(&this->scale)) { em8300_overlay_window_t win; _x_vo_scale_compute_output_size(&this->scale); /* fill video window with keycolor */ XLockDisplay(this->display); XSetForeground(this->display, this->gc, this->black.pixel); XFillRectangle(this->display, this->win, this->gc, this->scale.gui_x, this->scale.gui_y, this->scale.gui_width, this->scale.gui_height); XSetForeground(this->display, this->gc, this->key.pixel); XFillRectangle(this->display, this->win, this->gc, this->scale.output_xoffset, this->scale.output_yoffset + this->overlay.shrink, this->scale.output_width, this->scale.output_height - 2 * this->overlay.shrink); XFlush(this->display); XUnlockDisplay(this->display); win.xpos = this->scale.output_xoffset + this->scale.gui_win_x; win.ypos = this->scale.output_yoffset + this->scale.gui_win_y; win.width = this->scale.output_width; win.height = this->scale.output_height; if (this->pan_scan) { win.xpos -= win.width / 6; win.width *= 4; win.width /= 3; } /* is some part of the picture visible? */ if (win.xpos + win.width < 0) return; if (win.ypos + win.height < 0) return; if (win.xpos > this->overlay.screen_xres) return; if (win.ypos > this->overlay.screen_yres) return; ioctl(this->fd_control, EM8300_IOCTL_OVERLAY_SETWINDOW, &win); } } #endif static void dxr3_zoomTV(dxr3_driver_t *this) { em8300_register_t frame, visible, update; /* change left bound */ frame.microcode_register = 1; frame.reg = 93; // dicom frame left frame.val = 0x10; visible.microcode_register = 1; visible.reg = 97; // dicom visible left visible.val = 0x10; update.microcode_register = 1; update.reg = 65; // dicom_update update.val = 1; ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &frame); ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &visible); ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &update); /* change right bound */ frame.microcode_register = 1; frame.reg = 94; // dicom frame right frame.val = 0x10; visible.microcode_register = 1; visible.reg = 98; // dicom visible right visible.val = 968; update.microcode_register = 1; update.reg = 65; // dicom_update update.val = 1; ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &frame); ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &visible); ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, &update); } static void dxr3_update_add_bars(void *data, xine_cfg_entry_t *entry) { dxr3_driver_t *this = (dxr3_driver_t *)data; this->add_bars = entry->num_value; xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting add_bars to correct aspect ratio to %s\n", (this->add_bars ? "on" : "off")); } static void dxr3_update_swap_fields(void *data, xine_cfg_entry_t *entry) { dxr3_driver_t *this = (dxr3_driver_t *)data; this->swap_fields = entry->num_value; xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting swap fields to %s\n", (this->swap_fields ? "on" : "off")); } static void dxr3_update_enhanced_mode(void *data, xine_cfg_entry_t *entry) { dxr3_driver_t *this = (dxr3_driver_t *)data; this->enhanced_mode = entry->num_value; xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "video_out_dxr3: setting enhanced encoding playback to %s\n", (this->enhanced_mode ? "on" : "off")); } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/dxr3_mpeg_encoders.c����������������������������������������������������������0000644�0001750�0001750�00000041232�14647725152�016253� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* mpeg encoders for the dxr3 video out plugin. * supports the libfame and librte mpeg encoder libraries. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_LIBRTE # include <unistd.h> # include <rte.h> #endif #ifdef HAVE_LIBFAME # include <fame.h> #endif #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <string.h> #include <dlfcn.h> #include <fcntl.h> #include <errno.h> #include <math.h> #include <unistd.h> #ifdef HAVE_FFMPEG_AVUTIL_H # include <mem.h> #else # include <libavutil/mem.h> #endif #define LOG_MODULE "dxr3_mpeg_encoder" /* #define LOG_VERBOSE */ /* #define LOG */ #include <xine/xineutils.h> #include "video_out_dxr3.h" /* buffer size for encoded mpeg1 stream; will hold one intra frame * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ #define DEFAULT_BUFFER_SIZE 512*1024 #ifdef HAVE_LIBRTE /* initialization function */ int dxr3_rte_init(dxr3_driver_t *drv); /* functions required by encoder api */ static int rte_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame); static int rte_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame); static int rte_on_unneeded(dxr3_driver_t *drv); static int rte_on_close(dxr3_driver_t *drv); /* helper function */ static void mp1e_callback(rte_context *context, void *data, ssize_t size, void *user_data); /* encoder structure */ typedef struct rte_data_s { encoder_data_t encoder_data; rte_context *context; /* handle for encoding */ int width, height; void *rte_ptr; /* buffer maintened by librte */ double rte_bitrate; /* mpeg out bitrate, default 2.3e6 bits/s */ } rte_data_t; #endif #ifdef HAVE_LIBFAME /* initialization function */ int dxr3_fame_init(dxr3_driver_t *drv); /* functions required by encoder api */ static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame); static int fame_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame); static int fame_on_unneeded(dxr3_driver_t *drv); static int fame_on_close(dxr3_driver_t *drv); /* encoder structure */ typedef struct { encoder_data_t encoder_data; fame_context_t *context; /* needed for fame calls */ fame_parameters_t fp; fame_yuv_t yuv; char *buffer; /* temporary buffer for mpeg data */ /* temporary buffer for YUY2->YV12 conversion */ uint8_t *out[3]; /* aligned buffer for YV12 data */ uint8_t *buf; /* base address of YV12 buffer */ } fame_data_t; /* helper function */ static int fame_prepare_frame(fame_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame); #endif #ifdef HAVE_LIBRTE int dxr3_rte_init(dxr3_driver_t *drv) { rte_data_t* this; if (!rte_init()) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, _("dxr3_mpeg_encoder: failed to init librte\n")); return 0; } this = calloc(1, sizeof(rte_data_t)); if (!this) return 0; this->encoder_data.type = ENC_RTE; this->encoder_data.on_update_format = rte_on_update_format; this->encoder_data.on_frame_copy = NULL; this->encoder_data.on_display_frame = rte_on_display_frame; this->encoder_data.on_unneeded = rte_on_unneeded; this->encoder_data.on_close = rte_on_close; this->context = 0; drv->enc = &this->encoder_data; return 1; } static int rte_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) { rte_data_t *this = (rte_data_t *)drv->enc; rte_context *context; rte_codec *codec; double fps; if (this->context) { /* already running */ lprintf("closing current encoding context.\n"); rte_stop(this->context); rte_context_destroy(this->context); this->context = 0; } if ((frame->vo_frame.pitches[0] % 16 != 0) || (frame->oheight % 16 != 0)) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, _("dxr3_mpeg_encoder: rte only handles video dimensions which are multiples of 16\n")); return 0; } this->width = frame->vo_frame.pitches[0]; this->height = frame->oheight; /* create new rte context */ this->context = rte_context_new(this->width, this->height, "mp1e", drv); if (!this->context) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, _("dxr3_mpeg_encoder: failed to get rte context.\n")); return 0; } context = this->context; /* shortcut */ #if LOG_ENC rte_set_verbosity(context, 2); #endif /* get mpeg codec handle */ codec = rte_codec_set(context, RTE_STREAM_VIDEO, 0, "mpeg1_video"); if (!codec) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, _("dxr3_mpeg_encoder: could not create codec.\n")); rte_context_destroy(context); this->context = 0; return 0; } this->rte_bitrate = drv->class->xine->config->register_range(drv->class->xine->config, "dxr3.encoding.rte_bitrate", 10000, 1000, 20000, _("rte mpeg output bitrate (kbit/s)"), _("The bitrate the mpeg encoder library librte should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage."), 10, NULL, NULL); this->rte_bitrate *= 1000; /* config in kbit/s, rte wants bit/s */ /* FIXME: this needs to be replaced with a codec option call. * However, there seems to be none for the colour format! * So we'll use the deprecated set_video_parameters instead. * Alternative is to manually set context->video_format (RTE_YU... ) * and context->video_bytes (= width * height * bytes/pixel) */ rte_set_video_parameters(context, (frame->vo_frame.format == XINE_IMGFMT_YV12 ? RTE_YUV420 : RTE_YUYV), context->width, context->height, context->video_rate, context->output_video_bits, context->gop_sequence); /* Now set a whole bunch of codec options * If I understand correctly, virtual_frame_rate is the frame rate * of the source (can be anything), while coded_frame_rate must be * one of the mpeg1 alloweds */ fps = 90000.0 / frame->vo_frame.duration; if (!rte_option_set(codec, "virtual_frame_rate", fps)) xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: WARNING: rte_option_set failed; virtual_frame_rate = %g.\n", fps); if (!rte_option_set(codec, "coded_frame_rate", fps)) xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: WARNING: rte_option_set failed; coded_frame_rate = %g.\n", fps); if (!rte_option_set(codec, "bit_rate", (int)this->rte_bitrate)) xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: WARNING: rte_option_set failed; bit_rate = %d.\n", (int)this->rte_bitrate); if (!rte_option_set(codec, "gop_sequence", "I")) xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: WARNING: rte_option_set failed; gop_sequence = \"I\".\n"); /* just to be sure, disable motion comp (not needed in I frames) */ if (!rte_option_set(codec, "motion_compensation", 0)) xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: WARNING: rte_option_set failed; motion_compensation = 0.\n"); rte_set_input(context, RTE_VIDEO, RTE_PUSH, FALSE, NULL, NULL, NULL); rte_set_output(context, mp1e_callback, NULL, NULL); if (!rte_init_context(context)) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, _("dxr3_mpeg_encoder: cannot init the context: %s\n"), context->error); rte_context_destroy(context); this->context = 0; return 0; } /* do the sync'ing and start encoding */ if (!rte_start_encoding(context)) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, _("dxr3_mpeg_encoder: cannot start encoding: %s\n"), context->error); rte_context_destroy(context); this->context = 0; return 0; } this->rte_ptr = rte_push_video_data(context, NULL, 0); if (!this->rte_ptr) { xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: failed to get encoder buffer pointer.\n"); return 0; } return 1; } static int rte_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) { int size; rte_data_t* this = (rte_data_t *)drv->enc; if ((this->width == frame->vo_frame.pitches[0]) && (this->height == frame->oheight)) { /* This frame belongs to current context. */ size = frame->vo_frame.pitches[0] * frame->oheight; if (frame->vo_frame.format == XINE_IMGFMT_YV12) xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size * 3/2); else xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size * 2); this->rte_ptr = rte_push_video_data(this->context, this->rte_ptr, frame->vo_frame.vpts / 90000.0); } frame->vo_frame.free(&frame->vo_frame); return 1; } static int rte_on_unneeded(dxr3_driver_t *drv) { rte_data_t *this = (rte_data_t *)drv->enc; if (this->context) { rte_stop(this->context); rte_context_destroy(this->context); this->context = 0; } return 1; } static int rte_on_close(dxr3_driver_t *drv) { rte_on_unneeded(drv); free(drv->enc); drv->enc = 0; return 1; } static void mp1e_callback(rte_context *context, void *data, ssize_t size, void *user_data) { dxr3_driver_t *drv = (dxr3_driver_t *)user_data; char tmpstr[128]; ssize_t written; written = write(drv->fd_video, data, size); if (written < 0) { xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); return; } if (written != size) xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: Could only write %d of %d mpeg bytes.\n", written, size); } #endif #ifdef HAVE_LIBFAME int dxr3_fame_init(dxr3_driver_t *drv) { fame_data_t *this; this = calloc(1, sizeof(fame_data_t)); if (!this) return 0; this->encoder_data.type = ENC_FAME; this->encoder_data.on_update_format = fame_on_update_format; this->encoder_data.on_frame_copy = NULL; this->encoder_data.on_display_frame = fame_on_display_frame; this->encoder_data.on_unneeded = fame_on_unneeded; this->encoder_data.on_close = fame_on_close; this->context = 0; drv->enc = &this->encoder_data; return 1; } static int fame_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) { fame_data_t *this = (fame_data_t *)drv->enc; fame_parameters_t init_fp = FAME_PARAMETERS_INITIALIZER; double fps; av_freep(&this->buf); this->out[0] = this->out[1] = this->out[2] = 0; /* if YUY2 and dimensions changed, we need to re-allocate the * internal YV12 buffer */ if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { int image_size = frame->vo_frame.width * frame->oheight; this->out[0] = this->buf = av_mallocz(image_size * 3/2); this->out[1] = this->out[0] + image_size; this->out[2] = this->out[1] + image_size/4; /* fill with black (yuv 16,128,128) */ memset(this->out[0], 16, image_size); memset(this->out[1], 128, image_size/4); memset(this->out[2], 128, image_size/4); lprintf("Using YUY2->YV12 conversion\n"); } if (this->context) { lprintf("closing current encoding context.\n"); fame_close(this->context); this->context = 0; } this->context = fame_open(); if (!this->context) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, _("dxr3_mpeg_encoder: Couldn't start the FAME library\n")); return 0; } if (!this->buffer) this->buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE); if (!this->buffer) { xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n"); return 0; } this->fp = init_fp; this->fp.quality = drv->class->xine->config->register_range(drv->class->xine->config, "dxr3.encoding.fame_quality", 90, 10, 100, _("fame mpeg encoding quality"), _("The encoding quality of the libfame mpeg encoder library. " "Lower is faster but gives noticeable artifacts. Higher is better but slower."), 10, NULL,NULL); /* the really interesting bit is the quantizer scale. The formula * below is copied from libfame's sources (could be changed in the * future) */ lprintf("quality %d -> quant scale = %d\n", this->fp.quality, 1 + (30 * (100 - this->fp.quality) + 50) / 100); this->fp.width = frame->vo_frame.width; this->fp.height = frame->oheight; this->fp.profile = "mpeg1"; this->fp.coding = "I"; #if LOG_ENC this->fp.verbose = 1; #else this->fp.verbose = 0; #endif /* start guessing the framerate */ fps = 90000.0 / frame->vo_frame.duration; if (fps < 23.988) { /* NTSC-FILM */ lprintf("setting mpeg output framerate to NTSC-FILM (23.976 Hz)\n"); this->fp.frame_rate_num = 24000; this->fp.frame_rate_den = 1001; } else if (fps < 24.5) { /* FILM */ lprintf("setting mpeg output framerate to FILM (24 Hz)\n"); this->fp.frame_rate_num = 24; this->fp.frame_rate_den = 1; } else if (fps < 27.485) { /* PAL */ lprintf("setting mpeg output framerate to PAL (25 Hz)\n"); this->fp.frame_rate_num = 25; this->fp.frame_rate_den = 1; } else { /* NTSC */ lprintf("setting mpeg output framerate to NTSC (29.97 Hz)\n"); this->fp.frame_rate_num = 30000; this->fp.frame_rate_den = 1001; } fame_init (this->context, &this->fp, this->buffer, DEFAULT_BUFFER_SIZE); return 1; } static int fame_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) { fame_data_t *this = (fame_data_t *)drv->enc; ssize_t written; int size; if ((frame->vo_frame.width != this->fp.width) || (frame->oheight != this->fp.height)) { /* probably an old frame for a previous context. ignore it */ frame->vo_frame.free(&frame->vo_frame); return 1; } fame_prepare_frame(this, drv, frame); #ifdef HAVE_NEW_LIBFAME fame_start_frame(this->context, &this->yuv, NULL); size = fame_encode_slice(this->context); fame_end_frame(this->context, NULL); #else size = fame_encode_frame(this->context, &this->yuv, NULL); #endif frame->vo_frame.free(&frame->vo_frame); written = write(drv->fd_video, this->buffer, size); if (written < 0) { xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); return 0; } if (written != size) xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: Could only write %ld of %d mpeg bytes.\n", written, size); return 1; } static int fame_on_unneeded(dxr3_driver_t *drv) { fame_data_t *this = (fame_data_t *)drv->enc; if (this->context) { fame_close(this->context); this->context = 0; } return 1; } static int fame_on_close(dxr3_driver_t *drv) { fame_on_unneeded(drv); free(drv->enc); drv->enc = 0; return 1; } static int fame_prepare_frame(fame_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame) { int i, j, w2; uint8_t *y, *u, *v, *yuy2; if (frame->vo_frame.bad_frame) return 1; if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { /* need YUY2->YV12 conversion */ if (!(this->out[0] && this->out[1] && this->out[2]) ) { xprintf(drv->class->xine, XINE_VERBOSITY_DEBUG, "dxr3_mpeg_encoder: Internal YV12 buffer not created.\n"); return 0; } y = this->out[0] + frame->vo_frame.width * drv->top_bar; u = this->out[1] + (frame->vo_frame.width / 2) * (drv->top_bar / 2); v = this->out[2] + (frame->vo_frame.width / 2) * (drv->top_bar / 2); yuy2 = frame->vo_frame.base[0]; w2 = frame->vo_frame.width / 2; for (i = 0; i < frame->vo_frame.height; i += 2) { for (j = 0; j < w2; j++) { /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */ *(y++) = *(yuy2++); *(u++) = *(yuy2++); *(y++) = *(yuy2++); *(v++) = *(yuy2++); } /* down sampling */ for (j = 0; j < w2; j++) { /* skip every second line for U and V */ *(y++) = *(yuy2++); yuy2++; *(y++) = *(yuy2++); yuy2++; } } /* reset for encoder */ y = this->out[0]; u = this->out[1]; v = this->out[2]; } else { /* YV12 */ y = frame->real_base[0]; u = frame->real_base[1]; v = frame->real_base[2]; } this->yuv.y = y; this->yuv.u = u; this->yuv.v = v; return 1; } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/Makefile.am�������������������������������������������������������������������0000644�0001750�0001750�00000002666�14647725152�014401� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_CPPFLAGS += AM_LDFLAGS = $(xineplug_ldflags) if HAVE_X11 AM_CFLAGS += $(X_CFLAGS) link_x_libs = $(X_LIBS) -lXext endif if HAVE_LIBFAME AM_CFLAGS += $(LIBFAME_CFLAGS) link_fame = $(LIBFAME_LIBS) endif if HAVE_LIBRTE link_rte = -lrte endif if ENABLE_DXR3 if ENABLE_FFMPEG xineplug_LTLIBRARIES = xineplug_dxr3.la endif endif # foo_C[PP]FLAGS supersedes AM_C[PP]FLAGS when it is set somewhere. # This happens without respect to conditionals. # So make sure both alternatives use the same set of vars. # Otherwise, inherited flags may get lost in some cases. if WITH_EXTERNAL_DVDNAV link_dvdnav = $(DVDNAV_LIBS) $(DVDREAD_LIBS) AM_CFLAGS += $(DVDNAV_CFLAGS) $(DVDREAD_CFLAGS) else sources_dvdnav = nav_read.c AM_CPPFLAGS += -I$(top_srcdir)/src/input/libdvdnav endif xineplug_dxr3_la_SOURCES = \ $(sources_dvdnav) \ compat.c \ ffmpeg_encoder.c \ group_dxr3.c \ group_dxr3.h \ dxr3.h \ dxr3_decode_spu.c \ dxr3_decode_video.c \ dxr3_mpeg_encoders.c \ dxr3_scr.c \ dxr3_scr.h \ dxr3_spu_encoder.c \ em8300.h \ video_out_dxr3.c \ video_out_dxr3.h xineplug_dxr3_la_CFLAGS = $(AM_CFLAGS) $(AVUTIL_CFLAGS) $(FFMPEG_CFLAGS) xineplug_dxr3_la_LIBADD = $(XINE_LIB) $(link_fame) $(link_rte) $(link_x_libs) $(link_dvdnav) $(LTLIBINTL) $(AVUTIL_LIBS) $(FFMPEG_LIBS) -lm xineplug_dxr3_la_CPPFLAGS = $(AM_CPPFLAGS) ��������������������������������������������������������������������������xine-lib-1.2/src/dxr3/group_dxr3.c������������������������������������������������������������������0000644�0001750�0001750�00000004450�14647725152�014576� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * This file contains plugin entries for several demuxers used in games */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include <xine/xine_plugin.h> #include "group_dxr3.h" /* * exported plugin catalog entries */ static const uint32_t supported_types_spu[] = { BUF_SPU_DVD, 0, }; static const decoder_info_t dxr3_spudec_info = { .supported_types = supported_types_spu, .priority = 10, }; static const uint32_t supported_types_video[] = { BUF_VIDEO_MPEG, 0, }; static const decoder_info_t dxr3_video_decoder_info = { .supported_types = supported_types_video, .priority = 10, }; #ifdef HAVE_X11 static const vo_info_t vo_info_dxr3_x11 = { .priority = 10, .visual_type = XINE_VISUAL_TYPE_X11, }; #endif static const vo_info_t vo_info_dxr3_aa = { .priority = 10, .visual_type = XINE_VISUAL_TYPE_AA, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "dxr3-mpeg2", XINE_VERSION_CODE, &dxr3_video_decoder_info, &dxr3_video_init_plugin }, { PLUGIN_SPU_DECODER, 17, "dxr3-spudec", XINE_VERSION_CODE, &dxr3_spudec_info, &dxr3_spudec_init_plugin }, #ifdef HAVE_X11 { PLUGIN_VIDEO_OUT, 22, "dxr3", XINE_VERSION_CODE, &vo_info_dxr3_x11, &dxr3_x11_init_plugin }, #endif { PLUGIN_VIDEO_OUT, 22, "aadxr3", XINE_VERSION_CODE, &vo_info_dxr3_aa, &dxr3_aa_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/video_out_dxr3.h��������������������������������������������������������������0000644�0001750�0001750�00000013573�14647725152�015452� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included #endif #ifdef HAVE_X11 # include <X11/Xlib.h> #endif #include <xine/xine_internal.h> #include <xine/vo_scale.h> #include "dxr3_scr.h" #include "dxr3.h" /* the number of supported encoders */ #define SUPPORTED_ENCODER_COUNT 3 /* plugin structures */ typedef struct encoder_data_s encoder_data_t; typedef struct spu_encoder_s spu_encoder_t; typedef enum { ENC_FAME, ENC_RTE, ENC_LAVC } encoder_type; struct coeff { float k,m; }; typedef struct dxr3_overlay_s { xine_t *xine; int fd_control; int xoffset; int yoffset; int xcorr; int jitter; int stability; int colorkey; float color_interval; int screen_xres; int screen_yres; int screen_depth; int shrink; struct coeff colcal_upper[3]; struct coeff colcal_lower[3]; } dxr3_overlay_t; typedef struct dxr3_driver_class_s { video_driver_class_t video_driver_class; xine_t *xine; int visual_type; int instance; /* we allow only one instance of this plugin */ int devnum; } dxr3_driver_class_t; typedef struct dxr3_driver_s { vo_driver_t vo_driver; dxr3_driver_class_t *class; dxr3_scr_t *scr; /* to provide dxr3 clocking */ int fd_control; pthread_mutex_t video_device_lock; int fd_video; pthread_mutex_t spu_device_lock; int fd_spu; /* to access the relevant dxr3 devices */ int clut_cluttered; /* to tell spu decoder that it has to restore the palette */ int enhanced_mode; int swap_fields; /* swap fields */ int add_bars; /* add black bars to correct a.r. */ int aspect; int tv_mode; int pan_scan; int overlay_enabled; int tv_switchable; /* can switch from overlay<->tvout */ int widescreen_enabled; em8300_bcs_t bcs; encoder_data_t *enc; /* mpeg encoder data */ spu_encoder_t *spu_enc; /* spu encoder */ int need_update; /* the mpeg encoder needs to be updated */ uint32_t video_iheight; /* input height (before adding black bars) */ uint32_t video_oheight; /* output height (after adding black bars) */ uint32_t video_width; double video_ratio; int video_aspect; int top_bar; /* the height of the upper black bar */ vo_scale_t scale; alphablend_t alphablend_extra_data; dxr3_overlay_t overlay; #ifdef HAVE_X11 Display *display; Drawable win; GC gc; XColor black; XColor key; #endif } dxr3_driver_t; typedef struct dxr3_frame_s { vo_frame_t vo_frame; uint32_t oheight; int aspect, pan_scan; void *mem; /* allocated for YV12 or YUY2 buffers */ uint8_t *real_base[3]; /* yuv/yuy2 buffers in mem aligned on 16 */ int swap_fields; /* shifts Y buffer one line to exchange odd/even lines */ } dxr3_frame_t; struct encoder_data_s { encoder_type type; int (*on_update_format)(dxr3_driver_t *, dxr3_frame_t *); int (*on_frame_copy)(dxr3_driver_t *, dxr3_frame_t *, uint8_t **src); int (*on_display_frame)(dxr3_driver_t *, dxr3_frame_t *); int (*on_unneeded)(dxr3_driver_t *); int (*on_close)(dxr3_driver_t *); /* this is only used by the libavcodec encoder */ void *handle; }; struct spu_encoder_s { vo_overlay_t *overlay; int need_reencode; uint8_t *target; int size; int malloc_size; uint32_t color[16]; uint8_t trans[4]; int map[OVL_PALETTE_SIZE]; uint32_t hili_color[16]; uint8_t hili_trans[4]; int clip_map[OVL_PALETTE_SIZE]; }; /* mpeg encoder plugins initialization functions */ #ifdef HAVE_LIBRTE int dxr3_rte_init(dxr3_driver_t *); #endif #ifdef HAVE_LIBFAME int dxr3_fame_init(dxr3_driver_t *); #endif int dxr3_lavc_init(dxr3_driver_t *, plugin_node_t *); /* spu encoder functions */ spu_encoder_t *dxr3_spu_encoder_init(void); void dxr3_spu_encode(spu_encoder_t *); #define dxr3_video_setpts(fd,arg) dxr3_compat_ioctl((fd), EM8300_IOCTL_VIDEO_SETPTS, (arg)) #define dxr3_spu_setpts(fd,arg) dxr3_compat_ioctl((fd), EM8300_IOCTL_SPU_SETPTS, (arg)) #define dxr3_spu_setpalette(fd,arg) dxr3_compat_ioctl((fd), EM8300_IOCTL_SPU_SETPALETTE, (arg)) #define dxr3_spu_button(fd,arg) dxr3_compat_ioctl((fd), EM8300_IOCTL_SPU_BUTTON, (arg)) int dxr3_compat_ioctl (int, int, void *); �������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/dxr3_scr.c��������������������������������������������������������������������0000644�0001750�0001750�00000016727�14647725152�014243� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* dxr3 scr plugin. * enables xine to use the internal clock of the card as its * global time reference. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <sys/ioctl.h> #if defined(__sun) #include <sys/ioccom.h> #endif #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <pthread.h> #include <errno.h> #define LOG_MODULE "dxr3_scr" /* #define LOG_VERBOSE */ /* #define LOG */ #include "dxr3.h" #include "dxr3_scr.h" /* functions required by xine api */ static int dxr3_scr_get_priority(scr_plugin_t *scr); static void dxr3_scr_start(scr_plugin_t *scr, int64_t vpts); static int64_t dxr3_scr_get_current(scr_plugin_t *scr); static void dxr3_scr_adjust(scr_plugin_t *scr, int64_t vpts); static int dxr3_scr_set_speed(scr_plugin_t *scr, int speed); static void dxr3_scr_exit(scr_plugin_t *scr); /* config callback */ static void dxr3_scr_update_priority(void *this_gen, xine_cfg_entry_t *entry); /* inline helper implementations */ static inline int dxr3_mvcommand(int fd_control, int command) { em8300_register_t reg; reg.microcode_register = 1; reg.reg = 0; reg.val = command; return ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®); } dxr3_scr_t *dxr3_scr_init(xine_t *xine) { dxr3_scr_t *this; int devnum; char tmpstr[128]; this = calloc(1, sizeof(dxr3_scr_t)); if (!this) return NULL; devnum = xine->config->register_num(xine->config, CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL); snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300-%d", devnum); if ((this->fd_control = xine_open_cloexec(tmpstr, O_WRONLY)) < 0) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: Failed to open control device %s (%s)\n", tmpstr, strerror(errno)); free(this); return NULL; } this->xine = xine; this->scr_plugin.interface_version = 3; this->scr_plugin.get_priority = dxr3_scr_get_priority; this->scr_plugin.start = dxr3_scr_start; this->scr_plugin.get_current = dxr3_scr_get_current; this->scr_plugin.adjust = dxr3_scr_adjust; this->scr_plugin.set_fine_speed = dxr3_scr_set_speed; this->scr_plugin.exit = dxr3_scr_exit; this->priority = xine->config->register_num( xine->config, "dxr3.scr_priority", 10, _("SCR plugin priority"), _("Priority of the DXR3 SCR plugin. Values less than 5 mean that the " "unix system timer will be used. Values greater 5 force to use " "DXR3's internal clock as sync source."), 25, dxr3_scr_update_priority, this); this->offset = 0; this->last_pts = 0; this->scanning = 0; this->sync = 0; pthread_mutex_init(&this->mutex, NULL); lprintf("init complete\n"); return this; } static int dxr3_scr_get_priority(scr_plugin_t *scr) { dxr3_scr_t *this = (dxr3_scr_t *)scr; return this->priority; } static void dxr3_scr_start(scr_plugin_t *scr, int64_t vpts) { dxr3_scr_t *this = (dxr3_scr_t *)scr; uint32_t vpts32 = vpts >> 1; pthread_mutex_lock(&this->mutex); this->last_pts = vpts32; this->offset = vpts - ((int64_t)vpts32 << 1); if (ioctl(this->fd_control, EM8300_IOCTL_SCR_SET, &vpts32)) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: start failed (%s)\n", strerror(errno)); lprintf("started with vpts %" PRId64 "\n", vpts); /* mis-use vpts32 to set the clock speed to 0x900, which is normal speed */ vpts32 = 0x900; ioctl(this->fd_control, EM8300_IOCTL_SCR_SETSPEED, &vpts32); this->scanning = 0; this->sync = 0; pthread_mutex_unlock(&this->mutex); } static int64_t dxr3_scr_get_current(scr_plugin_t *scr) { dxr3_scr_t *this = (dxr3_scr_t *)scr; uint32_t pts; int64_t current; pthread_mutex_lock(&this->mutex); if (ioctl(this->fd_control, EM8300_IOCTL_SCR_GET, &pts)) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: get current failed (%s)\n", strerror(errno)); if (this->last_pts > 0xF0000000 && pts < 0x10000000) /* wrap around detected, compensate with offset */ this->offset += (int64_t)1 << 33; if (pts == 0) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: WARNING: pts dropped to zero.\n"); this->last_pts = pts; current = ((int64_t)pts << 1) + this->offset; pthread_mutex_unlock(&this->mutex); return current; } static void dxr3_scr_adjust(scr_plugin_t *scr, int64_t vpts) { dxr3_scr_t *this = (dxr3_scr_t *)scr; uint32_t current_pts32; int32_t offset32; pthread_mutex_lock(&this->mutex); if (ioctl(this->fd_control, EM8300_IOCTL_SCR_GET, ¤t_pts32)) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: adjust get failed (%s)\n", strerror(errno)); this->last_pts = current_pts32; this->offset = vpts - ((int64_t)current_pts32 << 1); offset32 = this->offset / 4; /* kernel driver ignores diffs < 7200, so abs(offset32) must be > 7200 / 4 */ if (offset32 < -7200/4 || offset32 > 7200/4) { uint32_t vpts32 = vpts >> 1; if (ioctl(this->fd_control, EM8300_IOCTL_SCR_SET, &vpts32)) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: adjust set failed (%s)\n", strerror(errno)); this->last_pts = vpts32; this->offset = vpts - ((int64_t)vpts32 << 1); } lprintf("adjusted to vpts %" PRId64 "\n", vpts); pthread_mutex_unlock(&this->mutex); } static int dxr3_scr_set_speed(scr_plugin_t *scr, int speed) { dxr3_scr_t *this = (dxr3_scr_t *)scr; uint32_t em_speed; int playmode; pthread_mutex_lock(&this->mutex); em_speed = 0x900LL * (int64_t)speed / XINE_FINE_SPEED_NORMAL; switch (em_speed) { case 0: /* pause mode */ playmode = MVCOMMAND_PAUSE; break; case 0x900: /* normal playback */ if (this->sync) playmode = MVCOMMAND_SYNC; else playmode = MVCOMMAND_START; break; default: playmode = MVCOMMAND_START; } if (dxr3_mvcommand(this->fd_control, playmode)) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: failed to playmode (%s)\n", strerror(errno)); if(em_speed > 0x900) this->scanning = 1; else this->scanning = 0; if (ioctl(this->fd_control, EM8300_IOCTL_SCR_SETSPEED, &em_speed)) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: failed to set speed (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->mutex); lprintf("speed set to mode %d\n", speed); return speed; } static void dxr3_scr_exit(scr_plugin_t *scr) { dxr3_scr_t *this = (dxr3_scr_t *)scr; close(this->fd_control); pthread_mutex_destroy(&this->mutex); free(this); } static void dxr3_scr_update_priority(void *this_gen, xine_cfg_entry_t *entry) { dxr3_scr_t *this = (dxr3_scr_t *)this_gen; this->priority = entry->num_value; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "dxr3_scr: setting scr priority to %d\n", entry->num_value); } �����������������������������������������xine-lib-1.2/src/dxr3/em8300.h����������������������������������������������������������������������0000644�0001750�0001750�00000040162�14647725152�013423� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * em8300.h * * Copyright (C) 2000 Henrik Johansson <lhj@users.sourceforge.net> * (C) 2000 Ze'ev Maor <zeev@users.sourceforge.net> * (C) 2001 Rick Haines <rick@kuroyi.net> * (C) 2001 Edward Salley <drawdeyellas@hotmail.com> * (C) 2001 Jeremy T. Braun <jtbraun@mmit.edu> * (C) 2001 Ralph Zimmermann <rz@ooe.net> * (C) 2001 Daniel Chassot <Daniel.Chassot@vibro-meter.com> * (C) 2002 Michael Hunold <michael@mihu.de> * (C) 2002-2003 David Holm <mswitch@users.sourceforge.net> * (C) 2003-2008 Nicolas Boullis <nboullis@debian.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef LINUX_EM8300_H #define LINUX_EM8300_H typedef struct { void *ucode; int ucode_size; } em8300_microcode_t; typedef struct { int reg; int val; int microcode_register; } em8300_register_t; typedef struct { int brightness; int contrast; int saturation; } em8300_bcs_t; typedef struct { int cal_mode; int arg; int arg2; int result; int result2; } em8300_overlay_calibrate_t; typedef struct { int xpos, ypos; int width, height; } em8300_overlay_window_t; typedef struct { int xsize, ysize; } em8300_overlay_screen_t; typedef struct { int attribute; int value; } em8300_attribute_t; typedef struct { int color; int contrast; int top; int bottom; int left; int right; } em8300_button_t; #define MAX_UCODE_REGISTER 110 #define EM8300_IOCTL_INIT _IOW('C',0,em8300_microcode_t) #define EM8300_IOCTL_READREG _IOWR('C',1,em8300_register_t) #define EM8300_IOCTL_WRITEREG _IOW('C',2,em8300_register_t) #define EM8300_IOCTL_GETSTATUS _IOR('C',3,char[1024]) #define EM8300_IOCTL_SETBCS _IOW('C',4,em8300_bcs_t) #define EM8300_IOCTL_GETBCS _IOR('C',4,em8300_bcs_t) #define EM8300_IOCTL_SET_ASPECTRATIO _IOW('C',5,int) #define EM8300_IOCTL_GET_ASPECTRATIO _IOR('C',5,int) #define EM8300_IOCTL_SET_VIDEOMODE _IOW('C',6,int) #define EM8300_IOCTL_GET_VIDEOMODE _IOR('C',6,int) #define EM8300_IOCTL_SET_PLAYMODE _IOW('C',7,int) #define EM8300_IOCTL_GET_PLAYMODE _IOR('C',7,int) #define EM8300_IOCTL_SET_AUDIOMODE _IOW('C',8,int) #define EM8300_IOCTL_GET_AUDIOMODE _IOR('C',8,int) #define EM8300_IOCTL_SET_SPUMODE _IOW('C',9,int) #define EM8300_IOCTL_GET_SPUMODE _IOR('C',9,int) #define EM8300_IOCTL_OVERLAY_CALIBRATE _IOWR('C',10,em8300_overlay_calibrate_t) #define EM8300_IOCTL_OVERLAY_SETMODE _IOW('C',11,int) #define EM8300_IOCTL_OVERLAY_SETWINDOW _IOWR('C',12,em8300_overlay_window_t) #define EM8300_IOCTL_OVERLAY_SETSCREEN _IOWR('C',13,em8300_overlay_screen_t) #define EM8300_IOCTL_OVERLAY_GET_ATTRIBUTE _IOR('C',14,em8300_attribute_t) #define EM8300_IOCTL_OVERLAY_SET_ATTRIBUTE _IOW('C',14,em8300_attribute_t) #define EM8300_IOCTL_OVERLAY_SIGNALMODE _IOW('C',15,em8300_attribute_t) #define EM8300_IOCTL_SCR_GET _IOR('C',16,unsigned) #define EM8300_IOCTL_SCR_SET _IOW('C',16,unsigned) #define EM8300_IOCTL_SCR_GETSPEED _IOR('C',17,unsigned) #define EM8300_IOCTL_SCR_SETSPEED _IOW('C',17,unsigned) #define EM8300_IOCTL_FLUSH _IOW('C',18,int) #define EM8300_IOCTL_VBI _IOW('C',19,struct timeval) #define EM8300_OVERLAY_SIGNAL_ONLY 1 #define EM8300_OVERLAY_SIGNAL_WITH_VGA 2 #define EM8300_OVERLAY_VGA_ONLY 3 #define EM8300_IOCTL_VIDEO_SETPTS _IOW('C',1,int) #define EM8300_IOCTL_VIDEO_GETSCR _IOR('C',2,unsigned) #define EM8300_IOCTL_VIDEO_SETSCR _IOW('C',2,unsigned) #define EM8300_IOCTL_SPU_SETPTS _IOW('C',1,int) #define EM8300_IOCTL_SPU_SETPALETTE _IOW('C',2,unsigned[16]) #define EM8300_IOCTL_SPU_BUTTON _IOW('C',3,em8300_button_t) #define EM8300_ASPECTRATIO_4_3 0 #define EM8300_ASPECTRATIO_16_9 1 #define EM8300_ASPECTRATIO_LAST 1 #define EM8300_VIDEOMODE_PAL 0 #define EM8300_VIDEOMODE_PAL60 1 #define EM8300_VIDEOMODE_NTSC 2 #define EM8300_VIDEOMODE_LAST 2 #ifndef EM8300_VIDEOMODE_DEFAULT #define EM8300_VIDEOMODE_DEFAULT EM8300_VIDEOMODE_PAL #endif #define EM8300_AUDIOMODE_ANALOG 0 #define EM8300_AUDIOMODE_DIGITALPCM 1 #define EM8300_AUDIOMODE_DIGITALAC3 2 #ifndef EM8300_AUDIOMODE_DEFAULT #define EM8300_AUDIOMODE_DEFAULT EM8300_AUDIOMODE_ANALOG #endif #define EM8300_SPUMODE_OFF 0 #define EM8300_SPUMODE_ON 1 #define EM8300_PLAYMODE_STOPPED 0 #define EM8300_PLAYMODE_PAUSED 1 #define EM8300_PLAYMODE_SLOWFORWARDS 2 #define EM8300_PLAYMODE_SLOWBACKWARDS 3 #define EM8300_PLAYMODE_SINGLESTEP 4 #define EM8300_PLAYMODE_PLAY 5 #define EM8300_PLAYMODE_REVERSEPLAY 6 #define EM8300_PLAYMODE_SCAN 7 #define EM8300_PLAYMODE_FRAMEBUF 8 #define EM8300_OVERLAY_MODE_OFF 0 #define EM8300_OVERLAY_MODE_RECTANGLE 1 #define EM8300_OVERLAY_MODE_OVERLAY 2 #define EM8300_OVERLAY_CALMODE_XOFFSET 1 #define EM8300_OVERLAY_CALMODE_YOFFSET 2 #define EM8300_OVERLAY_CALMODE_XCORRECTION 3 #define EM8300_OVERLAY_CALMODE_COLOR 4 #define EM9010_ATTRIBUTE_XCORR 1 #define EM9010_ATTRIBUTE_XOFFSET 2 #define EM9010_ATTRIBUTE_YOFFSET 3 #define EM9010_ATTRIBUTE_JITTER 4 #define EM9010_ATTRIBUTE_STABILITY 5 #define EM9010_ATTRIBUTE_KEYCOLOR_UPPER 6 #define EM9010_ATTRIBUTE_KEYCOLOR_LOWER 7 #define EM9010_ATTRIBUTE_MAX 7 #define EM8300_SUBDEVICE_CONTROL 0 #define EM8300_SUBDEVICE_VIDEO 1 #define EM8300_SUBDEVICE_AUDIO 2 #define EM8300_SUBDEVICE_SUBPICTURE 3 #ifndef PCI_VENDOR_ID_SIGMADESIGNS #define PCI_VENDOR_ID_SIGMADESIGNS 0x1105 #define PCI_DEVICE_ID_SIGMADESIGNS_EM8300 0x8300 #endif #define CLOCKGEN_SAMPFREQ_MASK 0xc0 #define CLOCKGEN_SAMPFREQ_66 0xc0 #define CLOCKGEN_SAMPFREQ_48 0x40 #define CLOCKGEN_SAMPFREQ_44 0x80 #define CLOCKGEN_SAMPFREQ_32 0x00 #define CLOCKGEN_OUTMASK 0x30 #define CLOCKGEN_DIGITALOUT 0x10 #define CLOCKGEN_ANALOGOUT 0x20 #define CLOCKGEN_MODEMASK 0x0f #define CLOCKGEN_OVERLAYMODE_1 0x07 #define CLOCKGEN_TVMODE_1 0x0b #define CLOCKGEN_OVERLAYMODE_2 0x04 #define CLOCKGEN_TVMODE_2 0x02 #define MVCOMMAND_STOP 0x0 #define MVCOMMAND_PAUSE 0x1 #define MVCOMMAND_START 0x3 #define MVCOMMAND_PLAYINTRA 0x4 #define MVCOMMAND_SYNC 0x6 #define MVCOMMAND_FLUSHBUF 0x10 #define MVCOMMAND_DISPLAYBUFINFO 0x11 #define MACOMMAND_STOP 0x0 #define MACOMMAND_PAUSE 0x1 #define MACOMMAND_PLAY 0x2 #define IRQSTATUS_VIDEO_VBL 0x10 #define IRQSTATUS_VIDEO_FIFO 0x2 #define IRQSTATUS_AUDIO_FIFO 0x8 #define ENCODER_UNKNOWN 0 #define ENCODER_ADV7175 1 #define ENCODER_ADV7170 2 #define ENCODER_BT865 3 #ifdef __KERNEL__ #define EM8300_MAX 4 #define EM8300_MAJOR 121 #define EM8300_LOGNAME "em8300" extern int major; #include <linux/version.h> #include <linux/types.h> /* ulong, uint32_t */ #include <linux/i2c.h> /* struct i2c_adapter */ #include <linux/i2c-algo-bit.h> /* struct i2c_algo_bit_data */ #include <linux/time.h> /* struct timeval */ #include <linux/wait.h> /* wait_queue_head_t */ #include <linux/list.h> /* struct list_head */ #if defined(CONFIG_SND) || defined(CONFIG_SND_MODULE) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) #define snd_card_t struct snd_card #else #include <sound/driver.h> #include <sound/core.h> #include <sound/pcm.h> #endif #endif struct dicom_s { int luma; int chroma; int frametop; int framebottom; int frameleft; int frameright; int visibletop; int visiblebottom; int visibleleft; int visibleright; int tvout; }; struct displaybuffer_info_s { int xsize; int ysize; int xsize2; int flag1,flag2; int buffer1; int buffer2; int unk_present; int unknown1; int unknown2; int unknown3; }; struct em8300_audio_s { int channels; int format; int speed; int slotsize; int enable_bits; }; struct em8300_model_config_s { int use_bt865; int dicom_other_pal; int dicom_fix; int dicom_control; int bt865_ucode_timeout; int activate_loopback; }; struct adv717x_model_config_s { int pixelport_16bit; int pixelport_other_pal; int pixeldata_adjust_ntsc; int pixeldata_adjust_pal; }; struct bt865_model_config_s { }; struct em8300_config_s { struct em8300_model_config_s model; struct adv717x_model_config_s adv717x_model; struct bt865_model_config_s bt865_model; }; struct em8300_s { char name[40]; int chip_revision; int pci_revision; int inuse[4]; int nonblock[4]; int ucodeloaded; struct pci_dev *dev; ulong adr; volatile unsigned *mem; ulong memsize; int playmode; #if defined(CONFIG_SND) || defined(CONFIG_SND_MODULE) snd_card_t *alsa_card; #endif /* Fifos */ struct fifo_s *mvfifo; struct fifo_s *mafifo; struct fifo_s *spfifo; int mtrr_reg; /* DICOM */ int dicom_vertoffset; int dicom_horizoffset; int dicom_brightness; int dicom_contrast; int dicom_saturation; int dicom_tvout; struct displaybuffer_info_s dbuf_info; /* I2C */ int i2c_pin_reg; int i2c_oe_reg; /* different between revision 1 and revision 2 boards */ int mystery_divisor; /* I2C bus 1*/ struct i2c_algo_bit_data i2c_data_1; struct i2c_adapter i2c_ops_1; /* I2C bus 2*/ struct i2c_algo_bit_data i2c_data_2; struct i2c_adapter i2c_ops_2; /* I2C clients */ int encoder_type; struct i2c_client *encoder; struct i2c_client *eeprom; /* Microcode registers */ unsigned ucode_regs[MAX_UCODE_REGISTER]; int var_ucode_reg1; /* These are registers that differ */ int var_ucode_reg2; /* between versions 1 and 2 of the board */ int var_ucode_reg3; /* " */ /* Interrupt */ unsigned irqmask; /* Clockgenerator */ int clockgen; int clockgen_overlaymode; int clockgen_tvmode; /* Timing measurement */ struct timeval tv, last_status_time; long irqtimediff; int irqcount; int frames; int scr; /* Audio */ struct em8300_audio_s audio; int audio_mode; int pcm_mode; int dsp_num; /* Channel status for S/PDIF */ unsigned int channel_status_pos; unsigned char channel_status[24]; enum { NONE, OSS, ALSA } audio_driver_style; struct semaphore audio_driver_style_lock; /* Video */ int video_mode; int video_playmode; int aspect_ratio; int zoom; uint32_t video_pts; uint32_t video_lastpts; int video_ptsvalid,video_offset,video_count; int video_ptsfifo_ptr; #if LINUX_VERSION_CODE < 0x020314 struct wait_queue *video_ptsfifo_wait; struct wait_queue *vbi_wait; #else wait_queue_head_t video_ptsfifo_wait; wait_queue_head_t vbi_wait; #endif int video_ptsfifo_waiting; int video_first; int var_video_value; /* Sub Picture */ int sp_pts, sp_ptsvalid, sp_count; int sp_ptsfifo_ptr; #if LINUX_VERSION_CODE < 0x020314 struct wait_queue *sp_ptsfifo_wait; #else wait_queue_head_t sp_ptsfifo_wait; #endif int sp_ptsfifo_waiting; int sp_mode; int linecounter; /* EM9010 overlay processor */ int overlay_enabled; int overlay_mode; int overlay_gamma_enable; int overlay_xres; int overlay_yres; int overlay_frame_xpos; int overlay_frame_ypos; int overlay_frame_width; int overlay_frame_height; int overlay_a[EM9010_ATTRIBUTE_MAX+1]; int overlay_double_y; int overlay_xcorr_default; int overlay_70; int overlay_dword_24bb8; #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,0) /* Memory exported via mmap() */ struct list_head memory; #endif /* Checksum for the on-board eeprom */ u8 *eeprom_checksum; int model; struct em8300_config_s config; /* To support different options for different cards */ unsigned int card_nr; }; #if defined(CONFIG_SND) || defined(CONFIG_SND_MODULE) #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16) #undef snd_card_t #endif #endif #define TIMEDIFF(a,b) a.tv_usec - b.tv_usec + \ 1000000 * (a.tv_sec - b.tv_sec) /* Prototypes */ /* em8300_i2c.c */ int em8300_i2c_init1(struct em8300_s *em); int em8300_i2c_init2(struct em8300_s *em); void em8300_i2c_exit(struct em8300_s *em); void em8300_clockgen_write(struct em8300_s *em, int abyte); void em9010_write(struct em8300_s *em, int reg, int data); int em9010_read(struct em8300_s *em, int reg); int em9010_read16(struct em8300_s *em, int reg); void em9010_write16(struct em8300_s *em, int reg, int value); /* em8300_audio.c */ int em8300_audio_ioctl(struct em8300_s *em,unsigned int cmd, unsigned long arg); int em8300_audio_flush(struct em8300_s *em); int em8300_audio_open(struct em8300_s *em); int em8300_audio_release(struct em8300_s *em); int em8300_audio_setup(struct em8300_s *em); ssize_t em8300_audio_write(struct em8300_s *em, const char * buf, size_t count, loff_t *ppos); int mpegaudio_command(struct em8300_s *em, int cmd); /* em8300_ucode.c */ void em8300_ucode_upload(struct em8300_s *em, void *ucode, int ucode_size); void em8300_require_ucode(struct em8300_s *em); /* em8300_misc.c */ int em8300_setregblock(struct em8300_s *em, int offset, int val, int len); int em8300_writeregblock(struct em8300_s *em, int offset, unsigned *buf, int len); int em8300_waitfor(struct em8300_s *em, int reg, int val, int mask); int em8300_waitfor_not(struct em8300_s *em, int reg, int val, int mask); /* em8300_dicom.c */ void em8300_dicom_setBCS(struct em8300_s *em, int brightness, int contrast, int saturation); void em8300_dicom_enable(struct em8300_s *em); void em8300_dicom_disable(struct em8300_s *em); int em8300_dicom_update(struct em8300_s *em); void em8300_dicom_init(struct em8300_s *em); int em8300_dicom_get_dbufinfo(struct em8300_s *em); void em8300_dicom_fill_dispbuffers(struct em8300_s *em, int xpos, int ypos, int xsize, int ysize, unsigned int pat1, unsigned int pat2); /* em8300_video.c */ void em8300_video_open(struct em8300_s *em); int em8300_video_setplaymode(struct em8300_s *em, int mode); int em8300_video_sync(struct em8300_s *em); int em8300_video_flush(struct em8300_s *em); int em8300_video_setup(struct em8300_s *em); int em8300_video_release(struct em8300_s *em); void em8300_video_setspeed(struct em8300_s *em, int speed); ssize_t em8300_video_write(struct em8300_s *em, const char * buf, size_t count, loff_t *ppos); int em8300_video_ioctl(struct em8300_s *em, unsigned int cmd, unsigned long arg); void em8300_video_check_ptsfifo(struct em8300_s *em); /* em8300_spu.c */ ssize_t em8300_spu_write(struct em8300_s *em, const char * buf, size_t count, loff_t *ppos); int em8300_spu_open(struct em8300_s *em); int em8300_spu_ioctl(struct em8300_s *em, unsigned int cmd, unsigned long arg); int em8300_spu_init(struct em8300_s *em); void em8300_spu_check_ptsfifo(struct em8300_s *em); int em8300_ioctl_setspumode(struct em8300_s *em, int mode); void em8300_spu_release(struct em8300_s *em); /* em8300_ioctl.c */ int em8300_control_ioctl(struct em8300_s *em, int cmd, unsigned long arg); int em8300_ioctl_setvideomode(struct em8300_s *em, int mode); int em8300_ioctl_setaspectratio(struct em8300_s *em, int ratio); int em8300_ioctl_getstatus(struct em8300_s *em, char *usermsg); int em8300_ioctl_init(struct em8300_s *em, em8300_microcode_t *useruc); void em8300_ioctl_enable_videoout(struct em8300_s *em, int mode); int em8300_ioctl_setplaymode(struct em8300_s *em, int mode); int em8300_ioctl_setaudiomode(struct em8300_s *em, int mode); int em8300_ioctl_getaudiomode(struct em8300_s *em, long int mode); int em8300_ioctl_overlay_calibrate(struct em8300_s *em, em8300_overlay_calibrate_t *c); int em8300_ioctl_overlay_setwindow(struct em8300_s *em,em8300_overlay_window_t *w); int em8300_ioctl_overlay_setscreen(struct em8300_s *em,em8300_overlay_screen_t *s); int em8300_ioctl_overlay_setmode(struct em8300_s *em,int val); /* em9010.c */ int em9010_cabledetect(struct em8300_s *em); int em9010_calibrate_xoffset(struct em8300_s *em); int em9010_calibrate_yoffset(struct em8300_s *em); int em9010_init(struct em8300_s *em); int em9010_overlay_set_signalmode(struct em8300_s *em, int val); int em9010_overlay_update(struct em8300_s *em); int em9010_overlay_set_res(struct em8300_s *em, int xres, int yres); void sub_4288c(struct em8300_s *em, int pa, int pb, int pc, int pd, int pe, int pf, int pg, int ph); int em9010_get_attribute(struct em8300_s *em, int attribute); int em9010_set_attribute(struct em8300_s *em, int attribute, int value); #endif /* __KERNEL__ */ #endif /* LINUX_EM8300_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/nav_read.c��������������������������������������������������������������������0000644�0001750�0001750�00000000051�14647725152�014252� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "../input/libdvdnav/nav_read.c" ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/dxr3_decode_spu.c�������������������������������������������������������������0000644�0001750�0001750�00000064351�14647725152�015562� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* dxr3 spu decoder plugin. * Accepts the spu data from xine and sends it directly to the * corresponding dxr3 device. Also handles dvd menu button highlights. * Takes precedence over libspudec due to a higher priority. */ #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <fcntl.h> #include <errno.h> #define LOG_MODULE "dxr3_decode_spu" /* #define LOG_VERBOSE */ /* #define LOG */ #define LOG_PTS 0 #define LOG_SPU 0 #define LOG_BTN 0 #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/buffer.h> #include "xine-engine/bswap.h" #ifdef HAVE_DVDNAV # ifdef HAVE_DVDNAV_NAVTYPES_H # include <dvdnav/nav_types.h> # include <dvdnav/nav_read.h> # else # include <dvdread/nav_types.h> # include <dvdread/nav_read.h> # endif #else # include "../input/libdvdnav/nav_types.h" # include "../input/libdvdnav/nav_read.h" #endif #include "video_out_dxr3.h" #include "dxr3.h" #include "group_dxr3.h" #define MAX_SPU_STREAMS 32 /* plugin class functions */ static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xine_stream_t *stream); /* plugin instance functions */ static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf); static void dxr3_spudec_reset(spu_decoder_t *this_gen); static void dxr3_spudec_discontinuity(spu_decoder_t *this_gen); static void dxr3_spudec_dispose(spu_decoder_t *this_gen); static int dxr3_spudec_interact_info(spu_decoder_t *this_gen, void *data); static void dxr3_spudec_set_button(spu_decoder_t *this_gen, int32_t button, int32_t mode); /* plugin structures */ typedef struct dxr3_spu_stream_state_s { int spu_length; int spu_ctrl; int spu_end; int parse; int bytes_passed; /* used to parse the spu */ } dxr3_spu_stream_state_t; typedef struct pci_node_s pci_node_t; struct pci_node_s { pci_t pci; uint64_t vpts; pci_node_t *next; }; typedef struct dxr3_spudec_class_s { spu_decoder_class_t spu_decoder_class; int instance; /* we allow only one instance of this plugin */ } dxr3_spudec_class_t; typedef struct dxr3_spudec_s { spu_decoder_t spu_decoder; dxr3_spudec_class_t *class; xine_stream_t *stream; dxr3_driver_t *dxr3_vo; /* we need to talk to the video out */ xine_event_queue_t *event_queue; int devnum; int fd_spu; /* to access the dxr3 spu device */ dxr3_spu_stream_state_t spu_stream_state[MAX_SPU_STREAMS]; uint32_t clut[16]; /* the current color lookup table */ int menu; /* are we in a menu? */ int button_filter; pci_node_t pci_cur; /* a list of PCI packs, with the list head being current */ pthread_mutex_t pci_lock; uint32_t buttonN; /* currently highlighted button */ int anamorphic; /* this is needed to detect anamorphic menus */ } dxr3_spudec_t; /* helper functions */ /* the NAV functions must be called with the pci_lock held */ static inline void dxr3_spudec_clear_nav_list(dxr3_spudec_t *this); static inline void dxr3_spudec_update_nav(dxr3_spudec_t *this); static void dxr3_spudec_process_nav(dxr3_spudec_t *this); static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300_button_t *btn); static inline void dxr3_swab_clut(int* clut); /* inline helper implementations */ static inline void dxr3_spudec_clear_nav_list(dxr3_spudec_t *this) { while (this->pci_cur.next) { pci_node_t *node = this->pci_cur.next->next; free(this->pci_cur.next); this->pci_cur.next = node; } /* invalidate current timestamp */ this->pci_cur.pci.hli.hl_gi.hli_s_ptm = (uint32_t)-1; } static inline void dxr3_spudec_update_nav(dxr3_spudec_t *this) { metronom_clock_t *clock = this->stream->xine->clock; if (this->pci_cur.next && (int64_t)this->pci_cur.next->vpts <= clock->get_current_time(clock)) { pci_node_t *node = this->pci_cur.next; xine_fast_memcpy(&this->pci_cur, this->pci_cur.next, sizeof(pci_node_t)); dxr3_spudec_process_nav(this); free(node); } } static inline void dxr3_swab_clut(int *clut) { int i; for (i=0; i<16; i++) clut[i] = bswap_32(clut[i]); } void *dxr3_spudec_init_plugin(xine_t *xine, const void* data) { dxr3_spudec_class_t *this; (void)xine; (void)data; this = calloc(1, sizeof(dxr3_spudec_class_t)); if (!this) return NULL; this->spu_decoder_class.open_plugin = dxr3_spudec_open_plugin; this->spu_decoder_class.identifier = "dxr3-spudec"; this->spu_decoder_class.description = N_("subtitle decoder plugin using the hardware decoding capabilities of a DXR3 decoder card"); this->spu_decoder_class.dispose = default_spu_decoder_class_dispose; this->instance = 0; return &this->spu_decoder_class; } static spu_decoder_t *dxr3_spudec_open_plugin(spu_decoder_class_t *class_gen, xine_stream_t *stream) { dxr3_spudec_t *this; dxr3_spudec_class_t *class = (dxr3_spudec_class_t *)class_gen; char tmpstr[128]; if (class->instance) return NULL; if (!dxr3_present(stream)) return NULL; this = calloc(1, sizeof(dxr3_spudec_t)); if (!this) return NULL; this->spu_decoder.decode_data = dxr3_spudec_decode_data; this->spu_decoder.reset = dxr3_spudec_reset; this->spu_decoder.discontinuity = dxr3_spudec_discontinuity; this->spu_decoder.dispose = dxr3_spudec_dispose; this->spu_decoder.get_interact_info = dxr3_spudec_interact_info; this->spu_decoder.set_button = dxr3_spudec_set_button; this->class = class; this->stream = stream; /* We need to talk to dxr3 video out to coordinate spus and overlays */ this->dxr3_vo = (dxr3_driver_t *)stream->video_driver; this->event_queue = xine_event_new_queue(stream); this->devnum = stream->xine->config->register_num(stream->xine->config, CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL); pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (this->dxr3_vo->fd_spu >= 0) this->fd_spu = this->dxr3_vo->fd_spu; else { /* open dxr3 spu device */ snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300_sp-%d", this->devnum); if ((this->fd_spu = xine_open_cloexec(tmpstr, O_WRONLY)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_spu: Failed to open spu device %s (%s)\n"), tmpstr, strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); free(this); return NULL; } llprintf(LOG_SPU, "init: SPU_FD = %i\n",this->fd_spu); /* We are talking directly to the dxr3 video out to allow concurrent * access to the same spu device */ this->dxr3_vo->fd_spu = this->fd_spu; } pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); this->menu = 0; this->button_filter = 1; this->pci_cur.pci.hli.hl_gi.hli_ss = 0; this->pci_cur.next = NULL; this->buttonN = 1; this->anamorphic = 0; pthread_mutex_init(&this->pci_lock, NULL); class->instance = 1; return &this->spu_decoder; } static void dxr3_spudec_decode_data(spu_decoder_t *this_gen, buf_element_t *buf) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; ssize_t written; uint32_t stream_id = buf->type & 0x1f; dxr3_spu_stream_state_t *state = &this->spu_stream_state[stream_id]; uint32_t spu_channel = this->stream->spu_channel; xine_event_t *event; /* handle queued events */ while ((event = xine_event_get(this->event_queue))) { llprintf(LOG_SPU, "event caught: SPU_FD = %i\n",this->fd_spu); switch (event->type) { case XINE_EVENT_FRAME_FORMAT_CHANGE: /* we are in anamorphic mode, if the frame is 16:9, but not pan&scan'ed */ this->anamorphic = (((xine_format_change_data_t *)event->data)->aspect == 3) && (((xine_format_change_data_t *)event->data)->pan_scan == 0); llprintf(LOG_BTN, "anamorphic mode %s\n", this->anamorphic ? "on" : "off"); break; } xine_event_free(event); } /* check, if we need to process the next PCI from the list */ pthread_mutex_lock(&this->pci_lock); dxr3_spudec_update_nav(this); pthread_mutex_unlock(&this->pci_lock); if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || !(buf->decoder_flags & BUF_FLAG_SPECIAL) || buf->decoder_info[1] != BUF_SPECIAL_SPU_DVD_SUBTYPE ) return; if (buf->decoder_info[2] == SPU_DVD_SUBTYPE_CLUT) { llprintf(LOG_SPU, "BUF_SPU_CLUT\n"); if (buf->content[0] == 0) /* cheap endianess detection */ dxr3_swab_clut((int *)buf->content); pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (dxr3_spu_setpalette(this->fd_spu, buf->content)) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set CLUT (%s)\n", strerror(errno)); /* remember clut, when video out places some overlay we may need to restore it */ memcpy(this->clut, buf->content, 16 * sizeof(uint32_t)); this->dxr3_vo->clut_cluttered = 0; pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); return; } if (buf->decoder_info[2] == SPU_DVD_SUBTYPE_NAV) { uint8_t *p = buf->content; llprintf(LOG_BTN, "got NAV packet\n"); pthread_mutex_lock(&this->pci_lock); /* just watch out for menus */ if (p[3] == 0xbf && p[6] == 0x00) { /* Private stream 2 */ pci_t pci; navRead_PCI(&pci, p + 7); llprintf(LOG_BTN, "PCI packet hli_ss is %d\n", pci.hli.hl_gi.hli_ss); if (pci.hli.hl_gi.hli_ss == 1) { /* menu ahead */ /* NAV packets contain start and end presentation timestamps, which tell the * application, when the highlight information in the NAV is supposed to be valid. * We handle these timestamps only in a very stripped-down way: We keep a list * of NAV packets (or better: the PCI part of them), tagged with a VPTS timestamp * telling, when the NAV should be processed. However, we only enqueue a new node * into this list, when we receive new highlight information during an already * showing menu. This happens very rarerly on common DVDs, so it is of low impact. * And we only check for processing of queued entries at some prominent * locations in this SPU decoder. Since presentation timestamps rarely solve a real * purpose on most DVDs, this is ok compared to the full-blown solution, which would * require a separate thread managing the queue all the time. */ if (this->pci_cur.pci.hli.hl_gi.hli_ss != 0 && pci.hli.hl_gi.hli_s_ptm > this->pci_cur.pci.hli.hl_gi.hli_s_ptm) { pci_node_t *node = &this->pci_cur; printf("dxr3_decode_spu: DEBUG: allocating new PCI node for hli_s_ptm %d\n", pci.hli.hl_gi.hli_s_ptm); /* append PCI at the end of the list */ while (node->next) node = node->next; node->next = calloc(1, sizeof(pci_node_t)); node->next->vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, pci.hli.hl_gi.hli_s_ptm); node->next->next = NULL; xine_fast_memcpy(&node->next->pci, &pci, sizeof(pci_t)); } else { dxr3_spudec_clear_nav_list(this); /* menu ahead, remember PCI for later use */ xine_fast_memcpy(&this->pci_cur.pci, &pci, sizeof(pci_t)); dxr3_spudec_process_nav(this); } } if ((pci.hli.hl_gi.hli_ss == 0) && (this->pci_cur.pci.hli.hl_gi.hli_ss == 1)) { /* this is (or: should be, I hope I got this right) a subpicture plane, that hides all menu buttons */ uint8_t empty_spu[] = { 0x00, 0x26, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x01, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x06, 0x00, 0x04, 0x00, 0x07, 0xFF, 0x00, 0x01, 0x00, 0x20, 0x02, 0xFF }; /* leaving menu */ dxr3_spudec_clear_nav_list(this); this->pci_cur.pci.hli.hl_gi.hli_ss = 0; this->menu = 0; this->button_filter = 1; pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); dxr3_spu_button(this->fd_spu, NULL); if (write(this->fd_spu, empty_spu, sizeof(empty_spu)) != sizeof(empty_spu)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_spu: spu device write failed (%s)\n"), strerror(errno)); } pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } } pthread_mutex_unlock(&this->pci_lock); return; } /* We parse the SPUs command and end sequence here for two reasons: * 1. Look for the display duration entry in the spu packets. * If the spu is a menu button highlight pane, this entry must not exist, * because the spu is hidden, when the menu is left, not by timeout. * Some broken dvds do not respect this and therefore confuse the spu * decoding pipeline of the card. We fix this here. * 2. We need to handle SPU forcing here. When we only display forced * SPUs, we have to prevent normal unforced SPUs from being displayed. * But since that decision is only possible after parts of the SPU * have already been written to the card, we have to manipulate the * SPU's command sequence to prevent it from being displayed. */ if (!state->spu_length) { state->spu_length = buf->content[0] << 8 | buf->content[1]; state->spu_ctrl = (buf->content[2] << 8 | buf->content[3]) + 2; state->spu_end = 0; state->parse = 0; state->bytes_passed = 0; } if (state->spu_length) { if (!state->parse) { int offset_in_buffer = state->spu_ctrl - state->bytes_passed; if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) state->spu_end = buf->content[offset_in_buffer] << 8; offset_in_buffer++; if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) { state->spu_end |= buf->content[offset_in_buffer]; state->parse = 2; } } if (state->parse > 1) { int offset_in_buffer; do { offset_in_buffer = state->spu_ctrl + state->parse - state->bytes_passed; if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) { switch (buf->content[offset_in_buffer]) { case 0x00: /* force display */ state->parse++; break; case 0x01: /* show */ /* when only forced SPUs are allowed, change show to hide */ if (spu_channel & 0x80) buf->content[offset_in_buffer] = 0x02; /* fall through */ case 0x02: /* hide */ state->parse++; break; case 0x03: /* colour lookup table */ case 0x04: /* transparency palette */ state->parse += 3; break; case 0x05: /* position and size */ state->parse += 7; break; case 0x06: /* field offsets */ state->parse += 5; break; case 0x07: /* wipe */ case 0xff: /* end */ default: state->parse = 1; /* bail out */ } } } while (offset_in_buffer < buf->size && state->parse > 1); } if (state->parse && this->menu) { int offset_in_buffer = state->spu_end - state->bytes_passed; if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) buf->content[offset_in_buffer] = 0x00; offset_in_buffer++; if (offset_in_buffer >= 0 && offset_in_buffer < buf->size) buf->content[offset_in_buffer] = 0x00; offset_in_buffer += 3; if (offset_in_buffer >= 0 && offset_in_buffer < buf->size && buf->content[offset_in_buffer] == 0x02) buf->content[offset_in_buffer] = 0x00; } state->spu_length -= buf->size; if (state->spu_length < 0) state->spu_length = 0; state->bytes_passed += buf->size; } /* filter unwanted streams */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) { llprintf(LOG_SPU, "Dropping SPU channel %d. Preview data\n", stream_id); return; } if (this->anamorphic && !this->dxr3_vo->widescreen_enabled && this->stream->spu_channel_user == -1 && this->stream->spu_channel_letterbox >= 0) { /* Use the letterbox version of the subpicture for letterboxed display. */ spu_channel = this->stream->spu_channel_letterbox; } if ((spu_channel & 0x1f) != stream_id) { llprintf(LOG_SPU, "Dropping SPU channel %d. Not selected stream_id\n", stream_id); return; } /* We used to filter for SPU forcing here as well, but this does not work * this way with the DXR3, because we have to evaluate the SPU command sequence * to detect, if a particular SPU is forced or not. See the parsing code above. */ pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); /* write sync timestamp to the card */ if (buf->pts) { int64_t vpts; uint32_t vpts32; vpts = this->stream->metronom->got_spu_packet(this->stream->metronom, buf->pts); llprintf(LOG_PTS, "pts = %" PRId64 " vpts = %" PRIu64 "\n", buf->pts, vpts); vpts32 = vpts; if (dxr3_spu_setpts(this->fd_spu, &vpts32)) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: spu setpts failed (%s)\n", strerror(errno)); } /* has video out tampered with our palette */ if (this->dxr3_vo->clut_cluttered) { if (dxr3_spu_setpalette(this->fd_spu, this->clut)) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set CLUT (%s)\n", strerror(errno)); this->dxr3_vo->clut_cluttered = 0; } /* write spu data to the card */ llprintf(LOG_SPU, "write: SPU_FD = %i\n",this->fd_spu); written = write(this->fd_spu, buf->content, buf->size); if (written < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: spu device write failed (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); return; } if (written != buf->size) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: Could only write %zd of %d spu bytes.\n", written, buf->size); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } static void dxr3_spudec_reset(spu_decoder_t *this_gen) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; int i; for (i = 0; i < MAX_SPU_STREAMS; i++) this->spu_stream_state[i].spu_length = 0; pthread_mutex_lock(&this->pci_lock); dxr3_spudec_clear_nav_list(this); pthread_mutex_unlock(&this->pci_lock); } static void dxr3_spudec_discontinuity(spu_decoder_t *this_gen) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; pthread_mutex_lock(&this->pci_lock); dxr3_spudec_clear_nav_list(this); pthread_mutex_unlock(&this->pci_lock); } static void dxr3_spudec_dispose(spu_decoder_t *this_gen) { static const uint8_t empty_spu[] = { 0x00, 0x26, 0x00, 0x08, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x20, 0x01, 0x03, 0x00, 0x00, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x06, 0x00, 0x04, 0x00, 0x07, 0xFF, 0x00, 0x01, 0x00, 0x20, 0x02, 0xFF }; dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; llprintf(LOG_SPU, "close: SPU_FD = %i\n",this->fd_spu); pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); /* clear any remaining spu */ dxr3_spu_button(this->fd_spu, NULL); if (write(this->fd_spu, empty_spu, sizeof(empty_spu)) != sizeof(empty_spu)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_spu: spu device write failed (%s)\n"), strerror(errno)); } close(this->fd_spu); this->fd_spu = -1; this->dxr3_vo->fd_spu = -1; pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); dxr3_spudec_clear_nav_list(this); xine_event_dispose_queue(this->event_queue); pthread_mutex_destroy(&this->pci_lock); this->class->instance = 0; free (this); } static int dxr3_spudec_interact_info(spu_decoder_t *this_gen, void *data) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; pthread_mutex_lock(&this->pci_lock); dxr3_spudec_update_nav(this); memcpy(data, &this->pci_cur.pci, sizeof(pci_t)); pthread_mutex_unlock(&this->pci_lock); return 1; } static void dxr3_spudec_set_button(spu_decoder_t *this_gen, int32_t button, int32_t mode) { dxr3_spudec_t *this = (dxr3_spudec_t *)this_gen; em8300_button_t btn; llprintf(LOG_BTN, "setting button\n"); this->buttonN = button; pthread_mutex_lock(&this->pci_lock); dxr3_spudec_update_nav(this); if (mode > 0 && !this->button_filter && (dxr3_spudec_copy_nav_to_btn(this, mode - 1, &btn ) > 0)) { pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (dxr3_spu_button(this->fd_spu, &btn)) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set spu button (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } pthread_mutex_unlock(&this->pci_lock); if (mode == 2) this->button_filter = 1; llprintf(LOG_BTN, "buttonN = %u\n", this->buttonN); } static void dxr3_spudec_process_nav(dxr3_spudec_t *this) { em8300_button_t btn; this->menu = 1; this->button_filter = 0; if (this->pci_cur.pci.hli.hl_gi.fosl_btnn > 0) { /* a button is forced here, inform nav plugin */ xine_event_t event; this->buttonN = this->pci_cur.pci.hli.hl_gi.fosl_btnn; event.type = XINE_EVENT_INPUT_BUTTON_FORCE; event.stream = this->stream; event.data = &this->buttonN; event.data_length = sizeof(this->buttonN); xine_event_send(this->stream, &event); } if ((dxr3_spudec_copy_nav_to_btn(this, 0, &btn ) > 0)) { pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (dxr3_spu_button(this->fd_spu, &btn)) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set spu button (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } else { /* current button does not exist -> use another one */ xine_event_t event; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("requested button not available\n")); if (this->buttonN > this->pci_cur.pci.hli.hl_gi.btn_ns) this->buttonN = this->pci_cur.pci.hli.hl_gi.btn_ns; else this->buttonN = 1; event.type = XINE_EVENT_INPUT_BUTTON_FORCE; event.stream = this->stream; event.data = &this->buttonN; event.data_length = sizeof(this->buttonN); xine_event_send(this->stream, &event); if ((dxr3_spudec_copy_nav_to_btn(this, 0, &btn ) > 0)) { pthread_mutex_lock(&this->dxr3_vo->spu_device_lock); if (dxr3_spu_button(this->fd_spu, &btn)) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: failed to set spu button (%s)\n", strerror(errno)); pthread_mutex_unlock(&this->dxr3_vo->spu_device_lock); } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "no working menu button found\n"); } } } static int dxr3_spudec_copy_nav_to_btn(dxr3_spudec_t *this, int32_t mode, em8300_button_t *btn) { btni_t *button_ptr = NULL; if ((this->buttonN <= 0) || (this->buttonN > this->pci_cur.pci.hli.hl_gi.btn_ns)) return -1; /* choosing a button from a matching button group */ if (this->anamorphic && !this->dxr3_vo->widescreen_enabled && this->stream->spu_channel_user == -1 && this->stream->spu_channel_letterbox != this->stream->spu_channel && this->stream->spu_channel_letterbox >= 0) { unsigned int btns_per_group = 36 / this->pci_cur.pci.hli.hl_gi.btngr_ns; /* use a letterbox button group for letterboxed anamorphic menus on tv out */ if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 1 && (this->pci_cur.pci.hli.hl_gi.btngr1_dsp_ty & 2)) button_ptr = &this->pci_cur.pci.hli.btnit[0 * btns_per_group + this->buttonN - 1]; if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 2 && (this->pci_cur.pci.hli.hl_gi.btngr2_dsp_ty & 2)) button_ptr = &this->pci_cur.pci.hli.btnit[1 * btns_per_group + this->buttonN - 1]; if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 3 && (this->pci_cur.pci.hli.hl_gi.btngr3_dsp_ty & 2)) button_ptr = &this->pci_cur.pci.hli.btnit[2 * btns_per_group + this->buttonN - 1]; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "No suitable letterbox button group found.\n"); _x_assert(button_ptr); } else { unsigned int btns_per_group = 36 / this->pci_cur.pci.hli.hl_gi.btngr_ns; /* otherwise use a normal 4:3 or widescreen button group */ if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 1 && !(this->pci_cur.pci.hli.hl_gi.btngr1_dsp_ty & 6)) button_ptr = &this->pci_cur.pci.hli.btnit[0 * btns_per_group + this->buttonN - 1]; if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 2 && !(this->pci_cur.pci.hli.hl_gi.btngr2_dsp_ty & 6)) button_ptr = &this->pci_cur.pci.hli.btnit[1 * btns_per_group + this->buttonN - 1]; if (!button_ptr && this->pci_cur.pci.hli.hl_gi.btngr_ns >= 3 && !(this->pci_cur.pci.hli.hl_gi.btngr3_dsp_ty & 6)) button_ptr = &this->pci_cur.pci.hli.btnit[2 * btns_per_group + this->buttonN - 1]; } if (!button_ptr) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_spu: No suitable menu button group found, using group 1.\n"); button_ptr = &this->pci_cur.pci.hli.btnit[this->buttonN - 1]; } if(button_ptr->btn_coln != 0) { llprintf(LOG_BTN, "normal button clut, mode %d\n", mode); btn->color = (this->pci_cur.pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode] >> 16); btn->contrast = (this->pci_cur.pci.hli.btn_colit.btn_coli[button_ptr->btn_coln-1][mode]); btn->left = button_ptr->x_start; btn->top = button_ptr->y_start; btn->right = button_ptr->x_end; btn->bottom = button_ptr->y_end; return 1; } return -1; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/dxr3_decode_video.c�����������������������������������������������������������0000644�0001750�0001750�00000070703�14647725152�016057� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* dxr3 video decoder plugin. * Accepts the video data from xine and sends it directly to the * corresponding dxr3 device. Takes precedence over the libmpeg2 * due to a higher priority. */ #include <sys/types.h> #include <sys/ioctl.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <fcntl.h> #include <errno.h> #define LOG_MODULE "dxr3_decode_video" /* #define LOG_VERBOSE */ /* #define LOG */ #define LOG_VID 0 #define LOG_PTS 0 #include <xine/xine_internal.h> #include <xine/buffer.h> #include "video_out_dxr3.h" #include "dxr3.h" #include "group_dxr3.h" /* once activated, we wait for this amount of missing pan&scan info * before disabling it again */ #define PAN_SCAN_WINDOW_SIZE 50 /* the number of frames to pass after an out-of-sync situation * before locking the stream again */ #define RESYNC_WINDOW_SIZE 50 /* we adjust vpts_offset in metronom, when skip_count reaches this value */ #define SKIP_TOLERANCE 200 /* the number of frames to pass before we stop duration correction */ #define FORCE_DURATION_WINDOW_SIZE 100 /* plugin class functions */ static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream); /* plugin instance functions */ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf); static void dxr3_reset(video_decoder_t *this_gen); static void dxr3_discontinuity(video_decoder_t *this_gen); static void dxr3_flush(video_decoder_t *this_gen); static void dxr3_dispose(video_decoder_t *this_gen); /* plugin structures */ typedef struct dxr3_decoder_class_s { video_decoder_class_t video_decoder_class; int instance; /* we allow only one instance of this plugin */ } dxr3_decoder_class_t; typedef struct dxr3_decoder_s { video_decoder_t video_decoder; dxr3_decoder_class_t *class; xine_stream_t *stream; dxr3_scr_t *scr; /* shortcut to the scr plugin in the dxr3 video out */ metronom_clock_t *clock; /* used for syncing */ int devnum; int fd_control; int fd_video; /* to access the dxr3 devices */ int have_header_info; int sequence_open; int width; int height; double ratio; int aspect_code; int frame_rate_code; int repeat_first_field; /* mpeg stream header data */ int force_aspect; /* when input plugin has better info, we are forced */ int force_pan_scan; /* to use a certain aspect or to do pan&scan */ int use_panscan; int panscan_smart_change; int afd_smart_change; int afd_code; /* use pan&scan info if present in stream */ int last_width; int last_height; int last_aspect_code; /* used to detect changes for event sending */ unsigned int dts_offset[3]; int sync_every_frame; int sync_retry; int enhanced_mode; int resync_window; int skip_count; /* syncing parameters */ int correct_durations; int64_t last_vpts; int force_duration_window; int avg_duration; /* logic to correct broken frame rates */ } dxr3_decoder_t; /* helper functions */ static inline int dxr3_mvcommand(int fd_control, int command); static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t *buffer); static int get_duration(dxr3_decoder_t *this); static void frame_format_change(dxr3_decoder_t *this); /* config callbacks */ static void dxr3_update_panscan(void *this_gen, xine_cfg_entry_t *entry); static void dxr3_update_sync_mode(void *this_gen, xine_cfg_entry_t *entry); static void dxr3_update_enhanced_mode(void *this_gen, xine_cfg_entry_t *entry); static void dxr3_update_correct_durations(void *this_gen, xine_cfg_entry_t *entry); /* inline helper implementations */ static inline int dxr3_mvcommand(int fd_control, int command) { em8300_register_t reg; reg.microcode_register = 1; reg.reg = 0; reg.val = command; return ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®); } void *dxr3_video_init_plugin(xine_t *xine, const void *data) { dxr3_decoder_class_t *this; (void)xine; (void)data; this = calloc(1, sizeof (dxr3_decoder_class_t)); if (!this) return NULL; this->video_decoder_class.open_plugin = dxr3_open_plugin; this->video_decoder_class.identifier = "dxr3-mpeg2"; this->video_decoder_class.description = N_("MPEGI/II decoder plugin using the hardware decoding capabilities of a DXR3 decoder card."); this->video_decoder_class.dispose = default_video_decoder_class_dispose; this->instance = 0; return &this->video_decoder_class; } static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream) { static const char *const panscan_types[] = { "only when forced", "use MPEG hint", "use DVB hint", NULL }; dxr3_decoder_t *this; dxr3_decoder_class_t *class = (dxr3_decoder_class_t *)class_gen; config_values_t *cfg; char tmpstr[128]; if (class->instance) return NULL; if (!dxr3_present(stream)) return NULL; this = calloc(1, sizeof (dxr3_decoder_t)); if (!this) return NULL; cfg = stream->xine->config; this->video_decoder.decode_data = dxr3_decode_data; this->video_decoder.reset = dxr3_reset; this->video_decoder.discontinuity = dxr3_discontinuity; this->video_decoder.flush = dxr3_flush; this->video_decoder.dispose = dxr3_dispose; this->class = class; this->stream = stream; this->scr = NULL; this->clock = stream->xine->clock; this->devnum = cfg->register_num(cfg, CONF_KEY, 0, CONF_NAME, CONF_HELP, 10, NULL, NULL); snprintf(tmpstr, sizeof(tmpstr), "/dev/em8300-%d", this->devnum); llprintf(LOG_VID, "Entering video init, devname=%s.\n",tmpstr); /* open later, because dxr3_video_out might have it open until we request a frame */ this->fd_video = -1; if ((this->fd_control = xine_open_cloexec(tmpstr, O_WRONLY)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_video: Failed to open control device %s (%s)\n"), tmpstr, strerror(errno)); free(this); return NULL; } this->use_panscan = cfg->register_enum(cfg, "dxr3.use_panscan", 0, (char **)panscan_types, _("use Pan & Scan info"), _("\"Pan & Scan\" is a special display mode which is sometimes used in MPEG " "encoded material. You can specify here, how to handle such content.\n\n" "only when forced\n" "Use Pan & Scan only, when the content you are playing enforces it.\n\n" "use MPEG hint\n" "Enable Pan & Scan based on information embedded in the MPEG video stream.\n\n" "use DVB hint\n" "Enable Pan & Scan based on information embedded in DVB streams. This makes " "use of the Active Format Descriptor (AFD) used in some European DVB channels."), 10, dxr3_update_panscan, this); this->dts_offset[0] = 21600; this->dts_offset[1] = 21600; this->dts_offset[2] = 21600; this->force_duration_window = -FORCE_DURATION_WINDOW_SIZE; this->last_vpts = this->clock->get_current_time(this->clock); this->sync_every_frame = cfg->register_bool(cfg, "dxr3.playback.sync_every_frame", 0, _("try to sync video every frame"), _("Tries to set a synchronization timestamp for every frame. " "Normally this is not necessary, because sync is sufficient " "even when the timestamp is set only every now and then.\n" "This is relevant for progressive video only (most PAL films)."), 20, dxr3_update_sync_mode, this); this->enhanced_mode = cfg->register_bool(cfg, "dxr3.playback.alt_play_mode", 1, _("use smooth play mode"), _("Enabling this option will utilise a smoother play mode."), 20, dxr3_update_enhanced_mode, this); this->correct_durations = cfg->register_bool(cfg, "dxr3.playback.correct_durations", 0, _("correct frame durations in broken streams"), _("Enables a small logic that corrects the frame durations of " "some mpeg streams with wrong framerate codes. Currently a " "correction for NTSC streams erroneously labeled as PAL " "streams is implemented. Enable only, when you encounter such streams."), 0, dxr3_update_correct_durations, this); /* the dxr3 needs a longer prebuffering to have time for its internal decoding */ this->stream->metronom->set_option(this->stream->metronom, METRONOM_PREBUFFER, 90000); (stream->video_out->open) (stream->video_out, stream); class->instance = 1; return &this->video_decoder; } static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) { dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen; ssize_t written; int64_t vpts; int i, skip; vo_frame_t *img; uint8_t *buffer, byte; uint32_t shift; vpts = 0; /* handle aspect hints from xine-dvdnav */ if (buf->decoder_flags & BUF_FLAG_SPECIAL) { if (buf->decoder_info[1] == BUF_SPECIAL_ASPECT) { this->aspect_code = this->force_aspect = buf->decoder_info[2]; if (buf->decoder_info[3] == 0x1 && this->force_aspect == 3) /* letterboxing is denied, we have to do pan&scan */ this->force_pan_scan = 1; else this->force_pan_scan = 0; frame_format_change(this); this->last_aspect_code = this->aspect_code; } return; } /* parse frames in the buffer handed in, evaluate headers, * send frames to video_out and handle some syncing */ buffer = buf->content; shift = 0xffffff00; for (i = 0; i < buf->size; i++) { byte = *buffer++; if (shift != 0x00000100) { shift = (shift | byte) << 8; continue; } /* header code of some kind found */ shift = 0xffffff00; if (byte == 0xb2) { /* check for AFD data */ if (buffer + 5 < buf->content + buf->size) { if (buffer[0] == 0x44 && buffer[1] == 0x54 && buffer[2] == 0x47) { this->afd_code = buffer[5] & 0x0f; if (this->aspect_code == 3) /* 4:3 image in 16:9 frame -> zoomit! */ this->afd_smart_change = PAN_SCAN_WINDOW_SIZE; } } continue; } if (byte == 0xb3) { /* sequence data */ if (buffer + 3 < buf->content + buf->size) parse_mpeg_header(this, buffer); this->sequence_open = 1; continue; } if (byte == 0xb5) { /* extension data */ /* parse the extension type and use what is necessary... * types are: sequence(1), sequence_display(2), quant_matrix(3), * copyright(4), picture_display(7), picture_coding(8), ... */ if (buffer + 4 < buf->content + buf->size) { switch (buffer[0] >> 4) { case 2: case 7: /* picture_display and sequence_display are pan&scan info */ if (this->use_panscan) this->panscan_smart_change = PAN_SCAN_WINDOW_SIZE; break; case 8: this->repeat_first_field = (buffer[3] >> 1) & 1; /* clearing the progessive flag gets rid of the slight shaking with * TV-out in the lower third of the image; but we have to set this * flag, when a still frame is coming along, otherwise the card will * drop one of the fields; therefore we check for the fifo size */ if (!((dxr3_driver_t *)this->stream->video_driver)->overlay_enabled) { if (this->stream->video_fifo->fifo_size > this->stream->video_fifo->buffer_pool_capacity / 2) buffer[4] &= ~(1 << 7); else buffer[4] |= (1 << 7); } break; } } /* check if we can keep syncing */ if (this->repeat_first_field && this->sync_retry) /* reset counter */ this->sync_retry = 500; if (this->repeat_first_field && this->sync_every_frame) { llprintf(LOG_VID, "non-progressive video detected. disabling sync_every_frame.\n"); this->sync_every_frame = 0; this->sync_retry = 500; /* see you later */ } /* check for pan&scan state */ if (this->use_panscan && (this->panscan_smart_change > 0 || this->afd_smart_change > 0)) { this->panscan_smart_change--; this->afd_smart_change--; if (this->panscan_smart_change > 0 || this->afd_smart_change > 0) { /* only pan&scan if source is anamorphic */ if (this->aspect_code == 3) { if (this->afd_smart_change && this->use_panscan == 2 && this->afd_code == 9) this->force_pan_scan = 1; /* panscan info available -> zoom */ else if (this->afd_smart_change && this->use_panscan == 2 && this->afd_code != 9) this->force_pan_scan = 0; /* force no panscan - image is 16:9 */ else if (this->use_panscan == 1 && this->panscan_smart_change) this->force_pan_scan = 1; /* panscan info available, ignore AFD mode */ else if (!this->afd_smart_change && this->panscan_smart_change) this->force_pan_scan = 1; frame_format_change(this); } } else { this->force_pan_scan = 0; frame_format_change(this); } } continue; } if (byte == 0xb7) /* sequence end */ this->sequence_open = 0; if (byte != 0x00) /* Don't care what it is. It's not a new frame */ continue; /* we have a code for a new frame */ if (!this->have_header_info) /* this->width et al may still be undefined */ continue; if (buf->decoder_flags & BUF_FLAG_PREVIEW) continue; /* pretend like we have decoded a frame */ img = this->stream->video_out->get_frame(this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_DXR3, VO_BOTH_FIELDS | (this->force_pan_scan ? VO_PAN_SCAN_FLAG : 0)); img->pts = buf->pts; img->bad_frame = 0; img->duration = get_duration(this); skip = img->draw(img, this->stream); if (skip <= 0) { /* don't skip */ vpts = img->vpts; /* copy so we can free img */ if (this->correct_durations) { /* calculate an average frame duration from metronom's vpts values */ this->avg_duration = this->avg_duration * 0.9 + (vpts - this->last_vpts) * 0.1; llprintf(LOG_PTS, "average frame duration %d\n", this->avg_duration); } if (this->skip_count) this->skip_count--; if (this->resync_window == 0 && this->scr && this->enhanced_mode && !this->scr->scanning) { /* we are in sync, so we can lock the stream now */ llprintf(LOG_VID, "in sync, stream locked\n"); dxr3_mvcommand(this->fd_control, MVCOMMAND_SYNC); this->resync_window = -RESYNC_WINDOW_SIZE; pthread_mutex_lock(&this->scr->mutex); this->scr->sync = 1; pthread_mutex_unlock(&this->scr->mutex); } if (this->resync_window != 0 && this->resync_window > -RESYNC_WINDOW_SIZE) this->resync_window--; } else { /* metronom says skip, so don't set vpts */ llprintf(LOG_VID, "%d frames to skip\n", skip); vpts = 0; this->avg_duration = 0; /* handle frame skip conditions */ if (this->scr && !this->scr->scanning) this->skip_count += skip; if (this->skip_count > SKIP_TOLERANCE) { /* we have had enough skipping messages now, let's react */ int64_t vpts_adjust = skip * (int64_t)img->duration / 2; if (vpts_adjust > 90000) vpts_adjust = 90000; this->stream->metronom->set_option(this->stream->metronom, METRONOM_ADJ_VPTS_OFFSET, vpts_adjust); this->skip_count = 0; this->resync_window = 0; } if (this->scr && this->scr->scanning) this->resync_window = 0; if (this->resync_window == 0 && this->scr && this->enhanced_mode && !this->scr->scanning) { /* switch off sync mode in the card to allow resyncing */ llprintf(LOG_VID, "out of sync, allowing stream resync\n"); dxr3_mvcommand(this->fd_control, MVCOMMAND_START); this->resync_window = RESYNC_WINDOW_SIZE; pthread_mutex_lock(&this->scr->mutex); this->scr->sync = 0; pthread_mutex_unlock(&this->scr->mutex); } if (this->resync_window != 0 && this->resync_window < RESYNC_WINDOW_SIZE) this->resync_window++; } this->last_vpts = img->vpts; img->free(img); /* if sync_every_frame was disabled, decrease the counter * for a retry * (it might be due to crappy studio logos and stuff * so we should give the main movie a chance) */ if (this->sync_retry) { if (!--this->sync_retry) { llprintf(LOG_VID, "retrying sync_every_frame"); this->sync_every_frame = 1; } } } if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; /* ensure video device is open * (we open it late because on occasion the dxr3 video out driver * wants to open it) * also ensure the scr is running */ if (this->fd_video < 0) { metronom_clock_t *clock = this->clock; char tmpstr[128]; int64_t time; /* open the device for the decoder */ snprintf (tmpstr, sizeof(tmpstr), "/dev/em8300_mv-%d", this->devnum); if ((this->fd_video = xine_open_cloexec(tmpstr, O_WRONLY)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_video: Failed to open video device %s (%s)\n"), tmpstr, strerror(errno)); return; } /* We may want to issue a SETPTS, so make sure the scr plugin * is running and registered. Unfortuantely wa cannot do this * earlier, because the dxr3's internal scr gets confused * when started with a closed video device. Maybe this is a * driver bug and gets fixed somewhen. FIXME: We might then * want to do this entirely in the video out. */ this->scr = ((dxr3_driver_t *)this->stream->video_driver)->scr; time = clock->get_current_time(clock); this->scr->scr_plugin.start(&this->scr->scr_plugin, time); clock->register_scr(clock, &this->scr->scr_plugin); } /* update the pts timestamp in the card, which tags the data we write to it */ if (vpts) { int64_t delay; /* The PTS values written to the DXR3 must be modified based on the difference * between stream's PTS and DTS (decoder timestamp). We receive this * difference via decoder_info */ buf->decoder_info[0] <<= 1; if (buf->pts) { if ((this->dts_offset[0] == buf->decoder_info[0]) && (this->dts_offset[1] == buf->decoder_info[0])) this->dts_offset[2] = buf->decoder_info[0]; else { this->dts_offset[1] = this->dts_offset[0]; this->dts_offset[0] = buf->decoder_info[0]; } llprintf(LOG_PTS, "PTS to DTS correction: %d\n", this->dts_offset[1]); } vpts -= this->dts_offset[2]; delay = vpts - this->clock->get_current_time(this->clock); llprintf(LOG_PTS, "SETPTS got %" PRId64 "\n", vpts); /* SETPTS only if less then one second in the future and * either buffer has pts or sync_every_frame is set */ if ((delay > 0) && (delay < 90000) && (this->sync_every_frame || buf->pts)) { uint32_t vpts32 = vpts; /* update the dxr3's current pts value */ if (dxr3_video_setpts(this->fd_video, &vpts32)) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_video: set video pts failed (%s)\n", strerror(errno)); } if (delay >= 90000) /* frame more than 1 sec ahead */ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_video: WARNING: vpts %" PRId64 " is %.02f seconds ahead of time!\n", vpts, delay/90000.0); if (delay < 0) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_video: WARNING: overdue frame.\n"); } else if (buf->pts) llprintf(LOG_PTS, "skip buf->pts = %" PRId64 " (no vpts)\n", buf->pts); /* now write the content to the dxr3 mpeg device and, in a dramatic * break with open source tradition, check the return value */ written = write(this->fd_video, buf->content, buf->size); if (written < 0) { if (errno == EAGAIN) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_video: write to device would block. flushing\n")); dxr3_flush(this_gen); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_video: video device write failed (%s)\n"), strerror(errno)); } return; } if (written != buf->size) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_video: Could only write %zd of %d video bytes.\n", written, buf->size); } static void dxr3_reset(video_decoder_t *this_gen) { dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen; this->sequence_open = 0; } static void dxr3_discontinuity(video_decoder_t *this_gen) { (void)this_gen; } static void dxr3_flush(video_decoder_t *this_gen) { dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen; if (this->sequence_open && ++this->sequence_open > 5 && _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_HAS_STILL)) { /* The dxr3 needs a sequence end code for still menus to work correctly * (the highlights won't move without), but some dvds have stills * with no sequence end code. Since it is very likely that flush() is called * in still situations, we send one here. */ static const uint8_t end_buffer[4] = { 0x00, 0x00, 0x01, 0xb7 }; if (write(this->fd_video, &end_buffer, 4) != 4) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_video: video device write failed (%s)\n"), strerror(errno)); } this->sequence_open = 0; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "dxr3_decode_video: WARNING: added missing end sequence\n"); } } static void dxr3_dispose(video_decoder_t *this_gen) { dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen; metronom_clock_t *clock = this->clock; if (this->scr) clock->unregister_scr(clock, &this->scr->scr_plugin); dxr3_mvcommand(this->fd_control, MVCOMMAND_FLUSHBUF); if (this->fd_video >= 0) close(this->fd_video); close(this->fd_control); this->stream->video_out->close(this->stream->video_out, this->stream); this->class->instance = 0; free(this); } static void parse_mpeg_header(dxr3_decoder_t *this, uint8_t * buffer) { this->frame_rate_code = buffer[3] & 15; this->height = (buffer[0] << 16) | (buffer[1] << 8) | (buffer[2] << 0); this->width = ((this->height >> 12) + 15) & ~15; this->height = ((this->height & 0xfff) + 15) & ~15; this->aspect_code = buffer[3] >> 4; this->have_header_info = 1; if (this->force_aspect) this->aspect_code = this->force_aspect; /* when width, height or aspect changes, * we have to send an event for dxr3 spu decoder */ if (!this->last_width || !this->last_height || !this->last_aspect_code || (this->last_width != this->width) || (this->last_height != this->height) || (this->last_aspect_code != this->aspect_code)) { frame_format_change(this); this->last_width = this->width; this->last_height = this->height; this->last_aspect_code = this->aspect_code; } } static int get_duration(dxr3_decoder_t *this) { int duration; switch (this->frame_rate_code) { case 1: /* 23.976 */ duration = 3754; /* actually it's 3753.75 */ break; case 2: /* 24.000 */ duration = 3750; break; case 3: /* 25.000 */ duration = this->repeat_first_field ? 5400 : 3600; break; case 4: /* 29.970 */ duration = this->repeat_first_field ? 4505 : 3003; break; case 5: /* 30.000 */ duration = 3000; break; case 6: /* 50.000 */ duration = 1800; break; case 7: /* 59.940 */ duration = 1502; /* actually it's 1501.5 */ break; case 8: /* 60.000 */ duration = 1500; break; default: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_video: WARNING: unknown frame rate code %d\n"), this->frame_rate_code); duration = 0; break; } /* update stream metadata */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, duration); if (this->correct_durations && duration) { /* we set an initial average frame duration here */ if (!this->avg_duration) this->avg_duration = duration; /* Apply a correction to the framerate-code if metronom * insists on a different frame duration. * The code below is for NTCS streams labeled as PAL streams. * (I have seen such things even on dvds!) */ if (this->avg_duration && this->avg_duration < 3300 && duration == 3600) { if (this->force_duration_window > 0) { /* we are already in a force_duration window, so we force duration */ this->force_duration_window = FORCE_DURATION_WINDOW_SIZE; return 3000; } if (this->force_duration_window <= 0 && (this->force_duration_window += 10) > 0) { /* we just entered a force_duration window, so we start the correction */ metronom_t *metronom = this->stream->metronom; int64_t cur_offset; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dxr3_decode_video: WARNING: correcting frame rate code from PAL to NTSC\n")); /* those weird streams need an offset, too */ cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET); metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset - 28800); this->force_duration_window = FORCE_DURATION_WINDOW_SIZE; return 3000; } } if (this->force_duration_window == -FORCE_DURATION_WINDOW_SIZE) /* we are far from a force_duration window */ return duration; if (--this->force_duration_window == 0) { /* we have just left a force_duration window */ metronom_t *metronom = this->stream->metronom; int64_t cur_offset; cur_offset = metronom->get_option(metronom, METRONOM_AV_OFFSET); metronom->set_option(metronom, METRONOM_AV_OFFSET, cur_offset + 28800); this->force_duration_window = -FORCE_DURATION_WINDOW_SIZE; } } return duration; } static void frame_format_change(dxr3_decoder_t *this) { /* inform the dxr3 SPU decoder about the current format, * so that it can choose the correctly matching SPU */ xine_event_t event; xine_format_change_data_t data; event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = this->stream; event.data = &data; event.data_length = sizeof(data); data.width = this->width; data.height = this->height; data.aspect = this->aspect_code; data.pan_scan = this->force_pan_scan; xine_event_send(this->stream, &event); /* update ratio */ switch (this->aspect_code) { case 2: this->ratio = 4.0 / 3.0; break; case 3: this->ratio = 16.0 / 9.0; break; case 4: this->ratio = 2.11; break; default: if (this->have_header_info) this->ratio = (double)this->width / (double)this->height; } /* update stream metadata */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, 10000 * this->ratio); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MPEG (DXR3)"); } static void dxr3_update_panscan(void *this_gen, xine_cfg_entry_t *entry) { ((dxr3_decoder_t *)this_gen)->use_panscan = entry->num_value; } static void dxr3_update_sync_mode(void *this_gen, xine_cfg_entry_t *entry) { ((dxr3_decoder_t *)this_gen)->sync_every_frame = entry->num_value; } static void dxr3_update_enhanced_mode(void *this_gen, xine_cfg_entry_t *entry) { ((dxr3_decoder_t *)this_gen)->enhanced_mode = entry->num_value; } static void dxr3_update_correct_durations(void *this_gen, xine_cfg_entry_t *entry) { ((dxr3_decoder_t *)this_gen)->correct_durations = entry->num_value; } �������������������������������������������������������������xine-lib-1.2/src/dxr3/ffmpeg_encoder.c��������������������������������������������������������������0000644�0001750�0001750�00000031505�14647725152�015446� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* mpeg encoders for the dxr3 video out plugin. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <errno.h> #include <math.h> #define LOG_MODULE "dxr3_mpeg_encoder" /* #define LOG_VERBOSE */ /* #define LOG */ #include "video_out_dxr3.h" #ifdef HAVE_FFMPEG_AVUTIL_H # include <avcodec.h> #else # include <libavcodec/avcodec.h> # include <libavutil/mem.h> #endif #include "../combined/ffmpeg/ffmpeg_compat.h" /* av_opt_set_int (), _after_ ffmpeg_compat.h */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(56,56,101) # include <libavutil/opt.h> #endif #if XFF_ENCVIDEO == 1 /* buffer size for encoded mpeg1 stream; will hold one intra frame * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ #define DEFAULT_BUFFER_SIZE 512*1024 #endif /* functions required by encoder api */ static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame); static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame); static int lavc_on_unneeded(dxr3_driver_t *drv); /*encoder structure*/ typedef struct lavc_data_s { encoder_data_t encoder_data; AVCodecContext *context; /* handle for encoding */ int width, height; /* width and height of the video frame */ #if XFF_ENCVIDEO == 1 uint8_t *ffmpeg_buffer; /* lavc buffer */ #endif AVFrame *picture; /* picture to be encoded */ uint8_t *out[3]; /* aligned buffer for YV12 data */ uint8_t *buf; /* base address of YV12 buffer */ #if XFF_ENCVIDEO > 1 XFF_PACKET_DECL (pkt); #endif } lavc_data_t; static int dxr3_lavc_close(dxr3_driver_t *drv) { drv->enc->on_unneeded(drv); free(drv->enc); drv->enc = NULL; return 1; } int dxr3_lavc_init(dxr3_driver_t *drv, plugin_node_t *plugin) { lavc_data_t* this; lprintf("lavc init , version %x\n", avcodec_version()); this = calloc(1, sizeof(lavc_data_t)); if (!this) return 0; (void)plugin; XFF_AVCODEC_INIT(); XFF_AVCODEC_REGISTER_ALL(); #if XFF_ENCVIDEO > 1 XFF_PACKET_NEW (this->pkt); #endif this->encoder_data.type = ENC_LAVC; this->encoder_data.on_update_format = lavc_on_update_format; this->encoder_data.on_frame_copy = NULL; this->encoder_data.on_display_frame = lavc_on_display_frame; this->encoder_data.on_unneeded = lavc_on_unneeded; this->context = 0; drv->enc = &this->encoder_data; drv->enc->on_close = dxr3_lavc_close; return 1; } /* helper function */ static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame); static int lavc_on_update_format(dxr3_driver_t *drv, dxr3_frame_t *frame) { lavc_data_t *this = (lavc_data_t *)drv->enc; const AVCodec *codec; unsigned char use_quantizer; if (this->context) { XFF_FREE_CONTEXT (this->context); free(this->picture); this->picture = NULL; } /* if YUY2 and dimensions changed, we need to re-allocate the * internal YV12 buffer */ if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { int image_size = frame->vo_frame.pitches[0] * frame->oheight; this->out[0] = this->buf = av_mallocz(image_size * 3/2); this->out[1] = this->out[0] + image_size; this->out[2] = this->out[1] + image_size/4; /* fill with black (yuv 16,128,128) */ memset(this->out[0], 16, image_size); memset(this->out[1], 128, image_size/4); memset(this->out[2], 128, image_size/4); lprintf("Using YUY2->YV12 conversion\n"); } /* resolution must be a multiple of two */ if ((frame->vo_frame.pitches[0] % 2 != 0) || (frame->oheight % 2 != 0)) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: lavc only handles video dimensions which are multiples of 2\n"); return 0; } /* get mpeg codec handle */ codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); if (!codec) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: lavc MPEG1 codec not found\n"); return 0; } lprintf("lavc MPEG1 encoder found.\n"); this->width = frame->vo_frame.pitches[0]; this->height = frame->oheight; this->context = XFF_ALLOC_CONTEXT(); if (!this->context) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: Couldn't start the ffmpeg library\n"); return 0; } this->picture = XFF_ALLOC_FRAME(); if (!this->picture) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: Couldn't allocate ffmpeg frame\n"); return 0; } /* mpeg1 encoder only support YUV420P */ this->context->pix_fmt = PIX_FMT_YUVJ420P; /* put sample parameters */ this->context->bit_rate = drv->class->xine->config->register_range(drv->class->xine->config, "dxr3.encoding.lavc_bitrate", 10000, 1000, 20000, _("libavcodec mpeg output bitrate (kbit/s)"), _("The bitrate the libavcodec mpeg encoder should use for DXR3's encoding mode. " "Higher values will increase quality and CPU usage.\n" "This setting is only considered, when constant quality mode is disabled."), 10, NULL, NULL); this->context->bit_rate *= 1000; /* config in kbit/s, libavcodec wants bit/s */ use_quantizer = drv->class->xine->config->register_bool(drv->class->xine->config, "dxr3.encoding.lavc_quantizer", 1, _("constant quality mode"), _("When enabled, libavcodec will use a constant quality mode by dynamically " "compressing the images based on their complexity. When disabled, libavcodec " "will use constant bitrate mode."), 10, NULL, NULL); if (use_quantizer) { this->context->qmin = drv->class->xine->config->register_range(drv->class->xine->config, "dxr3.encoding.lavc_qmin", 1, 1, 10, _("minimum compression"), _("The minimum compression to apply to an image in constant quality mode."), 10, NULL, NULL); this->context->qmax = drv->class->xine->config->register_range(drv->class->xine->config, "dxr3.encoding.lavc_qmax", 2, 1, 20, _("maximum quantizer"), _("The maximum compression to apply to an image in constant quality mode."), 10, NULL, NULL); } lprintf("lavc -> bitrate %" PRId64 " \n", (int64_t)this->context->bit_rate); this->context->width = frame->vo_frame.pitches[0]; this->context->height = frame->oheight; this->context->gop_size = 0; /*intra frames only */ /* TJ. this version is known to have that but maybe its not the first. */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(56,56,101) av_opt_set_int (this->context->priv_data, "motion_est", 0 /* "zero" */, 0); #else this->context->me_method = ME_ZERO; /*motion estimation type*/ #endif this->context->time_base.den = 90000; if (frame->vo_frame.duration > 90000 / 24) this->context->time_base.num = 90000 / 24; else if (frame->vo_frame.duration < 90000 / 60) this->context->time_base.num = 90000 / 60; else this->context->time_base.num = frame->vo_frame.duration; /* ffmpeg can complain about illegal framerates, but since this seems no * problem for the DXR3, we just tell ffmpeg to be more lax with */ this->context->strict_std_compliance = -1; /* open avcodec */ if (XFF_AVCODEC_OPEN(this->context, codec) < 0) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: could not open codec\n"); return 0; } lprintf("dxr3_mpeg_encoder: lavc MPEG1 codec opened.\n"); #if XFF_ENCVIDEO == 1 if (!this->ffmpeg_buffer) this->ffmpeg_buffer = (unsigned char *)malloc(DEFAULT_BUFFER_SIZE); /* why allocate more than needed ?! */ if (!this->ffmpeg_buffer) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: Couldn't allocate temp buffer for mpeg data\n"); return 0; } #endif return 1; } static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) { lavc_data_t* this = (lavc_data_t *)drv->enc; #if XFF_ENCVIDEO == 1 int size; #else /* 2, 3 */ int ret, got_output; this->pkt->data = NULL; #endif ssize_t written; if (frame->vo_frame.bad_frame) return 1; /* ignore old frames */ if ((frame->vo_frame.pitches[0] != this->context->width) || ((int)frame->oheight != this->context->height)) { frame->vo_frame.free(&frame->vo_frame); lprintf("LAVC ignoring frame !!!\n"); return 1; } /* prepare frame for conversion, handles YUY2 -> YV12 conversion when necessary */ lavc_prepare_frame(this, drv, frame); /* do the encoding */ #if XFF_ENCVIDEO == 1 size = avcodec_encode_video(this->context, this->ffmpeg_buffer, DEFAULT_BUFFER_SIZE, this->picture); #elif XFF_ENCVIDEO == 2 ret = avcodec_encode_video2(this->context, this->pkt, this->picture, &got_output); #else /* 3 */ got_output = 0; ret = avcodec_send_frame (this->context, this->picture); if ((ret >= 0) || (ret == AVERROR (EAGAIN))) { ret = avcodec_receive_packet (this->context, this->pkt); got_output = (ret == 0); ret = (ret == AVERROR (EAGAIN)) ? 0 : ret; } #endif frame->vo_frame.free(&frame->vo_frame); #if XFF_ENCVIDEO == 1 if (size < 0) #else /* 2, 3 */ if (ret < 0) #endif { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: encoding failed\n"); return 0; } #if XFF_ENCVIDEO >= 2 else if (!got_output) return 1; #endif #if XFF_ENCVIDEO == 1 written = write(drv->fd_video, this->ffmpeg_buffer, size); #else /* 2, 3 */ written = write(drv->fd_video, this->pkt->data, this->pkt->size); #endif if (written < 0) { xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); return 0; } #if XFF_ENCVIDEO == 1 if (written != size) xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: Could only write %zd of %d mpeg bytes.\n", written, size); #else /* 2, 3 */ if (written != this->pkt->size) xprintf(drv->class->xine, XINE_VERBOSITY_LOG, "dxr3_mpeg_encoder: Could only write %zd of %d mpeg bytes.\n", written, this->pkt->size); #endif return 1; } static int lavc_on_unneeded(dxr3_driver_t *drv) { lavc_data_t *this = (lavc_data_t *)drv->enc; lprintf("flushing buffers\n"); if (this->context) { #if XFF_ENCVIDEO > 1 XFF_PACKET_UNREF (this->pkt); #endif XFF_FREE_CONTEXT (this->context); free(this->picture); this->picture = NULL; } return 1; } static int lavc_prepare_frame(lavc_data_t *this, dxr3_driver_t *drv, dxr3_frame_t *frame) { int i, j, w2; uint8_t *yuy2; if (frame->vo_frame.bad_frame) return 1; if (frame->vo_frame.format == XINE_IMGFMT_YUY2) { /* need YUY2->YV12 conversion */ if (!(this->out[0] && this->out[1] && this->out[2]) ) { lprintf("Internal YV12 buffer not created.\n"); return 0; } this->picture->data[0] = this->out[0] + frame->vo_frame.pitches[0] * drv->top_bar; /* y */ this->picture->data[1] = this->out[1] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* u */ this->picture->data[2] = this->out[2] + (frame->vo_frame.pitches[0] / 2) * (drv->top_bar / 2); /* v */ yuy2 = frame->vo_frame.base[0]; w2 = frame->vo_frame.pitches[0] / 2; for (i = 0; i < frame->vo_frame.height; i += 2) { for (j = 0; j < w2; j++) { /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */ *(this->picture->data[0]++) = *(yuy2++); *(this->picture->data[1]++) = *(yuy2++); *(this->picture->data[0]++) = *(yuy2++); *(this->picture->data[2]++) = *(yuy2++); } /* down sampling */ for (j = 0; j < w2; j++) { /* skip every second line for U and V */ *(this->picture->data[0]++) = *(yuy2++); yuy2++; *(this->picture->data[0]++) = *(yuy2++); yuy2++; } } /* reset for encoder */ this->picture->data[0] = this->out[0]; this->picture->data[1] = this->out[1]; this->picture->data[2] = this->out[2]; } else { /* YV12 **/ this->picture->data[0] = frame->real_base[0]; this->picture->data[1] = frame->real_base[1]; this->picture->data[2] = frame->real_base[2]; } this->picture->linesize[0] = this->context->width; this->picture->linesize[1] = this->context->width / 2; this->picture->linesize[2] = this->context->width / 2; return 1; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/dxr3/compat.c����������������������������������������������������������������������0000644�0001750�0001750�00000002215�14647725152�013762� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2010-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <errno.h> #include <sys/ioctl.h> #include "video_out_dxr3.h" /* For compatibility with em8300 < 0.18.0 */ int dxr3_compat_ioctl (int fd, int rq, void *arg) { int ret = ioctl (fd, rq, arg); if (ret < 0 && (errno == EINVAL || errno == ENOTTY)) ret = ioctl (fd, rq & 0xFF, arg); return ret; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/��������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013233� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/flac_demuxer.h������������������������������������������������������������0000644�0001750�0001750�00000001717�14647725152�016050� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifndef XINE_FLAC_DEMUXER_H #define XINE_FLAC_DEMUXER_H #include <xine.h> void *demux_flac_init_class (xine_t *xine, const void *data); #endif /* XINE_FLAC_DEMUXER_H */ �������������������������������������������������xine-lib-1.2/src/combined/wavpack_combined.c��������������������������������������������������������0000644�0001750�0001750�00000003146�14647725152�016677� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2007-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include "wavpack_combined.h" static const demuxer_info_t demux_info_wv = { 0 /* priority */ }; static const uint32_t audio_types[] = { BUF_AUDIO_WAVPACK, 0 }; static const decoder_info_t decoder_info_wv = { audio_types, /* supported types */ 8 /* priority */ }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "wavpack", XINE_VERSION_CODE, &demux_info_wv, demux_wv_init_plugin }, { PLUGIN_AUDIO_DECODER, 16, "wavpackdec", XINE_VERSION_CODE, &decoder_info_wv, decoder_wavpack_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/nsf_demuxer.c�������������������������������������������������������������0000644�0001750�0001750�00000023470�14647725152�015724� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * NSF File "Demuxer" by Mike Melanson (melanson@pcisys.net) * This is really just a loader for NES Music File Format (extension NSF) * which loads an entire NSF file and passes it over to the NSF audio * decoder. * * After the file is sent over, the demuxer controls the playback by * sending empty buffers with incrementing pts values. * * For more information regarding the NSF format, visit: * http://www.tripoint.org/kevtris/nes/nsfspec.txt */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> /********** logging **********/ #define LOG_MODULE "demux_nsf" /* #define LOG_VERBOSE */ /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/demux.h> #include "bswap.h" #include "nsf_combined.h" #define NSF_HEADER_SIZE 0x80 #define NSF_SAMPLERATE 44100 #define NSF_BITS 8 #define NSF_CHANNELS 1 #define NSF_REFRESH_RATE 60 #define NSF_PTS_INC (90000 / NSF_REFRESH_RATE) typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; int total_songs; int current_song; int new_song; /* indicates song change */ char *title; char *artist; char *copyright; off_t filesize; int64_t current_pts; int file_sent; } demux_nsf_t; /* returns 1 if the NSF file was opened successfully, 0 otherwise */ static void parse_nsf_header(demux_nsf_t *this, const uint8_t *header) { this->total_songs = header[6]; this->current_song = header[7]; this->title = strndup((char*)&header[0x0E], 0x20); this->artist = strndup((char*)&header[0x2E], 0x20); this->copyright = strndup((char*)&header[0x4E], 0x20); this->filesize = this->input->get_length(this->input); } static int demux_nsf_send_chunk(demux_plugin_t *this_gen) { demux_nsf_t *this = (demux_nsf_t *) this_gen; buf_element_t *buf; int bytes_read; char title[100]; /* send chunks of the file to the decoder until file is completely * loaded; then send control buffers */ if (!this->file_sent) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_NSF; bytes_read = this->input->read(this->input, buf->content, buf->max_size); if (bytes_read <= 0) { /* the file has been completely loaded, free the buffer and start * sending control buffers */ buf->free_buffer(buf); this->file_sent = 1; } else { /* keep loading the file */ if (bytes_read < buf->max_size) buf->size = bytes_read; else buf->size = buf->max_size; buf->extra_info->input_normpos = 0; buf->extra_info->input_time = 0; buf->pts = 0; this->audio_fifo->put (this->audio_fifo, buf); } } /* this is not an 'else' because control might fall through from above */ if (this->file_sent) { /* send a control buffer */ buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); if (this->new_song) { buf->decoder_info[1] = this->current_song; this->new_song = 0; snprintf(title, sizeof(title), "%s, song %d/%d", this->title, this->current_song, this->total_songs); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, title); _x_demux_control_newpts(this->stream, this->current_pts, 0); } else buf->decoder_info[1] = 0; buf->type = BUF_AUDIO_NSF; if(this->total_songs) buf->extra_info->input_normpos = (this->current_song - 1) * 65535 / this->total_songs; buf->extra_info->input_time = this->current_pts / 90; buf->pts = this->current_pts; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); this->current_pts += NSF_PTS_INC; } return this->status; } static void demux_nsf_send_headers(demux_plugin_t *this_gen) { demux_nsf_t *this = (demux_nsf_t *) this_gen; buf_element_t *buf; char copyright[100]; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* load stream information */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, NSF_CHANNELS); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, NSF_SAMPLERATE); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, NSF_BITS); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, this->title); _x_meta_info_set(this->stream, XINE_META_INFO_ARTIST, this->artist); snprintf(copyright, sizeof(copyright), "(C) %s", this->copyright); _x_meta_info_set(this->stream, XINE_META_INFO_COMMENT, copyright); /* send start buffers */ _x_demux_control_start(this->stream); /* send init info to the audio decoder */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_NSF; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 5; buf->decoder_info[1] = NSF_SAMPLERATE; buf->decoder_info[2] = NSF_BITS; buf->decoder_info[3] = NSF_CHANNELS; /* send the NSF filesize in the body, big endian format */ buf->content[0] = (this->filesize >> 24) & 0xFF; buf->content[1] = (this->filesize >> 16) & 0xFF; buf->content[2] = (this->filesize >> 8) & 0xFF; buf->content[3] = (this->filesize >> 0) & 0xFF; /* send the requested song */ buf->content[4] = this->current_song + 5; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_nsf_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_nsf_t *this = (demux_nsf_t *) this_gen; start_pos = (off_t) ( (double) start_pos / 65535 * this->total_songs ); (void)start_time; /* if thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; /* reposition stream at the start for loading */ this->input->seek(this->input, 0, SEEK_SET); this->file_sent = 0; this->current_pts = 0; this->new_song = 1; } else { this->current_song = start_pos + 1; this->new_song = 1; this->current_pts = 0; _x_demux_flush_engine(this->stream); } return this->status; } static void demux_nsf_dispose (demux_plugin_t *this_gen) { demux_nsf_t *this = (demux_nsf_t *) this_gen; _x_freep(&this->title); _x_freep(&this->artist); _x_freep(&this->copyright); free(this); } static int demux_nsf_get_status (demux_plugin_t *this_gen) { demux_nsf_t *this = (demux_nsf_t *) this_gen; return this->status; } /* return the approximate length in miliseconds */ static int demux_nsf_get_stream_length (demux_plugin_t *this_gen) { (void)this_gen; return 0; } static uint32_t demux_nsf_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_nsf_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_nsf_t *this; unsigned char header[NSF_HEADER_SIZE]; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (_x_demux_read_header(input, header, sizeof(header)) != NSF_HEADER_SIZE) return NULL; /* check for the signature */ if (memcmp(header, "NESM\x1A", 5) != 0) return NULL; break; default: return NULL; } this = calloc(1, sizeof(demux_nsf_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_nsf_send_headers; this->demux_plugin.send_chunk = demux_nsf_send_chunk; this->demux_plugin.seek = demux_nsf_seek; this->demux_plugin.dispose = demux_nsf_dispose; this->demux_plugin.get_status = demux_nsf_get_status; this->demux_plugin.get_stream_length = demux_nsf_get_stream_length; this->demux_plugin.get_capabilities = demux_nsf_get_capabilities; this->demux_plugin.get_optional_data = demux_nsf_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; parse_nsf_header(this, header); return &this->demux_plugin; } void *demux_nsf_init_plugin (xine_t *xine, const void *data) { static const demux_class_t this = { .open_plugin = open_plugin, .description = N_("NES Music file demux plugin"), .identifier = "NSF", .mimetypes = NULL, .extensions = "nsf", .dispose = NULL }; (void)xine; (void)data; return (demux_class_t *)&this; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/Makefile.am���������������������������������������������������������������0000644�0001750�0001750�00000004255�14647725152�015275� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������SUBDIRS = ffmpeg include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) if ENABLE_WAVPACK xineplug_wavpack = xineplug_wavpack.la endif if ENABLE_NOSEFART xineplug_nsf = xineplug_nsf.la endif if ENABLE_LIBFLAC xineplug_flac = xineplug_flac.la endif $(top_builddir)/contrib/nosefart/libnosefart.la: $(MAKE) -C $(top_builddir)/contrib/nosefart xineplug_LTLIBRARIES = \ $(xineplug_wavpack) \ $(xineplug_flac) \ $(xineplug_nsf) xineplug_wavpack_la_SOURCES = wavpack_demuxer.c wavpack_decoder.c wavpack_combined.c wavpack_combined.h xineplug_wavpack_la_LIBADD = $(XINE_LIB) $(WAVPACK_LIBS) xineplug_wavpack_la_CFLAGS = $(AM_CFLAGS) $(WAVPACK_CFLAGS) xineplug_wavpack_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/demuxers xineplug_flac_la_SOURCES = flac_demuxer.c flac_demuxer.h flac_decoder.c xineplug_flac_la_LIBADD = $(XINE_LIB) $(LIBFLAC_LIBS) xineplug_flac_la_CFLAGS = $(AM_CFLAGS) $(LIBFLAC_CFLAGS) xineplug_nsf_la_SOURCES = nsf_decoder.c nsf_demuxer.c nsf_combined.c nsf_combined.h xineplug_nsf_la_LIBADD = $(XINE_LIB) $(top_builddir)/contrib/nosefart/libnosefart.la -lm xineplug_nsf_la_CFLAGS = $(AM_CFLAGS) -fno-strict-aliasing xineplug_nsf_la_CPPFLAGS = $(AM_CPPFLAGS) -DNSF_PLAYER -I$(top_srcdir)/contrib/nosefart -I$(top_srcdir)/src/demuxers xineplug_xiph_la_SOURCES = xine_ogg_demuxer.c ogg_combined.h ogg_combined.c xineplug_xiph_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_xiph_la_CFLAGS = $(AM_CFLAGS) xineplug_xiph_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/demuxers if ENABLE_VORBIS xineplug_LTLIBRARIES += xineplug_xiph.la xineplug_xiph_la_SOURCES += xine_vorbis_decoder.c xineplug_xiph_la_LIBADD += $(VORBIS_LIBS) xineplug_xiph_la_CFLAGS += $(VORBIS_CFLAGS) endif if ENABLE_THEORA xineplug_LTLIBRARIES += xineplug_xiph.la xineplug_xiph_la_SOURCES += xine_theora_decoder.c xineplug_xiph_la_LIBADD += $(THEORA_LIBS) xineplug_xiph_la_CFLAGS += $(THEORA_CFLAGS) endif if ENABLE_SPEEX xineplug_LTLIBRARIES += xineplug_xiph.la xineplug_xiph_la_SOURCES += xine_speex_decoder.c xineplug_xiph_la_LIBADD += $(SPEEX_LIBS) xineplug_xiph_la_CFLAGS += $(SPEEX_CFLAGS) endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/flac_demuxer.c������������������������������������������������������������0000644�0001750�0001750�00000050365�14647725152�016046� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * John McCutchan * FLAC demuxer (http://flac.sf.net) * * TODO: Skip id3v2 tags. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sched.h> #include <string.h> #include <stdlib.h> #include <FLAC/stream_decoder.h> #if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 8 #include <FLAC/seekable_stream_decoder.h> #define LEGACY_FLAC #else #undef LEGACY_FLAC #endif #define LOG_MODULE "demux_flac" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/demux.h> #include "flac_demuxer.h" #ifndef LEGACY_FLAC # define FLAC__SeekableStreamDecoder FLAC__StreamDecoder #endif /* FLAC Demuxer plugin */ typedef struct demux_flac_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int seek_flag; off_t data_start; off_t data_size; /* FLAC Stuff */ FLAC__SeekableStreamDecoder *flac_decoder; uint64_t total_samples; uint64_t bits_per_sample; uint64_t channels; uint64_t sample_rate; uint64_t length_in_msec; } demux_flac_t ; /* FLAC Callbacks */ static #ifdef LEGACY_FLAC FLAC__SeekableStreamDecoderReadStatus flac_read_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) #else FLAC__StreamDecoderReadStatus flac_read_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) #endif { demux_flac_t *this = (demux_flac_t *)client_data; input_plugin_t *input = this->input; off_t offset = *bytes; (void)decoder; lprintf("flac_read_callback\n"); /* This should only be called when flac is reading the metadata * of the flac stream. */ offset = input->read (input, buffer, offset); lprintf("Read %" PRId64 " / %zu bytes into buffer\n", (int64_t)offset, *bytes); /* This is the way to detect EOF with xine input plugins */ if ( offset <= 0 && *bytes != 0 ) { *bytes = offset; lprintf("Marking EOF\n"); this->status = DEMUX_FINISHED; #ifdef LEGACY_FLAC return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR; #else return FLAC__STREAM_DECODER_READ_STATUS_ABORT; #endif } else { *bytes = offset; lprintf("Read was perfect\n"); #ifdef LEGACY_FLAC return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK; #else return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; #endif } } static #ifdef LEGACY_FLAC FLAC__SeekableStreamDecoderSeekStatus #else FLAC__StreamDecoderSeekStatus #endif flac_seek_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) { input_plugin_t *input = ((demux_flac_t *)client_data)->input; off_t offset; (void)decoder; lprintf("flac_seek_callback\n"); offset = input->seek (input, absolute_byte_offset, SEEK_SET); if (offset == -1) #ifdef LEGACY_FLAC return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR; #else return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; #endif else #ifdef LEGACY_FLAC return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK; #else return FLAC__STREAM_DECODER_SEEK_STATUS_OK; #endif } static #ifdef LEGACY_FLAC FLAC__SeekableStreamDecoderTellStatus #else FLAC__StreamDecoderTellStatus #endif flac_tell_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) { input_plugin_t *input = ((demux_flac_t *)client_data)->input; off_t offset; (void)decoder; lprintf("flac_tell_callback\n"); offset = input->get_current_pos (input); *absolute_byte_offset = offset; #ifdef LEGACY_FLAC return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK; #else return FLAC__STREAM_DECODER_TELL_STATUS_OK; #endif } static #ifdef LEGACY_FLAC FLAC__SeekableStreamDecoderLengthStatus #else FLAC__StreamDecoderLengthStatus #endif flac_length_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) { input_plugin_t *input = ((demux_flac_t *)client_data)->input; off_t offset; (void)decoder; lprintf("flac_length_callback\n"); offset = input->get_length (input); if (offset > 0) { *stream_length = offset; } /* FIXME, can flac handle -1 as offset ? */ #ifdef LEGACY_FLAC return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK; #else return FLAC__STREAM_DECODER_LENGTH_STATUS_OK; #endif } static FLAC__bool flac_eof_callback (const FLAC__SeekableStreamDecoder *decoder, void *client_data) { demux_flac_t *this = (demux_flac_t *)client_data; (void)decoder; lprintf("flac_eof_callback\n"); if (this->status == DEMUX_FINISHED) { lprintf("flac_eof_callback: True!\n"); return true; } else { lprintf("flac_eof_callback: False!\n"); return false; } } static FLAC__StreamDecoderWriteStatus flac_write_callback (const FLAC__SeekableStreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) { /* This should never be called, all we use flac for in this demuxer * is seeking. We do the decoding in the decoder */ (void)decoder; (void)frame; (void)buffer; (void)client_data; lprintf("Error: Write callback was called!\n"); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } static void flac_metadata_callback (const FLAC__SeekableStreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { demux_flac_t *this = (demux_flac_t *)client_data; (void)decoder; lprintf("IN: Metadata callback\n"); /* This should be called when we first look at a flac stream, * We get information about the stream here. */ if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { lprintf("Got METADATA!\n"); this->total_samples = metadata->data.stream_info.total_samples; this->bits_per_sample = metadata->data.stream_info.bits_per_sample; this->channels = metadata->data.stream_info.channels; this->sample_rate = metadata->data.stream_info.sample_rate; if (this->sample_rate) this->length_in_msec = (this->total_samples * 1000) / this->sample_rate; } return; } static void flac_error_callback (const FLAC__SeekableStreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { demux_flac_t *this = (demux_flac_t *)client_data; /* This will be called if there is an error when flac is seeking * in the stream. */ (void)decoder; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: flac_error_callback\n"); if (status == FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: Decoder lost synchronization.\n"); else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: Decoder encounted a corrupted frame header.\n"); else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: Frame's data did not match the CRC in the footer.\n"); else xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_flac: unknown error.\n"); this->status = DEMUX_FINISHED; return; } /* FLAC Demuxer plugin */ static int demux_flac_send_chunk (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; buf_element_t *buf = NULL; off_t current_file_pos, file_size = 0; int64_t current_pts; /*unsigned*/ int remaining_sample_bytes; remaining_sample_bytes = 2048; current_file_pos = this->input->get_current_pos (this->input) - this->data_start; if( (this->data_size - this->data_start) > 0 ) file_size = (this->data_size - this->data_start); current_pts = current_file_pos; current_pts *= this->length_in_msec * 90; if( file_size ) current_pts /= file_size; if (this->seek_flag) { #ifdef USE_ESTIMATED_PTS _x_demux_control_newpts (this->stream, current_pts, BUF_FLAG_SEEK); #else _x_demux_control_newpts (this->stream, 0, BUF_FLAG_SEEK); #endif this->seek_flag = 0; } while (remaining_sample_bytes) { if(!this->audio_fifo) { this->status = DEMUX_FINISHED; break; } buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_FLAC; if( file_size ) buf->extra_info->input_normpos = (int) ((double)current_file_pos * 65535 / file_size); buf->extra_info->input_time = current_pts / 90; #ifdef USE_ESTIMATED_PTS buf->pts = current_pts; #else buf->pts = 0; #endif if (remaining_sample_bytes > buf->max_size) buf->size = buf->max_size; else buf->size = remaining_sample_bytes; remaining_sample_bytes -= buf->size; if (this->input->read (this->input,buf->content,buf->size)!=buf->size) { lprintf("buf->size != input->read()\n"); buf->free_buffer (buf); this->status = DEMUX_FINISHED; break; } /* if (!remaining_sample_bytes) { buf->decoder_flags |= BUF_FLAG_FRAME_END; }*/ this->audio_fifo->put (this->audio_fifo, buf); } return this->status; } static void demux_flac_send_headers (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; buf_element_t *buf; lprintf("demux_flac_send_headers\n"); this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->sample_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->bits_per_sample); _x_demux_control_start (this->stream); if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_FLAC; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = this->sample_rate; buf->decoder_info[2] = this->bits_per_sample; buf->decoder_info[3] = this->channels; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static void demux_flac_dispose (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; lprintf("demux_flac_dispose\n"); if (this->flac_decoder) #ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_delete (this->flac_decoder); #else FLAC__stream_decoder_delete (this->flac_decoder); #endif free(this); return; } static int demux_flac_get_status (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; lprintf("demux_flac_get_status\n"); return this->status; } static int demux_flac_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_flac_t *this = (demux_flac_t *) this_gen; (void)playing; lprintf("demux_flac_seek\n"); start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); if (!start_pos && start_time) { double distance = (double)start_time; if (this->length_in_msec != 0) { distance /= (double)this->length_in_msec; } start_pos = (uint64_t)(distance * (this->data_size - this->data_start)); } if (start_pos || !start_time) { start_pos += this->data_start; this->input->seek (this->input, start_pos, SEEK_SET); lprintf ("Seek to position: %" PRId64 "\n", (int64_t)start_pos); } else { double distance = (double)start_time; uint64_t target_sample; FLAC__bool s = false; if (this->length_in_msec != 0) { distance /= (double)this->length_in_msec; } target_sample = (uint64_t)(distance * this->total_samples); #ifdef LEGACY_FLAC s = FLAC__seekable_stream_decoder_seek_absolute (this->flac_decoder, target_sample); #else s = FLAC__stream_decoder_seek_absolute (this->flac_decoder, target_sample); #endif if (s) { lprintf ("Seek to: %d successfull!\n", start_time); } else this->status = DEMUX_FINISHED; } _x_demux_flush_engine (this->stream); this->seek_flag = 1; return this->status; } static int demux_flac_get_stream_length (demux_plugin_t *this_gen) { demux_flac_t *this = (demux_flac_t *) this_gen; lprintf("demux_flac_get_stream_length\n"); if (this->flac_decoder) return this->length_in_msec; else return 0; } static uint32_t demux_flac_get_capabilities (demux_plugin_t *this_gen) { lprintf("demux_flac_get_capabilities\n"); (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_flac_get_optional_data (demux_plugin_t *this_gen, void *data, int dtype) { lprintf("demux_flac_get_optional_data\n"); (void)this_gen; (void)data; (void)dtype; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t * open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_flac_t *this; lprintf("open_plugin\n"); switch (stream->content_detection_method) { case METHOD_BY_CONTENT: { uint8_t buf[4]; /* * try to get a preview of the data */ if (_x_demux_read_header(input, buf, sizeof(buf)) < 4) return NULL; /* FIXME: Skip id3v2 tag */ /* Look for fLaC tag at the beginning of file */ if ( (buf[0] != 'f') || (buf[1] != 'L') || (buf[2] != 'a') || (buf[3] != 'C') ) return NULL; } break; case METHOD_BY_MRL: case METHOD_EXPLICIT: break; default: return NULL; break; } /* * if we reach this point, the input has been accepted. */ this = calloc(1, sizeof (demux_flac_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_flac_send_headers; this->demux_plugin.send_chunk = demux_flac_send_chunk; this->demux_plugin.seek = demux_flac_seek; this->demux_plugin.dispose = demux_flac_dispose; this->demux_plugin.get_status = demux_flac_get_status; this->demux_plugin.get_stream_length = demux_flac_get_stream_length; this->demux_plugin.get_capabilities = demux_flac_get_capabilities; this->demux_plugin.get_optional_data = demux_flac_get_optional_data; this->demux_plugin.demux_class = class_gen; this->seek_flag = 0; /* Get a new FLAC decoder and hook up callbacks */ #ifdef LEGACY_FLAC this->flac_decoder = FLAC__seekable_stream_decoder_new(); lprintf("this->flac_decoder: %p\n", (void*)this->flac_decoder); FLAC__seekable_stream_decoder_set_md5_checking (this->flac_decoder, false); FLAC__seekable_stream_decoder_set_read_callback (this->flac_decoder, flac_read_callback); FLAC__seekable_stream_decoder_set_seek_callback (this->flac_decoder, flac_seek_callback); FLAC__seekable_stream_decoder_set_tell_callback (this->flac_decoder, flac_tell_callback); FLAC__seekable_stream_decoder_set_length_callback (this->flac_decoder, flac_length_callback); FLAC__seekable_stream_decoder_set_eof_callback (this->flac_decoder, flac_eof_callback); FLAC__seekable_stream_decoder_set_metadata_callback (this->flac_decoder, flac_metadata_callback); FLAC__seekable_stream_decoder_set_write_callback (this->flac_decoder, flac_write_callback); FLAC__seekable_stream_decoder_set_error_callback (this->flac_decoder, flac_error_callback); FLAC__seekable_stream_decoder_set_client_data (this->flac_decoder, this); FLAC__seekable_stream_decoder_init (this->flac_decoder); #else this->flac_decoder = FLAC__stream_decoder_new(); lprintf("this->flac_decoder: %p\n", (void*)this->flac_decoder); if ( ! this->flac_decoder ) { free(this); return NULL; } FLAC__stream_decoder_set_md5_checking (this->flac_decoder, false); if ( FLAC__stream_decoder_init_stream(this->flac_decoder, flac_read_callback, flac_seek_callback, flac_tell_callback, flac_length_callback, flac_eof_callback, flac_write_callback, flac_metadata_callback, flac_error_callback, this ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { #ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_delete (this->flac_decoder); #else FLAC__stream_decoder_delete (this->flac_decoder); #endif free(this); return NULL; } #endif /* Get some stream info */ this->data_size = this->input->get_length (this->input); this->data_start = this->input->get_current_pos (this->input); /* This will cause FLAC to give us the rest of the information on * this flac stream */ this->status = DEMUX_OK; #ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_process_until_end_of_metadata (this->flac_decoder); #else FLAC__stream_decoder_process_until_end_of_metadata (this->flac_decoder); #endif lprintf("Processed file until end of metadata: %s\n", this->status == DEMUX_OK ? "success" : "failure"); if (this->status != DEMUX_OK) { #ifdef LEGACY_FLAC FLAC__seekable_stream_decoder_delete (this->flac_decoder); #else FLAC__stream_decoder_delete (this->flac_decoder); #endif free (this); return NULL; } return &this->demux_plugin; } /* FLAC Demuxer class */ void * demux_flac_init_class (xine_t *xine, const void *data) { static const demux_class_t demux_flac_class = { .open_plugin = open_plugin, .description = N_("FLAC demux plugin"), .identifier = "FLAC", .mimetypes = "application/x-flac: flac: FLAC Audio;" "application/flac: flac: FLAC Audio;", .extensions = "flac", .dispose = NULL, }; (void)xine; (void)data; lprintf("demux_flac_init_class\n"); return (void *)&demux_flac_class; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/flac_decoder.c������������������������������������������������������������0000644�0001750�0001750�00000031244�14647725152�015775� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * John McCutchan 2003 * FLAC Decoder (http://flac.sf.net) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <FLAC/stream_decoder.h> #if !defined FLAC_API_VERSION_CURRENT || FLAC_API_VERSION_CURRENT < 8 #include <FLAC/seekable_stream_decoder.h> #define LEGACY_FLAC #else #undef LEGACY_FLAC #endif #define LOG_MODULE "flac_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include "flac_demuxer.h" typedef struct flac_decoder_s { audio_decoder_t audio_decoder; int64_t pts; xine_stream_t *stream; FLAC__StreamDecoder *flac_decoder; unsigned char *buf; size_t buf_size; size_t buf_pos; size_t min_size; int output_open; } flac_decoder_t; /* * FLAC callback functions */ #ifdef LEGACY_FLAC static FLAC__StreamDecoderReadStatus flac_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], unsigned *bytes, void *client_data) #else static FLAC__StreamDecoderReadStatus flac_read_callback (const FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) #endif { flac_decoder_t *this = (flac_decoder_t *)client_data; size_t number_of_bytes_to_copy; (void)decoder; lprintf("flac_read_callback: %zd\n", (size_t)*bytes); if (this->buf_pos > *bytes) number_of_bytes_to_copy = *bytes; else number_of_bytes_to_copy = this->buf_pos; lprintf("number_of_bytes_to_copy: %zd\n", number_of_bytes_to_copy); *bytes = number_of_bytes_to_copy; xine_fast_memcpy (buffer, this->buf, number_of_bytes_to_copy); this->buf_pos -= number_of_bytes_to_copy; memmove(this->buf, &this->buf[number_of_bytes_to_copy], this->buf_pos ); if(number_of_bytes_to_copy) return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; else return FLAC__STREAM_DECODER_READ_STATUS_ABORT; } static FLAC__StreamDecoderWriteStatus flac_write_callback (const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data) { flac_decoder_t *this = (flac_decoder_t *)client_data; audio_buffer_t *audio_buffer = NULL; unsigned int samples_left = frame->header.blocksize; unsigned int bytes_per_sample = (frame->header.bits_per_sample <= 8) ? 1 : 2; unsigned int buf_samples; int8_t *data8; int16_t *data16; unsigned int i,j; (void)decoder; lprintf("flac_write_callback\n"); while( samples_left ) { audio_buffer = this->stream->audio_out->get_buffer(this->stream->audio_out); if( (unsigned)audio_buffer->mem_size < samples_left * frame->header.channels * bytes_per_sample ) buf_samples = audio_buffer->mem_size / (frame->header.channels * bytes_per_sample); else buf_samples = samples_left; switch (frame->header.bits_per_sample) { case 8: data8 = (int8_t *)audio_buffer->mem; for( j=0; j < buf_samples; j++ ) for( i=0; i < frame->header.channels; i++ ) *data8++ = buffer[i][j]; break; case 16: data16 = (int16_t *)audio_buffer->mem; for( j=0; j < buf_samples; j++ ) for( i=0; i < frame->header.channels; i++ ) *data16++ = buffer[i][j]; break; case 24: data16 = (int16_t *)audio_buffer->mem; for( j=0; j < buf_samples; j++ ) for( i=0; i < frame->header.channels; i++ ) *data16++ = buffer[i][j] >> 8; break; } audio_buffer->num_frames = buf_samples; audio_buffer->vpts = this->pts; this->pts = 0; this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); samples_left -= buf_samples; } return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; } #ifdef LEGACY_FLAC static void flac_metadata_callback (const FLAC__StreamDecoder *decoder, const FLAC__StreamMetadata *metadata, void *client_data) { /* flac_decoder_t *this = (flac_decoder_t *)client_data; */ lprintf("Metadata callback called!\n"); #ifdef LOG if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) { printf("libflac: min_blocksize = %d\n", metadata->data.stream_info.min_blocksize); printf("libflac: max_blocksize = %d\n", metadata->data.stream_info.max_blocksize); printf("libflac: min_framesize = %d\n", metadata->data.stream_info.min_framesize); printf("libflac: max_framesize = %d\n", metadata->data.stream_info.max_framesize); /* does not work well: this->min_size = 2 * metadata->data.stream_info.max_blocksize; */ } #else (void)decoder; (void)metadata; (void)client_data; #endif return; } #endif static void flac_error_callback (const FLAC__StreamDecoder *decoder, FLAC__StreamDecoderErrorStatus status, void *client_data) { /* This will be called if there is an error in the flac stream */ lprintf("flac_error_callback\n"); #ifdef LOG if (status == FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC) printf("libflac: Decoder lost synchronization.\n"); else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER) printf("libflac: Decoder encounted a corrupted frame header.\n"); else if (status == FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH) printf("libflac: Frame's data did not match the CRC in the footer.\n"); else printf("libflac: unknown error.\n"); #else (void)decoder; (void)status; (void)client_data; #endif return; } /* * FLAC plugin decoder */ static void flac_reset (audio_decoder_t *this_gen) { flac_decoder_t *this = (flac_decoder_t *) this_gen; this->buf_pos = 0; if( FLAC__stream_decoder_get_state(this->flac_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ) FLAC__stream_decoder_flush (this->flac_decoder); } static void flac_discontinuity (audio_decoder_t *this_gen) { flac_decoder_t *this = (flac_decoder_t *) this_gen; this->pts = 0; lprintf("Discontinuity!\n"); } static void flac_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { flac_decoder_t *this = (flac_decoder_t *) this_gen; int ret = 1; /* We are getting the stream header, open up the audio * device, and collect information about the stream */ if (buf->decoder_flags & BUF_FLAG_STDHEADER) { const int sample_rate = buf->decoder_info[1]; const int bits_per_sample = buf->decoder_info[2]; const int channels = buf->decoder_info[3]; const int mode = _x_ao_channels2mode(channels); if (!this->output_open) { const int bits = bits_per_sample; this->output_open = (this->stream->audio_out->open) ( this->stream->audio_out, this->stream, bits > 16 ? 16 : bits, sample_rate, mode); } this->buf_pos = 0; } else if (this->output_open) { /* This isn't a header frame and we have opened the output device */ /* What we have buffered so far, and what is coming in * is larger than our buffer */ if (this->buf_pos + buf->size > this->buf_size) { this->buf_size += 2 * buf->size; this->buf = realloc (this->buf, this->buf_size); lprintf("reallocating buffer to %zu\n", this->buf_size); } xine_fast_memcpy (&this->buf[this->buf_pos], buf->content, buf->size); this->buf_pos += buf->size; if (buf->pts) this->pts = buf->pts; /* We have enough to decode a frame */ while( ret && this->buf_pos > this->min_size ) { FLAC__StreamDecoderState state = FLAC__stream_decoder_get_state(this->flac_decoder); if( state == FLAC__STREAM_DECODER_SEARCH_FOR_METADATA ) { lprintf("process_until_end_of_metadata\n"); ret = FLAC__stream_decoder_process_until_end_of_metadata (this->flac_decoder); } else if ( state == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC || state == FLAC__STREAM_DECODER_READ_FRAME ) { lprintf("process_single\n"); ret = FLAC__stream_decoder_process_single (this->flac_decoder); } else { lprintf("aborted.\n"); FLAC__stream_decoder_flush (this->flac_decoder); break; } } } else return; } static void flac_dispose (audio_decoder_t *this_gen) { flac_decoder_t *this = (flac_decoder_t *) this_gen; FLAC__stream_decoder_finish (this->flac_decoder); FLAC__stream_decoder_delete (this->flac_decoder); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); if (this->buf) free(this->buf); free (this_gen); } static audio_decoder_t * open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { flac_decoder_t *this ; (void)class_gen; this = calloc(1, sizeof (flac_decoder_t)); if (!this) return NULL; this->audio_decoder.decode_data = flac_decode_data; this->audio_decoder.reset = flac_reset; this->audio_decoder.discontinuity = flac_discontinuity; this->audio_decoder.dispose = flac_dispose; this->stream = stream; this->output_open = 0; this->buf = NULL; this->buf_size = 0; this->min_size = 65536; this->pts = 0; this->flac_decoder = FLAC__stream_decoder_new(); #ifdef LEGACY_FLAC FLAC__stream_decoder_set_read_callback (this->flac_decoder, flac_read_callback); FLAC__stream_decoder_set_write_callback (this->flac_decoder, flac_write_callback); FLAC__stream_decoder_set_metadata_callback (this->flac_decoder, flac_metadata_callback); FLAC__stream_decoder_set_error_callback (this->flac_decoder, flac_error_callback); FLAC__stream_decoder_set_client_data (this->flac_decoder, this); if (FLAC__stream_decoder_init (this->flac_decoder) != FLAC__STREAM_DECODER_SEARCH_FOR_METADATA) { free (this); return NULL; } #else if ( FLAC__stream_decoder_init_stream (this->flac_decoder, flac_read_callback, NULL, /* seek */ NULL, /* tell */ NULL, /* length */ NULL, /* eof */ flac_write_callback, NULL, /* metadata */ flac_error_callback, this ) != FLAC__STREAM_DECODER_INIT_STATUS_OK ) { free (this); return NULL; } #endif return (audio_decoder_t *) this; } /* * flac plugin class */ static void *init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "flacdec", .description = N_("flac audio decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (audio_decoder_class_t *)&this; } static const uint32_t audio_types[] = { BUF_AUDIO_FLAC, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 8, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "flac", XINE_VERSION_CODE, NULL, demux_flac_init_class }, { PLUGIN_AUDIO_DECODER, 16, "flacdec", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/xine_speex_decoder.c������������������������������������������������������0000644�0001750�0001750�00000025551�14647725152�017243� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * (ogg/)speex audio decoder plugin (libspeex wrapper) for xine */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #define LOG_MODULE "speex_decoder" #define LOG_VERBOSE /* #define LOG */ #define LOG_BUFFERS 0 #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <ogg/ogg.h> #include <speex/speex.h> #include <speex/speex_header.h> #include <speex/speex_callbacks.h> #include <speex/speex_stereo.h> #include "ogg_combined.h" #define MAX_FRAME_SIZE 2000 typedef struct speex_decoder_s { audio_decoder_t audio_decoder; int64_t pts; int output_sampling_rate; int output_open; int output_mode; /* speex stuff */ void *st; int frame_size; int rate; int nframes; int channels; SpeexBits bits; SpeexStereoState stereo; int expect_metadata; int header_count; xine_stream_t *stream; } speex_decoder_t; static void speex_reset (audio_decoder_t *this_gen) { speex_decoder_t *this = (speex_decoder_t *) this_gen; speex_bits_init (&this->bits); } static void speex_discontinuity (audio_decoder_t *this_gen) { speex_decoder_t *this = (speex_decoder_t *) this_gen; this->pts=0; } /* Known speex comment keys from ogg123 sources*/ static const struct { char key[16]; /* includes the '=' for programming convenience */ int xine_metainfo_index; } speex_comment_keys[] = { {"ARTIST=", XINE_META_INFO_ARTIST}, {"ALBUM=", XINE_META_INFO_ALBUM}, {"TITLE=", XINE_META_INFO_TITLE}, {"GENRE=", XINE_META_INFO_GENRE}, {"DESCRIPTION=", XINE_META_INFO_COMMENT}, {"DATE=", XINE_META_INFO_YEAR} }; #define readint(buf, base) (((buf[base+3]<<24)&0xff000000)| \ ((buf[base+2]<<16)&0xff0000)| \ ((buf[base+1]<<8)&0xff00)| \ (buf[base]&0xff)) static void read_metadata (speex_decoder_t *this, char * comments, int length) { char * c = comments; unsigned len, i, nb_fields; char * end; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "speex"); if (length < 8) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); return; } end = c+length; len = readint (c, 0); c += 4; if (c+len > end) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); return; } #ifdef LOG /* Encoder */ printf ("libspeex: "); fwrite (c, 1, len, stdout); printf ("\n"); #endif c += len; if (c+4 > end) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); return; } nb_fields = readint (c, 0); c += 4; for (i = 0; i < nb_fields; i++) { if (c+4 > end) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); return; } len = readint (c, 0); c += 4; if (c+len > end) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: invalid/corrupted comments\n"); return; } #ifdef LOG printf ("libspeex: "); fwrite (c, 1, len, stdout); printf ("\n"); #endif for (i = 0; i < (sizeof(speex_comment_keys)/sizeof(speex_comment_keys[0])); i++) { size_t keylen = strlen(speex_comment_keys[i].key); if ( !strncasecmp (speex_comment_keys[i].key, c, keylen) ) { char meta_info[(len - keylen) + 1]; lprintf ("known metadata %u %d\n", i, speex_comment_keys[i].xine_metainfo_index); strncpy(meta_info, &c[keylen], len-keylen); _x_meta_info_set_utf8(this->stream, speex_comment_keys[i].xine_metainfo_index, meta_info); } } c += len; } } static void speex_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { speex_decoder_t *this = (speex_decoder_t *) this_gen; char *const buf_content = (char*)buf->content; llprintf (LOG_BUFFERS, "decode buf=%8p content=%8p flags=%08x\n", (void*)buf, (void*)buf->content, buf->decoder_flags); if ( (buf->decoder_flags & BUF_FLAG_HEADER) && !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { lprintf ("preview buffer, %d headers to go\n", this->header_count); if (this->header_count) { if (!this->st) { const SpeexMode * spx_mode; SpeexHeader * spx_header; unsigned int modeID; int bitrate; speex_bits_init (&this->bits); spx_header = speex_packet_to_header (buf_content, buf->size); if (!spx_header) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: could not read Speex header\n"); return; } modeID = (unsigned int)spx_header->mode; if (modeID >= SPEEX_NB_MODES) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid mode ID %u\n", modeID); return; } spx_mode = speex_mode_list[modeID]; if (spx_mode->bitstream_version != spx_header->mode_bitstream_version) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: incompatible Speex mode bitstream version\n"); return; } this->st = speex_decoder_init (spx_mode); if (!this->st) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: decoder initialization failed\n"); return; } this->rate = spx_header->rate; speex_decoder_ctl (this->st, SPEEX_SET_SAMPLING_RATE, &this->rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->rate); this->channels = spx_header->nb_channels; if (this->channels == 2) { SpeexCallback callback; callback.callback_id = SPEEX_INBAND_STEREO; callback.func = speex_std_stereo_request_handler; callback.data = &this->stereo; speex_decoder_ctl (this->st, SPEEX_SET_HANDLER, &callback); } this->nframes = spx_header->frames_per_packet; if (!this->nframes) this->nframes = 1; speex_decoder_ctl (this->st, SPEEX_GET_FRAME_SIZE, &this->frame_size); speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate); if (bitrate <= 1) bitrate = 16000; /* assume 16 kbit */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, bitrate); this->header_count += spx_header->extra_headers; this->expect_metadata = 1; free (spx_header); } else if (this->expect_metadata) { read_metadata (this, buf_content, buf->size); } this->header_count--; if (!this->header_count) { int mode = _x_ao_channels2mode(this->channels); if (!this->output_open) { this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->rate, mode); lprintf ("this->output_open after attempt is %d\n", this->output_open); } } } } else if (this->output_open) { int j; audio_buffer_t *audio_buffer; audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); speex_bits_read_from (&this->bits, buf_content, buf->size); for (j = 0; j < this->nframes; j++) { int ret; int bitrate; ret = speex_decode_int (this->st, &this->bits, audio_buffer->mem); if (ret==-1) break; if (ret==-2) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: Decoding error, corrupted stream?\n"); break; } if (speex_bits_remaining(&this->bits)<0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libspeex: Decoding overflow, corrupted stream?\n"); break; } if (this->channels == 2) { speex_decode_stereo_int (audio_buffer->mem, this->frame_size, &this->stereo); } speex_decoder_ctl (this->st, SPEEX_GET_BITRATE, &bitrate); if (bitrate <= 1) bitrate = 16000; /* assume 16 kbit */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, bitrate); audio_buffer->vpts = this->pts; this->pts=0; audio_buffer->num_frames = this->frame_size; this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); buf->pts=0; } } else { llprintf (LOG_BUFFERS, "output not open\n"); } } static void speex_dispose (audio_decoder_t *this_gen) { speex_decoder_t *this = (speex_decoder_t *) this_gen; if (this->st) { speex_decoder_destroy (this->st); } speex_bits_destroy (&this->bits); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { speex_decoder_t *this ; static SpeexStereoState init_stereo = SPEEX_STEREO_STATE_INIT; (void)class_gen; this = (speex_decoder_t *) calloc(1, sizeof(speex_decoder_t)); if (!this) return NULL; this->audio_decoder.decode_data = speex_decode_data; this->audio_decoder.reset = speex_reset; this->audio_decoder.discontinuity = speex_discontinuity; this->audio_decoder.dispose = speex_dispose; this->stream = stream; this->output_open = 0; this->header_count = 1; this->expect_metadata = 0; this->st = NULL; this->channels = 1; memcpy (&this->stereo, &init_stereo, sizeof (SpeexStereoState)); return (audio_decoder_t *) this; } /* * speex plugin class */ void *speex_init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t decode_speex_class = { .open_plugin = open_plugin, .identifier = "speex", .description = N_("Speex audio decoder plugin"), .dispose = NULL, }; (void)xine; (void)data; return (void*)&decode_speex_class; } �������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014477� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/ff_video_decoder.c�������������������������������������������������0000644�0001750�0001750�00000315202�14647725152�020114� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine video decoder plugin using ffmpeg */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <inttypes.h> #include <string.h> #include <pthread.h> #include <math.h> #include <assert.h> #if defined(HAVE_LIBAVUTIL_AVUTIL_H) # include <libavutil/avutil.h> #endif #if defined(HAVE_LIBAVUTIL_MEM_H) # include <libavutil/mem.h> #endif #if defined(HAVE_AVUTIL_AVCODEC_H) # include <libavcodec/avcodec.h> #else # include <avcodec.h> #endif #define LOG_MODULE "ffmpeg_video_dec" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include "bswap.h" #include <xine/buffer.h> #include <xine/xineutils.h> #include "ffmpeg_decoder.h" #include "ff_mpeg_parser.h" #include "ffmpeg_compat.h" #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(59,0,100) # undef HAVE_POSTPROC #endif #ifdef HAVE_POSTPROC # ifdef HAVE_FFMPEG_AVUTIL_H # include <postprocess.h> # else # include <libpostproc/postprocess.h> # include <libavutil/mem.h> # endif #endif #ifdef HAVE_VA_VA_H # if XFF_VAAPI == 1 # include <libavcodec/vaapi.h> # elif XFF_VAAPI == 2 # warning rumms # include <libavutil/hwcontext.h> # include <libavutil/hwcontext_vaapi.h> # endif # include "accel_vaapi.h" # define ENABLE_VAAPI 1 #endif #if defined(ARCH_X86) && defined(HAVE_MMX) # include "xine_mmx.h" # define ENABLE_EMMS #endif /* #undef XFF_AVCODEC_SLICE_TABLE #define XFF_AVCODEC_SLICE_TABLE 1 */ #define VIDEOBUFSIZE (128*1024) #define SLICE_BUFFER_SIZE (1194*1024) #define SLICE_OFFSET_SIZE 128 #define ENABLE_DIRECT_RENDERING #ifndef ENABLE_DIRECT_RENDERING # undef ENABLE_VAAPI #endif typedef struct ff_video_decoder_s ff_video_decoder_t; typedef struct ff_video_class_s { video_decoder_class_t decoder_class; #ifdef HAVE_POSTPROC int pp_quality; #endif int thread_count; int8_t skip_loop_filter_enum; int8_t choose_speed_over_accuracy; uint8_t enable_dri; uint8_t enable_vaapi; uint8_t vaapi_mpeg_softdec; xine_t *xine; } ff_video_class_t; struct ff_video_decoder_s { video_decoder_t video_decoder; ff_video_class_t *class; xine_stream_t *stream; int64_t pts; int64_t last_pts; int64_t tagged_pts; int video_step; int reported_video_step; uint8_t pts_tag_pass; uint8_t decoder_ok:1; uint8_t decoder_init_mode:1; #ifdef HAVE_POSTPROC uint8_t pp_available:1; #endif uint8_t is_direct_rendering_disabled:1; /* used only to avoid flooding log */ uint8_t cs_convert_init:1; uint8_t assume_bad_field_picture:1; uint8_t use_bad_frames:1; xine_bmiheader bih; unsigned char *buf; int bufsize; int size; int skipframes; #if XFF_AVCODEC_SLICE_TABLE == 1 int *slice_offset_table; int slice_offset_size; int slice_offset_pos; #endif AVFrame *av_frame; AVFrame *av_frame2; AVCodecContext *context; const AVCodec *codec; #ifdef HAVE_POSTPROC int pp_quality; int pp_flags; pp_context *our_context; pp_mode *our_mode; #endif /* HAVE_POSTPROC */ /* mpeg-es parsing */ mpeg_parser_t *mpeg_parser; double aspect_ratio; int aspect_ratio_prio; int frame_flags; int edge; int output_format; #ifdef ENABLE_DIRECT_RENDERING dlist_t ffsf_free, ffsf_used; int ffsf_num, ffsf_total; pthread_mutex_t ffsf_mutex; #endif #if XFF_PALETTE == 1 AVPaletteControl palette_control; #elif XFF_PALETTE == 2 || XFF_PALETTE == 3 uint32_t palette[256]; int palette_changed; #endif int color_matrix, full2mpeg; unsigned char ytab[1024], ctab[1024]; int pix_fmt; rgb2yuy2_t *rgb2yuy2; #ifdef LOG enum PixelFormat debug_fmt; #endif uint8_t set_stream_info; #ifdef ENABLE_VAAPI int vaapi_width, vaapi_height; int vaapi_profile; # if XFF_VAAPI == 1 struct vaapi_context vaapi_context; # elif XFF_VAAPI == 2 /* these are _here_ for debugging mostly. */ AVBufferRef *vaapi_av_ctx_ref; AVHWDeviceContext *vaapi_av_ctx; AVVAAPIDeviceContext *vaapi_hw_ctx; AVVAAPIHWConfig *vaapi_hw_cfg; # endif const struct vaapi_accel_funcs_s *accel; vo_frame_t *accel_img; #endif /* Ugly: 2nd guess the reason for flush. ff_flush () should really have an extra argument telling this. */ enum { STATE_RESET = 0, STATE_DISCONTINUITY, STATE_READING_DATA, STATE_FRAME_SENT, STATE_FLUSHED } state; int decode_attempts; #if XFF_VIDEO == 3 int flush_packet_sent; #endif #ifdef ENABLE_EMMS /* see get_buffer () */ int use_emms; #endif #if XFF_VIDEO > 1 XFF_PACKET_DECL (avpkt); #endif #if XFF_AVCODEC_SLICE_TABLE == 2 uint8_t *temp_buf; uint32_t temp_size; int slice_num; uint8_t slice_table[1 + 256 * 8]; #endif }; /* import color matrix names */ #define CM_HAVE_YCGCO_SUPPORT 1 #include "../../video_out/color_matrix.c" #ifdef ENABLE_VAAPI # if XFF_VAAPI == 2 static void ff_vaapi_stop (ff_video_decoder_t *this) { if (this->vaapi_av_ctx) { av_buffer_unref (&this->vaapi_av_ctx_ref); this->vaapi_av_ctx = NULL; this->vaapi_av_ctx_ref = NULL; } } static void ff_vaapi_free_ctx (AVHWDeviceContext *ctx) { ff_video_decoder_t *this; if (!ctx) return; this = (ff_video_decoder_t *)ctx->user_opaque; if (!this) return; av_free (this->vaapi_hw_cfg); this->vaapi_hw_cfg = NULL; } static int ff_vaapi_start (ff_video_decoder_t *this, VADisplay display, VAConfigID config_id) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: ff_vaapi_start (display = %p, config_id = %d).\n", (void *)display, (int)config_id); this->vaapi_av_ctx_ref = av_hwdevice_ctx_alloc (AV_HWDEVICE_TYPE_VAAPI); if (!this->vaapi_av_ctx_ref) return 0; this->vaapi_av_ctx = (AVHWDeviceContext *)this->vaapi_av_ctx_ref->data; if (!this->vaapi_av_ctx) { ff_vaapi_stop (this); return 0; } this->vaapi_hw_ctx = (AVVAAPIDeviceContext *)this->vaapi_av_ctx->hwctx; if (!this->vaapi_hw_ctx) { ff_vaapi_stop (this); return 0; } this->vaapi_av_ctx->user_opaque = this; this->vaapi_av_ctx->free = ff_vaapi_free_ctx; this->vaapi_hw_ctx->display = display; this->vaapi_hw_cfg = (AVVAAPIHWConfig *)av_hwdevice_hwconfig_alloc (this->vaapi_av_ctx_ref); if (!this->vaapi_hw_cfg) { ff_vaapi_stop (this); return 0; } this->vaapi_hw_cfg->config_id = config_id; if (av_hwdevice_ctx_init (this->vaapi_av_ctx_ref)) { ff_vaapi_stop (this); return 0; } return 1; } # endif #endif static void ff_check_colorspace (ff_video_decoder_t *this) { int i, cm, caps; #ifdef XFF_AVCODEC_COLORSPACE cm = this->context->colorspace << 1; #else cm = 0; #endif /* ffmpeg bug: color_range not set by svq3 decoder */ i = this->context->pix_fmt; if (cm && ((i == PIX_FMT_YUVJ420P) || (i == PIX_FMT_YUVJ444P))) cm |= 1; #ifdef XFF_AVCODEC_COLORSPACE if (this->context->color_range == AVCOL_RANGE_JPEG) cm |= 1; #endif /* report changes of colorspyce and/or color range */ if (cm != this->color_matrix) { this->color_matrix = cm; this->full2mpeg = 0; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_video_dec: color matrix #%d [%s]\n", cm >> 1, cm_names[cm & 31]); caps = this->stream->video_out->get_capabilities (this->stream->video_out); if (!(caps & VO_CAP_COLOR_MATRIX)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_video_dec: video out plugin does not support colour matrix switching\n"); cm &= 1; } /* HD color matrix (ITU-R 709/SMTE 240) serves to provide a bit more depth at least for greens where it strikes the most. Having more than 8 bits for real makes this trick obsolete, so deep color defaults to good old SD mode. Bad thing: now we need real support in video out to benefit. Lets at least map to fullrange where available. */ #ifdef AV_PIX_FMT_YUV420P9 if (this->context->pix_fmt == AV_PIX_FMT_YUV420P9) { int mode = (caps & VO_CAP_FULLRANGE) ? ((cm & 1) ? 0 : 1) : (cm & 1) ? -1 : 0; if ((cm >> 1) == 2) cm = 10 | (cm & 1); if ((cm >> 1) == 8) mode = 0; if (mode > 0) { /* 9 bit mpeg to full */ memset (this->ytab, 0, 2 * 16); for (i = 2 * 16; i < 2 * 235; i++) this->ytab[i] = (255 * i - 255 * 2 * 16 + 219) / (2 * 219); memset (this->ytab + i, 255, 2 * 21); memset (this->ctab, 0, 2 * 16); for (i = 2 * 16; i < 2 * 240; i++) this->ctab[i] = (254 * i + (224 - 254) * 2 * 128 + 224) / (2 * 224); memset (this->ctab + i, 255, 2 * 16); cm |= 1; } else if (mode < 0) { /* 9 bit full to mpeg */ for (i = 0; i < 2 * 256; i++) { this->ytab[i] = (219 * i + 255) / (2 * 255) + 16; this->ctab[i] = (224 * i + (254 - 224) * 2 * 128 + 254) / (2 * 254); } cm &= ~1; } else { /* 9 bit 1:1 */ for (i = 0; i < 2 * 256 - 1; i++) this->ytab[i] = this->ctab[i] = (i + 1) >> 1; this->ytab[i] = this->ctab[i] = 255; } } else #endif #ifdef AV_PIX_FMT_YUV420P10 if (this->context->pix_fmt == AV_PIX_FMT_YUV420P10) { int mode = (caps & VO_CAP_FULLRANGE) ? ((cm & 1) ? 0 : 1) : (cm & 1) ? -1 : 0; if ((cm >> 1) == 2) cm = 10 | (cm & 1); if ((cm >> 1) == 8) mode = 0; if (mode > 0) { /* 10 bit mpeg to full */ memset (this->ytab, 0, 4 * 16); for (i = 4 * 16; i < 4 * 235; i++) this->ytab[i] = (255 * i - 255 * 4 * 16 + 2 * 219) / (4 * 219); memset (this->ytab + i, 255, 4 * 21); memset (this->ctab, 0, 4 * 16); for (i = 4 * 16; i < 4 * 240; i++) this->ctab[i] = (254 * i + (224 - 254) * 4 * 128 + 2 * 224) / (4 * 224); memset (this->ctab + i, 255, 4 * 16); cm |= 1; } else if (mode < 0) { /* 10 bit full to mpeg */ for (i = 0; i < 4 * 256; i++) { this->ytab[i] = (219 * i + 2 * 255) / (4 * 255) + 16; this->ctab[i] = (224 * i + (254 - 224) * 4 * 128 + 2 * 254) / (4 * 254); } cm &= ~1; } else { /* 10 bit 1:1 */ for (i = 0; i < 4 * 256 - 2; i++) this->ytab[i] = this->ctab[i] = (i + 2) >> 2; this->ytab[i] = this->ctab[i] = 255; i++; this->ytab[i] = this->ctab[i] = 255; } } else #endif if ((cm & 1) && !(caps & VO_CAP_FULLRANGE)) { /* sigh. fall back to manual conversion */ cm &= ~1; this->full2mpeg = 1; for (i = 0; i < 256; i++) { this->ytab[i] = (219 * i + 127) / 255 + 16; this->ctab[i] = 112 * (i - 128) / 127 + 128; } } VO_SET_FLAGS_CM (cm, this->frame_flags); } } static void set_stream_info(ff_video_decoder_t *this) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->aspect_ratio * 10000); } #ifdef ENABLE_DIRECT_RENDERING /* Keep track of DR1 frames */ typedef struct { dnode_t node; int refs; ff_video_decoder_t *this; vo_frame_t *vo_frame; # ifdef ENABLE_VAAPI ff_vaapi_surface_t *va_surface; # endif } ff_saved_frame_t; static ff_saved_frame_t *ffsf_new (ff_video_decoder_t *this) { ff_saved_frame_t *ffsf; pthread_mutex_lock (&this->ffsf_mutex); if (DLIST_IS_EMPTY (&this->ffsf_free)) { ffsf = calloc (1, sizeof (*ffsf)); if (ffsf) { ffsf->this = this; DLIST_ADD_TAIL (&ffsf->node, &this->ffsf_used); this->ffsf_num++; this->ffsf_total++; } } else { ffsf = (ff_saved_frame_t *)this->ffsf_free.head; DLIST_REMOVE (&ffsf->node); ffsf->refs = 0; ffsf->this = this; ffsf->vo_frame = NULL; # ifdef ENABLE_VAAPI ffsf->va_surface = NULL; # endif DLIST_ADD_TAIL (&ffsf->node, &this->ffsf_used); this->ffsf_num++; } pthread_mutex_unlock (&this->ffsf_mutex); return ffsf; } static void ffsf_delete (ff_saved_frame_t *ffsf) { if (!ffsf) return; pthread_mutex_lock (&ffsf->this->ffsf_mutex); DLIST_REMOVE (&ffsf->node); DLIST_ADD_TAIL (&ffsf->node, &ffsf->this->ffsf_free); ffsf->this->ffsf_num--; pthread_mutex_unlock (&ffsf->this->ffsf_mutex); } # ifdef XFF_AV_BUFFER static void release_frame (void *saved_frame, uint8_t *data) { ff_saved_frame_t *ffsf = saved_frame; (void)data; /* At this point in time, AVFrame may already be reused. So take our saved values instead. */ if (ffsf) { if (--(ffsf->refs)) return; # ifdef ENABLE_VAAPI if (ffsf->va_surface) ffsf->this->accel->release_vaapi_surface (ffsf->this->accel_img, ffsf->va_surface); # endif if (ffsf->vo_frame) ffsf->vo_frame->free (ffsf->vo_frame); ffsf_delete (ffsf); } } # else /* !XFF_AV_BUFFER */ static void release_buffer(struct AVCodecContext *context, AVFrame *av_frame){ ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; # ifdef ENABLE_VAAPI if( this->context->pix_fmt == PIX_FMT_VAAPI_VLD ) { if(this->accel->guarded_render(this->accel_img)) { ff_vaapi_surface_t *va_surface = (ff_vaapi_surface_t *)av_frame->data[0]; if(va_surface != NULL) { this->accel->release_vaapi_surface(this->accel_img, va_surface); lprintf("release_buffer: va_surface_id 0x%08x\n", (unsigned int)av_frame->data[3]); } } } # endif if (av_frame->type == FF_BUFFER_TYPE_USER) { if (av_frame->opaque) { ff_saved_frame_t *ffsf = (ff_saved_frame_t *)av_frame->opaque; if (ffsf->vo_frame) ffsf->vo_frame->free (ffsf->vo_frame); ffsf_delete (ffsf); } av_frame->opaque = NULL; av_frame->data[0] = NULL; av_frame->data[1] = NULL; av_frame->data[2] = NULL; av_frame->linesize[0] = 0; av_frame->linesize[1] = 0; av_frame->linesize[2] = 0; } else { avcodec_default_release_buffer(context, av_frame); } } # endif /* !XFF_AV_BUFFER */ # ifdef ENABLE_VAAPI static int get_buffer_vaapi_vld (AVCodecContext *context, AVFrame *av_frame) { ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; ff_saved_frame_t *ffsf; int width = context->width; int height = context->height; av_frame->opaque = NULL; av_frame->data[0] = NULL; av_frame->data[1] = NULL; av_frame->data[2] = NULL; av_frame->data[3] = NULL; # ifdef XFF_FRAME_AGE av_frame->age = 1; # endif #ifdef XFF_AVCODEC_REORDERED_OPAQUE av_frame->reordered_opaque = context->reordered_opaque; #endif ffsf = ffsf_new (this); if (!ffsf) return AVERROR (ENOMEM); av_frame->opaque = ffsf; /* reinitialize vaapi for new image size */ if (width != this->vaapi_width || height != this->vaapi_height) { VAStatus status; this->vaapi_width = width; this->vaapi_height = height; status = this->accel->vaapi_init (this->accel_img, this->vaapi_profile, width, height); if (status == VA_STATUS_SUCCESS) { ff_vaapi_context_t *va_context = this->accel->get_context (this->accel_img); if (va_context) { # if XFF_VAAPI == 2 /* avcodec.h saye custom frame allocators shall use AVCodecContext.hw_frames_ctx instead. * however, avcodec_default_get_buffer2 () seems the only 1 using it as such. */ if (ff_vaapi_start (this, va_context->va_display, va_context->va_config_id)) { AVBufferRef *old_vaapi_av_ctx_ref = context->hw_device_ctx; context->hw_device_ctx = this->vaapi_av_ctx_ref; av_buffer_unref (&old_vaapi_av_ctx_ref); } # else this->vaapi_context.config_id = va_context->va_config_id; this->vaapi_context.context_id = va_context->va_context_id; this->vaapi_context.display = va_context->va_display; # endif } } } if(!this->accel->guarded_render(this->accel_img)) { vo_frame_t *img; img = this->stream->video_out->get_frame (this->stream->video_out, width, height, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); vaapi_accel_t *accel = (vaapi_accel_t*)img->accel_data; ff_vaapi_surface_t *va_surface = accel->f->get_vaapi_surface(img); if(va_surface) { av_frame->data[0] = (void *)va_surface;//(void *)(uintptr_t)va_surface->va_surface_id; av_frame->data[3] = (void *)(uintptr_t)va_surface->va_surface_id; } ffsf->vo_frame = img; } else { ff_vaapi_surface_t *va_surface = this->accel->get_vaapi_surface(this->accel_img); if(va_surface) { av_frame->data[0] = (void *)va_surface;//(void *)(uintptr_t)va_surface->va_surface_id; av_frame->data[3] = (void *)(uintptr_t)va_surface->va_surface_id; } ffsf->va_surface = va_surface; } lprintf("1: 0x%08x\n", (unsigned int)(intptr_t)av_frame->data[3]); av_frame->linesize[0] = 0; av_frame->linesize[1] = 0; av_frame->linesize[2] = 0; av_frame->linesize[3] = 0; # ifdef XFF_AV_BUFFER /* Does this really work???? */ av_frame->buf[0] = av_buffer_create (NULL, 0, release_frame, ffsf, 0); if (av_frame->buf[0]) (ffsf->refs)++; av_frame->buf[1] = NULL; av_frame->buf[2] = NULL; # else av_frame->type = FF_BUFFER_TYPE_USER; # endif this->is_direct_rendering_disabled = 1; return 0; } # endif /* ENABLE_VAAPI */ /* called from ffmpeg to do direct rendering method 1 */ # ifdef XFF_AV_BUFFER static int get_buffer (AVCodecContext *context, AVFrame *av_frame, int flags) # else static int get_buffer (AVCodecContext *context, AVFrame *av_frame) # endif { ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; vo_frame_t *img; ff_saved_frame_t *ffsf; int buf_width = av_frame->width; int buf_height = av_frame->height; /* The visible size, may be smaller. */ int width = context->width; int height = context->height; int top_edge; int guarded_render = 0; # ifdef ENABLE_EMMS /* some background thread may call this while still in mmx mode. this will trash "double" aspect ratio values, even when only passing them to vo_get_frame () verbatim. */ if (this->use_emms) emms (); # endif /* multiple threads have individual contexts !! */ # ifdef XFF_AVCODEC_COLORSPACE if (context != this->context) { if (this->context->colorspace == 2) /* undefined */ this->context->colorspace = context->colorspace; if (this->context->color_range == 0) this->context->color_range = context->color_range; if (this->context->pix_fmt < 0) this->context->pix_fmt = context->pix_fmt; } # endif /* A bit of unmotivated paranoia... */ if (buf_width < width) buf_width = width; if (buf_height < height) buf_height = height; ff_check_colorspace (this); if (!this->bih.biWidth || !this->bih.biHeight) { this->bih.biWidth = width; this->bih.biHeight = height; } if (this->aspect_ratio_prio == 0) { this->aspect_ratio = (double)width / (double)height; this->aspect_ratio_prio = 1; lprintf("default aspect ratio: %f\n", this->aspect_ratio); this->set_stream_info = 1; } avcodec_align_dimensions(context, &buf_width, &buf_height); # ifdef ENABLE_VAAPI if( context->pix_fmt == PIX_FMT_VAAPI_VLD ) { return get_buffer_vaapi_vld(context, av_frame); } /* on vaapi out do not use direct rendeing */ if(this->class->enable_vaapi) { this->output_format = XINE_IMGFMT_YV12; } if(this->accel) guarded_render = this->accel->guarded_render(this->accel_img); # endif /* ENABLE_VAAPI */ /* The alignment rhapsody */ /* SSE2+ requirement (U, V rows need to be 16 byte aligned too) */ buf_width += 2 * this->edge + 31; buf_width &= ~31; /* 2 extra lines for the edge wrap below plus XINE requirement */ top_edge = this->edge; if (top_edge) top_edge += 2; buf_height += top_edge + this->edge + 15; buf_height &= ~15; if ((buf_width != width) || (buf_height != height)) { if (!(this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_CROP)) { if (!this->is_direct_rendering_disabled) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: unsupported frame dimensions, DR1 disabled.\n")); this->is_direct_rendering_disabled = 1; } /* FIXME: why should i have to do that ? */ av_frame->data[0]= NULL; av_frame->data[1]= NULL; av_frame->data[2]= NULL; # ifdef XFF_AV_BUFFER return avcodec_default_get_buffer2(context, av_frame, flags); # else return avcodec_default_get_buffer(context, av_frame); # endif } } #ifdef AV_PIX_FMT_YUV420P9 if ((context->pix_fmt == AV_PIX_FMT_YUV420P9) && (this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_YV12_DEEP)) { this->output_format = XINE_IMGFMT_YV12_DEEP; VO_SET_FLAGS_DEPTH (9, this->frame_flags); } else #endif #ifdef AV_PIX_FMT_YUV420P10 if ((context->pix_fmt == AV_PIX_FMT_YUV420P10) && (this->stream->video_out->get_capabilities(this->stream->video_out) & VO_CAP_YV12_DEEP)) { this->output_format = XINE_IMGFMT_YV12_DEEP; VO_SET_FLAGS_DEPTH (10, this->frame_flags); } else #endif if (this->full2mpeg || guarded_render || (context->pix_fmt != PIX_FMT_YUV420P && context->pix_fmt != PIX_FMT_YUVJ420P)) { if (!this->is_direct_rendering_disabled) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: unsupported frame format, DR1 disabled.\n")); this->is_direct_rendering_disabled = 1; } /* FIXME: why should i have to do that ? */ av_frame->data[0]= NULL; av_frame->data[1]= NULL; av_frame->data[2]= NULL; # ifdef XFF_AV_BUFFER return avcodec_default_get_buffer2(context, av_frame, flags); # else return avcodec_default_get_buffer(context, av_frame); # endif } if (this->is_direct_rendering_disabled) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: direct rendering enabled\n")); this->is_direct_rendering_disabled = 0; } img = this->stream->video_out->get_frame (this->stream->video_out, buf_width, buf_height, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); ffsf = ffsf_new (this); if (!ffsf) { img->free (img); return AVERROR (ENOMEM); } ffsf->vo_frame = img; # ifdef XFF_AV_BUFFER /* Sigh. Wrap vo image planes into AVBufferRefs. When ff unref's them, they unref our trigger. * That one then fires image release. * For single chunk render space like video_out_opengl2, just 1 AVBufferRef is enough. */ { size_t s0 = img->height * img->pitches[0]; size_t s1 = (img->height + 1) >> 1, s2 = s1; s1 *= img->pitches[1]; s2 *= img->pitches[2]; if ((img->base[1] == img->base[0] + s0) && (img->base[2] == img->base[1] + s1)) { s0 += s1 + s2; s1 = s2 = 0; av_frame->buf[1] = av_frame->buf[2] = NULL; } av_frame->buf[0] = av_buffer_create (img->base[0], s0, release_frame, ffsf, 0); if (av_frame->buf[0]) { (ffsf->refs)++; } else { img->free (img); ffsf_delete (ffsf); return AVERROR (ENOMEM); } if (s1) { av_frame->buf[1] = av_buffer_create (img->base[1], s1, release_frame, ffsf, 0); if (av_frame->buf[1]) (ffsf->refs)++; av_frame->buf[2] = av_buffer_create (img->base[2], s2, release_frame, ffsf, 0); if (av_frame->buf[2]) (ffsf->refs)++; } } # else av_frame->type = FF_BUFFER_TYPE_USER; # endif av_frame->opaque = ffsf; av_frame->extended_data = av_frame->data; av_frame->data[0]= img->base[0]; av_frame->data[1]= img->base[1]; av_frame->data[2]= img->base[2]; av_frame->linesize[0] = img->pitches[0]; av_frame->linesize[1] = img->pitches[1]; av_frame->linesize[2] = img->pitches[2]; if (this->output_format == XINE_IMGFMT_YV12 || this->output_format == XINE_IMGFMT_YV12_DEEP) { /* nasty hack: wrap left edge to the right side to get proper SSE2 alignment on all planes. */ av_frame->data[0] += img->pitches[0] * top_edge; av_frame->data[1] += img->pitches[1] * top_edge / 2; av_frame->data[2] += img->pitches[2] * top_edge / 2; img->crop_left = 0; img->crop_top = top_edge; img->crop_right = buf_width - width; img->crop_bottom = buf_height - height - top_edge; } /* We should really keep track of the ages of xine frames (see * avcodec_default_get_buffer in libavcodec/utils.c) * For the moment tell ffmpeg that every frame is new (age = bignumber) */ # ifdef XFF_FRAME_AGE av_frame->age = 256*256*256*64; # endif /* take over pts for this frame to have it reordered */ #ifdef XFF_AVCODEC_REORDERED_OPAQUE av_frame->reordered_opaque = context->reordered_opaque; #endif return 0; } #endif /* ENABLE_DR1 */ static const char *const skip_loop_filter_enum_names[] = { "default", /* AVDISCARD_DEFAULT */ "none", /* AVDISCARD_NONE */ "nonref", /* AVDISCARD_NONREF */ "bidir", /* AVDISCARD_BIDIR */ "nonkey", /* AVDISCARD_NONKEY */ "all", /* AVDISCARD_ALL */ NULL }; static const int skip_loop_filter_enum_values[] = { AVDISCARD_DEFAULT, AVDISCARD_NONE, AVDISCARD_NONREF, AVDISCARD_BIDIR, AVDISCARD_NONKEY, AVDISCARD_ALL }; #ifdef ENABLE_VAAPI static int vaapi_pixfmt2imgfmt(enum PixelFormat pix_fmt, unsigned codec_id, int profile) { static const struct { unsigned fmt; enum PixelFormat pix_fmt; # if defined LIBAVCODEC_VERSION_INT && LIBAVCODEC_VERSION_INT >= ((54<<16)|(25<<8)) enum AVCodecID codec_id; # else enum CodecID codec_id; # endif int profile; } conversion_map[] = { {IMGFMT_VAAPI_MPEG2, PIX_FMT_VAAPI_VLD, CODEC_ID_MPEG2VIDEO, -1}, {IMGFMT_VAAPI_MPEG2_IDCT,PIX_FMT_VAAPI_IDCT, CODEC_ID_MPEG2VIDEO, -1}, {IMGFMT_VAAPI_MPEG2_MOCO,PIX_FMT_VAAPI_MOCO, CODEC_ID_MPEG2VIDEO, -1}, {IMGFMT_VAAPI_MPEG4, PIX_FMT_VAAPI_VLD, CODEC_ID_MPEG4, -1}, {IMGFMT_VAAPI_H263, PIX_FMT_VAAPI_VLD, CODEC_ID_H263, -1}, {IMGFMT_VAAPI_H264, PIX_FMT_VAAPI_VLD, CODEC_ID_H264, -1}, {IMGFMT_VAAPI_WMV3, PIX_FMT_VAAPI_VLD, CODEC_ID_WMV3, -1}, {IMGFMT_VAAPI_VC1, PIX_FMT_VAAPI_VLD, CODEC_ID_VC1, -1}, # ifdef FF_PROFILE_HEVC_MAIN_10 {IMGFMT_VAAPI_HEVC_MAIN10, PIX_FMT_VAAPI_VLD, AV_CODEC_ID_HEVC, FF_PROFILE_HEVC_MAIN_10}, # endif # ifdef FF_PROFILE_HEVC_MAIN {IMGFMT_VAAPI_HEVC, PIX_FMT_VAAPI_VLD, AV_CODEC_ID_HEVC, -1}, # endif }; unsigned i; for (i = 0; i < sizeof(conversion_map)/sizeof(conversion_map[0]); i++) { if (conversion_map[i].pix_fmt == pix_fmt && (conversion_map[i].codec_id == 0 || conversion_map[i].codec_id == codec_id) && (conversion_map[i].profile == -1 || conversion_map[i].profile == profile)) { return conversion_map[i].fmt; } } return 0; } /* TJ. libavcodec calls this with a list of supported pixel formats and lets us choose 1. Returning PIX_FMT_VAAPI_VLD enables VAAPI. However, at this point we only got image width and height from container, being unreliable or zero (MPEG-TS). Thus we repeat vaapi_context initialization in get_buffer when needed. This should be OK since NAL unit parsing is always done in software. */ static enum PixelFormat get_format(struct AVCodecContext *context, const enum PixelFormat *fmt) { int i; ff_video_decoder_t *this = (ff_video_decoder_t *)context->opaque; if(!this->class->enable_vaapi || !this->accel_img) return avcodec_default_get_format(context, fmt); if (context->codec_id == CODEC_ID_MPEG2VIDEO && this->class->vaapi_mpeg_softdec) { return avcodec_default_get_format(context, fmt); } const struct vaapi_accel_funcs_s *accel = this->accel; for (i = 0; fmt[i] != PIX_FMT_NONE; i++) { if (fmt[i] != PIX_FMT_VAAPI_VLD) continue; uint32_t format = vaapi_pixfmt2imgfmt(fmt[i], context->codec_id, context->profile); if (!format) { continue; } this->vaapi_profile = accel->profile_from_imgfmt (this->accel_img, format); if (this->vaapi_profile >= 0) { int width = context->width; int height = context->height; VAStatus status; if (!width || !height) { width = 1920; height = 1080; } this->vaapi_width = width; this->vaapi_height = height; status = accel->vaapi_init (this->accel_img, this->vaapi_profile, width, height); if( status == VA_STATUS_SUCCESS ) { ff_vaapi_context_t *va_context = accel->get_context(this->accel_img); if(!va_context) break; context->draw_horiz_band = NULL; context->slice_flags = SLICE_FLAG_CODED_ORDER | SLICE_FLAG_ALLOW_FIELD; # if XFF_VAAPI == 2 /* avcodec.h saye custom frame allocators shall use AVCodecContext.hw_frames_ctx instead. * however, avcodec_default_get_buffer2 () seems the only 1 using it as such. */ if (ff_vaapi_start (this, va_context->va_display, va_context->va_config_id)) { AVBufferRef *old_vaapi_av_ctx_ref = context->hw_device_ctx; context->hw_device_ctx = this->vaapi_av_ctx_ref; av_buffer_unref (&old_vaapi_av_ctx_ref); } # else this->vaapi_context.config_id = va_context->va_config_id; this->vaapi_context.context_id = va_context->va_context_id; this->vaapi_context.display = va_context->va_display; context->hwaccel_context = &this->vaapi_context; # endif this->pts = 0; return fmt[i]; } } } xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: no suitable format for HW decoding\n")); return avcodec_default_get_format(context, fmt); } #endif /* ENABLE_VAAPI */ static void init_video_codec (ff_video_decoder_t *this, unsigned int codec_type) { int thread_count = this->class->thread_count; int use_vaapi = 0; this->context->width = this->bih.biWidth; this->context->height = this->bih.biHeight; #ifdef XFF_AVCODEC_STREAM_CODEC_TAG this->context->stream_codec_tag = #endif this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC); this->stream->video_out->open (this->stream->video_out, this->stream); this->edge = 0; if(this->codec->capabilities & AV_CODEC_CAP_DR1 && this->class->enable_dri) { if (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_CROP) { /* We can crop. Fine. Lets allow decoders to paint over the frame edges. This will be slightly faster. And it is also a workaround for buggy v54 who likes to ignore EMU_EDGE for wmv2 and xvid. */ this->edge = XFF_EDGE_WIDTH (); } #ifdef CODEC_FLAG_EMU_EDGE else { /* Some codecs (eg rv10) copy flags in init so it's necessary to set * this flag here in case we are going to use direct rendering */ this->context->flags |= CODEC_FLAG_EMU_EDGE; } #endif } /* TJ. without this, it wont work at all on my machine */ this->context->codec_id = this->codec->id; this->context->codec_type = this->codec->type; if (this->class->choose_speed_over_accuracy) this->context->flags2 |= AV_CODEC_FLAG2_FAST; this->context->skip_loop_filter = skip_loop_filter_enum_values[this->class->skip_loop_filter_enum]; /* disable threads for SVQ3 */ if (this->codec->id == CODEC_ID_SVQ3) { thread_count = 1; } /* Use "bad frames" to fill pts gaps */ if (codec_type != BUF_VIDEO_VP9) this->use_bad_frames = 1; /* Check for VAAPI HWDEC capability */ #ifdef ENABLE_VAAPI if( this->class->enable_vaapi ) { uint32_t format = vaapi_pixfmt2imgfmt(PIX_FMT_VAAPI_VLD, this->codec->id, -1); if (format && this->accel->profile_from_imgfmt (this->accel_img, format) >= 0) { use_vaapi = 1; } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_video_dec: VAAPI decoding of 0x%08x not supported by hardware\n", codec_type); } } #endif /* enable direct rendering by default */ this->output_format = XINE_IMGFMT_YV12; #ifdef ENABLE_DIRECT_RENDERING if( this->codec->capabilities & AV_CODEC_CAP_DR1 && this->class->enable_dri ) { # ifdef XFF_AV_BUFFER this->context->get_buffer2 = get_buffer; # if XFF_THREAD_SAFE_CB == 2 # warning h.264 still needs this set, or falls back to indirect rendering. please ignore the next warning. # endif # if XFF_THREAD_SAFE_CB != 0 this->context->thread_safe_callbacks = 1; # endif # if XFF_VIDEO != 3 this->context->refcounted_frames = 1; # endif # else this->context->get_buffer = get_buffer; this->context->release_buffer = release_buffer; # endif xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: direct rendering enabled\n")); } #endif #ifdef ENABLE_VAAPI if( use_vaapi ) { this->context->skip_loop_filter = AVDISCARD_DEFAULT; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: force AVDISCARD_DEFAULT for VAAPI\n")); this->class->enable_dri = 1; this->output_format = XINE_IMGFMT_VAAPI; # ifdef XFF_AV_BUFFER this->context->get_buffer2 = get_buffer; # else this->context->get_buffer = get_buffer; this->context->reget_buffer = get_buffer; this->context->release_buffer = release_buffer; # endif this->context->get_format = get_format; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: direct rendering enabled\n")); thread_count = 1; } #endif /* ENABLE_VAAPI */ #ifdef DEPRECATED_AVCODEC_THREAD_INIT if (thread_count > 1) { this->context->thread_count = thread_count; } #endif pthread_mutex_lock(&ffmpeg_lock); if (XFF_AVCODEC_OPEN (this->context, this->codec) < 0) { pthread_mutex_unlock(&ffmpeg_lock); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: couldn't open decoder\n")); free(this->context); this->context = NULL; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); this->stream->video_out->close (this->stream->video_out, this->stream); return; } if (this->codec->id == CODEC_ID_VC1 && (!this->bih.biWidth || !this->bih.biHeight)) { /* VC1 codec must be re-opened with correct width and height. */ if (this->context) { _x_freep (&this->context->extradata); this->context->extradata_size = 0; XFF_FREE_CONTEXT (this->context); } this->context = XFF_ALLOC_CONTEXT (); if (!(this->context && XFF_AVCODEC_OPEN (this->context, this->codec) >= 0)) { pthread_mutex_unlock(&ffmpeg_lock); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: couldn't open decoder (pass 2)\n")); free(this->context); this->context = NULL; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); this->stream->video_out->close (this->stream->video_out, this->stream); return; } } #ifndef DEPRECATED_AVCODEC_THREAD_INIT if (thread_count > 1) { if (avcodec_thread_init(this->context, thread_count) != -1) this->context->thread_count = thread_count; } #endif pthread_mutex_unlock(&ffmpeg_lock); lprintf("lavc decoder opened\n"); this->decoder_ok = 1; if ((codec_type != BUF_VIDEO_MPEG) && (codec_type != BUF_VIDEO_DV)) { if (!this->bih.biWidth || !this->bih.biHeight) { this->bih.biWidth = this->context->width; this->bih.biHeight = this->context->height; } set_stream_info(this); } this->skipframes = 0; /* flag for interlaced streams */ this->frame_flags = 0; /* FIXME: which codecs can be interlaced? FIXME: check interlaced DCT and other codec specific info. */ if (!use_vaapi) { switch( codec_type ) { case BUF_VIDEO_DV: this->frame_flags |= VO_INTERLACED_FLAG; break; case BUF_VIDEO_MPEG: this->frame_flags |= VO_INTERLACED_FLAG; break; case BUF_VIDEO_MJPEG: this->frame_flags |= VO_INTERLACED_FLAG; break; case BUF_VIDEO_HUFFYUV: this->frame_flags |= VO_INTERLACED_FLAG; break; case BUF_VIDEO_H264: this->frame_flags |= VO_INTERLACED_FLAG; break; } } #ifdef XFF_AVCODEC_REORDERED_OPAQUE /* dont want initial AV_NOPTS_VALUE here */ this->context->reordered_opaque = 0; #endif #ifdef XFF_AVCODEC_FRAME_PTS this->context->time_base.num = 1; this->context->time_base.den = 90000 << 8; #endif } #ifdef ENABLE_VAAPI static void vaapi_enable_vaapi(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; class->enable_vaapi = entry->num_value; } static void vaapi_mpeg_softdec_func(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; class->vaapi_mpeg_softdec = entry->num_value; } #endif /* ENABLE_VAAPI */ static void choose_speed_over_accuracy_cb(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; class->choose_speed_over_accuracy = entry->num_value; } static void skip_loop_filter_enum_cb(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; class->skip_loop_filter_enum = entry->num_value; } static void thread_count_cb(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; class->thread_count = entry->num_value; if (class->thread_count < 1) class->thread_count = 1; else if (class->thread_count > 8) class->thread_count = 8; } #ifdef HAVE_POSTPROC static void pp_quality_cb(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; class->pp_quality = entry->num_value; } #endif static void dri_cb(void *user_data, xine_cfg_entry_t *entry) { ff_video_class_t *class = (ff_video_class_t *) user_data; class->enable_dri = entry->num_value; } #ifdef HAVE_POSTPROC static void pp_change_quality (ff_video_decoder_t *this) { this->pp_quality = this->class->pp_quality; if(this->pp_available && this->pp_quality) { if(!this->our_context && this->context) this->our_context = pp_get_context(this->context->width, this->context->height, this->pp_flags); if(this->our_mode) pp_free_mode(this->our_mode); this->our_mode = pp_get_mode_by_name_and_quality("hb:a,vb:a,dr:a", this->pp_quality); } else { if(this->our_mode) { pp_free_mode(this->our_mode); this->our_mode = NULL; } if(this->our_context) { pp_free_context(this->our_context); this->our_context = NULL; } } } #endif /* HAVE_POSTPROC */ static void init_postprocess (ff_video_decoder_t *this) { #ifdef HAVE_POSTPROC # if defined(ARCH_X86) uint32_t cpu_caps; # endif /* Allow post processing on mpeg-4 (based) codecs */ switch(this->codec->id) { case CODEC_ID_MPEG4: case CODEC_ID_MSMPEG4V1: case CODEC_ID_MSMPEG4V2: case CODEC_ID_MSMPEG4V3: case CODEC_ID_WMV1: case CODEC_ID_WMV2: this->pp_available = 1; break; default: this->pp_available = 0; break; } this->pp_flags = PP_FORMAT_420; # if defined(ARCH_X86) /* Detect what cpu accel we have */ cpu_caps = xine_mm_accel(); if(cpu_caps & MM_ACCEL_X86_MMX) this->pp_flags |= PP_CPU_CAPS_MMX; if(cpu_caps & MM_ACCEL_X86_MMXEXT) this->pp_flags |= PP_CPU_CAPS_MMX2; if(cpu_caps & MM_ACCEL_X86_3DNOW) this->pp_flags |= PP_CPU_CAPS_3DNOW; # endif /* Set level */ pp_change_quality(this); #else (void)this; #endif /* HAVE_POSTPROC */ } static int ff_handle_mpeg_sequence(ff_video_decoder_t *this, mpeg_parser_t *parser) { /* frame format change */ if ((parser->width != this->bih.biWidth) || (parser->height != this->bih.biHeight) || (parser->frame_aspect_ratio != this->aspect_ratio)) { xine_event_t event; xine_format_change_data_t data; this->bih.biWidth = parser->width; this->bih.biHeight = parser->height; this->aspect_ratio = parser->frame_aspect_ratio; this->aspect_ratio_prio = 2; lprintf("mpeg seq aspect ratio: %f\n", this->aspect_ratio); set_stream_info(this); event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = this->stream; event.data = &data; event.data_length = sizeof(data); data.width = this->bih.biWidth; data.height = this->bih.biHeight; data.aspect = this->aspect_ratio; data.pan_scan = 0; xine_event_send(this->stream, &event); } this->video_step = this->mpeg_parser->frame_duration; return 1; } static void ff_setup_rgb2yuy2 (ff_video_decoder_t *this, int pix_fmt) { const char *fmt = ""; int cm = 10; /* mpeg range ITU-R 601 */ switch (pix_fmt) { case PIX_FMT_ARGB: fmt = "argb"; break; case PIX_FMT_BGRA: fmt = "bgra"; break; case PIX_FMT_RGB24: fmt = "rgb"; break; case PIX_FMT_BGR24: fmt = "bgr"; break; case PIX_FMT_RGB555BE: fmt = "rgb555be"; break; case PIX_FMT_RGB555LE: fmt = "rgb555le"; break; case PIX_FMT_RGB565BE: fmt = "rgb565be"; break; case PIX_FMT_RGB565LE: fmt = "rgb565le"; break; #ifdef __BIG_ENDIAN__ case PIX_FMT_PAL8: fmt = "argb"; break; #else case PIX_FMT_PAL8: fmt = "bgra"; break; #endif } if (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_FULLRANGE) cm = 11; /* full range */ rgb2yuy2_free (this->rgb2yuy2); this->rgb2yuy2 = rgb2yuy2_alloc (cm, fmt); this->pix_fmt = pix_fmt; VO_SET_FLAGS_CM (cm, this->frame_flags); if (pix_fmt == PIX_FMT_PAL8) fmt = "pal8"; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_video_dec: converting %s -> %s yuy2\n", fmt, cm_names[cm]); } #if defined(AV_PIX_FMT_YUV420P9) || defined(AV_PIX_FMT_YUV420P10) static void ff_get_deep_color (uint8_t *src, int sstride, uint8_t *dest, int dstride, int width, int height, uint8_t *tab) { uint16_t *p = (uint16_t *)ASSUME_ALIGNED_2 (src, 2); uint8_t *q = dest; int spad = sstride / 2 - width; int dpad = dstride - width; int i; while (height--) { for (i = width; i; i--) *q++ = tab[*p++]; p += spad; q += dpad; } } #endif static void ff_convert_frame(ff_video_decoder_t *this, vo_frame_t *img, AVFrame *av_frame) { int y; uint8_t *dy, *du, *dv, *sy, *su, *sv; #ifdef LOG if (this->debug_fmt != this->context->pix_fmt) printf ("frame format == %08x\n", this->debug_fmt = this->context->pix_fmt); #endif #ifdef ENABLE_VAAPI if (this->context->pix_fmt == PIX_FMT_VAAPI_VLD) { if (this->accel->guarded_render(this->accel_img)) { ff_vaapi_surface_t *va_surface = (ff_vaapi_surface_t *)av_frame->data[0]; this->accel->render_vaapi_surface (img, va_surface); } return; } #endif /* ENABLE_VAAPI */ ff_check_colorspace (this); dy = img->base[0]; du = img->base[1]; dv = img->base[2]; sy = av_frame->data[0]; su = av_frame->data[1]; sv = av_frame->data[2]; /* Some segfaults & heap corruption have been observed with img->height, * so we use this->bih.biHeight instead (which is the displayed height) */ switch (this->context->pix_fmt) { #ifdef AV_PIX_FMT_YUV420P9 case AV_PIX_FMT_YUV420P9: /* Y */ ff_get_deep_color (av_frame->data[0], av_frame->linesize[0], img->base[0], img->pitches[0], img->width, this->bih.biHeight, this->ytab); /* U */ ff_get_deep_color (av_frame->data[1], av_frame->linesize[1], img->base[1], img->pitches[1], img->width / 2, this->bih.biHeight / 2, this->ctab); /* V */ ff_get_deep_color (av_frame->data[2], av_frame->linesize[2], img->base[2], img->pitches[2], img->width / 2, this->bih.biHeight / 2, this->ctab); break; #endif #ifdef AV_PIX_FMT_YUV420P10 case AV_PIX_FMT_YUV420P10: /* Y */ ff_get_deep_color (av_frame->data[0], av_frame->linesize[0], img->base[0], img->pitches[0], img->width, this->bih.biHeight, this->ytab); /* U */ ff_get_deep_color (av_frame->data[1], av_frame->linesize[1], img->base[1], img->pitches[1], img->width / 2, this->bih.biHeight / 2, this->ctab); /* V */ ff_get_deep_color (av_frame->data[2], av_frame->linesize[2], img->base[2], img->pitches[2], img->width / 2, this->bih.biHeight / 2, this->ctab); break; #endif case PIX_FMT_YUV410P: yuv9_to_yv12( /* Y */ av_frame->data[0], av_frame->linesize[0], img->base[0], img->pitches[0], /* U */ av_frame->data[1], av_frame->linesize[1], img->base[1], img->pitches[1], /* V */ av_frame->data[2], av_frame->linesize[2], img->base[2], img->pitches[2], /* width x height */ img->width, this->bih.biHeight); break; case PIX_FMT_YUV411P: yuv411_to_yv12( /* Y */ av_frame->data[0], av_frame->linesize[0], img->base[0], img->pitches[0], /* U */ av_frame->data[1], av_frame->linesize[1], img->base[1], img->pitches[1], /* V */ av_frame->data[2], av_frame->linesize[2], img->base[2], img->pitches[2], /* width x height */ img->width, this->bih.biHeight); break; /* PIX_FMT_RGB32 etc. are only aliases for the native endian versions. Lets support them both - wont harm performance here :-) */ case PIX_FMT_ARGB: case PIX_FMT_BGRA: case PIX_FMT_RGB24: case PIX_FMT_BGR24: case PIX_FMT_RGB555BE: case PIX_FMT_RGB555LE: case PIX_FMT_RGB565BE: case PIX_FMT_RGB565LE: if (this->pix_fmt != this->context->pix_fmt) ff_setup_rgb2yuy2 (this, this->context->pix_fmt); rgb2yuy2_slice (this->rgb2yuy2, sy, av_frame->linesize[0], img->base[0], img->pitches[0], img->width, this->bih.biHeight); break; case PIX_FMT_PAL8: if (this->pix_fmt != this->context->pix_fmt) ff_setup_rgb2yuy2 (this, this->context->pix_fmt); rgb2yuy2_palette (this->rgb2yuy2, su, 256, 8); rgb2yuy2_slice (this->rgb2yuy2, sy, av_frame->linesize[0], img->base[0], img->pitches[0], img->width, this->bih.biHeight); break; default: { int subsamph = (this->context->pix_fmt == PIX_FMT_YUV444P) || (this->context->pix_fmt == PIX_FMT_YUVJ444P); int subsampv = (this->context->pix_fmt != PIX_FMT_YUV420P) && (this->context->pix_fmt != PIX_FMT_YUVJ420P); if (this->full2mpeg) { uint8_t *ytab = this->ytab; uint8_t *ctab = this->ctab; uint8_t *p, *q; int x; for (y = 0; y < this->bih.biHeight; y++) { p = sy; q = dy; for (x = img->width; x > 0; x--) *q++ = ytab[*p++]; dy += img->pitches[0]; sy += av_frame->linesize[0]; } for (y = 0; y < this->bih.biHeight / 2; y++) { if (!subsamph) { p = su, q = du; for (x = img->width / 2; x > 0; x--) *q++ = ctab[*p++]; p = sv, q = dv; for (x = img->width / 2; x > 0; x--) *q++ = ctab[*p++]; } else { p = su, q = du; for (x = img->width / 2; x > 0; x--) {*q++ = ctab[*p]; p += 2;} p = sv, q = dv; for (x = img->width / 2; x > 0; x--) {*q++ = ctab[*p]; p += 2;} } du += img->pitches[1]; dv += img->pitches[2]; if (subsampv) { su += 2 * av_frame->linesize[1]; sv += 2 * av_frame->linesize[2]; } else { su += av_frame->linesize[1]; sv += av_frame->linesize[2]; } } } else { for (y = 0; y < this->bih.biHeight; y++) { xine_fast_memcpy (dy, sy, img->width); dy += img->pitches[0]; sy += av_frame->linesize[0]; } for (y = 0; y < this->bih.biHeight / 2; y++) { if (!subsamph) { xine_fast_memcpy (du, su, img->width/2); xine_fast_memcpy (dv, sv, img->width/2); } else { int x; uint8_t *src; uint8_t *dst; src = su; dst = du; for (x = 0; x < (img->width / 2); x++) { *dst = *src; dst++; src += 2; } src = sv; dst = dv; for (x = 0; x < (img->width / 2); x++) { *dst = *src; dst++; src += 2; } } du += img->pitches[1]; dv += img->pitches[2]; if (subsampv) { su += 2*av_frame->linesize[1]; sv += 2*av_frame->linesize[2]; } else { su += av_frame->linesize[1]; sv += av_frame->linesize[2]; } } } } break; } } static void ff_check_bufsize (ff_video_decoder_t *this, int size) { if (size > this->bufsize) { this->bufsize = size + size / 2; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: increasing buffer to %d to avoid overflow.\n"), this->bufsize); this->buf = realloc(this->buf, this->bufsize + AV_INPUT_BUFFER_PADDING_SIZE ); } } static int ff_vc1_find_header(ff_video_decoder_t *this, buf_element_t *buf) { uint8_t *p = buf->content; if (!p[0] && !p[1] && p[2] == 1 && p[3] == 0x0f) { int i; this->context->extradata = calloc(1, buf->size + AV_INPUT_BUFFER_PADDING_SIZE); this->context->extradata_size = 0; for (i = 0; i < buf->size && i < 128; i++) { if (!p[i] && !p[i+1] && p[i+2]) { lprintf("00 00 01 %02x at %d\n", p[i+3], i); if (p[i+3] != 0x0e && p[i+3] != 0x0f) break; } this->context->extradata[i] = p[i]; this->context->extradata_size++; } lprintf("ff_video_decoder: found VC1 sequence header\n"); #if XFF_PARSE > 1 AVCodecParserContext *parser_context; uint8_t *outbuf; int outsize; parser_context = av_parser_init(CODEC_ID_VC1); if (!parser_context) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_video_dec: couldn't init VC1 parser\n"); return 1; } parser_context->flags |= PARSER_FLAG_COMPLETE_FRAMES; av_parser_parse2 (parser_context, this->context, &outbuf, &outsize, this->context->extradata, this->context->extradata_size, 0, 0, 0); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_video_dec: parsed VC1 video size %dx%d\n", this->context->width, this->context->height); this->bih.biWidth = this->context->width; this->bih.biHeight = this->context->height; av_parser_close(parser_context); #endif /* XFF_PARSE > 1 */ return 1; } xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: VC1 extradata missing !\n"); return 0; } static int ff_check_extradata(ff_video_decoder_t *this, unsigned int codec_type, buf_element_t *buf) { if (this->context->extradata) return 1; switch (codec_type) { case BUF_VIDEO_VC1: return ff_vc1_find_header(this, buf); default:; } return 1; } static void ff_init_mpeg12_mode(ff_video_decoder_t *this) { if (this->decoder_init_mode) { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "mpeg-1 (ffmpeg)"); init_video_codec (this, BUF_VIDEO_MPEG); this->decoder_init_mode = 0; } if ( this->mpeg_parser == NULL ) { this->mpeg_parser = calloc(1, sizeof(mpeg_parser_t)); if (this->mpeg_parser) mpeg_parser_init(this->mpeg_parser, AV_INPUT_BUFFER_PADDING_SIZE); } } static void ff_handle_preview_buffer (ff_video_decoder_t *this, buf_element_t *buf) { int codec_type; lprintf ("preview buffer\n"); codec_type = buf->type & 0xFFFF0000; if (codec_type == BUF_VIDEO_MPEG) { ff_init_mpeg12_mode(this); } else if (this->decoder_init_mode && !this->mpeg_parser) { if (!ff_check_extradata(this, codec_type, buf)) return; init_video_codec(this, codec_type); this->decoder_init_mode = 0; if (!this->decoder_ok) return; init_postprocess(this); } } static void ff_handle_header_buffer (ff_video_decoder_t *this, buf_element_t *buf) { lprintf ("header buffer\n"); /* accumulate data */ ff_check_bufsize(this, this->size + buf->size); xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { uint32_t codec_type = buf->type & 0xFFFF0000; lprintf ("header complete\n"); if (buf->decoder_flags & BUF_FLAG_STDHEADER) { lprintf("standard header\n"); /* init package containing bih */ memcpy ( &this->bih, this->buf, sizeof(xine_bmiheader) ); if (this->bih.biSize > (int)sizeof(xine_bmiheader)) { this->context->extradata_size = this->bih.biSize - sizeof(xine_bmiheader); this->context->extradata = malloc(this->context->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE); memcpy(this->context->extradata, this->buf + sizeof(xine_bmiheader), this->context->extradata_size); memset(this->context->extradata + this->context->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } this->context->bits_per_sample = this->bih.biBitCount; } else { switch (codec_type) { case BUF_VIDEO_RV10: case BUF_VIDEO_RV20: case BUF_VIDEO_RV30: case BUF_VIDEO_RV40: this->bih.biWidth = _X_BE_16(&this->buf[12]); this->bih.biHeight = _X_BE_16(&this->buf[14]); #ifdef XFF_AVCODEC_SUB_ID this->context->sub_id = _X_BE_32(&this->buf[30]); #endif if (this->size < 8 + 26) { uint32_t *b = calloc (1, 8 + AV_INPUT_BUFFER_PADDING_SIZE); if (b) { this->context->extradata_size = 8; this->context->extradata = (uint8_t *)b; b[0] = 0; if (codec_type == BUF_VIDEO_RV10) b[1] = 0x10000000; else b[1] = 0x10003001; } } else { this->context->extradata = malloc (this->size - 26 + AV_INPUT_BUFFER_PADDING_SIZE); if (this->context->extradata) { this->context->extradata_size = this->size - 26; memcpy (this->context->extradata, this->buf + 26, this->context->extradata_size); memset (this->context->extradata + this->context->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } } xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_video_dec: buf size %d\n", this->size); lprintf("w=%d, h=%d\n", this->bih.biWidth, this->bih.biHeight); break; default: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: unknown header for buf type 0x%X\n", codec_type); return; } } /* reset accumulator */ this->size = 0; } } static void ff_handle_special_buffer (ff_video_decoder_t *this, buf_element_t *buf) { /* take care of all the various types of special buffers * note that order is important here */ lprintf("special buffer\n"); if (buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM && !this->context->extradata_size) { lprintf("BUF_SPECIAL_STSD_ATOM\n"); this->context->extradata_size = buf->decoder_info[2]; this->context->extradata = malloc(buf->decoder_info[2] + AV_INPUT_BUFFER_PADDING_SIZE); memcpy(this->context->extradata, buf->decoder_info_ptr[2], buf->decoder_info[2]); memset(this->context->extradata + this->context->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } else if (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG && !this->context->extradata_size) { lprintf("BUF_SPECIAL_DECODER_CONFIG\n"); this->context->extradata_size = buf->decoder_info[2]; this->context->extradata = malloc(buf->decoder_info[2] + AV_INPUT_BUFFER_PADDING_SIZE); memcpy(this->context->extradata, buf->decoder_info_ptr[2], buf->decoder_info[2]); memset(this->context->extradata + this->context->extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); } else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) { unsigned int i; palette_entry_t *demuxer_palette = (palette_entry_t *)buf->decoder_info_ptr[2]; #if XFF_PALETTE == 1 AVPaletteControl *decoder_palette = &this->palette_control; lprintf ("BUF_SPECIAL_PALETTE\n"); for (i = 0; i < buf->decoder_info[2]; i++) { decoder_palette->palette[i] = (demuxer_palette[i].r << 16) | (demuxer_palette[i].g << 8) | (demuxer_palette[i].b << 0); } decoder_palette->palette_changed = 1; this->context->palctrl = decoder_palette; #elif XFF_PALETTE == 2 || XFF_PALETTE == 3 lprintf ("BUF_SPECIAL_PALETTE\n"); for (i = 0; i < buf->decoder_info[2]; i++) { this->palette[i] = (demuxer_palette[i].r << 16) | (demuxer_palette[i].g << 8) | (demuxer_palette[i].b << 0); } this->palette_changed = 1; #endif } else if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) { { #if XFF_AVCODEC_SLICE_TABLE == 1 /* o dear. Multiple decoding threads use individual contexts. * av_decode_video2 () does only copy the _pointer_ to the offsets, * not the offsets themselves. So we must not overwrite anything * that another thread has not yet read. */ int i, l, total; lprintf("BUF_SPECIAL_RV_CHUNK_TABLE\n"); l = buf->decoder_info[2] + 1; total = l * this->class->thread_count; if (total < SLICE_OFFSET_SIZE) total = SLICE_OFFSET_SIZE; if (total > this->slice_offset_size) { this->slice_offset_table = realloc (this->slice_offset_table, total * sizeof (int)); this->slice_offset_size = total; } if (this->slice_offset_pos + l > this->slice_offset_size) this->slice_offset_pos = 0; this->context->slice_offset = this->slice_offset_table + this->slice_offset_pos; this->context->slice_count = l; lprintf ("slice_count=%d\n", l); for (i = 0; i < l; i++) { this->slice_offset_table[this->slice_offset_pos++] = ((uint32_t *)buf->decoder_info_ptr[2])[(2 * i) + 1]; lprintf("slice_offset[%d]=%d\n", i, this->context->slice_offset[i]); } #elif XFF_AVCODEC_SLICE_TABLE == 2 /* (count-1):1, 1:4, (offs[0]):4, 1:4, (offs[1]:4, ... just in front of the frame bitstream. * reverse engineered from ffmpeg/libavcodec/rv34.c. they seem to expect no * external use of rv decoders, and did not document this. */ this->slice_table[0] = buf->decoder_info[2]; this->slice_num = this->slice_table[0] + 1; memcpy (this->slice_table + 1, buf->decoder_info_ptr[2], 8 * this->slice_num); #endif } } } static void ff_discontinuity (video_decoder_t *this_gen) { ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; lprintf ("ff_discontinuity\n"); this->pts = 0; this->state = STATE_DISCONTINUITY; /* * there is currently no way to reset all the pts which are stored in the decoder. * therefore, we add a unique tag (generated from pts_tag_counter) to pts (see * ff_tag_pts()) and wait for it to appear on returned frames. * until then, any retrieved pts value will be reset to 0 (see ff_untag_pts()). * NOTE: there may be small negative pts values, eg -7200, or even -1 (reordered .mp4). * hence the sign restore. * NOTE: previous code had an "inactive" mode that let _any_ value pass - when there * are no discontinuities. not very realistic. furthermore, many xine code parts * assume that pts never use more than 48 bits or so for their 64bit math. * so lets drop complexity, and _always_ tag 8 bits. */ this->pts_tag_pass = (this->pts_tag_pass + 1) & 0xff; } static int64_t ff_tag_pts (ff_video_decoder_t *this, int64_t pts) { /* NOTE: m68k has sign preserving left shifts, x86 has not. * both are correct with non overflowing 2's complement value. * anyway, some compilers warn about undefined op there, so use * 256. * NOTE: we still like notifications ;-) */ return (pts * 256) | this->pts_tag_pass; } static int64_t ff_untag_pts (ff_video_decoder_t *this, AVFrame *av_frame) { int64_t pts; #if defined(XFF_AVCODEC_FRAME_PTS) pts = (av_frame->pts != AV_NOPTS_VALUE) ? av_frame->pts : 0; # if defined(XFF_AVCODEC_REORDERED_OPAQUE) /* paranoia !!! */ if (pts != av_frame->reordered_opaque) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": WARNING: frame pts %" PRId64 " != reordered_opaque %" PRId64 ".\n", pts, av_frame->reordered_opaque); pts = av_frame->reordered_opaque; } av_frame->reordered_opaque = 0; # endif #elif defined(XFF_AVCODEC_REORDERED_OPAQUE) pts = av_frame->reordered_opaque; av_frame->reordered_opaque = 0; #else pts = this->tagged_pts; #endif if ((uint8_t)(pts & 0xff) == this->pts_tag_pass) { /* restore sign. */ return pts >> 8; } else { /* reset pts if outdated while waiting for first pass (see below). */ return 0; } } static int decode_video_wrapper (ff_video_decoder_t *this, AVFrame *av_frame, int *err, void *buf, size_t buf_size) { uint32_t tsize = 0; int len; #if ENABLE_VAAPI int locked = 0; if (this->accel) { locked = this->accel->lock_vaapi(this->accel_img); } #endif /* ENABLE_VAAPI */ #if XFF_AVCODEC_SLICE_TABLE == 2 if ((this->slice_num > 0) && buf) { uint32_t nsize; tsize = 1 + this->slice_num * 8; nsize = tsize + buf_size + AV_INPUT_BUFFER_PADDING_SIZE; if (this->temp_size < nsize) { nsize = nsize * 3 / 2; free (this->temp_buf); this->temp_buf = malloc (nsize); if (!this->temp_buf) nsize = 0; this->temp_size = nsize; nsize = tsize + buf_size + AV_INPUT_BUFFER_PADDING_SIZE; } if (this->temp_size >= nsize) { memcpy (this->temp_buf, this->slice_table, tsize); memcpy (this->temp_buf + tsize, buf, buf_size + AV_INPUT_BUFFER_PADDING_SIZE); buf = this->temp_buf; } this->slice_num = 0; } #endif #if XFF_VIDEO > 1 this->avpkt->data = buf; this->avpkt->size = buf_size + tsize; this->avpkt->flags = AV_PKT_FLAG_KEY; # ifdef XFF_AVCODEC_FRAME_PTS this->avpkt->pts = this->tagged_pts; # endif # if XFF_PALETTE == 2 || XFF_PALETTE == 3 if (buf && this->palette_changed) { uint8_t *sd = av_packet_new_side_data (this->avpkt, AV_PKT_DATA_PALETTE, 256 * 4); if (sd) memcpy (sd, this->palette, 256 * 4); } # endif /* XFF_PALETTE */ this->decode_attempts++; # if XFF_VIDEO == 3 { int e = AVERROR (EAGAIN); if (buf || !this->flush_packet_sent) { e = avcodec_send_packet (this->context, this->avpkt); this->flush_packet_sent = (buf == NULL); } len = (e == AVERROR (EAGAIN)) ? 0 : buf_size; /* that calls av_frame_unref () again but seems safe. */ *err = avcodec_receive_frame (this->context, av_frame); } # else { int got_picture = 0; len = avcodec_decode_video2 (this->context, av_frame, &got_picture, this->avpkt); if ((len < 0) || (len > (int)buf_size)) { *err = got_picture ? 0 : len; len = buf_size; } else { *err = got_picture ? 0 : AVERROR (EAGAIN); } } # endif # if XFF_PALETTE == 2 || XFF_PALETTE == 3 if (buf && this->palette_changed) { /* Prevent freeing our data buffer */ this->avpkt->data = NULL; this->avpkt->size = 0; # if XFF_PALETTE == 2 /* TJ. Oh dear and sigh. AVPacket side data handling is broken even in ffmpeg 1.1.1 - see avcodec/avpacket.c The suggested av_free_packet () would leave a memory leak here, and ff_packet_free_side_data () is private. */ av_destruct_packet (this->avpkt); # else /* XFF_PALETTE == 3 */ /* XFF_PACKET_UNREF (this->avpkt); */ ; # endif this->palette_changed = 0; } # endif /* XFF_PALETTE */ #else /* XFF_VIDEO */ this->decode_attempts++; { int got_picture = 0; len = avcodec_decode_video (this->context, av_frame, got_picture, buf, buf_size); if ((len < 0) || (len > (int)buf_size)) { *err = got_picture ? 0 : len; len = buf_size; } else { *err = got_picture ? 0 : AVERROR (EAGAIN); } } #endif /* XFF_VIDEO */ #if ENABLE_VAAPI if (locked) { this->accel->unlock_vaapi(this->accel_img); } #endif /* ENABLE_VAAPI */ return len; } static void ff_reset (video_decoder_t *this_gen); static void ff_handle_mpeg12_buffer (ff_video_decoder_t *this, buf_element_t *buf) { vo_frame_t *img; int free_img; int len; int offset = 0; int flush = 0; int size = buf->size; lprintf("handle_mpeg12_buffer\n"); if (!this->mpeg_parser) { /* initialize mpeg parser */ ff_init_mpeg12_mode(this); if (!this->mpeg_parser) { return; } } #ifdef DEBUG_MPEG_PARSER printf ("ff_mpeg_parser: buf %d bytes.\n", size); #endif while ((size > 0) || (flush == 1)) { uint8_t *current; int next_flush, err; #ifdef XFF_AV_BUFFER int need_unref = 0; #endif /* apply valid pts to first frame _starting_ thereafter only */ if (this->pts && !this->tagged_pts) { this->tagged_pts = ff_tag_pts (this, this->pts); #ifdef XFF_AVCODEC_REORDERED_OPAQUE this->context->reordered_opaque = this->av_frame->reordered_opaque = this->tagged_pts; #endif #ifdef XFF_AVCODEC_FRAME_PTS this->av_frame->pts = this->tagged_pts; #endif this->pts = 0; } if (!flush) { current = mpeg_parser_decode_data(this->mpeg_parser, buf->content + offset, buf->content + offset + size, &next_flush); } else { current = buf->content + offset + size; /* end of the buffer */ next_flush = 0; } if (current == NULL) { lprintf("current == NULL\n"); return; } if (this->mpeg_parser->has_sequence) { ff_handle_mpeg_sequence(this, this->mpeg_parser); } if (!this->decoder_ok) return; if (flush) { lprintf("flush lavc buffers\n"); /* hack: ffmpeg outputs the last frame if size=0 */ this->mpeg_parser->buffer_size = 0; } /* skip decoding b frames if too late */ #if XFF_VIDEO > 1 this->context->skip_frame = (this->skipframes > 0) ? AVDISCARD_NONREF : AVDISCARD_DEFAULT; #else this->context->hurry_up = (this->skipframes > 0); #endif lprintf("avcodec_decode_video: size=%d\n", this->mpeg_parser->buffer_size); err = 1; len = decode_video_wrapper (this, this->av_frame, &err, this->mpeg_parser->chunk_buffer, this->mpeg_parser->buffer_size); #ifdef XFF_AV_BUFFER need_unref = 1; #endif lprintf ("avcodec_decode_video: decoded_size=%d, err=%d\n", len, err); len = current - buf->content - offset; lprintf("avcodec_decode_video: consumed_size=%d\n", len); flush = next_flush; if ((err < 0) && (err != AVERROR (EAGAIN))) { #ifdef AVERROR_EOF if (err == AVERROR_EOF) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: lost track, reinitializing.\n"); ff_reset (&this->video_decoder); } else #endif { char b[20]; _x_tag32_me2str (b, -err); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: error decompressing frame [%s] (%d).\n", b, err); } } size -= len; offset += len; if (!err && this->class->enable_vaapi) { this->bih.biWidth = this->context->width; this->bih.biHeight = this->context->height; } if( this->set_stream_info) { set_stream_info(this); this->set_stream_info = 0; } if (!err && this->av_frame->data[0]) { /* got a picture, draw it */ img = NULL; #ifdef ENABLE_DIRECT_RENDERING if (this->av_frame->opaque) { ff_saved_frame_t *ffsf = (ff_saved_frame_t *)this->av_frame->opaque; img = ffsf->vo_frame; } #endif if (!img) { /* indirect rendering */ img = this->stream->video_out->get_frame (this->stream->video_out, this->bih.biWidth, this->bih.biHeight, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); ff_convert_frame(this, img, this->av_frame); free_img = 1; } else { /* DR1 */ free_img = 0; } /* transfer some more frame settings for deinterlacing */ img->progressive_frame = !this->av_frame->interlaced_frame; img->top_field_first = this->av_frame->top_field_first; /* get back reordered pts */ img->pts = ff_untag_pts (this, this->av_frame); this->tagged_pts = 0; #ifdef XFF_AVCODEC_REORDERED_OPAQUE this->context->reordered_opaque = 0; #endif if (this->av_frame->repeat_pict) img->duration = this->video_step * 3 / 2; else img->duration = this->video_step; this->skipframes = img->draw(img, this->stream); this->state = STATE_FRAME_SENT; if(free_img) img->free(img); } else { if ( #if XFF_VIDEO > 1 this->context->skip_frame != AVDISCARD_DEFAULT #else this->context->hurry_up #endif ) { /* skipped frame, output a bad frame */ img = this->stream->video_out->get_frame (this->stream->video_out, this->bih.biWidth, this->bih.biHeight, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); img->pts = 0; img->duration = this->video_step; img->bad_frame = 1; this->skipframes = img->draw(img, this->stream); img->free(img); } } #ifdef XFF_AV_BUFFER if (need_unref) { av_frame_unref (this->av_frame); need_unref = 0; } #endif } } #ifdef HAVE_POSTPROC static void ff_postprocess (ff_video_decoder_t *this, AVFrame *av_frame, vo_frame_t *img) { int qstride, qtype; int8_t *qtable; #ifdef XFF_AV_BUFFER # if LIBAVUTIL_VERSION_INT < XFF_INT_VERSION(53,0,0) qtable = av_frame_get_qp_table (av_frame, &qstride, &qtype); # else /* Why should they keep these long deprecated fields, and remove their safe accessor av_frame_get_qp_table () instead?? */ qtable = av_frame->qscale_table; qstride = av_frame->qstride; qtype = av_frame->qscale_type; # endif #else qtable = av_frame->qscale_table; qstride = av_frame->qstride; qtype = 0; #endif pp_postprocess ((const uint8_t **)av_frame->data, av_frame->linesize, img->base, img->pitches, this->bih.biWidth, this->bih.biHeight, qtable, qstride, this->our_mode, this->our_context, av_frame->pict_type | (qtype ? PP_PICT_TYPE_QP2 : 0)); } #endif /* HAVE_POSTPROC */ static int ff_video_step_get (ff_video_decoder_t *this) { /* use externally provided video_step or fall back to stream's time_base otherwise */ int step = this->video_step; if (step || !this->context->time_base.den) return step; /* good: 2 * 1001 / 48000. */ step = (int64_t)90000 * this->context->ticks_per_frame * this->context->time_base.num / this->context->time_base.den; if (step >= 90) return step; /* bad: 2 * 1 / 60000. seen this once from broken h.264 video usability info (VUI). * VAAPI seems to apply a similar HACK.*/ step = (int64_t)90000000 * this->context->ticks_per_frame * this->context->time_base.num / this->context->time_base.den; return step; } static void ff_handle_buffer (ff_video_decoder_t *this, buf_element_t *buf) { uint8_t *chunk_buf = this->buf; AVRational avr00 = {0, 1}; lprintf("handle_buffer\n"); if (!this->decoder_ok) { if (!this->decoder_init_mode) return; int codec_type = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); if (!ff_check_extradata(this, codec_type, buf)) return; /* init ffmpeg decoder */ init_video_codec(this, codec_type); this->decoder_init_mode = 0; if (!this->decoder_ok) return; init_postprocess(this); } if (buf->decoder_flags & BUF_FLAG_FRAME_START) { lprintf("BUF_FLAG_FRAME_START\n"); this->size = 0; } if (this->size == 0) { this->tagged_pts = ff_tag_pts (this, this->pts); /* take over pts when we are about to buffer a frame */ #ifdef XFF_AVCODEC_REORDERED_OPAQUE this->av_frame->reordered_opaque = this->context->reordered_opaque = this->tagged_pts; #endif #ifdef XFF_AVCODEC_FRAME_PTS this->av_frame->pts = this->tagged_pts; #endif this->pts = 0; } /* data accumulation */ if (buf->size > 0) { if ((this->size == 0) && ((buf->size + AV_INPUT_BUFFER_PADDING_SIZE) < buf->max_size) && (buf->decoder_flags & BUF_FLAG_FRAME_END)) { /* buf contains a complete frame */ /* no memcpy needed */ chunk_buf = buf->content; this->size = buf->size; lprintf("no memcpy needed to accumulate data\n"); } else { /* copy data into our internal buffer */ ff_check_bufsize(this, this->size + buf->size); chunk_buf = this->buf; /* ff_check_bufsize might realloc this->buf */ xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; lprintf("accumulate data into this->buf\n"); } } if (buf->decoder_flags & BUF_FLAG_FRAME_END) { vo_frame_t *img; int free_img; int err, len; int got_one_picture = 0; int offset = 0; int codec_type = buf->type & 0xFFFF0000; int video_step_to_use = this->video_step; #ifdef XFF_AV_BUFFER int need_unref = 0; #endif /* pad input data */ /* note: bitstream, alt bitstream reader or something will cause * severe mpeg4 artifacts if padding is less than 32 bits. */ memset(chunk_buf + this->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); while (this->size > 0) { /* DV frames can be completely skipped */ if ((codec_type == BUF_VIDEO_DV) && this->skipframes) { this->size = 0; err = 1; } else { /* skip decoding b frames if too late */ #if XFF_VIDEO > 1 this->context->skip_frame = (this->skipframes > 0) ? AVDISCARD_NONREF : AVDISCARD_DEFAULT; #else this->context->hurry_up = (this->skipframes > 0); #endif lprintf("buffer size: %d\n", this->size); #ifdef XFF_AV_BUFFER if (need_unref) { av_frame_unref (this->av_frame); need_unref = 0; } #endif len = decode_video_wrapper (this, this->av_frame, &err, &chunk_buf[offset], this->size); lprintf ("consumed size: %d, err: %d\n", len, err); #ifdef XFF_AV_BUFFER need_unref = 1; #endif /* reset consumed pts value */ this->tagged_pts = ff_tag_pts (this, 0); #ifdef XFF_AVCODEC_REORDERED_OPAQUE this->context->reordered_opaque = this->tagged_pts; #endif if (err) { if (err == AVERROR (EAGAIN)) { offset += len; this->size -= len; continue; } #ifdef AVERROR_EOF if (err == AVERROR_EOF) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: lost track, reinitializing.\n"); ff_reset (&this->video_decoder); } else #endif { char b[20]; _x_tag32_me2str (b, -err); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: error decompressing frame [%s] (%d).\n", b, err); } this->size = 0; } else { offset += len; this->size -= len; if (this->size > 0) { memmove (this->buf, &chunk_buf[offset], this->size); chunk_buf = this->buf; /* take over pts for next access unit */ this->tagged_pts = ff_tag_pts (this, this->pts); #ifdef XFF_AVCODEC_REORDERED_OPAQUE this->av_frame->reordered_opaque = this->context->reordered_opaque = this->tagged_pts; #endif #ifdef XFF_AVCODEC_FRAME_PTS this->av_frame->pts = this->tagged_pts; #endif this->pts = 0; } } } video_step_to_use = ff_video_step_get (this); /* aspect ratio provided by ffmpeg, override previous setting */ if ((this->aspect_ratio_prio < 2) && av_cmp_q(this->context->sample_aspect_ratio, avr00)) { if (!this->bih.biWidth || !this->bih.biHeight) { this->bih.biWidth = this->context->width; this->bih.biHeight = this->context->height; } this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * (double)this->bih.biWidth / (double)this->bih.biHeight; this->aspect_ratio_prio = 2; lprintf("ffmpeg aspect ratio: %f\n", this->aspect_ratio); set_stream_info(this); } if( this->set_stream_info) { set_stream_info(this); this->set_stream_info = 0; } if (!err && this->av_frame->data[0]) { /* got a picture, draw it */ got_one_picture = 1; img = NULL; #ifdef ENABLE_DIRECT_RENDERING if (this->av_frame->opaque) { ff_saved_frame_t *ffsf = (ff_saved_frame_t *)this->av_frame->opaque; img = ffsf->vo_frame; } #endif if (!img) { /* indirect rendering */ /* prepare for colorspace conversion */ #ifdef ENABLE_VAAPI if (this->context->pix_fmt != PIX_FMT_VAAPI_VLD && !this->cs_convert_init) #else if (!this->cs_convert_init) #endif { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ff_video_dec: PIX_FMT %d\n", this->context->pix_fmt); switch (this->context->pix_fmt) { case PIX_FMT_ARGB: case PIX_FMT_BGRA: case PIX_FMT_RGB24: case PIX_FMT_BGR24: case PIX_FMT_RGB555BE: case PIX_FMT_RGB555LE: case PIX_FMT_RGB565BE: case PIX_FMT_RGB565LE: case PIX_FMT_PAL8: this->output_format = XINE_IMGFMT_YUY2; break; default: ; } this->cs_convert_init = 1; } if (this->aspect_ratio_prio == 0) { this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight; this->aspect_ratio_prio = 1; lprintf("default aspect ratio: %f\n", this->aspect_ratio); set_stream_info(this); } /* xine-lib expects the framesize to be a multiple of 16x16 (macroblock) */ img = this->stream->video_out->get_frame (this->stream->video_out, (this->bih.biWidth + 15) & ~15, (this->bih.biHeight + 15) & ~15, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); img->crop_right = img->width - this->bih.biWidth; img->crop_bottom = img->height - this->bih.biHeight; free_img = 1; } else { /* DR1 */ free_img = 0; } /* post processing */ #ifdef HAVE_POSTPROC if(this->pp_quality != this->class->pp_quality && this->context->pix_fmt != PIX_FMT_VAAPI_VLD) pp_change_quality(this); if(this->pp_available && this->pp_quality && this->context->pix_fmt != PIX_FMT_VAAPI_VLD) { if (!free_img) { /* DR1: filter into a new frame. Same size to avoid reallcation, just move the image to top left corner. */ img = this->stream->video_out->get_frame (this->stream->video_out, img->width, img->height, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); img->crop_right = img->width - this->bih.biWidth; img->crop_bottom = img->height - this->bih.biHeight; free_img = 1; } ff_postprocess (this, this->av_frame, img); } else #endif /* HAVE_POSTPROC */ if (free_img) { /* colorspace conversion or copy */ ff_convert_frame(this, img, this->av_frame); } img->pts = ff_untag_pts(this, this->av_frame); /* workaround for weird 120fps streams, as well as some rv20 with frame duration 3pts. */ if (video_step_to_use <= 750) { /* fallback to the VIDEO_PTS_MODE */ video_step_to_use = 0; } if (video_step_to_use && video_step_to_use != this->reported_video_step) _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = video_step_to_use)); if (this->av_frame->repeat_pict) img->duration = video_step_to_use * 3 / 2; else img->duration = video_step_to_use; /* transfer some more frame settings for deinterlacing */ img->progressive_frame = !this->av_frame->interlaced_frame; img->top_field_first = this->av_frame->top_field_first; this->skipframes = img->draw(img, this->stream); this->state = STATE_FRAME_SENT; if(free_img) img->free(img); } } /* workaround for demux_mpeg_pes sending fields as frames: * do not generate a bad frame for the first field picture */ if (!got_one_picture && this->use_bad_frames && (this->size || this->video_step || this->assume_bad_field_picture)) { /* skipped frame, output a bad frame (use size 16x16, when size still uninitialized) */ img = this->stream->video_out->get_frame (this->stream->video_out, (this->bih.biWidth <= 0) ? 16 : ((this->bih.biWidth + 15) & ~15), (this->bih.biHeight <= 0) ? 16 : ((this->bih.biHeight + 15) & ~15), this->aspect_ratio, this->output_format, VO_BOTH_FIELDS|this->frame_flags); /* set PTS to allow early syncing */ img->pts = ff_untag_pts(this, this->av_frame); img->duration = video_step_to_use; /* additionally crop away the extra pixels due to adjusting frame size above */ img->crop_right = this->bih.biWidth <= 0 ? 0 : (img->width - this->bih.biWidth); img->crop_bottom = this->bih.biHeight <= 0 ? 0 : (img->height - this->bih.biHeight); img->bad_frame = 1; this->skipframes = img->draw(img, this->stream); img->free(img); this->state = STATE_FRAME_SENT; } this->assume_bad_field_picture = !got_one_picture; #ifdef XFF_AV_BUFFER if (need_unref) { av_frame_unref (this->av_frame); need_unref = 0; } #endif } } static void ff_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; lprintf ("processing packet type = %08x, len = %d, decoder_flags=%08x\n", buf->type, buf->size, buf->decoder_flags); if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { this->video_step = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = this->video_step)); } if (buf->decoder_flags & BUF_FLAG_PREVIEW) { ff_handle_preview_buffer(this, buf); } else { if (buf->decoder_flags & BUF_FLAG_SPECIAL) { ff_handle_special_buffer(this, buf); } if (buf->decoder_flags & BUF_FLAG_HEADER) { ff_handle_header_buffer(this, buf); if (buf->decoder_flags & BUF_FLAG_ASPECT) { if (this->aspect_ratio_prio < 3) { this->aspect_ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; this->aspect_ratio_prio = 3; lprintf("aspect ratio: %f\n", this->aspect_ratio); set_stream_info(this); } } } else { if (this->decoder_init_mode) ff_handle_preview_buffer(this, buf); /* decode */ /* PES: each valid pts shall be used only once */ if (buf->pts && (buf->pts != this->last_pts)) this->last_pts = this->pts = buf->pts; this->state = STATE_READING_DATA; if ((buf->type & 0xFFFF0000) == BUF_VIDEO_MPEG) { ff_handle_mpeg12_buffer(this, buf); } else { ff_handle_buffer(this, buf); } } } } static void ff_flush_internal (ff_video_decoder_t *this, int display) { vo_frame_t *img; int free_img, frames = 0; int video_step_to_use = this->video_step; AVRational avr00 = {0, 1}; /* This is a stripped version of ff_handle_buffer (). It shall return yet undisplayed frames. */ if (!this->context || !this->decoder_ok || this->state == STATE_FLUSHED) return; /* For some reason, we are flushed right while reading the first frame?? */ if (!this->decode_attempts) return; this->state = STATE_FLUSHED; while (1) { int err = 1; decode_video_wrapper (this, this->av_frame2, &err, NULL, 0); if (err || !this->av_frame2->data[0]) { #ifdef XFF_AV_BUFFER av_frame_unref (this->av_frame2); #endif break; } frames++; if (!display) { #ifdef XFF_AV_BUFFER av_frame_unref (this->av_frame2); #endif continue; } /* All that jizz just to view the last 2 frames of a stream ;-) */ video_step_to_use = ff_video_step_get (this); if ((this->aspect_ratio_prio < 2) && av_cmp_q (this->context->sample_aspect_ratio, avr00)) { if (!this->bih.biWidth || !this->bih.biHeight) { this->bih.biWidth = this->context->width; this->bih.biHeight = this->context->height; } this->aspect_ratio = av_q2d(this->context->sample_aspect_ratio) * (double)this->bih.biWidth / (double)this->bih.biHeight; this->aspect_ratio_prio = 2; set_stream_info (this); } if (this->set_stream_info) { set_stream_info (this); this->set_stream_info = 0; } img = NULL; #ifdef ENABLE_DIRECT_RENDERING if (this->av_frame->opaque) { ff_saved_frame_t *ffsf = (ff_saved_frame_t *)this->av_frame->opaque; img = ffsf->vo_frame; } #endif if (!img) { /* indirect rendering */ if (this->aspect_ratio_prio == 0) { this->aspect_ratio = (double)this->bih.biWidth / (double)this->bih.biHeight; this->aspect_ratio_prio = 1; lprintf ("default aspect ratio: %f\n", this->aspect_ratio); set_stream_info (this); } /* xine-lib expects the framesize to be a multiple of 16x16 (macroblock) */ img = this->stream->video_out->get_frame (this->stream->video_out, (this->bih.biWidth + 15) & ~15, (this->bih.biHeight + 15) & ~15, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS | this->frame_flags); img->crop_right = img->width - this->bih.biWidth; img->crop_bottom = img->height - this->bih.biHeight; free_img = 1; } else { /* DR1 */ free_img = 0; } /* post processing */ #ifdef HAVE_POSTPROC if (this->pp_quality != this->class->pp_quality && this->context->pix_fmt != PIX_FMT_VAAPI_VLD) pp_change_quality (this); if (this->pp_available && this->pp_quality && this->context->pix_fmt != PIX_FMT_VAAPI_VLD) { if (!free_img) { /* DR1: filter into a new frame. Same size to avoid reallcation, just move the image to top left corner. */ img = this->stream->video_out->get_frame (this->stream->video_out, img->width, img->height, this->aspect_ratio, this->output_format, VO_BOTH_FIELDS | this->frame_flags); img->crop_right = img->width - this->bih.biWidth; img->crop_bottom = img->height - this->bih.biHeight; free_img = 1; } ff_postprocess (this, this->av_frame2, img); } else #endif /* HAVE_POSTPROC */ if (free_img) { /* colorspace conversion or copy */ ff_convert_frame (this, img, this->av_frame2); } img->pts = ff_untag_pts (this, this->av_frame2); if (video_step_to_use <= 750) video_step_to_use = 0; img->duration = this->av_frame2->repeat_pict ? video_step_to_use * 3 / 2 : video_step_to_use; img->progressive_frame = !this->av_frame2->interlaced_frame; img->top_field_first = this->av_frame2->top_field_first; this->skipframes = img->draw (img, this->stream); if (free_img) img->free (img); #ifdef XFF_AV_BUFFER av_frame_unref (this->av_frame2); #endif } this->decode_attempts = 0; if (frames) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: flushed out %s%d frames.\n", display ? "and displayed " : "", frames); } #ifdef ENABLE_DIRECT_RENDERING static void ff_free_dr1_frames (ff_video_decoder_t *this, int all) { int frames; /* Some codecs (wmv2, vp6, svq3...) are hard-wired to a few reference frames. They will only be replaced when new ones arrive, and freed on codec close. They also have no AVCodec.flush () callback for manual freeing (that is, avcodec_flush_buffers () does nothing). Even worse: multithreading seems to always do it like that... So lets tolerate this behaviour on plain stream seek. */ if (!all) { frames = this->ffsf_num; if (!frames) return; if (frames < 12) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: tolerating %d held DR1 frames.\n", frames); return; } } /* frame garbage collector here - workaround for buggy ffmpeg codecs that * don't release their DR1 frames */ /* TJ. A note on libavcodec v55. Looks like I found a way not to get to this point. If it should happen anyway, we may earn some small memory leaks here. Using the old get_buffer () API emulation makes even bigger leaks (per frame, +3*AVBufferRef, +1*AVBuffer, +1*AVCodecContext, +1*AVFrame). Tracking and killing the AVBufferRef's themselves would risk heap corruption and segfaults. Now tell me whether I really sigh too much... */ pthread_mutex_lock (&this->ffsf_mutex); frames = 0; while (!DLIST_IS_EMPTY (&this->ffsf_used)) { ff_saved_frame_t *ffsf = (ff_saved_frame_t *)this->ffsf_used.head; if (ffsf->vo_frame) { ffsf->vo_frame->free (ffsf->vo_frame); frames++; } DLIST_REMOVE (&ffsf->node); DLIST_ADD_TAIL (&ffsf->node, &this->ffsf_free); this->ffsf_num--; } pthread_mutex_unlock (&this->ffsf_mutex); /* we probably never get this. */ if (frames) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_video_dec: freed %d orphaned DR1 frames.\n", frames); } #endif static void ff_flush (video_decoder_t *this_gen) { ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; lprintf ("ff_flush\n"); if (this->state == STATE_FRAME_SENT) ff_flush_internal (this, 1); } static void ff_reset (video_decoder_t *this_gen) { ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; lprintf ("ff_reset\n"); this->size = 0; this->state = STATE_RESET; if(this->context && this->decoder_ok) { /* Discard any undisplayed frames. */ ff_flush_internal (this, 0); /* Ask decoder to free held reference frames (which it may ignore). */ avcodec_flush_buffers(this->context); #ifdef ENABLE_DIRECT_RENDERING /* Free obviously too many DR1 frames. */ ff_free_dr1_frames (this, 0); #endif } if (this->mpeg_parser) mpeg_parser_reset(this->mpeg_parser); /* this->pts_tag_pass = 0; */ #if XFF_AVCODEC_SLICE_TABLE == 2 this->slice_num = 0; #endif } static void ff_dispose (video_decoder_t *this_gen) { ff_video_decoder_t *this = (ff_video_decoder_t *) this_gen; lprintf ("ff_dispose\n"); ff_flush_internal (this, 0); rgb2yuy2_free (this->rgb2yuy2); if (this->decoder_ok) { uint8_t *ed; pthread_mutex_lock(&ffmpeg_lock); ed = this->context->extradata; this->context->extradata = NULL; this->context->extradata_size = 0; XFF_FREE_CONTEXT (this->context); pthread_mutex_unlock(&ffmpeg_lock); _x_freep (&ed); #ifdef ENABLE_DIRECT_RENDERING ff_free_dr1_frames (this, 1); #endif this->stream->video_out->close(this->stream->video_out, this->stream); this->decoder_ok = 0; } else if (this->context) { _x_freep (&this->context->extradata); this->context->extradata_size = 0; XFF_FREE_CONTEXT (this->context); } #if XFF_AVCODEC_SLICE_TABLE == 1 free (this->slice_offset_table); #elif XFF_AVCODEC_SLICE_TABLE == 2 free (this->temp_buf); #endif #if XFF_VIDEO > 1 XFF_PACKET_UNREF (this->avpkt); #endif if( this->av_frame ) XFF_FREE_FRAME( this->av_frame ); if (this->av_frame2) XFF_FREE_FRAME (this->av_frame2); if (this->buf) free(this->buf); this->buf = NULL; #ifdef HAVE_POSTPROC if(this->our_context) pp_free_context(this->our_context); if(this->our_mode) pp_free_mode(this->our_mode); #endif /* HAVE_POSTPROC */ mpeg_parser_dispose(this->mpeg_parser); #ifdef ENABLE_DIRECT_RENDERING while (!DLIST_IS_EMPTY (&this->ffsf_free)) { ff_saved_frame_t *ffsf = (ff_saved_frame_t *)this->ffsf_free.head; DLIST_REMOVE (&ffsf->node); free (ffsf); } if (this->ffsf_total) xprintf (this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: used %d DR1 frames.\n"), this->ffsf_total); pthread_mutex_destroy (&this->ffsf_mutex); #endif #ifdef ENABLE_VAAPI if(this->accel_img) this->accel_img->free(this->accel_img); #endif free (this_gen); } static video_decoder_t *ff_video_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { ff_video_decoder_t *this ; const AVCodec *codec = NULL; uint32_t video_type; size_t i; lprintf ("open_plugin\n"); init_once_routine(); /* check for codec support */ video_type = BUF_VIDEO_BASE | (_x_get_video_streamtype(stream) << 16); for (i = 0; i < ff_video_lookup_entries; i++) { if(ff_video_lookup[i].type == video_type) { pthread_mutex_lock(&ffmpeg_lock); codec = avcodec_find_decoder(ff_video_lookup[i].id); pthread_mutex_unlock(&ffmpeg_lock); _x_meta_info_set_utf8(stream, XINE_META_INFO_VIDEOCODEC, ff_video_lookup[i].name); break; } } if (!codec) { xprintf (stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"), video_type); return NULL; } lprintf("lavc decoder found\n"); this = calloc(1, sizeof (ff_video_decoder_t)); if (!this) return NULL; /* Do these first, when compiler still knows stream is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ #ifndef HAVE_ZERO_SAFE_MEM this->size = 0; this->decoder_ok = 0; this->aspect_ratio = 0; this->pts_tag_pass = 0; # ifdef HAVE_POSTPROC this->pp_quality = 0; this->our_context = NULL; this->our_mode = NULL; # endif this->mpeg_parser = NULL; this->set_stream_info = 0; this->rgb2yuy2 = NULL; # ifdef ENABLE_VAAPI this->accel = NULL; this->accel_img = NULL; # endif # if XFF_VIDEO == 3 this->flush_packet_sent = 0; # endif # if XFF_AVCODEC_SLICE_TABLE == 2 this->temp_size = 0; this->temp_buf = NULL; # endif #endif this->video_decoder.decode_data = ff_decode_data; this->video_decoder.flush = ff_flush; this->video_decoder.reset = ff_reset; this->video_decoder.discontinuity = ff_discontinuity; this->video_decoder.dispose = ff_dispose; this->stream = stream; this->class = (ff_video_class_t *)class_gen; this->codec = codec; this->bufsize = VIDEOBUFSIZE; do { this->buf = malloc (VIDEOBUFSIZE + AV_INPUT_BUFFER_PADDING_SIZE); if (this->buf) { this->av_frame = XFF_ALLOC_FRAME (); if (this->av_frame) { this->av_frame2 = XFF_ALLOC_FRAME (); if (this->av_frame2) { this->context = XFF_ALLOC_CONTEXT (); if (this->context) break; XFF_FREE_FRAME (this->av_frame2); } XFF_FREE_FRAME (this->av_frame); } free (this->buf); } free (this); return NULL; } while (0); this->decoder_init_mode = 1; this->context->opaque = this; #if XFF_PALETTE == 1 this->context->palctrl = NULL; #endif #ifdef ENABLE_DIRECT_RENDERING DLIST_INIT (&this->ffsf_free); DLIST_INIT (&this->ffsf_used); pthread_mutex_init (&this->ffsf_mutex, NULL); #endif #ifdef ENABLE_EMMS this->use_emms = !!(xine_mm_accel () & (MM_ACCEL_X86_MMX | MM_ACCEL_X86_MMXEXT)); #endif this->pix_fmt = -1; #ifdef LOG this->debug_fmt = -1; #endif #if XFF_VIDEO > 1 XFF_PACKET_NEW (this->avpkt); #endif #ifdef ENABLE_VAAPI if (this->class->enable_vaapi && (stream->video_out->get_capabilities(stream->video_out) & VO_CAP_VAAPI)) { xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: vaapi_mpeg_softdec %d\n"), this->class->vaapi_mpeg_softdec ); this->accel_img = stream->video_out->get_frame( stream->video_out, 1920, 1080, 1, XINE_IMGFMT_VAAPI, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL ); if( this->accel_img ) { this->accel = ((vaapi_accel_t*)this->accel_img->accel_data)->f; xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: VAAPI Enabled in config.\n")); } else { this->class->enable_vaapi = 0; xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n")); } } else { this->class->enable_vaapi = 0; this->class->vaapi_mpeg_softdec = 0; xprintf(this->class->xine, XINE_VERBOSITY_LOG, _("ffmpeg_video_dec: VAAPI Enabled disabled by driver.\n")); } #endif return &this->video_decoder; } static void dispose_video_class (video_decoder_class_t *this_gen) { ff_video_class_t *this = (ff_video_class_t *)this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free (this); } void *init_video_plugin (xine_t *xine, const void *data) { ff_video_class_t *this; config_values_t *config; (void)data; this = calloc(1, sizeof (ff_video_class_t)); if (!this) { return NULL; } this->decoder_class.open_plugin = ff_video_open_plugin; this->decoder_class.identifier = "ffmpeg video"; this->decoder_class.description = N_("ffmpeg based video decoder plugin"); this->decoder_class.dispose = dispose_video_class; this->xine = xine; /* Configuration for post processing quality - default to mid (3) for the * moment */ config = xine->config; #ifdef HAVE_POSTPROC this->pp_quality = config->register_range(config, "video.processing.ffmpeg_pp_quality", 3, 0, PP_QUALITY_MAX, _("MPEG-4 postprocessing quality"), _("You can adjust the amount of post processing applied to MPEG-4 video.\n" "Higher values result in better quality, but need more CPU. Lower values may " "result in image defects like block artifacts. For high quality content, " "too heavy post processing can actually make the image worse by blurring it " "too much."), 10, pp_quality_cb, this); #endif /* HAVE_POSTPROC */ this->thread_count = config->register_num(config, "video.processing.ffmpeg_thread_count", 1, _("FFmpeg video decoding thread count"), _("You can adjust the number of video decoding threads which FFmpeg may use.\n" "Higher values should speed up decoding but it depends on the codec used " "whether parallel decoding is supported. A rule of thumb is to have one " "decoding thread per logical CPU (typically 1 to 4).\n" "A change of this setting will take effect with playing the next stream."), 10, thread_count_cb, this); if (this->thread_count < 1) this->thread_count = 1; else if (this->thread_count > 8) this->thread_count = 8; this->skip_loop_filter_enum = config->register_enum(config, "video.processing.ffmpeg_skip_loop_filter", 0, (char **)skip_loop_filter_enum_names, _("Skip loop filter"), _("You can control for which frames the loop filter shall be skipped after " "decoding.\n" "Skipping the loop filter will speedup decoding but may lead to artefacts. " "The number of frames for which it is skipped increases from 'none' to 'all'. " "The default value leaves the decision up to the implementation.\n" "A change of this setting will take effect with playing the next stream."), 10, skip_loop_filter_enum_cb, this); this->choose_speed_over_accuracy = config->register_bool(config, "video.processing.ffmpeg_choose_speed_over_accuracy", 0, _("Choose speed over specification compliance"), _("You may want to allow speed cheats which violate codec specification.\n" "Cheating may speed up decoding but can also lead to decoding artefacts.\n" "A change of this setting will take effect with playing the next stream."), 10, choose_speed_over_accuracy_cb, this); this->enable_dri = config->register_bool(config, "video.processing.ffmpeg_direct_rendering", 1, _("Enable direct rendering"), _("Disable direct rendering if you are experiencing lock-ups with\n" "streams with lot of reference frames."), 10, dri_cb, this); #ifdef ENABLE_VAAPI this->vaapi_mpeg_softdec = config->register_bool(config, "video.processing.vaapi_mpeg_softdec", 0, _("VAAPI Mpeg2 softdecoding"), _("If the machine freezes on mpeg2 decoding use mpeg2 software decoding."), 10, vaapi_mpeg_softdec_func, this); this->enable_vaapi = config->register_bool(config, "video.processing.ffmpeg_enable_vaapi", 1, _("Enable VAAPI"), _("Enable or disable usage of vaapi"), 10, vaapi_enable_vaapi, this); #endif /* ENABLE_VAAPI */ return this; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/demux_avformat.c���������������������������������������������������0000644�0001750�0001750�00000067371�14647725152�017702� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2013-2024 the xine project * Copyright (C) 2013-2020 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <pthread.h> #include <errno.h> #include <libavutil/avutil.h> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavformat/avio.h> #define LOG_MODULE "libavformat" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include <xine/demux.h> #include "ffmpeg_decoder.h" #include "ffmpeg_compat.h" #ifndef LIBAVFORMAT_VERSION_INT # if defined(LIBAVFORMAT_VERSION_MAJOR) && defined(LIBAVFORMAT_VERSION_MINOR) # define LIBAVFORMAT_VERSION_INT XFF_INT_VERSION(LIBAVFORMAT_VERSION_MAJOR,LIBAVFORMAT_VERSION_MINOR,0) # endif #endif #if LIBAVFORMAT_VERSION_INT < XFF_INT_VERSION(57,62,0) #define CODEC_ID(st) ((st)->codec->codec_id) #else #define CODEC_ID(st) ((st)->codecpar->codec_id) #define XFF_CODECPAR 1 #endif /* * avformat dummy input plugin */ typedef struct { input_plugin_t input_plugin; char *mrl; /* 'public' mrl without authentication credentials */ AVFormatContext *fmt_ctx; } avformat_input_plugin_t; static off_t input_avformat_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { (void)this_gen; (void)buf_gen; (void)len; return 0; } static buf_element_t *input_avformat_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { (void)this_gen; (void)fifo; (void)todo; return NULL; } static off_t input_avformat_get_length (input_plugin_t *this_gen) { (void)this_gen; return -1; } static uint32_t input_avformat_get_capabilities (input_plugin_t *this_gen) { (void)this_gen; return INPUT_CAP_SEEKABLE; } static uint32_t input_avformat_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return 0; } static off_t input_avformat_get_current_pos (input_plugin_t *this_gen) { (void)this_gen; return 0; } static off_t input_avformat_seek (input_plugin_t *this_gen, off_t offset, int origin) { (void)this_gen; (void)offset; (void)origin; return -1; } static const char* input_avformat_get_mrl (input_plugin_t *this_gen) { avformat_input_plugin_t *this = (avformat_input_plugin_t *) this_gen; return this->mrl; } static int input_avformat_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { avformat_input_plugin_t *this = (avformat_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_DEMUXER: if (this->fmt_ctx) { if (data) { *(const char **)data = DEMUX_AVFORMAT_ID; } return INPUT_OPTIONAL_SUCCESS; } break; case INPUT_OPTIONAL_DATA_fmt_ctx: *((AVFormatContext **)data) = this->fmt_ctx; this->fmt_ctx = NULL; return INPUT_OPTIONAL_SUCCESS; } return INPUT_OPTIONAL_UNSUPPORTED; } static int input_avformat_open (input_plugin_t *this_gen) { (void)this_gen; return 1; } static void input_avformat_dispose (input_plugin_t *this_gen ) { avformat_input_plugin_t *this = (avformat_input_plugin_t *) this_gen; avformat_close_input(&this->fmt_ctx); _x_freep (&this->mrl); free (this_gen); } /* * avformat input class */ static input_plugin_t *input_avformat_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { const int proto_len = strlen(DEMUX_AVFORMAT_ID"+"); if (!mrl || !*mrl) { return NULL; } /* accept only mrls with protocol part */ if (!strchr(mrl, ':') || (strchr(mrl, '/') < strchr(mrl, ':'))) { return NULL; } init_once_routine(); /* always accept own protocol */ /* avformat+http://... --> use avformat instead of xine native input/demux plugins */ if (!strncasecmp (mrl, DEMUX_AVFORMAT_ID"+", proto_len)) { mrl += proto_len; } /* rtsp lower transport */ AVDictionary *options = NULL; char *real_mrl = NULL; if (!strncmp(mrl, "rtsp+tcp", 8)) { av_dict_set(&options, "rtsp_transport", "tcp", 0); real_mrl = strdup(mrl); memmove(real_mrl + 4, real_mrl + 8, strlen(real_mrl) - 8 + 1); } else if (!strncmp(mrl, "rtsp+http", 9)) { av_dict_set(&options, "rtsp_transport", "http", 0); real_mrl = strdup(mrl); memmove(real_mrl + 4, real_mrl + 9, strlen(real_mrl) - 9 + 1); } /* open input file, and allocate format context */ AVFormatContext *fmt_ctx = NULL; int error; if ((error = avformat_open_input(&fmt_ctx, real_mrl ? real_mrl : mrl, NULL, &options)) < 0) { char buf[80] = ""; if (!av_strerror(error, buf, sizeof(buf))) { xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Could not open source '%s': %s\n", mrl, buf); } else { xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Could not open source '%s'\n", mrl); } free(real_mrl); return NULL; } _x_freep(&real_mrl); /* create xine input plugin */ avformat_input_plugin_t *this; this = calloc(1, sizeof(avformat_input_plugin_t)); if (!this) { return NULL; } this->mrl = _x_mrl_remove_auth(mrl); this->fmt_ctx = fmt_ctx; this->input_plugin.open = input_avformat_open; this->input_plugin.get_capabilities = input_avformat_get_capabilities; this->input_plugin.read = input_avformat_read; this->input_plugin.read_block = input_avformat_read_block; this->input_plugin.seek = input_avformat_seek; this->input_plugin.get_current_pos = input_avformat_get_current_pos; this->input_plugin.get_length = input_avformat_get_length; this->input_plugin.get_blocksize = input_avformat_get_blocksize; this->input_plugin.get_mrl = input_avformat_get_mrl; this->input_plugin.get_optional_data = input_avformat_get_optional_data; this->input_plugin.dispose = input_avformat_dispose; this->input_plugin.input_class = cls_gen; /* do not expose authentication credentials in title (if title is not set, it defaults to mrl in xine-ui) */ _x_meta_info_set(stream, XINE_META_INFO_TITLE, this->mrl); return &this->input_plugin; } void *init_avformat_input_plugin (xine_t *xine, const void *data) { static const input_class_t input_class = { .get_instance = input_avformat_get_instance, .description = N_("libavformat input plugin"), .identifier = DEMUX_AVFORMAT_ID, .dispose = NULL, }; (void)xine; (void)data; return (void *)&input_class; } /* * avformat demux plugin */ typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; int status; int num_video_frames; AVFormatContext *fmt_ctx; int video_stream_idx; /* selected avformat video stream */ unsigned int audio_track_count;/* number of xine audio tracks */ int *audio_stream_idx; /* selected avformat audio streams. index: xine audio track #. */ unsigned int num_streams; /* size of xine_buf_type[] array */ uint32_t *xine_buf_type; /* xine buffer types. index: avformat stream_index */ /* detect discontinuity */ int64_t last_pts; int send_newpts; int seek_flag; } avformat_demux_plugin_t; /* * TODO: * - subtitle streams * - metadata */ #define WRAP_THRESHOLD 360000 static void check_newpts(avformat_demux_plugin_t *this, int64_t pts) { int64_t diff = this->last_pts - pts; if (this->seek_flag || this->send_newpts || (this->last_pts && llabs(diff) > WRAP_THRESHOLD)) { _x_demux_control_newpts(this->stream, pts, this->seek_flag); this->send_newpts = 0; this->seek_flag = 0; this->last_pts = pts; } } static uint32_t video_codec_lookup(avformat_demux_plugin_t *this, unsigned id) { size_t i; for (i = 0; i < ff_video_lookup_entries; i++) { if (ff_video_lookup[i].id == id) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": found video codec '%s'\n", ff_video_lookup[i].name); return ff_video_lookup[i].type; } } return 0; } static uint32_t audio_codec_lookup(avformat_demux_plugin_t *this, unsigned id) { size_t i; for (i = 0; i < ff_audio_lookup_entries; i++) { if (ff_audio_lookup[i].id == id) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": found audio codec '%s'\n", ff_audio_lookup[i].name); return ff_audio_lookup[i].type; } } switch (id) { case CODEC_ID_PCM_S16LE: return BUF_AUDIO_LPCM_LE; case CODEC_ID_PCM_S16BE: return BUF_AUDIO_LPCM_BE; case CODEC_ID_MP2: return BUF_AUDIO_MPEG; case CODEC_ID_AC3: return BUF_AUDIO_A52; } return 0; } /* copied from libavformat/utils.c (not available in recent libav API) */ static AVProgram *_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s) { unsigned i, j; for (i = 0; i < ic->nb_programs; i++) { if (ic->programs[i] == last) { last = NULL; } else { if (!last) for (j = 0; j < ic->programs[i]->nb_stream_indexes; j++) if (ic->programs[i]->stream_index[j] == (unsigned int)s) return ic->programs[i]; } } return NULL; } static int find_avformat_streams(avformat_demux_plugin_t *this) { AVProgram *p = NULL; unsigned int nb_streams; unsigned int u; /* find avformat streams */ this->video_stream_idx = av_find_best_stream(this->fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0); if (this->video_stream_idx < 0 && av_find_best_stream(this->fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, this->video_stream_idx, NULL, 0) < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Could not find supported audio or video stream in the input\n"); return 0; } this->num_streams = this->fmt_ctx->nb_streams; this->xine_buf_type = calloc(this->num_streams, sizeof(uint32_t)); this->audio_stream_idx = calloc(this->num_streams, sizeof(int)); if (!this->xine_buf_type || !this->audio_stream_idx) { return 0; } /* map video stream to xine buffer type */ if (this->video_stream_idx >= 0) { AVStream *st = this->fmt_ctx->streams[this->video_stream_idx]; uint32_t xine_video_type = video_codec_lookup(this, CODEC_ID(st)); if (!xine_video_type) { this->video_stream_idx = -1; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": ffmpeg video codec id %d --> NO xine buffer type\n", CODEC_ID(st)); } else { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": ffmpeg video codec id %d --> xine buffer type 0x%08x\n", CODEC_ID(st), xine_video_type); this->xine_buf_type[this->video_stream_idx] = xine_video_type; } } /* get audio tracks of the program */ if (this->video_stream_idx >= 0) { p = _find_program_from_stream(this->fmt_ctx, NULL, this->video_stream_idx); } nb_streams = p ? p->nb_stream_indexes : this->fmt_ctx->nb_streams; for (u = 0; u < nb_streams; u++) { unsigned int stream_index = p ? p->stream_index[u] : u; AVStream *st = this->fmt_ctx->streams[stream_index]; if (stream_index >= this->num_streams) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Too many streams, ignoring stream #%u\n", u); continue; } #ifdef XFF_CODECPAR # if XFF_AUDIO_CHANNEL_LAYOUT < 2 if (st->codecpar && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate != 0 && st->codecpar->channels != 0) # else if (st->codecpar && st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->sample_rate != 0 && st->codecpar->ch_layout.nb_channels != 0) # endif #else if (st->codec && st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->sample_rate != 0 && st->codec->channels != 0) #endif { uint32_t xine_audio_type = audio_codec_lookup(this, CODEC_ID(st)); if (!xine_audio_type) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": ffmpeg audio codec id %d --> NO xine buffer type\n", CODEC_ID(st)); continue; } xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": ffmpeg audio codec id %d --> xine buffer type 0x%08x\n", CODEC_ID(st), xine_audio_type); this->audio_stream_idx[this->audio_track_count] = stream_index; this->xine_buf_type[stream_index] = xine_audio_type | this->audio_track_count; this->audio_track_count++; } } /* something to play ? */ if (this->video_stream_idx < 0 && !this->audio_track_count) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Could not find matching xine buffer types, aborting\n"); return 0; } /* TODO: set metadata */ #ifdef LOG /* dump metadata */ AVDictionaryEntry *tag = NULL; while ((tag = av_dict_get(this->fmt_ctx->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) printf(" %s=%s\n", tag->key, tag->value); #endif return 1; } static void send_headers_audio(avformat_demux_plugin_t *this) { unsigned ii; for (ii = 0; ii < this->audio_track_count; ii++) { #ifdef XFF_CODECPAR AVCodecParameters *ctx = this->fmt_ctx->streams[this->audio_stream_idx[ii]]->codecpar; #else AVCodecContext *ctx = this->fmt_ctx->streams[this->audio_stream_idx[ii]]->codec; #endif buf_element_t *buf = this->stream->audio_fifo->buffer_pool_alloc (this->stream->audio_fifo); size_t extradata_size = ctx->extradata_size; xine_waveformatex *fmt = (xine_waveformatex *)buf->content; if (!ctx->extradata || extradata_size + sizeof(xine_waveformatex) > (size_t)buf->max_size) { if (extradata_size) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": ignoring large audio extradata (%zd bytes)\n", extradata_size); } extradata_size = 0; } _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, ctx->codec_tag); memset(fmt, 0, sizeof(*fmt)); fmt->cbSize = extradata_size; fmt->nBlockAlign = ctx->block_align; fmt->nAvgBytesPerSec = ctx->bit_rate / 8; if (extradata_size) { memcpy(buf->content + sizeof(xine_waveformatex), ctx->extradata, extradata_size); } buf->type = this->xine_buf_type[this->audio_stream_idx[ii]]; buf->size = extradata_size + sizeof(xine_waveformatex); buf->decoder_info[1] = ctx->sample_rate; buf->decoder_info[2] = ctx->bits_per_coded_sample; #if XFF_AUDIO_CHANNEL_LAYOUT < 2 buf->decoder_info[3] = ctx->channels; #else buf->decoder_info[3] = ctx->ch_layout.nb_channels; #endif buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; this->stream->audio_fifo->put (this->stream->audio_fifo, buf); } } static void send_headers_video(avformat_demux_plugin_t *this) { #ifdef XFF_CODECPAR AVCodecParameters *ctx = this->fmt_ctx->streams[this->video_stream_idx]->codecpar; #else AVCodecContext *ctx = this->fmt_ctx->streams[this->video_stream_idx]->codec; #endif buf_element_t *buf = this->stream->video_fifo->buffer_pool_alloc (this->stream->video_fifo); size_t extradata_size = ctx->extradata_size; xine_bmiheader *bih = (xine_bmiheader *)buf->content; if (!ctx->extradata || extradata_size + sizeof(xine_bmiheader) > (size_t)buf->max_size) { if (extradata_size) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": ignoring large video extradata (%zd bytes)\n", extradata_size); } extradata_size = 0; } _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, ctx->codec_tag); memset(bih, 0, sizeof(*bih)); bih->biSize = sizeof(xine_bmiheader) + extradata_size; bih->biBitCount = ctx->bits_per_coded_sample; bih->biWidth = ctx->width; bih->biHeight = ctx->height; if (extradata_size) { memcpy(buf->content + sizeof(xine_bmiheader), ctx->extradata, extradata_size); } buf->type = this->xine_buf_type[this->video_stream_idx]; buf->size = extradata_size + sizeof(xine_bmiheader); buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_STDHEADER | BUF_FLAG_FRAME_END; this->stream->video_fifo->put (this->stream->video_fifo, buf); } static int send_avpacket(avformat_demux_plugin_t *this) { int64_t stream_pos = avio_tell(this->fmt_ctx->pb); int64_t stream_length = avio_size(this->fmt_ctx->pb); XFF_PACKET_DECL (pkt); uint32_t buffer_type = 0; fifo_buffer_t *fifo = NULL; XFF_PACKET_NEW (pkt); pkt->data = NULL; pkt->size = 0; /* read frame from the file */ if (av_read_frame(this->fmt_ctx, pkt) < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": av_read_frame() failed\n"); return -1; } /* map to xine fifo / buffer type */ if (pkt->stream_index >= 0 && (unsigned)pkt->stream_index < this->num_streams) { buffer_type = this->xine_buf_type [pkt->stream_index]; } else { // TODO: new streams found } if (this->video_stream_idx >= 0 && pkt->stream_index == this->video_stream_idx) { fifo = this->stream->video_fifo; } else { fifo = this->stream->audio_fifo; } /* send to decoder */ if (buffer_type && fifo) { int64_t pts = 0; float input_normpos = (stream_length > 0 && stream_pos > 0) ? (int)(65535 * stream_pos / stream_length) : 0; int total_time = (int)((int64_t)this->fmt_ctx->duration * 1000 / AV_TIME_BASE); int input_time = input_normpos * total_time / 65535; if (pkt->pts != AV_NOPTS_VALUE) { AVStream *stream = this->fmt_ctx->streams [pkt->stream_index]; pts = (int64_t)(pkt->pts * stream->time_base.num * 90000 / stream->time_base.den); check_newpts(this, pts); } if ((buffer_type & BUF_MAJOR_MASK) == BUF_VIDEO_BASE) this->num_video_frames++; _x_demux_send_data (fifo, pkt->data, pkt->size, pts, buffer_type, 0/*decoder_flags*/, input_normpos, input_time, total_time, 0/*frame_number*/); } XFF_PACKET_UNREF (pkt); return 1; } /* * demux interface */ static int demux_avformat_get_status (demux_plugin_t *this_gen) { avformat_demux_plugin_t *this = (avformat_demux_plugin_t *) this_gen; return this->status; } static int demux_avformat_get_stream_length (demux_plugin_t *this_gen) { avformat_demux_plugin_t *this = (avformat_demux_plugin_t *) this_gen; if (this->fmt_ctx) { return (int)((int64_t)this->fmt_ctx->duration * 1000 / AV_TIME_BASE); } return -1; } static uint32_t demux_avformat_get_capabilities(demux_plugin_t *this_gen) { (void)this_gen; return DEMUX_CAP_AUDIOLANG; } static int demux_avformat_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { avformat_demux_plugin_t *this = (avformat_demux_plugin_t *) this_gen; if (!data || !this || !this->fmt_ctx) { return DEMUX_OPTIONAL_UNSUPPORTED; } char *str = data; int channel = *((int *)data); switch (data_type) { case DEMUX_OPTIONAL_DATA_AUDIOLANG: if (channel >= 0 && (unsigned)channel < this->audio_track_count) { AVStream *st = this->fmt_ctx->streams[this->audio_stream_idx[channel]]; AVDictionaryEntry *tag = NULL; if ((tag = av_dict_get(st->metadata, "language", tag, AV_DICT_IGNORE_SUFFIX)) && tag->value[0]) { strcpy(str, tag->value); return DEMUX_OPTIONAL_SUCCESS; } /* input plugin may know the language */ if (this->stream->input_plugin->get_capabilities(this->stream->input_plugin) & INPUT_CAP_AUDIOLANG) return DEMUX_OPTIONAL_UNSUPPORTED; sprintf(str, "%3i", channel); return DEMUX_OPTIONAL_SUCCESS; } else { strcpy(str, "none"); } return DEMUX_OPTIONAL_UNSUPPORTED; } return DEMUX_OPTIONAL_UNSUPPORTED; } static int demux_avformat_send_chunk (demux_plugin_t *this_gen) { avformat_demux_plugin_t *this = (avformat_demux_plugin_t *) this_gen; if (send_avpacket (this) < 0) { /* auto detect still image in video container (webm, avif). */ if (this->num_video_frames == 1) xine_set_param (this->stream, XINE_PARAM_DELAY_FINISHED_EVENT, -1); this->status = DEMUX_FINISHED; } else { this->status = DEMUX_OK; } return this->status; } static void demux_avformat_send_headers (demux_plugin_t *this_gen) { avformat_demux_plugin_t *this = (avformat_demux_plugin_t *) this_gen; _x_demux_control_start(this->stream); if (this->audio_track_count > 0) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); send_headers_audio(this); } if (this->video_stream_idx >= 0) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 1); send_headers_video(this); } this->send_newpts = 1; this->status = DEMUX_OK; } static int avformat_seek (avformat_demux_plugin_t *this, off_t start_pos, int start_time) { int64_t pos; /* seek to timestamp */ if (!start_pos && start_time) { pos = (int)(AV_TIME_BASE * (int64_t)start_time / 1000); if (av_seek_frame(this->fmt_ctx, -1, pos, 0) >= 0) { return 0; } return -1; } #if 0 /* seek to byte offset */ pos = (int64_t)start_pos * avio_size(this->fmt_ctx->pb) / 65535; if (av_seek_frame(this->fmt_ctx, -1, pos, AVSEEK_FLAG_BYTE) >= 0) { return 0; } #endif /* stream does not support seeking to byte offset. Final try with timestamp. */ pos = (int64_t)start_pos * this->fmt_ctx->duration / 65535; if (av_seek_frame(this->fmt_ctx, -1, pos, 0) >= 0) { return 0; } return -1; } static int demux_avformat_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { avformat_demux_plugin_t *this = (avformat_demux_plugin_t *) this_gen; if (avformat_seek(this, start_pos, start_time) < 0) { return this->status; } if (playing) { this->seek_flag = BUF_FLAG_SEEK; _x_demux_flush_engine(this->stream); } return this->status; } static void demux_avformat_dispose (demux_plugin_t *this_gen) { avformat_demux_plugin_t *this = (avformat_demux_plugin_t *) this_gen; _x_freep(&this->xine_buf_type); _x_freep(&this->audio_stream_idx); avformat_close_input(&this->fmt_ctx); free (this_gen); } /* * demux class */ static int pb_input_read_packet(void *opaque, uint8_t *buf, int buf_size) { input_plugin_t *input = (input_plugin_t *)opaque; int r = input->read (input, buf, buf_size); /* avoid eternal misunderstanding :-O */ if (r > 0) return r; if (r == 0) { #ifdef AVERROR_EOF return AVERROR_EOF; #else return 0; #endif } return AVERROR (errno); } static int64_t pb_input_seek(void *opaque, int64_t offset, int whence) { input_plugin_t *input = (input_plugin_t *)opaque; int64_t r; if (whence == AVSEEK_SIZE) { off_t len = input->get_length(input); if (len > 0) return len; return -1; } r = input->seek (input, offset, whence); if (r >= 0) return r; return AVERROR (errno); } static AVIOContext *get_io_context(xine_stream_t *stream, input_plugin_t *input) { AVIOContext *pb = NULL; if (!strcmp(input->input_class->identifier, INPUT_AVIO_ID)) { /* get AVIOContext from avio input plugin */ if (input->get_optional_data(input, &pb, INPUT_OPTIONAL_DATA_pb) != INPUT_OPTIONAL_SUCCESS || !pb) { xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": could not get AVIOContext from input plugin\n"); return NULL; } xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": got AVIOContext from input plugin\n"); } else { /* create AVIO wrapper for native input plugin */ xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": creating AVIOContext wrapper for input plugin\n"); pb = avio_alloc_context(av_malloc(4096), 4096, 0/*write_flag*/, input, pb_input_read_packet, NULL, pb_input_seek); if (input->get_capabilities(input) & INPUT_CAP_SEEKABLE) pb->seekable = AVIO_SEEKABLE_NORMAL; else pb->seekable = 0; } avio_seek(pb, 0, SEEK_SET); return pb; } static AVFormatContext *get_format_context(xine_stream_t *stream, input_plugin_t *input) { AVFormatContext *fmt_ctx = NULL; if (!strcmp(input->input_class->identifier, DEMUX_AVFORMAT_ID)) { /* get AVFormatContext from input plugin */ if (input->get_optional_data(input, &fmt_ctx, INPUT_OPTIONAL_DATA_fmt_ctx) != INPUT_OPTIONAL_SUCCESS || !fmt_ctx) { xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": could not get AVFormatContext from input plugin\n"); return NULL; } xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": got AVFormtContext from input plugin\n"); } else { /* create and open AVFormatContext */ AVIOContext *pb = get_io_context(stream, input); if (!pb) { return NULL; } fmt_ctx = avformat_alloc_context(); fmt_ctx->pb = pb; if (avformat_open_input(&fmt_ctx, input->get_mrl(input), NULL, NULL) < 0) { xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": could not open AVFormatContext for source '%s'\n", input->get_mrl(input)); return NULL; } } return fmt_ctx; } /* * demux class interface */ static demux_plugin_t *open_demux_avformat_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { init_once_routine(); /* get AVFormatContext */ AVFormatContext *fmt_ctx = get_format_context(stream, input); if (!fmt_ctx) { return NULL; } /* retrieve stream information */ if (avformat_find_stream_info(fmt_ctx, NULL) < 0) { xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": could not find stream information\n"); avformat_close_input(&fmt_ctx); return NULL; } /* dump input information to stderr */ av_dump_format(fmt_ctx, 0, input->get_mrl(input), 0); /* initialize xine demuxer */ avformat_demux_plugin_t *this; this = calloc(1, sizeof(avformat_demux_plugin_t)); if (!this) { avformat_close_input(&fmt_ctx); return NULL; } this->stream = stream; this->demux_plugin.send_headers = demux_avformat_send_headers; this->demux_plugin.send_chunk = demux_avformat_send_chunk; this->demux_plugin.seek = demux_avformat_seek; this->demux_plugin.dispose = demux_avformat_dispose; this->demux_plugin.get_status = demux_avformat_get_status; this->demux_plugin.get_stream_length = demux_avformat_get_stream_length; this->demux_plugin.get_capabilities = demux_avformat_get_capabilities; this->demux_plugin.get_optional_data = demux_avformat_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; this->fmt_ctx = fmt_ctx; this->num_video_frames = 0; /* check if the stream can be played */ if (!find_avformat_streams(this)) { xprintf (stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": could not find any playable streams\n"); demux_avformat_dispose(&this->demux_plugin); return NULL; } return &this->demux_plugin; } void *init_avformat_demux_plugin (xine_t *xine, const void *data) { static const demux_class_t this = { .open_plugin = open_demux_avformat_plugin, .description = N_("libavformat demux plugin"), .identifier = DEMUX_AVFORMAT_ID, .mimetypes = NULL, .extensions = "", .dispose = NULL }; (void)xine; (void)data; return (demux_class_t *)&this; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/ffmpeg_compat.h����������������������������������������������������0000644�0001750�0001750�00000026275�14647725152�017473� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Compability macros for various ffmpeg versions */ #ifndef XINE_AVCODEC_COMPAT_H #define XINE_AVCODEC_COMPAT_H #define XFF_INT_VERSION(major,minor,micro) ((major<<16)|(minor<<8)|micro) /** NOTE: since 2022-09-01, ffmpeg headers are more detached from each other. * this goes that far: * libavformat/avformat.h includes libavcodec/packet.h which uses * (but not includes) libavutil/avutil.h :-/ */ #if !defined(LIBAVUTIL_VERSION_INT) && defined(LIBAVUTIL_VERSION_MAJOR) && defined(LIBAVUTIL_VERSION_MINOR) # define LIBAVUTIL_VERSION_INT XFF_INT_VERSION(LIBAVUTIL_VERSION_MAJOR,LIBAVUTIL_VERSION_MINOR,0) #endif #if !defined(LIBAVUTIL_VERSION_INT) # error avutil.h must be included first ! #endif #if !defined(LIBAVCODEC_VERSION_INT) && defined(LIBAVCODEC_VERSION_MAJOR) && defined(LIBAVCODEC_VERSION_MINOR) # define LIBAVCODEC_VERSION_INT XFF_INT_VERSION(LIBAVCODEC_VERSION_MAJOR,LIBAVCODEC_VERSION_MINOR,0) #endif #if defined(LIBAVCODEC_VERSION_INT) #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(52,0,0) # define bits_per_sample bits_per_coded_sample #endif #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(52,32,0) #else # define pp_context pp_context_t # define pp_mode pp_mode_t #endif /* reordered_opaque appeared in libavcodec 51.68.0 */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(51,68,0) && LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(60,0,0) # define XFF_AVCODEC_REORDERED_OPAQUE #else # undef XFF_AVCODEC_REORDERED_OPAQUE #endif #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(58,33,100) # define XFF_AVCODEC_FRAME_PTS #else # undef XFF_AVCODEC_FRAME_PTS #endif /* colorspace and color_range were added before 52.29.0 */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(52,29,0) # define XFF_AVCODEC_COLORSPACE #endif /* "unused" as of v54 */ #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(54,0,0) # define XFF_AVCODEC_SUB_ID #endif /* not 100% sure about this (between 55.19 and 56.56) */ #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(56,0,0) # define XFF_AVCODEC_STREAM_CODEC_TAG #endif /* avcodec_thread_init() */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(52,112,0) # define DEPRECATED_AVCODEC_THREAD_INIT 1 #endif /* av_parser_parse() */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(52,94,0) # define XFF_PARSE 2 #else # define XFF_PARSE 1 #endif /* avcodec_decode_video* (), avcodec_send_packet (), avcodec_receive_frame () */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(57,106,102) # define XFF_VIDEO 3 #elif LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(52,32,0) # define XFF_VIDEO 2 #else # define XFF_VIDEO 1 #endif /* avcodec_decode_audio* (), avcodec_send_packet (), avcodec_receive_frame () */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(57,106,102) # define XFF_AUDIO 5 #elif LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(54,0,0) # define XFF_AUDIO 4 #elif LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(52,32,0) # define XFF_AUDIO 3 #else # define XFF_AUDIO 2 #endif /* avcodec_encode_video(), av_packet_unref, avcodec_send_frame (), avcodec_receive_packet () */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(57,106,102) # define XFF_ENCVIDEO 3 #elif LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(55,25,100) # define XFF_ENCVIDEO 2 #else # define XFF_ENCVIDEO 1 #endif /* AVFrame.age not sure about this - original condition was broken */ #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(53,28,1) && LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(54,0,0) # define XFF_FRAME_AGE 1 #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(53,0,0) /* release 0.7.x (libavcodec 52) has deprecated AVCodecContext.palctrl but for backwards compatibility no working alternative. */ # define XFF_PALETTE 1 #elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(54,92,100) /* pass palette as AVPacket side data, free with av_destruct_packet () after NULLing main data pointer */ # define XFF_PALETTE 2 #else /* dito, free with av_free_packet () after NULLing main data pointer */ # define XFF_PALETTE 3 #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,42,100) /* AVCodecContext.slice_{offset,count} */ # define XFF_AVCODEC_SLICE_TABLE 1 #else /* inline offset table before the frame. */ # define XFF_AVCODEC_SLICE_TABLE 2 #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,0,100) /** << revise this */ # define XFF_VAAPI 1 /** << libavcodec/vaapi.h */ #else # define XFF_VAAPI 2 /** << libavutil/hwcontext.h, libavutil/hwcontext_vaapi.h */ #endif #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(54,25,0) /* dxr3/ffmpeg_encoder */ # define CODEC_ID_MPEG1VIDEO AV_CODEC_ID_MPEG1VIDEO /* video_out/video_out_vaapi */ # define CODEC_ID_MPEG2VIDEO AV_CODEC_ID_MPEG2VIDEO # define CODEC_ID_MPEG4 AV_CODEC_ID_MPEG4 # define CODEC_ID_H263 AV_CODEC_ID_H263 # define CODEC_ID_H264 AV_CODEC_ID_H264 # define CODEC_ID_WMV3 AV_CODEC_ID_WMV3 /* video_out/video_out_vaapi, ff_video_decoder */ # define CODEC_ID_VC1 AV_CODEC_ID_VC1 /* ff_video_decoder */ # define CODEC_ID_SVQ3 AV_CODEC_ID_SVQ3 # define CODEC_ID_MSMPEG4V1 AV_CODEC_ID_MSMPEG4V1 # define CODEC_ID_MSMPEG4V2 AV_CODEC_ID_MSMPEG4V2 # define CODEC_ID_MSMPEG4V3 AV_CODEC_ID_MSMPEG4V3 # define CODEC_ID_WMV1 AV_CODEC_ID_WMV1 # define CODEC_ID_WMV2 AV_CODEC_ID_WMV2 /* demux_avformat */ # define CODEC_ID_PCM_S16LE AV_CODEC_ID_PCM_S16LE # define CODEC_ID_PCM_S16BE AV_CODEC_ID_PCM_S16BE # define CODEC_ID_MP2 AV_CODEC_ID_MP2 # define CODEC_ID_AC3 AV_CODEC_ID_AC3 /* ff_*_decoder mapping is already handled by mkcodeclists.pl */ #endif #if LIBAVCODEC_VERSION_INT >= XFF_INT_VERSION(55,0,100) # define XFF_AV_BUFFER 1 #endif /* 0 (no), 1 (yes), 2 (deprecated but still needed to make direct rendering work) */ #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(55,0,100) # define XFF_THREAD_SAFE_CB 0 #elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,0,100) # define XFF_THREAD_SAFE_CB 1 #elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(60,0,0) # define XFF_THREAD_SAFE_CB 2 #else /* now callbacks shall always be thread safe. */ # define XFF_THREAD_SAFE_CB 0 #endif /* function aliases */ #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(52,66,0) # define XFF_EDGE_WIDTH() (16) #elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(55,48,102) # define XFF_EDGE_WIDTH() avcodec_get_edge_width() #else /* edges not needed anymore supposedly */ # define XFF_EDGE_WIDTH() (0) #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(53,8,0) # define XFF_AVCODEC_INIT() avcodec_init() #else # define XFF_AVCODEC_INIT() do {} while(0) #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(53,6,0) # define XFF_ALLOC_CONTEXT() avcodec_alloc_context() #else # define XFF_ALLOC_CONTEXT() avcodec_alloc_context3(NULL) #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(53,6,0) # define XFF_AVCODEC_OPEN(ctx,codec) avcodec_open(ctx,codec) #else # define XFF_AVCODEC_OPEN(ctx,codec) avcodec_open2(ctx, codec, NULL) #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(55,63,100) # define XFF_FREE_CONTEXT(pp) do {if (pp) avcodec_close (pp); av_free (pp); pp = NULL;} while (0) #elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(58,33,100) # define XFF_FREE_CONTEXT(pp) do {if (pp) avcodec_close (pp); avcodec_free_context (&(pp));} while (0) #else # define XFF_FREE_CONTEXT(pp) avcodec_free_context (&(pp)) #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(54,59,100) # define XFF_ALLOC_FRAME() avcodec_alloc_frame() # define XFF_FREE_FRAME(pp) do {av_free(pp); pp = NULL;} while (0) #elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(55,45,101) # define XFF_ALLOC_FRAME() avcodec_alloc_frame() # define XFF_FREE_FRAME(pp) avcodec_free_frame(&(pp)) #else # define XFF_ALLOC_FRAME() av_frame_alloc() # define XFF_FREE_FRAME(pp) av_frame_free(&(pp)) #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(57,12,100) # define XFF_PACKET_DECL(_p) AVPacket _p##_stat, *_p # define XFF_PACKET_NEW(_p) _p = &_p##_stat, av_init_packet (_p) # define XFF_PACKET_UNREF(_p) av_free_packet (_p) #elif LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,0,100) /** << revise this */ # define XFF_PACKET_DECL(_p) AVPacket _p##_stat, *_p # define XFF_PACKET_NEW(_p) _p = &_p##_stat, av_init_packet (_p) # define XFF_PACKET_UNREF(_p) av_packet_unref (_p) #else # define XFF_PACKET_DECL(_p) AVPacket *_p # define XFF_PACKET_NEW(_p) _p = av_packet_alloc () # define XFF_PACKET_UNREF(_p) av_packet_free (&(_p)) #endif #ifndef AV_INPUT_BUFFER_PADDING_SIZE # define AV_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE #endif #ifndef AV_CODEC_CAP_DR1 # define AV_CODEC_CAP_DR1 CODEC_CAP_DR1 #endif #ifndef AV_CODEC_FLAG2_FAST # define AV_CODEC_FLAG2_FAST CODEC_FLAG2_FAST #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(58,10,100) # define XFF_AVCODEC_REGISTER_ALL() avcodec_register_all() #else # define XFF_AVCODEC_REGISTER_ALL() do {} while(0) #endif #if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,24,100) # define XFF_AUDIO_CHANNEL_LAYOUT 1 /* AVCodecContext.channels, .channel_leyout */ #else # define XFF_AUDIO_CHANNEL_LAYOUT 2 /* AVCodecContext.ch_layout.nb_channels, .ch_layout.u.mask */ #endif #ifndef AVCODEC_MAX_AUDIO_FRAME_SIZE # define AVCODEC_MAX_AUDIO_FRAME_SIZE 192000 #endif #if LIBAVUTIL_VERSION_INT >= XFF_INT_VERSION(52,0,0) # define PIX_FMT_NONE AV_PIX_FMT_NONE # define PIX_FMT_YUV420P AV_PIX_FMT_YUV420P # define PIX_FMT_YUVJ420P AV_PIX_FMT_YUVJ420P # define PIX_FMT_YUV444P AV_PIX_FMT_YUV444P # define PIX_FMT_YUVJ444P AV_PIX_FMT_YUVJ444P # define PIX_FMT_YUV410P AV_PIX_FMT_YUV410P # define PIX_FMT_YUV411P AV_PIX_FMT_YUV411P # define PIX_FMT_ARGB AV_PIX_FMT_ARGB # define PIX_FMT_BGRA AV_PIX_FMT_BGRA # define PIX_FMT_RGB24 AV_PIX_FMT_RGB24 # define PIX_FMT_BGR24 AV_PIX_FMT_BGR24 # define PIX_FMT_RGB555BE AV_PIX_FMT_RGB555BE # define PIX_FMT_RGB555LE AV_PIX_FMT_RGB555LE # define PIX_FMT_RGB565BE AV_PIX_FMT_RGB565BE # define PIX_FMT_RGB565LE AV_PIX_FMT_RGB565LE # define PIX_FMT_PAL8 AV_PIX_FMT_PAL8 # define PixelFormat AVPixelFormat /* video_out/video_out_vaapi */ # if LIBAVCODEC_VERSION_INT < XFF_INT_VERSION(59,0,100) /** << revise this */ # define PIX_FMT_VAAPI_VLD AV_PIX_FMT_VAAPI_VLD # define PIX_FMT_VAAPI_IDCT AV_PIX_FMT_VAAPI_IDCT # define PIX_FMT_VAAPI_MOCO AV_PIX_FMT_VAAPI_MOCO # else # define PIX_FMT_VAAPI_VLD AV_PIX_FMT_VAAPI # define PIX_FMT_VAAPI_IDCT AV_PIX_FMT_VAAPI # define PIX_FMT_VAAPI_MOCO AV_PIX_FMT_VAAPI # endif # define CODEC_FLAG_BITEXACT AV_CODEC_FLAG_BITEXACT #endif #else /* defined(LIBAVCODEC_VERSION_INT) */ # error avcodec.h must be included first ! #endif /* defined(LIBAVCODEC_VERSION_INT) */ #endif /* XINE_AVCODEC_COMPAT_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/mkcodeclist.pl�����������������������������������������������������0000755�0001750�0001750�00000005475�14647725152�017353� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#! /usr/bin/perl -w # Make codec lists for #inclusion by ff_*_decoder.c. # Parameters: # list of ffmpeg CODEC_ID_* (pre-processed, one per line) # list of codecs recognised by xine-lib (see list for details) # output file name, or "-" to generate a report on unhandled codecs my ($ffmpeg, $xine, $out) = @ARGV; my $line; # Read in the ffmpeg codec IDs my %codecs; open LIST, "< $ffmpeg" or die $!; $line = <LIST>; my $ff_prefix = 'CODEC_ID_'; if (substr ($line, 0, 12) eq 'AV_CODEC_ID_') { $ff_prefix = 'AV_CODEC_ID_'; } while (defined $line) { chomp $line; $line =~ s/^$ff_prefix|\s+$//g; $codecs{$line} = 0; $line = <LIST>; } close LIST or die $!; # Read in the xine-lib codec IDs my %config; my @known; my $type = 'audio'; # default type my $Type = 'AUDIO'; my ($a, $f, $t); open LIST, "< $xine" or die $!; while (defined ($line = <LIST>)) { next if substr ($line, 0, 1) eq '#' or $line =~ /^\s*$/o; chomp $line; if (substr ($line, 0, 5) eq 'type=') { # codec type; "FOO" in "BUF_FOO_BAR" $type = substr ($line, 5); $type =~ tr/A-Z/a-z/; $Type = $type; $Type =~ tr/a-z/A-Z/; } elsif (substr ($line, 0, 7) eq 'config=') { # avcodec minimum version mappings ($a, $f, $t) = split (/=/, $line, 3); $config{$f} = $t if $t =~ /^\d+,\d+,\d+$/ } else { # codec details push @known, [split (/\s+/, $line, 3)]; } } close LIST or die $!; # Look through the mappings. # Mark what we can handle and report on what the installed ffmpeg can't foreach $line (@known) { if (defined $codecs{$line->[1]}) { ++$codecs{$line->[1]}; } else { print "Ignored $line->[0] = $line->[1]\n"; } } my $w = ($out ne '-'); if ($w) { # Write the C source code for the codec lists open LIST, "> $out" or die $!; print LIST "#ifndef AV_VERSION_INT\n# define AV_VERSION_INT(a,b,c) 0x7FFFFFFF\n#endif\n" or die $!; print LIST "const ff_codec_t ff_${type}_lookup[] = {\n" or die $!; foreach $line (@known) { next if $line->[0] eq '!'; next unless defined $codecs{$line->[1]}; print LIST " { BUF_${Type}_$line->[0], $ff_prefix$line->[1], \"$line->[2] (ffmpeg)\" },\n" or die $!; } print LIST "};\n\nstatic const uint32_t supported_${type}_types[] = {\n" or die $!; foreach $line (@known) { next if $line->[0] eq '!'; next unless defined $codecs{$line->[1]}; $a = ''; $a = $config{$a} if defined $config{$a}; if ($a eq '') { print LIST " BUF_${Type}_$line->[0],\n" or die $!; } else { print LIST " #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT($a)\n BUF_${Type}_$line->[0],\n #endif\n" or die $!; } } print LIST " 0,\n};\n" or die $!; close LIST or die $!; } else { # Report on ffmpeg codecs which we don't handle print "Unhandled $type codecs:\n"; foreach $line (sort keys %codecs) { print " $line\n" if $codecs{$line} == 0; } } exit 0; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/Makefile.am��������������������������������������������������������0000644�0001750�0001750�00000006010�14647725152�016530� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_CPPFLAGS += $(ZLIB_CPPFLAGS) AM_LDFLAGS = $(xineplug_ldflags) # make clean should always work. ff_generated = avcodec_video.list avcodec_audio.list ff_video_list.h ff_audio_list.h DISTCLEANFILES = $(ff_generated) # make dist should get them all, even when ENABLE_FFMPEG is false. # XXX: why does automake need these here while foo_SOURCES et al are # recognized even within false conditionals? EXTRA_DIST = xine_video.list xine_audio.list mkcodeclist.pl noinst_HEADERS = ffmpeg_compat.h if ENABLE_FFMPEG BUILT_SOURCES = $(ff_generated) xineplug_LTLIBRARIES = xineplug_decode_ff.la xineplug_decode_ff_la_SOURCES = ffmpeg_decoder.c ff_audio_decoder.c ff_video_decoder.c \ ff_mpeg_parser.c ffmpeg_decoder.h ff_mpeg_parser.h nodist_xineplug_decode_ff_la_SOURCES = ffmpeg_config.h xineplug_decode_ff_la_CFLAGS = $(AM_CFLAGS) $(FFMPEG_CFLAGS) $(POSTPROC_CFLAGS) xineplug_decode_ff_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) -lm $(ZLIB_LIBS) \ $(FFMPEG_LIBS) $(AVUTIL_LIBS) $(POSTPROC_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_decode_ff_la_LDFLAGS = $(AM_LDFLAGS) $(IMPURE_TEXT_LDFLAGS) if ENABLE_AVFORMAT xineplug_decode_ff_la_SOURCES += input_avio.c demux_avformat.c xineplug_decode_ff_la_CFLAGS += $(AVFORMAT_CFLAGS) xineplug_decode_ff_la_LIBADD += $(AVFORMAT_LIBS) endif # Generation of ffmpeg->xine codec mapping lists (see xine_*.list). AV_CPP = $(CPP) $(DEFS) $(DEFAULT_INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AVUTIL_CFLAGS) # Extract some CODEC_ID_* from avcodec.h. Requires some sed mangling. avcodec_audio.list: AV_CODECS:=/CODEC_ID_PCM_S16LE/,/CODEC_ID_DVD_SUBTITLE/ avcodec_video.list: AV_CODECS:=/CODEC_ID_MPEG1VIDEO/,/CODEC_ID_PCM_S16LE/ # that weird shell call just yields full path of the avcodec.h file avcodec_audio.list avcodec_video.list: Makefile $(shell \ echo -e '#include "config.h"\n#ifdef HAVE_FFMPEG_AVUTIL_H\n#include <avcodec.h>\n#else\n#include <libavcodec/avcodec.h>\n#endif' | $(AV_CPP) -M - |\ sed -e '/avcodec\.h/! d; s%^.* \([^ ]*/avcodec\.h\) .*%\1%') $(AM_V_GEN)echo -e '#include "config.h"\n#ifdef HAVE_FFMPEG_AVUTIL_H\n#include <avcodec.h>\n#else\n#include <libavcodec/avcodec.h>\n#endif' | $(AV_CPP) - |\ sed -e $(AV_CODECS)'! d; s/^[ \t]*//; s/[=,].*//; /^$$/ d' >$@ # Generate the mappings. These are #included where needed. ff_audio_list.h: $(srcdir)/mkcodeclist.pl avcodec_audio.list $(srcdir)/xine_audio.list $(AM_V_GEN)$(PERL) $^ $@ ff_video_list.h: $(srcdir)/mkcodeclist.pl avcodec_video.list $(srcdir)/xine_video.list $(AM_V_GEN)$(PERL) $^ $@ ff_audio_decoder.c: ff_audio_list.h ff_video_decoder.c: ff_video_list.h # 'make report' prints tokens corresponding to any unhandled codecs. report: avcodec_audio.list avcodec_video.list @$(top_srcdir)/src/combined/ffmpeg/mkcodeclist.pl avcodec_audio.list xine_audio.list - audio @$(top_srcdir)/src/combined/ffmpeg/mkcodeclist.pl avcodec_video.list xine_video.list - video .PHONY: report endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/input_avio.c�������������������������������������������������������0000644�0001750�0001750�00000023243�14647725152�017024� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2013-2022 the xine project * Copyright (C) 2013-2020 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <pthread.h> #include <libavutil/avutil.h> #include <libavcodec/avcodec.h> #include <libavformat/avio.h> #define LOG_MODULE "libavio" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/input_plugin.h> #include "ffmpeg_decoder.h" /* * avio input plugin */ typedef struct { input_plugin_t input_plugin; xine_stream_t *stream; char *mrl; /* 'public' mrl without authentication credentials */ char *mrl_private; /* 'private' mrl with authentication credentials */ AVIOContext *pb; off_t curpos; /* preview support */ size_t preview_size; char preview[MAX_PREVIEW_SIZE]; } avio_input_plugin_t; static off_t input_avio_read (input_plugin_t *this_gen, void *buf_gen, off_t len) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; char *buf = (char *)buf_gen; off_t total = 0; if (len < 0) return -1; if (this->curpos < (off_t)this->preview_size) { off_t n = this->preview_size - this->curpos; if (n > len) n = len; memcpy (buf, &this->preview[this->curpos], n); this->curpos += n; total += n; len -= n; } if (len > 0 && this->pb) { off_t n = avio_read(this->pb, buf + total, len); if (n < 0) { return n; } this->curpos += n; total += n; } return total; } static buf_element_t *input_avio_read_block (input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { (void)this_gen; (void)fifo; (void)todo; return NULL; } static off_t input_avio_get_length (input_plugin_t *this_gen) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; if (this->pb) { return avio_size(this->pb); } return -1; } static uint32_t input_avio_get_capabilities (input_plugin_t *this_gen) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; if (this->pb && this->pb->seekable) { return INPUT_CAP_SEEKABLE | INPUT_CAP_PREVIEW; } return INPUT_CAP_PREVIEW; } static off_t input_avio_seek_time (input_plugin_t *this_gen, int time_offset, int origin) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; if (origin == SEEK_SET && this->pb && this->pb->seekable) { int64_t ts = (int64_t)time_offset * AV_TIME_BASE / 1000; off_t result = avio_seek_time(this->pb, -1, ts, 0); if (result >= 0) { this->preview_size = 0; this->curpos = result; return this->curpos; } } return -1; } static uint32_t input_avio_get_blocksize (input_plugin_t *this_gen) { (void)this_gen; return 0; } static off_t input_avio_get_current_pos (input_plugin_t *this_gen) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; if (this->pb && this->curpos >= (off_t)this->preview_size) { this->curpos = avio_tell(this->pb); } return this->curpos; } static off_t input_avio_seek (input_plugin_t *this_gen, off_t offset, int origin) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; off_t size; off_t newpos; if (!this->pb || !this->pb->seekable) { return -1; } /* convert relative seeks to absolute */ switch (origin) { case SEEK_SET: break; case SEEK_CUR: offset += this->curpos; break; case SEEK_END: size = avio_size(this->pb); if (size < 1) { return -1; } offset = size + offset; if (offset < 0) offset = 0; if (offset > size) offset = size; break; } /* seek, take care of preview buffer */ newpos = offset; if (offset < (off_t)this->preview_size) { offset = this->preview_size; } if (offset != avio_seek(this->pb, offset, SEEK_SET)) { return -1; } this->curpos = newpos; return this->curpos; } static const char* input_avio_get_mrl (input_plugin_t *this_gen) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; return this->mrl; } static int input_avio_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: memcpy (data, this->preview, this->preview_size); return this->preview_size; case INPUT_OPTIONAL_DATA_pb: *((AVIOContext **)data) = this->pb; this->pb = NULL; return INPUT_OPTIONAL_SUCCESS; } return INPUT_OPTIONAL_UNSUPPORTED; } static int input_avio_open (input_plugin_t *this_gen) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; int toread = MAX_PREVIEW_SIZE; int trycount = 0; if (!this->pb) { /* try to open libavio protocol */ if (avio_open2(&this->pb, this->mrl_private, AVIO_FLAG_READ, NULL, NULL) < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": failed to open avio protocol for '%s'\n", this->mrl); _x_freep_wipe_string (&this->mrl_private); return 0; } xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": opened avio protocol for '%s'\n", this->mrl); } _x_freep_wipe_string (&this->mrl_private); while ((toread > 0) && (trycount < 10)) { off_t n = avio_read (this->pb, this->preview + this->preview_size, toread); if (n > 0) { this->preview_size += n; } trycount++; toread = MAX_PREVIEW_SIZE - this->preview_size; } return 1; } static void input_avio_dispose (input_plugin_t *this_gen ) { avio_input_plugin_t *this = (avio_input_plugin_t *) this_gen; avio_close(this->pb); _x_freep (&this->mrl); _x_freep_wipe_string (&this->mrl_private); free (this_gen); } /* * avio input class */ static int is_avio_supported_protocol(xine_t *xine, const char *mrl) { char *mrl_protocol = strdup(mrl); char *pt = strchr(mrl_protocol, ':'); int result = 0; if (pt) { const char *protocol; void *iter; *pt = 0; for (iter = NULL; NULL != (protocol = avio_enum_protocols(&iter, 0)); ) { if (!strcmp(mrl_protocol, protocol)) { xprintf (xine, XINE_VERBOSITY_LOG, LOG_MODULE": using avio protocol '%s' for '%s'\n", protocol, mrl); result = 1; } } } if (!result) { xprintf (xine, XINE_VERBOSITY_LOG, LOG_MODULE": no avio protocol for '%s'\n", mrl); } free(mrl_protocol); return result; } static input_plugin_t *input_avio_get_instance (input_class_t *cls_gen, xine_stream_t *stream, const char *mrl) { avio_input_plugin_t *this; const int proto_len = strlen(INPUT_AVIO_ID"+"); if (!mrl || !*mrl) { return NULL; } /* accept only mrls with protocol part */ if (!strchr(mrl, ':') || (strchr(mrl, '/') < strchr(mrl, ':'))) { return NULL; } init_once_routine(); /* always accept own protocol */ /* avio+http:// ... --> use avio instead of xine native http plugin */ if (!strncasecmp (mrl, INPUT_AVIO_ID"+", proto_len)) { mrl += proto_len; } if (!is_avio_supported_protocol(stream->xine, mrl)) { return NULL; } this = calloc(1, sizeof(avio_input_plugin_t)); if (!this) { return NULL; } this->stream = stream; this->mrl = _x_mrl_remove_auth(mrl); this->mrl_private = strdup(mrl); this->input_plugin.open = input_avio_open; this->input_plugin.get_capabilities = input_avio_get_capabilities; this->input_plugin.read = input_avio_read; this->input_plugin.read_block = input_avio_read_block; this->input_plugin.seek = input_avio_seek; this->input_plugin.seek_time = input_avio_seek_time; this->input_plugin.get_current_pos = input_avio_get_current_pos; this->input_plugin.get_length = input_avio_get_length; this->input_plugin.get_blocksize = input_avio_get_blocksize; this->input_plugin.get_mrl = input_avio_get_mrl; this->input_plugin.get_optional_data = input_avio_get_optional_data; this->input_plugin.dispose = input_avio_dispose; this->input_plugin.input_class = cls_gen; /* do not expose authentication credentials in title (if title is not set, it defaults to mrl in xine-ui) */ _x_meta_info_set(stream, XINE_META_INFO_TITLE, this->mrl); return &this->input_plugin; } void *init_avio_input_plugin (xine_t *xine, const void *data) { const char *protocol; void *iter; static const input_class_t this = { .get_instance = input_avio_get_instance, .description = N_("libavio input plugin"), .identifier = INPUT_AVIO_ID, .get_dir = NULL, .get_autoplay_list = NULL, .dispose = NULL, .eject_media = NULL }; (void)data; for (iter = NULL; NULL != (protocol = avio_enum_protocols(&iter, 0)); ) { xprintf (xine, XINE_VERBOSITY_DEBUG, LOG_MODULE": found avio protocol '%s'\n", protocol); } return (input_class_t *)&this; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/ff_audio_decoder.c�������������������������������������������������0000644�0001750�0001750�00000145705�14647725152�020120� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine audio decoder plugin using ffmpeg */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <inttypes.h> #include <string.h> #include <pthread.h> #include <math.h> #if defined(HAVE_LIBAVUTIL_AVUTIL_H) # include <libavutil/avutil.h> #endif #if defined(HAVE_LIBAVUTIL_MEM_H) # include <libavutil/mem.h> #endif #if defined(HAVE_AVUTIL_AVCODEC_H) # include <libavcodec/avcodec.h> #else # include <avcodec.h> #endif #define LOG_MODULE "ffmpeg_audio_dec" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" #include "ffmpeg_decoder.h" #include "ffmpeg_compat.h" #define AUDIOBUFSIZE (64 * 1024) #define MAX_CHANNELS 6 typedef struct { audio_decoder_class_t decoder_class; xine_t *xine; float gain; int bitexact; } ff_audio_class_t; typedef struct ff_audio_decoder_s { audio_decoder_t audio_decoder; ff_audio_class_t *class; xine_stream_t *stream; unsigned char *buf; int bufsize; int size; AVCodecContext *context; const AVCodec *codec; struct { uint8_t *buf; size_t len; } parse, decode, send; char *decode_buffer; int decoder_ok; int pkt_sent; AVCodecParserContext *parser_context; xine_pts_queue_t *pts_queue; #if XFF_AUDIO > 3 AVFrame *av_frame; #endif #if XFF_AUDIO > 2 XFF_PACKET_DECL (avpkt); #endif /* AAC ADTS */ uint32_t buftype; #define AAC_MODE_PROBE -8 #define AAC_MODE_OFF 0 #define AAC_MODE_RAW 1 #define AAC_MODE_ADTS 2 int aac_mode; /* decoder settings */ int ff_channels; int ff_bits; int ff_sample_rate; uint64_t ff_map; /* channel mixer settings */ /* map[ao_channel] = ff_channel */ int8_t map[MAX_CHANNELS]; int8_t left[4], right[4]; /* how many left[] / right[] entries are in use */ int front_mixes; /* volume adjustment */ int downmix_shift; /* audio out settings */ int output_open; int ao_channels; int new_mode; int ao_mode; int ao_caps; } ff_audio_decoder_t; static void ff_aac_mode_set (ff_audio_decoder_t *this, int reset) { if ((this->buftype == BUF_AUDIO_AAC) || (this->buftype == BUF_AUDIO_AAC_LATM)) { if (reset) { this->aac_mode = AAC_MODE_PROBE; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: looking for possible AAC ADTS syncwords...\n"); } if ((this->aac_mode < 0) || (this->aac_mode == AAC_MODE_ADTS)) { if (this->context->extradata_size) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: AAC raw mode with global header\n"); this->aac_mode = AAC_MODE_RAW; } } } else { this->aac_mode = AAC_MODE_OFF; } } static int ff_audio_open_codec (ff_audio_decoder_t *this, unsigned int codec_type); /* return -1 (need more data), 0 (no parsing done), > 0 (offset + size of found frame) */ static int ff_aac_mode_parse (ff_audio_decoder_t *this, uint8_t *buf, int size, int *offs) { int i; uint32_t v; *offs = 0; if (this->aac_mode < 0) { /* probe */ v = 0; for (i = 0; i < size; i++) { v <<= 8; v |= buf[i]; /* also test the "layer" bits for 0 (mpeg layer 4 audio). */ /* dont get fooled by 0xff padding bytes. */ if ((v & 0xfff6) == 0xfff0) { int s; /* test header size */ if (size - i < 7 - 1) continue; /* read frame size */ s = (_X_BE_32 (buf + i + 2) >> 13) & 0x1fff; if (s < 7) continue; /* test for next ADTS frame following */ if (size - i < s + 7 - 1) continue; if ((((buf[i + s - 1] << 8) | buf[i + s]) & 0xfff6) != 0xfff0) continue; *offs = --i; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: found AAC ADTS syncword after %d bytes\n", i); if (this->buftype == BUF_AUDIO_AAC_LATM) { uint8_t *ed = NULL; int es = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: stream says LATM but is ADTS -> switching decoders\n"); pthread_mutex_lock (&ffmpeg_lock); if (this->context) { ed = this->context->extradata; es = this->context->extradata_size; this->context->extradata = NULL; this->context->extradata_size = 0; XFF_FREE_CONTEXT (this->context); } this->decoder_ok = 0; this->context = XFF_ALLOC_CONTEXT (); if (this->context) { this->context->extradata = ed; this->context->extradata_size = es; } pthread_mutex_unlock (&ffmpeg_lock); this->codec = NULL; ff_audio_open_codec (this, BUF_AUDIO_AAC); } this->aac_mode = AAC_MODE_ADTS - 1; break; } } this->aac_mode++; if (this->aac_mode < 0) { if (size >= 2 * 0x1fff) this->aac_mode = AAC_MODE_OFF; else return -1; } if (this->aac_mode == AAC_MODE_OFF) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: no ADTS frames found\n"); } if (this->aac_mode == AAC_MODE_ADTS) { v = 0; for (i = *offs; i < size; i++) { v <<= 8; v |= buf[i]; if ((v & 0xfff6) == 0xfff0) { int s; /* test header size */ if (size - i < 7 - 1) return -1; /* read frame size */ s = (_X_BE_32 (buf + i + 2) >> 13) & 0x1fff; if (s < 7) continue; *offs = --i; if (size - i < s) return -1; return i + s; } } return -1; } return 0; } static void ff_audio_ensure_buffer_size(ff_audio_decoder_t *this, int size) { if (size > this->bufsize) { this->bufsize = size + size / 2; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: increasing buffer to %d to avoid overflow.\n"), this->bufsize); this->buf = xine_realloc_aligned (this->buf, this->bufsize + AV_INPUT_BUFFER_PADDING_SIZE); } } static void ff_audio_handle_special_buffer(ff_audio_decoder_t *this, buf_element_t *buf) { /* prefer plain global headers */ if (((buf->decoder_info[1] == BUF_SPECIAL_STSD_ATOM) && !this->context->extradata) || (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG)) { free (this->context->extradata); this->context->extradata_size = buf->decoder_info[2]; this->context->extradata = malloc (buf->decoder_info[2] + AV_INPUT_BUFFER_PADDING_SIZE); memcpy (this->context->extradata, buf->decoder_info_ptr[2], buf->decoder_info[2]); memset (this->context->extradata + buf->decoder_info[2], 0, AV_INPUT_BUFFER_PADDING_SIZE); ff_aac_mode_set (this, 0); } } static void ff_audio_init_codec(ff_audio_decoder_t *this, unsigned int codec_type) { size_t i; this->codec = NULL; for (i = 0; i < ff_audio_lookup_entries; i++) if(ff_audio_lookup[i].type == codec_type) { this->buftype = codec_type; ff_aac_mode_set (this, 1); pthread_mutex_lock (&ffmpeg_lock); this->codec = avcodec_find_decoder(ff_audio_lookup[i].id); pthread_mutex_unlock (&ffmpeg_lock); _x_meta_info_set(this->stream, XINE_META_INFO_AUDIOCODEC, ff_audio_lookup[i].name); break; } if (!this->codec) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: couldn't find ffmpeg decoder for buf type 0x%X\n"), codec_type); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return; } #if XFF_AUDIO < 4 /* Try to make the following true */ this->context->request_sample_fmt = AV_SAMPLE_FMT_S16; /* For lavc v54+, we have our channel mixer that wants default float samples to fix oversaturation via audio gain. */ #endif /* Current ffmpeg audio decoders usually use 16 bits/sample * buf->decoder_info[2] can't be used as it doesn't refer to the output * bits/sample for some codecs (e.g. MS ADPCM) */ this->ff_bits = 16; this->context->bits_per_sample = this->ff_bits; this->context->sample_rate = this->ff_sample_rate; #if XFF_AUDIO_CHANNEL_LAYOUT < 2 this->context->channels = this->ff_channels; #else this->context->ch_layout.nb_channels = this->ff_channels; #endif this->context->codec_id = this->codec->id; this->context->codec_type = this->codec->type; this->context->codec_tag = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC); /* Use parser for EAC3, AAC LATM, and MPEG. * Fixes: * - DVB streams where multiple AAC LATM frames are packed to single PES * - DVB streams where MPEG audio frames do not follow PES packet boundaries */ #if XFF_PARSE > 1 if (codec_type == BUF_AUDIO_AAC_LATM || codec_type == BUF_AUDIO_EAC3 || codec_type == BUF_AUDIO_A52 || codec_type == BUF_AUDIO_MPEG || codec_type == BUF_AUDIO_COOK) { this->parser_context = av_parser_init (this->codec->id); if (this->parser_context) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: using parser\n"); } else { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_audio_dec: couldn't init parser\n"); } } #endif } static int ff_audio_open_codec(ff_audio_decoder_t *this, unsigned int codec_type) { if ( !this->codec ) { ff_audio_init_codec(this, codec_type); } if ( !this->codec ) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: trying to open null codec\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return -1; } if (this->class->bitexact) this->context->flags |= CODEC_FLAG_BITEXACT; else this->context->flags &= ~CODEC_FLAG_BITEXACT; pthread_mutex_lock (&ffmpeg_lock); if (XFF_AVCODEC_OPEN (this->context, this->codec) < 0) { pthread_mutex_unlock (&ffmpeg_lock); xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: couldn't open decoder\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return -1; } pthread_mutex_unlock (&ffmpeg_lock); this->decoder_ok = 1; xine_pts_queue_reset (this->pts_queue); return 1; } static void ff_handle_header_buffer(ff_audio_decoder_t *this, buf_element_t *buf) { unsigned int codec_type = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); xine_waveformatex *audio_header; /* accumulate init data */ ff_audio_ensure_buffer_size(this, this->size + buf->size); xine_fast_memcpy(this->buf + this->size, buf->content, buf->size); this->size += buf->size; if (!(buf->decoder_flags & BUF_FLAG_FRAME_END)) { return; } if(buf->decoder_flags & BUF_FLAG_STDHEADER) { this->ff_sample_rate = buf->decoder_info[1]; this->ff_channels = buf->decoder_info[3]; if(this->size) { audio_header = (xine_waveformatex *)this->buf; this->context->block_align = audio_header->nBlockAlign; this->context->bit_rate = audio_header->nAvgBytesPerSec * 8; if(audio_header->cbSize > 0) { this->context->extradata = malloc(audio_header->cbSize); this->context->extradata_size = audio_header->cbSize; memcpy( this->context->extradata, (uint8_t *)audio_header + sizeof(xine_waveformatex), audio_header->cbSize ); } } } else { switch (codec_type) { case BUF_AUDIO_14_4: this->ff_sample_rate = 8000; this->ff_channels = 1; this->context->block_align = 240; break; case BUF_AUDIO_28_8: { uint16_t *ptr; this->ff_sample_rate = _X_BE_16 (&this->buf[0x30]); this->ff_channels = this->buf[0x37]; /* this->ff_bits = buf->content[0x35] */ this->context->block_align = _X_BE_32 (&this->buf[0x18]); this->context->extradata_size = 5 * sizeof (uint16_t); this->context->extradata = malloc (this->context->extradata_size); ptr = (uint16_t *)this->context->extradata; ptr[0] = _X_BE_16 (&this->buf[0x2C]); /* subpacket size */ ptr[1] = _X_BE_16 (&this->buf[0x28]); /* subpacket height */ ptr[2] = _X_BE_16 (&this->buf[0x16]); /* subpacket flavour */ ptr[3] = _X_BE_32 (&this->buf[0x18]); /* coded frame size */ ptr[4] = 0; /* codec's data length */ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: 28_8 audio channels %d bits %d sample rate %d block align %d\n", this->ff_channels, this->ff_bits, this->ff_sample_rate, this->context->block_align); break; } case BUF_AUDIO_COOK: case BUF_AUDIO_ATRK: { int version, subpacket_size = 0, coded_frame_size = 0, intl = 0; int data_len; uint8_t *p, *e; p = this->buf; e = p + this->size; if (p + 6 > e) break; version = p[5]; if (version == 3) { this->ff_sample_rate = 8000; this->ff_bits = 16; this->ff_channels = 1; data_len = 0; } else if (version == 4) { if (p + 73 > e) break; coded_frame_size = _X_BE_32 (p + 24); subpacket_size = _X_BE_16 (p + 44); this->ff_sample_rate = _X_BE_16 (p + 48); this->ff_bits = _X_BE_16 (p + 52); this->ff_channels = _X_BE_16 (p + 54); if (p[56] != 4) break; intl = 57; if (p[61] != 4) break; data_len = _X_BE_32 (p + 69); p += 73; } else { if (p + 78 > e) break; coded_frame_size = _X_BE_32 (p + 24); subpacket_size = _X_BE_16 (p + 44); this->ff_sample_rate = _X_BE_16 (p + 54); this->ff_bits = _X_BE_16 (p + 58); this->ff_channels = _X_BE_16 (p + 60); intl = 62; data_len = _X_BE_32 (p + 74); p += 78; } this->context->block_align = intl && !memcmp (this->buf + intl, "genr", 4) ? subpacket_size : coded_frame_size; if (p + data_len > e) break; if (p > e - data_len) break; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: %s audio channels %d bits %d sample rate %d block align %d\n", codec_type == BUF_AUDIO_COOK ? "cook" : "atrac 3", this->ff_channels, this->ff_bits, this->ff_sample_rate, this->context->block_align); if (!data_len) break; e = malloc (data_len + AV_INPUT_BUFFER_PADDING_SIZE); if (!e) break; xine_fast_memcpy (e, p, data_len); memset (e + data_len, 0, AV_INPUT_BUFFER_PADDING_SIZE); this->context->extradata = e; this->context->extradata_size = data_len; break; } case BUF_AUDIO_EAC3: break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_audio_dec: unknown header with buf type 0x%X\n", codec_type); break; } } ff_audio_init_codec(this, codec_type); this->size = 0; } static void ff_audio_reset_parser(ff_audio_decoder_t *this) { /* reset parser */ if (this->parser_context) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: resetting parser\n"); pthread_mutex_lock (&ffmpeg_lock); av_parser_close(this->parser_context); this->parser_context = av_parser_init(this->codec->id); pthread_mutex_unlock (&ffmpeg_lock); } } static void ff_audio_output_close(ff_audio_decoder_t *this) { if (this->output_open) { this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; } this->ff_sample_rate = 0; this->ao_mode = 0; } static unsigned int ff_list_channels (uint8_t *list, uint64_t map) { unsigned int n, bit; for (n = bit = 0; map; map >>= 1, bit++) { uint32_t b = map & 1; list[n] = bit; n += b; } return n; } static void ff_map_channels (ff_audio_decoder_t *this) { uint64_t ff_map; uint8_t ff_list[64]; unsigned int ff_num; const char *type = "native"; int caps = this->stream->audio_out->get_capabilities (this->stream->audio_out); #if XFF_AUDIO_CHANNEL_LAYOUT < 2 /* safety kludge for very old libavcodec */ # ifdef AV_CH_FRONT_LEFT ff_map = this->context->channel_layout; if (!ff_map) /* wma2 bug */ # endif ff_map = ((uint64_t)1 << this->context->channels) - 1; ff_num = ff_list_channels (ff_list, ff_map); #else /* XFF_AUDIO_CHANNEL_LAYOUT == 2 */ ff_num = this->context->ch_layout.nb_channels; if (ff_num > (int)(sizeof (ff_list) / sizeof (ff_list[0]))) ff_num = sizeof (ff_list) / sizeof (ff_list[0]); switch (this->context->ch_layout.order) { const AVChannelCustom *cmap; unsigned int i; case AV_CHANNEL_ORDER_UNSPEC: type = "unknown"; goto _fallback; case AV_CHANNEL_ORDER_NATIVE: ff_map = this->context->ch_layout.u.mask; if (!ff_map) /* wma2 bug */ ff_map = ((uint64_t)1 << ff_num) - 1; ff_num = ff_list_channels (ff_list, ff_map); break; case AV_CHANNEL_ORDER_CUSTOM: type = "custom"; if (!(cmap = this->context->ch_layout.u.map)) goto _fallback; ff_map = 0; for (i = 0; i < ff_num; i++) { ff_list[i] = cmap[i].id; ff_map |= (uint64_t)1 << ff_list[i]; } break; default: type = "unsupported"; /* fall through */ _fallback: ff_map = ((uint64_t)1 << ff_num) - 1; ff_num = ff_list_channels (ff_list, ff_map); } #endif if ((caps != this->ao_caps) || (ff_map != this->ff_map)) { unsigned int i, j; /* ff: see names[] below; xine: L R RL RR C LFE */ const int8_t base_map[] = {0, 1, 4, 5, 2, 3, -1, -1, -1, 2, 3}; int8_t name_map[MAX_CHANNELS] = {0, 0, 0, 0, 0, 0}; const int modes[] = { AO_CAP_MODE_MONO, AO_CAP_MODE_STEREO, AO_CAP_MODE_4CHANNEL, AO_CAP_MODE_4_1CHANNEL, AO_CAP_MODE_5CHANNEL, AO_CAP_MODE_5_1CHANNEL }; const unsigned int num_modes = sizeof (modes) / sizeof (modes[0]); const int8_t mode_channels[] = {1, 2, 4, 6, 6, 6}; const int8_t wishlist[] = { 0, 1, 2, 3, 4, 5, /* mono */ 1, 2, 3, 4, 5, 0, /* stereo */ 5, 4, 3, 2, 1, 0, /* center + lfe */ 4, 5, 2, 3, 1, 0, /* center */ 3, 5, 2, 4, 1, 0, /* lfe */ 2, 3, 4, 5, 1, 0 /* 4.0 */ }; const int8_t *tries; this->ao_caps = caps; this->ff_map = ff_map; this->ff_channels = ff_num; /* silence out */ for (i = 0; i < MAX_CHANNELS; i++) this->map[i] = -1; for (i = 0; i < 4; i++) this->left[i] = this->right[i] = -1; /* set up raw map and ao mode wishlist */ if (this->ff_channels == 1) { /* mono */ name_map[0] = 2; this->left[0] = this->right[0] = 0; tries = wishlist + 0 * num_modes; } else if (this->ff_channels == 2) { /* stereo */ /* FIXME: libxine does not yet support audio selection _after_ decoding. * For now, treat the most common "dual mono" case as stereo. */ name_map[0] = 0; name_map[1] = 1; this->left[0] = 0; this->right[0] = 1; tries = wishlist + 1 * num_modes; } else { for (i = 0; i < ff_num; i++) { int8_t target; uint32_t num = ff_list[i]; if (num >= sizeof (base_map) / sizeof (base_map[0])) continue; target = base_map[num]; if ((target >= 0) && (this->map[target] < 0)) this->map[target] = i; name_map[i] = num; /* for debug output below */ } this->left[0] = this->map[0] < 0 ? 0 : this->map[0]; this->map[0] = -1; this->right[0] = this->map[1] < 0 ? 1 : this->map[1]; this->map[1] = -1; tries = wishlist + (2 + (this->map[4] < 0 ? 2 : 0) + (this->map[5] < 0 ? 1 : 0)) * num_modes; } this->front_mixes = 1; /* find ao mode */ for (i = 0; i < num_modes; i++) if (caps & modes[tries[i]]) break; i = i == num_modes ? 1 : tries[i]; this->new_mode = modes[i]; this->ao_channels = mode_channels[i]; /* mix center to front */ if ((this->map[4] >= 0) && !((0x30 >> i) & 1)) { this->left[this->front_mixes] = this->map[4]; this->right[this->front_mixes++] = this->map[4]; this->map[4] = -1; } /* mix lfe to front */ if ((this->map[5] >= 0) && !((0x28 >> i) & 1)) { this->left[this->front_mixes] = this->map[5]; this->right[this->front_mixes++] = this->map[5]; this->map[5] = -1; } /* mix surround to front */ if ((this->map[2] >= 0) && (this->map[3] >= 0) && !((0x3c >> i) & 1)) { this->left[this->front_mixes] = this->map[2]; this->right[this->front_mixes++] = this->map[3]; this->map[2] = -1; this->map[3] = -1; } this->downmix_shift = this->front_mixes > 1 ? 1 : 0; /* this will be on the safe side but usually too soft?? */ #if 0 if (this->front_mixes > 2) this->downmix_shift = 2; #endif if (this->stream->xine->verbosity >= XINE_VERBOSITY_LOG) { const int8_t *names[] = { "left", "right", "center", "bass", "rear left", "rear right", "half left", "half right", "rear center", "side left", "side right" }; int8_t buf[256]; int p = sprintf (buf, "ff_audio_dec: %s channel layout: ", type); int8_t *indx = this->left; for (i = 0; i < 2; i++) { buf[p++] = '['; for (j = 0; (int)j < this->front_mixes; j++) p += sprintf (buf + p, "%s%s", names[name_map[indx[j]]], ((int)j < this->front_mixes - 1) ? " + " : ""); buf[p++] = ']'; buf[p++] = ' '; indx = this->right; } for (i = 2; i < (unsigned int)this->ao_channels; i++) p += sprintf (buf + p, "[%s] ", ((this->map[i] < 0) || (this->map[i] > 5)) ? (const int8_t *)"-" : names[name_map[this->map[i]]]); buf[p++] = '\n'; fwrite (buf, 1, p, stdout); } } } static int ff_audio_parse (ff_audio_decoder_t *this) { int offs, parser_consumed; this->pkt_sent = 0; /* NOTE #1: our own parser uses this->buf for efficiancy. when it says 0, * keep remaining bytes, and add more later. */ parser_consumed = ff_aac_mode_parse (this, this->parse.buf, this->parse.len, &offs); if (parser_consumed < 0) { this->decode.buf = NULL; this->decode.len = 0; this->parse.buf += offs; this->parse.len -= offs; return 0; } else if (parser_consumed > 0) { this->decode.buf = this->parse.buf + offs; this->decode.len = parser_consumed - offs; this->parse.buf += parser_consumed; this->parse.len -= parser_consumed; return 1; } /* parser_consumed == 0 */ #if XFF_PARSE > 1 /* NOTE #2: ffmpeg parser uses its own buf, and thus consumes all. */ if (this->parser_context) { uint8_t *outbuf; int outsize; /* NOTE: eac3 simply spans a frame from one sync word to the next. * with nice single frame input, we get * input=n1 consumed=n1 output=0 * input=n2 consumed=0 output=n1 * input=n2 consumed=n2 output=0 * input=n3 consumed=0 output=n2 * and so on, with no need for warnings. */ do { int ret = av_parser_parse2 (this->parser_context, this->context, &outbuf, &outsize, this->parse.buf, this->parse.len, 0, 0, 0); parser_consumed += ret; this->parse.buf += ret; this->parse.len -= ret; } while (this->parse.len && (outsize <= 0)); /* nothing to decode ? */ if (outsize <= 0) { this->decode.len = 0; return 0; } /* decode next packet */ this->decode.buf = outbuf; this->decode.len = outsize; return 1; } #endif /* XFF_PARSE > 1 */ this->decode.buf = this->parse.buf; this->decode.len = this->parse.len; return 1; } static void ff_audio_unparse (ff_audio_decoder_t *this) { if (this->decode.buf && this->parse.buf && (this->decode.buf >= this->parse.buf) && (this->decode.buf <= this->parse.buf + this->parse.len)) { /* parser just mapped through the input buf. post back. */ this->parse.len = (this->parse.buf + this->parse.len) - this->decode.buf; this->parse.buf = this->decode.buf; } } #define CLIP_16(v) ((v + 0x8000) & ~0xffff ? (v >> 31) ^ 0x7fff : v) static int ff_audio_decode (ff_audio_decoder_t *this) { int16_t *decode_buffer = (int16_t *)ASSUME_ALIGNED_2 (this->send.buf, 2); int consumed, got_frame = 0; #if XFF_AUDIO >= 4 float gain = this->class->gain; #endif #if XFF_AUDIO >= 3 this->avpkt->data = this->decode.buf; this->avpkt->size = this->decode.len; this->avpkt->flags = AV_PKT_FLAG_KEY; # if XFF_AUDIO >= 4 if (!this->av_frame) this->av_frame = XFF_ALLOC_FRAME (); # if XFF_AUDIO == 5 if (!this->pkt_sent) { int err = avcodec_send_packet (this->context, this->avpkt); /* xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ff_audio_dec: send (%d) = %d.\n", (int)size, err); */ /* NOTE: multiple frames per packet should now be avoided, * we no longer know the individual frame sizes here. * kludge: consume 1 symbolic byte. */ if (err >= 0) { consumed = 1; this->pkt_sent = 1; } else { consumed = (err == AVERROR (EAGAIN)) ? 0 : err; } } else { consumed = 1; } { /* that calls av_frame_unref () first. */ int err = avcodec_receive_frame (this->context, this->av_frame); /* xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ff_audio_dec: recv () = %d.\n", err); */ if (err != 0) { /* now, these are all frames from this packet. */ this->decode.buf += this->decode.len; this->decode.len = 0; this->send.len = 0; this->pkt_sent = 0; return 0; } got_frame = 1; } # else consumed = avcodec_decode_audio4 (this->context, this->av_frame, &got_frame, this->avpkt); # endif if ((consumed >= 0) && got_frame) { /* setup may have altered while decoding */ ff_map_channels (this); int16_t *q = decode_buffer; int samples = this->av_frame->nb_samples; int channels = this->ao_channels; int bytes, i, j, shift = this->downmix_shift; /* limit buffer */ if ((int)this->send.len < samples * channels * 2) samples = this->send.len / (channels * 2); bytes = samples * channels * 2; this->send.len = bytes; /* TJ. convert to packed int16_t while respecting the user's speaker arrangement. I tried to speed up and not to pull in libswresample. */ for (i = 2; i < channels; i++) if (this->map[i] < 0) { /* clear if there is an upmix mute channel */ memset (q, 0, bytes); break; } /* For mono output, downmix to stereo first */ if ((channels == 1) && (this->ff_channels > 1)) channels = 2; gain /= (float)(1 << shift); switch (this->context->sample_fmt) { /* "* 0.75" serves same purpose as "gain3" below. */ #define MIX_AUDIO(stype,planar,idx,num,dindx) do {\ const stype *p1, *p2, *p3, *p4;\ int i, sstep;\ int8_t *x = idx;\ int16_t *dptr = decode_buffer + dindx;\ if (planar) {\ p1 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[0]], sizeof (stype));\ if (!p1) break;\ sstep = 1;\ } else {\ p1 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype));\ if (!p1) break;\ p1 += x[0];\ sstep = this->ff_channels;\ }\ if (num == 1) {\ for (i = 0; i < samples; i++) {\ int32_t v = MIX_FIX(*p1);\ p1 += sstep;\ v >>= shift;\ *dptr = (v);\ dptr += channels;\ }\ break;\ }\ if (planar) {\ p2 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[1]], sizeof (stype));\ if (!p2) break;\ } else\ p2 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype)) + x[1];\ if (num == 2) {\ for (i = 0; i < samples; i++) {\ int32_t v = MIX_FIX(*p2);\ p2 += sstep;\ v -= v >> 2;\ v += MIX_FIX(*p1);\ p1 += sstep;\ v >>= shift;\ *dptr = CLIP_16(v);\ dptr += channels;\ }\ break;\ }\ if (planar) {\ p3 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[2]], sizeof (stype));\ if (!p3) break;\ } else\ p3 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype)) + x[2];\ if (num == 3) {\ for (i = 0; i < samples; i++) {\ int32_t v = MIX_FIX(*p2);\ p2 += sstep;\ v += MIX_FIX(*p3);\ p3 += sstep;\ v -= v >> 2;\ v += MIX_FIX(*p1);\ p1 += sstep;\ v >>= shift;\ *dptr = CLIP_16(v);\ dptr += channels;\ }\ break;\ }\ if (planar) {\ p4 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[3]], sizeof (stype));\ if (!p4) break;\ } else\ p4 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype)) + x[3];\ for (i = 0; i < samples; i++) {\ int32_t v = MIX_FIX(*p2);\ p2 += sstep;\ v += MIX_FIX(*p3);\ p3 += sstep;\ v += MIX_FIX(*p4);\ p4 += sstep;\ v -= v >> 2;\ v += MIX_FIX(*p1);\ p1 += sstep;\ v >>= shift;\ *dptr = CLIP_16(v);\ dptr += channels;\ }\ } while (0); #define MIX_FIX(v) (((int16_t)(v)<<8)^0x8000) case AV_SAMPLE_FMT_U8P: MIX_AUDIO (uint8_t, 1, this->left, this->front_mixes, 0); MIX_AUDIO (uint8_t, 1, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (uint8_t, 1, this->map + j, 1, j); break; case AV_SAMPLE_FMT_U8: MIX_AUDIO (uint8_t, 0, this->left, this->front_mixes, 0); MIX_AUDIO (uint8_t, 0, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (uint8_t, 0, this->map + j, 1, j); break; #undef MIX_FIX #define MIX_FIX(v) (v) case AV_SAMPLE_FMT_S16P: MIX_AUDIO (int16_t, 1, this->left, this->front_mixes, 0); MIX_AUDIO (int16_t, 1, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (int16_t, 1, this->map + j, 1, j); break; case AV_SAMPLE_FMT_S16: MIX_AUDIO (int16_t, 0, this->left, this->front_mixes, 0); MIX_AUDIO (int16_t, 0, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (int16_t, 0, this->map + j, 1, j); break; #undef MIX_FIX #define MIX_FIX(v) ((v)>>16) case AV_SAMPLE_FMT_S32P: MIX_AUDIO (int32_t, 1, this->left, this->front_mixes, 0); MIX_AUDIO (int32_t, 1, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (int32_t, 1, this->map + j, 1, j); break; case AV_SAMPLE_FMT_S32: MIX_AUDIO (int32_t, 0, this->left, this->front_mixes, 0); MIX_AUDIO (int32_t, 0, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (int32_t, 0, this->map + j, 1, j); break; #undef MIX_FIX #undef MIX_AUDIO /* Note on "gain3" below: */ /* - center and lfe downmix to both front left and right. */ /* This effectively doubles their power, so compensate by -3dB. */ /* - surround channels often contain some sound effects that may */ /* confuse when coming front, so the same -3dB do help here too. */ #define MIX_AUDIO(stype,planar,idx,num,dindx) do {\ const stype *p1, *p2, *p3, *p4;\ int i, sstep;\ float gain3;\ int8_t *x = idx;\ int16_t *dptr = decode_buffer + dindx;\ if (planar) {\ p1 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[0]], sizeof (stype));\ if (!p1) break;\ sstep = 1;\ } else {\ p1 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype));\ if (!p1) break;\ p1 += x[0];\ sstep = this->ff_channels;\ }\ if (num == 1) {\ for (i = 0; i < samples; i++) {\ int32_t v = (*p1) * gain;\ p1 += sstep;\ *dptr = CLIP_16(v);\ dptr += channels;\ }\ break;\ }\ gain3 = gain * 0.7071;\ if (planar) {\ p2 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[1]], sizeof (stype));\ if (!p2) break;\ } else\ p2 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype)) + x[1];\ if (num == 2) {\ for (i = 0; i < samples; i++) {\ int32_t v = (*p1) * gain + (*p2) * gain3;\ p1 += sstep;\ p2 += sstep;\ *dptr = CLIP_16(v);\ dptr += channels;\ }\ break;\ }\ if (planar) {\ p3 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[2]], sizeof (stype));\ if (!p3) break;\ } else\ p3 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype)) + x[2];\ if (num == 3) {\ for (i = 0; i < samples; i++) {\ int32_t v = (*p1) * gain + (*p2 + *p3) * gain3;\ p1 += sstep;\ p2 += sstep;\ p3 += sstep;\ *dptr = CLIP_16(v);\ dptr += channels;\ }\ break;\ }\ if (planar) {\ p4 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[x[3]], sizeof (stype));\ if (!p4) break;\ } else\ p4 = (stype *)ASSUME_ALIGNED_2 (this->av_frame->extended_data[0], sizeof (stype)) + x[3];\ for (i = 0; i < samples; i++) {\ int32_t v = (*p1) * gain + (*p2 + *p3 + *p4) * gain3;\ p1 += sstep;\ p2 += sstep;\ p3 += sstep;\ p4 += sstep;\ *dptr = CLIP_16(v);\ dptr += channels;\ }\ } while (0); case AV_SAMPLE_FMT_FLTP: /* the most popular one */ MIX_AUDIO (float, 1, this->left, this->front_mixes, 0); MIX_AUDIO (float, 1, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (float, 1, this->map + j, 1, j); break; case AV_SAMPLE_FMT_FLT: MIX_AUDIO (float, 0, this->left, this->front_mixes, 0); MIX_AUDIO (float, 0, this->right, this->front_mixes, 1); for (j = 0; j < channels; j++) if (this->map[j] >= 0) MIX_AUDIO (float, 0, this->map + j, 1, j); break; default: ; } if (channels > this->ao_channels) { /* final mono downmix */ int16_t *p = decode_buffer; q = p; for (i = samples; i; i--) { int v = *p++; v += *p++; *q++ = v >> 1; } this->send.len = samples * 2; } } else { /* !((consumed >= 0) && got_frame) */ this->send.len = 0; } # else /* XFF_AUDIO < 4 */ { int slen = this->send.len; consumed = avcodec_decode_audio3 (this->context, this->send.buf, &slen, this->avpkt); if (slen > 0) this->send.len = slen; } got_frame = consumed >= 0; ff_map_channels (this); # endif #else /* #if XFF_AUDIO < 3 */ { int slen = this->send.len; consumed = avcodec_decode_audio2 (this->context, this->send.buf, &slen, this->decode.buf, this->decode.len); if (slen > 0) this->send.len = slen; } got_frame = consumed >= 0; ff_map_channels (this); #endif if (consumed >= 0) { this->decode.buf += consumed; this->decode.len -= consumed; return got_frame; } else { this->decode.buf += this->decode.len; this->decode.len = 0; this->send.len = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: error decompressing audio frame (%d)\n", consumed); return 0; } } static void ff_audio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { ff_audio_decoder_t *this = xine_container_of(this_gen, ff_audio_decoder_t, audio_decoder); unsigned int codec_type = buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK); if (buf->decoder_flags & BUF_FLAG_SPECIAL) { ff_audio_handle_special_buffer(this, buf); return; } if (buf->decoder_flags & BUF_FLAG_HEADER) { ff_handle_header_buffer(this, buf); return; } else { if( !this->decoder_ok ) { if (ff_audio_open_codec(this, codec_type) < 0) { return; } } if( buf->decoder_flags & BUF_FLAG_PREVIEW ) return; ff_audio_ensure_buffer_size(this, this->size + buf->size); xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; xine_pts_queue_put (this->pts_queue, buf->size, buf->pts); if (this->parser_context || buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ /* pad input data */ memset (this->buf + this->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); this->parse.buf = this->buf; this->parse.len = this->size; while (this->parse.len) { if (!ff_audio_parse (this)) break; while (this->decode.len) { audio_buffer_t *audio_buffer; int bytes_to_send; int64_t pts; uint32_t have_len = this->decode.len, out; this->send.buf = this->decode_buffer; this->send.len = AVCODEC_MAX_AUDIO_FRAME_SIZE; if (!ff_audio_decode (this)) { have_len -= this->decode.len; xine_pts_queue_get (this->pts_queue, have_len); if (have_len > 0) continue; /* nothing used and nothing sent?? * a) ADTS probe running (< 16k bytes) * b) we can play this all day, or drop the undigestible after a while. */ if (this->size >= (64 << 10)) { this->decode.buf += this->decode.len; this->decode.len = 0; xine_pts_queue_get (this->pts_queue, this->parse.len); this->parse.buf += this->parse.len; this->parse.len = 0; } break; } have_len -= this->decode.len; pts = xine_pts_queue_get (this->pts_queue, have_len); if ((this->ff_sample_rate != this->context->sample_rate) || (this->ao_mode != this->new_mode)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: codec parameters changed\n")); /* close if it was open, and always trigger 1 new open attempt below */ ff_audio_output_close (this); } if (!this->output_open) { if (!this->ff_sample_rate || !this->ao_mode) { this->ff_sample_rate = this->context->sample_rate; this->ao_mode = this->new_mode; } if (this->ff_sample_rate && this->new_mode) { this->output_open = this->stream->audio_out->open (this->stream->audio_out, this->stream, 16, this->ff_sample_rate, this->ao_mode); if (!this->output_open) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "ffmpeg_audio_dec: error opening audio output\n"); this->size = 0; return; } } else { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("ffmpeg_audio_dec: cannot read codec parameters from packet\n")); /* try to decode next packet. */ /* there shouldn't be any output yet */ this->send.len = 0; /* pts applies only to first audio packet */ buf->pts = 0; } } #if XFF_AUDIO < 4 /* Old style postprocessing */ if (codec_type == BUF_AUDIO_WMAPRO) { /* the above codecs output float samples, not 16-bit integers */ int samples = this->send.len / sizeof(float); float gain = this->class->gain; float *p = (float *)ASSUME_ALIGNED_2 (this->decode_buffer, 4); int16_t *q = (int16_t *)ASSUME_ALIGNED_2 (this->decode_buffer, 2); int i; for (i = samples; i; i--) { int v = *p++ * gain; *q++ = CLIP_16 (v); } this->send.len = samples * 2; } if ((this->ao_channels != this->ff_channels) || (this->ao_channels > 2)) { /* Channel reordering and/or mixing */ int samples = this->send.len / (this->ff_channels * 2); int channels = this->ao_channels; int ff_channels = this->ff_channels; int16_t *p = (int16_t *)ASSUME_ALIGNED_2 (this->decode_buffer, 2); int16_t *q = p; int shift = this->downmix_shift, i, j; /* downmix mono output to stereo first */ if ((channels == 1) && (ff_channels > 1)) channels = 2; /* move to end of buf for in-place editing */ p += AVCODEC_MAX_AUDIO_FRAME_SIZE - this->send.len; if (p >= q + this->send.len) xine_fast_memcpy (p, q, this->send.len); else memmove (p, q, this->send.len); /* not very optimized but it only hits when playing multichannel audio through old ffmpeg - and its still better than previous code there */ if (this->front_mixes < 2) { /* just reorder and maybe upmix */ for (i = samples; i; i--) { q[0] = p[0]; q[1] = p[this->right[0]]; for (j = 2; j < channels; j++) q[j] = this->map[j] < 0 ? 0 : p[this->map[j]]; p += ff_channels; q += channels; } } else { /* downmix */ for (i = samples; i; i--) { int left = p[0]; int right = p[this->right[0]]; for (j = 1; j < this->front_mixes; j++) { left += p[this->left[j]]; right += p[this->right[j]]; } left >>= shift; q[0] = CLIP_16 (left); right >>= shift; q[1] = CLIP_16 (right); for (j = 2; j < channels; j++) q[j] = this->map[j] < 0 ? 0 : p[this->map[j]] >> shift; p += ff_channels; q += channels; } } /* final mono downmix */ if (channels > this->ao_channels) { p = (int16_t *)ASSUME_ALIGNED_2 (this->decode_buffer, 2); q = p; for (i = samples; i; i--) { int v = *p++; v += *p++; *q++ = v >> 1; } } this->send.len = samples * this->ao_channels * 2; } #endif /* dispatch the decoded audio */ out = 0; while (out < this->send.len) { int stream_status = xine_get_status (this->stream); if ((stream_status == XINE_STATUS_QUIT) || (stream_status == XINE_STATUS_STOP)) { this->size = 0; return; } audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); if (audio_buffer->mem_size == 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "ffmpeg_audio_dec: Help! Allocated audio buffer with nothing in it!\n"); return; } /* fill up this buffer */ if ((int)(this->send.len - out) > audio_buffer->mem_size) bytes_to_send = audio_buffer->mem_size; else bytes_to_send = this->send.len - out; xine_fast_memcpy (audio_buffer->mem, &this->decode_buffer[out], bytes_to_send); out += bytes_to_send; /* byte count / 2 (bytes / sample) / channels */ audio_buffer->num_frames = bytes_to_send / 2 / this->ao_channels; audio_buffer->vpts = pts; pts = 0; /* only first buffer gets the real pts */ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } /* output loop */ } /* decode loop */ ff_audio_unparse (this); } /* parse loop */ this->size = this->parse.len; if (this->size > 0) { int offs = this->parse.buf - this->buf; if (offs > 0) { if (offs >= this->size) memcpy (this->buf, this->buf + offs, this->size); else memmove (this->buf, this->buf + offs, this->size); } } } } } static void ff_audio_reset (audio_decoder_t *this_gen) { ff_audio_decoder_t *this = xine_container_of(this_gen, ff_audio_decoder_t, audio_decoder); this->size = 0; /* try to reset the wma decoder */ if( this->decoder_ok ) { #if XFF_AUDIO > 3 if (this->av_frame) { # if XFF_AUDIO == 5 av_frame_unref (this->av_frame); # endif XFF_FREE_FRAME (this->av_frame); } #endif #if 1 avcodec_flush_buffers (this->context); #else pthread_mutex_lock (&ffmpeg_lock); { uint8_t *ed = this->context->extradata; int es = this->context->extradata_size; this->context->extradata = NULL; this->context->extradata_size = 0; XFF_FREE_CONTEXT (this->context); this->decoder_ok = 0; this->context = XFF_ALLOC_CONTEXT (); if (this->context) { this->context->extradata = ed; this->context->extradata_size = es; } } if (XFF_AVCODEC_OPEN (this->context, this->codec) >= 0) this->decoder_ok = 1; pthread_mutex_unlock (&ffmpeg_lock); #endif } ff_audio_reset_parser(this); ff_aac_mode_set (this, 1); xine_pts_queue_reset (this->pts_queue); } static void ff_audio_discontinuity (audio_decoder_t *this_gen) { ff_audio_decoder_t *this = xine_container_of(this_gen, ff_audio_decoder_t, audio_decoder); this->size = 0; ff_audio_reset_parser(this); ff_aac_mode_set (this, 0); } static void ff_audio_dispose (audio_decoder_t *this_gen) { ff_audio_decoder_t *this = xine_container_of(this_gen, ff_audio_decoder_t, audio_decoder); if (this->parser_context) { pthread_mutex_lock (&ffmpeg_lock); av_parser_close(this->parser_context); this->parser_context = NULL; pthread_mutex_unlock (&ffmpeg_lock); } if( this->decoder_ok ) { #if XFF_AUDIO > 3 if (this->av_frame) { # if XFF_AUDIO == 5 av_frame_unref (this->av_frame); # endif XFF_FREE_FRAME (this->av_frame); } #endif } pthread_mutex_lock (&ffmpeg_lock); if (this->context) { _x_freep (&this->context->extradata); this->context->extradata_size = 0; XFF_FREE_CONTEXT (this->context); } pthread_mutex_unlock (&ffmpeg_lock); ff_audio_output_close(this); xine_free_aligned (this->buf); xine_free_aligned (this->decode_buffer); XFF_PACKET_UNREF (this->avpkt); xine_pts_queue_delete (&this->pts_queue); free (this_gen); } static audio_decoder_t *ff_audio_open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { ff_audio_decoder_t *this ; this = calloc(1, sizeof (ff_audio_decoder_t)); if (!this) return NULL; init_once_routine(); #ifndef HAVE_ZERO_SAFE_MEM /* Do these first, when compiler still knows stream is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ this->output_open = 0; this->ff_channels = 0; this->size = 0; this->decoder_ok = 0; # if XFF_AUDIO > 3 this->av_frame = NULL; # endif #endif # if XFF_AUDIO > 2 XFF_PACKET_NEW (this->avpkt); #endif this->class = (ff_audio_class_t *)class_gen; this->stream = stream; this->audio_decoder.decode_data = ff_audio_decode_data; this->audio_decoder.reset = ff_audio_reset; this->audio_decoder.discontinuity = ff_audio_discontinuity; this->audio_decoder.dispose = ff_audio_dispose; this->bufsize = AUDIOBUFSIZE; do { this->buf = xine_malloc_aligned (AUDIOBUFSIZE + AV_INPUT_BUFFER_PADDING_SIZE); if (this->buf) { this->context = XFF_ALLOC_CONTEXT (); if (this->context) { this->decode_buffer = xine_malloc_aligned (AVCODEC_MAX_AUDIO_FRAME_SIZE); if (this->decode_buffer) break; XFF_FREE_CONTEXT (this->context); } xine_free_aligned (this->buf); } free (this); return NULL; } while (0); this->pts_queue = xine_pts_queue_new (); return &this->audio_decoder; } static void ff_gain_cb (void *user_data, xine_cfg_entry_t *entry) { ff_audio_class_t *class = (ff_audio_class_t *)user_data; class->gain = (float)0x7fff * powf ((float)10, (float)entry->num_value / (float)20); } static void dispose_audio_class (audio_decoder_class_t *this_gen) { ff_audio_class_t *this = (ff_audio_class_t *)this_gen; config_values_t *config = this->xine->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free (this); } static void ff_bitexact_cb (void *user_data, xine_cfg_entry_t *entry) { ff_audio_class_t *class = (ff_audio_class_t *)user_data; class->bitexact = entry->num_value; } void *init_audio_plugin (xine_t *xine, const void *data) { ff_audio_class_t *this ; (void)data; this = calloc(1, sizeof (ff_audio_class_t)); if (!this) { return NULL; } this->decoder_class.open_plugin = ff_audio_open_plugin; this->decoder_class.identifier = "ffmpeg audio"; this->decoder_class.description = N_("ffmpeg based audio decoder plugin"); this->decoder_class.dispose = dispose_audio_class; this->xine = xine; this->gain = (float)0x7fff * powf ((float)10, (float) xine->config->register_num (xine->config, "audio.processing.ffmpeg_gain_dB", -3, _("FFmpeg audio gain (dB)"), _("Some AAC and WMA tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting."), 10, ff_gain_cb, this) / (float)20); this->bitexact = xine->config->register_bool (xine->config, "audio.processing.ffmpeg_bitexact", 0, _("Let FFmpeg use precise but slower math"), _("Get slightly better sound, at the expense of speed.\n" "Takes effect with next stream."), 10, ff_bitexact_cb, this); return this; } �����������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/ffmpeg_decoder.h���������������������������������������������������0000644�0001750�0001750�00000003673�14647725152�017612� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef HAVE_XINE_DECODER_H #define HAVE_XINE_DECODER_H #include <sys/types.h> #include <xine.h> #if defined LIBAVCODEC_VERSION_INT typedef struct ff_codec_s { uint32_t type; # if LIBAVCODEC_VERSION_INT >= ((54<<16)|(25<<8)) enum AVCodecID id; # else enum CodecID id; # endif const char *name; } ff_codec_t; extern const ff_codec_t ff_audio_lookup[]; extern const ff_codec_t ff_video_lookup[]; extern const size_t ff_video_lookup_entries; extern const size_t ff_audio_lookup_entries; #endif void *init_audio_plugin (xine_t *xine, const void *data); void *init_video_plugin (xine_t *xine, const void *data); void *init_avio_input_plugin (xine_t *xine, const void *data); void *init_avformat_input_plugin (xine_t *xine, const void *data); void *init_avformat_demux_plugin (xine_t *xine, const void *data); /* communication between avio/avformat input and avformat demux plugins */ #define INPUT_OPTIONAL_DATA_pb 0x1000 #define INPUT_OPTIONAL_DATA_fmt_ctx 0x1001 /* plugin ids */ #define INPUT_AVIO_ID "avio" #define DEMUX_AVFORMAT_ID "avformat" void init_once_routine(void); extern pthread_mutex_t ffmpeg_lock; #endif ���������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/ff_mpeg_parser.c���������������������������������������������������0000644�0001750�0001750�00000022451�14647725152�017626� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) * based on libmpeg2 decoder. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ff_mpeg_parser.h" #include <stdint.h> #include <stdlib.h> #define LOG_MODULE "mpeg_parser" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #define BUFFER_SIZE (1194 * 1024) /* libmpeg2's buffer size */ /* picture coding type (mpeg2 header) */ #define I_TYPE 1 #define P_TYPE 2 #define B_TYPE 3 #define D_TYPE 4 /* mpeg frame rate table from lavc */ static const int frame_rate_tab[][2] = { { 1, 1}, {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}, { 1, 1}, }; void mpeg_parser_init (mpeg_parser_t *parser, size_t padding_size) { parser->chunk_buffer = malloc(BUFFER_SIZE + padding_size); mpeg_parser_reset(parser); } void mpeg_parser_dispose (mpeg_parser_t *parser) { if ( parser == NULL ) return; free(parser->chunk_buffer); } void mpeg_parser_reset (mpeg_parser_t *parser) { parser->shift = 0xffffff00; parser->is_sequence_needed = 1; parser->in_slice = 0; parser->chunk_ptr = parser->chunk_buffer; parser->chunk_start = parser->chunk_buffer; parser->buffer_size = 0; parser->code = 0xb4; parser->picture_coding_type = 0; parser->width = 0; parser->height = 0; parser->rate_code = 0; parser->aspect_ratio_info = 0; parser->frame_duration = 0; parser->is_mpeg1 = 0; parser->has_sequence = 0; parser->frame_aspect_ratio = 0.0; } static void parse_header_picture (mpeg_parser_t *parser, uint8_t * buffer) { parser->picture_coding_type = (buffer [1] >> 3) & 7; } static double get_aspect_ratio(mpeg_parser_t *parser) { double ratio; double mpeg1_pel_ratio[16] = {1.0 /* forbidden */, 1.0, 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, 1.0 /*reserved*/ }; if( !parser->is_mpeg1 ) { /* these hardcoded values are defined on mpeg2 standard for * aspect ratio. other values are reserved or forbidden. */ switch (parser->aspect_ratio_info) { case 2: ratio = 4.0 / 3.0; break; case 3: ratio = 16.0 / 9.0; break; case 4: ratio = 2.11 / 1.0; break; case 1: default: ratio = (double)parser->width / (double)parser->height; break; } } else { /* mpeg1 constants refer to pixel aspect ratio */ ratio = (double)parser->width / (double)parser->height; ratio /= mpeg1_pel_ratio[parser->aspect_ratio_info]; } return ratio; } static int parse_chunk (mpeg_parser_t *parser, int code, uint8_t *buffer, int len) { int is_frame_done; int next_code = parser->code; (void)len; /* wait for sequence_header_code */ if (parser->is_sequence_needed) { if (code != 0xb3) { lprintf("waiting for sequence header\n"); parser->chunk_ptr = parser->chunk_buffer; return 0; } } switch (code) { case 0x00: /* picture_start_code */ if (len >= 2) { parse_header_picture (parser, buffer); parser->in_slice = 1; switch (parser->picture_coding_type) { case B_TYPE: lprintf ("B-Frame\n"); break; case P_TYPE: lprintf ("P-Frame\n"); break; case I_TYPE: lprintf ("I-Frame\n"); break; } } break; case 0xb2: /* user data code */ /* process_userdata(mpeg2dec, buffer); */ break; case 0xb3: /* sequence_header_code */ if (len >= 7) { int value; uint16_t width, height; if (parser->is_sequence_needed) { parser->is_sequence_needed = 0; } if ((buffer[6] & 0x20) != 0x20) { lprintf("Invalid sequence: missing marker_bit\n"); parser->has_sequence = 0; break; /* missing marker_bit */ } value = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; width = ((value >> 12) + 15) & ~15; height = ((value & 0xfff) + 15) & ~15; if ((width > 1920) || (height > 1152)) { lprintf("Invalid sequence: width=%d, height=%d\n", width, height); parser->has_sequence = 0; break; /* size restrictions for MP@HL */ } parser->width = width; parser->height = height; parser->rate_code = buffer[3] & 15; parser->aspect_ratio_info = buffer[3] >> 4; if (parser->rate_code < (sizeof(frame_rate_tab)/sizeof(*frame_rate_tab))) { parser->frame_duration = 90000; parser->frame_duration *= frame_rate_tab[parser->rate_code][1]; parser->frame_duration /= frame_rate_tab[parser->rate_code][0]; } else { printf ("invalid/unknown frame rate code : %d \n", parser->rate_code); parser->frame_duration = 0; } parser->has_sequence = 1; parser->is_mpeg1 = 1; } break; case 0xb5: /* extension_start_code */ if (len >= 1) { switch (buffer[0] & 0xf0) { case 0x10: /* sequence extension */ parser->is_mpeg1 = 0; break; } } break; default: if (code >= 0xb9) lprintf ("stream not demultiplexed ?\n"); //if (code >= 0xb0) // break; break; } if (parser->in_slice && ((next_code == 0x00) /* picture start */ || (next_code == 0xb3) /* sequence head */ // || (next_code == 0xb5) /* extension start */ || (next_code == 0xb7) /* sequence end */ )) { is_frame_done = 1; parser->in_slice = 0; } else { is_frame_done = 0; } #ifdef DEBUG_MPEG_PARSER printf ("ff_mpeg_parser: nalu 0x%02x, %d bytes%s.\n", (unsigned int)code, len, is_frame_done ? ", frame full" : ""); #endif return is_frame_done; } static inline uint8_t *copy_chunk (mpeg_parser_t *parser, uint8_t *current, uint8_t *end) { uint32_t shift; uint8_t *chunk_ptr; uint8_t *limit; uint8_t byte; shift = parser->shift; chunk_ptr = parser->chunk_ptr; limit = current + (parser->chunk_buffer + BUFFER_SIZE - chunk_ptr); if (limit > end) limit = end; while (1) { byte = *current++; *chunk_ptr++ = byte; if (shift != 0x00000100) { shift = (shift | byte) << 8; if (current < limit) continue; if (current == end) { parser->chunk_ptr = chunk_ptr; parser->shift = shift; lprintf("Need more bytes\n"); return NULL; } else { /* we filled the chunk buffer without finding a start code */ lprintf("Buffer full\n"); parser->code = 0xb4; /* sequence_error_code */ parser->chunk_ptr = parser->chunk_buffer; return current; } } lprintf("New chunk: 0x%2X\n", byte); parser->chunk_ptr = chunk_ptr; parser->shift = 0xffffff00; parser->code = byte; return current; } } uint8_t *mpeg_parser_decode_data (mpeg_parser_t *parser, uint8_t *current, uint8_t *end, int *flush) { int ret; uint8_t code; #ifdef DEBUG_MPEG_PARSER printf ("ff_mpeg_parser: input %d bytes.\n", (int)(end - current)); #endif ret = 0; *flush = 0; while (current != end) { if (parser->chunk_ptr == parser->chunk_buffer) { /* write the beginning of the chunk */ parser->chunk_buffer[0] = 0x00; parser->chunk_buffer[1] = 0x00; parser->chunk_buffer[2] = 0x01; parser->chunk_buffer[3] = parser->code; parser->chunk_ptr += 4; parser->chunk_start = parser->chunk_ptr; parser->has_sequence = 0; } code = parser->code; current = copy_chunk (parser, current, end); if (current == NULL) return NULL; ret = parse_chunk (parser, code, parser->chunk_start, parser->chunk_ptr - parser->chunk_start - 4); parser->chunk_start = parser->chunk_ptr; if (ret == 1) { if (parser->has_sequence) { parser->frame_aspect_ratio = get_aspect_ratio(parser); } parser->buffer_size = parser->chunk_ptr - parser->chunk_buffer - 4; parser->chunk_ptr = parser->chunk_buffer; if (parser->code == 0xb7) /* sequence end, maybe a still menu */ *flush = 1; return current; } } return NULL; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/ff_mpeg_parser.h���������������������������������������������������0000644�0001750�0001750�00000004423�14647725152�017632� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Simple MPEG-ES parser/framer by Thibaut Mattern (tmattern@noos.fr) * based on libmpeg2 decoder. */ #ifndef HAVE_MPEG_PARSER_H #define HAVE_MPEG_PARSER_H /* #define DEBUG_MPEG_PARSER */ #include <stdint.h> #include <stddef.h> typedef struct mpeg_parser_s { uint8_t *chunk_buffer; uint8_t *chunk_ptr; uint8_t *chunk_start; uint32_t shift; int buffer_size; uint8_t code; uint8_t picture_coding_type; uint8_t is_sequence_needed:1; uint8_t is_mpeg1:1; /* public */ uint8_t has_sequence:1; /* public */ uint8_t in_slice:1; uint8_t rate_code:4; int aspect_ratio_info; /* public properties */ uint16_t width; uint16_t height; int frame_duration; double frame_aspect_ratio; } mpeg_parser_t; /* parser initialization */ void mpeg_parser_init (mpeg_parser_t *parser, size_t padding_size); /* parser disposal */ void mpeg_parser_dispose (mpeg_parser_t *parser); /* read a frame * return a pointer to the first byte of the next frame * or NULL if more bytes are needed * *flush is set to 1 if the decoder must be flushed (needed for still menus) */ uint8_t *mpeg_parser_decode_data (mpeg_parser_t *parser, uint8_t *current, uint8_t *end, int *flush); /* reset the parser */ void mpeg_parser_reset (mpeg_parser_t *parser); #endif /* HAVE_MPEG_PARSER_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/xine_audio.list����������������������������������������������������0000644�0001750�0001750�00000003300�14647725152�017514� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������type=audio # xine-lib BUF_AUDIO_ ffmpeg CODEC_ID_ description or comment # ("!"=ignore) (quote any "s) WMAV1 WMAV1 MS Windows Media Audio 1 WMAV2 WMAV2 MS Windows Media Audio 2 WMAPRO WMAPRO MS Windows Media Audio Professional 14_4 RA_144 Real 14.4 28_8 RA_288 Real 28.8 MPEG MP3 MP3 MP3ADU MP3ADU MPEG-3 adu MSADPCM ADPCM_MS MS ADPCM QTIMAADPCM ADPCM_IMA_QT QT IMA ADPCM MSIMAADPCM ADPCM_IMA_WAV MS IMA ADPCM DK3ADPCM ADPCM_IMA_DK3 Duck DK3 ADPCM DK4ADPCM ADPCM_IMA_DK4 Duck DK4 ADPCM VQA_IMA ADPCM_IMA_WS Westwood Studios IMA SMJPEG_IMA ADPCM_IMA_SMJPEG SMJPEG IMA XA_ADPCM ADPCM_XA CD-ROM/XA ADPCM 4X_ADPCM ADPCM_4XM 4X ADPCM EA_ADPCM ADPCM_EA Electronic Arts ADPCM MULAW PCM_MULAW mu-law logarithmic PCM ALAW PCM_ALAW A-law logarithmic PCM ROQ ROQ_DPCM RoQ DPCM INTERPLAY INTERPLAY_DPCM Interplay DPCM MAC3 MACE3 MACE 3:1 MAC6 MACE6 MACE 6:1 XAN_DPCM XAN_DPCM Origin Xan DPCM VMD VMDAUDIO Sierra VMD Audio FLAC FLAC FLAC SHORTEN SHORTEN Shorten ALAC ALAC ALAC QDESIGN2 QDM2 QDesign COOK COOK RealAudio Cooker ATRK ATRAC3 ATRAC 3 TRUESPEECH TRUESPEECH TrueSpeech TTA TTA True Audio Lossless SMACKER SMACKAUDIO Smacker FLVADPCM ADPCM_SWF Flash ADPCM WAVPACK WAVPACK WavPack AMR_NB AMR_NB AMR narrow band AMR_WB AMR_WB AMR wide band A52 AC3 AC-3 EAC3 EAC3 E-AC-3 AAC AAC MPEG4 AAC_LATM AAC_LATM AAC LATM ADPCM_G726 ADPCM_G726 ADPCM G726 QCLP QCELP QualComm Purevoice OPUS OPUS Opus Audio DTS DTS DTS TRUEHD TRUEHD TrueHD # disabled codecs (ref. configure.ac) ! ADPCM_ADX ! ADPCM_G726 ! DSICINAUDIO ! DVAUDIO ! IMC ! MP3ON4 ! SONIC ! SONIC_LS ! VORBIS ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/xine_video.list����������������������������������������������������0000644�0001750�0001750�00000005437�14647725152�017536� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������type=video # xine-lib BUF_VIDEO_ ffmpeg CODEC_ID_ description or comment # ("!"=ignore) (quote any "s) MSMPEG4_V1 MSMPEG4V1 Microsoft MPEG-4 v1 MSMPEG4_V2 MSMPEG4V2 Microsoft MPEG-4 v2 MSMPEG4_V3 MSMPEG4V3 Microsoft MPEG-4 v3 WMV7 WMV1 MS Windows Media Video 7 WMV8 WMV2 MS Windows Media Video 8 WMV9 WMV3 MS Windows Media Video 9 VC1 VC1 MS Windows Media Video VC-1 MPEG4 MPEG4 ISO MPEG-4 XVID MPEG4 ISO MPEG-4 (XviD) DIVX5 MPEG4 ISO MPEG-4 (DivX5) 3IVX MPEG4 ISO MPEG-4 (3ivx) JPEG MJPEG Motion JPEG MJPEG MJPEG Motion JPEG MJPEG_B MJPEGB Motion JPEG B I263 H263I ITU H.263 H263 H263 H.263 RV10 RV10 Real Video 1.0 RV20 RV20 Real Video 2.0 RV30 RV30 Real Video 3.0 RV40 RV40 Real Video 4.0 IV31 INDEO3 Indeo Video 3.1 IV32 INDEO3 Indeo Video 3.2 SORENSON_V1 SVQ1 Sorenson Video 1 SORENSON_V3 SVQ3 Sorenson Video 3 DV DVVIDEO DV HUFFYUV HUFFYUV HuffYUV VP31 VP3 On2 VP3.1 VP5 VP5 On2 VP5 VP6 VP6 On2 VP6 VP6F VP6F On2 VP6 VP8 VP8 On2 VP8 VP9 VP9 VP9 AV1 AV1 AV1 4XM 4XM 4X Video CINEPAK CINEPAK Cinepak MSVC MSVIDEO1 Microsoft Video 1 MSRLE MSRLE Microsoft RLE RPZA RPZA Apple Quicktime Video/RPZA CYUV CYUV Creative YUV ROQ ROQ Id Software RoQ IDCIN IDCIN Id Software CIN WC3 XAN_WC3 Xan VQA WS_VQA Westwood Studios VQA INTERPLAY INTERPLAY_VIDEO Interplay MVE FLI FLIC FLIC Video 8BPS 8BPS Planar RGB SMC SMC Apple Quicktime Graphics/SMC DUCKTM1 TRUEMOTION1 Duck TrueMotion v1 DUCKTM2 TRUEMOTION2 Duck TrueMotion v2 VMD VMDVIDEO Sierra VMD Video ZLIB ZLIB ZLIB Video MSZH MSZH MSZH Video ASV1 ASV1 ASV v1 Video ASV2 ASV2 ASV v2 Video ATIVCR1 VCR1 ATI VCR-1 FLV1 FLV1 Flash Video QTRLE QTRLE Apple Quicktime Animation/RLE H264 H264 H.264/AVC H261 H261 H.261 AASC AASC Autodesk Video LOCO LOCO LOCO QDRW QDRAW QuickDraw QPEG QPEG Q-Team QPEG TSCC TSCC TechSmith Video ULTI ULTI IBM UltiMotion WNV1 WNV1 Winnow Video XL VIXL Miro/Pinnacle VideoXL RT21 INDEO2 Indeo/RealTime 2 FPS1 FRAPS Fraps MPEG MPEG2VIDEO MPEG 1/2 CSCD CSCD CamStudio AVS AVS AVS ALGMM MMVIDEO American Laser Games MM ZMBV ZMBV Zip Motion Blocks Video SMACKER SMACKVIDEO Smacker NUV NUV NuppelVideo KMVC KMVC Karl Morton's Video Codec FLASHSV FLASHSV Flash Screen Video CAVS CAVS Chinese AVS VMNC VMNC VMware Screen Codec THEORA_RAW THEORA Theora SNOW SNOW Snow HEVC HEVC HEVC/H.265 # disabled codecs (ref. configure.ac) ! BMP ! CLJR ! DSICINVIDEO ! FFV1 ! FFVHUFF ! GIF ! H263P ! JPEGLS ! LJPEG ! MDEC ! PAM ! PBM ! PGM ! PGMYUV ! PNG ! PPM ! RAWVIDEO ! SP5X ! TARGA ! TIERTEXSEQVIDEO ! TIFF ! XVID ⇒ MPEG4 ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ffmpeg/ffmpeg_decoder.c���������������������������������������������������0000644�0001750�0001750�00000010024�14647725152�017571� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine decoder plugin using ffmpeg */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <pthread.h> #if defined(HAVE_LIBAVUTIL_AVUTIL_H) # include <libavutil/avutil.h> #endif #if defined(HAVE_LIBAVUTIL_MEM_H) # include <libavutil/mem.h> #endif #if defined(HAVE_AVUTIL_AVCODEC_H) # include <libavcodec/avcodec.h> #else # include <avcodec.h> #endif #ifdef HAVE_AVFORMAT # include <libavformat/avformat.h> // av_register_all() #endif #include "ffmpeg_compat.h" #include <xine.h> #include <xine/xine_internal.h> // XINE_VERSION_CODE #include <xine/xine_plugin.h> #include <xine/buffer.h> #include "ffmpeg_decoder.h" #include "ff_audio_list.h" #include "ff_video_list.h" const size_t ff_video_lookup_entries = sizeof(ff_video_lookup) / sizeof(ff_video_lookup[0]); const size_t ff_audio_lookup_entries = sizeof(ff_audio_lookup) / sizeof(ff_audio_lookup[0]); /* * common initialisation */ pthread_mutex_t ffmpeg_lock; static void _init_once_routine(void) { pthread_mutex_init(&ffmpeg_lock, NULL); XFF_AVCODEC_INIT(); XFF_AVCODEC_REGISTER_ALL(); #ifdef HAVE_AVFORMAT # if !defined(LIBAVFORMAT_VERSION_INT) || LIBAVFORMAT_VERSION_INT < XFF_INT_VERSION(58,9,100) av_register_all(); # endif avformat_network_init(); #endif } void init_once_routine(void) { static pthread_once_t once_control = PTHREAD_ONCE_INIT; pthread_once( &once_control, _init_once_routine ); } /* * exported plugin catalog entry */ #ifdef HAVE_AVFORMAT static const input_info_t input_info_avio = { .priority = -1, }; static const input_info_t input_info_avformat = { .priority = -2, }; static const demuxer_info_t demux_info_avformat = { .priority = -2, }; #endif /* HAVE_AVFORMAT */ static const decoder_info_t dec_info_ffmpeg_audio = { .supported_types = supported_audio_types, .priority = 7, }; static const uint32_t wmv8_video_types[] = { BUF_VIDEO_WMV8, 0 }; static const decoder_info_t dec_info_ffmpeg_wmv8 = { .supported_types = wmv8_video_types, .priority = 0, }; static const uint32_t wmv9_video_types[] = { BUF_VIDEO_WMV9, 0 }; static const decoder_info_t dec_info_ffmpeg_wmv9 = { .supported_types = wmv9_video_types, .priority = 0, }; static const decoder_info_t dec_info_ffmpeg_video = { .supported_types = supported_video_types, .priority = 6, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 19, "ffmpegvideo", XINE_VERSION_CODE, &dec_info_ffmpeg_video, init_video_plugin }, { PLUGIN_VIDEO_DECODER, 19, "ffmpeg-wmv8", XINE_VERSION_CODE, &dec_info_ffmpeg_wmv8, init_video_plugin }, { PLUGIN_VIDEO_DECODER, 19, "ffmpeg-wmv9", XINE_VERSION_CODE, &dec_info_ffmpeg_wmv9, init_video_plugin }, { PLUGIN_AUDIO_DECODER, 16, "ffmpegaudio", XINE_VERSION_CODE, &dec_info_ffmpeg_audio, init_audio_plugin }, #ifdef HAVE_AVFORMAT { PLUGIN_INPUT, 18, INPUT_AVIO_ID, XINE_VERSION_CODE, &input_info_avio, init_avio_input_plugin }, { PLUGIN_INPUT, 18, DEMUX_AVFORMAT_ID, XINE_VERSION_CODE, &input_info_avformat, init_avformat_input_plugin }, { PLUGIN_DEMUX, 27, DEMUX_AVFORMAT_ID, XINE_VERSION_CODE, &demux_info_avformat, init_avformat_demux_plugin }, #endif { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/nsf_combined.h������������������������������������������������������������0000644�0001750�0001750�00000001643�14647725152�016036� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ void *decoder_nsf_init_plugin (xine_t *xine, const void *data); void *demux_nsf_init_plugin (xine_t *xine, const void *data); ���������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/ogg_combined.h������������������������������������������������������������0000644�0001750�0001750�00000002177�14647725152�016027� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2013-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #include <xine/os_types.h> #include <xine/attributes.h> void *vorbis_init_plugin (xine_t *xine, const void *data); void *speex_init_plugin (xine_t *xine, const void *data); void *theora_init_plugin (xine_t *xine, const void *data); void *anx_init_class (xine_t *xine, const void *data); void *ogg_init_class (xine_t *xine, const void *data); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/xine_ogg_demuxer.c��������������������������������������������������������0000644�0001750�0001750�00000214407�14647725152�016737� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * demultiplexer for ogg streams */ /* 2003.02.09 (dilb) update of the handling for audio/video infos for strongarm cpus. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <ctype.h> #include <stdlib.h> #include <inttypes.h> #include <ogg/ogg.h> #ifdef HAVE_VORBIS #include <vorbis/codec.h> #endif #ifdef HAVE_SPEEX #include <speex/speex.h> #include <speex/speex_header.h> #include <speex/speex_stereo.h> #include <speex/speex_callbacks.h> #endif #ifdef HAVE_THEORA #include <theora/theora.h> #endif #define LOG_MODULE "demux_ogg" #define LOG_VERBOSE /* #define LOG */ #define DEBUG_PACKETS 0 #define DEBUG_PREVIEWS 0 #define DEBUG_PTS 0 #define DEBUG_VIDEO_PACKETS 0 #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/demux.h> #include "bswap.h" #include "flacutils.h" #include "ogg_combined.h" #define CHUNKSIZE 8500 #define PACKET_TYPE_HEADER 0x01 #define PACKET_TYPE_COMMENT 0x03 #define PACKET_TYPE_CODEBOOK 0x05 #define PACKET_TYPE_BITS 0x07 #define PACKET_LEN_BITS01 0xc0 #define PACKET_LEN_BITS2 0x02 #define PACKET_IS_SYNCPOINT 0x08 #define MAX_STREAMS 32 #define PTS_AUDIO 0 #define PTS_VIDEO 1 #define WRAP_THRESHOLD 900000 #define SUB_BUFSIZE 1024 typedef struct chapter_entry_s { int64_t start_pts; char *name; } chapter_entry_t; typedef struct chapter_info_s { int current_chapter; int max_chapter; chapter_entry_t *entries; } chapter_info_t; typedef struct stream_info_s { ogg_stream_state oss; uint32_t buf_types; int headers; int64_t header_granulepos; int64_t factor; int64_t quotient; int resync; char *language; /* CMML, Ogg Skeleton stream information */ int granuleshift; /* Annodex v2 stream information */ int hide_first_header; int delivered_bos; int delivered_eos; } stream_info_t; typedef struct demux_ogg_s { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; fifo_buffer_t *video_fifo; input_plugin_t *input; int status; int frame_duration; #ifdef HAVE_THEORA theora_info t_info; theora_comment t_comment; #endif ogg_sync_state oy; ogg_page og; int64_t start_pts; int64_t last_pts[2]; int time_length; int num_streams; stream_info_t *si[MAX_STREAMS]; /* stream info */ int num_audio_streams; int num_video_streams; int unhandled_video_streams; int num_spu_streams; off_t avg_bitrate; char *meta[XINE_STREAM_INFO_MAX]; chapter_info_t *chapter_info; xine_event_queue_t *event_queue; uint8_t send_newpts:1; uint8_t buf_flag_seek:1; uint8_t keyframe_needed:1; uint8_t ignore_keyframes:1; } demux_ogg_t ; typedef struct { demux_class_t demux_class; } demux_ogg_class_t; typedef struct { demux_class_t demux_class; } demux_anx_class_t; #ifdef HAVE_THEORA static int intlog(int num) { int ret=0; while(num>0){ num=num/2; ret=ret+1; } return(ret); } #endif static int get_stream (demux_ogg_t *this, int serno) { /*finds the stream_num, which belongs to a ogg serno*/ int i; for (i = 0; i<this->num_streams; i++) { if (this->si[i]->oss.serialno == serno) { return i; } } return -1; } static int new_stream_info (demux_ogg_t *this, const int cur_serno) { int stream_num; this->si[this->num_streams] = (stream_info_t *)calloc(1, sizeof(stream_info_t)); ogg_stream_init(&this->si[this->num_streams]->oss, cur_serno); stream_num = this->num_streams; this->si[stream_num]->buf_types = 0; this->si[stream_num]->header_granulepos = -1; this->si[stream_num]->headers = 0; this->num_streams++; return stream_num; } static int64_t get_pts (demux_ogg_t *this, int stream_num , int64_t granulepos ) { /*calculates an pts from an granulepos*/ if (granulepos<0) { if ( this->si[stream_num]->header_granulepos>=0 ) { /*return the smallest valid pts*/ return 1; } else return 0; } else if (this->si[stream_num]->buf_types == BUF_VIDEO_THEORA || (this->si[stream_num]->buf_types & 0xFFFF0000) == BUF_SPU_CMML) { int64_t iframe, pframe; int granuleshift; granuleshift = this->si[stream_num]->granuleshift; iframe = granulepos >> granuleshift; pframe = granulepos - (iframe << granuleshift); if (this->si[stream_num]->quotient) return 1+((iframe+pframe) * this->si[stream_num]->factor / this->si[stream_num]->quotient); else return 0; } else if (this->si[stream_num]->quotient) return 1+(granulepos * this->si[stream_num]->factor / this->si[stream_num]->quotient); else return 0; } static int read_ogg_packet (demux_ogg_t *this) { char *buffer; long bytes; long total = 0; while (ogg_sync_pageout(&this->oy,&this->og)!=1) { buffer = ogg_sync_buffer(&this->oy, CHUNKSIZE); bytes = this->input->read(this->input, buffer, CHUNKSIZE); if (bytes <= 0) { if (total == 0) { lprintf("read_ogg_packet read nothing\n"); return 0; } break; } ogg_sync_wrote(&this->oy, bytes); total += bytes; } return 1; } static void get_stream_length (demux_ogg_t *this) { /*determine the streamlenght and set this->time_length accordingly. ATTENTION:current_pos and oggbuffers will be destroyed by this function, there will be no way to continue playback uninterrupted. You have to seek afterwards, because after get_stream_length, the current_position is at the end of the file */ off_t filelength; int done=0; int stream_num; this->time_length=-1; if (this->input->get_capabilities(this->input) & INPUT_CAP_SEEKABLE) { filelength=this->input->get_length(this->input); if (filelength!=-1) { if (filelength>70000) { this->demux_plugin.seek(&this->demux_plugin, (off_t) ( (double)(filelength-65536)/filelength*65535), 0, 0); } done=0; while (!done) { if (!read_ogg_packet (this)) { if (this->time_length) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_BITRATE, ((int64_t) 8000*filelength)/this->time_length); /*this is a fine place to compute avg_bitrate*/ this->avg_bitrate= 8000*filelength/this->time_length; } return; } stream_num=get_stream(this, ogg_page_serialno (&this->og) ); if (stream_num!=-1) { if (this->time_length < (get_pts(this, stream_num, ogg_page_granulepos(&this->og) / 90))) this->time_length = get_pts(this, stream_num, ogg_page_granulepos(&this->og)) / 90; } } } } } #ifdef HAVE_THEORA static void send_ogg_packet (demux_ogg_t *this, fifo_buffer_t *fifo, ogg_packet *op, int64_t pts, uint32_t decoder_flags, int stream_num) { buf_element_t *buf; size_t done = 0, todo = op->bytes; const size_t op_size = sizeof(ogg_packet); while (done<todo) { size_t offset=0; buf = fifo->buffer_pool_alloc (fifo); buf->decoder_flags = decoder_flags; if (done==0) { memcpy (buf->content, op, op_size); offset=op_size; buf->decoder_flags = buf->decoder_flags | BUF_FLAG_FRAME_START; } if (done+buf->max_size-offset < todo) { memcpy (buf->content+offset, op->packet+done, buf->max_size-offset); buf->size = buf->max_size; done=done+buf->max_size-offset; } else { memcpy (buf->content+offset , op->packet+done, todo-done); buf->size = todo-done+offset; done=todo; buf->decoder_flags = buf->decoder_flags | BUF_FLAG_FRAME_END; } buf->pts = pts; if( this->input->get_length (this->input) ) buf->extra_info->input_normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); buf->extra_info->input_time = buf->pts / 90 ; buf->type = this->si[stream_num]->buf_types; fifo->put (fifo, buf); } } #endif /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) static void check_newpts (demux_ogg_t *this, int64_t pts, int video, int preview) { int64_t diff; llprintf(DEBUG_PTS, "new pts %" PRId64 " found in stream\n",pts); diff = pts - this->last_pts[video]; if (!preview && (pts>=0) && (this->send_newpts || (this->last_pts[video] && abs(diff)>WRAP_THRESHOLD) ) ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "diff=%" PRId64 " (pts=%" PRId64 ", last_pts=%" PRId64 ")\n", diff, pts, this->last_pts[video]); if (this->buf_flag_seek) { _x_demux_control_newpts(this->stream, pts, BUF_FLAG_SEEK); this->buf_flag_seek = 0; } else { _x_demux_control_newpts(this->stream, pts, 0); } this->send_newpts = 0; this->last_pts[1-video] = 0; } if (!preview && (pts>=0) ) this->last_pts[video] = pts; /* use pts for bitrate measurement */ /*compute avg_bitrate if time_length isn't set*/ if ((pts>180000) && !(this->time_length)) { this->avg_bitrate = this->input->get_current_pos (this->input) * 8 * 90000/ pts; if (this->avg_bitrate<1) this->avg_bitrate = 1; } } static void ogg_handle_event (demux_ogg_t *this) { xine_event_t *event; while ((event = xine_event_get(this->event_queue))) { switch(event->type) { case XINE_EVENT_INPUT_NEXT: { if (this->chapter_info) { int c_chap = this->chapter_info->current_chapter; if (c_chap+1 < this->chapter_info->max_chapter) { int start_time = this->chapter_info->entries[c_chap+1].start_pts / 90; this->demux_plugin.seek(&this->demux_plugin, 0, start_time, 1); } } } break; case XINE_EVENT_INPUT_PREVIOUS: { if (this->chapter_info) { int c_chap = this->chapter_info->current_chapter; if (c_chap >= 1) { int start_time = this->chapter_info->entries[c_chap-1].start_pts / 90; this->demux_plugin.seek(&this->demux_plugin, 0, start_time, 1); } } } break; } xine_event_free(event); } return; } #define OGG_META(TAG,APPEND) { #TAG"=", XINE_META_INFO_##TAG, APPEND } #define OGG_META_L(TAG,APPEND,META) { #TAG"=", XINE_META_INFO_##META, APPEND } static const struct ogg_meta { char tag[16]; int meta; int append; } metadata[] = { OGG_META (ALBUM, 0), OGG_META (ARTIST, 0), OGG_META (PUBLISHER, 0), OGG_META (COPYRIGHT, 0), OGG_META (DISCNUMBER, 0), OGG_META (LICENSE, 0), OGG_META (TITLE, 0), OGG_META_L (TRACKNUMBER, 0, TRACK_NUMBER), OGG_META (COMPOSER, 1), OGG_META (ARRANGER, 1), OGG_META (LYRICIST, 1), OGG_META (AUTHOR, 1), OGG_META (CONDUCTOR, 1), OGG_META (PERFORMER, 1), OGG_META (ENSEMBLE, 1), OGG_META (OPUS, 0), OGG_META (PART, 0), OGG_META (PARTNUMBER, 0), OGG_META (GENRE, 1), OGG_META_L (DATE, 1, YEAR), /* hmm... */ OGG_META (LOCATION, 0), OGG_META (COMMENT, 0), }; #if 0 /* ensure that those marked "append" are cleared */ /* FIXME: is this useful? Should they be cleared on first write? */ static void prepare_read_comments (demux_ogg_t *this) { int i; for (i = 0; i < sizeof (metadata) / sizeof (struct ogg_meta); ++i) if (metadata[i].append) { free (this->meta[metadata[i].meta]); this->meta[metadata[i].meta] = NULL; } } #endif static int read_comments (demux_ogg_t *this, const char *comment) { unsigned i; for (i = 0; i < sizeof (metadata) / sizeof (metadata[0]); ++i) { size_t ml = strlen (metadata[i].tag); if (!strncasecmp (metadata[i].tag, comment, ml) && comment[ml]) { if (metadata[i].append && this->meta[metadata[i].meta]) { char *newstr; if (asprintf (&newstr, "%s\n%s", this->meta[metadata[i].meta], comment + ml) >= 0) { free (this->meta[metadata[i].meta]); this->meta[metadata[i].meta] = newstr; } } else { free (this->meta[metadata[i].meta]); this->meta[metadata[i].meta] = strdup (comment + ml); } _x_meta_info_set_utf8(this->stream, metadata[i].meta, this->meta[metadata[i].meta]); return 1; } } return 0; } /* * utility function to read a LANGUAGE= line from the user_comments, * to label audio and spu streams * utility function to read CHAPTER*=, TITLE= etc. from the user_comments, * to name (parts of) the stream */ static void read_language_comment (demux_ogg_t *this, ogg_packet *op, int stream_num) { #ifdef HAVE_VORBIS char **ptr; char *comment; vorbis_comment vc; vorbis_info vi; vorbis_comment_init(&vc); vorbis_info_init(&vi); /* this is necessary to make libvorbis accept this vorbis_info*/ vi.rate=1; if ( vorbis_synthesis_headerin(&vi, &vc, op) >= 0) { ptr=vc.user_comments; while(*ptr) { comment=*ptr++; if ( !strncasecmp ("LANGUAGE=", comment, 9) ) { this->si[stream_num]->language = strdup (comment + strlen ("LANGUAGE=") ); } else read_comments (this, comment); } } vorbis_comment_clear(&vc); vorbis_info_clear(&vi); #endif } /* * utility function to read CHAPTER*= from the user_comments, * to name parts of the stream */ static void read_chapter_comment (demux_ogg_t *this, ogg_packet *op) { #ifdef HAVE_VORBIS char **ptr; char *comment; vorbis_comment vc; vorbis_info vi; vorbis_comment_init(&vc); vorbis_info_init(&vi); /* this is necessary to make libvorbis accept this vorbis_info*/ vi.rate=1; if ( vorbis_synthesis_headerin(&vi, &vc, op) >= 0) { char *chapter_time = 0; char *chapter_name = 0; int chapter_no = 0; ptr=vc.user_comments; while(*ptr) { comment=*ptr++; if (read_comments (this, comment)) continue; if ( !chapter_time && strlen(comment) == 22 && !strncasecmp ("CHAPTER" , comment, 7) && isdigit(*(comment+7)) && isdigit(*(comment+8)) && (*(comment+9) == '=')) { chapter_time = strdup(comment+10); chapter_no = strtol(comment+7, NULL, 10); } if ( !chapter_name && !strncasecmp("CHAPTER", comment, 7) && isdigit(*(comment+7)) && isdigit(*(comment+8)) && !strncasecmp ("NAME=", comment+9, 5)) { if (strtol(comment+7,NULL,10) == chapter_no) { chapter_name = strdup(comment+14); } } if (chapter_time && chapter_name && chapter_no){ int hour, min, sec, msec; lprintf("create chapter entry: no=%d name=%s time=%s\n", chapter_no, chapter_name, chapter_time); hour= strtol(chapter_time, NULL, 10); min = strtol(chapter_time+3, NULL, 10); sec = strtol(chapter_time+6, NULL, 10); msec = strtol(chapter_time+9, NULL, 10); lprintf("time: %d %d %d %d\n", hour, min,sec,msec); if (!this->chapter_info) { this->chapter_info = (chapter_info_t *)calloc(1, sizeof(chapter_info_t)); } if (this->chapter_info) { this->chapter_info->current_chapter = -1; this->chapter_info->max_chapter = chapter_no; this->chapter_info->entries = realloc( this->chapter_info->entries, chapter_no*sizeof(chapter_entry_t)); this->chapter_info->entries[chapter_no-1].name = chapter_name; this->chapter_info->entries[chapter_no-1].start_pts = (msec + (1000.0 * sec) + (60000.0 * min) + (3600000.0 * hour))*90; } else { _x_freep (&chapter_name); } _x_freep (&chapter_time); chapter_no = 0; } } free(chapter_name); free(chapter_time); } vorbis_comment_clear(&vc); vorbis_info_clear(&vi); #endif } /* * update the display of the title, if needed */ static void update_chapter_display (demux_ogg_t *this, int stream_num, ogg_packet *op) { int chapter = 0; int64_t pts = get_pts(this, stream_num, op->granulepos ); while (chapter < this->chapter_info->max_chapter && this->chapter_info->entries[chapter].start_pts < pts) { chapter++; } chapter--; if (chapter != this->chapter_info->current_chapter){ xine_ui_data_t data = { .str = { 0, }, .str_len = 0 }; xine_event_t uevent = { .type = XINE_EVENT_UI_SET_TITLE, .stream = this->stream, .data = &data, .data_length = sizeof(data) }; this->chapter_info->current_chapter = chapter; if (chapter >= 0) { if (this->meta[XINE_META_INFO_TITLE]) { data.str_len = snprintf(data.str, sizeof(data.str), "%s / %s", this->meta[XINE_META_INFO_TITLE], this->chapter_info->entries[chapter].name); } else { strlcpy(data.str, this->chapter_info->entries[chapter].name, sizeof(data.str)); } } else { strlcpy(data.str, this->meta[XINE_META_INFO_TITLE], sizeof(data.str)); } if ( data.str_len == 0 ) data.str_len = strlen(data.str); _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, data.str); lprintf("new TITLE: %s\n", data.str); xine_event_send(this->stream, &uevent); } } /* * utility function to pack one ogg_packet into a xine * buffer, fill out all needed fields * and send it to the right fifo */ static void send_ogg_buf (demux_ogg_t *this, ogg_packet *op, int stream_num, uint32_t decoder_flags) { int hdrlen; int normpos = 0; if( this->input->get_length (this->input) ) normpos = (int)( (double) this->input->get_current_pos (this->input) * 65535 / this->input->get_length (this->input) ); hdrlen = (*op->packet & PACKET_LEN_BITS01) >> 6; hdrlen |= (*op->packet & PACKET_LEN_BITS2) << 1; /* for Annodex files: the first packet after the AnxData info packet needs * to have its BOS flag set: we set it here */ if (!this->si[stream_num]->delivered_bos) { op->b_o_s = 1; this->si[stream_num]->delivered_bos = 1; } if ( this->audio_fifo && (this->si[stream_num]->buf_types & 0xFF000000) == BUF_AUDIO_BASE) { uint8_t *data; int size; int64_t pts; if (op->packet[0] == PACKET_TYPE_COMMENT ) { read_language_comment(this, op, stream_num); } if ((this->si[stream_num]->buf_types & 0xFFFF0000) == BUF_AUDIO_SPEEX || (this->si[stream_num]->buf_types & 0xFFFF0000) == BUF_AUDIO_FLAC || (this->si[stream_num]->buf_types & 0xFFFF0000) == BUF_AUDIO_OPUS || (this->si[stream_num]->buf_types & 0xFFFF0000) == BUF_AUDIO_VORBIS) { data = op->packet; size = op->bytes; } else { data = op->packet+1+hdrlen; size = op->bytes-1-hdrlen; } llprintf(DEBUG_PACKETS, "audio data size %d\n", size); if ((op->granulepos != -1) || (this->si[stream_num]->header_granulepos != -1)) { pts = get_pts(this, stream_num, op->granulepos ); check_newpts( this, pts, PTS_AUDIO, decoder_flags ); } else pts = 0; llprintf(DEBUG_PACKETS, "audiostream %d op-gpos %" PRId64 " hdr-gpos %" PRId64 " pts %" PRId64 " \n", stream_num, op->granulepos, this->si[stream_num]->header_granulepos, pts); _x_demux_send_data(this->audio_fifo, data, size, pts, this->si[stream_num]->buf_types, decoder_flags, normpos, pts / 90, this->time_length, 0); } #ifdef HAVE_THEORA else if ((this->si[stream_num]->buf_types & 0xFFFF0000) == BUF_VIDEO_THEORA) { int64_t pts; theora_info t_info; theora_comment t_comment; theora_info_init (&t_info); theora_comment_init (&t_comment); /*Lets see if this is an Header*/ if ((theora_decode_header(&t_info, &t_comment, op))>=0) { decoder_flags=decoder_flags|BUF_FLAG_HEADER; lprintf ("found an header\n"); } if ((op->granulepos != -1) || (this->si[stream_num]->header_granulepos != -1)) { pts = get_pts(this, stream_num, op->granulepos ); check_newpts( this, pts, PTS_VIDEO, decoder_flags ); } else pts = 0; llprintf(DEBUG_PACKETS, "theorastream %d op-gpos %" PRId64 " hdr-gpos %" PRId64 " pts %" PRId64 " \n", stream_num, op->granulepos, this->si[stream_num]->header_granulepos, pts); send_ogg_packet (this, this->video_fifo, op, pts, decoder_flags, stream_num); theora_comment_clear (&t_comment); theora_info_clear (&t_info); } #endif else if ((this->si[stream_num]->buf_types & 0xFF000000) == BUF_VIDEO_BASE) { uint8_t *data; int size; int64_t pts; llprintf(DEBUG_VIDEO_PACKETS, "video buffer, type=%08x\n", this->si[stream_num]->buf_types); if (op->packet[0] == PACKET_TYPE_COMMENT ) { read_chapter_comment(this, op); }else{ data = op->packet+1+hdrlen; size = op->bytes-1-hdrlen; if ((op->granulepos != -1) || (this->si[stream_num]->header_granulepos != -1)) { pts = get_pts(this, stream_num, op->granulepos ); check_newpts( this, pts, PTS_VIDEO, decoder_flags ); } else pts = 0; llprintf(DEBUG_VIDEO_PACKETS, "videostream %d op-gpos %" PRId64 " hdr-gpos %" PRId64 " pts %" PRId64 " \n", stream_num, op->granulepos, this->si[stream_num]->header_granulepos, pts); _x_demux_send_data(this->video_fifo, data, size, pts, this->si[stream_num]->buf_types, decoder_flags, normpos, pts / 90, this->time_length, 0); if (this->chapter_info && op->granulepos != -1) { update_chapter_display(this, stream_num, op); } } } else if ((this->si[stream_num]->buf_types & 0xFFFF0000) == BUF_SPU_CMML) { buf_element_t *buf; char *str; buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = this->si[stream_num]->buf_types; buf->pts = get_pts (this, stream_num, op->granulepos); str = buf->content; memcpy (str, op->packet, op->bytes); str[op->bytes] = '\0'; buf->size = 12 + op->bytes + 1; lprintf ("CMML stream %d (bytes=%ld): PTS %"PRId64": %s\n", stream_num, op->bytes, buf->pts, str); this->video_fifo->put (this->video_fifo, buf); } else if ((this->si[stream_num]->buf_types & 0xFF000000) == BUF_SPU_BASE) { buf_element_t *buf; int i; char *subtitle,*str; int lenbytes; int start,end; uint32_t *val; for (i = 0, lenbytes = 0; i < hdrlen; i++) { lenbytes = lenbytes << 8; lenbytes += *((unsigned char *) op->packet + hdrlen - i); } if (op->packet[0] == PACKET_TYPE_HEADER ) { lprintf ("Textstream-header-packet\n"); } else if (op->packet[0] == PACKET_TYPE_COMMENT ) { lprintf ("Textstream-comment-packet\n"); read_language_comment(this, op, stream_num); } else { subtitle = (char *)&op->packet[hdrlen + 1]; if ((strlen(subtitle) > 1) || (*subtitle != ' ')) { start = op->granulepos; end = start+lenbytes; lprintf ("subtitlestream %d: %d -> %d :%s\n",stream_num,start,end,subtitle); buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = this->si[stream_num]->buf_types; buf->pts = 0; val = (uint32_t * )buf->content; *val++ = start; *val++ = end; str = (char *)val; memcpy (str, subtitle, 1+strlen(subtitle)); this->video_fifo->put (this->video_fifo, buf); } } } else { lprintf("unknown stream type %x\n", this->si[stream_num]->buf_types); } } static void decode_vorbis_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { #ifdef HAVE_VORBIS vorbis_info vi; vorbis_comment vc; this->si[stream_num]->buf_types = BUF_AUDIO_VORBIS +this->num_audio_streams++; this->si[stream_num]->headers = 3; vorbis_info_init(&vi); vorbis_comment_init(&vc); if (vorbis_synthesis_headerin(&vi, &vc, op) >= 0) { _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, vi.bitrate_nominal); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, vi.rate); this->si[stream_num]->factor = 90000; this->si[stream_num]->quotient = vi.rate; if (vi.bitrate_nominal<1) this->avg_bitrate += 100000; /* assume 100 kbit */ else this->avg_bitrate += vi.bitrate_nominal; } else { this->si[stream_num]->factor = 900; this->si[stream_num]->quotient = 441; this->si[stream_num]->headers = 0; xine_log (this->stream->xine, XINE_LOG_MSG, _("ogg: vorbis audio track indicated but no vorbis stream header found.\n")); } vorbis_comment_clear(&vc); vorbis_info_clear(&vi); #endif } static void decode_speex_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { #ifdef HAVE_SPEEX void *st; const SpeexMode *mode; SpeexHeader *header; this->si[stream_num]->buf_types = BUF_AUDIO_SPEEX +this->num_audio_streams++; this->si[stream_num]->headers = 1; header = speex_packet_to_header (op->packet, op->bytes); if (header) { int bitrate; mode = speex_mode_list[header->mode]; st = speex_decoder_init (mode); speex_decoder_ctl (st, SPEEX_GET_BITRATE, &bitrate); if (bitrate <= 1) bitrate = 16000; /* assume 16 kbit */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, bitrate); this->si[stream_num]->factor = 90000; this->si[stream_num]->quotient = header->rate; this->avg_bitrate += bitrate; lprintf ("detected Speex stream,\trate %d\tbitrate %d\n", header->rate, bitrate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, header->rate); this->si[stream_num]->headers += header->extra_headers; } #else (void)op; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Speex stream detected, unable to play\n"); this->si[stream_num]->buf_types = BUF_CONTROL_NOP; #endif } static void decode_video_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { buf_element_t *buf; xine_bmiheader bih; int channel; #ifdef LOG int16_t locbits_per_sample; int32_t locsize, locdefault_len, locbuffersize; int64_t locsamples_per_unit; #endif uint32_t locsubtype; int32_t locwidth, locheight; int64_t loctime_unit; /* read fourcc with machine endianness */ memcpy (&locsubtype, op->packet + 9, sizeof (locsubtype)); /* everything else little endian */ loctime_unit = _X_LE_64(&op->packet[17]); #ifdef LOG locsize = _X_LE_32(&op->packet[13]); locsamples_per_unit = _X_LE_64(&op->packet[25]); locdefault_len = _X_LE_32(&op->packet[33]); locbuffersize = _X_LE_32(&op->packet[37]); locbits_per_sample = _X_LE_16(&op->packet[41]); #endif locwidth = _X_LE_32(&op->packet[45]); locheight = _X_LE_32(&op->packet[49]); lprintf ("direct show filter created stream detected, hexdump:\n"); #ifdef LOG xine_hexdump (op->packet, op->bytes); #endif channel = this->num_video_streams++; this->si[stream_num]->buf_types = _x_fourcc_to_buf_video (locsubtype); if( !this->si[stream_num]->buf_types ) { this->si[stream_num]->buf_types = BUF_VIDEO_UNKNOWN; _x_report_video_fourcc (this->stream->xine, LOG_MODULE, locsubtype); } this->si[stream_num]->buf_types |= channel; this->si[stream_num]->headers = 0; /* header is sent below */ #ifdef LOG lprintf ("subtype %.4s\n", (char*)&locsubtype); lprintf ("time_unit %" PRId64 "\n", loctime_unit); lprintf ("samples_per_unit %" PRId64 "\n", locsamples_per_unit); lprintf ("default_len %d\n", locdefault_len); lprintf ("buffersize %d\n", locbuffersize); lprintf ("bits_per_sample %d\n", locbits_per_sample); lprintf ("width %d\n", locwidth); lprintf ("height %d\n", locheight); lprintf ("buf_type %08x\n",this->si[stream_num]->buf_types); #endif bih.biSize=sizeof(xine_bmiheader); bih.biWidth = locwidth; bih.biHeight= locheight; bih.biPlanes= 0; memcpy(&bih.biCompression, &locsubtype, 4); bih.biBitCount= 0; bih.biSizeImage=locwidth*locheight; bih.biXPelsPerMeter=1; bih.biYPelsPerMeter=1; bih.biClrUsed=0; bih.biClrImportant=0; buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; this->frame_duration = loctime_unit * 9 / 1000; this->si[stream_num]->factor = loctime_unit * 9; this->si[stream_num]->quotient = 1000; buf->decoder_info[0] = this->frame_duration; memcpy (buf->content, &bih, sizeof (xine_bmiheader)); buf->size = sizeof (xine_bmiheader); buf->type = this->si[stream_num]->buf_types; /* video metadata */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_FOURCC, locsubtype); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, locwidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, locheight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->frame_duration); this->avg_bitrate += 500000; /* FIXME */ this->video_fifo->put (this->video_fifo, buf); } static void decode_audio_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { if (this->audio_fifo) { buf_element_t *buf; int codec; char str[5]; int channel; #ifdef LOG int16_t locblockalign; int32_t locsize, locdefault_len, locbuffersize; int64_t loctime_unit; #endif int16_t locbits_per_sample, locchannels; int32_t locavgbytespersec; int64_t locsamples_per_unit; #ifdef LOG locsize = _X_LE_32(&op->packet[13]); loctime_unit = _X_LE_64(&op->packet[17]); locbuffersize = _X_LE_32(&op->packet[37]); locdefault_len = _X_LE_32(&op->packet[33]); locblockalign = _X_LE_16(&op->packet[47]); #endif locsamples_per_unit = _X_LE_64(&op->packet[25]); locbits_per_sample = _X_LE_16(&op->packet[41]); locchannels = _X_LE_16(&op->packet[45]); locavgbytespersec= _X_LE_32(&op->packet[49]); lprintf ("direct show filter created audio stream detected, hexdump:\n"); #ifdef LOG xine_hexdump (op->packet, op->bytes); #endif memcpy(str, &op->packet[9], 4); str[4] = 0; codec = strtoul(str, NULL, 16); channel= this->num_audio_streams++; this->si[stream_num]->buf_types = _x_formattag_to_buf_audio(codec); if( this->si[stream_num]->buf_types ) { this->si[stream_num]->buf_types |= channel; } else { this->si[stream_num]->buf_types = BUF_AUDIO_UNKNOWN; _x_report_audio_format_tag (this->stream->xine, LOG_MODULE, codec); /*break;*/ } #ifdef LOG lprintf ("subtype 0x%x\n", codec); lprintf ("time_unit %" PRId64 "\n", loctime_unit); lprintf ("samples_per_unit %" PRId64 "\n", locsamples_per_unit); lprintf ("default_len %d\n", locdefault_len); lprintf ("buffersize %d\n", locbuffersize); lprintf ("bits_per_sample %d\n", locbits_per_sample); lprintf ("channels %d\n", locchannels); lprintf ("blockalign %d\n", locblockalign); lprintf ("avgbytespersec %d\n", locavgbytespersec); lprintf ("buf_type %08x\n",this->si[stream_num]->buf_types); #endif buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = this->si[stream_num]->buf_types; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = locsamples_per_unit; buf->decoder_info[2] = locbits_per_sample; buf->decoder_info[3] = locchannels; this->audio_fifo->put (this->audio_fifo, buf); this->si[stream_num]->headers = 0; /* header already sent */ this->si[stream_num]->factor = 90000; this->si[stream_num]->quotient = locsamples_per_unit; this->avg_bitrate += locavgbytespersec*8; /* audio metadata */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, codec); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, locchannels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, locbits_per_sample); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, locsamples_per_unit); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, locavgbytespersec * 8); } else /* no audio_fifo there */ this->si[stream_num]->buf_types = BUF_CONTROL_NOP; } static void decode_dshow_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { lprintf ("older Direct Show filter-generated stream header detected. Hexdump:\n"); #ifdef LOG xine_hexdump (op->packet, op->bytes); #endif this->si[stream_num]->headers = 0; /* header is sent below */ if ( (_X_LE_32(&op->packet[96]) == 0x05589f80) && (op->bytes >= 184)) { buf_element_t *buf; xine_bmiheader bih; int channel; uint32_t fcc; lprintf ("seems to be a video stream.\n"); channel = this->num_video_streams++; memcpy (&fcc, op->packet + 68, sizeof (fcc)); lprintf ("fourcc %08x\n", fcc); this->si[stream_num]->buf_types = _x_fourcc_to_buf_video (fcc); if( !this->si[stream_num]->buf_types ) { this->si[stream_num]->buf_types = BUF_VIDEO_UNKNOWN; _x_report_video_fourcc (this->stream->xine, LOG_MODULE, fcc); } this->si[stream_num]->buf_types |= channel; bih.biSize = sizeof(xine_bmiheader); bih.biWidth = _X_LE_32(&op->packet[176]); bih.biHeight = _X_LE_32(&op->packet[180]); bih.biPlanes = 0; memcpy (&bih.biCompression, op->packet+68, 4); bih.biBitCount = _X_LE_16(&op->packet[182]); if (!bih.biBitCount) bih.biBitCount = 24; /* FIXME ? */ bih.biSizeImage = (bih.biBitCount>>3)*bih.biWidth*bih.biHeight; bih.biXPelsPerMeter = 1; bih.biYPelsPerMeter = 1; bih.biClrUsed = 0; bih.biClrImportant = 0; buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAMERATE| BUF_FLAG_FRAME_END; { int64_t v; memcpy (&v, op->packet + 164, sizeof (v)); this->si[stream_num]->factor = v * 9; this->frame_duration = v * 9 / 1000; } this->si[stream_num]->quotient = 1000; buf->decoder_info[0] = this->frame_duration; memcpy (buf->content, &bih, sizeof (xine_bmiheader)); buf->size = sizeof (xine_bmiheader); buf->type = this->si[stream_num]->buf_types; this->video_fifo->put (this->video_fifo, buf); lprintf ("subtype %.4s\n", (char*)&fcc); lprintf ("buf_type %08x\n", this->si[stream_num]->buf_types); lprintf ("video size %d x %d\n", bih.biWidth, bih.biHeight); lprintf ("frame duration %d\n", this->frame_duration); /* video metadata */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, bih.biWidth); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, bih.biHeight); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->frame_duration); this->avg_bitrate += 500000; /* FIXME */ this->ignore_keyframes = 1; } else if (_X_LE_32(&op->packet[96]) == 0x05589F81) { #if 0 /* FIXME: no test streams */ buf_element_t *buf; int codec; char str[5]; int channel; int extra_size; extra_size = *(int16_t*)(op->packet+140); format = *(int16_t*)(op->packet+124); channels = *(int16_t*)(op->packet+126); samplerate = *(int32_t*)(op->packet+128); nAvgBytesPerSec = *(int32_t*)(op->packet+132); nBlockAlign = *(int16_t*)(op->packet+136); wBitsPerSample = *(int16_t*)(op->packet+138); samplesize = (sh_a->wf->wBitsPerSample+7)/8; cbSize = extra_size; if(extra_size > 0) memcpy(wf+sizeof(WAVEFORMATEX),op->packet+142,extra_size); #endif xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "FIXME, old audio format not handled\n"); this->si[stream_num]->buf_types = BUF_CONTROL_NOP; } else { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "old header detected but stream type is unknown\n"); this->si[stream_num]->buf_types = BUF_CONTROL_NOP; } } static void decode_text_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { int channel=0; buf_element_t *buf; (void)op; lprintf ("textstream detected.\n"); this->si[stream_num]->headers = 2; channel = this->num_spu_streams++; this->si[stream_num]->buf_types = BUF_SPU_OGM | channel; /*send an empty spu to inform the video_decoder, that there is a stream*/ buf = this->video_fifo->buffer_pool_alloc (this->video_fifo); buf->type = this->si[stream_num]->buf_types; buf->pts = 0; memset (buf->content, 0, 12); this->video_fifo->put (this->video_fifo, buf); } static void decode_theora_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { #ifdef HAVE_THEORA xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ogg: Theorastreamsupport is highly alpha at the moment\n"); if (theora_decode_header(&this->t_info, &this->t_comment, op) >= 0) { this->num_video_streams++; this->si[stream_num]->factor = (int64_t) 90000 * (int64_t) this->t_info.fps_denominator; if (!this->t_info.fps_numerator) { this->t_info.fps_numerator = 1; /* FIXME: default value ? */ } this->si[stream_num]->quotient = this->t_info.fps_numerator; this->frame_duration = ((int64_t) 90000*this->t_info.fps_denominator); this->frame_duration /= this->t_info.fps_numerator; this->si[stream_num]->granuleshift = intlog(this->t_info.keyframe_frequency_force-1); this->si[stream_num]->headers=3; this->si[stream_num]->buf_types = BUF_VIDEO_THEORA; _x_meta_info_set(this->stream, XINE_META_INFO_VIDEOCODEC, "theora"); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->t_info.frame_width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->t_info.frame_height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->frame_duration); /*currently aspect_nominator and -denumerator are 0?*/ if (this->t_info.aspect_denominator) { int64_t ratio = ((int64_t) this->t_info.aspect_numerator * 10000); ratio /= this->t_info.aspect_denominator; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, ratio); } lprintf ("decoded theora header \n"); lprintf ("frameduration %d\n",this->frame_duration); lprintf ("w:%d h:%d \n",this->t_info.frame_width,this->t_info.frame_height); lprintf ("an:%d ad:%d \n",this->t_info.aspect_numerator,this->t_info.aspect_denominator); } else { /*Rejected stream*/ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "A theora header was rejected by libtheora\n"); this->si[stream_num]->buf_types = BUF_CONTROL_NOP; this->si[stream_num]->headers = 0; /* FIXME: don't know */ } #else (void)op; this->si[stream_num]->buf_types = BUF_VIDEO_THEORA; this->num_video_streams++; this->unhandled_video_streams++; _x_meta_info_set(this->stream, XINE_META_INFO_VIDEOCODEC, "theora"); #endif } static void decode_flac_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { xine_flac_metadata_header header; xine_flac_streaminfo_block streaminfo = {.samplerate = 0}; buf_element_t *buf; xine_waveformatex wave; memset(&wave, 0, sizeof(wave)); /* Packet type */ _x_assert(op->packet[0] == 0x7F); /* OggFLAC signature */ _x_assert(_X_BE_32(&op->packet[1]) == ME_FOURCC('F', 'L', 'A', 'C')); /* Version: supported only 1.0 */ _x_assert(op->packet[5] == 1); _x_assert(op->packet[6] == 0); /* Header count */ this->si[stream_num]->headers = 0/*_X_BE_16(&op->packet[7]) +1*/; /* fLaC signature */ _x_assert(_X_BE_32(&op->packet[9]) == ME_FOURCC('f', 'L', 'a', 'C')); _x_parse_flac_metadata_header(&op->packet[13], &header); switch ( header.blocktype ) { case FLAC_BLOCKTYPE_STREAMINFO: _x_assert(header.length == FLAC_STREAMINFO_SIZE); _x_parse_flac_streaminfo_block(&op->packet[17], &streaminfo); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, streaminfo.samplerate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, streaminfo.channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, streaminfo.bits_per_sample); break; } this->si[stream_num]->buf_types = BUF_AUDIO_FLAC +this->num_audio_streams++; this->si[stream_num]->factor = 90000; buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_FLAC; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = streaminfo.samplerate; buf->decoder_info[2] = streaminfo.bits_per_sample; buf->decoder_info[3] = streaminfo.channels; buf->size = sizeof(xine_waveformatex) + FLAC_STREAMINFO_SIZE; memcpy(buf->content+sizeof(xine_waveformatex), &op->packet[17], FLAC_STREAMINFO_SIZE); xine_hexdump(&op->packet[17], FLAC_STREAMINFO_SIZE); wave.cbSize = FLAC_STREAMINFO_SIZE; memcpy(buf->content, &wave, sizeof(xine_waveformatex)); this->audio_fifo->put(this->audio_fifo, buf); /* Skip the Ogg framing info */ op->bytes -= 9; op->packet += 9; } static void decode_opus_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { buf_element_t *buf; xine_waveformatex wave; memset(&wave, 0, sizeof(wave)); this->si[stream_num]->headers = 0; _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, _X_BE_32(&op->packet[12])); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, op->packet[9]); this->si[stream_num]->buf_types = BUF_AUDIO_OPUS + this->num_audio_streams++; this->si[stream_num]->factor = 90000; buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = this->si[stream_num]->buf_types; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = 0; buf->decoder_info[1] = _X_BE_32(&op->packet[12]); /* sample rate */ buf->decoder_info[2] = 0; buf->decoder_info[3] = op->packet[9]; /* channel count */ buf->size = sizeof(xine_waveformatex); wave.cbSize = 0; memcpy(buf->content, &wave, sizeof(xine_waveformatex)); this->audio_fifo->put(this->audio_fifo, buf); } static void decode_annodex_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { lprintf ("Annodex stream detected\n"); this->si[stream_num]->buf_types = BUF_CONTROL_NOP; this->si[stream_num]->headers = 1; this->si[stream_num]->header_granulepos = op->granulepos; _x_meta_info_set(this->stream, XINE_META_INFO_SYSTEMLAYER, "Annodex"); } static void decode_anxdata_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { int64_t granule_rate_n, granule_rate_d; uint32_t secondary_headers; const char *content_type = ""; size_t content_type_length = 0; lprintf("AnxData stream detected\n"); /* read granule rate */ granule_rate_n = _X_LE_64(&op->packet[8]); granule_rate_d = _X_LE_64(&op->packet[16]); secondary_headers = _X_LE_32(&op->packet[24]); lprintf("granule_rate %" PRId64 "/%" PRId64 ", %d secondary headers\n", granule_rate_n, granule_rate_d, secondary_headers); /* read "Content-Type" MIME header */ const char *startline = &op->packet[28]; const char *endline; if ( strcmp(&op->packet[28], "Content-Type: ") == 0 && (endline = strstr(startline, "\r\n")) ) { content_type = startline + sizeof("Content-Type: "); content_type_length = startline - endline; } lprintf("Content-Type: %s (length:%td)\n", content_type, content_type_length); /* how many header packets in the AnxData stream? */ this->si[stream_num]->headers = secondary_headers + 1; this->si[stream_num]->hide_first_header = 1; /* set factor and quotient */ this->si[stream_num]->factor = (int64_t) 90000 * granule_rate_d; this->si[stream_num]->quotient = granule_rate_n; lprintf("factor: %" PRId64 ", quotient: %" PRId64 "\n", this->si[stream_num]->factor, this->si[stream_num]->quotient); /* what type of stream are we dealing with? */ if (!strncmp(content_type, "audio/x-vorbis", content_type_length)) { #ifdef HAVE_VORBIS this->si[stream_num]->buf_types = BUF_AUDIO_VORBIS; #else this->si[stream_num]->buf_types = BUF_CONTROL_NOP; #endif this->num_audio_streams++; } else if (!strncmp(content_type, "audio/x-speex", content_type_length)) { this->num_audio_streams++; #ifdef HAVE_SPEEX this->si[stream_num]->buf_types = BUF_AUDIO_SPEEX; #else this->si[stream_num]->buf_types = BUF_CONTROL_NOP; #endif } else if (!strncmp(content_type, "video/x-theora", content_type_length)) { this->num_video_streams++; #ifdef HAVE_THEORA this->si[stream_num]->buf_types = BUF_VIDEO_THEORA; #else this->si[stream_num]->buf_types = BUF_CONTROL_NOP; #endif } else if (!strncmp(content_type, "text/x-cmml", content_type_length)) { unsigned int channel = this->num_spu_streams++; this->si[stream_num]->headers = 0; this->si[stream_num]->buf_types = BUF_SPU_CMML | channel; this->si[stream_num]->granuleshift = 0; } else { this->si[stream_num]->buf_types = BUF_CONTROL_NOP; } } static void decode_cmml_header (demux_ogg_t *this, const int stream_num, ogg_packet *op) { unsigned int channel = this->num_spu_streams++; this->si[stream_num]->headers = 0; this->si[stream_num]->buf_types = BUF_SPU_CMML | channel; this->si[stream_num]->factor = 90000 * _X_LE_64(&op->packet[20]); this->si[stream_num]->quotient = _X_LE_64(&op->packet[12]); this->si[stream_num]->granuleshift = (int)op->packet[28]; } /* * interpret stream start packages, send headers */ static void send_header (demux_ogg_t *this) { int stream_num = -1; int cur_serno; int done = 0; ogg_packet op; xine_event_t ui_event; lprintf ("detecting stream types...\n"); this->ignore_keyframes = 0; while (!done) { if (!read_ogg_packet(this) || !this->og.header || !this->og.body) { return; } /* now we've got at least one new page */ cur_serno = ogg_page_serialno (&this->og); if (ogg_page_bos(&this->og)) { lprintf ("beginning of stream\n"); lprintf ("serial number %d\n", cur_serno); if( this->num_streams == MAX_STREAMS ) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_ogg: MAX_STREAMS exceeded, aborting.\n"); this->status = DEMUX_FINISHED; return; } stream_num = new_stream_info(this, cur_serno); } else { stream_num = get_stream(this, cur_serno); if (stream_num == -1) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_ogg: stream with no beginning!\n"); this->status = DEMUX_FINISHED; return; } } ogg_stream_pagein(&this->si[stream_num]->oss, &this->og); while (ogg_stream_packetout(&this->si[stream_num]->oss, &op) == 1) { if (!this->si[stream_num]->buf_types) { /* detect buftype */ if (!memcmp (&op.packet[1], "vorbis", 6)) { decode_vorbis_header(this, stream_num, &op); } else if (!memcmp (&op.packet[0], "Speex", 5)) { decode_speex_header(this, stream_num, &op); } else if (!memcmp (&op.packet[1], "video", 5)) { decode_video_header(this, stream_num, &op); } else if (!memcmp (&op.packet[1], "audio", 5)) { decode_audio_header(this, stream_num, &op); } else if (op.bytes >= 142 && !memcmp (&op.packet[1], "Direct Show Samples embedded in Ogg", 35) ) { decode_dshow_header(this, stream_num, &op); } else if (!memcmp (&op.packet[1], "text", 4)) { decode_text_header(this, stream_num, &op); } else if (!memcmp (&op.packet[1], "theora", 6)) { decode_theora_header(this, stream_num, &op); } else if (!memcmp (&op.packet[1], "FLAC", 4)) { decode_flac_header(this, stream_num, &op); } else if (!memcmp (&op.packet[0], "Annodex", 7)) { decode_annodex_header(this, stream_num, &op); } else if (!memcmp (&op.packet[0], "AnxData", 7)) { decode_anxdata_header(this, stream_num, &op); } else if (!memcmp (&op.packet[0], "CMML", 4)) { decode_cmml_header(this, stream_num, &op); } else if (!memcmp (&op.packet[0], "OpusHead", 8)) { decode_opus_header(this, stream_num, &op); } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "demux_ogg: unknown stream type (signature >%.8s<). hex dump of bos packet follows:\n", op.packet); if(this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) xine_hexdump (op.packet, op.bytes); this->si[stream_num]->buf_types = BUF_CONTROL_NOP; } } /* send preview buffer */ if (this->si[stream_num]->headers > 0 || op.packet[0] == PACKET_TYPE_COMMENT) { if (this->si[stream_num]->hide_first_header) this->si[stream_num]->hide_first_header = 0; else { lprintf ("sending preview buffer of stream type %08x\n", this->si[stream_num]->buf_types); send_ogg_buf (this, &op, stream_num, BUF_FLAG_HEADER); this->si[stream_num]->headers --; } } /* are we finished ? */ if (!ogg_page_bos(&this->og)) { int i; done = 1; for (i=0; i<this->num_streams; i++) { if (this->si[i]->headers > 0) done = 0; llprintf(DEBUG_PREVIEWS, "%d preview buffers left to send from stream %d\n", this->si[i]->headers, i); } } } } ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send(this->stream, &ui_event); /*get the streamlength*/ get_stream_length (this); } static int demux_ogg_send_chunk (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; int stream_num; int cur_serno; ogg_packet op; ogg_handle_event(this); llprintf(DEBUG_PACKETS, "send package...\n"); if (!read_ogg_packet(this)) { this->status = DEMUX_FINISHED; lprintf ("EOF\n"); return this->status; } if (!this->og.header || !this->og.body) { this->status = DEMUX_FINISHED; lprintf ("EOF\n"); return this->status; } /* now we've got one new page */ cur_serno = ogg_page_serialno (&this->og); stream_num = get_stream(this, cur_serno); if (stream_num < 0) { lprintf ("error: unknown stream, serialnumber %d\n", cur_serno); if (!ogg_page_bos(&this->og)) { lprintf ("help, stream with no beginning!\n"); } lprintf ("adding late stream with serial number %d (all content will be discarded)\n", cur_serno); if( this->num_streams == MAX_STREAMS ) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, "demux_ogg: MAX_STREAMS exceeded, aborting.\n"); this->status = DEMUX_FINISHED; return this->status; } stream_num = new_stream_info(this, cur_serno); } ogg_stream_pagein(&this->si[stream_num]->oss, &this->og); if (ogg_page_bos(&this->og)) { lprintf ("beginning of stream: serial number %d - discard\n", ogg_page_serialno (&this->og)); while (ogg_stream_packetout(&this->si[stream_num]->oss, &op) == 1) ; return this->status; } /*while keyframeseeking only process videostream*/ if (!this->ignore_keyframes && this->keyframe_needed && ((this->si[stream_num]->buf_types & 0xFF000000) != BUF_VIDEO_BASE)) return this->status; while (ogg_stream_packetout(&this->si[stream_num]->oss, &op) == 1) { /* printf("demux_ogg: packet: %.8s\n", op.packet); */ /* printf("demux_ogg: got a packet\n"); */ if ((*op.packet & PACKET_TYPE_HEADER) && (this->si[stream_num]->buf_types!=BUF_VIDEO_THEORA) && (this->si[stream_num]->buf_types!=BUF_AUDIO_SPEEX) && (this->si[stream_num]->buf_types!=BUF_AUDIO_FLAC)) { if (op.granulepos != -1) { this->si[stream_num]->header_granulepos = op.granulepos; lprintf ("header with granulepos, remembering granulepos\n"); } else { lprintf ("header => discard\n"); } continue; } /*discard granulepos-less packets and to early audiopackets*/ if (this->si[stream_num]->resync) { if ((this->si[stream_num]->buf_types & 0xFF000000) == BUF_SPU_BASE) { /*never drop subtitles*/ this->si[stream_num]->resync=0; } else if ((op.granulepos == -1) && (this->si[stream_num]->header_granulepos == -1)) { continue; } else { /*dump too early packets*/ if ((get_pts(this,stream_num,op.granulepos)-this->start_pts) > -90000) this->si[stream_num]->resync=0; else continue; } } if (!this->ignore_keyframes && this->keyframe_needed) { lprintf ("keyframe needed... buf_type=%08x\n", this->si[stream_num]->buf_types); if (this->si[stream_num]->buf_types == BUF_VIDEO_THEORA) { #ifdef HAVE_THEORA int keyframe_granule_shift; int64_t pframe=-1,iframe=-1; keyframe_granule_shift = this->si[stream_num]->granuleshift; if(op.granulepos>=0){ iframe=op.granulepos>>keyframe_granule_shift; pframe=op.granulepos-(iframe<<keyframe_granule_shift); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "seeking keyframe i %" PRId64 " p %" PRId64 "\n", iframe, pframe); if (pframe!=0) continue; } else continue; this->keyframe_needed = 0; this->start_pts=get_pts(this,stream_num,op.granulepos); #endif } else if ((this->si[stream_num]->buf_types & 0xFF000000) == BUF_VIDEO_BASE) { /*calculate the current pts*/ if (op.granulepos!=-1) { this->start_pts=get_pts(this, stream_num, op.granulepos); } else if (this->start_pts!=-1) this->start_pts=this->start_pts+this->frame_duration; /*seek the keyframe*/ if ((*op.packet == PACKET_IS_SYNCPOINT) && (this->start_pts!=-1)) this->keyframe_needed = 0; else continue; } else if ((this->si[stream_num]->buf_types & 0xFF000000) == BUF_VIDEO_BASE) continue; } send_ogg_buf (this, &op, stream_num, 0); /*delete used header_granulepos*/ if (op.granulepos == -1) this->si[stream_num]->header_granulepos = -1; } if (ogg_page_eos(&this->og)) { int i; int finished_streams = 0; lprintf("end of stream, serialnumber %d\n", cur_serno); this->si[stream_num]->delivered_eos = 1; /* check if all logical streams are finished */ for (i = 0; i < this->num_streams; i++) { finished_streams += this->si[i]->delivered_eos; } /* if all streams are finished, perhaps a chained stream follows */ if (finished_streams == this->num_streams) { /* delete current logical streams */ for (i = 0; i < this->num_streams; i++) { ogg_stream_clear(&this->si[i]->oss); if (this->si[i]->language) { free (this->si[i]->language); } free (this->si[i]); } this->num_streams = 0; this->num_audio_streams = 0; this->num_video_streams = 0; this->unhandled_video_streams = 0; this->num_spu_streams = 0; this->avg_bitrate = 1; /* try to read a chained stream */ this->send_newpts = 1; this->last_pts[0] = 0; this->last_pts[1] = 0; /* send control buffer to avoid buffer leak */ _x_demux_control_end(this->stream, 0); _x_demux_control_start(this->stream); send_header(this); } } return this->status; } static void demux_ogg_dispose (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; int i; for (i=0; i<this->num_streams; i++) { ogg_stream_clear(&this->si[i]->oss); if (this->si[i]->language) { free (this->si[i]->language); } free(this->si[i]); } ogg_sync_clear(&this->oy); #ifdef HAVE_THEORA theora_comment_clear (&this->t_comment); theora_info_clear (&this->t_info); #endif if (this->chapter_info){ free (this->chapter_info->entries); free (this->chapter_info); } for (i = 0; i < XINE_STREAM_INFO_MAX; ++i) free (this->meta[i]); if (this->event_queue) xine_event_dispose_queue (this->event_queue); free (this); } static int demux_ogg_get_status (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; return this->status; } static void demux_ogg_send_headers (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; this->video_fifo = this->stream->video_fifo; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* * send start buffers */ this->last_pts[0] = 0; this->last_pts[1] = 0; /* * initialize ogg engine */ ogg_sync_init(&this->oy); this->num_streams = 0; this->num_audio_streams = 0; this->num_video_streams = 0; this->num_spu_streams = 0; this->avg_bitrate = 1; if (this->input->seek (this->input, 0, SEEK_SET) != 0) this->status = DEMUX_FINISHED; if (this->status == DEMUX_OK) { _x_demux_control_start(this->stream); send_header (this); lprintf ("headers sent, avg bitrate is %" PRId64 "\n", this->avg_bitrate); } _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, this->num_video_streams > 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, this->num_video_streams > this->unhandled_video_streams); _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, this->num_audio_streams > 0); _x_stream_info_set(this->stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL, this->num_spu_streams); } static int demux_ogg_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_ogg_t *this = (demux_ogg_t *) this_gen; int i; start_time /= 1000; start_pos = (off_t) ( (double) start_pos / 65535 * this->input->get_length (this->input) ); /* * seek to start position */ if (INPUT_IS_SEEKABLE(this->input)) { this->keyframe_needed = (this->num_video_streams>0); if ( (!start_pos) && (start_time)) { if (this->time_length != -1) { /*do the seek via time*/ int current_time=-1; off_t current_pos; current_pos=this->input->get_current_pos(this->input); /*try to find out the current time*/ if (this->last_pts[PTS_VIDEO]) { current_time=this->last_pts[PTS_VIDEO]/90000; } else if (this->last_pts[PTS_AUDIO]) { current_time=this->last_pts[PTS_AUDIO]/90000; } /*fixme, the file could grow, do something about this->time_length using get_lenght to verify, that the stream hasn` changed its length, otherwise no seek to "new" data is possible*/ lprintf ("seek to time %d called\n",start_time); lprintf ("current time is %d\n",current_time); if (current_time > start_time) { /*seek between beginning and current_pos*/ /*fixme - sometimes we seek backwards and during keyframeseeking, we undo the seek*/ start_pos = start_time * current_pos / current_time ; } else { /*seek between current_pos and end*/ start_pos = current_pos + ((start_time - current_time) * ( this->input->get_length(this->input) - current_pos ) / ( (this->time_length / 1000) - current_time) ); } lprintf ("current_pos is %" PRId64 "\n",current_pos); lprintf ("new_pos is %" PRId64 "\n",start_pos); } else { /*seek using avg_bitrate*/ start_pos = start_time * this->avg_bitrate/8; } lprintf ("seeking to %d seconds => %" PRId64 " bytes\n", start_time, start_pos); } ogg_sync_reset(&this->oy); for (i=0; i<this->num_streams; i++) { this->si[i]->header_granulepos = -1; ogg_stream_reset(&this->si[i]->oss); } /*some strange streams have no syncpoint flag set at the beginning*/ if (start_pos == 0) this->keyframe_needed = 0; lprintf ("seek to %" PRId64 " called\n",start_pos); this->input->seek (this->input, start_pos, SEEK_SET); } /* fixme - this would be a nice position to do the following tasks 1. adjust an ogg videostream to a keyframe 2. compare the keyframe_pts with start_time. if the difference is to high (e.g. larger than max keyframe_intervall, do a new seek or continue reading 3. adjust the audiostreams in such a way, that the difference is not to high. In short words, do all the cleanups necessary to continue playback without further actions */ this->send_newpts = 1; this->status = DEMUX_OK; if( !playing ) { this->buf_flag_seek = 0; } else { if (start_pos!=0) { this->buf_flag_seek = 1; /*each stream has to continue with a packet that has an granulepos*/ for (i=0; i<this->num_streams; i++) { this->si[i]->resync = 1; } this->start_pts=-1; } _x_demux_flush_engine(this->stream); } return this->status; } static int demux_ogg_get_stream_length (demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; if (this->time_length==-1){ if (this->avg_bitrate) { return (int)((int64_t)1000 * this->input->get_length (this->input) * 8 / this->avg_bitrate); } else { return 0; } } else { return this->time_length; } } static uint32_t demux_ogg_get_capabilities(demux_plugin_t *this_gen) { demux_ogg_t *this = (demux_ogg_t *) this_gen; int cap_chapter = 0; if (this->chapter_info) cap_chapter = DEMUX_CAP_CHAPTERS; return DEMUX_CAP_SPULANG | DEMUX_CAP_AUDIOLANG | cap_chapter; } static int format_lang_string (demux_ogg_t * this, uint32_t buf_mask, uint32_t buf_type, int channel, char *str) { int stream_num; for (stream_num=0; stream_num<this->num_streams; stream_num++) { if ((this->si[stream_num]->buf_types & buf_mask) == buf_type) { if (this->si[stream_num]->language) { if (snprintf (str, XINE_LANG_MAX, "%s", this->si[stream_num]->language) >= XINE_LANG_MAX) /* the string got truncated */ str[XINE_LANG_MAX - 2] = str[XINE_LANG_MAX - 3] = str[XINE_LANG_MAX - 4] = '.'; /* TODO: provide long version in XINE_META_INFO_FULL_LANG */ } else { snprintf(str, XINE_LANG_MAX, "channel %d",channel); } return DEMUX_OPTIONAL_SUCCESS; } } return DEMUX_OPTIONAL_UNSUPPORTED; } static int demux_ogg_get_optional_data(demux_plugin_t *this_gen, void *data, int data_type) { demux_ogg_t *this = (demux_ogg_t *) this_gen; char *str=(char *) data; int channel = *((int *)data); switch (data_type) { case DEMUX_OPTIONAL_DATA_SPULANG: lprintf ("DEMUX_OPTIONAL_DATA_SPULANG channel = %d\n",channel); if (channel==-1) { strcpy( str, "none"); return DEMUX_OPTIONAL_SUCCESS; } else if ((channel>=0) && (channel<this->num_streams)) { return format_lang_string (this, 0xFFFFFFFF, BUF_SPU_OGM+channel, channel, str); } return DEMUX_OPTIONAL_UNSUPPORTED; case DEMUX_OPTIONAL_DATA_AUDIOLANG: lprintf ("DEMUX_OPTIONAL_DATA_AUDIOLANG channel = %d\n",channel); if (channel==-1) { return format_lang_string (this, 0xFF00001F, BUF_AUDIO_BASE, channel, str); } else if ((channel>=0) && (channel<this->num_streams)) { return format_lang_string (this, 0xFF00001F, BUF_AUDIO_BASE+channel, channel, str); } return DEMUX_OPTIONAL_UNSUPPORTED; default: return DEMUX_OPTIONAL_UNSUPPORTED; } } static int detect_ogg_content (int detection_method, input_plugin_t *input) { switch (detection_method) { case METHOD_BY_CONTENT: { uint32_t header; if (_x_demux_read_header(input, &header, 4) != 4) return 0; return !!( header == ME_FOURCC('O', 'g', 'g', 'S') ); } case METHOD_BY_MRL: case METHOD_EXPLICIT: return 1; default: return 0; } } static int detect_anx_content (int detection_method, input_plugin_t *input) { if (detect_ogg_content(detection_method, input) == 0) return 0; switch (detection_method) { #define ANNODEX_SIGNATURE_SEARCH 128 case METHOD_BY_CONTENT: { uint8_t buf[ANNODEX_SIGNATURE_SEARCH]; if (_x_demux_read_header(input, buf, ANNODEX_SIGNATURE_SEARCH) != ANNODEX_SIGNATURE_SEARCH) return 0; /* scan for 'Annodex' signature in the first 64 bytes */ return !!memmem(buf, ANNODEX_SIGNATURE_SEARCH, "Annodex", sizeof("Annodex")-1); } #undef ANNODEX_SIGNATURE_SEARCH case METHOD_BY_MRL: case METHOD_EXPLICIT: return 1; default: return 0; } } static demux_plugin_t *anx_open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_ogg_t *this; int i; if (detect_anx_content(stream->content_detection_method, input) == 0) return NULL; /* * if we reach this point, the input has been accepted. */ this = calloc(1, sizeof(demux_ogg_t)); if (!this) return NULL; this->stream = stream; this->input = input; /* the Annodex demuxer currently calls into exactly the same functions as * the Ogg demuxer, which seems to make this function a bit redundant, but * this design leaves us a bit more room to change an Annodex demuxer's * behaviour in the future if necessary */ this->demux_plugin.send_headers = demux_ogg_send_headers; this->demux_plugin.send_chunk = demux_ogg_send_chunk; this->demux_plugin.seek = demux_ogg_seek; this->demux_plugin.dispose = demux_ogg_dispose; this->demux_plugin.get_status = demux_ogg_get_status; this->demux_plugin.get_stream_length = demux_ogg_get_stream_length; this->demux_plugin.get_capabilities = demux_ogg_get_capabilities; this->demux_plugin.get_optional_data = demux_ogg_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; #ifdef HAVE_THEORA theora_info_init (&this->t_info); theora_comment_init (&this->t_comment); #endif for (i = 0; i < XINE_STREAM_INFO_MAX; ++i) this->meta[i] = NULL; this->chapter_info = 0; this->event_queue = xine_event_new_queue (this->stream); return &this->demux_plugin; } static demux_plugin_t *ogg_open_plugin (demux_class_t *class_gen, xine_stream_t *stream, input_plugin_t *input) { demux_ogg_t *this; int i; if (detect_ogg_content(stream->content_detection_method, input) == 0) return NULL; /* * if we reach this point, the input has been accepted. */ this = calloc(1, sizeof(demux_ogg_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_ogg_send_headers; this->demux_plugin.send_chunk = demux_ogg_send_chunk; this->demux_plugin.seek = demux_ogg_seek; this->demux_plugin.dispose = demux_ogg_dispose; this->demux_plugin.get_status = demux_ogg_get_status; this->demux_plugin.get_stream_length = demux_ogg_get_stream_length; this->demux_plugin.get_capabilities = demux_ogg_get_capabilities; this->demux_plugin.get_optional_data = demux_ogg_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; #ifdef HAVE_THEORA theora_info_init (&this->t_info); theora_comment_init (&this->t_comment); #endif this->chapter_info = 0; for (i = 0; i < XINE_STREAM_INFO_MAX; ++i) this->meta[i] = NULL; this->event_queue = xine_event_new_queue (this->stream); return &this->demux_plugin; } /* * Annodex demuxer class */ void *anx_init_class (xine_t *xine, const void *data) { demux_anx_class_t *this; (void)xine; (void)data; this = calloc(1, sizeof(demux_anx_class_t)); if (!this) return NULL; this->demux_class.open_plugin = anx_open_plugin; this->demux_class.description = N_("Annodex demux plugin"); this->demux_class.identifier = "Annodex"; this->demux_class.mimetypes = "application/annodex: anx: Annodex media;" "application/x-annodex: anx: Annodex media;" "audio/annodex: axa: Annodex audio;" "audio/x-annodex: axa: Annodex audio;" "video/annodex: axv: Annodex video;" "video/x-annodex: axv: Annodex video;"; this->demux_class.extensions = "anx axa axv"; this->demux_class.dispose = default_demux_class_dispose; return this; } /* * ogg demuxer class */ void *ogg_init_class (xine_t *xine, const void *data) { demux_ogg_class_t *this; (void)xine; (void)data; this = calloc(1, sizeof(demux_ogg_class_t)); if (!this) return NULL; this->demux_class.open_plugin = ogg_open_plugin; this->demux_class.description = N_("OGG demux plugin"); this->demux_class.identifier = "OGG"; this->demux_class.mimetypes = "application/ogg: ogx: Ogg Stream;" "application/x-ogm: ogx: Ogg Stream;" "application/x-ogm-audio: oga: Ogg Audio;" "application/x-ogm-video: ogv: Ogg Video;" "application/x-ogg: ogx: Ogg Stream;" "audio/ogg: oga: Ogg Audio;" "audio/opus: opus: Opus Audio;" "audio/x-ogg: oga: Ogg Audio;" "video/ogg: ogv: Ogg Video;" "video/x-ogg: ogv: Ogg Video;"; this->demux_class.extensions = "ogx ogv oga ogg spx ogm opus"; this->demux_class.dispose = default_demux_class_dispose; return this; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/xine_theora_decoder.c�����������������������������������������������������0000644�0001750�0001750�00000032445�14647725152�017401� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine decoder plugin using libtheora */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <inttypes.h> #include <string.h> #include <pthread.h> #include <math.h> #include <theora/theora.h> #define LOG_MODULE "theora_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/metronom.h> #include <xine/xineutils.h> #include "ogg_combined.h" typedef struct theora_decoder_s { video_decoder_t theora_decoder; theora_info t_info; theora_comment t_comment; theora_state t_state; ogg_packet op; yuv_buffer yuv; xine_stream_t* stream; int reject; int op_max_size; unsigned char* packet; int done; int width, height; double ratio; int offset_x, offset_y; int frame_duration; int skipframes; int hp_read; int initialized; } theora_decoder_t; static void readin_op (theora_decoder_t *this, unsigned char* src, int size) { if ( this->done+size > this->op_max_size) { while (this->op_max_size < this->done+size) this->op_max_size=this->op_max_size*2; this->packet=realloc(this->packet, this->op_max_size); this->op.packet=this->packet; } xine_fast_memcpy ( this->packet+this->done, src, size); this->done=this->done+size; } static void yuv2frame(yuv_buffer *yuv, vo_frame_t *frame, int offset_x, int offset_y, unsigned pixel_format) { int x, y; int crop_offset_y, crop_offset_c; /* fixme - direct rendering (exchaning pointers) may be possible. * frame->base[0] = yuv->y could work if one could change the * pitches[0,1,2] values, and rely on the drawing routine using * the new pitches. With cropping and offsets, it's a bit trickier, * but it would still be possible. * Attempts at doing this have yielded nothing but SIGSEVs so far. */ /* Copy yuv data onto the frame. Cropping and offset as specified * by the frame_width, frame_height, offset_x and offset_y fields * in the theora header is carried out. */ if (pixel_format == OC_PF_444) { /* downsample */ init_yuv_conversion(); crop_offset_y = offset_x + yuv->y_stride * offset_y; crop_offset_c = offset_x + yuv->uv_stride * offset_y; yuv_planes_t yuv_planes; yuv_planes.y = yuv->y + crop_offset_y; yuv_planes.u = yuv->u + crop_offset_c; yuv_planes.v = yuv->v + crop_offset_c; yuv_planes.row_width = frame->width; yuv_planes.row_count = 1; for (y = 0; y < frame->height; y++) { yuv444_to_yuy2(&yuv_planes, frame->base[0] + frame->pitches[0] * y, frame->pitches[0]); yuv_planes.y += yuv->y_stride; yuv_planes.u += yuv->uv_stride; yuv_planes.v += yuv->uv_stride; } } else if (pixel_format == OC_PF_422) { /* interleave */ crop_offset_y = offset_x + yuv->y_stride * offset_y; crop_offset_c = offset_x/2 + yuv->uv_stride * offset_y; for (y = 0; y < frame->height; y++) { uint8_t *dst = frame->base[0] + frame->pitches[0] * y; uint8_t *src_y = yuv->y + crop_offset_y + yuv->y_stride * y; uint8_t *src_u = yuv->u + crop_offset_c + yuv->uv_stride * y; uint8_t *src_v = yuv->v + crop_offset_c + yuv->uv_stride * y; for (x = 0; x < frame->width/2; x++) { *dst++ = *src_y++; *dst++ = *src_u++; *dst++ = *src_y++; *dst++ = *src_v++; } } } else /*if (pixel_format == OC_PF_420)*/ { crop_offset_y = offset_x + yuv->y_stride * offset_y; crop_offset_c = offset_x/2 + yuv->uv_stride * (offset_y/2); for (y = 0; y < frame->height; y++) xine_fast_memcpy(frame->base[0] + frame->pitches[0] * y, yuv->y + crop_offset_y + yuv->y_stride * y, frame->width); for(y = 0; y < frame->height/2; y++) { xine_fast_memcpy(frame->base[1] + frame->pitches[1] * y, yuv->u + crop_offset_c + yuv->uv_stride * y, frame->width/2); xine_fast_memcpy(frame->base[2] + frame->pitches[2] * y, yuv->v + crop_offset_c + yuv->uv_stride * y, frame->width/2); } } } static int collect_data (theora_decoder_t *this, buf_element_t *buf ) { /* Assembles an ogg_packet which was sent with send_ogg_packet over xinebuffers */ /* this->done, this->rejected, this->op and this->decoder->flags are needed*/ if (buf->decoder_flags & BUF_FLAG_FRAME_START) { this->done=0; /*start from the beginnig*/ this->reject=0;/*new packet - new try*/ /*copy the ogg_packet struct and the sum, correct the adress of the packet*/ xine_fast_memcpy (&this->op, buf->content, sizeof(ogg_packet)); this->op.packet=this->packet; readin_op (this, buf->content + sizeof(ogg_packet), buf->size - sizeof(ogg_packet) ); /*read the rest of the data*/ } else { if (this->done==0 || this->reject) { /*we are starting to collect an packet without the beginnig reject the rest*/ printf ("libtheora: rejecting packet\n"); this->reject=1; return 0; } readin_op (this, buf->content, buf->size ); } if ((buf->decoder_flags & BUF_FLAG_FRAME_END) && !this->reject) { if ( this->done != this->op.bytes ) { printf ("libtheora: A packet changed its size during transfer - rejected\n"); printf (" size %d should be %ld\n", this->done , this->op.bytes); this->op.bytes=this->done; } return 1; } return 0; } static void theora_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { /* * decode data from buf and feed decoded frames to * video output */ theora_decoder_t *this = (theora_decoder_t *) this_gen; vo_frame_t *frame; yuv_buffer yuv; int ret; if (!collect_data(this, buf)) return; /*return, until a entire packets is collected*/ if ( (buf->decoder_flags & BUF_FLAG_HEADER) && !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { /*get the first 3 packets and decode the header during preview*/ if (this->hp_read==0) { /*decode first hp*/ if (theora_decode_header(&this->t_info, &this->t_comment, &this->op)>=0) { this->hp_read++; return; } } if (this->hp_read==1) { /*decode three header packets*/ if (theora_decode_header(&this->t_info, &this->t_comment,&this->op)) { printf ("libtheora: Was unable to decode header #%d, corrupt stream?\n",this->hp_read); } else { this->hp_read++; return; } } if (this->hp_read==2) { if (theora_decode_header(&this->t_info, &this->t_comment,&this->op)) { printf ("libtheora: Was unable to decode header #%d, corrupt stream?\n",this->hp_read); } /*headers are now decoded. initialize the decoder*/ theora_decode_init (&this->t_state, &this->t_info); lprintf("theora stream is Theora %dx%d %.02f fps video.\n" " frame content is %dx%d with offset (%d,%d).\n" " pixel aspect is %d:%d.\n", this->t_info.width,this->t_info.height, (double)this->t_info.fps_numerator/this->t_info.fps_denominator, this->t_info.frame_width, this->t_info.frame_height, this->t_info.offset_x, this->t_info.offset_y, this->t_info.aspect_numerator, this->t_info.aspect_denominator); this->frame_duration=((int64_t)90000*this->t_info.fps_denominator)/this->t_info.fps_numerator; this->width=this->t_info.frame_width; this->height=this->t_info.frame_height; if (this->t_info.aspect_numerator==0 || this->t_info.aspect_denominator==0) /* 0-values are undefined, so don't do any scaling. */ this->ratio=(double)this->width/(double)this->height; else /* Yes, this video needs to be scaled. */ this->ratio=(double)(this->width*this->t_info.aspect_numerator) / (double)(this->height*this->t_info.aspect_denominator); this->offset_x=this->t_info.offset_x; this->offset_y=this->t_info.offset_y; this->initialized=1; this->hp_read++; } } else if (buf->decoder_flags & BUF_FLAG_HEADER) { /*ignore headerpackets*/ return; } else { /*decode videodata*/ if (!this->initialized) { printf ("libtheora: cannot decode stream without header\n"); return; } ret=theora_decode_packetin( &this->t_state, &this->op); if ( ret!=0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libtheora:Received an bad packet\n"); } else if (!this->skipframes) { int format; theora_decode_YUVout(&this->t_state,&yuv); /* pixel format */ switch (this->t_state.i->pixelformat) { case OC_PF_444: format = XINE_IMGFMT_YUY2; break; case OC_PF_422: format = XINE_IMGFMT_YUY2; break; case OC_PF_420: format = XINE_IMGFMT_YV12; break; default: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, "libtheora: unknown pixel format %u\n", (unsigned)this->t_state.i->pixelformat); format = XINE_IMGFMT_YV12; break; } /*fixme - aspectratio from theora is not considered*/ frame = this->stream->video_out->get_frame( this->stream->video_out, this->width, this->height, this->ratio, format, VO_BOTH_FIELDS); yuv2frame(&yuv, frame, this->offset_x, this->offset_y, this->t_state.i->pixelformat); frame->pts = buf->pts; frame->duration=this->frame_duration; this->skipframes=frame->draw(frame, this->stream); frame->free(frame); } else { this->skipframes=this->skipframes-1; } } } static void theora_flush (video_decoder_t *this_gen) { /* * flush out any frames that are still stored in the decoder */ theora_decoder_t *this = (theora_decoder_t *) this_gen; this->skipframes=0; } static void theora_reset (video_decoder_t *this_gen) { /* * reset decoder after engine flush (prepare for new * video data not related to recently decoded data) */ theora_decoder_t *this = (theora_decoder_t *) this_gen; this->skipframes=0; } static void theora_discontinuity (video_decoder_t *this_gen) { /* * inform decoder that a time reference discontinuity has happened. * that is, it must forget any currently held pts value */ theora_decoder_t *this = (theora_decoder_t *) this_gen; this->skipframes=0; } static void theora_dispose (video_decoder_t *this_gen) { /* * close down, free all resources */ theora_decoder_t *this = (theora_decoder_t *) this_gen; lprintf ("dispose \n"); theora_clear (&this->t_state); theora_comment_clear (&this->t_comment); theora_info_clear (&this->t_info); this->stream->video_out->close(this->stream->video_out, this->stream); free (this->packet); free (this); } static video_decoder_t *theora_open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { /* * open a new instance of this plugin class */ theora_decoder_t *this ; (void)class_gen; this = (theora_decoder_t *) calloc(1, sizeof(theora_decoder_t)); if (!this) return NULL; this->theora_decoder.decode_data = theora_decode_data; this->theora_decoder.flush = theora_flush; this->theora_decoder.reset = theora_reset; this->theora_decoder.discontinuity = theora_discontinuity; this->theora_decoder.dispose = theora_dispose; this->stream = stream; this->op_max_size = 4096; this->packet = malloc(this->op_max_size); this->done = 0; this->stream = stream; this->initialized = 0; theora_comment_init (&this->t_comment); theora_info_init (&this->t_info); (stream->video_out->open) (stream->video_out, stream); return &this->theora_decoder; } /* * theora plugin class */ void *theora_init_plugin (xine_t *xine, const void *data) { /*initialize our plugin*/ static const video_decoder_class_t decode_theora_class = { .open_plugin = theora_open_plugin, .identifier = "theora video", .description = N_("theora video decoder plugin"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&decode_theora_class; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/wavpack_combined.h��������������������������������������������������������0000644�0001750�0001750�00000003557�14647725152�016712� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2007-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> */ #include <xine/os_types.h> #include <xine/attributes.h> #include "bswap.h" typedef struct { uint32_t idcode; /* This should always be the string "wvpk" */ uint32_t block_size; /* Size of the rest of the frame */ uint16_t wv_version; /* Version of the wavpack, 0x0403 should be latest */ uint8_t track; /* Unused, has to be 0 */ uint8_t index; /* Unused, has to be 0 */ uint32_t file_samples; /* (uint32_t)-1 if unknown, else the total number of samples for the file */ uint32_t samples_index; /* Index of the first sample in block, from the start of the file */ uint32_t samples_count; /* Count of samples in the current frame */ uint32_t flags; /* Misc flags */ uint32_t decoded_crc32; /* CRC32 of the decoded data */ } XINE_PACKED wvheader_t; static const uint32_t wvpk_signature = ME_FOURCC('w', 'v', 'p', 'k'); void *demux_wv_init_plugin (xine_t *xine, const void *data); void *decoder_wavpack_init_plugin (xine_t *xine, const void *data); �������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/wavpack_demuxer.c���������������������������������������������������������0000644�0001750�0001750�00000026461�14647725152�016575� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2006-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #define LOG_MODULE "demux_wavpack" #define LOG_VERBOSE #define LOG #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/demux.h> #include "bswap.h" #include <xine/attributes.h> #include <wavpack/wavpack.h> #include "wavpack_combined.h" typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; fifo_buffer_t *audio_fifo; input_plugin_t *input; int status; uint32_t current_sample; uint32_t samples; uint32_t samplerate; uint16_t bits_per_sample:6; uint16_t channels:4; } demux_wv_t; static int32_t xine_input_read_bytes(void *const this_gen, void *const data, const int32_t bcount) { input_plugin_t *const this = (input_plugin_t*)this_gen; return this->read(this, data, bcount); } static uint32_t xine_input_get_pos(void *const this_gen) { input_plugin_t *const this = (input_plugin_t*)this_gen; return this->get_current_pos(this); } static int xine_input_set_pos_abs(void *const this_gen, const uint32_t pos) { input_plugin_t *const this = (input_plugin_t*)this_gen; return this->seek(this, pos, SEEK_SET); } static int xine_input_set_pos_rel(void *const this_gen, const int32_t delta, const int mode) { input_plugin_t *const this = (input_plugin_t*)this_gen; return this->seek(this, delta, mode); } static int xine_input_push_back_byte(void *const this_gen, const int c) { input_plugin_t *const this = (input_plugin_t*)this_gen; if ( this->seek(this, -1, SEEK_CUR) ) { return c; } else { lprintf("xine_input_push_back_byte: unable to seek.\n"); return EOF; } } static uint32_t xine_input_get_length(void *const this_gen) { input_plugin_t *const this = (input_plugin_t*)this_gen; return this->get_length(this); } static int xine_input_can_seek(void *const this_gen) { input_plugin_t *const this = (input_plugin_t*)this_gen; return INPUT_IS_SEEKABLE(this); } static int32_t xine_input_write_bytes(__attr_unused void *const id, __attr_unused void *const data, __attr_unused const int32_t bcount) { lprintf("xine_input_write_bytes: access is read-only.\n"); return 0; } static WavpackStreamReader wavpack_input_reader = { .read_bytes = xine_input_read_bytes, .get_pos = xine_input_get_pos, .set_pos_abs = xine_input_set_pos_abs, .set_pos_rel = xine_input_set_pos_rel, .push_back_byte = xine_input_push_back_byte, .get_length = xine_input_get_length, .can_seek = xine_input_can_seek, .write_bytes = xine_input_write_bytes }; static int open_wv_file(demux_wv_t *const this) { WavpackContext *ctx = NULL; char error[256]; /* Current version of wavpack (4.31) does not write more than this */ wvheader_t header; uint32_t tmp; /* Right now we don't support non-seekable streams */ if (! INPUT_IS_SEEKABLE(this->input) ) { lprintf("open_wv_file: non-seekable inputs aren't supported yet.\n"); return 0; } /* Read the file header */ if (_x_demux_read_header(this->input, (uint8_t*)(&header), sizeof(wvheader_t)) != sizeof(wvheader_t)) return 0; /* Validate header, we currently support only Wavpack 4 */ if ( header.idcode != wvpk_signature || (le2me_16(header.wv_version) >> 8) != 4 ) return 0; /* Rewind */ this->input->seek(this->input, 0, SEEK_SET); ctx = WavpackOpenFileInputEx(&wavpack_input_reader, this->input, NULL, error, 0, 0); if ( ! ctx ) { lprintf("xine_open_wavpack_input: unable to open the stream: %s\n", error); return 0; } this->current_sample = 0; this->samples = WavpackGetNumSamples(ctx); lprintf("number of samples: %u\n", this->samples); this->samplerate = WavpackGetSampleRate(ctx); lprintf("samplerate: %u Hz\n", this->samplerate); tmp = WavpackGetBitsPerSample(ctx); _x_assert(tmp <= 32); lprintf("bits_per_sample: %u\n", tmp); this->bits_per_sample = tmp; tmp = WavpackGetNumChannels(ctx); _x_assert(tmp <= 8); lprintf("channels: %u\n", tmp); this->channels = tmp; _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_FOURCC, wvpk_signature); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_CHANNELS, this->channels); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->samplerate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITS, this->bits_per_sample); WavpackCloseFile(ctx); this->input->seek(this->input, SEEK_SET, 0); return 1; } static int demux_wv_send_chunk(demux_plugin_t *const this_gen) { demux_wv_t *const this = (demux_wv_t *) this_gen; uint32_t bytes_to_read; uint8_t header_sent = 0; wvheader_t header; lprintf("new frame\n"); /* Check if we've finished */ if (this->current_sample >= this->samples) { lprintf("all frames read\n"); this->status = DEMUX_FINISHED; return this->status; } lprintf("current sample: %u\n", this->current_sample); do { if ( this->input->read(this->input, (uint8_t*)(&header), sizeof(wvheader_t)) != sizeof(wvheader_t) ) { this->status = DEMUX_FINISHED; return this->status; } /* The size of the block is «of course» minus 8, and it also includes the size of the header. */ bytes_to_read = le2me_32(header.block_size) + 8 - sizeof(wvheader_t); lprintf("demux_wavpack: going to read %u bytes.\n", bytes_to_read); while(bytes_to_read) { off_t bytes_read = 0, bytes_to_read_now, offset = 0; buf_element_t *buf = NULL; int64_t input_time_guess; /* Get a buffer */ buf = this->audio_fifo->buffer_pool_alloc(this->audio_fifo); buf->type = BUF_AUDIO_WAVPACK; buf->decoder_flags = 0; /* Set normalised position */ buf->extra_info->input_normpos = (int) ((double) this->input->get_current_pos(this->input) * 65535 / this->input->get_length(this->input)); buf->pts = (((this->current_sample) / this->samplerate))*90000; lprintf("Sending buffer with PTS %"PRId64"\n", buf->pts); /* Set time */ input_time_guess = this->samples; input_time_guess /= this->samplerate; input_time_guess *= 1000; input_time_guess *= buf->extra_info->input_normpos; input_time_guess /= 65535; buf->extra_info->input_time = input_time_guess; if ( ! header_sent ) offset = sizeof(wvheader_t); bytes_to_read_now = ( bytes_to_read+offset > buf->max_size ) ? buf->max_size-offset : bytes_to_read; if ( ! header_sent ) { header_sent = 1; xine_fast_memcpy(buf->content, &header, sizeof(wvheader_t)); } bytes_read = this->input->read(this->input, &buf->content[offset], bytes_to_read_now); buf->size = offset + bytes_read; bytes_to_read -= bytes_read; if ( bytes_to_read <= 0 && (le2me_32(header.flags) & FINAL_BLOCK) == FINAL_BLOCK) buf->decoder_flags |= BUF_FLAG_FRAME_END; this->audio_fifo->put(this->audio_fifo, buf); } } while ( (le2me_32(header.flags) & FINAL_BLOCK) != FINAL_BLOCK ); this->current_sample += le2me_32(header.samples_count); return this->status; } static void demux_wv_send_headers(demux_plugin_t *const this_gen) { demux_wv_t *const this = (demux_wv_t *) this_gen; buf_element_t *buf; this->audio_fifo = this->stream->audio_fifo; this->status = DEMUX_OK; /* Send start buffers */ _x_demux_control_start(this->stream); /* Send header to decoder */ if (this->audio_fifo) { buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo); buf->type = BUF_AUDIO_WAVPACK; buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_STDHEADER|BUF_FLAG_FRAME_END; buf->decoder_info[0] = this->input->get_length(this->input); buf->decoder_info[1] = this->samplerate; buf->decoder_info[2] = this->bits_per_sample; buf->decoder_info[3] = this->channels; buf->size = 0; this->audio_fifo->put (this->audio_fifo, buf); } } static int demux_wv_seek (demux_plugin_t *this_gen, off_t start_pos, int start_time, int playing) { demux_wv_t *const this = (demux_wv_t *) this_gen; (void)start_pos; (void)start_time; /* If thread is not running, initialize demuxer */ if( !playing ) { /* send new pts */ _x_demux_control_newpts(this->stream, 0, 0); this->status = DEMUX_OK; } return this->status; } static int demux_wv_get_status (demux_plugin_t *const this_gen) { const demux_wv_t *const this = (const demux_wv_t *) this_gen; return this->status; } static int demux_wv_get_stream_length (demux_plugin_t *const this_gen) { const demux_wv_t *const this = (demux_wv_t *) this_gen; return (this->samples*1000) / this->samplerate; } static uint32_t demux_wv_get_capabilities(demux_plugin_t *const this_gen) { (void)this_gen; return DEMUX_CAP_NOCAP; } static int demux_wv_get_optional_data(demux_plugin_t *const this_gen, void *data, const int data_type) { (void)this_gen; (void)data; (void)data_type; return DEMUX_OPTIONAL_UNSUPPORTED; } static demux_plugin_t *open_plugin (demux_class_t *const class_gen, xine_stream_t *const stream, input_plugin_t *const input) { demux_wv_t *const this = calloc(1, sizeof (demux_wv_t)); if (!this) return NULL; this->stream = stream; this->input = input; this->demux_plugin.send_headers = demux_wv_send_headers; this->demux_plugin.send_chunk = demux_wv_send_chunk; this->demux_plugin.seek = demux_wv_seek; this->demux_plugin.dispose = default_demux_plugin_dispose; this->demux_plugin.get_status = demux_wv_get_status; this->demux_plugin.get_stream_length = demux_wv_get_stream_length; this->demux_plugin.get_capabilities = demux_wv_get_capabilities; this->demux_plugin.get_optional_data = demux_wv_get_optional_data; this->demux_plugin.demux_class = class_gen; this->status = DEMUX_FINISHED; switch (stream->content_detection_method) { case METHOD_BY_MRL: case METHOD_BY_CONTENT: case METHOD_EXPLICIT: if (!open_wv_file(this)) { free (this); return NULL; } break; default: free (this); return NULL; } return &this->demux_plugin; } void *demux_wv_init_plugin (xine_t *xine, const void *data) { static const demux_class_t this = { .open_plugin = open_plugin, .description = N_("Wavpack demux plugin"), .identifier = "Wavpack", .mimetypes = "audio/x-wavpack: wv,wvp: WavPack audio;", .extensions = "wv wvp", .dispose = NULL }; (void)xine; (void)data; return (demux_class_t *)&this; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/nsf_combined.c������������������������������������������������������������0000644�0001750�0001750�00000002747�14647725152�016037� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2007-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include "nsf_combined.h" static const demuxer_info_t demux_info_nsf = { 10 /* priority */ }; static const uint32_t audio_types[] = { BUF_AUDIO_NSF, 0 }; static const decoder_info_t decoder_info_nsf = { audio_types, /* supported types */ 5 /* priority */ }; const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_DEMUX, 27, "nsfdemux", XINE_VERSION_CODE, &demux_info_nsf, demux_nsf_init_plugin }, { PLUGIN_AUDIO_DECODER, 16, "nsfdec", XINE_VERSION_CODE, &decoder_info_nsf, decoder_nsf_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������xine-lib-1.2/src/combined/ogg_combined.c������������������������������������������������������������0000644�0001750�0001750�00000004667�14647725152�016030� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2007-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include <xine/xine_plugin.h> #include "ogg_combined.h" static const demuxer_info_t demux_info_anx = { .priority = 20, }; static const demuxer_info_t demux_info_ogg = { .priority = 10, }; #ifdef HAVE_VORBIS static const uint32_t vorbis_audio_types[] = { BUF_AUDIO_VORBIS, 0 }; static const decoder_info_t dec_info_vorbis = { .supported_types = vorbis_audio_types, .priority = 5, }; #endif /* HAVE_VORBIS */ #ifdef HAVE_SPEEX static const uint32_t speex_audio_types[] = { BUF_AUDIO_SPEEX, 0 }; static const decoder_info_t dec_info_speex = { .supported_types = speex_audio_types, .priority = 5, }; #endif /* HAVE_SPEEX */ #ifdef HAVE_THEORA static const uint32_t theora_video_types[] = { BUF_VIDEO_THEORA, 0 }; static const decoder_info_t dec_info_theora = { .supported_types = theora_video_types, .priority = 5, }; #endif /* HAVE_THEORA */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_DEMUX, 27, "ogg", XINE_VERSION_CODE, &demux_info_ogg, ogg_init_class }, { PLUGIN_DEMUX, 27, "anx", XINE_VERSION_CODE, &demux_info_anx, anx_init_class }, #ifdef HAVE_VORBIS { PLUGIN_AUDIO_DECODER, 16, "vorbis", XINE_VERSION_CODE, &dec_info_vorbis, vorbis_init_plugin }, #endif #ifdef HAVE_SPEEX { PLUGIN_AUDIO_DECODER, 16, "speex", XINE_VERSION_CODE, &dec_info_speex, speex_init_plugin }, #endif #ifdef HAVE_THEORA { PLUGIN_VIDEO_DECODER, 19, "theora", XINE_VERSION_CODE, &dec_info_theora, theora_init_plugin }, #endif { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������xine-lib-1.2/src/combined/wavpack_decoder.c���������������������������������������������������������0000644�0001750�0001750�00000023144�14647725152�016524� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2007-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * xine interface to libwavpack by Diego Pettenò <flameeyes@gmail.com> */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #define LOG_MODULE "decode_wavpack" #define LOG_VERBOSE #include <xine/xine_internal.h> #include <xine/attributes.h> #include "bswap.h" #include <wavpack/wavpack.h> #include "wavpack_combined.h" typedef struct { audio_decoder_t audio_decoder; xine_stream_t *stream; uint8_t *buf; size_t buf_size; size_t buf_pos; int sample_rate; uint16_t bits_per_sample:6; uint16_t channels:4; uint16_t output_open:1; } wavpack_decoder_t; /* Wrapper functions for Wavpack */ static int32_t xine_buffer_read_bytes(void *const this_gen, void *const data, int32_t bcount) { wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; if ( bcount <= 0 ) return 0; if ( (size_t)bcount > (this->buf_size - this->buf_pos) ) bcount = (this->buf_size - this->buf_pos); xine_fast_memcpy(data, this->buf + this->buf_pos, bcount); this->buf_pos += bcount; return bcount; } static uint32_t xine_buffer_get_pos(void *const this_gen) { wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; return this->buf_pos; } static int xine_buffer_set_pos_rel(void *const this_gen, const int32_t delta, const int mode) { wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; switch(mode) { case SEEK_SET: if ( delta < 0 || (size_t)delta > this->buf_size ) return -1; this->buf_pos = delta; return 0; case SEEK_CUR: if ( ((ssize_t)this->buf_pos+delta) < 0 || (this->buf_pos+delta) > this->buf_size ) return -1; this->buf_pos += delta; return 0; case SEEK_END: if ( delta < 0 || (size_t)delta > this->buf_size ) return -1; this->buf_pos = this->buf_size - delta; return 0; default: return -1; } return -1; } static int xine_buffer_set_pos_abs(void *const this_gen, const uint32_t pos) { return xine_buffer_set_pos_rel(this_gen, pos, SEEK_SET); } static int xine_buffer_push_back_byte(void *const this_gen, const int c) { if ( ! xine_buffer_set_pos_rel(this_gen, -1, SEEK_CUR) ) return EOF; return c; } static uint32_t xine_buffer_get_length(void *const this_gen) { wavpack_decoder_t *const this = (wavpack_decoder_t*)this_gen; return this->buf_size; } static int xine_buffer_can_seek(void *const this_gen) { (void)this_gen; return 1; } static int32_t xine_buffer_write_bytes(__attr_unused void *const id, __attr_unused void *const data, __attr_unused const int32_t bcount) { lprintf("xine_buffer_write_bytes: access is read-only.\n"); return 0; } /* Wavpack plugin functions */ static void wavpack_reset (audio_decoder_t *const this_gen) { wavpack_decoder_t *const this = (wavpack_decoder_t *) this_gen; this->buf_pos = 0; } static void wavpack_discontinuity (audio_decoder_t *const this_gen) { /* wavpack_decoder_t *this = (wavpack_decoder_t *) this_gen; */ (void)this_gen; lprintf("Discontinuity!\n"); } static void wavpack_decode_data (audio_decoder_t *const this_gen, buf_element_t *const buf) { wavpack_decoder_t *const this = (wavpack_decoder_t *) this_gen; /* We are getting the stream header, open up the audio * device, and collect information about the stream */ if (buf->decoder_flags & BUF_FLAG_STDHEADER) { int mode = AO_CAP_MODE_MONO; this->sample_rate = buf->decoder_info[1]; _x_assert(buf->decoder_info[2] <= 32); this->bits_per_sample = buf->decoder_info[2]; _x_assert(buf->decoder_info[3] <= 8); this->channels = buf->decoder_info[3]; mode = _x_ao_channels2mode(this->channels); _x_meta_info_set(this->stream, XINE_META_INFO_AUDIOCODEC, "WavPack"); if (!this->output_open) { this->output_open = (this->stream->audio_out->open) ( this->stream->audio_out, this->stream, this->bits_per_sample, this->sample_rate, mode) ? 1 : 0; } this->buf_pos = 0; } else if (this->output_open) { /* This isn't a header frame and we have opened the output device */ /* What we have buffered so far, and what is coming in * is larger than our buffer */ if (this->buf_pos + buf->size > this->buf_size) { this->buf_size += 2 * buf->size; this->buf = realloc (this->buf, this->buf_size); lprintf("reallocating buffer to %zd\n", this->buf_size); } xine_fast_memcpy (&this->buf[this->buf_pos], buf->content, buf->size); this->buf_pos += buf->size; if ( buf->decoder_flags & BUF_FLAG_FRAME_END ) { static WavpackStreamReader wavpack_buffer_reader = { .read_bytes = xine_buffer_read_bytes, .get_pos = xine_buffer_get_pos, .set_pos_abs = xine_buffer_set_pos_abs, .set_pos_rel = xine_buffer_set_pos_rel, .push_back_byte = xine_buffer_push_back_byte, .get_length = xine_buffer_get_length, .can_seek = xine_buffer_can_seek, .write_bytes = xine_buffer_write_bytes }; WavpackContext *ctx = NULL; /* Current version of wavpack (4.40) does not write more than this */ char error[256] = { 0, }; uint32_t samples_left; /*uint32_t samples_total;*/ const wvheader_t *header = (const wvheader_t*)this->buf; this->buf_pos = 0; if ( le2me_32(header->samples_count) == 0 ) return; ctx = WavpackOpenFileInputEx(&wavpack_buffer_reader, this, NULL, error, OPEN_STREAMING, 0); if ( ! ctx ) { lprintf("unable to open the stream: %s\n", error); this->buf_pos = 0; return; } samples_left = /*samples_total =*/ header->samples_count; while ( samples_left > 0 ) { uint32_t buf_samples, decoded_count; audio_buffer_t *audio_buffer = this->stream->audio_out->get_buffer(this->stream->audio_out); int32_t *decoded; unsigned int i; buf_samples = audio_buffer->mem_size / (this->channels * (this->bits_per_sample/8)); if ( buf_samples > samples_left ) buf_samples = samples_left; decoded = alloca(buf_samples * this->channels * sizeof(int32_t)); decoded_count = WavpackUnpackSamples(ctx, decoded, buf_samples); if ( decoded_count == 0 && *error ) { lprintf("Error during decode: %s\n", error); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, NULL); break; } if ( decoded_count == 0 ) { lprintf("Finished decoding, but still %d samples left?\n", samples_left); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, NULL); break; } lprintf("Decoded %d samples\n", buf_samples); samples_left -= decoded_count; audio_buffer->num_frames = decoded_count; audio_buffer->vpts = 0; /* TODO: Fix the pts calculation */ // audio_buffer->vpts = (buf->pts * (samples_total-samples_left)) / samples_total; lprintf("Audio buffer with pts %"PRId64"\n", audio_buffer->vpts); switch(this->bits_per_sample) { case 8: { int8_t *data8 = (int8_t*)audio_buffer->mem; for(i = 0; i < decoded_count*this->channels; i++) data8[i] = decoded[i]; } break; case 16: { int16_t *data16 = (int16_t*)audio_buffer->mem; for(i = 0; i < decoded_count*this->channels; i++) data16[i] = decoded[i]; } } this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } WavpackCloseFile(ctx); this->buf_pos = 0; } } } static void wavpack_dispose (audio_decoder_t *this_gen) { wavpack_decoder_t *this = (wavpack_decoder_t *) this_gen; if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); free(this->buf); free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { wavpack_decoder_t * const this = calloc(1, sizeof (wavpack_decoder_t)); (void)class_gen; if (!this) return NULL; this->audio_decoder.decode_data = wavpack_decode_data; this->audio_decoder.reset = wavpack_reset; this->audio_decoder.discontinuity = wavpack_discontinuity; this->audio_decoder.dispose = wavpack_dispose; this->stream = stream; this->buf = NULL; this->buf_size = 0; return (audio_decoder_t *) this; } /* * wavpack plugin class */ void *decoder_wavpack_init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "wavpackdec", .description = N_("wavpack audio decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (audio_decoder_class_t *)&this; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/nsf_decoder.c�������������������������������������������������������������0000644�0001750�0001750�00000017153�14647725152�015661� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * NSF Audio "Decoder" using the Nosefart NSF engine by Matt Conte * http://www.baisoku.org/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" /* Nosefart includes */ #include "types.h" #include "nsf.h" #include "nsf_combined.h" typedef struct nsf_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; int sample_rate; /* audio sample rate */ int bits_per_sample; /* bits/sample, usually 8 or 16 */ int channels; /* 1 or 2, usually */ int output_open; /* flag to indicate audio is ready */ int nsf_size; unsigned char *nsf_file; int nsf_index; int song_number; /* nsf-specific variables */ int64_t last_pts; unsigned int iteration; nsf_t *nsf; } nsf_decoder_t; /************************************************************************** * xine audio plugin functions *************************************************************************/ static void nsf_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { nsf_decoder_t *this = (nsf_decoder_t *) this_gen; audio_buffer_t *audio_buffer; if (buf->decoder_flags & BUF_FLAG_HEADER) { /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize * the decoder. The buffer element type has 4 decoder_info fields, * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field * 3 is the number of channels. */ this->sample_rate = buf->decoder_info[1]; this->bits_per_sample = buf->decoder_info[2]; this->channels = buf->decoder_info[3]; /* take this opportunity to initialize stream/meta information */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "NES Music (Nosefart)"); this->song_number = buf->content[4]; /* allocate a buffer for the file */ this->nsf_size = _X_BE_32(&buf->content[0]); this->nsf_file = calloc(1, this->nsf_size); this->nsf_index = 0; /* peform any other required initialization */ this->last_pts = -1; this->iteration = 0; return; } /* accumulate chunks from the NSF file until whole file is received */ if (this->nsf_index < this->nsf_size) { xine_fast_memcpy(&this->nsf_file[this->nsf_index], buf->content, buf->size); this->nsf_index += buf->size; if (this->nsf_index == this->nsf_size) { /* file has been received, proceed to initialize engine */ nsf_init(); this->nsf = nsf_load(NULL, this->nsf_file, this->nsf_size); if (!this->nsf) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "nsf: could not initialize NSF\n"); /* make the decoder return on every subsequent buffer */ this->nsf_index = 0; return; } this->nsf->current_song = this->song_number; nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate, this->bits_per_sample, this->channels); } return; } /* if the audio output is not open yet, open the audio output */ if (!this->output_open) { this->output_open = (this->stream->audio_out->open) ( this->stream->audio_out, this->stream, this->bits_per_sample, this->sample_rate, _x_ao_channels2mode(this->channels)); } /* if the audio still isn't open, do not go any further with the decode */ if (!this->output_open) return; /* check if a song change was requested */ if (buf->decoder_info[1]) { this->nsf->current_song = buf->decoder_info[1]; nsf_playtrack(this->nsf, this->nsf->current_song, this->sample_rate, this->bits_per_sample, this->channels); } /* time to decode a frame */ if (this->last_pts != -1) { /* process a frame */ nsf_frame(this->nsf); /* get an audio buffer */ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); if (audio_buffer->mem_size == 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "nsf: Help! Allocated audio buffer with nothing in it!\n"); return; } apu_process(audio_buffer->mem, this->sample_rate / this->nsf->playback_rate); audio_buffer->vpts = buf->pts; audio_buffer->num_frames = this->sample_rate / this->nsf->playback_rate; this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } this->last_pts = buf->pts; } /* This function resets the state of the audio decoder. This usually * entails resetting the data accumulation buffer. */ static void nsf_reset (audio_decoder_t *this_gen) { nsf_decoder_t *this = (nsf_decoder_t *) this_gen; this->last_pts = -1; } /* This function resets the last pts value of the audio decoder. */ static void nsf_discontinuity (audio_decoder_t *this_gen) { nsf_decoder_t *this = (nsf_decoder_t *) this_gen; this->last_pts = -1; } /* This function closes the audio output and frees the private audio decoder * structure. */ static void nsf_dispose (audio_decoder_t *this_gen) { nsf_decoder_t *this = (nsf_decoder_t *) this_gen; /* close the audio output */ if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; /* free anything that was allocated during operation */ nsf_free(&this->nsf); free(this->nsf_file); free(this); } /* This function allocates, initializes, and returns a private audio * decoder structure. */ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { nsf_decoder_t *this ; (void)class_gen; this = (nsf_decoder_t *) calloc(1, sizeof(nsf_decoder_t)); if (!this) return NULL; /* connect the member functions */ this->audio_decoder.decode_data = nsf_decode_data; this->audio_decoder.reset = nsf_reset; this->audio_decoder.discontinuity = nsf_discontinuity; this->audio_decoder.dispose = nsf_dispose; /* connect the stream */ this->stream = stream; /* audio output is not open at the start */ this->output_open = 0; /* initialize the basic audio parameters */ this->channels = 0; this->sample_rate = 0; this->bits_per_sample = 0; /* return the newly-initialized audio decoder */ return &this->audio_decoder; } /* This function allocates a private audio decoder class and initializes * the class's member functions. */ void *decoder_nsf_init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "NSF", .description = N_("NES Music audio decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (audio_decoder_class_t *)&this; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/combined/xine_vorbis_decoder.c�����������������������������������������������������0000644�0001750�0001750�00000026243�14647725152�017422� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * (ogg/)vorbis audio decoder plugin (libvorbis wrapper) for xine */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #define LOG_MODULE "vorbis_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <ogg/ogg.h> #include <vorbis/codec.h> #include "ogg_combined.h" #define MAX_NUM_SAMPLES 4096 #define INIT_BUFSIZE 8192 typedef struct { audio_decoder_class_t decoder_class; } vorbis_class_t; typedef struct vorbis_decoder_s { audio_decoder_t audio_decoder; int64_t pts; int output_sampling_rate; int output_open; int output_mode; ogg_packet op; /* we must use this struct to sent data to libvorbis */ /* vorbis stuff */ vorbis_info vi; /* stores static vorbis bitstream settings */ vorbis_comment vc; vorbis_dsp_state vd; /* central working state for packet->PCM decoder */ vorbis_block vb; /* local working state for packet->PCM decoder */ int16_t convbuffer[MAX_NUM_SAMPLES]; int convsize; int header_count; xine_stream_t *stream; /* data accumulation stuff */ unsigned char *buf; int bufsize; int size; } vorbis_decoder_t; static void vorbis_reset (audio_decoder_t *this_gen) { vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; if( this->header_count ) return; this->size = 0; /* clear block first, as it might contain allocated data */ vorbis_block_clear(&this->vb); vorbis_block_init(&this->vd,&this->vb); } static void vorbis_discontinuity (audio_decoder_t *this_gen) { vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; this->pts=0; } /* Known vorbis comment keys from ogg123 sources*/ static const struct { const char *key; /* includes the '=' for programming convenience */ int xine_metainfo_index; } vorbis_comment_keys[] = { {"ARTIST=", XINE_META_INFO_ARTIST}, {"ALBUM=", XINE_META_INFO_ALBUM}, {"TITLE=", XINE_META_INFO_TITLE}, {"GENRE=", XINE_META_INFO_GENRE}, {"DESCRIPTION=", XINE_META_INFO_COMMENT}, {"COMMENT=", XINE_META_INFO_COMMENT}, {"DATE=", XINE_META_INFO_YEAR}, {"TRACKNUMBER=", XINE_META_INFO_TRACK_NUMBER}, {NULL, 0} }; static void get_metadata (vorbis_decoder_t *this) { char **ptr=this->vc.user_comments; while(*ptr){ char *comment = *ptr; int i; lprintf("%s\n", comment); for (i = 0; vorbis_comment_keys[i].key != NULL; i++) { if ( !strncasecmp (vorbis_comment_keys[i].key, comment, strlen(vorbis_comment_keys[i].key)) ) { lprintf ("known metadata %d %d\n", i, vorbis_comment_keys[i].xine_metainfo_index); _x_meta_info_set_utf8(this->stream, vorbis_comment_keys[i].xine_metainfo_index, comment + strlen(vorbis_comment_keys[i].key)); } } ++ptr; } _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "vorbis"); } static void vorbis_check_bufsize (vorbis_decoder_t *this, int size) { if (size > this->bufsize) { this->bufsize = size + size / 2; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("vorbis: increasing buffer to %d to avoid overflow.\n"), this->bufsize); this->buf = realloc(this->buf, this->bufsize); } } static void vorbis_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; /* Disassemble a regular decoder configuration packet. Calm down, there is only 1 level of recursion ;-) */ if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG)) { uint8_t *head = buf->decoder_info_ptr[2], *data, *olddata = buf->content; int len = buf->decoder_info[2], part, i, oldsize = buf->size, oldflags = buf->decoder_flags; if (!head || (--len < 0)) return; i = *head++; if ((len -= i) < 0) return; data = head + i; buf->decoder_flags = BUF_FLAG_HEADER | BUF_FLAG_FRAME_END; for (; i >= 0; i--) { part = i ? *head++ : len; if (part > len) part = len; buf->content = data; buf->size = part; vorbis_decode_data (this_gen, buf); data += part; len -= part; } buf->decoder_flags = oldflags; buf->content = olddata; buf->size = oldsize; return; } memset( &this->op, 0, sizeof(this->op) ); /* data accumulation */ vorbis_check_bufsize(this, this->size + buf->size); xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { this->op.packet = this->buf; this->op.bytes = this->size; /* reset accumultaion buffer */ this->size = 0; if ( (buf->decoder_flags & BUF_FLAG_HEADER) && !(buf->decoder_flags & BUF_FLAG_STDHEADER) ) { lprintf ("%d headers to go\n", this->header_count); if (this->header_count) { int res = 0; if (this->header_count == 3) this->op.b_o_s = 1; if ( (res = vorbis_synthesis_headerin(&this->vi,&this->vc,&this->op)) < 0 ) { /* error case; not a vorbis header */ xine_log(this->stream->xine, XINE_LOG_MSG, "libvorbis: this bitstream does not contain vorbis audio data. Following first 64 bytes (return: %d).\n", res); xine_hexdump((char *)this->op.packet, this->op.bytes < 64 ? this->op.bytes : 64); return; } this->header_count--; if (!this->header_count) { int mode = AO_CAP_MODE_MONO; get_metadata (this); mode = _x_ao_channels2mode(this->vi.channels); this->convsize=MAX_NUM_SAMPLES/this->vi.channels; if (!this->output_open) { this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->vi.rate, mode) ; _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->vi.bitrate_nominal); } /* OK, got and parsed all three headers. Initialize the Vorbis * packet->PCM decoder. */ lprintf("all three headers parsed. initializing decoder.\n"); /* initialize central decode state */ vorbis_synthesis_init(&this->vd,&this->vi); /* initialize local state for most of the decode so multiple * block decodes can proceed in parallel. We could init * multiple vorbis_block structures for vd here */ vorbis_block_init(&this->vd,&this->vb); } } } else if (this->output_open) { float **pcm; int samples; if(vorbis_synthesis(&this->vb,&this->op)==0) vorbis_synthesis_blockin(&this->vd,&this->vb); if (buf->pts!=0) this->pts=buf->pts; while ((samples=vorbis_synthesis_pcmout(&this->vd,&pcm))>0){ /* **pcm is a multichannel float vector. In stereo, for * example, pcm[0][...] is left, and pcm[1][...] is right. * samples is the size of each channel. Convert the float * values (-1.<=range<=1.) to whatever PCM format and write * it out */ int i,j; int bout=(samples<this->convsize?samples:this->convsize); audio_buffer_t *audio_buffer; audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); /* convert floats to 16 bit signed ints (host order) and interleave */ for(i=0;i<this->vi.channels;i++){ ogg_int16_t *ptr=audio_buffer->mem+i; float *mono=pcm[i]; for(j=0;j<bout;j++){ int val=(mono[j] + 1.0f) * 32768.f; val -= 32768; /* might as well guard against clipping */ if(val>32767){ val=32767; } else if(val<-32768){ val=-32768; } *ptr=val; ptr+=this->vi.channels; } } audio_buffer->vpts = this->pts; this->pts=0; audio_buffer->num_frames = bout; this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); buf->pts=0; /* tell libvorbis how many samples we actually consumed */ vorbis_synthesis_read(&this->vd,bout); } } else { lprintf("output not open\n"); } } } static void vorbis_dispose (audio_decoder_t *this_gen) { vorbis_decoder_t *this = (vorbis_decoder_t *) this_gen; if( !this->header_count ) { lprintf("deinitializing decoder\n"); vorbis_block_clear(&this->vb); vorbis_dsp_clear(&this->vd); } vorbis_comment_clear(&this->vc); vorbis_info_clear(&this->vi); /* must be called last */ if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); lprintf("libvorbis instance destroyed\n"); free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { vorbis_decoder_t *this ; (void)class_gen; this = (vorbis_decoder_t *) calloc(1, sizeof(vorbis_decoder_t)); if (!this) return NULL; this->audio_decoder.decode_data = vorbis_decode_data; this->audio_decoder.reset = vorbis_reset; this->audio_decoder.discontinuity = vorbis_discontinuity; this->audio_decoder.dispose = vorbis_dispose; this->stream = stream; this->output_open = 0; this->header_count = 3; this->convsize = 0; this->bufsize = INIT_BUFSIZE; this->buf = calloc(1, INIT_BUFSIZE); this->size = 0; vorbis_info_init(&this->vi); vorbis_comment_init(&this->vc); lprintf("libvorbis decoder instance created\n"); return (audio_decoder_t *) this; } /* * vorbis plugin class */ void *vorbis_init_plugin (xine_t *xine, const void *data) { vorbis_class_t *this; (void)xine; (void)data; this = (vorbis_class_t *) calloc(1, sizeof(vorbis_class_t)); if (!this) return NULL; this->decoder_class.open_plugin = open_plugin; this->decoder_class.identifier = "vorbis"; this->decoder_class.description = N_("vorbis audio decoder plugin"); this->decoder_class.dispose = default_audio_decoder_class_dispose; return this; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013443� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_fusionsound_out.c��������������������������������������������������0000644�0001750�0001750�00000035162�14647725152�020242� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project and Claudio Ciccani * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * FusionSound based audio output plugin by Claudio Ciccani <klan@directfb.org> * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #define LOG_MODULE "audio_fusionsound_out" #define LOG_VERBOSE #include "xine.h" #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/xineutils.h> #include <directfb.h> #include <fusionsound.h> #include <fusionsound_version.h> #define VERSION_CODE(M, m, r) (((M) * 1000) + ((m) * 100) + (r)) #define FUSIONSOUND_VERSION_CODE VERSION_CODE( FUSIONSOUND_MAJOR_VERSION, \ FUSIONSOUND_MINOR_VERSION, \ FUSIONSOUND_MICRO_VERSION ) #if FUSIONSOUND_VERSION_CODE >= VERSION_CODE(1,1,0) # include <fusionsound_limits.h> /* defines FS_MAX_CHANNELS */ #else # define FS_MAX_CHANNELS 2 #endif #define AO_OUT_FS_IFACE_VERSION 9 #define GAP_TOLERANCE 5000 typedef struct fusionsound_driver_s { ao_driver_t ao_driver; xine_t *xine; IFusionSound *sound; IFusionSoundStream *stream; IFusionSoundPlayback *playback; FSSampleFormat format; int channels; int rate; int bytes_per_frame; float vol; int vol_mute; float amp; int amp_mute; int paused; } fusionsound_driver_t; typedef struct { audio_driver_class_t ao_class; xine_t *xine; } fusionsound_class_t; static int ao_fusionsound_open(ao_driver_t *ao_driver, uint32_t bits, uint32_t rate, int mode) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; FSStreamDescription dsc; DFBResult ret; lprintf ("ao_open( bits=%d, rate=%d, mode=%d )\n", bits, rate, mode); dsc.flags = FSSDF_BUFFERSIZE | FSBDF_CHANNELS | FSSDF_SAMPLEFORMAT | FSSDF_SAMPLERATE; switch (mode) { case AO_CAP_MODE_MONO: dsc.channels = 1; break; case AO_CAP_MODE_STEREO: dsc.channels = 2; break; #if FS_MAX_CHANNELS > 2 case AO_CAP_MODE_4CHANNEL: dsc.channels = 4; dsc.channelmode = FSCM_SURROUND40_2F2R; dsc.flags |= FSBDF_CHANNELMODE; break; case AO_CAP_MODE_4_1CHANNEL: dsc.channels = 5; dsc.channelmode = FSCM_SURROUND41_2F2R; dsc.flags |= FSBDF_CHANNELMODE; break; case AO_CAP_MODE_5CHANNEL: dsc.channels = 5; dsc.channelmode = FSCM_SURROUND50; dsc.flags |= FSBDF_CHANNELMODE; break; case AO_CAP_MODE_5_1CHANNEL: dsc.channels = 6; dsc.channelmode = FSCM_SURROUND51; dsc.flags |= FSBDF_CHANNELMODE; break; #endif default: xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: mode %#x not supported\n", mode); return 0; } switch (bits) { case 8: dsc.sampleformat = FSSF_U8; break; case 16: dsc.sampleformat = FSSF_S16; break; case 24: dsc.sampleformat = FSSF_S24; break; #if FUSIONSOUND_VERSION_CODE >= VERSION_CODE(0,9,26) case 32: dsc.sampleformat = FSSF_FLOAT; break; #endif default: xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: bits %d not supported\n", bits); return 0; } dsc.samplerate = rate; dsc.buffersize = rate / 5; if (dsc.sampleformat != this->format || dsc.channels != this->channels || dsc.samplerate != this->rate || this->stream == NULL) { if (this->playback) { this->playback->Release (this->playback); this->playback = NULL; } if (this->stream) { this->stream->Release (this->stream); this->stream = NULL; } ret = this->sound->CreateStream (this->sound, &dsc, &this->stream); if (ret != DFB_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: IFusionSound::CreateStream() failed [%s]\n", FusionSoundErrorString (ret)); return 0; } this->stream->GetDescription (this->stream, &dsc); this->format = dsc.sampleformat; this->channels = dsc.channels; this->rate = dsc.samplerate; this->bytes_per_frame = this->channels * FS_BYTES_PER_SAMPLE(this->format); ret = this->stream->GetPlayback (this->stream, &this->playback); if (ret == DFB_OK) { this->playback->SetVolume (this->playback, (this->vol_mute ? 0 : this->vol) * (this->amp_mute ? 0 : this->amp)); if (this->paused) this->playback->Stop (this->playback); } else { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: " "IFusionSoundStream::GetPlayback() failed [%s]\n", FusionSoundErrorString (ret)); } } return this->rate; } static int ao_fusionsound_num_channels(ao_driver_t *ao_driver) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; return this->channels; } static int ao_fusionsound_bytes_per_frame(ao_driver_t *ao_driver) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; return this->bytes_per_frame; } static int ao_fusionsound_delay(ao_driver_t *ao_driver) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; int delay = 0; this->stream->GetPresentationDelay (this->stream, &delay); return (delay * this->rate / 1000); } static int ao_fusionsound_get_gap_tolerance(ao_driver_t *ao_driver) { return GAP_TOLERANCE; } static int ao_fusionsound_write(ao_driver_t *ao_driver, int16_t *data, uint32_t num_frames) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; DFBResult ret; if (this->paused) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: " "ao_fusionsound_write() called in pause mode!\n"); return 0; } lprintf ("ao_write( data=%p, num_frames=%d )\n", data, num_frames); ret = this->stream->Write (this->stream, (void *)data, num_frames); if (ret != DFB_OK) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: IFusionSoundStream::Write() failed [%s]\n", FusionSoundErrorString (ret)); return 0; } return num_frames; } static void ao_fusionsound_close(ao_driver_t *ao_driver){ fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; if (this->playback) { this->playback->Release (this->playback); this->playback = NULL; } if (this->stream) { this->stream->Release (this->stream); this->stream = NULL; } } /* * FusionSound supports amplifier level adjustment; * probably AO_CAP_AMP should be added to take advantage of this feature. */ static uint32_t ao_fusionsound_get_capabilities(ao_driver_t *ao_driver) { uint32_t caps = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MIXER_VOL | AO_CAP_MUTE_VOL | AO_CAP_8BITS | AO_CAP_16BITS | AO_CAP_24BITS; #if FUSIONSOUND_VERSION_CODE >= VERSION_CODE(0,9,26) caps |= AO_CAP_FLOAT32; #endif #if FS_MAX_CHANNELS > 2 caps |= AO_CAP_MODE_4CHANNEL | AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL; #endif return caps; } static void ao_fusionsound_exit(ao_driver_t *ao_driver) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; if (this->playback) this->playback->Release (this->playback); if (this->stream) this->stream->Release (this->stream); if (this->sound) this->sound->Release (this->sound); free (this); } static int ao_fusionsound_get_property(ao_driver_t *ao_driver, int property) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; switch (property) { case AO_PROP_MIXER_VOL: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: volume is %.2f\n", this->vol); return (int) (this->vol * 100.0); case AO_PROP_MUTE_VOL: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: volume mute is %d\n", this->vol_mute); return this->vol_mute; case AO_PROP_AMP: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: amplifier is %.2f\n", this->amp); return (int) (this->amp * 100.0); case AO_PROP_AMP_MUTE: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: amplifier mute is %d\n", this->amp_mute); return this->amp_mute; default: break; } return 0; } static int ao_fusionsound_set_property(ao_driver_t *ao_driver, int property, int value ) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; if (!this->playback) return 0; switch (property) { case AO_PROP_MIXER_VOL: this->vol = (float)value / 100.0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: volume set to %.2f\n", this->vol); break; case AO_PROP_MUTE_VOL: this->vol_mute = value ? 1 : 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: volume mute set to %d\n", this->vol_mute); break; case AO_PROP_AMP: this->amp = (float)value / 100.0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: amplifier set to %.2f\n", this->amp); break; case AO_PROP_AMP_MUTE: this->amp_mute = value ? 1 : 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_fusionsound_out: amplifier mute set to %d\n", this->amp_mute); break; default: return 0; } if (this->playback) { this->playback->SetVolume (this->playback, (this->vol_mute ? 0 : this->vol) * (this->amp_mute ? 0 : this->amp)); } return value; } static int ao_fusionsound_control(ao_driver_t *ao_driver, int cmd, ...) { fusionsound_driver_t *this = (fusionsound_driver_t *) ao_driver; switch (cmd) { case AO_CTRL_PLAY_PAUSE: lprintf ("Pause()\n"); if (this->playback) this->playback->Stop (this->playback); this->paused = 1; return 1; case AO_CTRL_PLAY_RESUME: lprintf ("Resume()\n"); if (this->playback) this->playback->Continue (this->playback); this->paused = 0; return 1; case AO_CTRL_FLUSH_BUFFERS: lprintf ("Flush()\n"); if (this->stream) this->stream->Flush (this->stream); return 1; default: break; } return 0; } static ao_driver_t* open_plugin(audio_driver_class_t *ao_class, const void *data ) { fusionsound_class_t *class = (fusionsound_class_t *) ao_class; fusionsound_driver_t *this; const char *args[] = { "xine", "--dfb:no-sighandler", "--fs:no-banner" }; const size_t argn = sizeof(args) / sizeof(args[0]); char **argp = (char **) args; DFBResult ret; this = calloc(1, sizeof(fusionsound_driver_t)); if (!this) { xprintf (class->xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: driver interface allocation failed!\n"); return NULL; } FusionSoundInit (&argn, &argp); ret = FusionSoundCreate (&this->sound); if (ret != DFB_OK) { xprintf (class->xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: FusionSoundCreate() failed [%s]\n", FusionSoundErrorString (ret)); free (this); return NULL; } this->xine = class->xine; this->ao_driver.get_capabilities = ao_fusionsound_get_capabilities; this->ao_driver.get_property = ao_fusionsound_get_property; this->ao_driver.set_property = ao_fusionsound_set_property; this->ao_driver.open = ao_fusionsound_open; this->ao_driver.num_channels = ao_fusionsound_num_channels; this->ao_driver.bytes_per_frame = ao_fusionsound_bytes_per_frame; this->ao_driver.delay = ao_fusionsound_delay; this->ao_driver.write = ao_fusionsound_write; this->ao_driver.close = ao_fusionsound_close; this->ao_driver.exit = ao_fusionsound_exit; this->ao_driver.get_gap_tolerance = ao_fusionsound_get_gap_tolerance; this->ao_driver.control = ao_fusionsound_control; this->vol = this->amp = 1.0; return &this->ao_driver; } /* * class functions */ static void* init_class(xine_t *xine, const void *data) { fusionsound_class_t *class; const char *error; /* check FusionSound version */ error = FusionSoundCheckVersion( FUSIONSOUND_MAJOR_VERSION, FUSIONSOUND_MINOR_VERSION, FUSIONSOUND_MICRO_VERSION ); if (error) { xprintf (xine, XINE_VERBOSITY_NONE, "audio_fusionsound_out: %s!\n", error); return NULL; } class = calloc(1, sizeof( fusionsound_class_t)); if (!class) { xprintf (xine, XINE_VERBOSITY_LOG, "audio_fusionsound_out: class interface allocation failed!\n"); return NULL; } class->ao_class.open_plugin = open_plugin; class->ao_class.identifier = "FunsionSound"; class->ao_class.description = N_("xine FusionSound audio output plugin"); class->ao_class.dispose = default_audio_driver_class_dispose; class->xine = xine; return class; } static const ao_info_t ao_info_fusionsound = { .priority = 4, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_FS_IFACE_VERSION, "FusionSound", XINE_VERSION_CODE, &ao_info_fusionsound, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/speakers.h���������������������������������������������������������������0000644�0001750�0001750�00000007303�14647725152�015434� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2013 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #define MONO 0 #define STEREO 1 #define HEADPHONES 2 #define SURROUND21 3 #define SURROUND3 4 #define SURROUND4 5 #define SURROUND41 6 #define SURROUND5 7 #define SURROUND51 8 #define SURROUND6 9 #define SURROUND61 10 #define SURROUND71 11 #define A52_PASSTHRU 12 #define AUDIO_DEVICE_SPEAKER_ARRANGEMENT_HELP \ _("speaker arrangement"), \ _("Select how your speakers are arranged, " \ "this determines which speakers xine uses for sound output. " \ "The individual values are:\n\n" \ "Mono 1.0: You have only one speaker.\n" \ "Stereo 2.0: You have two speakers for left and right channel.\n" \ "Headphones 2.0: You use headphones.\n" \ "Stereo 2.1: You have two speakers for left and right channel, and one " \ "subwoofer for the low frequencies.\n" \ "Surround 3.0: You have three speakers for left, right and rear channel.\n" \ "Surround 4.0: You have four speakers for front left and right and rear " \ "left and right channels.\n" \ "Surround 4.1: You have four speakers for front left and right and rear " \ "left and right channels, and one subwoofer for the low frequencies.\n" \ "Surround 5.0: You have five speakers for front left, center and right and " \ "rear left and right channels.\n" \ "Surround 5.1: You have five speakers for front left, center and right and " \ "rear left and right channels, and one subwoofer for the low frequencies.\n" \ "Surround 6.0: You have six speakers for front left, center and right and " \ "rear left, center and right channels.\n" \ "Surround 6.1: You have six speakers for front left, center and right and " \ "rear left, center and right channels, and one subwoofer for the low frequencies.\n" \ "Surround 7.1: You have seven speakers for front left, center and right, " \ "left and right and rear left and right channels, and one subwoofer for the " \ "low frequencies.\n" \ "Pass Through: Your sound system will receive undecoded digital sound from xine. " \ "You need to connect a digital surround decoder capable of decoding the " \ "formats you want to play to your sound card's digital output.") #define AUDIO_DEVICE_SPEAKER_ARRANGEMENT_TYPES \ static const char * const speaker_arrangement[] = { \ "Mono 1.0", "Stereo 2.0", "Headphones 2.0", "Stereo 2.1", \ "Surround 3.0", "Surround 4.0", "Surround 4.1", "Surround 5.0", \ "Surround 5.1", "Surround 6.0", "Surround 6.1", "Surround 7.1", \ "Pass Through", NULL}; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_pulse_out.c��������������������������������������������������������0000644�0001750�0001750�00000076277�14647725152�017032� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */ /* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * ao plugin for PulseAudio: * http://0pointer.de/lennart/projects/pulsaudio/ * * Diego Petteno, Lennart Poettering */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <inttypes.h> #include <pthread.h> #include <pulse/pulseaudio.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include "bswap.h" #define GAP_TOLERANCE AO_MAX_GAP typedef struct { audio_driver_class_t driver_class; xine_t *xine; } pulse_class_t; typedef struct pulse_driver_s { ao_driver_t ao_driver; xine_t *xine; pulse_class_t *pa_class; char *host; /*< The host to connect to */ char *sink; /*< The sink to connect to */ pa_threaded_mainloop *mainloop; /*< Main event loop object */ pa_context *context; /*< Pulseaudio connection context */ pa_stream *stream; /*< Pulseaudio playback stream object */ pa_volume_t swvolume; int muted; pa_cvolume cvolume; int capabilities; int mode; uint32_t sample_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; int volume_bool; } pulse_driver_t; /** * @brief Callback function called when the state of the context is changed * @param c Context which changed status * @param this_gen pulse_class_t pointer for the PulseAudio output class */ static void __xine_pa_context_state_callback(pa_context *c, void *this_gen) { pulse_driver_t * this = (pulse_driver_t*) this_gen; switch (pa_context_get_state(c)) { case PA_CONTEXT_READY: case PA_CONTEXT_TERMINATED: case PA_CONTEXT_FAILED: pa_threaded_mainloop_signal(this->mainloop, 0); break; case PA_CONTEXT_CONNECTING: case PA_CONTEXT_UNCONNECTED: case PA_CONTEXT_AUTHORIZING: case PA_CONTEXT_SETTING_NAME: break; } } /** * @brief Callback function called when the state of the stream is changed * @param s Stream that changed status * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. */ static void __xine_pa_stream_state_callback(pa_stream *s, void *this_gen) { pulse_driver_t * this = (pulse_driver_t*) this_gen; switch (pa_stream_get_state(s)) { case PA_STREAM_READY: case PA_STREAM_TERMINATED: case PA_STREAM_FAILED: pa_threaded_mainloop_signal(this->mainloop, 0); break; case PA_STREAM_UNCONNECTED: case PA_STREAM_CREATING: break; } } /** * @brief Callback function called when PA asks for more audio data. * @param s Stream on which data is requested * @param nbytes the number of bytes PA requested * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. */ static void __xine_pa_stream_request_callback(pa_stream *s, size_t nbytes, void *this_gen) { pulse_driver_t * this = (pulse_driver_t*) this_gen; (void)s; (void)nbytes; pa_threaded_mainloop_signal(this->mainloop, 0); } /** * @brief Callback function called when PA notifies about something * @param s Stream on which the notification happened * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. */ static void __xine_pa_stream_notify_callback(pa_stream *s, void *this_gen) { pulse_driver_t * this = (pulse_driver_t*) this_gen; (void)s; pa_threaded_mainloop_signal(this->mainloop, 0); } /** * @brief Callback function called when PA completed an operation * @param ctx Context which operation has succeeded * @param nbytes the number of bytes PA requested * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. */ static void __xine_pa_stream_success_callback(pa_stream *s, int success, void *this_gen) { pulse_driver_t * this = (pulse_driver_t*) this_gen; (void)s; if (!success) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: stream operation failed: %s\n", pa_strerror(pa_context_errno(this->context))); pa_threaded_mainloop_signal(this->mainloop, 0); } /** * @brief Callback function called when PA completed an operation * @param c Context on which operation has succeeded * @param nbytes the number of bytes PA requested * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. */ static void __xine_pa_context_success_callback(pa_context *c, int success, void *this_gen) { pulse_driver_t *this = (pulse_driver_t*) this_gen; (void)c; if (!success) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: context operation failed: %s\n", pa_strerror(pa_context_errno(this->context))); pa_threaded_mainloop_signal(this->mainloop, 0); } /** * @brief Callback function called when the information on the * context's sink is retrieved. * @param ctx Context which operation has succeeded * @param info Structure containing the sink's information * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. * * This function saves the volume field of the passed structure to the * @c cvolume variable of the output instance and send an update volume * event to the frontend. */ static void __xine_pa_sink_info_callback(pa_context *c, const pa_sink_input_info *info, int is_last, void *userdata) { pulse_driver_t *const this = (pulse_driver_t *) userdata; (void)c; if (is_last < 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n", pa_strerror(pa_context_errno(this->context))); return; } if (!info) return; this->cvolume = info->volume; this->swvolume = pa_cvolume_avg(&info->volume); #if PA_PROTOCOL_VERSION >= 11 /* PulseAudio 0.9.7 and newer */ this->muted = info->mute; #else this->muted = pa_cvolume_is_muted (&this->cvolume); #endif /* send update volume event to frontend */ xine_event_t event; xine_audio_level_data_t data; xine_stream_t *stream; xine_list_iterator_t ite; data.right = data.left = (int) (pa_sw_volume_to_linear(this->swvolume)*100); data.mute = this->muted; event.type = XINE_EVENT_AUDIO_LEVEL; event.data = &data; event.data_length = sizeof(data); pthread_mutex_lock(&this->xine->streams_lock); ite = NULL; while ((stream = xine_list_next_value (this->xine->streams, &ite))) { event.stream = stream; xine_event_send(stream, &event); } pthread_mutex_unlock(&this->xine->streams_lock); } /** * @brief Callback function called when the state of the daemon changes * @param c Context in which the state of the daemon changes * @param t Subscription event type * @param idx Index of the sink * @param this_gen pulse_driver_t pointer for the PulseAudio output * instance. */ static void __xine_pa_context_subscribe_callback(pa_context *c, pa_subscription_event_type_t t, uint32_t idx, void *this_gen) { pulse_driver_t * this = (pulse_driver_t*) this_gen; uint32_t index; (void)c; if (this->stream == NULL) return; index = pa_stream_get_index(this->stream); if (index != idx) return; if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_CHANGE) return; pa_operation *operation = pa_context_get_sink_input_info( this->context, index, __xine_pa_sink_info_callback, this); if (operation == NULL) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to get sink info: %s\n", pa_strerror(pa_context_errno (this->context))); return; } pa_operation_unref(operation); } static int connect_context(pulse_driver_t *this) { if (this->context && (pa_context_get_state(this->context) == PA_CONTEXT_FAILED || pa_context_get_state(this->context) == PA_CONTEXT_TERMINATED)) { pa_context_unref(this->context); this->context = NULL; } if (!this->context) { char fn[XINE_PATH_MAX]; const char *p; if (pa_get_binary_name(fn, sizeof(fn))) p = pa_path_get_filename(fn); else p = "Xine"; this->context = pa_context_new(pa_threaded_mainloop_get_api(this->mainloop), p); if (!this->context) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: pa_context_new() failed\n"); return -1; } pa_context_set_state_callback(this->context, __xine_pa_context_state_callback, this); /* set subscribe callback (for volume change information) */ pa_context_set_subscribe_callback(this->context, __xine_pa_context_subscribe_callback, this); } if (pa_context_get_state(this->context) == PA_CONTEXT_UNCONNECTED) { if (pa_context_connect(this->context, this->host, 0, NULL) < 0) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object %s\n", pa_strerror(pa_context_errno(this->context))); return -1; } } for (;;) { pa_context_state_t state = pa_context_get_state(this->context); if (state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object: %s\n", pa_strerror(pa_context_errno(this->context))); return -1; } if (state == PA_CONTEXT_READY) break; pa_threaded_mainloop_wait(this->mainloop); } /* subscribe to sink input events (for volume change information) */ pa_operation *operation = pa_context_subscribe(this->context, PA_SUBSCRIPTION_MASK_SINK_INPUT, __xine_pa_context_success_callback, this); if (operation == NULL) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to enable event notification: %s\n", pa_strerror(pa_context_errno(this->context))); return -1; } pa_operation_unref(operation); return 0; } /* * open the audio device for writing to */ static int ao_pulse_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { pulse_driver_t *this = (pulse_driver_t *) this_gen; pa_sample_spec ss; pa_channel_map cm; #if PA_CHECK_VERSION(1,0,0) pa_encoding_t encoding = PA_ENCODING_INVALID; #endif xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); if ( (mode & this->capabilities) == 0 ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: unsupported mode %08x\n", mode); return 0; } pa_threaded_mainloop_lock(this->mainloop); if (this->stream) { if (mode == this->mode && rate == this->sample_rate && bits == this->bits_per_sample) { pa_threaded_mainloop_unlock(this->mainloop); return this->sample_rate; } pa_stream_disconnect(this->stream); pa_stream_unref(this->stream); this->stream = NULL; } this->mode = mode; this->sample_rate = rate; this->bits_per_sample = bits; this->num_channels = _x_ao_mode2channels( mode ); this->bytes_per_frame = (this->bits_per_sample*this->num_channels)/8; ss.rate = rate; ss.channels = this->num_channels; switch (bits) { case 8: ss.format = PA_SAMPLE_U8; break; case 16: ss.format = PA_SAMPLE_S16NE; break; case 32: ss.format = PA_SAMPLE_FLOAT32NE; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: unsupported bit depth %u\n", bits); goto fail; } #if PA_CHECK_VERSION(1,0,0) if (mode == AO_CAP_MODE_A52 || mode == AO_CAP_MODE_AC5) { this->num_channels = 2; this->bytes_per_frame = (this->bits_per_sample*this->num_channels)/8; ss.channels = 2; encoding = PA_ENCODING_AC3_IEC61937; } #endif if (!pa_sample_spec_valid(&ss)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Invalid sample spec\n"); goto fail; } cm.channels = ss.channels; switch (mode) { case AO_CAP_MODE_MONO: cm.map[0] = PA_CHANNEL_POSITION_MONO; _x_assert(cm.channels == 1); break; case AO_CAP_MODE_STEREO: case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; _x_assert(cm.channels == 2); break; case AO_CAP_MODE_4CHANNEL: cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; cm.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; cm.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; _x_assert(cm.channels == 4); break; case AO_CAP_MODE_4_1CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: cm.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; cm.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; cm.map[2] = PA_CHANNEL_POSITION_REAR_LEFT; cm.map[3] = PA_CHANNEL_POSITION_REAR_RIGHT; cm.map[4] = PA_CHANNEL_POSITION_FRONT_CENTER; cm.map[5] = PA_CHANNEL_POSITION_LFE; cm.channels = 6; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: unsupported mode %08x\n", mode); goto fail; } if (!pa_channel_map_valid(&cm)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Invalid channel map\n"); goto fail; } if (connect_context(this) < 0) goto fail; #if PA_CHECK_VERSION(1,0,0) pa_format_info *formatv[2]; unsigned formatc = 0; /* Use digital pass-through if enabled */ if (encoding != PA_ENCODING_INVALID) { formatv[formatc] = pa_format_info_new(); formatv[formatc]->encoding = encoding; pa_format_info_set_rate(formatv[formatc], ss.rate); pa_format_info_set_channels(formatv[formatc], ss.channels); pa_format_info_set_channel_map(formatv[formatc], &cm); formatc++; } /* Fallback to PCM */ formatv[formatc] = pa_format_info_new(); formatv[formatc]->encoding = PA_ENCODING_PCM; pa_format_info_set_sample_format(formatv[formatc], ss.format); pa_format_info_set_rate(formatv[formatc], ss.rate); pa_format_info_set_channels(formatv[formatc], ss.channels); pa_format_info_set_channel_map(formatv[formatc], &cm); formatc++; pa_proplist *proplist = pa_proplist_new(); if (proplist != NULL) pa_proplist_sets(proplist, PA_PROP_MEDIA_ROLE, "video"); _x_assert(!this->stream); this->stream = pa_stream_new_extended(this->context, "Audio Stream", formatv, formatc, proplist); if (proplist != NULL) pa_proplist_free(proplist); unsigned i = 0; for (i = 0; i < formatc; i++) pa_format_info_free(formatv[i]); #else _x_assert(!this->stream); this->stream = pa_stream_new(this->context, "Audio Stream", &ss, &cm); #endif if (!this->stream) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: pa_Stream_new() failed\n"); goto fail; } pa_stream_set_state_callback(this->stream, __xine_pa_stream_state_callback, this); pa_stream_set_write_callback(this->stream, __xine_pa_stream_request_callback, this); pa_stream_set_latency_update_callback(this->stream, __xine_pa_stream_notify_callback, this); pa_stream_connect_playback(this->stream, this->sink, NULL, PA_STREAM_INTERPOLATE_TIMING|PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL); for (;;) { pa_context_state_t cstate = pa_context_get_state(this->context); pa_stream_state_t sstate = pa_stream_get_state(this->stream); if (cstate == PA_CONTEXT_FAILED || cstate == PA_CONTEXT_TERMINATED || sstate == PA_STREAM_FAILED || sstate == PA_STREAM_TERMINATED) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to connect context object: %s\n", pa_strerror(pa_context_errno(this->context))); goto fail; } if (sstate == PA_STREAM_READY) break; pa_threaded_mainloop_wait(this->mainloop); } #if PA_CHECK_VERSION(1,0,0) if (encoding != PA_ENCODING_INVALID) { const pa_format_info *info = pa_stream_get_format_info(this->stream); if (info) { if (pa_format_info_is_pcm (info)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "digital pass-through not available\n"); } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "digital pass-through enabled\n"); } } } #endif /* Now we must handle a problem: at init time, xine might have tried to set the default volume value * This won't work with pulseaudio, because, at that time, pulseaudio doesn't have a stream. * As a workaround, we re-do the volume thingie here */ config_values_t *cfg; cfg = this->xine->config; cfg_entry_t *entry; if (this->volume_bool) { this->volume_bool = 0; if (this->num_channels) pa_cvolume_reset(&this->cvolume, this->num_channels); entry = cfg->lookup_entry (cfg, "audio.volume.remember_volume"); if (entry && entry->num_value) { entry = cfg->lookup_entry (cfg, "audio.volume.mixer_volume"); if (entry) { this->ao_driver.set_property(&this->ao_driver, AO_PROP_MIXER_VOL, entry->num_value); } } } /* get pa sink input information to trigger a update volume event in the frontend */ pa_operation *operation = pa_context_get_sink_input_info( this->context, pa_stream_get_index(this->stream), __xine_pa_sink_info_callback, this); if (operation == NULL) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to get sink info: %s\n", pa_strerror(pa_context_errno (this->context))); goto fail; } pa_operation_unref(operation); pa_threaded_mainloop_unlock(this->mainloop); return this->sample_rate; fail: pa_threaded_mainloop_unlock(this->mainloop); this_gen->close(this_gen); return 0; } static int ao_pulse_num_channels(ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; return this->num_channels; } static int ao_pulse_bytes_per_frame(ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_pulse_get_gap_tolerance (ao_driver_t *this_gen) { (void)this_gen; return GAP_TOLERANCE; } static int ao_pulse_write(ao_driver_t *this_gen, int16_t *data, uint32_t num_frames) { pulse_driver_t *this = (pulse_driver_t *) this_gen; size_t size = num_frames * this->bytes_per_frame; int ret = -1; size_t done = 0; pa_threaded_mainloop_lock(this->mainloop); while (size > 0) { size_t l; for (;;) { if (!this->stream || !this->context || pa_context_get_state(this->context) != PA_CONTEXT_READY || pa_stream_get_state(this->stream) != PA_STREAM_READY) goto finish; if ((l = pa_stream_writable_size(this->stream)) == (size_t) -1) goto finish; if (l > 0) break; pa_threaded_mainloop_wait(this->mainloop); } if (l > size) l = size; pa_stream_write(this->stream, data, l, NULL, 0, PA_SEEK_RELATIVE); data = (int16_t *) ((uint8_t*) data + l); size -= l; done += l; } ret = done; finish: pa_threaded_mainloop_unlock(this->mainloop); /* fprintf(stderr, "write-out\n"); */ return ret; } static int ao_pulse_delay (ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; int ret = 0; /* fprintf(stderr, "delay-in\n"); */ pa_threaded_mainloop_lock(this->mainloop); for (;;) { pa_usec_t latency = 0; if (!this->stream || !this->context || pa_context_get_state(this->context) != PA_CONTEXT_READY || pa_stream_get_state(this->stream) != PA_STREAM_READY) goto finish; if (pa_stream_get_latency(this->stream, &latency, NULL) >= 0) { ret = (int) ((latency * this->sample_rate) / 1000000); goto finish; } if (pa_context_errno(this->context) != PA_ERR_NODATA) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: failed to query latency: %s\n", pa_strerror(pa_context_errno(this->context))); goto finish; } pa_threaded_mainloop_wait(this->mainloop); } finish: pa_threaded_mainloop_unlock(this->mainloop); return ret; } static void ao_pulse_close(ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; pa_threaded_mainloop_lock(this->mainloop); if (this->stream) { pa_stream_disconnect(this->stream); pa_stream_unref(this->stream); this->stream = NULL; } pa_threaded_mainloop_unlock(this->mainloop); } static uint32_t ao_pulse_get_capabilities (ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; return this->capabilities; } static void ao_pulse_exit(ao_driver_t *this_gen) { pulse_driver_t *this = (pulse_driver_t *) this_gen; ao_pulse_close(this_gen); pa_threaded_mainloop_lock(this->mainloop); if (this->context) { pa_context_disconnect(this->context); pa_context_unref(this->context); } pa_threaded_mainloop_unlock(this->mainloop); pa_threaded_mainloop_free(this->mainloop); free(this->host); free(this->sink); free(this); } static int wait_for_operation(pulse_driver_t *this, pa_operation *o) { for (;;) { if (!this->stream || !this->context || pa_context_get_state(this->context) != PA_CONTEXT_READY || pa_stream_get_state(this->stream) != PA_STREAM_READY) return -1; if (pa_operation_get_state(o) != PA_OPERATION_RUNNING) return 0; pa_threaded_mainloop_wait(this->mainloop); } } static int ao_pulse_get_property (ao_driver_t *this_gen, int property) { pulse_driver_t *this = (pulse_driver_t *) this_gen; int result = 0; pa_operation *o = NULL; pa_threaded_mainloop_lock(this->mainloop); if (!this->stream || !this->context || pa_context_get_state(this->context) != PA_CONTEXT_READY || pa_stream_get_state(this->stream) != PA_STREAM_READY) { pa_threaded_mainloop_unlock(this->mainloop); return 0; } switch(property) { case AO_PROP_MUTE_VOL: case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: o = pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream), __xine_pa_sink_info_callback, this); break; } if (o) { wait_for_operation(this, o); pa_operation_unref(o); } switch(property) { case AO_PROP_MUTE_VOL: result = this->muted; break; case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: result = (int) (pa_sw_volume_to_linear(this->swvolume)*100); break; } pa_threaded_mainloop_unlock(this->mainloop); return result; } static int ao_pulse_set_property (ao_driver_t *this_gen, int property, int value) { pulse_driver_t *this = (pulse_driver_t *) this_gen; int result = ~value; pa_operation *o = NULL; pa_threaded_mainloop_lock(this->mainloop); if (!this->stream || !this->context || pa_context_get_state(this->context) != PA_CONTEXT_READY || pa_stream_get_state(this->stream) != PA_STREAM_READY) { pa_threaded_mainloop_unlock(this->mainloop); return 0; } switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: this->swvolume = pa_sw_volume_from_linear((double)value/100.0); pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); o = pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream), &this->cvolume, __xine_pa_context_success_callback, this); result = value; break; case AO_PROP_MUTE_VOL: this->muted = value; #if PA_PROTOCOL_VERSION >= 11 /* PulseAudio 0.9.7 and newer */ o = pa_context_set_sink_input_mute(this->context, pa_stream_get_index(this->stream), value, __xine_pa_context_success_callback, this); #else /* Get the current volume, so we can restore it properly. */ o = pa_context_get_sink_input_info(this->context, pa_stream_get_index(this->stream), __xine_pa_sink_info_callback, this); if (o) { wait_for_operation(this, o); pa_operation_unref(o); } if ( value ) pa_cvolume_mute(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels); else pa_cvolume_set(&this->cvolume, pa_stream_get_sample_spec(this->stream)->channels, this->swvolume); o = pa_context_set_sink_input_volume(this->context, pa_stream_get_index(this->stream), &this->cvolume, __xine_pa_context_success_callback, this); #endif result = value; } if (o) { wait_for_operation(this, o); pa_operation_unref(o); } pa_threaded_mainloop_unlock(this->mainloop); return result; } static int ao_pulse_ctrl(ao_driver_t *this_gen, int cmd, ...) { pulse_driver_t *this = (pulse_driver_t *) this_gen; pa_operation *o = NULL; pa_threaded_mainloop_lock(this->mainloop); if (!this->stream || !this->context || pa_context_get_state(this->context) != PA_CONTEXT_READY || pa_stream_get_state(this->stream) != PA_STREAM_READY) { pa_threaded_mainloop_unlock(this->mainloop); return 0; } switch (cmd) { case AO_CTRL_FLUSH_BUFFERS: o = pa_stream_flush(this->stream, __xine_pa_stream_success_callback, this); break; case AO_CTRL_PLAY_RESUME: case AO_CTRL_PLAY_PAUSE: o = pa_stream_cork(this->stream, cmd == AO_CTRL_PLAY_PAUSE, __xine_pa_stream_success_callback, this); break; } if (o) { wait_for_operation(this, o); pa_operation_unref(o); } pa_threaded_mainloop_unlock(this->mainloop); return 0; } static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { pulse_class_t *class = (pulse_class_t *) class_gen; pulse_driver_t *this; const char* device; int r; #if PA_CHECK_VERSION(1,0,0) int a52_passthru; #endif lprintf ("audio_pulse_out: open_plugin called\n"); (void)data; this = calloc(1, sizeof (pulse_driver_t)); if (!this) return NULL; this->xine = class->xine; this->host = NULL; this->sink = NULL; this->context = NULL; this->mainloop = NULL; device = class->xine->config->register_string(class->xine->config, "audio.pulseaudio_device", "", _("device used for pulseaudio"), _("use 'server[:sink]' for setting the " "pulseaudio sink device."), 10, NULL, NULL); #if PA_CHECK_VERSION(1,0,0) a52_passthru = class->xine->config->register_bool(class->xine->config, "audio.device.pulseaudio_a52_pass_through", 0, _("use A/52 pass through"), _("Enable this, if your want to use digital audio " "pass through with pulseaudio.\nYou need to connect a digital " "surround decoder capable of decoding the formats you want " "to play to your sound card's digital output."), 10, NULL, NULL); #endif if (device && *device) { char *sep = strrchr(device, ':'); if ( sep ) { if (!(this->host = strndup(device, sep-device))) { free(this); return NULL; } if (!(this->sink = strdup(sep+1))) { free(this->host); free(this); return NULL; } } else { if (!(this->host = strdup(device))) { free(this); return NULL; } } } _x_assert(!this->mainloop); this->mainloop = pa_threaded_mainloop_new(); if (!this->mainloop) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: pa_threaded_mainloop_new() failed\n"); ao_pulse_exit((ao_driver_t *) this); return NULL; } pa_threaded_mainloop_start(this->mainloop); /* * set capabilities */ this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL | AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL | AO_CAP_MIXER_VOL | AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL | AO_CAP_8BITS | AO_CAP_16BITS | AO_CAP_FLOAT32; #if PA_CHECK_VERSION(1,0,0) if (a52_passthru) { this->capabilities |= AO_CAP_MODE_A52; this->capabilities |= AO_CAP_MODE_AC5; } #endif this->sample_rate = 0; this->ao_driver.get_capabilities = ao_pulse_get_capabilities; this->ao_driver.get_property = ao_pulse_get_property; this->ao_driver.set_property = ao_pulse_set_property; this->ao_driver.open = ao_pulse_open; this->ao_driver.num_channels = ao_pulse_num_channels; this->ao_driver.bytes_per_frame = ao_pulse_bytes_per_frame; this->ao_driver.delay = ao_pulse_delay; this->ao_driver.write = ao_pulse_write; this->ao_driver.close = ao_pulse_close; this->ao_driver.exit = ao_pulse_exit; this->ao_driver.get_gap_tolerance = ao_pulse_get_gap_tolerance; this->ao_driver.control = ao_pulse_ctrl; xprintf (class->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: host %s sink %s\n", this->host ? this->host : "(null)", this->sink ? this->sink : "(null)"); this->pa_class = class; pa_threaded_mainloop_lock(this->mainloop); r = connect_context(this); pa_threaded_mainloop_unlock(this->mainloop); if (r < 0) { ao_pulse_exit((ao_driver_t *) this); return NULL; } this->volume_bool = 1; return &this->ao_driver; } /* * class functions */ static void dispose_class (audio_driver_class_t *this_gen) { pulse_class_t *this = (pulse_class_t *) this_gen; free(this); } static void *init_class (xine_t *xine, const void *data) { pulse_class_t *this; lprintf ("audio_pulse_out: init class\n"); (void)data; this = calloc(1, sizeof (pulse_class_t)); if (!this) return NULL; this->xine = xine; this->driver_class.open_plugin = open_plugin; this->driver_class.dispose = dispose_class; this->driver_class.identifier = "pulseaudio"; this->driver_class.description = N_("xine audio output plugin using pulseaudio sound server"); return this; } static const ao_info_t ao_info_pulse = { .priority = 12, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, 9, "pulseaudio", XINE_VERSION_CODE, &ao_info_pulse, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_coreaudio_out.c����������������������������������������������������0000644�0001750�0001750�00000042433�14647725152�017637� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * done by Daniel Mack <xine@zonque.org> * modified by Rich Wareham <richwareham@users.sourceforge.net> * * See http://developer.apple.com/technotes/tn2002/tn2091.html * and http://developer.apple.com/documentation/MusicAudio/Reference/CoreAudio/index.html * for conceptual documentation. * * The diffuculty here is that CoreAudio is pull-i/o while xine's internal * system works on push-i/o basis. So there is need of a buffer inbetween. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <inttypes.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include <CoreAudio/CoreAudio.h> #include <CoreAudio/CoreAudioTypes.h> #include <AudioUnit/AUComponent.h> #include <AudioUnit/AudioUnitProperties.h> #include <AudioUnit/AudioUnitParameters.h> #include <AudioUnit/AudioOutputUnit.h> #include <CoreServices/CoreServices.h> #define AO_OUT_COREAUDIO_IFACE_VERSION 9 #define GAP_TOLERANCE AO_MAX_GAP #define BUFSIZE 30720 /* Number of seconds to wait for buffered data to arrive/be used * before giving up. */ #define BUFFER_TIMEOUT 1 typedef struct coreaudio_driver_s { ao_driver_t ao_driver; xine_t *xine; int capabilities; int32_t sample_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; Component au_component; Component converter_component; AudioUnit au_unit; AudioUnit converter_unit; uint8_t buf[BUFSIZE]; uint32_t buf_head; uint32_t last_block_size; uint32_t buffered; int mute; Float32 pre_mute_volume; pthread_mutex_t mutex; pthread_cond_t buffer_ready_for_reading; pthread_cond_t buffer_ready_for_writing; } coreaudio_driver_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } coreaudio_class_t; inline void set_to_future(struct timespec *spec); inline void set_to_future(struct timespec *spec) { struct timeval tv; gettimeofday(&tv, NULL); spec->tv_sec = tv.tv_sec + BUFFER_TIMEOUT; spec->tv_nsec = tv.tv_usec * 1000; } /* this function is called every time the CoreAudio sytem wants us to * supply some data */ static OSStatus ao_coreaudio_render_proc (coreaudio_driver_t *this, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, unsigned int inBusNumber, unsigned int inNumberFrames, AudioBufferList * ioData) { int32_t i = 0; int32_t buffer_progress = 0; int32_t buffer_size = 0; int32_t chunk_size = 0; int32_t req_size = 0; struct timespec future; this->buffered = 0; while(i < ioData->mNumberBuffers) { buffer_size = ioData->mBuffers[i].mDataByteSize; pthread_mutex_lock (&this->mutex); if(this->buf_head < ((BUFSIZE) >> 2)) { set_to_future(&future); if(pthread_cond_timedwait (&this->buffer_ready_for_reading, &this->mutex, &future) == ETIMEDOUT) { /* Timed out, give up and fill remainder with silence. */ while(i < ioData->mNumberBuffers) { memset(ioData->mBuffers[i].mData, 0, ioData->mBuffers[i].mDataByteSize); i++; } pthread_mutex_unlock (&this->mutex); return noErr; } } if(this->buf_head < buffer_size - buffer_progress) { chunk_size = this->buf_head; } else { chunk_size = buffer_size - buffer_progress; } xine_fast_memcpy (ioData->mBuffers[i].mData, this->buf, chunk_size); if(chunk_size < this->buf_head) { memmove(this->buf, &(this->buf[chunk_size]), this->buf_head - chunk_size); } this->buf_head -= chunk_size; buffer_progress += chunk_size; this->buffered += chunk_size; req_size += chunk_size; if(this->buf_head < ((BUFSIZE) >> 2)) { pthread_cond_broadcast (&this->buffer_ready_for_writing); } pthread_mutex_unlock (&this->mutex); if(buffer_progress == buffer_size) { i++; buffer_progress = 0; } } this->last_block_size = req_size; return noErr; } /* * open the audio device for writing to */ static int ao_coreaudio_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; unsigned int err; /* CoreAudio and AudioUnit related stuff */ AURenderCallbackStruct input; AudioStreamBasicDescription format; AudioUnitConnection connection; ComponentDescription desc; switch (mode) { case AO_CAP_MODE_MONO: this->num_channels = 1; break; case AO_CAP_MODE_STEREO: this->num_channels = 2; break; } this->sample_rate = rate; this->bits_per_sample = bits; this->capabilities = AO_CAP_16BITS | AO_CAP_MODE_STEREO | AO_CAP_MIXER_VOL; this->bytes_per_frame = this->num_channels * (bits / 8); this->buf_head = 0; this->last_block_size = 0; this->buffered = 0; pthread_mutex_init (&this->mutex, NULL); pthread_cond_init (&this->buffer_ready_for_reading, NULL); pthread_cond_init (&this->buffer_ready_for_writing, NULL); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_coreaudio_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); /* find an audio output unit */ desc.componentType = kAudioUnitType_Output; desc.componentSubType = kAudioUnitSubType_DefaultOutput; desc.componentManufacturer = kAudioUnitManufacturer_Apple; desc.componentFlags = 0; desc.componentFlagsMask = 0; this->au_component = FindNextComponent (NULL, &desc); if (this->au_component == NULL) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_coreaudio_out: Unable to find a usable audio output unit component\n"); return 0; } OpenAComponent (this->au_component, &this->au_unit); /* find a converter unit */ desc.componentType = kAudioUnitType_FormatConverter; desc.componentSubType = kAudioUnitSubType_AUConverter; this->converter_component = FindNextComponent (NULL, &desc); if (this->converter_component == NULL) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_coreaudio_out: Unable to find a usable audio converter unit component\n"); return 0; } OpenAComponent (this->converter_component, &this->converter_unit); /* set up the render procedure */ input.inputProc = (AURenderCallback) ao_coreaudio_render_proc; input.inputProcRefCon = this; AudioUnitSetProperty (this->converter_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &input, sizeof(input)); /* connect the converter unit to the audio output unit */ connection.sourceAudioUnit = this->converter_unit; connection.sourceOutputNumber = 0; connection.destInputNumber = 0; AudioUnitSetProperty (this->au_unit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0, &connection, sizeof(connection)); /* set up the audio format we want to use */ format.mSampleRate = rate; format.mFormatID = kAudioFormatLinearPCM; format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger #ifdef WORDS_BIGENDIAN | kLinearPCMFormatFlagIsBigEndian #endif | kLinearPCMFormatFlagIsPacked; format.mBitsPerChannel = this->bits_per_sample; format.mChannelsPerFrame = this->num_channels; format.mBytesPerFrame = this->bytes_per_frame; format.mFramesPerPacket = 1; format.mBytesPerPacket = format.mBytesPerFrame; AudioUnitSetProperty (this->converter_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &format, sizeof (format)); /* boarding completed, now initialize and start the units... */ err = AudioUnitInitialize (this->converter_unit); if (err) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_coreaudio_out: failed to AudioUnitInitialize(converter_unit)\n"); return 0; } err = AudioUnitInitialize (this->au_unit); if (err) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_coreaudio_out: failed to AudioUnitInitialize(au_unit)\n"); return 0; } err = AudioOutputUnitStart (this->au_unit); if (err) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_coreaudio_out: failed to AudioOutputUnitStart(au_unit)\n"); return 0; } return rate; } static int ao_coreaudio_num_channels(ao_driver_t *this_gen) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; return this->num_channels; } static int ao_coreaudio_bytes_per_frame(ao_driver_t *this_gen) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_coreaudio_get_gap_tolerance (ao_driver_t *this_gen) { return GAP_TOLERANCE; } static int ao_coreaudio_write(ao_driver_t *this_gen, int16_t *data, uint32_t num_frames) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; int remaining_bytes; /* In total we want to write num_frames * this->bytes_per_frame */ remaining_bytes = num_frames * this->bytes_per_frame; while(remaining_bytes > 0) { int32_t chunk_size; struct timespec future; pthread_mutex_lock (&this->mutex); if(this->buf_head > ((3 * BUFSIZE)>>2)) { set_to_future(&future); if(pthread_cond_timedwait (&this->buffer_ready_for_writing, &this->mutex, &future) == ETIMEDOUT) { /* Timed out, give up. */ pthread_mutex_unlock (&this->mutex); return 0; } } /* Write as many bytes as possible from buf_head -> end of buffer */ if(remaining_bytes > BUFSIZE - this->buf_head) { chunk_size = BUFSIZE - this->buf_head; } else { chunk_size = remaining_bytes; } xine_fast_memcpy(&(this->buf[this->buf_head]), data, chunk_size); this->buf_head += chunk_size; remaining_bytes -= chunk_size; if(this->buf_head > 0) { pthread_cond_broadcast (&this->buffer_ready_for_reading); } pthread_mutex_unlock (&this->mutex); } return 1; } static int ao_coreaudio_delay (ao_driver_t *this_gen) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; return (this->last_block_size + this->buffered + this->buf_head) / this->bytes_per_frame; } static void ao_coreaudio_close(ao_driver_t *this_gen) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; if (this->au_unit) { AudioOutputUnitStop (this->au_unit); AudioUnitUninitialize (this->au_unit); /* contrary to some of Apple's documentation, the function to close a * component is called CloseComponent, not CloseAComponent */ CloseComponent (this->au_unit); this->au_unit = 0; } if (this->converter_unit) { AudioUnitUninitialize (this->converter_unit); CloseComponent (this->converter_unit); this->converter_unit = 0; } if (this->au_component) { this->au_component = NULL; } if (this->converter_component) { this->converter_component = NULL; } pthread_mutex_destroy (&this->mutex); pthread_cond_destroy (&this->buffer_ready_for_reading); pthread_cond_destroy (&this->buffer_ready_for_writing); } static uint32_t ao_coreaudio_get_capabilities (ao_driver_t *this_gen) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; return this->capabilities; } static void ao_coreaudio_exit(ao_driver_t *this_gen) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; ao_coreaudio_close(this_gen); free (this); } static int ao_coreaudio_get_property (ao_driver_t *this_gen, int property) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; Float32 val; switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: if(!(this->mute)) { AudioUnitGetParameter (this->au_unit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0, &val); } else { val = this->pre_mute_volume; } return (int) (val * 12); break; case AO_PROP_MUTE_VOL: return this->mute; break; } return 0; } static int ao_coreaudio_set_property (ao_driver_t *this_gen, int property, int value) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; Float32 val; switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: if(!this->mute) { val = value / 12.0; AudioUnitSetParameter (this->au_unit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0, val, 0); } return value; break; case AO_PROP_MUTE_VOL: if(value) { /* Should mute */ if(!(this->mute)) { AudioUnitGetParameter (this->au_unit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0, &(this->pre_mute_volume)); AudioUnitSetParameter (this->au_unit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0, 0, 0); this->mute = 1; } } else { /* Should un-mute */ if(this->mute) { AudioUnitSetParameter (this->au_unit, kHALOutputParam_Volume, kAudioUnitScope_Output, 0, this->pre_mute_volume, 0); this->mute = 0; } } return value; break; } return ~value; } static int ao_coreaudio_ctrl(ao_driver_t *this_gen, int cmd, ...) { coreaudio_driver_t *this = (coreaudio_driver_t *) this_gen; switch (cmd) { case AO_CTRL_PLAY_PAUSE: AudioOutputUnitStop (this->au_unit); break; case AO_CTRL_PLAY_RESUME: AudioOutputUnitStart (this->au_unit); break; case AO_CTRL_FLUSH_BUFFERS: AudioUnitReset (this->au_unit, kAudioUnitScope_Input, 0); this->last_block_size = 0; this->buf_head = 0; break; } return 0; } static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { coreaudio_class_t *class = (coreaudio_class_t *) class_gen; coreaudio_driver_t *this; lprintf ("open_plugin called\n"); this = calloc(1, sizeof (coreaudio_driver_t)); if (!this) return NULL; this->xine = class->xine; this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO; this->sample_rate = 0; this->mute = 0; this->pre_mute_volume = 0; this->ao_driver.get_capabilities = ao_coreaudio_get_capabilities; this->ao_driver.get_property = ao_coreaudio_get_property; this->ao_driver.set_property = ao_coreaudio_set_property; this->ao_driver.open = ao_coreaudio_open; this->ao_driver.num_channels = ao_coreaudio_num_channels; this->ao_driver.bytes_per_frame = ao_coreaudio_bytes_per_frame; this->ao_driver.delay = ao_coreaudio_delay; this->ao_driver.write = ao_coreaudio_write; this->ao_driver.close = ao_coreaudio_close; this->ao_driver.exit = ao_coreaudio_exit; this->ao_driver.get_gap_tolerance = ao_coreaudio_get_gap_tolerance; this->ao_driver.control = ao_coreaudio_ctrl; return &this->ao_driver; } /* * class functions */ static void *init_class (xine_t *xine, const void *data) { coreaudio_class_t *this; lprintf ("init class\n"); this = calloc(1, sizeof (coreaudio_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "coreaudio"; this->driver_class.description = N_("xine output plugin for Coreaudio/Mac OS X"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; return this; } static const ao_info_t ao_info_coreaudio = { .priority = 1, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_COREAUDIO_IFACE_VERSION, "coreaudio", XINE_VERSION_CODE, &ao_info_coreaudio, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/Makefile.am��������������������������������������������������������������0000644�0001750�0001750�00000010321�14647725152�015474� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������-include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) noinst_HEADERS = speakers.h ## # IMPORTANT: # --------- # all xine audio out plugins should be named like the # scheme "xineplug_ao_out_" # EXTRA_DIST = audio_irixal_out.c if !ENABLE_LIBXINE_BUILTINS ao_builtins = xineplug_ao_out_none.la xineplug_ao_out_file.la endif if ENABLE_OSS oss_module = xineplug_ao_out_oss.la endif if ENABLE_ALSA alsa_module = xineplug_ao_out_alsa.la endif if ENABLE_ESD esd_module = xineplug_ao_out_esd.la endif if ENABLE_SUNAUDIO sun_module = xineplug_ao_out_sun.la endif #if ENABLE_IRIXAL #irixal_module = xineplug_ao_out_irixal.la #endif if ENABLE_DIRECTX directx_module = xineplug_ao_out_directx.la directx2_module = xineplug_ao_out_directx2.la endif if ENABLE_COREAUDIO coreaudio_module = xineplug_ao_out_coreaudio.la endif if ENABLE_PULSEAUDIO pulseaudio_module = xineplug_ao_out_pulseaudio.la endif if ENABLE_FUSIONSOUND fusionsound_module = xineplug_ao_out_fusionsound.la endif if ENABLE_JACK jack_module = xineplug_ao_out_jack.la endif if ENABLE_SNDIO sndio_module = xineplug_ao_out_sndio.la endif if ENABLE_OPENSLES opensles_module = xineplug_ao_out_opensles.la endif xineplug_LTLIBRARIES = \ $(ao_builtins) \ $(oss_module) \ $(alsa_module) \ $(sun_module) \ $(esd_module) \ $(directx_module) \ $(coreaudio_module) \ $(pulseaudio_module) \ $(directx2_module) \ $(fusionsound_module) \ $(jack_module) \ $(opensles_module) \ $(sndio_module) xineplug_ao_out_none_la_SOURCES = audio_none_out.c xineplug_ao_out_none_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_ao_out_file_la_SOURCES = audio_file_out.c xineplug_ao_out_file_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_ao_out_oss_la_SOURCES = audio_oss_out.c xineplug_ao_out_oss_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(OSS_LIBS) xineplug_ao_out_alsa_la_SOURCES = audio_alsa_out.c xineplug_ao_out_alsa_la_LIBADD = $(XINE_LIB) $(ALSA_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_ao_out_alsa_la_CFLAGS = $(AM_CFLAGS) $(ALSA_CFLAGS) xineplug_ao_out_esd_la_SOURCES = audio_esd_out.c xineplug_ao_out_esd_la_LIBADD = $(XINE_LIB) $(ESD_LIBS) $(LTLIBINTL) xineplug_ao_out_esd_la_CFLAGS = $(AM_CFLAGS) $(ESD_CFLAGS) xineplug_ao_out_sun_la_SOURCES = audio_sun_out.c xineplug_ao_out_sun_la_LIBADD = $(XINE_LIB) #xineplug_ao_out_irixal_la_SOURCES = audio_irixal_out.c #xineplug_ao_out_irixal_la_LIBADD = $(IRIXAL_LIBS) #xineplug_ao_out_irixal_la_CFLAGS = $(AM_CFLAGS) $(IRIXAL_CFLAGS) xineplug_ao_out_directx_la_SOURCES = audio_directx_out.c xineplug_ao_out_directx_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(LTLIBINTL) xineplug_ao_out_directx_la_CFLAGS = $(AM_CFLAGS) $(DIRECTX_CFLAGS) -fno-strict-aliasing xineplug_ao_out_directx_la_CPPFLAGS = $(AM_CPPFLAGS) $(DIRECTX_CPPFLAGS) xineplug_ao_out_coreaudio_la_SOURCES = audio_coreaudio_out.c xineplug_ao_out_coreaudio_la_LIBADD = $(XINE_LIB) xineplug_ao_out_coreaudio_la_LDFLAGS = $(AM_LDFLAGS) -framework CoreAudio -framework AudioUnit xineplug_ao_out_pulseaudio_la_SOURCES = audio_pulse_out.c xineplug_ao_out_pulseaudio_la_LIBADD = $(XINE_LIB) $(PULSEAUDIO_LIBS) $(LTLIBINTL) xineplug_ao_out_pulseaudio_la_CFLAGS = $(AM_CFLAGS) $(PULSEAUDIO_CFLAGS) xineplug_ao_out_directx2_la_SOURCES = audio_directx2_out.c xineplug_ao_out_directx2_la_CPPFLAGS = $(AM_CPPFLAGS) $(DIRECTX_CPPFLAGS) xineplug_ao_out_directx2_la_LIBADD = $(XINE_LIB) $(DIRECTX_AUDIO_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_ao_out_fusionsound_la_SOURCES = audio_fusionsound_out.c xineplug_ao_out_fusionsound_la_LIBADD = $(XINE_LIB) $(FUSIONSOUND_LIBS) xineplug_ao_out_fusionsound_la_CFLAGS = $(AM_CFLAGS) $(FUSIONSOUND_CFLAGS) xineplug_ao_out_jack_la_SOURCES = audio_jack_out.c xineplug_ao_out_jack_la_LIBADD = $(XINE_LIB) $(JACK_LIBS) $(LTLIBINTL) xineplug_ao_out_jack_la_CFLAGS = $(AM_FLAGS) $(JACK_CFLAGS) xineplug_ao_out_sndio_la_SOURCES = audio_sndio_out.c xineplug_ao_out_sndio_la_LIBADD = $(XINE_LIB) $(SNDIO_LIBS) xineplug_ao_out_sndio_la_CFLAGS = $(AM_CFLAGS) $(SNDIO_CFLAGS) xineplug_ao_out_opensles_la_SOURCES = audio_opensles_out.c xineplug_ao_out_opensles_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) -lm xineplug_ao_out_opensles_la_CFLAGS = $(AM_CFLAGS) $(OPENSLES_CFLAGS) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_sun_out.c����������������������������������������������������������0000644�0001750�0001750�00000064742�14647725152�016501� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <sys/audioio.h> #if HAVE_SYS_MIXER_H #include <sys/mixer.h> #endif #include <sys/uio.h> #include <sys/ioctl.h> #include <inttypes.h> #ifdef __svr4__ #include <stropts.h> #endif #include <sys/param.h> #if (defined(BSD) && BSD >= 199306) typedef unsigned uint_t; #endif #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #ifdef __svr4__ #define CS4231_WORKAROUND 1 /* enable workaround for audiocs play.samples bug */ #define SW_SAMPLE_COUNT 1 #endif #ifndef AUDIO_CHANNELS_MONO #define AUDIO_CHANNELS_MONO 1 #define AUDIO_CHANNELS_STEREO 2 #endif #ifndef AUDIO_PRECISION_8 #define AUDIO_PRECISION_8 8 #define AUDIO_PRECISION_16 16 #endif #define AO_SUN_IFACE_VERSION 9 #define GAP_TOLERANCE 5000 #define GAP_NONRT_TOLERANCE AO_MAX_GAP #define NOT_REAL_TIME -1 typedef struct { audio_driver_class_t driver_class; xine_t *xine; } sun_class_t; typedef struct sun_driver_s { ao_driver_t ao_driver; xine_t *xine; char *audio_dev; int audio_fd; int capabilities; int mode; int32_t output_sample_rate, input_sample_rate; double sample_rate_factor; uint32_t num_channels; int bytes_per_frame; #ifdef __svr4__ uint32_t frames_in_buffer; /* number of frames writen to audio hardware */ #endif enum { RTSC_UNKNOWN = 0, RTSC_ENABLED, RTSC_DISABLED } use_rtsc; int convert_u8_s8; /* Builtin conversion 8-bit UNSIGNED->SIGNED */ int mixer_volume; #if CS4231_WORKAROUND /* * Sun's audiocs driver has problems counting samples when we send * sound data chunks with a length that is not a multiple of 1024. * As a workaround for this problem, we re-block the audio stream, * so that we always send buffers of samples to the driver that have * a size of N*1024 bytes; */ #define MIN_WRITE_SIZE 1024 char buffer[MIN_WRITE_SIZE]; unsigned buf_len; #endif #ifdef __svr4__ #if SW_SAMPLE_COUNT struct timeval tv0; size_t sample0; #endif size_t last_samplecnt; #endif } sun_driver_t; /* * try to figure out, if the soundcard driver provides usable (precise) * sample counter information */ static int realtime_samplecounter_available(xine_t *xine, char *dev) { #ifdef __svr4__ int fd = -1; audio_info_t info; int rtsc_ok = RTSC_DISABLED; int len; void *silence = NULL; struct timeval start, end; struct timespec delay; int usec_delay; unsigned last_samplecnt; unsigned increment; unsigned min_increment; len = 44100 * 4 / 4; /* amount of data for 0.25sec of 44.1khz, stereo, * 16bit. 44kbyte can be sent to all supported * sun audio devices without blocking in the * "write" below. */ silence = calloc(1, len); if (silence == NULL) goto error; if ((fd = xine_open_cloexec(dev, O_WRONLY|O_NONBLOCK)) < 0) goto error; /* We wanted non blocking open but now put it back to normal */ fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK); AUDIO_INITINFO(&info); info.play.sample_rate = 44100; info.play.channels = AUDIO_CHANNELS_STEREO; info.play.precision = AUDIO_PRECISION_16; info.play.encoding = AUDIO_ENCODING_LINEAR; info.play.samples = 0; if (ioctl(fd, AUDIO_SETINFO, &info)) { xprintf(xine, XINE_VERBOSITY_DEBUG, "rtsc: SETINFO failed\n"); goto error; } if (write(fd, silence, len) != len) { xprintf(xine, XINE_VERBOSITY_DEBUG, "rtsc: write failed\n"); goto error; } if (ioctl(fd, AUDIO_GETINFO, &info)) { xprintf(xine, XINE_VERBOSITY_DEBUG, "rtsc: GETINFO1, %s\n", strerror(errno)); goto error; } last_samplecnt = info.play.samples; min_increment = ~0; gettimeofday(&start, NULL); for (;;) { delay.tv_sec = 0; delay.tv_nsec = 10000000; nanosleep(&delay, NULL); gettimeofday(&end, NULL); usec_delay = (end.tv_sec - start.tv_sec) * 1000000 + end.tv_usec - start.tv_usec; /* stop monitoring sample counter after 0.2 seconds */ if (usec_delay > 200000) break; if (ioctl(fd, AUDIO_GETINFO, &info)) { xprintf(xine, XINE_VERBOSITY_DEBUG, "rtsc: GETINFO2 failed, %s\n", strerror(errno)); goto error; } if (info.play.samples < last_samplecnt) { xprintf(xine, XINE_VERBOSITY_DEBUG, "rtsc: %u > %u?\n", last_samplecnt, info.play.samples); goto error; } if ((increment = info.play.samples - last_samplecnt) > 0) { /* printf("audio_sun_out: sample counter increment: %d\n", increment); */ if (increment < min_increment) { min_increment = increment; if (min_increment < 2000) break; /* looks good */ } } last_samplecnt = info.play.samples; } /* * For 44.1kkz, stereo, 16-bit format we would send sound data in 16kbytes * chunks (== 4096 samples) to the audio device. If we see a minimum * sample counter increment from the soundcard driver of less than * 2000 samples, we assume that the driver provides a useable realtime * sample counter in the AUDIO_INFO play.samples field. Timing based * on sample counts should be much more accurate than counting whole * 16kbyte chunks. */ if (min_increment < 2000) rtsc_ok = RTSC_ENABLED; /* printf("audio_sun_out: minimum sample counter increment per 10msec interval: %d\n" "\t%susing sample counter based timing code\n", min_increment, rtsc_ok == RTSC_ENABLED ? "" : "not "); */ error: if (silence != NULL) free(silence); if (fd >= 0) { /* * remove the 0 bytes from the above measurement from the * audio driver's STREAMS queue */ ioctl(fd, I_FLUSH, FLUSHW); close(fd); } return rtsc_ok; #else return RTSC_ENABLED; #endif } /* * match the requested sample rate |sample_rate| against the * sample rates supported by the audio device |dev|. Return * a supported sample rate, it that sample rate is close to * (< 1% difference) the requested rate; return 0 otherwise. */ static int find_close_samplerate_match(int dev, int sample_rate) { #if HAVE_SYS_MIXER_H am_sample_rates_t *sr; int i, num, err, best_err, best_rate; for (num = 16; num < 1024; num *= 2) { sr = malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num)); if (!sr) return 0; sr->type = AUDIO_PLAY; sr->flags = 0; sr->num_samp_rates = num; if (ioctl(dev, AUDIO_MIXER_GET_SAMPLE_RATES, sr)) { free(sr); return 0; } if (sr->num_samp_rates <= num) break; free(sr); } if (sr->flags & MIXER_SR_LIMITS) { /* * HW can playback any rate between * sr->samp_rates[0] .. sr->samp_rates[1] */ free(sr); return 0; } else { /* HW supports fixed sample rates only */ best_err = 65535; best_rate = 0; for (i = 0; i < sr->num_samp_rates; i++) { err = abs(sr->samp_rates[i] - sample_rate); if (err == 0) { /* * exact supported sample rate match, no need to * retry something else */ best_rate = 0; break; } if (err < best_err) { best_err = err; best_rate = sr->samp_rates[i]; } } free(sr); if (best_rate > 0 && 100*best_err < sample_rate) { /* found a supported sample rate with <1% error? */ return best_rate; } return 0; } #else int i, err; static const int audiocs_rates[] = { 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050, 27420, 32000, 33075, 37800, 44100, 48000, 0 }; for (i = 0; audiocs_rates[i]; i++) { err = abs(audiocs_rates[i] - sample_rate); if (err == 0) { /* * exact supported sample rate match, no need to * retry something elise */ return 0; } if (100*err < audiocs_rates[i]) { /* <1% error? */ return audiocs_rates[i]; } } return 0; #endif } /* * return the highest sample rate supported by audio device |dev|. */ static int find_highest_samplerate(int dev) { #if HAVE_SYS_MIXER_H am_sample_rates_t *sr; int i, num, max_rate; for (num = 16; num < 1024; num *= 2) { sr = malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(num)); if (!sr) return 0; sr->type = AUDIO_PLAY; sr->flags = 0; sr->num_samp_rates = num; if (ioctl(dev, AUDIO_MIXER_GET_SAMPLE_RATES, sr)) { free(sr); return 0; } if (sr->num_samp_rates <= num) break; free(sr); } if (sr->flags & MIXER_SR_LIMITS) { /* * HW can playback any rate between * sr->samp_rates[0] .. sr->samp_rates[1] */ max_rate = sr->samp_rates[1]; } else { /* HW supports fixed sample rates only */ max_rate = 0; for (i = 0; i < sr->num_samp_rates; i++) { if (sr->samp_rates[i] > max_rate) max_rate = sr->samp_rates[i]; } } free(sr); return max_rate; #else return 44100; /* should be supported even on old ISA SB cards */ #endif } /* * open the audio device for writing to * * Implicit assumptions about audio format (bits/rate/mode): * * bits == 16: We always get 16-bit samples in native endian format, * using signed linear encoding * * bits == 8: 8-bit samples use unsigned linear encoding, * other 8-bit formats (uLaw, aLaw, etc) are currently not supported * by xine */ static int ao_sun_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { sun_driver_t *this = (sun_driver_t *) this_gen; audio_info_t info; int pass; int ok; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_sun_out: ao_sun_open rate=%d, mode=%d\n", rate, mode); if ( (mode & this->capabilities) == 0 ) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_sun_out: unsupported mode %08x\n", mode); return 0; } if (this->audio_fd >= 0) { if ( (mode == this->mode) && (rate == this->input_sample_rate) ) return this->output_sample_rate; close (this->audio_fd); } this->mode = mode; this->input_sample_rate = rate; #ifdef __svr4__ this->frames_in_buffer = 0; #endif /* * open audio device */ this->audio_fd = xine_open_cloexec(this->audio_dev, O_WRONLY|O_NONBLOCK); if(this->audio_fd < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("audio_sun_out: opening audio device %s failed: %s\n"), this->audio_dev, strerror(errno)); return 0; } /* We wanted non blocking open but now put it back to normal */ fcntl(this->audio_fd, F_SETFL, fcntl(this->audio_fd, F_GETFL) & ~O_NONBLOCK); /* * configure audio device */ for (ok = pass = 0; pass <= 5; pass++) { AUDIO_INITINFO(&info); info.play.channels = (mode & AO_CAP_MODE_STEREO) ? AUDIO_CHANNELS_STEREO : AUDIO_CHANNELS_MONO; info.play.precision = bits; info.play.encoding = bits == 8 ? AUDIO_ENCODING_LINEAR8 : AUDIO_ENCODING_LINEAR; info.play.sample_rate = this->input_sample_rate; info.play.eof = 0; info.play.samples = 0; #ifndef __svr4__ info.blocksize = 1024; #endif this->convert_u8_s8 = 0; if (pass & 1) { /* * on some sun audio drivers, 8-bit unsigned LINEAR8 encoding is * not supported, but 8-bit signed encoding is. * * Try S8, and if it works, use our own U8->S8 conversion before * sending the samples to the sound driver. */ if (info.play.encoding != AUDIO_ENCODING_LINEAR8) continue; info.play.encoding = AUDIO_ENCODING_LINEAR; this->convert_u8_s8 = 1; } if (pass & 2) { /* * on some sun audio drivers, only certain fixed sample rates are * supported. * * In case the requested sample rate is very close to one of the * supported rates, use the fixed supported rate instead. * * XXX: assuming the fixed supported rate works, should we * lie with our return value and report the requested input * sample rate, to avoid the software resample code? */ if (!(info.play.sample_rate = find_close_samplerate_match(this->audio_fd, this->input_sample_rate))) continue; } if (pass & 4) { /* like "pass & 2", but use the highest supported sample rate */ if (!(info.play.sample_rate = find_highest_samplerate(this->audio_fd))) continue; } if ((ok = ioctl(this->audio_fd, AUDIO_SETINFO, &info) >= 0)) { /* audio format accepted by audio driver */ break; } /* * format not supported? * retry with different encoding and/or sample rate */ } if (!ok) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_sun_out: Cannot configure audio device for %dhz, %d channel, %d bits: %s\n", rate, info.play.channels, bits, strerror(errno)); close(this->audio_fd); this->audio_fd = -1; return 0; } #ifdef __svr4__ this->last_samplecnt = 0; #endif this->output_sample_rate = info.play.sample_rate; this->num_channels = info.play.channels; this->bytes_per_frame = 1; if (info.play.channels == AUDIO_CHANNELS_STEREO) this->bytes_per_frame *= 2; if (info.play.precision == 16) this->bytes_per_frame *= 2; #if CS4231_WORKAROUND this->buf_len = 0; #endif /* printf ("audio_sun_out: audio rate : %d requested, %d provided by device/sec\n", this->input_sample_rate, this->output_sample_rate); */ xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_sun_out: %d channels output\n",this->num_channels); return this->output_sample_rate; } static int ao_sun_num_channels(ao_driver_t *this_gen) { sun_driver_t *this = (sun_driver_t *) this_gen; return this->num_channels; } static int ao_sun_bytes_per_frame(ao_driver_t *this_gen) { sun_driver_t *this = (sun_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_sun_delay(ao_driver_t *this_gen) { sun_driver_t *this = (sun_driver_t *) this_gen; audio_info_t info; #ifdef __svr4__ if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) == 0 && (this->frames_in_buffer == 0 || info.play.samples > 0)) { if (info.play.samples < this->last_samplecnt) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_sun_out: broken sound driver, sample counter runs backwards, cur %u < prev %u\n", info.play.samples, this->last_samplecnt); } this->last_samplecnt = info.play.samples; if (this->use_rtsc == RTSC_ENABLED) return this->frames_in_buffer - info.play.samples; #if SW_SAMPLE_COUNT /* compute "current sample" based on real time */ { struct timeval tv1; size_t cur_sample; size_t msec; gettimeofday(&tv1, NULL); msec = (tv1.tv_sec - this->tv0.tv_sec) * 1000 + (tv1.tv_usec - this->tv0.tv_usec) / 1000; cur_sample = this->sample0 + this->output_sample_rate * msec / 1000; if (info.play.error) { AUDIO_INITINFO(&info); info.play.error = 0; ioctl(this->audio_fd, AUDIO_SETINFO, &info); } /* * more than 0.5 seconds difference between HW sample counter and * computed sample counter? -> re-initialize */ if (abs(cur_sample - info.play.samples) > this->output_sample_rate/2) { this->tv0 = tv1; this->sample0 = cur_sample = info.play.samples; } return this->frames_in_buffer - cur_sample; } #endif } #else if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) == 0) return info.play.seek / this->bytes_per_frame; #endif return NOT_REAL_TIME; } static int ao_sun_get_gap_tolerance (ao_driver_t *this_gen) { sun_driver_t *this = (sun_driver_t *) this_gen; if (this->use_rtsc == RTSC_ENABLED) return GAP_TOLERANCE; else return GAP_NONRT_TOLERANCE; } #if CS4231_WORKAROUND /* * Sun's audiocs driver has problems counting samples when we send * sound data chunks with a length that is not a multiple of 1024. * As a workaround for this problem, we re-block the audio stream, * so that we always send buffers of samples to the driver that have * a size of N*1024 bytes; */ static int sun_audio_write(sun_driver_t *this, char *buf, unsigned nbytes) { unsigned total_bytes, remainder; int num_written; unsigned orig_nbytes = nbytes; total_bytes = this->buf_len + nbytes; remainder = total_bytes % MIN_WRITE_SIZE; if ((total_bytes -= remainder) > 0) { struct iovec iov[2]; int iovcnt = 0; if (this->buf_len > 0) { iov[iovcnt].iov_base = this->buffer; iov[iovcnt].iov_len = this->buf_len; iovcnt++; } iov[iovcnt].iov_base = buf; iov[iovcnt].iov_len = total_bytes - this->buf_len; this->buf_len = 0; buf += iov[iovcnt].iov_len; nbytes -= iov[iovcnt].iov_len; num_written = writev(this->audio_fd, iov, iovcnt+1); if (num_written != total_bytes) return -1; } if (nbytes > 0) { memcpy(this->buffer + this->buf_len, buf, nbytes); this->buf_len += nbytes; } return orig_nbytes; } static void sun_audio_flush(sun_driver_t *this) { if (this->buf_len > 0) { write(this->audio_fd, this->buffer, this->buf_len); this->buf_len = 0; } } #else static int sun_audio_write(sun_driver_t *this, char *buf, unsigned nbytes) { return write(this->audio_fd, buf, nbytes); } static void sun_audio_flush(sun_driver_t *this) { } #endif /* Write audio samples * num_frames is the number of audio frames present * audio frames are equivalent one sample on each channel. * I.E. Stereo 16 bits audio frames are 4 bytes. */ static int ao_sun_write(ao_driver_t *this_gen, int16_t* data, uint32_t num_frames) { uint8_t *frame_buffer=(uint8_t *)data; sun_driver_t *this = (sun_driver_t *) this_gen; int num_written; if (this->convert_u8_s8) { /* * Audio hardware does not support 8-bit unsigned format, * only 8-bit signed. Convert to 8-bit unsigned before sending * the data to the audio device. */ uint8_t *p = (void *)frame_buffer; int i; for (i = num_frames * this->bytes_per_frame; --i >= 0; p++) *p ^= 0x80; } num_written = sun_audio_write(this, frame_buffer, num_frames * this->bytes_per_frame); if (num_written > 0) { int buffered_samples; #ifdef __svr4__ this->frames_in_buffer += num_written / this->bytes_per_frame; #endif /* * Avoid storing too much data in the sound driver's buffers. * * When we find more than 3 seconds of buffered audio data in the * driver's buffer, deliberately block sending of more data, until * there is less then 2 seconds of buffered samples. * * During an active audio playback, this helps when either the * xine engine is stopped or a seek operation is performed. In * both cases the buffered audio samples need to be flushed from * the xine engine and the audio driver anyway. */ if ((buffered_samples = ao_sun_delay(this_gen)) >= 3*this->output_sample_rate) { sleep(buffered_samples/this->output_sample_rate - 2); } } return num_written; } static void ao_sun_close(ao_driver_t *this_gen) { sun_driver_t *this = (sun_driver_t *) this_gen; sun_audio_flush(this); close(this->audio_fd); this->audio_fd = -1; } static uint32_t ao_sun_get_capabilities (ao_driver_t *this_gen) { sun_driver_t *this = (sun_driver_t *) this_gen; return this->capabilities; } static void ao_sun_exit(ao_driver_t *this_gen) { sun_driver_t *this = (sun_driver_t *) this_gen; if (this->audio_fd >= 0) close(this->audio_fd); free (this); } /* * Get a property of audio driver. * return 1 in success, 0 on failure. (and the property value?) */ static int ao_sun_get_property (ao_driver_t *this_gen, int property) { sun_driver_t *this = (sun_driver_t *) this_gen; audio_info_t info; switch(property) { case AO_PROP_MIXER_VOL: case AO_PROP_PCM_VOL: if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) > -1) { this->mixer_volume = info.play.gain * 100 / AUDIO_MAX_GAIN; } return this->mixer_volume; #ifdef HAVE_AUDIO_INFO_T_OUTPUT_MUTED case AO_PROP_MUTE_VOL: if (ioctl(this->audio_fd, AUDIO_GETINFO, &info) < 0) return 0; return info.output_muted; #endif } return 0; } /* * Set a property of audio driver. * return value on success, ~value on failure */ static int ao_sun_set_property (ao_driver_t *this_gen, int property, int value) { sun_driver_t *this = (sun_driver_t *) this_gen; audio_info_t info; AUDIO_INITINFO(&info); switch(property) { case AO_PROP_MIXER_VOL: case AO_PROP_PCM_VOL: this->mixer_volume = value; info.play.gain = value * AUDIO_MAX_GAIN / 100; if (ioctl(this->audio_fd, AUDIO_SETINFO, &info) < 0) return ~value; return value; #ifdef HAVE_AUDIO_INFO_T_OUTPUT_MUTED case AO_PROP_MUTE_VOL: info.output_muted = value != 0; if (ioctl(this->audio_fd, AUDIO_SETINFO, &info) < 0) return ~value; return value; #endif } return ~value; } static int ao_sun_ctrl(ao_driver_t *this_gen, int cmd, ...) { sun_driver_t *this = (sun_driver_t *) this_gen; audio_info_t info; switch (cmd) { case AO_CTRL_PLAY_PAUSE: AUDIO_INITINFO(&info); info.play.pause = 1; ioctl(this->audio_fd, AUDIO_SETINFO, &info); break; case AO_CTRL_PLAY_RESUME: AUDIO_INITINFO(&info); info.play.pause = 0; ioctl(this->audio_fd, AUDIO_SETINFO, &info); break; case AO_CTRL_FLUSH_BUFFERS: #ifdef __svr4__ /* flush buffered STEAMS data first */ ioctl(this->audio_fd, I_FLUSH, FLUSHW); /* * the flush above discarded an unknown amount of data from the * audio device. To get the "*_delay" computation in sync again, * reset the audio device's sample counter to 0, after waiting * that all samples still active playing on the sound hardware * have finished playing. */ AUDIO_INITINFO(&info); info.play.pause = 0; ioctl(this->audio_fd, AUDIO_SETINFO, &info); ioctl(this->audio_fd, AUDIO_DRAIN); AUDIO_INITINFO(&info); info.play.samples = 0; ioctl(this->audio_fd, AUDIO_SETINFO, &info); this->frames_in_buffer = 0; this->last_samplecnt = 0; #endif #ifdef __NetBSD__ ioctl(this->audio_fd, AUDIO_FLUSH); #endif break; } return 0; } static ao_driver_t *ao_sun_open_plugin (audio_driver_class_t *class_gen, const void *data) { sun_class_t *class = (sun_class_t *) class_gen; config_values_t *config = class->xine->config; sun_driver_t *this; char *devname; char *audiodev; int audio_fd; int status; audio_info_t info; this = calloc(1, sizeof (sun_driver_t)); if (!this) return NULL; this->xine = class->xine; audiodev = getenv("AUDIODEV"); /* This config entry is security critical, is it really necessary? */ devname = config->register_filename(config, "audio.device.sun_audio_device", audiodev && *audiodev ? audiodev : "/dev/audio", XINE_CONFIG_STRING_IS_DEVICE_NAME, _("Sun audio device name"), _("Specifies the file name for the Sun audio device " "to be used.\nThis setting is security critical, " "because when changed to a different file, xine " "can be used to fill this file with arbitrary content. " "So you should be careful that the value you enter " "really is a proper Sun audio device."), XINE_CONFIG_SECURITY, NULL, NULL); /* * find best device driver/channel */ xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_sun_out: Opening audio device %s...\n", devname); /* * open the device */ this->audio_dev = devname; this->audio_fd = xine_open_cloexec(devname, O_WRONLY|O_NONBLOCK); if(this->audio_fd < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("audio_sun_out: opening audio device %s failed: %s\n"), devname, strerror(errno)); free (this); return NULL; } /* * set up driver to reasonable values for capabilities tests */ AUDIO_INITINFO(&info); info.play.encoding = AUDIO_ENCODING_LINEAR; info.play.precision = AUDIO_PRECISION_16; info.play.sample_rate = 44100; status = ioctl(this->audio_fd, AUDIO_SETINFO, &info); if (status < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("audio_sun_out: audio ioctl on device %s failed: %s\n"), devname, strerror(errno)); free (this); return NULL; } /* * get capabilities */ this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_8BITS | AO_CAP_16BITS | AO_CAP_PCM_VOL; #ifdef __svr4__ this->capabilities |= AO_CAP_MUTE_VOL; #endif /* * get initial mixer volume */ this->mixer_volume = ao_sun_get_property(&this->ao_driver, AO_PROP_MIXER_VOL); close (this->audio_fd); this->audio_fd = -1; this->xine = class->xine; this->use_rtsc = realtime_samplecounter_available(this->xine, this->audio_dev); this->output_sample_rate = 0; this->ao_driver.get_capabilities = ao_sun_get_capabilities; this->ao_driver.get_property = ao_sun_get_property; this->ao_driver.set_property = ao_sun_set_property; this->ao_driver.open = ao_sun_open; this->ao_driver.num_channels = ao_sun_num_channels; this->ao_driver.bytes_per_frame = ao_sun_bytes_per_frame; this->ao_driver.delay = ao_sun_delay; this->ao_driver.write = ao_sun_write; this->ao_driver.close = ao_sun_close; this->ao_driver.exit = ao_sun_exit; this->ao_driver.get_gap_tolerance = ao_sun_get_gap_tolerance; this->ao_driver.control = ao_sun_ctrl; return &this->ao_driver; } /* * class functions */ static void *ao_sun_init_class (xine_t *xine, const void *data) { sun_class_t *this; this = calloc(1, sizeof (sun_class_t)); if (!this) return NULL; this->driver_class.open_plugin = ao_sun_open_plugin; this->driver_class.identifier = "sun"; this->driver_class.description = N_("xine audio output plugin using sun-compliant audio devices/drivers"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; return this; } static const ao_info_t ao_info_sun = { .priority = 10, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_SUN_IFACE_VERSION, "sun", XINE_VERSION_CODE, &ao_info_sun, ao_sun_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������xine-lib-1.2/src/audio_out/audio_oss_out.c����������������������������������������������������������0000644�0001750�0001750�00000104476�14647725152�016477� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * 20-8-2001 First implementation of Audio sync and Audio driver separation. * Copyright (C) 2001 James Courtier-Dutton James@superbug.demon.co.uk * * General Programming Guidelines: - * New concept of an "audio_frame". * An audio_frame consists of all the samples required to fill every audio channel * to a full amount of bits. So, it does not matter how many bits per sample, * or how many audio channels are being used, the number of audio_frames is the same. * E.g. 16 bit stereo is 4 bytes, but one frame. * 16 bit 5.1 surround is 12 bytes, but one frame. * The purpose of this is to make the audio_sync code a lot more readable, * rather than having to multiply by the amount of channels all the time * when dealing with audio_bytes instead of audio_frames. * * The number of samples passed to/from the audio driver is also sent in units of audio_frames. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <sys/ioctl.h> #include <inttypes.h> #ifdef HAVE_SYS_SOUNDCARD_H # include <sys/soundcard.h> #endif #define LOG_MODULE "audio_oss_out" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/audio_out.h> #include <sys/time.h> #include "speakers.h" #ifndef SNDCTL_DSP_SETFMT /* Deprecated OSS API */ #define SNDCTL_DSP_SETFMT SOUND_PCM_SETFMT #endif #ifndef SNDCTL_DSP_SPEED /* Deprecated OSS API */ #define SNDCTL_DSP_SPEED SOUND_PCM_WRITE_RATE #endif #ifndef AFMT_S16_NE # ifdef WORDS_BIGENDIAN # define AFMT_S16_NE AFMT_S16_BE # else # define AFMT_S16_NE AFMT_S16_LE # endif #endif #ifndef AFMT_AC3 # define AFMT_AC3 0x00000400 #endif #define AO_OUT_OSS_IFACE_VERSION 9 #define AUDIO_NUM_FRAGMENTS 15 #define AUDIO_FRAGMENT_SIZE 8192 /* bufsize must be a multiple of 3 and 5 for 5.0 and 5.1 channel playback! */ #define ZERO_BUF_SIZE 15360 #define GAP_TOLERANCE 5000 #define MAX_GAP 90000 #define OSS_SYNC_AUTO_DETECT 0 #define OSS_SYNC_GETODELAY 1 #define OSS_SYNC_GETOPTR 2 #define OSS_SYNC_SOFTSYNC 3 #define OSS_SYNC_PROBEBUFFER 4 typedef struct oss_driver_s { ao_driver_t ao_driver; char audio_dev[30]; int audio_fd; int capabilities; int mode; int32_t output_sample_rate, input_sample_rate; int32_t output_sample_k_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; uint32_t bytes_in_buffer; /* number of bytes writen to audio hardware */ uint32_t last_getoptr; int audio_started; int sync_method; int latency; int buffer_size; struct { int fd; int prop; int volume; int mute; } mixer; struct timeval start_time; xine_t *xine; } oss_driver_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } oss_class_t; /* * open the audio device for writing to */ static int ao_oss_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { oss_driver_t *this = (oss_driver_t *) this_gen; int tmp; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: ao_open rate=%d, mode=%d, dev=%s\n", rate, mode, this->audio_dev); if ( (mode & this->capabilities) == 0 ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: unsupported mode %08x\n", mode); return 0; } if (this->audio_fd > -1) { if ( (mode == this->mode) && (rate == (uint32_t)this->input_sample_rate) ) { return this->output_sample_rate; } close (this->audio_fd); } this->mode = mode; this->input_sample_rate = rate; this->bits_per_sample = bits; this->bytes_in_buffer = 0; this->last_getoptr = 0; this->audio_started = 0; /* * open audio device */ this->audio_fd = xine_open_cloexec(this->audio_dev, O_WRONLY|O_NONBLOCK); if (this->audio_fd < 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: Opening audio device %s: %s\n"), this->audio_dev, strerror(errno)); return 0; } /* We wanted non blocking open but now put it back to normal */ { int val = fcntl(this->audio_fd, F_GETFL); if (val != -1) val = fcntl(this->audio_fd, F_SETFL, val & ~O_NONBLOCK); if (val == -1) lprintf("error restoring blocking mode: %s\n", strerror(errno)); } /* * configure audio device * In A52 mode, skip all other SNDCTL commands */ if(!(mode & (AO_CAP_MODE_A52 | AO_CAP_MODE_AC5))) { tmp = (mode & AO_CAP_MODE_STEREO) ? 1 : 0; ioctl(this->audio_fd,SNDCTL_DSP_STEREO,&tmp); tmp = bits; ioctl(this->audio_fd,SNDCTL_DSP_SAMPLESIZE,&tmp); tmp = this->input_sample_rate; if (ioctl(this->audio_fd,SNDCTL_DSP_SPEED, &tmp) == -1) { xprintf(this->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: warning: sampling rate %d Hz not supported, trying 44100 Hz\n"), this->input_sample_rate); tmp = 44100; if (ioctl(this->audio_fd,SNDCTL_DSP_SPEED, &tmp) == -1) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: error: 44100 Hz sampling rate not supported\n"); return 0; } } this->output_sample_rate = tmp; this->output_sample_k_rate = this->output_sample_rate / 1000; xprintf(this->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: audio rate : %d requested, %d provided by device\n"), this->input_sample_rate, this->output_sample_rate); } /* * set number of channels / a52 passthrough */ switch (mode) { case AO_CAP_MODE_MONO: tmp = 1; ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); this->num_channels = tmp; break; case AO_CAP_MODE_STEREO: tmp = 2; ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); this->num_channels = tmp; break; case AO_CAP_MODE_4CHANNEL: tmp = 4; ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); this->num_channels = tmp; break; case AO_CAP_MODE_5CHANNEL: tmp = 5; ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); this->num_channels = tmp; break; case AO_CAP_MODE_5_1CHANNEL: tmp = 6; ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); this->num_channels = tmp; break; case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: tmp = AFMT_AC3; this->num_channels = 2; /* FIXME: is this correct ? */ this->output_sample_rate = this->input_sample_rate; this->output_sample_k_rate = this->output_sample_rate / 1000; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: AO_CAP_MODE_A52\n"); break; } xprintf(this->xine, XINE_VERBOSITY_LOG, "audio_oss_out: %d channels output\n", this->num_channels); this->bytes_per_frame=(this->bits_per_sample*this->num_channels)/8; /* * set format */ switch (mode) { case AO_CAP_MODE_MONO: case AO_CAP_MODE_STEREO: case AO_CAP_MODE_4CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: if (bits==8) tmp = AFMT_U8; else tmp = AFMT_S16_NE; if (ioctl(this->audio_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || (tmp!=AFMT_S16_NE && tmp!=AFMT_U8)) { if (bits==8) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: SNDCTL_DSP_SETFMT failed for AFMT_U8.\n"); if (tmp != AFMT_U8) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: ioctl succeeded but set format to 0x%x.\n",tmp); else xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: The AFMT_U8 ioctl failed.\n"); return 0; } else { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: SNDCTL_DSP_SETFMT failed for AFMT_S16_NE.\n"); if (tmp != AFMT_S16_NE) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: ioctl succeeded but set format to 0x%x.\n",tmp); else xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: The AFMT_S16_NE ioctl failed.\n"); return 0; } } break; case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: tmp = bits; ioctl(this->audio_fd,SNDCTL_DSP_SAMPLESIZE,&tmp); tmp = this->input_sample_rate; ioctl(this->audio_fd,SNDCTL_DSP_SPEED, &tmp); tmp = 2; ioctl(this->audio_fd, SNDCTL_DSP_CHANNELS, &tmp); tmp = AFMT_AC3; if (ioctl(this->audio_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 || tmp != AFMT_AC3) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: AC3 SNDCTL_DSP_SETFMT failed. %d. Using alternative.\n",tmp); tmp = AFMT_S16_LE; ioctl(this->audio_fd, SNDCTL_DSP_SETFMT, &tmp); } break; } /* * audio buffer size handling */ /* WARNING: let's hope for good defaults here... tmp=0 ; fsize = AUDIO_FRAGMENT_SIZE; while (fsize>0) { fsize /=2; tmp++; } tmp--; tmp = (AUDIO_NUM_FRAGMENTS << 16) | tmp ; printf ("audio_oss_out: audio buffer fragment info : %x\n",tmp); ioctl(this->audio_fd,SNDCTL_DSP_SETFRAGMENT,&tmp); */ return this->output_sample_rate; } static int ao_oss_num_channels(ao_driver_t *this_gen) { oss_driver_t *this = (oss_driver_t *) this_gen; return this->num_channels; } static int ao_oss_bytes_per_frame(ao_driver_t *this_gen) { oss_driver_t *this = (oss_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_oss_get_gap_tolerance (ao_driver_t *this_gen){ /* oss_driver_t *this = (oss_driver_t *) this_gen; */ (void)this_gen; return GAP_TOLERANCE; } static int ao_oss_delay(ao_driver_t *this_gen) { count_info info; oss_driver_t *this = (oss_driver_t *) this_gen; int bytes_left = 0; int frames; struct timeval tv; switch (this->sync_method) { case OSS_SYNC_PROBEBUFFER: if( (int)(this->bytes_in_buffer) < this->buffer_size ) bytes_left = this->bytes_in_buffer; else bytes_left = this->buffer_size; break; case OSS_SYNC_SOFTSYNC: /* use system real-time clock to get pseudo audio frame position */ xine_monotonic_clock(&tv, NULL); frames = (tv.tv_usec - this->start_time.tv_usec) * this->output_sample_k_rate / 1000; frames += (tv.tv_sec - this->start_time.tv_sec) * this->output_sample_rate; frames -= this->latency * this->output_sample_k_rate; /* calc delay */ bytes_left = this->bytes_in_buffer - frames * this->bytes_per_frame; if (bytes_left<=0) /* buffer ran dry */ bytes_left = 0; break; case OSS_SYNC_GETODELAY: #ifdef SNDCTL_DSP_GETODELAY if (ioctl (this->audio_fd, SNDCTL_DSP_GETODELAY, &bytes_left)) { perror ("audio_oss_out: DSP_GETODELAY ioctl():"); } if (bytes_left<0) bytes_left = 0; lprintf ("%d bytes left\n", bytes_left); break; #endif case OSS_SYNC_GETOPTR: if (ioctl (this->audio_fd, SNDCTL_DSP_GETOPTR, &info)) { perror ("audio_oss_out: SNDCTL_DSP_GETOPTR failed:"); } lprintf ("%d bytes output\n", info.bytes); if ((int)(this->bytes_in_buffer) < info.bytes) { this->bytes_in_buffer -= this->last_getoptr; /* GETOPTR wrapped */ } bytes_left = this->bytes_in_buffer - info.bytes; /* calc delay */ if (bytes_left<=0) { /* buffer ran dry */ bytes_left = 0; this->bytes_in_buffer = info.bytes; } this->last_getoptr = info.bytes; break; } return bytes_left / this->bytes_per_frame; } /* Write audio samples * num_frames is the number of audio frames present * audio frames are equivalent one sample on each channel. * I.E. Stereo 16 bits audio frames are 4 bytes. */ static int ao_oss_write(ao_driver_t *this_gen, int16_t* frame_buffer, uint32_t num_frames) { oss_driver_t *this = (oss_driver_t *) this_gen; int n; lprintf ("ao_oss_write %d frames\n", num_frames); if (this->sync_method == OSS_SYNC_SOFTSYNC) { int simulated_bytes_in_buffer, frames ; struct timeval tv; /* check if simulated buffer ran dry */ xine_monotonic_clock(&tv, NULL); frames = (tv.tv_usec - this->start_time.tv_usec) * this->output_sample_k_rate / 1000; frames += (tv.tv_sec - this->start_time.tv_sec) * this->output_sample_rate; /* calc delay */ simulated_bytes_in_buffer = frames * this->bytes_per_frame; if ((int)(this->bytes_in_buffer) < simulated_bytes_in_buffer) this->bytes_in_buffer = simulated_bytes_in_buffer; } this->bytes_in_buffer += num_frames * this->bytes_per_frame; n = write(this->audio_fd, frame_buffer, num_frames * this->bytes_per_frame); lprintf ("ao_oss_write done\n"); return (n >= 0 ? n : 0); } static void ao_oss_close(ao_driver_t *this_gen) { oss_driver_t *this = (oss_driver_t *) this_gen; close(this->audio_fd); this->audio_fd = -1; } static uint32_t ao_oss_get_capabilities (ao_driver_t *this_gen) { oss_driver_t *this = (oss_driver_t *) this_gen; return this->capabilities; } static void ao_oss_exit(ao_driver_t *this_gen) { oss_driver_t *this = (oss_driver_t *) this_gen; this->xine->config->unregister_callbacks (this->xine->config, "audio.output.speaker_arrangement", NULL, this, sizeof (*this)); if (this->mixer.fd != -1) close(this->mixer.fd); if (this->audio_fd != -1) close(this->audio_fd); free (this); } static int ao_oss_get_property (ao_driver_t *this_gen, int property) { oss_driver_t *this = (oss_driver_t *) this_gen; int audio_devs; switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: if(!this->mixer.mute) { if(this->mixer.fd != -1) { IOCTL_REQUEST_TYPE cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); if(audio_devs & SOUND_MASK_PCM) cmd = SOUND_MIXER_READ_PCM; else if(audio_devs & SOUND_MASK_VOLUME) cmd = SOUND_MIXER_READ_VOLUME; else return -1; ioctl(this->mixer.fd, cmd, &v); this->mixer.volume = (((v & 0xFF00) >> 8) + (v & 0x00FF)) / 2; } else return -1; } return this->mixer.volume; break; case AO_PROP_MUTE_VOL: return this->mixer.mute; break; } return 0; } static int ao_oss_set_property (ao_driver_t *this_gen, int property, int value) { oss_driver_t *this = (oss_driver_t *) this_gen; int audio_devs; switch(property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: if(!this->mixer.mute) { if(this->mixer.fd != -1) { IOCTL_REQUEST_TYPE cmd = 0; int v; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); if(audio_devs & SOUND_MASK_PCM) cmd = SOUND_MIXER_WRITE_PCM; else if(audio_devs & SOUND_MASK_VOLUME) cmd = SOUND_MIXER_WRITE_VOLUME; else return -1; v = (value << 8) | value; ioctl(this->mixer.fd, cmd, &v); this->mixer.volume = value; } else return -1; } else this->mixer.volume = value; return this->mixer.volume; break; case AO_PROP_MUTE_VOL: this->mixer.mute = (value) ? 1 : 0; if(this->mixer.mute) { if(this->mixer.fd != -1) { IOCTL_REQUEST_TYPE cmd = 0; int v = 0; ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); if(audio_devs & SOUND_MASK_PCM) cmd = SOUND_MIXER_WRITE_PCM; else if(audio_devs & SOUND_MASK_VOLUME) cmd = SOUND_MIXER_WRITE_VOLUME; else return -1; ioctl(this->mixer.fd, cmd, &v); } else return -1; } else (void) ao_oss_set_property(&this->ao_driver, this->mixer.prop, this->mixer.volume); return value; break; } return -1; } static int ao_oss_ctrl(ao_driver_t *this_gen, int cmd, ...) { oss_driver_t *this = (oss_driver_t *) this_gen; switch (cmd) { case AO_CTRL_PLAY_PAUSE: lprintf ("AO_CTRL_PLAY_PAUSE\n"); if (this->sync_method != OSS_SYNC_SOFTSYNC) ioctl(this->audio_fd, SNDCTL_DSP_RESET, NULL); /* close/reopen if RESET causes problems */ if (this->sync_method == OSS_SYNC_GETOPTR) { ao_oss_close(this_gen); ao_oss_open(this_gen, this->bits_per_sample, this->input_sample_rate, this->mode); } break; case AO_CTRL_PLAY_RESUME: lprintf ("AO_CTRL_PLAY_RESUME\n"); break; case AO_CTRL_FLUSH_BUFFERS: lprintf ("AO_CTRL_FLUSH_BUFFERS\n"); if (this->sync_method != OSS_SYNC_SOFTSYNC) ioctl(this->audio_fd, SNDCTL_DSP_RESET, NULL); if (this->sync_method == OSS_SYNC_GETOPTR) { ao_oss_close(this_gen); ao_oss_open(this_gen, this->bits_per_sample, this->input_sample_rate, this->mode); } lprintf ("AO_CTRL_FLUSH_BUFFERS done\n"); break; } return 0; } /* Probe /dev/dsp, /dev/dsp1, /dev/dsp2 ... * /dev/sound/dsp, /dev/sound/dsp1, /dev/sound/dsp2, ... * If one is found, the name of the winner is placed in this->audio_dev * and the function returns the audio rate. * If not, the function returns 0. */ static int probe_audio_devices(oss_driver_t *this) { static const char *const base_names[2] = {"/dev/dsp", "/dev/sound/dsp"}; int base_num, i; int audio_fd, rate; int best_rate; char devname[30]; strcpy(this->audio_dev, "auto"); best_rate = 0; for(base_num = 0; base_num < 2; ++base_num) { for(i = -1; i < 16; i++) { if (i == -1) { strlcpy(devname, base_names[base_num], sizeof(devname)); } else { snprintf(devname, sizeof(devname), "%s%d", base_names[base_num], i); } /* Test the device */ audio_fd = open(devname, O_WRONLY|O_NONBLOCK); if (audio_fd >= 0) { /* test bitrate capability */ rate = 48000; ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); if (rate > best_rate) { strcpy(this->audio_dev, devname); /* Better, keep this one */ best_rate = rate; } close (audio_fd); } } } return best_rate; /* Will be zero if we did not find one */ } static void oss_speaker_arrangement_cb (void *user_data, xine_cfg_entry_t *entry); static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { oss_class_t *class = (oss_class_t *) class_gen; config_values_t *config = class->xine->config; oss_driver_t *this; int caps; int audio_fd; int num_channels, status, arg; static const char * const sync_methods[] = {"auto", "getodelay", "getoptr", "softsync", "probebuffer", NULL}; static const char * const devname_opts[] = {"auto", "/dev/dsp", "/dev/sound/dsp", NULL}; int devname_val, devname_num; AUDIO_DEVICE_SPEAKER_ARRANGEMENT_TYPES; int speakers; (void)data; this = calloc(1, sizeof (oss_driver_t)); if (!this) return NULL; /* * find best device driver/channel */ xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: Opening audio device...\n"); /* devname_val is offset used to select auto, /dev/dsp, or /dev/sound/dsp */ devname_val = config->register_enum (config, "audio.device.oss_device_name", 0, (char **)devname_opts, _("OSS audio device name"), _("Specifies the base part of the audio device name, " "to which the OSS device number is appended to get the " "full device name.\nSelect \"auto\" if you want xine to " "auto detect the correct setting."), 10, NULL, NULL); /* devname_num is the N in '/dev[/sound]/dsp[N]'. Set to -1 for nothing */ devname_num = config->register_num(config, "audio.device.oss_device_number", -1, _("OSS audio device number, -1 for none"), _("The full audio device name is created by concatenating the " "OSS device name and the audio device number.\n" "If you do not need a number because you are happy with " "your system's default audio device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is " "ignored, when the OSS audio device name is set to \"auto\"."), 10, NULL, NULL); if (devname_val == 0 || devname_val > 15) { xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: audio.device.oss_device_name = auto, probing devs\n")); if ( ! probe_audio_devices(this)) { /* Returns zero on fail */ xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: Auto probe for audio device failed\n")); free (this); return NULL; } } else { /* Create the device name /dev[/sound]/dsp[0-15] */ if (devname_num < 0) { strlcpy(this->audio_dev, devname_opts[devname_val], sizeof(this->audio_dev)); } else { snprintf(this->audio_dev, sizeof(this->audio_dev), "%s%d", devname_opts[devname_val], devname_num); } } /* * open that device */ xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: using device >%s<\n"), this->audio_dev); audio_fd = xine_open_cloexec(this->audio_dev, O_WRONLY|O_NONBLOCK); if (audio_fd < 0) { xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: opening audio device %s failed:\n%s\n"), this->audio_dev, strerror(errno)); free (this); return NULL; } /* * set up driver to reasonable values for capabilities tests */ arg = AFMT_S16_NE; status = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg); arg = 44100; status = ioctl(audio_fd, SNDCTL_DSP_SPEED, &arg); /* * find out which sync method to use */ this->sync_method = config->register_enum (config, "audio.oss_sync_method", OSS_SYNC_AUTO_DETECT, (char **)sync_methods, _("a/v sync method to use by OSS"), _("xine can use different methods to keep audio and video " "synchronized. Which setting works best depends on the " "OSS driver and sound hardware you are using. Try the " "various methods, if you experience sync problems.\n\n" "The meaning of the values is as follows:\n\n" "auto\n" "xine attempts to automatically detect the optimal setting\n\n" "getodelay\n" "uses the SNDCTL_DSP_GETODELAY ioctl to achieve true a/v " "sync even if the driver claims not to support realtime " "playback\n\n" "getoptr\n" "uses the SNDCTL_DSP_GETOPTR ioctl to achieve true a/v " "sync even if the driver supports the preferred " "SNDCTL_DSP_GETODELAY ioctl\n\n" "softsync\n" "uses software synchronization with the system clock; audio " "and video can get severely out of sync if the system clock " "speed does not precisely match your sound card's playback " "speed\n\n" "probebuffer\n" "probes the sound card buffer size on initialization to " "calculate the latency for a/v sync; try this if your " "system does not support any of the realtime ioctls and " "you experience sync errors after long playback"), 20, NULL, NULL); if (this->sync_method == OSS_SYNC_AUTO_DETECT) { count_info info; /* * check if SNDCTL_DSP_GETODELAY works. if so, using it is preferred. */ #ifdef SNDCTL_DSP_GETODELAY if (ioctl(audio_fd, SNDCTL_DSP_GETODELAY, &info) != -1) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: using SNDCTL_DSP_GETODELAY\n"); this->sync_method = OSS_SYNC_GETODELAY; } else #endif if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &info) != -1) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: using SNDCTL_DSP_GETOPTR\n"); this->sync_method = OSS_SYNC_GETOPTR; } else { this->sync_method = OSS_SYNC_SOFTSYNC; } } if (this->sync_method == OSS_SYNC_SOFTSYNC) { xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...will use system real-time clock for soft-sync instead\n" "audio_oss_out: ...there may be audio/video synchronization issues\n")); xine_monotonic_clock(&this->start_time, NULL); this->latency = config->register_range (config, "audio.oss_latency", 0, -3000, 3000, _("OSS audio output latency (adjust a/v sync)"), _("If you experience audio being not in sync " "with the video, you can enter a fixed offset " "here to compensate.\nThe unit of the value " "is one PTS tick, which is the 90000th part " "of a second."), 20, NULL, NULL); } if (this->sync_method == OSS_SYNC_PROBEBUFFER) { char *buf; int c; this->buffer_size = 0; if( (buf=calloc(1, 1024)) != NULL ) { do { c = write(audio_fd,buf,1024); if( c != -1 ) this->buffer_size += c; } while( c == 1024 ); free(buf); } close(audio_fd); xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: Audio driver realtime sync disabled...\n" "audio_oss_out: ...probing output buffer size: %d bytes\naudio_oss_out: ...there may be audio/video synchronization issues\n"), this->buffer_size); audio_fd = xine_open_cloexec(this->audio_dev, O_WRONLY|O_NONBLOCK); if(audio_fd < 0) { xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: opening audio device %s failed:\n%s\n"), this->audio_dev, strerror(errno)); free (this); return NULL; } } /* we always reset or reopen at pause for now. */ this->capabilities = AO_CAP_NO_UNPAUSE; arg = AFMT_U8; if( ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg) != -1 && arg == AFMT_U8) this->capabilities |= AO_CAP_8BITS; /* switch back to 16bits, because some soundcards otherwise do not report all their capabilities */ arg = AFMT_S16_NE; if (ioctl(audio_fd, SNDCTL_DSP_SETFMT, &arg) == -1 || arg != AFMT_S16_NE) { xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_oss_out: switching the soundcard to 16 bits mode failed\n"); free(this); close(audio_fd); return NULL; } /* for usability reasons, keep this in sync with audio_alsa_out.c */ speakers = config->register_enum(config, "audio.output.speaker_arrangement", STEREO, (char **)speaker_arrangement, AUDIO_DEVICE_SPEAKER_ARRANGEMENT_HELP, 0, oss_speaker_arrangement_cb, this); { char logbuf[2048], *q, *logend = logbuf + sizeof (logbuf); q = logbuf; q += strlcpy (q, _("audio_oss_out: supported modes are"), logend - q); if (q >= logend) q = logend; num_channels = 1; status = ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &num_channels); if ((status != -1) && (num_channels == 1)) { this->capabilities |= AO_CAP_MODE_MONO; q += strlcpy (q, _(" mono"), logend - q); if (q >= logend) q = logend; } num_channels = 2; status = ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &num_channels); if ((status != -1) && (num_channels == 2)) { this->capabilities |= AO_CAP_MODE_STEREO; q += strlcpy (q, _(" stereo"), logend - q); if (q >= logend) q = logend; } num_channels = 4; status = ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &num_channels); if ((status != -1) && (num_channels == 4)) { if (speakers == SURROUND4) { this->capabilities |= AO_CAP_MODE_4CHANNEL; q += strlcpy (q, _(" 4-channel"), logend - q); } else q += strlcpy (q, _(" (4-channel not enabled in xine config)"), logend - q); if (q >= logend) q = logend; } num_channels = 5; status = ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &num_channels); if ((status != -1) && (num_channels == 5)) { if (speakers == SURROUND5) { this->capabilities |= AO_CAP_MODE_5CHANNEL; q += strlcpy (q, _(" 5-channel"), logend - q); } else q += strlcpy (q, _(" (5-channel not enabled in xine config)"), logend - q); if (q >= logend) q = logend; } num_channels = 6; status = ioctl (audio_fd, SNDCTL_DSP_CHANNELS, &num_channels); if ((status != -1) && (num_channels == 6)) { if (speakers == SURROUND51 ) { this->capabilities |= AO_CAP_MODE_5_1CHANNEL; q += strlcpy (q, _(" 5.1-channel"), logend - q); } else q += strlcpy (q, _(" (5.1-channel not enabled in xine config)"), logend - q); if (q >= logend) q = logend; } ioctl (audio_fd, SNDCTL_DSP_GETFMTS, &caps); /* one would normally check for (caps & AFMT_AC3) before asking about passthrough, * but some buggy OSS drivers do not report this properly, so we ask anyway. */ if (speakers == A52_PASSTHRU) { this->capabilities |= AO_CAP_MODE_A52; this->capabilities |= AO_CAP_MODE_AC5; q += strlcpy (q, _(" a/52 pass-through"), logend - q); } else q += strlcpy (q, _(" (a/52 pass-through not enabled in xine config)"), logend - q); /* if (q >= logend) q = logend; */ xprintf (class->xine, XINE_VERBOSITY_DEBUG, "%s\n", logbuf); } /* * mixer initialisation. */ { char mixer_name[32]; char mixer_dev[48]; int mixer_num; int audio_devs; char *parse; this->mixer.fd = -1; mixer_dev[0] = 0; mixer_num = config->register_num(config, "audio.device.oss_mixer_number", -1, _("OSS audio mixer number, -1 for none"), _("The full mixer device name is created by taking the " "OSS device name, replacing \"dsp\" with \"mixer\" and " "adding the mixer number.\n" "If you do not need a number because you are happy with " "your system's default mixer device, set this to -1.\n" "The range of this value is -1 or 0-15. This setting is " "ignored, when the OSS audio device name is set to \"auto\"."), 10, NULL, NULL); /* get the mixer device name from the audio device name by replacing "dsp" with "mixer" */ strcpy(mixer_name, this->audio_dev); if ((parse = strstr(mixer_name, "dsp"))) { parse[0] = '\0'; parse += 3; if (devname_val == 0 || devname_val > 15) snprintf(mixer_dev, sizeof(mixer_dev), "%smixer%s", mixer_name, parse); else if (mixer_num == -1) snprintf(mixer_dev, sizeof(mixer_dev), "%smixer", mixer_name); else snprintf(mixer_dev, sizeof(mixer_dev), "%smixer%d", mixer_name, mixer_num); this->mixer.fd = xine_open_cloexec(mixer_dev, O_RDONLY); } if(this->mixer.fd != -1) { ioctl(this->mixer.fd, SOUND_MIXER_READ_DEVMASK, &audio_devs); if(audio_devs & SOUND_MASK_PCM) { this->capabilities |= AO_CAP_PCM_VOL; this->mixer.prop = AO_PROP_PCM_VOL; } else if(audio_devs & SOUND_MASK_VOLUME) { this->capabilities |= AO_CAP_MIXER_VOL; this->mixer.prop = AO_PROP_MIXER_VOL; } /* * This is obsolete in Linux kernel OSS * implementation, so this will certainly doesn't work. * So we just simulate the mute stuff */ /* if(audio_devs & SOUND_MASK_MUTE) this->capabilities |= AO_CAP_MUTE_VOL; */ this->capabilities |= AO_CAP_MUTE_VOL; } else xprintf (class->xine, XINE_VERBOSITY_LOG, _("audio_oss_out: open() mixer %s failed: %s\n"), mixer_dev, strerror(errno)); this->mixer.mute = 0; this->mixer.volume = ao_oss_get_property (&this->ao_driver, this->mixer.prop); } close (audio_fd); this->output_sample_rate = 0; this->output_sample_k_rate = 0; this->audio_fd = -1; this->xine = class->xine; this->ao_driver.get_capabilities = ao_oss_get_capabilities; this->ao_driver.get_property = ao_oss_get_property; this->ao_driver.set_property = ao_oss_set_property; this->ao_driver.open = ao_oss_open; this->ao_driver.num_channels = ao_oss_num_channels; this->ao_driver.bytes_per_frame = ao_oss_bytes_per_frame; this->ao_driver.delay = ao_oss_delay; this->ao_driver.write = ao_oss_write; this->ao_driver.close = ao_oss_close; this->ao_driver.exit = ao_oss_exit; this->ao_driver.get_gap_tolerance = ao_oss_get_gap_tolerance; this->ao_driver.control = ao_oss_ctrl; return &this->ao_driver; } static void oss_speaker_arrangement_cb (void *user_data, xine_cfg_entry_t *entry) { oss_driver_t *this = (oss_driver_t *) user_data; int32_t value = entry->num_value; if (value == A52_PASSTHRU) { this->capabilities |= AO_CAP_MODE_A52; this->capabilities |= AO_CAP_MODE_AC5; } else { this->capabilities &= ~AO_CAP_MODE_A52; this->capabilities &= ~AO_CAP_MODE_AC5; } if (value == SURROUND4) { this->capabilities |= AO_CAP_MODE_4CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_4CHANNEL; } if (value == SURROUND41) { this->capabilities |= AO_CAP_MODE_4_1CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_4_1CHANNEL; } if (value == SURROUND5) { this->capabilities |= AO_CAP_MODE_5CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_5CHANNEL; } if (value >= SURROUND51) { this->capabilities |= AO_CAP_MODE_5_1CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_5_1CHANNEL; } } /* * class functions */ static void *init_class (xine_t *xine, const void *data) { oss_class_t *this; (void)data; this = calloc(1, sizeof (oss_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "oss"; this->driver_class.description = N_("xine audio output plugin using oss-compliant audio devices/drivers"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; return this; } static const ao_info_t ao_info_oss = { .priority = 9, /* less than alsa so xine will use alsa's native interface by default */ }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_OSS_IFACE_VERSION, "oss", XINE_VERSION_CODE, &ao_info_oss, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_directx_out.c������������������������������������������������������0000644�0001750�0001750�00000060005�14647725152�017322� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2001-2022 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * audio_directx_out.c, direct sound audio output plugin for xine * by Matthew Grooms <elon@altavista.com> */ /* * TODO: * - stop looping on stop (requires AO_CTRL_PLAY_STOP?) * - posibility of bad state when buffer overrun */ #ifdef HAVE_CONFIG_H #include "config.h" #endif typedef unsigned char boolean; #include <windows.h> #include <dsound.h> #define LOG_MODULE "audio_directx_out" #define LOG_VERBOSE /* #define LOG */ #include <xine/audio_out.h> #include <xine/xine_internal.h> #define MAX_CHANNELS 6 #define MAX_BITS 16 #define MAX_SAMPLE_RATE 44100 #define SOUND_BUFFER_DIV 32 #define SOUND_BUFFER_MAX MAX_CHANNELS * (MAX_BITS / 8) * (((MAX_SAMPLE_RATE / SOUND_BUFFER_DIV) + 1) & ~1) #define DSBUFF_INIT 0 #define DSBUFF_LEFT 1 #define DSBUFF_RIGHT 2 #define AO_DIRECTX_IFACE_VERSION 9 /***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during * the linking stage. *****************************************************************************/ #if 1 static const GUID xine_IID_IDirectSoundNotify = { 0xB0210783,0x89CD,0x11D0,{0xAF,0x08,0x00,0xA0,0xC9,0x25,0xCD,0x16} }; #ifdef IID_IDirectSoundNotify # undef IID_IDirectSoundNotify #endif #define IID_IDirectSoundNotify xine_IID_IDirectSoundNotify #endif /* ----------------------------------------- * * ao_directx driver struct * * ----------------------------------------- */ typedef struct { ao_driver_t ao_driver; int capabilities; xine_t *xine; /* directx objects */ LPDIRECTSOUND dsobj; LPDIRECTSOUNDBUFFER dsbuffer; DSBCAPS dsbcaps; LPDIRECTSOUNDNOTIFY notify; DSBPOSITIONNOTIFY notify_events[ 2 ]; /* buffer vars */ long buffer_size; int write_status; unsigned long write_pos; uint8_t prebuff[ SOUND_BUFFER_MAX ]; uint32_t prebuff_size; /* current buffer properties */ int bits; int rate; int chnn; int frsz; /* current mixer settings */ int mute; int volume; } ao_directx_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } audiox_class_t; /* ------------------------------------------- * * BEGIN : Direct Sound and win32 handlers * for xine audio output plugins. * * ------------------------------------------- */ /* Display formatted error message in * popup message box. */ static void Error( HWND hwnd, LPCSTR szfmt, ... ) { char tempbuff[ 256 ]; *tempbuff = 0; wvsprintf( &tempbuff[ strlen( tempbuff ) ], szfmt, ( char * )( &szfmt + 1 ) ); MessageBox( hwnd, tempbuff, "Error", MB_ICONERROR | MB_OK | MB_APPLMODAL | MB_SYSTEMMODAL ); } /* Create our direct sound object and * set the cooperative level. */ static boolean CreateDirectSound( ao_directx_t * ao_directx ) { DSCAPS dscaps; HWND hxinewnd; lprintf("CreateDirectSound(%p) Enter\n", (void *)ao_directx); /* create direct sound object */ if( DirectSoundCreate( 0, &ao_directx->dsobj, 0 ) != DS_OK ) { Error( 0, "DirectSoundCreate : Unable to create direct sound object" ); lprintf("CreateDirectSound() Exit! Returning False\n"); return FALSE; } /* try to get our current xine window */ hxinewnd = FindWindow( "xinectrlwindow", "xine" ); if( !hxinewnd ) hxinewnd = GetDesktopWindow(); /* set direct sound cooperative level */ if( IDirectSound_SetCooperativeLevel( ao_directx->dsobj, hxinewnd, DSSCL_EXCLUSIVE ) != DS_OK ) { Error( 0, "IDirectSound_SetCooperativeLevel : could not set direct sound cooperative level" ); lprintf("CreateDirectSound() Exit! Returning False\n"); return FALSE; } /* get the direct sound device caps */ memset( &dscaps, 0, sizeof( dscaps ) ); dscaps.dwSize = sizeof( dscaps ); if( IDirectSound_GetCaps( ao_directx->dsobj, &dscaps ) != DS_OK ) { Error( 0, "IDirectSound_GetCaps : Unable to get direct sound device capabilities" ); lprintf("CreateDirectSound() Exit! Returning False\n"); return FALSE; } lprintf("CreateDirectSound() Exit! Returning True\n"); return TRUE; } /* Destroy all direct sound allocated * resources. */ static void DestroyDirectSound( ao_directx_t * ao_directx ) { lprintf("DestroyDirectSound(%p) Enter\n", (void *)ao_directx); if( ao_directx->dsobj ) { lprintf("IDirectSound_Release()\n"); IDirectSound_Release( ao_directx->dsobj ); ao_directx->dsobj = 0; } lprintf("DestroyDirectSound() Exit\n"); } /* Used to fill our looping sound buffer * with data. */ static uint32_t FillSoundBuffer( ao_directx_t * ao_directx, int code, unsigned char * samples ) { uint8_t * buff_pointer; /* pointer inside circular buffer */ DWORD buff_length; /* bytes locked by pointer */ uint32_t half_size; /* half our sound buffer size */ uint32_t result; /* error result */ #ifdef LOG if ((void*)samples != (void*)0) printf("audio_directx_out: FillSoundBuffer(%08x, %d, Null) Enter\n", (unsigned long)ao_directx, code); else printf("audio_directx_out: FillSoundBuffer(%08x, %d, Null) Enter\n", (unsigned long)ao_directx, code); #endif half_size = ao_directx->buffer_size / 2; if( code == DSBUFF_INIT ) { lprintf("FillSoundBuffer: DSBUFF_INIT\n"); /* set our new status code */ ao_directx->write_status = DSBUFF_RIGHT; /* lock our sound buffer for write access */ result = IDirectSoundBuffer_Lock( ao_directx->dsbuffer, 0, 0, (LPVOID *)&buff_pointer, &buff_length, NULL, 0, DSBLOCK_ENTIREBUFFER ); if( result != DS_OK ) { Error( 0, "IDirectSoundBuffer_Lock : could not lock sound buffer" ); return 0; } /* clear our entire sound buffer */ memset( buff_pointer, 0, buff_length ); /* unlock our sound buffer */ if( IDirectSoundBuffer_Unlock( ao_directx->dsbuffer, buff_pointer, buff_length, 0, 0 ) != DS_OK ) { Error( 0, "IDirectSoundBuffer_Unlock : could not unlock sound buffer" ); return 0; } /* start the buffer playing */ if( IDirectSoundBuffer_Play( ao_directx->dsbuffer, 0, 0, DSBPLAY_LOOPING ) != DS_OK ) { Error( 0, "IDirectSoundBuffer_Play : could not play sound buffer" ); return 0 ; } else IDirectSoundBuffer_SetVolume( ao_directx->dsbuffer, ao_directx->volume ); } else if( code == DSBUFF_LEFT ) { lprintf("FillSoundBuffer: DSBUFF_LEFT\n"); /* set our new status code */ ao_directx->write_status = DSBUFF_RIGHT; /* lock our sound buffer for write access */ result = IDirectSoundBuffer_Lock( ao_directx->dsbuffer, 0, half_size, (LPVOID *)&buff_pointer, &buff_length, 0, 0, 0 ); if( result != DS_OK ) { Error( 0, "IDirectSoundBuffer_Lock : could not lock sound buffer" ); return 0; } /* write data to our sound buffer */ memcpy( buff_pointer, samples, buff_length ); /* unlock our sound buffer */ if( IDirectSoundBuffer_Unlock( ao_directx->dsbuffer, buff_pointer, buff_length, 0, 0 ) != DS_OK ) { Error( 0, "IDirectSoundBuffer_Unlock : could not unlock sound buffer" ); return 0; } } else if( code == DSBUFF_RIGHT ) { lprintf("FillSoundBuffer: DSBUFF_RIGHT\n"); /* set our new status code */ ao_directx->write_status = DSBUFF_LEFT; /* lock our sound buffer for write access */ result = IDirectSoundBuffer_Lock( ao_directx->dsbuffer, half_size, half_size, (LPVOID *)&buff_pointer, &buff_length, 0, 0, 0 ); if( result != DS_OK ) { Error( 0, "IDirectSoundBuffer_Lock : could not lock sound buffer" ); return 0; } /* write data to our sound buffer */ memcpy( buff_pointer, samples, buff_length ); /* unlock our sound buffer */ if( IDirectSoundBuffer_Unlock( ao_directx->dsbuffer, buff_pointer, buff_length, 0, 0 ) != DS_OK ) { Error( 0, "IDirectSoundBuffer_Unlock : could not unlock sound buffer" ); return 0; } } lprintf("FillSoundBuffer() Exit\n"); return buff_length; } /* Destroy all direct sound buffer allocated * resources. */ static void DestroySoundBuffer( ao_directx_t * ao_directx ) { lprintf("DestroySoundBuffer(%p) Enter\n", (void *)ao_directx); /* stop our buffer and zero it out */ if( ao_directx->dsbuffer ) { IDirectSoundBuffer_SetVolume( ao_directx->dsbuffer, DSBVOLUME_MIN ); IDirectSoundBuffer_Stop( ao_directx->dsbuffer ); FillSoundBuffer( ao_directx, DSBUFF_INIT, 0 ); } /* release our notification events */ if( ao_directx->notify_events[ 0 ].hEventNotify ) { CloseHandle( ao_directx->notify_events[ 0 ].hEventNotify ); ao_directx->notify_events[ 0 ].hEventNotify = 0; } if( ao_directx->notify_events[ 1 ].hEventNotify ) { CloseHandle( ao_directx->notify_events[ 1 ].hEventNotify ); ao_directx->notify_events[ 1 ].hEventNotify = 0; } /* release our buffer notification interface */ if( ao_directx->notify ) { IDirectSoundNotify_Release( ao_directx->notify ); ao_directx->notify = 0; } /* release our direct sound buffer */ if( ao_directx->dsbuffer ) { IDirectSoundBuffer_Release( ao_directx->dsbuffer ); ao_directx->dsbuffer = 0; } lprintf("DestroySoundBuffer() Exit\n"); } /* Used to create directx sound buffer, * notification events, and initialize * buffer to null sample data. */ static boolean CreateSoundBuffer( ao_directx_t * ao_directx ) { DSBUFFERDESC dsbdesc; PCMWAVEFORMAT pcmwf; lprintf("CreateSoundBuffer(%p) Enter\n", (void *)ao_directx); /* calculate buffer and frame size */ ao_directx->frsz = ( ao_directx->bits / 8 ) * ao_directx->chnn; /* buffer size, must be even and aligned to frame size */ ao_directx->buffer_size = (ao_directx->frsz * ((ao_directx->rate / SOUND_BUFFER_DIV + 1) & ~1)); /* release any existing sound buffer * related resources */ DestroySoundBuffer( ao_directx ); /* create a secondary sound buffer */ memset( &pcmwf, 0, sizeof( PCMWAVEFORMAT ) ); pcmwf.wBitsPerSample = ( unsigned short ) ao_directx->bits; pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM; pcmwf.wf.nChannels = ao_directx->chnn; pcmwf.wf.nSamplesPerSec = ao_directx->rate; pcmwf.wf.nBlockAlign = ao_directx->frsz; pcmwf.wf.nAvgBytesPerSec = ao_directx->rate * ao_directx->frsz; memset( &dsbdesc, 0, sizeof( DSBUFFERDESC ) ); dsbdesc.dwSize = sizeof( DSBUFFERDESC ); dsbdesc.dwFlags = (DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLPOSITIONNOTIFY); dsbdesc.dwBufferBytes = ao_directx->buffer_size; dsbdesc.lpwfxFormat = ( LPWAVEFORMATEX ) &pcmwf; if( IDirectSound_CreateSoundBuffer( ao_directx->dsobj, &dsbdesc, &ao_directx->dsbuffer, 0 ) != DS_OK ) { Error( 0, "IDirectSound_CreateSoundBuffer : Unable to create secondary sound buffer" ); return FALSE; } /* get the buffer capabilities */ memset( &ao_directx->dsbcaps, 0, sizeof( DSBCAPS ) ); ao_directx->dsbcaps.dwSize = sizeof( DSBCAPS ); if( IDirectSound_GetCaps( ao_directx->dsbuffer, &ao_directx->dsbcaps ) != DS_OK ) { Error( 0, "IDirectSound_GetCaps : Unable to get secondary sound buffer capabilities" ); return FALSE; } /* create left side notification ( non-signaled ) */ ao_directx->notify_events[ 0 ].hEventNotify = CreateEvent( NULL, FALSE, FALSE, NULL ); /* create right side notification ( signaled ) */ ao_directx->notify_events[ 1 ].hEventNotify = CreateEvent( NULL, FALSE, FALSE, NULL ); if( !ao_directx->notify_events[ 0 ].hEventNotify || !ao_directx->notify_events[ 1 ].hEventNotify ) { Error( 0, "CreateEvent : Unable to create sound notification events" ); return FALSE; } /* get the direct sound notification interface */ if( IDirectSoundBuffer_QueryInterface( ao_directx->dsbuffer, &IID_IDirectSoundNotify, (LPVOID *)&ao_directx->notify ) != DS_OK ) { Error( 0, "IDirectSoundBuffer_QueryInterface : Unable to get notification interface" ); return FALSE; } /* set notification events */ ao_directx->notify_events[ 0 ].dwOffset = 0; ao_directx->notify_events[ 1 ].dwOffset = ao_directx->buffer_size / 2; if( IDirectSoundNotify_SetNotificationPositions( ao_directx->notify, 2, ao_directx->notify_events ) != DS_OK ) { Error( 0, "IDirectSoundNotify_SetNotificationPositions : Unable to set notification positions" ); return FALSE; } /* DEBUG : set sound buffer volume */ if( IDirectSoundBuffer_SetVolume( ao_directx->dsbuffer, DSBVOLUME_MAX ) != DS_OK ) { Error( 0, "IDirectSoundBuffer_SetVolume : Unable to set sound buffer volume" ); return FALSE; } /* initialize our sound buffer */ IDirectSoundBuffer_SetVolume( ao_directx->dsbuffer, DSBVOLUME_MIN ); FillSoundBuffer( ao_directx, DSBUFF_INIT, 0 ); return TRUE; lprintf("CreateSoundBuffer() Exit\n"); } /* ----------------------------------------- * * BEGIN : Xine driver audio output plugin * handlers. * * ----------------------------------------- */ static int ao_directx_control(ao_driver_t *this_gen, int cmd, ...) { switch (cmd) { case AO_CTRL_PLAY_PAUSE: break; case AO_CTRL_PLAY_RESUME: break; case AO_CTRL_FLUSH_BUFFERS: break; } return 0; } static int ao_directx_open( ao_driver_t * ao_driver, uint32_t bits, uint32_t rate, int mode ) { ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; lprintf("ao_directx_open(%p, %u, %u, %u) Enter\n", (void *)ao_directx, bits, rate, mode); /* store input rate and bits */ ao_directx->bits = bits; ao_directx->rate = rate; /* store channel count */ switch( mode ) { case AO_CAP_MODE_MONO: ao_directx->chnn = 1; xprintf(ao_directx->xine, XINE_VERBOSITY_DEBUG, "ao_directx : opened in AO_CAP_MODE_MONO mode\n" ); break; case AO_CAP_MODE_STEREO: ao_directx->chnn = 2; xprintf(ao_directx->xine, XINE_VERBOSITY_DEBUG, "ao_directx : opened in AO_CAP_MODE_STEREO mode\n" ); break; case AO_CAP_MODE_4CHANNEL: ao_directx->chnn = 4; xprintf(ao_directx->xine, XINE_VERBOSITY_DEBUG, "ao_directx : opened in AO_CAP_MODE_4CHANNEL mode\n" ); break; case AO_CAP_MODE_5CHANNEL: ao_directx->chnn = 5; xprintf(ao_directx->xine, XINE_VERBOSITY_DEBUG, "ao_directx : opened in AO_CAP_MODE_5CHANNEL mode\n" ); break; case AO_CAP_MODE_5_1CHANNEL: ao_directx->chnn = 6; xprintf(ao_directx->xine, XINE_VERBOSITY_DEBUG, "ao_directx : opened in AO_CAP_MODE_5_1CHANNEL mode\n" ); break; case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: return 0; } if (!CreateSoundBuffer( ao_directx )) return 0; lprintf("ao_directx_open() Exit! Returning ao_directx->rate=%d\n", ao_directx->rate); return ao_directx->rate; } static int ao_directx_num_channels( ao_driver_t * ao_driver ) { ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; return ao_directx->chnn; } static int ao_directx_bytes_per_frame( ao_driver_t * ao_driver ) { ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; return ao_directx->frsz; } static int ao_directx_get_gap_tolerance( ao_driver_t * ao_driver ) { return 5000; } static int ao_directx_delay( ao_driver_t * ao_driver ) { DWORD current_read; DWORD bytes_left; DWORD frames_left; ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; lprintf("ao_directx_delay(%p) Enter\n", (void *)ao_directx); IDirectSoundBuffer_GetCurrentPosition( ao_directx->dsbuffer, ¤t_read, 0 ); if( ao_directx->write_pos > current_read ) bytes_left = ( ao_directx->write_pos - current_read ); else bytes_left = ( ao_directx->write_pos + ao_directx->buffer_size - current_read ); frames_left = ( ao_directx->prebuff_size + bytes_left ) / ao_directx->frsz; lprintf("ao_directx_delay() Exit! Returning frames_left=%lu\n", (unsigned long)frames_left); return frames_left; } static int ao_directx_write( ao_driver_t * ao_driver, int16_t * frame_buffer, uint32_t num_frames ) { ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; uint32_t frame_bytes; /* how many bytes to lock */ uint32_t wrote; /* number of bytes written */ uint32_t half_size; /* half our sound buffer size */ lprintf("ao_directx_write(%p, %p, %u) Enter\n", (void *)ao_directx, (void *)frame_buffer, num_frames); /* zero write counter */ wrote = 0; /* calculate how many bytes in frame_buffer */ frame_bytes = num_frames * ao_directx->frsz; /* calculate half our buffer size */ half_size = ao_directx->buffer_size / 2; /* fill audio prebuff */ memcpy( ao_directx->prebuff + ao_directx->prebuff_size, frame_buffer, frame_bytes ); ao_directx->prebuff_size = ao_directx->prebuff_size + frame_bytes; /* check to see if we have enough in prebuff to * fill half of our sound buffer */ while( ao_directx->prebuff_size >= half_size ) { /* write to our sound buffer */ if( ao_directx->write_status == DSBUFF_LEFT ) { /* wait for our read pointer to reach the right half * of our sound buffer, we only want to write to the * left side */ WaitForSingleObject( ao_directx->notify_events[ 1 ].hEventNotify, INFINITE ); /* fill left half of our buffer */ wrote = FillSoundBuffer( ao_directx, DSBUFF_LEFT, ao_directx->prebuff ); } else if( ao_directx->write_status == DSBUFF_RIGHT ) { /* wait for our read pointer to reach the left half, * of our sound buffer, we only want to write to the * right side */ WaitForSingleObject( ao_directx->notify_events[ 0 ].hEventNotify, INFINITE ); /* fill right half of our buffer */ wrote = FillSoundBuffer( ao_directx, DSBUFF_RIGHT, ao_directx->prebuff ); } /* calc bytes written and store position for next write */ ao_directx->write_pos = ( ao_directx->write_pos + wrote ) % ao_directx->buffer_size; /* copy remaining contents of prebuff and recalc size */ memcpy( ao_directx->prebuff, ao_directx->prebuff + wrote, ao_directx->prebuff_size - wrote ); ao_directx->prebuff_size = ao_directx->prebuff_size - wrote; } lprintf("ao_directx_write() Exit! Returning num_frames=%u\n", num_frames); return num_frames; } static void ao_directx_close( ao_driver_t * ao_driver ) { ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; lprintf("ao_directx_close(%p) Enter\n", (void *)ao_directx); /* release any existing sound buffer * related resources */ DestroySoundBuffer( ao_directx ); lprintf("ao_directx_close() Exit!\n"); } static uint32_t ao_directx_get_capabilities( ao_driver_t * ao_driver ) { return AO_CAP_MODE_STEREO | AO_CAP_MIXER_VOL | AO_CAP_PCM_VOL | AO_CAP_MUTE_VOL; } static void ao_directx_exit( ao_driver_t * ao_driver ) { ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; lprintf("ao_directx_exit(%p) Enter\n", (void *)ao_directx); /* release any existing sound buffer * related resources */ DestroySoundBuffer( ao_directx ); /* release any existing direct sound * related resources */ DestroyDirectSound( ao_directx ); /* free our driver */ free( ao_directx ); lprintf("ao_directx_exit() Exit!\n"); } static int ao_directx_get_property( ao_driver_t * ao_driver, int property ) { return 0; } static int ao_directx_set_property( ao_driver_t * ao_driver, int property, int value ) { ao_directx_t *ao_directx = ( ao_directx_t * ) ao_driver; lprintf("ao_directx_set_property(%p, %d, %d) Enter\n", (void *)ao_directx, property, value); switch( property ) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: lprintf("ao_directx_set_property: AO_PROP_PCM_VOL|AO_PROP_MIXER_VOL\n"); ao_directx->volume = value * ( DSBVOLUME_MIN / 100 / 3); if( !ao_directx->mute && ao_directx->dsbuffer ) IDirectSoundBuffer_SetVolume( ao_directx->dsbuffer, ao_directx->volume ); xprintf(ao_directx->xine, XINE_VERBOSITY_DEBUG, "ao_directx : volume set to %d - directX volume = %d\n", value, ao_directx->volume); return value; break; case AO_PROP_MUTE_VOL: lprintf("ao_directx_set_property: AO_PROP_MUTE_VOL\n"); ao_directx->mute = value; if( !ao_directx->mute && ao_directx->dsbuffer ) IDirectSoundBuffer_SetVolume( ao_directx->dsbuffer, ao_directx->volume ); if( ao_directx->mute && ao_directx->dsbuffer ) IDirectSoundBuffer_SetVolume( ao_directx->dsbuffer, DSBVOLUME_MIN ); xprintf(ao_directx->xine, XINE_VERBOSITY_DEBUG, "ao_directx : mute toggled" ); return value; break; } lprintf("ao_directx_set_property() Exit! Returning ~value=%d\n", ~value); return ~value; } static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { audiox_class_t *class = (audiox_class_t *) class_gen; ao_directx_t *ao_directx; ao_directx = calloc(1, sizeof(ao_directx_t)); if (!ao_directx) return NULL; lprintf("open_plugin(%p, %p) Enter\n", (void *)class_gen, (void *)data); lprintf("open_plugin: ao_directx=%p\n", (void *)ao_directx); ao_directx->xine = class->xine; ao_directx->ao_driver.get_capabilities = ao_directx_get_capabilities; ao_directx->ao_driver.get_property = ao_directx_get_property; ao_directx->ao_driver.set_property = ao_directx_set_property; ao_directx->ao_driver.open = ao_directx_open; ao_directx->ao_driver.num_channels = ao_directx_num_channels; ao_directx->ao_driver.bytes_per_frame = ao_directx_bytes_per_frame; ao_directx->ao_driver.delay = ao_directx_delay; ao_directx->ao_driver.write = ao_directx_write; ao_directx->ao_driver.close = ao_directx_close; ao_directx->ao_driver.exit = ao_directx_exit; ao_directx->ao_driver.get_gap_tolerance = ao_directx_get_gap_tolerance; ao_directx->ao_driver.control = ao_directx_control; CreateDirectSound( ao_directx ); lprintf("open_plugin() Exit! Returning ao_directx=%p\n", (void *)ao_directx); return &ao_directx->ao_driver; } static void *init_class (xine_t *xine, const void *data) { audiox_class_t *audiox; lprintf("init_class() Enter\n"); /* * from this point on, nothing should go wrong anymore */ audiox = calloc(1, sizeof (audiox_class_t)); if (!audiox) return NULL; audiox->driver_class.open_plugin = open_plugin; audiox->driver_class.identifier = "DirectX"; audiox->driver_class.description = N_("xine audio output plugin for win32 using directx"); audiox->driver_class.dispose = default_audio_driver_class_dispose; audiox->xine = xine; lprintf("init_class() Exit! Returning audiox=%p\n", (void *)audiox); return audiox; } static const ao_info_t ao_info_directx = { .priority = 1, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_DIRECTX_IFACE_VERSION, "directx", XINE_VERSION_CODE, &ao_info_directx, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_none_out.c���������������������������������������������������������0000644�0001750�0001750�00000014406�14647725152�016623� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <inttypes.h> #define LOG_MODULE "audio_none_out" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #define AO_OUT_NONE_IFACE_VERSION 9 #define AUDIO_NUM_FRAGMENTS 15 #define AUDIO_FRAGMENT_SIZE 8192 #define AON_GAP_TOLERANCE AO_MAX_GAP typedef struct ao_none_driver_s { ao_driver_t ao_driver; xine_t *xine; int capabilities; int mode; int32_t sample_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; uint32_t latency; } ao_none_driver_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } ao_none_class_t; /* * open the audio device for writing to */ static int ao_none_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { ao_none_driver_t *this = (ao_none_driver_t *) this_gen; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_none_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); this->mode = mode; this->sample_rate = rate; this->bits_per_sample = bits; switch (mode) { case AO_CAP_MODE_MONO: this->num_channels = 1; break; case AO_CAP_MODE_STEREO: this->num_channels = 2; break; } return this->sample_rate; } static int ao_none_num_channels(ao_driver_t *this_gen) { ao_none_driver_t *this = (ao_none_driver_t *) this_gen; return this->num_channels; } static int ao_none_bytes_per_frame(ao_driver_t *this_gen) { ao_none_driver_t *this = (ao_none_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_none_get_gap_tolerance (ao_driver_t *this_gen) { (void)this_gen; return AON_GAP_TOLERANCE; } static int ao_none_write(ao_driver_t *this_gen, int16_t *data, uint32_t num_frames) { ao_none_driver_t *this = (ao_none_driver_t *) this_gen; (void)data; /* take some time to pretend we are doing something. * avoids burning cpu. */ if( (1000 * num_frames / this->sample_rate) > 10 ) xine_usec_sleep ((1000 * num_frames / this->sample_rate)*1000/2); return 1; } static int ao_none_delay (ao_driver_t *this_gen) { (void)this_gen; return 0; } static void ao_none_close(ao_driver_t *this_gen) { (void)this_gen; } static uint32_t ao_none_get_capabilities (ao_driver_t *this_gen) { ao_none_driver_t *this = (ao_none_driver_t *) this_gen; return this->capabilities; } static void ao_none_exit(ao_driver_t *this_gen) { ao_none_driver_t *this = (ao_none_driver_t *) this_gen; ao_none_close(this_gen); free (this); } static int ao_none_get_property (ao_driver_t *this_gen, int property) { (void)this_gen; (void)property; return 0; } static int ao_none_set_property (ao_driver_t *this_gen, int property, int value) { (void)this_gen; (void)property; return ~value; } static int ao_none_ctrl(ao_driver_t *this_gen, int cmd, ...) { /*ao_none_driver_t *this = (ao_none_driver_t *) this_gen;*/ (void)this_gen; switch (cmd) { case AO_CTRL_PLAY_PAUSE: break; case AO_CTRL_PLAY_RESUME: break; case AO_CTRL_FLUSH_BUFFERS: break; } return 0; } static ao_driver_t *ao_none_open_plugin (audio_driver_class_t *class_gen, const void *data) { ao_none_class_t *class = (ao_none_class_t *) class_gen; ao_none_driver_t *this; lprintf ("open_plugin called\n"); (void)data; this = calloc(1, sizeof (ao_none_driver_t)); if (!this) return NULL; this->xine = class->xine; this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO; this->sample_rate = 0; this->ao_driver.get_capabilities = ao_none_get_capabilities; this->ao_driver.get_property = ao_none_get_property; this->ao_driver.set_property = ao_none_set_property; this->ao_driver.open = ao_none_open; this->ao_driver.num_channels = ao_none_num_channels; this->ao_driver.bytes_per_frame = ao_none_bytes_per_frame; this->ao_driver.delay = ao_none_delay; this->ao_driver.write = ao_none_write; this->ao_driver.close = ao_none_close; this->ao_driver.exit = ao_none_exit; this->ao_driver.get_gap_tolerance = ao_none_get_gap_tolerance; this->ao_driver.control = ao_none_ctrl; return &this->ao_driver; } /* * class functions */ static void *ao_none_init_class (xine_t *xine, const void *data) { ao_none_class_t *this; lprintf ("init class\n"); (void)data; this = calloc(1, sizeof (ao_none_class_t)); if (!this) return NULL; this->driver_class.open_plugin = ao_none_open_plugin; this->driver_class.identifier = "none"; this->driver_class.description = N_("xine dummy audio output plugin"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; return this; } static const ao_info_t ao_info_none = { .priority = -1, /* do not auto probe this one */ }; /* * exported plugin catalog entry */ #define AO_NONE_CATALOG { PLUGIN_AUDIO_OUT, AO_OUT_NONE_IFACE_VERSION, "none", XINE_VERSION_CODE, &ao_info_none, ao_none_init_class } #ifndef XINE_MAKE_BUILTINS const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ AO_NONE_CATALOG, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_alsa_out.c���������������������������������������������������������0000644�0001750�0001750�00000173406�14647725152�016612� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Credits go * - for the SPDIF A/52 sync part * - frame size calculation added (16-08-2001) * (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> * for initial ALSA 0.9.x support. * adding MONO/STEREO/4CHANNEL/5CHANNEL/5.1CHANNEL analogue support. * (c) 2001 James Courtier-Dutton <James@superbug.demon.co.uk> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdarg.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #ifdef HAVE_ALLOCA_H #include <alloca.h> #endif #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API #include <alsa/asoundlib.h> #include <sys/ioctl.h> #include <inttypes.h> #include <pthread.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/audio_out.h> #include "speakers.h" /* #define ALSA_LOG #define ALSA_LOG_BUFFERS */ /* #define LOG_DEBUG */ #define AO_OUT_ALSA_IFACE_VERSION 9 #define BUFFER_TIME 1000*1000 #define GAP_TOLERANCE 5000 #define MIXER_MASK_LEFT 0x0001 #define MIXER_MASK_RIGHT 0x0002 #define MIXER_MASK_MUTE 0x0004 #define MIXER_MASK_STEREO 0x0008 #define MIXER_HAS_MUTE_SWITCH 0x0010 typedef struct { audio_driver_class_t driver_class; xine_t *xine; } alsa_class_t; typedef struct alsa_driver_s { ao_driver_t ao_driver; alsa_class_t *class; snd_pcm_t *audio_fd; int open_mode; int has_pause_resume; int is_paused; int32_t output_sample_rate, input_sample_rate; double sample_rate_factor; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; uint32_t bytes_in_buffer; /* number of bytes writen to audio hardware */ snd_pcm_uframes_t buffer_size; int32_t mmap; uint32_t supported_channels; /* field of 1 << num_channels */ uint32_t capabilities; struct _alsa_dev_info_s { struct alsa_driver_s *this; const char *type; const char *config_key; char *name; uint32_t supported_channels; /* field of 1 << num_channels */ uint32_t capabilities; } devs[5]; const char *bits_names[4]; /* 8, 16, 24, 32 */ struct { pthread_t thread; int thread_created; pthread_mutex_t mutex; char *name; snd_mixer_t *handle; snd_mixer_elem_t *elem; long min; long max; long left_vol; long right_vol; int mute; int running; } mixer; /* avoid *_alloca () */ snd_pcm_hw_params_t *hw_params; snd_pcm_sw_params_t *sw_params; snd_pcm_access_mask_t *ac_mask; snd_ctl_card_info_t *card_info; snd_pcm_status_t *pcm_status; } alsa_driver_t; static snd_output_t *jcd_out; /* * Get and convert volume to percent value */ static int ao_alsa_get_percent_from_volume(long val, long min, long max) { int range = max - min; return (range == 0) ? 0 : ((val - min) * 100.0 / range + .5); } /* Stolen from alsa-lib */ static int my_snd_mixer_wait(snd_mixer_t *mixer, int timeout) { struct pollfd spfds[16]; struct pollfd *pfds = spfds; int err, count; void *freeme = NULL; count = snd_mixer_poll_descriptors(mixer, pfds, sizeof(spfds) / sizeof(spfds[0])); if (count < 0) return count; if ((unsigned int) count > sizeof(spfds) / sizeof(spfds[0])) { freeme = pfds = calloc(count, sizeof(*pfds)); if (!pfds) return -ENOMEM; err = snd_mixer_poll_descriptors(mixer, pfds, (unsigned int) count); // XXX is this assert correct ? if triggered, it would be alsa bug, not xine bug ? assert(err == count); if (err < 0) { free(freeme); return err; } } err = poll(pfds, (unsigned int) count, timeout); free(freeme); if (err < 0) return -errno; return err; } /* * Wait (non blocking) till a mixer event happen */ static void *ao_alsa_handle_event_thread(void *data) { alsa_driver_t *this = (alsa_driver_t *) data; do { if(my_snd_mixer_wait(this->mixer.handle, 333) > 0) { int err, mute = 0, swl = 0, swr = 0; long right_vol, left_vol; int old_mute; pthread_mutex_lock(&this->mixer.mutex); old_mute = (this->mixer.mute & MIXER_MASK_MUTE) ? 1 : 0; if((err = snd_mixer_handle_events(this->mixer.handle)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_handle_events(): %s\n", snd_strerror(err)); pthread_mutex_unlock(&this->mixer.mutex); continue; } if((err = snd_mixer_selem_get_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &left_vol)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); pthread_mutex_unlock(&this->mixer.mutex); continue; } if((err = snd_mixer_selem_get_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, &right_vol)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); pthread_mutex_unlock(&this->mixer.mutex); continue; } if(this->mixer.mute & MIXER_HAS_MUTE_SWITCH) { if(this->mixer.mute & MIXER_MASK_STEREO) { snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &swl); mute = (swl) ? 0 : 1; } else { if (this->mixer.mute & MIXER_MASK_LEFT) snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &swl); if ((SND_MIXER_SCHN_FRONT_RIGHT != SND_MIXER_SCHN_UNKNOWN) && (this->mixer.mute & MIXER_MASK_RIGHT)) snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, &swr); mute = (swl || swr) ? 0 : 1; } } if((this->mixer.right_vol != right_vol) || (this->mixer.left_vol != left_vol) || (old_mute != mute)) { xine_event_t event; xine_audio_level_data_t data; xine_stream_t *stream; xine_list_iterator_t ite; this->mixer.right_vol = right_vol; this->mixer.left_vol = left_vol; if(mute) this->mixer.mute |= MIXER_MASK_MUTE; else this->mixer.mute &= ~MIXER_MASK_MUTE; data.right = ao_alsa_get_percent_from_volume(this->mixer.right_vol, this->mixer.min, this->mixer.max); data.left = ao_alsa_get_percent_from_volume(this->mixer.left_vol, this->mixer.min, this->mixer.max); data.mute = (this->mixer.mute & MIXER_MASK_MUTE) ? 1 : 0; event.type = XINE_EVENT_AUDIO_LEVEL; event.data = &data; event.data_length = sizeof(data); pthread_mutex_lock(&this->class->xine->streams_lock); ite = NULL; while ((stream = xine_list_next_value (this->class->xine->streams, &ite))) { event.stream = stream; xine_event_send(stream, &event); } pthread_mutex_unlock(&this->class->xine->streams_lock); } pthread_mutex_unlock(&this->mixer.mutex); } } while(this->mixer.running); pthread_exit(NULL); } /* * Convert percent value to volume and set */ static long ao_alsa_get_volume_from_percent(int val, long min, long max) { int range = max - min; return (range == 0) ? min : (val * range / 100.0 + min + .5); } /* * Error callback, we need to control this, * error message should be printed only in DEBUG mode. * XINE_FORMAT_PRINTF(5, 6) is true but useless here, * as alsa delivers "fmt" at runtime only. */ static void error_callback(const char *file, int line, const char *function, int err, const char *fmt, ...) { #ifdef DEBUG va_list args; char *buf = NULL; int result; va_start(args, fmt); result = vasprintf(&buf, fmt, args); va_end(args); if (result >= 0) { printf("%s: %s() %s.\n", file, function, buf); free(buf); } #else (void)file; (void)function; (void)fmt; #endif (void)err; (void)line; } /* * open the audio device for writing to */ static int ao_alsa_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { alsa_driver_t *this = (alsa_driver_t *) this_gen; char *pcm_device; int err; err = snd_output_stdio_attach(&jcd_out, stdout, 0); switch (mode) { case AO_CAP_MODE_MONO: this->num_channels = 1; pcm_device = this->devs[0].name; break; case AO_CAP_MODE_STEREO: this->num_channels = 2; pcm_device = this->devs[1].name; break; case AO_CAP_MODE_4CHANNEL: this->num_channels = 4; pcm_device = this->devs[2].name; break; case AO_CAP_MODE_4_1CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: this->num_channels = 6; pcm_device = this->devs[3].name; break; case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: this->num_channels = 2; pcm_device = this->devs[4].name; break; default: xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: ALSA Driver does not support the requested mode: 0x%X\n",mode); return 0; } #ifdef ALSA_LOG printf("audio_alsa_out: Audio Device name = %s\n",pcm_device); printf("audio_alsa_out: Number of channels = %d\n",this->num_channels); #endif if (this->audio_fd) { xine_log (this->class->xine, XINE_LOG_MSG, _("audio_alsa_out:Already open...WHY!")); snd_pcm_close (this->audio_fd); this->audio_fd = NULL; } this->open_mode = mode; this->input_sample_rate = rate; this->bits_per_sample = bits; this->bytes_in_buffer = 0; /* * open audio device * When switching to surround, dmix blocks the device some time, so we just keep trying for 0.8sec. */ { struct timeval start_time, end_time; gettimeofday (&start_time, NULL); while (1) { err = snd_pcm_open (&this->audio_fd, pcm_device, SND_PCM_STREAM_PLAYBACK, /* NONBLOCK */ 1); if (err != -EBUSY) break; gettimeofday (&end_time, NULL); if ((end_time.tv_sec - start_time.tv_sec) * 1000000 + end_time.tv_usec - start_time.tv_usec > 800000) break; usleep (10000); } } if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_LOG, _("audio_alsa_out: snd_pcm_open() of %s failed: %s\n"), pcm_device, snd_strerror (err)); if (err == -EBUSY) { xprintf (this->class->xine, XINE_VERBOSITY_LOG, _("audio_alsa_out: >>> check if another program already uses PCM <<<\n")); } return 0; } /* printf ("audio_alsa_out: snd_pcm_open() opened %s\n", pcm_device); */ /* We wanted non blocking open but now put it back to normal */ //snd_pcm_nonblock(this->audio_fd, 0); snd_pcm_nonblock(this->audio_fd, 1); do { /* configure audio device */ err = snd_pcm_hw_params_any (this->audio_fd, this->hw_params); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_LOG, _("audio_alsa_out: broken configuration for this PCM: no configurations available: %s\n"), snd_strerror (err)); break; } /* set interleaved access */ do { if (this->mmap != 0) { snd_pcm_access_mask_none (this->ac_mask); snd_pcm_access_mask_set (this->ac_mask, SND_PCM_ACCESS_MMAP_INTERLEAVED); snd_pcm_access_mask_set (this->ac_mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED); snd_pcm_access_mask_set (this->ac_mask, SND_PCM_ACCESS_MMAP_COMPLEX); err = snd_pcm_hw_params_set_access_mask (this->audio_fd, this->hw_params, this->ac_mask); if (err >= 0) break; xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: mmap not available, falling back to compatibility mode\n"); this->mmap = 0; } err = snd_pcm_hw_params_set_access (this->audio_fd, this->hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); } while (0); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: access type not available: %s\n", snd_strerror (err)); break; } /* set the sample format ([SU]{8,16,24,FLOAT}) */ /* ALSA automatically appends _LE or _BE depending on the CPU */ if ((bits < 8) || (bits > 32)) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: pcm format bits=%d unknown, trying 16.\n", (int)bits); bits = 16; } { static const snd_pcm_format_t fmts[5] = { 0, SND_PCM_FORMAT_U8, SND_PCM_FORMAT_S16, #ifdef WORDS_BIGENDIAN SND_PCM_FORMAT_S24_3BE, /* 24 bit samples taking 3 bytes. */ #else SND_PCM_FORMAT_S24_3LE, #endif SND_PCM_FORMAT_FLOAT }; snd_pcm_format_t format = fmts[bits >> 3]; err = snd_pcm_hw_params_set_format (this->audio_fd, this->hw_params, format); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: sample format not available: %s\n", snd_strerror (err)); break; } } /* set the number of channels */ err = snd_pcm_hw_params_set_channels (this->audio_fd, this->hw_params, this->num_channels); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Cannot set number of channels to %d (err=%d:%s)\n", this->num_channels, err, snd_strerror (err)); break; } { snd_pcm_uframes_t period_size, period_size_min, period_size_max; snd_pcm_uframes_t buffer_size_min, buffer_size_max; uint32_t buffer_time = BUFFER_TIME; snd_pcm_uframes_t buffer_time_to_size; int dir; #if 0 uint32_t periods; #endif #if 0 /* Restrict a configuration space to contain only real hardware rates */ err = snd_pcm_hw_params_set_rate_resample (this->audio_fd, this->hw_params, 0); #endif /* set the stream rate [Hz] */ dir = 0; err = snd_pcm_hw_params_set_rate_near (this->audio_fd, this->hw_params, &rate, &dir); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: rate not available: %s\n", snd_strerror (err)); break; } this->output_sample_rate = (uint32_t)rate; if (this->input_sample_rate != this->output_sample_rate) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: audio rate : %d requested, %d provided by device/sec\n", this->input_sample_rate, this->output_sample_rate); } buffer_time_to_size = ((uint64_t)buffer_time * rate) / 1000000; snd_pcm_hw_params_get_buffer_size_min (this->hw_params, &buffer_size_min); snd_pcm_hw_params_get_buffer_size_max (this->hw_params, &buffer_size_max); dir = 0; snd_pcm_hw_params_get_period_size_min (this->hw_params, &period_size_min, &dir); dir = 0; snd_pcm_hw_params_get_period_size_max (this->hw_params, &period_size_max, &dir); #ifdef ALSA_LOG_BUFFERS printf ("Buffer size range from %lu to %lu\n", buffer_size_min, buffer_size_max); printf ("Period size range from %lu to %lu\n", period_size_min, period_size_max); printf ("Buffer time size %lu\n", buffer_time_to_size); #endif this->buffer_size = buffer_time_to_size; if (buffer_size_max < this->buffer_size) this->buffer_size = buffer_size_max; if (buffer_size_min > this->buffer_size) this->buffer_size = buffer_size_min; period_size = this->buffer_size / 8; this->buffer_size = period_size * 8; #ifdef ALSA_LOG_BUFFERS printf ("To choose buffer_size = %ld\n", this->buffer_size); printf ("To choose period_size = %ld\n", period_size); #endif #if 0 /* Set period to buffer size ratios at 8 periods to 1 buffer */ dir = -1; periods = 8; err = snd_pcm_hw_params_set_periods_near (this->audio_fd, this->hw_params, &periods, &dir); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: unable to set any periods: %s\n", snd_strerror (err)); break; } /* set the ring-buffer time [us] (large enough for x us|y samples ...) */ dir = 0; err = snd_pcm_hw_params_set_buffer_time_near (this->audio_fd, this->hw_params, &buffer_time, &dir); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: buffer time not available: %s\n", snd_strerror (err)); break; } #endif #if 1 /* set the period time [us] (interrupt every x us|y samples ...) */ dir = 0; err = snd_pcm_hw_params_set_period_size_near (this->audio_fd, this->hw_params, &period_size, &dir); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: period time not available: %s\n", snd_strerror (err)); break; } #endif dir = 0; snd_pcm_hw_params_get_period_size (this->hw_params, &period_size, &dir); dir = 0; err = snd_pcm_hw_params_set_buffer_size_near (this->audio_fd, this->hw_params, &this->buffer_size); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: buffer time not available: %s\n", snd_strerror (err)); break; } snd_pcm_hw_params_get_buffer_size (this->hw_params, &(this->buffer_size)); #ifdef ALSA_LOG_BUFFERS printf ("was set period_size = %ld\n", period_size); printf ("was set buffer_size = %ld\n", this->buffer_size); #endif if (2 * period_size > this->buffer_size) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: buffer too small, could not use\n"); break; } /* write the parameters to device */ err = snd_pcm_hw_params (this->audio_fd, this->hw_params); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: pcm hw_params failed: %s\n", snd_strerror (err)); break; } /* Check for pause/resume support */ this->has_pause_resume = (snd_pcm_hw_params_can_pause (this->hw_params) && snd_pcm_hw_params_can_resume (this->hw_params)); xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out:open pause_resume=%d\n", this->has_pause_resume); if (this->has_pause_resume) this->capabilities &= ~AO_CAP_NO_UNPAUSE; else this->capabilities |= AO_CAP_NO_UNPAUSE; this->sample_rate_factor = (double) this->output_sample_rate / (double) this->input_sample_rate; this->bytes_per_frame = snd_pcm_frames_to_bytes (this->audio_fd, 1); /* audio buffer size handling */ /* Copy current parameters into swparams */ err = snd_pcm_sw_params_current (this->audio_fd, this->sw_params); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Unable to determine current swparams: %s\n", snd_strerror (err)); break; } #if defined(SND_LIB_VERSION) && SND_LIB_VERSION >= 0x010016 /* snd_pcm_sw_params_set_xfer_align() is deprecated, alignment is always 1 */ #else /* align all transfers to 1 sample */ err = snd_pcm_sw_params_set_xfer_align (this->audio_fd, this->sw_params, 1); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Unable to set transfer alignment: %s\n", snd_strerror (err)); break; } #endif /* allow the transfer when at least period_size samples can be processed */ err = snd_pcm_sw_params_set_avail_min (this->audio_fd, this->sw_params, period_size); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Unable to set available min: %s\n", snd_strerror (err)); break; } /* start the transfer when the buffer contains at least period_size samples */ err = snd_pcm_sw_params_set_start_threshold (this->audio_fd, this->sw_params, period_size); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Unable to set start threshold: %s\n", snd_strerror (err)); break; } } /* never stop the transfer, even on xruns */ err = snd_pcm_sw_params_set_stop_threshold (this->audio_fd, this->sw_params, this->buffer_size); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Unable to set stop threshold: %s\n", snd_strerror (err)); break; } /* Install swparams into current parameters */ err = snd_pcm_sw_params (this->audio_fd, this->sw_params); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Unable to set swparams: %s\n", snd_strerror (err)); break; } #ifdef ALSA_LOG snd_pcm_dump_setup (this->audio_fd, jcd_out); snd_pcm_sw_params_dump (this->sw_params, jcd_out); #endif return this->output_sample_rate; } while (0); snd_pcm_close (this->audio_fd); this->audio_fd = NULL; return 0; } /* * Return the number of audio channels */ static int ao_alsa_num_channels(ao_driver_t *this_gen) { alsa_driver_t *this = (alsa_driver_t *) this_gen; return this->num_channels; } /* * Return the number of bytes per frame */ static int ao_alsa_bytes_per_frame(ao_driver_t *this_gen) { alsa_driver_t *this = (alsa_driver_t *) this_gen; return this->bytes_per_frame; } /* * Return gap tolerance (in pts) */ static int ao_alsa_get_gap_tolerance (ao_driver_t *this_gen) { (void)this_gen; return GAP_TOLERANCE; } /* * Return the delay. is frames measured by looking at pending samples */ /* FIXME: delay returns invalid data if status is not RUNNING. * e.g When there is an XRUN or we are in PREPARED mode. */ static int ao_alsa_delay (ao_driver_t *this_gen) { snd_pcm_sframes_t delay = 0; int err = 0; alsa_driver_t *this = (alsa_driver_t *) this_gen; #ifdef LOG_DEBUG struct timeval now; printf("audio_alsa_out:delay:ENTERED\n"); #endif err = snd_pcm_delay( this->audio_fd, &delay ); #ifdef LOG_DEBUG printf("audio_alsa_out:delay:delay all=%ld err=%d\n",delay, err); gettimeofday(&now, 0); printf("audio_alsa_out:delay: Time = %ld.%ld\n", now.tv_sec, now.tv_usec); printf("audio_alsa_out:delay:FINISHED\n"); #endif /* * try to recover from errors and recalculate delay */ if(err) { #ifdef LOG_DEBUG printf("gap audio_alsa_out:delay: recovery\n"); #endif err = snd_pcm_recover( this->audio_fd, err, 1 ); err = snd_pcm_delay( this->audio_fd, &delay ); } /* * if we have a negative delay try to forward within the buffer */ if(!err && (delay < 0)) { #ifdef LOG_DEBUG printf("gap audio_alsa_out:delay: forwarding frames: %d\n", (int)-delay); #endif err = snd_pcm_forward( this->audio_fd, -delay ); if(err >= 0) { err = snd_pcm_delay( this->audio_fd, &delay ); } } /* * on error or (still) negative delays ensure delay * is not negative */ if (err || (delay < 0)) delay = 0; return delay; } #if 0 /* * Handle over/under-run */ static void xrun(alsa_driver_t *this) { int res; /* if ((res = snd_pcm_status (this->audio_fd, this->pcm_status)) < 0) { printf ("audio_alsa_out: status error: %s\n", snd_strerror(res)); return; } snd_pcm_status_dump (this->pcm_status, jcd_out); */ if (snd_pcm_state(this->audio_fd) == SND_PCM_STATE_XRUN) { /* struct timeval now, diff, tstamp; gettimeofday(&now, 0); snd_pcm_status_get_trigger_tstamp (this->pcm_status, &tstamp); timersub(&now, &tstamp, &diff); printf ("audio_alsa_out: xrun!!! (at least %.3f ms long)\n", diff.tv_sec * 1000 + diff.tv_usec / 1000.0); */ xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: XRUN!!!\n"); if ((res = snd_pcm_prepare(this->audio_fd))<0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: xrun: prepare error: %s", snd_strerror(res)); return; } return; /* ok, data should be accepted again */ } } #endif /* * resume from suspend */ static int resume(snd_pcm_t *pcm) { int res; while ((res = snd_pcm_resume(pcm)) == -EAGAIN) sleep(1); if (! res) return 0; return snd_pcm_prepare(pcm); } /* * Write audio data to output buffer (blocking using snd_pcm_wait) */ static int ao_alsa_write(ao_driver_t *this_gen, int16_t *data, uint32_t count) { snd_pcm_sframes_t result; snd_pcm_state_t state; #ifdef LOG_DEBUG struct timeval now; #endif int wait_result; int res; uint8_t *buffer=(uint8_t *)data; snd_pcm_uframes_t number_of_frames = (snd_pcm_uframes_t) count; alsa_driver_t *this = (alsa_driver_t *) this_gen; #ifdef LOG_DEBUG printf("audio_alsa_out:write:ENTERED\n"); gettimeofday(&now, 0); printf("audio_alsa_out:write: Time = %ld.%ld\n", now.tv_sec, now.tv_usec); printf("audio_alsa_out:write:count=%u\n",count); #endif state = snd_pcm_state(this->audio_fd); if (state == SND_PCM_STATE_SUSPENDED) { res = resume(this->audio_fd); if (res < 0) return 0; state = snd_pcm_state(this->audio_fd); } else if (state == SND_PCM_STATE_DISCONNECTED) { /* the device is gone. audio_out.c handles it if we return something < 0 */ return -1; } if (state == SND_PCM_STATE_XRUN) { #ifdef LOG_DEBUG printf("audio_alsa_out:write:XRUN before\n"); snd_pcm_status (this->audio_fd, this->pcm_status); snd_pcm_status_dump (this->pcm_status, jcd_out); #endif if ((res = snd_pcm_prepare(this->audio_fd))<0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: xrun: prepare error: %s", snd_strerror(res)); return 0; } state = snd_pcm_state(this->audio_fd); #ifdef LOG_DEBUG printf("audio_alsa_out:write:XRUN after\n"); #endif } if ( (state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING) && (state != SND_PCM_STATE_DRAINING) ) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out:write:BAD STATE, state = %d\n",state); } while( number_of_frames > 0) { if ( state == SND_PCM_STATE_RUNNING ) { #ifdef LOG_DEBUG printf("audio_alsa_out:write:loop:waiting for Godot\n"); #endif snd_pcm_status (this->audio_fd, this->pcm_status); if (snd_pcm_status_get_avail (this->pcm_status) < number_of_frames) { wait_result = snd_pcm_wait(this->audio_fd, 1000); #ifdef LOG_DEBUG printf("audio_alsa_out:write:loop:wait_result=%d\n",wait_result); #endif if (wait_result <= 0) return 0; } } if (this->mmap != 0) { result = snd_pcm_mmap_writei(this->audio_fd, buffer, number_of_frames); } else { result = snd_pcm_writei(this->audio_fd, buffer, number_of_frames); } if (result < 0) { #ifdef LOG_DEBUG printf("audio_alsa_out:write:result=%ld:%s\n",result, snd_strerror(result)); #endif state = snd_pcm_state(this->audio_fd); if (state == SND_PCM_STATE_SUSPENDED) { res = resume(this->audio_fd); if (res < 0) return 0; continue; } if (state == SND_PCM_STATE_DISCONNECTED) { /* the device is gone. audio_out.c handles it if we return something < 0 */ return -1; } else if ( (state != SND_PCM_STATE_PREPARED) && (state != SND_PCM_STATE_RUNNING) && (state != SND_PCM_STATE_DRAINING) ) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out:write:BAD STATE2, state = %d, going to try XRUN\n",state); if ((res = snd_pcm_prepare(this->audio_fd))<0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: xrun: prepare error: %s", snd_strerror(res)); return 0; } } } if (result > 0) { number_of_frames -= result; buffer += result * this->bytes_per_frame; } } #if 0 if ( (state == SND_PCM_STATE_RUNNING) ) { #ifdef LOG_DEBUG printf("audio_alsa_out:write:loop:waiting for Godot2\n"); #endif wait_result = snd_pcm_wait(this->audio_fd, 1000000); #ifdef LOG_DEBUG printf("audio_alsa_out:write:loop:wait_result=%d\n",wait_result); #endif if (wait_result < 0) return 0; } #endif #ifdef LOG_DEBUG gettimeofday(&now, 0); printf("audio_alsa_out:write: Time = %ld.%ld\n", now.tv_sec, now.tv_usec); printf("audio_alsa_out:write:FINISHED\n"); #endif return 1; /* audio samples were processed ok */ } /* * This is called when the decoder no longer uses the audio */ static void ao_alsa_close(ao_driver_t *this_gen) { alsa_driver_t *this = (alsa_driver_t *) this_gen; if(this->audio_fd) { snd_pcm_nonblock(this->audio_fd, 0); snd_pcm_drain(this->audio_fd); snd_pcm_close(this->audio_fd); } this->audio_fd = NULL; this->has_pause_resume = 0; /* This is set at open time */ } /* * Find out what output modes + capatilities are supported */ static uint32_t ao_alsa_get_capabilities (ao_driver_t *this_gen) { alsa_driver_t *this = (alsa_driver_t *) this_gen; return this->capabilities; } /* * Shut down audio output driver plugin and free all resources allocated */ static void ao_alsa_exit(ao_driver_t *this_gen) { alsa_driver_t *this = (alsa_driver_t *) this_gen; this->class->xine->config->unregister_callbacks (this->class->xine->config, NULL, NULL, this, sizeof (*this)); /* * Destroy the mixer thread and cleanup the mixer, so that * any child processes (such as xscreensaver) cannot inherit * the mixer's handle and keep it open. * By rejoining the mixer thread, we remove a race condition * between closing the handle and spawning the child process * (i.e. xscreensaver). */ if(this->mixer.handle && this->mixer.thread_created) { this->mixer.running = 0; pthread_join(this->mixer.thread, NULL); snd_mixer_close(this->mixer.handle); this->mixer.handle=0; } pthread_mutex_destroy(&this->mixer.mutex); if (this->audio_fd) snd_pcm_close(this->audio_fd); this->audio_fd=NULL; xine_config_free_string(this->class->xine, &this->mixer.name); { uint32_t u; for (u = 0; u < sizeof (this->devs) / sizeof (this->devs[0]); u++) { _x_freep (&this->devs[u].name); } } free (this); } /* * Get a property of audio driver */ static int ao_alsa_get_property (ao_driver_t *this_gen, int property) { alsa_driver_t *this = (alsa_driver_t *) this_gen; int err; switch(property) { case AO_PROP_MIXER_VOL: case AO_PROP_PCM_VOL: if(this->mixer.elem) { int vol; pthread_mutex_lock(&this->mixer.mutex); if((err = snd_mixer_selem_get_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &this->mixer.left_vol)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); goto done; } if((err = snd_mixer_selem_get_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, &this->mixer.right_vol)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); goto done; } done: vol = (((ao_alsa_get_percent_from_volume(this->mixer.left_vol, this->mixer.min, this->mixer.max)) + (ao_alsa_get_percent_from_volume(this->mixer.right_vol, this->mixer.min, this->mixer.max))) /2); pthread_mutex_unlock(&this->mixer.mutex); return vol; } break; case AO_PROP_MUTE_VOL: { int mute; pthread_mutex_lock(&this->mixer.mutex); mute = ((this->mixer.mute & MIXER_HAS_MUTE_SWITCH) && (this->mixer.mute & MIXER_MASK_MUTE)) ? 1 : 0; pthread_mutex_unlock(&this->mixer.mutex); return mute; } break; } return 0; } /* * Set a property of audio driver */ static int ao_alsa_set_property (ao_driver_t *this_gen, int property, int value) { alsa_driver_t *this = (alsa_driver_t *) this_gen; int err; switch(property) { case AO_PROP_MIXER_VOL: case AO_PROP_PCM_VOL: if(this->mixer.elem) { pthread_mutex_lock(&this->mixer.mutex); this->mixer.left_vol = this->mixer.right_vol = ao_alsa_get_volume_from_percent(value, this->mixer.min, this->mixer.max); if((err = snd_mixer_selem_set_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, this->mixer.left_vol)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); pthread_mutex_unlock(&this->mixer.mutex); return ~value; } if((err = snd_mixer_selem_set_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, this->mixer.right_vol)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); pthread_mutex_unlock(&this->mixer.mutex); return ~value; } pthread_mutex_unlock(&this->mixer.mutex); return value; } break; case AO_PROP_MUTE_VOL: if(this->mixer.elem) { if(this->mixer.mute & MIXER_HAS_MUTE_SWITCH) { int swl = 0, swr = 0; int old_mute; pthread_mutex_lock(&this->mixer.mutex); old_mute = this->mixer.mute; if(value) this->mixer.mute |= MIXER_MASK_MUTE; else this->mixer.mute &= ~MIXER_MASK_MUTE; if ((this->mixer.mute & MIXER_MASK_MUTE) != (old_mute & MIXER_MASK_MUTE)) { if(this->mixer.mute & MIXER_MASK_STEREO) { snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &swl); snd_mixer_selem_set_playback_switch_all(this->mixer.elem, !swl); } else { if (this->mixer.mute & MIXER_MASK_LEFT) { snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &swl); snd_mixer_selem_set_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, !swl); } if (SND_MIXER_SCHN_FRONT_RIGHT != SND_MIXER_SCHN_UNKNOWN && (this->mixer.mute & MIXER_MASK_RIGHT)) { snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, &swr); snd_mixer_selem_set_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, !swr); } } } pthread_mutex_unlock(&this->mixer.mutex); } return value; } return ~value; break; } return ~value; } /* * Misc control operations */ static int ao_alsa_ctrl(ao_driver_t *this_gen, int cmd, ...) { alsa_driver_t *this = (alsa_driver_t *) this_gen; int err; /* Alsa 0.9.x pause and resume is not stable enough at the moment. * Use snd_pcm_drop and restart instead. */ switch (cmd) { case AO_CTRL_PLAY_PAUSE: if (this->audio_fd) { if (this->has_pause_resume) { if ((err=snd_pcm_pause(this->audio_fd, 1)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Pause call failed. (err=%d:%s)\n",err, snd_strerror(err)); this->has_pause_resume = 0; ao_alsa_ctrl(this_gen, AO_CTRL_PLAY_PAUSE, NULL); } else { this->is_paused = 1; } } else { if ((err=snd_pcm_reset(this->audio_fd)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Reset call failed. (err=%d:%s)\n",err, snd_strerror(err)); } if ((err=snd_pcm_drain(this->audio_fd)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Drain call failed. (err=%d:%s)\n",err, snd_strerror(err)); } if ((err=snd_pcm_prepare(this->audio_fd)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Prepare call failed. (err=%d:%s)\n",err, snd_strerror(err)); } } } break; case AO_CTRL_PLAY_RESUME: if (this->audio_fd) { if (this->has_pause_resume && this->is_paused) { if ((err=snd_pcm_pause(this->audio_fd, 0)) < 0) { if (err == -77) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Warning: How am I supposed to RESUME, if I am not PAUSED. " "audio_out.c, please don't call me!\n"); break; } xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Resume call failed. (err=%d:%s)\n",err, snd_strerror(err)); this->has_pause_resume = 0; } else { this->is_paused = 0; } } } break; case AO_CTRL_FLUSH_BUFFERS: if (this->audio_fd) { if ((err=snd_pcm_drop(this->audio_fd)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Drop call failed. (err=%d:%s)\n",err, snd_strerror(err)); } if ((err=snd_pcm_prepare(this->audio_fd)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: Prepare call failed. (err=%d:%s)\n",err, snd_strerror(err)); } } break; } return 0; } /* * Initialize mixer */ static void ao_alsa_mixer_init(ao_driver_t *this_gen) { alsa_driver_t *this = (alsa_driver_t *) this_gen; config_values_t *config = this->class->xine->config; const char *pcm_device; snd_ctl_t *ctl_handle; int err; void *mixer_sid; snd_mixer_elem_t *elem; int mixer_n_selems = 0; snd_mixer_selem_id_t *sid; int loop = 0; int found; int swl = 0, swr = 0, send_events; this->mixer.elem = 0; pcm_device = this->devs[0].name; err = snd_ctl_open (&ctl_handle, pcm_device, 0); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_ctl_open(): %s\n", snd_strerror(err)); return; } if ((err = snd_ctl_card_info (ctl_handle, this->card_info)) < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_ctl_card_info(): %s\n", snd_strerror(err)); snd_ctl_close(ctl_handle); return; } snd_ctl_close (ctl_handle); /* * Open mixer device */ if ((err = snd_mixer_open (&this->mixer.handle, 0)) < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_open(): %s\n", snd_strerror(err)); this->mixer.handle=0; return; } if ((err = snd_mixer_attach (this->mixer.handle, pcm_device)) < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_attach(): %s\n", snd_strerror(err)); snd_mixer_close(this->mixer.handle); this->mixer.handle=0; return; } if ((err = snd_mixer_selem_register (this->mixer.handle, NULL, NULL)) < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_register(): %s\n", snd_strerror(err)); snd_mixer_close(this->mixer.handle); this->mixer.handle=0; return; } if ((err = snd_mixer_load (this->mixer.handle)) < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_load(): %s\n", snd_strerror(err)); snd_mixer_close(this->mixer.handle); this->mixer.handle=0; return; } mixer_sid = calloc (1, snd_mixer_selem_id_sizeof () * snd_mixer_get_count (this->mixer.handle)); if (mixer_sid == NULL) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: malloc () failed: %s\n", strerror (errno)); snd_mixer_close(this->mixer.handle); this->mixer.handle=0; return; } again: found = 0; mixer_n_selems = 0; for (elem = snd_mixer_first_elem(this->mixer.handle); elem; elem = snd_mixer_elem_next(elem)) { sid = (snd_mixer_selem_id_t *)(((char *)mixer_sid) + snd_mixer_selem_id_sizeof() * mixer_n_selems); if ((snd_mixer_elem_get_type(elem) != SND_MIXER_ELEM_SIMPLE) || !snd_mixer_selem_is_active(elem)) continue; snd_mixer_selem_get_id(elem, sid); mixer_n_selems++; if(!strcmp((snd_mixer_selem_get_name(elem)), this->mixer.name)) { /* printf("found %s\n", snd_mixer_selem_get_name(elem)); */ this->mixer.elem = elem; snd_mixer_selem_get_playback_volume_range(this->mixer.elem, &this->mixer.min, &this->mixer.max); if((err = snd_mixer_selem_get_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &this->mixer.left_vol)) < 0) { xprintf(this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); this->mixer.elem = NULL; continue; } if((err = snd_mixer_selem_get_playback_volume(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, &this->mixer.right_vol)) < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: snd_mixer_selem_get_playback_volume(): %s\n", snd_strerror(err)); this->mixer.elem = NULL; continue; } /* Channels mute */ this->mixer.mute = 0; if(snd_mixer_selem_has_playback_switch(this->mixer.elem)) { this->mixer.mute |= MIXER_HAS_MUTE_SWITCH; if (snd_mixer_selem_has_playback_switch_joined(this->mixer.elem)) { this->mixer.mute |= MIXER_MASK_STEREO; snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &swl); } else { this->mixer.mute |= MIXER_MASK_LEFT; snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_LEFT, &swl); if (SND_MIXER_SCHN_FRONT_RIGHT != SND_MIXER_SCHN_UNKNOWN) { this->mixer.mute |= MIXER_MASK_RIGHT; snd_mixer_selem_get_playback_switch(this->mixer.elem, SND_MIXER_SCHN_FRONT_RIGHT, &swr); } if(!swl || !swr) this->mixer.mute |= MIXER_MASK_MUTE; } this->capabilities |= AO_CAP_MUTE_VOL; } found++; goto mixer_found; } } if(loop) goto mixer_found; /* Yes, untrue but... ;-) */ if(!strcmp(this->mixer.name, "PCM")) { config->update_string(config, "audio.device.alsa_mixer_name", "Master"); loop++; } else { config->update_string(config, "audio.device.alsa_mixer_name", "PCM"); } config->free_string(config, &this->mixer.name); this->mixer.name = config->lookup_string(config, "audio.device.alsa_mixer_name"); goto again; mixer_found: free (mixer_sid); /* * Ugly: yes[*] no[ ] */ if(found) { if(!strcmp(this->mixer.name, "Master")) this->capabilities |= AO_CAP_MIXER_VOL; else this->capabilities |= AO_CAP_PCM_VOL; } else { if (this->mixer.handle) { snd_mixer_close(this->mixer.handle); this->mixer.handle=0; } return; } /* Create a thread which wait/handle mixer events */ send_events = config->register_bool(config, "audio.alsa_hw_mixer", 1, _("notify changes to the hardware mixer"), _("When the hardware mixer changes, your application will receive " "a notification so that it can update its graphical representation " "of the mixer settings on the fly."), 10, NULL, NULL); if (send_events && found) { pthread_attr_t pth_attrs; struct sched_param pth_params; this->mixer.running = 1; pthread_attr_init(&pth_attrs); pthread_attr_getschedparam(&pth_attrs, &pth_params); pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER); pthread_attr_setschedparam(&pth_attrs, &pth_params); if (pthread_create(&this->mixer.thread, &pth_attrs, ao_alsa_handle_event_thread, (void *) this)) { xprintf (this->class->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": pthread_create() failed\n"); } else { this->mixer.thread_created = 1; } pthread_attr_destroy(&pth_attrs); } } static void alsa_apply_speaker_arrangement (alsa_driver_t *this, int speakers) { char logbuf[2048], *q, *logend = logbuf + sizeof (logbuf); q = logbuf; q += strlcpy (q, _("audio_alsa_out : supported modes are"), logend - q); if (q >= logend) q = logend; if (this->capabilities & AO_CAP_8BITS) { q += strlcpy (q, this->bits_names[0], logend - q); if (q >= logend) q = logend; } if (this->capabilities & AO_CAP_16BITS) { q += strlcpy (q, this->bits_names[1], logend - q); if (q >= logend) q = logend; } if (this->capabilities & AO_CAP_24BITS) { q += strlcpy (q, this->bits_names[2], logend - q); if (q >= logend) q = logend; } if (this->capabilities & AO_CAP_FLOAT32) { q += strlcpy (q, this->bits_names[3], logend - q); if (q >= logend) q = logend; } this->capabilities &= ~(AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL | AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL | AO_CAP_MODE_A52 | AO_CAP_MODE_AC5); /* always set these. */ if (this->supported_channels & (1 << 1)) { this->capabilities |= AO_CAP_MODE_MONO; q += strlcpy (q, this->devs[0].type, logend - q); if (q >= logend) q = logend; } if (this->supported_channels & (1 << 2)) { this->capabilities |= AO_CAP_MODE_STEREO; q += strlcpy (q, this->devs[1].type, logend - q); if (q >= logend) q = logend; } if (this->supported_channels & (1 << 4)) { const char *t; if (speakers == SURROUND4) { this->capabilities |= AO_CAP_MODE_4CHANNEL; t = this->devs[2].type; } else { t = _(" (4-channel not enabled in xine config)"); } q += strlcpy (q, t, logend - q); if (q >= logend) q = logend; } if (this->supported_channels & (1 << 6)) { const char *t; if (speakers == SURROUND41) { this->capabilities |= AO_CAP_MODE_4_1CHANNEL; t = _(" 4.1-channel"); } else { t = _(" (4.1-channel not enabled in xine config)"); } q += strlcpy (q, t, logend - q); if (q >= logend) q = logend; if (speakers == SURROUND5) { this->capabilities |= AO_CAP_MODE_5CHANNEL; t = _(" 5-channel"); } else { t = _(" (5-channel not enabled in xine config)"); } q += strlcpy (q, t, logend - q); if (q >= logend) q = logend; /* NOTE: That ">=" covers both the high channel counts and passthrough mode. * This is more or less a BUG when a traditional SPDIF link is used. * However, if alsa_surround51_device refers to the same HDMI port * as alsa_passthrough_device, then we have a HACK that routes software * decoded 5.1 where it belongs :-) */ if (speakers >= SURROUND51) { this->capabilities |= AO_CAP_MODE_5_1CHANNEL; t = this->devs[3].type; } else { t = _(" (5.1-channel not enabled in xine config)"); } q += strlcpy (q, t, logend - q); if (q >= logend) q = logend; } { const char *t; if (speakers == A52_PASSTHRU) { this->capabilities |= AO_CAP_MODE_A52 | AO_CAP_MODE_AC5; t = this->devs[4].type; } else { t = _(" (a/52 and DTS pass-through not enabled in xine config)"); } q += strlcpy (q, t, logend - q); /* if (q >= logend) q = logend; */ } xprintf (this->class->xine, XINE_VERBOSITY_LOG, "%s.\n", logbuf); } static void _alsa_mmap_cb (void *user_data, xine_cfg_entry_t *entry) { alsa_driver_t *this = (alsa_driver_t *)user_data; this->mmap = entry->num_value; } static void _alsa_speaker_arrangement_cb (void *user_data, xine_cfg_entry_t *entry) { alsa_driver_t *this = (alsa_driver_t *)user_data; alsa_apply_speaker_arrangement (this, entry->num_value); } static char *_alsa_safe_strdup (const char *s) { return s ? strdup (s) : NULL; } static void _alsa_dev_name_cb (void *user_data, xine_cfg_entry_t *entry) { struct _alsa_dev_info_s *info = (struct _alsa_dev_info_s *)user_data; free (info->name); info->name = _alsa_safe_strdup (entry->str_value); } static int _alsa_query_dev (alsa_driver_t *this, uint32_t index) { char logbuf[2048], *q = logbuf, *logend = logbuf + sizeof (logbuf); struct _alsa_dev_info_s *info = &this->devs[index]; const char *name; uint32_t u; int err; name = info->name ? info->name : "default"; if (1) { /* skip doubles */ for (u = 0; u < sizeof (this->devs) / sizeof (this->devs[0]); u++) { if (u != index) { const char *alias = this->devs[u].name ? this->devs[u].name : "default"; if (!strcmp (name, alias) && this->devs[u].supported_channels) { info->capabilities = this->devs[u].capabilities; info->supported_channels = this->devs[u].supported_channels; xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: already probed \"%s\" for%s.\n", name, info->type); return 2; } } } } xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: probing \"%s\" for%s ...\n", name, info->type); q += strlcpy (q, "audio_alsa_out: ", logend - q); if (q > logend) q = logend; q += strlcpy (q, name, logend - q); if (q > logend) q = logend; q += strlcpy (q, ": ", logend - q); if (q > logend) q = logend; err = snd_pcm_open (&this->audio_fd, name, SND_PCM_STREAM_PLAYBACK, 1); /* NON-BLOCK mode */ if (err < 0) { xine_log (this->class->xine, XINE_LOG_MSG, _("snd_pcm_open() failed:%d:%s\n"), err, snd_strerror (err)); xine_log (this->class->xine, XINE_LOG_MSG, _(">>> Check if another program already uses PCM <<<\n")); return 0; } err = snd_pcm_hw_params_any (this->audio_fd, this->hw_params); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: broken configuration for this PCM: no configurations available.\n"); snd_pcm_close (this->audio_fd); this->audio_fd = NULL; return 0; } info->capabilities &= ~(AO_CAP_8BITS | AO_CAP_16BITS | AO_CAP_24BITS | AO_CAP_FLOAT32); if (!(snd_pcm_hw_params_test_format (this->audio_fd, this->hw_params, SND_PCM_FORMAT_U8))) { info->capabilities |= AO_CAP_8BITS; q += strlcpy (q, this->bits_names[0], logend - q); if (q > logend) q = logend; } if (!(snd_pcm_hw_params_test_format (this->audio_fd, this->hw_params, SND_PCM_FORMAT_S16))) { info->capabilities |= AO_CAP_16BITS; q += strlcpy (q, this->bits_names[1], logend - q); if (q > logend) q = logend; } if (!(snd_pcm_hw_params_test_format (this->audio_fd, this->hw_params, SND_PCM_FORMAT_S24))) { info->capabilities |= AO_CAP_24BITS; q += strlcpy (q, this->bits_names[2], logend - q); if (q > logend) q = logend; } if (!(snd_pcm_hw_params_test_format (this->audio_fd, this->hw_params, SND_PCM_FORMAT_FLOAT))) { info->capabilities |= AO_CAP_FLOAT32; q += strlcpy (q, this->bits_names[3], logend - q); if (q > logend) q = logend; } if (0 == (info->capabilities & (AO_CAP_FLOAT32 | AO_CAP_24BITS | AO_CAP_16BITS | AO_CAP_8BITS))) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: no supported PCM format found.\n"); snd_pcm_close (this->audio_fd); this->audio_fd = NULL; return 0; } info->supported_channels = 0; if (!(snd_pcm_hw_params_test_channels (this->audio_fd, this->hw_params, 1))) { info->supported_channels |= 1 << 1; q += strlcpy (q, this->devs[0].type, logend - q); if (q > logend) q = logend; } if (!(snd_pcm_hw_params_test_channels (this->audio_fd, this->hw_params, 2))) { info->supported_channels |= 1 << 2; q += strlcpy (q, this->devs[1].type, logend - q); if (q > logend) q = logend; } if (!(snd_pcm_hw_params_test_channels (this->audio_fd, this->hw_params, 4))) { info->supported_channels |= 1 << 4; q += strlcpy (q, this->devs[2].type, logend - q); if (q > logend) q = logend; } if (!(snd_pcm_hw_params_test_channels (this->audio_fd, this->hw_params, 6))) { info->supported_channels |= 1 << 6; q += strlcpy (q, this->devs[3].type, logend - q); if (q > logend) q = logend; } err = snd_pcm_hw_params_set_access (this->audio_fd, this->hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "audio_alsa_out: interleaved access not available."); snd_pcm_close (this->audio_fd); this->audio_fd = NULL; return 0; } if (index == 4) { info->capabilities |= AO_CAP_MODE_A52 | AO_CAP_MODE_AC5; q += strlcpy (q, this->devs[4].type, logend - q); if (q > logend) q = logend; } xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "%s.\n", logbuf); this->supported_channels = 0; for (u = 0; u < sizeof (this->devs) / sizeof (this->devs[0]); u++) { this->supported_channels |= this->devs[u].supported_channels; if (u != index) { const char *alias = this->devs[u].name ? this->devs[u].name : "default"; if (!strcmp (name, alias)) { this->devs[u].capabilities = info->capabilities; this->devs[u].supported_channels = info->supported_channels; } } } snd_pcm_close (this->audio_fd); this->audio_fd = NULL; return 1; } /* * Initialize plugin */ static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { alsa_class_t *class = (alsa_class_t *) class_gen; config_values_t *config = class->xine->config; alsa_driver_t *this; (void)data; { uint32_t s_this = (sizeof (*this) + 15) & ~15u; uint32_t s_hw_params = (snd_pcm_hw_params_sizeof () + 15) & ~15u; uint32_t s_sw_params = (snd_pcm_sw_params_sizeof () + 15) & ~15u; uint32_t s_ac_mask = (snd_pcm_access_mask_sizeof () + 15) & ~15u; uint32_t s_card_info = (snd_ctl_card_info_sizeof () + 15) & ~15u; uint32_t s_status = (snd_pcm_status_sizeof () + 15) & ~15u; uint8_t *m = calloc (1, s_this + s_hw_params + s_sw_params + s_ac_mask + s_card_info + s_status); if (!m) return NULL; this = (alsa_driver_t *)m; m += s_this; this->hw_params = (snd_pcm_hw_params_t *)m; m += s_hw_params; this->sw_params = (snd_pcm_sw_params_t *)m; m += s_sw_params; this->ac_mask = (snd_pcm_access_mask_t *)m; m += s_ac_mask; this->card_info = (snd_ctl_card_info_t *)m; m += s_card_info; this->pcm_status = (snd_pcm_status_t *)m; } #ifndef HAVE_ZERO_SAFE_MEM this->devs[0].supported_channels = 0; this->devs[0].capabilities = 0; this->devs[1].supported_channels = 0; this->devs[1].capabilities = 0; this->devs[2].supported_channels = 0; this->devs[2].capabilities = 0; this->devs[3].supported_channels = 0; this->devs[3].capabilities = 0; this->devs[4].supported_channels = 0; this->devs[4].capabilities = 0; this->capabilities = 0; this->has_pause_resume = 0; /* This is checked at open time instead */ this->is_paused = 0; this->output_sample_rate = 0; #endif this->class = class; this->bits_names[0] = _(" 8bit"); this->bits_names[1] = _(" 16bit"); this->bits_names[2] = _(" 24bit"); this->bits_names[3] = _(" 32bit"); this->mmap = config->register_bool (config, "audio.device.alsa_mmap_enable", 0, _("sound card can do mmap"), _("Enable this, if your sound card and alsa driver support memory mapped IO.\n" "You can try enabling it and check, if everything works. If it does, this " "will increase performance."), 10, _alsa_mmap_cb, this); this->devs[0].this = this; this->devs[0].type = _(" mono"); this->devs[0].config_key = "audio.device.alsa_default_device"; this->devs[0].name = _alsa_safe_strdup (config->register_string (config, this->devs[0].config_key, "default", _("device used for mono output"), _("xine will use this alsa device to output mono sound.\n" "See the alsa documentation for information on alsa devices."), 10, _alsa_dev_name_cb, &this->devs[0])); this->devs[1].this = this; this->devs[1].type = _(" stereo"); this->devs[1].config_key = "audio.device.alsa_front_device"; this->devs[1].name = _alsa_safe_strdup (config->register_string (config, this->devs[1].config_key, "plug:front:default", _("device used for stereo output"), _("xine will use this alsa device to output stereo sound.\n" "See the alsa documentation for information on alsa devices."), 10, _alsa_dev_name_cb, &this->devs[1])); this->devs[2].this = this; this->devs[2].type = _(" 4-channel"); this->devs[2].config_key = "audio.device.alsa_surround40_device"; this->devs[2].name = _alsa_safe_strdup (config->register_string (config, this->devs[2].config_key, "plug:surround40:0", _("device used for 4-channel output"), _("xine will use this alsa device to output 4 channel (4.0) surround sound.\n" "See the alsa documentation for information on alsa devices."), 10, _alsa_dev_name_cb, &this->devs[2])); this->devs[3].this = this; this->devs[3].type = _(" 5.1-channel"); this->devs[3].config_key = "audio.device.alsa_surround51_device"; this->devs[3].name = _alsa_safe_strdup (config->register_string (config, this->devs[3].config_key, "plug:surround51:0", _("device used for 5.1-channel output"), _("xine will use this alsa device to output 5 channel plus LFE (5.1) surround sound.\n" "See the alsa documentation for information on alsa devices."), 10, _alsa_dev_name_cb, &this->devs[3])); this->devs[4].this = this; this->devs[4].type = _(" a/52 and DTS pass-through"); this->devs[4].config_key = "audio.device.alsa_passthrough_device"; this->devs[4].name = _alsa_safe_strdup (config->register_string (config, this->devs[4].config_key, "iec958:AES0=0x6,AES1=0x82,AES2=0x0,AES3=0x2", _("device used for a/52 and DTS pass-through"), _("xine will use this alsa device to output undecoded digital surround sound. " "This can be used be external surround decoders.\n" "See the alsa documentation for information on alsa devices."), 10, _alsa_dev_name_cb, &this->devs[4])); { int err = snd_lib_error_set_handler (error_callback); if (err < 0) xine_log (this->class->xine, XINE_LOG_MSG, _("snd_lib_error_set_handler() failed: %d"), err); } { AUDIO_DEVICE_SPEAKER_ARRANGEMENT_TYPES; int speakers; /* for usability reasons, keep this in sync with audio_oss_out.c */ speakers = config->register_enum (config, "audio.output.speaker_arrangement", STEREO, (char **)speaker_arrangement, AUDIO_DEVICE_SPEAKER_ARRANGEMENT_HELP, 0, _alsa_speaker_arrangement_cb, this); /* query the devices we might need, and stop at stereo. */ switch (speakers) { case A52_PASSTHRU: if (_alsa_query_dev (this, 4)) this->capabilities |= this->devs[4].capabilities; /* fall through */ case SURROUND71: case SURROUND61: case SURROUND6: case SURROUND51: case SURROUND5: case SURROUND41: if (_alsa_query_dev (this, 3)) { this->capabilities |= this->devs[3].capabilities; break; } /* fall through */ case SURROUND4: if (_alsa_query_dev (this, 2)) this->capabilities |= this->devs[2].capabilities; break; default: ; } if (_alsa_query_dev (this, 0)) this->capabilities |= this->devs[0].capabilities; if (_alsa_query_dev (this, 1)) { this->capabilities |= this->devs[1].capabilities; } else { /* Fallback to "default" if device "front" does not exist. * Needed for some very basic sound cards. */ config->update_string (config, this->devs[1].config_key, "default"); if (_alsa_query_dev (this, 1)) this->capabilities |= this->devs[1].capabilities; } alsa_apply_speaker_arrangement (this, speakers); } do { /* printf("audio_alsa_out: capabilities 0x%X\n",this->capabilities); */ if (!this->capabilities) break; config->register_string (config, "audio.device.alsa_mixer_name", "PCM", _("alsa mixer device"), _("xine will use this alsa mixer device to change the volume.\n" "See the alsa documentation for information on alsa devices."), 10, NULL, NULL); this->mixer.name = config->lookup_string(config, "audio.device.alsa_mixer_name"); if (!this->mixer.name) break; pthread_mutex_init (&this->mixer.mutex, NULL); ao_alsa_mixer_init (&this->ao_driver); this->ao_driver.get_capabilities = ao_alsa_get_capabilities; this->ao_driver.get_property = ao_alsa_get_property; this->ao_driver.set_property = ao_alsa_set_property; this->ao_driver.open = ao_alsa_open; this->ao_driver.num_channels = ao_alsa_num_channels; this->ao_driver.bytes_per_frame = ao_alsa_bytes_per_frame; this->ao_driver.delay = ao_alsa_delay; this->ao_driver.write = ao_alsa_write; this->ao_driver.close = ao_alsa_close; this->ao_driver.exit = ao_alsa_exit; this->ao_driver.get_gap_tolerance = ao_alsa_get_gap_tolerance; this->ao_driver.control = ao_alsa_ctrl; return &this->ao_driver; } while (0); config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); { uint32_t u; for (u = 0; u < sizeof (this->devs) / sizeof (this->devs[0]); u++) { _x_freep (&this->devs[u].name); } } free (this); return NULL; } /* * class functions */ static void *init_class (xine_t *xine, const void *data) { alsa_class_t *this; (void)data; this = calloc(1, sizeof (alsa_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "alsa"; this->driver_class.description = N_("xine audio output plugin using alsa-compliant audio devices/drivers"); this->driver_class.dispose = default_audio_driver_class_dispose; /* this->config = xine->config; */ this->xine = xine; return this; } static ao_info_t ao_info_alsa = { .priority = 10, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_ALSA_IFACE_VERSION, "alsa", XINE_VERSION_CODE, &ao_info_alsa, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_esd_out.c����������������������������������������������������������0000644�0001750�0001750�00000040041�14647725152�016431� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <esd.h> #include <signal.h> #include <sys/time.h> #include <sys/uio.h> #include <inttypes.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include <xine/metronom.h> #define AO_OUT_ESD_IFACE_VERSION 9 #define REBLOCK 1 /* reblock output to ESD_BUF_SIZE blks */ #define GAP_TOLERANCE 5000 typedef struct esd_driver_s { ao_driver_t ao_driver; xine_t *xine; int audio_fd; int capabilities; int mode; char *pname; /* Player name id for esd daemon */ int32_t output_sample_rate, input_sample_rate; int32_t output_sample_k_rate; double sample_rate_factor; uint32_t num_channels; uint32_t bytes_per_frame; uint32_t bytes_in_buffer; /* number of bytes writen to esd */ int gap_tolerance, latency; int server_sample_rate; struct timeval start_time; struct { int source_id; int volume; int mute; } mixer; #if REBLOCK /* * Temporary sample buffer used to reblock the sample output stream * to writes using buffer sizes of n*ESD_BUF_SIZE bytes. * * The reblocking avoids a bug with esd 0.2.18 servers and reduces * cpu load with newer versions of the esd server. * * The esd 0.2.18 version zero fills "partial"/"incomplete" blocks. * esd 0.2.28+ has fixed this problem, by performing a busy polling * loop reading from a nonblocking socket to get the remainder of * the partial block. This is wasting a lot of cpu cycles. */ char reblock_buf[ESD_BUF_SIZE]; int reblock_rem; #endif } esd_driver_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } esd_class_t; /* * connect to esd */ static int ao_esd_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { esd_driver_t *this = (esd_driver_t *) this_gen; esd_format_t format; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_esd_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); if ( (mode & this->capabilities) == 0 ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_esd_out: unsupported mode %08x\n", mode); return 0; } if (this->audio_fd>=0) { if ( (mode == this->mode) && (rate == this->input_sample_rate) ) return this->output_sample_rate; esd_close (this->audio_fd); } this->mode = mode; this->input_sample_rate = rate; this->output_sample_rate = rate; this->bytes_in_buffer = 0; this->start_time.tv_sec = 0; /* * open stream to ESD server */ format = ESD_STREAM | ESD_PLAY | ESD_BITS16; switch (mode) { case AO_CAP_MODE_MONO: format |= ESD_MONO; this->num_channels = 1; break; case AO_CAP_MODE_STEREO: format |= ESD_STEREO; this->num_channels = 2; break; } xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_esd_out: %d channels output\n",this->num_channels); this->bytes_per_frame=(bits*this->num_channels)/8; #if ESD_RESAMPLE /* esd resamples (only for sample rates < the esd server's sample rate) */ if (this->output_sample_rate > this->server_sample_rate) this->output_sample_rate = this->server_sample_rate; #else /* use xine's resample code */ this->output_sample_rate = this->server_sample_rate; #endif this->output_sample_k_rate = this->output_sample_rate / 1000; this->audio_fd = esd_play_stream(format, this->output_sample_rate, NULL, this->pname); if (this->audio_fd < 0) { char *server = getenv("ESPEAKER"); xprintf(this->xine, XINE_VERBOSITY_LOG, _("audio_esd_out: connecting to ESD server %s: %s\n"), server ? server : "<default>", strerror(errno)); return 0; } return this->output_sample_rate; } static int ao_esd_num_channels(ao_driver_t *this_gen) { esd_driver_t *this = (esd_driver_t *) this_gen; return this->num_channels; } static int ao_esd_bytes_per_frame(ao_driver_t *this_gen) { esd_driver_t *this = (esd_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_esd_delay(ao_driver_t *this_gen) { esd_driver_t *this = (esd_driver_t *) this_gen; int bytes_left; int frames; struct timeval tv; if (this->start_time.tv_sec == 0) return 0; gettimeofday(&tv, NULL); frames = (tv.tv_usec - this->start_time.tv_usec) * this->output_sample_k_rate / 1000; frames += (tv.tv_sec - this->start_time.tv_sec) * this->output_sample_rate; frames -= this->latency; if (frames < 0) frames = 0; /* calc delay */ bytes_left = this->bytes_in_buffer - frames * this->bytes_per_frame; if (bytes_left<=0) /* buffer ran dry */ bytes_left = 0; return bytes_left / this->bytes_per_frame; } static int ao_esd_write(ao_driver_t *this_gen, int16_t* frame_buffer, uint32_t num_frames) { esd_driver_t *this = (esd_driver_t *) this_gen; int simulated_bytes_in_buffer, frames ; struct timeval tv; if (this->audio_fd<0) return 1; if (this->start_time.tv_sec == 0) gettimeofday(&this->start_time, NULL); /* check if simulated buffer ran dry */ gettimeofday(&tv, NULL); frames = (tv.tv_usec - this->start_time.tv_usec) * this->output_sample_k_rate / 1000; frames += (tv.tv_sec - this->start_time.tv_sec) * this->output_sample_rate; frames -= this->latency; if (frames < 0) frames = 0; /* calc delay */ simulated_bytes_in_buffer = frames * this->bytes_per_frame; if (this->bytes_in_buffer < simulated_bytes_in_buffer) this->bytes_in_buffer = simulated_bytes_in_buffer; #if REBLOCK { struct iovec iov[2]; int iovcnt; int num_bytes; int nwritten; int rem; if (this->reblock_rem + num_frames*this->bytes_per_frame < ESD_BUF_SIZE) { /* * the stuff in the temporary reblocking buffer plus the new * samples still do not give a complete ESD_BUF_SIZE block. * just save the new samples in the reblocking buffer for later. */ memcpy(this->reblock_buf + this->reblock_rem, frame_buffer, num_frames * this->bytes_per_frame); this->reblock_rem += num_frames * this->bytes_per_frame; return 1; } /* OK, we have at least one complete ESD_BUF_SIZE block */ iovcnt = 0; num_bytes = 0; if (this->reblock_rem > 0) { /* send any saved samples from the reblocking buffer first */ iov[iovcnt].iov_base = this->reblock_buf; iov[iovcnt].iov_len = this->reblock_rem; iovcnt++; num_bytes += this->reblock_rem; this->reblock_rem = 0; } rem = (num_bytes + num_frames * this->bytes_per_frame) % ESD_BUF_SIZE; if (num_frames * this->bytes_per_frame > rem) { /* * add samples from caller, so that the total number of bytes is * a multiple of ESD_BUF_SIZE */ iov[iovcnt].iov_base = frame_buffer; iov[iovcnt].iov_len = num_frames * this->bytes_per_frame - rem; num_bytes += num_frames * this->bytes_per_frame - rem; iovcnt++; } nwritten = writev(this->audio_fd, iov, iovcnt); if (nwritten != num_bytes) { if (nwritten < 0) xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_esd_out: writev failed: %s\n", strerror(errno)); else xprintf(this->xine, XINE_VERBOSITY_DEBUG, "audio_esd_out: warning, incomplete write: %d\n", nwritten); } if (nwritten > 0) this->bytes_in_buffer += nwritten; if (rem > 0) { /* save the remaining bytes for the next ao_esd_write() */ memcpy(this->reblock_buf, (char*)frame_buffer + iov[iovcnt-1].iov_len, rem); this->reblock_rem = rem; } } #else this->bytes_in_buffer += num_frames * this->bytes_per_frame; write(this->audio_fd, frame_buffer, num_frames * this->bytes_per_frame); #endif return 1; } static void ao_esd_close(ao_driver_t *this_gen) { esd_driver_t *this = (esd_driver_t *) this_gen; esd_close(this->audio_fd); this->audio_fd = -1; } static uint32_t ao_esd_get_capabilities (ao_driver_t *this_gen) { esd_driver_t *this = (esd_driver_t *) this_gen; return this->capabilities; } static int ao_esd_get_gap_tolerance (ao_driver_t *this_gen) { /* esd_driver_t *this = (esd_driver_t *) this_gen; */ (void)this_gen; return GAP_TOLERANCE; } static void ao_esd_exit(ao_driver_t *this_gen) { esd_driver_t *this = (esd_driver_t *) this_gen; if (this->audio_fd != -1) esd_close(this->audio_fd); free(this->pname); free (this); } static int ao_esd_get_property (ao_driver_t *this_gen, int property) { esd_driver_t *this = (esd_driver_t *) this_gen; int mixer_fd; esd_player_info_t *esd_pi; esd_info_t *esd_i; switch(property) { case AO_PROP_MIXER_VOL: if((mixer_fd = esd_open_sound(NULL)) >= 0) { if((esd_i = esd_get_all_info(mixer_fd)) != NULL) { for(esd_pi = esd_i->player_list; esd_pi != NULL; esd_pi = esd_pi->next) { if(!strcmp(this->pname, esd_pi->name)) { this->mixer.source_id = esd_pi->source_id; if(!this->mixer.mute) this->mixer.volume = (((esd_pi->left_vol_scale * 100) / 256) + ((esd_pi->right_vol_scale * 100) / 256)) >> 1; } } esd_free_all_info(esd_i); } esd_close(mixer_fd); } return this->mixer.volume; break; case AO_PROP_MUTE_VOL: return this->mixer.mute; break; } return 0; } static int ao_esd_set_property (ao_driver_t *this_gen, int property, int value) { esd_driver_t *this = (esd_driver_t *) this_gen; int mixer_fd; switch(property) { case AO_PROP_MIXER_VOL: if(!this->mixer.mute) { /* need this to get source_id */ (void) ao_esd_get_property(&this->ao_driver, AO_PROP_MIXER_VOL); if((mixer_fd = esd_open_sound(NULL)) >= 0) { int v = (value * 256) / 100; esd_set_stream_pan(mixer_fd, this->mixer.source_id, v, v); if(!this->mixer.mute) this->mixer.volume = value; esd_close(mixer_fd); } } else this->mixer.volume = value; return this->mixer.volume; break; case AO_PROP_MUTE_VOL: { int mute = (value) ? 1 : 0; /* need this to get source_id */ (void) ao_esd_get_property(&this->ao_driver, AO_PROP_MIXER_VOL); if(mute) { if((mixer_fd = esd_open_sound(NULL)) >= 0) { int v = 0; esd_set_stream_pan(mixer_fd, this->mixer.source_id, v, v); esd_close(mixer_fd); } } else { if((mixer_fd = esd_open_sound(NULL)) >= 0) { int v = (this->mixer.volume * 256) / 100; esd_set_stream_pan(mixer_fd, this->mixer.source_id, v, v); esd_close(mixer_fd); } } this->mixer.mute = mute; return value; } break; } return ~value; } static int ao_esd_ctrl(ao_driver_t *this_gen, int cmd, ...) { /* esd_driver_t *this = (esd_driver_t *) this_gen; */ (void)this_gen; (void)cmd; #if 0 switch (cmd) { case AO_CTRL_PLAY_PAUSE: break; case AO_CTRL_PLAY_RESUME: break; case AO_CTRL_FLUSH_BUFFERS: break; } #endif return 0; } static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { esd_class_t *class = (esd_class_t *) class_gen; config_values_t *config = class->xine->config; esd_driver_t *this; int audio_fd; int err; esd_server_info_t *esd_svinfo; int server_sample_rate; sigset_t vo_mask, vo_mask_orig; (void)data; /* * open stream to ESD server * * esd_open_sound needs a working SIGALRM for detecting a failed * attempt to autostart the esd daemon; esd notifies the process that * attempts the esd daemon autostart with a SIGALRM (SIGUSR1) signal * about a failure to open the audio device (successful daemon startup). * * Temporarily release the blocked SIGALRM, while esd_open_sound is active. * (Otherwise xine hangs in esd_open_sound on a machine without sound) */ sigemptyset(&vo_mask); sigaddset(&vo_mask, SIGALRM); if (sigprocmask(SIG_UNBLOCK, &vo_mask, &vo_mask_orig)) xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_esd_out: cannot unblock SIGALRM: %s\n", strerror(errno)); xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_esd_out: connecting to esd server...\n")); audio_fd = esd_open_sound(NULL); err = errno; if (sigprocmask(SIG_SETMASK, &vo_mask_orig, NULL)) xprintf(class->xine, XINE_VERBOSITY_DEBUG, "audio_esd_out: cannot block SIGALRM: %s\n", strerror(errno)); if(audio_fd < 0) { char *server = getenv("ESPEAKER"); /* print a message so the user knows why ESD failed */ xprintf(class->xine, XINE_VERBOSITY_LOG, _("audio_esd_out: can't connect to %s ESD server: %s\n"), server ? server : "<default>", strerror(err)); return NULL; } esd_svinfo = esd_get_server_info(audio_fd); if (esd_svinfo) { server_sample_rate = esd_svinfo->rate; esd_free_server_info(esd_svinfo); } else server_sample_rate = 44100; esd_close(audio_fd); this = calloc(1, sizeof (esd_driver_t)); if (!this) return NULL; this->xine = class->xine; this->pname = strdup("xine esd audio output plugin"); if (!this->pname) { free (this); return NULL; } this->output_sample_rate = 0; this->server_sample_rate = server_sample_rate; this->audio_fd = -1; this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MIXER_VOL | AO_CAP_MUTE_VOL; this->latency = config->register_range (config, "audio.device.esd_latency", 0, -30000, 90000, _("esd audio output latency (adjust a/v sync)"), _("If you experience audio being not in sync " "with the video, you can enter a fixed offset " "here to compensate.\nThe unit of the value " "is one PTS tick, which is the 90000th part " "of a second."), 10, NULL, NULL); this->ao_driver.get_capabilities = ao_esd_get_capabilities; this->ao_driver.get_property = ao_esd_get_property; this->ao_driver.set_property = ao_esd_set_property; this->ao_driver.open = ao_esd_open; this->ao_driver.num_channels = ao_esd_num_channels; this->ao_driver.bytes_per_frame = ao_esd_bytes_per_frame; this->ao_driver.get_gap_tolerance = ao_esd_get_gap_tolerance; this->ao_driver.delay = ao_esd_delay; this->ao_driver.write = ao_esd_write; this->ao_driver.close = ao_esd_close; this->ao_driver.exit = ao_esd_exit; this->ao_driver.control = ao_esd_ctrl; return &(this->ao_driver); } /* * class functions */ static void *init_class (xine_t *xine, const void *data) { esd_class_t *this; (void)data; this = calloc(1, sizeof (esd_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "esd"; this->driver_class.description = N_("xine audio output plugin using esound"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; return this; } static const ao_info_t ao_info_esd = { .priority = 4, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_ESD_IFACE_VERSION, "esd", XINE_VERSION_CODE, &ao_info_esd, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_jack_out.c���������������������������������������������������������0000644�0001750�0001750�00000063031�14647725152�016572� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <inttypes.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include <jack/jack.h> #include "speakers.h" #define AO_OUT_JACK_IFACE_VERSION 9 #define GAP_TOLERANCE AO_MAX_GAP /* maximum number of channels supported, avoids lots of mallocs */ #define MAX_CHANS 6 typedef struct jack_driver_s { ao_driver_t ao_driver; xine_t *xine; int capabilities; int mode; int paused; int underrun; uint32_t output_sample_rate, input_sample_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; uint32_t bytes_in_buffer; /* number of bytes writen to audio hardware */ uint32_t fragment_size; jack_client_t *client; jack_port_t *ports[MAX_CHANS]; /*! buffer for audio data */ unsigned char *buffer; /*! buffer read position, may only be modified by playback thread or while it is stopped */ uint32_t read_pos; /*! buffer write position, may only be modified by MPlayer's thread */ uint32_t write_pos; struct { int volume; int mute; } mixer; } jack_driver_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } jack_class_t; /************************************************************** * * Simple ringbuffer implementation * Lifted from mplayer ao_jack.c * **************************************************************/ /*! size of one chunk, if this is too small Xine will start to "stutter" */ /*! after a short time of playback */ #define CHUNK_SIZE (16 * 1024) /*! number of "virtual" chunks the buffer consists of */ #define NUM_CHUNKS 8 /* This type of ring buffer may never fill up completely, at least */ /* one byte must always be unused. */ /* For performance reasons (alignment etc.) one whole chunk always stays */ /* empty, not only one byte. */ #define BUFFSIZE ((NUM_CHUNKS + 1) * CHUNK_SIZE) /** * \brief get the number of free bytes in the buffer * \return number of free bytes in buffer * * may only be called by Xine's thread * return value may change between immediately following two calls, * and the real number of free bytes might be larger! */ static int buf_free (jack_driver_t *this) { int free = this->read_pos - this->write_pos - CHUNK_SIZE; if (free < 0) free += BUFFSIZE; return free; } /** * \brief get amount of data available in the buffer * \return number of bytes available in buffer * * may only be called by the playback thread * return value may change between immediately following two calls, * and the real number of buffered bytes might be larger! */ static int buf_used (jack_driver_t *this) { int used = this->write_pos - this->read_pos; if (used < 0) used += BUFFSIZE; return used; } /** * \brief insert len bytes into buffer * \param data data to insert * \param len length of data * \return number of bytes inserted into buffer * * If there is not enough room, the buffer is filled up * * TODO: Xine should really pass data as float, perhaps in V1.2? */ static int write_buffer_32 (jack_driver_t *this, unsigned char *data, int len) { int first_len = BUFFSIZE - this->write_pos; int free = buf_free (this); if (len > free) len = free; if (first_len > len) first_len = len; /* copy from current write_pos to end of buffer */ memcpy (&(this->buffer[this->write_pos]), data, first_len); if (len > first_len) { /* we have to wrap around */ /* remaining part from beginning of buffer */ memcpy (this->buffer, &data[first_len], len - first_len); } this->write_pos = (this->write_pos + len) % BUFFSIZE; return len; } static int write_buffer_16 (jack_driver_t *this, unsigned char *data, int len) { int samples_free = buf_free (this) / (sizeof (float)); int samples = len / 2; if (samples > samples_free) samples = samples_free; /* Rename some pointers so that the next bit of gymnastics is easier to read */ uint32_t write_pos = this->write_pos; float *p_write; int16_t *p_read = (int16_t *) data; int i; for (i = 0; i < samples; i++) { /* Read in 16bits, write out floats */ p_write = (float *) (&(this->buffer[write_pos])); *p_write = ((float) (p_read[i])) / 32768.0f; write_pos = (write_pos + sizeof (float)) % BUFFSIZE; } this->write_pos = write_pos; return samples * 2; } /** * \brief read data from buffer and splitting it into channels * \param bufs num_bufs float buffers, each will contain the data of one channel * \param cnt number of samples to read per channel * \param num_bufs number of channels to split the data into * \return number of samples read per channel, equals cnt unless there was too * little data in the buffer * * Assumes the data in the buffer is of type float, the number of bytes * read is res * num_bufs * sizeof(float), where res is the return value. * If there is not enough data in the buffer remaining parts will be filled * with silence. */ static jack_nframes_t read_buffer (jack_driver_t *this, float **bufs, jack_nframes_t cnt, unsigned num_bufs, float gain) { int buffered = buf_used (this); unsigned j; jack_nframes_t i, orig_cnt = cnt; if (cnt * num_bufs > buffered / sizeof(float)) cnt = buffered / (sizeof (float) * num_bufs); uint32_t read_pos = this->read_pos; unsigned char *buffer = this->buffer; for (i = 0; i < cnt; i++) { for (j = 0; j < num_bufs; j++) { bufs[j][i] = *((float *) (&(buffer[read_pos]))) * gain; read_pos = (read_pos + sizeof (float)) % BUFFSIZE; } } this->read_pos = read_pos; for (i = cnt; i < orig_cnt; i++) for (j = 0; j < num_bufs; j++) bufs[j][i] = 0; return cnt; } /** * \brief fill the buffers with silence * \param bufs num_bufs float buffers, each will contain the data of one channel * \param cnt number of samples in each buffer * \param num_bufs number of buffers */ static void silence (float **bufs, int cnt, int num_bufs) { int i, j; for (i = 0; i < cnt; i++) for (j = 0; j < num_bufs; j++) bufs[j][i] = 0; } /************************************************************** * * Jack interface functions * **************************************************************/ /** * \brief stop playing and empty buffers (for seeking/pause) */ static void jack_reset (jack_driver_t *this) { this->paused = 1; this->read_pos = this->write_pos = 0; this->paused = 0; } static int jack_callback (jack_nframes_t nframes, void *arg) { jack_driver_t *this = (jack_driver_t *) arg; if (!this->client) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_callback: called without a client parameter? silently trying to continue...\n"); return 0; } float gain = 0; if (!this->mixer.mute) { gain = (float) this->mixer.volume / 100.0; gain *= gain; /* experiment with increasing volume range */ } float *bufs[MAX_CHANS]; unsigned i; for (i = 0; i < this->num_channels; i++) bufs[i] = jack_port_get_buffer (this->ports[i], nframes); if (this->paused || this->underrun) { silence (bufs, nframes, this->num_channels); } else { jack_nframes_t frames_read = read_buffer (this, bufs, nframes, this->num_channels, gain); if (frames_read < nframes) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_callback: underrun - frames read: %d\n", frames_read); this->underrun = 1; } } return 0; } #if 0 static void jack_shutdown (void *arg) { jack_driver_t *this = (jack_driver_t *) arg; this->client = NULL; } #endif /* * Open the Jack audio device * Return 1 on success, 0 on failure * All error handling rests with the caller, we just try to open the device here */ static int jack_open_device (jack_driver_t *this, const char *jack_device, uint32_t *poutput_sample_rate, int num_channels) { const char **matching_ports = NULL; jack_client_t *client = this->client; int port_flags = JackPortIsInput; int i; int num_ports; if (num_channels > MAX_CHANS) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_open_device: Invalid number of channels: %i\n", num_channels); goto err_out; } /* Try to create a client called "xine[-NN]" */ if ((client = jack_client_open ("xine", JackNullOption, NULL)) == 0) { xprintf (this->xine, XINE_VERBOSITY_LOG, "\njack_open_device: Error: Failed to connect to JACK server\n"); goto err_out; } /* Save the new client */ this->client = client; jack_reset (this); jack_set_process_callback (client, jack_callback, this); /* list matching ports */ if (!jack_device) port_flags |= JackPortIsPhysical; matching_ports = jack_get_ports (client, jack_device, NULL, port_flags); for (num_ports = 0; matching_ports && matching_ports[num_ports]; num_ports++); if (!num_ports) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_open_device: no physical ports available\n"); goto err_out; } if (num_ports < num_channels) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_open_device: not enough physical ports available\n"); goto err_out; } /* create output ports */ for (i = 0; i < num_channels; i++) { char pname[50]; snprintf (pname, 50, "out_%d", i); this->ports[i] = jack_port_register (client, pname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (!this->ports[i]) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_open_device: could not create output ports? Why not?\n"); goto err_out; } } if (jack_activate (client)) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_open_device: jack_activate() failed\n"); goto err_out; } for (i = 0; i < num_channels; i++) { if (jack_connect (client, jack_port_name (this->ports[i]), matching_ports[i])) { xprintf (this->xine, XINE_VERBOSITY_LOG, "jack_open_device: jack_connect() failed\n"); goto err_out; } } *poutput_sample_rate = jack_get_sample_rate (client); free (matching_ports); return 1; err_out: free (matching_ports); if (client) { jack_client_close (client); this->client = NULL; } return 0; } /************************************************************** * * Xine interface functions * **************************************************************/ /** * close the device and reset the play position */ static void ao_jack_close (ao_driver_t *this_gen) { jack_driver_t *this = (jack_driver_t *) this_gen; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_close: closing\n"); jack_reset (this); if (this->client) { jack_client_close (this->client); this->client = NULL; } } /* * open the audio device for writing to */ static int ao_jack_open_int (jack_driver_t *this, const char *jack_device, uint32_t bits, uint32_t rate, int mode) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_open: ao_open rate=%d, mode=%d, bits=%d dev=%s\n", rate, mode, bits, jack_device); if ((bits != 16) && (bits != 32)) { xprintf (this->xine, XINE_VERBOSITY_LOG, "ao_jack_open: bits=%u expected 16 or 32bit only\n", bits); return 0; } if ((mode & this->capabilities) == 0) { xprintf (this->xine, XINE_VERBOSITY_LOG, "ao_jack_open: unsupported mode %08x\n", mode); return 0; } /* If device open already then either re-use it or close it */ if (this->client) { if ((mode == this->mode) && (rate == this->input_sample_rate)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_open: device already open, reusing it\n"); return this->output_sample_rate; } ao_jack_close (&this->ao_driver); } this->mode = mode; this->input_sample_rate = rate; this->bits_per_sample = bits; this->bytes_in_buffer = 0; this->read_pos = this->write_pos = 0; this->paused = 0; this->underrun = 0; /* * set number of channels / a52 passthrough */ switch (mode) { case AO_CAP_MODE_MONO: this->num_channels = 1; break; case AO_CAP_MODE_STEREO: this->num_channels = 2; break; case AO_CAP_MODE_4CHANNEL: this->num_channels = 4; break; case AO_CAP_MODE_4_1CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: this->num_channels = 6; break; case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: /* FIXME: Is this correct...? */ this->num_channels = 2; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_open: AO_CAP_MODE_A52\n"); break; default: xprintf (this->xine, XINE_VERBOSITY_LOG, "ao_jack_open: JACK Driver does not support the requested mode: 0x%X\n", mode); return 0; } xprintf (this->xine, XINE_VERBOSITY_LOG, "ao_jack_open: %d channels output\n", this->num_channels); this->bytes_per_frame = (this->bits_per_sample * this->num_channels) / 8; /* * open audio device */ if (!jack_open_device (this, jack_device, &(this->output_sample_rate), this->num_channels)) return 0; if (this->input_sample_rate != this->output_sample_rate) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_open: audio rate : %d requested, %d provided by device\n", this->input_sample_rate, this->output_sample_rate); } return this->output_sample_rate; } static int ao_jack_open (ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { jack_driver_t *this = (jack_driver_t *) this_gen; char *jack_device; int result; jack_device = xine_config_lookup_string(this->xine, "audio.device.jack_device_name"); if (!jack_device) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_open: no audio.device.jack_device_name in config\n"); /* not fatal - this is tested later */ } result = ao_jack_open_int(this, jack_device, bits, rate, mode); xine_config_free_string(this->xine, &jack_device); return result; } static int ao_jack_num_channels (ao_driver_t *this_gen) { jack_driver_t *this = (jack_driver_t *) this_gen; return this->num_channels; } static int ao_jack_bytes_per_frame (ao_driver_t *this_gen) { jack_driver_t *this = (jack_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_jack_get_gap_tolerance (ao_driver_t *this_gen) { (void)this_gen; return GAP_TOLERANCE; } /* * Return the number of outstanding frames in all output buffers * need to account for ring buffer plus Jack, plus soundcard */ static int ao_jack_delay (ao_driver_t *this_gen) { jack_driver_t *this = (jack_driver_t *) this_gen; int frames_played = jack_frames_since_cycle_start (this->client); int delay = 0; /* Ring Buffer always stores floats */ /* TODO: Unsure if the delay should be fragment_size*2 or *3? */ delay = buf_used (this) / (sizeof (float) * this->num_channels) + this->fragment_size * 3 - frames_played; return delay; } /* Write audio samples * num_frames is the number of audio frames present * audio frames are equivalent one sample on each channel. * I.E. Stereo 16 bits audio frames are 4 bytes. * MUST SIMULATE BLOCKING WRITES */ static int ao_jack_write (ao_driver_t *this_gen, int16_t *frame_buffer, uint32_t num_frames) { jack_driver_t *this = (jack_driver_t *) this_gen; int written = 0; int num_bytes = num_frames * this->bytes_per_frame; /* First try and write all the bytes in one go */ this->underrun = 0; /* TODO: In the future Xine should pass only floats to us, so no conversion needed */ if (this->bits_per_sample == 16) written = write_buffer_16 (this, (unsigned char *) frame_buffer, num_bytes); else if (this->bits_per_sample == 32) written = write_buffer_32 (this, (unsigned char *) frame_buffer, num_bytes); /* If this fails then need to spin and keep trying until everything written */ int spin_count = 0; while ((written < num_bytes) && (spin_count < 40)) { num_bytes -= written; frame_buffer += written / 2; /* Sleep to save CPU */ int until_callback = this->fragment_size - jack_frames_since_cycle_start (this->client); if ((until_callback < 0) || ((unsigned)until_callback > this->fragment_size)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_write: Invalid until_callback %d\n", until_callback); until_callback = this->fragment_size; } xine_usec_sleep (((until_callback + 100) * 1000.0 * 1000.0) / this->output_sample_rate); if (this->bits_per_sample == 16) written = write_buffer_16 (this, (unsigned char *) frame_buffer, num_bytes); else if (this->bits_per_sample == 32) written = write_buffer_32 (this, (unsigned char *) frame_buffer, num_bytes); if (written == 0) spin_count++; else spin_count = 0; if (written == 0) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "ao_jack_write: unusual, couldn't write anything\n"); }; if (spin_count) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "Nonzero spin_count...%d\n", spin_count); return spin_count ? 0 : 1; /* return 1 on success, 0 if we got stuck for some reason */ } static uint32_t ao_jack_get_capabilities (ao_driver_t *this_gen) { jack_driver_t *this = (jack_driver_t *) this_gen; return this->capabilities; } static void ao_jack_exit (ao_driver_t *this_gen) { jack_driver_t *this = (jack_driver_t *) this_gen; this->xine->config->unregister_callbacks (this->xine->config, "audio.output.speaker_arrangement", NULL, this, sizeof (*this)); ao_jack_close (this_gen); if (this->buffer) free (this->buffer); free (this); } static int ao_jack_get_property (ao_driver_t *this_gen, int property) { jack_driver_t *this = (jack_driver_t *) this_gen; switch (property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: return this->mixer.volume; break; case AO_PROP_MUTE_VOL: return this->mixer.mute; break; } return 0; } static int ao_jack_set_property (ao_driver_t *this_gen, int property, int value) { jack_driver_t *this = (jack_driver_t *) this_gen; switch (property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: this->mixer.volume = value; return value; break; case AO_PROP_MUTE_VOL: this->mixer.mute = value; return value; break; } return -1; } static int ao_jack_ctrl (ao_driver_t *this_gen, int cmd, ...) { jack_driver_t *this = (jack_driver_t *) this_gen; switch (cmd) { case AO_CTRL_PLAY_PAUSE: this->paused = 1; break; case AO_CTRL_PLAY_RESUME: this->paused = 0; break; case AO_CTRL_FLUSH_BUFFERS: jack_reset (this); break; } return 0; } static void jack_speaker_arrangement_cb (void *user_data, xine_cfg_entry_t *entry); static ao_driver_t *open_jack_plugin (audio_driver_class_t *class_gen, const void *data) { jack_class_t *class = (jack_class_t *) class_gen; config_values_t *config = class->xine->config; jack_driver_t *this; jack_client_t *client; uint32_t rate; char *jack_device; const char **matching_ports = NULL; (void)data; AUDIO_DEVICE_SPEAKER_ARRANGEMENT_TYPES; int speakers; /* Try to create a client called "xine[-NN]" */ if ((client = jack_client_open ("xine", JackNullOption, NULL)) == 0) { xprintf (class->xine, XINE_VERBOSITY_LOG, "\nopen_jack_plugin: Error: Failed to connect to JACK server\n"); return 0; } this = calloc(1, sizeof (jack_driver_t)); if (!this) goto err_out; rate = jack_get_sample_rate (client); xprintf (class->xine, XINE_VERBOSITY_DEBUG, "open_jack_plugin: JACK sample rate is %u\n", rate); /* devname_val is offset used to select auto, /dev/dsp, or /dev/sound/dsp */ jack_device = config->register_string (config, "audio.device.jack_device_name", "", _("JACK audio device name"), _("Specifies the jack audio device name, " "leave blank for the default physical output port."), 10, NULL, NULL); this->capabilities = 0; /* for usability reasons, keep this in sync with audio_alsa_out.c */ speakers = config->register_enum (config, "audio.output.speaker_arrangement", STEREO, (char **)speaker_arrangement, AUDIO_DEVICE_SPEAKER_ARRANGEMENT_HELP, 0, jack_speaker_arrangement_cb, this); int port_flags = JackPortIsInput; int num_ports; /* list matching ports */ if (!jack_device) port_flags |= JackPortIsPhysical; /* Find all the ports matching either the desired device regexp or physical output ports */ matching_ports = jack_get_ports (client, jack_device, NULL, port_flags); /* Count 'em */ for (num_ports = 0; matching_ports && matching_ports[num_ports]; num_ports++) /**/; if (!num_ports) { xprintf (this->xine, XINE_VERBOSITY_LOG, "open_jack_plugin: no physical ports available\n"); goto err_out; } /* TODO: We deliberately don't offer mono, let Xine upsample instead? */ /* if (num_ports >= 1) { */ /* this->capabilities |= AO_CAP_MODE_MONO; */ /* xprintf(class->xine, XINE_VERBOSITY_DEBUG, "mono "); */ /* } */ if (num_ports >= 2) { this->capabilities |= AO_CAP_MODE_STEREO; xprintf (class->xine, XINE_VERBOSITY_DEBUG, "stereo "); } if (num_ports >= 4) { if (speakers == SURROUND4) { this->capabilities |= AO_CAP_MODE_4CHANNEL; xprintf (class->xine, XINE_VERBOSITY_DEBUG, "4-channel "); } else xprintf (class->xine, XINE_VERBOSITY_DEBUG, "(4-channel not enabled in xine config) "); } if (num_ports >= 5) { if (speakers == SURROUND5) { this->capabilities |= AO_CAP_MODE_5CHANNEL; xprintf (class->xine, XINE_VERBOSITY_DEBUG, "5-channel "); } else xprintf (class->xine, XINE_VERBOSITY_DEBUG, "(5-channel not enabled in xine config) "); } if (num_ports >= 6) { if (speakers == SURROUND51) { this->capabilities |= AO_CAP_MODE_5_1CHANNEL; xprintf (class->xine, XINE_VERBOSITY_DEBUG, "5.1-channel "); } else xprintf (class->xine, XINE_VERBOSITY_DEBUG, "(5.1-channel not enabled in xine config) "); } this->buffer = (unsigned char *) malloc (BUFFSIZE); jack_reset (this); this->capabilities |= AO_CAP_MIXER_VOL; this->capabilities |= AO_CAP_MUTE_VOL; /* TODO: Currently not respected by Xine, perhaps v1.2? */ this->capabilities |= AO_CAP_FLOAT32; this->mixer.mute = 0; this->mixer.volume = 100; this->output_sample_rate = jack_get_sample_rate (client); this->fragment_size = jack_get_buffer_size (client); /* Close our JACK client */ jack_client_close (client); this->xine = class->xine; this->ao_driver.get_capabilities = ao_jack_get_capabilities; this->ao_driver.get_property = ao_jack_get_property; this->ao_driver.set_property = ao_jack_set_property; this->ao_driver.open = ao_jack_open; this->ao_driver.num_channels = ao_jack_num_channels; this->ao_driver.bytes_per_frame = ao_jack_bytes_per_frame; this->ao_driver.delay = ao_jack_delay; this->ao_driver.write = ao_jack_write; this->ao_driver.close = ao_jack_close; this->ao_driver.exit = ao_jack_exit; this->ao_driver.get_gap_tolerance = ao_jack_get_gap_tolerance; this->ao_driver.control = ao_jack_ctrl; return &this->ao_driver; err_out: free (matching_ports); if (client) jack_client_close (client); return 0; } static void jack_speaker_arrangement_cb (void *user_data, xine_cfg_entry_t *entry) { jack_driver_t *this = (jack_driver_t *) user_data; int32_t value = entry->num_value; if (value == SURROUND4) { this->capabilities |= AO_CAP_MODE_4CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_4CHANNEL; } if (value == SURROUND41) { this->capabilities |= AO_CAP_MODE_4_1CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_4_1CHANNEL; } if (value == SURROUND5) { this->capabilities |= AO_CAP_MODE_5CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_5CHANNEL; } if (value >= SURROUND51) { this->capabilities |= AO_CAP_MODE_5_1CHANNEL; } else { this->capabilities &= ~AO_CAP_MODE_5_1CHANNEL; } } /* * class functions */ static void *init_class (xine_t *xine, const void *data) { jack_class_t *this; (void)data; this = calloc(1, sizeof (jack_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_jack_plugin; this->driver_class.identifier = "jack"; this->driver_class.description = N_("xine output plugin for JACK Audio Connection Kit"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; fprintf(stderr, "jack init_class returning %p\n", (void *)this); return this; } static ao_info_t ao_info_jack = { .priority = 6, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_JACK_IFACE_VERSION, "jack", XINE_VERSION_CODE /* XINE_VERSION_CODE */, &ao_info_jack, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_opensles_out.c�����������������������������������������������������0000644�0001750�0001750�00000042251�14647725152�017513� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * Copyright (C) 2021 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Audio output plugin for OpenSL ES */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <string.h> #include <stdlib.h> #include <dlfcn.h> #include <math.h> #define LOG_MODULE "audio_opensles_out" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include <SLES/OpenSLES.h> #ifdef HAVE_SLES_OPENSLES_ANDROID_H # include <SLES/OpenSLES_Android.h> #endif #define AO_OUT_OPENSLES_IFACE_VERSION 9 #define OPENSLES_BUFFERS 250 /* max buffers, 10 ms each -> 2.5 seconds */ typedef struct opensles_driver_s { ao_driver_t ao_driver; xine_t *xine; int32_t sample_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; /* libOpenSLES.so */ void *hlib; SLInterfaceID SL_IID_myBUFFERQUEUE; SLInterfaceID SL_IID_VOLUME; SLInterfaceID SL_IID_PLAY; /* OpenSL ES objects */ SLObjectItf engine_object; SLObjectItf output_mix_object; SLObjectItf player_object; /* OpenSL ES interfaces */ SLEngineItf engine_if; SLPlayItf player_if; SLVolumeItf volume_if; #ifdef HAVE_SLES_OPENSLES_ANDROID_H SLAndroidSimpleBufferQueueItf buffer_if; #else SLBufferQueueItf buffer_if; #endif /* queue */ uint8_t *buf; /* playback buffer */ size_t buf_elem_size; /* size of single buffer chunk (10 ms) */ size_t next_buf; /* next free buffer */ size_t buf_size; /* bytes filled in next_buf (partial buffer) */ } opensles_driver_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } opensles_class_t; #define CHECK_OPENSL_RESULT(errmsg, erraction) \ do { \ if (result != SL_RESULT_SUCCESS) { \ xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " \ errmsg ": %" PRIu32 "\n", result); \ erraction ; \ } \ } while (0) static int _opensles_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { opensles_driver_t *this = (opensles_driver_t *) this_gen; SLresult result; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); this->sample_rate = rate; this->bits_per_sample = bits; switch (mode) { case AO_CAP_MODE_MONO: this->num_channels = 1; break; case AO_CAP_MODE_STEREO: this->num_channels = 2; break; default: xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unsupported mode 0x%X\n", mode); return 0; } if (bits != 16) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unsupported bits per sample %d\n", bits); return 0; } this->bytes_per_frame = (bits * this->num_channels) / 8; /* create audio player */ { #ifdef HAVE_SLES_OPENSLES_ANDROID_H SLDataLocator_AndroidSimpleBufferQueue loc_bufqueue = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, OPENSLES_BUFFERS }; #else SLDataLocator_BufferQueue loc_bufqueue = { SL_DATALOCATOR_BUFFERQUEUE, OPENSLES_BUFFERS }; #endif SLDataFormat_PCM format = { .formatType = SL_DATAFORMAT_PCM, .numChannels = this->num_channels, .samplesPerSec = rate * 1000, .bitsPerSample = SL_PCMSAMPLEFORMAT_FIXED_16, .containerSize = SL_PCMSAMPLEFORMAT_FIXED_16, .channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, .endianness = SL_BYTEORDER_LITTLEENDIAN, }; SLDataSource audio_src = { &loc_bufqueue, &format }; SLDataLocator_OutputMix loc_outputmix = { SL_DATALOCATOR_OUTPUTMIX, this->output_mix_object }; SLDataSink audio_sink = { &loc_outputmix, NULL}; SLInterfaceID if_ids[] = { this->SL_IID_myBUFFERQUEUE, this->SL_IID_VOLUME }; SLboolean if_req[] = { SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE }; result = (*(this->engine_if))->CreateAudioPlayer(this->engine_if, &this->player_object, &audio_src, &audio_sink, sizeof(if_ids) / sizeof(if_ids[0]), if_ids, if_req); CHECK_OPENSL_RESULT("error creating player", return 0); } result = (*(this->player_object))->Realize(this->player_object, SL_BOOLEAN_FALSE); CHECK_OPENSL_RESULT("error realizing player", goto fail); result = (*(this->player_object))->GetInterface(this->player_object, this->SL_IID_PLAY, &this->player_if); CHECK_OPENSL_RESULT("error getting player interface", goto fail); result = (*(this->player_object))->GetInterface(this->player_object, this->SL_IID_VOLUME, &this->volume_if); CHECK_OPENSL_RESULT("error getting volume interface", goto fail); result = (*(this->player_object))->GetInterface(this->player_object, this->SL_IID_myBUFFERQUEUE, &this->buffer_if); CHECK_OPENSL_RESULT("error getting buffer interface", goto fail); result = (*(this->player_if))->SetPlayState(this->player_if, SL_PLAYSTATE_PLAYING); CHECK_OPENSL_RESULT("error setting playing state", goto fail); /* initialize buffer */ this->buf_elem_size = this->bytes_per_frame * this->sample_rate / 100; this->buf_size = 0; this->next_buf = 0; free(this->buf); this->buf = malloc(this->buf_elem_size * OPENSLES_BUFFERS); if (!this->buf) goto fail; return this->sample_rate; fail: this_gen->close(this_gen); return 0; } static int _opensles_num_channels(ao_driver_t *this_gen) { opensles_driver_t *this = (opensles_driver_t *)this_gen; return this->num_channels; } static int _opensles_bytes_per_frame(ao_driver_t *this_gen) { opensles_driver_t *this = (opensles_driver_t *)this_gen; return this->bytes_per_frame; } static int _opensles_get_gap_tolerance (ao_driver_t *this_gen) { (void)this_gen; return AO_MAX_GAP; } static int _opensles_write(ao_driver_t *this_gen, int16_t *data, uint32_t num_frames) { opensles_driver_t *this = (opensles_driver_t *)this_gen; SLresult result; size_t need_bufs = (num_frames * this->bytes_per_frame + this->buf_elem_size - 1) / this->buf_elem_size; /* wait until we have enough free buffers */ while (1) { #ifdef HAVE_SLES_OPENSLES_ANDROID_H SLAndroidSimpleBufferQueueState st; #else SLBufferQueueState st; #endif result = (*(this->buffer_if))->GetState(this->buffer_if, &st); CHECK_OPENSL_RESULT("error querying buffer state", return -1); if (st.count < OPENSLES_BUFFERS - 1 - need_bufs) break; xine_usec_sleep(10000); } /* copy to buffers and queue (full) buffers */ while (num_frames > 0) { uint8_t *buf = this->buf + this->next_buf * this->buf_elem_size; size_t room = this->buf_elem_size - this->buf_size; if (room > num_frames * this->bytes_per_frame) { /* partial buffer, save data and return */ memcpy(buf + this->buf_size, data, num_frames * this->bytes_per_frame); this->buf_size += num_frames * this->bytes_per_frame; return 1; } memcpy(buf + this->buf_size, data, room); result = (*(this->buffer_if))->Enqueue(this->buffer_if, buf, this->buf_elem_size); CHECK_OPENSL_RESULT("enque failed", (void)result ); data += room * sizeof(uint16_t) / this->bytes_per_frame; num_frames -= room / this->bytes_per_frame; this->buf_size = 0; if (++this->next_buf >= OPENSLES_BUFFERS) this->next_buf = 0; } return 1; } static int _opensles_delay (ao_driver_t *this_gen) { opensles_driver_t *this = (opensles_driver_t *)this_gen; #ifdef HAVE_SLES_OPENSLES_ANDROID_H SLAndroidSimpleBufferQueueState st; #else SLBufferQueueState st; #endif SLresult result; if (!this->buffer_if) return -1; result = (*(this->buffer_if))->GetState(this->buffer_if, &st); CHECK_OPENSL_RESULT("error querying buffer state", return -1); lprintf("latency %u frames\n", st.count * this->buf_elem_size / this->bytes_per_frame); return st.count * this->buf_elem_size / this->bytes_per_frame; } static void _opensles_close(ao_driver_t *this_gen) { opensles_driver_t *this = (opensles_driver_t *)this_gen; if (this->player_if) { (*(this->player_if))->SetPlayState(this->player_if, SL_PLAYSTATE_STOPPED); } if (this->buffer_if) { (*(this->buffer_if))->Clear(this->buffer_if); } if (this->player_object) { (*(this->player_object))->Destroy(this->player_object); } this->player_object = NULL; this->buffer_if = NULL; this->volume_if = NULL; this->player_if = NULL; _x_freep(&this->buf); } static uint32_t _opensles_get_capabilities (ao_driver_t *this_gen) { (void)this_gen; return AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_16BITS | AO_CAP_MIXER_VOL | AO_CAP_MUTE_VOL; } static void _opensles_exit(ao_driver_t *this_gen) { opensles_driver_t *this = (opensles_driver_t *)this_gen; _opensles_close(this_gen); if (this->output_mix_object) (*(this->output_mix_object))->Destroy(this->output_mix_object); if (this->engine_object) (*(this->engine_object))->Destroy(this->engine_object); if (this->hlib) { dlclose(this->hlib); this->hlib = NULL; } free (this); } static int _opensles_get_property (ao_driver_t *this_gen, int property) { opensles_driver_t *this = (opensles_driver_t *)this_gen; SLresult result; SLboolean b; SLmillibel millibels; if (!this->volume_if) return -1; switch (property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: result = (*(this->volume_if))->GetVolumeLevel(this->volume_if, &millibels); CHECK_OPENSL_RESULT("error getting volume level", return -1); return lroundf(100.0 * expf(millibels * logf(10.0) / 2000.0)); break; case AO_PROP_MUTE_VOL: result = (*(this->volume_if))->GetMute(this->volume_if, &b); CHECK_OPENSL_RESULT("error getting mute state", return -1); return !!b; } return 0; } static int _opensles_set_property (ao_driver_t *this_gen, int property, int value) { opensles_driver_t *this = (opensles_driver_t *)this_gen; SLresult result; SLmillibel millibels; if (!this->volume_if) return -1; switch (property) { case AO_PROP_PCM_VOL: case AO_PROP_MIXER_VOL: millibels = lroundf(2000.0 * log10f( (value < 0 ? 0 : value) / 100.0)); if (millibels < SL_MILLIBEL_MIN) millibels = SL_MILLIBEL_MIN; else if (millibels > 0) millibels = 0; result = (*(this->volume_if))->SetVolumeLevel(this->volume_if, millibels); CHECK_OPENSL_RESULT("error setting volume level", return -1); return value; case AO_PROP_MUTE_VOL: result = (*(this->volume_if))->SetMute(this->volume_if, !!value); CHECK_OPENSL_RESULT("error setting mute state", return -1); return value; } return -1; } static int _opensles_ctrl(ao_driver_t *this_gen, int cmd, ...) { opensles_driver_t *this = (opensles_driver_t *)this_gen; SLresult result; switch (cmd) { case AO_CTRL_PLAY_PAUSE: if (this->player_if) { result = (*(this->player_if))->SetPlayState(this->player_if, SL_PLAYSTATE_PAUSED); CHECK_OPENSL_RESULT("failed pausing playback", return -1); } break; case AO_CTRL_PLAY_RESUME: if (this->player_if) { result = (*(this->player_if))->SetPlayState(this->player_if, SL_PLAYSTATE_PLAYING); CHECK_OPENSL_RESULT("failed resuming playback", return -1); } break; case AO_CTRL_FLUSH_BUFFERS: if (this->player_if) { (*(this->player_if))->SetPlayState(this->player_if, SL_PLAYSTATE_STOPPED); (*(this->buffer_if))->Clear(this->buffer_if); (*(this->player_if))->SetPlayState(this->player_if, SL_PLAYSTATE_PLAYING); } this->buf_size = 0; this->next_buf = 0; break; } return 0; } static int _dlsym_iid(opensles_driver_t *this, const char *name, SLInterfaceID *iid) { SLInterfaceID *p = dlsym(this->hlib, name); if (!p) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "dlsym(\'%s\') failed: %s\n", name, dlerror()); return -1; } *iid = *p; return 0; } static ao_driver_t *_opensles_open_plugin (audio_driver_class_t *class_gen, const void *data) { opensles_class_t *class = (opensles_class_t *)class_gen; opensles_driver_t *this; SLresult result; SLInterfaceID SL_IID_ENGINE; SLresult (*slCreateEngine)(SLObjectItf*, SLuint32, const SLEngineOption*, SLuint32, const SLInterfaceID*, const SLboolean*); lprintf ("open_plugin called\n"); (void)data; this = calloc(1, sizeof (opensles_driver_t)); if (!this) return NULL; this->xine = class->xine; /* Load OpenSL ES */ this->hlib = dlopen("libOpenSLES.so", RTLD_NOW); if (!this) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "error opening libOpenSLES.so: %s\n", dlerror()); goto fail; } slCreateEngine = dlsym(this->hlib, "slCreateEngine"); if (!slCreateEngine) { xprintf (this->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "dlsym(\'slCreateEngine\') failed: %s\n", dlerror()); goto fail; } if (_dlsym_iid(this, "SL_IID_ENGINE", &SL_IID_ENGINE) < 0) goto fail; if (_dlsym_iid(this, "SL_IID_PLAY", &this->SL_IID_PLAY) < 0) goto fail; if (_dlsym_iid(this, "SL_IID_VOLUME", &this->SL_IID_VOLUME) < 0) goto fail; #ifdef HAVE_SLES_OPENSLES_ANDROID_H if (_dlsym_iid(this, "SL_IID_ANDROIDSIMPLEBUFFERQUEUE", &this->SL_IID_myBUFFERQUEUE) < 0) goto fail; #else if (_dlsym_iid(this, "SL_IID_BUFFERQUEUE", &this->SL_IID_myBUFFERQUEUE) < 0) goto fail; #endif /* create engine */ result = slCreateEngine(&this->engine_object, 0, NULL, 0, NULL, NULL); CHECK_OPENSL_RESULT("error creating engine", goto fail); result = (*(this->engine_object))->Realize(this->engine_object, SL_BOOLEAN_FALSE); CHECK_OPENSL_RESULT("error realizing engine", goto fail); result = (*(this->engine_object))->GetInterface(this->engine_object, SL_IID_ENGINE, &this->engine_if); CHECK_OPENSL_RESULT("error getting engine interface", goto fail); /* init output mix */ { const SLInterfaceID ids1[] = { this->SL_IID_VOLUME }; const SLboolean req1[] = { SL_BOOLEAN_FALSE }; result = (*(this->engine_if))->CreateOutputMix(this->engine_if, &this->output_mix_object, 1, ids1, req1); CHECK_OPENSL_RESULT("error creating output mix", goto fail); } result = (*(this->output_mix_object))->Realize(this->output_mix_object, SL_BOOLEAN_FALSE); CHECK_OPENSL_RESULT("error realizing output mix", goto fail); this->ao_driver.get_capabilities = _opensles_get_capabilities; this->ao_driver.get_property = _opensles_get_property; this->ao_driver.set_property = _opensles_set_property; this->ao_driver.open = _opensles_open; this->ao_driver.num_channels = _opensles_num_channels; this->ao_driver.bytes_per_frame = _opensles_bytes_per_frame; this->ao_driver.delay = _opensles_delay; this->ao_driver.write = _opensles_write; this->ao_driver.close = _opensles_close; this->ao_driver.exit = _opensles_exit; this->ao_driver.get_gap_tolerance = _opensles_get_gap_tolerance; this->ao_driver.control = _opensles_ctrl; return &this->ao_driver; fail: _opensles_exit(&this->ao_driver); return NULL; } static void *_opensles_init_class (xine_t *xine, const void *data) { opensles_class_t *this; (void)data; this = calloc(1, sizeof (opensles_class_t)); if (!this) return NULL; this->xine = xine; this->driver_class.open_plugin = _opensles_open_plugin; this->driver_class.identifier = "opensles"; #ifdef HAVE_SLES_OPENSLES_ANDROID_H this->driver_class.description = N_("OpenSL ES audio output plugin (Android)"); #else this->driver_class.description = N_("OpenSL ES audio output plugin"); #endif this->driver_class.dispose = default_audio_driver_class_dispose; return this; } /* * exported plugin catalog entry */ static const ao_info_t ao_info_opensles = { .priority = 5, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_OPENSLES_IFACE_VERSION, "opensles", XINE_VERSION_CODE, &ao_info_opensles, _opensles_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_directx2_out.c�����������������������������������������������������0000644�0001750�0001750�00000065133�14647725152�017413� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2004-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * xine audio output plugin using DirectX * * Implementation: * - this version contains service thread which starts and stops playback * according to the data availability * - it uses the ring buffer offered by DirectSound API * - formula for volume level is deduced according to authors ears :-) * * Hacker notes: * - always lock the mutex before calling audio_* functions * * Authors: * - Frantisek Dvorak <valtri@atlas.cz> * - Original version with slotted ring buffer * - Matthias Ringald <mringwal@inf.ethz.ch> * - non-slotted simpler version for ring buffer handling * * Inspiration: * - mplayer for workarounding -lguid idea * - DirectX 7 documentation * * License: * - dual GPL/LGPL (LGPL for non xine-specific part) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdarg.h> #include <errno.h> #include <string.h> #include <math.h> #include <windows.h> #include <dsound.h> #define LOG_MODULE "audio_directx2_out" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #define AO_OUT_DIRECTX2_IFACE_VERSION 9 /* * If GAP_TOLERANCE is lower than AO_MAX_GAP, xine will * try to smooth playback without skipping frames or * inserting silence. */ #define GAP_TOLERANCE (AO_MAX_GAP/3) /* * buffer size in miliseconds * (one second takes 11-192 KB) */ #define BUFFER_MS 1000 /* * buffer below this threshold is considered a buffer underrun */ #define BUFFER_MIN_MS 200 /* * base power factor for volume remapping */ #define FACTOR 60.0 /* * buffer handler status */ #define STATUS_START 0 #define STATUS_WAIT 1 #define STATUS_RUNNING 2 #define PRIdword "lu" #define PRIsizet "u" typedef struct { audio_driver_class_t driver_class; xine_t *xine; } dx2_class_t; typedef struct { ao_driver_t ao_driver; dx2_class_t *class; LPDIRECTSOUND ds; /* DirectSound device */ LPDIRECTSOUNDBUFFER dsbuffer; /* DirectSound buffer */ size_t buffer_size; /* size of the buffer */ size_t write_pos; /* positition in ring buffer for writing*/ int status; /* current status of the driver */ int paused; /* paused mode */ int finished; /* driver finished */ int failed; /* don't open modal dialog again */ uint32_t bits; uint32_t rate; uint32_t frame_size; uint32_t capabilities; int channels; int volume; int muted; pthread_t buffer_service; /* service thread for operating with DSB */ pthread_cond_t data_cond; /* signals on data */ pthread_mutex_t data_mutex; /* data lock */ } dx2_driver_t; /***************************************************************************** * DirectDraw GUIDs. * Defining them here allows us to get rid of the dxguid library during * the linking stage. *****************************************************************************/ static const GUID xine_IID_IDirectSoundNotify = { 0xB0210783, 0x89CD, 0x11D0, {0xAF, 0x08, 0x00, 0xA0, 0xC9, 0x25, 0xCD, 0x16} }; #ifdef IID_IDirectSoundNotify # undef IID_IDirectSoundNotify #endif #define IID_IDirectSoundNotify xine_IID_IDirectSoundNotify /* popup a dialog with error */ static void XINE_FORMAT_PRINTF(1, 2) error_message(const char *fmt, ...) { char message[256]; va_list ap; va_start(ap, fmt); vsnprintf(message, sizeof(message), fmt, ap); va_end(ap); MessageBox(0, message, _("Error"), MB_ICONERROR | MB_OK | MB_APPLMODAL); } /* description of given error */ static char *dsound_strerror(HRESULT err) { switch(err) { case DS_OK: return _("success"); #ifdef DSERR_ACCESSDENIED case DSERR_ACCESSDENIED: return _("access denied"); #endif case DSERR_ALLOCATED: return _("resource is already in use"); case DSERR_ALREADYINITIALIZED: return _("object was already initialized"); case DSERR_BADFORMAT: return _("specified wave format is not supported"); case DSERR_BUFFERLOST: return _("memory buffer has been lost and must be restored"); case DSERR_CONTROLUNAVAIL: return _("requested buffer control is not available"); case DSERR_GENERIC: return _("undetermined error inside DirectSound subsystem"); #ifdef DSERR_HWUNAVAIL case DSERR_HWUNAVAIL: return _("DirectSound hardware device is unavailable"); #endif case DSERR_INVALIDCALL: return _("function is not valid for the current state of the object"); case DSERR_INVALIDPARAM: return _("invalid parameter was passed"); case DSERR_NOAGGREGATION: return _("object doesn't support aggregation"); case DSERR_NODRIVER: return _("no sound driver available for use"); case DSERR_NOINTERFACE: return _("requested COM interface not available"); case DSERR_OTHERAPPHASPRIO: return _("another application has a higher priority level"); case DSERR_OUTOFMEMORY: return _("insufficient memory"); case DSERR_PRIOLEVELNEEDED: return _("low priority level for this function"); case DSERR_UNINITIALIZED: return _("DirectSound wasn't initialized"); case DSERR_UNSUPPORTED: return _("function is not supported"); default: return _("unknown error"); } } /* create direct sound object */ static LPDIRECTSOUND dsound_create() { LPDIRECTSOUND ds; if (DirectSoundCreate(NULL, &ds, NULL) != DS_OK) { error_message(_("Unable to create direct sound object.")); return NULL; } if (IDirectSound_SetCooperativeLevel(ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK) { IDirectSound_Release(ds); error_message(_("Could not set direct sound cooperative level.")); return NULL; } return ds; } /* destroy direct sound object */ static void dsound_destroy(LPDIRECTSOUND ds) { IDirectSound_Release(ds); } /* fill out wave format header */ static void dsound_fill_wfx(WAVEFORMATEX *wfx, uint32_t bits, uint32_t rate, int channels, size_t frame_size) { memset(wfx, 0, sizeof(*wfx)); wfx->wFormatTag = WAVE_FORMAT_PCM; wfx->nChannels = channels; wfx->nSamplesPerSec = rate; wfx->wBitsPerSample = (WORD)bits; wfx->nBlockAlign = frame_size; wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign; } /* fill out buffer description structure */ static void dsound_fill_desc(DSBUFFERDESC *desc, DWORD flags, DWORD buffer_size, WAVEFORMATEX *wfx) { memset(desc, 0, sizeof(DSBUFFERDESC)); desc->dwSize = sizeof(DSBUFFERDESC); desc->dwFlags = flags; desc->dwBufferBytes = buffer_size; desc->lpwfxFormat = wfx; } /* send exit signal to the audio thread */ static void audio_thread_exit(dx2_driver_t *this) { this->finished = 1; pthread_cond_signal(&this->data_cond); } /* check for error, log it and pop up dialog */ static void audio_error(dx2_driver_t *this, HRESULT err, char *msg) { xine_log(this->class->xine, XINE_LOG_MSG, LOG_MODULE ": %s: %s\n", msg, dsound_strerror(err)); if (!this->failed) { error_message("%s: %s", msg, dsound_strerror(err)); this->failed = 1; } if (this->status != STATUS_START) audio_thread_exit(this); } /* create direct sound buffer */ static int audio_create_buffers(dx2_driver_t *this) { DSBUFFERDESC desc; WAVEFORMATEX wfx; DWORD flags; HRESULT err; size_t buffer_size; buffer_size = this->rate * BUFFER_MS / 1000 * this->frame_size; if (buffer_size > DSBSIZE_MAX) buffer_size = DSBSIZE_MAX; if (buffer_size < DSBSIZE_MIN) buffer_size = DSBSIZE_MIN; this->buffer_size = buffer_size; flags = DSBCAPS_GLOBALFOCUS | DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; dsound_fill_wfx(&wfx, this->bits, this->rate, this->channels, this->frame_size); dsound_fill_desc(&desc, flags, this->buffer_size, &wfx); if ((err = IDirectSound_CreateSoundBuffer(this->ds, &desc, &this->dsbuffer, NULL)) != DS_OK) { audio_error(this, err, _("Unable to create secondary direct sound buffer")); return 0; } lprintf("created direct sound buffer, size = %zu\n", this->buffer_size); return 1; } /* destroy the sound buffer */ static void audio_destroy_buffers(dx2_driver_t *this) { IDirectSoundBuffer_Release(this->dsbuffer); } /* start playback */ static int audio_play(dx2_driver_t *this) { HRESULT err; if ((err = IDirectSoundBuffer_Play(this->dsbuffer, 0, 0, DSBPLAY_LOOPING)) != DS_OK) { audio_error(this, err, _("Couldn't play sound buffer")); return 0; } return 1; } /* stop playback */ static int audio_stop(dx2_driver_t *this) { HRESULT err; if ((err = IDirectSoundBuffer_Stop(this->dsbuffer)) != DS_OK) { audio_error(this, err, _("Couldn't stop sound buffer")); return 0; } return 1; } /* get current playback position in the ring buffer */ static int audio_tell(dx2_driver_t *this, size_t *pos) { DWORD err; DWORD play_pos; if ((err = IDirectSoundBuffer_GetCurrentPosition(this->dsbuffer, &play_pos, NULL)) != DS_OK) { audio_error(this, err, _("Can't get buffer position")); return 0; } *pos = play_pos; return 1; } /* set playback position in the ring buffer */ static int audio_seek(dx2_driver_t *this, size_t pos) { DWORD err; if ((err = IDirectSoundBuffer_SetCurrentPosition(this->dsbuffer, pos)) != DS_OK) { audio_error(this, err, _("Can't set buffer position")); return 0; } return 1; } /* flush audio buffers */ static int audio_flush(dx2_driver_t *this) { this->status = STATUS_WAIT; this->write_pos = 0; return audio_seek(this, 0); } /* * set the volume * * DirecSound can only lower the volume by software way. * Unit is dB, value is always negative or zero. */ static int audio_set_volume(dx2_driver_t *this, int volume) { HRESULT err; LONG value; value = DSBVOLUME_MIN * (pow(FACTOR, 1 - volume / 100.0) - 1) / (FACTOR - 1); if (value < DSBVOLUME_MIN) value = DSBVOLUME_MIN; else if (value > DSBVOLUME_MAX) value = DSBVOLUME_MAX; lprintf("Setting sound to %ld%% (%lu dB)\n", (long)volume, (unsigned long)value); if ((err = IDirectSoundBuffer_SetVolume(this->dsbuffer, value) != DS_OK)) { audio_error(this, err, _("Can't set sound volume")); return 0; } return 1; } /* add given data into the ring buffer */ static int audio_fill(dx2_driver_t *this, char *data, size_t size) { DWORD size1 = 0, size2 = 0; void *ptr1 = NULL, *ptr2 = NULL; HRESULT err; /* lock a part of the buffer, begin position on free space */ err = IDirectSoundBuffer_Lock(this->dsbuffer, this->write_pos, size, &ptr1, &size1, &ptr2, &size2, 0); /* try to restore the buffer, if necessary */ if (err == DSERR_BUFFERLOST) { xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": buffer lost, trying to restore\n")); IDirectSoundBuffer_Restore(this->dsbuffer); err = IDirectSoundBuffer_Lock(this->dsbuffer, this->write_pos, size, &ptr1, &size1, &ptr2, &size2, 0); } if (err != DS_OK) { audio_error(this, err, _("Couldn't lock direct sound buffer")); return 0; } _x_assert(size == size1 + size2); if (ptr1 && size1) xine_fast_memcpy(ptr1, data, size1); if (ptr2 && size2) xine_fast_memcpy(ptr2, data + size1, size2); // this->read_size += size; this->write_pos = (this->write_pos + size ) % this->buffer_size; lprintf("size %lu, write_pos %zu\n", (unsigned long)size, this->write_pos); if ((err = IDirectSoundBuffer_Unlock(this->dsbuffer, ptr1, size1, ptr2, size2)) != DS_OK) { audio_error(this, err, _("Couldn't unlock direct sound buffer")); return 0; } return 1; } /* transform given mode the number of channels */ static int mode2channels(uint32_t mode) { int channels; switch(mode) { case AO_CAP_MODE_MONO: channels = 1; break; case AO_CAP_MODE_STEREO: channels = 2; break; case AO_CAP_MODE_4CHANNEL: channels = 4; break; case AO_CAP_MODE_5CHANNEL: channels = 5; break; case AO_CAP_MODE_5_1CHANNEL: channels = 6; break; default: return 0; } return channels; } /* test the capability on given buffer */ static int test_capability(LPDIRECTSOUNDBUFFER buffer, uint32_t bits, uint32_t rate, int mode) { WAVEFORMATEX wfx; int channels; channels = mode2channels(mode); if (!channels) return 0; dsound_fill_wfx(&wfx, bits, rate, channels, (bits >> 3) * channels); if (IDirectSoundBuffer_SetFormat(buffer, &wfx) != DS_OK) { lprintf("mode %d, bits %" PRIu32 " not supported\n", mode, bits); return 0; } lprintf("mode %d, bits %" PRIu32 " supported\n", mode, bits); return 1; } /* * test capabilities of driver before opening * * Passed only 8 bit and 16 bit with mono or stereo. */ static int test_capabilities(dx2_driver_t *this) { struct { uint32_t bits; uint32_t rate; uint32_t mode; uint32_t caps; } tests[] = { {8, 44100, AO_CAP_MODE_MONO, AO_CAP_8BITS | AO_CAP_MODE_MONO}, {8, 44100, AO_CAP_MODE_STEREO, AO_CAP_8BITS | AO_CAP_MODE_STEREO}, {16, 44100, AO_CAP_MODE_MONO, AO_CAP_16BITS | AO_CAP_MODE_MONO}, {16, 44100, AO_CAP_MODE_STEREO, AO_CAP_16BITS | AO_CAP_MODE_STEREO}, {16, 44100, AO_CAP_MODE_4CHANNEL, AO_CAP_16BITS | AO_CAP_MODE_4CHANNEL}, {16, 44100, AO_CAP_MODE_5CHANNEL, AO_CAP_16BITS | AO_CAP_MODE_5CHANNEL}, {16, 44100, AO_CAP_MODE_5_1CHANNEL, AO_CAP_16BITS | AO_CAP_MODE_5_1CHANNEL}, {24, 44100, AO_CAP_MODE_STEREO, AO_CAP_24BITS | AO_CAP_MODE_STEREO}, {32, 44100, AO_CAP_MODE_STEREO, AO_CAP_FLOAT32 | AO_CAP_MODE_STEREO}, {0, 0, 0, 0}, }; LPDIRECTSOUNDBUFFER buffer; DSBUFFERDESC desc; int i; /* create temporary primary sound buffer */ dsound_fill_desc(&desc, DSBCAPS_PRIMARYBUFFER, 0, NULL); if (IDirectSound_CreateSoundBuffer(this->ds, &desc, &buffer, NULL) != DS_OK) { error_message(_("Unable to create primary direct sound buffer.")); return 0; } /* test capabilities */ this->capabilities = 0; i = 0; while (tests[i].bits) { if (test_capability(buffer, tests[i].bits, tests[i].rate, tests[i].mode)) this->capabilities |= tests[i].caps; i++; } lprintf("result capabilities: 0x%" PRIX32 "\n", this->capabilities); IDirectSoundBuffer_Release(buffer); return 1; } /* size of free space in the ring buffer */ static size_t buffer_free_size(dx2_driver_t *this) { int ret; size_t play_pos; size_t free_space; // get current play pos ret = audio_tell(this, &play_pos); if (!ret) return 0; // calc free space (-1) free_space = (this->buffer_size + play_pos - this->write_pos - 1) % this->buffer_size; return free_space; } /* size of occupied space in the ring buffer */ static size_t buffer_occupied_size(dx2_driver_t *this) { int ret; size_t play_pos; size_t used_space; // get current play pos ret = audio_tell(this, &play_pos); if (!ret) return 0; // calc used space used_space = (this->buffer_size + this->write_pos - play_pos) % this->buffer_size; return used_space; } /* service thread working with direct sound buffer */ static void *buffer_service(void *data) { dx2_driver_t *this = (dx2_driver_t *)data; size_t buffer_min; size_t data_in_buffer; /* prepare empty buffer */ audio_flush(this); /* prepare min buffer fill */ buffer_min = BUFFER_MIN_MS * this->rate / 1000 * this->frame_size; /* we live! */ pthread_mutex_lock(&this->data_mutex); pthread_cond_signal(&this->data_cond); pthread_mutex_unlock(&this->data_mutex); while (!this->finished) { pthread_mutex_lock(&this->data_mutex); switch( this->status){ case STATUS_WAIT: // pre: stop/buffer flushed lprintf("no data, sleeping...\n"); pthread_cond_wait(&this->data_cond, &this->data_mutex); lprintf("woke up (write_pos=%zd,free=%zu\n", this->write_pos, buffer_free_size(this)); if (this->finished) goto finished; if (!audio_seek(this, 0)) goto fail; if (!this->paused) { if (!audio_play(this)) goto fail; } this->status = STATUS_RUNNING; pthread_mutex_unlock(&this->data_mutex); break; case STATUS_RUNNING: // check for buffer underrun data_in_buffer = buffer_occupied_size(this); if ( data_in_buffer < buffer_min){ xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": play cursor overran (data %zu, min %zu), flushing buffers\n"), data_in_buffer, buffer_min); if (!audio_stop(this)) goto fail; if (!audio_flush(this)) goto fail; } pthread_mutex_unlock(&this->data_mutex); // just wait BUFFER_MIN_MS before next check xine_usec_sleep(BUFFER_MIN_MS * 1000); break; default: pthread_mutex_unlock(&this->data_mutex); break; } } return NULL; fail: this->finished = 1; finished: pthread_mutex_unlock(&this->data_mutex); return NULL; } /* ---- driver functions ---- */ static uint32_t ao_dx2_get_capabilities(ao_driver_t *this_gen) { dx2_driver_t *this = (dx2_driver_t *)this_gen; return this->capabilities; } static int ao_dx2_get_property(ao_driver_t *this_gen, int property) { dx2_driver_t *this = (dx2_driver_t *)this_gen; switch(property) { case AO_PROP_MIXER_VOL: case AO_PROP_PCM_VOL: return this->volume; case AO_PROP_MUTE_VOL: return this->muted; default: return 0; } } static int ao_dx2_set_property(ao_driver_t *this_gen, int property, int value) { dx2_driver_t *this = (dx2_driver_t *)this_gen; switch(property) { case AO_PROP_MIXER_VOL: case AO_PROP_PCM_VOL: lprintf("set volume to %d\n", value); pthread_mutex_lock(&this->data_mutex); if (!this->muted) { if (this->dsbuffer && !audio_set_volume(this, value)) return ~value; } this->volume = value; pthread_mutex_unlock(&this->data_mutex); break; case AO_PROP_MUTE_VOL: pthread_mutex_lock(&this->data_mutex); if (this->dsbuffer && !audio_set_volume(this, value ? 0 : this->volume)) return ~value; this->muted = value; pthread_mutex_unlock(&this->data_mutex); break; default: return ~value; } return value; } static int ao_dx2_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { dx2_driver_t *this = (dx2_driver_t *)this_gen; lprintf("bits=%" PRIu32 ", rate=%" PRIu32 ", mode=%d\n", bits, rate, mode); if (rate < DSBFREQUENCY_MIN) rate = DSBFREQUENCY_MIN; if (rate > DSBFREQUENCY_MAX) rate = DSBFREQUENCY_MAX; this->bits = bits; this->rate = rate; if ((this->channels = mode2channels(mode)) == 0) return 0; this->frame_size = (this->bits >> 3) * this->channels; this->paused = 0; this->finished = 0; this->status = STATUS_START; if (!audio_create_buffers(this)) return 0; if (!audio_set_volume(this, this->volume)) goto fail_buffers; /* creating the service thread and waiting for its signal */ pthread_mutex_lock(&this->data_mutex); if (pthread_create(&this->buffer_service, NULL, buffer_service, this) != 0) { xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't create buffer pthread: %s\n"), strerror(errno)); goto fail_mutex; } pthread_cond_wait(&this->data_cond, &this->data_mutex); pthread_mutex_unlock(&this->data_mutex); return rate; fail_mutex: pthread_mutex_unlock(&this->data_mutex); fail_buffers: audio_destroy_buffers(this); return 0; } static int ao_dx2_num_channels(ao_driver_t *this_gen) { dx2_driver_t *this = (dx2_driver_t *)this_gen; lprintf("channels=%d\n", this->channels); return this->channels; } static int ao_dx2_bytes_per_frame(ao_driver_t *this_gen) { dx2_driver_t *this = (dx2_driver_t *)this_gen; lprintf("frame_size=%d\n", this->frame_size); return this->frame_size; } static int ao_dx2_delay(ao_driver_t *this_gen) { dx2_driver_t *this = (dx2_driver_t *)this_gen; int frames = 0; int ret; size_t play_pos; pthread_mutex_lock(&this->data_mutex); if (this->status != STATUS_RUNNING){ frames = this->write_pos / this->frame_size; } else { ret = audio_tell(this, &play_pos); if (ret){ frames = buffer_occupied_size(this) / this->frame_size; } } pthread_mutex_unlock(&this->data_mutex); #ifdef LOG if ((rand() % 10) == 0) lprintf("frames=%d, play_pos=%" PRIdword ", write_pos=%u\n", frames, play_pos, this->write_pos); #endif return frames; } static int ao_dx2_write(ao_driver_t *this_gen, int16_t* audio_data, uint32_t num_samples) { dx2_driver_t *this = (dx2_driver_t *)this_gen; size_t input_size; /* used size of input data */ size_t free_size; /* size of the free space in the ring buffer */ size_t size; /* current block size */ size_t read_pos; /* position in the input */ input_size = this->frame_size * num_samples; read_pos = 0; while (input_size && !this->finished) { pthread_mutex_lock(&this->data_mutex); while (((free_size = buffer_free_size(this)) == 0) && !this->finished) { lprintf("buffer full, waiting\n"); pthread_mutex_unlock(&this->data_mutex); xine_usec_sleep(1000 * BUFFER_MS / 10); pthread_mutex_lock(&this->data_mutex); } if (free_size >= input_size) size = input_size; else size = free_size; if (!audio_fill(this, ((char *)audio_data) + read_pos, size)) { audio_thread_exit(this); pthread_mutex_unlock(&this->data_mutex); return 0; } pthread_mutex_unlock(&this->data_mutex); read_pos += size; input_size -= size; } /* signal, if are waiting and need wake up */ if ((this->status == STATUS_WAIT) && (buffer_occupied_size(this) > BUFFER_MIN_MS * this->rate / 1000 * this->frame_size)) { lprintf("buffer ready, waking up\n"); pthread_cond_signal(&this->data_cond); } return 1; } static void ao_dx2_close(ao_driver_t *this_gen) { dx2_driver_t *this = (dx2_driver_t *)this_gen; lprintf("close plugin\n"); pthread_mutex_lock(&this->data_mutex); audio_thread_exit(this); pthread_mutex_unlock(&this->data_mutex); if (pthread_join(this->buffer_service, NULL) != 0) { xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't destroy buffer pthread: %s\n"), strerror(errno)); return; } lprintf("pthread joined\n"); audio_destroy_buffers(this); } static void ao_dx2_exit(ao_driver_t *this_gen) { dx2_driver_t *this = (dx2_driver_t *)this_gen; lprintf("exit instance\n"); if (this->ds) { dsound_destroy(this->ds); } if (pthread_cond_destroy(&this->data_cond) != 0) { xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't destroy pthread condition: %s\n"), strerror(errno)); } if (pthread_mutex_destroy(&this->data_mutex) != 0) { xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't destroy pthread mutex: %s\n"), strerror(errno)); } free(this); } static int ao_dx2_get_gap_tolerance(ao_driver_t *this_gen) { return GAP_TOLERANCE; } static int ao_dx2_control(ao_driver_t *this_gen, int cmd, ...) { dx2_driver_t *this = (dx2_driver_t *)this_gen; switch(cmd) { case AO_CTRL_PLAY_PAUSE: lprintf("control pause\n"); pthread_mutex_lock(&this->data_mutex); if (!this->paused) { audio_stop(this); this->paused = 1; } pthread_mutex_unlock(&this->data_mutex); break; case AO_CTRL_PLAY_RESUME: lprintf("control resume\n"); pthread_mutex_lock(&this->data_mutex); if (this->paused) { if (this->status != STATUS_WAIT) audio_play(this); this->paused = 0; } pthread_mutex_unlock(&this->data_mutex); break; case AO_CTRL_FLUSH_BUFFERS: lprintf("control flush\n"); pthread_mutex_lock(&this->data_mutex); audio_stop(this); audio_flush(this); pthread_mutex_unlock(&this->data_mutex); break; default: xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": unknown control command %d\n"), cmd); } return 0; } /* ---- class functions ---- */ static ao_driver_t *open_plugin(audio_driver_class_t *class_gen, const void *data) { dx2_class_t *class = (dx2_class_t *)class_gen; dx2_driver_t *this; lprintf("open plugin called\n"); this = calloc(1, sizeof(dx2_driver_t)); if (!this) return NULL; this->class = class; this->ao_driver.get_capabilities = ao_dx2_get_capabilities; this->ao_driver.get_property = ao_dx2_get_property; this->ao_driver.set_property = ao_dx2_set_property; this->ao_driver.open = ao_dx2_open; this->ao_driver.num_channels = ao_dx2_num_channels; this->ao_driver.bytes_per_frame = ao_dx2_bytes_per_frame; this->ao_driver.delay = ao_dx2_delay; this->ao_driver.write = ao_dx2_write; this->ao_driver.close = ao_dx2_close; this->ao_driver.exit = ao_dx2_exit; this->ao_driver.get_gap_tolerance = ao_dx2_get_gap_tolerance; this->ao_driver.control = ao_dx2_control; this->volume = 100; this->muted = 0; this->failed = 0; if (pthread_cond_init(&this->data_cond, NULL) != 0) { xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't create pthread condition: %s\n"), strerror(errno)); free(this); return NULL; } if (pthread_mutex_init(&this->data_mutex, NULL) != 0) { xine_log(this->class->xine, XINE_LOG_MSG, _(LOG_MODULE ": can't create pthread mutex: %s\n"), strerror(errno)); pthread_cond_destroy(&this->data_cond); free(this); return NULL; } if ((this->ds = dsound_create()) == NULL) { ao_dx2_exit(&this->ao_driver); return NULL; } test_capabilities(this); return (ao_driver_t *)this; } static void *init_class(xine_t *xine, const void *data) { dx2_class_t *this; lprintf("init class\n"); this = calloc(1, sizeof(dx2_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "directx2"; this->driver_class.description = N_("second xine audio output plugin using directx"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; return this; } static const ao_info_t ao_info_directx2 = { .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { { PLUGIN_AUDIO_OUT, AO_OUT_DIRECTX2_IFACE_VERSION, "directx2", XINE_VERSION_CODE, &ao_info_directx2, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_irixal_out.c�������������������������������������������������������0000644�0001750�0001750�00000027111�14647725152�017151� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #warning DISABLED: FIXME #if 0 #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <sys/ioctl.h> #include <inttypes.h> #include <dmedia/audio.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/compat.h> #include <xine/audio_out.h> //#ifndef AFMT_S16_NE //# if defined(sparc) || defined(__sparc__) || defined(PPC) ///* Big endian machines */ //# define AFMT_S16_NE AFMT_S16_BE //# else //# define AFMT_S16_NE AFMT_S16_LE //# endif //#endif #define AO_IRIXAL_IFACE_VERSION 4 #define DEFAULT_GAP_TOLERANCE 5000 typedef struct irixal_driver_s { ao_driver_t ao_driver; ALport port; int capabilities; int open_mode; int gap_tolerance; int32_t output_sample_rate, input_sample_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; stamp_t frames_in_buffer; /* number of frames writen to audio hardware */ } irixal_driver_t; // static snd_output_t *jcd_out; /* * open the audio device for writing to */ static int ao_irixal_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { irixal_driver_t *this = (irixal_driver_t *) this_gen; int resource; ALconfig config; ALpv parvalue; /* * Init config for audio port */ switch (mode) { case AO_CAP_MODE_MONO: this->num_channels = 1; break; case AO_CAP_MODE_STEREO: this->num_channels = 2; break; /* not tested so far (missing an Onyx with multichannel output...) */ case AO_CAP_MODE_4CHANNEL: this->num_channels = 4; break; #if 0 /* unsupported so far */ case AO_CAP_MODE_5CHANNEL: this->num_channels = 5; break; case AO_CAP_MODE_5_1CHANNEL: this->num_channels = 6; break; case AO_CAP_MODE_A52: this->num_channels = 2; break; #endif default: xlerror ("irixal Driver does not support the requested mode: 0x%x",mode); return 0; } if (! (config = alNewConfig ())) { xlerror ("cannot get new config: %s", strerror (oserror())); return 0; } if ( (alSetChannels (config, this->num_channels)) == -1) { xlerror ("cannot set to %d channels: %s", this->num_channels, strerror (oserror())); alFreeConfig (config); return 0; } switch (bits) { case 8: if ( (alSetWidth (config, AL_SAMPLE_8)) == -1) { xlerror ("cannot set 8bit mode: %s", strerror (oserror())); alFreeConfig (config); return 0; } break; case 16: /* Default format is 16bit PCM */ break; default: xlerror ("irixal Driver does not support %dbit audio", bits); alFreeConfig (config); return 0; } printf("audio_irixal_out: channels=%d, bits=%d\n", this->num_channels, bits); /* * Try to open audio port */ if (! (this->port = alOpenPort ("xine", "w", config))) { xlerror ("irixal Driver does not support the audio configuration"); alFreeConfig (config); return 0; } alFreeConfig (config); resource = alGetResource (this->port); this->open_mode = mode; this->input_sample_rate = rate; this->bits_per_sample = bits; /* FIXME: Can use an irixal function here ?!? */ this->bytes_per_frame = (this->bits_per_sample*this->num_channels) / 8; this->frames_in_buffer = 0; /* TODO: not yet settable (see alParams (3dm)): AL_INTERFACE, AL_CLOCK_GEN */ /* * Try to adapt sample rate of audio port */ parvalue.param = AL_MASTER_CLOCK; parvalue.value.i = AL_CRYSTAL_MCLK_TYPE; if (alSetParams (resource, &parvalue, 1) == -1) printf ("audio_irixal: FYI: cannot set audio master clock to crystal based clock\n"); parvalue.param = AL_RATE; parvalue.value.ll = alIntToFixed (rate); if (alSetParams (resource, &parvalue, 1) == -1) printf ("audio_irixal: FYI: cannot set sample rate, using software resampling\n"); if (alGetParams (resource, &parvalue, 1) == -1) { xlerror ("cannot ask for current sample rate, assuming everything worked..."); this->output_sample_rate = this->input_sample_rate; } else this->output_sample_rate = alFixedToInt (parvalue.value.ll); if (this->input_sample_rate != this->output_sample_rate) printf ("audio_irixal: FYI: sample_rate in %d, out %d\n", this->input_sample_rate, this->output_sample_rate); return this->output_sample_rate; } static int ao_irixal_num_channels(ao_driver_t *this_gen) { irixal_driver_t *this = (irixal_driver_t *) this_gen; return this->num_channels; } static int ao_irixal_bytes_per_frame(ao_driver_t *this_gen) { irixal_driver_t *this = (irixal_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_irixal_get_gap_tolerance (ao_driver_t *this_gen) { irixal_driver_t *this = (irixal_driver_t *) this_gen; return this->gap_tolerance; } static int ao_irixal_delay (ao_driver_t *this_gen) { irixal_driver_t *this = (irixal_driver_t *) this_gen; stamp_t stamp, time; int frames_left; if (alGetFrameTime (this->port, &stamp, &time) == -1) xlerror ("alGetFrameNumber failed"); frames_left = this->frames_in_buffer - stamp; if (frames_left <= 0) /* buffer ran dry */ frames_left = 0; return frames_left; } static int ao_irixal_write(ao_driver_t *this_gen,int16_t *data, uint32_t num_frames) { irixal_driver_t *this = (irixal_driver_t *) this_gen; stamp_t stamp; /* Grmbf. IRIX audio does not tell us, wenn we run dry. * We have to detect this ourself. */ /* get absolute number of samples played so far * note: this counts up when run dry as well... */ if (alGetFrameNumber (this->port, &stamp) == -1) xlerror ("alGetFrameNumber failed"); if (this->frames_in_buffer < stamp) /* dry run */ { if (this->frames_in_buffer > 0) printf ("audio_irixal: audio buffer dry run detected, buffer %llu should be > %llu!\n", this->frames_in_buffer, stamp); this->frames_in_buffer = stamp; } /* FIXME: what to do when the call would block? * We have to write things out anyway... * alGetFillable() would tell us, whether space was available */ alWriteFrames (this->port, data, num_frames); this->frames_in_buffer += num_frames; return num_frames; } static void ao_irixal_close(ao_driver_t *this_gen) { irixal_driver_t *this = (irixal_driver_t *) this_gen; if (this->port) alClosePort (this->port); this->port = NULL; } static uint32_t ao_irixal_get_capabilities (ao_driver_t *this_gen) { irixal_driver_t *this = (irixal_driver_t *) this_gen; return this->capabilities; } static void ao_irixal_exit(ao_driver_t *this_gen) { irixal_driver_t *this = (irixal_driver_t *) this_gen; ao_irixal_close (this_gen); free (this); } static int ao_irixal_get_property (ao_driver_t *this, int property) { /* FIXME: implement some properties */ return 0; } /* * */ static int ao_irixal_set_property (ao_driver_t *this, int property, int value) { /* FIXME: Implement property support */ return ~value; } /* * */ static int ao_irixal_ctrl(ao_driver_t *this_gen, int cmd, ...) { irixal_driver_t *this = (irixal_driver_t *) this_gen; switch (cmd) { case AO_CTRL_PLAY_PAUSE: break; case AO_CTRL_PLAY_RESUME: break; case AO_CTRL_FLUSH_BUFFERS: break; } return 0; } static void *init_audio_out_plugin (config_values_t *config) { irixal_driver_t *this; ALvalue values [32]; ALpv parvalue; char name[32]; int i, numvalues; int useresource = -1; printf ("audio_irixal: init...\n"); /* Check available outputs */ /* TODO: this is verbose information only right now, output is not selectable */ if ( (numvalues = alQueryValues (AL_SYSTEM, AL_DEFAULT_OUTPUT, values, 32, NULL, 0)) > 0) { useresource = values [0].i; for (i = 0; i < numvalues; i++) { parvalue.param = AL_NAME; parvalue.value.ptr = name; parvalue.sizeIn = 32; if (alGetParams (values [i].i, &parvalue, 1) != -1) printf (" available Output: %s\n", name); } } if (useresource == -1) { xlerror ("cannot find output resource"); return NULL; } #if 0 /* TODO */ device = config->lookup_str(config,"irixal_default_device", "default"); #endif /* allocate struct */ this = (irixal_driver_t *) calloc (sizeof (irixal_driver_t), 1); if (!this) return NULL; /* get capabilities */ if ( (numvalues = alQueryValues (useresource, AL_CHANNELS, values, 32, NULL, 0)) > 0) { for (i = 0; i < numvalues; i++) { switch (values[i].i) { case 1: this->capabilities |= AO_CAP_MODE_MONO; break; case 2: this->capabilities |= AO_CAP_MODE_STEREO; break; /* not tested so far (missing an Onyx with multichannel output...) */ case 4: this->capabilities |= AO_CAP_MODE_4CHANNEL; break; #if 0 /* unsupported so far */ case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: case AO_CAP_MODE_A52: #endif default: printf (" unsupported %d channel config available on system\n", values[i].i); } } } printf (" capabilities 0x%X\n",this->capabilities); /* TODO: anything can change during runtime... move check to the right location */ this->gap_tolerance = config->register_range (config, "audio.device.irixal_gap_tolerance", DEFAULT_GAP_TOLERANCE, 0, 90000, _("irixal audio output maximum gap length"), _("You can specify the maximum offset between audio " "and video xine will tolerate before trying to " "resync them.\nThe unit of this value is one PTS tick, " "which is the 90000th part of a second."), 30, NULL, NULL); this->ao_driver.get_capabilities = ao_irixal_get_capabilities; this->ao_driver.get_property = ao_irixal_get_property; this->ao_driver.set_property = ao_irixal_set_property; this->ao_driver.open = ao_irixal_open; this->ao_driver.num_channels = ao_irixal_num_channels; this->ao_driver.bytes_per_frame = ao_irixal_bytes_per_frame; this->ao_driver.delay = ao_irixal_delay; this->ao_driver.write = ao_irixal_write; this->ao_driver.close = ao_irixal_close; this->ao_driver.exit = ao_irixal_exit; this->ao_driver.get_gap_tolerance = ao_irixal_get_gap_tolerance; this->ao_driver.control = ao_irixal_ctrl; return this; } static const ao_info_t ao_info_irixal = { .priority = 10, }; ao_info_t *get_audio_out_plugin_info() { ao_info_irixal.description = _("xine audio output plugin using IRIX libaudio"); return &ao_info_irixal; } /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, AO_OUT_IRIXAL_IFACE_VERSION, "irixal", XINE_VERSION_CODE, &ao_info_irixal, init_audio_out_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_sndio_out.c��������������������������������������������������������0000644�0001750�0001750�00000023250�14647725152�016775� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (c) 2008 Brad Smith <brad@comstyle.com> * * Permission to use, copy, modify, and 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. */ /* ao plugin for sndio by Brad Smith <brad@comstyle.com>. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <inttypes.h> #include <pthread.h> #include <sndio.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include "bswap.h" #define GAP_TOLERANCE AO_MAX_GAP #define PCT_TO_MIDI(p) (((p) * SIO_MAXVOL + 50) / 100) typedef struct { audio_driver_class_t driver_class; xine_t *xine; } sndio_class_t; typedef struct sndio_driver_s { ao_driver_t ao_driver; xine_t *xine; struct sio_hdl *hdl; long long realpos, playpos; int capabilities; int num_channels; u_int32_t bits_per_sample; u_int32_t bytes_per_frame; struct { int volume; int mute; } mixer; } sndio_driver_t; /* * Callback to notify of frames processed by the hw. It is * called from the mail loop called from sio_write(). */ static void ao_sndio_onmove_cb(void *addr, int delta) { sndio_driver_t *this = (sndio_driver_t *)addr; this->realpos += delta; } /* * Open the audio device for writing to. */ static int ao_sndio_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { sndio_driver_t *this = (sndio_driver_t *) this_gen; struct sio_par par; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); if (this->hdl != NULL) { sio_close (this->hdl); this->hdl = NULL; } this->hdl = sio_open(NULL, SIO_PLAY, 0); if (this->hdl == NULL) goto bad; sio_initpar(&par); switch (mode) { case AO_CAP_MODE_MONO: par.pchan = 1; break; case AO_CAP_MODE_STEREO: par.pchan = 2; break; case AO_CAP_MODE_4CHANNEL: par.pchan = 4; break; case AO_CAP_MODE_4_1CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: par.pchan = 6; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_open does not support the requested mode: 0x%X\n", mode); goto bad; } switch (bits) { case 8: par.bits = 8; par.sig = 0; break; case 16: par.bits = 16; par.sig = 1; break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_open bits per sample not supported: %d\n", bits); goto bad; } par.rate = rate; par.appbufsz = par.rate * 250 / 1000; /* 250ms buffer */ if (!sio_setpar(this->hdl, &par)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_open could not set params\n"); goto bad; } if (!sio_getpar(this->hdl, &par)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_open could not get params\n"); goto bad; } xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_open %d channels output\n", par.pchan); this->num_channels = par.pchan; this->bytes_per_frame = par.bps * par.pchan; this->playpos = 0; this->realpos = 0; sio_onmove(this->hdl, ao_sndio_onmove_cb, this); if (!sio_start(this->hdl)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_open could not start\n"); goto bad; } return par.rate; bad: if (this->hdl != NULL) sio_close(this->hdl); return 0; } static int ao_sndio_num_channels(ao_driver_t *this_gen) { sndio_driver_t *this = (sndio_driver_t *) this_gen; return this->num_channels; } static int ao_sndio_bytes_per_frame(ao_driver_t *this_gen) { sndio_driver_t *this = (sndio_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_sndio_get_gap_tolerance (ao_driver_t *this_gen) { (void)this_gen; return GAP_TOLERANCE; } static int ao_sndio_write(ao_driver_t *this_gen, int16_t *data, uint32_t num_frames) { sndio_driver_t *this = (sndio_driver_t *) this_gen; size_t ret, size = num_frames * this->bytes_per_frame; ret = sio_write(this->hdl, data, size); if (ret == 0) return 0; this->playpos += num_frames; return 1; } static int ao_sndio_delay (ao_driver_t *this_gen) { sndio_driver_t *this = (sndio_driver_t *) this_gen; int bufused; if (this->realpos < 0) bufused = this->playpos; else bufused = this->playpos - this->realpos; return bufused; } static void ao_sndio_close(ao_driver_t *this_gen) { sndio_driver_t *this = (sndio_driver_t *) this_gen; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_close called\n"); if (!sio_stop(this->hdl)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_close could not stop\n"); } sio_close(this->hdl); this->hdl = NULL; } static uint32_t ao_sndio_get_capabilities (ao_driver_t *this_gen) { sndio_driver_t *this = (sndio_driver_t *) this_gen; return this->capabilities; } static void ao_sndio_exit(ao_driver_t *this_gen) { sndio_driver_t *this = (sndio_driver_t *) this_gen; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_sndio_out: ao_sndio_exit called\n"); if (this->hdl != NULL) sio_close(this->hdl); } static int ao_sndio_get_property (ao_driver_t *this_gen, int property) { sndio_driver_t *this = (sndio_driver_t *) this_gen; switch (property) { case AO_PROP_MIXER_VOL: return this->mixer.volume; break; case AO_PROP_MUTE_VOL: return this->mixer.mute; break; } return 0; } static int ao_sndio_set_property (ao_driver_t *this_gen, int property, int value) { sndio_driver_t *this = (sndio_driver_t *) this_gen; int vol; if (this->hdl == NULL) return 0; switch(property) { case AO_PROP_MIXER_VOL: this->mixer.volume = value; if (!this->mixer.mute) sio_setvol(this->hdl, PCT_TO_MIDI(this->mixer.volume)); return this->mixer.volume; break; case AO_PROP_MUTE_VOL: this->mixer.mute = (value) ? 1 : 0; vol = 0; if (!this->mixer.mute) vol = PCT_TO_MIDI(this->mixer.volume); sio_setvol(this->hdl, vol); return value; break; } return value; } /* * pause, resume, flush buffers */ static int ao_sndio_ctrl(ao_driver_t *this_gen, int cmd, ...) { (void)this_gen; (void)cmd; /* * sndio pauses automatically if there are no more samples to play * and resumes when there are samples again. So we leave this empty * for the moment. */ return 0; } static ao_driver_t *open_plugin (audio_driver_class_t *class_gen, const void *data) { sndio_class_t *class = (sndio_class_t *) class_gen; sndio_driver_t *this; (void)data; lprintf ("audio_sndio_out: open_plugin called\n"); this = calloc(1, sizeof (sndio_driver_t)); if (!this) return NULL; this->xine = class->xine; /* * Set capabilities */ this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL | AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL | AO_CAP_MIXER_VOL | AO_CAP_MUTE_VOL | AO_CAP_8BITS | AO_CAP_16BITS; this->ao_driver.get_capabilities = ao_sndio_get_capabilities; this->ao_driver.get_property = ao_sndio_get_property; this->ao_driver.set_property = ao_sndio_set_property; this->ao_driver.open = ao_sndio_open; this->ao_driver.num_channels = ao_sndio_num_channels; this->ao_driver.bytes_per_frame = ao_sndio_bytes_per_frame; this->ao_driver.delay = ao_sndio_delay; this->ao_driver.write = ao_sndio_write; this->ao_driver.close = ao_sndio_close; this->ao_driver.exit = ao_sndio_exit; this->ao_driver.get_gap_tolerance = ao_sndio_get_gap_tolerance; this->ao_driver.control = ao_sndio_ctrl; return &this->ao_driver; } /* * class functions */ static void dispose_class (audio_driver_class_t *this_gen) { sndio_class_t *this = (sndio_class_t *) this_gen; free(this); } static void *init_class (xine_t *xine, const void *data) { sndio_class_t *this; (void)data; lprintf ("audio_sndio_out: init class\n"); this = calloc(1, sizeof (sndio_class_t)); if (!this) return NULL; this->driver_class.open_plugin = open_plugin; this->driver_class.identifier = "sndio"; this->driver_class.description = N_("xine audio output plugin using sndio audio devices/drivers "); this->driver_class.dispose = dispose_class; this->xine = xine; return this; } static const ao_info_t ao_info_sndio = { .priority = 12, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_OUT, 9, "sndio", XINE_VERSION_CODE, &ao_info_sndio, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_out/audio_file_out.c���������������������������������������������������������0000644�0001750�0001750�00000025734�14647725152�016611� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <inttypes.h> #include <sys/stat.h> #define LOG_MODULE "audio_file_out" #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include "bswap.h" #define AO_OUT_FILE_IFACE_VERSION 9 #define AOF_GAP_TOLERANCE INT_MAX #ifdef WIN32 #ifndef S_IWUSR #define S_IWUSR 0x0000 #endif #ifndef S_IRGRP #define S_IRGRP 0x0000 #endif #ifndef S_IROTH #define S_IROTH 0x0000 #endif #endif /* Taken (hStudlyCapsAndAll) from sox's wavwritehdr */ struct ao_file_wavhdr { unsigned char bRiffMagic[4]; // 'RIFF' uint32_t wRiffLength ; // length of file minus the 8 byte riff header unsigned char bWaveMagic[8]; // 'WAVEfmt ' uint32_t wFmtSize; // length of format chunk minus 8 byte header uint16_t wFormatTag; // identifies PCM, ULAW etc uint16_t wChannels; uint32_t dwSamplesPerSecond; // samples per second per channel uint32_t dwAvgBytesPerSec; // non-trivial for compressed formats uint16_t wBlockAlign; // basic block size uint16_t wBitsPerSample; // non-trivial for compressed formats // PCM formats then go straight to the data chunk: unsigned char bData[4]; // 'data' unsigned long dwDataLength; // length of data chunk minus 8 byte header }; typedef struct ao_file_driver_s { ao_driver_t ao_driver; xine_t *xine; int capabilities; int mode; int32_t sample_rate; uint32_t num_channels; uint32_t bits_per_sample; uint32_t bytes_per_frame; const char *fname; int fd; size_t bytes_written; struct timeval endtime; } ao_file_driver_t; typedef struct { audio_driver_class_t driver_class; xine_t *xine; } ao_file_class_t; /* * open the audio device for writing to */ static int ao_file_open(ao_driver_t *this_gen, uint32_t bits, uint32_t rate, int mode) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; struct ao_file_wavhdr w; xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_file_out: ao_open bits=%d rate=%d, mode=%d\n", bits, rate, mode); this->mode = mode; this->sample_rate = rate; this->bits_per_sample = bits; switch (mode) { case AO_CAP_MODE_MONO: this->num_channels = 1; break; case AO_CAP_MODE_STEREO: this->num_channels = 2; break; } this->bytes_per_frame = (this->bits_per_sample*this->num_channels) / 8; this->fd = -1; this->fname = getenv("XINE_WAVE_OUTPUT"); if (!this->fname) this->fname = "xine-out.wav"; this->fd = xine_create_cloexec(this->fname, O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (this->fd == -1) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_file_out: Failed to open file '%s': %s\n", this->fname, strerror(errno)); return 0; } w.bRiffMagic[0] = 'R'; w.bRiffMagic[1] = 'I'; w.bRiffMagic[2] = 'F'; w.bRiffMagic[3] = 'F'; w.wRiffLength = le2me_32(0x7ff00024); w.bWaveMagic[0] = 'W'; w.bWaveMagic[1] = 'A'; w.bWaveMagic[2] = 'V'; w.bWaveMagic[3] = 'E'; w.bWaveMagic[4] = 'f'; w.bWaveMagic[5] = 'm'; w.bWaveMagic[6] = 't'; w.bWaveMagic[7] = ' '; w.wFmtSize = le2me_32(0x10); w.wFormatTag = le2me_16(1); // PCM; w.wChannels = le2me_16(this->num_channels); w.dwSamplesPerSecond = le2me_32(this->sample_rate); w.dwAvgBytesPerSec = le2me_32(this->sample_rate * this->bytes_per_frame); w.wBlockAlign = le2me_16(this->bytes_per_frame); w.wBitsPerSample = le2me_16(this->bits_per_sample); w.bData[0] = 'd'; w.bData[1] = 'a'; w.bData[2] = 't'; w.bData[3] = 'a'; w.dwDataLength = le2me_32(0x7ffff000); this->bytes_written = 0; if (write(this->fd, &w, sizeof(w)) != sizeof(w)) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_file_out: Failed to write WAVE header to file '%s': %s\n", this->fname, strerror(errno)); close(this->fd); this->fd = -1; return 0; } xine_monotonic_clock(&this->endtime, NULL); return this->sample_rate; } static int ao_file_num_channels(ao_driver_t *this_gen) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; return this->num_channels; } static int ao_file_bytes_per_frame(ao_driver_t *this_gen) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; return this->bytes_per_frame; } static int ao_file_get_gap_tolerance (ao_driver_t *this_gen) { (void)this_gen; return AOF_GAP_TOLERANCE; } static int ao_file_write(ao_driver_t *this_gen, int16_t *data, uint32_t num_frames) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; size_t len = num_frames * this->bytes_per_frame; unsigned long usecs; #ifdef WORDS_BIGENDIAN /* Eep. .WAV format is little-endian. We need to swap. Remind me why I picked this output format again? */ if (this->bits_per_sample == 16) { int i; for (i=0; i<len/2; i++) data[i] = bswap_16(data[i]); } else if (this->bits_per_sample == 32) { int i; uint32_t *d32 = (void *)data; for (i=0; i<len/4; i++) d32[i] = bswap_16(d32[i]); } #endif while(len) { ssize_t thislen = write(this->fd, data, len); if (thislen == -1) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_file_out: Failed to write data to file '%s': %s\n", this->fname, strerror(errno)); return -1; } len -= thislen; this->bytes_written += thislen; } /* Delay for an appropriate amount of time to prevent padding */ usecs = ((10000 * num_frames / (this->sample_rate/100))); this->endtime.tv_usec += usecs; while (this->endtime.tv_usec > 1000000) { this->endtime.tv_usec -= 1000000; this->endtime.tv_sec++; } return 1; } static int ao_file_delay (ao_driver_t *this_gen) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; struct timeval now; unsigned long tosleep; /* Work out how long we need to sleep for, and how much time we've already taken */ xine_monotonic_clock(&now, NULL); if (now.tv_sec > this->endtime.tv_sec) { /* We slipped. Compensate */ this->endtime = now; return 0; } if (now.tv_sec == this->endtime.tv_sec && now.tv_usec >= this->endtime.tv_usec) return 0; tosleep = this->endtime.tv_sec - now.tv_sec; tosleep *= 1000000; tosleep += this->endtime.tv_usec - now.tv_usec; xine_usec_sleep(tosleep); return 0; } static void ao_file_close(ao_driver_t *this_gen) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; uint32_t len; len = le2me_32(this->bytes_written); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_file_out: Close file '%s'. %zu KiB written\n", this->fname, this->bytes_written / 1024); if (lseek(this->fd, 40, SEEK_SET) != -1) { if (write(this->fd, &len, 4) != 4) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_file_out: Failed to write header to file '%s': %s\n", this->fname, strerror(errno)); } len = le2me_32(this->bytes_written + 0x24); if (lseek(this->fd, 4, SEEK_SET) != -1) { if (write(this->fd, &len, 4) != 4) { xprintf (this->xine, XINE_VERBOSITY_LOG, "audio_file_out: Failed to write header to file '%s': %s\n", this->fname, strerror(errno)); } } } close(this->fd); this->fd = -1; } static uint32_t ao_file_get_capabilities (ao_driver_t *this_gen) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; return this->capabilities; } static void ao_file_exit(ao_driver_t *this_gen) { ao_file_driver_t *this = (ao_file_driver_t *) this_gen; if (this->fd != -1) ao_file_close(this_gen); free (this); } static int ao_file_get_property (ao_driver_t *this_gen, int property) { (void)this_gen; (void)property; return 0; } static int ao_file_set_property (ao_driver_t *this_gen, int property, int value) { (void)this_gen; (void)property; return ~value; } static int ao_file_ctrl(ao_driver_t *this_gen, int cmd, ...) { /*file_driver_t *this = (file_driver_t *) this_gen;*/ (void)this_gen; switch (cmd) { case AO_CTRL_PLAY_PAUSE: break; case AO_CTRL_PLAY_RESUME: break; case AO_CTRL_FLUSH_BUFFERS: break; } return 0; } static ao_driver_t *ao_file_open_plugin (audio_driver_class_t *class_gen, const void *data) { ao_file_class_t *class = (ao_file_class_t *) class_gen; ao_file_driver_t *this; lprintf ("open_plugin called\n"); (void)data; this = calloc(1, sizeof (ao_file_driver_t)); if (!this) return NULL; this->xine = class->xine; this->capabilities = AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO; this->sample_rate = 0; this->ao_driver.get_capabilities = ao_file_get_capabilities; this->ao_driver.get_property = ao_file_get_property; this->ao_driver.set_property = ao_file_set_property; this->ao_driver.open = ao_file_open; this->ao_driver.num_channels = ao_file_num_channels; this->ao_driver.bytes_per_frame = ao_file_bytes_per_frame; this->ao_driver.delay = ao_file_delay; this->ao_driver.write = ao_file_write; this->ao_driver.close = ao_file_close; this->ao_driver.exit = ao_file_exit; this->ao_driver.get_gap_tolerance = ao_file_get_gap_tolerance; this->ao_driver.control = ao_file_ctrl; this->fd = -1; return &this->ao_driver; } /* * class functions */ static void *ao_file_init_class (xine_t *xine, const void *data) { ao_file_class_t *this; lprintf ("init class\n"); (void)data; this = calloc(1, sizeof (ao_file_class_t)); if (!this) return NULL; this->driver_class.open_plugin = ao_file_open_plugin; this->driver_class.identifier = "file"; this->driver_class.description = N_("xine file audio output plugin"); this->driver_class.dispose = default_audio_driver_class_dispose; this->xine = xine; return this; } static const ao_info_t ao_info_file = { .priority = -1, /* do not auto probe this one */ }; /* * exported plugin catalog entry */ #define AO_FILE_CATALOG { PLUGIN_AUDIO_OUT, AO_OUT_FILE_IFACE_VERSION, "file", XINE_VERSION_CODE, &ao_info_file, ao_file_init_class } #ifndef XINE_MAKE_BUILTINS const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ AO_FILE_CATALOG, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif ������������������������������������xine-lib-1.2/src/audio_dec/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013367� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/xine_a52_parser.h��������������������������������������������������������0000644�0001750�0001750�00000011737�14647725152�016537� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������� /* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * a52 frame parser */ #ifndef _XINE_A52_PARSER_H #define _XINE_A52_PARSER_H #include <sys/types.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> static const char *a52_channel_info(int a52_flags) { switch (a52_flags & A52_CHANNEL_MASK) { case A52_3F2R: return (a52_flags & A52_LFE) ? "A/52 5.1" : "A/52 5.0"; case A52_3F1R: case A52_2F2R: return (a52_flags & A52_LFE) ? "A/52 4.1" : "A/52 4.0"; case A52_2F1R: case A52_3F: return "A/52 3.0"; case A52_STEREO: return "A/52 2.0 (stereo)"; case A52_DOLBY: return "A/52 2.0 (dolby)"; case A52_MONO: return "A/52 1.0"; default: return "A/52"; } } static void a52_meta_info_set(xine_stream_t *stream, int a52_flags, int bit_rate, int sample_rate) { _x_meta_info_set_utf8 (stream, XINE_META_INFO_AUDIOCODEC, a52_channel_info(a52_flags)); _x_stream_info_set (stream, XINE_STREAM_INFO_AUDIO_BITRATE, bit_rate); _x_stream_info_set (stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, sample_rate); } static void do_swab(uint8_t *p, uint8_t *end) { lprintf ("byte-swapping dnet\n"); while (p != end) { uint8_t byte = *p++; *(p - 1) = *p; *p++ = byte; } } typedef struct { uint8_t got_frame; uint8_t sync_state; int a52_flags; int a52_bit_rate; int a52_sample_rate; int frame_length, frame_todo; uint16_t syncword; uint8_t *frame_ptr; uint8_t frame_buffer[3840]; } xine_a52_parser_t; static void xine_a52_parser_reset(xine_a52_parser_t *this) { this->syncword = 0; this->sync_state = 0; } static size_t xine_a52_parse_data(xine_a52_parser_t *this, xine_stream_t *stream, const uint8_t *data, size_t size) { const uint8_t *const end = data + size; const uint8_t *current = data; const uint8_t *sync_start = current + 1; this->got_frame = 0; while (current < end) { switch (this->sync_state) { case 0: /* Looking for sync header */ this->syncword = (this->syncword << 8) | *current++; if (this->syncword == 0x0b77) { this->frame_buffer[0] = 0x0b; this->frame_buffer[1] = 0x77; this->sync_state = 1; this->frame_ptr = this->frame_buffer+2; } break; case 1: /* Looking for enough bytes for sync_info. */ sync_start = current - 1; *this->frame_ptr++ = *current++; if ((this->frame_ptr - this->frame_buffer) > 16) { int a52_flags_old = this->a52_flags; int a52_sample_rate_old = this->a52_sample_rate; int a52_bit_rate_old = this->a52_bit_rate; this->frame_length = a52_syncinfo (this->frame_buffer, &this->a52_flags, &this->a52_sample_rate, &this->a52_bit_rate); if (this->frame_length < 80) { /* Invalid a52 frame_length */ this->syncword = 0; current = sync_start; this->sync_state = 0; break; } lprintf("Frame length = %d\n",this->frame_length); this->frame_todo = this->frame_length - 17; this->sync_state = 2; if (a52_flags_old != this->a52_flags || a52_sample_rate_old != this->a52_sample_rate || a52_bit_rate_old != this->a52_bit_rate) { a52_meta_info_set(stream, this->a52_flags, this->a52_bit_rate, this->a52_sample_rate); } } break; case 2: /* Filling frame_buffer with sync_info bytes */ *this->frame_ptr++ = *current++; this->frame_todo--; if (this->frame_todo > 0) break; /* Ready for decode */ this->syncword = 0; this->sync_state = 0; if (xine_crc16_ansi (0, &this->frame_buffer[2], this->frame_length - 2) != 0) { /* CRC16 failed */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "liba52:a52 frame failed crc16 checksum.\n"); current = sync_start; break; } this->got_frame = 1; return (current - data); break; default: /* No come here */ break; } } return size; } #endif /* _XINE_A52_PARSER_H */ ���������������������������������xine-lib-1.2/src/audio_dec/xine_mad_decoder.c�������������������������������������������������������0000644�0001750�0001750�00000062406�14647725152�017014� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stuff needed to turn libmad into a xine decoder plugin */ #include <stdlib.h> #include <string.h> #include "config.h" #define LOG_MODULE "mad_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" #ifdef HAVE_MAD_H # include <mad.h> #else # include "frame.h" # include "synth.h" #endif #define REST_SIZE 16384 /* According to Rob Leslie (libmad author) : * The absolute theoretical maximum frame size is 2881 bytes: MPEG 2.5 Layer II, * 8000 Hz @ 160 kbps, with a padding slot. (Such a frame is unlikely, but it was * a useful exercise to compute all possible frame sizes.) Add to this an 8 byte * MAD_BUFFER_GUARD, and the minimum buffer size you should be streaming to * libmad in the general case is 2889 bytes. * Theoretical frame sizes for Layer III range from 24 to 1441 bytes, but there * is a "soft" limit imposed by the standard of 960 bytes. Nonetheless MAD can * decode frames of any size as long as they fit entirely in the buffer you pass, * not including the MAD_BUFFER_GUARD bytes. * TJ. Well. * 1. (MAD_ERROR_BUFLEN) libmad always wants >= MAD_BUFFER_GUARD explicit extra bytes, * containing a next frame head. A fake one does the trick with layers 1 and 2. * 2. (MAD_ERROR_BADDATAPTR) Layer 3 uses forward references, and therefore * needs at least 2 frames. */ #define MAD_MIN_SIZE 2889 typedef struct mad_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *xstream; #define MAD_PTS_LD 3 #define MAD_PTS_SIZE (1 << MAD_PTS_LD) #define MAD_PTS_MASK (MAD_PTS_SIZE - 1) unsigned int pts_samples; unsigned int pts_delay; uint32_t pts_read; uint32_t pts_write; struct { int64_t pts; int bytes; } pts_ring[MAD_PTS_SIZE]; struct mad_synth synth; struct mad_stream stream; struct mad_frame frame; unsigned int output_sampling_rate; int output_open; int output_mode; int preview_mode; unsigned int start_padding; unsigned int end_padding; int needs_more_data; uint8_t *inbuf; int insize; mad_fixed_t peak; uint32_t seek; uint32_t declip; unsigned int num_inbufs; unsigned int num_bytes_d; unsigned int num_bytes_r; unsigned int num_outbufs; /* sliding window reassemble buf */ uint32_t rest_read, rest_write; uint8_t rest_buf[REST_SIZE + MAD_BUFFER_GUARD]; } mad_decoder_t; static int _mad_frame_size (const uint8_t *h) { /* bitrate table[type, 6][bitrate index, 16] */ static const uint8_t mp3_byterates[] = { 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 255, 0, 4, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 255, 0, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 255, 0, 4, 6, 7, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 18, 20, 255 }; /* frequency table[mpeg version bits, 4][frequence index, 4] (in Hz) */ static const uint16_t mp3_freqs[] = { 11025, 12000, 8000, 0, /* v2.5 */ 0, 0, 0, 0, /* reserved */ 22050, 24000, 16000, 0, /* v2 */ 44100, 48000, 32000, 0 /* v1 */ }; /* samples per frame table[type, 6] */ static const uint16_t mp3_samples[6] = { 384, 1152, 1152, 384, 1152, 576 }; /* padding bytes table[type, 6] */ static const uint8_t mp3_padding[6] = { 4, 1, 1, 4, 1, 1 }; static const uint8_t mp3_type[16] = { /* Layer 4(aac_latm) 3 2 1 */ /* MPEG Version 2.5 */ 255, 5, 4, 3, /* reserved */ 255, 255, 255, 255, /* v2 */ 255, 5, 4, 3, /* v1 */ 255, 2, 1, 0 }; uint32_t byterate, freq, padding, samples; uint32_t type; /* read header */ uint32_t head = _X_BE_32 (h); /* check if really mp3 */ if ((head >> 21) != 0x7ff) return 0; type = mp3_type[(head >> 17) & 15]; if (type & 128) return 0; samples = mp3_samples[type]; byterate = mp3_byterates[16 * type + ((head >> 12) & 15)]; if (byterate & 128) return 0; freq = mp3_freqs[((head >> 17) & 12) + ((head >> 10) & 3)]; if (!freq) return 0; padding = head & (1 << 9) ? mp3_padding[type] : 0; if (byterate) return samples * byterate * 1000 / freq + padding; return 0; } static void mad_reset (audio_decoder_t *this_gen) { mad_decoder_t *this = xine_container_of(this_gen, mad_decoder_t, audio_decoder); mad_synth_finish (&this->synth); mad_frame_finish (&this->frame); mad_stream_finish(&this->stream); this->pts_read = 0; this->pts_write = 0; this->rest_read = 0; this->rest_write = 0; this->preview_mode = 0; this->start_padding = 0; this->end_padding = 0; this->needs_more_data = 0; this->seek = 2; mad_synth_init (&this->synth); mad_stream_init (&this->stream); this->stream.options = MAD_OPTION_IGNORECRC; mad_frame_init (&this->frame); } static void mad_discontinuity (audio_decoder_t *this_gen) { mad_decoder_t *this = xine_container_of(this_gen, mad_decoder_t, audio_decoder); int b = this->rest_write - this->rest_read; if (b > 0) { this->pts_ring[0].pts = 0; this->pts_ring[0].bytes = b; this->pts_write = 1; } else { this->pts_write = 0; } this->pts_read = 0; this->seek = 2; } /* utility to scale and round samples to 16 bits */ static inline int32_t _mad_scale (mad_fixed_t sample) { int32_t v = (sample + (1L << (MAD_F_FRACBITS - 16))) >> (MAD_F_FRACBITS + 1 - 16); return ((v + 0x8000) & 0xffff0000) ? (v >> 31) ^ 0x7fff : v; } /* static int head_check(mad_decoder_t *this) { if( (this->header & 0xffe00000) != 0xffe00000) return 0; if(!((this->header>>17)&3)) return 0; if( ((this->header>>12)&0xf) == 0xf) return 0; if( ((this->header>>10)&0x3) == 0x3 ) return 0; return 1; } */ static int _mad_consume (mad_decoder_t *this) { int d, l; if (!this->stream.next_frame) return 0; d = (const uint8_t *)this->stream.next_frame - (const uint8_t *)this->inbuf; if (d <= 0) return 0; this->inbuf += d; this->insize -= d; if (this->rest_write) this->rest_read += d; l = d; while (this->pts_read != this->pts_write) { l -= this->pts_ring[this->pts_read].bytes; if (l >= 0) { this->pts_read = (this->pts_read + 1) & MAD_PTS_MASK; if (l == 0) break; } else { this->pts_ring[this->pts_read].bytes += l; break; } } return d; } static void mad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { mad_decoder_t *this = xine_container_of(this_gen, mad_decoder_t, audio_decoder); lprintf ("decode data, size: %d, decoder_flags: %d\n", buf->size, buf->decoder_flags); if (!(buf->decoder_flags & BUF_FLAG_HEADER)) { int donebytes = 0; this->insize = 0; this->inbuf = NULL; /* reset decoder on leaving preview mode */ if ((buf->decoder_flags & BUF_FLAG_PREVIEW) == 0) { if (this->preview_mode) { mad_reset (this_gen); } } else { this->preview_mode = 1; } this->num_inbufs += 1; this->pts_ring[this->pts_write].pts = buf->pts; this->pts_ring[this->pts_write].bytes = buf->size; this->pts_write = (this->pts_write + 1) & MAD_PTS_MASK; xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG + 1, "mad_audio_decoder: inbuf bytes %d, pts %" PRId64 ".\n", buf->size, buf->pts); while (1) { int err; if (this->insize <= 0) { int left = buf->size - donebytes; if (left <= 0) break; if (!this->rest_write) { /* try using buf mem itself. */ this->inbuf = buf->content + donebytes; this->insize = left; this->num_bytes_d += left; donebytes = buf->size; } else { /* fall back to reassembling. */ int n = REST_SIZE - this->rest_write; if ((n < left) && this->rest_read) { n = this->rest_write - this->rest_read; if (n > 0) { if (this->rest_read >= (uint32_t)n) memcpy (this->rest_buf, this->rest_buf + this->rest_read, n); else memmove (this->rest_buf, this->rest_buf + this->rest_read, n); } this->rest_write = n; this->rest_read = 0; n = REST_SIZE - n; } if (n > left) n = left; xine_fast_memcpy (this->rest_buf + this->rest_write, buf->content + donebytes, n); donebytes += n; this->rest_write += n; this->num_bytes_r += n; this->insize = this->rest_write - this->rest_read; this->inbuf = this->rest_buf + this->rest_read; } mad_stream_buffer (&this->stream, this->inbuf, this->insize); } if (!this->needs_more_data) { if (buf->decoder_flags & BUF_FLAG_AUDIO_PADDING) { this->start_padding = buf->decoder_info[1]; this->end_padding = buf->decoder_info[2]; } else { this->start_padding = 0; this->end_padding = 0; } } do { err = mad_frame_decode (&this->frame, &this->stream); if (!err) break; { int d = _mad_consume (this); if (d > 0) { xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG + 1, "mad_audio_decoder: error 0x%x, consumed %d.\n", (unsigned int)this->stream.error, d); } } /* HACK: demuxers - even mpeg-ts - usually send whole frames. * libmad refuses to decode the last frame there. * retry with a fake next. */ do { if ((this->stream.error != MAD_ERROR_BUFLEN) || (this->insize < 4)) break; if (!(this->inbuf[1] & 0x04)) /* layer > 2 */ break; if (this->rest_write || (buf->content != buf->mem) || (buf->max_size - buf->size < MAD_BUFFER_GUARD)) break; if (_mad_frame_size (this->inbuf) != this->insize) break; memset (this->inbuf + this->insize, 0, MAD_BUFFER_GUARD); this->inbuf[this->insize] = 0xff; this->inbuf[this->insize + 1] = 0xe0; mad_stream_buffer (&this->stream, this->inbuf, this->insize + MAD_BUFFER_GUARD); err = mad_frame_decode (&this->frame, &this->stream); if (!err) this->insize = 0; } while (0); if (!err) break; if ((this->stream.error == MAD_ERROR_BUFLEN) || (this->stream.error == MAD_ERROR_BADDATAPTR)) { /* libmad wants more data */ this->needs_more_data = 1; if (this->insize > 0) { if (!this->rest_write) { memcpy (this->rest_buf, this->inbuf, this->insize); this->rest_write = this->insize; this->num_bytes_d -= this->insize; this->num_bytes_r += this->insize; this->rest_read = 0; } this->insize = 0; } else { this->rest_read = 0; this->rest_write = 0; } } else { int d; lprintf ("error 0x%04X\n", this->stream.error); d = _mad_consume (this); xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG + 1, "mad_audio_decoder: error 0x%x, consumed %d.\n", (unsigned int)this->stream.error, d); if (this->insize > 0) mad_stream_buffer (&this->stream, this->inbuf, this->insize); } } while (0); if (!err) { mad_fixed_t old_peak = this->peak; int mode = (this->frame.header.mode == MAD_MODE_SINGLE_CHANNEL) ? AO_CAP_MODE_MONO : AO_CAP_MODE_STEREO; if (!this->output_open || (this->output_sampling_rate != this->frame.header.samplerate) || (this->output_mode != mode)) { lprintf ("audio sample rate %d mode %08x\n", this->frame.header.samplerate, mode); /* the mpeg audio demuxer can set audio bitrate */ if (! _x_stream_info_get(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE)) { _x_stream_info_set(this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE, this->frame.header.bitrate); } /* the mpeg audio demuxer can set this meta info */ if (! _x_meta_info_get(this->xstream, XINE_META_INFO_AUDIOCODEC)) { const char *s; switch (this->frame.header.layer) { case MAD_LAYER_I: s = "MPEG audio layer 1 (lib: MAD)"; break; case MAD_LAYER_II: s = "MPEG audio layer 2 (lib: MAD)"; break; case MAD_LAYER_III: s = "MPEG audio layer 3 (lib: MAD)"; break; default: s = "MPEG audio (lib: MAD)"; } _x_meta_info_set_utf8 (this->xstream, XINE_META_INFO_AUDIOCODEC, s); } if (this->output_open) this->xstream->audio_out->close (this->xstream->audio_out, this->xstream); this->output_open = this->xstream->audio_out->open (this->xstream->audio_out, this->xstream, 16, this->frame.header.samplerate, mode); if (!this->output_open) break; this->output_sampling_rate = this->frame.header.samplerate; this->output_mode = mode; this->pts_samples = 0; } mad_synth_frame (&this->synth, &this->frame); if ( (buf->decoder_flags & BUF_FLAG_PREVIEW) == 0 ) { unsigned int nsamples; audio_buffer_t *audio_buffer; this->num_outbufs += 1; audio_buffer = this->xstream->audio_out->get_buffer (this->xstream->audio_out); nsamples = this->synth.pcm.length; /* padding */ if (this->start_padding || this->end_padding) { /* check padding validity */ if (nsamples < this->start_padding + this->end_padding) { lprintf("invalid padding data"); this->start_padding = 0; this->end_padding = 0; } else { lprintf ("nsamples=%u, start_padding=%u, end_padding=%u\n", nsamples, this->start_padding, this->end_padding); nsamples -= this->start_padding + this->end_padding; } } audio_buffer->num_frames = nsamples; if (this->synth.pcm.channels == 2) { const mad_fixed_t *left = this->synth.pcm.samples[0] + this->start_padding; const mad_fixed_t *right = this->synth.pcm.samples[1] + this->start_padding; int16_t *output = audio_buffer->mem; if (this->declip) { while (nsamples--) { mad_fixed_t v, a; v = *left++; a = v < 0 ? -v : v; if (a > this->peak) this->peak = a; v -= v >> 2; *output++ = _mad_scale (v); v = *right++; a = v < 0 ? -v : v; if (a > this->peak) this->peak = a; v -= v >> 2; *output++ = _mad_scale (v); } } else { while (nsamples--) { mad_fixed_t v, a; v = *left++; a = v < 0 ? -v : v; if (a > this->peak) this->peak = a; *output++ = _mad_scale (v); v = *right++; a = v < 0 ? -v : v; if (a > this->peak) this->peak = a; *output++ = _mad_scale (v); } } } else { const mad_fixed_t *mid = this->synth.pcm.samples[0] + this->start_padding; int16_t *output = audio_buffer->mem; if (this->declip) { while (nsamples--) { mad_fixed_t v, a; v = *mid++; a = v < 0 ? -v : v; if (a > this->peak) this->peak = a; v -= v >> 2; *output++ = _mad_scale (v); } } else { while (nsamples--) { mad_fixed_t v, a; v = *mid++; a = v < 0 ? -v : v; if (a > this->peak) this->peak = a; *output++ = _mad_scale (v); } } } /* disregard glitches after seek. */ if (this->seek) { this->seek -= 1; this->peak = old_peak; } /* auto declip when peaks exnceed 0.4dB. */ if (!this->declip && ((uint32_t)this->peak > (0x860dbbdb >> (31 - MAD_F_FRACBITS)))) { this->declip = 1; xprintf (this->xstream->xine, XINE_VERBOSITY_LOG, "mad_audio_decoder: source too loud, adding -2.5dB declip filter.\n"); } /* pts computing */ if (this->synth.pcm.length != this->pts_samples) { /* mpeg audio involves frequency transform, which needs some delay on both the * encoding and decoding sides. encode delay varies with encoding algorithm. * it is available from optional Xing head via BUF_FLAG_AUDIO_PADDING in the * buf->decoder_info[1] field. * decode delay is more or less standardized. * the simpliest approach to deal with this is to let each side compensate * for its own known delay. thus, remove decoder delay from timeline here. */ this->pts_samples = this->synth.pcm.length; if (this->frame.header.samplerate) { if (this->frame.header.layer == MAD_LAYER_III) { /* 528 of 1152 samples. */ this->pts_delay = this->synth.pcm.length * (528 * 90000 / 1152) / this->frame.header.samplerate; } else { /* 240 of 1152 samples. */ this->pts_delay = this->synth.pcm.length * (240 * 90000 / 1152) / this->frame.header.samplerate; } } xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG, "mad_audio_decoder: decoder delay %u pts.\n", this->pts_delay); } if (this->pts_read != this->pts_write) { audio_buffer->vpts = this->pts_ring[this->pts_read].pts; this->pts_ring[this->pts_read].pts = 0; if (audio_buffer->vpts) audio_buffer->vpts -= this->pts_delay; } else { audio_buffer->vpts = 0; } { int d = _mad_consume (this); xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG + 1, "mad_audio_decoder: outbuf consumed %d, samples %d, pts %" PRId64 ".\n", d, audio_buffer->num_frames, audio_buffer->vpts); } { #if 0 int bitrate = this->frame.header.bitrate; if (bitrate <= 0) { bitrate = _x_stream_info_get (this->xstream, XINE_STREAM_INFO_AUDIO_BITRATE); lprintf ("offset %d bps\n", bitrate); } if (audio_buffer->vpts && (bitrate > 0)) { int pts_offset = (bytes_in_buffer_at_pts * 8 * 90) / (bitrate / 1000); lprintf ("pts: %"PRId64", offset: %d pts, %d bytes\n", buf->pts, pts_offset, bytes_in_buffer_at_pts); if (audio_buffer->vpts < pts_offset) pts_offset = audio_buffer->vpts; audio_buffer->vpts -= pts_offset; } #endif } this->xstream->audio_out->put_buffer (this->xstream->audio_out, audio_buffer, this->xstream); if (buf->decoder_flags & BUF_FLAG_AUDIO_PADDING) { this->start_padding = buf->decoder_info[1]; this->end_padding = buf->decoder_info[2]; buf->decoder_info[1] = 0; buf->decoder_info[2] = 0; } else { this->start_padding = 0; this->end_padding = 0; } } lprintf ("decode worked\n"); } } } } /* Report peak level _before_ clipping. Seen up to +3.5dB there. Why? * Well, most audio CDs are mastered with a "wave shaper" like the one * audacity once had. It folds some peaks in towards 0, and allowes to * louden everything then. We hardly hear a difference, which is why * mpeg and most other audio codecs drop that info. After decoding, * some of those peaks are back, and get chopped off. That yields * distortion, and kills background sounds during loud passages. * Even worse, lame encoder seems to be affected by internal clipping * there, too. Recommended: lame --scale 0.707 -V1 foo.wav. */ static int _mad_fixed_2_db (mad_fixed_t v) { static const uint32_t tab[] = { /* 0x80000000 * pow (2.0, index / 60.0) */ 0x80000000, 0x817CBEEE, 0x82FDEA6A, 0x84838F9F, 0x860DBBDB, 0x879C7C96, 0x892FDF71, 0x8AC7F232, 0x8C64C2CC, 0x8E065F59, 0x8FACD61E, 0x91583589, 0x93088C35, 0x94BDE8E8, 0x96785A92, 0x9837F051, 0x99FCB971, 0x9BC6C569, 0x9D9623DF, 0x9F6AE4AA, 0xA14517CC, 0xA324CD79, 0xA50A1615, 0xA6F50235, 0xA8E5A29D, 0xAADC0847, 0xACD8445C, 0xAEDA6839, 0xB0E28570, 0xB2F0ADC6, 0xB504F333, 0xB71F67E9, 0xB9401E4D, 0xBB6728FB, 0xBD949AC6, 0xBFC886BB, 0xC203001D, 0xC4441A6B, 0xC68BE95B, 0xC8DA80E1, 0xCB2FF529, 0xCD8C5A9E, 0xCFEFC5E6, 0xD25A4BE4, 0xD4CC01BB, 0xD744FCCA, 0xD9C552B4, 0xDC4D1957, 0xDEDC66D6, 0xE1735195, 0xE411F03A, 0xE6B859AE, 0xE966A51F, 0xEC1CEA00, 0xEEDB4008, 0xF1A1BF38, 0xF4707FD5, 0xF7479A6E, 0xFA2727DB, 0xFD0F413D }; uint32_t u, b, m, e; int r = 60 * (31 - MAD_F_FRACBITS); u = v; while (!(u & 0x80000000)) { r -= 60; u <<= 1; } b = 0; e = sizeof (tab) / sizeof (tab[0]); do { m = (b + e) >> 1; if (u < tab[m]) e = m; else b = m + 1; } while (b != e); r += b; return r; } static void mad_dispose (audio_decoder_t *this_gen) { mad_decoder_t *this = xine_container_of(this_gen, mad_decoder_t, audio_decoder); mad_synth_finish (&this->synth); mad_frame_finish (&this->frame); mad_stream_finish(&this->stream); if (this->output_open) { this->xstream->audio_out->close (this->xstream->audio_out, this->xstream); this->output_open = 0; } xprintf (this->xstream->xine, XINE_VERBOSITY_DEBUG, "mad_audio_decoder: %u inbufs, %u direct bytes, %u reassembled bytes, %u outbufs.\n", this->num_inbufs, this->num_bytes_d, this->num_bytes_r, this->num_outbufs); { int l = this->declip ? XINE_VERBOSITY_LOG : XINE_VERBOSITY_DEBUG; int peak = _mad_fixed_2_db (this->peak); const char *s = peak < 0 ? "-" : "+"; peak = peak < 0 ? -peak : peak; xprintf (this->xstream->xine, l, "mad_audio_decoder: peak level %d / %s%0d.%01ddB.\n", (int)this->peak, s, peak / 10, peak % 10); } free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { mad_decoder_t *this ; (void)class_gen; this = (mad_decoder_t *) calloc(1, sizeof(mad_decoder_t)); if (!this) return NULL; /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ #ifndef HAVE_ZERO_SAFE_MEM this->output_open = 0; this->rest_read = 0; this->rest_write = 0; this->preview_mode = 0; this->num_inbufs = 0; this->num_bytes_d = 0; this->num_bytes_r = 0; this->num_outbufs = 0; this->declip = 0; this->pts_samples = 0; this->pts_delay = 0; this->pts_read = 0; this->pts_write = 0; #endif this->seek = 2; this->peak = 1; this->audio_decoder.decode_data = mad_decode_data; this->audio_decoder.reset = mad_reset; this->audio_decoder.discontinuity = mad_discontinuity; this->audio_decoder.dispose = mad_dispose; this->xstream = stream; mad_synth_init (&this->synth); mad_stream_init (&this->stream); mad_frame_init (&this->frame); this->stream.options = MAD_OPTION_IGNORECRC; lprintf ("init\n"); return &this->audio_decoder; } /* * mad plugin class */ static void *init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "mad", .description = N_("libmad based mpeg audio layer 1/2/3 decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (void *)&this; } static const uint32_t audio_types[] = { BUF_AUDIO_MPEG, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 8, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 16, "mad", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/latm.c�������������������������������������������������������������������0000644�0001750�0001750�00000070400�14647725152�014471� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * AAC LATM parser and demuxer by Torsten Jager <t.jager@gmx.de> * Limitations: * - LATM v0 and v1 only * - 1 program / 1 layer of the possible 16 / 8 (DVB) * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <sys/types.h> #include <string.h> #include <stdlib.h> #define LOG_MODULE "latm" #define LOG_VERBOSE /* #define LOG */ #if (defined (__GNUC__) && (__GNUC__ >= 4)) || defined (__clang__) # if defined (__i386) || defined (__i386__) # define BEBF_X86_32_ASM # endif # define bebf_UNUSED __attribute__((unused)) # ifdef WORDS_BIGENDIAN # define bebf_ADJ32(v) (v) # else # define bebf_ADJ32(v) ((uint32_t)__builtin_bswap32 ((int32_t)(v))) # endif #else # define bebf_UNUSED # ifdef WORDS_BIGENDIAN # define bebf_ADJ32(v) (v) # else # define bebf_ADJ32(v) (((v) >> 24) | (((v) & 0xff0000) >> 8) | (((v) & 0xff00) << 8) | ((v) << 24)) # endif #endif /************************************************************************* * Big Endian BitFile helper * *************************************************************************/ typedef struct { uint64_t readcache; /* left justified */ const uint32_t *readptr, *readstop; const uint8_t *readstart; int32_t readbits, writebits; /* # of invalid bits in cache */ uint64_t writecache; uint32_t *writeptr; uint8_t *writestart; } bebf_t; /** * Jump to stream reader bit position. * @param bebf pointer to bebf_t struct to use. * @param nbits new position in bits from the beginning. */ static void bebf_UNUSED bebf_seek (bebf_t *bebf, uint32_t nbits) { const uint32_t *p = (const uint32_t *)(((uintptr_t)bebf->readstart + (nbits >> 3)) & ~(uintptr_t)3); uint32_t n = (int32_t)nbits - (((const uint8_t *)p - bebf->readstart) << 3); bebf->readbits = n; if (p < bebf->readstop) { uint64_t b = bebf_ADJ32 (p[0]); b <<= 32; b |= bebf_ADJ32 (p[1]); bebf->readcache = b << n; bebf->readptr = p + 2; } else { bebf->readcache = 0; bebf->readptr = bebf->readstop; } } /** * Align to next byte boundary. * @param bebf pointer to bebf_t struct to use. */ static void bebf_UNUSED bebf_align (bebf_t *bebf) { uint32_t n = (64 - bebf->readbits) & 7; if (n) { bebf->readcache <<= n; bebf->readbits += n; } } /** * Initialize big endian bit stream reader. * @param bebf pointer to bebf_t struct to use. * @param rp pointer to read stream, padded by at least 8 bytes. * @param nbytes byte length of input. */ static void bebf_UNUSED bebf_set_read (bebf_t *bebf, const uint8_t *rp, uint32_t nbytes) { bebf->readstart = rp; bebf->readstop = (const uint32_t *)(((uintptr_t)rp + nbytes + 3) & ~(uintptr_t)3); bebf_seek (bebf, 0); } /** * Initialize big endian bit stream writer. * @param bebf pointer to bebf_t struct to use. * @param wp pointer to 4 byte aligned write buffer. */ static void bebf_UNUSED bebf_set_write (bebf_t *bebf, uint8_t *wp) { bebf->writestart = wp; bebf->writeptr = (uint32_t *)wp; bebf->writecache = 0; bebf->writebits = 64; } /** * Get 1 .. 32 bits of data from read stream. * @param bebf pointer to bebf_t struct to use. * @param nbits bit count. * @return the requested data, right justified. */ static uint32_t bebf_UNUSED bebf_get (bebf_t *bebf, uint32_t nbits) { uint32_t b; if (bebf->readbits > 31) { bebf->readbits -= 32; if (bebf->readptr < bebf->readstop) { uint32_t v = bebf_ADJ32 (*(bebf->readptr)++); bebf->readcache |= (uint64_t)v << bebf->readbits; } } bebf->readbits += nbits; b = bebf->readcache >> 32; bebf->readcache <<= nbits; return b >> (32 - nbits); } /** * Sniff 1 .. 32 bits of data from read stream, not changing the stream position. * @param bebf pointer to bebf_t struct to use. * @param nbits bit count. * @return the requested data, right justified. */ static uint32_t bebf_UNUSED bebf_sniff (bebf_t *bebf, uint32_t nbits) { uint32_t b; if (bebf->readbits > 31) { bebf->readbits -= 32; if (bebf->readptr < bebf->readstop) { uint32_t v = bebf_ADJ32 (*(bebf->readptr)++); bebf->readcache |= (uint64_t)v << bebf->readbits; } } bebf->readbits += nbits; b = bebf->readcache >> 32; return b >> (32 - nbits); } /** * Discard 1 .. 32 bits of data from read stream. * @param bebf pointer to bebf_t struct to use. * @param nbits bit count. */ static void bebf_UNUSED bebf_skip (bebf_t *bebf, uint32_t nbits) { if (bebf->readbits > 31) { bebf->readbits -= 32; if (bebf->readptr < bebf->readstop) { uint32_t v = bebf_ADJ32 (*(bebf->readptr)++); bebf->readcache |= (uint64_t)v << bebf->readbits; } } bebf->readbits += nbits; bebf->readcache <<= nbits; } /** * Tell current read stream position. * @param bebf pointer to bebf_t struct to use. * @return stream position in bits. */ static uint32_t bebf_UNUSED bebf_tell (bebf_t *bebf) { return (((const uint8_t *)bebf->readptr - bebf->readstart) << 3) + bebf->readbits - 64; } /** * Seek forward to right after next appearence of sync pattern. * @param bebf pointer to bebf_t struct to use. * @param pattern the sync pattern to search for, right justified. * @param pbits bit length of pattern. * @return 1 (found), 0 (end of bitfile reached). */ static int bebf_UNUSED bebf_sync (bebf_t *bebf, uint32_t pattern, uint32_t pbits) { uint32_t _pat = pattern << (32 - pbits); uint32_t _mask = ~0U << (32 - pbits); if (bebf->readbits > 31) { bebf->readbits -= 32; if (bebf->readptr < bebf->readstop) { uint32_t v = bebf_ADJ32 (*(bebf->readptr)++); bebf->readcache |= (uint64_t)v << bebf->readbits; } } while (1) { if (bebf->readbits > 31) { uint32_t v; bebf->readbits -= 32; if (bebf->readptr >= bebf->readstop) return 0; v = bebf_ADJ32 (*(bebf->readptr)++); bebf->readcache |= v; } if (((bebf->readcache >> 32) & _mask) == _pat) break; bebf->readbits++; bebf->readcache <<= 1; } bebf->readbits += pbits; bebf->readcache <<= pbits; return 1; } /** * Write 1 .. 32 bits of data to write stream. * @param bebf pointer to bebf_t struct to use. * @param bits The data to write, right justified. * @param nbits bit count. */ static void bebf_UNUSED bebf_put (bebf_t *bebf, uint32_t bits, uint32_t nbits) { if (bebf->writebits < 33) { *(bebf->writeptr)++ = bebf_ADJ32 (bebf->writecache >> 32); bebf->writecache <<= 32; bebf->writebits += 32; } bebf->writebits -= nbits; bebf->writecache |= (uint64_t)bits << bebf->writebits; } /** * Flush out any unsaved data to write stream. * @param bebf pointer to bebf_t struct to use. * @return byte count of write buffer so far. */ static size_t bebf_UNUSED bebf_flush (bebf_t *bebf) { if (bebf->writebits < 33) { *(bebf->writeptr)++ = bebf_ADJ32 (bebf->writecache >> 32); bebf->writecache <<= 32; bebf->writebits += 32; } if (bebf->writebits < 64) { *(bebf->writeptr) = bebf_ADJ32 (bebf->writecache >> 32); } return ((uint8_t *)bebf->writeptr - bebf->writestart) + ((64 - bebf->writebits + 7) >> 3); } /** * Copy bits from read stream to write stream verbatim, and try to be fast. * @param bebf pointer to bebf_t struct to use. * @param nbits bit count. */ static void bebf_UNUSED bebf_copy (bebf_t *bebf, uint32_t nbits) { const uint32_t *p = bebf->readptr; uint32_t *q = bebf->writeptr; /* refill read */ if (bebf->readbits > 31) { bebf->readbits -= 32; bebf->readcache |= (uint64_t)bebf_ADJ32 (p[0]) << bebf->readbits; p++; } /* flush write */ if (bebf->writebits < 33) { *q = bebf_ADJ32 (bebf->writecache >> 32); bebf->writecache <<= 32; q++; bebf->writebits += 32; } /* staying inside cache? */ if (bebf->writebits >= (int32_t)nbits) { bebf->readptr = p; bebf->writeptr = q; bebf->writebits -= nbits; bebf->writecache |= (bebf->readcache >> (64 - nbits)) << bebf->writebits; bebf->readcache <<= nbits; bebf->readbits += nbits; return; } /* align write */ if (bebf->writebits < 64) { uint32_t n = bebf->writebits - 32; uint32_t b = bebf->readcache >> (64 - n); b |= bebf->writecache >> 32; *q = bebf_ADJ32 (b); q++; bebf->readcache <<= n; bebf->readbits += n; bebf->writebits = 64; nbits -= n; if (bebf->readbits > 31) { bebf->readbits -= 32; bebf->readcache |= (uint64_t)bebf_ADJ32 (p[0]) << bebf->readbits; p++; } } /* fast blocks */ if (nbits & ~31) { uint32_t words = nbits >> 5; switch ((64 - bebf->readbits) & 31) { /* If only my old Amiga blitter could see this :-)) */ #ifdef BEBF_X86_32_ASM # define bebf_shift(nn) { \ uint32_t hi = bebf->readcache >> 32, lo = bebf->readcache, dummy; \ do { \ __asm__ __volatile__ ( \ "movl\t%1, %4\n\t" \ "shldl\t%5, %0, %1\n\t" \ "bswap\t%4\n\t" \ "movl\t(%2), %0\n\t" \ "bswap\t%0\n\t" \ "movl\t%4, (%3)\n\t" \ "addl\t$4, %2\n\t" \ "leal\t4(%3), %3\n\t" \ "shldl\t%6, %0, %1\n\t" \ "sall\t%6, %0" \ : "=r" (lo), "=r" (hi), "=r" (p), "=r" (q), "=r" (dummy) \ : "I" (nn), "I" (32 - nn), "0" (lo), "1" (hi), "2" (p), "3" (q) \ : "cc"); \ } while (--words); \ bebf->readcache = ((uint64_t)hi << 32) | lo; \ } #else # define bebf_shift(nn) { \ uint64_t b = bebf->readcache; \ do {*q++ = bebf_ADJ32 (b >> 32); b <<= nn; b |= bebf_ADJ32 (*p++); b <<= 32 - nn;} while (--words); \ bebf->readcache = b; \ } #endif case 1: bebf_shift ( 1); break; case 2: bebf_shift ( 2); break; case 3: bebf_shift ( 3); break; case 4: bebf_shift ( 4); break; case 5: bebf_shift ( 5); break; case 6: bebf_shift ( 6); break; case 7: bebf_shift ( 7); break; case 9: bebf_shift ( 9); break; case 10: bebf_shift (10); break; case 11: bebf_shift (11); break; case 12: bebf_shift (12); break; case 13: bebf_shift (13); break; case 14: bebf_shift (14); break; case 15: bebf_shift (15); break; case 17: bebf_shift (17); break; case 18: bebf_shift (18); break; case 19: bebf_shift (19); break; case 20: bebf_shift (20); break; case 21: bebf_shift (21); break; case 22: bebf_shift (22); break; case 23: bebf_shift (23); break; case 25: bebf_shift (25); break; case 26: bebf_shift (26); break; case 27: bebf_shift (27); break; case 28: bebf_shift (28); break; case 29: bebf_shift (29); break; case 30: bebf_shift (30); break; case 31: bebf_shift (31); break; default: memcpy (q, (const uint8_t *)p - ((64 - bebf->readbits) >> 3), words << 2); p += words; q += words; bebf->readcache = (((uint64_t)bebf_ADJ32 (p[-2]) << 32) | bebf_ADJ32 (p[-1])) << bebf->readbits; } nbits &= 31; } /* tail bits */ if (nbits) { bebf->writecache = (bebf->readcache >> (64 - nbits)) << (64 - nbits); bebf->writebits = 64 - nbits; bebf->readcache <<= nbits; bebf->readbits += nbits; } else { bebf->writecache = 0; } bebf->readptr = p; bebf->writeptr = q; } /************************************************************************* * AAC config data parser * *************************************************************************/ typedef enum { AOT_AAC_MAIN = 1, /* Main */ AOT_AAC_LC = 2, /* Low Complexity */ AOT_AAC_SSR = 3, /* Scalable Sample Rate */ AOT_AAC_LTP = 4, /* Long Term Prediction */ AOT_SBR = 5, /* Spectral Band Replication */ AOT_AAC_SCALABLE = 6, /* Scalable */ AOT_TWINVQ = 7, /* Twin Vector Quantizer */ AOT_CELP = 8, /* Code Excited Linear Prediction */ AOT_HVXC = 9, /* Harmonic Vector eXcitation Coding */ AOT_ER_AAC_LC = 17, /* Error Resilient variants */ AOT_ER_AAC_LTP = 19, AOT_ER_AAC_SCALABLE = 20, AOT_ER_TWINVQ = 21, AOT_ER_BSAC = 22, /* Bit-Sliced Arithmetic Coding */ AOT_ER_AAC_LD = 23, /* Low Delay */ AOT_ER_CELP = 24, AOT_ER_HVXC = 25, AOT_ER_HILN = 26, /* Harmonic and Individual Lines plus Noise */ AOT_ER_PARAM = 27, /* Parametric */ AOT_SSC = 28, /* SinuSoidal Coding */ AOT_PS = 29, /* Parametric Stereo */ AOT_L1 = 32, /* Layer 1 */ AOT_L2 = 33, /* Layer 2 */ AOT_L3 = 34, /* Layer 3 */ AOT_ALS = 36, /* Audio LosslesS */ AOT_ER_AAC_ELD = 39 /* Enhanced Low Delay */ } bebf_aot_t; #define AOTF_SHORT 0x0001 /* frameLengthFlag */ #define AOTF_CORE 0x0002 /* dependsOnCoreCoder */ #define AOTF_EXT1 0x0004 /* extensionFlag1 */ #define AOTF_LAYER 0x0008 /* layerNr */ #define AOTF_CHAN 0x0010 /* custom channel layout */ #define AOTF_SUBFR 0x0020 /* subFrames */ #define AOTF_RESIL 0x0040 /* errorResilienceFlags */ #define AOTF_LDSBR 0x0080 /* lowDelaySbr */ #define AOTF_ELD 0x0100 /* enhancedLowDelay */ #define AOTF_EPCNF 0x0200 /* epConfig */ static const uint32_t bebf_latm_flags[40] = { 0, /* AOT_AAC_MAIN */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN, /* AOT_AAC_LC */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN, /* AOT_AAC_SSR */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN, /* AOT_AAC_LTP */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN, /* AOT_SBR */ 0, /* AOT_AAC_SCALABLE */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_LAYER|AOTF_CHAN, /* AOT_TWINVQ */ 0, /* AOT_CELP */ 0, /* AOT_HVXC */ 0, 0, 0, 0, 0, 0, 0, 0, /* AOT_ER_AAC_LC */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN|AOTF_RESIL|AOTF_EPCNF, 0, /* AOT_ER_AAC_LTP */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN|AOTF_RESIL|AOTF_EPCNF, /* AOT_ER_AAC_SCALABLE */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_LAYER|AOTF_CHAN|AOTF_RESIL|AOTF_EPCNF, /* AOT_ER_TWINVQ */ 0, /* AOT_ER_BSAC */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN|AOTF_SUBFR, /* AOT_ER_AAC_LD */ AOTF_SHORT|AOTF_CORE|AOTF_EXT1|AOTF_CHAN|AOTF_RESIL|AOTF_EPCNF, /* AOT_ER_CELP */ 0, /* AOT_ER_HVXC */ 0, /* AOT_ER_HILN */ 0, /* AOT_ER_PARAM */ 0, /* AOT_SSC */ 0, /* AOT_PS */ 0, 0, 0, /* AOT_L1 */ 0, /* AOT_L2 */ 0, /* AOT_L3 */ 0, 0, /* AOT_ALS */ 0, 0, 0, /* AOT_ER_AAC_ELD */ AOTF_SHORT|AOTF_RESIL|AOTF_LDSBR|AOTF_ELD|AOTF_EPCNF }; #define BEBF_LATM_GOT_CONF 1 #define BEBF_LATM_GOT_FRAME 2 typedef struct { bebf_t bebf; uint8_t *frame; uint32_t framelen, fbuflen; uint8_t *config; uint32_t conflen, confbuflen; uint32_t version; uint32_t frame_len_type, frame_len; bebf_aot_t object_type, object_type2; uint32_t samplerate_index, samplerate; uint32_t samplerate_index2, samplerate2; uint32_t samples; uint32_t channel_conf, numchannels; uint32_t channel_conf2; int32_t sbr, ps; } bebf_latm_t; /** * Parse and export AAC configuration data. * @param latm pointer to bebf_latm_t struct. * @param nbits count of input bits or 0. * @return BEBF_LATM_GOT_CONF or 0. */ static int bebf_UNUSED bebf_latm_configure (bebf_latm_t *latm, uint32_t nbits) { /* Aargh - LATM v0 does not provide config length, so we need to fully parse it ... */ static const uint32_t rates[16] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350, 0, 0, 0 }; static const uint8_t channels[16] = { 0, 1, 2, 3, 4, 5, 6, 8, 0, 0, 0, 0, 0, 0, 0, 0 }; uint32_t conf_pos = bebf_tell (&latm->bebf), conf_pos2; uint32_t n, ext1_flag, flags, ret = 0; /* object type */ latm->object_type = bebf_get (&latm->bebf, 5); if (latm->object_type == 31) latm->object_type = bebf_get (&latm->bebf, 6) + 32; /* sample rate */ latm->samplerate_index = bebf_get (&latm->bebf, 4); latm->samplerate = latm->samplerate_index == 15 ? bebf_get (&latm->bebf, 24) : rates[latm->samplerate_index]; /* channels */ latm->channel_conf = bebf_get (&latm->bebf, 4); latm->numchannels = channels[latm->channel_conf]; /* explicit sbr/ps */ latm->sbr = latm->ps = -1; n = 0; if (latm->object_type == AOT_SBR) { n = 1; } else if (latm->object_type == AOT_PS) { if ((latm->channel_conf == 1) && (bebf_sniff (&latm->bebf, 9) & 0x0ff)) { latm->ps = 1; n = 1; } } if (n) { latm->object_type2 = AOT_SBR; latm->sbr = 1; latm->samplerate_index2 = bebf_get (&latm->bebf, 4); latm->samplerate2 = latm->samplerate_index2 == 15 ? bebf_get (&latm->bebf, 24) : rates[latm->samplerate_index2]; latm->object_type = bebf_get (&latm->bebf, 5); if (latm->object_type == 31) latm->object_type = bebf_get (&latm->bebf, 6) + 32; if (latm->object_type == AOT_ER_BSAC) latm->channel_conf2 = bebf_get (&latm->bebf, 4); } else { latm->object_type2 = 0; latm->samplerate_index2 = 0; latm->samplerate2 = 0; } /* implicit ps */ if (latm->ps == -1) { if (!latm->sbr || (latm->object_type != AOT_AAC_LC)) latm->ps = 0; } /* more specific info */ conf_pos2 = bebf_tell (&latm->bebf); /* lossless audio */ if (latm->object_type == AOT_ALS) { bebf_skip (&latm->bebf, 5); conf_pos2 += 5; if (bebf_sniff (&latm->bebf, 24) != 0x414c53) { /* "ALS" */ bebf_skip (&latm->bebf, 24); conf_pos2 += 24; } /* sniff first frame head for correct settings */ if (bebf_get (&latm->bebf, 32) == 0x414c5300) { /* "ALS\0" */ latm->samplerate = bebf_get (&latm->bebf, 32); bebf_skip (&latm->bebf, 32); /* numSamples */ latm->channel_conf = 0; latm->numchannels = bebf_get (&latm->bebf, 16) + 1; } } n = latm->object_type; if (n > 39) n = 0; flags = bebf_latm_flags[n]; if (flags & AOTF_SHORT) /* frameLengthFlag */ latm->samples = bebf_get (&latm->bebf, 1) ? 960 : 1024; if (flags & AOTF_CORE) { /* dependsOnCoreCoder */ if (bebf_get (&latm->bebf, 1)) bebf_skip (&latm->bebf, 14); /* coreCoderDelay */ } ext1_flag = 2; if (flags & AOTF_EXT1) /* extensionFlag1 */ ext1_flag = bebf_get (&latm->bebf, 1); if (flags & AOTF_LAYER) /* layerNr */ bebf_skip (&latm->bebf, 3); if (flags & AOTF_CHAN) { /* custom channel layout */ if (!latm->channel_conf) { int front, side, back, lfe, data, coupling, n; /* program config element */ bebf_skip (&latm->bebf, 10); /* elementInstanceTag, objectType, Freq */ n = bebf_get (&latm->bebf, 4 + 4 + 4 + 2 + 3 + 4); front = n >> (4 + 4 + 2 + 3 + 4); side = (n >> ( 4 + 2 + 3 + 4)) & 15; back = (n >> ( 2 + 3 + 4)) & 15; lfe = (n >> ( 3 + 4)) & 3; data = (n >> 4 ) & 7; coupling = n & 15; latm->numchannels = front + side + back + lfe; if (bebf_get (&latm->bebf, 1)) bebf_skip (&latm->bebf, 4); /* mono downmix */ if (bebf_get (&latm->bebf, 1)) bebf_skip (&latm->bebf, 4); /* stereo downmix */ if (bebf_get (&latm->bebf, 1)) bebf_skip (&latm->bebf, 3); /* matrix downmix */ bebf_seek (&latm->bebf, bebf_tell (&latm->bebf) + 5 * (front + side + back + coupling) + 4 * (lfe + data)); /* comment text */ bebf_align (&latm->bebf); n = bebf_get (&latm->bebf, 8); bebf_seek (&latm->bebf, bebf_tell (&latm->bebf) + 8 * n); } } if (ext1_flag) { if (flags & AOTF_SUBFR) /* subFrames */ bebf_skip (&latm->bebf, 5 + 11); /* numSubFrames, layerLength */ if (flags & AOTF_RESIL) /* errorResilienceFlags */ bebf_skip (&latm->bebf, 3); if (ext1_flag == 1) bebf_skip (&latm->bebf, 1); /* extFlag3 */ } if (flags & AOTF_LDSBR) /* lowDelaySbr */ bebf_skip (&latm->bebf, 1); if (flags & AOTF_ELD) { /* enhancedLowDelay */ while (bebf_get (&latm->bebf, 4)) { n = bebf_get (&latm->bebf, 4); if (n == 15) { n += bebf_get (&latm->bebf, 8); if (n == 231) n += bebf_get (&latm->bebf, 16); } bebf_seek (&latm->bebf, bebf_tell (&latm->bebf) + 8 * n); } } if (flags & AOTF_EPCNF) /* epConfig */ bebf_skip (&latm->bebf, 2); conf_pos2 = bebf_tell (&latm->bebf); /* export config */ do { size_t l = (conf_pos2 - conf_pos + 7) >> 3; if (l > latm->confbuflen) { free (latm->config); latm->confbuflen = (3 * l / 2 + 7) & ~(size_t)7; latm->config = malloc (2 * (latm->confbuflen)); } if (!latm->config) break; bebf_set_write (&latm->bebf, latm->config); bebf_seek (&latm->bebf, conf_pos); bebf_copy (&latm->bebf, conf_pos2 - conf_pos); bebf_flush (&latm->bebf); ret = BEBF_LATM_GOT_CONF; if (latm->conflen == l) { if (!memcmp (latm->config, latm->config + latm->confbuflen, l)) ret = 0; } if (ret) memcpy (latm->config + latm->confbuflen, latm->config, l); latm->conflen = l; } while (0); bebf_seek (&latm->bebf, nbits ? conf_pos + nbits : conf_pos2); return ret; } /************************************************************************* * AAC LATM demuxer * *************************************************************************/ /** * Demultiplex 1 LATM packet. * @param latm pointer to bebf_latm_t struct. * @param in pointer to packet. * @param nbytes byte length of packet. * @return BEBF_LATM_GOT_* flags. */ static int bebf_UNUSED bebf_latm_demux (bebf_latm_t *latm, const uint8_t *in, uint32_t nbytes) { uint32_t ret = 0; bebf_set_read (&latm->bebf, in, nbytes); { /* latm sync */ uint32_t n = bebf_get (&latm->bebf, 24); if ((n >> 13) != 0x2b7) return 0; n &= 0x1fff; n += 3; if (n < nbytes) nbytes = n; } if (bebf_get (&latm->bebf, 1)) { /* same settings */ if (!latm->conflen) return 0; } else { /* new settings */ latm->version = bebf_get (&latm->bebf, 1); if (latm->version) latm->version += bebf_get (&latm->bebf, 1); if (latm->version < 2) { uint32_t n; /* some yet not mattering values */ if (latm->version) { n = bebf_get (&latm->bebf, 2); bebf_skip (&latm->bebf, 8 * n + 8); /* taraFullness */ } bebf_skip (&latm->bebf, 1 + 6); /* allStreamSameTimeFraming, numSubFrames */ /* part count (DVB uses 1:1) */ if (bebf_get (&latm->bebf, 4)) /* numPrograms */ return 0; if (bebf_get (&latm->bebf, 3)) /* numLayers */ return 0; /* config len */ n = 0; if (latm->version) { n = bebf_get (&latm->bebf, 2); n = bebf_get (&latm->bebf, 8 * n + 8); } /* extract config */ ret |= bebf_latm_configure (latm, n); /* frame len */ latm->frame_len_type = n = bebf_get (&latm->bebf, 3); if (n < 3) { if (n == 0) bebf_skip (&latm->bebf, 8); /* latmBufferFullness */ else if (n == 1) latm->frame_len = bebf_get (&latm->bebf, 9); /* fixed frameLength */ } else { if (n <= 5) bebf_skip (&latm->bebf, 6); /* CELP frame len index */ else bebf_skip (&latm->bebf, 1); /* HVXC frame len index */ } /* more extra stuff */ if (bebf_get (&latm->bebf, 1)) { /* other data present */ if (latm->version) { n = bebf_get (&latm->bebf, 2); bebf_skip (&latm->bebf, 8 * n + 8); } else { do { n = bebf_get (&latm->bebf, 1); bebf_skip (&latm->bebf, 8); } while (n); } } if (bebf_get (&latm->bebf, 1)) /* crc present */ bebf_skip (&latm->bebf, 8); } } if (latm->version < 2) { /* payload len */ uint32_t l = 0; if (latm->frame_len_type == 0) { uint32_t n; do { n = bebf_get (&latm->bebf, 8); l += n; } while (n == 255); latm->frame_len = l; /* variable frameLength */ } else if (latm->frame_len_type == 1) { l = latm->frame_len; } else if (latm->frame_len & 1) { /* 3, 5, 7 */ bebf_skip (&latm->bebf, 2); /* mux_slot_len_coded */ } } /* * Export frame. * @#?!*#$!! Looks like LATM actually appends the frame contents to the * bitstream without gap. They dont win much by not byte aligning it there!! * Some possible workarounds: * - Merge LATM demuxer and AAC decoder. Terribly complex code, ff does it * that way. * - Tell main decoding function to skip first 0..7 bits. Very easy, but * wont work with external libfaad. * - Bit shift whole frame. Thats what we do here. */ do { size_t n = nbytes - (bebf_tell (&latm->bebf) >> 3); if (n > latm->fbuflen) { free (latm->frame); latm->fbuflen = (3 * n / 2 + 7) & ~(size_t)7; latm->frame = malloc (latm->fbuflen); } if (!latm->frame) break; bebf_set_write (&latm->bebf, latm->frame); bebf_copy (&latm->bebf, 8 * nbytes - bebf_tell (&latm->bebf)); latm->framelen = bebf_flush (&latm->bebf); ret |= BEBF_LATM_GOT_FRAME; } while (0); return ret; } /************************************************************************* * AAC LATM parser * *************************************************************************/ static void bebf_UNUSED bebf_latm_open (bebf_latm_t *latm) { memset (latm, 0, sizeof (*latm)); } static void bebf_UNUSED bebf_latm_close (bebf_latm_t *latm) { free (latm->config); latm->config = NULL; free (latm->frame); latm->frame = NULL; latm->fbuflen = 0; latm->framelen = 0; } typedef enum { BEBF_LATM_NEED_MORE_DATA, BEBF_LATM_IS_RAW, BEBF_LATM_IS_ADTS, BEBF_LATM_IS_LATM, BEBF_LATM_IS_UNKNOWN } bebf_latm_parser_status_t; /** * Test if really LATM. * @param in pointer to input data. * @param nbytes byte count. * @return status. */ static bebf_latm_parser_status_t bebf_UNUSED bebf_latm_test (const uint8_t *in, int nbytes) { uint32_t word = 0; int n = nbytes; #define BEBF_TEST_MAX (2 * (0x1fff + 3)) if (n > BEBF_TEST_MAX) n = BEBF_TEST_MAX; while (n--) { word <<= 8; word |= *in++; if ((word & 0xfff60000) == 0xfff00000) do { /* ADTS */ int size; if (n < 7 - 4) break; size = ((word << 11) | ((uint32_t)in[0] << 3) | (in[1] >> 5)) & 0x1fff; if ((size < 7) || (n < size + 7 - 4)) break; if ((in[size - 4] != 0xff) || ((in[size + 1 - 4] & 0xf6) != 0xf0)) break; return BEBF_LATM_IS_ADTS; } while (0); if ((word & 0xffe00000) == 0x56e00000) do { /* LATM */ int size = ((word >> 8) & 0x1fff) + 3; if (n < size + 3 - 4) break; if ((in[size - 4] != 0x56) || ((in[size + 1 - 4] & 0xe0) != 0xe0)) break; return BEBF_LATM_IS_LATM; } while (0); } return nbytes < BEBF_TEST_MAX ? BEBF_LATM_NEED_MORE_DATA : BEBF_LATM_IS_UNKNOWN; } /** * Parse and demux LATM. * @param latm pointer to bebf_latm_t struct. * @param in pointer to input data. * @param nbytes pointer to byte count, will be adjusted to consumed. * @return BEBF_LATM_GOT_* flags. */ static int bebf_UNUSED bebf_latm_parse (bebf_latm_t *latm, const uint8_t *in, int *nbytes) { const uint8_t *p = in; int n = *nbytes, size; /* discard leading garbage */ n -= 2; while (n >= 0) { if (p[0] == 0x56) { if ((p[1] & 0xe0) == 0xe0) break; } p++; n--; } n += 2; *nbytes = p - in; if (n < 3) { if ((n == 1) && (p[0] != 0x56)) *nbytes += 1; return 0; } size = ((((uint32_t)p[1] << 8) | p[2]) & 0x1fff) + 3; if (n < size) return 0; *nbytes += size; return bebf_latm_demux (latm, p, size); } #undef LOG_MODULE ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/xine_a52_decoder.c�������������������������������������������������������0000644�0001750�0001750�00000055364�14647725152�016647� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stuff needed to turn liba52 into a xine decoder plugin */ #include "config.h" #include <stdlib.h> #include <string.h> #include <sys/types.h> #define LOG_MODULE "a52_decoder" #define LOG_VERBOSE /* #define LOG #define LOG_PTS */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #ifdef HAVE_A52DEC_A52_H # include <a52dec/a52.h> #else # include "a52.h" #endif #include <xine/buffer.h> #include <xine/xineutils.h> #if defined(LIBA52_FIXED) # define SAMPLE_OFFS 0 #elif defined(LIBA52_DOUBLE) # define SAMPLE_OFFS 48 #else # define SAMPLE_OFFS 384 #endif #undef DEBUG_A52 #ifdef DEBUG_A52 int a52file; #endif #include "xine_a52_parser.h" typedef struct { audio_decoder_class_t decoder_class; config_values_t *config; sample_t a52_level; int disable_dynrng_compress; int enable_surround_downmix; sample_t lfe_level_1; sample_t lfe_level_2; } a52dec_class_t; typedef struct a52dec_decoder_s { audio_decoder_t audio_decoder; a52dec_class_t *class; xine_stream_t *stream; int64_t pts; a52_state_t *a52_state; int have_lfe; int a52_flags_map[11]; int a52_flags_map_lfe[11]; int ao_flags_map[11]; int ao_flags_map_lfe[11]; int output_sampling_rate; int output_open; int output_mode; xine_a52_parser_t parser; } a52dec_decoder_t; static void a52dec_reset (audio_decoder_t *this_gen) { a52dec_decoder_t *this = xine_container_of(this_gen, a52dec_decoder_t, audio_decoder); xine_a52_parser_reset(&this->parser); this->pts = 0; } static void a52dec_discontinuity (audio_decoder_t *this_gen) { a52dec_decoder_t *this = xine_container_of(this_gen, a52dec_decoder_t, audio_decoder); this->pts = 0; } /* Note we write to the samples array here. This seems OK since liba52 itself does so when downmixing non-lfe channels. */ #if defined(LIBA52_FIXED) static inline void downmix_lfe_1 (sample_t *target, sample_t *lfe, sample_t gain) { int i; for (i = 0; i < 256; i++) target[i] += (lfe[i] * (int64_t)gain) >> 26; } static inline void downmix_lfe_2 (sample_t *target1, sample_t *target2, sample_t *lfe, sample_t gain) { int i; for (i = 0; i < 256; i++) { sample_t v = (lfe[i] * (int64_t)gain) >> 26; target1[i] += v; target2[i] += v; } } static inline void float_to_int (sample_t *_f, int16_t *s16, int num_channels) { int i; for (i = 0; i < 256; i++) { int32_t v = _f[i] >> (30 - 15); s16[num_channels * i] = (v + 0x8000) & ~0xffff ? (v >> 31) ^ 0x7fff : v; } } #elif defined(LIBA52_DOUBLE) static inline void downmix_lfe_1 (sample_t *target, sample_t *lfe, sample_t gain) { int i; for (i = 0; i < 256; i++) target[i] += (lfe[i] - 48.0) * gain; } static inline void downmix_lfe_2 (sample_t *target1, sample_t *target2, sample_t *lfe, sample_t gain) { int i; for (i = 0; i < 256; i++) { sample_t v = (lfe[i] - 48.0) * gain; target1[i] += v; target2[i] += v; } } static inline void float_to_int (sample_t *_f, int16_t *s16, int num_channels) { int i; /* HACK: assume IEEE double, then simplify (int32_t)((double)v * (1 << 15)) to * (int32_t)(<reinterpret_cast>(int64_t)((double)v + 48.0) >> 32) - 0x40480000. * This will work with -32.0 < v < 32.0 only, but liba52 hardly sends more than +/- 2.0. */ for (i = 0; i < 256; i++) { # ifdef WORDS_BIGENDIAN # define HI_INDEX 0 # else # define HI_INDEX 1 # endif union {sample_t s; int32_t i[2];} u; int32_t v; u.s = _f[i]; v = u.i[HI_INDEX] - 0x40480000; s16[num_channels * i] = (v + 0x8000) & ~0xffff ? (v >> 31) ^ 0x7fff : v; } } #else /* float */ static inline void downmix_lfe_1 (sample_t *target, sample_t *lfe, sample_t gain) { int i; for (i = 0; i < 256; i++) target[i] += (lfe[i] - 384.0) * gain; } static inline void downmix_lfe_2 (sample_t *target1, sample_t *target2, sample_t *lfe, sample_t gain) { int i; for (i = 0; i < 256; i++) { sample_t v = (lfe[i] - 384.0) * gain; target1[i] += v; target2[i] += v; } } static inline void float_to_int (sample_t *_f, int16_t *s16, int num_channels) { int i; /* XXX assumes IEEE float format, range -2.0 ... 2.0 */ for (i = 0; i < 256; i++) { union {sample_t s; int32_t i;} u; int32_t v; u.s = _f[i]; v = u.i - 0x43c00000; s16[num_channels * i] = (v + 0x8000) & ~0xffff ? (v >> 31) ^ 0x7fff : v; } } #endif static inline void mute_channel (int16_t * s16, int num_channels) { int i; for (i = 0; i < 256; i++) { s16[num_channels*i] = 0; } } static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts, int preview_mode) { int output_mode = AO_CAP_MODE_STEREO; int a52_output_flags, i; sample_t level = this->class->a52_level; audio_buffer_t *buf; int16_t *int_samples; sample_t *samples = a52_samples(this->a52_state); /* * do we want to decode this frame in software? */ #ifdef LOG_PTS printf("a52dec:decode_frame:pts=%lld\n",pts); #endif /* * oki, decode this frame in software */ /* determine output mode */ a52_output_flags = this->parser.a52_flags & A52_LFE ? this->a52_flags_map_lfe[this->parser.a52_flags & A52_CHANNEL_MASK] : this->a52_flags_map[this->parser.a52_flags]; if (a52_frame (this->a52_state, this->parser.frame_buffer, &a52_output_flags, &level, SAMPLE_OFFS)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: a52_frame error\n"); return; } if (this->class->disable_dynrng_compress) a52_dynrng (this->a52_state, NULL, NULL); this->have_lfe = a52_output_flags & A52_LFE; if (this->have_lfe) { output_mode = this->ao_flags_map_lfe[a52_output_flags & A52_CHANNEL_MASK]; samples += 256; } else output_mode = this->ao_flags_map[a52_output_flags]; /* * (re-)open output device */ if (!this->output_open || (this->parser.a52_sample_rate != this->output_sampling_rate) || (output_mode != this->output_mode)) { if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->parser.a52_sample_rate, output_mode) ; this->output_sampling_rate = this->parser.a52_sample_rate; this->output_mode = output_mode; } if (!this->output_open || preview_mode) return; /* * decode a52 and convert/interleave samples */ buf = this->stream->audio_out->get_buffer (this->stream->audio_out); int_samples = buf->mem; buf->num_frames = 256*6; for (i = 0; i < 6; i++) { if (a52_block (this->a52_state)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: a52_block error on audio channel %d\n", i); #if 0 for(n=0;n<2000;n++) { printf("%02x ",this->parser.frame_buffer[n]); if ((n % 32) == 0) printf("\n"); } printf("\n"); #endif buf->num_frames = 0; break; } /* We now have up to 6 groups of 256 samples each, in the order LFE L C R RL RR. Channels not present and/or not requested are simply left out (no gaps). Downmixing had only been applied to non-LFE stuff, so we need to do that one ourselves. */ switch (output_mode) { case AO_CAP_MODE_MONO: if (this->have_lfe) downmix_lfe_1 (&samples[0*256], &samples[-1*256], this->class->lfe_level_1); float_to_int (&samples[0], int_samples+(i*256), 1); break; case AO_CAP_MODE_STEREO: if (this->have_lfe) downmix_lfe_2 (&samples[0*256], &samples[1*256], &samples[-1*256], this->class->lfe_level_2); float_to_int (&samples[0*256], int_samples+(i*256*2), 2); float_to_int (&samples[1*256], int_samples+(i*256*2)+1, 2); break; case AO_CAP_MODE_4CHANNEL: if (this->have_lfe) downmix_lfe_2 (&samples[0*256], &samples[1*256], &samples[-1*256], this->class->lfe_level_2); float_to_int (&samples[0*256], int_samples+(i*256*4), 4); /* L */ float_to_int (&samples[1*256], int_samples+(i*256*4)+1, 4); /* R */ float_to_int (&samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */ float_to_int (&samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */ break; case AO_CAP_MODE_4_1CHANNEL: if (this->have_lfe) float_to_int (&samples[-1*256], int_samples+(i*256*6)+5, 6); /* LFE */ else mute_channel (int_samples+(i*256*6)+5, 6); float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ float_to_int (&samples[1*256], int_samples+(i*256*6)+1, 6); /* R */ float_to_int (&samples[2*256], int_samples+(i*256*6)+2, 6); /* RL */ float_to_int (&samples[3*256], int_samples+(i*256*6)+3, 6); /* RR */ mute_channel ( int_samples+(i*256*6)+4, 6); /* C */ break; case AO_CAP_MODE_5CHANNEL: if (this->have_lfe) downmix_lfe_2 (&samples[0*256], &samples[2*256], &samples[-1*256], this->class->lfe_level_2); float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ float_to_int (&samples[1*256], int_samples+(i*256*6)+4, 6); /* C */ float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ mute_channel ( int_samples+(i*256*6)+5, 6); /* LFE */ break; case AO_CAP_MODE_5_1CHANNEL: if (this->have_lfe) float_to_int (&samples[-1*256], int_samples+(i*256*6)+5, 6); /* lfe */ else mute_channel (int_samples+(i*256*6)+5, 6); float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ float_to_int (&samples[1*256], int_samples+(i*256*6)+4, 6); /* C */ float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ break; default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "liba52: help - unsupported mode %08x\n", output_mode); } } lprintf ("%d frames output\n", buf->num_frames); /* output decoded samples */ buf->vpts = pts; this->stream->audio_out->put_buffer (this->stream->audio_out, buf, this->stream); } static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { a52dec_decoder_t *this = xine_container_of(this_gen, a52dec_decoder_t, audio_decoder); lprintf ("decode data %d bytes of type %08x, pts=%"PRId64"\n", buf->size, buf->type, buf->pts); lprintf ("decode data decoder_info=%d, %d\n",buf->decoder_info[1],buf->decoder_info[2]); if (buf->decoder_flags & BUF_FLAG_HEADER) return; /* swap byte pairs if this is RealAudio DNET data */ if (buf->type == BUF_AUDIO_DNET) { do_swab(buf->content, buf->content + buf->size); } /* A52 packs come from the DVD in blocks of about 2048 bytes. * Only 1 PTS values can be assigned to each block. * An A52 frame is about 1700 bytes long. * So, a single A52 packs can contain 2 A52 frames (or the beginning of an A52 frame at least). * If we have a PTS value, which A52 frame does it apply to? The A52 pack tells us that. * So, the info about which A52 frame the PTS applies to is contained in decoder_info sent from the demuxer. * * The PTS value from the A52 pack (DVD sector) can only be applied at the start of an A52 frame. * We call the start of an A52 frame a frame header. * So, if a A52 pack has 2 "Number of frame headers" is means that the A52 pack contains 2 A52 frame headers. * The "First access unit" then tells us which A52 frame the PTS value applies to. * * Take the following example: - * PACK1: PTS = 10. Contains the entire A52 frame1, followed by the beginning of the frame2. PTS applies to frame1. * PACK2: PTS = 1000, Contains the rest of frame2, and the whole of frame3. and the start of frame4. PTS applies to frame4. * PACK3: PTS = 0 (none), Contains the rest of frame4. * * Output should be: - * frame1, PTS=10 * frame2, PTS=0 * frame3, PTS=0 * frame4, PTS=1000 * * So, we have to keep track of PTS values from previous A52 packs here, otherwise they get put on the wrong frame. */ /* FIXME: the code here does not match the explanation above */ if (buf->pts) { this->pts = buf->pts; } #if 0 for(n=0;n < buf->size;n++) { if ((n % 32) == 0) printf("\n"); printf("%x ", current[n]); } printf("\n"); #endif lprintf ("processing...state %d\n", this->parser.sync_state); while (buf->size > 0) { int consumed = xine_a52_parse_data(&this->parser, this->stream, buf->content, buf->size); buf->content += consumed; buf->size -= consumed; if (this->parser.got_frame) { a52dec_decode_frame (this, this->pts, buf->decoder_flags & BUF_FLAG_PREVIEW); this->pts = 0; #ifdef DEBUG_A52 write (a52file, this->parser.frame_buffer, this->parser.frame_length); #endif } } } static void a52dec_dispose (audio_decoder_t *this_gen) { a52dec_decoder_t *this = xine_container_of(this_gen, a52dec_decoder_t, audio_decoder); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; a52_free(this->a52_state); this->a52_state = NULL; #ifdef DEBUG_A52 close (a52file); #endif free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { a52dec_decoder_t *this ; int audio_caps; lprintf ("open_plugin called\n"); this = calloc(1, sizeof (a52dec_decoder_t)); if (!this) return NULL; /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ xine_a52_parser_reset(&this->parser); this->output_open = 0; this->pts = 0; this->audio_decoder.decode_data = a52dec_decode_data; this->audio_decoder.reset = a52dec_reset; this->audio_decoder.discontinuity = a52dec_discontinuity; this->audio_decoder.dispose = a52dec_dispose; this->stream = stream; this->class = (a52dec_class_t *)class_gen; audio_caps = stream->audio_out->get_capabilities (stream->audio_out); if( !this->a52_state ) { this->a52_state = #ifdef HAVE_A52DEC_A52_H /* External liba52 */ # ifdef HAVE_A52_INIT_VOID a52_init () # else /* When using external liba52, enable _all_ capabilities, even if that might break stuff if they add some new capability that depends on CPU's caps. At the moment the only capability is DJBFFT, which is tested only if djbfft is being used at compile time. The actual question would be: why don't they check for capabilities themselves? */ a52_init (0xFFFFFFFF) # endif #else a52_init (xine_mm_accel()) #endif ; } /* * find out if this driver supports a52 output * or, if not, how many channels we've got */ const int modes[] = { AO_CAP_MODE_MONO, A52_MONO, AO_CAP_MODE_STEREO, A52_STEREO, AO_CAP_MODE_4CHANNEL, A52_2F2R, AO_CAP_MODE_4_1CHANNEL, A52_2F2R | A52_LFE, AO_CAP_MODE_5CHANNEL, A52_3F2R, AO_CAP_MODE_5_1CHANNEL, A52_3F2R | A52_LFE }, wishlist[] = { A52_MONO, 0, 2, 4, 6, 8, 10, A52_STEREO, 2, 4, 6, 8, 10, 0, A52_3F, 8, 10, 2, 4, 6, 0, A52_2F1R, 4, 6, 8, 10, 2, 0, A52_3F1R, 8, 10, 4, 6, 2, 0, A52_2F2R, 4, 6, 8, 10, 2, 0, A52_3F2R, 8, 10, 4, 6, 2, 0, A52_DOLBY, 2, 4, 6, 8, 10, 0, /* same thing again with lfe */ A52_MONO, 6, 10, 0, 2, 4, 8, A52_STEREO, 6, 10, 2, 4, 8, 0, A52_3F, 10, 6, 8, 2, 4, 0, A52_2F1R, 6, 10, 4, 8, 2, 0, A52_3F1R, 10, 6, 8, 4, 2, 0, A52_2F2R, 6, 10, 4, 8, 2, 0, A52_3F2R, 10, 6, 8, 4, 2, 0, A52_DOLBY, 2, 4, 6, 8, 10, 0 }; int i, j; /* guard against weird audio out */ if (!(audio_caps & (AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO | AO_CAP_MODE_4CHANNEL | AO_CAP_MODE_4_1CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL))) audio_caps |= AO_CAP_MODE_MONO; /* find best mode */ for (i = 0; i < 8 * 7; i += 7) { for (j = 1; j < 7; j++) { if (audio_caps & modes[wishlist[i + j]]) { this->a52_flags_map[wishlist[i]] = modes[wishlist[i + j] + 1]; this->ao_flags_map[wishlist[i]] = modes[wishlist[i + j]]; break; } } } /* Always request extra bass. Liba52 will discard it if we dont. */ /* Instead, downmix it manually if present and audio out does not support it. */ for (; i < 16 * 7; i += 7) { for (j = 1; j < 7; j++) { if (audio_caps & modes[wishlist[i + j]]) { this->a52_flags_map_lfe[wishlist[i]] = modes[wishlist[i + j] + 1] | A52_LFE; this->ao_flags_map_lfe[wishlist[i]] = modes[wishlist[i + j]]; break; } } } /* downmix to analogue dematrix? */ if (this->class->enable_surround_downmix) { for (i = 0; i < 11; i++) { if (this->a52_flags_map[i] == A52_STEREO) this->a52_flags_map[i] = A52_DOLBY; if (this->a52_flags_map_lfe[i] == (A52_STEREO | A52_LFE)) this->a52_flags_map_lfe[i] = A52_DOLBY | A52_LFE; } } if (this->ao_flags_map[A52_STEREO] == AO_CAP_MODE_MONO) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("HELP! a mono-only audio driver?!\n")); } /* for (i = 0; i<8; i++) this->a52_flags_map[i] |= A52_ADJUST_LEVEL; */ #ifdef DEBUG_A52 a52file = xine_create_cloexec("test.a52", O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); #endif return &this->audio_decoder; } static void dispose_class (audio_decoder_class_t *this_gen) { a52dec_class_t *this = (a52dec_class_t *)this_gen; config_values_t *config = this->config; config->unregister_callbacks (config, NULL, NULL, this, sizeof (*this)); free (this); } static void lfe_level_change_cb (void *this_gen, xine_cfg_entry_t *entry) { a52dec_class_t *this = (a52dec_class_t *)this_gen; #ifdef LIBA52_FIXED this->lfe_level_1 = ((1 << 26) * 0.7 / 100.0) * entry->num_value; this->lfe_level_2 = ((1 << 26) * 0.5 / 100.0) * entry->num_value; #else this->lfe_level_1 = (0.7 / 100.0) * entry->num_value; this->lfe_level_2 = (0.5 / 100.0) * entry->num_value; #endif } static void a52_level_change_cb (void *this_gen, xine_cfg_entry_t *entry) { a52dec_class_t *this = (a52dec_class_t *)this_gen; #ifdef LIBA52_FIXED this->a52_level = ((1 << 26) / 100.0) * entry->num_value; #else this->a52_level = (1.0 / 100.0) * entry->num_value; #endif } static void dynrng_compress_change_cb (void *this_gen, xine_cfg_entry_t *entry) { ((a52dec_class_t *)this_gen)->disable_dynrng_compress = !entry->num_value; } static void surround_downmix_change_cb (void *this_gen, xine_cfg_entry_t *entry) { ((a52dec_class_t *)this_gen)->enable_surround_downmix = entry->num_value; } static void *init_plugin (xine_t *xine, const void *data) { a52dec_class_t *this; config_values_t *cfg; (void)data; this = calloc(1, sizeof (a52dec_class_t)); if (!this) return NULL; this->decoder_class.open_plugin = open_plugin; this->decoder_class.identifier = "a/52dec"; this->decoder_class.description = N_("liba52 based a52 audio decoder plugin"); this->decoder_class.dispose = dispose_class; cfg = this->config = xine->config; { int v = cfg->register_range (cfg, "audio.a52.level", 100, 0, 200, _("A/52 volume"), _("With A/52 audio, you can modify the volume at the decoder level. This has the advantage " "of the audio being already decoded for the specified volume, so later operations like " "channel downmixing will work on an audio stream of the given volume."), 10, a52_level_change_cb, this); #ifdef LIBA52_FIXED this->a52_level = ((1 << 26) / 100.0) * v; #else this->a52_level = (1.0 / 100.0) * v; #endif } this->disable_dynrng_compress = !cfg->register_bool (cfg, "audio.a52.dynamic_range", 0, _("use A/52 dynamic range compression"), _("Dynamic range compression limits the dynamic range of the audio. This means making the loud " "sounds softer, and the soft sounds louder, so you can more easily listen to the audio in a noisy " "environment without disturbing anyone."), 0, dynrng_compress_change_cb, this); this->enable_surround_downmix = cfg->register_bool (cfg, "audio.a52.surround_downmix", 0, _("downmix audio to 2 channel surround stereo"), _("When you want to listen to multichannel surround sound, but you have only two speakers or a " "surround decoder or amplifier which does some sort of matrix surround decoding like prologic, " "you should enable this option so that the additional channels are mixed into the stereo signal."), 0, surround_downmix_change_cb, this); { int v = cfg->register_range (cfg, "audio.a52.lfe_level", 100, 0, 200, _("A/52 bass downmix volume"), _("Use this volume to mix in the bass effect,\n" "if you have large stereo speakers\n" "or an analogue subwoofer."), 10, lfe_level_change_cb, this); #ifdef LIBA52_FIXED this->lfe_level_1 = ((1 << 26) * 0.7 / 100.0) * v; this->lfe_level_2 = ((1 << 26) * 0.5 / 100.0) * v; #else this->lfe_level_1 = (0.7 / 100.0) * v; this->lfe_level_2 = (0.5 / 100.0) * v; #endif } lprintf ("init_plugin called\n"); return this; } static const uint32_t audio_types[] = { BUF_AUDIO_A52, BUF_AUDIO_DNET, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 8, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 16, "a/52", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/ff_dvdata.h��������������������������������������������������������������0000644�0001750�0001750�00000326500�14647725152�015464� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Constants for DV codec * 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 dvdata.h * Constants for DV codec. */ #ifndef FFMPEG_DVDATA_H #define FFMPEG_DVDATA_H typedef struct { int num, den; } AVRational; /* TJ. This is a fairly old snapshot. Dont mess it up by including a recent avcodec.h, and put a little outtake from it here. */ enum PixelFormat { PIX_FMT_YUV420P = 0, PIX_FMT_YUV422P = 4, PIX_FMT_YUV411P = 7 }; /* * DVprofile 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 DVprofile { int dsf; /* value of the dsf in the DV header */ 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 */ int frame_rate; int frame_rate_base; 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 */ const uint16_t *video_place; /* positions of all DV macro blocks */ enum PixelFormat pix_fmt; /* picture pixel format */ int audio_stride; /* size of audio_shuffle table */ int audio_min_samples[3];/* min ammount 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 */ } DVprofile; #define NB_DV_VLC 409 /* * There's a catch about the following three tables: the mapping they establish * between (run, level) and vlc is not 1-1. So you have to watch out for that * when building misc. tables. E.g. (1, 0) can be either 0x7cf or 0x1f82. */ static const uint16_t dv_vlc_bits[409] = { 0x0000, 0x0002, 0x0007, 0x0008, 0x0009, 0x0014, 0x0015, 0x0016, 0x0017, 0x0030, 0x0031, 0x0032, 0x0033, 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x01e0, 0x01e1, 0x01e2, 0x01e3, 0x01e4, 0x01e5, 0x01e6, 0x01e7, 0x01e8, 0x01e9, 0x01ea, 0x01eb, 0x01ec, 0x01ed, 0x01ee, 0x01ef, 0x03e0, 0x03e1, 0x03e2, 0x03e3, 0x03e4, 0x03e5, 0x03e6, 0x07ce, 0x07cf, 0x07d0, 0x07d1, 0x07d2, 0x07d3, 0x07d4, 0x07d5, 0x0fac, 0x0fad, 0x0fae, 0x0faf, 0x0fb0, 0x0fb1, 0x0fb2, 0x0fb3, 0x0fb4, 0x0fb5, 0x0fb6, 0x0fb7, 0x0fb8, 0x0fb9, 0x0fba, 0x0fbb, 0x0fbc, 0x0fbd, 0x0fbe, 0x0fbf, 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, 0x1f90, 0x1f91, 0x1f92, 0x1f93, 0x1f94, 0x1f95, 0x1f96, 0x1f97, 0x1f98, 0x1f99, 0x1f9a, 0x1f9b, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa0, 0x1fa1, 0x1fa2, 0x1fa3, 0x1fa4, 0x1fa5, 0x1fa6, 0x1fa7, 0x1fa8, 0x1fa9, 0x1faa, 0x1fab, 0x1fac, 0x1fad, 0x1fae, 0x1faf, 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, 0x1fb5, 0x1fb6, 0x1fb7, 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, 0x1fbd, 0x1fbe, 0x1fbf, 0x7f00, 0x7f01, 0x7f02, 0x7f03, 0x7f04, 0x7f05, 0x7f06, 0x7f07, 0x7f08, 0x7f09, 0x7f0a, 0x7f0b, 0x7f0c, 0x7f0d, 0x7f0e, 0x7f0f, 0x7f10, 0x7f11, 0x7f12, 0x7f13, 0x7f14, 0x7f15, 0x7f16, 0x7f17, 0x7f18, 0x7f19, 0x7f1a, 0x7f1b, 0x7f1c, 0x7f1d, 0x7f1e, 0x7f1f, 0x7f20, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, 0x7f28, 0x7f29, 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f, 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x7f35, 0x7f36, 0x7f37, 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, 0x7f3f, 0x7f40, 0x7f41, 0x7f42, 0x7f43, 0x7f44, 0x7f45, 0x7f46, 0x7f47, 0x7f48, 0x7f49, 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, 0x7f50, 0x7f51, 0x7f52, 0x7f53, 0x7f54, 0x7f55, 0x7f56, 0x7f57, 0x7f58, 0x7f59, 0x7f5a, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f5f, 0x7f60, 0x7f61, 0x7f62, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f67, 0x7f68, 0x7f69, 0x7f6a, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6e, 0x7f6f, 0x7f70, 0x7f71, 0x7f72, 0x7f73, 0x7f74, 0x7f75, 0x7f76, 0x7f77, 0x7f78, 0x7f79, 0x7f7a, 0x7f7b, 0x7f7c, 0x7f7d, 0x7f7e, 0x7f7f, 0x7f80, 0x7f81, 0x7f82, 0x7f83, 0x7f84, 0x7f85, 0x7f86, 0x7f87, 0x7f88, 0x7f89, 0x7f8a, 0x7f8b, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f, 0x7f90, 0x7f91, 0x7f92, 0x7f93, 0x7f94, 0x7f95, 0x7f96, 0x7f97, 0x7f98, 0x7f99, 0x7f9a, 0x7f9b, 0x7f9c, 0x7f9d, 0x7f9e, 0x7f9f, 0x7fa0, 0x7fa1, 0x7fa2, 0x7fa3, 0x7fa4, 0x7fa5, 0x7fa6, 0x7fa7, 0x7fa8, 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7faf, 0x7fb0, 0x7fb1, 0x7fb2, 0x7fb3, 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, 0x7fb8, 0x7fb9, 0x7fba, 0x7fbb, 0x7fbc, 0x7fbd, 0x7fbe, 0x7fbf, 0x7fc0, 0x7fc1, 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc5, 0x7fc6, 0x7fc7, 0x7fc8, 0x7fc9, 0x7fca, 0x7fcb, 0x7fcc, 0x7fcd, 0x7fce, 0x7fcf, 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd4, 0x7fd5, 0x7fd6, 0x7fd7, 0x7fd8, 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fdf, 0x7fe0, 0x7fe1, 0x7fe2, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7, 0x7fe8, 0x7fe9, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fee, 0x7fef, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, 0x7ff8, 0x7ff9, 0x7ffa, 0x7ffb, 0x7ffc, 0x7ffd, 0x7ffe, 0x7fff, 0x0006, }; static const uint8_t dv_vlc_len[409] = { 2, 3, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 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, 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, 4, }; static const uint8_t dv_vlc_run[409] = { 0, 0, 1, 0, 0, 2, 1, 0, 0, 3, 4, 0, 0, 5, 6, 2, 1, 1, 0, 0, 0, 7, 8, 9, 10, 3, 4, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 11, 12, 13, 14, 5, 6, 3, 4, 2, 2, 1, 0, 0, 0, 0, 0, 5, 3, 3, 2, 1, 1, 1, 0, 1, 6, 4, 3, 1, 1, 1, 2, 3, 4, 5, 7, 8, 9, 10, 7, 8, 4, 3, 2, 2, 2, 2, 2, 1, 1, 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, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 127, }; static const uint8_t dv_vlc_level[409] = { 1, 2, 1, 3, 4, 1, 2, 5, 6, 1, 1, 7, 8, 1, 1, 2, 3, 4, 9, 10, 11, 1, 1, 1, 1, 2, 2, 3, 5, 6, 7, 12, 13, 14, 15, 16, 17, 1, 1, 1, 1, 2, 2, 3, 3, 4, 5, 8, 18, 19, 20, 21, 22, 3, 4, 5, 6, 9, 10, 11, 0, 0, 3, 4, 6, 12, 13, 14, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 5, 7, 7, 8, 9, 10, 11, 15, 16, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 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, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 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, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 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, 0, }; /* unquant tables (not used directly) */ static const uint8_t dv_88_areas[64] = { 0,0,0,1,1,1,2,2, 0,0,1,1,1,2,2,2, 0,1,1,1,2,2,2,3, 1,1,1,2,2,2,3,3, 1,1,2,2,2,3,3,3, 1,2,2,2,3,3,3,3, 2,2,2,3,3,3,3,3, 2,2,3,3,3,3,3,3, }; static const uint8_t dv_248_areas[64] = { 0,0,1,1,1,2,2,3, 0,0,1,1,2,2,2,3, 0,1,1,2,2,2,3,3, 0,1,1,2,2,2,3,3, 1,1,2,2,2,3,3,3, 1,1,2,2,2,3,3,3, 1,2,2,2,3,3,3,3, 1,2,2,3,3,3,3,3, }; static const uint8_t dv_quant_shifts[22][4] = { { 3,3,4,4 }, { 3,3,4,4 }, { 2,3,3,4 }, { 2,3,3,4 }, { 2,2,3,3 }, { 2,2,3,3 }, { 1,2,2,3 }, { 1,2,2,3 }, { 1,1,2,2 }, { 1,1,2,2 }, { 0,1,1,2 }, { 0,1,1,2 }, { 0,0,1,1 }, { 0,0,1,1 }, { 0,0,0,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 }, }; static const uint8_t dv_quant_offset[4] = { 6, 3, 0, 1 }; /* NOTE: I prefer hardcoding the positionning of dv blocks, it is simpler :-) */ static const uint16_t dv_place_420[1620] = { 0x0c24, 0x2412, 0x3036, 0x0000, 0x1848, 0x0e24, 0x2612, 0x3236, 0x0200, 0x1a48, 0x1024, 0x2812, 0x3436, 0x0400, 0x1c48, 0x1026, 0x2814, 0x3438, 0x0402, 0x1c4a, 0x0e26, 0x2614, 0x3238, 0x0202, 0x1a4a, 0x0c26, 0x2414, 0x3038, 0x0002, 0x184a, 0x0c28, 0x2416, 0x303a, 0x0004, 0x184c, 0x0e28, 0x2616, 0x323a, 0x0204, 0x1a4c, 0x1028, 0x2816, 0x343a, 0x0404, 0x1c4c, 0x102a, 0x2818, 0x343c, 0x0406, 0x1c4e, 0x0e2a, 0x2618, 0x323c, 0x0206, 0x1a4e, 0x0c2a, 0x2418, 0x303c, 0x0006, 0x184e, 0x0c2c, 0x241a, 0x303e, 0x0008, 0x1850, 0x0e2c, 0x261a, 0x323e, 0x0208, 0x1a50, 0x102c, 0x281a, 0x343e, 0x0408, 0x1c50, 0x102e, 0x281c, 0x3440, 0x040a, 0x1c52, 0x0e2e, 0x261c, 0x3240, 0x020a, 0x1a52, 0x0c2e, 0x241c, 0x3040, 0x000a, 0x1852, 0x0c30, 0x241e, 0x3042, 0x000c, 0x1854, 0x0e30, 0x261e, 0x3242, 0x020c, 0x1a54, 0x1030, 0x281e, 0x3442, 0x040c, 0x1c54, 0x1032, 0x2820, 0x3444, 0x040e, 0x1c56, 0x0e32, 0x2620, 0x3244, 0x020e, 0x1a56, 0x0c32, 0x2420, 0x3044, 0x000e, 0x1856, 0x0c34, 0x2422, 0x3046, 0x0010, 0x1858, 0x0e34, 0x2622, 0x3246, 0x0210, 0x1a58, 0x1034, 0x2822, 0x3446, 0x0410, 0x1c58, 0x1224, 0x2a12, 0x3636, 0x0600, 0x1e48, 0x1424, 0x2c12, 0x3836, 0x0800, 0x2048, 0x1624, 0x2e12, 0x3a36, 0x0a00, 0x2248, 0x1626, 0x2e14, 0x3a38, 0x0a02, 0x224a, 0x1426, 0x2c14, 0x3838, 0x0802, 0x204a, 0x1226, 0x2a14, 0x3638, 0x0602, 0x1e4a, 0x1228, 0x2a16, 0x363a, 0x0604, 0x1e4c, 0x1428, 0x2c16, 0x383a, 0x0804, 0x204c, 0x1628, 0x2e16, 0x3a3a, 0x0a04, 0x224c, 0x162a, 0x2e18, 0x3a3c, 0x0a06, 0x224e, 0x142a, 0x2c18, 0x383c, 0x0806, 0x204e, 0x122a, 0x2a18, 0x363c, 0x0606, 0x1e4e, 0x122c, 0x2a1a, 0x363e, 0x0608, 0x1e50, 0x142c, 0x2c1a, 0x383e, 0x0808, 0x2050, 0x162c, 0x2e1a, 0x3a3e, 0x0a08, 0x2250, 0x162e, 0x2e1c, 0x3a40, 0x0a0a, 0x2252, 0x142e, 0x2c1c, 0x3840, 0x080a, 0x2052, 0x122e, 0x2a1c, 0x3640, 0x060a, 0x1e52, 0x1230, 0x2a1e, 0x3642, 0x060c, 0x1e54, 0x1430, 0x2c1e, 0x3842, 0x080c, 0x2054, 0x1630, 0x2e1e, 0x3a42, 0x0a0c, 0x2254, 0x1632, 0x2e20, 0x3a44, 0x0a0e, 0x2256, 0x1432, 0x2c20, 0x3844, 0x080e, 0x2056, 0x1232, 0x2a20, 0x3644, 0x060e, 0x1e56, 0x1234, 0x2a22, 0x3646, 0x0610, 0x1e58, 0x1434, 0x2c22, 0x3846, 0x0810, 0x2058, 0x1634, 0x2e22, 0x3a46, 0x0a10, 0x2258, 0x1824, 0x3012, 0x3c36, 0x0c00, 0x2448, 0x1a24, 0x3212, 0x3e36, 0x0e00, 0x2648, 0x1c24, 0x3412, 0x4036, 0x1000, 0x2848, 0x1c26, 0x3414, 0x4038, 0x1002, 0x284a, 0x1a26, 0x3214, 0x3e38, 0x0e02, 0x264a, 0x1826, 0x3014, 0x3c38, 0x0c02, 0x244a, 0x1828, 0x3016, 0x3c3a, 0x0c04, 0x244c, 0x1a28, 0x3216, 0x3e3a, 0x0e04, 0x264c, 0x1c28, 0x3416, 0x403a, 0x1004, 0x284c, 0x1c2a, 0x3418, 0x403c, 0x1006, 0x284e, 0x1a2a, 0x3218, 0x3e3c, 0x0e06, 0x264e, 0x182a, 0x3018, 0x3c3c, 0x0c06, 0x244e, 0x182c, 0x301a, 0x3c3e, 0x0c08, 0x2450, 0x1a2c, 0x321a, 0x3e3e, 0x0e08, 0x2650, 0x1c2c, 0x341a, 0x403e, 0x1008, 0x2850, 0x1c2e, 0x341c, 0x4040, 0x100a, 0x2852, 0x1a2e, 0x321c, 0x3e40, 0x0e0a, 0x2652, 0x182e, 0x301c, 0x3c40, 0x0c0a, 0x2452, 0x1830, 0x301e, 0x3c42, 0x0c0c, 0x2454, 0x1a30, 0x321e, 0x3e42, 0x0e0c, 0x2654, 0x1c30, 0x341e, 0x4042, 0x100c, 0x2854, 0x1c32, 0x3420, 0x4044, 0x100e, 0x2856, 0x1a32, 0x3220, 0x3e44, 0x0e0e, 0x2656, 0x1832, 0x3020, 0x3c44, 0x0c0e, 0x2456, 0x1834, 0x3022, 0x3c46, 0x0c10, 0x2458, 0x1a34, 0x3222, 0x3e46, 0x0e10, 0x2658, 0x1c34, 0x3422, 0x4046, 0x1010, 0x2858, 0x1e24, 0x3612, 0x4236, 0x1200, 0x2a48, 0x2024, 0x3812, 0x4436, 0x1400, 0x2c48, 0x2224, 0x3a12, 0x4636, 0x1600, 0x2e48, 0x2226, 0x3a14, 0x4638, 0x1602, 0x2e4a, 0x2026, 0x3814, 0x4438, 0x1402, 0x2c4a, 0x1e26, 0x3614, 0x4238, 0x1202, 0x2a4a, 0x1e28, 0x3616, 0x423a, 0x1204, 0x2a4c, 0x2028, 0x3816, 0x443a, 0x1404, 0x2c4c, 0x2228, 0x3a16, 0x463a, 0x1604, 0x2e4c, 0x222a, 0x3a18, 0x463c, 0x1606, 0x2e4e, 0x202a, 0x3818, 0x443c, 0x1406, 0x2c4e, 0x1e2a, 0x3618, 0x423c, 0x1206, 0x2a4e, 0x1e2c, 0x361a, 0x423e, 0x1208, 0x2a50, 0x202c, 0x381a, 0x443e, 0x1408, 0x2c50, 0x222c, 0x3a1a, 0x463e, 0x1608, 0x2e50, 0x222e, 0x3a1c, 0x4640, 0x160a, 0x2e52, 0x202e, 0x381c, 0x4440, 0x140a, 0x2c52, 0x1e2e, 0x361c, 0x4240, 0x120a, 0x2a52, 0x1e30, 0x361e, 0x4242, 0x120c, 0x2a54, 0x2030, 0x381e, 0x4442, 0x140c, 0x2c54, 0x2230, 0x3a1e, 0x4642, 0x160c, 0x2e54, 0x2232, 0x3a20, 0x4644, 0x160e, 0x2e56, 0x2032, 0x3820, 0x4444, 0x140e, 0x2c56, 0x1e32, 0x3620, 0x4244, 0x120e, 0x2a56, 0x1e34, 0x3622, 0x4246, 0x1210, 0x2a58, 0x2034, 0x3822, 0x4446, 0x1410, 0x2c58, 0x2234, 0x3a22, 0x4646, 0x1610, 0x2e58, 0x2424, 0x3c12, 0x0036, 0x1800, 0x3048, 0x2624, 0x3e12, 0x0236, 0x1a00, 0x3248, 0x2824, 0x4012, 0x0436, 0x1c00, 0x3448, 0x2826, 0x4014, 0x0438, 0x1c02, 0x344a, 0x2626, 0x3e14, 0x0238, 0x1a02, 0x324a, 0x2426, 0x3c14, 0x0038, 0x1802, 0x304a, 0x2428, 0x3c16, 0x003a, 0x1804, 0x304c, 0x2628, 0x3e16, 0x023a, 0x1a04, 0x324c, 0x2828, 0x4016, 0x043a, 0x1c04, 0x344c, 0x282a, 0x4018, 0x043c, 0x1c06, 0x344e, 0x262a, 0x3e18, 0x023c, 0x1a06, 0x324e, 0x242a, 0x3c18, 0x003c, 0x1806, 0x304e, 0x242c, 0x3c1a, 0x003e, 0x1808, 0x3050, 0x262c, 0x3e1a, 0x023e, 0x1a08, 0x3250, 0x282c, 0x401a, 0x043e, 0x1c08, 0x3450, 0x282e, 0x401c, 0x0440, 0x1c0a, 0x3452, 0x262e, 0x3e1c, 0x0240, 0x1a0a, 0x3252, 0x242e, 0x3c1c, 0x0040, 0x180a, 0x3052, 0x2430, 0x3c1e, 0x0042, 0x180c, 0x3054, 0x2630, 0x3e1e, 0x0242, 0x1a0c, 0x3254, 0x2830, 0x401e, 0x0442, 0x1c0c, 0x3454, 0x2832, 0x4020, 0x0444, 0x1c0e, 0x3456, 0x2632, 0x3e20, 0x0244, 0x1a0e, 0x3256, 0x2432, 0x3c20, 0x0044, 0x180e, 0x3056, 0x2434, 0x3c22, 0x0046, 0x1810, 0x3058, 0x2634, 0x3e22, 0x0246, 0x1a10, 0x3258, 0x2834, 0x4022, 0x0446, 0x1c10, 0x3458, 0x2a24, 0x4212, 0x0636, 0x1e00, 0x3648, 0x2c24, 0x4412, 0x0836, 0x2000, 0x3848, 0x2e24, 0x4612, 0x0a36, 0x2200, 0x3a48, 0x2e26, 0x4614, 0x0a38, 0x2202, 0x3a4a, 0x2c26, 0x4414, 0x0838, 0x2002, 0x384a, 0x2a26, 0x4214, 0x0638, 0x1e02, 0x364a, 0x2a28, 0x4216, 0x063a, 0x1e04, 0x364c, 0x2c28, 0x4416, 0x083a, 0x2004, 0x384c, 0x2e28, 0x4616, 0x0a3a, 0x2204, 0x3a4c, 0x2e2a, 0x4618, 0x0a3c, 0x2206, 0x3a4e, 0x2c2a, 0x4418, 0x083c, 0x2006, 0x384e, 0x2a2a, 0x4218, 0x063c, 0x1e06, 0x364e, 0x2a2c, 0x421a, 0x063e, 0x1e08, 0x3650, 0x2c2c, 0x441a, 0x083e, 0x2008, 0x3850, 0x2e2c, 0x461a, 0x0a3e, 0x2208, 0x3a50, 0x2e2e, 0x461c, 0x0a40, 0x220a, 0x3a52, 0x2c2e, 0x441c, 0x0840, 0x200a, 0x3852, 0x2a2e, 0x421c, 0x0640, 0x1e0a, 0x3652, 0x2a30, 0x421e, 0x0642, 0x1e0c, 0x3654, 0x2c30, 0x441e, 0x0842, 0x200c, 0x3854, 0x2e30, 0x461e, 0x0a42, 0x220c, 0x3a54, 0x2e32, 0x4620, 0x0a44, 0x220e, 0x3a56, 0x2c32, 0x4420, 0x0844, 0x200e, 0x3856, 0x2a32, 0x4220, 0x0644, 0x1e0e, 0x3656, 0x2a34, 0x4222, 0x0646, 0x1e10, 0x3658, 0x2c34, 0x4422, 0x0846, 0x2010, 0x3858, 0x2e34, 0x4622, 0x0a46, 0x2210, 0x3a58, 0x3024, 0x0012, 0x0c36, 0x2400, 0x3c48, 0x3224, 0x0212, 0x0e36, 0x2600, 0x3e48, 0x3424, 0x0412, 0x1036, 0x2800, 0x4048, 0x3426, 0x0414, 0x1038, 0x2802, 0x404a, 0x3226, 0x0214, 0x0e38, 0x2602, 0x3e4a, 0x3026, 0x0014, 0x0c38, 0x2402, 0x3c4a, 0x3028, 0x0016, 0x0c3a, 0x2404, 0x3c4c, 0x3228, 0x0216, 0x0e3a, 0x2604, 0x3e4c, 0x3428, 0x0416, 0x103a, 0x2804, 0x404c, 0x342a, 0x0418, 0x103c, 0x2806, 0x404e, 0x322a, 0x0218, 0x0e3c, 0x2606, 0x3e4e, 0x302a, 0x0018, 0x0c3c, 0x2406, 0x3c4e, 0x302c, 0x001a, 0x0c3e, 0x2408, 0x3c50, 0x322c, 0x021a, 0x0e3e, 0x2608, 0x3e50, 0x342c, 0x041a, 0x103e, 0x2808, 0x4050, 0x342e, 0x041c, 0x1040, 0x280a, 0x4052, 0x322e, 0x021c, 0x0e40, 0x260a, 0x3e52, 0x302e, 0x001c, 0x0c40, 0x240a, 0x3c52, 0x3030, 0x001e, 0x0c42, 0x240c, 0x3c54, 0x3230, 0x021e, 0x0e42, 0x260c, 0x3e54, 0x3430, 0x041e, 0x1042, 0x280c, 0x4054, 0x3432, 0x0420, 0x1044, 0x280e, 0x4056, 0x3232, 0x0220, 0x0e44, 0x260e, 0x3e56, 0x3032, 0x0020, 0x0c44, 0x240e, 0x3c56, 0x3034, 0x0022, 0x0c46, 0x2410, 0x3c58, 0x3234, 0x0222, 0x0e46, 0x2610, 0x3e58, 0x3434, 0x0422, 0x1046, 0x2810, 0x4058, 0x3624, 0x0612, 0x1236, 0x2a00, 0x4248, 0x3824, 0x0812, 0x1436, 0x2c00, 0x4448, 0x3a24, 0x0a12, 0x1636, 0x2e00, 0x4648, 0x3a26, 0x0a14, 0x1638, 0x2e02, 0x464a, 0x3826, 0x0814, 0x1438, 0x2c02, 0x444a, 0x3626, 0x0614, 0x1238, 0x2a02, 0x424a, 0x3628, 0x0616, 0x123a, 0x2a04, 0x424c, 0x3828, 0x0816, 0x143a, 0x2c04, 0x444c, 0x3a28, 0x0a16, 0x163a, 0x2e04, 0x464c, 0x3a2a, 0x0a18, 0x163c, 0x2e06, 0x464e, 0x382a, 0x0818, 0x143c, 0x2c06, 0x444e, 0x362a, 0x0618, 0x123c, 0x2a06, 0x424e, 0x362c, 0x061a, 0x123e, 0x2a08, 0x4250, 0x382c, 0x081a, 0x143e, 0x2c08, 0x4450, 0x3a2c, 0x0a1a, 0x163e, 0x2e08, 0x4650, 0x3a2e, 0x0a1c, 0x1640, 0x2e0a, 0x4652, 0x382e, 0x081c, 0x1440, 0x2c0a, 0x4452, 0x362e, 0x061c, 0x1240, 0x2a0a, 0x4252, 0x3630, 0x061e, 0x1242, 0x2a0c, 0x4254, 0x3830, 0x081e, 0x1442, 0x2c0c, 0x4454, 0x3a30, 0x0a1e, 0x1642, 0x2e0c, 0x4654, 0x3a32, 0x0a20, 0x1644, 0x2e0e, 0x4656, 0x3832, 0x0820, 0x1444, 0x2c0e, 0x4456, 0x3632, 0x0620, 0x1244, 0x2a0e, 0x4256, 0x3634, 0x0622, 0x1246, 0x2a10, 0x4258, 0x3834, 0x0822, 0x1446, 0x2c10, 0x4458, 0x3a34, 0x0a22, 0x1646, 0x2e10, 0x4658, 0x3c24, 0x0c12, 0x1836, 0x3000, 0x0048, 0x3e24, 0x0e12, 0x1a36, 0x3200, 0x0248, 0x4024, 0x1012, 0x1c36, 0x3400, 0x0448, 0x4026, 0x1014, 0x1c38, 0x3402, 0x044a, 0x3e26, 0x0e14, 0x1a38, 0x3202, 0x024a, 0x3c26, 0x0c14, 0x1838, 0x3002, 0x004a, 0x3c28, 0x0c16, 0x183a, 0x3004, 0x004c, 0x3e28, 0x0e16, 0x1a3a, 0x3204, 0x024c, 0x4028, 0x1016, 0x1c3a, 0x3404, 0x044c, 0x402a, 0x1018, 0x1c3c, 0x3406, 0x044e, 0x3e2a, 0x0e18, 0x1a3c, 0x3206, 0x024e, 0x3c2a, 0x0c18, 0x183c, 0x3006, 0x004e, 0x3c2c, 0x0c1a, 0x183e, 0x3008, 0x0050, 0x3e2c, 0x0e1a, 0x1a3e, 0x3208, 0x0250, 0x402c, 0x101a, 0x1c3e, 0x3408, 0x0450, 0x402e, 0x101c, 0x1c40, 0x340a, 0x0452, 0x3e2e, 0x0e1c, 0x1a40, 0x320a, 0x0252, 0x3c2e, 0x0c1c, 0x1840, 0x300a, 0x0052, 0x3c30, 0x0c1e, 0x1842, 0x300c, 0x0054, 0x3e30, 0x0e1e, 0x1a42, 0x320c, 0x0254, 0x4030, 0x101e, 0x1c42, 0x340c, 0x0454, 0x4032, 0x1020, 0x1c44, 0x340e, 0x0456, 0x3e32, 0x0e20, 0x1a44, 0x320e, 0x0256, 0x3c32, 0x0c20, 0x1844, 0x300e, 0x0056, 0x3c34, 0x0c22, 0x1846, 0x3010, 0x0058, 0x3e34, 0x0e22, 0x1a46, 0x3210, 0x0258, 0x4034, 0x1022, 0x1c46, 0x3410, 0x0458, 0x4224, 0x1212, 0x1e36, 0x3600, 0x0648, 0x4424, 0x1412, 0x2036, 0x3800, 0x0848, 0x4624, 0x1612, 0x2236, 0x3a00, 0x0a48, 0x4626, 0x1614, 0x2238, 0x3a02, 0x0a4a, 0x4426, 0x1414, 0x2038, 0x3802, 0x084a, 0x4226, 0x1214, 0x1e38, 0x3602, 0x064a, 0x4228, 0x1216, 0x1e3a, 0x3604, 0x064c, 0x4428, 0x1416, 0x203a, 0x3804, 0x084c, 0x4628, 0x1616, 0x223a, 0x3a04, 0x0a4c, 0x462a, 0x1618, 0x223c, 0x3a06, 0x0a4e, 0x442a, 0x1418, 0x203c, 0x3806, 0x084e, 0x422a, 0x1218, 0x1e3c, 0x3606, 0x064e, 0x422c, 0x121a, 0x1e3e, 0x3608, 0x0650, 0x442c, 0x141a, 0x203e, 0x3808, 0x0850, 0x462c, 0x161a, 0x223e, 0x3a08, 0x0a50, 0x462e, 0x161c, 0x2240, 0x3a0a, 0x0a52, 0x442e, 0x141c, 0x2040, 0x380a, 0x0852, 0x422e, 0x121c, 0x1e40, 0x360a, 0x0652, 0x4230, 0x121e, 0x1e42, 0x360c, 0x0654, 0x4430, 0x141e, 0x2042, 0x380c, 0x0854, 0x4630, 0x161e, 0x2242, 0x3a0c, 0x0a54, 0x4632, 0x1620, 0x2244, 0x3a0e, 0x0a56, 0x4432, 0x1420, 0x2044, 0x380e, 0x0856, 0x4232, 0x1220, 0x1e44, 0x360e, 0x0656, 0x4234, 0x1222, 0x1e46, 0x3610, 0x0658, 0x4434, 0x1422, 0x2046, 0x3810, 0x0858, 0x4634, 0x1622, 0x2246, 0x3a10, 0x0a58, 0x0024, 0x1812, 0x2436, 0x3c00, 0x0c48, 0x0224, 0x1a12, 0x2636, 0x3e00, 0x0e48, 0x0424, 0x1c12, 0x2836, 0x4000, 0x1048, 0x0426, 0x1c14, 0x2838, 0x4002, 0x104a, 0x0226, 0x1a14, 0x2638, 0x3e02, 0x0e4a, 0x0026, 0x1814, 0x2438, 0x3c02, 0x0c4a, 0x0028, 0x1816, 0x243a, 0x3c04, 0x0c4c, 0x0228, 0x1a16, 0x263a, 0x3e04, 0x0e4c, 0x0428, 0x1c16, 0x283a, 0x4004, 0x104c, 0x042a, 0x1c18, 0x283c, 0x4006, 0x104e, 0x022a, 0x1a18, 0x263c, 0x3e06, 0x0e4e, 0x002a, 0x1818, 0x243c, 0x3c06, 0x0c4e, 0x002c, 0x181a, 0x243e, 0x3c08, 0x0c50, 0x022c, 0x1a1a, 0x263e, 0x3e08, 0x0e50, 0x042c, 0x1c1a, 0x283e, 0x4008, 0x1050, 0x042e, 0x1c1c, 0x2840, 0x400a, 0x1052, 0x022e, 0x1a1c, 0x2640, 0x3e0a, 0x0e52, 0x002e, 0x181c, 0x2440, 0x3c0a, 0x0c52, 0x0030, 0x181e, 0x2442, 0x3c0c, 0x0c54, 0x0230, 0x1a1e, 0x2642, 0x3e0c, 0x0e54, 0x0430, 0x1c1e, 0x2842, 0x400c, 0x1054, 0x0432, 0x1c20, 0x2844, 0x400e, 0x1056, 0x0232, 0x1a20, 0x2644, 0x3e0e, 0x0e56, 0x0032, 0x1820, 0x2444, 0x3c0e, 0x0c56, 0x0034, 0x1822, 0x2446, 0x3c10, 0x0c58, 0x0234, 0x1a22, 0x2646, 0x3e10, 0x0e58, 0x0434, 0x1c22, 0x2846, 0x4010, 0x1058, 0x0624, 0x1e12, 0x2a36, 0x4200, 0x1248, 0x0824, 0x2012, 0x2c36, 0x4400, 0x1448, 0x0a24, 0x2212, 0x2e36, 0x4600, 0x1648, 0x0a26, 0x2214, 0x2e38, 0x4602, 0x164a, 0x0826, 0x2014, 0x2c38, 0x4402, 0x144a, 0x0626, 0x1e14, 0x2a38, 0x4202, 0x124a, 0x0628, 0x1e16, 0x2a3a, 0x4204, 0x124c, 0x0828, 0x2016, 0x2c3a, 0x4404, 0x144c, 0x0a28, 0x2216, 0x2e3a, 0x4604, 0x164c, 0x0a2a, 0x2218, 0x2e3c, 0x4606, 0x164e, 0x082a, 0x2018, 0x2c3c, 0x4406, 0x144e, 0x062a, 0x1e18, 0x2a3c, 0x4206, 0x124e, 0x062c, 0x1e1a, 0x2a3e, 0x4208, 0x1250, 0x082c, 0x201a, 0x2c3e, 0x4408, 0x1450, 0x0a2c, 0x221a, 0x2e3e, 0x4608, 0x1650, 0x0a2e, 0x221c, 0x2e40, 0x460a, 0x1652, 0x082e, 0x201c, 0x2c40, 0x440a, 0x1452, 0x062e, 0x1e1c, 0x2a40, 0x420a, 0x1252, 0x0630, 0x1e1e, 0x2a42, 0x420c, 0x1254, 0x0830, 0x201e, 0x2c42, 0x440c, 0x1454, 0x0a30, 0x221e, 0x2e42, 0x460c, 0x1654, 0x0a32, 0x2220, 0x2e44, 0x460e, 0x1656, 0x0832, 0x2020, 0x2c44, 0x440e, 0x1456, 0x0632, 0x1e20, 0x2a44, 0x420e, 0x1256, 0x0634, 0x1e22, 0x2a46, 0x4210, 0x1258, 0x0834, 0x2022, 0x2c46, 0x4410, 0x1458, 0x0a34, 0x2222, 0x2e46, 0x4610, 0x1658, }; static const uint16_t dv_place_411P[1620] = { 0x0c24, 0x2710, 0x3334, 0x0000, 0x1848, 0x0d24, 0x2810, 0x3434, 0x0100, 0x1948, 0x0e24, 0x2910, 0x3534, 0x0200, 0x1a48, 0x0f24, 0x2914, 0x3538, 0x0300, 0x1b48, 0x1024, 0x2814, 0x3438, 0x0400, 0x1c48, 0x1124, 0x2714, 0x3338, 0x0500, 0x1d48, 0x1128, 0x2614, 0x3238, 0x0504, 0x1d4c, 0x1028, 0x2514, 0x3138, 0x0404, 0x1c4c, 0x0f28, 0x2414, 0x3038, 0x0304, 0x1b4c, 0x0e28, 0x2418, 0x303c, 0x0204, 0x1a4c, 0x0d28, 0x2518, 0x313c, 0x0104, 0x194c, 0x0c28, 0x2618, 0x323c, 0x0004, 0x184c, 0x0c2c, 0x2718, 0x333c, 0x0008, 0x1850, 0x0d2c, 0x2818, 0x343c, 0x0108, 0x1950, 0x0e2c, 0x2918, 0x353c, 0x0208, 0x1a50, 0x0f2c, 0x291c, 0x3540, 0x0308, 0x1b50, 0x102c, 0x281c, 0x3440, 0x0408, 0x1c50, 0x112c, 0x271c, 0x3340, 0x0508, 0x1d50, 0x1130, 0x261c, 0x3240, 0x050c, 0x1d54, 0x1030, 0x251c, 0x3140, 0x040c, 0x1c54, 0x0f30, 0x241c, 0x3040, 0x030c, 0x1b54, 0x0e30, 0x2420, 0x3044, 0x020c, 0x1a54, 0x0d30, 0x2520, 0x3144, 0x010c, 0x1954, 0x0c30, 0x2620, 0x3244, 0x000c, 0x1854, 0x0c34, 0x2720, 0x3344, 0x0010, 0x1858, 0x0d34, 0x2820, 0x3444, 0x0110, 0x1a58, 0x0e34, 0x2920, 0x3544, 0x0210, 0x1c58, 0x1224, 0x2d10, 0x3934, 0x0600, 0x1e48, 0x1324, 0x2e10, 0x3a34, 0x0700, 0x1f48, 0x1424, 0x2f10, 0x3b34, 0x0800, 0x2048, 0x1524, 0x2f14, 0x3b38, 0x0900, 0x2148, 0x1624, 0x2e14, 0x3a38, 0x0a00, 0x2248, 0x1724, 0x2d14, 0x3938, 0x0b00, 0x2348, 0x1728, 0x2c14, 0x3838, 0x0b04, 0x234c, 0x1628, 0x2b14, 0x3738, 0x0a04, 0x224c, 0x1528, 0x2a14, 0x3638, 0x0904, 0x214c, 0x1428, 0x2a18, 0x363c, 0x0804, 0x204c, 0x1328, 0x2b18, 0x373c, 0x0704, 0x1f4c, 0x1228, 0x2c18, 0x383c, 0x0604, 0x1e4c, 0x122c, 0x2d18, 0x393c, 0x0608, 0x1e50, 0x132c, 0x2e18, 0x3a3c, 0x0708, 0x1f50, 0x142c, 0x2f18, 0x3b3c, 0x0808, 0x2050, 0x152c, 0x2f1c, 0x3b40, 0x0908, 0x2150, 0x162c, 0x2e1c, 0x3a40, 0x0a08, 0x2250, 0x172c, 0x2d1c, 0x3940, 0x0b08, 0x2350, 0x1730, 0x2c1c, 0x3840, 0x0b0c, 0x2354, 0x1630, 0x2b1c, 0x3740, 0x0a0c, 0x2254, 0x1530, 0x2a1c, 0x3640, 0x090c, 0x2154, 0x1430, 0x2a20, 0x3644, 0x080c, 0x2054, 0x1330, 0x2b20, 0x3744, 0x070c, 0x1f54, 0x1230, 0x2c20, 0x3844, 0x060c, 0x1e54, 0x1234, 0x2d20, 0x3944, 0x0610, 0x1e58, 0x1334, 0x2e20, 0x3a44, 0x0710, 0x2058, 0x1434, 0x2f20, 0x3b44, 0x0810, 0x2258, 0x1824, 0x3310, 0x3f34, 0x0c00, 0x2448, 0x1924, 0x3410, 0x4034, 0x0d00, 0x2548, 0x1a24, 0x3510, 0x4134, 0x0e00, 0x2648, 0x1b24, 0x3514, 0x4138, 0x0f00, 0x2748, 0x1c24, 0x3414, 0x4038, 0x1000, 0x2848, 0x1d24, 0x3314, 0x3f38, 0x1100, 0x2948, 0x1d28, 0x3214, 0x3e38, 0x1104, 0x294c, 0x1c28, 0x3114, 0x3d38, 0x1004, 0x284c, 0x1b28, 0x3014, 0x3c38, 0x0f04, 0x274c, 0x1a28, 0x3018, 0x3c3c, 0x0e04, 0x264c, 0x1928, 0x3118, 0x3d3c, 0x0d04, 0x254c, 0x1828, 0x3218, 0x3e3c, 0x0c04, 0x244c, 0x182c, 0x3318, 0x3f3c, 0x0c08, 0x2450, 0x192c, 0x3418, 0x403c, 0x0d08, 0x2550, 0x1a2c, 0x3518, 0x413c, 0x0e08, 0x2650, 0x1b2c, 0x351c, 0x4140, 0x0f08, 0x2750, 0x1c2c, 0x341c, 0x4040, 0x1008, 0x2850, 0x1d2c, 0x331c, 0x3f40, 0x1108, 0x2950, 0x1d30, 0x321c, 0x3e40, 0x110c, 0x2954, 0x1c30, 0x311c, 0x3d40, 0x100c, 0x2854, 0x1b30, 0x301c, 0x3c40, 0x0f0c, 0x2754, 0x1a30, 0x3020, 0x3c44, 0x0e0c, 0x2654, 0x1930, 0x3120, 0x3d44, 0x0d0c, 0x2554, 0x1830, 0x3220, 0x3e44, 0x0c0c, 0x2454, 0x1834, 0x3320, 0x3f44, 0x0c10, 0x2458, 0x1934, 0x3420, 0x4044, 0x0d10, 0x2658, 0x1a34, 0x3520, 0x4144, 0x0e10, 0x2858, 0x1e24, 0x3910, 0x4534, 0x1200, 0x2a48, 0x1f24, 0x3a10, 0x4634, 0x1300, 0x2b48, 0x2024, 0x3b10, 0x4734, 0x1400, 0x2c48, 0x2124, 0x3b14, 0x4738, 0x1500, 0x2d48, 0x2224, 0x3a14, 0x4638, 0x1600, 0x2e48, 0x2324, 0x3914, 0x4538, 0x1700, 0x2f48, 0x2328, 0x3814, 0x4438, 0x1704, 0x2f4c, 0x2228, 0x3714, 0x4338, 0x1604, 0x2e4c, 0x2128, 0x3614, 0x4238, 0x1504, 0x2d4c, 0x2028, 0x3618, 0x423c, 0x1404, 0x2c4c, 0x1f28, 0x3718, 0x433c, 0x1304, 0x2b4c, 0x1e28, 0x3818, 0x443c, 0x1204, 0x2a4c, 0x1e2c, 0x3918, 0x453c, 0x1208, 0x2a50, 0x1f2c, 0x3a18, 0x463c, 0x1308, 0x2b50, 0x202c, 0x3b18, 0x473c, 0x1408, 0x2c50, 0x212c, 0x3b1c, 0x4740, 0x1508, 0x2d50, 0x222c, 0x3a1c, 0x4640, 0x1608, 0x2e50, 0x232c, 0x391c, 0x4540, 0x1708, 0x2f50, 0x2330, 0x381c, 0x4440, 0x170c, 0x2f54, 0x2230, 0x371c, 0x4340, 0x160c, 0x2e54, 0x2130, 0x361c, 0x4240, 0x150c, 0x2d54, 0x2030, 0x3620, 0x4244, 0x140c, 0x2c54, 0x1f30, 0x3720, 0x4344, 0x130c, 0x2b54, 0x1e30, 0x3820, 0x4444, 0x120c, 0x2a54, 0x1e34, 0x3920, 0x4544, 0x1210, 0x2a58, 0x1f34, 0x3a20, 0x4644, 0x1310, 0x2c58, 0x2034, 0x3b20, 0x4744, 0x1410, 0x2e58, 0x2424, 0x3f10, 0x0334, 0x1800, 0x3048, 0x2524, 0x4010, 0x0434, 0x1900, 0x3148, 0x2624, 0x4110, 0x0534, 0x1a00, 0x3248, 0x2724, 0x4114, 0x0538, 0x1b00, 0x3348, 0x2824, 0x4014, 0x0438, 0x1c00, 0x3448, 0x2924, 0x3f14, 0x0338, 0x1d00, 0x3548, 0x2928, 0x3e14, 0x0238, 0x1d04, 0x354c, 0x2828, 0x3d14, 0x0138, 0x1c04, 0x344c, 0x2728, 0x3c14, 0x0038, 0x1b04, 0x334c, 0x2628, 0x3c18, 0x003c, 0x1a04, 0x324c, 0x2528, 0x3d18, 0x013c, 0x1904, 0x314c, 0x2428, 0x3e18, 0x023c, 0x1804, 0x304c, 0x242c, 0x3f18, 0x033c, 0x1808, 0x3050, 0x252c, 0x4018, 0x043c, 0x1908, 0x3150, 0x262c, 0x4118, 0x053c, 0x1a08, 0x3250, 0x272c, 0x411c, 0x0540, 0x1b08, 0x3350, 0x282c, 0x401c, 0x0440, 0x1c08, 0x3450, 0x292c, 0x3f1c, 0x0340, 0x1d08, 0x3550, 0x2930, 0x3e1c, 0x0240, 0x1d0c, 0x3554, 0x2830, 0x3d1c, 0x0140, 0x1c0c, 0x3454, 0x2730, 0x3c1c, 0x0040, 0x1b0c, 0x3354, 0x2630, 0x3c20, 0x0044, 0x1a0c, 0x3254, 0x2530, 0x3d20, 0x0144, 0x190c, 0x3154, 0x2430, 0x3e20, 0x0244, 0x180c, 0x3054, 0x2434, 0x3f20, 0x0344, 0x1810, 0x3058, 0x2534, 0x4020, 0x0444, 0x1910, 0x3258, 0x2634, 0x4120, 0x0544, 0x1a10, 0x3458, 0x2a24, 0x4510, 0x0934, 0x1e00, 0x3648, 0x2b24, 0x4610, 0x0a34, 0x1f00, 0x3748, 0x2c24, 0x4710, 0x0b34, 0x2000, 0x3848, 0x2d24, 0x4714, 0x0b38, 0x2100, 0x3948, 0x2e24, 0x4614, 0x0a38, 0x2200, 0x3a48, 0x2f24, 0x4514, 0x0938, 0x2300, 0x3b48, 0x2f28, 0x4414, 0x0838, 0x2304, 0x3b4c, 0x2e28, 0x4314, 0x0738, 0x2204, 0x3a4c, 0x2d28, 0x4214, 0x0638, 0x2104, 0x394c, 0x2c28, 0x4218, 0x063c, 0x2004, 0x384c, 0x2b28, 0x4318, 0x073c, 0x1f04, 0x374c, 0x2a28, 0x4418, 0x083c, 0x1e04, 0x364c, 0x2a2c, 0x4518, 0x093c, 0x1e08, 0x3650, 0x2b2c, 0x4618, 0x0a3c, 0x1f08, 0x3750, 0x2c2c, 0x4718, 0x0b3c, 0x2008, 0x3850, 0x2d2c, 0x471c, 0x0b40, 0x2108, 0x3950, 0x2e2c, 0x461c, 0x0a40, 0x2208, 0x3a50, 0x2f2c, 0x451c, 0x0940, 0x2308, 0x3b50, 0x2f30, 0x441c, 0x0840, 0x230c, 0x3b54, 0x2e30, 0x431c, 0x0740, 0x220c, 0x3a54, 0x2d30, 0x421c, 0x0640, 0x210c, 0x3954, 0x2c30, 0x4220, 0x0644, 0x200c, 0x3854, 0x2b30, 0x4320, 0x0744, 0x1f0c, 0x3754, 0x2a30, 0x4420, 0x0844, 0x1e0c, 0x3654, 0x2a34, 0x4520, 0x0944, 0x1e10, 0x3658, 0x2b34, 0x4620, 0x0a44, 0x1f10, 0x3858, 0x2c34, 0x4720, 0x0b44, 0x2010, 0x3a58, 0x3024, 0x0310, 0x0f34, 0x2400, 0x3c48, 0x3124, 0x0410, 0x1034, 0x2500, 0x3d48, 0x3224, 0x0510, 0x1134, 0x2600, 0x3e48, 0x3324, 0x0514, 0x1138, 0x2700, 0x3f48, 0x3424, 0x0414, 0x1038, 0x2800, 0x4048, 0x3524, 0x0314, 0x0f38, 0x2900, 0x4148, 0x3528, 0x0214, 0x0e38, 0x2904, 0x414c, 0x3428, 0x0114, 0x0d38, 0x2804, 0x404c, 0x3328, 0x0014, 0x0c38, 0x2704, 0x3f4c, 0x3228, 0x0018, 0x0c3c, 0x2604, 0x3e4c, 0x3128, 0x0118, 0x0d3c, 0x2504, 0x3d4c, 0x3028, 0x0218, 0x0e3c, 0x2404, 0x3c4c, 0x302c, 0x0318, 0x0f3c, 0x2408, 0x3c50, 0x312c, 0x0418, 0x103c, 0x2508, 0x3d50, 0x322c, 0x0518, 0x113c, 0x2608, 0x3e50, 0x332c, 0x051c, 0x1140, 0x2708, 0x3f50, 0x342c, 0x041c, 0x1040, 0x2808, 0x4050, 0x352c, 0x031c, 0x0f40, 0x2908, 0x4150, 0x3530, 0x021c, 0x0e40, 0x290c, 0x4154, 0x3430, 0x011c, 0x0d40, 0x280c, 0x4054, 0x3330, 0x001c, 0x0c40, 0x270c, 0x3f54, 0x3230, 0x0020, 0x0c44, 0x260c, 0x3e54, 0x3130, 0x0120, 0x0d44, 0x250c, 0x3d54, 0x3030, 0x0220, 0x0e44, 0x240c, 0x3c54, 0x3034, 0x0320, 0x0f44, 0x2410, 0x3c58, 0x3134, 0x0420, 0x1044, 0x2510, 0x3e58, 0x3234, 0x0520, 0x1144, 0x2610, 0x4058, 0x3624, 0x0910, 0x1534, 0x2a00, 0x4248, 0x3724, 0x0a10, 0x1634, 0x2b00, 0x4348, 0x3824, 0x0b10, 0x1734, 0x2c00, 0x4448, 0x3924, 0x0b14, 0x1738, 0x2d00, 0x4548, 0x3a24, 0x0a14, 0x1638, 0x2e00, 0x4648, 0x3b24, 0x0914, 0x1538, 0x2f00, 0x4748, 0x3b28, 0x0814, 0x1438, 0x2f04, 0x474c, 0x3a28, 0x0714, 0x1338, 0x2e04, 0x464c, 0x3928, 0x0614, 0x1238, 0x2d04, 0x454c, 0x3828, 0x0618, 0x123c, 0x2c04, 0x444c, 0x3728, 0x0718, 0x133c, 0x2b04, 0x434c, 0x3628, 0x0818, 0x143c, 0x2a04, 0x424c, 0x362c, 0x0918, 0x153c, 0x2a08, 0x4250, 0x372c, 0x0a18, 0x163c, 0x2b08, 0x4350, 0x382c, 0x0b18, 0x173c, 0x2c08, 0x4450, 0x392c, 0x0b1c, 0x1740, 0x2d08, 0x4550, 0x3a2c, 0x0a1c, 0x1640, 0x2e08, 0x4650, 0x3b2c, 0x091c, 0x1540, 0x2f08, 0x4750, 0x3b30, 0x081c, 0x1440, 0x2f0c, 0x4754, 0x3a30, 0x071c, 0x1340, 0x2e0c, 0x4654, 0x3930, 0x061c, 0x1240, 0x2d0c, 0x4554, 0x3830, 0x0620, 0x1244, 0x2c0c, 0x4454, 0x3730, 0x0720, 0x1344, 0x2b0c, 0x4354, 0x3630, 0x0820, 0x1444, 0x2a0c, 0x4254, 0x3634, 0x0920, 0x1544, 0x2a10, 0x4258, 0x3734, 0x0a20, 0x1644, 0x2b10, 0x4458, 0x3834, 0x0b20, 0x1744, 0x2c10, 0x4658, 0x3c24, 0x0f10, 0x1b34, 0x3000, 0x0048, 0x3d24, 0x1010, 0x1c34, 0x3100, 0x0148, 0x3e24, 0x1110, 0x1d34, 0x3200, 0x0248, 0x3f24, 0x1114, 0x1d38, 0x3300, 0x0348, 0x4024, 0x1014, 0x1c38, 0x3400, 0x0448, 0x4124, 0x0f14, 0x1b38, 0x3500, 0x0548, 0x4128, 0x0e14, 0x1a38, 0x3504, 0x054c, 0x4028, 0x0d14, 0x1938, 0x3404, 0x044c, 0x3f28, 0x0c14, 0x1838, 0x3304, 0x034c, 0x3e28, 0x0c18, 0x183c, 0x3204, 0x024c, 0x3d28, 0x0d18, 0x193c, 0x3104, 0x014c, 0x3c28, 0x0e18, 0x1a3c, 0x3004, 0x004c, 0x3c2c, 0x0f18, 0x1b3c, 0x3008, 0x0050, 0x3d2c, 0x1018, 0x1c3c, 0x3108, 0x0150, 0x3e2c, 0x1118, 0x1d3c, 0x3208, 0x0250, 0x3f2c, 0x111c, 0x1d40, 0x3308, 0x0350, 0x402c, 0x101c, 0x1c40, 0x3408, 0x0450, 0x412c, 0x0f1c, 0x1b40, 0x3508, 0x0550, 0x4130, 0x0e1c, 0x1a40, 0x350c, 0x0554, 0x4030, 0x0d1c, 0x1940, 0x340c, 0x0454, 0x3f30, 0x0c1c, 0x1840, 0x330c, 0x0354, 0x3e30, 0x0c20, 0x1844, 0x320c, 0x0254, 0x3d30, 0x0d20, 0x1944, 0x310c, 0x0154, 0x3c30, 0x0e20, 0x1a44, 0x300c, 0x0054, 0x3c34, 0x0f20, 0x1b44, 0x3010, 0x0058, 0x3d34, 0x1020, 0x1c44, 0x3110, 0x0258, 0x3e34, 0x1120, 0x1d44, 0x3210, 0x0458, 0x4224, 0x1510, 0x2134, 0x3600, 0x0648, 0x4324, 0x1610, 0x2234, 0x3700, 0x0748, 0x4424, 0x1710, 0x2334, 0x3800, 0x0848, 0x4524, 0x1714, 0x2338, 0x3900, 0x0948, 0x4624, 0x1614, 0x2238, 0x3a00, 0x0a48, 0x4724, 0x1514, 0x2138, 0x3b00, 0x0b48, 0x4728, 0x1414, 0x2038, 0x3b04, 0x0b4c, 0x4628, 0x1314, 0x1f38, 0x3a04, 0x0a4c, 0x4528, 0x1214, 0x1e38, 0x3904, 0x094c, 0x4428, 0x1218, 0x1e3c, 0x3804, 0x084c, 0x4328, 0x1318, 0x1f3c, 0x3704, 0x074c, 0x4228, 0x1418, 0x203c, 0x3604, 0x064c, 0x422c, 0x1518, 0x213c, 0x3608, 0x0650, 0x432c, 0x1618, 0x223c, 0x3708, 0x0750, 0x442c, 0x1718, 0x233c, 0x3808, 0x0850, 0x452c, 0x171c, 0x2340, 0x3908, 0x0950, 0x462c, 0x161c, 0x2240, 0x3a08, 0x0a50, 0x472c, 0x151c, 0x2140, 0x3b08, 0x0b50, 0x4730, 0x141c, 0x2040, 0x3b0c, 0x0b54, 0x4630, 0x131c, 0x1f40, 0x3a0c, 0x0a54, 0x4530, 0x121c, 0x1e40, 0x390c, 0x0954, 0x4430, 0x1220, 0x1e44, 0x380c, 0x0854, 0x4330, 0x1320, 0x1f44, 0x370c, 0x0754, 0x4230, 0x1420, 0x2044, 0x360c, 0x0654, 0x4234, 0x1520, 0x2144, 0x3610, 0x0658, 0x4334, 0x1620, 0x2244, 0x3710, 0x0858, 0x4434, 0x1720, 0x2344, 0x3810, 0x0a58, 0x0024, 0x1b10, 0x2734, 0x3c00, 0x0c48, 0x0124, 0x1c10, 0x2834, 0x3d00, 0x0d48, 0x0224, 0x1d10, 0x2934, 0x3e00, 0x0e48, 0x0324, 0x1d14, 0x2938, 0x3f00, 0x0f48, 0x0424, 0x1c14, 0x2838, 0x4000, 0x1048, 0x0524, 0x1b14, 0x2738, 0x4100, 0x1148, 0x0528, 0x1a14, 0x2638, 0x4104, 0x114c, 0x0428, 0x1914, 0x2538, 0x4004, 0x104c, 0x0328, 0x1814, 0x2438, 0x3f04, 0x0f4c, 0x0228, 0x1818, 0x243c, 0x3e04, 0x0e4c, 0x0128, 0x1918, 0x253c, 0x3d04, 0x0d4c, 0x0028, 0x1a18, 0x263c, 0x3c04, 0x0c4c, 0x002c, 0x1b18, 0x273c, 0x3c08, 0x0c50, 0x012c, 0x1c18, 0x283c, 0x3d08, 0x0d50, 0x022c, 0x1d18, 0x293c, 0x3e08, 0x0e50, 0x032c, 0x1d1c, 0x2940, 0x3f08, 0x0f50, 0x042c, 0x1c1c, 0x2840, 0x4008, 0x1050, 0x052c, 0x1b1c, 0x2740, 0x4108, 0x1150, 0x0530, 0x1a1c, 0x2640, 0x410c, 0x1154, 0x0430, 0x191c, 0x2540, 0x400c, 0x1054, 0x0330, 0x181c, 0x2440, 0x3f0c, 0x0f54, 0x0230, 0x1820, 0x2444, 0x3e0c, 0x0e54, 0x0130, 0x1920, 0x2544, 0x3d0c, 0x0d54, 0x0030, 0x1a20, 0x2644, 0x3c0c, 0x0c54, 0x0034, 0x1b20, 0x2744, 0x3c10, 0x0c58, 0x0134, 0x1c20, 0x2844, 0x3d10, 0x0e58, 0x0234, 0x1d20, 0x2944, 0x3e10, 0x1058, 0x0624, 0x2110, 0x2d34, 0x4200, 0x1248, 0x0724, 0x2210, 0x2e34, 0x4300, 0x1348, 0x0824, 0x2310, 0x2f34, 0x4400, 0x1448, 0x0924, 0x2314, 0x2f38, 0x4500, 0x1548, 0x0a24, 0x2214, 0x2e38, 0x4600, 0x1648, 0x0b24, 0x2114, 0x2d38, 0x4700, 0x1748, 0x0b28, 0x2014, 0x2c38, 0x4704, 0x174c, 0x0a28, 0x1f14, 0x2b38, 0x4604, 0x164c, 0x0928, 0x1e14, 0x2a38, 0x4504, 0x154c, 0x0828, 0x1e18, 0x2a3c, 0x4404, 0x144c, 0x0728, 0x1f18, 0x2b3c, 0x4304, 0x134c, 0x0628, 0x2018, 0x2c3c, 0x4204, 0x124c, 0x062c, 0x2118, 0x2d3c, 0x4208, 0x1250, 0x072c, 0x2218, 0x2e3c, 0x4308, 0x1350, 0x082c, 0x2318, 0x2f3c, 0x4408, 0x1450, 0x092c, 0x231c, 0x2f40, 0x4508, 0x1550, 0x0a2c, 0x221c, 0x2e40, 0x4608, 0x1650, 0x0b2c, 0x211c, 0x2d40, 0x4708, 0x1750, 0x0b30, 0x201c, 0x2c40, 0x470c, 0x1754, 0x0a30, 0x1f1c, 0x2b40, 0x460c, 0x1654, 0x0930, 0x1e1c, 0x2a40, 0x450c, 0x1554, 0x0830, 0x1e20, 0x2a44, 0x440c, 0x1454, 0x0730, 0x1f20, 0x2b44, 0x430c, 0x1354, 0x0630, 0x2020, 0x2c44, 0x420c, 0x1254, 0x0634, 0x2120, 0x2d44, 0x4210, 0x1258, 0x0734, 0x2220, 0x2e44, 0x4310, 0x1458, 0x0834, 0x2320, 0x2f44, 0x4410, 0x1658, }; static const uint16_t dv_place_411[1350] = { 0x0c24, 0x2710, 0x3334, 0x0000, 0x1848, 0x0d24, 0x2810, 0x3434, 0x0100, 0x1948, 0x0e24, 0x2910, 0x3534, 0x0200, 0x1a48, 0x0f24, 0x2914, 0x3538, 0x0300, 0x1b48, 0x1024, 0x2814, 0x3438, 0x0400, 0x1c48, 0x1124, 0x2714, 0x3338, 0x0500, 0x1d48, 0x1128, 0x2614, 0x3238, 0x0504, 0x1d4c, 0x1028, 0x2514, 0x3138, 0x0404, 0x1c4c, 0x0f28, 0x2414, 0x3038, 0x0304, 0x1b4c, 0x0e28, 0x2418, 0x303c, 0x0204, 0x1a4c, 0x0d28, 0x2518, 0x313c, 0x0104, 0x194c, 0x0c28, 0x2618, 0x323c, 0x0004, 0x184c, 0x0c2c, 0x2718, 0x333c, 0x0008, 0x1850, 0x0d2c, 0x2818, 0x343c, 0x0108, 0x1950, 0x0e2c, 0x2918, 0x353c, 0x0208, 0x1a50, 0x0f2c, 0x291c, 0x3540, 0x0308, 0x1b50, 0x102c, 0x281c, 0x3440, 0x0408, 0x1c50, 0x112c, 0x271c, 0x3340, 0x0508, 0x1d50, 0x1130, 0x261c, 0x3240, 0x050c, 0x1d54, 0x1030, 0x251c, 0x3140, 0x040c, 0x1c54, 0x0f30, 0x241c, 0x3040, 0x030c, 0x1b54, 0x0e30, 0x2420, 0x3044, 0x020c, 0x1a54, 0x0d30, 0x2520, 0x3144, 0x010c, 0x1954, 0x0c30, 0x2620, 0x3244, 0x000c, 0x1854, 0x0c34, 0x2720, 0x3344, 0x0010, 0x1858, 0x0d34, 0x2820, 0x3444, 0x0110, 0x1a58, 0x0e34, 0x2920, 0x3544, 0x0210, 0x1c58, 0x1224, 0x2d10, 0x3934, 0x0600, 0x1e48, 0x1324, 0x2e10, 0x3a34, 0x0700, 0x1f48, 0x1424, 0x2f10, 0x3b34, 0x0800, 0x2048, 0x1524, 0x2f14, 0x3b38, 0x0900, 0x2148, 0x1624, 0x2e14, 0x3a38, 0x0a00, 0x2248, 0x1724, 0x2d14, 0x3938, 0x0b00, 0x2348, 0x1728, 0x2c14, 0x3838, 0x0b04, 0x234c, 0x1628, 0x2b14, 0x3738, 0x0a04, 0x224c, 0x1528, 0x2a14, 0x3638, 0x0904, 0x214c, 0x1428, 0x2a18, 0x363c, 0x0804, 0x204c, 0x1328, 0x2b18, 0x373c, 0x0704, 0x1f4c, 0x1228, 0x2c18, 0x383c, 0x0604, 0x1e4c, 0x122c, 0x2d18, 0x393c, 0x0608, 0x1e50, 0x132c, 0x2e18, 0x3a3c, 0x0708, 0x1f50, 0x142c, 0x2f18, 0x3b3c, 0x0808, 0x2050, 0x152c, 0x2f1c, 0x3b40, 0x0908, 0x2150, 0x162c, 0x2e1c, 0x3a40, 0x0a08, 0x2250, 0x172c, 0x2d1c, 0x3940, 0x0b08, 0x2350, 0x1730, 0x2c1c, 0x3840, 0x0b0c, 0x2354, 0x1630, 0x2b1c, 0x3740, 0x0a0c, 0x2254, 0x1530, 0x2a1c, 0x3640, 0x090c, 0x2154, 0x1430, 0x2a20, 0x3644, 0x080c, 0x2054, 0x1330, 0x2b20, 0x3744, 0x070c, 0x1f54, 0x1230, 0x2c20, 0x3844, 0x060c, 0x1e54, 0x1234, 0x2d20, 0x3944, 0x0610, 0x1e58, 0x1334, 0x2e20, 0x3a44, 0x0710, 0x2058, 0x1434, 0x2f20, 0x3b44, 0x0810, 0x2258, 0x1824, 0x3310, 0x0334, 0x0c00, 0x2448, 0x1924, 0x3410, 0x0434, 0x0d00, 0x2548, 0x1a24, 0x3510, 0x0534, 0x0e00, 0x2648, 0x1b24, 0x3514, 0x0538, 0x0f00, 0x2748, 0x1c24, 0x3414, 0x0438, 0x1000, 0x2848, 0x1d24, 0x3314, 0x0338, 0x1100, 0x2948, 0x1d28, 0x3214, 0x0238, 0x1104, 0x294c, 0x1c28, 0x3114, 0x0138, 0x1004, 0x284c, 0x1b28, 0x3014, 0x0038, 0x0f04, 0x274c, 0x1a28, 0x3018, 0x003c, 0x0e04, 0x264c, 0x1928, 0x3118, 0x013c, 0x0d04, 0x254c, 0x1828, 0x3218, 0x023c, 0x0c04, 0x244c, 0x182c, 0x3318, 0x033c, 0x0c08, 0x2450, 0x192c, 0x3418, 0x043c, 0x0d08, 0x2550, 0x1a2c, 0x3518, 0x053c, 0x0e08, 0x2650, 0x1b2c, 0x351c, 0x0540, 0x0f08, 0x2750, 0x1c2c, 0x341c, 0x0440, 0x1008, 0x2850, 0x1d2c, 0x331c, 0x0340, 0x1108, 0x2950, 0x1d30, 0x321c, 0x0240, 0x110c, 0x2954, 0x1c30, 0x311c, 0x0140, 0x100c, 0x2854, 0x1b30, 0x301c, 0x0040, 0x0f0c, 0x2754, 0x1a30, 0x3020, 0x0044, 0x0e0c, 0x2654, 0x1930, 0x3120, 0x0144, 0x0d0c, 0x2554, 0x1830, 0x3220, 0x0244, 0x0c0c, 0x2454, 0x1834, 0x3320, 0x0344, 0x0c10, 0x2458, 0x1934, 0x3420, 0x0444, 0x0d10, 0x2658, 0x1a34, 0x3520, 0x0544, 0x0e10, 0x2858, 0x1e24, 0x3910, 0x0934, 0x1200, 0x2a48, 0x1f24, 0x3a10, 0x0a34, 0x1300, 0x2b48, 0x2024, 0x3b10, 0x0b34, 0x1400, 0x2c48, 0x2124, 0x3b14, 0x0b38, 0x1500, 0x2d48, 0x2224, 0x3a14, 0x0a38, 0x1600, 0x2e48, 0x2324, 0x3914, 0x0938, 0x1700, 0x2f48, 0x2328, 0x3814, 0x0838, 0x1704, 0x2f4c, 0x2228, 0x3714, 0x0738, 0x1604, 0x2e4c, 0x2128, 0x3614, 0x0638, 0x1504, 0x2d4c, 0x2028, 0x3618, 0x063c, 0x1404, 0x2c4c, 0x1f28, 0x3718, 0x073c, 0x1304, 0x2b4c, 0x1e28, 0x3818, 0x083c, 0x1204, 0x2a4c, 0x1e2c, 0x3918, 0x093c, 0x1208, 0x2a50, 0x1f2c, 0x3a18, 0x0a3c, 0x1308, 0x2b50, 0x202c, 0x3b18, 0x0b3c, 0x1408, 0x2c50, 0x212c, 0x3b1c, 0x0b40, 0x1508, 0x2d50, 0x222c, 0x3a1c, 0x0a40, 0x1608, 0x2e50, 0x232c, 0x391c, 0x0940, 0x1708, 0x2f50, 0x2330, 0x381c, 0x0840, 0x170c, 0x2f54, 0x2230, 0x371c, 0x0740, 0x160c, 0x2e54, 0x2130, 0x361c, 0x0640, 0x150c, 0x2d54, 0x2030, 0x3620, 0x0644, 0x140c, 0x2c54, 0x1f30, 0x3720, 0x0744, 0x130c, 0x2b54, 0x1e30, 0x3820, 0x0844, 0x120c, 0x2a54, 0x1e34, 0x3920, 0x0944, 0x1210, 0x2a58, 0x1f34, 0x3a20, 0x0a44, 0x1310, 0x2c58, 0x2034, 0x3b20, 0x0b44, 0x1410, 0x2e58, 0x2424, 0x0310, 0x0f34, 0x1800, 0x3048, 0x2524, 0x0410, 0x1034, 0x1900, 0x3148, 0x2624, 0x0510, 0x1134, 0x1a00, 0x3248, 0x2724, 0x0514, 0x1138, 0x1b00, 0x3348, 0x2824, 0x0414, 0x1038, 0x1c00, 0x3448, 0x2924, 0x0314, 0x0f38, 0x1d00, 0x3548, 0x2928, 0x0214, 0x0e38, 0x1d04, 0x354c, 0x2828, 0x0114, 0x0d38, 0x1c04, 0x344c, 0x2728, 0x0014, 0x0c38, 0x1b04, 0x334c, 0x2628, 0x0018, 0x0c3c, 0x1a04, 0x324c, 0x2528, 0x0118, 0x0d3c, 0x1904, 0x314c, 0x2428, 0x0218, 0x0e3c, 0x1804, 0x304c, 0x242c, 0x0318, 0x0f3c, 0x1808, 0x3050, 0x252c, 0x0418, 0x103c, 0x1908, 0x3150, 0x262c, 0x0518, 0x113c, 0x1a08, 0x3250, 0x272c, 0x051c, 0x1140, 0x1b08, 0x3350, 0x282c, 0x041c, 0x1040, 0x1c08, 0x3450, 0x292c, 0x031c, 0x0f40, 0x1d08, 0x3550, 0x2930, 0x021c, 0x0e40, 0x1d0c, 0x3554, 0x2830, 0x011c, 0x0d40, 0x1c0c, 0x3454, 0x2730, 0x001c, 0x0c40, 0x1b0c, 0x3354, 0x2630, 0x0020, 0x0c44, 0x1a0c, 0x3254, 0x2530, 0x0120, 0x0d44, 0x190c, 0x3154, 0x2430, 0x0220, 0x0e44, 0x180c, 0x3054, 0x2434, 0x0320, 0x0f44, 0x1810, 0x3058, 0x2534, 0x0420, 0x1044, 0x1910, 0x3258, 0x2634, 0x0520, 0x1144, 0x1a10, 0x3458, 0x2a24, 0x0910, 0x1534, 0x1e00, 0x3648, 0x2b24, 0x0a10, 0x1634, 0x1f00, 0x3748, 0x2c24, 0x0b10, 0x1734, 0x2000, 0x3848, 0x2d24, 0x0b14, 0x1738, 0x2100, 0x3948, 0x2e24, 0x0a14, 0x1638, 0x2200, 0x3a48, 0x2f24, 0x0914, 0x1538, 0x2300, 0x3b48, 0x2f28, 0x0814, 0x1438, 0x2304, 0x3b4c, 0x2e28, 0x0714, 0x1338, 0x2204, 0x3a4c, 0x2d28, 0x0614, 0x1238, 0x2104, 0x394c, 0x2c28, 0x0618, 0x123c, 0x2004, 0x384c, 0x2b28, 0x0718, 0x133c, 0x1f04, 0x374c, 0x2a28, 0x0818, 0x143c, 0x1e04, 0x364c, 0x2a2c, 0x0918, 0x153c, 0x1e08, 0x3650, 0x2b2c, 0x0a18, 0x163c, 0x1f08, 0x3750, 0x2c2c, 0x0b18, 0x173c, 0x2008, 0x3850, 0x2d2c, 0x0b1c, 0x1740, 0x2108, 0x3950, 0x2e2c, 0x0a1c, 0x1640, 0x2208, 0x3a50, 0x2f2c, 0x091c, 0x1540, 0x2308, 0x3b50, 0x2f30, 0x081c, 0x1440, 0x230c, 0x3b54, 0x2e30, 0x071c, 0x1340, 0x220c, 0x3a54, 0x2d30, 0x061c, 0x1240, 0x210c, 0x3954, 0x2c30, 0x0620, 0x1244, 0x200c, 0x3854, 0x2b30, 0x0720, 0x1344, 0x1f0c, 0x3754, 0x2a30, 0x0820, 0x1444, 0x1e0c, 0x3654, 0x2a34, 0x0920, 0x1544, 0x1e10, 0x3658, 0x2b34, 0x0a20, 0x1644, 0x1f10, 0x3858, 0x2c34, 0x0b20, 0x1744, 0x2010, 0x3a58, 0x3024, 0x0f10, 0x1b34, 0x2400, 0x0048, 0x3124, 0x1010, 0x1c34, 0x2500, 0x0148, 0x3224, 0x1110, 0x1d34, 0x2600, 0x0248, 0x3324, 0x1114, 0x1d38, 0x2700, 0x0348, 0x3424, 0x1014, 0x1c38, 0x2800, 0x0448, 0x3524, 0x0f14, 0x1b38, 0x2900, 0x0548, 0x3528, 0x0e14, 0x1a38, 0x2904, 0x054c, 0x3428, 0x0d14, 0x1938, 0x2804, 0x044c, 0x3328, 0x0c14, 0x1838, 0x2704, 0x034c, 0x3228, 0x0c18, 0x183c, 0x2604, 0x024c, 0x3128, 0x0d18, 0x193c, 0x2504, 0x014c, 0x3028, 0x0e18, 0x1a3c, 0x2404, 0x004c, 0x302c, 0x0f18, 0x1b3c, 0x2408, 0x0050, 0x312c, 0x1018, 0x1c3c, 0x2508, 0x0150, 0x322c, 0x1118, 0x1d3c, 0x2608, 0x0250, 0x332c, 0x111c, 0x1d40, 0x2708, 0x0350, 0x342c, 0x101c, 0x1c40, 0x2808, 0x0450, 0x352c, 0x0f1c, 0x1b40, 0x2908, 0x0550, 0x3530, 0x0e1c, 0x1a40, 0x290c, 0x0554, 0x3430, 0x0d1c, 0x1940, 0x280c, 0x0454, 0x3330, 0x0c1c, 0x1840, 0x270c, 0x0354, 0x3230, 0x0c20, 0x1844, 0x260c, 0x0254, 0x3130, 0x0d20, 0x1944, 0x250c, 0x0154, 0x3030, 0x0e20, 0x1a44, 0x240c, 0x0054, 0x3034, 0x0f20, 0x1b44, 0x2410, 0x0058, 0x3134, 0x1020, 0x1c44, 0x2510, 0x0258, 0x3234, 0x1120, 0x1d44, 0x2610, 0x0458, 0x3624, 0x1510, 0x2134, 0x2a00, 0x0648, 0x3724, 0x1610, 0x2234, 0x2b00, 0x0748, 0x3824, 0x1710, 0x2334, 0x2c00, 0x0848, 0x3924, 0x1714, 0x2338, 0x2d00, 0x0948, 0x3a24, 0x1614, 0x2238, 0x2e00, 0x0a48, 0x3b24, 0x1514, 0x2138, 0x2f00, 0x0b48, 0x3b28, 0x1414, 0x2038, 0x2f04, 0x0b4c, 0x3a28, 0x1314, 0x1f38, 0x2e04, 0x0a4c, 0x3928, 0x1214, 0x1e38, 0x2d04, 0x094c, 0x3828, 0x1218, 0x1e3c, 0x2c04, 0x084c, 0x3728, 0x1318, 0x1f3c, 0x2b04, 0x074c, 0x3628, 0x1418, 0x203c, 0x2a04, 0x064c, 0x362c, 0x1518, 0x213c, 0x2a08, 0x0650, 0x372c, 0x1618, 0x223c, 0x2b08, 0x0750, 0x382c, 0x1718, 0x233c, 0x2c08, 0x0850, 0x392c, 0x171c, 0x2340, 0x2d08, 0x0950, 0x3a2c, 0x161c, 0x2240, 0x2e08, 0x0a50, 0x3b2c, 0x151c, 0x2140, 0x2f08, 0x0b50, 0x3b30, 0x141c, 0x2040, 0x2f0c, 0x0b54, 0x3a30, 0x131c, 0x1f40, 0x2e0c, 0x0a54, 0x3930, 0x121c, 0x1e40, 0x2d0c, 0x0954, 0x3830, 0x1220, 0x1e44, 0x2c0c, 0x0854, 0x3730, 0x1320, 0x1f44, 0x2b0c, 0x0754, 0x3630, 0x1420, 0x2044, 0x2a0c, 0x0654, 0x3634, 0x1520, 0x2144, 0x2a10, 0x0658, 0x3734, 0x1620, 0x2244, 0x2b10, 0x0858, 0x3834, 0x1720, 0x2344, 0x2c10, 0x0a58, 0x0024, 0x1b10, 0x2734, 0x3000, 0x0c48, 0x0124, 0x1c10, 0x2834, 0x3100, 0x0d48, 0x0224, 0x1d10, 0x2934, 0x3200, 0x0e48, 0x0324, 0x1d14, 0x2938, 0x3300, 0x0f48, 0x0424, 0x1c14, 0x2838, 0x3400, 0x1048, 0x0524, 0x1b14, 0x2738, 0x3500, 0x1148, 0x0528, 0x1a14, 0x2638, 0x3504, 0x114c, 0x0428, 0x1914, 0x2538, 0x3404, 0x104c, 0x0328, 0x1814, 0x2438, 0x3304, 0x0f4c, 0x0228, 0x1818, 0x243c, 0x3204, 0x0e4c, 0x0128, 0x1918, 0x253c, 0x3104, 0x0d4c, 0x0028, 0x1a18, 0x263c, 0x3004, 0x0c4c, 0x002c, 0x1b18, 0x273c, 0x3008, 0x0c50, 0x012c, 0x1c18, 0x283c, 0x3108, 0x0d50, 0x022c, 0x1d18, 0x293c, 0x3208, 0x0e50, 0x032c, 0x1d1c, 0x2940, 0x3308, 0x0f50, 0x042c, 0x1c1c, 0x2840, 0x3408, 0x1050, 0x052c, 0x1b1c, 0x2740, 0x3508, 0x1150, 0x0530, 0x1a1c, 0x2640, 0x350c, 0x1154, 0x0430, 0x191c, 0x2540, 0x340c, 0x1054, 0x0330, 0x181c, 0x2440, 0x330c, 0x0f54, 0x0230, 0x1820, 0x2444, 0x320c, 0x0e54, 0x0130, 0x1920, 0x2544, 0x310c, 0x0d54, 0x0030, 0x1a20, 0x2644, 0x300c, 0x0c54, 0x0034, 0x1b20, 0x2744, 0x3010, 0x0c58, 0x0134, 0x1c20, 0x2844, 0x3110, 0x0e58, 0x0234, 0x1d20, 0x2944, 0x3210, 0x1058, 0x0624, 0x2110, 0x2d34, 0x3600, 0x1248, 0x0724, 0x2210, 0x2e34, 0x3700, 0x1348, 0x0824, 0x2310, 0x2f34, 0x3800, 0x1448, 0x0924, 0x2314, 0x2f38, 0x3900, 0x1548, 0x0a24, 0x2214, 0x2e38, 0x3a00, 0x1648, 0x0b24, 0x2114, 0x2d38, 0x3b00, 0x1748, 0x0b28, 0x2014, 0x2c38, 0x3b04, 0x174c, 0x0a28, 0x1f14, 0x2b38, 0x3a04, 0x164c, 0x0928, 0x1e14, 0x2a38, 0x3904, 0x154c, 0x0828, 0x1e18, 0x2a3c, 0x3804, 0x144c, 0x0728, 0x1f18, 0x2b3c, 0x3704, 0x134c, 0x0628, 0x2018, 0x2c3c, 0x3604, 0x124c, 0x062c, 0x2118, 0x2d3c, 0x3608, 0x1250, 0x072c, 0x2218, 0x2e3c, 0x3708, 0x1350, 0x082c, 0x2318, 0x2f3c, 0x3808, 0x1450, 0x092c, 0x231c, 0x2f40, 0x3908, 0x1550, 0x0a2c, 0x221c, 0x2e40, 0x3a08, 0x1650, 0x0b2c, 0x211c, 0x2d40, 0x3b08, 0x1750, 0x0b30, 0x201c, 0x2c40, 0x3b0c, 0x1754, 0x0a30, 0x1f1c, 0x2b40, 0x3a0c, 0x1654, 0x0930, 0x1e1c, 0x2a40, 0x390c, 0x1554, 0x0830, 0x1e20, 0x2a44, 0x380c, 0x1454, 0x0730, 0x1f20, 0x2b44, 0x370c, 0x1354, 0x0630, 0x2020, 0x2c44, 0x360c, 0x1254, 0x0634, 0x2120, 0x2d44, 0x3610, 0x1258, 0x0734, 0x2220, 0x2e44, 0x3710, 0x1458, 0x0834, 0x2320, 0x2f44, 0x3810, 0x1658, }; /* 4:2:2 macroblock placement tables created by dvtables.py */ /* 2 channels per frame, 10 DIF sequences per channel, 27 video segments per DIF sequence, 5 macroblocks per video segment */ static const uint16_t dv_place_422_525[2*10*27*5] = { 0x0c48, 0x2424, 0x306c, 0x0000, 0x1890, 0x0d48, 0x2524, 0x316c, 0x0100, 0x1990, 0x0e48, 0x2624, 0x326c, 0x0200, 0x1a90, 0x0e4c, 0x2628, 0x3270, 0x0204, 0x1a94, 0x0d4c, 0x2528, 0x3170, 0x0104, 0x1994, 0x0c4c, 0x2428, 0x3070, 0x0004, 0x1894, 0x0c50, 0x242c, 0x3074, 0x0008, 0x1898, 0x0d50, 0x252c, 0x3174, 0x0108, 0x1998, 0x0e50, 0x262c, 0x3274, 0x0208, 0x1a98, 0x0e54, 0x2630, 0x3278, 0x020c, 0x1a9c, 0x0d54, 0x2530, 0x3178, 0x010c, 0x199c, 0x0c54, 0x2430, 0x3078, 0x000c, 0x189c, 0x0c58, 0x2434, 0x307c, 0x0010, 0x18a0, 0x0d58, 0x2534, 0x317c, 0x0110, 0x19a0, 0x0e58, 0x2634, 0x327c, 0x0210, 0x1aa0, 0x0e5c, 0x2638, 0x3280, 0x0214, 0x1aa4, 0x0d5c, 0x2538, 0x3180, 0x0114, 0x19a4, 0x0c5c, 0x2438, 0x3080, 0x0014, 0x18a4, 0x0c60, 0x243c, 0x3084, 0x0018, 0x18a8, 0x0d60, 0x253c, 0x3184, 0x0118, 0x19a8, 0x0e60, 0x263c, 0x3284, 0x0218, 0x1aa8, 0x0e64, 0x2640, 0x3288, 0x021c, 0x1aac, 0x0d64, 0x2540, 0x3188, 0x011c, 0x19ac, 0x0c64, 0x2440, 0x3088, 0x001c, 0x18ac, 0x0c68, 0x2444, 0x308c, 0x0020, 0x18b0, 0x0d68, 0x2544, 0x318c, 0x0120, 0x19b0, 0x0e68, 0x2644, 0x328c, 0x0220, 0x1ab0, 0x1248, 0x2a24, 0x366c, 0x0600, 0x1e90, 0x1348, 0x2b24, 0x376c, 0x0700, 0x1f90, 0x1448, 0x2c24, 0x386c, 0x0800, 0x2090, 0x144c, 0x2c28, 0x3870, 0x0804, 0x2094, 0x134c, 0x2b28, 0x3770, 0x0704, 0x1f94, 0x124c, 0x2a28, 0x3670, 0x0604, 0x1e94, 0x1250, 0x2a2c, 0x3674, 0x0608, 0x1e98, 0x1350, 0x2b2c, 0x3774, 0x0708, 0x1f98, 0x1450, 0x2c2c, 0x3874, 0x0808, 0x2098, 0x1454, 0x2c30, 0x3878, 0x080c, 0x209c, 0x1354, 0x2b30, 0x3778, 0x070c, 0x1f9c, 0x1254, 0x2a30, 0x3678, 0x060c, 0x1e9c, 0x1258, 0x2a34, 0x367c, 0x0610, 0x1ea0, 0x1358, 0x2b34, 0x377c, 0x0710, 0x1fa0, 0x1458, 0x2c34, 0x387c, 0x0810, 0x20a0, 0x145c, 0x2c38, 0x3880, 0x0814, 0x20a4, 0x135c, 0x2b38, 0x3780, 0x0714, 0x1fa4, 0x125c, 0x2a38, 0x3680, 0x0614, 0x1ea4, 0x1260, 0x2a3c, 0x3684, 0x0618, 0x1ea8, 0x1360, 0x2b3c, 0x3784, 0x0718, 0x1fa8, 0x1460, 0x2c3c, 0x3884, 0x0818, 0x20a8, 0x1464, 0x2c40, 0x3888, 0x081c, 0x20ac, 0x1364, 0x2b40, 0x3788, 0x071c, 0x1fac, 0x1264, 0x2a40, 0x3688, 0x061c, 0x1eac, 0x1268, 0x2a44, 0x368c, 0x0620, 0x1eb0, 0x1368, 0x2b44, 0x378c, 0x0720, 0x1fb0, 0x1468, 0x2c44, 0x388c, 0x0820, 0x20b0, 0x1848, 0x3024, 0x006c, 0x0c00, 0x2490, 0x1948, 0x3124, 0x016c, 0x0d00, 0x2590, 0x1a48, 0x3224, 0x026c, 0x0e00, 0x2690, 0x1a4c, 0x3228, 0x0270, 0x0e04, 0x2694, 0x194c, 0x3128, 0x0170, 0x0d04, 0x2594, 0x184c, 0x3028, 0x0070, 0x0c04, 0x2494, 0x1850, 0x302c, 0x0074, 0x0c08, 0x2498, 0x1950, 0x312c, 0x0174, 0x0d08, 0x2598, 0x1a50, 0x322c, 0x0274, 0x0e08, 0x2698, 0x1a54, 0x3230, 0x0278, 0x0e0c, 0x269c, 0x1954, 0x3130, 0x0178, 0x0d0c, 0x259c, 0x1854, 0x3030, 0x0078, 0x0c0c, 0x249c, 0x1858, 0x3034, 0x007c, 0x0c10, 0x24a0, 0x1958, 0x3134, 0x017c, 0x0d10, 0x25a0, 0x1a58, 0x3234, 0x027c, 0x0e10, 0x26a0, 0x1a5c, 0x3238, 0x0280, 0x0e14, 0x26a4, 0x195c, 0x3138, 0x0180, 0x0d14, 0x25a4, 0x185c, 0x3038, 0x0080, 0x0c14, 0x24a4, 0x1860, 0x303c, 0x0084, 0x0c18, 0x24a8, 0x1960, 0x313c, 0x0184, 0x0d18, 0x25a8, 0x1a60, 0x323c, 0x0284, 0x0e18, 0x26a8, 0x1a64, 0x3240, 0x0288, 0x0e1c, 0x26ac, 0x1964, 0x3140, 0x0188, 0x0d1c, 0x25ac, 0x1864, 0x3040, 0x0088, 0x0c1c, 0x24ac, 0x1868, 0x3044, 0x008c, 0x0c20, 0x24b0, 0x1968, 0x3144, 0x018c, 0x0d20, 0x25b0, 0x1a68, 0x3244, 0x028c, 0x0e20, 0x26b0, 0x1e48, 0x3624, 0x066c, 0x1200, 0x2a90, 0x1f48, 0x3724, 0x076c, 0x1300, 0x2b90, 0x2048, 0x3824, 0x086c, 0x1400, 0x2c90, 0x204c, 0x3828, 0x0870, 0x1404, 0x2c94, 0x1f4c, 0x3728, 0x0770, 0x1304, 0x2b94, 0x1e4c, 0x3628, 0x0670, 0x1204, 0x2a94, 0x1e50, 0x362c, 0x0674, 0x1208, 0x2a98, 0x1f50, 0x372c, 0x0774, 0x1308, 0x2b98, 0x2050, 0x382c, 0x0874, 0x1408, 0x2c98, 0x2054, 0x3830, 0x0878, 0x140c, 0x2c9c, 0x1f54, 0x3730, 0x0778, 0x130c, 0x2b9c, 0x1e54, 0x3630, 0x0678, 0x120c, 0x2a9c, 0x1e58, 0x3634, 0x067c, 0x1210, 0x2aa0, 0x1f58, 0x3734, 0x077c, 0x1310, 0x2ba0, 0x2058, 0x3834, 0x087c, 0x1410, 0x2ca0, 0x205c, 0x3838, 0x0880, 0x1414, 0x2ca4, 0x1f5c, 0x3738, 0x0780, 0x1314, 0x2ba4, 0x1e5c, 0x3638, 0x0680, 0x1214, 0x2aa4, 0x1e60, 0x363c, 0x0684, 0x1218, 0x2aa8, 0x1f60, 0x373c, 0x0784, 0x1318, 0x2ba8, 0x2060, 0x383c, 0x0884, 0x1418, 0x2ca8, 0x2064, 0x3840, 0x0888, 0x141c, 0x2cac, 0x1f64, 0x3740, 0x0788, 0x131c, 0x2bac, 0x1e64, 0x3640, 0x0688, 0x121c, 0x2aac, 0x1e68, 0x3644, 0x068c, 0x1220, 0x2ab0, 0x1f68, 0x3744, 0x078c, 0x1320, 0x2bb0, 0x2068, 0x3844, 0x088c, 0x1420, 0x2cb0, 0x2448, 0x0024, 0x0c6c, 0x1800, 0x3090, 0x2548, 0x0124, 0x0d6c, 0x1900, 0x3190, 0x2648, 0x0224, 0x0e6c, 0x1a00, 0x3290, 0x264c, 0x0228, 0x0e70, 0x1a04, 0x3294, 0x254c, 0x0128, 0x0d70, 0x1904, 0x3194, 0x244c, 0x0028, 0x0c70, 0x1804, 0x3094, 0x2450, 0x002c, 0x0c74, 0x1808, 0x3098, 0x2550, 0x012c, 0x0d74, 0x1908, 0x3198, 0x2650, 0x022c, 0x0e74, 0x1a08, 0x3298, 0x2654, 0x0230, 0x0e78, 0x1a0c, 0x329c, 0x2554, 0x0130, 0x0d78, 0x190c, 0x319c, 0x2454, 0x0030, 0x0c78, 0x180c, 0x309c, 0x2458, 0x0034, 0x0c7c, 0x1810, 0x30a0, 0x2558, 0x0134, 0x0d7c, 0x1910, 0x31a0, 0x2658, 0x0234, 0x0e7c, 0x1a10, 0x32a0, 0x265c, 0x0238, 0x0e80, 0x1a14, 0x32a4, 0x255c, 0x0138, 0x0d80, 0x1914, 0x31a4, 0x245c, 0x0038, 0x0c80, 0x1814, 0x30a4, 0x2460, 0x003c, 0x0c84, 0x1818, 0x30a8, 0x2560, 0x013c, 0x0d84, 0x1918, 0x31a8, 0x2660, 0x023c, 0x0e84, 0x1a18, 0x32a8, 0x2664, 0x0240, 0x0e88, 0x1a1c, 0x32ac, 0x2564, 0x0140, 0x0d88, 0x191c, 0x31ac, 0x2464, 0x0040, 0x0c88, 0x181c, 0x30ac, 0x2468, 0x0044, 0x0c8c, 0x1820, 0x30b0, 0x2568, 0x0144, 0x0d8c, 0x1920, 0x31b0, 0x2668, 0x0244, 0x0e8c, 0x1a20, 0x32b0, 0x2a48, 0x0624, 0x126c, 0x1e00, 0x3690, 0x2b48, 0x0724, 0x136c, 0x1f00, 0x3790, 0x2c48, 0x0824, 0x146c, 0x2000, 0x3890, 0x2c4c, 0x0828, 0x1470, 0x2004, 0x3894, 0x2b4c, 0x0728, 0x1370, 0x1f04, 0x3794, 0x2a4c, 0x0628, 0x1270, 0x1e04, 0x3694, 0x2a50, 0x062c, 0x1274, 0x1e08, 0x3698, 0x2b50, 0x072c, 0x1374, 0x1f08, 0x3798, 0x2c50, 0x082c, 0x1474, 0x2008, 0x3898, 0x2c54, 0x0830, 0x1478, 0x200c, 0x389c, 0x2b54, 0x0730, 0x1378, 0x1f0c, 0x379c, 0x2a54, 0x0630, 0x1278, 0x1e0c, 0x369c, 0x2a58, 0x0634, 0x127c, 0x1e10, 0x36a0, 0x2b58, 0x0734, 0x137c, 0x1f10, 0x37a0, 0x2c58, 0x0834, 0x147c, 0x2010, 0x38a0, 0x2c5c, 0x0838, 0x1480, 0x2014, 0x38a4, 0x2b5c, 0x0738, 0x1380, 0x1f14, 0x37a4, 0x2a5c, 0x0638, 0x1280, 0x1e14, 0x36a4, 0x2a60, 0x063c, 0x1284, 0x1e18, 0x36a8, 0x2b60, 0x073c, 0x1384, 0x1f18, 0x37a8, 0x2c60, 0x083c, 0x1484, 0x2018, 0x38a8, 0x2c64, 0x0840, 0x1488, 0x201c, 0x38ac, 0x2b64, 0x0740, 0x1388, 0x1f1c, 0x37ac, 0x2a64, 0x0640, 0x1288, 0x1e1c, 0x36ac, 0x2a68, 0x0644, 0x128c, 0x1e20, 0x36b0, 0x2b68, 0x0744, 0x138c, 0x1f20, 0x37b0, 0x2c68, 0x0844, 0x148c, 0x2020, 0x38b0, 0x3048, 0x0c24, 0x186c, 0x2400, 0x0090, 0x3148, 0x0d24, 0x196c, 0x2500, 0x0190, 0x3248, 0x0e24, 0x1a6c, 0x2600, 0x0290, 0x324c, 0x0e28, 0x1a70, 0x2604, 0x0294, 0x314c, 0x0d28, 0x1970, 0x2504, 0x0194, 0x304c, 0x0c28, 0x1870, 0x2404, 0x0094, 0x3050, 0x0c2c, 0x1874, 0x2408, 0x0098, 0x3150, 0x0d2c, 0x1974, 0x2508, 0x0198, 0x3250, 0x0e2c, 0x1a74, 0x2608, 0x0298, 0x3254, 0x0e30, 0x1a78, 0x260c, 0x029c, 0x3154, 0x0d30, 0x1978, 0x250c, 0x019c, 0x3054, 0x0c30, 0x1878, 0x240c, 0x009c, 0x3058, 0x0c34, 0x187c, 0x2410, 0x00a0, 0x3158, 0x0d34, 0x197c, 0x2510, 0x01a0, 0x3258, 0x0e34, 0x1a7c, 0x2610, 0x02a0, 0x325c, 0x0e38, 0x1a80, 0x2614, 0x02a4, 0x315c, 0x0d38, 0x1980, 0x2514, 0x01a4, 0x305c, 0x0c38, 0x1880, 0x2414, 0x00a4, 0x3060, 0x0c3c, 0x1884, 0x2418, 0x00a8, 0x3160, 0x0d3c, 0x1984, 0x2518, 0x01a8, 0x3260, 0x0e3c, 0x1a84, 0x2618, 0x02a8, 0x3264, 0x0e40, 0x1a88, 0x261c, 0x02ac, 0x3164, 0x0d40, 0x1988, 0x251c, 0x01ac, 0x3064, 0x0c40, 0x1888, 0x241c, 0x00ac, 0x3068, 0x0c44, 0x188c, 0x2420, 0x00b0, 0x3168, 0x0d44, 0x198c, 0x2520, 0x01b0, 0x3268, 0x0e44, 0x1a8c, 0x2620, 0x02b0, 0x3648, 0x1224, 0x1e6c, 0x2a00, 0x0690, 0x3748, 0x1324, 0x1f6c, 0x2b00, 0x0790, 0x3848, 0x1424, 0x206c, 0x2c00, 0x0890, 0x384c, 0x1428, 0x2070, 0x2c04, 0x0894, 0x374c, 0x1328, 0x1f70, 0x2b04, 0x0794, 0x364c, 0x1228, 0x1e70, 0x2a04, 0x0694, 0x3650, 0x122c, 0x1e74, 0x2a08, 0x0698, 0x3750, 0x132c, 0x1f74, 0x2b08, 0x0798, 0x3850, 0x142c, 0x2074, 0x2c08, 0x0898, 0x3854, 0x1430, 0x2078, 0x2c0c, 0x089c, 0x3754, 0x1330, 0x1f78, 0x2b0c, 0x079c, 0x3654, 0x1230, 0x1e78, 0x2a0c, 0x069c, 0x3658, 0x1234, 0x1e7c, 0x2a10, 0x06a0, 0x3758, 0x1334, 0x1f7c, 0x2b10, 0x07a0, 0x3858, 0x1434, 0x207c, 0x2c10, 0x08a0, 0x385c, 0x1438, 0x2080, 0x2c14, 0x08a4, 0x375c, 0x1338, 0x1f80, 0x2b14, 0x07a4, 0x365c, 0x1238, 0x1e80, 0x2a14, 0x06a4, 0x3660, 0x123c, 0x1e84, 0x2a18, 0x06a8, 0x3760, 0x133c, 0x1f84, 0x2b18, 0x07a8, 0x3860, 0x143c, 0x2084, 0x2c18, 0x08a8, 0x3864, 0x1440, 0x2088, 0x2c1c, 0x08ac, 0x3764, 0x1340, 0x1f88, 0x2b1c, 0x07ac, 0x3664, 0x1240, 0x1e88, 0x2a1c, 0x06ac, 0x3668, 0x1244, 0x1e8c, 0x2a20, 0x06b0, 0x3768, 0x1344, 0x1f8c, 0x2b20, 0x07b0, 0x3868, 0x1444, 0x208c, 0x2c20, 0x08b0, 0x0048, 0x1824, 0x246c, 0x3000, 0x0c90, 0x0148, 0x1924, 0x256c, 0x3100, 0x0d90, 0x0248, 0x1a24, 0x266c, 0x3200, 0x0e90, 0x024c, 0x1a28, 0x2670, 0x3204, 0x0e94, 0x014c, 0x1928, 0x2570, 0x3104, 0x0d94, 0x004c, 0x1828, 0x2470, 0x3004, 0x0c94, 0x0050, 0x182c, 0x2474, 0x3008, 0x0c98, 0x0150, 0x192c, 0x2574, 0x3108, 0x0d98, 0x0250, 0x1a2c, 0x2674, 0x3208, 0x0e98, 0x0254, 0x1a30, 0x2678, 0x320c, 0x0e9c, 0x0154, 0x1930, 0x2578, 0x310c, 0x0d9c, 0x0054, 0x1830, 0x2478, 0x300c, 0x0c9c, 0x0058, 0x1834, 0x247c, 0x3010, 0x0ca0, 0x0158, 0x1934, 0x257c, 0x3110, 0x0da0, 0x0258, 0x1a34, 0x267c, 0x3210, 0x0ea0, 0x025c, 0x1a38, 0x2680, 0x3214, 0x0ea4, 0x015c, 0x1938, 0x2580, 0x3114, 0x0da4, 0x005c, 0x1838, 0x2480, 0x3014, 0x0ca4, 0x0060, 0x183c, 0x2484, 0x3018, 0x0ca8, 0x0160, 0x193c, 0x2584, 0x3118, 0x0da8, 0x0260, 0x1a3c, 0x2684, 0x3218, 0x0ea8, 0x0264, 0x1a40, 0x2688, 0x321c, 0x0eac, 0x0164, 0x1940, 0x2588, 0x311c, 0x0dac, 0x0064, 0x1840, 0x2488, 0x301c, 0x0cac, 0x0068, 0x1844, 0x248c, 0x3020, 0x0cb0, 0x0168, 0x1944, 0x258c, 0x3120, 0x0db0, 0x0268, 0x1a44, 0x268c, 0x3220, 0x0eb0, 0x0648, 0x1e24, 0x2a6c, 0x3600, 0x1290, 0x0748, 0x1f24, 0x2b6c, 0x3700, 0x1390, 0x0848, 0x2024, 0x2c6c, 0x3800, 0x1490, 0x084c, 0x2028, 0x2c70, 0x3804, 0x1494, 0x074c, 0x1f28, 0x2b70, 0x3704, 0x1394, 0x064c, 0x1e28, 0x2a70, 0x3604, 0x1294, 0x0650, 0x1e2c, 0x2a74, 0x3608, 0x1298, 0x0750, 0x1f2c, 0x2b74, 0x3708, 0x1398, 0x0850, 0x202c, 0x2c74, 0x3808, 0x1498, 0x0854, 0x2030, 0x2c78, 0x380c, 0x149c, 0x0754, 0x1f30, 0x2b78, 0x370c, 0x139c, 0x0654, 0x1e30, 0x2a78, 0x360c, 0x129c, 0x0658, 0x1e34, 0x2a7c, 0x3610, 0x12a0, 0x0758, 0x1f34, 0x2b7c, 0x3710, 0x13a0, 0x0858, 0x2034, 0x2c7c, 0x3810, 0x14a0, 0x085c, 0x2038, 0x2c80, 0x3814, 0x14a4, 0x075c, 0x1f38, 0x2b80, 0x3714, 0x13a4, 0x065c, 0x1e38, 0x2a80, 0x3614, 0x12a4, 0x0660, 0x1e3c, 0x2a84, 0x3618, 0x12a8, 0x0760, 0x1f3c, 0x2b84, 0x3718, 0x13a8, 0x0860, 0x203c, 0x2c84, 0x3818, 0x14a8, 0x0864, 0x2040, 0x2c88, 0x381c, 0x14ac, 0x0764, 0x1f40, 0x2b88, 0x371c, 0x13ac, 0x0664, 0x1e40, 0x2a88, 0x361c, 0x12ac, 0x0668, 0x1e44, 0x2a8c, 0x3620, 0x12b0, 0x0768, 0x1f44, 0x2b8c, 0x3720, 0x13b0, 0x0868, 0x2044, 0x2c8c, 0x3820, 0x14b0, 0x0f48, 0x2724, 0x336c, 0x0300, 0x1b90, 0x1048, 0x2824, 0x346c, 0x0400, 0x1c90, 0x1148, 0x2924, 0x356c, 0x0500, 0x1d90, 0x114c, 0x2928, 0x3570, 0x0504, 0x1d94, 0x104c, 0x2828, 0x3470, 0x0404, 0x1c94, 0x0f4c, 0x2728, 0x3370, 0x0304, 0x1b94, 0x0f50, 0x272c, 0x3374, 0x0308, 0x1b98, 0x1050, 0x282c, 0x3474, 0x0408, 0x1c98, 0x1150, 0x292c, 0x3574, 0x0508, 0x1d98, 0x1154, 0x2930, 0x3578, 0x050c, 0x1d9c, 0x1054, 0x2830, 0x3478, 0x040c, 0x1c9c, 0x0f54, 0x2730, 0x3378, 0x030c, 0x1b9c, 0x0f58, 0x2734, 0x337c, 0x0310, 0x1ba0, 0x1058, 0x2834, 0x347c, 0x0410, 0x1ca0, 0x1158, 0x2934, 0x357c, 0x0510, 0x1da0, 0x115c, 0x2938, 0x3580, 0x0514, 0x1da4, 0x105c, 0x2838, 0x3480, 0x0414, 0x1ca4, 0x0f5c, 0x2738, 0x3380, 0x0314, 0x1ba4, 0x0f60, 0x273c, 0x3384, 0x0318, 0x1ba8, 0x1060, 0x283c, 0x3484, 0x0418, 0x1ca8, 0x1160, 0x293c, 0x3584, 0x0518, 0x1da8, 0x1164, 0x2940, 0x3588, 0x051c, 0x1dac, 0x1064, 0x2840, 0x3488, 0x041c, 0x1cac, 0x0f64, 0x2740, 0x3388, 0x031c, 0x1bac, 0x0f68, 0x2744, 0x338c, 0x0320, 0x1bb0, 0x1068, 0x2844, 0x348c, 0x0420, 0x1cb0, 0x1168, 0x2944, 0x358c, 0x0520, 0x1db0, 0x1548, 0x2d24, 0x396c, 0x0900, 0x2190, 0x1648, 0x2e24, 0x3a6c, 0x0a00, 0x2290, 0x1748, 0x2f24, 0x3b6c, 0x0b00, 0x2390, 0x174c, 0x2f28, 0x3b70, 0x0b04, 0x2394, 0x164c, 0x2e28, 0x3a70, 0x0a04, 0x2294, 0x154c, 0x2d28, 0x3970, 0x0904, 0x2194, 0x1550, 0x2d2c, 0x3974, 0x0908, 0x2198, 0x1650, 0x2e2c, 0x3a74, 0x0a08, 0x2298, 0x1750, 0x2f2c, 0x3b74, 0x0b08, 0x2398, 0x1754, 0x2f30, 0x3b78, 0x0b0c, 0x239c, 0x1654, 0x2e30, 0x3a78, 0x0a0c, 0x229c, 0x1554, 0x2d30, 0x3978, 0x090c, 0x219c, 0x1558, 0x2d34, 0x397c, 0x0910, 0x21a0, 0x1658, 0x2e34, 0x3a7c, 0x0a10, 0x22a0, 0x1758, 0x2f34, 0x3b7c, 0x0b10, 0x23a0, 0x175c, 0x2f38, 0x3b80, 0x0b14, 0x23a4, 0x165c, 0x2e38, 0x3a80, 0x0a14, 0x22a4, 0x155c, 0x2d38, 0x3980, 0x0914, 0x21a4, 0x1560, 0x2d3c, 0x3984, 0x0918, 0x21a8, 0x1660, 0x2e3c, 0x3a84, 0x0a18, 0x22a8, 0x1760, 0x2f3c, 0x3b84, 0x0b18, 0x23a8, 0x1764, 0x2f40, 0x3b88, 0x0b1c, 0x23ac, 0x1664, 0x2e40, 0x3a88, 0x0a1c, 0x22ac, 0x1564, 0x2d40, 0x3988, 0x091c, 0x21ac, 0x1568, 0x2d44, 0x398c, 0x0920, 0x21b0, 0x1668, 0x2e44, 0x3a8c, 0x0a20, 0x22b0, 0x1768, 0x2f44, 0x3b8c, 0x0b20, 0x23b0, 0x1b48, 0x3324, 0x036c, 0x0f00, 0x2790, 0x1c48, 0x3424, 0x046c, 0x1000, 0x2890, 0x1d48, 0x3524, 0x056c, 0x1100, 0x2990, 0x1d4c, 0x3528, 0x0570, 0x1104, 0x2994, 0x1c4c, 0x3428, 0x0470, 0x1004, 0x2894, 0x1b4c, 0x3328, 0x0370, 0x0f04, 0x2794, 0x1b50, 0x332c, 0x0374, 0x0f08, 0x2798, 0x1c50, 0x342c, 0x0474, 0x1008, 0x2898, 0x1d50, 0x352c, 0x0574, 0x1108, 0x2998, 0x1d54, 0x3530, 0x0578, 0x110c, 0x299c, 0x1c54, 0x3430, 0x0478, 0x100c, 0x289c, 0x1b54, 0x3330, 0x0378, 0x0f0c, 0x279c, 0x1b58, 0x3334, 0x037c, 0x0f10, 0x27a0, 0x1c58, 0x3434, 0x047c, 0x1010, 0x28a0, 0x1d58, 0x3534, 0x057c, 0x1110, 0x29a0, 0x1d5c, 0x3538, 0x0580, 0x1114, 0x29a4, 0x1c5c, 0x3438, 0x0480, 0x1014, 0x28a4, 0x1b5c, 0x3338, 0x0380, 0x0f14, 0x27a4, 0x1b60, 0x333c, 0x0384, 0x0f18, 0x27a8, 0x1c60, 0x343c, 0x0484, 0x1018, 0x28a8, 0x1d60, 0x353c, 0x0584, 0x1118, 0x29a8, 0x1d64, 0x3540, 0x0588, 0x111c, 0x29ac, 0x1c64, 0x3440, 0x0488, 0x101c, 0x28ac, 0x1b64, 0x3340, 0x0388, 0x0f1c, 0x27ac, 0x1b68, 0x3344, 0x038c, 0x0f20, 0x27b0, 0x1c68, 0x3444, 0x048c, 0x1020, 0x28b0, 0x1d68, 0x3544, 0x058c, 0x1120, 0x29b0, 0x2148, 0x3924, 0x096c, 0x1500, 0x2d90, 0x2248, 0x3a24, 0x0a6c, 0x1600, 0x2e90, 0x2348, 0x3b24, 0x0b6c, 0x1700, 0x2f90, 0x234c, 0x3b28, 0x0b70, 0x1704, 0x2f94, 0x224c, 0x3a28, 0x0a70, 0x1604, 0x2e94, 0x214c, 0x3928, 0x0970, 0x1504, 0x2d94, 0x2150, 0x392c, 0x0974, 0x1508, 0x2d98, 0x2250, 0x3a2c, 0x0a74, 0x1608, 0x2e98, 0x2350, 0x3b2c, 0x0b74, 0x1708, 0x2f98, 0x2354, 0x3b30, 0x0b78, 0x170c, 0x2f9c, 0x2254, 0x3a30, 0x0a78, 0x160c, 0x2e9c, 0x2154, 0x3930, 0x0978, 0x150c, 0x2d9c, 0x2158, 0x3934, 0x097c, 0x1510, 0x2da0, 0x2258, 0x3a34, 0x0a7c, 0x1610, 0x2ea0, 0x2358, 0x3b34, 0x0b7c, 0x1710, 0x2fa0, 0x235c, 0x3b38, 0x0b80, 0x1714, 0x2fa4, 0x225c, 0x3a38, 0x0a80, 0x1614, 0x2ea4, 0x215c, 0x3938, 0x0980, 0x1514, 0x2da4, 0x2160, 0x393c, 0x0984, 0x1518, 0x2da8, 0x2260, 0x3a3c, 0x0a84, 0x1618, 0x2ea8, 0x2360, 0x3b3c, 0x0b84, 0x1718, 0x2fa8, 0x2364, 0x3b40, 0x0b88, 0x171c, 0x2fac, 0x2264, 0x3a40, 0x0a88, 0x161c, 0x2eac, 0x2164, 0x3940, 0x0988, 0x151c, 0x2dac, 0x2168, 0x3944, 0x098c, 0x1520, 0x2db0, 0x2268, 0x3a44, 0x0a8c, 0x1620, 0x2eb0, 0x2368, 0x3b44, 0x0b8c, 0x1720, 0x2fb0, 0x2748, 0x0324, 0x0f6c, 0x1b00, 0x3390, 0x2848, 0x0424, 0x106c, 0x1c00, 0x3490, 0x2948, 0x0524, 0x116c, 0x1d00, 0x3590, 0x294c, 0x0528, 0x1170, 0x1d04, 0x3594, 0x284c, 0x0428, 0x1070, 0x1c04, 0x3494, 0x274c, 0x0328, 0x0f70, 0x1b04, 0x3394, 0x2750, 0x032c, 0x0f74, 0x1b08, 0x3398, 0x2850, 0x042c, 0x1074, 0x1c08, 0x3498, 0x2950, 0x052c, 0x1174, 0x1d08, 0x3598, 0x2954, 0x0530, 0x1178, 0x1d0c, 0x359c, 0x2854, 0x0430, 0x1078, 0x1c0c, 0x349c, 0x2754, 0x0330, 0x0f78, 0x1b0c, 0x339c, 0x2758, 0x0334, 0x0f7c, 0x1b10, 0x33a0, 0x2858, 0x0434, 0x107c, 0x1c10, 0x34a0, 0x2958, 0x0534, 0x117c, 0x1d10, 0x35a0, 0x295c, 0x0538, 0x1180, 0x1d14, 0x35a4, 0x285c, 0x0438, 0x1080, 0x1c14, 0x34a4, 0x275c, 0x0338, 0x0f80, 0x1b14, 0x33a4, 0x2760, 0x033c, 0x0f84, 0x1b18, 0x33a8, 0x2860, 0x043c, 0x1084, 0x1c18, 0x34a8, 0x2960, 0x053c, 0x1184, 0x1d18, 0x35a8, 0x2964, 0x0540, 0x1188, 0x1d1c, 0x35ac, 0x2864, 0x0440, 0x1088, 0x1c1c, 0x34ac, 0x2764, 0x0340, 0x0f88, 0x1b1c, 0x33ac, 0x2768, 0x0344, 0x0f8c, 0x1b20, 0x33b0, 0x2868, 0x0444, 0x108c, 0x1c20, 0x34b0, 0x2968, 0x0544, 0x118c, 0x1d20, 0x35b0, 0x2d48, 0x0924, 0x156c, 0x2100, 0x3990, 0x2e48, 0x0a24, 0x166c, 0x2200, 0x3a90, 0x2f48, 0x0b24, 0x176c, 0x2300, 0x3b90, 0x2f4c, 0x0b28, 0x1770, 0x2304, 0x3b94, 0x2e4c, 0x0a28, 0x1670, 0x2204, 0x3a94, 0x2d4c, 0x0928, 0x1570, 0x2104, 0x3994, 0x2d50, 0x092c, 0x1574, 0x2108, 0x3998, 0x2e50, 0x0a2c, 0x1674, 0x2208, 0x3a98, 0x2f50, 0x0b2c, 0x1774, 0x2308, 0x3b98, 0x2f54, 0x0b30, 0x1778, 0x230c, 0x3b9c, 0x2e54, 0x0a30, 0x1678, 0x220c, 0x3a9c, 0x2d54, 0x0930, 0x1578, 0x210c, 0x399c, 0x2d58, 0x0934, 0x157c, 0x2110, 0x39a0, 0x2e58, 0x0a34, 0x167c, 0x2210, 0x3aa0, 0x2f58, 0x0b34, 0x177c, 0x2310, 0x3ba0, 0x2f5c, 0x0b38, 0x1780, 0x2314, 0x3ba4, 0x2e5c, 0x0a38, 0x1680, 0x2214, 0x3aa4, 0x2d5c, 0x0938, 0x1580, 0x2114, 0x39a4, 0x2d60, 0x093c, 0x1584, 0x2118, 0x39a8, 0x2e60, 0x0a3c, 0x1684, 0x2218, 0x3aa8, 0x2f60, 0x0b3c, 0x1784, 0x2318, 0x3ba8, 0x2f64, 0x0b40, 0x1788, 0x231c, 0x3bac, 0x2e64, 0x0a40, 0x1688, 0x221c, 0x3aac, 0x2d64, 0x0940, 0x1588, 0x211c, 0x39ac, 0x2d68, 0x0944, 0x158c, 0x2120, 0x39b0, 0x2e68, 0x0a44, 0x168c, 0x2220, 0x3ab0, 0x2f68, 0x0b44, 0x178c, 0x2320, 0x3bb0, 0x3348, 0x0f24, 0x1b6c, 0x2700, 0x0390, 0x3448, 0x1024, 0x1c6c, 0x2800, 0x0490, 0x3548, 0x1124, 0x1d6c, 0x2900, 0x0590, 0x354c, 0x1128, 0x1d70, 0x2904, 0x0594, 0x344c, 0x1028, 0x1c70, 0x2804, 0x0494, 0x334c, 0x0f28, 0x1b70, 0x2704, 0x0394, 0x3350, 0x0f2c, 0x1b74, 0x2708, 0x0398, 0x3450, 0x102c, 0x1c74, 0x2808, 0x0498, 0x3550, 0x112c, 0x1d74, 0x2908, 0x0598, 0x3554, 0x1130, 0x1d78, 0x290c, 0x059c, 0x3454, 0x1030, 0x1c78, 0x280c, 0x049c, 0x3354, 0x0f30, 0x1b78, 0x270c, 0x039c, 0x3358, 0x0f34, 0x1b7c, 0x2710, 0x03a0, 0x3458, 0x1034, 0x1c7c, 0x2810, 0x04a0, 0x3558, 0x1134, 0x1d7c, 0x2910, 0x05a0, 0x355c, 0x1138, 0x1d80, 0x2914, 0x05a4, 0x345c, 0x1038, 0x1c80, 0x2814, 0x04a4, 0x335c, 0x0f38, 0x1b80, 0x2714, 0x03a4, 0x3360, 0x0f3c, 0x1b84, 0x2718, 0x03a8, 0x3460, 0x103c, 0x1c84, 0x2818, 0x04a8, 0x3560, 0x113c, 0x1d84, 0x2918, 0x05a8, 0x3564, 0x1140, 0x1d88, 0x291c, 0x05ac, 0x3464, 0x1040, 0x1c88, 0x281c, 0x04ac, 0x3364, 0x0f40, 0x1b88, 0x271c, 0x03ac, 0x3368, 0x0f44, 0x1b8c, 0x2720, 0x03b0, 0x3468, 0x1044, 0x1c8c, 0x2820, 0x04b0, 0x3568, 0x1144, 0x1d8c, 0x2920, 0x05b0, 0x3948, 0x1524, 0x216c, 0x2d00, 0x0990, 0x3a48, 0x1624, 0x226c, 0x2e00, 0x0a90, 0x3b48, 0x1724, 0x236c, 0x2f00, 0x0b90, 0x3b4c, 0x1728, 0x2370, 0x2f04, 0x0b94, 0x3a4c, 0x1628, 0x2270, 0x2e04, 0x0a94, 0x394c, 0x1528, 0x2170, 0x2d04, 0x0994, 0x3950, 0x152c, 0x2174, 0x2d08, 0x0998, 0x3a50, 0x162c, 0x2274, 0x2e08, 0x0a98, 0x3b50, 0x172c, 0x2374, 0x2f08, 0x0b98, 0x3b54, 0x1730, 0x2378, 0x2f0c, 0x0b9c, 0x3a54, 0x1630, 0x2278, 0x2e0c, 0x0a9c, 0x3954, 0x1530, 0x2178, 0x2d0c, 0x099c, 0x3958, 0x1534, 0x217c, 0x2d10, 0x09a0, 0x3a58, 0x1634, 0x227c, 0x2e10, 0x0aa0, 0x3b58, 0x1734, 0x237c, 0x2f10, 0x0ba0, 0x3b5c, 0x1738, 0x2380, 0x2f14, 0x0ba4, 0x3a5c, 0x1638, 0x2280, 0x2e14, 0x0aa4, 0x395c, 0x1538, 0x2180, 0x2d14, 0x09a4, 0x3960, 0x153c, 0x2184, 0x2d18, 0x09a8, 0x3a60, 0x163c, 0x2284, 0x2e18, 0x0aa8, 0x3b60, 0x173c, 0x2384, 0x2f18, 0x0ba8, 0x3b64, 0x1740, 0x2388, 0x2f1c, 0x0bac, 0x3a64, 0x1640, 0x2288, 0x2e1c, 0x0aac, 0x3964, 0x1540, 0x2188, 0x2d1c, 0x09ac, 0x3968, 0x1544, 0x218c, 0x2d20, 0x09b0, 0x3a68, 0x1644, 0x228c, 0x2e20, 0x0ab0, 0x3b68, 0x1744, 0x238c, 0x2f20, 0x0bb0, 0x0348, 0x1b24, 0x276c, 0x3300, 0x0f90, 0x0448, 0x1c24, 0x286c, 0x3400, 0x1090, 0x0548, 0x1d24, 0x296c, 0x3500, 0x1190, 0x054c, 0x1d28, 0x2970, 0x3504, 0x1194, 0x044c, 0x1c28, 0x2870, 0x3404, 0x1094, 0x034c, 0x1b28, 0x2770, 0x3304, 0x0f94, 0x0350, 0x1b2c, 0x2774, 0x3308, 0x0f98, 0x0450, 0x1c2c, 0x2874, 0x3408, 0x1098, 0x0550, 0x1d2c, 0x2974, 0x3508, 0x1198, 0x0554, 0x1d30, 0x2978, 0x350c, 0x119c, 0x0454, 0x1c30, 0x2878, 0x340c, 0x109c, 0x0354, 0x1b30, 0x2778, 0x330c, 0x0f9c, 0x0358, 0x1b34, 0x277c, 0x3310, 0x0fa0, 0x0458, 0x1c34, 0x287c, 0x3410, 0x10a0, 0x0558, 0x1d34, 0x297c, 0x3510, 0x11a0, 0x055c, 0x1d38, 0x2980, 0x3514, 0x11a4, 0x045c, 0x1c38, 0x2880, 0x3414, 0x10a4, 0x035c, 0x1b38, 0x2780, 0x3314, 0x0fa4, 0x0360, 0x1b3c, 0x2784, 0x3318, 0x0fa8, 0x0460, 0x1c3c, 0x2884, 0x3418, 0x10a8, 0x0560, 0x1d3c, 0x2984, 0x3518, 0x11a8, 0x0564, 0x1d40, 0x2988, 0x351c, 0x11ac, 0x0464, 0x1c40, 0x2888, 0x341c, 0x10ac, 0x0364, 0x1b40, 0x2788, 0x331c, 0x0fac, 0x0368, 0x1b44, 0x278c, 0x3320, 0x0fb0, 0x0468, 0x1c44, 0x288c, 0x3420, 0x10b0, 0x0568, 0x1d44, 0x298c, 0x3520, 0x11b0, 0x0948, 0x2124, 0x2d6c, 0x3900, 0x1590, 0x0a48, 0x2224, 0x2e6c, 0x3a00, 0x1690, 0x0b48, 0x2324, 0x2f6c, 0x3b00, 0x1790, 0x0b4c, 0x2328, 0x2f70, 0x3b04, 0x1794, 0x0a4c, 0x2228, 0x2e70, 0x3a04, 0x1694, 0x094c, 0x2128, 0x2d70, 0x3904, 0x1594, 0x0950, 0x212c, 0x2d74, 0x3908, 0x1598, 0x0a50, 0x222c, 0x2e74, 0x3a08, 0x1698, 0x0b50, 0x232c, 0x2f74, 0x3b08, 0x1798, 0x0b54, 0x2330, 0x2f78, 0x3b0c, 0x179c, 0x0a54, 0x2230, 0x2e78, 0x3a0c, 0x169c, 0x0954, 0x2130, 0x2d78, 0x390c, 0x159c, 0x0958, 0x2134, 0x2d7c, 0x3910, 0x15a0, 0x0a58, 0x2234, 0x2e7c, 0x3a10, 0x16a0, 0x0b58, 0x2334, 0x2f7c, 0x3b10, 0x17a0, 0x0b5c, 0x2338, 0x2f80, 0x3b14, 0x17a4, 0x0a5c, 0x2238, 0x2e80, 0x3a14, 0x16a4, 0x095c, 0x2138, 0x2d80, 0x3914, 0x15a4, 0x0960, 0x213c, 0x2d84, 0x3918, 0x15a8, 0x0a60, 0x223c, 0x2e84, 0x3a18, 0x16a8, 0x0b60, 0x233c, 0x2f84, 0x3b18, 0x17a8, 0x0b64, 0x2340, 0x2f88, 0x3b1c, 0x17ac, 0x0a64, 0x2240, 0x2e88, 0x3a1c, 0x16ac, 0x0964, 0x2140, 0x2d88, 0x391c, 0x15ac, 0x0968, 0x2144, 0x2d8c, 0x3920, 0x15b0, 0x0a68, 0x2244, 0x2e8c, 0x3a20, 0x16b0, 0x0b68, 0x2344, 0x2f8c, 0x3b20, 0x17b0, }; /* 2 channels per frame, 12 DIF sequences per channel, 27 video segments per DIF sequence, 5 macroblocks per video segment */ static const uint16_t dv_place_422_625[2*12*27*5] = { 0x0c48, 0x2424, 0x306c, 0x0000, 0x1890, 0x0d48, 0x2524, 0x316c, 0x0100, 0x1990, 0x0e48, 0x2624, 0x326c, 0x0200, 0x1a90, 0x0e4c, 0x2628, 0x3270, 0x0204, 0x1a94, 0x0d4c, 0x2528, 0x3170, 0x0104, 0x1994, 0x0c4c, 0x2428, 0x3070, 0x0004, 0x1894, 0x0c50, 0x242c, 0x3074, 0x0008, 0x1898, 0x0d50, 0x252c, 0x3174, 0x0108, 0x1998, 0x0e50, 0x262c, 0x3274, 0x0208, 0x1a98, 0x0e54, 0x2630, 0x3278, 0x020c, 0x1a9c, 0x0d54, 0x2530, 0x3178, 0x010c, 0x199c, 0x0c54, 0x2430, 0x3078, 0x000c, 0x189c, 0x0c58, 0x2434, 0x307c, 0x0010, 0x18a0, 0x0d58, 0x2534, 0x317c, 0x0110, 0x19a0, 0x0e58, 0x2634, 0x327c, 0x0210, 0x1aa0, 0x0e5c, 0x2638, 0x3280, 0x0214, 0x1aa4, 0x0d5c, 0x2538, 0x3180, 0x0114, 0x19a4, 0x0c5c, 0x2438, 0x3080, 0x0014, 0x18a4, 0x0c60, 0x243c, 0x3084, 0x0018, 0x18a8, 0x0d60, 0x253c, 0x3184, 0x0118, 0x19a8, 0x0e60, 0x263c, 0x3284, 0x0218, 0x1aa8, 0x0e64, 0x2640, 0x3288, 0x021c, 0x1aac, 0x0d64, 0x2540, 0x3188, 0x011c, 0x19ac, 0x0c64, 0x2440, 0x3088, 0x001c, 0x18ac, 0x0c68, 0x2444, 0x308c, 0x0020, 0x18b0, 0x0d68, 0x2544, 0x318c, 0x0120, 0x19b0, 0x0e68, 0x2644, 0x328c, 0x0220, 0x1ab0, 0x1248, 0x2a24, 0x366c, 0x0600, 0x1e90, 0x1348, 0x2b24, 0x376c, 0x0700, 0x1f90, 0x1448, 0x2c24, 0x386c, 0x0800, 0x2090, 0x144c, 0x2c28, 0x3870, 0x0804, 0x2094, 0x134c, 0x2b28, 0x3770, 0x0704, 0x1f94, 0x124c, 0x2a28, 0x3670, 0x0604, 0x1e94, 0x1250, 0x2a2c, 0x3674, 0x0608, 0x1e98, 0x1350, 0x2b2c, 0x3774, 0x0708, 0x1f98, 0x1450, 0x2c2c, 0x3874, 0x0808, 0x2098, 0x1454, 0x2c30, 0x3878, 0x080c, 0x209c, 0x1354, 0x2b30, 0x3778, 0x070c, 0x1f9c, 0x1254, 0x2a30, 0x3678, 0x060c, 0x1e9c, 0x1258, 0x2a34, 0x367c, 0x0610, 0x1ea0, 0x1358, 0x2b34, 0x377c, 0x0710, 0x1fa0, 0x1458, 0x2c34, 0x387c, 0x0810, 0x20a0, 0x145c, 0x2c38, 0x3880, 0x0814, 0x20a4, 0x135c, 0x2b38, 0x3780, 0x0714, 0x1fa4, 0x125c, 0x2a38, 0x3680, 0x0614, 0x1ea4, 0x1260, 0x2a3c, 0x3684, 0x0618, 0x1ea8, 0x1360, 0x2b3c, 0x3784, 0x0718, 0x1fa8, 0x1460, 0x2c3c, 0x3884, 0x0818, 0x20a8, 0x1464, 0x2c40, 0x3888, 0x081c, 0x20ac, 0x1364, 0x2b40, 0x3788, 0x071c, 0x1fac, 0x1264, 0x2a40, 0x3688, 0x061c, 0x1eac, 0x1268, 0x2a44, 0x368c, 0x0620, 0x1eb0, 0x1368, 0x2b44, 0x378c, 0x0720, 0x1fb0, 0x1468, 0x2c44, 0x388c, 0x0820, 0x20b0, 0x1848, 0x3024, 0x3c6c, 0x0c00, 0x2490, 0x1948, 0x3124, 0x3d6c, 0x0d00, 0x2590, 0x1a48, 0x3224, 0x3e6c, 0x0e00, 0x2690, 0x1a4c, 0x3228, 0x3e70, 0x0e04, 0x2694, 0x194c, 0x3128, 0x3d70, 0x0d04, 0x2594, 0x184c, 0x3028, 0x3c70, 0x0c04, 0x2494, 0x1850, 0x302c, 0x3c74, 0x0c08, 0x2498, 0x1950, 0x312c, 0x3d74, 0x0d08, 0x2598, 0x1a50, 0x322c, 0x3e74, 0x0e08, 0x2698, 0x1a54, 0x3230, 0x3e78, 0x0e0c, 0x269c, 0x1954, 0x3130, 0x3d78, 0x0d0c, 0x259c, 0x1854, 0x3030, 0x3c78, 0x0c0c, 0x249c, 0x1858, 0x3034, 0x3c7c, 0x0c10, 0x24a0, 0x1958, 0x3134, 0x3d7c, 0x0d10, 0x25a0, 0x1a58, 0x3234, 0x3e7c, 0x0e10, 0x26a0, 0x1a5c, 0x3238, 0x3e80, 0x0e14, 0x26a4, 0x195c, 0x3138, 0x3d80, 0x0d14, 0x25a4, 0x185c, 0x3038, 0x3c80, 0x0c14, 0x24a4, 0x1860, 0x303c, 0x3c84, 0x0c18, 0x24a8, 0x1960, 0x313c, 0x3d84, 0x0d18, 0x25a8, 0x1a60, 0x323c, 0x3e84, 0x0e18, 0x26a8, 0x1a64, 0x3240, 0x3e88, 0x0e1c, 0x26ac, 0x1964, 0x3140, 0x3d88, 0x0d1c, 0x25ac, 0x1864, 0x3040, 0x3c88, 0x0c1c, 0x24ac, 0x1868, 0x3044, 0x3c8c, 0x0c20, 0x24b0, 0x1968, 0x3144, 0x3d8c, 0x0d20, 0x25b0, 0x1a68, 0x3244, 0x3e8c, 0x0e20, 0x26b0, 0x1e48, 0x3624, 0x426c, 0x1200, 0x2a90, 0x1f48, 0x3724, 0x436c, 0x1300, 0x2b90, 0x2048, 0x3824, 0x446c, 0x1400, 0x2c90, 0x204c, 0x3828, 0x4470, 0x1404, 0x2c94, 0x1f4c, 0x3728, 0x4370, 0x1304, 0x2b94, 0x1e4c, 0x3628, 0x4270, 0x1204, 0x2a94, 0x1e50, 0x362c, 0x4274, 0x1208, 0x2a98, 0x1f50, 0x372c, 0x4374, 0x1308, 0x2b98, 0x2050, 0x382c, 0x4474, 0x1408, 0x2c98, 0x2054, 0x3830, 0x4478, 0x140c, 0x2c9c, 0x1f54, 0x3730, 0x4378, 0x130c, 0x2b9c, 0x1e54, 0x3630, 0x4278, 0x120c, 0x2a9c, 0x1e58, 0x3634, 0x427c, 0x1210, 0x2aa0, 0x1f58, 0x3734, 0x437c, 0x1310, 0x2ba0, 0x2058, 0x3834, 0x447c, 0x1410, 0x2ca0, 0x205c, 0x3838, 0x4480, 0x1414, 0x2ca4, 0x1f5c, 0x3738, 0x4380, 0x1314, 0x2ba4, 0x1e5c, 0x3638, 0x4280, 0x1214, 0x2aa4, 0x1e60, 0x363c, 0x4284, 0x1218, 0x2aa8, 0x1f60, 0x373c, 0x4384, 0x1318, 0x2ba8, 0x2060, 0x383c, 0x4484, 0x1418, 0x2ca8, 0x2064, 0x3840, 0x4488, 0x141c, 0x2cac, 0x1f64, 0x3740, 0x4388, 0x131c, 0x2bac, 0x1e64, 0x3640, 0x4288, 0x121c, 0x2aac, 0x1e68, 0x3644, 0x428c, 0x1220, 0x2ab0, 0x1f68, 0x3744, 0x438c, 0x1320, 0x2bb0, 0x2068, 0x3844, 0x448c, 0x1420, 0x2cb0, 0x2448, 0x3c24, 0x006c, 0x1800, 0x3090, 0x2548, 0x3d24, 0x016c, 0x1900, 0x3190, 0x2648, 0x3e24, 0x026c, 0x1a00, 0x3290, 0x264c, 0x3e28, 0x0270, 0x1a04, 0x3294, 0x254c, 0x3d28, 0x0170, 0x1904, 0x3194, 0x244c, 0x3c28, 0x0070, 0x1804, 0x3094, 0x2450, 0x3c2c, 0x0074, 0x1808, 0x3098, 0x2550, 0x3d2c, 0x0174, 0x1908, 0x3198, 0x2650, 0x3e2c, 0x0274, 0x1a08, 0x3298, 0x2654, 0x3e30, 0x0278, 0x1a0c, 0x329c, 0x2554, 0x3d30, 0x0178, 0x190c, 0x319c, 0x2454, 0x3c30, 0x0078, 0x180c, 0x309c, 0x2458, 0x3c34, 0x007c, 0x1810, 0x30a0, 0x2558, 0x3d34, 0x017c, 0x1910, 0x31a0, 0x2658, 0x3e34, 0x027c, 0x1a10, 0x32a0, 0x265c, 0x3e38, 0x0280, 0x1a14, 0x32a4, 0x255c, 0x3d38, 0x0180, 0x1914, 0x31a4, 0x245c, 0x3c38, 0x0080, 0x1814, 0x30a4, 0x2460, 0x3c3c, 0x0084, 0x1818, 0x30a8, 0x2560, 0x3d3c, 0x0184, 0x1918, 0x31a8, 0x2660, 0x3e3c, 0x0284, 0x1a18, 0x32a8, 0x2664, 0x3e40, 0x0288, 0x1a1c, 0x32ac, 0x2564, 0x3d40, 0x0188, 0x191c, 0x31ac, 0x2464, 0x3c40, 0x0088, 0x181c, 0x30ac, 0x2468, 0x3c44, 0x008c, 0x1820, 0x30b0, 0x2568, 0x3d44, 0x018c, 0x1920, 0x31b0, 0x2668, 0x3e44, 0x028c, 0x1a20, 0x32b0, 0x2a48, 0x4224, 0x066c, 0x1e00, 0x3690, 0x2b48, 0x4324, 0x076c, 0x1f00, 0x3790, 0x2c48, 0x4424, 0x086c, 0x2000, 0x3890, 0x2c4c, 0x4428, 0x0870, 0x2004, 0x3894, 0x2b4c, 0x4328, 0x0770, 0x1f04, 0x3794, 0x2a4c, 0x4228, 0x0670, 0x1e04, 0x3694, 0x2a50, 0x422c, 0x0674, 0x1e08, 0x3698, 0x2b50, 0x432c, 0x0774, 0x1f08, 0x3798, 0x2c50, 0x442c, 0x0874, 0x2008, 0x3898, 0x2c54, 0x4430, 0x0878, 0x200c, 0x389c, 0x2b54, 0x4330, 0x0778, 0x1f0c, 0x379c, 0x2a54, 0x4230, 0x0678, 0x1e0c, 0x369c, 0x2a58, 0x4234, 0x067c, 0x1e10, 0x36a0, 0x2b58, 0x4334, 0x077c, 0x1f10, 0x37a0, 0x2c58, 0x4434, 0x087c, 0x2010, 0x38a0, 0x2c5c, 0x4438, 0x0880, 0x2014, 0x38a4, 0x2b5c, 0x4338, 0x0780, 0x1f14, 0x37a4, 0x2a5c, 0x4238, 0x0680, 0x1e14, 0x36a4, 0x2a60, 0x423c, 0x0684, 0x1e18, 0x36a8, 0x2b60, 0x433c, 0x0784, 0x1f18, 0x37a8, 0x2c60, 0x443c, 0x0884, 0x2018, 0x38a8, 0x2c64, 0x4440, 0x0888, 0x201c, 0x38ac, 0x2b64, 0x4340, 0x0788, 0x1f1c, 0x37ac, 0x2a64, 0x4240, 0x0688, 0x1e1c, 0x36ac, 0x2a68, 0x4244, 0x068c, 0x1e20, 0x36b0, 0x2b68, 0x4344, 0x078c, 0x1f20, 0x37b0, 0x2c68, 0x4444, 0x088c, 0x2020, 0x38b0, 0x3048, 0x0024, 0x0c6c, 0x2400, 0x3c90, 0x3148, 0x0124, 0x0d6c, 0x2500, 0x3d90, 0x3248, 0x0224, 0x0e6c, 0x2600, 0x3e90, 0x324c, 0x0228, 0x0e70, 0x2604, 0x3e94, 0x314c, 0x0128, 0x0d70, 0x2504, 0x3d94, 0x304c, 0x0028, 0x0c70, 0x2404, 0x3c94, 0x3050, 0x002c, 0x0c74, 0x2408, 0x3c98, 0x3150, 0x012c, 0x0d74, 0x2508, 0x3d98, 0x3250, 0x022c, 0x0e74, 0x2608, 0x3e98, 0x3254, 0x0230, 0x0e78, 0x260c, 0x3e9c, 0x3154, 0x0130, 0x0d78, 0x250c, 0x3d9c, 0x3054, 0x0030, 0x0c78, 0x240c, 0x3c9c, 0x3058, 0x0034, 0x0c7c, 0x2410, 0x3ca0, 0x3158, 0x0134, 0x0d7c, 0x2510, 0x3da0, 0x3258, 0x0234, 0x0e7c, 0x2610, 0x3ea0, 0x325c, 0x0238, 0x0e80, 0x2614, 0x3ea4, 0x315c, 0x0138, 0x0d80, 0x2514, 0x3da4, 0x305c, 0x0038, 0x0c80, 0x2414, 0x3ca4, 0x3060, 0x003c, 0x0c84, 0x2418, 0x3ca8, 0x3160, 0x013c, 0x0d84, 0x2518, 0x3da8, 0x3260, 0x023c, 0x0e84, 0x2618, 0x3ea8, 0x3264, 0x0240, 0x0e88, 0x261c, 0x3eac, 0x3164, 0x0140, 0x0d88, 0x251c, 0x3dac, 0x3064, 0x0040, 0x0c88, 0x241c, 0x3cac, 0x3068, 0x0044, 0x0c8c, 0x2420, 0x3cb0, 0x3168, 0x0144, 0x0d8c, 0x2520, 0x3db0, 0x3268, 0x0244, 0x0e8c, 0x2620, 0x3eb0, 0x3648, 0x0624, 0x126c, 0x2a00, 0x4290, 0x3748, 0x0724, 0x136c, 0x2b00, 0x4390, 0x3848, 0x0824, 0x146c, 0x2c00, 0x4490, 0x384c, 0x0828, 0x1470, 0x2c04, 0x4494, 0x374c, 0x0728, 0x1370, 0x2b04, 0x4394, 0x364c, 0x0628, 0x1270, 0x2a04, 0x4294, 0x3650, 0x062c, 0x1274, 0x2a08, 0x4298, 0x3750, 0x072c, 0x1374, 0x2b08, 0x4398, 0x3850, 0x082c, 0x1474, 0x2c08, 0x4498, 0x3854, 0x0830, 0x1478, 0x2c0c, 0x449c, 0x3754, 0x0730, 0x1378, 0x2b0c, 0x439c, 0x3654, 0x0630, 0x1278, 0x2a0c, 0x429c, 0x3658, 0x0634, 0x127c, 0x2a10, 0x42a0, 0x3758, 0x0734, 0x137c, 0x2b10, 0x43a0, 0x3858, 0x0834, 0x147c, 0x2c10, 0x44a0, 0x385c, 0x0838, 0x1480, 0x2c14, 0x44a4, 0x375c, 0x0738, 0x1380, 0x2b14, 0x43a4, 0x365c, 0x0638, 0x1280, 0x2a14, 0x42a4, 0x3660, 0x063c, 0x1284, 0x2a18, 0x42a8, 0x3760, 0x073c, 0x1384, 0x2b18, 0x43a8, 0x3860, 0x083c, 0x1484, 0x2c18, 0x44a8, 0x3864, 0x0840, 0x1488, 0x2c1c, 0x44ac, 0x3764, 0x0740, 0x1388, 0x2b1c, 0x43ac, 0x3664, 0x0640, 0x1288, 0x2a1c, 0x42ac, 0x3668, 0x0644, 0x128c, 0x2a20, 0x42b0, 0x3768, 0x0744, 0x138c, 0x2b20, 0x43b0, 0x3868, 0x0844, 0x148c, 0x2c20, 0x44b0, 0x3c48, 0x0c24, 0x186c, 0x3000, 0x0090, 0x3d48, 0x0d24, 0x196c, 0x3100, 0x0190, 0x3e48, 0x0e24, 0x1a6c, 0x3200, 0x0290, 0x3e4c, 0x0e28, 0x1a70, 0x3204, 0x0294, 0x3d4c, 0x0d28, 0x1970, 0x3104, 0x0194, 0x3c4c, 0x0c28, 0x1870, 0x3004, 0x0094, 0x3c50, 0x0c2c, 0x1874, 0x3008, 0x0098, 0x3d50, 0x0d2c, 0x1974, 0x3108, 0x0198, 0x3e50, 0x0e2c, 0x1a74, 0x3208, 0x0298, 0x3e54, 0x0e30, 0x1a78, 0x320c, 0x029c, 0x3d54, 0x0d30, 0x1978, 0x310c, 0x019c, 0x3c54, 0x0c30, 0x1878, 0x300c, 0x009c, 0x3c58, 0x0c34, 0x187c, 0x3010, 0x00a0, 0x3d58, 0x0d34, 0x197c, 0x3110, 0x01a0, 0x3e58, 0x0e34, 0x1a7c, 0x3210, 0x02a0, 0x3e5c, 0x0e38, 0x1a80, 0x3214, 0x02a4, 0x3d5c, 0x0d38, 0x1980, 0x3114, 0x01a4, 0x3c5c, 0x0c38, 0x1880, 0x3014, 0x00a4, 0x3c60, 0x0c3c, 0x1884, 0x3018, 0x00a8, 0x3d60, 0x0d3c, 0x1984, 0x3118, 0x01a8, 0x3e60, 0x0e3c, 0x1a84, 0x3218, 0x02a8, 0x3e64, 0x0e40, 0x1a88, 0x321c, 0x02ac, 0x3d64, 0x0d40, 0x1988, 0x311c, 0x01ac, 0x3c64, 0x0c40, 0x1888, 0x301c, 0x00ac, 0x3c68, 0x0c44, 0x188c, 0x3020, 0x00b0, 0x3d68, 0x0d44, 0x198c, 0x3120, 0x01b0, 0x3e68, 0x0e44, 0x1a8c, 0x3220, 0x02b0, 0x4248, 0x1224, 0x1e6c, 0x3600, 0x0690, 0x4348, 0x1324, 0x1f6c, 0x3700, 0x0790, 0x4448, 0x1424, 0x206c, 0x3800, 0x0890, 0x444c, 0x1428, 0x2070, 0x3804, 0x0894, 0x434c, 0x1328, 0x1f70, 0x3704, 0x0794, 0x424c, 0x1228, 0x1e70, 0x3604, 0x0694, 0x4250, 0x122c, 0x1e74, 0x3608, 0x0698, 0x4350, 0x132c, 0x1f74, 0x3708, 0x0798, 0x4450, 0x142c, 0x2074, 0x3808, 0x0898, 0x4454, 0x1430, 0x2078, 0x380c, 0x089c, 0x4354, 0x1330, 0x1f78, 0x370c, 0x079c, 0x4254, 0x1230, 0x1e78, 0x360c, 0x069c, 0x4258, 0x1234, 0x1e7c, 0x3610, 0x06a0, 0x4358, 0x1334, 0x1f7c, 0x3710, 0x07a0, 0x4458, 0x1434, 0x207c, 0x3810, 0x08a0, 0x445c, 0x1438, 0x2080, 0x3814, 0x08a4, 0x435c, 0x1338, 0x1f80, 0x3714, 0x07a4, 0x425c, 0x1238, 0x1e80, 0x3614, 0x06a4, 0x4260, 0x123c, 0x1e84, 0x3618, 0x06a8, 0x4360, 0x133c, 0x1f84, 0x3718, 0x07a8, 0x4460, 0x143c, 0x2084, 0x3818, 0x08a8, 0x4464, 0x1440, 0x2088, 0x381c, 0x08ac, 0x4364, 0x1340, 0x1f88, 0x371c, 0x07ac, 0x4264, 0x1240, 0x1e88, 0x361c, 0x06ac, 0x4268, 0x1244, 0x1e8c, 0x3620, 0x06b0, 0x4368, 0x1344, 0x1f8c, 0x3720, 0x07b0, 0x4468, 0x1444, 0x208c, 0x3820, 0x08b0, 0x0048, 0x1824, 0x246c, 0x3c00, 0x0c90, 0x0148, 0x1924, 0x256c, 0x3d00, 0x0d90, 0x0248, 0x1a24, 0x266c, 0x3e00, 0x0e90, 0x024c, 0x1a28, 0x2670, 0x3e04, 0x0e94, 0x014c, 0x1928, 0x2570, 0x3d04, 0x0d94, 0x004c, 0x1828, 0x2470, 0x3c04, 0x0c94, 0x0050, 0x182c, 0x2474, 0x3c08, 0x0c98, 0x0150, 0x192c, 0x2574, 0x3d08, 0x0d98, 0x0250, 0x1a2c, 0x2674, 0x3e08, 0x0e98, 0x0254, 0x1a30, 0x2678, 0x3e0c, 0x0e9c, 0x0154, 0x1930, 0x2578, 0x3d0c, 0x0d9c, 0x0054, 0x1830, 0x2478, 0x3c0c, 0x0c9c, 0x0058, 0x1834, 0x247c, 0x3c10, 0x0ca0, 0x0158, 0x1934, 0x257c, 0x3d10, 0x0da0, 0x0258, 0x1a34, 0x267c, 0x3e10, 0x0ea0, 0x025c, 0x1a38, 0x2680, 0x3e14, 0x0ea4, 0x015c, 0x1938, 0x2580, 0x3d14, 0x0da4, 0x005c, 0x1838, 0x2480, 0x3c14, 0x0ca4, 0x0060, 0x183c, 0x2484, 0x3c18, 0x0ca8, 0x0160, 0x193c, 0x2584, 0x3d18, 0x0da8, 0x0260, 0x1a3c, 0x2684, 0x3e18, 0x0ea8, 0x0264, 0x1a40, 0x2688, 0x3e1c, 0x0eac, 0x0164, 0x1940, 0x2588, 0x3d1c, 0x0dac, 0x0064, 0x1840, 0x2488, 0x3c1c, 0x0cac, 0x0068, 0x1844, 0x248c, 0x3c20, 0x0cb0, 0x0168, 0x1944, 0x258c, 0x3d20, 0x0db0, 0x0268, 0x1a44, 0x268c, 0x3e20, 0x0eb0, 0x0648, 0x1e24, 0x2a6c, 0x4200, 0x1290, 0x0748, 0x1f24, 0x2b6c, 0x4300, 0x1390, 0x0848, 0x2024, 0x2c6c, 0x4400, 0x1490, 0x084c, 0x2028, 0x2c70, 0x4404, 0x1494, 0x074c, 0x1f28, 0x2b70, 0x4304, 0x1394, 0x064c, 0x1e28, 0x2a70, 0x4204, 0x1294, 0x0650, 0x1e2c, 0x2a74, 0x4208, 0x1298, 0x0750, 0x1f2c, 0x2b74, 0x4308, 0x1398, 0x0850, 0x202c, 0x2c74, 0x4408, 0x1498, 0x0854, 0x2030, 0x2c78, 0x440c, 0x149c, 0x0754, 0x1f30, 0x2b78, 0x430c, 0x139c, 0x0654, 0x1e30, 0x2a78, 0x420c, 0x129c, 0x0658, 0x1e34, 0x2a7c, 0x4210, 0x12a0, 0x0758, 0x1f34, 0x2b7c, 0x4310, 0x13a0, 0x0858, 0x2034, 0x2c7c, 0x4410, 0x14a0, 0x085c, 0x2038, 0x2c80, 0x4414, 0x14a4, 0x075c, 0x1f38, 0x2b80, 0x4314, 0x13a4, 0x065c, 0x1e38, 0x2a80, 0x4214, 0x12a4, 0x0660, 0x1e3c, 0x2a84, 0x4218, 0x12a8, 0x0760, 0x1f3c, 0x2b84, 0x4318, 0x13a8, 0x0860, 0x203c, 0x2c84, 0x4418, 0x14a8, 0x0864, 0x2040, 0x2c88, 0x441c, 0x14ac, 0x0764, 0x1f40, 0x2b88, 0x431c, 0x13ac, 0x0664, 0x1e40, 0x2a88, 0x421c, 0x12ac, 0x0668, 0x1e44, 0x2a8c, 0x4220, 0x12b0, 0x0768, 0x1f44, 0x2b8c, 0x4320, 0x13b0, 0x0868, 0x2044, 0x2c8c, 0x4420, 0x14b0, 0x0f48, 0x2724, 0x336c, 0x0300, 0x1b90, 0x1048, 0x2824, 0x346c, 0x0400, 0x1c90, 0x1148, 0x2924, 0x356c, 0x0500, 0x1d90, 0x114c, 0x2928, 0x3570, 0x0504, 0x1d94, 0x104c, 0x2828, 0x3470, 0x0404, 0x1c94, 0x0f4c, 0x2728, 0x3370, 0x0304, 0x1b94, 0x0f50, 0x272c, 0x3374, 0x0308, 0x1b98, 0x1050, 0x282c, 0x3474, 0x0408, 0x1c98, 0x1150, 0x292c, 0x3574, 0x0508, 0x1d98, 0x1154, 0x2930, 0x3578, 0x050c, 0x1d9c, 0x1054, 0x2830, 0x3478, 0x040c, 0x1c9c, 0x0f54, 0x2730, 0x3378, 0x030c, 0x1b9c, 0x0f58, 0x2734, 0x337c, 0x0310, 0x1ba0, 0x1058, 0x2834, 0x347c, 0x0410, 0x1ca0, 0x1158, 0x2934, 0x357c, 0x0510, 0x1da0, 0x115c, 0x2938, 0x3580, 0x0514, 0x1da4, 0x105c, 0x2838, 0x3480, 0x0414, 0x1ca4, 0x0f5c, 0x2738, 0x3380, 0x0314, 0x1ba4, 0x0f60, 0x273c, 0x3384, 0x0318, 0x1ba8, 0x1060, 0x283c, 0x3484, 0x0418, 0x1ca8, 0x1160, 0x293c, 0x3584, 0x0518, 0x1da8, 0x1164, 0x2940, 0x3588, 0x051c, 0x1dac, 0x1064, 0x2840, 0x3488, 0x041c, 0x1cac, 0x0f64, 0x2740, 0x3388, 0x031c, 0x1bac, 0x0f68, 0x2744, 0x338c, 0x0320, 0x1bb0, 0x1068, 0x2844, 0x348c, 0x0420, 0x1cb0, 0x1168, 0x2944, 0x358c, 0x0520, 0x1db0, 0x1548, 0x2d24, 0x396c, 0x0900, 0x2190, 0x1648, 0x2e24, 0x3a6c, 0x0a00, 0x2290, 0x1748, 0x2f24, 0x3b6c, 0x0b00, 0x2390, 0x174c, 0x2f28, 0x3b70, 0x0b04, 0x2394, 0x164c, 0x2e28, 0x3a70, 0x0a04, 0x2294, 0x154c, 0x2d28, 0x3970, 0x0904, 0x2194, 0x1550, 0x2d2c, 0x3974, 0x0908, 0x2198, 0x1650, 0x2e2c, 0x3a74, 0x0a08, 0x2298, 0x1750, 0x2f2c, 0x3b74, 0x0b08, 0x2398, 0x1754, 0x2f30, 0x3b78, 0x0b0c, 0x239c, 0x1654, 0x2e30, 0x3a78, 0x0a0c, 0x229c, 0x1554, 0x2d30, 0x3978, 0x090c, 0x219c, 0x1558, 0x2d34, 0x397c, 0x0910, 0x21a0, 0x1658, 0x2e34, 0x3a7c, 0x0a10, 0x22a0, 0x1758, 0x2f34, 0x3b7c, 0x0b10, 0x23a0, 0x175c, 0x2f38, 0x3b80, 0x0b14, 0x23a4, 0x165c, 0x2e38, 0x3a80, 0x0a14, 0x22a4, 0x155c, 0x2d38, 0x3980, 0x0914, 0x21a4, 0x1560, 0x2d3c, 0x3984, 0x0918, 0x21a8, 0x1660, 0x2e3c, 0x3a84, 0x0a18, 0x22a8, 0x1760, 0x2f3c, 0x3b84, 0x0b18, 0x23a8, 0x1764, 0x2f40, 0x3b88, 0x0b1c, 0x23ac, 0x1664, 0x2e40, 0x3a88, 0x0a1c, 0x22ac, 0x1564, 0x2d40, 0x3988, 0x091c, 0x21ac, 0x1568, 0x2d44, 0x398c, 0x0920, 0x21b0, 0x1668, 0x2e44, 0x3a8c, 0x0a20, 0x22b0, 0x1768, 0x2f44, 0x3b8c, 0x0b20, 0x23b0, 0x1b48, 0x3324, 0x3f6c, 0x0f00, 0x2790, 0x1c48, 0x3424, 0x406c, 0x1000, 0x2890, 0x1d48, 0x3524, 0x416c, 0x1100, 0x2990, 0x1d4c, 0x3528, 0x4170, 0x1104, 0x2994, 0x1c4c, 0x3428, 0x4070, 0x1004, 0x2894, 0x1b4c, 0x3328, 0x3f70, 0x0f04, 0x2794, 0x1b50, 0x332c, 0x3f74, 0x0f08, 0x2798, 0x1c50, 0x342c, 0x4074, 0x1008, 0x2898, 0x1d50, 0x352c, 0x4174, 0x1108, 0x2998, 0x1d54, 0x3530, 0x4178, 0x110c, 0x299c, 0x1c54, 0x3430, 0x4078, 0x100c, 0x289c, 0x1b54, 0x3330, 0x3f78, 0x0f0c, 0x279c, 0x1b58, 0x3334, 0x3f7c, 0x0f10, 0x27a0, 0x1c58, 0x3434, 0x407c, 0x1010, 0x28a0, 0x1d58, 0x3534, 0x417c, 0x1110, 0x29a0, 0x1d5c, 0x3538, 0x4180, 0x1114, 0x29a4, 0x1c5c, 0x3438, 0x4080, 0x1014, 0x28a4, 0x1b5c, 0x3338, 0x3f80, 0x0f14, 0x27a4, 0x1b60, 0x333c, 0x3f84, 0x0f18, 0x27a8, 0x1c60, 0x343c, 0x4084, 0x1018, 0x28a8, 0x1d60, 0x353c, 0x4184, 0x1118, 0x29a8, 0x1d64, 0x3540, 0x4188, 0x111c, 0x29ac, 0x1c64, 0x3440, 0x4088, 0x101c, 0x28ac, 0x1b64, 0x3340, 0x3f88, 0x0f1c, 0x27ac, 0x1b68, 0x3344, 0x3f8c, 0x0f20, 0x27b0, 0x1c68, 0x3444, 0x408c, 0x1020, 0x28b0, 0x1d68, 0x3544, 0x418c, 0x1120, 0x29b0, 0x2148, 0x3924, 0x456c, 0x1500, 0x2d90, 0x2248, 0x3a24, 0x466c, 0x1600, 0x2e90, 0x2348, 0x3b24, 0x476c, 0x1700, 0x2f90, 0x234c, 0x3b28, 0x4770, 0x1704, 0x2f94, 0x224c, 0x3a28, 0x4670, 0x1604, 0x2e94, 0x214c, 0x3928, 0x4570, 0x1504, 0x2d94, 0x2150, 0x392c, 0x4574, 0x1508, 0x2d98, 0x2250, 0x3a2c, 0x4674, 0x1608, 0x2e98, 0x2350, 0x3b2c, 0x4774, 0x1708, 0x2f98, 0x2354, 0x3b30, 0x4778, 0x170c, 0x2f9c, 0x2254, 0x3a30, 0x4678, 0x160c, 0x2e9c, 0x2154, 0x3930, 0x4578, 0x150c, 0x2d9c, 0x2158, 0x3934, 0x457c, 0x1510, 0x2da0, 0x2258, 0x3a34, 0x467c, 0x1610, 0x2ea0, 0x2358, 0x3b34, 0x477c, 0x1710, 0x2fa0, 0x235c, 0x3b38, 0x4780, 0x1714, 0x2fa4, 0x225c, 0x3a38, 0x4680, 0x1614, 0x2ea4, 0x215c, 0x3938, 0x4580, 0x1514, 0x2da4, 0x2160, 0x393c, 0x4584, 0x1518, 0x2da8, 0x2260, 0x3a3c, 0x4684, 0x1618, 0x2ea8, 0x2360, 0x3b3c, 0x4784, 0x1718, 0x2fa8, 0x2364, 0x3b40, 0x4788, 0x171c, 0x2fac, 0x2264, 0x3a40, 0x4688, 0x161c, 0x2eac, 0x2164, 0x3940, 0x4588, 0x151c, 0x2dac, 0x2168, 0x3944, 0x458c, 0x1520, 0x2db0, 0x2268, 0x3a44, 0x468c, 0x1620, 0x2eb0, 0x2368, 0x3b44, 0x478c, 0x1720, 0x2fb0, 0x2748, 0x3f24, 0x036c, 0x1b00, 0x3390, 0x2848, 0x4024, 0x046c, 0x1c00, 0x3490, 0x2948, 0x4124, 0x056c, 0x1d00, 0x3590, 0x294c, 0x4128, 0x0570, 0x1d04, 0x3594, 0x284c, 0x4028, 0x0470, 0x1c04, 0x3494, 0x274c, 0x3f28, 0x0370, 0x1b04, 0x3394, 0x2750, 0x3f2c, 0x0374, 0x1b08, 0x3398, 0x2850, 0x402c, 0x0474, 0x1c08, 0x3498, 0x2950, 0x412c, 0x0574, 0x1d08, 0x3598, 0x2954, 0x4130, 0x0578, 0x1d0c, 0x359c, 0x2854, 0x4030, 0x0478, 0x1c0c, 0x349c, 0x2754, 0x3f30, 0x0378, 0x1b0c, 0x339c, 0x2758, 0x3f34, 0x037c, 0x1b10, 0x33a0, 0x2858, 0x4034, 0x047c, 0x1c10, 0x34a0, 0x2958, 0x4134, 0x057c, 0x1d10, 0x35a0, 0x295c, 0x4138, 0x0580, 0x1d14, 0x35a4, 0x285c, 0x4038, 0x0480, 0x1c14, 0x34a4, 0x275c, 0x3f38, 0x0380, 0x1b14, 0x33a4, 0x2760, 0x3f3c, 0x0384, 0x1b18, 0x33a8, 0x2860, 0x403c, 0x0484, 0x1c18, 0x34a8, 0x2960, 0x413c, 0x0584, 0x1d18, 0x35a8, 0x2964, 0x4140, 0x0588, 0x1d1c, 0x35ac, 0x2864, 0x4040, 0x0488, 0x1c1c, 0x34ac, 0x2764, 0x3f40, 0x0388, 0x1b1c, 0x33ac, 0x2768, 0x3f44, 0x038c, 0x1b20, 0x33b0, 0x2868, 0x4044, 0x048c, 0x1c20, 0x34b0, 0x2968, 0x4144, 0x058c, 0x1d20, 0x35b0, 0x2d48, 0x4524, 0x096c, 0x2100, 0x3990, 0x2e48, 0x4624, 0x0a6c, 0x2200, 0x3a90, 0x2f48, 0x4724, 0x0b6c, 0x2300, 0x3b90, 0x2f4c, 0x4728, 0x0b70, 0x2304, 0x3b94, 0x2e4c, 0x4628, 0x0a70, 0x2204, 0x3a94, 0x2d4c, 0x4528, 0x0970, 0x2104, 0x3994, 0x2d50, 0x452c, 0x0974, 0x2108, 0x3998, 0x2e50, 0x462c, 0x0a74, 0x2208, 0x3a98, 0x2f50, 0x472c, 0x0b74, 0x2308, 0x3b98, 0x2f54, 0x4730, 0x0b78, 0x230c, 0x3b9c, 0x2e54, 0x4630, 0x0a78, 0x220c, 0x3a9c, 0x2d54, 0x4530, 0x0978, 0x210c, 0x399c, 0x2d58, 0x4534, 0x097c, 0x2110, 0x39a0, 0x2e58, 0x4634, 0x0a7c, 0x2210, 0x3aa0, 0x2f58, 0x4734, 0x0b7c, 0x2310, 0x3ba0, 0x2f5c, 0x4738, 0x0b80, 0x2314, 0x3ba4, 0x2e5c, 0x4638, 0x0a80, 0x2214, 0x3aa4, 0x2d5c, 0x4538, 0x0980, 0x2114, 0x39a4, 0x2d60, 0x453c, 0x0984, 0x2118, 0x39a8, 0x2e60, 0x463c, 0x0a84, 0x2218, 0x3aa8, 0x2f60, 0x473c, 0x0b84, 0x2318, 0x3ba8, 0x2f64, 0x4740, 0x0b88, 0x231c, 0x3bac, 0x2e64, 0x4640, 0x0a88, 0x221c, 0x3aac, 0x2d64, 0x4540, 0x0988, 0x211c, 0x39ac, 0x2d68, 0x4544, 0x098c, 0x2120, 0x39b0, 0x2e68, 0x4644, 0x0a8c, 0x2220, 0x3ab0, 0x2f68, 0x4744, 0x0b8c, 0x2320, 0x3bb0, 0x3348, 0x0324, 0x0f6c, 0x2700, 0x3f90, 0x3448, 0x0424, 0x106c, 0x2800, 0x4090, 0x3548, 0x0524, 0x116c, 0x2900, 0x4190, 0x354c, 0x0528, 0x1170, 0x2904, 0x4194, 0x344c, 0x0428, 0x1070, 0x2804, 0x4094, 0x334c, 0x0328, 0x0f70, 0x2704, 0x3f94, 0x3350, 0x032c, 0x0f74, 0x2708, 0x3f98, 0x3450, 0x042c, 0x1074, 0x2808, 0x4098, 0x3550, 0x052c, 0x1174, 0x2908, 0x4198, 0x3554, 0x0530, 0x1178, 0x290c, 0x419c, 0x3454, 0x0430, 0x1078, 0x280c, 0x409c, 0x3354, 0x0330, 0x0f78, 0x270c, 0x3f9c, 0x3358, 0x0334, 0x0f7c, 0x2710, 0x3fa0, 0x3458, 0x0434, 0x107c, 0x2810, 0x40a0, 0x3558, 0x0534, 0x117c, 0x2910, 0x41a0, 0x355c, 0x0538, 0x1180, 0x2914, 0x41a4, 0x345c, 0x0438, 0x1080, 0x2814, 0x40a4, 0x335c, 0x0338, 0x0f80, 0x2714, 0x3fa4, 0x3360, 0x033c, 0x0f84, 0x2718, 0x3fa8, 0x3460, 0x043c, 0x1084, 0x2818, 0x40a8, 0x3560, 0x053c, 0x1184, 0x2918, 0x41a8, 0x3564, 0x0540, 0x1188, 0x291c, 0x41ac, 0x3464, 0x0440, 0x1088, 0x281c, 0x40ac, 0x3364, 0x0340, 0x0f88, 0x271c, 0x3fac, 0x3368, 0x0344, 0x0f8c, 0x2720, 0x3fb0, 0x3468, 0x0444, 0x108c, 0x2820, 0x40b0, 0x3568, 0x0544, 0x118c, 0x2920, 0x41b0, 0x3948, 0x0924, 0x156c, 0x2d00, 0x4590, 0x3a48, 0x0a24, 0x166c, 0x2e00, 0x4690, 0x3b48, 0x0b24, 0x176c, 0x2f00, 0x4790, 0x3b4c, 0x0b28, 0x1770, 0x2f04, 0x4794, 0x3a4c, 0x0a28, 0x1670, 0x2e04, 0x4694, 0x394c, 0x0928, 0x1570, 0x2d04, 0x4594, 0x3950, 0x092c, 0x1574, 0x2d08, 0x4598, 0x3a50, 0x0a2c, 0x1674, 0x2e08, 0x4698, 0x3b50, 0x0b2c, 0x1774, 0x2f08, 0x4798, 0x3b54, 0x0b30, 0x1778, 0x2f0c, 0x479c, 0x3a54, 0x0a30, 0x1678, 0x2e0c, 0x469c, 0x3954, 0x0930, 0x1578, 0x2d0c, 0x459c, 0x3958, 0x0934, 0x157c, 0x2d10, 0x45a0, 0x3a58, 0x0a34, 0x167c, 0x2e10, 0x46a0, 0x3b58, 0x0b34, 0x177c, 0x2f10, 0x47a0, 0x3b5c, 0x0b38, 0x1780, 0x2f14, 0x47a4, 0x3a5c, 0x0a38, 0x1680, 0x2e14, 0x46a4, 0x395c, 0x0938, 0x1580, 0x2d14, 0x45a4, 0x3960, 0x093c, 0x1584, 0x2d18, 0x45a8, 0x3a60, 0x0a3c, 0x1684, 0x2e18, 0x46a8, 0x3b60, 0x0b3c, 0x1784, 0x2f18, 0x47a8, 0x3b64, 0x0b40, 0x1788, 0x2f1c, 0x47ac, 0x3a64, 0x0a40, 0x1688, 0x2e1c, 0x46ac, 0x3964, 0x0940, 0x1588, 0x2d1c, 0x45ac, 0x3968, 0x0944, 0x158c, 0x2d20, 0x45b0, 0x3a68, 0x0a44, 0x168c, 0x2e20, 0x46b0, 0x3b68, 0x0b44, 0x178c, 0x2f20, 0x47b0, 0x3f48, 0x0f24, 0x1b6c, 0x3300, 0x0390, 0x4048, 0x1024, 0x1c6c, 0x3400, 0x0490, 0x4148, 0x1124, 0x1d6c, 0x3500, 0x0590, 0x414c, 0x1128, 0x1d70, 0x3504, 0x0594, 0x404c, 0x1028, 0x1c70, 0x3404, 0x0494, 0x3f4c, 0x0f28, 0x1b70, 0x3304, 0x0394, 0x3f50, 0x0f2c, 0x1b74, 0x3308, 0x0398, 0x4050, 0x102c, 0x1c74, 0x3408, 0x0498, 0x4150, 0x112c, 0x1d74, 0x3508, 0x0598, 0x4154, 0x1130, 0x1d78, 0x350c, 0x059c, 0x4054, 0x1030, 0x1c78, 0x340c, 0x049c, 0x3f54, 0x0f30, 0x1b78, 0x330c, 0x039c, 0x3f58, 0x0f34, 0x1b7c, 0x3310, 0x03a0, 0x4058, 0x1034, 0x1c7c, 0x3410, 0x04a0, 0x4158, 0x1134, 0x1d7c, 0x3510, 0x05a0, 0x415c, 0x1138, 0x1d80, 0x3514, 0x05a4, 0x405c, 0x1038, 0x1c80, 0x3414, 0x04a4, 0x3f5c, 0x0f38, 0x1b80, 0x3314, 0x03a4, 0x3f60, 0x0f3c, 0x1b84, 0x3318, 0x03a8, 0x4060, 0x103c, 0x1c84, 0x3418, 0x04a8, 0x4160, 0x113c, 0x1d84, 0x3518, 0x05a8, 0x4164, 0x1140, 0x1d88, 0x351c, 0x05ac, 0x4064, 0x1040, 0x1c88, 0x341c, 0x04ac, 0x3f64, 0x0f40, 0x1b88, 0x331c, 0x03ac, 0x3f68, 0x0f44, 0x1b8c, 0x3320, 0x03b0, 0x4068, 0x1044, 0x1c8c, 0x3420, 0x04b0, 0x4168, 0x1144, 0x1d8c, 0x3520, 0x05b0, 0x4548, 0x1524, 0x216c, 0x3900, 0x0990, 0x4648, 0x1624, 0x226c, 0x3a00, 0x0a90, 0x4748, 0x1724, 0x236c, 0x3b00, 0x0b90, 0x474c, 0x1728, 0x2370, 0x3b04, 0x0b94, 0x464c, 0x1628, 0x2270, 0x3a04, 0x0a94, 0x454c, 0x1528, 0x2170, 0x3904, 0x0994, 0x4550, 0x152c, 0x2174, 0x3908, 0x0998, 0x4650, 0x162c, 0x2274, 0x3a08, 0x0a98, 0x4750, 0x172c, 0x2374, 0x3b08, 0x0b98, 0x4754, 0x1730, 0x2378, 0x3b0c, 0x0b9c, 0x4654, 0x1630, 0x2278, 0x3a0c, 0x0a9c, 0x4554, 0x1530, 0x2178, 0x390c, 0x099c, 0x4558, 0x1534, 0x217c, 0x3910, 0x09a0, 0x4658, 0x1634, 0x227c, 0x3a10, 0x0aa0, 0x4758, 0x1734, 0x237c, 0x3b10, 0x0ba0, 0x475c, 0x1738, 0x2380, 0x3b14, 0x0ba4, 0x465c, 0x1638, 0x2280, 0x3a14, 0x0aa4, 0x455c, 0x1538, 0x2180, 0x3914, 0x09a4, 0x4560, 0x153c, 0x2184, 0x3918, 0x09a8, 0x4660, 0x163c, 0x2284, 0x3a18, 0x0aa8, 0x4760, 0x173c, 0x2384, 0x3b18, 0x0ba8, 0x4764, 0x1740, 0x2388, 0x3b1c, 0x0bac, 0x4664, 0x1640, 0x2288, 0x3a1c, 0x0aac, 0x4564, 0x1540, 0x2188, 0x391c, 0x09ac, 0x4568, 0x1544, 0x218c, 0x3920, 0x09b0, 0x4668, 0x1644, 0x228c, 0x3a20, 0x0ab0, 0x4768, 0x1744, 0x238c, 0x3b20, 0x0bb0, 0x0348, 0x1b24, 0x276c, 0x3f00, 0x0f90, 0x0448, 0x1c24, 0x286c, 0x4000, 0x1090, 0x0548, 0x1d24, 0x296c, 0x4100, 0x1190, 0x054c, 0x1d28, 0x2970, 0x4104, 0x1194, 0x044c, 0x1c28, 0x2870, 0x4004, 0x1094, 0x034c, 0x1b28, 0x2770, 0x3f04, 0x0f94, 0x0350, 0x1b2c, 0x2774, 0x3f08, 0x0f98, 0x0450, 0x1c2c, 0x2874, 0x4008, 0x1098, 0x0550, 0x1d2c, 0x2974, 0x4108, 0x1198, 0x0554, 0x1d30, 0x2978, 0x410c, 0x119c, 0x0454, 0x1c30, 0x2878, 0x400c, 0x109c, 0x0354, 0x1b30, 0x2778, 0x3f0c, 0x0f9c, 0x0358, 0x1b34, 0x277c, 0x3f10, 0x0fa0, 0x0458, 0x1c34, 0x287c, 0x4010, 0x10a0, 0x0558, 0x1d34, 0x297c, 0x4110, 0x11a0, 0x055c, 0x1d38, 0x2980, 0x4114, 0x11a4, 0x045c, 0x1c38, 0x2880, 0x4014, 0x10a4, 0x035c, 0x1b38, 0x2780, 0x3f14, 0x0fa4, 0x0360, 0x1b3c, 0x2784, 0x3f18, 0x0fa8, 0x0460, 0x1c3c, 0x2884, 0x4018, 0x10a8, 0x0560, 0x1d3c, 0x2984, 0x4118, 0x11a8, 0x0564, 0x1d40, 0x2988, 0x411c, 0x11ac, 0x0464, 0x1c40, 0x2888, 0x401c, 0x10ac, 0x0364, 0x1b40, 0x2788, 0x3f1c, 0x0fac, 0x0368, 0x1b44, 0x278c, 0x3f20, 0x0fb0, 0x0468, 0x1c44, 0x288c, 0x4020, 0x10b0, 0x0568, 0x1d44, 0x298c, 0x4120, 0x11b0, 0x0948, 0x2124, 0x2d6c, 0x4500, 0x1590, 0x0a48, 0x2224, 0x2e6c, 0x4600, 0x1690, 0x0b48, 0x2324, 0x2f6c, 0x4700, 0x1790, 0x0b4c, 0x2328, 0x2f70, 0x4704, 0x1794, 0x0a4c, 0x2228, 0x2e70, 0x4604, 0x1694, 0x094c, 0x2128, 0x2d70, 0x4504, 0x1594, 0x0950, 0x212c, 0x2d74, 0x4508, 0x1598, 0x0a50, 0x222c, 0x2e74, 0x4608, 0x1698, 0x0b50, 0x232c, 0x2f74, 0x4708, 0x1798, 0x0b54, 0x2330, 0x2f78, 0x470c, 0x179c, 0x0a54, 0x2230, 0x2e78, 0x460c, 0x169c, 0x0954, 0x2130, 0x2d78, 0x450c, 0x159c, 0x0958, 0x2134, 0x2d7c, 0x4510, 0x15a0, 0x0a58, 0x2234, 0x2e7c, 0x4610, 0x16a0, 0x0b58, 0x2334, 0x2f7c, 0x4710, 0x17a0, 0x0b5c, 0x2338, 0x2f80, 0x4714, 0x17a4, 0x0a5c, 0x2238, 0x2e80, 0x4614, 0x16a4, 0x095c, 0x2138, 0x2d80, 0x4514, 0x15a4, 0x0960, 0x213c, 0x2d84, 0x4518, 0x15a8, 0x0a60, 0x223c, 0x2e84, 0x4618, 0x16a8, 0x0b60, 0x233c, 0x2f84, 0x4718, 0x17a8, 0x0b64, 0x2340, 0x2f88, 0x471c, 0x17ac, 0x0a64, 0x2240, 0x2e88, 0x461c, 0x16ac, 0x0964, 0x2140, 0x2d88, 0x451c, 0x15ac, 0x0968, 0x2144, 0x2d8c, 0x4520, 0x15b0, 0x0a68, 0x2244, 0x2e8c, 0x4620, 0x16b0, 0x0b68, 0x2344, 0x2f8c, 0x4720, 0x17b0, }; /* DV25/50 DCT coefficient weights and inverse weights */ /* created by dvtables.py */ static const int dv_weight_bits = 18; static const int dv_weight_88[64] = { 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536, 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935, 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916, 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433, 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704, 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568, 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627, 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258, }; static const int dv_weight_248[64] = { 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754, 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536, 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568, 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965, 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627, 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965, 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364, 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651, }; static const int dv_iweight_bits = 14; static const int dv_iweight_88[64] = { 32768, 16710, 16710, 17735, 17015, 17735, 18197, 18079, 18079, 18197, 18725, 18559, 19196, 18559, 18725, 19284, 19108, 19692, 19692, 19108, 19284, 21400, 19645, 20262, 20214, 20262, 19645, 21400, 22733, 21845, 20867, 20815, 20815, 20867, 21845, 22733, 23173, 23173, 21400, 21400, 21400, 23173, 23173, 24600, 23764, 22017, 22017, 23764, 24600, 25267, 24457, 22672, 24457, 25267, 25971, 25191, 25191, 25971, 26715, 27962, 26715, 29642, 29642, 31536, }; static const int dv_iweight_248[64] = { 32768, 17735, 16710, 18079, 18725, 21400, 17735, 19196, 19108, 21845, 16384, 17735, 18725, 21400, 16710, 18079, 20262, 23173, 18197, 19692, 18725, 20262, 20815, 23764, 17735, 19196, 19108, 21845, 20262, 23173, 18197, 19692, 21400, 24457, 19284, 20867, 21400, 23173, 22017, 25191, 18725, 20262, 20815, 23764, 21400, 24457, 19284, 20867, 24457, 27962, 22733, 24600, 25971, 29642, 21400, 23173, 22017, 25191, 24457, 27962, 22733, 24600, 25971, 29642, }; 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}, }; static const int dv_audio_frequency[3] = { 48000, 44100, 32000, }; static const DVprofile dv_profiles[] = { { .dsf = 0, .frame_size = 120000, /* IEC 61834, SMPTE-314M - 525/60 (NTSC) */ .difseg_size = 10, .n_difchan = 1, .frame_rate = 30000, .ltc_divisor = 30, .frame_rate_base = 1001, .height = 480, .width = 720, .sar = {{10, 11}, {40, 33}}, .video_place = dv_place_411, .pix_fmt = PIX_FMT_YUV411P, .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, .frame_size = 144000, /* IEC 61834 - 625/50 (PAL) */ .difseg_size = 12, .n_difchan = 1, .frame_rate = 25, .frame_rate_base = 1, .ltc_divisor = 25, .height = 576, .width = 720, .sar = {{59, 54}, {118, 81}}, .video_place = dv_place_420, .pix_fmt = PIX_FMT_YUV420P, .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, .frame_size = 144000, /* SMPTE-314M - 625/50 (PAL) */ .difseg_size = 12, .n_difchan = 1, .frame_rate = 25, .frame_rate_base = 1, .ltc_divisor = 25, .height = 576, .width = 720, .sar = {{59, 54}, {118, 81}}, .video_place = dv_place_411P, .pix_fmt = PIX_FMT_YUV411P, .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, .frame_size = 240000, /* SMPTE-314M - 525/60 (NTSC) 50 Mbps */ .difseg_size = 10, /* also known as "DVCPRO50" */ .n_difchan = 2, .frame_rate = 30000, .ltc_divisor = 30, .frame_rate_base = 1001, .height = 480, .width = 720, .sar = {{10, 11}, {40, 33}}, .video_place = dv_place_422_525, .pix_fmt = PIX_FMT_YUV422P, .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, .frame_size = 288000, /* SMPTE-314M - 625/50 (PAL) 50 Mbps */ .difseg_size = 12, /* also known as "DVCPRO50" */ .n_difchan = 2, .frame_rate = 25, .frame_rate_base = 1, .ltc_divisor = 25, .height = 576, .width = 720, .sar = {{59, 54}, {118, 81}}, .video_place = dv_place_422_625, .pix_fmt = PIX_FMT_YUV422P, .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, } }; enum dv_section_type { dv_sect_header = 0x1f, dv_sect_subcode = 0x3f, dv_sect_vaux = 0x56, dv_sect_audio = 0x76, dv_sect_video = 0x96, }; enum dv_pack_type { dv_header525 = 0x3f, /* see dv_write_pack for important details on */ dv_header625 = 0xbf, /* these two packs */ dv_timecode = 0x13, dv_audio_source = 0x50, dv_audio_control = 0x51, dv_audio_recdate = 0x52, dv_audio_rectime = 0x53, dv_video_source = 0x60, dv_video_control = 0x61, dv_video_recdate = 0x62, dv_video_rectime = 0x63, dv_unknown_pack = 0xff, }; /* 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 */ /* largest possible DV frame, in bytes (PAL 50Mbps) */ #define DV_MAX_FRAME_SIZE 288000 static inline const DVprofile* dv_frame_profile(uint8_t* frame) { if ((frame[3] & 0x80) == 0) { /* DSF flag */ /* it's an NTSC format */ if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) { /* 4:2:2 sampling */ return &dv_profiles[3]; /* NTSC 50Mbps */ } else { /* 4:1:1 sampling */ return &dv_profiles[0]; /* NTSC 25Mbps */ } } else { /* it's a PAL format */ if ((frame[80*5 + 48 + 3] & 0x4) && (frame[80*5 + 48] == dv_video_source)) { /* 4:2:2 sampling */ return &dv_profiles[4]; /* PAL 50Mbps */ } else if ((frame[5] & 0x07) == 0) { /* APT flag */ return &dv_profiles[1]; /* PAL 25Mbps 4:2:0 */ } else return &dv_profiles[2]; /* PAL 25Mbps 4:1:1 */ } } #if 0 /* not used in xine DV audio */ static inline const DVprofile* dv_codec_profile(AVCodecContext* codec) { int i; if (codec->width != 720) return NULL; for (i=0; i<sizeof(dv_profiles)/sizeof(DVprofile); i++) if (codec->height == dv_profiles[i].height && codec->pix_fmt == dv_profiles[i].pix_fmt) return &dv_profiles[i]; return NULL; } #endif static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num, uint8_t seq_num, uint8_t dif_num, uint8_t* buf) { buf[0] = (uint8_t)t; /* Section type */ buf[1] = (seq_num<<4) | /* DIF seq number 0-9 for 525/60; 0-11 for 625/50 */ (chan_num << 3) | /* FSC: for 50Mb/s 0 - first channel; 1 - second */ 7; /* reserved -- always 1 */ buf[2] = dif_num; /* DIF block number Video: 0-134, Audio: 0-8 */ return 3; } static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf) { if (syb_num == 0 || syb_num == 6) { buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */ (0<<4) | /* AP3 (Subcode application ID) */ 0x0f; /* reserved -- always 1 */ } else if (syb_num == 11) { buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */ 0x7f; /* reserved -- always 1 */ } else { buf[0] = (fr<<7) | /* FR ID 1 - first half of each channel; 0 - second */ (0<<4) | /* APT (Track application ID) */ 0x0f; /* reserved -- always 1 */ } buf[1] = 0xf0 | /* reserved -- always 1 */ (syb_num & 0x0f); /* SSYB number 0 - 11 */ buf[2] = 0xff; /* reserved -- always 1 */ return 3; } #endif /* FFMPEG_DVDATA_H */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/Makefile.am��������������������������������������������������������������0000644�0001750�0001750�00000006410�14647725152�015424� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) EXTRA_DIST = fooaudio.c latm.c if ENABLE_MUSEPACK musepack_module = xineplug_decode_mpc.la endif if ENABLE_DTS dts_module = xineplug_decode_dts.la endif if ENABLE_MAD mad_module = xineplug_decode_mad.la endif if ENABLE_A52DEC a52_module = xineplug_decode_a52.la endif if ENABLE_FAAD faad_module = xineplug_decode_faad.la endif if ENABLE_GSM610 gsm610_module = xineplug_decode_gsm610.la endif if ENABLE_LPCM lpcm_module = xineplug_decode_lpcm.la endif if ENABLE_DVAUDIO dvaudio_module = xineplug_decode_dvaudio.la endif $(top_builddir)/contrib/a52dec/liba52.la: $(MAKE) -C $(top_builddir)/contrib/a52dec $(top_builddir)/contrib/libfaad/libfaad.la: $(MAKE) -C $(top_builddir)/contrib/libfaad $(top_builddir)/contrib/libmad/libmad.la: $(MAKE) -C $(top_builddir)/contrib/libmad $(top_builddir)/contrib/libmpcdec/libmpcdec.la: $(MAKE) -C $(top_builddir)/contrib/libmpcdec $(top_builddir)/contrib/libdca/libdca.la: $(MAKE) -C $(top_builddir)/contrib/libdca $(top_builddir)/contrib/gsm610/libgsm610.la: $(MAKE) -C $(top_builddir)/contrib/gsm610 xineplug_LTLIBRARIES = \ xineplug_decode_to_spdif.la \ $(dvaudio_module) \ $(lpcm_module) \ $(gsm610_module) \ $(musepack_module) \ $(dts_module) \ $(mad_module) \ $(a52_module) \ $(faad_module) xineplug_decode_gsm610_la_SOURCES = gsm610.c xineplug_decode_gsm610_la_LIBADD = $(XINE_LIB) $(top_builddir)/contrib/gsm610/libgsm610.la xineplug_decode_gsm610_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/contrib/gsm610 xineplug_decode_lpcm_la_SOURCES = xine_lpcm_decoder.c xineplug_decode_lpcm_la_LIBADD = $(XINE_LIB) xineplug_decode_mpc_la_SOURCES = xine_musepack_decoder.c xineplug_decode_mpc_la_DEPENDENCIES = $(MPCDEC_DEPS) xineplug_decode_mpc_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(MPCDEC_LIBS) xineplug_decode_mpc_la_CFLAGS = $(AM_CFLAGS) $(MPCDEC_CFLAGS) xineplug_decode_dts_la_SOURCES = xine_dts_decoder.c xineplug_decode_dts_la_DEPENDENCIES = $(LIBDTS_DEPS) xineplug_decode_dts_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(LIBDTS_LIBS) xineplug_decode_dts_la_CFLAGS = $(AM_CFLAGS) $(LIBDTS_CFLAGS) xineplug_decode_mad_la_SOURCES = xine_mad_decoder.c xineplug_decode_mad_la_DEPENDENCIES = $(LIBMAD_DEPS) xineplug_decode_mad_la_LIBADD = $(XINE_LIB) $(LIBMAD_LIBS) xineplug_decode_mad_la_CFLAGS = $(AM_CFLAGS) $(LIBMAD_CFLAGS) xineplug_decode_a52_la_SOURCES = xine_a52_decoder.c xine_a52_parser.h xineplug_decode_a52_la_DEPENDENCIES = $(A52DEC_DEPS) xineplug_decode_a52_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(A52DEC_LIBS) -lm xineplug_decode_a52_la_CFLAGS = $(AM_CFLAGS) $(A52DEC_CFLAGS) xineplug_decode_a52_la_CPPFLAGS = $(AM_CPPFLAGS) $(A52DEC_MATH) xineplug_decode_to_spdif_la_SOURCES = xine_a52_spdif.c xineplug_decode_to_spdif_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) -lm xineplug_decode_faad_la_SOURCES = xine_faad_decoder.c xineplug_decode_faad_la_DEPENDENCIES = $(FAAD_DEPS) xineplug_decode_faad_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(FAAD_LIBS) -lm xineplug_decode_faad_la_CFLAGS = $(FAAD_CFLAGS) xineplug_decode_dvaudio_la_SOURCES = ff_dvaudio_decoder.c ff_dvdata.h xineplug_decode_dvaudio_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_decode_dvaudio_la_CPPFLAGS = $(AM_CPPFLAGS) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/xine_faad_decoder.c������������������������������������������������������0000644�0001750�0001750�00000123223�14647725152�017141� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include "latm.c" #define LOG_MODULE "libfaad" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #ifdef HAVE_NEAACDEC_H #include <neaacdec.h> #else #include "common.h" #include "structs.h" #include "syntax.h" #endif #define FAAD_MIN_STREAMSIZE 768 /* 6144 bits/channel */ typedef struct { audio_decoder_class_t decoder_class; xine_t *xine; int gain_db; /* fixed point scalers (v * gain?_i) >> 32 */ int32_t gain_i, gain3_i, gain6_i, gain9_i, gain12_i; /* floating point scalers */ float gain_f, gain3_f, gain6_f, gain9_f, gain12_f; /* look here for fixed or float mode */ int caps; } faad_class_t; typedef struct { audio_decoder_t audio_decoder; faad_class_t *class; xine_stream_t *stream; /* faad2 stuff */ NeAACDecHandle faac_dec; NeAACDecConfigurationPtr faac_cfg; NeAACDecFrameInfo faac_finfo; int faac_failed; unsigned char *buf; int size; int rec_audio_src_size; int max_audio_src_size; #define FAAD_PTS_LD 3 #define FAAD_PTS_SIZE (1 << FAAD_PTS_LD) #define FAAD_PTS_MASK (FAAD_PTS_SIZE - 1) int used_last; int pts_last; struct { int64_t pts; int bytes; } pts_ring[FAAD_PTS_SIZE]; unsigned char *dec_config; int dec_config_size; uint32_t rate; int bits_per_sample; unsigned char num_channels; int sbr; /* 1 (OK), 0 (closed), < 0 (# failed attempts) */ int output_open; int in_channels, out_channels, out_used; int in_mode, out_mode, out_flags; bebf_latm_t latm; bebf_latm_parser_status_t latm_mode; uint32_t adts_fake; uint8_t adts_lasthead[2]; struct { int64_t base_pts; uint32_t seconds; uint32_t samples; enum { _ADIF_UNKNOWN = 0, _ADIF_YES, _ADIF_NO } mode; } adif; } faad_decoder_t; static void faad_pts_reset (faad_decoder_t *this) { this->pts_ring[0].pts = 0; this->pts_ring[0].bytes = 0x7fffffff; this->pts_last = 0; /* leave this->used_last alone. we dont reinit libfaad in faad_reset () yet. */ } static void faad_pts_add (faad_decoder_t *this, int64_t pts, int bytes) { this->pts_last = (this->pts_last + 1) & FAAD_PTS_MASK; this->pts_ring[this->pts_last].pts = pts; this->pts_ring[this->pts_last].bytes = bytes; } static int64_t faad_pts_get (faad_decoder_t *this, int bytes_left) { int64_t pts; int i; bytes_left += this->used_last; i = this->pts_last; while (1) { bytes_left -= this->pts_ring[i].bytes; if (bytes_left <= 0) break; i = (i - 1) & FAAD_PTS_MASK; } pts = this->pts_ring[i].pts; this->pts_ring[i].pts = 0; return pts; } static int faad_map_channels (faad_decoder_t *this) { static const char *input_names[4] = { "mono", "stereo", "5.1", "7.1" }; static const uint8_t input_modes[16] = { 255, 0, 1, 255, 255, 255, 2, 255, 3, 255, 255, 255, 255, 255, 255, 255 }; /* the audio out modes we use. */ static const char *out_names[6] = { "mono", "stereo", "4.0", "4.1", "5.0", "5.1" }; static const int out_modes[6] = { AO_CAP_MODE_MONO, AO_CAP_MODE_STEREO, AO_CAP_MODE_4CHANNEL, AO_CAP_MODE_4_1CHANNEL, AO_CAP_MODE_5CHANNEL, AO_CAP_MODE_5_1CHANNEL }; /* how many channels are sent to audio out. */ static const uint8_t out_chan[6] = { 1, 2, 4, 6, 6, 6 }; /* how many of them contain audible data. */ static const uint8_t out_used[6] = { 1, 2, 4, 5, 5, 6 }; /* what out modes we prefer in what order for a given input. */ static const uint8_t wishlist[4 * 6] = { 0, 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 0, 5, 4, 3, 2, 1, 0, 5, 4, 3, 2, 1, 0 }; /**/ int out_caps = 0; int in_mode = input_modes[this->num_channels & 15]; const uint8_t *p; int i; if (!this->stream->audio_out) return 0; if (in_mode == 255) return 0; this->in_mode = in_mode; out_caps = this->stream->audio_out->get_capabilities (this->stream->audio_out); p = wishlist + in_mode * 6; for (i = 0; i < 6; i++) { int out_flags = out_modes[p[i]]; if (out_caps & out_flags) { this->out_flags = out_flags; this->out_mode = p[i]; break; } } if (i == 6) return 0; this->in_channels = this->num_channels; this->out_channels = out_chan[this->out_mode]; this->out_used = out_used[this->out_mode]; xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": channel layout: %s -> %s\n", input_names[this->in_mode], out_names[this->out_mode]); return 1; } static void faad_reset (audio_decoder_t *this_gen) { faad_decoder_t *this = xine_container_of(this_gen, faad_decoder_t, audio_decoder); this->size = 0; faad_pts_reset (this); #if 0 bebf_latm_close (&this->latm); bebf_latm_open (&this->latm); this->latm_mode = BEBF_LATM_NEED_MORE_DATA; memset (&this->adts_lasthead, 0, 2); this->adts_fake = 0; #endif } static void faad_meta_info_set ( faad_decoder_t *this ) { switch (this->num_channels) { case 1: if (this->faac_finfo.sbr == SBR_UPSAMPLED) _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "HE-AAC 1.0 (libfaad)"); else _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "AAC 1.0 (libfaad)"); break; case 2: /* check if this is downmixed 5.1 */ if (!this->faac_cfg || !this->faac_cfg->downMatrix) { if (this->faac_finfo.sbr == SBR_UPSAMPLED) _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "HE-AAC 2.0 (libfaad)"); else _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "AAC 2.0 (libfaad)"); break; } /* fall through */ case 6: if (this->faac_finfo.sbr == SBR_UPSAMPLED) _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "HE-AAC 5.1 (libfaad)"); else _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "AAC 5.1 (libfaad)"); break; } } static void faad_close_output (faad_decoder_t *this) { if (this->output_open > 0) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; } static int faad_open_output( faad_decoder_t *this ) { #if 0 int ao_cap_mode; #endif this->rec_audio_src_size = this->num_channels * FAAD_MIN_STREAMSIZE; /* maybe not needed again here */ this->faac_cfg = NeAACDecGetCurrentConfiguration (this->faac_dec); if (this->faac_cfg) { this->faac_cfg->outputFormat = (this->class->caps & FIXED_POINT_CAP) ? FAAD_FMT_FIXED : FAAD_FMT_FLOAT; NeAACDecSetConfiguration (this->faac_dec, this->faac_cfg); } #if 0 switch( this->num_channels ) { case 1: ao_cap_mode=AO_CAP_MODE_MONO; break; case 6: if(this->stream->audio_out->get_capabilities(this->stream->audio_out) & AO_CAP_MODE_5_1CHANNEL) { ao_cap_mode = AO_CAP_MODE_5_1CHANNEL; break; } else { this->faac_cfg = NeAACDecGetCurrentConfiguration(this->faac_dec); this->faac_cfg->downMatrix = 1; NeAACDecSetConfiguration(this->faac_dec, this->faac_cfg); this->num_channels = 2; } case 2: ao_cap_mode=AO_CAP_MODE_STEREO; break; default: return 0; } #endif if (!faad_map_channels (this)) return 0; { int ret = this->stream->audio_out->open ( this->stream->audio_out, this->stream, this->bits_per_sample, this->rate, this->out_flags); this->output_open = ret ? 1 : (this->output_open - 1); return ret; } } static int faad_reopen_dec (faad_decoder_t *this) { if (this->faac_dec) NeAACDecClose (this->faac_dec); this->faac_dec = NeAACDecOpen (); if (!this->faac_dec) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libfaad: libfaad NeAACDecOpen() failed.\n")); this->faac_failed++; return -1; } this->class->caps = NeAACDecGetCapabilities (); this->faac_cfg = NeAACDecGetCurrentConfiguration (this->faac_dec); if (this->faac_cfg) { /* We want float or fixed point data. */ this->faac_cfg->outputFormat = (this->class->caps & FIXED_POINT_CAP) ? FAAD_FMT_FIXED : FAAD_FMT_FLOAT; NeAACDecSetConfiguration (this->faac_dec, this->faac_cfg); } return 0; } static int faad_apply_conf (faad_decoder_t *this, uint8_t *conf, int len) { unsigned long rate = 0; uint8_t num_channels = 0; int res; if (faad_reopen_dec (this) < 0) return -1; res = NeAACDecInit2 (this->faac_dec, conf, len, &rate, &num_channels); /* HACK: At least internal libfaad does not understand * AOT_PS / n Hz / Mono / n*2 Hz / AOT_AAC_LC. * But it does understand (and find that PS in) * AOT_SBR / n Hz / Mono / n*2 Hz / AOT_AAC_LC. */ if (res < 0) do { static const uint8_t double_samplerates[16] = {~0, ~0, ~0, ~0, ~0, ~0, 3, 4, 5, 6, 7, 8, ~0, ~0, ~0, ~0}; uint32_t bits; uint8_t save = conf[0]; if (len < 3) break; memcpy (&bits, conf, 4); bits = bebf_ADJ32 (bits); if ((bits & 0xf8787c00) != (uint32_t)((AOT_PS << (32 - 5)) | (1 << (32 - 5 - 4 - 4)) | (AOT_AAC_LC << (32 - 5 - 4 - 4 - 4 - 5)))) break; if (double_samplerates[(bits >> (32 - 5 - 4)) & 15] != ((bits >> (32 - 5 - 4 - 4 - 4)) & 15)) break; conf[0] = (conf[0] & 7) | (AOT_SBR << 3); xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": using AOT_PS -> AOT_SBR hack\n"); res = NeAACDecInit2 (this->faac_dec, conf, len, &rate, &num_channels); conf[0] = save; } while (0); /* more HACK s here */ /* are we fine? */ if (res >= 0) { if ((rate != this->rate) || (num_channels != this->num_channels)) { this->rate = rate; this->num_channels = num_channels; faad_close_output (this); } if (this->output_open <= 0) faad_open_output (this); faad_meta_info_set (this); this->used_last = 0; this->adif.mode = _ADIF_NO; return res; } /* no, its not working */ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libfaad: libfaad NeAACDecInit2 failed.\n")); return res; } static int faad_apply_frame (faad_decoder_t *this, uint8_t *frame, int len) { unsigned long rate = 0; uint8_t num_channels = 0; int res; if (faad_reopen_dec (this) < 0) return -1; res = NeAACDecInit (this->faac_dec, frame, len, &rate, &num_channels); /* are we fine? */ if (res >= 0) { if ((rate != this->rate) || (num_channels != this->num_channels)) { this->rate = rate; this->num_channels = num_channels; faad_close_output (this); if (this->adif.mode == _ADIF_YES) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": got new AAC config from ADIF\n"); } } if (this->output_open <= 0) faad_open_output (this); faad_meta_info_set (this); this->used_last = 0; return res; } /* no, its not working */ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libfaad: libfaad NeAACDecInit failed.\n")); return res; } static int faad_open_dec (faad_decoder_t *this) { int res; if (this->dec_config) res = faad_apply_conf (this, this->dec_config, this->dec_config_size); else res = faad_apply_frame (this, this->buf, this->size); if (res < 0) { if (this->faac_dec) { NeAACDecClose (this->faac_dec); this->faac_dec = NULL; } _x_stream_info_set (this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return 1; } lprintf ("NeAACDecInit() returned rate=%u channels=%u (res=%d)\n", this->rate, this->num_channels, res); return 0; } static void faad_decode_audio ( faad_decoder_t *this, int end_frame ) { int used, decoded, framecount; const void *sample_buffer; uint8_t *inbuf; #define ADTS_FAKE_CFG inbuf = this->buf; framecount = 0; while (1) { int64_t pts = 0; if (this->latm_mode == BEBF_LATM_IS_ADTS) { if (framecount == 0) { /* quick and dirty ADTS parser. */ /* It is faster than libfaad's own, and it is safe with 0xff padding bytes. */ uint8_t *q = inbuf; int headsize, s; memcpy (q + this->size, "\xf0\xff\xf0\x00", 4); /* overread stop */ while (1) { if (q[0] == 0xff) { if ((q[1] & 0xf6) == 0xf0) break; } q++; } this->size -= q - inbuf; if (this->size < 0) { /* no sync */ this->size = 0; break; } inbuf = q; headsize = (q[1] & 1) ? 7 : 9; /* optional 2 bytes crc */ if (this->size < headsize) /* incomplete head */ break; s = (((uint32_t)q[3] << 11) | ((uint32_t)q[4] << 3) | (q[5] >> 5)) & 0x1fff; if (s < headsize) { /* invalid head */ inbuf++; this->size--; continue; } if (this->size < s) /* incomplete frame */ break; framecount = (q[6] & 3) + 1; /* seen this head before? */ if (((q[2] ^ this->adts_lasthead[0]) & 0xfd) | ((q[3] ^ this->adts_lasthead[1]) & 0xc0)) { /* Safety: require this new head to appear at least got7 I mean twice ;-) */ if (this->size < s + 4) break; if ((q[s] != 0xff) || ((q[s + 1] & 0xf6) != 0xf0) || ((q[2] ^ q[s + 2]) & 0xfd) || ((q[3] ^ q[s + 3]) & 0xc0)) { framecount = 0; inbuf++; this->size--; continue; } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": got new AAC config from ADTS\n"); memcpy (this->adts_lasthead, q + 2, 2); /* TJ. A note on that nasty SBR hack below. * SBR (Spectral Band Replication) is a more efficient algorithm for encoding high pitched sound. * It is common to do the base as plain LC (Low Complexity) at half samplerate (eg 22050), then * add treble as SBR at full rate (eg 44100). The actual SBR data hides inside "filler" blocks, * so old decoders can still play in AM radio quality. * SBR need not show up in every frame, and ADTS heads have no room for announcing SBR initially. * So output may open at half rate. If SBR appears later, it cannot play properly, and will be dropped. * This hack now always prepares for SBR when it might be useful. If there is really no SBR used, * we will just upsample. */ this->adts_fake = 0; #ifdef ADTS_FAKE_CFG do { static const uint8_t double_samplerates[16] = {0, 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, 8, 0, 0, 0, 0}; uint32_t sr1, sr2, chancfg; if ((q[2] >> 6) != AOT_AAC_LC - 1) break; sr1 = (q[2] >> 2) & 15; sr2 = double_samplerates[sr1]; if (!sr2) break; chancfg = ((q[2] << 2) | (q[3] >> 6)) & 7; this->adts_fake = AOT_SBR << (32 - 5); this->adts_fake |= sr1 << (32 - 5 - 4); this->adts_fake |= chancfg << (32 - 5 - 4 - 4); this->adts_fake |= sr2 << (32 - 5 - 4 - 4 - 4); this->adts_fake |= AOT_AAC_LC << (32 - 5 - 4 - 4 - 4 - 5); /* + 3 more 0 bits: frameLength, dependsOnCoreCoder, extensionFlag1 = 25 bits = 4 bytes */ this->adts_fake = bebf_ADJ32 (this->adts_fake); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": trying fake AAC config to enable SBR\n"); if (faad_apply_conf (this, (uint8_t *)&this->adts_fake, 4) >= 0) break; this->adts_fake = 0; } while (0); #endif if (!this->adts_fake) { if (faad_apply_frame (this, inbuf, s) < 0) { framecount = 0; inbuf++; this->size--; continue; } } } if (this->adts_fake) { inbuf += headsize; this->size -= headsize; } else { framecount = 0; } } if (framecount) framecount--; sample_buffer = NeAACDecDecode (this->faac_dec, &this->faac_finfo, inbuf, this->size); if (!sample_buffer) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libfaad: %s\n", NeAACDecGetErrorMessage (this->faac_finfo.error)); used = 1; } else { used = this->faac_finfo.bytesconsumed; } } else if (this->latm_mode == BEBF_LATM_IS_LATM) { int l = this->size; int latm_state = bebf_latm_parse (&this->latm, (const uint8_t *)inbuf, &l); if (l <= 0) break; used = l; if (latm_state & BEBF_LATM_GOT_CONF) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": got new AAC config from LATM\n"); if (faad_apply_conf (this, this->latm.config, this->latm.conflen) < 0) { inbuf++; this->size--; continue; } } sample_buffer = NULL; if (latm_state & BEBF_LATM_GOT_FRAME) { sample_buffer = NeAACDecDecode (this->faac_dec, &this->faac_finfo, this->latm.frame, this->latm.framelen); if (!sample_buffer) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libfaad: %s\n", NeAACDecGetErrorMessage (this->faac_finfo.error)); } } } else { if (!this->faac_dec) { if (faad_open_dec (this)) { this->size = 0; return; } } if (this->latm_mode == BEBF_LATM_IS_RAW) { if (!end_frame || this->size < 10) break; } else { if (this->size < this->rec_audio_src_size) break; } sample_buffer = NeAACDecDecode (this->faac_dec, &this->faac_finfo, inbuf, this->size); if (!sample_buffer) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libfaad: %s\n", NeAACDecGetErrorMessage (this->faac_finfo.error)); used = 1; } else { used = this->faac_finfo.bytesconsumed; } } if (sample_buffer) { /* need a different output? */ if ((this->num_channels != this->faac_finfo.channels) || (this->rate != this->faac_finfo.samplerate)) { this->num_channels = this->faac_finfo.channels; this->rate = this->faac_finfo.samplerate; lprintf("NeAACDecDecode() returned rate=%u channels=%u used=%d\n", this->rate, this->num_channels, used); faad_close_output (this); } if (this->output_open <= 0) { if (this->output_open <= -5) { /* too many fails for same settings */ this->size = 0; break; } if (!faad_open_output (this)) { this->size = 0; break; } faad_meta_info_set( this ); } /* faad doesn't tell us about sbr until after the first frame */ if (this->sbr != this->faac_finfo.sbr) { this->sbr = this->faac_finfo.sbr; faad_meta_info_set( this ); } pts = faad_pts_get (this, this->size - (inbuf - (const uint8_t *)this->buf)); decoded = this->faac_finfo.samples / this->num_channels; if (decoded <= 0) { /* mp4a involves frequency transform, which needs some delay on both the * encoding and decoding sides. encode delay varies with encoding algorithm. * decode delay is more or less standardized, like this: * libfaad usually decodes first frame after init as preroll, without output. * the simpliest approach to deal with this is to let each side compensate * for its own known delay. thus, remove this 1 frame from timeline here. * ffmpeg -i foo.mp4 -af volume=0.707 -acodec pcm_s16le -vcodec copy foo.flv * also does that. */ this->used_last = used; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": empty outbuf, pts %" PRId64 ".\n", pts); } else if (this->used_last > 0) { this->used_last = used; } lprintf("decoded %d/%d output %ld\n", used, this->size, this->faac_finfo.samples ); /* Performing necessary channel reordering because aac uses a different * layout than alsa: * * aac 5.1 channel layout: c l r ls rs lfe * alsa 5.1 channel layout: l r ls rs c lfe * * Reordering is only necessary for 5.0 and above. Currently only 5.0 * and 5.1 is being taken care of, the rest will stay in the wrong order * for now. */ #define sat16(v) (((v + 0x8000) & ~0xffff) ? ((v) >> 31) ^ 0x7fff : (v)) /* Maximum frame size is 1024 samples * 8 channels * 2 bytes = 16k. * Thus we probably dont need to while this. */ while (decoded) { audio_buffer_t *audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); int done = this->out_channels; done = audio_buffer->mem_size / done / 2; if (done > decoded) done = decoded; audio_buffer->num_frames = done; audio_buffer->vpts = pts; pts = 0; if ((this->in_channels <= 2) && (this->out_channels > this->in_channels)) memset (audio_buffer->mem, 0, this->out_channels * done * 2); if (this->class->caps & FIXED_POINT_CAP) { /* hint compiler to use 32 to 64 bit multiply instruction where available. */ /* also, that shift optimizes to almost nothing at 32bit system. */ #define GET1(i,j) v = ((int64_t)g1 * (int64_t)p[i]) >> 32; q[j] = sat16 (v) #define GET2(i,j) v = ((int64_t)g1 * (int64_t)(p[i] + p[i + 1])) >> 32; q[j] = sat16 (v) #define GET1M(i,j) v = (m + (int64_t)g1 * (int64_t)p[i]) >> 32; q[j] = sat16 (v) #define GET2M(i,j,l) v = ((int64_t)g1 * (int64_t)p[i] + (int64_t)g2 * (int64_t)(m + p[j])) >> 32; q[l] = sat16 (v) const int32_t *p = sample_buffer; int16_t *q = (int16_t *)audio_buffer->mem; int n = done; if (this->in_channels < 6) { if (this->in_channels < 2) { if (this->out_used <= 1) { /* M -> M */ int32_t g1 = this->class->gain_i; do { int32_t v; GET1 (0, 0); p++; q++; } while (--n); } else { /* M -> M M ... */ int32_t g1 = this->class->gain_i; do { int32_t v; GET1 (0, 0); q[1] = q[0]; p++; q += this->out_channels; } while (--n); } } else { if (this->out_used < 2) { /* L R -> M */ int32_t g1 = this->class->gain6_i; do { int32_t v; GET2 (0, 0); p += 2; q++; } while (--n); } else { /* L R -> L R ... */ int32_t g1 = this->class->gain_i; do { int32_t v; GET1 (0, 0); GET1 (1, 1); p += 2; q += this->out_channels; } while (--n); } } } else { /* if (this->in_channels < 8) */ { switch (this->out_mode) { case 0: /* C L R SL SR B -> M */ do { int32_t v; v = ((int64_t)this->class->gain9_i * (int64_t)(p[1] + p[2]) + (int64_t)this->class->gain6_i * (int64_t)(p[0] + p[5]) + (int64_t)this->class->gain12_i * (int64_t)(p[3] + p[4])) >> 32; *q++ = sat16 (v); p += this->in_channels; } while (--n); break; case 1: { /* C L R SL SR B -> L R */ int32_t g1 = this->class->gain3_i; int32_t g2 = this->class->gain6_i; do { int32_t m = p[0] + p[5]; int32_t v; GET2M (1, 3, 0); GET2M (2, 4, 1); p += this->in_channels; q += 2; } while (--n); } break; case 2: { /* C L R SL SR B -> L R SL SR */ int32_t g1 = this->class->gain3_i; do { int64_t m = (int64_t)this->class->gain6_i * (int64_t)(p[0] + p[5]); int32_t v; GET1M (1, 0); GET1M (2, 1); GET1 (3, 2); GET1 (4, 3); p += this->in_channels; q += 4; } while (--n); } break; case 3: { /* C L R SL SR B -> L R SL SR 0 B */ int32_t g1 = this->class->gain3_i; do { int64_t m = (int64_t)this->class->gain6_i * (int64_t)p[0]; int32_t v; GET1M (1, 0); GET1M (2, 1); GET1 (3, 2); GET1 (4, 3); q[4] = 0; GET1 (5, 5); p += this->in_channels; q += 6; } while (--n); } break; case 4: { /* C L R SL SR B -> L R SL SR C 0 */ int32_t g1 = this->class->gain3_i; do { int64_t m = (int64_t)this->class->gain6_i * (int64_t)p[5]; int32_t v; GET1M (1, 0); GET1M (2, 1); GET1 (3, 2); GET1 (4, 3); GET1 (0, 4); q[5] = 0; p += this->in_channels; q += 6; } while (--n); } break; case 5: { /* C L R SL SR B -> L R SL SR C B */ int32_t g1 = this->class->gain_i; do { int32_t v; GET1 (1, 0); GET1 (2, 1); GET1 (3, 2); GET1 (4, 3); GET1 (0, 4); GET1 (5, 5); p += this->in_channels; q += 6; } while (--n); } break; } } } sample_buffer = p; #undef GET1 #undef GET2 #undef GET1M #undef GET2M } else { #define GET1(i,j) v = g1 * p[i]; q[j] = sat16 (v) #define GET2(i,j) v = g1 * (p[i] + p[i + 1]); q[j] = sat16 (v) #define GET1M(i,j) v = m + g1 * p[i]; q[j] = sat16 (v) #define GET2M(i,j,l) v = g1 * p[i] + g2 * (m + p[j]); q[l] = sat16 (v) const float *p = (const float *)sample_buffer; int16_t *q = (int16_t *)audio_buffer->mem; int n = done; if (this->in_channels < 6) { if (this->in_channels < 2) { if (this->out_used <= 1) { /* M -> M */ float g1 = this->class->gain_f; do { int32_t v; GET1 (0, 0); p++; q++; } while (--n); } else { /* M -> M M ... */ float g1 = this->class->gain_f; do { int32_t v; GET1 (0, 0); q[1] = q[0]; p++; q += this->out_channels; } while (--n); } } else { if (this->out_used < 2) { /* L R -> M */ float g1 = this->class->gain6_f; do { int32_t v; GET2 (0, 0); p += 2; q++; } while (--n); } else { /* L R -> L R ... */ float g1 = this->class->gain_f; do { int32_t v; GET1 (0, 0); GET1 (1, 1); p += 2; q += this->out_channels; } while (--n); } } } else { /* if (this->in_channels < 8) */ { switch (this->out_mode) { case 0: /* C L R SL SR B -> M */ do { int32_t v; v = this->class->gain9_f * (p[1] + p[2]) + this->class->gain6_f * (p[0] + p[5]) + this->class->gain12_f * (p[3] + p[4]); *q++ = sat16 (v); p += this->in_channels; } while (--n); break; case 1: { /* C L R SL SR B -> L R */ float g1 = this->class->gain3_f; float g2 = this->class->gain6_f; do { float m = p[0] + p[5]; int32_t v; GET2M (1, 3, 0); GET2M (2, 4, 1); p += this->in_channels; q += 2; } while (--n); } break; case 2: { /* C L R SL SR B -> L R SL SR */ float g1 = this->class->gain3_f; do { float m = this->class->gain6_f * (p[0] + p[5]); int32_t v; GET1M (1, 0); GET1M (2, 1); GET1 (3, 2); GET1 (4, 3); p += this->in_channels; q += 4; } while (--n); } break; case 3: { /* C L R SL SR B -> L R SL SR 0 B */ float g1 = this->class->gain3_f; do { float m = this->class->gain6_f * p[0]; int32_t v; GET1M (1, 0); GET1M (2, 1); GET1 (3, 2); GET1 (4, 3); q[4] = 0; GET1 (5, 5); p += this->in_channels; q += 6; } while (--n); } break; case 4: { /* C L R SL SR B -> L R SL SR C 0 */ float g1 = this->class->gain3_f; do { float m = this->class->gain6_f * p[5]; int32_t v; GET1M (1, 0); GET1M (2, 1); GET1 (3, 2); GET1 (4, 3); GET1 (0, 4); q[5] = 0; p += this->in_channels; q += 6; } while (--n); } break; case 5: { /* C L R SL SR B -> L R SL SR C B */ float g1 = this->class->gain_f; do { int32_t v; GET1 (1, 0); GET1 (2, 1); GET1 (3, 2); GET1 (4, 3); GET1 (0, 4); GET1 (5, 5); p += this->in_channels; q += 6; } while (--n); } break; } } } sample_buffer = p; #undef GET1 #undef GET2 #undef GET1M #undef GET2M } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1, LOG_MODULE ": outbuf samples %d, pts %" PRId64 ".\n", (int)audio_buffer->num_frames, audio_buffer->vpts); if (this->adif.mode == _ADIF_YES) { this->adif.samples += audio_buffer->num_frames; if (this->adif.samples >= this->rate) { this->adif.samples -= this->rate; this->adif.seconds += 1; } } this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); decoded -= done; } } if ((used >= this->size) || (this->latm_mode == BEBF_LATM_IS_RAW)) { this->size = 0; break; } this->size -= used; inbuf += used; } if( this->size ) memmove( this->buf, inbuf, this->size); } static void faad_get_conf (faad_decoder_t *this, const uint8_t *d, int len) { uint8_t *b; if (!d || (len <= 0)) return; b = this->dec_config; if (b) { if ((this->dec_config_size == len) && !memcmp (b, d, len)) return; if (this->dec_config_size < len) { free (b); this->dec_config = b = NULL; this->dec_config_size = 0; } } if (!b) { b = malloc (len + 8); if (!b) return; } memcpy (b, d, len); memset (b + len, 0, 8); this->dec_config = b; this->dec_config_size = len; this->latm_mode = BEBF_LATM_IS_RAW; xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": got new AAC config from demuxer\n"); if (!this->faac_dec) return; NeAACDecClose (this->faac_dec); this->faac_dec = NULL; } static void faad_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { faad_decoder_t *this = xine_container_of(this_gen, faad_decoder_t, audio_decoder); if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; /* store config information from ESDS mp4/qt atom */ if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG)) faad_get_conf (this, buf->decoder_info_ptr[2], buf->decoder_info[2]); /* get audio parameters from file header (may be overwritten by libfaad returned parameters) */ if (buf->decoder_flags & BUF_FLAG_STDHEADER) { xine_waveformatex *wavex = (xine_waveformatex *)buf->content; this->rate = buf->decoder_info[1]; this->bits_per_sample = buf->decoder_info[2]; this->num_channels = buf->decoder_info[3]; if (wavex) { int len = (int)buf->size - sizeof (xine_waveformatex); if (len > 0) { if (len > wavex->cbSize) len = wavex->cbSize; faad_get_conf (this, buf->content + sizeof (xine_waveformatex), len); } } } else { lprintf ("decoding %d data bytes...\n", buf->size); if ((int)buf->size <= 0) return; if (this->adif.mode == _ADIF_UNKNOWN) { if (buf->size >= 4) { this->adif.mode = !memcmp (buf->content, "ADIF", 4) ? _ADIF_YES : _ADIF_NO; } } if (this->adif.mode == _ADIF_YES) { if (buf->pts != this->adif.base_pts) { this->adif.base_pts = buf->pts; this->adif.seconds = 0; this->adif.samples = 0; } buf->pts = this->adif.base_pts + (int64_t)90000 * this->adif.seconds + 90000u * this->adif.samples / this->rate; } /* Queue pts values as frames may overlap buffer boundaries (mpeg-ts). */ faad_pts_add (this, buf->pts, buf->size); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG + 1, LOG_MODULE ": inbuf bytes %d, pts %" PRId64 ".\n", buf->size, buf->pts); if (this->size + buf->size + 8 > this->max_audio_src_size) { size_t s = this->size + 2 * buf->size + 8; uint8_t *b = realloc (this->buf, s); if (!b) return; this->buf = b; this->max_audio_src_size = s; } memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; /* Instream header formats like ADTS do support midstream config changes, * eg a 5.1 movie following the stereo news show. * Unfortunately, libfaad by itself does detect such changes, but it does * not follow them, and bails out instead. It probably does so to prevent * glitches from damaged streams. * However, this leaves us to decide what a real change is, and call * NeAACDecInit () again on the new data. Even worse, switching from 5.1 * to stereo needs a full reopen. * Making that sane requires parsing anyway, so maybe it is a good idea * to always parse here. */ #ifdef PARSE_ONLY_LATM if ((buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_AUDIO_AAC_LATM) #endif { if (this->latm_mode == BEBF_LATM_NEED_MORE_DATA) { this->latm_mode = bebf_latm_test ((const uint8_t *)this->buf, this->size); if (this->latm_mode == BEBF_LATM_NEED_MORE_DATA) return; if (this->latm_mode == BEBF_LATM_IS_ADTS) { #ifndef PARSE_ONLY_LATM if ((buf->type & (BUF_MAJOR_MASK | BUF_DECODER_MASK)) == BUF_AUDIO_AAC_LATM) #endif xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": stream says LATM but is ADTS\n"); } } } faad_decode_audio(this, buf->decoder_flags & BUF_FLAG_FRAME_END ); } } static void faad_discontinuity (audio_decoder_t *this_gen) { faad_decoder_t *this = xine_container_of(this_gen, faad_decoder_t, audio_decoder); this->adif.base_pts = -1; faad_pts_reset (this); } static void faad_dispose (audio_decoder_t *this_gen) { faad_decoder_t *this = xine_container_of(this_gen, faad_decoder_t, audio_decoder); bebf_latm_close (&this->latm); faad_close_output (this); _x_freep(&this->buf); this->size = 0; this->max_audio_src_size = 0; _x_freep(&this->dec_config); this->dec_config_size = 0; if( this->faac_dec ) NeAACDecClose(this->faac_dec); this->faac_dec = NULL; this->faac_failed = 0; free (this); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { faad_decoder_t *this ; this = calloc(1, sizeof (faad_decoder_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ this->output_open = 0; this->faac_dec = NULL; this->faac_failed = 0; this->buf = NULL; this->size = 0; this->max_audio_src_size = 0; this->dec_config = NULL; this->dec_config_size = 0; this->rate = 0; this->used_last = 0; this->adif.base_pts = 0; this->adif.seconds = 0; this->adif.samples = 0; this->adif.mode = _ADIF_UNKNOWN; #endif this->rate = 1; /* no / 0 please */ faad_pts_reset (this); this->class = (faad_class_t *)class_gen; this->stream = stream; this->audio_decoder.decode_data = faad_decode_data; this->audio_decoder.reset = faad_reset; this->audio_decoder.discontinuity = faad_discontinuity; this->audio_decoder.dispose = faad_dispose; this->bits_per_sample = 16; bebf_latm_open (&this->latm); this->latm_mode = BEBF_LATM_NEED_MORE_DATA; return &this->audio_decoder; } /* * TJ. The default -3dB preamp gain fixes stereo streams done with * buggy encoders. FFmpeg used to have that bug, and even today (2016) * certain people keep publishing such material. * Multichannel downmixing stategy: * - Downmix center and bass to front left and right. As that doubles * their power (1 -> 2 playback channels), compensate by -3dB. * - Downmix sides to front by -3dB as well, this time to reduce fx. * - Downmix to mono by simply averaging (l + r -6dB). * To be absolutely clip safe, we would need to attenuate the result * by up to 1 / (1 + 3 * sqrt (1 / 2)), or -9.9 dB. However, this is * hardly ever needed. So lets use another -3dB instead, and - hey - * we got gain control now ;-) * Note these are binary (6 * ld (v)) not decimal (20 * log (v)) dB, * as they are easier to handle in fixed point mode. */ static void gain_update (faad_class_t *this) { /* XXX: assuming 30bit fixed point math. If it is not, simply adjust your gain ;-) */ static const int32_t gi[6] = { 262144, 294247, 330281, 370728, 416128, 467088 }; static const float gf[6] = { 32768.0000, 36780.8364, 41285.0930, 46340.9500, 52015.9577, 58385.9384 }; int exp = this->gain_db, mant = exp; /* main channel scaling */ if (exp < 0) { exp = (5 - exp) / 6; mant = (6000 + mant) % 6; this->gain_i = gi[mant] >> exp; this->gain_f = gf[mant] / (float)(1 << exp); } else { exp = exp / 6; mant = mant % 6; this->gain_i = gi[mant] << exp; this->gain_f = gf[mant] * (float)(1 << exp); } /* sub channel downmixing */ this->gain3_i = (this->gain_i * 11) >> 4; this->gain9_i = this->gain3_i >> 1; this->gain6_i = this->gain_i >> 1; this->gain12_i = this->gain_i >> 2; this->gain3_f = this->gain_f * 0.7071; this->gain6_f = this->gain_f * 0.5; this->gain9_f = this->gain_f * 0.3535; this->gain12_f = this->gain_f * 0.25; } static void gain_cb (void *user_data, xine_cfg_entry_t *entry) { faad_class_t *class = (faad_class_t *)user_data; class->gain_db = entry->num_value; gain_update (class); } /* class management */ static void faad_class_dispose (audio_decoder_class_t *this_gen) { faad_class_t *this = (faad_class_t *)this_gen; this->xine->config->unregister_callbacks (this->xine->config, "audio.processing.faad_gain_dB", NULL, this, sizeof (*this)); free (this); } static void *faad_init_plugin (xine_t *xine, const void *data, const char *id) { faad_class_t *this; (void)data; this = calloc(1, sizeof (faad_class_t)); if (!this) return NULL; this->decoder_class.open_plugin = open_plugin; this->decoder_class.identifier = id; this->decoder_class.description = N_("Freeware Advanced Audio Decoder"); this->decoder_class.dispose = faad_class_dispose; this->xine = xine; /* we made 2 classes just to allow different xine decoder priorities. * xine config now supports multiple change callbacks per key. */ this->gain_db = xine->config->register_num (xine->config, "audio.processing.faad_gain_dB", -3, _("FAAD audio gain (dB)"), _("Some AAC tracks are encoded too loud and thus play distorted.\n" "This cannot be fixed by volume control, but by this setting."), 10, gain_cb, this); gain_update (this); return this; } static void *latm_init_class (xine_t *xine, const void *data) { return faad_init_plugin (xine, data, "FAAD-LATM"); } static void *faad_init_class (xine_t *xine, const void *data) { return faad_init_plugin (xine, data, "FAAD"); } static const uint32_t audio_types[] = { BUF_AUDIO_AAC, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 8, }; static const uint32_t latm_audio_types[] = { BUF_AUDIO_AAC_LATM, 0 }; static const decoder_info_t dec_info_latm_audio = { .supported_types = latm_audio_types, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 16, "faad", XINE_VERSION_CODE, &dec_info_audio, faad_init_class }, { PLUGIN_AUDIO_DECODER, 16, "faad-latm", XINE_VERSION_CODE, &dec_info_latm_audio, latm_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/ff_dvaudio_decoder.c�����������������������������������������������������0000644�0001750�0001750�00000025475�14647725152�017343� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2005-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * dv audio decoder based on patch by Dan Dennedy <dan@dennedy.org> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <stdio.h> #include <inttypes.h> #include <string.h> #include <math.h> #define LOG_MODULE "dvaudio" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "ff_dvdata.h" /* This is not installed by FFmpeg, its usage has to be cleared up */ #define AUDIOBUFSIZE 128*1024 #define MAXFRAMESIZE 131072 typedef struct dvaudio_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; int output_open; int audio_channels; int audio_bits; int audio_sample_rate; unsigned char *buf; int bufsize; int size; uint8_t *decode_buffer; int decoder_ok; } dvaudio_decoder_t; /* * This is the dumbest implementation of all -- it simply looks at * a fixed offset and if pack isn't there -- fails. We might want * to have a fallback mechanism for complete search of missing packs. */ static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t) { int offs; switch (t) { case dv_audio_source: offs = (80*6 + 80*16*3 + 3); break; case dv_audio_control: offs = (80*6 + 80*16*4 + 3); break; case dv_video_control: offs = (80*5 + 48 + 5); break; default: return NULL; } return (frame[offs] == t ? &frame[offs] : NULL); } static inline uint16_t dv_audio_12to16(uint16_t sample) { uint16_t shift, result; sample = (sample < 0x800) ? sample : sample | 0xf000; shift = (sample & 0xf00) >> 8; if (shift < 0x2 || shift > 0xd) { result = sample; } else if (shift < 0x8) { shift--; result = (sample - (256 * shift)) << shift; } else { shift = 0xe - shift; result = ((sample + ((256 * shift) + 1)) << shift) - 1; } return result; } /* * There's a couple of assumptions being made here: * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples. * We can pass them upwards when ffmpeg will be ready to deal with them. * 2. We don't do software emphasis. * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples * are converted into 16bit linear ones. */ static int dv_extract_audio(uint8_t* frame, uint8_t* pcm, uint8_t* pcm2) { int size, i, j, d, of, smpls, freq, quant, half_ch; uint16_t lc, rc; const DVprofile* sys; const uint8_t* as_pack; as_pack = dv_extract_pack(frame, dv_audio_source); if (!as_pack) /* No audio ? */ return 0; sys = dv_frame_profile(frame); smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */ freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48KHz, 1 - 44,1kHz, 2 - 32 kHz */ quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ if (quant > 1) return -1; /* Unsupported quantization */ size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ half_ch = sys->difseg_size/2; /* for each DIF segment */ for (i = 0; i < sys->difseg_size; i++) { frame += 6 * 80; /* skip DIF segment header */ if (quant == 1 && i == half_ch) { if (!pcm2) break; else pcm = pcm2; } for (j = 0; j < 9; j++) { for (d = 8; d < 80; d += 2) { if (quant == 0) { /* 16bit quantization */ of = sys->audio_shuffle[i][j] + (d - 8)/2 * sys->audio_stride; if (of*2 >= size) continue; #ifdef WORDS_BIGENDIAN pcm[of*2] = frame[d]; pcm[of*2+1] = frame[d+1]; #else pcm[of*2] = frame[d+1]; pcm[of*2+1] = frame[d]; #endif if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00) pcm[of*2+1] = 0; } else { /* 12bit quantization */ lc = ((uint16_t)frame[d] << 4) | ((uint16_t)frame[d+2] >> 4); rc = ((uint16_t)frame[d+1] << 4) | ((uint16_t)frame[d+2] & 0x0f); lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc)); rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc)); of = sys->audio_shuffle[i%half_ch][j] + (d - 8)/3 * sys->audio_stride; if (of*2 >= size) continue; #ifdef WORDS_BIGENDIAN pcm[of*2] = lc >> 8; pcm[of*2+1] = lc & 0xff; #else pcm[of*2] = lc & 0xff; pcm[of*2+1] = lc >> 8; #endif of = sys->audio_shuffle[i%half_ch+half_ch][j] + (d - 8)/3 * sys->audio_stride; #ifdef WORDS_BIGENDIAN pcm[of*2] = rc >> 8; pcm[of*2+1] = rc & 0xff; #else pcm[of*2] = rc & 0xff; pcm[of*2+1] = rc >> 8; #endif ++d; } } frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ } } return size; } static void dvaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { dvaudio_decoder_t *this = xine_container_of(this_gen, dvaudio_decoder_t, audio_decoder); int bytes_consumed; int decode_buffer_size; int offset; int out; audio_buffer_t *audio_buffer; int bytes_to_send; if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if (buf->decoder_flags & BUF_FLAG_STDHEADER) { this->buf = calloc(1, AUDIOBUFSIZE); this->bufsize = AUDIOBUFSIZE; this->size = 0; this->decode_buffer = calloc(1, MAXFRAMESIZE); this->audio_sample_rate = buf->decoder_info[1]; this->audio_bits = buf->decoder_info[2]; this->audio_channels = buf->decoder_info[3]; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DV Audio"); this->decoder_ok = 1; return; } if (this->decoder_ok && !(buf->decoder_flags & (BUF_FLAG_HEADER|BUF_FLAG_SPECIAL))) { if (!this->output_open) { this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, this->audio_bits, this->audio_sample_rate, _x_ao_channels2mode(this->audio_channels)); } /* if the audio still isn't open, bail */ if (!this->output_open) return; if( this->size + buf->size > this->bufsize ) { this->bufsize = this->size + 2 * buf->size; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("dvaudio: increasing buffer to %d to avoid overflow.\n"), this->bufsize); this->buf = realloc( this->buf, this->bufsize ); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ offset = 0; while (this->size>0) { decode_buffer_size = dv_extract_audio(&this->buf[offset], this->decode_buffer, NULL); if (decode_buffer_size > -1) bytes_consumed = dv_frame_profile(&this->buf[offset])->frame_size; else bytes_consumed = decode_buffer_size; /* dispatch the decoded audio */ out = 0; while (out < decode_buffer_size) { audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); if (audio_buffer->mem_size == 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "dvaudio: Help! Allocated audio buffer with nothing in it!\n"); return; } if ((decode_buffer_size - out) > audio_buffer->mem_size) bytes_to_send = audio_buffer->mem_size; else bytes_to_send = decode_buffer_size - out; /* fill up this buffer */ xine_fast_memcpy(audio_buffer->mem, &this->decode_buffer[out], bytes_to_send); /* byte count / 2 (bytes / sample) / channels */ audio_buffer->num_frames = bytes_to_send / 2 / this->audio_channels; audio_buffer->vpts = buf->pts; buf->pts = 0; /* only first buffer gets the real pts */ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); out += bytes_to_send; } this->size -= bytes_consumed; offset += bytes_consumed; } /* reset internal accumulation buffer */ this->size = 0; } } } static void dvaudio_reset (audio_decoder_t *this_gen) { dvaudio_decoder_t *this = xine_container_of(this_gen, dvaudio_decoder_t, audio_decoder); this->size = 0; } static void dvaudio_discontinuity (audio_decoder_t *this_gen) { (void)this_gen; } static void dvaudio_dispose (audio_decoder_t *this_gen) { dvaudio_decoder_t *this = xine_container_of(this_gen, dvaudio_decoder_t, audio_decoder); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; _x_freep(&this->buf); _x_freep(&this->decode_buffer); free (this_gen); } static audio_decoder_t *dvaudio_open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { dvaudio_decoder_t *this ; (void)class_gen; this = calloc(1, sizeof (dvaudio_decoder_t)); if (!this) return NULL; this->audio_decoder.decode_data = dvaudio_decode_data; this->audio_decoder.reset = dvaudio_reset; this->audio_decoder.discontinuity = dvaudio_discontinuity; this->audio_decoder.dispose = dvaudio_dispose; this->output_open = 0; this->audio_channels = 0; this->stream = stream; this->buf = NULL; this->size = 0; this->decoder_ok = 0; return &this->audio_decoder; } static void *init_dvaudio_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = dvaudio_open_plugin, .identifier = "dv audio", .description = N_("dv audio decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (void *)&this; } static uint32_t supported_audio_types[] = { BUF_AUDIO_DV, 0 }; static const decoder_info_t dec_info_dvaudio = { .supported_types = supported_audio_types, .priority = 5, }; /* * exported plugin catalog entry */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 16, "dvaudio", XINE_VERSION_CODE, &dec_info_dvaudio, init_dvaudio_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/fooaudio.c���������������������������������������������������������������0000644�0001750�0001750�00000026606�14647725152�015352� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * fooaudio.c: This is a reference audio decoder for the xine multimedia * player. It really works too! It will output a continuous sine wave in * place of the data it should actually send. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" /* math.h required for fooaudio sine wave generation */ #include <math.h> #define AUDIOBUFSIZE 128*1024 typedef struct { audio_decoder_class_t decoder_class; } fooaudio_class_t; typedef struct fooaudio_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; int sample_rate; /* audio sample rate */ int bits_per_sample; /* bits/sample, usually 8 or 16 */ int channels; /* 1 or 2, usually */ int output_open; /* flag to indicate audio is ready */ unsigned char *buf; /* data accumulation buffer */ int bufsize; /* maximum size of buf */ int size; /* size of accumulated data in buf */ /* fooaudio-specific variables */ int64_t last_pts; unsigned int iteration; } fooaudio_decoder_t; /************************************************************************** * fooaudio specific decode functions *************************************************************************/ /************************************************************************** * xine audio plugin functions *************************************************************************/ static void fooaudio_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; audio_buffer_t *audio_buffer; int i; int64_t samples_to_generate; int samples_to_send; if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* When the engine sends a BUF_FLAG_HEADER flag, it is time to initialize * the decoder. The buffer element type has 4 decoder_info fields, * 0..3. Field 1 is the sample rate. Field 2 is the bits/sample. Field * 3 is the number of channels. */ this->sample_rate = buf->decoder_info[1]; this->bits_per_sample = buf->decoder_info[2]; this->channels = buf->decoder_info[3]; /* initialize the data accumulation buffer */ this->buf = calloc(1, AUDIOBUFSIZE); this->bufsize = AUDIOBUFSIZE; this->size = 0; /* take this opportunity to initialize stream/meta information */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "fooaudio"); /* perform any other required initialization */ this->last_pts = -1; this->iteration = 0; return; } /* if the audio output is not open yet, open the audio output */ #warning: Audio output is hardcoded to mono 16-bit PCM if (!this->output_open) { this->output_open = (this->stream->audio_out->open) ( this->stream->audio_out, this->stream, /* this->bits_per_sample, */ 16, this->sample_rate, /* _x_ao_channels2mode(this->channels));*/ AO_CAP_MODE_MONO); } /* if the audio still isn't open, do not go any further with the decode */ if (!this->output_open) return; /* accumulate the data passed through the buffer element type; increase * the accumulator buffer size as necessary */ if( this->size + buf->size > this->bufsize ) { this->bufsize = this->size + 2 * buf->size; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "fooaudio: increasing source buffer to %d to avoid overflow.\n", this->bufsize); this->buf = realloc( this->buf, this->bufsize ); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; /* When a buffer element type has the BUF_FLAG_FRAME_END flag set, it is * time to decode the data in the buffer. */ if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* This is where the real meat of the audio decoder is implemented. * The general strategy is to decode the data in the accumulation buffer * into raw PCM data and then dispatch the PCM to the engine in smaller * buffers. What follows in the inside of this scope is the meat of * this particular audio decoder. */ /* Operation of the fooaudio decoder: * This decoder generates a continuous sine pattern based on the pts * values sent by the xine engine. Two pts values are needed to know * how long to make the audio. Thus, If this is the first frame or * a seek has occurred (indicated by this->last_pts = -1), * log the pts but do not create any audio. * * When a valid pts delta is generated, create n audio samples, where * n is given as: * * n pts delta * ----------- = --------- => n = (pts delta * sample rate) / 90000 * sample rate 90000 * */ if (this->last_pts != -1) { /* no real reason to set this variable to 0 first; I just wanted the * novelty of using all 4 basic arithmetic ops in a row (+ - * /) */ samples_to_generate = 0; samples_to_generate += buf->pts; samples_to_generate -= this->last_pts; samples_to_generate *= this->sample_rate; samples_to_generate /= 90000; /* save the pts now since it will likely be trashed later */ this->last_pts = buf->pts; while (samples_to_generate) { /* get an audio buffer */ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); if (audio_buffer->mem_size == 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "fooaudio: Help! Allocated audio buffer with nothing in it!\n"); return; } /* samples_to_generate is a sample count; mem_size is a byte count */ if (samples_to_generate > audio_buffer->mem_size / 2) samples_to_send = audio_buffer->mem_size / 2; else samples_to_send = samples_to_generate; samples_to_generate -= samples_to_send; #define WAVE_HZ 300 /* fill up the samples in the buffer */ for (i = 0; i < samples_to_send; i++) audio_buffer->mem[i] = (short)(sin(2 * M_PI * this->iteration++ / WAVE_HZ) * 32767); /* final prep for audio buffer dispatch */ audio_buffer->num_frames = samples_to_send; audio_buffer->vpts = buf->pts; buf->pts = 0; /* only first buffer gets the real pts */ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } } else { /* log the pts for the next time */ this->last_pts = buf->pts; } /* reset data accumulation buffer */ this->size = 0; } } /* This function resets the state of the audio decoder. This usually * entails resetting the data accumulation buffer. */ static void fooaudio_reset (audio_decoder_t *this_gen) { fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; this->size = 0; /* this is specific to fooaudio */ this->last_pts = -1; } /* This function resets the last pts value of the audio decoder. */ static void fooaudio_discontinuity (audio_decoder_t *this_gen) { fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; /* this is specific to fooaudio */ this->last_pts = -1; } /* This function closes the audio output and frees the private audio decoder * structure. */ static void fooaudio_dispose (audio_decoder_t *this_gen) { fooaudio_decoder_t *this = (fooaudio_decoder_t *) this_gen; /* close the audio output */ if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; /* free anything that was allocated during operation */ free(this->buf); free(this); } /* This function allocates, initializes, and returns a private audio * decoder structure. */ static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { fooaudio_decoder_t *this ; this = (fooaudio_decoder_t *) calloc(1, sizeof(fooaudio_decoder_t)); /* connect the member functions */ this->audio_decoder.decode_data = fooaudio_decode_data; this->audio_decoder.reset = fooaudio_reset; this->audio_decoder.discontinuity = fooaudio_discontinuity; this->audio_decoder.dispose = fooaudio_dispose; /* connect the stream */ this->stream = stream; /* audio output is not open at the start */ this->output_open = 0; /* initialize the basic audio parameters */ this->channels = 0; this->sample_rate = 0; this->bits_per_sample = 0; /* initialize the data accumulation buffer */ this->buf = NULL; this->bufsize = 0; this->size = 0; /* return the newly-initialized audio decoder */ return &this->audio_decoder; } /* This function frees the audio decoder class and any other memory that was * allocated. */ static void dispose_class (audio_decoder_class_t *this_gen) { fooaudio_class_t *this = (fooaudio_class_t *)this_gen; free (this); } /* This function allocates a private audio decoder class and initializes * the class's member functions. */ static void *init_plugin (xine_t *xine, const void *data) { fooaudio_class_t *this ; this = (fooaudio_class_t *) calloc (1, sizeof (fooaudio_class_t)); this->decoder_class.open_plugin = open_plugin; this->decoder_class.identifier = "fooaudio"; this->decoder_class.description = N_("fooaudio: reference xine audio decoder plugin"); this->decoder_class.dispose = dispose_class; return this; } /* This is a list of all of the internal xine audio buffer types that * this decoder is able to handle. Check src/xine-engine/buffer.h for a * list of valid buffer types (and add a new one if the one you need does * not exist). Terminate the list with a 0. */ static const uint32_t audio_types[] = { /* BUF_AUDIO_FOO, */ 0 }; /* This data structure combines the list of supported xine buffer types and * the priority that the plugin should be given with respect to other * plugins that handle the same buffer type. A plugin with priority (n+1) * will be used instead of a plugin with priority (n). */ static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 5, }; /* The plugin catalog entry. This is the only information that this plugin * will export to the public. */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* { type, API version, "name", version, special_info, init_function }, */ { PLUGIN_AUDIO_DECODER, 16, "fooaudio", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/xine_dts_decoder.c�������������������������������������������������������0000644�0001750�0001750�00000051757�14647725152�017054� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /** * @file * @brief DTS decoder for xine * * @author Joachim Koenig (2001-09-04) * @author James Courtier-Dutton (2001-12-09) */ #define _DEFAULT_SOURCE 1 #ifndef __sun /* required for swab() */ #define _XOPEN_SOURCE 500 #endif /* avoid compiler warnings */ #define _BSD_SOURCE 1 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #define LOG_MODULE "libdts" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include "bswap.h" #include <dts.h> #define MAX_AC5_FRAME 4096 typedef struct { audio_decoder_t audio_decoder; xine_stream_t *stream; dts_state_t *dts_state; int64_t pts; int audio_caps; int sync_state; int ac5_length, ac5_pcm_length, frame_todo; uint32_t syncdword; uint8_t frame_buffer[MAX_AC5_FRAME + 1]; uint8_t *frame_ptr; int output_open; int bypass_mode; int dts_flags; int dts_sample_rate; int dts_bit_rate; int dts_flags_map[11]; /* Convert from stream dts_flags to the dts_flags we want from the dts downmixer */ int ao_flags_map[11]; /* Convert from the xine AO_CAP's to dts_flags. */ int have_lfe; } dts_decoder_t; static void dts_reset (audio_decoder_t *const this_gen) { (void)this_gen; } static void dts_discontinuity (audio_decoder_t *const this_gen) { (void)this_gen; } /** * @brief Convert a array of floating point samples into 16-bit signed integer samples * @param f Floating point samples array (origin) * @param s16 16-bit signed integer samples array (destination) * @param num_channels Number of channels present in the stream * * @todo This same work is being done in many decoders to adapt the output of * the decoder to what the audio output can actually use, this should be * done by the audio_output loop, not by the decoders. * @note This is subtly different from the function with the same name in xine_musepack_decoder.c */ static inline void float_to_int (const float *const _f, int16_t *const s16, const int num_channels) { const int endidx = 256 * num_channels; int i, j; for (i = 0, j = 0; j < endidx; i++, j += num_channels) { const float f = _f[i] * 32767; if (f > INT16_MAX) s16[j] = INT16_MAX; else if (f < INT16_MIN) s16[j] = INT16_MIN; else s16[j] = f; /* printf("samples[%d] = %f, %d\n", i, _f[i], s16[num_channels*i]); */ } } static inline void mute_channel (int16_t *const s16, const int num_channels) { const int endidx = 256 * num_channels; int i; for (i = 0; i < endidx; i += num_channels) s16[i] = 0; } static void dts_decode_frame (dts_decoder_t *this, const int64_t pts) { audio_buffer_t *audio_buffer; uint32_t ac5_spdif_type=0; int output_mode = AO_CAP_MODE_STEREO; uint8_t *data_out; uint8_t *const data_in = this->frame_buffer; lprintf("decode_frame\n"); audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); audio_buffer->vpts = pts; if(this->bypass_mode) { /* SPDIF digital output */ if (!this->output_open) { this->output_open = ((this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->dts_sample_rate, AO_CAP_MODE_AC5)); } if (!this->output_open) return; data_out=(uint8_t *) audio_buffer->mem; if (this->ac5_length > MAX_AC5_FRAME) { /* XXX is this even possible ? ac5_length is checked in dts_decode_data() */ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: ac5_length too long\n"); this->ac5_pcm_length = 0; return; } switch (this->ac5_pcm_length) { case 512: ac5_spdif_type = 0x0b; /* DTS-1 (512-sample bursts) */ break; case 1024: ac5_spdif_type = 0x0c; /* DTS-1 (1024-sample bursts) */ break; case 2048: ac5_spdif_type = 0x0d; /* DTS-1 (2048-sample bursts) */ break; default: xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: DTS %i-sample bursts not supported\n", this->ac5_pcm_length); return; } #ifdef LOG_DEBUG { int i; printf("libdts: DTS frame type=%d\n",data_in[4] >> 7); printf("libdts: DTS deficit frame count=%d\n",(data_in[4] & 0x7f) >> 2); printf("libdts: DTS AC5 PCM samples=%d\n",ac5_pcm_samples); printf("libdts: DTS AC5 length=%d\n",this->ac5_length); printf("libdts: DTS AC5 bitrate=%d\n",((data_in[8] & 0x03) << 4) | (data_in[8] >> 4)); printf("libdts: DTS AC5 spdif type=%d\n", ac5_spdif_type); printf("libdts: "); for(i=2000;i<2048;i++) { printf("%02x ",data_in[i]); } printf("\n"); } #endif lprintf("length=%d pts=%"PRId64"\n",this->ac5_pcm_length,audio_buffer->vpts); audio_buffer->num_frames = this->ac5_pcm_length; // Checking if AC5 data plus IEC958 header will fit into frames samples data if ( this->ac5_length + 8 <= this->ac5_pcm_length * 2 * 2 ) { data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */ data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */ data_out[4] = ac5_spdif_type; /* DTS data */ data_out[5] = 0; /* Unknown */ data_out[6] = (this->ac5_length << 3) & 0xff; /* ac5_length * 8 */ data_out[7] = ((this->ac5_length ) >> 5) & 0xff; if( this->ac5_pcm_length ) { if( this->ac5_pcm_length % 2) { swab(data_in, &data_out[8], this->ac5_length ); } else { swab(data_in, &data_out[8], this->ac5_length + 1); } } // Transmit it without header otherwise, receivers will autodetect DTS } else { lprintf("AC5 data is too large (%i > %i), sending without IEC958 header\n", this->ac5_length + 8, this->ac5_pcm_length * 2 * 2); memcpy(data_out, data_in, this->ac5_length); } } else { /* Software decode */ int i, dts_output_flags; int16_t *const int_samples = audio_buffer->mem; int number_of_dts_blocks; level_t level = 1.0; sample_t *samples; dts_output_flags = this->dts_flags_map[this->dts_flags & DTS_CHANNEL_MASK]; if(dts_frame(this->dts_state, data_in, &dts_output_flags, &level, 0)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: dts_frame error\n"); return; } this->have_lfe = dts_output_flags & DTS_LFE; if (this->have_lfe) if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { output_mode = AO_CAP_MODE_5_1CHANNEL; } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { output_mode = AO_CAP_MODE_4_1CHANNEL; } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: WHAT DO I DO!!!\n"); output_mode = this->ao_flags_map[dts_output_flags & DTS_CHANNEL_MASK]; } else output_mode = this->ao_flags_map[dts_output_flags & DTS_CHANNEL_MASK]; if (!this->output_open) { this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->dts_sample_rate, output_mode); } if (!this->output_open) return; number_of_dts_blocks = dts_blocks_num (this->dts_state); audio_buffer->num_frames = 256*number_of_dts_blocks; for(i = 0; i < number_of_dts_blocks; i++) { if(dts_block(this->dts_state)) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: dts_block error on audio channel %d\n", i); audio_buffer->num_frames = 0; break; } samples = dts_samples(this->dts_state); switch (output_mode) { case AO_CAP_MODE_MONO: float_to_int (&samples[0], int_samples+(i*256), 1); break; case AO_CAP_MODE_STEREO: /* Tested, working. */ float_to_int (&samples[0*256], int_samples+(i*256*2), 2); /* L */ float_to_int (&samples[1*256], int_samples+(i*256*2)+1, 2); /* R */ break; case AO_CAP_MODE_4CHANNEL: /* Tested, working */ float_to_int (&samples[0*256], int_samples+(i*256*4), 4); /* L */ float_to_int (&samples[1*256], int_samples+(i*256*4)+1, 4); /* R */ float_to_int (&samples[2*256], int_samples+(i*256*4)+2, 4); /* RL */ float_to_int (&samples[3*256], int_samples+(i*256*4)+3, 4); /* RR */ break; case AO_CAP_MODE_4_1CHANNEL: /* Tested, working */ float_to_int (&samples[0*256], int_samples+(i*256*6)+0, 6); /* L */ float_to_int (&samples[1*256], int_samples+(i*256*6)+1, 6); /* R */ float_to_int (&samples[2*256], int_samples+(i*256*6)+2, 6); /* RL */ float_to_int (&samples[3*256], int_samples+(i*256*6)+3, 6); /* RR */ float_to_int (&samples[4*256], int_samples+(i*256*6)+5, 6); /* LFE */ mute_channel ( int_samples+(i*256*6)+4, 6); /* C */ break; case AO_CAP_MODE_5CHANNEL: /* Tested, working */ float_to_int (&samples[0*256], int_samples+(i*256*6)+4, 6); /* C */ float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ mute_channel ( int_samples+(i*256*6)+5, 6); /* LFE */ break; case AO_CAP_MODE_5_1CHANNEL: float_to_int (&samples[0*256], int_samples+(i*256*6)+4, 6); /* C */ float_to_int (&samples[1*256], int_samples+(i*256*6)+0, 6); /* L */ float_to_int (&samples[2*256], int_samples+(i*256*6)+1, 6); /* R */ float_to_int (&samples[3*256], int_samples+(i*256*6)+2, 6); /* RL */ float_to_int (&samples[4*256], int_samples+(i*256*6)+3, 6); /* RR */ float_to_int (&samples[5*256], int_samples+(i*256*6)+5, 6); /* LFE */ /* Not working yet */ break; default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libdts: help - unsupported mode %08x\n", output_mode); } } } this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } static void dts_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { dts_decoder_t *const this = xine_container_of(this_gen, dts_decoder_t, audio_decoder); uint8_t *current = (uint8_t *)buf->content; uint8_t *sync_start=current + 1; uint8_t *const end = buf->content + buf->size; lprintf("decode_data\n"); if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if (buf->decoder_flags & BUF_FLAG_STDHEADER) return; lprintf ("processing...state %d\n", this->sync_state); while (current < end) { switch (this->sync_state) { case 0: /* Looking for sync header */ this->syncdword = (this->syncdword << 8) | *current++; /* if ((this->syncdword == 0xff1f00e8) || (this->syncdword == 0x1fffe800) || (this->syncdword == 0xfe7f0180) || (this->syncdword == 0x7ffe8001) ) { */ if ((this->syncdword == 0x7ffe8001) || (this->syncdword == 0xff1f00e8)) { const uint32_t be_syncdword = be2me_32(this->syncdword); lprintf ("sync found: syncdword=0x%x\n", this->syncdword); memcpy(this->frame_buffer, &be_syncdword, sizeof(be_syncdword)); this->sync_state = 1; this->frame_ptr = this->frame_buffer+4; this->pts = buf->pts; } break; case 1: /* Looking for enough bytes for sync_info. */ sync_start = current - 1; *this->frame_ptr++ = *current++; if ((this->frame_ptr - this->frame_buffer) > 19) { const int old_dts_flags = this->dts_flags; const int old_dts_sample_rate = this->dts_sample_rate; const int old_dts_bit_rate = this->dts_bit_rate; this->ac5_length = dts_syncinfo (this->dts_state, this->frame_buffer, &this->dts_flags, &this->dts_sample_rate, &this->dts_bit_rate, &(this->ac5_pcm_length)); lprintf("ac5_length=%d\n",this->ac5_length); lprintf("dts_sample_rate=%d\n",this->dts_sample_rate); if ( (this->ac5_length < 80) || (this->ac5_length > MAX_AC5_FRAME) ) { /* Invalid dts ac5_pcm_length */ this->syncdword = 0; current = sync_start; this->sync_state = 0; break; } lprintf("Frame length = %d\n",this->ac5_pcm_length); this->frame_todo = this->ac5_length - 20; this->sync_state = 2; if (!_x_meta_info_get(this->stream, XINE_META_INFO_AUDIOCODEC) || old_dts_flags != this->dts_flags || old_dts_sample_rate != this->dts_sample_rate || old_dts_bit_rate != this->dts_bit_rate) { switch (this->dts_flags & DTS_CHANNEL_MASK) { case DTS_3F2R: if (this->dts_flags & DTS_LFE) _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 5.1"); else _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 5.0"); break; case DTS_3F1R: case DTS_2F2R: if (this->dts_flags & DTS_LFE) _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 4.1"); else _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 4.0"); break; case DTS_2F1R: case DTS_3F: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 3.0"); break; case DTS_STEREO: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 2.0 (stereo)"); break; case DTS_MONO: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS 1.0"); break; default: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "DTS"); break; } _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->dts_bit_rate); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_SAMPLERATE, this->dts_sample_rate); } } break; case 2: /* Filling frame_buffer with sync_info bytes */ *this->frame_ptr++ = *current++; this->frame_todo--; if (this->frame_todo > 0) { break; } this->sync_state = 3; /* fall through */ case 3: /* Ready for decode */ #if 0 dtsdec_decode_frame (this, this->pts_list[0]); #else dts_decode_frame (this, this->pts); #endif /* fall through */ case 4: /* Clear up ready for next frame */ this->pts = 0; this->syncdword = 0; this->sync_state = 0; break; default: /* No come here */ break; } } } static void dts_dispose (audio_decoder_t *this_gen) { dts_decoder_t *const this = xine_container_of(this_gen, dts_decoder_t, audio_decoder); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); dca_free(this->dts_state); this->dts_state = NULL; free (this); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { dts_decoder_t *this ; (void)class_gen; lprintf("open_plugin\n"); this = calloc(1, sizeof (dts_decoder_t)); if (!this) return NULL; this->audio_decoder.decode_data = dts_decode_data; this->audio_decoder.reset = dts_reset; this->audio_decoder.discontinuity = dts_discontinuity; this->audio_decoder.dispose = dts_dispose; this->dts_state = dts_init(0); this->audio_caps = stream->audio_out->get_capabilities(stream->audio_out); if(this->audio_caps & AO_CAP_MODE_AC5) this->bypass_mode = 1; else { this->bypass_mode = 0; /* FIXME: Leave "DOLBY pro logic" downmix out for now. */ this->dts_flags_map[DTS_MONO] = DTS_MONO; this->dts_flags_map[DTS_STEREO] = DTS_STEREO; this->dts_flags_map[DTS_3F] = DTS_STEREO; this->dts_flags_map[DTS_2F1R] = DTS_STEREO; this->dts_flags_map[DTS_3F1R] = DTS_STEREO; this->dts_flags_map[DTS_2F2R] = DTS_STEREO; this->dts_flags_map[DTS_3F2R] = DTS_STEREO; this->ao_flags_map[DTS_MONO] = AO_CAP_MODE_MONO; this->ao_flags_map[DTS_STEREO] = AO_CAP_MODE_STEREO; this->ao_flags_map[DTS_3F] = AO_CAP_MODE_STEREO; this->ao_flags_map[DTS_2F1R] = AO_CAP_MODE_STEREO; this->ao_flags_map[DTS_3F1R] = AO_CAP_MODE_STEREO; this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_STEREO; this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_STEREO; /* find best mode */ if (this->audio_caps & AO_CAP_MODE_5_1CHANNEL) { this->dts_flags_map[DTS_2F2R] = DTS_2F2R; this->dts_flags_map[DTS_3F2R] = DTS_3F2R | DTS_LFE; this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_5CHANNEL; } else if (this->audio_caps & AO_CAP_MODE_5CHANNEL) { this->dts_flags_map[DTS_2F2R] = DTS_2F2R; this->dts_flags_map[DTS_3F2R] = DTS_3F2R; this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_5CHANNEL; } else if (this->audio_caps & AO_CAP_MODE_4_1CHANNEL) { this->dts_flags_map[DTS_2F2R] = DTS_2F2R; this->dts_flags_map[DTS_3F2R] = DTS_2F2R | DTS_LFE; this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_4CHANNEL; } else if (this->audio_caps & AO_CAP_MODE_4CHANNEL) { this->dts_flags_map[DTS_2F2R] = DTS_2F2R; this->dts_flags_map[DTS_3F2R] = DTS_2F2R; this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_4CHANNEL; this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_4CHANNEL; /* else if (this->audio_caps & AO_CAP_MODE_STEREO) defaults are ok */ } else if (!(this->audio_caps & AO_CAP_MODE_STEREO)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("HELP! a mono-only audio driver?!\n")); this->dts_flags_map[DTS_MONO] = DTS_MONO; this->dts_flags_map[DTS_STEREO] = DTS_MONO; this->dts_flags_map[DTS_3F] = DTS_MONO; this->dts_flags_map[DTS_2F1R] = DTS_MONO; this->dts_flags_map[DTS_3F1R] = DTS_MONO; this->dts_flags_map[DTS_2F2R] = DTS_MONO; this->dts_flags_map[DTS_3F2R] = DTS_MONO; this->ao_flags_map[DTS_MONO] = AO_CAP_MODE_MONO; this->ao_flags_map[DTS_STEREO] = AO_CAP_MODE_MONO; this->ao_flags_map[DTS_3F] = AO_CAP_MODE_MONO; this->ao_flags_map[DTS_2F1R] = AO_CAP_MODE_MONO; this->ao_flags_map[DTS_3F1R] = AO_CAP_MODE_MONO; this->ao_flags_map[DTS_2F2R] = AO_CAP_MODE_MONO; this->ao_flags_map[DTS_3F2R] = AO_CAP_MODE_MONO; } } this->stream = stream; this->output_open = 0; return &this->audio_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "DTS", .description = N_("DTS passthru audio format decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (void *)&this; } static const uint32_t audio_types[] = { BUF_AUDIO_DTS, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 8, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 16, "dts", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������xine-lib-1.2/src/audio_dec/xine_musepack_decoder.c��������������������������������������������������0000644�0001750�0001750�00000036650�14647725152�020065� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2005-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /** * @file * @brief xine interface to libmusepack/libmpcdec * @author James Stembridge <jstembridge@gmail.com> * * @todo Add support for 32-bit float samples. * @todo Add support for seeking. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #define LOG_MODULE "mpc_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #ifdef HAVE_MPCDEC_MPCDEC_H # include <mpcdec/mpcdec.h> #elif defined(HAVE_MPC_MPCDEC_H) # include <mpc/mpcdec.h> #else # include "mpcdec/mpcdec.h" #endif #define MPC_DECODER_MEMSIZE 65536 #define MPC_DECODER_MEMSIZE2 (MPC_DECODER_MEMSIZE/2) #define INIT_BUFSIZE (MPC_DECODER_MEMSIZE*2) typedef struct mpc_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; int sample_rate; /* audio sample rate */ int bits_per_sample; /* bits/sample, usually 8 or 16 */ int channels; /* 1 or 2, usually */ int output_open; /* flag to indicate audio is ready */ unsigned char *buf; /* data accumulation buffer */ unsigned int buf_max; /* maximum size of buf */ unsigned int read; /* size of accum. data already read */ unsigned int size; /* size of accumulated data in buf */ mpc_reader reader; mpc_streaminfo streaminfo; #ifndef HAVE_MPC_MPCDEC_H mpc_decoder decoder; #else mpc_demux *decoder; #endif int decoder_ok; unsigned int current_frame; int32_t file_size; } mpc_decoder_t; /************************************************************************** * musepack specific functions *************************************************************************/ #ifndef HAVE_MPC_MPCDEC_H # define MPC_THIS mpc_decoder_t * const this = (mpc_decoder_t *)data #else # define MPC_THIS mpc_decoder_t * const this = (mpc_decoder_t *)data->data #endif /* Reads size bytes of data into buffer at ptr. */ #ifndef HAVE_MPC_MPCDEC_H static int32_t mpc_reader_read (void *const data, void *const ptr, int size) #else static int32_t mpc_reader_read (mpc_reader *data, void *ptr, int32_t size) #endif { MPC_THIS; lprintf("mpc_reader_read: size=%d\n", size); /* Don't try to read more data than we have */ if ((unsigned int)size > (this->size - this->read)) size = this->size - this->read; /* Copy the data */ xine_fast_memcpy(ptr, &this->buf[this->read], size); /* Update our position in the data buffer */ this->read += size; return size; } /* Seeks to byte position offset. */ #ifndef HAVE_MPC_MPCDEC_H static mpc_bool_t mpc_reader_seek (void *const data, const int32_t offset) #else static mpc_bool_t mpc_reader_seek(mpc_reader *data, int32_t offset) #endif { MPC_THIS; lprintf("mpc_reader_seek: offset=%d\n", offset); /* seek is only called when reading the header so we can assume * that the buffer starts at the start of the file */ this->read = offset; #ifndef HAVE_MPC_MPCDEC_H return TRUE; #else return MPC_TRUE; #endif } /* Returns the current byte offset in the stream. */ #ifndef HAVE_MPC_MPCDEC_H static int32_t mpc_reader_tell (void *const data) #else static int32_t mpc_reader_tell (mpc_reader *const data) #endif { (void)data; lprintf("mpc_reader_tell\n"); /* Tell isn't used so just return 0 */ return 0; } /* Returns the total length of the source stream, in bytes. */ #ifndef HAVE_MPC_MPCDEC_H static int32_t mpc_reader_get_size (void *const data) #else static int32_t mpc_reader_get_size (mpc_reader *const data) #endif { MPC_THIS; lprintf("mpc_reader_get_size\n"); return this->file_size; } /* True if the stream is a seekable stream. */ #ifndef HAVE_MPC_MPCDEC_H static mpc_bool_t mpc_reader_canseek(void *data) { (void)data; lprintf("mpc_reader_canseek\n"); return TRUE; } #else static mpc_bool_t mpc_reader_canseek(mpc_reader *data) { (void)data; lprintf("mpc_reader_canseek\n"); return MPC_TRUE; } #endif /** * @brief Convert a array of floating point samples into 16-bit signed integer samples * @param f Floating point samples array (origin) * @param s16 16-bit signed integer samples array (destination) * @param samples Number of samples to convert * * @todo This same work is being done in many decoders to adapt the output of * the decoder to what the audio output can actually use, this should be * done by the audio_output loop, not by the decoders. */ static inline void float_to_int(const float *const _f, int16_t *const s16, const int samples) { int i; for (i = 0; i < samples; i++) { const float f = _f[i] * 32767; if (f > INT16_MAX) s16[i] = INT16_MAX; else if (f < INT16_MIN) s16[i] = INT16_MIN; else s16[i] = f; /* printf("samples[%d] = %f, %d\n", i, _f[i], s16[num_channels*i]); */ } } /* Decode a musepack frame */ static int mpc_decode_frame (mpc_decoder_t *this) { float buffer[MPC_DECODER_BUFFER_LENGTH]; uint32_t frames; #ifdef HAVE_MPC_MPCDEC_H mpc_frame_info frame; #endif lprintf("mpd_decode_frame\n"); #ifndef HAVE_MPC_MPCDEC_H frames = mpc_decoder_decode(&this->decoder, buffer, 0, 0); #else frame.buffer = buffer; mpc_demux_decode(this->decoder, &frame); frames = frame.samples; #endif if (frames > 0) { audio_buffer_t *audio_buffer; int16_t *int_samples; lprintf("got %d samples\n", frames); /* Get audio buffer */ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); audio_buffer->vpts = 0; audio_buffer->num_frames = frames; /* Convert samples */ int_samples = (int16_t *) audio_buffer->mem; float_to_int(buffer, int_samples, frames*this->channels); /* Output converted samples */ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } return frames; } /************************************************************************** * xine audio plugin functions *************************************************************************/ static void mpc_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { mpc_decoder_t *this = xine_container_of(this_gen, mpc_decoder_t, audio_decoder); int err; lprintf("mpc_decode_data\n"); if (!_x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED)) return; /* We don't handle special buffers */ if (buf->decoder_flags & BUF_FLAG_SPECIAL) return; /* Read header */ if (buf->decoder_flags & BUF_FLAG_HEADER) { lprintf("header\n"); /* File size is in decoder_info[0] */ this->file_size = buf->decoder_info[0]; /* Initialise the data accumulation buffer */ this->buf = calloc(1, INIT_BUFSIZE); this->buf_max = INIT_BUFSIZE; this->read = 0; this->size = 0; /* Initialise the reader */ this->reader.read = mpc_reader_read; this->reader.seek = mpc_reader_seek; this->reader.tell = mpc_reader_tell; this->reader.get_size = mpc_reader_get_size; this->reader.canseek = mpc_reader_canseek; this->reader.data = this; /* Copy header to buffer */ xine_fast_memcpy(this->buf, buf->content, buf->size); this->size = buf->size; #ifdef HAVE_MPC_MPCDEC_H this->decoder = mpc_demux_init(&this->reader); if (!this->decoder) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("libmusepack: mpc_demux_init failed.\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return; } mpc_demux_get_info(this->decoder, &this->streaminfo); #else /* Initialise and read stream info */ mpc_streaminfo_init(&this->streaminfo); if ((err = mpc_streaminfo_read(&this->streaminfo, &this->reader))) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("libmusepack: mpc_streaminfo_read failed: %d\n"), err); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return; } #endif this->sample_rate = this->streaminfo.sample_freq; this->channels = this->streaminfo.channels; this->bits_per_sample = 16; /* After the header the demuxer starts sending data from an offset * of 28 bytes */ this->size = 28; /* We need to keep track of the current frame so we now when we've * reached the end of the stream */ this->current_frame = 0; /* Setup the decoder */ #ifndef HAVE_MPC_MPCDEC_H mpc_decoder_setup(&this->decoder, &this->reader); #endif this->decoder_ok = 0; /* Take this opportunity to initialize stream/meta information */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Musepack (libmusepack)"); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, (int) this->streaminfo.average_bitrate); return; } lprintf("data: %u size=%u read=%u\n", buf->size, this->size, this->read); /* if the audio output is not open yet, open the audio output */ if (!this->output_open) { this->output_open = (this->stream->audio_out->open) ( this->stream->audio_out, this->stream, this->bits_per_sample, this->sample_rate, _x_ao_channels2mode(this->channels)); /* if the audio still isn't open, do not go any further with the decode */ if (!this->output_open) return; } /* If we run out of space in our internal buffer we discard what's * already been read */ if (((this->size + buf->size) > this->buf_max) && this->read) { lprintf("discarding read data\n"); this->size -= this->read; memmove(this->buf, &this->buf[this->read], this->size); this->read = 0; } /* If there still isn't space we have to increase the size of the * internal buffer */ if ((this->size + buf->size) > this->buf_max) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libmusepack: increasing internal buffer size\n"); this->buf_max += 2*buf->size; this->buf = realloc(this->buf, this->buf_max); } /* Copy data */ xine_fast_memcpy(&this->buf[this->size], buf->content, buf->size); this->size += buf->size; /* Time to decode */ if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* Increment frame count */ #ifndef HAVE_MPC_MPCDEC_H if (this->current_frame++ == this->streaminfo.frames) #else if (this->current_frame++ == this->streaminfo.samples) #endif { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("libmusepack: data after last frame ignored\n")); return; } if (!this->decoder_ok) { /* We require MPC_DECODER_MEMSIZE bytes to initialise the decoder */ if ((this->size - this->read) >= MPC_DECODER_MEMSIZE) { lprintf("initialise"); #ifndef HAVE_MPC_MPCDEC_H if (!mpc_decoder_initialize (&this->decoder, &this->streaminfo)) #else if (!this->decoder) #endif { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("libmusepack: mpc_decoder_initialise failed\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return; } this->decoder_ok = 1; } else { /* Not enough data yet */ return; } } /* mpc_decoder_decode may cause a read of MPC_DECODER_MEMSIZE/2 bytes so * make sure we have enough data available */ if ((this->size - this->read) >= MPC_DECODER_MEMSIZE2) { lprintf("decoding\n"); if ((err = mpc_decode_frame(this)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("libmusepack: mpc_decoder_decode failed: %d\n"), err); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); return; } } /* If we are at the end of the stream we decode the remaining frames as we * know we'll have enough data */ #ifndef HAVE_MPC_MPCDEC_H if (this->current_frame == this->streaminfo.frames) #else if (this->current_frame == this->streaminfo.samples) #endif { lprintf("flushing buffers\n"); do { if ((err = mpc_decode_frame(this)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("libmusepack: mpc_decoder_decode failed: %d\n"), err); } } while (err > 0); lprintf("buffers flushed\n"); } } } static void mpc_reset (audio_decoder_t *this_gen) { mpc_decoder_t *this = xine_container_of(this_gen, mpc_decoder_t, audio_decoder); this->size = 0; this->read = 0; } static void mpc_discontinuity (audio_decoder_t *this_gen) { /* mpc_decoder_t *this = (mpc_decoder_t *) this_gen; */ (void)this_gen; } static void mpc_dispose (audio_decoder_t *this_gen) { mpc_decoder_t *this = xine_container_of(this_gen, mpc_decoder_t, audio_decoder); /* close the audio output */ if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; /* free anything that was allocated during operation */ _x_freep(&this->buf); #ifdef HAVE_MPC_MPCDEC_H if (this->decoder) mpc_demux_exit(this->decoder); #endif free(this); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { mpc_decoder_t *this ; (void)class_gen; this = (mpc_decoder_t *) calloc(1, sizeof(mpc_decoder_t)); if (!this) return NULL; /* connect the member functions */ this->audio_decoder.decode_data = mpc_decode_data; this->audio_decoder.reset = mpc_reset; this->audio_decoder.discontinuity = mpc_discontinuity; this->audio_decoder.dispose = mpc_dispose; /* connect the stream */ this->stream = stream; /* audio output is not open at the start */ this->output_open = 0; /* no buffer yet */ this->buf = NULL; /* initialize the basic audio parameters */ this->channels = 0; this->sample_rate = 0; this->bits_per_sample = 0; /* return the newly-initialized audio decoder */ return &this->audio_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "mpc", .description = N_("mpc: musepack audio decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (void *)&this; } static const uint32_t audio_types[] = { BUF_AUDIO_MPC, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 5, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* { type, API version, "name", version, special_info, init_function }, */ { PLUGIN_AUDIO_DECODER, 16, "mpc", XINE_VERSION_CODE, &dec_info_audio, &init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/gsm610.c�����������������������������������������������������������������0000644�0001750�0001750�00000020751�14647725152�014555� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * GSM 6.10 Audio Decoder * This decoder is based on the GSM 6.10 codec library found at: * http://kbs.cs.tu-berlin.de/~jutta/toast.html * Additionally, here is an article regarding the software that appeared * in Dr. Dobbs Journal: * http://www.ddj.com/documents/s=1012/ddj9412b/9412b.htm * * This is the notice that comes with the software: * -------------------------------------------------------------------- * Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann, * Technische Universitaet Berlin * * Any use of this software is permitted provided that this notice is not * removed and that neither the authors nor the Technische Universitaet Berlin * are deemed to have made any representations as to the suitability of this * software for any purpose nor are held responsible for any defects of * this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. * * As a matter of courtesy, the authors request to be informed about uses * this software has found, about bugs in this software, and about any * improvements that may be of general interest. * * Berlin, 28.11.1994 * Jutta Degener * Carsten Bormann * -------------------------------------------------------------------- */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" #include "private.h" #include "gsm.h" #define AUDIOBUFSIZE 128*1024 #define GSM610_SAMPLE_SIZE 16 #define GSM610_BLOCK_SIZE 160 typedef struct gsm610_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; unsigned int buf_type; int output_open; int sample_rate; unsigned char *buf; int bufsize; int size; gsm gsm_state; } gsm610_decoder_t; /************************************************************************** * xine audio plugin functions *************************************************************************/ static void gsm610_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { gsm610_decoder_t *this = xine_container_of(this_gen, gsm610_decoder_t, audio_decoder); audio_buffer_t *audio_buffer; int in_ptr; if (buf->decoder_flags & BUF_FLAG_STDHEADER) { this->sample_rate = buf->decoder_info[1]; this->buf = calloc(1, AUDIOBUFSIZE); this->bufsize = AUDIOBUFSIZE; this->size = 0; /* stream/meta info */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "GSM 6.10"); return; } if (!this->output_open) { this->gsm_state = gsm_create(); this->buf_type = buf->type; this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, GSM610_SAMPLE_SIZE, this->sample_rate, AO_CAP_MODE_MONO); } /* if the audio still isn't open, bail */ if (!this->output_open) return; if( this->size + buf->size > this->bufsize ) { this->bufsize = this->size + 2 * buf->size; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "gsm610: increasing source buffer to %d to avoid overflow.\n", this->bufsize); this->buf = realloc( this->buf, this->bufsize ); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { /* time to decode a frame */ int16_t decode_buffer[GSM610_BLOCK_SIZE]; /* handle the Microsoft variant of GSM data */ if (this->buf_type == BUF_AUDIO_MSGSM) { this->gsm_state->wav_fmt = 1; /* the data should line up on a 65-byte boundary */ if ((buf->size % 65) != 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "gsm610: received MS GSM block that does not line up\n"); this->size = 0; return; } in_ptr = 0; while (this->size) { gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer); if ((in_ptr % 65) == 0) { in_ptr += 33; this->size -= 33; } else { in_ptr += 32; this->size -= 32; } /* dispatch the decoded audio; assume that the audio buffer will * always contain at least 160 samples */ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); xine_fast_memcpy(audio_buffer->mem, decode_buffer, GSM610_BLOCK_SIZE * 2); audio_buffer->num_frames = GSM610_BLOCK_SIZE; audio_buffer->vpts = buf->pts; buf->pts = 0; /* only first buffer gets the real pts */ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } } else { /* handle the other variant, which consists of 33-byte blocks */ this->gsm_state->wav_fmt = 0; /* the data should line up on a 33-byte boundary */ if ((buf->size % 33) != 0) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "gsm610: received GSM block that does not line up\n"); this->size = 0; return; } in_ptr = 0; while (this->size) { gsm_decode(this->gsm_state, &this->buf[in_ptr], decode_buffer); in_ptr += 33; this->size -= 33; /* dispatch the decoded audio; assume that the audio buffer will * always contain at least 160 samples */ audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); xine_fast_memcpy(audio_buffer->mem, decode_buffer, GSM610_BLOCK_SIZE * 2); audio_buffer->num_frames = GSM610_BLOCK_SIZE; audio_buffer->vpts = buf->pts; buf->pts = 0; /* only first buffer gets the real pts */ this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); } } } } static void gsm610_reset (audio_decoder_t *this_gen) { (void)this_gen; } static void gsm610_discontinuity (audio_decoder_t *this_gen) { (void)this_gen; } static void gsm610_dispose (audio_decoder_t *this_gen) { gsm610_decoder_t *this = xine_container_of(this_gen, gsm610_decoder_t, audio_decoder); if (this->gsm_state) gsm_destroy(this->gsm_state); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; _x_freep(&this->buf); free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { gsm610_decoder_t *this ; (void)class_gen; this = (gsm610_decoder_t *) calloc(1, sizeof(gsm610_decoder_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->output_open = 0; this->sample_rate = 0; this->buf = NULL; this->size = 0; #endif this->stream = stream; this->audio_decoder.decode_data = gsm610_decode_data; this->audio_decoder.reset = gsm610_reset; this->audio_decoder.discontinuity = gsm610_discontinuity; this->audio_decoder.dispose = gsm610_dispose; return &this->audio_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "GSM 6.10", .description = N_("GSM 6.10 audio decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (void *)&this; } static const uint32_t audio_types[] = { BUF_AUDIO_MSGSM, BUF_AUDIO_GSM610, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 9, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 16, "gsm610", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������xine-lib-1.2/src/audio_dec/xine_lpcm_decoder.c������������������������������������������������������0000644�0001750�0001750�00000030514�14647725152�017201� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /** * @file * @author James Courtier-Dutton <james@superbug.demon.co.uk> * * @date 2001-08-31 Added LPCM rate sensing */ #define _DEFAULT_SOURCE 1 #ifndef __sun #define _XOPEN_SOURCE 500 #endif /* avoid compiler warnings */ #define _BSD_SOURCE 1 #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> /* htons */ #endif #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #ifdef WIN32 #include <winsock.h> /*#include <Winsock2.h>*/ /* htons */ #endif typedef struct lpcm_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; uint32_t rate; uint32_t bits_per_sample; uint32_t number_of_channels; uint32_t ao_cap_mode; int output_open; int cpu_be; /* TRUE, if we're a Big endian CPU */ int64_t pts; uint8_t *buf; size_t buffered_bytes; size_t buf_size; } lpcm_decoder_t; static void lpcm_reset (audio_decoder_t *this_gen) { lpcm_decoder_t *this = xine_container_of(this_gen, lpcm_decoder_t, audio_decoder); _x_freep (&this->buf); } static void lpcm_discontinuity (audio_decoder_t *this_gen) { lpcm_reset(this_gen); } static void lpcm_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { lpcm_decoder_t *this = xine_container_of(this_gen, lpcm_decoder_t, audio_decoder); uint8_t *sample_buffer = buf->content; int buf_size = buf->size; int stream_be; audio_buffer_t *audio_buffer; int format_changed = 0; int special_dvd_audio = 0; /* Drop preview data */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; /* get config byte from mpeg2 stream */ if ( (buf->decoder_flags & BUF_FLAG_SPECIAL) && buf->decoder_info[1] == BUF_SPECIAL_LPCM_CONFIG ) { unsigned int bits_per_sample = 16; unsigned int sample_rate = 0; unsigned int num_channels; lprintf("lpcm_decoder: config data 0x%x\n", buf->decoder_info[2]); /* BluRay PCM header is 4 bytes */ if (buf->decoder_info[2] & 0xffffff00) { static const uint8_t channels[16] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0}; num_channels = channels[(buf->decoder_info[2] >> (16+4)) & 0x0f]; switch ((buf->decoder_info[2] >> (24+6)) & 0x03) { case 1: bits_per_sample = 16; break; case 2: /*bits_per_sample = 20; break;*/ /* fall thru. Samples are 0-padded to 24 bits, and * converted later to 16 bits by dropping 8 lowest bits. * this needs to be changed if audio out some day accepts 24bit samples. */ case 3: bits_per_sample = 24; break; default: bits_per_sample = 0; break; } switch ((buf->decoder_info[2] >> 16) & 0x0f) { case 1: sample_rate = 48000; break; case 4: sample_rate = 96000; break; case 5: sample_rate = 192000; break; default: sample_rate = 0; break; } if (!num_channels || !sample_rate || !bits_per_sample) xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: unsupported BluRay PCM format: 0x%08x\n", buf->decoder_info[2]); if (this->buffered_bytes) xine_log (this->stream->xine, XINE_LOG_MSG, "lpcm_decoder: %zd bytes lost !\n", this->buffered_bytes); if (!this->buf) { this->buffered_bytes = 0; this->buf_size = 8128; this->buf = malloc(this->buf_size); } } else { /* MPEG2/DVD PCM header is one byte */ num_channels = (buf->decoder_info[2] & 0x7) + 1; switch ((buf->decoder_info[2]>>4) & 3) { case 0: sample_rate = 48000; break; case 1: sample_rate = 96000; break; case 2: sample_rate = 44100; break; case 3: sample_rate = 32000; break; } switch ((buf->decoder_info[2]>>6) & 3) { case 0: bits_per_sample = 16; break; case 1: bits_per_sample = 20; break; case 2: bits_per_sample = 24; special_dvd_audio = 1; break; } } if( this->bits_per_sample != bits_per_sample || this->number_of_channels != num_channels || this->rate != sample_rate || !this->output_open ) { this->bits_per_sample = bits_per_sample; this->number_of_channels = num_channels; this->rate = sample_rate; format_changed++; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: format changed to %d channels, %d bits per sample, %d Hz, %d kbit/s\n", num_channels, bits_per_sample, sample_rate, (num_channels * sample_rate * bits_per_sample)/1024); } } if( buf->decoder_flags & BUF_FLAG_STDHEADER ) { this->rate=buf->decoder_info[1]; this->bits_per_sample=buf->decoder_info[2]; this->number_of_channels=buf->decoder_info[3]; format_changed++; } /* bail out if format was not regonized (avoid division by zero) */ if (!this->bits_per_sample || !this->number_of_channels || !this->rate) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: unregonized format, dropped %zu bytes\n", this->buffered_bytes); return; } /* * (re-)open output device */ if ( format_changed ) { if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->ao_cap_mode=_x_ao_channels2mode(this->number_of_channels); /* force 24-bit samples into 16 bits for now */ if (this->bits_per_sample == 24) this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->rate, this->ao_cap_mode) ; else this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, this->bits_per_sample, this->rate, this->ao_cap_mode) ; /* stream/meta info */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Linear PCM"); _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE, this->bits_per_sample * this->rate * this->number_of_channels); } if (!this->output_open || (buf->decoder_flags & BUF_FLAG_HEADER) ) return; if (buf->pts && !this->pts) this->pts = buf->pts; /* data accumulation */ if (this->buf) { int frame_end = buf->decoder_flags & BUF_FLAG_FRAME_END; if (this->buffered_bytes || !frame_end) { if (this->buf_size < this->buffered_bytes + buf->size) { while (this->buf_size < this->buffered_bytes + buf->size) this->buf_size *= 2; this->buf = realloc(this->buf, this->buf_size); } memcpy(this->buf + this->buffered_bytes, buf->content, buf->size); this->buffered_bytes += buf->size; if (!frame_end) return; sample_buffer = this->buf; buf_size = this->buffered_bytes; this->buffered_bytes = 0; } } audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); /* Swap LPCM samples into native byte order, if necessary */ buf->type &= 0xffff0000; stream_be = ( buf->type == BUF_AUDIO_LPCM_BE ); if( this->bits_per_sample == 16 ){ if (stream_be != this->cpu_be) swab (sample_buffer, audio_buffer->mem, buf_size); else memcpy (audio_buffer->mem, sample_buffer, buf_size); } else if( this->bits_per_sample == 20 ) { uint8_t *s = sample_buffer; uint8_t *d = (uint8_t *)audio_buffer->mem; int n = buf_size; if (stream_be != this->cpu_be) { while( n >= 0 ) { swab( s, d, 8 ); s += 10; d += 8; n -= 10; } } else { while( n >= 0 ) { memcpy( d, s, 8 ); s += 10; d += 8; n -= 10; } } } else if( this->bits_per_sample == 24 ) { uint8_t *s = sample_buffer; uint8_t *d = (uint8_t *)audio_buffer->mem; int n = buf_size; if ( stream_be ) { if (special_dvd_audio) while (n >= 12) { if ( stream_be == this->cpu_be ) { *d++ = s[0]; *d++ = s[1]; *d++ = s[2]; *d++ = s[3]; *d++ = s[4]; *d++ = s[5]; *d++ = s[6]; *d++ = s[7]; } else { *d++ = s[1]; *d++ = s[0]; *d++ = s[3]; *d++ = s[2]; *d++ = s[5]; *d++ = s[4]; *d++ = s[7]; *d++ = s[6]; } s += 12; n -= 12; } else while (n >= 3) { if ( stream_be == this->cpu_be ) { *d++ = s[0]; *d++ = s[1]; } else { *d++ = s[1]; *d++ = s[0]; } s += 3; n -= 3; } } else { while (n >= 3) { if ( stream_be == this->cpu_be ) { *d++ = s[1]; *d++ = s[2]; } else { *d++ = s[2]; *d++ = s[1]; } s += 3; n -= 3; } } if ( (d - (uint8_t*)audio_buffer->mem)/2*3 < buf_size ) xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "lpcm_decoder: lost %i bytes of %i in the buffer\n", (int)(buf_size - (d - (uint8_t*)audio_buffer->mem)/2*3), buf_size); } else { memcpy (audio_buffer->mem, sample_buffer, buf_size); } audio_buffer->vpts = this->pts; audio_buffer->num_frames = (((buf_size*8)/this->number_of_channels)/this->bits_per_sample); this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); this->pts = 0; } static void lpcm_dispose (audio_decoder_t *this_gen) { lpcm_decoder_t *this = xine_container_of(this_gen, lpcm_decoder_t, audio_decoder); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; _x_freep (&this->buf); free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { lpcm_decoder_t *this ; (void)class_gen; this = (lpcm_decoder_t *) calloc(1, sizeof(lpcm_decoder_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->output_open = 0; this->rate = 0; this->bits_per_sample = 0; this->number_of_channels = 0; this->ao_cap_mode = 0; #endif this->audio_decoder.decode_data = lpcm_decode_data; this->audio_decoder.reset = lpcm_reset; this->audio_decoder.discontinuity = lpcm_discontinuity; this->audio_decoder.dispose = lpcm_dispose; this->stream = stream; this->cpu_be = ( htons(1) == 1 ); return &this->audio_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "Linear PCM", .description = N_("Linear PCM audio decoder plugin"), .dispose = NULL }; (void)xine; (void)data; return (void *)&this; } static const uint32_t audio_types[] = { BUF_AUDIO_LPCM_BE, BUF_AUDIO_LPCM_LE, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER, 16, "pcm", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/audio_dec/xine_a52_spdif.c���������������������������������������������������������0000644�0001750�0001750�00000022513�14647725152�016335� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stuff needed to turn liba52 into a xine decoder plugin */ #define _DEFAULT_SOURCE 1 #ifndef __sun /* required for swab() */ #define _XOPEN_SOURCE 500 #endif /* avoid compiler warnings */ #define _BSD_SOURCE 1 #include "config.h" #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #define LOG_MODULE "a52_spdif" #define LOG_VERBOSE /* #define LOG #define LOG_PTS */ #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #define A52_MONO 1 #define A52_STEREO 2 #define A52_3F 3 #define A52_2F1R 4 #define A52_3F1R 5 #define A52_2F2R 6 #define A52_3F2R 7 #define A52_DOLBY 10 #define A52_CHANNEL_MASK 15 #define A52_LFE 16 struct frmsize_s { uint16_t bit_rate; uint16_t frm_size[3]; }; static const struct frmsize_s frmsizecod_tbl[64] = { { 32 ,{64 ,69 ,96 } }, { 32 ,{64 ,70 ,96 } }, { 40 ,{80 ,87 ,120 } }, { 40 ,{80 ,88 ,120 } }, { 48 ,{96 ,104 ,144 } }, { 48 ,{96 ,105 ,144 } }, { 56 ,{112 ,121 ,168 } }, { 56 ,{112 ,122 ,168 } }, { 64 ,{128 ,139 ,192 } }, { 64 ,{128 ,140 ,192 } }, { 80 ,{160 ,174 ,240 } }, { 80 ,{160 ,175 ,240 } }, { 96 ,{192 ,208 ,288 } }, { 96 ,{192 ,209 ,288 } }, { 112 ,{224 ,243 ,336 } }, { 112 ,{224 ,244 ,336 } }, { 128 ,{256 ,278 ,384 } }, { 128 ,{256 ,279 ,384 } }, { 160 ,{320 ,348 ,480 } }, { 160 ,{320 ,349 ,480 } }, { 192 ,{384 ,417 ,576 } }, { 192 ,{384 ,418 ,576 } }, { 224 ,{448 ,487 ,672 } }, { 224 ,{448 ,488 ,672 } }, { 256 ,{512 ,557 ,768 } }, { 256 ,{512 ,558 ,768 } }, { 320 ,{640 ,696 ,960 } }, { 320 ,{640 ,697 ,960 } }, { 384 ,{768 ,835 ,1152 } }, { 384 ,{768 ,836 ,1152 } }, { 448 ,{896 ,975 ,1344 } }, { 448 ,{896 ,976 ,1344 } }, { 512 ,{1024 ,1114 ,1536 } }, { 512 ,{1024 ,1115 ,1536 } }, { 576 ,{1152 ,1253 ,1728 } }, { 576 ,{1152 ,1254 ,1728 } }, { 640 ,{1280 ,1393 ,1920 } }, { 640 ,{1280 ,1394 ,1920 } } }; static int a52_syncinfo (uint8_t *buf, int *flags, int *sample_rate, int *bit_rate) { static const uint16_t rate[] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640}; static const uint8_t lfeon[8] = {0x10, 0x10, 0x04, 0x04, 0x04, 0x01, 0x04, 0x01}; static const uint8_t halfrate[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3}; int frmsizecod; int bitrate; int half; int acmod; if ((buf[0] != 0x0b) || (buf[1] != 0x77)) /* syncword */ return 0; if (buf[5] >= 0x60) /* bsid >= 12 */ return 0; half = halfrate[buf[5] >> 3]; /* acmod, dsurmod and lfeon */ acmod = buf[6] >> 5; *flags = ((((buf[6] & 0xf8) == 0x50) ? A52_DOLBY : acmod) | ((buf[6] & lfeon[acmod]) ? A52_LFE : 0)); frmsizecod = buf[4] & 63; if (frmsizecod >= 38) return 0; bitrate = rate [frmsizecod >> 1]; *bit_rate = (bitrate * 1000) >> half; switch (buf[4] & 0xc0) { case 0: *sample_rate = 48000 >> half; return 4 * bitrate; case 0x40: *sample_rate = 44100 >> half; return 2 * (320 * bitrate / 147 + (frmsizecod & 1)); case 0x80: *sample_rate = 32000 >> half; return 6 * bitrate; default: return 0; } } #include "xine_a52_parser.h" typedef struct a52dec_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; int64_t pts; int output_open; xine_a52_parser_t parser; } a52dec_decoder_t; static void a52dec_reset (audio_decoder_t *this_gen) { a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; xine_a52_parser_reset(&this->parser); this->pts = 0; } static void a52dec_discontinuity (audio_decoder_t *this_gen) { a52dec_reset(this_gen); } static void a52dec_decode_frame (a52dec_decoder_t *this, int64_t pts, int preview_mode) { #ifdef LOG_PTS printf("a52dec:decode_frame:pts=%lld\n",pts); #endif /* * loop through a52 data */ if (!this->output_open) { this->output_open = (this->stream->audio_out->open) (this->stream->audio_out, this->stream, 16, this->parser.a52_sample_rate, AO_CAP_MODE_A52); } if (this->output_open && !preview_mode) { /* SPDIF Passthrough * Build SPDIF Header and encaps the A52 audio data in it. */ uint32_t /*syncword, crc1,*/ fscod,frmsizecod,/*bsid,*/bsmod,frame_size; uint8_t *data_out,*data_in; audio_buffer_t *buf = this->stream->audio_out->get_buffer (this->stream->audio_out); data_in=(uint8_t *) this->parser.frame_buffer; data_out=(uint8_t *) buf->mem; /*syncword = data_in[0] | (data_in[1] << 8);*/ /*crc1 = data_in[2] | (data_in[3] << 8);*/ fscod = (data_in[4] >> 6) & 0x3; frmsizecod = data_in[4] & 0x3f; /*bsid = (data_in[5] >> 3) & 0x1f;*/ bsmod = data_in[5] & 0x7; /* bsmod, stream = 0 */ frame_size = frmsizecod_tbl[frmsizecod].frm_size[fscod] ; data_out[0] = 0x72; data_out[1] = 0xf8; /* spdif syncword */ data_out[2] = 0x1f; data_out[3] = 0x4e; /* .............. */ data_out[4] = 0x01; /* AC3 data */ data_out[5] = bsmod; /* bsmod, stream = 0 */ data_out[6] = (frame_size << 4) & 0xff; /* frame_size * 16 */ data_out[7] = ((frame_size ) >> 4) & 0xff; swab(data_in, &data_out[8], frame_size * 2 ); buf->num_frames = 1536; buf->vpts = pts; this->stream->audio_out->put_buffer (this->stream->audio_out, buf, this->stream); } } static void a52dec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; if (buf->decoder_flags & BUF_FLAG_HEADER) return; /* swap byte pairs if this is RealAudio DNET data */ if (buf->type == BUF_AUDIO_DNET) { do_swab(buf->content, buf->content + buf->size); } if (buf->pts) { this->pts = buf->pts; } while (buf->size > 0) { int consumed = xine_a52_parse_data(&this->parser, this->stream, buf->content, buf->size); buf->content += consumed; buf->size -= consumed; if (this->parser.got_frame) { a52dec_decode_frame (this, this->pts, buf->decoder_flags & BUF_FLAG_PREVIEW); this->pts = 0; } } } static void a52dec_dispose (audio_decoder_t *this_gen) { a52dec_decoder_t *this = (a52dec_decoder_t *) this_gen; if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); this->output_open = 0; free (this_gen); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { a52dec_decoder_t *this; (void)class_gen; lprintf ("open_plugin called\n"); /* * find out if this driver supports a52 output * if not, bail out early. */ if (!(stream->audio_out->get_capabilities (stream->audio_out) & AO_CAP_MODE_A52)) return (audio_decoder_t *)1; this = calloc(1, sizeof (a52dec_decoder_t)); if (!this) return NULL; xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "a52: Using a52 bitstream output (spdif)\n"); /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ xine_a52_parser_reset(&this->parser); this->output_open = 0; this->audio_decoder.decode_data = a52dec_decode_data; this->audio_decoder.reset = a52dec_reset; this->audio_decoder.discontinuity = a52dec_discontinuity; this->audio_decoder.dispose = a52dec_dispose; this->stream = stream; return &this->audio_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const audio_decoder_class_t decoder_class = { .open_plugin = open_plugin, .identifier = "a/52dec_spdif", .description = N_("liba52 based a52 audio decoder plugin for SPDIF output"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&decoder_class; } static const uint32_t audio_types[] = { BUF_AUDIO_A52, BUF_AUDIO_DNET, 0 }; static const decoder_info_t dec_info_audio = { .supported_types = audio_types, .priority = 20, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 16, "a/52_spdif", XINE_VERSION_CODE, &dec_info_audio, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013374� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/foovideo.c���������������������������������������������������������������0000644�0001750�0001750�00000021305�14647725152�015353� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * foovideo.c: This is a reference video decoder for the xine multimedia * player. It really works too! It will output frames of packed YUY2 data * where each byte in the map is the same value, which is 3 larger than the * value from the last frame. This creates a slowly rotating solid color * frame when the frames are played in succession. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" #define VIDEOBUFSIZE 128*1024 typedef struct { video_decoder_class_t decoder_class; } foovideo_class_t; typedef struct foovideo_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ foovideo_class_t *class; xine_stream_t *stream; /* these are traditional variables in a video decoder object */ uint64_t video_step; /* frame duration in pts units */ int decoder_ok; /* current decoder status */ int skipframes; unsigned char *buf; /* the accumulated buffer data */ int bufsize; /* the maximum size of buf */ int size; /* the current size of buf */ int width; /* the width of a video frame */ int height; /* the height of a video frame */ double ratio; /* the width to height ratio */ /* these are variables exclusive to the foo video decoder */ unsigned char current_yuv_byte; } foovideo_decoder_t; /************************************************************************** * foovideo specific decode functions *************************************************************************/ /************************************************************************** * xine video plugin functions *************************************************************************/ /* * This function receives a buffer of data from the demuxer layer and * figures out how to handle it based on its header flags. */ static void foovideo_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; xine_bmiheader *bih; vo_frame_t *img; /* video out frame */ /* a video decoder does not care about this flag (?) */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { this->video_step = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ (this->stream->video_out->open) (this->stream->video_out, this->stream); free(this->buf); bih = (xine_bmiheader *) buf->content; this->width = bih->biWidth; this->height = bih->biHeight; this->ratio = (double)this->width/(double)this->height; if (this->buf) free (this->buf); this->bufsize = VIDEOBUFSIZE; this->buf = malloc(this->bufsize); this->size = 0; /* take this opportunity to load the stream/meta info */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "foovideo"); /* do anything else relating to initializing this decoder */ this->current_yuv_byte = 0; this->decoder_ok = 1; return; } else if (this->decoder_ok) { if (this->size + buf->size > this->bufsize) { this->bufsize = this->size + 2 * buf->size; this->buf = realloc (this->buf, this->bufsize); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); if (!img) { this->size = 0; return; } img->duration = this->video_step; img->pts = buf->pts; img->bad_frame = 0; memset(img->base[0], this->current_yuv_byte, this->width * this->height * 2); this->current_yuv_byte += 3; img->draw(img, this->stream); img->free(img); this->size = 0; } } } /* * This function is called when xine needs to flush the system. */ static void foovideo_flush (video_decoder_t *this_gen) { } /* * This function resets the video decoder. */ static void foovideo_reset (video_decoder_t *this_gen) { foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; this->size = 0; } /* * The decoder should forget any stored pts values here. */ static void foovideo_discontinuity (video_decoder_t *this_gen) { foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; } /* * This function frees the video decoder instance allocated to the decoder. */ static void foovideo_dispose (video_decoder_t *this_gen) { foovideo_decoder_t *this = (foovideo_decoder_t *) this_gen; free (this->buf); if (this->decoder_ok) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this_gen); } /* * This function allocates, initializes, and returns a private video * decoder structure. */ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { foovideo_decoder_t *this ; this = (foovideo_decoder_t *) calloc(1, sizeof(foovideo_decoder_t)); this->video_decoder.decode_data = foovideo_decode_data; this->video_decoder.flush = foovideo_flush; this->video_decoder.reset = foovideo_reset; this->video_decoder.discontinuity = foovideo_discontinuity; this->video_decoder.dispose = foovideo_dispose; this->size = 0; this->stream = stream; this->class = (foovideo_class_t *) class_gen; this->decoder_ok = 0; this->buf = NULL; return &this->video_decoder; } /* * This function frees the video decoder class and any other memory that was * allocated. */ static void dispose_class (video_decoder_class_t *this) { free (this); } /* * This function allocates a private video decoder class and initializes * the class's member functions. */ static void *init_plugin (xine_t *xine, const void *data) { foovideo_class_t *this; this = (foovideo_class_t *) calloc(1, sizeof(foovideo_class_t)); this->decoder_class.open_plugin = open_plugin; this->decoder_class.identifier = "foovideo"; this->decoder_class.description = N_("foovideo: reference xine video decoder plugin"); this->decoder_class.dispose = dispose_class; return this; } /* * This is a list of all of the internal xine video buffer types that * this decoder is able to handle. Check src/xine-engine/buffer.h for a * list of valid buffer types (and add a new one if the one you need does * not exist). Terminate the list with a 0. */ static const uint32_t video_types[] = { /* BUF_VIDEO_FOOVIDEO, */ BUF_VIDEO_VQA, BUF_VIDEO_SORENSON_V3, 0 }; /* * This data structure combines the list of supported xine buffer types and * the priority that the plugin should be given with respect to other * plugins that handle the same buffer type. A plugin with priority (n+1) * will be used instead of a plugin with priority (n). */ static const decoder_info_t dec_info_video = { .supported_types = video_types, .priority = 5, }; /* * The plugin catalog entry. This is the only information that this plugin * will export to the public. */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* { type, API, "name", version, special_info, init_function } */ { PLUGIN_VIDEO_DECODER, 19, "foovideo", XINE_VERSION_CODE, &dec_info_video, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/rgb.c��������������������������������������������������������������������0000644�0001750�0001750�00000022116�14647725152�014314� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Raw RGB "Decoder" by Mike Melanson (melanson@pcisys.net) * Actually, this decoder just converts a raw RGB image to a YUY2 map * suitable for display under xine. * * This decoder deals with raw RGB data from Microsoft and Quicktime files. * Data from a MS file can be 32-, 24-, 16-, or 8-bit. The latter can also * be grayscale, depending on whether a palette is present. Data from a QT * file can be 32-, 24-, 16-, 8-, 4-, 2-, or 1-bit. Any resolutions <= 8 * can also be greyscale depending on what the QT file specifies. * * One more catch: Raw RGB from a Microsoft file is upside down. This is * indicated by a negative height parameter. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #define LOG_MODULE "rgb" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "group_raw.h" typedef struct rgb_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; /* these are traditional variables in a video decoder object */ uint64_t video_step; /* frame duration in pts units */ int decoder_ok; /* current decoder status */ int skipframes; unsigned char *buf; /* the accumulated buffer data */ int bufsize; /* the maximum size of buf */ int size; /* the current size of buf */ int width; /* the width of a video frame */ int height; /* the height of a video frame */ double ratio; /* the width to height ratio */ int bytes_per_pixel; int bit_depth; int upside_down; int palette_loaded; int color_matrix; const char *fmtstring; rgb2yuy2_t *rgb2yuy2; } rgb_decoder_t; static void rgb_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { rgb_decoder_t *this = (rgb_decoder_t *) this_gen; xine_bmiheader *bih; vo_frame_t *img; /* video out frame */ /* a video decoder does not care about this flag (?) */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { rgb2yuy2_palette (this->rgb2yuy2, buf->decoder_info_ptr[2], buf->decoder_info[2], this->bit_depth); this->palette_loaded = 1; } if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { this->video_step = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ (this->stream->video_out->open) (this->stream->video_out, this->stream); bih = (xine_bmiheader *) buf->content; this->width = bih->biWidth; this->height = bih->biHeight; if (this->height < 0) { this->upside_down = 1; this->height = -this->height; } else { this->upside_down = 0; } this->ratio = (double)this->width/(double)this->height; this->bit_depth = bih->biBitCount; if (this->bit_depth > 32) this->bit_depth &= 0x1F; /* round this number up in case of 15 */ lprintf("width = %d, height = %d, bit_depth = %d\n", this->width, this->height, this->bit_depth); this->bytes_per_pixel = (this->bit_depth + 1) / 8; (this->stream->video_out->open) (this->stream->video_out, this->stream); if (this->bit_depth <= 8) { this->fmtstring = "rgb"; /* see palette_entry_t */ } else if (this->upside_down) { this->fmtstring = this->bytes_per_pixel == 2 ? "rgb555le" : this->bytes_per_pixel == 3 ? "bgr" : "bgra"; } else { this->fmtstring = this->bytes_per_pixel == 2 ? "rgb555be" : this->bytes_per_pixel == 3 ? "rgb" : "rgba"; } this->color_matrix = this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_FULLRANGE ? 11 : 10; rgb2yuy2_free (this->rgb2yuy2); this->rgb2yuy2 = rgb2yuy2_alloc (this->color_matrix, this->fmtstring); free (this->buf); /* minimal buffer size */ this->bufsize = this->width * this->height * this->bytes_per_pixel; this->buf = calloc(1, this->bufsize); this->size = 0; this->decoder_ok = 1; /* load the stream/meta info */ _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw RGB"); return; } else if (this->decoder_ok) { if (this->size + buf->size > this->bufsize) { this->bufsize = this->size + 2 * buf->size; this->buf = realloc (this->buf, this->bufsize); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { int flags = VO_BOTH_FIELDS; VO_SET_FLAGS_CM (this->color_matrix, flags); img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_YUY2, flags | VO_GET_FRAME_MAY_FAIL); if (!img) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame(%dx%d) failed\n", this->width, this->height); this->size = 0; return; } img->duration = this->video_step; img->pts = buf->pts; img->bad_frame = 0; if ((this->bit_depth <= 8) && !this->palette_loaded) { rgb2yuy2_palette (this->rgb2yuy2, NULL, 1 << this->bit_depth, this->bit_depth); this->palette_loaded = 1; } /* crop if allocated frame is smaller than requested */ int width = this->width, height = this->height; if (width > img->width) width = img->width; if (height > img->height) height = img->height; if (this->upside_down) { rgb2yuy2_slice ( this->rgb2yuy2, this->buf + (this->height - 1) * this->width, -this->width, img->base[0], img->pitches[0], width, height); } else { rgb2yuy2_slice ( this->rgb2yuy2, this->buf, this->width, img->base[0], img->pitches[0], width, height); } img->draw(img, this->stream); img->free(img); this->size = 0; } } } /* * This function is called when xine needs to flush the system. Not * sure when or if this is used or even if it needs to do anything. */ static void rgb_flush (video_decoder_t *this_gen) { (void)this_gen; } /* * This function resets the video decoder. */ static void rgb_reset (video_decoder_t *this_gen) { rgb_decoder_t *this = (rgb_decoder_t *) this_gen; this->size = 0; } static void rgb_discontinuity (video_decoder_t *this_gen) { (void)this_gen; } /* * This function frees the video decoder instance allocated to the decoder. */ static void rgb_dispose (video_decoder_t *this_gen) { rgb_decoder_t *this = (rgb_decoder_t *) this_gen; free (this->buf); rgb2yuy2_free (this->rgb2yuy2); if (this->decoder_ok) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this_gen); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { rgb_decoder_t *this ; (void)class_gen; this = (rgb_decoder_t *) calloc(1, sizeof(rgb_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = rgb_decode_data; this->video_decoder.flush = rgb_flush; this->video_decoder.reset = rgb_reset; this->video_decoder.discontinuity = rgb_discontinuity; this->video_decoder.dispose = rgb_dispose; this->size = 0; this->stream = stream; this->decoder_ok = 0; this->buf = NULL; return &this->video_decoder; } void *decode_rgb_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_rgb_class = { .open_plugin = open_plugin, .identifier = "RGB", .description = N_("Raw RGB video decoder plugin"), .dispose = NULL, }; return (void *)&decode_video_rgb_class; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/yuv.c��������������������������������������������������������������������0000644�0001750�0001750�00000025624�14647725152�014374� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * YUV "Decoder" by Mike Melanson (melanson@pcisys.net) * Actually, this decoder just reorganizes chunks of raw YUV data in such * a way that xine can display them. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" #include "group_raw.h" #define VIDEOBUFSIZE 128*1024 typedef struct yuv_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; /* these are traditional variables in a video decoder object */ uint64_t video_step; /* frame duration in pts units */ int decoder_ok; /* current decoder status */ int skipframes; unsigned char *buf; /* the accumulated buffer data */ int bufsize; /* the maximum size of buf */ int size; /* the current size of buf */ int width; /* the width of a video frame */ int height; /* the height of a video frame */ double ratio; /* the width to height ratio */ int progressive; int top_field_first; int color_matrix; } yuv_decoder_t; /************************************************************************** * xine video plugin functions *************************************************************************/ /* * This function receives a buffer of data from the demuxer layer and * figures out how to handle it based on its header flags. */ static void yuv_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { yuv_decoder_t *this = (yuv_decoder_t *) this_gen; xine_bmiheader *bih; vo_frame_t *img; /* video out frame */ /* a video decoder does not care about this flag (?) */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { this->video_step = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ (this->stream->video_out->open) (this->stream->video_out, this->stream); bih = (xine_bmiheader *) buf->content; this->width = bih->biWidth; this->height = bih->biHeight; if (buf->decoder_flags & BUF_FLAG_ASPECT) this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; else this->ratio = (double)this->width / (double)this->height; this->progressive = buf->decoder_info[3]; this->top_field_first = buf->decoder_info[4]; this->color_matrix = 4; /* undefined, mpeg range */ free (this->buf); this->buf = NULL; this->bufsize = 0; this->size = 0; this->decoder_ok = 1; /* load the stream/meta info */ switch (buf->type) { case BUF_VIDEO_YUY2: this->width = (this->width + 1) & ~1; this->bufsize = this->width * this->height * 2; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YUY2"); break; case BUF_VIDEO_YV12: this->width = (this->width + 1) & ~1; this->height = (this->height + 1) & ~1; this->bufsize = this->width * this->height * 3 / 2; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YV12"); break; case BUF_VIDEO_YVU9: this->width = (this->width + 3) & ~3; this->height = (this->height + 3) & ~3; this->bufsize = this->width * this->height * 9 / 8; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw YVU9"); break; case BUF_VIDEO_GREY: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Greyscale YUV"); break; case BUF_VIDEO_I420: this->width = (this->width + 1) & ~1; this->height = (this->height + 1) & ~1; this->bufsize = this->width * this->height * 3 / 2; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Raw I420"); break; } this->buf = malloc(this->bufsize); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); return; } else if (this->decoder_ok && !(buf->decoder_flags & BUF_FLAG_SPECIAL)) { uint8_t *src; /* if buffer contains an entire frame then there's no need to copy it * into our internal buffer */ if ((buf->decoder_flags & BUF_FLAG_FRAME_START) && (buf->decoder_flags & BUF_FLAG_FRAME_END)) src = buf->content; else { if (this->size + buf->size > this->bufsize) { this->bufsize = this->size + 2 * buf->size; this->buf = realloc (this->buf, this->bufsize); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; src = this->buf; } if (buf->decoder_flags & BUF_FLAG_COLOR_MATRIX) this->color_matrix = buf->decoder_info[4]; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { int format; if (buf->type == BUF_VIDEO_YUY2) { format = XINE_IMGFMT_YUY2; } else { format = XINE_IMGFMT_YV12; } img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, format, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL); if (!img) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame(%dx%d) failed\n", this->width, this->height); this->size = 0; return; } if (buf->type == BUF_VIDEO_YUY2) { yuy2_to_yuy2( /* src */ src, this->width*2, /* dst */ img->base[0], img->pitches[0], /* width x height */ this->width, this->height); } else if (buf->type == BUF_VIDEO_YV12) { yv12_to_yv12( /* Y */ src, this->width, img->base[0], img->pitches[0], /* U */ src + (this->width * this->height * 5/4), this->width/2, img->base[1], img->pitches[1], /* V */ src + (this->width * this->height), this->width/2, img->base[2], img->pitches[2], /* width x height */ this->width, this->height); } else if (buf->type == BUF_VIDEO_I420) { yv12_to_yv12( /* Y */ src, this->width, img->base[0], img->pitches[0], /* U */ src + (this->width * this->height), this->width/2, img->base[1], img->pitches[1], /* V */ src + (this->width * this->height * 5/4), this->width/2, img->base[2], img->pitches[2], /* width x height */ this->width, this->height); } else if (buf->type == BUF_VIDEO_YVU9) { yuv9_to_yv12( /* Y */ src, this->width, img->base[0], img->pitches[0], /* U */ src + (this->width * this->height), this->width / 4, img->base[1], img->pitches[1], /* V */ src + (this->width * this->height) + (this->width * this->height / 16), this->width / 4, img->base[2], img->pitches[2], /* width x height */ this->width, this->height); } else if (buf->type == BUF_VIDEO_GREY) { xine_fast_memcpy(img->base[0], src, this->width * this->height); memset( img->base[1], 0x80, this->width * this->height / 4 ); memset( img->base[2], 0x80, this->width * this->height / 4 ); } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": unsupported format 0x%x\n", buf->type); } VO_SET_FLAGS_CM (this->color_matrix, img->flags); img->duration = this->video_step; img->pts = buf->pts; img->bad_frame = 0; img->draw(img, this->stream); img->free(img); this->size = 0; } } } /* * This function is called when xine needs to flush the system. Not * sure when or if this is used or even if it needs to do anything. */ static void yuv_flush (video_decoder_t *this_gen) { (void)this_gen; } /* * This function resets the video decoder. */ static void yuv_reset (video_decoder_t *this_gen) { yuv_decoder_t *this = (yuv_decoder_t *) this_gen; this->size = 0; } static void yuv_discontinuity (video_decoder_t *this_gen) { (void)this_gen; } /* * This function frees the video decoder instance allocated to the decoder. */ static void yuv_dispose (video_decoder_t *this_gen) { yuv_decoder_t *this = (yuv_decoder_t *) this_gen; free (this->buf); if (this->decoder_ok) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this_gen); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { yuv_decoder_t *this ; (void)class_gen; this = (yuv_decoder_t *) calloc(1, sizeof(yuv_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = yuv_decode_data; this->video_decoder.flush = yuv_flush; this->video_decoder.reset = yuv_reset; this->video_decoder.discontinuity = yuv_discontinuity; this->video_decoder.dispose = yuv_dispose; this->size = 0; this->stream = stream; this->decoder_ok = 0; this->buf = NULL; return &this->video_decoder; } void *decode_yuv_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_yuv_class = { .open_plugin = open_plugin, .identifier = "YUV", .description = N_("Raw YUV video decoder plugin"), .dispose = NULL, }; return (void *)&decode_video_yuv_class; } ������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/Makefile.am��������������������������������������������������������������0000644�0001750�0001750�00000012632�14647725152�015434� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AUTOMAKE_OPTIONS = subdir-objects include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) EXTRA_DIST = foovideo.c xineplug_LTLIBRARIES = if ENABLE_IMAGEMAGICK xineplug_LTLIBRARIES += xineplug_decode_image.la endif if ENABLE_GDK_PIXBUF xineplug_LTLIBRARIES += xineplug_decode_gdk_pixbuf.la endif if ENABLE_DAV1D xineplug_LTLIBRARIES += xineplug_decode_dav1d.la endif if ENABLE_LIBAOM xineplug_LTLIBRARIES += xineplug_decode_libaom.la endif if ENABLE_LIBJPEG xineplug_LTLIBRARIES += xineplug_decode_libjpeg.la endif if ENABLE_LIBPNG xineplug_LTLIBRARIES += xineplug_decode_libpng.la endif if ENABLE_OPENHEVC xineplug_LTLIBRARIES += xineplug_decode_libopenhevc.la endif if ENABLE_VPX xineplug_LTLIBRARIES += xineplug_decode_libvpx.la endif if ENABLE_MMAL xineplug_LTLIBRARIES += xineplug_decode_libmmal.la endif if ENABLE_VDPAU xineplug_LTLIBRARIES += xineplug_decode_vdpau.la endif if ENABLE_RAWVIDEO xineplug_LTLIBRARIES += xineplug_decode_rawvideo.la endif if ENABLE_LIBMPEG2 xineplug_LTLIBRARIES += xineplug_decode_mpeg2.la endif if ENABLE_MPEG2NEW xineplug_LTLIBRARIES += xineplug_decode_mpeg2new.la endif xineplug_decode_rawvideo_la_SOURCES = \ group_raw.c \ group_raw.h \ bitplane.c \ rgb.c \ yuv.c xineplug_decode_rawvideo_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_decode_image_la_SOURCES = image.c xineplug_decode_image_la_LIBADD = $(XINE_LIB) $(WAND_LIBS) xineplug_decode_image_la_CFLAGS = $(AM_CFLAGS) $(WAND_CFLAGS) xineplug_decode_gdk_pixbuf_la_SOURCES = gdkpixbuf.c xineplug_decode_gdk_pixbuf_la_LIBADD = $(XINE_LIB) $(GDK_PIXBUF_LIBS) xineplug_decode_gdk_pixbuf_la_CFLAGS = $(AM_CFLAGS) $(GDK_PIXBUF_CFLAGS) xineplug_decode_libjpeg_la_SOURCES = libjpeg.c xineplug_decode_libjpeg_la_LIBADD = $(XINE_LIB) $(JPEG_LIBS) $(LTLIBINTL) xineplug_decode_libjpeg_la_CFLAGS = $(AM_CFLAGS) $(JPEG_CFLAGS) xineplug_decode_libpng_la_SOURCES = libpng.c xineplug_decode_libpng_la_LIBADD = $(XINE_LIB) $(LIBPNG_LIBS) $(LTLIBINTL) xineplug_decode_libpng_la_CFLAGS = $(AM_CFLAGS) $(LIBPNG_CFLAGS) xineplug_decode_libopenhevc_la_SOURCES = libopenhevc.c xineplug_decode_libopenhevc_la_LIBADD = $(XINE_LIB) $(OPENHEVC_LIBS) -lm xineplug_decode_libopenhevc_la_CFLAGS = $(AM_CFLAGS) $(OPENHEVC_CFLAGS) xineplug_decode_libopenhevc_la_LDFLAGS = $(AM_LDFLAGS) -Wl,-Bsymbolic xineplug_decode_libvpx_la_SOURCES = libvpx.c xineplug_decode_libvpx_la_LIBADD = $(XINE_LIB) $(VPX_LIBS) xineplug_decode_libvpx_la_CFLAGS = $(AM_CFLAGS) $(VPX_CFLAGS) xineplug_decode_libaom_la_SOURCES = libaom.c xineplug_decode_libaom_la_LIBADD = $(XINE_LIB) $(AOM_LIBS) xineplug_decode_libaom_la_CFLAGS = $(AM_CFLAGS) $(AOM_CFLAGS) xineplug_decode_dav1d_la_SOURCES = dav1d.c xineplug_decode_dav1d_la_LIBADD = $(XINE_LIB) $(DAV1D_LIBS) xineplug_decode_dav1d_la_CFLAGS = $(AM_CFLAGS) $(DAV1D_CFLAGS) xineplug_decode_libmmal_la_SOURCES = mmal.c xineplug_decode_libmmal_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(MMAL_LIBS) xineplug_decode_libmmal_la_CFLAGS = $(AM_CFLAGS) $(MMAL_CFLAGS) xineplug_decode_libmmal_la_LDFLAGS = $(AM_LDFLAGS) $(MMAL_LDFLAGS) xineplug_decode_vdpau_la_SOURCES = \ libvdpau/group_vdpau.c \ libvdpau/group_vdpau.h \ libvdpau/vdec_hw_bits_reader.h \ libvdpau/vdec_hw_h264.h \ libvdpau/vdec_hw_h264.c \ libvdpau/alterh264_decode.c \ libvdpau/bits_reader.h \ libvdpau/vdpau_h264.c \ libvdpau/vdpau_mpeg12.c \ libvdpau/vdpau_vc1.c \ libvdpau/vdpau_mpeg4.c xineplug_decode_vdpau_la_CFLAGS = $(AM_CFLAGS) $(VDPAU_CFLAGS) -D_ISOC99_SOURCE xineplug_decode_vdpau_la_LIBADD = $(XINE_LIB) -lm xineplug_decode_mpeg2_la_SOURCES = \ libmpeg2/cpu_state.c \ libmpeg2/decode.c \ libmpeg2/header.c \ libmpeg2/idct.c \ libmpeg2/idct_altivec.c \ libmpeg2/idct_mlib.h \ libmpeg2/idct_mlib.c \ libmpeg2/idct_mmx.c \ libmpeg2/motion_comp.c \ libmpeg2/motion_comp_altivec.c \ libmpeg2/motion_comp_mmx.c \ libmpeg2/motion_comp_mlib.c \ libmpeg2/motion_comp_vis.c \ libmpeg2/mpeg2.h \ libmpeg2/mpeg2_internal.h \ libmpeg2/slice.c \ libmpeg2/slice_xvmc.c \ libmpeg2/slice_xvmc_vld.c \ libmpeg2/stats.c \ libmpeg2/vis.h \ libmpeg2/vlc.h \ libmpeg2/xine_mpeg2_decoder.c \ libmpeg2/xvmc.h \ libmpeg2/xvmc_vld.h \ libmpeg2/libmpeg2_accel.h \ libmpeg2/libmpeg2_accel.c xineplug_decode_mpeg2_la_LIBADD = $(XINE_LIB) $(MLIB_LIBS) $(LTLIBINTL) -lm xineplug_decode_mpeg2_la_CFLAGS = $(AM_CFLAGS) $(MLIB_CFLAGS) xineplug_decode_mpeg2new_la_SOURCES = \ libmpeg2new/xine_mpeg2new_decoder.c \ \ libmpeg2new/include/attributes.h \ libmpeg2new/include/video_out.h \ libmpeg2new/include/mpeg2.h \ libmpeg2new/include/mpeg2convert.h \ libmpeg2new/libmpeg2/alloc.c \ libmpeg2new/libmpeg2/decode.c \ libmpeg2new/libmpeg2/header.c \ libmpeg2new/libmpeg2/idct.c \ libmpeg2new/libmpeg2/motion_comp.c \ libmpeg2new/libmpeg2/mpeg2_internal.h \ libmpeg2new/libmpeg2/slice.c \ libmpeg2new/libmpeg2/vlc.h \ \ libmpeg2new/include/alpha_asm.h \ libmpeg2new/include/mmx.h \ libmpeg2new/include/tendra.h \ libmpeg2new/include/vis.h \ libmpeg2new/libmpeg2/motion_comp_mmx.c \ libmpeg2new/libmpeg2/idct_mmx.c \ libmpeg2new/libmpeg2/motion_comp_altivec.c \ libmpeg2new/libmpeg2/idct_altivec.c \ libmpeg2new/libmpeg2/motion_comp_alpha.c \ libmpeg2new/libmpeg2/idct_alpha.c \ libmpeg2new/libmpeg2/motion_comp_vis.c \ libmpeg2new/libmpeg2/cpu_accel.c \ libmpeg2new/libmpeg2/cpu_state.c xineplug_decode_mpeg2new_la_LIBADD = $(XINE_LIB) xineplug_decode_mpeg2new_la_CFLAGS = $(AM_CFLAGS) $(MLIB_CFLAGS) ������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libjpeg.c����������������������������������������������������������������0000644�0001750�0001750�00000036540�14647725152�015164� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2003-2021 the xine project * Copyright (C) 2012 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Fast JPEG image decoder using libjpeg */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #define LOG_MODULE "jpeg_video_decoder" #define LOG_VERBOSE /* #define LOG */ #include <jpeglib.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xine_buffer.h> typedef struct jpeg_decoder_s { video_decoder_t video_decoder; xine_stream_t *stream; int64_t pts; vo_frame_t *vo_frame; unsigned char *image; int index; int enable_downscaling; int video_open; } jpeg_decoder_t; /* * memory source */ METHODDEF(void) mem_init_source (j_decompress_ptr cinfo) { (void)cinfo; } METHODDEF(boolean) mem_fill_input_buffer (j_decompress_ptr cinfo) { static const JOCTET EOI[] = { 0xFF, JPEG_EOI }; cinfo->src->next_input_byte = EOI; cinfo->src->bytes_in_buffer = 2; return TRUE; } METHODDEF(void) mem_skip_input_data (j_decompress_ptr cinfo, long num_bytes) { if (num_bytes <= (int)cinfo->src->bytes_in_buffer) { cinfo->src->bytes_in_buffer -= num_bytes; cinfo->src->next_input_byte += num_bytes; } else { mem_fill_input_buffer(cinfo); } } METHODDEF(void) mem_term_source (j_decompress_ptr cinfo) { (void)cinfo; } static void jpeg_memory_src (j_decompress_ptr cinfo, const JOCTET *data, size_t size) { if (!cinfo->src) { cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr)); } cinfo->src->init_source = mem_init_source; cinfo->src->fill_input_buffer = mem_fill_input_buffer; cinfo->src->skip_input_data = mem_skip_input_data; cinfo->src->resync_to_restart = jpeg_resync_to_restart; cinfo->src->term_source = mem_term_source; cinfo->src->bytes_in_buffer = size; cinfo->src->next_input_byte = data; } /* * xine-lib decoder interface */ static vo_frame_t *_jpeg_decode_data (jpeg_decoder_t *this, const char *data, size_t size) { vo_frame_t *f = NULL; if (!this->video_open) { lprintf("opening video\n"); (this->stream->video_out->open) (this->stream->video_out, this->stream); this->video_open = 1; } if (size > 0) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; JSAMPARRAY buffer; int i, linesize; int width, height; int max_width, max_height; uint8_t *slice_start[3] = {NULL, NULL, NULL}; int slice_line = 0; int fullrange; uint8_t ytab[256], ctab[256]; int frame_flags = VO_BOTH_FIELDS; int format; /* query max. image size vo can handle */ max_width = this->stream->video_out->get_property( this->stream->video_out, VO_PROP_MAX_VIDEO_WIDTH); max_height = this->stream->video_out->get_property( this->stream->video_out, VO_PROP_MAX_VIDEO_HEIGHT); /* init and parse header */ cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); jpeg_memory_src (&cinfo, data, size); jpeg_read_header(&cinfo, TRUE); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, cinfo.image_width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, cinfo.image_height); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "JPEG"); lprintf("header parsed\n"); /* set decoding parameters */ cinfo.out_color_space = JCS_YCbCr; /* request scaling when image is too large for vo */ if (this->enable_downscaling) { cinfo.output_width = cinfo.image_width; cinfo.output_height = cinfo.image_height; cinfo.scale_num = 1; cinfo.scale_denom = 1; while ((max_width > 0 && (int)cinfo.output_width > max_width) || (max_height > 0 && (int)cinfo.output_height > max_height)) { cinfo.scale_denom <<= 1; cinfo.output_width >>= 1; cinfo.output_height >>= 1; } if (cinfo.scale_denom > 1) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": downscaling image by 1:%d to %dx%d\n", cinfo.scale_denom, cinfo.output_width, cinfo.output_height); } } /* start decompress */ jpeg_start_decompress(&cinfo); width = cinfo.output_width; height = cinfo.output_height; /* crop when image is too large for vo */ if (max_width > 0 && (int)cinfo.output_width > max_width) width = max_width; if (max_height > 0 && (int)cinfo.output_height > max_height) height = max_height; /* TJ. As far as I know JPEG always uses fullrange ITU-R 601 YUV. Let vo handle it (fast, good quality) or shrink to mpeg range here. In any case, set cm flags _before_ calling proc_slice (). */ fullrange = !!(this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_FULLRANGE); if (fullrange) { VO_SET_FLAGS_CM (11, frame_flags); } else { unsigned int i; for (i = 0; i < 256; i++) { ytab[i] = (219 * i + 16 * 255 + 127) / 255; ctab[i] = (112 * i + (127 - 112) * 128 + 63) / 127; } VO_SET_FLAGS_CM (10, frame_flags); } format = (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_YUY2) ? XINE_IMGFMT_YUY2 : XINE_IMGFMT_YV12; f = this->stream->video_out->get_frame (this->stream->video_out, width, height, (double)width/(double)height, format, frame_flags | VO_GET_FRAME_MAY_FAIL); if (!f) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame(%dx%d) failed\n", width, height); jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); this->index = 0; return NULL; } linesize = cinfo.output_width * cinfo.output_components; buffer = (cinfo.mem->alloc_sarray)((void*)&cinfo, JPOOL_IMAGE, linesize, 1); if (f->proc_slice && !(f->height & 0xf)) { slice_start[0] = f->base[0]; slice_start[1] = f->base[1]; slice_start[2] = f->base[2]; } /* cut to frame width */ if ((int)cinfo.output_width > f->width) { lprintf ("cut right border %d pixels\n", cinfo.output_width - f->width); linesize = f->width * 3; } /* YUV444->YUV422 simple */ while (cinfo.output_scanline < cinfo.output_height) { uint8_t *dst = f->base[0] + f->pitches[0] * cinfo.output_scanline; jpeg_read_scanlines(&cinfo, buffer, 1); /* cut to frame height */ if ((int)cinfo.output_scanline > f->height) { lprintf("cut bottom scanline %d\n", cinfo.output_scanline - 1); continue; } if (f->format == XINE_IMGFMT_YV12) { if (fullrange) { for (i = 0; i < linesize; i += 3) { *dst++ = buffer[0][i]; } if (!(cinfo.output_scanline & 1)) { dst = f->base[1] + f->pitches[1] * cinfo.output_scanline / 2; for (i = 0; i < linesize; i += 6) { *dst++ = buffer[0][i + 1]; } dst = f->base[2] + f->pitches[2] * cinfo.output_scanline / 2; for (i = 0; i < linesize; i += 6) { *dst++ = buffer[0][i + 2]; } } } else { for (i = 0; i < linesize; i += 3) { *dst++ = ytab[(uint8_t)buffer[0][i]]; } if (!(cinfo.output_scanline & 1)) { dst = f->base[1] + f->pitches[1] * cinfo.output_scanline / 2; for (i = 0; i < linesize; i += 6) { *dst++ = ctab[(uint8_t)buffer[0][i + 1]]; } dst = f->base[2] + f->pitches[2] * cinfo.output_scanline / 2; for (i = 0; i < linesize; i += 6) { *dst++ = ctab[(uint8_t)buffer[0][i + 2]]; } } } if (slice_start[0]) { slice_line++; if (slice_line == 16) { f->proc_slice (f, slice_start); slice_start[0] += 16 * f->pitches[0]; slice_start[1] += 8 * f->pitches[1]; slice_start[2] += 8 * f->pitches[2]; slice_line = 0; } } } else /* XINE_IMGFMT_YUY2 */ { if (fullrange) { for (i = 0; i < linesize; i += 3) { *dst++ = buffer[0][i]; if (i & 1) { *dst++ = buffer[0][i + 2]; } else { *dst++ = buffer[0][i + 1]; } } } else { for (i = 0; i < linesize; i += 3) { /* are these casts paranoid? */ *dst++ = ytab[(uint8_t)buffer[0][i]]; if (i & 1) { *dst++ = ctab[(uint8_t)buffer[0][i + 2]]; } else { *dst++ = ctab[(uint8_t)buffer[0][i + 1]]; } } } if (slice_start[0]) { slice_line++; if (slice_line == 16) { f->proc_slice (f, slice_start); slice_start[0] += 16 * f->pitches[0]; slice_line = 0; } } } } /* final slice */ if (slice_start[0] && slice_line) { f->proc_slice (f, slice_start); } jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); f->duration = 3600; f->bad_frame = 0; _x_stream_info_set (this->stream, XINE_STREAM_INFO_FRAME_DURATION, f->duration); this->index = 0; } return f; } static void jpeg_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { jpeg_decoder_t *this = (jpeg_decoder_t *) this_gen; vo_frame_t *f = NULL; /* demux_image sends everything as preview at open time, * then an empty buf at play time. * we need to defer output to the latter because * - we want it to get correct vpts, * - we want it marked as first frame after seek, and * - we dont want it flushed by a previous stream stop. */ if (!(buf->decoder_flags & BUF_FLAG_PREVIEW) && buf->pts) this->pts = buf->pts; do { if (buf->size > 0) { if (this->index == 0 && (buf->decoder_flags & BUF_FLAG_FRAME_END)) { /* complete frame */ f = _jpeg_decode_data (this, buf->content, buf->size); break; } xine_buffer_copyin (this->image, this->index, buf->mem, buf->size); this->index += buf->size; } if ((buf->decoder_flags & BUF_FLAG_FRAME_END) && (this->index > 0)) { f = _jpeg_decode_data (this, this->image, this->index); this->index = 0; } } while (0); if (f) { if (this->vo_frame) { if (!(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); } this->vo_frame->free (this->vo_frame); } this->vo_frame = f; } if (this->vo_frame && !(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void jpeg_flush (video_decoder_t *this_gen) { jpeg_decoder_t *this = (jpeg_decoder_t *) this_gen; /* * flush out any frames that are still stored in the decoder */ if (this->vo_frame) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void jpeg_reset (video_decoder_t *this_gen) { jpeg_decoder_t *this = (jpeg_decoder_t *) this_gen; /* * reset decoder after engine flush (prepare for new * video data not related to recently decoded data) */ if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } this->index = 0; } static void jpeg_discontinuity (video_decoder_t *this_gen) { (void)this_gen; /* * a time reference discontinuity has happened. * that is, it must forget any currently held pts value */ } static void jpeg_dispose (video_decoder_t *this_gen) { jpeg_decoder_t *this = (jpeg_decoder_t *) this_gen; if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } if (this->video_open) { lprintf("closing video\n"); this->stream->video_out->close(this->stream->video_out, this->stream); this->video_open = 0; } xine_buffer_free(this->image); lprintf("closed\n"); free (this); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { jpeg_decoder_t *this; cfg_entry_t *cfg_entry; lprintf("opened\n"); (void)class_gen; this = calloc(1, sizeof(jpeg_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = jpeg_decode_data; this->video_decoder.flush = jpeg_flush; this->video_decoder.reset = jpeg_reset; this->video_decoder.discontinuity = jpeg_discontinuity; this->video_decoder.dispose = jpeg_dispose; this->stream = stream; /* * initialisation of privates */ this->vo_frame = NULL; this->image = xine_buffer_init(10240); cfg_entry = stream->xine->config->lookup_entry(stream->xine->config, "video.processing.libjpeg_downscaling"); if (cfg_entry) { this->enable_downscaling = cfg_entry->num_value; } return &this->video_decoder; } /* * jpeg plugin class */ static void *init_class (xine_t *xine, const void *data) { (void)data; static video_decoder_class_t decode_video_libjpeg_class = { .open_plugin = open_plugin, .identifier = "jpegvdec", .description = N_("JPEG image video decoder plugin"), .dispose = NULL, }; /* * initialisation of privates */ xine->config->register_bool(xine->config, "video.processing.libjpeg_downscaling", 1, _("allow downscaling of JPEG images (an alternative is to crop)"), _("If enabled, you allow xine to downscale JPEG images " "so that those can be viewed with your graphics hardware. " "If scaling is disabled, images will be cropped."), 10, NULL, NULL); lprintf("class opened\n"); return (void *)&decode_video_libjpeg_class; } /* * exported plugin catalog entry */ static const uint32_t supported_types[] = { BUF_VIDEO_JPEG, 0 }; static const decoder_info_t dec_info_jpeg = { .supported_types = supported_types, .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "jpeg", XINE_VERSION_CODE, &dec_info_jpeg, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libopenhevc.c������������������������������������������������������������0000644�0001750�0001750�00000016666�14647725152�016055� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * libOpenHevc decoder wrapped by Petri Hintukainen <phintuka@users.sourceforge.net> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "libopenhevc" #include <stdlib.h> #include <openHevcWrapper.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> typedef struct hevc_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; int64_t pts; OpenHevc_Handle handle; int decoder_ok; /* current decoder status */ unsigned char *buf; /* the accumulated buffer data */ int bufsize; /* the maximum size of buf */ int size; /* the current size of buf */ int frame_flags; /* color matrix and fullrange */ } hevc_decoder_t; static void hevc_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { hevc_decoder_t *this = (hevc_decoder_t *) this_gen; if (buf->decoder_flags & (BUF_FLAG_COLOR_MATRIX | BUF_FLAG_PREVIEW | BUF_FLAG_STDHEADER | BUF_FLAG_SPECIAL)) { if (buf->decoder_flags & BUF_FLAG_COLOR_MATRIX) { VO_SET_FLAGS_CM (buf->decoder_info[4], this->frame_flags); } if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_STDHEADER | BUF_FLAG_SPECIAL)) { return; } } /* collect data */ if (this->size + buf->size > this->bufsize) { int newsize = this->size + 2 * buf->size; void *tmp; tmp = realloc (this->buf, newsize); if (!tmp) return; this->buf = tmp; this->bufsize = newsize; } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; /* save pts */ if (buf->pts > 0) { this->pts = buf->pts; } if (!(buf->decoder_flags & BUF_FLAG_FRAME_END)) { return; } if (!this->decoder_ok) { (this->stream->video_out->open) (this->stream->video_out, this->stream); libOpenHevcStartDecoder(this->handle); this->decoder_ok = 1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "HEVC"); } /* decode */ int got_pic = libOpenHevcDecode(this->handle, this->buf, this->size, this->pts); this->size = 0; if (got_pic > 0) { vo_frame_t *img; OpenHevc_Frame_cpy frame; OpenHevc_FrameInfo *info = &frame.frameInfo; float ratio; memset(&frame, 0, sizeof(frame)); libOpenHevcGetPictureInfo(this->handle, info); if (info->nBitDepth != 8) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Unsupported bit depth %d\n", info->nBitDepth); return; } if (info->chromat_format != YUV420) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Unsupported colour space %d\n", info->chromat_format); return; } ratio = (float)info->sample_aspect_ratio.num / (float)info->sample_aspect_ratio.den; ratio = ratio * (float)info->nWidth / (float)info->nHeight, img = this->stream->video_out->get_frame (this->stream->video_out, info->nWidth, info->nHeight, ratio, XINE_IMGFMT_YV12, this->frame_flags | VO_BOTH_FIELDS); if (!img || img->width < info->nWidth || img->height < info->nHeight) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": get_frame(%dx%d) failed\n", info->nWidth, info->nHeight); if (img) { img->free(img); } return; } img->pts = info->nTimeStamp; img->bad_frame = 0; img->progressive_frame = 1; img->width = info->nWidth; img->height = info->nHeight; frame.frameInfo.nYPitch = img->pitches[0]; frame.frameInfo.nUPitch = img->pitches[1]; frame.frameInfo.nVPitch = img->pitches[2]; frame.pvY = (void*) img->base[0]; frame.pvU = (void*) img->base[1]; frame.pvV = (void*) img->base[2]; if (!libOpenHevcGetOutputCpy(this->handle, 1, &frame)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": libOpenHevcGetOutputCpy failed\n"); img->free(img); return; } img->draw(img, this->stream); img->free(img); } } static void hevc_flush (video_decoder_t *this_gen) { hevc_decoder_t *this = (hevc_decoder_t *) this_gen; libOpenHevcFlush(this->handle); } static void hevc_reset (video_decoder_t *this_gen) { hevc_decoder_t *this = (hevc_decoder_t *) this_gen; hevc_flush(this_gen); this->size = 0; } static void hevc_discontinuity (video_decoder_t *this_gen) { (void)this_gen; //this->size = 0; } static void hevc_dispose (video_decoder_t *this_gen) { hevc_decoder_t *this = (hevc_decoder_t *) this_gen; if (this->decoder_ok) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } libOpenHevcClose(this->handle); _x_freep (&this->buf); free (this_gen); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { hevc_decoder_t *this; (void)class_gen; this = (hevc_decoder_t *) calloc(1, sizeof(hevc_decoder_t)); if (!this) { return NULL; } this->video_decoder.decode_data = hevc_decode_data; this->video_decoder.flush = hevc_flush; this->video_decoder.reset = hevc_reset; this->video_decoder.discontinuity = hevc_discontinuity; this->video_decoder.dispose = hevc_dispose; this->stream = stream; this->handle = libOpenHevcInit(0, 0); //int nb_pthreads, int thread_type); if (!this->handle) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": libOpenHevcInit failed\n"); free(this); return NULL; } xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": Using libOpenHevc version %s\n", libOpenHevcVersion(this->handle)); return &this->video_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const video_decoder_class_t decode_video_openhevc_class = { .open_plugin = open_plugin, .identifier = "libopenhevc", .description = N_("HEVC video decoder plugin"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&decode_video_openhevc_class; } /* * exported plugin catalog entry */ static const uint32_t video_types[] = { BUF_VIDEO_HEVC, 0 }; static const decoder_info_t dec_info_video = { .supported_types = video_types, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "libopenhevc", XINE_VERSION_CODE, &dec_info_video, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������xine-lib-1.2/src/video_dec/gdkpixbuf.c��������������������������������������������������������������0000644�0001750�0001750�00000023541�14647725152�015530� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2006-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * a gdk-pixbuf-based image video decoder */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #define LOG_MODULE "gdkpixbuf_video_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" #include <gdk-pixbuf/gdk-pixbuf.h> typedef struct image_decoder_s { video_decoder_t video_decoder; xine_stream_t *stream; vo_frame_t *vo_frame; int64_t pts; int video_open; GdkPixbufLoader *loader; } image_decoder_t; static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { image_decoder_t *this = (image_decoder_t *) this_gen; GError *error = NULL; vo_frame_t *f = NULL; /* demux_image sends everything as preview at open time, * then an empty buf at play time. * we need to defer output to the latter because * - we want it to get correct vpts, * - we want it marked as first frame after seek, and * - we dont want it flushed by a previous stream stop. */ if (!(buf->decoder_flags & BUF_FLAG_PREVIEW) && buf->pts) this->pts = buf->pts; if (!this->video_open) { lprintf("opening video\n"); (this->stream->video_out->open) (this->stream->video_out, this->stream); this->video_open = 1; } if (this->loader == NULL) { this->loader = gdk_pixbuf_loader_new (); } if (gdk_pixbuf_loader_write (this->loader, buf->mem, buf->size, &error) == FALSE) { lprintf("error loading image: %s\n", error->message); g_error_free (error); gdk_pixbuf_loader_close (this->loader, NULL); g_object_unref (G_OBJECT (this->loader)); this->loader = NULL; return; } if (buf->decoder_flags & BUF_FLAG_FRAME_END) { GdkPixbuf *pixbuf; int width, height, rowstride, n_channels; guchar *img_buf; int color_matrix, flags, format; rgb2yuy2_t *rgb2yuy2; /* * this->image -> rgb data */ if (gdk_pixbuf_loader_close (this->loader, &error) == FALSE) { lprintf("error loading image: %s\n", error->message); g_error_free (error); g_object_unref (G_OBJECT (this->loader)); this->loader = NULL; return; } pixbuf = gdk_pixbuf_loader_get_pixbuf (this->loader); if (pixbuf != NULL) g_object_ref (G_OBJECT (pixbuf)); g_object_unref (this->loader); this->loader = NULL; if (pixbuf == NULL) { lprintf("error loading image\n"); return; } width = gdk_pixbuf_get_width (pixbuf) & ~1; /* must be even for init_yuv_planes */ height = gdk_pixbuf_get_height (pixbuf); img_buf = gdk_pixbuf_get_pixels (pixbuf); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); lprintf("image loaded successfully\n"); flags = VO_BOTH_FIELDS; color_matrix = this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_FULLRANGE ? 11 : 10; VO_SET_FLAGS_CM (color_matrix, flags); /* * alloc video frame */ format = (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_YUY2) ? XINE_IMGFMT_YUY2 : XINE_IMGFMT_YV12; f = this->stream->video_out->get_frame (this->stream->video_out, width, height, (double)width / (double)height, format, flags | VO_GET_FRAME_MAY_FAIL); if (!f) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame(%dx%d) failed\n", width, height); g_object_unref (pixbuf); return; } /* crop if allocated frame is smaller than requested */ if (width > f->width) width = f->width; if (height > f->height) height = f->height; f->ratio = (double)width / (double)height; /* rgb data -> yuv */ n_channels = gdk_pixbuf_get_n_channels (pixbuf); rowstride = gdk_pixbuf_get_rowstride (pixbuf); rgb2yuy2 = rgb2yuy2_alloc (color_matrix, n_channels > 3 ? "rgba" : "rgb"); if (f->format == XINE_IMGFMT_YV12) { rgb2yv12_slice (rgb2yuy2, img_buf, rowstride, f->base[0], f->pitches[0], f->base[1], f->pitches[1], f->base[2], f->pitches[2], width, height); } else { if (!f->proc_slice || (f->height & 15)) { /* do all at once */ rgb2yuy2_slice (rgb2yuy2, img_buf, rowstride, f->base[0], f->pitches[0], width, height); } else { /* sliced */ uint8_t *sptr[1]; int y, h = 16; for (y = 0; y < height; y += 16) { if (y + 16 > height) h = height & 15; sptr[0] = f->base[0] + y * f->pitches[0]; rgb2yuy2_slice (rgb2yuy2, img_buf + y * rowstride, rowstride, sptr[0], f->pitches[0], width, h); f->proc_slice (f, sptr); } } } rgb2yuy2_free (rgb2yuy2); g_object_unref (pixbuf); /* * draw video frame */ f->duration = 3600; f->bad_frame = 0; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, f->duration); } if (f) { if (this->vo_frame) { if (!(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); } this->vo_frame->free (this->vo_frame); } this->vo_frame = f; } if (this->vo_frame && !(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void image_flush (video_decoder_t *this_gen) { image_decoder_t *this = (image_decoder_t *) this_gen; /* * flush out any frames that are still stored in the decoder */ if (this->vo_frame) { this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void image_reset (video_decoder_t *this_gen) { image_decoder_t *this = (image_decoder_t *) this_gen; /* * reset decoder after engine flush (prepare for new * video data not related to recently decoded data) */ if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } if (this->loader != NULL) { gdk_pixbuf_loader_close (this->loader, NULL); g_object_unref (G_OBJECT (this->loader)); this->loader = NULL; } } static void image_discontinuity (video_decoder_t *this_gen) { /* image_decoder_t *this = (image_decoder_t *) this_gen; */ (void)this_gen; /* * a time reference discontinuity has happened. * that is, it must forget any currently held pts value */ } static void image_dispose (video_decoder_t *this_gen) { image_decoder_t *this = (image_decoder_t *) this_gen; if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } if (this->video_open) { lprintf("closing video\n"); this->stream->video_out->close(this->stream->video_out, this->stream); this->video_open = 0; } if (this->loader != NULL) { gdk_pixbuf_loader_close (this->loader, NULL); g_object_unref (G_OBJECT (this->loader)); this->loader = NULL; } lprintf("closed\n"); free (this); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { image_decoder_t *this; lprintf("opened\n"); (void)class_gen; #if (GLIB_MAJOR_VERSION < 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION <= 35)) g_type_init (); #endif this = (image_decoder_t *) calloc(1, sizeof(image_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = image_decode_data; this->video_decoder.flush = image_flush; this->video_decoder.reset = image_reset; this->video_decoder.discontinuity = image_discontinuity; this->video_decoder.dispose = image_dispose; this->stream = stream; /* * initialisation of privates */ this->vo_frame = NULL; this->loader = NULL; return &this->video_decoder; } /* * image plugin class */ static void *init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_gdkpixbuf_class = { .open_plugin = open_plugin, .identifier = "gdkpixbuf", .description = N_("gdk-pixbuf image video decoder plugin"), .dispose = NULL, }; return (void *)&decode_video_gdkpixbuf_class; } /* * exported plugin catalog entry */ static const uint32_t supported_types[] = { BUF_VIDEO_IMAGE, BUF_VIDEO_JPEG, BUF_VIDEO_PNG, 0 }; static const decoder_info_t dec_info_image = { .supported_types = supported_types, .priority = 8, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "gdkpixbuf", XINE_VERSION_CODE, &dec_info_image, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/group_raw.h��������������������������������������������������������������0000644�0001750�0001750�00000002235�14647725152�015554� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * A group of decoders for raw (uncompressed or slightly compressed) video. * */ #ifndef HAVE_GROUP_RAW_H #define HAVE_GROUP_RAW_H #include <xine/xine_internal.h> void *decode_rgb_init_class (xine_t *xine, const void *data); void *decode_yuv_init_class (xine_t *xine, const void *data); void *decode_bitplane_init_class (xine_t *xine, const void *data); #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/dav1d.c������������������������������������������������������������������0000644�0001750�0001750�00000041513�14647725152�014543� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2018-2022 the xine project * Copyright (C) 2018 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <errno.h> #include <stdlib.h> #include <dav1d/dav1d.h> #define LOG_MODULE "dav1d_video_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> typedef struct dav1d_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; Dav1dContext *ctx; Dav1dPicAllocator default_allocator; /* used as fallback when dri is not possible */ uint8_t cap_deep; uint8_t dri; uint8_t video_open; uint8_t meta_set; int64_t pts; /* current incoming pts */ double ratio; unsigned char *buf; /* the accumulated buffer data */ size_t bufsize; /* the maximum size of buf */ size_t size; /* the current size of buf */ } dav1d_decoder_t; /* * frame allocator for DRI */ static void _free_frame_cb(Dav1dPicture *pic, void *cookie) { dav1d_decoder_t *this = cookie; vo_frame_t *img; if (!this->dri || !pic->allocator_data || pic->allocator_data == pic->data[0]) { this->default_allocator.release_picture_callback(pic, this->default_allocator.cookie); return; } img = pic->allocator_data; img->free(img); } static int _alloc_frame_cb(Dav1dPicture *pic, void *cookie) { dav1d_decoder_t *this = cookie; vo_frame_t *img; int width, height, format, flags = 0; int i; if (!this->dri) return this->default_allocator.alloc_picture_callback(pic, this->default_allocator.cookie); switch (pic->p.layout) { case DAV1D_PIXEL_LAYOUT_I400: /* monochrome */ case DAV1D_PIXEL_LAYOUT_I420: /* 4:2:0 planar */ this->dri = (pic->p.bpc == 8 || this->cap_deep); break; case DAV1D_PIXEL_LAYOUT_I422: /* 4:2:2 planar */ case DAV1D_PIXEL_LAYOUT_I444: /* 4:4:4 planar */ this->dri = 0; break; default: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "get_frame() failed: unknown layout %d\n", pic->p.layout); return -1; } if (this->ratio < 0.01) this->ratio = (double)pic->p.w / (double)pic->p.h; if (!this->dri) { /* unsupported frame format, need to copy ... */ return this->default_allocator.alloc_picture_callback(pic, this->default_allocator.cookie); } /* The data[0], data[1] and data[2] must be 32 bytes aligned and with a * pixel width/height multiple of 128 pixels. * data[1] and data[2] must share the same stride[1]. */ width = (pic->p.w + 127) & ~127; height = (pic->p.h + 127) & ~127; if (pic->p.bpc > 8) { format = XINE_IMGFMT_YV12_DEEP; VO_SET_FLAGS_DEPTH (pic->p.bpc, flags); } else { format = XINE_IMGFMT_YV12; } img = this->stream->video_out->get_frame (this->stream->video_out, width, height, this->ratio, format, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL | flags); if (!img || img->width < width || img->height < height) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "get_frame(%dx%d) failed\n", width, height); if (img) img->free(img); return -1; } if (format == XINE_IMGFMT_YV12 && img->pitches[1] != img->pitches[2]) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "get_frame(%dx%d) returned incompatible frame\n", width, height); img->free(img); return -1; } img->crop_right = width - pic->p.w; img->crop_bottom = height - pic->p.h; for (i = 0; i < 3; i++) pic->data[i] = img->base[i]; pic->stride[0] = img->pitches[0]; pic->stride[1] = img->pitches[1]; _x_assert(img->pitches[1] == img->pitches[2]); pic->allocator_data = img; return 0; } /* * image copy / conversion (when dri not in use) */ static void _copy_plane(uint8_t *dst, const uint8_t *src, int dst_pitch, int src_pitch, int width, int height, int shift) { int x, y; if (shift > 0) { for (y = 0; y < height; y++) { const uint16_t *restrict s = (uint16_t *)(src + y * src_pitch); uint8_t *restrict d = dst + y * dst_pitch; for (x = 0; x < width; x++) d[x] = s[x] >> shift; } } else { for (y = 0; y < height; y++) { xine_fast_memcpy(dst, src, width); src += src_pitch; dst += dst_pitch; } } } /* I420 / I400 -> YV12 */ static void _copy_planes(vo_frame_t *img, const Dav1dPicture *pic, int width, int height, int shift) { _copy_plane(img->base[0], pic->data[0], img->pitches[0], pic->stride[0], width, height, shift); if (pic->p.layout == DAV1D_PIXEL_LAYOUT_I400) { memset(img->base[1], 0x80, img->height * img->pitches[1]); memset(img->base[2], 0x80, img->height * img->pitches[2]); } else { _copy_plane(img->base[1], pic->data[1], img->pitches[1], pic->stride[1], width/2, height/2, shift); _copy_plane(img->base[2], pic->data[2], img->pitches[2], pic->stride[1], width/2, height/2, shift); } } /* I422 / I444 planar -> YUY2 */ static void _merge_planes(uint8_t *dst, int dst_pitch, const Dav1dPicture *pic, int width, int height, int shift, int subsamp) { uint8_t *src_y = pic->data[0], *src_u = pic->data[1], *src_v = pic->data[2]; int x, y; int skip = 2 - !!subsamp; if (shift > 0) { for (y = 0; y < height; y++) { const uint16_t *restrict sy = (const uint16_t *)(src_y + y * pic->stride[0]); const uint16_t *restrict su = (const uint16_t *)(src_u + y * pic->stride[1]); const uint16_t *restrict sv = (const uint16_t *)(src_v + y * pic->stride[1]); uint8_t *restrict d = dst + y * dst_pitch; for (x = 0; x < width; x++) { *d++ = *sy++ >> shift; *d++ = *su >> shift; *d++ = *sy++ >> shift; *d++ = *sv >> shift; su += skip; sv += skip; } } } else { for (y = 0; y < height; y++) { const uint8_t *restrict sy = src_y + y * pic->stride[0]; const uint8_t *restrict su = src_u + y * pic->stride[1]; const uint8_t *restrict sv = src_v + y * pic->stride[1]; uint8_t *restrict d = dst + y * dst_pitch; for (x = 0; x < width; x++) { *d++ = *sy++; *d++ = *su; *d++ = *sy++; *d++ = *sv; su += skip; sv += skip; } } } } static vo_frame_t * _copy_image(dav1d_decoder_t *this, Dav1dPicture *pic) { vo_frame_t *img = NULL; int width = pic->p.w; int height = pic->p.h; int shift = pic->p.bpc - 8; int format; switch (pic->p.layout) { case DAV1D_PIXEL_LAYOUT_I400: /* monochrome */ case DAV1D_PIXEL_LAYOUT_I420: /* 4:2:0 planar */ format = XINE_IMGFMT_YV12; break; case DAV1D_PIXEL_LAYOUT_I422: /* 4:2:2 planar */ case DAV1D_PIXEL_LAYOUT_I444: /* 4:4:4 planar */ format = XINE_IMGFMT_YUY2; break; default: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unknown dav1d pixl layout %d\n", pic->p.layout); return NULL; } img = this->stream->video_out->get_frame (this->stream->video_out, width, height, this->ratio, format, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL); if (!img || img->width < width || img->height < height) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "get_frame(%dx%d) failed\n", width, height); if (img) img->free(img); return NULL; } switch (pic->p.layout) { case DAV1D_PIXEL_LAYOUT_I400: /* monochrome */ case DAV1D_PIXEL_LAYOUT_I420: /* 4:2:0 planar */ _copy_planes(img, pic, width, height, shift); break; case DAV1D_PIXEL_LAYOUT_I422: /* 4:2:2 planar */ case DAV1D_PIXEL_LAYOUT_I444: /* 4:4:4 planar */ _merge_planes(img->base[0], img->pitches[0], pic, width, height, shift, (pic->p.layout == DAV1D_PIXEL_LAYOUT_I422)); break; } return img; } /* * */ static void _draw_image(dav1d_decoder_t *this, Dav1dPicture *pic) { vo_frame_t *img; if (!this->meta_set) { this->meta_set = 1; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "AV1"); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, pic->p.w); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, pic->p.h); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); } if (this->dri) { img = pic->allocator_data; } else { img = _copy_image(this, pic); } if (!img) return; img->progressive_frame = 1; VO_SET_FLAGS_CM ((pic->seq_hdr->mtrx << 1) | (!!pic->seq_hdr->color_range), img->flags); switch (pic->frame_hdr->frame_type) { case DAV1D_FRAME_TYPE_KEY: /* Key Intra frame */ case DAV1D_FRAME_TYPE_INTRA: /* Non key Intra frame */ img->picture_coding_type = 1; break; case DAV1D_FRAME_TYPE_INTER: /* Inter frame */ img->picture_coding_type = 2; break; case DAV1D_FRAME_TYPE_SWITCH: /* Switch Inter frame */ img->picture_coding_type = 3; break; } img->pts = pic->m.timestamp; img->bad_frame = 0; img->progressive_frame = 1; img->draw(img, this->stream); /* when using dri, frame may still be used as a reference frame inside decoder. * it is freed in free_frame_cb(). */ if (!this->dri) img->free(img); } static void _decode(dav1d_decoder_t *this, Dav1dData *data) { Dav1dPicture pic; int r; memset(&pic, 0, sizeof(pic)); data->m.timestamp = this->pts; this->pts = 0; do { if (data->sz > 0) { r = dav1d_send_data(this->ctx, data); if (r < 0 && r != -EAGAIN) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "send_data() failed: %d\n", r); break; } } r = dav1d_get_picture(this->ctx, &pic); if (r == 0) { _draw_image(this, &pic); dav1d_picture_unref(&pic); } else if (r != -EAGAIN) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "get_picture() failed: %d\n", r); break; } } while (data->sz > 0); } static void _data_free_wrapper(const uint8_t *data, void *opaque) { (void)data; free(opaque); } static void _dav1d_decode_data(video_decoder_t *this_gen, buf_element_t *buf) { dav1d_decoder_t *this = xine_container_of(this_gen, dav1d_decoder_t, video_decoder); Dav1dData data; int r; if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_SPECIAL | BUF_FLAG_STDHEADER | BUF_FLAG_ASPECT)) { if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_SPECIAL | BUF_FLAG_STDHEADER)) { return; } if (buf->decoder_flags & BUF_FLAG_ASPECT) { if (buf->decoder_info[2]) { this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; } } } /* save pts */ if (buf->pts > 0) { this->pts = buf->pts; } /* collect data */ if (this->size + buf->size > this->bufsize) { this->bufsize = this->size + 2 * buf->size; this->buf = realloc (this->buf, this->bufsize); if (!this->buf) { this->bufsize = 0; return; } } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (!(buf->decoder_flags & BUF_FLAG_FRAME_END)) { return; } /* wrap gathered data */ r = dav1d_data_wrap(&data, this->buf, this->size, _data_free_wrapper, this->buf); this->size = 0; if (r < 0) { return; } this->buf = NULL; this->bufsize = 0; if (!this->video_open) { (this->stream->video_out->open) (this->stream->video_out, this->stream); this->video_open = 1; } /* decode */ _decode(this, &data); } static void _dav1d_flush(video_decoder_t *this_gen) { dav1d_decoder_t *this = xine_container_of(this_gen, dav1d_decoder_t, video_decoder); Dav1dPicture pic; memset(&pic, 0, sizeof(pic)); while (1) { if (dav1d_get_picture(this->ctx, &pic) < 0) break; _draw_image(this, &pic); dav1d_picture_unref(&pic); } } static void _dav1d_discontinuity(video_decoder_t *this_gen) { dav1d_decoder_t *this = xine_container_of(this_gen, dav1d_decoder_t, video_decoder); this->pts = 0; this->size = 0; } static void _dav1d_reset(video_decoder_t *this_gen) { dav1d_decoder_t *this = xine_container_of(this_gen, dav1d_decoder_t, video_decoder); Dav1dPicture pic; dav1d_flush(this->ctx); /* drop frames */ memset(&pic, 0, sizeof(pic)); while (1) { if (dav1d_get_picture(this->ctx, &pic) < 0) break; dav1d_picture_unref(&pic); } this->pts = 0; this->size = 0; } static void _dav1d_dispose(video_decoder_t *this_gen) { dav1d_decoder_t *this = xine_container_of(this_gen, dav1d_decoder_t, video_decoder); _dav1d_reset(this_gen); dav1d_close(&this->ctx); _x_freep(&this->buf); if (this->video_open) { this->video_open = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this_gen); } static video_decoder_t *_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream) { dav1d_decoder_t *this; Dav1dSettings settings; int ncpu; (void)class_gen; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "using dav1d version %s\n", dav1d_version()); this = (dav1d_decoder_t *)calloc(1, sizeof(*this)); if (!this) return NULL; this->size = 0; this->buf = NULL; this->stream = stream; this->ratio = 0.0; this->dri = 1; this->cap_deep = !!(stream->video_out->get_capabilities(stream->video_out) & VO_CAP_YV12_DEEP); this->video_decoder.decode_data = _dav1d_decode_data; this->video_decoder.flush = _dav1d_flush; this->video_decoder.reset = _dav1d_reset; this->video_decoder.discontinuity = _dav1d_discontinuity; this->video_decoder.dispose = _dav1d_dispose; /* * set up decoder */ dav1d_default_settings(&settings); /* save default allocator before overriding. It will be used when dri is not possible. */ this->default_allocator = settings.allocator; /* multithreading */ ncpu = xine_cpu_count(); #if DAV1D_API_VERSION_MAJOR > 5 settings.n_threads = ncpu + 1; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Using %d threads\n", settings.n_threads); #else settings.n_frame_threads = (ncpu > 8) ? 4 : (ncpu < 2) ? 1 : ncpu/2; settings.n_tile_threads = MAX(1, ncpu - settings.n_frame_threads + 1); xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "Using %d frame threads, %d tile threads\n", settings.n_frame_threads, settings.n_tile_threads); #endif /* dri frame allocator */ settings.allocator.cookie = this; settings.allocator.alloc_picture_callback = _alloc_frame_cb; settings.allocator.release_picture_callback = _free_frame_cb; if (dav1d_open(&this->ctx, &settings) < 0) { xine_log(stream->xine, XINE_LOG_MSG, "Failed to initialize dav1d AV1 decoder\n"); free(this); return NULL; } return &this->video_decoder; } static void *init_plugin_dav1d(xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_dav1d_class = { .open_plugin = _open_plugin, .identifier = "dav1d", .description = N_("AV1 (dav1d) video decoder"), .dispose = NULL, }; return (void *)&decode_video_dav1d_class; } /* * exported plugin catalog entry */ static const uint32_t video_types_dav1d[] = { BUF_VIDEO_AV1, 0 }; static const decoder_info_t dec_info_video_dav1d = { .supported_types = video_types_dav1d, .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "dav1d", XINE_VERSION_CODE, &dec_info_video_dav1d, init_plugin_dav1d }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libaom.c�����������������������������������������������������������������0000644�0001750�0001750�00000024212�14647725152�015004� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2013-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * libaom AV1 decoder wrapped by Petri Hintukainen <phintuka@users.sourceforge.net> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <aom/aom_decoder.h> #include <aom/aomdx.h> #define LOG_MODULE "libaom_video_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> typedef struct aom_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; struct aom_codec_ctx decoder; int64_t pts; int video_open; unsigned char *buf; /* the accumulated buffer data */ int bufsize; /* the maximum size of buf */ int size; /* the current size of buf */ double ratio; } aom_decoder_t; static void _copy_yv12_16_to_8(vo_frame_t *img, struct aom_image *aom_img, int width, int height) { int i; for (i = 0; i < 3; i++) { int w = width; int h = height; int x, y; if (i) { w = (w + 1) >> 1; h = (h + 1) >> 1; } for (y = 0; y < h; y++) { uint16_t *src = (uint16_t *)(aom_img->planes[i] + y * aom_img->stride[i]); uint8_t *dst = img->base[i] + y * img->pitches[i]; for (x = 0; x < w; x++) { *dst++ = *src++; } } } } static void _draw_image(aom_decoder_t *this, aom_image_t *aom_img) { vo_frame_t *img; int64_t pts; int width, height; int frame_flags = 0; pts = (int64_t)(intptr_t)aom_img->user_priv; /* check format */ switch (aom_img->fmt) { case AOM_IMG_FMT_I420: case AOM_IMG_FMT_YV12: case AOM_IMG_FMT_I42016: break; default: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unsupported image format %d 0x%x depth=%d\n", aom_img->fmt, aom_img->fmt, aom_img->bit_depth); return; } if (aom_img->bit_depth != 8) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "unsupported color depth %d\n", aom_img->bit_depth); return; } VO_SET_FLAGS_CM ((aom_img->mc << 1) | (aom_img->range == AOM_CR_FULL_RANGE), frame_flags); /* get frame */ img = this->stream->video_out->get_frame (this->stream->video_out, aom_img->d_w, aom_img->d_h, this->ratio, XINE_IMGFMT_YV12, frame_flags | VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL); if (!img) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "get_frame(%dx%d) failed\n", aom_img->d_w, aom_img->d_h); return; } /* copy */ /* crop if allocated frame is smaller than requested */ width = ((int)aom_img->d_w > img->width) ? img->width : (int)aom_img->d_w; height = ((int)aom_img->d_h > img->height) ? img->height : (int)aom_img->d_h; switch (aom_img->fmt) { case AOM_IMG_FMT_I420: case AOM_IMG_FMT_YV12: yv12_to_yv12(/* Y */ aom_img->planes[0], aom_img->stride[0], img->base[0], img->pitches[0], /* U */ aom_img->planes[1], aom_img->stride[1], img->base[1], img->pitches[1], /* V */ aom_img->planes[2], aom_img->stride[2], img->base[2], img->pitches[2], /* width x height */ width, height); break; case AOM_IMG_FMT_I42016: _copy_yv12_16_to_8(img, aom_img, width, height); break; default: /* not reached */ break; } /* draw */ VO_SET_FLAGS_CM ((aom_img->mc << 1) | (aom_img->range == AOM_CR_FULL_RANGE), img->flags); img->pts = pts; img->bad_frame = 0; img->progressive_frame = 1; img->draw(img, this->stream); img->free(img); } static void _decode(aom_decoder_t *this, const uint8_t *buf, size_t size) { const void *iter = NULL; struct aom_image *aom_img; void *priv; priv = (void*)(intptr_t)this->pts; this->pts = 0; if (aom_codec_decode(&this->decoder, buf, size, priv) != AOM_CODEC_OK) { const char *error = aom_codec_error(&this->decoder); const char *detail = aom_codec_error_detail(&this->decoder); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "error decoding frame: %s%s%s", error, detail ? ": " : "", detail ? detail : ""); return; } while ((aom_img = aom_codec_get_frame(&this->decoder, &iter))) { if (aom_img->d_h < 1 || aom_img->d_w < 1) continue; if (!this->video_open) { (this->stream->video_out->open) (this->stream->video_out, this->stream); this->video_open = 1; if (this->ratio < 0.01) this->ratio = (double)aom_img->d_w / (double)aom_img->d_h; _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "AV1"); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, aom_img->d_w); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, aom_img->d_h); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); } _draw_image(this, aom_img); } } static void _aom_decode_data(video_decoder_t *this_gen, buf_element_t *buf) { aom_decoder_t *this = (aom_decoder_t *) this_gen; uint8_t *data; size_t size; if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_SPECIAL | BUF_FLAG_STDHEADER | BUF_FLAG_ASPECT)) { if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_SPECIAL | BUF_FLAG_STDHEADER)) { return; } if (buf->decoder_flags & BUF_FLAG_ASPECT) { if (buf->decoder_info[2]) { this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; } } } /* save pts */ if (buf->pts > 0) { this->pts = buf->pts; } /* collect data */ if (this->size == 0 && (buf->decoder_flags & BUF_FLAG_FRAME_END)) { /* complete buffer - no need to copy */ data = buf->content; size = buf->size; } else { if (this->size + buf->size > this->bufsize) { this->bufsize = this->size + 2 * buf->size; this->buf = realloc (this->buf, this->bufsize); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (!(buf->decoder_flags & BUF_FLAG_FRAME_END)) { return; } data = this->buf; size = this->size; this->size = 0; } /* decode */ _decode(this, data, size); } static void _aom_flush(video_decoder_t *this_gen) { aom_decoder_t *this = (aom_decoder_t *) this_gen; _decode(this, NULL, 0); } static void _aom_reset(video_decoder_t *this_gen) { aom_decoder_t *this = (aom_decoder_t *) this_gen; const void *iter = NULL; while (aom_codec_get_frame(&this->decoder, &iter) != NULL) { } this->pts = 0; this->size = 0; } static void _aom_discontinuity(video_decoder_t *this_gen) { aom_decoder_t *this = (aom_decoder_t *) this_gen; _aom_flush(this_gen); this->pts = 0; this->size = 0; } static void _aom_dispose(video_decoder_t *this_gen) { aom_decoder_t *this = (aom_decoder_t *) this_gen; aom_codec_destroy(&this->decoder); _x_freep(&this->buf); if (this->video_open) { this->video_open = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this_gen); } static video_decoder_t *_open_plugin(video_decoder_class_t *class_gen, xine_stream_t *stream) { aom_decoder_t *this; struct aom_codec_dec_cfg deccfg = { .threads = xine_cpu_count(), .allow_lowbitdepth = 1, }; (void)class_gen; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "using %d CPU cores\n", deccfg.threads); this = (aom_decoder_t *) calloc(1, sizeof(aom_decoder_t)); if (!this) return NULL; this->size = 0; this->buf = NULL; this->stream = stream; this->ratio = 0.0; this->video_decoder.decode_data = _aom_decode_data; this->video_decoder.flush = _aom_flush; this->video_decoder.reset = _aom_reset; this->video_decoder.discontinuity = _aom_discontinuity; this->video_decoder.dispose = _aom_dispose; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "using libaom %s\n", aom_codec_version_str()); if (aom_codec_dec_init(&this->decoder, &aom_codec_av1_dx_algo, &deccfg, 0) != AOM_CODEC_OK) { xine_log(stream->xine, XINE_LOG_MSG, "Failed to initialize libaom AV1 decoder: %s\n", aom_codec_error(&this->decoder)); free(this); return NULL; } return &this->video_decoder; } static void *init_plugin_aom(xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_aom_class = { .open_plugin = _open_plugin, .identifier = "libaom", .description = N_("AV1 (libaom) video decoder"), .dispose = NULL, }; return (void *)&decode_video_aom_class; } /* * exported plugin catalog entry */ static const uint32_t video_types_aom[] = { BUF_VIDEO_AV1, 0 }; static const decoder_info_t dec_info_video_aom = { .supported_types = video_types_aom, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "libaom", XINE_VERSION_CODE, &dec_info_video_aom, init_plugin_aom }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/image.c������������������������������������������������������������������0000644�0001750�0001750�00000023561�14647725152�014631� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2003-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * a image video decoder */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <stdio.h> #define LOG_MODULE "image_video_decoder" #define LOG_VERBOSE /* #define LOG */ #ifdef HAVE_MAGICKWAND_MAGICKWAND_H #include <MagickWand/MagickWand.h> #else #include <wand/magick_wand.h> #endif #ifdef PACKAGE_NAME #undef PACKAGE_BUGREPORT #undef PACKAGE_NAME #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #endif #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include <xine/xine_buffer.h> #include "bswap.h" #ifdef HAVE_GRAPHICSMAGICK # define MAGICK_VERSION 0x660 #else # if !defined(MagickLibVersion) || MagickLibVersion < 0x661 # define MAGICK_VERSION 0x660 # else # define MAGICK_VERSION MagickLibVersion # endif #endif typedef struct image_decoder_s { video_decoder_t video_decoder; xine_stream_t *stream; int64_t pts; vo_frame_t *vo_frame; unsigned char *buf; int buf_size; int video_open; } image_decoder_t; static vo_frame_t *_image_decode_data (image_decoder_t *this, unsigned char *data, size_t size) { if (!this->video_open) { lprintf("opening video\n"); (this->stream->video_out->open) (this->stream->video_out, this->stream); this->video_open = 1; } { int width, height, img_stride; int status; MagickWand *wand; uint8_t *img_buf; vo_frame_t *img; rgb2yuy2_t *rgb2yuy2; int frame_flags, cm, format; /* * this->image -> rgb data */ #if MAGICK_VERSION < 0x661 InitializeMagick(NULL); #else MagickWandGenesis(); #endif wand = NewMagickWand(); status = MagickReadImageBlob (wand, data, size); if (!status) { DestroyMagickWand(wand); #if MAGICK_VERSION < 0x661 DestroyMagick(); #else MagickWandTerminus(); #endif lprintf("error loading image\n"); return NULL; } width = MagickGetImageWidth(wand); height = MagickGetImageHeight(wand); img_stride = 3 * width; img_buf = malloc (img_stride * height); #if MAGICK_VERSION < 0x661 MagickGetImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); DestroyMagickWand(wand); DestroyMagick(); #else MagickExportImagePixels(wand, 0, 0, width, height, "RGB", CharPixel, img_buf); DestroyMagickWand(wand); MagickWandTerminus(); #endif _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); lprintf("image loaded successfully\n"); frame_flags = VO_BOTH_FIELDS; cm = 10; /* mpeg range ITU-R 601 */ if (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_FULLRANGE) cm = 11; /* full range */ VO_SET_FLAGS_CM (cm, frame_flags); /* * alloc video frame and set cropping */ format = (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_YUY2) ? XINE_IMGFMT_YUY2 : XINE_IMGFMT_YV12; img = this->stream->video_out->get_frame (this->stream->video_out, width, height, (double)width / (double)height, format, frame_flags); if (!img) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame(%dx%d) failed\n", width, height); free (img_buf); return NULL; } if (width > img->width) width = img->width; if (height > img->height) height = img->height; img->ratio = (double)width / (double)height; /* * rgb data -> yuv_planes */ rgb2yuy2 = rgb2yuy2_alloc (cm, "rgb"); if (img->format == XINE_IMGFMT_YV12) { rgb2yv12_slice (rgb2yuy2, img_buf, img_stride, img->base[0], img->pitches[0], img->base[1], img->pitches[1], img->base[2], img->pitches[2], width, height); } else { rgb2yuy2_slice (rgb2yuy2, img_buf, img_stride, img->base[0], img->pitches[0], width, height); } rgb2yuy2_free (rgb2yuy2); free (img_buf); /* * draw video frame */ img->duration = 3600; img->bad_frame = 0; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); return img; } } static void image_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { image_decoder_t *this = (image_decoder_t *) this_gen; vo_frame_t *f = NULL; /* demux_image sends everything as preview at open time, * then an empty buf at play time. * we need to defer output to the latter because * - we want it to get correct vpts, * - we want it marked as first frame after seek, and * - we dont want it flushed by a previous stream stop. */ if (!(buf->decoder_flags & BUF_FLAG_PREVIEW) && buf->pts) this->pts = buf->pts; do { if (buf->size > 0) { if (this->buf_size == 0 && (buf->decoder_flags & BUF_FLAG_FRAME_END)) { /* complete frame */ f = _image_decode_data(this, buf->content, buf->size); break; } xine_buffer_copyin (this->buf, this->buf_size, buf->mem, buf->size); this->buf_size += buf->size; } if ((buf->decoder_flags & BUF_FLAG_FRAME_END) && (this->buf_size > 0)) { f = _image_decode_data(this, this->buf, this->buf_size); this->buf_size = 0; } } while (0); if (f) { if (this->vo_frame) { if (!(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); } this->vo_frame->free (this->vo_frame); } this->vo_frame = f; } if (this->vo_frame && !(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void image_flush (video_decoder_t *this_gen) { image_decoder_t *this = (image_decoder_t *) this_gen; /* * flush out any frames that are still stored in the decoder */ if (this->vo_frame) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void image_reset (video_decoder_t *this_gen) { image_decoder_t *this = (image_decoder_t *) this_gen; /* * reset decoder after engine flush (prepare for new * video data not related to recently decoded data) */ if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } this->buf_size = 0; } static void image_discontinuity (video_decoder_t *this_gen) { /* image_decoder_t *this = (image_decoder_t *) this_gen; */ (void)this_gen; /* * a time reference discontinuity has happened. * that is, it must forget any currently held pts value */ } static void image_dispose (video_decoder_t *this_gen) { image_decoder_t *this = (image_decoder_t *) this_gen; if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } if (this->video_open) { lprintf("closing video\n"); this->stream->video_out->close(this->stream->video_out, this->stream); this->video_open = 0; } xine_buffer_free (this->buf); lprintf("closed\n"); free (this); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { image_decoder_t *this; lprintf("opened\n"); (void)class_gen; this = (image_decoder_t *) calloc(1, sizeof(image_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = image_decode_data; this->video_decoder.flush = image_flush; this->video_decoder.reset = image_reset; this->video_decoder.discontinuity = image_discontinuity; this->video_decoder.dispose = image_dispose; this->stream = stream; /* * initialisation of privates */ this->vo_frame = NULL; this->buf = xine_buffer_init (10240); return &this->video_decoder; } /* * image plugin class */ static void *init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_image_class = { .open_plugin = open_plugin, .identifier = "imagevdec", .description = N_("image video decoder plugin"), .dispose = NULL, }; return (void*)&decode_video_image_class; } /* * exported plugin catalog entry */ static const uint32_t supported_types[] = { BUF_VIDEO_IMAGE, BUF_VIDEO_JPEG, BUF_VIDEO_PNG, 0 }; static const decoder_info_t dec_info_image = { .supported_types = supported_types, .priority = 7, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "image", XINE_VERSION_CODE, &dec_info_image, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/bitplane.c���������������������������������������������������������������0000644�0001750�0001750�00000204116�14647725152�015342� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2004-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Bitplane "Decoder" by Manfred Tremmel (Manfred.Tremmel@iiv.de) * Converts Amiga typical bitplane pictures to a YUV2 map * suitable for display under xine. It's based on the rgb-decoder * and the development documentation from the Amiga Developer CD * * Supported formats: * - uncompressed and byterun1 compressed ILBM data * - IFF ANIM compression methods OPT 5, 7 (long and short) and * 8 (long and short) * - untested (found no testfiles) IFF-ANIM OPT 3, 4 and 6 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "bswap.h" #include "group_raw.h" #include "demuxers/iff.h" #define IFF_REPLACE_BYTE_SIMPLE(ptr, old_data, new_data, colorindexx ) { \ register uint8_t *index_ptr = ptr; \ register uint8_t colorindex = colorindexx; \ *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ *index_ptr++ += ((new_data & 0x80) ? colorindex : 0); \ *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ *index_ptr++ += ((new_data & 0x40) ? colorindex : 0); \ *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ *index_ptr++ += ((new_data & 0x20) ? colorindex : 0); \ *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ *index_ptr++ += ((new_data & 0x10) ? colorindex : 0); \ *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ *index_ptr++ += ((new_data & 0x08) ? colorindex : 0); \ *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ *index_ptr++ += ((new_data & 0x04) ? colorindex : 0); \ *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ *index_ptr++ += ((new_data & 0x02) ? colorindex : 0); \ *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ old_data = new_data; \ } #define IFF_REPLACE_BYTE(ptr, yuvy, yuvu, yuvv, yuv_palette, old_data, new_data, colorindexx ) { \ register uint8_t *index_ptr = ptr; \ register uint8_t colorindex = colorindexx; \ register uint8_t *yuv_y = yuvy; \ register uint8_t *yuv_u = yuvu; \ register uint8_t *yuv_v = yuvv; \ *index_ptr -= ((old_data & 0x80) ? colorindex : 0); \ *index_ptr += ((new_data & 0x80) ? colorindex : 0); \ yuv_index = *index_ptr++ * 4; \ *yuv_y++ = yuv_palette[yuv_index++]; \ *yuv_u++ = yuv_palette[yuv_index++]; \ *yuv_v++ = yuv_palette[yuv_index]; \ *index_ptr -= ((old_data & 0x40) ? colorindex : 0); \ *index_ptr += ((new_data & 0x40) ? colorindex : 0); \ yuv_index = *index_ptr++ * 4; \ *yuv_y++ = yuv_palette[yuv_index++]; \ *yuv_u++ = yuv_palette[yuv_index++]; \ *yuv_v++ = yuv_palette[yuv_index]; \ *index_ptr -= ((old_data & 0x20) ? colorindex : 0); \ *index_ptr += ((new_data & 0x20) ? colorindex : 0); \ yuv_index = *index_ptr++ * 4; \ *yuv_y++ = yuv_palette[yuv_index++]; \ *yuv_u++ = yuv_palette[yuv_index++]; \ *yuv_v++ = yuv_palette[yuv_index]; \ *index_ptr -= ((old_data & 0x10) ? colorindex : 0); \ *index_ptr += ((new_data & 0x10) ? colorindex : 0); \ yuv_index = *index_ptr++ * 4; \ *yuv_y++ = yuv_palette[yuv_index++]; \ *yuv_u++ = yuv_palette[yuv_index++]; \ *yuv_v++ = yuv_palette[yuv_index]; \ *index_ptr -= ((old_data & 0x08) ? colorindex : 0); \ *index_ptr += ((new_data & 0x08) ? colorindex : 0); \ yuv_index = *index_ptr++ * 4; \ *yuv_y++ = yuv_palette[yuv_index++]; \ *yuv_u++ = yuv_palette[yuv_index++]; \ *yuv_v++ = yuv_palette[yuv_index]; \ *index_ptr -= ((old_data & 0x04) ? colorindex : 0); \ *index_ptr += ((new_data & 0x04) ? colorindex : 0); \ yuv_index = *index_ptr++ * 4; \ *yuv_y++ = yuv_palette[yuv_index++]; \ *yuv_u++ = yuv_palette[yuv_index++]; \ *yuv_v++ = yuv_palette[yuv_index]; \ *index_ptr -= ((old_data & 0x02) ? colorindex : 0); \ *index_ptr += ((new_data & 0x02) ? colorindex : 0); \ yuv_index = *index_ptr++ * 4; \ *yuv_y++ = yuv_palette[yuv_index++]; \ *yuv_u++ = yuv_palette[yuv_index++]; \ *yuv_v++ = yuv_palette[yuv_index]; \ *index_ptr -= ((old_data & 0x01) ? colorindex : 0); \ *index_ptr += ((new_data & 0x01) ? colorindex : 0); \ yuv_index = *index_ptr * 4; \ *yuv_y = yuv_palette[yuv_index++]; \ *yuv_u = yuv_palette[yuv_index++]; \ *yuv_v = yuv_palette[yuv_index]; \ old_data = new_data; \ } #define IFF_REPLACE_SHORT_SIMPLE(ptr_s, old_data_s, new_data_s, colorindexx_s ) { \ uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ uint8_t *xold_data = (uint8_t *)old_data_s; \ uint8_t *xnew_data = (uint8_t *)new_data_s; \ IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_s ); \ } #define IFF_REPLACE_SHORT(ptr_s, yuvy_s, yuvu_s, yuvv_s, yuv_palette_s, old_data_s, new_data_s, colorindexx_s ) { \ uint8_t *xindex_ptr = (uint8_t *)ptr_s; \ uint8_t *xold_data = (uint8_t *)old_data_s; \ uint8_t *xnew_data = (uint8_t *)new_data_s; \ uint8_t *xyuv_y = yuvy_s; \ uint8_t *xyuv_u = yuvu_s; \ uint8_t *xyuv_v = yuvv_s; \ IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ xyuv_y += 8; \ xyuv_u += 8; \ xyuv_v += 8; \ IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_s, *xold_data, *xnew_data, colorindexx_s ); \ } #define IFF_REPLACE_LONG_SIMPLE(ptr_l, old_data_l, new_data_l, colorindexx_l ) { \ uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ uint8_t *xold_data = (uint8_t *)old_data_l; \ uint8_t *xnew_data = (uint8_t *)new_data_l; \ IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ IFF_REPLACE_BYTE_SIMPLE(xindex_ptr, *xold_data, *xnew_data, colorindexx_l ); \ } #define IFF_REPLACE_LONG(ptr_l, yuvy_l, yuvu_l, yuvv_l, yuv_palette_l, old_data_l, new_data_l, colorindexx_l ) { \ uint8_t *xindex_ptr = (uint8_t *)ptr_l; \ uint8_t *xold_data = (uint8_t *)old_data_l; \ uint8_t *xnew_data = (uint8_t *)new_data_l; \ uint8_t *xyuv_y = yuvy_l; \ uint8_t *xyuv_u = yuvu_l; \ uint8_t *xyuv_v = yuvv_l; \ IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ xyuv_y += 8; \ xyuv_u += 8; \ xyuv_v += 8; \ IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ xyuv_y += 8; \ xyuv_u += 8; \ xyuv_v += 8; \ IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ xindex_ptr += 8; \ xold_data++; \ xnew_data++; \ xyuv_y += 8; \ xyuv_u += 8; \ xyuv_v += 8; \ IFF_REPLACE_BYTE(xindex_ptr, xyuv_y, xyuv_u, xyuv_v, yuv_palette_l, *xold_data, *xnew_data, colorindexx_l ); \ } typedef struct bitplane_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; /* these are traditional variables in a video decoder object */ uint64_t video_step; /* frame duration in pts units */ int decoder_ok; /* current decoder status */ int skipframes; /* 0 = draw picture, 1 = skip it */ int framenumber; unsigned char *buf; /* the accumulated buffer data */ int bufsize; /* the maximum size of buf */ int size; /* the current size of buf */ int size_uk; /* size of unkompressed bitplane */ int width; /* the width of a video frame */ int height; /* the height of a video frame */ int num_pixel; /* number pixel */ double ratio; /* the width to height ratio */ int bytes_per_pixel; int num_bitplanes; int camg_mode; int is_ham; unsigned char yuv_palette[256 * 4]; unsigned char rgb_palette[256 * 4]; yuv_planes_t yuv_planes; yuv_planes_t yuv_planes_hist; uint8_t *buf_uk; /* uncompressed buffer */ uint8_t *buf_uk_hist; /* uncompressed buffer historic */ uint8_t *index_buf; /* index buffer (for indexed pics) */ uint8_t *index_buf_hist;/* index buffer historic */ } bitplane_decoder_t; /* create a new buffer and decde a byterun1 decoded buffer into it */ static uint8_t *bitplane_decode_byterun1 (uint8_t *compressed, int size_compressed, int size_uncompressed) { /* BytRun1 decompression */ int pixel_ptr = 0; int i = 0; int j = 0; uint8_t *uncompressed = calloc(1, size_uncompressed ); if (!uncompressed) return NULL; while ( i < size_compressed && pixel_ptr < size_uncompressed ) { if( compressed[i] <= 127 ) { j = compressed[i++]; if( (i+j) > size_compressed ) { free(uncompressed); return NULL; } for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { uncompressed[pixel_ptr++] = compressed[i++]; } } else if ( compressed[i] > 128 ) { j = 256 - compressed[i++]; if( i >= size_compressed ) { free(uncompressed); return NULL; } for( ; (j >= 0) && (pixel_ptr < size_uncompressed); j-- ) { uncompressed[pixel_ptr++] = compressed[i]; } i++; } } return uncompressed; } /* create a new buffer with "normal" index or rgb numbers out of a bitplane */ static void bitplane_decode_bitplane (uint8_t *bitplane_buffer, uint8_t *index_buf, int width, int height, int num_bitplanes, int bytes_per_pixel ) { int rowsize = width / 8; int pixel_ptr = 0; int row_ptr = 0; int palette_index = 0; int i = 0; int j = 0; int row_i = 0; int row_j = 0; int palette_offset = 0; int palette_index_rowsize = 0; uint8_t color = 0; uint8_t data = 0; int bytes_per_pixel_8 = bytes_per_pixel * 8; int rowsize_num_bitplanes = rowsize * num_bitplanes; int width_bytes_per_pixel = width * bytes_per_pixel; for (i = 0; i < (height * width_bytes_per_pixel); index_buf[i++] = 0); /* decode Bitplanes to RGB/Index Numbers */ for (row_ptr = 0; row_ptr < height; row_ptr++) { row_i = row_ptr * width_bytes_per_pixel; row_j = row_ptr * rowsize_num_bitplanes; for (palette_index = 0; palette_index < num_bitplanes; palette_index++) { palette_offset = ((palette_index > 15) ? 2 : (palette_index > 7) ? 1 : 0); color = bitplainoffeset[palette_index]; palette_index_rowsize = palette_index * rowsize; for (pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { i = row_i + (pixel_ptr * bytes_per_pixel_8) + palette_offset; j = row_j + palette_index_rowsize + pixel_ptr; data = bitplane_buffer[j]; index_buf[i] += ((data & 0x80) ? color : 0); i += bytes_per_pixel; index_buf[i] += ((data & 0x40) ? color : 0); i += bytes_per_pixel; index_buf[i] += ((data & 0x20) ? color : 0); i += bytes_per_pixel; index_buf[i] += ((data & 0x10) ? color : 0); i += bytes_per_pixel; index_buf[i] += ((data & 0x08) ? color : 0); i += bytes_per_pixel; index_buf[i] += ((data & 0x04) ? color : 0); i += bytes_per_pixel; index_buf[i] += ((data & 0x02) ? color : 0); i += bytes_per_pixel; index_buf[i] += ((data & 0x01) ? color : 0); } } } } /* create Buffer decode HAM6 and HAM8 to YUV color */ static void bitplane_decode_ham (uint8_t *ham_buffer, yuv_planes_t *yuv_planes, int width, int height, int num_bitplanes, int bytes_per_pixel, unsigned char *rgb_palette ) { uint8_t *ham_buffer_work = ham_buffer; uint8_t *ham_buffer_end = &ham_buffer[(width * height)]; uint8_t *yuv_ptr_y = yuv_planes->y; uint8_t *yuv_ptr_u = yuv_planes->u; uint8_t *yuv_ptr_v = yuv_planes->v; int i = 0; int j = 0; uint8_t r = 0; uint8_t g = 0; uint8_t b = 0; /* position of special HAM-Bits differs in HAM6 and HAM8, detect them */ int hambits = num_bitplanes > 6 ? 6 : 4; /* the other bits contain the real data, dreate a mask out of it */ int maskbits = 8 - hambits; int mask = ( 1 << hambits ) - 1; (void)bytes_per_pixel; for(; ham_buffer_work < ham_buffer_end; j = *ham_buffer_work++) { i = (j & mask); switch ( j >> hambits ) { case HAMBITS_CMAP: /* Take colors from palette */ r = rgb_palette[i * 4 + 0]; g = rgb_palette[i * 4 + 1]; b = rgb_palette[i * 4 + 2]; break; case HAMBITS_BLUE: /* keep red and green and modify blue */ b = i << maskbits; b |= b >> hambits; break; case HAMBITS_RED: /* keep green and blue and modify red */ r = i << maskbits; r |= r >> hambits; break; case HAMBITS_GREEN: /* keep red and blue and modify green */ g = i << maskbits; g |= g >> hambits; break; default: break; } *yuv_ptr_y++ = COMPUTE_Y(r, g, b); *yuv_ptr_u++ = COMPUTE_U(r, g, b); *yuv_ptr_v++ = COMPUTE_V(r, g, b); } } /* decoding method 3 */ static void bitplane_sdelta_opt_3 (bitplane_decoder_t *this) { uint32_t rowsize = this->width / 16; uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; uint32_t palette_index = 0; uint32_t *deltadata = (uint32_t *)this->buf; uint16_t *ptr = NULL; uint16_t *planeptr = NULL; uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); uint16_t *data = NULL; uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); uint16_t *rowworkptr = NULL; int16_t s = 0; int16_t size = 0; uint32_t pixel_ptr_bit = 0; uint32_t row_ptr = 0; uint32_t yuv_index = 0; /* Repeat for each plane */ for (palette_index = 0; (int32_t)palette_index < this->num_bitplanes; palette_index++) { planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); /* data starts at beginn of delta-Buffer + offset of the first */ /* 32 Bit long word in the buffer. The buffer starts with 8 */ /* of this Offset, for every bitplane (max 8) one */ data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); if( data != (uint16_t *)this->buf ) { /* This 8 Pointers are followd by another 8 */ ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); /* in this case, I think big/little endian is not important ;-) */ while( *data != 0xFFFF) { row_ptr = 0; size = _X_BE_16(data); data++; if( size >= 0 ) { rowworkptr = planeptr + size; pixel_ptr_bit = size * 16; if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } data++; } else { size = 0 - size + 2; rowworkptr = planeptr + size; pixel_ptr_bit = size * 16; s = _X_BE_16(data); data++; while( s--) { if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[pixel_ptr_bit], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[pixel_ptr_bit], &this->yuv_planes.y[pixel_ptr_bit], &this->yuv_planes.u[pixel_ptr_bit], &this->yuv_planes.v[pixel_ptr_bit], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } rowworkptr++; data++; } } size = _X_BE_16(ptr); ptr++; if (size < 0) { for (s = size; s < 0; s++) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } rowworkptr += rowsize_all_planes; row_ptr++; } data++; } else { for (s = 0; s < size; s++) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } data++; rowworkptr += rowsize_all_planes; row_ptr++; } } } } } } /* decoding method 4 */ static void bitplane_set_dlta_short (bitplane_decoder_t *this) { uint32_t rowsize = this->width / 16; uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; uint32_t palette_index = 0; uint32_t *deltadata = (uint32_t *)this->buf; uint16_t *ptr = NULL; uint16_t *planeptr = NULL; uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); uint16_t *data = NULL; uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); uint16_t *rowworkptr = NULL; int16_t s = 0; int16_t size = 0; uint16_t pixel_ptr = 0; uint32_t pixel_ptr_bit = 0; uint32_t row_ptr = 0; uint32_t yuv_index = 0; /* Repeat for each plane */ for (palette_index = 0; (int32_t)palette_index < this->num_bitplanes; palette_index++) { planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); /* data starts at beginn of delta-Buffer + offset of the first */ /* 32 Bit long word in the buffer. The buffer starts with 8 */ /* of this Offset, for every bitplane (max 8) one */ data = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[palette_index])]); if( data != (uint16_t *)this->buf ) { /* This 8 Pointers are followd by another 8 */ ptr = (uint16_t *)(&this->buf[_X_BE_32(&deltadata[(palette_index+8)])]); /* in this case, I think big/little endian is not important ;-) */ while( *ptr != 0xFFFF) { pixel_ptr = _X_BE_16(ptr); pixel_ptr_bit = pixel_ptr * 16; row_ptr = 0; rowworkptr = planeptr + pixel_ptr; ptr++; size = _X_BE_16(ptr); ptr++; if (size < 0) { for (s = size; s < 0; s++) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } rowworkptr += rowsize_all_planes; row_ptr++; } data++; } else { for (s = 0; s < size; s++) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } data++; rowworkptr += rowsize_all_planes; row_ptr++; } } } } } } /* decoding method 5 */ static void bitplane_dlta_5 (bitplane_decoder_t *this) { uint32_t rowsize = this->width / 8; uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; uint32_t yuv_index = 0; uint32_t delta_offset = 0; uint32_t palette_index = 0; uint32_t pixel_ptr = 0; uint32_t pixel_ptr_bit = 0; uint32_t row_ptr = 0; uint32_t *deltadata = (uint32_t *)this->buf; uint8_t *planeptr = NULL; uint8_t *rowworkptr = NULL; uint8_t *picture_end = this->buf_uk + (rowsize_all_planes * this->height); uint8_t *data = NULL; uint8_t *data_end = this->buf + this->size; uint8_t op_count = 0; uint8_t op = 0; uint8_t count = 0; /* Repeat for each plane */ for (palette_index = 0; (int32_t)palette_index < this->num_bitplanes; palette_index++) { planeptr = &this->buf_uk[(palette_index * rowsize)]; /* data starts at beginn of delta-Buffer + offset of the first */ /* 32 Bit long word in the buffer. The buffer starts with 8 */ /* of this Offset, for every bitplane (max 8) one */ delta_offset = _X_BE_32(&deltadata[palette_index]); if (delta_offset > 0) { data = this->buf + delta_offset; for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { rowworkptr = planeptr + pixel_ptr; pixel_ptr_bit = pixel_ptr * 8; row_ptr = 0; /* execute ops */ for( op_count = *data++; op_count; op_count--) { op = *data++; if (op & 0x80) { /* Uniq ops */ count = op & 0x7f; /* get count */ while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], *rowworkptr, *data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_BYTE( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, *rowworkptr, *data, bitplainoffeset[palette_index] ); } data++; rowworkptr += rowsize_all_planes; row_ptr++; } } else { if (op == 0) { /* Same ops */ count = *data++; while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_BYTE_SIMPLE(&this->index_buf[yuv_index], *rowworkptr, *data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_BYTE( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, *rowworkptr, *data, bitplainoffeset[palette_index] ); } rowworkptr += rowsize_all_planes; row_ptr++; } data++; } else { /* Skip ops */ rowworkptr += (rowsize_all_planes * op); row_ptr += op; } } } } } } } /* decoding method 7 (short version) */ static void bitplane_dlta_7_short (bitplane_decoder_t *this) { uint32_t rowsize = this->width / 16; uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; uint32_t yuv_index = 0; uint32_t opcode_offset = 0; uint32_t data_offset = 0; uint32_t palette_index = 0; uint32_t pixel_ptr = 0; uint32_t pixel_ptr_bit = 0; uint32_t row_ptr = 0; uint32_t *deltadata = (uint32_t *)this->buf; uint8_t *planeptr = NULL; uint16_t *rowworkptr = NULL; uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); uint16_t *data = NULL; uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); uint8_t *op_ptr = NULL; uint8_t op_count = 0; uint8_t op = 0; uint8_t count = 0; /* Repeat for each plane */ for (palette_index = 0; (int32_t)palette_index < this->num_bitplanes; palette_index++) { planeptr = &this->buf_uk[(palette_index * rowsize * 2)]; /* find opcode and data offset (up to 8 pointers, one for every bitplane */ opcode_offset = _X_BE_32(&deltadata[palette_index]); data_offset = _X_BE_32(&deltadata[palette_index + 8]); if (opcode_offset > 0 && data_offset > 0) { data = (uint16_t *)(&this->buf[data_offset]); op_ptr = this->buf + opcode_offset; for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { rowworkptr = (uint16_t *)(&planeptr[pixel_ptr * 2]); pixel_ptr_bit = pixel_ptr * 16; row_ptr = 0; /* execute ops */ for( op_count = *op_ptr++; op_count; op_count--) { op = *op_ptr++; if (op & 0x80) { /* Uniq ops */ count = op & 0x7f; /* get count */ while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } data++; rowworkptr += rowsize_all_planes; row_ptr++; } } else { if (op == 0) { /* Same ops */ count = *op_ptr++; while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } rowworkptr += rowsize_all_planes; row_ptr++; } data++; } else { /* Skip ops */ rowworkptr += (rowsize_all_planes * op); row_ptr += op; } } } } } } } /* decoding method 7 (long version) */ static void bitplane_dlta_7_long (bitplane_decoder_t *this) { uint32_t rowsize = this->width / 32; uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; uint32_t yuv_index = 0; uint32_t opcode_offset = 0; uint32_t data_offset = 0; uint32_t palette_index = 0; uint32_t pixel_ptr = 0; uint32_t pixel_ptr_bit = 0; uint32_t row_ptr = 0; uint32_t *deltadata = (uint32_t *)this->buf; uint8_t *planeptr = NULL; uint32_t *rowworkptr = NULL; uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); uint32_t *data = NULL; uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); uint8_t *op_ptr = NULL; uint8_t op_count = 0; uint8_t op = 0; uint8_t count = 0; /* Repeat for each plane */ for (palette_index = 0; (int32_t)palette_index < this->num_bitplanes; palette_index++) { planeptr = &this->buf_uk[(palette_index * rowsize * 4)]; /* find opcode and data offset (up to 8 pointers, one for every bitplane */ opcode_offset = _X_BE_32(&deltadata[palette_index]); data_offset = _X_BE_32(&deltadata[palette_index + 8]); if (opcode_offset > 0 && data_offset > 0) { data = (uint32_t *)(&this->buf[data_offset]); op_ptr = this->buf + opcode_offset; for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { rowworkptr = (uint32_t *)(&planeptr[pixel_ptr * 4]); pixel_ptr_bit = pixel_ptr * 32; row_ptr = 0; /* execute ops */ for( op_count = *op_ptr++; op_count; op_count--) { op = *op_ptr++; if (op & 0x80) { /* Uniq ops */ count = op & 0x7f; /* get count */ while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_LONG( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } data++; rowworkptr += rowsize_all_planes; row_ptr++; } } else { if (op == 0) { /* Same ops */ count = *op_ptr++; while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_LONG( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } rowworkptr += rowsize_all_planes; row_ptr++; } data++; } else { /* Skip ops */ rowworkptr += (rowsize_all_planes * op); row_ptr += op; } } } } } } } /* decoding method 8 short */ static void bitplane_dlta_8_short (bitplane_decoder_t *this) { uint32_t rowsize = this->width / 16; uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; uint32_t yuv_index = 0; uint32_t delta_offset = 0; uint32_t palette_index = 0; uint32_t pixel_ptr = 0; uint32_t row_ptr = 0; uint32_t pixel_ptr_bit = 0; uint32_t *deltadata = (uint32_t *)this->buf; uint16_t *planeptr = NULL; uint16_t *rowworkptr = NULL; uint16_t *picture_end = (uint16_t *)(&this->buf_uk[(rowsize_all_planes * 2 * this->height)]); uint16_t *data = NULL; uint16_t *data_end = (uint16_t *)(&this->buf[this->size]); uint16_t op_count = 0; uint16_t op = 0; uint16_t count = 0; /* Repeat for each plane */ for (palette_index = 0; (int32_t)palette_index < this->num_bitplanes; palette_index++) { planeptr = (uint16_t *)(&this->buf_uk[(palette_index * rowsize * 2)]); /* data starts at beginn of delta-Buffer + offset of the first */ /* 32 Bit long word in the buffer. The buffer starts with 8 */ /* of this Offset, for every bitplane (max 8) one */ delta_offset = _X_BE_32(&deltadata[palette_index]); if (delta_offset > 0) { data = (uint16_t *)(&this->buf[delta_offset]); for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { rowworkptr = planeptr + pixel_ptr; pixel_ptr_bit = pixel_ptr * 16; row_ptr = 0; /* execute ops */ op_count = _X_BE_16(data); data++; for( ; op_count; op_count--) { op = _X_BE_16(data); data++; if (op & 0x8000) { /* Uniq ops */ count = op & 0x7fff; /* get count */ while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } data++; rowworkptr += rowsize_all_planes; row_ptr++; } } else { if (op == 0) { /* Same ops */ count = _X_BE_16(data); data++; while(count--) { if (data > data_end || rowworkptr > picture_end) return; yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_SHORT_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_SHORT( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } rowworkptr += rowsize_all_planes; row_ptr++; } data++; } else { /* Skip ops */ rowworkptr += (rowsize_all_planes * op); row_ptr += op; } } } } } } } /* decoding method 8 long */ static void bitplane_dlta_8_long (bitplane_decoder_t *this) { uint32_t rowsize = this->width / 32; uint32_t rowsize_all_planes = rowsize * this->num_bitplanes; uint32_t yuv_index = 0; uint32_t delta_offset = 0; uint32_t palette_index = 0; uint32_t pixel_ptr = 0; uint32_t pixel_ptr_bit = 0; uint32_t row_ptr = 0; uint32_t *deltadata = (uint32_t *)this->buf; uint32_t *planeptr = NULL; uint32_t *rowworkptr = NULL; uint32_t *picture_end = (uint32_t *)(&this->buf_uk[(rowsize_all_planes * 4 * this->height)]); uint32_t *data = NULL; uint32_t *data_end = (uint32_t *)(&this->buf[this->size]); uint32_t op_count = 0; uint32_t op = 0; uint32_t count = 0; /* Repeat for each plane */ for (palette_index = 0; (int32_t)palette_index < this->num_bitplanes; palette_index++) { planeptr = (uint32_t *)(&this->buf_uk[(palette_index * rowsize * 4)]); /* data starts at beginn of delta-Buffer + offset of the first */ /* 32 Bit long word in the buffer. The buffer starts with 8 */ /* of this Offset, for every bitplane (max 8) one */ delta_offset = _X_BE_32(&deltadata[palette_index]); if (delta_offset > 0) { data = (uint32_t *)(&this->buf[delta_offset]); for( pixel_ptr = 0; pixel_ptr < rowsize; pixel_ptr++) { rowworkptr = planeptr + pixel_ptr; pixel_ptr_bit = pixel_ptr * 32; row_ptr = 0; /* execute ops */ op_count = _X_BE_32(data); data++; for( ; op_count; op_count--) { op = _X_BE_32(data); data++; if (op & 0x80000000) { /* Uniq ops */ count = op & 0x7fffffff; /* get count */ while(count--) { if (data <= data_end || rowworkptr <= picture_end) { yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_LONG( &this->index_buf[((row_ptr * this->width) + pixel_ptr_bit)], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } } data++; rowworkptr += rowsize_all_planes; row_ptr++; } } else { if (op == 0) { /* Same ops */ count = _X_BE_32(data); data++; while(count--) { if (data <= data_end && rowworkptr <= picture_end) { yuv_index = ((row_ptr * this->width) + pixel_ptr_bit); if( this->is_ham ) { IFF_REPLACE_LONG_SIMPLE(&this->index_buf[yuv_index], rowworkptr, data, bitplainoffeset[palette_index] ); } else { IFF_REPLACE_LONG( &this->index_buf[yuv_index], &this->yuv_planes.y[yuv_index], &this->yuv_planes.u[yuv_index], &this->yuv_planes.v[yuv_index], this->yuv_palette, rowworkptr, data, bitplainoffeset[palette_index] ); } } rowworkptr += rowsize_all_planes; row_ptr++; } data++; } else { /* Skip ops */ rowworkptr += (rowsize_all_planes * op); row_ptr += op; } } } } } } /* bitplane_decode_bitplane(this->buf_uk, this->index_buf, this->width, this->height, this->num_bitplanes, 1);*/ } static void bitplane_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; xine_bmiheader *bih = 0; palette_entry_t *palette = 0; AnimHeader *anhd = NULL; int i = 0; int j = 0; unsigned char r = 0; unsigned char g = 0; unsigned char b = 0; uint8_t *buf_exchange = NULL; vo_frame_t *img = 0; /* video out frame */ /* a video decoder does not care about this flag (?) */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if ((buf->decoder_flags & BUF_FLAG_SPECIAL) && (buf->decoder_info[1] == BUF_SPECIAL_PALETTE)) { unsigned int u; palette = (palette_entry_t *)buf->decoder_info_ptr[2]; for (u = 0; u < buf->decoder_info[2]; u++) { this->yuv_palette[u * 4 + 0] = COMPUTE_Y(palette[u].r, palette[u].g, palette[u].b); this->yuv_palette[u * 4 + 1] = COMPUTE_U(palette[u].r, palette[u].g, palette[u].b); this->yuv_palette[u * 4 + 2] = COMPUTE_V(palette[u].r, palette[u].g, palette[u].b); this->rgb_palette[u * 4 + 0] = palette[u].r; this->rgb_palette[u * 4 + 1] = palette[u].g; this->rgb_palette[u * 4 + 2] = palette[u].b; } /* EHB Pictures not allways contain all 64 colors, sometimes only */ /* the first 32 are included and sometimes all 64 colors are provide,*/ /* but second 32 are only stupid dirt, so recalculate them */ if (((this->num_bitplanes == 6) && (buf->decoder_info[2] == 32)) || (this->camg_mode & CAMG_EHB)) { for (i = 32; i < 64; i++) { this->rgb_palette[i * 4 + 0] = palette[(i-32)].r / 2; this->rgb_palette[i * 4 + 1] = palette[(i-32)].g / 2; this->rgb_palette[i * 4 + 2] = palette[(i-32)].b / 2; this->yuv_palette[i * 4 + 0] = COMPUTE_Y(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); this->yuv_palette[i * 4 + 1] = COMPUTE_U(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); this->yuv_palette[i * 4 + 2] = COMPUTE_V(this->rgb_palette[i*4+0], this->rgb_palette[i*4+1], this->rgb_palette[i*4+2]); } } return; } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ (this->stream->video_out->open) (this->stream->video_out, this->stream); bih = (xine_bmiheader *) buf->content; this->width = (bih->biWidth + 15) & ~0x0f; this->height = bih->biHeight; this->num_pixel = this->width * this->height; this->ratio = (double)this->width/(double)this->height; this->video_step = buf->decoder_info[1]; /* Palette based Formates use up to 8 Bit per pixel, always use 8 Bit if less */ this->bytes_per_pixel = (bih->biBitCount + 1) / 8; if( this->bytes_per_pixel < 1 ) this->bytes_per_pixel = 1; /* New Buffer for indexes (palette based formats) */ this->index_buf = calloc( this->num_pixel, this->bytes_per_pixel ); this->index_buf_hist = calloc( this->num_pixel, this->bytes_per_pixel ); this->num_bitplanes = bih->biPlanes; this->camg_mode = bih->biCompression; if( this->camg_mode & CAMG_HAM ) this->is_ham = 1; else this->is_ham = 0; if( buf->decoder_info[2] != buf->decoder_info[3] && buf->decoder_info[3] > 0 ) { this->ratio *= buf->decoder_info[2]; this->ratio /= buf->decoder_info[3]; } if( (bih->biCompression & CAMG_HIRES) && !(bih->biCompression & CAMG_LACE) ) { if( (buf->decoder_info[2] * 16) > (buf->decoder_info[3] * 10) ) this->ratio /= 2.0; } if( !(bih->biCompression & CAMG_HIRES) && (bih->biCompression & CAMG_LACE) ) { if( (buf->decoder_info[2] * 10) < (buf->decoder_info[3] * 16) ) this->ratio *= 2.0; } free (this->buf); this->bufsize = VIDEOBUFSIZE; this->buf = calloc(1, this->bufsize); this->size = 0; this->framenumber = 0; init_yuv_planes(&this->yuv_planes, this->width, this->height); init_yuv_planes(&this->yuv_planes_hist, this->width, this->height); (this->stream->video_out->open) (this->stream->video_out, this->stream); this->decoder_ok = 1; /* load the stream/meta info */ switch( buf->type ) { case BUF_VIDEO_BITPLANE: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Uncompressed bitplane"); break; case BUF_VIDEO_BITPLANE_BR1: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "ByteRun1 bitplane"); break; default: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Unknown bitplane"); break; } return; } else if (this->decoder_ok) { this->skipframes = 0; this->framenumber++; if (this->size + buf->size > this->bufsize) { this->bufsize = this->size + 2 * buf->size; this->buf = realloc (this->buf, this->bufsize); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAMERATE) this->video_step = buf->decoder_info[0]; if (buf->decoder_flags & BUF_FLAG_FRAME_END) { img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL); if (!img) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame(%dx%d) failed\n", this->width, this->height); this->size = 0; return; } img->duration = this->video_step; img->pts = buf->pts; img->bad_frame = 0; anhd = (AnimHeader *)(buf->decoder_info_ptr[0]); if( (this->buf_uk == NULL) || (anhd == NULL) || (anhd->operation == IFF_ANHD_ILBM) ) { /* iterate through each row */ this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); if( this->buf_uk_hist != NULL ) xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); switch( buf->type ) { case BUF_VIDEO_BITPLANE: /* uncompressed Buffer, set decoded_buf pointer direct to input stream */ if( this->buf_uk == NULL ) this->buf_uk = malloc(this->size); xine_fast_memcpy (this->buf_uk, this->buf, this->size); break; case BUF_VIDEO_BITPLANE_BR1: /* create Buffer for decompressed bitmap */ this->buf_uk = bitplane_decode_byterun1( this->buf, /* compressed buffer */ this->size, /* size of compressed data */ this->size_uk ); /* size of uncompressed data */ if( this->buf_uk == NULL ) { xine_log(this->stream->xine, XINE_LOG_MSG, _("bitplane: error doing ByteRun1 decompression\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); return; } /* set pointer to decompressed Buffer */ break; default: break; } bitplane_decode_bitplane( this->buf_uk, /* bitplane buffer */ this->index_buf, /* index buffer */ this->width, /* width */ this->height, /* hight */ this->num_bitplanes, /* number bitplanes */ this->bytes_per_pixel); /* used Bytes per pixel */ if ((this->bytes_per_pixel == 1) && (this->is_ham == 0) ) { buf_exchange = this->index_buf; for (i = 0; i < (this->height * this->width); i++) { j = *buf_exchange++ * 4; this->yuv_planes.y[i] = this->yuv_palette[j++]; this->yuv_planes.u[i] = this->yuv_palette[j++]; this->yuv_planes.v[i] = this->yuv_palette[j]; } } if( this->buf_uk_hist == NULL ) { this->buf_uk_hist = malloc(this->size_uk); xine_fast_memcpy (this->buf_uk_hist, this->buf_uk, this->size_uk); xine_fast_memcpy (this->index_buf_hist, this->index_buf, (this->num_pixel * this->bytes_per_pixel)); xine_fast_memcpy (this->yuv_planes_hist.y, this->yuv_planes.y, (this->num_pixel)); xine_fast_memcpy (this->yuv_planes_hist.u, this->yuv_planes.u, (this->num_pixel)); xine_fast_memcpy (this->yuv_planes_hist.v, this->yuv_planes.v, (this->num_pixel)); } } else { /* when no start-picture is given, create a empty one */ if( this->buf_uk_hist == NULL ) { this->size_uk = (((this->num_pixel) / 8) * this->num_bitplanes); this->buf_uk = calloc(this->num_bitplanes, ((this->num_pixel) / 8)); this->buf_uk_hist = calloc(this->num_bitplanes, ((this->num_pixel) / 8)); } if( this->index_buf == NULL ) { this->index_buf = calloc( this->num_pixel, this->bytes_per_pixel ); this->index_buf_hist = calloc( this->num_pixel, this->bytes_per_pixel ); } switch( anhd->operation ) { /* also known as IFF-ANIM OPT1 (never seen in real world) */ case IFF_ANHD_XOR: xine_log(this->stream->xine, XINE_LOG_MSG, _("bitplane: Anim Opt 1 is not supported at the moment\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); return; break; /* also known as IFF-ANIM OPT2 (never seen in real world) */ case IFF_ANHD_LDELTA: xine_log(this->stream->xine, XINE_LOG_MSG, _("bitplane: Anim Opt 2 is not supported at the moment\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); return; break; /* also known as IFF-ANIM OPT3 */ case IFF_ANHD_SDELTA: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT3"); bitplane_sdelta_opt_3 ( this ); return; break; /* also known as IFF-ANIM OPT4 (never seen in real world) */ case IFF_ANHD_SLDELTA: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT4 (SLDELTA)"); bitplane_set_dlta_short ( this ); break; /* also known as IFF-ANIM OPT5 */ case IFF_ANHD_BVDELTA: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT5 (BVDELTA)"); bitplane_dlta_5(this); break; /* IFF-ANIM OPT6 is exactly the same as OPT5, but for stereo-displays */ /* first picture is on the left display, second on the right, third on */ /* the left, forth on right, ... Only display left picture on mono display*/ case IFF_ANHD_STEREOO5: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT6 (BVDELTA STEREO)"); bitplane_dlta_5(this); if( this->framenumber % 2 == 0 ) this->skipframes = 1; return; break; case IFF_ANHD_OPT7: if(anhd->bits == 0) { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (SHORT)"); bitplane_dlta_7_short(this); } else { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT7 (LONG)"); bitplane_dlta_7_long(this); } break; case IFF_ANHD_OPT8: if(anhd->bits == 0) { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (SHORT)"); bitplane_dlta_8_short(this); } else { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Anim OPT8 (LONG)"); bitplane_dlta_8_long(this); } break; case IFF_ANHD_ASCIIJ: xine_log(this->stream->xine, XINE_LOG_MSG, _("bitplane: Anim ASCIIJ is not supported at the moment\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); return; break; default: xine_log(this->stream->xine, XINE_LOG_MSG, _("bitplane: This anim-type is not supported at the moment\n")); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); return; break; } /* change old bitmap buffer (which now is the new one) with new buffer */ buf_exchange = this->buf_uk; this->buf_uk = this->buf_uk_hist; this->buf_uk_hist = buf_exchange; /* do the same with the index buffer */ buf_exchange = this->index_buf; this->index_buf = this->index_buf_hist; this->index_buf_hist = buf_exchange; /* and also with yuv buffer */ buf_exchange = this->yuv_planes.y; this->yuv_planes.y = this->yuv_planes_hist.y; this->yuv_planes_hist.y = buf_exchange; buf_exchange = this->yuv_planes.u; this->yuv_planes.u = this->yuv_planes_hist.u; this->yuv_planes_hist.u = buf_exchange; buf_exchange = this->yuv_planes.v; this->yuv_planes.v = this->yuv_planes_hist.v; this->yuv_planes_hist.v = buf_exchange; } if( this->skipframes == 0 ) { switch (this->bytes_per_pixel) { case 1: /* HAM-pictrues need special handling */ if( this->is_ham ) { /* Decode HAM-Pictures to YUV */ bitplane_decode_ham( this->index_buf, /* HAM-bitplane buffer */ &(this->yuv_planes), /* YUV buffer */ this->width, /* width */ this->height, /* hight */ this->num_bitplanes, /* number bitplanes */ this->bytes_per_pixel, /* used Bytes per pixel */ this->rgb_palette); /* Palette (RGB) */ } break; case 3: buf_exchange = this->index_buf; for (i = 0; i < (this->height * this->width); i++) { r = *buf_exchange++; g = *buf_exchange++; b = *buf_exchange++; this->yuv_planes.y[i] = COMPUTE_Y(r, g, b); this->yuv_planes.u[i] = COMPUTE_U(r, g, b); this->yuv_planes.v[i] = COMPUTE_V(r, g, b); } break; default: break; } yuv444_to_yuy2(&this->yuv_planes, img->base[0], img->pitches[0]); img->draw(img, this->stream); } img->free(img); this->size = 0; if ( buf->decoder_info[1] > 90000 ) xine_usec_sleep(buf->decoder_info[1]); } } } /* * This function is called when xine needs to flush the system. Not * sure when or if this is used or even if it needs to do anything. */ static void bitplane_flush (video_decoder_t *this_gen) { (void)this_gen; } /* * This function resets the video decoder. */ static void bitplane_reset (video_decoder_t *this_gen) { bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; this->size = 0; } static void bitplane_discontinuity (video_decoder_t *this_gen) { (void)this_gen; } /* * This function frees the video decoder instance allocated to the decoder. */ static void bitplane_dispose (video_decoder_t *this_gen) { bitplane_decoder_t *this = (bitplane_decoder_t *) this_gen; free (this->buf); free (this->buf_uk); free (this->buf_uk_hist); free (this->index_buf); free (this->index_buf_hist); if (this->decoder_ok) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this_gen); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { bitplane_decoder_t *this; (void)class_gen; this = (bitplane_decoder_t *) calloc(1, sizeof(bitplane_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = bitplane_decode_data; this->video_decoder.flush = bitplane_flush; this->video_decoder.reset = bitplane_reset; this->video_decoder.discontinuity = bitplane_discontinuity; this->video_decoder.dispose = bitplane_dispose; this->size = 0; this->stream = stream; this->decoder_ok = 0; this->buf = NULL; this->buf_uk = NULL; this->index_buf = NULL; this->index_buf = NULL; return &this->video_decoder; } void *decode_bitplane_init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_bitplane_class = { .open_plugin = open_plugin, .identifier = "bitplane", .description = N_("Raw bitplane video decoder plugin"), .dispose = NULL, }; return (void *)&decode_video_bitplane_class; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/����������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�015202� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/group_vdpau.h���������������������������������������������������0000644�0001750�0001750�00000003204�14647725152�017705� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2008-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * A group of video stream parsers using the VDPAU hardware decoder. * */ #ifndef GROUP_VDPAU_H #define GROUP_VDPAU_H 1 #include <xine/xine_internal.h> /* TJ. My vdpau.h says typedef void * VdpPictureInfo; then defines arg #3 of VdpDecoderRender () as VdpPictureInfo const * picture_info This is obviously wrong. If this should have been fixed in the meantime, change the following define to 0. */ #if 1 # define CAST_VdpPictureInfo_PTR (void *) #else # define CAST_VdpPictureInfo_PTR (VdpPictureInfo *) #endif void *h264_alter_init_plugin (xine_t *xine, const void *data); void *h264_init_plugin (xine_t *xine, const void *data); void *vc1_init_plugin (xine_t *xine, const void *data); void *mpeg12_init_plugin (xine_t *xine, const void *data); void *mpeg4_init_plugin (xine_t *xine, const void *data); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/alterh264_decode.c����������������������������������������������0000644�0001750�0001750�00000057207�14647725152�020377� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; * Copyright (C) 2008-2023 the xine project * Copyright (C) 2008 Christophe Thommeret <hftom@free.fr> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * alterh264_decode.c, a H264 video stream parser using VDPAU hardware decoder * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif //#define LOG #define LOG_MODULE "vdpau_h264" #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "accel_vdpau.h" #include <vdpau/vdpau.h> #include "group_vdpau.h" #include "vdec_hw_h264.h" typedef struct { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; vdec_hw_h264_t *vdec; VdpDecoderProfile profile; vdpau_accel_t *accel_vdpau; VdpDecoder decoder; VdpDecoderProfile decoder_profile; int vdp_runtime_nr; int decoder_width; int decoder_height; int safe_seek; int seek; double reported_ratio; int reported_video_step; int reported_width; int reported_height; int used; } vdpau_h264_alter_decoder_t; static VdpDecoderProfile vdpau_h264_map_profile (int profile_idc) { /* nvidia's vdpau doesn't suppot baseline (66), force main (77) */ return profile_idc >= 100 ? VDP_DECODER_PROFILE_H264_HIGH : VDP_DECODER_PROFILE_H264_MAIN; } static __attribute__((format (printf, 3, 4))) int vdpau_h264_alter_logg (void *user_data, vdec_hw_h264_logg_t level, const char *fmt, ...) { char b[2048]; vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *)user_data; int l2 = level == VDEC_HW_H264_LOGG_ERR ? XINE_VERBOSITY_LOG : level == VDEC_HW_H264_LOGG_INFO ? XINE_VERBOSITY_DEBUG : /* VDEC_HW_H264_LOGG_DEBUG */ XINE_VERBOSITY_DEBUG + 1; if (l2 <= this->stream->xine->verbosity) { va_list va; va_start (va, fmt); vsnprintf (b, sizeof (b), fmt, va); va_end (va); xprintf (this->stream->xine, l2, LOG_MODULE ": %s", b); return 1; } return 0; } static int vdpau_h264_alter_frame_new (void *user_data, vdec_hw_h264_frame_t *frame) { vdpau_h264_alter_decoder_t * this = (vdpau_h264_alter_decoder_t *)user_data; int flags = ((frame->flags & VDEC_HW_H264_FRAME_TOP_FIELD) ? VO_TOP_FIELD : 0) | ((frame->flags & VDEC_HW_H264_FRAME_BOTTOM_FIELD) ? VO_BOTTOM_FIELD : 0) | ((frame->flags & VDEC_HW_H264_FRAME_NEW_SEQ) ? VO_NEW_SEQUENCE_FLAG : 0); vo_frame_t *img; if (frame->user_data) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ERROR: user frame set already.\n"); return 0; } VO_SET_FLAGS_CM (frame->color_matrix, flags); frame->user_data = img = this->stream->video_out->get_frame (this->stream->video_out, frame->width, frame->height, frame->ratio, XINE_IMGFMT_VDPAU, flags); img->progressive_frame = -1; img->pts = frame->pts; img->duration = frame->duration; img->progressive_frame = frame->progressive_frame; /* try to view small errors as well. */ img->bad_frame = frame->bad_frame > 1; this->used += 1; if (this->used > 19) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": WARNING: too many frames (%d).\n", this->used); } return 1; } static int vdpau_h264_alter_int_reset (vdpau_h264_alter_decoder_t *this) { /** vdpau.h says that a ref frame * - starts being usable when it is decoded, and * - stops when it is no longer mentioned in a decode call. * lets try to misuse that for a internal reset here ;-) */ VdpPictureInfoH264 info; VdpStatus st; info.slice_count = 0; info.field_order_cnt[0] = 0; info.field_order_cnt[1] = 0; info.is_reference = VDP_FALSE; info.frame_num = 0; info.field_pic_flag = 0; info.bottom_field_flag = 0; info.num_ref_frames = 0; info.mb_adaptive_frame_field_flag = 0; info.constrained_intra_pred_flag = 0; info.weighted_pred_flag = 0; info.weighted_bipred_idc = 0; info.frame_mbs_only_flag = 0; info.transform_8x8_mode_flag = 0; info.chroma_qp_index_offset = 0; info.second_chroma_qp_index_offset = 0; info.pic_init_qp_minus26 = 0; info.num_ref_idx_l0_active_minus1 = 0; info.num_ref_idx_l1_active_minus1 = 0; info.log2_max_frame_num_minus4 = 0; info.pic_order_cnt_type = 0; info.log2_max_pic_order_cnt_lsb_minus4 = 0; info.delta_pic_order_always_zero_flag = 0; info.direct_8x8_inference_flag = 0; info.entropy_coding_mode_flag = 0; info.pic_order_present_flag = 0; info.deblocking_filter_control_present_flag = 0; info.redundant_pic_cnt_present_flag = 0; memset (info.scaling_lists_4x4, 0, sizeof (info.scaling_lists_4x4)); memset (info.scaling_lists_8x8, 0, sizeof (info.scaling_lists_8x8)); { uint32_t u; for (u = 0; u < sizeof (info.referenceFrames) / sizeof (info.referenceFrames[0]); u++) { info.referenceFrames[u].surface = VDP_INVALID_HANDLE; info.referenceFrames[u].is_long_term = 0; info.referenceFrames[u].frame_idx = 0; info.referenceFrames[u].top_is_reference = VDP_FALSE; info.referenceFrames[u].bottom_is_reference = VDP_FALSE; info.referenceFrames[u].field_order_cnt[0] = 0; info.referenceFrames[u].field_order_cnt[1] = 0; } } { VdpBitstreamBuffer vbits = { .struct_version = VDP_BITSTREAM_BUFFER_VERSION, .bitstream = NULL, .bitstream_bytes = 0, }; if (this->accel_vdpau->lock) this->accel_vdpau->lock (this->accel_vdpau->vo_frame); st = this->accel_vdpau->vdp_decoder_render (this->decoder, VDP_INVALID_HANDLE, CAST_VdpPictureInfo_PTR &info, 1, &vbits); if (this->accel_vdpau->lock) this->accel_vdpau->unlock (this->accel_vdpau->vo_frame); } return st == VDP_STATUS_OK; } static int vdpau_h264_alter_frame_render (void *user_data, vdec_hw_h264_frame_t *frame) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *)user_data; vo_frame_t *img = (vo_frame_t *)frame->user_data; vdpau_accel_t *accel; VdpPictureInfoH264 info; VdpDecoderProfile profile; VdpStatus st; if (!img) return 0; accel = (vdpau_accel_t *)img->accel_data; if (!this->accel_vdpau) this->accel_vdpau = accel; if (this->vdp_runtime_nr != *(this->accel_vdpau->current_vdp_runtime_nr)) this->decoder = VDP_INVALID_HANDLE; profile = vdpau_h264_map_profile (frame->profile); if ((this->decoder == VDP_INVALID_HANDLE) || (this->decoder_profile != profile) || (this->decoder_width != frame->width) || (this->decoder_height != frame->height)) { if (accel->lock) accel->lock (accel->vo_frame); if (this->decoder != VDP_INVALID_HANDLE) { accel->vdp_decoder_destroy (this->decoder); this->decoder = VDP_INVALID_HANDLE; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": closed decoder.\n"); } st = accel->vdp_decoder_create (accel->vdp_device, profile, frame->width, frame->height, frame->num_ref_frames, &this->decoder); if (accel->unlock) accel->unlock (accel->vo_frame); if (st != VDP_STATUS_OK) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": failed to create decoder !! %s\n", accel->vdp_get_error_string (st)); } else { this->decoder_profile = profile; this->decoder_width = frame->width; this->decoder_height = frame->height; this->vdp_runtime_nr = accel->vdp_runtime_nr; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": created decoder for %dx%d %s @#%d.\n", this->decoder_width, this->decoder_height, this->decoder_profile == VDP_DECODER_PROFILE_H264_HIGH ? "high" : "main", this->vdp_runtime_nr); } } info.slice_count = frame->info->slice_count; info.field_order_cnt[0] = frame->info->field_order_cnt[0]; info.field_order_cnt[1] = frame->info->field_order_cnt[1]; info.is_reference = frame->info->is_reference ? VDP_TRUE : VDP_FALSE; info.frame_num = frame->info->frame_num; info.field_pic_flag = frame->info->field_pic_flag; info.bottom_field_flag = frame->info->bottom_field_flag; info.num_ref_frames = frame->info->num_ref_frames; info.mb_adaptive_frame_field_flag = frame->info->mb_adaptive_frame_field_flag; info.constrained_intra_pred_flag = frame->info->constrained_intra_pred_flag; info.weighted_pred_flag = frame->info->weighted_pred_flag; info.weighted_bipred_idc = frame->info->weighted_bipred_idc; info.frame_mbs_only_flag = frame->info->frame_mbs_only_flag; info.transform_8x8_mode_flag = frame->info->transform_8x8_mode_flag; info.chroma_qp_index_offset = frame->info->chroma_qp_index_offset; info.second_chroma_qp_index_offset = frame->info->second_chroma_qp_index_offset; info.pic_init_qp_minus26 = frame->info->pic_init_qp_minus26; info.num_ref_idx_l0_active_minus1 = frame->info->num_ref_idx_l0_active_minus1; info.num_ref_idx_l1_active_minus1 = frame->info->num_ref_idx_l1_active_minus1; info.log2_max_frame_num_minus4 = frame->info->log2_max_frame_num_minus4; info.pic_order_cnt_type = frame->info->pic_order_cnt_type; info.log2_max_pic_order_cnt_lsb_minus4 = frame->info->log2_max_pic_order_cnt_lsb_minus4; info.delta_pic_order_always_zero_flag = frame->info->delta_pic_order_always_zero_flag; info.direct_8x8_inference_flag = frame->info->direct_8x8_inference_flag; info.entropy_coding_mode_flag = frame->info->entropy_coding_mode_flag; info.pic_order_present_flag = frame->info->pic_order_present_flag; info.deblocking_filter_control_present_flag = frame->info->deblocking_filter_control_present_flag; info.redundant_pic_cnt_present_flag = frame->info->redundant_pic_cnt_present_flag; xine_fast_memcpy (info.scaling_lists_4x4, frame->info->scaling_lists_4x4, sizeof (info.scaling_lists_4x4)); xine_fast_memcpy (info.scaling_lists_8x8, frame->info->scaling_lists_8x8, sizeof (info.scaling_lists_8x8)); { uint32_t u; for (u = 0; u < sizeof (info.referenceFrames) / sizeof (info.referenceFrames[0]); u++) { if (frame->info->referenceFrames[u].frame) { vo_frame_t *rimg = (vo_frame_t *)frame->info->referenceFrames[u].frame->user_data; vdpau_accel_t *accel = (vdpau_accel_t *)rimg->accel_data; info.referenceFrames[u].surface = accel->surface; } else { info.referenceFrames[u].surface = VDP_INVALID_HANDLE; } info.referenceFrames[u].is_long_term = 0; info.referenceFrames[u].frame_idx = frame->info->referenceFrames[u].frame_idx; info.referenceFrames[u].top_is_reference = frame->info->referenceFrames[u].top_is_reference ? VDP_TRUE : VDP_FALSE; info.referenceFrames[u].bottom_is_reference = frame->info->referenceFrames[u].bottom_is_reference ? VDP_TRUE : VDP_FALSE; info.referenceFrames[u].field_order_cnt[0] = frame->info->referenceFrames[u].field_order_cnt[0]; info.referenceFrames[u].field_order_cnt[1] = frame->info->referenceFrames[u].field_order_cnt[1]; } } { const uint8_t sc[3] = { 0, 0, 1 }; VdpBitstreamBuffer vbits[80 * 2]; uint32_t u, m = frame->info->slice_count < 80 ? frame->info->slice_count : 80; for (u = 0; u < m; u++) { vbits[u * 2].struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbits[u * 2].bitstream = sc; vbits[u * 2].bitstream_bytes = 3; vbits[u * 2 + 1].struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbits[u * 2 + 1].bitstream = frame->info->slices_bitstream[u]; vbits[u * 2 + 1].bitstream_bytes = frame->info->slices_bytes[u]; } if (accel->lock) accel->lock (accel->vo_frame); st = accel->vdp_decoder_render (this->decoder, accel->surface, CAST_VdpPictureInfo_PTR &info, m * 2, vbits); if (accel->unlock) accel->unlock (accel->vo_frame); } if (st != VDP_STATUS_OK) lprintf ("**********************DECODING failed! - surface = %d - %s\n", accel->surface, accel->vdp_get_error_string (st)); else lprintf ("**********************DECODING success! - surface = %d\n", accel->surface); if ((frame->ratio != this->reported_ratio) || (frame->width != this->reported_width) || (frame->height != this->reported_height) || (frame->duration != this->reported_video_step)) { xine_event_t event; xine_format_change_data_t data; this->reported_ratio = frame->ratio; this->reported_width = frame->width; this->reported_height = frame->height; this->reported_video_step = frame->duration; _x_stream_info_set (this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, frame->width); _x_stream_info_set (this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, frame->height); _x_stream_info_set (this->stream, XINE_STREAM_INFO_VIDEO_RATIO, ((double) 10000 * frame->ratio)); _x_stream_info_set (this->stream, XINE_STREAM_INFO_FRAME_DURATION, frame->duration); _x_meta_info_set_utf8 (this->stream, XINE_META_INFO_VIDEOCODEC, "H264/AVC (vdpau_alter)"); event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = this->stream; event.data = &data; event.data_length = sizeof (data); data.width = frame->width; data.height = frame->height; data.aspect = frame->ratio; xine_event_send (this->stream, &event); } return st == VDP_STATUS_OK; } static int vdpau_h264_alter_frame_ready (void *user_data, vdec_hw_h264_frame_t *frame) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *)user_data; vo_frame_t *img = (vo_frame_t *)frame->user_data; if (!img) return 0; /* the render call above is asynchroneous. it uploads frame info, and returns. * this is OK with most frames as they show "much" later. * however, first frame after seek is an exception. xine engine wants to show * the user where the seek has landed early. we dont know when that frame is * really done, so wait a fixed amount instead. */ if (this->seek) { this->seek = 0; xine_usec_sleep (10000); } img->pts = frame->pts; img->top_field_first = frame->top_field_first; img->draw (img, this->stream); return 1; } static void vdpau_h264_alter_frame_delete (void *user_data, vdec_hw_h264_frame_t *frame) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *)user_data; vo_frame_t *img = (vo_frame_t *)frame->user_data; (void)this; if (img) { img->free (img); frame->user_data = NULL; this->used -= 1; if (this->used < 0) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": WARNING: too few frames (%d).\n", this->used); } } } /* * This function receives a buffer of data from the demuxer layer and * figures out how to handle it based on its header flags. */ static void vdpau_h264_alter_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *)this_gen; if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { lprintf ("BUF_FLAG_FRAMERATE\n"); vdec_hw_h264_put_container_info (this->vdec, 0, 0, buf->decoder_info[0], 0); } if (buf->decoder_flags & BUF_FLAG_ASPECT) { lprintf ("BUF_FLAG_ASPECT\n"); vdec_hw_h264_put_container_info (this->vdec, 0, 0, 0, (double)buf->decoder_info[1] / (double) buf->decoder_info[2]); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { xine_bmiheader *bih = (xine_bmiheader *) buf->content; uint8_t *codec_private = buf->content + sizeof (xine_bmiheader); uint32_t codec_private_len = bih->biSize - sizeof (xine_bmiheader); lprintf ("BUF_FLAG_STDHEADER\n"); vdec_hw_h264_put_container_info (this->vdec, bih->biWidth, bih->biHeight, 0, 0); vdec_hw_h264_put_config (this->vdec, codec_private, codec_private_len); return; } if (buf->decoder_flags & BUF_FLAG_SPECIAL) { if (buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG) { const uint8_t *codec_private = buf->decoder_info_ptr[2]; uint32_t codec_private_len = buf->decoder_info[2]; lprintf ("BUF_SPECIAL_DECODER_CONFIG\n"); vdec_hw_h264_put_config (this->vdec, codec_private, codec_private_len); } return; } if (!buf->size) return; vdec_hw_h264_put_frame (this->vdec, buf->pts, (const uint8_t *)buf->content, buf->size, !!(buf->decoder_flags & BUF_FLAG_FRAME_END)); } /* * This function is called when xine needs to flush the system. */ static void vdpau_h264_alter_flush (video_decoder_t *this_gen) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *) this_gen; lprintf ("vdpau_h264_alter_flush\n"); vdec_hw_h264_flush (this->vdec); } /* * This function resets the video decoder. */ static void vdpau_h264_alter_reset (video_decoder_t *this_gen) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *) this_gen; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": reset.\n"); /* TJ. nvidia_bin works fine without this, buf newer radeonsi crashes * on vdp_video_mixer_render () of first new frame (or filler frame, * who knows - i cannot test that myself). */ if ((this->decoder != VDP_INVALID_HANDLE) && this->accel_vdpau) { if (this->safe_seek) { if (this->accel_vdpau->lock) this->accel_vdpau->lock (this->accel_vdpau->vo_frame); this->accel_vdpau->vdp_decoder_destroy (this->decoder); this->decoder = VDP_INVALID_HANDLE; if (this->accel_vdpau->unlock) this->accel_vdpau->unlock (this->accel_vdpau->vo_frame); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": closed decoder.\n"); } else { vdpau_h264_alter_int_reset (this); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": reset decoder.\n"); } } vdec_hw_h264_reset (this->vdec); this->seek = 1; } /* * The decoder should forget any stored pts values here. */ static void vdpau_h264_alter_discontinuity (video_decoder_t *this_gen) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *) this_gen; lprintf ("vdpau_h264_alter_discontinuity\n"); vdec_hw_h264_zero_pts (this->vdec); } /* * This function frees the video decoder instance allocated to the decoder. */ static void vdpau_h264_alter_dispose (video_decoder_t *this_gen) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *) this_gen; lprintf ("vdpau_h264_alter_dispose\n"); this->stream->xine->config->unregister_callbacks (this->stream->xine->config, NULL, NULL, this, sizeof (*this)); vdec_hw_h264_delete (&this->vdec); if ((this->decoder != VDP_INVALID_HANDLE) && this->accel_vdpau) { if (this->accel_vdpau->lock) this->accel_vdpau->lock (this->accel_vdpau->vo_frame); this->accel_vdpau->vdp_decoder_destroy (this->decoder); this->decoder = VDP_INVALID_HANDLE; if (this->accel_vdpau->unlock) this->accel_vdpau->unlock (this->accel_vdpau->vo_frame); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": closed decoder.\n"); } this->stream->video_out->close (this->stream->video_out, this->stream); free (this_gen); } static void vdpau_h264_alter_safe_seek (void *this_gen, xine_cfg_entry_t *entry) { vdpau_h264_alter_decoder_t *this = (vdpau_h264_alter_decoder_t *)this_gen; this->safe_seek = entry->num_value; } /* * This function allocates, initializes, and returns a private video * decoder structure. */ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { vdpau_h264_alter_decoder_t *this; vo_frame_t *img; vdpau_accel_t *accel; int runtime_nr; VdpDecoder decoder; VdpStatus st; vdec_hw_h264_t *vdec; (void)class_gen; /* the videoout must be vdpau-capable to support this decoder */ if (!(stream->video_out->get_capabilities (stream->video_out) & VO_CAP_VDPAU_H264)) return NULL; /* now check if vdpau has free decoder resource */ img = stream->video_out->get_frame (stream->video_out, 1920, 1080, 1, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL); if (!img) return NULL; accel = (vdpau_accel_t *)img->accel_data; runtime_nr = accel->vdp_runtime_nr; img->free (img); if (accel->lock) accel->lock (accel->vo_frame); st = accel->vdp_decoder_create (accel->vdp_device, VDP_DECODER_PROFILE_H264_MAIN, 1920, 1080, 16, &decoder); if (st != VDP_STATUS_OK) { if (accel->unlock) accel->unlock (accel->vo_frame); xprintf (stream->xine, XINE_VERBOSITY_LOG, "can't create vdpau decoder!\n"); return NULL; } accel->vdp_decoder_destroy (decoder); if (accel->unlock) accel->unlock (accel->vo_frame); this = (vdpau_h264_alter_decoder_t *)calloc (1, sizeof (*this)); if (!this) return NULL; vdec = vdec_hw_h264_new (vdpau_h264_alter_logg, this, vdpau_h264_alter_frame_new, vdpau_h264_alter_frame_render, vdpau_h264_alter_frame_ready, vdpau_h264_alter_frame_delete, stream->video_out->get_property (stream->video_out, VO_PROP_BUFS_TOTAL)); if (!vdec) { free (this); return NULL; } this->video_decoder.decode_data = vdpau_h264_alter_decode_data; this->video_decoder.flush = vdpau_h264_alter_flush; this->video_decoder.reset = vdpau_h264_alter_reset; this->video_decoder.discontinuity = vdpau_h264_alter_discontinuity; this->video_decoder.dispose = vdpau_h264_alter_dispose; this->stream = stream; this->vdec = vdec; this->safe_seek = this->stream->xine->config->register_bool (this->stream->xine->config, "video.processing.vdpau_seek_with_new_decoder", 1, _("vdpau: reopen decoder on seek"), _("Some drivers crash without this."), 10, vdpau_h264_alter_safe_seek, this); this->vdp_runtime_nr = runtime_nr; this->reported_ratio = 0.0; this->reported_video_step = 0; this->reported_width = 0; this->reported_height = 0; this->used = 0; this->decoder = VDP_INVALID_HANDLE; this->accel_vdpau = NULL; stream->video_out->open (stream->video_out, stream); this->seek = 1; return &this->video_decoder; } /* * This function allocates a private video decoder class and initializes * the class's member functions. */ void *h264_alter_init_plugin (xine_t * xine, const void *data) { static const video_decoder_class_t decode_video_vdpau_h264_alter_class = { .open_plugin = open_plugin, .identifier = "vdpau_h264_alter", .description = N_ ("Alternative H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau."), .dispose = NULL, }; (void)xine; (void)data; return (void *)&decode_video_vdpau_h264_alter_class; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/vdec_hw_bits_reader.h�������������������������������������������0000644�0001750�0001750�00000020603�14647725152�021336� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* kate: tab-indent on; indent-width 4; mixedindent off; indent-mode cstyle; remove-trailing-space on; */ /* * Copyright (C) 2008-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifndef ALTERH264_BITS_READER_H #define ALTERH264_BITS_READER_H #include <sys/types.h> #include <inttypes.h> #include <stdio.h> typedef struct { const uint32_t *read; const uint8_t *start, *end; uint32_t val, bits, oflow; } bits_reader_t; static void bits_set_buf (bits_reader_t *br, const uint8_t *buf, uint32_t len) { const union { uint32_t word; uint8_t little; } endian_is = {1}; uint32_t v; br->start = buf; br->end = buf + len; br->read = (const uint32_t *)((uintptr_t)buf & ~(uintptr_t)3); br->bits = 32 - (buf - (const uint8_t *)br->read) * 8; v = *br->read++; if (endian_is.little) v = (v >> 24) | ((v >> 8) & 0x0000ff00) | ((v << 8) & 0x00ff0000) | (v << 24); br->val = v << (32 - br->bits); br->oflow = 0; } static inline uint32_t bits_tell (bits_reader_t *br) { return ((const uint8_t *)br->read - br->start) * 8 - br->bits; } /* NOTE: mathematically, uint32_t << 32 yields 0. * however, real life truncates the shift width to 5 bits (32 == 0), * and thus has no effect. lets use some paranoia that gcc will * optimize away in most cases where width is constant. */ /** NOTE: old code bailed out when end of bitstream was reached exactly. */ static uint32_t _bits_read_slow (bits_reader_t *br, uint32_t bits) { const union { uint32_t word; uint8_t little; } endian_is = {1}; uint32_t v1, v2; int left = (br->end - (const uint8_t *)br->read) * 8; if (br->bits) { v1 = br->val >> (32 - br->bits); bits -= br->bits; v1 <<= bits; } else { v1 = 0; } if (left < 32) { if (left < (int)bits) { br->read = (const uint32_t *)(((uintptr_t)br->end + 3) & ~(uintptr_t)3); br->bits = 0; br->oflow = 1; return 0; } } else { left = 32; } v2 = *br->read++; if (endian_is.little) v2 = (v2 >> 24) | ((v2 >> 8) & 0x0000ff00) | ((v2 << 8) & 0x00ff0000) | (v2 << 24); /* bits > 0 is sure here. */ v1 |= v2 >> (32 - bits); br->val = v2 << bits; br->bits = left - bits; return v1; } /** bits <= 32 */ static inline uint32_t bits_read (bits_reader_t *br, const uint32_t bits) { uint32_t v; if (!bits) return 0; if (br->bits >= bits) { v = br->val >> (32 - bits); br->val <<= bits; br->bits -= bits; return v; } return _bits_read_slow (br, bits); } static void _bits_skip_slow (bits_reader_t *br, uint32_t bits) { const union { uint32_t word; uint8_t little; } endian_is = {1}; uint32_t v2; int left = (br->end - (const uint8_t *)br->read) * 8; bits -= br->bits; left -= bits; if (left < 0) { br->read = (const uint32_t *)(((uintptr_t)br->end + 3) & ~(uintptr_t)3); br->bits = 0; br->oflow = 1; return; } br->read += bits >> 5; v2 = *br->read++; if (endian_is.little) v2 = (v2 >> 24) | ((v2 >> 8) & 0x0000ff00) | ((v2 << 8) & 0x00ff0000) | (v2 << 24); bits &= 31; br->val = v2 << bits; br->bits = (left >= 32 ? 32 : left) - bits; } /** bits unlimited */ static inline void bits_skip (bits_reader_t *br, const uint32_t bits) { if (!bits) return; if (br->bits >= bits) { br->val <<= bits; br->bits -= bits; } else { _bits_skip_slow (br, bits); } } /* needing this func at all is a nasty kludge. * h.264 PPS has an optional extension that has been added without defining * a presence flag earlier... */ /** how many bits are left from here to the last "1"? NOTE: old code was off by -1. */ static uint32_t bits_valid_left (bits_reader_t *br) { static const uint32_t mask[4] = {0x00000000, 0xff000000, 0xffff0000, 0xffffff00}; const union { uint32_t word; uint8_t little; } endian_is = {1}; uint32_t v; int n; do { /* search yet unread bits for last "1". */ if ((const uint8_t *)br->read < br->end) { const uint32_t *p = (const uint32_t *)((uintptr_t)br->end & ~(uintptr_t)3); n = br->end - (const uint8_t *)p; if (n > 0) { v = *p; if (endian_is.little) v = (v >> 24) | ((v >> 8) & 0x0000ff00) | ((v << 8) & 0x00ff0000) | (v << 24); v &= mask[n]; } else { v = 0; } while (!v && (p > br->read)) { v = *--p; if (endian_is.little) v = (v >> 24) | ((v >> 8) & 0x0000ff00) | ((v << 8) & 0x00ff0000) | (v << 24); } n = (p - br->read) * 32 + br->bits; if (v) break; } /* well, only value cache is left to test. */ if (!br->bits) return 0; /* for performance, we dont end mask br->val generally. */ n = 32 - br->bits; v = br->val >> n << n; n = 0; } while (0); while (v) n++, v <<= 1; return n; } static uint32_t bits_exp_ue (bits_reader_t * br) { const union { uint32_t word; uint8_t little; } endian_is = {1}; uint32_t size; /* count leading 0 bits */ if (br->bits && br->val) { uint32_t v1 = br->val; size = 0; while (!(v1 & 0x80000000)) v1 <<= 1, size++; br->val = v1; br->bits -= size; } else { int left = (br->end - (const uint8_t *)br->read) * 8; uint32_t v2, rest; if (left <= 0) { br->read = (const uint32_t *)(((uintptr_t)br->end + 3) & ~(uintptr_t)3); br->bits = 0; br->oflow = 1; return 0; } size = br->bits; rest = 32 - size; if (rest > (uint32_t)left) rest = left; v2 = *br->read++; if (endian_is.little) v2 = (v2 >> 24) | ((v2 >> 8) & 0x0000ff00) | ((v2 << 8) & 0x00ff0000) | (v2 << 24); if (v2 & (0xffffffff << (32 - rest))) { while (!(v2 & 0x80000000)) v2 <<= 1, size++; } else { v2 <<= rest; size += rest; } br->val = v2; br->bits = (left > 32 ? 32 : left) + br->bits - size; } /* get sized value */ size++; if (br->bits >= size) { uint32_t res = br->val >> (32 - size); br->val <<= size; br->bits -= size; return res - 1; } else { uint32_t v2, res; int left = (br->end - (const uint8_t *)br->read) * 8; size -= br->bits; if (left < (int)size) { br->read = (const uint32_t *)(((uintptr_t)br->end + 3) & ~(uintptr_t)3); br->bits = 0; br->oflow = 1; return 0; } res = br->bits ? br->val >> (32 - br->bits) : 0; v2 = *br->read++; if (endian_is.little) v2 = (v2 >> 24) | ((v2 >> 8) & 0x0000ff00) | ((v2 << 8) & 0x00ff0000) | (v2 << 24); res = (res << size) + (v2 >> (32 - size)); br->val = v2 << size; br->bits = (left > 32 ? 32 : left) - size; return res - 1; } } static inline int32_t bits_exp_se (bits_reader_t * br) { uint32_t res = bits_exp_ue (br); return (res & 1) ? (int32_t)((res + 1) >> 1) : -(int32_t)(res >> 1); } #ifdef TEST_THIS_FILE # include <stdio.h> int main (int argc, char **argv) { static const uint8_t test[] = "\x75\x99\xfb\x07\x55\xd8\xff\x23\x11\xab\xa8"; bits_reader_t br; unsigned int v1, v2, v3, v4, v5, v6, v7, v8, v9, m; (void)argc; (void)argv; bits_set_buf (&br, test + 1, sizeof (test) - 1); bits_skip (&br, 1); v1 = bits_read (&br, 3); v2 = bits_read (&br, 7); v3 = bits_read (&br, 5); bits_skip (&br, 8); v4 = bits_read (&br, 8); bits_skip (&br, 7); v5 = bits_read (&br, 1); m = bits_valid_left (&br); v6 = bits_read (&br, 12); v7 = bits_read (&br, 4); v8 = bits_read (&br, 23); v9 = bits_read (&br, 9); printf ("%s\n", __FILE__); printf ("(1) 3 7 5 (8) 8 (7) 1 12 4 23 9\n"); printf ("--- %08x %08x %08x --- %08x --- %08x %08x %08x %08x %08x\n", v1, v2, v3, v4, v5, v6, v7, v8, v9); printf ("more: %08x\n", m); return 0; } #endif #endif /* ALTERH264_BITS_READER_H */ �����������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/vdec_hw_h264.h��������������������������������������������������0000644�0001750�0001750�00000012233�14647725152�017536� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* kate: tab-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; */ /* * Copyright (C) 2008-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * h264.h, a generic H264 video stream parser for VDPAU and VAAPI hardware decoders */ #ifndef VDEC_HW_H264_H #define VDEC_HW_H264_H #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include <sys/types.h> typedef struct vdec_hw_h264_s vdec_hw_h264_t; typedef struct vdec_hw_h264_frame_info_s vdec_hw_h264_frame_info_t; typedef struct { void *user_data; vdec_hw_h264_t *vdec; int profile; int level; int width; int height; double ratio; int64_t pts; /** << reordered from vdec_hw_info_h264_put_frame () */ int duration; /** << in pts */ #define VDEC_HW_H264_FRAME_TOP_FIELD 1 #define VDEC_HW_H264_FRAME_BOTTOM_FIELD 2 #define VDEC_HW_H264_FRAME_NEW_SEQ 4 int flags; int bad_frame; /** 0 (OK), 1 (may be distorted by missing ref frames), 2 (decode error). */ int progressive_frame; int top_field_first; int color_matrix; /** << (MPEG matrix # << 1) | fullrange */ int num_ref_frames; const vdec_hw_h264_frame_info_t *info; } vdec_hw_h264_frame_t; typedef struct { vdec_hw_h264_frame_t *frame; int is_long_term; int top_is_reference; int bottom_is_reference; int32_t field_order_cnt[2]; uint16_t frame_idx; } vdec_hw_h264_info_ref_frame_t; struct vdec_hw_h264_frame_info_s { const uint8_t * const *slices_bitstream; const uint32_t *slices_bytes; uint32_t slice_count; int32_t field_order_cnt[2]; int is_reference; uint16_t frame_num; uint8_t field_pic_flag; uint8_t bottom_field_flag; uint8_t num_ref_frames; uint8_t gaps_in_frame_num_value_allowed_flag; uint8_t mb_adaptive_frame_field_flag; uint8_t constrained_intra_pred_flag; uint8_t weighted_pred_flag; uint8_t weighted_bipred_idc; uint8_t frame_mbs_only_flag; uint8_t transform_8x8_mode_flag; uint8_t chroma_format_idc; uint8_t separate_colour_plane_flag; uint8_t bit_depth_luma_minus8; uint8_t bit_depth_chroma_minus8; int8_t chroma_qp_index_offset; int8_t second_chroma_qp_index_offset; int8_t pic_init_qp_minus26; int8_t pic_init_qs_minus26; uint8_t num_ref_idx_l0_active_minus1; uint8_t num_ref_idx_l1_active_minus1; uint8_t log2_max_frame_num_minus4; uint8_t pic_order_cnt_type; uint8_t log2_max_pic_order_cnt_lsb_minus4; uint8_t delta_pic_order_always_zero_flag; uint8_t direct_8x8_inference_flag; uint8_t entropy_coding_mode_flag; uint8_t pic_order_present_flag; uint8_t deblocking_filter_control_present_flag; uint8_t redundant_pic_cnt_present_flag; uint8_t num_slice_groups_minus1; uint8_t slice_group_map_type; uint8_t scaling_lists_4x4[6][16]; uint8_t scaling_lists_8x8[2][64]; vdec_hw_h264_info_ref_frame_t referenceFrames[16]; }; typedef enum { VDEC_HW_H264_LOGG_ERR = 0, VDEC_HW_H264_LOGG_INFO, VDEC_HW_H264_LOGG_DEBUG } vdec_hw_h264_logg_t; vdec_hw_h264_t *vdec_hw_h264_new ( int __attribute__((format (printf, 3, 4))) (*logg) (void *user_data, vdec_hw_h264_logg_t level, const char *fmt, ...), /** << can be NULL */ void *user_data, /** << passed to logg () and frame_* () verbatim */ int (*frame_new) (void *user_data, vdec_hw_h264_frame_t *frame), /** << get user part of this frame */ int (*frame_render) (void *user_data, vdec_hw_h264_frame_t *frame), /** << perform hw decoding based on info */ int (*frame_ready) (void *user_data, vdec_hw_h264_frame_t *frame), /** << put this frame to output queue */ void (*frame_delete) (void *user_data, vdec_hw_h264_frame_t *frame), /** << unref/free user part */ int num_frames /** << max frames to use */ ); /** frame_delete () any held frames, set defaults */ int vdec_hw_h264_reset (vdec_hw_h264_t *dec); /** zero all held frame pts */ int vdec_hw_h264_zero_pts (vdec_hw_h264_t *dec); /** frame_ready () / frame_delete () any held frames now */ int vdec_hw_h264_flush (vdec_hw_h264_t *dec); /** optional, 0 means "no change". */ int vdec_hw_h264_put_container_info (vdec_hw_h264_t *dec, int width, int height, int duration, double ratio); /** optional global head from media container */ int vdec_hw_h264_put_config (vdec_hw_h264_t *dec, const uint8_t *bitstream, uint32_t num_bytes); /** send what you have */ int vdec_hw_h264_put_frame (vdec_hw_h264_t *dec, int64_t pts, const uint8_t *bitstream, uint32_t num_bytes, int frame_end); /** done */ void vdec_hw_h264_delete (vdec_hw_h264_t **dec); #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/vdpau_vc1.c�����������������������������������������������������0000644�0001750�0001750�00000110221�14647725152�017233� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2008-2023 the xine project * Copyright (C) 2008 Christophe Thommeret <hftom@free.fr> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vdpau_vc1.c, a vc1 video stream parser using VDPAU hardware decoder * */ /*#define LOG*/ #define LOG_MODULE "vdpau_vc1" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "accel_vdpau.h" #include "bits_reader.h" #include "group_vdpau.h" #include <vdpau/vdpau.h> #define sequence_header_code 0x0f #define sequence_end_code 0x0a #define entry_point_code 0x0e #define frame_start_code 0x0d #define field_start_code 0x0c #define slice_start_code 0x0b #define PICTURE_FRAME 0 #define PICTURE_FRAME_INTERLACE 2 #define PICTURE_FIELD_INTERLACE 3 #define I_FRAME 0 #define P_FRAME 1 #define B_FRAME 3 #define BI_FRAME 4 #define FIELDS_I_I 0 #define FIELDS_I_P 1 #define FIELDS_P_I 2 #define FIELDS_P_P 3 #define FIELDS_B_B 4 #define FIELDS_B_BI 5 #define FIELDS_BI_B 6 #define FIELDS_BI_BI 7 #define MODE_STARTCODE 0 #define MODE_FRAME 1 /*#define MAKE_DAT*/ /*do NOT define this, unless you know what you do */ #ifdef MAKE_DAT static int nframes; static FILE *outfile; #endif const double aspect_ratio[] = { 0.0, 1.0, 12./11., 10./11., 16./11., 40./33., 24./11., 20./11., 32./11., 80./33., 18./11., 15./11., 64./33., 160./99. }; typedef struct { VdpPictureInfoVC1 vdp_infos; int slices; int fptype; int field; int header_size; int hrd_param_flag; int hrd_num_leaky_buckets; int repeat_first_field; int top_field_first; int skipped; } picture_t; typedef struct { uint32_t coded_width; uint32_t coded_height; uint64_t video_step; /* frame duration in pts units */ uint64_t reported_video_step; /* frame duration in pts units */ double ratio; VdpDecoderProfile profile; int mode; int have_header; uint8_t *buf; /* accumulate data */ int bufseek; int start; int code_start, current_code; uint32_t bufsize; uint32_t bufpos; picture_t picture; vo_frame_t *forward_ref; vo_frame_t *backward_ref; int64_t seq_pts; int64_t cur_pts; vdpau_accel_t *accel_vdpau; bits_reader_t br; int vdp_runtime_nr; int color_matrix; } sequence_t; typedef struct vdpau_vc1_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; sequence_t sequence; VdpDecoder decoder; VdpDecoderProfile decoder_profile; uint32_t decoder_width; uint32_t decoder_height; } vdpau_vc1_decoder_t; static void init_picture( picture_t *pic ) { memset( pic, 0, sizeof( picture_t ) ); } static void reset_picture( picture_t *pic ) { pic->slices = 1; } static void reset_sequence( sequence_t *sequence ) { lprintf( "reset_sequence\n" ); sequence->bufpos = 0; sequence->bufseek = 0; sequence->start = -1; sequence->code_start = sequence->current_code = 0; sequence->seq_pts = sequence->cur_pts = 0; if ( sequence->forward_ref ) sequence->forward_ref->free( sequence->forward_ref ); sequence->forward_ref = NULL; if ( sequence->backward_ref ) sequence->backward_ref->free( sequence->backward_ref ); sequence->backward_ref = NULL; reset_picture( &sequence->picture ); } static void init_sequence( sequence_t *sequence ) { lprintf( "init_sequence\n" ); sequence->have_header = 0; sequence->profile = VDP_DECODER_PROFILE_VC1_SIMPLE; sequence->ratio = 0; sequence->video_step = 0; sequence->picture.hrd_param_flag = 0; reset_sequence( sequence ); } static void update_metadata( vdpau_vc1_decoder_t *this_gen ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; if ( !sequence->have_header ) { sequence->have_header = 1; _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_WIDTH, sequence->coded_width ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, sequence->coded_height ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_RATIO, ((double)10000*sequence->ratio) ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_FRAME_DURATION, (sequence->reported_video_step = sequence->video_step) ); _x_meta_info_set_utf8( this_gen->stream, XINE_META_INFO_VIDEOCODEC, "VC1/WMV9 (vdpau)" ); xine_event_t event; xine_format_change_data_t data; event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = this_gen->stream; event.data = &data; event.data_length = sizeof(data); data.width = sequence->coded_width; data.height = sequence->coded_height; data.aspect = sequence->ratio; xine_event_send( this_gen->stream, &event ); } } static void sequence_header_advanced( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { lprintf( "sequence_header_advanced\n" ); sequence_t *sequence = (sequence_t*)&this_gen->sequence; int xine_color_matrix = 4; /* undefined, mpeg range */ if ( len < 5 ) return; sequence->profile = VDP_DECODER_PROFILE_VC1_ADVANCED; lprintf("VDP_DECODER_PROFILE_VC1_ADVANCED\n"); bits_reader_set( &sequence->br, buf, len ); skip_bits( &sequence->br, 15 ); sequence->picture.vdp_infos.postprocflag = read_bits( &sequence->br, 1 ); sequence->coded_width = (read_bits( &sequence->br, 12 )+1)<<1; sequence->coded_height = (read_bits( &sequence->br, 12 )+1)<<1; sequence->picture.vdp_infos.pulldown = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.interlace = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.tfcntrflag = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.finterpflag = read_bits( &sequence->br, 1 ); skip_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.psf = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.maxbframes = 7; if ( read_bits( &sequence->br, 1 ) ) { double w, h; int ar=0; w = read_bits( &sequence->br, 14 )+1; h = read_bits( &sequence->br, 14 )+1; if ( read_bits( &sequence->br, 1 ) ) { ar = read_bits( &sequence->br, 4 ); } if ( ar==15 ) { w = read_bits( &sequence->br, 8 ); h = read_bits( &sequence->br, 8 ); sequence->ratio = w/h; lprintf("aspect_ratio (w/h) = %f\n", sequence->ratio); } else if ( ar && ar<14 ) { sequence->ratio = sequence->coded_width*aspect_ratio[ar]/sequence->coded_height; lprintf("aspect_ratio = %f\n", sequence->ratio); } if ( read_bits( &sequence->br, 1 ) ) { if ( read_bits( &sequence->br, 1 ) ) { #ifdef LOG int exp = read_bits( &sequence->br, 16 ); lprintf("framerate exp = %d\n", exp); #else skip_bits( &sequence->br, 16 ); #endif } else { double nr = read_bits( &sequence->br, 8 ); switch ((int)nr) { case 1: nr = 24000; break; case 2: nr = 25000; break; case 3: nr = 30000; break; case 4: nr = 50000; break; case 5: nr = 60000; break; default: nr = 0; } double dr = read_bits( &sequence->br, 4 ); switch ((int)dr) { case 2: dr = 1001; break; default: dr = 1000; } sequence->video_step = 90000/(nr/dr); lprintf("framerate = %f video_step = %" PRId64 "\n", nr/dr, sequence->video_step); } } if ( read_bits( &sequence->br, 1 ) ) { skip_bits( &sequence->br, 16 ); xine_color_matrix = read_bits (&sequence->br, 8) << 1; /* VC1 is always mpeg range?? */ } } VO_SET_FLAGS_CM (xine_color_matrix, sequence->color_matrix); sequence->picture.hrd_param_flag = read_bits( &sequence->br, 1 ); if ( sequence->picture.hrd_param_flag ) sequence->picture.hrd_num_leaky_buckets = read_bits( &sequence->br, 5 ); update_metadata( this_gen ); } static void sequence_header( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { lprintf( "sequence_header\n" ); sequence_t *sequence = (sequence_t*)&this_gen->sequence; if ( len < 4 ) return; bits_reader_set( &sequence->br, buf, len ); switch ( read_bits( &sequence->br, 2 ) ) { case 0: sequence->profile = VDP_DECODER_PROFILE_VC1_SIMPLE; lprintf("VDP_DECODER_PROFILE_VC1_SIMPLE\n"); break; case 1: sequence->profile = VDP_DECODER_PROFILE_VC1_MAIN; lprintf("VDP_DECODER_PROFILE_VC1_MAIN\n"); break; case 2: sequence->profile = VDP_DECODER_PROFILE_VC1_MAIN; fprintf(stderr, "vc1_complex profile not supported by vdpau, forcing vc1_main, expect corruption!.\n"); break; case 3: sequence_header_advanced( this_gen, buf, len ); return; default: return; /* illegal value, broken header? */ } skip_bits( &sequence->br, 10 ); sequence->picture.vdp_infos.loopfilter = read_bits( &sequence->br, 1 ); skip_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.multires = read_bits( &sequence->br, 1 ); skip_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.fastuvmc = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.extended_mv = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.dquant = read_bits( &sequence->br, 2 ); sequence->picture.vdp_infos.vstransform = read_bits( &sequence->br, 1 ); skip_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.overlap = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.syncmarker = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.rangered = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.maxbframes = read_bits( &sequence->br, 3 ); sequence->picture.vdp_infos.quantizer = read_bits( &sequence->br, 2 ); sequence->picture.vdp_infos.finterpflag = read_bits( &sequence->br, 1 ); VO_SET_FLAGS_CM (4, sequence->color_matrix); update_metadata( this_gen ); } static void entry_point( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { lprintf( "entry_point\n" ); sequence_t *sequence = (sequence_t*)&this_gen->sequence; bits_reader_set( &sequence->br, buf, len ); skip_bits( &sequence->br, 2 ); sequence->picture.vdp_infos.panscan_flag = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.refdist_flag = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.loopfilter = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.fastuvmc = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.extended_mv = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.dquant = read_bits( &sequence->br, 2 ); sequence->picture.vdp_infos.vstransform = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.overlap = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.quantizer = read_bits( &sequence->br, 2 ); if ( sequence->picture.hrd_param_flag ) { int i; for ( i=0; i<sequence->picture.hrd_num_leaky_buckets; ++i ) skip_bits( &sequence->br, 8 ); } if ( read_bits( &sequence->br, 1 ) ) { sequence->coded_width = (read_bits( &sequence->br, 12 )+1)<<1; sequence->coded_height = (read_bits( &sequence->br, 12 )+1)<<1; } if ( sequence->picture.vdp_infos.extended_mv ) sequence->picture.vdp_infos.extended_dmv = read_bits( &sequence->br, 1 ); sequence->picture.vdp_infos.range_mapy_flag = read_bits( &sequence->br, 1 ); if ( sequence->picture.vdp_infos.range_mapy_flag ) { sequence->picture.vdp_infos.range_mapy = read_bits( &sequence->br, 3 ); } sequence->picture.vdp_infos.range_mapuv_flag = read_bits( &sequence->br, 1 ); if ( sequence->picture.vdp_infos.range_mapuv_flag ) { sequence->picture.vdp_infos.range_mapuv = read_bits( &sequence->br, 3 ); } } static void picture_header( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; //picture_t *pic = (picture_t*)&sequence->picture; VdpPictureInfoVC1 *info = &(sequence->picture.vdp_infos); int tmp; lprintf("picture_header\n"); bits_reader_set( &sequence->br, buf, len ); skip_bits( &sequence->br, 2 ); if ( info->finterpflag ) skip_bits( &sequence->br, 1 ); if ( info->rangered ) { /*info->rangered &= ~2; info->rangered |= get_bits( buf,off++,1 ) << 1;*/ info->rangered = (read_bits( &sequence->br, 1 ) << 1) +1; } if ( !info->maxbframes ) { if ( read_bits( &sequence->br, 1 ) ) info->picture_type = P_FRAME; else info->picture_type = I_FRAME; } else { if ( read_bits( &sequence->br, 1 ) ) info->picture_type = P_FRAME; else { if ( read_bits( &sequence->br, 1 ) ) info->picture_type = I_FRAME; else info->picture_type = B_FRAME; } } if ( info->picture_type == B_FRAME ) { tmp = read_bits( &sequence->br, 3 ); if ( tmp==7 ) { tmp = (tmp<<4) | read_bits( &sequence->br, 4 ); if ( tmp==127 ) info->picture_type = BI_FRAME; } } } static void picture_header_advanced( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; picture_t *pic = (picture_t*)&sequence->picture; VdpPictureInfoVC1 *info = &(sequence->picture.vdp_infos); lprintf("picture_header_advanced\n"); bits_reader_set( &sequence->br, buf, len ); if ( info->interlace ) { lprintf("frame->interlace=1\n"); if ( !read_bits( &sequence->br, 1 ) ) { lprintf("progressive frame\n"); info->frame_coding_mode = PICTURE_FRAME; } else { if ( !read_bits( &sequence->br, 1 ) ) { lprintf("frame interlaced\n"); info->frame_coding_mode = PICTURE_FRAME_INTERLACE; } else { lprintf("field interlaced\n"); info->frame_coding_mode = PICTURE_FIELD_INTERLACE; } } } if ( info->interlace && info->frame_coding_mode == PICTURE_FIELD_INTERLACE ) { pic->fptype = read_bits( &sequence->br, 3 ); switch ( pic->fptype ) { case FIELDS_I_I: case FIELDS_I_P: info->picture_type = I_FRAME; break; case FIELDS_P_I: case FIELDS_P_P: info->picture_type = P_FRAME; break; case FIELDS_B_B: case FIELDS_B_BI: info->picture_type = B_FRAME; break; default: info->picture_type = BI_FRAME; } } else { if ( !read_bits( &sequence->br, 1 ) ) info->picture_type = P_FRAME; else { if ( !read_bits( &sequence->br, 1 ) ) info->picture_type = B_FRAME; else { if ( !read_bits( &sequence->br, 1 ) ) info->picture_type = I_FRAME; else { if ( !read_bits( &sequence->br, 1 ) ) info->picture_type = BI_FRAME; else { info->picture_type = P_FRAME; pic->skipped = 1; } } } } } if ( info->tfcntrflag ) { lprintf("tfcntrflag=1\n"); skip_bits( &sequence->br, 8 ); } if ( info->pulldown && info->interlace ) { pic->top_field_first = read_bits( &sequence->br, 1 ); pic->repeat_first_field = read_bits( &sequence->br, 1 ); } } static void parse_header( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; int off=0; while ( off < (len-4) ) { uint8_t *buffer = buf+off; if ( buffer[0]==0 && buffer[1]==0 && buffer[2]==1 ) { switch ( buffer[3] ) { case sequence_header_code: sequence_header( this_gen, buf+off+4, len-off-4 ); break; case entry_point_code: entry_point( this_gen, buf+off+4, len-off-4 ); break; } } ++off; } if ( !sequence->have_header ) sequence_header( this_gen, buf, len ); } static void remove_emulation_prevention( uint8_t *src, uint8_t *dst, int src_len, int *dst_len ) { int i; int len = 0; int removed = 0; for ( i=0; i<src_len-3; ++i ) { if ( src[i]==0 && src[i+1]==0 && src[i+2]==3 ) { lprintf("removed emulation prevention byte\n"); dst[len++] = src[i]; dst[len++] = src[i+1]; i += 2; ++removed; } else { memcpy( dst+len, src+i, 4 ); ++len; } } for ( ; i<src_len; ++i ) dst[len++] = src[i]; *dst_len = src_len-removed; } static int parse_code( vdpau_vc1_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; if ( !sequence->have_header && buf[3]!=sequence_header_code ) return 0; if ( sequence->code_start == frame_start_code ) { if ( sequence->current_code==field_start_code || sequence->current_code==slice_start_code ) { sequence->picture.slices++; return -1; } return 1; /* frame complete, decode */ } switch ( buf[3] ) { int dst_len; uint8_t *tmp; case sequence_header_code: lprintf("sequence_header_code\n"); tmp = malloc( len ); remove_emulation_prevention( buf, tmp, len, &dst_len ); sequence_header( this_gen, tmp+4, dst_len-4 ); free( tmp ); break; case entry_point_code: lprintf("entry_point_code\n"); tmp = malloc( len ); remove_emulation_prevention( buf, tmp, len, &dst_len ); entry_point( this_gen, tmp+4, dst_len-4 ); free( tmp ); break; case sequence_end_code: lprintf("sequence_end_code\n"); break; case frame_start_code: lprintf("frame_start_code, len=%d\n", len); break; case field_start_code: lprintf("field_start_code\n"); break; case slice_start_code: lprintf("slice_start_code, len=%d\n", len); break; } return 0; } static void decode_render( vdpau_vc1_decoder_t *vd, vdpau_accel_t *accel, uint8_t *buf, int len ) { sequence_t *seq = (sequence_t*)&vd->sequence; picture_t *pic = (picture_t*)&seq->picture; VdpStatus st; if ( vd->decoder==VDP_INVALID_HANDLE || vd->decoder_profile!=seq->profile || vd->decoder_width!=seq->coded_width || vd->decoder_height!=seq->coded_height ) { if (accel->lock) accel->lock (accel->vo_frame); if ( vd->decoder!=VDP_INVALID_HANDLE ) { accel->vdp_decoder_destroy( vd->decoder ); vd->decoder = VDP_INVALID_HANDLE; } st = accel->vdp_decoder_create( accel->vdp_device, seq->profile, seq->coded_width, seq->coded_height, 2, &vd->decoder); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) fprintf(stderr, "vdpau_vc1: failed to create decoder !! %s\n", accel->vdp_get_error_string( st ) ); else { lprintf( "decoder created.\n" ); vd->decoder_profile = seq->profile; vd->decoder_width = seq->coded_width; vd->decoder_height = seq->coded_height; seq->vdp_runtime_nr = accel->vdp_runtime_nr; } } VdpBitstreamBuffer vbit; vbit.struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit.bitstream = buf; vbit.bitstream_bytes = len; if ( pic->field ) vbit.bitstream_bytes = pic->field; if (accel->lock) accel->lock (accel->vo_frame); st = accel->vdp_decoder_render( vd->decoder, accel->surface, CAST_VdpPictureInfo_PTR &pic->vdp_infos, 1, &vbit ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) fprintf(stderr, "vdpau_vc1: decoder failed : %d!! %s\n", st, accel->vdp_get_error_string( st ) ); else { lprintf( "DECODER SUCCESS : slices=%d, slices_bytes=%d, current=%d, forwref:%d, backref:%d, pts:%" PRId64 "\n", pic->vdp_infos.slice_count, vbit.bitstream_bytes, accel->surface, pic->vdp_infos.forward_reference, pic->vdp_infos.backward_reference, seq->seq_pts ); } #ifdef LOG VdpPictureInfoVC1 *info = &(seq->picture.vdp_infos); lprintf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", info->slice_count, info->picture_type, info->frame_coding_mode, info->postprocflag, info->pulldown, info->interlace, info->tfcntrflag, info->finterpflag, info->psf, info->dquant, info->panscan_flag, info->refdist_flag, info->quantizer, info->extended_mv, info->extended_dmv, info->overlap, info->vstransform, info->loopfilter, info->fastuvmc, info->range_mapy_flag, info->range_mapy, info->range_mapuv_flag, info->range_mapuv, info->multires, info->syncmarker, info->rangered, info->maxbframes, info->deblockEnable, info->pquant ); #endif if ( pic->field ) { int old_type = pic->vdp_infos.picture_type; switch ( pic->fptype ) { case FIELDS_I_I: case FIELDS_P_I: pic->vdp_infos.picture_type = I_FRAME; pic->vdp_infos.backward_reference = VDP_INVALID_HANDLE; pic->vdp_infos.forward_reference = VDP_INVALID_HANDLE; break; case FIELDS_I_P: pic->vdp_infos.forward_reference = accel->surface; pic->vdp_infos.picture_type = P_FRAME; break; case FIELDS_P_P: if ( seq->backward_ref ) pic->vdp_infos.forward_reference = ((vdpau_accel_t*)seq->backward_ref->accel_data)->surface; pic->vdp_infos.picture_type = P_FRAME; break; case FIELDS_B_B: case FIELDS_BI_B: pic->vdp_infos.picture_type = B_FRAME; break; default: pic->vdp_infos.picture_type = BI_FRAME; } vbit.bitstream = buf+pic->field+4; vbit.bitstream_bytes = len-pic->field-4; if (accel->lock) accel->lock (accel->vo_frame); st = accel->vdp_decoder_render( vd->decoder, accel->surface, CAST_VdpPictureInfo_PTR &pic->vdp_infos, 1, &vbit ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) fprintf(stderr, "vdpau_vc1: decoder failed : %d!! %s\n", st, accel->vdp_get_error_string( st ) ); else { lprintf( "DECODER SUCCESS (second field): slices=%d, slices_bytes=%d, current=%d, forwref:%d, backref:%d, pts:%" PRId64 "\n", pic->vdp_infos.slice_count, vbit.bitstream_bytes, accel->surface, pic->vdp_infos.forward_reference, pic->vdp_infos.backward_reference, seq->seq_pts ); } #ifdef LOG VdpPictureInfoVC1 *info = &(seq->picture.vdp_infos); lprintf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", info->slice_count, info->picture_type, info->frame_coding_mode, info->postprocflag, info->pulldown, info->interlace, info->tfcntrflag, info->finterpflag, info->psf, info->dquant, info->panscan_flag, info->refdist_flag, info->quantizer, info->extended_mv, info->extended_dmv, info->overlap, info->vstransform, info->loopfilter, info->fastuvmc, info->range_mapy_flag, info->range_mapy, info->range_mapuv_flag, info->range_mapuv, info->multires, info->syncmarker, info->rangered, info->maxbframes, info->deblockEnable, info->pquant ); #endif pic->vdp_infos.picture_type = old_type; } } static int search_field( vdpau_vc1_decoder_t *vd, uint8_t *buf, int len ) { int i; lprintf("search_fields, len=%d\n", len); (void)vd; for ( i=0; i<len-4; ++i ) { if ( buf[i]==0 && buf[i+1]==0 && buf[i+2]==1 && buf[i+3]==field_start_code ) { lprintf("found field_start_code at %d\n", i); return i; } } return 0; } static void decode_picture( vdpau_vc1_decoder_t *vd ) { sequence_t *seq = (sequence_t*)&vd->sequence; picture_t *pic = (picture_t*)&seq->picture; vdpau_accel_t *ref_accel; int field; uint8_t *buf; int len; pic->skipped = 0; pic->field = 0; if ( seq->mode == MODE_FRAME ) { buf = seq->buf; len = seq->bufpos; if ( seq->profile==VDP_DECODER_PROFILE_VC1_ADVANCED ) picture_header_advanced( vd, buf, len ); else picture_header( vd, buf, len ); if ( len < 2 ) pic->skipped = 1; } else { seq->picture.vdp_infos.slice_count = seq->picture.slices; buf = seq->buf+seq->start+4; len = seq->bufseek-seq->start-4; if ( seq->profile==VDP_DECODER_PROFILE_VC1_ADVANCED ) { int tmplen = (len>50) ? 50 : len; uint8_t *tmp = malloc( tmplen ); remove_emulation_prevention( buf, tmp, tmplen, &tmplen ); picture_header_advanced( vd, tmp, tmplen ); free( tmp ); } else picture_header( vd, buf, len ); if ( len < 2 ) pic->skipped = 1; } if ( pic->skipped ) pic->vdp_infos.picture_type = P_FRAME; if ( pic->vdp_infos.interlace && pic->vdp_infos.frame_coding_mode == PICTURE_FIELD_INTERLACE ) { if ( !(field = search_field( vd, buf, len )) ) lprintf("error, no fields found!\n"); else pic->field = field; } pic->vdp_infos.forward_reference = VDP_INVALID_HANDLE; pic->vdp_infos.backward_reference = VDP_INVALID_HANDLE; if ( pic->vdp_infos.picture_type==P_FRAME ) { if ( seq->backward_ref ) { ref_accel = (vdpau_accel_t*)seq->backward_ref->accel_data; pic->vdp_infos.forward_reference = ref_accel->surface; } else { reset_picture( &seq->picture ); return; } } else if ( pic->vdp_infos.picture_type>=B_FRAME ) { if ( seq->forward_ref ) { ref_accel = (vdpau_accel_t*)seq->forward_ref->accel_data; pic->vdp_infos.forward_reference = ref_accel->surface; } else { reset_picture( &seq->picture ); return; } if ( seq->backward_ref ) { ref_accel = (vdpau_accel_t*)seq->backward_ref->accel_data; pic->vdp_infos.backward_reference = ref_accel->surface; } else { reset_picture( &seq->picture ); return; } } vo_frame_t *img = vd->stream->video_out->get_frame( vd->stream->video_out, seq->coded_width, seq->coded_height, seq->ratio, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | seq->color_matrix ); vdpau_accel_t *accel = (vdpau_accel_t*)img->accel_data; if ( !seq->accel_vdpau ) seq->accel_vdpau = accel; if( seq->vdp_runtime_nr != *(seq->accel_vdpau->current_vdp_runtime_nr) ) { seq->accel_vdpau = accel; if ( seq->forward_ref ) seq->forward_ref->free( seq->forward_ref ); seq->forward_ref = NULL; if ( seq->backward_ref ) seq->backward_ref->free( seq->backward_ref ); seq->backward_ref = NULL; vd->decoder = VDP_INVALID_HANDLE; } decode_render( vd, accel, buf, len ); #ifdef MAKE_DAT if ( nframes==0 ) { fwrite( &seq->coded_width, 1, sizeof(seq->coded_width), outfile ); fwrite( &seq->coded_height, 1, sizeof(seq->coded_height), outfile ); fwrite( &seq->ratio, 1, sizeof(seq->ratio), outfile ); fwrite( &seq->profile, 1, sizeof(seq->profile), outfile ); } if ( nframes++ < 25 ) { fwrite( &pic->vdp_infos, 1, sizeof(pic->vdp_infos), outfile ); fwrite( &len, 1, sizeof(len), outfile ); fwrite( buf, 1, len, outfile ); printf( "picture_type = %d\n", pic->vdp_infos.picture_type); } #endif if ( pic->vdp_infos.interlace && pic->vdp_infos.frame_coding_mode ) { img->progressive_frame = 0; img->top_field_first = pic->top_field_first; } else { img->progressive_frame = 1; img->top_field_first = 1; } img->pts = seq->seq_pts; img->bad_frame = 0; img->duration = seq->video_step; if ( pic->vdp_infos.picture_type<B_FRAME ) { if ( pic->vdp_infos.picture_type==I_FRAME && !seq->backward_ref ) { img->pts = 0; img->draw( img, vd->stream ); ++img->drawn; } if ( seq->forward_ref ) { seq->forward_ref->drawn = 0; seq->forward_ref->free( seq->forward_ref ); } seq->forward_ref = seq->backward_ref; if ( seq->forward_ref && !seq->forward_ref->drawn ) { seq->forward_ref->draw( seq->forward_ref, vd->stream ); } seq->backward_ref = img; } else { img->draw( img, vd->stream ); img->free( img ); } seq->seq_pts +=seq->video_step; reset_picture( &seq->picture ); } /* * This function receives a buffer of data from the demuxer layer and * figures out how to handle it based on its header flags. */ static void vdpau_vc1_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { vdpau_vc1_decoder_t *this = (vdpau_vc1_decoder_t *) this_gen; sequence_t *seq = (sequence_t*)&this->sequence; /* a video decoder does not care about this flag (?) */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) { lprintf("BUF_FLAG_PREVIEW\n"); } if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { lprintf("BUF_FLAG_FRAMERATE=%d\n", buf->decoder_info[0]); if ( buf->decoder_info[0] > 0 ) { this->sequence.video_step = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->sequence.video_step); } } if (this->sequence.reported_video_step != this->sequence.video_step){ _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->sequence.reported_video_step = this->sequence.video_step)); } if (buf->decoder_flags & BUF_FLAG_HEADER) { lprintf("BUF_FLAG_HEADER\n"); } if (buf->decoder_flags & BUF_FLAG_ASPECT) { lprintf("BUF_FLAG_ASPECT\n"); seq->ratio = (double)buf->decoder_info[1]/(double)buf->decoder_info[2]; lprintf("arx=%d ary=%d ratio=%f\n", buf->decoder_info[1], buf->decoder_info[2], seq->ratio); } if ( !buf->size ) return; seq->cur_pts = buf->pts; if (buf->decoder_flags & BUF_FLAG_STDHEADER) { lprintf("BUF_FLAG_STDHEADER\n"); xine_bmiheader *bih = (xine_bmiheader *) buf->content; int bs = sizeof( xine_bmiheader ); seq->coded_width = bih->biWidth; seq->coded_height = bih->biHeight; lprintf( "width=%d height=%d\n", bih->biWidth, bih->biHeight ); if ( buf->size > bs ) { seq->mode = MODE_FRAME; parse_header( this, buf->content+bs, buf->size-bs ); } return; } int size = seq->bufpos+buf->size; if ( seq->bufsize < (unsigned int)size ) { seq->bufsize = size+10000; seq->buf = realloc( seq->buf, seq->bufsize ); lprintf("sequence buffer realloced = %d\n", seq->bufsize ); } xine_fast_memcpy( seq->buf+seq->bufpos, buf->content, buf->size ); seq->bufpos += buf->size; if (buf->decoder_flags & BUF_FLAG_FRAME_START) { lprintf("BUF_FLAG_FRAME_START\n"); seq->seq_pts = buf->pts; seq->mode = MODE_FRAME; if ( seq->bufpos > 3 ) { if ( seq->buf[0]==0 && seq->buf[1]==0 && seq->buf[2]==1 ) { seq->mode = MODE_STARTCODE; } } } if ( seq->mode == MODE_FRAME ) { if ( buf->decoder_flags & BUF_FLAG_FRAME_END ) { lprintf("BUF_FLAG_FRAME_END\n"); decode_picture( this ); seq->bufpos = 0; } return; } int res; while ( seq->bufseek <= (int)(seq->bufpos)-4 ) { uint8_t *buffer = seq->buf+seq->bufseek; if ( buffer[0]==0 && buffer[1]==0 && buffer[2]==1 ) { seq->current_code = buffer[3]; lprintf("current_code = %d\n", seq->current_code); if ( seq->start<0 ) { seq->start = seq->bufseek; seq->code_start = buffer[3]; lprintf("code_start = %d\n", seq->code_start); if ( seq->cur_pts ) seq->seq_pts = seq->cur_pts; } else { res = parse_code( this, seq->buf+seq->start, seq->bufseek-seq->start ); if ( res==1 ) { seq->mode = MODE_STARTCODE; decode_picture( this ); parse_code( this, seq->buf+seq->start, seq->bufseek-seq->start ); } if ( res!=-1 ) { uint8_t *tmp = (uint8_t*)malloc(seq->bufsize); xine_fast_memcpy( tmp, seq->buf+seq->bufseek, seq->bufpos-seq->bufseek ); seq->bufpos -= seq->bufseek; seq->start = -1; seq->bufseek = -1; free( seq->buf ); seq->buf = tmp; } } } ++seq->bufseek; } } /* * This function is called when xine needs to flush the system. */ static void vdpau_vc1_flush (video_decoder_t *this_gen) { lprintf( "vdpau_vc1_flush\n" ); (void)this_gen; } /* * This function resets the video decoder. */ static void vdpau_vc1_reset (video_decoder_t *this_gen) { vdpau_vc1_decoder_t *this = (vdpau_vc1_decoder_t *) this_gen; lprintf( "vdpau_vc1_reset\n" ); reset_sequence( &this->sequence ); } /* * The decoder should forget any stored pts values here. */ static void vdpau_vc1_discontinuity (video_decoder_t *this_gen) { lprintf( "vdpau_vc1_discontinuity\n" ); (void)this_gen; } /* * This function frees the video decoder instance allocated to the decoder. */ static void vdpau_vc1_dispose (video_decoder_t *this_gen) { vdpau_vc1_decoder_t *this = (vdpau_vc1_decoder_t *) this_gen; lprintf( "vdpau_vc1_dispose\n" ); if ( this->decoder!=VDP_INVALID_HANDLE && this->sequence.accel_vdpau ) { if (this->sequence.accel_vdpau->lock) this->sequence.accel_vdpau->lock (this->sequence.accel_vdpau->vo_frame); this->sequence.accel_vdpau->vdp_decoder_destroy( this->decoder ); this->decoder = VDP_INVALID_HANDLE; if (this->sequence.accel_vdpau->unlock) this->sequence.accel_vdpau->unlock (this->sequence.accel_vdpau->vo_frame); } reset_sequence( &this->sequence ); this->stream->video_out->close( this->stream->video_out, this->stream ); free( this->sequence.buf ); free( this_gen ); } /* * This function allocates, initializes, and returns a private video * decoder structure. */ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { vdpau_vc1_decoder_t *this ; lprintf( "open_plugin\n" ); (void)class_gen; /* the videoout must be vdpau-capable to support this decoder */ if ( !(stream->video_out->get_capabilities(stream->video_out) & VO_CAP_VDPAU_VC1) ) return NULL; /* now check if vdpau has free decoder resource */ vo_frame_t *img = stream->video_out->get_frame( stream->video_out, 1920, 1080, 1, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL ); if (!img) { return NULL; } vdpau_accel_t *accel = (vdpau_accel_t*)img->accel_data; int runtime_nr = accel->vdp_runtime_nr; img->free(img); VdpDecoder decoder; if (accel->lock) accel->lock (accel->vo_frame); VdpStatus st = accel->vdp_decoder_create( accel->vdp_device, VDP_DECODER_PROFILE_VC1_MAIN, 1920, 1080, 2, &decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) { lprintf( "can't create vdpau decoder.\n" ); return NULL; } if (accel->lock) accel->lock (accel->vo_frame); accel->vdp_decoder_destroy( decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); this = (vdpau_vc1_decoder_t *) calloc(1, sizeof(vdpau_vc1_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = vdpau_vc1_decode_data; this->video_decoder.flush = vdpau_vc1_flush; this->video_decoder.reset = vdpau_vc1_reset; this->video_decoder.discontinuity = vdpau_vc1_discontinuity; this->video_decoder.dispose = vdpau_vc1_dispose; this->stream = stream; this->sequence.bufsize = 10000; this->sequence.buf = (uint8_t*)malloc(this->sequence.bufsize); this->sequence.forward_ref = 0; this->sequence.backward_ref = 0; this->sequence.vdp_runtime_nr = runtime_nr; init_sequence( &this->sequence ); init_picture( &this->sequence.picture ); this->decoder = VDP_INVALID_HANDLE; this->sequence.accel_vdpau = NULL; this->sequence.mode = MODE_STARTCODE; (stream->video_out->open)(stream->video_out, stream); #ifdef MAKE_DAT outfile = fopen( "/tmp/vc1.dat","w"); nframes = 0; #endif return &this->video_decoder; } /* * This function allocates a private video decoder class and initializes * the class's member functions. */ void *vc1_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_vdpau_vc1_class = { .open_plugin = open_plugin, .identifier = "vdpau_vc1", .description = N_("VC-1/WMV3 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau."), .dispose = NULL, }; return (void *)&decode_video_vdpau_vc1_class; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/vdec_hw_h264.c��������������������������������������������������0000644�0001750�0001750�00000250113�14647725152�017532� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; * Copyright (C) 2008-2022 the xine project * Copyright (C) 2008 Christophe Thommeret <hftom@free.fr> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * h264.c, a generic H264 video stream parser for VDPAU and VAAPI hardware decoders */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #undef LOG #define LOG_MODULE "vdec_hw_h264" #ifdef LOG # define lprintf(_fmt, ...) fprintf (stderr, LOG_MODULE _fmt, ...) #else # define lprintf(_fmt, ...) /* nothing */ #endif #include <stdio.h> #include <stdarg.h> #include "vdec_hw_h264.h" #include "vdec_hw_bits_reader.h" #define PICTURE_TOP_DONE 1 #define PICTURE_BOTTOM_DONE 2 #define PICTURE_DONE 3 #define SHORT_TERM_REF 1 #define LONG_TERM_REF 2 #define MAX_SPS 32 #define MAX_PPS 256 #define MAX_SLICES 80 /* 68? */ #define MAX_REF_FRAMES 16 #define MIN_BUFFER_SIZE 10000 #define MAX_BUFFER_SIZE 3145728 #define BUF_PAD 8 #define NAL_UNSPECIFIED 0 #define NAL_SLICE_NO_IDR 1 #define NAL_SLICE_IDR 5 #define NAL_SEI 6 #define NAL_SEQUENCE 7 #define NAL_PICTURE 8 #define NAL_SEEK_POINT 9 #define NAL_END_SEQUENCE 10 #define NAL_END_STREAM 11 #define NAL_FILLER 12 #define NAL_SEQUENCE_EXT 13 #define SLICE_TYPE_P 0 #define SLICE_TYPE_B 1 #define SLICE_TYPE_I 2 #define SLICE_TYPE_SP 3 #define SLICE_TYPE_SI 4 #define START_IDR_FLAG 1000 #define MAX_POC 2147483647 #define DPB_DRAW_CLEAR 1 #define DPB_DRAW_REFS 2 #define DPB_DRAW_CURRENT 3 /* SPS: sequence parameter set * PPS: picture parameter set * LPS: slice parameter set */ typedef struct{ uint8_t aspect_ratio_info; uint8_t aspect_ratio_idc; uint16_t sar_width; uint16_t sar_height; uint8_t colour_desc; uint8_t colour_primaries; uint8_t timing_info; uint32_t num_units_in_tick; uint32_t time_scale; } vdec_hw_h264_vui_t; typedef struct { uint8_t reused; uint8_t profile_idc; uint8_t level_idc; uint8_t sps_id; uint8_t constraint_set0_flag; uint8_t constraint_set1_flag; uint8_t constraint_set2_flag; uint8_t constraint_set3_flag; uint8_t chroma_format_idc; uint8_t separate_colour_plane_flag; uint8_t bit_depth_luma_minus8; uint8_t bit_depth_chroma_minus8; uint8_t qpprime_y_zero_transform_bypass_flag; uint8_t seq_scaling_matrix_present_flag; uint8_t scaling_lists_4x4[6][16]; uint8_t scaling_lists_8x8[2][64]; uint8_t log2_max_frame_num_minus4; uint8_t pic_order_cnt_type; uint8_t log2_max_pic_order_cnt_lsb_minus4; uint8_t delta_pic_order_always_zero_flag; int32_t offset_for_non_ref_pic; int32_t offset_for_top_to_bottom_field; uint8_t ref_frames_used_in_pic_order_cnt_cycle; int32_t offset_for_ref_frame[256]; uint8_t ref_frames_used; uint8_t gaps_in_frame_num_value_allowed_flag; uint8_t pic_width_in_mbs_minus1; uint8_t pic_height_in_map_units_minus1; uint8_t frame_mbs_only_flag; uint8_t mb_adaptive_frame_field_flag; uint8_t direct_8x8_inference_flag; uint8_t frame_cropping_flag; uint16_t frame_crop_left_offset; uint16_t frame_crop_right_offset; uint16_t frame_crop_top_offset; uint16_t frame_crop_bottom_offset; uint8_t vui_parameters_present_flag; vdec_hw_h264_vui_t vui; } vdec_hw_h264_sps_t; #define VDEC_HW_H264_MAX_SLICE_GROUPS 80 typedef struct{ uint8_t pps_id; uint8_t sps_id; uint8_t entropy_coding_mode_flag; uint8_t pic_order_present_flag; uint8_t num_ref_idx_l0_active_minus1; uint8_t num_ref_idx_l1_active_minus1; uint8_t weighted_pred_flag; uint8_t weighted_bipred_idc; int8_t pic_init_qp_minus26; int8_t pic_init_qs_minus26; int8_t chroma_qp_index_offset; int8_t second_chroma_qp_index_offset; uint8_t deblocking_filter_control_present_flag; uint8_t constrained_intra_pred_flag; uint8_t redundant_pic_cnt_present_flag; uint8_t transform_8x8_mode_flag; uint8_t pic_scaling_matrix_present_flag; uint8_t pic_scaling_list_present_flag[8]; uint8_t scaling_lists_4x4[6][16]; uint8_t scaling_lists_8x8[2][64]; uint8_t num_slice_groups_minus1; uint8_t slice_group_map_type; uint8_t slice_group_change_direction_flag; uint16_t slice_group_change_rate_minus1; uint16_t pic_size_in_map_units_minus1; struct { uint16_t id; uint16_t run_length_minus1; uint16_t top_left; uint16_t bottom_right; } slice_groups[VDEC_HW_H264_MAX_SLICE_GROUPS]; } vdec_hw_h264_pps_t; typedef struct { uint8_t nal_ref_idc; uint8_t nal_unit_type; uint8_t slice_type; uint8_t pps_id; uint16_t frame_num; uint32_t MaxFrameNum; uint8_t field_pic_flag; uint8_t bottom_field_flag; uint16_t idr_pic_id; uint16_t pic_order_cnt_lsb; int32_t delta_pic_order_cnt_bottom; int32_t delta_pic_order_cnt[2]; uint8_t redundant_pic_cnt; /* slice_type B */ uint8_t direct_spatial_mv_pred_flag; /* slice_type P, SP, B */ uint8_t num_ref_idx_active_override_flag; uint8_t num_ref_idx_l0_active_minus1; /* slice type B */ uint8_t num_ref_idx_l1_active_minus1; /* pred_weight_table */ struct { uint32_t luma_log2_weight_denom; /* chroma_format_idc != 0 */ uint32_t chroma_log2_weight_denom; int32_t luma_weight_l0[32]; int32_t luma_offset_l0[32]; int32_t chroma_weight_l0[32][2]; int32_t chroma_offset_l0[32][2]; int32_t luma_weight_l1[32]; int32_t luma_offset_l1[32]; int32_t chroma_weight_l1[32][2]; int32_t chroma_offset_l1[32][2]; } pred_weight_table; } vdec_hw_h264_lps_t; typedef struct vdec_hw_h264_frame_int_s { vdec_hw_h264_frame_t f; struct vdec_hw_h264_frame_int_s *link; int drawn; uint8_t used; uint8_t missing_header; uint8_t drop_pts; uint8_t completed; uint16_t FrameNum; int32_t FrameNumWrap; int32_t PicNum[2]; /* 0:top, 1:bottom */ uint8_t is_reference[2]; /* 0:top, 1:bottom, short or long term */ uint8_t field_pic_flag; int32_t PicOrderCntMsb; int32_t TopFieldOrderCnt; int32_t BottomFieldOrderCnt; uint16_t pic_order_cnt_lsb; uint8_t mmc5; } vdec_hw_h264_frame_int_t; static __attribute__((format (printf, 3, 4))) int _vdec_hw_h264_dummy_logg (void *user_data, vdec_hw_h264_logg_t level, const char *fmt, ...) { (void)user_data; if (level == VDEC_HW_H264_LOGG_ERR) { va_list args; int n; va_start (args, fmt); n = vfprintf (stderr, fmt, args); va_end (args); return n; } return 0; } typedef struct { uint32_t coded_width; uint32_t coded_height; uint64_t video_step; /** << frame duration in pts units */ double ratio; double user_ratio; int color_matrix; int slices_count; uint32_t slice_mode; const uint8_t *slices_bitstream[MAX_SLICES]; uint32_t slices_bytes[MAX_SLICES]; vdec_hw_h264_sps_t *sps[MAX_SPS]; vdec_hw_h264_pps_t *pps[MAX_PPS]; vdec_hw_h264_lps_t lps; vdec_hw_h264_frame_int_t *dpb[MAX_REF_FRAMES + 1]; uint16_t prevFrameNum; uint16_t prevFrameNumOffset; uint8_t prevMMC5; int chroma; vdec_hw_h264_frame_info_t info; struct { /** << bytestream buf */ uint8_t *mem; /** << memory */ uint32_t max; /** << allocated size, minus a pad reserve */ int32_t nal_unit; /** << offs of a yet unprocessed nal unit, or -1 */ uint32_t read; /** << parse here */ uint32_t write; /** << append here */ } buf; int64_t pic_pts; bits_reader_t br; int reset; int startup_frame; /* 0: standard 00 00 01 * 1..4: a big endian int of that many bytes telling the unit size */ uint8_t nal_unit_prefix; } vdec_hw_h264_sequence_t; struct vdec_hw_h264_s { /* user supolied */ __attribute__((format (printf, 3, 4))) int (*logg) (void *user_data, vdec_hw_h264_logg_t level, const char *fmt, ...); void *user_data; int (*frame_new) (void *user_data, vdec_hw_h264_frame_t *frame); int (*frame_render) (void *user_data, vdec_hw_h264_frame_t *frame); int (*frame_ready) (void *user_data, vdec_hw_h264_frame_t *frame); void (*frame_delete) (void *user_data, vdec_hw_h264_frame_t *frame); vdec_hw_h264_sequence_t seq; struct { int sps; int pps; int slices; int frame_ready; } stats; int32_t user_frames; uint32_t ref_frames_max; uint32_t ref_frames_used; vdec_hw_h264_frame_int_t frames[MAX_REF_FRAMES + 1]; uint8_t tempbuf[1 << 16]; }; static const uint8_t zigzag_4x4[16] = { 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 }; static const uint8_t zigzag_8x8[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 }; static const uint8_t default_4x4_intra[16] = { 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42 }; static const uint8_t default_4x4_inter[16] = { 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34 }; static const uint8_t default_8x8_intra[64] = { 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42 }; static const uint8_t default_8x8_inter[64] = { 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35 }; /** 00 00 03 foo -> 00 00 foo */ static uint32_t _vdec_hw_h264_unescape (uint8_t *b, uint32_t len) { uint8_t *p = b, *e = b + len, *q, *a; uint32_t v = 0xffffff00; while (p < e) { v = (v + *p) << 8; if (v == 0x00000300) break; p++; } if (p >= e) return p - b; q = p; do { int32_t d; a = ++p; while (p < e) { v = (v + *p) << 8; if (v == 0x00000300) break; p++; } d = p - a; if (d > 0) { memmove (q, a, d); q += d; } } while (p < e); return q - b; } static void _vdec_hw_h264_frame_free (vdec_hw_h264_t *vdec, vdec_hw_h264_frame_int_t *frame, int zero) { if (frame->link) { if (frame->link->link == frame) { frame->link->link = NULL; frame->f.user_data = NULL; } frame->link = NULL; } if (frame->f.user_data && vdec->frame_delete) { vdec->frame_delete (vdec->user_data, &frame->f); frame->f.user_data = NULL; vdec->user_frames--; if (vdec->user_frames < 0) vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": ERROR: too few user frames (%d).\n", (int)vdec->user_frames); } if (zero) { memset (frame, 0, sizeof (*frame)); frame->f.vdec = vdec; } } static void _vdec_hw_h264_frame_new (vdec_hw_h264_t *vdec, vdec_hw_h264_frame_int_t *frame) { if (frame->link) { if (frame->link->link == frame) return; frame->link = NULL; } _vdec_hw_h264_frame_free (vdec, frame, 0); if (!frame->f.user_data && vdec->frame_new) { vdec->frame_new (vdec->user_data, &frame->f); frame->f.bad_frame = 0; frame->drawn = 0; vdec->user_frames++; if (vdec->user_frames > (int32_t)vdec->ref_frames_max + 1) vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": ERROR: too many user frames (%d).\n", (int)vdec->user_frames); } } static void _vdec_hw_h264_frame_link (vdec_hw_h264_t *vdec, vdec_hw_h264_frame_int_t *frame, vdec_hw_h264_frame_int_t *to) { (void)vdec; if ((to->link && (to->link != frame)) || (to->f.user_data && (to->f.user_data != frame->f.user_data))) _vdec_hw_h264_frame_free (vdec, to, 0); if (frame->link && (frame->link != to)) _vdec_hw_h264_frame_free (vdec, frame, 0); *to = *frame; frame->link = to; to->link = frame; } static void _vdec_hw_h264_frame_draw (vdec_hw_h264_t *vdec, vdec_hw_h264_frame_int_t *frame) { if (!frame->drawn && vdec->frame_ready) { vdec->stats.frame_ready++; vdec->frame_ready (vdec->user_data, &frame->f); frame->drawn = 1; if (frame->link) frame->link->drawn = 1; } } /*-------- DPB -------------------------------------------*/ #if 0 static void dpb_print (vdec_hw_h264_sequence_t * sequence) { int i; vdec_hw_h264_frame_int_t *frame; uint32_t sf; for (i = 0; i < MAX_REF_FRAMES; i++) { frame = vdec->seq.dpb[i]; if (!frame->used) break; vo_frame_t *vo = (vo_frame_t *) frame->videoSurface; vdpau_accel_t *accel; if (vo) accel = (vdpau_accel_t *) vo->accel_data; sf = (vo) ? accel->surface : (uint32_t)-1; fprintf (stderr, "{ i:%d u:%d c:%d pn:%d-%d ir:%d-%d tpoc:%d bpoc:%d sf:%u }\n", i, frame->used, frame->completed, frame->PicNum[0], frame->PicNum[1], frame->is_reference[0], frame->is_reference[1], frame->TopFieldOrderCnt, frame->BottomFieldOrderCnt, sf); } } #endif int vdec_hw_h264_zero_pts (vdec_hw_h264_t *vdec) { uint32_t u, n = 0; if (!vdec) return 0; vdec->seq.reset = VDEC_HW_H264_FRAME_NEW_SEQ; for (u = 0; u < vdec->ref_frames_used; u++) { vdec_hw_h264_frame_int_t *frame = vdec->seq.dpb[u]; if (frame->f.pts) frame->f.pts = 0, frame->drop_pts = 1, n++; } { vdec_hw_h264_frame_int_t *frame = vdec->frames + MAX_REF_FRAMES; if (frame->f.pts) frame->f.pts = 0, frame->drop_pts = 1, n++; } return n; } static void _vdec_hw_h264_dpb_reset (vdec_hw_h264_t *vdec) { uint32_t u; for (u = 0; u < vdec->ref_frames_used; u++) _vdec_hw_h264_frame_free (vdec, vdec->seq.dpb[u], 1); vdec->ref_frames_used = 0; if (!vdec->frames[MAX_REF_FRAMES].is_reference[0] && !vdec->frames[MAX_REF_FRAMES].is_reference[1]) _vdec_hw_h264_frame_free (vdec, vdec->frames + MAX_REF_FRAMES, 0); } static void _vdec_hw_h264_dpb_remove (vdec_hw_h264_t *vdec, uint32_t index) { vdec_hw_h264_frame_int_t *frame = vdec->seq.dpb[index]; uint32_t u; lprintf ("|||||||||||||||||||||||||||||||||||||||| dbp_remove\n"); _vdec_hw_h264_frame_free (vdec, frame, 1); for (u = index + 1; u < vdec->ref_frames_used; u++) vdec->seq.dpb[u - 1] = vdec->seq.dpb[u]; vdec->seq.dpb[u - 1] = frame; vdec->ref_frames_used = u - 1; } static vdec_hw_h264_frame_int_t *_vdec_hw_h264_dpb_get_prev_ref (vdec_hw_h264_t *vdec) { return vdec->ref_frames_used > 0 ? vdec->seq.dpb[vdec->ref_frames_used - 1] : NULL; } static void _vdec_hw_h264_dpb_draw_frames (vdec_hw_h264_t *vdec, int32_t curpoc, int draw_mode) { int i, index; int32_t poc, tpoc; vdec_hw_h264_frame_int_t *frame; do { index = -1; poc = curpoc; for (i = 0; i < (int)vdec->ref_frames_used; i++) { frame = vdec->seq.dpb[i]; tpoc = (frame->TopFieldOrderCnt > frame->BottomFieldOrderCnt) ? frame->TopFieldOrderCnt : frame->BottomFieldOrderCnt; if (!frame->drawn && (tpoc <= poc)) { poc = tpoc; index = i; } } if ((index < 0) || (poc > curpoc)) break; //fprintf(stderr,"|||||||||||||||||||||||||||||||||||||||| dpb_draw_frame = %d\n", poc); frame = vdec->seq.dpb[index]; //fprintf(stderr,"H264 PTS = %llu\n", frame->pts); _vdec_hw_h264_frame_draw (vdec, frame); if ((draw_mode != DPB_DRAW_CLEAR) && !frame->is_reference[0] && !frame->is_reference[1]) _vdec_hw_h264_dpb_remove (vdec, index); } while (index >= 0); if (draw_mode == DPB_DRAW_CURRENT) { frame = &vdec->frames[MAX_REF_FRAMES]; //fprintf(stderr,"|||||||||||||||||||||||||||||||||||||||| dpb_draw_frame = %d\n", curpoc); _vdec_hw_h264_frame_draw (vdec, frame); _vdec_hw_h264_frame_free (vdec, frame, 1); } else if (draw_mode == DPB_DRAW_CLEAR) { _vdec_hw_h264_dpb_reset (vdec); } } static vdec_hw_h264_frame_int_t *_vdec_hw_h264_dpb_get_PicNum (vdec_hw_h264_t *vdec, int32_t pic_num, int *index) { vdec_hw_h264_frame_int_t *frame; uint32_t i; for (i = 0; i < vdec->ref_frames_used; i++) { frame = vdec->seq.dpb[i]; if ((frame->PicNum[0] == pic_num) || (frame->PicNum[1] == pic_num)) { *index = i; return frame; } } return NULL; } static void _vdec_hw_h264_dpb_mmc1 (vdec_hw_h264_t *vdec, int32_t picnum) { int index; vdec_hw_h264_frame_int_t *frame = _vdec_hw_h264_dpb_get_PicNum (vdec, picnum, &index); lprintf ("_vdec_hw_h264_dpb_mmc1\n"); if (frame) { frame->is_reference[0] = frame->is_reference[1] = 0; if (frame->drawn) _vdec_hw_h264_dpb_remove (vdec, index); else _vdec_hw_h264_dpb_draw_frames (vdec, (frame->TopFieldOrderCnt > frame->BottomFieldOrderCnt) ? frame->TopFieldOrderCnt : frame->BottomFieldOrderCnt, DPB_DRAW_REFS); } } static vdec_hw_h264_sps_t *_vdec_hw_h264_get_sps (vdec_hw_h264_t *vdec) { vdec_hw_h264_lps_t *lps = &vdec->seq.lps; vdec_hw_h264_pps_t *pps = vdec->seq.pps[lps->pps_id]; if (!pps) return NULL; return vdec->seq.sps[pps->sps_id]; } static void _vdec_hw_h264_dbp_append (vdec_hw_h264_t *vdec, int second_field) { uint32_t i, index = 0, max_refs = vdec->ref_frames_max; int32_t fnw = MAX_POC; vdec_hw_h264_frame_int_t *tmp = NULL, *cur_pic = &vdec->frames[MAX_REF_FRAMES]; vdec_hw_h264_sps_t *sps = _vdec_hw_h264_get_sps (vdec); if (sps) { max_refs = sps->ref_frames_used ? sps->ref_frames_used : 1; if (max_refs > vdec->ref_frames_max) max_refs = vdec->ref_frames_max; } if (second_field) { tmp = _vdec_hw_h264_dpb_get_prev_ref (vdec); if (tmp) { _vdec_hw_h264_frame_link (vdec, cur_pic, tmp); } else { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": no frame to store the second field ?!\n"); } return; } for (i = 0; i < vdec->ref_frames_used; i++) { if (vdec->seq.dpb[i]->FrameNumWrap < fnw) { fnw = vdec->seq.dpb[i]->FrameNumWrap; index = i; } } if (vdec->ref_frames_used >= max_refs) { if (0 /* sps && sps->reused && (max_refs < vdec->ref_frames_max) */) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": SPS #%d is reused, raising ref frame count from %d to %d.\n", (int)sps->sps_id, (int)max_refs, (int)max_refs + 1); sps->ref_frames_used = ++max_refs; } else { lprintf ("sliding window\n"); tmp = vdec->seq.dpb[index]; tmp->is_reference[0] = tmp->is_reference[1] = 0; if (tmp->drawn) _vdec_hw_h264_dpb_remove (vdec, index); else _vdec_hw_h264_dpb_draw_frames (vdec, (tmp->TopFieldOrderCnt > tmp->BottomFieldOrderCnt) ? tmp->TopFieldOrderCnt : tmp->BottomFieldOrderCnt, DPB_DRAW_REFS); i = vdec->ref_frames_used; } } if (i < max_refs) { /* should always be true */ if (cur_pic->field_pic_flag) { _vdec_hw_h264_frame_link (vdec, cur_pic, vdec->seq.dpb[i]); } else { *vdec->seq.dpb[i] = *cur_pic; cur_pic->f.user_data = NULL; } vdec->ref_frames_used = i + 1; } else { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": too many reference frames (%d).\n", i + 1); } } /*--------------------------------------------------------*/ static void _vdec_hw_h264_reset_slices (vdec_hw_h264_t *vdec) { vdec->seq.slices_count = 0; vdec->seq.slice_mode = 0; } static void _vdec_hw_h264_reset_sequence (vdec_hw_h264_t *vdec) { vdec->seq.prevFrameNum = 0; vdec->seq.prevFrameNumOffset = 0; vdec->seq.prevMMC5 = 0; vdec->seq.startup_frame = 0; vdec->seq.reset = 0; vdec->seq.chroma = 0; vdec->seq.pic_pts = 0; vdec->seq.buf.write = 0; vdec->seq.buf.read = 0; vdec->seq.buf.nal_unit = -1; _vdec_hw_h264_reset_slices (vdec); _vdec_hw_h264_dpb_reset (vdec); _vdec_hw_h264_frame_free (vdec, vdec->frames + MAX_REF_FRAMES, 1); vdec->seq.reset = VDEC_HW_H264_FRAME_NEW_SEQ; } static void _vdec_hw_h264_set_ratio (vdec_hw_h264_t *vdec, vdec_hw_h264_sps_t *sps) { static const double fixed_ratios[] = { (double)1, /* ASPECT_UNSPECIFIED */ (double)1, /* 1/1 */ (double)12 / (double)11, (double)10 / (double)11, (double)16 / (double)11, (double)40 / (double)33, (double)24 / (double)11, (double)20 / (double)11, (double)32 / (double)11, (double)80 / (double)33, (double)18 / (double)11, (double)15 / (double)11, (double)64 / (double)33, (double)160 / (double)99, (double)4 / (double)3, (double)3 / (double)2, (double)2 / (double)1, (double)1 /* RESERVED */ }; if (!vdec->seq.coded_height) vdec->seq.coded_height = 1; vdec->seq.ratio = (double)vdec->seq.coded_width / (double)vdec->seq.coded_height; if (sps->vui.aspect_ratio_info) { if (sps->vui.aspect_ratio_idc < sizeof (fixed_ratios) / sizeof (fixed_ratios[0])) { vdec->seq.ratio *= fixed_ratios[sps->vui.aspect_ratio_idc]; } else if (sps->vui.aspect_ratio_idc == 255) { if (sps->vui.sar_height) vdec->seq.ratio *= (double)sps->vui.sar_width / sps->vui.sar_height; } } } static void parse_scaling_list (bits_reader_t *br, uint8_t *scaling_list, int len, int index) { int last_scale = 8; int next_scale = 8; int32_t delta_scale; uint8_t use_default_scaling_matrix_flag = 0; int i; uint32_t u; const uint8_t *zigzag = (len == 64) ? zigzag_8x8 : zigzag_4x4; for (i = 0; i < len; i++) { if (next_scale != 0) { delta_scale = bits_exp_se (br); next_scale = (last_scale + delta_scale + 256) % 256; if (i == 0 && next_scale == 0) { use_default_scaling_matrix_flag = 1; break; } } scaling_list[zigzag[i]] = last_scale = (next_scale == 0) ? last_scale : next_scale; } if (use_default_scaling_matrix_flag) { switch (index) { case 0: case 1: case 2: { for (u = 0; u < sizeof (default_4x4_intra); u++) scaling_list[zigzag_4x4[u]] = default_4x4_intra[u]; break; } case 3: case 4: case 5: { for (u = 0; u < sizeof (default_4x4_inter); u++) scaling_list[zigzag_4x4[u]] = default_4x4_inter[u]; break; } case 6: { for (u = 0; u < sizeof (default_8x8_intra); u++) scaling_list[zigzag_8x8[u]] = default_8x8_intra[u]; break; } case 7: { for (u = 0; u < sizeof (default_8x8_inter); u++) scaling_list[zigzag_8x8[u]] = default_8x8_inter[u]; break; } } } } static void _vdec_hw_h264_scaling_list_fallback_A (uint8_t * scaling_lists_4x4, uint8_t * scaling_lists_8x8, int i) { uint32_t j; switch (i) { case 0: for (j = 0; j < sizeof (default_4x4_intra); j++) scaling_lists_4x4[(i * 16) + zigzag_4x4[j]] = default_4x4_intra[j]; break; case 3: for (j = 0; j < sizeof (default_4x4_inter); j++) scaling_lists_4x4[(i * 16) + zigzag_4x4[j]] = default_4x4_inter[j]; break; case 1: case 2: case 4: case 5: memcpy (&scaling_lists_4x4[i * 16], &scaling_lists_4x4[(i - 1) * 16], 16); break; case 6: for (j = 0; j < sizeof (default_8x8_intra); j++) scaling_lists_8x8[(i - 6) * 64 + zigzag_8x8[j]] = default_8x8_intra[j]; break; case 7: for (j = 0; j < sizeof (default_8x8_inter); j++) scaling_lists_8x8[(i - 6) * 64 + zigzag_8x8[j]] = default_8x8_inter[j]; break; } } static void _vdec_hw_h264_scaling_list_fallback_B (vdec_hw_h264_sps_t *sps, vdec_hw_h264_pps_t *pps, int i) { switch (i) { case 0: case 3: memcpy (pps->scaling_lists_4x4[i], sps->scaling_lists_4x4[i], sizeof (pps->scaling_lists_4x4[i])); break; case 1: case 2: case 4: case 5: memcpy (pps->scaling_lists_4x4[i], pps->scaling_lists_4x4[i - 1], sizeof (pps->scaling_lists_4x4[i])); break; case 6: case 7: memcpy (pps->scaling_lists_8x8[i - 6], sps->scaling_lists_8x8[i - 6], sizeof (pps->scaling_lists_8x8[i - 6])); break; } } static void _vdec_hw_h264_read_vui (vdec_hw_h264_t *vdec, vdec_hw_h264_vui_t *vui) { bits_reader_t *br = &vdec->seq.br; vdec->seq.color_matrix = 4; /* undefined, mpeg range */ vui->aspect_ratio_info = bits_read (br, 1); lprintf ("aspect_ratio_info_present_flag = %d\n", (int)vui->aspect_ratio_info); if (vui->aspect_ratio_info) { vui->aspect_ratio_idc = bits_read (br, 8); lprintf ("aspect_ratio_idc = %d\n", (int)vui->aspect_ratio_idc); if (vui->aspect_ratio_idc == 255) { vui->sar_width = bits_read (br, 16); lprintf ("sar_width = %d\n", (int)vui->sar_width); vui->sar_height = bits_read (br, 16); lprintf ("sar_height = %d\n", (int)vui->sar_height); } } if (bits_read (br, 1)) /* overscan_info_present_flag */ bits_skip (br, 1); /* overscan_appropriate_falg */ if (bits_read (br, 1)) { /* video_signal_type_present_flag */ bits_skip (br, 3); /* video_format */ vdec->seq.color_matrix = (vdec->seq.color_matrix & ~1) | bits_read (br, 1); /*video_full_range_flag */ vui->colour_desc = bits_read (br, 1); lprintf ("colour_desc = %d\n", (int)vui->colour_desc); if (vui->colour_desc) { bits_skip (br, 16); /* colour_primaries, transfer_characteristics */ vdec->seq.color_matrix = (vdec->seq.color_matrix & 1) | (bits_read (br, 8) << 1); /* matrix_coefficients */ } } if (bits_read (br, 1)) { /* chroma_loc_info_present_flag */ bits_exp_ue (br); /* chroma_sample_loc_type_top_field */ bits_exp_ue (br); /* chroma_sample_loc_type_bottom_field */ } vui->timing_info = bits_read (br, 1); lprintf ("timing_info = %d\n", (int)vui->timing_info); if (vui->timing_info) { /* seen (500, (24000 + 0x80000000)) here... */ vui->num_units_in_tick = bits_read (br, 32) & 0x7fffffff; lprintf ("num_units_in_tick = %d\n", (int)vui->num_units_in_tick); vui->time_scale = bits_read (br, 32) & 0x7fffffff; lprintf ("time_scale = %d\n", (int)vui->time_scale); if (vui->time_scale > 0) { /* good: 2 * 1001 / 48000. */ vdec->seq.video_step = (uint64_t)90000 * 2 * vui->num_units_in_tick / vui->time_scale; if (vdec->seq.video_step < 90) { /* bad: 2 * 1 / 60000. seen this once from broken h.264 video usability info (VUI). * VAAPI seems to apply a similar HACK. */ vdec->seq.video_step = (uint64_t)90000000 * 2 * vui->num_units_in_tick / vui->time_scale; /* seen 1 / 180000, ignore. */ if (vdec->seq.video_step < 1500) vdec->seq.video_step = 0; } } } } static vdec_hw_h264_sps_t *_vdec_hw_h264_read_sps (vdec_hw_h264_t *vdec) { vdec_hw_h264_sps_t tsps, *sps; uint8_t bits; int i; memset (&tsps, 0, sizeof (tsps)); tsps.profile_idc = bits_read (&vdec->seq.br, 8); bits = bits_read (&vdec->seq.br, 8); tsps.constraint_set0_flag = (bits >> 7) & 1; tsps.constraint_set1_flag = (bits >> 6) & 1; tsps.constraint_set2_flag = (bits >> 5) & 1; tsps.constraint_set3_flag = (bits >> 4) & 1; /* skip 4 */ tsps.level_idc = bits_read (&vdec->seq.br, 8); tsps.sps_id = bits_exp_ue (&vdec->seq.br); if (tsps.sps_id > 31) { lprintf ("invalid SPS id %d!!\n", (int)tsps.sps_id); return NULL; } /* this is read only for now. */ tsps.reused = 0; memset (&tsps.scaling_lists_4x4, 16, sizeof (tsps.scaling_lists_4x4)); memset (&tsps.scaling_lists_8x8, 16, sizeof (tsps.scaling_lists_8x8)); tsps.chroma_format_idc = 1; tsps.separate_colour_plane_flag = 0; if (tsps.profile_idc == 100 || tsps.profile_idc == 110 || tsps.profile_idc == 122 || tsps.profile_idc == 244 || tsps.profile_idc == 44 || tsps.profile_idc == 83 || tsps.profile_idc == 86) { tsps.chroma_format_idc = bits_exp_ue (&vdec->seq.br); lprintf ("chroma_format_idc = %d\n", (int)tsps.chroma_format_idc); if (tsps.chroma_format_idc == 3) { tsps.separate_colour_plane_flag = bits_read (&vdec->seq.br, 1); lprintf ("separate_colour_plane_flag = %d\n", (int)tsps.separate_colour_plane_flag); } tsps.bit_depth_luma_minus8 = bits_exp_ue (&vdec->seq.br); lprintf ("bit_depth_luma_minus8 = %d\n", (int)tsps.bit_depth_luma_minus8); tsps.bit_depth_chroma_minus8 = bits_exp_ue (&vdec->seq.br); lprintf ("bit_depth_chroma_minus8 = %d\n", (int)tsps.bit_depth_chroma_minus8); tsps.qpprime_y_zero_transform_bypass_flag = bits_read (&vdec->seq.br, 1); lprintf ("qpprime_y_zero_transform_bypass_flag = %d\n", (int)tsps.qpprime_y_zero_transform_bypass_flag); tsps.seq_scaling_matrix_present_flag = bits_read (&vdec->seq.br, 1); lprintf ("seq_scaling_matrix_present_flag = %d\n", (int)tsps.seq_scaling_matrix_present_flag); if (tsps.seq_scaling_matrix_present_flag) { for (i = 0; i < 8; i++) { int scaling_flag = bits_read (&vdec->seq.br, 1); if (scaling_flag) { if (i < 6) parse_scaling_list (&vdec->seq.br, &tsps.scaling_lists_4x4[i][0], 16, i); else parse_scaling_list (&vdec->seq.br, &tsps.scaling_lists_8x8[i - 6][0], 64, i); } else { _vdec_hw_h264_scaling_list_fallback_A ((uint8_t *)tsps.scaling_lists_4x4, (uint8_t *)tsps.scaling_lists_8x8, i); } } } } tsps.log2_max_frame_num_minus4 = bits_exp_ue (&vdec->seq.br); lprintf ("log2_max_frame_num_minus4 = %d\n", (int)tsps.log2_max_frame_num_minus4); tsps.pic_order_cnt_type = bits_exp_ue (&vdec->seq.br); lprintf ("pic_order_cnt_type = %d\n", (int)tsps.pic_order_cnt_type); if (tsps.pic_order_cnt_type == 0) { tsps.log2_max_pic_order_cnt_lsb_minus4 = bits_exp_ue (&vdec->seq.br); lprintf ("log2_max_pic_order_cnt_lsb_minus4 = %d\n", (int)tsps.log2_max_pic_order_cnt_lsb_minus4); } else if (tsps.pic_order_cnt_type == 1) { tsps.delta_pic_order_always_zero_flag = bits_read (&vdec->seq.br, 1); lprintf ("delta_pic_order_always_zero_flag = %d\n", (int)tsps.delta_pic_order_always_zero_flag); tsps.offset_for_non_ref_pic = bits_exp_se (&vdec->seq.br); lprintf ("offset_for_non_ref_pic = %d\n", (int)tsps.offset_for_non_ref_pic); tsps.offset_for_top_to_bottom_field = bits_exp_se (&vdec->seq.br); lprintf ("offset_for_top_to_bottom_field = %d\n", (int)tsps.offset_for_top_to_bottom_field); tsps.ref_frames_used_in_pic_order_cnt_cycle = bits_exp_ue (&vdec->seq.br); lprintf ("ref_frames_used_in_pic_order_cnt_cycle = %d\n", (int)tsps.ref_frames_used_in_pic_order_cnt_cycle); for (i = 0; i < (int)tsps.ref_frames_used_in_pic_order_cnt_cycle; i++) { tsps.offset_for_ref_frame[i] = bits_exp_se (&vdec->seq.br); lprintf ("offset_for_ref_frame[%d] = %d\n", i, (int)tsps.offset_for_ref_frame[i]); } } tsps.ref_frames_used = bits_exp_ue (&vdec->seq.br); if (tsps.ref_frames_used > 16) tsps.ref_frames_used = 16; lprintf ("ref_frames_used = %d\n", (int)tsps.ref_frames_used); tsps.gaps_in_frame_num_value_allowed_flag = bits_read (&vdec->seq.br, 1); lprintf ("gaps_in_frame_num_value_allowed_flag = %d\n", (int)tsps.gaps_in_frame_num_value_allowed_flag); tsps.pic_width_in_mbs_minus1 = bits_exp_ue (&vdec->seq.br); lprintf ("pic_width_in_mbs_minus1 = %d\n", (int)tsps.pic_width_in_mbs_minus1); tsps.pic_height_in_map_units_minus1 = bits_exp_ue (&vdec->seq.br); lprintf ("pic_height_in_map_units_minus1 = %d\n", (int)tsps.pic_height_in_map_units_minus1); tsps.frame_mbs_only_flag = bits_read (&vdec->seq.br, 1); lprintf ("frame_mbs_only_flag = %d\n", (int)tsps.frame_mbs_only_flag); vdec->seq.coded_width = (tsps.pic_width_in_mbs_minus1 + 1) * 16; vdec->seq.coded_height = (2 - tsps.frame_mbs_only_flag) * (tsps.pic_height_in_map_units_minus1 + 1) * 16; if (!tsps.frame_mbs_only_flag) { tsps.mb_adaptive_frame_field_flag = bits_read (&vdec->seq.br, 1); lprintf ("mb_adaptive_frame_field_flag = %d\n", (int)tsps.mb_adaptive_frame_field_flag); } else { tsps.mb_adaptive_frame_field_flag = 0; } tsps.direct_8x8_inference_flag = bits_read (&vdec->seq.br, 1); lprintf ("direct_8x8_inference_flag = %d\n", (int)tsps.direct_8x8_inference_flag); tsps.frame_cropping_flag = bits_read (&vdec->seq.br, 1); lprintf ("frame_cropping_flag = %d\n", (int)tsps.frame_cropping_flag); if (tsps.frame_cropping_flag) { tsps.frame_crop_left_offset = bits_exp_ue (&vdec->seq.br); lprintf ("frame_crop_left_offset = %d\n", (int)tsps.frame_crop_left_offset); tsps.frame_crop_right_offset = bits_exp_ue (&vdec->seq.br); lprintf ("frame_crop_right_offset = %d\n", (int)tsps.frame_crop_right_offset); tsps.frame_crop_top_offset = bits_exp_ue (&vdec->seq.br); lprintf ("frame_crop_top_offset = %d\n", (int)tsps.frame_crop_top_offset); tsps.frame_crop_bottom_offset = bits_exp_ue (&vdec->seq.br); lprintf ("frame_crop_bottom_offset = %d\n", (int)tsps.frame_crop_bottom_offset); vdec->seq.coded_height -= (2 - tsps.frame_mbs_only_flag) * 2 * tsps.frame_crop_bottom_offset; } /* XXX? */ if (vdec->seq.coded_height == 1088) vdec->seq.coded_height = 1080; tsps.vui_parameters_present_flag = bits_read (&vdec->seq.br, 1); lprintf ("vui_parameters_present_flag = %d\n", (int)tsps.vui_parameters_present_flag); if (tsps.vui_parameters_present_flag) _vdec_hw_h264_read_vui (vdec, &tsps.vui); _vdec_hw_h264_set_ratio (vdec, &tsps); sps = vdec->seq.sps[tsps.sps_id]; if (!sps) { vdec->seq.sps[tsps.sps_id] = sps = malloc (sizeof (*sps)); if (!sps) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": no memory for SPS #%d.}n", (int)tsps.sps_id); return NULL; } vdec->stats.sps++; } else { sps->reused = 0; if (!memcmp (&tsps, sps, sizeof (tsps))) return sps; } memcpy (sps, &tsps, sizeof (tsps)); vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": new SPS #%d.\n", (int)tsps.sps_id); return sps; } static vdec_hw_h264_pps_t *_vdec_hw_h264_read_pps (vdec_hw_h264_t *vdec) { vdec_hw_h264_pps_t *pps, tpps; vdec_hw_h264_sps_t *sps; uint32_t more; uint8_t bits; memset (&tpps, 0, sizeof (tpps)); tpps.pps_id = bits_exp_ue (&vdec->seq.br); tpps.sps_id = bits_exp_ue (&vdec->seq.br); if (tpps.sps_id > 31) { lprintf ("referenced SPS #%d does not exist!!\n", (int)tpps.sps_id); return NULL; } sps = vdec->seq.sps[tpps.sps_id]; if (!sps) { lprintf ("referenced SPS #%d does not exist!!\n", (int)tpps.sps_id); return NULL; } bits = bits_read (&vdec->seq.br, 2); tpps.entropy_coding_mode_flag = (bits >> 1) & 1; tpps.pic_order_present_flag = (bits >> 0) & 1; tpps.num_slice_groups_minus1 = bits_exp_ue (&vdec->seq.br); lprintf ("num_slice_groups_minus1 = %d\n", (int)tpps.num_slice_groups_minus1); if (tpps.num_slice_groups_minus1 > 0) { uint32_t slice_group_id_bits, u, i; for (slice_group_id_bits = 0, u = tpps.num_slice_groups_minus1; u; slice_group_id_bits++, u >>= 1) ; u = 0; tpps.slice_group_map_type = bits_exp_ue (&vdec->seq.br); lprintf ("slice_group_map_type = %d\n", (int)slice_group_map_type); switch (tpps.slice_group_map_type) { case 0: for (i = 0; i <= tpps.num_slice_groups_minus1; i++) { tpps.slice_groups[u].run_length_minus1 = bits_exp_ue (&vdec->seq.br); if (u < VDEC_HW_H264_MAX_SLICE_GROUPS - 1) u++; } break; case 2: for (i = 0; i <= tpps.num_slice_groups_minus1; i++) { bits_exp_ue (&vdec->seq.br); bits_exp_ue (&vdec->seq.br); } break; case 3: case 4: case 5: tpps.slice_group_change_direction_flag = bits_read (&vdec->seq.br, 1); tpps.slice_group_change_rate_minus1 = bits_exp_ue (&vdec->seq.br); break; case 6: tpps.pic_size_in_map_units_minus1 = bits_exp_ue (&vdec->seq.br); for (i = 0; i <= tpps.num_slice_groups_minus1; i++) { tpps.slice_groups[u].id = bits_read (&vdec->seq.br, slice_group_id_bits); if (u < VDEC_HW_H264_MAX_SLICE_GROUPS - 1) u++; } break; default: ; } } else { tpps.slice_group_map_type = 0; } tpps.num_ref_idx_l0_active_minus1 = bits_exp_ue (&vdec->seq.br) & 31; tpps.num_ref_idx_l1_active_minus1 = bits_exp_ue (&vdec->seq.br) & 31; bits = bits_read (&vdec->seq.br, 3); tpps.weighted_pred_flag = (bits >> 2) & 1; tpps.weighted_bipred_idc = (bits >> 0) & 3; tpps.pic_init_qp_minus26 = bits_exp_se (&vdec->seq.br); tpps.pic_init_qs_minus26 = bits_exp_se (&vdec->seq.br); tpps.chroma_qp_index_offset = bits_exp_se (&vdec->seq.br); bits = bits_read (&vdec->seq.br, 3); tpps.deblocking_filter_control_present_flag = (bits >> 2) & 1; tpps.constrained_intra_pred_flag = (bits >> 1) & 1; tpps.redundant_pic_cnt_present_flag = (bits >> 0) & 1; more = bits_valid_left (&vdec->seq.br); /* no typo, we want at least 2 "1" bits. */ if (more > 1) { bits = bits_read (&vdec->seq.br, 2); tpps.transform_8x8_mode_flag = (bits >> 1) & 1; tpps.pic_scaling_matrix_present_flag = (bits >> 0) & 1; if (tpps.pic_scaling_matrix_present_flag) { int i; for (i = 0; i < 8; i++) { if ((i < 6) || tpps.transform_8x8_mode_flag) tpps.pic_scaling_list_present_flag[i] = bits_read (&vdec->seq.br, 1); else tpps.pic_scaling_list_present_flag[i] = 0; if (tpps.pic_scaling_list_present_flag[i]) { if (i < 6) parse_scaling_list (&vdec->seq.br, &tpps.scaling_lists_4x4[i][0], 16, i); else parse_scaling_list (&vdec->seq.br, &tpps.scaling_lists_8x8[i - 6][0], 64, i); } else { if (!sps->seq_scaling_matrix_present_flag) _vdec_hw_h264_scaling_list_fallback_A ((uint8_t *)tpps.scaling_lists_4x4, (uint8_t *)tpps.scaling_lists_8x8, i); else _vdec_hw_h264_scaling_list_fallback_B (sps, &tpps, i); } } } tpps.second_chroma_qp_index_offset = bits_exp_se (&vdec->seq.br); lprintf ("second_chroma_qp_index_offset = %d\n", (int)tpps.second_chroma_qp_index_offset); } else { tpps.transform_8x8_mode_flag = 0; tpps.pic_scaling_matrix_present_flag = 0; tpps.second_chroma_qp_index_offset = tpps.chroma_qp_index_offset; } pps = vdec->seq.pps[tpps.pps_id]; if (!pps) { vdec->seq.pps[tpps.pps_id] = pps = malloc (sizeof (*pps)); if (!pps) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": no memory for PPS #%d.}n", (int)tpps.pps_id); return NULL; } vdec->stats.pps++; } else { if (!memcmp (&tpps, pps, sizeof (tpps))) return pps; } memcpy (pps, &tpps, sizeof (tpps)); vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": new PPS #%d.\n", (int)tpps.pps_id); return pps; } static void _vdec_hw_h264_pred_weight_table (vdec_hw_h264_t *vdec, uint32_t slice_type, uint32_t ChromaArrayType, uint32_t l0, uint32_t l1) { uint32_t i; vdec->seq.lps.pred_weight_table.luma_log2_weight_denom = bits_exp_ue (&vdec->seq.br); if (ChromaArrayType) vdec->seq.lps.pred_weight_table.chroma_log2_weight_denom = bits_exp_ue (&vdec->seq.br); for (i = 0; i <= l0; i++) { if (bits_read (&vdec->seq.br, 1)) { vdec->seq.lps.pred_weight_table.luma_weight_l0[i] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.luma_offset_l0[i] = bits_exp_se (&vdec->seq.br); } if (ChromaArrayType && bits_read (&vdec->seq.br, 1)) { vdec->seq.lps.pred_weight_table.chroma_weight_l0[i][0] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.chroma_weight_l0[i][1] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.chroma_offset_l0[i][0] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.chroma_offset_l0[i][1] = bits_exp_se (&vdec->seq.br); } } if (slice_type == SLICE_TYPE_B) { for (i = 0; i <= l1; i++) { if (bits_read (&vdec->seq.br, 1)) { vdec->seq.lps.pred_weight_table.luma_weight_l1[i] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.luma_offset_l1[i] = bits_exp_se (&vdec->seq.br); } if (ChromaArrayType && bits_read (&vdec->seq.br, 1)) { vdec->seq.lps.pred_weight_table.chroma_weight_l1[i][0] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.chroma_weight_l1[i][1] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.chroma_offset_l1[i][0] = bits_exp_se (&vdec->seq.br); vdec->seq.lps.pred_weight_table.chroma_offset_l1[i][1] = bits_exp_se (&vdec->seq.br); } } } } static void _vdec_hw_h264_ref_pic_list_reordering (vdec_hw_h264_t *vdec) { vdec_hw_h264_lps_t *lps = &vdec->seq.lps; if ((lps->slice_type != SLICE_TYPE_I) && (lps->slice_type != SLICE_TYPE_SI)) { if (bits_read (&vdec->seq.br, 1)) { uint32_t tmp /*, diff */; do { tmp = bits_exp_ue (&vdec->seq.br); if (tmp == 0 || tmp == 1) /*diff =*/ bits_exp_ue (&vdec->seq.br); else if (tmp == 2) /*diff =*/ bits_exp_ue (&vdec->seq.br); } while (tmp != 3 && !vdec->seq.br.oflow); } } if (lps->slice_type == SLICE_TYPE_B) { if (bits_read (&vdec->seq.br, 1)) { uint32_t tmp2/*, diff2*/; do { tmp2 = bits_exp_ue (&vdec->seq.br); if (tmp2 == 0 || tmp2 == 1) /*diff2 =*/ bits_exp_ue (&vdec->seq.br); else if (tmp2 == 2) /*diff2 =*/ bits_exp_ue (&vdec->seq.br); } while (tmp2 != 3 && !vdec->seq.br.oflow); } } } static void _vdec_hw_h264_dec_ref_pic_marking (vdec_hw_h264_t *vdec, uint8_t idr) { int32_t pic_num; if (idr) { #ifdef LOG uint8_t no_output_of_prior_pics_flag = bits_read (&vdec->seq.br, 1); uint8_t long_term_reference_flag = bits_read (&vdec->seq.br, 1); lprintf ("no_output_of_prior_pics_flag = %d\n", (int)no_output_of_prior_pics_flag); lprintf ("long_term_reference_flag = %d\n", (int)long_term_reference_flag); #else bits_skip (&vdec->seq.br, 2); #endif } else { uint8_t adaptive_ref_pic_marking_mode_flag = bits_read (&vdec->seq.br, 1); lprintf ("adaptive_ref_pic_marking_mode_flag = %d\n", (int)adaptive_ref_pic_marking_mode_flag); if (!adaptive_ref_pic_marking_mode_flag) { if (vdec->frames[MAX_REF_FRAMES].field_pic_flag && (vdec->frames[MAX_REF_FRAMES].completed == PICTURE_DONE) && (vdec->frames[MAX_REF_FRAMES].is_reference[0] || vdec->frames[MAX_REF_FRAMES].is_reference[1])) { vdec->frames[MAX_REF_FRAMES].is_reference[0] = vdec->frames[MAX_REF_FRAMES].is_reference[1] = SHORT_TERM_REF; lprintf ("short_ref marking\n"); } // sliding window is always performed in dpb_append() } else { uint8_t memory_management_control_operation; do { memory_management_control_operation = bits_exp_ue (&vdec->seq.br); lprintf ("memory_management_control_operation = %d\n", (int)memory_management_control_operation); if ((memory_management_control_operation == 1) || (memory_management_control_operation == 3)) { uint32_t difference_of_pic_nums_minus1 = bits_exp_ue (&vdec->seq.br); lprintf ("difference_of_pic_nums_minus1 = %d\n", difference_of_pic_nums_minus1); pic_num = vdec->frames[MAX_REF_FRAMES].PicNum[0] - (difference_of_pic_nums_minus1 + 1); _vdec_hw_h264_dpb_mmc1 (vdec, pic_num); } if (memory_management_control_operation == 2) { #ifdef LOG uint32_t long_term_pic_num = bits_exp_ue (&vdec->seq.br); lprintf ("long_term_pic_num = %d\n", (int)long_term_pic_num); #else bits_exp_ue (&vdec->seq.br); #endif } if ((memory_management_control_operation == 3) || (memory_management_control_operation == 6)) { #ifdef LOG uint32_t long_term_frame_idx = bits_exp_ue (&vdec->seq.br); lprintf ("long_term_frame_idx = %d\n", (int)long_term_frame_idx); #else bits_exp_ue (&vdec->seq.br); #endif } if (memory_management_control_operation == 4) { #ifdef LOG uint32_t max_long_term_frame_idx_plus1 = bits_exp_ue (&vdec->seq.br); lprintf ("max_long_term_frame_idx_plus1 = %d\n", max_long_term_frame_idx_plus1); #else bits_exp_ue (&vdec->seq.br); #endif } } while (memory_management_control_operation && !vdec->seq.br.oflow); } } } static void _vdec_hw_h264_slice_header (vdec_hw_h264_t *vdec, uint8_t nal_ref_idc, uint8_t nal_unit_type) { vdec_hw_h264_lps_t *lps = &vdec->seq.lps; vdec_hw_h264_pps_t *pps; vdec_hw_h264_sps_t *sps; lps->nal_ref_idc = nal_ref_idc; lps->nal_unit_type = nal_unit_type; bits_exp_ue (&vdec->seq.br); /* first_mb_in_slice */ lps->slice_type = bits_exp_ue (&vdec->seq.br) % 5; lprintf ("slice_type = %u\n", lps->slice_type); lps->pps_id = bits_exp_ue (&vdec->seq.br); lprintf ("_vdec_hw_h264_read_pps_id = %d\n", (int)lps->pps_id); pps = vdec->seq.pps[lps->pps_id]; if (!pps) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": referenced PPS #%d does not exist!!\n", (int)lps->pps_id); vdec->frames[MAX_REF_FRAMES].missing_header = 1; return; } sps = vdec->seq.sps[pps->sps_id]; if (!sps) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": referenced SPS #%d does not exist!!\n", (int)pps->sps_id); vdec->frames[MAX_REF_FRAMES].missing_header = 1; return; } if (!vdec->seq.startup_frame && (lps->slice_type == SLICE_TYPE_I) && !vdec->frames[MAX_REF_FRAMES].completed) vdec->seq.startup_frame = 1; lprintf ("sps_id = %d\n", (int)pps->sps_id); if (sps->separate_colour_plane_flag) bits_read (&vdec->seq.br, 2); /* colour_plane_id */ lps->frame_num = bits_read (&vdec->seq.br, sps->log2_max_frame_num_minus4 + 4); lprintf ("frame_num = %d\n", (int)lps->frame_num); lps->MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); lps->field_pic_flag = lps->bottom_field_flag = lps->delta_pic_order_cnt_bottom = 0; lps->delta_pic_order_cnt[0] = lps->delta_pic_order_cnt[1] = 0; if (!sps->frame_mbs_only_flag) { lps->field_pic_flag = bits_read (&vdec->seq.br, 1); lprintf ("field_pic_flag = %d\n", (int)lps->field_pic_flag); if (lps->field_pic_flag) { lps->bottom_field_flag = bits_read (&vdec->seq.br, 1); lprintf ("bottom_field_flag = %d\n", (int)lps->bottom_field_flag); } } if (nal_unit_type == NAL_SLICE_IDR) { lps->idr_pic_id = bits_exp_ue (&vdec->seq.br); lprintf ("idr_pic_id = %d\n", (int)lps->idr_pic_id); } if (sps->pic_order_cnt_type == 0) { lps->pic_order_cnt_lsb = bits_read (&vdec->seq.br, sps->log2_max_pic_order_cnt_lsb_minus4 + 4); lprintf ("pic_order_cnt_lsb = %d\n", (int)lps->pic_order_cnt_lsb); if (pps->pic_order_present_flag && !lps->field_pic_flag) { lps->delta_pic_order_cnt_bottom = bits_exp_se (&vdec->seq.br); lprintf ("delta_pic_order_cnt_bottom = %d\n", (int)lps->delta_pic_order_cnt_bottom); } } if ((sps->pic_order_cnt_type == 1) && !sps->delta_pic_order_always_zero_flag) { lps->delta_pic_order_cnt[0] = bits_exp_se (&vdec->seq.br); lprintf ("delta_pic_order_cnt[0] = %d\n", (int)lps->delta_pic_order_cnt[0]); if (pps->pic_order_present_flag && !lps->field_pic_flag) { lps->delta_pic_order_cnt[1] = bits_exp_se (&vdec->seq.br); lprintf ("delta_pic_order_cnt[1] = %d\n", (int)lps->delta_pic_order_cnt[1]); } } if (pps->redundant_pic_cnt_present_flag) { lps->redundant_pic_cnt = bits_exp_ue (&vdec->seq.br); lprintf ("redundant_pic_cnt = %d\n", (int)lps->redundant_pic_cnt); } if (lps->slice_type == SLICE_TYPE_B) bits_skip (&vdec->seq.br, 1); /* direct_spatial_mv_pred_flag */ lps->num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_active_minus1; lps->num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_active_minus1; if ((lps->slice_type == SLICE_TYPE_P) || (lps->slice_type == SLICE_TYPE_SP) || (lps->slice_type == SLICE_TYPE_B)) { if (bits_read (&vdec->seq.br, 1)) { lprintf ("num_ref_idx_active_override_flag = 1\n"); lps->num_ref_idx_l0_active_minus1 = bits_exp_ue (&vdec->seq.br) & 31; if (lps->slice_type == SLICE_TYPE_B) lps->num_ref_idx_l1_active_minus1 = bits_exp_ue (&vdec->seq.br); lprintf ("num_ref_idx_l0_active_minus1 = %d\n", (int)lps->num_ref_idx_l0_active_minus1); lprintf ("num_ref_idx_l1_active_minus1 = %d\n", (int)lps->num_ref_idx_l1_active_minus1); } } } static void _vdec_hw_h264_slice_header_post (vdec_hw_h264_t *vdec) { vdec_hw_h264_lps_t *lps = &vdec->seq.lps; vdec_hw_h264_pps_t *pps; vdec_hw_h264_sps_t *sps; if (!lps->nal_ref_idc) return; pps = vdec->seq.pps[lps->pps_id]; sps = vdec->seq.sps[pps->sps_id]; if ((pps->weighted_pred_flag && ((lps->slice_type == SLICE_TYPE_P) || (lps->slice_type == SLICE_TYPE_SP))) || ((pps->weighted_bipred_idc == 1) && (lps->slice_type == SLICE_TYPE_B))) { uint8_t chroma = (sps->separate_colour_plane_flag) ? 0 : sps->chroma_format_idc; _vdec_hw_h264_pred_weight_table (vdec, lps->slice_type, chroma, lps->num_ref_idx_l0_active_minus1, lps->num_ref_idx_l1_active_minus1); } _vdec_hw_h264_dec_ref_pic_marking (vdec, (lps->nal_unit_type == 5) ? 1 : 0); } static void _vdec_hw_h264_decode_poc (vdec_hw_h264_t *vdec) { vdec_hw_h264_lps_t *lps = &vdec->seq.lps; vdec_hw_h264_pps_t *pps = vdec->seq.pps[lps->pps_id]; vdec_hw_h264_sps_t *sps = vdec->seq.sps[pps->sps_id]; int parity = lps->bottom_field_flag ? 1 : 0; vdec->frames[MAX_REF_FRAMES].used = 1; vdec->frames[MAX_REF_FRAMES].FrameNum = lps->frame_num; vdec->frames[MAX_REF_FRAMES].is_reference[parity] = lps->nal_ref_idc; vdec->frames[MAX_REF_FRAMES].field_pic_flag = lps->field_pic_flag; if (lps->field_pic_flag) { if (!vdec->frames[MAX_REF_FRAMES].completed) vdec->frames[MAX_REF_FRAMES].f.top_field_first = !parity; vdec->frames[MAX_REF_FRAMES].completed |= (parity ? PICTURE_BOTTOM_DONE : PICTURE_TOP_DONE); } else { vdec->frames[MAX_REF_FRAMES].is_reference[!parity] = vdec->frames[MAX_REF_FRAMES].is_reference[parity]; vdec->frames[MAX_REF_FRAMES].completed = PICTURE_DONE; } if (sps->pic_order_cnt_type == 0) { vdec_hw_h264_frame_int_t *prev_frame = _vdec_hw_h264_dpb_get_prev_ref (vdec); int32_t prevPicOrderCntMsb, prevPicOrderCntLsb; uint32_t MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); vdec->frames[MAX_REF_FRAMES].pic_order_cnt_lsb = lps->pic_order_cnt_lsb; vdec->frames[MAX_REF_FRAMES].f.top_field_first = (lps->delta_pic_order_cnt_bottom < 0) ? 0 : 1; if (!prev_frame) { vdec->frames[MAX_REF_FRAMES].PicOrderCntMsb = vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = 0; return; } if (lps->nal_unit_type == NAL_SLICE_IDR) { prevPicOrderCntMsb = prevPicOrderCntLsb = 0; } else if (prev_frame->mmc5) { if (!lps->bottom_field_flag) { prevPicOrderCntMsb = 0; prevPicOrderCntLsb = prev_frame->TopFieldOrderCnt; } else { prevPicOrderCntMsb = prevPicOrderCntLsb = 0; } } else { prevPicOrderCntMsb = prev_frame->PicOrderCntMsb; prevPicOrderCntLsb = prev_frame->pic_order_cnt_lsb; } if ((lps->pic_order_cnt_lsb < prevPicOrderCntLsb) && ((prevPicOrderCntLsb - lps->pic_order_cnt_lsb) >= (int32_t)(MaxPicOrderCntLsb / 2))) vdec->frames[MAX_REF_FRAMES].PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb; else if ((lps->pic_order_cnt_lsb > prevPicOrderCntLsb) && ((lps->pic_order_cnt_lsb - prevPicOrderCntLsb) > (int32_t)(MaxPicOrderCntLsb / 2))) vdec->frames[MAX_REF_FRAMES].PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb; else vdec->frames[MAX_REF_FRAMES].PicOrderCntMsb = prevPicOrderCntMsb; if (!lps->field_pic_flag) { vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].PicOrderCntMsb + lps->pic_order_cnt_lsb; vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt + lps->delta_pic_order_cnt_bottom; } else { if (lps->bottom_field_flag) vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].PicOrderCntMsb + lps->pic_order_cnt_lsb; else vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].PicOrderCntMsb + lps->pic_order_cnt_lsb; } } else { int16_t FrameNumOffset, prevFrameNumOffset; uint16_t MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4); if (lps->nal_unit_type == NAL_SLICE_IDR) { FrameNumOffset = 0; } else { if (vdec->seq.prevMMC5) prevFrameNumOffset = 0; else prevFrameNumOffset = vdec->seq.prevFrameNumOffset; if (vdec->seq.prevFrameNum > lps->frame_num) FrameNumOffset = prevFrameNumOffset + MaxFrameNum; else FrameNumOffset = prevFrameNumOffset; } if (sps->pic_order_cnt_type == 1) { int16_t absFrameNum = 0, picOrderCntCycleCnt = 0, frameNumInPicOrderCntCycle = 0, expectedDeltaPerPicOrderCntCycle = 0, expectedPicOrderCnt = 0; int i; if (sps->ref_frames_used_in_pic_order_cnt_cycle) absFrameNum = FrameNumOffset + lps->frame_num; if (!lps->nal_ref_idc && (absFrameNum > 0)) --absFrameNum; for (i = 0; i < sps->ref_frames_used_in_pic_order_cnt_cycle; i++) expectedDeltaPerPicOrderCntCycle += sps->offset_for_ref_frame[i]; if (absFrameNum > 0) { picOrderCntCycleCnt = (absFrameNum - 1) / sps->ref_frames_used_in_pic_order_cnt_cycle; frameNumInPicOrderCntCycle = (absFrameNum - 1) % sps->ref_frames_used_in_pic_order_cnt_cycle; expectedPicOrderCnt = picOrderCntCycleCnt * expectedDeltaPerPicOrderCntCycle; for (i = 0; i < frameNumInPicOrderCntCycle; i++) expectedPicOrderCnt += sps->offset_for_ref_frame[i]; } if (!lps->nal_ref_idc) expectedPicOrderCnt += sps->offset_for_non_ref_pic; if (!lps->field_pic_flag) { vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = expectedPicOrderCnt + lps->delta_pic_order_cnt[0]; vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt + sps->offset_for_top_to_bottom_field + lps->delta_pic_order_cnt[1]; } else if (!lps->bottom_field_flag) vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = expectedPicOrderCnt + lps->delta_pic_order_cnt[0]; else vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = expectedPicOrderCnt + sps->offset_for_top_to_bottom_field + lps->delta_pic_order_cnt[1]; } else { int32_t tmpPicOrderCnt; if (lps->nal_unit_type == NAL_SLICE_IDR) tmpPicOrderCnt = 0; else if (!lps->nal_ref_idc) tmpPicOrderCnt = 2 * (FrameNumOffset + lps->frame_num) - 1; else tmpPicOrderCnt = 2 * (FrameNumOffset + lps->frame_num); if (!lps->field_pic_flag) vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = tmpPicOrderCnt; else if (lps->bottom_field_flag) vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = tmpPicOrderCnt; else vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = tmpPicOrderCnt; } vdec->seq.prevFrameNum = vdec->frames[MAX_REF_FRAMES].FrameNum; vdec->seq.prevFrameNumOffset = FrameNumOffset; } if (vdec->frames[MAX_REF_FRAMES].completed < PICTURE_DONE) { if (lps->bottom_field_flag) vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt; else vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt = vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt; } } static void _vdec_hw_h264_decode_picnum (vdec_hw_h264_t *vdec) { vdec_hw_h264_lps_t *lps = &vdec->seq.lps; vdec_hw_h264_frame_int_t *frame; int parity = lps->bottom_field_flag ? 1 : 0; uint32_t i; frame = &vdec->frames[MAX_REF_FRAMES]; if (!frame->field_pic_flag) frame->PicNum[0] = frame->FrameNum; else frame->PicNum[parity] = 2 * frame->FrameNum + 1; for (i = 0; i < vdec->ref_frames_used; i++) { frame = vdec->seq.dpb[i]; if (frame->FrameNum > vdec->frames[MAX_REF_FRAMES].FrameNum) frame->FrameNumWrap = frame->FrameNum - lps->MaxFrameNum; else frame->FrameNumWrap = frame->FrameNum; if (!lps->field_pic_flag) { frame->PicNum[0] = frame->PicNum[1] = frame->FrameNumWrap; } else { frame->PicNum[0] = 2 * frame->FrameNumWrap + (parity ? 0 : 1); frame->PicNum[1] = 2 * frame->FrameNumWrap + (parity ? 1 : 0); } } } static int _vdec_hw_h264_check_ref_list (vdec_hw_h264_t *vdec) { int i, j, bad_frame = 0; vdec_hw_h264_frame_int_t *frame; vdec_hw_h264_lps_t *lps = &vdec->seq.lps; vdec_hw_h264_pps_t *pps = vdec->seq.pps[lps->pps_id]; vdec_hw_h264_sps_t *sps = vdec->seq.sps[pps->sps_id]; int prefs = 0; int brefs = 0; int poc, curpoc; int fps; // int fps = (double)sps->vui.time_scale / (double)sps->vui.num_units_in_tick / ( 2 - lps->field_pic_flag ); fps = (1 + lps->field_pic_flag) * 2 * sps->ref_frames_used; if (vdec->seq.startup_frame >= fps) return 0; curpoc = (vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt > vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt) ? vdec->frames[MAX_REF_FRAMES].TopFieldOrderCnt : vdec->frames[MAX_REF_FRAMES].BottomFieldOrderCnt; for (i = vdec->ref_frames_used - 1; i >= 0; i--) { frame = vdec->seq.dpb[i]; poc = (frame->TopFieldOrderCnt > frame->BottomFieldOrderCnt) ? frame->TopFieldOrderCnt : frame->BottomFieldOrderCnt; if (vdec->frames[MAX_REF_FRAMES].field_pic_flag) { if (!frame->f.bad_frame) { for (j = 0; j < 2; j++) { if (frame->is_reference[j]) { if (poc <= curpoc) ++prefs; else ++brefs; } } } } else { if (!frame->f.bad_frame) { if (poc <= curpoc) ++prefs; else ++brefs; } } } if (lps->slice_type != SLICE_TYPE_I) { if (vdec->ref_frames_used <= 0) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": first frame after seek is type %s??\n", (lps->slice_type == SLICE_TYPE_B) ? "B" : "P"); } if (prefs < (int)(lps->num_ref_idx_l0_active_minus1 + 1)) bad_frame = 1; if (lps->slice_type == SLICE_TYPE_B) { if (brefs < (int)(lps->num_ref_idx_l1_active_minus1 + 1)) bad_frame = 1; } } if (bad_frame) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": pts %" PRId64 ": Missing ref frames. refs=%d l0=%d prefs=%d l1=%d brefs=%d type=%s (%d fps)\n", vdec->seq.pic_pts, sps->ref_frames_used, (int)lps->num_ref_idx_l0_active_minus1 + 1, prefs, (int)lps->num_ref_idx_l1_active_minus1 + 1, brefs, (lps->slice_type == SLICE_TYPE_B) ? "B" : "P", fps); } /* else { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_DEBUG, LOG_MODULE ": GOOD ! nrf=%d lo=%d prefs=%d l1=%d brefs=%d type=%d (%d fps)\n", (int)sps->ref_frames_used, (int)lps->num_ref_idx_l0_active_minus1 + 1, (int)prefs, (int)lps->num_ref_idx_l1_active_minus1 + 1, (int)brefs, lps->slice_type, fps ); ] */ if (vdec->frames[MAX_REF_FRAMES].is_reference[0] || vdec->frames[MAX_REF_FRAMES].is_reference[1]) ++vdec->seq.startup_frame; return bad_frame; } static int _vdec_hw_h264_render (vdec_hw_h264_t *vdec, int bad_frame) { int i, j; vdec_hw_h264_frame_int_t *frame; vdec_hw_h264_sps_t *sps; vdec_hw_h264_pps_t *pps; vdec_hw_h264_lps_t *lps; frame = vdec->frames + MAX_REF_FRAMES; frame->f.width = vdec->seq.coded_width; frame->f.height = vdec->seq.coded_height; frame->f.duration = vdec->seq.video_step; frame->f.ratio = vdec->seq.user_ratio > 0.001 ? vdec->seq.user_ratio : vdec->seq.ratio; frame->f.color_matrix = vdec->seq.color_matrix; frame->f.flags = VDEC_HW_H264_FRAME_TOP_FIELD | VDEC_HW_H264_FRAME_BOTTOM_FIELD | vdec->seq.reset; if (frame->completed == PICTURE_DONE) { frame->f.pts = vdec->seq.pic_pts; vdec->seq.pic_pts = 0; } if (frame->drop_pts) frame->f.pts = 0; frame->f.bad_frame = bad_frame; lps = &vdec->seq.lps; pps = vdec->seq.pps[lps->pps_id]; if (!pps) return 0; sps = vdec->seq.sps[pps->sps_id]; if (!sps) return 0; frame->f.profile = sps->profile_idc; frame->f.level = sps->level_idc; frame->f.num_ref_frames = sps->ref_frames_used; if (sps->frame_mbs_only_flag) frame->f.progressive_frame = -1; if (!frame->field_pic_flag || (frame->completed < PICTURE_DONE)) { _vdec_hw_h264_frame_new (vdec, frame); vdec->seq.reset = 0; } /* FIXME: I-frames need not be seek points. They can appear in the * middle of a group of pictures (GOP), with frames after that * reference frames before. However, many containers nevertheless * mark _all_ I-frames as seekable. A seek may thus lead to a * short period of missing ref frames. * We can skip decoding here, which means extra artifacts. * We can try to decode anyway, which may crash. * We can wait for a real seek point, with a large gap. * Any ideas? */ /* if (bad_frame) return 0; */ vdec->seq.info.field_order_cnt[0] = frame->TopFieldOrderCnt; vdec->seq.info.field_order_cnt[1] = frame->BottomFieldOrderCnt; vdec->seq.info.is_reference = lps->nal_ref_idc ? 1 : 0; vdec->seq.info.frame_num = lps->frame_num; vdec->seq.info.field_pic_flag = lps->field_pic_flag; vdec->seq.info.bottom_field_flag = lps->bottom_field_flag; vdec->seq.info.num_ref_frames = sps->ref_frames_used; vdec->seq.info.gaps_in_frame_num_value_allowed_flag = sps->gaps_in_frame_num_value_allowed_flag; vdec->seq.info.mb_adaptive_frame_field_flag = sps->mb_adaptive_frame_field_flag && !lps->field_pic_flag; vdec->seq.info.constrained_intra_pred_flag = pps->constrained_intra_pred_flag; vdec->seq.info.weighted_pred_flag = pps->weighted_pred_flag; vdec->seq.info.weighted_bipred_idc = pps->weighted_bipred_idc; vdec->seq.info.frame_mbs_only_flag = sps->frame_mbs_only_flag; vdec->seq.info.transform_8x8_mode_flag = pps->transform_8x8_mode_flag; vdec->seq.info.bit_depth_luma_minus8 = sps->bit_depth_luma_minus8; vdec->seq.info.bit_depth_chroma_minus8 = sps->bit_depth_chroma_minus8; vdec->seq.info.chroma_format_idc = sps->chroma_format_idc; vdec->seq.info.separate_colour_plane_flag = sps->separate_colour_plane_flag; vdec->seq.info.chroma_qp_index_offset = pps->chroma_qp_index_offset; vdec->seq.info.second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset; vdec->seq.info.pic_init_qp_minus26 = pps->pic_init_qp_minus26; vdec->seq.info.pic_init_qs_minus26 = pps->pic_init_qs_minus26; vdec->seq.info.num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_active_minus1; vdec->seq.info.num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_active_minus1; vdec->seq.info.log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4; vdec->seq.info.pic_order_cnt_type = sps->pic_order_cnt_type; vdec->seq.info.log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_pic_order_cnt_lsb_minus4; vdec->seq.info.delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag; vdec->seq.info.direct_8x8_inference_flag = sps->direct_8x8_inference_flag; vdec->seq.info.entropy_coding_mode_flag = pps->entropy_coding_mode_flag; vdec->seq.info.pic_order_present_flag = pps->pic_order_present_flag; vdec->seq.info.deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag; vdec->seq.info.redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present_flag; vdec->seq.info.num_slice_groups_minus1 = pps->num_slice_groups_minus1; vdec->seq.info.slice_group_map_type = pps->slice_group_map_type; vdec->seq.info.slice_count = vdec->seq.slices_count; vdec->seq.info.slices_bitstream = (const uint8_t * const *)vdec->seq.slices_bitstream; vdec->seq.info.slices_bytes = (const uint32_t *)vdec->seq.slices_bytes; if (!pps->pic_scaling_matrix_present_flag) { memcpy (vdec->seq.info.scaling_lists_4x4, sps->scaling_lists_4x4, sizeof (vdec->seq.info.scaling_lists_4x4)); memcpy (vdec->seq.info.scaling_lists_8x8, sps->scaling_lists_8x8, sizeof (vdec->seq.info.scaling_lists_8x8)); } else { memcpy (vdec->seq.info.scaling_lists_4x4, pps->scaling_lists_4x4, sizeof (vdec->seq.info.scaling_lists_4x4)); memcpy (vdec->seq.info.scaling_lists_8x8, pps->scaling_lists_8x8, sizeof (vdec->seq.info.scaling_lists_8x8)); } for (i = vdec->ref_frames_used - 1, j = 0; i >= 0; i--, j++) { vdec_hw_h264_info_ref_frame_t *ref = vdec->seq.info.referenceFrames + j; vdec_hw_h264_frame_int_t *rf = vdec->seq.dpb[i]; ref->frame = &rf->f; ref->is_long_term = 0; ref->frame_idx = rf->FrameNum; ref->top_is_reference = rf->is_reference[0] ? 1 : 0; ref->bottom_is_reference = rf->is_reference[1] ? 1 : 0; ref->field_order_cnt[0] = rf->TopFieldOrderCnt; ref->field_order_cnt[1] = rf->BottomFieldOrderCnt; } for (; j < MAX_REF_FRAMES; j++) { vdec_hw_h264_info_ref_frame_t *ref = vdec->seq.info.referenceFrames + j; ref->frame = NULL; ref->is_long_term = 0; ref->frame_idx = 0; ref->top_is_reference = 0; ref->bottom_is_reference = 0; ref->field_order_cnt[0] = 0; ref->field_order_cnt[1] = 0; } frame->f.info = &vdec->seq.info; i = 1; if (vdec->frame_render) { i = vdec->frame_render (vdec->user_data, &frame->f); if (!i) { frame->f.bad_frame = 2; vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": pts %" PRId64 ": render failure.\n", vdec->seq.pic_pts); } } frame->f.info = NULL; return i; } static int _vdec_hw_h264_decode_picture (vdec_hw_h264_t *vdec) { vdec_hw_h264_frame_int_t *cur_frame = &vdec->frames[MAX_REF_FRAMES]; vdec_hw_h264_lps_t *lps = &vdec->seq.lps; int res; if (cur_frame->missing_header || !vdec->seq.startup_frame) { _vdec_hw_h264_frame_free (vdec, cur_frame, 1); lprintf ("MISSING_HEADER or !startup_frame\n\n"); return 0; } if (cur_frame->completed && cur_frame->field_pic_flag) { int wrong_field = 0; if ((lps->frame_num != cur_frame->FrameNum) || (lps->bottom_field_flag && (cur_frame->completed == PICTURE_BOTTOM_DONE)) || (!lps->bottom_field_flag && (cur_frame->completed == PICTURE_TOP_DONE)) || !lps->field_pic_flag) { wrong_field = 1; } if (wrong_field) { fprintf (stderr, "vdpau_h264_alter : Wrong field, skipping.\n"); _vdec_hw_h264_frame_free (vdec, cur_frame, 1); _vdec_hw_h264_dpb_reset (vdec); cur_frame->missing_header = 1; vdec->seq.startup_frame = 0; return 0; } } /* picture decoding */ _vdec_hw_h264_decode_poc (vdec); lprintf ("TopFieldOrderCnt = %d - BottomFieldOrderCnt = %d\n", cur_frame->TopFieldOrderCnt, cur_frame->BottomFieldOrderCnt); if (lps->nal_unit_type == 5) { _vdec_hw_h264_dpb_draw_frames (vdec, MAX_POC, DPB_DRAW_CLEAR); vdec->seq.startup_frame = START_IDR_FLAG; } _vdec_hw_h264_decode_picnum (vdec); _vdec_hw_h264_ref_pic_list_reordering (vdec); lprintf ("............................. slices_count = %d\n", vdec->seq.slices_count); res = _vdec_hw_h264_render (vdec, _vdec_hw_h264_check_ref_list (vdec)); /* _vdec_hw_h264_dec_ref_pic_marking */ _vdec_hw_h264_slice_header_post (vdec); if (!cur_frame->is_reference[0] && !cur_frame->is_reference[1]) { if (cur_frame->completed == PICTURE_DONE) { _vdec_hw_h264_dpb_draw_frames (vdec, (cur_frame->TopFieldOrderCnt > cur_frame->BottomFieldOrderCnt) ? cur_frame->TopFieldOrderCnt : cur_frame->BottomFieldOrderCnt, DPB_DRAW_CURRENT); } } else { if (vdec->seq.sps[vdec->seq.pps[lps->pps_id]->sps_id]->pic_order_cnt_type == 2) _vdec_hw_h264_dpb_draw_frames (vdec, (cur_frame->TopFieldOrderCnt > cur_frame->BottomFieldOrderCnt) ? cur_frame->TopFieldOrderCnt : cur_frame->BottomFieldOrderCnt, DPB_DRAW_REFS); _vdec_hw_h264_dbp_append (vdec, (!lps->field_pic_flag || cur_frame->completed < PICTURE_DONE) ? 0 : 1); } if (cur_frame->completed == PICTURE_DONE) _vdec_hw_h264_frame_free (vdec, cur_frame, 1); lprintf ("\n___________________________________________________________________________________________\n\n"); return res; } static int _vdec_hw_h264_flush_slices (vdec_hw_h264_t *vdec, uint32_t new_type) { if (vdec->seq.slices_count && ((new_type != vdec->seq.slice_mode) || (vdec->seq.slices_count >= MAX_SLICES))) { int res = _vdec_hw_h264_decode_picture (vdec); vdec->seq.slices_count = 0; vdec->seq.slice_mode = new_type; return res; } vdec->seq.slice_mode = new_type; return 0; } static int _vdec_hw_h264_nal_unit (vdec_hw_h264_t *vdec, uint8_t *buf, uint32_t len) { static const uint8_t flush[32] = { [NAL_SLICE_IDR] = NAL_SLICE_IDR, [NAL_SLICE_NO_IDR] = NAL_SLICE_NO_IDR }; int ret; uint8_t nal_ref_idc, nal_unit_type; uint32_t ulen; vdec_hw_h264_sps_t *sps; /* forbidden_zero_bit 7 */ nal_ref_idc = (*buf >> 5) & 3; nal_unit_type = *buf & 0x1f; lprintf ("NAL size = %d, nal_ref_idc = %d, nal_unit_type = %d\n", (int)len, (int)nal_ref_idc, (int)nal_unit_type); /* a lost reader looks for standard nal heads (0, 0, 1, type) to get back on track. * unfortunately, such byte sequence may appear elsewhere - for example from sps.vui * frame timing fields who are plain uint32, not exp_ue. * encoders/muxers work around and insert 0x03 break bytes. * remove them here (not generally in bits reader like before). */ ret = _vdec_hw_h264_flush_slices (vdec, flush[nal_unit_type]); switch (nal_unit_type) { case NAL_END_SEQUENCE: _vdec_hw_h264_dpb_draw_frames (vdec, MAX_POC, DPB_DRAW_CLEAR); vdec->seq.reset = VDEC_HW_H264_FRAME_NEW_SEQ; vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": sequence end.\n"); /* TJ. got some buggy .mp4 files there made from multiple sequences. * the NAL_END_SEQUENCE's are still there, buf the NAL_SEQUENCE's have * been dropped in favour of a single global config. */ sps = _vdec_hw_h264_get_sps (vdec); if (sps) sps->reused = 1; break; case NAL_SEQUENCE: /* this is just for us, unescape and read in place. */ ulen = _vdec_hw_h264_unescape (buf + 1, len); bits_set_buf (&vdec->seq.br, buf + 1, ulen); sps = _vdec_hw_h264_read_sps (vdec); if (!sps) { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": ERROR: sequence start failed.\n"); } break; case NAL_PICTURE: /* this is just for us, unescape and read in place. */ ulen = _vdec_hw_h264_unescape (buf + 1, len); bits_set_buf (&vdec->seq.br, buf + 1, ulen); _vdec_hw_h264_read_pps (vdec); break; case NAL_SLICE_IDR: case NAL_SLICE_NO_IDR: /* copy, unescape and read the small head here, and pass the whole original to hw later. */ ulen = len > 256 ? 256 : len; memcpy (vdec->tempbuf, buf + 1, ulen); ulen = _vdec_hw_h264_unescape (vdec->tempbuf, ulen); bits_set_buf (&vdec->seq.br, vdec->tempbuf, ulen); _vdec_hw_h264_slice_header (vdec, nal_ref_idc, nal_unit_type); vdec->seq.slices_bitstream[vdec->seq.slices_count] = buf; vdec->seq.slices_bytes[vdec->seq.slices_count] = len; vdec->seq.slices_count++; if ((int)vdec->seq.slices_count > vdec->stats.slices) vdec->stats.slices = vdec->seq.slices_count; break; case NAL_SEI: case NAL_SEEK_POINT: case NAL_FILLER: break; default: vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": unhandled nal unit type %d.\n", (int)nal_unit_type); } return ret; } int vdec_hw_h264_put_config (vdec_hw_h264_t *vdec, const uint8_t *bitstream, uint32_t num_bytes) { const uint8_t *buf, *e; uint32_t count, i; if (!vdec || !bitstream || (num_bytes < 7)) return 0; lprintf ("vdec_hw_h264_put_config\n"); /* reserved:8, profile_idc:8, reserved:8, level_idc:8, reserved:6 frame_header_size_minus_1:2 */ vdec->seq.nal_unit_prefix = (bitstream[4] & 3) + 1; buf = bitstream + 5; e = bitstream + num_bytes; /* reserved:3, sps_count:5 */ count = *buf++ & 31; for (i = 0; i < count; i++) { uint32_t sps_size, s2; if (buf + 2 > e) return 1; sps_size = ((uint32_t)buf[0] << 8) + buf[1], buf += 2; if (buf + sps_size > e) sps_size = e - buf; memcpy (vdec->tempbuf, buf, sps_size); s2 = _vdec_hw_h264_unescape (vdec->tempbuf, sps_size); /* reserved:8 */ bits_set_buf (&vdec->seq.br, vdec->tempbuf + 1, s2 ? s2 - 1 : 0); _vdec_hw_h264_read_sps (vdec); buf += sps_size; } if (buf + 1 > e) return 1; count = *buf++; for (i = 0; i < count; i++) { uint32_t pps_size, s2; if (buf + 2 > e) return 1; pps_size = ((uint32_t)buf[0] << 8) + buf[1], buf += 2; if (buf + pps_size > e) pps_size = e - buf; memcpy (vdec->tempbuf, buf, pps_size); s2 = _vdec_hw_h264_unescape (vdec->tempbuf, pps_size); /* reserved:8 */ bits_set_buf (&vdec->seq.br, vdec->tempbuf + 1, s2 ? s2 - 1 : 0); _vdec_hw_h264_read_pps (vdec); buf += pps_size; } return 1; } static void _vdec_hw_h264_flush_buffer (vdec_hw_h264_t *vdec) { uint32_t drop, keep; drop = vdec->seq.buf.nal_unit >= 0 ? (uint32_t)vdec->seq.buf.nal_unit : vdec->seq.buf.read; if (vdec->seq.slices_count > 0) { uint32_t d2 = vdec->seq.slices_bitstream[0] - vdec->seq.buf.mem; if (d2 < drop) drop = d2; } keep = vdec->seq.buf.write - drop; /* printf ("--------[%d/%d]\n", (int)drop, (int)keep); */ if (drop) { int i; if (keep) { if (keep > drop) memmove (vdec->seq.buf.mem, vdec->seq.buf.mem + drop, keep); else memcpy (vdec->seq.buf.mem, vdec->seq.buf.mem + drop, keep); } for (i = 0; i < vdec->seq.slices_count; i++) vdec->seq.slices_bitstream[i] -= drop; } vdec->seq.buf.write = keep; vdec->seq.buf.read -= drop; if (vdec->seq.buf.nal_unit >= 0) { vdec->seq.buf.nal_unit -= drop; if ((uint32_t)vdec->seq.buf.nal_unit > vdec->seq.buf.write) vdec->seq.buf.nal_unit = -1; } } int vdec_hw_h264_put_frame (vdec_hw_h264_t *vdec, int64_t pts, const uint8_t *bitstream, uint32_t num_bytes, int frame_end) { uint32_t nal_unit_prefix = vdec->seq.nal_unit_prefix; int flush; if (!vdec) return 1; if (!bitstream || !num_bytes) { if (!frame_end) return 1; } else { uint32_t s; /* if this really is the start of a new frame, flush the previous one * before all that memcpy's. */ if ((vdec->seq.buf.nal_unit >= 0) && (num_bytes > 4) && !memcmp (bitstream, "\x00\x00\x00\x01", 4)) { _vdec_hw_h264_nal_unit (vdec, vdec->seq.buf.mem + vdec->seq.buf.nal_unit + 3, vdec->seq.buf.write - vdec->seq.buf.nal_unit - 3); vdec->seq.buf.read = vdec->seq.buf.write; vdec->seq.buf.nal_unit = -1; _vdec_hw_h264_flush_slices (vdec, bitstream[4] & 0x1f); _vdec_hw_h264_flush_buffer (vdec); } s = vdec->seq.buf.write + num_bytes; if (s > vdec->seq.buf.max) { if (s > MAX_BUFFER_SIZE) vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": frame too large, truncating.\n"); s = s * 3 / 2; if (s > MAX_BUFFER_SIZE) s = MAX_BUFFER_SIZE; if (s > vdec->seq.buf.max) { uint8_t *nb = realloc (vdec->seq.buf.mem, s + BUF_PAD); if (nb) { int i; for (i = 0; i < vdec->seq.slices_count; i++) vdec->seq.slices_bitstream[i] = nb + (vdec->seq.slices_bitstream[i] - vdec->seq.buf.mem); vdec->seq.buf.mem = nb; vdec->seq.buf.max = s; vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_DEBUG, LOG_MODULE ": enlarged bitstream buffer to %u bytes.\n", (unsigned int)vdec->seq.buf.max); } else { vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": cannot enlarge bitstream buffer, truncating.\n"); } } } s = vdec->seq.buf.max - vdec->seq.buf.write; if (s > num_bytes) s = num_bytes; memcpy (vdec->seq.buf.mem + vdec->seq.buf.write, bitstream, s); vdec->seq.buf.write += s; memset (vdec->seq.buf.mem + vdec->seq.buf.write, 0, BUF_PAD); } /* always decode into cur_frame (vdec->frames[MAX_REF_FRAMES]). * if this is a reference frame, move it to the dpb array. * otherwise, draw and free immediately. */ /* TJ. I once made an .mp4 file with ffmpeg -vcodec copy. It has a global config (just fine), * but then the frames have standard nal units... */ if (vdec->seq.buf.nal_unit >= 0) nal_unit_prefix = 0; if (nal_unit_prefix && (vdec->seq.buf.write - vdec->seq.buf.read > 4)) { if (!memcmp (vdec->seq.buf.mem + vdec->seq.buf.read, "\x00\x00\x00\x01", 4) && ((vdec->seq.buf.mem[vdec->seq.buf.read + 4] & 0x1f) != NAL_END_SEQUENCE)) nal_unit_prefix = 0; } if (nal_unit_prefix) { if (!vdec->seq.pic_pts) vdec->seq.pic_pts = pts; if (frame_end) { uint8_t *p = vdec->seq.buf.mem + vdec->seq.buf.read; uint8_t *e = vdec->seq.buf.mem + vdec->seq.buf.write; lprintf ("frame_end && vdec->seq.nal_unit_prefix\n"); while (p < e) { uint32_t s = 0; vdec->seq.buf.read = p - vdec->seq.buf.mem; switch (vdec->seq.nal_unit_prefix) { case 4: s = *p++; s <<= 8; /* fall through */ case 3: s += *p++; s <<= 8; /* fall through */ case 2: s += *p++; s <<= 8; /* fall through */ default: s += *p++; } if (p >= e) break; if ((s > 0x00ffffff) || (p + s > e)) s = e - p; _vdec_hw_h264_nal_unit (vdec, p, s); p += s; } _vdec_hw_h264_flush_slices (vdec, 0); vdec->seq.buf.read = vdec->seq.buf.write = 0; vdec->seq.buf.nal_unit = -1; } return 0; } flush = 0; while (1) { uint8_t *b = vdec->seq.buf.mem + vdec->seq.buf.read; uint8_t *e = vdec->seq.buf.mem + vdec->seq.buf.write; uint32_t v; memcpy (e, "\x00\x00\x01", 4); v = 0xffffff00; do { v = (v + *b++) << 8; } while (v != 0x00000100); if (b >= e) { /* we hit our fake stop mark. last unit may or may not be complete. * rewind read pos a bit to amke sure that a possible begun standard unit * prefix will be recognized next time. */ vdec->seq.buf.read = vdec->seq.buf.read + 3 > vdec->seq.buf.write ? vdec->seq.buf.read : vdec->seq.buf.write - 3; break; } vdec->seq.buf.read = b - vdec->seq.buf.mem - 3; if (vdec->seq.buf.nal_unit >= 0) { flush += _vdec_hw_h264_nal_unit (vdec, vdec->seq.buf.mem + vdec->seq.buf.nal_unit + 3, vdec->seq.buf.read - vdec->seq.buf.nal_unit - 3); vdec->seq.buf.nal_unit = -1; } { uint8_t tb = b[0] & 0x1f; vdec->seq.buf.nal_unit = vdec->seq.buf.read; if (((tb == NAL_SLICE_NO_IDR) || (tb == NAL_SLICE_IDR)) && !vdec->seq.pic_pts) vdec->seq.pic_pts = pts; if (tb == NAL_END_SEQUENCE) { _vdec_hw_h264_dpb_draw_frames (vdec, MAX_POC, DPB_DRAW_CLEAR); lprintf ("NAL_END_SEQUENCE\n"); } vdec->seq.buf.read += 1; } if (vdec->seq.buf.read > vdec->seq.buf.write) vdec->seq.buf.read = vdec->seq.buf.write; } if (vdec->seq.buf.nal_unit >= 0) { uint8_t tb = vdec->seq.buf.mem[vdec->seq.buf.nal_unit + 3] & 0x1f; /* in nal_unit_prefix workaround mode, assume this last nalu complete. */ if (vdec->seq.nal_unit_prefix) { if (frame_end) { _vdec_hw_h264_nal_unit (vdec, vdec->seq.buf.mem + vdec->seq.buf.nal_unit + 3, vdec->seq.buf.write - vdec->seq.buf.nal_unit - 3); if (((tb == NAL_SLICE_NO_IDR) || (tb == NAL_SLICE_IDR)) && !vdec->seq.pic_pts) vdec->seq.pic_pts = pts; _vdec_hw_h264_flush_slices (vdec, 0); vdec->seq.buf.read = vdec->seq.buf.write = 0; vdec->seq.buf.nal_unit = -1; } } /* sequence end just has the type byte. do it right now. */ else if (tb == NAL_END_SEQUENCE) { _vdec_hw_h264_nal_unit (vdec, vdec->seq.buf.mem + vdec->seq.buf.nal_unit + 3, 1); vdec->seq.buf.nal_unit = -1; } else if (((tb == NAL_SLICE_NO_IDR) || (tb == NAL_SLICE_IDR)) && !vdec->seq.pic_pts) { vdec->seq.pic_pts = pts; } } /* frame_end seems to be unreliable here. */ if (flush) _vdec_hw_h264_flush_buffer (vdec); return 0; } int vdec_hw_h264_flush (vdec_hw_h264_t *vdec) { uint32_t n; lprintf ("vdec_hw_h264_flush\n"); if (!vdec) return 0; if ((vdec->seq.buf.nal_unit >= 0) && ((uint32_t)vdec->seq.buf.nal_unit + 3 < vdec->seq.buf.write)) { _vdec_hw_h264_nal_unit (vdec, vdec->seq.buf.mem + vdec->seq.buf.nal_unit + 3, vdec->seq.buf.write - vdec->seq.buf.nal_unit - 3); } vdec->seq.buf.read = vdec->seq.buf.write = 0; vdec->seq.buf.nal_unit = -1; _vdec_hw_h264_flush_slices (vdec, 0); n = vdec->ref_frames_used; _vdec_hw_h264_dpb_draw_frames (vdec, MAX_POC, DPB_DRAW_REFS); return n; } vdec_hw_h264_t *vdec_hw_h264_new ( int (*logg) (void *user_data, vdec_hw_h264_logg_t level, const char *fmt, ...), void *user_data, int (*frame_new) (void *user_data, vdec_hw_h264_frame_t *frame), int (*frame_render) (void *user_data, vdec_hw_h264_frame_t *frame), int (*frame_ready) (void *user_data, vdec_hw_h264_frame_t *frame), void (*frame_delete) (void *user_data, vdec_hw_h264_frame_t *frame), int num_frames ) { vdec_hw_h264_t *vdec; uint32_t u; vdec = calloc (1, sizeof (*vdec)); if (!vdec) return NULL; vdec->logg = logg ? logg : _vdec_hw_h264_dummy_logg; vdec->user_data = user_data; vdec->frame_new = frame_new; vdec->frame_render = frame_render; vdec->frame_ready = frame_ready; vdec->frame_delete = frame_delete; vdec->ref_frames_max = num_frames <= 1 ? 1 : num_frames > MAX_REF_FRAMES + 1 ? MAX_REF_FRAMES : num_frames - 1; vdec->seq.buf.mem = malloc (MIN_BUFFER_SIZE + BUF_PAD); if (!vdec->seq.buf.mem) { free (vdec); return NULL; } vdec->seq.buf.max = MIN_BUFFER_SIZE; vdec->seq.buf.read = 0; vdec->seq.buf.write = 0; vdec->seq.buf.nal_unit = -1; for (u = 0; u < MAX_REF_FRAMES + 1; u++) vdec->seq.dpb[u] = vdec->frames + u; vdec->ref_frames_used = 0; vdec->user_frames = 0; vdec->seq.reset = VDEC_HW_H264_FRAME_NEW_SEQ; vdec->seq.ratio = 0.0; vdec->seq.user_ratio = 0.0; vdec->seq.video_step = 3600; vdec->seq.coded_width = 1280; vdec->seq.coded_height = 720; vdec->seq.nal_unit_prefix = 0; _vdec_hw_h264_reset_sequence (vdec); for (u = 0; u < MAX_SPS; u++) vdec->seq.sps[u] = NULL; for (u = 0; u < MAX_PPS; u++) vdec->seq.pps[u] = NULL; vdec->stats.sps = 0; vdec->stats.pps = 0; vdec->stats.slices = 0; vdec->stats.frame_ready = 0; return vdec; } int vdec_hw_h264_reset (vdec_hw_h264_t *vdec) { int n = 0; if (!vdec) return 0; n = vdec->ref_frames_used; _vdec_hw_h264_reset_sequence (vdec); return n; } int vdec_hw_h264_put_container_info (vdec_hw_h264_t *vdec, int width, int height, int duration, double ratio) { if (!vdec) return 0; if (width > 0) vdec->seq.coded_width = width; if (height > 0) vdec->seq.coded_height = height; if (duration > 0) vdec->seq.video_step = duration; if (ratio > 0.001) vdec->seq.user_ratio = ratio; return 1; } void vdec_hw_h264_delete (vdec_hw_h264_t **dec) { vdec_hw_h264_t *vdec; uint32_t u; if (!dec) return; vdec = *dec; if (!vdec) return; *dec = NULL; for (u = 0; u < vdec->ref_frames_used; u++) _vdec_hw_h264_frame_free (vdec, vdec->seq.dpb[u], 1); vdec->ref_frames_used = 0; _vdec_hw_h264_frame_free (vdec, vdec->frames + MAX_REF_FRAMES, 1); vdec_hw_h264_reset (vdec); _vdec_hw_h264_reset_sequence (vdec); if (vdec->user_frames) vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_ERR, LOG_MODULE ": ERROR: %d user frames still in use.\n", (int)vdec->user_frames); for (u = 0; u < MAX_SPS; u++) if (vdec->seq.sps[u]) free (vdec->seq.sps[u]); for (u = 0; u < MAX_PPS; u++) if (vdec->seq.pps[u]) free (vdec->seq.pps[u]); free (vdec->seq.buf.mem); vdec->logg (vdec->user_data, VDEC_HW_H264_LOGG_INFO, LOG_MODULE ": used %d SPS, %d PPS, %d slices per frame, %d stream bytes, %d render calls.\n", vdec->stats.sps, vdec->stats.pps, vdec->stats.slices, (int)vdec->seq.buf.max, (int)vdec->stats.frame_ready); free (vdec); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/bits_reader.h���������������������������������������������������0000644�0001750�0001750�00000003730�14647725152�017641� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2008-2013 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #include <sys/types.h> typedef struct { const uint8_t *buffer, *start; int offbits, length, oflow; } bits_reader_t; static void bits_reader_set( bits_reader_t *br, const uint8_t *buf, int len ) { br->buffer = br->start = buf; br->offbits = 0; br->length = len; br->oflow = 0; } static void skip_bits( bits_reader_t *br, int nbits ) { br->offbits += nbits; br->buffer += br->offbits / 8; br->offbits %= 8; if ( br->buffer > (br->start + br->length) ) { br->oflow = 1; } } static uint32_t get_bits( bits_reader_t *br, int nbits ) { int i, nbytes; uint32_t ret = 0; const uint8_t *buf; buf = br->buffer; nbytes = (br->offbits + nbits)/8; if ( ((br->offbits + nbits) %8 ) > 0 ) nbytes++; if ( (buf + nbytes) > (br->start + br->length) ) { br->oflow = 1; return 0; } for ( i=0; i<nbytes; i++ ) ret += buf[i]<<((nbytes-i-1)*8); i = (4-nbytes)*8+br->offbits; ret = ((ret<<i)>>i)>>((nbytes*8)-nbits-br->offbits); return ret; } static uint32_t read_bits( bits_reader_t *br, int nbits ) { uint32_t ret = get_bits(br, nbits); br->offbits += nbits; br->buffer += br->offbits / 8; br->offbits %= 8; return ret; } ����������������������������������������xine-lib-1.2/src/video_dec/libvdpau/vdpau_mpeg4.c���������������������������������������������������0000644�0001750�0001750�00000112016�14647725152�017562� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; * * Copyright (C) 2010-2023 the xine project * Copyright (C) 2010 Christophe Thommeret <hftom@free.fr> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vdpau_mpeg4.c, a mpeg4-part-2 video stream parser using VDPAU hardware decoder * */ /*#define LOG*/ #define LOG_MODULE "vdpau_mpeg4" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "accel_vdpau.h" #include "bits_reader.h" #include "group_vdpau.h" #include <vdpau/vdpau.h> #define begin_vo_start_code 0x00 #define end_vo_start_code 0x1f #define begin_vol_start_code 0x20 #define end_vol_start_code 0x2f #define viso_sequence_start_code 0xb0 #define viso_sequence_end_code 0xb1 #define viso_start_code 0xb5 #define group_start_code 0xb3 #define user_data_start_code 0xb2 #define vop_start_code 0xb6 #define I_FRAME 0 #define P_FRAME 1 #define B_FRAME 2 #define PICTURE_TOP 1 #define PICTURE_BOTTOM 2 #define PICTURE_FRAME 3 #define SHAPE_RECT 0 #define SHAPE_BIN 1 #define SHAPE_BINONLY 2 #define SHAPE_GRAY 3 #define SPRITE_STATIC 1 #define SPRITE_GMC 2 static int nframe; /*#define MAKE_DAT*/ /*do NOT define this, unless you know what you do */ #ifdef MAKE_DAT static int nframes; static FILE *outfile; #endif /* default intra quant matrix, in zig-zag order */ static const uint8_t default_intra_quantizer_matrix[64] = { 8, 17, 17, 20, 18, 18, 19, 19, 21, 21, 22, 22, 22, 21, 21, 23, 23, 23, 23, 23, 23, 25, 24, 24, 24, 24, 25, 25, 27, 27, 26, 26, 26, 26, 26, 27, 28, 28, 28, 28, 28, 28, 28, 30, 30, 30, 30, 30, 30, 32, 32, 32, 32, 32, 35, 35, 35, 35, 38, 38, 38, 41, 41, 45 }; /* default non intra quant matrix, in zig-zag order */ static const uint8_t default_non_intra_quantizer_matrix[64] = { 16, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 25, 24, 24, 24, 25, 26, 26, 26, 26, 25, 27, 27, 27, 27, 27, 28, 28, 28, 28, 30, 30, 30, 31, 31, 33 }; uint8_t mpeg_scan_norm[64] = { /* Zig-Zag scan pattern */ 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 }; typedef struct { VdpPictureInfoMPEG4Part2 vdp_infos; /* first field, also used for frame */ int viso_verid; int newpred_enable; int reduced_resolution_vop_enable; int vol_shape; int complexity_estimation_disable; int sprite_enable; int quant_precision; int progressive_frame; } picture_t; typedef struct { uint32_t coded_width; uint32_t coded_height; uint64_t video_step; /* frame duration in pts units */ double ratio; VdpDecoderProfile profile; int chroma; int top_field_first; int have_header; uint8_t *buf; /* accumulate data */ int bufseek; uint32_t bufsize; uint32_t bufpos; int start; picture_t picture; vo_frame_t *forward_ref; vo_frame_t *backward_ref; int64_t cur_pts, seq_pts; vdpau_accel_t *accel_vdpau; bits_reader_t br; int vdp_runtime_nr; int reset; int have_codec_name; char codec_name[256]; int fixed_vop_time_increment; int time_increment_bits; int last_time_base; int time_base; int time; int last_non_b_time; int t_frame; int color_matrix; } sequence_t; typedef struct vdpau_mpeg4_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; sequence_t sequence; VdpDecoder decoder; VdpDecoderProfile decoder_profile; uint32_t decoder_width; uint32_t decoder_height; } vdpau_mpeg4_decoder_t; static void reset_picture( picture_t *pic ) { lprintf( "reset_picture\n" ); pic->vdp_infos.vop_coding_type = 0; pic->vdp_infos.alternate_vertical_scan_flag = 0; pic->vdp_infos.quant_type = 0; pic->vdp_infos.vop_time_increment_resolution = 0; pic->vdp_infos.vop_fcode_forward = 1; pic->vdp_infos.vop_fcode_backward = 1; pic->vdp_infos.resync_marker_disable = 0; pic->vdp_infos.interlaced = 0; pic->vdp_infos.quarter_sample = 0; pic->vdp_infos.short_video_header = 0; pic->vdp_infos.rounding_control = 0; pic->vdp_infos.top_field_first = 1; pic->progressive_frame = 1; pic->viso_verid = 1; pic->newpred_enable = 0; pic->reduced_resolution_vop_enable = 0; pic->complexity_estimation_disable = 1; pic->vol_shape = SHAPE_RECT; pic->quant_precision = 5; pic->vdp_infos.trd[0] = pic->vdp_infos.trd[1] = 0; pic->vdp_infos.trb[0] = pic->vdp_infos.trb[1] = 0; } static void init_picture( picture_t *pic ) { reset_picture( pic ); } static void reset_sequence( sequence_t *sequence, int free_refs ) { sequence->cur_pts = sequence->seq_pts = 0; if ( sequence->forward_ref ) sequence->forward_ref->pts = 0; if ( sequence->backward_ref ) sequence->backward_ref->pts = 0; if ( !free_refs ) return; sequence->bufpos = 0; sequence->bufseek = 0; sequence->start = -1; if ( sequence->forward_ref ) sequence->forward_ref->free( sequence->forward_ref ); sequence->forward_ref = NULL; if ( sequence->backward_ref ) sequence->backward_ref->free( sequence->backward_ref ); sequence->backward_ref = NULL; sequence->top_field_first = 0; sequence->reset = VO_NEW_SEQUENCE_FLAG; sequence->last_time_base = 0; sequence->time_base = 0; sequence->time = 0; sequence->last_non_b_time = 0; sequence->t_frame = 0; } static void free_sequence( sequence_t *sequence ) { lprintf( "init_sequence\n" ); sequence->have_header = 0; sequence->profile = VDP_DECODER_PROFILE_MPEG4_PART2_ASP; sequence->chroma = 0; sequence->video_step = 3600; sequence->have_codec_name = 0; strcpy( sequence->codec_name, "MPEG4 / XviD / DivX (vdpau)" ); reset_sequence( sequence, 1 ); } static void update_metadata( vdpau_mpeg4_decoder_t *this_gen ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_WIDTH, sequence->coded_width ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, sequence->coded_height ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_RATIO, ((double)10000*sequence->ratio) ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_FRAME_DURATION, sequence->video_step ); _x_meta_info_set_utf8( this_gen->stream, XINE_META_INFO_VIDEOCODEC, sequence->codec_name ); xine_event_t event; xine_format_change_data_t data; event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = this_gen->stream; event.data = &data; event.data_length = sizeof(data); data.width = sequence->coded_width; data.height = sequence->coded_height; data.aspect = sequence->ratio; xine_event_send( this_gen->stream, &event ); } static void visual_object( vdpau_mpeg4_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; picture_t *picture = (picture_t*)&sequence->picture; int xine_color_matrix = 4; /* undefined, mpeg range */ bits_reader_set( &sequence->br, buf, len ); if ( read_bits( &sequence->br, 1 ) ) { picture->viso_verid = read_bits( &sequence->br, 4 ); lprintf("visual_object_verid: %d\n", picture->viso_verid); skip_bits( &sequence->br, 3 ); } if ( read_bits( &sequence->br, 4 ) == 1 ) { if ( read_bits( &sequence->br, 1 ) ) { skip_bits (&sequence->br, 3); /* video_format */ xine_color_matrix |= read_bits (&sequence->br, 1); /* full range */ if ( read_bits( &sequence->br, 1 ) ) { skip_bits (&sequence->br, 16); xine_color_matrix = (xine_color_matrix & 1) | (read_bits (&sequence->br, 8) << 1); /* matrix_coefficients */ } } } VO_SET_FLAGS_CM (xine_color_matrix, sequence->color_matrix); } static void video_object_layer( vdpau_mpeg4_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; picture_t *picture = (picture_t*)&sequence->picture; bits_reader_set( &sequence->br, buf, len ); int vol_verid = 1; picture->vdp_infos.short_video_header = 0; sequence->t_frame = 0; skip_bits( &sequence->br, 9 ); if ( read_bits( &sequence->br, 1 ) ) { vol_verid = read_bits( &sequence->br, 4 ); lprintf("video_object_layer_verid: %d\n", vol_verid); skip_bits( &sequence->br, 3 ); } double parw=1, parh=1; int ar = read_bits( &sequence->br, 4 ); lprintf("aspect_ratio_info: %d\n", ar); switch ( ar ) { case 1: parw = parh = 1; break; case 2: parw = 12; parh = 11; break; case 3: parw = 10; parh = 11; break; case 4: parw = 16; parh = 11; break; case 5: parw = 40; parh = 33; break; case 15: { parw = read_bits( &sequence->br, 8 ); parh = read_bits( &sequence->br, 8 ); break; } } lprintf("parw: %f, parh: %f\n", parw, parh); if ( read_bits( &sequence->br, 1 ) ) { skip_bits( &sequence->br, 3 ); if ( read_bits( &sequence->br, 1 ) ) { read_bits( &sequence->br, 16 ); read_bits( &sequence->br, 16 ); read_bits( &sequence->br, 16 ); read_bits( &sequence->br, 15 ); read_bits( &sequence->br, 16 ); } } picture->vol_shape = read_bits( &sequence->br, 2 ); if ( (picture->vol_shape == SHAPE_GRAY) && (vol_verid != 1) ) { skip_bits( &sequence->br, 4 ); fprintf(stderr, "vdpau_mpeg4: unsupported SHAPE_GRAY!\n"); } skip_bits( &sequence->br, 1 ); picture->vdp_infos.vop_time_increment_resolution = read_bits( &sequence->br, 16 ); lprintf("vop_time_increment_resolution: %d\n", picture->vdp_infos.vop_time_increment_resolution); int length=1, max=2; while ( (max - 1) < picture->vdp_infos.vop_time_increment_resolution ) { ++length; max *= 2; } sequence->time_increment_bits = length; if ( sequence->time_increment_bits < 1 ) sequence->time_increment_bits = 1; skip_bits( &sequence->br, 1 ); if ( read_bits( &sequence->br, 1 ) ) { sequence->fixed_vop_time_increment = read_bits( &sequence->br, sequence->time_increment_bits ); } else sequence->fixed_vop_time_increment = 1; sequence->video_step = 90000 / (picture->vdp_infos.vop_time_increment_resolution / sequence->fixed_vop_time_increment); lprintf("fixed_vop_time_increment: %d\n", sequence->fixed_vop_time_increment); lprintf("video_step: %d\n", (int)sequence->video_step); if ( picture->vol_shape != SHAPE_BINONLY ) { if ( picture->vol_shape == SHAPE_RECT ) { skip_bits( &sequence->br, 1 ); sequence->coded_width = read_bits( &sequence->br, 13 ); lprintf("vol_width: %d\n", sequence->coded_width); skip_bits( &sequence->br, 1 ); sequence->coded_height = read_bits( &sequence->br, 13 ); lprintf("vol_height: %d\n", sequence->coded_height); skip_bits( &sequence->br, 1 ); } sequence->ratio = ((double)sequence->coded_width * parw) / ((double)sequence->coded_height * parh); lprintf("aspect_ratio: %f\n", sequence->ratio); picture->vdp_infos.interlaced = read_bits( &sequence->br, 1 ); skip_bits( &sequence->br, 1 ); picture->sprite_enable = 0; if ( vol_verid == 1 ) picture->sprite_enable = read_bits( &sequence->br, 1 ); else picture->sprite_enable = read_bits( &sequence->br, 2 ); if ( (picture->sprite_enable == SPRITE_STATIC) || (picture->sprite_enable == SPRITE_GMC) ) { if ( picture->sprite_enable != SPRITE_GMC ) { skip_bits( &sequence->br, 14 ); skip_bits( &sequence->br, 14 ); skip_bits( &sequence->br, 14 ); skip_bits( &sequence->br, 14 ); } skip_bits( &sequence->br, 9 ); if ( picture->sprite_enable != SPRITE_GMC ) skip_bits( &sequence->br, 1 ); } if ( (vol_verid != 1) && (picture->vol_shape != SHAPE_RECT) ) skip_bits( &sequence->br, 1 ); if ( read_bits( &sequence->br, 1 ) ) { picture->quant_precision = read_bits( &sequence->br, 4 ); skip_bits( &sequence->br, 4 ); } else picture->quant_precision = 5; if ( picture->vol_shape == SHAPE_GRAY ) skip_bits( &sequence->br, 3 ); picture->vdp_infos.quant_type = read_bits( &sequence->br, 1 ); /* load default matrices */ int j; for ( j=0; j<64; ++j ) { sequence->picture.vdp_infos.intra_quantizer_matrix[mpeg_scan_norm[j]] = default_intra_quantizer_matrix[j]; sequence->picture.vdp_infos.non_intra_quantizer_matrix[mpeg_scan_norm[j]] = default_non_intra_quantizer_matrix[j]; } if ( picture->vdp_infos.quant_type ) { int val, last = 0; if ( read_bits( &sequence->br, 1 ) ) { /* load_intra_quant_matrix */ lprintf("load_intra_quant_matrix\n"); for ( j=0; j<64; ++j ) { val = read_bits( &sequence->br, 8 ); if ( !val ) break; last = sequence->picture.vdp_infos.intra_quantizer_matrix[j] = val; } for ( ; j<64; ++j ) sequence->picture.vdp_infos.intra_quantizer_matrix[j] = last; } if ( read_bits( &sequence->br, 1 ) ) { /* load_non_intra_quant_matrix */ lprintf("load_non_intra_quant_matrix\n"); for ( j=0; j<64; ++j ) { val = read_bits( &sequence->br, 8 ); if ( !val ) break; last = sequence->picture.vdp_infos.non_intra_quantizer_matrix[j] = val; } for ( ; j<64; ++j ) sequence->picture.vdp_infos.non_intra_quantizer_matrix[j] = last; } if ( picture->vol_shape == SHAPE_GRAY ) { /* FIXME */ fprintf(stderr, "vdpau_mpeg4: grayscale shape not supported!\n"); return; } } if ( vol_verid != 1 ) sequence->picture.vdp_infos.quarter_sample = read_bits( &sequence->br, 1 ); else sequence->picture.vdp_infos.quarter_sample = 0; picture->complexity_estimation_disable = read_bits( &sequence->br, 1 ); if ( !picture->complexity_estimation_disable ) { /* define_vop_complexity_estimation_header */ int estimation_method = read_bits( &sequence->br, 2 ); if ( (estimation_method == 0) || (estimation_method == 1) ){ if ( !read_bits( &sequence->br, 1 ) ) skip_bits( &sequence->br, 6 ); if ( !read_bits( &sequence->br, 1 ) ) skip_bits( &sequence->br, 4 ); skip_bits( &sequence->br, 1 ); if ( !read_bits( &sequence->br, 1 ) ) skip_bits( &sequence->br, 4 ); if ( !read_bits( &sequence->br, 1 ) ) skip_bits( &sequence->br, 6 ); skip_bits( &sequence->br, 1 ); if ( estimation_method == 1 ) { if ( !read_bits( &sequence->br, 1 ) ) skip_bits( &sequence->br, 2 ); } } } picture->vdp_infos.resync_marker_disable = read_bits( &sequence->br, 1 ); if ( read_bits( &sequence->br, 1 ) ) skip_bits( &sequence->br, 1 ); if ( vol_verid != 1 ) { picture->newpred_enable = read_bits( &sequence->br, 1 ); if ( picture->newpred_enable ) skip_bits( &sequence->br, 3 ); picture->reduced_resolution_vop_enable = read_bits( &sequence->br, 1 ); } else { picture->newpred_enable = 0; picture->reduced_resolution_vop_enable = 0; } /* .... */ } else { if ( vol_verid != 1 ) { if ( read_bits( &sequence->br, 1 ) ) skip_bits( &sequence->br, 24 ); } picture->vdp_infos.resync_marker_disable = read_bits( &sequence->br, 1 ); } if ( !sequence->have_header ) { update_metadata( this_gen ); sequence->have_header = 1; } } #define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) static void video_object_plane( vdpau_mpeg4_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; picture_t *picture = (picture_t*)&sequence->picture; bits_reader_set( &sequence->br, buf, len ); int time_inc=0, time_increment; sequence->seq_pts = sequence->cur_pts; sequence->cur_pts = 0; picture->vdp_infos.vop_coding_type = read_bits( &sequence->br, 2 ); while ( read_bits( &sequence->br, 1 ) ) ++time_inc; skip_bits( &sequence->br, 1 ); if ( sequence->time_increment_bits == 0 || !(get_bits( &sequence->br, sequence->time_increment_bits + 1) & 1) ) { for ( sequence->time_increment_bits = 1; sequence->time_increment_bits < 16; ++sequence->time_increment_bits ) { if ( picture->vdp_infos.vop_coding_type == P_FRAME ) { if ( (get_bits( &sequence->br, sequence->time_increment_bits + 6 ) & 0x37) == 0x30 ) break; } else { if ( (get_bits( &sequence->br, sequence->time_increment_bits + 5 ) & 0x1f) == 0x18 ) break; } fprintf(stderr, "Headers are not complete, guessing time_increment_bits: %d\n", sequence->time_increment_bits); } } time_increment = read_bits( &sequence->br, sequence->time_increment_bits ); if ( picture->vdp_infos.vop_coding_type != B_FRAME ) { sequence->last_time_base = sequence->time_base; sequence->time_base += time_inc; sequence->time = sequence->time_base * picture->vdp_infos.vop_time_increment_resolution + time_increment; if ( sequence->time < sequence->last_non_b_time ) { ++sequence->time_base; sequence->time += picture->vdp_infos.vop_time_increment_resolution; } picture->vdp_infos.trd[0] = sequence->time - sequence->last_non_b_time; sequence->last_non_b_time = sequence->time; } else { sequence->time = (sequence->last_time_base + time_inc) * picture->vdp_infos.vop_time_increment_resolution + time_increment; picture->vdp_infos.trb[0] = picture->vdp_infos.trd[0] - (sequence->last_non_b_time - sequence->time); if ( (picture->vdp_infos.trd[0] <= picture->vdp_infos.trb[0] ) || (picture->vdp_infos.trd[0] <= (picture->vdp_infos.trd[0] - picture->vdp_infos.trb[0])) || (picture->vdp_infos.trd[0] <= 0) ) { /* FIXME */ } if ( sequence->t_frame == 0 ) sequence->t_frame = picture->vdp_infos.trb[0]; if ( sequence->t_frame == 0 ) sequence->t_frame = 1; picture->vdp_infos.trd[1] = ( ROUNDED_DIV(sequence->last_non_b_time, sequence->t_frame) - ROUNDED_DIV(sequence->last_non_b_time - picture->vdp_infos.trd[0], sequence->t_frame)); picture->vdp_infos.trb[1] = ( ROUNDED_DIV(sequence->time, sequence->t_frame) - ROUNDED_DIV(sequence->last_non_b_time - picture->vdp_infos.trd[0], sequence->t_frame)); if ( picture->vdp_infos.interlaced ) { /* FIXME */ } } /*if ( sequence->fixed_vop_time_increment ) sequence->seq_pts = ( sequence->time + sequence->fixed_vop_time_increment/2 ) / sequence->fixed_vop_time_increment;*/ skip_bits( &sequence->br, 1 ); if ( !read_bits( &sequence->br, 1 ) ) return; /* vop_coded == 0 */ if ( picture->newpred_enable ) { /* FIXME */ fprintf(stderr, "vdpau_mpeg4: newpred_enable, dunno what to do !!!\n"); return; } if ( (picture->vol_shape != SHAPE_BINONLY) && (picture->vdp_infos.vop_coding_type == P_FRAME) ) picture->vdp_infos.rounding_control = read_bits( &sequence->br, 1 ); else picture->vdp_infos.rounding_control = 0; if ( picture->reduced_resolution_vop_enable && (picture->vol_shape == SHAPE_RECT) && (picture->vdp_infos.vop_coding_type != B_FRAME) ) skip_bits( &sequence->br, 1 ); if ( picture->vol_shape != SHAPE_RECT ) { /* FIXME */ fprintf(stderr, "vdpau_mpeg4: vol_shape != SHAPE_RECT, return\n"); return; } if ( picture->vol_shape != SHAPE_BINONLY ) { if ( !picture->complexity_estimation_disable ) { /* FIXME */ fprintf(stderr, "vdpau_mpeg4: TODO: read_vop_complexity_estimation_header\n"); return; } } if ( picture->vol_shape != SHAPE_BINONLY ) { skip_bits( &sequence->br, 3 ); if ( picture->vdp_infos.interlaced ) { picture->vdp_infos.top_field_first = read_bits( &sequence->br, 1 ); picture->vdp_infos.alternate_vertical_scan_flag = read_bits( &sequence->br, 1 ); } } if ( picture->vol_shape != SHAPE_BINONLY ) { skip_bits( &sequence->br, picture->quant_precision ); if ( picture->vol_shape == SHAPE_GRAY ) { /* FIXME */ fprintf(stderr, "vdpau_mpeg4: unsupported SHAPE_GRAY!\n"); return; } if ( picture->vdp_infos.vop_coding_type != I_FRAME ) picture->vdp_infos.vop_fcode_forward = read_bits( &sequence->br, 3 ); if ( picture->vdp_infos.vop_coding_type == B_FRAME ) picture->vdp_infos.vop_fcode_backward = read_bits( &sequence->br, 3 ); } } static void gop_header( vdpau_mpeg4_decoder_t *this_gen, uint8_t *buf, int len ) { int h, m, s; sequence_t *sequence = (sequence_t*)&this_gen->sequence; bits_reader_set( &sequence->br, buf, len ); h = read_bits( &sequence->br, 5 ); m = read_bits( &sequence->br, 6 ); skip_bits( &sequence->br, 1 ); s = read_bits( &sequence->br, 6 ); sequence->time_base = s + (60 * (m + (60 * h))); } static void user_data( vdpau_mpeg4_decoder_t *this_gen, uint8_t *buffer, int len ) { /* code from ffmpeg's mpeg4videodec.c */ char buf[256]; int i, e, ver = 0, build = 0, ver2 = 0, ver3 = 0; char last; if ( this_gen->sequence.have_codec_name ) return; for( i=0; i<255 && i<len; i++ ) { if ( buffer[i] == 0 ) break; buf[i]= buffer[i]; } buf[i]=0; /* divx detection */ e = sscanf(buf, "DivX%dBuild%d%c", &ver, &build, &last); if ( e < 2 ) e=sscanf(buf, "DivX%db%d%c", &ver, &build, &last); if ( e >= 2 ) { strcpy( this_gen->sequence.codec_name, "MPEG4 / DivX " ); sprintf( buf, "%d", ver ); strcat( this_gen->sequence.codec_name, " (vdpau)" ); this_gen->sequence.have_codec_name = 1; } /* ffmpeg detection */ e = sscanf(buf, "FFmpe%*[^b]b%d", &build) + 3; if ( e != 4 ) e=sscanf(buf, "FFmpeg v%d.%d.%d / libavcodec build: %d", &ver, &ver2, &ver3, &build); if ( e != 4 ) { e=sscanf(buf, "Lavc%d.%d.%d", &ver, &ver2, &ver3)+1; if ( e > 1 ) build= (ver<<16) + (ver2<<8) + ver3; } if ( e == 4 ) { strcpy( this_gen->sequence.codec_name, "MPEG4 / FFmpeg " ); sprintf( buf, "%d", build ); strcat( this_gen->sequence.codec_name, " (vdpau)" ); this_gen->sequence.have_codec_name = 1; } else { if(strcmp(buf, "ffmpeg")==0) { strcpy( this_gen->sequence.codec_name, "MPEG4 / FFmpeg " ); strcpy( this_gen->sequence.codec_name, "4600" ); strcat( this_gen->sequence.codec_name, " (vdpau)" ); this_gen->sequence.have_codec_name = 1; } } /* Xvid detection */ e = sscanf(buf, "XviD%d", &build); if ( e == 1 ) { strcpy( this_gen->sequence.codec_name, "MPEG4 / XviD " ); sprintf( buf, "%d", build ); strcat( this_gen->sequence.codec_name, " (vdpau)" ); this_gen->sequence.have_codec_name = 1; } update_metadata( this_gen ); } static int parse_code( vdpau_mpeg4_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; if ( /* (buf[3] >= begin_vo_start_code) ">= 0" && */ (buf[3] <= end_vo_start_code) ) { lprintf( " ----------- vo_start_code\n" ); return 0; } if ( (buf[3] >= begin_vol_start_code) && (buf[3] <= end_vol_start_code) ) { lprintf( " ----------- vol_start_code\n" ); video_object_layer( this_gen, buf+4, len-4); return 0; } switch ( buf[3] ) { case viso_sequence_start_code: lprintf( " ----------- viso_sequence_start_code\n" ); break; case viso_sequence_end_code: lprintf( " ----------- viso_sequence_end_code\n" ); break; case viso_start_code: lprintf( " ----------- viso_start_code\n" ); visual_object( this_gen, buf+4, len-4 ); break; } if ( !sequence->have_header ) return 0; switch ( buf[3] ) { case group_start_code: lprintf( " ----------- group_start_code\n" ); gop_header( this_gen, buf+4, len-4 ); break; case user_data_start_code: lprintf( " ----------- user_data_start_code\n" ); user_data( this_gen, buf+4, len-4 ); break; case vop_start_code: lprintf( " ----------- vop_start_code\n" ); video_object_plane( this_gen, buf+4, len-4 ); return 1; break; } return 0; } static void decode_render( vdpau_mpeg4_decoder_t *vd, vdpau_accel_t *accel, uint8_t *buf, int len ) { sequence_t *seq = (sequence_t*)&vd->sequence; picture_t *pic = (picture_t*)&seq->picture; VdpStatus st; if ( vd->decoder==VDP_INVALID_HANDLE || vd->decoder_profile!=seq->profile || vd->decoder_width!=seq->coded_width || vd->decoder_height!=seq->coded_height ) { if (accel->lock) accel->lock (accel->vo_frame); if ( vd->decoder!=VDP_INVALID_HANDLE ) { accel->vdp_decoder_destroy( vd->decoder ); vd->decoder = VDP_INVALID_HANDLE; } st = accel->vdp_decoder_create( accel->vdp_device, seq->profile, seq->coded_width, seq->coded_height, 2, &vd->decoder); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) fprintf(stderr, "vdpau_mpeg4: failed to create decoder !! %s\n", accel->vdp_get_error_string( st ) ); else { lprintf( "decoder created.\n" ); vd->decoder_profile = seq->profile; vd->decoder_width = seq->coded_width; vd->decoder_height = seq->coded_height; seq->vdp_runtime_nr = accel->vdp_runtime_nr; } } VdpPictureInfoMPEG4Part2 *infos = (VdpPictureInfoMPEG4Part2*)&pic->vdp_infos; printf("%d: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", ++nframe, infos->vop_coding_type,infos->vop_time_increment_resolution, infos->vop_fcode_forward, infos->vop_fcode_backward, infos->resync_marker_disable, infos->interlaced, infos->quant_type, infos->quarter_sample, infos->short_video_header, infos->rounding_control, infos->alternate_vertical_scan_flag, len, infos->trd[0], infos->trd[1], infos->trb[0], infos->trb[1]); VdpBitstreamBuffer vbit; vbit.struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit.bitstream = buf; vbit.bitstream_bytes = len; if (accel->lock) accel->lock (accel->vo_frame); st = accel->vdp_decoder_render( vd->decoder, accel->surface, CAST_VdpPictureInfo_PTR &pic->vdp_infos, 1, &vbit ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) fprintf(stderr, "vdpau_mpeg4: decoder failed : %d!! %s\n", st, accel->vdp_get_error_string( st ) ); else { lprintf( "DECODER SUCCESS : vop_coding_type=%d, bytes=%d, current=%d, forwref:%d, backref:%d, pts:%" PRId64 "\n", pic->vdp_infos.vop_coding_type, vbit.bitstream_bytes, accel->surface, pic->vdp_infos.forward_reference, pic->vdp_infos.backward_reference, seq->seq_pts ); } } static void decode_picture( vdpau_mpeg4_decoder_t *vd ) { sequence_t *seq = (sequence_t*)&vd->sequence; picture_t *pic = (picture_t*)&seq->picture; vdpau_accel_t *ref_accel; uint8_t *buf = seq->buf; int len = seq->bufpos; pic->vdp_infos.forward_reference = VDP_INVALID_HANDLE; pic->vdp_infos.backward_reference = VDP_INVALID_HANDLE; if ( pic->vdp_infos.vop_coding_type == P_FRAME ) { if ( seq->backward_ref ) { ref_accel = (vdpau_accel_t*)seq->backward_ref->accel_data; pic->vdp_infos.forward_reference = ref_accel->surface; } else { /* reset_picture( &seq->picture ); */ return; } } else if ( pic->vdp_infos.vop_coding_type == B_FRAME ) { if ( seq->forward_ref ) { ref_accel = (vdpau_accel_t*)seq->forward_ref->accel_data; pic->vdp_infos.forward_reference = ref_accel->surface; } else { /* reset_picture( &seq->picture ); */ return; } if ( seq->backward_ref ) { ref_accel = (vdpau_accel_t*)seq->backward_ref->accel_data; pic->vdp_infos.backward_reference = ref_accel->surface; } else { /* reset_picture( &seq->picture );*/ return; } } vo_frame_t *img = vd->stream->video_out->get_frame( vd->stream->video_out, seq->coded_width, seq->coded_height, seq->ratio, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | seq->color_matrix ); vdpau_accel_t *accel = (vdpau_accel_t*)img->accel_data; if ( !seq->accel_vdpau ) seq->accel_vdpau = accel; if( seq->vdp_runtime_nr != *(seq->accel_vdpau->current_vdp_runtime_nr) ) { seq->accel_vdpau = accel; if ( seq->forward_ref ) seq->forward_ref->free( seq->forward_ref ); seq->forward_ref = NULL; if ( seq->backward_ref ) seq->backward_ref->free( seq->backward_ref ); seq->backward_ref = NULL; vd->decoder = VDP_INVALID_HANDLE; } decode_render( vd, accel, buf, len ); #ifdef MAKE_DAT if ( nframes==0 ) { fwrite( &seq->coded_width, 1, sizeof(seq->coded_width), outfile ); fwrite( &seq->coded_height, 1, sizeof(seq->coded_height), outfile ); fwrite( &seq->ratio, 1, sizeof(seq->ratio), outfile ); fwrite( &seq->profile, 1, sizeof(seq->profile), outfile ); } if ( nframes++ < 25 ) { fwrite( &pic->vdp_infos, 1, sizeof(pic->vdp_infos), outfile ); fwrite( &len, 1, sizeof(len), outfile ); fwrite( buf, 1, len, outfile ); printf( "picture_type = %d\n", pic->vdp_infos.picture_type); } #endif if ( pic->vdp_infos.interlaced ) { img->progressive_frame = 0; img->top_field_first = pic->vdp_infos.top_field_first; } else { img->progressive_frame = -1; /* set to -1 to let the vo know that it MUST NOT deinterlace */ img->top_field_first = 1; } img->pts = seq->seq_pts; img->bad_frame = 0; if ( seq->video_step > 900 ) /* some buggy streams */ img->duration = seq->video_step; if ( pic->vdp_infos.vop_coding_type < B_FRAME ) { if ( pic->vdp_infos.vop_coding_type == I_FRAME && !seq->backward_ref ) { img->pts = 0; img->draw( img, vd->stream ); ++img->drawn; } if ( seq->forward_ref ) { seq->forward_ref->drawn = 0; seq->forward_ref->free( seq->forward_ref ); } seq->forward_ref = seq->backward_ref; if ( seq->forward_ref && !seq->forward_ref->drawn ) { seq->forward_ref->draw( seq->forward_ref, vd->stream ); } seq->backward_ref = img; } else { img->draw( img, vd->stream ); img->free( img ); } } /* * This function receives a buffer of data from the demuxer layer and * figures out how to handle it based on its header flags. */ static void vdpau_mpeg4_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { vdpau_mpeg4_decoder_t *this = (vdpau_mpeg4_decoder_t *) this_gen; sequence_t *seq = (sequence_t*)&this->sequence; /* preview buffers shall not be decoded and drawn -- use them only to supply stream information */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if ( !buf->size ) return; if ( buf->pts ) seq->cur_pts = buf->pts; int size = seq->bufpos+buf->size; if ( seq->bufsize < (unsigned int)size ) { seq->bufsize = size+1024; seq->buf = realloc( seq->buf, seq->bufsize ); } xine_fast_memcpy( seq->buf+seq->bufpos, buf->content, buf->size ); seq->bufpos += buf->size; while ( seq->bufseek <= (int)(seq->bufpos)-4 ) { uint8_t *buffer = seq->buf+seq->bufseek; if ( buffer[0]==0 && buffer[1]==0 && buffer[2]==1 ) { if ( seq->start<0 ) { seq->start = seq->bufseek; } else { if ( parse_code( this, seq->buf+seq->start, seq->bufseek-seq->start ) ) { decode_picture( this ); } uint8_t *tmp = (uint8_t*)malloc(seq->bufsize); xine_fast_memcpy( tmp, seq->buf+seq->bufseek, seq->bufpos-seq->bufseek ); seq->bufpos -= seq->bufseek; seq->start = -1; seq->bufseek = -1; free( seq->buf ); seq->buf = tmp; } } ++seq->bufseek; } } /* * This function is called when xine needs to flush the system. */ static void vdpau_mpeg4_flush (video_decoder_t *this_gen) { lprintf( "vdpau_mpeg4_flush\n" ); (void)this_gen; } /* * This function resets the video decoder. */ static void vdpau_mpeg4_reset (video_decoder_t *this_gen) { vdpau_mpeg4_decoder_t *this = (vdpau_mpeg4_decoder_t *) this_gen; lprintf( "vdpau_mpeg4_reset\n" ); reset_sequence( &this->sequence, 1 ); } /* * The decoder should forget any stored pts values here. */ static void vdpau_mpeg4_discontinuity (video_decoder_t *this_gen) { vdpau_mpeg4_decoder_t *this = (vdpau_mpeg4_decoder_t *) this_gen; lprintf( "vdpau_mpeg4_discontinuity\n" ); reset_sequence( &this->sequence, 0 ); } /* * This function frees the video decoder instance allocated to the decoder. */ static void vdpau_mpeg4_dispose (video_decoder_t *this_gen) { vdpau_mpeg4_decoder_t *this = (vdpau_mpeg4_decoder_t *) this_gen; lprintf( "vdpau_mpeg4_dispose\n" ); if ( this->decoder!=VDP_INVALID_HANDLE && this->sequence.accel_vdpau ) { if (this->sequence.accel_vdpau->lock) this->sequence.accel_vdpau->lock (this->sequence.accel_vdpau->vo_frame); this->sequence.accel_vdpau->vdp_decoder_destroy( this->decoder ); this->decoder = VDP_INVALID_HANDLE; if (this->sequence.accel_vdpau->unlock) this->sequence.accel_vdpau->unlock (this->sequence.accel_vdpau->vo_frame); } free_sequence( &this->sequence ); this->stream->video_out->close( this->stream->video_out, this->stream ); free( this->sequence.buf ); free( this_gen ); } /* * This function allocates, initializes, and returns a private video * decoder structure. */ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { vdpau_mpeg4_decoder_t *this ; lprintf( "open_plugin\n" ); (void)class_gen; /* the videoout must be vdpau-capable to support this decoder */ if ( !(stream->video_out->get_capabilities(stream->video_out) & VO_CAP_VDPAU_MPEG4) ) return NULL; /* now check if vdpau has free decoder resource */ vo_frame_t *img = stream->video_out->get_frame( stream->video_out, 1920, 1080, 1, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL ); if (!img) { return NULL; } vdpau_accel_t *accel = (vdpau_accel_t*)img->accel_data; int runtime_nr = accel->vdp_runtime_nr; img->free(img); VdpDecoder decoder; if (accel->lock) accel->lock (accel->vo_frame); VdpStatus st = accel->vdp_decoder_create( accel->vdp_device, VDP_DECODER_PROFILE_MPEG4_PART2_ASP, 1920, 1080, 2, &decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) { lprintf( "can't create vdpau decoder.\n" ); return NULL; } if (accel->lock) accel->lock (accel->vo_frame); accel->vdp_decoder_destroy( decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); this = (vdpau_mpeg4_decoder_t *) calloc(1, sizeof(vdpau_mpeg4_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = vdpau_mpeg4_decode_data; this->video_decoder.flush = vdpau_mpeg4_flush; this->video_decoder.reset = vdpau_mpeg4_reset; this->video_decoder.discontinuity = vdpau_mpeg4_discontinuity; this->video_decoder.dispose = vdpau_mpeg4_dispose; this->stream = stream; this->sequence.bufsize = 1024; this->sequence.buf = (uint8_t*)malloc(this->sequence.bufsize); this->sequence.forward_ref = 0; this->sequence.backward_ref = 0; this->sequence.vdp_runtime_nr = runtime_nr; free_sequence( &this->sequence ); this->sequence.ratio = 1; this->sequence.reset = VO_NEW_SEQUENCE_FLAG; init_picture( &this->sequence.picture ); this->decoder = VDP_INVALID_HANDLE; this->sequence.accel_vdpau = NULL; (stream->video_out->open)(stream->video_out, stream); #ifdef MAKE_DAT outfile = fopen( "/tmp/mpeg4.dat","w"); nframes = 0; #endif nframe = 0; return &this->video_decoder; } /* * This function allocates a private video decoder class and initializes * the class's member functions. */ void *mpeg4_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_vdpau_mpeg4_class = { .open_plugin = open_plugin, .identifier = "vdpau_mpeg4", .description = N_("MPEG4 part 2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau."), .dispose = NULL, }; return (void *)&decode_video_vdpau_mpeg4_class; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/vdpau_h264.c����������������������������������������������������0000644�0001750�0001750�00000413753�14647725152�017245� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2008-2023 the xine project * Copyright (C) 2008-2009 Julian Scheel * * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vdpau_h264.c: H264 Video Decoder utilizing nvidia VDPAU engine */ #define LOG_MODULE "vdpau_h264" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <math.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <vdpau/vdpau.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include <xine/list.h> #include "bswap.h" #include "accel_vdpau.h" #include "group_vdpau.h" //#define DEBUG_H264 //#define DEBUG_DPB /************************************************************************* * nal.c: nal-structure utility functions * *************************************************************************/ enum nal_unit_types { NAL_UNSPECIFIED = 0, NAL_SLICE, NAL_PART_A, NAL_PART_B, NAL_PART_C, NAL_SLICE_IDR, NAL_SEI, NAL_SPS, NAL_PPS, NAL_AU_DELIMITER, NAL_END_OF_SEQUENCE, NAL_END_OF_STREAM, NAL_FILLER_DATA, NAL_SPS_EXT }; enum pic_struct { DISP_FRAME = 0, DISP_TOP, DISP_BOTTOM, DISP_TOP_BOTTOM, DISP_BOTTOM_TOP, DISP_TOP_BOTTOM_TOP, DISP_BOTTOM_TOP_BOTTOM, DISP_FRAME_DOUBLING, DISP_FRAME_TRIPLING }; enum ct_type { CT_PROGRESSIVE = 0, CT_INTERLACED, CT_UNKNOWN, CT_RESERVED }; /* slice types repeat from 5-9, we * need a helper function for comparison */ enum slice_types { SLICE_P = 0, SLICE_B, SLICE_I, SLICE_SP, SLICE_SI }; enum aspect_ratio { ASPECT_UNSPECIFIED = 0, ASPECT_1_1, ASPECT_12_11, ASPECT_10_11, ASPECT_16_11, ASPECT_40_33, ASPECT_24_11, ASPECT_20_11, ASPECT_32_11, ASPECT_80_33, ASPECT_18_11, ASPECT_15_11, ASPECT_64_33, ASPECT_160_99, ASPECT_4_3, ASPECT_3_2, ASPECT_2_1, ASPECT_RESERVED, ASPECT_EXTENDED_SAR=255 }; static inline uint32_t slice_type(uint32_t slice_type) { return (slice_type < 10 ? slice_type % 5 : slice_type); } #if 0 static inline void print_slice_type(uint32_t slice_type) { switch(slice_type) { case SLICE_P: printf("SLICE_P\n"); break; case SLICE_B: printf("SLICE_B\n"); break; case SLICE_I: printf("SLICE_I\n"); break; case SLICE_SP: printf("SLICE_SP\n"); break; case SLICE_SI: printf("SLICE_SI\n"); break; default: printf("Unknown SLICE\n"); } } #endif struct hrd_parameters { uint32_t cpb_cnt_minus1; uint8_t bit_rate_scale; uint8_t cpb_size_scale; uint32_t bit_rate_value_minus1[32]; uint32_t cpb_size_value_minus1[32]; uint8_t cbr_flag[32]; uint8_t initial_cpb_removal_delay_length_minus1; uint8_t cpb_removal_delay_length_minus1; uint8_t dpb_output_delay_length_minus1; uint8_t time_offset_length; }; struct seq_parameter_set_rbsp { uint8_t profile_idc; // 0xff uint8_t constraint_setN_flag; // 0x0f uint8_t level_idc; // 0xff uint32_t seq_parameter_set_id; uint32_t chroma_format_idc; uint8_t separate_colour_plane_flag; // 0x01 uint32_t bit_depth_luma_minus8; uint32_t bit_depth_chroma_minus8; uint8_t qpprime_y_zero_transform_bypass_flag; uint8_t seq_scaling_matrix_present_flag; /* if(seq_scaling_matrix_present_flag) */ uint8_t seq_scaling_list_present_flag[8]; uint8_t scaling_lists_4x4[6][16]; uint8_t scaling_lists_8x8[2][64]; /* endif */ uint32_t log2_max_frame_num_minus4; uint32_t max_frame_num; uint32_t pic_order_cnt_type; // if pic_order_cnt_type==0 uint32_t log2_max_pic_order_cnt_lsb_minus4; // else uint8_t delta_pic_order_always_zero_flag; int32_t offset_for_non_ref_pic; int32_t offset_for_top_to_bottom_field; uint8_t num_ref_frames_in_pic_order_cnt_cycle; int32_t offset_for_ref_frame[256]; // TODO: some more ignored here uint32_t num_ref_frames; uint8_t gaps_in_frame_num_value_allowed_flag; /*uint32_t pic_width_in_mbs_minus1; uint32_t pic_height_in_map_units_minus1;*/ uint32_t pic_width; uint32_t pic_height; uint8_t frame_mbs_only_flag; uint8_t mb_adaptive_frame_field_flag; uint8_t direct_8x8_inference_flag; uint8_t frame_cropping_flag; uint32_t frame_crop_left_offset; uint32_t frame_crop_right_offset; uint32_t frame_crop_top_offset; uint32_t frame_crop_bottom_offset; uint8_t vui_parameters_present_flag; /* vui_parameters */ struct { uint8_t aspect_ration_info_present_flag; /* aspect_ration_info_present_flag == 1 */ uint8_t aspect_ratio_idc; uint16_t sar_width; uint16_t sar_height; uint8_t overscan_info_present_flag; /* overscan_info_present_flag == 1 */ uint8_t overscan_appropriate_flag; uint8_t video_signal_type_present_flag; /* video_signal_type_present_flag == 1 */ uint8_t video_format; uint8_t video_full_range_flag; uint8_t colour_description_present; /* colour_description_present == 1 */ uint8_t colour_primaries; uint8_t transfer_characteristics; uint8_t matrix_coefficients; uint8_t chroma_loc_info_present_flag; /* chroma_loc_info_present_flag == 1 */ uint8_t chroma_sample_loc_type_top_field; uint8_t chroma_sample_loc_type_bottom_field; uint8_t timing_info_present_flag; /* timing_info_present_flag == 1 */ uint32_t num_units_in_tick; uint32_t time_scale; uint8_t fixed_frame_rate_flag; uint8_t nal_hrd_parameters_present_flag; struct hrd_parameters nal_hrd_parameters; uint8_t vc1_hrd_parameters_present_flag; struct hrd_parameters vc1_hrd_parameters; uint8_t low_delay_hrd_flag; uint8_t pic_struct_present_flag; uint8_t bitstream_restriction_flag; /* bitstream_restriction_flag == 1 */ uint8_t motion_vectors_over_pic_boundaries; uint32_t max_bytes_per_pic_denom; uint32_t max_bits_per_mb_denom; uint32_t log2_max_mv_length_horizontal; uint32_t log2_max_mv_length_vertical; uint32_t num_reorder_frames; uint32_t max_dec_frame_buffering; } vui_parameters; }; struct pic_parameter_set_rbsp { uint32_t pic_parameter_set_id; uint32_t seq_parameter_set_id; uint8_t entropy_coding_mode_flag; uint8_t pic_order_present_flag; uint32_t num_slice_groups_minus1; /* num_slice_groups_minus1 > 0 */ uint32_t slice_group_map_type; /* slice_group_map_type == 1 */ uint32_t run_length_minus1[64]; /* slice_group_map_type == 2 */ uint32_t top_left[64]; uint32_t bottom_right[64]; /* slice_group_map_type == 3,4,5 */ uint8_t slice_group_change_direction_flag; uint32_t slice_group_change_rate_minus1; /* slice_group_map_type == 6 */ uint32_t pic_size_in_map_units_minus1; uint8_t slice_group_id[64]; uint32_t num_ref_idx_l0_active_minus1; uint32_t num_ref_idx_l1_active_minus1; uint8_t weighted_pred_flag; uint8_t weighted_bipred_idc; int32_t pic_init_qp_minus26; int32_t pic_init_qs_minus26; int32_t chroma_qp_index_offset; uint8_t deblocking_filter_control_present_flag; uint8_t constrained_intra_pred_flag; uint8_t redundant_pic_cnt_present_flag; /* if(more_rbsp_data) */ uint8_t transform_8x8_mode_flag; uint8_t pic_scaling_matrix_present_flag; /* if(pic_scaling_matrix_present_flag) */ uint8_t pic_scaling_list_present_flag[8]; uint8_t scaling_lists_4x4[6][16]; uint8_t scaling_lists_8x8[2][64]; int32_t second_chroma_qp_index_offset; }; /*struct clock_timestamp { uint8_t ct_type; uint8_t nuit_fiel_based_flag; uint8_t counting_type; uint8_t full_timestamp_flag; uint8_t discontinuity_flag; uint8_t cnt_dropped_flag; uint8_t n_frames };*/ /* sei contains several additional info, we do * only care for pic_timing, to handle display * reordering */ struct sei_message { uint32_t payload_type; uint8_t last_payload_type_byte; uint32_t payload_size; uint8_t last_payload_size_byte; struct { /* cpb_dpb_delays_present_flag == 1 */ uint8_t cpb_removal_delay; uint8_t dpb_output_delay; uint8_t pic_struct; uint8_t ct_type : 1; uint8_t nuit_field_based_flag : 1; uint8_t counting_type : 5; uint8_t full_timestamp_flag : 1; uint8_t discontinuity_flag : 1; uint8_t cnt_dropped_flag : 1; uint8_t n_frames; uint8_t seconds_value : 6; uint8_t minutes_value : 6; uint8_t hours_value : 5; int32_t time_offset; } pic_timing; }; struct slice_header { uint32_t first_mb_in_slice; uint32_t slice_type; uint32_t pic_parameter_set_id; uint8_t colour_plane_id; uint32_t frame_num; uint8_t field_pic_flag; uint8_t bottom_field_flag; uint32_t idr_pic_id; /* sps->pic_order_cnt_type == 0 */ uint32_t pic_order_cnt_lsb; int32_t delta_pic_order_cnt_bottom; /* sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag */ int32_t delta_pic_order_cnt[2]; /* pps->redundant_pic_cnt_present_flag == 1 */ int32_t redundant_pic_cnt; /* slice_type == B */ uint8_t direct_spatial_mv_pred_flag; /* slice_type == P, SP, B */ uint8_t num_ref_idx_active_override_flag; /* num_ref_idx_active_override_flag == 1 */ uint32_t num_ref_idx_l0_active_minus1; /* slice type == B */ uint32_t num_ref_idx_l1_active_minus1; /* ref_pic_list_reordering */ struct { /* slice_type != I && slice_type != SI */ uint8_t ref_pic_list_reordering_flag_l0; /* slice_type == B */ uint8_t ref_pic_list_reordering_flag_l1; /* ref_pic_list_reordering_flag_l0 == 1 */ uint32_t reordering_of_pic_nums_idc; /* reordering_of_pic_nums_idc == 0, 1 */ uint32_t abs_diff_pic_num_minus1; /* reordering_of_pic_nums_idc == 2) */ uint32_t long_term_pic_num; } ref_pic_list_reordering; /* pred_weight_table */ struct { uint32_t luma_log2_weight_denom; /* chroma_format_idc != 0 */ uint32_t chroma_log2_weight_denom; int32_t luma_weight_l0[32]; int32_t luma_offset_l0[32]; int32_t chroma_weight_l0[32][2]; int32_t chroma_offset_l0[32][2]; int32_t luma_weight_l1[32]; int32_t luma_offset_l1[32]; int32_t chroma_weight_l1[32][2]; int32_t chroma_offset_l1[32][2]; } pred_weight_table; /* def_rec_pic_marking */ struct { /* nal_unit_type == NAL_SLICE_IDR */ uint8_t no_output_of_prior_pics_flag; uint8_t long_term_reference_flag; /* else */ uint8_t adaptive_ref_pic_marking_mode_flag; uint32_t memory_management_control_operation; uint32_t difference_of_pic_nums_minus1; uint32_t long_term_pic_num; uint32_t long_term_frame_idx; uint32_t max_long_term_frame_idx_plus1; } dec_ref_pic_marking[10]; uint32_t dec_ref_pic_marking_count; }; struct nal_unit { uint8_t nal_ref_idc; // 0x03 enum nal_unit_types nal_unit_type; // 0x1f //union { struct sei_message sei; struct seq_parameter_set_rbsp sps; struct pic_parameter_set_rbsp pps; struct slice_header slc; //}; struct nal_unit *prev; struct nal_unit *next; uint32_t lock_counter; }; struct nal_buffer { struct nal_unit *first; struct nal_unit *last; uint8_t max_size; uint8_t used; }; static struct nal_buffer* create_nal_buffer(uint8_t max_size) { struct nal_buffer *nal_buffer = calloc(1, sizeof(struct nal_buffer)); if (!nal_buffer) return NULL; nal_buffer->max_size = max_size; return nal_buffer; } static void release_nal_unit(struct nal_unit *nal) { if(!nal) return; nal->lock_counter--; if(nal->lock_counter <= 0) { free(nal); } } /** * destroys a nal buffer. all referenced nals are released */ static void free_nal_buffer(struct nal_buffer *nal_buffer) { struct nal_unit *nal = nal_buffer->first; while (nal) { struct nal_unit *delete = nal; nal = nal->next; release_nal_unit(delete); } free(nal_buffer); } static void nal_buffer_remove(struct nal_buffer *nal_buffer, struct nal_unit *nal) { if (nal == nal_buffer->first && nal == nal_buffer->last) { nal_buffer->first = nal_buffer->last = NULL; } else { if (nal == nal_buffer->first) { nal_buffer->first = nal->next; nal_buffer->first->prev = NULL; } else { nal->prev->next = nal->next; } if (nal == nal_buffer->last) { nal_buffer->last = nal->prev; nal_buffer->last->next = NULL; } else { nal->next->prev = nal->prev; } } nal->next = nal->prev = NULL; release_nal_unit(nal); nal_buffer->used--; } static void lock_nal_unit(struct nal_unit *nal) { nal->lock_counter++; } /** * appends a nal unit to the end of the buffer */ static void nal_buffer_append(struct nal_buffer *nal_buffer, struct nal_unit *nal) { if(nal_buffer->used == nal_buffer->max_size) { nal_buffer_remove(nal_buffer, nal_buffer->first); } if (nal_buffer->first == NULL) { nal_buffer->first = nal_buffer->last = nal; nal->prev = nal->next = NULL; lock_nal_unit(nal); nal_buffer->used++; } else if (nal_buffer->last != NULL) { nal_buffer->last->next = nal; nal->prev = nal_buffer->last; nal_buffer->last = nal; lock_nal_unit(nal); nal_buffer->used++; } else { lprintf("ERR: nal_buffer is in a broken state\n"); } } #if 0 static void nal_buffer_flush(struct nal_buffer *nal_buffer) { while(nal_buffer->used > 0) { nal_buffer_remove(nal_buffer, nal_buffer->first); } } #endif /** * returns the last element in the buffer */ static struct nal_unit *nal_buffer_get_last(struct nal_buffer *nal_buffer) { return nal_buffer->last; } /** * get a nal unit from a nal_buffer from it's * seq parameter_set_id */ static struct nal_unit* nal_buffer_get_by_sps_id(struct nal_buffer *nal_buffer, uint32_t seq_parameter_set_id) { struct nal_unit *nal = nal_buffer->last; if (nal != NULL) { do { if(nal->nal_unit_type == NAL_SPS) { if(nal->sps.seq_parameter_set_id == seq_parameter_set_id) { return nal; } } nal = nal->prev; } while(nal != NULL); } return NULL; } /** * get a nal unit from a nal_buffer from it's * pic parameter_set_id */ static struct nal_unit* nal_buffer_get_by_pps_id(struct nal_buffer *nal_buffer, uint32_t pic_parameter_set_id) { struct nal_unit *nal = nal_buffer->last; if (nal != NULL) { do { if(nal->nal_unit_type == NAL_PPS) { if(nal->pps.pic_parameter_set_id == pic_parameter_set_id) { return nal; } } nal = nal->prev; } while(nal != NULL); } return NULL; } /** * create a new nal unit, with a lock_counter of 1 */ static struct nal_unit* create_nal_unit() { struct nal_unit *nal = calloc(1, sizeof(struct nal_unit)); if (!nal) return NULL; nal->lock_counter = 1; return nal; } #if 0 /** * creates a copy of a nal unit with a single lock */ static void copy_nal_unit(struct nal_unit *dest, struct nal_unit *src) { /* size without pps, sps and slc units: */ int size = sizeof(struct nal_unit); xine_fast_memcpy(dest, src, size); dest->lock_counter = 1; dest->prev = dest->next = NULL; } #endif /************************************************************************* * cpb.h: Coded Picture Buffer * *************************************************************************/ enum picture_flags { IDR_PIC = 0x01, REFERENCE = 0x02, NOT_EXISTING = 0x04, INTERLACED = 0x08 }; struct coded_picture { uint32_t flag_mask; uint32_t max_pic_num; int32_t pic_num; uint8_t used_for_long_term_ref; uint32_t long_term_pic_num; uint32_t long_term_frame_idx; int32_t top_field_order_cnt; int32_t bottom_field_order_cnt; uint8_t repeat_pic; /* buffer data for the image slices, which * are passed to the decoder */ uint32_t slice_cnt; int64_t pts; struct nal_unit *sei_nal; struct nal_unit *sps_nal; struct nal_unit *pps_nal; struct nal_unit *slc_nal; }; static inline struct coded_picture* create_coded_picture(void) { struct coded_picture* pic = calloc(1, sizeof(struct coded_picture)); return pic; } static inline void free_coded_picture(struct coded_picture *pic) { if(!pic) return; release_nal_unit(pic->sei_nal); release_nal_unit(pic->sps_nal); release_nal_unit(pic->pps_nal); release_nal_unit(pic->slc_nal); free(pic); } /************************************************************************* * dpb.c: Implementing Decoded Picture Buffer * *************************************************************************/ #define MAX_DPB_COUNT 16 #define USED_FOR_REF (top_is_reference || bottom_is_reference) /** * ---------------------------------------------------------------------------- * decoded picture * ---------------------------------------------------------------------------- */ struct decoded_picture { vo_frame_t *img; /* this is the image we block, to make sure * the surface is not double-used */ /** * a decoded picture always contains a whole frame, * respective a field pair, so it can contain up to * 2 coded pics */ struct coded_picture *coded_pic[2]; int32_t frame_num_wrap; uint8_t top_is_reference; uint8_t bottom_is_reference; uint32_t lock_counter; }; /* from parser */ enum parser_flags { CPB_DPB_DELAYS_PRESENT = 0x01, PIC_STRUCT_PRESENT = 0x02 }; /** * ---------------------------------------------------------------------------- * dpb code starting here * ---------------------------------------------------------------------------- */ /* Decoded Picture Buffer */ struct dpb { xine_list_t *reference_list; xine_list_t *output_list; int max_reorder_frames; int max_dpb_frames; }; static int dp_top_field_first(struct decoded_picture *decoded_pic) { int top_field_first = 1; if (decoded_pic->coded_pic[1] != NULL) { if (!decoded_pic->coded_pic[0]->slc_nal->slc.bottom_field_flag && decoded_pic->coded_pic[1]->slc_nal->slc.bottom_field_flag && decoded_pic->coded_pic[0]->top_field_order_cnt != decoded_pic->coded_pic[1]->bottom_field_order_cnt) { top_field_first = decoded_pic->coded_pic[0]->top_field_order_cnt < decoded_pic->coded_pic[1]->bottom_field_order_cnt; } else if (decoded_pic->coded_pic[0]->slc_nal->slc.bottom_field_flag && !decoded_pic->coded_pic[1]->slc_nal->slc.bottom_field_flag && decoded_pic->coded_pic[0]->bottom_field_order_cnt != decoded_pic->coded_pic[1]->top_field_order_cnt) { top_field_first = decoded_pic->coded_pic[0]->bottom_field_order_cnt > decoded_pic->coded_pic[1]->top_field_order_cnt; } } if (decoded_pic->coded_pic[0]->flag_mask & PIC_STRUCT_PRESENT && decoded_pic->coded_pic[0]->sei_nal != NULL) { uint8_t pic_struct = decoded_pic->coded_pic[0]->sei_nal->sei.pic_timing.pic_struct; if(pic_struct == DISP_TOP_BOTTOM || pic_struct == DISP_TOP_BOTTOM_TOP) { top_field_first = 1; } else if (pic_struct == DISP_BOTTOM_TOP || pic_struct == DISP_BOTTOM_TOP_BOTTOM) { top_field_first = 0; } else if (pic_struct == DISP_FRAME) { top_field_first = 1; } } return top_field_first; } /** * ---------------------------------------------------------------------------- * decoded picture * ---------------------------------------------------------------------------- */ static void free_decoded_picture(struct decoded_picture *pic) { if(!pic) return; if(pic->img != NULL) { pic->img->free(pic->img); } free_coded_picture(pic->coded_pic[1]); free_coded_picture(pic->coded_pic[0]); pic->coded_pic[0] = NULL; pic->coded_pic[1] = NULL; free(pic); } static void decoded_pic_check_reference(struct decoded_picture *pic) { int i; for(i = 0; i < 2; i++) { struct coded_picture *cpic = pic->coded_pic[i]; if(cpic && (cpic->flag_mask & REFERENCE)) { // FIXME: this assumes Top Field First! if(i == 0) { pic->top_is_reference = cpic->slc_nal->slc.field_pic_flag ? (cpic->slc_nal->slc.bottom_field_flag ? 0 : 1) : 1; } pic->bottom_is_reference = cpic->slc_nal->slc.field_pic_flag ? (cpic->slc_nal->slc.bottom_field_flag ? 1 : 0) : 1; } } } static struct decoded_picture* init_decoded_picture(struct coded_picture *cpic, vo_frame_t *img) { struct decoded_picture *pic = calloc(1, sizeof(struct decoded_picture)); if (!pic) return NULL; pic->coded_pic[0] = cpic; decoded_pic_check_reference(pic); pic->img = img; pic->lock_counter = 1; return pic; } static void decoded_pic_add_field(struct decoded_picture *pic, struct coded_picture *cpic) { pic->coded_pic[1] = cpic; decoded_pic_check_reference(pic); } static void release_decoded_picture(struct decoded_picture *pic) { if(!pic) return; pic->lock_counter--; //printf("release decoded picture: %p (%d)\n", pic, pic->lock_counter); if(pic->lock_counter <= 0) { free_decoded_picture(pic); } } static void lock_decoded_picture(struct decoded_picture *pic) { if(!pic) return; pic->lock_counter++; //printf("lock decoded picture: %p (%d)\n", pic, pic->lock_counter); } /** * ---------------------------------------------------------------------------- * dpb code starting here * ---------------------------------------------------------------------------- */ static struct dpb* create_dpb(void) { struct dpb *dpb = calloc(1, sizeof(struct dpb)); if (!dpb) return NULL; dpb->output_list = xine_list_new(); dpb->reference_list = xine_list_new(); dpb->max_reorder_frames = MAX_DPB_COUNT; dpb->max_dpb_frames = MAX_DPB_COUNT; return dpb; } /** * calculates the total number of frames in the dpb * when frames are used for reference and are not drawn * yet the result would be less then reference_list-size+ * output_list-size */ static int dpb_total_frames(struct dpb *dpb) { int num_frames = xine_list_size(dpb->output_list); xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while(ite) { struct decoded_picture *pic = xine_list_get_value(dpb->reference_list, ite); if (xine_list_find(dpb->output_list, pic) == NULL) { num_frames++; } ite = xine_list_next(dpb->reference_list, ite); } return num_frames; } static struct decoded_picture* dpb_get_next_out_picture(struct dpb *dpb, int do_flush) { struct decoded_picture *pic = NULL;; struct decoded_picture *outpic = NULL; if(!do_flush && (int)xine_list_size(dpb->output_list) < dpb->max_reorder_frames && dpb_total_frames(dpb) < dpb->max_dpb_frames) { return NULL; } xine_list_iterator_t ite = NULL; while ((pic = xine_list_prev_value (dpb->output_list, &ite))) { int32_t out_top_field_order_cnt = outpic != NULL ? outpic->coded_pic[0]->top_field_order_cnt : 0; int32_t top_field_order_cnt = pic->coded_pic[0]->top_field_order_cnt; int32_t out_bottom_field_order_cnt = outpic != NULL ? (outpic->coded_pic[1] != NULL ? outpic->coded_pic[1]->bottom_field_order_cnt : outpic->coded_pic[0]->top_field_order_cnt) : 0; int32_t bottom_field_order_cnt = pic->coded_pic[1] != NULL ? pic->coded_pic[1]->bottom_field_order_cnt : pic->coded_pic[0]->top_field_order_cnt; if (outpic == NULL || (top_field_order_cnt <= out_top_field_order_cnt && bottom_field_order_cnt <= out_bottom_field_order_cnt) || (out_top_field_order_cnt <= 0 && top_field_order_cnt > 0 && out_bottom_field_order_cnt <= 0 && bottom_field_order_cnt > 0) || outpic->coded_pic[0]->flag_mask & IDR_PIC) { outpic = pic; } } return outpic; } static struct decoded_picture* dpb_get_picture(struct dpb *dpb, uint32_t picnum) { struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while (ite) { pic = xine_list_get_value(dpb->reference_list, ite); if ((pic->coded_pic[0]->pic_num == (int32_t)picnum || (pic->coded_pic[1] != NULL && pic->coded_pic[1]->pic_num == (int32_t)picnum))) { return pic; } ite = xine_list_next(dpb->reference_list, ite); } return NULL; } static struct decoded_picture* dpb_get_picture_by_ltpn(struct dpb *dpb, uint32_t longterm_picnum) { struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while (ite) { pic = xine_list_get_value(dpb->reference_list, ite); if (pic->coded_pic[0]->long_term_pic_num == longterm_picnum || (pic->coded_pic[1] != NULL && pic->coded_pic[1]->long_term_pic_num == longterm_picnum)) { return pic; } ite = xine_list_next(dpb->reference_list, ite); } return NULL; } static struct decoded_picture* dpb_get_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx) { struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while (ite) { pic = xine_list_get_value(dpb->reference_list, ite); if (pic->coded_pic[0]->long_term_frame_idx == longterm_idx || (pic->coded_pic[1] != NULL && pic->coded_pic[1]->long_term_frame_idx == longterm_idx)) { return pic; } ite = xine_list_next(dpb->reference_list, ite); } return NULL; } static int dpb_unmark_reference_picture(struct dpb *dpb, struct decoded_picture *pic) { if(!pic) return -1; xine_list_iterator_t ite = xine_list_find(dpb->reference_list, pic); if (ite) { xine_list_remove(dpb->reference_list, ite); release_decoded_picture(pic); return 0; } return -1; } static int dpb_set_unused_ref_picture_byltpn(struct dpb *dpb, uint32_t longterm_picnum) { struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while (ite) { pic = xine_list_get_value(dpb->reference_list, ite); uint8_t found = 0; if (pic->coded_pic[0]->long_term_pic_num == longterm_picnum) { pic->coded_pic[0]->used_for_long_term_ref = 0; found = 1; } if ((pic->coded_pic[1] != NULL && pic->coded_pic[1]->long_term_pic_num == longterm_picnum)) { pic->coded_pic[1]->used_for_long_term_ref = 0; found = 1; } if(found && !pic->coded_pic[0]->used_for_long_term_ref && (pic->coded_pic[1] == NULL || !pic->coded_pic[1]->used_for_long_term_ref)) { dpb_unmark_reference_picture(dpb, pic); } if (found) return 0; ite = xine_list_next(dpb->reference_list, ite); } return -1; } static int dpb_set_unused_ref_picture_bylidx(struct dpb *dpb, uint32_t longterm_idx) { struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while (ite) { pic = xine_list_get_value(dpb->reference_list, ite); uint8_t found = 0; if (pic->coded_pic[0]->long_term_frame_idx == longterm_idx) { pic->coded_pic[0]->used_for_long_term_ref = 0; found = 1; } if ((pic->coded_pic[1] != NULL && pic->coded_pic[1]->long_term_frame_idx == longterm_idx)) { pic->coded_pic[1]->used_for_long_term_ref = 0; found = 1; } if(found && !pic->coded_pic[0]->used_for_long_term_ref && (pic->coded_pic[1] == NULL || !pic->coded_pic[1]->used_for_long_term_ref)) { dpb_unmark_reference_picture(dpb, pic); } if (found) return 0; ite = xine_list_next(dpb->reference_list, ite); } return -1; } static int dpb_set_unused_ref_picture_lidx_gt(struct dpb *dpb, int32_t longterm_idx) { struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while (ite) { pic = xine_list_get_value(dpb->reference_list, ite); uint8_t found = 0; if ((int32_t)(pic->coded_pic[0]->long_term_frame_idx) >= longterm_idx) { pic->coded_pic[0]->used_for_long_term_ref = 0; found = 1; } if ((pic->coded_pic[1] != NULL && (int32_t)(pic->coded_pic[1]->long_term_frame_idx) >= longterm_idx)) { pic->coded_pic[1]->used_for_long_term_ref = 0; found = 1; } if(found && !pic->coded_pic[0]->used_for_long_term_ref && (pic->coded_pic[1] == NULL || !pic->coded_pic[1]->used_for_long_term_ref)) { dpb_unmark_reference_picture(dpb, pic); } ite = xine_list_next(dpb->reference_list, ite); } return -1; } static int dpb_unmark_picture_delayed(struct dpb *dpb, struct decoded_picture *pic) { if(!pic) return -1; xine_list_iterator_t ite = xine_list_find(dpb->output_list, pic); if (ite) { xine_list_remove(dpb->output_list, ite); release_decoded_picture(pic); return 0; } return -1; } /*static int dpb_remove_picture_by_img(struct dpb *dpb, vo_frame_t *remimg) { int retval = -1; struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->output_list); while (ite) { pic = xine_list_get_value(dpb->output_list, ite); if (pic->img == remimg) { dpb_unmark_picture_delayed(dpb, pic); dpb->used--; retval = 0; } ite = xine_list_next(dpb->output_list, ite); } return retval; }*/ static int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic, uint32_t num_ref_frames) { #if 0 /* this should never happen */ pic->img->lock(pic->img); if (0 == dpb_remove_picture_by_img(dpb, pic->img)) lprintf("H264/DPB broken stream: current img was already in dpb -- freed it\n"); else pic->img->free(pic->img); #endif /* add the pic to the output picture list, as no * pic would be immediately drawn. * acquire a lock for this list */ lock_decoded_picture(pic); xine_list_push_back(dpb->output_list, pic); /* check if the pic is a reference pic, * if it is it should be added to the reference * list. another lock has to be acquired in that case */ if (pic->coded_pic[0]->flag_mask & REFERENCE || (pic->coded_pic[1] != NULL && pic->coded_pic[1]->flag_mask & REFERENCE)) { lock_decoded_picture(pic); xine_list_push_back(dpb->reference_list, pic); /* * always apply the sliding window reference removal, if more reference * frames than expected are in the list. we will always remove the oldest * reference frame */ if(xine_list_size(dpb->reference_list) > num_ref_frames) { struct decoded_picture *discard = xine_list_get_value(dpb->reference_list, xine_list_front(dpb->reference_list)); dpb_unmark_reference_picture(dpb, discard); } } #if DEBUG_DPB printf("DPB list sizes: Total: %2d, Output: %2d, Reference: %2d\n", dpb_total_frames(dpb), xine_list_size(dpb->output_list), xine_list_size(dpb->reference_list)); #endif return 0; } static int dpb_flush(struct dpb *dpb) { struct decoded_picture *pic = NULL; xine_list_iterator_t ite = xine_list_front(dpb->reference_list); while (ite) { pic = xine_list_get_value(dpb->reference_list, ite); dpb_unmark_reference_picture(dpb, pic); /* CAUTION: xine_list_next would return an item, but not the one we * expect, as the current one was deleted */ ite = xine_list_front(dpb->reference_list); } return 0; } static void dpb_free_all(struct dpb *dpb) { xine_list_iterator_t ite = xine_list_front(dpb->output_list); while(ite) { dpb_unmark_picture_delayed(dpb, xine_list_get_value(dpb->output_list, ite)); /* CAUTION: xine_list_next would return an item, but not the one we * expect, as the current one was deleted */ ite = xine_list_front(dpb->output_list); } ite = xine_list_front(dpb->reference_list); while(ite) { dpb_unmark_reference_picture(dpb, xine_list_get_value(dpb->reference_list, ite)); /* CAUTION: xine_list_next would return an item, but not the one we * expect, as the current one was deleted */ ite = xine_list_front(dpb->reference_list); } } static void dpb_clear_all_pts(struct dpb *dpb) { xine_list_iterator_t ite = xine_list_front(dpb->output_list); while(ite) { struct decoded_picture *pic = xine_list_get_value(dpb->output_list, ite); pic->img->pts = 0; ite = xine_list_next(dpb->output_list, ite); } } static int fill_vdpau_reference_list(struct dpb *dpb, VdpReferenceFrameH264 *reflist) { struct decoded_picture *pic = NULL; int i = 0; int used_refframes = 0; xine_list_iterator_t ite = NULL; while ((pic = xine_list_prev_value (dpb->reference_list, &ite))) { reflist[i].surface = ((vdpau_accel_t*)pic->img->accel_data)->surface; reflist[i].is_long_term = pic->coded_pic[0]->used_for_long_term_ref || (pic->coded_pic[1] != NULL && pic->coded_pic[1]->used_for_long_term_ref); reflist[i].frame_idx = pic->coded_pic[0]->used_for_long_term_ref ? pic->coded_pic[0]->long_term_pic_num : pic->coded_pic[0]->slc_nal->slc.frame_num; reflist[i].top_is_reference = pic->top_is_reference; reflist[i].bottom_is_reference = pic->bottom_is_reference; reflist[i].field_order_cnt[0] = pic->coded_pic[0]->top_field_order_cnt; reflist[i].field_order_cnt[1] = pic->coded_pic[1] != NULL ? pic->coded_pic[1]->bottom_field_order_cnt : pic->coded_pic[0]->bottom_field_order_cnt; i++; } used_refframes = i; // fill all other frames with invalid handles while(i < 16) { reflist[i].bottom_is_reference = VDP_FALSE; reflist[i].top_is_reference = VDP_FALSE; reflist[i].frame_idx = 0; reflist[i].is_long_term = VDP_FALSE; reflist[i].surface = VDP_INVALID_HANDLE; reflist[i].field_order_cnt[0] = 0; reflist[i].field_order_cnt[1] = 0; i++; } return used_refframes; } /************************************************************************* * h264_parser.c: Almost full-features H264 NAL-Parser * *************************************************************************/ #define MAX_FRAME_SIZE 1024*1024 /* specifies wether the parser last parsed * non-vcl or vcl nal units. depending on * this the access unit boundaries are detected */ enum parser_position { NON_VCL, VCL }; struct h264_parser { uint8_t buf[MAX_FRAME_SIZE]; uint32_t buf_len; /* prebuf is used to store the currently * processed nal unit */ uint8_t prebuf[MAX_FRAME_SIZE]; uint32_t prebuf_len; uint32_t next_nal_position; uint8_t last_nal_res; uint8_t nal_size_length; uint32_t next_nal_size; uint8_t *nal_size_length_buf; uint8_t have_nal_size_length_buf; enum parser_position position; struct coded_picture *pic; struct nal_unit *last_vcl_nal; struct nal_buffer *sps_buffer; struct nal_buffer *pps_buffer; uint32_t prev_pic_order_cnt_lsb; uint32_t prev_pic_order_cnt_msb; uint32_t frame_num_offset; int32_t prev_top_field_order_cnt; uint32_t curr_pic_num; uint16_t flag_mask; /* this is dpb used for reference frame * heading to vdpau + unordered frames */ struct dpb *dpb; xine_t *xine; }; static int parse_nal(const uint8_t *buf, int buf_len, struct h264_parser *parser, struct coded_picture **completed_picture); static int seek_for_nal(uint8_t *buf, int buf_len, struct h264_parser *parser); #if 0 static void reset_parser(struct h264_parser *parser); #endif static void free_parser(struct h264_parser *parser); static int parse_frame(struct h264_parser *parser, const uint8_t *inbuf, int inbuf_len, int64_t pts, const void **ret_buf, uint32_t *ret_len, struct coded_picture **ret_pic); /* this has to be called after decoding the frame delivered by parse_frame, * but before adding a decoded frame to the dpb. */ static void process_mmc_operations(struct h264_parser *parser, struct coded_picture *picture); static void parse_codec_private(struct h264_parser *parser, const uint8_t *inbuf, int inbuf_len); /* XXX duplicated in two decoders. Move to shared .c file ? */ static const uint8_t zigzag_4x4[16] = { 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, }; static const uint8_t zigzag_8x8[64] = { 0+0*8, 1+0*8, 0+1*8, 0+2*8, 1+1*8, 2+0*8, 3+0*8, 2+1*8, 1+2*8, 0+3*8, 0+4*8, 1+3*8, 2+2*8, 3+1*8, 4+0*8, 5+0*8, 4+1*8, 3+2*8, 2+3*8, 1+4*8, 0+5*8, 0+6*8, 1+5*8, 2+4*8, 3+3*8, 4+2*8, 5+1*8, 6+0*8, 7+0*8, 6+1*8, 5+2*8, 4+3*8, 3+4*8, 2+5*8, 1+6*8, 0+7*8, 1+7*8, 2+6*8, 3+5*8, 4+4*8, 5+3*8, 6+2*8, 7+1*8, 7+2*8, 6+3*8, 5+4*8, 4+5*8, 3+6*8, 2+7*8, 3+7*8, 4+6*8, 5+5*8, 6+4*8, 7+3*8, 7+4*8, 6+5*8, 5+6*8, 4+7*8, 5+7*8, 6+6*8, 7+5*8, 7+6*8, 6+7*8, 7+7*8, }; /* default scaling_lists according to Table 7-2 */ static const uint8_t default_4x4_intra[16] = { 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42 }; static const uint8_t default_4x4_inter[16] = { 10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34 }; static const uint8_t default_8x8_intra[64] = { 6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42 }; static const uint8_t default_8x8_inter[64] = { 9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35 }; struct buf_reader { const uint8_t *buf; const uint8_t *cur_pos; int len; int cur_offset; }; static uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps); static void parse_vui_parameters(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps); static void parse_hrd_parameters(struct buf_reader *buf, struct hrd_parameters *hrd); static uint8_t parse_pps(struct buf_reader *buf, struct pic_parameter_set_rbsp *pps); static void parse_sei(struct buf_reader *buf, struct sei_message *sei, struct h264_parser *parser); static uint8_t parse_slice_header(struct buf_reader *buf, struct nal_unit *slc_nal, struct h264_parser *parser); static void parse_ref_pic_list_reordering(struct buf_reader *buf, struct slice_header *slc); static void parse_pred_weight_table(struct buf_reader *buf, struct slice_header *slc, struct h264_parser *parser); static void parse_dec_ref_pic_marking(struct buf_reader *buf, struct nal_unit *slc_nal); /* here goes the parser implementation */ #if 0 static void decode_nal(uint8_t **ret, int *len_ret, uint8_t *buf, int buf_len) { // TODO: rework without copying uint8_t *end = &buf[buf_len]; uint8_t *pos = malloc(buf_len); *ret = pos; while (buf < end) { if (buf < end - 3 && buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x03) { *pos++ = 0x00; *pos++ = 0x00; buf += 3; continue; } *pos++ = *buf++; } *len_ret = pos - *ret; } #endif #if 0 static inline void dump_bits(const char *label, const struct buf_reader *buf, int bits) { struct buf_reader lbuf; memcpy(&lbuf, buf, sizeof(struct buf_reader)); int i; printf("%s: 0b", label); for(i=0; i < bits; i++) printf("%d", read_bits(&lbuf, 1)); printf("\n"); } #endif /** * @return total number of bits read by the buf_reader */ static inline uint32_t bits_read(struct buf_reader *buf) { int bits_read = 0; bits_read = (buf->cur_pos - buf->buf)*8; bits_read += (8-buf->cur_offset); return bits_read; } /* skips stuffing bytes in the buf_reader */ static inline void skip_emulation_prevention_three_byte(struct buf_reader *buf) { if(buf->cur_pos - buf->buf > 2 && *(buf->cur_pos-2) == 0x00 && *(buf->cur_pos-1) == 0x00 && *buf->cur_pos == 0x03) { buf->cur_pos++; } } /* * read len bits from the buffer and return them * @return right aligned bits */ static inline uint32_t read_bits(struct buf_reader *buf, int len) { static uint32_t i_mask[33] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; int i_shr; uint32_t bits = 0; while (len > 0 && (buf->cur_pos - buf->buf) < buf->len) { if ((i_shr = buf->cur_offset - len) >= 0) { bits |= (*buf->cur_pos >> i_shr) & i_mask[len]; buf->cur_offset -= len; if (buf->cur_offset == 0) { buf->cur_pos++; buf->cur_offset = 8; skip_emulation_prevention_three_byte(buf); } return bits; } else { bits |= (*buf->cur_pos & i_mask[buf->cur_offset]) << -i_shr; len -= buf->cur_offset; buf->cur_pos++; buf->cur_offset = 8; skip_emulation_prevention_three_byte(buf); } } return bits; } /* determines if following bits are rtsb_trailing_bits */ static inline int rbsp_trailing_bits(const uint8_t *buf, int buf_len) { const uint8_t *cur_buf = buf+(buf_len-1); uint8_t cur_val; int parsed_bits = 0; int i; while(buf_len > 0) { cur_val = *cur_buf; for(i = 0; i < 9; i++) { if (cur_val&1) return parsed_bits+i; cur_val>>=1; } parsed_bits += 8; cur_buf--; } lprintf("rbsp trailing bits could not be found\n"); return 0; } static uint32_t read_exp_golomb(struct buf_reader *buf) { int leading_zero_bits = 0; while (read_bits(buf, 1) == 0 && leading_zero_bits < 32) leading_zero_bits++; uint32_t code = ((uint64_t)1 << leading_zero_bits) - 1 + read_bits(buf, leading_zero_bits); return code; } static int32_t read_exp_golomb_s(struct buf_reader *buf) { uint32_t ue = read_exp_golomb(buf); int32_t code = ue & 0x01 ? (ue + 1) / 2 : -(ue / 2); return code; } /** * parses the NAL header data and calls the subsequent * parser methods that handle specific NAL units */ static struct nal_unit* parse_nal_header(struct buf_reader *buf, struct coded_picture *pic, struct h264_parser *parser) { if (buf->len < 1) return NULL; (void)pic; struct nal_unit *nal = create_nal_unit(); nal->nal_ref_idc = (buf->buf[0] >> 5) & 0x03; nal->nal_unit_type = buf->buf[0] & 0x1f; buf->cur_pos = buf->buf + 1; //lprintf("NAL: %d\n", nal->nal_unit_type); //struct buf_reader ibuf; //ibuf.cur_offset = 8; switch (nal->nal_unit_type) { case NAL_SPS: parse_sps(buf, &nal->sps); break; case NAL_PPS: parse_pps(buf, &nal->pps); break; case NAL_SLICE: case NAL_PART_A: case NAL_PART_B: case NAL_PART_C: case NAL_SLICE_IDR: parse_slice_header(buf, nal, parser); break; case NAL_SEI: memset(&(nal->sei), 0x00, sizeof(struct sei_message)); parse_sei(buf, &nal->sei, parser); break; default: break; } return nal; } /** * calculates the picture order count according to ITU-T Rec. H.264 (11/2007) * chapter 8.2.1, p104f */ static void calculate_pic_order(struct h264_parser *parser, struct coded_picture *pic, struct slice_header *slc) { /* retrieve sps and pps from the buffers */ struct nal_unit *pps_nal = nal_buffer_get_by_pps_id(parser->pps_buffer, slc->pic_parameter_set_id); if (pps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "ERR: calculate_pic_order: pic_parameter_set_id %d not found in buffers\n", slc->pic_parameter_set_id); return; } struct pic_parameter_set_rbsp *pps = &pps_nal->pps; struct nal_unit *sps_nal = nal_buffer_get_by_sps_id(parser->sps_buffer, pps->seq_parameter_set_id); if (sps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "ERR: calculate_pic_order: seq_parameter_set_id %d not found in buffers\n", pps->seq_parameter_set_id); return; } struct seq_parameter_set_rbsp *sps = &sps_nal->sps; if (sps->pic_order_cnt_type == 0) { if (pic->flag_mask & IDR_PIC) { parser->prev_pic_order_cnt_lsb = 0; parser->prev_pic_order_cnt_msb = 0; // FIXME parser->frame_num_offset = 0; } const int max_poc_lsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4); uint32_t pic_order_cnt_msb = 0; if (slc->pic_order_cnt_lsb < parser->prev_pic_order_cnt_lsb && (int)(parser->prev_pic_order_cnt_lsb - slc->pic_order_cnt_lsb) >= max_poc_lsb / 2) pic_order_cnt_msb = parser->prev_pic_order_cnt_msb + max_poc_lsb; else if (slc->pic_order_cnt_lsb > parser->prev_pic_order_cnt_lsb && (int)(parser->prev_pic_order_cnt_lsb - slc->pic_order_cnt_lsb) < -max_poc_lsb / 2) pic_order_cnt_msb = parser->prev_pic_order_cnt_msb - max_poc_lsb; else pic_order_cnt_msb = parser->prev_pic_order_cnt_msb; if(!slc->field_pic_flag || !slc->bottom_field_flag) { pic->top_field_order_cnt = pic_order_cnt_msb + slc->pic_order_cnt_lsb; parser->prev_top_field_order_cnt = pic->top_field_order_cnt; } if (pic->flag_mask & REFERENCE) { parser->prev_pic_order_cnt_msb = pic_order_cnt_msb; } pic->bottom_field_order_cnt = 0; if(!slc->field_pic_flag) pic->bottom_field_order_cnt = pic->top_field_order_cnt + slc->delta_pic_order_cnt_bottom; else //if(slc->bottom_field_flag) //TODO: this is not spec compliant, but works... pic->bottom_field_order_cnt = pic_order_cnt_msb + slc->pic_order_cnt_lsb; if(slc->field_pic_flag && slc->bottom_field_flag) pic->top_field_order_cnt = parser->prev_top_field_order_cnt; } else if (sps->pic_order_cnt_type == 2) { uint32_t prev_frame_num = parser->last_vcl_nal ? parser->last_vcl_nal->slc.frame_num : 0; uint32_t prev_frame_num_offset = parser->frame_num_offset; uint32_t temp_pic_order_cnt = 0; if (parser->pic->flag_mask & IDR_PIC) parser->frame_num_offset = 0; else if (prev_frame_num > slc->frame_num) parser->frame_num_offset = prev_frame_num_offset + sps->max_frame_num; else parser->frame_num_offset = prev_frame_num_offset; if(parser->pic->flag_mask & IDR_PIC) temp_pic_order_cnt = 0; else if(!(parser->pic->flag_mask & REFERENCE)) temp_pic_order_cnt = 2 * (parser->frame_num_offset + slc->frame_num)-1; else temp_pic_order_cnt = 2 * (parser->frame_num_offset + slc->frame_num); if(!slc->field_pic_flag) pic->top_field_order_cnt = pic->bottom_field_order_cnt = temp_pic_order_cnt; else if(slc->bottom_field_flag) pic->bottom_field_order_cnt = temp_pic_order_cnt; else pic->top_field_order_cnt = temp_pic_order_cnt; } else { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "FIXME: Unsupported poc_type: %d\n", sps->pic_order_cnt_type); } } #if 0 static void skip_scaling_list(struct buf_reader *buf, int size) { int i; for (i = 0; i < size; i++) { read_exp_golomb_s(buf); } } #endif static void parse_scaling_list(struct buf_reader *buf, uint8_t *scaling_list, int length, int index) { int last_scale = 8; int next_scale = 8; int32_t delta_scale; uint8_t use_default_scaling_matrix_flag = 0; int i; unsigned int u; const uint8_t *zigzag = (length==64) ? zigzag_8x8 : zigzag_4x4; for (i = 0; i < length; i++) { if (next_scale != 0) { delta_scale = read_exp_golomb_s(buf); next_scale = (last_scale + delta_scale + 256) % 256; if (i == 0 && next_scale == 0) { use_default_scaling_matrix_flag = 1; break; } } scaling_list[zigzag[i]] = last_scale = (next_scale == 0) ? last_scale : next_scale; } if (use_default_scaling_matrix_flag) { switch (index) { case 0: case 1: case 2: { for(u = 0; u < sizeof(default_4x4_intra); u++) { scaling_list[zigzag_4x4[u]] = default_4x4_intra[u]; } //memcpy(scaling_list, default_4x4_intra, sizeof(default_4x4_intra)); break; } case 3: case 4: case 5: { for(u = 0; u < sizeof(default_4x4_inter); u++) { scaling_list[zigzag_4x4[u]] = default_4x4_inter[u]; } //memcpy(scaling_list, default_4x4_inter, sizeof(default_4x4_inter)); break; } case 6: { for(u = 0; u < sizeof(default_8x8_intra); u++) { scaling_list[zigzag_8x8[u]] = default_8x8_intra[u]; } //memcpy(scaling_list, default_8x8_intra, sizeof(default_8x8_intra)); break; } case 7: { for(u = 0; u < sizeof(default_8x8_inter); u++) { scaling_list[zigzag_8x8[u]] = default_8x8_inter[u]; } //memcpy(scaling_list, default_8x8_inter, sizeof(default_8x8_inter)); break; } } } } static void sps_scaling_list_fallback(struct seq_parameter_set_rbsp *sps, int i) { unsigned int j; switch (i) { case 0: for(j = 0; j < sizeof(default_4x4_intra); j++) { sps->scaling_lists_4x4[i][zigzag_4x4[j]] = default_4x4_intra[j]; } //memcpy(sps->scaling_lists_4x4[i], default_4x4_intra, sizeof(sps->scaling_lists_4x4[i])); break; case 3: for(j = 0; j < sizeof(default_4x4_inter); j++) { sps->scaling_lists_4x4[i][zigzag_4x4[j]] = default_4x4_inter[j]; } //memcpy(sps->scaling_lists_4x4[i], default_4x4_inter, sizeof(sps->scaling_lists_4x4[i])); break; case 1: case 2: case 4: case 5: memcpy(sps->scaling_lists_4x4[i], sps->scaling_lists_4x4[i-1], sizeof(sps->scaling_lists_4x4[i])); break; case 6: for(j = 0; j < sizeof(default_8x8_intra); j++) { sps->scaling_lists_8x8[i-6][zigzag_8x8[j]] = default_8x8_intra[j]; } //memcpy(sps->scaling_lists_8x8[i-6], default_8x8_intra, sizeof(sps->scaling_lists_8x8[i-6])); break; case 7: for(j = 0; j < sizeof(default_8x8_inter); j++) { sps->scaling_lists_8x8[i-6][zigzag_8x8[j]] = default_8x8_inter[j]; } //memcpy(sps->scaling_lists_8x8[i-6], default_8x8_inter, sizeof(sps->scaling_lists_8x8[i-6])); break; } } static void pps_scaling_list_fallback(struct seq_parameter_set_rbsp *sps, struct pic_parameter_set_rbsp *pps, int i) { switch (i) { case 0: case 3: memcpy(pps->scaling_lists_4x4[i], sps->scaling_lists_4x4[i], sizeof(pps->scaling_lists_4x4[i])); break; case 1: case 2: case 4: case 5: memcpy(pps->scaling_lists_4x4[i], pps->scaling_lists_4x4[i-1], sizeof(pps->scaling_lists_4x4[i])); break; case 6: case 7: memcpy(pps->scaling_lists_8x8[i-6], sps->scaling_lists_8x8[i-6], sizeof(pps->scaling_lists_8x8[i-6])); break; } } static uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps) { sps->profile_idc = read_bits(buf, 8); sps->constraint_setN_flag = read_bits(buf, 4); read_bits(buf, 4); sps->level_idc = read_bits(buf, 8); sps->seq_parameter_set_id = read_exp_golomb(buf); memset(sps->scaling_lists_4x4, 16, sizeof(sps->scaling_lists_4x4)); memset(sps->scaling_lists_8x8, 16, sizeof(sps->scaling_lists_8x8)); if (sps->profile_idc == 100 || sps->profile_idc == 110 || sps->profile_idc == 122 || sps->profile_idc == 244 || sps->profile_idc == 44 || sps->profile_idc == 83 || sps->profile_idc == 86) { sps->chroma_format_idc = read_exp_golomb(buf); if (sps->chroma_format_idc == 3) { sps->separate_colour_plane_flag = read_bits(buf, 1); } sps->bit_depth_luma_minus8 = read_exp_golomb(buf); sps->bit_depth_chroma_minus8 = read_exp_golomb(buf); sps->qpprime_y_zero_transform_bypass_flag = read_bits(buf, 1); sps->seq_scaling_matrix_present_flag = read_bits(buf, 1); if (sps->seq_scaling_matrix_present_flag) { int i; for (i = 0; i < 8; i++) { sps->seq_scaling_list_present_flag[i] = read_bits(buf, 1); if (sps->seq_scaling_list_present_flag[i]) { if (i < 6) parse_scaling_list(buf, sps->scaling_lists_4x4[i], 16, i); else parse_scaling_list(buf, sps->scaling_lists_8x8[i - 6], 64, i); } else { sps_scaling_list_fallback(sps, i); } } } } else sps->chroma_format_idc = 1; sps->log2_max_frame_num_minus4 = read_exp_golomb(buf); sps->max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4); sps->pic_order_cnt_type = read_exp_golomb(buf); if (!sps->pic_order_cnt_type) sps->log2_max_pic_order_cnt_lsb_minus4 = read_exp_golomb(buf); else if(sps->pic_order_cnt_type == 1) { sps->delta_pic_order_always_zero_flag = read_bits(buf, 1); sps->offset_for_non_ref_pic = read_exp_golomb_s(buf); sps->offset_for_top_to_bottom_field = read_exp_golomb_s(buf); sps->num_ref_frames_in_pic_order_cnt_cycle = read_exp_golomb(buf); int i; for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++) { sps->offset_for_ref_frame[i] = read_exp_golomb_s(buf); } } sps->num_ref_frames = read_exp_golomb(buf); sps->gaps_in_frame_num_value_allowed_flag = read_bits(buf, 1); /*sps->pic_width_in_mbs_minus1 = read_exp_golomb(buf); sps->pic_height_in_map_units_minus1 = read_exp_golomb(buf);*/ sps->pic_width = 16 * (read_exp_golomb(buf) + 1); sps->pic_height = 16 * (read_exp_golomb(buf) + 1); sps->frame_mbs_only_flag = read_bits(buf, 1); /* compute the height correctly even for interlaced material */ sps->pic_height = (2 - sps->frame_mbs_only_flag) * sps->pic_height; if (sps->pic_height == 1088) sps->pic_height = 1080; if (!sps->frame_mbs_only_flag) sps->mb_adaptive_frame_field_flag = read_bits(buf, 1); sps->direct_8x8_inference_flag = read_bits(buf, 1); sps->frame_cropping_flag = read_bits(buf, 1); if (sps->frame_cropping_flag) { sps->frame_crop_left_offset = read_exp_golomb(buf); sps->frame_crop_right_offset = read_exp_golomb(buf); sps->frame_crop_top_offset = read_exp_golomb(buf); sps->frame_crop_bottom_offset = read_exp_golomb(buf); } sps->vui_parameters_present_flag = read_bits(buf, 1); if (sps->vui_parameters_present_flag) { parse_vui_parameters(buf, sps); } return 0; } /* evaluates values parsed by sps and modifies the current * picture according to them */ static void interpret_sps(struct coded_picture *pic, struct h264_parser *parser) { if(pic->sps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "WARNING: Picture contains no seq_parameter_set\n"); return; } struct seq_parameter_set_rbsp *sps = &pic->sps_nal->sps; if(sps->vui_parameters_present_flag && sps->vui_parameters.pic_struct_present_flag) { parser->flag_mask |= PIC_STRUCT_PRESENT; } else { parser->flag_mask &= ~PIC_STRUCT_PRESENT; } if(sps->vui_parameters_present_flag && (sps->vui_parameters.nal_hrd_parameters_present_flag || sps->vui_parameters.vc1_hrd_parameters_present_flag)) { parser->flag_mask |= CPB_DPB_DELAYS_PRESENT; } else { parser->flag_mask &= ~(CPB_DPB_DELAYS_PRESENT); } if(pic->slc_nal != NULL) { struct slice_header *slc = &pic->slc_nal->slc; if (slc->field_pic_flag == 0) { pic->max_pic_num = sps->max_frame_num; parser->curr_pic_num = slc->frame_num; } else { pic->max_pic_num = 2 * sps->max_frame_num; parser->curr_pic_num = 2 * slc->frame_num + 1; } } } static void parse_sei(struct buf_reader *buf, struct sei_message *sei, struct h264_parser *parser) { uint8_t tmp; struct nal_unit *sps_nal = nal_buffer_get_last(parser->sps_buffer); if (sps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "ERR: parse_sei: seq_parameter_set_id not found in buffers\n"); return; } struct seq_parameter_set_rbsp *sps = &sps_nal->sps; sei->payload_type = 0; while((tmp = read_bits(buf, 8)) == 0xff) { sei->payload_type += 255; } sei->last_payload_type_byte = tmp; sei->payload_type += sei->last_payload_type_byte; sei->payload_size = 0; while((tmp = read_bits(buf, 8)) == 0xff) { sei->payload_size += 255; } sei->last_payload_size_byte = tmp; sei->payload_size += sei->last_payload_size_byte; /* pic_timing */ if(sei->payload_type == 1) { if(parser->flag_mask & CPB_DPB_DELAYS_PRESENT) { sei->pic_timing.cpb_removal_delay = read_bits(buf, 5); sei->pic_timing.dpb_output_delay = read_bits(buf, 5); } if(parser->flag_mask & PIC_STRUCT_PRESENT) { sei->pic_timing.pic_struct = read_bits(buf, 4); uint8_t NumClockTs = 0; switch(sei->pic_timing.pic_struct) { case 0: case 1: case 2: NumClockTs = 1; break; case 3: case 4: case 7: NumClockTs = 2; break; case 5: case 6: case 8: NumClockTs = 3; break; } int i; for(i = 0; i < NumClockTs; i++) { if(read_bits(buf, 1)) { /* clock_timestamp_flag == 1 */ sei->pic_timing.ct_type = read_bits(buf, 2); sei->pic_timing.nuit_field_based_flag = read_bits(buf, 1); sei->pic_timing.counting_type = read_bits(buf, 5); sei->pic_timing.full_timestamp_flag = read_bits(buf, 1); sei->pic_timing.discontinuity_flag = read_bits(buf, 1); sei->pic_timing.cnt_dropped_flag = read_bits(buf, 1); sei->pic_timing.n_frames = read_bits(buf, 8); if(sei->pic_timing.full_timestamp_flag) { sei->pic_timing.seconds_value = read_bits(buf, 6); sei->pic_timing.minutes_value = read_bits(buf, 6); sei->pic_timing.hours_value = read_bits(buf, 5); } else { if(read_bits(buf, 1)) { sei->pic_timing.seconds_value = read_bits(buf, 6); if(read_bits(buf, 1)) { sei->pic_timing.minutes_value = read_bits(buf, 6); if(read_bits(buf, 1)) { sei->pic_timing.hours_value = read_bits(buf, 5); } } } } if(sps->vui_parameters_present_flag && sps->vui_parameters.nal_hrd_parameters_present_flag) { sei->pic_timing.time_offset = read_bits(buf, sps->vui_parameters.nal_hrd_parameters.time_offset_length); } } } } } /*else { fprintf(stderr, "Unimplemented SEI payload: %d\n", sei->payload_type); }*/ } static void interpret_sei(struct coded_picture *pic) { if(!pic->sps_nal || !pic->sei_nal) return; struct seq_parameter_set_rbsp *sps = &pic->sps_nal->sps; struct sei_message *sei = &pic->sei_nal->sei; if(sps && sps->vui_parameters_present_flag && sps->vui_parameters.pic_struct_present_flag) { switch(sei->pic_timing.pic_struct) { case DISP_FRAME: pic->flag_mask &= ~INTERLACED; pic->repeat_pic = 0; break; case DISP_TOP: case DISP_BOTTOM: case DISP_TOP_BOTTOM: case DISP_BOTTOM_TOP: pic->flag_mask |= INTERLACED; break; case DISP_TOP_BOTTOM_TOP: case DISP_BOTTOM_TOP_BOTTOM: pic->flag_mask |= INTERLACED; pic->repeat_pic = 1; break; case DISP_FRAME_DOUBLING: pic->flag_mask &= ~INTERLACED; pic->repeat_pic = 2; break; case DISP_FRAME_TRIPLING: pic->flag_mask &= ~INTERLACED; pic->repeat_pic = 3; } } } static void parse_vui_parameters(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps) { sps->vui_parameters.aspect_ration_info_present_flag = read_bits(buf, 1); if (sps->vui_parameters.aspect_ration_info_present_flag == 1) { sps->vui_parameters.aspect_ratio_idc = read_bits(buf, 8); if (sps->vui_parameters.aspect_ratio_idc == ASPECT_EXTENDED_SAR) { sps->vui_parameters.sar_width = read_bits(buf, 16); sps->vui_parameters.sar_height = read_bits(buf, 16); } } sps->vui_parameters.overscan_info_present_flag = read_bits(buf, 1); if (sps->vui_parameters.overscan_info_present_flag) { sps->vui_parameters.overscan_appropriate_flag = read_bits(buf, 1); } sps->vui_parameters.video_signal_type_present_flag = read_bits(buf, 1); if (sps->vui_parameters.video_signal_type_present_flag) { sps->vui_parameters.video_format = read_bits(buf, 3); sps->vui_parameters.video_full_range_flag = read_bits(buf, 1); sps->vui_parameters.colour_description_present = read_bits(buf, 1); if (sps->vui_parameters.colour_description_present) { sps->vui_parameters.colour_primaries = read_bits(buf, 8); sps->vui_parameters.transfer_characteristics = read_bits(buf, 8); sps->vui_parameters.matrix_coefficients = read_bits(buf, 8); } } sps->vui_parameters.chroma_loc_info_present_flag = read_bits(buf, 1); if (sps->vui_parameters.chroma_loc_info_present_flag) { sps->vui_parameters.chroma_sample_loc_type_top_field = read_exp_golomb(buf); sps->vui_parameters.chroma_sample_loc_type_bottom_field = read_exp_golomb( buf); } sps->vui_parameters.timing_info_present_flag = read_bits(buf, 1); if (sps->vui_parameters.timing_info_present_flag) { uint32_t num_units_in_tick = read_bits(buf, 32); uint32_t time_scale = read_bits(buf, 32); sps->vui_parameters.num_units_in_tick = num_units_in_tick; sps->vui_parameters.time_scale = time_scale; sps->vui_parameters.fixed_frame_rate_flag = read_bits(buf, 1); } sps->vui_parameters.nal_hrd_parameters_present_flag = read_bits(buf, 1); if (sps->vui_parameters.nal_hrd_parameters_present_flag) parse_hrd_parameters(buf, &sps->vui_parameters.nal_hrd_parameters); sps->vui_parameters.vc1_hrd_parameters_present_flag = read_bits(buf, 1); if (sps->vui_parameters.vc1_hrd_parameters_present_flag) parse_hrd_parameters(buf, &sps->vui_parameters.vc1_hrd_parameters); if (sps->vui_parameters.nal_hrd_parameters_present_flag || sps->vui_parameters.vc1_hrd_parameters_present_flag) sps->vui_parameters.low_delay_hrd_flag = read_bits(buf, 1); sps->vui_parameters.pic_struct_present_flag = read_bits(buf, 1); sps->vui_parameters.bitstream_restriction_flag = read_bits(buf, 1); if (sps->vui_parameters.bitstream_restriction_flag) { sps->vui_parameters.motion_vectors_over_pic_boundaries = read_bits(buf, 1); sps->vui_parameters.max_bytes_per_pic_denom = read_exp_golomb(buf); sps->vui_parameters.max_bits_per_mb_denom = read_exp_golomb(buf); sps->vui_parameters.log2_max_mv_length_horizontal = read_exp_golomb(buf); sps->vui_parameters.log2_max_mv_length_vertical = read_exp_golomb(buf); sps->vui_parameters.num_reorder_frames = read_exp_golomb(buf); sps->vui_parameters.max_dec_frame_buffering = read_exp_golomb(buf); } } static void parse_hrd_parameters(struct buf_reader *buf, struct hrd_parameters *hrd) { hrd->cpb_cnt_minus1 = read_exp_golomb(buf); hrd->bit_rate_scale = read_bits(buf, 4); hrd->cpb_size_scale = read_bits(buf, 4); if (hrd->cpb_cnt_minus1 > 31) hrd->cpb_cnt_minus1 = 31; unsigned int i; for (i = 0; i <= hrd->cpb_cnt_minus1; i++) { hrd->bit_rate_value_minus1[i] = read_exp_golomb(buf); hrd->cpb_size_value_minus1[i] = read_exp_golomb(buf); hrd->cbr_flag[i] = read_bits(buf, 1); } hrd->initial_cpb_removal_delay_length_minus1 = read_bits(buf, 5); hrd->cpb_removal_delay_length_minus1 = read_bits(buf, 5); hrd->dpb_output_delay_length_minus1 = read_bits(buf, 5); hrd->time_offset_length = read_bits(buf, 5); } static uint8_t parse_pps(struct buf_reader *buf, struct pic_parameter_set_rbsp *pps) { pps->pic_parameter_set_id = read_exp_golomb(buf); pps->seq_parameter_set_id = read_exp_golomb(buf); pps->entropy_coding_mode_flag = read_bits(buf, 1); pps->pic_order_present_flag = read_bits(buf, 1); pps->num_slice_groups_minus1 = read_exp_golomb(buf); if (pps->num_slice_groups_minus1 > 0) { pps->slice_group_map_type = read_exp_golomb(buf); if (pps->slice_group_map_type == 0) { unsigned int i_group; for (i_group = 0; i_group <= pps->num_slice_groups_minus1; i_group++) { if (i_group < 64) pps->run_length_minus1[i_group] = read_exp_golomb(buf); else { // FIXME: skips if more than 64 groups exist lprintf("Error: Only 64 slice_groups are supported\n"); read_exp_golomb(buf); } } } else if (pps->slice_group_map_type == 3 || pps->slice_group_map_type == 4 || pps->slice_group_map_type == 5) { pps->slice_group_change_direction_flag = read_bits(buf, 1); pps->slice_group_change_rate_minus1 = read_exp_golomb(buf); } else if (pps->slice_group_map_type == 6) { pps->pic_size_in_map_units_minus1 = read_exp_golomb(buf); unsigned int i_group; for (i_group = 0; i_group <= pps->num_slice_groups_minus1; i_group++) { pps->slice_group_id[i_group] = read_bits(buf, ceil(log( pps->num_slice_groups_minus1 + 1))); } } } pps->num_ref_idx_l0_active_minus1 = read_exp_golomb(buf); pps->num_ref_idx_l1_active_minus1 = read_exp_golomb(buf); pps->weighted_pred_flag = read_bits(buf, 1); pps->weighted_bipred_idc = read_bits(buf, 2); pps->pic_init_qp_minus26 = read_exp_golomb_s(buf); pps->pic_init_qs_minus26 = read_exp_golomb_s(buf); pps->chroma_qp_index_offset = read_exp_golomb_s(buf); pps->deblocking_filter_control_present_flag = read_bits(buf, 1); pps->constrained_intra_pred_flag = read_bits(buf, 1); pps->redundant_pic_cnt_present_flag = read_bits(buf, 1); int bit_length = (buf->len*8)-rbsp_trailing_bits(buf->buf, buf->len); int bit_read = bits_read(buf); memset(pps->scaling_lists_4x4, 16, sizeof(pps->scaling_lists_4x4)); memset(pps->scaling_lists_8x8, 16, sizeof(pps->scaling_lists_8x8)); if (bit_length-bit_read > 1) { pps->transform_8x8_mode_flag = read_bits(buf, 1); pps->pic_scaling_matrix_present_flag = read_bits(buf, 1); if (pps->pic_scaling_matrix_present_flag) { int i; for (i = 0; i < 8; i++) { if(i < 6 || pps->transform_8x8_mode_flag) pps->pic_scaling_list_present_flag[i] = read_bits(buf, 1); else pps->pic_scaling_list_present_flag[i] = 0; if (pps->pic_scaling_list_present_flag[i]) { if (i < 6) parse_scaling_list(buf, pps->scaling_lists_4x4[i], 16, i); else parse_scaling_list(buf, pps->scaling_lists_8x8[i - 6], 64, i); } } } pps->second_chroma_qp_index_offset = read_exp_golomb_s(buf); } else pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset; return 0; } static void interpret_pps(struct coded_picture *pic) { if(pic->sps_nal == NULL) { lprintf("WARNING: Picture contains no seq_parameter_set\n"); return; } else if(pic->pps_nal == NULL) { lprintf("WARNING: Picture contains no pic_parameter_set\n"); return; } struct seq_parameter_set_rbsp *sps = &pic->sps_nal->sps; struct pic_parameter_set_rbsp *pps = &pic->pps_nal->pps; int i; for (i = 0; i < 8; i++) { if (!pps->pic_scaling_list_present_flag[i]) { pps_scaling_list_fallback(sps, pps, i); } } if (!pps->pic_scaling_matrix_present_flag && sps != NULL) { memcpy(pps->scaling_lists_4x4, sps->scaling_lists_4x4, sizeof(pps->scaling_lists_4x4)); memcpy(pps->scaling_lists_8x8, sps->scaling_lists_8x8, sizeof(pps->scaling_lists_8x8)); } } static uint8_t parse_slice_header(struct buf_reader *buf, struct nal_unit *slc_nal, struct h264_parser *parser) { struct slice_header *slc = &slc_nal->slc; slc->first_mb_in_slice = read_exp_golomb(buf); /* we do some parsing on the slice type, because the list is doubled */ slc->slice_type = slice_type(read_exp_golomb(buf)); //print_slice_type(slc->slice_type); slc->pic_parameter_set_id = read_exp_golomb(buf); /* retrieve sps and pps from the buffers */ struct nal_unit *pps_nal = nal_buffer_get_by_pps_id(parser->pps_buffer, slc->pic_parameter_set_id); if (pps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "ERR: parse_slice_header: pic_parameter_set_id %d not found in buffers\n", slc->pic_parameter_set_id); return -1; } struct pic_parameter_set_rbsp *pps = &pps_nal->pps; struct nal_unit *sps_nal = nal_buffer_get_by_sps_id(parser->sps_buffer, pps->seq_parameter_set_id); if (sps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "ERR: parse_slice_header: seq_parameter_set_id %d not found in buffers\n", pps->seq_parameter_set_id); return -1; } struct seq_parameter_set_rbsp *sps = &sps_nal->sps; if(sps->separate_colour_plane_flag) slc->colour_plane_id = read_bits(buf, 2); slc->frame_num = read_bits(buf, sps->log2_max_frame_num_minus4 + 4); if (!sps->frame_mbs_only_flag) { slc->field_pic_flag = read_bits(buf, 1); if (slc->field_pic_flag) slc->bottom_field_flag = read_bits(buf, 1); else slc->bottom_field_flag = 0; } else { slc->field_pic_flag = 0; slc->bottom_field_flag = 0; } if (slc_nal->nal_unit_type == NAL_SLICE_IDR) slc->idr_pic_id = read_exp_golomb(buf); if (!sps->pic_order_cnt_type) { slc->pic_order_cnt_lsb = read_bits(buf, sps->log2_max_pic_order_cnt_lsb_minus4 + 4); if (pps->pic_order_present_flag && !slc->field_pic_flag) slc->delta_pic_order_cnt_bottom = read_exp_golomb_s(buf); } if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) { slc->delta_pic_order_cnt[0] = read_exp_golomb_s(buf); if (pps->pic_order_present_flag && !slc->field_pic_flag) slc->delta_pic_order_cnt[1] = read_exp_golomb_s(buf); } if (pps->redundant_pic_cnt_present_flag == 1) { slc->redundant_pic_cnt = read_exp_golomb(buf); } if (slc->slice_type == SLICE_B) slc->direct_spatial_mv_pred_flag = read_bits(buf, 1); /* take default values in case they are not set here */ slc->num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_active_minus1; slc->num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_active_minus1; if (slc->slice_type == SLICE_P || slc->slice_type == SLICE_SP || slc->slice_type == SLICE_B) { slc->num_ref_idx_active_override_flag = read_bits(buf, 1); if (slc->num_ref_idx_active_override_flag == 1) { slc->num_ref_idx_l0_active_minus1 = read_exp_golomb(buf); if (slc->slice_type == SLICE_B) { slc->num_ref_idx_l1_active_minus1 = read_exp_golomb(buf); } } } /* --- ref_pic_list_reordering --- */ parse_ref_pic_list_reordering(buf, slc); /* --- pred_weight_table --- */ if ((pps->weighted_pred_flag && (slc->slice_type == SLICE_P || slc->slice_type == SLICE_SP)) || (pps->weighted_bipred_idc == 1 && slc->slice_type == SLICE_B)) { parse_pred_weight_table(buf, slc, parser); } /* --- dec_ref_pic_marking --- */ if (slc_nal->nal_ref_idc != 0) parse_dec_ref_pic_marking(buf, slc_nal); else slc->dec_ref_pic_marking_count = 0; return 0; } static void interpret_slice_header(struct h264_parser *parser, struct nal_unit *slc_nal) { struct coded_picture *pic = parser->pic; struct slice_header *slc = &slc_nal->slc; /* retrieve sps and pps from the buffers */ struct nal_unit *pps_nal = nal_buffer_get_by_pps_id(parser->pps_buffer, slc->pic_parameter_set_id); if (pps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "ERR: interpret_slice_header: pic_parameter_set_id %d not found in buffers\n", slc->pic_parameter_set_id); return; } struct nal_unit *sps_nal = nal_buffer_get_by_sps_id(parser->sps_buffer, pps_nal->pps.seq_parameter_set_id); if (sps_nal == NULL) { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "ERR: interpret_slice_header: seq_parameter_set_id %d not found in buffers\n", pps_nal->pps.seq_parameter_set_id); return; } if (pic->sps_nal) { release_nal_unit(pic->sps_nal); } if (pic->pps_nal) { release_nal_unit(pic->pps_nal); } lock_nal_unit(sps_nal); pic->sps_nal = sps_nal; lock_nal_unit(pps_nal); pic->pps_nal = pps_nal; } static void parse_ref_pic_list_reordering(struct buf_reader *buf, struct slice_header *slc) { if (slc->slice_type != SLICE_I && slc->slice_type != SLICE_SI) { slc->ref_pic_list_reordering.ref_pic_list_reordering_flag_l0 = read_bits( buf, 1); if (slc->ref_pic_list_reordering.ref_pic_list_reordering_flag_l0 == 1) { do { slc->ref_pic_list_reordering.reordering_of_pic_nums_idc = read_exp_golomb(buf); if (slc->ref_pic_list_reordering.reordering_of_pic_nums_idc == 0 || slc->ref_pic_list_reordering.reordering_of_pic_nums_idc == 1) { slc->ref_pic_list_reordering.abs_diff_pic_num_minus1 = read_exp_golomb(buf); } else if (slc->ref_pic_list_reordering.reordering_of_pic_nums_idc == 2) { slc->ref_pic_list_reordering.long_term_pic_num = read_exp_golomb(buf); } } while (slc->ref_pic_list_reordering.reordering_of_pic_nums_idc != 3); } } if (slc->slice_type == SLICE_B) { slc->ref_pic_list_reordering.ref_pic_list_reordering_flag_l1 = read_bits( buf, 1); if (slc->ref_pic_list_reordering.ref_pic_list_reordering_flag_l1 == 1) { do { slc->ref_pic_list_reordering.reordering_of_pic_nums_idc = read_exp_golomb(buf); if (slc->ref_pic_list_reordering.reordering_of_pic_nums_idc == 0 || slc->ref_pic_list_reordering.reordering_of_pic_nums_idc == 1) { slc->ref_pic_list_reordering.abs_diff_pic_num_minus1 = read_exp_golomb(buf); } else if (slc->ref_pic_list_reordering.reordering_of_pic_nums_idc == 2) { slc->ref_pic_list_reordering.long_term_pic_num = read_exp_golomb(buf); } } while (slc->ref_pic_list_reordering.reordering_of_pic_nums_idc != 3); } } } static void parse_pred_weight_table(struct buf_reader *buf, struct slice_header *slc, struct h264_parser *parser) { unsigned int i; /* retrieve sps and pps from the buffers */ struct pic_parameter_set_rbsp *pps = &nal_buffer_get_by_pps_id(parser->pps_buffer, slc->pic_parameter_set_id) ->pps; struct seq_parameter_set_rbsp *sps = &nal_buffer_get_by_sps_id(parser->sps_buffer, pps->seq_parameter_set_id) ->sps; slc->pred_weight_table.luma_log2_weight_denom = read_exp_golomb(buf); uint32_t ChromaArrayType = sps->chroma_format_idc; if(sps->separate_colour_plane_flag) ChromaArrayType = 0; if (ChromaArrayType != 0) slc->pred_weight_table.chroma_log2_weight_denom = read_exp_golomb(buf); for (i = 0; i <= slc->num_ref_idx_l0_active_minus1; i++) { uint8_t luma_weight_l0_flag = read_bits(buf, 1); if (luma_weight_l0_flag == 1) { slc->pred_weight_table.luma_weight_l0[i] = read_exp_golomb_s(buf); slc->pred_weight_table.luma_offset_l0[i] = read_exp_golomb_s(buf); } if (ChromaArrayType != 0) { uint8_t chroma_weight_l0_flag = read_bits(buf, 1); if (chroma_weight_l0_flag == 1) { int j; for (j = 0; j < 2; j++) { slc->pred_weight_table.chroma_weight_l0[i][j] = read_exp_golomb_s(buf); slc->pred_weight_table.chroma_offset_l0[i][j] = read_exp_golomb_s(buf); } } } } if ((slc->slice_type % 5) == SLICE_B) { /* FIXME: Being spec-compliant here and loop to num_ref_idx_l0_active_minus1 * will break Divx7 files. Keep this in mind if any other streams are broken */ for (i = 0; i <= slc->num_ref_idx_l1_active_minus1; i++) { uint8_t luma_weight_l1_flag = read_bits(buf, 1); if (luma_weight_l1_flag == 1) { slc->pred_weight_table.luma_weight_l1[i] = read_exp_golomb_s(buf); slc->pred_weight_table.luma_offset_l1[i] = read_exp_golomb_s(buf); } if (ChromaArrayType != 0) { uint8_t chroma_weight_l1_flag = read_bits(buf, 1); if (chroma_weight_l1_flag == 1) { int j; for (j = 0; j < 2; j++) { slc->pred_weight_table.chroma_weight_l1[i][j] = read_exp_golomb_s(buf); slc->pred_weight_table.chroma_offset_l1[i][j] = read_exp_golomb_s(buf); } } } } } } /** * PicNum calculation following ITU-T H264 11/2007 * 8.2.4.1 p112f */ static void calculate_pic_nums(struct h264_parser *parser, struct coded_picture *cpic) { struct decoded_picture *pic = NULL; struct slice_header *cslc = &cpic->slc_nal->slc; xine_list_iterator_t ite = xine_list_front(parser->dpb->reference_list); while (ite) { pic = xine_list_get_value(parser->dpb->reference_list, ite); int i; for (i=0; i<2; i++) { if(pic->coded_pic[i] == NULL) continue; struct slice_header *slc = &pic->coded_pic[i]->slc_nal->slc; struct seq_parameter_set_rbsp *sps = &pic->coded_pic[i]->sps_nal->sps; if (!pic->coded_pic[i]->used_for_long_term_ref) { int32_t frame_num_wrap = 0; if (slc->frame_num > cslc->frame_num) frame_num_wrap = slc->frame_num - sps->max_frame_num; else frame_num_wrap = slc->frame_num; if(i == 0) { pic->frame_num_wrap = frame_num_wrap; } if (cslc->field_pic_flag == 0) { pic->coded_pic[i]->pic_num = frame_num_wrap; } else { pic->coded_pic[i]->pic_num = 2 * frame_num_wrap; if((slc->field_pic_flag == 1 && cslc->bottom_field_flag == slc->bottom_field_flag) || (slc->field_pic_flag == 0 && !cslc->bottom_field_flag)) pic->coded_pic[i]->pic_num++; } } else { pic->coded_pic[i]->long_term_pic_num = pic->coded_pic[i]->long_term_frame_idx; if(slc->bottom_field_flag == cslc->bottom_field_flag) pic->coded_pic[i]->long_term_pic_num++; } } ite = xine_list_next(parser->dpb->reference_list, ite); } } static void execute_ref_pic_marking(struct coded_picture *cpic, uint32_t memory_management_control_operation, uint32_t marking_nr, struct h264_parser *parser) { /** * according to NOTE 6, p83 the dec_ref_pic_marking * structure is identical for all slice headers within * a coded picture, so we can simply use the last * slice_header we saw in the pic */ if (!cpic->slc_nal) return; struct slice_header *slc = &cpic->slc_nal->slc; struct dpb *dpb = parser->dpb; calculate_pic_nums(parser, cpic); if (cpic->flag_mask & IDR_PIC) { if(slc->dec_ref_pic_marking[marking_nr].long_term_reference_flag) { cpic->used_for_long_term_ref = 1; dpb_set_unused_ref_picture_lidx_gt(dpb, 0); } else { dpb_set_unused_ref_picture_lidx_gt(dpb, -1); } return; } /* MMC operation == 1 : 8.2.5.4.1, p. 120 */ if (memory_management_control_operation == 1) { // short-term -> unused for reference int32_t pic_num_x = (parser->curr_pic_num - (slc->dec_ref_pic_marking[marking_nr].difference_of_pic_nums_minus1 + 1)); //% cpic->max_pic_num; struct decoded_picture* pic = NULL; if ((pic = dpb_get_picture(dpb, pic_num_x)) != NULL) { if (cpic->slc_nal->slc.field_pic_flag == 0) { dpb_unmark_reference_picture(dpb, pic); } else { if (pic->coded_pic[0]->slc_nal->slc.field_pic_flag == 1) { if (pic->top_is_reference) pic->top_is_reference = 0; else if (pic->bottom_is_reference) pic->bottom_is_reference = 0; if(!pic->top_is_reference && !pic->bottom_is_reference) dpb_unmark_reference_picture(dpb, pic); } else { pic->top_is_reference = pic->bottom_is_reference = 0; dpb_unmark_reference_picture(dpb, pic); } } } else { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "H264: mmc 1 failed: %d not existent - curr_pic: %d\n", pic_num_x, parser->curr_pic_num); } } else if (memory_management_control_operation == 2) { // long-term -> unused for reference struct decoded_picture* pic = dpb_get_picture_by_ltpn(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_pic_num); if (pic != NULL) { if (cpic->slc_nal->slc.field_pic_flag == 0) dpb_set_unused_ref_picture_byltpn(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_pic_num); else { if (pic->coded_pic[0]->slc_nal->slc.field_pic_flag == 1) { if (pic->top_is_reference) pic->top_is_reference = 0; else if (pic->bottom_is_reference) pic->bottom_is_reference = 0; if(!pic->top_is_reference && !pic->bottom_is_reference) { dpb_set_unused_ref_picture_byltpn(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_pic_num); } } else { pic->top_is_reference = pic->bottom_is_reference = 0; dpb_set_unused_ref_picture_byltpn(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_pic_num); } } } } else if (memory_management_control_operation == 3) { // short-term -> long-term, set long-term frame index uint32_t pic_num_x = parser->curr_pic_num - (slc->dec_ref_pic_marking[marking_nr].difference_of_pic_nums_minus1 + 1); struct decoded_picture* pic = dpb_get_picture_by_ltidx(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_pic_num); if (pic != NULL) dpb_set_unused_ref_picture_bylidx(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_frame_idx); pic = dpb_get_picture(dpb, pic_num_x); if (pic) { pic = dpb_get_picture(dpb, pic_num_x); if (pic->coded_pic[0]->slc_nal->slc.field_pic_flag == 0) { pic->coded_pic[0]->long_term_frame_idx = slc->dec_ref_pic_marking[marking_nr].long_term_frame_idx; pic->coded_pic[0]->long_term_pic_num = pic->coded_pic[0]->long_term_frame_idx; } else { if(pic->coded_pic[0]->pic_num == (int32_t)pic_num_x) { pic->coded_pic[0]->long_term_frame_idx = slc->dec_ref_pic_marking[marking_nr].long_term_frame_idx; pic->coded_pic[0]->long_term_pic_num = pic->coded_pic[0]->long_term_frame_idx * 2 + 1; } else if(pic->coded_pic[1] != NULL && pic->coded_pic[1]->pic_num == (int32_t)pic_num_x) { pic->coded_pic[1]->long_term_frame_idx = slc->dec_ref_pic_marking[marking_nr].long_term_frame_idx; pic->coded_pic[1]->long_term_pic_num = pic->coded_pic[1]->long_term_frame_idx * 2 + 1; } } } else { xprintf(parser->xine, XINE_VERBOSITY_DEBUG, "memory_management_control_operation: 3 failed. No such picture.\n"); } } else if (memory_management_control_operation == 4) { /* set max-long-term frame index, * mark all long-term pictures with long-term frame idx * greater max-long-term farme idx as unused for ref */ if (slc->dec_ref_pic_marking[marking_nr].max_long_term_frame_idx_plus1 == 0) dpb_set_unused_ref_picture_lidx_gt(dpb, 0); else dpb_set_unused_ref_picture_lidx_gt(dpb, slc->dec_ref_pic_marking[marking_nr].max_long_term_frame_idx_plus1 - 1); } else if (memory_management_control_operation == 5) { /* mark all ref pics as unused for reference, * set max-long-term frame index = no long-term frame idxs */ dpb_flush(dpb); if (!slc->bottom_field_flag) { parser->prev_pic_order_cnt_lsb = cpic->top_field_order_cnt; parser->prev_pic_order_cnt_msb = 0; } else { parser->prev_pic_order_cnt_lsb = 0; parser->prev_pic_order_cnt_msb = 0; } } else if (memory_management_control_operation == 6) { /* mark current picture as used for long-term ref, * assing long-term frame idx to it */ struct decoded_picture* pic = dpb_get_picture_by_ltidx(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_frame_idx); if (pic != NULL) dpb_set_unused_ref_picture_bylidx(dpb, slc->dec_ref_pic_marking[marking_nr].long_term_frame_idx); cpic->long_term_frame_idx = slc->dec_ref_pic_marking[marking_nr].long_term_frame_idx; cpic->used_for_long_term_ref = 1; if (slc->field_pic_flag == 0) { cpic->long_term_pic_num = cpic->long_term_frame_idx; } else { cpic->long_term_pic_num = cpic->long_term_frame_idx * 2 + 1; } } } static void parse_dec_ref_pic_marking(struct buf_reader *buf, struct nal_unit *slc_nal) { struct slice_header *slc = &slc_nal->slc; if (!slc) return; slc->dec_ref_pic_marking_count = 0; int i = slc->dec_ref_pic_marking_count; if (slc_nal->nal_unit_type == NAL_SLICE_IDR) { slc->dec_ref_pic_marking[i].no_output_of_prior_pics_flag = read_bits(buf, 1); slc->dec_ref_pic_marking[i].long_term_reference_flag = read_bits(buf, 1); i+=2; } else { slc->dec_ref_pic_marking[i].adaptive_ref_pic_marking_mode_flag = read_bits( buf, 1); if (slc->dec_ref_pic_marking[i].adaptive_ref_pic_marking_mode_flag) { do { slc->dec_ref_pic_marking[i].memory_management_control_operation = read_exp_golomb(buf); if (slc->dec_ref_pic_marking[i].memory_management_control_operation == 1 || slc->dec_ref_pic_marking[i].memory_management_control_operation == 3) slc->dec_ref_pic_marking[i].difference_of_pic_nums_minus1 = read_exp_golomb(buf); if (slc->dec_ref_pic_marking[i].memory_management_control_operation == 2) slc->dec_ref_pic_marking[i].long_term_pic_num = read_exp_golomb(buf); if (slc->dec_ref_pic_marking[i].memory_management_control_operation == 3 || slc->dec_ref_pic_marking[i].memory_management_control_operation == 6) slc->dec_ref_pic_marking[i].long_term_frame_idx = read_exp_golomb(buf); if (slc->dec_ref_pic_marking[i].memory_management_control_operation == 4) slc->dec_ref_pic_marking[i].max_long_term_frame_idx_plus1 = read_exp_golomb(buf); i++; if(i >= 10) { lprintf("Error: Not more than 10 MMC operations supported per slice. Dropping some.\n"); i = 0; } } while (slc->dec_ref_pic_marking[i-1].memory_management_control_operation != 0); } } slc->dec_ref_pic_marking_count = (i>0) ? (i-1) : 0; } /* ----------------- NAL parser ----------------- */ #if 0 static void reset_parser(struct h264_parser *parser) { parser->position = NON_VCL; parser->buf_len = parser->prebuf_len = 0; parser->next_nal_position = 0; parser->last_nal_res = 0; if(parser->last_vcl_nal) { release_nal_unit(parser->last_vcl_nal); } parser->last_vcl_nal = NULL; parser->prev_pic_order_cnt_msb = 0; parser->prev_pic_order_cnt_lsb = 0; parser->frame_num_offset = 0; parser->prev_top_field_order_cnt = 0; parser->curr_pic_num = 0; parser->flag_mask = 0; if(parser->pic != NULL) { free_coded_picture(parser->pic); parser->pic = create_coded_picture(); } } #endif static void release_dpb(struct dpb *dpb) { if(!dpb) return; dpb_free_all(dpb); xine_list_delete(dpb->output_list); xine_list_delete(dpb->reference_list); free(dpb); } static void free_parser(struct h264_parser *parser) { dpb_free_all(parser->dpb); release_dpb(parser->dpb); free_nal_buffer(parser->pps_buffer); free_nal_buffer(parser->sps_buffer); free(parser); } static struct h264_parser* init_parser(xine_t *xine) { struct h264_parser *parser = calloc(1, sizeof(struct h264_parser)); if (!parser) return NULL; parser->pic = create_coded_picture(); parser->position = NON_VCL; parser->last_vcl_nal = NULL; parser->sps_buffer = create_nal_buffer(32); parser->pps_buffer = create_nal_buffer(32); parser->xine = xine; parser->dpb = create_dpb(); if (!parser->dpb || !parser->pic || !parser->pps_buffer || !parser->sps_buffer) { free_parser(parser); return NULL; } return parser; } static void parse_codec_private(struct h264_parser *parser, const uint8_t *inbuf, int inbuf_len) { struct buf_reader bufr; bufr.buf = inbuf; bufr.cur_pos = inbuf; bufr.cur_offset = 8; bufr.len = inbuf_len; // FIXME: Might be broken! struct nal_unit *nal = calloc(1, sizeof(struct nal_unit)); if (!nal) return; /* reserved */ read_bits(&bufr, 8); nal->sps.profile_idc = read_bits(&bufr, 8); read_bits(&bufr, 8); nal->sps.level_idc = read_bits(&bufr, 8); read_bits(&bufr, 6); parser->nal_size_length = read_bits(&bufr, 2) + 1; parser->nal_size_length_buf = calloc(1, parser->nal_size_length); read_bits(&bufr, 3); uint8_t sps_count = read_bits(&bufr, 5); inbuf += 6; inbuf_len -= 6; int i; struct coded_picture *dummy = NULL; for(i = 0; i < sps_count; i++) { uint16_t sps_size = read_bits(&bufr, 16); inbuf += 2; inbuf_len -= 2; parse_nal(inbuf, sps_size, parser, &dummy); inbuf += sps_size; inbuf_len -= sps_size; } bufr.buf = inbuf; bufr.cur_pos = inbuf; bufr.cur_offset = 8; bufr.len = inbuf_len; uint8_t pps_count = read_bits(&bufr, 8); inbuf += 1; for(i = 0; i < pps_count; i++) { uint16_t pps_size = read_bits(&bufr, 16); inbuf += 2; inbuf_len -= 2; parse_nal(inbuf, pps_size, parser, &dummy); inbuf += pps_size; inbuf_len -= pps_size; } nal_buffer_append(parser->sps_buffer, nal); } static void process_mmc_operations(struct h264_parser *parser, struct coded_picture *picture) { if (picture->flag_mask & REFERENCE) { parser->prev_pic_order_cnt_lsb = picture->slc_nal->slc.pic_order_cnt_lsb; } uint32_t i; for(i = 0; i < picture->slc_nal->slc. dec_ref_pic_marking_count; i++) { execute_ref_pic_marking( picture, picture->slc_nal->slc.dec_ref_pic_marking[i]. memory_management_control_operation, i, parser); } } static int parse_frame(struct h264_parser *parser, const uint8_t *inbuf, int inbuf_len, int64_t pts, const void **ret_buf, uint32_t *ret_len, struct coded_picture **ret_pic) { int32_t next_nal = 0; int32_t offset = 0; int start_seq_len = 3; *ret_pic = NULL; *ret_buf = NULL; *ret_len = 0; if(parser->nal_size_length > 0) start_seq_len = offset = parser->nal_size_length; if (parser->prebuf_len + inbuf_len > MAX_FRAME_SIZE) { xprintf(parser->xine, XINE_VERBOSITY_LOG,"h264_parser: prebuf underrun\n"); *ret_len = 0; *ret_buf = NULL; parser->prebuf_len = 0; return inbuf_len; } /* copy the whole inbuf to the prebuf, * then search for a nal-start sequence in the prebuf, * if it's in there, parse the nal and append to parser->buf * or return a frame */ xine_fast_memcpy(parser->prebuf + parser->prebuf_len, inbuf, inbuf_len); parser->prebuf_len += inbuf_len; while((next_nal = seek_for_nal(parser->prebuf+start_seq_len-offset, parser->prebuf_len-start_seq_len+offset, parser)) > 0) { struct coded_picture *completed_pic = NULL; if(!parser->nal_size_length && (parser->prebuf[0] != 0x00 || parser->prebuf[1] != 0x00 || parser->prebuf[2] != 0x01)) { xprintf(parser->xine, XINE_VERBOSITY_LOG, "Broken NAL, skip it.\n"); parser->last_nal_res = 2; } else { parser->last_nal_res = parse_nal(parser->prebuf+start_seq_len, next_nal, parser, &completed_pic); } if (completed_pic != NULL && completed_pic->slice_cnt > 0 && parser->buf_len > 0) { //lprintf("Frame complete: %d bytes\n", parser->buf_len); *ret_len = parser->buf_len; { uint8_t *rbuf = malloc(parser->buf_len); *ret_buf = rbuf; if (rbuf) xine_fast_memcpy(rbuf, parser->buf, parser->buf_len); } *ret_pic = completed_pic; parser->buf_len = 0; if (pts != 0 && (parser->pic->pts == 0 || parser->pic->pts != pts)) { parser->pic->pts = pts; } /** * if the new coded picture started with a VCL nal * we have to copy this to buffer for the next picture * now. */ if(parser->last_nal_res == 1) { if(parser->nal_size_length > 0) { static const uint8_t start_seq[3] = { 0x00, 0x00, 0x01 }; xine_fast_memcpy(parser->buf, start_seq, 3); parser->buf_len += 3; } xine_fast_memcpy(parser->buf+parser->buf_len, parser->prebuf+offset, next_nal+start_seq_len-2*offset); parser->buf_len += next_nal+start_seq_len-2*offset; } memmove(parser->prebuf, parser->prebuf+(next_nal+start_seq_len-offset), parser->prebuf_len-(next_nal+start_seq_len-offset)); parser->prebuf_len -= next_nal+start_seq_len-offset; return inbuf_len; } /* got a new nal, which is part of the current * coded picture. add it to buf */ if (parser->last_nal_res < 2) { if (parser->buf_len + next_nal+start_seq_len-offset > MAX_FRAME_SIZE) { xprintf(parser->xine, XINE_VERBOSITY_LOG, "h264_parser: buf underrun!\n"); parser->buf_len = 0; *ret_len = 0; *ret_buf = NULL; return inbuf_len; } if(parser->nal_size_length > 0) { static const uint8_t start_seq[3] = { 0x00, 0x00, 0x01 }; xine_fast_memcpy(parser->buf+parser->buf_len, start_seq, 3); parser->buf_len += 3; } xine_fast_memcpy(parser->buf+parser->buf_len, parser->prebuf+offset, next_nal+start_seq_len-2*offset); parser->buf_len += next_nal+start_seq_len-2*offset; memmove(parser->prebuf, parser->prebuf+(next_nal+start_seq_len-offset), parser->prebuf_len-(next_nal+start_seq_len-offset)); parser->prebuf_len -= next_nal+start_seq_len-offset; } else { /* got a non-relevant nal, just remove it */ memmove(parser->prebuf, parser->prebuf+(next_nal+start_seq_len-offset), parser->prebuf_len-(next_nal+start_seq_len-offset)); parser->prebuf_len -= next_nal+start_seq_len-offset; } } if (pts != 0 && (parser->pic->pts == 0 || parser->pic->pts != pts)) { parser->pic->pts = pts; } *ret_buf = NULL; *ret_len = 0; return inbuf_len; } /** * @return 0: NAL is part of coded picture * 2: NAL is not part of coded picture * 1: NAL is the beginning of a new coded picture * 3: NAL is marked as END_OF_SEQUENCE */ static int parse_nal(const uint8_t *buf, int buf_len, struct h264_parser *parser, struct coded_picture **completed_picture) { int ret = 0; struct buf_reader bufr; bufr.buf = buf; bufr.cur_pos = buf; bufr.cur_offset = 8; bufr.len = buf_len; *completed_picture = NULL; struct nal_unit *nal = parse_nal_header(&bufr, parser->pic, parser); /** * we detect the start of a new access unit if * a non-vcl nal unit is received after a vcl * nal unit * NAL_END_OF_SEQUENCE terminates the current * access unit */ if (nal->nal_unit_type >= NAL_SLICE && nal->nal_unit_type <= NAL_SLICE_IDR) { parser->position = VCL; } else if ((parser->position == VCL && nal->nal_unit_type >= NAL_SEI && nal->nal_unit_type <= NAL_PPS) || nal->nal_unit_type == NAL_AU_DELIMITER || nal->nal_unit_type == NAL_END_OF_SEQUENCE) { /* start of a new access unit! */ *completed_picture = parser->pic; parser->pic = create_coded_picture(); if(parser->last_vcl_nal != NULL) { release_nal_unit(parser->last_vcl_nal); parser->last_vcl_nal = NULL; } parser->position = NON_VCL; } else { parser->position = NON_VCL; } switch(nal->nal_unit_type) { case NAL_SPS: nal_buffer_append(parser->sps_buffer, nal); break; case NAL_PPS: nal_buffer_append(parser->pps_buffer, nal); break; case NAL_SEI: { if (parser->pic != NULL) { if(parser->pic->sei_nal) { release_nal_unit(parser->pic->sei_nal); } lock_nal_unit(nal); parser->pic->sei_nal = nal; interpret_sei(parser->pic); } } default: break; } /** * in case of an access unit which does not contain any * non-vcl nal units we have to detect the new access * unit through the algorithm for detecting first vcl nal * units of a primary coded picture */ if (parser->position == VCL && parser->last_vcl_nal != NULL && nal->nal_unit_type >= NAL_SLICE && nal->nal_unit_type <= NAL_SLICE_IDR) { /** * frame boundary detection according to * ITU-T Rec. H264 (11/2007) chapt 7.4.1.2.4, p65 */ struct nal_unit* last_nal = parser->last_vcl_nal; if (nal == NULL || last_nal == NULL) { ret = 1; } else if (nal->slc.frame_num != last_nal->slc.frame_num) { ret = 1; } else if (nal->slc.pic_parameter_set_id != last_nal->slc.pic_parameter_set_id) { ret = 1; } else if (nal->slc.field_pic_flag != last_nal->slc.field_pic_flag) { ret = 1; } else if (nal->slc.bottom_field_flag != last_nal->slc.bottom_field_flag) { ret = 1; } else if (nal->nal_ref_idc != last_nal->nal_ref_idc && (nal->nal_ref_idc == 0 || last_nal->nal_ref_idc == 0)) { ret = 1; } else if (nal->sps.pic_order_cnt_type == 0 && last_nal->sps.pic_order_cnt_type == 0 && (nal->slc.pic_order_cnt_lsb != last_nal->slc.pic_order_cnt_lsb || nal->slc.delta_pic_order_cnt_bottom != last_nal->slc.delta_pic_order_cnt_bottom)) { ret = 1; } else if (nal->sps.pic_order_cnt_type == 1 && last_nal->sps.pic_order_cnt_type == 1 && (nal->slc.delta_pic_order_cnt[0] != last_nal->slc.delta_pic_order_cnt[0] || nal->slc.delta_pic_order_cnt[1] != last_nal->slc.delta_pic_order_cnt[1])) { ret = 1; } else if (nal->nal_unit_type != last_nal->nal_unit_type && (nal->nal_unit_type == NAL_SLICE_IDR || last_nal->nal_unit_type == NAL_SLICE_IDR)) { ret = 1; } else if (nal->nal_unit_type == NAL_SLICE_IDR && last_nal->nal_unit_type == NAL_SLICE_IDR && nal->slc.idr_pic_id != last_nal->slc.idr_pic_id) { ret = 1; } /* increase the slice_cnt until a new frame is detected */ if (ret && *completed_picture == NULL) { *completed_picture = parser->pic; parser->pic = create_coded_picture(); } } else if (nal->nal_unit_type == NAL_PPS || nal->nal_unit_type == NAL_SPS) { ret = 2; } else if (nal->nal_unit_type == NAL_AU_DELIMITER) { ret = 2; } else if (nal->nal_unit_type == NAL_END_OF_SEQUENCE) { ret = 3; } else if (nal->nal_unit_type >= NAL_SEI) { ret = 2; } if (parser->pic) { if (nal->nal_unit_type == NAL_SLICE_IDR) { parser->pic->flag_mask |= IDR_PIC; } /* reference flag is only set for slice NALs, * as PPS/SPS/SEI only references are not relevant * for the vdpau decoder. */ if (nal->nal_ref_idc && nal->nal_unit_type <= NAL_SLICE_IDR) { parser->pic->flag_mask |= REFERENCE; } else if (!nal->nal_ref_idc && nal->nal_unit_type >= NAL_SLICE && nal->nal_unit_type <= NAL_PART_C) { /* remove reference flag if a picture is not * continously flagged as reference. */ parser->pic->flag_mask &= ~REFERENCE; } if (nal->nal_unit_type >= NAL_SLICE && nal->nal_unit_type <= NAL_SLICE_IDR) { lock_nal_unit(nal); if(parser->last_vcl_nal) { release_nal_unit(parser->last_vcl_nal); } parser->last_vcl_nal = nal; parser->pic->slice_cnt++; if(parser->pic->slc_nal) { release_nal_unit(parser->pic->slc_nal); } lock_nal_unit(nal); parser->pic->slc_nal = nal; interpret_slice_header(parser, nal); } if (*completed_picture != NULL && (*completed_picture)->slice_cnt > 0) { calculate_pic_order(parser, *completed_picture, &((*completed_picture)->slc_nal->slc)); interpret_sps(*completed_picture, parser); interpret_pps(*completed_picture); } } release_nal_unit(nal); return ret; } static int seek_for_nal(uint8_t *buf, int buf_len, struct h264_parser *parser) { if(buf_len <= 0) return -1; if(parser->nal_size_length > 0) { if(buf_len < parser->nal_size_length) { return -1; } uint32_t next_nal = parser->next_nal_position; if(!next_nal) { struct buf_reader bufr; bufr.buf = buf; bufr.cur_pos = buf; bufr.cur_offset = 8; bufr.len = buf_len; next_nal = read_bits(&bufr, parser->nal_size_length*8)+parser->nal_size_length; } if(next_nal > (uint32_t)buf_len) { parser->next_nal_position = next_nal; return -1; } else parser->next_nal_position = 0; return next_nal; } /* NAL_END_OF_SEQUENCE has only 1 byte, so * we do not need to search for the next start sequence */ if(buf[0] == NAL_END_OF_SEQUENCE) return 1; int i; for (i = 0; i < buf_len - 2; i++) { if (buf[i] == 0x00 && buf[i + 1] == 0x00 && buf[i + 2] == 0x01) { //lprintf("found nal at: %d\n", i); return i; } } return -1; } /************************************************************************* * main * *************************************************************************/ #define VIDEOBUFSIZE 128*1024 typedef struct vdpau_h264_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; /* these are traditional variables in a video decoder object */ uint64_t video_step; /* frame duration in pts units */ uint64_t reported_video_step; /* frame duration in pts units */ int width; /* the width of a video frame */ int height; /* the height of a video frame */ double ratio; /* the width to height ratio */ struct h264_parser *nal_parser; /* h264 nal parser. extracts stream data for vdpau */ struct decoded_picture *incomplete_pic; uint32_t last_top_field_order_cnt; int have_frame_boundary_marks; int wait_for_frame_start; VdpDecoder decoder; int decoder_started; int progressive_cnt; /* count of progressive marked frames in line */ VdpDecoderProfile profile; vdpau_accel_t *vdpau_accel; xine_t *xine; struct coded_picture *completed_pic; vo_frame_t *dangling_img; uint8_t *codec_private; uint32_t codec_private_len; int vdp_runtime_nr; int reset; } vdpau_h264_decoder_t; static void vdpau_h264_reset (video_decoder_t *this_gen); static void vdpau_h264_flush (video_decoder_t *this_gen); /************************************************************************** * vdpau_h264 specific decode functions *************************************************************************/ /************************************************************************** * xine video plugin functions *************************************************************************/ #ifdef DEBUG_H264 static inline void dump_pictureinfo_h264(VdpPictureInfoH264 *pic) { printf("C: slice_count: %d\n", pic->slice_count); printf("C: field_order_cnt[0]: %d\n", pic->field_order_cnt[0]); printf("C: field_order_cnt[1]: %d\n", pic->field_order_cnt[1]); printf("C: is_reference: %d\n", pic->is_reference); printf("C: frame_num: %d\n", pic->frame_num); printf("C: field_pic_flag: %d\n", pic->field_pic_flag); printf("C: bottom_field_flag: %d\n", pic->bottom_field_flag); printf("C: num_ref_frames: %d\n", pic->num_ref_frames); printf("C: mb_adaptive_frame_field_flag: %d\n", pic->mb_adaptive_frame_field_flag); printf("C: constrained_intra_pred_flag: %d\n", pic->constrained_intra_pred_flag); printf("C: weighted_pred_flag: %d\n", pic->weighted_pred_flag); printf("C: weighted_bipred_idc: %d\n", pic->weighted_bipred_idc); printf("C: frame_mbs_only_flag: %d\n", pic->frame_mbs_only_flag); printf("C: transform_8x8_mode_flag: %d\n", pic->transform_8x8_mode_flag); printf("C: chroma_qp_index_offset: %d\n", pic->chroma_qp_index_offset); printf("C: second_chroma_qp_index_offset: %d\n", pic->second_chroma_qp_index_offset); printf("C: pic_init_qp_minus26: %d\n", pic->pic_init_qp_minus26); printf("C: num_ref_idx_l0_active_minus1: %d\n", pic->num_ref_idx_l0_active_minus1); printf("C: num_ref_idx_l1_active_minus1: %d\n", pic->num_ref_idx_l1_active_minus1); printf("C: log2_max_frame_num_minus4: %d\n", pic->log2_max_frame_num_minus4); printf("C: pic_order_cnt_type: %d\n", pic->pic_order_cnt_type); printf("C: log2_max_pic_order_cnt_lsb_minus4: %d\n", pic->log2_max_pic_order_cnt_lsb_minus4); printf("C: delta_pic_order_always_zero_flag: %d\n", pic->delta_pic_order_always_zero_flag); printf("C: direct_8x8_inference_flag: %d\n", pic->direct_8x8_inference_flag); printf("C: entropy_coding_mode_flag: %d\n", pic->entropy_coding_mode_flag); printf("C: pic_order_present_flag: %d\n", pic->pic_order_present_flag); printf("C: deblocking_filter_control_present_flag: %d\n", pic->deblocking_filter_control_present_flag); printf("C: redundant_pic_cnt_present_flag: %d\n", pic->redundant_pic_cnt_present_flag); int i, j; for(i = 0; i < 6; i++) { printf("C: scalint_list4x4[%d]:\nC:", i); for(j = 0; j < 16; j++) { printf(" [%d]", pic->scaling_lists_4x4[i][j]); if(j%8 == 0) printf("\nC:"); } printf("C: \n"); } for(i = 0; i < 2; i++) { printf("C: scalint_list8x8[%d]:\nC:", i); for(j = 0; j < 64; j++) { printf(" [%d] ", pic->scaling_lists_8x8[i][j]); if(j%8 == 0) printf("\nC:"); } printf("C: \n"); } //int i; for(i = 0; i < 16; i++) { if(pic->referenceFrames[i].surface != VDP_INVALID_HANDLE) { printf("C: -------------------\n"); printf("C: Reference Frame %d:\n", i); printf("C: frame_idx: %d\n", pic->referenceFrames[i].frame_idx); printf("C: field_order_cnt[0]: %d\n", pic->referenceFrames[i].field_order_cnt[0]); printf("C: field_order_cnt[1]: %d\n", pic->referenceFrames[i].field_order_cnt[0]); printf("C: is_long_term: %d\n", pic->referenceFrames[i].is_long_term); printf("C: top_is_reference: %d\n", pic->referenceFrames[i].top_is_reference); printf("C: bottom_is_reference: %d\n", pic->referenceFrames[i].bottom_is_reference); } } printf("C: ---------------------------------------------------------------\n"); /*memcpy(pic.scaling_lists_4x4, pps->scaling_lists_4x4, 6*16); memcpy(pic.scaling_lists_8x8, pps->scaling_lists_8x8, 2*64); memcpy(pic.referenceFrames, this->reference_frames, sizeof(this->reference_frames));*/ } #endif static void set_ratio(video_decoder_t *this_gen) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *)this_gen; this->ratio = (double)this->width / (double)this->height; if(this->completed_pic->sps_nal->sps.vui_parameters.aspect_ration_info_present_flag) { switch(this->completed_pic->sps_nal->sps.vui_parameters.aspect_ratio_idc) { case ASPECT_1_1: this->ratio = 1 * this->ratio; break; case ASPECT_12_11: this->ratio *= 12.0/11.0; break; case ASPECT_10_11: this->ratio *= 10.0/11.0; break; case ASPECT_16_11: this->ratio *= 16.0/11.0; break; case ASPECT_40_33: this->ratio *= 40.0/33.0; break; case ASPECT_24_11: this->ratio *= 24.0/11.0; break; case ASPECT_20_11: this->ratio *= 20.0/11.0; break; case ASPECT_32_11: this->ratio *= 32.0/11.0; break; case ASPECT_80_33: this->ratio *= 80.0/33.0; break; case ASPECT_18_11: this->ratio *= 18.0/11.0; break; case ASPECT_15_11: this->ratio *= 15.0/11.0; break; case ASPECT_64_33: this->ratio *= 64.0/33.0; break; case ASPECT_160_99: this->ratio *= 160.0/99.0; break; case ASPECT_4_3: this->ratio *= 4.0/3.0; break; case ASPECT_3_2: this->ratio *= 3.0/2.0; break; case ASPECT_2_1: this->ratio *= 2.0/1.0; break; case ASPECT_EXTENDED_SAR: this->ratio *= (double)this->completed_pic->sps_nal->sps.vui_parameters.sar_width/ (double)this->completed_pic->sps_nal->sps.vui_parameters.sar_height; break; } } } static void fill_vdpau_pictureinfo_h264(video_decoder_t *this_gen, uint32_t slice_count, VdpPictureInfoH264 *pic) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *)this_gen; struct pic_parameter_set_rbsp *pps = &this->completed_pic->pps_nal->pps; struct seq_parameter_set_rbsp *sps = &this->completed_pic->sps_nal->sps; struct slice_header *slc = &this->completed_pic->slc_nal->slc; pic->slice_count = slice_count; pic->field_order_cnt[0] = this->completed_pic->top_field_order_cnt; pic->field_order_cnt[1] = this->completed_pic->bottom_field_order_cnt; pic->is_reference = (this->completed_pic->flag_mask & REFERENCE) ? VDP_TRUE : VDP_FALSE; pic->frame_num = slc->frame_num; pic->field_pic_flag = slc->field_pic_flag; pic->bottom_field_flag = slc->bottom_field_flag; pic->num_ref_frames = sps->num_ref_frames; pic->mb_adaptive_frame_field_flag = sps->mb_adaptive_frame_field_flag && !slc->field_pic_flag; pic->constrained_intra_pred_flag = pps->constrained_intra_pred_flag; pic->weighted_pred_flag = pps->weighted_pred_flag; pic->weighted_bipred_idc = pps->weighted_bipred_idc; pic->frame_mbs_only_flag = sps->frame_mbs_only_flag; pic->transform_8x8_mode_flag = pps->transform_8x8_mode_flag; pic->chroma_qp_index_offset = pps->chroma_qp_index_offset; pic->second_chroma_qp_index_offset = pps->second_chroma_qp_index_offset; pic->pic_init_qp_minus26 = pps->pic_init_qp_minus26; pic->num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_active_minus1; pic->num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_active_minus1; pic->log2_max_frame_num_minus4 = sps->log2_max_frame_num_minus4; pic->pic_order_cnt_type = sps->pic_order_cnt_type; pic->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_pic_order_cnt_lsb_minus4; pic->delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag; pic->direct_8x8_inference_flag = sps->direct_8x8_inference_flag; pic->entropy_coding_mode_flag = pps->entropy_coding_mode_flag; pic->pic_order_present_flag = pps->pic_order_present_flag; pic->deblocking_filter_control_present_flag = pps->deblocking_filter_control_present_flag; pic->redundant_pic_cnt_present_flag = pps->redundant_pic_cnt_present_flag; memcpy(pic->scaling_lists_4x4, pps->scaling_lists_4x4, sizeof(pic->scaling_lists_4x4)); memcpy(pic->scaling_lists_8x8, pps->scaling_lists_8x8, sizeof(pic->scaling_lists_8x8)); /* set num_ref_frames to the number of actually available reference frames, * if this is not set generation 3 decoders will fail. */ /*pic->num_ref_frames =*/ fill_vdpau_reference_list(this->nal_parser->dpb, pic->referenceFrames); } static int check_progressive(video_decoder_t *this_gen, struct decoded_picture *dpic) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *)this_gen; int progressive = 0; int i; for(i = 0; i < 2; i++) { struct coded_picture *pic = dpic->coded_pic[i]; if (!pic) { continue; } if (pic->flag_mask & PIC_STRUCT_PRESENT && pic->sei_nal != NULL) { uint8_t pic_struct = pic->sei_nal->sei.pic_timing.pic_struct; if (pic_struct == DISP_FRAME) { progressive = 1; continue; } else if (pic_struct == DISP_TOP_BOTTOM || pic_struct == DISP_BOTTOM_TOP) { progressive = 0; break; } /* FIXME: seems unreliable, maybe it's has to be interpreted more complex */ /*if (pic->sei_nal->sei.pic_timing.ct_type == CT_INTERLACED) { return 0; } else if (pic->sei_nal->sei.pic_timing.ct_type == CT_PROGRESSIVE) { return 1; } */ } if (pic->slc_nal->slc.field_pic_flag && pic->pps_nal->pps.pic_order_present_flag) { if(pic->slc_nal->slc.delta_pic_order_cnt_bottom == 1 || pic->slc_nal->slc.delta_pic_order_cnt_bottom == -1) { progressive = 0; break; } else { progressive = 1; continue; } } if (!pic->slc_nal->slc.field_pic_flag && pic->sps_nal->sps.frame_mbs_only_flag) { progressive = 1; continue; } } if (progressive) { this->progressive_cnt++; } else { this->progressive_cnt = 0; } /* only switch to progressive mode if at least 5 * frames in order were marked as progressive */ return (this->progressive_cnt >= 5); } static int vdpau_decoder_init(video_decoder_t *this_gen) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *)this_gen; vo_frame_t *img; if(this->width == 0) { this->width = this->completed_pic->sps_nal->sps.pic_width; this->height = this->completed_pic->sps_nal->sps.pic_height; } set_ratio(this_gen); _x_stream_info_set( this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width ); _x_stream_info_set( this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height ); _x_stream_info_set( this->stream, XINE_STREAM_INFO_VIDEO_RATIO, ((double)10000*this->ratio) ); _x_stream_info_set( this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = this->video_step) ); _x_meta_info_set_utf8( this->stream, XINE_META_INFO_VIDEOCODEC, "H264/AVC (vdpau)" ); xine_event_t event; xine_format_change_data_t data; event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = this->stream; event.data = &data; event.data_length = sizeof(data); data.width = this->width; data.height = this->height; data.aspect = this->ratio; xine_event_send( this->stream, &event ); switch(this->completed_pic->sps_nal->sps.profile_idc) { case 100: this->profile = VDP_DECODER_PROFILE_H264_HIGH; break; case 77: this->profile = VDP_DECODER_PROFILE_H264_MAIN; break; case 66: default: // nvidia's VDPAU doesn't support BASELINE. But most (every?) streams marked BASELINE do not use BASELINE specifics, // so, just force MAIN. //this->profile = VDP_DECODER_PROFILE_H264_BASELINE; this->profile = VDP_DECODER_PROFILE_H264_MAIN; break; } // Level 4.1 limits: int ref_frames = 0; if(this->completed_pic->sps_nal->sps.num_ref_frames) { ref_frames = this->completed_pic->sps_nal->sps.num_ref_frames; } else { uint32_t round_width = (this->width + 15) & ~15; uint32_t round_height = (this->height + 15) & ~15; uint32_t surf_size = (round_width * round_height * 3) / 2; ref_frames = (12 * 1024 * 1024) / surf_size; } if (ref_frames > 16) { ref_frames = 16; } xprintf(this->xine, XINE_VERBOSITY_LOG, "Allocate %d reference frames\n", ref_frames); /* get the vdpau context from vo */ //(this->stream->video_out->open) (this->stream->video_out, this->stream); img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | this->reset); this->reset = 0; this->vdpau_accel = (vdpau_accel_t*)img->accel_data; img->free(img); img = NULL; /*VdpBool is_supported; uint32_t max_level, max_references, max_width, max_height;*/ if(this->vdpau_accel->vdp_runtime_nr > 0) { xprintf(this->xine, XINE_VERBOSITY_LOG, "Create decoder: vdp_device: %d, profile: %d, res: %dx%d\n", this->vdpau_accel->vdp_device, this->profile, this->width, this->height); VdpStatus status; if (this->vdpau_accel->lock) this->vdpau_accel->lock (this->vdpau_accel->vo_frame); status = this->vdpau_accel->vdp_decoder_create(this->vdpau_accel->vdp_device, this->profile, this->width, this->height, 16, &this->decoder); if (this->vdpau_accel->unlock) this->vdpau_accel->unlock (this->vdpau_accel->vo_frame); if(status != VDP_STATUS_OK) { xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: ERROR: VdpDecoderCreate returned status != OK (%s)\n", this->vdpau_accel->vdp_get_error_string(status)); return 0; } } return 1; } static void draw_frames(video_decoder_t *this_gen, int flush) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *)this_gen; struct decoded_picture *decoded_pic = NULL; while ((decoded_pic = dpb_get_next_out_picture(this->nal_parser->dpb, flush)) != NULL) { decoded_pic->img->top_field_first = dp_top_field_first(decoded_pic); decoded_pic->img->progressive_frame = check_progressive(this_gen, decoded_pic); #ifdef DEBUG_H264 printf("progressive: %d\n", decoded_pic->img->progressive_frame); #endif if (flush) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "h264 flush, draw pts: %"PRId64"\n", decoded_pic->img->pts); } decoded_pic->img->draw(decoded_pic->img, this->stream); dpb_unmark_picture_delayed(this->nal_parser->dpb, decoded_pic); decoded_pic = NULL; } } static int vdpau_decoder_render(video_decoder_t *this_gen, VdpBitstreamBuffer *vdp_buffer, uint32_t slice_count) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *)this_gen; vo_frame_t *img = NULL; /* if we wait for a second field for this frame, we * have to render to the same surface again. */ if (this->incomplete_pic) { img = this->incomplete_pic->img; } // FIXME: what is if this is the second field of a field coded // picture? - should we keep the first field in dpb? if(this->completed_pic->flag_mask & IDR_PIC) { dpb_flush(this->nal_parser->dpb); if(this->incomplete_pic) { release_decoded_picture(this->incomplete_pic); this->incomplete_pic = NULL; } } struct seq_parameter_set_rbsp *sps = &this->completed_pic->sps_nal->sps; struct slice_header *slc = &this->completed_pic->slc_nal->slc; if ((this->video_step == 0) && sps->vui_parameters_present_flag && sps->vui_parameters.timing_info_present_flag && sps->vui_parameters.time_scale) { /* good: 2 * 1001 / 48000. */ this->video_step = (uint64_t)90000 * 2 * sps->vui_parameters.num_units_in_tick / sps->vui_parameters.time_scale; if (this->video_step < 90) { /* bad: 2 * 1 / 60000. seen this once from broken h.264 video usability info (VUI). * VAAPI seems to apply a similar HACK.*/ this->video_step = (uint64_t)90000000 * 2 * sps->vui_parameters.num_units_in_tick / sps->vui_parameters.time_scale; } } /* go and decode a frame */ /* check if we expect a second field, but got a frame */ if (this->incomplete_pic && img) { if ((this->completed_pic->slc_nal->slc.frame_num != this->incomplete_pic->coded_pic[0]->slc_nal->slc.frame_num) || !slc->field_pic_flag) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "H264 warning: Expected a second field, stream might be broken\n"); /* remove this pic from dpb, as it is not complete */ dpb_unmark_picture_delayed(this->nal_parser->dpb, this->incomplete_pic); dpb_unmark_reference_picture(this->nal_parser->dpb, this->incomplete_pic); release_decoded_picture(this->incomplete_pic); this->incomplete_pic = NULL; img = NULL; } } VdpPictureInfoH264 pic; fill_vdpau_pictureinfo_h264(this_gen, slice_count, &pic); #ifdef DEBUG_H264 dump_pictureinfo_h264(&pic); int i; printf("E: Bytes used: %d\n", vdp_buffer->bitstream_bytes); printf("E: Decode data: \nE:"); for(i = 0; i < ((vdp_buffer->bitstream_bytes < 20) ? vdp_buffer->bitstream_bytes : 20); i++) { printf("%02x ", ((uint8_t*)vdp_buffer->bitstream)[i]); if((i+1) % 10 == 0) printf("\nE:"); } printf("\n...\n"); for(i = vdp_buffer->bitstream_bytes - 20; i < vdp_buffer->bitstream_bytes; i++) { printf("%02x ", ((uint8_t*)vdp_buffer->bitstream)[i]); if((i+1) % 10 == 0) printf("\nE:"); } printf("\nE: ---------------------------------------------------------------\n"); #endif if(!this->decoder_started && !pic.is_reference) return 0; this->decoder_started = 1; if(img == NULL) { int frame_flags = VO_BOTH_FIELDS; int color_matrix = 4; /* undefined, mpeg range */ if (sps->vui_parameters.video_signal_type_present_flag) { if (sps->vui_parameters.colour_description_present) color_matrix = sps->vui_parameters.matrix_coefficients << 1; color_matrix |= sps->vui_parameters.video_full_range_flag; } VO_SET_FLAGS_CM (color_matrix, frame_flags); img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_VDPAU, frame_flags); this->vdpau_accel = (vdpau_accel_t*)img->accel_data; img->duration = this->video_step; img->pts = this->completed_pic->pts; if (this->dangling_img) { xprintf(this->xine, XINE_VERBOSITY_LOG, "broken stream: current img wasn't processed -- freeing it!\n"); this->dangling_img->free(this->dangling_img); } this->dangling_img = img; } else { if (img->pts == 0) { img->pts = this->completed_pic->pts; } } if(this->vdp_runtime_nr != *(this->vdpau_accel->current_vdp_runtime_nr)) { xprintf(this->xine, XINE_VERBOSITY_LOG, "VDPAU was preempted. Reinitialise the decoder.\n"); this->decoder = VDP_INVALID_HANDLE; vdpau_h264_reset(this_gen); this->vdp_runtime_nr = this->vdpau_accel->vdp_runtime_nr; return 0; } VdpVideoSurface surface = this->vdpau_accel->surface; /*xprintf(this->xine, XINE_VERBOSITY_DEBUG, "Decode: NUM: %d, REF: %d, BYTES: %d, PTS: %lld\n", pic.frame_num, pic.is_reference, vdp_buffer->bitstream_bytes, this->completed_pic->pts);*/ if (this->vdpau_accel->lock) this->vdpau_accel->lock (this->vdpau_accel->vo_frame); VdpStatus status = this->vdpau_accel->vdp_decoder_render(this->decoder, surface, CAST_VdpPictureInfo_PTR &pic, 1, vdp_buffer); if (this->vdpau_accel->unlock) this->vdpau_accel->unlock (this->vdpau_accel->vo_frame); /* free the image data */ if(((uint8_t*)vdp_buffer->bitstream) != NULL) { free((uint8_t*)vdp_buffer->bitstream); } process_mmc_operations(this->nal_parser, this->completed_pic); if(status != VDP_STATUS_OK) { xprintf(this->xine, XINE_VERBOSITY_LOG, "vdpau_h264: Decoder failure: %s\n", this->vdpau_accel->vdp_get_error_string(status)); if (this->dangling_img) this->dangling_img->free(this->dangling_img); img = NULL; this->dangling_img = NULL; free_coded_picture(this->completed_pic); this->completed_pic = NULL; } else { img->bad_frame = 0; if(!img->progressive_frame && this->completed_pic->repeat_pic) img->repeat_first_field = 1; //else if(img->progressive_frame && this->nal_parser->current_nal->repeat_pic) // img->duration *= this->nal_parser->current_nal->repeat_pic; struct decoded_picture *decoded_pic = NULL; uint8_t draw_frame = 0; if (!slc->field_pic_flag) { /* frame coded: simply add to dpb */ decoded_pic = init_decoded_picture(this->completed_pic, img); this->completed_pic = NULL; this->dangling_img = NULL; dpb_add_picture(this->nal_parser->dpb, decoded_pic, sps->num_ref_frames); draw_frame = 1; } else { /* field coded: check for second field */ if (!this->incomplete_pic) { decoded_pic = init_decoded_picture(this->completed_pic, img); this->completed_pic = NULL; this->dangling_img = NULL; this->incomplete_pic = decoded_pic; lock_decoded_picture(this->incomplete_pic); dpb_add_picture(this->nal_parser->dpb, decoded_pic, sps->num_ref_frames); /* don't do a draw yet as the field was incomplete */ draw_frame = 0; } else { decoded_pic = this->incomplete_pic; lock_decoded_picture(decoded_pic); /* picture is complete now */ release_decoded_picture(this->incomplete_pic); this->incomplete_pic = NULL; this->dangling_img = NULL; decoded_pic_add_field(decoded_pic, this->completed_pic); this->completed_pic = NULL; draw_frame = 1; } } release_decoded_picture(decoded_pic); /* draw the next frame in display order */ if (draw_frame) { draw_frames(this_gen, 0); } } return 1; } /* * This function receives a buffer of data from the demuxer layer and * figures out how to handle it based on its header flags. */ static void vdpau_h264_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *) this_gen; VdpBitstreamBuffer vdp_buffer; vdp_buffer.struct_version = VDP_BITSTREAM_BUFFER_VERSION; /* a video decoder does not care about this flag (?) */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if(buf->decoder_flags & BUF_FLAG_FRAME_START || buf->decoder_flags & BUF_FLAG_FRAME_END) this->have_frame_boundary_marks = 1; if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { this->video_step = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->video_step); } if (this->video_step != this->reported_video_step){ _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, (this->reported_video_step = this->video_step)); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { /* need to initialize */ this->have_frame_boundary_marks = 0; xine_bmiheader *bih = (xine_bmiheader*)buf->content; this->width = bih->biWidth; this->height = bih->biHeight; uint8_t *codec_private = buf->content + sizeof(xine_bmiheader); uint32_t codec_private_len = bih->biSize - sizeof(xine_bmiheader); this->codec_private_len = codec_private_len; this->codec_private = malloc(codec_private_len); memcpy(this->codec_private, codec_private, codec_private_len); if(codec_private_len > 0) { parse_codec_private(this->nal_parser, codec_private, codec_private_len); } } else if (buf->decoder_flags & BUF_FLAG_SPECIAL) { this->have_frame_boundary_marks = 0; if(buf->decoder_info[1] == BUF_SPECIAL_DECODER_CONFIG) { const uint8_t *codec_private = buf->decoder_info_ptr[2]; uint32_t codec_private_len = buf->decoder_info[2]; this->codec_private_len = codec_private_len; this->codec_private = malloc(codec_private_len); memcpy(this->codec_private, codec_private, codec_private_len); if(codec_private_len > 0) { parse_codec_private(this->nal_parser, codec_private, codec_private_len); } } else if (buf->decoder_info[1] == BUF_SPECIAL_PALETTE) { xprintf(this->xine, XINE_VERBOSITY_LOG, "SPECIAL PALETTE is not yet handled\n"); } else xprintf(this->xine, XINE_VERBOSITY_LOG, "UNKNOWN SPECIAL HEADER\n"); } else { /* parse the first nal packages to retrieve profile type */ int len = 0; while(len < buf->size && !(this->wait_for_frame_start && !(buf->decoder_flags & BUF_FLAG_FRAME_START))) { this->wait_for_frame_start = 0; len += parse_frame(this->nal_parser, buf->content + len, buf->size - len, buf->pts, &vdp_buffer.bitstream, &vdp_buffer.bitstream_bytes, &this->completed_pic); if(this->decoder == VDP_INVALID_HANDLE && this->completed_pic && this->completed_pic->sps_nal != NULL && this->completed_pic->sps_nal->sps.pic_width > 0 && this->completed_pic->sps_nal->sps.pic_height > 0) { vdpau_decoder_init(this_gen); } if(this->completed_pic && this->completed_pic->sps_nal != NULL && this->completed_pic->sps_nal->sps.vui_parameters_present_flag && this->completed_pic->sps_nal->sps.vui_parameters.bitstream_restriction_flag) { this->nal_parser->dpb->max_reorder_frames = this->completed_pic->sps_nal->sps.vui_parameters.num_reorder_frames + 1; this->nal_parser->dpb->max_dpb_frames = this->completed_pic->sps_nal->sps.vui_parameters.max_dec_frame_buffering + 1; xprintf(this->xine, XINE_VERBOSITY_DEBUG, "max reorder count: %d, max dpb count %d\n", this->nal_parser->dpb->max_reorder_frames, this->nal_parser->dpb->max_dpb_frames); } if(this->decoder != VDP_INVALID_HANDLE && vdp_buffer.bitstream_bytes > 0 && this->completed_pic->slc_nal != NULL && this->completed_pic->pps_nal != NULL) { vdpau_decoder_render(this_gen, &vdp_buffer, this->completed_pic->slice_cnt); } else if (this->completed_pic != NULL) { free_coded_picture(this->completed_pic); } /* in case the last nal was detected as END_OF_SEQUENCE * we will flush the dpb, so that all pictures get drawn */ if(this->nal_parser->last_nal_res == 3) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, "END_OF_SEQUENCE, flush buffers\n"); vdpau_h264_flush(this_gen); } } } if(buf->decoder_flags & BUF_FLAG_FRAME_END) this->wait_for_frame_start = 0; } /* * This function is called when xine needs to flush the system. */ static void vdpau_h264_flush (video_decoder_t *this_gen) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t*) this_gen; //struct decoded_picture *decoded_pic = NULL; if(this->dangling_img){ this->dangling_img->free(this->dangling_img); this->dangling_img = NULL; } if (this->incomplete_pic) { release_decoded_picture(this->incomplete_pic); this->incomplete_pic = NULL; } draw_frames(this_gen, 1); dpb_free_all(this->nal_parser->dpb); this->reset = VO_NEW_SEQUENCE_FLAG; } /* * This function resets the video decoder. */ static void vdpau_h264_reset (video_decoder_t *this_gen) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *) this_gen; dpb_free_all(this->nal_parser->dpb); if (this->decoder != VDP_INVALID_HANDLE) { if (this->vdpau_accel->lock) this->vdpau_accel->lock (this->vdpau_accel->vo_frame); this->vdpau_accel->vdp_decoder_destroy( this->decoder ); this->decoder = VDP_INVALID_HANDLE; if (this->vdpau_accel->unlock) this->vdpau_accel->unlock (this->vdpau_accel->vo_frame); } // Doing a full parser reinit here works more reliable than // resetting //reset_parser(this->nal_parser); free_parser(this->nal_parser); this->nal_parser = init_parser(this->xine); this->video_step = 0; if(this->codec_private_len > 0) { parse_codec_private(this->nal_parser, this->codec_private, this->codec_private_len); /* if the stream does not contain frame boundary marks we * have to hope that the next nal will start with the next * incoming buf... seems to work, though... */ this->wait_for_frame_start = this->have_frame_boundary_marks; } if (this->incomplete_pic) { release_decoded_picture(this->incomplete_pic); this->incomplete_pic = NULL; } if (this->dangling_img) { this->dangling_img->free(this->dangling_img); this->dangling_img = NULL; } this->progressive_cnt = 0; this->reset = VO_NEW_SEQUENCE_FLAG; } /* * The decoder should forget any stored pts values here. */ static void vdpau_h264_discontinuity (video_decoder_t *this_gen) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *) this_gen; dpb_clear_all_pts(this->nal_parser->dpb); this->reset = VO_NEW_SEQUENCE_FLAG; } /* * This function frees the video decoder instance allocated to the decoder. */ static void vdpau_h264_dispose (video_decoder_t *this_gen) { vdpau_h264_decoder_t *this = (vdpau_h264_decoder_t *) this_gen; if (this->incomplete_pic) { release_decoded_picture(this->incomplete_pic); this->incomplete_pic = NULL; } if (this->dangling_img) { this->dangling_img->free(this->dangling_img); this->dangling_img = NULL; } dpb_free_all(this->nal_parser->dpb); if (this->decoder != VDP_INVALID_HANDLE) { if (this->vdpau_accel->lock) this->vdpau_accel->lock (this->vdpau_accel->vo_frame); this->vdpau_accel->vdp_decoder_destroy( this->decoder ); this->decoder = VDP_INVALID_HANDLE; if (this->vdpau_accel->unlock) this->vdpau_accel->unlock (this->vdpau_accel->vo_frame); } this->stream->video_out->close( this->stream->video_out, this->stream ); free_parser (this->nal_parser); free (this_gen); } /* * This function allocates, initializes, and returns a private video * decoder structure. */ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { vdpau_h264_decoder_t *this ; (void)class_gen; /* the videoout must be vdpau-capable to support this decoder */ if ( !(stream->video_out->get_capabilities(stream->video_out) & VO_CAP_VDPAU_H264) ) return NULL; /* now check if vdpau has free decoder resource */ vo_frame_t *img = stream->video_out->get_frame( stream->video_out, 1920, 1080, 1, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL ); if (!img) { return NULL; } vdpau_accel_t *accel = (vdpau_accel_t*)img->accel_data; int runtime_nr = accel->vdp_runtime_nr; img->free(img); VdpDecoder decoder; if (accel->lock) accel->lock (accel->vo_frame); VdpStatus st = accel->vdp_decoder_create( accel->vdp_device, VDP_DECODER_PROFILE_H264_MAIN, 1920, 1080, 16, &decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) { lprintf( "can't create vdpau decoder.\n" ); return NULL; } if (accel->lock) accel->lock (accel->vo_frame); accel->vdp_decoder_destroy( decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); this = (vdpau_h264_decoder_t *) calloc(1, sizeof(vdpau_h264_decoder_t)); if (!this) return NULL; this->nal_parser = init_parser(stream->xine); if (!this->nal_parser) { free(this); return NULL; } this->video_decoder.decode_data = vdpau_h264_decode_data; this->video_decoder.flush = vdpau_h264_flush; this->video_decoder.reset = vdpau_h264_reset; this->video_decoder.discontinuity = vdpau_h264_discontinuity; this->video_decoder.dispose = vdpau_h264_dispose; this->stream = stream; this->xine = stream->xine; this->decoder = VDP_INVALID_HANDLE; this->vdp_runtime_nr = runtime_nr; this->progressive_cnt = 0; this->reset = VO_NEW_SEQUENCE_FLAG; (this->stream->video_out->open) (this->stream->video_out, this->stream); return &this->video_decoder; } /* * This function allocates a private video decoder class and initializes * the class's member functions. */ void *h264_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_vdpau_h264_class = { .open_plugin = open_plugin, .identifier = "vdpau_h264", .description = N_("H264 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau."), .dispose = NULL, }; return (void *)&decode_video_vdpau_h264_class; } ���������������������xine-lib-1.2/src/video_dec/libvdpau/group_vdpau.c���������������������������������������������������0000644�0001750�0001750�00000006344�14647725152�017710� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2008-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * A group of video stream parsers using the VDPAU hardware decoder. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "group_vdpau.h" /* * This is a list of all of the internal xine video buffer types that * a decoder is able to handle. Check src/xine-engine/buffer.h for a * list of valid buffer types (and add a new one if the one you need does * not exist). Terminate the list with a 0. */ static const uint32_t video_types_h264[] = { BUF_VIDEO_H264, 0 }; static const uint32_t video_types_vc1[] = { BUF_VIDEO_VC1, BUF_VIDEO_WMV9, 0 }; static const uint32_t video_types_mpeg12[] = { BUF_VIDEO_MPEG, 0 }; static const uint32_t video_types_mpeg4[] = { BUF_VIDEO_MPEG4, BUF_VIDEO_XVID, BUF_VIDEO_DIVX5, BUF_VIDEO_3IVX, 0 }; /* * This data structure combines the list of supported xine buffer types and * the priority that the plugin should be given with respect to other * plugins that handle the same buffer type. A plugin with priority (n+1) * will be used instead of a plugin with priority (n). */ static const decoder_info_t dec_info_video_alterh264 = { .supported_types = video_types_h264, .priority = 9 }; static const decoder_info_t dec_info_video_h264 = { .supported_types = video_types_h264, .priority = 7 }; static const decoder_info_t dec_info_video_vc1 = { .supported_types = video_types_vc1, .priority = 8 }; static const decoder_info_t dec_info_video_mpeg12 = { .supported_types = video_types_mpeg12, .priority = 8 }; static const decoder_info_t dec_info_video_mpeg4 = { .supported_types = video_types_mpeg4, .priority = 8 }; /* * The plugin catalog entry. This is the only information that a plugin * will export to the public. */ const plugin_info_t xine_plugin_info[] EXPORTED = { /* { type, API, "name", version, special_info, init_function } */ { PLUGIN_VIDEO_DECODER, 19, "vdpau_h264_alter", XINE_VERSION_CODE, &dec_info_video_alterh264, h264_alter_init_plugin }, { PLUGIN_VIDEO_DECODER, 19, "vdpau_h264", XINE_VERSION_CODE, &dec_info_video_h264, h264_init_plugin }, { PLUGIN_VIDEO_DECODER, 19, "vdpau_vc1", XINE_VERSION_CODE, &dec_info_video_vc1, vc1_init_plugin }, { PLUGIN_VIDEO_DECODER, 19, "vdpau_mpeg12", XINE_VERSION_CODE, &dec_info_video_mpeg12, mpeg12_init_plugin }, { PLUGIN_VIDEO_DECODER, 19, "vdpau_mpeg4", XINE_VERSION_CODE, &dec_info_video_mpeg4, mpeg4_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvdpau/vdpau_mpeg12.c��������������������������������������������������0000644�0001750�0001750�00000114426�14647725152�017650� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * kate: space-indent on; indent-width 2; mixedindent off; indent-mode cstyle; remove-trailing-space on; * Copyright (C) 2008-2023 the xine project * Copyright (C) 2008 Christophe Thommeret <hftom@free.fr> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * vdpau_mpeg12.c, a mpeg1/2 video stream parser using VDPAU hardware decoder * */ /*#define LOG*/ #define LOG_MODULE "vdpau_mpeg12" #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "accel_vdpau.h" #include "bits_reader.h" #include "group_vdpau.h" #include <vdpau/vdpau.h> #define sequence_header_code 0xb3 #define sequence_error_code 0xb4 #define sequence_end_code 0xb7 #define group_start_code 0xb8 #define extension_start_code 0xb5 #define user_data_start_code 0xb2 #define picture_start_code 0x00 #define begin_slice_start_code 0x01 #define end_slice_start_code 0xaf #define sequence_ext_sc 1 #define quant_matrix_ext_sc 3 #define picture_coding_ext_sc 8 #define sequence_display_ext_sc 2 #define I_FRAME 1 #define P_FRAME 2 #define B_FRAME 3 #define PICTURE_TOP 1 #define PICTURE_BOTTOM 2 #define PICTURE_FRAME 3 /*#define MAKE_DAT*/ /*do NOT define this, unless you know what you do */ #ifdef MAKE_DAT static int nframes; static FILE *outfile; #endif /* default intra quant matrix, in zig-zag order */ static const uint8_t default_intra_quantizer_matrix[64] = { 8, 16, 16, 19, 16, 19, 22, 22, 22, 22, 22, 22, 26, 24, 26, 27, 27, 27, 26, 26, 26, 26, 27, 27, 27, 29, 29, 29, 34, 34, 34, 29, 29, 29, 27, 27, 29, 29, 32, 32, 34, 34, 37, 38, 37, 35, 35, 34, 35, 38, 38, 40, 40, 40, 48, 48, 46, 46, 56, 56, 58, 69, 69, 83 }; uint8_t mpeg2_scan_norm[64] = { /* Zig-Zag scan pattern */ 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 }; typedef struct { VdpPictureInfoMPEG1Or2 vdp_infos; /* first field, also used for frame */ VdpPictureInfoMPEG1Or2 vdp_infos2; /* second field */ int slices_count, slices_count2; uint8_t *slices; int slices_size; int slices_pos, slices_pos_top; int progressive_frame; int repeat_first_field; } picture_t; typedef struct { uint32_t coded_width; uint32_t coded_height; double video_step; /* frame duration in pts units */ double reported_video_step; /* frame duration in pts units */ double ratio; VdpDecoderProfile profile; int horizontal_size_value; int vertical_size_value; int aspect_ratio_information; int frame_rate_code; int progressive_sequence; int chroma; int horizontal_size_extension; int vertical_size_extension; int frame_rate_extension_n; int frame_rate_extension_d; int display_horizontal_size; int display_vertical_size; int top_field_first; int have_header; int have_display_extension; uint8_t *buf; /* accumulate data */ int bufseek; uint32_t bufsize; uint32_t bufpos; int start; picture_t picture; vo_frame_t *forward_ref; vo_frame_t *backward_ref; int64_t cur_pts, seq_pts; vdpau_accel_t *accel_vdpau; bits_reader_t br; int vdp_runtime_nr; int reset; } sequence_t; typedef struct vdpau_mpeg12_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; sequence_t sequence; VdpDecoder decoder; VdpDecoderProfile decoder_profile; uint32_t decoder_width; uint32_t decoder_height; } vdpau_mpeg12_decoder_t; static void picture_ready( vdpau_mpeg12_decoder_t *vd, uint8_t end_of_sequence ); static void reset_picture( picture_t *pic ) { lprintf( "reset_picture\n" ); pic->vdp_infos.picture_structure = pic->vdp_infos2.picture_structure = 0; pic->vdp_infos2.intra_dc_precision = pic->vdp_infos.intra_dc_precision = 0; pic->vdp_infos2.frame_pred_frame_dct = pic->vdp_infos.frame_pred_frame_dct = 1; pic->vdp_infos2.concealment_motion_vectors = pic->vdp_infos.concealment_motion_vectors = 0; pic->vdp_infos2.intra_vlc_format = pic->vdp_infos.intra_vlc_format = 0; pic->vdp_infos2.alternate_scan = pic->vdp_infos.alternate_scan = 0; pic->vdp_infos2.q_scale_type = pic->vdp_infos.q_scale_type = 0; pic->vdp_infos2.top_field_first = pic->vdp_infos.top_field_first = 1; pic->slices_count = 0; pic->slices_count2 = 0; pic->slices_pos = 0; pic->slices_pos_top = 0; pic->progressive_frame = 0; pic->repeat_first_field = 0; } static void init_picture( picture_t *pic ) { pic->slices_size = 2048; pic->slices = (uint8_t*)malloc(pic->slices_size); reset_picture( pic ); } static void reset_sequence( sequence_t *sequence, int free_refs ) { sequence->cur_pts = sequence->seq_pts = 0; if ( sequence->forward_ref ) sequence->forward_ref->pts = 0; if ( sequence->backward_ref ) sequence->backward_ref->pts = 0; if ( !free_refs ) return; sequence->bufpos = 0; sequence->bufseek = 0; sequence->start = -1; if ( sequence->forward_ref ) sequence->forward_ref->free( sequence->forward_ref ); sequence->forward_ref = NULL; if ( sequence->backward_ref ) sequence->backward_ref->free( sequence->backward_ref ); sequence->backward_ref = NULL; sequence->top_field_first = 0; sequence->reset = VO_NEW_SEQUENCE_FLAG; } static void free_sequence( sequence_t *sequence ) { lprintf( "init_sequence\n" ); sequence->have_header = 0; sequence->profile = VDP_DECODER_PROFILE_MPEG1; sequence->chroma = 0; sequence->video_step = 3600; reset_sequence( sequence, 1 ); } static void sequence_header( vdpau_mpeg12_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; int i, j; if ( !sequence->have_header ) sequence->have_header = 1; sequence->profile = VDP_DECODER_PROFILE_MPEG1; sequence->horizontal_size_extension = 0; sequence->vertical_size_extension = 0; sequence->have_display_extension = 0; bits_reader_set( &sequence->br, buf, len ); sequence->horizontal_size_value = read_bits( &sequence->br, 12 ); lprintf( "horizontal_size_value: %d\n", sequence->horizontal_size_value ); sequence->vertical_size_value = read_bits( &sequence->br, 12 ); lprintf( "vertical_size_value: %d\n", sequence->vertical_size_value ); sequence->aspect_ratio_information = read_bits( &sequence->br, 4 ); lprintf( "aspect_ratio_information: %d\n", sequence->aspect_ratio_information ); sequence->frame_rate_code = read_bits( &sequence->br, 4 ); lprintf( "frame_rate_code: %d\n", sequence->frame_rate_code ); #ifdef LOG int tmp; tmp = read_bits( &sequence->br, 18 ); lprintf( "bit_rate_value: %d\n", tmp ); tmp = read_bits( &sequence->br, 1 ); lprintf( "marker_bit: %d\n", tmp ); tmp = read_bits( &sequence->br, 10 ); lprintf( "vbv_buffer_size_value: %d\n", tmp ); tmp = read_bits( &sequence->br, 1 ); lprintf( "constrained_parameters_flag: %d\n", tmp ); #else skip_bits(&sequence->br, 30); #endif i = read_bits( &sequence->br, 1 ); lprintf( "load_intra_quantizer_matrix: %d\n", i ); if ( i ) { for ( j=0; j<64; ++j ) { sequence->picture.vdp_infos2.intra_quantizer_matrix[mpeg2_scan_norm[j]] = sequence->picture.vdp_infos.intra_quantizer_matrix[mpeg2_scan_norm[j]] = read_bits( &sequence->br, 8 ); } } else { for ( j=0; j<64; ++j ) { sequence->picture.vdp_infos2.intra_quantizer_matrix[mpeg2_scan_norm[j]] = sequence->picture.vdp_infos.intra_quantizer_matrix[mpeg2_scan_norm[j]] = default_intra_quantizer_matrix[j]; } } i = read_bits( &sequence->br, 1 ); lprintf( "load_non_intra_quantizer_matrix: %d\n", i ); if ( i ) { for ( j=0; j<64; ++j ) { sequence->picture.vdp_infos2.non_intra_quantizer_matrix[mpeg2_scan_norm[j]] = sequence->picture.vdp_infos.non_intra_quantizer_matrix[mpeg2_scan_norm[j]] = read_bits( &sequence->br, 8 ); } } else { memset( sequence->picture.vdp_infos.non_intra_quantizer_matrix, 16, 64 ); memset( sequence->picture.vdp_infos2.non_intra_quantizer_matrix, 16, 64 ); } } static void process_sequence_mpeg12_dependent_data( vdpau_mpeg12_decoder_t *this_gen ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; int frame_rate_value_n, frame_rate_value_d; sequence->coded_width = sequence->horizontal_size_value | (sequence->horizontal_size_extension << 14); sequence->coded_height = sequence->vertical_size_value | (sequence->vertical_size_extension << 14); switch ( sequence->frame_rate_code ) { case 1: frame_rate_value_n = 24; frame_rate_value_d = 1001; break; /* 23.976.. */ case 2: frame_rate_value_n = 24; frame_rate_value_d = 1000; break; /* 24 */ case 3: frame_rate_value_n = 25; frame_rate_value_d = 1000; break; /* 25 */ case 4: frame_rate_value_n = 30; frame_rate_value_d = 1001; break; /* 29.97.. */ case 5: frame_rate_value_n = 30; frame_rate_value_d = 1000; break; /* 30 */ case 6: frame_rate_value_n = 50; frame_rate_value_d = 1000; break; /* 50 */ case 7: frame_rate_value_n = 60; frame_rate_value_d = 1001; break; /* 59.94.. */ case 8: frame_rate_value_n = 60; frame_rate_value_d = 1000; break; /* 60 */ default: frame_rate_value_n = 50; frame_rate_value_d = 1000; /* assume 50 */ } sequence->video_step = 90.0 * (frame_rate_value_d * (sequence->frame_rate_extension_d + 1)) / (frame_rate_value_n * (sequence->frame_rate_extension_n + 1)); if ( sequence->profile==VDP_DECODER_PROFILE_MPEG1 ) { double pel_aspect_ratio; /* height / width */ switch ( sequence->aspect_ratio_information ) { case 1: pel_aspect_ratio = 1.0000; break; case 2: pel_aspect_ratio = 0.6735; break; case 3: pel_aspect_ratio = 0.7031; break; case 4: pel_aspect_ratio = 0.7615; break; case 5: pel_aspect_ratio = 0.8055; break; case 6: pel_aspect_ratio = 0.8437; break; case 7: pel_aspect_ratio = 0.8935; break; case 8: pel_aspect_ratio = 0.9157; break; case 9: pel_aspect_ratio = 0.9815; break; case 10: pel_aspect_ratio = 1.0255; break; case 11: pel_aspect_ratio = 1.0695; break; case 12: pel_aspect_ratio = 1.0950; break; case 13: pel_aspect_ratio = 1.1575; break; case 14: pel_aspect_ratio = 1.2015; break; default: pel_aspect_ratio = 1.0000; /* fallback */ break; } sequence->ratio = ((double)sequence->coded_width/(double)sequence->coded_height)/pel_aspect_ratio; } else { switch ( sequence->aspect_ratio_information ) { case 1: sequence->ratio = sequence->have_display_extension ? ((double)sequence->display_horizontal_size/(double)sequence->display_vertical_size)/1.0 : ((double)sequence->coded_width/(double)sequence->coded_height)/1.0; break; case 2: sequence->ratio = 4.0/3.0; break; case 3: sequence->ratio = 16.0/9.0; break; case 4: sequence->ratio = 2.21; break; default: sequence->ratio = ((double)sequence->coded_width/(double)sequence->coded_height)/1.0; } } if ( sequence->have_header == 1 ) { sequence->have_header = 2; _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_WIDTH, sequence->coded_width ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, sequence->coded_height ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_VIDEO_RATIO, ((double)10000*sequence->ratio) ); _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_FRAME_DURATION, (sequence->reported_video_step = sequence->video_step) ); _x_meta_info_set_utf8( this_gen->stream, XINE_META_INFO_VIDEOCODEC, "MPEG1/2 (vdpau)" ); xine_event_t event; xine_format_change_data_t data; event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = this_gen->stream; event.data = &data; event.data_length = sizeof(data); data.width = sequence->coded_width; data.height = sequence->coded_height; data.aspect = sequence->ratio; xine_event_send( this_gen->stream, &event ); } else if ( sequence->have_header == 2 && sequence->reported_video_step != sequence->video_step ) { _x_stream_info_set( this_gen->stream, XINE_STREAM_INFO_FRAME_DURATION, (sequence->reported_video_step = sequence->video_step) ); } } static void picture_header( vdpau_mpeg12_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; process_sequence_mpeg12_dependent_data(this_gen); if ( sequence->profile==VDP_DECODER_PROFILE_MPEG1 ) sequence->picture.vdp_infos.picture_structure = PICTURE_FRAME; VdpPictureInfoMPEG1Or2 *infos = &sequence->picture.vdp_infos; if ( sequence->picture.vdp_infos.picture_structure==PICTURE_FRAME ) { picture_ready( this_gen, 0 ); reset_picture( &sequence->picture ); } else if ( sequence->picture.vdp_infos.picture_structure && sequence->picture.vdp_infos2.picture_structure ) { picture_ready( this_gen, 0 ); reset_picture( &sequence->picture ); } else if ( sequence->picture.vdp_infos.picture_structure ) { infos = &sequence->picture.vdp_infos2; sequence->picture.slices_pos_top = sequence->picture.slices_pos; sequence->cur_pts = 0; /* ignore pts of second field */ } /* take over pts for next issued image */ if ( sequence->cur_pts ) { sequence->seq_pts = sequence->cur_pts; sequence->cur_pts = 0; } bits_reader_set( &sequence->br, buf, len ); #ifdef LOG int tmp = read_bits( &sequence->br, 10 ); lprintf( "temporal_reference: %d\n", tmp ); #else skip_bits( &sequence->br, 10 ); #endif infos->picture_coding_type = read_bits( &sequence->br, 3 ); lprintf( "picture_coding_type: %d\n", infos->picture_coding_type ); infos->forward_reference = VDP_INVALID_HANDLE; infos->backward_reference = VDP_INVALID_HANDLE; skip_bits( &sequence->br, 16 ); if ( infos->picture_coding_type > I_FRAME ) { infos->full_pel_forward_vector = read_bits( &sequence->br, 1 ); infos->f_code[0][0] = infos->f_code[0][1] = read_bits( &sequence->br, 3 ); if ( infos->picture_coding_type==B_FRAME ) { infos->full_pel_backward_vector = read_bits( &sequence->br, 1 ); infos->f_code[1][0] = infos->f_code[1][1] = read_bits( &sequence->br, 3 ); } } else { infos->full_pel_forward_vector = 0; infos->full_pel_backward_vector = 0; } } static void sequence_extension( sequence_t *sequence, uint8_t *buf, int len ) { bits_reader_set( &sequence->br, buf, len ); #ifdef LOG int tmp = read_bits( &sequence->br, 4 ); lprintf( "extension_start_code_identifier: %d\n", tmp ); skip_bits( &sequence->br, 1 ); #else skip_bits( &sequence->br, 5 ); #endif switch ( read_bits( &sequence->br, 3 ) ) { case 5: sequence->profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE; break; default: sequence->profile = VDP_DECODER_PROFILE_MPEG2_MAIN; } skip_bits( &sequence->br, 4 ); sequence->progressive_sequence = read_bits( &sequence->br, 1 ); lprintf( "progressive_sequence: %d\n", sequence->progressive_sequence ); if ( read_bits( &sequence->br, 2 ) == 2 ) sequence->chroma = VO_CHROMA_422; #ifdef LOG tmp = read_bits( &sequence->br, 2 ); lprintf( "horizontal_size_extension: %d\n", tmp ); tmp = read_bits( &sequence->br, 2 ); lprintf( "vertical_size_extension: %d\n", tmp ); tmp = read_bits( &sequence->br, 12 ); lprintf( "bit_rate_extension: %d\n", tmp ); tmp = read_bits( &sequence->br, 1 ); lprintf( "marker_bit: %d\n", tmp ); tmp = read_bits( &sequence->br, 8 ); lprintf( "vbv_buffer_size_extension: %d\n", tmp ); tmp = read_bits( &sequence->br, 1 ); lprintf( "low_delay: %d\n", tmp ); #else skip_bits( &sequence->br, 26 ); #endif sequence->frame_rate_extension_n = read_bits( &sequence->br, 2 ); lprintf( "frame_rate_extension_n: %d\n", sequence->frame_rate_extension_n ); sequence->frame_rate_extension_d = read_bits( &sequence->br, 5 ); lprintf( "frame_rate_extension_d: %d\n", sequence->frame_rate_extension_d ); } static void picture_coding_extension( sequence_t *sequence, uint8_t *buf, int len ) { VdpPictureInfoMPEG1Or2 *infos = &sequence->picture.vdp_infos; if ( infos->picture_structure && infos->picture_structure!=PICTURE_FRAME ) infos = &sequence->picture.vdp_infos2; bits_reader_set( &sequence->br, buf, len ); #ifdef LOG int tmp = read_bits( &sequence->br, 4 ); lprintf( "extension_start_code_identifier: %d\n", tmp ); #else skip_bits( &sequence->br, 4 ); #endif infos->f_code[0][0] = read_bits( &sequence->br, 4 ); infos->f_code[0][1] = read_bits( &sequence->br, 4 ); infos->f_code[1][0] = read_bits( &sequence->br, 4 ); infos->f_code[1][1] = read_bits( &sequence->br, 4 ); lprintf( "f_code_0_0: %d\n", infos->f_code[0][0] ); lprintf( "f_code_0_1: %d\n", infos->f_code[0][1] ); lprintf( "f_code_1_0: %d\n", infos->f_code[1][0] ); lprintf( "f_code_1_1: %d\n", infos->f_code[1][1] ); infos->intra_dc_precision = read_bits( &sequence->br, 2 ); lprintf( "intra_dc_precision: %d\n", infos->intra_dc_precision ); infos->picture_structure = read_bits( &sequence->br, 2 ); lprintf( "picture_structure: %d\n", infos->picture_structure ); infos->top_field_first = read_bits( &sequence->br, 1 ); lprintf( "top_field_first: %d\n", infos->top_field_first ); infos->frame_pred_frame_dct = read_bits( &sequence->br, 1 ); lprintf( "frame_pred_frame_dct: %d\n", infos->frame_pred_frame_dct ); infos->concealment_motion_vectors = read_bits( &sequence->br, 1 ); lprintf( "concealment_motion_vectors: %d\n", infos->concealment_motion_vectors ); infos->q_scale_type = read_bits( &sequence->br, 1 ); lprintf( "q_scale_type: %d\n", infos->q_scale_type ); infos->intra_vlc_format = read_bits( &sequence->br, 1 ); lprintf( "intra_vlc_format: %d\n", infos->intra_vlc_format ); infos->alternate_scan = read_bits( &sequence->br, 1 ); lprintf( "alternate_scan: %d\n", infos->alternate_scan ); sequence->picture.repeat_first_field = read_bits( &sequence->br, 1 ); lprintf( "repeat_first_field: %d\n", sequence->picture.repeat_first_field ); #ifdef LOG tmp = read_bits( &sequence->br, 1 ); lprintf( "chroma_420_type: %d\n", tmp ); #else skip_bits( &sequence->br, 1 ); #endif sequence->picture.progressive_frame = read_bits( &sequence->br, 1 ); lprintf( "progressive_frame: %d\n", sequence->picture.progressive_frame ); } static void quant_matrix_extension( sequence_t *sequence, uint8_t *buf, int len ) { int i, j; bits_reader_set( &sequence->br, buf, len ); skip_bits( &sequence->br, 4 ); i = read_bits( &sequence->br, 1 ); lprintf( "load_intra_quantizer_matrix: %d\n", i ); if ( i ) { for ( j=0; j<64; ++j ) { sequence->picture.vdp_infos2.intra_quantizer_matrix[mpeg2_scan_norm[j]] = sequence->picture.vdp_infos.intra_quantizer_matrix[mpeg2_scan_norm[j]] = read_bits( &sequence->br, 8 ); } } else { for ( j=0; j<64; ++j ) { sequence->picture.vdp_infos2.intra_quantizer_matrix[mpeg2_scan_norm[j]] = sequence->picture.vdp_infos.intra_quantizer_matrix[mpeg2_scan_norm[j]] = default_intra_quantizer_matrix[j]; } } i = read_bits( &sequence->br, 1 ); lprintf( "load_non_intra_quantizer_matrix: %d\n", i ); if ( i ) { for ( j=0; j<64; ++j ) { sequence->picture.vdp_infos2.non_intra_quantizer_matrix[mpeg2_scan_norm[j]] = sequence->picture.vdp_infos.non_intra_quantizer_matrix[mpeg2_scan_norm[j]] = read_bits( &sequence->br, 8 ); } } else { memset( sequence->picture.vdp_infos.non_intra_quantizer_matrix, 16, 64 ); memset( sequence->picture.vdp_infos2.non_intra_quantizer_matrix, 16, 64 ); } } static void copy_slice( sequence_t *sequence, uint8_t *buf, int len ) { int size = sequence->picture.slices_pos+len; if ( sequence->picture.slices_size < size ) { sequence->picture.slices_size = size+1024; sequence->picture.slices = realloc( sequence->picture.slices, sequence->picture.slices_size ); } xine_fast_memcpy( sequence->picture.slices+sequence->picture.slices_pos, buf, len ); sequence->picture.slices_pos += len; if ( sequence->picture.slices_pos_top ) sequence->picture.slices_count2++; else sequence->picture.slices_count++; } static int parse_code( vdpau_mpeg12_decoder_t *this_gen, uint8_t *buf, int len ) { sequence_t *sequence = (sequence_t*)&this_gen->sequence; if ( !sequence->have_header && buf[3]!=sequence_header_code ) { lprintf( " ----------- no sequence header yet.\n" ); return 0; } if ( (buf[3] >= begin_slice_start_code) && (buf[3] <= end_slice_start_code) ) { lprintf( " ----------- slice_start_code\n" ); copy_slice( sequence, buf, len ); return 0; } switch ( buf[3] ) { case sequence_header_code: lprintf( " ----------- sequence_header_code\n" ); sequence_header( this_gen, buf+4, len-4 ); break; case extension_start_code: { switch ( buf[4]>>4 ) { case sequence_ext_sc: lprintf( " ----------- sequence_extension_start_code\n" ); sequence_extension( sequence, buf+4, len-4 ); break; case quant_matrix_ext_sc: lprintf( " ----------- quant_matrix_extension_start_code\n" ); quant_matrix_extension( sequence, buf+4, len-4 ); break; case picture_coding_ext_sc: lprintf( " ----------- picture_coding_extension_start_code\n" ); picture_coding_extension( sequence, buf+4, len-4 ); break; case sequence_display_ext_sc: lprintf( " ----------- sequence_display_extension_start_code\n" ); break; } break; } case user_data_start_code: lprintf( " ----------- user_data_start_code\n" ); break; case group_start_code: lprintf( " ----------- group_start_code\n" ); break; case picture_start_code: lprintf( " ----------- picture_start_code\n" ); picture_header( this_gen, buf+4, len-4 ); break; case sequence_error_code: lprintf( " ----------- sequence_error_code\n" ); break; case sequence_end_code: lprintf( " ----------- sequence_end_code\n" ); break; } return 0; } static void decode_render( vdpau_mpeg12_decoder_t *vd, vdpau_accel_t *accel ) { sequence_t *seq = (sequence_t*)&vd->sequence; picture_t *pic = (picture_t*)&seq->picture; pic->vdp_infos.slice_count = pic->slices_count; pic->vdp_infos2.slice_count = pic->slices_count2; VdpStatus st; if ( vd->decoder==VDP_INVALID_HANDLE || vd->decoder_profile!=seq->profile || vd->decoder_width!=seq->coded_width || vd->decoder_height!=seq->coded_height ) { if (accel->lock) accel->lock (accel->vo_frame); if ( vd->decoder!=VDP_INVALID_HANDLE ) { accel->vdp_decoder_destroy( vd->decoder ); vd->decoder = VDP_INVALID_HANDLE; } st = accel->vdp_decoder_create( accel->vdp_device, seq->profile, seq->coded_width, seq->coded_height, 2, &vd->decoder); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) lprintf( "failed to create decoder !! %s\n", accel->vdp_get_error_string( st ) ); else { vd->decoder_profile = seq->profile; vd->decoder_width = seq->coded_width; vd->decoder_height = seq->coded_height; seq->vdp_runtime_nr = accel->vdp_runtime_nr; } } VdpBitstreamBuffer vbit; vbit.struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit.bitstream = pic->slices; vbit.bitstream_bytes = (pic->vdp_infos.picture_structure==PICTURE_FRAME)? pic->slices_pos : pic->slices_pos_top; if (accel->lock) accel->lock (accel->vo_frame); st = accel->vdp_decoder_render( vd->decoder, accel->surface, CAST_VdpPictureInfo_PTR &pic->vdp_infos, 1, &vbit ); if (accel->unlock) accel->unlock (accel->vo_frame); #ifdef LOG if ( st!=VDP_STATUS_OK ) lprintf( "decoder failed : %d!! %s\n", st, accel->vdp_get_error_string( st ) ); else { lprintf( "DECODER SUCCESS : frame_type:%d, slices=%d, slices_bytes=%d, current=%d, forwref:%d, backref:%d, pts:%"PRId64"\n", pic->vdp_infos.picture_coding_type, pic->vdp_infos.slice_count, vbit.bitstream_bytes, accel->surface, pic->vdp_infos.forward_reference, pic->vdp_infos.backward_reference, seq->cur_pts ); VdpPictureInfoMPEG1Or2 *info = &pic->vdp_infos; lprintf("%d %d %d %d %d %d %d %d %d %d %d %d %d\n", info->intra_dc_precision, info->frame_pred_frame_dct, info->concealment_motion_vectors, info->intra_vlc_format, info->alternate_scan, info->q_scale_type, info->top_field_first, info->full_pel_forward_vector, info->full_pel_backward_vector, info->f_code[0][0], info->f_code[0][1], info->f_code[1][0], info->f_code[1][1] ); } #endif if ( pic->vdp_infos.picture_structure != PICTURE_FRAME ) { pic->vdp_infos2.backward_reference = VDP_INVALID_HANDLE; pic->vdp_infos2.forward_reference = VDP_INVALID_HANDLE; if ( pic->vdp_infos2.picture_coding_type==P_FRAME ) { if ( pic->vdp_infos.picture_coding_type==I_FRAME ) pic->vdp_infos2.forward_reference = accel->surface; else pic->vdp_infos2.forward_reference = pic->vdp_infos.forward_reference; } else if ( pic->vdp_infos.picture_coding_type==B_FRAME ) { pic->vdp_infos2.forward_reference = pic->vdp_infos.forward_reference; pic->vdp_infos2.backward_reference = pic->vdp_infos.backward_reference; } vbit.struct_version = VDP_BITSTREAM_BUFFER_VERSION; vbit.bitstream = pic->slices+pic->slices_pos_top; vbit.bitstream_bytes = pic->slices_pos-pic->slices_pos_top; if (accel->lock) accel->lock (accel->vo_frame); st = accel->vdp_decoder_render( vd->decoder, accel->surface, CAST_VdpPictureInfo_PTR &pic->vdp_infos2, 1, &vbit ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) lprintf( "decoder failed : %d!! %s\n", st, accel->vdp_get_error_string( st ) ); else lprintf( "DECODER SUCCESS : frame_type:%d, slices=%d, current=%d, forwref:%d, backref:%d, pts:%" PRId64 "\n", pic->vdp_infos2.picture_coding_type, pic->vdp_infos2.slice_count, accel->surface, pic->vdp_infos2.forward_reference, pic->vdp_infos2.backward_reference, seq->cur_pts ); } } static void decode_picture( vdpau_mpeg12_decoder_t *vd, uint8_t end_of_sequence ) { sequence_t *seq = (sequence_t*)&vd->sequence; picture_t *pic = (picture_t*)&seq->picture; vdpau_accel_t *ref_accel; if ( seq->profile == VDP_DECODER_PROFILE_MPEG1 ) pic->vdp_infos.picture_structure=PICTURE_FRAME; if ( pic->vdp_infos.picture_coding_type==P_FRAME ) { if ( seq->backward_ref ) { ref_accel = (vdpau_accel_t*)seq->backward_ref->accel_data; pic->vdp_infos.forward_reference = ref_accel->surface; } else return; } else if ( pic->vdp_infos.picture_coding_type==B_FRAME ) { if ( seq->forward_ref ) { ref_accel = (vdpau_accel_t*)seq->forward_ref->accel_data; pic->vdp_infos.forward_reference = ref_accel->surface; } else return; if ( seq->backward_ref ) { ref_accel = (vdpau_accel_t*)seq->backward_ref->accel_data; pic->vdp_infos.backward_reference = ref_accel->surface; } else return; } int still_image = (end_of_sequence) ? VO_STILL_IMAGE : 0; /* no sequence display extension parser yet so at least enable autoselection */ int color_matrix = 0; VO_SET_FLAGS_CM (4, color_matrix); vo_frame_t *img = vd->stream->video_out->get_frame( vd->stream->video_out, seq->coded_width, seq->coded_height, seq->ratio, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | seq->chroma | seq->reset | still_image | color_matrix ); seq->reset = 0; vdpau_accel_t *accel = (vdpau_accel_t*)img->accel_data; if ( !seq->accel_vdpau ) seq->accel_vdpau = accel; if( seq->vdp_runtime_nr != *(seq->accel_vdpau->current_vdp_runtime_nr) ) { seq->accel_vdpau = accel; if ( seq->forward_ref ) seq->forward_ref->free( seq->forward_ref ); seq->forward_ref = NULL; if ( seq->backward_ref ) seq->backward_ref->free( seq->backward_ref ); seq->backward_ref = NULL; vd->decoder = VDP_INVALID_HANDLE; } decode_render( vd, accel ); #ifdef MAKE_DAT if ( nframes==0 ) { fwrite( &seq->coded_width, 1, sizeof(seq->coded_width), outfile ); fwrite( &seq->coded_height, 1, sizeof(seq->coded_height), outfile ); fwrite( &seq->ratio, 1, sizeof(seq->ratio), outfile ); fwrite( &seq->profile, 1, sizeof(seq->profile), outfile ); } if ( nframes++ < 25 ) { fwrite( &pic->vdp_infos, 1, sizeof(pic->vdp_infos), outfile ); fwrite( &pic->slices_pos, 1, sizeof(pic->slices_pos), outfile ); fwrite( pic->slices, 1, pic->slices_pos, outfile ); } #endif img->drawn = 0; img->pts = seq->seq_pts; seq->seq_pts = 0; /* reset */ img->bad_frame = 0; if ( end_of_sequence ) { if ( seq->backward_ref ) seq->backward_ref->free( seq->backward_ref ); seq->backward_ref = NULL; } #if 0 /* trying to deal with (french) buggy streams that randomly set bottom_field_first while stream is top_field_first. So we assume that when top_field_first is set one time, the stream _is_ top_field_first. */ lprintf("pic->vdp_infos.top_field_first = %d\n", pic->vdp_infos.top_field_first); if ( pic->vdp_infos.top_field_first ) seq->top_field_first = 1; img->top_field_first = seq->top_field_first; #else img->top_field_first = pic->vdp_infos.top_field_first; #endif /* progressive_frame is unreliable with most mpeg2 streams */ if ( pic->vdp_infos.picture_structure!=PICTURE_FRAME ) img->progressive_frame = 0; else img->progressive_frame = pic->progressive_frame; img->repeat_first_field = pic->repeat_first_field; double duration = seq->video_step; if ( img->repeat_first_field ) { if( !seq->progressive_sequence && pic->progressive_frame ) { /* decoder should output 3 fields, so adjust duration to count on this extra field time */ duration *= 3; duration /= 2; } else if ( seq->progressive_sequence ) { /* for progressive sequences the output should repeat the frame 1 or 2 times depending on top_field_first flag. */ duration *= (pic->vdp_infos.top_field_first ? 3 : 2); } } img->duration = (int)(duration + .5); if ( pic->vdp_infos.picture_coding_type!=B_FRAME ) { if ( pic->vdp_infos.picture_coding_type==I_FRAME && !seq->backward_ref ) { img->pts = 0; img->draw( img, vd->stream ); ++img->drawn; } if ( seq->forward_ref ) { seq->forward_ref->drawn = 0; seq->forward_ref->free( seq->forward_ref ); } seq->forward_ref = seq->backward_ref; if ( seq->forward_ref && !seq->forward_ref->drawn ) { seq->forward_ref->draw( seq->forward_ref, vd->stream ); } seq->backward_ref = img; } else { img->draw( img, vd->stream ); img->free( img ); } } static void picture_ready( vdpau_mpeg12_decoder_t *vd, uint8_t end_of_sequence ) { picture_t *pic = (picture_t*)&vd->sequence.picture; if ( !pic->slices_count ) return; if ( pic->vdp_infos2.picture_structure && !pic->slices_count2 ) return; decode_picture( vd, end_of_sequence ); } /* * This function receives a buffer of data from the demuxer layer and * figures out how to handle it based on its header flags. */ static void vdpau_mpeg12_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { vdpau_mpeg12_decoder_t *this = (vdpau_mpeg12_decoder_t *) this_gen; sequence_t *seq = (sequence_t*)&this->sequence; /* preview buffers shall not be decoded and drawn -- use them only to supply stream information */ if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; if ( !buf->size ) return; if ( buf->pts ) seq->cur_pts = buf->pts; int size = seq->bufpos+buf->size; if ( seq->bufsize < (unsigned int)size ) { seq->bufsize = size+1024; seq->buf = realloc( seq->buf, seq->bufsize ); } xine_fast_memcpy( seq->buf+seq->bufpos, buf->content, buf->size ); seq->bufpos += buf->size; while ( seq->bufseek <= (int)(seq->bufpos)-4 ) { uint8_t *buffer = seq->buf+seq->bufseek; if ( buffer[0]==0 && buffer[1]==0 && buffer[2]==1 ) { if ( seq->start<0 ) { seq->start = seq->bufseek; } else { parse_code( this, seq->buf+seq->start, seq->bufseek-seq->start ); uint8_t *tmp = (uint8_t*)malloc(seq->bufsize); xine_fast_memcpy( tmp, seq->buf+seq->bufseek, seq->bufpos-seq->bufseek ); seq->bufpos -= seq->bufseek; seq->start = -1; seq->bufseek = -1; free( seq->buf ); seq->buf = tmp; } } ++seq->bufseek; } /* still image detection -- don't wait for further data if buffer ends in sequence end code */ if (seq->start >= 0 && seq->buf[seq->start + 3] == sequence_end_code) { decode_picture(this, 1); parse_code(this, seq->buf+seq->start, 4); seq->start = -1; } } /* * This function is called when xine needs to flush the system. */ static void vdpau_mpeg12_flush (video_decoder_t *this_gen) { lprintf( "vdpau_mpeg12_flush\n" ); (void)this_gen; } /* * This function resets the video decoder. */ static void vdpau_mpeg12_reset (video_decoder_t *this_gen) { vdpau_mpeg12_decoder_t *this = (vdpau_mpeg12_decoder_t *) this_gen; lprintf( "vdpau_mpeg12_reset\n" ); reset_sequence( &this->sequence, 1 ); } /* * The decoder should forget any stored pts values here. */ static void vdpau_mpeg12_discontinuity (video_decoder_t *this_gen) { vdpau_mpeg12_decoder_t *this = (vdpau_mpeg12_decoder_t *) this_gen; lprintf( "vdpau_mpeg12_discontinuity\n" ); reset_sequence( &this->sequence, 0 ); } /* * This function frees the video decoder instance allocated to the decoder. */ static void vdpau_mpeg12_dispose (video_decoder_t *this_gen) { vdpau_mpeg12_decoder_t *this = (vdpau_mpeg12_decoder_t *) this_gen; lprintf( "vdpau_mpeg12_dispose\n" ); if ( this->decoder!=VDP_INVALID_HANDLE && this->sequence.accel_vdpau ) { if (this->sequence.accel_vdpau->lock) this->sequence.accel_vdpau->lock (this->sequence.accel_vdpau->vo_frame); this->sequence.accel_vdpau->vdp_decoder_destroy( this->decoder ); this->decoder = VDP_INVALID_HANDLE; if (this->sequence.accel_vdpau->unlock) this->sequence.accel_vdpau->unlock (this->sequence.accel_vdpau->vo_frame); } free_sequence( &this->sequence ); this->stream->video_out->close( this->stream->video_out, this->stream ); free( this->sequence.picture.slices ); free( this->sequence.buf ); free( this_gen ); } /* * This function allocates, initializes, and returns a private video * decoder structure. */ static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { vdpau_mpeg12_decoder_t *this ; lprintf( "open_plugin\n" ); (void)class_gen; /* the videoout must be vdpau-capable to support this decoder */ if ( !(stream->video_out->get_capabilities(stream->video_out) & VO_CAP_VDPAU_MPEG12) ) return NULL; /* now check if vdpau has free decoder resource */ vo_frame_t *img = stream->video_out->get_frame( stream->video_out, 1920, 1080, 1, XINE_IMGFMT_VDPAU, VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL ); if (!img) { return NULL; } vdpau_accel_t *accel = (vdpau_accel_t*)img->accel_data; int runtime_nr = accel->vdp_runtime_nr; img->free(img); VdpDecoder decoder; if (accel->lock) accel->lock (accel->vo_frame); VdpStatus st = accel->vdp_decoder_create( accel->vdp_device, VDP_DECODER_PROFILE_MPEG2_MAIN, 1920, 1080, 2, &decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); if ( st!=VDP_STATUS_OK ) { lprintf( "can't create vdpau decoder.\n" ); return NULL; } if (accel->lock) accel->lock (accel->vo_frame); accel->vdp_decoder_destroy( decoder ); if (accel->unlock) accel->unlock (accel->vo_frame); this = (vdpau_mpeg12_decoder_t *) calloc(1, sizeof(vdpau_mpeg12_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = vdpau_mpeg12_decode_data; this->video_decoder.flush = vdpau_mpeg12_flush; this->video_decoder.reset = vdpau_mpeg12_reset; this->video_decoder.discontinuity = vdpau_mpeg12_discontinuity; this->video_decoder.dispose = vdpau_mpeg12_dispose; this->stream = stream; this->sequence.bufsize = 1024; this->sequence.buf = (uint8_t*)malloc(this->sequence.bufsize); this->sequence.forward_ref = 0; this->sequence.backward_ref = 0; this->sequence.vdp_runtime_nr = runtime_nr; free_sequence( &this->sequence ); this->sequence.ratio = 1; this->sequence.reset = VO_NEW_SEQUENCE_FLAG; init_picture( &this->sequence.picture ); this->decoder = VDP_INVALID_HANDLE; this->sequence.accel_vdpau = NULL; (stream->video_out->open)(stream->video_out, stream); #ifdef MAKE_DAT outfile = fopen( "/tmp/mpg.dat","w"); nframes = 0; #endif return &this->video_decoder; } /* * This function allocates a private video decoder class and initializes * the class's member functions. */ void *mpeg12_init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_vdpau_mpeg12_class = { .open_plugin = open_plugin, .identifier = "vdpau_mpeg12", .description = N_("MPEG1/2 decoder plugin using VDPAU hardware decoding.\n" "Must be used along with video_out_vdpau."), .dispose = NULL, }; return (void *)&decode_video_vdpau_mpeg12_class; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libvpx.c�����������������������������������������������������������������0000644�0001750�0001750�00000025034�14647725152�015050� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2013-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * libvpx decoder wrapped by Petri Hintukainen <phintuka@users.sourceforge.net> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <vpx/vpx_decoder.h> #include <vpx/vp8dx.h> #define LOG_MODULE "libvpx_video_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> typedef struct vpx_decoder_s { video_decoder_t video_decoder; /* parent video decoder structure */ xine_stream_t *stream; int64_t pts; struct vpx_codec_ctx ctx; int decoder_ok; /* current decoder status */ unsigned char *buf; /* the accumulated buffer data */ int bufsize; /* the maximum size of buf */ int size; /* the current size of buf */ int width; /* the width of a video frame */ int height; /* the height of a video frame */ double ratio; /* the width to height ratio */ int frame_flags; /* color matrix and fullrange */ } vpx_decoder_t; /************************************************************************** * xine video plugin functions *************************************************************************/ static void vpx_handle_header(vpx_decoder_t *this, buf_element_t *buf) { xine_bmiheader *bih; (this->stream->video_out->open) (this->stream->video_out, this->stream); bih = (xine_bmiheader *) buf->content; this->width = (bih->biWidth + 1) & ~1; this->height = (bih->biHeight + 1) & ~1; if (buf->decoder_flags & BUF_FLAG_ASPECT) this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; else this->ratio = (double)this->width / (double)this->height; free (this->buf); this->buf = NULL; this->bufsize = 0; this->size = 0; this->decoder_ok = 1; switch (buf->type) { case BUF_VIDEO_VP8: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "VP8"); break; case BUF_VIDEO_VP9: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "VP9"); break; } _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); } static void vpx_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { vpx_decoder_t *this = (vpx_decoder_t *) this_gen; if ((!this->decoder_ok) | (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_COLOR_MATRIX | BUF_FLAG_STDHEADER | BUF_FLAG_SPECIAL))) { if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_SPECIAL)) { return; } /* optional demux override (matroska/webm) */ if (buf->decoder_flags & BUF_FLAG_COLOR_MATRIX) { VO_SET_FLAGS_CM (buf->decoder_info[4], this->frame_flags); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { vpx_handle_header(this, buf); return; } if (!this->decoder_ok) return; } /* collect data */ if (this->size + buf->size > this->bufsize) { this->bufsize = this->size + 2 * buf->size; this->buf = realloc (this->buf, this->bufsize); } xine_fast_memcpy (&this->buf[this->size], buf->content, buf->size); this->size += buf->size; /* save pts */ if (buf->pts > 0) { this->pts = buf->pts; } if (!(buf->decoder_flags & BUF_FLAG_FRAME_END)) { return; } /* decode */ struct vpx_codec_ctx *ctx = &this->ctx; vpx_codec_err_t err; vo_frame_t *img; int64_t pts, *p_pts; p_pts = malloc(sizeof(*p_pts)); *p_pts = this->pts; err = vpx_codec_decode(ctx, this->buf, this->size, p_pts, 0); this->size = 0; if (err != VPX_CODEC_OK) { const char *error = vpx_codec_error(ctx); const char *detail = vpx_codec_error_detail(ctx); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to decode frame: %s (%s)\n", error, detail ? detail : ""); free(p_pts); return; } const void *iter = NULL; struct vpx_image *vpx_img = vpx_codec_get_frame(ctx, &iter); if (!vpx_img) return; p_pts = vpx_img->user_priv; vpx_img->user_priv = NULL; pts = *p_pts; free(p_pts); if (vpx_img->fmt != VPX_IMG_FMT_I420) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Unsupported colour space %d\n", vpx_img->fmt); return; } img = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_YV12, this->frame_flags | VO_BOTH_FIELDS | VO_GET_FRAME_MAY_FAIL); if (!img) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame(%dx%d) failed\n", this->width, this->height); return; } /* crop if allocated frame is smaller than requested */ int width = this->width, height = this->height; if (width > img->width) width = img->width; if (height > img->height) height = img->height; yv12_to_yv12( /* Y */ vpx_img->planes[0], vpx_img->stride[0], img->base[0], img->pitches[0], /* U */ vpx_img->planes[1], vpx_img->stride[1], img->base[1], img->pitches[1], /* V */ vpx_img->planes[2], vpx_img->stride[2], img->base[2], img->pitches[2], /* width x height */ width, height); img->pts = pts; img->bad_frame = 0; img->progressive_frame = 1; img->draw(img, this->stream); img->free(img); } static void vpx_flush (video_decoder_t *this_gen) { (void)this_gen; } static void vpx_reset (video_decoder_t *this_gen) { vpx_decoder_t *this = (vpx_decoder_t *) this_gen; if (this->decoder_ok) { const void *iter = NULL; while (1) { struct vpx_image *img = vpx_codec_get_frame(&this->ctx, &iter); if (!img) break; free(img->user_priv); img->user_priv = NULL; } } this->size = 0; } static void vpx_discontinuity (video_decoder_t *this_gen) { (void)this_gen; } /* * This function frees the video decoder instance allocated to the decoder. */ static void vpx_dispose (video_decoder_t *this_gen) { vpx_decoder_t *this = (vpx_decoder_t *) this_gen; const void *iter = NULL; while (1) { struct vpx_image *img = vpx_codec_get_frame(&this->ctx, &iter); if (!img) break; free(img->user_priv); img->user_priv = NULL; } vpx_codec_destroy(&this->ctx); free (this->buf); if (this->decoder_ok) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } free (this_gen); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { vpx_decoder_t *this; const struct vpx_codec_iface *iface; struct vpx_codec_dec_cfg deccfg = { .threads = xine_cpu_count(), .w = 0, .h = 0 }; int vp_version; uint32_t video_type = BUF_VIDEO_BASE | (_x_get_video_streamtype(stream) << 16); switch (video_type) { case BUF_VIDEO_VP8: iface = &vpx_codec_vp8_dx_algo; vp_version = 8; break; #ifdef HAVE_VPX_VP9_DECODER case BUF_VIDEO_VP9: iface = &vpx_codec_vp9_dx_algo; vp_version = 9; break; #endif default: return NULL; } (void)class_gen; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "using %d CPU cores\n", deccfg.threads); this = (vpx_decoder_t *) calloc(1, sizeof(vpx_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = vpx_decode_data; this->video_decoder.flush = vpx_flush; this->video_decoder.reset = vpx_reset; this->video_decoder.discontinuity = vpx_discontinuity; this->video_decoder.dispose = vpx_dispose; this->size = 0; this->stream = stream; this->decoder_ok = 0; this->buf = NULL; /* VP8/9 seems not to transport color matrix and fullrange info. So lets at least tell video out to do image size based selection. */ this->frame_flags = 0; VO_SET_FLAGS_CM (4, this->frame_flags); /* undefined, mpeg range */ xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "VP%d: using libvpx version %s\n", vp_version, vpx_codec_version_str()); /* FIXME: ver should be VPX_DECODER_ABI_VERSION not 0. */ if (vpx_codec_dec_init(&this->ctx, iface, &deccfg, 0) != VPX_CODEC_OK) { const char *err = vpx_codec_error(&this->ctx); xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Failed to initialize VP%d decoder: %s\n", vp_version, err); free(this); return NULL; } return &this->video_decoder; } static void *init_plugin_vpx (xine_t *xine, const void *data) { (void)xine; (void)data; static const video_decoder_class_t decode_video_vpx_class = { .open_plugin = open_plugin, .identifier = "libvpx", .description = N_("WebM (VP8/VP9) video decoder plugin"), .dispose = NULL, }; return (void *)&decode_video_vpx_class; } /* * exported plugin catalog entry */ static const uint32_t video_types_vpx[] = { BUF_VIDEO_VP8, #ifdef HAVE_VPX_VP9_DECODER BUF_VIDEO_VP9, #endif 0 }; static const decoder_info_t dec_info_video_vpx = { .supported_types = video_types_vpx, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "libvpx", XINE_VERSION_CODE, &dec_info_video_vpx, init_plugin_vpx }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/�������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�015607� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/xine_mpeg2new_decoder.c��������������������������������������0000644�0001750�0001750�00000037167�14647725152�022225� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * * stuff needed to turn libmpeg2 into a xine decoder plugin */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <inttypes.h> #include <assert.h> #include "./include/mpeg2.h" #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> /* #define LOG #define LOG_FRAME_ALLOC_FREE #define LOG_ENTRY #define LOG_FRAME_COUNTER */ #undef _x_abort #define _x_abort() do {} while (0) typedef struct { uint32_t id; vo_frame_t * img; } img_state_t; typedef struct mpeg2_video_decoder_s { video_decoder_t video_decoder; mpeg2dec_t *mpeg2dec; xine_stream_t *stream; int32_t force_aspect; int force_pan_scan; double ratio; img_state_t img_state[30]; uint32_t frame_number; uint32_t rff_pattern; } mpeg2_video_decoder_t; #ifndef LOG_FRAME_ALLOC_FREE inline static void mpeg2_video_print_bad_state(img_state_t * img_state) {} #else static void mpeg2_video_print_bad_state(img_state_t * img_state) { int32_t n,m; m=0; for(n=0;n<30;n++) { if (img_state[n].id>0) { printf("%d = %u\n",n, img_state[n].id); m++; } } if (m > 3) _x_abort(); if (m == 0) printf("NO FRAMES\n"); } #endif static void mpeg2_video_free_all(img_state_t * img_state) { int32_t n; vo_frame_t * img; printf("libmpeg2new:free_all\n"); for(n=0;n<30;n++) { if (img_state[n].id>0) { img = img_state[n].img; img->free(img); img_state[n].id = 0; } } } #if 0 static void mpeg2_video_print_fbuf(const mpeg2_fbuf_t * fbuf) { printf("%p",fbuf); vo_frame_t * img; if (fbuf) { img = (vo_frame_t *) fbuf->id; if (img) { printf (", img=%p, (id=%d)\n", img, img->id); } else { printf (", img=NULL\n"); } } else { printf ("\n"); } } #endif static void mpeg2_video_decode_data (video_decoder_t *this_gen, buf_element_t *buf_element) { mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; uint8_t * current = buf_element->content; uint8_t * end = buf_element->content + buf_element->size; const mpeg2_info_t * info; mpeg2_state_t state; vo_frame_t * img; uint32_t picture_structure; //int32_t frame_skipping; /* handle aspect hints from xine-dvdnav */ if (buf_element->decoder_flags & BUF_FLAG_SPECIAL) { if (buf_element->decoder_info[1] == BUF_SPECIAL_ASPECT) { this->force_aspect = buf_element->decoder_info[2]; if (buf_element->decoder_info[3] == 0x1 && buf_element->decoder_info[2] == 3) /* letterboxing is denied, we have to do pan&scan */ this->force_pan_scan = 1; else this->force_pan_scan = 0; } return; } if (buf_element->decoder_flags != 0) return; #ifdef LOG_ENTRY printf ("libmpeg2: decode_data: enter\n"); #endif mpeg2_buffer (this->mpeg2dec, current, end); info = mpeg2_info (this->mpeg2dec); while ((state = mpeg2_parse (this->mpeg2dec)) != STATE_BUFFER) { switch (state) { case STATE_SEQUENCE: /* might set nb fbuf, convert format, stride */ /* might set fbufs */ _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_BITRATE, info->sequence->byte_rate * 8); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, info->sequence->picture_width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, info->sequence->picture_height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, info->sequence->frame_period / 300); if (this->force_aspect) ((mpeg2_sequence_t *)info->sequence)->pixel_width = this->force_aspect; /* ugly... */ switch (info->sequence->pixel_width) { case 3: this->ratio = 16.0 / 9.0; break; case 4: this->ratio = 2.11; break; case 2: this->ratio = 4.0 / 3.0; break; case 1: default: this->ratio = (double)info->sequence->picture_width/(double)info->sequence->picture_height; break; } _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, (int)(10000*this->ratio)); if (info->sequence->flags & SEQ_FLAG_MPEG2) { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MPEG 2 (libmpeg2new)"); } else { _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "MPEG 1 (libmpeg2new)"); } break; case STATE_PICTURE: /* might skip */ /* might set fbuf */ if (info->current_picture->nb_fields == 1) { picture_structure = info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? VO_TOP_FIELD : VO_BOTTOM_FIELD; } else { picture_structure = VO_BOTH_FIELDS; } img = this->stream->video_out->get_frame (this->stream->video_out, info->sequence->picture_width, info->sequence->picture_height, this->ratio, XINE_IMGFMT_YV12, picture_structure); this->frame_number++; #ifdef LOG_FRAME_COUNTER printf("libmpeg2:frame_number=%d\n",this->frame_number); #endif img->top_field_first = info->current_picture->flags & PIC_FLAG_TOP_FIELD_FIRST ? 1 : 0; img->repeat_first_field = (info->current_picture->nb_fields > 2) ? 1 : 0; img->duration=info->sequence->frame_period / 300; if( ((this->rff_pattern & 0xff) == 0xaa || (this->rff_pattern & 0xff) == 0x55) ) { /* special case for ntsc 3:2 pulldown */ img->duration += img->duration/4; } else { if( img->repeat_first_field ) { img->duration = (img->duration * info->current_picture->nb_fields) / 2; } } if ((info->current_picture->flags & 7) == 1) { img->pts=buf_element->pts; /* If an I frame, use PTS */ } else { img->pts=0; } #ifdef LOG_FRAME_ALLOC_FREE printf ("libmpeg2:decode_data:get_frame xine=%p (id=%d)\n", img,img->id); #endif if (this->img_state[img->id].id != 0) { printf ("libmpeg2:decode_data:get_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); _x_abort(); } this->img_state[img->id].id = 1; this->img_state[img->id].img = img; mpeg2_set_buf (this->mpeg2dec, img->base, img); break; case STATE_SLICE: case STATE_END: #if 0 printf("libmpeg2:decode_data:current_fbuf="); mpeg2_video_print_fbuf(info->current_fbuf); printf("libmpeg2:decode_data:display_fbuf="); mpeg2_video_print_fbuf(info->display_fbuf); printf("libmpeg2:decode_data:discard_fbuf="); mpeg2_video_print_fbuf(info->discard_fbuf); #endif /* draw current picture */ /* might free frame buffer */ if (info->display_fbuf && info->display_fbuf->id) { img = (vo_frame_t *) info->display_fbuf->id; /* this should be used to detect any special rff pattern */ this->rff_pattern = this->rff_pattern << 1; this->rff_pattern |= img->repeat_first_field; #ifdef LOG_FRAME_ALLOC_FREE printf ("libmpeg2:decode_data:draw_frame xine=%p, fbuf=%p, id=%d \n", img, info->display_fbuf, img->id); #endif if (this->img_state[img->id].id != 1) { printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); _x_abort(); } if (this->img_state[img->id].id == 1) { /*frame_skipping =*/ img->draw (img, this->stream); /* FIXME: Handle skipping */ this->img_state[img->id].id = 2; } } if (info->discard_fbuf && !info->discard_fbuf->id) { printf ("libmpeg2:decode_data:BAD free_frame discard: xine=%p, fbuf=%p\n", info->discard_fbuf->id, info->discard_fbuf); //_x_abort(); } if (info->discard_fbuf && info->discard_fbuf->id) { img = (vo_frame_t *) info->discard_fbuf->id; #ifdef LOG_FRAME_ALLOC_FREE printf ("libmpeg2:decode_data:free_frame xine=%p, fbuf=%p,id=%d\n", img, info->discard_fbuf, img->id); #endif if (this->img_state[img->id].id != 2) { printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id].id); _x_abort(); } if (this->img_state[img->id].id == 2) { img->free(img); this->img_state[img->id].id = 0; } } #ifdef LOG_FRAME_ALLOC_FREE mpeg2_video_print_bad_state(this->img_state); #endif break; case STATE_GOP: break; default: printf("libmpeg2new: STATE unknown %d\n",state); break; } } #ifdef LOG_ENTRY printf ("libmpeg2: decode_data: exit\n"); #endif } static void mpeg2_video_flush (video_decoder_t *this_gen) { #ifdef LOG_ENTRY printf ("libmpeg2: flush\n"); #endif /* mpeg2_flush (&this->mpeg2); */ } static void mpeg2_video_reset (video_decoder_t *this_gen) { mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; #if 0 int32_t state; const mpeg2_info_t * info; vo_frame_t * img; int32_t frame_skipping; #endif #ifdef LOG_ENTRY printf ("libmpeg2: reset\n"); #endif mpeg2_reset (this->mpeg2dec, 1); /* 1 for full reset */ mpeg2_video_free_all(this->img_state); #if 0 /* This bit of code does not work yet. */ info = mpeg2_info (this->mpeg2dec); state = mpeg2_reset (this->mpeg2dec); printf("reset state1:%d\n",state); if (info->display_fbuf && info->display_fbuf->id) { img = (vo_frame_t *) info->display_fbuf->id; if (this->img_state[img->id] != 1) { printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); _x_abort(); } if (this->img_state[img->id] == 1) { frame_skipping = img->draw (img, this->stream); /* FIXME: Handle skipping */ this->img_state[img->id] = 2; } } if (info->discard_fbuf && !info->discard_fbuf->id) { printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); _x_abort(); } if (info->discard_fbuf && info->discard_fbuf->id) { img = (vo_frame_t *) info->discard_fbuf->id; if (this->img_state[img->id] != 2) { printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); _x_abort(); } if (this->img_state[img->id] == 2) { img->free(img); this->img_state[img->id] = 0; } } state = mpeg2_parse (this->mpeg2dec); printf("reset state2:%d\n",state); if (info->display_fbuf && info->display_fbuf->id) { img = (vo_frame_t *) info->display_fbuf->id; if (this->img_state[img->id] != 1) { printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); _x_abort(); } if (this->img_state[img->id] == 1) { frame_skipping = img->draw (img, this->stream); /* FIXME: Handle skipping */ this->img_state[img->id] = 2; } } if (info->discard_fbuf && !info->discard_fbuf->id) { printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); _x_abort(); } if (info->discard_fbuf && info->discard_fbuf->id) { img = (vo_frame_t *) info->discard_fbuf->id; if (this->img_state[img->id] != 2) { printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); _x_abort(); } if (this->img_state[img->id] == 2) { img->free(img); this->img_state[img->id] = 0; } } state = mpeg2_parse (this->mpeg2dec); printf("reset state3:%d\n",state); if (info->display_fbuf && info->display_fbuf->id) { img = (vo_frame_t *) info->display_fbuf->id; if (this->img_state[img->id] != 1) { printf ("libmpeg2:decode_data:draw_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); _x_abort(); } if (this->img_state[img->id] == 1) { frame_skipping = img->draw (img, this->stream); /* FIXME: Handle skipping */ this->img_state[img->id] = 2; } } if (info->discard_fbuf && !info->discard_fbuf->id) { printf ("libmpeg2:decode_data:BAD free_frame discard_fbuf=%p\n", info->discard_fbuf); _x_abort(); } if (info->discard_fbuf && info->discard_fbuf->id) { img = (vo_frame_t *) info->discard_fbuf->id; if (this->img_state[img->id] != 2) { printf ("libmpeg2:decode_data:free_frame id=%d BAD STATE:%d\n", img->id, this->img_state[img->id]); _x_abort(); } if (this->img_state[img->id] == 2) { img->free(img); this->img_state[img->id] = 0; } } #endif } static void mpeg2_video_discontinuity (video_decoder_t *this_gen) { #ifdef LOG_ENTRY printf ("libmpeg2: dicontinuity\n"); #endif /* mpeg2_discontinuity (&this->mpeg2dec); */ } static void mpeg2_video_dispose (video_decoder_t *this_gen) { mpeg2_video_decoder_t *this = (mpeg2_video_decoder_t *) this_gen; #ifdef LOG_ENTRY printf ("libmpeg2: close\n"); #endif mpeg2_close (this->mpeg2dec); this->stream->video_out->close(this->stream->video_out, this->stream); free (this); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { mpeg2_video_decoder_t *this ; int32_t n; this = (mpeg2_video_decoder_t *) calloc(1, sizeof(mpeg2_video_decoder_t)); this->video_decoder.decode_data = mpeg2_video_decode_data; this->video_decoder.flush = mpeg2_video_flush; this->video_decoder.reset = mpeg2_video_reset; this->video_decoder.discontinuity = mpeg2_video_discontinuity; this->video_decoder.dispose = mpeg2_video_dispose; this->stream = stream; this->frame_number=0; this->rff_pattern=0; this->mpeg2dec = mpeg2_init (); mpeg2_custom_fbuf (this->mpeg2dec, 1); /* <- Force libmpeg2 to use xine frame buffers. */ (stream->video_out->open) (stream->video_out, stream); this->force_aspect = this->force_pan_scan = 0; for(n=0;n<30;n++) this->img_state[n].id=0; return &this->video_decoder; } /* * mpeg2 plugin class */ static void *init_plugin (xine_t *xine, const void *data) { static const video_decoder_class_t decode_video_mpeg2new_class = { .open_plugin = open_plugin, .identifier = "mpeg2new", .description = N_("mpeg2 based video decoder plugin"), .dispose = NULL, }; return (void *)&decode_video_mpeg2new_class; } /* * exported plugin catalog entry */ static const uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 }; static const decoder_info_t dec_info_mpeg2 = { .supported_types = supported_types, .priority = 6, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "mpeg2new", XINE_VERSION_CODE, &dec_info_mpeg2, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/�����������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�017232� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/mpeg2convert.h���������������������������������������0000644�0001750�0001750�00000003165�14647725152�022023� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mpeg2convert.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MPEG2CONVERT_H #define MPEG2CONVERT_H mpeg2_convert_t mpeg2convert_rgb32; mpeg2_convert_t mpeg2convert_rgb24; mpeg2_convert_t mpeg2convert_rgb16; mpeg2_convert_t mpeg2convert_rgb15; mpeg2_convert_t mpeg2convert_rgb8; mpeg2_convert_t mpeg2convert_bgr32; mpeg2_convert_t mpeg2convert_bgr24; mpeg2_convert_t mpeg2convert_bgr16; mpeg2_convert_t mpeg2convert_bgr15; mpeg2_convert_t mpeg2convert_bgr8; typedef enum { MPEG2CONVERT_RGB = 0, MPEG2CONVERT_BGR = 1 } mpeg2convert_rgb_order_t; mpeg2_convert_t * mpeg2convert_rgb (mpeg2convert_rgb_order_t order, unsigned int bpp); mpeg2_convert_t mpeg2convert_uyvy; #endif /* MPEG2CONVERT_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/alpha_asm.h������������������������������������������0000644�0001750�0001750�00000017356�14647725152�021344� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Alpha assembly macros * Copyright (c) 2002-2003 Falk Hueffner <falk@debian.org> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef ALPHA_ASM_H #define ALPHA_ASM_H #include <inttypes.h> #if defined __GNUC__ # define GNUC_PREREQ(maj, min) \ ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) #else # define GNUC_PREREQ(maj, min) 0 #endif #define AMASK_BWX (1 << 0) #define AMASK_FIX (1 << 1) #define AMASK_CIX (1 << 2) #define AMASK_MVI (1 << 8) #ifdef __alpha_bwx__ # define HAVE_BWX() 1 #else # define HAVE_BWX() (amask(AMASK_BWX) == 0) #endif #ifdef __alpha_fix__ # define HAVE_FIX() 1 #else # define HAVE_FIX() (amask(AMASK_FIX) == 0) #endif #ifdef __alpha_max__ # define HAVE_MVI() 1 #else # define HAVE_MVI() (amask(AMASK_MVI) == 0) #endif #ifdef __alpha_cix__ # define HAVE_CIX() 1 #else # define HAVE_CIX() (amask(AMASK_CIX) == 0) #endif inline static uint64_t BYTE_VEC(uint64_t x) { x |= x << 8; x |= x << 16; x |= x << 32; return x; } inline static uint64_t WORD_VEC(uint64_t x) { x |= x << 16; x |= x << 32; return x; } #define ldq(p) (*(const uint64_t *) (p)) #define ldl(p) (*(const int32_t *) (p)) #define stl(l, p) do { *(uint32_t *) (p) = (l); } while (0) #define stq(l, p) do { *(uint64_t *) (p) = (l); } while (0) #define sextw(x) ((int16_t) (x)) #ifdef __GNUC__ struct unaligned_long { uint64_t l; } __attribute__((packed)); #define ldq_u(p) (*(const uint64_t *) (((uint64_t) (p)) & ~7ul)) #define uldq(a) (((const struct unaligned_long *) (a))->l) #if GNUC_PREREQ(3,3) #define prefetch(p) __builtin_prefetch((p), 0, 1) #define prefetch_en(p) __builtin_prefetch((p), 0, 0) #define prefetch_m(p) __builtin_prefetch((p), 1, 1) #define prefetch_men(p) __builtin_prefetch((p), 1, 0) #define cmpbge __builtin_alpha_cmpbge /* Avoid warnings. */ #define extql(a, b) __builtin_alpha_extql(a, (uint64_t) (b)) #define extwl(a, b) __builtin_alpha_extwl(a, (uint64_t) (b)) #define extqh(a, b) __builtin_alpha_extqh(a, (uint64_t) (b)) #define zap __builtin_alpha_zap #define zapnot __builtin_alpha_zapnot #define amask __builtin_alpha_amask #define implver __builtin_alpha_implver #define rpcc __builtin_alpha_rpcc #else #define prefetch(p) asm volatile("ldl $31,%0" : : "m"(*(const char *) (p)) : "memory") #define prefetch_en(p) asm volatile("ldq $31,%0" : : "m"(*(const char *) (p)) : "memory") #define prefetch_m(p) asm volatile("lds $f31,%0" : : "m"(*(const char *) (p)) : "memory") #define prefetch_men(p) asm volatile("ldt $f31,%0" : : "m"(*(const char *) (p)) : "memory") #define cmpbge(a, b) ({ uint64_t __r; asm ("cmpbge %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) #define extql(a, b) ({ uint64_t __r; asm ("extql %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) #define extwl(a, b) ({ uint64_t __r; asm ("extwl %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) #define extqh(a, b) ({ uint64_t __r; asm ("extqh %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) #define zap(a, b) ({ uint64_t __r; asm ("zap %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) #define zapnot(a, b) ({ uint64_t __r; asm ("zapnot %r1,%2,%0" : "=r" (__r) : "rJ" (a), "rI" (b)); __r; }) #define amask(a) ({ uint64_t __r; asm ("amask %1,%0" : "=r" (__r) : "rI" (a)); __r; }) #define implver() ({ uint64_t __r; asm ("implver %0" : "=r" (__r)); __r; }) #define rpcc() ({ uint64_t __r; asm volatile ("rpcc %0" : "=r" (__r)); __r; }) #endif #define wh64(p) asm volatile("wh64 (%0)" : : "r"(p) : "memory") #if GNUC_PREREQ(3,3) && defined(__alpha_max__) #define minub8 __builtin_alpha_minub8 #define minsb8 __builtin_alpha_minsb8 #define minuw4 __builtin_alpha_minuw4 #define minsw4 __builtin_alpha_minsw4 #define maxub8 __builtin_alpha_maxub8 #define maxsb8 __builtin_alpha_maxsb8 #define maxuw4 __builtin_alpha_maxuw4 #define maxsw4 __builtin_alpha_maxsw4 #define perr __builtin_alpha_perr #define pklb __builtin_alpha_pklb #define pkwb __builtin_alpha_pkwb #define unpkbl __builtin_alpha_unpkbl #define unpkbw __builtin_alpha_unpkbw #else #define minub8(a, b) ({ uint64_t __r; asm (".arch ev6; minub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define minsb8(a, b) ({ uint64_t __r; asm (".arch ev6; minsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define minuw4(a, b) ({ uint64_t __r; asm (".arch ev6; minuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define minsw4(a, b) ({ uint64_t __r; asm (".arch ev6; minsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define maxub8(a, b) ({ uint64_t __r; asm (".arch ev6; maxub8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define maxsb8(a, b) ({ uint64_t __r; asm (".arch ev6; maxsb8 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define maxuw4(a, b) ({ uint64_t __r; asm (".arch ev6; maxuw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define maxsw4(a, b) ({ uint64_t __r; asm (".arch ev6; maxsw4 %r1,%2,%0" : "=r" (__r) : "%rJ" (a), "rI" (b)); __r; }) #define perr(a, b) ({ uint64_t __r; asm (".arch ev6; perr %r1,%r2,%0" : "=r" (__r) : "%rJ" (a), "rJ" (b)); __r; }) #define pklb(a) ({ uint64_t __r; asm (".arch ev6; pklb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) #define pkwb(a) ({ uint64_t __r; asm (".arch ev6; pkwb %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) #define unpkbl(a) ({ uint64_t __r; asm (".arch ev6; unpkbl %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) #define unpkbw(a) ({ uint64_t __r; asm (".arch ev6; unpkbw %r1,%0" : "=r" (__r) : "rJ" (a)); __r; }) #endif #elif defined(__DECC) /* Digital/Compaq/hp "ccc" compiler */ #include <c_asm.h> #define ldq_u(a) asm ("ldq_u %v0,0(%a0)", a) #define uldq(a) (*(const __unaligned uint64_t *) (a)) #define cmpbge(a, b) asm ("cmpbge %a0,%a1,%v0", a, b) #define extql(a, b) asm ("extql %a0,%a1,%v0", a, b) #define extwl(a, b) asm ("extwl %a0,%a1,%v0", a, b) #define extqh(a, b) asm ("extqh %a0,%a1,%v0", a, b) #define zap(a, b) asm ("zap %a0,%a1,%v0", a, b) #define zapnot(a, b) asm ("zapnot %a0,%a1,%v0", a, b) #define amask(a) asm ("amask %a0,%v0", a) #define implver() asm ("implver %v0") #define rpcc() asm ("rpcc %v0") #define minub8(a, b) asm ("minub8 %a0,%a1,%v0", a, b) #define minsb8(a, b) asm ("minsb8 %a0,%a1,%v0", a, b) #define minuw4(a, b) asm ("minuw4 %a0,%a1,%v0", a, b) #define minsw4(a, b) asm ("minsw4 %a0,%a1,%v0", a, b) #define maxub8(a, b) asm ("maxub8 %a0,%a1,%v0", a, b) #define maxsb8(a, b) asm ("maxsb8 %a0,%a1,%v0", a, b) #define maxuw4(a, b) asm ("maxuw4 %a0,%a1,%v0", a, b) #define maxsw4(a, b) asm ("maxsw4 %a0,%a1,%v0", a, b) #define perr(a, b) asm ("perr %a0,%a1,%v0", a, b) #define pklb(a) asm ("pklb %a0,%v0", a) #define pkwb(a) asm ("pkwb %a0,%v0", a) #define unpkbl(a) asm ("unpkbl %a0,%v0", a) #define unpkbw(a) asm ("unpkbw %a0,%v0", a) #define wh64(a) asm ("wh64 %a0", a) #else #error "Unknown compiler!" #endif #endif /* ALPHA_ASM_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/video_out.h������������������������������������������0000644�0001750�0001750�00000004255�14647725152�021406� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * video_out.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ struct mpeg2_sequence_s; struct mpeg2_convert_init_s; typedef struct { int (* convert) (int stage, void * id, const struct mpeg2_sequence_s * sequence, int stride, uint32_t accel, void * arg, struct mpeg2_convert_init_s * result); } vo_setup_result_t; typedef struct vo_instance_s vo_instance_t; struct vo_instance_s { int (* setup) (vo_instance_t * instance, unsigned int width, unsigned int height, unsigned int chroma_width, unsigned int chroma_height, vo_setup_result_t * result); void (* setup_fbuf) (vo_instance_t * instance, uint8_t ** buf, void ** id); void (* set_fbuf) (vo_instance_t * instance, uint8_t ** buf, void ** id); void (* start_fbuf) (vo_instance_t * instance, uint8_t * const * buf, void * id); void (* draw) (vo_instance_t * instance, uint8_t * const * buf, void * id); void (* discard) (vo_instance_t * instance, uint8_t * const * buf, void * id); void (* close) (vo_instance_t * instance); }; typedef vo_instance_t * vo_open_t (void); typedef struct { char * name; vo_open_t * open; } vo_driver_t; void vo_accel (uint32_t accel); /* return NULL terminated array of all drivers */ vo_driver_t const * vo_drivers (void); ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/sse.h������������������������������������������������0000644�0001750�0001750�00000022340�14647725152�020176� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * sse.h * Copyright (C) 1999-2003 R. Fisher * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ typedef union { float sf[4]; /* Single-precision (32-bit) value */ } ATTR_ALIGN(16) sse_t; /* On a 16 byte (128-bit) boundary */ #define sse_i2r(op, imm, reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "X" (imm) ) #define sse_m2r(op, mem, reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "X" (mem)) #define sse_r2m(op, reg, mem) \ __asm__ __volatile__ (#op " %%" #reg ", %0" \ : "=X" (mem) \ : /* nothing */ ) #define sse_r2r(op, regs, regd) \ __asm__ __volatile__ (#op " %" #regs ", %" #regd) #define sse_r2ri(op, regs, regd, imm) \ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ : /* nothing */ \ : "X" (imm) ) #define sse_m2ri(op, mem, reg, subop) \ __asm__ __volatile__ (#op " %0, %%" #reg ", " #subop \ : /* nothing */ \ : "X" (mem)) #define movaps_m2r(var, reg) sse_m2r(movaps, var, reg) #define movaps_r2m(reg, var) sse_r2m(movaps, reg, var) #define movaps_r2r(regs, regd) sse_r2r(movaps, regs, regd) #define movntps_r2m(xmmreg, var) sse_r2m(movntps, xmmreg, var) #define movups_m2r(var, reg) sse_m2r(movups, var, reg) #define movups_r2m(reg, var) sse_r2m(movups, reg, var) #define movups_r2r(regs, regd) sse_r2r(movups, regs, regd) #define movhlps_r2r(regs, regd) sse_r2r(movhlps, regs, regd) #define movlhps_r2r(regs, regd) sse_r2r(movlhps, regs, regd) #define movhps_m2r(var, reg) sse_m2r(movhps, var, reg) #define movhps_r2m(reg, var) sse_r2m(movhps, reg, var) #define movlps_m2r(var, reg) sse_m2r(movlps, var, reg) #define movlps_r2m(reg, var) sse_r2m(movlps, reg, var) #define movss_m2r(var, reg) sse_m2r(movss, var, reg) #define movss_r2m(reg, var) sse_r2m(movss, reg, var) #define movss_r2r(regs, regd) sse_r2r(movss, regs, regd) #define shufps_m2r(var, reg, index) sse_m2ri(shufps, var, reg, index) #define shufps_r2r(regs, regd, index) sse_r2ri(shufps, regs, regd, index) #define cvtpi2ps_m2r(var, xmmreg) sse_m2r(cvtpi2ps, var, xmmreg) #define cvtpi2ps_r2r(mmreg, xmmreg) sse_r2r(cvtpi2ps, mmreg, xmmreg) #define cvtps2pi_m2r(var, mmreg) sse_m2r(cvtps2pi, var, mmreg) #define cvtps2pi_r2r(xmmreg, mmreg) sse_r2r(cvtps2pi, mmreg, xmmreg) #define cvttps2pi_m2r(var, mmreg) sse_m2r(cvttps2pi, var, mmreg) #define cvttps2pi_r2r(xmmreg, mmreg) sse_r2r(cvttps2pi, mmreg, xmmreg) #define cvtsi2ss_m2r(var, xmmreg) sse_m2r(cvtsi2ss, var, xmmreg) #define cvtsi2ss_r2r(reg, xmmreg) sse_r2r(cvtsi2ss, reg, xmmreg) #define cvtss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) #define cvtss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) #define cvttss2si_m2r(var, reg) sse_m2r(cvtss2si, var, reg) #define cvttss2si_r2r(xmmreg, reg) sse_r2r(cvtss2si, xmmreg, reg) #define movmskps(xmmreg, reg) \ __asm__ __volatile__ ("movmskps %" #xmmreg ", %" #reg) #define addps_m2r(var, reg) sse_m2r(addps, var, reg) #define addps_r2r(regs, regd) sse_r2r(addps, regs, regd) #define addss_m2r(var, reg) sse_m2r(addss, var, reg) #define addss_r2r(regs, regd) sse_r2r(addss, regs, regd) #define subps_m2r(var, reg) sse_m2r(subps, var, reg) #define subps_r2r(regs, regd) sse_r2r(subps, regs, regd) #define subss_m2r(var, reg) sse_m2r(subss, var, reg) #define subss_r2r(regs, regd) sse_r2r(subss, regs, regd) #define mulps_m2r(var, reg) sse_m2r(mulps, var, reg) #define mulps_r2r(regs, regd) sse_r2r(mulps, regs, regd) #define mulss_m2r(var, reg) sse_m2r(mulss, var, reg) #define mulss_r2r(regs, regd) sse_r2r(mulss, regs, regd) #define divps_m2r(var, reg) sse_m2r(divps, var, reg) #define divps_r2r(regs, regd) sse_r2r(divps, regs, regd) #define divss_m2r(var, reg) sse_m2r(divss, var, reg) #define divss_r2r(regs, regd) sse_r2r(divss, regs, regd) #define rcpps_m2r(var, reg) sse_m2r(rcpps, var, reg) #define rcpps_r2r(regs, regd) sse_r2r(rcpps, regs, regd) #define rcpss_m2r(var, reg) sse_m2r(rcpss, var, reg) #define rcpss_r2r(regs, regd) sse_r2r(rcpss, regs, regd) #define rsqrtps_m2r(var, reg) sse_m2r(rsqrtps, var, reg) #define rsqrtps_r2r(regs, regd) sse_r2r(rsqrtps, regs, regd) #define rsqrtss_m2r(var, reg) sse_m2r(rsqrtss, var, reg) #define rsqrtss_r2r(regs, regd) sse_r2r(rsqrtss, regs, regd) #define sqrtps_m2r(var, reg) sse_m2r(sqrtps, var, reg) #define sqrtps_r2r(regs, regd) sse_r2r(sqrtps, regs, regd) #define sqrtss_m2r(var, reg) sse_m2r(sqrtss, var, reg) #define sqrtss_r2r(regs, regd) sse_r2r(sqrtss, regs, regd) #define andps_m2r(var, reg) sse_m2r(andps, var, reg) #define andps_r2r(regs, regd) sse_r2r(andps, regs, regd) #define andnps_m2r(var, reg) sse_m2r(andnps, var, reg) #define andnps_r2r(regs, regd) sse_r2r(andnps, regs, regd) #define orps_m2r(var, reg) sse_m2r(orps, var, reg) #define orps_r2r(regs, regd) sse_r2r(orps, regs, regd) #define xorps_m2r(var, reg) sse_m2r(xorps, var, reg) #define xorps_r2r(regs, regd) sse_r2r(xorps, regs, regd) #define maxps_m2r(var, reg) sse_m2r(maxps, var, reg) #define maxps_r2r(regs, regd) sse_r2r(maxps, regs, regd) #define maxss_m2r(var, reg) sse_m2r(maxss, var, reg) #define maxss_r2r(regs, regd) sse_r2r(maxss, regs, regd) #define minps_m2r(var, reg) sse_m2r(minps, var, reg) #define minps_r2r(regs, regd) sse_r2r(minps, regs, regd) #define minss_m2r(var, reg) sse_m2r(minss, var, reg) #define minss_r2r(regs, regd) sse_r2r(minss, regs, regd) #define cmpps_m2r(var, reg, op) sse_m2ri(cmpps, var, reg, op) #define cmpps_r2r(regs, regd, op) sse_r2ri(cmpps, regs, regd, op) #define cmpeqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 0) #define cmpeqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 0) #define cmpltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 1) #define cmpltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 1) #define cmpleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 2) #define cmpleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 2) #define cmpunordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 3) #define cmpunordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 3) #define cmpneqps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 4) #define cmpneqps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 4) #define cmpnltps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 5) #define cmpnltps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 5) #define cmpnleps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 6) #define cmpnleps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 6) #define cmpordps_m2r(var, reg) sse_m2ri(cmpps, var, reg, 7) #define cmpordps_r2r(regs, regd) sse_r2ri(cmpps, regs, regd, 7) #define cmpss_m2r(var, reg, op) sse_m2ri(cmpss, var, reg, op) #define cmpss_r2r(regs, regd, op) sse_r2ri(cmpss, regs, regd, op) #define cmpeqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 0) #define cmpeqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 0) #define cmpltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 1) #define cmpltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 1) #define cmpless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 2) #define cmpless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 2) #define cmpunordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 3) #define cmpunordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 3) #define cmpneqss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 4) #define cmpneqss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 4) #define cmpnltss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 5) #define cmpnltss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 5) #define cmpnless_m2r(var, reg) sse_m2ri(cmpss, var, reg, 6) #define cmpnless_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 6) #define cmpordss_m2r(var, reg) sse_m2ri(cmpss, var, reg, 7) #define cmpordss_r2r(regs, regd) sse_r2ri(cmpss, regs, regd, 7) #define comiss_m2r(var, reg) sse_m2r(comiss, var, reg) #define comiss_r2r(regs, regd) sse_r2r(comiss, regs, regd) #define ucomiss_m2r(var, reg) sse_m2r(ucomiss, var, reg) #define ucomiss_r2r(regs, regd) sse_r2r(ucomiss, regs, regd) #define unpcklps_m2r(var, reg) sse_m2r(unpcklps, var, reg) #define unpcklps_r2r(regs, regd) sse_r2r(unpcklps, regs, regd) #define unpckhps_m2r(var, reg) sse_m2r(unpckhps, var, reg) #define unpckhps_r2r(regs, regd) sse_r2r(unpckhps, regs, regd) #define fxrstor(mem) \ __asm__ __volatile__ ("fxrstor %0" \ : /* nothing */ \ : "X" (mem)) #define fxsave(mem) \ __asm__ __volatile__ ("fxsave %0" \ : /* nothing */ \ : "X" (mem)) #define stmxcsr(mem) \ __asm__ __volatile__ ("stmxcsr %0" \ : /* nothing */ \ : "X" (mem)) #define ldmxcsr(mem) \ __asm__ __volatile__ ("ldmxcsr %0" \ : /* nothing */ \ : "X" (mem)) ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/mpeg2.h����������������������������������������������0000644�0001750�0001750�00000014475�14647725152�020430� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mpeg2.h * Copyright (C) 2000-2004 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MPEG2_H #define MPEG2_H #define MPEG2_VERSION(a,b,c) (((a)<<16)|((b)<<8)|(c)) #define MPEG2_RELEASE MPEG2_VERSION (0, 4, 1) /* 0.4.1 */ #define SEQ_FLAG_MPEG2 1 #define SEQ_FLAG_CONSTRAINED_PARAMETERS 2 #define SEQ_FLAG_PROGRESSIVE_SEQUENCE 4 #define SEQ_FLAG_LOW_DELAY 8 #define SEQ_FLAG_COLOUR_DESCRIPTION 16 #define SEQ_MASK_VIDEO_FORMAT 0xe0 #define SEQ_VIDEO_FORMAT_COMPONENT 0 #define SEQ_VIDEO_FORMAT_PAL 0x20 #define SEQ_VIDEO_FORMAT_NTSC 0x40 #define SEQ_VIDEO_FORMAT_SECAM 0x60 #define SEQ_VIDEO_FORMAT_MAC 0x80 #define SEQ_VIDEO_FORMAT_UNSPECIFIED 0xa0 typedef struct mpeg2_sequence_s { unsigned int width, height; unsigned int chroma_width, chroma_height; unsigned int byte_rate; unsigned int vbv_buffer_size; uint32_t flags; unsigned int picture_width, picture_height; unsigned int display_width, display_height; unsigned int pixel_width, pixel_height; unsigned int frame_period; uint8_t profile_level_id; uint8_t colour_primaries; uint8_t transfer_characteristics; uint8_t matrix_coefficients; } mpeg2_sequence_t; #define GOP_FLAG_DROP_FRAME 1 #define GOP_FLAG_BROKEN_LINK 2 #define GOP_FLAG_CLOSED_GOP 4 typedef struct mpeg2_gop_s { uint8_t hours; uint8_t minutes; uint8_t seconds; uint8_t pictures; uint32_t flags; } mpeg2_gop_t; #define PIC_MASK_CODING_TYPE 7 #define PIC_FLAG_CODING_TYPE_I 1 #define PIC_FLAG_CODING_TYPE_P 2 #define PIC_FLAG_CODING_TYPE_B 3 #define PIC_FLAG_CODING_TYPE_D 4 #define PIC_FLAG_TOP_FIELD_FIRST 8 #define PIC_FLAG_PROGRESSIVE_FRAME 16 #define PIC_FLAG_COMPOSITE_DISPLAY 32 #define PIC_FLAG_SKIP 64 #define PIC_FLAG_TAGS 128 #define PIC_MASK_COMPOSITE_DISPLAY 0xfffff000 typedef struct mpeg2_picture_s { unsigned int temporal_reference; unsigned int nb_fields; uint32_t tag, tag2; uint32_t flags; struct { int x, y; } display_offset[3]; } mpeg2_picture_t; typedef struct mpeg2_fbuf_s { uint8_t * buf[3]; void * id; } mpeg2_fbuf_t; typedef struct mpeg2_info_s { const mpeg2_sequence_t * sequence; const mpeg2_gop_t * gop; const mpeg2_picture_t * current_picture; const mpeg2_picture_t * current_picture_2nd; const mpeg2_fbuf_t * current_fbuf; const mpeg2_picture_t * display_picture; const mpeg2_picture_t * display_picture_2nd; const mpeg2_fbuf_t * display_fbuf; const mpeg2_fbuf_t * discard_fbuf; const uint8_t * user_data; unsigned int user_data_len; } mpeg2_info_t; typedef struct mpeg2dec_s mpeg2dec_t; typedef struct mpeg2_decoder_s mpeg2_decoder_t; typedef enum { STATE_BUFFER = 0, STATE_SEQUENCE = 1, STATE_SEQUENCE_REPEATED = 2, STATE_SEQUENCE_MODIFIED = 3, STATE_GOP = 4, STATE_PICTURE = 5, STATE_SLICE_1ST = 6, STATE_PICTURE_2ND = 7, STATE_SLICE = 8, STATE_END = 9, STATE_INVALID = 10, STATE_INVALID_END = 11 } mpeg2_state_t; typedef struct mpeg2_convert_init_s { unsigned int id_size; unsigned int buf_size[3]; void (* start) (void * id, const mpeg2_fbuf_t * fbuf, const mpeg2_picture_t * picture, const mpeg2_gop_t * gop); void (* copy) (void * id, uint8_t * const * src, unsigned int v_offset); } mpeg2_convert_init_t; typedef enum { MPEG2_CONVERT_SET = 0, MPEG2_CONVERT_STRIDE = 1, MPEG2_CONVERT_START = 2 } mpeg2_convert_stage_t; typedef int mpeg2_convert_t (int stage, void * id, const mpeg2_sequence_t * sequence, int stride, uint32_t accel, void * arg, mpeg2_convert_init_t * result); int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg); int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride); void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id); void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf); #define MPEG2_ACCEL_X86_MMX 1 #define MPEG2_ACCEL_X86_3DNOW 2 #define MPEG2_ACCEL_X86_MMXEXT 4 #define MPEG2_ACCEL_X86_SSE2 8 #define MPEG2_ACCEL_X86_SSE3 16 #define MPEG2_ACCEL_PPC_ALTIVEC 1 #define MPEG2_ACCEL_ALPHA 1 #define MPEG2_ACCEL_ALPHA_MVI 2 #define MPEG2_ACCEL_SPARC_VIS 1 #define MPEG2_ACCEL_SPARC_VIS2 2 #define MPEG2_ACCEL_DETECT 0x80000000 uint32_t mpeg2_accel (uint32_t accel); mpeg2dec_t * mpeg2_init (void); const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec); void mpeg2_close (mpeg2dec_t * mpeg2dec); void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end); int mpeg2_getpos (mpeg2dec_t * mpeg2dec); mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec); void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset); void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip); void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end); void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2); void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3], uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3]); void mpeg2_slice (mpeg2_decoder_t * decoder, int code, const uint8_t * buffer); int mpeg2_guess_aspect (const mpeg2_sequence_t * sequence, unsigned int * pixel_width, unsigned int * pixel_height); typedef enum { MPEG2_ALLOC_MPEG2DEC = 0, MPEG2_ALLOC_CHUNK = 1, MPEG2_ALLOC_YUV = 2, MPEG2_ALLOC_CONVERT_ID = 3, MPEG2_ALLOC_CONVERTED = 4 } mpeg2_alloc_t; void * mpeg2_malloc (unsigned size, mpeg2_alloc_t reason); void mpeg2_free (void * buf); void mpeg2_malloc_hooks (void * malloc (unsigned, mpeg2_alloc_t), int free (void *)); #endif /* MPEG2_H */ ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/tendra.h���������������������������������������������0000644�0001750�0001750�00000002377�14647725152�020671� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * tendra.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #pragma TenDRA begin #pragma TenDRA longlong type warning #ifdef TenDRA_check #pragma TenDRA conversion analysis (pointer-int explicit) off #pragma TenDRA implicit function declaration off /* avoid the "No declarations in translation unit" problem */ int TenDRA; #endif /* TenDRA_check */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/attributes.h�����������������������������������������0000644�0001750�0001750�00000002356�14647725152�021577� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * attributes.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* use gcc attribs to align critical data structures */ #include <xine/attributes.h> #ifdef HAVE_BUILTIN_EXPECT #define likely(x) __builtin_expect ((x) != 0, 1) #define unlikely(x) __builtin_expect ((x) != 0, 0) #else #define likely(x) (x) #define unlikely(x) (x) #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/vis.h������������������������������������������������0000644�0001750�0001750�00000027034�14647725152�020212� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * vis.h * Copyright (C) 2003 David S. Miller <davem@redhat.com> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* You may be asking why I hard-code the instruction opcodes and don't * use the normal VIS assembler mnenomics for the VIS instructions. * * The reason is that Sun, in their infinite wisdom, decided that a binary * using a VIS instruction will cause it to be marked (in the ELF headers) * as doing so, and this prevents the OS from loading such binaries if the * current cpu doesn't have VIS. There is no way to easily override this * behavior of the assembler that I am aware of. * * This totally defeats what libmpeg2 is trying to do which is allow a * single binary to be created, and then detect the availability of VIS * at runtime. * * I'm not saying that tainting the binary by default is bad, rather I'm * saying that not providing a way to override this easily unnecessarily * ties people's hands. * * Thus, we do the opcode encoding by hand and output 32-bit words in * the assembler to keep the binary from becoming tainted. */ #define vis_opc_base ((0x1 << 31) | (0x36 << 19)) #define vis_opf(X) ((X) << 5) #define vis_sreg(X) (X) #define vis_dreg(X) (((X)&0x1f)|((X)>>5)) #define vis_rs1_s(X) (vis_sreg(X) << 14) #define vis_rs1_d(X) (vis_dreg(X) << 14) #define vis_rs2_s(X) (vis_sreg(X) << 0) #define vis_rs2_d(X) (vis_dreg(X) << 0) #define vis_rd_s(X) (vis_sreg(X) << 25) #define vis_rd_d(X) (vis_dreg(X) << 25) #define vis_ss2s(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rs2_s(rs2) | \ vis_rd_s(rd))) #define vis_dd2d(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_d(rs1) | \ vis_rs2_d(rs2) | \ vis_rd_d(rd))) #define vis_ss2d(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rs2_s(rs2) | \ vis_rd_d(rd))) #define vis_sd2d(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rs2_d(rs2) | \ vis_rd_d(rd))) #define vis_d2s(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_d(rs2) | \ vis_rd_s(rd))) #define vis_s2d(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_s(rs2) | \ vis_rd_d(rd))) #define vis_d12d(opf,rs1,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_d(rs1) | \ vis_rd_d(rd))) #define vis_d22d(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_d(rs2) | \ vis_rd_d(rd))) #define vis_s12s(opf,rs1,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rd_s(rd))) #define vis_s22s(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_s(rs2) | \ vis_rd_s(rd))) #define vis_s(opf,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rd_s(rd))) #define vis_d(opf,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rd_d(rd))) #define vis_r2m(op,rd,mem) \ __asm__ __volatile__ (#op "\t%%f" #rd ", [%0]" : : "r" (&(mem)) ) #define vis_r2m_2(op,rd,mem1,mem2) \ __asm__ __volatile__ (#op "\t%%f" #rd ", [%0 + %1]" : : "r" (mem1), "r" (mem2) ) #define vis_m2r(op,mem,rd) \ __asm__ __volatile__ (#op "\t[%0], %%f" #rd : : "r" (&(mem)) ) #define vis_m2r_2(op,mem1,mem2,rd) \ __asm__ __volatile__ (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) ) static inline void vis_set_gsr(unsigned int _val) { register unsigned int val asm("g1"); val = _val; __asm__ __volatile__(".word 0xa7804000" : : "r" (val)); } #define VIS_GSR_ALIGNADDR_MASK 0x0000007 #define VIS_GSR_ALIGNADDR_SHIFT 0 #define VIS_GSR_SCALEFACT_MASK 0x0000078 #define VIS_GSR_SCALEFACT_SHIFT 3 #define vis_ld32(mem,rs1) vis_m2r(ld, mem, rs1) #define vis_ld32_2(mem1,mem2,rs1) vis_m2r_2(ld, mem1, mem2, rs1) #define vis_st32(rs1,mem) vis_r2m(st, rs1, mem) #define vis_st32_2(rs1,mem1,mem2) vis_r2m_2(st, rs1, mem1, mem2) #define vis_ld64(mem,rs1) vis_m2r(ldd, mem, rs1) #define vis_ld64_2(mem1,mem2,rs1) vis_m2r_2(ldd, mem1, mem2, rs1) #define vis_st64(rs1,mem) vis_r2m(std, rs1, mem) #define vis_st64_2(rs1,mem1,mem2) vis_r2m_2(std, rs1, mem1, mem2) #define vis_ldblk(mem, rd) \ do { register void *__mem asm("g1"); \ __mem = &(mem); \ __asm__ __volatile__(".word 0xc1985e00 | %1" \ : \ : "r" (__mem), \ "i" (vis_rd_d(rd)) \ : "memory"); \ } while (0) #define vis_stblk(rd, mem) \ do { register void *__mem asm("g1"); \ __mem = &(mem); \ __asm__ __volatile__(".word 0xc1b85e00 | %1" \ : \ : "r" (__mem), \ "i" (vis_rd_d(rd)) \ : "memory"); \ } while (0) #define vis_membar_storestore() \ __asm__ __volatile__(".word 0x8143e008" : : : "memory") #define vis_membar_sync() \ __asm__ __volatile__(".word 0x8143e040" : : : "memory") /* 16 and 32 bit partitioned addition and subtraction. The normal * versions perform 4 16-bit or 2 32-bit additions or subtractions. * The 's' versions perform 2 16-bit or 2 32-bit additions or * subtractions. */ #define vis_padd16(rs1,rs2,rd) vis_dd2d(0x50, rs1, rs2, rd) #define vis_padd16s(rs1,rs2,rd) vis_ss2s(0x51, rs1, rs2, rd) #define vis_padd32(rs1,rs2,rd) vis_dd2d(0x52, rs1, rs2, rd) #define vis_padd32s(rs1,rs2,rd) vis_ss2s(0x53, rs1, rs2, rd) #define vis_psub16(rs1,rs2,rd) vis_dd2d(0x54, rs1, rs2, rd) #define vis_psub16s(rs1,rs2,rd) vis_ss2s(0x55, rs1, rs2, rd) #define vis_psub32(rs1,rs2,rd) vis_dd2d(0x56, rs1, rs2, rd) #define vis_psub32s(rs1,rs2,rd) vis_ss2s(0x57, rs1, rs2, rd) /* Pixel formatting instructions. */ #define vis_pack16(rs2,rd) vis_d2s( 0x3b, rs2, rd) #define vis_pack32(rs1,rs2,rd) vis_dd2d(0x3a, rs1, rs2, rd) #define vis_packfix(rs2,rd) vis_d2s( 0x3d, rs2, rd) #define vis_expand(rs2,rd) vis_s2d( 0x4d, rs2, rd) #define vis_pmerge(rs1,rs2,rd) vis_ss2d(0x4b, rs1, rs2, rd) /* Partitioned multiply instructions. */ #define vis_mul8x16(rs1,rs2,rd) vis_sd2d(0x31, rs1, rs2, rd) #define vis_mul8x16au(rs1,rs2,rd) vis_ss2d(0x33, rs1, rs2, rd) #define vis_mul8x16al(rs1,rs2,rd) vis_ss2d(0x35, rs1, rs2, rd) #define vis_mul8sux16(rs1,rs2,rd) vis_dd2d(0x36, rs1, rs2, rd) #define vis_mul8ulx16(rs1,rs2,rd) vis_dd2d(0x37, rs1, rs2, rd) #define vis_muld8sux16(rs1,rs2,rd) vis_ss2d(0x38, rs1, rs2, rd) #define vis_muld8ulx16(rs1,rs2,rd) vis_ss2d(0x39, rs1, rs2, rd) /* Alignment instructions. */ static inline void *vis_alignaddr(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x18) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(1))); return ptr; } static inline void vis_alignaddr_g0(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x18) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(0))); } static inline void *vis_alignaddrl(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x19) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(1))); return ptr; } static inline void vis_alignaddrl_g0(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x19) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(0))); } #define vis_faligndata(rs1,rs2,rd) vis_dd2d(0x48, rs1, rs2, rd) /* Logical operate instructions. */ #define vis_fzero(rd) vis_d( 0x60, rd) #define vis_fzeros(rd) vis_s( 0x61, rd) #define vis_fone(rd) vis_d( 0x7e, rd) #define vis_fones(rd) vis_s( 0x7f, rd) #define vis_src1(rs1,rd) vis_d12d(0x74, rs1, rd) #define vis_src1s(rs1,rd) vis_s12s(0x75, rs1, rd) #define vis_src2(rs2,rd) vis_d22d(0x78, rs2, rd) #define vis_src2s(rs2,rd) vis_s22s(0x79, rs2, rd) #define vis_not1(rs1,rd) vis_d12d(0x6a, rs1, rd) #define vis_not1s(rs1,rd) vis_s12s(0x6b, rs1, rd) #define vis_not2(rs2,rd) vis_d22d(0x66, rs2, rd) #define vis_not2s(rs2,rd) vis_s22s(0x67, rs2, rd) #define vis_or(rs1,rs2,rd) vis_dd2d(0x7c, rs1, rs2, rd) #define vis_ors(rs1,rs2,rd) vis_ss2s(0x7d, rs1, rs2, rd) #define vis_nor(rs1,rs2,rd) vis_dd2d(0x62, rs1, rs2, rd) #define vis_nors(rs1,rs2,rd) vis_ss2s(0x63, rs1, rs2, rd) #define vis_and(rs1,rs2,rd) vis_dd2d(0x70, rs1, rs2, rd) #define vis_ands(rs1,rs2,rd) vis_ss2s(0x71, rs1, rs2, rd) #define vis_nand(rs1,rs2,rd) vis_dd2d(0x6e, rs1, rs2, rd) #define vis_nands(rs1,rs2,rd) vis_ss2s(0x6f, rs1, rs2, rd) #define vis_xor(rs1,rs2,rd) vis_dd2d(0x6c, rs1, rs2, rd) #define vis_xors(rs1,rs2,rd) vis_ss2s(0x6d, rs1, rs2, rd) #define vis_xnor(rs1,rs2,rd) vis_dd2d(0x72, rs1, rs2, rd) #define vis_xnors(rs1,rs2,rd) vis_ss2s(0x73, rs1, rs2, rd) #define vis_ornot1(rs1,rs2,rd) vis_dd2d(0x7a, rs1, rs2, rd) #define vis_ornot1s(rs1,rs2,rd) vis_ss2s(0x7b, rs1, rs2, rd) #define vis_ornot2(rs1,rs2,rd) vis_dd2d(0x76, rs1, rs2, rd) #define vis_ornot2s(rs1,rs2,rd) vis_ss2s(0x77, rs1, rs2, rd) #define vis_andnot1(rs1,rs2,rd) vis_dd2d(0x68, rs1, rs2, rd) #define vis_andnot1s(rs1,rs2,rd) vis_ss2s(0x69, rs1, rs2, rd) #define vis_andnot2(rs1,rs2,rd) vis_dd2d(0x64, rs1, rs2, rd) #define vis_andnot2s(rs1,rs2,rd) vis_ss2s(0x65, rs1, rs2, rd) /* Pixel component distance. */ #define vis_pdist(rs1,rs2,rd) vis_dd2d(0x3e, rs1, rs2, rd) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/include/mmx.h������������������������������������������������0000644�0001750�0001750�00000024421�14647725152�020207� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mmx.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * The type of an value that fits in an MMX register (note that long * long constant values MUST be suffixed by LL and unsigned long long * values by ULL, lest they be truncated by the compiler) */ typedef union { long long q; /* Quadword (64-bit) value */ unsigned long long uq; /* Unsigned Quadword */ int d[2]; /* 2 Doubleword (32-bit) values */ unsigned int ud[2]; /* 2 Unsigned Doubleword */ short w[4]; /* 4 Word (16-bit) values */ unsigned short uw[4]; /* 4 Unsigned Word */ char b[8]; /* 8 Byte (8-bit) values */ unsigned char ub[8]; /* 8 Unsigned Byte */ float s[2]; /* Single-precision (32-bit) value */ } ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ #define mmx_i2r(op,imm,reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "i" (imm) ) #define mmx_m2r(op,mem,reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "m" (mem)) #define mmx_r2m(op,reg,mem) \ __asm__ __volatile__ (#op " %%" #reg ", %0" \ : "=m" (mem) \ : /* nothing */ ) #define mmx_r2r(op,regs,regd) \ __asm__ __volatile__ (#op " %" #regs ", %" #regd) #define emms() __asm__ __volatile__ ("emms") #define movd_m2r(var,reg) mmx_m2r (movd, var, reg) #define movd_r2m(reg,var) mmx_r2m (movd, reg, var) #define movd_v2r(var,reg) __asm__ __volatile__ ("movd %0, %%" #reg \ : /* nothing */ \ : "rm" (var)) #define movd_r2v(reg,var) __asm__ __volatile__ ("movd %%" #reg ", %0" \ : "=rm" (var) \ : /* nothing */ ) #define movq_m2r(var,reg) mmx_m2r (movq, var, reg) #define movq_r2m(reg,var) mmx_r2m (movq, reg, var) #define movq_r2r(regs,regd) mmx_r2r (movq, regs, regd) #define packssdw_m2r(var,reg) mmx_m2r (packssdw, var, reg) #define packssdw_r2r(regs,regd) mmx_r2r (packssdw, regs, regd) #define packsswb_m2r(var,reg) mmx_m2r (packsswb, var, reg) #define packsswb_r2r(regs,regd) mmx_r2r (packsswb, regs, regd) #define packuswb_m2r(var,reg) mmx_m2r (packuswb, var, reg) #define packuswb_r2r(regs,regd) mmx_r2r (packuswb, regs, regd) #define paddb_m2r(var,reg) mmx_m2r (paddb, var, reg) #define paddb_r2r(regs,regd) mmx_r2r (paddb, regs, regd) #define paddd_m2r(var,reg) mmx_m2r (paddd, var, reg) #define paddd_r2r(regs,regd) mmx_r2r (paddd, regs, regd) #define paddw_m2r(var,reg) mmx_m2r (paddw, var, reg) #define paddw_r2r(regs,regd) mmx_r2r (paddw, regs, regd) #define paddsb_m2r(var,reg) mmx_m2r (paddsb, var, reg) #define paddsb_r2r(regs,regd) mmx_r2r (paddsb, regs, regd) #define paddsw_m2r(var,reg) mmx_m2r (paddsw, var, reg) #define paddsw_r2r(regs,regd) mmx_r2r (paddsw, regs, regd) #define paddusb_m2r(var,reg) mmx_m2r (paddusb, var, reg) #define paddusb_r2r(regs,regd) mmx_r2r (paddusb, regs, regd) #define paddusw_m2r(var,reg) mmx_m2r (paddusw, var, reg) #define paddusw_r2r(regs,regd) mmx_r2r (paddusw, regs, regd) #define pand_m2r(var,reg) mmx_m2r (pand, var, reg) #define pand_r2r(regs,regd) mmx_r2r (pand, regs, regd) #define pandn_m2r(var,reg) mmx_m2r (pandn, var, reg) #define pandn_r2r(regs,regd) mmx_r2r (pandn, regs, regd) #define pcmpeqb_m2r(var,reg) mmx_m2r (pcmpeqb, var, reg) #define pcmpeqb_r2r(regs,regd) mmx_r2r (pcmpeqb, regs, regd) #define pcmpeqd_m2r(var,reg) mmx_m2r (pcmpeqd, var, reg) #define pcmpeqd_r2r(regs,regd) mmx_r2r (pcmpeqd, regs, regd) #define pcmpeqw_m2r(var,reg) mmx_m2r (pcmpeqw, var, reg) #define pcmpeqw_r2r(regs,regd) mmx_r2r (pcmpeqw, regs, regd) #define pcmpgtb_m2r(var,reg) mmx_m2r (pcmpgtb, var, reg) #define pcmpgtb_r2r(regs,regd) mmx_r2r (pcmpgtb, regs, regd) #define pcmpgtd_m2r(var,reg) mmx_m2r (pcmpgtd, var, reg) #define pcmpgtd_r2r(regs,regd) mmx_r2r (pcmpgtd, regs, regd) #define pcmpgtw_m2r(var,reg) mmx_m2r (pcmpgtw, var, reg) #define pcmpgtw_r2r(regs,regd) mmx_r2r (pcmpgtw, regs, regd) #define pmaddwd_m2r(var,reg) mmx_m2r (pmaddwd, var, reg) #define pmaddwd_r2r(regs,regd) mmx_r2r (pmaddwd, regs, regd) #define pmulhw_m2r(var,reg) mmx_m2r (pmulhw, var, reg) #define pmulhw_r2r(regs,regd) mmx_r2r (pmulhw, regs, regd) #define pmullw_m2r(var,reg) mmx_m2r (pmullw, var, reg) #define pmullw_r2r(regs,regd) mmx_r2r (pmullw, regs, regd) #define por_m2r(var,reg) mmx_m2r (por, var, reg) #define por_r2r(regs,regd) mmx_r2r (por, regs, regd) #define pslld_i2r(imm,reg) mmx_i2r (pslld, imm, reg) #define pslld_m2r(var,reg) mmx_m2r (pslld, var, reg) #define pslld_r2r(regs,regd) mmx_r2r (pslld, regs, regd) #define psllq_i2r(imm,reg) mmx_i2r (psllq, imm, reg) #define psllq_m2r(var,reg) mmx_m2r (psllq, var, reg) #define psllq_r2r(regs,regd) mmx_r2r (psllq, regs, regd) #define psllw_i2r(imm,reg) mmx_i2r (psllw, imm, reg) #define psllw_m2r(var,reg) mmx_m2r (psllw, var, reg) #define psllw_r2r(regs,regd) mmx_r2r (psllw, regs, regd) #define psrad_i2r(imm,reg) mmx_i2r (psrad, imm, reg) #define psrad_m2r(var,reg) mmx_m2r (psrad, var, reg) #define psrad_r2r(regs,regd) mmx_r2r (psrad, regs, regd) #define psraw_i2r(imm,reg) mmx_i2r (psraw, imm, reg) #define psraw_m2r(var,reg) mmx_m2r (psraw, var, reg) #define psraw_r2r(regs,regd) mmx_r2r (psraw, regs, regd) #define psrld_i2r(imm,reg) mmx_i2r (psrld, imm, reg) #define psrld_m2r(var,reg) mmx_m2r (psrld, var, reg) #define psrld_r2r(regs,regd) mmx_r2r (psrld, regs, regd) #define psrlq_i2r(imm,reg) mmx_i2r (psrlq, imm, reg) #define psrlq_m2r(var,reg) mmx_m2r (psrlq, var, reg) #define psrlq_r2r(regs,regd) mmx_r2r (psrlq, regs, regd) #define psrlw_i2r(imm,reg) mmx_i2r (psrlw, imm, reg) #define psrlw_m2r(var,reg) mmx_m2r (psrlw, var, reg) #define psrlw_r2r(regs,regd) mmx_r2r (psrlw, regs, regd) #define psubb_m2r(var,reg) mmx_m2r (psubb, var, reg) #define psubb_r2r(regs,regd) mmx_r2r (psubb, regs, regd) #define psubd_m2r(var,reg) mmx_m2r (psubd, var, reg) #define psubd_r2r(regs,regd) mmx_r2r (psubd, regs, regd) #define psubw_m2r(var,reg) mmx_m2r (psubw, var, reg) #define psubw_r2r(regs,regd) mmx_r2r (psubw, regs, regd) #define psubsb_m2r(var,reg) mmx_m2r (psubsb, var, reg) #define psubsb_r2r(regs,regd) mmx_r2r (psubsb, regs, regd) #define psubsw_m2r(var,reg) mmx_m2r (psubsw, var, reg) #define psubsw_r2r(regs,regd) mmx_r2r (psubsw, regs, regd) #define psubusb_m2r(var,reg) mmx_m2r (psubusb, var, reg) #define psubusb_r2r(regs,regd) mmx_r2r (psubusb, regs, regd) #define psubusw_m2r(var,reg) mmx_m2r (psubusw, var, reg) #define psubusw_r2r(regs,regd) mmx_r2r (psubusw, regs, regd) #define punpckhbw_m2r(var,reg) mmx_m2r (punpckhbw, var, reg) #define punpckhbw_r2r(regs,regd) mmx_r2r (punpckhbw, regs, regd) #define punpckhdq_m2r(var,reg) mmx_m2r (punpckhdq, var, reg) #define punpckhdq_r2r(regs,regd) mmx_r2r (punpckhdq, regs, regd) #define punpckhwd_m2r(var,reg) mmx_m2r (punpckhwd, var, reg) #define punpckhwd_r2r(regs,regd) mmx_r2r (punpckhwd, regs, regd) #define punpcklbw_m2r(var,reg) mmx_m2r (punpcklbw, var, reg) #define punpcklbw_r2r(regs,regd) mmx_r2r (punpcklbw, regs, regd) #define punpckldq_m2r(var,reg) mmx_m2r (punpckldq, var, reg) #define punpckldq_r2r(regs,regd) mmx_r2r (punpckldq, regs, regd) #define punpcklwd_m2r(var,reg) mmx_m2r (punpcklwd, var, reg) #define punpcklwd_r2r(regs,regd) mmx_r2r (punpcklwd, regs, regd) #define pxor_m2r(var,reg) mmx_m2r (pxor, var, reg) #define pxor_r2r(regs,regd) mmx_r2r (pxor, regs, regd) /* 3DNOW extensions */ #define pavgusb_m2r(var,reg) mmx_m2r (pavgusb, var, reg) #define pavgusb_r2r(regs,regd) mmx_r2r (pavgusb, regs, regd) /* AMD MMX extensions - also available in intel SSE */ #define mmx_m2ri(op,mem,reg,imm) \ __asm__ __volatile__ (#op " %1, %0, %%" #reg \ : /* nothing */ \ : "m" (mem), "i" (imm)) #define mmx_r2ri(op,regs,regd,imm) \ __asm__ __volatile__ (#op " %0, %%" #regs ", %%" #regd \ : /* nothing */ \ : "i" (imm) ) #define mmx_fetch(mem,hint) \ __asm__ __volatile__ ("prefetch" #hint " %0" \ : /* nothing */ \ : "m" (mem)) #define maskmovq(regs,maskreg) mmx_r2ri (maskmovq, regs, maskreg) #define movntq_r2m(mmreg,var) mmx_r2m (movntq, mmreg, var) #define pavgb_m2r(var,reg) mmx_m2r (pavgb, var, reg) #define pavgb_r2r(regs,regd) mmx_r2r (pavgb, regs, regd) #define pavgw_m2r(var,reg) mmx_m2r (pavgw, var, reg) #define pavgw_r2r(regs,regd) mmx_r2r (pavgw, regs, regd) #define pextrw_r2r(mmreg,reg,imm) mmx_r2ri (pextrw, mmreg, reg, imm) #define pinsrw_r2r(reg,mmreg,imm) mmx_r2ri (pinsrw, reg, mmreg, imm) #define pmaxsw_m2r(var,reg) mmx_m2r (pmaxsw, var, reg) #define pmaxsw_r2r(regs,regd) mmx_r2r (pmaxsw, regs, regd) #define pmaxub_m2r(var,reg) mmx_m2r (pmaxub, var, reg) #define pmaxub_r2r(regs,regd) mmx_r2r (pmaxub, regs, regd) #define pminsw_m2r(var,reg) mmx_m2r (pminsw, var, reg) #define pminsw_r2r(regs,regd) mmx_r2r (pminsw, regs, regd) #define pminub_m2r(var,reg) mmx_m2r (pminub, var, reg) #define pminub_r2r(regs,regd) mmx_r2r (pminub, regs, regd) #define pmovmskb(mmreg,reg) \ __asm__ __volatile__ ("movmskps %" #mmreg ", %" #reg) #define pmulhuw_m2r(var,reg) mmx_m2r (pmulhuw, var, reg) #define pmulhuw_r2r(regs,regd) mmx_r2r (pmulhuw, regs, regd) #define prefetcht0(mem) mmx_fetch (mem, t0) #define prefetcht1(mem) mmx_fetch (mem, t1) #define prefetcht2(mem) mmx_fetch (mem, t2) #define prefetchnta(mem) mmx_fetch (mem, nta) #define psadbw_m2r(var,reg) mmx_m2r (psadbw, var, reg) #define psadbw_r2r(regs,regd) mmx_r2r (psadbw, regs, regd) #define pshufw_m2r(var,reg,imm) mmx_m2ri(pshufw, var, reg, imm) #define pshufw_r2r(regs,regd,imm) mmx_r2ri(pshufw, regs, regd, imm) #define sfence() __asm__ __volatile__ ("sfence\n\t") �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/����������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�017310� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/rgb_mmx.c�������������������������������������������0000644�0001750�0001750�00000023170�14647725152�021112� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * rgb_mmx.c * Copyright (C) 2000-2003 Silicon Integrated System Corp. * All Rights Reserved. * * Author: Olie Lho <ollie@sis.com.tw> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_X86 #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include "mpeg2.h" #include "mpeg2convert.h" #include "convert_internal.h" #include <xine/attributes.h> #include "mmx.h" #define CPU_MMXEXT 0 #define CPU_MMX 1 /* CPU_MMXEXT/CPU_MMX adaptation layer */ #define movntq(src,dest) \ do { \ if (cpu == CPU_MMXEXT) \ movntq_r2m (src, dest); \ else \ movq_r2m (src, dest); \ } while (0) static inline void mmx_yuv2rgb (uint8_t * py, uint8_t * pu, uint8_t * pv) { static mmx_t mmx_80w = {0x0080008000800080LL}; static mmx_t mmx_U_green = {0xf37df37df37df37dLL}; static mmx_t mmx_U_blue = {0x4093409340934093LL}; static mmx_t mmx_V_red = {0x3312331233123312LL}; static mmx_t mmx_V_green = {0xe5fce5fce5fce5fcLL}; static mmx_t mmx_10w = {0x1010101010101010LL}; static mmx_t mmx_00ffw = {0x00ff00ff00ff00ffLL}; static mmx_t mmx_Y_coeff = {0x253f253f253f253fLL}; movd_m2r (*pu, mm0); /* mm0 = 00 00 00 00 u3 u2 u1 u0 */ movd_m2r (*pv, mm1); /* mm1 = 00 00 00 00 v3 v2 v1 v0 */ movq_m2r (*py, mm6); /* mm6 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ pxor_r2r (mm4, mm4); /* mm4 = 0 */ /* XXX might do cache preload for image here */ /* * Do the multiply part of the conversion for even and odd pixels * register usage: * mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels * mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels * mm6 -> Y even, mm7 -> Y odd */ punpcklbw_r2r (mm4, mm0); /* mm0 = u3 u2 u1 u0 */ punpcklbw_r2r (mm4, mm1); /* mm1 = v3 v2 v1 v0 */ psubsw_m2r (mmx_80w, mm0); /* u -= 128 */ psubsw_m2r (mmx_80w, mm1); /* v -= 128 */ psllw_i2r (3, mm0); /* promote precision */ psllw_i2r (3, mm1); /* promote precision */ movq_r2r (mm0, mm2); /* mm2 = u3 u2 u1 u0 */ movq_r2r (mm1, mm3); /* mm3 = v3 v2 v1 v0 */ pmulhw_m2r (mmx_U_green, mm2); /* mm2 = u * u_green */ pmulhw_m2r (mmx_V_green, mm3); /* mm3 = v * v_green */ pmulhw_m2r (mmx_U_blue, mm0); /* mm0 = chroma_b */ pmulhw_m2r (mmx_V_red, mm1); /* mm1 = chroma_r */ paddsw_r2r (mm3, mm2); /* mm2 = chroma_g */ psubusb_m2r (mmx_10w, mm6); /* Y -= 16 */ movq_r2r (mm6, mm7); /* mm7 = Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 */ pand_m2r (mmx_00ffw, mm6); /* mm6 = Y6 Y4 Y2 Y0 */ psrlw_i2r (8, mm7); /* mm7 = Y7 Y5 Y3 Y1 */ psllw_i2r (3, mm6); /* promote precision */ psllw_i2r (3, mm7); /* promote precision */ pmulhw_m2r (mmx_Y_coeff, mm6); /* mm6 = luma_rgb even */ pmulhw_m2r (mmx_Y_coeff, mm7); /* mm7 = luma_rgb odd */ /* * Do the addition part of the conversion for even and odd pixels * register usage: * mm0 -> Cblue, mm1 -> Cred, mm2 -> Cgreen even pixels * mm3 -> Cblue, mm4 -> Cred, mm5 -> Cgreen odd pixels * mm6 -> Y even, mm7 -> Y odd */ movq_r2r (mm0, mm3); /* mm3 = chroma_b */ movq_r2r (mm1, mm4); /* mm4 = chroma_r */ movq_r2r (mm2, mm5); /* mm5 = chroma_g */ paddsw_r2r (mm6, mm0); /* mm0 = B6 B4 B2 B0 */ paddsw_r2r (mm7, mm3); /* mm3 = B7 B5 B3 B1 */ paddsw_r2r (mm6, mm1); /* mm1 = R6 R4 R2 R0 */ paddsw_r2r (mm7, mm4); /* mm4 = R7 R5 R3 R1 */ paddsw_r2r (mm6, mm2); /* mm2 = G6 G4 G2 G0 */ paddsw_r2r (mm7, mm5); /* mm5 = G7 G5 G3 G1 */ packuswb_r2r (mm0, mm0); /* saturate to 0-255 */ packuswb_r2r (mm1, mm1); /* saturate to 0-255 */ packuswb_r2r (mm2, mm2); /* saturate to 0-255 */ packuswb_r2r (mm3, mm3); /* saturate to 0-255 */ packuswb_r2r (mm4, mm4); /* saturate to 0-255 */ packuswb_r2r (mm5, mm5); /* saturate to 0-255 */ punpcklbw_r2r (mm3, mm0); /* mm0 = B7 B6 B5 B4 B3 B2 B1 B0 */ punpcklbw_r2r (mm4, mm1); /* mm1 = R7 R6 R5 R4 R3 R2 R1 R0 */ punpcklbw_r2r (mm5, mm2); /* mm2 = G7 G6 G5 G4 G3 G2 G1 G0 */ } static inline void mmx_unpack_16rgb (uint8_t * image, const int cpu) { static mmx_t mmx_bluemask = {0xf8f8f8f8f8f8f8f8LL}; static mmx_t mmx_greenmask = {0xfcfcfcfcfcfcfcfcLL}; static mmx_t mmx_redmask = {0xf8f8f8f8f8f8f8f8LL}; /* * convert RGB plane to RGB 16 bits * mm0 -> B, mm1 -> R, mm2 -> G * mm4 -> GB, mm5 -> AR pixel 4-7 * mm6 -> GB, mm7 -> AR pixel 0-3 */ pand_m2r (mmx_bluemask, mm0); /* mm0 = b7b6b5b4b3______ */ pand_m2r (mmx_greenmask, mm2); /* mm2 = g7g6g5g4g3g2____ */ pand_m2r (mmx_redmask, mm1); /* mm1 = r7r6r5r4r3______ */ psrlq_i2r (3, mm0); /* mm0 = ______b7b6b5b4b3 */ pxor_r2r (mm4, mm4); /* mm4 = 0 */ movq_r2r (mm0, mm5); /* mm5 = ______b7b6b5b4b3 */ movq_r2r (mm2, mm7); /* mm7 = g7g6g5g4g3g2____ */ punpcklbw_r2r (mm4, mm2); punpcklbw_r2r (mm1, mm0); psllq_i2r (3, mm2); por_r2r (mm2, mm0); movntq (mm0, *image); punpckhbw_r2r (mm4, mm7); punpckhbw_r2r (mm1, mm5); psllq_i2r (3, mm7); por_r2r (mm7, mm5); movntq (mm5, *(image+8)); } static inline void mmx_unpack_32rgb (uint8_t * image, const int cpu) { /* * convert RGB plane to RGB packed format, * mm0 -> B, mm1 -> R, mm2 -> G, mm3 -> 0, * mm4 -> GB, mm5 -> AR pixel 4-7, * mm6 -> GB, mm7 -> AR pixel 0-3 */ pxor_r2r (mm3, mm3); movq_r2r (mm0, mm6); movq_r2r (mm1, mm7); movq_r2r (mm0, mm4); movq_r2r (mm1, mm5); punpcklbw_r2r (mm2, mm6); punpcklbw_r2r (mm3, mm7); punpcklwd_r2r (mm7, mm6); movntq (mm6, *image); movq_r2r (mm0, mm6); punpcklbw_r2r (mm2, mm6); punpckhwd_r2r (mm7, mm6); movntq (mm6, *(image+8)); punpckhbw_r2r (mm2, mm4); punpckhbw_r2r (mm3, mm5); punpcklwd_r2r (mm5, mm4); movntq (mm4, *(image+16)); movq_r2r (mm0, mm4); punpckhbw_r2r (mm2, mm4); punpckhwd_r2r (mm5, mm4); movntq (mm4, *(image+24)); } static inline void rgb16 (void * const _id, uint8_t * const * src, const unsigned int v_offset, const int cpu) { convert_rgb_t * const id = (convert_rgb_t *) _id; uint8_t * dst; uint8_t * py, * pu, * pv; int i, j; dst = id->rgb_ptr + id->rgb_slice * v_offset; py = src[0]; pu = src[1]; pv = src[2]; i = 16; do { j = id->width; do { mmx_yuv2rgb (py, pu, pv); mmx_unpack_16rgb (dst, cpu); py += 8; pu += 4; pv += 4; dst += 16; } while (--j); dst += id->rgb_increm; py += id->y_increm; if (--i == id->field) { dst = id->rgb_ptr + id->rgb_slice * (v_offset + 1); py = src[0] + id->y_stride_frame; pu = src[1] + id->uv_stride_frame; pv = src[2] + id->uv_stride_frame; } else if (! (i & id->chroma420)) { pu += id->uv_increm; pv += id->uv_increm; } else { pu -= id->uv_stride_frame; pv -= id->uv_stride_frame; } } while (i); } static inline void argb32 (void * const _id, uint8_t * const * src, const unsigned int v_offset, const int cpu) { convert_rgb_t * const id = (convert_rgb_t *) _id; uint8_t * dst; uint8_t * py, * pu, * pv; int i, j; dst = id->rgb_ptr + id->rgb_slice * v_offset; py = src[0]; pu = src[1]; pv = src[2]; i = 16; do { j = id->width; do { mmx_yuv2rgb (py, pu, pv); mmx_unpack_32rgb (dst, cpu); py += 8; pu += 4; pv += 4; dst += 32; } while (--j); dst += id->rgb_increm; py += id->y_increm; if (--i == id->field) { dst = id->rgb_ptr + id->rgb_slice * (v_offset + 1); py = src[0] + id->y_stride_frame; pu = src[1] + id->uv_stride_frame; pv = src[2] + id->uv_stride_frame; } else if (! (i & id->chroma420)) { pu += id->uv_increm; pv += id->uv_increm; } else { pu -= id->uv_stride_frame; pv -= id->uv_stride_frame; } } while (i); } static void mmxext_rgb16 (void * id, uint8_t * const * src, unsigned int v_offset) { rgb16 (id, src, v_offset, CPU_MMXEXT); } static void mmxext_argb32 (void * id, uint8_t * const * src, unsigned int v_offset) { argb32 (id, src, v_offset, CPU_MMXEXT); } static void mmx_rgb16 (void * id, uint8_t * const * src, unsigned int v_offset) { rgb16 (id, src, v_offset, CPU_MMX); } static void mmx_argb32 (void * id, uint8_t * const * src, unsigned int v_offset) { argb32 (id, src, v_offset, CPU_MMX); } mpeg2convert_copy_t * mpeg2convert_rgb_mmxext (int order, int bpp, const mpeg2_sequence_t * seq) { if (order == MPEG2CONVERT_RGB && seq->chroma_width < seq->width) { if (bpp == 16) return mmxext_rgb16; else if (bpp == 32) return mmxext_argb32; } return NULL; /* Fallback to C */ } mpeg2convert_copy_t * mpeg2convert_rgb_mmx (int order, int bpp, const mpeg2_sequence_t * seq) { if (order == MPEG2CONVERT_RGB && seq->chroma_width < seq->width) { if (bpp == 16) return mmx_rgb16; else if (bpp == 32) return mmx_argb32; } return NULL; /* Fallback to C */ } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/decode.c��������������������������������������������0000644�0001750�0001750�00000027624�14647725152�020712� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * decode.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <string.h> /* memcmp/memset, try to remove */ #include <stdlib.h> #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" static int mpeg2_accels = 0; #define BUFFER_SIZE (1194 * 1024) const mpeg2_info_t * mpeg2_info (mpeg2dec_t * mpeg2dec) { return &(mpeg2dec->info); } static inline int skip_chunk (mpeg2dec_t * mpeg2dec, int bytes) { uint8_t * current; uint32_t shift; uint8_t * limit; uint8_t byte; if (!bytes) return 0; current = mpeg2dec->buf_start; shift = mpeg2dec->shift; limit = current + bytes; do { byte = *current++; if (shift == 0x00000100) { int skipped; mpeg2dec->shift = 0xffffff00; skipped = current - mpeg2dec->buf_start; mpeg2dec->buf_start = current; return skipped; } shift = (shift | byte) << 8; } while (current < limit); mpeg2dec->shift = shift; mpeg2dec->buf_start = current; return 0; } static inline int copy_chunk (mpeg2dec_t * mpeg2dec, int bytes) { uint8_t * current; uint32_t shift; uint8_t * chunk_ptr; uint8_t * limit; uint8_t byte; if (!bytes) return 0; current = mpeg2dec->buf_start; shift = mpeg2dec->shift; chunk_ptr = mpeg2dec->chunk_ptr; limit = current + bytes; do { byte = *current++; if (shift == 0x00000100) { int copied; mpeg2dec->shift = 0xffffff00; mpeg2dec->chunk_ptr = chunk_ptr + 1; copied = current - mpeg2dec->buf_start; mpeg2dec->buf_start = current; return copied; } shift = (shift | byte) << 8; *chunk_ptr++ = byte; } while (current < limit); mpeg2dec->shift = shift; mpeg2dec->buf_start = current; return 0; } void mpeg2_buffer (mpeg2dec_t * mpeg2dec, uint8_t * start, uint8_t * end) { mpeg2dec->buf_start = start; mpeg2dec->buf_end = end; } int mpeg2_getpos (mpeg2dec_t * mpeg2dec) { return mpeg2dec->buf_end - mpeg2dec->buf_start; } static inline mpeg2_state_t seek_chunk (mpeg2dec_t * mpeg2dec) { int size, skipped; size = mpeg2dec->buf_end - mpeg2dec->buf_start; skipped = skip_chunk (mpeg2dec, size); if (!skipped) { mpeg2dec->bytes_since_tag += size; return STATE_BUFFER; } mpeg2dec->bytes_since_tag += skipped; mpeg2dec->code = mpeg2dec->buf_start[-1]; return STATE_INTERNAL_NORETURN; } mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec) { while (!(mpeg2dec->code == 0xb3 || ((mpeg2dec->code == 0xb7 || mpeg2dec->code == 0xb8 || !mpeg2dec->code) && mpeg2dec->sequence.width != (unsigned)-1))) if (seek_chunk (mpeg2dec) == STATE_BUFFER) return STATE_BUFFER; mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->user_data_len = 0; return ((mpeg2dec->code == 0xb7) ? mpeg2_header_end (mpeg2dec) : mpeg2_parse_header (mpeg2dec)); } #define RECEIVED(code,state) (((state) << 8) + (code)) mpeg2_state_t mpeg2_parse (mpeg2dec_t * mpeg2dec) { int size_buffer, size_chunk, copied; if (mpeg2dec->action) { mpeg2_state_t state; state = mpeg2dec->action (mpeg2dec); if ((int)state > (int)STATE_INTERNAL_NORETURN) return state; } while (1) { while ((unsigned) (mpeg2dec->code - mpeg2dec->first_decode_slice) < mpeg2dec->nb_decode_slices) { size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start; size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); if (size_buffer <= size_chunk) { copied = copy_chunk (mpeg2dec, size_buffer); if (!copied) { mpeg2dec->bytes_since_tag += size_buffer; mpeg2dec->chunk_ptr += size_buffer; return STATE_BUFFER; } } else { copied = copy_chunk (mpeg2dec, size_chunk); if (!copied) { /* filled the chunk buffer without finding a start code */ mpeg2dec->bytes_since_tag += size_chunk; mpeg2dec->action = seek_chunk; return STATE_INVALID; } } mpeg2dec->bytes_since_tag += copied; mpeg2_slice (&(mpeg2dec->decoder), mpeg2dec->code, mpeg2dec->chunk_start); mpeg2dec->code = mpeg2dec->buf_start[-1]; mpeg2dec->chunk_ptr = mpeg2dec->chunk_start; } if ((unsigned) (mpeg2dec->code - 1) >= 0xb0 - 1) break; if (seek_chunk (mpeg2dec) == STATE_BUFFER) return STATE_BUFFER; } mpeg2dec->action = mpeg2_seek_header; switch (mpeg2dec->code) { case 0x00: return mpeg2dec->state; case 0xb3: case 0xb7: case 0xb8: return (mpeg2dec->state == STATE_SLICE) ? STATE_SLICE : STATE_INVALID; default: mpeg2dec->action = seek_chunk; return STATE_INVALID; } } mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec) { static int (* process_header[]) (mpeg2dec_t * mpeg2dec) = { mpeg2_header_picture, mpeg2_header_extension, mpeg2_header_user_data, mpeg2_header_sequence, NULL, NULL, NULL, NULL, mpeg2_header_gop }; int size_buffer, size_chunk, copied; mpeg2dec->action = mpeg2_parse_header; mpeg2dec->info.user_data = NULL; mpeg2dec->info.user_data_len = 0; while (1) { size_buffer = mpeg2dec->buf_end - mpeg2dec->buf_start; size_chunk = (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); if (size_buffer <= size_chunk) { copied = copy_chunk (mpeg2dec, size_buffer); if (!copied) { mpeg2dec->bytes_since_tag += size_buffer; mpeg2dec->chunk_ptr += size_buffer; return STATE_BUFFER; } } else { copied = copy_chunk (mpeg2dec, size_chunk); if (!copied) { /* filled the chunk buffer without finding a start code */ mpeg2dec->bytes_since_tag += size_chunk; mpeg2dec->code = 0xb4; mpeg2dec->action = mpeg2_seek_header; return STATE_INVALID; } } mpeg2dec->bytes_since_tag += copied; if (process_header[mpeg2dec->code & 0x0b] (mpeg2dec)) { mpeg2dec->code = mpeg2dec->buf_start[-1]; mpeg2dec->action = mpeg2_seek_header; return STATE_INVALID; } mpeg2dec->code = mpeg2dec->buf_start[-1]; switch (RECEIVED (mpeg2dec->code, mpeg2dec->state)) { /* state transition after a sequence header */ case RECEIVED (0x00, STATE_SEQUENCE): case RECEIVED (0xb8, STATE_SEQUENCE): mpeg2_header_sequence_finalize (mpeg2dec); break; /* other legal state transitions */ case RECEIVED (0x00, STATE_GOP): mpeg2_header_gop_finalize (mpeg2dec); break; case RECEIVED (0x01, STATE_PICTURE): case RECEIVED (0x01, STATE_PICTURE_2ND): mpeg2_header_picture_finalize (mpeg2dec, mpeg2_accels); mpeg2dec->action = mpeg2_header_slice_start; break; /* legal headers within a given state */ case RECEIVED (0xb2, STATE_SEQUENCE): case RECEIVED (0xb2, STATE_GOP): case RECEIVED (0xb2, STATE_PICTURE): case RECEIVED (0xb2, STATE_PICTURE_2ND): case RECEIVED (0xb5, STATE_SEQUENCE): case RECEIVED (0xb5, STATE_PICTURE): case RECEIVED (0xb5, STATE_PICTURE_2ND): mpeg2dec->chunk_ptr = mpeg2dec->chunk_start; continue; default: mpeg2dec->action = mpeg2_seek_header; return STATE_INVALID; } mpeg2dec->chunk_start = mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->user_data_len = 0; return mpeg2dec->state; } } int mpeg2_convert (mpeg2dec_t * mpeg2dec, mpeg2_convert_t convert, void * arg) { mpeg2_convert_init_t convert_init; int error; error = convert (MPEG2_CONVERT_SET, NULL, &(mpeg2dec->sequence), 0, mpeg2_accels, arg, &convert_init); if (!error) { mpeg2dec->convert = convert; mpeg2dec->convert_arg = arg; mpeg2dec->convert_id_size = convert_init.id_size; mpeg2dec->convert_stride = 0; } return error; } int mpeg2_stride (mpeg2dec_t * mpeg2dec, int stride) { if (!mpeg2dec->convert) { if (stride < (int) mpeg2dec->sequence.width) stride = mpeg2dec->sequence.width; mpeg2dec->decoder.stride_frame = stride; } else { mpeg2_convert_init_t convert_init; stride = mpeg2dec->convert (MPEG2_CONVERT_STRIDE, NULL, &(mpeg2dec->sequence), stride, mpeg2_accels, mpeg2dec->convert_arg, &convert_init); mpeg2dec->convert_id_size = convert_init.id_size; mpeg2dec->convert_stride = stride; } return stride; } void mpeg2_set_buf (mpeg2dec_t * mpeg2dec, uint8_t * buf[3], void * id) { mpeg2_fbuf_t * fbuf; if (mpeg2dec->custom_fbuf) { if (mpeg2dec->state == STATE_SEQUENCE) { mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1]; mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0]; } mpeg2_set_fbuf (mpeg2dec, (mpeg2dec->decoder.coding_type == PIC_FLAG_CODING_TYPE_B)); fbuf = mpeg2dec->fbuf[0]; } else { fbuf = &(mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index].fbuf); mpeg2dec->alloc_index_user = ++mpeg2dec->alloc_index; } fbuf->buf[0] = buf[0]; fbuf->buf[1] = buf[1]; fbuf->buf[2] = buf[2]; fbuf->id = id; } void mpeg2_custom_fbuf (mpeg2dec_t * mpeg2dec, int custom_fbuf) { mpeg2dec->custom_fbuf = custom_fbuf; } void mpeg2_skip (mpeg2dec_t * mpeg2dec, int skip) { mpeg2dec->first_decode_slice = 1; mpeg2dec->nb_decode_slices = skip ? 0 : (0xb0 - 1); } void mpeg2_slice_region (mpeg2dec_t * mpeg2dec, int start, int end) { start = (start < 1) ? 1 : (start > 0xb0) ? 0xb0 : start; end = (end < start) ? start : (end > 0xb0) ? 0xb0 : end; mpeg2dec->first_decode_slice = start; mpeg2dec->nb_decode_slices = end - start; } void mpeg2_tag_picture (mpeg2dec_t * mpeg2dec, uint32_t tag, uint32_t tag2) { mpeg2dec->tag_previous = mpeg2dec->tag_current; mpeg2dec->tag2_previous = mpeg2dec->tag2_current; mpeg2dec->tag_current = tag; mpeg2dec->tag2_current = tag2; mpeg2dec->num_tags++; mpeg2dec->bytes_since_tag = 0; } uint32_t mpeg2_accel (uint32_t accel) { if (!mpeg2_accels) { mpeg2_accels = mpeg2_detect_accel (accel) | MPEG2_ACCEL_DETECT; mpeg2_cpu_state_init (mpeg2_accels); mpeg2_idct_init (mpeg2_accels); mpeg2_mc_init (mpeg2_accels); } return mpeg2_accels & ~MPEG2_ACCEL_DETECT; } void mpeg2_reset (mpeg2dec_t * mpeg2dec, int full_reset) { mpeg2dec->buf_start = mpeg2dec->buf_end = NULL; mpeg2dec->num_tags = 0; mpeg2dec->shift = 0xffffff00; mpeg2dec->code = 0xb4; mpeg2dec->action = mpeg2_seek_header; mpeg2dec->state = STATE_INVALID; mpeg2dec->first = 1; mpeg2_reset_info(&(mpeg2dec->info)); mpeg2dec->info.gop = NULL; mpeg2dec->info.user_data = NULL; mpeg2dec->info.user_data_len = 0; if (full_reset) { mpeg2dec->info.sequence = NULL; mpeg2_header_state_init (mpeg2dec); } } mpeg2dec_t * mpeg2_init (void) { mpeg2dec_t * mpeg2dec; mpeg2_accel (MPEG2_ACCEL_DETECT); mpeg2dec = (mpeg2dec_t *) mpeg2_malloc (sizeof (mpeg2dec_t), MPEG2_ALLOC_MPEG2DEC); if (mpeg2dec == NULL) return NULL; memset (mpeg2dec->decoder.DCTblock, 0, 64 * sizeof (int16_t)); memset (mpeg2dec->quantizer_matrix, 0, 4 * 64 * sizeof (uint8_t)); mpeg2dec->chunk_buffer = (uint8_t *) mpeg2_malloc (BUFFER_SIZE + 4, MPEG2_ALLOC_CHUNK); mpeg2dec->sequence.width = (unsigned)-1; mpeg2_reset (mpeg2dec, 1); return mpeg2dec; } void mpeg2_close (mpeg2dec_t * mpeg2dec) { mpeg2_header_state_init (mpeg2dec); mpeg2_free (mpeg2dec->chunk_buffer); mpeg2_free (mpeg2dec); } ������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/motion_comp_mlib.c����������������������������������0000644�0001750�0001750�00000013024�14647725152�023002� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_mlib.c * Copyright (C) 2000-2003 Håkan Hjort <d95hjort@dtek.chalmers.se> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef LIBMPEG2_MLIB #include <mlib_types.h> #include <mlib_status.h> #include <mlib_sys.h> #include <mlib_video.h> #include <inttypes.h> #include "../include/mpeg2.h" #include "mpeg2_internal.h" static void MC_put_o_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoCopyRef_U8_U8_16x16 (dest, (uint8_t *) ref, stride); else mlib_VideoCopyRef_U8_U8_16x8 (dest, (uint8_t *) ref, stride); } static void MC_put_x_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpX_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpX_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); } static void MC_put_y_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpY_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpY_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); } static void MC_put_xy_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpXY_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpXY_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); } static void MC_put_o_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoCopyRef_U8_U8_8x8 (dest, (uint8_t *) ref, stride); else mlib_VideoCopyRef_U8_U8_8x4 (dest, (uint8_t *) ref, stride); } static void MC_put_x_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpX_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpX_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); } static void MC_put_y_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpY_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpY_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); } static void MC_put_xy_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpXY_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpXY_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); } static void MC_avg_o_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoCopyRefAve_U8_U8_16x16 (dest, (uint8_t *) ref, stride); else mlib_VideoCopyRefAve_U8_U8_16x8 (dest, (uint8_t *) ref, stride); } static void MC_avg_x_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpAveX_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpAveX_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); } static void MC_avg_y_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpAveY_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpAveY_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); } static void MC_avg_xy_16_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpAveXY_U8_U8_16x16 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpAveXY_U8_U8_16x8 (dest, (uint8_t *) ref, stride, stride); } static void MC_avg_o_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoCopyRefAve_U8_U8_8x8 (dest, (uint8_t *) ref, stride); else mlib_VideoCopyRefAve_U8_U8_8x4 (dest, (uint8_t *) ref, stride); } static void MC_avg_x_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpAveX_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpAveX_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); } static void MC_avg_y_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpAveY_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpAveY_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); } static void MC_avg_xy_8_mlib (uint8_t * dest, const uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpAveXY_U8_U8_8x8 (dest, (uint8_t *) ref, stride, stride); else mlib_VideoInterpAveXY_U8_U8_8x4 (dest, (uint8_t *) ref, stride, stride); } MPEG2_MC_EXTERN (mlib) #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/idct_mmx.c������������������������������������������0000644�0001750�0001750�00000060703�14647725152�021266� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_mmx.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_X86 #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #include "../include/mmx.h" #define ROW_SHIFT 15 #define COL_SHIFT 6 #define round(bias) ((int)(((bias)+0.5) * (1<<ROW_SHIFT))) #define rounder(bias) {round (bias), round (bias)} #if 0 /* C row IDCT - its just here to document the MMXEXT and MMX versions */ static inline void idct_row (int16_t * row, int offset, int16_t * table, int32_t * rounder) { int C1, C2, C3, C4, C5, C6, C7; int a0, a1, a2, a3, b0, b1, b2, b3; row += offset; C1 = table[1]; C2 = table[2]; C3 = table[3]; C4 = table[4]; C5 = table[5]; C6 = table[6]; C7 = table[7]; a0 = C4*row[0] + C2*row[2] + C4*row[4] + C6*row[6] + *rounder; a1 = C4*row[0] + C6*row[2] - C4*row[4] - C2*row[6] + *rounder; a2 = C4*row[0] - C6*row[2] - C4*row[4] + C2*row[6] + *rounder; a3 = C4*row[0] - C2*row[2] + C4*row[4] - C6*row[6] + *rounder; b0 = C1*row[1] + C3*row[3] + C5*row[5] + C7*row[7]; b1 = C3*row[1] - C7*row[3] - C1*row[5] - C5*row[7]; b2 = C5*row[1] - C1*row[3] + C7*row[5] + C3*row[7]; b3 = C7*row[1] - C5*row[3] + C3*row[5] - C1*row[7]; row[0] = (a0 + b0) >> ROW_SHIFT; row[1] = (a1 + b1) >> ROW_SHIFT; row[2] = (a2 + b2) >> ROW_SHIFT; row[3] = (a3 + b3) >> ROW_SHIFT; row[4] = (a3 - b3) >> ROW_SHIFT; row[5] = (a2 - b2) >> ROW_SHIFT; row[6] = (a1 - b1) >> ROW_SHIFT; row[7] = (a0 - b0) >> ROW_SHIFT; } #endif /* MMXEXT row IDCT */ #define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \ c4, c6, c4, c6, \ c1, c3, -c1, -c5, \ c5, c7, c3, -c7, \ c4, -c6, c4, -c6, \ -c4, c2, c4, -c2, \ c5, -c1, c3, -c1, \ c7, c3, c7, -c5 } static inline void mmxext_row_head (int16_t * const row, const int offset, const int16_t * const table) { movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ movq_m2r (*table, mm3); /* mm3 = -C2 -C4 C2 C4 */ movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ movq_m2r (*(table+4), mm4); /* mm4 = C6 C4 C6 C4 */ pmaddwd_r2r (mm0, mm3); /* mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 */ pshufw_r2r (mm2, mm2, 0x4e); /* mm2 = x2 x0 x6 x4 */ } static inline void mmxext_row (const int16_t * const table, const int32_t * const rounder) { movq_m2r (*(table+8), mm1); /* mm1 = -C5 -C1 C3 C1 */ pmaddwd_r2r (mm2, mm4); /* mm4 = C4*x0+C6*x2 C4*x4+C6*x6 */ pmaddwd_m2r (*(table+16), mm0); /* mm0 = C4*x4-C6*x6 C4*x0-C6*x2 */ pshufw_r2r (mm6, mm6, 0x4e); /* mm6 = x3 x1 x7 x5 */ movq_m2r (*(table+12), mm7); /* mm7 = -C7 C3 C7 C5 */ pmaddwd_r2r (mm5, mm1); /* mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 */ paddd_m2r (*rounder, mm3); /* mm3 += rounder */ pmaddwd_r2r (mm6, mm7); /* mm7 = C3*x1-C7*x3 C5*x5+C7*x7 */ pmaddwd_m2r (*(table+20), mm2); /* mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 */ paddd_r2r (mm4, mm3); /* mm3 = a1 a0 + rounder */ pmaddwd_m2r (*(table+24), mm5); /* mm5 = C3*x5-C1*x7 C5*x1-C1*x3 */ movq_r2r (mm3, mm4); /* mm4 = a1 a0 + rounder */ pmaddwd_m2r (*(table+28), mm6); /* mm6 = C7*x1-C5*x3 C7*x5+C3*x7 */ paddd_r2r (mm7, mm1); /* mm1 = b1 b0 */ paddd_m2r (*rounder, mm0); /* mm0 += rounder */ psubd_r2r (mm1, mm3); /* mm3 = a1-b1 a0-b0 + rounder */ psrad_i2r (ROW_SHIFT, mm3); /* mm3 = y6 y7 */ paddd_r2r (mm4, mm1); /* mm1 = a1+b1 a0+b0 + rounder */ paddd_r2r (mm2, mm0); /* mm0 = a3 a2 + rounder */ psrad_i2r (ROW_SHIFT, mm1); /* mm1 = y1 y0 */ paddd_r2r (mm6, mm5); /* mm5 = b3 b2 */ movq_r2r (mm0, mm4); /* mm4 = a3 a2 + rounder */ paddd_r2r (mm5, mm0); /* mm0 = a3+b3 a2+b2 + rounder */ psubd_r2r (mm5, mm4); /* mm4 = a3-b3 a2-b2 + rounder */ } static inline void mmxext_row_tail (int16_t * const row, const int store) { psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ psrad_i2r (ROW_SHIFT, mm4); /* mm4 = y4 y5 */ packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ packssdw_r2r (mm3, mm4); /* mm4 = y6 y7 y4 y5 */ movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ pshufw_r2r (mm4, mm4, 0xb1); /* mm4 = y7 y6 y5 y4 */ /* slot */ movq_r2m (mm4, *(row+store+4)); /* save y7 y6 y5 y4 */ } static inline void mmxext_row_mid (int16_t * const row, const int store, const int offset, const int16_t * const table) { movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ psrad_i2r (ROW_SHIFT, mm4); /* mm4 = y4 y5 */ packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ packssdw_r2r (mm3, mm4); /* mm4 = y6 y7 y4 y5 */ movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ pshufw_r2r (mm4, mm4, 0xb1); /* mm4 = y7 y6 y5 y4 */ movq_m2r (*table, mm3); /* mm3 = -C2 -C4 C2 C4 */ movq_r2m (mm4, *(row+store+4)); /* save y7 y6 y5 y4 */ pmaddwd_r2r (mm0, mm3); /* mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 */ movq_m2r (*(table+4), mm4); /* mm4 = C6 C4 C6 C4 */ pshufw_r2r (mm2, mm2, 0x4e); /* mm2 = x2 x0 x6 x4 */ } /* MMX row IDCT */ #define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \ c4, c6, -c4, -c2, \ c1, c3, c3, -c7, \ c5, c7, -c1, -c5, \ c4, -c6, c4, -c2, \ -c4, c2, c4, -c6, \ c5, -c1, c7, -c5, \ c7, c3, c3, -c1 } static inline void mmx_row_head (int16_t * const row, const int offset, const int16_t * const table) { movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ movq_m2r (*table, mm3); /* mm3 = C6 C4 C2 C4 */ movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ punpckldq_r2r (mm0, mm0); /* mm0 = x2 x0 x2 x0 */ movq_m2r (*(table+4), mm4); /* mm4 = -C2 -C4 C6 C4 */ pmaddwd_r2r (mm0, mm3); /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */ movq_m2r (*(table+8), mm1); /* mm1 = -C7 C3 C3 C1 */ punpckhdq_r2r (mm2, mm2); /* mm2 = x6 x4 x6 x4 */ } static inline void mmx_row (const int16_t * const table, const int32_t * const rounder) { pmaddwd_r2r (mm2, mm4); /* mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 */ punpckldq_r2r (mm5, mm5); /* mm5 = x3 x1 x3 x1 */ pmaddwd_m2r (*(table+16), mm0); /* mm0 = C4*x0-C2*x2 C4*x0-C6*x2 */ punpckhdq_r2r (mm6, mm6); /* mm6 = x7 x5 x7 x5 */ movq_m2r (*(table+12), mm7); /* mm7 = -C5 -C1 C7 C5 */ pmaddwd_r2r (mm5, mm1); /* mm1 = C3*x1-C7*x3 C1*x1+C3*x3 */ paddd_m2r (*rounder, mm3); /* mm3 += rounder */ pmaddwd_r2r (mm6, mm7); /* mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 */ pmaddwd_m2r (*(table+20), mm2); /* mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 */ paddd_r2r (mm4, mm3); /* mm3 = a1 a0 + rounder */ pmaddwd_m2r (*(table+24), mm5); /* mm5 = C7*x1-C5*x3 C5*x1-C1*x3 */ movq_r2r (mm3, mm4); /* mm4 = a1 a0 + rounder */ pmaddwd_m2r (*(table+28), mm6); /* mm6 = C3*x5-C1*x7 C7*x5+C3*x7 */ paddd_r2r (mm7, mm1); /* mm1 = b1 b0 */ paddd_m2r (*rounder, mm0); /* mm0 += rounder */ psubd_r2r (mm1, mm3); /* mm3 = a1-b1 a0-b0 + rounder */ psrad_i2r (ROW_SHIFT, mm3); /* mm3 = y6 y7 */ paddd_r2r (mm4, mm1); /* mm1 = a1+b1 a0+b0 + rounder */ paddd_r2r (mm2, mm0); /* mm0 = a3 a2 + rounder */ psrad_i2r (ROW_SHIFT, mm1); /* mm1 = y1 y0 */ paddd_r2r (mm6, mm5); /* mm5 = b3 b2 */ movq_r2r (mm0, mm7); /* mm7 = a3 a2 + rounder */ paddd_r2r (mm5, mm0); /* mm0 = a3+b3 a2+b2 + rounder */ psubd_r2r (mm5, mm7); /* mm7 = a3-b3 a2-b2 + rounder */ } static inline void mmx_row_tail (int16_t * const row, const int store) { psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ psrad_i2r (ROW_SHIFT, mm7); /* mm7 = y4 y5 */ packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ packssdw_r2r (mm3, mm7); /* mm7 = y6 y7 y4 y5 */ movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ movq_r2r (mm7, mm4); /* mm4 = y6 y7 y4 y5 */ pslld_i2r (16, mm7); /* mm7 = y7 0 y5 0 */ psrld_i2r (16, mm4); /* mm4 = 0 y6 0 y4 */ por_r2r (mm4, mm7); /* mm7 = y7 y6 y5 y4 */ /* slot */ movq_r2m (mm7, *(row+store+4)); /* save y7 y6 y5 y4 */ } static inline void mmx_row_mid (int16_t * const row, const int store, const int offset, const int16_t * const table) { movq_m2r (*(row+offset), mm2); /* mm2 = x6 x4 x2 x0 */ psrad_i2r (ROW_SHIFT, mm0); /* mm0 = y3 y2 */ movq_m2r (*(row+offset+4), mm5); /* mm5 = x7 x5 x3 x1 */ psrad_i2r (ROW_SHIFT, mm7); /* mm7 = y4 y5 */ packssdw_r2r (mm0, mm1); /* mm1 = y3 y2 y1 y0 */ movq_r2r (mm5, mm6); /* mm6 = x7 x5 x3 x1 */ packssdw_r2r (mm3, mm7); /* mm7 = y6 y7 y4 y5 */ movq_r2r (mm2, mm0); /* mm0 = x6 x4 x2 x0 */ movq_r2m (mm1, *(row+store)); /* save y3 y2 y1 y0 */ movq_r2r (mm7, mm1); /* mm1 = y6 y7 y4 y5 */ punpckldq_r2r (mm0, mm0); /* mm0 = x2 x0 x2 x0 */ psrld_i2r (16, mm7); /* mm7 = 0 y6 0 y4 */ movq_m2r (*table, mm3); /* mm3 = C6 C4 C2 C4 */ pslld_i2r (16, mm1); /* mm1 = y7 0 y5 0 */ movq_m2r (*(table+4), mm4); /* mm4 = -C2 -C4 C6 C4 */ por_r2r (mm1, mm7); /* mm7 = y7 y6 y5 y4 */ movq_m2r (*(table+8), mm1); /* mm1 = -C7 C3 C3 C1 */ punpckhdq_r2r (mm2, mm2); /* mm2 = x6 x4 x6 x4 */ movq_r2m (mm7, *(row+store+4)); /* save y7 y6 y5 y4 */ pmaddwd_r2r (mm0, mm3); /* mm3 = C4*x0+C6*x2 C4*x0+C2*x2 */ } #if 0 /* C column IDCT - its just here to document the MMXEXT and MMX versions */ static inline void idct_col (int16_t * col, int offset) { /* multiplication - as implemented on mmx */ #define F(c,x) (((c) * (x)) >> 16) /* saturation - it helps us handle torture test cases */ #define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x)) int16_t x0, x1, x2, x3, x4, x5, x6, x7; int16_t y0, y1, y2, y3, y4, y5, y6, y7; int16_t a0, a1, a2, a3, b0, b1, b2, b3; int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12; col += offset; x0 = col[0*8]; x1 = col[1*8]; x2 = col[2*8]; x3 = col[3*8]; x4 = col[4*8]; x5 = col[5*8]; x6 = col[6*8]; x7 = col[7*8]; u04 = S (x0 + x4); v04 = S (x0 - x4); u26 = S (F (T2, x6) + x2); v26 = S (F (T2, x2) - x6); a0 = S (u04 + u26); a1 = S (v04 + v26); a2 = S (v04 - v26); a3 = S (u04 - u26); u17 = S (F (T1, x7) + x1); v17 = S (F (T1, x1) - x7); u35 = S (F (T3, x5) + x3); v35 = S (F (T3, x3) - x5); b0 = S (u17 + u35); b3 = S (v17 - v35); u12 = S (u17 - u35); v12 = S (v17 + v35); u12 = S (2 * F (C4, u12)); v12 = S (2 * F (C4, v12)); b1 = S (u12 + v12); b2 = S (u12 - v12); y0 = S (a0 + b0) >> COL_SHIFT; y1 = S (a1 + b1) >> COL_SHIFT; y2 = S (a2 + b2) >> COL_SHIFT; y3 = S (a3 + b3) >> COL_SHIFT; y4 = S (a3 - b3) >> COL_SHIFT; y5 = S (a2 - b2) >> COL_SHIFT; y6 = S (a1 - b1) >> COL_SHIFT; y7 = S (a0 - b0) >> COL_SHIFT; col[0*8] = y0; col[1*8] = y1; col[2*8] = y2; col[3*8] = y3; col[4*8] = y4; col[5*8] = y5; col[6*8] = y6; col[7*8] = y7; } #endif /* MMX column IDCT */ static inline void idct_col (int16_t * const col, const int offset) { #define T1 13036 #define T2 27146 #define T3 43790 #define C4 23170 static const short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; static const short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; static const short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; static const short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; /* column code adapted from peter gubanov */ /* http://www.elecard.com/peter/idct.shtml */ movq_m2r (*_T1, mm0); /* mm0 = T1 */ movq_m2r (*(col+offset+1*8), mm1); /* mm1 = x1 */ movq_r2r (mm0, mm2); /* mm2 = T1 */ movq_m2r (*(col+offset+7*8), mm4); /* mm4 = x7 */ pmulhw_r2r (mm1, mm0); /* mm0 = T1*x1 */ movq_m2r (*_T3, mm5); /* mm5 = T3 */ pmulhw_r2r (mm4, mm2); /* mm2 = T1*x7 */ movq_m2r (*(col+offset+5*8), mm6); /* mm6 = x5 */ movq_r2r (mm5, mm7); /* mm7 = T3-1 */ movq_m2r (*(col+offset+3*8), mm3); /* mm3 = x3 */ psubsw_r2r (mm4, mm0); /* mm0 = v17 */ movq_m2r (*_T2, mm4); /* mm4 = T2 */ pmulhw_r2r (mm3, mm5); /* mm5 = (T3-1)*x3 */ paddsw_r2r (mm2, mm1); /* mm1 = u17 */ pmulhw_r2r (mm6, mm7); /* mm7 = (T3-1)*x5 */ /* slot */ movq_r2r (mm4, mm2); /* mm2 = T2 */ paddsw_r2r (mm3, mm5); /* mm5 = T3*x3 */ pmulhw_m2r (*(col+offset+2*8), mm4);/* mm4 = T2*x2 */ paddsw_r2r (mm6, mm7); /* mm7 = T3*x5 */ psubsw_r2r (mm6, mm5); /* mm5 = v35 */ paddsw_r2r (mm3, mm7); /* mm7 = u35 */ movq_m2r (*(col+offset+6*8), mm3); /* mm3 = x6 */ movq_r2r (mm0, mm6); /* mm6 = v17 */ pmulhw_r2r (mm3, mm2); /* mm2 = T2*x6 */ psubsw_r2r (mm5, mm0); /* mm0 = b3 */ psubsw_r2r (mm3, mm4); /* mm4 = v26 */ paddsw_r2r (mm6, mm5); /* mm5 = v12 */ movq_r2m (mm0, *(col+offset+3*8)); /* save b3 in scratch0 */ movq_r2r (mm1, mm6); /* mm6 = u17 */ paddsw_m2r (*(col+offset+2*8), mm2);/* mm2 = u26 */ paddsw_r2r (mm7, mm6); /* mm6 = b0 */ psubsw_r2r (mm7, mm1); /* mm1 = u12 */ movq_r2r (mm1, mm7); /* mm7 = u12 */ movq_m2r (*(col+offset+0*8), mm3); /* mm3 = x0 */ paddsw_r2r (mm5, mm1); /* mm1 = u12+v12 */ movq_m2r (*_C4, mm0); /* mm0 = C4/2 */ psubsw_r2r (mm5, mm7); /* mm7 = u12-v12 */ movq_r2m (mm6, *(col+offset+5*8)); /* save b0 in scratch1 */ pmulhw_r2r (mm0, mm1); /* mm1 = b1/2 */ movq_r2r (mm4, mm6); /* mm6 = v26 */ pmulhw_r2r (mm0, mm7); /* mm7 = b2/2 */ movq_m2r (*(col+offset+4*8), mm5); /* mm5 = x4 */ movq_r2r (mm3, mm0); /* mm0 = x0 */ psubsw_r2r (mm5, mm3); /* mm3 = v04 */ paddsw_r2r (mm5, mm0); /* mm0 = u04 */ paddsw_r2r (mm3, mm4); /* mm4 = a1 */ movq_r2r (mm0, mm5); /* mm5 = u04 */ psubsw_r2r (mm6, mm3); /* mm3 = a2 */ paddsw_r2r (mm2, mm5); /* mm5 = a0 */ paddsw_r2r (mm1, mm1); /* mm1 = b1 */ psubsw_r2r (mm2, mm0); /* mm0 = a3 */ paddsw_r2r (mm7, mm7); /* mm7 = b2 */ movq_r2r (mm3, mm2); /* mm2 = a2 */ movq_r2r (mm4, mm6); /* mm6 = a1 */ paddsw_r2r (mm7, mm3); /* mm3 = a2+b2 */ psraw_i2r (COL_SHIFT, mm3); /* mm3 = y2 */ paddsw_r2r (mm1, mm4); /* mm4 = a1+b1 */ psraw_i2r (COL_SHIFT, mm4); /* mm4 = y1 */ psubsw_r2r (mm1, mm6); /* mm6 = a1-b1 */ movq_m2r (*(col+offset+5*8), mm1); /* mm1 = b0 */ psubsw_r2r (mm7, mm2); /* mm2 = a2-b2 */ psraw_i2r (COL_SHIFT, mm6); /* mm6 = y6 */ movq_r2r (mm5, mm7); /* mm7 = a0 */ movq_r2m (mm4, *(col+offset+1*8)); /* save y1 */ psraw_i2r (COL_SHIFT, mm2); /* mm2 = y5 */ movq_r2m (mm3, *(col+offset+2*8)); /* save y2 */ paddsw_r2r (mm1, mm5); /* mm5 = a0+b0 */ movq_m2r (*(col+offset+3*8), mm4); /* mm4 = b3 */ psubsw_r2r (mm1, mm7); /* mm7 = a0-b0 */ psraw_i2r (COL_SHIFT, mm5); /* mm5 = y0 */ movq_r2r (mm0, mm3); /* mm3 = a3 */ movq_r2m (mm2, *(col+offset+5*8)); /* save y5 */ psubsw_r2r (mm4, mm3); /* mm3 = a3-b3 */ psraw_i2r (COL_SHIFT, mm7); /* mm7 = y7 */ paddsw_r2r (mm0, mm4); /* mm4 = a3+b3 */ movq_r2m (mm5, *(col+offset+0*8)); /* save y0 */ psraw_i2r (COL_SHIFT, mm3); /* mm3 = y4 */ movq_r2m (mm6, *(col+offset+6*8)); /* save y6 */ psraw_i2r (COL_SHIFT, mm4); /* mm4 = y3 */ movq_r2m (mm7, *(col+offset+7*8)); /* save y7 */ movq_r2m (mm3, *(col+offset+4*8)); /* save y4 */ movq_r2m (mm4, *(col+offset+3*8)); /* save y3 */ } static const int32_t rounder0[] ATTR_ALIGN(8) = rounder ((1 << (COL_SHIFT - 1)) - 0.5); static const int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); static const int32_t rounder1[] ATTR_ALIGN(8) = rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ static const int32_t rounder7[] ATTR_ALIGN(8) = rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ static const int32_t rounder2[] ATTR_ALIGN(8) = rounder (0.60355339059); /* C2 * (C6+C2)/2 */ static const int32_t rounder6[] ATTR_ALIGN(8) = rounder (-0.25); /* C2 * (C6-C2)/2 */ static const int32_t rounder3[] ATTR_ALIGN(8) = rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ static const int32_t rounder5[] ATTR_ALIGN(8) = rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */ #define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \ static inline void idct (int16_t * const block) \ { \ static const int16_t table04[] ATTR_ALIGN(16) = \ table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ static const int16_t table17[] ATTR_ALIGN(16) = \ table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ static const int16_t table26[] ATTR_ALIGN(16) = \ table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ static const int16_t table35[] ATTR_ALIGN(16) = \ table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \ \ idct_row_head (block, 0*8, table04); \ idct_row (table04, rounder0); \ idct_row_mid (block, 0*8, 4*8, table04); \ idct_row (table04, rounder4); \ idct_row_mid (block, 4*8, 1*8, table17); \ idct_row (table17, rounder1); \ idct_row_mid (block, 1*8, 7*8, table17); \ idct_row (table17, rounder7); \ idct_row_mid (block, 7*8, 2*8, table26); \ idct_row (table26, rounder2); \ idct_row_mid (block, 2*8, 6*8, table26); \ idct_row (table26, rounder6); \ idct_row_mid (block, 6*8, 3*8, table35); \ idct_row (table35, rounder3); \ idct_row_mid (block, 3*8, 5*8, table35); \ idct_row (table35, rounder5); \ idct_row_tail (block, 5*8); \ \ idct_col (block, 0); \ idct_col (block, 4); \ } #define COPY_MMX(offset,r0,r1,r2) \ do { \ movq_m2r (*(block+offset), r0); \ dest += stride; \ movq_m2r (*(block+offset+4), r1); \ movq_r2m (r2, *dest); \ packuswb_r2r (r1, r0); \ } while (0) static inline void block_copy (int16_t * const block, uint8_t * dest, const int stride) { movq_m2r (*(block+0*8), mm0); movq_m2r (*(block+0*8+4), mm1); movq_m2r (*(block+1*8), mm2); packuswb_r2r (mm1, mm0); movq_m2r (*(block+1*8+4), mm3); movq_r2m (mm0, *dest); packuswb_r2r (mm3, mm2); COPY_MMX (2*8, mm0, mm1, mm2); COPY_MMX (3*8, mm2, mm3, mm0); COPY_MMX (4*8, mm0, mm1, mm2); COPY_MMX (5*8, mm2, mm3, mm0); COPY_MMX (6*8, mm0, mm1, mm2); COPY_MMX (7*8, mm2, mm3, mm0); movq_r2m (mm2, *(dest+stride)); } #define ADD_MMX(offset,r1,r2,r3,r4) \ do { \ movq_m2r (*(dest+2*stride), r1); \ packuswb_r2r (r4, r3); \ movq_r2r (r1, r2); \ dest += stride; \ movq_r2m (r3, *dest); \ punpcklbw_r2r (mm0, r1); \ paddsw_m2r (*(block+offset), r1); \ punpckhbw_r2r (mm0, r2); \ paddsw_m2r (*(block+offset+4), r2); \ } while (0) static inline void block_add (int16_t * const block, uint8_t * dest, const int stride) { movq_m2r (*dest, mm1); pxor_r2r (mm0, mm0); movq_m2r (*(dest+stride), mm3); movq_r2r (mm1, mm2); punpcklbw_r2r (mm0, mm1); movq_r2r (mm3, mm4); paddsw_m2r (*(block+0*8), mm1); punpckhbw_r2r (mm0, mm2); paddsw_m2r (*(block+0*8+4), mm2); punpcklbw_r2r (mm0, mm3); paddsw_m2r (*(block+1*8), mm3); packuswb_r2r (mm2, mm1); punpckhbw_r2r (mm0, mm4); movq_r2m (mm1, *dest); paddsw_m2r (*(block+1*8+4), mm4); ADD_MMX (2*8, mm1, mm2, mm3, mm4); ADD_MMX (3*8, mm3, mm4, mm1, mm2); ADD_MMX (4*8, mm1, mm2, mm3, mm4); ADD_MMX (5*8, mm3, mm4, mm1, mm2); ADD_MMX (6*8, mm1, mm2, mm3, mm4); ADD_MMX (7*8, mm3, mm4, mm1, mm2); packuswb_r2r (mm4, mm3); movq_r2m (mm3, *(dest+stride)); } static inline void block_zero (int16_t * const block) { pxor_r2r (mm0, mm0); movq_r2m (mm0, *(block+0*4)); movq_r2m (mm0, *(block+1*4)); movq_r2m (mm0, *(block+2*4)); movq_r2m (mm0, *(block+3*4)); movq_r2m (mm0, *(block+4*4)); movq_r2m (mm0, *(block+5*4)); movq_r2m (mm0, *(block+6*4)); movq_r2m (mm0, *(block+7*4)); movq_r2m (mm0, *(block+8*4)); movq_r2m (mm0, *(block+9*4)); movq_r2m (mm0, *(block+10*4)); movq_r2m (mm0, *(block+11*4)); movq_r2m (mm0, *(block+12*4)); movq_r2m (mm0, *(block+13*4)); movq_r2m (mm0, *(block+14*4)); movq_r2m (mm0, *(block+15*4)); } #define CPU_MMXEXT 0 #define CPU_MMX 1 #define dup4(reg) \ do { \ if (cpu != CPU_MMXEXT) { \ punpcklwd_r2r (reg, reg); \ punpckldq_r2r (reg, reg); \ } else \ pshufw_r2r (reg, reg, 0x00); \ } while (0) static inline void block_add_DC (int16_t * const block, uint8_t * dest, const int stride, const int cpu) { movd_v2r ((block[0] + 64) >> 7, mm0); pxor_r2r (mm1, mm1); movq_m2r (*dest, mm2); dup4 (mm0); psubsw_r2r (mm0, mm1); packuswb_r2r (mm0, mm0); paddusb_r2r (mm0, mm2); packuswb_r2r (mm1, mm1); movq_m2r (*(dest + stride), mm3); psubusb_r2r (mm1, mm2); block[0] = 0; paddusb_r2r (mm0, mm3); movq_r2m (mm2, *dest); psubusb_r2r (mm1, mm3); movq_m2r (*(dest + 2*stride), mm2); dest += stride; movq_r2m (mm3, *dest); paddusb_r2r (mm0, mm2); movq_m2r (*(dest + 2*stride), mm3); psubusb_r2r (mm1, mm2); dest += stride; paddusb_r2r (mm0, mm3); movq_r2m (mm2, *dest); psubusb_r2r (mm1, mm3); movq_m2r (*(dest + 2*stride), mm2); dest += stride; movq_r2m (mm3, *dest); paddusb_r2r (mm0, mm2); movq_m2r (*(dest + 2*stride), mm3); psubusb_r2r (mm1, mm2); dest += stride; paddusb_r2r (mm0, mm3); movq_r2m (mm2, *dest); psubusb_r2r (mm1, mm3); movq_m2r (*(dest + 2*stride), mm2); dest += stride; movq_r2m (mm3, *dest); paddusb_r2r (mm0, mm2); movq_m2r (*(dest + 2*stride), mm3); psubusb_r2r (mm1, mm2); block[63] = 0; paddusb_r2r (mm0, mm3); movq_r2m (mm2, *(dest + stride)); psubusb_r2r (mm1, mm3); movq_r2m (mm3, *(dest + 2*stride)); } declare_idct (mmxext_idct, mmxext_table, mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid) void mpeg2_idct_copy_mmxext (int16_t * const block, uint8_t * const dest, const int stride) { mmxext_idct (block); block_copy (block, dest, stride); block_zero (block); } void mpeg2_idct_add_mmxext (const int last, int16_t * const block, uint8_t * const dest, const int stride) { if (last != 129 || (block[0] & (7 << 4)) == (4 << 4)) { mmxext_idct (block); block_add (block, dest, stride); block_zero (block); } else block_add_DC (block, dest, stride, CPU_MMXEXT); } declare_idct (mmx_idct, mmx_table, mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid) void mpeg2_idct_copy_mmx (int16_t * const block, uint8_t * const dest, const int stride) { mmx_idct (block); block_copy (block, dest, stride); block_zero (block); } void mpeg2_idct_add_mmx (const int last, int16_t * const block, uint8_t * const dest, const int stride) { if (last != 129 || (block[0] & (7 << 4)) == (4 << 4)) { mmx_idct (block); block_add (block, dest, stride); block_zero (block); } else block_add_DC (block, dest, stride, CPU_MMX); } void mpeg2_idct_mmx_init (void) { extern uint8_t mpeg2_scan_norm[64]; extern uint8_t mpeg2_scan_alt[64]; int i, j; /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ for (i = 0; i < 64; i++) { j = mpeg2_scan_norm[i]; mpeg2_scan_norm[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); j = mpeg2_scan_alt[i]; mpeg2_scan_alt[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); } } #endif �������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/uyvy.c����������������������������������������������0000644�0001750�0001750�00000006763�14647725152�020504� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * uyvy.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 2003 Regis Duchesne <hpreg@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <inttypes.h> #include "mpeg2.h" #include "mpeg2convert.h" typedef struct { int width; int stride; int chroma420; uint8_t * out; } convert_uyvy_t; static void uyvy_start (void * _id, const mpeg2_fbuf_t * fbuf, const mpeg2_picture_t * picture, const mpeg2_gop_t * gop) { convert_uyvy_t * instance = (convert_uyvy_t *) _id; instance->out = fbuf->buf[0]; instance->stride = instance->width; if (picture->nb_fields == 1) { if (! (picture->flags & PIC_FLAG_TOP_FIELD_FIRST)) instance->out += 2 * instance->stride; instance->stride <<= 1; } } #ifdef WORDS_BIGENDIAN #define PACK(a,b,c,d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d)) #else #define PACK(a,b,c,d) (((d) << 24) | ((c) << 16) | ((b) << 8) | (a)) #endif static void uyvy_copy (void * const _id, uint8_t * const * src, const unsigned int v_offset) { const convert_uyvy_t * const id = (convert_uyvy_t *) _id; uint8_t * _dst; uint8_t * py, * pu, * pv; int i, j; _dst = id->out + 2 * id->stride * v_offset; py = src[0]; pu = src[1]; pv = src[2]; i = 16; do { uint32_t * dst = (uint32_t *) _dst; j = id->width >> 4; do { dst[0] = PACK (pu[0], py[0], pv[0], py[1]); dst[1] = PACK (pu[1], py[2], pv[1], py[3]); dst[2] = PACK (pu[2], py[4], pv[2], py[5]); dst[3] = PACK (pu[3], py[6], pv[3], py[7]); dst[4] = PACK (pu[4], py[8], pv[4], py[9]); dst[5] = PACK (pu[5], py[10], pv[5], py[11]); dst[6] = PACK (pu[6], py[12], pv[6], py[13]); dst[7] = PACK (pu[7], py[14], pv[7], py[15]); py += 16; pu += 8; pv += 8; dst += 8; } while (--j); py -= id->width; pu -= id->width >> 1; pv -= id->width >> 1; _dst += 2 * id->stride; py += id->stride; if (! (--i & id->chroma420)) { pu += id->stride >> 1; pv += id->stride >> 1; } } while (i); } int mpeg2convert_uyvy (int stage, void * _id, const mpeg2_sequence_t * seq, int stride, uint32_t accel, void * arg, mpeg2_convert_init_t * result) { convert_uyvy_t * instance = (convert_uyvy_t *) _id; if (seq->chroma_width == seq->width) return 1; if (instance) { instance->width = seq->width; instance->chroma420 = (seq->chroma_height < seq->height); result->buf_size[0] = seq->width * seq->height * 2; result->buf_size[1] = result->buf_size[2] = 0; result->start = uyvy_start; result->copy = uyvy_copy; } else { result->id_size = sizeof (convert_uyvy_t); } return 0; } �������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/motion_comp_vis.c�����������������������������������0000644�0001750�0001750�00000131316�14647725152�022665� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_vis.c * Copyright (C) 2003 David S. Miller <davem@redhat.com> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #if defined(ARCH_SPARC) && defined(ENABLE_VIS) #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #include "../include/vis.h" /* The trick used in some of this file is the formula from the MMX * motion comp code, which is: * * (x+y+1)>>1 == (x|y)-((x^y)>>1) * * This allows us to average 8 bytes at a time in a 64-bit FPU reg. * We avoid overflows by masking before we do the shift, and we * implement the shift by multiplying by 1/2 using mul8x16. So in * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and * the value 0x80808080 is in f8): * * fxor f0, f2, f10 * fand f10, f4, f10 * fmul8x16 f8, f10, f10 * fand f10, f6, f10 * for f0, f2, f12 * fpsub16 f12, f10, f10 */ #define DUP4(x) {x, x, x, x} #define DUP8(x) {x, x, x, x, x, x, x, x} static const int16_t constants1[] ATTR_ALIGN(8) = DUP4 (1); static const int16_t constants2[] ATTR_ALIGN(8) = DUP4 (2); static const int16_t constants3[] ATTR_ALIGN(8) = DUP4 (3); static const int16_t constants6[] ATTR_ALIGN(8) = DUP4 (6); static const int8_t constants_fe[] ATTR_ALIGN(8) = DUP8 (0xfe); static const int8_t constants_7f[] ATTR_ALIGN(8) = DUP8 (0x7f); static const int8_t constants128[] ATTR_ALIGN(8) = DUP8 (128); static const int16_t constants256_512[] ATTR_ALIGN(8) = {256, 512, 256, 512}; static const int16_t constants256_1024[] ATTR_ALIGN(8) = {256, 1024, 256, 1024}; #define REF_0 0 #define REF_0_1 1 #define REF_2 2 #define REF_2_1 3 #define REF_4 4 #define REF_4_1 5 #define REF_6 6 #define REF_6_1 7 #define REF_S0 8 #define REF_S0_1 9 #define REF_S2 10 #define REF_S2_1 11 #define REF_S4 12 #define REF_S4_1 13 #define REF_S6 14 #define REF_S6_1 15 #define DST_0 16 #define DST_1 17 #define DST_2 18 #define DST_3 19 #define CONST_1 20 #define CONST_2 20 #define CONST_3 20 #define CONST_6 20 #define MASK_fe 20 #define CONST_128 22 #define CONST_256 22 #define CONST_512 22 #define CONST_1024 22 #define TMP0 24 #define TMP1 25 #define TMP2 26 #define TMP3 27 #define TMP4 28 #define TMP5 29 #define ZERO 30 #define MASK_7f 30 #define TMP6 32 #define TMP8 34 #define TMP10 36 #define TMP12 38 #define TMP14 40 #define TMP16 42 #define TMP18 44 #define TMP20 46 #define TMP22 48 #define TMP24 50 #define TMP26 52 #define TMP28 54 #define TMP30 56 #define TMP32 58 static void MC_put_o_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; do { /* 5 cycles */ vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_faligndata(TMP0, TMP2, REF_0); vis_st64(REF_0, dest[0]); vis_faligndata(TMP2, TMP4, REF_2); vis_st64_2(REF_2, dest, 8); dest += stride; } while (--height); } static void MC_put_o_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; do { /* 4 cycles */ vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); ref += stride; /* stall */ vis_faligndata(TMP0, TMP2, REF_0); vis_st64(REF_0, dest[0]); dest += stride; } while (--height); } static void MC_avg_o_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int stride_8 = stride + 8; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; vis_ld64(ref[0], TMP0); vis_ld64(ref[8], TMP2); vis_ld64_2(ref, offset, TMP4); vis_ld64(dest[0], DST_0); vis_ld64(dest[8], DST_2); vis_ld64(constants_fe[0], MASK_fe); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP2, TMP4, REF_2); vis_ld64(constants128[0], CONST_128); ref += stride; height = (height >> 1) - 1; do { /* 24 cycles */ vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP6); vis_ld64_2(ref, 8, TMP2); vis_and(TMP6, MASK_fe, TMP6); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_mul8x16(CONST_128, TMP6, TMP6); vis_xor(DST_2, REF_2, TMP8); vis_and(TMP8, MASK_fe, TMP8); vis_or(DST_0, REF_0, TMP10); vis_ld64_2(dest, stride, DST_0); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(DST_2, REF_2, TMP12); vis_ld64_2(dest, stride_8, DST_2); vis_ld64(ref[0], TMP14); vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_ld64_2(ref, 8, TMP16); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, offset, TMP18); vis_faligndata(TMP2, TMP4, REF_2); ref += stride; vis_xor(DST_0, REF_0, TMP20); vis_and(TMP20, MASK_fe, TMP20); vis_xor(DST_2, REF_2, TMP22); vis_mul8x16(CONST_128, TMP20, TMP20); vis_and(TMP22, MASK_fe, TMP22); vis_or(DST_0, REF_0, TMP24); vis_mul8x16(CONST_128, TMP22, TMP22); vis_or(DST_2, REF_2, TMP26); vis_ld64_2(dest, stride, DST_0); vis_faligndata(TMP14, TMP16, REF_0); vis_ld64_2(dest, stride_8, DST_2); vis_faligndata(TMP16, TMP18, REF_2); vis_and(TMP20, MASK_7f, TMP20); vis_and(TMP22, MASK_7f, TMP22); vis_psub16(TMP24, TMP20, TMP20); vis_st64(TMP20, dest[0]); vis_psub16(TMP26, TMP22, TMP22); vis_st64_2(TMP22, dest, 8); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP6); vis_ld64_2(ref, 8, TMP2); vis_and(TMP6, MASK_fe, TMP6); vis_ld64_2(ref, offset, TMP4); vis_mul8x16(CONST_128, TMP6, TMP6); vis_xor(DST_2, REF_2, TMP8); vis_and(TMP8, MASK_fe, TMP8); vis_or(DST_0, REF_0, TMP10); vis_ld64_2(dest, stride, DST_0); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(DST_2, REF_2, TMP12); vis_ld64_2(dest, stride_8, DST_2); vis_ld64(ref[0], TMP14); vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_2); vis_xor(DST_0, REF_0, TMP20); vis_and(TMP20, MASK_fe, TMP20); vis_xor(DST_2, REF_2, TMP22); vis_mul8x16(CONST_128, TMP20, TMP20); vis_and(TMP22, MASK_fe, TMP22); vis_or(DST_0, REF_0, TMP24); vis_mul8x16(CONST_128, TMP22, TMP22); vis_or(DST_2, REF_2, TMP26); vis_and(TMP20, MASK_7f, TMP20); vis_and(TMP22, MASK_7f, TMP22); vis_psub16(TMP24, TMP20, TMP20); vis_st64(TMP20, dest[0]); vis_psub16(TMP26, TMP22, TMP22); vis_st64_2(TMP22, dest, 8); } static void MC_avg_o_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); vis_ld64(dest[0], DST_0); vis_ld64(constants_fe[0], MASK_fe); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants128[0], CONST_128); ref += stride; height = (height >> 1) - 1; do { /* 12 cycles */ vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP4); vis_ld64_2(ref, offset, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(DST_0, REF_0, TMP6); vis_ld64_2(dest, stride, DST_0); ref += stride; vis_mul8x16(CONST_128, TMP4, TMP4); vis_ld64(ref[0], TMP12); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, offset, TMP2); vis_xor(DST_0, REF_0, TMP0); ref += stride; vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, TMP4); vis_st64(TMP4, dest[0]); dest += stride; vis_mul8x16(CONST_128, TMP0, TMP0); vis_or(DST_0, REF_0, TMP6); vis_ld64_2(dest, stride, DST_0); vis_faligndata(TMP12, TMP2, REF_0); vis_and(TMP0, MASK_7f, TMP0); vis_psub16(TMP6, TMP0, TMP4); vis_st64(TMP4, dest[0]); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP4); vis_ld64_2(ref, offset, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(DST_0, REF_0, TMP6); vis_ld64_2(dest, stride, DST_0); vis_mul8x16(CONST_128, TMP4, TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_xor(DST_0, REF_0, TMP0); vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, TMP4); vis_st64(TMP4, dest[0]); dest += stride; vis_mul8x16(CONST_128, TMP0, TMP0); vis_or(DST_0, REF_0, TMP6); vis_and(TMP0, MASK_7f, TMP0); vis_psub16(TMP6, TMP0, TMP4); vis_st64(TMP4, dest[0]); } static void MC_put_x_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; ref = vis_alignaddr(ref); vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); vis_ld64_2(ref, 16, TMP4); vis_ld64(constants_fe[0], MASK_fe); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants128[0], CONST_128); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } ref += stride; height = (height >> 1) - 1; do { /* 34 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP6); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP8); vis_ld64_2(ref, 16, TMP4); vis_and(TMP6, MASK_fe, TMP6); ref += stride; vis_ld64(ref[0], TMP14); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_ld64_2(ref, 8, TMP16); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_ld64_2(ref, 16, TMP18); ref += stride; vis_or(REF_4, REF_6, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_xor(REF_0, REF_2, TMP6); vis_xor(REF_4, REF_6, TMP8); vis_and(TMP6, MASK_fe, TMP6); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_or(REF_4, REF_6, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP14, TMP16, REF_0); vis_faligndata(TMP16, TMP18, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP14, TMP16, REF_2); vis_faligndata(TMP16, TMP18, REF_6); } else { vis_src1(TMP16, REF_2); vis_src1(TMP18, REF_6); } vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP6); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP8); vis_ld64_2(ref, 16, TMP4); vis_and(TMP6, MASK_fe, TMP6); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_or(REF_4, REF_6, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_xor(REF_0, REF_2, TMP6); vis_xor(REF_4, REF_6, TMP8); vis_and(TMP6, MASK_fe, TMP6); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_or(REF_4, REF_6, TMP12); vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); } static void MC_put_x_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; ref = vis_alignaddr(ref); vis_ld64(ref[0], TMP0); vis_ld64(ref[8], TMP2); vis_ld64(constants_fe[0], MASK_fe); vis_ld64(constants_7f[0], MASK_7f); vis_ld64(constants128[0], CONST_128); vis_faligndata(TMP0, TMP2, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); } else { vis_src1(TMP2, REF_2); } ref += stride; height = (height >> 1) - 1; do { /* 20 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, 8, TMP2); vis_and(TMP4, MASK_fe, TMP4); ref += stride; vis_ld64(ref[0], TMP8); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, 8, TMP10); ref += stride; vis_faligndata(TMP0, TMP2, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); } else { vis_src1(TMP2, REF_2); } vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_xor(REF_0, REF_2, TMP12); vis_and(TMP12, MASK_fe, TMP12); vis_or(REF_0, REF_2, TMP14); vis_mul8x16(CONST_128, TMP12, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP8, TMP10, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP8, TMP10, REF_2); } else { vis_src1(TMP10, REF_2); } vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, 8, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_alignaddr_g0((void *)off); vis_faligndata(TMP0, TMP2, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); } else { vis_src1(TMP2, REF_2); } vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_xor(REF_0, REF_2, TMP12); vis_and(TMP12, MASK_fe, TMP12); vis_or(REF_0, REF_2, TMP14); vis_mul8x16(CONST_128, TMP12, TMP12); vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); dest += stride; } static void MC_avg_x_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); vis_ld64(constants3[0], CONST_3); vis_fzero(ZERO); vis_ld64(constants256_512[0], CONST_256); ref = vis_alignaddr(ref); do { /* 26 cycles */ vis_ld64(ref[0], TMP0); vis_ld64(ref[8], TMP2); vis_alignaddr_g0((void *)off); vis_ld64(ref[16], TMP4); vis_ld64(dest[0], DST_0); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(dest[8], DST_2); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } vis_mul8x16au(REF_0, CONST_256, TMP0); vis_pmerge(ZERO, REF_2, TMP4); vis_mul8x16au(REF_0_1, CONST_256, TMP2); vis_pmerge(ZERO, REF_2_1, TMP6); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16al(DST_0, CONST_512, TMP4); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16al(DST_1, CONST_512, TMP6); vis_mul8x16au(REF_6, CONST_256, TMP12); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16au(REF_6_1, CONST_256, TMP14); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_4, CONST_256, TMP16); vis_padd16(TMP0, CONST_3, TMP8); vis_mul8x16au(REF_4_1, CONST_256, TMP18); vis_padd16(TMP2, CONST_3, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_padd16(TMP16, TMP12, TMP0); vis_st64(DST_0, dest[0]); vis_mul8x16al(DST_2, CONST_512, TMP4); vis_padd16(TMP18, TMP14, TMP2); vis_mul8x16al(DST_3, CONST_512, TMP6); vis_padd16(TMP0, CONST_3, TMP0); vis_padd16(TMP2, CONST_3, TMP2); vis_padd16(TMP0, TMP4, TMP0); vis_padd16(TMP2, TMP6, TMP2); vis_pack16(TMP0, DST_2); vis_pack16(TMP2, DST_3); vis_st64(DST_2, dest[8]); ref += stride; dest += stride; } while (--height); } static void MC_avg_x_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_times_2 = stride << 1; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); vis_ld64(constants3[0], CONST_3); vis_fzero(ZERO); vis_ld64(constants256_512[0], CONST_256); ref = vis_alignaddr(ref); height >>= 2; do { /* 47 cycles */ vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); ref += stride; vis_alignaddr_g0((void *)off); vis_ld64(ref[0], TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, 8, TMP6); ref += stride; vis_ld64(ref[0], TMP8); vis_ld64_2(ref, 8, TMP10); ref += stride; vis_faligndata(TMP4, TMP6, REF_4); vis_ld64(ref[0], TMP12); vis_ld64_2(ref, 8, TMP14); ref += stride; vis_faligndata(TMP8, TMP10, REF_S0); vis_faligndata(TMP12, TMP14, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_ld64(dest[0], DST_0); vis_faligndata(TMP0, TMP2, REF_2); vis_ld64_2(dest, stride, DST_2); vis_faligndata(TMP4, TMP6, REF_6); vis_faligndata(TMP8, TMP10, REF_S2); vis_faligndata(TMP12, TMP14, REF_S6); } else { vis_ld64(dest[0], DST_0); vis_src1(TMP2, REF_2); vis_ld64_2(dest, stride, DST_2); vis_src1(TMP6, REF_6); vis_src1(TMP10, REF_S2); vis_src1(TMP14, REF_S6); } vis_pmerge(ZERO, REF_0, TMP0); vis_mul8x16au(REF_0_1, CONST_256, TMP2); vis_pmerge(ZERO, REF_2, TMP4); vis_mul8x16au(REF_2_1, CONST_256, TMP6); vis_padd16(TMP0, CONST_3, TMP0); vis_mul8x16al(DST_0, CONST_512, TMP16); vis_padd16(TMP2, CONST_3, TMP2); vis_mul8x16al(DST_1, CONST_512, TMP18); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16au(REF_4, CONST_256, TMP8); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_4_1, CONST_256, TMP10); vis_padd16(TMP0, TMP16, TMP0); vis_mul8x16au(REF_6, CONST_256, TMP12); vis_padd16(TMP2, TMP18, TMP2); vis_mul8x16au(REF_6_1, CONST_256, TMP14); vis_padd16(TMP8, CONST_3, TMP8); vis_mul8x16al(DST_2, CONST_512, TMP16); vis_padd16(TMP8, TMP12, TMP8); vis_mul8x16al(DST_3, CONST_512, TMP18); vis_padd16(TMP10, TMP14, TMP10); vis_pack16(TMP0, DST_0); vis_pack16(TMP2, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP10, CONST_3, TMP10); vis_ld64_2(dest, stride, DST_0); vis_padd16(TMP8, TMP16, TMP8); vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/); vis_padd16(TMP10, TMP18, TMP10); vis_pack16(TMP8, DST_2); vis_pack16(TMP10, DST_3); vis_st64(DST_2, dest[0]); dest += stride; vis_mul8x16au(REF_S0_1, CONST_256, TMP2); vis_pmerge(ZERO, REF_S0, TMP0); vis_pmerge(ZERO, REF_S2, TMP24); vis_mul8x16au(REF_S2_1, CONST_256, TMP6); vis_padd16(TMP0, CONST_3, TMP0); vis_mul8x16au(REF_S4, CONST_256, TMP8); vis_padd16(TMP2, CONST_3, TMP2); vis_mul8x16au(REF_S4_1, CONST_256, TMP10); vis_padd16(TMP0, TMP24, TMP0); vis_mul8x16au(REF_S6, CONST_256, TMP12); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_S6_1, CONST_256, TMP14); vis_padd16(TMP8, CONST_3, TMP8); vis_mul8x16al(DST_0, CONST_512, TMP16); vis_padd16(TMP10, CONST_3, TMP10); vis_mul8x16al(DST_1, CONST_512, TMP18); vis_padd16(TMP8, TMP12, TMP8); vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20); vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22); vis_padd16(TMP0, TMP16, TMP0); vis_padd16(TMP2, TMP18, TMP2); vis_pack16(TMP0, DST_0); vis_padd16(TMP10, TMP14, TMP10); vis_pack16(TMP2, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP8, TMP20, TMP8); vis_padd16(TMP10, TMP22, TMP10); vis_pack16(TMP8, DST_2); vis_pack16(TMP10, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } static void MC_put_y_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_ld64(ref[0], TMP6); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, 8, TMP8); vis_faligndata(TMP2, TMP4, REF_4); vis_ld64_2(ref, offset, TMP10); ref += stride; vis_ld64(constants_fe[0], MASK_fe); vis_faligndata(TMP6, TMP8, REF_2); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP8, TMP10, REF_6); vis_ld64(constants128[0], CONST_128); height = (height >> 1) - 1; do { /* 24 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP12); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP16); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_or(REF_0, REF_2, TMP14); vis_ld64(ref[0], TMP6); vis_or(REF_4, REF_6, TMP18); vis_ld64_2(ref, 8, TMP8); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, offset, TMP10); ref += stride; vis_faligndata(TMP2, TMP4, REF_4); vis_and(TMP12, MASK_fe, TMP12); vis_and(TMP16, MASK_fe, TMP16); vis_mul8x16(CONST_128, TMP12, TMP12); vis_mul8x16(CONST_128, TMP16, TMP16); vis_xor(REF_0, REF_2, TMP0); vis_xor(REF_4, REF_6, TMP2); vis_or(REF_0, REF_2, TMP20); vis_and(TMP12, MASK_7f, TMP12); vis_and(TMP16, MASK_7f, TMP16); vis_psub16(TMP14, TMP12, TMP12); vis_st64(TMP12, dest[0]); vis_psub16(TMP18, TMP16, TMP16); vis_st64_2(TMP16, dest, 8); dest += stride; vis_or(REF_4, REF_6, TMP18); vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP2, MASK_fe, TMP2); vis_mul8x16(CONST_128, TMP0, TMP0); vis_faligndata(TMP6, TMP8, REF_2); vis_mul8x16(CONST_128, TMP2, TMP2); vis_faligndata(TMP8, TMP10, REF_6); vis_and(TMP0, MASK_7f, TMP0); vis_and(TMP2, MASK_7f, TMP2); vis_psub16(TMP20, TMP0, TMP0); vis_st64(TMP0, dest[0]); vis_psub16(TMP18, TMP2, TMP2); vis_st64_2(TMP2, dest, 8); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP12); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP16); vis_ld64_2(ref, offset, TMP4); vis_or(REF_0, REF_2, TMP14); vis_or(REF_4, REF_6, TMP18); vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_4); vis_and(TMP12, MASK_fe, TMP12); vis_and(TMP16, MASK_fe, TMP16); vis_mul8x16(CONST_128, TMP12, TMP12); vis_mul8x16(CONST_128, TMP16, TMP16); vis_xor(REF_0, REF_2, TMP0); vis_xor(REF_4, REF_6, TMP2); vis_or(REF_0, REF_2, TMP20); vis_and(TMP12, MASK_7f, TMP12); vis_and(TMP16, MASK_7f, TMP16); vis_psub16(TMP14, TMP12, TMP12); vis_st64(TMP12, dest[0]); vis_psub16(TMP18, TMP16, TMP16); vis_st64_2(TMP16, dest, 8); dest += stride; vis_or(REF_4, REF_6, TMP18); vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP2, MASK_fe, TMP2); vis_mul8x16(CONST_128, TMP0, TMP0); vis_mul8x16(CONST_128, TMP2, TMP2); vis_and(TMP0, MASK_7f, TMP0); vis_and(TMP2, MASK_7f, TMP2); vis_psub16(TMP20, TMP0, TMP0); vis_st64(TMP0, dest[0]); vis_psub16(TMP18, TMP2, TMP2); vis_st64_2(TMP2, dest, 8); } static void MC_put_y_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); ref += stride; vis_ld64(ref[0], TMP4); vis_ld64_2(ref, offset, TMP6); ref += stride; vis_ld64(constants_fe[0], MASK_fe); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP4, TMP6, REF_2); vis_ld64(constants128[0], CONST_128); height = (height >> 1) - 1; do { /* 12 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, offset, TMP2); ref += stride; vis_and(TMP4, MASK_fe, TMP4); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); ref += stride; vis_xor(REF_0, REF_2, TMP12); vis_and(TMP4, MASK_7f, TMP4); vis_and(TMP12, MASK_fe, TMP12); vis_mul8x16(CONST_128, TMP12, TMP12); vis_or(REF_0, REF_2, TMP14); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_faligndata(TMP0, TMP2, REF_2); vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, offset, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_xor(REF_0, REF_2, TMP12); vis_and(TMP4, MASK_7f, TMP4); vis_and(TMP12, MASK_fe, TMP12); vis_mul8x16(CONST_128, TMP12, TMP12); vis_or(REF_0, REF_2, TMP14); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); } static void MC_avg_y_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int stride_8 = stride + 8; int stride_16; int offset; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64_2(ref, offset, TMP4); stride_16 = stride + offset; vis_ld64(constants3[0], CONST_3); vis_faligndata(TMP0, TMP2, REF_2); vis_ld64(constants256_512[0], CONST_256); vis_faligndata(TMP2, TMP4, REF_6); height >>= 1; do { /* 31 cycles */ vis_ld64_2(ref, stride, TMP0); vis_pmerge(ZERO, REF_2, TMP12); vis_mul8x16au(REF_2_1, CONST_256, TMP14); vis_ld64_2(ref, stride_8, TMP2); vis_pmerge(ZERO, REF_6, TMP16); vis_mul8x16au(REF_6_1, CONST_256, TMP18); vis_ld64_2(ref, stride_16, TMP4); ref += stride; vis_ld64(dest[0], DST_0); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(dest, 8, DST_2); vis_faligndata(TMP2, TMP4, REF_4); vis_ld64_2(ref, stride, TMP6); vis_pmerge(ZERO, REF_0, TMP0); vis_mul8x16au(REF_0_1, CONST_256, TMP2); vis_ld64_2(ref, stride_8, TMP8); vis_pmerge(ZERO, REF_4, TMP4); vis_ld64_2(ref, stride_16, TMP10); ref += stride; vis_ld64_2(dest, stride, REF_S0/*DST_4*/); vis_faligndata(TMP6, TMP8, REF_2); vis_mul8x16au(REF_4_1, CONST_256, TMP6); vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/); vis_faligndata(TMP8, TMP10, REF_6); vis_mul8x16al(DST_0, CONST_512, TMP20); vis_padd16(TMP0, CONST_3, TMP0); vis_mul8x16al(DST_1, CONST_512, TMP22); vis_padd16(TMP2, CONST_3, TMP2); vis_mul8x16al(DST_2, CONST_512, TMP24); vis_padd16(TMP4, CONST_3, TMP4); vis_mul8x16al(DST_3, CONST_512, TMP26); vis_padd16(TMP6, CONST_3, TMP6); vis_padd16(TMP12, TMP20, TMP12); vis_mul8x16al(REF_S0, CONST_512, TMP20); vis_padd16(TMP14, TMP22, TMP14); vis_mul8x16al(REF_S0_1, CONST_512, TMP22); vis_padd16(TMP16, TMP24, TMP16); vis_mul8x16al(REF_S2, CONST_512, TMP24); vis_padd16(TMP18, TMP26, TMP18); vis_mul8x16al(REF_S2_1, CONST_512, TMP26); vis_padd16(TMP12, TMP0, TMP12); vis_mul8x16au(REF_2, CONST_256, TMP28); vis_padd16(TMP14, TMP2, TMP14); vis_mul8x16au(REF_2_1, CONST_256, TMP30); vis_padd16(TMP16, TMP4, TMP16); vis_mul8x16au(REF_6, CONST_256, REF_S4); vis_padd16(TMP18, TMP6, TMP18); vis_mul8x16au(REF_6_1, CONST_256, REF_S6); vis_pack16(TMP12, DST_0); vis_padd16(TMP28, TMP0, TMP12); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP30, TMP2, TMP14); vis_pack16(TMP16, DST_2); vis_padd16(REF_S4, TMP4, TMP16); vis_pack16(TMP18, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; vis_padd16(REF_S6, TMP6, TMP18); vis_padd16(TMP12, TMP20, TMP12); vis_padd16(TMP14, TMP22, TMP14); vis_pack16(TMP12, DST_0); vis_padd16(TMP16, TMP24, TMP16); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP18, TMP26, TMP18); vis_pack16(TMP16, DST_2); vis_pack16(TMP18, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; } while (--height); } static void MC_avg_y_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int stride_8; int offset; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64_2(ref, offset, TMP2); stride_8 = stride + offset; vis_ld64(constants3[0], CONST_3); vis_faligndata(TMP0, TMP2, REF_2); vis_ld64(constants256_512[0], CONST_256); height >>= 1; do { /* 20 cycles */ vis_ld64_2(ref, stride, TMP0); vis_pmerge(ZERO, REF_2, TMP8); vis_mul8x16au(REF_2_1, CONST_256, TMP10); vis_ld64_2(ref, stride_8, TMP2); ref += stride; vis_ld64(dest[0], DST_0); vis_ld64_2(dest, stride, DST_2); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, stride, TMP4); vis_mul8x16al(DST_0, CONST_512, TMP16); vis_pmerge(ZERO, REF_0, TMP12); vis_ld64_2(ref, stride_8, TMP6); ref += stride; vis_mul8x16al(DST_1, CONST_512, TMP18); vis_pmerge(ZERO, REF_0_1, TMP14); vis_padd16(TMP12, CONST_3, TMP12); vis_mul8x16al(DST_2, CONST_512, TMP24); vis_padd16(TMP14, CONST_3, TMP14); vis_mul8x16al(DST_3, CONST_512, TMP26); vis_faligndata(TMP4, TMP6, REF_2); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_mul8x16au(REF_2, CONST_256, TMP20); vis_padd16(TMP8, TMP16, TMP0); vis_mul8x16au(REF_2_1, CONST_256, TMP22); vis_padd16(TMP10, TMP18, TMP2); vis_pack16(TMP0, DST_0); vis_pack16(TMP2, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP12, TMP20, TMP12); vis_padd16(TMP14, TMP22, TMP14); vis_padd16(TMP12, TMP24, TMP0); vis_padd16(TMP14, TMP26, TMP2); vis_pack16(TMP0, DST_2); vis_pack16(TMP2, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } static void MC_put_xy_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; int stride_16 = stride + 16; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64(ref[16], TMP4); vis_ld64(constants2[0], CONST_2); vis_faligndata(TMP0, TMP2, REF_S0); vis_ld64(constants256_512[0], CONST_256); vis_faligndata(TMP2, TMP4, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); vis_faligndata(TMP2, TMP4, REF_S6); } else { vis_src1(TMP2, REF_S2); vis_src1(TMP4, REF_S6); } height >>= 1; do { vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP12); vis_pmerge(ZERO, REF_S0_1, TMP14); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride_8, TMP2); vis_mul8x16au(REF_S2, CONST_256, TMP16); vis_pmerge(ZERO, REF_S2_1, TMP18); vis_ld64_2(ref, stride_16, TMP4); ref += stride; vis_mul8x16au(REF_S4, CONST_256, TMP20); vis_pmerge(ZERO, REF_S4_1, TMP22); vis_ld64_2(ref, stride, TMP6); vis_mul8x16au(REF_S6, CONST_256, TMP24); vis_pmerge(ZERO, REF_S6_1, TMP26); vis_ld64_2(ref, stride_8, TMP8); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, stride_16, TMP10); ref += stride; vis_faligndata(TMP2, TMP4, REF_4); vis_faligndata(TMP6, TMP8, REF_S0); vis_faligndata(TMP8, TMP10, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); vis_faligndata(TMP6, TMP8, REF_S2); vis_faligndata(TMP8, TMP10, REF_S6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); vis_src1(TMP8, REF_S2); vis_src1(TMP10, REF_S6); } vis_mul8x16au(REF_0, CONST_256, TMP0); vis_pmerge(ZERO, REF_0_1, TMP2); vis_mul8x16au(REF_2, CONST_256, TMP4); vis_pmerge(ZERO, REF_2_1, TMP6); vis_padd16(TMP0, CONST_2, TMP8); vis_mul8x16au(REF_4, CONST_256, TMP0); vis_padd16(TMP2, CONST_2, TMP10); vis_mul8x16au(REF_4_1, CONST_256, TMP2); vis_padd16(TMP8, TMP4, TMP8); vis_mul8x16au(REF_6, CONST_256, TMP4); vis_padd16(TMP10, TMP6, TMP10); vis_mul8x16au(REF_6_1, CONST_256, TMP6); vis_padd16(TMP12, TMP8, TMP12); vis_padd16(TMP14, TMP10, TMP14); vis_padd16(TMP12, TMP16, TMP12); vis_padd16(TMP14, TMP18, TMP14); vis_pack16(TMP12, DST_0); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP0, CONST_2, TMP12); vis_mul8x16au(REF_S0, CONST_256, TMP0); vis_padd16(TMP2, CONST_2, TMP14); vis_mul8x16au(REF_S0_1, CONST_256, TMP2); vis_padd16(TMP12, TMP4, TMP12); vis_mul8x16au(REF_S2, CONST_256, TMP4); vis_padd16(TMP14, TMP6, TMP14); vis_mul8x16au(REF_S2_1, CONST_256, TMP6); vis_padd16(TMP20, TMP12, TMP20); vis_padd16(TMP22, TMP14, TMP22); vis_padd16(TMP20, TMP24, TMP20); vis_padd16(TMP22, TMP26, TMP22); vis_pack16(TMP20, DST_2); vis_pack16(TMP22, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; vis_padd16(TMP0, TMP4, TMP24); vis_mul8x16au(REF_S4, CONST_256, TMP0); vis_padd16(TMP2, TMP6, TMP26); vis_mul8x16au(REF_S4_1, CONST_256, TMP2); vis_padd16(TMP24, TMP8, TMP24); vis_padd16(TMP26, TMP10, TMP26); vis_pack16(TMP24, DST_0); vis_pack16(TMP26, DST_1); vis_st64(DST_0, dest[0]); vis_pmerge(ZERO, REF_S6, TMP4); vis_pmerge(ZERO, REF_S6_1, TMP6); vis_padd16(TMP0, TMP4, TMP0); vis_padd16(TMP2, TMP6, TMP2); vis_padd16(TMP0, TMP12, TMP0); vis_padd16(TMP2, TMP14, TMP2); vis_pack16(TMP0, DST_2); vis_pack16(TMP2, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; } while (--height); } static void MC_put_xy_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64(constants2[0], CONST_2); vis_ld64(constants256_512[0], CONST_256); vis_faligndata(TMP0, TMP2, REF_S0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); } else { vis_src1(TMP2, REF_S2); } height >>= 1; do { /* 26 cycles */ vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP8); vis_pmerge(ZERO, REF_S2, TMP12); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride_8, TMP2); ref += stride; vis_mul8x16au(REF_S0_1, CONST_256, TMP10); vis_pmerge(ZERO, REF_S2_1, TMP14); vis_ld64_2(ref, stride, TMP4); vis_ld64_2(ref, stride_8, TMP6); ref += stride; vis_faligndata(TMP0, TMP2, REF_S4); vis_pmerge(ZERO, REF_S4, TMP18); vis_pmerge(ZERO, REF_S4_1, TMP20); vis_faligndata(TMP4, TMP6, REF_S0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S6); vis_faligndata(TMP4, TMP6, REF_S2); } else { vis_src1(TMP2, REF_S6); vis_src1(TMP6, REF_S2); } vis_padd16(TMP18, CONST_2, TMP18); vis_mul8x16au(REF_S6, CONST_256, TMP22); vis_padd16(TMP20, CONST_2, TMP20); vis_mul8x16au(REF_S6_1, CONST_256, TMP24); vis_mul8x16au(REF_S0, CONST_256, TMP26); vis_pmerge(ZERO, REF_S0_1, TMP28); vis_mul8x16au(REF_S2, CONST_256, TMP30); vis_padd16(TMP18, TMP22, TMP18); vis_mul8x16au(REF_S2_1, CONST_256, TMP32); vis_padd16(TMP20, TMP24, TMP20); vis_padd16(TMP8, TMP18, TMP8); vis_padd16(TMP10, TMP20, TMP10); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP18, TMP26, TMP18); vis_padd16(TMP20, TMP28, TMP20); vis_padd16(TMP18, TMP30, TMP18); vis_padd16(TMP20, TMP32, TMP20); vis_pack16(TMP18, DST_2); vis_pack16(TMP20, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } static void MC_avg_xy_16_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; int stride_16 = stride + 16; vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64(ref[16], TMP4); vis_ld64(constants6[0], CONST_6); vis_faligndata(TMP0, TMP2, REF_S0); vis_ld64(constants256_1024[0], CONST_256); vis_faligndata(TMP2, TMP4, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); vis_faligndata(TMP2, TMP4, REF_S6); } else { vis_src1(TMP2, REF_S2); vis_src1(TMP4, REF_S6); } height >>= 1; do { /* 55 cycles */ vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP12); vis_pmerge(ZERO, REF_S0_1, TMP14); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride_8, TMP2); vis_mul8x16au(REF_S2, CONST_256, TMP16); vis_pmerge(ZERO, REF_S2_1, TMP18); vis_ld64_2(ref, stride_16, TMP4); ref += stride; vis_mul8x16au(REF_S4, CONST_256, TMP20); vis_pmerge(ZERO, REF_S4_1, TMP22); vis_ld64_2(ref, stride, TMP6); vis_mul8x16au(REF_S6, CONST_256, TMP24); vis_pmerge(ZERO, REF_S6_1, TMP26); vis_ld64_2(ref, stride_8, TMP8); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, stride_16, TMP10); ref += stride; vis_faligndata(TMP2, TMP4, REF_4); vis_ld64(dest[0], DST_0); vis_faligndata(TMP6, TMP8, REF_S0); vis_ld64_2(dest, 8, DST_2); vis_faligndata(TMP8, TMP10, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); vis_faligndata(TMP6, TMP8, REF_S2); vis_faligndata(TMP8, TMP10, REF_S6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); vis_src1(TMP8, REF_S2); vis_src1(TMP10, REF_S6); } vis_mul8x16al(DST_0, CONST_1024, TMP30); vis_pmerge(ZERO, REF_0, TMP0); vis_mul8x16al(DST_1, CONST_1024, TMP32); vis_pmerge(ZERO, REF_0_1, TMP2); vis_mul8x16au(REF_2, CONST_256, TMP4); vis_pmerge(ZERO, REF_2_1, TMP6); vis_mul8x16al(DST_2, CONST_1024, REF_0); vis_padd16(TMP0, CONST_6, TMP0); vis_mul8x16al(DST_3, CONST_1024, REF_2); vis_padd16(TMP2, CONST_6, TMP2); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16au(REF_4, CONST_256, TMP4); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_4_1, CONST_256, TMP6); vis_padd16(TMP12, TMP0, TMP12); vis_mul8x16au(REF_6, CONST_256, TMP8); vis_padd16(TMP14, TMP2, TMP14); vis_mul8x16au(REF_6_1, CONST_256, TMP10); vis_padd16(TMP12, TMP16, TMP12); vis_mul8x16au(REF_S0, CONST_256, REF_4); vis_padd16(TMP14, TMP18, TMP14); vis_mul8x16au(REF_S0_1, CONST_256, REF_6); vis_padd16(TMP12, TMP30, TMP12); vis_padd16(TMP14, TMP32, TMP14); vis_pack16(TMP12, DST_0); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP4, CONST_6, TMP4); vis_ld64_2(dest, stride, DST_0); vis_padd16(TMP6, CONST_6, TMP6); vis_mul8x16au(REF_S2, CONST_256, TMP12); vis_padd16(TMP4, TMP8, TMP4); vis_mul8x16au(REF_S2_1, CONST_256, TMP14); vis_padd16(TMP6, TMP10, TMP6); vis_padd16(TMP20, TMP4, TMP20); vis_padd16(TMP22, TMP6, TMP22); vis_padd16(TMP20, TMP24, TMP20); vis_padd16(TMP22, TMP26, TMP22); vis_padd16(TMP20, REF_0, TMP20); vis_mul8x16au(REF_S4, CONST_256, REF_0); vis_padd16(TMP22, REF_2, TMP22); vis_pack16(TMP20, DST_2); vis_pack16(TMP22, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; vis_ld64_2(dest, 8, DST_2); vis_mul8x16al(DST_0, CONST_1024, TMP30); vis_pmerge(ZERO, REF_S4_1, REF_2); vis_mul8x16al(DST_1, CONST_1024, TMP32); vis_padd16(REF_4, TMP0, TMP8); vis_mul8x16au(REF_S6, CONST_256, REF_4); vis_padd16(REF_6, TMP2, TMP10); vis_mul8x16au(REF_S6_1, CONST_256, REF_6); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_padd16(TMP8, TMP30, TMP8); vis_padd16(TMP10, TMP32, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(REF_0, TMP4, REF_0); vis_mul8x16al(DST_2, CONST_1024, TMP30); vis_padd16(REF_2, TMP6, REF_2); vis_mul8x16al(DST_3, CONST_1024, TMP32); vis_padd16(REF_0, REF_4, REF_0); vis_padd16(REF_2, REF_6, REF_2); vis_padd16(REF_0, TMP30, REF_0); /* stall */ vis_padd16(REF_2, TMP32, REF_2); vis_pack16(REF_0, DST_2); vis_pack16(REF_2, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; } while (--height); } static void MC_avg_xy_8_vis (uint8_t * dest, const uint8_t * _ref, const int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[0], TMP0); vis_fzero(ZERO); vis_ld64_2(ref, 8, TMP2); vis_ld64(constants6[0], CONST_6); vis_ld64(constants256_1024[0], CONST_256); vis_faligndata(TMP0, TMP2, REF_S0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); } else { vis_src1(TMP2, REF_S2); } height >>= 1; do { /* 31 cycles */ vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP8); vis_pmerge(ZERO, REF_S0_1, TMP10); vis_ld64_2(ref, stride_8, TMP2); ref += stride; vis_mul8x16au(REF_S2, CONST_256, TMP12); vis_pmerge(ZERO, REF_S2_1, TMP14); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride, TMP4); vis_faligndata(TMP0, TMP2, REF_S4); vis_ld64_2(ref, stride_8, TMP6); ref += stride; vis_ld64(dest[0], DST_0); vis_faligndata(TMP4, TMP6, REF_S0); vis_ld64_2(dest, stride, DST_2); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S6); vis_faligndata(TMP4, TMP6, REF_S2); } else { vis_src1(TMP2, REF_S6); vis_src1(TMP6, REF_S2); } vis_mul8x16al(DST_0, CONST_1024, TMP30); vis_pmerge(ZERO, REF_S4, TMP22); vis_mul8x16al(DST_1, CONST_1024, TMP32); vis_pmerge(ZERO, REF_S4_1, TMP24); vis_mul8x16au(REF_S6, CONST_256, TMP26); vis_pmerge(ZERO, REF_S6_1, TMP28); vis_mul8x16au(REF_S0, CONST_256, REF_S4); vis_padd16(TMP22, CONST_6, TMP22); vis_mul8x16au(REF_S0_1, CONST_256, REF_S6); vis_padd16(TMP24, CONST_6, TMP24); vis_mul8x16al(DST_2, CONST_1024, REF_0); vis_padd16(TMP22, TMP26, TMP22); vis_mul8x16al(DST_3, CONST_1024, REF_2); vis_padd16(TMP24, TMP28, TMP24); vis_mul8x16au(REF_S2, CONST_256, TMP26); vis_padd16(TMP8, TMP22, TMP8); vis_mul8x16au(REF_S2_1, CONST_256, TMP28); vis_padd16(TMP10, TMP24, TMP10); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_padd16(TMP8, TMP30, TMP8); vis_padd16(TMP10, TMP32, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(REF_S4, TMP22, TMP12); vis_padd16(REF_S6, TMP24, TMP14); vis_padd16(TMP12, TMP26, TMP12); vis_padd16(TMP14, TMP28, TMP14); vis_padd16(TMP12, REF_0, TMP12); vis_padd16(TMP14, REF_2, TMP14); vis_pack16(TMP12, DST_2); vis_pack16(TMP14, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } MPEG2_MC_EXTERN(vis); #endif /* defined(ARCH_SPARC) && defined(ENABLE_VIS) */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/libmpeg2convert.pc.in�������������������������������0000644�0001750�0001750�00000000411�14647725152�023337� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libmpeg2convert Description: libmpeg2 helper functions for converting to various formats. Version: @VERSION@ Libs: -L${libdir} -lmpeg2convert Cflags: -I${includedir}/@PACKAGE@ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/rgb.c�����������������������������������������������0000644�0001750�0001750�00000047630�14647725152�020240� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * rgb.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <xine/attributes.h> #include <inttypes.h> #include "mpeg2.h" #include "mpeg2convert.h" #include "convert_internal.h" static int matrix_coefficients = 6; static const int Inverse_Table_6_9[8][4] = { {117504, 138453, 13954, 34903}, /* no sequence_display_extension */ {117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */ {104597, 132201, 25675, 53279}, /* unspecified */ {104597, 132201, 25675, 53279}, /* reserved */ {104448, 132798, 24759, 53109}, /* FCC */ {104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */ {104597, 132201, 25675, 53279}, /* SMPTE 170M */ {117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ }; static const uint8_t dither[] ATTR_ALIGN(32) = { 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35, 15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35, 15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35, 15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35, 3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62, 3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62, 3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62, 3, 9, 27, 63, 1, 4, 25, 59, 5, 12, 28, 67, 3, 7, 26, 62, 19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26, 19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26, 19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26, 19, 45, 11, 27, 17, 41, 9, 22, 21, 49, 13, 30, 19, 44, 11, 26, 0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69, 0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69, 0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69, 0, 2, 24, 57, 6, 15, 30, 70, 0, 1, 23, 55, 6, 14, 29, 69, 16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33, 16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33, 16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33, 16, 38, 8, 20, 22, 52, 14, 34, 16, 37, 8, 19, 21, 51, 14, 33, 4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60, 4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60, 4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60, 4, 11, 28, 66, 2, 6, 26, 61, 4, 10, 27, 65, 2, 5, 25, 60, 20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23, 20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23, 20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23, 20, 47, 12, 29, 18, 43, 10, 25, 20, 46, 12, 28, 18, 42, 10, 23, 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 0, 0, 23, 54, 5, 13, 29, 68, 1, 3, 24, 58, 7, 17, 30, 71, 15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35, 15, 36, 7, 18, 21, 50, 13, 31, 17, 39, 9, 21, 22, 53, 15, 35 }; static const uint8_t dither_temporal[64] = { 0x00, 0x20, 0x21, 0x01, 0x40, 0x60, 0x61, 0x41, 0x42, 0x62, 0x63, 0x43, 0x02, 0x22, 0x23, 0x03, 0x80, 0xa0, 0xa1, 0x81, 0xc0, 0xe0, 0xe1, 0xc1, 0xc2, 0xe2, 0xe3, 0xc3, 0x82, 0xa2, 0xa3, 0x83, 0x84, 0xa4, 0xa5, 0x85, 0xc4, 0xe4, 0xe5, 0xc5, 0xc6, 0xe6, 0xe7, 0xc7, 0x86, 0xa6, 0xa7, 0x87, 0x04, 0x24, 0x25, 0x05, 0x44, 0x64, 0x65, 0x45, 0x46, 0x66, 0x67, 0x47, 0x06, 0x26, 0x27, 0x07 }; typedef struct { convert_rgb_t base; void * table_rV[256]; void * table_gU[256]; int table_gV[256]; void * table_bU[256]; } convert_rgb_c_t; #define RGB(type,i) \ U = pu[i]; \ V = pv[i]; \ r = (type *) id->table_rV[V]; \ g = (type *) (((uint8_t *)id->table_gU[U]) + id->table_gV[V]); \ b = (type *) id->table_bU[U]; #define DST(py,dst,i,j) \ Y = py[i]; \ dst[i] = r[Y] + g[Y] + b[Y]; #define DSTRGB(py,dst,i,j) \ Y = py[i]; \ dst[3*i] = r[Y]; dst[3*i+1] = g[Y]; dst[3*i+2] = b[Y]; #define DSTBGR(py,dst,i,j) \ Y = py[i]; \ dst[3*i] = b[Y]; dst[3*i+1] = g[Y]; dst[3*i+2] = r[Y]; #define DSTDITHER(py,dst,i,j) \ Y = py[i]; \ dst[i] = r[Y+pd[2*i+96*j]] + g[Y-pd[2*i+96*j]] + b[Y+pd[2*i+1+96*j]]; #define DO(x) x #define SKIP(x) #define DECLARE_420(func,type,num,DST,DITHER) \ static void func (void * _id, uint8_t * const * src, \ unsigned int v_offset) \ { \ const convert_rgb_c_t * const id = (convert_rgb_c_t *) _id; \ type * dst_1; \ const uint8_t * py_1, * pu, * pv; \ int i; \ DITHER(uint8_t dithpos = id->base.dither_offset;) \ \ dst_1 = (type *)(id->base.rgb_ptr + id->base.rgb_slice * v_offset); \ py_1 = src[0]; pu = src[1]; pv = src[2]; \ \ i = 8; \ do { \ const uint8_t * py_2; \ int j, U, V, Y; \ const type * r, * g, * b; \ type * dst_2; \ DITHER(const uint8_t * const pd = dither + 2 * dithpos;) \ \ dst_2 = (type *)((char *)dst_1 + id->base.rgb_stride); \ py_2 = py_1 + id->base.y_stride; \ j = id->base.width; \ do { \ RGB (type, 0) \ DST (py_1, dst_1, 0, 0) \ DST (py_1, dst_1, 1, 0) \ DST (py_2, dst_2, 0, 1) \ DST (py_2, dst_2, 1, 1) \ \ RGB (type, 1) \ DST (py_2, dst_2, 2, 1) \ DST (py_2, dst_2, 3, 1) \ DST (py_1, dst_1, 2, 0) \ DST (py_1, dst_1, 3, 0) \ \ RGB (type, 2) \ DST (py_1, dst_1, 4, 0) \ DST (py_1, dst_1, 5, 0) \ DST (py_2, dst_2, 4, 1) \ DST (py_2, dst_2, 5, 1) \ \ RGB (type, 3) \ DST (py_2, dst_2, 6, 1) \ DST (py_2, dst_2, 7, 1) \ DST (py_1, dst_1, 6, 0) \ DST (py_1, dst_1, 7, 0) \ \ pu += 4; \ pv += 4; \ py_1 += 8; \ py_2 += 8; \ dst_1 += 8 * num; \ dst_2 += 8 * num; \ } while (--j); \ if (--i == id->base.field) { \ dst_1 = (type *)(id->base.rgb_ptr + \ id->base.rgb_slice * (v_offset + 1)); \ py_1 = src[0] + id->base.y_stride_frame; \ pu = src[1] + id->base.uv_stride_frame; \ pv = src[2] + id->base.uv_stride_frame; \ } else { \ py_1 += id->base.y_increm; \ pu += id->base.uv_increm; \ pv += id->base.uv_increm; \ dst_1 = (type *)((char *)dst_1 + id->base.rgb_increm); \ DITHER(dithpos += id->base.dither_stride;) \ } \ } while (i); \ } DECLARE_420 (rgb_c_32_420, uint32_t, 1, DST, SKIP) DECLARE_420 (rgb_c_24_rgb_420, uint8_t, 3, DSTRGB, SKIP) DECLARE_420 (rgb_c_24_bgr_420, uint8_t, 3, DSTBGR, SKIP) DECLARE_420 (rgb_c_16_420, uint16_t, 1, DST, SKIP) DECLARE_420 (rgb_c_8_420, uint8_t, 1, DSTDITHER, DO) #define DECLARE_422(func,type,num,DST,DITHER) \ static void func (void * _id, uint8_t * const * src, \ unsigned int v_offset) \ { \ const convert_rgb_c_t * const id = (convert_rgb_c_t *) _id; \ type * dst; \ const uint8_t * py, * pu, * pv; \ int i; \ DITHER(uint8_t dithpos = id->base.dither_offset;) \ \ dst = (type *)(id->base.rgb_ptr + id->base.rgb_stride * v_offset); \ py = src[0]; pu = src[1]; pv = src[2]; \ \ i = 16; \ do { \ int j, U, V, Y; \ const type * r, * g, * b; \ DITHER(const uint8_t * const pd = dither + 2 * dithpos;) \ \ j = id->base.width; \ do { \ RGB (type, 0) \ DST (py, dst, 0, 0) \ DST (py, dst, 1, 0) \ \ RGB (type, 1) \ DST (py, dst, 2, 0) \ DST (py, dst, 3, 0) \ \ RGB (type, 2) \ DST (py, dst, 4, 0) \ DST (py, dst, 5, 0) \ \ RGB (type, 3) \ DST (py, dst, 6, 0) \ DST (py, dst, 7, 0) \ \ pu += 4; \ pv += 4; \ py += 8; \ dst += 8 * num; \ } while (--j); \ py += id->base.y_increm; \ pu += id->base.uv_increm; \ pv += id->base.uv_increm; \ dst = (type *)((char *)dst + id->base.rgb_increm); \ DITHER(dithpos += id->base.dither_stride;) \ } while (--i); \ } DECLARE_422 (rgb_c_32_422, uint32_t, 1, DST, SKIP) DECLARE_422 (rgb_c_24_rgb_422, uint8_t, 3, DSTRGB, SKIP) DECLARE_422 (rgb_c_24_bgr_422, uint8_t, 3, DSTBGR, SKIP) DECLARE_422 (rgb_c_16_422, uint16_t, 1, DST, SKIP) DECLARE_422 (rgb_c_8_422, uint8_t, 1, DSTDITHER, DO) #define DECLARE_444(func,type,num,DST,DITHER) \ static void func (void * _id, uint8_t * const * src, \ unsigned int v_offset) \ { \ const convert_rgb_c_t * const id = (convert_rgb_c_t *) _id; \ type * dst; \ const uint8_t * py, * pu, * pv; \ int i; \ DITHER(uint8_t dithpos = id->base.dither_offset;) \ \ dst = (type *)(id->base.rgb_ptr + id->base.rgb_stride * v_offset); \ py = src[0]; pu = src[1]; pv = src[2]; \ \ i = 16; \ do { \ int j, U, V, Y; \ const type * r, * g, * b; \ DITHER(const uint8_t * const pd = dither + 2 * dithpos;) \ \ j = id->base.width; \ do { \ RGB (type, 0) \ DST (py, dst, 0, 0) \ RGB (type, 1) \ DST (py, dst, 1, 0) \ RGB (type, 2) \ DST (py, dst, 2, 0) \ RGB (type, 3) \ DST (py, dst, 3, 0) \ RGB (type, 4) \ DST (py, dst, 4, 0) \ RGB (type, 5) \ DST (py, dst, 5, 0) \ RGB (type, 6) \ DST (py, dst, 6, 0) \ RGB (type, 7) \ DST (py, dst, 7, 0) \ \ pu += 8; \ pv += 8; \ py += 8; \ dst += 8 * num; \ } while (--j); \ py += id->base.y_increm; \ pu += id->base.y_increm; \ pv += id->base.y_increm; \ dst = (type *)((char *)dst + id->base.rgb_increm); \ DITHER(dithpos += id->base.dither_stride;) \ } while (--i); \ } DECLARE_444 (rgb_c_32_444, uint32_t, 1, DST, SKIP) DECLARE_444 (rgb_c_24_rgb_444, uint8_t, 3, DSTRGB, SKIP) DECLARE_444 (rgb_c_24_bgr_444, uint8_t, 3, DSTBGR, SKIP) DECLARE_444 (rgb_c_16_444, uint16_t, 1, DST, SKIP) DECLARE_444 (rgb_c_8_444, uint8_t, 1, DSTDITHER, DO) static void rgb_start (void * _id, const mpeg2_fbuf_t * fbuf, const mpeg2_picture_t * picture, const mpeg2_gop_t * gop) { convert_rgb_t * id = (convert_rgb_t *) _id; int uv_stride = id->uv_stride_frame; id->y_stride = id->y_stride_frame; id->rgb_ptr = fbuf->buf[0]; id->rgb_slice = id->rgb_stride = id->rgb_stride_frame; id->dither_stride = 32; id->dither_offset = dither_temporal[picture->temporal_reference & 63]; id->field = 0; if ((picture->nb_fields == 1) || (id->chroma420 && !(picture->flags & PIC_FLAG_PROGRESSIVE_FRAME))) { uv_stride <<= 1; id->y_stride <<= 1; id->rgb_stride <<= 1; id->dither_stride <<= 1; id->dither_offset += 16; if (picture->nb_fields == 1) { id->rgb_slice <<= 1; if (!(picture->flags & PIC_FLAG_TOP_FIELD_FIRST)) { id->rgb_ptr += id->rgb_stride_frame; id->dither_offset += 32; } } else id->field = 8 >> id->convert420; } id->y_increm = (id->y_stride << id->convert420) - id->y_stride_frame; id->uv_increm = uv_stride - id->uv_stride_frame; id->rgb_increm = (id->rgb_stride << id->convert420) - id->rgb_stride_min; id->dither_stride <<= id->convert420; } static inline int div_round (int dividend, int divisor) { if (dividend > 0) return (dividend + (divisor>>1)) / divisor; else return -((-dividend + (divisor>>1)) / divisor); } static unsigned int rgb_c_init (convert_rgb_c_t * id, mpeg2convert_rgb_order_t order, unsigned int bpp) { int i; uint8_t table_Y[1024]; uint32_t * table_32 = 0; uint16_t * table_16 = 0; uint8_t * table_8 = 0; uint8_t * table_332 = 0; int entry_size = 0; void * table_r = 0; void * table_g = 0; void * table_b = 0; int crv = Inverse_Table_6_9[matrix_coefficients][0]; int cbu = Inverse_Table_6_9[matrix_coefficients][1]; int cgu = -Inverse_Table_6_9[matrix_coefficients][2]; int cgv = -Inverse_Table_6_9[matrix_coefficients][3]; for (i = 0; i < 1024; i++) { int j; j = (76309 * (i - 384 - 16) + 32768) >> 16; table_Y[i] = (j < 0) ? 0 : ((j > 255) ? 255 : j); } switch (bpp) { case 32: if (!id) return (197 + 2*682 + 256 + 132) * sizeof (uint32_t); table_32 = (uint32_t *) (id + 1); entry_size = sizeof (uint32_t); table_r = table_32 + 197; table_b = table_32 + 197 + 685; table_g = table_32 + 197 + 2*682; for (i = -197; i < 256+197; i++) ((uint32_t *) table_r)[i] = table_Y[i+384] << ((order == MPEG2CONVERT_RGB) ? 16 : 0); for (i = -132; i < 256+132; i++) ((uint32_t *) table_g)[i] = table_Y[i+384] << 8; for (i = -232; i < 256+232; i++) ((uint32_t *) table_b)[i] = table_Y[i+384] << ((order == MPEG2CONVERT_RGB) ? 0 : 16); break; case 24: if (!id) return (256 + 2*232) * sizeof (uint8_t); table_8 = (uint8_t *) (id + 1); entry_size = sizeof (uint8_t); table_r = table_g = table_b = table_8 + 232; for (i = -232; i < 256+232; i++) ((uint8_t * )table_b)[i] = table_Y[i+384]; break; case 15: case 16: if (!id) return (197 + 2*682 + 256 + 132) * sizeof (uint16_t); table_16 = (uint16_t *) (id + 1); entry_size = sizeof (uint16_t); table_r = table_16 + 197; table_b = table_16 + 197 + 685; table_g = table_16 + 197 + 2*682; for (i = -197; i < 256+197; i++) { int j = table_Y[i+384] >> 3; if (order == MPEG2CONVERT_RGB) j <<= ((bpp==16) ? 11 : 10); ((uint16_t *)table_r)[i] = j; } for (i = -132; i < 256+132; i++) { int j = table_Y[i+384] >> ((bpp==16) ? 2 : 3); ((uint16_t *)table_g)[i] = j << 5; } for (i = -232; i < 256+232; i++) { int j = table_Y[i+384] >> 3; if (order == MPEG2CONVERT_BGR) j <<= ((bpp==16) ? 11 : 10); ((uint16_t *)table_b)[i] = j; } break; case 8: if (!id) return (197 + 2*682 + 256 + 232 + 71) * sizeof (uint8_t); table_332 = (uint8_t *) (id + 1); entry_size = sizeof (uint8_t); table_r = table_332 + 197; table_g = table_332 + 197 + 682 + 30; table_b = table_332 + 197 + 2*682; for (i = -197; i < 256+197+30; i++) ((uint8_t *)table_r)[i] = ((table_Y[i+384] * 7 / 255) << (order == MPEG2CONVERT_RGB ? 5 : 0)); for (i = -132; i < 256+132+30; i++) ((uint8_t *)table_g)[i-30] = ((table_Y[i+384] * 7 / 255) << (order == MPEG2CONVERT_RGB ? 2 : 3)); for (i = -232; i < 256+232+71; i++) ((uint8_t *)table_b)[i] = ((table_Y[i+384] / 85) << (order == MPEG2CONVERT_RGB ? 0 : 6)); break; } for (i = 0; i < 256; i++) { id->table_rV[i] = (((uint8_t *)table_r) + entry_size * div_round (crv * (i-128), 76309)); id->table_gU[i] = (((uint8_t *)table_g) + entry_size * div_round (cgu * (i-128), 76309)); id->table_gV[i] = entry_size * div_round (cgv * (i-128), 76309); id->table_bU[i] = (((uint8_t *)table_b) + entry_size * div_round (cbu * (i-128), 76309)); } return 0; } static int rgb_internal (mpeg2convert_rgb_order_t order, unsigned int bpp, int stage, void * _id, const mpeg2_sequence_t * seq, int stride, uint32_t accel, void * arg, mpeg2_convert_init_t * result) { convert_rgb_t * id = (convert_rgb_t *) _id; mpeg2convert_copy_t * copy = (mpeg2convert_copy_t *) 0; unsigned int id_size = sizeof (convert_rgb_t); int chroma420 = (seq->chroma_height < seq->height); int convert420 = 0; int rgb_stride_min = ((bpp + 7) >> 3) * seq->width; #ifdef ARCH_X86 if (!copy && (accel & MPEG2_ACCEL_X86_MMXEXT)) { convert420 = 0; copy = mpeg2convert_rgb_mmxext (order, bpp, seq); } if (!copy && (accel & MPEG2_ACCEL_X86_MMX)) { convert420 = 0; copy = mpeg2convert_rgb_mmx (order, bpp, seq); } #endif #ifdef ARCH_SPARC if (!copy && (accel & MPEG2_ACCEL_SPARC_VIS)) { convert420 = chroma420; copy = mpeg2convert_rgb_vis (order, bpp, seq); } #endif if (!copy) { int src, dest; static void (* rgb_c[3][5]) (void *, uint8_t * const *, unsigned int) = {{rgb_c_24_bgr_420, rgb_c_8_420, rgb_c_16_420, rgb_c_24_rgb_420, rgb_c_32_420}, {rgb_c_24_bgr_422, rgb_c_8_422, rgb_c_16_422, rgb_c_24_rgb_422, rgb_c_32_422}, {rgb_c_24_bgr_444, rgb_c_8_444, rgb_c_16_444, rgb_c_24_rgb_444, rgb_c_32_444}}; convert420 = chroma420; id_size = (sizeof (convert_rgb_c_t) + rgb_c_init ((convert_rgb_c_t *) id, order, bpp)); src = ((seq->chroma_width == seq->width) + (seq->chroma_height == seq->height)); dest = ((bpp == 24 && order == MPEG2CONVERT_BGR) ? 0 : (bpp + 7) >> 3); copy = rgb_c[src][dest]; } result->id_size = id_size; if (stride < rgb_stride_min) stride = rgb_stride_min; if (stage == MPEG2_CONVERT_STRIDE) return stride; else if (stage == MPEG2_CONVERT_START) { id->width = seq->width >> 3; id->y_stride_frame = seq->width; id->uv_stride_frame = seq->chroma_width; id->rgb_stride_frame = stride; id->rgb_stride_min = rgb_stride_min; id->chroma420 = chroma420; id->convert420 = convert420; result->buf_size[0] = stride * seq->height; result->buf_size[1] = result->buf_size[2] = 0; result->start = rgb_start; result->copy = copy; } return 0; } #define DECLARE(func,order,bpp) \ int func (int stage, void * id, \ const mpeg2_sequence_t * sequence, int stride, \ uint32_t accel, void * arg, mpeg2_convert_init_t * result) \ { \ return rgb_internal (order, bpp, stage, id, sequence, stride, \ accel, arg, result); \ } DECLARE (mpeg2convert_rgb32, MPEG2CONVERT_RGB, 32) DECLARE (mpeg2convert_rgb24, MPEG2CONVERT_RGB, 24) DECLARE (mpeg2convert_rgb16, MPEG2CONVERT_RGB, 16) DECLARE (mpeg2convert_rgb15, MPEG2CONVERT_RGB, 15) DECLARE (mpeg2convert_rgb8, MPEG2CONVERT_RGB, 8) DECLARE (mpeg2convert_bgr32, MPEG2CONVERT_BGR, 32) DECLARE (mpeg2convert_bgr24, MPEG2CONVERT_BGR, 24) DECLARE (mpeg2convert_bgr16, MPEG2CONVERT_BGR, 16) DECLARE (mpeg2convert_bgr15, MPEG2CONVERT_BGR, 15) DECLARE (mpeg2convert_bgr8, MPEG2CONVERT_BGR, 8) mpeg2_convert_t * mpeg2convert_rgb (mpeg2convert_rgb_order_t order, unsigned int bpp) { static mpeg2_convert_t * table[5][2] = {{mpeg2convert_rgb15, mpeg2convert_bgr15}, {mpeg2convert_rgb8, mpeg2convert_bgr8}, {mpeg2convert_rgb16, mpeg2convert_bgr16}, {mpeg2convert_rgb24, mpeg2convert_bgr24}, {mpeg2convert_rgb32, mpeg2convert_bgr32}}; if (order == MPEG2CONVERT_RGB || order == MPEG2CONVERT_BGR) { if (bpp == 15) return table[0][order == MPEG2CONVERT_BGR]; else if (bpp >= 8 && bpp <= 32 && (bpp & 7) == 0) return table[bpp >> 3][order == MPEG2CONVERT_BGR]; } return (mpeg2_convert_t *) 0; } ��������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/vlc.h�����������������������������������������������0000644�0001750�0001750�00000041652�14647725152�020255� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * vlc.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define GETWORD(bit_buf,shift,bit_ptr) \ do { \ bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \ bit_ptr += 2; \ } while (0) static inline void bitstream_init (mpeg2_decoder_t * decoder, const uint8_t * start) { decoder->bitstream_buf = (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3]; decoder->bitstream_ptr = start + 4; decoder->bitstream_bits = -16; } /* make sure that there are at least 16 valid bits in bit_buf */ #define NEEDBITS(bit_buf,bits,bit_ptr) \ do { \ if (unlikely (bits > 0)) { \ GETWORD (bit_buf, bits, bit_ptr); \ bits -= 16; \ } \ } while (0) /* remove num valid bits from bit_buf */ #define DUMPBITS(bit_buf,bits,num) \ do { \ bit_buf <<= (num); \ bits += (num); \ } while (0) /* take num bits from the high part of bit_buf and zero extend them */ #define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num))) /* take num bits from the high part of bit_buf and sign extend them */ #define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num))) typedef struct { uint8_t modes; uint8_t len; } MBtab; typedef struct { uint8_t delta; uint8_t len; } MVtab; typedef struct { int8_t dmv; uint8_t len; } DMVtab; typedef struct { uint8_t cbp; uint8_t len; } CBPtab; typedef struct { uint8_t size; uint8_t len; } DCtab; typedef struct { uint8_t run; uint8_t level; uint8_t len; } DCTtab; typedef struct { uint8_t mba; uint8_t len; } MBAtab; #define INTRA MACROBLOCK_INTRA #define QUANT MACROBLOCK_QUANT static const MBtab MB_I [] = { {INTRA|QUANT, 2}, {INTRA, 1} }; #define MC MACROBLOCK_MOTION_FORWARD #define CODED MACROBLOCK_PATTERN static const MBtab MB_P [] = { {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5}, {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1} }; #define FWD MACROBLOCK_MOTION_FORWARD #define BWD MACROBLOCK_MOTION_BACKWARD #define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD static const MBtab MB_B [] = { {0, 6}, {INTRA|QUANT, 6}, {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6}, {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5}, {INTRA, 5}, {INTRA, 5}, {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2} }; #undef INTRA #undef QUANT #undef MC #undef CODED #undef FWD #undef BWD #undef INTER static const MVtab MV_4 [] = { { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} }; static const MVtab MV_10 [] = { { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10}, {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7} }; static const DMVtab DMV_2 [] = { { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2} }; static const CBPtab CBP_7 [] = { {0x11, 7}, {0x12, 7}, {0x14, 7}, {0x18, 7}, {0x21, 7}, {0x22, 7}, {0x24, 7}, {0x28, 7}, {0x3f, 6}, {0x3f, 6}, {0x30, 6}, {0x30, 6}, {0x09, 6}, {0x09, 6}, {0x06, 6}, {0x06, 6}, {0x1f, 5}, {0x1f, 5}, {0x1f, 5}, {0x1f, 5}, {0x10, 5}, {0x10, 5}, {0x10, 5}, {0x10, 5}, {0x2f, 5}, {0x2f, 5}, {0x2f, 5}, {0x2f, 5}, {0x20, 5}, {0x20, 5}, {0x20, 5}, {0x20, 5}, {0x07, 5}, {0x07, 5}, {0x07, 5}, {0x07, 5}, {0x0b, 5}, {0x0b, 5}, {0x0b, 5}, {0x0b, 5}, {0x0d, 5}, {0x0d, 5}, {0x0d, 5}, {0x0d, 5}, {0x0e, 5}, {0x0e, 5}, {0x0e, 5}, {0x0e, 5}, {0x05, 5}, {0x05, 5}, {0x05, 5}, {0x05, 5}, {0x0a, 5}, {0x0a, 5}, {0x0a, 5}, {0x0a, 5}, {0x03, 5}, {0x03, 5}, {0x03, 5}, {0x03, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x01, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x02, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3}, {0x0f, 3} }; static const CBPtab CBP_9 [] = { {0, 9}, {0x00, 9}, {0x39, 9}, {0x36, 9}, {0x37, 9}, {0x3b, 9}, {0x3d, 9}, {0x3e, 9}, {0x17, 8}, {0x17, 8}, {0x1b, 8}, {0x1b, 8}, {0x1d, 8}, {0x1d, 8}, {0x1e, 8}, {0x1e, 8}, {0x27, 8}, {0x27, 8}, {0x2b, 8}, {0x2b, 8}, {0x2d, 8}, {0x2d, 8}, {0x2e, 8}, {0x2e, 8}, {0x19, 8}, {0x19, 8}, {0x16, 8}, {0x16, 8}, {0x29, 8}, {0x29, 8}, {0x26, 8}, {0x26, 8}, {0x35, 8}, {0x35, 8}, {0x3a, 8}, {0x3a, 8}, {0x33, 8}, {0x33, 8}, {0x3c, 8}, {0x3c, 8}, {0x15, 8}, {0x15, 8}, {0x1a, 8}, {0x1a, 8}, {0x13, 8}, {0x13, 8}, {0x1c, 8}, {0x1c, 8}, {0x25, 8}, {0x25, 8}, {0x2a, 8}, {0x2a, 8}, {0x23, 8}, {0x23, 8}, {0x2c, 8}, {0x2c, 8}, {0x31, 8}, {0x31, 8}, {0x32, 8}, {0x32, 8}, {0x34, 8}, {0x34, 8}, {0x38, 8}, {0x38, 8} }; static const DCtab DC_lum_5 [] = { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5} }; static const DCtab DC_chrom_5 [] = { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 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}, {4, 4}, {4, 4}, {5, 5} }; static const DCtab DC_long [] = { {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6}, {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9} }; static const DCTtab DCT_16 [] = { {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0}, { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0}, { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0}, { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0} }; static const DCTtab DCT_15 [] = { { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15}, { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15}, { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15}, { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15}, { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14}, { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14}, { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14}, { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14}, { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14}, { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14}, { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14}, { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14} }; static const DCTtab DCT_13 [] = { { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13}, { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13}, { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13}, { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13}, { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12}, { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12}, { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12}, { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12}, { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12}, { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12}, { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12}, { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12} }; static const DCTtab DCT_B14_10 [] = { { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10}, { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10} }; static const DCTtab DCT_B14_8 [] = { { 65, 0,12}, { 65, 0,12}, { 65, 0,12}, { 65, 0,12}, { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7}, { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8}, { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8} }; static const DCTtab DCT_B14AC_5 [] = { { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2} }; static const DCTtab DCT_B14DC_5 [] = { { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 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} }; static const DCTtab DCT_B15_10 [] = { { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9}, { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9} }; static const DCTtab DCT_B15_8 [] = { { 65, 0,12}, { 65, 0,12}, { 65, 0,12}, { 65, 0,12}, { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7}, { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8}, { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7}, { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7}, { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8}, { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8} }; static const MBAtab MBA_5 [] = { {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} }; static const MBAtab MBA_11 [] = { {32, 11}, {31, 11}, {30, 11}, {29, 11}, {28, 11}, {27, 11}, {26, 11}, {25, 11}, {24, 11}, {23, 11}, {22, 11}, {21, 11}, {20, 10}, {20, 10}, {19, 10}, {19, 10}, {18, 10}, {18, 10}, {17, 10}, {17, 10}, {16, 10}, {16, 10}, {15, 10}, {15, 10}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 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} }; ��������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/libmpeg2.pc.in��������������������������������������0000644�0001750�0001750�00000000360�14647725152�021741� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libmpeg2 Description: A decoding library for MPEG-1 and MPEG-2 streams. Version: @VERSION@ Libs: -L${libdir} -lmpeg2 Cflags: -I${includedir}/@PACKAGE@ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/motion_comp_mmx.c�����������������������������������0000644�0001750�0001750�00000062252�14647725152�022667� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_mmx.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_X86 #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #include "../include/mmx.h" #define CPU_MMXEXT 0 #define CPU_3DNOW 1 /* MMX code - needs a rewrite */ /* * Motion Compensation frequently needs to average values using the * formula (x+y+1)>>1. Both MMXEXT and 3Dnow include one instruction * to compute this, but it's been left out of classic MMX. * * We need to be careful of overflows when doing this computation. * Rather than unpacking data to 16-bits, which reduces parallelism, * we use the following formulas: * * (x+y)>>1 == (x&y)+((x^y)>>1) * (x+y+1)>>1 == (x|y)-((x^y)>>1) */ /* some rounding constants */ static mmx_t mask1 = {0xfefefefefefefefeLL}; static mmx_t round4 = {0x0002000200020002LL}; /* * This code should probably be compiled with loop unrolling * (ie, -funroll-loops in gcc)becuase some of the loops * use a small static number of iterations. This was written * with the assumption the compiler knows best about when * unrolling will help */ static inline void mmx_zero_reg () { /* load 0 into mm0 */ pxor_r2r (mm0, mm0); } static inline void mmx_average_2_U8 (uint8_t * dest, const uint8_t * src1, const uint8_t * src2) { /* *dest = (*src1 + *src2 + 1)/ 2; */ movq_m2r (*src1, mm1); /* load 8 src1 bytes */ movq_r2r (mm1, mm2); /* copy 8 src1 bytes */ movq_m2r (*src2, mm3); /* load 8 src2 bytes */ movq_r2r (mm3, mm4); /* copy 8 src2 bytes */ pxor_r2r (mm1, mm3); /* xor src1 and src2 */ pand_m2r (mask1, mm3); /* mask lower bits */ psrlq_i2r (1, mm3); /* /2 */ por_r2r (mm2, mm4); /* or src1 and src2 */ psubb_r2r (mm3, mm4); /* subtract subresults */ movq_r2m (mm4, *dest); /* store result in dest */ } static inline void mmx_interp_average_2_U8 (uint8_t * dest, const uint8_t * src1, const uint8_t * src2) { /* *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2; */ movq_m2r (*dest, mm1); /* load 8 dest bytes */ movq_r2r (mm1, mm2); /* copy 8 dest bytes */ movq_m2r (*src1, mm3); /* load 8 src1 bytes */ movq_r2r (mm3, mm4); /* copy 8 src1 bytes */ movq_m2r (*src2, mm5); /* load 8 src2 bytes */ movq_r2r (mm5, mm6); /* copy 8 src2 bytes */ pxor_r2r (mm3, mm5); /* xor src1 and src2 */ pand_m2r (mask1, mm5); /* mask lower bits */ psrlq_i2r (1, mm5); /* /2 */ por_r2r (mm4, mm6); /* or src1 and src2 */ psubb_r2r (mm5, mm6); /* subtract subresults */ movq_r2r (mm6, mm5); /* copy subresult */ pxor_r2r (mm1, mm5); /* xor srcavg and dest */ pand_m2r (mask1, mm5); /* mask lower bits */ psrlq_i2r (1, mm5); /* /2 */ por_r2r (mm2, mm6); /* or srcavg and dest */ psubb_r2r (mm5, mm6); /* subtract subresults */ movq_r2m (mm6, *dest); /* store result in dest */ } static inline void mmx_average_4_U8 (uint8_t * dest, const uint8_t * src1, const uint8_t * src2, const uint8_t * src3, const uint8_t * src4) { /* *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4; */ movq_m2r (*src1, mm1); /* load 8 src1 bytes */ movq_r2r (mm1, mm2); /* copy 8 src1 bytes */ punpcklbw_r2r (mm0, mm1); /* unpack low src1 bytes */ punpckhbw_r2r (mm0, mm2); /* unpack high src1 bytes */ movq_m2r (*src2, mm3); /* load 8 src2 bytes */ movq_r2r (mm3, mm4); /* copy 8 src2 bytes */ punpcklbw_r2r (mm0, mm3); /* unpack low src2 bytes */ punpckhbw_r2r (mm0, mm4); /* unpack high src2 bytes */ paddw_r2r (mm3, mm1); /* add lows */ paddw_r2r (mm4, mm2); /* add highs */ /* now have partials in mm1 and mm2 */ movq_m2r (*src3, mm3); /* load 8 src3 bytes */ movq_r2r (mm3, mm4); /* copy 8 src3 bytes */ punpcklbw_r2r (mm0, mm3); /* unpack low src3 bytes */ punpckhbw_r2r (mm0, mm4); /* unpack high src3 bytes */ paddw_r2r (mm3, mm1); /* add lows */ paddw_r2r (mm4, mm2); /* add highs */ movq_m2r (*src4, mm5); /* load 8 src4 bytes */ movq_r2r (mm5, mm6); /* copy 8 src4 bytes */ punpcklbw_r2r (mm0, mm5); /* unpack low src4 bytes */ punpckhbw_r2r (mm0, mm6); /* unpack high src4 bytes */ paddw_r2r (mm5, mm1); /* add lows */ paddw_r2r (mm6, mm2); /* add highs */ /* now have subtotal in mm1 and mm2 */ paddw_m2r (round4, mm1); psraw_i2r (2, mm1); /* /4 */ paddw_m2r (round4, mm2); psraw_i2r (2, mm2); /* /4 */ packuswb_r2r (mm2, mm1); /* pack (w/ saturation) */ movq_r2m (mm1, *dest); /* store result in dest */ } static inline void mmx_interp_average_4_U8 (uint8_t * dest, const uint8_t * src1, const uint8_t * src2, const uint8_t * src3, const uint8_t * src4) { /* *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2; */ movq_m2r (*src1, mm1); /* load 8 src1 bytes */ movq_r2r (mm1, mm2); /* copy 8 src1 bytes */ punpcklbw_r2r (mm0, mm1); /* unpack low src1 bytes */ punpckhbw_r2r (mm0, mm2); /* unpack high src1 bytes */ movq_m2r (*src2, mm3); /* load 8 src2 bytes */ movq_r2r (mm3, mm4); /* copy 8 src2 bytes */ punpcklbw_r2r (mm0, mm3); /* unpack low src2 bytes */ punpckhbw_r2r (mm0, mm4); /* unpack high src2 bytes */ paddw_r2r (mm3, mm1); /* add lows */ paddw_r2r (mm4, mm2); /* add highs */ /* now have partials in mm1 and mm2 */ movq_m2r (*src3, mm3); /* load 8 src3 bytes */ movq_r2r (mm3, mm4); /* copy 8 src3 bytes */ punpcklbw_r2r (mm0, mm3); /* unpack low src3 bytes */ punpckhbw_r2r (mm0, mm4); /* unpack high src3 bytes */ paddw_r2r (mm3, mm1); /* add lows */ paddw_r2r (mm4, mm2); /* add highs */ movq_m2r (*src4, mm5); /* load 8 src4 bytes */ movq_r2r (mm5, mm6); /* copy 8 src4 bytes */ punpcklbw_r2r (mm0, mm5); /* unpack low src4 bytes */ punpckhbw_r2r (mm0, mm6); /* unpack high src4 bytes */ paddw_r2r (mm5, mm1); /* add lows */ paddw_r2r (mm6, mm2); /* add highs */ paddw_m2r (round4, mm1); psraw_i2r (2, mm1); /* /4 */ paddw_m2r (round4, mm2); psraw_i2r (2, mm2); /* /4 */ /* now have subtotal/4 in mm1 and mm2 */ movq_m2r (*dest, mm3); /* load 8 dest bytes */ movq_r2r (mm3, mm4); /* copy 8 dest bytes */ packuswb_r2r (mm2, mm1); /* pack (w/ saturation) */ movq_r2r (mm1,mm2); /* copy subresult */ pxor_r2r (mm1, mm3); /* xor srcavg and dest */ pand_m2r (mask1, mm3); /* mask lower bits */ psrlq_i2r (1, mm3); /* /2 */ por_r2r (mm2, mm4); /* or srcavg and dest */ psubb_r2r (mm3, mm4); /* subtract subresults */ movq_r2m (mm4, *dest); /* store result in dest */ } /*-----------------------------------------------------------------------*/ static inline void MC_avg_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { mmx_zero_reg (); do { mmx_average_2_U8 (dest, dest, ref); if (width == 16) mmx_average_2_U8 (dest+8, dest+8, ref+8); dest += stride; ref += stride; } while (--height); } static void MC_avg_o_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_mmx (16, height, dest, ref, stride); } static void MC_avg_o_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { mmx_zero_reg (); do { movq_m2r (* ref, mm1); /* load 8 ref bytes */ movq_r2m (mm1,* dest); /* store 8 bytes at curr */ if (width == 16) { movq_m2r (* (ref+8), mm1); /* load 8 ref bytes */ movq_r2m (mm1,* (dest+8)); /* store 8 bytes at curr */ } dest += stride; ref += stride; } while (--height); } static void MC_put_o_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_mmx (16, height, dest, ref, stride); } static void MC_put_o_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ /* Half pixel interpolation in the x direction */ static inline void MC_avg_x_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { mmx_zero_reg (); do { mmx_interp_average_2_U8 (dest, ref, ref+1); if (width == 16) mmx_interp_average_2_U8 (dest+8, ref+8, ref+9); dest += stride; ref += stride; } while (--height); } static void MC_avg_x_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_x_mmx (16, height, dest, ref, stride); } static void MC_avg_x_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_x_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_x_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { mmx_zero_reg (); do { mmx_average_2_U8 (dest, ref, ref+1); if (width == 16) mmx_average_2_U8 (dest+8, ref+8, ref+9); dest += stride; ref += stride; } while (--height); } static void MC_put_x_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_x_mmx (16, height, dest, ref, stride); } static void MC_put_x_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_x_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_avg_xy_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { const uint8_t * ref_next = ref + stride; mmx_zero_reg (); do { mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); if (width == 16) mmx_interp_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_avg_xy_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_xy_mmx (16, height, dest, ref, stride); } static void MC_avg_xy_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_xy_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_xy_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { const uint8_t * ref_next = ref + stride; mmx_zero_reg (); do { mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); if (width == 16) mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_put_xy_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_xy_mmx (16, height, dest, ref, stride); } static void MC_put_xy_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_xy_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_avg_y_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { const uint8_t * ref_next = ref + stride; mmx_zero_reg (); do { mmx_interp_average_2_U8 (dest, ref, ref_next); if (width == 16) mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_avg_y_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_y_mmx (16, height, dest, ref, stride); } static void MC_avg_y_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg_y_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_y_mmx (const int width, int height, uint8_t * dest, const uint8_t * ref, const int stride) { const uint8_t * ref_next = ref + stride; mmx_zero_reg (); do { mmx_average_2_U8 (dest, ref, ref_next); if (width == 16) mmx_average_2_U8 (dest+8, ref+8, ref_next+8); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_put_y_16_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_y_mmx (16, height, dest, ref, stride); } static void MC_put_y_8_mmx (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put_y_mmx (8, height, dest, ref, stride); } MPEG2_MC_EXTERN (mmx) /* CPU_MMXEXT/CPU_3DNOW adaptation layer */ #define pavg_r2r(src,dest) \ do { \ if (cpu == CPU_MMXEXT) \ pavgb_r2r (src, dest); \ else \ pavgusb_r2r (src, dest); \ } while (0) #define pavg_m2r(src,dest) \ do { \ if (cpu == CPU_MMXEXT) \ pavgb_m2r (src, dest); \ else \ pavgusb_m2r (src, dest); \ } while (0) /* CPU_MMXEXT code */ static inline void MC_put1_8 (int height, uint8_t * dest, const uint8_t * ref, const int stride) { do { movq_m2r (*ref, mm0); movq_r2m (mm0, *dest); ref += stride; dest += stride; } while (--height); } static inline void MC_put1_16 (int height, uint8_t * dest, const uint8_t * ref, const int stride) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); ref += stride; movq_r2m (mm0, *dest); movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static inline void MC_avg1_8 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int cpu) { do { movq_m2r (*ref, mm0); pavg_m2r (*dest, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_avg1_16 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); pavg_m2r (*dest, mm0); pavg_m2r (*(dest+8), mm1); movq_r2m (mm0, *dest); ref += stride; movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static inline void MC_put2_8 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int offset, const int cpu) { do { movq_m2r (*ref, mm0); pavg_m2r (*(ref+offset), mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_put2_16 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int offset, const int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); pavg_m2r (*(ref+offset), mm0); pavg_m2r (*(ref+offset+8), mm1); movq_r2m (mm0, *dest); ref += stride; movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static inline void MC_avg2_8 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int offset, const int cpu) { do { movq_m2r (*ref, mm0); pavg_m2r (*(ref+offset), mm0); pavg_m2r (*dest, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_avg2_16 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int offset, const int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); pavg_m2r (*(ref+offset), mm0); pavg_m2r (*(ref+offset+8), mm1); pavg_m2r (*dest, mm0); pavg_m2r (*(dest+8), mm1); ref += stride; movq_r2m (mm0, *dest); movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static mmx_t mask_one = {0x0101010101010101LL}; static inline void MC_put4_8 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int cpu) { movq_m2r (*ref, mm0); movq_m2r (*(ref+1), mm1); movq_r2r (mm0, mm7); pxor_r2r (mm1, mm7); pavg_r2r (mm1, mm0); ref += stride; do { movq_m2r (*ref, mm2); movq_r2r (mm0, mm5); movq_m2r (*(ref+1), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); pxor_r2r (mm2, mm5); pand_r2r (mm5, mm7); pavg_r2r (mm2, mm0); pand_m2r (mask_one, mm7); psubusb_r2r (mm7, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; movq_r2r (mm6, mm7); /* unroll ! */ movq_r2r (mm2, mm0); /* unroll ! */ } while (--height); } static inline void MC_put4_16 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+stride+1), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+1), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_r2m (mm0, *dest); movq_m2r (*(ref+8), mm0); movq_m2r (*(ref+stride+9), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+9), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride+8), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); ref += stride; movq_r2m (mm0, *(dest+8)); dest += stride; } while (--height); } static inline void MC_avg4_8 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+stride+1), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+1), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_m2r (*dest, mm1); pavg_r2r (mm1, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_avg4_16 (int height, uint8_t * dest, const uint8_t * ref, const int stride, const int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+stride+1), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+1), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_m2r (*dest, mm1); pavg_r2r (mm1, mm0); movq_r2m (mm0, *dest); movq_m2r (*(ref+8), mm0); movq_m2r (*(ref+stride+9), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+9), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride+8), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_m2r (*(dest+8), mm1); pavg_r2r (mm1, mm0); ref += stride; movq_r2m (mm0, *(dest+8)); dest += stride; } while (--height); } static void MC_avg_o_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_avg_o_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_put_o_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put1_16 (height, dest, ref, stride); } static void MC_put_o_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put1_8 (height, dest, ref, stride); } static void MC_avg_x_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_avg_x_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_put_x_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_put_x_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_avg_y_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_avg_y_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_put_y_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_put_y_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_avg_xy_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_avg_xy_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_put_xy_16_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_put_xy_8_mmxext (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT); } MPEG2_MC_EXTERN (mmxext) static void MC_avg_o_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW); } static void MC_avg_o_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW); } static void MC_put_o_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put1_16 (height, dest, ref, stride); } static void MC_put_o_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put1_8 (height, dest, ref, stride); } static void MC_avg_x_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_avg_x_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_put_x_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_put_x_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_avg_y_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_avg_y_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_put_y_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_put_y_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_avg_xy_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW); } static void MC_avg_xy_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW); } static void MC_put_xy_16_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put4_16 (height, dest, ref, stride, CPU_3DNOW); } static void MC_put_xy_8_3dnow (uint8_t * dest, const uint8_t * ref, int stride, int height) { MC_put4_8 (height, dest, ref, stride, CPU_3DNOW); } MPEG2_MC_EXTERN (3dnow) #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/idct_mlib.c�����������������������������������������0000644�0001750�0001750�00000003576�14647725152�021415� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_mlib.c * Copyright (C) 1999-2003 Håkan Hjort <d95hjort@dtek.chalmers.se> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef LIBMPEG2_MLIB #include <mlib_types.h> #include <mlib_status.h> #include <mlib_sys.h> #include <mlib_video.h> #include <string.h> #include <inttypes.h> #include "../include/mpeg2.h" #include "mpeg2_internal.h" void mpeg2_idct_add_mlib (const int last, int16_t * const block, uint8_t * const dest, const int stride) { mlib_VideoIDCT_IEEE_S16_S16 (block, block); mlib_VideoAddBlock_U8_S16 (dest, block, stride); memset (block, 0, 64 * sizeof (uint16_t)); } void mpeg2_idct_copy_mlib_non_ieee (int16_t * const block, uint8_t * const dest, const int stride) { mlib_VideoIDCT8x8_U8_S16 (dest, block, stride); memset (block, 0, 64 * sizeof (uint16_t)); } void mpeg2_idct_add_mlib_non_ieee (const int last, int16_t * const block, uint8_t * const dest, const int stride) { mlib_VideoIDCT8x8_S16_S16 (block, block); mlib_VideoAddBlock_U8_S16 (dest, block, stride); memset (block, 0, 64 * sizeof (uint16_t)); } #endif ����������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/idct_alpha.c����������������������������������������0000644�0001750�0001750�00000022604�14647725152�021550� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_alpha.c * Copyright (C) 2002-2003 Falk Hueffner <falk@debian.org> * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_ALPHA #include <stdlib.h> #include <inttypes.h> #include "mpeg2.h" #include <xine/attributes.h> #include "mpeg2_internal.h" #include "alpha_asm.h" #define W1 2841 /* 2048 * sqrt (2) * cos (1 * pi / 16) */ #define W2 2676 /* 2048 * sqrt (2) * cos (2 * pi / 16) */ #define W3 2408 /* 2048 * sqrt (2) * cos (3 * pi / 16) */ #define W5 1609 /* 2048 * sqrt (2) * cos (5 * pi / 16) */ #define W6 1108 /* 2048 * sqrt (2) * cos (6 * pi / 16) */ #define W7 565 /* 2048 * sqrt (2) * cos (7 * pi / 16) */ extern uint8_t mpeg2_clip[3840 * 2 + 256]; #define CLIP(i) ((mpeg2_clip + 3840)[i]) #if 0 #define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ do { \ t0 = W0 * d0 + W1 * d1; \ t1 = W0 * d1 - W1 * d0; \ } while (0) #else #define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ do { \ int_fast32_t tmp = W0 * (d0 + d1); \ t0 = tmp + (W1 - W0) * d1; \ t1 = tmp - (W1 + W0) * d0; \ } while (0) #endif static void inline idct_row (int16_t * const block) { uint64_t l, r; int_fast32_t d0, d1, d2, d3; int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3; int_fast32_t t0, t1, t2, t3; l = ldq (block); r = ldq (block + 4); /* shortcut */ if (likely (!((l & ~0xffffUL) | r))) { uint64_t tmp = (uint16_t) (l >> 1); tmp |= tmp << 16; tmp |= tmp << 32; ((int32_t *)block)[0] = tmp; ((int32_t *)block)[1] = tmp; ((int32_t *)block)[2] = tmp; ((int32_t *)block)[3] = tmp; return; } d0 = (sextw (l) << 11) + 2048; d1 = sextw (extwl (l, 2)); d2 = sextw (extwl (l, 4)) << 11; d3 = sextw (extwl (l, 6)); t0 = d0 + d2; t1 = d0 - d2; BUTTERFLY (t2, t3, W6, W2, d3, d1); a0 = t0 + t2; a1 = t1 + t3; a2 = t1 - t3; a3 = t0 - t2; d0 = sextw (r); d1 = sextw (extwl (r, 2)); d2 = sextw (extwl (r, 4)); d3 = sextw (extwl (r, 6)); BUTTERFLY (t0, t1, W7, W1, d3, d0); BUTTERFLY (t2, t3, W3, W5, d1, d2); b0 = t0 + t2; b3 = t1 + t3; t0 -= t2; t1 -= t3; b1 = ((t0 + t1) >> 8) * 181; b2 = ((t0 - t1) >> 8) * 181; block[0] = (a0 + b0) >> 12; block[1] = (a1 + b1) >> 12; block[2] = (a2 + b2) >> 12; block[3] = (a3 + b3) >> 12; block[4] = (a3 - b3) >> 12; block[5] = (a2 - b2) >> 12; block[6] = (a1 - b1) >> 12; block[7] = (a0 - b0) >> 12; } static void inline idct_col (int16_t * const block) { int_fast32_t d0, d1, d2, d3; int_fast32_t a0, a1, a2, a3, b0, b1, b2, b3; int_fast32_t t0, t1, t2, t3; d0 = (block[8*0] << 11) + 65536; d1 = block[8*1]; d2 = block[8*2] << 11; d3 = block[8*3]; t0 = d0 + d2; t1 = d0 - d2; BUTTERFLY (t2, t3, W6, W2, d3, d1); a0 = t0 + t2; a1 = t1 + t3; a2 = t1 - t3; a3 = t0 - t2; d0 = block[8*4]; d1 = block[8*5]; d2 = block[8*6]; d3 = block[8*7]; BUTTERFLY (t0, t1, W7, W1, d3, d0); BUTTERFLY (t2, t3, W3, W5, d1, d2); b0 = t0 + t2; b3 = t1 + t3; t0 -= t2; t1 -= t3; b1 = ((t0 + t1) >> 8) * 181; b2 = ((t0 - t1) >> 8) * 181; block[8*0] = (a0 + b0) >> 17; block[8*1] = (a1 + b1) >> 17; block[8*2] = (a2 + b2) >> 17; block[8*3] = (a3 + b3) >> 17; block[8*4] = (a3 - b3) >> 17; block[8*5] = (a2 - b2) >> 17; block[8*6] = (a1 - b1) >> 17; block[8*7] = (a0 - b0) >> 17; } void mpeg2_idct_copy_mvi (int16_t * block, uint8_t * dest, const int stride) { uint64_t clampmask; int i; for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); clampmask = zap (-1, 0xaa); /* 0x00ff00ff00ff00ff */ do { uint64_t shorts0, shorts1; shorts0 = ldq (block); shorts0 = maxsw4 (shorts0, 0); shorts0 = minsw4 (shorts0, clampmask); stl (pkwb (shorts0), dest); shorts1 = ldq (block + 4); shorts1 = maxsw4 (shorts1, 0); shorts1 = minsw4 (shorts1, clampmask); stl (pkwb (shorts1), dest + 4); stq (0, block); stq (0, block + 4); dest += stride; block += 8; } while (--i); } void mpeg2_idct_add_mvi (const int last, int16_t * block, uint8_t * dest, const int stride) { uint64_t clampmask; uint64_t signmask; int i; if (last != 129 || (block[0] & (7 << 4)) == (4 << 4)) { for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); clampmask = zap (-1, 0xaa); /* 0x00ff00ff00ff00ff */ signmask = zap (-1, 0x33); signmask ^= signmask >> 1; /* 0x8000800080008000 */ do { uint64_t shorts0, pix0, signs0; uint64_t shorts1, pix1, signs1; shorts0 = ldq (block); shorts1 = ldq (block + 4); pix0 = unpkbw (ldl (dest)); /* signed subword add (MMX paddw). */ signs0 = shorts0 & signmask; shorts0 &= ~signmask; shorts0 += pix0; shorts0 ^= signs0; /* clamp. */ shorts0 = maxsw4 (shorts0, 0); shorts0 = minsw4 (shorts0, clampmask); /* next 4. */ pix1 = unpkbw (ldl (dest + 4)); signs1 = shorts1 & signmask; shorts1 &= ~signmask; shorts1 += pix1; shorts1 ^= signs1; shorts1 = maxsw4 (shorts1, 0); shorts1 = minsw4 (shorts1, clampmask); stl (pkwb (shorts0), dest); stl (pkwb (shorts1), dest + 4); stq (0, block); stq (0, block + 4); dest += stride; block += 8; } while (--i); } else { int DC; uint64_t p0, p1, p2, p3, p4, p5, p6, p7; uint64_t DCs; DC = (block[0] + 64) >> 7; block[0] = block[63] = 0; p0 = ldq (dest + 0 * stride); p1 = ldq (dest + 1 * stride); p2 = ldq (dest + 2 * stride); p3 = ldq (dest + 3 * stride); p4 = ldq (dest + 4 * stride); p5 = ldq (dest + 5 * stride); p6 = ldq (dest + 6 * stride); p7 = ldq (dest + 7 * stride); if (DC > 0) { DCs = BYTE_VEC (likely (DC <= 255) ? DC : 255); p0 += minub8 (DCs, ~p0); p1 += minub8 (DCs, ~p1); p2 += minub8 (DCs, ~p2); p3 += minub8 (DCs, ~p3); p4 += minub8 (DCs, ~p4); p5 += minub8 (DCs, ~p5); p6 += minub8 (DCs, ~p6); p7 += minub8 (DCs, ~p7); } else { DCs = BYTE_VEC (likely (-DC <= 255) ? -DC : 255); p0 -= minub8 (DCs, p0); p1 -= minub8 (DCs, p1); p2 -= minub8 (DCs, p2); p3 -= minub8 (DCs, p3); p4 -= minub8 (DCs, p4); p5 -= minub8 (DCs, p5); p6 -= minub8 (DCs, p6); p7 -= minub8 (DCs, p7); } stq (p0, dest + 0 * stride); stq (p1, dest + 1 * stride); stq (p2, dest + 2 * stride); stq (p3, dest + 3 * stride); stq (p4, dest + 4 * stride); stq (p5, dest + 5 * stride); stq (p6, dest + 6 * stride); stq (p7, dest + 7 * stride); } } void mpeg2_idct_copy_alpha (int16_t * block, uint8_t * dest, const int stride) { int i; for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); do { dest[0] = CLIP (block[0]); dest[1] = CLIP (block[1]); dest[2] = CLIP (block[2]); dest[3] = CLIP (block[3]); dest[4] = CLIP (block[4]); dest[5] = CLIP (block[5]); dest[6] = CLIP (block[6]); dest[7] = CLIP (block[7]); stq(0, block); stq(0, block + 4); dest += stride; block += 8; } while (--i); } void mpeg2_idct_add_alpha (const int last, int16_t * block, uint8_t * dest, const int stride) { int i; if (last != 129 || (block[0] & (7 << 4)) == (4 << 4)) { for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); do { dest[0] = CLIP (block[0] + dest[0]); dest[1] = CLIP (block[1] + dest[1]); dest[2] = CLIP (block[2] + dest[2]); dest[3] = CLIP (block[3] + dest[3]); dest[4] = CLIP (block[4] + dest[4]); dest[5] = CLIP (block[5] + dest[5]); dest[6] = CLIP (block[6] + dest[6]); dest[7] = CLIP (block[7] + dest[7]); stq(0, block); stq(0, block + 4); dest += stride; block += 8; } while (--i); } else { int DC; DC = (block[0] + 64) >> 7; block[0] = block[63] = 0; i = 8; do { dest[0] = CLIP (DC + dest[0]); dest[1] = CLIP (DC + dest[1]); dest[2] = CLIP (DC + dest[2]); dest[3] = CLIP (DC + dest[3]); dest[4] = CLIP (DC + dest[4]); dest[5] = CLIP (DC + dest[5]); dest[6] = CLIP (DC + dest[6]); dest[7] = CLIP (DC + dest[7]); dest += stride; } while (--i); } } void mpeg2_idct_alpha_init (void) { extern uint8_t mpeg2_scan_norm[64]; extern uint8_t mpeg2_scan_alt[64]; int i, j; for (i = 0; i < 64; i++) { j = mpeg2_scan_norm[i]; mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); j = mpeg2_scan_alt[i]; mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); } } #endif /* ARCH_ALPHA */ ����������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/motion_comp.c���������������������������������������0000644�0001750�0001750�00000007034�14647725152�022003� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" mpeg2_mc_t mpeg2_mc; void mpeg2_mc_init (uint32_t accel) { #ifdef ARCH_X86 if (accel & MPEG2_ACCEL_X86_MMXEXT) mpeg2_mc = mpeg2_mc_mmxext; else if (accel & MPEG2_ACCEL_X86_3DNOW) mpeg2_mc = mpeg2_mc_3dnow; else if (accel & MPEG2_ACCEL_X86_MMX) mpeg2_mc = mpeg2_mc_mmx; else #endif #ifdef ARCH_PPC if (accel & MPEG2_ACCEL_PPC_ALTIVEC) mpeg2_mc = mpeg2_mc_altivec; else #endif #ifdef ARCH_ALPHA if (accel & MPEG2_ACCEL_ALPHA) mpeg2_mc = mpeg2_mc_alpha; else #endif #ifdef ARCH_SPARC if (accel & MPEG2_ACCEL_SPARC_VIS) mpeg2_mc = mpeg2_mc_vis; else #endif mpeg2_mc = mpeg2_mc_c; } #define avg2(a,b) ((a+b+1)>>1) #define avg4(a,b,c,d) ((a+b+c+d+2)>>2) #define predict_o(i) (ref[i]) #define predict_x(i) (avg2 (ref[i], ref[i+1])) #define predict_y(i) (avg2 (ref[i], (ref+stride)[i])) #define predict_xy(i) (avg4 (ref[i], ref[i+1], \ (ref+stride)[i], (ref+stride)[i+1])) #define put(predictor,i) dest[i] = predictor (i) #define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i]) /* mc function template */ #define MC_FUNC(op,xy) \ static void MC_##op##_##xy##_16_c (uint8_t * dest, const uint8_t * ref, \ const int stride, int height) \ { \ do { \ op (predict_##xy, 0); \ op (predict_##xy, 1); \ op (predict_##xy, 2); \ op (predict_##xy, 3); \ op (predict_##xy, 4); \ op (predict_##xy, 5); \ op (predict_##xy, 6); \ op (predict_##xy, 7); \ op (predict_##xy, 8); \ op (predict_##xy, 9); \ op (predict_##xy, 10); \ op (predict_##xy, 11); \ op (predict_##xy, 12); \ op (predict_##xy, 13); \ op (predict_##xy, 14); \ op (predict_##xy, 15); \ ref += stride; \ dest += stride; \ } while (--height); \ } \ static void MC_##op##_##xy##_8_c (uint8_t * dest, const uint8_t * ref, \ const int stride, int height) \ { \ do { \ op (predict_##xy, 0); \ op (predict_##xy, 1); \ op (predict_##xy, 2); \ op (predict_##xy, 3); \ op (predict_##xy, 4); \ op (predict_##xy, 5); \ op (predict_##xy, 6); \ op (predict_##xy, 7); \ ref += stride; \ dest += stride; \ } while (--height); \ } /* definitions of the actual mc functions */ MC_FUNC (put,o) MC_FUNC (avg,o) MC_FUNC (put,x) MC_FUNC (avg,x) MC_FUNC (put,y) MC_FUNC (avg,y) MC_FUNC (put,xy) MC_FUNC (avg,xy) MPEG2_MC_EXTERN (c) ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/motion_comp_alpha.c���������������������������������0000644�0001750�0001750�00000016571�14647725152�023156� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_alpha.c * Copyright (C) 2002-2003 Falk Hueffner <falk@debian.org> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_ALPHA #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #include "../include/alpha_asm.h" static inline uint64_t avg2 (uint64_t a, uint64_t b) { return (a | b) - (((a ^ b) & BYTE_VEC (0xfe)) >> 1); } // Load two unaligned quadwords from addr. This macro only works if // addr is actually unaligned. #define ULOAD16(ret_l,ret_r,addr) \ do { \ uint64_t _l = ldq_u (addr + 0); \ uint64_t _m = ldq_u (addr + 8); \ uint64_t _r = ldq_u (addr + 16); \ ret_l = extql (_l, addr) | extqh (_m, addr); \ ret_r = extql (_m, addr) | extqh (_r, addr); \ } while (0) // Load two aligned quadwords from addr. #define ALOAD16(ret_l,ret_r,addr) \ do { \ ret_l = ldq (addr); \ ret_r = ldq (addr + 8); \ } while (0) #define OP8(LOAD,LOAD16,STORE) \ do { \ STORE (LOAD (pixels), block); \ pixels += line_size; \ block += line_size; \ } while (--h) #define OP16(LOAD,LOAD16,STORE) \ do { \ uint64_t l, r; \ LOAD16 (l, r, pixels); \ STORE (l, block); \ STORE (r, block + 8); \ pixels += line_size; \ block += line_size; \ } while (--h) #define OP8_X2(LOAD,LOAD16,STORE) \ do { \ uint64_t p0, p1; \ \ p0 = LOAD (pixels); \ p1 = p0 >> 8 | ((uint64_t) pixels[8] << 56); \ STORE (avg2 (p0, p1), block); \ pixels += line_size; \ block += line_size; \ } while (--h) #define OP16_X2(LOAD,LOAD16,STORE) \ do { \ uint64_t p0, p1; \ \ LOAD16 (p0, p1, pixels); \ STORE (avg2(p0, p0 >> 8 | p1 << 56), block); \ STORE (avg2(p1, p1 >> 8 | (uint64_t) pixels[16] << 56), \ block + 8); \ pixels += line_size; \ block += line_size; \ } while (--h) #define OP8_Y2(LOAD,LOAD16,STORE) \ do { \ uint64_t p0, p1; \ p0 = LOAD (pixels); \ pixels += line_size; \ p1 = LOAD (pixels); \ do { \ uint64_t av = avg2 (p0, p1); \ if (--h == 0) line_size = 0; \ pixels += line_size; \ p0 = p1; \ p1 = LOAD (pixels); \ STORE (av, block); \ block += line_size; \ } while (h); \ } while (0) #define OP16_Y2(LOAD,LOAD16,STORE) \ do { \ uint64_t p0l, p0r, p1l, p1r; \ LOAD16 (p0l, p0r, pixels); \ pixels += line_size; \ LOAD16 (p1l, p1r, pixels); \ do { \ uint64_t avl, avr; \ if (--h == 0) line_size = 0; \ avl = avg2 (p0l, p1l); \ avr = avg2 (p0r, p1r); \ p0l = p1l; \ p0r = p1r; \ pixels += line_size; \ LOAD16 (p1l, p1r, pixels); \ STORE (avl, block); \ STORE (avr, block + 8); \ block += line_size; \ } while (h); \ } while (0) #define OP8_XY2(LOAD,LOAD16,STORE) \ do { \ uint64_t pl, ph; \ uint64_t p1 = LOAD (pixels); \ uint64_t p2 = p1 >> 8 | ((uint64_t) pixels[8] << 56); \ \ ph = (((p1 & ~BYTE_VEC (0x03)) >> 2) + \ ((p2 & ~BYTE_VEC (0x03)) >> 2)); \ pl = ((p1 & BYTE_VEC (0x03)) + \ (p2 & BYTE_VEC (0x03))); \ \ do { \ uint64_t npl, nph; \ \ pixels += line_size; \ p1 = LOAD (pixels); \ p2 = (p1 >> 8) | ((uint64_t) pixels[8] << 56); \ nph = (((p1 & ~BYTE_VEC (0x03)) >> 2) + \ ((p2 & ~BYTE_VEC (0x03)) >> 2)); \ npl = ((p1 & BYTE_VEC (0x03)) + \ (p2 & BYTE_VEC (0x03))); \ \ STORE (ph + nph + \ (((pl + npl + BYTE_VEC (0x02)) >> 2) & \ BYTE_VEC (0x03)), block); \ \ block += line_size; \ pl = npl; \ ph = nph; \ } while (--h); \ } while (0) #define OP16_XY2(LOAD,LOAD16,STORE) \ do { \ uint64_t p0, p1, p2, p3, pl_l, ph_l, pl_r, ph_r; \ LOAD16 (p0, p2, pixels); \ p1 = p0 >> 8 | (p2 << 56); \ p3 = p2 >> 8 | ((uint64_t)pixels[16] << 56); \ \ ph_l = (((p0 & ~BYTE_VEC (0x03)) >> 2) + \ ((p1 & ~BYTE_VEC (0x03)) >> 2)); \ pl_l = ((p0 & BYTE_VEC (0x03)) + \ (p1 & BYTE_VEC(0x03))); \ ph_r = (((p2 & ~BYTE_VEC (0x03)) >> 2) + \ ((p3 & ~BYTE_VEC (0x03)) >> 2)); \ pl_r = ((p2 & BYTE_VEC (0x03)) + \ (p3 & BYTE_VEC (0x03))); \ \ do { \ uint64_t npl_l, nph_l, npl_r, nph_r; \ \ pixels += line_size; \ LOAD16 (p0, p2, pixels); \ p1 = p0 >> 8 | (p2 << 56); \ p3 = p2 >> 8 | ((uint64_t)pixels[16] << 56); \ nph_l = (((p0 & ~BYTE_VEC (0x03)) >> 2) + \ ((p1 & ~BYTE_VEC (0x03)) >> 2)); \ npl_l = ((p0 & BYTE_VEC (0x03)) + \ (p1 & BYTE_VEC (0x03))); \ nph_r = (((p2 & ~BYTE_VEC (0x03)) >> 2) + \ ((p3 & ~BYTE_VEC (0x03)) >> 2)); \ npl_r = ((p2 & BYTE_VEC (0x03)) + \ (p3 & BYTE_VEC (0x03))); \ \ STORE (ph_l + nph_l + \ (((pl_l + npl_l + BYTE_VEC (0x02)) >> 2) & \ BYTE_VEC(0x03)), block); \ STORE (ph_r + nph_r + \ (((pl_r + npl_r + BYTE_VEC (0x02)) >> 2) & \ BYTE_VEC(0x03)), block + 8); \ \ block += line_size; \ pl_l = npl_l; \ ph_l = nph_l; \ pl_r = npl_r; \ ph_r = nph_r; \ } while (--h); \ } while (0) #define MAKE_OP(OPNAME,SIZE,SUFF,OPKIND,STORE) \ static void MC_ ## OPNAME ## _ ## SUFF ## _ ## SIZE ## _alpha \ (uint8_t *restrict block, const uint8_t *restrict pixels, \ int line_size, int h) \ { \ if ((uint64_t) pixels & 0x7) { \ OPKIND (uldq, ULOAD16, STORE); \ } else { \ OPKIND (ldq, ALOAD16, STORE); \ } \ } #define PIXOP(OPNAME,STORE) \ MAKE_OP (OPNAME, 8, o, OP8, STORE); \ MAKE_OP (OPNAME, 8, x, OP8_X2, STORE); \ MAKE_OP (OPNAME, 8, y, OP8_Y2, STORE); \ MAKE_OP (OPNAME, 8, xy, OP8_XY2, STORE); \ MAKE_OP (OPNAME, 16, o, OP16, STORE); \ MAKE_OP (OPNAME, 16, x, OP16_X2, STORE); \ MAKE_OP (OPNAME, 16, y, OP16_Y2, STORE); \ MAKE_OP (OPNAME, 16, xy, OP16_XY2, STORE); #define STORE(l,b) stq (l, b) PIXOP (put, STORE); #undef STORE #define STORE(l,b) stq (avg2 (l, ldq (b)), b); PIXOP (avg, STORE); mpeg2_mc_t mpeg2_mc_alpha = { { MC_put_o_16_alpha, MC_put_x_16_alpha, MC_put_y_16_alpha, MC_put_xy_16_alpha, MC_put_o_8_alpha, MC_put_x_8_alpha, MC_put_y_8_alpha, MC_put_xy_8_alpha }, { MC_avg_o_16_alpha, MC_avg_x_16_alpha, MC_avg_y_16_alpha, MC_avg_xy_16_alpha, MC_avg_o_8_alpha, MC_avg_x_8_alpha, MC_avg_y_8_alpha, MC_avg_xy_8_alpha } }; #endif ���������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/alloc.c���������������������������������������������0000644�0001750�0001750�00000003570�14647725152�020553� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * alloc.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <stdlib.h> #include <inttypes.h> #include "../include/mpeg2.h" static void * (* malloc_hook) (unsigned size, mpeg2_alloc_t reason) = NULL; static int (* free_hook) (void * buf) = NULL; void * mpeg2_malloc (unsigned size, mpeg2_alloc_t reason) { char * buf; if (malloc_hook) { buf = (char *) malloc_hook (size, reason); if (buf) return buf; } if (size) { buf = (char *) malloc (size + 63 + sizeof (void **)); if (buf) { char * align_buf; align_buf = buf + 63 + sizeof (void **); align_buf -= (long)align_buf & 63; *(((void **)align_buf) - 1) = buf; return align_buf; } } return NULL; } void mpeg2_free (void * buf) { if (free_hook && free_hook (buf)) return; if (buf) free (*(((void **)buf) - 1)); } void mpeg2_malloc_hooks (void * malloc (unsigned, mpeg2_alloc_t), int free (void *)) { malloc_hook = malloc; free_hook = free; } ����������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/cpu_state.c�����������������������������������������0000644�0001750�0001750�00000006155�14647725152�021452� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * cpu_state.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <stdlib.h> #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #ifdef ARCH_X86 #include "../include/mmx.h" #endif void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL; void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL; #ifdef ARCH_X86 static void state_restore_mmx (cpu_state_t * state) { emms (); } #endif #ifdef ARCH_PPC #ifdef HAVE_ALTIVEC_H /* gnu */ #define LI(a,b) "li " #a "," #b "\n\t" #define STVX0(a,b,c) "stvx " #a ",0," #c "\n\t" #define STVX(a,b,c) "stvx " #a "," #b "," #c "\n\t" #define LVX0(a,b,c) "lvx " #a ",0," #c "\n\t" #define LVX(a,b,c) "lvx " #a "," #b "," #c "\n\t" #else /* apple */ #define LI(a,b) "li r" #a "," #b "\n\t" #define STVX0(a,b,c) "stvx v" #a ",0,r" #c "\n\t" #define STVX(a,b,c) "stvx v" #a ",r" #b ",r" #c "\n\t" #define LVX0(a,b,c) "lvx v" #a ",0,r" #c "\n\t" #define LVX(a,b,c) "lvx v" #a ",r" #b ",r" #c "\n\t" #endif static void state_save_altivec (cpu_state_t * state) { asm (LI (9, 16) STVX0 (20, 0, 3) LI (11, 32) STVX (21, 9, 3) LI (9, 48) STVX (22, 11, 3) LI (11, 64) STVX (23, 9, 3) LI (9, 80) STVX (24, 11, 3) LI (11, 96) STVX (25, 9, 3) LI (9, 112) STVX (26, 11, 3) LI (11, 128) STVX (27, 9, 3) LI (9, 144) STVX (28, 11, 3) LI (11, 160) STVX (29, 9, 3) LI (9, 176) STVX (30, 11, 3) STVX (31, 9, 3)); } static void state_restore_altivec (cpu_state_t * state) { asm (LI (9, 16) LVX0 (20, 0, 3) LI (11, 32) LVX (21, 9, 3) LI (9, 48) LVX (22, 11, 3) LI (11, 64) LVX (23, 9, 3) LI (9, 80) LVX (24, 11, 3) LI (11, 96) LVX (25, 9, 3) LI (9, 112) LVX (26, 11, 3) LI (11, 128) LVX (27, 9, 3) LI (9, 144) LVX (28, 11, 3) LI (11, 160) LVX (29, 9, 3) LI (9, 176) LVX (30, 11, 3) LVX (31, 9, 3)); } #endif void mpeg2_cpu_state_init (uint32_t accel) { #ifdef ARCH_X86 if (accel & MPEG2_ACCEL_X86_MMX) { mpeg2_cpu_state_restore = state_restore_mmx; } #endif #ifdef ARCH_PPC if (accel & MPEG2_ACCEL_PPC_ALTIVEC) { mpeg2_cpu_state_save = state_save_altivec; mpeg2_cpu_state_restore = state_restore_altivec; } #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/idct.c����������������������������������������������0000644�0001750�0001750�00000017265�14647725152�020412� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <stdlib.h> #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #define W1 2841 /* 2048 * sqrt (2) * cos (1 * pi / 16) */ #define W2 2676 /* 2048 * sqrt (2) * cos (2 * pi / 16) */ #define W3 2408 /* 2048 * sqrt (2) * cos (3 * pi / 16) */ #define W5 1609 /* 2048 * sqrt (2) * cos (5 * pi / 16) */ #define W6 1108 /* 2048 * sqrt (2) * cos (6 * pi / 16) */ #define W7 565 /* 2048 * sqrt (2) * cos (7 * pi / 16) */ /* idct main entry point */ void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); void (* mpeg2_idct_add) (int last, int16_t * block, uint8_t * dest, int stride); /* * In legal streams, the IDCT output should be between -384 and +384. * In corrupted streams, it is possible to force the IDCT output to go * to +-3826 - this is the worst case for a column IDCT where the * column inputs are 16-bit values. */ uint8_t mpeg2_clip[3840 * 2 + 256]; #define CLIP(i) ((mpeg2_clip + 3840)[i]) #if 0 #define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ do { \ t0 = W0 * d0 + W1 * d1; \ t1 = W0 * d1 - W1 * d0; \ } while (0) #else #define BUTTERFLY(t0,t1,W0,W1,d0,d1) \ do { \ int tmp = W0 * (d0 + d1); \ t0 = tmp + (W1 - W0) * d1; \ t1 = tmp - (W1 + W0) * d0; \ } while (0) #endif static void inline idct_row (int16_t * const block) { int d0, d1, d2, d3; int a0, a1, a2, a3, b0, b1, b2, b3; int t0, t1, t2, t3; /* shortcut */ if (likely (!(block[1] | ((int32_t *)block)[1] | ((int32_t *)block)[2] | ((int32_t *)block)[3]))) { uint32_t tmp = (uint16_t) (block[0] >> 1); tmp |= tmp << 16; ((int32_t *)block)[0] = tmp; ((int32_t *)block)[1] = tmp; ((int32_t *)block)[2] = tmp; ((int32_t *)block)[3] = tmp; return; } d0 = (block[0] << 11) + 2048; d1 = block[1]; d2 = block[2] << 11; d3 = block[3]; t0 = d0 + d2; t1 = d0 - d2; BUTTERFLY (t2, t3, W6, W2, d3, d1); a0 = t0 + t2; a1 = t1 + t3; a2 = t1 - t3; a3 = t0 - t2; d0 = block[4]; d1 = block[5]; d2 = block[6]; d3 = block[7]; BUTTERFLY (t0, t1, W7, W1, d3, d0); BUTTERFLY (t2, t3, W3, W5, d1, d2); b0 = t0 + t2; b3 = t1 + t3; t0 -= t2; t1 -= t3; b1 = ((t0 + t1) >> 8) * 181; b2 = ((t0 - t1) >> 8) * 181; block[0] = (a0 + b0) >> 12; block[1] = (a1 + b1) >> 12; block[2] = (a2 + b2) >> 12; block[3] = (a3 + b3) >> 12; block[4] = (a3 - b3) >> 12; block[5] = (a2 - b2) >> 12; block[6] = (a1 - b1) >> 12; block[7] = (a0 - b0) >> 12; } static void inline idct_col (int16_t * const block) { int d0, d1, d2, d3; int a0, a1, a2, a3, b0, b1, b2, b3; int t0, t1, t2, t3; d0 = (block[8*0] << 11) + 65536; d1 = block[8*1]; d2 = block[8*2] << 11; d3 = block[8*3]; t0 = d0 + d2; t1 = d0 - d2; BUTTERFLY (t2, t3, W6, W2, d3, d1); a0 = t0 + t2; a1 = t1 + t3; a2 = t1 - t3; a3 = t0 - t2; d0 = block[8*4]; d1 = block[8*5]; d2 = block[8*6]; d3 = block[8*7]; BUTTERFLY (t0, t1, W7, W1, d3, d0); BUTTERFLY (t2, t3, W3, W5, d1, d2); b0 = t0 + t2; b3 = t1 + t3; t0 -= t2; t1 -= t3; b1 = ((t0 + t1) >> 8) * 181; b2 = ((t0 - t1) >> 8) * 181; block[8*0] = (a0 + b0) >> 17; block[8*1] = (a1 + b1) >> 17; block[8*2] = (a2 + b2) >> 17; block[8*3] = (a3 + b3) >> 17; block[8*4] = (a3 - b3) >> 17; block[8*5] = (a2 - b2) >> 17; block[8*6] = (a1 - b1) >> 17; block[8*7] = (a0 - b0) >> 17; } static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest, const int stride) { int i; for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); do { dest[0] = CLIP (block[0]); dest[1] = CLIP (block[1]); dest[2] = CLIP (block[2]); dest[3] = CLIP (block[3]); dest[4] = CLIP (block[4]); dest[5] = CLIP (block[5]); dest[6] = CLIP (block[6]); dest[7] = CLIP (block[7]); ((int32_t *)block)[0] = 0; ((int32_t *)block)[1] = 0; ((int32_t *)block)[2] = 0; ((int32_t *)block)[3] = 0; dest += stride; block += 8; } while (--i); } static void mpeg2_idct_add_c (const int last, int16_t * block, uint8_t * dest, const int stride) { int i; if (last != 129 || (block[0] & (7 << 4)) == (4 << 4)) { for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); do { dest[0] = CLIP (block[0] + dest[0]); dest[1] = CLIP (block[1] + dest[1]); dest[2] = CLIP (block[2] + dest[2]); dest[3] = CLIP (block[3] + dest[3]); dest[4] = CLIP (block[4] + dest[4]); dest[5] = CLIP (block[5] + dest[5]); dest[6] = CLIP (block[6] + dest[6]); dest[7] = CLIP (block[7] + dest[7]); ((int32_t *)block)[0] = 0; ((int32_t *)block)[1] = 0; ((int32_t *)block)[2] = 0; ((int32_t *)block)[3] = 0; dest += stride; block += 8; } while (--i); } else { int DC; DC = (block[0] + 64) >> 7; block[0] = block[63] = 0; i = 8; do { dest[0] = CLIP (DC + dest[0]); dest[1] = CLIP (DC + dest[1]); dest[2] = CLIP (DC + dest[2]); dest[3] = CLIP (DC + dest[3]); dest[4] = CLIP (DC + dest[4]); dest[5] = CLIP (DC + dest[5]); dest[6] = CLIP (DC + dest[6]); dest[7] = CLIP (DC + dest[7]); dest += stride; } while (--i); } } void mpeg2_idct_init (uint32_t accel) { #ifdef ARCH_X86 if (accel & MPEG2_ACCEL_X86_MMXEXT) { mpeg2_idct_copy = mpeg2_idct_copy_mmxext; mpeg2_idct_add = mpeg2_idct_add_mmxext; mpeg2_idct_mmx_init (); } else if (accel & MPEG2_ACCEL_X86_MMX) { mpeg2_idct_copy = mpeg2_idct_copy_mmx; mpeg2_idct_add = mpeg2_idct_add_mmx; mpeg2_idct_mmx_init (); } else #endif #ifdef ARCH_PPC if (accel & MPEG2_ACCEL_PPC_ALTIVEC) { mpeg2_idct_copy = mpeg2_idct_copy_altivec; mpeg2_idct_add = mpeg2_idct_add_altivec; mpeg2_idct_altivec_init (); } else #endif #ifdef ARCH_ALPHA if (accel & MPEG2_ACCEL_ALPHA_MVI) { mpeg2_idct_copy = mpeg2_idct_copy_mvi; mpeg2_idct_add = mpeg2_idct_add_mvi; mpeg2_idct_alpha_init (); } else if (accel & MPEG2_ACCEL_ALPHA) { int i; mpeg2_idct_copy = mpeg2_idct_copy_alpha; mpeg2_idct_add = mpeg2_idct_add_alpha; mpeg2_idct_alpha_init (); for (i = -3840; i < 3840 + 256; i++) CLIP(i) = (i < 0) ? 0 : ((i > 255) ? 255 : i); } else #endif { extern uint8_t mpeg2_scan_norm[64]; extern uint8_t mpeg2_scan_alt[64]; int i, j; mpeg2_idct_copy = mpeg2_idct_copy_c; mpeg2_idct_add = mpeg2_idct_add_c; for (i = -3840; i < 3840 + 256; i++) CLIP(i) = (i < 0) ? 0 : ((i > 255) ? 255 : i); for (i = 0; i < 64; i++) { j = mpeg2_scan_norm[i]; mpeg2_scan_norm[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); j = mpeg2_scan_alt[i]; mpeg2_scan_alt[i] = ((j & 0x36) >> 1) | ((j & 0x09) << 2); } } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/configure.incl��������������������������������������0000644�0001750�0001750�00000000564�14647725152�022145� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AC_SUBST([LIBMPEG2_CFLAGS]) dnl avoid -fPIC when possible AC_LIBTOOL_NON_PIC([LIBMPEG2_CFLAGS="$LIBMPEG2_CFLAGS -prefer-non-pic"]) dnl check for cpudetect AC_ARG_ENABLE([accel-detect], [ --disable-accel-detect make a version without accel detection code]) if test x"$enable_accel_detect" != x"no"; then AC_DEFINE([ACCEL_DETECT],,[autodetect accelerations]) fi ��������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/rgb_vis.c�������������������������������������������0000644�0001750�0001750�00000022147�14647725152�021115� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * rgb_vis.c * Copyright (C) 2003 David S. Miller <davem@redhat.com> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_SPARC #include <stddef.h> #include <inttypes.h> #include "mpeg2.h" #include "mpeg2convert.h" #include "convert_internal.h" #include <xine/attributes.h> #include "vis.h" /* Based partially upon the MMX yuv2rgb code, see there for credits. * * The difference here is that since we have enough registers we * process both even and odd scanlines in one pass. */ static const uint16_t const_2048[] ATTR_ALIGN(8) = {2048, 2048, 2048, 2048}; static const uint16_t const_1024[] ATTR_ALIGN(8) = {1024, 1024, 1024, 1024}; static const uint16_t const_128[] ATTR_ALIGN(8) = {128, 128, 128, 128}; static const uint8_t const_Ugreen[] ATTR_ALIGN(8) = {0xf3, 0x00, 0xf3, 0x00, 0xf3, 0x00, 0xf3, 0x00}; static const uint8_t const_Vgreen[] ATTR_ALIGN(8) = {0xe6, 0x00, 0xe6, 0x00, 0xe6, 0x00, 0xe6, 0x00}; static const uint8_t const_Ublue_Vred[] ATTR_ALIGN(8) = {0x41, 0x41, 0x41, 0x41, 0x33, 0x33, 0x33, 0x33}; static const uint8_t const_Ycoeff[] ATTR_ALIGN(4) = {0x25, 0x25, 0x25, 0x25}; #define TMP0 0 #define TMP1 1 #define TMP2 2 #define TMP3 3 #define TMP4 4 #define TMP5 5 #define TMP6 6 #define TMP7 7 #define TMP8 8 #define TMP9 9 #define TMP10 10 #define TMP11 11 #define TMP12 12 #define TMP13 13 #define CONST_UBLUE 14 #define CONST_VRED 15 #define CONST_2048 16 #define BLUE8_EVEN 18 #define BLUE8_ODD 19 #define RED8_EVEN 20 #define RED8_ODD 21 #define GREEN8_EVEN 22 #define GREEN8_ODD 23 #define BLUE8_2_EVEN 24 #define BLUE8_2_ODD 25 #define RED8_2_EVEN 26 #define RED8_2_ODD 27 #define GREEN8_2_EVEN 28 #define GREEN8_2_ODD 29 #define CONST_YCOEFF 30 #define ZEROS 31 #define PU_0 32 #define PU_2 34 #define PV_0 36 #define PV_2 38 #define PY_0 40 #define PY_2 42 #define PY_4 44 #define PY_6 46 #define CONST_128 56 #define CONST_1024 58 #define CONST_VGREEN 60 #define CONST_UGREEN 62 static inline void vis_init_consts(void) { vis_set_gsr(7 << VIS_GSR_SCALEFACT_SHIFT); vis_ld64(const_2048[0], CONST_2048); vis_ld64(const_1024[0], CONST_1024); vis_ld64(const_Ugreen[0], CONST_UGREEN); vis_ld64(const_Vgreen[0], CONST_VGREEN); vis_fzeros(ZEROS); vis_ld64(const_Ublue_Vred[0], CONST_UBLUE); vis_ld32(const_Ycoeff[0], CONST_YCOEFF); vis_ld64(const_128[0], CONST_128); } static inline void vis_yuv2rgb(uint8_t *py, uint8_t *pu, uint8_t *pv, int y_stride) { vis_ld32(pu[0], TMP0); vis_ld32(pv[0], TMP2); vis_ld64(py[0], TMP4); vis_mul8x16au(TMP0, CONST_2048, PU_0); vis_ld64_2(py, y_stride, TMP8); vis_mul8x16au(TMP2, CONST_2048, PV_0); vis_pmerge(TMP4, TMP5, TMP6); vis_pmerge(TMP6, TMP7, TMP4); vis_pmerge(TMP8, TMP9, TMP10); vis_pmerge(TMP10, TMP11, TMP8); vis_mul8x16au(TMP4, CONST_2048, PY_0); vis_psub16(PU_0, CONST_1024, PU_0); vis_mul8x16au(TMP5, CONST_2048, PY_2); vis_psub16(PV_0, CONST_1024, PV_0); vis_mul8x16au(TMP8, CONST_2048, PY_4); vis_psub16(PY_0, CONST_128, PY_0); vis_mul8x16au(TMP9, CONST_2048, PY_6); vis_psub16(PY_2, CONST_128, PY_2); vis_mul8x16(CONST_YCOEFF, PY_0, PY_0); vis_psub16(PY_4, CONST_128, PY_4); vis_mul8x16(CONST_YCOEFF, PY_2, PY_2); vis_psub16(PY_6, CONST_128, PY_6); vis_mul8x16(CONST_YCOEFF, PY_4, PY_4); vis_mul8x16(CONST_YCOEFF, PY_6, PY_6); vis_mul8sux16(CONST_UGREEN, PU_0, TMP0); vis_mul8sux16(CONST_VGREEN, PV_0, TMP2); vis_mul8x16(CONST_UBLUE, PU_0, TMP4); vis_mul8x16(CONST_VRED, PV_0, TMP6); vis_padd16(TMP0, TMP2, TMP10); vis_padd16(PY_0, TMP4, TMP0); vis_padd16(PY_2, TMP4, TMP2); vis_pack16(TMP0, BLUE8_EVEN); vis_padd16(PY_4, TMP4, TMP0); vis_pack16(TMP2, BLUE8_ODD); vis_padd16(PY_6, TMP4, TMP2); vis_pack16(TMP0, BLUE8_2_EVEN); vis_padd16(PY_0, TMP6, TMP0); vis_pack16(TMP2, BLUE8_2_ODD); vis_padd16(PY_2, TMP6, TMP2); vis_pack16(TMP0, RED8_EVEN); vis_padd16(PY_4, TMP6, TMP0); vis_pack16(TMP2, RED8_ODD); vis_padd16(PY_6, TMP6, TMP2); vis_pack16(TMP0, RED8_2_EVEN); vis_padd16(PY_0, TMP10, TMP0); vis_pack16(TMP2, RED8_2_ODD); vis_padd16(PY_2, TMP10, TMP2); vis_pack16(TMP0, GREEN8_EVEN); vis_padd16(PY_4, TMP10, TMP0); vis_pack16(TMP2, GREEN8_ODD); vis_padd16(PY_6, TMP10, TMP2); vis_pack16(TMP0, GREEN8_2_EVEN); vis_pack16(TMP2, GREEN8_2_ODD); vis_pmerge(BLUE8_EVEN, BLUE8_ODD, BLUE8_EVEN); vis_pmerge(BLUE8_2_EVEN, BLUE8_2_ODD, BLUE8_2_EVEN); vis_pmerge(RED8_EVEN, RED8_ODD, RED8_EVEN); vis_pmerge(RED8_2_EVEN, RED8_2_ODD, RED8_2_EVEN); vis_pmerge(GREEN8_EVEN, GREEN8_ODD, GREEN8_EVEN); vis_pmerge(GREEN8_2_EVEN, GREEN8_2_ODD, GREEN8_2_EVEN); } static inline void vis_unpack_32rgb(uint8_t *image, int stride) { vis_pmerge(ZEROS, GREEN8_EVEN, TMP0); vis_pmerge(RED8_EVEN, BLUE8_EVEN, TMP2); vis_pmerge(TMP0, TMP2, TMP4); vis_st64(TMP4, image[0]); vis_pmerge(TMP1, TMP3, TMP6); vis_st64_2(TMP6, image, 8); vis_pmerge(ZEROS, GREEN8_ODD, TMP8); vis_pmerge(RED8_ODD, BLUE8_ODD, TMP10); vis_pmerge(TMP8, TMP10, TMP0); vis_st64_2(TMP0, image, 16); vis_pmerge(TMP9, TMP11, TMP2); vis_st64_2(TMP2, image, 24); image += stride; vis_pmerge(ZEROS, GREEN8_2_EVEN, TMP0); vis_pmerge(RED8_2_EVEN, BLUE8_2_EVEN, TMP2); vis_pmerge(TMP0, TMP2, TMP4); vis_st64(TMP4, image[0]); vis_pmerge(TMP1, TMP3, TMP6); vis_st64_2(TMP6, image, 8); vis_pmerge(ZEROS, GREEN8_2_ODD, TMP8); vis_pmerge(RED8_2_ODD, BLUE8_2_ODD, TMP10); vis_pmerge(TMP8, TMP10, TMP0); vis_st64_2(TMP0, image, 16); vis_pmerge(TMP9, TMP11, TMP2); vis_st64_2(TMP2, image, 24); } static inline void vis_unpack_32bgr(uint8_t *image, int stride) { vis_pmerge(ZEROS, GREEN8_EVEN, TMP0); vis_pmerge(BLUE8_EVEN, RED8_EVEN, TMP2); vis_pmerge(TMP0, TMP2, TMP4); vis_st64(TMP4, image[0]); vis_pmerge(TMP1, TMP3, TMP6); vis_st64_2(TMP6, image, 8); vis_pmerge(ZEROS, GREEN8_ODD, TMP8); vis_pmerge(BLUE8_ODD, RED8_ODD, TMP10); vis_pmerge(TMP8, TMP10, TMP0); vis_st64_2(TMP0, image, 16); vis_pmerge(TMP9, TMP11, TMP2); vis_st64_2(TMP2, image, 24); image += stride; vis_pmerge(ZEROS, GREEN8_2_EVEN, TMP0); vis_pmerge(BLUE8_2_EVEN, RED8_2_EVEN, TMP2); vis_pmerge(TMP0, TMP2, TMP4); vis_st64(TMP4, image[0]); vis_pmerge(TMP1, TMP3, TMP6); vis_st64_2(TMP6, image, 8); vis_pmerge(ZEROS, GREEN8_2_ODD, TMP8); vis_pmerge(BLUE8_2_ODD, RED8_2_ODD, TMP10); vis_pmerge(TMP8, TMP10, TMP0); vis_st64_2(TMP0, image, 16); vis_pmerge(TMP9, TMP11, TMP2); vis_st64_2(TMP2, image, 24); } static inline void vis_yuv420_argb32(uint8_t *image, uint8_t *py, uint8_t *pu, uint8_t *pv, int width, int height, int rgb_stride, int y_stride, int uv_stride) { height >>= 1; uv_stride -= width >> 1; do { int i = width >> 3; do { vis_yuv2rgb(py, pu, pv, y_stride); vis_unpack_32rgb(image, rgb_stride); py += 8; pu += 4; pv += 4; image += 32; } while (--i); py += (y_stride << 1) - width; image += (rgb_stride << 1) - 4 * width; pu += uv_stride; pv += uv_stride; } while (--height); } static inline void vis_yuv420_abgr32(uint8_t *image, uint8_t *py, uint8_t *pu, uint8_t *pv, int width, int height, int rgb_stride, int y_stride, int uv_stride) { height >>= 1; uv_stride -= width >> 1; do { int i = width >> 3; do { vis_yuv2rgb(py, pu, pv, y_stride); vis_unpack_32bgr(image, rgb_stride); py += 8; pu += 4; pv += 4; image += 32; } while (--i); py += (y_stride << 1) - width; image += (rgb_stride << 1) - 4 * width; pu += uv_stride; pv += uv_stride; } while (--height); } static void vis_argb32(void *_id, uint8_t * const *src, unsigned int v_offset) { convert_rgb_t *id = (convert_rgb_t *) _id; vis_init_consts(); vis_yuv420_argb32(id->rgb_ptr + id->rgb_stride * v_offset, src[0], src[1], src[2], id->width, 16, id->rgb_stride, id->y_stride, id->y_stride >> 1); } static void vis_abgr32(void *_id, uint8_t * const *src, unsigned int v_offset) { convert_rgb_t *id = (convert_rgb_t *) _id; vis_init_consts(); vis_yuv420_abgr32(id->rgb_ptr + id->rgb_stride * v_offset, src[0], src[1], src[2], id->width, 16, id->rgb_stride, id->y_stride, id->y_stride >> 1); } mpeg2convert_copy_t *mpeg2convert_rgb_vis(int order, int bpp, const mpeg2_sequence_t * seq) { if (bpp == 32 && seq->chroma_height < seq->height) { if (order == MPEG2CONVERT_RGB) return vis_argb32; if (order == MPEG2CONVERT_BGR) return vis_abgr32; } return NULL; /* Fallback to C */ } #endif /* ARCH_SPARC */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/idct_altivec.c��������������������������������������0000644�0001750�0001750�00000023310�14647725152�022105� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_altivec.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_PPC #ifdef HAVE_ALTIVEC_H #include <altivec.h> #endif #include <inttypes.h> #include "mpeg2.h" #include <xine/attributes.h> #include "mpeg2_internal.h" typedef vector signed char vector_s8_t; typedef vector unsigned char vector_u8_t; typedef vector signed short vector_s16_t; typedef vector unsigned short vector_u16_t; typedef vector signed int vector_s32_t; typedef vector unsigned int vector_u32_t; #if defined(HAVE_ALTIVEC_H) && (__GNUC__ * 100 + __GNUC_MINOR__ < 303) /* work around gcc <3.3 vec_mergel bug */ static inline vector_s16_t my_vec_mergel (vector_s16_t const A, vector_s16_t const B) { static const vector_u8_t mergel = { 0x08, 0x09, 0x18, 0x19, 0x0a, 0x0b, 0x1a, 0x1b, 0x0c, 0x0d, 0x1c, 0x1d, 0x0e, 0x0f, 0x1e, 0x1f }; return vec_perm (A, B, mergel); } #undef vec_mergel #define vec_mergel my_vec_mergel #endif #ifdef HAVE_ALTIVEC_H /* gnu */ #define VEC_S16(a,b,c,d,e,f,g,h) {a, b, c, d, e, f, g, h} #else /* apple */ #define VEC_S16(a,b,c,d,e,f,g,h) (vector_s16_t) (a, b, c, d, e, f, g, h) #endif static const vector_s16_t constants ATTR_ALIGN(16) = VEC_S16 (23170, 13573, 6518, 21895, -23170, -21895, 32, 31); static const vector_s16_t constants_1 ATTR_ALIGN(16) = VEC_S16 (16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725); static const vector_s16_t constants_2 ATTR_ALIGN(16) = VEC_S16 (16069, 22289, 20995, 18895, 16069, 18895, 20995, 22289); static const vector_s16_t constants_3 ATTR_ALIGN(16) = VEC_S16 (21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692); static const vector_s16_t constants_4 ATTR_ALIGN(16) = VEC_S16 (13623, 18895, 17799, 16019, 13623, 16019, 17799, 18895); #define IDCT \ vector_s16_t vx0, vx1, vx2, vx3, vx4, vx5, vx6, vx7; \ vector_s16_t vy0, vy1, vy2, vy3, vy4, vy5, vy6, vy7; \ vector_s16_t a0, a1, a2, ma2, c4, mc4, zero, bias; \ vector_s16_t t0, t1, t2, t3, t4, t5, t6, t7, t8; \ vector_u16_t shift; \ \ c4 = vec_splat (constants, 0); \ a0 = vec_splat (constants, 1); \ a1 = vec_splat (constants, 2); \ a2 = vec_splat (constants, 3); \ mc4 = vec_splat (constants, 4); \ ma2 = vec_splat (constants, 5); \ bias = (vector_s16_t)vec_splat ((vector_s32_t)constants, 3); \ \ zero = vec_splat_s16 (0); \ \ vx0 = vec_adds (block[0], block[4]); \ vx4 = vec_subs (block[0], block[4]); \ t5 = vec_mradds (vx0, constants_1, zero); \ t0 = vec_mradds (vx4, constants_1, zero); \ \ vx1 = vec_mradds (a1, block[7], block[1]); \ vx7 = vec_mradds (a1, block[1], vec_subs (zero, block[7])); \ t1 = vec_mradds (vx1, constants_2, zero); \ t8 = vec_mradds (vx7, constants_2, zero); \ \ vx2 = vec_mradds (a0, block[6], block[2]); \ vx6 = vec_mradds (a0, block[2], vec_subs (zero, block[6])); \ t2 = vec_mradds (vx2, constants_3, zero); \ t4 = vec_mradds (vx6, constants_3, zero); \ \ vx3 = vec_mradds (block[3], constants_4, zero); \ vx5 = vec_mradds (block[5], constants_4, zero); \ t7 = vec_mradds (a2, vx5, vx3); \ t3 = vec_mradds (ma2, vx3, vx5); \ \ t6 = vec_adds (t8, t3); \ t3 = vec_subs (t8, t3); \ t8 = vec_subs (t1, t7); \ t1 = vec_adds (t1, t7); \ t6 = vec_mradds (a0, t6, t6); /* a0+1 == 2*c4 */ \ t1 = vec_mradds (a0, t1, t1); /* a0+1 == 2*c4 */ \ \ t7 = vec_adds (t5, t2); \ t2 = vec_subs (t5, t2); \ t5 = vec_adds (t0, t4); \ t0 = vec_subs (t0, t4); \ t4 = vec_subs (t8, t3); \ t3 = vec_adds (t8, t3); \ \ vy0 = vec_adds (t7, t1); \ vy7 = vec_subs (t7, t1); \ vy1 = vec_adds (t5, t3); \ vy6 = vec_subs (t5, t3); \ vy2 = vec_adds (t0, t4); \ vy5 = vec_subs (t0, t4); \ vy3 = vec_adds (t2, t6); \ vy4 = vec_subs (t2, t6); \ \ vx0 = vec_mergeh (vy0, vy4); \ vx1 = vec_mergel (vy0, vy4); \ vx2 = vec_mergeh (vy1, vy5); \ vx3 = vec_mergel (vy1, vy5); \ vx4 = vec_mergeh (vy2, vy6); \ vx5 = vec_mergel (vy2, vy6); \ vx6 = vec_mergeh (vy3, vy7); \ vx7 = vec_mergel (vy3, vy7); \ \ vy0 = vec_mergeh (vx0, vx4); \ vy1 = vec_mergel (vx0, vx4); \ vy2 = vec_mergeh (vx1, vx5); \ vy3 = vec_mergel (vx1, vx5); \ vy4 = vec_mergeh (vx2, vx6); \ vy5 = vec_mergel (vx2, vx6); \ vy6 = vec_mergeh (vx3, vx7); \ vy7 = vec_mergel (vx3, vx7); \ \ vx0 = vec_mergeh (vy0, vy4); \ vx1 = vec_mergel (vy0, vy4); \ vx2 = vec_mergeh (vy1, vy5); \ vx3 = vec_mergel (vy1, vy5); \ vx4 = vec_mergeh (vy2, vy6); \ vx5 = vec_mergel (vy2, vy6); \ vx6 = vec_mergeh (vy3, vy7); \ vx7 = vec_mergel (vy3, vy7); \ \ vx0 = vec_adds (vx0, bias); \ t5 = vec_adds (vx0, vx4); \ t0 = vec_subs (vx0, vx4); \ \ t1 = vec_mradds (a1, vx7, vx1); \ t8 = vec_mradds (a1, vx1, vec_subs (zero, vx7)); \ \ t2 = vec_mradds (a0, vx6, vx2); \ t4 = vec_mradds (a0, vx2, vec_subs (zero, vx6)); \ \ t7 = vec_mradds (a2, vx5, vx3); \ t3 = vec_mradds (ma2, vx3, vx5); \ \ t6 = vec_adds (t8, t3); \ t3 = vec_subs (t8, t3); \ t8 = vec_subs (t1, t7); \ t1 = vec_adds (t1, t7); \ \ t7 = vec_adds (t5, t2); \ t2 = vec_subs (t5, t2); \ t5 = vec_adds (t0, t4); \ t0 = vec_subs (t0, t4); \ t4 = vec_subs (t8, t3); \ t3 = vec_adds (t8, t3); \ \ vy0 = vec_adds (t7, t1); \ vy7 = vec_subs (t7, t1); \ vy1 = vec_mradds (c4, t3, t5); \ vy6 = vec_mradds (mc4, t3, t5); \ vy2 = vec_mradds (c4, t4, t0); \ vy5 = vec_mradds (mc4, t4, t0); \ vy3 = vec_adds (t2, t6); \ vy4 = vec_subs (t2, t6); \ \ shift = vec_splat_u16 (6); \ vx0 = vec_sra (vy0, shift); \ vx1 = vec_sra (vy1, shift); \ vx2 = vec_sra (vy2, shift); \ vx3 = vec_sra (vy3, shift); \ vx4 = vec_sra (vy4, shift); \ vx5 = vec_sra (vy5, shift); \ vx6 = vec_sra (vy6, shift); \ vx7 = vec_sra (vy7, shift); void mpeg2_idct_copy_altivec (int16_t * const _block, uint8_t * dest, const int stride) { vector_s16_t * const block = (vector_s16_t *)_block; vector_u8_t tmp; IDCT #define COPY(dest,src) \ tmp = vec_packsu (src, src); \ vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); COPY (dest, vx0) dest += stride; COPY (dest, vx1) dest += stride; COPY (dest, vx2) dest += stride; COPY (dest, vx3) dest += stride; COPY (dest, vx4) dest += stride; COPY (dest, vx5) dest += stride; COPY (dest, vx6) dest += stride; COPY (dest, vx7) block[0] = block[1] = block[2] = block[3] = zero; block[4] = block[5] = block[6] = block[7] = zero; } void mpeg2_idct_add_altivec (const int last, int16_t * const _block, uint8_t * dest, const int stride) { vector_s16_t * const block = (vector_s16_t *)_block; vector_u8_t tmp; vector_s16_t tmp2, tmp3; vector_u8_t perm0; vector_u8_t perm1; vector_u8_t p0, p1, p; IDCT p0 = vec_lvsl (0, dest); p1 = vec_lvsl (stride, dest); p = vec_splat_u8 (-1); perm0 = vec_mergeh (p, p0); perm1 = vec_mergeh (p, p1); #define ADD(dest,src,perm) \ /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ tmp = vec_ld (0, dest); \ tmp2 = (vector_s16_t)vec_perm (tmp, (vector_u8_t)zero, perm); \ tmp3 = vec_adds (tmp2, src); \ tmp = vec_packsu (tmp3, tmp3); \ vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); ADD (dest, vx0, perm0) dest += stride; ADD (dest, vx1, perm1) dest += stride; ADD (dest, vx2, perm0) dest += stride; ADD (dest, vx3, perm1) dest += stride; ADD (dest, vx4, perm0) dest += stride; ADD (dest, vx5, perm1) dest += stride; ADD (dest, vx6, perm0) dest += stride; ADD (dest, vx7, perm1) block[0] = block[1] = block[2] = block[3] = zero; block[4] = block[5] = block[6] = block[7] = zero; } void mpeg2_idct_altivec_init (void) { extern uint8_t mpeg2_scan_norm[64]; extern uint8_t mpeg2_scan_alt[64]; int i, j; /* the altivec idct uses a transposed input, so we patch scan tables */ for (i = 0; i < 64; i++) { j = mpeg2_scan_norm[i]; mpeg2_scan_norm[i] = (j >> 3) | ((j & 7) << 3); j = mpeg2_scan_alt[i]; mpeg2_scan_alt[i] = (j >> 3) | ((j & 7) << 3); } } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/mpeg2_internal.h������������������������������������0000644�0001750�0001750�00000021403�14647725152�022367� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mpeg2_internal.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define STATE_INTERNAL_NORETURN ((mpeg2_state_t)-1) /* macroblock modes */ #define MACROBLOCK_INTRA 1 #define MACROBLOCK_PATTERN 2 #define MACROBLOCK_MOTION_BACKWARD 4 #define MACROBLOCK_MOTION_FORWARD 8 #define MACROBLOCK_QUANT 16 #define DCT_TYPE_INTERLACED 32 /* motion_type */ #define MOTION_TYPE_SHIFT 6 #define MC_FIELD 1 #define MC_FRAME 2 #define MC_16X8 2 #define MC_DMV 3 /* picture structure */ #define TOP_FIELD 1 #define BOTTOM_FIELD 2 #define FRAME_PICTURE 3 /* picture coding type */ #define I_TYPE 1 #define P_TYPE 2 #define B_TYPE 3 #define D_TYPE 4 typedef void mpeg2_mc_fct (uint8_t *, const uint8_t *, int, int); typedef struct { uint8_t * ref[2][3]; uint8_t ** ref2[2]; int pmv[2][2]; int f_code[2]; } motion_t; typedef void motion_parser_t (mpeg2_decoder_t * decoder, motion_t * motion, mpeg2_mc_fct * const * table); struct mpeg2_decoder_s { /* first, state that carries information from one macroblock to the */ /* next inside a slice, and is never used outside of mpeg2_slice() */ /* bit parsing stuff */ uint32_t bitstream_buf; /* current 32 bit working set */ int bitstream_bits; /* used bits in working set */ const uint8_t * bitstream_ptr; /* buffer with stream data */ uint8_t * dest[3]; int offset; int stride; int uv_stride; int slice_stride; int slice_uv_stride; int stride_frame; unsigned int limit_x; unsigned int limit_y_16; unsigned int limit_y_8; unsigned int limit_y; /* Motion vectors */ /* The f_ and b_ correspond to the forward and backward motion */ /* predictors */ motion_t b_motion; motion_t f_motion; motion_parser_t * motion_parser[5]; /* predictor for DC coefficients in intra blocks */ int16_t dc_dct_pred[3]; /* DCT coefficients */ int16_t DCTblock[64] ATTR_ALIGN(64); uint8_t * picture_dest[3]; void (* convert) (void * convert_id, uint8_t * const * src, unsigned int v_offset); void * convert_id; int dmv_offset; unsigned int v_offset; /* now non-slice-specific information */ /* sequence header stuff */ uint16_t * quantizer_matrix[4]; uint16_t (* chroma_quantizer[2])[64]; uint16_t quantizer_prescale[4][32][64]; /* The width and height of the picture snapped to macroblock units */ int width; int height; int vertical_position_extension; int chroma_format; /* picture header stuff */ /* what type of picture this is (I, P, B, D) */ int coding_type; /* picture coding extension stuff */ /* quantization factor for intra dc coefficients */ int intra_dc_precision; /* top/bottom/both fields */ int picture_structure; /* bool to indicate all predictions are frame based */ int frame_pred_frame_dct; /* bool to indicate whether intra blocks have motion vectors */ /* (for concealment) */ int concealment_motion_vectors; /* bool to use different vlc tables */ int intra_vlc_format; /* used for DMV MC */ int top_field_first; /* stuff derived from bitstream */ /* pointer to the zigzag scan we're supposed to be using */ const uint8_t * scan; int second_field; int mpeg1; }; typedef struct { mpeg2_fbuf_t fbuf; } fbuf_alloc_t; struct mpeg2dec_s { mpeg2_decoder_t decoder; mpeg2_info_t info; uint32_t shift; int is_display_initialized; mpeg2_state_t (* action) (struct mpeg2dec_s * mpeg2dec); mpeg2_state_t state; uint32_t ext_state; /* allocated in init - gcc has problems allocating such big structures */ uint8_t * chunk_buffer; /* pointer to start of the current chunk */ uint8_t * chunk_start; /* pointer to current position in chunk_buffer */ uint8_t * chunk_ptr; /* last start code ? */ uint8_t code; /* picture tags */ uint32_t tag_current, tag2_current, tag_previous, tag2_previous; int num_tags; int bytes_since_tag; int first; int alloc_index_user; int alloc_index; uint8_t first_decode_slice; uint8_t nb_decode_slices; unsigned int user_data_len; mpeg2_sequence_t new_sequence; mpeg2_sequence_t sequence; mpeg2_gop_t new_gop; mpeg2_gop_t gop; mpeg2_picture_t new_picture; mpeg2_picture_t pictures[4]; mpeg2_picture_t * picture; /*const*/ mpeg2_fbuf_t * fbuf[3]; /* 0: current fbuf, 1-2: prediction fbufs */ fbuf_alloc_t fbuf_alloc[3]; int custom_fbuf; uint8_t * yuv_buf[3][3]; int yuv_index; mpeg2_convert_t * convert; void * convert_arg; unsigned int convert_id_size; int convert_stride; void (* convert_start) (void * id, const mpeg2_fbuf_t * fbuf, const mpeg2_picture_t * picture, const mpeg2_gop_t * gop); uint8_t * buf_start; uint8_t * buf_end; int16_t display_offset_x, display_offset_y; int copy_matrix; int8_t q_scale_type, scaled[4]; uint8_t quantizer_matrix[4][64]; uint8_t new_quantizer_matrix[4][64]; }; typedef struct { #ifdef ARCH_PPC uint8_t regv[12*16]; #endif int dummy; } cpu_state_t; /* cpu_accel.c */ uint32_t mpeg2_detect_accel (uint32_t accel); /* cpu_state.c */ void mpeg2_cpu_state_init (uint32_t accel); /* decode.c */ mpeg2_state_t mpeg2_seek_header (mpeg2dec_t * mpeg2dec); mpeg2_state_t mpeg2_parse_header (mpeg2dec_t * mpeg2dec); /* header.c */ void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec); void mpeg2_reset_info (mpeg2_info_t * info); int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec); int mpeg2_header_gop (mpeg2dec_t * mpeg2dec); mpeg2_state_t mpeg2_header_picture_start (mpeg2dec_t * mpeg2dec); int mpeg2_header_picture (mpeg2dec_t * mpeg2dec); int mpeg2_header_extension (mpeg2dec_t * mpeg2dec); int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec); void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec); void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec); void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec, uint32_t accels); mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec); mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec); void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type); /* idct.c */ void mpeg2_idct_init (uint32_t accel); /* idct_mmx.c */ void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_mmxext (int last, int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_mmx (int last, int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_mmx_init (void); /* idct_altivec.c */ void mpeg2_idct_copy_altivec (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_altivec (int last, int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_altivec_init (void); /* idct_alpha.c */ void mpeg2_idct_copy_mvi (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_mvi (int last, int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_copy_alpha (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_alpha (int last, int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_alpha_init (void); /* motion_comp.c */ void mpeg2_mc_init (uint32_t accel); typedef struct { mpeg2_mc_fct * put [8]; mpeg2_mc_fct * avg [8]; } mpeg2_mc_t; #define MPEG2_MC_EXTERN(x) mpeg2_mc_t mpeg2_mc_##x = { \ {MC_put_o_16_##x, MC_put_x_16_##x, MC_put_y_16_##x, MC_put_xy_16_##x, \ MC_put_o_8_##x, MC_put_x_8_##x, MC_put_y_8_##x, MC_put_xy_8_##x}, \ {MC_avg_o_16_##x, MC_avg_x_16_##x, MC_avg_y_16_##x, MC_avg_xy_16_##x, \ MC_avg_o_8_##x, MC_avg_x_8_##x, MC_avg_y_8_##x, MC_avg_xy_8_##x} \ }; extern mpeg2_mc_t mpeg2_mc_c; extern mpeg2_mc_t mpeg2_mc_mmx; extern mpeg2_mc_t mpeg2_mc_mmxext; extern mpeg2_mc_t mpeg2_mc_3dnow; extern mpeg2_mc_t mpeg2_mc_altivec; extern mpeg2_mc_t mpeg2_mc_alpha; extern mpeg2_mc_t mpeg2_mc_vis; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/cpu_accel.c�����������������������������������������0000644�0001750�0001750�00000013633�14647725152�021400� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * cpu_accel.c * Copyright (C) 2000-2004 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #ifdef ARCH_X86 static inline uint32_t arch_accel (uint32_t accel) { if (accel & (MPEG2_ACCEL_X86_3DNOW | MPEG2_ACCEL_X86_MMXEXT)) accel |= MPEG2_ACCEL_X86_MMX; if (accel & (MPEG2_ACCEL_X86_SSE2 | MPEG2_ACCEL_X86_SSE3)) accel |= MPEG2_ACCEL_X86_MMXEXT; if (accel & (MPEG2_ACCEL_X86_SSE3)) accel |= MPEG2_ACCEL_X86_SSE2; #ifdef ACCEL_DETECT if (accel & MPEG2_ACCEL_DETECT) { uint32_t eax, ebx, ecx, edx; int AMD; #if !defined(PIC) && !defined(__PIC__) #define cpuid(op,eax,ebx,ecx,edx) \ __asm__ ("cpuid" \ : "=a" (eax), \ "=b" (ebx), \ "=c" (ecx), \ "=d" (edx) \ : "a" (op) \ : "cc") #else /* PIC version : save ebx */ #define cpuid(op,eax,ebx,ecx,edx) \ __asm__ ("push %%ebx\n\t" \ "cpuid\n\t" \ "movl %%ebx,%1\n\t" \ "pop %%ebx" \ : "=a" (eax), \ "=r" (ebx), \ "=c" (ecx), \ "=d" (edx) \ : "a" (op) \ : "cc") #endif __asm__ ("pushf\n\t" "pushf\n\t" "pop %0\n\t" "movl %0,%1\n\t" "xorl $0x200000,%0\n\t" "push %0\n\t" "popf\n\t" "pushf\n\t" "pop %0\n\t" "popf" : "=r" (eax), "=r" (ebx) : : "cc"); if (eax == ebx) /* no cpuid */ return accel; cpuid (0x00000000, eax, ebx, ecx, edx); if (!eax) /* vendor string only */ return accel; AMD = (ebx == 0x68747541 && ecx == 0x444d4163 && edx == 0x69746e65); cpuid (0x00000001, eax, ebx, ecx, edx); if (! (edx & 0x00800000)) /* no MMX */ return accel; accel |= MPEG2_ACCEL_X86_MMX; if (edx & 0x02000000) /* SSE - identical to AMD MMX extensions */ accel |= MPEG2_ACCEL_X86_MMXEXT; if (edx & 0x04000000) /* SSE2 */ accel |= MPEG2_ACCEL_X86_SSE2; if (ecx & 0x00000001) /* SSE3 */ accel |= MPEG2_ACCEL_X86_SSE3; cpuid (0x80000000, eax, ebx, ecx, edx); if (eax < 0x80000001) /* no extended capabilities */ return accel; cpuid (0x80000001, eax, ebx, ecx, edx); if (edx & 0x80000000) accel |= MPEG2_ACCEL_X86_3DNOW; if (AMD && (edx & 0x00400000)) /* AMD MMX extensions */ accel |= MPEG2_ACCEL_X86_MMXEXT; } #endif /* ACCEL_DETECT */ return accel; } #endif /* ARCH_X86 */ #if defined(ACCEL_DETECT) && (defined(ARCH_PPC) || defined(ARCH_SPARC)) #include <signal.h> #include <setjmp.h> static sigjmp_buf jmpbuf; static volatile sig_atomic_t canjump = 0; static RETSIGTYPE sigill_handler (int sig) { if (!canjump) { signal (sig, SIG_DFL); raise (sig); } canjump = 0; siglongjmp (jmpbuf, 1); } #endif /* ACCEL_DETECT && (ARCH_PPC || ARCH_SPARC) */ #ifdef ARCH_PPC static inline uint32_t arch_accel (uint32_t accel) { #ifdef ACCEL_DETECT if (accel & (MPEG2_ACCEL_PPC_ALTIVEC | MPEG2_ACCEL_DETECT) == MPEG2_ACCEL_DETECT) { static RETSIGTYPE (* oldsig) (int); oldsig = signal (SIGILL, sigill_handler); if (sigsetjmp (jmpbuf, 1)) { signal (SIGILL, oldsig); return accel; } canjump = 1; #ifdef HAVE_ALTIVEC_H /* gnu */ #define VAND(a,b,c) "vand " #a "," #b "," #c "\n\t" #else /* apple */ #define VAND(a,b,c) "vand v" #a ",v" #b ",v" #c "\n\t" #endif asm volatile ("mtspr 256, %0\n\t" VAND (0, 0, 0) : : "r" (-1)); canjump = 0; accel |= MPEG2_ACCEL_PPC_ALTIVEC; signal (SIGILL, oldsig); } #endif /* ACCEL_DETECT */ return accel; } #endif /* ARCH_PPC */ #ifdef ARCH_SPARC static inline uint32_t arch_accel (uint32_t accel) { if (accel & MPEG2_ACCEL_SPARC_VIS2) accel |= MPEG2_ACCEL_SPARC_VIS; #ifdef ACCEL_DETECT if (accel & (MPEG2_ACCEL_SPARC_VIS2 | MPEG2_ACCEL_DETECT) == MPEG2_ACCEL_DETECT) { static RETSIGTYPE (* oldsig) (int); oldsig = signal (SIGILL, sigill_handler); if (sigsetjmp (jmpbuf, 1)) { signal (SIGILL, oldsig); return accel; } canjump = 1; /* pdist %f0, %f0, %f0 */ __asm__ __volatile__(".word\t0x81b007c0"); canjump = 0; accel |= MPEG2_ACCEL_SPARC_VIS; if (sigsetjmp (jmpbuf, 1)) { signal (SIGILL, oldsig); return accel; } canjump = 1; /* edge8n %g0, %g0, %g0 */ __asm__ __volatile__(".word\t0x81b00020"); canjump = 0; accel |= MPEG2_ACCEL_SPARC_VIS2; signal (SIGILL, oldsig); } #endif /* ACCEL_DETECT */ return accel; } #endif /* ARCH_SPARC */ #ifdef ARCH_ALPHA static inline uint32_t arch_accel (uint32_t accel) { if (accel & MPEG2_ACCEL_ALPHA_MVI) accel |= MPEG2_ACCEL_ALPHA; #ifdef ACCEL_DETECT if (accel & MPEG2_ACCEL_DETECT) { uint64_t no_mvi; asm volatile ("amask %1, %0" : "=r" (no_mvi) : "rI" (256)); /* AMASK_MVI */ accel |= no_mvi ? MPEG2_ACCEL_ALPHA : (MPEG2_ACCEL_ALPHA | MPEG2_ACCEL_ALPHA_MVI); } #endif /* ACCEL_DETECT */ return accel; } #endif /* ARCH_ALPHA */ uint32_t mpeg2_detect_accel (uint32_t accel) { #if defined (ARCH_X86) || defined (ARCH_PPC) || defined (ARCH_ALPHA) || defined (ARCH_SPARC) accel = arch_accel (accel); #endif return accel; } �����������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/convert_internal.h����������������������������������0000644�0001750�0001750�00000003264�14647725152�023042� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * convert_internal.h * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ typedef struct { uint8_t * rgb_ptr; int width; int field; int y_stride, rgb_stride, y_increm, uv_increm, rgb_increm, rgb_slice; int chroma420, convert420; int dither_offset, dither_stride; int y_stride_frame, uv_stride_frame, rgb_stride_frame, rgb_stride_min; } convert_rgb_t; typedef void mpeg2convert_copy_t (void * id, uint8_t * const * src, unsigned int v_offset); mpeg2convert_copy_t * mpeg2convert_rgb_mmxext (int bpp, int mode, const mpeg2_sequence_t * seq); mpeg2convert_copy_t * mpeg2convert_rgb_mmx (int bpp, int mode, const mpeg2_sequence_t * seq); mpeg2convert_copy_t * mpeg2convert_rgb_vis (int bpp, int mode, const mpeg2_sequence_t * seq); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/motion_comp_altivec.c�������������������������������0000644�0001750�0001750�00000071427�14647725152�023521� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_altivec.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #ifdef ARCH_PPC #ifdef HAVE_ALTIVEC_H #include <altivec.h> #endif #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" typedef vector signed char vector_s8_t; typedef vector unsigned char vector_u8_t; typedef vector signed short vector_s16_t; typedef vector unsigned short vector_u16_t; typedef vector signed int vector_s32_t; typedef vector unsigned int vector_u32_t; #ifndef COFFEE_BREAK /* Workarounds for gcc suckage */ static inline vector_u8_t my_vec_ld (int const A, const uint8_t * const B) { return vec_ld (A, (uint8_t *)B); } #undef vec_ld #define vec_ld my_vec_ld static inline vector_u8_t my_vec_and (vector_u8_t const A, vector_u8_t const B) { return vec_and (A, B); } #undef vec_and #define vec_and my_vec_and static inline vector_u8_t my_vec_avg (vector_u8_t const A, vector_u8_t const B) { return vec_avg (A, B); } #undef vec_avg #define vec_avg my_vec_avg #endif static void MC_put_o_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm, ref0, ref1, tmp; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp = vec_perm (ref0, ref1, perm); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, 0, dest); tmp = vec_perm (ref0, ref1, perm); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_perm (ref0, ref1, perm); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); vec_st (tmp, 0, dest); tmp = vec_perm (ref0, ref1, perm); vec_st (tmp, stride, dest); } static void MC_put_o_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm0); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } static void MC_put_x_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t permA, permB, ref0, ref1, tmp; permA = vec_lvsl (0, ref); permB = vec_add (permA, vec_splat_u8 (1)); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, 0, dest); tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); vec_st (tmp, 0, dest); tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); vec_st (tmp, stride, dest); } static void MC_put_x_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; ones = vec_splat_u8 (1); tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); perm0B = vec_add (perm0A, ones); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B)); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B)); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } static void MC_put_y_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); vec_st (tmp, stride, dest); } static void MC_put_y_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm0); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (tmp0, tmp1); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (tmp0, tmp1); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (tmp0, tmp1); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (tmp0, tmp1); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } static void MC_put_xy_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; vector_u8_t ones; ones = vec_splat_u8 (1); permA = vec_lvsl (0, ref); permB = vec_add (permA, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); vec_st (tmp, stride, dest); } static void MC_put_xy_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; vector_u8_t avg0, avg1, xor0, xor1, tmp, ones; ones = vec_splat_u8 (1); perm0A = vec_lvsl (0, ref); perm0A = vec_mergeh (perm0A, perm0A); perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); perm0B = vec_add (perm0A, ones); perm1A = vec_lvsl (stride, ref); perm1A = vec_mergeh (perm1A, perm1A); perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } #if 0 static void MC_put_xy_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t permA, permB, ref0, ref1, A, B, C, D, tmp, zero, ones; vector_u16_t splat2, temp; ones = vec_splat_u8 (1); permA = vec_lvsl (0, ref); permB = vec_add (permA, ones); zero = vec_splat_u8 (0); splat2 = vec_splat_u16 (2); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); C = vec_perm (ref0, ref1, permA); D = vec_perm (ref0, ref1, permB); temp = vec_add (vec_add ((vector_u16_t)vec_mergeh (zero, A), (vector_u16_t)vec_mergeh (zero, B)), vec_add ((vector_u16_t)vec_mergeh (zero, C), (vector_u16_t)vec_mergeh (zero, D))); temp = vec_sr (vec_add (temp, splat2), splat2); tmp = vec_pack (temp, temp); vec_st (tmp, 0, dest); dest += stride; tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); } while (--height); } #endif static void MC_avg_o_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm, ref0, ref1, tmp, prev; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (0, dest); tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); vec_st (tmp, stride, dest); } static void MC_avg_o_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1, prev; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (0, dest); tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } static void MC_avg_x_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t permA, permB, ref0, ref1, tmp, prev; permA = vec_lvsl (0, ref); permB = vec_add (permA, vec_splat_u8 (1)); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); prev = vec_ld (0, dest); ref += stride; tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); vec_st (tmp, stride, dest); } static void MC_avg_x_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; vector_u8_t prev; ones = vec_splat_u8 (1); tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); perm0B = vec_add (perm0A, ones); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); prev = vec_ld (0, dest); ref += stride; tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B))); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B))); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } static void MC_avg_y_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp, prev; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (0, dest); tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); vec_st (tmp, stride, dest); } static void MC_avg_y_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1, prev; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm0); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (0, dest); tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } static void MC_avg_xy_16_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; vector_u8_t ones, prev; ones = vec_splat_u8 (1); permA = vec_lvsl (0, ref); permB = vec_add (permA, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); vec_st (tmp, stride, dest); } static void MC_avg_xy_8_altivec (uint8_t * dest, const uint8_t * ref, const int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; vector_u8_t avg0, avg1, xor0, xor1, tmp, ones, prev; ones = vec_splat_u8 (1); perm0A = vec_lvsl (0, ref); perm0A = vec_mergeh (perm0A, perm0A); perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); perm0B = vec_add (perm0A, ones); perm1A = vec_lvsl (stride, ref); perm1A = vec_mergeh (perm1A, perm1A); perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; prev = vec_ld (0, dest); A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } MPEG2_MC_EXTERN (altivec) #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/slice.c���������������������������������������������0000644�0001750�0001750�00000207030�14647725152�020555� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * slice.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 2003 Peter Gubanov <peter@elecard.net.ru> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <inttypes.h> #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" extern mpeg2_mc_t mpeg2_mc; extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); extern void (* mpeg2_idct_add) (int last, int16_t * block, uint8_t * dest, int stride); extern void (* mpeg2_cpu_state_save) (cpu_state_t * state); extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state); #include "vlc.h" static inline int get_macroblock_modes (mpeg2_decoder_t * const decoder) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) int macroblock_modes; const MBtab * tab; switch (decoder->coding_type) { case I_TYPE: tab = MB_I + UBITS (bit_buf, 1); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if ((! (decoder->frame_pred_frame_dct)) && (decoder->picture_structure == FRAME_PICTURE)) { macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; case P_TYPE: tab = MB_P + UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (decoder->picture_structure != FRAME_PICTURE) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT; DUMPBITS (bit_buf, bits, 2); } return macroblock_modes | MACROBLOCK_MOTION_FORWARD; } else if (decoder->frame_pred_frame_dct) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT; return macroblock_modes | MACROBLOCK_MOTION_FORWARD; } else { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT; DUMPBITS (bit_buf, bits, 2); } if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes | MACROBLOCK_MOTION_FORWARD; } case B_TYPE: tab = MB_B + UBITS (bit_buf, 6); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (decoder->picture_structure != FRAME_PICTURE) { if (! (macroblock_modes & MACROBLOCK_INTRA)) { macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT; DUMPBITS (bit_buf, bits, 2); } return macroblock_modes; } else if (decoder->frame_pred_frame_dct) { /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ macroblock_modes |= MC_FRAME << MOTION_TYPE_SHIFT; return macroblock_modes; } else { if (macroblock_modes & MACROBLOCK_INTRA) goto intra; macroblock_modes |= UBITS (bit_buf, 2) << MOTION_TYPE_SHIFT; DUMPBITS (bit_buf, bits, 2); if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { intra: macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; } case D_TYPE: DUMPBITS (bit_buf, bits, 1); return MACROBLOCK_INTRA; default: return 0; } #undef bit_buf #undef bits #undef bit_ptr } static inline void get_quantizer_scale (mpeg2_decoder_t * const decoder) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) int quantizer_scale_code; quantizer_scale_code = UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, 5); decoder->quantizer_matrix[0] = decoder->quantizer_prescale[0][quantizer_scale_code]; decoder->quantizer_matrix[1] = decoder->quantizer_prescale[1][quantizer_scale_code]; decoder->quantizer_matrix[2] = decoder->chroma_quantizer[0][quantizer_scale_code]; decoder->quantizer_matrix[3] = decoder->chroma_quantizer[1][quantizer_scale_code]; #undef bit_buf #undef bits #undef bit_ptr } static inline int get_motion_delta (mpeg2_decoder_t * const decoder, const int f_code) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) int delta; int sign; const MVtab * tab; if (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 1); return 0; } else if (bit_buf >= 0x0c000000) { tab = MV_4 + UBITS (bit_buf, 4); delta = (tab->delta << f_code) + 1; bits += tab->len + f_code + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) delta += UBITS (bit_buf, f_code); bit_buf <<= f_code; return (delta ^ sign) - sign; } else { tab = MV_10 + UBITS (bit_buf, 10); delta = (tab->delta << f_code) + 1; bits += tab->len + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) { NEEDBITS (bit_buf, bits, bit_ptr); delta += UBITS (bit_buf, f_code); DUMPBITS (bit_buf, bits, f_code); } return (delta ^ sign) - sign; } #undef bit_buf #undef bits #undef bit_ptr } static inline int bound_motion_vector (const int vector, const int f_code) { return ((int32_t)vector << (27 - f_code)) >> (27 - f_code); } static inline int get_dmv (mpeg2_decoder_t * const decoder) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) const DMVtab * tab; tab = DMV_2 + UBITS (bit_buf, 2); DUMPBITS (bit_buf, bits, tab->len); return tab->dmv; #undef bit_buf #undef bits #undef bit_ptr } static inline int get_coded_block_pattern (mpeg2_decoder_t * const decoder) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) const CBPtab * tab; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x20000000) { tab = CBP_7 + (UBITS (bit_buf, 7) - 16); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; } else { tab = CBP_9 + UBITS (bit_buf, 9); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_luma_dc_dct_diff (mpeg2_decoder_t * const decoder) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) const DCtab * tab; int size; int dc_diff; if (bit_buf < 0xf8000000) { tab = DC_lum_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { bits += tab->len + size; bit_buf <<= tab->len; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff << decoder->intra_dc_precision; } else { DUMPBITS (bit_buf, bits, 3); return 0; } } else { tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len); NEEDBITS (bit_buf, bits, bit_ptr); dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); DUMPBITS (bit_buf, bits, size); return dc_diff << decoder->intra_dc_precision; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_chroma_dc_dct_diff (mpeg2_decoder_t * const decoder) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) const DCtab * tab; int size; int dc_diff; if (bit_buf < 0xf8000000) { tab = DC_chrom_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { bits += tab->len + size; bit_buf <<= tab->len; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff << decoder->intra_dc_precision; } else { DUMPBITS (bit_buf, bits, 2); return 0; } } else { tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len + 1); NEEDBITS (bit_buf, bits, bit_ptr); dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); DUMPBITS (bit_buf, bits, size); return dc_diff << decoder->intra_dc_precision; } #undef bit_buf #undef bits #undef bit_ptr } #define SATURATE(val) \ do { \ val <<= 4; \ if (unlikely (val != (int16_t) val)) \ val = (SBITS (val, 1) ^ 2047) << 4; \ } while (0) static void get_intra_block_B14 (mpeg2_decoder_t * const decoder, const uint16_t * const quant_matrix) { int i; int j; int val; const uint8_t * const scan = decoder->scan; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; const uint8_t * bit_ptr; int16_t * const dest = decoder->DCTblock; i = 0; mismatch = ~dest[0]; bit_buf = decoder->bitstream_buf; bits = decoder->bitstream_bits; bit_ptr = decoder->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quant_matrix[j]) >> 4; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 16; DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; decoder->bitstream_ptr = bit_ptr; } static void get_intra_block_B15 (mpeg2_decoder_t * const decoder, const uint16_t * const quant_matrix) { int i; int j; int val; const uint8_t * const scan = decoder->scan; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; const uint8_t * bit_ptr; int16_t * const dest = decoder->DCTblock; i = 0; mismatch = ~dest[0]; bit_buf = decoder->bitstream_buf; bits = decoder->bitstream_bits; bit_ptr = decoder->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x04000000) { tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) { normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quant_matrix[j]) >> 4; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else { /* end of block. I commented out this code because if we */ /* dont exit here we will still exit at the later test :) */ /* if (i >= 128) break; */ /* end of block */ /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check against buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = (SBITS (bit_buf, 12) * quant_matrix[j]) / 16; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } } else if (bit_buf >= 0x02000000) { tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 16; DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; decoder->bitstream_ptr = bit_ptr; } static int get_non_intra_block (mpeg2_decoder_t * const decoder, const uint16_t * const quant_matrix) { int i; int j; int val; const uint8_t * const scan = decoder->scan; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; const uint8_t * bit_ptr; int16_t * const dest = decoder->DCTblock; i = -1; mismatch = -1; bit_buf = decoder->bitstream_buf; bits = decoder->bitstream_bits; bit_ptr = decoder->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x28000000) { tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); goto entry_1; } else goto entry_2; while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); entry_1: i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } entry_2: if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; val = (val * quant_matrix[j]) / 32; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 16; DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; decoder->bitstream_ptr = bit_ptr; return i; } static void get_mpeg1_intra_block (mpeg2_decoder_t * const decoder) { int i; int j; int val; const uint8_t * const scan = decoder->scan; const uint16_t * const quant_matrix = decoder->quantizer_matrix[0]; const DCTtab * tab; uint32_t bit_buf; int bits; const uint8_t * bit_ptr; int16_t * const dest = decoder->DCTblock; i = 0; bit_buf = decoder->bitstream_buf; bits = decoder->bitstream_bits; bit_ptr = decoder->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quant_matrix[j]) >> 4; /* oddification */ val = (val - 1) | 1; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = SBITS (bit_buf, 8); if (! (val & 0x7f)) { DUMPBITS (bit_buf, bits, 8); val = UBITS (bit_buf, 8) + 2 * val; } val = (val * quant_matrix[j]) / 16; /* oddification */ val = (val + ~SBITS (val, 1)) | 1; SATURATE (val); dest[j] = val; DUMPBITS (bit_buf, bits, 8); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; decoder->bitstream_ptr = bit_ptr; } static int get_mpeg1_non_intra_block (mpeg2_decoder_t * const decoder) { int i; int j; int val; const uint8_t * const scan = decoder->scan; const uint16_t * const quant_matrix = decoder->quantizer_matrix[1]; const DCTtab * tab; uint32_t bit_buf; int bits; const uint8_t * bit_ptr; int16_t * const dest = decoder->DCTblock; i = -1; bit_buf = decoder->bitstream_buf; bits = decoder->bitstream_bits; bit_ptr = decoder->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x28000000) { tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); goto entry_1; } else goto entry_2; while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); entry_1: i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = ((2 * tab->level + 1) * quant_matrix[j]) >> 5; /* oddification */ val = (val - 1) | 1; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } entry_2: if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = SBITS (bit_buf, 8); if (! (val & 0x7f)) { DUMPBITS (bit_buf, bits, 8); val = UBITS (bit_buf, 8) + 2 * val; } val = 2 * (val + SBITS (val, 1)) + 1; val = (val * quant_matrix[j]) / 32; /* oddification */ val = (val + ~SBITS (val, 1)) | 1; SATURATE (val); dest[j] = val; DUMPBITS (bit_buf, bits, 8); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } DUMPBITS (bit_buf, bits, tab->len); /* dump end of block code */ decoder->bitstream_buf = bit_buf; decoder->bitstream_bits = bits; decoder->bitstream_ptr = bit_ptr; return i; } static inline void slice_intra_DCT (mpeg2_decoder_t * const decoder, const int cc, uint8_t * const dest, const int stride) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) NEEDBITS (bit_buf, bits, bit_ptr); /* Get the intra DC coefficient and inverse quantize it */ if (cc == 0) decoder->DCTblock[0] = decoder->dc_dct_pred[0] += get_luma_dc_dct_diff (decoder); else decoder->DCTblock[0] = decoder->dc_dct_pred[cc] += get_chroma_dc_dct_diff (decoder); if (decoder->mpeg1) { if (decoder->coding_type != D_TYPE) get_mpeg1_intra_block (decoder); } else if (decoder->intra_vlc_format) get_intra_block_B15 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]); else get_intra_block_B14 (decoder, decoder->quantizer_matrix[cc ? 2 : 0]); mpeg2_idct_copy (decoder->DCTblock, dest, stride); #undef bit_buf #undef bits #undef bit_ptr } static inline void slice_non_intra_DCT (mpeg2_decoder_t * const decoder, const int cc, uint8_t * const dest, const int stride) { int last; if (decoder->mpeg1) last = get_mpeg1_non_intra_block (decoder); else last = get_non_intra_block (decoder, decoder->quantizer_matrix[cc ? 3 : 1]); mpeg2_idct_add (last, decoder->DCTblock, dest, stride); } #define MOTION_420(table,ref,motion_x,motion_y,size,y) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y_ ## size)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \ motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \ ref[0] + (pos_x >> 1) + (pos_y >> 1) * decoder->stride, \ decoder->stride, size); \ motion_x /= 2; motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ offset = (((decoder->offset + motion_x) >> 1) + \ ((((decoder->v_offset + motion_y) >> 1) + y/2) * \ decoder->uv_stride)); \ table[4+xy_half] (decoder->dest[1] + y/2 * decoder->uv_stride + \ (decoder->offset >> 1), ref[1] + offset, \ decoder->uv_stride, size/2); \ table[4+xy_half] (decoder->dest[2] + y/2 * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ decoder->uv_stride, size/2) #define MOTION_FIELD_420(table,ref,motion_x,motion_y,dest_field,op,src_field) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = decoder->v_offset + motion_y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \ motion_y = pos_y - decoder->v_offset; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \ decoder->offset, \ (ref[0] + (pos_x >> 1) + \ ((pos_y op) + src_field) * decoder->stride), \ 2 * decoder->stride, 8); \ motion_x /= 2; motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ offset = (((decoder->offset + motion_x) >> 1) + \ (((decoder->v_offset >> 1) + (motion_y op) + src_field) * \ decoder->uv_stride)); \ table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \ (decoder->offset >> 1), ref[1] + offset, \ 2 * decoder->uv_stride, 4); \ table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ 2 * decoder->uv_stride, 4) #define MOTION_DMV_420(table,ref,motion_x,motion_y) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = decoder->v_offset + motion_y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \ motion_y = pos_y - decoder->v_offset; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \ table[xy_half] (decoder->dest[0] + decoder->offset, \ ref[0] + offset, 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \ ref[0] + decoder->stride + offset, \ 2 * decoder->stride, 8); \ motion_x /= 2; motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ offset = (((decoder->offset + motion_x) >> 1) + \ (((decoder->v_offset >> 1) + (motion_y & ~1)) * \ decoder->uv_stride)); \ table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \ ref[1] + offset, 2 * decoder->uv_stride, 4); \ table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \ (decoder->offset >> 1), \ ref[1] + decoder->uv_stride + offset, \ 2 * decoder->uv_stride, 4); \ table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \ ref[2] + offset, 2 * decoder->uv_stride, 4); \ table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \ (decoder->offset >> 1), \ ref[2] + decoder->uv_stride + offset, \ 2 * decoder->uv_stride, 4) #define MOTION_ZERO_420(table,ref) \ table[0] (decoder->dest[0] + decoder->offset, \ (ref[0] + decoder->offset + \ decoder->v_offset * decoder->stride), decoder->stride, 16); \ offset = ((decoder->offset >> 1) + \ (decoder->v_offset >> 1) * decoder->uv_stride); \ table[4] (decoder->dest[1] + (decoder->offset >> 1), \ ref[1] + offset, decoder->uv_stride, 8); \ table[4] (decoder->dest[2] + (decoder->offset >> 1), \ ref[2] + offset, decoder->uv_stride, 8) #define MOTION_422(table,ref,motion_x,motion_y,size,y) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y_ ## size)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \ motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \ table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \ ref[0] + offset, decoder->stride, size); \ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \ motion_x /= 2; \ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \ table[4+xy_half] (decoder->dest[1] + y * decoder->uv_stride + \ (decoder->offset >> 1), ref[1] + offset, \ decoder->uv_stride, size); \ table[4+xy_half] (decoder->dest[2] + y * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ decoder->uv_stride, size) #define MOTION_FIELD_422(table,ref,motion_x,motion_y,dest_field,op,src_field) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = decoder->v_offset + motion_y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \ motion_y = pos_y - decoder->v_offset; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \ table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \ decoder->offset, ref[0] + offset, \ 2 * decoder->stride, 8); \ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \ motion_x /= 2; \ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \ table[4+xy_half] (decoder->dest[1] + dest_field * decoder->uv_stride + \ (decoder->offset >> 1), ref[1] + offset, \ 2 * decoder->uv_stride, 8); \ table[4+xy_half] (decoder->dest[2] + dest_field * decoder->uv_stride + \ (decoder->offset >> 1), ref[2] + offset, \ 2 * decoder->uv_stride, 8) #define MOTION_DMV_422(table,ref,motion_x,motion_y) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = decoder->v_offset + motion_y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \ motion_y = pos_y - decoder->v_offset; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \ table[xy_half] (decoder->dest[0] + decoder->offset, \ ref[0] + offset, 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \ ref[0] + decoder->stride + offset, \ 2 * decoder->stride, 8); \ offset = (offset + (motion_x & (motion_x < 0))) >> 1; \ motion_x /= 2; \ xy_half = ((pos_y & 1) << 1) | (motion_x & 1); \ table[4+xy_half] (decoder->dest[1] + (decoder->offset >> 1), \ ref[1] + offset, 2 * decoder->uv_stride, 8); \ table[4+xy_half] (decoder->dest[1] + decoder->uv_stride + \ (decoder->offset >> 1), \ ref[1] + decoder->uv_stride + offset, \ 2 * decoder->uv_stride, 8); \ table[4+xy_half] (decoder->dest[2] + (decoder->offset >> 1), \ ref[2] + offset, 2 * decoder->uv_stride, 8); \ table[4+xy_half] (decoder->dest[2] + decoder->uv_stride + \ (decoder->offset >> 1), \ ref[2] + decoder->uv_stride + offset, \ 2 * decoder->uv_stride, 8) #define MOTION_ZERO_422(table,ref) \ offset = decoder->offset + decoder->v_offset * decoder->stride; \ table[0] (decoder->dest[0] + decoder->offset, \ ref[0] + offset, decoder->stride, 16); \ offset >>= 1; \ table[4] (decoder->dest[1] + (decoder->offset >> 1), \ ref[1] + offset, decoder->uv_stride, 16); \ table[4] (decoder->dest[2] + (decoder->offset >> 1), \ ref[2] + offset, decoder->uv_stride, 16) #define MOTION_444(table,ref,motion_x,motion_y,size,y) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = 2 * decoder->v_offset + motion_y + 2 * y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y_ ## size)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y_ ## size; \ motion_y = pos_y - 2 * decoder->v_offset - 2 * y; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ offset = (pos_x >> 1) + (pos_y >> 1) * decoder->stride; \ table[xy_half] (decoder->dest[0] + y * decoder->stride + decoder->offset, \ ref[0] + offset, decoder->stride, size); \ table[xy_half] (decoder->dest[1] + y * decoder->stride + decoder->offset, \ ref[1] + offset, decoder->stride, size); \ table[xy_half] (decoder->dest[2] + y * decoder->stride + decoder->offset, \ ref[2] + offset, decoder->stride, size) #define MOTION_FIELD_444(table,ref,motion_x,motion_y,dest_field,op,src_field) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = decoder->v_offset + motion_y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \ motion_y = pos_y - decoder->v_offset; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ offset = (pos_x >> 1) + ((pos_y op) + src_field) * decoder->stride; \ table[xy_half] (decoder->dest[0] + dest_field * decoder->stride + \ decoder->offset, ref[0] + offset, \ 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[1] + dest_field * decoder->stride + \ decoder->offset, ref[1] + offset, \ 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[2] + dest_field * decoder->stride + \ decoder->offset, ref[2] + offset, \ 2 * decoder->stride, 8) #define MOTION_DMV_444(table,ref,motion_x,motion_y) \ pos_x = 2 * decoder->offset + motion_x; \ pos_y = decoder->v_offset + motion_y; \ if (unlikely (pos_x > decoder->limit_x)) { \ pos_x = ((int)pos_x < 0) ? 0 : decoder->limit_x; \ motion_x = pos_x - 2 * decoder->offset; \ } \ if (unlikely (pos_y > decoder->limit_y)) { \ pos_y = ((int)pos_y < 0) ? 0 : decoder->limit_y; \ motion_y = pos_y - decoder->v_offset; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ offset = (pos_x >> 1) + (pos_y & ~1) * decoder->stride; \ table[xy_half] (decoder->dest[0] + decoder->offset, \ ref[0] + offset, 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[0] + decoder->stride + decoder->offset, \ ref[0] + decoder->stride + offset, \ 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[1] + decoder->offset, \ ref[1] + offset, 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[1] + decoder->stride + decoder->offset, \ ref[1] + decoder->stride + offset, \ 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[2] + decoder->offset, \ ref[2] + offset, 2 * decoder->stride, 8); \ table[xy_half] (decoder->dest[2] + decoder->stride + decoder->offset, \ ref[2] + decoder->stride + offset, \ 2 * decoder->stride, 8) #define MOTION_ZERO_444(table,ref) \ offset = decoder->offset + decoder->v_offset * decoder->stride; \ table[0] (decoder->dest[0] + decoder->offset, \ ref[0] + offset, decoder->stride, 16); \ table[4] (decoder->dest[1] + decoder->offset, \ ref[1] + offset, decoder->stride, 16); \ table[4] (decoder->dest[2] + (decoder->offset >> 1), \ ref[2] + offset, decoder->stride, 16) #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) static void motion_mp1 (mpeg2_decoder_t * const decoder, motion_t * const motion, mpeg2_mc_fct * const * const table) { int motion_x, motion_y; unsigned int pos_x, pos_y, xy_half, offset; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = (motion->pmv[0][0] + (get_motion_delta (decoder, motion->f_code[0]) << motion->f_code[1])); motion_x = bound_motion_vector (motion_x, motion->f_code[0] + motion->f_code[1]); motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[0][1] + (get_motion_delta (decoder, motion->f_code[0]) << motion->f_code[1])); motion_y = bound_motion_vector (motion_y, motion->f_code[0] + motion->f_code[1]); motion->pmv[0][1] = motion_y; MOTION_420 (table, motion->ref[0], motion_x, motion_y, 16, 0); } #define MOTION_FUNCTIONS(FORMAT,MOTION,MOTION_FIELD,MOTION_DMV,MOTION_ZERO) \ \ static void motion_fr_frame_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ int motion_x, motion_y; \ unsigned int pos_x, pos_y, xy_half, offset; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \ motion->f_code[1]); \ motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \ motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \ \ MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); \ } \ \ static void motion_fr_field_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ int motion_x, motion_y, field; \ unsigned int pos_x, pos_y, xy_half, offset; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ field = UBITS (bit_buf, 1); \ DUMPBITS (bit_buf, bits, 1); \ \ motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[0][0] = motion_x; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_y = ((motion->pmv[0][1] >> 1) + \ get_motion_delta (decoder, motion->f_code[1])); \ /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \ motion->pmv[0][1] = motion_y << 1; \ \ MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field); \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ field = UBITS (bit_buf, 1); \ DUMPBITS (bit_buf, bits, 1); \ \ motion_x = motion->pmv[1][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[1][0] = motion_x; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_y = ((motion->pmv[1][1] >> 1) + \ get_motion_delta (decoder, motion->f_code[1])); \ /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \ motion->pmv[1][1] = motion_y << 1; \ \ MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field); \ } \ \ static void motion_fr_dmv_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ int motion_x, motion_y, dmv_x, dmv_y, m, other_x, other_y; \ unsigned int pos_x, pos_y, xy_half, offset; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \ NEEDBITS (bit_buf, bits, bit_ptr); \ dmv_x = get_dmv (decoder); \ \ motion_y = ((motion->pmv[0][1] >> 1) + \ get_motion_delta (decoder, motion->f_code[1])); \ /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ \ motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; \ dmv_y = get_dmv (decoder); \ \ m = decoder->top_field_first ? 1 : 3; \ other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; \ other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; \ MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 0, | 1, 0); \ \ m = decoder->top_field_first ? 3 : 1; \ other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; \ other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; \ MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 1, & ~1, 0);\ \ MOTION_DMV (mpeg2_mc.avg, motion->ref[0], motion_x, motion_y); \ } \ \ static void motion_reuse_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ int motion_x, motion_y; \ unsigned int pos_x, pos_y, xy_half, offset; \ \ motion_x = motion->pmv[0][0]; \ motion_y = motion->pmv[0][1]; \ \ MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); \ } \ \ static void motion_zero_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ unsigned int offset; \ \ motion->pmv[0][0] = motion->pmv[0][1] = 0; \ motion->pmv[1][0] = motion->pmv[1][1] = 0; \ \ MOTION_ZERO (table, motion->ref[0]); \ } \ \ static void motion_fi_field_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ int motion_x, motion_y; \ uint8_t ** ref_field; \ unsigned int pos_x, pos_y, xy_half, offset; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ ref_field = motion->ref2[UBITS (bit_buf, 1)]; \ DUMPBITS (bit_buf, bits, 1); \ \ motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \ motion->f_code[1]); \ motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \ motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \ \ MOTION (table, ref_field, motion_x, motion_y, 16, 0); \ } \ \ static void motion_fi_16x8_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ int motion_x, motion_y; \ uint8_t ** ref_field; \ unsigned int pos_x, pos_y, xy_half, offset; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ ref_field = motion->ref2[UBITS (bit_buf, 1)]; \ DUMPBITS (bit_buf, bits, 1); \ \ motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[0][0] = motion_x; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \ motion->f_code[1]); \ motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \ motion->pmv[0][1] = motion_y; \ \ MOTION (table, ref_field, motion_x, motion_y, 8, 0); \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ ref_field = motion->ref2[UBITS (bit_buf, 1)]; \ DUMPBITS (bit_buf, bits, 1); \ \ motion_x = motion->pmv[1][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[1][0] = motion_x; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_y = motion->pmv[1][1] + get_motion_delta (decoder, \ motion->f_code[1]); \ motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \ motion->pmv[1][1] = motion_y; \ \ MOTION (table, ref_field, motion_x, motion_y, 8, 8); \ } \ \ static void motion_fi_dmv_##FORMAT (mpeg2_decoder_t * const decoder, \ motion_t * const motion, \ mpeg2_mc_fct * const * const table) \ { \ int motion_x, motion_y, other_x, other_y; \ unsigned int pos_x, pos_y, xy_half, offset; \ \ NEEDBITS (bit_buf, bits, bit_ptr); \ motion_x = motion->pmv[0][0] + get_motion_delta (decoder, \ motion->f_code[0]); \ motion_x = bound_motion_vector (motion_x, motion->f_code[0]); \ motion->pmv[1][0] = motion->pmv[0][0] = motion_x; \ NEEDBITS (bit_buf, bits, bit_ptr); \ other_x = ((motion_x + (motion_x > 0)) >> 1) + get_dmv (decoder); \ \ motion_y = motion->pmv[0][1] + get_motion_delta (decoder, \ motion->f_code[1]); \ motion_y = bound_motion_vector (motion_y, motion->f_code[1]); \ motion->pmv[1][1] = motion->pmv[0][1] = motion_y; \ other_y = (((motion_y + (motion_y > 0)) >> 1) + get_dmv (decoder) + \ decoder->dmv_offset); \ \ MOTION (mpeg2_mc.put, motion->ref[0], motion_x, motion_y, 16, 0); \ MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); \ } \ MOTION_FUNCTIONS (420, MOTION_420, MOTION_FIELD_420, MOTION_DMV_420, MOTION_ZERO_420) MOTION_FUNCTIONS (422, MOTION_422, MOTION_FIELD_422, MOTION_DMV_422, MOTION_ZERO_422) MOTION_FUNCTIONS (444, MOTION_444, MOTION_FIELD_444, MOTION_DMV_444, MOTION_ZERO_444) /* like motion_frame, but parsing without actual motion compensation */ static void motion_fr_conceal (mpeg2_decoder_t * const decoder) { int tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (decoder->f_motion.pmv[0][0] + get_motion_delta (decoder, decoder->f_motion.f_code[0])); tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]); decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (decoder->f_motion.pmv[0][1] + get_motion_delta (decoder, decoder->f_motion.f_code[1])); tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]); decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp; DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ } static void motion_fi_conceal (mpeg2_decoder_t * const decoder) { int tmp; NEEDBITS (bit_buf, bits, bit_ptr); DUMPBITS (bit_buf, bits, 1); /* remove field_select */ tmp = (decoder->f_motion.pmv[0][0] + get_motion_delta (decoder, decoder->f_motion.f_code[0])); tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[0]); decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[0][0] = tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (decoder->f_motion.pmv[0][1] + get_motion_delta (decoder, decoder->f_motion.f_code[1])); tmp = bound_motion_vector (tmp, decoder->f_motion.f_code[1]); decoder->f_motion.pmv[1][1] = decoder->f_motion.pmv[0][1] = tmp; DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ } #undef bit_buf #undef bits #undef bit_ptr #define MOTION_CALL(routine,direction) \ do { \ if ((direction) & MACROBLOCK_MOTION_FORWARD) \ routine (decoder, &(decoder->f_motion), mpeg2_mc.put); \ if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ routine (decoder, &(decoder->b_motion), \ ((direction) & MACROBLOCK_MOTION_FORWARD ? \ mpeg2_mc.avg : mpeg2_mc.put)); \ } while (0) #define NEXT_MACROBLOCK \ do { \ decoder->offset += 16; \ if (decoder->offset == decoder->width) { \ do { /* just so we can use the break statement */ \ if (decoder->convert) { \ decoder->convert (decoder->convert_id, decoder->dest, \ decoder->v_offset); \ if (decoder->coding_type == B_TYPE) \ break; \ } \ decoder->dest[0] += decoder->slice_stride; \ decoder->dest[1] += decoder->slice_uv_stride; \ decoder->dest[2] += decoder->slice_uv_stride; \ } while (0); \ decoder->v_offset += 16; \ if (decoder->v_offset > decoder->limit_y) { \ if (mpeg2_cpu_state_restore) \ mpeg2_cpu_state_restore (&cpu_state); \ return; \ } \ decoder->offset = 0; \ } \ } while (0) void mpeg2_init_fbuf (mpeg2_decoder_t * decoder, uint8_t * current_fbuf[3], uint8_t * forward_fbuf[3], uint8_t * backward_fbuf[3]) { int offset, stride, height, bottom_field; stride = decoder->stride_frame; bottom_field = (decoder->picture_structure == BOTTOM_FIELD); offset = bottom_field ? stride : 0; height = decoder->height; decoder->picture_dest[0] = current_fbuf[0] + offset; decoder->picture_dest[1] = current_fbuf[1] + (offset >> 1); decoder->picture_dest[2] = current_fbuf[2] + (offset >> 1); decoder->f_motion.ref[0][0] = forward_fbuf[0] + offset; decoder->f_motion.ref[0][1] = forward_fbuf[1] + (offset >> 1); decoder->f_motion.ref[0][2] = forward_fbuf[2] + (offset >> 1); decoder->b_motion.ref[0][0] = backward_fbuf[0] + offset; decoder->b_motion.ref[0][1] = backward_fbuf[1] + (offset >> 1); decoder->b_motion.ref[0][2] = backward_fbuf[2] + (offset >> 1); if (decoder->picture_structure != FRAME_PICTURE) { decoder->dmv_offset = bottom_field ? 1 : -1; decoder->f_motion.ref2[0] = decoder->f_motion.ref[bottom_field]; decoder->f_motion.ref2[1] = decoder->f_motion.ref[!bottom_field]; decoder->b_motion.ref2[0] = decoder->b_motion.ref[bottom_field]; decoder->b_motion.ref2[1] = decoder->b_motion.ref[!bottom_field]; offset = stride - offset; if (decoder->second_field && (decoder->coding_type != B_TYPE)) forward_fbuf = current_fbuf; decoder->f_motion.ref[1][0] = forward_fbuf[0] + offset; decoder->f_motion.ref[1][1] = forward_fbuf[1] + (offset >> 1); decoder->f_motion.ref[1][2] = forward_fbuf[2] + (offset >> 1); decoder->b_motion.ref[1][0] = backward_fbuf[0] + offset; decoder->b_motion.ref[1][1] = backward_fbuf[1] + (offset >> 1); decoder->b_motion.ref[1][2] = backward_fbuf[2] + (offset >> 1); stride <<= 1; height >>= 1; } decoder->stride = stride; decoder->uv_stride = stride >> 1; decoder->slice_stride = 16 * stride; decoder->slice_uv_stride = decoder->slice_stride >> (2 - decoder->chroma_format); decoder->limit_x = 2 * decoder->width - 32; decoder->limit_y_16 = 2 * height - 32; decoder->limit_y_8 = 2 * height - 16; decoder->limit_y = height - 16; if (decoder->mpeg1) { decoder->motion_parser[0] = motion_zero_420; decoder->motion_parser[MC_FRAME] = motion_mp1; decoder->motion_parser[4] = motion_reuse_420; } else if (decoder->picture_structure == FRAME_PICTURE) { if (decoder->chroma_format == 0) { decoder->motion_parser[0] = motion_zero_420; decoder->motion_parser[MC_FIELD] = motion_fr_field_420; decoder->motion_parser[MC_FRAME] = motion_fr_frame_420; decoder->motion_parser[MC_DMV] = motion_fr_dmv_420; decoder->motion_parser[4] = motion_reuse_420; } else if (decoder->chroma_format == 1) { decoder->motion_parser[0] = motion_zero_422; decoder->motion_parser[MC_FIELD] = motion_fr_field_422; decoder->motion_parser[MC_FRAME] = motion_fr_frame_422; decoder->motion_parser[MC_DMV] = motion_fr_dmv_422; decoder->motion_parser[4] = motion_reuse_422; } else { decoder->motion_parser[0] = motion_zero_444; decoder->motion_parser[MC_FIELD] = motion_fr_field_444; decoder->motion_parser[MC_FRAME] = motion_fr_frame_444; decoder->motion_parser[MC_DMV] = motion_fr_dmv_444; decoder->motion_parser[4] = motion_reuse_444; } } else { if (decoder->chroma_format == 0) { decoder->motion_parser[0] = motion_zero_420; decoder->motion_parser[MC_FIELD] = motion_fi_field_420; decoder->motion_parser[MC_16X8] = motion_fi_16x8_420; decoder->motion_parser[MC_DMV] = motion_fi_dmv_420; decoder->motion_parser[4] = motion_reuse_420; } else if (decoder->chroma_format == 1) { decoder->motion_parser[0] = motion_zero_422; decoder->motion_parser[MC_FIELD] = motion_fi_field_422; decoder->motion_parser[MC_16X8] = motion_fi_16x8_422; decoder->motion_parser[MC_DMV] = motion_fi_dmv_422; decoder->motion_parser[4] = motion_reuse_422; } else { decoder->motion_parser[0] = motion_zero_444; decoder->motion_parser[MC_FIELD] = motion_fi_field_444; decoder->motion_parser[MC_16X8] = motion_fi_16x8_444; decoder->motion_parser[MC_DMV] = motion_fi_dmv_444; decoder->motion_parser[4] = motion_reuse_444; } } } static inline int slice_init (mpeg2_decoder_t * const decoder, int code) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) int offset; const MBAtab * mba; decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = decoder->dc_dct_pred[2] = 16384; decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0; decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0; decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0; decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0; if (decoder->vertical_position_extension) { code += UBITS (bit_buf, 3) << 7; DUMPBITS (bit_buf, bits, 3); } decoder->v_offset = (code - 1) * 16; offset = 0; if (!(decoder->convert) || decoder->coding_type != B_TYPE) offset = (code - 1) * decoder->slice_stride; decoder->dest[0] = decoder->picture_dest[0] + offset; offset >>= (2 - decoder->chroma_format); decoder->dest[1] = decoder->picture_dest[1] + offset; decoder->dest[2] = decoder->picture_dest[2] + offset; get_quantizer_scale (decoder); /* ignore intra_slice and all the extra data */ while (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 9); NEEDBITS (bit_buf, bits, bit_ptr); } /* decode initial macroblock address increment */ offset = 0; while (1) { if (bit_buf >= 0x08000000) { mba = MBA_5 + (UBITS (bit_buf, 6) - 2); break; } else if (bit_buf >= 0x01800000) { mba = MBA_11 + (UBITS (bit_buf, 12) - 24); break; } else switch (UBITS (bit_buf, 12)) { case 8: /* macroblock_escape */ offset += 33; DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; case 15: /* macroblock_stuffing (MPEG1 only) */ bit_buf &= 0xfffff; DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; default: /* error */ return 1; } } DUMPBITS (bit_buf, bits, mba->len + 1); decoder->offset = (offset + mba->mba) << 4; while (decoder->offset - decoder->width >= 0) { decoder->offset -= decoder->width; if (!(decoder->convert) || decoder->coding_type != B_TYPE) { decoder->dest[0] += decoder->slice_stride; decoder->dest[1] += decoder->slice_uv_stride; decoder->dest[2] += decoder->slice_uv_stride; } decoder->v_offset += 16; } if (decoder->v_offset > decoder->limit_y) return 1; return 0; #undef bit_buf #undef bits #undef bit_ptr } void mpeg2_slice (mpeg2_decoder_t * const decoder, const int code, const uint8_t * const buffer) { #define bit_buf (decoder->bitstream_buf) #define bits (decoder->bitstream_bits) #define bit_ptr (decoder->bitstream_ptr) cpu_state_t cpu_state; bitstream_init (decoder, buffer); if (slice_init (decoder, code)) return; if (mpeg2_cpu_state_save) mpeg2_cpu_state_save (&cpu_state); while (1) { int macroblock_modes; int mba_inc; const MBAtab * mba; NEEDBITS (bit_buf, bits, bit_ptr); macroblock_modes = get_macroblock_modes (decoder); /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */ if (macroblock_modes & MACROBLOCK_QUANT) get_quantizer_scale (decoder); if (macroblock_modes & MACROBLOCK_INTRA) { int DCT_offset, DCT_stride; int offset; uint8_t * dest_y; if (decoder->concealment_motion_vectors) { if (decoder->picture_structure == FRAME_PICTURE) motion_fr_conceal (decoder); else motion_fi_conceal (decoder); } else { decoder->f_motion.pmv[0][0] = decoder->f_motion.pmv[0][1] = 0; decoder->f_motion.pmv[1][0] = decoder->f_motion.pmv[1][1] = 0; decoder->b_motion.pmv[0][0] = decoder->b_motion.pmv[0][1] = 0; decoder->b_motion.pmv[1][0] = decoder->b_motion.pmv[1][1] = 0; } if (macroblock_modes & DCT_TYPE_INTERLACED) { DCT_offset = decoder->stride; DCT_stride = decoder->stride * 2; } else { DCT_offset = decoder->stride * 8; DCT_stride = decoder->stride; } offset = decoder->offset; dest_y = decoder->dest[0] + offset; slice_intra_DCT (decoder, 0, dest_y, DCT_stride); slice_intra_DCT (decoder, 0, dest_y + 8, DCT_stride); slice_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); slice_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); if (likely (decoder->chroma_format == 0)) { slice_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1), decoder->uv_stride); slice_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1), decoder->uv_stride); if (decoder->coding_type == D_TYPE) { NEEDBITS (bit_buf, bits, bit_ptr); DUMPBITS (bit_buf, bits, 1); } } else if (likely (decoder->chroma_format == 1)) { uint8_t * dest_u = decoder->dest[1] + (offset >> 1); uint8_t * dest_v = decoder->dest[2] + (offset >> 1); DCT_stride >>= 1; DCT_offset >>= 1; slice_intra_DCT (decoder, 1, dest_u, DCT_stride); slice_intra_DCT (decoder, 2, dest_v, DCT_stride); slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride); slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride); } else { uint8_t * dest_u = decoder->dest[1] + offset; uint8_t * dest_v = decoder->dest[2] + offset; slice_intra_DCT (decoder, 1, dest_u, DCT_stride); slice_intra_DCT (decoder, 2, dest_v, DCT_stride); slice_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride); slice_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride); slice_intra_DCT (decoder, 1, dest_u + 8, DCT_stride); slice_intra_DCT (decoder, 2, dest_v + 8, DCT_stride); slice_intra_DCT (decoder, 1, dest_u + DCT_offset + 8, DCT_stride); slice_intra_DCT (decoder, 2, dest_v + DCT_offset + 8, DCT_stride); } } else { motion_parser_t * parser; parser = decoder->motion_parser[macroblock_modes >> MOTION_TYPE_SHIFT]; MOTION_CALL (parser, macroblock_modes); if (macroblock_modes & MACROBLOCK_PATTERN) { int coded_block_pattern; int DCT_offset, DCT_stride; if (macroblock_modes & DCT_TYPE_INTERLACED) { DCT_offset = decoder->stride; DCT_stride = decoder->stride * 2; } else { DCT_offset = decoder->stride * 8; DCT_stride = decoder->stride; } coded_block_pattern = get_coded_block_pattern (decoder); if (likely (decoder->chroma_format == 0)) { int offset = decoder->offset; uint8_t * dest_y = decoder->dest[0] + offset; if (coded_block_pattern & 1) slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride); if (coded_block_pattern & 2) slice_non_intra_DCT (decoder, 0, dest_y + 8, DCT_stride); if (coded_block_pattern & 4) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); if (coded_block_pattern & 8) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); if (coded_block_pattern & 16) slice_non_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1), decoder->uv_stride); if (coded_block_pattern & 32) slice_non_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1), decoder->uv_stride); } else if (likely (decoder->chroma_format == 1)) { int offset; uint8_t * dest_y; coded_block_pattern |= bit_buf & (3 << 30); DUMPBITS (bit_buf, bits, 2); offset = decoder->offset; dest_y = decoder->dest[0] + offset; if (coded_block_pattern & 1) slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride); if (coded_block_pattern & 2) slice_non_intra_DCT (decoder, 0, dest_y + 8, DCT_stride); if (coded_block_pattern & 4) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); if (coded_block_pattern & 8) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); DCT_stride >>= 1; DCT_offset = (DCT_offset + offset) >> 1; if (coded_block_pattern & 16) slice_non_intra_DCT (decoder, 1, decoder->dest[1] + (offset >> 1), DCT_stride); if (coded_block_pattern & 32) slice_non_intra_DCT (decoder, 2, decoder->dest[2] + (offset >> 1), DCT_stride); if (coded_block_pattern & (2 << 30)) slice_non_intra_DCT (decoder, 1, decoder->dest[1] + DCT_offset, DCT_stride); if (coded_block_pattern & (1 << 30)) slice_non_intra_DCT (decoder, 2, decoder->dest[2] + DCT_offset, DCT_stride); } else { int offset; uint8_t * dest_y, * dest_u, * dest_v; coded_block_pattern |= bit_buf & (63 << 26); DUMPBITS (bit_buf, bits, 6); offset = decoder->offset; dest_y = decoder->dest[0] + offset; dest_u = decoder->dest[1] + offset; dest_v = decoder->dest[2] + offset; if (coded_block_pattern & 1) slice_non_intra_DCT (decoder, 0, dest_y, DCT_stride); if (coded_block_pattern & 2) slice_non_intra_DCT (decoder, 0, dest_y + 8, DCT_stride); if (coded_block_pattern & 4) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset, DCT_stride); if (coded_block_pattern & 8) slice_non_intra_DCT (decoder, 0, dest_y + DCT_offset + 8, DCT_stride); if (coded_block_pattern & 16) slice_non_intra_DCT (decoder, 1, dest_u, DCT_stride); if (coded_block_pattern & 32) slice_non_intra_DCT (decoder, 2, dest_v, DCT_stride); if (coded_block_pattern & (32 << 26)) slice_non_intra_DCT (decoder, 1, dest_u + DCT_offset, DCT_stride); if (coded_block_pattern & (16 << 26)) slice_non_intra_DCT (decoder, 2, dest_v + DCT_offset, DCT_stride); if (coded_block_pattern & (8 << 26)) slice_non_intra_DCT (decoder, 1, dest_u + 8, DCT_stride); if (coded_block_pattern & (4 << 26)) slice_non_intra_DCT (decoder, 2, dest_v + 8, DCT_stride); if (coded_block_pattern & (2 << 26)) slice_non_intra_DCT (decoder, 1, dest_u + DCT_offset + 8, DCT_stride); if (coded_block_pattern & (1 << 26)) slice_non_intra_DCT (decoder, 2, dest_v + DCT_offset + 8, DCT_stride); } } decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = decoder->dc_dct_pred[2] = 16384; } NEXT_MACROBLOCK; NEEDBITS (bit_buf, bits, bit_ptr); mba_inc = 0; while (1) { if (bit_buf >= 0x10000000) { mba = MBA_5 + (UBITS (bit_buf, 5) - 2); break; } else if (bit_buf >= 0x03000000) { mba = MBA_11 + (UBITS (bit_buf, 11) - 24); break; } else switch (UBITS (bit_buf, 11)) { case 8: /* macroblock_escape */ mba_inc += 33; /* pass through */ case 15: /* macroblock_stuffing (MPEG1 only) */ DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; default: /* end of slice, or error */ if (mpeg2_cpu_state_restore) mpeg2_cpu_state_restore (&cpu_state); return; } } DUMPBITS (bit_buf, bits, mba->len); mba_inc += mba->mba; if (mba_inc) { decoder->dc_dct_pred[0] = decoder->dc_dct_pred[1] = decoder->dc_dct_pred[2] = 16384; if (decoder->coding_type == P_TYPE) { do { MOTION_CALL (decoder->motion_parser[0], MACROBLOCK_MOTION_FORWARD); NEXT_MACROBLOCK; } while (--mba_inc); } else { do { MOTION_CALL (decoder->motion_parser[4], macroblock_modes); NEXT_MACROBLOCK; } while (--mba_inc); } } } #undef bit_buf #undef bits #undef bit_ptr } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2new/libmpeg2/header.c��������������������������������������������0000644�0001750�0001750�00000076517�14647725152�020724� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * header.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 2003 Regis Duchesne <hpreg@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include <inttypes.h> #include <stdlib.h> /* defines NULL */ #include <string.h> /* memcmp */ #include "../include/mpeg2.h" #include "../include/attributes.h" #include "mpeg2_internal.h" #define SEQ_EXT 2 #define SEQ_DISPLAY_EXT 4 #define QUANT_MATRIX_EXT 8 #define COPYRIGHT_EXT 0x10 #define PIC_DISPLAY_EXT 0x80 #define PIC_CODING_EXT 0x100 /* default intra quant matrix, in zig-zag order */ static const uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = { 8, 16, 16, 19, 16, 19, 22, 22, 22, 22, 22, 22, 26, 24, 26, 27, 27, 27, 26, 26, 26, 26, 27, 27, 27, 29, 29, 29, 34, 34, 34, 29, 29, 29, 27, 27, 29, 29, 32, 32, 34, 34, 37, 38, 37, 35, 35, 34, 35, 38, 38, 40, 40, 40, 48, 48, 46, 46, 56, 56, 58, 69, 69, 83 }; uint8_t mpeg2_scan_norm[64] ATTR_ALIGN(16) = { /* Zig-Zag scan pattern */ 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 }; uint8_t mpeg2_scan_alt[64] ATTR_ALIGN(16) = { /* Alternate scan pattern */ 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 }; void mpeg2_header_state_init (mpeg2dec_t * mpeg2dec) { if (mpeg2dec->sequence.width != (unsigned)-1) { int i; mpeg2dec->sequence.width = (unsigned)-1; if (!mpeg2dec->custom_fbuf) for (i = mpeg2dec->alloc_index_user; i < mpeg2dec->alloc_index; i++) { mpeg2_free (mpeg2dec->fbuf_alloc[i].fbuf.buf[0]); mpeg2_free (mpeg2dec->fbuf_alloc[i].fbuf.buf[1]); mpeg2_free (mpeg2dec->fbuf_alloc[i].fbuf.buf[2]); } if (mpeg2dec->convert_start) for (i = 0; i < 3; i++) { mpeg2_free (mpeg2dec->yuv_buf[i][0]); mpeg2_free (mpeg2dec->yuv_buf[i][1]); mpeg2_free (mpeg2dec->yuv_buf[i][2]); } if (mpeg2dec->decoder.convert_id) mpeg2_free (mpeg2dec->decoder.convert_id); } mpeg2dec->decoder.coding_type = I_TYPE; mpeg2dec->decoder.convert = NULL; mpeg2dec->decoder.convert_id = NULL; mpeg2dec->picture = mpeg2dec->pictures; mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[0].fbuf; mpeg2dec->fbuf[1] = &mpeg2dec->fbuf_alloc[1].fbuf; mpeg2dec->fbuf[2] = &mpeg2dec->fbuf_alloc[2].fbuf; mpeg2dec->first = 1; mpeg2dec->alloc_index = 0; mpeg2dec->alloc_index_user = 0; mpeg2dec->first_decode_slice = 1; mpeg2dec->nb_decode_slices = 0xb0 - 1; mpeg2dec->convert = NULL; mpeg2dec->convert_start = NULL; mpeg2dec->custom_fbuf = 0; mpeg2dec->yuv_index = 0; } void mpeg2_reset_info (mpeg2_info_t * info) { info->current_picture = info->current_picture_2nd = NULL; info->display_picture = info->display_picture_2nd = NULL; info->current_fbuf = info->display_fbuf = info->discard_fbuf = NULL; } static void info_user_data (mpeg2dec_t * mpeg2dec) { if (mpeg2dec->user_data_len) { mpeg2dec->info.user_data = mpeg2dec->chunk_buffer; mpeg2dec->info.user_data_len = mpeg2dec->user_data_len - 3; } } int mpeg2_header_sequence (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence); static unsigned int frame_period[16] = { 0, 1126125, 1125000, 1080000, 900900, 900000, 540000, 450450, 450000, /* unofficial: xing 15 fps */ 1800000, /* unofficial: libmpeg3 "Unofficial economy rates" 5/10/12/15 fps */ 5400000, 2700000, 2250000, 1800000, 0, 0 }; int i; if ((buffer[6] & 0x20) != 0x20) /* missing marker_bit */ return 1; i = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; if (! (sequence->display_width = sequence->picture_width = i >> 12)) return 1; if (! (sequence->display_height = sequence->picture_height = i & 0xfff)) return 1; sequence->width = (sequence->picture_width + 15) & ~15; sequence->height = (sequence->picture_height + 15) & ~15; sequence->chroma_width = sequence->width >> 1; sequence->chroma_height = sequence->height >> 1; sequence->flags = (SEQ_FLAG_PROGRESSIVE_SEQUENCE | SEQ_VIDEO_FORMAT_UNSPECIFIED); sequence->pixel_width = buffer[3] >> 4; /* aspect ratio */ sequence->frame_period = frame_period[buffer[3] & 15]; sequence->byte_rate = (buffer[4]<<10) | (buffer[5]<<2) | (buffer[6]>>6); sequence->vbv_buffer_size = ((buffer[6]<<16)|(buffer[7]<<8))&0x1ff800; if (buffer[7] & 4) sequence->flags |= SEQ_FLAG_CONSTRAINED_PARAMETERS; mpeg2dec->copy_matrix = 3; if (buffer[7] & 2) { for (i = 0; i < 64; i++) mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] = (buffer[i+7] << 7) | (buffer[i+8] >> 1); buffer += 64; } else for (i = 0; i < 64; i++) mpeg2dec->new_quantizer_matrix[0][mpeg2_scan_norm[i]] = default_intra_quantizer_matrix[i]; if (buffer[7] & 1) for (i = 0; i < 64; i++) mpeg2dec->new_quantizer_matrix[1][mpeg2_scan_norm[i]] = buffer[i+8]; else memset (mpeg2dec->new_quantizer_matrix[1], 16, 64); sequence->profile_level_id = 0x80; sequence->colour_primaries = 0; sequence->transfer_characteristics = 0; sequence->matrix_coefficients = 0; mpeg2dec->ext_state = SEQ_EXT; mpeg2dec->state = STATE_SEQUENCE; mpeg2dec->display_offset_x = mpeg2dec->display_offset_y = 0; return 0; } static int sequence_ext (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence); uint32_t flags; if (!(buffer[3] & 1)) return 1; sequence->profile_level_id = (buffer[0] << 4) | (buffer[1] >> 4); sequence->display_width = sequence->picture_width += ((buffer[1] << 13) | (buffer[2] << 5)) & 0x3000; sequence->display_height = sequence->picture_height += (buffer[2] << 7) & 0x3000; sequence->width = (sequence->picture_width + 15) & ~15; sequence->height = (sequence->picture_height + 15) & ~15; flags = sequence->flags | SEQ_FLAG_MPEG2; if (!(buffer[1] & 8)) { flags &= ~SEQ_FLAG_PROGRESSIVE_SEQUENCE; sequence->height = (sequence->height + 31) & ~31; } if (buffer[5] & 0x80) flags |= SEQ_FLAG_LOW_DELAY; sequence->flags = flags; sequence->chroma_width = sequence->width; sequence->chroma_height = sequence->height; switch (buffer[1] & 6) { case 0: /* invalid */ return 1; case 2: /* 4:2:0 */ sequence->chroma_height >>= 1; case 4: /* 4:2:2 */ sequence->chroma_width >>= 1; } sequence->byte_rate += ((buffer[2]<<25) | (buffer[3]<<17)) & 0x3ffc0000; sequence->vbv_buffer_size |= buffer[4] << 21; sequence->frame_period = sequence->frame_period * ((buffer[5]&31)+1) / (((buffer[5]>>2)&3)+1); mpeg2dec->ext_state = SEQ_DISPLAY_EXT; return 0; } static int sequence_display_ext (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence); sequence->flags = ((sequence->flags & ~SEQ_MASK_VIDEO_FORMAT) | ((buffer[0]<<4) & SEQ_MASK_VIDEO_FORMAT)); if (buffer[0] & 1) { sequence->flags |= SEQ_FLAG_COLOUR_DESCRIPTION; sequence->colour_primaries = buffer[1]; sequence->transfer_characteristics = buffer[2]; sequence->matrix_coefficients = buffer[3]; buffer += 3; } if (!(buffer[2] & 2)) /* missing marker_bit */ return 1; sequence->display_width = (buffer[1] << 6) | (buffer[2] >> 2); sequence->display_height = ((buffer[2]& 1 ) << 13) | (buffer[3] << 5) | (buffer[4] >> 3); return 0; } static inline void simplify (unsigned int * u, unsigned int * v) { unsigned int a, b, tmp; a = *u; b = *v; while (a) { /* find greatest common divisor */ tmp = a; a = b % tmp; b = tmp; } *u /= b; *v /= b; } static inline void finalize_sequence (mpeg2_sequence_t * sequence) { int width; int height; sequence->byte_rate *= 50; if (sequence->flags & SEQ_FLAG_MPEG2) { switch (sequence->pixel_width) { case 1: /* square pixels */ sequence->pixel_width = sequence->pixel_height = 1; return; case 2: /* 4:3 aspect ratio */ width = 4; height = 3; break; case 3: /* 16:9 aspect ratio */ width = 16; height = 9; break; case 4: /* 2.21:1 aspect ratio */ width = 221; height = 100; break; default: /* illegal */ sequence->pixel_width = sequence->pixel_height = 0; return; } width *= sequence->display_height; height *= sequence->display_width; } else { if (sequence->byte_rate == 50 * 0x3ffff) sequence->byte_rate = 0; /* mpeg-1 VBR */ switch (sequence->pixel_width) { case 0: case 15: /* illegal */ sequence->pixel_width = sequence->pixel_height = 0; return; case 1: /* square pixels */ sequence->pixel_width = sequence->pixel_height = 1; return; case 3: /* 720x576 16:9 */ sequence->pixel_width = 64; sequence->pixel_height = 45; return; case 6: /* 720x480 16:9 */ sequence->pixel_width = 32; sequence->pixel_height = 27; return; case 8: /* BT.601 625 lines 4:3 */ sequence->pixel_width = 59; sequence->pixel_height = 54; return; case 12: /* BT.601 525 lines 4:3 */ sequence->pixel_width = 10; sequence->pixel_height = 11; return; default: height = 88 * sequence->pixel_width + 1171; width = 2000; } } sequence->pixel_width = width; sequence->pixel_height = height; simplify (&sequence->pixel_width, &sequence->pixel_height); } int mpeg2_guess_aspect (const mpeg2_sequence_t * sequence, unsigned int * pixel_width, unsigned int * pixel_height) { static struct { unsigned int width, height; } video_modes[] = { {720, 576}, /* 625 lines, 13.5 MHz (D1, DV, DVB, DVD) */ {704, 576}, /* 625 lines, 13.5 MHz (1/1 D1, DVB, DVD, 4CIF) */ {544, 576}, /* 625 lines, 10.125 MHz (DVB, laserdisc) */ {528, 576}, /* 625 lines, 10.125 MHz (3/4 D1, DVB, laserdisc) */ {480, 576}, /* 625 lines, 9 MHz (2/3 D1, DVB, SVCD) */ {352, 576}, /* 625 lines, 6.75 MHz (D2, 1/2 D1, CVD, DVB, DVD) */ {352, 288}, /* 625 lines, 6.75 MHz, 1 field (D4, VCD, DVB, DVD, CIF) */ {176, 144}, /* 625 lines, 3.375 MHz, half field (QCIF) */ {720, 486}, /* 525 lines, 13.5 MHz (D1) */ {704, 486}, /* 525 lines, 13.5 MHz */ {720, 480}, /* 525 lines, 13.5 MHz (DV, DSS, DVD) */ {704, 480}, /* 525 lines, 13.5 MHz (1/1 D1, ATSC, DVD) */ {544, 480}, /* 525 lines. 10.125 MHz (DSS, laserdisc) */ {528, 480}, /* 525 lines. 10.125 MHz (3/4 D1, laserdisc) */ {480, 480}, /* 525 lines, 9 MHz (2/3 D1, SVCD) */ {352, 480}, /* 525 lines, 6.75 MHz (D2, 1/2 D1, CVD, DVD) */ {352, 240} /* 525 lines. 6.75 MHz, 1 field (D4, VCD, DSS, DVD) */ }; unsigned int width, height, pix_width, pix_height, i, DAR_16_9; *pixel_width = sequence->pixel_width; *pixel_height = sequence->pixel_height; width = sequence->picture_width; height = sequence->picture_height; for (i = 0; i < sizeof (video_modes) / sizeof (video_modes[0]); i++) if (width == video_modes[i].width && height == video_modes[i].height) break; if (i == sizeof (video_modes) / sizeof (video_modes[0]) || (sequence->pixel_width == 1 && sequence->pixel_height == 1) || width != sequence->display_width || height != sequence->display_height) return 0; for (pix_height = 1; height * pix_height < 480; pix_height <<= 1); height *= pix_height; for (pix_width = 1; width * pix_width <= 352; pix_width <<= 1); width *= pix_width; if (! (sequence->flags & SEQ_FLAG_MPEG2)) { static unsigned int mpeg1_check[2][2] = {{11, 54}, {27, 45}}; DAR_16_9 = (sequence->pixel_height == 27 || sequence->pixel_height == 45); if (width < 704 || sequence->pixel_height != mpeg1_check[DAR_16_9][height == 576]) return 0; } else { DAR_16_9 = (3 * sequence->picture_width * sequence->pixel_width > 4 * sequence->picture_height * sequence->pixel_height); switch (width) { case 528: case 544: pix_width *= 4; pix_height *= 3; break; case 480: pix_width *= 3; pix_height *= 2; break; } } if (DAR_16_9) { pix_width *= 4; pix_height *= 3; } if (height == 576) { pix_width *= 59; pix_height *= 54; } else { pix_width *= 10; pix_height *= 11; } *pixel_width = pix_width; *pixel_height = pix_height; simplify (pixel_width, pixel_height); return (height == 576) ? 1 : 2; } static void copy_matrix (mpeg2dec_t * mpeg2dec, int index) { if (memcmp (mpeg2dec->quantizer_matrix[index], mpeg2dec->new_quantizer_matrix[index], 64)) { memcpy (mpeg2dec->quantizer_matrix[index], mpeg2dec->new_quantizer_matrix[index], 64); mpeg2dec->scaled[index] = -1; } } static void finalize_matrix (mpeg2dec_t * mpeg2dec) { mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); int i; for (i = 0; i < 2; i++) { if (mpeg2dec->copy_matrix & (1 << i)) copy_matrix (mpeg2dec, i); if ((mpeg2dec->copy_matrix & (4 << i)) && memcmp (mpeg2dec->quantizer_matrix[i], mpeg2dec->new_quantizer_matrix[i+2], 64)) { copy_matrix (mpeg2dec, i + 2); decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i+2]; } else if (mpeg2dec->copy_matrix & (5 << i)) decoder->chroma_quantizer[i] = decoder->quantizer_prescale[i]; } } static mpeg2_state_t invalid_end_action (mpeg2dec_t * mpeg2dec) { mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.gop = NULL; info_user_data (mpeg2dec); mpeg2_header_state_init (mpeg2dec); mpeg2dec->sequence = mpeg2dec->new_sequence; mpeg2dec->action = mpeg2_seek_header; mpeg2dec->state = STATE_SEQUENCE; return STATE_SEQUENCE; } void mpeg2_header_sequence_finalize (mpeg2dec_t * mpeg2dec) { mpeg2_sequence_t * sequence = &(mpeg2dec->new_sequence); mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); finalize_sequence (sequence); finalize_matrix (mpeg2dec); decoder->mpeg1 = !(sequence->flags & SEQ_FLAG_MPEG2); decoder->width = sequence->width; decoder->height = sequence->height; decoder->vertical_position_extension = (sequence->picture_height > 2800); decoder->chroma_format = ((sequence->chroma_width == sequence->width) + (sequence->chroma_height == sequence->height)); if (mpeg2dec->sequence.width != (unsigned)-1) { /* * According to 6.1.1.6, repeat sequence headers should be * identical to the original. However some encoders dont * respect that and change various fields (including bitrate * and aspect ratio) in the repeat sequence headers. So we * choose to be as conservative as possible and only restart * the decoder if the width, height, chroma_width, * chroma_height or low_delay flag are modified. */ if (sequence->width != mpeg2dec->sequence.width || sequence->height != mpeg2dec->sequence.height || sequence->chroma_width != mpeg2dec->sequence.chroma_width || sequence->chroma_height != mpeg2dec->sequence.chroma_height || ((sequence->flags ^ mpeg2dec->sequence.flags) & SEQ_FLAG_LOW_DELAY)) { decoder->stride_frame = sequence->width; mpeg2_header_end (mpeg2dec); mpeg2dec->action = invalid_end_action; mpeg2dec->state = STATE_INVALID_END; return; } mpeg2dec->state = (memcmp (&(mpeg2dec->sequence), sequence, sizeof (mpeg2_sequence_t)) ? STATE_SEQUENCE_MODIFIED : STATE_SEQUENCE_REPEATED); } else decoder->stride_frame = sequence->width; mpeg2dec->sequence = *sequence; mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.sequence = &(mpeg2dec->sequence); mpeg2dec->info.gop = NULL; info_user_data (mpeg2dec); } int mpeg2_header_gop (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_gop_t * gop = &(mpeg2dec->new_gop); if (! (buffer[1] & 8)) return 1; gop->hours = (buffer[0] >> 2) & 31; gop->minutes = ((buffer[0] << 4) | (buffer[1] >> 4)) & 63; gop->seconds = ((buffer[1] << 3) | (buffer[2] >> 5)) & 63; gop->pictures = ((buffer[2] << 1) | (buffer[3] >> 7)) & 63; gop->flags = (buffer[0] >> 7) | ((buffer[3] >> 4) & 6); mpeg2dec->state = STATE_GOP; return 0; } void mpeg2_header_gop_finalize (mpeg2dec_t * mpeg2dec) { mpeg2dec->gop = mpeg2dec->new_gop; mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.gop = &(mpeg2dec->gop); info_user_data (mpeg2dec); } void mpeg2_set_fbuf (mpeg2dec_t * mpeg2dec, int b_type) { int i; for (i = 0; i < 3; i++) if (mpeg2dec->fbuf[1] != &mpeg2dec->fbuf_alloc[i].fbuf && mpeg2dec->fbuf[2] != &mpeg2dec->fbuf_alloc[i].fbuf) { mpeg2dec->fbuf[0] = &mpeg2dec->fbuf_alloc[i].fbuf; mpeg2dec->info.current_fbuf = mpeg2dec->fbuf[0]; if (b_type || (mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY)) { if (b_type || mpeg2dec->convert) mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[0]; mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[0]; } break; } } int mpeg2_header_picture (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_picture_t * picture = &(mpeg2dec->new_picture); mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); int type; mpeg2dec->state = ((mpeg2dec->state != STATE_SLICE_1ST) ? STATE_PICTURE : STATE_PICTURE_2ND); mpeg2dec->ext_state = PIC_CODING_EXT; picture->temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6); type = (buffer [1] >> 3) & 7; if (type == PIC_FLAG_CODING_TYPE_P || type == PIC_FLAG_CODING_TYPE_B) { /* forward_f_code and backward_f_code - used in mpeg1 only */ decoder->f_motion.f_code[1] = (buffer[3] >> 2) & 1; decoder->f_motion.f_code[0] = (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1; decoder->b_motion.f_code[1] = (buffer[4] >> 6) & 1; decoder->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1; } picture->flags = PIC_FLAG_PROGRESSIVE_FRAME | type; picture->tag = picture->tag2 = 0; if (mpeg2dec->num_tags) { if (mpeg2dec->bytes_since_tag >= mpeg2dec->chunk_ptr - buffer + 4) { mpeg2dec->num_tags = 0; picture->tag = mpeg2dec->tag_current; picture->tag2 = mpeg2dec->tag2_current; picture->flags |= PIC_FLAG_TAGS; } else if (mpeg2dec->num_tags > 1) { mpeg2dec->num_tags = 1; picture->tag = mpeg2dec->tag_previous; picture->tag2 = mpeg2dec->tag2_previous; picture->flags |= PIC_FLAG_TAGS; } } picture->nb_fields = 2; picture->display_offset[0].x = picture->display_offset[1].x = picture->display_offset[2].x = mpeg2dec->display_offset_x; picture->display_offset[0].y = picture->display_offset[1].y = picture->display_offset[2].y = mpeg2dec->display_offset_y; /* XXXXXX decode extra_information_picture as well */ mpeg2dec->q_scale_type = 0; decoder->intra_dc_precision = 7; decoder->frame_pred_frame_dct = 1; decoder->concealment_motion_vectors = 0; decoder->scan = mpeg2_scan_norm; decoder->picture_structure = FRAME_PICTURE; mpeg2dec->copy_matrix = 0; return 0; } static int picture_coding_ext (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_picture_t * picture = &(mpeg2dec->new_picture); mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); uint32_t flags; /* pre subtract 1 for use later in compute_motion_vector */ decoder->f_motion.f_code[0] = (buffer[0] & 15) - 1; decoder->f_motion.f_code[1] = (buffer[1] >> 4) - 1; decoder->b_motion.f_code[0] = (buffer[1] & 15) - 1; decoder->b_motion.f_code[1] = (buffer[2] >> 4) - 1; flags = picture->flags; decoder->intra_dc_precision = 7 - ((buffer[2] >> 2) & 3); decoder->picture_structure = buffer[2] & 3; switch (decoder->picture_structure) { case TOP_FIELD: flags |= PIC_FLAG_TOP_FIELD_FIRST; case BOTTOM_FIELD: picture->nb_fields = 1; break; case FRAME_PICTURE: if (!(mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE)) { picture->nb_fields = (buffer[3] & 2) ? 3 : 2; flags |= (buffer[3] & 128) ? PIC_FLAG_TOP_FIELD_FIRST : 0; } else picture->nb_fields = (buffer[3]&2) ? ((buffer[3]&128) ? 6 : 4) : 2; break; default: return 1; } decoder->top_field_first = buffer[3] >> 7; decoder->frame_pred_frame_dct = (buffer[3] >> 6) & 1; decoder->concealment_motion_vectors = (buffer[3] >> 5) & 1; mpeg2dec->q_scale_type = buffer[3] & 16; decoder->intra_vlc_format = (buffer[3] >> 3) & 1; decoder->scan = (buffer[3] & 4) ? mpeg2_scan_alt : mpeg2_scan_norm; if (!(buffer[4] & 0x80)) flags &= ~PIC_FLAG_PROGRESSIVE_FRAME; if (buffer[4] & 0x40) flags |= (((buffer[4]<<26) | (buffer[5]<<18) | (buffer[6]<<10)) & PIC_MASK_COMPOSITE_DISPLAY) | PIC_FLAG_COMPOSITE_DISPLAY; picture->flags = flags; mpeg2dec->ext_state = PIC_DISPLAY_EXT | COPYRIGHT_EXT | QUANT_MATRIX_EXT; return 0; } static int picture_display_ext (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; mpeg2_picture_t * picture = &(mpeg2dec->new_picture); int i, nb_pos; nb_pos = picture->nb_fields; if (mpeg2dec->sequence.flags & SEQ_FLAG_PROGRESSIVE_SEQUENCE) nb_pos >>= 1; for (i = 0; i < nb_pos; i++) { int x, y; x = ((buffer[4*i] << 24) | (buffer[4*i+1] << 16) | (buffer[4*i+2] << 8) | buffer[4*i+3]) >> (11-2*i); y = ((buffer[4*i+2] << 24) | (buffer[4*i+3] << 16) | (buffer[4*i+4] << 8) | buffer[4*i+5]) >> (10-2*i); if (! (x & y & 1)) return 1; picture->display_offset[i].x = mpeg2dec->display_offset_x = x >> 1; picture->display_offset[i].y = mpeg2dec->display_offset_y = y >> 1; } for (; i < 3; i++) { picture->display_offset[i].x = mpeg2dec->display_offset_x; picture->display_offset[i].y = mpeg2dec->display_offset_y; } return 0; } void mpeg2_header_picture_finalize (mpeg2dec_t * mpeg2dec, uint32_t accels) { mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); int old_type_b = (decoder->coding_type == B_TYPE); int low_delay = mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY; finalize_matrix (mpeg2dec); decoder->coding_type = mpeg2dec->new_picture.flags & PIC_MASK_CODING_TYPE; if (mpeg2dec->state == STATE_PICTURE) { mpeg2_picture_t * picture; mpeg2_picture_t * other; decoder->second_field = 0; picture = other = mpeg2dec->pictures; if (old_type_b ^ (mpeg2dec->picture < mpeg2dec->pictures + 2)) picture += 2; else other += 2; mpeg2dec->picture = picture; *picture = mpeg2dec->new_picture; if (!old_type_b) { mpeg2dec->fbuf[2] = mpeg2dec->fbuf[1]; mpeg2dec->fbuf[1] = mpeg2dec->fbuf[0]; } mpeg2dec->fbuf[0] = NULL; mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.current_picture = picture; mpeg2dec->info.display_picture = picture; if (decoder->coding_type != B_TYPE) { if (!low_delay) { if (mpeg2dec->first) { mpeg2dec->info.display_picture = NULL; mpeg2dec->first = 0; } else { mpeg2dec->info.display_picture = other; if (other->nb_fields == 1) mpeg2dec->info.display_picture_2nd = other + 1; mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[1]; } } if (!low_delay + !mpeg2dec->convert) mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[!low_delay + !mpeg2dec->convert]; } if (mpeg2dec->convert) { mpeg2_convert_init_t convert_init; if (!mpeg2dec->convert_start) { int y_size, uv_size; mpeg2dec->decoder.convert_id = mpeg2_malloc (mpeg2dec->convert_id_size, MPEG2_ALLOC_CONVERT_ID); mpeg2dec->convert (MPEG2_CONVERT_START, mpeg2dec->decoder.convert_id, &(mpeg2dec->sequence), mpeg2dec->convert_stride, accels, mpeg2dec->convert_arg, &convert_init); mpeg2dec->convert_start = convert_init.start; mpeg2dec->decoder.convert = convert_init.copy; y_size = decoder->stride_frame * mpeg2dec->sequence.height; uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format); mpeg2dec->yuv_buf[0][0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[0][1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[0][2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[1][0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[1][1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[1][2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); y_size = decoder->stride_frame * 32; uv_size = y_size >> (2 - mpeg2dec->decoder.chroma_format); mpeg2dec->yuv_buf[2][0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[2][1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); mpeg2dec->yuv_buf[2][2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); } if (!mpeg2dec->custom_fbuf) { while (mpeg2dec->alloc_index < 3) { mpeg2_fbuf_t * fbuf; fbuf = &mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf; fbuf->id = NULL; fbuf->buf[0] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[0], MPEG2_ALLOC_CONVERTED); fbuf->buf[1] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[1], MPEG2_ALLOC_CONVERTED); fbuf->buf[2] = (uint8_t *) mpeg2_malloc (convert_init.buf_size[2], MPEG2_ALLOC_CONVERTED); } mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE)); } } else if (!mpeg2dec->custom_fbuf) { while (mpeg2dec->alloc_index < 3) { mpeg2_fbuf_t * fbuf; int y_size, uv_size; fbuf = &(mpeg2dec->fbuf_alloc[mpeg2dec->alloc_index++].fbuf); fbuf->id = NULL; y_size = decoder->stride_frame * mpeg2dec->sequence.height; uv_size = y_size >> (2 - decoder->chroma_format); fbuf->buf[0] = (uint8_t *) mpeg2_malloc (y_size, MPEG2_ALLOC_YUV); fbuf->buf[1] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); fbuf->buf[2] = (uint8_t *) mpeg2_malloc (uv_size, MPEG2_ALLOC_YUV); } mpeg2_set_fbuf (mpeg2dec, (decoder->coding_type == B_TYPE)); } } else { decoder->second_field = 1; mpeg2dec->picture++; /* second field picture */ *(mpeg2dec->picture) = mpeg2dec->new_picture; mpeg2dec->info.current_picture_2nd = mpeg2dec->picture; if (low_delay || decoder->coding_type == B_TYPE) mpeg2dec->info.display_picture_2nd = mpeg2dec->picture; } info_user_data (mpeg2dec); } static int copyright_ext (mpeg2dec_t * mpeg2dec) { return 0; } static int quant_matrix_ext (mpeg2dec_t * mpeg2dec) { uint8_t * buffer = mpeg2dec->chunk_start; int i, j; for (i = 0; i < 4; i++) if (buffer[0] & (8 >> i)) { for (j = 0; j < 64; j++) mpeg2dec->new_quantizer_matrix[i][mpeg2_scan_norm[j]] = (buffer[j] << (i+5)) | (buffer[j+1] >> (3-i)); mpeg2dec->copy_matrix |= 1 << i; buffer += 64; } return 0; } int mpeg2_header_extension (mpeg2dec_t * mpeg2dec) { static int (* parser[]) (mpeg2dec_t *) = { 0, sequence_ext, sequence_display_ext, quant_matrix_ext, copyright_ext, 0, 0, picture_display_ext, picture_coding_ext }; int ext, ext_bit; ext = mpeg2dec->chunk_start[0] >> 4; ext_bit = 1 << ext; if (!(mpeg2dec->ext_state & ext_bit)) return 0; /* ignore illegal extensions */ mpeg2dec->ext_state &= ~ext_bit; return parser[ext] (mpeg2dec); } int mpeg2_header_user_data (mpeg2dec_t * mpeg2dec) { mpeg2dec->user_data_len += mpeg2dec->chunk_ptr - 1 - mpeg2dec->chunk_start; mpeg2dec->chunk_start = mpeg2dec->chunk_ptr - 1; return 0; } static void prescale (mpeg2dec_t * mpeg2dec, int index) { static int non_linear_scale [] = { 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 }; int i, j, k; mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); if (mpeg2dec->scaled[index] != mpeg2dec->q_scale_type) { mpeg2dec->scaled[index] = mpeg2dec->q_scale_type; for (i = 0; i < 32; i++) { k = mpeg2dec->q_scale_type ? non_linear_scale[i] : (i << 1); for (j = 0; j < 64; j++) decoder->quantizer_prescale[index][i][j] = k * mpeg2dec->quantizer_matrix[index][j]; } } } mpeg2_state_t mpeg2_header_slice_start (mpeg2dec_t * mpeg2dec) { mpeg2_decoder_t * decoder = &(mpeg2dec->decoder); mpeg2dec->info.user_data = NULL; mpeg2dec->info.user_data_len = 0; mpeg2dec->state = ((mpeg2dec->picture->nb_fields > 1 || mpeg2dec->state == STATE_PICTURE_2ND) ? STATE_SLICE : STATE_SLICE_1ST); if (mpeg2dec->decoder.coding_type != D_TYPE) { prescale (mpeg2dec, 0); if (decoder->chroma_quantizer[0] == decoder->quantizer_prescale[2]) prescale (mpeg2dec, 2); if (mpeg2dec->decoder.coding_type != I_TYPE) { prescale (mpeg2dec, 1); if (decoder->chroma_quantizer[1] == decoder->quantizer_prescale[3]) prescale (mpeg2dec, 3); } } if (!(mpeg2dec->nb_decode_slices)) mpeg2dec->picture->flags |= PIC_FLAG_SKIP; else if (mpeg2dec->convert_start) { mpeg2dec->convert_start (decoder->convert_id, mpeg2dec->fbuf[0], mpeg2dec->picture, mpeg2dec->info.gop); if (mpeg2dec->decoder.coding_type == B_TYPE) mpeg2_init_fbuf (&(mpeg2dec->decoder), mpeg2dec->yuv_buf[2], mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1], mpeg2dec->yuv_buf[mpeg2dec->yuv_index]); else { mpeg2_init_fbuf (&(mpeg2dec->decoder), mpeg2dec->yuv_buf[mpeg2dec->yuv_index ^ 1], mpeg2dec->yuv_buf[mpeg2dec->yuv_index], mpeg2dec->yuv_buf[mpeg2dec->yuv_index]); if (mpeg2dec->state == STATE_SLICE) mpeg2dec->yuv_index ^= 1; } } else { int b_type; b_type = (mpeg2dec->decoder.coding_type == B_TYPE); mpeg2_init_fbuf (&(mpeg2dec->decoder), mpeg2dec->fbuf[0]->buf, mpeg2dec->fbuf[b_type + 1]->buf, mpeg2dec->fbuf[b_type]->buf); } mpeg2dec->action = NULL; return STATE_INTERNAL_NORETURN; } static mpeg2_state_t seek_sequence (mpeg2dec_t * mpeg2dec) { mpeg2_reset_info (&(mpeg2dec->info)); mpeg2dec->info.sequence = NULL; mpeg2dec->info.gop = NULL; mpeg2_header_state_init (mpeg2dec); mpeg2dec->action = mpeg2_seek_header; return mpeg2_seek_header (mpeg2dec); } mpeg2_state_t mpeg2_header_end (mpeg2dec_t * mpeg2dec) { mpeg2_picture_t * picture; int b_type; b_type = (mpeg2dec->decoder.coding_type == B_TYPE); picture = mpeg2dec->pictures; if ((mpeg2dec->picture >= picture + 2) ^ b_type) picture = mpeg2dec->pictures + 2; mpeg2_reset_info (&(mpeg2dec->info)); if (!(mpeg2dec->sequence.flags & SEQ_FLAG_LOW_DELAY)) { mpeg2dec->info.display_picture = picture; if (picture->nb_fields == 1) mpeg2dec->info.display_picture_2nd = picture + 1; mpeg2dec->info.display_fbuf = mpeg2dec->fbuf[b_type]; if (!mpeg2dec->convert) mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type + 1]; } else if (!mpeg2dec->convert) mpeg2dec->info.discard_fbuf = mpeg2dec->fbuf[b_type]; mpeg2dec->action = seek_sequence; return STATE_END; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/����������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�015075� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/decode.c��������������������������������������������������������0000644�0001750�0001750�00000100240�14647725152�016461� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * decode.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * xine-specific version by G. Bartsch * */ #include "config.h" #include <stdio.h> #include <string.h> /* memcpy/memset, try to remove */ #include <stdlib.h> #include <inttypes.h> #include <math.h> #define LOG_MODULE "decode" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include "mpeg2.h" #include "mpeg2_internal.h" #include <xine/xineutils.h> #include "libmpeg2_accel.h" /* #define LOG_PAN_SCAN */ /* #define BUFFER_SIZE (224 * 1024) */ #define BUFFER_SIZE (1194 * 1024) /* new buffer size for mpeg2dec 0.2.1 */ static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); void mpeg2_init (mpeg2dec_t * mpeg2dec, xine_video_port_t * output) { static int do_init = 1; uint32_t mm_accel; if (do_init) { do_init = 0; mm_accel = xine_mm_accel(); mpeg2_cpu_state_init (mm_accel); mpeg2_idct_init (mm_accel); mpeg2_mc_init (mm_accel); libmpeg2_accel_scan(&mpeg2dec->accel, mpeg2_scan_norm, mpeg2_scan_alt); } if( !mpeg2dec->chunk_buffer ) mpeg2dec->chunk_buffer = xine_mallocz_aligned(BUFFER_SIZE + 4); if( !mpeg2dec->picture ) mpeg2dec->picture = xine_mallocz_aligned(sizeof(picture_t)); mpeg2dec->shift = 0xffffff00; mpeg2dec->new_sequence = 0; mpeg2dec->is_sequence_needed = 1; mpeg2dec->is_wait_for_ip_frames = 2; mpeg2dec->frames_to_drop = 0; mpeg2dec->drop_frame = 0; mpeg2dec->in_slice = 0; mpeg2dec->output = output; mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->code = 0xb4; mpeg2dec->seek_mode = 0; /* initialize AFD storage */ mpeg2dec->afd_value_seen = XINE_VIDEO_AFD_NOT_PRESENT; mpeg2dec->afd_value_reported = (XINE_VIDEO_AFD_NOT_PRESENT - 1); /* initialize substructures */ mpeg2_header_state_init (mpeg2dec->picture); if ( output->get_capabilities(output) & VO_CAP_XXMC) { printf("libmpeg2: output port has XxMC capability\n"); mpeg2dec->frame_format = XINE_IMGFMT_XXMC; } else if( output->get_capabilities(output) & VO_CAP_XVMC_MOCOMP) { printf("libmpeg2: output port has XvMC capability\n"); mpeg2dec->frame_format = XINE_IMGFMT_XVMC; } else { mpeg2dec->frame_format = XINE_IMGFMT_YV12; } } static inline void get_frame_duration (mpeg2dec_t * mpeg2dec, vo_frame_t *frame) { static const double durations[] = { 0, /* invalid */ 3753.75, /* 23.976 fps */ 3750, /* 24 fps */ 3600, /* 25 fps */ 3003, /* 29.97 fps */ 3000, /* 30 fps */ 1800, /* 50 fps */ 1501.5, /* 59.94 fps */ 1500, /* 60 fps */ }; double duration = ((unsigned) mpeg2dec->picture->frame_rate_code > 8u) ? 0 : durations[mpeg2dec->picture->frame_rate_code]; duration = duration * (mpeg2dec->picture->frame_rate_ext_n + 1.0) / (mpeg2dec->picture->frame_rate_ext_d + 1.0); /* this should be used to detect any special rff pattern */ mpeg2dec->rff_pattern = mpeg2dec->rff_pattern << 1; mpeg2dec->rff_pattern |= !!frame->repeat_first_field; if( ((mpeg2dec->rff_pattern & 0xff) == 0xaa || (mpeg2dec->rff_pattern & 0xff) == 0x55) && !mpeg2dec->picture->progressive_sequence ) { /* special case for ntsc 3:2 pulldown */ duration *= 5.0 / 4.0; } else { if( frame->repeat_first_field ) { if( !mpeg2dec->picture->progressive_sequence && frame->progressive_frame ) { /* decoder should output 3 fields, so adjust duration to count on this extra field time */ duration *= 3.0 / 2.0; } else if( mpeg2dec->picture->progressive_sequence ) { /* for progressive sequences the output should repeat the frame 1 or 2 times depending on top_field_first flag. */ duration *= (frame->top_field_first) ? 3 : 2; } } } frame->duration = (int) ceil (duration); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, frame->duration); /*printf("mpeg2dec: rff=%u\n",frame->repeat_first_field);*/ } static double get_aspect_ratio(mpeg2dec_t *mpeg2dec) { double ratio; picture_t * picture = mpeg2dec->picture; double mpeg1_pel_ratio[16] = {1.0 /* forbidden */, 1.0, 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, 1.0 /*reserved*/ }; /* TODO: For slower machines the value of this function should be computed * once and cached! */ if( !picture->mpeg1 ) { /* these hardcoded values are defined on mpeg2 standard for * aspect ratio. other values are reserved or forbidden. */ switch(picture->aspect_ratio_information) { case 2: ratio = 4.0/3.0; break; case 3: ratio = 16.0/9.0; break; case 4: ratio = 2.11/1.0; break; case 1: default: ratio = (double)picture->coded_picture_width/(double)picture->coded_picture_height; break; } } else { /* mpeg1 constants refer to pixel aspect ratio */ ratio = (double)picture->coded_picture_width/(double)picture->coded_picture_height; ratio /= mpeg1_pel_ratio[picture->aspect_ratio_information]; } return ratio; } static void remember_metainfo (mpeg2dec_t *mpeg2dec) { picture_t * picture = mpeg2dec->picture; _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, picture->display_width); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, picture->display_height); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_RATIO, ((double)10000 * get_aspect_ratio(mpeg2dec))); switch (mpeg2dec->picture->frame_rate_code) { case 1: /* 23.976 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3913); break; case 2: /* 24 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3750); break; case 3: /* 25 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3600); break; case 4: /* 29.97 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3003); break; case 5: /* 30 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3000); break; case 6: /* 50 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1800); break; case 7: /* 59.94 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1525); break; case 8: /* 60 fps */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 1509); break; default: /* printf ("invalid/unknown frame rate code : %d \n", frame->frame_rate_code); */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_FRAME_DURATION, 3000); } _x_meta_info_set_utf8(mpeg2dec->stream, XINE_META_INFO_VIDEOCODEC, "MPEG (libmpeg2)"); } static inline int parse_chunk (mpeg2dec_t * mpeg2dec, int code, uint8_t * buffer, int next_code) { picture_t * picture; int is_frame_done; double ratio; /* wait for sequence_header_code */ if (mpeg2dec->is_sequence_needed) { if (code != 0xb3) { /* printf ("libmpeg2: waiting for sequence header\n"); */ mpeg2dec->pts = 0; return 0; } } if (mpeg2dec->is_frame_needed) { /* printf ("libmpeg2: waiting for frame start\n"); */ mpeg2dec->pts = 0; if (mpeg2dec->picture->current_frame) mpeg2dec->picture->current_frame->bad_frame = 1; } mpeg2_stats (code, buffer); picture = mpeg2dec->picture; is_frame_done = mpeg2dec->in_slice && ((!code) || (code >= 0xb0)); if (is_frame_done) mpeg2dec->in_slice = 0; if (is_frame_done && picture->current_frame != NULL) { libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format, picture, code); if (((picture->picture_structure == FRAME_PICTURE) || (picture->second_field)) ) { if (mpeg2dec->drop_frame) picture->current_frame->bad_frame = 1; if (picture->picture_coding_type == B_TYPE) { if( picture->current_frame && !picture->current_frame->drawn ) { /* hack against wrong mpeg1 pts */ if (picture->mpeg1) picture->current_frame->pts = 0; get_frame_duration(mpeg2dec, picture->current_frame); mpeg2dec->frames_to_drop = picture->current_frame->draw (picture->current_frame, mpeg2dec->stream); picture->current_frame->drawn = 1; } } else if (picture->forward_reference_frame && !picture->forward_reference_frame->drawn) { get_frame_duration(mpeg2dec, picture->forward_reference_frame); mpeg2dec->frames_to_drop = picture->forward_reference_frame->draw (picture->forward_reference_frame, mpeg2dec->stream); picture->forward_reference_frame->drawn = 1; } } } switch (code) { case 0x00: /* picture_start_code */ if (mpeg2_header_picture (picture, buffer)) { fprintf (stderr, "bad picture header\n"); /* abort(); */ return 0; } mpeg2dec->is_frame_needed=0; if (!picture->second_field) { /* find out if we want to skip this frame */ mpeg2dec->drop_frame = 0; /* picture->skip_non_intra_dct = (mpeg2dec->frames_to_drop>0) ; */ switch (picture->picture_coding_type) { case B_TYPE: lprintf ("B-Frame\n"); if (mpeg2dec->frames_to_drop>1) { lprintf ("dropping b-frame because frames_to_drop==%d\n", mpeg2dec->frames_to_drop); mpeg2dec->drop_frame = 1; } else if (!picture->forward_reference_frame || picture->forward_reference_frame->bad_frame || !picture->backward_reference_frame || picture->backward_reference_frame->bad_frame) { #ifdef LOG printf ("libmpeg2: dropping b-frame because ref is bad ("); if (picture->forward_reference_frame) printf ("fw ref frame %d, bad %d;", picture->forward_reference_frame->id, picture->forward_reference_frame->bad_frame); else printf ("fw ref frame not there;"); if (picture->backward_reference_frame) printf ("bw ref frame %d, bad %d)\n", picture->backward_reference_frame->id, picture->backward_reference_frame->bad_frame); else printf ("fw ref frame not there)\n"); #endif mpeg2dec->drop_frame = 1; } else if (mpeg2dec->is_wait_for_ip_frames > 0) { lprintf("dropping b-frame because refs are invalid\n"); mpeg2dec->drop_frame = 1; } break; case P_TYPE: lprintf ("P-Frame\n"); if (mpeg2dec->frames_to_drop>2) { mpeg2dec->drop_frame = 1; lprintf ("dropping p-frame because frames_to_drop==%d\n", mpeg2dec->frames_to_drop); } else if (!picture->backward_reference_frame || picture->backward_reference_frame->bad_frame) { mpeg2dec->drop_frame = 1; #ifdef LOG if (!picture->backward_reference_frame) printf ("libmpeg2: dropping p-frame because no ref frame\n"); else printf ("libmpeg2: dropping p-frame because ref %d is bad\n", picture->backward_reference_frame->id); #endif } else if (mpeg2dec->is_wait_for_ip_frames > 1) { lprintf("dropping p-frame because ref is invalid\n"); mpeg2dec->drop_frame = 1; } else if (mpeg2dec->is_wait_for_ip_frames) mpeg2dec->is_wait_for_ip_frames--; break; case I_TYPE: lprintf ("I-Frame\n"); /* for the sake of dvd menus, never drop i-frames if (mpeg2dec->frames_to_drop>4) { mpeg2dec->drop_frame = 1; } */ if (mpeg2dec->is_wait_for_ip_frames) mpeg2dec->is_wait_for_ip_frames--; break; } } break; case 0xb2: /* user data code */ process_userdata(mpeg2dec, buffer); break; case 0xb3: /* sequence_header_code */ if (mpeg2_header_sequence (picture, buffer)) { fprintf (stderr, "bad sequence header\n"); /* abort(); */ break; } /* reset AFD value to detect absence */ mpeg2dec->afd_value_seen = XINE_VIDEO_AFD_NOT_PRESENT; /* according to ISO/IEC 13818-2, an extension start code will follow. * Otherwise the stream follows ISO/IEC 11172-2 which means MPEG1 */ picture->mpeg1 = (next_code != 0xb5); if (mpeg2dec->force_aspect) picture->aspect_ratio_information = mpeg2dec->force_aspect; if (mpeg2dec->is_sequence_needed ) { mpeg2dec->new_sequence = 1; } if (mpeg2dec->is_sequence_needed || (picture->aspect_ratio_information != picture->saved_aspect_ratio) || (picture->frame_width != picture->coded_picture_width) || (picture->frame_height != picture->coded_picture_height)) { xine_event_t event; xine_format_change_data_t data; remember_metainfo (mpeg2dec); event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = mpeg2dec->stream; event.data = &data; event.data_length = sizeof(data); data.width = picture->coded_picture_width; data.height = picture->coded_picture_height; data.aspect = picture->aspect_ratio_information; data.pan_scan = mpeg2dec->force_pan_scan; xine_event_send(mpeg2dec->stream, &event); _x_stream_info_set(mpeg2dec->stream,XINE_STREAM_INFO_VIDEO_WIDTH, picture->display_width); _x_stream_info_set(mpeg2dec->stream,XINE_STREAM_INFO_VIDEO_HEIGHT, picture->display_height); if (picture->forward_reference_frame && picture->forward_reference_frame != picture->current_frame && picture->forward_reference_frame != picture->backward_reference_frame) picture->forward_reference_frame->free (picture->forward_reference_frame); if (picture->backward_reference_frame && picture->backward_reference_frame != picture->current_frame) picture->backward_reference_frame->free (picture->backward_reference_frame); mpeg2dec->is_sequence_needed = 0; picture->forward_reference_frame = NULL; picture->backward_reference_frame = NULL; picture->frame_width = picture->coded_picture_width; picture->frame_height = picture->coded_picture_height; picture->saved_aspect_ratio = picture->aspect_ratio_information; } break; case 0xb5: /* extension_start_code */ if (mpeg2_header_extension (picture, buffer)) { fprintf (stderr, "bad extension\n"); /* abort(); */ return 0; } break; case 0xb7: /* sequence end code */ mpeg2_flush(mpeg2dec); mpeg2dec->is_sequence_needed = 1; break; case 0xb8: /* group of pictures start code */ if (mpeg2_header_group_of_pictures (picture, buffer)) { printf ("libmpeg2: bad group of pictures\n"); /* abort(); */ return 0; } break; default: if ((code >= 0xb9) && (code != 0xe4)) { printf("Not multiplexed? 0x%x\n",code); } if (code >= 0xb0) break; /* check for AFD change once per picture */ if (mpeg2dec->afd_value_reported != mpeg2dec->afd_value_seen) { /* AFD data should better be stored in current_frame to have it */ /* ready and synchronous with other data like width or height. */ /* An AFD change should then be detected when a new frame is emitted */ /* from the decoder to report the AFD change in display order and not */ /* in decoding order like it happens below for now. */ _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_AFD, mpeg2dec->afd_value_seen); lprintf ("AFD changed from %d to %d\n", mpeg2dec->afd_value_reported, mpeg2dec->afd_value_seen); mpeg2dec->afd_value_reported = mpeg2dec->afd_value_seen; } if (!(mpeg2dec->in_slice)) { mpeg2dec->in_slice = 1; if (picture->second_field) { if (picture->current_frame) picture->current_frame->field(picture->current_frame, picture->picture_structure); else mpeg2dec->drop_frame = 1; } else { int flags = picture->picture_structure; if (!picture->mpeg1) flags |= VO_INTERLACED_FLAG; if (mpeg2dec->force_pan_scan) flags |= VO_PAN_SCAN_FLAG; if (mpeg2dec->new_sequence) flags |= VO_NEW_SEQUENCE_FLAG; if ( picture->current_frame && picture->current_frame != picture->backward_reference_frame && picture->current_frame != picture->forward_reference_frame ) { picture->current_frame->free (picture->current_frame); } ratio = get_aspect_ratio(mpeg2dec); picture->current_frame = mpeg2dec->stream->video_out->get_frame (mpeg2dec->stream->video_out, picture->coded_picture_width, picture->coded_picture_height, ratio, mpeg2dec->frame_format, flags); libmpeg2_accel_new_frame( &mpeg2dec->accel, mpeg2dec->frame_format, picture, ratio, flags); if (picture->picture_coding_type != B_TYPE) { if (picture->forward_reference_frame && picture->forward_reference_frame != picture->backward_reference_frame) picture->forward_reference_frame->free (picture->forward_reference_frame); picture->forward_reference_frame = picture->backward_reference_frame; picture->backward_reference_frame = picture->current_frame; } if(mpeg2dec->new_sequence) mpeg2dec->new_sequence = libmpeg2_accel_new_sequence(&mpeg2dec->accel, mpeg2dec->frame_format, picture); picture->current_frame->bad_frame = 1; picture->current_frame->drawn = 0; picture->current_frame->pts = mpeg2dec->pts; picture->current_frame->top_field_first = picture->top_field_first; picture->current_frame->repeat_first_field = picture->repeat_first_field; picture->current_frame->progressive_frame = picture->progressive_frame; picture->current_frame->crop_right = picture->coded_picture_width - picture->display_width; picture->current_frame->crop_bottom = picture->coded_picture_height - picture->display_height; switch( picture->picture_coding_type ) { case I_TYPE: picture->current_frame->picture_coding_type = XINE_PICT_I_TYPE; break; case P_TYPE: picture->current_frame->picture_coding_type = XINE_PICT_P_TYPE; break; case B_TYPE: picture->current_frame->picture_coding_type = XINE_PICT_B_TYPE; break; case D_TYPE: picture->current_frame->picture_coding_type = XINE_PICT_D_TYPE; break; } lprintf ("decoding frame %d, type %s\n", picture->current_frame->id, picture->picture_coding_type == I_TYPE ? "I" : picture->picture_coding_type == P_TYPE ? "P" : "B"); mpeg2dec->pts = 0; /*printf("Starting to decode frame %d\n",picture->current_frame->id);*/ } } if (!mpeg2dec->drop_frame && picture->current_frame != NULL) { #ifdef DEBUG_LOG printf("slice target %08x past %08x future %08x\n",picture->current_frame,picture->forward_reference_frame,picture->backward_reference_frame); fflush(stdout); #endif libmpeg2_accel_slice(&mpeg2dec->accel, picture, code, buffer, mpeg2dec->chunk_size, mpeg2dec->chunk_buffer); if( picture->v_offset > picture->limit_y || picture->v_offset + 16 > picture->display_height ) { picture->current_frame->bad_frame = 0; } } } /* printf ("libmpeg2: parse_chunk %d completed\n", code); */ return is_frame_done; } static inline int find_start_code (mpeg2dec_t * mpeg2dec, uint8_t ** current, uint8_t * limit) { uint8_t * p; if (*current >= limit) return 0; if (mpeg2dec->shift == 0x00000100) return 1; mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; if (*current >= limit) return 0; if (mpeg2dec->shift == 0x00000100) return 1; mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; if (*current >= limit) return 0; if (mpeg2dec->shift == 0x00000100) return 1; limit--; if (*current >= limit) { mpeg2dec->shift = (mpeg2dec->shift | *(*current)++) << 8; return 0; } p = *current; while (p < limit && (p = (uint8_t *)memchr(p, 0x01, limit - p))) { if (p[-2] || p[-1]) p += 3; else { *current = ++p; return 1; } } *current = ++limit; p = limit - 3; mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; mpeg2dec->shift = (mpeg2dec->shift | *p++) << 8; return 0; } static inline uint8_t * copy_chunk (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end) { uint8_t * limit; uint8_t * data = current; int found, bite; /* sequence end code 0xb7 doesn't have any data and there might be the case * that no start code will follow this code for quite some time (e. g. in case * of a still image. * Therefore, return immediately with a chunk_size of 0. Setting code to 0xb4 * will eat up any trailing garbage next time. */ if (mpeg2dec->code == 0xb7) { mpeg2dec->code = 0xb4; mpeg2dec->chunk_size = 0; return current; } limit = current + (mpeg2dec->chunk_buffer + BUFFER_SIZE - mpeg2dec->chunk_ptr); if (limit > end) limit = end; found = find_start_code(mpeg2dec, ¤t, limit); bite = current - data; if (bite) { xine_fast_memcpy(mpeg2dec->chunk_ptr, data, bite); mpeg2dec->chunk_ptr += bite; } if (found) { mpeg2dec->code = *current++; mpeg2dec->chunk_size = mpeg2dec->chunk_ptr - mpeg2dec->chunk_buffer - 3; mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->shift = 0xffffff00; return current; } if (current == end) return NULL; /* we filled the chunk buffer without finding a start code */ mpeg2dec->code = 0xb4; /* sequence_error_code */ mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; return current; } int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end, uint64_t pts) { int ret; uint8_t code; ret = 0; if (mpeg2dec->seek_mode) { mpeg2dec->chunk_ptr = mpeg2dec->chunk_buffer; mpeg2dec->code = 0xb4; mpeg2dec->seek_mode = 0; mpeg2dec->shift = 0xffffff00; mpeg2dec->is_frame_needed = 1; } if (pts) mpeg2dec->pts = pts; while (current != end || mpeg2dec->code == 0xb7) { code = mpeg2dec->code; current = copy_chunk (mpeg2dec, current, end); if (current == NULL) break; ret += parse_chunk (mpeg2dec, code, mpeg2dec->chunk_buffer, mpeg2dec->code); } libmpeg2_accel_frame_completion(&mpeg2dec->accel, mpeg2dec->frame_format, mpeg2dec->picture, 0xff); return ret; } void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec) { picture_t *picture = mpeg2dec->picture; if( !picture ) return; mpeg2dec->in_slice = 0; mpeg2dec->pts = 0; if ( picture->current_frame ) picture->current_frame->pts = 0; if ( picture->forward_reference_frame ) picture->forward_reference_frame->pts = 0; if ( picture->backward_reference_frame ) picture->backward_reference_frame->pts = 0; libmpeg2_accel_discontinuity(&mpeg2dec->accel, mpeg2dec->frame_format, picture); } void mpeg2_reset (mpeg2dec_t * mpeg2dec) { picture_t *picture = mpeg2dec->picture; if( !picture ) return; mpeg2_discontinuity(mpeg2dec); if( !picture->mpeg1 ) { mpeg2dec->is_wait_for_ip_frames = 2; /* mark current frames as bad so they won't make to screen */ if ( picture->current_frame ) picture->current_frame->bad_frame=1; if (picture->forward_reference_frame ) picture->forward_reference_frame->bad_frame=1; if (picture->backward_reference_frame) picture->backward_reference_frame->bad_frame=1; } else { /* to free reference frames one also needs to fix slice.c to * abort when they are NULL. unfortunately it seems to break * DVD menus. * * ...so let's do this for mpeg-1 only :) */ if ( picture->current_frame && picture->current_frame != picture->backward_reference_frame && picture->current_frame != picture->forward_reference_frame ) picture->current_frame->free (picture->current_frame); picture->current_frame = NULL; if (picture->forward_reference_frame && picture->forward_reference_frame != picture->backward_reference_frame) picture->forward_reference_frame->free (picture->forward_reference_frame); picture->forward_reference_frame = NULL; if (picture->backward_reference_frame) picture->backward_reference_frame->free (picture->backward_reference_frame); picture->backward_reference_frame = NULL; } mpeg2dec->in_slice = 0; mpeg2dec->seek_mode = 1; } void mpeg2_flush (mpeg2dec_t * mpeg2dec) { picture_t *picture = mpeg2dec->picture; if (!picture) return; if (picture->current_frame && !picture->current_frame->drawn && !picture->current_frame->bad_frame) { lprintf ("blasting out current frame %d on flush\n", picture->current_frame->id); picture->current_frame->drawn = 1; get_frame_duration(mpeg2dec, picture->current_frame); picture->current_frame->pts = 0; picture->current_frame->draw(picture->current_frame, mpeg2dec->stream); } } void mpeg2_close (mpeg2dec_t * mpeg2dec) { picture_t *picture = mpeg2dec->picture; /* { static uint8_t finalizer[] = {0,0,1,0xb4}; mpeg2_decode_data (mpeg2dec, finalizer, finalizer+4, 0); } */ /* dont remove any picture->*->free() below. doing so will cause buffer leak, and we only have about 15 of them. */ if ( picture->current_frame ) { if( !picture->current_frame->drawn ) { lprintf ("blasting out current frame on close\n"); picture->current_frame->pts = 0; get_frame_duration(mpeg2dec, picture->current_frame); picture->current_frame->draw (picture->current_frame, mpeg2dec->stream); picture->current_frame->drawn = 1; } if( picture->current_frame != picture->backward_reference_frame && picture->current_frame != picture->forward_reference_frame ) { picture->current_frame->free (picture->current_frame); } picture->current_frame = NULL; } if (picture->forward_reference_frame && picture->forward_reference_frame != picture->backward_reference_frame) { picture->forward_reference_frame->free (picture->forward_reference_frame); picture->forward_reference_frame = NULL; } if (picture->backward_reference_frame) { if( !picture->backward_reference_frame->drawn) { lprintf ("blasting out backward reference frame on close\n"); picture->backward_reference_frame->pts = 0; get_frame_duration(mpeg2dec, picture->backward_reference_frame); picture->backward_reference_frame->draw (picture->backward_reference_frame, mpeg2dec->stream); picture->backward_reference_frame->drawn = 1; } picture->backward_reference_frame->free (picture->backward_reference_frame); picture->backward_reference_frame = NULL; } xine_freep_aligned(&mpeg2dec->chunk_buffer); xine_freep_aligned(&mpeg2dec->picture); if ( mpeg2dec->cc_dec) { /* dispose the closed caption decoder */ mpeg2dec->cc_dec->dispose(mpeg2dec->cc_dec); mpeg2dec->cc_dec = NULL; } } void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec, uint8_t * current, uint8_t * end){ uint8_t code, next_code; picture_t *picture = mpeg2dec->picture; mpeg2dec->seek_mode = 1; while (current < end) { code = mpeg2dec->code; current = copy_chunk (mpeg2dec, current, end); if (current == NULL) return ; next_code = mpeg2dec->code; /* printf ("looking for sequence header... %02x\n", code); */ mpeg2_stats (code, mpeg2dec->chunk_buffer); if (code == 0xb3) { /* sequence_header_code */ if (mpeg2_header_sequence (picture, mpeg2dec->chunk_buffer)) { printf ("libmpeg2: bad sequence header\n"); continue; } /* according to ISO/IEC 13818-2, an extension start code will follow. * Otherwise the stream follows ISO/IEC 11172-2 which means MPEG1 */ picture->mpeg1 = (next_code != 0xb5); if (mpeg2dec->force_aspect) picture->aspect_ratio_information = mpeg2dec->force_aspect; if (mpeg2dec->is_sequence_needed) { xine_event_t event; xine_format_change_data_t data; mpeg2dec->new_sequence = 1; mpeg2dec->is_sequence_needed = 0; picture->frame_width = picture->coded_picture_width; picture->frame_height = picture->coded_picture_height; remember_metainfo (mpeg2dec); event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = mpeg2dec->stream; event.data = &data; event.data_length = sizeof(data); data.width = picture->coded_picture_width; data.height = picture->coded_picture_height; data.aspect = picture->aspect_ratio_information; data.pan_scan = mpeg2dec->force_pan_scan; xine_event_send(mpeg2dec->stream, &event); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, picture->display_width); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, picture->display_height); } } else if (code == 0xb5) { /* extension_start_code */ if (mpeg2_header_extension (picture, mpeg2dec->chunk_buffer)) { printf ("libmpeg2: bad extension\n"); continue ; } } } } /* Find the end of the userdata field in an MPEG-2 stream */ static uint8_t *find_end(uint8_t *buffer) { uint8_t *current = buffer; while(1) { if (current[0] == 0 && current[1] == 0 && current[2] == 1) break; current++; } return current; } static void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer) { /* check if user data denotes closed captions */ if (buffer[0] == 'C' && buffer[1] == 'C') { if (!mpeg2dec->cc_dec) { xine_event_t event; xine_format_change_data_t data; /* open the closed caption decoder first */ mpeg2dec->cc_dec = _x_get_spu_decoder(mpeg2dec->stream, (BUF_SPU_CC >> 16) & 0xff); /* send a frame format event so that the CC decoder knows the initial image size */ event.type = XINE_EVENT_FRAME_FORMAT_CHANGE; event.stream = mpeg2dec->stream; event.data = &data; event.data_length = sizeof(data); data.width = mpeg2dec->picture->coded_picture_width; data.height = mpeg2dec->picture->coded_picture_height; data.aspect = mpeg2dec->picture->aspect_ratio_information; data.pan_scan = mpeg2dec->force_pan_scan; xine_event_send(mpeg2dec->stream, &event); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_WIDTH, mpeg2dec->picture->display_width); _x_stream_info_set(mpeg2dec->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, mpeg2dec->picture->display_height); } if (mpeg2dec->cc_dec) { buf_element_t buf; buf.type = BUF_SPU_CC; buf.content = &buffer[2]; buf.pts = mpeg2dec->pts; buf.size = find_end(buffer) - &buffer[2]; buf.decoder_flags = 0; mpeg2dec->cc_dec->decode_data(mpeg2dec->cc_dec, &buf); } } /* check Active Format Description ETSI TS 101 154 V1.5.1 */ else if (buffer[0] == 0x44 && buffer[1] == 0x54 && buffer[2] == 0x47 && buffer[3] == 0x31) mpeg2dec->afd_value_seen = (buffer[4] & 0x40) ? (buffer[5] & 0x0f) : XINE_VIDEO_AFD_NOT_PRESENT; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/motion_comp_mlib.c����������������������������������������������0000644�0001750�0001750�00000011744�14647725152�020576� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_mlib.c * Copyright (C) 2000-2002 Håkan Hjort <d95hjort@dtek.chalmers.se> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #ifdef LIBMPEG2_MLIB #include <mlib_types.h> #include <mlib_status.h> #include <mlib_sys.h> #include <mlib_video.h> #include <inttypes.h> #include "mpeg2_internal.h" static void MC_put_o_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoCopyRef_U8_U8_16x16 (dest, ref, stride); else mlib_VideoCopyRef_U8_U8_16x8 (dest, ref, stride); } static void MC_put_x_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpX_U8_U8_16x16 (dest, ref, stride, stride); else mlib_VideoInterpX_U8_U8_16x8 (dest, ref, stride, stride); } static void MC_put_y_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpY_U8_U8_16x16 (dest, ref, stride, stride); else mlib_VideoInterpY_U8_U8_16x8 (dest, ref, stride, stride); } static void MC_put_xy_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpXY_U8_U8_16x16 (dest, ref, stride, stride); else mlib_VideoInterpXY_U8_U8_16x8 (dest, ref, stride, stride); } static void MC_put_o_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoCopyRef_U8_U8_8x8 (dest, ref, stride); else mlib_VideoCopyRef_U8_U8_8x4 (dest, ref, stride); } static void MC_put_x_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpX_U8_U8_8x8 (dest, ref, stride, stride); else mlib_VideoInterpX_U8_U8_8x4 (dest, ref, stride, stride); } static void MC_put_y_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpY_U8_U8_8x8 (dest, ref, stride, stride); else mlib_VideoInterpY_U8_U8_8x4 (dest, ref, stride, stride); } static void MC_put_xy_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpXY_U8_U8_8x8 (dest, ref, stride, stride); else mlib_VideoInterpXY_U8_U8_8x4 (dest, ref, stride, stride); } static void MC_avg_o_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoCopyRefAve_U8_U8_16x16 (dest, ref, stride); else mlib_VideoCopyRefAve_U8_U8_16x8 (dest, ref, stride); } static void MC_avg_x_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpAveX_U8_U8_16x16 (dest, ref, stride, stride); else mlib_VideoInterpAveX_U8_U8_16x8 (dest, ref, stride, stride); } static void MC_avg_y_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpAveY_U8_U8_16x16 (dest, ref, stride, stride); else mlib_VideoInterpAveY_U8_U8_16x8 (dest, ref, stride, stride); } static void MC_avg_xy_16_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 16) mlib_VideoInterpAveXY_U8_U8_16x16 (dest, ref, stride, stride); else mlib_VideoInterpAveXY_U8_U8_16x8 (dest, ref, stride, stride); } static void MC_avg_o_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoCopyRefAve_U8_U8_8x8 (dest, ref, stride); else mlib_VideoCopyRefAve_U8_U8_8x4 (dest, ref, stride); } static void MC_avg_x_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpAveX_U8_U8_8x8 (dest, ref, stride, stride); else mlib_VideoInterpAveX_U8_U8_8x4 (dest, ref, stride, stride); } static void MC_avg_y_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpAveY_U8_U8_8x8 (dest, ref, stride, stride); else mlib_VideoInterpAveY_U8_U8_8x4 (dest, ref, stride, stride); } static void MC_avg_xy_8_mlib (uint8_t * dest, uint8_t * ref, int stride, int height) { if (height == 8) mlib_VideoInterpAveXY_U8_U8_8x8 (dest, ref, stride, stride); else mlib_VideoInterpAveXY_U8_U8_8x4 (dest, ref, stride, stride); } MPEG2_MC_EXTERN (mlib) #endif ����������������������������xine-lib-1.2/src/video_dec/libmpeg2/idct_mmx.c������������������������������������������������������0000644�0001750�0001750�00000053334�14647725152�017055� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_mmx.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #if defined(ARCH_X86) || defined(ARCH_X86_64) #include <inttypes.h> #include "mpeg2_internal.h" #include <xine/xineutils.h> #include "xine_mmx.h" #define ROW_SHIFT 11 #define COL_SHIFT 6 #define round(bias) ((int)(((bias)+0.5) * (1<<ROW_SHIFT))) #define rounder(bias) {round (bias), round (bias)} #if 0 /* C row IDCT - its just here to document the MMXEXT and MMX versions */ static inline void idct_row (int16_t * row, int offset, int16_t * table, int32_t * rounder) { int C1, C2, C3, C4, C5, C6, C7; int a0, a1, a2, a3, b0, b1, b2, b3; row += offset; C1 = table[1]; C2 = table[2]; C3 = table[3]; C4 = table[4]; C5 = table[5]; C6 = table[6]; C7 = table[7]; a0 = C4*row[0] + C2*row[2] + C4*row[4] + C6*row[6] + *rounder; a1 = C4*row[0] + C6*row[2] - C4*row[4] - C2*row[6] + *rounder; a2 = C4*row[0] - C6*row[2] - C4*row[4] + C2*row[6] + *rounder; a3 = C4*row[0] - C2*row[2] + C4*row[4] - C6*row[6] + *rounder; b0 = C1*row[1] + C3*row[3] + C5*row[5] + C7*row[7]; b1 = C3*row[1] - C7*row[3] - C1*row[5] - C5*row[7]; b2 = C5*row[1] - C1*row[3] + C7*row[5] + C3*row[7]; b3 = C7*row[1] - C5*row[3] + C3*row[5] - C1*row[7]; row[0] = (a0 + b0) >> ROW_SHIFT; row[1] = (a1 + b1) >> ROW_SHIFT; row[2] = (a2 + b2) >> ROW_SHIFT; row[3] = (a3 + b3) >> ROW_SHIFT; row[4] = (a3 - b3) >> ROW_SHIFT; row[5] = (a2 - b2) >> ROW_SHIFT; row[6] = (a1 - b1) >> ROW_SHIFT; row[7] = (a0 - b0) >> ROW_SHIFT; } #endif /* MMXEXT row IDCT */ #define mmxext_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, -c4, -c2, \ c4, c6, c4, c6, \ c1, c3, -c1, -c5, \ c5, c7, c3, -c7, \ c4, -c6, c4, -c6, \ -c4, c2, c4, -c2, \ c5, -c1, c3, -c1, \ c7, c3, c7, -c5 } static inline void mmxext_row_head (int16_t * row, int offset, int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 } static inline void mmxext_row (int16_t * table, int32_t * rounder) { movq_m2r (*(table+8), mm1); // mm1 = -C5 -C1 C3 C1 pmaddwd_r2r (mm2, mm4); // mm4 = C4*x0+C6*x2 C4*x4+C6*x6 pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x4-C6*x6 C4*x0-C6*x2 pshufw_r2r (mm6, mm6, 0x4e); // mm6 = x3 x1 x7 x5 movq_m2r (*(table+12), mm7); // mm7 = -C7 C3 C7 C5 pmaddwd_r2r (mm5, mm1); // mm1 = -C1*x5-C5*x7 C1*x1+C3*x3 paddd_m2r (*rounder, mm3); // mm3 += rounder pmaddwd_r2r (mm6, mm7); // mm7 = C3*x1-C7*x3 C5*x5+C7*x7 pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x0-C2*x2 -C4*x4+C2*x6 paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder pmaddwd_m2r (*(table+24), mm5); // mm5 = C3*x5-C1*x7 C5*x1-C1*x3 movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder pmaddwd_m2r (*(table+28), mm6); // mm6 = C7*x1-C5*x3 C7*x5+C3*x7 paddd_r2r (mm7, mm1); // mm1 = b1 b0 paddd_m2r (*rounder, mm0); // mm0 += rounder psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 paddd_r2r (mm6, mm5); // mm5 = b3 b2 movq_r2r (mm0, mm4); // mm4 = a3 a2 + rounder paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder psubd_r2r (mm5, mm4); // mm4 = a3-b3 a2-b2 + rounder } static inline void mmxext_row_tail (int16_t * row, int store) { psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 /* slot */ movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 } static inline void mmxext_row_mid (int16_t * row, int store, int offset, int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 psrad_i2r (ROW_SHIFT, mm4); // mm4 = y4 y5 packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 packssdw_r2r (mm3, mm4); // mm4 = y6 y7 y4 y5 movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 pshufw_r2r (mm4, mm4, 0xb1); // mm4 = y7 y6 y5 y4 movq_m2r (*table, mm3); // mm3 = -C2 -C4 C2 C4 movq_r2m (mm4, *(row+store+4)); // save y7 y6 y5 y4 pmaddwd_r2r (mm0, mm3); // mm3 = -C4*x4-C2*x6 C4*x0+C2*x2 movq_m2r (*(table+4), mm4); // mm4 = C6 C4 C6 C4 pshufw_r2r (mm2, mm2, 0x4e); // mm2 = x2 x0 x6 x4 } /* MMX row IDCT */ #define mmx_table(c1,c2,c3,c4,c5,c6,c7) { c4, c2, c4, c6, \ c4, c6, -c4, -c2, \ c1, c3, c3, -c7, \ c5, c7, -c1, -c5, \ c4, -c6, c4, -c2, \ -c4, c2, c4, -c6, \ c5, -c1, c7, -c5, \ c7, c3, c3, -c1 } static inline void mmx_row_head (int16_t * row, int offset, int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 } static inline void mmx_row (int16_t * table, int32_t * rounder) { pmaddwd_r2r (mm2, mm4); // mm4 = -C4*x4-C2*x6 C4*x4+C6*x6 punpckldq_r2r (mm5, mm5); // mm5 = x3 x1 x3 x1 pmaddwd_m2r (*(table+16), mm0); // mm0 = C4*x0-C2*x2 C4*x0-C6*x2 punpckhdq_r2r (mm6, mm6); // mm6 = x7 x5 x7 x5 movq_m2r (*(table+12), mm7); // mm7 = -C5 -C1 C7 C5 pmaddwd_r2r (mm5, mm1); // mm1 = C3*x1-C7*x3 C1*x1+C3*x3 paddd_m2r (*rounder, mm3); // mm3 += rounder pmaddwd_r2r (mm6, mm7); // mm7 = -C1*x5-C5*x7 C5*x5+C7*x7 pmaddwd_m2r (*(table+20), mm2); // mm2 = C4*x4-C6*x6 -C4*x4+C2*x6 paddd_r2r (mm4, mm3); // mm3 = a1 a0 + rounder pmaddwd_m2r (*(table+24), mm5); // mm5 = C7*x1-C5*x3 C5*x1-C1*x3 movq_r2r (mm3, mm4); // mm4 = a1 a0 + rounder pmaddwd_m2r (*(table+28), mm6); // mm6 = C3*x5-C1*x7 C7*x5+C3*x7 paddd_r2r (mm7, mm1); // mm1 = b1 b0 paddd_m2r (*rounder, mm0); // mm0 += rounder psubd_r2r (mm1, mm3); // mm3 = a1-b1 a0-b0 + rounder psrad_i2r (ROW_SHIFT, mm3); // mm3 = y6 y7 paddd_r2r (mm4, mm1); // mm1 = a1+b1 a0+b0 + rounder paddd_r2r (mm2, mm0); // mm0 = a3 a2 + rounder psrad_i2r (ROW_SHIFT, mm1); // mm1 = y1 y0 paddd_r2r (mm6, mm5); // mm5 = b3 b2 movq_r2r (mm0, mm7); // mm7 = a3 a2 + rounder paddd_r2r (mm5, mm0); // mm0 = a3+b3 a2+b2 + rounder psubd_r2r (mm5, mm7); // mm7 = a3-b3 a2-b2 + rounder } static inline void mmx_row_tail (int16_t * row, int store) { psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 movq_r2r (mm7, mm4); // mm4 = y6 y7 y4 y5 pslld_i2r (16, mm7); // mm7 = y7 0 y5 0 psrld_i2r (16, mm4); // mm4 = 0 y6 0 y4 por_r2r (mm4, mm7); // mm7 = y7 y6 y5 y4 /* slot */ movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 } static inline void mmx_row_mid (int16_t * row, int store, int offset, int16_t * table) { movq_m2r (*(row+offset), mm2); // mm2 = x6 x4 x2 x0 psrad_i2r (ROW_SHIFT, mm0); // mm0 = y3 y2 movq_m2r (*(row+offset+4), mm5); // mm5 = x7 x5 x3 x1 psrad_i2r (ROW_SHIFT, mm7); // mm7 = y4 y5 packssdw_r2r (mm0, mm1); // mm1 = y3 y2 y1 y0 movq_r2r (mm5, mm6); // mm6 = x7 x5 x3 x1 packssdw_r2r (mm3, mm7); // mm7 = y6 y7 y4 y5 movq_r2r (mm2, mm0); // mm0 = x6 x4 x2 x0 movq_r2m (mm1, *(row+store)); // save y3 y2 y1 y0 movq_r2r (mm7, mm1); // mm1 = y6 y7 y4 y5 punpckldq_r2r (mm0, mm0); // mm0 = x2 x0 x2 x0 psrld_i2r (16, mm7); // mm7 = 0 y6 0 y4 movq_m2r (*table, mm3); // mm3 = C6 C4 C2 C4 pslld_i2r (16, mm1); // mm1 = y7 0 y5 0 movq_m2r (*(table+4), mm4); // mm4 = -C2 -C4 C6 C4 por_r2r (mm1, mm7); // mm7 = y7 y6 y5 y4 movq_m2r (*(table+8), mm1); // mm1 = -C7 C3 C3 C1 punpckhdq_r2r (mm2, mm2); // mm2 = x6 x4 x6 x4 movq_r2m (mm7, *(row+store+4)); // save y7 y6 y5 y4 pmaddwd_r2r (mm0, mm3); // mm3 = C4*x0+C6*x2 C4*x0+C2*x2 } #if 0 // C column IDCT - its just here to document the MMXEXT and MMX versions static inline void idct_col (int16_t * col, int offset) { /* multiplication - as implemented on mmx */ #define F(c,x) (((c) * (x)) >> 16) /* saturation - it helps us handle torture test cases */ #define S(x) (((x)>32767) ? 32767 : ((x)<-32768) ? -32768 : (x)) int16_t x0, x1, x2, x3, x4, x5, x6, x7; int16_t y0, y1, y2, y3, y4, y5, y6, y7; int16_t a0, a1, a2, a3, b0, b1, b2, b3; int16_t u04, v04, u26, v26, u17, v17, u35, v35, u12, v12; col += offset; x0 = col[0*8]; x1 = col[1*8]; x2 = col[2*8]; x3 = col[3*8]; x4 = col[4*8]; x5 = col[5*8]; x6 = col[6*8]; x7 = col[7*8]; u04 = S (x0 + x4); v04 = S (x0 - x4); u26 = S (F (T2, x6) + x2); v26 = S (F (T2, x2) - x6); a0 = S (u04 + u26); a1 = S (v04 + v26); a2 = S (v04 - v26); a3 = S (u04 - u26); u17 = S (F (T1, x7) + x1); v17 = S (F (T1, x1) - x7); u35 = S (F (T3, x5) + x3); v35 = S (F (T3, x3) - x5); b0 = S (u17 + u35); b3 = S (v17 - v35); u12 = S (u17 - u35); v12 = S (v17 + v35); u12 = S (2 * F (C4, u12)); v12 = S (2 * F (C4, v12)); b1 = S (u12 + v12); b2 = S (u12 - v12); y0 = S (a0 + b0) >> COL_SHIFT; y1 = S (a1 + b1) >> COL_SHIFT; y2 = S (a2 + b2) >> COL_SHIFT; y3 = S (a3 + b3) >> COL_SHIFT; y4 = S (a3 - b3) >> COL_SHIFT; y5 = S (a2 - b2) >> COL_SHIFT; y6 = S (a1 - b1) >> COL_SHIFT; y7 = S (a0 - b0) >> COL_SHIFT; col[0*8] = y0; col[1*8] = y1; col[2*8] = y2; col[3*8] = y3; col[4*8] = y4; col[5*8] = y5; col[6*8] = y6; col[7*8] = y7; } #endif // MMX column IDCT static inline void idct_col (int16_t * col, int offset) { #define T1 13036 #define T2 27146 #define T3 43790 #define C4 23170 static short _T1[] ATTR_ALIGN(8) = {T1,T1,T1,T1}; static short _T2[] ATTR_ALIGN(8) = {T2,T2,T2,T2}; static short _T3[] ATTR_ALIGN(8) = {T3,T3,T3,T3}; static short _C4[] ATTR_ALIGN(8) = {C4,C4,C4,C4}; /* column code adapted from peter gubanov */ /* http://www.elecard.com/peter/idct.shtml */ movq_m2r (*_T1, mm0); // mm0 = T1 movq_m2r (*(col+offset+1*8), mm1); // mm1 = x1 movq_r2r (mm0, mm2); // mm2 = T1 movq_m2r (*(col+offset+7*8), mm4); // mm4 = x7 pmulhw_r2r (mm1, mm0); // mm0 = T1*x1 movq_m2r (*_T3, mm5); // mm5 = T3 pmulhw_r2r (mm4, mm2); // mm2 = T1*x7 movq_m2r (*(col+offset+5*8), mm6); // mm6 = x5 movq_r2r (mm5, mm7); // mm7 = T3-1 movq_m2r (*(col+offset+3*8), mm3); // mm3 = x3 psubsw_r2r (mm4, mm0); // mm0 = v17 movq_m2r (*_T2, mm4); // mm4 = T2 pmulhw_r2r (mm3, mm5); // mm5 = (T3-1)*x3 paddsw_r2r (mm2, mm1); // mm1 = u17 pmulhw_r2r (mm6, mm7); // mm7 = (T3-1)*x5 /* slot */ movq_r2r (mm4, mm2); // mm2 = T2 paddsw_r2r (mm3, mm5); // mm5 = T3*x3 pmulhw_m2r (*(col+offset+2*8), mm4);// mm4 = T2*x2 paddsw_r2r (mm6, mm7); // mm7 = T3*x5 psubsw_r2r (mm6, mm5); // mm5 = v35 paddsw_r2r (mm3, mm7); // mm7 = u35 movq_m2r (*(col+offset+6*8), mm3); // mm3 = x6 movq_r2r (mm0, mm6); // mm6 = v17 pmulhw_r2r (mm3, mm2); // mm2 = T2*x6 psubsw_r2r (mm5, mm0); // mm0 = b3 psubsw_r2r (mm3, mm4); // mm4 = v26 paddsw_r2r (mm6, mm5); // mm5 = v12 movq_r2m (mm0, *(col+offset+3*8)); // save b3 in scratch0 movq_r2r (mm1, mm6); // mm6 = u17 paddsw_m2r (*(col+offset+2*8), mm2);// mm2 = u26 paddsw_r2r (mm7, mm6); // mm6 = b0 psubsw_r2r (mm7, mm1); // mm1 = u12 movq_r2r (mm1, mm7); // mm7 = u12 movq_m2r (*(col+offset+0*8), mm3); // mm3 = x0 paddsw_r2r (mm5, mm1); // mm1 = u12+v12 movq_m2r (*_C4, mm0); // mm0 = C4/2 psubsw_r2r (mm5, mm7); // mm7 = u12-v12 movq_r2m (mm6, *(col+offset+5*8)); // save b0 in scratch1 pmulhw_r2r (mm0, mm1); // mm1 = b1/2 movq_r2r (mm4, mm6); // mm6 = v26 pmulhw_r2r (mm0, mm7); // mm7 = b2/2 movq_m2r (*(col+offset+4*8), mm5); // mm5 = x4 movq_r2r (mm3, mm0); // mm0 = x0 psubsw_r2r (mm5, mm3); // mm3 = v04 paddsw_r2r (mm5, mm0); // mm0 = u04 paddsw_r2r (mm3, mm4); // mm4 = a1 movq_r2r (mm0, mm5); // mm5 = u04 psubsw_r2r (mm6, mm3); // mm3 = a2 paddsw_r2r (mm2, mm5); // mm5 = a0 paddsw_r2r (mm1, mm1); // mm1 = b1 psubsw_r2r (mm2, mm0); // mm0 = a3 paddsw_r2r (mm7, mm7); // mm7 = b2 movq_r2r (mm3, mm2); // mm2 = a2 movq_r2r (mm4, mm6); // mm6 = a1 paddsw_r2r (mm7, mm3); // mm3 = a2+b2 psraw_i2r (COL_SHIFT, mm3); // mm3 = y2 paddsw_r2r (mm1, mm4); // mm4 = a1+b1 psraw_i2r (COL_SHIFT, mm4); // mm4 = y1 psubsw_r2r (mm1, mm6); // mm6 = a1-b1 movq_m2r (*(col+offset+5*8), mm1); // mm1 = b0 psubsw_r2r (mm7, mm2); // mm2 = a2-b2 psraw_i2r (COL_SHIFT, mm6); // mm6 = y6 movq_r2r (mm5, mm7); // mm7 = a0 movq_r2m (mm4, *(col+offset+1*8)); // save y1 psraw_i2r (COL_SHIFT, mm2); // mm2 = y5 movq_r2m (mm3, *(col+offset+2*8)); // save y2 paddsw_r2r (mm1, mm5); // mm5 = a0+b0 movq_m2r (*(col+offset+3*8), mm4); // mm4 = b3 psubsw_r2r (mm1, mm7); // mm7 = a0-b0 psraw_i2r (COL_SHIFT, mm5); // mm5 = y0 movq_r2r (mm0, mm3); // mm3 = a3 movq_r2m (mm2, *(col+offset+5*8)); // save y5 psubsw_r2r (mm4, mm3); // mm3 = a3-b3 psraw_i2r (COL_SHIFT, mm7); // mm7 = y7 paddsw_r2r (mm0, mm4); // mm4 = a3+b3 movq_r2m (mm5, *(col+offset+0*8)); // save y0 psraw_i2r (COL_SHIFT, mm3); // mm3 = y4 movq_r2m (mm6, *(col+offset+6*8)); // save y6 psraw_i2r (COL_SHIFT, mm4); // mm4 = y3 movq_r2m (mm7, *(col+offset+7*8)); // save y7 movq_r2m (mm3, *(col+offset+4*8)); // save y4 movq_r2m (mm4, *(col+offset+3*8)); // save y3 } static int32_t rounder0[] ATTR_ALIGN(8) = rounder ((1 << (COL_SHIFT - 1)) - 0.5); static int32_t rounder4[] ATTR_ALIGN(8) = rounder (0); static int32_t rounder1[] ATTR_ALIGN(8) = rounder (1.25683487303); /* C1*(C1/C4+C1+C7)/2 */ static int32_t rounder7[] ATTR_ALIGN(8) = rounder (-0.25); /* C1*(C7/C4+C7-C1)/2 */ static int32_t rounder2[] ATTR_ALIGN(8) = rounder (0.60355339059); /* C2 * (C6+C2)/2 */ static int32_t rounder6[] ATTR_ALIGN(8) = rounder (-0.25); /* C2 * (C6-C2)/2 */ static int32_t rounder3[] ATTR_ALIGN(8) = rounder (0.087788325588); /* C3*(-C3/C4+C3+C5)/2 */ static int32_t rounder5[] ATTR_ALIGN(8) = rounder (-0.441341716183); /* C3*(-C5/C4+C5-C3)/2 */ #define declare_idct(idct,table,idct_row_head,idct_row,idct_row_tail,idct_row_mid) \ static inline void idct (int16_t * block) \ { \ static int16_t table04[] ATTR_ALIGN(16) = \ table (22725, 21407, 19266, 16384, 12873, 8867, 4520); \ static int16_t table17[] ATTR_ALIGN(16) = \ table (31521, 29692, 26722, 22725, 17855, 12299, 6270); \ static int16_t table26[] ATTR_ALIGN(16) = \ table (29692, 27969, 25172, 21407, 16819, 11585, 5906); \ static int16_t table35[] ATTR_ALIGN(16) = \ table (26722, 25172, 22654, 19266, 15137, 10426, 5315); \ \ idct_row_head (block, 0*8, table04); \ idct_row (table04, rounder0); \ idct_row_mid (block, 0*8, 4*8, table04); \ idct_row (table04, rounder4); \ idct_row_mid (block, 4*8, 1*8, table17); \ idct_row (table17, rounder1); \ idct_row_mid (block, 1*8, 7*8, table17); \ idct_row (table17, rounder7); \ idct_row_mid (block, 7*8, 2*8, table26); \ idct_row (table26, rounder2); \ idct_row_mid (block, 2*8, 6*8, table26); \ idct_row (table26, rounder6); \ idct_row_mid (block, 6*8, 3*8, table35); \ idct_row (table35, rounder3); \ idct_row_mid (block, 3*8, 5*8, table35); \ idct_row (table35, rounder5); \ idct_row_tail (block, 5*8); \ \ idct_col (block, 0); \ idct_col (block, 4); \ } #define COPY_MMX(offset,r0,r1,r2) \ do { \ movq_m2r (*(block+offset), r0); \ dest += stride; \ movq_m2r (*(block+offset+4), r1); \ movq_r2m (r2, *dest); \ packuswb_r2r (r1, r0); \ } while (0) static void block_copy (int16_t * block, uint8_t * dest, int stride) { movq_m2r (*(block+0*8), mm0); movq_m2r (*(block+0*8+4), mm1); movq_m2r (*(block+1*8), mm2); packuswb_r2r (mm1, mm0); movq_m2r (*(block+1*8+4), mm3); movq_r2m (mm0, *dest); packuswb_r2r (mm3, mm2); COPY_MMX (2*8, mm0, mm1, mm2); COPY_MMX (3*8, mm2, mm3, mm0); COPY_MMX (4*8, mm0, mm1, mm2); COPY_MMX (5*8, mm2, mm3, mm0); COPY_MMX (6*8, mm0, mm1, mm2); COPY_MMX (7*8, mm2, mm3, mm0); movq_r2m (mm2, *(dest+stride)); } #define ADD_MMX(offset,r1,r2,r3,r4) \ do { \ movq_m2r (*(dest+2*stride), r1); \ packuswb_r2r (r4, r3); \ movq_r2r (r1, r2); \ dest += stride; \ movq_r2m (r3, *dest); \ punpcklbw_r2r (mm0, r1); \ paddsw_m2r (*(block+offset), r1); \ punpckhbw_r2r (mm0, r2); \ paddsw_m2r (*(block+offset+4), r2); \ } while (0) static void block_add (int16_t * block, uint8_t * dest, int stride) { movq_m2r (*dest, mm1); pxor_r2r (mm0, mm0); movq_m2r (*(dest+stride), mm3); movq_r2r (mm1, mm2); punpcklbw_r2r (mm0, mm1); movq_r2r (mm3, mm4); paddsw_m2r (*(block+0*8), mm1); punpckhbw_r2r (mm0, mm2); paddsw_m2r (*(block+0*8+4), mm2); punpcklbw_r2r (mm0, mm3); paddsw_m2r (*(block+1*8), mm3); packuswb_r2r (mm2, mm1); punpckhbw_r2r (mm0, mm4); movq_r2m (mm1, *dest); paddsw_m2r (*(block+1*8+4), mm4); ADD_MMX (2*8, mm1, mm2, mm3, mm4); ADD_MMX (3*8, mm3, mm4, mm1, mm2); ADD_MMX (4*8, mm1, mm2, mm3, mm4); ADD_MMX (5*8, mm3, mm4, mm1, mm2); ADD_MMX (6*8, mm1, mm2, mm3, mm4); ADD_MMX (7*8, mm3, mm4, mm1, mm2); packuswb_r2r (mm4, mm3); movq_r2m (mm3, *(dest+stride)); } static inline void block_zero (int16_t * block) { pxor_r2r (mm0, mm0); movq_r2m (mm0, *(block+0*4)); movq_r2m (mm0, *(block+1*4)); movq_r2m (mm0, *(block+2*4)); movq_r2m (mm0, *(block+3*4)); movq_r2m (mm0, *(block+4*4)); movq_r2m (mm0, *(block+5*4)); movq_r2m (mm0, *(block+6*4)); movq_r2m (mm0, *(block+7*4)); movq_r2m (mm0, *(block+8*4)); movq_r2m (mm0, *(block+9*4)); movq_r2m (mm0, *(block+10*4)); movq_r2m (mm0, *(block+11*4)); movq_r2m (mm0, *(block+12*4)); movq_r2m (mm0, *(block+13*4)); movq_r2m (mm0, *(block+14*4)); movq_r2m (mm0, *(block+15*4)); } declare_idct (mmxext_idct, mmxext_table, mmxext_row_head, mmxext_row, mmxext_row_tail, mmxext_row_mid) void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride) { mmxext_idct (block); block_copy (block, dest, stride); block_zero (block); } void mpeg2_idct_add_mmxext (int16_t * block, uint8_t * dest, int stride) { mmxext_idct (block); block_add (block, dest, stride); block_zero (block); } void mpeg2_idct_mmxext (int16_t * block) { mmxext_idct (block); } declare_idct (mmx_idct, mmx_table, mmx_row_head, mmx_row, mmx_row_tail, mmx_row_mid) void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride) { mmx_idct (block); block_copy (block, dest, stride); block_zero (block); } void mpeg2_idct_add_mmx (int16_t * block, uint8_t * dest, int stride) { mmx_idct (block); block_add (block, dest, stride); block_zero (block); } void mpeg2_idct_mmx (int16_t * block) { mmx_idct (block); } void mpeg2_zero_block_mmx (int16_t * block) { block_zero (block); } void mpeg2_idct_mmx_init (void) { int i, j; /* the mmx/mmxext idct uses a reordered input, so we patch scan tables */ for (i = 0; i < 64; i++) { j = mpeg2_scan_norm[i]; mpeg2_scan_norm[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); j = mpeg2_scan_alt[i]; mpeg2_scan_alt[i] = (j & 0x38) | ((j & 6) >> 1) | ((j & 1) << 2); } } #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/motion_comp_vis.c�����������������������������������������������0000644�0001750�0001750�00000130703�14647725152�020451� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_vis.c * Copyright (C) 2003 David S. Miller <davem@redhat.com> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #if defined(ARCH_SPARC) && defined(ENABLE_VIS) #include <inttypes.h> #include "mpeg2_internal.h" #include "vis.h" /* The trick used in some of this file is the formula from the MMX * motion comp code, which is: * * (x+y+1)>>1 == (x|y)-((x^y)>>1) * * This allows us to average 8 bytes at a time in a 64-bit FPU reg. * We avoid overflows by masking before we do the shift, and we * implement the shift by multiplying by 1/2 using mul8x16. So in * VIS this is (assume 'x' is in f0, 'y' is in f2, a repeating mask * of '0xfe' is in f4, a repeating mask of '0x7f' is in f6, and * the value 0x80808080 is in f8): * * fxor f0, f2, f10 * fand f10, f4, f10 * fmul8x16 f8, f10, f10 * fand f10, f6, f10 * for f0, f2, f12 * fpsub16 f12, f10, f10 */ #define DUP4(x) {x, x, x, x} #define DUP8(x) {x, x, x, x, x, x, x, x} static const int16_t constants1[] ATTR_ALIGN(8) = DUP4 (1); static const int16_t constants2[] ATTR_ALIGN(8) = DUP4 (2); static const int16_t constants3[] ATTR_ALIGN(8) = DUP4 (3); static const int16_t constants6[] ATTR_ALIGN(8) = DUP4 (6); static const int8_t constants_fe[] ATTR_ALIGN(8) = DUP8 (0xfe); static const int8_t constants_7f[] ATTR_ALIGN(8) = DUP8 (0x7f); static const int8_t constants128[] ATTR_ALIGN(8) = DUP8 (128); static const int16_t constants256_512[] ATTR_ALIGN(8) = {256, 512, 256, 512}; static const int16_t constants256_1024[] ATTR_ALIGN(8) = {256, 1024, 256, 1024}; #define REF_0 0 #define REF_0_1 1 #define REF_2 2 #define REF_2_1 3 #define REF_4 4 #define REF_4_1 5 #define REF_6 6 #define REF_6_1 7 #define REF_S0 8 #define REF_S0_1 9 #define REF_S2 10 #define REF_S2_1 11 #define REF_S4 12 #define REF_S4_1 13 #define REF_S6 14 #define REF_S6_1 15 #define DST_0 16 #define DST_1 17 #define DST_2 18 #define DST_3 19 #define CONST_1 20 #define CONST_2 20 #define CONST_3 20 #define CONST_6 20 #define MASK_fe 20 #define CONST_128 22 #define CONST_256 22 #define CONST_512 22 #define CONST_1024 22 #define TMP0 24 #define TMP1 25 #define TMP2 26 #define TMP3 27 #define TMP4 28 #define TMP5 29 #define ZERO 30 #define MASK_7f 30 #define TMP6 32 #define TMP8 34 #define TMP10 36 #define TMP12 38 #define TMP14 40 #define TMP16 42 #define TMP18 44 #define TMP20 46 #define TMP22 48 #define TMP24 50 #define TMP26 52 #define TMP28 54 #define TMP30 56 #define TMP32 58 static void MC_put_o_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; do { /* 5 cycles */ vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_faligndata(TMP0, TMP2, REF_0); vis_st64(REF_0, dest[0]); vis_faligndata(TMP2, TMP4, REF_2); vis_st64_2(REF_2, dest, 8); dest += stride; } while (--height); } static void MC_put_o_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; do { /* 4 cycles */ vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); ref += stride; /* stall */ vis_faligndata(TMP0, TMP2, REF_0); vis_st64(REF_0, dest[0]); dest += stride; } while (--height); } static void MC_avg_o_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int stride_8 = stride + 8; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; vis_ld64(ref[0], TMP0); vis_ld64(ref[8], TMP2); vis_ld64_2(ref, offset, TMP4); vis_ld64(dest[0], DST_0); vis_ld64(dest[8], DST_2); vis_ld64(constants_fe[0], MASK_fe); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP2, TMP4, REF_2); vis_ld64(constants128[0], CONST_128); ref += stride; height = (height >> 1) - 1; do { /* 24 cycles */ vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP6); vis_ld64_2(ref, 8, TMP2); vis_and(TMP6, MASK_fe, TMP6); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_mul8x16(CONST_128, TMP6, TMP6); vis_xor(DST_2, REF_2, TMP8); vis_and(TMP8, MASK_fe, TMP8); vis_or(DST_0, REF_0, TMP10); vis_ld64_2(dest, stride, DST_0); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(DST_2, REF_2, TMP12); vis_ld64_2(dest, stride_8, DST_2); vis_ld64(ref[0], TMP14); vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_ld64_2(ref, 8, TMP16); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, offset, TMP18); vis_faligndata(TMP2, TMP4, REF_2); ref += stride; vis_xor(DST_0, REF_0, TMP20); vis_and(TMP20, MASK_fe, TMP20); vis_xor(DST_2, REF_2, TMP22); vis_mul8x16(CONST_128, TMP20, TMP20); vis_and(TMP22, MASK_fe, TMP22); vis_or(DST_0, REF_0, TMP24); vis_mul8x16(CONST_128, TMP22, TMP22); vis_or(DST_2, REF_2, TMP26); vis_ld64_2(dest, stride, DST_0); vis_faligndata(TMP14, TMP16, REF_0); vis_ld64_2(dest, stride_8, DST_2); vis_faligndata(TMP16, TMP18, REF_2); vis_and(TMP20, MASK_7f, TMP20); vis_and(TMP22, MASK_7f, TMP22); vis_psub16(TMP24, TMP20, TMP20); vis_st64(TMP20, dest[0]); vis_psub16(TMP26, TMP22, TMP22); vis_st64_2(TMP22, dest, 8); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP6); vis_ld64_2(ref, 8, TMP2); vis_and(TMP6, MASK_fe, TMP6); vis_ld64_2(ref, offset, TMP4); vis_mul8x16(CONST_128, TMP6, TMP6); vis_xor(DST_2, REF_2, TMP8); vis_and(TMP8, MASK_fe, TMP8); vis_or(DST_0, REF_0, TMP10); vis_ld64_2(dest, stride, DST_0); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(DST_2, REF_2, TMP12); vis_ld64_2(dest, stride_8, DST_2); vis_ld64(ref[0], TMP14); vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_2); vis_xor(DST_0, REF_0, TMP20); vis_and(TMP20, MASK_fe, TMP20); vis_xor(DST_2, REF_2, TMP22); vis_mul8x16(CONST_128, TMP20, TMP20); vis_and(TMP22, MASK_fe, TMP22); vis_or(DST_0, REF_0, TMP24); vis_mul8x16(CONST_128, TMP22, TMP22); vis_or(DST_2, REF_2, TMP26); vis_and(TMP20, MASK_7f, TMP20); vis_and(TMP22, MASK_7f, TMP22); vis_psub16(TMP24, TMP20, TMP20); vis_st64(TMP20, dest[0]); vis_psub16(TMP26, TMP22, TMP22); vis_st64_2(TMP22, dest, 8); } static void MC_avg_o_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); vis_ld64(dest[0], DST_0); vis_ld64(constants_fe[0], MASK_fe); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants128[0], CONST_128); ref += stride; height = (height >> 1) - 1; do { /* 12 cycles */ vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP4); vis_ld64_2(ref, offset, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(DST_0, REF_0, TMP6); vis_ld64_2(dest, stride, DST_0); ref += stride; vis_mul8x16(CONST_128, TMP4, TMP4); vis_ld64(ref[0], TMP12); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, offset, TMP2); vis_xor(DST_0, REF_0, TMP0); ref += stride; vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, TMP4); vis_st64(TMP4, dest[0]); dest += stride; vis_mul8x16(CONST_128, TMP0, TMP0); vis_or(DST_0, REF_0, TMP6); vis_ld64_2(dest, stride, DST_0); vis_faligndata(TMP12, TMP2, REF_0); vis_and(TMP0, MASK_7f, TMP0); vis_psub16(TMP6, TMP0, TMP4); vis_st64(TMP4, dest[0]); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(DST_0, REF_0, TMP4); vis_ld64_2(ref, offset, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(DST_0, REF_0, TMP6); vis_ld64_2(dest, stride, DST_0); vis_mul8x16(CONST_128, TMP4, TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_xor(DST_0, REF_0, TMP0); vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, TMP4); vis_st64(TMP4, dest[0]); dest += stride; vis_mul8x16(CONST_128, TMP0, TMP0); vis_or(DST_0, REF_0, TMP6); vis_and(TMP0, MASK_7f, TMP0); vis_psub16(TMP6, TMP0, TMP4); vis_st64(TMP4, dest[0]); } static void MC_put_x_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; ref = vis_alignaddr(ref); vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); vis_ld64_2(ref, 16, TMP4); vis_ld64(constants_fe[0], MASK_fe); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants128[0], CONST_128); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } ref += stride; height = (height >> 1) - 1; do { /* 34 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP6); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP8); vis_ld64_2(ref, 16, TMP4); vis_and(TMP6, MASK_fe, TMP6); ref += stride; vis_ld64(ref[0], TMP14); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_ld64_2(ref, 8, TMP16); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_ld64_2(ref, 16, TMP18); ref += stride; vis_or(REF_4, REF_6, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_xor(REF_0, REF_2, TMP6); vis_xor(REF_4, REF_6, TMP8); vis_and(TMP6, MASK_fe, TMP6); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_or(REF_4, REF_6, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP14, TMP16, REF_0); vis_faligndata(TMP16, TMP18, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP14, TMP16, REF_2); vis_faligndata(TMP16, TMP18, REF_6); } else { vis_src1(TMP16, REF_2); vis_src1(TMP18, REF_6); } vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP6); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP8); vis_ld64_2(ref, 16, TMP4); vis_and(TMP6, MASK_fe, TMP6); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_or(REF_4, REF_6, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); dest += stride; vis_xor(REF_0, REF_2, TMP6); vis_xor(REF_4, REF_6, TMP8); vis_and(TMP6, MASK_fe, TMP6); vis_mul8x16(CONST_128, TMP6, TMP6); vis_and(TMP8, MASK_fe, TMP8); vis_mul8x16(CONST_128, TMP8, TMP8); vis_or(REF_0, REF_2, TMP10); vis_or(REF_4, REF_6, TMP12); vis_and(TMP6, MASK_7f, TMP6); vis_and(TMP8, MASK_7f, TMP8); vis_psub16(TMP10, TMP6, TMP6); vis_st64(TMP6, dest[0]); vis_psub16(TMP12, TMP8, TMP8); vis_st64_2(TMP8, dest, 8); } static void MC_put_x_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; ref = vis_alignaddr(ref); vis_ld64(ref[0], TMP0); vis_ld64(ref[8], TMP2); vis_ld64(constants_fe[0], MASK_fe); vis_ld64(constants_7f[0], MASK_7f); vis_ld64(constants128[0], CONST_128); vis_faligndata(TMP0, TMP2, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); } else { vis_src1(TMP2, REF_2); } ref += stride; height = (height >> 1) - 1; do { /* 20 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, 8, TMP2); vis_and(TMP4, MASK_fe, TMP4); ref += stride; vis_ld64(ref[0], TMP8); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, 8, TMP10); ref += stride; vis_faligndata(TMP0, TMP2, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); } else { vis_src1(TMP2, REF_2); } vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_xor(REF_0, REF_2, TMP12); vis_and(TMP12, MASK_fe, TMP12); vis_or(REF_0, REF_2, TMP14); vis_mul8x16(CONST_128, TMP12, TMP12); vis_alignaddr_g0((void *)off); vis_faligndata(TMP8, TMP10, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP8, TMP10, REF_2); } else { vis_src1(TMP10, REF_2); } vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, 8, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_alignaddr_g0((void *)off); vis_faligndata(TMP0, TMP2, REF_0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); } else { vis_src1(TMP2, REF_2); } vis_and(TMP4, MASK_7f, TMP4); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_xor(REF_0, REF_2, TMP12); vis_and(TMP12, MASK_fe, TMP12); vis_or(REF_0, REF_2, TMP14); vis_mul8x16(CONST_128, TMP12, TMP12); vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); dest += stride; } static void MC_avg_x_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); vis_ld64(constants3[0], CONST_3); vis_fzero(ZERO); vis_ld64(constants256_512[0], CONST_256); ref = vis_alignaddr(ref); do { /* 26 cycles */ vis_ld64(ref[0], TMP0); vis_ld64(ref[8], TMP2); vis_alignaddr_g0((void *)off); vis_ld64(ref[16], TMP4); vis_ld64(dest[0], DST_0); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(dest[8], DST_2); vis_faligndata(TMP2, TMP4, REF_4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); } vis_mul8x16au(REF_0, CONST_256, TMP0); vis_pmerge(ZERO, REF_2, TMP4); vis_mul8x16au(REF_0_1, CONST_256, TMP2); vis_pmerge(ZERO, REF_2_1, TMP6); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16al(DST_0, CONST_512, TMP4); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16al(DST_1, CONST_512, TMP6); vis_mul8x16au(REF_6, CONST_256, TMP12); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16au(REF_6_1, CONST_256, TMP14); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_4, CONST_256, TMP16); vis_padd16(TMP0, CONST_3, TMP8); vis_mul8x16au(REF_4_1, CONST_256, TMP18); vis_padd16(TMP2, CONST_3, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_padd16(TMP16, TMP12, TMP0); vis_st64(DST_0, dest[0]); vis_mul8x16al(DST_2, CONST_512, TMP4); vis_padd16(TMP18, TMP14, TMP2); vis_mul8x16al(DST_3, CONST_512, TMP6); vis_padd16(TMP0, CONST_3, TMP0); vis_padd16(TMP2, CONST_3, TMP2); vis_padd16(TMP0, TMP4, TMP0); vis_padd16(TMP2, TMP6, TMP2); vis_pack16(TMP0, DST_2); vis_pack16(TMP2, DST_3); vis_st64(DST_2, dest[8]); ref += stride; dest += stride; } while (--height); } static void MC_avg_x_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_times_2 = stride << 1; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); vis_ld64(constants3[0], CONST_3); vis_fzero(ZERO); vis_ld64(constants256_512[0], CONST_256); ref = vis_alignaddr(ref); height >>= 2; do { /* 47 cycles */ vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); ref += stride; vis_alignaddr_g0((void *)off); vis_ld64(ref[0], TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, 8, TMP6); ref += stride; vis_ld64(ref[0], TMP8); vis_ld64_2(ref, 8, TMP10); ref += stride; vis_faligndata(TMP4, TMP6, REF_4); vis_ld64(ref[0], TMP12); vis_ld64_2(ref, 8, TMP14); ref += stride; vis_faligndata(TMP8, TMP10, REF_S0); vis_faligndata(TMP12, TMP14, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_ld64(dest[0], DST_0); vis_faligndata(TMP0, TMP2, REF_2); vis_ld64_2(dest, stride, DST_2); vis_faligndata(TMP4, TMP6, REF_6); vis_faligndata(TMP8, TMP10, REF_S2); vis_faligndata(TMP12, TMP14, REF_S6); } else { vis_ld64(dest[0], DST_0); vis_src1(TMP2, REF_2); vis_ld64_2(dest, stride, DST_2); vis_src1(TMP6, REF_6); vis_src1(TMP10, REF_S2); vis_src1(TMP14, REF_S6); } vis_pmerge(ZERO, REF_0, TMP0); vis_mul8x16au(REF_0_1, CONST_256, TMP2); vis_pmerge(ZERO, REF_2, TMP4); vis_mul8x16au(REF_2_1, CONST_256, TMP6); vis_padd16(TMP0, CONST_3, TMP0); vis_mul8x16al(DST_0, CONST_512, TMP16); vis_padd16(TMP2, CONST_3, TMP2); vis_mul8x16al(DST_1, CONST_512, TMP18); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16au(REF_4, CONST_256, TMP8); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_4_1, CONST_256, TMP10); vis_padd16(TMP0, TMP16, TMP0); vis_mul8x16au(REF_6, CONST_256, TMP12); vis_padd16(TMP2, TMP18, TMP2); vis_mul8x16au(REF_6_1, CONST_256, TMP14); vis_padd16(TMP8, CONST_3, TMP8); vis_mul8x16al(DST_2, CONST_512, TMP16); vis_padd16(TMP8, TMP12, TMP8); vis_mul8x16al(DST_3, CONST_512, TMP18); vis_padd16(TMP10, TMP14, TMP10); vis_pack16(TMP0, DST_0); vis_pack16(TMP2, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP10, CONST_3, TMP10); vis_ld64_2(dest, stride, DST_0); vis_padd16(TMP8, TMP16, TMP8); vis_ld64_2(dest, stride_times_2, TMP4/*DST_2*/); vis_padd16(TMP10, TMP18, TMP10); vis_pack16(TMP8, DST_2); vis_pack16(TMP10, DST_3); vis_st64(DST_2, dest[0]); dest += stride; vis_mul8x16au(REF_S0_1, CONST_256, TMP2); vis_pmerge(ZERO, REF_S0, TMP0); vis_pmerge(ZERO, REF_S2, TMP24); vis_mul8x16au(REF_S2_1, CONST_256, TMP6); vis_padd16(TMP0, CONST_3, TMP0); vis_mul8x16au(REF_S4, CONST_256, TMP8); vis_padd16(TMP2, CONST_3, TMP2); vis_mul8x16au(REF_S4_1, CONST_256, TMP10); vis_padd16(TMP0, TMP24, TMP0); vis_mul8x16au(REF_S6, CONST_256, TMP12); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_S6_1, CONST_256, TMP14); vis_padd16(TMP8, CONST_3, TMP8); vis_mul8x16al(DST_0, CONST_512, TMP16); vis_padd16(TMP10, CONST_3, TMP10); vis_mul8x16al(DST_1, CONST_512, TMP18); vis_padd16(TMP8, TMP12, TMP8); vis_mul8x16al(TMP4/*DST_2*/, CONST_512, TMP20); vis_mul8x16al(TMP5/*DST_3*/, CONST_512, TMP22); vis_padd16(TMP0, TMP16, TMP0); vis_padd16(TMP2, TMP18, TMP2); vis_pack16(TMP0, DST_0); vis_padd16(TMP10, TMP14, TMP10); vis_pack16(TMP2, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP8, TMP20, TMP8); vis_padd16(TMP10, TMP22, TMP10); vis_pack16(TMP8, DST_2); vis_pack16(TMP10, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } static void MC_put_y_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; vis_ld64(ref[0], TMP0); vis_ld64_2(ref, 8, TMP2); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_ld64(ref[0], TMP6); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, 8, TMP8); vis_faligndata(TMP2, TMP4, REF_4); vis_ld64_2(ref, offset, TMP10); ref += stride; vis_ld64(constants_fe[0], MASK_fe); vis_faligndata(TMP6, TMP8, REF_2); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP8, TMP10, REF_6); vis_ld64(constants128[0], CONST_128); height = (height >> 1) - 1; do { /* 24 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP12); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP16); vis_ld64_2(ref, offset, TMP4); ref += stride; vis_or(REF_0, REF_2, TMP14); vis_ld64(ref[0], TMP6); vis_or(REF_4, REF_6, TMP18); vis_ld64_2(ref, 8, TMP8); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, offset, TMP10); ref += stride; vis_faligndata(TMP2, TMP4, REF_4); vis_and(TMP12, MASK_fe, TMP12); vis_and(TMP16, MASK_fe, TMP16); vis_mul8x16(CONST_128, TMP12, TMP12); vis_mul8x16(CONST_128, TMP16, TMP16); vis_xor(REF_0, REF_2, TMP0); vis_xor(REF_4, REF_6, TMP2); vis_or(REF_0, REF_2, TMP20); vis_and(TMP12, MASK_7f, TMP12); vis_and(TMP16, MASK_7f, TMP16); vis_psub16(TMP14, TMP12, TMP12); vis_st64(TMP12, dest[0]); vis_psub16(TMP18, TMP16, TMP16); vis_st64_2(TMP16, dest, 8); dest += stride; vis_or(REF_4, REF_6, TMP18); vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP2, MASK_fe, TMP2); vis_mul8x16(CONST_128, TMP0, TMP0); vis_faligndata(TMP6, TMP8, REF_2); vis_mul8x16(CONST_128, TMP2, TMP2); vis_faligndata(TMP8, TMP10, REF_6); vis_and(TMP0, MASK_7f, TMP0); vis_and(TMP2, MASK_7f, TMP2); vis_psub16(TMP20, TMP0, TMP0); vis_st64(TMP0, dest[0]); vis_psub16(TMP18, TMP2, TMP2); vis_st64_2(TMP2, dest, 8); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP12); vis_ld64_2(ref, 8, TMP2); vis_xor(REF_4, REF_6, TMP16); vis_ld64_2(ref, offset, TMP4); vis_or(REF_0, REF_2, TMP14); vis_or(REF_4, REF_6, TMP18); vis_faligndata(TMP0, TMP2, REF_0); vis_faligndata(TMP2, TMP4, REF_4); vis_and(TMP12, MASK_fe, TMP12); vis_and(TMP16, MASK_fe, TMP16); vis_mul8x16(CONST_128, TMP12, TMP12); vis_mul8x16(CONST_128, TMP16, TMP16); vis_xor(REF_0, REF_2, TMP0); vis_xor(REF_4, REF_6, TMP2); vis_or(REF_0, REF_2, TMP20); vis_and(TMP12, MASK_7f, TMP12); vis_and(TMP16, MASK_7f, TMP16); vis_psub16(TMP14, TMP12, TMP12); vis_st64(TMP12, dest[0]); vis_psub16(TMP18, TMP16, TMP16); vis_st64_2(TMP16, dest, 8); dest += stride; vis_or(REF_4, REF_6, TMP18); vis_and(TMP0, MASK_fe, TMP0); vis_and(TMP2, MASK_fe, TMP2); vis_mul8x16(CONST_128, TMP0, TMP0); vis_mul8x16(CONST_128, TMP2, TMP2); vis_and(TMP0, MASK_7f, TMP0); vis_and(TMP2, MASK_7f, TMP2); vis_psub16(TMP20, TMP0, TMP0); vis_st64(TMP0, dest[0]); vis_psub16(TMP18, TMP2, TMP2); vis_st64_2(TMP2, dest, 8); } static void MC_put_y_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int offset; ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); ref += stride; vis_ld64(ref[0], TMP4); vis_ld64_2(ref, offset, TMP6); ref += stride; vis_ld64(constants_fe[0], MASK_fe); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(constants_7f[0], MASK_7f); vis_faligndata(TMP4, TMP6, REF_2); vis_ld64(constants128[0], CONST_128); height = (height >> 1) - 1; do { /* 12 cycles */ vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, offset, TMP2); ref += stride; vis_and(TMP4, MASK_fe, TMP4); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64(ref[0], TMP0); vis_ld64_2(ref, offset, TMP2); ref += stride; vis_xor(REF_0, REF_2, TMP12); vis_and(TMP4, MASK_7f, TMP4); vis_and(TMP12, MASK_fe, TMP12); vis_mul8x16(CONST_128, TMP12, TMP12); vis_or(REF_0, REF_2, TMP14); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_faligndata(TMP0, TMP2, REF_2); vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); dest += stride; } while (--height); vis_ld64(ref[0], TMP0); vis_xor(REF_0, REF_2, TMP4); vis_ld64_2(ref, offset, TMP2); vis_and(TMP4, MASK_fe, TMP4); vis_or(REF_0, REF_2, TMP6); vis_mul8x16(CONST_128, TMP4, TMP4); vis_faligndata(TMP0, TMP2, REF_0); vis_xor(REF_0, REF_2, TMP12); vis_and(TMP4, MASK_7f, TMP4); vis_and(TMP12, MASK_fe, TMP12); vis_mul8x16(CONST_128, TMP12, TMP12); vis_or(REF_0, REF_2, TMP14); vis_psub16(TMP6, TMP4, DST_0); vis_st64(DST_0, dest[0]); dest += stride; vis_and(TMP12, MASK_7f, TMP12); vis_psub16(TMP14, TMP12, DST_0); vis_st64(DST_0, dest[0]); } static void MC_avg_y_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int stride_8 = stride + 8; int stride_16; int offset; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); offset = (ref != _ref) ? 16 : 0; vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64_2(ref, offset, TMP4); stride_16 = stride + offset; vis_ld64(constants3[0], CONST_3); vis_faligndata(TMP0, TMP2, REF_2); vis_ld64(constants256_512[0], CONST_256); vis_faligndata(TMP2, TMP4, REF_6); height >>= 1; do { /* 31 cycles */ vis_ld64_2(ref, stride, TMP0); vis_pmerge(ZERO, REF_2, TMP12); vis_mul8x16au(REF_2_1, CONST_256, TMP14); vis_ld64_2(ref, stride_8, TMP2); vis_pmerge(ZERO, REF_6, TMP16); vis_mul8x16au(REF_6_1, CONST_256, TMP18); vis_ld64_2(ref, stride_16, TMP4); ref += stride; vis_ld64(dest[0], DST_0); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(dest, 8, DST_2); vis_faligndata(TMP2, TMP4, REF_4); vis_ld64_2(ref, stride, TMP6); vis_pmerge(ZERO, REF_0, TMP0); vis_mul8x16au(REF_0_1, CONST_256, TMP2); vis_ld64_2(ref, stride_8, TMP8); vis_pmerge(ZERO, REF_4, TMP4); vis_ld64_2(ref, stride_16, TMP10); ref += stride; vis_ld64_2(dest, stride, REF_S0/*DST_4*/); vis_faligndata(TMP6, TMP8, REF_2); vis_mul8x16au(REF_4_1, CONST_256, TMP6); vis_ld64_2(dest, stride_8, REF_S2/*DST_6*/); vis_faligndata(TMP8, TMP10, REF_6); vis_mul8x16al(DST_0, CONST_512, TMP20); vis_padd16(TMP0, CONST_3, TMP0); vis_mul8x16al(DST_1, CONST_512, TMP22); vis_padd16(TMP2, CONST_3, TMP2); vis_mul8x16al(DST_2, CONST_512, TMP24); vis_padd16(TMP4, CONST_3, TMP4); vis_mul8x16al(DST_3, CONST_512, TMP26); vis_padd16(TMP6, CONST_3, TMP6); vis_padd16(TMP12, TMP20, TMP12); vis_mul8x16al(REF_S0, CONST_512, TMP20); vis_padd16(TMP14, TMP22, TMP14); vis_mul8x16al(REF_S0_1, CONST_512, TMP22); vis_padd16(TMP16, TMP24, TMP16); vis_mul8x16al(REF_S2, CONST_512, TMP24); vis_padd16(TMP18, TMP26, TMP18); vis_mul8x16al(REF_S2_1, CONST_512, TMP26); vis_padd16(TMP12, TMP0, TMP12); vis_mul8x16au(REF_2, CONST_256, TMP28); vis_padd16(TMP14, TMP2, TMP14); vis_mul8x16au(REF_2_1, CONST_256, TMP30); vis_padd16(TMP16, TMP4, TMP16); vis_mul8x16au(REF_6, CONST_256, REF_S4); vis_padd16(TMP18, TMP6, TMP18); vis_mul8x16au(REF_6_1, CONST_256, REF_S6); vis_pack16(TMP12, DST_0); vis_padd16(TMP28, TMP0, TMP12); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP30, TMP2, TMP14); vis_pack16(TMP16, DST_2); vis_padd16(REF_S4, TMP4, TMP16); vis_pack16(TMP18, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; vis_padd16(REF_S6, TMP6, TMP18); vis_padd16(TMP12, TMP20, TMP12); vis_padd16(TMP14, TMP22, TMP14); vis_pack16(TMP12, DST_0); vis_padd16(TMP16, TMP24, TMP16); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP18, TMP26, TMP18); vis_pack16(TMP16, DST_2); vis_pack16(TMP18, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; } while (--height); } static void MC_avg_y_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; int stride_8; int offset; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); offset = (ref != _ref) ? 8 : 0; vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64_2(ref, offset, TMP2); stride_8 = stride + offset; vis_ld64(constants3[0], CONST_3); vis_faligndata(TMP0, TMP2, REF_2); vis_ld64(constants256_512[0], CONST_256); height >>= 1; do { /* 20 cycles */ vis_ld64_2(ref, stride, TMP0); vis_pmerge(ZERO, REF_2, TMP8); vis_mul8x16au(REF_2_1, CONST_256, TMP10); vis_ld64_2(ref, stride_8, TMP2); ref += stride; vis_ld64(dest[0], DST_0); vis_ld64_2(dest, stride, DST_2); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, stride, TMP4); vis_mul8x16al(DST_0, CONST_512, TMP16); vis_pmerge(ZERO, REF_0, TMP12); vis_ld64_2(ref, stride_8, TMP6); ref += stride; vis_mul8x16al(DST_1, CONST_512, TMP18); vis_pmerge(ZERO, REF_0_1, TMP14); vis_padd16(TMP12, CONST_3, TMP12); vis_mul8x16al(DST_2, CONST_512, TMP24); vis_padd16(TMP14, CONST_3, TMP14); vis_mul8x16al(DST_3, CONST_512, TMP26); vis_faligndata(TMP4, TMP6, REF_2); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_mul8x16au(REF_2, CONST_256, TMP20); vis_padd16(TMP8, TMP16, TMP0); vis_mul8x16au(REF_2_1, CONST_256, TMP22); vis_padd16(TMP10, TMP18, TMP2); vis_pack16(TMP0, DST_0); vis_pack16(TMP2, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP12, TMP20, TMP12); vis_padd16(TMP14, TMP22, TMP14); vis_padd16(TMP12, TMP24, TMP0); vis_padd16(TMP14, TMP26, TMP2); vis_pack16(TMP0, DST_2); vis_pack16(TMP2, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } static void MC_put_xy_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; int stride_16 = stride + 16; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64(ref[16], TMP4); vis_ld64(constants2[0], CONST_2); vis_faligndata(TMP0, TMP2, REF_S0); vis_ld64(constants256_512[0], CONST_256); vis_faligndata(TMP2, TMP4, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); vis_faligndata(TMP2, TMP4, REF_S6); } else { vis_src1(TMP2, REF_S2); vis_src1(TMP4, REF_S6); } height >>= 1; do { vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP12); vis_pmerge(ZERO, REF_S0_1, TMP14); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride_8, TMP2); vis_mul8x16au(REF_S2, CONST_256, TMP16); vis_pmerge(ZERO, REF_S2_1, TMP18); vis_ld64_2(ref, stride_16, TMP4); ref += stride; vis_mul8x16au(REF_S4, CONST_256, TMP20); vis_pmerge(ZERO, REF_S4_1, TMP22); vis_ld64_2(ref, stride, TMP6); vis_mul8x16au(REF_S6, CONST_256, TMP24); vis_pmerge(ZERO, REF_S6_1, TMP26); vis_ld64_2(ref, stride_8, TMP8); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, stride_16, TMP10); ref += stride; vis_faligndata(TMP2, TMP4, REF_4); vis_faligndata(TMP6, TMP8, REF_S0); vis_faligndata(TMP8, TMP10, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); vis_faligndata(TMP6, TMP8, REF_S2); vis_faligndata(TMP8, TMP10, REF_S6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); vis_src1(TMP8, REF_S2); vis_src1(TMP10, REF_S6); } vis_mul8x16au(REF_0, CONST_256, TMP0); vis_pmerge(ZERO, REF_0_1, TMP2); vis_mul8x16au(REF_2, CONST_256, TMP4); vis_pmerge(ZERO, REF_2_1, TMP6); vis_padd16(TMP0, CONST_2, TMP8); vis_mul8x16au(REF_4, CONST_256, TMP0); vis_padd16(TMP2, CONST_2, TMP10); vis_mul8x16au(REF_4_1, CONST_256, TMP2); vis_padd16(TMP8, TMP4, TMP8); vis_mul8x16au(REF_6, CONST_256, TMP4); vis_padd16(TMP10, TMP6, TMP10); vis_mul8x16au(REF_6_1, CONST_256, TMP6); vis_padd16(TMP12, TMP8, TMP12); vis_padd16(TMP14, TMP10, TMP14); vis_padd16(TMP12, TMP16, TMP12); vis_padd16(TMP14, TMP18, TMP14); vis_pack16(TMP12, DST_0); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP0, CONST_2, TMP12); vis_mul8x16au(REF_S0, CONST_256, TMP0); vis_padd16(TMP2, CONST_2, TMP14); vis_mul8x16au(REF_S0_1, CONST_256, TMP2); vis_padd16(TMP12, TMP4, TMP12); vis_mul8x16au(REF_S2, CONST_256, TMP4); vis_padd16(TMP14, TMP6, TMP14); vis_mul8x16au(REF_S2_1, CONST_256, TMP6); vis_padd16(TMP20, TMP12, TMP20); vis_padd16(TMP22, TMP14, TMP22); vis_padd16(TMP20, TMP24, TMP20); vis_padd16(TMP22, TMP26, TMP22); vis_pack16(TMP20, DST_2); vis_pack16(TMP22, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; vis_padd16(TMP0, TMP4, TMP24); vis_mul8x16au(REF_S4, CONST_256, TMP0); vis_padd16(TMP2, TMP6, TMP26); vis_mul8x16au(REF_S4_1, CONST_256, TMP2); vis_padd16(TMP24, TMP8, TMP24); vis_padd16(TMP26, TMP10, TMP26); vis_pack16(TMP24, DST_0); vis_pack16(TMP26, DST_1); vis_st64(DST_0, dest[0]); vis_pmerge(ZERO, REF_S6, TMP4); vis_pmerge(ZERO, REF_S6_1, TMP6); vis_padd16(TMP0, TMP4, TMP0); vis_padd16(TMP2, TMP6, TMP2); vis_padd16(TMP0, TMP12, TMP0); vis_padd16(TMP2, TMP14, TMP2); vis_pack16(TMP0, DST_2); vis_pack16(TMP2, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; } while (--height); } static void MC_put_xy_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; vis_set_gsr(5 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64(constants2[0], CONST_2); vis_ld64(constants256_512[0], CONST_256); vis_faligndata(TMP0, TMP2, REF_S0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); } else { vis_src1(TMP2, REF_S2); } height >>= 1; do { /* 26 cycles */ vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP8); vis_pmerge(ZERO, REF_S2, TMP12); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride_8, TMP2); ref += stride; vis_mul8x16au(REF_S0_1, CONST_256, TMP10); vis_pmerge(ZERO, REF_S2_1, TMP14); vis_ld64_2(ref, stride, TMP4); vis_ld64_2(ref, stride_8, TMP6); ref += stride; vis_faligndata(TMP0, TMP2, REF_S4); vis_pmerge(ZERO, REF_S4, TMP18); vis_pmerge(ZERO, REF_S4_1, TMP20); vis_faligndata(TMP4, TMP6, REF_S0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S6); vis_faligndata(TMP4, TMP6, REF_S2); } else { vis_src1(TMP2, REF_S6); vis_src1(TMP6, REF_S2); } vis_padd16(TMP18, CONST_2, TMP18); vis_mul8x16au(REF_S6, CONST_256, TMP22); vis_padd16(TMP20, CONST_2, TMP20); vis_mul8x16au(REF_S6_1, CONST_256, TMP24); vis_mul8x16au(REF_S0, CONST_256, TMP26); vis_pmerge(ZERO, REF_S0_1, TMP28); vis_mul8x16au(REF_S2, CONST_256, TMP30); vis_padd16(TMP18, TMP22, TMP18); vis_mul8x16au(REF_S2_1, CONST_256, TMP32); vis_padd16(TMP20, TMP24, TMP20); vis_padd16(TMP8, TMP18, TMP8); vis_padd16(TMP10, TMP20, TMP10); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(TMP18, TMP26, TMP18); vis_padd16(TMP20, TMP28, TMP20); vis_padd16(TMP18, TMP30, TMP18); vis_padd16(TMP20, TMP32, TMP20); vis_pack16(TMP18, DST_2); vis_pack16(TMP20, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } static void MC_avg_xy_16_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; int stride_16 = stride + 16; vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[ 0], TMP0); vis_fzero(ZERO); vis_ld64(ref[ 8], TMP2); vis_ld64(ref[16], TMP4); vis_ld64(constants6[0], CONST_6); vis_faligndata(TMP0, TMP2, REF_S0); vis_ld64(constants256_1024[0], CONST_256); vis_faligndata(TMP2, TMP4, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); vis_faligndata(TMP2, TMP4, REF_S6); } else { vis_src1(TMP2, REF_S2); vis_src1(TMP4, REF_S6); } height >>= 1; do { /* 55 cycles */ vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP12); vis_pmerge(ZERO, REF_S0_1, TMP14); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride_8, TMP2); vis_mul8x16au(REF_S2, CONST_256, TMP16); vis_pmerge(ZERO, REF_S2_1, TMP18); vis_ld64_2(ref, stride_16, TMP4); ref += stride; vis_mul8x16au(REF_S4, CONST_256, TMP20); vis_pmerge(ZERO, REF_S4_1, TMP22); vis_ld64_2(ref, stride, TMP6); vis_mul8x16au(REF_S6, CONST_256, TMP24); vis_pmerge(ZERO, REF_S6_1, TMP26); vis_ld64_2(ref, stride_8, TMP8); vis_faligndata(TMP0, TMP2, REF_0); vis_ld64_2(ref, stride_16, TMP10); ref += stride; vis_faligndata(TMP2, TMP4, REF_4); vis_ld64(dest[0], DST_0); vis_faligndata(TMP6, TMP8, REF_S0); vis_ld64_2(dest, 8, DST_2); vis_faligndata(TMP8, TMP10, REF_S4); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_2); vis_faligndata(TMP2, TMP4, REF_6); vis_faligndata(TMP6, TMP8, REF_S2); vis_faligndata(TMP8, TMP10, REF_S6); } else { vis_src1(TMP2, REF_2); vis_src1(TMP4, REF_6); vis_src1(TMP8, REF_S2); vis_src1(TMP10, REF_S6); } vis_mul8x16al(DST_0, CONST_1024, TMP30); vis_pmerge(ZERO, REF_0, TMP0); vis_mul8x16al(DST_1, CONST_1024, TMP32); vis_pmerge(ZERO, REF_0_1, TMP2); vis_mul8x16au(REF_2, CONST_256, TMP4); vis_pmerge(ZERO, REF_2_1, TMP6); vis_mul8x16al(DST_2, CONST_1024, REF_0); vis_padd16(TMP0, CONST_6, TMP0); vis_mul8x16al(DST_3, CONST_1024, REF_2); vis_padd16(TMP2, CONST_6, TMP2); vis_padd16(TMP0, TMP4, TMP0); vis_mul8x16au(REF_4, CONST_256, TMP4); vis_padd16(TMP2, TMP6, TMP2); vis_mul8x16au(REF_4_1, CONST_256, TMP6); vis_padd16(TMP12, TMP0, TMP12); vis_mul8x16au(REF_6, CONST_256, TMP8); vis_padd16(TMP14, TMP2, TMP14); vis_mul8x16au(REF_6_1, CONST_256, TMP10); vis_padd16(TMP12, TMP16, TMP12); vis_mul8x16au(REF_S0, CONST_256, REF_4); vis_padd16(TMP14, TMP18, TMP14); vis_mul8x16au(REF_S0_1, CONST_256, REF_6); vis_padd16(TMP12, TMP30, TMP12); vis_padd16(TMP14, TMP32, TMP14); vis_pack16(TMP12, DST_0); vis_pack16(TMP14, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(TMP4, CONST_6, TMP4); vis_ld64_2(dest, stride, DST_0); vis_padd16(TMP6, CONST_6, TMP6); vis_mul8x16au(REF_S2, CONST_256, TMP12); vis_padd16(TMP4, TMP8, TMP4); vis_mul8x16au(REF_S2_1, CONST_256, TMP14); vis_padd16(TMP6, TMP10, TMP6); vis_padd16(TMP20, TMP4, TMP20); vis_padd16(TMP22, TMP6, TMP22); vis_padd16(TMP20, TMP24, TMP20); vis_padd16(TMP22, TMP26, TMP22); vis_padd16(TMP20, REF_0, TMP20); vis_mul8x16au(REF_S4, CONST_256, REF_0); vis_padd16(TMP22, REF_2, TMP22); vis_pack16(TMP20, DST_2); vis_pack16(TMP22, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; vis_ld64_2(dest, 8, DST_2); vis_mul8x16al(DST_0, CONST_1024, TMP30); vis_pmerge(ZERO, REF_S4_1, REF_2); vis_mul8x16al(DST_1, CONST_1024, TMP32); vis_padd16(REF_4, TMP0, TMP8); vis_mul8x16au(REF_S6, CONST_256, REF_4); vis_padd16(REF_6, TMP2, TMP10); vis_mul8x16au(REF_S6_1, CONST_256, REF_6); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_padd16(TMP8, TMP30, TMP8); vis_padd16(TMP10, TMP32, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_st64(DST_0, dest[0]); vis_padd16(REF_0, TMP4, REF_0); vis_mul8x16al(DST_2, CONST_1024, TMP30); vis_padd16(REF_2, TMP6, REF_2); vis_mul8x16al(DST_3, CONST_1024, TMP32); vis_padd16(REF_0, REF_4, REF_0); vis_padd16(REF_2, REF_6, REF_2); vis_padd16(REF_0, TMP30, REF_0); /* stall */ vis_padd16(REF_2, TMP32, REF_2); vis_pack16(REF_0, DST_2); vis_pack16(REF_2, DST_3); vis_st64_2(DST_2, dest, 8); dest += stride; } while (--height); } static void MC_avg_xy_8_vis (uint8_t * dest, uint8_t * _ref, int stride, int height) { uint8_t *ref = (uint8_t *) _ref; unsigned long off = (unsigned long) ref & 0x7; unsigned long off_plus_1 = off + 1; int stride_8 = stride + 8; vis_set_gsr(4 << VIS_GSR_SCALEFACT_SHIFT); ref = vis_alignaddr(ref); vis_ld64(ref[0], TMP0); vis_fzero(ZERO); vis_ld64_2(ref, 8, TMP2); vis_ld64(constants6[0], CONST_6); vis_ld64(constants256_1024[0], CONST_256); vis_faligndata(TMP0, TMP2, REF_S0); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S2); } else { vis_src1(TMP2, REF_S2); } height >>= 1; do { /* 31 cycles */ vis_ld64_2(ref, stride, TMP0); vis_mul8x16au(REF_S0, CONST_256, TMP8); vis_pmerge(ZERO, REF_S0_1, TMP10); vis_ld64_2(ref, stride_8, TMP2); ref += stride; vis_mul8x16au(REF_S2, CONST_256, TMP12); vis_pmerge(ZERO, REF_S2_1, TMP14); vis_alignaddr_g0((void *)off); vis_ld64_2(ref, stride, TMP4); vis_faligndata(TMP0, TMP2, REF_S4); vis_ld64_2(ref, stride_8, TMP6); ref += stride; vis_ld64(dest[0], DST_0); vis_faligndata(TMP4, TMP6, REF_S0); vis_ld64_2(dest, stride, DST_2); if (off != 0x7) { vis_alignaddr_g0((void *)off_plus_1); vis_faligndata(TMP0, TMP2, REF_S6); vis_faligndata(TMP4, TMP6, REF_S2); } else { vis_src1(TMP2, REF_S6); vis_src1(TMP6, REF_S2); } vis_mul8x16al(DST_0, CONST_1024, TMP30); vis_pmerge(ZERO, REF_S4, TMP22); vis_mul8x16al(DST_1, CONST_1024, TMP32); vis_pmerge(ZERO, REF_S4_1, TMP24); vis_mul8x16au(REF_S6, CONST_256, TMP26); vis_pmerge(ZERO, REF_S6_1, TMP28); vis_mul8x16au(REF_S0, CONST_256, REF_S4); vis_padd16(TMP22, CONST_6, TMP22); vis_mul8x16au(REF_S0_1, CONST_256, REF_S6); vis_padd16(TMP24, CONST_6, TMP24); vis_mul8x16al(DST_2, CONST_1024, REF_0); vis_padd16(TMP22, TMP26, TMP22); vis_mul8x16al(DST_3, CONST_1024, REF_2); vis_padd16(TMP24, TMP28, TMP24); vis_mul8x16au(REF_S2, CONST_256, TMP26); vis_padd16(TMP8, TMP22, TMP8); vis_mul8x16au(REF_S2_1, CONST_256, TMP28); vis_padd16(TMP10, TMP24, TMP10); vis_padd16(TMP8, TMP12, TMP8); vis_padd16(TMP10, TMP14, TMP10); vis_padd16(TMP8, TMP30, TMP8); vis_padd16(TMP10, TMP32, TMP10); vis_pack16(TMP8, DST_0); vis_pack16(TMP10, DST_1); vis_st64(DST_0, dest[0]); dest += stride; vis_padd16(REF_S4, TMP22, TMP12); vis_padd16(REF_S6, TMP24, TMP14); vis_padd16(TMP12, TMP26, TMP12); vis_padd16(TMP14, TMP28, TMP14); vis_padd16(TMP12, REF_0, TMP12); vis_padd16(TMP14, REF_2, TMP14); vis_pack16(TMP12, DST_2); vis_pack16(TMP14, DST_3); vis_st64(DST_2, dest[0]); dest += stride; } while (--height); } MPEG2_MC_EXTERN(vis); #endif /* defined(ARCH_SPARC) && defined(ENABLE_VIS) */ �������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/slice_xvmc.c����������������������������������������������������0000644�0001750�0001750�00000157445�14647725152�017415� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * slice_xvmc.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include <stdio.h> #include <string.h> /* memcpy/memset, try to remove */ #include <stdlib.h> #include <inttypes.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include "mpeg2_internal.h" #include <xine/xineutils.h> #include <xine/attributes.h> #include "accel_xvmc.h" #include "xvmc.h" #define MOTION_ACCEL XINE_VO_MOTION_ACCEL #define IDCT_ACCEL XINE_VO_IDCT_ACCEL #define SIGNED_INTRA XINE_VO_SIGNED_INTRA #define ACCEL (MOTION_ACCEL | IDCT_ACCEL) #include "vlc.h" /* original (non-patched) scan tables */ static const uint8_t mpeg2_scan_norm_orig[64] ATTR_ALIGN(16) = { /* Zig-Zag scan pattern */ 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 }; static const uint8_t mpeg2_scan_alt_orig[64] ATTR_ALIGN(16) = { /* Alternate scan pattern */ 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 }; static uint8_t mpeg2_scan_alt_ptable[64] ATTR_ALIGN(16); static uint8_t mpeg2_scan_norm_ptable[64] ATTR_ALIGN(16); static uint8_t mpeg2_scan_orig_ptable[64] ATTR_ALIGN(16); void xvmc_setup_scan_ptable( void ) { int i; for (i=0; i<64; ++i) { mpeg2_scan_norm_ptable[mpeg2_scan_norm_orig[i]] = mpeg2_scan_norm[i]; mpeg2_scan_alt_ptable[mpeg2_scan_alt_orig[i]] = mpeg2_scan_alt[i]; mpeg2_scan_orig_ptable[i] = i; } } static const int non_linear_quantizer_scale [] = { 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 }; static inline int get_xvmc_macroblock_modes (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int macroblock_modes; const MBtab * tab; switch (picture->picture_coding_type) { case I_TYPE: tab = MB_I + UBITS (bit_buf, 1); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if ((! (picture->frame_pred_frame_dct)) && (picture->picture_structure == FRAME_PICTURE)) { macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; case P_TYPE: tab = MB_P + UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (picture->picture_structure != FRAME_PICTURE) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); } return macroblock_modes; } else if (picture->frame_pred_frame_dct) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) macroblock_modes |= MC_FRAME; return macroblock_modes; } else { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); } if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; } case B_TYPE: tab = MB_B + UBITS (bit_buf, 6); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (picture->picture_structure != FRAME_PICTURE) { if (! (macroblock_modes & MACROBLOCK_INTRA)) { macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); } return macroblock_modes; } else if (picture->frame_pred_frame_dct) { /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ macroblock_modes |= MC_FRAME; return macroblock_modes; } else { if (macroblock_modes & MACROBLOCK_INTRA) goto intra; macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { intra: macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; } case D_TYPE: DUMPBITS (bit_buf, bits, 1); return MACROBLOCK_INTRA; default: return 0; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_xvmc_quantizer_scale (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int quantizer_scale_code; quantizer_scale_code = UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, 5); if (picture->q_scale_type) return non_linear_quantizer_scale [quantizer_scale_code]; else return quantizer_scale_code << 1; #undef bit_buf #undef bits #undef bit_ptr } static inline int get_xvmc_motion_delta (picture_t * picture, int f_code) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int delta; int sign; const MVtab * tab; if (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 1); return 0; } else if (bit_buf >= 0x0c000000) { tab = MV_4 + UBITS (bit_buf, 4); delta = (tab->delta << f_code) + 1; bits += tab->len + f_code + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) delta += UBITS (bit_buf, f_code); bit_buf <<= f_code; return (delta ^ sign) - sign; } else { tab = MV_10 + UBITS (bit_buf, 10); delta = (tab->delta << f_code) + 1; bits += tab->len + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) { NEEDBITS (bit_buf, bits, bit_ptr); delta += UBITS (bit_buf, f_code); DUMPBITS (bit_buf, bits, f_code); } return (delta ^ sign) - sign; } #undef bit_buf #undef bits #undef bit_ptr } static inline int bound_motion_vector (int vec, int f_code) { #if 1 unsigned int limit; int sign; limit = 16 << f_code; if ((unsigned int)(vec + limit) < 2 * limit) return vec; else { sign = ((int32_t)vec) >> 31; return vec - ((2 * limit) ^ sign) + sign; } #else return ((int32_t)vec << (27 - f_code)) >> (27 - f_code); #endif } static inline int get_xvmc_dmv (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const DMVtab * tab; tab = DMV_2 + UBITS (bit_buf, 2); DUMPBITS (bit_buf, bits, tab->len); return tab->dmv; #undef bit_buf #undef bits #undef bit_ptr } static inline int get_xvmc_coded_block_pattern (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const CBPtab * tab; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x20000000) { tab = CBP_7 + (UBITS (bit_buf, 7) - 16); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; } else { tab = CBP_9 + UBITS (bit_buf, 9); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_xvmc_luma_dc_dct_diff (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const DCtab * tab; int size; int dc_diff; if (bit_buf < 0xf8000000) { tab = DC_lum_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { bits += tab->len + size; bit_buf <<= tab->len; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff; } else { DUMPBITS (bit_buf, bits, 3); return 0; } } else { tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len); NEEDBITS (bit_buf, bits, bit_ptr); dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); DUMPBITS (bit_buf, bits, size); return dc_diff; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_xvmc_chroma_dc_dct_diff (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const DCtab * tab; int size; int dc_diff; if (bit_buf < 0xf8000000) { tab = DC_chrom_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { bits += tab->len + size; bit_buf <<= tab->len; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff; } else { DUMPBITS (bit_buf, bits, 2); return 0; } } else { tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len + 1); NEEDBITS (bit_buf, bits, bit_ptr); dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); DUMPBITS (bit_buf, bits, size); return dc_diff; } #undef bit_buf #undef bits #undef bit_ptr } #define SATURATE(val) \ do { \ if ((uint32_t)(val + 2048) > 4095) \ val = (val > 0) ? 2047 : -2048; \ } while (0) static void get_xvmc_intra_block_B14 (picture_t * picture) { int i; int j; int l; int val; const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; dest = picture->mc->blockptr; if( picture->mc->xvmc_accel & IDCT_ACCEL ) { if ( scan == mpeg2_scan_norm ) { scan = mpeg2_scan_norm_orig; scan_ptable = mpeg2_scan_norm_ptable; } else { scan = mpeg2_scan_alt_orig; scan_ptable = mpeg2_scan_alt_ptable; } } i = 0; mismatch = ~dest[0]; bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); i += tab->run; if (i >= 64) break; /* end of block */ normal_code: l = scan_ptable[j = scan[i]]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ l = scan_ptable[j = scan[i]]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = (SBITS (bit_buf, 12) * quantizer_scale * quant_matrix[l]) / 16; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 1; DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_xvmc_intra_block_B15 (picture_t * picture) { int i; int j; int l; int val; const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; dest = picture->mc->blockptr; if( picture->mc->xvmc_accel & IDCT_ACCEL ) { if ( scan == mpeg2_scan_norm ) { scan = mpeg2_scan_norm_orig; scan_ptable = mpeg2_scan_norm_ptable; } else { scan = mpeg2_scan_alt_orig; scan_ptable = mpeg2_scan_alt_ptable; } } i = 0; mismatch = ~dest[0]; bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x04000000) { tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) { normal_code: l = scan_ptable[j = scan[i]]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else { /* end of block. I commented out this code because if we */ /* dont exit here we will still exit at the later test :) */ /* if (i >= 128) break; */ /* end of block */ /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check against buffer overflow */ l = scan_ptable[j = scan[i]]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = (SBITS (bit_buf, 12) * quantizer_scale * quant_matrix[l]) / 16; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } } else if (bit_buf >= 0x02000000) { tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 1; DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_xvmc_non_intra_block (picture_t * picture) { int i; int j; int l; int val; const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; i = -1; mismatch = 1; dest = picture->mc->blockptr; if( picture->mc->xvmc_accel & IDCT_ACCEL ) { if ( scan == mpeg2_scan_norm ) { scan = mpeg2_scan_norm_orig; scan_ptable = mpeg2_scan_norm_ptable; } else { scan = mpeg2_scan_alt_orig; scan_ptable = mpeg2_scan_alt_ptable; } } bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x28000000) { tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); goto entry_1; } else goto entry_2; while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); entry_1: i += tab->run; if (i >= 64) break; /* end of block */ normal_code: l = scan_ptable[j = scan[i]]; bit_buf <<= tab->len; bits += tab->len + 1; val = ((2*tab->level+1) * quantizer_scale * quant_matrix[l]) >> 5; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } entry_2: if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ l = scan_ptable[j = scan[i]]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; val = (val * quantizer_scale * quant_matrix[l]) / 32; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 1; DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_xvmc_mpeg1_intra_block (picture_t * picture) { int i; int j; int l; int val; const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; i = 0; dest = picture->mc->blockptr; if( picture->mc->xvmc_accel & IDCT_ACCEL ) { if ( scan == mpeg2_scan_norm ) { scan = mpeg2_scan_norm_orig; scan_ptable = mpeg2_scan_norm_ptable; } else { scan = mpeg2_scan_alt_orig; scan_ptable = mpeg2_scan_alt_ptable; } } bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); i += tab->run; if (i >= 64) break; /* end of block */ normal_code: l = scan_ptable[j = scan[i]]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quantizer_scale * quant_matrix[l]) >> 4; /* oddification */ val = (val - 1) | 1; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ l = scan_ptable[j = scan[i]]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = SBITS (bit_buf, 8); if (! (val & 0x7f)) { DUMPBITS (bit_buf, bits, 8); val = UBITS (bit_buf, 8) + 2 * val; } val = (val * quantizer_scale * quant_matrix[l]) / 16; /* oddification */ val = (val + ~SBITS (val, 1)) | 1; SATURATE (val); dest[j] = val; DUMPBITS (bit_buf, bits, 8); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_xvmc_mpeg1_non_intra_block (picture_t * picture) { int i; int j; int l; int val; const uint8_t * scan = picture->scan; uint8_t * scan_ptable = mpeg2_scan_orig_ptable; uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; i = -1; dest = picture->mc->blockptr; if( picture->mc->xvmc_accel & IDCT_ACCEL ) { if ( scan == mpeg2_scan_norm ) { scan = mpeg2_scan_norm_orig; scan_ptable = mpeg2_scan_norm_ptable; } else { scan = mpeg2_scan_alt_orig; scan_ptable = mpeg2_scan_alt_ptable; } } bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x28000000) { tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); goto entry_1; } else goto entry_2; while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); entry_1: i += tab->run; if (i >= 64) break; /* end of block */ normal_code: l = scan_ptable[j = scan[i]]; bit_buf <<= tab->len; bits += tab->len + 1; val = ((2*tab->level+1) * quantizer_scale * quant_matrix[l]) >> 5; /* oddification */ val = (val - 1) | 1; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } entry_2: if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ l = scan_ptable[j = scan[i]]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = SBITS (bit_buf, 8); if (! (val & 0x7f)) { DUMPBITS (bit_buf, bits, 8); val = UBITS (bit_buf, 8) + 2 * val; } val = 2 * (val + SBITS (val, 1)) + 1; val = (val * quantizer_scale * quant_matrix[l]) / 32; /* oddification */ val = (val + ~SBITS (val, 1)) | 1; SATURATE (val); dest[j] = val; DUMPBITS (bit_buf, bits, 8); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static inline void slice_xvmc_intra_DCT (picture_t * picture, int cc, uint8_t * dest, int stride) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) (void)dest; (void)stride; NEEDBITS (bit_buf, bits, bit_ptr); /* Get the intra DC coefficient and inverse quantize it */ // printf("slice: slice_xvmc_intra_DCT cc=%d pred[0]=%d\n",cc,picture->dc_dct_pred[0]); if (cc == 0) picture->dc_dct_pred[0] += get_xvmc_luma_dc_dct_diff (picture); else picture->dc_dct_pred[cc] += get_xvmc_chroma_dc_dct_diff (picture); //TODO conversion to signed format // printf("slice: pred[0]=%d presision=%d\n",picture->dc_dct_pred[0], // picture->intra_dc_precision); mpeg2_zero_block(picture->mc->blockptr); picture->mc->blockptr[0] = picture->dc_dct_pred[cc] << (3 - picture->intra_dc_precision); if (picture->mpeg1) { if (picture->picture_coding_type != D_TYPE) get_xvmc_mpeg1_intra_block (picture); } else if (picture->intra_vlc_format) get_xvmc_intra_block_B15 (picture); else get_xvmc_intra_block_B14 (picture); if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL) { //motion_comp only no idct acceleration so do it in software mpeg2_idct (picture->mc->blockptr); } picture->mc->blockptr += 64; #undef bit_buf #undef bits #undef bit_ptr } static inline void slice_xvmc_non_intra_DCT (picture_t * picture, uint8_t * dest, int stride) { (void)dest; (void)stride; mpeg2_zero_block(picture->mc->blockptr); if (picture->mpeg1) get_xvmc_mpeg1_non_intra_block (picture); else get_xvmc_non_intra_block (picture); if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL) { // motion comp only no idct acceleration so do it in sw mpeg2_idct (picture->mc->blockptr); } picture->mc->blockptr += 64; } static void motion_mp1 (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; (void)table; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = (motion->pmv[0][0] + (get_xvmc_motion_delta (picture, motion->f_code[0]) << motion->f_code[1])); motion_x = bound_motion_vector (motion_x, motion->f_code[0] + motion->f_code[1]); motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[0][1] + (get_xvmc_motion_delta (picture, motion->f_code[0]) << motion->f_code[1])); motion_y = bound_motion_vector (motion_y, motion->f_code[0] + motion->f_code[1]); motion->pmv[0][1] = motion_y; #undef bit_buf #undef bits #undef bit_ptr } static void motion_fr_frame (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; (void)table; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; #undef bit_buf #undef bits #undef bit_ptr } static void motion_fr_field (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int), int dir) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y, field; // unsigned int pos_x, pos_y, xy_half; (void)table; NEEDBITS (bit_buf, bits, bit_ptr); field = UBITS (bit_buf, 1); picture->XvMC_mv_field_sel[0][dir] = field; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[0][1] >> 1) + get_xvmc_motion_delta (picture, motion->f_code[1]); /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[0][1] = motion_y << 1; NEEDBITS (bit_buf, bits, bit_ptr); field = UBITS (bit_buf, 1); //TODO look at field select need bob (weave ok) picture->XvMC_mv_field_sel[1][dir] = field; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[1][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[1][1] >> 1) + get_xvmc_motion_delta (picture, motion->f_code[1]); /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[1][1] = motion_y << 1; #undef bit_buf #undef bits #undef bit_ptr } static void motion_fr_dmv (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; (void)table; // TODO field select ?? possible need to be 0 picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[0][1] >> 1) + get_xvmc_motion_delta (picture, motion->f_code[1]); /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; #undef bit_buf #undef bits #undef bit_ptr } #if 0 static void motion_reuse (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { int motion_x, motion_y; motion_x = motion->pmv[0][0]; motion_y = motion->pmv[0][1]; } #endif /* like motion_frame, but parsing without actual motion compensation */ static void motion_fr_conceal (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (picture->f_motion.pmv[0][0] + get_xvmc_motion_delta (picture, picture->f_motion.f_code[0])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (picture->f_motion.pmv[0][1] + get_xvmc_motion_delta (picture, picture->f_motion.f_code[1])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_field (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; /*uint8_t ** ref_field;*/ (void)table; NEEDBITS (bit_buf, bits, bit_ptr); /*ref_field = motion->ref2[UBITS (bit_buf, 1)];*/ // TODO field select may need to do something here for bob (weave ok) picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_16x8 (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; /*uint8_t ** ref_field;*/ (void)table; NEEDBITS (bit_buf, bits, bit_ptr); /*ref_field = motion->ref2[UBITS (bit_buf, 1)];*/ // TODO field select may need to do something here bob (weave ok) picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[0][1] = motion_y; NEEDBITS (bit_buf, bits, bit_ptr); /*ref_field = motion->ref2[UBITS (bit_buf, 1)];*/ // TODO field select may need to do something here for bob (weave ok) picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[1][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[1][1] + get_xvmc_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion_y; #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_dmv (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; (void)table; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = motion->pmv[0][0] + get_xvmc_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[0][1] + get_xvmc_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; // TODO field select may need to do something here for bob (weave ok) picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = 0; #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_conceal (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int tmp; NEEDBITS (bit_buf, bits, bit_ptr); DUMPBITS (bit_buf, bits, 1); /* remove field_select */ tmp = (picture->f_motion.pmv[0][0] + get_xvmc_motion_delta (picture, picture->f_motion.f_code[0])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (picture->f_motion.pmv[0][1] + get_xvmc_motion_delta (picture, picture->f_motion.f_code[1])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ #undef bit_buf #undef bits #undef bit_ptr } #define MOTION_CALL(routine,direction) \ do { \ if ((direction) & MACROBLOCK_MOTION_FORWARD) \ routine (picture, &(picture->f_motion), mpeg2_mc.put); \ if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ routine (picture, &(picture->b_motion), \ ((direction) & MACROBLOCK_MOTION_FORWARD ? \ mpeg2_mc.avg : mpeg2_mc.put)); \ } while (0) #define NEXT_MACROBLOCK \ do { \ picture->offset += 16; \ if (picture->offset == picture->coded_picture_width) { \ do { /* just so we can use the break statement */ \ if (picture->current_frame->proc_slice) { \ picture->current_frame->proc_slice (picture->current_frame, \ picture->dest); \ if (picture->picture_coding_type == B_TYPE) \ break; \ } \ picture->dest[0] += 16 * picture->pitches[0]; \ picture->dest[1] += 8 * picture->pitches[1]; \ picture->dest[2] += 8 * picture->pitches[2]; \ } while (0); \ picture->v_offset += 16; \ if (picture->v_offset > picture->limit_y) { \ if (mpeg2_cpu_state_restore) \ mpeg2_cpu_state_restore (&cpu_state); \ return; \ } \ picture->offset = 0; \ } \ } while (0) static inline int slice_xvmc_init (picture_t * picture, int code) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int offset, height; struct vo_frame_s * forward_reference_frame; struct vo_frame_s * backward_reference_frame; const MBAtab * mba; offset = picture->picture_structure == BOTTOM_FIELD; picture->pitches[0] = picture->current_frame->pitches[0]; picture->pitches[1] = picture->current_frame->pitches[1]; picture->pitches[2] = picture->current_frame->pitches[2]; if( picture->forward_reference_frame ) { forward_reference_frame = picture->forward_reference_frame; } else { /* return 1; */ forward_reference_frame = picture->current_frame; } if( picture->backward_reference_frame ) { backward_reference_frame = picture->backward_reference_frame; } else { /* return 1; */ backward_reference_frame = picture->current_frame; } picture->f_motion.ref[0][0] = forward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); picture->f_motion.ref[0][1] = forward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); picture->f_motion.ref[0][2] = forward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); picture->b_motion.ref[0][0] = backward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); picture->b_motion.ref[0][1] = backward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); picture->b_motion.ref[0][2] = backward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); if (picture->picture_structure != FRAME_PICTURE) { uint8_t ** forward_ref; int bottom_field; bottom_field = (picture->picture_structure == BOTTOM_FIELD); picture->dmv_offset = bottom_field ? 1 : -1; picture->f_motion.ref2[0] = picture->f_motion.ref[bottom_field]; picture->f_motion.ref2[1] = picture->f_motion.ref[!bottom_field]; picture->b_motion.ref2[0] = picture->b_motion.ref[bottom_field]; picture->b_motion.ref2[1] = picture->b_motion.ref[!bottom_field]; forward_ref = forward_reference_frame->base; if (picture->second_field && (picture->picture_coding_type != B_TYPE)) forward_ref = picture->current_frame->base; picture->f_motion.ref[1][0] = forward_ref[0] + (bottom_field ? 0 : picture->pitches[0]); picture->f_motion.ref[1][1] = forward_ref[1] + (bottom_field ? 0 : picture->pitches[1]); picture->f_motion.ref[1][2] = forward_ref[2] + (bottom_field ? 0 : picture->pitches[2]); picture->b_motion.ref[1][0] = backward_reference_frame->base[0] + (bottom_field ? 0 : picture->pitches[0]); picture->b_motion.ref[1][1] = backward_reference_frame->base[1] + (bottom_field ? 0 : picture->pitches[1]); picture->b_motion.ref[1][2] = backward_reference_frame->base[2] + (bottom_field ? 0 : picture->pitches[2]); } picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; picture->v_offset = (code - 1) * 16; offset = (code - 1); if (picture->current_frame->proc_slice && picture->picture_coding_type == B_TYPE) offset = 0; else if (picture->picture_structure != FRAME_PICTURE) offset = 2 * offset; picture->dest[0] = picture->current_frame->base[0] + picture->pitches[0] * offset * 16; picture->dest[1] = picture->current_frame->base[1] + picture->pitches[1] * offset * 8; picture->dest[2] = picture->current_frame->base[2] + picture->pitches[2] * offset * 8; height = picture->coded_picture_height; switch (picture->picture_structure) { case BOTTOM_FIELD: picture->dest[0] += picture->pitches[0]; picture->dest[1] += picture->pitches[1]; picture->dest[2] += picture->pitches[2]; /* fall through */ case TOP_FIELD: picture->pitches[0] <<= 1; picture->pitches[1] <<= 1; picture->pitches[2] <<= 1; height >>= 1; } picture->limit_x = 2 * picture->coded_picture_width - 32; picture->limit_y_16 = 2 * height - 32; picture->limit_y_8 = 2 * height - 16; picture->limit_y = height - 16; //TODO conversion to signed format signed format if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && !(picture->mc->xvmc_accel & SIGNED_INTRA)) { //Motion Comp only unsigned intra // original: picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7); } else { //Motion Comp only signed intra MOTION_ACCEL+SIGNED_INTRA picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 0; } picture->quantizer_scale = get_xvmc_quantizer_scale (picture); /* ignore intra_slice and all the extra data */ while (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 9); NEEDBITS (bit_buf, bits, bit_ptr); } /* decode initial macroblock address increment */ offset = 0; while (1) { if (bit_buf >= 0x08000000) { mba = MBA_5 + (UBITS (bit_buf, 6) - 2); break; } else if (bit_buf >= 0x01800000) { mba = MBA_11 + (UBITS (bit_buf, 12) - 24); break; } else switch (UBITS (bit_buf, 12)) { case 8: /* macroblock_escape */ offset += 33; DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; case 15: /* macroblock_stuffing (MPEG1 only) */ bit_buf &= 0xfffff; DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; default: /* error */ return 1; } } DUMPBITS (bit_buf, bits, mba->len + 1); picture->offset = (offset + mba->mba) << 4; while (picture->offset - picture->coded_picture_width >= 0) { picture->offset -= picture->coded_picture_width; if ((picture->current_frame->proc_slice == NULL) || (picture->picture_coding_type != B_TYPE)) { picture->dest[0] += 16 * picture->pitches[0]; picture->dest[1] += 8 * picture->pitches[1]; picture->dest[2] += 8 * picture->pitches[2]; } picture->v_offset += 16; } if (picture->v_offset > picture->limit_y) return 1; return 0; #undef bit_buf #undef bits #undef bit_ptr } void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) cpu_state_t cpu_state; xine_xvmc_t *xvmc = (xine_xvmc_t *) picture->current_frame->accel_data; if (1 == code) { accel->xvmc_last_slice_code = 0; } if ((code != accel->xvmc_last_slice_code + 1) && (code != accel->xvmc_last_slice_code)) return; bitstream_init (picture, buffer); if (slice_xvmc_init (picture, code)) return; if (mpeg2_cpu_state_save) mpeg2_cpu_state_save (&cpu_state); while (1) { int macroblock_modes; int mba_inc; const MBAtab * mba; NEEDBITS (bit_buf, bits, bit_ptr); macroblock_modes = get_xvmc_macroblock_modes (picture); //macroblock_modes() picture->XvMC_mb_type = macroblock_modes & 0x1F; picture->XvMC_dct_type = (macroblock_modes & DCT_TYPE_INTERLACED)>>5; picture->XvMC_motion_type = (macroblock_modes & MOTION_TYPE_MASK)>>6; picture->XvMC_x = picture->offset/16; picture->XvMC_y = picture->v_offset/16; if((picture->XvMC_x == 0) && (picture->XvMC_y == 0)) { picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[1][0] = picture->XvMC_mv_field_sel[0][1] = picture->XvMC_mv_field_sel[1][1] = 0; } picture->XvMC_cbp = 0x3f; //TODO set for intra 4:2:0 6 blocks yyyyuv all enabled /* maybe integrate MACROBLOCK_QUANT test into get_xvmc_macroblock_modes ? */ if (macroblock_modes & MACROBLOCK_QUANT) picture->quantizer_scale = get_xvmc_quantizer_scale (picture); if (macroblock_modes & MACROBLOCK_INTRA) { int DCT_offset, DCT_stride; int offset; uint8_t * dest_y; if (picture->concealment_motion_vectors) { if (picture->picture_structure == FRAME_PICTURE) motion_fr_conceal (picture); else motion_fi_conceal (picture); } else { picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; } if (macroblock_modes & DCT_TYPE_INTERLACED) { DCT_offset = picture->pitches[0]; DCT_stride = picture->pitches[0] * 2; } else { DCT_offset = picture->pitches[0] * 8; DCT_stride = picture->pitches[0]; } offset = picture->offset; dest_y = picture->dest[0] + offset; // unravaled loop of 6 block(i) calls in macroblock() slice_xvmc_intra_DCT (picture, 0, dest_y, DCT_stride); slice_xvmc_intra_DCT (picture, 0, dest_y + 8, DCT_stride); slice_xvmc_intra_DCT (picture, 0, dest_y + DCT_offset, DCT_stride); slice_xvmc_intra_DCT (picture, 0, dest_y + DCT_offset + 8, DCT_stride); slice_xvmc_intra_DCT (picture, 1, picture->dest[1] + (offset >> 1), picture->pitches[1]); slice_xvmc_intra_DCT (picture, 2, picture->dest[2] + (offset >> 1), picture->pitches[2]); if (picture->picture_coding_type == D_TYPE) { NEEDBITS (bit_buf, bits, bit_ptr); DUMPBITS (bit_buf, bits, 1); } } else { picture->XvMC_cbp = 0; if (picture->picture_structure == FRAME_PICTURE) switch (macroblock_modes & MOTION_TYPE_MASK) { case MC_FRAME: if (picture->mpeg1) { MOTION_CALL (motion_mp1, macroblock_modes); } else { MOTION_CALL (motion_fr_frame, macroblock_modes); } break; case MC_FIELD: //MOTION_CALL (motion_fr_field, macroblock_modes); if ((macroblock_modes) & MACROBLOCK_MOTION_FORWARD) motion_fr_field(picture, &(picture->f_motion), mpeg2_mc.put,0); if ((macroblock_modes) & MACROBLOCK_MOTION_BACKWARD) motion_fr_field(picture, &(picture->b_motion), ((macroblock_modes) & MACROBLOCK_MOTION_FORWARD ? mpeg2_mc.avg : mpeg2_mc.put),1); break; case MC_DMV: MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); break; case 0: /* non-intra mb without forward mv in a P picture */ picture->f_motion.pmv[0][0] = 0; picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = 0; picture->f_motion.pmv[1][1] = 0; // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); break; } else switch (macroblock_modes & MOTION_TYPE_MASK) { case MC_FIELD: MOTION_CALL (motion_fi_field, macroblock_modes); break; case MC_16X8: MOTION_CALL (motion_fi_16x8, macroblock_modes); break; case MC_DMV: MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); break; case 0: /* non-intra mb without forward mv in a P picture */ picture->f_motion.pmv[0][0] = 0; picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = 0; picture->f_motion.pmv[1][1] = 0; // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); break; } if (macroblock_modes & MACROBLOCK_PATTERN) { int coded_block_pattern; int DCT_offset, DCT_stride; int offset; uint8_t * dest_y; if (macroblock_modes & DCT_TYPE_INTERLACED) { DCT_offset = picture->pitches[0]; DCT_stride = picture->pitches[0] * 2; } else { DCT_offset = picture->pitches[0] * 8; DCT_stride = picture->pitches[0]; } picture->XvMC_cbp = coded_block_pattern = get_xvmc_coded_block_pattern (picture); offset = picture->offset; dest_y = picture->dest[0] + offset; // TODO optimize not fully used for idct accel only mc. if (coded_block_pattern & 0x20) slice_xvmc_non_intra_DCT (picture, dest_y, DCT_stride); // cc0 luma 0 if (coded_block_pattern & 0x10) slice_xvmc_non_intra_DCT (picture, dest_y + 8, DCT_stride); // cc0 luma 1 if (coded_block_pattern & 0x08) slice_xvmc_non_intra_DCT (picture, dest_y + DCT_offset, DCT_stride); // cc0 luma 2 if (coded_block_pattern & 0x04) slice_xvmc_non_intra_DCT (picture, dest_y + DCT_offset + 8, DCT_stride); // cc0 luma 3 if (coded_block_pattern & 0x2) slice_xvmc_non_intra_DCT (picture, picture->dest[1] + (offset >> 1), picture->pitches[1]); // cc1 croma if (coded_block_pattern & 0x1) slice_xvmc_non_intra_DCT (picture, picture->dest[2] + (offset >> 1), picture->pitches[2]); // cc2 croma } if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && !(picture->mc->xvmc_accel & SIGNED_INTRA)) { // original: picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; } else { // MOTION_ACCEL+SIGNED_INTRA picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 0; } } xvmc->proc_macro_block(picture->XvMC_x, picture->XvMC_y, picture->XvMC_mb_type, picture->XvMC_motion_type, picture->XvMC_mv_field_sel, picture->XvMC_dmvector, picture->XvMC_cbp, picture->XvMC_dct_type, picture->current_frame, picture->forward_reference_frame, picture->backward_reference_frame, picture->picture_structure, picture->second_field, picture->f_motion.pmv, picture->b_motion.pmv); NEXT_MACROBLOCK; NEEDBITS (bit_buf, bits, bit_ptr); mba_inc = 0; while (1) { if (bit_buf >= 0x10000000) { mba = MBA_5 + (UBITS (bit_buf, 5) - 2); break; } else if (bit_buf >= 0x03000000) { mba = MBA_11 + (UBITS (bit_buf, 11) - 24); break; } else switch (UBITS (bit_buf, 11)) { case 8: /* macroblock_escape */ mba_inc += 33; /* fall through */ case 15: /* macroblock_stuffing (MPEG1 only) */ DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; default: /* end of slice, or error */ if (mpeg2_cpu_state_restore) mpeg2_cpu_state_restore (&cpu_state); accel->xvmc_last_slice_code = code; return; } } DUMPBITS (bit_buf, bits, mba->len); mba_inc += mba->mba; if (mba_inc) { //TODO conversion to signed format signed format if((picture->mc->xvmc_accel & ACCEL) == MOTION_ACCEL && !(picture->mc->xvmc_accel & SIGNED_INTRA)) { // original: picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; } else { // MOTION_ACCEL+SIGNED_INTRA picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 0; } picture->XvMC_cbp = 0; if (picture->picture_coding_type == P_TYPE) { picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; do { if(picture->mc->xvmc_accel) { /* derive motion_type */ if(picture->picture_structure == FRAME_PICTURE) { picture->XvMC_motion_type = XINE_MC_FRAME; } else { picture->XvMC_motion_type = XINE_MC_FIELD; /* predict from field of same parity */ picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[0][1] = (picture->picture_structure==BOTTOM_FIELD); } picture->XvMC_mb_type = macroblock_modes & 0x1E; picture->XvMC_x = picture->offset/16; picture->XvMC_y = picture->v_offset/16; xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y, picture->XvMC_mb_type, picture->XvMC_motion_type, picture->XvMC_mv_field_sel, picture->XvMC_dmvector, picture->XvMC_cbp, picture->XvMC_dct_type, picture->current_frame, picture->forward_reference_frame, picture->backward_reference_frame, picture->picture_structure, picture->second_field, picture->f_motion.pmv, picture->b_motion.pmv); } else { // MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); } NEXT_MACROBLOCK; } while (--mba_inc); } else { do { if(picture->mc->xvmc_accel) { /* derive motion_type */ if(picture->picture_structure == FRAME_PICTURE) { picture->XvMC_motion_type = XINE_MC_FRAME; } else { picture->XvMC_motion_type = XINE_MC_FIELD; /* predict from field of same parity */ picture->XvMC_mv_field_sel[0][0] = picture->XvMC_mv_field_sel[0][1] = (picture->picture_structure==BOTTOM_FIELD); } picture->XvMC_mb_type = macroblock_modes & 0x1E; picture->XvMC_x = picture->offset/16; picture->XvMC_y = picture->v_offset/16; xvmc->proc_macro_block(picture->XvMC_x,picture->XvMC_y, picture->XvMC_mb_type, picture->XvMC_motion_type, picture->XvMC_mv_field_sel, picture->XvMC_dmvector, picture->XvMC_cbp, picture->XvMC_dct_type, picture->current_frame, picture->forward_reference_frame, picture->backward_reference_frame, picture->picture_structure, picture->second_field, picture->f_motion.pmv, picture->b_motion.pmv); } else { //MOTION_CALL (motion_reuse, macroblock_modes); } NEXT_MACROBLOCK; } while (--mba_inc); } } } accel->xvmc_last_slice_code = code; #undef bit_buf #undef bits #undef bit_ptr } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/vlc.h�����������������������������������������������������������0000644�0001750�0001750�00000041616�14647725152�016042� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * vlc.h * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #define GETWORD(bit_buf,shift,bit_ptr) \ do { \ bit_buf |= ((bit_ptr[0] << 8) | bit_ptr[1]) << (shift); \ bit_ptr += 2; \ } while (0) static inline void bitstream_init (picture_t * picture, uint8_t * start) { picture->bitstream_buf = (start[0] << 24) | (start[1] << 16) | (start[2] << 8) | start[3]; picture->bitstream_ptr = start + 4; picture->bitstream_bits = -16; } /* make sure that there are at least 16 valid bits in bit_buf */ #define NEEDBITS(bit_buf,bits,bit_ptr) \ do { \ if (bits > 0) { \ GETWORD (bit_buf, bits, bit_ptr); \ bits -= 16; \ } \ } while (0) /* remove num valid bits from bit_buf */ #define DUMPBITS(bit_buf,bits,num) \ do { \ bit_buf <<= (num); \ bits += (num); \ } while (0) /* take num bits from the high part of bit_buf and zero extend them */ #define UBITS(bit_buf,num) (((uint32_t)(bit_buf)) >> (32 - (num))) /* take num bits from the high part of bit_buf and sign extend them */ #define SBITS(bit_buf,num) (((int32_t)(bit_buf)) >> (32 - (num))) typedef struct { uint8_t modes; uint8_t len; } MBtab; typedef struct { uint8_t delta; uint8_t len; } MVtab; typedef struct { int8_t dmv; uint8_t len; } DMVtab; typedef struct { uint8_t cbp; uint8_t len; } CBPtab; typedef struct { uint8_t size; uint8_t len; } DCtab; typedef struct { uint8_t run; uint8_t level; uint8_t len; } DCTtab; typedef struct { uint8_t mba; uint8_t len; } MBAtab; #define INTRA MACROBLOCK_INTRA #define QUANT MACROBLOCK_QUANT static const MBtab MB_I [] = { {INTRA|QUANT, 2}, {INTRA, 1} }; #define MC MACROBLOCK_MOTION_FORWARD #define CODED MACROBLOCK_PATTERN static const MBtab MB_P [] = { {INTRA|QUANT, 6}, {CODED|QUANT, 5}, {MC|CODED|QUANT, 5}, {INTRA, 5}, {MC, 3}, {MC, 3}, {MC, 3}, {MC, 3}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {CODED, 2}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1}, {MC|CODED, 1} }; #define FWD MACROBLOCK_MOTION_FORWARD #define BWD MACROBLOCK_MOTION_BACKWARD #define INTER MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD static const MBtab MB_B [] = { {0, 0}, {INTRA|QUANT, 6}, {BWD|CODED|QUANT, 6}, {FWD|CODED|QUANT, 6}, {INTER|CODED|QUANT, 5}, {INTER|CODED|QUANT, 5}, {INTRA, 5}, {INTRA, 5}, {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {FWD|CODED, 4}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {BWD|CODED, 3}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2}, {INTER|CODED, 2} }; #undef INTRA #undef QUANT #undef MC #undef CODED #undef FWD #undef BWD #undef INTER static const MVtab MV_4 [] = { { 3, 6}, { 2, 4}, { 1, 3}, { 1, 3}, { 0, 2}, { 0, 2}, { 0, 2}, { 0, 2} }; static const MVtab MV_10 [] = { { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, { 0,10}, {15,10}, {14,10}, {13,10}, {12,10}, {11,10}, {10,10}, { 9, 9}, { 9, 9}, { 8, 9}, { 8, 9}, { 7, 9}, { 7, 9}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 6, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 5, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7}, { 4, 7} }; static const DMVtab DMV_2 [] = { { 0, 1}, { 0, 1}, { 1, 2}, {-1, 2} }; static const CBPtab CBP_7 [] = { {0x22, 7}, {0x12, 7}, {0x0a, 7}, {0x06, 7}, {0x21, 7}, {0x11, 7}, {0x09, 7}, {0x05, 7}, {0x3f, 6}, {0x3f, 6}, {0x03, 6}, {0x03, 6}, {0x24, 6}, {0x24, 6}, {0x18, 6}, {0x18, 6}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x3e, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x02, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x3d, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x01, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x38, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x34, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x2c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x1c, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x28, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x14, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x30, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x0c, 5}, {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x20, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x10, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x08, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x04, 4}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3}, {0x3c, 3} }; static const CBPtab CBP_9 [] = { {0, 0}, {0x00, 9}, {0x27, 9}, {0x1b, 9}, {0x3b, 9}, {0x37, 9}, {0x2f, 9}, {0x1f, 9}, {0x3a, 8}, {0x3a, 8}, {0x36, 8}, {0x36, 8}, {0x2e, 8}, {0x2e, 8}, {0x1e, 8}, {0x1e, 8}, {0x39, 8}, {0x39, 8}, {0x35, 8}, {0x35, 8}, {0x2d, 8}, {0x2d, 8}, {0x1d, 8}, {0x1d, 8}, {0x26, 8}, {0x26, 8}, {0x1a, 8}, {0x1a, 8}, {0x25, 8}, {0x25, 8}, {0x19, 8}, {0x19, 8}, {0x2b, 8}, {0x2b, 8}, {0x17, 8}, {0x17, 8}, {0x33, 8}, {0x33, 8}, {0x0f, 8}, {0x0f, 8}, {0x2a, 8}, {0x2a, 8}, {0x16, 8}, {0x16, 8}, {0x32, 8}, {0x32, 8}, {0x0e, 8}, {0x0e, 8}, {0x29, 8}, {0x29, 8}, {0x15, 8}, {0x15, 8}, {0x31, 8}, {0x31, 8}, {0x0d, 8}, {0x0d, 8}, {0x23, 8}, {0x23, 8}, {0x13, 8}, {0x13, 8}, {0x0b, 8}, {0x0b, 8}, {0x07, 8}, {0x07, 8} }; static const DCtab DC_lum_5 [] = { {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5} }; static const DCtab DC_chrom_5 [] = { {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 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}, {4, 4}, {4, 4}, {5, 5} }; static const DCtab DC_long [] = { {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, {6, 5}, { 6, 5}, { 6, 5}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, { 7, 6}, { 7, 6}, {8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10, 9}, {11, 9} }; static const DCTtab DCT_16 [] = { {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, {129, 0, 0}, { 2,18, 0}, { 2,17, 0}, { 2,16, 0}, { 2,15, 0}, { 7, 3, 0}, { 17, 2, 0}, { 16, 2, 0}, { 15, 2, 0}, { 14, 2, 0}, { 13, 2, 0}, { 12, 2, 0}, { 32, 1, 0}, { 31, 1, 0}, { 30, 1, 0}, { 29, 1, 0}, { 28, 1, 0} }; static const DCTtab DCT_15 [] = { { 1,40,15}, { 1,39,15}, { 1,38,15}, { 1,37,15}, { 1,36,15}, { 1,35,15}, { 1,34,15}, { 1,33,15}, { 1,32,15}, { 2,14,15}, { 2,13,15}, { 2,12,15}, { 2,11,15}, { 2,10,15}, { 2, 9,15}, { 2, 8,15}, { 1,31,14}, { 1,31,14}, { 1,30,14}, { 1,30,14}, { 1,29,14}, { 1,29,14}, { 1,28,14}, { 1,28,14}, { 1,27,14}, { 1,27,14}, { 1,26,14}, { 1,26,14}, { 1,25,14}, { 1,25,14}, { 1,24,14}, { 1,24,14}, { 1,23,14}, { 1,23,14}, { 1,22,14}, { 1,22,14}, { 1,21,14}, { 1,21,14}, { 1,20,14}, { 1,20,14}, { 1,19,14}, { 1,19,14}, { 1,18,14}, { 1,18,14}, { 1,17,14}, { 1,17,14}, { 1,16,14}, { 1,16,14} }; static const DCTtab DCT_13 [] = { { 11, 2,13}, { 10, 2,13}, { 6, 3,13}, { 4, 4,13}, { 3, 5,13}, { 2, 7,13}, { 2, 6,13}, { 1,15,13}, { 1,14,13}, { 1,13,13}, { 1,12,13}, { 27, 1,13}, { 26, 1,13}, { 25, 1,13}, { 24, 1,13}, { 23, 1,13}, { 1,11,12}, { 1,11,12}, { 9, 2,12}, { 9, 2,12}, { 5, 3,12}, { 5, 3,12}, { 1,10,12}, { 1,10,12}, { 3, 4,12}, { 3, 4,12}, { 8, 2,12}, { 8, 2,12}, { 22, 1,12}, { 22, 1,12}, { 21, 1,12}, { 21, 1,12}, { 1, 9,12}, { 1, 9,12}, { 20, 1,12}, { 20, 1,12}, { 19, 1,12}, { 19, 1,12}, { 2, 5,12}, { 2, 5,12}, { 4, 3,12}, { 4, 3,12}, { 1, 8,12}, { 1, 8,12}, { 7, 2,12}, { 7, 2,12}, { 18, 1,12}, { 18, 1,12} }; static const DCTtab DCT_B14_10 [] = { { 17, 1,10}, { 6, 2,10}, { 1, 7,10}, { 3, 3,10}, { 2, 4,10}, { 16, 1,10}, { 15, 1,10}, { 5, 2,10} }; static const DCTtab DCT_B14_8 [] = { { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 3, 2, 7}, { 3, 2, 7}, { 10, 1, 7}, { 10, 1, 7}, { 1, 4, 7}, { 1, 4, 7}, { 9, 1, 7}, { 9, 1, 7}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 8, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 7, 1, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 2, 2, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 14, 1, 8}, { 1, 6, 8}, { 13, 1, 8}, { 12, 1, 8}, { 4, 2, 8}, { 2, 3, 8}, { 1, 5, 8}, { 11, 1, 8} }; static const DCTtab DCT_B14AC_5 [] = { { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, {129, 0, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2} }; static const DCTtab DCT_B14DC_5 [] = { { 1, 3, 5}, { 5, 1, 5}, { 4, 1, 5}, { 1, 2, 4}, { 1, 2, 4}, { 3, 1, 4}, { 3, 1, 4}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 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} }; static const DCTtab DCT_B15_10 [] = { { 6, 2, 9}, { 6, 2, 9}, { 15, 1, 9}, { 15, 1, 9}, { 3, 4,10}, { 17, 1,10}, { 16, 1, 9}, { 16, 1, 9} }; static const DCTtab DCT_B15_8 [] = { { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 65, 0, 6}, { 8, 1, 7}, { 8, 1, 7}, { 9, 1, 7}, { 9, 1, 7}, { 7, 1, 7}, { 7, 1, 7}, { 3, 2, 7}, { 3, 2, 7}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 7, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 1, 6, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 5, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 6, 1, 6}, { 2, 5, 8}, { 12, 1, 8}, { 1,11, 8}, { 1,10, 8}, { 14, 1, 8}, { 13, 1, 8}, { 4, 2, 8}, { 2, 4, 8}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 3, 1, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 2, 2, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 4, 1, 5}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, { 2, 1, 3}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, {129, 0, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 3, 4}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 1, 2}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 2, 3}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 4, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 1, 5, 5}, { 10, 1, 7}, { 10, 1, 7}, { 2, 3, 7}, { 2, 3, 7}, { 11, 1, 7}, { 11, 1, 7}, { 1, 8, 7}, { 1, 8, 7}, { 1, 9, 7}, { 1, 9, 7}, { 1,12, 8}, { 1,13, 8}, { 3, 3, 8}, { 5, 2, 8}, { 1,14, 8}, { 1,15, 8} }; static const MBAtab MBA_5 [] = { {6, 5}, {5, 5}, {4, 4}, {4, 4}, {3, 4}, {3, 4}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {1, 3}, {1, 3}, {1, 3}, {1, 3}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1}, {0, 1} }; static const MBAtab MBA_11 [] = { {32, 11}, {31, 11}, {30, 11}, {29, 11}, {28, 11}, {27, 11}, {26, 11}, {25, 11}, {24, 11}, {23, 11}, {22, 11}, {21, 11}, {20, 10}, {20, 10}, {19, 10}, {19, 10}, {18, 10}, {18, 10}, {17, 10}, {17, 10}, {16, 10}, {16, 10}, {15, 10}, {15, 10}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {14, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {13, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {12, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {11, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, {10, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 9, 8}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 7}, { 8, 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} }; ������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/motion_comp_mmx.c�����������������������������������������������0000644�0001750�0001750�00000060435�14647725152�020455� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_mmx.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #if defined(ARCH_X86) || defined(ARCH_X86_64) #include <inttypes.h> #include "mpeg2_internal.h" #include <xine/xineutils.h> #include "xine_mmx.h" #define CPU_MMXEXT 0 #define CPU_3DNOW 1 /* MMX code - needs a rewrite */ /* some rounding constants */ static mmx_t round1 = {0x0001000100010001LL}; static mmx_t round4 = {0x0002000200020002LL}; /* * This code should probably be compiled with loop unrolling * (ie, -funroll-loops in gcc)becuase some of the loops * use a small static number of iterations. This was written * with the assumption the compiler knows best about when * unrolling will help */ static inline void mmx_zero_reg () { /* load 0 into mm0 */ pxor_r2r (mm0, mm0); } static inline void mmx_average_2_U8 (uint8_t * dest, uint8_t * src1, uint8_t * src2) { /* *dest = (*src1 + *src2 + 1)/ 2; */ movq_m2r (*src1, mm1); // load 8 src1 bytes movq_r2r (mm1, mm2); // copy 8 src1 bytes movq_m2r (*src2, mm3); // load 8 src2 bytes movq_r2r (mm3, mm4); // copy 8 src2 bytes punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes paddw_r2r (mm3, mm1); // add lows to mm1 paddw_m2r (round1, mm1); psraw_i2r (1, mm1); // /2 paddw_r2r (mm4, mm2); // add highs to mm2 paddw_m2r (round1, mm2); psraw_i2r (1, mm2); // /2 packuswb_r2r (mm2, mm1); // pack (w/ saturation) movq_r2m (mm1, *dest); // store result in dest } static inline void mmx_interp_average_2_U8 (uint8_t * dest, uint8_t * src1, uint8_t * src2) { /* *dest = (*dest + (*src1 + *src2 + 1)/ 2 + 1)/ 2; */ movq_m2r (*dest, mm1); // load 8 dest bytes movq_r2r (mm1, mm2); // copy 8 dest bytes movq_m2r (*src1, mm3); // load 8 src1 bytes movq_r2r (mm3, mm4); // copy 8 src1 bytes movq_m2r (*src2, mm5); // load 8 src2 bytes movq_r2r (mm5, mm6); // copy 8 src2 bytes punpcklbw_r2r (mm0, mm1); // unpack low dest bytes punpckhbw_r2r (mm0, mm2); // unpack high dest bytes punpcklbw_r2r (mm0, mm3); // unpack low src1 bytes punpckhbw_r2r (mm0, mm4); // unpack high src1 bytes punpcklbw_r2r (mm0, mm5); // unpack low src2 bytes punpckhbw_r2r (mm0, mm6); // unpack high src2 bytes paddw_r2r (mm5, mm3); // add lows paddw_m2r (round1, mm3); psraw_i2r (1, mm3); // /2 paddw_r2r (mm6, mm4); // add highs paddw_m2r (round1, mm4); psraw_i2r (1, mm4); // /2 paddw_r2r (mm3, mm1); // add lows paddw_m2r (round1, mm1); psraw_i2r (1, mm1); // /2 paddw_r2r (mm4, mm2); // add highs paddw_m2r (round1, mm2); psraw_i2r (1, mm2); // /2 packuswb_r2r (mm2, mm1); // pack (w/ saturation) movq_r2m (mm1, *dest); // store result in dest } static inline void mmx_average_4_U8 (uint8_t * dest, uint8_t * src1, uint8_t * src2, uint8_t * src3, uint8_t * src4) { /* *dest = (*src1 + *src2 + *src3 + *src4 + 2)/ 4; */ movq_m2r (*src1, mm1); // load 8 src1 bytes movq_r2r (mm1, mm2); // copy 8 src1 bytes punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes movq_m2r (*src2, mm3); // load 8 src2 bytes movq_r2r (mm3, mm4); // copy 8 src2 bytes punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes paddw_r2r (mm3, mm1); // add lows paddw_r2r (mm4, mm2); // add highs /* now have partials in mm1 and mm2 */ movq_m2r (*src3, mm3); // load 8 src3 bytes movq_r2r (mm3, mm4); // copy 8 src3 bytes punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes paddw_r2r (mm3, mm1); // add lows paddw_r2r (mm4, mm2); // add highs movq_m2r (*src4, mm5); // load 8 src4 bytes movq_r2r (mm5, mm6); // copy 8 src4 bytes punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes paddw_r2r (mm5, mm1); // add lows paddw_r2r (mm6, mm2); // add highs /* now have subtotal in mm1 and mm2 */ paddw_m2r (round4, mm1); psraw_i2r (2, mm1); // /4 paddw_m2r (round4, mm2); psraw_i2r (2, mm2); // /4 packuswb_r2r (mm2, mm1); // pack (w/ saturation) movq_r2m (mm1, *dest); // store result in dest } static inline void mmx_interp_average_4_U8 (uint8_t * dest, uint8_t * src1, uint8_t * src2, uint8_t * src3, uint8_t * src4) { /* *dest = (*dest + (*src1 + *src2 + *src3 + *src4 + 2)/ 4 + 1)/ 2; */ movq_m2r (*src1, mm1); // load 8 src1 bytes movq_r2r (mm1, mm2); // copy 8 src1 bytes punpcklbw_r2r (mm0, mm1); // unpack low src1 bytes punpckhbw_r2r (mm0, mm2); // unpack high src1 bytes movq_m2r (*src2, mm3); // load 8 src2 bytes movq_r2r (mm3, mm4); // copy 8 src2 bytes punpcklbw_r2r (mm0, mm3); // unpack low src2 bytes punpckhbw_r2r (mm0, mm4); // unpack high src2 bytes paddw_r2r (mm3, mm1); // add lows paddw_r2r (mm4, mm2); // add highs /* now have partials in mm1 and mm2 */ movq_m2r (*src3, mm3); // load 8 src3 bytes movq_r2r (mm3, mm4); // copy 8 src3 bytes punpcklbw_r2r (mm0, mm3); // unpack low src3 bytes punpckhbw_r2r (mm0, mm4); // unpack high src3 bytes paddw_r2r (mm3, mm1); // add lows paddw_r2r (mm4, mm2); // add highs movq_m2r (*src4, mm5); // load 8 src4 bytes movq_r2r (mm5, mm6); // copy 8 src4 bytes punpcklbw_r2r (mm0, mm5); // unpack low src4 bytes punpckhbw_r2r (mm0, mm6); // unpack high src4 bytes paddw_r2r (mm5, mm1); // add lows paddw_r2r (mm6, mm2); // add highs paddw_m2r (round4, mm1); psraw_i2r (2, mm1); // /4 paddw_m2r (round4, mm2); psraw_i2r (2, mm2); // /4 /* now have subtotal/4 in mm1 and mm2 */ movq_m2r (*dest, mm3); // load 8 dest bytes movq_r2r (mm3, mm4); // copy 8 dest bytes punpcklbw_r2r (mm0, mm3); // unpack low dest bytes punpckhbw_r2r (mm0, mm4); // unpack high dest bytes paddw_r2r (mm3, mm1); // add lows paddw_r2r (mm4, mm2); // add highs paddw_m2r (round1, mm1); psraw_i2r (1, mm1); // /2 paddw_m2r (round1, mm2); psraw_i2r (1, mm2); // /2 /* now have end value in mm1 and mm2 */ packuswb_r2r (mm2, mm1); // pack (w/ saturation) movq_r2m (mm1,*dest); // store result in dest } /*-----------------------------------------------------------------------*/ static inline void MC_avg_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { mmx_zero_reg (); do { mmx_average_2_U8 (dest, dest, ref); if (width == 16) mmx_average_2_U8 (dest+8, dest+8, ref+8); dest += stride; ref += stride; } while (--height); } static void MC_avg_o_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_mmx (16, height, dest, ref, stride); } static void MC_avg_o_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { mmx_zero_reg (); do { movq_m2r (* ref, mm1); // load 8 ref bytes movq_r2m (mm1,* dest); // store 8 bytes at curr if (width == 16) { movq_m2r (* (ref+8), mm1); // load 8 ref bytes movq_r2m (mm1,* (dest+8)); // store 8 bytes at curr } dest += stride; ref += stride; } while (--height); } static void MC_put_o_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_mmx (16, height, dest, ref, stride); } static void MC_put_o_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ /* Half pixel interpolation in the x direction */ static inline void MC_avg_x_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { mmx_zero_reg (); do { mmx_interp_average_2_U8 (dest, ref, ref+1); if (width == 16) mmx_interp_average_2_U8 (dest+8, ref+8, ref+9); dest += stride; ref += stride; } while (--height); } static void MC_avg_x_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_x_mmx (16, height, dest, ref, stride); } static void MC_avg_x_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_x_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_x_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { mmx_zero_reg (); do { mmx_average_2_U8 (dest, ref, ref+1); if (width == 16) mmx_average_2_U8 (dest+8, ref+8, ref+9); dest += stride; ref += stride; } while (--height); } static void MC_put_x_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_x_mmx (16, height, dest, ref, stride); } static void MC_put_x_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_x_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_avg_xy_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { uint8_t * ref_next = ref+stride; mmx_zero_reg (); do { mmx_interp_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); if (width == 16) mmx_interp_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_avg_xy_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_xy_mmx (16, height, dest, ref, stride); } static void MC_avg_xy_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_xy_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_xy_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { uint8_t * ref_next = ref+stride; mmx_zero_reg (); do { mmx_average_4_U8 (dest, ref, ref+1, ref_next, ref_next+1); if (width == 16) mmx_average_4_U8 (dest+8, ref+8, ref+9, ref_next+8, ref_next+9); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_put_xy_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_xy_mmx (16, height, dest, ref, stride); } static void MC_put_xy_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_xy_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_avg_y_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { uint8_t * ref_next = ref+stride; mmx_zero_reg (); do { mmx_interp_average_2_U8 (dest, ref, ref_next); if (width == 16) mmx_interp_average_2_U8 (dest+8, ref+8, ref_next+8); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_avg_y_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_y_mmx (16, height, dest, ref, stride); } static void MC_avg_y_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg_y_mmx (8, height, dest, ref, stride); } /*-----------------------------------------------------------------------*/ static inline void MC_put_y_mmx (int width, int height, uint8_t * dest, uint8_t * ref, int stride) { uint8_t * ref_next = ref+stride; mmx_zero_reg (); do { mmx_average_2_U8 (dest, ref, ref_next); if (width == 16) mmx_average_2_U8 (dest+8, ref+8, ref_next+8); dest += stride; ref += stride; ref_next += stride; } while (--height); } static void MC_put_y_16_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_y_mmx (16, height, dest, ref, stride); } static void MC_put_y_8_mmx (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put_y_mmx (8, height, dest, ref, stride); } MPEG2_MC_EXTERN (mmx) /* CPU_MMXEXT/CPU_3DNOW adaptation layer */ #define pavg_r2r(src,dest) \ do { \ if (cpu == CPU_MMXEXT) \ pavgb_r2r (src, dest); \ else \ pavgusb_r2r (src, dest); \ } while (0) #define pavg_m2r(src,dest) \ do { \ if (cpu == CPU_MMXEXT) \ pavgb_m2r (src, dest); \ else \ pavgusb_m2r (src, dest); \ } while (0) /* CPU_MMXEXT code */ static inline void MC_put1_8 (int height, uint8_t * dest, uint8_t * ref, int stride) { do { movq_m2r (*ref, mm0); movq_r2m (mm0, *dest); ref += stride; dest += stride; } while (--height); } static inline void MC_put1_16 (int height, uint8_t * dest, uint8_t * ref, int stride) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); ref += stride; movq_r2m (mm0, *dest); movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static inline void MC_avg1_8 (int height, uint8_t * dest, uint8_t * ref, int stride, int cpu) { do { movq_m2r (*ref, mm0); pavg_m2r (*dest, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_avg1_16 (int height, uint8_t * dest, uint8_t * ref, int stride, int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); pavg_m2r (*dest, mm0); pavg_m2r (*(dest+8), mm1); movq_r2m (mm0, *dest); ref += stride; movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static inline void MC_put2_8 (int height, uint8_t * dest, uint8_t * ref, int stride, int offset, int cpu) { do { movq_m2r (*ref, mm0); pavg_m2r (*(ref+offset), mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_put2_16 (int height, uint8_t * dest, uint8_t * ref, int stride, int offset, int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); pavg_m2r (*(ref+offset), mm0); pavg_m2r (*(ref+offset+8), mm1); movq_r2m (mm0, *dest); ref += stride; movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static inline void MC_avg2_8 (int height, uint8_t * dest, uint8_t * ref, int stride, int offset, int cpu) { do { movq_m2r (*ref, mm0); pavg_m2r (*(ref+offset), mm0); pavg_m2r (*dest, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_avg2_16 (int height, uint8_t * dest, uint8_t * ref, int stride, int offset, int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+8), mm1); pavg_m2r (*(ref+offset), mm0); pavg_m2r (*(ref+offset+8), mm1); pavg_m2r (*dest, mm0); pavg_m2r (*(dest+8), mm1); ref += stride; movq_r2m (mm0, *dest); movq_r2m (mm1, *(dest+8)); dest += stride; } while (--height); } static mmx_t mask_one = {0x0101010101010101LL}; static inline void MC_put4_8 (int height, uint8_t * dest, uint8_t * ref, int stride, int cpu) { movq_m2r (*ref, mm0); movq_m2r (*(ref+1), mm1); movq_r2r (mm0, mm7); pxor_r2r (mm1, mm7); pavg_r2r (mm1, mm0); ref += stride; do { movq_m2r (*ref, mm2); movq_r2r (mm0, mm5); movq_m2r (*(ref+1), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); pxor_r2r (mm2, mm5); pand_r2r (mm5, mm7); pavg_r2r (mm2, mm0); pand_m2r (mask_one, mm7); psubusb_r2r (mm7, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; movq_r2r (mm6, mm7); // unroll ! movq_r2r (mm2, mm0); // unroll ! } while (--height); } static inline void MC_put4_16 (int height, uint8_t * dest, uint8_t * ref, int stride, int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+stride+1), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+1), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_r2m (mm0, *dest); movq_m2r (*(ref+8), mm0); movq_m2r (*(ref+stride+9), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+9), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride+8), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); ref += stride; movq_r2m (mm0, *(dest+8)); dest += stride; } while (--height); } static inline void MC_avg4_8 (int height, uint8_t * dest, uint8_t * ref, int stride, int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+stride+1), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+1), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_m2r (*dest, mm1); pavg_r2r (mm1, mm0); ref += stride; movq_r2m (mm0, *dest); dest += stride; } while (--height); } static inline void MC_avg4_16 (int height, uint8_t * dest, uint8_t * ref, int stride, int cpu) { do { movq_m2r (*ref, mm0); movq_m2r (*(ref+stride+1), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+1), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_m2r (*dest, mm1); pavg_r2r (mm1, mm0); movq_r2m (mm0, *dest); movq_m2r (*(ref+8), mm0); movq_m2r (*(ref+stride+9), mm1); movq_r2r (mm0, mm7); movq_m2r (*(ref+9), mm2); pxor_r2r (mm1, mm7); movq_m2r (*(ref+stride+8), mm3); movq_r2r (mm2, mm6); pxor_r2r (mm3, mm6); pavg_r2r (mm1, mm0); pavg_r2r (mm3, mm2); por_r2r (mm6, mm7); movq_r2r (mm0, mm6); pxor_r2r (mm2, mm6); pand_r2r (mm6, mm7); pand_m2r (mask_one, mm7); pavg_r2r (mm2, mm0); psubusb_r2r (mm7, mm0); movq_m2r (*(dest+8), mm1); pavg_r2r (mm1, mm0); ref += stride; movq_r2m (mm0, *(dest+8)); dest += stride; } while (--height); } static void MC_avg_o_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg1_16 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_avg_o_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg1_8 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_put_o_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put1_16 (height, dest, ref, stride); } static void MC_put_o_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put1_8 (height, dest, ref, stride); } static void MC_avg_x_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_avg_x_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_put_x_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_put_x_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, 1, CPU_MMXEXT); } static void MC_avg_y_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_avg_y_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_put_y_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_put_y_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, stride, CPU_MMXEXT); } static void MC_avg_xy_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg4_16 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_avg_xy_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg4_8 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_put_xy_16_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put4_16 (height, dest, ref, stride, CPU_MMXEXT); } static void MC_put_xy_8_mmxext (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put4_8 (height, dest, ref, stride, CPU_MMXEXT); } MPEG2_MC_EXTERN (mmxext) static void MC_avg_o_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg1_16 (height, dest, ref, stride, CPU_3DNOW); } static void MC_avg_o_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg1_8 (height, dest, ref, stride, CPU_3DNOW); } static void MC_put_o_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put1_16 (height, dest, ref, stride); } static void MC_put_o_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put1_8 (height, dest, ref, stride); } static void MC_avg_x_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_avg_x_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_put_x_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_put_x_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, 1, CPU_3DNOW); } static void MC_avg_y_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_16 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_avg_y_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg2_8 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_put_y_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_16 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_put_y_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put2_8 (height, dest, ref, stride, stride, CPU_3DNOW); } static void MC_avg_xy_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg4_16 (height, dest, ref, stride, CPU_3DNOW); } static void MC_avg_xy_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_avg4_8 (height, dest, ref, stride, CPU_3DNOW); } static void MC_put_xy_16_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put4_16 (height, dest, ref, stride, CPU_3DNOW); } static void MC_put_xy_8_3dnow (uint8_t * dest, uint8_t * ref, int stride, int height) { MC_put4_8 (height, dest, ref, stride, CPU_3DNOW); } MPEG2_MC_EXTERN (3dnow) #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/idct_mlib.c�����������������������������������������������������0000644�0001750�0001750�00000003533�14647725152�017173� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_mlib.c * Copyright (C) 1999-2002 Håkan Hjort <d95hjort@dtek.chalmers.se> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #ifdef LIBMPEG2_MLIB #include <mlib_types.h> #include <mlib_status.h> #include <mlib_sys.h> #include <mlib_video.h> #include <string.h> #include <inttypes.h> #include "mpeg2_internal.h" void mpeg2_idct_add_mlib (int16_t * block, uint8_t * dest, int stride) { mlib_VideoIDCT_IEEE_S16_S16 (block, block); mlib_VideoAddBlock_U8_S16 (dest, block, stride); memset (block, 0, 64 * sizeof (uint16_t)); } void mpeg2_idct_copy_mlib_non_ieee (int16_t * block, uint8_t * dest, int stride) { mlib_VideoIDCT8x8_U8_S16 (dest, block, stride); memset (block, 0, 64 * sizeof (uint16_t)); } void mpeg2_idct_add_mlib_non_ieee (int16_t * block, uint8_t * dest, int stride) { mlib_VideoIDCT8x8_S16_S16 (block, block); mlib_VideoAddBlock_U8_S16 (dest, block, stride); memset (block, 0, 64 * sizeof (uint16_t)); } void mpeg2_idct_mlib (int16_t * block) { mlib_VideoIDCT_IEEE_S16_S16 (block, block); } #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/motion_comp.c���������������������������������������������������0000644�0001750�0001750�00000010234�14647725152�017564� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include <stdio.h> #include <inttypes.h> #include "mpeg2_internal.h" #include <xine/xineutils.h> mpeg2_mc_t mpeg2_mc; void mpeg2_mc_init (uint32_t mm_accel) { #ifdef LIBMPEG2_MLIB if (mm_accel & MM_ACCEL_MLIB) { #ifdef LOG fprintf (stderr, "Using mediaLib for motion compensation\n"); #endif mpeg2_mc = mpeg2_mc_mlib; } #endif #if defined(ARCH_X86) || defined(ARCH_X86_64) if (mm_accel & MM_ACCEL_X86_MMXEXT) { #ifdef LOG fprintf (stderr, "Using MMXEXT for motion compensation\n"); #endif mpeg2_mc = mpeg2_mc_mmxext; } else if (mm_accel & MM_ACCEL_X86_3DNOW) { #ifdef LOG fprintf (stderr, "Using 3DNOW for motion compensation\n"); #endif mpeg2_mc = mpeg2_mc_3dnow; } else if (mm_accel & MM_ACCEL_X86_MMX) { #ifdef LOG fprintf (stderr, "Using MMX for motion compensation\n"); #endif mpeg2_mc = mpeg2_mc_mmx; } else #endif #if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { #ifdef LOG fprintf (stderr, "Using altivec for motion compensation\n"); #endif mpeg2_mc = mpeg2_mc_altivec; } else #endif #if defined(ARCH_SPARC) && defined(ENABLE_VIS) if (mm_accel & MM_ACCEL_SPARC_VIS) { #ifdef LOG fprintf (stderr, "Using VIS for motion compensation\n"); #endif mpeg2_mc = mpeg2_mc_vis; } else #endif { #ifdef LOG fprintf (stderr, "No accelerated motion compensation found\n"); #endif mpeg2_mc = mpeg2_mc_c; } } #define avg2(a,b) ((a+b+1)>>1) #define avg4(a,b,c,d) ((a+b+c+d+2)>>2) #define predict_o(i) (ref[i]) #define predict_x(i) (avg2 (ref[i], ref[i+1])) #define predict_y(i) (avg2 (ref[i], (ref+stride)[i])) #define predict_xy(i) (avg4 (ref[i], ref[i+1], \ (ref+stride)[i], (ref+stride)[i+1])) #define put(predictor,i) dest[i] = predictor (i) #define avg(predictor,i) dest[i] = avg2 (predictor (i), dest[i]) /* mc function template */ #define MC_FUNC(op,xy) \ static void MC_##op##_##xy##_16_c (uint8_t * dest, uint8_t * ref, \ int stride, int height) \ { \ do { \ op (predict_##xy, 0); \ op (predict_##xy, 1); \ op (predict_##xy, 2); \ op (predict_##xy, 3); \ op (predict_##xy, 4); \ op (predict_##xy, 5); \ op (predict_##xy, 6); \ op (predict_##xy, 7); \ op (predict_##xy, 8); \ op (predict_##xy, 9); \ op (predict_##xy, 10); \ op (predict_##xy, 11); \ op (predict_##xy, 12); \ op (predict_##xy, 13); \ op (predict_##xy, 14); \ op (predict_##xy, 15); \ ref += stride; \ dest += stride; \ } while (--height); \ } \ static void MC_##op##_##xy##_8_c (uint8_t * dest, uint8_t * ref, \ int stride, int height) \ { \ do { \ op (predict_##xy, 0); \ op (predict_##xy, 1); \ op (predict_##xy, 2); \ op (predict_##xy, 3); \ op (predict_##xy, 4); \ op (predict_##xy, 5); \ op (predict_##xy, 6); \ op (predict_##xy, 7); \ ref += stride; \ dest += stride; \ } while (--height); \ } /* definitions of the actual mc functions */ MC_FUNC (put,o) MC_FUNC (avg,o) MC_FUNC (put,x) MC_FUNC (avg,x) MC_FUNC (put,y) MC_FUNC (avg,y) MC_FUNC (put,xy) MC_FUNC (avg,xy) MPEG2_MC_EXTERN (c) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/libmpeg2_accel.c������������������������������������������������0000644�0001750�0001750�00000014312�14647725152�020072� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * libmpeg2_accel.c * Copyright (C) 2004 The Unichrome Project. * Copyright (C) 2005 Thomas Hellstrom. * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include "mpeg2.h" #include "mpeg2_internal.h" #include "xvmc_vld.h" #include "libmpeg2_accel.h" void libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt) { (void)accel; (void)scan_norm; (void)scan_alt; xvmc_setup_scan_ptable(); } int libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture) { accel->xvmc_last_slice_code=-1; if ( !picture->current_frame ) return 0; if (frame_format == XINE_IMGFMT_XXMC) { xine_xxmc_t *xxmc = (xine_xxmc_t *) picture->current_frame->accel_data; switch(xxmc->acceleration) { case XINE_XVMC_ACCEL_VLD: case XINE_XVMC_ACCEL_IDCT: case XINE_XVMC_ACCEL_MOCOMP: xxmc->proc_xxmc_flush( picture->current_frame ); break; default: break; } } return 0; } int libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture) { (void)accel; switch(frame_format) { case XINE_IMGFMT_XXMC: case XINE_IMGFMT_XVMC: { xine_xvmc_t *xvmc = (xine_xvmc_t *) picture->current_frame->accel_data; picture->mc = xvmc->macroblocks; return 0; } default: break; } return 1; } int libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, double ratio, uint32_t flags) { (void)accel; if (picture->current_frame) { if (XINE_IMGFMT_XXMC == frame_format) { xine_xxmc_t *xxmc = (xine_xxmc_t *) picture->current_frame->accel_data; /* * Make a request for acceleration type and mpeg coding from * the output plugin. */ xxmc->fallback_format = XINE_IMGFMT_YV12; xxmc->acceleration = XINE_XVMC_ACCEL_VLD| XINE_XVMC_ACCEL_IDCT | XINE_XVMC_ACCEL_MOCOMP ; /* * Standard MOCOMP / IDCT XvMC implementation for interlaced streams * is buggy. The bug is inherited from the old XvMC driver. Don't use it until * it has been fixed. (A volunteer ?) */ if ( picture->picture_structure != 3 ) { picture->top_field_first = (picture->picture_structure == 1); xxmc->acceleration &= ~( XINE_XVMC_ACCEL_IDCT | XINE_XVMC_ACCEL_MOCOMP ); } xxmc->mpeg = (picture->mpeg1) ? XINE_XVMC_MPEG_1:XINE_XVMC_MPEG_2; xxmc->proc_xxmc_update_frame (picture->current_frame->driver, picture->current_frame, picture->coded_picture_width, picture->coded_picture_height, ratio, XINE_IMGFMT_XXMC, flags); } } return 0; } void libmpeg2_accel_frame_completion(mpeg2dec_accel_t * accel, uint32_t frame_format, picture_t *picture, int code) { if ( !picture->current_frame ) return; if (frame_format == XINE_IMGFMT_XXMC) { xine_xxmc_t *xxmc = (xine_xxmc_t *) picture->current_frame->accel_data; if (!xxmc->decoded) { switch(picture->current_frame->format) { case XINE_IMGFMT_XXMC: switch(xxmc->acceleration) { case XINE_XVMC_ACCEL_VLD: mpeg2_xxmc_vld_frame_complete(accel, picture, code); break; case XINE_XVMC_ACCEL_IDCT: case XINE_XVMC_ACCEL_MOCOMP: xxmc->decoded = !picture->current_frame->bad_frame; xxmc->proc_xxmc_flush( picture->current_frame ); break; default: break; } default: break; } } } } int libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code, char * buffer, uint32_t chunk_size, uint8_t *chunk_buffer) { /* * Don't reference frames of other formats. They are invalid. This may happen if the * xxmc plugin suddenly falls back to software decoding. */ if (( picture->current_frame->picture_coding_type == XINE_PICT_P_TYPE ) || ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE )) { if (! picture->forward_reference_frame) return 1; if (picture->forward_reference_frame->format != picture->current_frame->format) { picture->v_offset = 0; return 1; } } if ( picture->current_frame->picture_coding_type == XINE_PICT_B_TYPE ) { if (! picture->backward_reference_frame) return 1; if (picture->backward_reference_frame->format != picture->current_frame->format) { picture->v_offset = 0; return 1; } } switch( picture->current_frame->format ) { case XINE_IMGFMT_XXMC: { xine_xxmc_t *xxmc = (xine_xxmc_t *) picture->current_frame->accel_data; if ( xxmc->proc_xxmc_lock_valid( picture->current_frame, picture->forward_reference_frame, picture->backward_reference_frame, picture->current_frame->picture_coding_type)) { picture->v_offset = 0; return 1; } switch(picture->current_frame->format) { case XINE_IMGFMT_XXMC: switch(xxmc->acceleration) { case XINE_XVMC_ACCEL_VLD: mpeg2_xxmc_slice(accel, picture, code, buffer, chunk_size, chunk_buffer); break; case XINE_XVMC_ACCEL_IDCT: case XINE_XVMC_ACCEL_MOCOMP: mpeg2_xvmc_slice (accel, picture, code, buffer); break; default: mpeg2_slice (picture, code, buffer); break; } break; default: mpeg2_slice (picture, code, buffer); break; } xxmc->proc_xxmc_unlock(picture->current_frame->driver); break; } case XINE_IMGFMT_XVMC: mpeg2_xvmc_slice (accel, picture, code, buffer); break; default: mpeg2_slice (picture, code, buffer); break; } return 0; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/xvmc_vld.h������������������������������������������������������0000644�0001750�0001750�00000002205�14647725152�017067� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (c) 2004 The Unichrome project. All rights reserved. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTIES OR REPRESENTATIONS; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _XVMC_VLD_H #define _XVMC_VLD_H #include "accel_xvmc.h" #include "xvmc.h" extern void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture, int code, uint8_t *buffer, uint32_t chunk_size, uint8_t *chunk_buffer); extern void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code); #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/mpeg2.h���������������������������������������������������������0000644�0001750�0001750�00000006021�14647725152�016257� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mpeg2.h * Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ /* Structure for the mpeg2dec decoder */ #ifndef MPEG2_H #define MPEG2_H #include "libmpeg2_accel.h" typedef struct mpeg2dec_s { xine_video_port_t * output; uint32_t frame_format; /* this is where we keep the state of the decoder */ struct picture_s * picture; uint32_t shift; int new_sequence; int is_sequence_needed; int is_wait_for_ip_frames; int frames_to_drop, drop_frame; int in_slice; int seek_mode, is_frame_needed; /* the maximum chunk size is determined by vbv_buffer_size */ /* which is 224K for MP@ML streams. */ /* (we make no pretenses of decoding anything more than that) */ /* allocated in init - gcc has problems allocating such big structures */ uint8_t * chunk_buffer; /* pointer to current position in chunk_buffer */ uint8_t * chunk_ptr; /* last start code ? */ uint8_t code; uint32_t chunk_size; int64_t pts; uint32_t rff_pattern; int force_aspect; int force_pan_scan; /* AFD data can be found after a sequence, group or picture start code */ /* and will be stored in afd_value_seen. Later it will be transfered to */ /* a stream property and stored into afd_value_reported to detect changes */ int afd_value_seen; int afd_value_reported; xine_stream_t *stream; /* a spu decoder for possible closed captions */ spu_decoder_t *cc_dec; mpeg2dec_accel_t accel; } mpeg2dec_t ; /* initialize mpegdec with a opaque user pointer */ void mpeg2_init (mpeg2dec_t * mpeg2dec, xine_video_port_t * output); /* destroy everything which was allocated, shutdown the output */ void mpeg2_close (mpeg2dec_t * mpeg2dec); int mpeg2_decode_data (mpeg2dec_t * mpeg2dec, uint8_t * data_start, uint8_t * data_end, uint64_t pts); void mpeg2_find_sequence_header (mpeg2dec_t * mpeg2dec, uint8_t * data_start, uint8_t * data_end); void mpeg2_flush (mpeg2dec_t * mpeg2dec); void mpeg2_reset (mpeg2dec_t * mpeg2dec); void mpeg2_discontinuity (mpeg2dec_t * mpeg2dec); /* Not needed, it is defined as static in decode.c, and no-one else called it * currently */ /* void process_userdata(mpeg2dec_t *mpeg2dec, uint8_t *buffer); */ #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/libmpeg2_accel.h������������������������������������������������0000644�0001750�0001750�00000003515�14647725152�020102� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * libmpeg2_accel.h * Copyright (C) 2004 The Unichrome Project. * Copyright (C) 2005 Thomas Hellstrom. * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef LIBMPEG2_ACCEL_H #define LIBMPEG2_ACCEL_H #include "mpeg2_internal.h" /* * Internal context data type. */ typedef struct { int xvmc_last_slice_code; int slices_per_row; int row_slice_count; unsigned xxmc_mb_pic_height; } mpeg2dec_accel_t; extern int libmpeg2_accel_discontinuity(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture); extern int libmpeg2_accel_new_sequence(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture); extern int libmpeg2_accel_new_frame(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, double ratio, uint32_t flags); extern void libmpeg2_accel_frame_completion(mpeg2dec_accel_t *accel, uint32_t frame_format, picture_t *picture, int code); extern int libmpeg2_accel_slice(mpeg2dec_accel_t *accel, picture_t *picture, int code, char * buffer, uint32_t chunk_size, uint8_t *chunk_buffer); extern void libmpeg2_accel_scan( mpeg2dec_accel_t *accel, uint8_t *scan_norm, uint8_t *scan_alt); #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/cpu_state.c�����������������������������������������������������0000644�0001750�0001750�00000010551�14647725152�017232� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * cpu_state.c * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include <stdlib.h> #include <inttypes.h> #include "mpeg2_internal.h" #include <xine/xineutils.h> #include "xine_mmx.h" void (* mpeg2_cpu_state_save) (cpu_state_t * state) = NULL; void (* mpeg2_cpu_state_restore) (cpu_state_t * state) = NULL; #if defined(ARCH_X86) || defined(ARCH_X86_64) static void state_restore_mmx (cpu_state_t * state) { (void)state; emms (); } #endif #if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) #ifndef HOST_OS_DARWIN static void state_save_altivec (cpu_state_t * state) { asm (" \n" " li %r9, 16 \n" " stvx %v20, 0, %r3 \n" " li %r11, 32 \n" " stvx %v21, %r9, %r3 \n" " li %r9, 48 \n" " stvx %v22, %r11, %r3 \n" " li %r11, 64 \n" " stvx %v23, %r9, %r3 \n" " li %r9, 80 \n" " stvx %v24, %r11, %r3 \n" " li %r11, 96 \n" " stvx %v25, %r9, %r3 \n" " li %r9, 112 \n" " stvx %v26, %r11, %r3 \n" " li %r11, 128 \n" " stvx %v27, %r9, %r3 \n" " li %r9, 144 \n" " stvx %v28, %r11, %r3 \n" " li %r11, 160 \n" " stvx %v29, %r9, %r3 \n" " li %r9, 176 \n" " stvx %v30, %r11, %r3 \n" " stvx %v31, %r9, %r3 \n" ); } static void state_restore_altivec (cpu_state_t * state) { asm (" \n" " li %r9, 16 \n" " lvx %v20, 0, %r3 \n" " li %r11, 32 \n" " lvx %v21, %r9, %r3 \n" " li %r9, 48 \n" " lvx %v22, %r11, %r3 \n" " li %r11, 64 \n" " lvx %v23, %r9, %r3 \n" " li %r9, 80 \n" " lvx %v24, %r11, %r3 \n" " li %r11, 96 \n" " lvx %v25, %r9, %r3 \n" " li %r9, 112 \n" " lvx %v26, %r11, %r3 \n" " li %r11, 128 \n" " lvx %v27, %r9, %r3 \n" " li %r9, 144 \n" " lvx %v28, %r11, %r3 \n" " li %r11, 160 \n" " lvx %v29, %r9, %r3 \n" " li %r9, 176 \n" " lvx %v30, %r11, %r3 \n" " lvx %v31, %r9, %r3 \n" ); } #else /* HOST_OS_DARWIN */ #define LI(a,b) "li r" #a "," #b "\n\t" #define STVX0(a,b,c) "stvx v" #a ",0,r" #c "\n\t" #define STVX(a,b,c) "stvx v" #a ",r" #b ",r" #c "\n\t" #define LVX0(a,b,c) "lvx v" #a ",0,r" #c "\n\t" #define LVX(a,b,c) "lvx v" #a ",r" #b ",r" #c "\n\t" static void state_save_altivec (cpu_state_t * state) { asm (LI (9, 16) STVX0 (20, 0, 3) LI (11, 32) STVX (21, 9, 3) LI (9, 48) STVX (22, 11, 3) LI (11, 64) STVX (23, 9, 3) LI (9, 80) STVX (24, 11, 3) LI (11, 96) STVX (25, 9, 3) LI (9, 112) STVX (26, 11, 3) LI (11, 128) STVX (27, 9, 3) LI (9, 144) STVX (28, 11, 3) LI (11, 160) STVX (29, 9, 3) LI (9, 176) STVX (30, 11, 3) STVX (31, 9, 3)); } static void state_restore_altivec (cpu_state_t * state) { asm (LI (9, 16) LVX0 (20, 0, 3) LI (11, 32) LVX (21, 9, 3) LI (9, 48) LVX (22, 11, 3) LI (11, 64) LVX (23, 9, 3) LI (9, 80) LVX (24, 11, 3) LI (11, 96) LVX (25, 9, 3) LI (9, 112) LVX (26, 11, 3) LI (11, 128) LVX (27, 9, 3) LI (9, 144) LVX (28, 11, 3) LI (11, 160) LVX (29, 9, 3) LI (9, 176) LVX (30, 11, 3) LVX (31, 9, 3)); } #endif /* HOST_OS_DARWIN */ #endif /* defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) */ void mpeg2_cpu_state_init (uint32_t mm_accel) { #if defined(ARCH_X86) || defined(ARCH_X86_64) if (mm_accel & MM_ACCEL_X86_MMX) { mpeg2_cpu_state_restore = state_restore_mmx; } #endif #if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { mpeg2_cpu_state_save = state_save_altivec; mpeg2_cpu_state_restore = state_restore_altivec; } #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/idct.c����������������������������������������������������������0000644�0001750�0001750�00000021576�14647725152�016177� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * Portions of this code are from the MPEG software simulation group * idct implementation. This code will be replaced with a new * implementation soon. * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ /**********************************************************/ /* inverse two dimensional DCT, Chen-Wang algorithm */ /* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ /* 32-bit integer arithmetic (8 bit coefficients) */ /* 11 mults, 29 adds per DCT */ /* sE, 18.8.91 */ /**********************************************************/ /* coefficients extended to 12 bit for IEEE1180-1990 */ /* compliance sE, 2.1.94 */ /**********************************************************/ /* this code assumes >> to be a two's-complement arithmetic */ /* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include "mpeg2_internal.h" #include <xine/xineutils.h> #define W1 2841 /* 2048*sqrt (2)*cos (1*pi/16) */ #define W2 2676 /* 2048*sqrt (2)*cos (2*pi/16) */ #define W3 2408 /* 2048*sqrt (2)*cos (3*pi/16) */ #define W5 1609 /* 2048*sqrt (2)*cos (5*pi/16) */ #define W6 1108 /* 2048*sqrt (2)*cos (6*pi/16) */ #define W7 565 /* 2048*sqrt (2)*cos (7*pi/16) */ /* idct main entry points */ void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); void (* mpeg2_idct_add) (int16_t * block, uint8_t * dest, int stride); void (* mpeg2_idct) (int16_t * block); void (* mpeg2_zero_block) (int16_t * block); static uint8_t clip_lut[1024]; #define CLIP(i) ((clip_lut+384)[ (i)]) /* row (horizontal) IDCT * * 7 pi 1 * dst[k] = sum c[l] * src[l] * cos ( -- * ( k + - ) * l ) * l=0 8 2 * * where: c[0] = 128 * c[1..7] = 128*sqrt (2) */ static inline void idct_row (int16_t * block) { int x0, x1, x2, x3, x4, x5, x6, x7, x8; x1 = block[4] << 11; x2 = block[6]; x3 = block[2]; x4 = block[1]; x5 = block[7]; x6 = block[5]; x7 = block[3]; /* shortcut */ if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { block[0] = block[1] = block[2] = block[3] = block[4] = block[5] = block[6] = block[7] = block[0]<<3; return; } x0 = (block[0] << 11) + 128; /* for proper rounding in the fourth stage */ /* first stage */ x8 = W7 * (x4 + x5); x4 = x8 + (W1 - W7) * x4; x5 = x8 - (W1 + W7) * x5; x8 = W3 * (x6 + x7); x6 = x8 - (W3 - W5) * x6; x7 = x8 - (W3 + W5) * x7; /* second stage */ x8 = x0 + x1; x0 -= x1; x1 = W6 * (x3 + x2); x2 = x1 - (W2 + W6) * x2; x3 = x1 + (W2 - W6) * x3; x1 = x4 + x6; x4 -= x6; x6 = x5 + x7; x5 -= x7; /* third stage */ x7 = x8 + x3; x8 -= x3; x3 = x0 + x2; x0 -= x2; x2 = (181 * (x4 + x5) + 128) >> 8; x4 = (181 * (x4 - x5) + 128) >> 8; /* fourth stage */ block[0] = (x7 + x1) >> 8; block[1] = (x3 + x2) >> 8; block[2] = (x0 + x4) >> 8; block[3] = (x8 + x6) >> 8; block[4] = (x8 - x6) >> 8; block[5] = (x0 - x4) >> 8; block[6] = (x3 - x2) >> 8; block[7] = (x7 - x1) >> 8; } /* column (vertical) IDCT * * 7 pi 1 * dst[8*k] = sum c[l] * src[8*l] * cos ( -- * ( k + - ) * l ) * l=0 8 2 * * where: c[0] = 1/1024 * c[1..7] = (1/1024)*sqrt (2) */ static inline void idct_col (int16_t *block) { int x0, x1, x2, x3, x4, x5, x6, x7, x8; /* shortcut */ x1 = block [8*4] << 8; x2 = block [8*6]; x3 = block [8*2]; x4 = block [8*1]; x5 = block [8*7]; x6 = block [8*5]; x7 = block [8*3]; #if 0 if (! (x1 | x2 | x3 | x4 | x5 | x6 | x7 )) { block[8*0] = block[8*1] = block[8*2] = block[8*3] = block[8*4] = block[8*5] = block[8*6] = block[8*7] = (block[8*0] + 32) >> 6; return; } #endif x0 = (block[8*0] << 8) + 8192; /* first stage */ x8 = W7 * (x4 + x5) + 4; x4 = (x8 + (W1 - W7) * x4) >> 3; x5 = (x8 - (W1 + W7) * x5) >> 3; x8 = W3 * (x6 + x7) + 4; x6 = (x8 - (W3 - W5) * x6) >> 3; x7 = (x8 - (W3 + W5) * x7) >> 3; /* second stage */ x8 = x0 + x1; x0 -= x1; x1 = W6 * (x3 + x2) + 4; x2 = (x1 - (W2 + W6) * x2) >> 3; x3 = (x1 + (W2 - W6) * x3) >> 3; x1 = x4 + x6; x4 -= x6; x6 = x5 + x7; x5 -= x7; /* third stage */ x7 = x8 + x3; x8 -= x3; x3 = x0 + x2; x0 -= x2; x2 = (181 * (x4 + x5) + 128) >> 8; x4 = (181 * (x4 - x5) + 128) >> 8; /* fourth stage */ block[8*0] = (x7 + x1) >> 14; block[8*1] = (x3 + x2) >> 14; block[8*2] = (x0 + x4) >> 14; block[8*3] = (x8 + x6) >> 14; block[8*4] = (x8 - x6) >> 14; block[8*5] = (x0 - x4) >> 14; block[8*6] = (x3 - x2) >> 14; block[8*7] = (x7 - x1) >> 14; } static void mpeg2_idct_copy_c (int16_t * block, uint8_t * dest, int stride) { int i; for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); i = 8; do { dest[0] = CLIP (block[0]); dest[1] = CLIP (block[1]); dest[2] = CLIP (block[2]); dest[3] = CLIP (block[3]); dest[4] = CLIP (block[4]); dest[5] = CLIP (block[5]); dest[6] = CLIP (block[6]); dest[7] = CLIP (block[7]); block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; dest += stride; block += 8; } while (--i); } static void mpeg2_idct_add_c (int16_t * block, uint8_t * dest, int stride) { int i; for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); i = 8; do { dest[0] = CLIP (block[0] + dest[0]); dest[1] = CLIP (block[1] + dest[1]); dest[2] = CLIP (block[2] + dest[2]); dest[3] = CLIP (block[3] + dest[3]); dest[4] = CLIP (block[4] + dest[4]); dest[5] = CLIP (block[5] + dest[5]); dest[6] = CLIP (block[6] + dest[6]); dest[7] = CLIP (block[7] + dest[7]); block[0] = 0; block[1] = 0; block[2] = 0; block[3] = 0; block[4] = 0; block[5] = 0; block[6] = 0; block[7] = 0; dest += stride; block += 8; } while (--i); } static void mpeg2_idct_c (int16_t * block) { int i; for (i = 0; i < 8; i++) idct_row (block + 8 * i); for (i = 0; i < 8; i++) idct_col (block + i); } static void mpeg2_zero_block_c (int16_t * wblock) { memset( wblock, 0, sizeof(int16_t) * 64 ); } void mpeg2_idct_init (uint32_t mm_accel) { mpeg2_zero_block = mpeg2_zero_block_c; #if defined(ARCH_X86) || defined(ARCH_X86_64) if (mm_accel & MM_ACCEL_X86_MMXEXT) { #ifdef LOG fprintf (stderr, "Using MMXEXT for IDCT transform\n"); #endif mpeg2_idct_copy = mpeg2_idct_copy_mmxext; mpeg2_idct_add = mpeg2_idct_add_mmxext; mpeg2_idct = mpeg2_idct_mmxext; mpeg2_zero_block = mpeg2_zero_block_mmx; mpeg2_idct_mmx_init (); } else if (mm_accel & MM_ACCEL_X86_MMX) { #ifdef LOG fprintf (stderr, "Using MMX for IDCT transform\n"); #endif mpeg2_idct_copy = mpeg2_idct_copy_mmx; mpeg2_idct_add = mpeg2_idct_add_mmx; mpeg2_idct = mpeg2_idct_mmx; mpeg2_zero_block = mpeg2_zero_block_mmx; mpeg2_idct_mmx_init (); } else #endif #if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) if (mm_accel & MM_ACCEL_PPC_ALTIVEC) { #ifdef LOG fprintf (stderr, "Using altivec for IDCT transform\n"); #endif mpeg2_idct_copy = mpeg2_idct_copy_altivec; mpeg2_idct_add = mpeg2_idct_add_altivec; mpeg2_idct_altivec_init (); mpeg2_idct = mpeg2_idct_c; } else #endif #ifdef LIBMPEG2_MLIB if (mm_accel & MM_ACCEL_MLIB) { char * env_var; env_var = getenv ("MLIB_NON_IEEE"); mpeg2_idct = mpeg2_idct_mlib; if (env_var == NULL) { #ifdef LOG fprintf (stderr, "Using mlib for IDCT transform\n"); #endif mpeg2_idct_add = mpeg2_idct_add_mlib; } else { fprintf (stderr, "Using non-IEEE mlib for IDCT transform\n"); mpeg2_idct_add = mpeg2_idct_add_mlib_non_ieee; } mpeg2_idct_copy = mpeg2_idct_copy_mlib_non_ieee; } else #endif { int i; #ifdef LOG fprintf (stderr, "No accelerated IDCT transform found\n"); #endif mpeg2_idct_copy = mpeg2_idct_copy_c; mpeg2_idct_add = mpeg2_idct_add_c; mpeg2_idct = mpeg2_idct_c; for (i = -384; i < 640; i++) clip_lut[i+384] = (i < 0) ? 0 : ((i > 255) ? 255 : i); } } ����������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/vis.h�����������������������������������������������������������0000644�0001750�0001750�00000027035�14647725152�016056� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * vis.h * Copyright (C) 2003 David S. Miller <davem@redhat.com> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ /* You may be asking why I hard-code the instruction opcodes and don't * use the normal VIS assembler mnenomics for the VIS instructions. * * The reason is that Sun, in their infinite wisdom, decided that a binary * using a VIS instruction will cause it to be marked (in the ELF headers) * as doing so, and this prevents the OS from loading such binaries if the * current cpu doesn't have VIS. There is no way to easily override this * behavior of the assembler that I am aware of. * * This totally defeats what libmpeg2 is trying to do which is allow a * single binary to be created, and then detect the availability of VIS * at runtime. * * I'm not saying that tainting the binary by default is bad, rather I'm * saying that not providing a way to override this easily unnecessarily * ties people's hands. * * Thus, we do the opcode encoding by hand and output 32-bit words in * the assembler to keep the binary from becoming tainted. */ #define vis_opc_base ((0x1 << 31) | (0x36 << 19)) #define vis_opf(X) ((X) << 5) #define vis_sreg(X) (X) #define vis_dreg(X) (((X)&0x1f)|((X)>>5)) #define vis_rs1_s(X) (vis_sreg(X) << 14) #define vis_rs1_d(X) (vis_dreg(X) << 14) #define vis_rs2_s(X) (vis_sreg(X) << 0) #define vis_rs2_d(X) (vis_dreg(X) << 0) #define vis_rd_s(X) (vis_sreg(X) << 25) #define vis_rd_d(X) (vis_dreg(X) << 25) #define vis_ss2s(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rs2_s(rs2) | \ vis_rd_s(rd))) #define vis_dd2d(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_d(rs1) | \ vis_rs2_d(rs2) | \ vis_rd_d(rd))) #define vis_ss2d(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rs2_s(rs2) | \ vis_rd_d(rd))) #define vis_sd2d(opf,rs1,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rs2_d(rs2) | \ vis_rd_d(rd))) #define vis_d2s(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_d(rs2) | \ vis_rd_s(rd))) #define vis_s2d(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_s(rs2) | \ vis_rd_d(rd))) #define vis_d12d(opf,rs1,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_d(rs1) | \ vis_rd_d(rd))) #define vis_d22d(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_d(rs2) | \ vis_rd_d(rd))) #define vis_s12s(opf,rs1,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs1_s(rs1) | \ vis_rd_s(rd))) #define vis_s22s(opf,rs2,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rs2_s(rs2) | \ vis_rd_s(rd))) #define vis_s(opf,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rd_s(rd))) #define vis_d(opf,rd) \ __asm__ __volatile__ (".word %0" \ : : "i" (vis_opc_base | vis_opf(opf) | \ vis_rd_d(rd))) #define vis_r2m(op,rd,mem) \ __asm__ __volatile__ (#op "\t%%f" #rd ", [%0]" : : "r" (&(mem)) ) #define vis_r2m_2(op,rd,mem1,mem2) \ __asm__ __volatile__ (#op "\t%%f" #rd ", [%0 + %1]" : : "r" (mem1), "r" (mem2) ) #define vis_m2r(op,mem,rd) \ __asm__ __volatile__ (#op "\t[%0], %%f" #rd : : "r" (&(mem)) ) #define vis_m2r_2(op,mem1,mem2,rd) \ __asm__ __volatile__ (#op "\t[%0 + %1], %%f" #rd : : "r" (mem1), "r" (mem2) ) static inline void vis_set_gsr(unsigned int _val) { register unsigned int val asm("g1"); val = _val; __asm__ __volatile__(".word 0xa7804000" : : "r" (val)); } #define VIS_GSR_ALIGNADDR_MASK 0x0000007 #define VIS_GSR_ALIGNADDR_SHIFT 0 #define VIS_GSR_SCALEFACT_MASK 0x0000078 #define VIS_GSR_SCALEFACT_SHIFT 3 #define vis_ld32(mem,rs1) vis_m2r(ld, mem, rs1) #define vis_ld32_2(mem1,mem2,rs1) vis_m2r_2(ld, mem1, mem2, rs1) #define vis_st32(rs1,mem) vis_r2m(st, rs1, mem) #define vis_st32_2(rs1,mem1,mem2) vis_r2m_2(st, rs1, mem1, mem2) #define vis_ld64(mem,rs1) vis_m2r(ldd, mem, rs1) #define vis_ld64_2(mem1,mem2,rs1) vis_m2r_2(ldd, mem1, mem2, rs1) #define vis_st64(rs1,mem) vis_r2m(std, rs1, mem) #define vis_st64_2(rs1,mem1,mem2) vis_r2m_2(std, rs1, mem1, mem2) #define vis_ldblk(mem, rd) \ do { register void *__mem asm("g1"); \ __mem = &(mem); \ __asm__ __volatile__(".word 0xc1985e00 | %1" \ : \ : "r" (__mem), \ "i" (vis_rd_d(rd)) \ : "memory"); \ } while (0) #define vis_stblk(rd, mem) \ do { register void *__mem asm("g1"); \ __mem = &(mem); \ __asm__ __volatile__(".word 0xc1b85e00 | %1" \ : \ : "r" (__mem), \ "i" (vis_rd_d(rd)) \ : "memory"); \ } while (0) #define vis_membar_storestore() \ __asm__ __volatile__(".word 0x8143e008" : : : "memory") #define vis_membar_sync() \ __asm__ __volatile__(".word 0x8143e040" : : : "memory") /* 16 and 32 bit partitioned addition and subtraction. The normal * versions perform 4 16-bit or 2 32-bit additions or subtractions. * The 's' versions perform 2 16-bit or 2 32-bit additions or * subtractions. */ #define vis_padd16(rs1,rs2,rd) vis_dd2d(0x50, rs1, rs2, rd) #define vis_padd16s(rs1,rs2,rd) vis_ss2s(0x51, rs1, rs2, rd) #define vis_padd32(rs1,rs2,rd) vis_dd2d(0x52, rs1, rs2, rd) #define vis_padd32s(rs1,rs2,rd) vis_ss2s(0x53, rs1, rs2, rd) #define vis_psub16(rs1,rs2,rd) vis_dd2d(0x54, rs1, rs2, rd) #define vis_psub16s(rs1,rs2,rd) vis_ss2s(0x55, rs1, rs2, rd) #define vis_psub32(rs1,rs2,rd) vis_dd2d(0x56, rs1, rs2, rd) #define vis_psub32s(rs1,rs2,rd) vis_ss2s(0x57, rs1, rs2, rd) /* Pixel formatting instructions. */ #define vis_pack16(rs2,rd) vis_d2s( 0x3b, rs2, rd) #define vis_pack32(rs1,rs2,rd) vis_dd2d(0x3a, rs1, rs2, rd) #define vis_packfix(rs2,rd) vis_d2s( 0x3d, rs2, rd) #define vis_expand(rs2,rd) vis_s2d( 0x4d, rs2, rd) #define vis_pmerge(rs1,rs2,rd) vis_ss2d(0x4b, rs1, rs2, rd) /* Partitioned multiply instructions. */ #define vis_mul8x16(rs1,rs2,rd) vis_sd2d(0x31, rs1, rs2, rd) #define vis_mul8x16au(rs1,rs2,rd) vis_ss2d(0x33, rs1, rs2, rd) #define vis_mul8x16al(rs1,rs2,rd) vis_ss2d(0x35, rs1, rs2, rd) #define vis_mul8sux16(rs1,rs2,rd) vis_dd2d(0x36, rs1, rs2, rd) #define vis_mul8ulx16(rs1,rs2,rd) vis_dd2d(0x37, rs1, rs2, rd) #define vis_muld8sux16(rs1,rs2,rd) vis_ss2d(0x38, rs1, rs2, rd) #define vis_muld8ulx16(rs1,rs2,rd) vis_ss2d(0x39, rs1, rs2, rd) /* Alignment instructions. */ static inline void *vis_alignaddr(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x18) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(1))); return ptr; } static inline void vis_alignaddr_g0(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x18) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(0))); } static inline void *vis_alignaddrl(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x19) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(1))); return ptr; } static inline void vis_alignaddrl_g0(void *_ptr) { register void *ptr asm("g1"); ptr = _ptr; __asm__ __volatile__(".word %2" : "=&r" (ptr) : "0" (ptr), "i" (vis_opc_base | vis_opf(0x19) | vis_rs1_s(1) | vis_rs2_s(0) | vis_rd_s(0))); } #define vis_faligndata(rs1,rs2,rd) vis_dd2d(0x48, rs1, rs2, rd) /* Logical operate instructions. */ #define vis_fzero(rd) vis_d( 0x60, rd) #define vis_fzeros(rd) vis_s( 0x61, rd) #define vis_fone(rd) vis_d( 0x7e, rd) #define vis_fones(rd) vis_s( 0x7f, rd) #define vis_src1(rs1,rd) vis_d12d(0x74, rs1, rd) #define vis_src1s(rs1,rd) vis_s12s(0x75, rs1, rd) #define vis_src2(rs2,rd) vis_d22d(0x78, rs2, rd) #define vis_src2s(rs2,rd) vis_s22s(0x79, rs2, rd) #define vis_not1(rs1,rd) vis_d12d(0x6a, rs1, rd) #define vis_not1s(rs1,rd) vis_s12s(0x6b, rs1, rd) #define vis_not2(rs2,rd) vis_d22d(0x66, rs2, rd) #define vis_not2s(rs2,rd) vis_s22s(0x67, rs2, rd) #define vis_or(rs1,rs2,rd) vis_dd2d(0x7c, rs1, rs2, rd) #define vis_ors(rs1,rs2,rd) vis_ss2s(0x7d, rs1, rs2, rd) #define vis_nor(rs1,rs2,rd) vis_dd2d(0x62, rs1, rs2, rd) #define vis_nors(rs1,rs2,rd) vis_ss2s(0x63, rs1, rs2, rd) #define vis_and(rs1,rs2,rd) vis_dd2d(0x70, rs1, rs2, rd) #define vis_ands(rs1,rs2,rd) vis_ss2s(0x71, rs1, rs2, rd) #define vis_nand(rs1,rs2,rd) vis_dd2d(0x6e, rs1, rs2, rd) #define vis_nands(rs1,rs2,rd) vis_ss2s(0x6f, rs1, rs2, rd) #define vis_xor(rs1,rs2,rd) vis_dd2d(0x6c, rs1, rs2, rd) #define vis_xors(rs1,rs2,rd) vis_ss2s(0x6d, rs1, rs2, rd) #define vis_xnor(rs1,rs2,rd) vis_dd2d(0x72, rs1, rs2, rd) #define vis_xnors(rs1,rs2,rd) vis_ss2s(0x73, rs1, rs2, rd) #define vis_ornot1(rs1,rs2,rd) vis_dd2d(0x7a, rs1, rs2, rd) #define vis_ornot1s(rs1,rs2,rd) vis_ss2s(0x7b, rs1, rs2, rd) #define vis_ornot2(rs1,rs2,rd) vis_dd2d(0x76, rs1, rs2, rd) #define vis_ornot2s(rs1,rs2,rd) vis_ss2s(0x77, rs1, rs2, rd) #define vis_andnot1(rs1,rs2,rd) vis_dd2d(0x68, rs1, rs2, rd) #define vis_andnot1s(rs1,rs2,rd) vis_ss2s(0x69, rs1, rs2, rd) #define vis_andnot2(rs1,rs2,rd) vis_dd2d(0x64, rs1, rs2, rd) #define vis_andnot2s(rs1,rs2,rd) vis_ss2s(0x65, rs1, rs2, rd) /* Pixel component distance. */ #define vis_pdist(rs1,rs2,rd) vis_dd2d(0x3e, rs1, rs2, rd) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/xine_mpeg2_decoder.c��������������������������������������������0000644�0001750�0001750�00000011544�14647725152�020770� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stuff needed to turn libmpeg2 into a xine decoder plugin */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define LOG_MODULE "mpeg2_decoder" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include "mpeg2.h" #include "mpeg2_internal.h" #include <xine/buffer.h> typedef struct mpeg2dec_decoder_s { video_decoder_t video_decoder; mpeg2dec_t mpeg2; xine_stream_t *stream; } mpeg2dec_decoder_t; static void mpeg2dec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { mpeg2dec_decoder_t *this = xine_container_of(this_gen, mpeg2dec_decoder_t, video_decoder); lprintf ("decode_data, flags=0x%08x ...\n", buf->decoder_flags); /* handle aspect hints from xine-dvdnav */ if (buf->decoder_flags & BUF_FLAG_SPECIAL) { if (buf->decoder_info[1] == BUF_SPECIAL_ASPECT) { this->mpeg2.force_aspect = buf->decoder_info[2]; if (buf->decoder_info[3] == 0x1 && buf->decoder_info[2] == 3) /* letterboxing is denied, we have to do pan&scan */ this->mpeg2.force_pan_scan = 1; else this->mpeg2.force_pan_scan = 0; } return; } if (buf->decoder_flags & BUF_FLAG_PREVIEW) { mpeg2_find_sequence_header (&this->mpeg2, buf->content, buf->content + buf->size); } else { mpeg2_decode_data (&this->mpeg2, buf->content, buf->content + buf->size, buf->pts); } lprintf ("decode_data...done\n"); } static void mpeg2dec_flush (video_decoder_t *this_gen) { mpeg2dec_decoder_t *this = xine_container_of(this_gen, mpeg2dec_decoder_t, video_decoder); lprintf ("flush\n"); mpeg2_flush (&this->mpeg2); } static void mpeg2dec_reset (video_decoder_t *this_gen) { mpeg2dec_decoder_t *this = xine_container_of(this_gen, mpeg2dec_decoder_t, video_decoder); mpeg2_reset (&this->mpeg2); } static void mpeg2dec_discontinuity (video_decoder_t *this_gen) { mpeg2dec_decoder_t *this = xine_container_of(this_gen, mpeg2dec_decoder_t, video_decoder); mpeg2_discontinuity (&this->mpeg2); } static void mpeg2dec_dispose (video_decoder_t *this_gen) { mpeg2dec_decoder_t *this = xine_container_of(this_gen, mpeg2dec_decoder_t, video_decoder); lprintf ("close\n"); mpeg2_close (&this->mpeg2); this->stream->video_out->close(this->stream->video_out, this->stream); free (this); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { mpeg2dec_decoder_t *this ; (void)class_gen; this = (mpeg2dec_decoder_t *) calloc(1, sizeof(mpeg2dec_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = mpeg2dec_decode_data; this->video_decoder.flush = mpeg2dec_flush; this->video_decoder.reset = mpeg2dec_reset; this->video_decoder.discontinuity = mpeg2dec_discontinuity; this->video_decoder.dispose = mpeg2dec_dispose; this->stream = stream; this->mpeg2.stream = stream; mpeg2_init (&this->mpeg2, stream->video_out); (stream->video_out->open) (stream->video_out, stream); this->mpeg2.force_aspect = this->mpeg2.force_pan_scan = 0; return &this->video_decoder; } /* * mpeg2 plugin class */ static void *init_plugin (xine_t *xine, const void *data) { static const video_decoder_class_t decode_video_mpeg2_class = { .open_plugin = open_plugin, .identifier = "mpeg2dec", .description = N_("mpeg2 based video decoder plugin"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&decode_video_mpeg2_class; } /* * exported plugin catalog entry */ static const uint32_t supported_types[] = { BUF_VIDEO_MPEG, 0 }; static const decoder_info_t dec_info_mpeg2 = { .supported_types = supported_types, .priority = 7, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "mpeg2", XINE_VERSION_CODE, &dec_info_mpeg2, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/slice_xvmc_vld.c������������������������������������������������0000644�0001750�0001750�00000015452�14647725152�020251� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (c) 2004 The Unichrome project. All rights reserved. * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTIES OR REPRESENTATIONS; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include <xine/video_out.h> #include "mpeg2.h" #include "mpeg2_internal.h" #include "xvmc_vld.h" static const uint8_t zig_zag_scan[64] ATTR_ALIGN(16) = { /* Zig-Zag scan pattern */ 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 }; static const uint8_t alternate_scan [64] ATTR_ALIGN(16) = { /* Alternate scan pattern */ 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 }; void mpeg2_xxmc_slice( mpeg2dec_accel_t *accel, picture_t *picture, int code, uint8_t *buffer, uint32_t chunk_size, uint8_t *chunk_buffer) { vo_frame_t *frame = picture->current_frame; xine_xxmc_t *xxmc = (xine_xxmc_t *) frame->accel_data; xine_vld_frame_t *vft = &xxmc->vld_frame; unsigned mb_frame_height; int i; const uint8_t * scan_pattern; float ms_per_slice; (void)buffer; if (1 == code && accel->xvmc_last_slice_code != 1) { frame->bad_frame = 1; accel->slices_per_row = 1; accel->row_slice_count = 1; /* * Check that first field went through OK. Otherwise, * indicate bad frame. */ if (picture->second_field) { accel->xvmc_last_slice_code = (xxmc->decoded) ? 0 : -1; xxmc->decoded = 0; } else { accel->xvmc_last_slice_code = 0; } mb_frame_height = (!(picture->mpeg1) && (picture->progressive_sequence)) ? 2*((picture->coded_picture_height+31) >> 5) : (picture->coded_picture_height+15) >> 4; accel->xxmc_mb_pic_height = (picture->picture_structure == FRAME_PICTURE ) ? mb_frame_height : mb_frame_height >> 1; ms_per_slice = 1000. / (90000. * mb_frame_height) * frame->duration; xxmc->sleep = 1. / (ms_per_slice * 0.45); if (xxmc->sleep < 1.) xxmc->sleep = 1.; if (picture->mpeg1) { vft->mv_ranges[0][0] = picture->b_motion.f_code[0]; vft->mv_ranges[0][1] = picture->b_motion.f_code[0]; vft->mv_ranges[1][0] = picture->f_motion.f_code[0]; vft->mv_ranges[1][1] = picture->f_motion.f_code[0]; } else { vft->mv_ranges[0][0] = picture->b_motion.f_code[0]; vft->mv_ranges[0][1] = picture->b_motion.f_code[1]; vft->mv_ranges[1][0] = picture->f_motion.f_code[0]; vft->mv_ranges[1][1] = picture->f_motion.f_code[1]; } vft->picture_structure = picture->picture_structure; vft->picture_coding_type = picture->picture_coding_type; vft->mpeg_coding = (picture->mpeg1) ? 0 : 1; vft->progressive_sequence = picture->progressive_sequence; vft->scan = (picture->scan == mpeg2_scan_alt); vft->pred_dct_frame = picture->frame_pred_frame_dct; vft->concealment_motion_vectors = picture->concealment_motion_vectors; vft->q_scale_type = picture->q_scale_type; vft->intra_vlc_format = picture->intra_vlc_format; vft->intra_dc_precision = picture->intra_dc_precision; vft->second_field = picture->second_field; /* * Translation of libmpeg2's Q-matrix layout to VLD XvMC's. * Errors here will give * blocky artifacts and sometimes wrong colors. */ scan_pattern = (vft->scan) ? alternate_scan : zig_zag_scan; if ((vft->load_intra_quantizer_matrix = picture->load_intra_quantizer_matrix)) { for (i=0; i<64; ++i) { vft->intra_quantizer_matrix[scan_pattern[i]] = picture->intra_quantizer_matrix[picture->scan[i]]; } } if ((vft->load_non_intra_quantizer_matrix = picture->load_non_intra_quantizer_matrix)) { for (i=0; i<64; ++i) { vft->non_intra_quantizer_matrix[scan_pattern[i]] = picture->non_intra_quantizer_matrix[picture->scan[i]]; } } picture->load_intra_quantizer_matrix = 0; picture->load_non_intra_quantizer_matrix = 0; vft->forward_reference_frame = picture->forward_reference_frame; vft->backward_reference_frame = picture->backward_reference_frame; xxmc->proc_xxmc_begin( frame ); if (xxmc->result != 0) { accel->xvmc_last_slice_code=-1; } } if (((code == accel->xvmc_last_slice_code + 1) || (code == accel->xvmc_last_slice_code))) { /* * Send this slice to the output plugin. May stall for a long * time in proc_slice; */ frame->bad_frame = 1; xxmc->slice_data_size = chunk_size; xxmc->slice_data = chunk_buffer; xxmc->slice_code = code; xxmc->proc_xxmc_slice( frame ); if (xxmc->result != 0) { accel->xvmc_last_slice_code=-1; return; } /* * Keep track of slices. */ accel->row_slice_count = (accel->xvmc_last_slice_code == code) ? accel->row_slice_count + 1 : 1; accel->slices_per_row = (accel->row_slice_count > accel->slices_per_row) ? accel->row_slice_count:accel->slices_per_row; accel->xvmc_last_slice_code = code; } else { /* * An error has occured. */ lprintf("libmpeg2: VLD XvMC: Slice error.\n"); accel->xvmc_last_slice_code = -1; return; } } void mpeg2_xxmc_vld_frame_complete(mpeg2dec_accel_t *accel, picture_t *picture, int code) { vo_frame_t *frame = picture->current_frame; xine_xxmc_t *xxmc = (xine_xxmc_t *) frame->accel_data; if (xxmc->decoded) return; if (accel->xvmc_last_slice_code == -1) { xxmc->proc_xxmc_flush( frame ); return; } if ((code != 0xff) || ((accel->xvmc_last_slice_code == (int)accel->xxmc_mb_pic_height) && accel->slices_per_row == accel->row_slice_count)) { xxmc->proc_xxmc_flush( frame ); if (xxmc->result) { accel->xvmc_last_slice_code=-1; frame->bad_frame = 1; return; } xxmc->decoded = 1; accel->xvmc_last_slice_code = 0; if (picture->picture_structure == 3 || picture->second_field) { if (xxmc->result == 0) frame->bad_frame = 0; } } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/idct_altivec.c��������������������������������������������������0000644�0001750�0001750�00000017531�14647725152�017702� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_altivec.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) #include <altivec.h> #include <inttypes.h> #include "mpeg2_internal.h" #include <xine/xineutils.h> #define vector_s16_t vector signed short #define vector_u16_t vector unsigned short #define vector_s8_t vector signed char #define vector_u8_t vector unsigned char #define vector_s32_t vector signed int #define vector_u32_t vector unsigned int #define IDCT_HALF \ /* 1st stage */ \ t1 = vec_mradds (a1, vx7, vx1 ); \ t8 = vec_mradds (a1, vx1, vec_subs (zero, vx7)); \ t7 = vec_mradds (a2, vx5, vx3); \ t3 = vec_mradds (ma2, vx3, vx5); \ \ /* 2nd stage */ \ t5 = vec_adds (vx0, vx4); \ t0 = vec_subs (vx0, vx4); \ t2 = vec_mradds (a0, vx6, vx2); \ t4 = vec_mradds (a0, vx2, vec_subs (zero,vx6)); \ t6 = vec_adds (t8, t3); \ t3 = vec_subs (t8, t3); \ t8 = vec_subs (t1, t7); \ t1 = vec_adds (t1, t7); \ \ /* 3rd stage */ \ t7 = vec_adds (t5, t2); \ t2 = vec_subs (t5, t2); \ t5 = vec_adds (t0, t4); \ t0 = vec_subs (t0, t4); \ t4 = vec_subs (t8, t3); \ t3 = vec_adds (t8, t3); \ \ /* 4th stage */ \ vy0 = vec_adds (t7, t1); \ vy7 = vec_subs (t7, t1); \ vy1 = vec_mradds (c4, t3, t5); \ vy6 = vec_mradds (mc4, t3, t5); \ vy2 = vec_mradds (c4, t4, t0); \ vy5 = vec_mradds (mc4, t4, t0); \ vy3 = vec_adds (t2, t6); \ vy4 = vec_subs (t2, t6); #define IDCT \ vector_s16_t vx0, vx1, vx2, vx3, vx4, vx5, vx6, vx7; \ vector_s16_t vy0, vy1, vy2, vy3, vy4, vy5, vy6, vy7; \ vector_s16_t a0, a1, a2, ma2, c4, mc4, zero, bias; \ vector_s16_t t0, t1, t2, t3, t4, t5, t6, t7, t8; \ vector_u16_t shift; \ \ c4 = vec_splat (constants[0], 0); \ a0 = vec_splat (constants[0], 1); \ a1 = vec_splat (constants[0], 2); \ a2 = vec_splat (constants[0], 3); \ mc4 = vec_splat (constants[0], 4); \ ma2 = vec_splat (constants[0], 5); \ bias = (vector_s16_t)vec_splat ((vector_s32_t)constants[0], 3); \ \ zero = vec_splat_s16 (0); \ shift = vec_splat_u16 (4); \ \ vx0 = vec_mradds (vec_sl (block[0], shift), constants[1], zero); \ vx1 = vec_mradds (vec_sl (block[1], shift), constants[2], zero); \ vx2 = vec_mradds (vec_sl (block[2], shift), constants[3], zero); \ vx3 = vec_mradds (vec_sl (block[3], shift), constants[4], zero); \ vx4 = vec_mradds (vec_sl (block[4], shift), constants[1], zero); \ vx5 = vec_mradds (vec_sl (block[5], shift), constants[4], zero); \ vx6 = vec_mradds (vec_sl (block[6], shift), constants[3], zero); \ vx7 = vec_mradds (vec_sl (block[7], shift), constants[2], zero); \ \ IDCT_HALF \ \ vx0 = vec_mergeh (vy0, vy4); \ vx1 = vec_mergel (vy0, vy4); \ vx2 = vec_mergeh (vy1, vy5); \ vx3 = vec_mergel (vy1, vy5); \ vx4 = vec_mergeh (vy2, vy6); \ vx5 = vec_mergel (vy2, vy6); \ vx6 = vec_mergeh (vy3, vy7); \ vx7 = vec_mergel (vy3, vy7); \ \ vy0 = vec_mergeh (vx0, vx4); \ vy1 = vec_mergel (vx0, vx4); \ vy2 = vec_mergeh (vx1, vx5); \ vy3 = vec_mergel (vx1, vx5); \ vy4 = vec_mergeh (vx2, vx6); \ vy5 = vec_mergel (vx2, vx6); \ vy6 = vec_mergeh (vx3, vx7); \ vy7 = vec_mergel (vx3, vx7); \ \ vx0 = vec_adds (vec_mergeh (vy0, vy4), bias); \ vx1 = vec_mergel (vy0, vy4); \ vx2 = vec_mergeh (vy1, vy5); \ vx3 = vec_mergel (vy1, vy5); \ vx4 = vec_mergeh (vy2, vy6); \ vx5 = vec_mergel (vy2, vy6); \ vx6 = vec_mergeh (vy3, vy7); \ vx7 = vec_mergel (vy3, vy7); \ \ IDCT_HALF \ \ shift = vec_splat_u16 (6); \ vx0 = vec_sra (vy0, shift); \ vx1 = vec_sra (vy1, shift); \ vx2 = vec_sra (vy2, shift); \ vx3 = vec_sra (vy3, shift); \ vx4 = vec_sra (vy4, shift); \ vx5 = vec_sra (vy5, shift); \ vx6 = vec_sra (vy6, shift); \ vx7 = vec_sra (vy7, shift); #if defined( __APPLE_CC__ ) && defined( __APPLE_ALTIVEC__ ) /* apple */ #define VEC_S16(a,b,c,d,e,f,g,h) (vector_s16_t) (a, b, c, d, e, f, g, h) #else /* gnu */ #define VEC_S16(a,b,c,d,e,f,g,h) (vector_s16_t) {a, b, c, d, e, f, g, h} #endif static vector_s16_t constants[5] = { VEC_S16(23170, 13573, 6518, 21895, -23170, -21895, 32, 31), VEC_S16(16384, 22725, 21407, 19266, 16384, 19266, 21407, 22725), VEC_S16(22725, 31521, 29692, 26722, 22725, 26722, 29692, 31521), VEC_S16(21407, 29692, 27969, 25172, 21407, 25172, 27969, 29692), VEC_S16(19266, 26722, 25172, 22654, 19266, 22654, 25172, 26722) }; void mpeg2_idct_copy_altivec (vector_s16_t * block, unsigned char * dest, int stride) { vector_u8_t tmp; IDCT #define COPY(dest,src) \ tmp = vec_packsu (src, src); \ vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); COPY (dest, vx0) dest += stride; COPY (dest, vx1) dest += stride; COPY (dest, vx2) dest += stride; COPY (dest, vx3) dest += stride; COPY (dest, vx4) dest += stride; COPY (dest, vx5) dest += stride; COPY (dest, vx6) dest += stride; COPY (dest, vx7) memset (block, 0, 64 * sizeof (signed short)); } void mpeg2_idct_add_altivec (vector_s16_t * block, unsigned char * dest, int stride) { vector_u8_t tmp; vector_s16_t tmp2, tmp3; vector_u8_t perm0; vector_u8_t perm1; vector_u8_t p0, p1, p; IDCT p0 = vec_lvsl (0, dest); p1 = vec_lvsl (stride, dest); p = vec_splat_u8 (-1); perm0 = vec_mergeh (p, p0); perm1 = vec_mergeh (p, p1); #define ADD(dest,src,perm) \ /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ tmp = vec_ld (0, dest); \ tmp2 = (vector_s16_t)vec_perm (tmp, (vector_u8_t)zero, perm); \ tmp3 = vec_adds (tmp2, src); \ tmp = vec_packsu (tmp3, tmp3); \ vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); \ vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); ADD (dest, vx0, perm0) dest += stride; ADD (dest, vx1, perm1) dest += stride; ADD (dest, vx2, perm0) dest += stride; ADD (dest, vx3, perm1) dest += stride; ADD (dest, vx4, perm0) dest += stride; ADD (dest, vx5, perm1) dest += stride; ADD (dest, vx6, perm0) dest += stride; ADD (dest, vx7, perm1) memset (block, 0, 64 * sizeof (signed short)); } void mpeg2_idct_altivec_init (void) { int i, j; /* the altivec idct uses a transposed input, so we patch scan tables */ for (i = 0; i < 64; i++) { j = mpeg2_scan_norm[i]; mpeg2_scan_norm[i] = (j >> 3) | ((j & 7) << 3); j = mpeg2_scan_alt[i]; mpeg2_scan_alt[i] = (j >> 3) | ((j & 7) << 3); } } #endif /* ARCH_PPC && ENABLED_ALTIVEC */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/mpeg2_internal.h������������������������������������������������0000644�0001750�0001750�00000022166�14647725152�020163� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mpeg2_internal.h * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MPEG2_INTERNAL_H #define MPEG2_INTERNAL_H #include <xine/video_out.h> #include "accel_xvmc.h" #ifdef ENABLE_ALTIVEC #include <altivec.h> #endif /* macroblock modes */ #define MACROBLOCK_INTRA XINE_MACROBLOCK_INTRA #define MACROBLOCK_PATTERN XINE_MACROBLOCK_PATTERN #define MACROBLOCK_MOTION_BACKWARD XINE_MACROBLOCK_MOTION_BACKWARD #define MACROBLOCK_MOTION_FORWARD XINE_MACROBLOCK_MOTION_FORWARD #define MACROBLOCK_QUANT XINE_MACROBLOCK_QUANT #define DCT_TYPE_INTERLACED XINE_MACROBLOCK_DCT_TYPE_INTERLACED /* motion_type */ #define MOTION_TYPE_MASK (3*64) #define MOTION_TYPE_BASE 64 #define MC_FIELD (1*64) #define MC_FRAME (2*64) #define MC_16X8 (2*64) #define MC_DMV (3*64) /* picture structure */ #define TOP_FIELD VO_TOP_FIELD #define BOTTOM_FIELD VO_BOTTOM_FIELD #define FRAME_PICTURE VO_BOTH_FIELDS /* picture coding type (mpeg2 header) */ #define I_TYPE 1 #define P_TYPE 2 #define B_TYPE 3 #define D_TYPE 4 typedef struct motion_s { uint8_t * ref[2][3]; uint8_t ** ref2[2]; int pmv[2][2]; int f_code[2]; } motion_t; typedef struct picture_s { /* first, state that carries information from one macroblock to the */ /* next inside a slice, and is never used outside of mpeg2_slice() */ /* DCT coefficients - should be kept aligned ! */ int16_t DCTblock[64]; /* XvMC DCT block and macroblock data for XvMC acceleration */ xine_macroblocks_t *mc; int XvMC_mb_type; int XvMC_mv_field_sel[2][2]; int XvMC_x; int XvMC_y; int XvMC_motion_type; int XvMC_dmvector[2]; int XvMC_cbp; int XvMC_dct_type; /* bit parsing stuff */ uint32_t bitstream_buf; /* current 32 bit working set of buffer */ int bitstream_bits; /* used bits in working set */ uint8_t * bitstream_ptr; /* buffer with stream data */ uint8_t * dest[3]; int pitches[3]; int offset; unsigned int limit_x; unsigned int limit_y_16; unsigned int limit_y_8; unsigned int limit_y; /* Motion vectors */ /* The f_ and b_ correspond to the forward and backward motion */ /* predictors */ motion_t b_motion; motion_t f_motion; /* predictor for DC coefficients in intra blocks */ int16_t dc_dct_pred[3]; int quantizer_scale; /* remove */ int current_field; /* remove */ int dmv_offset; /* remove */ unsigned int v_offset; /* remove */ /* now non-slice-specific information */ /* sequence header stuff */ uint8_t intra_quantizer_matrix [64]; uint8_t non_intra_quantizer_matrix [64]; int load_intra_quantizer_matrix; int load_non_intra_quantizer_matrix; /* The width and height of the picture snapped to macroblock units */ int coded_picture_width; int coded_picture_height; /* The width and height as it appears on header sequence */ unsigned int display_width, display_height; /* picture header stuff */ /* what type of picture this is (I, P, B, D) */ int picture_coding_type; int vbv_delay; int low_delay; /* picture coding extension stuff */ /* quantization factor for intra dc coefficients */ int intra_dc_precision; /* top/bottom/both fields */ int picture_structure; /* bool to indicate all predictions are frame based */ int frame_pred_frame_dct; /* bool to indicate whether intra blocks have motion vectors */ /* (for concealment) */ int concealment_motion_vectors; /* bit to indicate which quantization table to use */ int q_scale_type; /* bool to use different vlc tables */ int intra_vlc_format; /* used for DMV MC */ int top_field_first; /* stuff derived from bitstream */ /* pointer to the zigzag scan we're supposed to be using */ uint8_t * scan; struct vo_frame_s * current_frame; struct vo_frame_s * forward_reference_frame; struct vo_frame_s * backward_reference_frame; int frame_width, frame_height; int second_field; int mpeg1; int skip_non_intra_dct; /* these things are not needed by the decoder */ /* this is a temporary interface, we will build a better one later. */ int aspect_ratio_information; int saved_aspect_ratio; int frame_rate_code; int progressive_sequence; int repeat_first_field; int progressive_frame; int32_t frame_centre_horizontal_offset; int32_t frame_centre_vertical_offset; uint32_t video_format; uint32_t colour_description; uint32_t colour_primatives; uint32_t transfer_characteristics; uint32_t matrix_coefficients; uint32_t display_horizontal_size; uint32_t display_vertical_size; uint32_t drop_frame_flag; uint32_t time_code_hours; uint32_t time_code_minutes; uint32_t time_code_seconds; uint32_t time_code_pictures; uint32_t closed_gop; uint32_t broken_link; int bitrate; int frame_rate_ext_n; int frame_rate_ext_d; } picture_t; typedef struct cpu_state_s { #ifdef ARCH_PPC uint8_t regv[12*16]; #endif int dummy; } cpu_state_t; /* cpu_state.c */ extern void (* mpeg2_cpu_state_save) (cpu_state_t * state); extern void (* mpeg2_cpu_state_restore) (cpu_state_t * state); void mpeg2_cpu_state_init (uint32_t mm_accel); /* header.c */ extern uint8_t mpeg2_scan_norm[64]; extern uint8_t mpeg2_scan_alt[64]; void mpeg2_header_state_init (picture_t * picture); int mpeg2_header_picture (picture_t * picture, uint8_t * buffer); int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer); int mpeg2_header_extension (picture_t * picture, uint8_t * buffer); int mpeg2_header_group_of_pictures (picture_t * picture, uint8_t * buffer); /* idct.c */ extern void (* mpeg2_idct_copy) (int16_t * block, uint8_t * dest, int stride); extern void (* mpeg2_idct_add) (int16_t * block, uint8_t * dest, int stride); extern void (* mpeg2_idct) (int16_t * block); extern void (* mpeg2_zero_block) (int16_t * block); void mpeg2_idct_init (uint32_t mm_accel); /* idct_mlib.c */ void mpeg2_idct_add_mlib (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_copy_mlib_non_ieee (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_mlib_non_ieee (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_mlib (int16_t * block); /* idct_mmx.c */ void mpeg2_idct_copy_mmxext (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_mmxext (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_mmxext (int16_t * block); void mpeg2_idct_copy_mmx (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_add_mmx (int16_t * block, uint8_t * dest, int stride); void mpeg2_idct_mmx (int16_t * block); void mpeg2_zero_block_mmx (int16_t * block); void mpeg2_idct_mmx_init (void); /* idct_altivec.c */ # ifdef ENABLE_ALTIVEC void mpeg2_idct_copy_altivec (vector signed short * block, unsigned char * dest, int stride); void mpeg2_idct_add_altivec (vector signed short * block, unsigned char * dest, int stride); # else /* ! ENABLE_ALTIVEC */ void mpeg2_idct_copy_altivec (signed short * block, unsigned char * dest, int stride); void mpeg2_idct_add_altivec (signed short * block, unsigned char * dest, int stride); # endif /* ENABLE_ALTIVEC */ void mpeg2_idct_altivec_init (void); /* motion_comp.c */ void mpeg2_mc_init (uint32_t mm_accel); typedef struct mpeg2_mc_s { void (* put [8]) (uint8_t * dst, uint8_t *, int32_t, int32_t); void (* avg [8]) (uint8_t * dst, uint8_t *, int32_t, int32_t); } mpeg2_mc_t; #define MPEG2_MC_EXTERN(x) mpeg2_mc_t mpeg2_mc_##x = { \ {MC_put_o_16_##x, MC_put_x_16_##x, MC_put_y_16_##x, MC_put_xy_16_##x, \ MC_put_o_8_##x, MC_put_x_8_##x, MC_put_y_8_##x, MC_put_xy_8_##x}, \ {MC_avg_o_16_##x, MC_avg_x_16_##x, MC_avg_y_16_##x, MC_avg_xy_16_##x, \ MC_avg_o_8_##x, MC_avg_x_8_##x, MC_avg_y_8_##x, MC_avg_xy_8_##x} \ }; extern mpeg2_mc_t mpeg2_mc; extern mpeg2_mc_t mpeg2_mc_c; extern mpeg2_mc_t mpeg2_mc_mmx; extern mpeg2_mc_t mpeg2_mc_mmxext; extern mpeg2_mc_t mpeg2_mc_3dnow; extern mpeg2_mc_t mpeg2_mc_altivec; extern mpeg2_mc_t mpeg2_mc_mlib; extern mpeg2_mc_t mpeg2_mc_vis; /* slice.c */ void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer); /* stats.c */ void mpeg2_stats (int code, uint8_t * buffer); #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/motion_comp_altivec.c�������������������������������������������0000644�0001750�0001750�00000161527�14647725152�021307� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * motion_comp_altivec.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #ifndef HOST_OS_DARWIN #if defined (ARCH_PPC) && defined (ENABLE_ALTIVEC) #include "mpeg2_internal.h" #include <inttypes.h> /* * The asm code is generated with: * * gcc-2.95 -fvec -DHOST_OS_DARWIN -O9 -fomit-frame-pointer -mregnames -S * motion_comp_altivec.c * * sed 's/.L/._L/g' motion_comp_altivec.s | * awk '{args=""; len=split ($2, arg, ","); * for (i=1; i<=len; i++) { a=arg[i]; if (i<len) a=a","; * args = args sprintf ("%-6s", a) } * printf ("\t\"\t%-16s%-24s\\n\"\n", $1, args) }' | * unexpand -a */ static void MC_put_o_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " srawi %r6, %r6, 1 \n" " li %r9, 15 \n" " addi %r6, %r6, -1 \n" " lvsl %v12, 0, %r4 \n" " mtctr %r6 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r9, %r4 \n" " add %r0, %r5, %r5 \n" " vperm %v13, %v1, %v0, %v12 \n" " add %r4, %r4, %r5 \n" "._L6: \n" " li %r9, 15 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r9, %r4 \n" " stvx %v13, 0, %r3 \n" " vperm %v13, %v1, %v0, %v12 \n" " add %r4, %r4, %r5 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r9, %r4 \n" " stvx %v13, %r5, %r3 \n" " vperm %v13, %v1, %v0, %v12 \n" " add %r4, %r4, %r5 \n" " add %r3, %r3, %r0 \n" " bdnz ._L6 \n" " lvx %v0, %r9, %r4 \n" " lvx %v1, 0, %r4 \n" " stvx %v13, 0, %r3 \n" " vperm %v13, %v1, %v0, %v12 \n" " stvx %v13, %r5, %r3 \n" ); } static void MC_put_o_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v12, 0, %r4 \n" " lvsl %v1, %r5, %r4 \n" " vmrghb %v12, %v12, %v12 \n" " srawi %r6, %r6, 1 \n" " li %r9, 7 \n" " vmrghb %v1, %v1, %v1 \n" " addi %r6, %r6, -1 \n" " vpkuhum %v10, %v12, %v12 \n" " lvx %v13, 0, %r4 \n" " mtctr %r6 \n" " vpkuhum %v11, %v1, %v1 \n" " lvx %v0, %r9, %r4 \n" " add %r4, %r4, %r5 \n" " vperm %v12, %v13, %v0, %v10 \n" "._L11: \n" " li %r9, 7 \n" " lvx %v0, %r9, %r4 \n" " lvx %v13, 0, %r4 \n" " stvewx %v12, 0, %r3 \n" " li %r9, 4 \n" " vperm %v1, %v13, %v0, %v11 \n" " stvewx %v12, %r9, %r3 \n" " add %r4, %r4, %r5 \n" " li %r9, 7 \n" " lvx %v0, %r9, %r4 \n" " lvx %v13, 0, %r4 \n" " add %r3, %r3, %r5 \n" " stvewx %v1, 0, %r3 \n" " vperm %v12, %v13, %v0, %v10 \n" " li %r9, 4 \n" " stvewx %v1, %r9, %r3 \n" " add %r4, %r4, %r5 \n" " add %r3, %r3, %r5 \n" " bdnz ._L11 \n" " li %r9, 7 \n" " lvx %v0, %r9, %r4 \n" " lvx %v13, 0, %r4 \n" " stvewx %v12, 0, %r3 \n" " li %r9, 4 \n" " vperm %v1, %v13, %v0, %v11 \n" " stvewx %v12, %r9, %r3 \n" " add %r3, %r3, %r5 \n" " stvewx %v1, 0, %r3 \n" " stvewx %v1, %r9, %r3 \n" ); } static void MC_put_x_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v11, 0, %r4 \n" " vspltisb %v0, 1 \n" " li %r9, 16 \n" " lvx %v12, 0, %r4 \n" " vaddubm %v10, %v11, %v0 \n" " lvx %v13, %r9, %r4 \n" " srawi %r6, %r6, 1 \n" " addi %r6, %r6, -1 \n" " vperm %v1, %v12, %v13, %v10 \n" " vperm %v0, %v12, %v13, %v11 \n" " mtctr %r6 \n" " add %r0, %r5, %r5 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v0, %v1 \n" "._L16: \n" " li %r9, 16 \n" " lvx %v12, 0, %r4 \n" " lvx %v13, %r9, %r4 \n" " stvx %v0, 0, %r3 \n" " vperm %v1, %v12, %v13, %v10 \n" " add %r4, %r4, %r5 \n" " vperm %v0, %v12, %v13, %v11 \n" " lvx %v12, 0, %r4 \n" " lvx %v13, %r9, %r4 \n" " vavgub %v0, %v0, %v1 \n" " stvx %v0, %r5, %r3 \n" " vperm %v1, %v12, %v13, %v10 \n" " add %r4, %r4, %r5 \n" " vperm %v0, %v12, %v13, %v11 \n" " add %r3, %r3, %r0 \n" " vavgub %v0, %v0, %v1 \n" " bdnz ._L16 \n" " lvx %v13, %r9, %r4 \n" " lvx %v12, 0, %r4 \n" " stvx %v0, 0, %r3 \n" " vperm %v1, %v12, %v13, %v10 \n" " vperm %v0, %v12, %v13, %v11 \n" " vavgub %v0, %v0, %v1 \n" " stvx %v0, %r5, %r3 \n" ); } static void MC_put_x_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v0, 0, %r4 \n" " vspltisb %v13, 1 \n" " lvsl %v10, %r5, %r4 \n" " vmrghb %v0, %v0, %v0 \n" " li %r9, 8 \n" " lvx %v11, 0, %r4 \n" " vmrghb %v10, %v10, %v10 \n" " vpkuhum %v8, %v0, %v0 \n" " lvx %v12, %r9, %r4 \n" " srawi %r6, %r6, 1 \n" " vpkuhum %v9, %v10, %v10 \n" " vaddubm %v7, %v8, %v13 \n" " addi %r6, %r6, -1 \n" " vperm %v1, %v11, %v12, %v8 \n" " mtctr %r6 \n" " vaddubm %v13, %v9, %v13 \n" " add %r4, %r4, %r5 \n" " vperm %v0, %v11, %v12, %v7 \n" " vavgub %v0, %v1, %v0 \n" "._L21: \n" " li %r9, 8 \n" " lvx %v12, %r9, %r4 \n" " lvx %v11, 0, %r4 \n" " stvewx %v0, 0, %r3 \n" " li %r9, 4 \n" " vperm %v1, %v11, %v12, %v13 \n" " stvewx %v0, %r9, %r3 \n" " vperm %v0, %v11, %v12, %v9 \n" " add %r4, %r4, %r5 \n" " li %r9, 8 \n" " lvx %v12, %r9, %r4 \n" " vavgub %v10, %v0, %v1 \n" " lvx %v11, 0, %r4 \n" " add %r3, %r3, %r5 \n" " stvewx %v10, 0, %r3 \n" " vperm %v1, %v11, %v12, %v7 \n" " vperm %v0, %v11, %v12, %v8 \n" " li %r9, 4 \n" " stvewx %v10, %r9, %r3 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v0, %v1 \n" " add %r3, %r3, %r5 \n" " bdnz ._L21 \n" " li %r9, 8 \n" " lvx %v12, %r9, %r4 \n" " lvx %v11, 0, %r4 \n" " stvewx %v0, 0, %r3 \n" " li %r9, 4 \n" " vperm %v1, %v11, %v12, %v13 \n" " stvewx %v0, %r9, %r3 \n" " vperm %v0, %v11, %v12, %v9 \n" " add %r3, %r3, %r5 \n" " vavgub %v10, %v0, %v1 \n" " stvewx %v10, 0, %r3 \n" " stvewx %v10, %r9, %r3 \n" ); } static void MC_put_y_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " li %r9, 15 \n" " lvsl %v10, 0, %r4 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r9, %r4 \n" " add %r4, %r4, %r5 \n" " vperm %v12, %v13, %v1, %v10 \n" " srawi %r6, %r6, 1 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r9, %r4 \n" " addi %r6, %r6, -1 \n" " vperm %v11, %v13, %v1, %v10 \n" " mtctr %r6 \n" " add %r0, %r5, %r5 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v12, %v11 \n" "._L26: \n" " li %r9, 15 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r9, %r4 \n" " stvx %v0, 0, %r3 \n" " vperm %v12, %v13, %v1, %v10 \n" " add %r4, %r4, %r5 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r9, %r4 \n" " vavgub %v0, %v12, %v11 \n" " stvx %v0, %r5, %r3 \n" " vperm %v11, %v13, %v1, %v10 \n" " add %r4, %r4, %r5 \n" " add %r3, %r3, %r0 \n" " vavgub %v0, %v12, %v11 \n" " bdnz ._L26 \n" " lvx %v1, %r9, %r4 \n" " lvx %v13, 0, %r4 \n" " stvx %v0, 0, %r3 \n" " vperm %v12, %v13, %v1, %v10 \n" " vavgub %v0, %v12, %v11 \n" " stvx %v0, %r5, %r3 \n" ); } static void MC_put_y_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v13, 0, %r4 \n" " lvsl %v11, %r5, %r4 \n" " vmrghb %v13, %v13, %v13 \n" " li %r9, 7 \n" " lvx %v12, 0, %r4 \n" " vmrghb %v11, %v11, %v11 \n" " lvx %v1, %r9, %r4 \n" " vpkuhum %v9, %v13, %v13 \n" " add %r4, %r4, %r5 \n" " vpkuhum %v10, %v11, %v11 \n" " vperm %v13, %v12, %v1, %v9 \n" " srawi %r6, %r6, 1 \n" " lvx %v12, 0, %r4 \n" " lvx %v1, %r9, %r4 \n" " addi %r6, %r6, -1 \n" " vperm %v11, %v12, %v1, %v10 \n" " mtctr %r6 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v13, %v11 \n" "._L31: \n" " li %r9, 7 \n" " lvx %v1, %r9, %r4 \n" " lvx %v12, 0, %r4 \n" " stvewx %v0, 0, %r3 \n" " li %r9, 4 \n" " vperm %v13, %v12, %v1, %v9 \n" " stvewx %v0, %r9, %r3 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v13, %v11 \n" " li %r9, 7 \n" " lvx %v1, %r9, %r4 \n" " lvx %v12, 0, %r4 \n" " add %r3, %r3, %r5 \n" " stvewx %v0, 0, %r3 \n" " vperm %v11, %v12, %v1, %v10 \n" " li %r9, 4 \n" " stvewx %v0, %r9, %r3 \n" " vavgub %v0, %v13, %v11 \n" " add %r4, %r4, %r5 \n" " add %r3, %r3, %r5 \n" " bdnz ._L31 \n" " li %r9, 7 \n" " lvx %v1, %r9, %r4 \n" " lvx %v12, 0, %r4 \n" " stvewx %v0, 0, %r3 \n" " li %r9, 4 \n" " vperm %v13, %v12, %v1, %v9 \n" " stvewx %v0, %r9, %r3 \n" " add %r3, %r3, %r5 \n" " vavgub %v0, %v13, %v11 \n" " stvewx %v0, 0, %r3 \n" " stvewx %v0, %r9, %r3 \n" ); } static void MC_put_xy_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v5, 0, %r4 \n" " vspltisb %v3, 1 \n" " li %r9, 16 \n" " lvx %v1, 0, %r4 \n" " vaddubm %v4, %v5, %v3 \n" " lvx %v0, %r9, %r4 \n" " add %r4, %r4, %r5 \n" " vperm %v10, %v1, %v0, %v4 \n" " srawi %r6, %r6, 1 \n" " vperm %v11, %v1, %v0, %v5 \n" " addi %r6, %r6, -1 \n" " lvx %v1, 0, %r4 \n" " mtctr %r6 \n" " lvx %v0, %r9, %r4 \n" " vavgub %v9, %v11, %v10 \n" " vxor %v8, %v11, %v10 \n" " add %r0, %r5, %r5 \n" " vperm %v10, %v1, %v0, %v4 \n" " add %r4, %r4, %r5 \n" " vperm %v11, %v1, %v0, %v5 \n" " vxor %v6, %v11, %v10 \n" " vavgub %v7, %v11, %v10 \n" " vor %v0, %v8, %v6 \n" " vxor %v13, %v9, %v7 \n" " vand %v0, %v3, %v0 \n" " vavgub %v1, %v9, %v7 \n" " vand %v0, %v0, %v13 \n" " vsububm %v13, %v1, %v0 \n" "._L36: \n" " li %r9, 16 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r9, %r4 \n" " stvx %v13, 0, %r3 \n" " vperm %v10, %v1, %v0, %v4 \n" " add %r4, %r4, %r5 \n" " vperm %v11, %v1, %v0, %v5 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r9, %r4 \n" " vavgub %v9, %v11, %v10 \n" " vxor %v8, %v11, %v10 \n" " add %r4, %r4, %r5 \n" " vperm %v10, %v1, %v0, %v4 \n" " vavgub %v12, %v9, %v7 \n" " vperm %v11, %v1, %v0, %v5 \n" " vor %v13, %v8, %v6 \n" " vxor %v0, %v9, %v7 \n" " vxor %v6, %v11, %v10 \n" " vand %v13, %v3, %v13 \n" " vavgub %v7, %v11, %v10 \n" " vor %v1, %v8, %v6 \n" " vand %v13, %v13, %v0 \n" " vxor %v0, %v9, %v7 \n" " vand %v1, %v3, %v1 \n" " vsububm %v13, %v12, %v13 \n" " vand %v1, %v1, %v0 \n" " stvx %v13, %r5, %r3 \n" " vavgub %v0, %v9, %v7 \n" " add %r3, %r3, %r0 \n" " vsububm %v13, %v0, %v1 \n" " bdnz ._L36 \n" " lvx %v0, %r9, %r4 \n" " lvx %v1, 0, %r4 \n" " stvx %v13, 0, %r3 \n" " vperm %v10, %v1, %v0, %v4 \n" " vperm %v11, %v1, %v0, %v5 \n" " vxor %v8, %v11, %v10 \n" " vavgub %v9, %v11, %v10 \n" " vor %v0, %v8, %v6 \n" " vxor %v13, %v9, %v7 \n" " vand %v0, %v3, %v0 \n" " vavgub %v1, %v9, %v7 \n" " vand %v0, %v0, %v13 \n" " vsububm %v13, %v1, %v0 \n" " stvx %v13, %r5, %r3 \n" ); } static void MC_put_xy_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v4, 0, %r4 \n" " vspltisb %v3, 1 \n" " lvsl %v5, %r5, %r4 \n" " vmrghb %v4, %v4, %v4 \n" " li %r9, 16 \n" " vmrghb %v5, %v5, %v5 \n" " lvx %v1, 0, %r4 \n" " vpkuhum %v4, %v4, %v4 \n" " lvx %v0, %r9, %r4 \n" " vpkuhum %v5, %v5, %v5 \n" " add %r4, %r4, %r5 \n" " vaddubm %v2, %v4, %v3 \n" " vperm %v11, %v1, %v0, %v4 \n" " srawi %r6, %r6, 1 \n" " vaddubm %v19, %v5, %v3 \n" " addi %r6, %r6, -1 \n" " vperm %v10, %v1, %v0, %v2 \n" " mtctr %r6 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r9, %r4 \n" " vavgub %v9, %v11, %v10 \n" " vxor %v8, %v11, %v10 \n" " add %r4, %r4, %r5 \n" " vperm %v10, %v1, %v0, %v19 \n" " vperm %v11, %v1, %v0, %v5 \n" " vxor %v6, %v11, %v10 \n" " vavgub %v7, %v11, %v10 \n" " vor %v0, %v8, %v6 \n" " vxor %v13, %v9, %v7 \n" " vand %v0, %v3, %v0 \n" " vavgub %v1, %v9, %v7 \n" " vand %v0, %v0, %v13 \n" " vsububm %v13, %v1, %v0 \n" "._L41: \n" " li %r9, 16 \n" " lvx %v0, %r9, %r4 \n" " lvx %v1, 0, %r4 \n" " stvewx %v13, 0, %r3 \n" " li %r9, 4 \n" " vperm %v10, %v1, %v0, %v2 \n" " stvewx %v13, %r9, %r3 \n" " vperm %v11, %v1, %v0, %v4 \n" " add %r4, %r4, %r5 \n" " li %r9, 16 \n" " vavgub %v9, %v11, %v10 \n" " lvx %v0, %r9, %r4 \n" " vxor %v8, %v11, %v10 \n" " lvx %v1, 0, %r4 \n" " vavgub %v12, %v9, %v7 \n" " vor %v13, %v8, %v6 \n" " add %r3, %r3, %r5 \n" " vperm %v10, %v1, %v0, %v19 \n" " li %r9, 4 \n" " vperm %v11, %v1, %v0, %v5 \n" " vand %v13, %v3, %v13 \n" " add %r4, %r4, %r5 \n" " vxor %v0, %v9, %v7 \n" " vxor %v6, %v11, %v10 \n" " vavgub %v7, %v11, %v10 \n" " vor %v1, %v8, %v6 \n" " vand %v13, %v13, %v0 \n" " vxor %v0, %v9, %v7 \n" " vand %v1, %v3, %v1 \n" " vsububm %v13, %v12, %v13 \n" " vand %v1, %v1, %v0 \n" " stvewx %v13, 0, %r3 \n" " vavgub %v0, %v9, %v7 \n" " stvewx %v13, %r9, %r3 \n" " add %r3, %r3, %r5 \n" " vsububm %v13, %v0, %v1 \n" " bdnz ._L41 \n" " li %r9, 16 \n" " lvx %v0, %r9, %r4 \n" " lvx %v1, 0, %r4 \n" " stvewx %v13, 0, %r3 \n" " vperm %v10, %v1, %v0, %v2 \n" " li %r9, 4 \n" " vperm %v11, %v1, %v0, %v4 \n" " stvewx %v13, %r9, %r3 \n" " add %r3, %r3, %r5 \n" " vxor %v8, %v11, %v10 \n" " vavgub %v9, %v11, %v10 \n" " vor %v0, %v8, %v6 \n" " vxor %v13, %v9, %v7 \n" " vand %v0, %v3, %v0 \n" " vavgub %v1, %v9, %v7 \n" " vand %v0, %v0, %v13 \n" " vsububm %v13, %v1, %v0 \n" " stvewx %v13, 0, %r3 \n" " stvewx %v13, %r9, %r3 \n" ); } static void MC_avg_o_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " li %r9, 15 \n" " lvx %v0, %r9, %r4 \n" " lvsl %v11, 0, %r4 \n" " lvx %v1, 0, %r4 \n" " srawi %r6, %r6, 1 \n" " addi %r6, %r6, -1 \n" " vperm %v0, %v1, %v0, %v11 \n" " lvx %v13, 0, %r3 \n" " mtctr %r6 \n" " add %r9, %r5, %r5 \n" " vavgub %v12, %v13, %v0 \n" " add %r4, %r4, %r5 \n" "._L46: \n" " li %r11, 15 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r11, %r4 \n" " lvx %v13, %r5, %r3 \n" " vperm %v0, %v1, %v0, %v11 \n" " stvx %v12, 0, %r3 \n" " add %r4, %r4, %r5 \n" " vavgub %v12, %v13, %v0 \n" " lvx %v1, 0, %r4 \n" " lvx %v0, %r11, %r4 \n" " lvx %v13, %r9, %r3 \n" " vperm %v0, %v1, %v0, %v11 \n" " stvx %v12, %r5, %r3 \n" " add %r4, %r4, %r5 \n" " vavgub %v12, %v13, %v0 \n" " add %r3, %r3, %r9 \n" " bdnz ._L46 \n" " lvx %v0, %r11, %r4 \n" " lvx %v1, 0, %r4 \n" " lvx %v13, %r5, %r3 \n" " vperm %v0, %v1, %v0, %v11 \n" " stvx %v12, 0, %r3 \n" " vavgub %v12, %v13, %v0 \n" " stvx %v12, %r5, %r3 \n" ); } static void MC_avg_o_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v12, 0, %r4 \n" " li %r9, 7 \n" " vmrghb %v12, %v12, %v12 \n" " lvsl %v1, %r5, %r4 \n" " lvx %v13, 0, %r4 \n" " vpkuhum %v9, %v12, %v12 \n" " lvx %v0, %r9, %r4 \n" " srawi %r6, %r6, 1 \n" " vmrghb %v1, %v1, %v1 \n" " addi %r6, %r6, -1 \n" " vperm %v0, %v13, %v0, %v9 \n" " lvx %v11, 0, %r3 \n" " mtctr %r6 \n" " vpkuhum %v10, %v1, %v1 \n" " add %r4, %r4, %r5 \n" " vavgub %v12, %v11, %v0 \n" "._L51: \n" " li %r9, 7 \n" " lvx %v0, %r9, %r4 \n" " lvx %v13, 0, %r4 \n" " lvx %v11, %r5, %r3 \n" " stvewx %v12, 0, %r3 \n" " vperm %v0, %v13, %v0, %v10 \n" " li %r9, 4 \n" " stvewx %v12, %r9, %r3 \n" " vavgub %v1, %v11, %v0 \n" " add %r4, %r4, %r5 \n" " li %r9, 7 \n" " lvx %v0, %r9, %r4 \n" " add %r3, %r3, %r5 \n" " lvx %v13, 0, %r4 \n" " lvx %v11, %r5, %r3 \n" " stvewx %v1, 0, %r3 \n" " vperm %v0, %v13, %v0, %v9 \n" " li %r9, 4 \n" " stvewx %v1, %r9, %r3 \n" " vavgub %v12, %v11, %v0 \n" " add %r4, %r4, %r5 \n" " add %r3, %r3, %r5 \n" " bdnz ._L51 \n" " li %r9, 7 \n" " lvx %v0, %r9, %r4 \n" " lvx %v13, 0, %r4 \n" " lvx %v11, %r5, %r3 \n" " stvewx %v12, 0, %r3 \n" " vperm %v0, %v13, %v0, %v10 \n" " li %r9, 4 \n" " stvewx %v12, %r9, %r3 \n" " vavgub %v1, %v11, %v0 \n" " add %r3, %r3, %r5 \n" " stvewx %v1, 0, %r3 \n" " stvewx %v1, %r9, %r3 \n" ); } static void MC_avg_x_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v8, 0, %r4 \n" " vspltisb %v0, 1 \n" " li %r9, 16 \n" " lvx %v12, %r9, %r4 \n" " vaddubm %v7, %v8, %v0 \n" " lvx %v11, 0, %r4 \n" " srawi %r6, %r6, 1 \n" " vperm %v1, %v11, %v12, %v7 \n" " addi %r6, %r6, -1 \n" " vperm %v0, %v11, %v12, %v8 \n" " lvx %v9, 0, %r3 \n" " mtctr %r6 \n" " add %r9, %r5, %r5 \n" " vavgub %v0, %v0, %v1 \n" " add %r4, %r4, %r5 \n" " vavgub %v10, %v9, %v0 \n" "._L56: \n" " li %r11, 16 \n" " lvx %v11, 0, %r4 \n" " lvx %v12, %r11, %r4 \n" " lvx %v9, %r5, %r3 \n" " stvx %v10, 0, %r3 \n" " vperm %v0, %v11, %v12, %v7 \n" " add %r4, %r4, %r5 \n" " vperm %v1, %v11, %v12, %v8 \n" " lvx %v11, 0, %r4 \n" " lvx %v12, %r11, %r4 \n" " vavgub %v1, %v1, %v0 \n" " add %r4, %r4, %r5 \n" " vperm %v13, %v11, %v12, %v7 \n" " vavgub %v10, %v9, %v1 \n" " vperm %v0, %v11, %v12, %v8 \n" " lvx %v9, %r9, %r3 \n" " stvx %v10, %r5, %r3 \n" " vavgub %v0, %v0, %v13 \n" " add %r3, %r3, %r9 \n" " vavgub %v10, %v9, %v0 \n" " bdnz ._L56 \n" " lvx %v12, %r11, %r4 \n" " lvx %v11, 0, %r4 \n" " lvx %v9, %r5, %r3 \n" " vperm %v1, %v11, %v12, %v7 \n" " stvx %v10, 0, %r3 \n" " vperm %v0, %v11, %v12, %v8 \n" " vavgub %v0, %v0, %v1 \n" " vavgub %v10, %v9, %v0 \n" " stvx %v10, %r5, %r3 \n" ); } static void MC_avg_x_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v10, 0, %r4 \n" " vspltisb %v13, 1 \n" " li %r9, 8 \n" " vmrghb %v10, %v10, %v10 \n" " lvx %v11, 0, %r4 \n" " lvx %v12, %r9, %r4 \n" " vpkuhum %v7, %v10, %v10 \n" " srawi %r6, %r6, 1 \n" " lvsl %v10, %r5, %r4 \n" " vaddubm %v6, %v7, %v13 \n" " vperm %v0, %v11, %v12, %v7 \n" " addi %r6, %r6, -1 \n" " vmrghb %v10, %v10, %v10 \n" " lvx %v9, 0, %r3 \n" " mtctr %r6 \n" " vperm %v1, %v11, %v12, %v6 \n" " add %r4, %r4, %r5 \n" " vpkuhum %v8, %v10, %v10 \n" " vavgub %v0, %v0, %v1 \n" " vaddubm %v13, %v8, %v13 \n" " vavgub %v10, %v9, %v0 \n" "._L61: \n" " li %r9, 8 \n" " lvx %v12, %r9, %r4 \n" " lvx %v11, 0, %r4 \n" " lvx %v9, %r5, %r3 \n" " stvewx %v10, 0, %r3 \n" " vperm %v1, %v11, %v12, %v13 \n" " vperm %v0, %v11, %v12, %v8 \n" " li %r9, 4 \n" " stvewx %v10, %r9, %r3 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v0, %v1 \n" " li %r9, 8 \n" " lvx %v12, %r9, %r4 \n" " vavgub %v10, %v9, %v0 \n" " lvx %v11, 0, %r4 \n" " add %r3, %r3, %r5 \n" " vperm %v1, %v11, %v12, %v6 \n" " lvx %v9, %r5, %r3 \n" " vperm %v0, %v11, %v12, %v7 \n" " stvewx %v10, 0, %r3 \n" " li %r9, 4 \n" " vavgub %v0, %v0, %v1 \n" " stvewx %v10, %r9, %r3 \n" " add %r4, %r4, %r5 \n" " add %r3, %r3, %r5 \n" " vavgub %v10, %v9, %v0 \n" " bdnz ._L61 \n" " li %r9, 8 \n" " lvx %v12, %r9, %r4 \n" " lvx %v11, 0, %r4 \n" " lvx %v9, %r5, %r3 \n" " vperm %v1, %v11, %v12, %v13 \n" " stvewx %v10, 0, %r3 \n" " vperm %v0, %v11, %v12, %v8 \n" " li %r9, 4 \n" " stvewx %v10, %r9, %r3 \n" " vavgub %v0, %v0, %v1 \n" " add %r3, %r3, %r5 \n" " vavgub %v10, %v9, %v0 \n" " stvewx %v10, 0, %r3 \n" " stvewx %v10, %r9, %r3 \n" ); } static void MC_avg_y_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " li %r9, 15 \n" " lvx %v1, %r9, %r4 \n" " lvsl %v9, 0, %r4 \n" " lvx %v13, 0, %r4 \n" " add %r4, %r4, %r5 \n" " vperm %v11, %v13, %v1, %v9 \n" " li %r11, 15 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r11, %r4 \n" " srawi %r6, %r6, 1 \n" " vperm %v10, %v13, %v1, %v9 \n" " addi %r6, %r6, -1 \n" " lvx %v12, 0, %r3 \n" " mtctr %r6 \n" " vavgub %v0, %v11, %v10 \n" " add %r9, %r5, %r5 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v12, %v0 \n" "._L66: \n" " li %r11, 15 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r11, %r4 \n" " lvx %v12, %r5, %r3 \n" " vperm %v11, %v13, %v1, %v9 \n" " stvx %v0, 0, %r3 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v11, %v10 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r11, %r4 \n" " vavgub %v0, %v12, %v0 \n" " add %r4, %r4, %r5 \n" " lvx %v12, %r9, %r3 \n" " vperm %v10, %v13, %v1, %v9 \n" " stvx %v0, %r5, %r3 \n" " vavgub %v0, %v11, %v10 \n" " add %r3, %r3, %r9 \n" " vavgub %v0, %v12, %v0 \n" " bdnz ._L66 \n" " lvx %v1, %r11, %r4 \n" " lvx %v13, 0, %r4 \n" " lvx %v12, %r5, %r3 \n" " vperm %v11, %v13, %v1, %v9 \n" " stvx %v0, 0, %r3 \n" " vavgub %v0, %v11, %v10 \n" " vavgub %v0, %v12, %v0 \n" " stvx %v0, %r5, %r3 \n" ); } static void MC_avg_y_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v12, 0, %r4 \n" " lvsl %v9, %r5, %r4 \n" " vmrghb %v12, %v12, %v12 \n" " li %r9, 7 \n" " lvx %v11, 0, %r4 \n" " vmrghb %v9, %v9, %v9 \n" " lvx %v13, %r9, %r4 \n" " vpkuhum %v7, %v12, %v12 \n" " add %r4, %r4, %r5 \n" " vpkuhum %v8, %v9, %v9 \n" " vperm %v12, %v11, %v13, %v7 \n" " srawi %r6, %r6, 1 \n" " lvx %v11, 0, %r4 \n" " lvx %v13, %r9, %r4 \n" " addi %r6, %r6, -1 \n" " vperm %v9, %v11, %v13, %v8 \n" " lvx %v10, 0, %r3 \n" " mtctr %r6 \n" " add %r4, %r4, %r5 \n" " vavgub %v0, %v12, %v9 \n" " vavgub %v1, %v10, %v0 \n" "._L71: \n" " li %r9, 7 \n" " lvx %v13, %r9, %r4 \n" " lvx %v11, 0, %r4 \n" " lvx %v10, %r5, %r3 \n" " stvewx %v1, 0, %r3 \n" " vperm %v12, %v11, %v13, %v7 \n" " li %r9, 4 \n" " stvewx %v1, %r9, %r3 \n" " vavgub %v0, %v12, %v9 \n" " add %r4, %r4, %r5 \n" " li %r9, 7 \n" " vavgub %v1, %v10, %v0 \n" " lvx %v13, %r9, %r4 \n" " lvx %v11, 0, %r4 \n" " add %r3, %r3, %r5 \n" " vperm %v9, %v11, %v13, %v8 \n" " lvx %v10, %r5, %r3 \n" " stvewx %v1, 0, %r3 \n" " vavgub %v0, %v12, %v9 \n" " li %r9, 4 \n" " stvewx %v1, %r9, %r3 \n" " add %r4, %r4, %r5 \n" " vavgub %v1, %v10, %v0 \n" " add %r3, %r3, %r5 \n" " bdnz ._L71 \n" " li %r9, 7 \n" " lvx %v13, %r9, %r4 \n" " lvx %v11, 0, %r4 \n" " lvx %v10, %r5, %r3 \n" " vperm %v12, %v11, %v13, %v7 \n" " stvewx %v1, 0, %r3 \n" " li %r9, 4 \n" " vavgub %v0, %v12, %v9 \n" " stvewx %v1, %r9, %r3 \n" " add %r3, %r3, %r5 \n" " vavgub %v1, %v10, %v0 \n" " stvewx %v1, 0, %r3 \n" " stvewx %v1, %r9, %r3 \n" ); } static void MC_avg_xy_16_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v4, 0, %r4 \n" " vspltisb %v2, 1 \n" " li %r9, 16 \n" " lvx %v1, %r9, %r4 \n" " vaddubm %v3, %v4, %v2 \n" " lvx %v13, 0, %r4 \n" " add %r4, %r4, %r5 \n" " vperm %v10, %v13, %v1, %v3 \n" " li %r11, 16 \n" " vperm %v11, %v13, %v1, %v4 \n" " srawi %r6, %r6, 1 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r11, %r4 \n" " vavgub %v9, %v11, %v10 \n" " vxor %v8, %v11, %v10 \n" " addi %r6, %r6, -1 \n" " vperm %v10, %v13, %v1, %v3 \n" " lvx %v6, 0, %r3 \n" " mtctr %r6 \n" " vperm %v11, %v13, %v1, %v4 \n" " add %r9, %r5, %r5 \n" " add %r4, %r4, %r5 \n" " vxor %v5, %v11, %v10 \n" " vavgub %v7, %v11, %v10 \n" " vor %v1, %v8, %v5 \n" " vxor %v13, %v9, %v7 \n" " vand %v1, %v2, %v1 \n" " vavgub %v0, %v9, %v7 \n" " vand %v1, %v1, %v13 \n" " vsububm %v0, %v0, %v1 \n" " vavgub %v12, %v6, %v0 \n" "._L76: \n" " li %r11, 16 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r11, %r4 \n" " lvx %v6, %r5, %r3 \n" " stvx %v12, 0, %r3 \n" " vperm %v10, %v13, %v1, %v3 \n" " vperm %v11, %v13, %v1, %v4 \n" " add %r4, %r4, %r5 \n" " lvx %v13, 0, %r4 \n" " lvx %v1, %r11, %r4 \n" " vavgub %v9, %v11, %v10 \n" " vxor %v8, %v11, %v10 \n" " add %r4, %r4, %r5 \n" " vperm %v10, %v13, %v1, %v3 \n" " vavgub %v12, %v9, %v7 \n" " vperm %v11, %v13, %v1, %v4 \n" " vor %v0, %v8, %v5 \n" " vxor %v13, %v9, %v7 \n" " vxor %v5, %v11, %v10 \n" " vand %v0, %v2, %v0 \n" " vavgub %v7, %v11, %v10 \n" " vor %v1, %v8, %v5 \n" " vand %v0, %v0, %v13 \n" " vand %v1, %v2, %v1 \n" " vxor %v13, %v9, %v7 \n" " vsububm %v12, %v12, %v0 \n" " vand %v1, %v1, %v13 \n" " vavgub %v0, %v9, %v7 \n" " vavgub %v12, %v6, %v12 \n" " lvx %v6, %r9, %r3 \n" " vsububm %v0, %v0, %v1 \n" " stvx %v12, %r5, %r3 \n" " vavgub %v12, %v6, %v0 \n" " add %r3, %r3, %r9 \n" " bdnz ._L76 \n" " lvx %v1, %r11, %r4 \n" " lvx %v13, 0, %r4 \n" " lvx %v6, %r5, %r3 \n" " vperm %v10, %v13, %v1, %v3 \n" " stvx %v12, 0, %r3 \n" " vperm %v11, %v13, %v1, %v4 \n" " vxor %v8, %v11, %v10 \n" " vavgub %v9, %v11, %v10 \n" " vor %v0, %v8, %v5 \n" " vxor %v13, %v9, %v7 \n" " vand %v0, %v2, %v0 \n" " vavgub %v1, %v9, %v7 \n" " vand %v0, %v0, %v13 \n" " vsububm %v1, %v1, %v0 \n" " vavgub %v12, %v6, %v1 \n" " stvx %v12, %r5, %r3 \n" ); } static void MC_avg_xy_8_altivec (uint8_t * dest, uint8_t * ref, int stride, int height) { asm (" \n" " lvsl %v2, 0, %r4 \n" " vspltisb %v19, 1 \n" " lvsl %v3, %r5, %r4 \n" " vmrghb %v2, %v2, %v2 \n" " li %r9, 16 \n" " vmrghb %v3, %v3, %v3 \n" " lvx %v9, 0, %r4 \n" " vpkuhum %v2, %v2, %v2 \n" " lvx %v1, %r9, %r4 \n" " vpkuhum %v3, %v3, %v3 \n" " add %r4, %r4, %r5 \n" " vaddubm %v18, %v2, %v19 \n" " vperm %v11, %v9, %v1, %v2 \n" " srawi %r6, %r6, 1 \n" " vaddubm %v17, %v3, %v19 \n" " addi %r6, %r6, -1 \n" " vperm %v10, %v9, %v1, %v18 \n" " lvx %v4, 0, %r3 \n" " mtctr %r6 \n" " lvx %v1, %r9, %r4 \n" " lvx %v9, 0, %r4 \n" " vavgub %v8, %v11, %v10 \n" " vxor %v7, %v11, %v10 \n" " add %r4, %r4, %r5 \n" " vperm %v10, %v9, %v1, %v17 \n" " vperm %v11, %v9, %v1, %v3 \n" " vxor %v5, %v11, %v10 \n" " vavgub %v6, %v11, %v10 \n" " vor %v1, %v7, %v5 \n" " vxor %v13, %v8, %v6 \n" " vand %v1, %v19, %v1 \n" " vavgub %v0, %v8, %v6 \n" " vand %v1, %v1, %v13 \n" " vsububm %v0, %v0, %v1 \n" " vavgub %v13, %v4, %v0 \n" "._L81: \n" " li %r9, 16 \n" " lvx %v1, %r9, %r4 \n" " lvx %v9, 0, %r4 \n" " lvx %v4, %r5, %r3 \n" " stvewx %v13, 0, %r3 \n" " vperm %v10, %v9, %v1, %v18 \n" " vperm %v11, %v9, %v1, %v2 \n" " li %r9, 4 \n" " stvewx %v13, %r9, %r3 \n" " vxor %v7, %v11, %v10 \n" " add %r4, %r4, %r5 \n" " li %r9, 16 \n" " vavgub %v8, %v11, %v10 \n" " lvx %v1, %r9, %r4 \n" " vor %v0, %v7, %v5 \n" " lvx %v9, 0, %r4 \n" " vxor %v12, %v8, %v6 \n" " vand %v0, %v19, %v0 \n" " add %r3, %r3, %r5 \n" " vperm %v10, %v9, %v1, %v17 \n" " vavgub %v13, %v8, %v6 \n" " li %r9, 4 \n" " vperm %v11, %v9, %v1, %v3 \n" " vand %v0, %v0, %v12 \n" " add %r4, %r4, %r5 \n" " vxor %v5, %v11, %v10 \n" " vavgub %v6, %v11, %v10 \n" " vor %v1, %v7, %v5 \n" " vsububm %v13, %v13, %v0 \n" " vxor %v0, %v8, %v6 \n" " vand %v1, %v19, %v1 \n" " vavgub %v13, %v4, %v13 \n" " vand %v1, %v1, %v0 \n" " lvx %v4, %r5, %r3 \n" " vavgub %v0, %v8, %v6 \n" " stvewx %v13, 0, %r3 \n" " stvewx %v13, %r9, %r3 \n" " vsububm %v0, %v0, %v1 \n" " add %r3, %r3, %r5 \n" " vavgub %v13, %v4, %v0 \n" " bdnz ._L81 \n" " li %r9, 16 \n" " lvx %v1, %r9, %r4 \n" " lvx %v9, 0, %r4 \n" " lvx %v4, %r5, %r3 \n" " vperm %v10, %v9, %v1, %v18 \n" " stvewx %v13, 0, %r3 \n" " vperm %v11, %v9, %v1, %v2 \n" " li %r9, 4 \n" " stvewx %v13, %r9, %r3 \n" " vxor %v7, %v11, %v10 \n" " add %r3, %r3, %r5 \n" " vavgub %v8, %v11, %v10 \n" " vor %v0, %v7, %v5 \n" " vxor %v13, %v8, %v6 \n" " vand %v0, %v19, %v0 \n" " vavgub %v1, %v8, %v6 \n" " vand %v0, %v0, %v13 \n" " vsububm %v1, %v1, %v0 \n" " vavgub %v13, %v4, %v1 \n" " stvewx %v13, 0, %r3 \n" " stvewx %v13, %r9, %r3 \n" ); } MPEG2_MC_EXTERN (altivec) #endif /* ARCH_PPC */ #else /* HOST_OS_DARWIN */ #ifdef ENABLE_ALTIVEC #include "mpeg2_internal.h" #define vector_s16_t vector signed short #define vector_u16_t vector unsigned short #define vector_s8_t vector signed char #define vector_u8_t vector unsigned char #define vector_s32_t vector signed int #define vector_u32_t vector unsigned int void MC_put_o_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm, ref0, ref1, tmp; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp = vec_perm (ref0, ref1, perm); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, 0, dest); tmp = vec_perm (ref0, ref1, perm); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_perm (ref0, ref1, perm); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); vec_st (tmp, 0, dest); tmp = vec_perm (ref0, ref1, perm); vec_st (tmp, stride, dest); } void MC_put_o_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm0); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } void MC_put_x_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t permA, permB, ref0, ref1, tmp; permA = vec_lvsl (0, ref); permB = vec_add (permA, vec_splat_u8 (1)); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, 0, dest); tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); vec_st (tmp, 0, dest); tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); vec_st (tmp, stride, dest); } void MC_put_x_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; ones = vec_splat_u8 (1); tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); perm0B = vec_add (perm0A, ones); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B)); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B)); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } void MC_put_y_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (tmp0, tmp1); vec_st (tmp, stride, dest); } void MC_put_y_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm0); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (tmp0, tmp1); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (tmp0, tmp1); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (tmp0, tmp1); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (tmp0, tmp1); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } void MC_put_xy_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; vector_u8_t ones; ones = vec_splat_u8 (1); permA = vec_lvsl (0, ref); permB = vec_add (permA, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_st (tmp, stride, dest); dest += 2*stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); vec_st (tmp, stride, dest); } void MC_put_xy_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; vector_u8_t avg0, avg1, xor0, xor1, tmp, ones; ones = vec_splat_u8 (1); perm0A = vec_lvsl (0, ref); perm0A = vec_mergeh (perm0A, perm0A); perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); perm0B = vec_add (perm0A, ones); perm1A = vec_lvsl (stride, ref); perm1A = vec_mergeh (perm1A, perm1A); perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1))); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } #if 0 void MC_put_xy_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t permA, permB, ref0, ref1, A, B, C, D, tmp, zero, ones; vector_u16_t splat2, temp; ones = vec_splat_u8 (1); permA = vec_lvsl (0, ref); permB = vec_add (permA, ones); zero = vec_splat_u8 (0); splat2 = vec_splat_u16 (2); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); C = vec_perm (ref0, ref1, permA); D = vec_perm (ref0, ref1, permB); temp = vec_add (vec_add ((vector_u16_t)vec_mergeh (zero, A), (vector_u16_t)vec_mergeh (zero, B)), vec_add ((vector_u16_t)vec_mergeh (zero, C), (vector_u16_t)vec_mergeh (zero, D))); temp = vec_sr (vec_add (temp, splat2), splat2); tmp = vec_pack (temp, temp); vec_st (tmp, 0, dest); dest += stride; tmp = vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB)); } while (--height); } #endif void MC_avg_o_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm, ref0, ref1, tmp, prev; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (0, dest); tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_perm (ref0, ref1, perm)); vec_st (tmp, stride, dest); } void MC_avg_o_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, ref0, ref1, prev; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (0, dest); tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_avg (prev, vec_perm (ref0, ref1, perm0)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_perm (ref0, ref1, perm1)); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } void MC_avg_x_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t permA, permB, ref0, ref1, tmp, prev; permA = vec_lvsl (0, ref); permB = vec_add (permA, vec_splat_u8 (1)); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); prev = vec_ld (0, dest); ref += stride; tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, permA), vec_perm (ref0, ref1, permB))); vec_st (tmp, stride, dest); } void MC_avg_x_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ones, tmp0, tmp1, ref0, ref1; vector_u8_t prev; ones = vec_splat_u8 (1); tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0A = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); perm0B = vec_add (perm0A, ones); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1A = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); prev = vec_ld (0, dest); ref += stride; tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B))); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm0A), vec_perm (ref0, ref1, perm0B))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (8, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp0, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp0, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_avg (prev, vec_avg (vec_perm (ref0, ref1, perm1A), vec_perm (ref0, ref1, perm1B))); vec_ste ((vector_u32_t)tmp1, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp1, 4, (unsigned int *)dest); } void MC_avg_y_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm, ref0, ref1, tmp0, tmp1, tmp, prev; perm = vec_lvsl (0, ref); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (0, dest); tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; tmp1 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (15, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); tmp0 = vec_perm (ref0, ref1, perm); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); vec_st (tmp, stride, dest); } void MC_avg_y_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0, perm1, tmp0, tmp1, tmp, ref0, ref1, prev; tmp0 = vec_lvsl (0, ref); tmp0 = vec_mergeh (tmp0, tmp0); perm0 = vec_pack ((vector_u16_t)tmp0, (vector_u16_t)tmp0); tmp1 = vec_lvsl (stride, ref); tmp1 = vec_mergeh (tmp1, tmp1); perm1 = vec_pack ((vector_u16_t)tmp1, (vector_u16_t)tmp1); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; tmp0 = vec_perm (ref0, ref1, perm0); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (0, dest); tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp1 = vec_perm (ref0, ref1, perm1); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (7, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; tmp0 = vec_perm (ref0, ref1, perm0); tmp = vec_avg (prev, vec_avg (tmp0, tmp1)); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } void MC_avg_xy_16_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t permA, permB, ref0, ref1, A, B, avg0, avg1, xor0, xor1, tmp; vector_u8_t ones, prev; ones = vec_splat_u8 (1); permA = vec_lvsl (0, ref); permB = vec_add (permA, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (2*stride, dest); vec_st (tmp, stride, dest); dest += 2*stride; A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); prev = vec_ld (stride, dest); vec_st (tmp, 0, dest); A = vec_perm (ref0, ref1, permA); B = vec_perm (ref0, ref1, permB); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); vec_st (tmp, stride, dest); } void MC_avg_xy_8_altivec (unsigned char * dest, unsigned char * ref, int stride, int height) { vector_u8_t perm0A, perm0B, perm1A, perm1B, ref0, ref1, A, B; vector_u8_t avg0, avg1, xor0, xor1, tmp, ones, prev; ones = vec_splat_u8 (1); perm0A = vec_lvsl (0, ref); perm0A = vec_mergeh (perm0A, perm0A); perm0A = vec_pack ((vector_u16_t)perm0A, (vector_u16_t)perm0A); perm0B = vec_add (perm0A, ones); perm1A = vec_lvsl (stride, ref); perm1A = vec_mergeh (perm1A, perm1A); perm1A = vec_pack ((vector_u16_t)perm1A, (vector_u16_t)perm1A); perm1B = vec_add (perm1A, ones); height = (height >> 1) - 1; ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (0, dest); A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); do { ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); ref += stride; prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm1A); B = vec_perm (ref0, ref1, perm1B); avg1 = vec_avg (A, B); xor1 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); } while (--height); ref0 = vec_ld (0, ref); ref1 = vec_ld (16, ref); prev = vec_ld (stride, dest); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); dest += stride; A = vec_perm (ref0, ref1, perm0A); B = vec_perm (ref0, ref1, perm0B); avg0 = vec_avg (A, B); xor0 = vec_xor (A, B); tmp = vec_avg (prev, vec_sub (vec_avg (avg0, avg1), vec_and (vec_and (ones, vec_or (xor0, xor1)), vec_xor (avg0, avg1)))); vec_ste ((vector_u32_t)tmp, 0, (unsigned int *)dest); vec_ste ((vector_u32_t)tmp, 4, (unsigned int *)dest); } MPEG2_MC_EXTERN (altivec) #endif /* ENABLE_ALTIVEC */ #endif /* HOST_OS_DARWIN */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/xvmc.h����������������������������������������������������������0000644�0001750�0001750�00000002263�14647725152�016226� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * mpeg2_internal.h * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef _XVMC_H #include "libmpeg2_accel.h" /* slice_xvmc.c */ void mpeg2_xvmc_slice (mpeg2dec_accel_t *accel, picture_t * picture, int code, uint8_t * buffer); void xvmc_setup_scan_ptable( void ); #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/slice.c���������������������������������������������������������0000644�0001750�0001750�00000150674�14647725152�016355� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * slice.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include <inttypes.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include "mpeg2_internal.h" #include <xine/attributes.h> #include "vlc.h" static const int non_linear_quantizer_scale [] = { 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 }; static inline int get_macroblock_modes (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int macroblock_modes; const MBtab * tab; switch (picture->picture_coding_type) { case I_TYPE: tab = MB_I + UBITS (bit_buf, 1); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if ((! (picture->frame_pred_frame_dct)) && (picture->picture_structure == FRAME_PICTURE)) { macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; case P_TYPE: tab = MB_P + UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (picture->picture_structure != FRAME_PICTURE) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); } return macroblock_modes; } else if (picture->frame_pred_frame_dct) { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) macroblock_modes |= MC_FRAME; return macroblock_modes; } else { if (macroblock_modes & MACROBLOCK_MOTION_FORWARD) { macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); } if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; } case B_TYPE: tab = MB_B + UBITS (bit_buf, 6); DUMPBITS (bit_buf, bits, tab->len); macroblock_modes = tab->modes; if (picture->picture_structure != FRAME_PICTURE) { if (! (macroblock_modes & MACROBLOCK_INTRA)) { macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); } return macroblock_modes; } else if (picture->frame_pred_frame_dct) { /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */ macroblock_modes |= MC_FRAME; return macroblock_modes; } else { if (macroblock_modes & MACROBLOCK_INTRA) goto intra; macroblock_modes |= UBITS (bit_buf, 2) * MOTION_TYPE_BASE; DUMPBITS (bit_buf, bits, 2); if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN)) { intra: macroblock_modes |= UBITS (bit_buf, 1) * DCT_TYPE_INTERLACED; DUMPBITS (bit_buf, bits, 1); } return macroblock_modes; } case D_TYPE: DUMPBITS (bit_buf, bits, 1); return MACROBLOCK_INTRA; default: return 0; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_quantizer_scale (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int quantizer_scale_code; quantizer_scale_code = UBITS (bit_buf, 5); DUMPBITS (bit_buf, bits, 5); if (picture->q_scale_type) return non_linear_quantizer_scale [quantizer_scale_code]; else return quantizer_scale_code << 1; #undef bit_buf #undef bits #undef bit_ptr } static inline int get_motion_delta (picture_t * picture, int f_code) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int delta; int sign; const MVtab * tab; if (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 1); return 0; } else if (bit_buf >= 0x0c000000) { tab = MV_4 + UBITS (bit_buf, 4); delta = (tab->delta << f_code) + 1; bits += tab->len + f_code + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) delta += UBITS (bit_buf, f_code); bit_buf <<= f_code; return (delta ^ sign) - sign; } else { tab = MV_10 + UBITS (bit_buf, 10); delta = (tab->delta << f_code) + 1; bits += tab->len + 1; bit_buf <<= tab->len; sign = SBITS (bit_buf, 1); bit_buf <<= 1; if (f_code) { NEEDBITS (bit_buf, bits, bit_ptr); delta += UBITS (bit_buf, f_code); DUMPBITS (bit_buf, bits, f_code); } return (delta ^ sign) - sign; } #undef bit_buf #undef bits #undef bit_ptr } static inline int bound_motion_vector (int vec, int f_code) { #if 1 unsigned int limit; int sign; limit = 16 << f_code; if ((unsigned int)(vec + limit) < 2 * limit) return vec; else { sign = ((int32_t)vec) >> 31; return vec - ((2 * limit) ^ sign) + sign; } #else return ((int32_t)vector << (27 - f_code)) >> (27 - f_code); #endif } static inline int get_dmv (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const DMVtab * tab; tab = DMV_2 + UBITS (bit_buf, 2); DUMPBITS (bit_buf, bits, tab->len); return tab->dmv; #undef bit_buf #undef bits #undef bit_ptr } static inline int get_coded_block_pattern (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const CBPtab * tab; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x20000000) { tab = CBP_7 + (UBITS (bit_buf, 7) - 16); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; } else { tab = CBP_9 + UBITS (bit_buf, 9); DUMPBITS (bit_buf, bits, tab->len); return tab->cbp; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_luma_dc_dct_diff (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const DCtab * tab; int size; int dc_diff; if (bit_buf < 0xf8000000) { tab = DC_lum_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { bits += tab->len + size; bit_buf <<= tab->len; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff; } else { DUMPBITS (bit_buf, bits, 3); return 0; } } else { tab = DC_long + (UBITS (bit_buf, 9) - 0x1e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len); NEEDBITS (bit_buf, bits, bit_ptr); dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); DUMPBITS (bit_buf, bits, size); return dc_diff; } #undef bit_buf #undef bits #undef bit_ptr } static inline int get_chroma_dc_dct_diff (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) const DCtab * tab; int size; int dc_diff; if (bit_buf < 0xf8000000) { tab = DC_chrom_5 + UBITS (bit_buf, 5); size = tab->size; if (size) { bits += tab->len + size; bit_buf <<= tab->len; dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); bit_buf <<= size; return dc_diff; } else { DUMPBITS (bit_buf, bits, 2); return 0; } } else { tab = DC_long + (UBITS (bit_buf, 10) - 0x3e0); size = tab->size; DUMPBITS (bit_buf, bits, tab->len + 1); NEEDBITS (bit_buf, bits, bit_ptr); dc_diff = UBITS (bit_buf, size) - UBITS (SBITS (~bit_buf, 1), size); DUMPBITS (bit_buf, bits, size); return dc_diff; } #undef bit_buf #undef bits #undef bit_ptr } #define SATURATE(val) \ do { \ if ((uint32_t)(val + 2048) > 4095) \ val = (val > 0) ? 2047 : -2048; \ } while (0) static void get_intra_block_B14 (picture_t * picture) { int i; int j; int val; uint8_t * scan = picture->scan; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; dest = picture->DCTblock; i = 0; mismatch = ~dest[0]; bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = (SBITS (bit_buf, 12) * quantizer_scale * quant_matrix[j]) / 16; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 1; DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_intra_block_B15 (picture_t * picture) { int i; int j; int val; uint8_t * scan = picture->scan; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; dest = picture->DCTblock; i = 0; mismatch = ~dest[0]; bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x04000000) { tab = DCT_B15_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) { normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else { /* end of block. I commented out this code because if we */ /* dont exit here we will still exit at the later test :) */ /* if (i >= 128) break; */ /* end of block */ /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check against buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = (SBITS (bit_buf, 12) * quantizer_scale * quant_matrix[j]) / 16; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } } else if (bit_buf >= 0x02000000) { tab = DCT_B15_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 1; DUMPBITS (bit_buf, bits, 4); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_non_intra_block (picture_t * picture) { int i; int j; int val; uint8_t * scan = picture->scan; uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; int mismatch; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; i = -1; mismatch = 1; dest = picture->DCTblock; bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x28000000) { tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); goto entry_1; } else goto entry_2; while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); entry_1: i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; mismatch ^= val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } entry_2: if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = 2 * (SBITS (bit_buf, 12) + SBITS (bit_buf, 1)) + 1; val = (val * quantizer_scale * quant_matrix[j]) / 32; SATURATE (val); dest[j] = val; mismatch ^= val; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } dest[63] ^= mismatch & 1; DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_mpeg1_intra_block (picture_t * picture) { int i; int j; int val; uint8_t * scan = picture->scan; uint8_t * quant_matrix = picture->intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; i = 0; dest = picture->DCTblock; bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = (tab->level * quantizer_scale * quant_matrix[j]) >> 4; /* oddification */ val = (val - 1) | 1; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = SBITS (bit_buf, 8); if (! (val & 0x7f)) { DUMPBITS (bit_buf, bits, 8); val = UBITS (bit_buf, 8) + 2 * val; } val = (val * quantizer_scale * quant_matrix[j]) / 16; /* oddification */ val = (val + ~SBITS (val, 1)) | 1; SATURATE (val); dest[j] = val; DUMPBITS (bit_buf, bits, 8); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static void get_mpeg1_non_intra_block (picture_t * picture) { int i; int j; int val; uint8_t * scan = picture->scan; uint8_t * quant_matrix = picture->non_intra_quantizer_matrix; int quantizer_scale = picture->quantizer_scale; const DCTtab * tab; uint32_t bit_buf; int bits; uint8_t * bit_ptr; int16_t * dest; i = -1; dest = picture->DCTblock; bit_buf = picture->bitstream_buf; bits = picture->bitstream_bits; bit_ptr = picture->bitstream_ptr; NEEDBITS (bit_buf, bits, bit_ptr); if (bit_buf >= 0x28000000) { tab = DCT_B14DC_5 + (UBITS (bit_buf, 5) - 5); goto entry_1; } else goto entry_2; while (1) { if (bit_buf >= 0x28000000) { tab = DCT_B14AC_5 + (UBITS (bit_buf, 5) - 5); entry_1: i += tab->run; if (i >= 64) break; /* end of block */ normal_code: j = scan[i]; bit_buf <<= tab->len; bits += tab->len + 1; val = ((2*tab->level+1) * quantizer_scale * quant_matrix[j]) >> 5; /* oddification */ val = (val - 1) | 1; /* if (bitstream_get (1)) val = -val; */ val = (val ^ SBITS (bit_buf, 1)) - SBITS (bit_buf, 1); SATURATE (val); dest[j] = val; bit_buf <<= 1; NEEDBITS (bit_buf, bits, bit_ptr); continue; } entry_2: if (bit_buf >= 0x04000000) { tab = DCT_B14_8 + (UBITS (bit_buf, 8) - 4); i += tab->run; if (i < 64) goto normal_code; /* escape code */ i += UBITS (bit_buf << 6, 6) - 64; if (i >= 64) break; /* illegal, check needed to avoid buffer overflow */ j = scan[i]; DUMPBITS (bit_buf, bits, 12); NEEDBITS (bit_buf, bits, bit_ptr); val = SBITS (bit_buf, 8); if (! (val & 0x7f)) { DUMPBITS (bit_buf, bits, 8); val = UBITS (bit_buf, 8) + 2 * val; } val = 2 * (val + SBITS (val, 1)) + 1; val = (val * quantizer_scale * quant_matrix[j]) / 32; /* oddification */ val = (val + ~SBITS (val, 1)) | 1; SATURATE (val); dest[j] = val; DUMPBITS (bit_buf, bits, 8); NEEDBITS (bit_buf, bits, bit_ptr); continue; } else if (bit_buf >= 0x02000000) { tab = DCT_B14_10 + (UBITS (bit_buf, 10) - 8); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00800000) { tab = DCT_13 + (UBITS (bit_buf, 13) - 16); i += tab->run; if (i < 64) goto normal_code; } else if (bit_buf >= 0x00200000) { tab = DCT_15 + (UBITS (bit_buf, 15) - 16); i += tab->run; if (i < 64) goto normal_code; } else { tab = DCT_16 + UBITS (bit_buf, 16); bit_buf <<= 16; GETWORD (bit_buf, bits + 16, bit_ptr); i += tab->run; if (i < 64) goto normal_code; } break; /* illegal, check needed to avoid buffer overflow */ } DUMPBITS (bit_buf, bits, 2); /* dump end of block code */ picture->bitstream_buf = bit_buf; picture->bitstream_bits = bits; picture->bitstream_ptr = bit_ptr; } static inline void slice_intra_DCT (picture_t * picture, int cc, uint8_t * dest, int stride) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) NEEDBITS (bit_buf, bits, bit_ptr); /* Get the intra DC coefficient and inverse quantize it */ if (cc == 0) picture->dc_dct_pred[0] += get_luma_dc_dct_diff (picture); else picture->dc_dct_pred[cc] += get_chroma_dc_dct_diff (picture); picture->DCTblock[0] = picture->dc_dct_pred[cc] << (3 - picture->intra_dc_precision); if (picture->mpeg1) { if (picture->picture_coding_type != D_TYPE) get_mpeg1_intra_block (picture); } else if (picture->intra_vlc_format) get_intra_block_B15 (picture); else get_intra_block_B14 (picture); mpeg2_idct_copy (picture->DCTblock, dest, stride); #undef bit_buf #undef bits #undef bit_ptr } static inline void slice_non_intra_DCT (picture_t * picture, uint8_t * dest, int stride) { if (picture->mpeg1) get_mpeg1_non_intra_block (picture); else get_non_intra_block (picture); mpeg2_idct_add (picture->DCTblock, dest, stride); } #define MOTION(table,ref,motion_x,motion_y,size,y) \ pos_x = 2 * picture->offset + motion_x; \ pos_y = 2 * picture->v_offset + motion_y + 2 * y; \ if (pos_x > picture->limit_x) { \ pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; \ motion_x = pos_x - 2 * picture->offset; \ } \ if (pos_y > picture->limit_y_ ## size){ \ pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y_ ## size; \ motion_y = pos_y - 2 * picture->v_offset - 2 * y; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ table[xy_half] (picture->dest[0] + y * picture->pitches[0] + \ picture->offset, ref[0] + (pos_x >> 1) + \ (pos_y >> 1) * picture->pitches[0], picture->pitches[0], \ size); \ motion_x /= 2; motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ table[4+xy_half] (picture->dest[1] + y/2 * picture->pitches[1] + \ (picture->offset >> 1), ref[1] + \ (((picture->offset + motion_x) >> 1) + \ ((((picture->v_offset + motion_y) >> 1) + y/2) * \ picture->pitches[1])), picture->pitches[1], size/2); \ table[4+xy_half] (picture->dest[2] + y/2 * picture->pitches[2] + \ (picture->offset >> 1), ref[2] + \ (((picture->offset + motion_x) >> 1) + \ ((((picture->v_offset + motion_y) >> 1) + y/2) * \ picture->pitches[2])), picture->pitches[2], size/2) \ #define MOTION_FIELD(table,ref,motion_x,motion_y,dest_field,op,src_field) \ pos_x = 2 * picture->offset + motion_x; \ pos_y = picture->v_offset + motion_y; \ if (pos_x > picture->limit_x) { \ pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; \ motion_x = pos_x - 2 * picture->offset; \ } \ if (pos_y > picture->limit_y){ \ pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y; \ motion_y = pos_y - picture->v_offset; \ } \ xy_half = ((pos_y & 1) << 1) | (pos_x & 1); \ table[xy_half] (picture->dest[0] + dest_field * picture->pitches[0] + \ picture->offset, \ (ref[0] + (pos_x >> 1) + \ ((pos_y op) + src_field) * picture->pitches[0]), \ 2 * picture->pitches[0], 8); \ motion_x /= 2; motion_y /= 2; \ xy_half = ((motion_y & 1) << 1) | (motion_x & 1); \ table[4+xy_half] (picture->dest[1] + dest_field * picture->pitches[1] + \ (picture->offset >> 1), ref[1] + \ (((picture->offset + motion_x) >> 1) + \ (((picture->v_offset >> 1) + \ (motion_y op) + src_field) * picture->pitches[1])), \ 2 * picture->pitches[1], 4); \ table[4+xy_half] (picture->dest[2] + dest_field * picture->pitches[2] + \ (picture->offset >> 1), ref[2] + \ (((picture->offset + motion_x) >> 1) + \ (((picture->v_offset >> 1) + \ (motion_y op) + src_field) * picture->pitches[2])), \ 2 * picture->pitches[2], 4) static void motion_mp1 (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; unsigned int pos_x, pos_y, xy_half; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = (motion->pmv[0][0] + (get_motion_delta (picture, motion->f_code[0]) << motion->f_code[1])); motion_x = bound_motion_vector (motion_x, motion->f_code[0] + motion->f_code[1]); motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[0][1] + (get_motion_delta (picture, motion->f_code[0]) << motion->f_code[1])); motion_y = bound_motion_vector (motion_y, motion->f_code[0] + motion->f_code[1]); motion->pmv[0][1] = motion_y; MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); #undef bit_buf #undef bits #undef bit_ptr } static void motion_fr_frame (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; unsigned int pos_x, pos_y, xy_half; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = motion->pmv[0][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[0][1] + get_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); #undef bit_buf #undef bits #undef bit_ptr } static void motion_fr_field (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y, field; unsigned int pos_x, pos_y, xy_half; NEEDBITS (bit_buf, bits, bit_ptr); field = UBITS (bit_buf, 1); DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[0][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture, motion->f_code[1]); /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[0][1] = motion_y << 1; MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 0, & ~1, field); NEEDBITS (bit_buf, bits, bit_ptr); field = UBITS (bit_buf, 1); DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[1][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = (motion->pmv[1][1] >> 1) + get_motion_delta (picture, motion->f_code[1]); /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[1][1] = motion_y << 1; MOTION_FIELD (table, motion->ref[0], motion_x, motion_y, 1, & ~1, field); #undef bit_buf #undef bits #undef bit_ptr } static void motion_fr_dmv (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y, dmv_x, dmv_y, m, other_x, other_y; unsigned int pos_x, pos_y, xy_half, offset; (void)table; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = motion->pmv[0][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); dmv_x = get_dmv (picture); motion_y = (motion->pmv[0][1] >> 1) + get_motion_delta (picture, motion->f_code[1]); /* motion_y = bound_motion_vector (motion_y, motion->f_code[1]); */ motion->pmv[1][1] = motion->pmv[0][1] = motion_y << 1; dmv_y = get_dmv (picture); m = picture->top_field_first ? 1 : 3; other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y - 1; MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 0, | 1, 0); m = picture->top_field_first ? 3 : 1; other_x = ((motion_x * m + (motion_x > 0)) >> 1) + dmv_x; other_y = ((motion_y * m + (motion_y > 0)) >> 1) + dmv_y + 1; MOTION_FIELD (mpeg2_mc.put, motion->ref[0], other_x, other_y, 1, & ~1, 0); pos_x = 2 * picture->offset + motion_x; pos_y = picture->v_offset + motion_y; if(pos_x > picture->limit_x){ pos_x = ((int)pos_x < 0) ? 0 : picture->limit_x; motion_x = pos_x - 2 * picture->offset; } if(pos_y > picture->limit_y){ pos_y = ((int)pos_y < 0) ? 0 : picture->limit_y; motion_y = pos_y - picture->v_offset; } xy_half = ((pos_y & 1) << 1) | (pos_x & 1); offset = (pos_x >> 1) + (pos_y & ~1) * picture->pitches[0]; mpeg2_mc.avg[xy_half] (picture->dest[0] + picture->offset, motion->ref[0][0] + offset, 2 * picture->pitches[0], 8); mpeg2_mc.avg[xy_half] (picture->dest[0] + picture->pitches[0] + picture->offset, motion->ref[0][0] + picture->pitches[0] + offset, 2 * picture->pitches[0], 8); motion_x /= 2; motion_y /= 2; xy_half = ((motion_y & 1) << 1) | (motion_x & 1); offset = (((picture->offset + motion_x) >> 1) + (((picture->v_offset >> 1) + (motion_y & ~1)) * picture->pitches[1])); mpeg2_mc.avg[4+xy_half] (picture->dest[1] + (picture->offset >> 1), motion->ref[0][1] + offset, 2 * picture->pitches[1], 4); mpeg2_mc.avg[4+xy_half] (picture->dest[1] + picture->pitches[1] + (picture->offset >> 1), motion->ref[0][1] + picture->pitches[1] + offset, 2 * picture->pitches[1], 4); offset = (((picture->offset + motion_x) >> 1) + (((picture->v_offset >> 1) + (motion_y & ~1)) * picture->pitches[2])); mpeg2_mc.avg[4+xy_half] (picture->dest[2] + (picture->offset >> 1), motion->ref[0][2] + offset, 2 * picture->pitches[2], 4); mpeg2_mc.avg[4+xy_half] (picture->dest[2] + picture->pitches[2] + (picture->offset >> 1), motion->ref[0][2] + picture->pitches[2] + offset, 2 * picture->pitches[2], 4); #undef bit_buf #undef bits #undef bit_ptr } static void motion_reuse (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { int motion_x, motion_y; unsigned int pos_x, pos_y, xy_half; motion_x = motion->pmv[0][0]; motion_y = motion->pmv[0][1]; MOTION (table, motion->ref[0], motion_x, motion_y, 16, 0); } static void motion_zero (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { table[0] (picture->dest[0] + picture->offset, (motion->ref[0][0] + picture->offset + picture->v_offset * picture->pitches[0]), picture->pitches[0], 16); table[4] (picture->dest[1] + (picture->offset >> 1), motion->ref[0][1] + (picture->offset >> 1) + (picture->v_offset >> 1) * picture->pitches[1], picture->pitches[1], 8); table[4] (picture->dest[2] + (picture->offset >> 1), motion->ref[0][2] + (picture->offset >> 1) + (picture->v_offset >> 1) * picture->pitches[2], picture->pitches[2], 8); } /* like motion_frame, but parsing without actual motion compensation */ static void motion_fr_conceal (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (picture->f_motion.pmv[0][0] + get_motion_delta (picture, picture->f_motion.f_code[0])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (picture->f_motion.pmv[0][1] + get_motion_delta (picture, picture->f_motion.f_code[1])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_field (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; uint8_t ** ref_field; unsigned int pos_x, pos_y, xy_half; NEEDBITS (bit_buf, bits, bit_ptr); ref_field = motion->ref2[UBITS (bit_buf, 1)]; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[0][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[0][1] + get_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; MOTION (table, ref_field, motion_x, motion_y, 16, 0); #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_16x8 (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y; uint8_t ** ref_field; unsigned int pos_x, pos_y, xy_half; NEEDBITS (bit_buf, bits, bit_ptr); ref_field = motion->ref2[UBITS (bit_buf, 1)]; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[0][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[0][1] + get_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[0][1] = motion_y; MOTION (table, ref_field, motion_x, motion_y, 8, 0); NEEDBITS (bit_buf, bits, bit_ptr); ref_field = motion->ref2[UBITS (bit_buf, 1)]; DUMPBITS (bit_buf, bits, 1); motion_x = motion->pmv[1][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); motion_y = motion->pmv[1][1] + get_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion_y; MOTION (table, ref_field, motion_x, motion_y, 8, 8); #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_dmv (picture_t * picture, motion_t * motion, void (** table) (uint8_t *, uint8_t *, int, int)) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int motion_x, motion_y, other_x, other_y; unsigned int pos_x, pos_y, xy_half; (void)table; NEEDBITS (bit_buf, bits, bit_ptr); motion_x = motion->pmv[0][0] + get_motion_delta (picture, motion->f_code[0]); motion_x = bound_motion_vector (motion_x, motion->f_code[0]); motion->pmv[1][0] = motion->pmv[0][0] = motion_x; NEEDBITS (bit_buf, bits, bit_ptr); other_x = ((motion_x + (motion_x > 0)) >> 1) + get_dmv (picture); motion_y = motion->pmv[0][1] + get_motion_delta (picture, motion->f_code[1]); motion_y = bound_motion_vector (motion_y, motion->f_code[1]); motion->pmv[1][1] = motion->pmv[0][1] = motion_y; other_y = (((motion_y + (motion_y > 0)) >> 1) + get_dmv (picture) + picture->dmv_offset); MOTION (mpeg2_mc.put, motion->ref[0], motion_x, motion_y, 16, 0); MOTION (mpeg2_mc.avg, motion->ref[1], other_x, other_y, 16, 0); #undef bit_buf #undef bits #undef bit_ptr } static void motion_fi_conceal (picture_t * picture) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int tmp; NEEDBITS (bit_buf, bits, bit_ptr); DUMPBITS (bit_buf, bits, 1); /* remove field_select */ tmp = (picture->f_motion.pmv[0][0] + get_motion_delta (picture, picture->f_motion.f_code[0])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[0]); picture->f_motion.pmv[1][0] = picture->f_motion.pmv[0][0] = tmp; NEEDBITS (bit_buf, bits, bit_ptr); tmp = (picture->f_motion.pmv[0][1] + get_motion_delta (picture, picture->f_motion.f_code[1])); tmp = bound_motion_vector (tmp, picture->f_motion.f_code[1]); picture->f_motion.pmv[1][1] = picture->f_motion.pmv[0][1] = tmp; DUMPBITS (bit_buf, bits, 1); /* remove marker_bit */ #undef bit_buf #undef bits #undef bit_ptr } #define MOTION_CALL(routine,direction) \ do { \ if ((direction) & MACROBLOCK_MOTION_FORWARD) \ routine (picture, &(picture->f_motion), mpeg2_mc.put); \ if ((direction) & MACROBLOCK_MOTION_BACKWARD) \ routine (picture, &(picture->b_motion), \ ((direction) & MACROBLOCK_MOTION_FORWARD ? \ mpeg2_mc.avg : mpeg2_mc.put)); \ } while (0) #define NEXT_MACROBLOCK \ do { \ picture->offset += 16; \ if (picture->offset == picture->coded_picture_width) { \ do { /* just so we can use the break statement */ \ if (picture->current_frame->proc_slice) { \ picture->current_frame->proc_slice (picture->current_frame, \ picture->dest); \ } \ picture->dest[0] += 16 * picture->pitches[0]; \ picture->dest[1] += 8 * picture->pitches[1]; \ picture->dest[2] += 8 * picture->pitches[2]; \ } while (0); \ picture->v_offset += 16; \ if (picture->v_offset > picture->limit_y) { \ if (mpeg2_cpu_state_restore) \ mpeg2_cpu_state_restore (&cpu_state); \ return; \ } \ picture->offset = 0; \ } \ } while (0) static inline int slice_init (picture_t * picture, int code) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) int offset, height; struct vo_frame_s * forward_reference_frame; struct vo_frame_s * backward_reference_frame; const MBAtab * mba; offset = picture->picture_structure == BOTTOM_FIELD; picture->pitches[0] = picture->current_frame->pitches[0]; picture->pitches[1] = picture->current_frame->pitches[1]; picture->pitches[2] = picture->current_frame->pitches[2]; if( picture->forward_reference_frame ) { forward_reference_frame = picture->forward_reference_frame; } else { /* return 1; */ forward_reference_frame = picture->current_frame; } if( picture->backward_reference_frame ) { backward_reference_frame = picture->backward_reference_frame; } else { /* return 1; */ backward_reference_frame = picture->current_frame; } picture->f_motion.ref[0][0] = forward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); picture->f_motion.ref[0][1] = forward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); picture->f_motion.ref[0][2] = forward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); picture->b_motion.ref[0][0] = backward_reference_frame->base[0] + (offset ? picture->pitches[0] : 0); picture->b_motion.ref[0][1] = backward_reference_frame->base[1] + (offset ? picture->pitches[1] : 0); picture->b_motion.ref[0][2] = backward_reference_frame->base[2] + (offset ? picture->pitches[2] : 0); if (picture->picture_structure != FRAME_PICTURE) { uint8_t ** forward_ref; int bottom_field; bottom_field = (picture->picture_structure == BOTTOM_FIELD); picture->dmv_offset = bottom_field ? 1 : -1; picture->f_motion.ref2[0] = picture->f_motion.ref[bottom_field]; picture->f_motion.ref2[1] = picture->f_motion.ref[!bottom_field]; picture->b_motion.ref2[0] = picture->b_motion.ref[bottom_field]; picture->b_motion.ref2[1] = picture->b_motion.ref[!bottom_field]; forward_ref = forward_reference_frame->base; if (picture->second_field && (picture->picture_coding_type != B_TYPE)) forward_ref = picture->current_frame->base; picture->f_motion.ref[1][0] = forward_ref[0] + (bottom_field ? 0 : picture->pitches[0]); picture->f_motion.ref[1][1] = forward_ref[1] + (bottom_field ? 0 : picture->pitches[1]); picture->f_motion.ref[1][2] = forward_ref[2] + (bottom_field ? 0 : picture->pitches[2]); picture->b_motion.ref[1][0] = backward_reference_frame->base[0] + (bottom_field ? 0 : picture->pitches[0]); picture->b_motion.ref[1][1] = backward_reference_frame->base[1] + (bottom_field ? 0 : picture->pitches[1]); picture->b_motion.ref[1][2] = backward_reference_frame->base[2] + (bottom_field ? 0 : picture->pitches[2]); } picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; picture->v_offset = (code - 1) * 16; offset = (code - 1); if (picture->picture_structure != FRAME_PICTURE) offset = 2 * offset; picture->dest[0] = picture->current_frame->base[0] + picture->pitches[0] * offset * 16; picture->dest[1] = picture->current_frame->base[1] + picture->pitches[1] * offset * 8; picture->dest[2] = picture->current_frame->base[2] + picture->pitches[2] * offset * 8; height = picture->coded_picture_height; switch (picture->picture_structure) { case BOTTOM_FIELD: picture->dest[0] += picture->pitches[0]; picture->dest[1] += picture->pitches[1]; picture->dest[2] += picture->pitches[2]; /* fall through */ case TOP_FIELD: picture->pitches[0] <<= 1; picture->pitches[1] <<= 1; picture->pitches[2] <<= 1; height >>= 1; } picture->limit_x = 2 * picture->coded_picture_width - 32; picture->limit_y_16 = 2 * height - 32; picture->limit_y_8 = 2 * height - 16; picture->limit_y = height - 16; picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 1 << (picture->intra_dc_precision + 7); picture->quantizer_scale = get_quantizer_scale (picture); /* ignore intra_slice and all the extra data */ while (bit_buf & 0x80000000) { DUMPBITS (bit_buf, bits, 9); NEEDBITS (bit_buf, bits, bit_ptr); } /* decode initial macroblock address increment */ offset = 0; while (1) { if (bit_buf >= 0x08000000) { mba = MBA_5 + (UBITS (bit_buf, 6) - 2); break; } else if (bit_buf >= 0x01800000) { mba = MBA_11 + (UBITS (bit_buf, 12) - 24); break; } else switch (UBITS (bit_buf, 12)) { case 8: /* macroblock_escape */ offset += 33; DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; case 15: /* macroblock_stuffing (MPEG1 only) */ bit_buf &= 0xfffff; DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; default: /* error */ return 1; } } DUMPBITS (bit_buf, bits, mba->len + 1); picture->offset = (offset + mba->mba) << 4; while (picture->offset - picture->coded_picture_width >= 0) { picture->offset -= picture->coded_picture_width; if ((picture->current_frame->proc_slice == NULL) || (picture->picture_coding_type != B_TYPE)) { picture->dest[0] += 16 * picture->pitches[0]; picture->dest[1] += 8 * picture->pitches[1]; picture->dest[2] += 8 * picture->pitches[2]; } picture->v_offset += 16; } if (picture->v_offset > picture->limit_y) return 1; return 0; #undef bit_buf #undef bits #undef bit_ptr } void mpeg2_slice (picture_t * picture, int code, uint8_t * buffer) { #define bit_buf (picture->bitstream_buf) #define bits (picture->bitstream_bits) #define bit_ptr (picture->bitstream_ptr) cpu_state_t cpu_state; bitstream_init (picture, buffer); if (slice_init (picture, code)) return; if (mpeg2_cpu_state_save) mpeg2_cpu_state_save (&cpu_state); while (1) { int macroblock_modes; int mba_inc; const MBAtab * mba; NEEDBITS (bit_buf, bits, bit_ptr); macroblock_modes = get_macroblock_modes (picture); /* maybe integrate MACROBLOCK_QUANT test into get_macroblock_modes ? */ if (macroblock_modes & MACROBLOCK_QUANT) picture->quantizer_scale = get_quantizer_scale (picture); if (macroblock_modes & MACROBLOCK_INTRA) { int DCT_offset, DCT_stride; int offset; uint8_t * dest_y; if (picture->concealment_motion_vectors) { if (picture->picture_structure == FRAME_PICTURE) motion_fr_conceal (picture); else motion_fi_conceal (picture); } else { picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; picture->b_motion.pmv[0][0] = picture->b_motion.pmv[0][1] = 0; picture->b_motion.pmv[1][0] = picture->b_motion.pmv[1][1] = 0; } if (macroblock_modes & DCT_TYPE_INTERLACED) { DCT_offset = picture->pitches[0]; DCT_stride = picture->pitches[0] * 2; } else { DCT_offset = picture->pitches[0] * 8; DCT_stride = picture->pitches[0]; } offset = picture->offset; dest_y = picture->dest[0] + offset; slice_intra_DCT (picture, 0, dest_y, DCT_stride); slice_intra_DCT (picture, 0, dest_y + 8, DCT_stride); slice_intra_DCT (picture, 0, dest_y + DCT_offset, DCT_stride); slice_intra_DCT (picture, 0, dest_y + DCT_offset + 8, DCT_stride); slice_intra_DCT (picture, 1, picture->dest[1] + (offset >> 1), picture->pitches[1]); slice_intra_DCT (picture, 2, picture->dest[2] + (offset >> 1), picture->pitches[2]); if (picture->picture_coding_type == D_TYPE) { NEEDBITS (bit_buf, bits, bit_ptr); DUMPBITS (bit_buf, bits, 1); } } else { if (picture->picture_structure == FRAME_PICTURE) switch (macroblock_modes & MOTION_TYPE_MASK) { case MC_FRAME: if (picture->mpeg1) MOTION_CALL (motion_mp1, macroblock_modes); else MOTION_CALL (motion_fr_frame, macroblock_modes); break; case MC_FIELD: MOTION_CALL (motion_fr_field, macroblock_modes); break; case MC_DMV: MOTION_CALL (motion_fr_dmv, MACROBLOCK_MOTION_FORWARD); break; case 0: /* non-intra mb without forward mv in a P picture */ picture->f_motion.pmv[0][0] = 0; picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = 0; picture->f_motion.pmv[1][1] = 0; MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); break; } else switch (macroblock_modes & MOTION_TYPE_MASK) { case MC_FIELD: MOTION_CALL (motion_fi_field, macroblock_modes); break; case MC_16X8: MOTION_CALL (motion_fi_16x8, macroblock_modes); break; case MC_DMV: MOTION_CALL (motion_fi_dmv, MACROBLOCK_MOTION_FORWARD); break; case 0: /* non-intra mb without forward mv in a P picture */ picture->f_motion.pmv[0][0] = 0; picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = 0; picture->f_motion.pmv[1][1] = 0; MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); break; } if (macroblock_modes & MACROBLOCK_PATTERN) { int coded_block_pattern; int DCT_offset, DCT_stride; int offset; uint8_t * dest_y; if (macroblock_modes & DCT_TYPE_INTERLACED) { DCT_offset = picture->pitches[0]; DCT_stride = picture->pitches[0] * 2; } else { DCT_offset = picture->pitches[0] * 8; DCT_stride = picture->pitches[0]; } coded_block_pattern = get_coded_block_pattern (picture); offset = picture->offset; dest_y = picture->dest[0] + offset; if (coded_block_pattern & 0x20) slice_non_intra_DCT (picture, dest_y, DCT_stride); if (coded_block_pattern & 0x10) slice_non_intra_DCT (picture, dest_y + 8, DCT_stride); if (coded_block_pattern & 0x08) slice_non_intra_DCT (picture, dest_y + DCT_offset, DCT_stride); if (coded_block_pattern & 0x04) slice_non_intra_DCT (picture, dest_y + DCT_offset + 8, DCT_stride); if (coded_block_pattern & 0x2) slice_non_intra_DCT (picture, picture->dest[1] + (offset >> 1), picture->pitches[1]); if (coded_block_pattern & 0x1) slice_non_intra_DCT (picture, picture->dest[2] + (offset >> 1), picture->pitches[2]); } picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; } NEXT_MACROBLOCK; NEEDBITS (bit_buf, bits, bit_ptr); mba_inc = 0; while (1) { if (bit_buf >= 0x10000000) { mba = MBA_5 + (UBITS (bit_buf, 5) - 2); break; } else if (bit_buf >= 0x03000000) { mba = MBA_11 + (UBITS (bit_buf, 11) - 24); break; } else switch (UBITS (bit_buf, 11)) { case 8: /* macroblock_escape */ mba_inc += 33; /* fall through */ case 15: /* macroblock_stuffing (MPEG1 only) */ DUMPBITS (bit_buf, bits, 11); NEEDBITS (bit_buf, bits, bit_ptr); continue; default: /* end of slice, or error */ if (mpeg2_cpu_state_restore) mpeg2_cpu_state_restore (&cpu_state); return; } } DUMPBITS (bit_buf, bits, mba->len); mba_inc += mba->mba; if (mba_inc) { picture->dc_dct_pred[0] = picture->dc_dct_pred[1] = picture->dc_dct_pred[2] = 128 << picture->intra_dc_precision; if (picture->picture_coding_type == P_TYPE) { picture->f_motion.pmv[0][0] = picture->f_motion.pmv[0][1] = 0; picture->f_motion.pmv[1][0] = picture->f_motion.pmv[1][1] = 0; do { MOTION_CALL (motion_zero, MACROBLOCK_MOTION_FORWARD); NEXT_MACROBLOCK; } while (--mba_inc); } else { do { MOTION_CALL (motion_reuse, macroblock_modes); NEXT_MACROBLOCK; } while (--mba_inc); } } } #undef bit_buf #undef bits #undef bit_ptr } ��������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/stats.c���������������������������������������������������������0000644�0001750�0001750�00000021503�14647725152�016400� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * stats.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include <stdio.h> #include <stdlib.h> #include <inttypes.h> #include "mpeg2_internal.h" static int debug_level = -1; /* Determine is debug output is required. */ /* We could potentially have multiple levels of debug info */ static int debug_is_on (void) { char * env_var; if (debug_level < 0) { env_var = getenv ("MPEG2_DEBUG"); if (env_var) debug_level = 1; else debug_level = 0; } return debug_level; } static void stats_picture (uint8_t * buffer) { static const char *const picture_coding_type_str [8] = { "Invalid picture type", "I-type", "P-type", "B-type", "D (very bad)", "Invalid","Invalid","Invalid" }; int picture_coding_type; int temporal_reference; int vbv_delay; temporal_reference = (buffer[0] << 2) | (buffer[1] >> 6); picture_coding_type = (buffer [1] >> 3) & 7; vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) | (buffer[3] >> 3)) & 0xffff; fprintf (stderr, " (picture) %s temporal_reference %d, vbv_delay %d\n", picture_coding_type_str [picture_coding_type], temporal_reference, vbv_delay); } static void stats_user_data (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (user_data)\n"); } static void stats_sequence (uint8_t * buffer) { static const char *const aspect_ratio_information_str[8] = { "Invalid Aspect Ratio", "1:1", "4:3", "16:9", "2.21:1", "Invalid Aspect Ratio", "Invalid Aspect Ratio", "Invalid Aspect Ratio" }; static const char *const frame_rate_str[16] = { "Invalid frame_rate_code", "23.976", "24", "25" , "29.97", "30" , "50", "59.94", "60" , "Invalid frame_rate_code", "Invalid frame_rate_code", "Invalid frame_rate_code", "Invalid frame_rate_code", "Invalid frame_rate_code", "Invalid frame_rate_code", "Invalid frame_rate_code" }; int horizontal_size; int vertical_size; int aspect_ratio_information; int frame_rate_code; int bit_rate_value; int vbv_buffer_size_value; int constrained_parameters_flag; int load_intra_quantizer_matrix; int load_non_intra_quantizer_matrix; vertical_size = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; horizontal_size = vertical_size >> 12; vertical_size &= 0xfff; aspect_ratio_information = buffer[3] >> 4; frame_rate_code = buffer[3] & 15; bit_rate_value = (buffer[4] << 10) | (buffer[5] << 2) | (buffer[6] >> 6); vbv_buffer_size_value = ((buffer[6] << 5) | (buffer[7] >> 3)) & 0x3ff; constrained_parameters_flag = buffer[7] & 4; load_intra_quantizer_matrix = buffer[7] & 2; if (load_intra_quantizer_matrix) buffer += 64; load_non_intra_quantizer_matrix = buffer[7] & 1; fprintf (stderr, " (seq) %dx%d %s, %s fps, %5.0f kbps, VBV %d kB%s%s%s\n", horizontal_size, vertical_size, aspect_ratio_information_str [aspect_ratio_information], frame_rate_str [frame_rate_code], bit_rate_value * 400.0 / 1000.0, 2 * vbv_buffer_size_value, constrained_parameters_flag ? " , CP":"", load_intra_quantizer_matrix ? " , Custom Intra Matrix":"", load_non_intra_quantizer_matrix ? " , Custom Non-Intra Matrix":""); } static void stats_sequence_error (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (sequence_error)\n"); } static void stats_sequence_end (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (sequence_end)\n"); } static void stats_group (uint8_t * buffer) { fprintf (stderr, " (group)%s%s\n", (buffer[4] & 0x40) ? " closed_gop" : "", (buffer[4] & 0x20) ? " broken_link" : ""); } static void stats_slice (int code, uint8_t * buffer) { /* fprintf (stderr, " (slice %d)\n", code); */ (void)code; (void)buffer; } static void stats_sequence_extension (uint8_t * buffer) { static const char *const chroma_format_str[4] = { "Invalid Chroma Format", "4:2:0 Chroma", "4:2:2 Chroma", "4:4:4 Chroma" }; int progressive_sequence; int chroma_format; progressive_sequence = (buffer[1] >> 3) & 1; chroma_format = (buffer[1] >> 1) & 3; fprintf (stderr, " (seq_ext) progressive_sequence %d, %s\n", progressive_sequence, chroma_format_str [chroma_format]); } static void stats_sequence_display_extension (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (sequence_display_extension)\n"); } static void stats_quant_matrix_extension (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (quant_matrix_extension)\n"); } static void stats_copyright_extension (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (copyright_extension)\n"); } static void stats_sequence_scalable_extension (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (sequence_scalable_extension)\n"); } static void stats_picture_display_extension (uint8_t * buffer) { (void)buffer; fprintf (stderr, " (picture_display_extension)\n"); } static void stats_picture_coding_extension (uint8_t * buffer) { static const char *const picture_structure_str[4] = { "Invalid Picture Structure", "Top field", "Bottom field", "Frame Picture" }; int f_code[2][2]; int intra_dc_precision; int picture_structure; int top_field_first; int frame_pred_frame_dct; int concealment_motion_vectors; int q_scale_type; int intra_vlc_format; int alternate_scan; int repeat_first_field; int progressive_frame; f_code[0][0] = buffer[0] & 15; f_code[0][1] = buffer[1] >> 4; f_code[1][0] = buffer[1] & 15; f_code[1][1] = buffer[2] >> 4; intra_dc_precision = (buffer[2] >> 2) & 3; picture_structure = buffer[2] & 3; top_field_first = buffer[3] >> 7; frame_pred_frame_dct = (buffer[3] >> 6) & 1; concealment_motion_vectors = (buffer[3] >> 5) & 1; q_scale_type = (buffer[3] >> 4) & 1; intra_vlc_format = (buffer[3] >> 3) & 1; alternate_scan = (buffer[3] >> 2) & 1; repeat_first_field = (buffer[3] >> 1) & 1; progressive_frame = buffer[4] >> 7; fprintf (stderr, " (pic_ext) %s\n", picture_structure_str [picture_structure]); fprintf (stderr, " (pic_ext) forward horizontal f_code % d, forward vertical f_code % d\n", f_code[0][0], f_code[0][1]); fprintf (stderr, " (pic_ext) backward horizontal f_code % d, backward vertical f_code % d\n", f_code[1][0], f_code[1][1]); fprintf (stderr, " (pic_ext) intra_dc_precision %d, top_field_first %d, frame_pred_frame_dct %d\n", intra_dc_precision, top_field_first, frame_pred_frame_dct); fprintf (stderr, " (pic_ext) concealment_motion_vectors %d, q_scale_type %d, intra_vlc_format %d\n", concealment_motion_vectors, q_scale_type, intra_vlc_format); fprintf (stderr, " (pic_ext) alternate_scan %d, repeat_first_field %d, progressive_frame %d\n", alternate_scan, repeat_first_field, progressive_frame); } void mpeg2_stats (int code, uint8_t * buffer) { if (! (debug_is_on ())) return; switch (code) { case 0x00: stats_picture (buffer); break; case 0xb2: stats_user_data (buffer); break; case 0xb3: stats_sequence (buffer); break; case 0xb4: stats_sequence_error (buffer); break; case 0xb5: switch (buffer[0] >> 4) { case 1: stats_sequence_extension (buffer); break; case 2: stats_sequence_display_extension (buffer); break; case 3: stats_quant_matrix_extension (buffer); break; case 4: stats_copyright_extension (buffer); break; case 5: stats_sequence_scalable_extension (buffer); break; case 7: stats_picture_display_extension (buffer); break; case 8: stats_picture_coding_extension (buffer); break; default: fprintf (stderr, " (unknown extension %#x)\n", buffer[0] >> 4); } break; case 0xb7: stats_sequence_end (buffer); break; case 0xb8: stats_group (buffer); break; default: if (code < 0xb0) stats_slice (code, buffer); else fprintf (stderr, " (unknown start code %#02x)\n", code); } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/header.c��������������������������������������������������������0000644�0001750�0001750�00000031710�14647725152�016473� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * header.c * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * See http://libmpeg2.sourceforge.net/ for updates. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ /* #define LOG_PAN_SCAN */ #include "config.h" #include <stdio.h> /* For printf debugging */ #include <inttypes.h> #include "mpeg2_internal.h" #include <xine/attributes.h> /* default intra quant matrix, in zig-zag order */ static const uint8_t default_intra_quantizer_matrix[64] ATTR_ALIGN(16) = { 8, 16, 16, 19, 16, 19, 22, 22, 22, 22, 22, 22, 26, 24, 26, 27, 27, 27, 26, 26, 26, 26, 27, 27, 27, 29, 29, 29, 34, 34, 34, 29, 29, 29, 27, 27, 29, 29, 32, 32, 34, 34, 37, 38, 37, 35, 35, 34, 35, 38, 38, 40, 40, 40, 48, 48, 46, 46, 56, 56, 58, 69, 69, 83 }; uint8_t mpeg2_scan_norm[64] ATTR_ALIGN(16) = { /* Zig-Zag scan pattern */ 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 }; uint8_t mpeg2_scan_alt[64] ATTR_ALIGN(16) = { /* Alternate scan pattern */ 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 }; /* count must be between 1 and 32 */ static uint32_t get_bits(uint8_t *buffer, uint32_t count, uint32_t *bit_position) { uint32_t byte_offset; uint32_t bit_offset; uint32_t bit_mask; uint32_t bit_bite; uint32_t result=0; if (count == 0) return 0; do { byte_offset = *bit_position >> 3; /* Div 8 */ bit_offset = 8 - (*bit_position & 0x7); /* Bits got 87654321 */ bit_mask = ((1 << (bit_offset)) - 1); bit_bite = bit_offset; if (count < bit_offset) { bit_mask ^= ((1 << (bit_offset-count)) - 1); bit_bite = count; } /* printf("Byte=0x%02x Bitmask=0x%04x byte_offset=%u bit_offset=%u bit_byte=%u count=%u\n",buffer[byte_offset], bit_mask, byte_offset, bit_offset, bit_bite,count); */ result = (result << bit_bite) | ((buffer[byte_offset] & bit_mask) >> (bit_offset-bit_bite)); *bit_position+=bit_bite; count-=bit_bite; } while ((count > 0) && (byte_offset<50) ); return result; } static int32_t get_bits_signed(uint8_t *buffer, uint32_t count, uint32_t *bit_position) { uint32_t value = get_bits(buffer, count, bit_position); uint32_t sign_mask = (uint32_t)((uint32_t)-1 << (count - 1)); if (value & sign_mask) value |= sign_mask; /* sign-extend value */ return (int32_t)value; } void mpeg2_header_state_init (picture_t * picture) { picture->scan = mpeg2_scan_norm; picture->load_intra_quantizer_matrix = 1; picture->load_non_intra_quantizer_matrix = 1; } int mpeg2_header_sequence (picture_t * picture, uint8_t * buffer) { int width, height; int i; if ((buffer[6] & 0x20) != 0x20) return 1; /* missing marker_bit */ height = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2]; picture->display_width = width = (height >> 12); picture->display_height = height = (height & 0xfff); width = (width + 15) & ~15; height = (height + 15) & ~15; if ((width > 1920) || (height > 1152)) return 1; /* size restrictions for MP@HL */ picture->coded_picture_width = width; picture->coded_picture_height = height; /* this is not used by the decoder */ picture->aspect_ratio_information = buffer[3] >> 4; picture->frame_rate_code = buffer[3] & 15; picture->bitrate = (buffer[4]<<10)|(buffer[5]<<2)|(buffer[6]>>6); if (buffer[7] & 2) { for (i = 0; i < 64; i++) picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = (buffer[i+7] << 7) | (buffer[i+8] >> 1); buffer += 64; } else for (i = 0; i < 64; i++) picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = default_intra_quantizer_matrix [i]; if (buffer[7] & 1) for (i = 0; i < 64; i++) picture->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = buffer[i+8]; else for (i = 0; i < 64; i++) picture->non_intra_quantizer_matrix[i] = 16; picture->load_intra_quantizer_matrix = 1; picture->load_non_intra_quantizer_matrix = 1; /* MPEG1 - for testing only */ picture->mpeg1 = 1; picture->intra_dc_precision = 0; picture->frame_pred_frame_dct = 1; picture->q_scale_type = 0; picture->concealment_motion_vectors = 0; /* picture->alternate_scan = 0; */ picture->picture_structure = FRAME_PICTURE; /* picture->second_field = 0; */ return 0; } static int sequence_extension (picture_t * picture, uint8_t * buffer) { /* check chroma format, size extensions, marker bit */ if (((buffer[1] & 0x07) != 0x02) || (buffer[2] & 0xe0) || ((buffer[3] & 0x01) != 0x01)) return 1; /* this is not used by the decoder */ picture->progressive_sequence = (buffer[1] >> 3) & 1; picture->low_delay = buffer[5] & 0x80; if (!picture->progressive_sequence) picture->coded_picture_height = (picture->coded_picture_height + 31) & ~31; /* printf ("libmpeg2: low_delay : %d\n", picture->low_delay); */ /* printf ("libmpeg2: sequence extension+5 : %08x (%d)\n", buffer[5], buffer[5] % 0x80); */ picture->frame_rate_ext_n = buffer[5] & 0x31; picture->frame_rate_ext_d = (buffer[5] >> 2) & 0x03; /* MPEG1 - for testing only */ picture->mpeg1 = 0; return 0; } static int quant_matrix_extension (picture_t * picture, uint8_t * buffer) { int i; if (buffer[0] & 8) { for (i = 0; i < 64; i++) picture->intra_quantizer_matrix[mpeg2_scan_norm[i]] = (buffer[i] << 5) | (buffer[i+1] >> 3); buffer += 64; } if (buffer[0] & 4) for (i = 0; i < 64; i++) picture->non_intra_quantizer_matrix[mpeg2_scan_norm[i]] = (buffer[i] << 6) | (buffer[i+1] >> 2); return 0; } static int picture_coding_extension (picture_t * picture, uint8_t * buffer) { /* pre subtract 1 for use later in compute_motion_vector */ picture->f_motion.f_code[0] = (buffer[0] & 15) - 1; picture->f_motion.f_code[1] = (buffer[1] >> 4) - 1; picture->b_motion.f_code[0] = (buffer[1] & 15) - 1; picture->b_motion.f_code[1] = (buffer[2] >> 4) - 1; picture->intra_dc_precision = (buffer[2] >> 2) & 3; picture->picture_structure = buffer[2] & 3; picture->frame_pred_frame_dct = (buffer[3] >> 6) & 1; picture->concealment_motion_vectors = (buffer[3] >> 5) & 1; picture->q_scale_type = (buffer[3] >> 4) & 1; picture->intra_vlc_format = (buffer[3] >> 3) & 1; if (buffer[3] & 4) /* alternate_scan */ picture->scan = mpeg2_scan_alt; else picture->scan = mpeg2_scan_norm; /* these are not used by the decoder */ picture->top_field_first = buffer[3] >> 7; picture->repeat_first_field = (buffer[3] >> 1) & 1; picture->progressive_frame = buffer[4] >> 7; return 0; } static int sequence_display_extension (picture_t * picture, uint8_t * buffer) { /* FIXME: implement. */ uint32_t bit_position; /*uint32_t padding;*/ bit_position = 0; /*padding = get_bits(buffer, 4, &bit_position);*/ bit_position += 4; picture->video_format = get_bits(buffer, 3, &bit_position); picture->colour_description = get_bits(buffer, 1, &bit_position); if(picture->colour_description) { picture->colour_primatives = get_bits(buffer, 8, &bit_position); picture->transfer_characteristics = get_bits(buffer, 8, &bit_position); picture->matrix_coefficients = get_bits(buffer, 8, &bit_position); } picture->display_horizontal_size = get_bits(buffer, 14, &bit_position); /*padding = get_bits(buffer, 1, &bit_position);*/ bit_position++; picture->display_vertical_size = get_bits(buffer, 14, &bit_position); #ifdef LOG_PAN_SCAN printf("Sequence_display_extension\n"); printf(" video_format: %u\n", picture->video_format); printf(" colour_description: %u\n", picture->colour_description); if(picture->colour_description) { printf(" colour_primatives: %u\n", picture->colour_primatives); printf(" transfer_characteristics %u\n", picture->transfer_characteristics); printf(" matrix_coefficients %u\n", picture->matrix_coefficients); } printf(" display_horizontal_size %u\n", picture->display_horizontal_size); printf(" display_vertical_size %u\n", picture->display_vertical_size); #endif return 0; } static int picture_display_extension (picture_t * picture, uint8_t * buffer) { uint32_t bit_position; /*uint32_t padding;*/ #ifdef LOG_PAN_SCAN printf ("libmpeg2: picture_display_extension\n"); #endif bit_position = 0; /*padding = get_bits(buffer, 4, &bit_position);*/ bit_position += 4; picture->frame_centre_horizontal_offset = get_bits_signed(buffer, 16, &bit_position); /*padding = get_bits(buffer, 1, &bit_position);*/ bit_position++; picture->frame_centre_vertical_offset = get_bits_signed(buffer, 16, &bit_position); /*padding = get_bits(buffer, 1, &bit_position);*/ bit_position++; #ifdef LOG_PAN_SCAN printf("Pan & Scan centre (x,y) = (%d, %d)\n", picture->frame_centre_horizontal_offset, picture->frame_centre_vertical_offset); #endif return 0; } int mpeg2_header_extension (picture_t * picture, uint8_t * buffer) { switch (buffer[0] & 0xf0) { case 0x00: /* reserved */ return 0; case 0x10: /* sequence extension */ return sequence_extension (picture, buffer); case 0x20: /* sequence display extension for Pan & Scan */ return sequence_display_extension (picture, buffer); case 0x30: /* quant matrix extension */ return quant_matrix_extension (picture, buffer); case 0x40: /* copyright extension */ return 0; case 0x50: /* sequence scalable extension */ return 0; case 0x60: /* reserved */ return 0; case 0x70: /* picture display extension for Pan & Scan */ return picture_display_extension (picture, buffer); case 0x80: /* picture coding extension */ return picture_coding_extension (picture, buffer); case 0x90: /* picture spacial scalable extension */ return 0; case 0xA0: /* picture temporal scalable extension */ return 0; case 0xB0: /* camera parameters extension */ return 0; case 0xC0: /* ITU-T extension */ return 0; case 0xD0: /* reserved */ return 0; case 0xE0: /* reserved */ return 0; case 0xF0: /* reserved */ return 0; } return 0; } int mpeg2_header_group_of_pictures (picture_t * picture, uint8_t * buffer) { uint32_t bit_position; /*uint32_t padding;*/ bit_position = 0; picture->drop_frame_flag = get_bits(buffer, 1, &bit_position); picture->time_code_hours = get_bits(buffer, 5, &bit_position); picture->time_code_minutes = get_bits(buffer, 6, &bit_position); /*padding = get_bits(buffer, 1, &bit_position);*/ bit_position++; picture->time_code_seconds = get_bits(buffer, 6, &bit_position); picture->time_code_pictures = get_bits(buffer, 6, &bit_position); picture->closed_gop = get_bits(buffer, 1, &bit_position); picture->broken_link = get_bits(buffer, 1, &bit_position); #ifdef LOG_PAN_SCAN printf("Group of pictures\n"); printf(" drop_frame_flag: %u\n", picture->drop_frame_flag); printf(" time_code: HH:MM:SS:Pictures %02u:%02u:%02u:%02u\n", picture->time_code_hours, picture->time_code_minutes, picture->time_code_seconds, picture->time_code_pictures); printf(" closed_gop: %u\n", picture->closed_gop); printf(" bloken_link: %u\n", picture->broken_link); #endif return 0; } int mpeg2_header_picture (picture_t * picture, uint8_t * buffer) { picture->picture_coding_type = (buffer [1] >> 3) & 7; picture->vbv_delay = ((buffer[1] << 13) | (buffer[2] << 5) | (buffer[3] >> 3)) & 0xffff; /* forward_f_code and backward_f_code - used in mpeg1 only */ picture->f_motion.f_code[1] = (buffer[3] >> 2) & 1; picture->f_motion.f_code[0] = (((buffer[3] << 1) | (buffer[4] >> 7)) & 7) - 1; picture->b_motion.f_code[1] = (buffer[4] >> 6) & 1; picture->b_motion.f_code[0] = ((buffer[4] >> 3) & 7) - 1; /* move in header_process_picture_header */ picture->second_field = (picture->picture_structure != FRAME_PICTURE) && !(picture->second_field); return 0; } ��������������������������������������������������������xine-lib-1.2/src/video_dec/libmpeg2/idct_mlib.h�����������������������������������������������������0000644�0001750�0001750�00000001703�14647725152�017175� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * idct_mlib.h * * Copyright (C) 1999, Håkan Hjort <d95hjort@dtek.chalmers.se> * * This file is part of mpeg2dec, a free MPEG-2 video stream decoder. * * mpeg2dec is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * mpeg2dec is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU Make; see the file COPYING. If not, write to * the Free Software Foundation, * */ void idct_block_copy_mlib (int16_t * block, uint8_t * dest, int stride); void idct_block_add_mlib (int16_t * block, uint8_t * dest, int stride); �������������������������������������������������������������xine-lib-1.2/src/video_dec/group_raw.c��������������������������������������������������������������0000644�0001750�0001750�00000004177�14647725152�015556� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * A group of decoders for raw (uncompressed or slightly compressed) video. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include "group_raw.h" /* * exported plugin catalog entries */ static const uint32_t rgb_video_types[] = { BUF_VIDEO_RGB, 0 }; static const uint32_t yuv_video_types[] = { BUF_VIDEO_YUY2, BUF_VIDEO_YV12, BUF_VIDEO_YVU9, BUF_VIDEO_GREY, BUF_VIDEO_I420, 0 }; static const uint32_t bitplane_video_types[] = { BUF_VIDEO_BITPLANE, BUF_VIDEO_BITPLANE_BR1, 0 }; static const decoder_info_t rgb_info = { .supported_types = rgb_video_types, .priority = 1 }; static const decoder_info_t yuv_info = { .supported_types = yuv_video_types, .priority = 1 }; static const decoder_info_t bitplane_info = { .supported_types = bitplane_video_types, .priority = 1 }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "rgb", XINE_VERSION_CODE, &rgb_info, decode_rgb_init_class }, { PLUGIN_VIDEO_DECODER, 19, "yuv", XINE_VERSION_CODE, &yuv_info, decode_yuv_init_class }, { PLUGIN_VIDEO_DECODER, 19, "bitplane", XINE_VERSION_CODE, &bitplane_info, decode_bitplane_init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/libpng.c�����������������������������������������������������������������0000644�0001750�0001750�00000033077�14647725152�015025� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2003-2021 the xine project * Copyright (C) 2018-2019 Petri Hintukainen <phintuka@users.sourceforge.net> * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * PNG image decoder using libpng */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #define LOG_MODULE "png_video_decoder" #define LOG_VERBOSE /* #define LOG */ #include <png.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xine_buffer.h> /* decoder input data */ typedef struct { xine_t *xine; const uint8_t *image; int size; int pos; } dec_data; typedef struct png_decoder_s { video_decoder_t video_decoder; xine_stream_t *stream; int64_t pts; vo_frame_t *vo_frame; uint8_t *buf; int buf_size; uint8_t error; uint8_t video_open; /* private to _png_decode_data (). we place it here just to prevent setjump () / * longjump () from resetting values. */ struct { png_structp png; png_infop png_info, png_end_info; png_bytep row_pointers[16]; dec_data png_data; rgb2yuy2_t *rgb2yuy2; vo_frame_t *img, *free_img; } pdd; } png_decoder_t; /* * libpng callbacks */ static void _user_error(png_structp png, png_const_charp msg) { png_decoder_t *this = (png_decoder_t *)png_get_error_ptr(png); this->error = 1; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "%s\n", msg); } static void _user_warning(png_structp png, png_const_charp msg) { png_decoder_t *this = (png_decoder_t *)png_get_error_ptr(png); xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "%s\n", msg); } static void _user_read(png_structp png, png_bytep data, png_size_t length) { dec_data *this = (dec_data *)png_get_io_ptr(png); if (this->pos + length > (png_size_t)this->size) { xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": " "not enough data\n"); return; } memcpy(data, this->image + this->pos, length); this->pos += length; } /* * decoding */ static vo_frame_t *_png_decode_data (png_decoder_t *this, const uint8_t *data, size_t size) { this->pdd.rgb2yuy2 = NULL; this->pdd.img = NULL; this->pdd.free_img = NULL; this->pdd.row_pointers[0] = NULL; this->pdd.png_data.xine = this->stream->xine; this->pdd.png_data.image = data; this->pdd.png_data.size = size; this->pdd.png_data.pos = 0; if (!this->video_open) { (this->stream->video_out->open) (this->stream->video_out, this->stream); this->video_open = 1; } do { vo_frame_t *img; uint8_t *slice_start[3] = {NULL, NULL, NULL}; png_uint_32 width, height, y; int max_width, max_height; int frame_flags = VO_BOTH_FIELDS; int format; int cm; int color_type, interlace_type, compression_type, filter_type, bit_depth; int linesize; /* set up decoding */ this->pdd.png = png_create_read_struct (PNG_LIBPNG_VER_STRING, 0, 0, 0); if (!this->pdd.png) break; this->pdd.png_end_info = NULL; this->pdd.png_info = png_create_info_struct (this->pdd.png); if (!this->pdd.png_info) break; this->pdd.png_end_info = png_create_info_struct (this->pdd.png); if (!this->pdd.png_end_info) break; /* libpng bail out path */ if (setjmp (png_jmpbuf (this->pdd.png))) break; png_set_read_fn (this->pdd.png, &this->pdd.png_data, _user_read); png_set_error_fn (this->pdd.png, this, _user_error, _user_warning); /* parse header */ png_read_info (this->pdd.png, this->pdd.png_info); if (this->error) break; png_get_IHDR (this->pdd.png, this->pdd.png_info, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); if (this->error) break; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, height); _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "PNG"); /* set up libpng csc */ if (color_type == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb (this->pdd.png); } if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb (this->pdd.png); } if (bit_depth == 16) { png_set_scale_16 (this->pdd.png); } if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { png_set_expand_gray_1_2_4_to_8 (this->pdd.png); } png_set_strip_alpha (this->pdd.png); /* alloc decoder image */ linesize = png_get_rowbytes (this->pdd.png, this->pdd.png_info); this->pdd.row_pointers[0] = png_malloc (this->pdd.png, 16 * linesize); if (!this->pdd.row_pointers[0]) break; for (y = 1; y < 16; y++) { this->pdd.row_pointers[y] = this->pdd.row_pointers[y - 1] + linesize; } /* check output capabilities */ /* check max. image size */ max_width = this->stream->video_out->get_property (this->stream->video_out, VO_PROP_MAX_VIDEO_WIDTH); max_height = this->stream->video_out->get_property (this->stream->video_out, VO_PROP_MAX_VIDEO_HEIGHT); /* crop when image is too large for vo */ if (max_width > 0 && width > (png_uint_32)max_width) width = max_width; if (max_height > 0 && height > (png_uint_32)max_height) height = max_height; /* check full range capability */ cm = 10; /* mpeg range ITU-R 601 */ if (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_FULLRANGE) cm = 11; /* full range */ VO_SET_FLAGS_CM (cm, frame_flags); /* check output format - prefer YUY2 */ format = (this->stream->video_out->get_capabilities (this->stream->video_out) & VO_CAP_YUY2) ? XINE_IMGFMT_YUY2 : XINE_IMGFMT_YV12; /* allocate output frame and set up slices */ this->pdd.img = this->pdd.free_img = img = this->stream->video_out->get_frame (this->stream->video_out, width, height, (double)width / (double)height, format, frame_flags | VO_GET_FRAME_MAY_FAIL); if (!img) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": get_frame (%dx%d) failed\n", width, height); break; } /* init slices */ if (img->proc_slice && !(img->height & 0xf)) { slice_start[0] = img->base[0]; slice_start[1] = img->base[1]; slice_start[2] = img->base[2]; } /* decode and convert in slices */ this->pdd.rgb2yuy2 = rgb2yuy2_alloc (cm, "rgb"); if (!this->pdd.rgb2yuy2) break; for (y = 0; y < height; y += 16) { int lines = y + 16 <= height ? 16 : height - y; png_read_rows (this->pdd.png, &this->pdd.row_pointers[0], NULL, lines); if (img->format == XINE_IMGFMT_YV12) { rgb2yv12_slice (this->pdd.rgb2yuy2, this->pdd.row_pointers[0], png_get_rowbytes (this->pdd.png, this->pdd.png_info), img->base[0] + y * img->pitches[0], img->pitches[0], img->base[1] + (y / 2) * img->pitches[1], img->pitches[1], img->base[2] + (y / 2) * img->pitches[2], img->pitches[2], width, lines); } else { rgb2yuy2_slice (this->pdd.rgb2yuy2, this->pdd.row_pointers[0], png_get_rowbytes (this->pdd.png, this->pdd.png_info), img->base[0] + y * img->pitches[0], img->pitches[0], width, lines); } if (slice_start[0]) { img->proc_slice (img, slice_start); slice_start[0] += 16 * img->pitches[0]; slice_start[1] += 8 * img->pitches[1]; slice_start[2] += 8 * img->pitches[2]; } } /* from here, always return valid image. */ img->duration = 3600; img->bad_frame = 0; _x_stream_info_set (this->stream, XINE_STREAM_INFO_FRAME_DURATION, img->duration); this->pdd.free_img = NULL; png_read_end (this->pdd.png, this->pdd.png_end_info); } while (0); /* joint exit path */ if (this->pdd.rgb2yuy2) { rgb2yuy2_free (this->pdd.rgb2yuy2); this->pdd.rgb2yuy2 = NULL; } if (this->pdd.free_img) { this->pdd.free_img->free (this->pdd.free_img); this->pdd.img = NULL; this->pdd.free_img = NULL; } if (this->pdd.row_pointers[0]) { png_free (this->pdd.png, this->pdd.row_pointers[0]); this->pdd.row_pointers[0] = NULL; } if (this->pdd.png) png_destroy_read_struct (&this->pdd.png, &this->pdd.png_info, &this->pdd.png_end_info); if (!this->pdd.img) this->pts = 0; return this->pdd.img; } /* * xine-lib decoder interface */ static void png_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { png_decoder_t *this = xine_container_of(this_gen, png_decoder_t, video_decoder); vo_frame_t *f = NULL; /* demux_image sends everything as preview at open time, * then an empty buf at play time. * we need to defer output to the latter because * - we want it to get correct vpts, * - we want it marked as first frame after seek, and * - we dont want it flushed by a previous stream stop. */ if (!(buf->decoder_flags & BUF_FLAG_PREVIEW) && buf->pts) this->pts = buf->pts; do { if (buf->size > 0) { if (this->buf_size == 0 && (buf->decoder_flags & BUF_FLAG_FRAME_END)) { /* complete frame */ f = _png_decode_data(this, buf->content, buf->size); break; } xine_buffer_copyin (this->buf, this->buf_size, buf->mem, buf->size); this->buf_size += buf->size; } if ((buf->decoder_flags & BUF_FLAG_FRAME_END) && (this->buf_size > 0)) { f = _png_decode_data(this, this->buf, this->buf_size); this->buf_size = 0; } } while (0); if (f) { if (this->vo_frame) { if (!(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); } this->vo_frame->free (this->vo_frame); } this->vo_frame = f; } if (this->vo_frame && !(buf->decoder_flags & BUF_FLAG_PREVIEW)) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void png_flush (video_decoder_t *this_gen) { png_decoder_t *this = xine_container_of(this_gen, png_decoder_t, video_decoder); if (this->vo_frame) { this->vo_frame->pts = this->pts; this->vo_frame->draw (this->vo_frame, this->stream); this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } } static void png_reset (video_decoder_t *this_gen) { png_decoder_t *this = xine_container_of(this_gen, png_decoder_t, video_decoder); if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } this->buf_size = 0; this->pts = 0; } static void png_discontinuity (video_decoder_t *this_gen) { png_decoder_t *this = xine_container_of(this_gen, png_decoder_t, video_decoder); this->pts = 0; } static void png_dispose (video_decoder_t *this_gen) { png_decoder_t *this = xine_container_of(this_gen, png_decoder_t, video_decoder); if (this->vo_frame) { this->vo_frame->free (this->vo_frame); this->vo_frame = NULL; } if (this->video_open) { this->stream->video_out->close(this->stream->video_out, this->stream); this->video_open = 0; } xine_buffer_free(this->buf); free (this); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { png_decoder_t *this; (void)class_gen; this = calloc(1, sizeof(png_decoder_t)); if (!this) return NULL; this->video_decoder.decode_data = png_decode_data; this->video_decoder.flush = png_flush; this->video_decoder.reset = png_reset; this->video_decoder.discontinuity = png_discontinuity; this->video_decoder.dispose = png_dispose; this->stream = stream; this->vo_frame = NULL; this->buf = xine_buffer_init(65536); if (!this->buf) { free(this); return NULL; } return &this->video_decoder; } /* * plugin class */ static void *init_class (xine_t *xine, const void *data) { (void)xine; (void)data; static video_decoder_class_t decode_video_png_class = { .open_plugin = open_plugin, .identifier = "pngdec", .description = N_("PNG image video decoder"), .dispose = NULL, }; return (void *)&decode_video_png_class; } /* * exported plugin catalog entry */ static const uint32_t supported_types[] = { BUF_VIDEO_PNG, 0 }; static const decoder_info_t dec_info_png = { .supported_types = supported_types, .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "png", XINE_VERSION_CODE, &dec_info_png, init_class }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/video_dec/mmal.c�������������������������������������������������������������������0000644�0001750�0001750�00000061424�14647725152�014475� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2014-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * libmmal decoder wrapped by Petri Hintukainen <phintuka@users.sourceforge.net> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <bcm_host.h> #include <interface/mmal/mmal.h> #include <interface/mmal/util/mmal_util.h> #include <interface/mmal/util/mmal_default_components.h> #define LOG_MODULE "mmal_video_decoder" #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> typedef struct mmal_decoder_s { video_decoder_t video_decoder; pthread_mutex_t mutex; /* xine */ xine_stream_t *stream; MMAL_BUFFER_HEADER_T *input_buffer; /* mmal decoder */ MMAL_COMPONENT_T *decoder; MMAL_POOL_T *input_pool; MMAL_POOL_T *output_pool; MMAL_QUEUE_T *decoded_frames; MMAL_ES_FORMAT_T *output_format; /* decoder output format */ double ratio; int width; int height; int frame_flags; int crop_x, crop_y, crop_w, crop_h; uint8_t decoder_ok; uint8_t discontinuity; } mmal_decoder_t; /* * decoder output buffers */ static void free_output_buffer(MMAL_BUFFER_HEADER_T *buffer) { vo_frame_t *frame = (vo_frame_t *)buffer->user_data; if (frame) { if (buffer->data != frame->base[0]) { /* free indirect rendering buffer */ free(buffer->data); } frame->free(frame); } buffer->user_data = NULL; buffer->alloc_size = 0; buffer->data = NULL; mmal_buffer_header_release(buffer); } static int send_output_buffer(mmal_decoder_t *this) { MMAL_BUFFER_HEADER_T *buffer; vo_frame_t *frame; MMAL_STATUS_T status; buffer = mmal_queue_get(this->output_pool->queue); if (!buffer) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to get new output buffer\n"); return -1; } frame = this->stream->video_out->get_frame (this->stream->video_out, this->width, this->height, this->ratio, XINE_IMGFMT_YV12, this->frame_flags | VO_BOTH_FIELDS); if (!frame) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to get new xine frame\n"); mmal_buffer_header_release(buffer); return -1; } mmal_buffer_header_reset(buffer); buffer->user_data = frame; buffer->cmd = 0; buffer->alloc_size = this->decoder->output[0]->buffer_size; buffer->data = frame->base[0]; /* check if we can render directly to frame */ if (frame->pitches[0] != this->width || frame->pitches[1] != this->width/2 || frame->pitches[2] != this->width/2 || frame->base[1] - frame->base[0] != this->width * this->height || frame->base[2] - frame->base[1] != this->width * this->height / 4 ) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "xine frame not suitable for direct rendering\n"); buffer->data = malloc(buffer->alloc_size); if (!buffer->data) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to allocate output buffer\n"); free_output_buffer(buffer); return -1; } } status = mmal_port_send_buffer(this->decoder->output[0], buffer); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to send buffer to output port: %s (%d)\n", mmal_status_to_string(status), status); free_output_buffer(buffer); return -1; } return 0; } static void fill_output_port(mmal_decoder_t *this) { if (this->output_pool) { unsigned buffers_available = mmal_queue_length(this->output_pool->queue); unsigned buffers_to_send = this->decoder->output[0]->buffer_num_recommended - ( this->output_pool->headers_num - buffers_available - mmal_queue_length(this->decoded_frames)); unsigned i; if (buffers_to_send > buffers_available) { buffers_to_send = buffers_available; } for (i = 0; i < buffers_to_send; ++i) { if (send_output_buffer(this) < 0) { break; } } } } /* * MMAL callbacks */ static void control_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { mmal_decoder_t *this = (mmal_decoder_t *)port->userdata; if (buffer->cmd == MMAL_EVENT_ERROR) { MMAL_STATUS_T status = *(uint32_t *)buffer->data; xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "MMAL error: %s (%d)\n", mmal_status_to_string(status), status); } mmal_buffer_header_release(buffer); } static void input_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { mmal_buffer_header_release(buffer); } static void output_port_cb(MMAL_PORT_T *port, MMAL_BUFFER_HEADER_T *buffer) { mmal_decoder_t *this = (mmal_decoder_t *)port->userdata; if (buffer->cmd == 0) { if (buffer->length > 0) { mmal_queue_put(this->decoded_frames, buffer); pthread_mutex_lock(&this->mutex); fill_output_port(this); pthread_mutex_unlock(&this->mutex); } else { free_output_buffer(buffer); } } else if (buffer->cmd == MMAL_EVENT_FORMAT_CHANGED) { MMAL_EVENT_FORMAT_CHANGED_T *fmt = mmal_event_format_changed_get(buffer); MMAL_ES_FORMAT_T *format = mmal_format_alloc(); mmal_format_full_copy(format, fmt->format); pthread_mutex_lock(&this->mutex); if (this->output_format) { mmal_format_free(this->output_format); this->output_format = NULL; } this->output_format = format; pthread_mutex_unlock(&this->mutex); mmal_buffer_header_release(buffer); } else { mmal_buffer_header_release(buffer); } } /* * mmal codec */ static void stop_codec(mmal_decoder_t *this) { if (this->decoder) { if (this->decoder->control->is_enabled) { mmal_port_disable(this->decoder->control); } if (this->decoder->input[0]->is_enabled) { mmal_port_disable(this->decoder->input[0]); } if (this->decoder->output[0]->is_enabled) { mmal_port_disable(this->decoder->output[0]); } if (this->decoder->is_enabled) { mmal_component_disable(this->decoder); } } } static int start_codec(mmal_decoder_t *this) { MMAL_PORT_T *input = this->decoder->input[0]; MMAL_STATUS_T status; if (!this->decoder->output[0]->is_enabled) { status = mmal_port_enable(this->decoder->output[0], output_port_cb); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to enable output port: %s (%d)\n", mmal_status_to_string(status), status); return -1; } } if (!this->decoder->is_enabled) { status = mmal_component_enable(this->decoder); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to enable decoder: %s (%d)\n", mmal_status_to_string(status), status); return -1; } } if (!this->input_pool) { this->input_pool = mmal_pool_create_with_allocator(input->buffer_num, input->buffer_size, input, (mmal_pool_allocator_alloc_t)mmal_port_payload_alloc, (mmal_pool_allocator_free_t)mmal_port_payload_free); } if (!this->decoded_frames) { this->decoded_frames = mmal_queue_create(); } return 0; } /* * decoder output */ static void send_frames(mmal_decoder_t *this) { MMAL_BUFFER_HEADER_T *buffer; vo_frame_t *frame; if (!this->decoded_frames) { return; } /* get ready frames */ while (NULL != (buffer = mmal_queue_get(this->decoded_frames))) { frame = (vo_frame_t *)buffer->user_data; if (frame) { frame->pts = buffer->pts; frame->crop_left = this->crop_x; frame->crop_top = this->crop_y; frame->crop_right = this->width - this->crop_x - this->crop_w; frame->crop_bottom = this->height - this->crop_y - this->crop_h; /* indirect rendering ? */ if (buffer->data != frame->base[0]) { int sz = this->width * this->height; yv12_to_yv12( /* Y */ buffer->data, this->width, frame->base[0], frame->pitches[0], /* U */ buffer->data + sz, this->width / 2, frame->base[1], frame->pitches[1], /* V */ buffer->data + sz*5/4, this->width / 2, frame->base[2], frame->pitches[2], /* width x height */ this->width, this->height); } frame->draw(frame, this->stream); } free_output_buffer(buffer); } if (pthread_mutex_trylock(&this->mutex) == 0) { fill_output_port(this); pthread_mutex_unlock(&this->mutex); } } static int change_output_format(mmal_decoder_t *this) { MMAL_PORT_T *output = this->decoder->output[0]; MMAL_STATUS_T status; double rate; int ret = 0; status = mmal_port_disable(output); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to disable output port: %s (%d)\n", mmal_status_to_string(status), status); ret = -1; goto out; } mmal_format_full_copy(output->format, this->output_format); status = mmal_port_format_commit(output); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to commit output format: %s (%d)", mmal_status_to_string(status), status); ret = -1; goto out; } output->buffer_num = output->buffer_num_recommended; output->buffer_size = output->buffer_size_recommended; status = mmal_port_enable(output, output_port_cb); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to enable output port: %s (%d)", mmal_status_to_string(status), status); ret = -1; goto out; } if (!this->output_pool) { this->output_pool = mmal_pool_create(output->buffer_num_recommended + 10, 0); } this->width = output->format->es->video.width; this->height = output->format->es->video.height; this->crop_x = output->format->es->video.crop.x; this->crop_y = output->format->es->video.crop.y; this->crop_w = output->format->es->video.crop.width; this->crop_h = output->format->es->video.crop.height; this->ratio = output->format->es->video.par.num; this->ratio /= output->format->es->video.par.den; this->ratio *= this->width; this->ratio /= this->height; switch (output->format->es->video.color_space) { case MMAL_COLOR_SPACE_ITUR_BT601: case MMAL_COLOR_SPACE_BT470_2_BG: case MMAL_COLOR_SPACE_JFIF_Y16_255: VO_SET_FLAGS_CM (10, this->frame_flags); break; case MMAL_COLOR_SPACE_ITUR_BT709: VO_SET_FLAGS_CM (2, this->frame_flags); break; case MMAL_COLOR_SPACE_JPEG_JFIF: VO_SET_FLAGS_CM (11, this->frame_flags); break; case MMAL_COLOR_SPACE_FCC: VO_SET_FLAGS_CM (8, this->frame_flags); break; case MMAL_COLOR_SPACE_SMPTE240M: VO_SET_FLAGS_CM (14, this->frame_flags); break; case MMAL_COLOR_SPACE_UNKNOWN: default: //VO_SET_FLAGS_CM (4, this->frame_flags); /* undefined, mpeg range */ // might have beed set by demux break; } rate = output->format->es->video.frame_rate.num; rate /= output->format->es->video.frame_rate.den; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, 90000/rate); out: mmal_format_free(this->output_format); this->output_format = NULL; return ret; } static void handle_output(mmal_decoder_t *this) { /* handle output re-config request */ if (this->output_format) { pthread_mutex_lock(&this->mutex); change_output_format(this); pthread_mutex_unlock(&this->mutex); } /* handle decoder output */ send_frames(this); } /* * decoder input */ static void set_extradata(mmal_decoder_t *this, void *extradata, size_t extradata_size) { MMAL_PORT_T *input = this->decoder->input[0]; MMAL_STATUS_T status; status = mmal_port_disable(input); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to disable input port: %s (%d)\n", mmal_status_to_string(status), status); } status = mmal_format_extradata_alloc(input->format, extradata_size); if (status == MMAL_SUCCESS) { memcpy(input->format->extradata, extradata, extradata_size); input->format->extradata_size = extradata_size; } else { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to allocate extradata: %s (%d)", mmal_status_to_string(status), status); } status = mmal_port_format_commit(input); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to commit input format: %s (%d)\n", mmal_status_to_string(status), status); } status = mmal_port_enable(input, input_port_cb); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to enable input port: %s (%d)\n", mmal_status_to_string(status), status); } } static void free_input_buffer(mmal_decoder_t *this) { if (this->input_buffer) { mmal_buffer_header_release(this->input_buffer); this->input_buffer = NULL; } } static MMAL_BUFFER_HEADER_T *get_input_buffer(mmal_decoder_t *this) { if (!this->input_buffer) { int retries = 40; this->input_buffer = mmal_queue_timedwait(this->input_pool->queue, 200); while (!this->input_buffer) { handle_output(this); if (--retries < 1 || _x_action_pending(this->stream)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to retrieve buffer header for input data\n"); this->discontinuity = 1; return NULL; } this->input_buffer = mmal_queue_timedwait(this->input_pool->queue, 200); } mmal_buffer_header_reset(this->input_buffer); this->input_buffer->cmd = 0; this->input_buffer->length = 0; this->input_buffer->flags = 0; } return this->input_buffer; } static int send_input_buffer(mmal_decoder_t *this) { MMAL_STATUS_T status; if (this->input_buffer) { if (this->discontinuity) { this->input_buffer->flags |= MMAL_BUFFER_HEADER_FLAG_DISCONTINUITY; this->discontinuity = 0; } status = mmal_port_send_buffer(this->decoder->input[0], this->input_buffer); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to send buffer to input port: %s (%d)", mmal_status_to_string(status), status); free_input_buffer(this); return -1; } this->input_buffer = NULL; } return 0; } /* * xine video decoder plugin functions */ static void handle_header(mmal_decoder_t *this, buf_element_t *buf) { xine_bmiheader *bih; size_t extradata_size = 0; uint8_t *extradata = NULL; if (buf->decoder_flags & BUF_FLAG_STDHEADER) { bih = (xine_bmiheader *) buf->content; this->width = (bih->biWidth + 1) & ~1; this->height = (bih->biHeight + 1) & ~1; if (buf->decoder_flags & BUF_FLAG_ASPECT) this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; else this->ratio = (double)this->width / (double)this->height; if (bih->biSize > sizeof(xine_bmiheader)) { extradata_size = bih->biSize - sizeof(xine_bmiheader); extradata = buf->content + sizeof(xine_bmiheader); } } if (buf->type == BUF_VIDEO_H264) { if (extradata && extradata_size > 0) { set_extradata(this, extradata, extradata_size); } } } static void mmal_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { mmal_decoder_t *this = xine_container_of(this_gen, mmal_decoder_t, video_decoder); if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_SPECIAL | BUF_FLAG_COLOR_MATRIX | BUF_FLAG_STDHEADER)) { if (buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_SPECIAL)) { return; } if (buf->decoder_flags & BUF_FLAG_COLOR_MATRIX) { VO_SET_FLAGS_CM (buf->decoder_info[4], this->frame_flags); } if (buf->decoder_flags & BUF_FLAG_STDHEADER) { handle_header(this, buf); return; } } if (!this->decoder_ok) { start_codec(this); (this->stream->video_out->open) (this->stream->video_out, this->stream); this->decoder_ok = 1; } /* handle decoder output and config */ handle_output(this); /* feed decoder */ while (buf->size > 0) { MMAL_BUFFER_HEADER_T *buffer = get_input_buffer(this); if (!buffer) return; if (buf->pts > 0) buffer->pts = buf->pts; uint32_t len = buf->size; if (len > buffer->alloc_size - buffer->length) len = buffer->alloc_size - buffer->length; memcpy(buffer->data + buffer->length, buf->content, len); buf->content += len; buf->size -= len; buffer->length += len; if (buf->size > 0 || (buf->decoder_flags & BUF_FLAG_FRAME_END)) { send_input_buffer(this); } } } static void mmal_flush (video_decoder_t *this_gen) { mmal_decoder_t *this = xine_container_of(this_gen, mmal_decoder_t, video_decoder); send_frames(this); } static void mmal_reset (video_decoder_t *this_gen) { mmal_decoder_t *this = xine_container_of(this_gen, mmal_decoder_t, video_decoder); free_input_buffer(this); if (this->decoder && this->decoder->is_enabled) { stop_codec(this); /* free frames */ MMAL_BUFFER_HEADER_T *buffer; while ((buffer = mmal_queue_get(this->decoded_frames))) { free_output_buffer(buffer); } mmal_port_enable(this->decoder->control, control_port_cb); mmal_port_enable(this->decoder->input[0], input_port_cb); this->stream->video_out->close(this->stream->video_out, this->stream); this->decoder_ok = 0; } } static void mmal_discontinuity (video_decoder_t *this_gen) { mmal_decoder_t *this = xine_container_of(this_gen, mmal_decoder_t, video_decoder); send_input_buffer(this); this->discontinuity = 1; } static void mmal_dispose (video_decoder_t *this_gen) { mmal_decoder_t *this = xine_container_of(this_gen, mmal_decoder_t, video_decoder); free_input_buffer(this); stop_codec(this); if (this->input_pool) { mmal_pool_destroy(this->input_pool); } if (this->output_format) { mmal_format_free(this->output_format); } /* free frames */ if (this->decoded_frames) { MMAL_BUFFER_HEADER_T *buffer; while ((buffer = mmal_queue_get(this->decoded_frames))) { free_output_buffer(buffer); } mmal_queue_destroy(this->decoded_frames); } if (this->output_pool) { mmal_pool_destroy(this->output_pool); } if (this->decoder) { mmal_component_release(this->decoder); } if (this->decoder_ok) { this->decoder_ok = 0; this->stream->video_out->close(this->stream->video_out, this->stream); } pthread_mutex_destroy (&this->mutex); free (this_gen); bcm_host_deinit(); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { mmal_decoder_t *this; MMAL_STATUS_T status; const char *codec = NULL; bcm_host_init(); this = (mmal_decoder_t *) calloc(1, sizeof(mmal_decoder_t)); if (!this) return NULL; pthread_mutex_init (&this->mutex, NULL); this->video_decoder.decode_data = mmal_decode_data; this->video_decoder.flush = mmal_flush; this->video_decoder.reset = mmal_reset; this->video_decoder.discontinuity = mmal_discontinuity; this->video_decoder.dispose = mmal_dispose; this->stream = stream; VO_SET_FLAGS_CM (4, this->frame_flags); /* undefined, mpeg range */ /* create decoder component */ status = mmal_component_create(MMAL_COMPONENT_DEFAULT_VIDEO_DECODER, &this->decoder); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to create "MMAL_COMPONENT_DEFAULT_VIDEO_DECODER": %s (%d)\n", mmal_status_to_string(status), status); mmal_dispose(&this->video_decoder); return NULL; } this->decoder->control->userdata = (void *)this; this->decoder->input[0]->userdata = (void *)this; this->decoder->output[0]->userdata = (void *)this; status = mmal_port_enable(this->decoder->control, control_port_cb); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to enable control port: %s (%d)\n", mmal_status_to_string(status), status); mmal_dispose(&this->video_decoder); return NULL; } /* test if decoder supports requested codec */ uint32_t video_type = BUF_VIDEO_BASE | (_x_get_video_streamtype(stream) << 16); MMAL_PORT_T *input = this->decoder->input[0]; switch (video_type) { case BUF_VIDEO_H264: codec = "H.264"; input->format->encoding = MMAL_ENCODING_H264; break; case BUF_VIDEO_VC1: codec = "VC-1"; input->format->encoding = MMAL_FOURCC('V','C','-','1'); break; case BUF_VIDEO_MPEG: codec = "MPEG"; input->format->encoding = MMAL_ENCODING_MP2V; break; case BUF_VIDEO_JPEG: codec = "JPEG"; input->format->encoding = MMAL_ENCODING_JPEG; break; default: xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "unsupported video codec: 0x%x\n", video_type); mmal_dispose(&this->video_decoder); return (video_decoder_t *)1; } _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, codec); if (video_type == BUF_VIDEO_H264) { MMAL_PARAMETER_BOOLEAN_T param; param.hdr.id = MMAL_PARAMETER_VIDEO_DECODE_ERROR_CONCEALMENT; param.hdr.size = sizeof(MMAL_PARAMETER_BOOLEAN_T); param.enable = MMAL_FALSE; status = mmal_port_parameter_set(input, ¶m.hdr); if (status != MMAL_SUCCESS) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to disable error concealment: %s (%d)", mmal_status_to_string(status), status); } status = mmal_port_format_commit(input); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to commit input format %s: %s (%d)\n", codec, mmal_status_to_string(status), status); mmal_dispose(&this->video_decoder); return (video_decoder_t *)1; } input->buffer_size = input->buffer_size_recommended; input->buffer_num = input->buffer_num_recommended * 4; status = mmal_port_enable(input, input_port_cb); if (status != MMAL_SUCCESS) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE": " "failed to enable input port: %s (%d)\n", mmal_status_to_string(status), status); mmal_dispose(&this->video_decoder); return (video_decoder_t *)1; } return &this->video_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const video_decoder_class_t decode_video_mmal_class = { .open_plugin = open_plugin, .identifier = "libmmal", .description = N_("mmal-based HW video decoder plugin"), .dispose = NULL, }; return (void *)&decode_video_mmal_class; } /* * exported plugin catalog entry */ static const uint32_t video_types[] = { BUF_VIDEO_H264, BUF_VIDEO_VC1, BUF_VIDEO_MPEG, BUF_VIDEO_JPEG, 0 }; static const decoder_info_t dec_info = { .supported_types = video_types, .priority = 10, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER, 19, "libmmal", XINE_VERSION_CODE, &dec_info, init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libreal/���������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013065� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libreal/xine_real_audio_decoder.c��������������������������������������������������0000644�0001750�0001750�00000034315�14647725152�020053� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * thin layer to use real binary-only codecs in xine * * code inspired by work from Florian Schneider for the MPlayer Project */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <dlfcn.h> #define LOG_MODULE "real_audio_decoder" #define LOG_VERBOSE /* #define LOG */ #include "bswap.h" #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "real_common.h" typedef void * ra_codec_t; typedef struct realdec_decoder_s { audio_decoder_t audio_decoder; xine_stream_t *stream; void *ra_handle; uint32_t (*raCloseCodec)(ra_codec_t); uint32_t (*raDecode)(ra_codec_t, char *, uint32_t, char *, uint32_t *, uint32_t); uint32_t (*raFlush)(ra_codec_t, char *, uint32_t *); uint32_t (*raFreeDecoder)(ra_codec_t); void * (*raGetFlavorProperty)(ra_codec_t, uint16_t, uint16_t, uint16_t *); uint32_t (*raInitDecoder)(ra_codec_t, void *); uint32_t (*raOpenCodec2)(ra_codec_t *, const char *); uint32_t (*raSetFlavor)(ra_codec_t, uint16_t); void (*raSetDLLAccessPath)(char *); void (*raSetPwd)(ra_codec_t, const char *); ra_codec_t context; int sps, w, h; int block_align; uint8_t *frame_buffer; uint8_t *frame_reordered; int frame_size; int frame_num_bytes; int sample_size; uint64_t pts; int output_open; int decoder_ok; } realdec_decoder_t; typedef struct { uint32_t samplerate; uint16_t bits; uint16_t channels; uint16_t quality; uint32_t subpacket_size; uint32_t coded_frame_size; uint32_t codec_data_length; void *extras; } ra_init_t; static int load_syms_linux (realdec_decoder_t *this, const char *const codec_name, const char *const codec_alternate) { cfg_entry_t* entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "decoder.external.real_codecs_path"); if ( (this->ra_handle = _x_real_codec_open(this->stream, entry->str_value, codec_name, codec_alternate)) == NULL ) return 0; this->raCloseCodec = dlsym (this->ra_handle, "RACloseCodec"); this->raDecode = dlsym (this->ra_handle, "RADecode"); this->raFlush = dlsym (this->ra_handle, "RAFlush"); this->raFreeDecoder = dlsym (this->ra_handle, "RAFreeDecoder"); this->raGetFlavorProperty = dlsym (this->ra_handle, "RAGetFlavorProperty"); this->raOpenCodec2 = dlsym (this->ra_handle, "RAOpenCodec2"); this->raInitDecoder = dlsym (this->ra_handle, "RAInitDecoder"); this->raSetFlavor = dlsym (this->ra_handle, "RASetFlavor"); this->raSetDLLAccessPath = dlsym (this->ra_handle, "SetDLLAccessPath"); this->raSetPwd = dlsym (this->ra_handle, "RASetPwd"); /* optional, used by SIPR */ if (!this->raCloseCodec || !this->raDecode || !this->raFlush || !this->raFreeDecoder || !this->raGetFlavorProperty || !this->raOpenCodec2 || !this->raSetFlavor || /*!raSetDLLAccessPath ||*/ !this->raInitDecoder){ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libareal: (audio) Cannot resolve symbols - incompatible dll: %s\n"), codec_name); return 0; } if (this->raSetDLLAccessPath){ char path[1024]; snprintf(path, sizeof(path) - 2, "DT_Codecs=%s", entry->str_value); if (path[strlen(path)-1]!='/'){ path[strlen(path)+1]=0; path[strlen(path)]='/'; } path[strlen(path)+1]=0; this->raSetDLLAccessPath(path); } lprintf ("audio decoder loaded successfully\n"); return 1; } static int init_codec (realdec_decoder_t *this, buf_element_t *buf) { int version, result ; int samples_per_sec, bits_per_sample, num_channels; int subpacket_size, coded_frame_size, codec_data_length; int coded_frame_size2, data_len, flavor; int mode; void *extras; /* * extract header data */ version = _X_BE_16 (buf->content+4); lprintf ("header buffer detected, header version %d\n", version); #ifdef LOG xine_hexdump (buf->content, buf->size); #endif flavor = _X_BE_16 (buf->content+22); coded_frame_size = _X_BE_32 (buf->content+24); codec_data_length= _X_BE_16 (buf->content+40); coded_frame_size2= _X_BE_16 (buf->content+42); subpacket_size = _X_BE_16 (buf->content+44); this->sps = subpacket_size; this->w = coded_frame_size2; this->h = codec_data_length; if (version == 4) { samples_per_sec = _X_BE_16 (buf->content+48); bits_per_sample = _X_BE_16 (buf->content+52); num_channels = _X_BE_16 (buf->content+54); /* FIXME: */ if (buf->type==BUF_AUDIO_COOK) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libareal: audio header version 4 for COOK audio not supported.\n"); return 0; } data_len = 0; /* FIXME: COOK audio needs this */ extras = buf->content+71; } else { samples_per_sec = _X_BE_16 (buf->content+54); bits_per_sample = _X_BE_16 (buf->content+58); num_channels = _X_BE_16 (buf->content+60); data_len = _X_BE_32 (buf->content+74); extras = buf->content+78; } this->block_align= coded_frame_size2; lprintf ("0x%04x 0x%04x 0x%04x 0x%04x data_len 0x%04x\n", subpacket_size, coded_frame_size, codec_data_length, coded_frame_size2, data_len); lprintf ("%d samples/sec, %d bits/sample, %d channels\n", samples_per_sec, bits_per_sample, num_channels); /* load codec, resolv symbols */ switch (buf->type) { case BUF_AUDIO_COOK: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Cook"); if (!load_syms_linux (this, "cook.so", "cook.so.6.0")) return 0; this->block_align = subpacket_size; break; case BUF_AUDIO_ATRK: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Atrac"); if (!load_syms_linux (this, "atrc.so", "atrc.so.6.0")) return 0; this->block_align = subpacket_size; break; case BUF_AUDIO_14_4: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Real 14.4"); if (!load_syms_linux (this, "14_4.so", "14_4.so.6.0")) return 0; break; case BUF_AUDIO_28_8: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Real 28.8"); if (!load_syms_linux (this, "28_8.so", "28_8.so.6.0")) return 0; break; case BUF_AUDIO_SIPRO: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_AUDIOCODEC, "Sipro"); if (!load_syms_linux (this, "sipr.so", "sipr.so.6.0")) return 0; /* this->block_align = 19; */ break; default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libareal: error, i don't handle buf type 0x%08x\n", buf->type); return 0; } /* * init codec */ result = this->raOpenCodec2 (&this->context, NULL); if (result) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libareal: error in raOpenCodec2: %d\n", result); return 0; } { ra_init_t init_data; init_data.samplerate = samples_per_sec; init_data.bits = bits_per_sample; init_data.channels = num_channels; init_data.quality = 100; /* ??? */ init_data.subpacket_size = subpacket_size; /* subpacket size */ init_data.coded_frame_size = coded_frame_size; /* coded frame size */ init_data.codec_data_length = data_len; /* codec data length */ init_data.extras = extras; /* extras */ #ifdef LOG printf ("libareal: init_data:\n"); xine_hexdump ((char *) &init_data, sizeof (ra_init_t)); printf ("libareal: extras :\n"); xine_hexdump (init_data.extras, data_len); #endif result = this->raInitDecoder (this->context, &init_data); if(result){ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libareal: decoder init failed, error code: 0x%x\n"), result); return 0; } } if (this->raSetPwd){ /* used by 'SIPR' */ this->raSetPwd (this->context, "Ardubancel Quazanga"); /* set password... lol. */ lprintf ("password set\n"); } result = this->raSetFlavor (this->context, flavor); if (result){ xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libareal: decoder flavor setup failed, error code: 0x%x\n"), result); return 0; } /* * alloc buffers for data reordering */ if (this->sps) { this->frame_size = this->w/this->sps*this->h*this->sps; this->frame_buffer = calloc (1, this->frame_size); this->frame_reordered = calloc (1, this->frame_size); this->frame_num_bytes = 0; } else { this->frame_size = this->w*this->h; this->frame_buffer = calloc (this->w, this->h); this->frame_reordered = this->frame_buffer; this->frame_num_bytes = 0; } /* * open audio output */ switch (num_channels) { case 1: mode = AO_CAP_MODE_MONO; break; case 2: mode = AO_CAP_MODE_STEREO; break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libareal: oups, real can do more than 2 channels ?\n")); return 0; } (this->stream->audio_out->open) (this->stream->audio_out, this->stream, bits_per_sample, samples_per_sec, mode) ; this->output_open = 1; this->sample_size = num_channels * (bits_per_sample>>3); return 1; } static void realdec_decode_data (audio_decoder_t *this_gen, buf_element_t *buf) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; lprintf ("decode_data %d bytes, flags=0x%08x, pts=%"PRId64" ...\n", buf->size, buf->decoder_flags, buf->pts); if (buf->decoder_flags & BUF_FLAG_PREVIEW) { /* real_find_sequence_header (&this->real, buf->content, buf->content + buf->size);*/ } else if (buf->decoder_flags & BUF_FLAG_HEADER) { this->decoder_ok = init_codec (this, buf) ; if( !this->decoder_ok ) _x_stream_info_set(this->stream, XINE_STREAM_INFO_AUDIO_HANDLED, 0); } else if( this->decoder_ok ) { int size; lprintf ("content buffer detected, %d bytes\n", buf->size); if (buf->pts && !this->pts) this->pts = buf->pts; size = buf->size; while (size) { int need; need = this->frame_size - this->frame_num_bytes; if (size < need) { memcpy (this->frame_buffer + this->frame_num_bytes, buf->content + buf->size - size, size); this->frame_num_bytes += size; size = 0; } else { audio_buffer_t *audio_buffer; int n, len; #ifdef LOG int result; #endif memcpy (this->frame_buffer + this->frame_num_bytes, buf->content + buf->size - size, need); size -= need; this->frame_num_bytes = 0; n = 0; while (n < this->frame_size) { audio_buffer = this->stream->audio_out->get_buffer (this->stream->audio_out); #ifdef LOG result = #endif this->raDecode (this->context, this->frame_buffer + n, this->block_align, (char *) audio_buffer->mem, &len, -1); #ifdef LOG lprintf ("raDecode result %d, len=%d\n", result, len); #endif audio_buffer->vpts = this->pts; this->pts = 0; audio_buffer->num_frames = len/this->sample_size;; this->stream->audio_out->put_buffer (this->stream->audio_out, audio_buffer, this->stream); n += this->block_align; } } } } lprintf ("decode_data...done\n"); } static void realdec_reset (audio_decoder_t *this_gen) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; this->frame_num_bytes = 0; } static void realdec_discontinuity (audio_decoder_t *this_gen) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; this->pts = 0; } static void realdec_dispose (audio_decoder_t *this_gen) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; lprintf ("dispose\n"); if (this->context) this->raCloseCodec (this->context); #if 0 printf ("libareal: FreeDecoder...\n"); if (this->context) this->raFreeDecoder (this->context); #endif lprintf ("dlclose...\n"); if (this->ra_handle) dlclose (this->ra_handle); if (this->output_open) this->stream->audio_out->close (this->stream->audio_out, this->stream); _x_freep (&this->frame_buffer); free (this); lprintf ("dispose done\n"); } static audio_decoder_t *open_plugin (audio_decoder_class_t *class_gen, xine_stream_t *stream) { realdec_decoder_t *this ; (void)class_gen; this = (realdec_decoder_t *) calloc(1, sizeof(realdec_decoder_t)); if (!this) { return NULL; } this->audio_decoder.decode_data = realdec_decode_data; this->audio_decoder.reset = realdec_reset; this->audio_decoder.discontinuity = realdec_discontinuity; this->audio_decoder.dispose = realdec_dispose; this->stream = stream; this->output_open = 0; return &this->audio_decoder; } /* * real plugin class */ void *init_realadec (xine_t *xine, const void *data) { static const audio_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "realadec", .description = N_("real binary-only codec based audio decoder plugin"), .dispose = NULL }; (void)data; _x_real_codecs_init(xine); return (audio_decoder_class_t *)&this; } /* * exported plugin catalog entry */ static const uint32_t audio_types[] = { BUF_AUDIO_COOK, BUF_AUDIO_ATRK, /* BUF_AUDIO_14_4, BUF_AUDIO_28_8, */ BUF_AUDIO_SIPRO, 0 }; const decoder_info_t dec_info_realaudio = { audio_types, /* supported types */ 6 /* priority */ }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/libreal/Makefile.am����������������������������������������������������������������0000644�0001750�0001750�00000000677�14647725152�015133� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) if ENABLE_REAL xineplug_LTLIBRARIES = xineplug_decode_real.la endif xineplug_decode_real_la_SOURCES = \ real_common.h \ real_common.c \ xine_real_audio_decoder.c \ xine_real_video_decoder.c xineplug_decode_real_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) �����������������������������������������������������������������xine-lib-1.2/src/libreal/real_common.h��������������������������������������������������������������0000644�0001750�0001750�00000004732�14647725152�015537� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Common function for the thin layer to use Real binary-only codecs in xine */ #ifndef __REAL_COMMON_H__ #define __REAL_COMMON_H__ #include <xine/xine_internal.h> /* * some fake functions to make real codecs happy * These are, on current date (20070316) needed only for Alpha * codecs. * As they are far from being proper replacements, define them only there * until new codecs are available there too. */ #ifdef __alpha__ void *__builtin_new(size_t size); void __builtin_delete (void *foo); void *__builtin_vec_new(size_t size) EXPORTED; void __builtin_vec_delete(void *mem) EXPORTED; void __pure_virtual(void) EXPORTED; #endif #ifndef HAVE___ENVIRON # ifdef HAVE__ENVIRON char **__environ __attribute__((weak, alias("_environ"))); # elif defined(HAVE_ENVIRON) char **__environ __attribute__((weak, alias("environ"))); # else char **fake__environ = { NULL }; char **__environ __attribute__((weak, alias("fake__environ"))); # endif #endif #ifndef HAVE_STDERR # ifdef HAVE___STDERRP # undef stderr FILE *stderr __attribute__((weak, alias("__stderrp"))); # else # error Your stderr alias is not supported, please report to xine developers. # endif #endif #ifndef HAVE____BRK_ADDR void ___brk_addr(void) EXPORTED; #endif #ifndef HAVE___CTYPE_B void __ctype_b(void) EXPORTED; #endif void _x_real_codecs_init(xine_t *const xine); void *_x_real_codec_open(xine_stream_t *const stream, const char *const path, const char *const codec_name, const char *const codec_alternate); extern const decoder_info_t dec_info_realvideo; void *init_realvdec (xine_t *xine, const void *data); extern const decoder_info_t dec_info_realaudio; void *init_realadec (xine_t *xine, const void *data); #endif ��������������������������������������xine-lib-1.2/src/libreal/real_common.c��������������������������������������������������������������0000644�0001750�0001750�00000012633�14647725152�015531� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Common function for the thin layer to use Real binary-only codecs in xine */ #define LOG_MODULE "real_common" #define LOG_VERBOSE /* #define LOG */ #include "config.h" #include <sys/stat.h> #include <string.h> #include <dlfcn.h> #include "real_common.h" #ifdef __alpha__ void *__builtin_new(size_t size) { return malloc(size); } void __builtin_delete (void *foo) { /* printf ("libareal: __builtin_delete called\n"); */ free (foo); } void *__builtin_vec_new(size_t size) { return malloc(size); } void __builtin_vec_delete(void *mem) { free(mem); } void __pure_virtual(void) { lprintf("libreal: FATAL: __pure_virtual() called!\n"); /* exit(1); */ } #endif #ifndef HAVE____BRK_ADDR void ___brk_addr(void) { exit(0); } #endif #ifndef HAVE___CTYPE_B void __ctype_b(void) { exit(0); } #endif void _x_real_codecs_init(xine_t *const xine) { #ifdef LOG const char *real_codecs_path; #endif #ifdef REAL_CODEC_PATH const char *const default_real_codecs_path = REAL_CODEC_PATH; #else char default_real_codecs_path[256]; default_real_codecs_path[0] = 0; #define UL64 0x03 /* /usr/{,local/}lib64 */ #define UL 0x0C /* /usr/{,local/}lib */ #define O 0x10 /* /opt */ #define OL64 0x20 /* /opt/lib64 */ #define OL 0x40 /* /opt/lib */ static const char *const prefix[] = { "/usr/lib64", "/usr/local/lib64", "/usr/lib", "/usr/local/lib", "/opt", "/opt/lib64", "/opt/lib", }; static const struct { int prefix; const char *path; } paths[] = { { O | UL, "win32" }, { O | UL | UL64, "codecs" }, { O | UL | UL64, "real" }, { O, "real/RealPlayer/codecs" }, { OL | OL64 | UL | UL64, "RealPlayer10GOLD/codecs" }, { OL | OL64 | UL | UL64, "RealPlayer10/codecs" }, { OL | OL64 | UL | UL64, "RealPlayer9/users/Real/Codecs" }, { O | OL | UL, "RealPlayer8/Codecs" }, { 0, NULL} }; int i; for (i = 0; paths[i].prefix; ++i) { int p; for (p = 0; p < (int)sizeof (prefix) / (int)sizeof (prefix[0]); ++p) { if (paths[i].prefix & (1 << p)) { void *handle; snprintf (default_real_codecs_path, sizeof (default_real_codecs_path), "%s/%s/drvc.so", prefix[p], paths[i].path); handle = dlopen (default_real_codecs_path, RTLD_NOW); if (handle) { dlclose (handle); snprintf (default_real_codecs_path, sizeof (default_real_codecs_path), "%s/%s", prefix[p], paths[i].path); goto found; } } } } /* if this is reached, no valid path was found */ default_real_codecs_path[0] = 0; found:; #endif #ifdef LOG real_codecs_path = #endif xine->config->register_filename (xine->config, "decoder.external.real_codecs_path", default_real_codecs_path, XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("path to RealPlayer codecs"), _("If you have RealPlayer installed, specify the path " "to its codec directory here. You can easily find " "the codec directory by looking for a file named " "\"drvc.so\" in it. If xine can find the RealPlayer " "codecs, it will use them to decode RealPlayer content " "for you. Consult the xine FAQ for more information on " "how to install the codecs."), 10, NULL, NULL); #ifdef LOG lprintf ("real codecs path : %s\n", real_codecs_path); #endif } void *_x_real_codec_open(xine_stream_t *const stream, const char *const path, const char *const codec_name, const char *const codec_alternate) { char *codecpath = NULL; void *codecmodule = NULL; codecpath = _x_asprintf("%s/%s", path, codec_name); if ( (codecmodule = dlopen(codecpath, RTLD_NOW)) ) { free(codecpath); return codecmodule; } xprintf (stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": error loading %s: %s\n", codecpath, dlerror()); free(codecpath); if ( codec_alternate ) { codecpath = _x_asprintf("%s/%s", path, codec_alternate); if ( (codecmodule = dlopen(codecpath, RTLD_NOW)) ) { free(codecpath); return codecmodule; } xprintf (stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": error loading %s: %s\n", codecpath, dlerror()); free(codecpath); } _x_message(stream, XINE_MSG_LIBRARY_LOAD_ERROR, codec_name, NULL); return NULL; } const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_VIDEO_DECODER | PLUGIN_MUST_PRELOAD, 19, "realvdec", XINE_VERSION_CODE, &dec_info_realvideo, init_realvdec }, { PLUGIN_AUDIO_DECODER | PLUGIN_MUST_PRELOAD, 16, "realadec", XINE_VERSION_CODE, &dec_info_realaudio, init_realadec }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������xine-lib-1.2/src/libreal/xine_real_video_decoder.c��������������������������������������������������0000644�0001750�0001750�00000041100�14647725152�020046� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * thin layer to use real binary-only codecs in xine * * code inspired by work from Florian Schneider for the MPlayer Project */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <dlfcn.h> #define LOG_MODULE "real_decoder" #define LOG_VERBOSE /* #define LOG */ #include "bswap.h" #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/buffer.h> #include <xine/xineutils.h> #include "real_common.h" #define BUF_SIZE 65536 typedef struct realdec_decoder_s { video_decoder_t video_decoder; xine_stream_t *stream; void *rv_handle; uint32_t (*rvyuv_custom_message)(void*, void*); uint32_t (*rvyuv_free)(void*); uint32_t (*rvyuv_hive_message)(uint32_t, void*); uint32_t (*rvyuv_init)(void*, void*); /* initdata,context */ uint32_t (*rvyuv_transform)(char*, char*, void*, void*, void*); void *context; uint32_t width, height; double ratio; double fps; uint8_t *chunk_buffer; int chunk_buffer_size; int chunk_buffer_max; int64_t pts; int duration; uint8_t *frame_buffer; int frame_size; int decoder_ok; } realdec_decoder_t; /* we need exact positions */ typedef struct { int16_t unk1; int16_t w; int16_t h; int16_t unk3; int32_t unk2; int32_t subformat; int32_t unk5; int32_t format; } rv_init_t; /* * Structures for data packets. These used to be tables of unsigned ints, but * that does not work on 64 bit platforms (e.g. Alpha). The entries that are * pointers get truncated. Pointers on 64 bit platforms are 8 byte longs. * So we have to use structures so the compiler will assign the proper space * for the pointer. */ typedef struct cmsg_data_s { uint32_t data1; uint32_t data2; uint32_t* dimensions; } cmsg_data_t; typedef struct transform_in_s { uint32_t len; uint32_t interpolate; uint32_t nsegments; void *segments; uint32_t flags; uint32_t timestamp; } transform_in_t; typedef struct { uint32_t frames; uint32_t notes; uint32_t timestamp; uint32_t width; uint32_t height; } transform_out_t; /* * real codec loader */ static int load_syms_linux (realdec_decoder_t *this, const char *codec_name, const char *const codec_alternate) { cfg_entry_t* entry = this->stream->xine->config->lookup_entry(this->stream->xine->config, "decoder.external.real_codecs_path"); if ( (this->rv_handle = _x_real_codec_open(this->stream, entry->str_value, codec_name, codec_alternate)) == NULL ) return 0; this->rvyuv_custom_message = dlsym (this->rv_handle, "RV20toYUV420CustomMessage"); this->rvyuv_free = dlsym (this->rv_handle, "RV20toYUV420Free"); this->rvyuv_hive_message = dlsym (this->rv_handle, "RV20toYUV420HiveMessage"); this->rvyuv_init = dlsym (this->rv_handle, "RV20toYUV420Init"); this->rvyuv_transform = dlsym (this->rv_handle, "RV20toYUV420Transform"); if (this->rvyuv_custom_message && this->rvyuv_free && this->rvyuv_hive_message && this->rvyuv_init && this->rvyuv_transform) return 1; this->rvyuv_custom_message = dlsym (this->rv_handle, "RV40toYUV420CustomMessage"); this->rvyuv_free = dlsym (this->rv_handle, "RV40toYUV420Free"); this->rvyuv_hive_message = dlsym (this->rv_handle, "RV40toYUV420HiveMessage"); this->rvyuv_init = dlsym (this->rv_handle, "RV40toYUV420Init"); this->rvyuv_transform = dlsym (this->rv_handle, "RV40toYUV420Transform"); if (this->rvyuv_custom_message && this->rvyuv_free && this->rvyuv_hive_message && this->rvyuv_init && this->rvyuv_transform) return 1; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("libreal: Error resolving symbols! (version incompatibility?)\n")); return 0; } static int init_codec (realdec_decoder_t *this, buf_element_t *buf) { /* unsigned int* extrahdr = (unsigned int*) (buf->content+28); */ #ifdef LOG int result; #endif rv_init_t init_data = {11, 0, 0, 0, 0, 0, 1, 0}; /* rv30 */ switch (buf->type) { case BUF_VIDEO_RV20: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 2.0"); if (!load_syms_linux (this, "drv2.so", "drv2.so.6.0")) return 0; break; case BUF_VIDEO_RV30: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 3.0"); if (!load_syms_linux (this, "drvc.so", "drv3.so.6.0")) return 0; break; case BUF_VIDEO_RV40: _x_meta_info_set_utf8(this->stream, XINE_META_INFO_VIDEOCODEC, "Real Video 4.0"); if (!load_syms_linux(this, "drvc.so", "drv3.so.6.0")) return 0; break; default: xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "libreal: error, i don't handle buf type 0x%08x\n", buf->type); return 0; } init_data.w = _X_BE_16(&buf->content[12]); init_data.h = _X_BE_16(&buf->content[14]); this->width = (init_data.w + 1) & (~1); this->height = (init_data.h + 1) & (~1); if(buf->decoder_flags & BUF_FLAG_ASPECT) this->ratio = (double)buf->decoder_info[1] / (double)buf->decoder_info[2]; else this->ratio = (double)this->width / (double)this->height; /* While the framerate is stored in the header it sometimes doesn't bear * much resemblence to the actual frequency of frames in the file. Hence * it's better to just let the engine estimate the frame duration for us */ #if 0 this->fps = (double) _X_BE_16(&buf->content[22]) + ((double) _X_BE_16(&buf->content[24]) / 65536.0); this->duration = 90000.0 / this->fps; #endif lprintf("this->ratio=%f\n", this->ratio); lprintf ("init_data.w=%d(0x%x), init_data.h=%d(0x%x)," "this->width=%d(0x%x), this->height=%d(0x%x)\n", init_data.w, init_data.w, init_data.h, init_data.h, this->width, this->width, this->height, this->height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_RATIO, this->ratio*10000); _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration); init_data.subformat = _X_BE_32(&buf->content[26]); init_data.format = _X_BE_32(&buf->content[30]); #ifdef LOG printf ("libreal: init_data for rvyuv_init:\n"); xine_hexdump ((char *) &init_data, sizeof (init_data)); printf ("libreal: buf->content\n"); xine_hexdump (buf->content, buf->size); #endif lprintf ("init codec %dx%d... %x %x\n", init_data.w, init_data.h, init_data.subformat, init_data.format ); this->context = NULL; #ifdef LOG result = #endif this->rvyuv_init (&init_data, &this->context); #ifdef LOG lprintf ("init result: %d\n", result); #endif /* setup rv30 codec (codec sub-type and image dimensions): */ if ((init_data.format>=0x20200002) && (buf->type != BUF_VIDEO_RV40)) { int i, j; uint32_t cmsg24[(buf->size - 34 + 2) * sizeof(uint32_t)]; cmsg_data_t cmsg_data = { 0x24, 1 + ((init_data.subformat >> 16) & 7), &cmsg24[0] }; cmsg24[0] = this->width; cmsg24[1] = this->height; for(i = 2, j = 34; j < buf->size; i++, j++) cmsg24[i] = 4 * buf->content[j]; #ifdef LOG printf ("libreal: CustomMessage cmsg_data:\n"); xine_hexdump ((uint8_t *) &cmsg_data, sizeof (cmsg_data)); printf ("libreal: cmsg24:\n"); xine_hexdump ((uint8_t *) cmsg24, (buf->size - 34 + 2) * sizeof(uint32_t)); #endif this->rvyuv_custom_message (&cmsg_data, this->context); } (this->stream->video_out->open) (this->stream->video_out, this->stream); this->frame_size = this->width * this->height; this->frame_buffer = calloc (1, this->frame_size * 3 / 2); this->chunk_buffer = calloc(1, BUF_SIZE); this->chunk_buffer_max = BUF_SIZE; return 1; } static void realdec_decode_data (video_decoder_t *this_gen, buf_element_t *buf) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; lprintf ("decode_data, flags=0x%08x, len=%d, pts=%"PRId64" ...\n", buf->decoder_flags, buf->size, buf->pts); if (buf->decoder_flags & BUF_FLAG_PREVIEW) { /* real_find_sequence_header (&this->real, buf->content, buf->content + buf->size);*/ return; } if (buf->decoder_flags & BUF_FLAG_FRAMERATE) { this->duration = buf->decoder_info[0]; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration); } if (buf->decoder_flags & BUF_FLAG_HEADER) { this->decoder_ok = init_codec (this, buf); if( !this->decoder_ok ) _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HANDLED, 0); } else if (this->decoder_ok && this->context) { /* Each frame starts with BUF_FLAG_FRAME_START and ends with * BUF_FLAG_FRAME_END. * The last buffer contains the chunk offset table. */ if (!(buf->decoder_flags & BUF_FLAG_SPECIAL)) { lprintf ("buffer (%d bytes)\n", buf->size); if (buf->decoder_flags & BUF_FLAG_FRAME_START) { /* new frame starting */ this->chunk_buffer_size = 0; this->pts = buf->pts; lprintf ("new frame starting, pts=%"PRId64"\n", this->pts); } if ((this->chunk_buffer_size + buf->size) > this->chunk_buffer_max) { lprintf("increasing chunk buffer size\n"); this->chunk_buffer_max *= 2; this->chunk_buffer = realloc(this->chunk_buffer, this->chunk_buffer_max); } xine_fast_memcpy (this->chunk_buffer + this->chunk_buffer_size, buf->content, buf->size); this->chunk_buffer_size += buf->size; } else { /* end of frame, chunk table */ lprintf ("special buffer (%d bytes)\n", buf->size); if (buf->decoder_info[1] == BUF_SPECIAL_RV_CHUNK_TABLE) { #ifdef LOG int result; #endif vo_frame_t *img; transform_out_t transform_out; transform_in_t transform_in = { this->chunk_buffer_size, /* length of the packet (sub-packets appended) */ 0, /* unknown, seems to be unused */ buf->decoder_info[2], /* number of sub-packets - 1 */ buf->decoder_info_ptr[2], /* table of sub-packet offsets */ 0, /* unknown, seems to be unused */ this->pts / 90 /* timestamp (the integer value from the stream) */ }; lprintf ("chunk table\n"); #ifdef LOG printf ("libreal: got %d chunks\n", buf->decoder_info[2] + 1); printf ("libreal: decoding %d bytes:\n", this->chunk_buffer_size); xine_hexdump (this->chunk_buffer, this->chunk_buffer_size); printf ("libreal: transform_in:\n"); xine_hexdump ((uint8_t *) &transform_in, sizeof(transform_in_t)); printf ("libreal: chunk_table:\n"); xine_hexdump ((uint8_t *) buf->decoder_info_ptr[2], 2*(buf->decoder_info[2]+1)*sizeof(uint32_t)); #endif #ifdef LOG result = #endif this->rvyuv_transform (this->chunk_buffer, this->frame_buffer, &transform_in, &transform_out, this->context); #ifdef LOG lprintf ("transform result: %08x\n", result); lprintf ("transform_out:\n"); xine_hexdump ((uint8_t *) &transform_out, 5 * 4); #endif /* Sometimes the stream contains video of a different size * to that specified in the realmedia header */ if(transform_out.frames && ((transform_out.width != this->width) || (transform_out.height != this->height))) { this->width = transform_out.width; this->height = transform_out.height; this->frame_size = this->width * this->height; _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_WIDTH, this->width); _x_stream_info_set(this->stream, XINE_STREAM_INFO_VIDEO_HEIGHT, this->height); } img = this->stream->video_out->get_frame (this->stream->video_out, /* this->av_picture.linesize[0], */ this->width, this->height, this->ratio, XINE_IMGFMT_YV12, VO_BOTH_FIELDS); img->pts = (int64_t)transform_out.timestamp * 90; img->duration = this->duration; _x_stream_info_set(this->stream, XINE_STREAM_INFO_FRAME_DURATION, this->duration); img->bad_frame = 0; yv12_to_yv12( /* Y */ this->frame_buffer, this->width, img->base[0], img->pitches[0], /* U */ this->frame_buffer + this->frame_size, this->width/2, img->base[1], img->pitches[1], /* V */ this->frame_buffer + this->frame_size * 5/4, this->width/2, img->base[2], img->pitches[2], /* width x height */ this->width, this->height); img->draw(img, this->stream); img->free(img); } else { /* unsupported special buf */ } } } lprintf ("decode_data...done\n"); } static void realdec_flush (video_decoder_t *this_gen) { /* realdec_decoder_t *this = (realdec_decoder_t *) this_gen; */ (void)this_gen; lprintf ("flush\n"); } static void realdec_reset (video_decoder_t *this_gen) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; this->chunk_buffer_size = 0; } static void realdec_discontinuity (video_decoder_t *this_gen) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; this->pts = 0; } static void realdec_dispose (video_decoder_t *this_gen) { realdec_decoder_t *this = (realdec_decoder_t *) this_gen; lprintf ("dispose\n"); if (this->context) this->stream->video_out->close(this->stream->video_out, this->stream); if (this->rvyuv_free && this->context) this->rvyuv_free (this->context); if (this->rv_handle) dlclose (this->rv_handle); _x_freep (&this->frame_buffer); _x_freep (&this->chunk_buffer); free (this); lprintf ("dispose done\n"); } static video_decoder_t *open_plugin (video_decoder_class_t *class_gen, xine_stream_t *stream) { realdec_decoder_t *this ; (void)class_gen; this = (realdec_decoder_t *) calloc(1, sizeof(realdec_decoder_t)); if (!this) { return NULL; } this->video_decoder.decode_data = realdec_decode_data; this->video_decoder.flush = realdec_flush; this->video_decoder.reset = realdec_reset; this->video_decoder.discontinuity = realdec_discontinuity; this->video_decoder.dispose = realdec_dispose; this->stream = stream; this->context = 0; this->pts = 0; this->duration = 0; return &this->video_decoder; } /* * real plugin class */ void *init_realvdec (xine_t *xine, const void *data) { static const video_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "realvdec", .description = N_("real binary-only codec based video decoder plugin"), .dispose = NULL }; (void)data; _x_real_codecs_init(xine); return (video_decoder_class_t *)&this; } /* * exported plugin catalog entry */ static const uint32_t supported_types[] = { BUF_VIDEO_RV30, BUF_VIDEO_RV40, 0 }; const decoder_info_t dec_info_realvideo = { supported_types, /* supported types */ 7 /* priority */ }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/������������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�012440� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013541� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/audio_filters.h���������������������������������������������������������0000644�0001750�0001750�00000002152�14647725152�016543� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * catalog for audio filter plugins */ #include <xine/xine_internal.h> void *upmix_init_plugin (xine_t *xine, const void *data); void *upmix_mono_init_plugin (xine_t *xine, const void *data); void *stretch_init_plugin (xine_t *xine, const void *data); void *volnorm_init_plugin (xine_t *xine, const void *data); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/window.c����������������������������������������������������������������0000644�0001750�0001750�00000012133�14647725152�015214� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*============================================================================= * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. * * Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au * *============================================================================= */ /* Calculates a number of window functions. The following window * functions are currently implemented: Boxcar, Triang, Hanning, * Hamming, Blackman, Flattop and Kaiser. In the function call n is * the number of filter taps and w the buffer in which the filter * coefficients will be stored. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <math.h> #include "dsp.h" /* * Boxcar * * n window length * w buffer for the window parameters */ void boxcar(int n, _ftype_t* w) { int i; /* Calculate window coefficients */ for (i=0 ; i<n ; i++) w[i] = 1.0; } /* * Triang a.k.a Bartlett * * | (N-1)| * 2 * |k - -----| * | 2 | * w = 1.0 - --------------- * N+1 * n window length * w buffer for the window parameters */ void triang(int n, _ftype_t* w) { _ftype_t k1 = (_ftype_t)(n & 1); _ftype_t k2 = 1/((_ftype_t)n + k1); int end = (n + 1) >> 1; int i; /* Calculate window coefficients */ for (i=0 ; i<end ; i++) w[i] = w[n-i-1] = (2.0*((_ftype_t)(i+1))-(1.0-k1))*k2; } /* * Hanning * 2*pi*k * w = 0.5 - 0.5*cos(------), where 0 < k <= N * N+1 * n window length * w buffer for the window parameters */ void hanning(int n, _ftype_t* w) { int i; _ftype_t k = 2*M_PI/((_ftype_t)(n+1)); /* 2*pi/(N+1) */ /* Calculate window coefficients */ for (i=0; i<n; i++) *w++ = 0.5*(1.0 - cos(k*(_ftype_t)(i+1))); } /* * Hamming * 2*pi*k * w(k) = 0.54 - 0.46*cos(------), where 0 <= k < N * N-1 * * n window length * w buffer for the window parameters */ void hamming(int n,_ftype_t* w) { int i; _ftype_t k = 2*M_PI/((_ftype_t)(n-1)); /* 2*pi/(N-1) */ /* Calculate window coefficients */ for (i=0; i<n; i++) *w++ = 0.54 - 0.46*cos(k*(_ftype_t)i); } /* * Blackman * 2*pi*k 4*pi*k * w(k) = 0.42 - 0.5*cos(------) + 0.08*cos(------), where 0 <= k < N * N-1 N-1 * * n window length * w buffer for the window parameters */ void blackman(int n,_ftype_t* w) { int i; _ftype_t k1 = 2*M_PI/((_ftype_t)(n-1)); /* 2*pi/(N-1) */ _ftype_t k2 = 2*k1; /* 4*pi/(N-1) */ /* Calculate window coefficients */ for (i=0; i<n; i++) *w++ = 0.42 - 0.50*cos(k1*(_ftype_t)i) + 0.08*cos(k2*(_ftype_t)i); } /* * Flattop * 2*pi*k 4*pi*k * w(k) = 0.2810638602 - 0.5208971735*cos(------) + 0.1980389663*cos(------), where 0 <= k < N * N-1 N-1 * * n window length * w buffer for the window parameters */ void flattop(int n,_ftype_t* w) { int i; _ftype_t k1 = 2*M_PI/((_ftype_t)(n-1)); /* 2*pi/(N-1) */ _ftype_t k2 = 2*k1; /* 4*pi/(N-1) */ /* Calculate window coefficients */ for (i=0; i<n; i++) *w++ = 0.2810638602 - 0.5208971735*cos(k1*(_ftype_t)i) + 0.1980389663*cos(k2*(_ftype_t)i); } /* Computes the 0th order modified Bessel function of the first kind. * (Needed to compute Kaiser window) * * y = sum( (x/(2*n))^2 ) * n */ #define BIZ_EPSILON 1E-21 /* Max error acceptable */ static _ftype_t besselizero(_ftype_t x) { _ftype_t temp; _ftype_t sum = 1.0; _ftype_t u = 1.0; _ftype_t halfx = x/2.0; int n = 1; do { temp = halfx/(_ftype_t)n; u *=temp * temp; sum += u; n++; } while (u >= BIZ_EPSILON * sum); return(sum); } /* * Kaiser * * n window length * w buffer for the window parameters * b beta parameter of Kaiser window, Beta >= 1 * * Beta trades the rejection of the low pass filter against the * transition width from passband to stop band. Larger Beta means a * slower transition and greater stop band rejection. See Rabiner and * Gold (Theory and Application of DSP) under Kaiser windows for more * about Beta. The following table from Rabiner and Gold gives some * feel for the effect of Beta: * * All ripples in dB, width of transition band = D*N where N = window * length * * BETA D PB RIP SB RIP * 2.120 1.50 +-0.27 -30 * 3.384 2.23 0.0864 -40 * 4.538 2.93 0.0274 -50 * 5.658 3.62 0.00868 -60 * 6.764 4.32 0.00275 -70 * 7.865 5.0 0.000868 -80 * 8.960 5.7 0.000275 -90 * 10.056 6.4 0.000087 -100 */ void kaiser(int n, _ftype_t* w, _ftype_t b) { _ftype_t tmp; _ftype_t k1 = 1.0/besselizero(b); int k2 = 1 - (n & 1); int end = (n + 1) >> 1; int i; /* Calculate window coefficients */ for (i=0 ; i<end ; i++){ tmp = (_ftype_t)(2*i + k2) / ((_ftype_t)n - 1.0); w[end-(1&(!k2))+i] = w[end-1-i] = k1 * besselizero(b*sqrt(1.0 - tmp*tmp)); } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/volnorm.c���������������������������������������������������������������0000644�0001750�0001750�00000031536�14647725152�015411� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Volume normalization audio filter for xine. Ported by Jason Tackaberry * from MPlayer's af_volnorm, which is copyright 2004 by Alex Beregszaszi * & Pierre Lombard. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <math.h> #include <pthread.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "dsp.h" #include "audio_filters.h" // Methods: // 1: uses a 1 value memory and coefficients new=a*old+b*cur (with a+b=1) // 2: uses several samples to smooth the variations (standard weighted mean // on past samples) // Size of the memory array // FIXME: should depend on the frequency of the data (should be a few seconds) #define NSAMPLES 128 // If summing all the mem[].len is lower than MIN_SAMPLE_SIZE bytes, then we // choose to ignore the computed value as it's not significant enough // FIXME: should depend on the frequency of the data (0.5s maybe) #define MIN_SAMPLE_SIZE 32000 // mul is the value by which the samples are scaled // and has to be in [MUL_MIN, MUL_MAX] #define MUL_INIT 1.0 #define MUL_MIN 0.1 #define MUL_MAX 5.0 // "Ideal" level #define MID_S16 (SHRT_MAX * 0.25) #define MID_FLOAT (INT_MAX * 0.25) // Silence level // FIXME: should be relative to the level of the samples #define SIL_S16 (SHRT_MAX * 0.01) #define SIL_FLOAT (INT_MAX * 0.01) // FIXME // smooth must be in ]0.0, 1.0[ #define SMOOTH_MUL 0.06 #define SMOOTH_LASTAVG 0.06 #define clamp(a,min,max) (((a)>(max))?(max):(((a)<(min))?(min):(a))) typedef struct post_plugin_volnorm_s post_plugin_volnorm_t; typedef struct volnorm_parameters_s { int method; } volnorm_parameters_t; /* * description of params struct */ START_PARAM_DESCR( volnorm_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, method, NULL, 0, 2, 0, "Normalization method" ) END_PARAM_DESCR( param_descr ) struct post_plugin_volnorm_s { post_plugin_t post; /* private data */ pthread_mutex_t lock; // From mplayer af_volnorm int method; float mul; // method 1 float lastavg; // history value of the filter // method 2 int idx; struct { float avg; // average level of the sample int len; // sample size (weight) } mem[NSAMPLES]; }; /************************************************************************** * volnorm parameters functions *************************************************************************/ static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_volnorm_t *this = (post_plugin_volnorm_t *)this_gen; const volnorm_parameters_t *param = (const volnorm_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); this->method = param->method; pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_volnorm_t *this = (post_plugin_volnorm_t *)this_gen; volnorm_parameters_t *param = (volnorm_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); param->method = this->method; pthread_mutex_unlock (&this->lock); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return (void *)¶m_descr; } static char * get_help (void) { return _("Normalizes audio by maximizing the volume without distorting " "the sound.\n" "\n" "Parameters:\n" " method: 1: use a single sample to smooth the variations via " "the standard weighted mean over past samples (default); 2: use " "several samples to smooth the variations via the standard " "weighted mean over past samples.\n" ); } /************************************************************************** * xine audio post plugin functions *************************************************************************/ static int volnorm_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_volnorm_t *this = (post_plugin_volnorm_t *)port->post; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } static void volnorm_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; port->stream = NULL; port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } static void method1_int16(post_plugin_volnorm_t *this, audio_buffer_t *buf) { register int i = 0; int16_t *data = (int16_t*)buf->mem; // Audio data int len = buf->mem_size / 2; // Number of samples float curavg = 0.0, newavg, neededmul; int tmp; for (i = 0; i < len; i++) { tmp = data[i]; curavg += tmp * tmp; } curavg = sqrt(curavg / (float) len); // Evaluate an adequate 'mul' coefficient based on previous state, current // samples level, etc if (curavg > SIL_S16) { neededmul = MID_S16 / (curavg * this->mul); this->mul = (1.0 - SMOOTH_MUL) * this->mul + SMOOTH_MUL * neededmul; // clamp the mul coefficient this->mul = clamp(this->mul, MUL_MIN, MUL_MAX); } // Scale & clamp the samples for (i = 0; i < len; i++) { tmp = this->mul * data[i]; tmp = clamp(tmp, SHRT_MIN, SHRT_MAX); data[i] = tmp; } // Evaulation of newavg (not 100% accurate because of values clamping) newavg = this->mul * curavg; // Stores computed values for future smoothing this->lastavg = (1.0 - SMOOTH_LASTAVG) * this->lastavg + SMOOTH_LASTAVG * newavg; } static void method1_float(post_plugin_volnorm_t *this, audio_buffer_t *buf) { register int i = 0; float *data = (float*)buf->mem; // Audio data int len = buf->mem_size / 4; // Number of samples float curavg = 0.0, newavg, neededmul, tmp; for (i = 0; i < len; i++) { tmp = data[i]; curavg += tmp * tmp; } curavg = sqrt(curavg / (float) len); // Evaluate an adequate 'mul' coefficient based on previous state, current // samples level, etc if (curavg > SIL_FLOAT) // FIXME { neededmul = MID_FLOAT / (curavg * this->mul); this->mul = (1.0 - SMOOTH_MUL) * this->mul + SMOOTH_MUL * neededmul; // clamp the mul coefficient this->mul = clamp(this->mul, MUL_MIN, MUL_MAX); } // Scale & clamp the samples for (i = 0; i < len; i++) data[i] *= this->mul; // Evaulation of newavg (not 100% accurate because of values clamping) newavg = this->mul * curavg; // Stores computed values for future smoothing this->lastavg = (1.0 - SMOOTH_LASTAVG) * this->lastavg + SMOOTH_LASTAVG * newavg; } static void method2_int16(post_plugin_volnorm_t *this, audio_buffer_t *buf) { register int i = 0; int16_t *data = (int16_t*)buf->mem; // Audio data int len = buf->mem_size / 2; // Number of samples float curavg = 0.0, newavg, avg = 0.0; int tmp, totallen = 0; for (i = 0; i < len; i++) { tmp = data[i]; curavg += tmp * tmp; } curavg = sqrt(curavg / (float) len); // Evaluate an adequate 'mul' coefficient based on previous state, current // samples level, etc for (i = 0; i < NSAMPLES; i++) { avg += this->mem[i].avg * (float)this->mem[i].len; totallen += this->mem[i].len; } if (totallen > MIN_SAMPLE_SIZE) { avg /= (float)totallen; if (avg >= SIL_S16) { this->mul = MID_S16 / avg; this->mul = clamp(this->mul, MUL_MIN, MUL_MAX); } } // Scale & clamp the samples for (i = 0; i < len; i++) { tmp = this->mul * data[i]; tmp = clamp(tmp, SHRT_MIN, SHRT_MAX); data[i] = tmp; } // Evaulation of newavg (not 100% accurate because of values clamping) newavg = this->mul * curavg; // Stores computed values for future smoothing this->mem[this->idx].len = len; this->mem[this->idx].avg = newavg; this->idx = (this->idx + 1) % NSAMPLES; } static void method2_float(post_plugin_volnorm_t *this, audio_buffer_t *buf) { register int i = 0; float *data = (float*)buf->mem; // Audio data int len = buf->mem_size / 4; // Number of samples float curavg = 0.0, newavg, avg = 0.0, tmp; int totallen = 0; for (i = 0; i < len; i++) { tmp = data[i]; curavg += tmp * tmp; } curavg = sqrt(curavg / (float) len); // Evaluate an adequate 'mul' coefficient based on previous state, current // samples level, etc for (i = 0; i < NSAMPLES; i++) { avg += this->mem[i].avg * (float)this->mem[i].len; totallen += this->mem[i].len; } if (totallen > MIN_SAMPLE_SIZE) { avg /= (float)totallen; if (avg >= SIL_FLOAT) { this->mul = MID_FLOAT / avg; this->mul = clamp(this->mul, MUL_MIN, MUL_MAX); } } // Scale & clamp the samples for (i = 0; i < len; i++) data[i] *= this->mul; // Evaulation of newavg (not 100% accurate because of values clamping) newavg = this->mul * curavg; // Stores computed values for future smoothing this->mem[this->idx].len = len; this->mem[this->idx].avg = newavg; this->idx = (this->idx + 1) % NSAMPLES; } static void volnorm_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_volnorm_t *this = (post_plugin_volnorm_t *)port->post; if (this->method == 1) { if (buf->format.bits == 16) method1_int16(this, buf); else if (buf->format.bits == 32) method1_float(this, buf); } else { if (buf->format.bits == 16) method2_int16(this, buf); else if (buf->format.bits == 32) method2_float(this, buf); } port->original_port->put_buffer(port->original_port, buf, stream ); return; } static void volnorm_dispose(post_plugin_t *this_gen) { post_plugin_volnorm_t *this = (post_plugin_volnorm_t *)this_gen; if (_x_post_dispose(this_gen)) { pthread_mutex_destroy(&this->lock); free(this); } } /* plugin class functions */ static post_plugin_t *volnorm_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_volnorm_t *this = calloc(1, sizeof(post_plugin_volnorm_t)); post_in_t *input; post_out_t *output; post_audio_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !audio_target || !audio_target[0] ) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)video_target; _x_post_init(&this->post, 1, 0); pthread_mutex_init (&this->lock, NULL); this->method = 1; this->mul = MUL_INIT; this->lastavg = MID_S16; this->idx = 0; memset(this->mem, 0, sizeof(this->mem)); port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = volnorm_port_open; port->new_port.close = volnorm_port_close; port->new_port.put_buffer = volnorm_port_put_buffer; xine_list_push_back(this->post.input, (void *)¶ms_input); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = volnorm_dispose; return &this->post; } /* plugin class initialization function */ void *volnorm_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_volnorm_class = { .open_plugin = volnorm_open_plugin, .identifier = "volnorm", .description = N_("Normalize volume"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_volnorm_class; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/filter.h����������������������������������������������������������������0000644�0001750�0001750�00000005006�14647725152�015200� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*============================================================================= * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. * * Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au * *============================================================================= */ #if !defined _DSP_H # error "Never use <filter.h> directly; include <dsp.h> instead" #endif #ifndef _FILTER_H #define _FILTER_H 1 /* Design and implementation of different types of digital filters */ /* Flags used for filter design */ /* Filter characteristics */ #define LP 0x00010000 /* Low pass */ #define HP 0x00020000 /* High pass */ #define BP 0x00040000 /* Band pass */ #define BS 0x00080000 /* Band stop */ #define TYPE_MASK 0x000F0000 /* Window types */ #define BOXCAR 0x00000001 #define TRIANG 0x00000002 #define HAMMING 0x00000004 #define HANNING 0x00000008 #define BLACKMAN 0x00000010 #define FLATTOP 0x00000011 #define KAISER 0x00000012 #define WINDOW_MASK 0x0000001F /* Parallel filter design */ #define FWD 0x00000001 /* Forward indexing of polyphase filter */ #define REW 0x00000002 /* Reverse indexing of polyphase filter */ #define ODD 0x00000010 /* Make filter HP */ /* Exported functions */ extern _ftype_t fir(unsigned int n, _ftype_t* w, _ftype_t* x); extern _ftype_t* pfir(unsigned int n, unsigned int k, unsigned int xi, _ftype_t** w, _ftype_t** x, _ftype_t* y, unsigned int s); extern int updateq(unsigned int n, unsigned int xi, _ftype_t* xq, _ftype_t* in); extern int updatepq(unsigned int n, unsigned int k, unsigned int xi, _ftype_t** xq, _ftype_t* in, unsigned int s); extern int design_fir(unsigned int n, _ftype_t* w, _ftype_t* fc, unsigned int flags, _ftype_t opt); extern int design_pfir(unsigned int n, unsigned int k, _ftype_t* w, _ftype_t** pw, _ftype_t g, unsigned int flags); extern void prewarp(_ftype_t* a, _ftype_t fc, _ftype_t fs); void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef); extern int szxform(const _ftype_t* a, const _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef); /* Add new data to circular queue designed to be used with a FIR * filter. xq is the circular queue, in pointing at the new sample, xi * current index for xq and n the length of the filter. xq must be n*2 * long. */ #define updateq(n,xi,xq,in)\ xq[xi]=(xq)[(xi)+(n)]=*(in);\ xi=(++(xi))&((n)-1); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/upmix.c�����������������������������������������������������������������0000644�0001750�0001750�00000033105�14647725152�015051� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Upmix audio filter for xine. * (c) 2004 James Courtier-Dutton (James@superbug.demon.co.uk) * This is an up-mix audio filter post plugin. * It simply creates output channels to match the speaker arrangement. * E.g. Converts Stereo into Surround 5.1 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <pthread.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "dsp.h" #include "audio_filters.h" typedef struct post_plugin_upmix_s post_plugin_upmix_t; /* Q value for low-pass filter */ #define Q 1.0 /* Analog domain biquad section */ typedef struct{ float a[3]; /* Numerator coefficients */ float b[3]; /* Denominator coefficients */ } biquad_t; /* S-parameters for designing 4th order Butterworth filter */ static const biquad_t s_param[2] = {{{1.0,0.0,0.0},{1.0,0.765367,1.0}}, {{1.0,0.0,0.0},{1.0,1.847759,1.0}}}; /* Data for specific instances of this filter */ typedef struct af_sub_s { float w[2][4]; /* Filter taps for low-pass filter */ float q[2][2]; /* Circular queues */ float fc; /* Cutoff frequency [Hz] for low-pass filter */ float k; /* Filter gain */ }af_sub_t; #ifndef IIR #define IIR(in,w,q,out) { \ float h0 = (q)[0]; \ float h1 = (q)[1]; \ float hn = (in) - h0 * (w)[0] - h1 * (w)[1]; \ out = hn + h0 * (w)[2] + h1 * (w)[3]; \ (q)[1] = h0; \ (q)[0] = hn; \ } #endif typedef struct upmix_parameters_s { int cut_off_freq; } upmix_parameters_t; /* * description of params struct */ START_PARAM_DESCR( upmix_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, cut_off_freq, NULL, 0, 500, 0, "cut_off_freq" ) END_PARAM_DESCR( param_descr ) struct post_plugin_upmix_s { post_plugin_t post; /* private data */ pthread_mutex_t lock; upmix_parameters_t params; audio_buffer_t *buf; /* dummy buffer just to hold a copy of audio data */ af_sub_t *sub; int channels; int channels_out; }; /************************************************************************** * upmix parameters functions *************************************************************************/ static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_upmix_t *this = (post_plugin_upmix_t *)this_gen; const upmix_parameters_t *param = (const upmix_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( &this->params, param, sizeof(upmix_parameters_t) ); pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_upmix_t *this = (post_plugin_upmix_t *)this_gen; upmix_parameters_t *param = (upmix_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( param, &this->params, sizeof(upmix_parameters_t) ); pthread_mutex_unlock (&this->lock); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { return _("Upmix functions. e.g. Take stereo input and produce Surround 5.1 output." "\n" "Parameters\n" " cut_off_freq\n" "\n" "Note: It is possible to use frontend's control window to set " "these parameters.\n" "\n" ); } /************************************************************************** * xine audio post plugin functions *************************************************************************/ static int upmix_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_upmix_t *this = (post_plugin_upmix_t *)port->post; uint32_t capabilities; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; capabilities = port->original_port->get_capabilities(port->original_port); this->channels = _x_ao_mode2channels(mode); /* FIXME: Handle all desired output formats */ if ((capabilities & AO_CAP_MODE_5_1CHANNEL) && (capabilities & AO_CAP_FLOAT32)) { this->channels_out=6; mode = AO_CAP_MODE_5_1CHANNEL; bits = 32; /* Upmix to Floats */ } else { this->channels_out=2; } pthread_mutex_lock (&this->lock); this->sub = calloc(1, sizeof(af_sub_t)); if (!this->sub) { pthread_mutex_unlock (&this->lock); return 0; } this->sub->fc = this->params.cut_off_freq; /* LFE Cutoff frequency 100Hz */ this->sub->k = 1.0; if((-1 == szxform(s_param[0].a, s_param[0].b, Q, this->sub->fc, (float)rate, &this->sub->k, this->sub->w[0])) || (-1 == szxform(s_param[1].a, s_param[1].b, Q, this->sub->fc, (float)rate, &this->sub->k, this->sub->w[1]))) { _x_freep(&this->sub); pthread_mutex_unlock (&this->lock); return 0; } pthread_mutex_unlock (&this->lock); return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } #if 0 static void upmix_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; port->stream = NULL; port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } #endif static int upmix_frames_2to51_any_to_float( uint8_t *dst8, uint8_t *src8, int num_frames, int step_channel_in, af_sub_t *sub) { float *dst=(float *)dst8; int16_t *src16=(int16_t *)src8; float *src_float=(float *)src8; int src_num_channels=2; int dst_num_channels=6; int src_frame; int dst_frame; int32_t sample24; float sample; float left; float right; float sum; int frame; int src_units_per_sample=1; if (step_channel_in == 3) src_units_per_sample=step_channel_in; /* Special handling for 24 bit 3byte input */ for (frame=0;frame < num_frames; frame++) { dst_frame=frame*dst_num_channels; src_frame=frame*src_num_channels*src_units_per_sample; switch (step_channel_in) { case 1: left = src8[src_frame]; left = (left - 128 ) / 128; /* FIXME: Need to verify this is correct */ right = src8[src_frame+1]; right = (right - 128) / 128; break; case 2: left = (1.0/SHRT_MAX)*((float)src16[src_frame]); right = (1.0/SHRT_MAX)*((float)src16[src_frame+1]); break; case 3: #ifdef WORDS_BIGENDIAN sample24 = (src8[src_frame] << 24) | (src8[src_frame+1] << 16) | ( src8[src_frame+2] << 8); #else sample24 = (src8[src_frame] << 8) | (src8[src_frame+1] << 16) | ( src8[src_frame+2] << 24); #endif left = (1.0/INT32_MAX)*((float)sample24); #ifdef WORDS_BIGENDIAN sample24 = (src8[src_frame+3] << 24) | (src8[src_frame+4] << 16) | ( src8[src_frame+5] << 8); #else sample24 = (src8[src_frame+3] << 8) | (src8[src_frame+4] << 16) | ( src8[src_frame+5] << 24); #endif right = (1.0/INT32_MAX)*((float)sample24); break; case 4: left = src_float[src_frame]; right = src_float[src_frame+1]; break; default: left = right = 0.0; } /* Left channel */ dst[dst_frame] = left; /* Right channel */ dst[dst_frame+1] = right; /* try a bit of dolby */ /* FIXME: Dobly surround is a bit more complicated than this, but this is a start. */ /* Rear Left channel */ dst[dst_frame+2] = (left - right) / 2; /* Rear Right channel */ dst[dst_frame+3] = (left - right) / 2; sum = (left + right) / 2; /* Center channel */ /* Mute this one because it just causes the Left/Right channel spacing to get moved to the center. */ /* dst[dst_frame+4] = sum; */ dst[dst_frame+4] = 0; /* Create the LFE channel using a low pass filter */ /* filter feature ported from mplayer */ sample = sum; IIR(sample * sub->k, sub->w[0], sub->q[0], sample); IIR(sample , sub->w[1], sub->q[1], sample); /* LFE or Sub woofer channel */ dst[dst_frame+5] = sample; } return frame; } static void upmix_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_upmix_t *this = (post_plugin_upmix_t *)port->post; int src_step_frame; int dst_step_frame; int step_channel_in; int step_channel_out; uint8_t *data8src; uint8_t *data8dst; int num_bytes; int num_frames; int num_frames_done; int num_frames_processed=0; if ((this->channels==2) && (this->channels_out==6)) { while (num_frames_processed < buf->num_frames) { this->buf = port->original_port->get_buffer(port->original_port); /* this->buf->num_frames is handled after the upmix */ this->buf->vpts = buf->vpts; if (num_frames_processed != 0) this->buf->vpts = 0; this->buf->frame_header_count = buf->frame_header_count; this->buf->first_access_unit = buf->first_access_unit; /* FIXME: The audio buffer should contain this info. * We should not have to get it from the open call. */ this->buf->format.bits = 32; /* Upmix to floats */ this->buf->format.rate = port->rate; this->buf->format.mode = AO_CAP_MODE_5_1CHANNEL; _x_extra_info_merge( this->buf->extra_info, buf->extra_info); step_channel_in = port->bits>>3; step_channel_out = this->buf->format.bits>>3; dst_step_frame = this->channels_out*step_channel_out; src_step_frame = this->channels*step_channel_in; num_bytes=(buf->num_frames-num_frames_processed)*dst_step_frame; if (num_bytes > this->buf->mem_size) { num_bytes = this->buf->mem_size; } num_frames = num_bytes/dst_step_frame; data8src=(int8_t*)buf->mem; data8src+=num_frames_processed*src_step_frame; data8dst=(int8_t*)this->buf->mem; pthread_mutex_lock (&this->lock); if (this->sub->fc != this->params.cut_off_freq) { this->sub->fc = this->params.cut_off_freq; /* LFE Cutoff frequency 100Hz */ this->sub->k = 1.0; if((-1 == szxform(s_param[0].a, s_param[0].b, Q, this->sub->fc, (float)port->rate, &this->sub->k, this->sub->w[0])) || (-1 == szxform(s_param[1].a, s_param[1].b, Q, this->sub->fc, (float)port->rate, &this->sub->k, this->sub->w[1]))) { /* Complain fairly loudly! */ printf("Low pass filter init failed!\n"); } } pthread_mutex_unlock (&this->lock); num_frames_done = upmix_frames_2to51_any_to_float(data8dst, data8src, num_frames, step_channel_in, this->sub); this->buf->num_frames = num_frames_done; num_frames_processed+= num_frames_done; /* pass data to original port */ port->original_port->put_buffer(port->original_port, this->buf, stream ); } /* free data from origial buffer */ buf->num_frames=0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */ } port->original_port->put_buffer(port->original_port, buf, stream ); return; } static void upmix_dispose(post_plugin_t *this_gen) { post_plugin_upmix_t *this = (post_plugin_upmix_t *)this_gen; if (_x_post_dispose(this_gen)) { _x_freep(&this->sub); free(this); } } /* plugin class functions */ static post_plugin_t *upmix_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_upmix_t *this = calloc(1, sizeof(post_plugin_upmix_t)); post_in_t *input; post_out_t *output; post_audio_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t input_api = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; (void)class_gen; (void)inputs; (void)video_target; if (!this || !audio_target || !audio_target[0] ) { free(this); return NULL; } _x_post_init(&this->post, 1, 0); pthread_mutex_init(&this->lock, NULL); this->params.cut_off_freq = 100; port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = upmix_port_open; #if 0 port->new_port.close = upmix_port_close; #endif port->new_port.put_buffer = upmix_port_put_buffer; xine_list_push_back(this->post.input, (void *)&input_api); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = upmix_dispose; return &this->post; } /* plugin class initialization function */ void *upmix_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_upmix_class = { .open_plugin = upmix_open_plugin, .identifier = "upmix", .description = N_("upmix"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_upmix_class; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/upmix_mono.c������������������������������������������������������������0000644�0001750�0001750�00000024700�14647725152�016102� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Upmix audio filter for xine. * (c) 2004 James Courtier-Dutton (James@superbug.demon.co.uk) * This is an up-mix audio filter post plugin. * It simply converts Mono into Stereo. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <pthread.h> #define LOG_MODULE "upmix_mono" #define LOG_VERBOSE /* #define LOG */ #include <xine/xineutils.h> #include <xine/post.h> #include "audio_filters.h" typedef struct upmix_mono_parameters_s { int channel; } upmix_mono_parameters_t; /* * description of params struct */ START_PARAM_DESCR( upmix_mono_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, channel, NULL, -1, 5, 0, "Select channel to upmix (duplicate) to stereo" ) END_PARAM_DESCR( param_descr ) typedef struct post_plugin_upmix_mono_s post_plugin_upmix_mono_t; struct post_plugin_upmix_mono_s { post_plugin_t post; /* private data */ int channels; upmix_mono_parameters_t params; int params_changed; pthread_mutex_t lock; }; /************************************************************************** * upmix_mono parameters functions *************************************************************************/ static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_upmix_mono_t *this = (post_plugin_upmix_mono_t *)this_gen; const upmix_mono_parameters_t *param = (const upmix_mono_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( &this->params, param, sizeof(upmix_mono_parameters_t) ); this->params_changed = 1; pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_upmix_mono_t *this = (post_plugin_upmix_mono_t *)this_gen; upmix_mono_parameters_t *param = (upmix_mono_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( param, &this->params, sizeof(upmix_mono_parameters_t) ); pthread_mutex_unlock (&this->lock); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { return _("This filter will upmix a mono stream to stereo, by " "duplicating channels. Alternatively, one may use this " "plugin to listen just one channel of a given stream.\n" ); } /************************************************************************** * xine audio post plugin functions *************************************************************************/ static int upmix_mono_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_upmix_mono_t *this = (post_plugin_upmix_mono_t *)port->post; uint32_t capabilities; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->channels = _x_ao_mode2channels(mode); capabilities = port->original_port->get_capabilities(port->original_port); if (this->channels == 1 && (capabilities & AO_CAP_MODE_STEREO)) { xprintf(stream->xine, XINE_VERBOSITY_LOG, _(LOG_MODULE ": upmixing Mono to Stereo.\n")); mode = AO_CAP_MODE_STEREO; } else { if ( this->channels != 1) xprintf(stream->xine, XINE_VERBOSITY_LOG, ngettext(LOG_MODULE ": upmixing a single channel from original %d channel stream.\n", LOG_MODULE ": upmixing a single channel from original %d channels stream.\n", this->channels), this->channels); else { xprintf(stream->xine, XINE_VERBOSITY_LOG, _(LOG_MODULE ": audio device not capable of AO_CAP_MODE_STEREO.\n")); this->channels = 0; } } return (port->original_port->open) (port->original_port, stream, bits, rate, mode); } static void upmix_mono_port_put_buffer(xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_upmix_mono_t *this = (post_plugin_upmix_mono_t *)port->post; pthread_mutex_lock (&this->lock); if (this->channels == 1) { audio_buffer_t *buf0 = port->original_port->get_buffer(port->original_port); audio_buffer_t *buf1 = port->original_port->get_buffer(port->original_port); buf0->num_frames = buf->num_frames / 2; buf1->num_frames = buf->num_frames - (buf->num_frames / 2); buf0->vpts = buf->vpts; buf1->vpts = 0; buf0->frame_header_count = buf->frame_header_count; buf1->frame_header_count = buf->frame_header_count; buf0->first_access_unit = buf->first_access_unit; buf1->first_access_unit = buf->first_access_unit; /* FIXME: The audio buffer should contain this info. * We should not have to get it from the open call. */ buf0->format.bits = buf->format.bits; buf1->format.bits = buf->format.bits; buf0->format.rate = buf->format.rate; buf1->format.rate = buf->format.rate; buf0->format.mode = AO_CAP_MODE_STEREO; buf1->format.mode = AO_CAP_MODE_STEREO; _x_extra_info_merge(buf0->extra_info, buf->extra_info); _x_extra_info_merge(buf1->extra_info, buf->extra_info); { const size_t step = buf->format.bits / 8; uint8_t *src = (uint8_t *)buf->mem; uint8_t *dst0 = (uint8_t *)buf0->mem; uint8_t *dst1 = (uint8_t *)buf1->mem; int i; for (i = 0; i < buf->num_frames / 2; i++) { memcpy(dst0, src, step); dst0 += step; memcpy(dst0, src, step); dst0 += step; src += step; } for (i = buf->num_frames / 2; i < buf->num_frames; i++) { memcpy(dst1, src, step); dst1 += step; memcpy(dst1, src, step); dst1 += step; src += step; } } /* pass data to original port */ port->original_port->put_buffer(port->original_port, buf0, stream); port->original_port->put_buffer(port->original_port, buf1, stream); /* free data from origial buffer */ buf->num_frames = 0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */ } else if (this->channels && this->params.channel >= 0) { audio_buffer_t *buf0 = port->original_port->get_buffer(port->original_port); buf0->num_frames = buf->num_frames; buf0->vpts = buf->vpts; buf0->frame_header_count = buf->frame_header_count; buf0->first_access_unit = buf->first_access_unit; /* FIXME: The audio buffer should contain this info. * We should not have to get it from the open call. */ buf0->format.bits = buf->format.bits; buf0->format.rate = buf->format.rate; buf0->format.mode = AO_CAP_MODE_STEREO; _x_extra_info_merge(buf0->extra_info, buf->extra_info); { const size_t step = buf->format.bits / 8; uint8_t *src = (uint8_t *)buf->mem; uint8_t *dst0 = (uint8_t *)buf0->mem; int cur_channel = this->params.channel; int i, j; if( cur_channel >= this->channels ) cur_channel = this->channels-1; src += cur_channel * step; for (i = 0; i < buf->num_frames; i++) { for (j = 0; j < this->channels; j++ ) { memcpy(dst0, src, step); dst0 += step; } src += this->channels * step; } } /* pass data to original port */ port->original_port->put_buffer(port->original_port, buf0, stream); /* free data from origial buffer */ buf->num_frames = 0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */ } pthread_mutex_unlock (&this->lock); port->original_port->put_buffer(port->original_port, buf, stream); return; } static void upmix_mono_dispose(post_plugin_t *this_gen) { post_plugin_upmix_mono_t *this = (post_plugin_upmix_mono_t *)this_gen; if (_x_post_dispose(this_gen)) free(this); } /* plugin class functions */ static post_plugin_t *upmix_mono_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_upmix_mono_t *this = calloc(1, sizeof(post_plugin_upmix_mono_t)); post_in_t *input; post_out_t *output; post_audio_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; static const upmix_mono_parameters_t init_params = { .channel = -1, }; if (!this || !audio_target || !audio_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)video_target; _x_post_init(&this->post, 1, 0); pthread_mutex_init (&this->lock, NULL); set_parameters (&this->post.xine_post, &init_params); port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = upmix_mono_port_open; port->new_port.put_buffer = upmix_mono_port_put_buffer; xine_list_push_back(this->post.input, (void *)¶ms_input); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = upmix_mono_dispose; return &this->post; } /* plugin class initialization function */ void *upmix_mono_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_upmix_mono_class = { .open_plugin = upmix_mono_open_plugin, .identifier = "upmix_mono", .description = N_("converts Mono into Stereo"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_upmix_mono_class; } ����������������������������������������������������������������xine-lib-1.2/src/post/audio/filter.c����������������������������������������������������������������0000644�0001750�0001750�00000032055�14647725152�015177� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*============================================================================= * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. * * Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au * *============================================================================= */ /* Design and implementation of different types of digital filters */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <string.h> #include <math.h> #include "dsp.h" /****************************************************************************** * FIR filter implementations ******************************************************************************/ /* C implementation of FIR filter y=w*x * * n number of filter taps, where mod(n,4)==0 * w filter taps * x input signal must be a circular buffer which is indexed backwards */ inline _ftype_t fir(register unsigned int n, _ftype_t* w, _ftype_t* x) { register _ftype_t y; /* Output */ y = 0.0; do{ n--; y+=w[n]*x[n]; }while(n != 0); return y; } /* C implementation of parallel FIR filter y(k)=w(k) * x(k) (where * denotes convolution) * * n number of filter taps, where mod(n,4)==0 * d number of filters * xi current index in xq * w filter taps k by n big * x input signal must be a circular buffers which are indexed backwards * y output buffer * s output buffer stride */ inline _ftype_t* pfir(unsigned int n, unsigned int d, unsigned int xi, _ftype_t** w, _ftype_t** x, _ftype_t* y, unsigned int s) { register _ftype_t* xt = *x + xi; register _ftype_t* wt = *w; register int nt = 2*n; while(d-- > 0){ *y = fir(n,wt,xt); wt+=n; xt+=nt; y+=s; } return y; } /* Add new data to circular queue designed to be used with a parallel FIR filter, with d filters. xq is the circular queue, in pointing at the new samples, xi current index in xq and n the length of the filter. xq must be n*2 by k big, s is the index for in. */ inline int updatepq(unsigned int n, unsigned int d, unsigned int xi, _ftype_t** xq, _ftype_t* in, unsigned int s) { register _ftype_t* txq = *xq + xi; register int nt = n*2; while(d-- >0){ *txq= *(txq+n) = *in; txq+=nt; in+=s; } return (++xi)&(n-1); } /****************************************************************************** * FIR filter design ******************************************************************************/ /* Design FIR filter using the Window method n filter length must be odd for HP and BS filters w buffer for the filter taps (must be n long) fc cutoff frequencies (1 for LP and HP, 2 for BP and BS) 0 < fc < 1 where 1 <=> Fs/2 flags window and filter type as defined in filter.h variables are ored together: i.e. LP|HAMMING will give a low pass filter designed using a hamming window opt beta constant used only when designing using kaiser windows returns 0 if OK, -1 if fail */ int design_fir(unsigned int n, _ftype_t* w, _ftype_t* fc, unsigned int flags, _ftype_t opt) { unsigned int o = n & 1; /* Indicator for odd filter length */ unsigned int end = ((n + 1) >> 1) - o; /* Loop end */ unsigned int i; /* Loop index */ _ftype_t k1 = 2 * M_PI; /* 2*pi*fc1 */ _ftype_t k2 = 0.5 * (_ftype_t)(1 - o);/* Constant used if the filter has even length */ _ftype_t k3; /* 2*pi*fc2 Constant used in BP and BS design */ _ftype_t g = 0.0; /* Gain */ _ftype_t t1,t2,t3; /* Temporary variables */ _ftype_t fc1,fc2; /* Cutoff frequencies */ /* Sanity check */ if(!w || (n == 0)) return -1; /* Get window coefficients */ switch(flags & WINDOW_MASK){ case(BOXCAR): boxcar(n,w); break; case(TRIANG): triang(n,w); break; case(HAMMING): hamming(n,w); break; case(HANNING): hanning(n,w); break; case(BLACKMAN): blackman(n,w); break; case(FLATTOP): flattop(n,w); break; case(KAISER): kaiser(n,w,opt); break; default: return -1; } if(flags & (LP | HP)){ fc1=*fc; /* Cutoff frequency must be < 0.5 where 0.5 <=> Fs/2 */ fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25; k1 *= fc1; if(flags & LP){ /* Low pass filter */ /* * If the filter length is odd, there is one point which is exactly * in the middle. The value at this point is 2*fCutoff*sin(x)/x, * where x is zero. To make sure nothing strange happens, we set this * value separately. */ if (o){ w[end] = fc1 * w[end] * 2.0; g=w[end]; } /* Create filter */ for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1) - k2; w[end-i-1] = w[n-end+i] = w[end-i-1] * sin(k1 * t1)/(M_PI * t1); /* Sinc */ g += 2*w[end-i-1]; /* Total gain in filter */ } } else{ /* High pass filter */ if (!o) /* High pass filters must have odd length */ return -1; w[end] = 1.0 - (fc1 * w[end] * 2.0); g= w[end]; /* Create filter */ for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1); w[end-i-1] = w[n-end+i] = -1 * w[end-i-1] * sin(k1 * t1)/(M_PI * t1); /* Sinc */ g += ((i&1) ? (2*w[end-i-1]) : (-2*w[end-i-1])); /* Total gain in filter */ } } } if(flags & (BP | BS)){ fc1=fc[0]; fc2=fc[1]; /* Cutoff frequencies must be < 1.0 where 1.0 <=> Fs/2 */ fc1 = ((fc1 <= 1.0) && (fc1 > 0.0)) ? fc1/2 : 0.25; fc2 = ((fc2 <= 1.0) && (fc2 > 0.0)) ? fc2/2 : 0.25; k3 = k1 * fc2; /* 2*pi*fc2 */ k1 *= fc1; /* 2*pi*fc1 */ if(flags & BP){ /* Band pass */ /* Calculate center tap */ if (o){ g=w[end]*(fc1+fc2); w[end] = (fc2 - fc1) * w[end] * 2.0; } /* Create filter */ for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1) - k2; t2 = sin(k3 * t1)/(M_PI * t1); /* Sinc fc2 */ t3 = sin(k1 * t1)/(M_PI * t1); /* Sinc fc1 */ g += w[end-i-1] * (t3 + t2); /* Total gain in filter */ w[end-i-1] = w[n-end+i] = w[end-i-1] * (t2 - t3); } } else{ /* Band stop */ if (!o) /* Band stop filters must have odd length */ return -1; w[end] = 1.0 - (fc2 - fc1) * w[end] * 2.0; g= w[end]; /* Create filter */ for (i=0 ; i<end ; i++){ t1 = (_ftype_t)(i+1); t2 = sin(k1 * t1)/(M_PI * t1); /* Sinc fc1 */ t3 = sin(k3 * t1)/(M_PI * t1); /* Sinc fc2 */ w[end-i-1] = w[n-end+i] = w[end-i-1] * (t2 - t3); g += 2*w[end-i-1]; /* Total gain in filter */ } } } /* Normalize gain */ g=1/g; for (i=0; i<n; i++) w[i] *= g; return 0; } /* Design polyphase FIR filter from prototype filter * * n length of prototype filter * k number of polyphase components * w prototype filter taps * pw Parallel FIR filter * g Filter gain * flags FWD forward indexing * REW reverse indexing * ODD multiply every 2nd filter tap by -1 => HP filter * * returns 0 if OK, -1 if fail */ int design_pfir(unsigned int n, unsigned int k, _ftype_t* w, _ftype_t** pw, _ftype_t g, unsigned int flags) { int l = (int)n/k; /* Length of individual FIR filters */ int i; /* Counters */ int j; _ftype_t t; /* g * w[i] */ /* Sanity check */ if(l<1 || k<1 || !w || !pw) return -1; /* Do the stuff */ if(flags&REW){ for(j=l-1;j>-1;j--){ /* Columns */ for(i=0;i<(int)k;i++){ /* Rows */ t=g * *w++; pw[i][j]=t * ((flags & ODD) ? ((j & 1) ? -1 : 1) : 1); } } } else{ for(j=0;j<l;j++){ /* Columns */ for(i=0;i<(int)k;i++){ /* Rows */ t=g * *w++; pw[i][j]=t * ((flags & ODD) ? ((j & 1) ? 1 : -1) : 1); } } } return -1; } /****************************************************************************** * IIR filter design ******************************************************************************/ /* Helper functions for the bilinear transform */ /* Pre-warp the coefficients of a numerator or denominator. * Note that a0 is assumed to be 1, so there is no wrapping * of it. */ void prewarp(_ftype_t* a, _ftype_t fc, _ftype_t fs) { _ftype_t wp; wp = 2.0 * fs * tan(M_PI * fc / fs); a[2] = a[2]/(wp * wp); a[1] = a[1]/wp; } /* Transform the numerator and denominator coefficients of s-domain * biquad section into corresponding z-domain coefficients. * * The transfer function for z-domain is: * * 1 + alpha1 * z^(-1) + alpha2 * z^(-2) * H(z) = ------------------------------------- * 1 + beta1 * z^(-1) + beta2 * z^(-2) * * Store the 4 IIR coefficients in array pointed by coef in following * order: * beta1, beta2 (denominator) * alpha1, alpha2 (numerator) * * Arguments: * a - s-domain numerator coefficients * b - s-domain denominator coefficients * k - filter gain factor. Initially set to 1 and modified by each * biquad section in such a way, as to make it the * coefficient by which to multiply the overall filter gain * in order to achieve a desired overall filter gain, * specified in initial value of k. * fs - sampling rate (Hz) * coef - array of z-domain coefficients to be filled in. * * Return: On return, set coef z-domain coefficients and k to the gain * required to maintain overall gain = 1.0; */ void bilinear(_ftype_t* a, _ftype_t* b, _ftype_t* k, _ftype_t fs, _ftype_t *coef) { _ftype_t ad, bd; /* alpha (Numerator in s-domain) */ ad = 4. * a[2] * fs * fs + 2. * a[1] * fs + a[0]; /* beta (Denominator in s-domain) */ bd = 4. * b[2] * fs * fs + 2. * b[1] * fs + b[0]; /* Update gain constant for this section */ *k *= ad/bd; /* Denominator */ *coef++ = (2. * b[0] - 8. * b[2] * fs * fs)/bd; /* beta1 */ *coef++ = (4. * b[2] * fs * fs - 2. * b[1] * fs + b[0])/bd; /* beta2 */ /* Numerator */ *coef++ = (2. * a[0] - 8. * a[2] * fs * fs)/ad; /* alpha1 */ *coef = (4. * a[2] * fs * fs - 2. * a[1] * fs + a[0])/ad; /* alpha2 */ } /* IIR filter design using bilinear transform and prewarp. Transforms * 2nd order s domain analog filter into a digital IIR biquad link. To * create a filter fill in a, b, Q and fs and make space for coef and k. * * * Example Butterworth design: * * Below are Butterworth polynomials, arranged as a series of 2nd * order sections: * * Note: n is filter order. * * n Polynomials * ------------------------------------------------------------------- * 2 s^2 + 1.4142s + 1 * 4 (s^2 + 0.765367s + 1) * (s^2 + 1.847759s + 1) * 6 (s^2 + 0.5176387s + 1) * (s^2 + 1.414214 + 1) * (s^2 + 1.931852s + 1) * * For n=4 we have following equation for the filter transfer function: * 1 1 * T(s) = --------------------------- * ---------------------------- * s^2 + (1/Q) * 0.765367s + 1 s^2 + (1/Q) * 1.847759s + 1 * * The filter consists of two 2nd order sections since highest s power * is 2. Now we can take the coefficients, or the numbers by which s * is multiplied and plug them into a standard formula to be used by * bilinear transform. * * Our standard form for each 2nd order section is: * * a2 * s^2 + a1 * s + a0 * H(s) = ---------------------- * b2 * s^2 + b1 * s + b0 * * Note that Butterworth numerator is 1 for all filter sections, which * means s^2 = 0 and s^1 = 0 * * Let's convert standard Butterworth polynomials into this form: * * 0 + 0 + 1 0 + 0 + 1 * --------------------------- * -------------------------- * 1 + ((1/Q) * 0.765367) + 1 1 + ((1/Q) * 1.847759) + 1 * * Section 1: * a2 = 0; a1 = 0; a0 = 1; * b2 = 1; b1 = 0.765367; b0 = 1; * * Section 2: * a2 = 0; a1 = 0; a0 = 1; * b2 = 1; b1 = 1.847759; b0 = 1; * * Q is filter quality factor or resonance, in the range of 1 to * 1000. The overall filter Q is a product of all 2nd order stages. * For example, the 6th order filter (3 stages, or biquads) with * individual Q of 2 will have filter Q = 2 * 2 * 2 = 8. * * * Arguments: * a - s-domain numerator coefficients, a[1] is always assumed to be 1.0 * b - s-domain denominator coefficients * Q - Q value for the filter * k - filter gain factor. Initially set to 1 and modified by each * biquad section in such a way, as to make it the * coefficient by which to multiply the overall filter gain * in order to achieve a desired overall filter gain, * specified in initial value of k. * fs - sampling rate (Hz) * coef - array of z-domain coefficients to be filled in. * * Note: Upon return from each call, the k argument will be set to a * value, by which to multiply our actual signal in order for the gain * to be one. On second call to szxform() we provide k that was * changed by the previous section. During actual audio filtering * k can be used for gain compensation. * * return -1 if fail 0 if success. */ int szxform(const _ftype_t* a, const _ftype_t* b, _ftype_t Q, _ftype_t fc, _ftype_t fs, _ftype_t *k, _ftype_t *coef) { _ftype_t at[3]; _ftype_t bt[3]; if(!a || !b || !k || !coef || (Q>1000.0 || Q< 1.0)) return -1; memcpy(at,a,3*sizeof(_ftype_t)); memcpy(bt,b,3*sizeof(_ftype_t)); bt[1]/=Q; /* Calculate a and b and overwrite the original values */ prewarp(at, fc, fs); prewarp(bt, fc, fs); /* Execute bilinear transform */ bilinear(at, bt, k, fs, coef); return 0; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/stretch.c���������������������������������������������������������������0000644�0001750�0001750�00000047555�14647725152�015401� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Time stretch by a given factor, optionally preserving pitch */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <pthread.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "dsp.h" #include <xine/resample.h> #include "audio_filters.h" #define AUDIO_FRAGMENT 120/1000 /* ms of audio */ #define CLIP_INT16(s) ((s) < INT16_MIN) ? INT16_MIN : \ (((s) > INT16_MAX) ? INT16_MAX : (s)) /* * *************************************************** * stretchable unix System Clock Reference * use stretch factor to calculate speed * *************************************************** */ struct stretchscr_s { scr_plugin_t scr; struct timeval cur_time; int64_t cur_pts; int xine_speed; double speed_factor; double *stretch_factor; pthread_mutex_t lock; }; typedef struct stretchscr_s stretchscr_t; static int stretchscr_get_priority (scr_plugin_t *scr) { (void)scr; return 10; /* high priority */ } /* Only call this when already mutex locked */ static void stretchscr_set_pivot (stretchscr_t *this) { struct timeval tv; int64_t pts; double pts_calc; xine_monotonic_clock(&tv, NULL); pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; /* This next part introduces a one off inaccuracy * to the scr due to rounding tv to pts. */ this->cur_time.tv_sec=tv.tv_sec; this->cur_time.tv_usec=tv.tv_usec; this->cur_pts=pts; return ; } static int stretchscr_set_speed (scr_plugin_t *scr, int speed) { stretchscr_t *this = (stretchscr_t*) scr; pthread_mutex_lock (&this->lock); stretchscr_set_pivot( this ); this->xine_speed = speed; this->speed_factor = (double) speed * 90000.0 / XINE_FINE_SPEED_NORMAL / (*this->stretch_factor); pthread_mutex_unlock (&this->lock); return speed; } static void stretchscr_adjust (scr_plugin_t *scr, int64_t vpts) { stretchscr_t *this = (stretchscr_t*) scr; struct timeval tv; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&tv, NULL); this->cur_time.tv_sec=tv.tv_sec; this->cur_time.tv_usec=tv.tv_usec; this->cur_pts = vpts; pthread_mutex_unlock (&this->lock); } static void stretchscr_start (scr_plugin_t *scr, int64_t start_vpts) { stretchscr_t *this = (stretchscr_t*) scr; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&this->cur_time, NULL); this->cur_pts = start_vpts; pthread_mutex_unlock (&this->lock); stretchscr_set_speed (&this->scr, XINE_FINE_SPEED_NORMAL); } static int64_t stretchscr_get_current (scr_plugin_t *scr) { stretchscr_t *this = (stretchscr_t*) scr; struct timeval tv; int64_t pts; double pts_calc; pthread_mutex_lock (&this->lock); xine_monotonic_clock(&tv, NULL); pts_calc = (tv.tv_sec - this->cur_time.tv_sec) * this->speed_factor; pts_calc += (tv.tv_usec - this->cur_time.tv_usec) * this->speed_factor / 1e6; pts = this->cur_pts + pts_calc; pthread_mutex_unlock (&this->lock); return pts; } static void stretchscr_exit (scr_plugin_t *scr) { stretchscr_t *this = (stretchscr_t*) scr; pthread_mutex_destroy (&this->lock); free(this); } static stretchscr_t *XINE_MALLOC stretchscr_init (double *stretch_factor) { stretchscr_t *this; this = calloc(1, sizeof(stretchscr_t)); if (!this) { return NULL; } this->scr.interface_version = 3; this->scr.get_priority = stretchscr_get_priority; this->scr.set_fine_speed = stretchscr_set_speed; this->scr.adjust = stretchscr_adjust; this->scr.start = stretchscr_start; this->scr.get_current = stretchscr_get_current; this->scr.exit = stretchscr_exit; pthread_mutex_init (&this->lock, NULL); this->stretch_factor = stretch_factor; stretchscr_set_speed (&this->scr, XINE_SPEED_PAUSE); return this; } /*****************************************************/ typedef struct post_plugin_stretch_s post_plugin_stretch_t; typedef struct stretch_parameters_s { int preserve_pitch; double factor; } stretch_parameters_t; /* * description of params struct */ START_PARAM_DESCR( stretch_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_BOOL, preserve_pitch, NULL, 0, 1, 0, "Preserve pitch" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, factor, NULL, 0.5, 1.5, 0, "Time stretch factor (<1.0 shorten duration)" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_stretch_s { post_plugin_t post; stretchscr_t* scr; /* private data */ stretch_parameters_t params; int params_changed; int channels; int bytes_per_frame; int16_t *audiofrag; /* audio fragment to work on */ int16_t *outfrag; /* processed audio fragment */ _ftype_t *w; int frames_per_frag; int frames_per_outfrag; int num_frames; /* current # of frames on audiofrag */ int16_t last_sample[RESAMPLE_MAX_CHANNELS]; int64_t pts; /* pts for audiofrag */ pthread_mutex_t lock; }; /************************************************************************** * stretch parameters functions *************************************************************************/ static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen; const stretch_parameters_t *param = (const stretch_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( &this->params, param, sizeof(stretch_parameters_t) ); this->params_changed = 1; pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen; stretch_parameters_t *param = (stretch_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( param, &this->params, sizeof(stretch_parameters_t) ); pthread_mutex_unlock (&this->lock); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { return _("This filter will perform a time stretch, playing the " "stream faster or slower by a factor. Pitch is optionally " "preserved, so it is possible, for example, to use it to " "watch a movie in less time than it was originally shot.\n" ); } /************************************************************************** * xine audio post plugin functions *************************************************************************/ static int stretch_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; int64_t time; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; /* register our own scr provider */ time = port->stream->xine->clock->get_current_time(port->stream->xine->clock); this->scr = stretchscr_init(&this->params.factor); if (this->scr) { this->scr->scr.start(&this->scr->scr, time); port->stream->xine->clock->register_scr(port->stream->xine->clock, &this->scr->scr); } /* force updating on stretch_port_put_buffer */ this->params_changed = 1; return (port->original_port->open) (port->original_port, stream, bits, rate, mode); } static void stretch_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; if (this->scr) { port->stream->xine->clock->unregister_scr(port->stream->xine->clock, &this->scr->scr); this->scr->scr.exit(&this->scr->scr); } _x_freep(&this->audiofrag); _x_freep(&this->outfrag); _x_freep(&this->w); port->stream = NULL; port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } static void stretch_process_fragment( post_audio_port_t *port, xine_stream_t *stream, extra_info_t *extra_info ) { post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; audio_buffer_t *outbuf; int16_t *data_out = this->outfrag; int num_frames_in = this->num_frames; int num_frames_out = this->num_frames * this->frames_per_outfrag / this->frames_per_frag; if( !this->params.preserve_pitch ) { if( this->channels == 2 ) _x_audio_out_resample_stereo(this->last_sample, this->audiofrag, num_frames_in, this->outfrag, num_frames_out); else if( this->channels == 1 ) _x_audio_out_resample_mono(this->last_sample, this->audiofrag, num_frames_in, this->outfrag, num_frames_out); } else { if (this->channels == 2) memcpy (this->last_sample, &this->audiofrag[(num_frames_in - 1) * 2], 2 * sizeof (this->last_sample[0])); else if (this->channels == 1) memcpy (this->last_sample, &this->audiofrag[num_frames_in - 1], sizeof (this->last_sample[0])); if( num_frames_in > num_frames_out ) { /* * time compressing strategy * * input chunk has two halves, A and B. * output chunk is composed as follow: * - some frames copied directly from A * - some frames copied from A merged with frames from B * weighted by an increasing factor (0 -> 1.0) * - frames from A weighted by a decreasing factor (1.0 -> 0) * merged with frames copied from B * - some frames copied directly from B */ int merge_frames = num_frames_in - num_frames_out; int copy_frames; int16_t *src = this->audiofrag; int16_t *dst = this->outfrag; int i, j; if( merge_frames > num_frames_out ) merge_frames = num_frames_out; copy_frames = num_frames_out - merge_frames; memcpy(dst, src, copy_frames/2 * this->bytes_per_frame); dst += copy_frames/2 * this->channels; src += copy_frames/2 * this->channels; for( i = 0; i < merge_frames/2; i++ ) { for( j = 0; j < this->channels; j++, src++, dst++ ) { int32_t s = (int32_t) ((_ftype_t) src[0] + src[merge_frames * this->channels] * this->w[i]); *dst = CLIP_INT16(s); } } for( ; i < merge_frames; i++ ) { for( j = 0; j < this->channels; j++, src++, dst++ ) { int32_t s = (int32_t) ((_ftype_t) src[0] * this->w[i] + src[merge_frames * this->channels]); *dst = CLIP_INT16(s); } } src += merge_frames * this->channels; memcpy(dst, src, (copy_frames - copy_frames/2) * this->bytes_per_frame); } else { /* * time expansion strategy * * output chunk is composed of two versions of the * input chunk: * - first part copied directly from input, and then * merged with the second (delayed) part using a * decreasing factor (1.0 -> 0) * - the delayed version of the input is merged with * an increasing factor (0 -> 1.0) and then (when * factor reaches 1.0) just copied until the end. */ int merge_frames = num_frames_out - num_frames_in; int copy_frames = num_frames_out - merge_frames; int16_t *src1 = this->audiofrag; int16_t *src2; int16_t *dst = this->outfrag; int i, j; memcpy(dst, src1, copy_frames/2 * this->bytes_per_frame); dst += copy_frames/2 * this->channels; src1 += copy_frames/2 * this->channels; src2 = src1 - merge_frames * this->channels; for( i = 0; i < merge_frames/2; i++ ) { for( j = 0; j < this->channels; j++, src1++, src2++, dst++ ) { int32_t s = (int32_t) ((_ftype_t) *src1 + *src2 * this->w[i]); *dst = CLIP_INT16(s); } } for( ; i < merge_frames; i++ ) { for( j = 0; j < this->channels; j++, src1++, src2++, dst++ ) { int32_t s = (int32_t) ((_ftype_t) *src1 * this->w[i] + *src2); *dst = CLIP_INT16(s); } } memcpy(dst, src2, (copy_frames - copy_frames/2) * this->bytes_per_frame); } } /* copy processed fragment into multiple audio buffers, if needed */ while( num_frames_out ) { outbuf = port->original_port->get_buffer(port->original_port); outbuf->num_frames = outbuf->mem_size / this->bytes_per_frame; if( outbuf->num_frames > num_frames_out ) outbuf->num_frames = num_frames_out; memcpy( outbuf->mem, data_out, outbuf->num_frames * this->bytes_per_frame ); num_frames_out -= outbuf->num_frames; data_out = (uint16_t *)((uint8_t *)data_out + outbuf->num_frames * this->bytes_per_frame); outbuf->vpts = this->pts; this->pts = 0; outbuf->stream = stream; outbuf->format.bits = port->bits; outbuf->format.rate = port->rate; outbuf->format.mode = port->mode; _x_extra_info_merge( outbuf->extra_info, extra_info ); port->original_port->put_buffer(port->original_port, outbuf, stream ); } this->num_frames = 0; } static void stretch_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_stretch_t *this = (post_plugin_stretch_t *)port->post; int16_t *data_in; pthread_mutex_lock (&this->lock); if( this->params_changed ) { int64_t audio_step; if( this->num_frames && this->audiofrag && this->outfrag ) { /* output whatever we have before changing parameters */ stretch_process_fragment( port, stream, buf->extra_info ); } this->channels = _x_ao_mode2channels(port->mode); this->bytes_per_frame = port->bits / 8 * this->channels; audio_step = ((int64_t)90000 * (int64_t)32768) / (int64_t)port->rate; audio_step = (int64_t) ((double)audio_step / this->params.factor); stream->metronom->set_audio_rate(stream->metronom, audio_step); stretchscr_set_speed(&this->scr->scr, this->scr->xine_speed); if(this->audiofrag) { free(this->audiofrag); this->audiofrag = NULL; } if(this->outfrag) { free(this->outfrag); this->outfrag = NULL; } if(this->w) { free(this->w); this->w = NULL; } this->frames_per_frag = port->rate * AUDIO_FRAGMENT; this->frames_per_outfrag = (int) ((double)this->params.factor * this->frames_per_frag); if( this->frames_per_frag != this->frames_per_outfrag ) { int wsize; this->audiofrag = malloc( this->frames_per_frag * this->bytes_per_frame ); this->outfrag = malloc( this->frames_per_outfrag * this->bytes_per_frame ); if( this->frames_per_frag > this->frames_per_outfrag ) wsize = this->frames_per_frag - this->frames_per_outfrag; else wsize = this->frames_per_outfrag - this->frames_per_frag; this->w = (_ftype_t*) malloc( wsize * sizeof(_ftype_t) ); triang(wsize, this->w); } this->num_frames = 0; this->pts = 0; this->params_changed = 0; } pthread_mutex_unlock (&this->lock); /* just pass data through if we have nothing to do */ if( this->frames_per_frag == this->frames_per_outfrag || /* FIXME: we only handle 1 or 2 channels, 16 bits for now */ (this->channels != 1 && this->channels != 2) || port->bits != 16 ) { port->original_port->put_buffer(port->original_port, buf, stream ); return; } /* update pts for our current audio fragment */ if( buf->vpts ) this->pts = buf->vpts - (this->num_frames * 90000 / port->rate); data_in = buf->mem; while( buf->num_frames ) { int frames_to_copy = this->frames_per_frag - this->num_frames; if( frames_to_copy > buf->num_frames ) frames_to_copy = buf->num_frames; /* copy up to one fragment from input buf to our buffer */ memcpy( (uint8_t *)this->audiofrag + this->num_frames * this->bytes_per_frame, data_in, frames_to_copy * this->bytes_per_frame ); data_in = (uint16_t *)((uint8_t *)data_in + frames_to_copy * this->bytes_per_frame); this->num_frames += frames_to_copy; buf->num_frames -= frames_to_copy; /* check if we have a complete audio fragment to process */ if( this->num_frames == this->frames_per_frag ) { stretch_process_fragment( port, stream, buf->extra_info ); } } buf->num_frames=0; /* UNDOCUMENTED, but hey, it works! Force old audio_out buffer free. */ port->original_port->put_buffer(port->original_port, buf, stream ); return; } static void stretch_dispose(post_plugin_t *this_gen) { post_plugin_stretch_t *this = (post_plugin_stretch_t *)this_gen; if (_x_post_dispose(this_gen)) { free(this); } } /* plugin class functions */ static post_plugin_t *stretch_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_stretch_t *this = calloc(1, sizeof(post_plugin_stretch_t)); post_in_t *input; post_out_t *output; post_audio_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; static const stretch_parameters_t init_params = { .preserve_pitch = 1, .factor = 0.80, }; (void)class_gen; (void)inputs; (void)video_target; if (!this || !audio_target || !audio_target[0] ) { free(this); return NULL; } _x_post_init(&this->post, 1, 0); pthread_mutex_init (&this->lock, NULL); set_parameters (&this->post.xine_post, &init_params); port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = stretch_port_open; port->new_port.close = stretch_port_close; port->new_port.put_buffer = stretch_port_put_buffer; xine_list_push_back(this->post.input, (void*)¶ms_input); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = stretch_dispose; return &this->post; } /* plugin class initialization function */ void *stretch_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_scretch_class = { .open_plugin = stretch_open_plugin, .identifier = "stretch", .description = N_("Time stretch by a given factor, optionally preserving pitch"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_scretch_class; } ���������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/window.h����������������������������������������������������������������0000644�0001750�0001750�00000002120�14647725152�015214� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*============================================================================= * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. * * Copyright 2001 Anders Johansson ajh@atri.curtin.edu.au * *============================================================================= */ /* Calculates a number of window functions. The following window * functions are currently implemented: Boxcar, Triang, Hanning, * Hamming, Blackman, Flattop and Kaiser. In the function call n is * the number of filter taps and w the buffer in which the filter * coefficients will be stored. */ #if !defined _DSP_H # error "Never use <window.h> directly; include <dsp.h> instead" #endif #ifndef _WINDOW_H #define _WINDOW_H 1 extern void boxcar(int n, _ftype_t* w); extern void triang(int n, _ftype_t* w); extern void hanning(int n, _ftype_t* w); extern void hamming(int n,_ftype_t* w); extern void blackman(int n,_ftype_t* w); extern void flattop(int n,_ftype_t* w); extern void kaiser(int n, _ftype_t* w,_ftype_t b); #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/audio_filters.c���������������������������������������������������������0000644�0001750�0001750�00000003267�14647725152�016546� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * catalog for audio filter plugins */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "audio_filters.h" static const post_info_t gen_special_info = { .type = XINE_POST_TYPE_AUDIO_FILTER, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST, 10, "upmix", XINE_VERSION_CODE, &gen_special_info, &upmix_init_plugin }, { PLUGIN_POST, 10, "upmix_mono", XINE_VERSION_CODE, &gen_special_info, &upmix_mono_init_plugin }, { PLUGIN_POST, 10, "stretch", XINE_VERSION_CODE, &gen_special_info, &stretch_init_plugin }, { PLUGIN_POST, 10, "volnorm", XINE_VERSION_CODE, &gen_special_info, &volnorm_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/audio/dsp.h�������������������������������������������������������������������0000644�0001750�0001750�00000001075�14647725152�014503� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*============================================================================= * * This software has been released under the terms of the GNU Public * license. See http://www.gnu.org/copyleft/gpl.html for details. * * Copyright 2002 Anders Johansson ajh@atri.curtin.edu.au * *============================================================================= */ #ifndef _DSP_H #define _DSP_H 1 /* Implementation of routines used for DSP */ /* Size of floating point type used in routines */ #define _ftype_t float #include "window.h" #include "filter.h" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013715� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/x86/�������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014342� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/x86/noise.h������������������������������������������������������������0000644�0001750�0001750�00000002322�14647725152�015627� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's noise filter, ported by Jason Tackaberry. Original filter * is copyright 2002 Michael Niedermayer <michaelni@gmx.at> */ #include <stdint.h> void lineNoise_MMX(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift); void lineNoise_MMX2(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift); void lineNoiseAvg_MMX(uint8_t *dst, const uint8_t *src, int len, int8_t **shift); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/x86/noise.c������������������������������������������������������������0000644�0001750�0001750�00000011116�14647725152�015623� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's noise filter, ported by Jason Tackaberry. Original filter * is copyright 2002 Michael Niedermayer <michaelni@gmx.at> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "noise.h" #ifndef ARCH_X86 #error this file is X86 only #endif #if defined(ARCH_X86_64) # define TYPEA int64_t # define REGA "%rax" # define MOVA(val) "\n\tmovq\t"val", %%rax" # define MEMA(reg) "(%"reg", %%rax)" # define ADDA(val) "\n\taddq\t"val", %%rax" #elif defined(ARCH_X86_X32) # define TYPEA int64_t # define REGA "%rax" # define MOVA(val) "\n\tmovq\t"val", %%rax" # define MEMA(reg) "(%q"reg", %%rax)" # define ADDA(val) "\n\taddq\t"val", %%rax" #else # define TYPEA int32_t # define REGA "%eax" # define MOVA(val) "\n\tmovl\t"val", %%eax" # define MEMA(reg) "(%"reg", %%eax)" # define ADDA(val) "\n\taddl\t"val", %%eax" #endif static inline int saturate(int v, int min, int max) { if (v > max) return max; if (v < min) return min; return v; } void lineNoise_MMX(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift) { TYPEA mmx_len = len & (~7); noise += shift; src += mmx_len; dst += mmx_len; noise += mmx_len; __asm__ __volatile__ ( MOVA("%3") "\n\tpcmpeqb\t%%mm7, %%mm7" "\n\tpsllw\t$15, %%mm7" "\n\tpacksswb\t%%mm7, %%mm7" "\n\t"ASMALIGN(4) "\n1:" "\n\tmovq\t"MEMA("0")", %%mm0" "\n\tmovq\t"MEMA("1")", %%mm1" "\n\tpxor\t%%mm7, %%mm0" "\n\tpaddsb\t%%mm1, %%mm0" "\n\tpxor\t%%mm7, %%mm0" "\n\tmovq\t%%mm0, "MEMA("2") ADDA("$8") "\n\tjs\t1b" :: "r" (src), "r" (noise), "r" (dst), "g" (-mmx_len) : REGA ); if (mmx_len != len) { int i; for (i = 0; i < (len & 7); i++) { dst[i] = saturate(src[i] + noise[i], 0, 255); } } } //duplicate of previous except movntq void lineNoise_MMX2(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift) { TYPEA mmx_len = len & (~7); noise += shift; src += mmx_len; dst += mmx_len; noise += mmx_len; __asm__ __volatile__ ( MOVA("%3") "\n\tpcmpeqb\t%%mm7, %%mm7" "\n\tpsllw\t$15, %%mm7" "\n\tpacksswb\t%%mm7, %%mm7" "\n\t"ASMALIGN(4) "\n1:" "\n\tmovq\t"MEMA("0")", %%mm0" "\n\tmovq\t"MEMA("1")", %%mm1" "\n\tpxor\t%%mm7, %%mm0" "\n\tpaddsb\t%%mm1, %%mm0" "\n\tpxor\t%%mm7, %%mm0" "\n\tmovntq\t%%mm0, "MEMA("2") ADDA("$8") "\n\tjs\t1b" :: "r" (src), "r" (noise), "r" (dst), "g" (-mmx_len) : REGA ); if (mmx_len != len) { int i; for (i = 0; i < (len & 7); i++) { dst[i] = saturate(src[i] + noise[i], 0, 255); } } } void lineNoiseAvg_MMX(uint8_t *dst, const uint8_t *src, int len, int8_t **shift) { TYPEA mmx_len = len & (~7); __asm__ __volatile__ ( MOVA("%5") "\n\t"ASMALIGN(4) "\n1:" "\n\tmovq\t"MEMA("1")", %%mm1" "\n\tmovq\t"MEMA("0")", %%mm0" "\n\tpaddb\t"MEMA("2")", %%mm1" "\n\tpaddb\t"MEMA("3")", %%mm1" "\n\tmovq\t%%mm0, %%mm2" "\n\tmovq\t%%mm1, %%mm3" "\n\tpunpcklbw\t%%mm0, %%mm0" "\n\tpunpckhbw\t%%mm2, %%mm2" "\n\tpunpcklbw\t%%mm1, %%mm1" "\n\tpunpckhbw\t%%mm3, %%mm3" "\n\tpmulhw\t%%mm0, %%mm1" "\n\tpmulhw\t%%mm2, %%mm3" "\n\tpaddw\t%%mm1, %%mm1" "\n\tpaddw\t%%mm3, %%mm3" "\n\tpaddw\t%%mm0, %%mm1" "\n\tpaddw\t%%mm2, %%mm3" "\n\tpsrlw\t$8, %%mm1" "\n\tpsrlw\t$8, %%mm3" "\n\tpackuswb\t%%mm3, %%mm1" "\n\tmovq\t%%mm1, "MEMA("4") ADDA("$8") "\n\tjs\t1b" :: "r" (src + mmx_len), "r" (shift[0] + mmx_len), "r" (shift[1] + mmx_len), "r" (shift[2] + mmx_len), "r" (dst + mmx_len), "g" (-mmx_len) : REGA ); if (mmx_len != len) { const int8_t *src2 = (const int8_t*)src; int i; for (i = mmx_len; i < len; i++) { const int n = shift[0][i] + shift[1][i] + shift[2][i]; dst[i] = src2[i] + ((n * src2[i]) >> 7); } } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/expand.c���������������������������������������������������������������0000644�0001750�0001750�00000033712�14647725152�015346� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2003-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * $Id: * * expand video filter by James Stembridge 24/05/2003 * improved by Michael Roitzsch * centre_crop_out_mode by Reinhard Nissl * * based on invert.c * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> /* The expand trick explained: * * The expand plugin is meant to take frames of arbitrary aspect ratio and * converts them to 4:3 aspect by adding black bars on the top and bottom * of the frame. This allows us to shift overlays down into the black area * so they don't cover the image. * * How do we do that? The naive approach would be to intercept the frame's * draw() function and simply copy the frame's content into a larger one. * This is quite CPU intensive because of the huge memcpy()s involved. * * Therefore the better idea is to trick the decoder into rendering the * image into a frame with pre-attached black borders. This is the way: * - when the decoder asks for a new frame, we allocate an enlarged * frame from the original port and prepare it with black borders * - we modify this frame's base pointers so that the decoder will only see * the area between the black bars * - this frame is given to the decoder, which paints its image inside * - when the decoder draws the frame, the post plugin architecture * will automatically restore the old pointers * This way, the decoder (or any other post plugin up the tree) will only * see the frame area between the black bars and by that modify the * enlarged version directly. No need for later copying. * * When centre_crop_out_mode is enabled, the plugin will detect the black * bars to the left and right of the image and will then set up cropping * to efficiently remove the black border around the 4:3 image, which the * plugin would produce otherwise for this case. */ /* plugin structures */ typedef struct expand_parameters_s { int enable_automatic_shift; int overlay_y_offset; double aspect; int centre_cut_out_mode; } expand_parameters_t; START_PARAM_DESCR(expand_parameters_t) PARAM_ITEM(POST_PARAM_TYPE_BOOL, enable_automatic_shift, NULL, 0, 1, 0, "enable automatic overlay shifting") PARAM_ITEM(POST_PARAM_TYPE_INT, overlay_y_offset, NULL, -500, 500, 0, "manually shift the overlay vertically") PARAM_ITEM(POST_PARAM_TYPE_DOUBLE, aspect, NULL, 1.0, 3.5, 0, "target aspect ratio") PARAM_ITEM(POST_PARAM_TYPE_BOOL, centre_cut_out_mode, NULL, 0, 1, 0, "cut out centred 4:3 image contained in 16:9 frame") END_PARAM_DESCR(expand_param_descr) typedef struct post_expand_s { post_plugin_t post; int enable_automatic_shift; int overlay_y_offset; double aspect; int top_bar_height; int centre_cut_out_mode; int cropping_active; } post_expand_t; static void expand_dispose(post_plugin_t *this_gen) { post_expand_t *this = (post_expand_t *)this_gen; if (_x_post_dispose(this_gen)) free(this); } static xine_post_api_descr_t *expand_get_param_descr(void) { return &expand_param_descr; } static int expand_set_parameters(xine_post_t *this_gen, const void *param_gen) { post_expand_t *this = (post_expand_t *)this_gen; const expand_parameters_t *param = (const expand_parameters_t *)param_gen; this->enable_automatic_shift = param->enable_automatic_shift; this->overlay_y_offset = param->overlay_y_offset; this->aspect = param->aspect; this->centre_cut_out_mode = param->centre_cut_out_mode; return 1; } static int expand_get_parameters(xine_post_t *this_gen, void *param_gen) { post_expand_t *this = (post_expand_t *)this_gen; expand_parameters_t *param = (expand_parameters_t *)param_gen; param->enable_automatic_shift = this->enable_automatic_shift; param->overlay_y_offset = this->overlay_y_offset; param->aspect = this->aspect; param->centre_cut_out_mode = this->centre_cut_out_mode; return 1; } static char *expand_get_help(void) { return _("The expand plugin is meant to take frames of arbitrary aspect ratio and " "converts them to a different aspect (4:3 by default) by adding black bars " "on the top and bottom of the frame. This allows us to shift overlays " "down into the black area so they don't cover the image.\n" "\n" "Parameters (FIXME: better help)\n" " Enable_automatic_shift: Enable automatic overlay shifting\n" " Overlay_y_offset: Manually shift the overlay vertically\n" " aspect: The target aspect ratio (default 4:3)\n" " Centre_cut_out_mode: extracts 4:3 image contained in 16:9 frame\n" "\n" ); } static int is_pixel_black(vo_frame_t *frame, int x, int y) { int Y = 0x00, Cr = 0x00, Cb = 0x00; if (x < 0) x = 0; if (x >= frame->width) x = frame->width - 1; if (y < 0) y = 0; if (y >= frame->height) y = frame->height - 1; switch (frame->format) { case XINE_IMGFMT_YV12: Y = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x); Cr = *(frame->base[ 1 ] + frame->pitches[ 1 ] * y / 2 + x / 2); Cb = *(frame->base[ 2 ] + frame->pitches[ 2 ] * y / 2 + x / 2); break; case XINE_IMGFMT_YUY2: Y = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 0); x &= ~1; Cr = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 1); Cb = *(frame->base[ 0 ] + frame->pitches[ 0 ] * y + x * 2 + 3); break; } return (Y == 0x10 && Cr == 0x80 && Cb == 0x80); } static int expand_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_expand_t *this = (post_expand_t *)port->post; int skip; if (this->centre_cut_out_mode && !frame->bad_frame) { /* expected area of inner 4:3 image */ int centre_width = frame->width * (9 * 4) / (16 * 3); int centre_left = (frame->width - centre_width ) / 2; /* centre point for detecting a black frame */ int centre_x = frame->width / 2; int centre_y = frame->height / 2; /* ignore a black frame as it could lead to wrong results */ if (!is_pixel_black(frame, centre_x, centre_y)) { /* coordinates for testing black border near the centre area */ int test_left = centre_left - 16; int test_right = centre_left + 16 + centre_width; /* enable cropping when these pixels are black */ this->cropping_active = is_pixel_black(frame, test_left, centre_y) && is_pixel_black(frame, test_right, centre_y); } /* crop frame */ if (this->centre_cut_out_mode && this->cropping_active) { frame->crop_left += centre_left; frame->crop_right += centre_left; /* get_frame() allocated an extra high frame */ frame->crop_top += (frame->next->height - frame->height) / 2; frame->crop_bottom += (frame->next->height - frame->height) / 2; } } frame->ratio = this->aspect; _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); return skip; } static vo_frame_t *expand_get_frame(xine_video_port_t *port_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { post_video_port_t *port = (post_video_port_t *)port_gen; post_expand_t *this = (post_expand_t *)port->post; vo_frame_t *frame; uint32_t new_height, top_bar_height; int i, end; _x_post_rewire(&this->post); if (ratio <= 0.0) ratio = (double)width / (double)height; /* Calculate height of expanded frame */ new_height = (double)height * ratio / this->aspect; new_height = (new_height + 1) & ~1; top_bar_height = (new_height - height) / 2; top_bar_height = (top_bar_height + 1) & ~1; this->top_bar_height = top_bar_height; if (new_height > height && (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2)) { frame = port->original_port->get_frame(port->original_port, width, new_height, this->aspect, format, flags); _x_post_inc_usage(port); frame = _x_post_intercept_video_frame(frame, port); /* paint black bars in the top and bottom of the frame and hide these * from the decoders by modifying the pointers to and * the size of the drawing area */ frame->height = height; frame->ratio = ratio; switch (format) { case XINE_IMGFMT_YV12: /* paint top bar */ memset(frame->base[0], 0, frame->pitches[0] * top_bar_height ); memset(frame->base[1], 128, frame->pitches[1] * top_bar_height / 2); memset(frame->base[2], 128, frame->pitches[2] * top_bar_height / 2); /* paint bottom bar */ memset(frame->base[0] + frame->pitches[0] * (top_bar_height + height) , 0, frame->pitches[0] * (new_height - top_bar_height - height) ); memset(frame->base[1] + frame->pitches[1] * (top_bar_height + height) / 2, 128, frame->pitches[1] * (new_height - top_bar_height - height) / 2); memset(frame->base[2] + frame->pitches[2] * (top_bar_height + height) / 2, 128, frame->pitches[2] * (new_height - top_bar_height - height) / 2); /* modify drawing area */ frame->base[0] += frame->pitches[0] * top_bar_height; frame->base[1] += frame->pitches[1] * top_bar_height / 2; frame->base[2] += frame->pitches[2] * top_bar_height / 2; break; case XINE_IMGFMT_YUY2: /* paint top bar */ end = frame->pitches[0] * top_bar_height; for (i = 0; i < end; i += 2) { frame->base[0][i] = 0; frame->base[0][i+1] = 128; } /* paint bottom bar */ end = frame->pitches[0] * new_height; for (i = frame->pitches[0] * (top_bar_height + height); i < end; i += 2) { frame->base[0][i] = 0; frame->base[0][i+1] = 128; } /* modify drawing area */ frame->base[0] += frame->pitches[0] * top_bar_height; } } else { frame = port->original_port->get_frame(port->original_port, width, height, ratio, format, flags); /* no need to intercept this one, we are not going to do anything with it */ } return frame; } static int expand_intercept_ovl(post_video_port_t *port) { post_expand_t *this = (post_expand_t *)port->post; if (this->centre_cut_out_mode && this->cropping_active) return 0; /* we always intercept overlay manager */ return 1; } static int32_t expand_overlay_add_event(video_overlay_manager_t *this_gen, void *event_gen) { video_overlay_event_t *event = (video_overlay_event_t *)event_gen; post_video_port_t *port = _x_post_ovl_manager_to_port(this_gen); post_expand_t *this = (post_expand_t *)port->post; if (event->event_type == OVERLAY_EVENT_SHOW) { switch (event->object.object_type) { case 0: /* regular subtitle */ if (this->enable_automatic_shift) event->object.overlay->y += 2 * this->top_bar_height; else event->object.overlay->y += this->overlay_y_offset; break; case 1: /* menu overlay */ event->object.overlay->y += this->top_bar_height; } } return port->original_manager->add_event(port->original_manager, event_gen); } static post_plugin_t *expand_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_expand_t *this = calloc(1, sizeof(post_expand_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; static const xine_post_api_t post_api = { .set_parameters = expand_set_parameters, .get_parameters = expand_get_parameters, .get_param_descr = expand_get_param_descr, .get_help = expand_get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post, 0, 1); this->enable_automatic_shift = 0; this->overlay_y_offset = 0; this->aspect = 4.0 / 3.0; this->centre_cut_out_mode = 0; this->cropping_active = 0; port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->new_port.get_frame = expand_get_frame; port->new_frame->draw = expand_draw; port->intercept_ovl = expand_intercept_ovl; port->new_manager->add_event = expand_overlay_add_event; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "expanded video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = expand_dispose; return &this->post; } void *expand_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_expand_class = { .open_plugin = expand_open_plugin, .identifier = "expand", .description = N_("add black borders to top and bottom of video to expand it to 4:3 aspect ratio"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_expand_class; } ������������������������������������������������������xine-lib-1.2/src/post/planar/eq.c�������������������������������������������������������������������0000644�0001750�0001750�00000026152�14647725152�014474� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's eq (soft video equalizer) * Copyright (C) Richard Felker */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #include <pthread.h> #if defined(ARCH_X86) #if defined(ARCH_X86_64) # define MEM1(reg) "(%"reg")" # define MEM2(offs,reg) offs"(%"reg")" # define BUMPPTR(offs,reg) "\n\tleaq\t"offs"(%"reg"), %"reg #elif defined(ARCH_X86_X32) # define MEM1(reg) "(%q"reg")" # define MEM2(offs,reg) offs"(%q"reg")" # define BUMPPTR(offs,reg) "\n\tleaq\t"offs"(%q"reg"), %q"reg #else # define MEM1(reg) "(%"reg")" # define MEM2(offs,reg) offs"(%"reg")" # define BUMPPTR(offs,reg) "\n\tleal\t"offs"(%"reg"), %"reg #endif static void process_MMX(unsigned char *dest, int dstride, unsigned char *src, int sstride, int w, int h, int brightness, int contrast) { int i; int pel; int dstep = dstride - w; int sstep = sstride - w; short cvec[8]; contrast = ((contrast + 100) * 256 * 16) / 100; brightness = ((brightness + 100) * 511) / 200 - 128 - contrast / 32; cvec[0] = cvec[1] = cvec[2] = cvec[3] = brightness; cvec[4] = cvec[5] = cvec[6] = cvec[7] = contrast; __asm__ __volatile__ ( "\n\tmovq\t"MEM1( "0")", %%mm3" "\n\tmovq\t"MEM2("8", "0")", %%mm4" "\n\tpxor\t%%mm0, %%mm0" : : "r" (cvec) ); while (h--) { __asm__ __volatile__ ( "\n\tmovl\t%4, %%eax" "\n\t"ASMALIGN(4) "\n1:" "\n\tmovq\t"MEM1("0")", %%mm1" "\n\tmovq\t"MEM1("0")", %%mm2" "\n\tpunpcklbw\t%%mm0, %%mm1" "\n\tpunpckhbw\t%%mm0, %%mm2" "\n\tpsllw\t$4, %%mm1" "\n\tpsllw\t$4, %%mm2" "\n\tpmulhw\t%%mm4, %%mm1" "\n\tpmulhw\t%%mm4, %%mm2" "\n\tpaddw\t%%mm3, %%mm1" "\n\tpaddw\t%%mm3, %%mm2" "\n\tpackuswb\t%%mm2, %%mm1" BUMPPTR("8","0") "\n\tmovq\t%%mm1, "MEM1("1") BUMPPTR("8","1") "\n\tdecl\t%%eax" "\n\tjnz\t1b" : "=r" (src), "=r" (dest) : "0" (src), "1" (dest), "r" (w>>3) : "%eax" ); for (i = w & 7; i; i--) { pel = ((*src++ * contrast) >> 12) + brightness; if (pel & 768) pel = (-pel) >> 31; *dest++ = pel; } src += sstep; dest += dstep; } __asm__ __volatile__ ( "emms \n\t" ::: "memory" ); } #endif static void process_C(unsigned char *dest, int dstride, unsigned char *src, int sstride, int w, int h, int brightness, int contrast) { int i; int pel; int dstep = dstride-w; int sstep = sstride-w; contrast = ((contrast+100)*256*256)/100; brightness = ((brightness+100)*511)/200-128 - contrast/512; while (h--) { for (i = w; i; i--) { pel = ((*src++* contrast)>>16) + brightness; if(pel&768) pel = (-pel)>>31; *dest++ = pel; } src += sstep; dest += dstep; } } static void (*process)(unsigned char *dest, int dstride, unsigned char *src, int sstride, int w, int h, int brightness, int contrast); typedef struct post_plugin_eq_s post_plugin_eq_t; /* * this is the struct used by "parameters api" */ typedef struct eq_parameters_s { int brightness; int contrast; } eq_parameters_t; /* * description of params struct */ START_PARAM_DESCR( eq_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, brightness, NULL, -100, 100, 0, "brightness" ) PARAM_ITEM( POST_PARAM_TYPE_INT, contrast, NULL, -100, 100, 0, "contrast" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_eq_s { post_plugin_t post; /* private data */ eq_parameters_t params; pthread_mutex_t lock; }; static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_eq_t *this = (post_plugin_eq_t *)this_gen; const eq_parameters_t *param = (const eq_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( &this->params, param, sizeof(eq_parameters_t) ); pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_eq_t *this = (post_plugin_eq_t *)this_gen; eq_parameters_t *param = (eq_parameters_t *)param_gen; memcpy( param, &this->params, sizeof(eq_parameters_t) ); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { return _("Software equalizer with interactive controls just like the hardware " "equalizer, for cards/drivers that do not support brightness and " "contrast controls in hardware.\n" "\n" "Parameters\n" " brightness\n" " contrast\n" "\n" "Note: It is possible to use frontend's control window to set " "these parameters.\n" "\n" "* mplayer's eq (C) Richard Felker\n" ); } static void eq_dispose(post_plugin_t *this_gen) { post_plugin_eq_t *this = (post_plugin_eq_t *)this_gen; if (_x_post_dispose(this_gen)) { pthread_mutex_destroy(&this->lock); free(this); } } static int eq_get_property(xine_video_port_t *port_gen, int property) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_eq_t *this = (post_plugin_eq_t *)port->post; if( property == XINE_PARAM_VO_BRIGHTNESS ) return 65535 * (this->params.brightness + 100) / 200; else if( property == XINE_PARAM_VO_CONTRAST ) return 65535 * (this->params.contrast + 100) / 200; else return port->original_port->get_property(port->original_port, property); } static int eq_set_property(xine_video_port_t *port_gen, int property, int value) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_eq_t *this = (post_plugin_eq_t *)port->post; if( property == XINE_PARAM_VO_BRIGHTNESS ) { pthread_mutex_lock (&this->lock); this->params.brightness = (200 * value / 65535) - 100; pthread_mutex_unlock (&this->lock); return value; } else if( property == XINE_PARAM_VO_CONTRAST ) { pthread_mutex_lock (&this->lock); this->params.contrast = (200 * value / 65535) - 100; pthread_mutex_unlock (&this->lock); return value; } else return port->original_port->set_property(port->original_port, property, value); } static int eq_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2); } static int eq_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_eq_t *this = (post_plugin_eq_t *)port->post; vo_frame_t *out_frame; vo_frame_t *yv12_frame; int skip; if( !frame->bad_frame && ((this->params.brightness != 0) || (this->params.contrast != 0)) ) { /* convert to YV12 if needed */ if( frame->format != XINE_IMGFMT_YV12 ) { yv12_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, yv12_frame); yuy2_to_yv12(frame->base[0], frame->pitches[0], yv12_frame->base[0], yv12_frame->pitches[0], yv12_frame->base[1], yv12_frame->pitches[1], yv12_frame->base[2], yv12_frame->pitches[2], frame->width, frame->height); } else { yv12_frame = frame; yv12_frame->lock(yv12_frame); } out_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, out_frame); pthread_mutex_lock (&this->lock); process(out_frame->base[0], out_frame->pitches[0], yv12_frame->base[0], yv12_frame->pitches[0], frame->width, frame->height, this->params.brightness, this->params.contrast); xine_fast_memcpy(out_frame->base[1],yv12_frame->base[1], yv12_frame->pitches[1] * frame->height/2); xine_fast_memcpy(out_frame->base[2],yv12_frame->base[2], yv12_frame->pitches[2] * frame->height/2); pthread_mutex_unlock (&this->lock); skip = out_frame->draw(out_frame, stream); _x_post_frame_copy_up(frame, out_frame); out_frame->free(out_frame); yv12_frame->free(yv12_frame); } else { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); } return skip; } static post_plugin_t *eq_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_eq_t *this = calloc(1, sizeof(post_plugin_eq_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; process = process_C; #if defined(ARCH_X86) if( xine_mm_accel() & MM_ACCEL_X86_MMX ) process = process_MMX; #endif _x_post_init(&this->post, 0, 1); this->params.brightness = 0; this->params.contrast = 0; pthread_mutex_init (&this->lock, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->new_port.get_property = eq_get_property; port->new_port.set_property = eq_set_property; port->intercept_frame = eq_intercept_frame; port->new_frame->draw = eq_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "eqd video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = eq_dispose; return &this->post; } void *eq_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_eq_class = { .open_plugin = eq_open_plugin, .identifier = "eq", .description = N_("soft video equalizer"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_eq_class; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/planar.c���������������������������������������������������������������0000644�0001750�0001750�00000004212�14647725152�015335� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * catalog for planar post plugins */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_plugin.h> #include <xine/post.h> static const post_info_t gen_special_info = { .type = XINE_POST_TYPE_VIDEO_FILTER, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST, 10, "boxblur", XINE_VERSION_CODE, &gen_special_info, &boxblur_init_plugin }, { PLUGIN_POST, 10, "denoise3d", XINE_VERSION_CODE, &gen_special_info, &denoise3d_init_plugin }, { PLUGIN_POST, 10, "eq", XINE_VERSION_CODE, &gen_special_info, &eq_init_plugin }, { PLUGIN_POST, 10, "eq2", XINE_VERSION_CODE, &gen_special_info, &eq2_init_plugin }, { PLUGIN_POST, 10, "expand", XINE_VERSION_CODE, &gen_special_info, &expand_init_plugin }, { PLUGIN_POST, 10, "fill", XINE_VERSION_CODE, &gen_special_info, &fill_init_plugin }, { PLUGIN_POST, 10, "invert", XINE_VERSION_CODE, &gen_special_info, &invert_init_plugin }, { PLUGIN_POST, 10, "noise", XINE_VERSION_CODE, &gen_special_info, &noise_init_plugin }, #ifdef HAVE_POSTPROC { PLUGIN_POST, 10, "pp", XINE_VERSION_CODE, &gen_special_info, &pp_init_plugin }, #endif { PLUGIN_POST, 10, "unsharp", XINE_VERSION_CODE, &gen_special_info, &unsharp_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/denoise3d.c������������������������������������������������������������0000644�0001750�0001750�00000026764�14647725152�015755� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's denoise3d * Copyright (C) 2003 Daniel Moreno <comac@comac.darktech.org> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #include <math.h> #include <pthread.h> #define PARAM1_DEFAULT 4.0 #define PARAM2_DEFAULT 3.0 #define PARAM3_DEFAULT 6.0 #define MAX_LINE_WIDTH 2048 typedef struct post_plugin_denoise3d_s post_plugin_denoise3d_t; /* * this is the struct used by "parameters api" */ typedef struct denoise3d_parameters_s { double luma; double chroma; double time; } denoise3d_parameters_t; /* * description of params struct */ START_PARAM_DESCR( denoise3d_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, luma, NULL, 0, 10, 0, "spatial luma strength" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, chroma, NULL, 0, 10, 0, "spatial chroma strength" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, time, NULL, 0, 10, 0, "temporal strength" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_denoise3d_s { post_plugin_t post; /* private data */ denoise3d_parameters_t params; int Coefs[4][512]; unsigned char Line[MAX_LINE_WIDTH]; vo_frame_t *prev_frame; pthread_mutex_t lock; }; #define ABS(A) ( (A) > 0 ? (A) : -(A) ) static void ATTR_NO_FAST_VECTOR_MATH PrecalcCoefs(int *Ct, double Dist25) { int i; double Gamma, Simil; Gamma = log(0.25) / log(1.0 - Dist25/255.0); for (i = -256; i <= 255; i++) { Simil = 1.0 - ABS(i) / 255.0; Ct[256+i] = pow(Simil, Gamma) * 65536; } } static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_denoise3d_t *this = (post_plugin_denoise3d_t *)this_gen; const denoise3d_parameters_t *param = (const denoise3d_parameters_t *)param_gen; double ChromTmp; pthread_mutex_lock (&this->lock); if( &this->params != param ) memcpy( &this->params, param, sizeof(denoise3d_parameters_t) ); ChromTmp = this->params.time * this->params.chroma / this->params.luma; PrecalcCoefs(this->Coefs[0], this->params.luma); PrecalcCoefs(this->Coefs[1], this->params.time); PrecalcCoefs(this->Coefs[2], this->params.chroma); PrecalcCoefs(this->Coefs[3], ChromTmp); pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_denoise3d_t *this = (post_plugin_denoise3d_t *)this_gen; denoise3d_parameters_t *param = (denoise3d_parameters_t *)param_gen; memcpy( param, &this->params, sizeof(denoise3d_parameters_t) ); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { return _("This filter aims to reduce image noise producing smooth images and " "making still images really still (This should enhance compressibility.). " "It can be given from 0 to 3 parameters. If you omit a parameter, " "a reasonable value will be inferred.\n" "\n" "Parameters\n" " Luma: Spatial luma strength (default = 4)\n" " Chroma: Spatial chroma strength (default = 3)\n" " Time: Temporal strength (default = 6)\n" "\n" "* mplayer's denoise3d (C) 2003 Daniel Moreno\n" ); } static void denoise3d_dispose(post_plugin_t *this_gen) { post_plugin_denoise3d_t *this = (post_plugin_denoise3d_t *)this_gen; if (_x_post_dispose(this_gen)) { pthread_mutex_destroy(&this->lock); free(this); } } static void denoise3d_close(xine_video_port_t *port_gen, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_denoise3d_t *this = (post_plugin_denoise3d_t *)port->post; if(this->prev_frame) { this->prev_frame->free(this->prev_frame); this->prev_frame = NULL; } port->original_port->close(port->original_port, stream); port->stream = NULL; _x_post_dec_usage(port); } static int denoise3d_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2); } #define LowPass(Prev, Curr, Coef) (((Prev)*Coef[Prev - Curr] + (Curr)*(65536-(Coef[Prev - Curr]))) / 65536) static void deNoise(unsigned char *Frame, unsigned char *FramePrev, unsigned char *FrameDest, unsigned char *LineAnt, int W, int H, int sStride, int pStride, int dStride, int *Horizontal, int *Vertical, int *Temporal) { int X, Y; int sLineOffs = 0, pLineOffs = 0, dLineOffs = 0; unsigned char PixelAnt; /* First pixel has no left nor top neightbour. Only previous frame */ LineAnt[0] = PixelAnt = Frame[0]; FrameDest[0] = LowPass(FramePrev[0], LineAnt[0], Temporal); /* Fist line has no top neightbour. Only left one for each pixel and * last frame */ for (X = 1; X < W; X++) { PixelAnt = LowPass(PixelAnt, Frame[X], Horizontal); LineAnt[X] = PixelAnt; FrameDest[X] = LowPass(FramePrev[X], LineAnt[X], Temporal); } for (Y = 1; Y < H; Y++) { sLineOffs += sStride, pLineOffs += pStride, dLineOffs += dStride; /* First pixel on each line doesn't have previous pixel */ PixelAnt = Frame[sLineOffs]; LineAnt[0] = LowPass(LineAnt[0], PixelAnt, Vertical); FrameDest[dLineOffs] = LowPass(FramePrev[pLineOffs], LineAnt[0], Temporal); for (X = 1; X < W; X++) { /* The rest are normal */ PixelAnt = LowPass(PixelAnt, Frame[sLineOffs+X], Horizontal); LineAnt[X] = LowPass(LineAnt[X], PixelAnt, Vertical); FrameDest[dLineOffs+X] = LowPass(FramePrev[pLineOffs+X], LineAnt[X], Temporal); } } } static int denoise3d_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_denoise3d_t *this = (post_plugin_denoise3d_t *)port->post; vo_frame_t *out_frame; vo_frame_t *prev_frame; vo_frame_t *yv12_frame; int cw, ch; int skip; if( !frame->bad_frame ) { /* convert to YV12 if needed */ if( frame->format != XINE_IMGFMT_YV12 ) { yv12_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, yv12_frame); yuy2_to_yv12(frame->base[0], frame->pitches[0], yv12_frame->base[0], yv12_frame->pitches[0], yv12_frame->base[1], yv12_frame->pitches[1], yv12_frame->base[2], yv12_frame->pitches[2], frame->width, frame->height); } else { yv12_frame = frame; yv12_frame->lock(yv12_frame); } out_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, out_frame); pthread_mutex_lock (&this->lock); cw = yv12_frame->width/2; ch = yv12_frame->height/2; prev_frame = (this->prev_frame) ? this->prev_frame : yv12_frame; deNoise(yv12_frame->base[0], prev_frame->base[0], out_frame->base[0], this->Line, yv12_frame->width, yv12_frame->height, yv12_frame->pitches[0], prev_frame->pitches[0], out_frame->pitches[0], this->Coefs[0] + 256, this->Coefs[0] + 256, this->Coefs[1] + 256); deNoise(yv12_frame->base[1], prev_frame->base[1], out_frame->base[1], this->Line, cw, ch, yv12_frame->pitches[1], prev_frame->pitches[1], out_frame->pitches[1], this->Coefs[2] + 256, this->Coefs[2] + 256, this->Coefs[3] + 256); deNoise(yv12_frame->base[2], prev_frame->base[2], out_frame->base[2], this->Line, cw, ch, yv12_frame->pitches[2], prev_frame->pitches[2], out_frame->pitches[2], this->Coefs[2] + 256, this->Coefs[2] + 256, this->Coefs[3] + 256); pthread_mutex_unlock (&this->lock); skip = out_frame->draw(out_frame, stream); _x_post_frame_copy_up(frame, out_frame); out_frame->free(out_frame); if(this->prev_frame) this->prev_frame->free(this->prev_frame); if(port->stream) this->prev_frame = yv12_frame; else /* do not keep this frame when no stream is connected to us, * otherwise, this frame might never get freed */ yv12_frame->free(yv12_frame); } else { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); } return skip; } static post_plugin_t *denoise3d_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_denoise3d_t *this = calloc(1, sizeof(post_plugin_denoise3d_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post, 0, 1); this->params.luma = PARAM1_DEFAULT; this->params.chroma = PARAM2_DEFAULT; this->params.time = PARAM3_DEFAULT; this->prev_frame = NULL; pthread_mutex_init(&this->lock, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->new_port.close = denoise3d_close; port->intercept_frame = denoise3d_intercept_frame; port->new_frame->draw = denoise3d_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "denoise3d video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = denoise3d_dispose; set_parameters ((xine_post_t *)this, &this->params); return &this->post; } void *denoise3d_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_denoise3d_class = { .open_plugin = denoise3d_open_plugin, .identifier = "denoise3d", .description = N_("3D Denoiser (variable lowpass filter)"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_denoise3d_class; } ������������xine-lib-1.2/src/post/planar/fill.c�����������������������������������������������������������������0000644�0001750�0001750�00000007323�14647725152�015014� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2005-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * fill video filter by James Stembridge (jstembridge@gmail.com) * * based on invert.c */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> static void fill_dispose(post_plugin_t *this) { if (_x_post_dispose(this)) free(this); } static vo_frame_t *fill_get_frame(xine_video_port_t *port_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_t *this = port->post; vo_frame_t *frame; _x_post_rewire(this); if (ratio <= 0.0) ratio = (double)width / (double)height; if ((ratio > 4.0/3.0) && (format == XINE_IMGFMT_YV12 || format == XINE_IMGFMT_YUY2)) { frame = port->original_port->get_frame(port->original_port, width, height, 4.0/3.0, format, flags); _x_post_inc_usage(port); frame = _x_post_intercept_video_frame(frame, port); frame->ratio = ratio; } else { frame = port->original_port->get_frame(port->original_port, width, height, ratio, format, flags); /* no need to intercept this one, we are not going to do anything with it */ } return frame; } static int fill_draw(vo_frame_t *frame, xine_stream_t *stream) { int skip, new_width; new_width = (4.0*frame->width) / (3.0*frame->ratio); frame->crop_left += (frame->width - new_width) / 2; frame->crop_right += (frame->width + 1 - new_width) / 2; frame->ratio = 4.0/3.0; _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); return skip; } static post_plugin_t *fill_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_t *this = calloc(1, sizeof(post_plugin_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(this, 0, 1); port = _x_post_intercept_video_port(this, video_target[0], &input, &output); port->new_port.get_frame = fill_get_frame; port->new_frame->draw = fill_draw; input->xine_in.name = "video"; output->xine_out.name = "cropped video"; this->xine_post.video_input[0] = &port->new_port; this->dispose = fill_dispose; return this; } void *fill_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_fill_class = { .open_plugin = fill_open_plugin, .identifier = "fill", .description = N_("crops left and right of video to fill 4:3 aspect ratio"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_fill_class; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/unsharp.c��������������������������������������������������������������0000644�0001750�0001750�00000031707�14647725152�015551� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's unsharp * Copyright (C) 2002 Rémi Guyomarch <rguyom@pobox.com> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #include <pthread.h> /*===========================================================================*/ #define MIN_MATRIX_SIZE 3 #define MAX_MATRIX_SIZE 63 typedef struct FilterParam { int msizeX, msizeY; double amount; uint32_t *SC[MAX_MATRIX_SIZE-1]; } FilterParam; struct vf_priv_s { FilterParam lumaParam; FilterParam chromaParam; int width, height; }; /*===========================================================================*/ /* This code is based on : An Efficient algorithm for Gaussian blur using finite-state machines Frederick M. Waltz and John W. V. Miller SPIE Conf. on Machine Vision Systems for Inspection and Metrology VII Originally published Boston, Nov 98 */ static void unsharp( uint8_t *dst, uint8_t *src, int dstStride, int srcStride, int width, int height, FilterParam *fp ) { uint32_t **SC = fp->SC; uint32_t SR[MAX_MATRIX_SIZE-1], Tmp1, Tmp2; uint8_t* src2 = src; int32_t res; int x, y, z; int amount = fp->amount * 65536.0; int stepsX = fp->msizeX/2; int stepsY = fp->msizeY/2; int scalebits = (stepsX+stepsY)*2; int32_t halfscale = 1 << ((stepsX+stepsY)*2-1); if( !fp->amount ) { if( src == dst ) return; if( dstStride == srcStride ) xine_fast_memcpy( dst, src, srcStride*height ); else for( y=0; y<height; y++, dst+=dstStride, src+=srcStride ) xine_fast_memcpy( dst, src, width ); return; } for( y=0; y<2*stepsY; y++ ) memset( SC[y], 0, sizeof(SC[y][0]) * (width+2*stepsX) ); for( y=-stepsY; y<height+stepsY; y++ ) { if( y < height ) src2 = src; memset( SR, 0, sizeof(SR[0]) * (2*stepsX-1) ); for( x=-stepsX; x<width+stepsX; x++ ) { Tmp1 = x<=0 ? src2[0] : x>=width ? src2[width-1] : src2[x]; for( z=0; z<stepsX*2; z+=2 ) { Tmp2 = SR[z+0] + Tmp1; SR[z+0] = Tmp1; Tmp1 = SR[z+1] + Tmp2; SR[z+1] = Tmp2; } for( z=0; z<stepsY*2; z+=2 ) { Tmp2 = SC[z+0][x+stepsX] + Tmp1; SC[z+0][x+stepsX] = Tmp1; Tmp1 = SC[z+1][x+stepsX] + Tmp2; SC[z+1][x+stepsX] = Tmp2; } if( x>=stepsX && y>=stepsY ) { uint8_t* srx = src - stepsY*srcStride + x - stepsX; uint8_t* dsx = dst - stepsY*dstStride + x - stepsX; res = (int32_t)*srx + ( ( ( (int32_t)*srx - (int32_t)((Tmp1+halfscale) >> scalebits) ) * amount ) >> 16 ); *dsx = res>255 ? 255 : res<0 ? 0 : (uint8_t)res; } } if( y >= 0 ) { dst += dstStride; src += srcStride; } } } typedef struct post_plugin_unsharp_s post_plugin_unsharp_t; /* * this is the struct used by "parameters api" */ typedef struct unsharp_parameters_s { int luma_matrix_width; int luma_matrix_height; double luma_amount; int chroma_matrix_width; int chroma_matrix_height; double chroma_amount; } unsharp_parameters_t; /* * description of params struct */ START_PARAM_DESCR( unsharp_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, luma_matrix_width, NULL, 3, 11, 0, "width of the matrix (must be odd)" ) PARAM_ITEM( POST_PARAM_TYPE_INT, luma_matrix_height, NULL, 3, 11, 0, "height of the matrix (must be odd)" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, luma_amount, NULL, -2, 2, 0, "relative amount of sharpness/blur (=0 disable, <0 blur, >0 sharpen)" ) PARAM_ITEM( POST_PARAM_TYPE_INT, chroma_matrix_width, NULL, 3, 11, 0, "width of the matrix (must be odd)" ) PARAM_ITEM( POST_PARAM_TYPE_INT, chroma_matrix_height, NULL, 3, 11, 0, "height of the matrix (must be odd)" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, chroma_amount, NULL, -2, 2, 0, "relative amount of sharpness/blur (=0 disable, <0 blur, >0 sharpen)" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_unsharp_s { post_plugin_t post; /* private data */ unsharp_parameters_t params; struct vf_priv_s priv; pthread_mutex_t lock; }; static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_unsharp_t *this = (post_plugin_unsharp_t *)this_gen; const unsharp_parameters_t *param = (const unsharp_parameters_t *)param_gen; FilterParam *fp; pthread_mutex_lock (&this->lock); if( &this->params != param ) memcpy( &this->params, param, sizeof(unsharp_parameters_t) ); fp = &this->priv.lumaParam; fp->msizeX = 1 | MIN( MAX( param->luma_matrix_width, MIN_MATRIX_SIZE ), MAX_MATRIX_SIZE ); fp->msizeY = 1 | MIN( MAX( param->luma_matrix_height, MIN_MATRIX_SIZE ), MAX_MATRIX_SIZE ); fp->amount = param->luma_amount; fp = &this->priv.chromaParam; fp->msizeX = 1 | MIN( MAX( param->chroma_matrix_width, MIN_MATRIX_SIZE ), MAX_MATRIX_SIZE ); fp->msizeY = 1 | MIN( MAX( param->chroma_matrix_height, MIN_MATRIX_SIZE ), MAX_MATRIX_SIZE ); fp->amount = param->chroma_amount; this->priv.width = this->priv.height = 0; pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_unsharp_t *this = (post_plugin_unsharp_t *)this_gen; unsharp_parameters_t *param = (unsharp_parameters_t *)param_gen; memcpy( param, &this->params, sizeof(unsharp_parameters_t) ); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { /* use real name "Rémi Guyomarch" in translations */ return _("Unsharp mask / gaussian blur\n" "It is possible to set the width and height of the matrix, " "odd sized in both directions (min = 3x3, max = 13x11 or 11x13, " "usually something between 3x3 and 7x7) and the relative amount " "of sharpness/blur to add to the image (a sane range should be " "-1.5 - 1.5).\n" "\n" "Parameters\n" "\n" " Luma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Luma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Luma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 sharpen)\n" "\n" " Chroma_matrix_width: Width of the matrix (must be odd)\n" "\n" " Chroma_matrix_height: Height of the matrix (must be odd)\n" "\n" " Chroma_amount: Relative amount of sharpness/blur (=0 disable, <0 blur, >0 sharpen)\n" "\n" "\n" "* mplayer's unsharp (C) 2002 Remi Guyomarch\n" ); } static void unsharp_free_SC(post_plugin_unsharp_t *this) { int i; for( i = 0; i < MAX_MATRIX_SIZE-1; i++ ) { if( this->priv.lumaParam.SC[i] ) { free( this->priv.lumaParam.SC[i] ); this->priv.lumaParam.SC[i] = NULL; } } for( i = 0; i < MAX_MATRIX_SIZE-1; i++ ) { if( this->priv.chromaParam.SC[i] ) { free( this->priv.chromaParam.SC[i] ); this->priv.chromaParam.SC[i] = NULL; } } } static void unsharp_dispose(post_plugin_t *this_gen) { post_plugin_unsharp_t *this = (post_plugin_unsharp_t *)this_gen; if (_x_post_dispose(this_gen)) { unsharp_free_SC(this); pthread_mutex_destroy(&this->lock); free(this); } } static int unsharp_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2); } static int unsharp_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_unsharp_t *this = (post_plugin_unsharp_t *)port->post; vo_frame_t *out_frame; vo_frame_t *yv12_frame; int skip; if( !frame->bad_frame && (this->priv.lumaParam.amount || this->priv.chromaParam.amount) ) { /* convert to YV12 if needed */ if( frame->format != XINE_IMGFMT_YV12 ) { yv12_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, yv12_frame); yuy2_to_yv12(frame->base[0], frame->pitches[0], yv12_frame->base[0], yv12_frame->pitches[0], yv12_frame->base[1], yv12_frame->pitches[1], yv12_frame->base[2], yv12_frame->pitches[2], frame->width, frame->height); } else { yv12_frame = frame; yv12_frame->lock(yv12_frame); } out_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, out_frame); pthread_mutex_lock (&this->lock); if( frame->width != this->priv.width || frame->height != this->priv.height ) { int z, stepsX, stepsY; FilterParam *fp; this->priv.width = frame->width; this->priv.height = frame->height; unsharp_free_SC(this); fp = &this->priv.lumaParam; stepsX = fp->msizeX/2; stepsY = fp->msizeY/2; for( z=0; z<2*stepsY; z++ ) fp->SC[z] = malloc( sizeof(*(fp->SC[z])) * (frame->width+2*stepsX) ); fp = &this->priv.chromaParam; stepsX = fp->msizeX/2; stepsY = fp->msizeY/2; for( z=0; z<2*stepsY; z++ ) fp->SC[z] = malloc( sizeof(*(fp->SC[z])) * (frame->width+2*stepsX) ); } unsharp( out_frame->base[0], yv12_frame->base[0], out_frame->pitches[0], yv12_frame->pitches[0], yv12_frame->width, yv12_frame->height, &this->priv.lumaParam ); unsharp( out_frame->base[1], yv12_frame->base[1], out_frame->pitches[1], yv12_frame->pitches[1], yv12_frame->width/2, yv12_frame->height/2, &this->priv.chromaParam ); unsharp( out_frame->base[2], yv12_frame->base[2], out_frame->pitches[2], yv12_frame->pitches[2], yv12_frame->width/2, yv12_frame->height/2, &this->priv.chromaParam ); pthread_mutex_unlock (&this->lock); skip = out_frame->draw(out_frame, stream); _x_post_frame_copy_up(frame, out_frame); out_frame->free(out_frame); yv12_frame->free(yv12_frame); } else { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); } return skip; } static post_plugin_t *unsharp_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_unsharp_t *this = calloc(1, sizeof(post_plugin_unsharp_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post, 0, 1); this->params.luma_matrix_width = 5; this->params.luma_matrix_height = 5; this->params.luma_amount = 0.0; this->params.chroma_matrix_width = 3; this->params.chroma_matrix_height = 3; this->params.chroma_amount = 0.0; pthread_mutex_init (&this->lock, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->intercept_frame = unsharp_intercept_frame; port->new_frame->draw = unsharp_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "unsharped video"; this->post.xine_post.video_input[0] = &port->new_port; set_parameters ((xine_post_t *)this, &this->params); this->post.dispose = unsharp_dispose; return &this->post; } void *unsharp_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_unsharp_class = { .open_plugin = unsharp_open_plugin, .identifier = "unsharp", .description = N_("unsharp mask & gaussian blur"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_unsharp_class; } ���������������������������������������������������������xine-lib-1.2/src/post/planar/planar.h���������������������������������������������������������������0000644�0001750�0001750�00000003044�14647725152�015344� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * catalog for planar post plugins */ #ifndef XINE_POST_PLANAR_H #define XINE_POST_PLANAR_H #include <xine/xine_internal.h> void *boxblur_init_plugin (xine_t *xine, const void *); void *denoise3d_init_plugin (xine_t *xine, const void *); void *eq_init_plugin (xine_t *xine, const void *); void *eq2_init_plugin (xine_t *xine, const void *); void *expand_init_plugin (xine_t *xine, const void *); void *fill_init_plugin (xine_t *xine, const void *); void *invert_init_plugin (xine_t *xine, const void *); void *noise_init_plugin (xine_t *xine, const void *); #ifdef HAVE_POSTPROC void *pp_init_plugin (xine_t *xine, const void *); #endif void *unsharp_init_plugin (xine_t *xine, const void *); #endif /* XINE_POST_PLANAR_H */ ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/noise.c����������������������������������������������������������������0000644�0001750�0001750�00000034056�14647725152�015206� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's noise filter, ported by Jason Tackaberry. Original filter * is copyright 2002 Michael Niedermayer <michaelni@gmx.at> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #include <math.h> #include <pthread.h> #ifdef ARCH_X86 #include "x86/noise.h" #endif #define MAX_NOISE 4096 #define MAX_SHIFT 1024 #define MAX_RES (MAX_NOISE-MAX_SHIFT) typedef struct noise_param_t { void (*lineNoise)(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift); void (*lineNoiseAvg)(uint8_t *dst, const uint8_t *src, int len, int8_t **shift); int strength, uniform, temporal, quality, averaged, pattern, shiftptr; int8_t *noise, *prev_shift[MAX_RES][3]; } noise_param_t; static int nonTempRandShift[MAX_RES]= {-1}; static const int patt[4] = { -1,0,1,0 }; #define RAND_N(range) ((int) ((double)range*rand()/(RAND_MAX+1.0))) static int8_t *initNoise(noise_param_t *fp){ int strength= fp->strength; int uniform= fp->uniform; int averaged= fp->averaged; int pattern= fp->pattern; int8_t *noise; int i, j; noise = xine_mallocz_aligned(MAX_NOISE*sizeof(int8_t)); srand(123457); for(i=0,j=0; i<MAX_NOISE; i++,j++) { if(uniform) { if (averaged) { if (pattern) { noise[i]= (RAND_N(strength) - strength/2)/6 +patt[j%4]*strength*0.25/3; } else { noise[i]= (RAND_N(strength) - strength/2)/3; } } else { if (pattern) { noise[i]= (RAND_N(strength) - strength/2)/2 + patt[j%4]*strength*0.25; } else { noise[i]= RAND_N(strength) - strength/2; } } } else { double x1, x2, w, y1; do { x1 = 2.0 * rand()/(float)RAND_MAX - 1.0; x2 = 2.0 * rand()/(float)RAND_MAX - 1.0; w = x1 * x1 + x2 * x2; } while ( w >= 1.0 ); w = sqrt( (-2.0 * log( w ) ) / w ); y1= x1 * w; y1*= strength / sqrt(3.0); if (pattern) { y1 /= 2; y1 += patt[j%4]*strength*0.35; } if (y1<-128) y1=-128; else if(y1> 127) y1= 127; if (averaged) y1 /= 3.0; noise[i]= (int)y1; } if (RAND_N(6) == 0) j--; } for (i = 0; i < MAX_RES; i++) for (j = 0; j < 3; j++) fp->prev_shift[i][j] = noise + (rand()&(MAX_SHIFT-1)); if(nonTempRandShift[0]==-1){ for(i=0; i<MAX_RES; i++){ nonTempRandShift[i]= rand()&(MAX_SHIFT-1); } } fp->noise= noise; fp->shiftptr= 0; return noise; } static inline void lineNoise_C(uint8_t *dst, const uint8_t *src, const int8_t *noise, int len, int shift) { int i; noise+= shift; for(i=0; i<len; i++) { int v= src[i]+ noise[i]; if(v>255) dst[i]=255; //FIXME optimize else if(v<0) dst[i]=0; else dst[i]=v; } } /***************************************************************************/ static inline void lineNoiseAvg_C(uint8_t *dst, const uint8_t *src, int len, int8_t **shift) { int i; const int8_t *src2= (const int8_t*)src; for(i=0; i<len; i++) { const int n= shift[0][i] + shift[1][i] + shift[2][i]; dst[i]= src2[i]+((n*src2[i])>>7); } } /***************************************************************************/ static void noise(uint8_t *dst, const uint8_t *src, int dstStride, int srcStride, int width, int height, noise_param_t *fp) { int8_t *noise= fp->noise; int y; int shift=0; if(!noise) { if(src==dst) return; if(dstStride==srcStride) memcpy(dst, src, srcStride*height); else { for(y=0; y<height; y++) { memcpy(dst, src, width); dst+= dstStride; src+= srcStride; } } return; } for(y=0; y<height; y++) { if(fp->temporal) shift= rand()&(MAX_SHIFT -1); else shift= nonTempRandShift[y]; if(fp->quality==0) shift&= ~7; if (fp->averaged) { fp->lineNoiseAvg(dst, src, width, fp->prev_shift[y]); fp->prev_shift[y][fp->shiftptr] = noise + shift; } else { fp->lineNoise(dst, src, noise, width, shift); } dst+= dstStride; src+= srcStride; } fp->shiftptr++; if (fp->shiftptr == 3) fp->shiftptr = 0; } typedef struct post_plugin_noise_s post_plugin_noise_t; /* * this is the struct used by "parameters api" */ typedef struct noise_parameters_s { int luma_strength, chroma_strength, type, quality, pattern; } noise_parameters_t; static const char *const enum_types[] = {"uniform", "gaussian", NULL}; static const char *const enum_quality[] = {"fixed", "temporal", "averaged temporal", NULL}; /* * description of params struct */ START_PARAM_DESCR( noise_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, luma_strength, NULL, 0, 100, 0, "Amount of noise to add to luma channel" ) PARAM_ITEM( POST_PARAM_TYPE_INT, chroma_strength, NULL, 0, 100, 0, "Amount of noise to add to chroma channel" ) PARAM_ITEM( POST_PARAM_TYPE_INT, quality, (char **)enum_quality, 0, 0, 0, "Quality level of noise" ) PARAM_ITEM( POST_PARAM_TYPE_INT, type, (char **)enum_types, 0, 0, 0, "Type of noise" ) PARAM_ITEM( POST_PARAM_TYPE_BOOL, pattern, NULL, 0, 1, 0, "Mix random noise with a (semi)regular pattern" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_noise_s { post_plugin_t post; /* private data */ noise_param_t params[2]; // luma and chroma pthread_mutex_t lock; }; static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_noise_t *this = (post_plugin_noise_t *)this_gen; const noise_parameters_t *param = (const noise_parameters_t *)param_gen; int i; pthread_mutex_lock (&this->lock); for (i = 0; i < 2; i++) { this->params[i].uniform = (param->type == 0); this->params[i].temporal = (param->quality >= 1); this->params[i].averaged = (param->quality == 2); this->params[i].quality = 1; this->params[i].pattern = param->pattern; } this->params[0].strength = param->luma_strength; this->params[1].strength = param->chroma_strength; pthread_mutex_unlock (&this->lock); initNoise(&this->params[0]); initNoise(&this->params[1]); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_noise_t *this = (post_plugin_noise_t *)this_gen; noise_parameters_t *param = (noise_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); param->type = (this->params[0].uniform == 0); if (this->params[0].averaged) param->quality = 2; else if (this->params[0].temporal) param->quality = 1; else param->quality = 0; param->pattern = this->params[0].pattern; param->luma_strength = this->params[0].strength; param->chroma_strength = this->params[1].strength; pthread_mutex_unlock (&this->lock); return 1; } static xine_post_api_descr_t *get_param_descr (void) { return ¶m_descr; } static char *get_help (void) { return _("Adds random noise to the video.\n" "\n" "Parameters:\n" " luma_strength: strength of noise added to luma channel " "(0-100, default: 8)\n" " chroma_strength: strength of noise added to chroma channel " "(0-100, default: 5)\n" " quality: quality level of the noise. fixed: constant noise " "pattern; temporal: noise pattern changes between frames; " "averaged temporal: smoother noise pattern that changes between " "frames. (default: averaged temporal)\n" " type: Type of noise: uniform or gaussian. (default: " "gaussian)\n" " pattern: Mix random noise with a (semi)regular pattern. " "(default: False)\n" "\n" "* mplayer's noise (C) Michael Niedermayer\n" ); } static void noise_dispose(post_plugin_t *this_gen) { post_plugin_noise_t *this = (post_plugin_noise_t *)this_gen; if (_x_post_dispose(this_gen)) { pthread_mutex_destroy(&this->lock); xine_freep_aligned(&this->params[0].noise); xine_freep_aligned(&this->params[1].noise); free(this); } } static int noise_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2); } static int noise_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_noise_t *this = (post_plugin_noise_t *)port->post; vo_frame_t *out_frame; int skip; if (frame->bad_frame || (this->params[0].strength == 0 && this->params[1].strength == 0)) { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); return skip; } frame->lock(frame); out_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, frame->format, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, out_frame); pthread_mutex_lock (&this->lock); if (frame->format == XINE_IMGFMT_YV12) { noise(out_frame->base[0], frame->base[0], out_frame->pitches[0], frame->pitches[0], frame->width, frame->height, &this->params[0]); noise(out_frame->base[1], frame->base[1], out_frame->pitches[1], frame->pitches[1], frame->width/2, frame->height/2, &this->params[1]); noise(out_frame->base[2], frame->base[2], out_frame->pitches[2], frame->pitches[2], frame->width/2, frame->height/2, &this->params[1]); } else { // Chroma strength is ignored for YUY2. noise(out_frame->base[0], frame->base[0], out_frame->pitches[0], frame->pitches[0], frame->width * 2, frame->height, &this->params[0]); } #ifdef ARCH_X86 if (xine_mm_accel() & MM_ACCEL_X86_MMX) __asm__ __volatile__ ("emms\n\t"); if (xine_mm_accel() & MM_ACCEL_X86_MMXEXT) __asm__ __volatile__ ("sfence\n\t"); #endif pthread_mutex_unlock (&this->lock); skip = out_frame->draw(out_frame, stream); _x_post_frame_copy_up(frame, out_frame); out_frame->free(out_frame); frame->free(frame); return skip; } static post_plugin_t *noise_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_noise_t *this = calloc(1, sizeof(post_plugin_noise_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; static const noise_parameters_t init_params = { .luma_strength = 8, .chroma_strength = 5, .type = 1, .quality = 2, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post, 0, 1); pthread_mutex_init(&this->lock, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->intercept_frame = noise_intercept_frame; port->new_frame->draw = noise_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "filtered video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = noise_dispose; set_parameters ((xine_post_t *)this, &init_params); /* */ this->params[0].lineNoise = lineNoise_C; this->params[0].lineNoiseAvg = lineNoiseAvg_C; #ifdef ARCH_X86 if (xine_mm_accel() & MM_ACCEL_X86_MMX) { this->params[0].lineNoise = lineNoise_MMX; this->params[0].lineNoiseAvg = lineNoiseAvg_MMX; } if (xine_mm_accel() & MM_ACCEL_X86_MMXEXT) { this->params[0].lineNoise = lineNoise_MMX2; } #endif this->params[1].lineNoise = this->params[0].lineNoise; this->params[1].lineNoiseAvg = this->params[0].lineNoiseAvg; return &this->post; } void *noise_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_noise_class = { .open_plugin = noise_open_plugin, .identifier = "noise", .description = N_("Adds noise"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_noise_class; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/invert.c���������������������������������������������������������������0000644�0001750�0001750�00000007647�14647725152�015406� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * simple video inverter plugin */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> static void invert_dispose(post_plugin_t *this) { if (_x_post_dispose(this)) free(this); } static int invert_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2 || frame->format == XINE_IMGFMT_NV12); } static int invert_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; vo_frame_t *inverted_frame; int size, i, skip; if (frame->bad_frame) { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); return skip; } inverted_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, frame->format, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, inverted_frame); switch (inverted_frame->format) { case XINE_IMGFMT_YV12: /* V */ size = inverted_frame->pitches[2] * ((inverted_frame->height + 1) / 2); for (i = 0; i < size; i++) inverted_frame->base[2][i] = 0xff - frame->base[2][i]; /* fall thru */ case XINE_IMGFMT_NV12: /* U or UV */ size = inverted_frame->pitches[1] * ((inverted_frame->height + 1) / 2); for (i = 0; i < size; i++) inverted_frame->base[1][i] = 0xff - frame->base[1][i]; /* fall thru */ case XINE_IMGFMT_YUY2: /* Y or YUY2 */ size = inverted_frame->pitches[0] * inverted_frame->height; for (i = 0; i < size; i++) inverted_frame->base[0][i] = 0xff - frame->base[0][i]; break; } skip = inverted_frame->draw(inverted_frame, stream); _x_post_frame_copy_up(frame, inverted_frame); inverted_frame->free(inverted_frame); return skip; } static post_plugin_t *invert_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_t *this = calloc(1, sizeof(post_plugin_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(this, 0, 1); port = _x_post_intercept_video_port(this, video_target[0], &input, &output); port->intercept_frame = invert_intercept_frame; port->new_frame->draw = invert_draw; input->xine_in.name = "video"; output->xine_out.name = "inverted video"; this->xine_post.video_input[0] = &port->new_port; this->dispose = invert_dispose; return this; } void *invert_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_invert_class = { .open_plugin = invert_open_plugin, .identifier = "invert", .description = N_("inverts the colours of every video frame"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_invert_class; } �����������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/boxblur.c��������������������������������������������������������������0000644�0001750�0001750�00000023717�14647725152�015550� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's boxblur * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at> */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #include <pthread.h> typedef struct post_plugin_boxblur_s post_plugin_boxblur_t; /* * this is the struct used by "parameters api" */ typedef struct boxblur_parameters_s { int luma_radius; int luma_power; int chroma_radius; int chroma_power; } boxblur_parameters_t; /* * description of params struct */ START_PARAM_DESCR( boxblur_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, luma_radius, NULL, 0, 10, 0, "radius of luma blur" ) PARAM_ITEM( POST_PARAM_TYPE_INT, luma_power, NULL, 0, 10, 0, "power of luma blur" ) PARAM_ITEM( POST_PARAM_TYPE_INT, chroma_radius, NULL, -1, 10, 0, "radius of chroma blur (-1 = same as luma)" ) PARAM_ITEM( POST_PARAM_TYPE_INT, chroma_power, NULL, -1, 10, 0, "power of chroma blur (-1 = same as luma)" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_boxblur_s { post_plugin_t post; /* private data */ boxblur_parameters_t params; pthread_mutex_t lock; }; static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_boxblur_t *this = (post_plugin_boxblur_t *)this_gen; const boxblur_parameters_t *param = (const boxblur_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( &this->params, param, sizeof(boxblur_parameters_t) ); pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_boxblur_t *this = (post_plugin_boxblur_t *)this_gen; boxblur_parameters_t *param = (boxblur_parameters_t *)param_gen; memcpy( param, &this->params, sizeof(boxblur_parameters_t) ); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { return _("Box blur does a simple blurring of the image.\n" "\n" "Parameters\n" " Radius: size of the filter\n" " Power: how often the filter should be applied\n" "\n" "* mplayer's boxblur (C) 2002 Michael Niedermayer\n" ); } static void boxblur_dispose(post_plugin_t *this_gen) { post_plugin_boxblur_t *this = (post_plugin_boxblur_t *)this_gen; if (_x_post_dispose(this_gen)) { pthread_mutex_destroy(&this->lock); free(this); } } static int boxblur_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2); } static inline void blur(uint8_t *dst, uint8_t *src, int w, int radius, int dstStep, int srcStep){ int x; const int length= radius*2 + 1; const int inv= ((1<<16) + length/2)/length; int sum= 0; for(x=0; x<radius; x++){ sum+= src[x*srcStep]<<1; } sum+= src[radius*srcStep]; for(x=0; x<=radius; x++){ sum+= src[(radius+x)*srcStep] - src[(radius-x)*srcStep]; dst[x*dstStep]= (sum*inv + (1<<15))>>16; } for(; x<w-radius; x++){ sum+= src[(radius+x)*srcStep] - src[(x-radius-1)*srcStep]; dst[x*dstStep]= (sum*inv + (1<<15))>>16; } for(; x<w; x++){ sum+= src[(2*w-radius-x-1)*srcStep] - src[(x-radius-1)*srcStep]; dst[x*dstStep]= (sum*inv + (1<<15))>>16; } } static inline void blur2(uint8_t *dst, uint8_t *src, int w, int radius, int power, int dstStep, int srcStep){ uint8_t temp[2][4096]; uint8_t *a= temp[0], *b=temp[1]; if(radius){ blur(a, src, w, radius, 1, srcStep); for(; power>2; power--){ uint8_t *c; blur(b, a, w, radius, 1, 1); c=a; a=b; b=c; } if(power>1) blur(dst, a, w, radius, dstStep, 1); else{ int i; for(i=0; i<w; i++) dst[i*dstStep]= a[i]; } }else{ int i; for(i=0; i<w; i++) dst[i*dstStep]= src[i*srcStep]; } } static void hBlur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, int radius, int power){ int y; if(radius==0 && dst==src) return; for(y=0; y<h; y++){ blur2(dst + y*dstStride, src + y*srcStride, w, radius, power, 1, 1); } } static void vBlur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, int radius, int power){ int x; if(radius==0 && dst==src) return; for(x=0; x<w; x++){ blur2(dst + x, src + x, h, radius, power, dstStride, srcStride); } } static int boxblur_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_boxblur_t *this = (post_plugin_boxblur_t *)port->post; vo_frame_t *out_frame; vo_frame_t *yv12_frame; int chroma_radius, chroma_power; int cw, ch; int skip; if( !frame->bad_frame ) { /* convert to YV12 if needed */ if( frame->format != XINE_IMGFMT_YV12 ) { yv12_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, yv12_frame); yuy2_to_yv12(frame->base[0], frame->pitches[0], yv12_frame->base[0], yv12_frame->pitches[0], yv12_frame->base[1], yv12_frame->pitches[1], yv12_frame->base[2], yv12_frame->pitches[2], frame->width, frame->height); } else { yv12_frame = frame; yv12_frame->lock(yv12_frame); } out_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, out_frame); pthread_mutex_lock (&this->lock); chroma_radius = (this->params.chroma_radius != -1) ? this->params.chroma_radius : this->params.luma_radius; chroma_power = (this->params.chroma_power != -1) ? this->params.chroma_power : this->params.luma_power; cw = yv12_frame->width/2; ch = yv12_frame->height/2; hBlur(out_frame->base[0], yv12_frame->base[0], yv12_frame->width, yv12_frame->height, out_frame->pitches[0], yv12_frame->pitches[0], this->params.luma_radius, this->params.luma_power); hBlur(out_frame->base[1], yv12_frame->base[1], cw,ch, out_frame->pitches[1], yv12_frame->pitches[1], chroma_radius, chroma_power); hBlur(out_frame->base[2], yv12_frame->base[2], cw,ch, out_frame->pitches[2], yv12_frame->pitches[2], chroma_radius, chroma_power); vBlur(out_frame->base[0], out_frame->base[0], yv12_frame->width, yv12_frame->height, out_frame->pitches[0], out_frame->pitches[0], this->params.luma_radius, this->params.luma_power); vBlur(out_frame->base[1], out_frame->base[1], cw,ch, out_frame->pitches[1], out_frame->pitches[1], chroma_radius, chroma_power); vBlur(out_frame->base[2], out_frame->base[2], cw,ch, out_frame->pitches[2], out_frame->pitches[2], chroma_radius, chroma_power); pthread_mutex_unlock (&this->lock); skip = out_frame->draw(out_frame, stream); _x_post_frame_copy_up(frame, out_frame); out_frame->free(out_frame); yv12_frame->free(yv12_frame); } else { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); } return skip; } static post_plugin_t *boxblur_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_boxblur_t *this = calloc(1, sizeof(post_plugin_boxblur_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post, 0, 1); this->params.luma_radius = 2; this->params.luma_power = 1; this->params.chroma_radius = -1; this->params.chroma_power = -1; pthread_mutex_init(&this->lock, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->intercept_frame = boxblur_intercept_frame; port->new_frame->draw = boxblur_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "boxblured video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = boxblur_dispose; return &this->post; } void *boxblur_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_boxblur_class = { .open_plugin = boxblur_open_plugin, .identifier = "boxblur", .description = N_("box blur filter from mplayer"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_boxblur_class; } �������������������������������������������������xine-lib-1.2/src/post/planar/pp.c�������������������������������������������������������������������0000644�0001750�0001750�00000021554�14647725152�014507� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * plugin for ffmpeg libpostprocess */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #ifdef HAVE_FFMPEG_AVUTIL_H # include <postprocess.h> #else # include <libpostproc/postprocess.h> #endif #include <pthread.h> #if LIBPOSTPROC_VERSION_MAJOR < 52 # define pp_context pp_context_t # define pp_mode pp_mode_t # define PP_PARAMETERS_T #endif #define PP_STRING_SIZE 256 /* size of pp mode string (including all options) */ typedef struct post_plugin_pp_s post_plugin_pp_t; /* * this is the struct used by "parameters api" */ typedef struct pp_parameters_s { int quality; char mode[PP_STRING_SIZE]; } pp_parameters_t; /* * description of params struct */ START_PARAM_DESCR( pp_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, quality, NULL, 0, PP_QUALITY_MAX, 0, "postprocessing quality" ) PARAM_ITEM( POST_PARAM_TYPE_CHAR, mode, NULL, 0, 0, 0, "mode string (overwrites all other options except quality)" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_pp_s { post_plugin_t post; /* private data */ int frame_width; int frame_height; pp_parameters_t params; /* libpostproc specific stuff */ int pp_flags; pp_context *our_context; pp_mode *our_mode; pthread_mutex_t lock; }; static int set_parameters (xine_post_t *this_gen, const void *param_gen) { #ifdef PP_PARAMETERS_T post_plugin_pp_t *this = (post_plugin_pp_t *)this_gen; const pp_parameters_t *param = (const pp_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); memcpy( &this->params, param, sizeof(pp_parameters_t) ); pthread_mutex_unlock (&this->lock); #else (void)this_gen; (void)param_gen; #endif return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { #ifdef PP_PARAMETERS_T post_plugin_pp_t *this = (post_plugin_pp_t *)this_gen; pp_parameters_t *param = (pp_parameters_t *)param_gen; memcpy( param, &this->params, sizeof(pp_parameters_t) ); #else (void)this_gen; (void)param_gen; #endif return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { static char *help = NULL; if( !help ) { help = _x_asprintf("%s%s%s", _("FFmpeg libpostprocess plugin.\n" "\n" "Parameters\n" "\n"), pp_help, _("\n" "* libpostprocess (C) Michael Niedermayer\n") ); } return help; } static void pp_dispose(post_plugin_t *this_gen) { post_plugin_pp_t *this = (post_plugin_pp_t *)this_gen; if (_x_post_dispose(this_gen)) { if(this->our_mode) { pp_free_mode(this->our_mode); this->our_mode = NULL; } if(this->our_context) { pp_free_context(this->our_context); this->our_context = NULL; } free(this); } } static int pp_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2); } static int pp_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_pp_t *this = (post_plugin_pp_t *)port->post; vo_frame_t *out_frame; vo_frame_t *yv12_frame; int skip; int pp_flags; if( !frame->bad_frame ) { /* convert to YV12 if needed */ if( frame->format != XINE_IMGFMT_YV12 ) { yv12_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, yv12_frame); yuy2_to_yv12(frame->base[0], frame->pitches[0], yv12_frame->base[0], yv12_frame->pitches[0], yv12_frame->base[1], yv12_frame->pitches[1], yv12_frame->base[2], yv12_frame->pitches[2], frame->width, frame->height); } else { yv12_frame = frame; yv12_frame->lock(yv12_frame); } out_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, out_frame); pthread_mutex_lock (&this->lock); if( !this->our_context || this->frame_width != yv12_frame->width || this->frame_height != yv12_frame->height ) { this->frame_width = yv12_frame->width; this->frame_height = yv12_frame->height; pp_flags = this->pp_flags; if(this->our_context) pp_free_context(this->our_context); this->our_context = pp_get_context(frame->width, frame->height, pp_flags); if(this->our_mode) { pp_free_mode(this->our_mode); this->our_mode = NULL; } } if(!this->our_mode) this->our_mode = pp_get_mode_by_name_and_quality(this->params.mode, this->params.quality); if(this->our_mode) pp_postprocess((const uint8_t **)yv12_frame->base, yv12_frame->pitches, out_frame->base, out_frame->pitches, (frame->width+7)&(~7), frame->height, NULL, 0, this->our_mode, this->our_context, 0 /*this->av_frame->pict_type*/); pthread_mutex_unlock (&this->lock); if(this->our_mode) { skip = out_frame->draw(out_frame, stream); _x_post_frame_copy_up(frame, out_frame); } else { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); } out_frame->free(out_frame); yv12_frame->free(yv12_frame); } else { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); } return skip; } static post_plugin_t *pp_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_pp_t *this = calloc(1, sizeof(post_plugin_pp_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; #if defined(ARCH_X86) uint32_t cpu_caps; #endif static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post, 0, 1); this->params.quality = 3; strcpy(this->params.mode, "de"); this->pp_flags = PP_FORMAT_420; #if defined(ARCH_X86) /* Detect what cpu accel we have */ cpu_caps = xine_mm_accel(); if(cpu_caps & MM_ACCEL_X86_MMX) this->pp_flags |= PP_CPU_CAPS_MMX; if(cpu_caps & MM_ACCEL_X86_MMXEXT) this->pp_flags |= PP_CPU_CAPS_MMX2; if(cpu_caps & MM_ACCEL_X86_3DNOW) this->pp_flags |= PP_CPU_CAPS_3DNOW; #endif this->our_mode = NULL; this->our_context = NULL; pthread_mutex_init (&this->lock, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->intercept_frame = pp_intercept_frame; port->new_frame->draw = pp_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "pped video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = pp_dispose; return &this->post; } void *pp_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_pp_class = { .open_plugin = pp_open_plugin, .identifier = "pp", .description = N_("plugin for ffmpeg libpostprocess"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_pp_class; } ����������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/planar/eq2.c������������������������������������������������������������������0000644�0001750�0001750�00000037040�14647725152�014554� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * mplayer's eq2 (soft video equalizer) * Software equalizer (brightness, contrast, gamma, saturation) * * Hampa Hug <hampa@hampa.ch> (original LUT gamma/contrast/brightness filter) * Daniel Moreno <comac@comac.darktech.org> (saturation, R/G/B gamma support) * Richard Felker (original MMX contrast/brightness code (vf_eq.c)) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "planar.h" #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #include <math.h> #include <pthread.h> /* Per channel parameters */ typedef struct eq2_param_t { unsigned char lut[256]; int lut_clean; void (*adjust) (struct eq2_param_t *par, unsigned char *dst, unsigned char *src, unsigned w, unsigned h, unsigned dstride, unsigned sstride); double c; double b; double g; } eq2_param_t; typedef struct vf_priv_s { eq2_param_t param[3]; double contrast; double brightness; double saturation; double gamma; double rgamma; double ggamma; double bgamma; unsigned buf_w[3]; unsigned buf_h[3]; unsigned char *buf[3]; } vf_eq2_t; static void create_lut (eq2_param_t *par) { unsigned i; double g, v; g = par->g; if ((g < 0.001) || (g > 1000.0)) { g = 1.0; } g = 1.0 / g; for (i = 0; i < 256; i++) { v = (double) i / 255.0; v = par->c * (v - 0.5) + 0.5 + par->b; if (v <= 0.0) { par->lut[i] = 0; } else { v = pow (v, g); if (v >= 1.0) { par->lut[i] = 255; } else { par->lut[i] = (unsigned char) (256.0 * v); } } } par->lut_clean = 1; } #if defined(ARCH_X86) #if defined(ARCH_X86_64) # define MEM1(reg) "(%"reg")" # define BUMPPTR(offs,reg) "\n\tleaq\t"offs"(%"reg"), %"reg #elif defined(ARCH_X86_X32) # define MEM1(reg) "(%q"reg")" # define BUMPPTR(offs,reg) "\n\tleaq\t"offs"(%q"reg"), %q"reg #else # define MEM1(reg) "(%"reg")" # define BUMPPTR(offs,reg) "\n\tleal\t"offs"(%"reg"), %"reg #endif static void affine_1d_MMX (eq2_param_t *par, unsigned char *dst, unsigned char *src, unsigned w, unsigned h, unsigned dstride, unsigned sstride) { unsigned i; int contrast, brightness; unsigned dstep, sstep; int pel; short brvec[4]; short contvec[4]; contrast = (int) (par->c * 256 * 16); brightness = ((int) (100.0 * par->b + 100.0) * 511) / 200 - 128 - contrast / 32; brvec[0] = brvec[1] = brvec[2] = brvec[3] = brightness; contvec[0] = contvec[1] = contvec[2] = contvec[3] = contrast; sstep = sstride - w; dstep = dstride - w; __asm__ __volatile__ ( "\n\tmovq\t"MEM1("0")", %%mm3" "\n\tmovq\t"MEM1("1")", %%mm4" "\n\tpxor\t%%mm0, %%mm0" : : "r" (brvec), "r" (contvec) ); while (h-- > 0) { __asm__ __volatile__ ( "\n\tmovl\t%4, %%eax" "\n\t"ASMALIGN(4) "\n1:" "\n\tmovq\t"MEM1("0")", %%mm1" "\n\tmovq\t"MEM1("0")", %%mm2" "\n\tpunpcklbw\t%%mm0, %%mm1" "\n\tpunpckhbw\t%%mm0, %%mm2" "\n\tpsllw\t$4, %%mm1" "\n\tpsllw\t$4, %%mm2" "\n\tpmulhw\t%%mm4, %%mm1" "\n\tpmulhw\t%%mm4, %%mm2" "\n\tpaddw\t%%mm3, %%mm1" "\n\tpaddw\t%%mm3, %%mm2" "\n\tpackuswb\t%%mm2, %%mm1" BUMPPTR("8","0") "\n\tmovq\t%%mm1, "MEM1("1") BUMPPTR("8","1") "\n\tdecl\t%%eax" "\n\tjnz\t1b" : "=r" (src), "=r" (dst) : "0" (src), "1" (dst), "r" (w >> 3) : "%eax" ); for (i = w & 7; i > 0; i--) { pel = ((*src++ * contrast) >> 12) + brightness; if (pel & 768) { pel = (-pel) >> 31; } *dst++ = pel; } src += sstep; dst += dstep; } __asm__ __volatile__ ( "emms \n\t" ::: "memory" ); } #endif static void apply_lut (eq2_param_t *par, unsigned char *dst, unsigned char *src, unsigned w, unsigned h, unsigned dstride, unsigned sstride) { unsigned i, j; unsigned char *lut; if (!par->lut_clean) { create_lut (par); } lut = par->lut; for (j = 0; j < h; j++) { for (i = 0; i < w; i++) { dst[i] = lut[src[i]]; } src += sstride; dst += dstride; } } static void check_values (eq2_param_t *par) { /* yuck! floating point comparisons... */ if ((par->c == 1.0) && (par->b == 0.0) && (par->g == 1.0)) { par->adjust = NULL; } #if defined(ARCH_X86) else if (par->g == 1.0 && (xine_mm_accel() & MM_ACCEL_X86_MMX) ) { par->adjust = &affine_1d_MMX; } #endif else { par->adjust = &apply_lut; } } static void set_contrast (vf_eq2_t *eq2, double c) { eq2->contrast = c; eq2->param[0].c = c; eq2->param[0].lut_clean = 0; check_values (&eq2->param[0]); } static void set_brightness (vf_eq2_t *eq2, double b) { eq2->brightness = b; eq2->param[0].b = b; eq2->param[0].lut_clean = 0; check_values (&eq2->param[0]); } static void set_gamma (vf_eq2_t *eq2, double g) { eq2->gamma = g; eq2->param[0].g = eq2->gamma * eq2->ggamma; eq2->param[1].g = sqrt (eq2->bgamma / eq2->ggamma); eq2->param[2].g = sqrt (eq2->rgamma / eq2->ggamma); eq2->param[0].lut_clean = 0; eq2->param[1].lut_clean = 0; eq2->param[2].lut_clean = 0; check_values (&eq2->param[0]); check_values (&eq2->param[1]); check_values (&eq2->param[2]); } static void set_saturation (vf_eq2_t *eq2, double s) { eq2->saturation = s; eq2->param[1].c = s; eq2->param[2].c = s; eq2->param[1].lut_clean = 0; eq2->param[2].lut_clean = 0; check_values (&eq2->param[1]); check_values (&eq2->param[2]); } typedef struct post_plugin_eq2_s post_plugin_eq2_t; /* * this is the struct used by "parameters api" */ typedef struct eq2_parameters_s { double gamma; double contrast; double brightness; double saturation; double rgamma; double ggamma; double bgamma; } eq2_parameters_t; /* * description of params struct */ START_PARAM_DESCR( eq2_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, gamma, NULL, 0, 5, 0, "gamma" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, brightness, NULL, -1, 1, 0, "brightness" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, contrast, NULL, 0, 2, 0, "contrast" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, saturation, NULL, 0, 2, 0, "saturation" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, rgamma, NULL, 0, 5, 0, "rgamma" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, ggamma, NULL, 0, 5, 0, "ggamma" ) PARAM_ITEM( POST_PARAM_TYPE_DOUBLE, bgamma, NULL, 0, 5, 0, "bgamma" ) END_PARAM_DESCR( param_descr ) /* plugin structure */ struct post_plugin_eq2_s { post_plugin_t post; /* private data */ eq2_parameters_t params; vf_eq2_t eq2; pthread_mutex_t lock; }; static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_eq2_t *this = (post_plugin_eq2_t *)this_gen; const eq2_parameters_t *param = (const eq2_parameters_t *)param_gen; vf_eq2_t *eq2 = &this->eq2; pthread_mutex_lock (&this->lock); if( &this->params != param ) memcpy( &this->params, param, sizeof(eq2_parameters_t) ); eq2->rgamma = param->rgamma; eq2->ggamma = param->ggamma; eq2->bgamma = param->bgamma; set_gamma (eq2, param->gamma); set_contrast (eq2, param->contrast); set_brightness (eq2, param->brightness); set_saturation (eq2, param->saturation); pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_eq2_t *this = (post_plugin_eq2_t *)this_gen; eq2_parameters_t *param = (eq2_parameters_t *)param_gen; memcpy( param, &this->params, sizeof(eq2_parameters_t) ); return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_help (void) { return _("Alternative software equalizer that uses lookup tables (very slow), " "allowing gamma correction in addition to simple brightness, " "contrast and saturation adjustment.\n" "Note that it uses the same MMX optimized code as 'eq' if all " "gamma values are 1.0.\n" "\n" "Parameters\n" " gamma\n" " brightness\n" " contrast\n" " saturation\n" " rgamma (gamma for the red component)\n" " ggamma (gamma for the green component)\n" " bgamma (gamma for the blue component)\n" "\n" "Value ranges are 0.1 - 10 for gammas, -2 - 2 for contrast " "(negative values result in a negative image), -1 - 1 for " "brightness and 0 - 3 for saturation.\n" "\n" "* mplayer's eq2 (C) Hampa Hug, Daniel Moreno, Richard Felker\n" ); } static void eq2_dispose(post_plugin_t *this_gen) { post_plugin_eq2_t *this = (post_plugin_eq2_t *)this_gen; if (_x_post_dispose(this_gen)) { pthread_mutex_destroy(&this->lock); free(this); } } static int eq2_get_property(xine_video_port_t *port_gen, int property) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_eq2_t *this = (post_plugin_eq2_t *)port->post; if( property == XINE_PARAM_VO_BRIGHTNESS ) return 65535 * (this->params.brightness + 1.0) / 2.0; else if( property == XINE_PARAM_VO_CONTRAST ) return 65535 * (this->params.contrast) / 2.0; else if( property == XINE_PARAM_VO_SATURATION ) return 65535 * (this->params.saturation) / 2.0; else return port->original_port->get_property(port->original_port, property); } static int eq2_set_property(xine_video_port_t *port_gen, int property, int value) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_eq2_t *this = (post_plugin_eq2_t *)port->post; if( property == XINE_PARAM_VO_BRIGHTNESS ) { this->params.brightness = (2.0 * value / 65535) - 1.0; set_parameters ((xine_post_t *)this, &this->params); return value; } else if( property == XINE_PARAM_VO_CONTRAST ) { this->params.contrast = (2.0 * value / 65535); set_parameters ((xine_post_t *)this, &this->params); return value; } else if( property == XINE_PARAM_VO_SATURATION ) { this->params.saturation = (2.0 * value / 65535); set_parameters ((xine_post_t *)this, &this->params); return value; } else return port->original_port->set_property(port->original_port, property, value); } static int eq2_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; return (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2); } static int eq2_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_eq2_t *this = (post_plugin_eq2_t *)port->post; vo_frame_t *out_frame; vo_frame_t *yv12_frame; vf_eq2_t *eq2 = &this->eq2; int skip; int i; if( !frame->bad_frame && (eq2->param[0].adjust || eq2->param[1].adjust || eq2->param[2].adjust) ) { /* convert to YV12 if needed */ if( frame->format != XINE_IMGFMT_YV12 ) { yv12_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, yv12_frame); yuy2_to_yv12(frame->base[0], frame->pitches[0], yv12_frame->base[0], yv12_frame->pitches[0], yv12_frame->base[1], yv12_frame->pitches[1], yv12_frame->base[2], yv12_frame->pitches[2], frame->width, frame->height); } else { yv12_frame = frame; yv12_frame->lock(yv12_frame); } out_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YV12, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, out_frame); pthread_mutex_lock (&this->lock); for (i = 0; i < 3; i++) { int height, width; height = (i==0) ? frame->height : frame->height/2; width = (i==0) ? frame->width : frame->width/2; if (eq2->param[i].adjust != NULL) { eq2->param[i].adjust (&eq2->param[i], out_frame->base[i], yv12_frame->base[i], width, height, out_frame->pitches[i], yv12_frame->pitches[i]); } else { xine_fast_memcpy(out_frame->base[i],yv12_frame->base[i], yv12_frame->pitches[i] * height); } } pthread_mutex_unlock (&this->lock); skip = out_frame->draw(out_frame, stream); _x_post_frame_copy_up(frame, out_frame); out_frame->free(out_frame); yv12_frame->free(yv12_frame); } else { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); } return skip; } static post_plugin_t *eq2_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_eq2_t *this = calloc(1, sizeof(post_plugin_eq2_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; _x_post_init(&this->post, 0, 1); memset(&this->eq2, 0, sizeof(this->eq2)); this->eq2.gamma = this->params.gamma = 1.0; this->eq2.contrast = this->params.contrast = 1.0; this->eq2.brightness = this->params.brightness = 0.0; this->eq2.saturation = this->params.saturation = 1.0; this->eq2.rgamma = this->params.rgamma = 1.0; this->eq2.ggamma = this->params.ggamma = 1.0; this->eq2.bgamma = this->params.bgamma = 1.0; pthread_mutex_init(&this->lock, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->new_port.get_property = eq2_get_property; port->new_port.set_property = eq2_set_property; port->intercept_frame = eq2_intercept_frame; port->new_frame->draw = eq2_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "eqd video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = eq2_dispose; set_parameters ((xine_post_t *)this, &this->params); return &this->post; } void *eq2_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_eq2_class = { .open_plugin = eq2_open_plugin, .identifier = "eq2", .description = N_("Software video equalizer"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_eq2_class; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014717� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/deinterlace.h�����������������������������������������������������0000644�0001750�0001750�00000012535�14647725152�017355� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (C) 2002, 2005 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifndef DEINTERLACE_H_INCLUDED #define DEINTERLACE_H_INCLUDED #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #ifdef __cplusplus extern "C" { #endif /** * Our deinterlacer plugin API is modeled after DScaler's. This module * represents the API that all deinterlacer plugins must export, and * also provides a registration mechanism for the application to be able * to iterate through available plugins and select an appropriate one. */ typedef struct deinterlace_method_s deinterlace_method_t; typedef struct deinterlace_scanline_data_s deinterlace_scanline_data_t; typedef struct deinterlace_frame_data_s deinterlace_frame_data_t; /** * There are two scanline functions that every deinterlacer plugin * must implement to do its work: one for a 'copy' and one for * an 'interpolate' for the currently active field. This so so that * while plugins may be delaying fields, the external API assumes that * the plugin is completely realtime. * * Each deinterlacing routine can require data from up to four fields. * The most recent field captured is field 0, and increasing numbers go * backwards in time. */ struct deinterlace_scanline_data_s { uint8_t *tt0, *t0, *m0, *b0, *bb0; uint8_t *tt1, *t1, *m1, *b1, *bb1; uint8_t *tt2, *t2, *m2, *b2, *bb2; uint8_t *tt3, *t3, *m3, *b3, *bb3; int bottom_field; /* xv frame bufs may have no padding. Dont prefetch over the end. */ int bytes_left; }; /** * | t-3 t-2 t-1 t * | Field 3 | Field 2 | Field 1 | Field 0 | * | TT3 | | TT1 | | * | | T2 | | T0 | * | M3 | | M1 | | * | | B2 | | B0 | * | BB3 | | BB1 | | * * While all pointers are passed in, each plugin is only guarenteed for * the ones it indicates it requires (in the fields_required parameter) * to be available. * * Pointers are always to scanlines in the standard packed 4:2:2 format. */ typedef void (*deinterlace_interp_scanline_t)( uint8_t *output, deinterlace_scanline_data_t *data, int width ); /** * For the copy scanline, the API is basically the same, except that * we're given a scanline to 'copy'. * * | t-3 t-2 t-1 t * | Field 3 | Field 2 | Field 1 | Field 0 | * | | TT2 | | TT0 | * | T3 | | T1 | | * | | M2 | | M0 | * | B3 | | B1 | | * | | BB2 | | BB0 | */ typedef void (*deinterlace_copy_scanline_t)( uint8_t *output, deinterlace_scanline_data_t *data, int width ); /** * The frame function is for deinterlacing plugins that can only act * on whole frames, rather than on a scanline at a time. */ struct deinterlace_frame_data_s { uint8_t *f0; uint8_t *f1; uint8_t *f2; uint8_t *f3; }; /** * Note: second_field is used in xine. For tvtime it should be the same as bottom_field. */ typedef void (*deinterlace_frame_t)( uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ); /** * This structure defines the deinterlacer plugin. */ struct deinterlace_method_s { const char *name; const char *short_name; int fields_required; int accelrequired; int doscalerbob; int scanlinemode; deinterlace_interp_scanline_t interpolate_scanline; deinterlace_copy_scanline_t copy_scanline; deinterlace_frame_t deinterlace_frame; int delaysfield; /* xine: this method delays output by one field relative to input */ const char *description; }; typedef struct methodlist_item_s * deinterlace_methods_t; /** * Registers a new deinterlace method. */ void register_deinterlace_method( deinterlace_methods_t *, const deinterlace_method_t *method ); /** * Returns how many deinterlacing methods are available. */ int get_num_deinterlace_methods( deinterlace_methods_t ); /** * Returns the specified method in the list. */ const deinterlace_method_t *get_deinterlace_method( deinterlace_methods_t, int i ); /** * Builds the usable method list. */ void filter_deinterlace_methods( deinterlace_methods_t *, int accel, int fieldsavailable ); void free_deinterlace_methods( deinterlace_methods_t * ); #ifdef __cplusplus }; #endif #endif /* DEINTERLACE_H_INCLUDED */ �������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/xine_plugin.c�����������������������������������������������������0000644�0001750�0001750�00000105052�14647725152�017407� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * advanced video deinterlacer plugin * Jun/2003 by Miguel Freitas * * heavily based on tvtime.sf.net by Billy Biggs */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* #define LOG */ #include <xine/xine_internal.h> #include <xine/post.h> #include <xine/xineutils.h> #include <xine/xine_buffer.h> #include <pthread.h> #include "tvtime.h" #include "speedy.h" #include "deinterlace.h" #include "plugins/plugins.h" typedef struct post_plugin_deinterlace_s post_plugin_deinterlace_t; #define MAX_NUM_METHODS 30 static const char *enum_methods[MAX_NUM_METHODS]; static const char *const enum_pulldown[] = { "none", "vektor", NULL }; static const char *const enum_framerate[] = { "full", "half_top", "half_bottom", NULL }; static void *help_string; /* * this is the struct used by "parameters api" */ typedef struct deinterlace_parameters_s { int method; int enabled; int pulldown; int pulldown_error_wait; int framerate_mode; int judder_correction; int use_progressive_frame_flag; int chroma_filter; int cheap_mode; } deinterlace_parameters_t; /* * description of params struct */ START_PARAM_DESCR( deinterlace_parameters_t ) PARAM_ITEM( POST_PARAM_TYPE_INT, method, (char **)enum_methods, 0, 0, 0, "deinterlace method" ) PARAM_ITEM( POST_PARAM_TYPE_BOOL, enabled, NULL, 0, 1, 0, "enable/disable" ) PARAM_ITEM( POST_PARAM_TYPE_INT, pulldown, (char **)enum_pulldown, 0, 0, 0, "pulldown algorithm" ) PARAM_ITEM( POST_PARAM_TYPE_INT, pulldown_error_wait, NULL, 0, 0, 0, "number of frames of telecine pattern sync required before mode change" ) PARAM_ITEM( POST_PARAM_TYPE_INT, framerate_mode, (char **)enum_framerate, 0, 0, 0, "framerate output mode" ) PARAM_ITEM( POST_PARAM_TYPE_BOOL, judder_correction, NULL, 0, 1, 0, "make frames evenly spaced for film mode (24 fps)" ) PARAM_ITEM( POST_PARAM_TYPE_BOOL, use_progressive_frame_flag, NULL, 0, 1, 0, "disable deinterlacing when progressive_frame flag is set" ) PARAM_ITEM( POST_PARAM_TYPE_BOOL, chroma_filter, NULL, 0, 1, 0, "apply chroma filter after deinterlacing" ) PARAM_ITEM( POST_PARAM_TYPE_BOOL, cheap_mode, NULL, 0, 1, 0, "skip image format conversion - cheaper but not 100% correct" ) END_PARAM_DESCR( param_descr ) #define NUM_RECENT_FRAMES 2 #define FPS_24_DURATION 3754 #define FRAMES_TO_SYNC 20 typedef struct post_class_deinterlace_s { post_class_t class; deinterlace_methods_t methods; } post_class_deinterlace_t; /* plugin structure */ struct post_plugin_deinterlace_s { post_plugin_t post; /* private data */ int cur_method; int enabled; int pulldown; int framerate_mode; int judder_correction; int use_progressive_frame_flag; int chroma_filter; int cheap_mode; tvtime_t *tvtime; int tvtime_changed; int tvtime_last_filmmode; int vo_deinterlace_enabled; int framecounter; uint8_t rff_pattern; vo_frame_t *recent_frame[NUM_RECENT_FRAMES]; pthread_mutex_t lock; post_class_deinterlace_t *class; }; static void _flush_frames(post_plugin_deinterlace_t *this) { int i; for( i = 0; i < NUM_RECENT_FRAMES; i++ ) { if( this->recent_frame[i] ) { this->recent_frame[i]->free(this->recent_frame[i]); this->recent_frame[i] = NULL; } } this->tvtime_changed++; } static int set_parameters (xine_post_t *this_gen, const void *param_gen) { post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)this_gen; const deinterlace_parameters_t *param = (const deinterlace_parameters_t *)param_gen; pthread_mutex_lock (&this->lock); if( this->enabled != param->enabled || this->cheap_mode != param->cheap_mode ) _flush_frames(this); this->cur_method = param->method; this->enabled = param->enabled; this->pulldown = param->pulldown; this->tvtime->pulldown_error_wait = param->pulldown_error_wait; this->framerate_mode = param->framerate_mode; this->judder_correction = param->judder_correction; this->use_progressive_frame_flag = param->use_progressive_frame_flag; this->chroma_filter = param->chroma_filter; this->cheap_mode = param->cheap_mode; this->tvtime_changed++; pthread_mutex_unlock (&this->lock); return 1; } static int get_parameters (xine_post_t *this_gen, void *param_gen) { post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)this_gen; deinterlace_parameters_t *param = (deinterlace_parameters_t *)param_gen; param->method = this->cur_method; param->enabled = this->enabled; param->pulldown = this->pulldown; param->pulldown_error_wait = this->tvtime->pulldown_error_wait; param->framerate_mode = this->framerate_mode; param->judder_correction = this->judder_correction; param->use_progressive_frame_flag = this->use_progressive_frame_flag; param->chroma_filter = this->chroma_filter; param->cheap_mode = this->cheap_mode; return 1; } static xine_post_api_descr_t * get_param_descr (void) { return ¶m_descr; } static char * get_static_help (void) { return _("Advanced tvtime/deinterlacer plugin with pulldown detection\n" "This plugin aims to provide deinterlacing mechanisms comparable " "to high quality progressive DVD players and so called " "line-doublers, for use with computer monitors, projectors and " "other progressive display devices.\n" "\n" "Parameters\n" "\n" " Method: Select deinterlacing method/algorithm to use, see below for " "explanation of each method.\n" "\n" " Enabled: Enable/disable the plugin.\n" "\n" " Pulldown_error_wait: Ensures that the telecine pattern has been " "locked for this many frames before changing to filmmode.\n" "\n" " Pulldown: Choose the 2-3 pulldown detection algorithm. 24 FPS films " "that have being converted to NTSC can be detected and intelligently " "reconstructed to their original (non-interlaced) frames.\n" "\n" " Framerate_mode: Selecting 'full' will deinterlace every field " "to an unique frame for television quality and beyond. This feature will " "effetively double the frame rate, improving smoothness. Note, however, " "that full 59.94 FPS is not possible with plain 2.4 Linux kernel (that " "use a timer interrupt frequency of 100Hz). Newer RedHat and 2.6 kernels " "use higher HZ settings (512 and 1000, respectively) and should work fine.\n" "\n" " Judder_correction: Once 2-3 pulldown is enabled and a film material " "is detected, it is possible to reduce the frame rate to original rate " "used (24 FPS). This will make the frames evenly spaced in time, " "matching the speed they were shot and eliminating the judder effect.\n" "\n" " Use_progressive_frame_flag: Well mastered MPEG2 streams uses a flag " "to indicate progressive material. This setting control whether we trust " "this flag or not (some rare and buggy mpeg2 streams set it wrong).\n" "\n" " Chroma_filter: DVD/MPEG2 use an interlaced image format that has " "a very poor vertical chroma resolution. Upsampling the chroma for purposes " "of deinterlacing may cause some artifacts to occur (eg. colour stripes). Use " "this option to blur the chroma vertically after deinterlacing to remove " "the artifacts. Warning: cpu intensive.\n" "\n" " Cheap_mode: This will skip the expensive YV12->YUY2 image conversion, " "tricking tvtime/dscaler routines like if they were still handling YUY2 " "images. Of course, this is not correct, not all pixels will be evaluated " "by the algorithms to decide the regions to deinterlace and chroma will be " "processed separately. Nevertheless, it allows people with not so fast " "systems to try deinterlace algorithms, in a tradeoff between quality " "and cpu usage.\n" "\n" "* Uses several algorithms from tvtime and dscaler projects.\n" "Deinterlacing methods: (Not all methods are available for all platforms)\n" "\n" ); } static char * get_help (void) { return (char *)help_string; } /* plugin class functions */ static post_plugin_t *deinterlace_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target); static void deinterlace_class_dispose(post_class_t *class_gen); /* plugin instance functions */ static void deinterlace_dispose(post_plugin_t *this_gen); /* replaced video_port functions */ static int deinterlace_get_property(xine_video_port_t *port_gen, int property); static int deinterlace_set_property(xine_video_port_t *port_gen, int property, int value); static void deinterlace_flush(xine_video_port_t *port_gen); static void deinterlace_open(xine_video_port_t *port_gen, xine_stream_t *stream); static void deinterlace_close(xine_video_port_t *port_gen, xine_stream_t *stream); /* frame intercept check */ static int deinterlace_intercept_frame(post_video_port_t *port, vo_frame_t *frame); /* replaced vo_frame functions */ static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream); static void *deinterlace_init_plugin(xine_t *xine, const void *data) { post_class_deinterlace_t *class = calloc(1, sizeof(post_class_deinterlace_t)); uint32_t config_flags = xine_mm_accel(); int i; if (!class) return NULL; (void)data; class->class.open_plugin = deinterlace_open_plugin; class->class.identifier = "tvtime"; class->class.description = N_("advanced deinterlacer plugin with pulldown detection"); class->class.dispose = deinterlace_class_dispose; setup_speedy_calls(xine_mm_accel(),0); register_deinterlace_method( &class->methods, linear_get_method() ); register_deinterlace_method( &class->methods, linearblend_get_method() ); register_deinterlace_method( &class->methods, greedy_get_method() ); register_deinterlace_method( &class->methods, greedy2frame_get_method() ); register_deinterlace_method( &class->methods, weave_get_method() ); register_deinterlace_method( &class->methods, double_get_method() ); register_deinterlace_method( &class->methods, vfir_get_method() ); register_deinterlace_method( &class->methods, scalerbob_get_method() ); register_deinterlace_method( &class->methods, dscaler_greedyh_get_method() ); register_deinterlace_method( &class->methods, dscaler_tomsmocomp_get_method() ); filter_deinterlace_methods( &class->methods, config_flags, 5 /*fieldsavailable*/ ); if( !get_num_deinterlace_methods( class->methods ) ) { xprintf(xine, XINE_VERBOSITY_LOG, _("tvtime: No deinterlacing methods available, exiting.\n")); free(class); return NULL; } help_string = xine_buffer_init(1024); xine_buffer_strcat( help_string, get_static_help() ); enum_methods[0] = "use_vo_driver"; for(i = 0; i < get_num_deinterlace_methods( class->methods ); i++ ) { const deinterlace_method_t *method; method = get_deinterlace_method( class->methods, i ); enum_methods[i+1] = method->short_name; xine_buffer_strcat( help_string, "[" ); xine_buffer_strcat( help_string, method->short_name ); xine_buffer_strcat( help_string, "] " ); xine_buffer_strcat( help_string, method->name ); xine_buffer_strcat( help_string, ":\n" ); if (method->description) xine_buffer_strcat( help_string, method->description ); xine_buffer_strcat( help_string, "\n---\n" ); } enum_methods[i+1] = NULL; return &class->class; } static post_plugin_t *deinterlace_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_deinterlace_t *this = calloc(1, sizeof(post_plugin_deinterlace_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; tvtime_t *tvtime; static const xine_post_api_t post_api = { .set_parameters = set_parameters, .get_parameters = get_parameters, .get_param_descr = get_param_descr, .get_help = get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; /* Some default values */ static const deinterlace_parameters_t init_param = { .method = 1, /* First (plugin) method available */ .enabled = 1, .pulldown = 1, /* vektor */ .pulldown_error_wait = 60, /* about one second */ .framerate_mode = 0, /* full */ .judder_correction = 1, .use_progressive_frame_flag = 1, .chroma_filter = 0, .cheap_mode = 0, }; if (!this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)inputs; (void)audio_target; tvtime = tvtime_new_context(); if (!tvtime) { free(this); return NULL; } _x_post_init(&this->post, 0, 1); this->tvtime = tvtime; this->tvtime_changed++; this->tvtime_last_filmmode = 0; this->class = (post_class_deinterlace_t *)class_gen; pthread_mutex_init (&this->lock, NULL); set_parameters (&this->post.xine_post, &init_param); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); /* replace with our own get_frame function */ port->new_port.open = deinterlace_open; port->new_port.close = deinterlace_close; port->new_port.get_property = deinterlace_get_property; port->new_port.set_property = deinterlace_set_property; port->new_port.flush = deinterlace_flush; port->intercept_frame = deinterlace_intercept_frame; port->new_frame->draw = deinterlace_draw; xine_list_push_back(this->post.input, (void *)¶ms_input); input->xine_in.name = "video"; output->xine_out.name = "deinterlaced video"; this->post.xine_post.video_input[0] = &port->new_port; this->post.dispose = deinterlace_dispose; return &this->post; } static void deinterlace_class_dispose(post_class_t *class_gen) { post_class_deinterlace_t *class = (post_class_deinterlace_t *)class_gen; xine_buffer_free(help_string); help_string = NULL; free_deinterlace_methods( &class->methods ); free(class_gen); } static void deinterlace_dispose(post_plugin_t *this_gen) { post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)this_gen; if (_x_post_dispose(this_gen)) { _flush_frames(this); pthread_mutex_destroy(&this->lock); free(this->tvtime); free(this); } } static int deinterlace_get_property(xine_video_port_t *port_gen, int property) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; if( property == XINE_PARAM_VO_DEINTERLACE && this->cur_method ) return this->enabled; else return port->original_port->get_property(port->original_port, property); } static int deinterlace_set_property(xine_video_port_t *port_gen, int property, int value) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; if( property == XINE_PARAM_VO_DEINTERLACE ) { pthread_mutex_lock (&this->lock); if( this->enabled != value ) _flush_frames(this); this->enabled = value; pthread_mutex_unlock (&this->lock); this->vo_deinterlace_enabled = this->enabled && (!this->cur_method); port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, this->vo_deinterlace_enabled); return this->enabled; } else return port->original_port->set_property(port->original_port, property, value); } static void deinterlace_flush(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; _flush_frames(this); port->original_port->flush(port->original_port); } static void deinterlace_open(xine_video_port_t *port_gen, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; (port->original_port->open) (port->original_port, stream); this->vo_deinterlace_enabled = !this->cur_method; port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, this->vo_deinterlace_enabled); } static void deinterlace_close(xine_video_port_t *port_gen, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)port_gen; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; port->stream = NULL; _flush_frames(this); port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, 0); port->original_port->close(port->original_port, stream); _x_post_dec_usage(port); } static int deinterlace_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; int vo_deinterlace_enabled = 0; vo_deinterlace_enabled = ( frame->format != XINE_IMGFMT_YV12 && frame->format != XINE_IMGFMT_YUY2 && this->enabled ); if( this->cur_method && this->vo_deinterlace_enabled != vo_deinterlace_enabled ) { this->vo_deinterlace_enabled = vo_deinterlace_enabled; port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, this->vo_deinterlace_enabled); } return (this->enabled && this->cur_method && (frame->flags & VO_INTERLACED_FLAG) && (frame->format == XINE_IMGFMT_YV12 || frame->format == XINE_IMGFMT_YUY2) ); } static void apply_chroma_filter( uint8_t *data, int stride, int width, int height ) { int i; /* ok, using linearblend inplace is a bit weird: the result of a scanline * interpolation will affect the next scanline. this might not be a problem * at all, we just want a kind of filter here. */ for( i = 0; i < height; i++, data += stride ) { vfilter_chroma_332_packed422_scanline( data, width, data, (i) ? (data - stride) : data, (i < height-1) ? (data + stride) : data ); } } /* Build the output frame from the specified field. */ static int deinterlace_build_output_field( post_plugin_deinterlace_t *this, post_video_port_t *port, xine_stream_t *stream, vo_frame_t *frame, vo_frame_t *yuy2_frame, int bottom_field, int second_field, int64_t pts, int64_t duration, int skip) { vo_frame_t *deinterlaced_frame; int scaler = 1; int force24fps; force24fps = this->judder_correction && !this->cheap_mode && ( this->pulldown == PULLDOWN_VEKTOR && this->tvtime->filmmode ); if( this->tvtime->curmethod->doscalerbob ) { scaler = 2; } pthread_mutex_unlock (&this->lock); deinterlaced_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height / scaler, frame->ratio, yuy2_frame->format, frame->flags | VO_BOTH_FIELDS); pthread_mutex_lock (&this->lock); deinterlaced_frame->crop_left = frame->crop_left; deinterlaced_frame->crop_right = frame->crop_right; deinterlaced_frame->crop_top = frame->crop_top; deinterlaced_frame->crop_bottom = frame->crop_bottom; _x_extra_info_merge(deinterlaced_frame->extra_info, frame->extra_info); if( skip > 0 && !this->pulldown ) { deinterlaced_frame->bad_frame = 1; } else { if( this->tvtime->curmethod->doscalerbob ) { if( yuy2_frame->format == XINE_IMGFMT_YUY2 ) { deinterlaced_frame->bad_frame = !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[0], yuy2_frame->base[0], bottom_field, frame->width, frame->height, yuy2_frame->pitches[0], deinterlaced_frame->pitches[0] ); } else { deinterlaced_frame->bad_frame = !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[0], yuy2_frame->base[0], bottom_field, frame->width/2, frame->height, yuy2_frame->pitches[0], deinterlaced_frame->pitches[0] ); deinterlaced_frame->bad_frame += !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[1], yuy2_frame->base[1], bottom_field, frame->width/4, frame->height/2, yuy2_frame->pitches[1], deinterlaced_frame->pitches[1] ); deinterlaced_frame->bad_frame += !tvtime_build_copied_field(this->tvtime, deinterlaced_frame->base[2], yuy2_frame->base[2], bottom_field, frame->width/4, frame->height/2, yuy2_frame->pitches[2], deinterlaced_frame->pitches[2] ); } } else { if( yuy2_frame->format == XINE_IMGFMT_YUY2 ) { deinterlaced_frame->bad_frame = !tvtime_build_deinterlaced_frame(this->tvtime, deinterlaced_frame->base[0], yuy2_frame->base[0], (this->recent_frame[0])?this->recent_frame[0]->base[0]:yuy2_frame->base[0], (this->recent_frame[1])?this->recent_frame[1]->base[0]:yuy2_frame->base[0], bottom_field, second_field, frame->width, frame->height, yuy2_frame->pitches[0], deinterlaced_frame->pitches[0]); } else { deinterlaced_frame->bad_frame = !tvtime_build_deinterlaced_frame(this->tvtime, deinterlaced_frame->base[0], yuy2_frame->base[0], (this->recent_frame[0])?this->recent_frame[0]->base[0]:yuy2_frame->base[0], (this->recent_frame[1])?this->recent_frame[1]->base[0]:yuy2_frame->base[0], bottom_field, second_field, frame->width/2, frame->height, yuy2_frame->pitches[0], deinterlaced_frame->pitches[0]); deinterlaced_frame->bad_frame += !tvtime_build_deinterlaced_frame(this->tvtime, deinterlaced_frame->base[1], yuy2_frame->base[1], (this->recent_frame[0])?this->recent_frame[0]->base[1]:yuy2_frame->base[1], (this->recent_frame[1])?this->recent_frame[1]->base[1]:yuy2_frame->base[1], bottom_field, second_field, frame->width/4, frame->height/2, yuy2_frame->pitches[1], deinterlaced_frame->pitches[1]); deinterlaced_frame->bad_frame += !tvtime_build_deinterlaced_frame(this->tvtime, deinterlaced_frame->base[2], yuy2_frame->base[2], (this->recent_frame[0])?this->recent_frame[0]->base[2]:yuy2_frame->base[2], (this->recent_frame[1])?this->recent_frame[1]->base[2]:yuy2_frame->base[2], bottom_field, second_field, frame->width/4, frame->height/2, yuy2_frame->pitches[2], deinterlaced_frame->pitches[2]); } } } pthread_mutex_unlock (&this->lock); if( force24fps ) { if( !deinterlaced_frame->bad_frame ) { this->framecounter++; if( pts && this->framecounter > FRAMES_TO_SYNC ) { deinterlaced_frame->pts = pts; this->framecounter = 0; } else deinterlaced_frame->pts = 0; deinterlaced_frame->duration = FPS_24_DURATION; if( this->chroma_filter && !this->cheap_mode ) apply_chroma_filter( deinterlaced_frame->base[0], deinterlaced_frame->pitches[0], frame->width, frame->height / scaler ); skip = deinterlaced_frame->draw(deinterlaced_frame, stream); } else { skip = 0; } } else { deinterlaced_frame->pts = pts; deinterlaced_frame->duration = duration; if( this->chroma_filter && !this->cheap_mode && !deinterlaced_frame->bad_frame ) apply_chroma_filter( deinterlaced_frame->base[0], deinterlaced_frame->pitches[0], frame->width, frame->height / scaler ); skip = deinterlaced_frame->draw(deinterlaced_frame, stream); } /* _x_post_frame_copy_up(frame, deinterlaced_frame); */ deinterlaced_frame->free(deinterlaced_frame); pthread_mutex_lock (&this->lock); return skip; } static int deinterlace_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_plugin_deinterlace_t *this = (post_plugin_deinterlace_t *)port->post; vo_frame_t *orig_frame; vo_frame_t *yuy2_frame; int i, skip = 0, progressive = 0; int fields[2] = {0, 0}; int framerate_mode; orig_frame = frame; _x_post_frame_copy_down(frame, frame->next); frame = frame->next; /* update tvtime context and method */ pthread_mutex_lock (&this->lock); if( this->tvtime_changed ) { tvtime_reset_context(this->tvtime); if( this->cur_method ) this->tvtime->curmethod = get_deinterlace_method( this->class->methods, this->cur_method-1 ); else this->tvtime->curmethod = NULL; port->original_port->set_property(port->original_port, XINE_PARAM_VO_DEINTERLACE, !this->cur_method); this->tvtime_changed = 0; } if( this->tvtime_last_filmmode != this->tvtime->filmmode ) { xine_event_t event; event.type = XINE_EVENT_POST_TVTIME_FILMMODE_CHANGE; event.stream = stream; event.data = (void *)&this->tvtime->filmmode; event.data_length = sizeof(this->tvtime->filmmode); xine_event_send(stream, &event); this->tvtime_last_filmmode = this->tvtime->filmmode; } pthread_mutex_unlock (&this->lock); lprintf("frame flags pf: %d rff: %d tff: %d duration: %d\n", frame->progressive_frame, frame->repeat_first_field, frame->top_field_first, frame->duration); /* detect special rff patterns */ this->rff_pattern = this->rff_pattern << 1; this->rff_pattern |= !!frame->repeat_first_field; if( ((this->rff_pattern & 0xff) == 0xaa || (this->rff_pattern & 0xff) == 0x55) ) { /* * special case for ntsc 3:2 pulldown (called flags or soft pulldown). * we know all frames are indeed progressive. */ progressive = 1; } /* using frame->progressive_frame may help displaying still menus. * however, it is known that some rare material set it wrong. * * we also assume that repeat_first_field is progressive (it doesn't * make much sense to display interlaced fields out of order) */ if( this->use_progressive_frame_flag && (frame->repeat_first_field || frame->progressive_frame) ) { progressive = 1; } if( !frame->bad_frame && (frame->flags & VO_INTERLACED_FLAG) && this->tvtime->curmethod ) { frame->flags &= ~VO_INTERLACED_FLAG; /* convert to YUY2 if needed */ if( frame->format == XINE_IMGFMT_YV12 && !this->cheap_mode ) { yuy2_frame = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, XINE_IMGFMT_YUY2, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, yuy2_frame); /* the logic for deciding upsampling to use comes from: * http://www.hometheaterhifi.com/volume_8_2/dvd-benchmark-special-report-chroma-bug-4-2001.html */ yv12_to_yuy2(frame->base[0], frame->pitches[0], frame->base[1], frame->pitches[1], frame->base[2], frame->pitches[2], yuy2_frame->base[0], yuy2_frame->pitches[0], frame->width, frame->height, frame->progressive_frame || progressive ); } else { yuy2_frame = frame; yuy2_frame->lock(yuy2_frame); } pthread_mutex_lock (&this->lock); /* check if frame format changed */ for(i = 0; i < NUM_RECENT_FRAMES; i++ ) { if( this->recent_frame[i] && (this->recent_frame[i]->width != frame->width || this->recent_frame[i]->height != frame->height || this->recent_frame[i]->format != yuy2_frame->format ) ) { this->recent_frame[i]->free(this->recent_frame[i]); this->recent_frame[i] = NULL; } } if( !this->cheap_mode ) { framerate_mode = this->framerate_mode; this->tvtime->pulldown_alg = this->pulldown; } else { framerate_mode = FRAMERATE_HALF_TFF; this->tvtime->pulldown_alg = PULLDOWN_NONE; } if( framerate_mode == FRAMERATE_FULL ) { int top_field_first = frame->top_field_first; /* if i understood mpeg2 specs correctly, top_field_first * shall be zero for field pictures and the output order * is the same that the fields are decoded. * frame->flags allow us to find the first decoded field. * * note: frame->field() is called later to switch decoded * field but frame->flags do not change. */ if ( (frame->flags & VO_BOTH_FIELDS) != VO_BOTH_FIELDS ) { top_field_first = (frame->flags & VO_TOP_FIELD) ? 1 : 0; } if ( top_field_first ) { fields[0] = 0; fields[1] = 1; } else { fields[0] = 1; fields[1] = 0; } } else if ( framerate_mode == FRAMERATE_HALF_TFF ) { fields[0] = 0; } else if ( framerate_mode == FRAMERATE_HALF_BFF ) { fields[0] = 1; } if( progressive ) { /* If the previous field was interlaced and this one is progressive * we need to run a deinterlace on the first field of this frame * in order to let output for the previous frames last field be * generated. This is only necessary for the deinterlacers that * delay output by one field. This is signaled by the delaysfield * flag in the deinterlace method structure. The previous frames * duration is used in the calculation because the generated frame * represents the second half of the previous frame. */ if (this->recent_frame[0] && !this->recent_frame[0]->progressive_frame && this->tvtime->curmethod->delaysfield) { deinterlace_build_output_field( this, port, stream, frame, yuy2_frame, fields[0], 0, 0, (framerate_mode == FRAMERATE_FULL) ? this->recent_frame[0]->duration/2 : this->recent_frame[0]->duration, 0); } pthread_mutex_unlock (&this->lock); skip = yuy2_frame->draw(yuy2_frame, stream); pthread_mutex_lock (&this->lock); _x_post_frame_copy_up(frame, yuy2_frame); } else { /* If the previous field was progressive and we are using a * filter that delays it's output by one field then we need * to skip the first field's output. Otherwise the effective * display duration of the previous frame will be extended * by 1/2 of this frames duration when output is generated * using the last field of the progressive frame. */ /* Build the output from the first field. */ if ( !(this->recent_frame[0] && this->recent_frame[0]->progressive_frame && this->tvtime->curmethod->delaysfield) ) { skip = deinterlace_build_output_field( this, port, stream, frame, yuy2_frame, fields[0], 0, frame->pts, (framerate_mode == FRAMERATE_FULL) ? frame->duration/2 : frame->duration, 0); } if( framerate_mode == FRAMERATE_FULL ) { /* Build the output from the second field. */ skip = deinterlace_build_output_field( this, port, stream, frame, yuy2_frame, fields[1], 1, 0, frame->duration/2, skip); } } /* don't drop frames when pulldown mode is enabled. otherwise * pulldown detection fails (yo-yo effect has also been seen) */ if( this->pulldown ) skip = 0; /* store back progressive flag for frame history */ yuy2_frame->progressive_frame = progressive; /* keep track of recent frames */ i = NUM_RECENT_FRAMES-1; if( this->recent_frame[i] ) this->recent_frame[i]->free(this->recent_frame[i]); for( ; i ; i-- ) this->recent_frame[i] = this->recent_frame[i-1]; if (port->stream) this->recent_frame[0] = yuy2_frame; else { /* do not keep this frame when no stream is connected to us, * otherwise, this frame might never get freed */ yuy2_frame->free(yuy2_frame); this->recent_frame[0] = NULL; } pthread_mutex_unlock (&this->lock); } else { skip = frame->draw(frame, stream); } _x_post_frame_copy_up(orig_frame, frame); return skip; } /* plugin catalog information */ static const post_info_t deinterlace_special_info = { .type = XINE_POST_TYPE_VIDEO_FILTER, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST | PLUGIN_MUST_PRELOAD, 10, "tvtime", XINE_VERSION_CODE, &deinterlace_special_info, &deinterlace_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/speedy.c����������������������������������������������������������0000644�0001750�0001750�00000250222�14647725152�016357� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2002, 2003 Billy Biggs <vektor@dumbterm.net>. * Copyright (C) 2001 Matthew J. Marjanovic <maddog@mir.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ /** * Includes 420to422, 422to444 scaling filters from the MPEG2 reference * implementation. The v12 source code indicates that they were written * by Cheung Auyeung <auyeung@mot.com>. The file they were in was: * * store.c, picture output routines * Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. * * Disclaimer of Warranty * * These software programs are available to the user without any license fee or * royalty on an "as is" basis. The MPEG Software Simulation Group disclaims * any and all warranties, whether express, implied, or statuary, including any * implied warranties or merchantability or of fitness for a particular * purpose. In no event shall the copyright-holder be liable for any * incidental, punitive, or consequential damages of any kind whatsoever * arising from the use of these programs. * * This disclaimer of warranty extends to the user of these programs and user's * customers, employees, agents, transferees, successors, and assigns. * * The MPEG Software Simulation Group does not represent or warrant that the * programs furnished hereunder are free of infringement of any third-party * patents. * * Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, * are subject to royalty fees to patent holders. Many of these patents are * general enough such that they are unavoidable regardless of implementation * design. * */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <string.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include <xine/attributes.h> #include <xine/xineutils.h> #include "xine_mmx.h" #include "speedtools.h" #include "speedy.h" /* Function pointer definitions. */ void (*interpolate_packed422_scanline)( uint8_t *output, uint8_t *top, uint8_t *bot, int width ); void (*blit_colour_packed422_scanline)( uint8_t *output, int width, int y, int cb, int cr ); void (*blit_colour_packed4444_scanline)( uint8_t *output, int width, int alpha, int luma, int cb, int cr ); void (*blit_packed422_scanline)( uint8_t *dest, const uint8_t *src, int width ); void (*composite_packed4444_to_packed422_scanline)( uint8_t *output, uint8_t *input, uint8_t *foreground, int width ); void (*composite_packed4444_alpha_to_packed422_scanline)( uint8_t *output, uint8_t *input, uint8_t *foreground, int width, int alpha ); void (*composite_alphamask_to_packed4444_scanline)( uint8_t *output, uint8_t *input, uint8_t *mask, int width, int textluma, int textcb, int textcr ); void (*composite_alphamask_alpha_to_packed4444_scanline)( uint8_t *output, uint8_t *input, uint8_t *mask, int width, int textluma, int textcb, int textcr, int alpha ); void (*premultiply_packed4444_scanline)( uint8_t *output, uint8_t *input, int width ); void (*blend_packed422_scanline)( uint8_t *output, uint8_t *src1, uint8_t *src2, int width, int pos ); void (*filter_luma_121_packed422_inplace_scanline)( uint8_t *data, int width ); void (*filter_luma_14641_packed422_inplace_scanline)( uint8_t *data, int width ); unsigned int (*diff_factor_packed422_scanline)( uint8_t *cur, uint8_t *old, int width ); unsigned int (*comb_factor_packed422_scanline)( uint8_t *top, uint8_t *mid, uint8_t *bot, int width ); void (*kill_chroma_packed422_inplace_scanline)( uint8_t *data, int width ); void (*mirror_packed422_inplace_scanline)( uint8_t *data, int width ); void (*halfmirror_packed422_inplace_scanline)( uint8_t *data, int width ); void *(*speedy_memcpy)( void *output, const void *input, size_t size ); void (*diff_packed422_block8x8)( pulldown_metrics_t *m, uint8_t *old, uint8_t *new, int os, int ns ); void (*a8_subpix_blit_scanline)( uint8_t *output, uint8_t *input, int lasta, int startpos, int width ); void (*quarter_blit_vertical_packed422_scanline)( uint8_t *output, uint8_t *one, uint8_t *three, int width ); void (*subpix_blit_vertical_packed422_scanline)( uint8_t *output, uint8_t *top, uint8_t *bot, int subpixpos, int width ); void (*composite_bars_packed4444_scanline)( uint8_t *output, uint8_t *background, int width, int a, int luma, int cb, int cr, int percentage ); void (*packed444_to_nonpremultiplied_packed4444_scanline)( uint8_t *output, uint8_t *input, int width, int alpha ); #if 0 void (*aspect_adjust_packed4444_scanline)( uint8_t *output, uint8_t *input, int width, double pixel_aspect ); #endif void (*packed444_to_packed422_scanline)( uint8_t *output, uint8_t *input, int width ); void (*packed422_to_packed444_scanline)( uint8_t *output, uint8_t *input, int width ); void (*packed422_to_packed444_rec601_scanline)( uint8_t *dest, uint8_t *src, int width ); void (*packed444_to_rgb24_rec601_scanline)( uint8_t *output, uint8_t *input, int width ); void (*rgb24_to_packed444_rec601_scanline)( uint8_t *output, uint8_t *input, int width ); void (*rgba32_to_packed4444_rec601_scanline)( uint8_t *output, uint8_t *input, int width ); void (*chroma_422_to_444_mpeg2_plane)( uint8_t *dst, uint8_t *src, int width, int height ); void (*chroma_420_to_422_mpeg2_plane)( uint8_t *dst, uint8_t *src, int width, int height, int progressive ); void (*invert_colour_packed422_inplace_scanline)( uint8_t *data, int width ); void (*vfilter_chroma_121_packed422_scanline)( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ); void (*vfilter_chroma_332_packed422_scanline)( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ); /** * result = (1 - alpha)B + alpha*F * = B - alpha*B + alpha*F * = B + alpha*(F - B) */ static inline __attribute__ ((always_inline,const)) int multiply_alpha( int a, int r ) { int temp; temp = (r * a) + 0x80; return ((temp + (temp >> 8)) >> 8); } static inline __attribute__ ((always_inline,const)) uint8_t clip255( int x ) { if( x > 255 ) { return 255; } else if( x < 0 ) { return 0; } else { return x; } } #if defined(ARCH_X86) static unsigned int comb_factor_packed422_scanline_mmx( uint8_t *top, uint8_t *mid, uint8_t *bot, int width ) { const unsigned int CombJaggieThreshold = 73; const mmx_t qwYMask = { 0x00ff00ff00ff00ffULL }; const mmx_t qwOnes = { 0x0001000100010001ULL }; mmx_t qwThreshold; unsigned int temp1, temp2; width /= 4; qwThreshold.uw[ 0 ] = CombJaggieThreshold; qwThreshold.uw[ 1 ] = CombJaggieThreshold; qwThreshold.uw[ 2 ] = CombJaggieThreshold; qwThreshold.uw[ 3 ] = CombJaggieThreshold; movq_m2r( qwThreshold, mm0 ); movq_m2r( qwYMask, mm1 ); movq_m2r( qwOnes, mm2 ); pxor_r2r( mm7, mm7 ); /* mm7 = 0. */ while( width-- ) { /* Load and keep just the luma. */ movq_m2r( *top, mm3 ); movq_m2r( *mid, mm4 ); movq_m2r( *bot, mm5 ); pand_r2r( mm1, mm3 ); pand_r2r( mm1, mm4 ); pand_r2r( mm1, mm5 ); /* Work out mm6 = (top - mid) * (bot - mid) - ( (top - mid)^2 >> 7 ) */ psrlw_i2r( 1, mm3 ); psrlw_i2r( 1, mm4 ); psrlw_i2r( 1, mm5 ); /* mm6 = (top - mid) */ movq_r2r( mm3, mm6 ); psubw_r2r( mm4, mm6 ); /* mm3 = (top - bot) */ psubw_r2r( mm5, mm3 ); /* mm5 = (bot - mid) */ psubw_r2r( mm4, mm5 ); /* mm6 = (top - mid) * (bot - mid) */ pmullw_r2r( mm5, mm6 ); /* mm3 = (top - bot)^2 >> 7 */ pmullw_r2r( mm3, mm3 ); /* mm3 = (top - bot)^2 */ psrlw_i2r( 7, mm3 ); /* mm3 = ((top - bot)^2 >> 7) */ /* mm6 is what we want. */ psubw_r2r( mm3, mm6 ); /* FF's if greater than qwTheshold */ pcmpgtw_r2r( mm0, mm6 ); /* Add to count if we are greater than threshold */ pand_r2r( mm2, mm6 ); paddw_r2r( mm6, mm7 ); top += 8; mid += 8; bot += 8; } movd_r2m( mm7, temp1 ); psrlq_i2r( 32, mm7 ); movd_r2m( mm7, temp2 ); temp1 += temp2; temp2 = temp1; temp1 >>= 16; temp1 += temp2 & 0xffff; emms(); return temp1; } #endif static unsigned long BitShift = 6; static unsigned int diff_factor_packed422_scanline_c( uint8_t *cur, uint8_t *old, int width ) { unsigned int ret = 0; width /= 4; while( width-- ) { unsigned int tmp1 = (cur[ 0 ] + cur[ 2 ] + cur[ 4 ] + cur[ 6 ] + 2)>>2; unsigned int tmp2 = (old[ 0 ] + old[ 2 ] + old[ 4 ] + old[ 6 ] + 2)>>2; tmp1 = (tmp1 - tmp2); tmp1 *= tmp1; tmp1 >>= BitShift; ret += tmp1; cur += 8; old += 8; } return ret; } /* static unsigned int diff_factor_packed422_scanline_test_c( uint8_t *cur, uint8_t *old, int width ) { unsigned int ret = 0; width /= 16; while( width-- ) { unsigned int tmp1 = (cur[ 0 ] + cur[ 2 ] + cur[ 4 ] + cur[ 6 ])>>2; unsigned int tmp2 = (old[ 0 ] + old[ 2 ] + old[ 4 ] + old[ 6 ])>>2; tmp1 = (tmp1 - tmp2); tmp1 *= tmp1; tmp1 >>= BitShift; ret += tmp1; cur += (8*4); old += (8*4); } return ret; } */ #if defined(ARCH_X86) static unsigned int diff_factor_packed422_scanline_mmx( uint8_t *cur, uint8_t *old, int width ) { const mmx_t qwYMask = { 0x00ff00ff00ff00ffULL }; unsigned int temp1, temp2; width /= 4; movq_m2r( qwYMask, mm1 ); movd_m2r( BitShift, mm7 ); pxor_r2r( mm0, mm0 ); while( width-- ) { movq_m2r( *cur, mm4 ); movq_m2r( *old, mm5 ); pand_r2r( mm1, mm4 ); pand_r2r( mm1, mm5 ); psubw_r2r( mm5, mm4 ); /* mm4 = Y1 - Y2 */ pmaddwd_r2r( mm4, mm4 ); /* mm4 = (Y1 - Y2)^2 */ psrld_r2r( mm7, mm4 ); /* divide mm4 by 2^BitShift */ paddd_r2r( mm4, mm0 ); /* keep total in mm0 */ cur += 8; old += 8; } movd_r2m( mm0, temp1 ); psrlq_i2r( 32, mm0 ); movd_r2m( mm0, temp2 ); temp1 += temp2; emms(); return temp1; } #endif #if defined(ARCH_X86) static const sse_t dqwYMask = { .uq = { 0x00ff00ff00ff00ffULL, 0x00ff00ff00ff00ffULL }}; static const sse_t dqwCMask = { .uq = { 0xff00ff00ff00ff00ULL, 0xff00ff00ff00ff00ULL }}; static unsigned int diff_factor_packed422_scanline_sse2_aligned( uint8_t *cur, uint8_t *old, int width ) { register unsigned int temp; width /= 8; movdqa_m2r( dqwYMask, xmm1 ); movd_m2r( BitShift, xmm7 ); pxor_r2r( xmm0, xmm0 ); while( width-- ) { movdqa_m2r( *cur, xmm4 ); movdqa_m2r( *old, xmm5 ); pand_r2r( xmm1, xmm4 ); pand_r2r( xmm1, xmm5 ); psubw_r2r( xmm5, xmm4 ); /* mm4 = Y1 - Y2 */ pmaddwd_r2r( xmm4, xmm4 ); /* mm4 = (Y1 - Y2)^2 */ psrld_r2r( xmm7, xmm4 ); /* divide mm4 by 2^BitShift */ paddd_r2r( xmm4, xmm0 ); /* keep total in mm0 */ cur += 16; old += 16; } pshufd_r2r(xmm0, xmm1, 0x0e); paddd_r2r(xmm1, xmm0); pshufd_r2r(xmm0, xmm1, 0x01); paddd_r2r(xmm1, xmm0); movd_r2a(xmm0, temp); return temp; } #endif #if defined(ARCH_X86) static unsigned int diff_factor_packed422_scanline_sse2( uint8_t *cur, uint8_t *old, int width ) { if (0 == (((intptr_t)cur | (intptr_t)old) & 15)) { return diff_factor_packed422_scanline_sse2_aligned(cur, old, width); } register unsigned int temp; width /= 8; movdqa_m2r( dqwYMask, xmm1 ); movd_m2r( BitShift, xmm7 ); pxor_r2r( xmm0, xmm0 ); while( width-- ) { movdqu_m2r( *cur, xmm4 ); movdqu_m2r( *old, xmm5 ); pand_r2r( xmm1, xmm4 ); pand_r2r( xmm1, xmm5 ); psubw_r2r( xmm5, xmm4 ); /* mm4 = Y1 - Y2 */ pmaddwd_r2r( xmm4, xmm4 ); /* mm4 = (Y1 - Y2)^2 */ psrld_r2r( xmm7, xmm4 ); /* divide mm4 by 2^BitShift */ paddd_r2r( xmm4, xmm0 ); /* keep total in mm0 */ cur += 16; old += 16; } pshufd_r2r(xmm0, xmm1, 0x0e); paddd_r2r(xmm1, xmm0); pshufd_r2r(xmm0, xmm1, 0x01); paddd_r2r(xmm1, xmm0); movd_r2a(xmm0, temp); return temp; } #endif #define ABS(a) (((a) < 0)?-(a):(a)) #if defined(ARCH_X86) static void diff_packed422_block8x8_mmx( pulldown_metrics_t *m, uint8_t *old, uint8_t *new, int os, int ns ) { const mmx_t ymask = { 0x00ff00ff00ff00ffULL }; short out[ 24 ]; /* Output buffer for the partial metrics from the mmx code. */ uint8_t *outdata = (uint8_t *) out; uint8_t *oldp, *newp; int i; pxor_r2r( mm4, mm4 ); // 4 even difference sums. pxor_r2r( mm5, mm5 ); // 4 odd difference sums. pxor_r2r( mm7, mm7 ); // zeros oldp = old; newp = new; for( i = 4; i; --i ) { // Even difference. movq_m2r( oldp[0], mm0 ); movq_m2r( oldp[8], mm2 ); pand_m2r( ymask, mm0 ); pand_m2r( ymask, mm2 ); oldp += os; movq_m2r( newp[0], mm1 ); movq_m2r( newp[8], mm3 ); pand_m2r( ymask, mm1 ); pand_m2r( ymask, mm3 ); newp += ns; movq_r2r( mm0, mm6 ); psubusb_r2r( mm1, mm0 ); psubusb_r2r( mm6, mm1 ); movq_r2r( mm2, mm6 ); psubusb_r2r( mm3, mm2 ); psubusb_r2r( mm6, mm3 ); paddw_r2r( mm0, mm4 ); paddw_r2r( mm1, mm4 ); paddw_r2r( mm2, mm4 ); paddw_r2r( mm3, mm4 ); // Odd difference. movq_m2r( oldp[0], mm0 ); movq_m2r( oldp[8], mm2 ); pand_m2r( ymask, mm0 ); pand_m2r( ymask, mm2 ); oldp += os; movq_m2r( newp[0], mm1 ); movq_m2r( newp[8], mm3 ); pand_m2r( ymask, mm1 ); pand_m2r( ymask, mm3 ); newp += ns; movq_r2r( mm0, mm6 ); psubusb_r2r( mm1, mm0 ); psubusb_r2r( mm6, mm1 ); movq_r2r( mm2, mm6 ); psubusb_r2r( mm3, mm2 ); psubusb_r2r( mm6, mm3 ); paddw_r2r( mm0, mm5 ); paddw_r2r( mm1, mm5 ); paddw_r2r( mm2, mm5 ); paddw_r2r( mm3, mm5 ); } movq_r2m( mm4, outdata[0] ); movq_r2m( mm5, outdata[8] ); m->e = out[0] + out[1] + out[2] + out[3]; m->o = out[4] + out[5] + out[6] + out[7]; m->d = m->e + m->o; pxor_r2r( mm4, mm4 ); // Past spacial noise. pxor_r2r( mm5, mm5 ); // Temporal noise. pxor_r2r( mm6, mm6 ); // Current spacial noise. // First loop to measure first four columns oldp = old; newp = new; for( i = 4; i; --i ) { movq_m2r( oldp[0], mm0 ); movq_m2r( oldp[os], mm1 ); pand_m2r( ymask, mm0 ); pand_m2r( ymask, mm1 ); oldp += (os*2); movq_m2r( newp[0], mm2 ); movq_m2r( newp[ns], mm3 ); pand_m2r( ymask, mm2 ); pand_m2r( ymask, mm3 ); newp += (ns*2); paddw_r2r( mm1, mm4 ); paddw_r2r( mm1, mm5 ); paddw_r2r( mm3, mm6 ); psubw_r2r( mm0, mm4 ); psubw_r2r( mm2, mm5 ); psubw_r2r( mm2, mm6 ); } movq_r2m( mm4, outdata[0] ); movq_r2m( mm5, outdata[16] ); movq_r2m( mm6, outdata[32] ); pxor_r2r( mm4, mm4 ); pxor_r2r( mm5, mm5 ); pxor_r2r( mm6, mm6 ); // Second loop for the last four columns oldp = old; newp = new; for( i = 4; i; --i ) { movq_m2r( oldp[8], mm0 ); movq_m2r( oldp[os+8], mm1 ); pand_m2r( ymask, mm0 ); pand_m2r( ymask, mm1 ); oldp += (os*2); movq_m2r( newp[8], mm2 ); movq_m2r( newp[ns+8], mm3 ); pand_m2r( ymask, mm2 ); pand_m2r( ymask, mm3 ); newp += (ns*2); paddw_r2r( mm1, mm4 ); paddw_r2r( mm1, mm5 ); paddw_r2r( mm3, mm6 ); psubw_r2r( mm0, mm4 ); psubw_r2r( mm2, mm5 ); psubw_r2r( mm2, mm6 ); } movq_r2m( mm4, outdata[8] ); movq_r2m( mm5, outdata[24] ); movq_r2m( mm6, outdata[40] ); m->p = m->t = m->s = 0; for (i=0; i<8; i++) { // FIXME: move abs() into the mmx code! m->p += ABS(out[i]); m->t += ABS(out[8+i]); m->s += ABS(out[16+i]); } emms(); } #endif static void diff_packed422_block8x8_c( pulldown_metrics_t *m, uint8_t *old, uint8_t *new, int os, int ns ) { int x, y, e=0, o=0, s=0, p=0, t=0; uint8_t *oldp, *newp; m->s = m->p = m->t = 0; for (x = 8; x; x--) { oldp = old; old += 2; newp = new; new += 2; s = p = t = 0; for (y = 4; y; y--) { e += ABS(newp[0] - oldp[0]); o += ABS(newp[ns] - oldp[os]); s += newp[ns]-newp[0]; p += oldp[os]-oldp[0]; t += oldp[os]-newp[0]; oldp += os<<1; newp += ns<<1; } m->s += ABS(s); m->p += ABS(p); m->t += ABS(t); } m->e = e; m->o = o; m->d = e+o; } static void packed444_to_packed422_scanline_c( uint8_t *output, uint8_t *input, int width ) { width /= 2; while( width-- ) { output[ 0 ] = input[ 0 ]; output[ 1 ] = input[ 1 ]; output[ 2 ] = input[ 3 ]; output[ 3 ] = input[ 2 ]; output += 4; input += 6; } } static void packed422_to_packed444_scanline_c( uint8_t *output, uint8_t *input, int width ) { width /= 2; while( width-- ) { output[ 0 ] = input[ 0 ]; output[ 1 ] = input[ 1 ]; output[ 2 ] = input[ 3 ]; output[ 3 ] = input[ 2 ]; output[ 4 ] = input[ 1 ]; output[ 5 ] = input[ 3 ]; output += 6; input += 4; } } /** * For the middle pixels, the filter kernel is: * * [-1 3 -6 12 -24 80 80 -24 12 -6 3 -1] */ static void packed422_to_packed444_rec601_scanline_c( uint8_t *dest, uint8_t *src, int width ) { int i; /* Process two input pixels at a time. Input is [Y'][Cb][Y'][Cr]. */ for( i = 0; i < width / 2; i++ ) { dest[ (i*6) + 0 ] = src[ (i*4) + 0 ]; dest[ (i*6) + 1 ] = src[ (i*4) + 1 ]; dest[ (i*6) + 2 ] = src[ (i*4) + 3 ]; dest[ (i*6) + 3 ] = src[ (i*4) + 2 ]; if( i > (5*2) && i < ((width/2) - (6*2)) ) { dest[ (i*6) + 4 ] = clip255( (( (80*(src[ (i*4) + 1 ] + src[ (i*4) + 5 ])) - (24*(src[ (i*4) - 3 ] + src[ (i*4) + 9 ])) + (12*(src[ (i*4) - 7 ] + src[ (i*4) + 13])) - ( 6*(src[ (i*4) - 11] + src[ (i*4) + 17])) + ( 3*(src[ (i*4) - 15] + src[ (i*4) + 21])) - ( (src[ (i*4) - 19] + src[ (i*4) + 25]))) + 64) >> 7 ); dest[ (i*6) + 5 ] = clip255( (( (80*(src[ (i*4) + 3 ] + src[ (i*4) + 7 ])) - (24*(src[ (i*4) - 1 ] + src[ (i*4) + 11])) + (12*(src[ (i*4) - 5 ] + src[ (i*4) + 15])) - ( 6*(src[ (i*4) - 9 ] + src[ (i*4) + 19])) + ( 3*(src[ (i*4) - 13] + src[ (i*4) + 23])) - ( (src[ (i*4) - 17] + src[ (i*4) + 27]))) + 64) >> 7 ); } else if( i < ((width/2) - 1) ) { dest[ (i*6) + 4 ] = (src[ (i*4) + 1 ] + src[ (i*4) + 5 ] + 1) >> 1; dest[ (i*6) + 5 ] = (src[ (i*4) + 3 ] + src[ (i*4) + 7 ] + 1) >> 1; } else { dest[ (i*6) + 4 ] = src[ (i*4) + 1 ]; dest[ (i*6) + 5 ] = src[ (i*4) + 3 ]; } } } #if defined(ARCH_X86) static void vfilter_chroma_121_packed422_scanline_mmx( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ) { int i; const mmx_t ymask = { 0x00ff00ff00ff00ffULL }; const mmx_t cmask = { 0xff00ff00ff00ff00ULL }; // Get width in bytes. width *= 2; i = width / 8; width -= i * 8; movq_m2r( ymask, mm7 ); movq_m2r( cmask, mm6 ); while( i-- ) { movq_m2r( *t, mm0 ); movq_m2r( *b, mm1 ); movq_m2r( *m, mm2 ); movq_r2r ( mm2, mm3 ); pand_r2r ( mm7, mm3 ); pand_r2r ( mm6, mm0 ); pand_r2r ( mm6, mm1 ); pand_r2r ( mm6, mm2 ); psrlq_i2r( 8, mm0 ); psrlq_i2r( 8, mm1 ); psrlq_i2r( 7, mm2 ); paddw_r2r( mm0, mm2 ); paddw_r2r( mm1, mm2 ); psllw_i2r( 6, mm2 ); pand_r2r( mm6, mm2 ); por_r2r ( mm3, mm2 ); movq_r2m( mm2, *output ); output += 8; t += 8; b += 8; m += 8; } output++; t++; b++; m++; while( width-- ) { *output = (*t + *b + (*m << 1)) >> 2; output+=2; t+=2; b+=2; m+=2; } emms(); } #endif static void vfilter_chroma_121_packed422_scanline_c( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ) { output++; t++; b++; m++; while( width-- ) { *output = (*t + *b + (*m << 1)) >> 2; output +=2; t+=2; b+=2; m+=2; } } #if defined(ARCH_X86) static void vfilter_chroma_332_packed422_scanline_mmx( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ) { int i; const mmx_t ymask = { 0x00ff00ff00ff00ffULL }; const mmx_t cmask = { 0xff00ff00ff00ff00ULL }; // Get width in bytes. width *= 2; i = width / 8; width -= i * 8; movq_m2r( ymask, mm7 ); movq_m2r( cmask, mm6 ); while( i-- ) { movq_m2r( *t, mm0 ); movq_m2r( *b, mm1 ); movq_m2r( *m, mm2 ); movq_r2r ( mm2, mm3 ); pand_r2r ( mm7, mm3 ); pand_r2r ( mm6, mm0 ); pand_r2r ( mm6, mm1 ); pand_r2r ( mm6, mm2 ); psrlq_i2r( 8, mm0 ); psrlq_i2r( 7, mm1 ); psrlq_i2r( 8, mm2 ); movq_r2r ( mm0, mm4 ); psllw_i2r( 1, mm4 ); paddw_r2r( mm4, mm0 ); movq_r2r ( mm2, mm4 ); psllw_i2r( 1, mm4 ); paddw_r2r( mm4, mm2 ); paddw_r2r( mm0, mm2 ); paddw_r2r( mm1, mm2 ); psllw_i2r( 5, mm2 ); pand_r2r( mm6, mm2 ); por_r2r ( mm3, mm2 ); movq_r2m( mm2, *output ); output += 8; t += 8; b += 8; m += 8; } output++; t++; b++; m++; while( width-- ) { *output = (3 * *t + 3 * *m + 2 * *b) >> 3; output +=2; t+=2; b+=2; m+=2; } emms(); } #endif #if defined(ARCH_X86) static void vfilter_chroma_332_packed422_scanline_sse2_aligned( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ) { int i; // Get width in bytes. width *= 2; i = width / 16; width -= i * 16; movdqa_m2r( dqwYMask, xmm7 ); movdqa_m2r( dqwCMask, xmm6 ); while( i-- ) { movdqa_m2r ( *t, xmm0 ); movdqa_m2r ( *b, xmm1 ); movdqa_m2r ( *m, xmm2 ); movdqa_r2r ( xmm2, xmm3 ); pand_r2r ( xmm7, xmm3 ); pand_r2r ( xmm6, xmm0 ); pand_r2r ( xmm6, xmm1 ); pand_r2r ( xmm6, xmm2 ); psrlq_i2r ( 8, xmm0 ); psrlq_i2r ( 7, xmm1 ); psrlq_i2r ( 8, xmm2 ); movdqa_r2r ( xmm0, xmm4 ); movdqa_r2r ( xmm2, xmm5 ); psllw_i2r ( 1, xmm4 ); psllw_i2r ( 1, xmm5 ); paddw_r2r ( xmm4, xmm0 ); paddw_r2r ( xmm5, xmm2 ); paddw_r2r ( xmm0, xmm2 ); paddw_r2r ( xmm1, xmm2 ); psllw_i2r ( 5, xmm2 ); pand_r2r ( xmm6, xmm2 ); por_r2r ( xmm3, xmm2 ); movdqa_r2m( xmm2, *output ); output += 16; t += 16; b += 16; m += 16; } output++; t++; b++; m++; while( width-- ) { *output = (3 * *t + 3 * *m + 2 * *b) >> 3; output +=2; t+=2; b+=2; m+=2; } } #endif #if defined(ARCH_X86) static void vfilter_chroma_332_packed422_scanline_sse2( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ) { int i; if (0 == (((intptr_t)output | (intptr_t)m | (intptr_t)t | (intptr_t)b) & 15)) { vfilter_chroma_332_packed422_scanline_sse2_aligned(output, width, m, t, b); return; } // Get width in bytes. width *= 2; i = width / 16; width -= i * 16; movdqa_m2r( dqwYMask, xmm7 ); movdqa_m2r( dqwCMask, xmm6 ); while( i-- ) { movdqu_m2r ( *t, xmm0 ); movdqu_m2r ( *b, xmm1 ); movdqu_m2r ( *m, xmm2 ); movdqa_r2r ( xmm2, xmm3 ); pand_r2r ( xmm7, xmm3 ); pand_r2r ( xmm6, xmm0 ); pand_r2r ( xmm6, xmm1 ); pand_r2r ( xmm6, xmm2 ); psrlq_i2r ( 8, xmm0 ); psrlq_i2r ( 7, xmm1 ); psrlq_i2r ( 8, xmm2 ); movdqa_r2r ( xmm0, xmm4 ); movdqa_r2r ( xmm2, xmm5 ); psllw_i2r ( 1, xmm4 ); psllw_i2r ( 1, xmm5 ); paddw_r2r ( xmm4, xmm0 ); paddw_r2r ( xmm5, xmm2 ); paddw_r2r ( xmm0, xmm2 ); paddw_r2r ( xmm1, xmm2 ); psllw_i2r ( 5, xmm2 ); pand_r2r ( xmm6, xmm2 ); por_r2r ( xmm3, xmm2 ); movdqu_r2m( xmm2, *output ); output += 16; t += 16; b += 16; m += 16; } output++; t++; b++; m++; while( width-- ) { *output = (3 * *t + 3 * *m + 2 * *b) >> 3; output +=2; t+=2; b+=2; m+=2; } } #endif static void vfilter_chroma_332_packed422_scanline_c( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ) { output++; t++; b++; m++; while( width-- ) { *output = (3 * *t + 3 * *m + 2 * *b) >> 3; output +=2; t+=2; b+=2; m+=2; } } #if defined(ARCH_X86) static void kill_chroma_packed422_inplace_scanline_mmx( uint8_t *data, int width ) { const mmx_t ymask = { 0x00ff00ff00ff00ffULL }; const mmx_t nullchroma = { 0x8000800080008000ULL }; movq_m2r( ymask, mm7 ); movq_m2r( nullchroma, mm6 ); for(; width > 4; width -= 4 ) { movq_m2r( *data, mm0 ); pand_r2r( mm7, mm0 ); paddb_r2r( mm6, mm0 ); movq_r2m( mm0, *data ); data += 8; } emms(); while( width-- ) { data[ 1 ] = 128; data += 2; } } #endif static void kill_chroma_packed422_inplace_scanline_c( uint8_t *data, int width ) { while( width-- ) { data[ 1 ] = 128; data += 2; } } #if defined(ARCH_X86) static void invert_colour_packed422_inplace_scanline_mmx( uint8_t *data, int width ) { const mmx_t allones = { 0xffffffffffffffffULL }; movq_m2r( allones, mm1 ); for(; width > 4; width -= 4 ) { movq_r2r( mm1, mm2 ); movq_m2r( *data, mm0 ); psubb_r2r( mm0, mm2 ); movq_r2m( mm2, *data ); data += 8; } emms(); width *= 2; while( width-- ) { *data = 255 - *data; data++; } } #endif static void invert_colour_packed422_inplace_scanline_c( uint8_t *data, int width ) { width *= 2; while( width-- ) { *data = 255 - *data; data++; } } /* // this duplicates alternate lines in alternate frames to highlight or mute // the effects of chroma crawl. it is not a solution or proper filter. it's // only for testing. void testing_packed422_inplace_scanline_c( uint8_t *data, int width, int scanline ) { volatile static int topbottom = 0; static uint8_t scanbuffer[2048]; if( scanline <= 1 ) { topbottom = scanline; memcpy(scanbuffer, data, width*2); } if ( scanline < 10 ) { printf("scanline: %d %d\n", scanline, topbottom); } if ( ((scanline-topbottom)/2)%2 && scanline > 1 ) { memcpy(data, scanbuffer, width*2); } else { memcpy(scanbuffer, data, width*2); } } */ static void mirror_packed422_inplace_scanline_c( uint8_t *data, int width ) { int x, tmp1, tmp2; int width2 = width*2; for( x = 0; x < width; x += 2 ) { tmp1 = data[ x ]; tmp2 = data[ x+1 ]; data[ x ] = data[ width2 - x ]; data[ x+1 ] = data[ width2 - x + 1 ]; data[ width2 - x ] = tmp1; data[ width2 - x + 1 ] = tmp2; } } static void halfmirror_packed422_inplace_scanline_c( uint8_t *data, int width ) { int x; for( x = 0; x < width; x += 2 ) { data[ width + x ] = data[ width - x ]; data[ width + x + 1 ] = data[ width - x + 1 ]; } } static void filter_luma_121_packed422_inplace_scanline_c( uint8_t *data, int width ) { int r1 = 0; int r2 = 0; data += 2; width -= 1; while( width-- ) { int s1, s2; s1 = *data + r1; r1 = *data; s2 = s1 + r2; r2 = s1; *(data - 2) = s2 >> 2; data += 2; } } static void filter_luma_14641_packed422_inplace_scanline_c( uint8_t *data, int width ) { int r1 = 0; int r2 = 0; int r3 = 0; int r4 = 0; width -= 4; data += 4; while( width-- ) { int s1, s2, s3, s4; s1 = *data + r1; r1 = *data; s2 = s1 + r2; r2 = s1; s3 = s2 + r3; r3 = s2; s4 = s3 + r4; r4 = s3; *(data - 4) = s4 >> 4; data += 2; } } static void interpolate_packed422_scanline_c( uint8_t *output, uint8_t *top, uint8_t *bot, int width ) { int i; for( i = width*2; i; --i ) { *output++ = ((*top++) + (*bot++)) >> 1; } } #if defined(ARCH_X86) static void interpolate_packed422_scanline_mmx( uint8_t *output, uint8_t *top, uint8_t *bot, int width ) { const mmx_t shiftmask = { 0xfefffefffefffeffULL }; /* To avoid shifting chroma to luma. */ int i; for( i = width/16; i; --i ) { movq_m2r( *bot, mm0 ); movq_m2r( *top, mm1 ); movq_m2r( *(bot + 8), mm2 ); movq_m2r( *(top + 8), mm3 ); movq_m2r( *(bot + 16), mm4 ); movq_m2r( *(top + 16), mm5 ); movq_m2r( *(bot + 24), mm6 ); movq_m2r( *(top + 24), mm7 ); pand_m2r( shiftmask, mm0 ); pand_m2r( shiftmask, mm1 ); pand_m2r( shiftmask, mm2 ); pand_m2r( shiftmask, mm3 ); pand_m2r( shiftmask, mm4 ); pand_m2r( shiftmask, mm5 ); pand_m2r( shiftmask, mm6 ); pand_m2r( shiftmask, mm7 ); psrlw_i2r( 1, mm0 ); psrlw_i2r( 1, mm1 ); psrlw_i2r( 1, mm2 ); psrlw_i2r( 1, mm3 ); psrlw_i2r( 1, mm4 ); psrlw_i2r( 1, mm5 ); psrlw_i2r( 1, mm6 ); psrlw_i2r( 1, mm7 ); paddb_r2r( mm1, mm0 ); paddb_r2r( mm3, mm2 ); paddb_r2r( mm5, mm4 ); paddb_r2r( mm7, mm6 ); movq_r2m( mm0, *output ); movq_r2m( mm2, *(output + 8) ); movq_r2m( mm4, *(output + 16) ); movq_r2m( mm6, *(output + 24) ); output += 32; top += 32; bot += 32; } width = (width & 0xf); for( i = width/4; i; --i ) { movq_m2r( *bot, mm0 ); movq_m2r( *top, mm1 ); pand_m2r( shiftmask, mm0 ); pand_m2r( shiftmask, mm1 ); psrlw_i2r( 1, mm0 ); psrlw_i2r( 1, mm1 ); paddb_r2r( mm1, mm0 ); movq_r2m( mm0, *output ); output += 8; top += 8; bot += 8; } width = width & 0x7; /* Handle last few pixels. */ for( i = width * 2; i; --i ) { *output++ = ((*top++) + (*bot++)) >> 1; } emms(); } #endif #if defined(ARCH_X86) static void interpolate_packed422_scanline_mmxext( uint8_t *output, uint8_t *top, uint8_t *bot, int width ) { int i; for( i = width/16; i; --i ) { movq_m2r( *bot, mm0 ); movq_m2r( *top, mm1 ); movq_m2r( *(bot + 8), mm2 ); movq_m2r( *(top + 8), mm3 ); movq_m2r( *(bot + 16), mm4 ); movq_m2r( *(top + 16), mm5 ); movq_m2r( *(bot + 24), mm6 ); movq_m2r( *(top + 24), mm7 ); pavgb_r2r( mm1, mm0 ); pavgb_r2r( mm3, mm2 ); pavgb_r2r( mm5, mm4 ); pavgb_r2r( mm7, mm6 ); movntq_r2m( mm0, *output ); movntq_r2m( mm2, *(output + 8) ); movntq_r2m( mm4, *(output + 16) ); movntq_r2m( mm6, *(output + 24) ); output += 32; top += 32; bot += 32; } width = (width & 0xf); for( i = width/4; i; --i ) { movq_m2r( *bot, mm0 ); movq_m2r( *top, mm1 ); pavgb_r2r( mm1, mm0 ); movntq_r2m( mm0, *output ); output += 8; top += 8; bot += 8; } width = width & 0x7; /* Handle last few pixels. */ for( i = width * 2; i; --i ) { *output++ = ((*top++) + (*bot++)) >> 1; } sfence(); emms(); } #endif static void blit_colour_packed422_scanline_c( uint8_t *output, int width, int y, int cb, int cr ) { uint32_t colour = cr << 24 | y << 16 | cb << 8 | y; uint32_t *o = (uint32_t *)ASSUME_ALIGNED_2 (output, 4); for( width /= 2; width; --width ) { *o++ = colour; } } #if defined(ARCH_X86) static void blit_colour_packed422_scanline_mmx( uint8_t *output, int width, int y, int cb, int cr ) { uint32_t colour = cr << 24 | y << 16 | cb << 8 | y; int i; movd_m2r( colour, mm1 ); movd_m2r( colour, mm2 ); psllq_i2r( 32, mm1 ); por_r2r( mm1, mm2 ); for( i = width / 16; i; --i ) { movq_r2m( mm2, *output ); movq_r2m( mm2, *(output + 8) ); movq_r2m( mm2, *(output + 16) ); movq_r2m( mm2, *(output + 24) ); output += 32; } width = (width & 0xf); for( i = width / 4; i; --i ) { movq_r2m( mm2, *output ); output += 8; } width = (width & 0x7); for( i = width / 2; i; --i ) { *((uint32_t *) output) = colour; output += 4; } if( width & 1 ) { *output = y; *(output + 1) = cb; } emms(); } #endif #if defined(ARCH_X86) static void blit_colour_packed422_scanline_mmxext( uint8_t *output, int width, int y, int cb, int cr ) { uint32_t colour = cr << 24 | y << 16 | cb << 8 | y; int i; movd_m2r( colour, mm1 ); movd_m2r( colour, mm2 ); psllq_i2r( 32, mm1 ); por_r2r( mm1, mm2 ); for( i = width / 16; i; --i ) { movntq_r2m( mm2, *output ); movntq_r2m( mm2, *(output + 8) ); movntq_r2m( mm2, *(output + 16) ); movntq_r2m( mm2, *(output + 24) ); output += 32; } width = (width & 0xf); for( i = width / 4; i; --i ) { movntq_r2m( mm2, *output ); output += 8; } width = (width & 0x7); for( i = width / 2; i; --i ) { *((uint32_t *) output) = colour; output += 4; } if( width & 1 ) { *output = y; *(output + 1) = cb; } sfence(); emms(); } #endif static void blit_colour_packed4444_scanline_c( uint8_t *output, int width, int alpha, int luma, int cb, int cr ) { int j; for( j = 0; j < width; j++ ) { *output++ = alpha; *output++ = luma; *output++ = cb; *output++ = cr; } } #if defined(ARCH_X86) static void blit_colour_packed4444_scanline_mmx( uint8_t *output, int width, int alpha, int luma, int cb, int cr ) { uint32_t colour = (cr << 24) | (cb << 16) | (luma << 8) | alpha; int i; movd_m2r( colour, mm1 ); movd_m2r( colour, mm2 ); psllq_i2r( 32, mm1 ); por_r2r( mm1, mm2 ); for( i = width / 8; i; --i ) { movq_r2m( mm2, *output ); movq_r2m( mm2, *(output + 8) ); movq_r2m( mm2, *(output + 16) ); movq_r2m( mm2, *(output + 24) ); output += 32; } width = (width & 0x7); for( i = width / 2; i; --i ) { movq_r2m( mm2, *output ); output += 8; } width = (width & 0x1); if( width ) { uint32_t *d = (uint32_t *)ASSUME_ALIGNED_2 (output, 4); *d = colour; output += 4; } emms(); } #endif #if defined(ARCH_X86) static void blit_colour_packed4444_scanline_mmxext( uint8_t *output, int width, int alpha, int luma, int cb, int cr ) { uint32_t colour = (cr << 24) | (cb << 16) | (luma << 8) | alpha; int i; movd_m2r( colour, mm1 ); movd_m2r( colour, mm2 ); psllq_i2r( 32, mm1 ); por_r2r( mm1, mm2 ); for( i = width / 8; i; --i ) { movntq_r2m( mm2, *output ); movntq_r2m( mm2, *(output + 8) ); movntq_r2m( mm2, *(output + 16) ); movntq_r2m( mm2, *(output + 24) ); output += 32; } width = (width & 0x7); for( i = width / 2; i; --i ) { movntq_r2m( mm2, *output ); output += 8; } width = (width & 0x1); if( width ) { uint32_t *d = (uint32_t *)ASSUME_ALIGNED_2 (output, 4); *d = colour; output += 4; } sfence(); emms(); } #endif #define speedy_memcpy_c xine_fast_memcpy #define speedy_memcpy_mmx xine_fast_memcpy #define speedy_memcpy_mmxext xine_fast_memcpy static void blit_packed422_scanline_c( uint8_t *dest, const uint8_t *src, int width ) { speedy_memcpy_c( dest, src, width*2 ); } #if defined(ARCH_X86) static void blit_packed422_scanline_mmx( uint8_t *dest, const uint8_t *src, int width ) { speedy_memcpy_mmx( dest, src, width*2 ); } #endif #if defined(ARCH_X86) static void blit_packed422_scanline_mmxext( uint8_t *dest, const uint8_t *src, int width ) { speedy_memcpy_mmxext( dest, src, width*2 ); } #endif static void composite_packed4444_alpha_to_packed422_scanline_c( uint8_t *output, uint8_t *input, uint8_t *foreground, int width, int alpha ) { int i; for( i = 0; i < width; i++ ) { int af = foreground[ 0 ]; if( af ) { int a = ((af * alpha) + 0x80) >> 8; if( a == 0xff ) { output[ 0 ] = foreground[ 1 ]; if( ( i & 1 ) == 0 ) { output[ 1 ] = foreground[ 2 ]; output[ 3 ] = foreground[ 3 ]; } } else if( a ) { /** * (1 - alpha)*B + alpha*F * (1 - af*a)*B + af*a*F * B - af*a*B + af*a*F * B + a*(af*F - af*B) */ output[ 0 ] = input[ 0 ] + ((alpha*( foreground[ 1 ] - multiply_alpha( foreground[ 0 ], input[ 0 ] ) ) + 0x80) >> 8); if( ( i & 1 ) == 0 ) { /** * At first I thought I was doing this incorrectly, but * the following math has convinced me otherwise. * * C_r = (1 - alpha)*B + alpha*F * C_r = B - af*a*B + af*a*F * * C_r = 128 + ((1 - af*a)*(B - 128) + a*af*(F - 128)) * C_r = 128 + (B - af*a*B - 128 + af*a*128 + a*af*F - a*af*128) * C_r = B - af*a*B + a*af*F */ output[ 1 ] = input[ 1 ] + ((alpha*( foreground[ 2 ] - multiply_alpha( foreground[ 0 ], input[ 1 ] ) ) + 0x80) >> 8); output[ 3 ] = input[ 3 ] + ((alpha*( foreground[ 3 ] - multiply_alpha( foreground[ 0 ], input[ 3 ] ) ) + 0x80) >> 8); } } } foreground += 4; output += 2; input += 2; } } #if defined(ARCH_X86) static void composite_packed4444_alpha_to_packed422_scanline_mmxext( uint8_t *output, uint8_t *input, uint8_t *foreground, int width, int alpha ) { const mmx_t alpha2 = { 0x0000FFFF00000000ULL }; const mmx_t alpha1 = { 0xFFFF0000FFFFFFFFULL }; const mmx_t round = { 0x0080008000800080ULL }; int i; if( !alpha ) { blit_packed422_scanline( output, input, width ); return; } if( alpha == 256 ) { composite_packed4444_to_packed422_scanline( output, input, foreground, width ); return; } READ_PREFETCH_2048( input ); READ_PREFETCH_2048( foreground ); movq_m2r( alpha, mm2 ); pshufw_r2r( mm2, mm2, 0 ); pxor_r2r( mm7, mm7 ); for( i = width/2; i; i-- ) { int fg1 = *((uint32_t *) foreground); int fg2 = *(((uint32_t *) foreground)+1); if( fg1 || fg2 ) { /* mm1 = [ cr ][ y ][ cb ][ y ] */ movd_m2r( *input, mm1 ); punpcklbw_r2r( mm7, mm1 ); movq_m2r( *foreground, mm3 ); movq_r2r( mm3, mm4 ); punpcklbw_r2r( mm7, mm3 ); punpckhbw_r2r( mm7, mm4 ); /* mm3 and mm4 will be the appropriate colours, mm5 and mm6 for alpha. */ /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 0 a ][ 0 a ][ 0 a ][ 0 a ] */ pshufw_r2r( mm3, mm5, 0 ); pshufw_r2r( mm4, mm6, 0 ); /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 3 cr ][ 0 a ][ 2 cb ][ 1 y ] == 11001000 == 201 */ pshufw_r2r( mm3, mm3, 201 ); /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 0 a ][ 1 y ][ 0 a ][ 0 a ] == 00010000 == 16 */ pshufw_r2r( mm4, mm4, 16 ); pand_m2r( alpha1, mm3 ); pand_m2r( alpha2, mm4 ); pand_m2r( alpha1, mm5 ); pand_m2r( alpha2, mm6 ); por_r2r( mm4, mm3 ); por_r2r( mm6, mm5 ); /* now, mm5 is af and mm1 is B. Need to multiply them. */ pmullw_r2r( mm1, mm5 ); /* Multiply by appalpha. */ pmullw_r2r( mm2, mm3 ); paddw_m2r( round, mm3 ); psrlw_i2r( 8, mm3 ); /* Result is now B + F. */ paddw_r2r( mm3, mm1 ); /* Round up appropriately. */ paddw_m2r( round, mm5 ); /* mm6 contains our i>>8; */ movq_r2r( mm5, mm6 ); psrlw_i2r( 8, mm6 ); /* Add mm6 back into mm5. Now our result is in the high bytes. */ paddw_r2r( mm6, mm5 ); /* Shift down. */ psrlw_i2r( 8, mm5 ); /* Multiply by appalpha. */ pmullw_r2r( mm2, mm5 ); paddw_m2r( round, mm5 ); psrlw_i2r( 8, mm5 ); psubusw_r2r( mm5, mm1 ); /* mm1 = [ B + F - af*B ] */ packuswb_r2r( mm1, mm1 ); movd_r2m( mm1, *output ); } foreground += 8; output += 4; input += 4; } sfence(); emms(); } #endif static void composite_packed4444_to_packed422_scanline_c( uint8_t *output, uint8_t *input, uint8_t *foreground, int width ) { int i; for( i = 0; i < width; i++ ) { int a = foreground[ 0 ]; if( a == 0xff ) { output[ 0 ] = foreground[ 1 ]; if( ( i & 1 ) == 0 ) { output[ 1 ] = foreground[ 2 ]; output[ 3 ] = foreground[ 3 ]; } } else if( a ) { /** * (1 - alpha)*B + alpha*F * B + af*F - af*B */ output[ 0 ] = input[ 0 ] + foreground[ 1 ] - multiply_alpha( foreground[ 0 ], input[ 0 ] ); if( ( i & 1 ) == 0 ) { /** * C_r = (1 - af)*B + af*F * C_r = B - af*B + af*F */ output[ 1 ] = input[ 1 ] + foreground[ 2 ] - multiply_alpha( foreground[ 0 ], input[ 1 ] ); output[ 3 ] = input[ 3 ] + foreground[ 3 ] - multiply_alpha( foreground[ 0 ], input[ 3 ] ); } } foreground += 4; output += 2; input += 2; } } #if defined(ARCH_X86) static void composite_packed4444_to_packed422_scanline_mmxext( uint8_t *output, uint8_t *input, uint8_t *foreground, int width ) { const mmx_t alpha2 = { 0x0000FFFF00000000ULL }; const mmx_t alpha1 = { 0xFFFF0000FFFFFFFFULL }; const mmx_t round = { 0x0080008000800080ULL }; int i; READ_PREFETCH_2048( input ); READ_PREFETCH_2048( foreground ); pxor_r2r( mm7, mm7 ); for( i = width/2; i; i-- ) { int fg1 = *((uint32_t *) foreground); int fg2 = *(((uint32_t *) foreground)+1); if( (fg1 & 0xff) == 0xff && (fg2 & 0xff) == 0xff ) { movq_m2r( *foreground, mm3 ); movq_r2r( mm3, mm4 ); punpcklbw_r2r( mm7, mm3 ); punpckhbw_r2r( mm7, mm4 ); /* mm3 and mm4 will be the appropriate colours, mm5 and mm6 for alpha. */ /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 3 cr ][ 0 a ][ 2 cb ][ 1 y ] == 11001000 == 201 */ pshufw_r2r( mm3, mm3, 201 ); /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 0 a ][ 1 y ][ 0 a ][ 0 a ] == 00010000 == 16 */ pshufw_r2r( mm4, mm4, 16 ); pand_m2r( alpha1, mm3 ); pand_m2r( alpha2, mm4 ); por_r2r( mm4, mm3 ); /* mm1 = [ B + F - af*B ] */ packuswb_r2r( mm3, mm3 ); movd_r2m( mm3, *output ); } else if( fg1 || fg2 ) { /* mm1 = [ cr ][ y ][ cb ][ y ] */ movd_m2r( *input, mm1 ); punpcklbw_r2r( mm7, mm1 ); movq_m2r( *foreground, mm3 ); movq_r2r( mm3, mm4 ); punpcklbw_r2r( mm7, mm3 ); punpckhbw_r2r( mm7, mm4 ); /* mm3 and mm4 will be the appropriate colours, mm5 and mm6 for alpha. */ /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 0 a ][ 0 a ][ 0 a ][ 0 a ] */ pshufw_r2r( mm3, mm5, 0 ); pshufw_r2r( mm4, mm6, 0 ); /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 3 cr ][ 0 a ][ 2 cb ][ 1 y ] == 11001000 == 201 */ pshufw_r2r( mm3, mm3, 201 ); /* [ 3 cr ][ 2 cb ][ 1 y ][ 0 a ] -> [ 0 a ][ 1 y ][ 0 a ][ 0 a ] == 00010000 == 16 */ pshufw_r2r( mm4, mm4, 16 ); pand_m2r( alpha1, mm3 ); pand_m2r( alpha2, mm4 ); pand_m2r( alpha1, mm5 ); pand_m2r( alpha2, mm6 ); por_r2r( mm4, mm3 ); por_r2r( mm6, mm5 ); /* now, mm5 is af and mm1 is B. Need to multiply them. */ pmullw_r2r( mm1, mm5 ); /* Result is now B + F. */ paddw_r2r( mm3, mm1 ); /* Round up appropriately. */ paddw_m2r( round, mm5 ); /* mm6 contains our i>>8; */ movq_r2r( mm5, mm6 ); psrlw_i2r( 8, mm6 ); /* Add mm6 back into mm5. Now our result is in the high bytes. */ paddw_r2r( mm6, mm5 ); /* Shift down. */ psrlw_i2r( 8, mm5 ); psubusw_r2r( mm5, mm1 ); /* mm1 = [ B + F - af*B ] */ packuswb_r2r( mm1, mm1 ); movd_r2m( mm1, *output ); } foreground += 8; output += 4; input += 4; } sfence(); emms(); } #endif /** * um... just need some scrap paper... * D = (1 - alpha)*B + alpha*F * D = (1 - a)*B + a*textluma * = B - a*B + a*textluma * = B + a*(textluma - B) * Da = (1 - a)*b + a */ static void composite_alphamask_to_packed4444_scanline_c( uint8_t *output, uint8_t *input, uint8_t *mask, int width, int textluma, int textcb, int textcr ) { uint32_t opaque = (textcr << 24) | (textcb << 16) | (textluma << 8) | 0xff; int i; for( i = 0; i < width; i++ ) { int a = *mask; uint32_t *d = (uint32_t *)ASSUME_ALIGNED_2 (output, 4); if( a == 0xff ) { *d = opaque; } else if( input[ 0 ] == 0x00 ) { *d = (multiply_alpha (a, textcr) << 24) | (multiply_alpha( a, textcb) << 16) | (multiply_alpha( a, textluma ) << 8) | a; } else if( a ) { *d = ((input[3] + multiply_alpha (a, textcr - input[3])) << 24) | ((input[2] + multiply_alpha (a, textcb - input[2])) << 16) | ((input[1] + multiply_alpha (a, textluma - input[1])) << 8) | (input[0] + multiply_alpha (a, 0xff - input[0])); } mask++; output += 4; input += 4; } } #if defined(ARCH_X86) static void composite_alphamask_to_packed4444_scanline_mmxext( uint8_t *output, uint8_t *input, uint8_t *mask, int width, int textluma, int textcb, int textcr ) { uint32_t opaque = (textcr << 24) | (textcb << 16) | (textluma << 8) | 0xff; const mmx_t round = { 0x0080008000800080ULL }; const mmx_t fullalpha = { 0x00000000000000ffULL }; mmx_t colour; colour.w[ 0 ] = 0x00; colour.w[ 1 ] = textluma; colour.w[ 2 ] = textcb; colour.w[ 3 ] = textcr; movq_m2r( colour, mm1 ); movq_r2r( mm1, mm0 ); /* mm0 = [ cr ][ cb ][ y ][ 0xff ] */ paddw_m2r( fullalpha, mm0 ); /* mm7 = 0 */ pxor_r2r( mm7, mm7 ); /* mm6 = round */ movq_m2r( round, mm6 ); while( width-- ) { int a = *mask; if( a == 0xff ) { uint32_t *d = (uint32_t *)ASSUME_ALIGNED_2 (output, 4); *d = opaque; } else if( input[ 0 ] == 0x00 ) { /* We just need to multiply our colour by the alpha value. */ /* mm2 = [ a ][ a ][ a ][ a ] */ movd_m2r( a, mm2 ); movq_r2r( mm2, mm3 ); pshufw_r2r( mm2, mm2, 0 ); /* mm5 = [ cr ][ cb ][ y ][ 0 ] */ movq_r2r( mm1, mm5 ); /* Multiply by alpha. */ pmullw_r2r( mm2, mm5 ); paddw_m2r( round, mm5 ); movq_r2r( mm5, mm6 ); psrlw_i2r( 8, mm6 ); paddw_r2r( mm6, mm5 ); psrlw_i2r( 8, mm5 ); /* Set alpha to a. */ por_r2r( mm3, mm5 ); /* Pack and write our result. */ packuswb_r2r( mm5, mm5 ); movd_r2m( mm5, *output ); } else if( a ) { /* mm2 = [ a ][ a ][ a ][ a ] */ movd_m2r( a, mm2 ); pshufw_r2r( mm2, mm2, 0 ); /* mm3 = [ cr ][ cb ][ y ][ 0xff ] */ movq_r2r( mm0, mm3 ); /* mm4 = [ i_cr ][ i_cb ][ i_y ][ i_a ] */ movd_m2r( *input, mm4 ); punpcklbw_r2r( mm7, mm4 ); /* Subtract input and colour. */ psubw_r2r( mm4, mm3 ); /* mm3 = mm3 - mm4 */ /* Multiply alpha. */ pmullw_r2r( mm2, mm3 ); paddw_r2r( mm6, mm3 ); movq_r2r( mm3, mm2 ); psrlw_i2r( 8, mm3 ); paddw_r2r( mm2, mm3 ); psrlw_i2r( 8, mm3 ); /* Add back in the input. */ paddb_r2r( mm3, mm4 ); /* Write result. */ packuswb_r2r( mm4, mm4 ); movd_r2m( mm4, *output ); } mask++; output += 4; input += 4; } sfence(); emms(); } #endif static void composite_alphamask_alpha_to_packed4444_scanline_c( uint8_t *output, uint8_t *input, uint8_t *mask, int width, int textluma, int textcb, int textcr, int alpha ) { uint32_t opaque = (textcr << 24) | (textcb << 16) | (textluma << 8) | 0xff; int i; for( i = 0; i < width; i++ ) { int af = *mask; if( af ) { int a = ((af * alpha) + 0x80) >> 8; uint32_t *d = (uint32_t *)ASSUME_ALIGNED_2 (output, 4); if( a == 0xff ) { *d = opaque; } else if( input[ 0 ] == 0x00 ) { *d = (multiply_alpha (a, textcr) << 24) | (multiply_alpha (a, textcb) << 16) | (multiply_alpha (a, textluma) << 8) | a; } else if( a ) { *d = ((input[3] + multiply_alpha (a, textcr - input[3])) << 24) | ((input[2] + multiply_alpha (a, textcb - input[2])) << 16) | ((input[1] + multiply_alpha (a, textluma - input[1])) << 8) | (a + multiply_alpha (0xff - a, input[0])); } } mask++; output += 4; input += 4; } } static void premultiply_packed4444_scanline_c( uint8_t *output, uint8_t *input, int width ) { uint32_t *d = (uint32_t *)ASSUME_ALIGNED_2 (output, 4); while( width-- ) { unsigned int cur_a = input[ 0 ]; *d = (multiply_alpha (cur_a, input[3]) << 24) | (multiply_alpha (cur_a, input[2]) << 16) | (multiply_alpha (cur_a, input[1]) << 8) | cur_a; d += 1; input += 4; } } #if defined(ARCH_X86) static void premultiply_packed4444_scanline_mmxext( uint8_t *output, uint8_t *input, int width ) { const mmx_t round = { 0x0080008000800080ULL }; const mmx_t alpha = { 0x00000000000000ffULL }; const mmx_t noalp = { 0xffffffffffff0000ULL }; pxor_r2r( mm7, mm7 ); while( width-- ) { movd_m2r( *input, mm0 ); punpcklbw_r2r( mm7, mm0 ); movq_r2r( mm0, mm2 ); pshufw_r2r( mm2, mm2, 0 ); movq_r2r( mm2, mm4 ); pand_m2r( alpha, mm4 ); pmullw_r2r( mm2, mm0 ); paddw_m2r( round, mm0 ); movq_r2r( mm0, mm3 ); psrlw_i2r( 8, mm3 ); paddw_r2r( mm3, mm0 ); psrlw_i2r( 8, mm0 ); pand_m2r( noalp, mm0 ); paddw_r2r( mm4, mm0 ); packuswb_r2r( mm0, mm0 ); movd_r2m( mm0, *output ); output += 4; input += 4; } sfence(); emms(); } #endif static void blend_packed422_scanline_c( uint8_t *output, uint8_t *src1, uint8_t *src2, int width, int pos ) { if( pos == 0 ) { blit_packed422_scanline( output, src1, width ); } else if( pos == 256 ) { blit_packed422_scanline( output, src2, width ); } else if( pos == 128 ) { interpolate_packed422_scanline( output, src1, src2, width ); } else { width *= 2; while( width-- ) { *output++ = ( (*src1++ * ( 256 - pos )) + (*src2++ * pos) + 0x80 ) >> 8; } } } #if defined(ARCH_X86) static void blend_packed422_scanline_mmxext( uint8_t *output, uint8_t *src1, uint8_t *src2, int width, int pos ) { if( pos <= 0 ) { blit_packed422_scanline( output, src1, width ); } else if( pos >= 256 ) { blit_packed422_scanline( output, src2, width ); } else if( pos == 128 ) { interpolate_packed422_scanline( output, src1, src2, width ); } else { const mmx_t all256 = { 0x0100010001000100ULL }; const mmx_t round = { 0x0080008000800080ULL }; movd_m2r( pos, mm0 ); pshufw_r2r( mm0, mm0, 0 ); movq_m2r( all256, mm1 ); psubw_r2r( mm0, mm1 ); pxor_r2r( mm7, mm7 ); for( width /= 2; width; width-- ) { movd_m2r( *src1, mm3 ); movd_m2r( *src2, mm4 ); punpcklbw_r2r( mm7, mm3 ); punpcklbw_r2r( mm7, mm4 ); pmullw_r2r( mm1, mm3 ); pmullw_r2r( mm0, mm4 ); paddw_r2r( mm4, mm3 ); paddw_m2r( round, mm3 ); psrlw_i2r( 8, mm3 ); packuswb_r2r( mm3, mm3 ); movd_r2m( mm3, *output ); output += 4; src1 += 4; src2 += 4; } sfence(); emms(); } } #endif #if defined(ARCH_X86) static void quarter_blit_vertical_packed422_scanline_mmxext( uint8_t *output, uint8_t *one, uint8_t *three, int width ) { int i; for( i = width/16; i; --i ) { movq_m2r( *one, mm0 ); movq_m2r( *three, mm1 ); movq_m2r( *(one + 8), mm2 ); movq_m2r( *(three + 8), mm3 ); movq_m2r( *(one + 16), mm4 ); movq_m2r( *(three + 16), mm5 ); movq_m2r( *(one + 24), mm6 ); movq_m2r( *(three + 24), mm7 ); pavgb_r2r( mm1, mm0 ); pavgb_r2r( mm1, mm0 ); pavgb_r2r( mm3, mm2 ); pavgb_r2r( mm3, mm2 ); pavgb_r2r( mm5, mm4 ); pavgb_r2r( mm5, mm4 ); pavgb_r2r( mm7, mm6 ); pavgb_r2r( mm7, mm6 ); movntq_r2m( mm0, *output ); movntq_r2m( mm2, *(output + 8) ); movntq_r2m( mm4, *(output + 16) ); movntq_r2m( mm6, *(output + 24) ); output += 32; one += 32; three += 32; } width = (width & 0xf); for( i = width/4; i; --i ) { movq_m2r( *one, mm0 ); movq_m2r( *three, mm1 ); pavgb_r2r( mm1, mm0 ); pavgb_r2r( mm1, mm0 ); movntq_r2m( mm0, *output ); output += 8; one += 8; three += 8; } width = width & 0x7; /* Handle last few pixels. */ for( i = width * 2; i; --i ) { *output++ = (*one + *three + *three + *three + 2) / 4; one++; three++; } sfence(); emms(); } #endif static void quarter_blit_vertical_packed422_scanline_c( uint8_t *output, uint8_t *one, uint8_t *three, int width ) { width *= 2; while( width-- ) { *output++ = (*one + *three + *three + *three + 2) / 4; one++; three++; } } static void subpix_blit_vertical_packed422_scanline_c( uint8_t *output, uint8_t *top, uint8_t *bot, int subpixpos, int width ) { if( subpixpos == 32768 ) { interpolate_packed422_scanline( output, top, bot, width ); } else if( subpixpos == 16384 ) { quarter_blit_vertical_packed422_scanline( output, top, bot, width ); } else if( subpixpos == 49152 ) { quarter_blit_vertical_packed422_scanline( output, bot, top, width ); } else { int x; width *= 2; for( x = 0; x < width; x++ ) { output[ x ] = ( ( top[ x ] * subpixpos ) + ( bot[ x ] * ( 0xffff - subpixpos ) ) ) >> 16; } } } static void a8_subpix_blit_scanline_c( uint8_t *output, uint8_t *input, int lasta, int startpos, int width ) { int pos = 0xffff - (startpos & 0xffff); int prev = lasta; int x; for( x = 0; x < width; x++ ) { output[ x ] = ( ( prev * pos ) + ( input[ x ] * ( 0xffff - pos ) ) ) >> 16; prev = input[ x ]; } } /** * These are from lavtools in mjpegtools: * * colorspace.c: Routines to perform colorspace conversions. * * Copyright (C) 2001 Matthew J. Marjanovic <maddog@mir.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #define FP_BITS 18 /* precomputed tables */ static int Y_R[256]; static int Y_G[256]; static int Y_B[256]; static int Cb_R[256]; static int Cb_G[256]; static int Cb_B[256]; static int Cr_R[256]; static int Cr_G[256]; static int Cr_B[256]; static int conv_RY_inited = 0; static int RGB_Y[256]; static int R_Cr[256]; static int G_Cb[256]; static int G_Cr[256]; static int B_Cb[256]; static int conv_YR_inited = 0; static int myround(double n) { if (n >= 0) return (int)(n + 0.5); else return (int)(n - 0.5); } static void init_RGB_to_YCbCr_tables(void) { int i; /* * Q_Z[i] = (coefficient * i * * (Q-excursion) / (Z-excursion) * fixed-point-factor) * * to one of each, add the following: * + (fixed-point-factor / 2) --- for rounding later * + (Q-offset * fixed-point-factor) --- to add the offset * */ for (i = 0; i < 256; i++) { Y_R[i] = myround(0.299 * (double)i * 219.0 / 255.0 * (double)(1<<FP_BITS)); Y_G[i] = myround(0.587 * (double)i * 219.0 / 255.0 * (double)(1<<FP_BITS)); Y_B[i] = myround((0.114 * (double)i * 219.0 / 255.0 * (double)(1<<FP_BITS)) + (double)(1<<(FP_BITS-1)) + (16.0 * (double)(1<<FP_BITS))); Cb_R[i] = myround(-0.168736 * (double)i * 224.0 / 255.0 * (double)(1<<FP_BITS)); Cb_G[i] = myround(-0.331264 * (double)i * 224.0 / 255.0 * (double)(1<<FP_BITS)); Cb_B[i] = myround((0.500 * (double)i * 224.0 / 255.0 * (double)(1<<FP_BITS)) + (double)(1<<(FP_BITS-1)) + (128.0 * (double)(1<<FP_BITS))); Cr_R[i] = myround(0.500 * (double)i * 224.0 / 255.0 * (double)(1<<FP_BITS)); Cr_G[i] = myround(-0.418688 * (double)i * 224.0 / 255.0 * (double)(1<<FP_BITS)); Cr_B[i] = myround((-0.081312 * (double)i * 224.0 / 255.0 * (double)(1<<FP_BITS)) + (double)(1<<(FP_BITS-1)) + (128.0 * (double)(1<<FP_BITS))); } conv_RY_inited = 1; } static void init_YCbCr_to_RGB_tables(void) { int i; /* * Q_Z[i] = (coefficient * i * * (Q-excursion) / (Z-excursion) * fixed-point-factor) * * to one of each, add the following: * + (fixed-point-factor / 2) --- for rounding later * + (Q-offset * fixed-point-factor) --- to add the offset * */ /* clip Y values under 16 */ for (i = 0; i < 16; i++) { RGB_Y[i] = myround((1.0 * (double)(16) * 255.0 / 219.0 * (double)(1<<FP_BITS)) + (double)(1<<(FP_BITS-1))); } for (i = 16; i < 236; i++) { RGB_Y[i] = myround((1.0 * (double)(i - 16) * 255.0 / 219.0 * (double)(1<<FP_BITS)) + (double)(1<<(FP_BITS-1))); } /* clip Y values above 235 */ for (i = 236; i < 256; i++) { RGB_Y[i] = myround((1.0 * (double)(235) * 255.0 / 219.0 * (double)(1<<FP_BITS)) + (double)(1<<(FP_BITS-1))); } /* clip Cb/Cr values below 16 */ for (i = 0; i < 16; i++) { R_Cr[i] = myround(1.402 * (double)(-112) * 255.0 / 224.0 * (double)(1<<FP_BITS)); G_Cr[i] = myround(-0.714136 * (double)(-112) * 255.0 / 224.0 * (double)(1<<FP_BITS)); G_Cb[i] = myround(-0.344136 * (double)(-112) * 255.0 / 224.0 * (double)(1<<FP_BITS)); B_Cb[i] = myround(1.772 * (double)(-112) * 255.0 / 224.0 * (double)(1<<FP_BITS)); } for (i = 16; i < 241; i++) { R_Cr[i] = myround(1.402 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<FP_BITS)); G_Cr[i] = myround(-0.714136 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<FP_BITS)); G_Cb[i] = myround(-0.344136 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<FP_BITS)); B_Cb[i] = myround(1.772 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<FP_BITS)); } /* clip Cb/Cr values above 240 */ for (i = 241; i < 256; i++) { R_Cr[i] = myround(1.402 * (double)(112) * 255.0 / 224.0 * (double)(1<<FP_BITS)); G_Cr[i] = myround(-0.714136 * (double)(112) * 255.0 / 224.0 * (double)(1<<FP_BITS)); G_Cb[i] = myround(-0.344136 * (double)(i - 128) * 255.0 / 224.0 * (double)(1<<FP_BITS)); B_Cb[i] = myround(1.772 * (double)(112) * 255.0 / 224.0 * (double)(1<<FP_BITS)); } conv_YR_inited = 1; } static void rgb24_to_packed444_rec601_scanline_c( uint8_t *output, uint8_t *input, int width ) { if( !conv_RY_inited ) init_RGB_to_YCbCr_tables(); while( width-- ) { int r = input[ 0 ]; int g = input[ 1 ]; int b = input[ 2 ]; output[ 0 ] = (Y_R[ r ] + Y_G[ g ] + Y_B[ b ]) >> FP_BITS; output[ 1 ] = (Cb_R[ r ] + Cb_G[ g ] + Cb_B[ b ]) >> FP_BITS; output[ 2 ] = (Cr_R[ r ] + Cr_G[ g ] + Cr_B[ b ]) >> FP_BITS; output += 3; input += 3; } } static void rgba32_to_packed4444_rec601_scanline_c( uint8_t *output, uint8_t *input, int width ) { if( !conv_RY_inited ) init_RGB_to_YCbCr_tables(); while( width-- ) { int r = input[ 0 ]; int g = input[ 1 ]; int b = input[ 2 ]; int a = input[ 3 ]; output[ 0 ] = a; output[ 1 ] = (Y_R[ r ] + Y_G[ g ] + Y_B[ b ]) >> FP_BITS; output[ 2 ] = (Cb_R[ r ] + Cb_G[ g ] + Cb_B[ b ]) >> FP_BITS; output[ 3 ] = (Cr_R[ r ] + Cr_G[ g ] + Cr_B[ b ]) >> FP_BITS; output += 4; input += 4; } } static void packed444_to_rgb24_rec601_scanline_c( uint8_t *output, uint8_t *input, int width ) { if( !conv_YR_inited ) init_YCbCr_to_RGB_tables(); while( width-- ) { int luma = input[ 0 ]; int cb = input[ 1 ]; int cr = input[ 2 ]; output[ 0 ] = clip255( (RGB_Y[ luma ] + R_Cr[ cr ]) >> FP_BITS ); output[ 1 ] = clip255( (RGB_Y[ luma ] + G_Cb[ cb ] + G_Cr[cr]) >> FP_BITS ); output[ 2 ] = clip255( (RGB_Y[ luma ] + B_Cb[ cb ]) >> FP_BITS ); output += 3; input += 3; } } /** * 601 numbers: * * Y' = 0.299*R' + 0.587*G' + 0.114*B' (in 0.0 to 1.0) * Cb = -0.169*R' - 0.331*G' + 0.500*B' (in -0.5 to +0.5) * Cr = 0.500*R' - 0.419*G' - 0.081*B' (in -0.5 to +0.5) * * Inverse: * Y Cb Cr * R 1.0000 -0.0009 1.4017 * G 1.0000 -0.3437 -0.7142 * B 1.0000 1.7722 0.0010 * * S170M numbers: * Y' = 0.299*R' + 0.587*G' + 0.114*B' (in 0.0 to 1.0) * B-Y' = -0.299*R' - 0.587*G' + 0.886*B' * R-Y' = 0.701*R' - 0.587*G' - 0.114*B' */ /* static void packed444_to_rgb24_rec601_reference_scanline( uint8_t *output, uint8_t *input, int width ) { while( width-- ) { double yp = (((double) input[ 0 ]) - 16.0) / 255.0; double cb = (((double) input[ 1 ]) - 128.0) / 255.0; double cr = (((double) input[ 2 ]) - 128.0) / 255.0; double r, g, b; r = yp - (0.0009*cb) + (1.4017*cr); g = yp - (0.3437*cb) - (0.7142*cr); b = yp + (1.7722*cb) + (0.0010*cr); if( r > 1.0 ) r = 1.0; else if( r < 0.0 ) r = 0.0; if( g > 1.0 ) g = 1.0; else if( g < 0.0 ) g = 0.0; if( b > 1.0 ) b = 1.0; else if( b < 0.0 ) b = 0.0; output[ 0 ] = (int) ((r * 255.0) + 0.5); output[ 1 ] = (int) ((g * 255.0) + 0.5); output[ 2 ] = (int) ((b * 255.0) + 0.5); output += 3; input += 3; } } */ static void packed444_to_nonpremultiplied_packed4444_scanline_c( uint8_t *output, uint8_t *input, int width, int alpha ) { int i; for( i = 0; i < width; i++ ) { output[ 0 ] = alpha & 0xff; output[ 1 ] = input[ 0 ] & 0xff; output[ 2 ] = input[ 1 ] & 0xff; output[ 3 ] = input[ 2 ] & 0xff; output += 4; input += 3; } } #if 0 static void aspect_adjust_packed4444_scanline_c( uint8_t *output, uint8_t *input, int width, double pixel_aspect ) { double i; int prev_i = 0; int w = 0; pixel_aspect = 1.0 / pixel_aspect; for( i = 0.0; i < width; i += pixel_aspect ) { uint8_t *curin = input + ((int) i)*4; if( !prev_i ) { output[ 0 ] = curin[ 0 ]; output[ 1 ] = curin[ 1 ]; output[ 2 ] = curin[ 2 ]; output[ 3 ] = curin[ 3 ]; } else { int avg_a = 0; int avg_y = 0; int avg_cb = 0; int avg_cr = 0; int pos = prev_i * 4; int c = 0; int j; for( j = prev_i; j <= (int) i; j++ ) { avg_a += input[ pos++ ]; avg_y += input[ pos++ ]; avg_cb += input[ pos++ ]; avg_cr += input[ pos++ ]; c++; } output[ 0 ] = avg_a / c; output[ 1 ] = avg_y / c; output[ 2 ] = avg_cb / c; output[ 3 ] = avg_cr / c; } output += 4; prev_i = (int) i; w++; } } #endif /** * Sub-pixel data bar renderer. There are 128 bars. */ static void composite_bars_packed4444_scanline_c( uint8_t *output, uint8_t *background, int width, int a, int luma, int cb, int cr, int percentage ) { /** * This is the size of both the bar and the spacing in between in subpixel * units out of 256. Yes, as it so happens, that puts it equal to 'width'. */ int barsize = ( width * 256 ) / 256; int i; /* We only need to composite the bar on the pixels that matter. */ for( i = 0; i < percentage; i++ ) { int barstart = i * barsize * 2; int barend = barstart + barsize; int pixstart = barstart / 256; int pixend = barend / 256; int j; for( j = pixstart; j <= pixend; j++ ) { uint8_t *curout = output + (j*4); uint8_t *curin = background + (j*4); int curstart = j * 256; int curend = curstart + 256; int alpha; if( barstart > curstart ) curstart = barstart; if( barend < curend ) curend = barend; if( curend - curstart < 256 ) { alpha = ( ( curend - curstart ) * a ) / 256; } else { alpha = a; } curout[ 0 ] = curin[ 0 ] + multiply_alpha( alpha - curin[ 0 ], alpha ); curout[ 1 ] = curin[ 1 ] + multiply_alpha( luma - curin[ 1 ], alpha ); curout[ 2 ] = curin[ 2 ] + multiply_alpha( cb - curin[ 2 ], alpha ); curout[ 3 ] = curin[ 3 ] + multiply_alpha( cr - curin[ 3 ], alpha ); } } } /* horizontal 1:2 interpolation filter */ static void chroma_422_to_444_mpeg2_plane_c( uint8_t *dst, uint8_t *src, int width, int height ) { int i, i2, w, j, im2, im1, ip1, ip2, ip3; w = width / 2; for( j = 0; j < height; j++ ) { for( i = 0; i < w; i++ ) { i2 = i << 1; im2 = (i<2) ? 0 : i-2; im1 = (i<1) ? 0 : i-1; ip1 = (i<w-1) ? i+1 : w-1; ip2 = (i<w-2) ? i+2 : w-1; ip3 = (i<w-3) ? i+3 : w-1; /* FIR filter coefficients (*256): 21 0 -52 0 159 256 159 0 -52 0 21 */ /* even samples (0 0 256 0 0) */ dst[ i2 ] = src[i]; /* odd samples (21 -52 159 159 -52 21) */ dst[ i2 + 1 ] = clip255( ( 21*(src[im2]+src[ip3]) - 52*(src[im1]+src[ip2]) + 159*(src[i]+src[ip1]) + 128 ) >> 8 ); } src += w; dst += width; } } /* vertical 1:2 interpolation filter */ static void chroma_420_to_422_mpeg2_plane_c( uint8_t *dst, uint8_t *src, int width, int height, int progressive ) { int w, h, i, j, j2; int jm6, jm5, jm4, jm3, jm2, jm1, jp1, jp2, jp3, jp4, jp5, jp6, jp7; w = width / 2; h = height / 2; if( progressive ) { /* intra frame */ for( i = 0; i < w; i++ ) { for( j = 0; j < h; j++ ) { j2 = j << 1; jm3 = (j<3) ? 0 : j-3; jm2 = (j<2) ? 0 : j-2; jm1 = (j<1) ? 0 : j-1; jp1 = (j<h-1) ? j+1 : h-1; jp2 = (j<h-2) ? j+2 : h-1; jp3 = (j<h-3) ? j+3 : h-1; /* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */ /* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */ dst[w*j2] = clip255( ( 3*src[w*jm3] - 16*src[w*jm2] + 67*src[w*jm1] + 227*src[w*j] - 32*src[w*jp1] + 7*src[w*jp2] + 128 ) >> 8 ); dst[w*(j2+1)] = clip255( ( 3*src[w*jp3] - 16*src[w*jp2] + 67*src[w*jp1] + 227*src[w*j] - 32*src[w*jm1] + 7*src[w*jm2] + 128 ) >> 8 ); } src++; dst++; } } else { /* intra field */ for( i = 0; i < w; i++ ) { for( j = 0; j < h; j += 2 ) { j2 = j << 1; /* top field */ jm6 = (j<6) ? 0 : j-6; jm4 = (j<4) ? 0 : j-4; jm2 = (j<2) ? 0 : j-2; jp2 = (j<h-2) ? j+2 : h-2; jp4 = (j<h-4) ? j+4 : h-2; jp6 = (j<h-6) ? j+6 : h-2; /* Polyphase FIR filter coefficients (*256): 2 -10 35 242 -18 5 */ /* New polyphase FIR filter coefficients (*256): 1 -7 30 248 -21 5 */ dst[w*j2] = clip255( ( 1*src[w*jm6] - 7*src[w*jm4] + 30*src[w*jm2] + 248*src[w*j] - 21*src[w*jp2] + 5*src[w*jp4] + 128 ) >> 8 ); /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */ /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */ dst[w*(j2+2)] = clip255( ( 7*src[w*jm4] -35*src[w*jm2] +194*src[w*j] +110*src[w*jp2] -24*src[w*jp4] +4*src[w*jp6] + 128 ) >> 8 ); /* bottom field */ jm5 = (j<5) ? 1 : j-5; jm3 = (j<3) ? 1 : j-3; jm1 = (j<1) ? 1 : j-1; jp1 = (j<h-1) ? j+1 : h-1; jp3 = (j<h-3) ? j+3 : h-1; jp5 = (j<h-5) ? j+5 : h-1; jp7 = (j<h-7) ? j+7 : h-1; /* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */ /* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */ dst[w*(j2+1)] = clip255( ( 7*src[w*jp5] -35*src[w*jp3] +194*src[w*jp1] +110*src[w*jm1] -24*src[w*jm3] +4*src[w*jm5] + 128 ) >> 8 ); dst[w*(j2+3)] = clip255( ( 1*src[w*jp7] -7*src[w*jp5] +30*src[w*jp3] +248*src[w*jp1] -21*src[w*jm1] +5*src[w*jm3] + 128 ) >> 8 ); } src++; dst++; } } } static uint32_t speedy_accel; void setup_speedy_calls( uint32_t accel, int verbose ) { speedy_accel = accel; interpolate_packed422_scanline = interpolate_packed422_scanline_c; blit_colour_packed422_scanline = blit_colour_packed422_scanline_c; blit_colour_packed4444_scanline = blit_colour_packed4444_scanline_c; blit_packed422_scanline = blit_packed422_scanline_c; composite_packed4444_to_packed422_scanline = composite_packed4444_to_packed422_scanline_c; composite_packed4444_alpha_to_packed422_scanline = composite_packed4444_alpha_to_packed422_scanline_c; composite_alphamask_to_packed4444_scanline = composite_alphamask_to_packed4444_scanline_c; composite_alphamask_alpha_to_packed4444_scanline = composite_alphamask_alpha_to_packed4444_scanline_c; premultiply_packed4444_scanline = premultiply_packed4444_scanline_c; blend_packed422_scanline = blend_packed422_scanline_c; filter_luma_121_packed422_inplace_scanline = filter_luma_121_packed422_inplace_scanline_c; filter_luma_14641_packed422_inplace_scanline = filter_luma_14641_packed422_inplace_scanline_c; comb_factor_packed422_scanline = 0; diff_factor_packed422_scanline = diff_factor_packed422_scanline_c; kill_chroma_packed422_inplace_scanline = kill_chroma_packed422_inplace_scanline_c; mirror_packed422_inplace_scanline = mirror_packed422_inplace_scanline_c; halfmirror_packed422_inplace_scanline = halfmirror_packed422_inplace_scanline_c; speedy_memcpy = speedy_memcpy_c; diff_packed422_block8x8 = diff_packed422_block8x8_c; a8_subpix_blit_scanline = a8_subpix_blit_scanline_c; quarter_blit_vertical_packed422_scanline = quarter_blit_vertical_packed422_scanline_c; subpix_blit_vertical_packed422_scanline = subpix_blit_vertical_packed422_scanline_c; composite_bars_packed4444_scanline = composite_bars_packed4444_scanline_c; packed444_to_nonpremultiplied_packed4444_scanline = packed444_to_nonpremultiplied_packed4444_scanline_c; #if 0 aspect_adjust_packed4444_scanline = aspect_adjust_packed4444_scanline_c; #endif packed444_to_packed422_scanline = packed444_to_packed422_scanline_c; packed422_to_packed444_scanline = packed422_to_packed444_scanline_c; packed422_to_packed444_rec601_scanline = packed422_to_packed444_rec601_scanline_c; packed444_to_rgb24_rec601_scanline = packed444_to_rgb24_rec601_scanline_c; rgb24_to_packed444_rec601_scanline = rgb24_to_packed444_rec601_scanline_c; rgba32_to_packed4444_rec601_scanline = rgba32_to_packed4444_rec601_scanline_c; chroma_422_to_444_mpeg2_plane = chroma_422_to_444_mpeg2_plane_c; chroma_420_to_422_mpeg2_plane = chroma_420_to_422_mpeg2_plane_c; invert_colour_packed422_inplace_scanline = invert_colour_packed422_inplace_scanline_c; vfilter_chroma_121_packed422_scanline = vfilter_chroma_121_packed422_scanline_c; vfilter_chroma_332_packed422_scanline = vfilter_chroma_332_packed422_scanline_c; #if defined(ARCH_X86) if( speedy_accel & MM_ACCEL_X86_MMXEXT ) { if( verbose ) { printf( "speedycode: Using MMXEXT optimized functions.\n" ); } interpolate_packed422_scanline = interpolate_packed422_scanline_mmxext; blit_colour_packed422_scanline = blit_colour_packed422_scanline_mmxext; blit_colour_packed4444_scanline = blit_colour_packed4444_scanline_mmxext; blit_packed422_scanline = blit_packed422_scanline_mmxext; composite_packed4444_to_packed422_scanline = composite_packed4444_to_packed422_scanline_mmxext; composite_packed4444_alpha_to_packed422_scanline = composite_packed4444_alpha_to_packed422_scanline_mmxext; composite_alphamask_to_packed4444_scanline = composite_alphamask_to_packed4444_scanline_mmxext; premultiply_packed4444_scanline = premultiply_packed4444_scanline_mmxext; kill_chroma_packed422_inplace_scanline = kill_chroma_packed422_inplace_scanline_mmx; blend_packed422_scanline = blend_packed422_scanline_mmxext; diff_factor_packed422_scanline = diff_factor_packed422_scanline_mmx; comb_factor_packed422_scanline = comb_factor_packed422_scanline_mmx; diff_packed422_block8x8 = diff_packed422_block8x8_mmx; quarter_blit_vertical_packed422_scanline = quarter_blit_vertical_packed422_scanline_mmxext; invert_colour_packed422_inplace_scanline = invert_colour_packed422_inplace_scanline_mmx; vfilter_chroma_121_packed422_scanline = vfilter_chroma_121_packed422_scanline_mmx; vfilter_chroma_332_packed422_scanline = vfilter_chroma_332_packed422_scanline_mmx; speedy_memcpy = speedy_memcpy_mmxext; } else if( speedy_accel & MM_ACCEL_X86_MMX ) { if( verbose ) { printf( "speedycode: Using MMX optimized functions.\n" ); } interpolate_packed422_scanline = interpolate_packed422_scanline_mmx; blit_colour_packed422_scanline = blit_colour_packed422_scanline_mmx; blit_colour_packed4444_scanline = blit_colour_packed4444_scanline_mmx; blit_packed422_scanline = blit_packed422_scanline_mmx; diff_factor_packed422_scanline = diff_factor_packed422_scanline_mmx; comb_factor_packed422_scanline = comb_factor_packed422_scanline_mmx; kill_chroma_packed422_inplace_scanline = kill_chroma_packed422_inplace_scanline_mmx; diff_packed422_block8x8 = diff_packed422_block8x8_mmx; invert_colour_packed422_inplace_scanline = invert_colour_packed422_inplace_scanline_mmx; vfilter_chroma_121_packed422_scanline = vfilter_chroma_121_packed422_scanline_mmx; vfilter_chroma_332_packed422_scanline = vfilter_chroma_332_packed422_scanline_mmx; speedy_memcpy = speedy_memcpy_mmx; } else { if( verbose ) { printf( "speedycode: No MMX or MMXEXT support detected, using C fallbacks.\n" ); } } if( speedy_accel & MM_ACCEL_X86_SSE2 ) { if( verbose ) { printf( "speedycode: Using SSE2 optimized functions.\n" ); } diff_factor_packed422_scanline = diff_factor_packed422_scanline_sse2; vfilter_chroma_332_packed422_scanline = vfilter_chroma_332_packed422_scanline_sse2; } #endif } uint32_t speedy_get_accel( void ) { return speedy_accel; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/tvtime.h����������������������������������������������������������0000644�0001750�0001750�00000005410�14647725152�016400� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifndef TVTIME_H_INCLUDED #define TVTIME_H_INCLUDED #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "deinterlace.h" /** * Which pulldown algorithm we're using. */ enum { PULLDOWN_NONE = 0, PULLDOWN_VEKTOR = 1, /* vektor's adaptive pulldown detection. */ PULLDOWN_MAX = 2, }; enum { FRAMERATE_FULL = 0, FRAMERATE_HALF_TFF = 1, FRAMERATE_HALF_BFF = 2, FRAMERATE_MAX = 3 }; typedef struct { /** * Which pulldown algorithm we're using. */ unsigned int pulldown_alg; /** * Current deinterlacing method. */ const deinterlace_method_t *curmethod; /** * This is how many frames to wait until deciding if the pulldown phase * has changed or if we've really found a pulldown sequence. */ unsigned int pulldown_error_wait; /* internal data */ int last_topdiff; int last_botdiff; int pdoffset; int pderror; int pdlastbusted; int filmmode; } tvtime_t; int tvtime_build_deinterlaced_frame( tvtime_t *this, uint8_t *output, uint8_t *curframe, uint8_t *lastframe, uint8_t *secondlastframe, int bottom_field, int second_field, int width, int frame_height, int instride, int outstride ); int tvtime_build_copied_field( tvtime_t *this, uint8_t *output, uint8_t *curframe, int bottom_field, int width, int frame_height, int instride, int outstride ); tvtime_t *tvtime_new_context(void); void tvtime_reset_context( tvtime_t *this ); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/deinterlace.c�����������������������������������������������������0000644�0001750�0001750�00000006747�14647725152�017360� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2002, 2005 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <stdlib.h> #define LOG_MODULE "deinterlace" #define LOG_VERBOSE /* #define LOG */ #include "deinterlace.h" #include <xine/xine_internal.h> typedef struct methodlist_item_s methodlist_item_t; struct methodlist_item_s { const deinterlace_method_t *method; methodlist_item_t *next; }; void free_deinterlace_methods( deinterlace_methods_t *methodlist ) { methodlist_item_t *cur = *methodlist; *methodlist = NULL; while (cur) { methodlist_item_t *next = cur->next; free(cur); cur = next; } } void register_deinterlace_method( deinterlace_methods_t *methodlist, const deinterlace_method_t *method ) { methodlist_item_t **dest = methodlist; methodlist_item_t *cur = *methodlist; if (!method) return; while( cur ) { if( cur->method == method ) return; dest = &(cur->next); cur = cur->next; } *dest = malloc( sizeof( methodlist_item_t ) ); if( *dest ) { (*dest)->method = method; (*dest)->next = 0; } else { printf( "deinterlace: Can't allocate memory.\n" ); } } int get_num_deinterlace_methods( deinterlace_methods_t methodlist ) { methodlist_item_t *cur = methodlist; int count = 0; while( cur ) { count++; cur = cur->next; } return count; } const deinterlace_method_t *get_deinterlace_method( deinterlace_methods_t methodlist, int i ) { methodlist_item_t *cur = methodlist; if( !cur ) return 0; while( i-- ) { if( !cur->next ) return 0; cur = cur->next; } return cur->method; } void filter_deinterlace_methods( deinterlace_methods_t *methodlist, int accel, int fields_available ) { methodlist_item_t *prev = 0; methodlist_item_t *cur = *methodlist; while( cur ) { methodlist_item_t *next = cur->next; int drop = 0; if( (cur->method->accelrequired & accel) != cur->method->accelrequired ) { /* This method is no good, drop it from the list. */ lprintf( "%s disabled: required CPU accelleration features unavailable.\n", cur->method->short_name ); drop = 1; } if( cur->method->fields_required > fields_available ) { /* This method is no good, drop it from the list. */ lprintf( "%s disabled: requires %d field buffers, only %d available.\n", cur->method->short_name, cur->method->fields_required, fields_available ); drop = 1; } if( drop ) { if( prev ) { prev->next = next; } else { *methodlist = next; } free( cur ); } else { prev = cur; } cur = next; } } �������������������������xine-lib-1.2/src/post/deinterlace/pulldown.c��������������������������������������������������������0000644�0001750�0001750�00000045406�14647725152�016740� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (C) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <limits.h> #include <string.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "pulldown.h" /** * scratch paper: * * A A A B B C C C D D * [T B T][B T][B T B][T B] * [1 1][2 2][3 3][4 4][5 5] * [C C] [M M][C C][C C] * D A A A B B C C C D * * Top 1 : Drop * Bot 1 : Show * Top 2 : Drop * Bot 2 : Drop * Top 3 : Merge * Bot 3 : Drop * Top 4 : Show * Bot 4 : Drop * Top 5 : Drop * Bot 5 : Show * * A A 1 * A B 2 * B C 4 * C C 8 * D D 16 * * D D A A A B B C C C D D A A A +------------ * [ ] * [* * ] | 1 top AA * [ * *] | 0 AA bottom AA * * [ ] * [* * ] | 1 top AB * [* * ] | 1 AB bottom AB * * [ ] * [ * *] | 0 top BC * [* * ] | 1 BC bottom BC * * [ ] * [ * *] | 0 top CC * [ * *] | 0 CC bottom CC * * [ ] * [* * ] | 1 top DD * [ * *] | 0 DD bottom DD * * * [* * ] | 1 top AA * [ * *] | 0 AA bottom AA * */ /* Offset 1 2 3 4 5 */ /* Field Pattern [T B T][B T][B T B] [T B] */ /* Action Copy Save Merge Copy Copy */ /* Bot Top */ static const int tff_top_pattern[] = { 0, 1, 0, 0, 0 }; static const int tff_bot_pattern[] = { 0, 0, 0, 1, 0 }; /* Offset 1 2 3 4 5 */ /* Field Pattern [B T B][T B][T B T] [B T] */ /* Action Copy Save Merge Copy Copy */ /* Top Bot */ static const int bff_top_pattern[] = { 0, 0, 0, 1, 0 }; static const int bff_bot_pattern[] = { 0, 1, 0, 0, 0 }; /* Timestamp mangling */ /* From the DVD : 0 + 3003+ 6006 + 9009+ 12012 = 15015 */ /* In 24fps time: 0 + + 3754 + 7508+ 11262 = 15016 */ /** * Flag Pattern Treat as * on DVD last offset * ============================ * T B T bff 3 * B T bff 4 * B T B tff 3 * T B tff 4 */ int determine_pulldown_offset( int top_repeat, int bot_repeat, int tff, int last_offset ) { int predicted_offset; int pd_patterns = 0; int offset = -1; int exact = -1; int i; predicted_offset = last_offset << 1; if( predicted_offset > PULLDOWN_SEQ_DD ) predicted_offset = PULLDOWN_SEQ_AA; /** * Detect our pattern. */ for( i = 0; i < 5; i++ ) { /** * Truth table: * * ref repeat, frame repeat valid * ===========+==============+======= * 0 0 -> 1 * 0 1 -> 1 * 1 0 -> 0 * 1 1 -> 1 */ if( tff ) { if( ( !tff_top_pattern[ i ] || top_repeat ) && ( !tff_bot_pattern[ i ] || bot_repeat ) ) { pd_patterns |= ( 1 << i ); offset = i; } } else { if( ( !bff_top_pattern[ i ] || top_repeat ) && ( !bff_bot_pattern[ i ] || bot_repeat ) ) { pd_patterns |= ( 1 << i ); offset = i; } if( bff_top_pattern[ i ] == top_repeat && bff_bot_pattern[ i ] == bot_repeat ) { exact = i; } } } offset = 1 << offset; /** * Check if the 3:2 pulldown pattern we previously decided on is * valid for this set. If so, we use that. */ if( pd_patterns & predicted_offset ) offset = predicted_offset; if( ( top_repeat || bot_repeat ) && exact > 0 ) offset = ( 1 << exact ); return offset; } #define HISTORY_SIZE 5 static int tophistory[ 5 ]; static int bothistory[ 5 ]; static int tophistory_diff[ 5 ]; static int bothistory_diff[ 5 ]; static int histpos = 0; #if 0 /* FIXME: unused */ static void fill_history( int tff ) { if( tff ) { tophistory[ 0 ] = INT_MAX; bothistory[ 0 ] = INT_MAX; tophistory[ 1 ] = 0; bothistory[ 1 ] = INT_MAX; tophistory[ 2 ] = INT_MAX; bothistory[ 2 ] = INT_MAX; tophistory[ 3 ] = INT_MAX; bothistory[ 3 ] = 0; tophistory[ 4 ] = INT_MAX; bothistory[ 3 ] = INT_MAX; tophistory_diff[ 0 ] = 0; bothistory_diff[ 0 ] = 0; tophistory_diff[ 1 ] = 1; bothistory_diff[ 1 ] = 0; tophistory_diff[ 2 ] = 0; bothistory_diff[ 2 ] = 0; tophistory_diff[ 3 ] = 0; bothistory_diff[ 3 ] = 1; tophistory_diff[ 4 ] = 0; bothistory_diff[ 3 ] = 0; } else { tophistory[ 0 ] = INT_MAX; bothistory[ 0 ] = INT_MAX; tophistory[ 1 ] = INT_MAX; bothistory[ 1 ] = 0; tophistory[ 2 ] = INT_MAX; bothistory[ 2 ] = INT_MAX; tophistory[ 3 ] = 0; bothistory[ 3 ] = INT_MAX; tophistory[ 4 ] = INT_MAX; bothistory[ 3 ] = INT_MAX; tophistory_diff[ 0 ] = 0; bothistory_diff[ 0 ] = 0; tophistory_diff[ 1 ] = 0; bothistory_diff[ 1 ] = 1; tophistory_diff[ 2 ] = 0; bothistory_diff[ 2 ] = 0; tophistory_diff[ 3 ] = 1; bothistory_diff[ 3 ] = 0; tophistory_diff[ 4 ] = 0; bothistory_diff[ 3 ] = 0; } histpos = 0; } #endif int determine_pulldown_offset_history( int top_repeat, int bot_repeat, int tff, int *realbest ) { int avgbot = 0; int avgtop = 0; int best = 0; int min = -1; int minpos = 0; int minbot = 0; int j; int ret; int mintopval = -1; int mintoppos = -1; int minbotval = -1; int minbotpos = -1; tophistory[ histpos ] = top_repeat; bothistory[ histpos ] = bot_repeat; for( j = 0; j < HISTORY_SIZE; j++ ) { avgtop += tophistory[ j ]; avgbot += bothistory[ j ]; } avgtop /= 5; avgbot /= 5; for( j = 0; j < HISTORY_SIZE; j++ ) { // int cur = (tophistory[ j ] - avgtop); int cur = tophistory[ j ]; if( cur < min || min < 0 ) { min = cur; minpos = j; } if( cur < mintopval || mintopval < 0 ) { mintopval = cur; mintoppos = j; } } for( j = 0; j < HISTORY_SIZE; j++ ) { // int cur = (bothistory[ j ] - avgbot); int cur = bothistory[ j ]; if( cur < min || min < 0 ) { min = cur; minpos = j; minbot = 1; } if( cur < minbotval || minbotval < 0 ) { minbotval = cur; minbotpos = j; } } if( minbot ) { best = tff ? ( minpos + 2 ) : ( minpos + 4 ); } else { best = tff ? ( minpos + 4 ) : ( minpos + 2 ); } best = best % HISTORY_SIZE; *realbest = 1 << ( ( histpos + (2*HISTORY_SIZE) - best ) % HISTORY_SIZE ); best = (minbotpos + 2) % 5; ret = 1 << ( ( histpos + (2*HISTORY_SIZE) - best ) % HISTORY_SIZE ); best = (mintoppos + 4) % 5; ret |= 1 << ( ( histpos + (2*HISTORY_SIZE) - best ) % HISTORY_SIZE ); histpos = (histpos + 1) % HISTORY_SIZE; return ret; } static int reference = 0; int determine_pulldown_offset_history_new( int top_repeat, int bot_repeat, int tff, int predicted ) { int avgbot = 0; int avgtop = 0; int i, j; int ret; int mintopval = -1; int mintoppos = -1; int min2topval = -1; int min2toppos = -1; int minbotval = -1; int minbotpos = -1; int min2botval = -1; int min2botpos = -1; /*int predicted_pos = 0;*/ (void)tff; tophistory[ histpos ] = top_repeat; bothistory[ histpos ] = bot_repeat; for( j = 0; j < HISTORY_SIZE; j++ ) { avgtop += tophistory[ j ]; avgbot += bothistory[ j ]; } avgtop /= 5; avgbot /= 5; for( i = 0; i < 5; i++ ) { if( (1<<i) == predicted ) { /*predicted_pos = i;*/ break; } } /* printf(top: %8d bot: %8d\ttop-avg: %8d bot-avg: %8d (%d)\n", top_repeat, bot_repeat, top_repeat - avgtop, bot_repeat - avgbot, (5 + predicted_pos - reference) % 5 ); */ for( j = 0; j < HISTORY_SIZE; j++ ) { int cur = tophistory[ j ]; if( cur < mintopval || mintopval < 0 ) { min2topval = mintopval; min2toppos = mintoppos; mintopval = cur; mintoppos = j; } else if( cur < min2topval || min2topval < 0 ) { min2topval = cur; min2toppos = j; } } for( j = 0; j < HISTORY_SIZE; j++ ) { int cur = bothistory[ j ]; if( cur < minbotval || minbotval < 0 ) { min2botval = minbotval; min2botpos = minbotpos; minbotval = cur; minbotpos = j; } else if( cur < min2botval || min2botval < 0 ) { min2botval = cur; min2botpos = j; } } tophistory_diff[ histpos ] = ((mintoppos == histpos) || (min2toppos == histpos)); bothistory_diff[ histpos ] = ((minbotpos == histpos) || (min2botpos == histpos)); ret = 0; for( i = 0; i < 5; i++ ) { int valid = 1; for( j = 0; j < 5; j++ ) { // if( tff_top_pattern[ j ] && !tophistory_diff[ (i + j) % 5 ] && tophistory[ (i + j) % 5 ] != mintopval ) { if( tff_top_pattern[ j ] && (tophistory[ (i + j) % 5 ] > avgtop || !tophistory_diff[ (i + j) % 5 ]) ) { valid = 0; break; } // if( tff_bot_pattern[ j ] && !bothistory_diff[ (i + j) % 5 ] && bothistory[ (i + j) % 5 ] != minbotval ) { if( tff_bot_pattern[ j ] && (bothistory[ (i + j) % 5 ] > avgbot || !bothistory_diff[ (i + j) % 5 ]) ) { valid = 0; break; } } if( valid ) ret |= (1<<(((5-i)+histpos)%5)); } /* printf( "ret: %d %d %d %d %d\n", PULLDOWN_OFFSET_1 & ret, PULLDOWN_OFFSET_2 & ret, PULLDOWN_OFFSET_3 & ret, PULLDOWN_OFFSET_4 & ret, PULLDOWN_OFFSET_5 & ret ); */ histpos = (histpos + 1) % HISTORY_SIZE; reference = (reference + 1) % 5; if( !ret ) { /* No pulldown sequence is valid, return an error. */ return 0; } else if( !(predicted & ret) ) { /** * We have a valid sequence, but it doesn't match our prediction. * Return the first 'valid' sequence in the list. */ for( i = 0; i < 5; i++ ) { if( ret & (1<<i) ) return (1<<i); } } /** * The predicted phase is still valid. */ return predicted; } int determine_pulldown_offset_short_history_new( int top_repeat, int bot_repeat, int tff, int predicted ) { int avgbot = 0; int avgtop = 0; int i, j; int ret; int mintopval = -1; int mintoppos = -1; int min2topval = -1; int min2toppos = -1; int minbotval = -1; int minbotpos = -1; int min2botval = -1; int min2botpos = -1; /*int predicted_pos = 0;*/ (void)tff; tophistory[ histpos ] = top_repeat; bothistory[ histpos ] = bot_repeat; for( j = 0; j < 3; j++ ) { avgtop += tophistory[ (histpos + 5 - j) % 5 ]; avgbot += bothistory[ (histpos + 5 - j) % 5 ]; } avgtop /= 3; avgbot /= 3; for( i = 0; i < 5; i++ ) { if( (1<<i) == predicted ) { /*predicted_pos = i;*/ break; } } /* printf( "top: %8d bot: %8d\ttop-avg: %8d bot-avg: %8d (%d)\n", top_repeat, bot_repeat, top_repeat - avgtop, bot_repeat - avgbot, (5 + predicted_pos - reference) % 5 ); */ for( j = 0; j < 3; j++ ) { int cur = tophistory[ (histpos + 5 - j) % 5 ]; if( cur < mintopval || mintopval < 0 ) { min2topval = mintopval; min2toppos = mintoppos; mintopval = cur; mintoppos = j; } else if( cur < min2topval || min2topval < 0 ) { min2topval = cur; min2toppos = j; } } for( j = 0; j < 3; j++ ) { int cur = bothistory[ (histpos + 5 - j) % 5 ]; if( cur < minbotval || minbotval < 0 ) { min2botval = minbotval; min2botpos = minbotpos; minbotval = cur; minbotpos = j; } else if( cur < min2botval || min2botval < 0 ) { min2botval = cur; min2botpos = j; } } tophistory_diff[ histpos ] = ((mintoppos == histpos) || (min2toppos == histpos)); bothistory_diff[ histpos ] = ((minbotpos == histpos) || (min2botpos == histpos)); ret = 0; for( i = 0; i < 5; i++ ) { int valid = 1; for( j = 0; j < 3; j++ ) { // if( tff_top_pattern[ j ] && !tophistory_diff[ (i + j) % 5 ] && tophistory[ (i + j) % 5 ] != mintopval ) { // if( tff_top_pattern[ j ] && (tophistory[ (i + j) % 5 ] > avgtop || !tophistory_diff[ (i + j) % 5 ]) ) { if( tff_top_pattern[ (i + 5 - j) % 5 ] && tophistory[ (histpos + 5 - j) % 5 ] > avgtop ) { // if( tff_top_pattern[ (i + 5 - j) % 5 ] && !tophistory_diff[ (histpos + 5 - j) % 5 ] && tophistory[ (histpos + 5 - j) % 5 ] != mintopval ) { valid = 0; break; } // if( tff_bot_pattern[ j ] && !bothistory_diff[ (i + j) % 5 ] && bothistory[ (i + j) % 5 ] != minbotval ) { // if( tff_bot_pattern[ j ] && (bothistory[ (i + j) % 5 ] > avgbot || !bothistory_diff[ (i + j) % 5 ]) ) { if( tff_bot_pattern[ (i + 5 - j) % 5 ] && bothistory[ (histpos + 5 - j) % 5 ] > avgbot ) { // if( tff_bot_pattern[ (i + 5 - j) % 5 ] && !bothistory_diff[ (histpos + 5 - j) % 5 ] && bothistory[ (histpos + 5 - j) % 5 ] != minbotval ) { valid = 0; break; } } if( valid ) ret |= (1<<i); } /* printf( "ret: %d %d %d %d %d\n", PULLDOWN_OFFSET_1 & ret, PULLDOWN_OFFSET_2 & ret, PULLDOWN_OFFSET_3 & ret, PULLDOWN_OFFSET_4 & ret, PULLDOWN_OFFSET_5 & ret ); */ histpos = (histpos + 1) % HISTORY_SIZE; reference = (reference + 1) % 5; if( !ret ) { /* No pulldown sequence is valid, return an error. */ return 0; } else if( !(predicted & ret) ) { /** * We have a valid sequence, but it doesn't match our prediction. * Return the first 'valid' sequence in the list. */ for( i = 0; i < 5; i++ ) { if( ret & (1<<i) ) return (1<<i); } } /** * The predicted phase is still valid. */ return predicted; } int determine_pulldown_offset_dalias( pulldown_metrics_t *old_peak, pulldown_metrics_t *old_relative, pulldown_metrics_t *old_mean, pulldown_metrics_t *new_peak, pulldown_metrics_t *new_relative, pulldown_metrics_t *new_mean ) { int laced = 0; (void)old_mean; (void)new_mean; if (old_peak->d > 360) { if (3*old_relative->e < old_relative->o) laced=1; if ((2*old_relative->d < old_relative->s) && (old_relative->s > 600)) laced=1; } if (new_peak->d > 360) { if ((2*new_relative->t < new_relative->p) && (new_relative->p > 600)) laced=1; } if( !laced ) return PULLDOWN_ACTION_NEXT_PREV; if (new_relative->t < 2*new_relative->p) { if ((3*old_relative->e < old_relative->o) || (2*new_relative->t < new_relative->p)) { return PULLDOWN_ACTION_PREV_NEXT; } } return PULLDOWN_ACTION_PREV_NEXT; } #define MAXUP(a,b) ((a) = ((a)>(b)) ? (a) : (b)) void diff_factor_packed422_frame( pulldown_metrics_t *peak, pulldown_metrics_t *rel, pulldown_metrics_t *mean, uint8_t *old, uint8_t *new, int w, int h, int os, int ns ) { int x, y; pulldown_metrics_t l; memset(peak, 0, sizeof(pulldown_metrics_t)); memset(rel, 0, sizeof(pulldown_metrics_t)); memset(mean, 0, sizeof(pulldown_metrics_t)); for (y = 0; y < h-7; y += 8) { for (x = 8; x < w-8-7; x += 8) { diff_packed422_block8x8(&l, old+x+y*os, new+x+y*ns, os, ns); mean->d += l.d; mean->e += l.e; mean->o += l.o; mean->s += l.s; mean->p += l.p; mean->t += l.t; MAXUP(peak->d, l.d); MAXUP(peak->e, l.e); MAXUP(peak->o, l.o); MAXUP(peak->s, l.s); MAXUP(peak->p, l.p); MAXUP(peak->t, l.t); MAXUP(rel->e, l.e-l.o); MAXUP(rel->o, l.o-l.e); MAXUP(rel->s, l.s-l.t); MAXUP(rel->p, l.p-l.t); MAXUP(rel->t, l.t-l.p); MAXUP(rel->d, l.t-l.s); /* hack */ } } x = (w/8-2)*(h/8); mean->d /= x; mean->e /= x; mean->o /= x; mean->s /= x; mean->p /= x; mean->t /= x; } int pulldown_source( int action, int bottom_field ) { if( action == PULLDOWN_SEQ_AA ) { return !bottom_field; } else if( action == PULLDOWN_SEQ_AB ) { return 1; } else if( action == PULLDOWN_SEQ_BC ) { return bottom_field; } else if( action == PULLDOWN_SEQ_CC ) { return 0; } else if( action == PULLDOWN_SEQ_DD ) { return !bottom_field; } return 0; } int pulldown_drop( int action, int bottom_field ) { int ret = 1; if( action == PULLDOWN_SEQ_AA && bottom_field ) ret = 0; if( action == PULLDOWN_SEQ_BC && !bottom_field ) ret = 0; if( action == PULLDOWN_SEQ_CC && !bottom_field ) ret = 0; if( action == PULLDOWN_SEQ_DD && bottom_field ) ret = 0; return ret; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/speedy.h����������������������������������������������������������0000644�0001750�0001750�00000030627�14647725152�016371� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2002, 2003 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifndef SPEEDY_H_INCLUDED #define SPEEDY_H_INCLUDED #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #ifdef __cplusplus extern "C" { #endif /** * Speedy is a collection of optimized functions plus their C fallbacks. * This includes a simple system to select which functions to use * at runtime. * * The optimizations are done with the help of the mmx.h system, from * libmpeg2 by Michel Lespinasse and Aaron Holtzman. * * The library is a collection of function pointers which must be first * initialized by setup_speedy_calls() to point at the fastest available * implementation of each function. */ /** * Struct for pulldown detection metrics. */ typedef struct pulldown_metrics_s { /* difference: total, even lines, odd lines */ int d, e, o; /* noise: temporal, spacial (current), spacial (past) */ int t, s, p; } pulldown_metrics_t; /** * Interpolates a packed 4:2:2 scanline using linear interpolation. */ extern void (*interpolate_packed422_scanline)( uint8_t *output, uint8_t *top, uint8_t *bot, int width ); /** * Blits a colour to a packed 4:2:2 scanline. */ extern void (*blit_colour_packed422_scanline)( uint8_t *output, int width, int y, int cb, int cr ); /** * Blits a colour to a packed 4:4:4:4 scanline. I use luma/cb/cr instead of * RGB but this will of course work for either. */ extern void (*blit_colour_packed4444_scanline)( uint8_t *output, int width, int alpha, int luma, int cb, int cr ); /** * Blit from and to packed 4:2:2 scanline. */ extern void (*blit_packed422_scanline)( uint8_t *dest, const uint8_t *src, int width ); /** * Composites a packed 4:4:4:4 scanline onto a packed 4:2:2 scanline. * Chroma is downsampled by dropping samples (nearest neighbour). */ extern void (*composite_packed4444_to_packed422_scanline)( uint8_t *output, uint8_t *input, uint8_t *foreground, int width ); /** * Composites a packed 4:4:4:4 scanline onto a packed 4:2:2 scanline. * Chroma is downsampled by dropping samples (nearest neighbour). The * alpha value provided is in the range 0-256 and is first applied to * the input (for fadeouts). */ extern void (*composite_packed4444_alpha_to_packed422_scanline)( uint8_t *output, uint8_t *input, uint8_t *foreground, int width, int alpha ); /** * Takes an alphamask and the given colour (in Y'CbCr) and composites it * onto a packed 4:4:4:4 scanline. */ extern void (*composite_alphamask_to_packed4444_scanline)( uint8_t *output, uint8_t *input, uint8_t *mask, int width, int textluma, int textcb, int textcr ); /** * Takes an alphamask and the given colour (in Y'CbCr) and composites it * onto a packed 4:4:4:4 scanline. The alpha value provided is in the * range 0-256 and is first applied to the input (for fadeouts). */ extern void (*composite_alphamask_alpha_to_packed4444_scanline)( uint8_t *output, uint8_t *input, uint8_t *mask, int width, int textluma, int textcb, int textcr, int alpha ); /** * Sub-pixel data bar renderer. There are 128 bars. */ extern void (*composite_bars_packed4444_scanline)( uint8_t *output, uint8_t *background, int width, int a, int luma, int cb, int cr, int percentage ); /** * Premultiplies the colour by the alpha channel in a packed 4:4:4:4 * scanline. */ extern void (*premultiply_packed4444_scanline)( uint8_t *output, uint8_t *input, int width ); /** * Blend between two packed 4:2:2 scanline. Pos is the fade value in * the range 0-256. A value of 0 gives 100% src1, and a value of 256 * gives 100% src2. Anything in between gives the appropriate faded * version. */ extern void (*blend_packed422_scanline)( uint8_t *output, uint8_t *src1, uint8_t *src2, int width, int pos ); /** * Calculates the 'difference factor' for two scanlines. This is a * metric where higher values indicate that the two scanlines are more * different. */ extern unsigned int (*diff_factor_packed422_scanline)( uint8_t *cur, uint8_t *old, int width ); /** * Calculates the 'comb factor' for a set of three scanlines. This is a * metric where higher values indicate a more likely chance that the two * fields are at separate points in time. */ extern unsigned int (*comb_factor_packed422_scanline)( uint8_t *top, uint8_t *mid, uint8_t *bot, int width ); /** * Vertical [1 2 1] chroma filter. */ extern void (*vfilter_chroma_121_packed422_scanline)( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ); /** * Vertical [3 3 2] chroma filter. */ extern void (*vfilter_chroma_332_packed422_scanline)( uint8_t *output, int width, uint8_t *m, uint8_t *t, uint8_t *b ); /** * In-place [1 2 1] filter. */ extern void (*filter_luma_121_packed422_inplace_scanline)( uint8_t *data, int width ); /** * In-place [1 4 6 4 1] filter. */ extern void (*filter_luma_14641_packed422_inplace_scanline)( uint8_t *data, int width ); /** * Sets the chroma of the scanline to neutral (128) in-place. */ extern void (*kill_chroma_packed422_inplace_scanline)( uint8_t *data, int width ); /** * Mirrors the scanline in-place. */ extern void (*mirror_packed422_inplace_scanline)( uint8_t *data, int width ); /** * Mirrors the first half of the scanline onto the second half in-place. */ extern void (*halfmirror_packed422_inplace_scanline)( uint8_t *data, int width ); /** * Inverts the colours on a scanline in-place. */ extern void (*invert_colour_packed422_inplace_scanline)( uint8_t *data, int width ); /** * Fast memcpy function, used by all of the blit functions. Won't blit * anything if dest == src. */ extern void *(*speedy_memcpy)( void *output, const void *input, size_t size ); /** * Calculates the block difference metrics for dalias' pulldown * detection algorithm. */ extern void (*diff_packed422_block8x8)( pulldown_metrics_t *m, uint8_t *old, uint8_t *new, int os, int ns ); /** * Takes an alpha mask and subpixelly blits it using linear * interpolation. */ extern void (*a8_subpix_blit_scanline)( uint8_t *output, uint8_t *input, int lasta, int startpos, int width ); /** * 1/4 vertical subpixel blit for packed 4:2:2 scanlines using linear * interpolation. */ extern void (*quarter_blit_vertical_packed422_scanline)( uint8_t *output, uint8_t *one, uint8_t *three, int width ); /** * Vertical subpixel blit for packed 4:2:2 scanlines using linear * interpolation. */ extern void (*subpix_blit_vertical_packed422_scanline)( uint8_t *output, uint8_t *top, uint8_t *bot, int subpixpos, int width ); /** * Simple function to convert a 4:4:4 scanline to a 4:4:4:4 scanline by * adding an alpha channel. Result is non-premultiplied. */ extern void (*packed444_to_nonpremultiplied_packed4444_scanline)( uint8_t *output, uint8_t *input, int width, int alpha ); /** * I think this function needs to be rethought and renamed, but here * it is for now. This function horizontally resamples a scanline * using linear interpolation to compensate for a change in pixel * aspect ratio. */ #if 0 extern void (*aspect_adjust_packed4444_scanline)( uint8_t *output, uint8_t *input, int width, double pixel_aspect ); #endif /** * Convert a packed 4:4:4 surface to a packed 4:2:2 surface using * nearest neighbour chroma downsampling. */ extern void (*packed444_to_packed422_scanline)( uint8_t *output, uint8_t *input, int width ); /** * Converts packed 4:2:2 to packed 4:4:4 scanlines using nearest * neighbour chroma upsampling. */ extern void (*packed422_to_packed444_scanline)( uint8_t *output, uint8_t *input, int width ); /** * This filter actually does not meet the spec so calling it rec601 * is a bit of a lie. I got the filter from Poynton's site. This * converts a scanline from packed 4:2:2 to packed 4:4:4. But this * function should point at some high quality to-the-spec resampler. */ extern void (*packed422_to_packed444_rec601_scanline)( uint8_t *dest, uint8_t *src, int width ); /** * Conversions between Y'CbCr and R'G'B'. We use Rec.601 numbers * since our source is broadcast video, but I think there is an * argument to be made for switching to Rec.709. */ extern void (*packed444_to_rgb24_rec601_scanline)( uint8_t *output, uint8_t *input, int width ); extern void (*rgb24_to_packed444_rec601_scanline)( uint8_t *output, uint8_t *input, int width ); extern void (*rgba32_to_packed4444_rec601_scanline)( uint8_t *output, uint8_t *input, int width ); /** * Chroma upsampler for a chroma plane (8 bit per pixel) from * 4:2:2 to 4:4:4. I believe that implements the filter described * in the MPEG2 spec, but I have not confirmed. */ extern void (*chroma_422_to_444_mpeg2_plane)( uint8_t *dst, uint8_t *src, int width, int height ); /** * Chroma upsampler for a chroma plane (8 bit per pixel) from * 4:2:0 to 4:2:2. I believe that implements the filter described * in the MPEG2 spec, but I have not confirmed. */ extern void (*chroma_420_to_422_mpeg2_plane)( uint8_t *dst, uint8_t *src, int width, int height, int progressive ); /** * Sets up the function pointers to point at the fastest function * available. Requires accelleration settings (see mm_accel.h). */ void setup_speedy_calls( uint32_t accel, int verbose ); /** * Returns a bitfield of what accellerations were used when speedy was * initialized. See mm_accel.h. */ uint32_t speedy_get_accel( void ); #ifdef __cplusplus }; #endif #endif /* SPEEDY_H_INCLUDED */ ���������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/pulldown.h��������������������������������������������������������0000644�0001750�0001750�00000004733�14647725152�016743� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifndef PULLDOWN_H_INCLUDED #define PULLDOWN_H_INCLUDED #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "speedy.h" #ifdef __cplusplus extern "C" { #endif #define PULLDOWN_SEQ_AA (1<<0) /* next - prev */ #define PULLDOWN_SEQ_AB (1<<1) /* prev - next */ #define PULLDOWN_SEQ_BC (1<<2) /* prev - next */ #define PULLDOWN_SEQ_CC (1<<3) /* next - prev */ #define PULLDOWN_SEQ_DD (1<<4) /* next - prev */ #define PULLDOWN_ACTION_NEXT_PREV (1<<0) /* next - prev */ #define PULLDOWN_ACTION_PREV_NEXT (1<<1) /* prev - next */ /** * Returns 1 if the source is the previous field, 0 if it is * the next field, for the given action. */ int pulldown_source( int action, int bottom_field ); int determine_pulldown_offset( int top_repeat, int bot_repeat, int tff, int last_offset ); int determine_pulldown_offset_history( int top_repeat, int bot_repeat, int tff, int *realbest ); int determine_pulldown_offset_history_new( int top_repeat, int bot_repeat, int tff, int predicted ); int determine_pulldown_offset_short_history_new( int top_repeat, int bot_repeat, int tff, int predicted ); int determine_pulldown_offset_dalias( pulldown_metrics_t *old_peak, pulldown_metrics_t *old_relative, pulldown_metrics_t *old_mean, pulldown_metrics_t *new_peak, pulldown_metrics_t *new_relative, pulldown_metrics_t *new_mean ); void diff_factor_packed422_frame( pulldown_metrics_t *peak, pulldown_metrics_t *rel, pulldown_metrics_t *mean, uint8_t *old, uint8_t *new, int w, int h, int os, int ns ); int pulldown_drop( int action, int bottom_field ); #ifdef __cplusplus }; #endif #endif /* PULLDOWN_H_INCLUDED */ �������������������������������������xine-lib-1.2/src/post/deinterlace/speedtools.h������������������������������������������������������0000644�0001750�0001750�00000004434�14647725152�017256� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2002 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifndef SPEEDTOOLS_H_INCLUDED #define SPEEDTOOLS_H_INCLUDED #define PREFETCH_2048(x) \ { int *pfetcha = (int *) x; \ prefetchnta( pfetcha ); \ prefetchnta( pfetcha + 64 ); \ prefetchnta( pfetcha + 128 ); \ prefetchnta( pfetcha + 192 ); \ pfetcha += 256; \ prefetchnta( pfetcha ); \ prefetchnta( pfetcha + 64 ); \ prefetchnta( pfetcha + 128 ); \ prefetchnta( pfetcha + 192 ); } static inline unsigned int read_pf(volatile unsigned int *addr) { return *addr; } #define READ_PREFETCH_2048(x) \ { int * pfetcha = (int *) x; \ read_pf(pfetcha); read_pf(pfetcha + 16); read_pf(pfetcha + 32); read_pf(pfetcha + 48); \ read_pf(pfetcha + 64); read_pf(pfetcha + 80); read_pf(pfetcha + 96); read_pf(pfetcha + 112); \ read_pf(pfetcha + 128); read_pf(pfetcha + 144); read_pf(pfetcha + 160); read_pf(pfetcha + 176); \ read_pf(pfetcha + 192); read_pf(pfetcha + 208); read_pf(pfetcha + 224); read_pf(pfetcha + 240); \ pfetcha += 256; \ read_pf(pfetcha); read_pf(pfetcha + 16); read_pf(pfetcha + 32); read_pf(pfetcha + 48); \ read_pf(pfetcha + 64); read_pf(pfetcha + 80); read_pf(pfetcha + 96); read_pf(pfetcha + 112); \ read_pf(pfetcha + 128); read_pf(pfetcha + 144); read_pf(pfetcha + 160); read_pf(pfetcha + 176); \ read_pf(pfetcha + 192); read_pf(pfetcha + 208); read_pf(pfetcha + 224); read_pf(pfetcha + 240); } #endif /* SPEEDTOOLS_H_INCLUDED */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/����������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�016400� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/�����������������������������������������������0000755�0001750�0001750�00000000000�14647725152�020575� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/StrangeBob.inc���������������������������������0000644�0001750�0001750�00000026147�14647725152�023330� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // First, get and save our possible Bob values // Assume our pixels are layed out as follows with x the calc'd bob value // and the other pixels are from the current field // // j a b c k current field // x calculated line // m d e f n current field // // we calc the bob value luma value as: // if |j - n| < Thres && |a - m| > Thres // avg(j,n) // end if // if |k - m| < Thres && |c - n| > Thres // avg(k,m) // end if // if |c - d| < Thres && |b - f| > Thres // avg(c,d) // end if // if |a - f| < Thres && |b - d| > Thres // avg(a,f) // end if // if |b - e| < Thres // avg(b,e) // end if // pickup any thing not yet set with avg(b,e) // j, n "pxor %%mm5, %%mm5\n\t" "pxor %%mm6, %%mm6\n\t" "pxor %%mm7, %%mm7\n\t" "movq -2"MEMREF1("dx")", %%mm0\n\t" // value a from top left "movq -4"MEMREF2("dx","cx")", %%mm1\n\t" // value m from bottom right "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(a,m) "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(a,m) > Thres else 0 "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(a,m) < Thres, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(a,m) > Thres, else 00 "movq -4"MEMREF1("dx")", %%mm0\n\t" // value j "movq 4"MEMREF2("dx","cx")", %%mm1\n\t" // value n "movq %%mm0, %%mm2\n\t" "pavgb %%mm1, %%mm2\n\t" // avg(j,n) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm0\n\t" "psubusb %%mm3, %%mm1\n\t" "por %%mm1, %%mm0\n\t" // abs(j,n) "movq %%mm0, %%mm1\n\t" "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(j,n) > Thres else 0 "pxor %%mm3, %%mm3\n\t" "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(j,n) < Thres, else 00 "pand %%mm4, %%mm1\n\t" "pand %%mm1, %%mm2\n\t" "pand %%mm1, %%mm0\n\t" "movq %%mm1, %%mm3\n\t" "pxor %%mm5, %%mm3\n\t" "pand %%mm3, %%mm6\n\t" "pand %%mm3, %%mm7\n\t" "pand %%mm3, %%mm5\n\t" "por %%mm1, %%mm5\n\t" "por %%mm2, %%mm6\n\t" "por %%mm0, %%mm7\n\t" // k & m "movq 2"MEMREF1("dx")", %%mm0\n\t" // value c from top left "movq 4"MEMREF2("dx","cx")", %%mm1\n\t" // value n from bottom right "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(c,n) "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(c,n) > Thres else 0 "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(c,n) < Thres, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(c,n) > Thres, else 00 "movq 4"MEMREF1("dx")", %%mm0\n\t" // value k "movq -4"MEMREF2("dx","cx")", %%mm1\n\t" // value m "movq %%mm0, %%mm2\n\t" V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(k,m) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm0\n\t" "psubusb %%mm3, %%mm1\n\t" "por %%mm1, %%mm0\n\t" // abs(k,m) "movq %%mm0, %%mm1\n\t" "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(k,m) > Thres else 0 "pxor %%mm3, %%mm3\n\t" "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(k,m) < Thres, else 00 "pand %%mm4, %%mm1\n\t" "pand %%mm1, %%mm2\n\t" "pand %%mm1, %%mm0\n\t" "movq %%mm1, %%mm3\n\t" "pxor %%mm5, %%mm3\n\t" "pand %%mm3, %%mm6\n\t" "pand %%mm3, %%mm7\n\t" "pand %%mm3, %%mm5\n\t" "por %%mm1, %%mm5\n\t" "por %%mm2, %%mm6\n\t" "por %%mm0, %%mm7\n\t" // c & d "movq "MEMREF1("dx")", %%mm0\n\t" // value b from top left "movq 2"MEMREF2("dx","cx")", %%mm1\n\t" // value f from bottom right "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(b,f) "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(b,f) > Thres else 0 "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(b,f) < Thres, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(b,f) > Thres, else 00 "movq 2"MEMREF1("dx")", %%mm0\n\t" // value c "movq -2"MEMREF2("dx","cx")", %%mm1\n\t" // value d "movq %%mm0, %%mm2\n\t" V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(c,d) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm0\n\t" "psubusb %%mm3, %%mm1\n\t" "por %%mm1, %%mm0\n\t" // abs(c,d) "movq %%mm0, %%mm1\n\t" "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(c,d) > Thres else 0 "pxor %%mm3, %%mm3\n\t" "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(c,d) < Thres, else 00 "pand %%mm4, %%mm1\n\t" "pand %%mm1, %%mm2\n\t" "pand %%mm1, %%mm0\n\t" "movq %%mm1, %%mm3\n\t" "pxor %%mm5, %%mm3\n\t" "pand %%mm3, %%mm6\n\t" "pand %%mm3, %%mm7\n\t" "pand %%mm3, %%mm5\n\t" "por %%mm1, %%mm5\n\t" "por %%mm2, %%mm6\n\t" "por %%mm0, %%mm7\n\t" // a & f "movq "MEMREF1("dx")", %%mm0\n\t" // value b from top left "movq -2"MEMREF2("dx","cx")", %%mm1\n\t" // value d from bottom right "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(b,d) "psubusb "_DiffThres", %%mm3\n\t" // nonzero where abs(b,d) > Thres else 0 "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where abs(b,d) < Thres, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where abs(b,d) > Thres, else 00 "movq -2"MEMREF1("dx")", %%mm0\n\t" // value a "movq 2"MEMREF2("dx","cx")", %%mm1\n\t" // value f "movq %%mm0, %%mm2\n\t" V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(a,f) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm0\n\t" "psubusb %%mm3, %%mm1\n\t" "por %%mm1, %%mm0\n\t" // abs(a,f) "movq %%mm0, %%mm1\n\t" "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(a,f) > Thres else 0 "pxor %%mm3, %%mm3\n\t" "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(a,f) < Thres, else 00 "pand %%mm4, %%mm1\n\t" "pand %%mm1, %%mm2\n\t" "pand %%mm1, %%mm0\n\t" "movq %%mm1, %%mm3\n\t" "pxor %%mm5, %%mm3\n\t" "pand %%mm3, %%mm6\n\t" "pand %%mm3, %%mm7\n\t" "pand %%mm3, %%mm5\n\t" "por %%mm1, %%mm5\n\t" "por %%mm2, %%mm6\n\t" "por %%mm0, %%mm7\n\t" "pand "_YMask", %%mm5\n\t" // mask out chroma from here "pand "_YMask", %%mm6\n\t" // mask out chroma from here "pand "_YMask", %%mm7\n\t" // mask out chroma from here // b,e "movq "MEMREF1("dx")", %%mm0\n\t" // value b from top "movq "MEMREF2("dx","cx")", %%mm1\n\t" // value e from bottom "movq %%mm0, %%mm2\n\t" V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm0\n\t" "psubusb %%mm3, %%mm1\n\t" "por %%mm1, %%mm0\n\t" // abs(b,e) "movq %%mm0, %%mm1\n\t" "psubusb "_DiffThres", %%mm1\n\t" // nonzero where abs(b,e) > Thres else 0 "pxor %%mm3, %%mm3\n\t" "pcmpeqb %%mm3, %%mm1\n\t" // now ff where abs(b,e) < Thres, else 00 "pand %%mm1, %%mm2\n\t" "pand %%mm1, %%mm0\n\t" "movq %%mm1, %%mm3\n\t" "pxor %%mm5, %%mm3\n\t" "pand %%mm3, %%mm6\n\t" "pand %%mm3, %%mm7\n\t" "pand %%mm3, %%mm5\n\t" "por %%mm1, %%mm5\n\t" "por %%mm2, %%mm6\n\t" "por %%mm0, %%mm7\n\t" // bob in any leftovers "movq "MEMREF1("dx")", %%mm0\n\t" // value b from top "movq "MEMREF2("dx","cx")", %%mm1\n\t" // value e from bottom // We will also calc here the max/min values to later limit comb // so the max excursion will not exceed the Max_Comb constant #ifdef SKIP_SEARCH "movq %%mm0, %%mm2\n\t" //"pminub %%mm2, %%mm1\n\t" V_PMINUB ("%%mm2", "%%mm1", "%%mm4") //"pmaxub %%mm6, %%mm2\n\t" // clip our current results so far to be above this V_PMAXUB ("%%mm6", "%%mm2") "movq %%mm0, %%mm2\n\t" V_PMAXUB ("%%mm2", "%%mm1") //"pminub %%mm6, %%mm2\n\t" // clip our current results so far to be below this V_PMINUB ("%%mm6", "%%mm2", "%%mm4") #else "movq %%mm0, %%mm2\n\t" "movq "MEMREF1("ax")", %%mm4\n\t" "psubusb %%mm4, %%mm2\n\t" "psubusb %%mm0, %%mm4\n\t" "por %%mm2, %%mm4\n\t" // abs diff "movq %%mm1, %%mm2\n\t" "movq "MEMREF2("ax","cx")", %%mm3\n\t" "psubusb %%mm3, %%mm2\n\t" "psubusb %%mm1, %%mm3\n\t" "por %%mm2, %%mm3\n\t" // abs diff //"pmaxub %%mm3, %%mm4\n\t" // top or bottom pixel moved most V_PMAXUB ("%%mm3", "%%mm4") // top or bottom pixel moved most "psubusb "_DiffThres", %%mm3\n\t" // moved more than allowed? or goes to 0? "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where low motion, else high motion "movq %%mm0, %%mm2\n\t" //"pminub %%mm2, %%mm1\n\t" V_PMINUB ("%%mm2", "%%mm1", "%%mm4") //"pmaxub %%mm6, %%mm2\n\t" // clip our current results so far to be above this V_PMAXUB ("%%mm6", "%%mm2") "psubusb %%mm3, %%mm2\n\t" // maybe decrease it to 0000.. if no surround motion //"movq %%mm2, "_Min_Vals"\n\t" "movq %%mm0, %%mm2\n\t" V_PMAXUB ("%%mm2", "%%mm1") //"pminub %%mm6, %%mm2\n\t" // clip our current results so far to be below this V_PMINUB ("%%mm6", "%%mm2", "%%mm4") "paddusb %%mm3, %%mm2\n\t" // maybe increase it to ffffff if no surround motion //"movq %%mm2, "_Max_Vals"\n\t" #endif "movq %%mm0, %%mm2\n\t" //"pavgb %%mm2, %%mm1\n\t" // avg(b,e) V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(b,e) "movq %%mm3, %%mm1\n\t" // keep copy of diffs "pxor %%mm4, %%mm4\n\t" "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00 "pcmpeqb %%mm0, %%mm0\n\t" "pandn %%mm0, %%mm5\n\t" "por %%mm5, %%mm3\n\t" "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00 "pand %%mm3, %%mm1\n\t" "pand %%mm3, %%mm2\n\t" "pand %%mm4, %%mm6\n\t" "pand %%mm4, %%mm7\n\t" "por %%mm2, %%mm6\n\t" // our x2 value "por %%mm1, %%mm7\n\t" // our x2 diffs "movq %%mm7, %%mm4\n\t" // save as bob uncertainty indicator �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA.inc����������������������������0000644�0001750�0001750�00000001240�14647725152�024212� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // Searches 2 pixel to the left and right, in both the old // and new fields, but takes averages. These are even // pixel addresses. Chroma match will be used. (YUY2) MERGE4PIXavg ("-4"MEMREF1("di"), "4"MEMREF3("si","cx","2")) // up left, down right MERGE4PIXavg ("4"MEMREF1("di"), "-4"MEMREF3("si","cx","2")) // up right, down left MERGE4PIXavg ("-4"MEMREF2("di","cx"), "4"MEMREF2("si","cx")) // left, right MERGE4PIXavg ("4"MEMREF2("di","cx"), "-4"MEMREF2("si","cx")) // right, left MERGE4PIXavg ("-4"MEMREF3("di","cx","2"), "4"MEMREF1("si")) // down left, up right MERGE4PIXavg ("4"MEMREF3("di","cx","2"), "-4"MEMREF1("si")) // down right, up left ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopTop.inc������������������������������0000644�0001750�0001750�00000013475�14647725152�024024� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- unsigned char* pDest; const unsigned char* pSrcP; const unsigned char* pSrc; const unsigned char* pBob; const unsigned char* pBobP; // long is int32 on ARCH_368, int64 on ARCH_AMD64. Declaring it this way // saves a lot of xor's to delete 64bit garbage. #if defined(DBL_RESIZE) || defined(USE_FOR_DSCALER) long src_pitch2 = src_pitch; // even & odd lines are not longerleaved in DScaler #else long src_pitch2 = 2 * src_pitch; // even & odd lines are longerleaved in Avisynth #endif long dst_pitch2 = 2 * dst_pitch; long y; #ifdef IS_SSE2 long Last8 = (rowsize-16); // ofs to last 16 bytes in row for SSE2 #else long Last8 = (rowsize-8); // ofs to last 8 bytes in row #endif long dst_pitchw = dst_pitch; // local stor so asm can ref pSrc = pWeaveSrc; // polongs 1 weave line above pSrcP = pWeaveSrcP; // " #ifdef DBL_RESIZE #ifdef USE_VERTICAL_FILTER pDest = pWeaveDest + dst_pitch2; #else pDest = pWeaveDest + 3*dst_pitch; #endif #else #ifdef USE_VERTICAL_FILTER pDest = pWeaveDest + dst_pitch; #else pDest = pWeaveDest + dst_pitch2; #endif #endif if (TopFirst) { pBob = pCopySrc + src_pitch2; // remember one weave line just copied previously pBobP = pCopySrcP + src_pitch2; } else { pBob = pCopySrc; pBobP = pCopySrcP; } #ifndef _pBob #define _pBob "%0" #define _src_pitch2 "%1" #define _pDest "%2" #define _dst_pitchw "%3" #define _Last8 "%4" #define _pSrc "%5" #define _pSrcP "%6" #define _pBobP "%7" #define _olddx "%8" #define _UVMask "%9" #define _ShiftMask "%10" #define _FOURS "%11" #define _TENS "%12" #define _Max_Vals "%13" #define _Min_Vals "%14" #define _YMask "%15" #define _Max_Mov "%16" #define _ONES "%17" #define _DiffThres "%18" #endif for (y=1; y < FldHeight-1; y++) { // pretend it's indented -->> __asm__ __volatile__ ( // Loop general reg usage // // ax - pBobP, then pDest // dx - pBob // cx - src_pitch2 // _olddx - current offset // di - prev weave pixels, 1 line up // si - next weave pixels, 1 line up #ifdef IS_SSE2 // sse2 code deleted for now #else // simple bob first 8 bytes MEMREG ("mov", _pBob, "dx") MEMREG ("mov", _src_pitch2, "cx") #ifdef USE_VERTICAL_FILTER "movq "MEMREF1("dx")", %%mm0\n\t" "movq "MEMREF2("dx", "cx")", %%mm1\n\t" //, qword ptr["XDX"+"XCX"] "movq %%mm0, %%mm2\n\t" V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // halfway between V_PAVGB ("%%mm0", "%%mm2", "%%mm3", _ShiftMask) // 1/4 way V_PAVGB ("%%mm1", "%%mm2", "%%mm3", _ShiftMask) // 3/4 way MEMREG ("mov", _pDest, "di") MEMREG ("mov", _dst_pitchw, "ax") V_MOVNTQ (MEMREF1("di"), "%%mm0") V_MOVNTQ (MEMREF2("di","ax"), "%%mm1") // qword ptr["XDI"+"XAX"], mm1 // simple bob last 8 bytes MEMREG ("mov", _Last8, "si") REGMEM ("mov", "si", _olddx) REG2 ("add", "dx", "si") // ["XDX"+"_olddx"] "movq "MEMREF1("si")", %%mm0\n\t" "movq "MEMREF2("si", "cx")", %%mm1\n\t" // qword ptr["XSI"+"XCX"] "movq %%mm0, %%mm2\n\t" V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // halfway between V_PAVGB ("%%mm0", "%%mm2", "%%mm3", _ShiftMask) // 1/4 way V_PAVGB ("%%mm1", "%%mm2", "%%mm3", _ShiftMask) // 3/4 way MEMREG ("add", _olddx, "di") // last 8 bytes of dest V_MOVNTQ (MEMREF1("di"), "%%mm0") V_MOVNTQ (MEMREF2("di", "ax"), "%%mm1") // qword ptr["XDI"+"XAX"], mm1) #else "movq "MEMREF1("dx")", %%mm0\n\t" // pavgb mm0, qword ptr["XDX"+"XCX"] V_PAVGB ("%%mm0", MEMREF2("dx","cx"), "%%mm2", _ShiftMask) // qword ptr["XDX"+"XCX"], mm2, ShiftMask) MEMREG ("mov", _pDest, "di") V_MOVNTQ (MEMREF1("di"), "%%mm0") // simple bob last 8 bytes MEMREG ("mov", _Last8, "si") REGMEM ("mov", "si", _olddx) REG2 ("add", "dx", "si") //"XSI", ["XDX"+"_olddx"] "movq "MEMREF1("si")", %%mm0\n\t" // pavgb mm0, qword ptr["XSI"+"XCX"] V_PAVGB ("%%mm0", MEMREF2("si","cx"), "%%mm2", _ShiftMask) // qword ptr["XSI"+"XCX"], mm2, ShiftMask) MEMREG ("add", _olddx, "di") V_MOVNTQ (MEMREF1("di"), "%%mm0") // qword ptr["XDI"+"_olddx"], mm0) #endif // now loop and get the middle qwords MEMREG ("mov", _pSrc, "si") MEMREG ("mov", _pSrcP, "di") CONSTMEM ("mov", "8", _olddx) // curr offset longo all lines "1:\n\t" MEMREG ("mov", _pBobP, "ax") BUMPPTR ("8", "di", "di") BUMPPTR ("8", "si", "si") BUMPPTR ("8", "dx", "dx") MEMREG ("add", _olddx, "ax") #ifdef USE_STRANGE_BOB #include "StrangeBob.inc" #else #include "WierdBob.inc" #endif // For non-SSE2: // through out most of the rest of this loop we will malongain // mm4 our min bob value // mm5 best weave pixels so far // mm6 our max Bob value // mm7 best weighted pixel ratings so far // We will keep a slight bias to using the weave pixels // from the current location, by rating them by the min distance // from the Bob value instead of the avg distance from that value. // our best and only rating so far "pcmpeqb %%mm7, %%mm7\n\t" // ffff, say we didn't find anything good yet #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVAH.inc������������������������������0000644�0001750�0001750�00000000574�14647725152�023674� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // Searches the center vertical line above center and below, in both the old // and new fields, but takes averages. These are even pixel addresses. MERGE4PIXavgH (MEMREF3("di","cx","2"), MEMREF2("di","cx"), MEMREF2("si","cx"), MEMREF1("si")) // down, up MERGE4PIXavgH (MEMREF1("di"), MEMREF2("di","cx"), MEMREF2("si","cx"), MEMREF3("si","cx","2")) // up, down ������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/WierdBob.inc�����������������������������������0000644�0001750�0001750�00000017231�14647725152�022771� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // First, get and save our possible Bob values // Assume our pixels are layed out as follows with x the calc'd bob value // and the other pixels are from the current field // // j a b c k current field // x calculated line // m d e f n current field // // we calc the bob value as: // x2 = either avg(a,f), avg(c,d), avg(b,e), avg(j,n), or avg(k,m) // selected for the smallest of abs(a,f), abs(c,d), or abs(b,e), etc. // a,f "movq -2"MEMREF1("dx")", %%mm0\n\t" // value a from top left "movq 2"MEMREF2("dx","cx")", %%mm1\n\t" // value f from bottom right "movq %%mm0, %%mm6\n\t" //"pavgb %%mm6, %%mm1\n\t" // avg(a,f), also best so far V_PAVGB ("%%mm6", "%%mm1", "%%mm7", _ShiftMask) // avg(a,f), also best so far "movq %%mm0, %%mm7\n\t" "psubusb %%mm1, %%mm7\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm7\n\t" // abs diff, also best so far // c,d "movq 2"MEMREF1("dx")", %%mm0\n\t" // value a from top left "movq -2"MEMREF2("dx","cx")", %%mm1\n\t" // value f from bottom right "movq %%mm0, %%mm2\n\t" //"pavgb %%mm2, %%mm1\n\t" // avg(c,d) V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(c,d) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(c,d) "movq %%mm3, %%mm1\n\t" // keep copy "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0 "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00 "pand %%mm3, %%mm1\n\t" // keep only better new avg and abs "pand %%mm3, %%mm2\n\t" "pand %%mm4, %%mm6\n\t" "pand %%mm4, %%mm7\n\t" "por %%mm2, %%mm6\n\t" // and merge new & old vals keeping best "por %%mm1, %%mm7\n\t" "por "_UVMask", %%mm7\n\t" // but we know chroma is worthless so far "pand "_YMask", %%mm5\n\t" // mask out chroma from here also // j,n "movq -4"MEMREF1("dx")", %%mm0\n\t" // value j from top left "movq 4"MEMREF2("dx","cx")", %%mm1\n\t" // value n from bottom right "movq %%mm0, %%mm2\n\t" //"pavgb %%mm2, %%mm1\n\t" // avg(j,n) V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(j,n) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(j-n) "movq %%mm3, %%mm1\n\t" // keep copy "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0 "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00 "pand %%mm3, %%mm1\n\t" // keep only better new avg and abs "pand %%mm2, %%mm3\n\t" "pand %%mm4, %%mm6\n\t" "pand %%mm4, %%mm7\n\t" "por %%mm3, %%mm6\n\t" // and merge new & old vals keeping best "por %%mm1, %%mm7\n\t" // k, m "movq 4"MEMREF1("dx")", %%mm0\n\t" // value k from top right "movq -4"MEMREF2("dx","cx")", %%mm1\n\t" // value n from bottom left "movq %%mm0, %%mm4\n\t" //"pavgb %%mm4, %%mm1\n\t" // avg(k,m) V_PAVGB ("%%mm4", "%%mm1", "%%mm3", _ShiftMask) // avg(k,m) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(k,m) "movq %%mm3, %%mm1\n\t" // keep copy "movq %%mm4, %%mm2\n\t" // avg(k,m) "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0 "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00 "pand %%mm3, %%mm1\n\t" // keep only better new avg and abs "pand %%mm2, %%mm3\n\t" "pand %%mm4, %%mm6\n\t" "pand %%mm4, %%mm7\n\t" "por %%mm3, %%mm6\n\t" // and merge new & old vals keeping best "por %%mm1, %%mm7\n\t" // b,e "movq "MEMREF1("dx")", %%mm0\n\t" // value b from top "movq "MEMREF2("dx","cx")", %%mm1\n\t" // value e from bottom // We will also calc here the max/min values to later limit comb // so the max excursion will not exceed the Max_Comb constant #ifdef SKIP_SEARCH "movq %%mm0, %%mm2\n\t" //"pminub %%mm2, %%mm1\n\t" V_PMINUB ("%%mm2", "%%mm1", "%%mm4") //"pmaxub %%mm6, %%mm2\n\t" // clip our current results so far to be above this V_PMAXUB ("%%mm6", "%%mm2") "movq %%mm0, %%mm2\n\t" V_PMAXUB ("%%mm2", "%%mm1") //"pminub %%mm6, %%mm2\n\t" // clip our current results so far to be below this V_PMINUB ("%%mm6", "%%mm2", "%%mm4") #else "movq %%mm0, %%mm2\n\t" "movq "MEMREF1("ax")", %%mm4\n\t" "psubusb %%mm4, %%mm2\n\t" "psubusb %%mm0, %%mm4\n\t" "por %%mm2, %%mm4\n\t" // abs diff "movq %%mm1, %%mm2\n\t" "movq "MEMREF2("ax","cx")", %%mm3\n\t" "psubusb %%mm3, %%mm2\n\t" "psubusb %%mm1, %%mm3\n\t" "por %%mm2, %%mm3\n\t" // abs diff //"pmaxub %%mm3, %%mm4\n\t" // top or bottom pixel moved most V_PMAXUB ("%%mm3", "%%mm4") // top or bottom pixel moved most "psubusb "_Max_Mov", %%mm3\n\t" // moved more than allowed? or goes to 0? "pxor %%mm4, %%mm4\n\t" "pcmpeqb %%mm4, %%mm3\n\t" // now ff where low motion, else high motion "movq %%mm0, %%mm2\n\t" //"pminub %%mm2, %%mm1\n\t" V_PMINUB ("%%mm2", "%%mm1", "%%mm4") //"pmaxub %%mm6, %%mm2\n\t" // clip our current results so far to be above this V_PMAXUB ("%%mm6", "%%mm2") "psubusb %%mm3, %%mm2\n\t" // maybe decrease it to 0000.. if no surround motion //""movq %%mm2, "_Min_Vals"\n\t" "movq %%mm0, %%mm2\n\t" V_PMAXUB ("%%mm2", "%%mm1") //"pminub %%mm6, %%mm2" // clip our current results so far to be below this V_PMINUB ("%%mm6", "%%mm2", "%%mm4") "paddusb %%mm3, %%mm2\n\t" // maybe increase it to ffffff if no surround motion //"movq %%mm2, "_Max_Vals"\n\t" #endif "movq %%mm0, %%mm2\n\t" //"pavgb %%mm2, %%mm1\n\t" // avg(b,e) V_PAVGB ("%%mm2", "%%mm1", "%%mm3", _ShiftMask) // avg(b,e) "movq %%mm0, %%mm3\n\t" "psubusb %%mm1, %%mm3\n\t" "psubusb %%mm0, %%mm1\n\t" "por %%mm1, %%mm3\n\t" // abs(c,d) "movq %%mm3, %%mm1\n\t" // keep copy of diffs "pxor %%mm4, %%mm4\n\t" "psubusb %%mm7, %%mm3\n\t" // nonzero where new weights bigger, else 0 "pcmpeqb %%mm4, %%mm3\n\t" // now ff where new better, else 00 "pcmpeqb %%mm3, %%mm4\n\t" // here ff where old better, else 00 "pand %%mm3, %%mm1\n\t" "pand %%mm3, %%mm2\n\t" "pand %%mm4, %%mm6\n\t" "pand %%mm4, %%mm7\n\t" "por %%mm2, %%mm6\n\t" // our x2 value "por %%mm1, %%mm7\n\t" // our x2 diffs "movq %%mm7, %%mm4\n\t" // save as bob uncertainty indicator �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/tomsmocompmacros.h�����������������������������0000644�0001750�0001750�00000025213�14647725152�024353� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include <string.h> #include <math.h> #include <stdlib.h> #include "mangle.h" #define USE_FOR_DSCALER #define MyMemCopy xine_fast_memcpy // Define a few macros for CPU dependent instructions. // I suspect I don't really understand how the C macro preprocessor works but // this seems to get the job done. // TRB 7/01 // BEFORE USING THESE YOU MUST SET: // #define SSE_TYPE SSE (or MMX or 3DNOW) // some macros for pavgb instruction // V_PAVGB(mmr1, mmr2, mmr work register, smask) mmr2 may = mmrw if you can trash it #define V_PAVGB_MMX(mmr1, mmr2, mmrw, smask) \ "movq "mmr2", "mmrw"\n\t" \ "pand "smask", "mmrw"\n\t" \ "psrlw $1, "mmrw"\n\t" \ "pand "smask", "mmr1"\n\t" \ "psrlw $1, "mmr1"\n\t" \ "paddusb "mmrw", "mmr1"\n\t" #define V_PAVGB_SSE(mmr1, mmr2, mmrw, smask) "pavgb "mmr2", "mmr1"\n\t" #define V_PAVGB_3DNOW(mmr1, mmr2, mmrw, smask) "pavgusb "mmr2", "mmr1"\n\t" #define V_PAVGB(mmr1, mmr2, mmrw, smask) V_PAVGB2(mmr1, mmr2, mmrw, smask, SSE_TYPE) #define V_PAVGB2(mmr1, mmr2, mmrw, smask, ssetyp) V_PAVGB3(mmr1, mmr2, mmrw, smask, ssetyp) #define V_PAVGB3(mmr1, mmr2, mmrw, smask, ssetyp) V_PAVGB_##ssetyp(mmr1, mmr2, mmrw, smask) // some macros for pmaxub instruction #define V_PMAXUB_MMX(mmr1, mmr2) \ "psubusb "mmr2", "mmr1"\n\t" \ "paddusb "mmr2", "mmr1"\n\t" #define V_PMAXUB_SSE(mmr1, mmr2) "pmaxub "mmr2", "mmr1"\n\t" #define V_PMAXUB_3DNOW(mmr1, mmr2) V_PMAXUB_MMX(mmr1, mmr2) // use MMX version #define V_PMAXUB(mmr1, mmr2) V_PMAXUB2(mmr1, mmr2, SSE_TYPE) #define V_PMAXUB2(mmr1, mmr2, ssetyp) V_PMAXUB3(mmr1, mmr2, ssetyp) #define V_PMAXUB3(mmr1, mmr2, ssetyp) V_PMAXUB_##ssetyp(mmr1, mmr2) // some macros for pminub instruction // V_PMINUB(mmr1, mmr2, mmr work register) mmr2 may NOT = mmrw #define V_PMINUB_MMX(mmr1, mmr2, mmrw) \ "pcmpeqb "mmrw", "mmrw"\n\t" \ "psubusb "mmr2", "mmrw"\n\t" \ "paddusb "mmrw", "mmr1"\n\t" \ "psubusb "mmrw", "mmr1"\n\t" #define V_PMINUB_SSE(mmr1, mmr2, mmrw) "pminub "mmr2", "mmr1"\n\t" #define V_PMINUB_3DNOW(mmr1, mmr2, mmrw) V_PMINUB_MMX(mmr1, mmr2, mmrw) // use MMX version #define V_PMINUB(mmr1, mmr2, mmrw) V_PMINUB2(mmr1, mmr2, mmrw, SSE_TYPE) #define V_PMINUB2(mmr1, mmr2, mmrw, ssetyp) V_PMINUB3(mmr1, mmr2, mmrw, ssetyp) #define V_PMINUB3(mmr1, mmr2, mmrw, ssetyp) V_PMINUB_##ssetyp(mmr1, mmr2, mmrw) // some macros for movntq instruction // V_MOVNTQ(mmr1, mmr2) #define V_MOVNTQ_MMX(mmr1, mmr2) "movq "mmr2", "mmr1"\n\t" #define V_MOVNTQ_3DNOW(mmr1, mmr2) "movq "mmr2", "mmr1"\n\t" #define V_MOVNTQ_SSE(mmr1, mmr2) "movntq "mmr2", "mmr1"\n\t" #define V_MOVNTQ(mmr1, mmr2) V_MOVNTQ2(mmr1, mmr2, SSE_TYPE) #define V_MOVNTQ2(mmr1, mmr2, ssetyp) V_MOVNTQ3(mmr1, mmr2, ssetyp) #define V_MOVNTQ3(mmr1, mmr2, ssetyp) V_MOVNTQ_##ssetyp(mmr1, mmr2) // end of macros #ifdef IS_SSE2 #define MERGE4PIXavg(PADDR1, PADDR2) \ "movdqu "PADDR1", %%xmm0\n\t" /* our 4 pixels */ \ "movdqu "PADDR2", %%xmm1\n\t" /* our pixel2 value */ \ "movdqa %%xmm0, %%xmm2\n\t" /* another copy of our pixel1 value */ \ "movdqa %%xmm1, %%xmm3\n\t" /* another copy of our pixel1 value */ \ "psubusb %%xmm1, %%xmm2\n\t" \ "psubusb %%xmm0, %%xmm3\n\t" \ "por %%xmm3, %%xmm2\n\t" \ "pavgb %%xmm1, %%xmm0\n\t" /* avg of 2 pixels */ \ "movdqa %%xmm2, %%xmm3\n\t" /* another copy of our our weights */ \ "pxor %%xmm1, %%xmm1\n\t" \ "psubusb %%xmm7, %%xmm3\n\t" /* nonzero where old weights lower, else 0 */ \ "pcmpeqb %%xmm1, %%xmm3\n\t" /* now ff where new better, else 00 */ \ "pcmpeqb %%xmm3, %%xmm1\n\t" /* here ff where old better, else 00 */ \ "pand %%xmm3, %%xmm0\n\t" /* keep only better new pixels */ \ "pand %%xmm3, %%xmm2\n\t" /* and weights */ \ "pand %%xmm1, %%xmm5\n\t" /* keep only better old pixels */ \ "pand %%xmm1, %%xmm7\n\t" \ "por %%xmm0, %%xmm5\n\t" /* and merge new & old vals */ \ "por %%xmm2, %%xmm7\n\t" #define MERGE4PIXavgH(PADDR1A, PADDR1B, PADDR2A, PADDR2B) \ "movdqu "PADDR1A", %%xmm0\n\t" /* our 4 pixels */ \ "movdqu "PADDR2A", %%xmm1\n\t" /* our pixel2 value */ \ "movdqu "PADDR1B", %%xmm2\n\t" /* our 4 pixels */ \ "movdqu "PADDR2B", %%xmm3\n\t" /* our pixel2 value */ \ "pavgb %%xmm2, %%xmm0\n\t" \ "pavgb %%xmm3, %%xmm1\n\t" \ "movdqa %%xmm0, %%xmm2\n\t" /* another copy of our pixel1 value */ \ "movdqa %%xmm1, %%xmm3\n\t" /* another copy of our pixel1 value */ \ "psubusb %%xmm1, %%xmm2\n\t" \ "psubusb %%xmm0, %%xmm3\n\t" \ "por %%xmm3, %%xmm2\n\t" \ "pavgb %%xmm1, %%xmm0\n\t" /* avg of 2 pixels */ \ "movdqa %%xmm2, %%xmm3\n\t" /* another copy of our our weights */ \ "pxor %%xmm1, %%xmm1\n\t" \ "psubusb %%xmm7, %%xmm3\n\t" /* nonzero where old weights lower, else 0 */ \ "pcmpeqb %%xmm1, %%xmm3\n\t" /* now ff where new better, else 00 */ \ "pcmpeqb %%xmm3, %%xmm1\n\t" /* here ff where old better, else 00 */ \ "pand %%xmm3, %%xmm0\n\t" /* keep only better new pixels */ \ "pand %%xmm3, %%xmm2\n\t" /* and weights */ \ "pand %%xmm1, %%xmm5\n\t" /* keep only better old pixels */ \ "pand %%xmm1, %%xmm7\n\t" \ "por %%xmm0, %%xmm5\n\t" /* and merge new & old vals */ \ "por %%xmm2, %%xmm7\n\t" #define RESET_CHROMA "por "_UVMask", %%xmm7\n\t" #else // ifdef IS_SSE2 #define MERGE4PIXavg(PADDR1, PADDR2) \ "movq "PADDR1", %%mm0\n\t" /* our 4 pixels */ \ "movq "PADDR2", %%mm1\n\t" /* our pixel2 value */ \ "movq %%mm0, %%mm2\n\t" /* another copy of our pixel1 value */ \ "movq %%mm1, %%mm3\n\t" /* another copy of our pixel1 value */ \ "psubusb %%mm1, %%mm2\n\t" \ "psubusb %%mm0, %%mm3\n\t" \ "por %%mm3, %%mm2\n\t" \ V_PAVGB ("%%mm0", "%%mm1", "%%mm3", _ShiftMask) /* avg of 2 pixels */ \ "movq %%mm2, %%mm3\n\t" /* another copy of our our weights */ \ "pxor %%mm1, %%mm1\n\t" \ "psubusb %%mm7, %%mm3\n\t" /* nonzero where old weights lower, else 0 */ \ "pcmpeqb %%mm1, %%mm3\n\t" /* now ff where new better, else 00 */ \ "pcmpeqb %%mm3, %%mm1\n\t" /* here ff where old better, else 00 */ \ "pand %%mm3, %%mm0\n\t" /* keep only better new pixels */ \ "pand %%mm3, %%mm2\n\t" /* and weights */ \ "pand %%mm1, %%mm5\n\t" /* keep only better old pixels */ \ "pand %%mm1, %%mm7\n\t" \ "por %%mm0, %%mm5\n\t" /* and merge new & old vals */ \ "por %%mm2, %%mm7\n\t" #define MERGE4PIXavgH(PADDR1A, PADDR1B, PADDR2A, PADDR2B) \ "movq "PADDR1A", %%mm0\n\t" /* our 4 pixels */ \ "movq "PADDR2A", %%mm1\n\t" /* our pixel2 value */ \ "movq "PADDR1B", %%mm2\n\t" /* our 4 pixels */ \ "movq "PADDR2B", %%mm3\n\t" /* our pixel2 value */ \ V_PAVGB("%%mm0", "%%mm2", "%%mm2", _ShiftMask) \ V_PAVGB("%%mm1", "%%mm3", "%%mm3", _ShiftMask) \ "movq %%mm0, %%mm2\n\t" /* another copy of our pixel1 value */ \ "movq %%mm1, %%mm3\n\t" /* another copy of our pixel1 value */ \ "psubusb %%mm1, %%mm2\n\t" \ "psubusb %%mm0, %%mm3\n\t" \ "por %%mm3, %%mm2\n\t" \ V_PAVGB("%%mm0", "%%mm1", "%%mm3", _ShiftMask) /* avg of 2 pixels */ \ "movq %%mm2, %%mm3\n\t" /* another copy of our our weights */ \ "pxor %%mm1, %%mm1\n\t" \ "psubusb %%mm7, %%mm3\n\t" /* nonzero where old weights lower, else 0 */ \ "pcmpeqb %%mm1, %%mm3\n\t" /* now ff where new better, else 00 */ \ "pcmpeqb %%mm3, %%mm1\n\t" /* here ff where old better, else 00 */ \ "pand %%mm3, %%mm0\n\t" /* keep only better new pixels */ \ "pand %%mm3, %%mm2\n\t" /* and weights */ \ "pand %%mm1, %%mm5\n\t" /* keep only better old pixels */ \ "pand %%mm1, %%mm7\n\t" \ "por %%mm0, %%mm5\n\t" /* and merge new & old vals */ \ "por %%mm2, %%mm7\n\t" #define RESET_CHROMA "por "_UVMask", %%mm7\n\t" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopVA.inc�������������������������������0000644�0001750�0001750�00000000452�14647725152�023557� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // Searches the center vertical line above center and below, in both the old // and new fields, but takes averages. These are even pixel addresses. MERGE4PIXavg (MEMREF3("di","cx","2"), MEMREF1("si")) // down, up MERGE4PIXavg (MEMREF1("di"), MEMREF3("si","cx","2")) // up, down ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH.inc����������������������������0000644�0001750�0001750�00000001312�14647725152�024164� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Searches 1 pixel to the left and right, in both the old // and new fields, but takes v-half pel averages. These are odd // pixel addresses. Any chroma match will not be used. (YUY2) MERGE4PIXavgH ("-2"MEMREF1("di"), "-2"MEMREF2("di","cx"), "2"MEMREF2("si","cx"), "2"MEMREF3("si","cx","2")) // up left, down right MERGE4PIXavgH ("2"MEMREF1("di"), "2"MEMREF2("di","cx"), "-2"MEMREF2("si","cx"), "-2"MEMREF3("si","cx","2")) // up right, down left MERGE4PIXavgH ("-2"MEMREF3("di","cx","2"), "-2"MEMREF2("di","cx"), "2"MEMREF2("si","cx"), "2"MEMREF1("si")) // down left, up right MERGE4PIXavgH ("2"MEMREF3("di","cx","2"), "2"MEMREF2("di","cx"), "-2"MEMREF2("si","cx"), "-2"MEMREF1("si")) // down right, up left ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopEdgeA8.inc���������������������������0000644�0001750�0001750�00000001241�14647725152�024303� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // Searches 4 pixel to the left and right, in both the old // and new fields, but takes averages. These are even // pixel addresses. Chroma match will be used. (YUY2) MERGE4PIXavg ("-8"MEMREF1("di"), "8"MEMREF3("si","cx","2")) // up left, down right MERGE4PIXavg ("8"MEMREF1("di"), "-8"MEMREF3("si","cx","2")) // up right, down left MERGE4PIXavg ("-8"MEMREF2("di","cx"), "8"MEMREF2("si","cx")) // left, right MERGE4PIXavg ("8"MEMREF2("di","cx"), "-8"MEMREF2("si","cx")) // right, left MERGE4PIXavg ("-8"MEMREF3("di","cx","2"), "8"MEMREF1("si")) // down left, up right MERGE4PIXavg ("8"MEMREF3("di","cx","2"), "-8"MEMREF1("si")) // down right, up left ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll.inc������������������������������0000644�0001750�0001750�00000014246�14647725152�023765� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- ///////////////////////////////////////////////////////////////////////////// // Copyright (c) 2002 Tom Barry All rights reserved. ///////////////////////////////////////////////////////////////////////////// // // This file is subject to the terms of the GNU General Public License as // published by the Free Software Foundation. A copy of this license is // included with this software distribution in the file COPYING. If you // do not have a copy, you may obtain a copy by writing to the Free // Software Foundation, 51 Franklin St, Fifth Floor, Boston, MA // 02110-1301, USA. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details // // Also, this program is "Philanthropy-Ware". That is, if you like it and // feel the need to reward or inspire the author then please feel free (but // not obligated) to consider joining or donating to the Electronic Frontier // Foundation. This will help keep cyber space free of barbed wire and bullsh*t. // See www.eff.org for details ///////////////////////////////////////////////////////////////////////////// #if !defined(MASKS_DEFINED) #define MASKS_DEFINED static const int64_t __attribute__((__used__)) Max_Mov = 0x0404040404040404ull; static const int64_t __attribute__((__used__)) DiffThres = 0x0f0f0f0f0f0f0f0full; static const int64_t __attribute__((__used__)) YMask = 0x00ff00ff00ff00ffull; // keeps only luma static const int64_t __attribute__((__used__)) UVMask = 0xff00ff00ff00ff00ull; // keeps only chroma static const int64_t __attribute__((__used__)) TENS = 0x0a0a0a0a0a0a0a0aull; static const int64_t __attribute__((__used__)) FOURS = 0x0404040404040404ull; static const int64_t __attribute__((__used__)) ONES = 0x0101010101010101ull; static const int64_t __attribute__((__used__)) ShiftMask = 0xfefffefffefffeffull; static int64_t Min_Vals = 0x0000000000000000ull; static int64_t Max_Vals = 0x0000000000000000ull; #endif #ifndef TopFirst #define TopFirst IsOdd #endif #ifdef SEFUNC #undef SEFUNC #endif #if defined(IS_SSE) #define SEFUNC(x) Search_Effort_SSE_##x #elif defined(IS_3DNOW) #define SEFUNC(x) Search_Effort_3DNOW_##x #else #define SEFUNC(x) Search_Effort_MMX_##x #endif static void FUNCT_NAME(uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) { int IsOdd; const unsigned char* pWeaveSrc; const unsigned char* pWeaveSrcP; unsigned char* pWeaveDest; const unsigned char* pCopySrc; const unsigned char* pCopySrcP; unsigned char* pCopyDest; int src_pitch; int dst_pitch; int rowsize; int FldHeight; int stride = (width*2); long olddx; src_pitch = stride*2; dst_pitch = outstride; rowsize = stride; FldHeight = height / 2; if( second_field ) { pWeaveSrc = data->f0; pCopySrc = data->f0; pWeaveSrcP = data->f1; pCopySrcP = data->f1; } else { pWeaveSrc = data->f0; pCopySrc = data->f1; pWeaveSrcP = data->f1; pCopySrcP = data->f2; } if( bottom_field ) { pWeaveSrc += stride; pCopySrc += 0; pWeaveSrcP += stride; pCopySrcP += 0; } else { pWeaveSrc += 0; pCopySrc += stride; pWeaveSrcP += 0; pCopySrcP += stride; } IsOdd = bottom_field; #ifdef IS_SSE2 // SSE2 support temporarily deleted #endif if(IsOdd) { // if we have an odd field we copy an even field and weave an odd field pCopyDest = output; pWeaveDest = output + dst_pitch; } else { // if we have an ever field we copy an odd field and weave an even field pCopyDest = output + dst_pitch; pWeaveDest = output; } // copy 1st and last weave lines Fieldcopy(pWeaveDest, pCopySrc, rowsize, 1, dst_pitch*2, src_pitch); Fieldcopy(pWeaveDest+(FldHeight-1)*dst_pitch*2, pCopySrc+(FldHeight-1)*src_pitch, rowsize, 1, dst_pitch*2, src_pitch); #ifdef USE_VERTICAL_FILTER // Vertical Filter currently not implemented for DScaler !! // copy 1st and last lines the copy field Fieldcopy(pCopyDest, pCopySrc, rowsize, 1, dst_pitch*2, src_pitch); Fieldcopy(pCopyDest+(FldHeight-1)*dst_pitch*2, pCopySrc+(FldHeight-1)*src_pitch, rowsize, 1, dst_pitch*2, src_pitch); #else // copy all of the copy field Fieldcopy(pCopyDest, pCopySrc, rowsize, FldHeight, dst_pitch*2, src_pitch); #endif // then go fill in the hard part, being variously lazy depending upon // SearchEffort if (UseStrangeBob == 0) { if (SearchEffort == 0) goto SEFUNC (0); else if (SearchEffort <= 1) goto SEFUNC (1); /* else if (SearchEffort <= 2) goto SEFUNC (2); */ else if (SearchEffort <= 3) goto SEFUNC (3); else if (SearchEffort <= 5) goto SEFUNC (5); else if (SearchEffort <= 9) goto SEFUNC (9); else if (SearchEffort <= 11) goto SEFUNC(11); else if (SearchEffort <= 13) goto SEFUNC(13); else if (SearchEffort <= 15) goto SEFUNC(15); else if (SearchEffort <= 19) goto SEFUNC(19); else if (SearchEffort <= 21) goto SEFUNC(21); else goto SEFUNC(Max); } else { if (SearchEffort == 0) goto SEFUNC (0_SB); else if (SearchEffort <= 1) goto SEFUNC (1_SB); /* else if (SearchEffort <= 2) goto SEFUNC (2_SB); */ else if (SearchEffort <= 3) goto SEFUNC (3_SB); else if (SearchEffort <= 5) goto SEFUNC (5_SB); else if (SearchEffort <= 9) goto SEFUNC (9_SB); else if (SearchEffort <= 11) goto SEFUNC(11_SB); else if (SearchEffort <= 13) goto SEFUNC(13_SB); else if (SearchEffort <= 15) goto SEFUNC(15_SB); else if (SearchEffort <= 19) goto SEFUNC(19_SB); else if (SearchEffort <= 21) goto SEFUNC(21_SB); else goto SEFUNC(Max_SB); } end: #if defined(ARCH_X86) __asm__ __volatile__("emms"); #endif return; #include "TomsMoCompAll2.inc" #define USE_STRANGE_BOB #include "TomsMoCompAll2.inc" #undef USE_STRANGE_BOB } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopBottom.inc���������������������������0000644�0001750�0001750�00000010535�14647725152�024520� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- #ifdef IS_SSE2 //sse2 code deleted for now #else // Version for non-SSE2 #ifdef SKIP_SEARCH "movq %%mm6, %%mm0\n\t" // just use the results of our wierd bob #else // JA 9/Dec/2002 // failed experiment // but leave in placeholder for me to play about #ifdef DONT_USE_STRANGE_BOB // Use the best weave if diffs less than 10 as that // means the image is still or moving cleanly // if there is motion we will clip which will catch anything "psubusb "_FOURS", %%mm7\n\t" // sets bits to zero if weave diff < 4 "pxor %%mm0, %%mm0\n\t" "pcmpeqb %%mm0, %%mm7\n\t" // all ff where weave better, else 00 "pcmpeqb %%mm7, %%mm0\n\t" // all ff where bob better, else 00 "pand %%mm6, %%mm0\n\t" // use bob for these pixel values "pand %%mm5, %%mm7\n\t" // use weave for these "por %%mm7, %%mm0\n\t" // combine both #else // Use the better of bob or weave // pminub mm4, TENS // the most we care about V_PMINUB ("%%mm4", _TENS, "%%mm0") // the most we care about "psubusb %%mm4, %%mm7\n\t" // foregive that much from weave est? "psubusb "_FOURS", %%mm7\n\t" // bias it a bit toward weave "pxor %%mm0, %%mm0\n\t" "pcmpeqb %%mm0, %%mm7\n\t" // all ff where weave better, else 00 "pcmpeqb %%mm7, %%mm0\n\t" // all ff where bob better, else 00 "pand %%mm6, %%mm0\n\t" // use bob for these pixel values "pand %%mm5, %%mm7\n\t" // use weave for these "por %%mm7, %%mm0\n\t" // combine both #endif // pminub mm0, Max_Vals // but clip to catch the stray error // V_PMINUB ("%%mm0", _Max_Vals, "%%mm1") // but clip to catch the stray error // pmaxub mm0, Min_Vals // V_PMAXUB ("%%mm0", _Min_Vals) #endif MEMREG ("mov", _pDest, "ax") MEMREG ("add", _olddx, "ax") #ifdef USE_VERTICAL_FILTER "movq %%mm0, %%mm1\n\t" // pavgb mm0, qword ptr["XDX"] V_PAVGB ("%%mm0", MEMREF1("dx"), "%%mm2", _ShiftMask) // movntq qword ptr["XAX"+"_olddx"], mm0 V_MOVNTQ (MEMREF1("ax"), "%%mm0") // pavgb mm1, qword ptr["XDX"+"XCX"] V_PAVGB ("%%mm1", MEMREF2("dx","cx"), "%%mm2", _ShiftMask) MEMREG ("add", _dst_pitchw, "dx") // movntq qword ptr["XAX"+"_olddx"], mm1 V_MOVNTQ (MEMREF1("ax"), "%%mm1") #else // movntq qword ptr["XAX"+"_olddx"], mm0 V_MOVNTQ (MEMREF1("ax"), "%%mm0") #endif CONSTMEM ("add", "8", _olddx) // bump offset pointer MEMREG ("mov", _olddx, "ax") MEMREG ("cmp", _Last8, "ax") // done with line? "jb 1b\n\t" // y #endif : /* no outputs */ : "m"(pBob), "m"(src_pitch2), "m"(pDest), "m"(dst_pitchw), "m"(Last8), "m"(pSrc), "m"(pSrcP), "m"(pBobP), "m"(olddx), "m"(UVMask), "m"(ShiftMask), "m"(FOURS), "m"(TENS), "m"(Max_Vals), "m"(Min_Vals), "m"(YMask), "m"(Max_Mov), "m"(ONES), "m"(DiffThres) : #if defined(ARCH_X86_64) || defined(ARCH_X86_X32) "rax", "rcx", "rdx", "rsi", "rdi", /* the following clobber list causes trouble for gcc 2.95. it shouldn't be * an issue as, afaik, mmx registers map to the existing fp registers. */ "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", #elif defined(ARCH_X86) "eax", "ecx", "edx", "esi", "edi", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", #endif "memory", "cc" ); // adjust for next line pSrc += src_pitch2; pSrcP += src_pitch2; pDest += dst_pitch2; pBob += src_pitch2; pBobP += src_pitch2; } goto end; �������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA.inc�����������������������������0000644�0001750�0001750�00000001061�14647725152�024055� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // Searches 1 pixel to the left and right, in both the old // and new fields, but takes averages. These are odd // pixel addresses. Any chroma match will not be used. (YUY2) MERGE4PIXavg ("-2"MEMREF1("di"), "2"MEMREF3("si","cx","2")) // up left, down right MERGE4PIXavg ("2"MEMREF1("di"), "-2"MEMREF3("si","cx","2")) // up right, down left MERGE4PIXavg ("-2"MEMREF3("di","cx","2"), "2"MEMREF1("si")) // down left, up right MERGE4PIXavg ("2"MEMREF3("di","cx","2"), "-2"MEMREF1("si")) // down right, up left #include "SearchLoopOddA2.inc" �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA6.inc����������������������������0000644�0001750�0001750�00000001250�14647725152�024143� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // Searches 3 pixels to the left and right, in both the old // and new fields, but takes averages. These are odd // pixel addresses. Any chroma match will not be used. (YUY2) MERGE4PIXavg ("-6"MEMREF1("di"), "6"MEMREF3("si","cx","2")) // up left, down right MERGE4PIXavg ("6"MEMREF1("di"), "-6"MEMREF3("si","cx","2")) // up right, down left MERGE4PIXavg ("-6"MEMREF2("di","cx"), "6"MEMREF2("si","cx")) // left, right MERGE4PIXavg ("6"MEMREF2("di","cx"), "-6"MEMREF2("si","cx")) // right, left MERGE4PIXavg ("-6"MEMREF3("di","cx","2"), "6"MEMREF1("si")) // down left, up right MERGE4PIXavg ("6"MEMREF3("di","cx","2"), "-6"MEMREF1("si")) // down right, up left ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddA2.inc����������������������������0000644�0001750�0001750�00000000510�14647725152�024135� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Searches 1 pixel to the left and right, in both the old // and new fields, but takes averages. These are odd // pixel addresses. Any chroma match will not be used. (YUY2) MERGE4PIXavg ("-2"MEMREF2("di","cx"), "2"MEMREF2("si","cx")) // left, right MERGE4PIXavg ("2"MEMREF2("di","cx"), "-2"MEMREF2("si","cx")) // right, left ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoop0A.inc�������������������������������0000644�0001750�0001750�00000001020�14647725152�023501� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- // Searches just the center pixel, in both the old // and new fields, but takes averages. This is an even // pixel address. Any chroma match will be used. (YUY2) // We best like finding 0 motion so we will bias everything we found previously // up by a little, and adjust later #ifdef IS_SSE2 "paddusb "_ONES", %%xmm7\n\t" // bias toward no motion #else "paddusb "_ONES", %%mm7\n\t" // bias toward no motion #endif MERGE4PIXavg (MEMREF2("di","cx"), MEMREF2("si","cx")) // center, in old and new ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/SearchLoopOddAH2.inc���������������������������0000644�0001750�0001750�00000000644�14647725152�024255� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Searches 1 pixel to the left and right, in both the old // and new fields, but takes vertical averages. These are odd // pixel addresses. Any chroma match will not be used. (YUY2) MERGE4PIXavgH ("-2"MEMREF2("di","cx"), MEMREF2("di","cx"), MEMREF2("si","cx"), "2"MEMREF2("si","cx")) // left, right MERGE4PIXavgH ("2"MEMREF2("di","cx"), MEMREF2("di","cx"), MEMREF2("si","cx"), "-2"MEMREF2("si","cx")) // right, left ��������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/tomsmocomp/TomsMoCompAll2.inc�����������������������������0000644�0001750�0001750�00000010543�14647725152�024043� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- #ifdef SEARCH_EFFORT_FUNC #undef SEARCH_EFFORT_FUNC #endif #ifdef USE_STRANGE_BOB #define SEARCH_EFFORT_FUNC(n) SEFUNC(n##_SB): #else #define SEARCH_EFFORT_FUNC(n) SEFUNC(n): #endif SEARCH_EFFORT_FUNC(0) // we don't try at all ;-) { //see Search_Effort_Max() for comments #define SKIP_SEARCH #include "SearchLoopTop.inc" #include "SearchLoopBottom.inc" #undef SKIP_SEARCH } SEARCH_EFFORT_FUNC(1) { //see Search_Effort_Max() for comments #include "SearchLoopTop.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } SEARCH_EFFORT_FUNC(3) { //see Search_Effort_Max() for comments #include "SearchLoopTop.inc" #include "SearchLoopOddA2.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } SEARCH_EFFORT_FUNC(5) { //see Search_Effort_Max() for comments #include "SearchLoopTop.inc" #include "SearchLoopOddA2.inc" #include "SearchLoopOddAH2.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } // 3x3 search SEARCH_EFFORT_FUNC(9) { //see SearchEffortMax() for comments #include "SearchLoopTop.inc" #include "SearchLoopOddA.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoopVA.inc" #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } // Search 9 with 2 H-half pels added SEARCH_EFFORT_FUNC(11) { //see SearchEffortMax() for comments #include "SearchLoopTop.inc" #include "SearchLoopOddA.inc" #include "SearchLoopOddAH2.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoopVA.inc" #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } // Search 11 with 2 V-half pels added SEARCH_EFFORT_FUNC(13) { //see SearchEffortMax() for comments #include "SearchLoopTop.inc" #include "SearchLoopOddA.inc" #include "SearchLoopOddAH2.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoopVAH.inc" #include "SearchLoopVA.inc" #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } // 5x3 SEARCH_EFFORT_FUNC(15) { //see SearchEffortMax() for comments #include "SearchLoopTop.inc" #include "SearchLoopOddA.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoopEdgeA.inc" #include "SearchLoopVA.inc" #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } // 5x3 + 4 half pels SEARCH_EFFORT_FUNC(19) { //see SearchEffortMax() for comments #include "SearchLoopTop.inc" #include "SearchLoopOddA.inc" #include "SearchLoopOddAH2.inc" RESET_CHROMA // pretend chroma diffs was 255 each #include "SearchLoopEdgeA.inc" #include "SearchLoopVAH.inc" #include "SearchLoopVA.inc" #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } // Handle one 4x1 block of pixels // Search a 7x3 area, no half pels SEARCH_EFFORT_FUNC(21) { //see SearchLoopTop.inc for comments #include "SearchLoopTop.inc" // odd addresses -- the pixels at odd address wouldn't generate // good luma values but we will mask those off #include "SearchLoopOddA6.inc" // 4 odd v half pels, 3 to left & right #include "SearchLoopOddA.inc" // 6 odd pels, 1 to left & right RESET_CHROMA // pretend chroma diffs was 255 each // even addresses -- use both luma and chroma from these // search averages of 2 pixels left and right #include "SearchLoopEdgeA.inc" // search vertical line and averages, -1,0,+1 #include "SearchLoopVA.inc" // blend our results and loop #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } // Handle one 4x1 block of pixels // Search a 9x3 area, no half pels SEARCH_EFFORT_FUNC(Max) { //see SearchLoopTop.inc for comments #include "SearchLoopTop.inc" // odd addresses -- the pixels at odd address wouldn't generate // good luma values but we will mask those off #include "SearchLoopOddA6.inc" // 4 odd v half pels, 3 to left & right #include "SearchLoopOddA.inc" // 6 odd pels, 1 to left & right RESET_CHROMA // pretend chroma diffs was 255 each // even addresses -- use both luma and chroma from these // search averages of 4 pixels left and right #include "SearchLoopEdgeA8.inc" // search averages of 2 pixels left and right #include "SearchLoopEdgeA.inc" // search vertical line and averages, -1,0,+1 #include "SearchLoopVA.inc" // blend our results and loop #include "SearchLoop0A.inc" #include "SearchLoopBottom.inc" } #undef SEARCH_EFFORT_FUNC �������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/scalerbob.c�����������������������������������������������0000644�0001750�0001750�00000003247�14647725152�020506� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Dummy plugin for 'scalerbob' support. * * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "plugins.h" #include "speedy.h" #include "deinterlace.h" static const deinterlace_method_t scalerbobmethod = { "Scaler Bob", "ScalerBob", /* "Television: Half Resolution", "TelevisionHalf", */ 1, 0, 1, 1, 0, 0, 0, 0, "Expands each field independently without blurring or copying in time. " "Use this if you want TV-quality with low CPU, and you have configured " "your monitor to run at the refresh rate of the video signal.\n" "\n" "Half resolution is poor quality but low CPU requirements for watching " "in a small window." }; const deinterlace_method_t *scalerbob_get_method( void ) { return &scalerbobmethod; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/greedyh.asm�����������������������������������������������0000644�0001750�0001750�00000034315�14647725152�020537� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// -*- c++ -*- ///////////////////////////////////////////////////////////////////////////// // Copyright (c) 2001 Tom Barry. All rights reserved. ///////////////////////////////////////////////////////////////////////////// // // This file is subject to the terms of the GNU General Public License as // published by the Free Software Foundation. A copy of this license is // included with this software distribution in the file COPYING. If you // do not have a copy, you may obtain a copy by writing to the Free // Software Foundation, 51 Franklin St, Fifth Floor, Boston, MA // 02110-1301, USA. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details // ///////////////////////////////////////////////////////////////////////////// #include "x86-64_macros.inc" #if !defined(MASKS_DEFINED) #define MASKS_DEFINED static const int64_t __attribute__((__used__)) YMask = 0x00ff00ff00ff00ffull; // to keep only luma static const int64_t __attribute__((__used__)) UVMask = 0xff00ff00ff00ff00ull; // to keep only chroma static const int64_t __attribute__((__used__)) ShiftMask = 0xfefffefffefffeffull; // to avoid shifting chroma to luma static const int64_t __attribute__((__used__)) QW256 = 0x0100010001000100ull; // 4 256's static int64_t MaxComb; static int64_t MotionThreshold; static int64_t MotionSense; static int64_t QW256B; #endif static void FUNCT_NAME(uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) { int64_t i; int stride = (width*2); int InfoIsOdd = bottom_field; int Line; long LoopCtr; unsigned int Pitch = stride*2; int FieldHeight = height / 2; unsigned char* L1; // ptr to Line1, of 3 unsigned char* L2; // ptr to Line2, the weave line unsigned char* L3; // ptr to Line3 unsigned char* L2P; // ptr to prev Line2 unsigned char* temp; unsigned char* Dest = output; int64_t LastAvg=0; //interp value from left qword // Set up our two parms that are actually evaluated for each pixel i=GreedyMaxComb; MaxComb = i << 56 | i << 48 | i << 40 | i << 32 | i << 24 | i << 16 | i << 8 | i; i = GreedyMotionThreshold; // scale to range of 0-257 MotionThreshold = i << 48 | i << 32 | i << 16 | i | UVMask; i = GreedyMotionSense; // scale to range of 0-257 MotionSense = i << 48 | i << 32 | i << 16 | i; i = 0xffffffff - 256; QW256B = i << 48 | i << 32 | i << 16 | i; // save a couple instr on PMINSW instruct. // copy first even line no matter what, and the first odd line if we're // processing an EVEN field. (note diff from other deint rtns.) if( second_field ) { L1 = data->f0; L2 = data->f0; L2P = data->f1; } else { L1 = data->f1; L2 = data->f0; L2P = data->f1; } if( InfoIsOdd ) { L1 += 0; L2 += stride; L3 = L1 + Pitch; L2P += stride; // copy first even line xine_fast_memcpy(Dest, L1, stride); Dest += outstride; } else { // copy first even line xine_fast_memcpy(Dest, L2, stride); Dest += outstride; L1 += stride; L2 += Pitch; L3 = L1 + Pitch; L2P += Pitch; // then first odd line xine_fast_memcpy(Dest, L1, stride); Dest += outstride; } for (Line = 0; Line < (FieldHeight - 1); ++Line) { LoopCtr = stride / 8 - 1; // there are LineLength / 8 qwords per line but do 1 less, adj at end of loop /* Hans-Dieter Kosch writes: * * > The older compilers do not understand the syntax * > __asm__ ( "command %[name0]" : : [name0] "x"(arg0) ) * > They only understand * > __asm__ ( "command %0" : : "x"(arg0) ) * * now we define the arguments to make the asm code less ugly. */ #ifndef asmLastAvg #define asmLastAvg "%0" #define asmL1 "%1" #define asmL3 "%2" #define asmtemp "%3" #define asmL2 "%4" #define asmDest "%5" #define asmLoopCtr "%6" #endif // For ease of reading, the comments below assume that we're operating on an odd // field (i.e., that InfoIsOdd is true). Assume the obvious for even lines.. temp = L2P; __asm__ __volatile__ ( MEMREG ("mov", asmL1, "ax") BUMPPTR ("8", "ax", "dx") // next qword needed by DJR MEMREG ("mov", asmL3, "cx") REG2 ("sub", "ax", "cx") // carry L3 addr as an offset MEMREG ("mov", asmL2, "si") MEMREG ("mov", asmDest, "di") // DL1 if Odd or DL2 if Even ".align 8\n\t" "1:\n\t" "movq "MEMREF1("si")", %%mm0\n\t" // L2 - the newest weave pixel value "movq "MEMREF1("ax")", %%mm1\n\t" // L1 - the top pixel REG1 ("push", "dx") MEMREG ("mov", asmtemp, "dx") "movq "MEMREF1("dx")", %%mm2\n\t" // L2P - the prev weave pixel REG1 ("pop", "dx") "movq "MEMREF2("ax","cx")", %%mm3\n\t" // L3, next odd row "movq %%mm1, %%mm6\n\t" // L1 - get simple single pixel interp // pavgb mm6, mm3 // use macro below V_PAVGB ("%%mm6", "%%mm3", "%%mm4", "%8") // DJR - Diagonal Jaggie Reduction // In the event that we are going to use an average (Bob) pixel we do not want a jagged // stair step effect. To combat this we avg in the 2 horizontally adjacen pixels into the // interpolated Bob mix. This will do horizontal smoothing for only the Bob'd pixels. "movq "asmLastAvg", %%mm4\n\t" // the bob value from prev qword in row "movq %%mm6, "asmLastAvg"\n\t" // save for next pass "psrlq $48, %%mm4\n\t" // right justify 1 pixel "movq %%mm6, %%mm7\n\t" // copy of simple bob pixel "psllq $16, %%mm7\n\t" // left justify 3 pixels "por %%mm7, %%mm4\n\t" // and combine "movq "MEMREF1("dx")", %%mm5\n\t" // next horiz qword from L1 // pavgb mm5, qword ptr[ebx+ecx] // next horiz qword from L3, use macro below V_PAVGB ("%%mm5", MEMREF2("dx","cx"), "%%mm7", "%8") "psllq $48, %%mm5\n\t" // left just 1 pixel "movq %%mm6, %%mm7\n\t" // another copy of simple bob pixel "psrlq $16, %%mm7\n\t" // right just 3 pixels "por %%mm7, %%mm5\n\t" // combine // pavgb mm4, mm5 // avg of forward and prev by 1 pixel, use macro V_PAVGB ("%%mm4", "%%mm5", "%%mm5", "%8") // mm5 gets modified if MMX // pavgb mm6, mm4 // avg of center and surround interp vals, use macro V_PAVGB ("%%mm6", "%%mm4", "%%mm7", "%8") // Don't do any more averaging than needed for mmx. It hurts performance and causes rounding errors. #ifndef IS_MMX // pavgb mm4, mm6 // 1/4 center, 3/4 adjacent V_PAVGB ("%%mm4", "%%mm6", "%%mm7", "%8") // pavgb mm6, mm4 // 3/8 center, 5/8 adjacent V_PAVGB ("%%mm6", "%%mm4", "%%mm7", "%8") #endif // get abs value of possible L2 comb "movq %%mm6, %%mm4\n\t" // work copy of interp val "movq %%mm2, %%mm7\n\t" // L2 "psubusb %%mm4, %%mm7\n\t" // L2 - avg "movq %%mm4, %%mm5\n\t" // avg "psubusb %%mm2, %%mm5\n\t" // avg - L2 "por %%mm7, %%mm5\n\t" // abs(avg-L2) // get abs value of possible L2P comb "movq %%mm0, %%mm7\n\t" // L2P "psubusb %%mm4, %%mm7\n\t" // L2P - avg "psubusb %%mm0, %%mm4\n\t" // avg - L2P "por %%mm7, %%mm4\n\t" // abs(avg-L2P) // use L2 or L2P depending upon which makes smaller comb "psubusb %%mm5, %%mm4\n\t" // see if it goes to zero "psubusb %%mm5, %%mm5\n\t" // 0 "pcmpeqb %%mm5, %%mm4\n\t" // if (mm4=0) then FF else 0 "pcmpeqb %%mm4, %%mm5\n\t" // opposite of mm4 // if Comb(L2P) <= Comb(L2) then mm4=ff, mm5=0 else mm4=0, mm5 = 55 "pand %%mm2, %%mm5\n\t" // use L2 if mm5 == ff, else 0 "pand %%mm0, %%mm4\n\t" // use L2P if mm4 = ff, else 0 "por %%mm5, %%mm4\n\t" // may the best win // Inventory: at this point we have the following values: // mm0 = L2P (or L2) // mm1 = L1 // mm2 = L2 (or L2P) // mm3 = L3 // mm4 = the best of L2,L2P weave pixel, base upon comb // mm6 = the avg interpolated value, if we need to use it // Let's measure movement, as how much the weave pixel has changed "movq %%mm2, %%mm7\n\t" "psubusb %%mm0, %%mm2\n\t" "psubusb %%mm7, %%mm0\n\t" "por %%mm2, %%mm0\n\t" // abs value of change, used later // Now lets clip our chosen value to be not outside of the range // of the high/low range L1-L3 by more than MaxComb. // This allows some comb but limits the damages and also allows more // detail than a boring oversmoothed clip. "movq %%mm1, %%mm2\n\t" // copy L1 // pmaxub mm2, mm3 // use macro V_PMAXUB ("%%mm2", "%%mm3") // now = Max(L1,L3) "movq %%mm1, %%mm5\n\t" // copy L1 // pminub mm5, mm3 // now = Min(L1,L3), use macro V_PMINUB ("%%mm5", "%%mm3", "%%mm7") // allow the value to be above the high or below the low by amt of MaxComb "psubusb %9, %%mm5\n\t" // lower min by diff "paddusb %9, %%mm2\n\t" // increase max by diff // pmaxub mm4, mm5 // now = Max(best,Min(L1,L3) use macro V_PMAXUB ("%%mm4", "%%mm5") // pminub mm4, mm2 // now = Min( Max(best, Min(L1,L3), L2 )=L2 clipped V_PMINUB ("%%mm4", "%%mm2", "%%mm7") // Blend weave pixel with bob pixel, depending on motion val in mm0 "psubusb %10, %%mm0\n\t"// test Threshold, clear chroma change >>>?? "pmullw %11, %%mm0\n\t" // mul by user factor, keep low 16 bits "movq %12, %%mm7\n\t" #ifdef IS_SSE "pminsw %%mm7, %%mm0\n\t" // max = 256 #else "paddusw %13, %%mm0\n\t" // add, may sat at fff.. "psubusw %13, %%mm0\n\t" // now = Min(L1,256) #endif "psubusw %%mm0, %%mm7\n\t" // so the 2 sum to 256, weighted avg "movq %%mm4, %%mm2\n\t" // save weave chroma info before trashing "pand %14, %%mm4\n\t" // keep only luma from calc'd value "pmullw %%mm7, %%mm4\n\t" // use more weave for less motion "pand %14, %%mm6\n\t" // keep only luma from calc'd value "pmullw %%mm0, %%mm6\n\t" // use more bob for large motion "paddusw %%mm6, %%mm4\n\t" // combine "psrlw $8, %%mm4\n\t" // div by 256 to get weighted avg // chroma comes from weave pixel "pand %15, %%mm2\n\t" // keep chroma "por %%mm4, %%mm2\n\t" // and combine V_MOVNTQ (MEMREF1("di"), "%%mm2") // move in our clipped best, use macro // bump ptrs and loop BUMPPTR ("8", "ax", "ax") BUMPPTR ("8", "dx", "dx") CONSTMEM ("add", "8", asmtemp) BUMPPTR ("8", "di", "di") BUMPPTR ("8", "si", "si") CONSTMEM ("sub", "1", asmLoopCtr) "jg 1b\n\t" // loop if not to last line // note P-III default assumes backward branches taken "jl 1f\n\t" // done REG2 ("mov", "ax", "dx") // sharpness lookahead 1 byte only, be wrong on 1 "jmp 1b\n\t" "1:\n\t" : /* no outputs */ : "m"(LastAvg), "m"(L1), "m"(L3), "m"(temp), "m"(L2), "m"(Dest), "m"(LoopCtr), "m"(temp), "m"(ShiftMask), "m"(MaxComb), "m"(MotionThreshold), "m"(MotionSense), "m"(QW256), "m"(QW256B), "m"(YMask), "m"(UVMask) : #if defined(ARCH_X86_X32) || defined(ARCH_X86_64) "rax", "rcx", "rdx", "rsi", "rdi", /* the following clobber list causes trouble for gcc 2.95. it shouldn't be * an issue as, afaik, mmx registers map to the existing fp registers. */ "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", #elif defined(ARCH_X86) "eax", "ecx", "edx", "esi", "edi", "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", #endif "memory", "cc" ); Dest += outstride; xine_fast_memcpy(Dest, L3, stride); Dest += outstride; L1 += Pitch; L2 += Pitch; L3 += Pitch; L2P += Pitch; } if (InfoIsOdd) { xine_fast_memcpy(Dest, L2, stride); } // clear out the MMX registers ready for doing floating point again #if defined(ARCH_X86) __asm__ __volatile__ ("emms\n\t"); #endif } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/greedy.c��������������������������������������������������0000644�0001750�0001750�00000015370�14647725152�020031� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2000 Tom Barry All rights reserved. * mmx.h port copyright (c) 2002 Billy Biggs <vektor@dumbterm.net>. * * This code is ported from DScaler: http://deinterlace.sf.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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include <xine/attributes.h> #include <xine/xineutils.h> #include "xine_mmx.h" #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" #include "plugins.h" // This is a simple lightweight DeInterlace method that uses little CPU time // but gives very good results for low or intermedite motion. // It defers frames by one field, but that does not seem to produce noticeable // lip sync problems. // // The method used is to take either the older or newer weave pixel depending // upon which give the smaller comb factor, and then clip to avoid large damage // when wrong. // // I'd intended this to be part of a larger more elaborate method added to // Blended Clip but this give too good results for the CPU to ignore here. static void copy_scanline( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { blit_packed422_scanline( output, data->m1, width ); } static void deinterlace_greedy_packed422_scanline_mmxext( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { #if defined(ARCH_X86) const uint8_t GreedyMaxComb = 15; mmx_t MaxComb; uint8_t *m0 = data->m0; uint8_t *t1 = data->t1; uint8_t *b1 = data->b1; uint8_t *m2 = data->m2; // How badly do we let it weave? 0-255 MaxComb.ub[ 0 ] = GreedyMaxComb; MaxComb.ub[ 1 ] = GreedyMaxComb; MaxComb.ub[ 2 ] = GreedyMaxComb; MaxComb.ub[ 3 ] = GreedyMaxComb; MaxComb.ub[ 4 ] = GreedyMaxComb; MaxComb.ub[ 5 ] = GreedyMaxComb; MaxComb.ub[ 6 ] = GreedyMaxComb; MaxComb.ub[ 7 ] = GreedyMaxComb; // L2 == m0 // L1 == t1 // L3 == b1 // LP2 == m2 width /= 4; while( width-- ) { movq_m2r( *t1, mm1 ); // L1 movq_m2r( *m0, mm2 ); // L2 movq_m2r( *b1, mm3 ); // L3 movq_m2r( *m2, mm0 ); // LP2 // average L1 and L3 leave result in mm4 movq_r2r( mm1, mm4 ); // L1 pavgb_r2r( mm3, mm4 ); // (L1 + L3)/2 // get abs value of possible L2 comb movq_r2r( mm2, mm7 ); // L2 psubusb_r2r( mm4, mm7 ); // L2 - avg movq_r2r( mm4, mm5 ); // avg psubusb_r2r( mm2, mm5 ); // avg - L2 por_r2r( mm7, mm5 ); // abs(avg-L2) movq_r2r( mm4, mm6 ); // copy of avg for later // get abs value of possible LP2 comb movq_r2r( mm0, mm7 ); // LP2 psubusb_r2r( mm4, mm7 ); // LP2 - avg psubusb_r2r( mm0, mm4 ); // avg - LP2 por_r2r( mm7, mm4 ); // abs(avg-LP2) // use L2 or LP2 depending upon which makes smaller comb psubusb_r2r( mm5, mm4 ); // see if it goes to zero psubusb_r2r( mm5, mm5 ); // 0 pcmpeqb_r2r( mm5, mm4 ); // if (mm4=0) then FF else 0 pcmpeqb_r2r( mm4, mm5 ); // opposite of mm4 // if Comb(LP2) <= Comb(L2) then mm4=ff, mm5=0 else mm4=0, mm5 = 55 pand_r2r( mm2, mm5 ); // use L2 if mm5 == ff, else 0 pand_r2r( mm0, mm4 ); // use LP2 if mm4 = ff, else 0 por_r2r( mm5, mm4 ); // may the best win // Now lets clip our chosen value to be not outside of the range // of the high/low range L1-L3 by more than abs(L1-L3) // This allows some comb but limits the damages and also allows more // detail than a boring oversmoothed clip. movq_r2r( mm1, mm2 ); // copy L1 psubusb_r2r( mm3, mm2 ); // - L3, with saturation paddusb_r2r( mm3, mm2 ); // now = Max(L1,L3) pcmpeqb_r2r( mm7, mm7 ); // all ffffffff psubusb_r2r( mm1, mm7 ); // - L1 paddusb_r2r( mm7, mm3 ); // add, may sat at fff.. psubusb_r2r( mm7, mm3 ); // now = Min(L1,L3) // allow the value to be above the high or below the low by amt of MaxComb paddusb_m2r( MaxComb, mm2 ); // increase max by diff psubusb_m2r( MaxComb, mm3 ); // lower min by diff psubusb_r2r( mm3, mm4 ); // best - Min paddusb_r2r( mm3, mm4 ); // now = Max(best,Min(L1,L3) pcmpeqb_r2r( mm7, mm7 ); // all ffffffff psubusb_r2r( mm4, mm7 ); // - Max(best,Min(best,L3) paddusb_r2r( mm7, mm2 ); // add may sat at FFF.. psubusb_r2r( mm7, mm2 ); // now = Min( Max(best, Min(L1,L3), L2 )=L2 clipped movntq_r2m( mm2, *output ); // move in our clipped best // Advance to the next set of pixels. output += 8; m0 += 8; t1 += 8; b1 += 8; m2 += 8; } sfence(); emms(); #endif } /** * The greedy deinterlacer introduces a one-field delay on the input. * From the diagrams in deinterlace.h, the field being deinterlaced is * always t-1. For this reason, our copy_scanline method is used for * deinterlace_method_t's interpolate_scanline function, and the real * work is done in deinterlace_method_t's copy_scanline function. */ static const deinterlace_method_t greedymethod = { "Greedy - Low motion (DScaler)", "Greedy", /* "Motion Adaptive: Simple Detection", "AdaptiveSimple", */ 3, MM_ACCEL_X86_MMXEXT, 0, 1, copy_scanline, deinterlace_greedy_packed422_scanline_mmxext, 0, 1, "Uses heuristics to detect motion in the input frames and reconstruct " "image detail where possible. Use this for high quality output even " "on monitors set to an arbitrary refresh rate.\n" "\n" "Simple detection uses linear interpolation where motion is detected, " "using a two-field buffer. This is the Greedy: Low Motion deinterlacer " "from DScaler." }; const deinterlace_method_t *greedy_get_method( void ) { return &greedymethod; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/vfir.c����������������������������������������������������0000644�0001750�0001750�00000010361�14647725152�017513� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * This file contains code from ffmpeg, see http://ffmpeg.org/ * * Originated in imgconvert.c: Misc image convertion routines * Copyright (c) 2001, 2002, 2003 Fabrice Bellard. * * tvtime port Copyright (C) 2003 Billy Biggs <vektor@dumbterm.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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include <xine/attributes.h> #include <xine/xineutils.h> #include "xine_mmx.h" #include "speedy.h" #include "deinterlace.h" #include "plugins.h" /** * The MPEG2 spec uses a slightly harsher filter, they specify * [-1 8 2 8 -1]. ffmpeg uses a similar filter but with more of * a tendancy to blur than to use the local information. The * filter taps here are: [-1 4 2 4 -1]. */ static void deinterlace_line( uint8_t *dst, uint8_t *lum_m4, uint8_t *lum_m3, uint8_t *lum_m2, uint8_t *lum_m1, uint8_t *lum, int size ) { #if defined(ARCH_X86) mmx_t rounder; rounder.uw[0]=4; rounder.uw[1]=4; rounder.uw[2]=4; rounder.uw[3]=4; pxor_r2r(mm7,mm7); movq_m2r(rounder,mm6); for (;size > 3; size-=4) { movd_m2r(lum_m4[0],mm0); movd_m2r(lum_m3[0],mm1); movd_m2r(lum_m2[0],mm2); movd_m2r(lum_m1[0],mm3); movd_m2r(lum[0],mm4); punpcklbw_r2r(mm7,mm0); punpcklbw_r2r(mm7,mm1); punpcklbw_r2r(mm7,mm2); punpcklbw_r2r(mm7,mm3); punpcklbw_r2r(mm7,mm4); paddw_r2r(mm3,mm1); psllw_i2r(1,mm2); paddw_r2r(mm4,mm0); psllw_i2r(2,mm1);// 2 paddw_r2r(mm6,mm2); paddw_r2r(mm2,mm1); psubusw_r2r(mm0,mm1); psrlw_i2r(3,mm1); // 3 packuswb_r2r(mm7,mm1); movd_r2m(mm1,dst[0]); lum_m4+=4; lum_m3+=4; lum_m2+=4; lum_m1+=4; lum+=4; dst+=4; } emms(); #else /** * C implementation. */ int sum; for(;size > 0;size--) { sum = -lum_m4[0]; sum += lum_m3[0] << 2; sum += lum_m2[0] << 1; sum += lum_m1[0] << 2; sum += -lum[0]; dst[0] = (sum + 4) >> 3; // This needs to be clipped at 0 and 255: cm[(sum + 4) >> 3]; lum_m4++; lum_m3++; lum_m2++; lum_m1++; lum++; dst++; } #endif } static void deinterlace_scanline_vfir( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { deinterlace_line( output, data->tt1, data->t0, data->m1, data->b0, data->bb1, width*2 ); } static void copy_scanline( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { blit_packed422_scanline( output, data->m0, width ); } static const deinterlace_method_t vfirmethod = { "Vertical Blend (ffmpeg)", "Vertical", /* "Blur: Vertical", "BlurVertical", */ 1, #if defined(ARCH_X86) MM_ACCEL_X86_MMXEXT, #else 0, #endif 0, 1, deinterlace_scanline_vfir, copy_scanline, 0, 0, "Avoids flicker by blurring consecutive frames of input. Use this if you " "want to run your monitor at an arbitrary refresh rate and not use much " "CPU, and are willing to sacrifice detail.\n" "\n" "Vertical mode blurs favouring the most recent field for less visible " "trails. From the deinterlacer filter in ffmpeg." }; const deinterlace_method_t *vfir_get_method( void ) { return &vfirmethod; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/greedy2frame_template_sse2.c������������������������������0000644�0001750�0001750�00000024156�14647725152�023757� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/***************************************************************************** ** Copyright (c) 2000 John Adcock, Tom Barry, Steve Grimm All rights reserved. ** port copyright (c) 2003 Miguel Freitas ****************************************************************************** ** ** This file is subject to the terms of the GNU General Public License as ** published by the Free Software Foundation. A copy of this license is ** included with this software distribution in the file COPYING. If you ** do not have a copy, you may obtain a copy by writing to the Free ** Software Foundation, 51 Franklin St, Fifth Floor, Boston, MA ** 02110-1301, USA. ** ** This software is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details ****************************************************************************** ** CVS Log ** ** Revision 1.10 2006/12/21 09:54:45 dgp85 ** Apply the textrel patch from Gentoo, thanks to PaX team for providing it. The patch was applied and tested for a while in Gentoo and Pardus, and solves also Debian's problems with non-PIC code. If problems will arise, they'll be debugged. ** ** Revision 1.9 2006/02/04 14:06:29 miguelfreitas ** Enable AMD64 mmx/sse support in some plugins (tvtime, libmpeg2, goom...) ** patch by dani3l ** ** Revision 1.8 2005/06/05 16:00:06 miguelfreitas ** quite some hacks for gcc 2.95 compatibility ** ** Revision 1.7 2004/04/09 02:57:06 miguelfreitas ** tvtime deinterlacing algorithms assumed top_field_first=1 ** top_field_first=0 (aka bottom_field_first) should now work as expected ** ** Revision 1.6 2004/02/12 20:53:31 mroi ** my gcc (partly 3.4 already) optimizes these away, because they are only used ** inside inline assembler (which the compiler does not recognize); so actually ** the code is wrong (the asm parts should list these as inputs), but telling ** the compiler to keep them is the easier fix ** ** Revision 1.5 2004/01/05 12:15:55 siggi ** wonder why Mike isn't complaining about C++ style comments, any more... ** ** Revision 1.4 2004/01/05 01:47:26 tmmm ** DOS/Win CRs are forbidden, verboten, interdit ** ** Revision 1.3 2004/01/02 20:53:43 miguelfreitas ** better MANGLE from ffmpeg ** ** Revision 1.2 2004/01/02 20:47:03 miguelfreitas ** my small contribution to the cygwin port ;-) ** ** Revision 1.1 2003/06/22 17:30:03 miguelfreitas ** use our own port of greedy2frame (tvtime port is currently broken) ** ** Revision 1.8 2001/11/23 17:18:54 adcockj ** Fixed silly and/or confusion ** ** Revision 1.7 2001/11/22 22:27:00 adcockj ** Bug Fixes ** ** Revision 1.6 2001/11/21 15:21:40 adcockj ** Renamed DEINTERLACE_INFO to TDeinterlaceInfo in line with standards ** Changed TDeinterlaceInfo structure to have history of pictures. ** ** Revision 1.5 2001/07/31 06:48:33 adcockj ** Fixed index bug spotted by Peter Gubanov ** ** Revision 1.4 2001/07/13 16:13:33 adcockj ** Added CVS tags and removed tabs ** *****************************************************************************/ /* * This is the implementation of the Greedy 2-frame deinterlace algorithm * described in DI_Greedy2Frame.c. It's in a separate file so we can compile * variants for different CPU types; most of the code is the same in the * different variants. */ /**************************************************************************** ** Field 1 | Field 2 | Field 3 | Field 4 | ** T0 | | T1 | | ** | M0 | | M1 | ** B0 | | B1 | | */ #if defined(ARCH_X86) static const sse_t Mask128 = { .uq = { 0x7f7f7f7f7f7f7f7fll, 0x7f7f7f7f7f7f7f7fll} }; #define TP GREEDYTWOFRAMETHRESHOLD, GREEDYTWOFRAMETHRESHOLD2 static const sse_t GreedyTwoFrameThreshold128 = { .ub = {TP, TP, TP, TP, TP, TP, TP, TP} }; #undef TP #endif static void DeinterlaceGreedy2Frame_SSE2(uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) { #if defined(ARCH_X86) int Line; int stride = width * 2; register uint8_t* M1; register uint8_t* M0; register uint8_t* T1; register uint8_t* T0; uint8_t* Dest = output; register uint8_t* Dest2; register uint8_t* Destc; register int count; uint32_t Pitch = stride * 2; uint32_t LineLength = stride; uint32_t PitchRest = Pitch - (LineLength >> 4)*16; if( second_field ) { M1 = data->f0; T1 = data->f0; M0 = data->f1; T0 = data->f1; } else { M1 = data->f0; T1 = data->f1; M0 = data->f1; T0 = data->f2; } if( bottom_field ) { M1 += stride; T1 += 0; M0 += stride; T0 += 0; } else { M1 += Pitch; T1 += stride; M0 += Pitch; T0 += stride; xine_fast_memcpy(Dest, M1, LineLength); Dest += outstride; } for (Line = 0; Line < (height / 2) - 1; ++Line) { /* Always use the most recent data verbatim. By definition it's correct * (it'd be shown on an interlaced display) and our job is to fill in * the spaces between the new lines. */ /* xine_fast_memcpy would be pretty pointless here as we load the same * data anyway it's just one additional mov per loop... * XXX I believe some cpus with sse2 (early A64?) only have one write * buffer. Using movntdq with 2 different streams may have quite * bad performance consequences on such cpus. */ Destc = Dest; Dest += outstride; Dest2 = Dest; /* just rely on gcc not using xmm regs... */ do { __asm__ __volatile__( "movdqa %0, %%xmm6 \n\t" // xmm6 = Mask "pxor %%xmm7, %%xmm7 \n\t" // xmm7 = zero : /* no output */ : "m" (Mask128) ); } while (0); count = LineLength >> 4; do { __asm__ __volatile__( /* Figure out what to do with the scanline above the one we copy. * See above for a description of the algorithm. * weave if (weave(M) AND (weave(T) OR weave(B))) */ "movdqa (%2), %%xmm1 \n\t" /* xmm1 = T1 */ "movdqa (%3), %%xmm0 \n\t" /* xmm0 = T0 */ "movdqa (%4,%2), %%xmm3 \n\t" /* xmm3 = B1 */ "movdqa (%4,%3), %%xmm2 \n\t" /* xmm2 = B0 */ /* calculate |T1-T0| keep T1 put result in xmm5 */ "movdqa %%xmm1, %%xmm5 \n\t" "psubusb %%xmm0, %%xmm5 \n\t" "psubusb %%xmm1, %%xmm0 \n\t" "por %%xmm0, %%xmm5 \n\t" /* T1 is data for line to copy */ "movntdq %%xmm1, %1 \n\t" /* if |T1-T0| > Threshold we want 0 else dword minus one */ "psrlw $1, %%xmm5 \n\t" "pand %%xmm6, %%xmm5 \n\t" "pcmpgtb %0, %%xmm5 \n\t" "pcmpeqd %%xmm7, %%xmm5 \n\t" "prefetcht0 64(%4,%2) \n\t" "prefetcht0 64(%4,%3) \n\t" : : "m" (GreedyTwoFrameThreshold128), "m" (*Destc), "r" (T1), "r" (T0), "r" ((void*)(intptr_t)Pitch) ); __asm__ __volatile__ ( /* calculate |B1-B0| keep B1 put result in xmm4 */ "movdqa %%xmm3, %%xmm4 \n\t" "psubusb %%xmm2, %%xmm4 \n\t" "psubusb %%xmm3, %%xmm2 \n\t" "por %%xmm2, %%xmm4 \n\t" "movdqa (%0), %%xmm0 \n\t" /* xmm0 = M1 */ "movdqa (%1), %%xmm2 \n\t" /* xmm2 = M0 */ /* if |B1-B0| > Threshold we want 0 else dword minus one */ "psrlw $1, %%xmm4 \n\t" "pand %%xmm6, %%xmm4 \n\t" "pcmpgtb %2, %%xmm4 \n\t" "pcmpeqd %%xmm7, %%xmm4 \n\t" "por %%xmm4, %%xmm5 \n\t" /* Average T1 and B1 so we can do interpolated bobbing if we bob * onto T1 */ "pavgb %%xmm3, %%xmm1 \n\t" /* xmm1 = avg(T1,B1) */ "prefetcht0 64(%0) \n\t" "prefetcht0 64(%1) \n\t" /* make mm0 the average of M1 and M0 which should make weave * look better when there is small amounts of movement */ "movdqa %%xmm2, %%xmm3 \n\t" "pavgb %%xmm0, %%xmm3 \n\t" /* xmm3 = avg(M1,M0) */ /* calculate |M1-M0| put result in xmm4 */ "movdqa %%xmm0, %%xmm4 \n\t" "psubusb %%xmm2, %%xmm4 \n\t" "psubusb %%xmm0, %%xmm2 \n\t" "por %%xmm2, %%xmm4 \n\t" /* if |M1-M0| > Threshold we want 0 else dword minus one */ "psrlw $1, %%xmm4 \n\t" "pand %%xmm6, %%xmm4 \n\t" "pcmpgtb %2, %%xmm4 \n\t" "pcmpeqd %%xmm7, %%xmm4 \n\t" /* do we want to bob */ "pand %%xmm5, %%xmm4 \n\t" /* debugging feature * output the value of xmm4 at this point which is pink where we will weave * and green where we are going to bob */ #ifdef CHECK_BOBWEAVE "movntdq %%xmm4, %3 \n\t" #else /* xmm4 now is 1 where we want to weave and 0 where we want to bob */ "pand %%xmm4, %%xmm3 \n\t" "pandn %%xmm1, %%xmm4 \n\t" "por %%xmm3, %%xmm4 \n\t" "movntdq %%xmm4, %3 \n\t" #endif : : "r" (M1), "r" (M0), "m" (GreedyTwoFrameThreshold128), "m" (*Dest2)); /* Advance to the next set of pixels. */ T1 += 16; M1 += 16; M0 += 16; T0 += 16; Dest2 += 16; Destc += 16; } while( --count ); Dest += outstride; M1 += PitchRest; T1 += PitchRest; M0 += PitchRest; T0 += PitchRest; } __asm__ __volatile__("sfence\n\t"); if( bottom_field ) { xine_fast_memcpy(Dest, T1, stride); Dest += outstride; xine_fast_memcpy(Dest, M1, stride); } else { xine_fast_memcpy(Dest, T1, stride); } #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/x86-64_macros.inc�����������������������������������������0000644�0001750�0001750�00000004703�14647725152�021317� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2017 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. * * Helper macros to size x86 memory locations and hardcoded registers properly. * Registers may be: "ax" "bx" "cx" "dx" "si" "di" "bp" "sp". */ //#ifdef HAVE_CONFIG_H //# include "config.h" //#endif #ifndef MEMREF1 /* register only stuff */ #if defined(ARCH_X86_64) || defined(ARCH_X86_X32) # define BUMPPTR(offs,src,dest) "leaq "offs"(%%r"src"), %%r"dest"\n\t" # define REG1(what,reg) what"q %%r"reg"\n\t" # define REG2(what,reg1,reg2) what"q %%r"reg1", %%r"reg2"\n\t" # define MEMREF1(reg) "(%%r"reg")" # define MEMREF2(base,offs) "(%%r"base", %%r"offs")" # define MEMREF3(base,index,mult) "(%%r"base", %%r"index", "mult")" #elif defined(ARCH_X86) # define BUMPPTR(offs,src,dest) "leal "offs"(%%e"src"), %%e"dest"\n\t" # define REG1(what,reg) what"l %%e"reg"\n\t" # define REG2(what,reg1,reg2) what"l %%e"reg1", %%e"reg2"\n\t" # define MEMREF1(reg) "(%%e"reg")" # define MEMREF2(base,offs) "(%%e"base", %%e"offs")" # define MEMREF3(base,index,mult) "(%%e"base", %%e"index", "mult")" #endif /* memory location or constant + register */ #if defined(ARCH_X86_64) # define MEMREG(what,addr,reg) what"q "addr", %%r"reg"\n\t" # define REGMEM(what,reg,addr) what"q %%r"reg", "addr"\n\t" # define CONSTMEM(what,val,addr) what"q $"val", "addr"\n\t" #elif defined(ARCH_X86_X32) || defined (ARCH_X86) # define MEMREG(what,addr,reg) what"l "addr", %%e"reg"\n\t" # define REGMEM(what,reg,addr) what"l %%e"reg", "addr"\n\t" # define CONSTMEM(what,val,addr) what"l $"val", "addr"\n\t" #endif #ifndef MEMREF1 # error Undefined architecture. Define either ARCH_X86, ARCH_X86_X32 or ARCH_X86_64. #endif #endif �������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/linearblend.c���������������������������������������������0000644�0001750�0001750�00000022244�14647725152�021027� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Linear blend deinterlacing plugin. The idea for this algorithm came * from the linear blend deinterlacer which originated in the mplayer * sources. * * 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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include <xine/attributes.h> #include <xine/xineutils.h> #include "xine_mmx.h" #include "speedtools.h" #include "speedy.h" #include "deinterlace.h" #include "plugins.h" static const char linearblendmethod_help[] = "Avoids flicker by blurring consecutive frames of input. Use this if " "you want to run your monitor at an arbitrary refresh rate and not use " "much CPU, and are willing to sacrifice detail.\n" "\n" "Temporal mode evenly blurs content for least flicker, but with visible " "trails on fast motion. From the linear blend deinterlacer in mplayer."; static void deinterlace_scanline_linear_blend( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { uint8_t *t0 = data->t0; uint8_t *b0 = data->b0; uint8_t *m1 = data->m1; #if defined(ARCH_X86) int i; // Get width in bytes. width *= 2; i = width / 8; width -= i * 8; pxor_r2r( mm7, mm7 ); while( i-- ) { movd_m2r( *t0, mm0 ); movd_m2r( *b0, mm1 ); movd_m2r( *m1, mm2 ); movd_m2r( *(t0+4), mm3 ); movd_m2r( *(b0+4), mm4 ); movd_m2r( *(m1+4), mm5 ); punpcklbw_r2r( mm7, mm0 ); punpcklbw_r2r( mm7, mm1 ); punpcklbw_r2r( mm7, mm2 ); punpcklbw_r2r( mm7, mm3 ); punpcklbw_r2r( mm7, mm4 ); punpcklbw_r2r( mm7, mm5 ); psllw_i2r( 1, mm2 ); psllw_i2r( 1, mm5 ); paddw_r2r( mm0, mm2 ); paddw_r2r( mm3, mm5 ); paddw_r2r( mm1, mm2 ); paddw_r2r( mm4, mm5 ); psrlw_i2r( 2, mm2 ); psrlw_i2r( 2, mm5 ); packuswb_r2r( mm2, mm2 ); packuswb_r2r( mm5, mm5 ); movd_r2m( mm2, *output ); movd_r2m( mm5, *(output+4) ); output += 8; t0 += 8; b0 += 8; m1 += 8; } while( width-- ) { *output++ = (*t0++ + *b0++ + (*m1++ << 1)) >> 2; } emms(); #else width *= 2; while( width-- ) { *output++ = (*t0++ + *b0++ + (*m1++ << 1)) >> 2; } #endif } static void deinterlace_scanline_linear_blend2( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { uint8_t *m0 = data->m0; uint8_t *t1 = data->t1; uint8_t *b1 = data->b1; #if defined(ARCH_X86) int i; // Get width in bytes. width *= 2; i = width / 8; width -= i * 8; pxor_r2r( mm7, mm7 ); while( i-- ) { movd_m2r( *t1, mm0 ); movd_m2r( *b1, mm1 ); movd_m2r( *m0, mm2 ); movd_m2r( *(t1+4), mm3 ); movd_m2r( *(b1+4), mm4 ); movd_m2r( *(m0+4), mm5 ); punpcklbw_r2r( mm7, mm0 ); punpcklbw_r2r( mm7, mm1 ); punpcklbw_r2r( mm7, mm2 ); punpcklbw_r2r( mm7, mm3 ); punpcklbw_r2r( mm7, mm4 ); punpcklbw_r2r( mm7, mm5 ); psllw_i2r( 1, mm2 ); psllw_i2r( 1, mm5 ); paddw_r2r( mm0, mm2 ); paddw_r2r( mm3, mm5 ); paddw_r2r( mm1, mm2 ); paddw_r2r( mm4, mm5 ); psrlw_i2r( 2, mm2 ); psrlw_i2r( 2, mm5 ); packuswb_r2r( mm2, mm2 ); packuswb_r2r( mm5, mm5 ); movd_r2m( mm2, *output ); movd_r2m( mm5, *(output+4) ); output += 8; t1 += 8; b1 += 8; m0 += 8; } while( width-- ) { *output++ = (*t1++ + *b1++ + (*m0++ << 1)) >> 2; } emms(); #else width *= 2; while( width-- ) { *output++ = (*t1++ + *b1++ + (*m0++ << 1)) >> 2; } #endif } #if defined(ARCH_X86) /* MMXEXT version is about 15% faster with Athlon XP [MF] */ static void deinterlace_scanline_linear_blend_mmxext( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { uint8_t *t0 = data->t0; uint8_t *b0 = data->b0; uint8_t *m1 = data->m1; int i; static mmx_t high_mask = { .ub = {0xff,0xff,0xff,0xff,0,0,0,0}}; if (data->bytes_left >= 2048) { READ_PREFETCH_2048 (t0); READ_PREFETCH_2048 (b0); READ_PREFETCH_2048 (m1); } // Get width in bytes. width *= 2; i = width / 8; width -= i * 8; movd_m2r( high_mask, mm6 ); pxor_r2r( mm7, mm7 ); while( i-- ) { movd_m2r( *t0, mm0 ); movd_m2r( *b0, mm1 ); movd_m2r( *m1, mm2 ); movd_m2r( *(t0+4), mm3 ); movd_m2r( *(b0+4), mm4 ); movd_m2r( *(m1+4), mm5 ); punpcklbw_r2r( mm7, mm0 ); punpcklbw_r2r( mm7, mm1 ); punpcklbw_r2r( mm7, mm2 ); punpcklbw_r2r( mm7, mm3 ); punpcklbw_r2r( mm7, mm4 ); punpcklbw_r2r( mm7, mm5 ); psllw_i2r( 1, mm2 ); psllw_i2r( 1, mm5 ); paddw_r2r( mm0, mm2 ); paddw_r2r( mm3, mm5 ); paddw_r2r( mm1, mm2 ); paddw_r2r( mm4, mm5 ); psrlw_i2r( 2, mm2 ); psrlw_i2r( 2, mm5 ); packuswb_r2r( mm2, mm2 ); packuswb_r2r( mm5, mm5 ); psllq_i2r( 32, mm5 ); pand_r2r( mm6, mm2 ); por_r2r( mm2, mm5 ); movntq_r2m( mm5, *output ); output += 8; t0 += 8; b0 += 8; m1 += 8; } while( width-- ) { *output++ = (*t0++ + *b0++ + (*m1++ << 1)) >> 2; } sfence(); emms(); } static void deinterlace_scanline_linear_blend2_mmxext( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { uint8_t *m0 = data->m0; uint8_t *t1 = data->t1; uint8_t *b1 = data->b1; int i; if (data->bytes_left >= 2048) { READ_PREFETCH_2048 (t1); READ_PREFETCH_2048 (b1); READ_PREFETCH_2048 (m0); } // Get width in bytes. width *= 2; i = width / 8; width -= i * 8; pxor_r2r( mm7, mm7 ); while( i-- ) { movd_m2r( *t1, mm0 ); movd_m2r( *b1, mm1 ); movd_m2r( *m0, mm2 ); movd_m2r( *(t1+4), mm3 ); movd_m2r( *(b1+4), mm4 ); movd_m2r( *(m0+4), mm5 ); punpcklbw_r2r( mm7, mm0 ); punpcklbw_r2r( mm7, mm1 ); punpcklbw_r2r( mm7, mm2 ); punpcklbw_r2r( mm7, mm3 ); punpcklbw_r2r( mm7, mm4 ); punpcklbw_r2r( mm7, mm5 ); psllw_i2r( 1, mm2 ); psllw_i2r( 1, mm5 ); paddw_r2r( mm0, mm2 ); paddw_r2r( mm3, mm5 ); paddw_r2r( mm1, mm2 ); paddw_r2r( mm4, mm5 ); psrlw_i2r( 2, mm2 ); psrlw_i2r( 2, mm5 ); packuswb_r2r( mm2, mm2 ); packuswb_r2r( mm5, mm5 ); psllq_i2r( 32, mm5 ); pand_r2r( mm6, mm2 ); por_r2r( mm2, mm5 ); movntq_r2m( mm5, *output ); output += 8; t1 += 8; b1 += 8; m0 += 8; } while( width-- ) { *output++ = (*t1++ + *b1++ + (*m0++ << 1)) >> 2; } sfence(); emms(); } static deinterlace_method_t linearblendmethod_mmxext = { .name = "Linear Blend (mplayer)", .short_name = "LinearBlend", .fields_required = 2, .accelrequired = MM_ACCEL_X86_MMXEXT, .doscalerbob = 0, .scanlinemode = 1, .interpolate_scanline = deinterlace_scanline_linear_blend_mmxext, .copy_scanline = deinterlace_scanline_linear_blend2_mmxext, .deinterlace_frame = 0, .delaysfield = 0, .description = linearblendmethod_help }; #endif static const deinterlace_method_t linearblendmethod = { .name = "Linear Blend (mplayer)", .short_name = "LinearBlend", /* "Blur: Temporal", "BlurTemporal", */ .fields_required = 2, #if defined(ARCH_X86) .accelrequired = MM_ACCEL_X86_MMX, #else .accelrequired = 0, #endif .doscalerbob = 0, .scanlinemode = 1, .interpolate_scanline = deinterlace_scanline_linear_blend, .copy_scanline = deinterlace_scanline_linear_blend2, .deinterlace_frame = 0, .delaysfield = 0, .description = linearblendmethod_help }; const deinterlace_method_t *linearblend_get_method( void ) { #if defined(ARCH_X86) if( xine_mm_accel() & MM_ACCEL_X86_MMXEXT ) return &linearblendmethod_mmxext; else #endif return &linearblendmethod; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/linear.c��������������������������������������������������0000644�0001750�0001750�00000004163�14647725152�020022� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "speedy.h" #include "deinterlace.h" #include "plugins.h" static void deinterlace_scanline_linear( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { interpolate_packed422_scanline( output, data->t0, data->b0, width ); } static void copy_scanline( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { blit_packed422_scanline( output, data->m0, width ); } static const deinterlace_method_t linearmethod = { "Linear Interpolation", "Linear", /* "Television: Full resolution", "TelevisionFull", */ 1, 0, 0, 1, deinterlace_scanline_linear, copy_scanline, 0, 0, "Expands each field independently without blurring or copying in time. " "Use this if you want TV-quality with low CPU, and you have configured " "your monitor to run at the refresh rate of the video signal.\n" "\n" "Full resolution mode expands each field to full size for high quality " "fullscreen use." }; const deinterlace_method_t *linear_get_method( void ) { return &linearmethod; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/plugins.h�������������������������������������������������0000644�0001750�0001750�00000003571�14647725152�020240� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (C) 2002, 2004 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifndef TVTIME_PLUGINS_H_INCLUDED #define TVTIME_PLUGINS_H_INCLUDED /** * tvtime was going to have a plugin system, but there * was never any interest in it outside of tvtime, so instead * we include all deinterlacer methods right in the tvtime * executable. */ #include <deinterlace.h> const deinterlace_method_t *greedy_get_method( void ); const deinterlace_method_t *greedy2frame_get_method( void ); const deinterlace_method_t *weave_get_method( void ); const deinterlace_method_t *double_get_method( void ); const deinterlace_method_t *linear_get_method( void ); const deinterlace_method_t *scalerbob_get_method( void ); const deinterlace_method_t *linearblend_get_method( void ); const deinterlace_method_t *vfir_get_method( void ); const deinterlace_method_t *dscaler_tomsmocomp_get_method( void ); const deinterlace_method_t *dscaler_greedyh_get_method( void ); const deinterlace_method_t *greedy_get_method( void ); const deinterlace_method_t *weave_get_method( void ); const deinterlace_method_t *weavetff_get_method( void ); const deinterlace_method_t *weavebff_get_method( void ); #endif /* TVTIME_PLUGINS_H_INCLUDED */ ���������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/weave.c���������������������������������������������������0000644�0001750�0001750�00000003434�14647725152�017657� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Pure weave deinterlacing plugin. * * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "speedy.h" #include "deinterlace.h" #include "plugins.h" static void deinterlace_scanline_weave( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { blit_packed422_scanline( output, data->m1, width ); } static void copy_scanline( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { blit_packed422_scanline( output, data->m0, width ); } static const deinterlace_method_t weavemethod = { "Weave Last Field", "Weave", 2, 0, 0, 1, deinterlace_scanline_weave, copy_scanline, 0, 0, "Only updates the most recent field." }; const deinterlace_method_t *weave_get_method( void ) { return &weavemethod; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/greedy2frame_template.c�����������������������������������0000644�0001750�0001750�00000026426�14647725152�023025� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/***************************************************************************** ** Copyright (c) 2000 John Adcock, Tom Barry, Steve Grimm All rights reserved. ** port copyright (c) 2003 Miguel Freitas ****************************************************************************** ** ** This file is subject to the terms of the GNU General Public License as ** published by the Free Software Foundation. A copy of this license is ** included with this software distribution in the file COPYING. If you ** do not have a copy, you may obtain a copy by writing to the Free ** Software Foundation, 51 Franklin St, Fifth Floor, Boston, MA ** 02110-1301, USA. ** ** This software is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details ****************************************************************************** ** CVS Log ** ** Revision 1.10 2006/12/21 09:54:45 dgp85 ** Apply the textrel patch from Gentoo, thanks to PaX team for providing it. The patch was applied and tested for a while in Gentoo and Pardus, and solves also Debian's problems with non-PIC code. If problems will arise, they'll be debugged. ** ** Revision 1.9 2006/02/04 14:06:29 miguelfreitas ** Enable AMD64 mmx/sse support in some plugins (tvtime, libmpeg2, goom...) ** patch by dani3l ** ** Revision 1.8 2005/06/05 16:00:06 miguelfreitas ** quite some hacks for gcc 2.95 compatibility ** ** Revision 1.7 2004/04/09 02:57:06 miguelfreitas ** tvtime deinterlacing algorithms assumed top_field_first=1 ** top_field_first=0 (aka bottom_field_first) should now work as expected ** ** Revision 1.6 2004/02/12 20:53:31 mroi ** my gcc (partly 3.4 already) optimizes these away, because they are only used ** inside inline assembler (which the compiler does not recognize); so actually ** the code is wrong (the asm parts should list these as inputs), but telling ** the compiler to keep them is the easier fix ** ** Revision 1.5 2004/01/05 12:15:55 siggi ** wonder why Mike isn't complaining about C++ style comments, any more... ** ** Revision 1.4 2004/01/05 01:47:26 tmmm ** DOS/Win CRs are forbidden, verboten, interdit ** ** Revision 1.3 2004/01/02 20:53:43 miguelfreitas ** better MANGLE from ffmpeg ** ** Revision 1.2 2004/01/02 20:47:03 miguelfreitas ** my small contribution to the cygwin port ;-) ** ** Revision 1.1 2003/06/22 17:30:03 miguelfreitas ** use our own port of greedy2frame (tvtime port is currently broken) ** ** Revision 1.8 2001/11/23 17:18:54 adcockj ** Fixed silly and/or confusion ** ** Revision 1.7 2001/11/22 22:27:00 adcockj ** Bug Fixes ** ** Revision 1.6 2001/11/21 15:21:40 adcockj ** Renamed DEINTERLACE_INFO to TDeinterlaceInfo in line with standards ** Changed TDeinterlaceInfo structure to have history of pictures. ** ** Revision 1.5 2001/07/31 06:48:33 adcockj ** Fixed index bug spotted by Peter Gubanov ** ** Revision 1.4 2001/07/13 16:13:33 adcockj ** Added CVS tags and removed tabs ** *****************************************************************************/ /* * This is the implementation of the Greedy 2-frame deinterlace algorithm * described in DI_Greedy2Frame.c. It's in a separate file so we can compile * variants for different CPU types; most of the code is the same in the * different variants. */ /**************************************************************************** ** Field 1 | Field 2 | Field 3 | Field 4 | ** T0 | | T1 | | ** | M0 | | M1 | ** B0 | | B1 | | */ #if defined(ARCH_X86) #if !defined(MASKS_DEFINED) #define MASKS_DEFINED static const mmx_t Mask = { .uq = 0x7f7f7f7f7f7f7f7fll }; #define TP GREEDYTWOFRAMETHRESHOLD, GREEDYTWOFRAMETHRESHOLD2 static const mmx_t GreedyTwoFrameThreshold = { .ub = {TP, TP, TP, TP} }; #undef TP #endif #endif #if defined(IS_MMXEXT) static void DeinterlaceGreedy2Frame_MMXEXT(uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) #elif defined(IS_3DNOW) static void DeinterlaceGreedy2Frame_3DNOW(uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) #else static void DeinterlaceGreedy2Frame_MMX(uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) #endif { #if defined(ARCH_X86) int Line; int stride = width * 2; register uint8_t* M1; register uint8_t* M0; register uint8_t* T0; register uint8_t* T1; register uint8_t* B1; register uint8_t* B0; uint8_t* Dest = output; register uint8_t* Dest2; register int count; uint32_t Pitch = stride*2; uint32_t LineLength = stride; uint32_t PitchRest = Pitch - (LineLength >> 3)*8; if( second_field ) { M1 = data->f0; T1 = data->f0; M0 = data->f1; T0 = data->f1; } else { M1 = data->f0; T1 = data->f1; M0 = data->f1; T0 = data->f2; } if( bottom_field ) { M1 += stride; T1 += 0; B1 = T1 + Pitch; M0 += stride; T0 += 0; B0 = T0 + Pitch; } else { M1 += Pitch; T1 += stride; B1 = T1 + Pitch; M0 += Pitch; T0 += stride; B0 = T0 + Pitch; xine_fast_memcpy(Dest, M1, LineLength); Dest += outstride; } for (Line = 0; Line < (height / 2) - 1; ++Line) { /* Always use the most recent data verbatim. By definition it's correct * (it'd be shown on an interlaced display) and our job is to fill in * the spaces between the new lines. */ xine_fast_memcpy(Dest, T1, stride); Dest += outstride; Dest2 = Dest; count = LineLength >> 3; do { __asm__ __volatile__( /* Figure out what to do with the scanline above the one we just copied. * See above for a description of the algorithm. * weave if (weave(M) AND (weave(T) OR weave(B))) */ "movq %0, %%mm1 \n\t" // T1 "movq %1, %%mm0 \n\t" // M1 "movq %2, %%mm3 \n\t" // B1 "movq %3, %%mm2 \n\t" // M0 "movq %4, %%mm6 \n\t" // Mask : /* no output */ : "m" (*T1), "m" (*M1), "m" (*B1), "m" (*M0), "m" (Mask) ); __asm__ __volatile__( /* Figure out what to do with the scanline above the one we just copied. * See above for a description of the algorithm. * Average T1 and B1 so we can do interpolated bobbing if we bob onto T1 */ "movq %%mm3, %%mm7 \n\t" /* mm7 = B1 */ #if defined(IS_MMXEXT) "pavgb %%mm1, %%mm7 \n\t" #elif defined(IS_3DNOW) "pavgusb %%mm1, %%mm7 \n\t" #else "movq %%mm1, %%mm5 \n\t" /* mm5 = T1 */ "psrlw $1, %%mm7 \n\t" /* mm7 = B1 / 2 */ "pand %%mm6, %%mm7 \n\t" /* mask off lower bits */ "psrlw $1, %%mm5 \n\t" /* mm5 = T1 / 2 */ "pand %%mm6, %%mm5 \n\t" /* mask off lower bits */ "paddw %%mm5, %%mm7 \n\t" /* mm7 = (T1 + B1) / 2 */ #endif /* calculate |M1-M0| put result in mm4 need to keep mm0 intact * if we have a good processor then make mm0 the average of M1 and M0 * which should make weave look better when there is small amounts of * movement */ #if defined(IS_MMXEXT) "movq %%mm0, %%mm4 \n\t" "movq %%mm2, %%mm5 \n\t" "psubusb %%mm2, %%mm4 \n\t" "psubusb %%mm0, %%mm5 \n\t" "por %%mm5, %%mm4 \n\t" "pavgb %%mm2, %%mm0 \n\t" #elif defined(IS_3DNOW) "movq %%mm0, %%mm4 \n\t" "movq %%mm2, %%mm5 \n\t" "psubusb %%mm2, %%mm4 \n\t" "psubusb %%mm0, %%mm5 \n\t" "por %%mm5, %%mm4 \n\t" "pavgusb %%mm2, %%mm0 \n\t" #else "movq %%mm0, %%mm4 \n\t" "psubusb %%mm2, %%mm4 \n\t" "psubusb %%mm0, %%mm2 \n\t" "por %%mm2, %%mm4 \n\t" #endif "movq %1, %%mm2 \n\t" /* mm2 = T0 */ /* if |M1-M0| > Threshold we want 0 else dword minus one */ "psrlw $1, %%mm4 \n\t" "pand %%mm6, %%mm4 \n\t" "pxor %%mm5, %%mm5 \n\t" // zero "pcmpgtb %3, %%mm4 \n\t" "pcmpeqd %%mm5, %%mm4 \n\t" /* do we want to bob */ /* calculate |T1-T0| put result in mm5 */ "movq %%mm2, %%mm5 \n\t" "psubusb %%mm1, %%mm5 \n\t" "psubusb %%mm2, %%mm1 \n\t" "por %%mm1, %%mm5 \n\t" "movq %2, %%mm2 \n\t" /* mm2 = B0 */ /* if |T1-T0| > Threshold we want 0 else dword minus one */ "psrlw $1, %%mm5 \n\t" "pand %%mm6, %%mm5 \n\t" "pxor %%mm1, %%mm1 \n\t" // zero "pcmpgtb %3, %%mm5 \n\t" "pcmpeqd %%mm1, %%mm5 \n\t" /* calculate |B1-B0| put result in mm1 */ "movq %%mm2, %%mm1 \n\t" "psubusb %%mm3, %%mm1 \n\t" "psubusb %%mm2, %%mm3 \n\t" "por %%mm3, %%mm1 \n\t" /* if |B1-B0| > Threshold we want 0 else dword minus one */ "psrlw $1, %%mm1 \n\t" "pand %%mm6, %%mm1 \n\t" "pxor %%mm3, %%mm3 \n\t" // zero "pcmpgtb %3, %%mm1 \n\t" "pcmpeqd %%mm3, %%mm1 \n\t" "por %%mm1, %%mm5 \n\t" "pand %%mm5, %%mm4 \n\t" /* debugging feature * output the value of mm4 at this point which is pink where we will weave * and green where we are going to bob */ #ifdef CHECK_BOBWEAVE #ifdef IS_MMXEXT "movntq %%mm4, %0 \n\t" #else "movq %%mm4, %0 \n\t" #endif #else /* mm4 now is 1 where we want to weave and 0 where we want to bob */ "pand %%mm4, %%mm0 \n\t" "pandn %%mm7, %%mm4 \n\t" "por %%mm0, %%mm4 \n\t" #ifdef IS_MMXEXT "movntq %%mm4, %0 \n\t" #else "movq %%mm4, %0 \n\t" #endif #endif : "=m" (*Dest2) : "m" (*T0), "m" (*B0), "m" (GreedyTwoFrameThreshold) ); /* Advance to the next set of pixels. */ T1 += 8; M1 += 8; B1 += 8; M0 += 8; T0 += 8; B0 += 8; Dest2 += 8; } while( --count ); Dest += outstride; M1 += PitchRest; T1 += PitchRest; B1 += PitchRest; M0 += PitchRest; T0 += PitchRest; B0 += PitchRest; } #ifdef IS_MMXEXT __asm__ __volatile__("sfence\n\t"); #endif if( bottom_field ) { xine_fast_memcpy(Dest, T1, stride); Dest += outstride; xine_fast_memcpy(Dest, M1, stride); } else { xine_fast_memcpy(Dest, T1, stride); } /* clear out the MMX registers ready for doing floating point again */ __asm__ __volatile__("emms\n\t"); #endif } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/greedy2frame.c��������������������������������������������0000644�0001750�0001750�00000006530�14647725152�021124� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2000 John Adcock, Tom Barry, Steve Grimm All rights reserved. * port copyright (c) 2003 Miguel Freitas * * This code is ported from DScaler: http://deinterlace.sf.net/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include <xine/attributes.h> #include <xine/xineutils.h> #include "xine_mmx.h" #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" #include "plugins.h" // debugging feature // output the value of mm4 at this point which is pink where we will weave // and green were we are going to bob // uncomment next line to see this //#define CHECK_BOBWEAVE #define GREEDYTWOFRAMETHRESHOLD 4 #define GREEDYTWOFRAMETHRESHOLD2 8 #if defined(ARCH_X86) #define IS_MMXEXT 1 #include "greedy2frame_template.c" #undef IS_MMXEXT #include "greedy2frame_template_sse2.c" #endif /* ARCH_X86 */ static void DeinterlaceGreedy2Frame(uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) { #if defined(ARCH_X86) if (xine_mm_accel() & MM_ACCEL_X86_SSE2) { if (((uintptr_t)output & 15) || (outstride & 15) || width & 7 || ((uintptr_t)data->f0 & 15) || ((uintptr_t)data->f1 & 15)) { /* * instead of using an unaligned sse2 version just fall back to mmx * which has no alignment restriction (though might be slow unaliged, * but shouldn't hit this hopefully anyway). Plus in my experiments this * was at least as fast as a naive unaligned sse2 version anyway (due to * the inability to use streaming stores). */ DeinterlaceGreedy2Frame_MMXEXT(output, outstride, data, bottom_field, second_field, width, height ); } else { DeinterlaceGreedy2Frame_SSE2(output, outstride, data, bottom_field, second_field, width, height ); } } else { DeinterlaceGreedy2Frame_MMXEXT(output, outstride, data, bottom_field, second_field, width, height ); /* could fall back to 3dnow/mmx here too */ } #endif /*ARCH_X86 */ } static const deinterlace_method_t greedy2framemethod = { "Greedy 2-frame (DScaler)", "Greedy2Frame", 4, MM_ACCEL_X86_MMXEXT, 0, 0, 0, 0, DeinterlaceGreedy2Frame, 1, NULL }; const deinterlace_method_t *greedy2frame_get_method( void ) { return &greedy2framemethod; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/double.c��������������������������������������������������0000644�0001750�0001750�00000003335�14647725152�020022� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Line doubler deinterlacing plugin. * * Copyright (C) 2002 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "speedy.h" #include "deinterlace.h" #include "plugins.h" static void deinterlace_scanline_double( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { blit_packed422_scanline( output, data->t0, width ); } static void copy_scanline( uint8_t *output, deinterlace_scanline_data_t *data, int width ) { blit_packed422_scanline( output, data->m0, width ); } static const deinterlace_method_t doublemethod = { "Line Doubler", "LineDoubler", 1, 0, 0, 1, deinterlace_scanline_double, copy_scanline, 0, 0, NULL }; const deinterlace_method_t *double_get_method( void ) { return &doublemethod; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/kdetv_greedyh.c�������������������������������������������0000644�0001750�0001750�00000007057�14647725152�021401� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include <xine/attributes.h> #include <xine/xineutils.h> #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" #include "plugins.h" #if defined (ARCH_X86) #include "greedyhmacros.h" #define MAXCOMB_DEFAULT 5 #define MOTIONTHRESHOLD_DEFAULT 25 #define MOTIONSENSE_DEFAULT 30 static unsigned int GreedyMaxComb = MAXCOMB_DEFAULT; static unsigned int GreedyMotionThreshold = MOTIONTHRESHOLD_DEFAULT; static unsigned int GreedyMotionSense = MOTIONSENSE_DEFAULT; #define IS_SSE #define SSE_TYPE SSE #define FUNCT_NAME greedyh_filter_sse #include "greedyh.asm" #undef SSE_TYPE #undef IS_SSE #undef FUNCT_NAME #define IS_3DNOW #define FUNCT_NAME greedyh_filter_3dnow #define SSE_TYPE 3DNOW #include "greedyh.asm" #undef SSE_TYPE #undef IS_3DNOW #undef FUNCT_NAME #define IS_MMX #define SSE_TYPE MMX #define FUNCT_NAME greedyh_filter_mmx #include "greedyh.asm" #undef SSE_TYPE #undef IS_MMX #undef FUNCT_NAME #endif static void deinterlace_frame_di_greedyh( uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) { #if defined (ARCH_X86) if( xine_mm_accel() & MM_ACCEL_X86_MMXEXT ) { greedyh_filter_sse( output, outstride, data, bottom_field, second_field, width, height ); } else if( xine_mm_accel() & MM_ACCEL_X86_3DNOW ) { greedyh_filter_3dnow( output, outstride, data, bottom_field, second_field, width, height ); } else { greedyh_filter_mmx( output, outstride, data, bottom_field, second_field, width, height ); } #endif } static const deinterlace_method_t greedymethod = { "Greedy - High Motion (DScaler)", "GreedyH", /* "Motion Adaptive: Advanced Detection", "AdaptiveAdvanced", */ 4, MM_ACCEL_X86_MMX, 0, 0, 0, 0, deinterlace_frame_di_greedyh, 0, "Uses heuristics to detect motion in the input frames and reconstruct " "image detail where possible. Use this for high quality output even " "on monitors set to an arbitrary refresh rate.\n" "\n" "Advanced detection uses linear interpolation where motion is " "detected, using a four-field buffer. This is the Greedy: High Motion " "deinterlacer from DScaler." }; const deinterlace_method_t *dscaler_greedyh_get_method( void ) { return &greedymethod; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/greedyhmacros.h�������������������������������������������0000644�0001750�0001750�00000007240�14647725152�021410� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������///////////////////////////////////////////////////////////////////////////// // Copyright (c) 2001 Tom Barry. All rights reserved. ///////////////////////////////////////////////////////////////////////////// // // This file is subject to the terms of the GNU General Public License as // published by the Free Software Foundation. A copy of this license is // included with this software distribution in the file COPYING. If you // do not have a copy, you may obtain a copy by writing to the Free // Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. // // This software is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details // ///////////////////////////////////////////////////////////////////////////// // Define a few macros for CPU dependent instructions. // I suspect I don't really understand how the C macro preprocessor works but // this seems to get the job done. // TRB 7/01 // BEFORE USING THESE YOU MUST SET: // #define SSE_TYPE SSE (or MMX or 3DNOW) // some macros for pavgb instruction // V_PAVGB(mmr1, mmr2, mmr work register, smask) mmr2 may = mmrw if you can trash it #define V_PAVGB_MMX(mmr1, mmr2, mmrw, smask) \ "movq "mmr2", "mmrw"\n\t" \ "pand "smask", "mmrw"\n\t" \ "psrlw $1, "mmrw"\n\t" \ "pand "smask", "mmr1"\n\t" \ "psrlw $1, "mmr1"\n\t" \ "paddusb "mmrw", "mmr1"\n\t" #define V_PAVGB_SSE(mmr1, mmr2, mmrw, smask) "pavgb "mmr2", "mmr1"\n\t" #define V_PAVGB_3DNOW(mmr1, mmr2, mmrw, smask) "pavgusb "mmr2", "mmr1"\n\t" #define V_PAVGB(mmr1, mmr2, mmrw, smask) V_PAVGB2(mmr1, mmr2, mmrw, smask, SSE_TYPE) #define V_PAVGB2(mmr1, mmr2, mmrw, smask, ssetyp) V_PAVGB3(mmr1, mmr2, mmrw, smask, ssetyp) #define V_PAVGB3(mmr1, mmr2, mmrw, smask, ssetyp) V_PAVGB_##ssetyp(mmr1, mmr2, mmrw, smask) // some macros for pmaxub instruction #define V_PMAXUB_MMX(mmr1, mmr2) \ "psubusb "mmr2", "mmr1"\n\t" \ "paddusb "mmr2", "mmr1"\n\t" #define V_PMAXUB_SSE(mmr1, mmr2) "pmaxub "mmr2", "mmr1"\n\t" #define V_PMAXUB_3DNOW(mmr1, mmr2) V_PMAXUB_MMX(mmr1, mmr2) // use MMX version #define V_PMAXUB(mmr1, mmr2) V_PMAXUB2(mmr1, mmr2, SSE_TYPE) #define V_PMAXUB2(mmr1, mmr2, ssetyp) V_PMAXUB3(mmr1, mmr2, ssetyp) #define V_PMAXUB3(mmr1, mmr2, ssetyp) V_PMAXUB_##ssetyp(mmr1, mmr2) // some macros for pminub instruction // V_PMINUB(mmr1, mmr2, mmr work register) mmr2 may NOT = mmrw #define V_PMINUB_MMX(mmr1, mmr2, mmrw) \ "pcmpeqb "mmrw", "mmrw"\n\t" \ "psubusb "mmr2", "mmrw"\n\t" \ "paddusb "mmrw", "mmr1"\n\t" \ "psubusb "mmrw", "mmr1"\n\t" #define V_PMINUB_SSE(mmr1, mmr2, mmrw) "pminub "mmr2", "mmr1"\n\t" #define V_PMINUB_3DNOW(mmr1, mmr2, mmrw) V_PMINUB_MMX(mmr1, mmr2, mmrw) // use MMX version #define V_PMINUB(mmr1, mmr2, mmrw) V_PMINUB2(mmr1, mmr2, mmrw, SSE_TYPE) #define V_PMINUB2(mmr1, mmr2, mmrw, ssetyp) V_PMINUB3(mmr1, mmr2, mmrw, ssetyp) #define V_PMINUB3(mmr1, mmr2, mmrw, ssetyp) V_PMINUB_##ssetyp(mmr1, mmr2, mmrw) // some macros for movntq instruction // V_MOVNTQ(mmr1, mmr2) #define V_MOVNTQ_MMX(mmr1, mmr2) "movq "mmr2", "mmr1"\n\t" #define V_MOVNTQ_3DNOW(mmr1, mmr2) "movq "mmr2", "mmr1"\n\t" #define V_MOVNTQ_SSE(mmr1, mmr2) "movntq "mmr2", "mmr1"\n\t" #define V_MOVNTQ(mmr1, mmr2) V_MOVNTQ2(mmr1, mmr2, SSE_TYPE) #define V_MOVNTQ2(mmr1, mmr2, ssetyp) V_MOVNTQ3(mmr1, mmr2, ssetyp) #define V_MOVNTQ3(mmr1, mmr2, ssetyp) V_MOVNTQ_##ssetyp(mmr1, mmr2) // end of macros ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/plugins/kdetv_tomsmocomp.c����������������������������������������0000644�0001750�0001750�00000007671�14647725152�022151� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (C) 2004 Billy Biggs <vektor@dumbterm.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 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., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <string.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include <xine/attributes.h> #include <xine/xineutils.h> #include "deinterlace.h" #include "speedtools.h" #include "speedy.h" #include "plugins.h" #if defined (ARCH_X86) static int Fieldcopy(void *dest, const void *src, size_t count, int rows, int dst_pitch, int src_pitch) { unsigned char* pDest = (unsigned char*) dest; const unsigned char* pSrc = (const unsigned char*) src; int i; for (i=0; i < rows; i++) { xine_fast_memcpy(pDest, pSrc, count); pSrc += src_pitch; pDest += dst_pitch; } return 0; } #include "tomsmocomp/tomsmocompmacros.h" #include "x86-64_macros.inc" #define SearchEffortDefault 5 #define UseStrangeBobDefault 0 static long SearchEffort=SearchEffortDefault; static int UseStrangeBob=UseStrangeBobDefault; #define IS_MMX #define SSE_TYPE MMX #define FUNCT_NAME tomsmocomp_filter_mmx #include "tomsmocomp/TomsMoCompAll.inc" #undef IS_MMX #undef SSE_TYPE #undef FUNCT_NAME #define IS_3DNOW #define SSE_TYPE 3DNOW #define FUNCT_NAME tomsmocomp_filter_3dnow #include "tomsmocomp/TomsMoCompAll.inc" #undef IS_3DNOW #undef SSE_TYPE #undef FUNCT_NAME #define IS_SSE #define SSE_TYPE SSE #define FUNCT_NAME tomsmocomp_filter_sse #include "tomsmocomp/TomsMoCompAll.inc" #undef IS_SSE #undef SSE_TYPE #undef FUNCT_NAME #endif static void deinterlace_frame_di_tomsmocomp( uint8_t *output, int outstride, deinterlace_frame_data_t *data, int bottom_field, int second_field, int width, int height ) { #if defined (ARCH_X86) if( xine_mm_accel() & MM_ACCEL_X86_MMXEXT ) { tomsmocomp_filter_sse( output, outstride, data, bottom_field, second_field, width, height ); } else if( xine_mm_accel() & MM_ACCEL_X86_3DNOW ) { tomsmocomp_filter_3dnow( output, outstride, data, bottom_field, second_field, width, height ); } else { tomsmocomp_filter_mmx( output, outstride, data, bottom_field, second_field, width, height ); } #endif } static const deinterlace_method_t tomsmocompmethod = { "Tom's Motion Compensated (DScaler)", "TomsMoComp", /* "Motion Adaptive: Motion Search", "AdaptiveSearch", */ 4, MM_ACCEL_X86_MMX, 0, 0, 0, 0, deinterlace_frame_di_tomsmocomp, 0, "Uses heuristics to detect motion in the input frames and reconstruct " "image detail where possible. Use this for high quality output even " "on monitors set to an arbitrary refresh rate.\n" "\n" "Motion search mode finds and follows motion vectors for accurate " "interpolation. This is the TomsMoComp deinterlacer from DScaler." }; const deinterlace_method_t *dscaler_tomsmocomp_get_method( void ) { return &tomsmocompmethod; } �����������������������������������������������������������������������xine-lib-1.2/src/post/deinterlace/tvtime.c����������������������������������������������������������0000644�0001750�0001750�00000041776�14647725152�016412� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * Copyright (c) 2001, 2002, 2003 Billy Biggs <vektor@dumbterm.net>. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <stdio.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <math.h> #if HAVE_INTTYPES_H #include <inttypes.h> #else #include <stdint.h> #endif #include "speedy.h" #include "deinterlace.h" #include "pulldown.h" #include "tvtime.h" /** * This is how many predictions have to be incorrect before we fall back to * video mode. Right now, if we mess up, we jump to video mode immediately. */ #define PULLDOWN_ERROR_THRESHOLD 2 /** * Explination of the loop: * * We want to build frames so that they look like this: * Top field: Bot field: * Copy Double * Interp Copy * Copy Interp * Interp Copy * Copy -- * -- -- * -- -- * Copy Interp * Interp Copy * Copy Interp * Double Copy * * So, say a frame is n high. * For the bottom field, the first scanline is blank (special case). * For the top field, the final scanline is blank (special case). * For the rest of the scanlines, we alternate between Copy then Interpolate. * * To do the loop, I go 'Interp then Copy', and handle the first copy * outside the loop for both top and bottom. * The top field therefore handles n-2 scanlines in the loop. * The bot field handles n-2 scanlines in the loop. * * What we pass to the deinterlacing routines: * * Each deinterlacing routine can require data from up to four fields. * The current field is being output is Field 4: * * | Field 3 | Field 2 | Field 1 | Field 0 | * | | T2 | | T0 | * | M3 | | M1 | | * | | B2 | | B0 | * | NX3 | | NX1 | | * * So, since we currently get frames not individual fields from V4L, there * are two possibilities for where these come from: * * CASE 1: Deinterlacing the top field: * | Field 4 | Field 3 | Field 2 | Field 1 | Field 0 | * | T4 | | T2 | | T0 | * | | M3 | | M1 | | * | B4 | | B2 | | B0 | * [-- secondlast --] [-- lastframe --] [-- curframe --] * * CASE 2: Deinterlacing the bottom field: * | Field 4 | Field 3 | Field 2 | Field 1 | Field 0 | * | T4 | | T2 | | T0 | * | | M3 | | M1 | | * | B4 | | B2 | | B0 | * ndlast --] [-- lastframe --] [-- curframe --] * * So, in case 1, we need the previous 2 frames as well as the current * frame, and in case 2, we only need the previous frame, since the * current frame contains both Field 3 and Field 4. */ static void pulldown_merge_fields( uint8_t *output, uint8_t *topfield, uint8_t *botfield, int width, int frame_height, int fieldstride, int outstride ) { int i; for( i = 0; i < frame_height; i++ ) { uint8_t *curoutput = output + (i * outstride); if( i & 1 ) { blit_packed422_scanline( curoutput, botfield + ((i / 2) * fieldstride), width ); } else { blit_packed422_scanline( curoutput, topfield + ((i / 2) * fieldstride), width ); } } } static void calculate_pulldown_score_vektor( tvtime_t *tvtime, uint8_t *curframe, uint8_t *lastframe, int instride, int frame_height, int width ) { int i; tvtime->last_topdiff = 0; tvtime->last_botdiff = 0; for( i = 0; i < frame_height; i++ ) { if( i > 40 && (i & 3) == 0 && i < frame_height - 40 ) { tvtime->last_topdiff += diff_factor_packed422_scanline( curframe + (i*instride), lastframe + (i*instride), width ); tvtime->last_botdiff += diff_factor_packed422_scanline( curframe + (i*instride) + instride, lastframe + (i*instride) + instride, width ); } } } int tvtime_build_deinterlaced_frame( tvtime_t *tvtime, uint8_t *output, uint8_t *curframe, uint8_t *lastframe, uint8_t *secondlastframe, int bottom_field, int second_field, int width, int frame_height, int instride, int outstride ) { if( tvtime->pulldown_alg != PULLDOWN_VEKTOR ) { /* If we leave vektor pulldown mode, lose our state. */ tvtime->filmmode = 0; } if( tvtime->pulldown_alg == PULLDOWN_VEKTOR ) { /* Make pulldown phase decisions every top field. */ if( !bottom_field ) { int predicted; predicted = tvtime->pdoffset << 1; if( predicted > PULLDOWN_SEQ_DD ) predicted = PULLDOWN_SEQ_AA; calculate_pulldown_score_vektor( tvtime, curframe, lastframe, instride, frame_height, width ); tvtime->pdoffset = determine_pulldown_offset_short_history_new( tvtime->last_topdiff, tvtime->last_botdiff, 1, predicted ); /* 3:2 pulldown state machine. */ if( !tvtime->pdoffset ) { /* No pulldown offset applies, drop out of pulldown immediately. */ tvtime->pdlastbusted = 0; tvtime->pderror = tvtime->pulldown_error_wait; } else if( tvtime->pdoffset != predicted ) { if( tvtime->pdlastbusted ) { tvtime->pdlastbusted--; tvtime->pdoffset = predicted; } else { tvtime->pderror = tvtime->pulldown_error_wait; } } else { if( tvtime->pderror ) { tvtime->pderror--; } if( !tvtime->pderror ) { tvtime->pdlastbusted = PULLDOWN_ERROR_THRESHOLD; } } if( !tvtime->pderror ) { /* We're in pulldown, reverse it. */ if( !tvtime->filmmode ) { printf( "Film mode enabled.\n" ); tvtime->filmmode = 1; } if( pulldown_drop( tvtime->pdoffset, 0 ) ) return 0; if( pulldown_source( tvtime->pdoffset, 0 ) ) { pulldown_merge_fields( output, lastframe, lastframe + instride, width, frame_height, instride*2, outstride ); } else { pulldown_merge_fields( output, curframe, lastframe + instride, width, frame_height, instride*2, outstride ); } return 1; } else { if( tvtime->filmmode ) { printf( "Film mode disabled.\n" ); tvtime->filmmode = 0; } } } else if( !tvtime->pderror ) { if( pulldown_drop( tvtime->pdoffset, 1 ) ) return 0; if( pulldown_source( tvtime->pdoffset, 1 ) ) { pulldown_merge_fields( output, curframe, lastframe + instride, width, frame_height, instride*2, outstride ); } else { pulldown_merge_fields( output, curframe, curframe + instride, width, frame_height, instride*2, outstride ); } return 1; } } if( !tvtime->curmethod->scanlinemode ) { deinterlace_frame_data_t data; data.f0 = curframe; data.f1 = lastframe; data.f2 = secondlastframe; tvtime->curmethod->deinterlace_frame( output, outstride, &data, bottom_field, second_field, width, frame_height ); } else { int loop_size, bytes_left; uint8_t *f3, *f4; if (frame_height < 8) { /* should not happen */ while (frame_height-- > 0) { blit_packed422_scanline (output, curframe, width); curframe += instride; output += outstride; } } else { if (bottom_field) { /* Advance frame pointers to the next input line. */ curframe += instride; lastframe += instride; secondlastframe += instride; /* Double the top scanline a scanline. */ blit_packed422_scanline (output, curframe, width); output += outstride; } /* Copy a scanline. */ blit_packed422_scanline (output, curframe, width); output += outstride; if (second_field) { f3 = curframe; f4 = lastframe; } else { f3 = lastframe; f4 = secondlastframe; } /* Something is wrong here. -Billy */ loop_size = ((frame_height - 6) / 2); bytes_left = (frame_height - 5) * instride; { deinterlace_scanline_data_t data; data.bottom_field = bottom_field; data.bytes_left = bytes_left; data.t0 = curframe; data.b0 = curframe + instride * 2; data.tt1 = data.m1 = f3 + instride; data.bb1 = f3 + instride * 3; data.t2 = lastframe; data.b2 = lastframe + instride * 2; data.tt3 = data.m3 = f4 + instride; data.bb3 = f4 + instride * 3; tvtime->curmethod->interpolate_scanline (output, &data, width); output += outstride; data.tt0 = curframe; data.m0 = curframe + instride * 2; data.bb0 = curframe + instride * 4; data.t1 = f3 + instride; data.b1 = f3 + instride * 3; data.tt2 = lastframe; data.t2 = f4 + instride; data.m2 = lastframe + instride * 2; data.b2 = f4 + instride * 3; data.bb2 = lastframe + instride * 4; tvtime->curmethod->copy_scanline (output, &data, width); curframe += instride * 2; lastframe += instride * 2; f3 += instride * 2; f4 += instride * 2; bytes_left -= instride * 2; output += outstride; } while (loop_size-- > 0) { deinterlace_scanline_data_t data; data.bottom_field = bottom_field; data.bytes_left = bytes_left; data.t0 = curframe; data.b0 = curframe + instride * 2; data.tt1 = f3 - instride; data.m1 = f3 + instride; data.bb1 = f3 + instride * 3; data.t2 = lastframe; data.b2 = lastframe + instride * 2; data.tt3 = f4 - instride; data.m3 = f4 + instride; data.bb3 = f4 + instride * 3; tvtime->curmethod->interpolate_scanline (output, &data, width); output += outstride; data.tt0 = curframe; data.m0 = curframe + instride * 2; data.bb0 = curframe + instride * 4; data.t1 = f3 + instride; data.b1 = f3 + instride * 3; data.tt2 = lastframe; data.t2 = f4 + instride; data.m2 = lastframe + instride * 2; data.b2 = f4 + instride * 3; data.bb2 = lastframe + instride * 4; tvtime->curmethod->copy_scanline (output, &data, width); curframe += instride * 2; lastframe += instride * 2; f3 += instride * 2; f4 += instride * 2; bytes_left -= instride * 2; output += outstride; } { deinterlace_scanline_data_t data; data.bottom_field = bottom_field; data.bytes_left = bytes_left; data.t0 = curframe; data.b0 = curframe + instride * 2; data.tt1 = f3 - instride; data.m1 = data.bb1 = f3 + instride; data.t2 = lastframe; data.b2 = lastframe + instride * 2; data.tt3 = f4 - instride; data.m3 = data.bb3 = f4 + instride; tvtime->curmethod->interpolate_scanline (output, &data, width); output += outstride; data.tt0 = curframe; data.m0 = data.bb0 = curframe + instride * 2; data.t1 = data.b1 = f3 + instride; data.tt2 = lastframe; data.t2 = data.b2 = f4 + instride; data.m2 = data.bb2 = lastframe + instride * 2; tvtime->curmethod->copy_scanline (output, &data, width); } if (!bottom_field) { curframe += instride * 2; output += outstride; /* Double the bottom scanline. */ blit_packed422_scanline (output, curframe, width); } } } return 1; } int tvtime_build_copied_field( tvtime_t *tvtime, uint8_t *output, uint8_t *curframe, int bottom_field, int width, int frame_height, int instride, int outstride ) { int scanline = 0; int i; (void)tvtime; if( bottom_field ) { /* Advance frame pointers to the next input line. */ curframe += instride; } /* Copy a scanline. */ // blit_packed422_scanline( output, curframe, width ); quarter_blit_vertical_packed422_scanline( output, curframe + (instride*2), curframe, width ); curframe += instride * 2; output += outstride; scanline += 2; for( i = ((frame_height - 2) / 2); i; --i ) { /* Copy/interpolate a scanline. */ if( bottom_field ) { // interpolate_packed422_scanline( output, curframe, curframe - (instride*2), width ); quarter_blit_vertical_packed422_scanline( output, curframe - (instride*2), curframe, width ); } else { // blit_packed422_scanline( output, curframe, width ); if( i > 1 ) { quarter_blit_vertical_packed422_scanline( output, curframe + (instride*2), curframe, width ); } else { blit_packed422_scanline( output, curframe, width ); } } curframe += instride * 2; output += outstride; scanline += 2; } (void)scanline; return 1; } tvtime_t *tvtime_new_context(void) { tvtime_t *tvtime; tvtime = calloc(1, sizeof(tvtime_t)); if (!tvtime) return NULL; tvtime->pulldown_alg = PULLDOWN_NONE; tvtime->curmethod = NULL; tvtime_reset_context(tvtime); return tvtime; } void tvtime_reset_context( tvtime_t *tvtime ) { tvtime->last_topdiff = 0; tvtime->last_botdiff = 0; tvtime->pdoffset = PULLDOWN_SEQ_AA; tvtime->pderror = tvtime->pulldown_error_wait; tvtime->pdlastbusted = 0; tvtime->filmmode = 0; } ��xine-lib-1.2/src/post/Makefile.am�������������������������������������������������������������������0000644�0001750�0001750�00000016004�14647725152�014475� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������AUTOMAKE_OPTIONS = subdir-objects include $(top_srcdir)/misc/Makefile.common include $(top_builddir)/misc/Makefile.plugins noinst_LTLIBRARIES = EXTRA_DIST = AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) EXTRA_DIST += visualizations/fooviz.c xinepost_LTLIBRARIES = \ xineplug_post_audio_filters.la \ xineplug_post_goom.la \ xineplug_post_mosaico.la \ xineplug_post_planar.la \ xineplug_post_switch.la \ xineplug_post_tvtime.la \ xineplug_post_visualizations.la xineplug_post_visualizations_la_SOURCES = \ visualizations/fft.h \ visualizations/fft.c \ visualizations/fftgraph.c \ visualizations/fftscope.c \ visualizations/oscope.c \ visualizations/tdaudioanalyzer.c \ visualizations/visualizations.c \ visualizations/visualizations.h xineplug_post_visualizations_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(MVEC_LIB) -lm xineplug_post_audio_filters_la_SOURCES = \ audio/audio_filters.c \ audio/audio_filters.h \ audio/dsp.h \ audio/filter.c \ audio/filter.h \ audio/stretch.c \ audio/upmix.c \ audio/upmix_mono.c \ audio/volnorm.c \ audio/window.c \ audio/window.h xineplug_post_audio_filters_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) $(MVEC_LIB) -lm xineplug_post_mosaico_la_SOURCES = mosaico/mosaico.c xineplug_post_mosaico_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_post_switch_la_SOURCES = mosaico/switch.c xineplug_post_switch_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) # # deinterlace # EXTRA_DIST += \ deinterlace/plugins/greedy2frame_template.c \ deinterlace/plugins/greedy2frame_template_sse2.c \ deinterlace/plugins/greedyh.asm \ deinterlace/plugins/tomsmocomp/SearchLoop0A.inc \ deinterlace/plugins/tomsmocomp/SearchLoopBottom.inc \ deinterlace/plugins/tomsmocomp/SearchLoopEdgeA.inc \ deinterlace/plugins/tomsmocomp/SearchLoopEdgeA8.inc \ deinterlace/plugins/tomsmocomp/SearchLoopOddA.inc \ deinterlace/plugins/tomsmocomp/SearchLoopOddA2.inc \ deinterlace/plugins/tomsmocomp/SearchLoopOddA6.inc \ deinterlace/plugins/tomsmocomp/SearchLoopOddAH.inc \ deinterlace/plugins/tomsmocomp/SearchLoopOddAH2.inc \ deinterlace/plugins/tomsmocomp/SearchLoopTop.inc \ deinterlace/plugins/tomsmocomp/SearchLoopVA.inc \ deinterlace/plugins/tomsmocomp/SearchLoopVAH.inc \ deinterlace/plugins/tomsmocomp/StrangeBob.inc \ deinterlace/plugins/tomsmocomp/TomsMoCompAll.inc \ deinterlace/plugins/tomsmocomp/TomsMoCompAll2.inc \ deinterlace/plugins/tomsmocomp/WierdBob.inc \ deinterlace/plugins/tomsmocomp/tomsmocompmacros.h \ deinterlace/plugins/x86-64_macros.inc if DEBUG_BUILD debug_sources = deinterlace/plugins/greedy2frame.c nodebug_sources = else debug_sources = nodebug_sources = deinterlace/plugins/greedy2frame.c endif # per-object CFLAGS -- drop optimization on kdetv_greedyh.c so that gcc # doesn't run out of general registers trying to compile it. noinst_LTLIBRARIES += \ libdeinterlaceplugins_O1.la \ libdeinterlaceplugins.la libdeinterlaceplugins_O1_la_SOURCES = \ deinterlace/plugins/kdetv_greedyh.c \ $(debug_sources) libdeinterlaceplugins_O1_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/post/deinterlace libdeinterlaceplugins_O1_la_CFLAGS = $(O1_CFLAGS) $(VISIBILITY_FLAG) libdeinterlaceplugins_O1_la_LDFLAGS = libdeinterlaceplugins_la_SOURCES = \ deinterlace/plugins/double.c \ deinterlace/plugins/greedy.c \ deinterlace/plugins/greedyhmacros.h \ deinterlace/plugins/kdetv_tomsmocomp.c \ deinterlace/plugins/linear.c \ deinterlace/plugins/linearblend.c \ deinterlace/plugins/plugins.h \ deinterlace/plugins/vfir.c \ deinterlace/plugins/weave.c \ deinterlace/plugins/scalerbob.c \ $(nodebug_sources) libdeinterlaceplugins_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/post/deinterlace libdeinterlaceplugins_la_LIBADD = $(XINE_LIB) libdeinterlaceplugins_O1.la libdeinterlaceplugins_la_LDFLAGS = # xineplug_post_tvtime_la_SOURCES = \ deinterlace/deinterlace.c \ deinterlace/deinterlace.h \ deinterlace/pulldown.c \ deinterlace/pulldown.h \ deinterlace/speedtools.h \ deinterlace/speedy.c \ deinterlace/speedy.h \ deinterlace/tvtime.c \ deinterlace/tvtime.h \ deinterlace/xine_plugin.c xineplug_post_tvtime_la_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/post/deinterlace xineplug_post_tvtime_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) $(PTHREAD_LIBS) libdeinterlaceplugins.la xineplug_post_tvtime_la_LDFLAGS = $(AM_LDFLAGS) $(IMPURE_TEXT_LDFLAGS) # # planar # if ENABLE_POSTPROC pp_module_sources = planar/pp.c pp_module_libs = $(POSTPROC_LIBS) pp_module_deps = $(POSTPROC_DEPS) pp_module_cflags = $(FFMPEG_CFLAGS) $(POSTPROC_CFLAGS) endif if ARCH_X86 PLANAR_X86_LIB = libpost_planar_x86.la libpost_planar_x86_la_SOURCES = planar/x86/noise.c planar/x86/noise.h libpost_planar_x86_la_CFLAGS = $(O1_CFLAGS) -fomit-frame-pointer $(VISIBILITY_FLAG) libpost_planar_x86_la_LDFLAGS = noinst_LTLIBRARIES += $(PLANAR_X86_LIB) endif # xineplug_post_planar_la_SOURCES = \ planar/boxblur.c \ planar/denoise3d.c \ planar/eq.c \ planar/eq2.c \ planar/expand.c \ planar/fill.c \ planar/invert.c \ planar/noise.c \ planar/planar.c \ planar/planar.h \ planar/unsharp.c \ $(pp_module_sources) xineplug_post_planar_la_LIBADD = $(XINE_LIB) $(pp_module_libs) $(MVEC_LIB) -lm $(PTHREAD_LIBS) $(LTLIBINTL) $(PLANAR_X86_LIB) xineplug_post_planar_la_DEPS = $(pp_module_deps) xineplug_post_planar_la_CFLAGS = $(AM_CFLAGS) $(pp_module_cflags) xineplug_post_planar_la_LDFLAGS = $(AM_LDFLAGS) $(IMPURE_TEXT_LDFLAGS) # # goom # EXTRA_DIST += goom/diff_against_release.patch # following files are included to other files. # TODO: rename to .h ? EXTRA_DIST += goom/gfontrle.c goom/mathtools.c # following files are currently unused. EXTRA_DIST += \ goom/goomsl.c goom/goomsl.h goom/goomsl_hash.c goom/goomsl_hash.h \ goom/goomsl_heap.c goom/goomsl_heap.h goom/goomsl_private.h \ goom/goomsl_lex.c goom/goomsl_yacc.c goom/goomsl_yacc.h goom/default_scripts.h noinst_LTLIBRARIES += libpost_goom_asm.la libpost_goom_asm_la_SOURCES = goom/xmmx.c if DEBUG_BUILD libpost_goom_asm_la_CFLAGS = $(O1_CFLAGS) $(VISIBILITY_FLAG) endif libpost_goom_asm_la_LDFLAGS = xineplug_post_goom_la_SOURCES = \ goom/config_param.c \ goom/convolve_fx.c \ goom/cpu_info.c \ goom/cpu_info.h \ goom/drawmethods.c \ goom/drawmethods.h \ goom/filters.c \ goom/flying_stars_fx.c \ goom/gfontlib.c \ goom/gfontlib.h \ goom/goom.h \ goom/goom_config.h \ goom/goom_config_param.h \ goom/goom_core.c \ goom/goom_filters.h \ goom/goom_fx.h \ goom/goom_graphic.h \ goom/goom_plugin_info.h \ goom/goom_tools.c \ goom/goom_tools.h \ goom/goom_typedefs.h \ goom/goom_visual_fx.h \ goom/graphic.c \ goom/ifs.c \ goom/ifs.h \ goom/lines.c \ goom/lines.h \ goom/mathtools.h \ goom/mmx.c \ goom/mmx.h \ goom/motif_goom1.h \ goom/motif_goom2.h \ goom/plugin_info.c \ goom/ppc_drawings.h \ goom/ppc_zoom_ultimate.h \ goom/sound_tester.c \ goom/sound_tester.h \ goom/surf3d.c \ goom/surf3d.h \ goom/tentacle3d.c \ goom/tentacle3d.h \ goom/v3d.c \ goom/v3d.h \ goom/xine_goom.c xineplug_post_goom_la_LIBADD = $(XINE_LIB) $(GOOM_LIBS) $(PTHREAD_LIBS) $(LTLIBINTL) $(MVEC_LIB) -lm libpost_goom_asm.la ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/���������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�015524� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/oscope.c�������������������������������������������������������0000644�0001750�0001750�00000025535�14647725152�017172� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Basic Oscilloscope Visualization Post Plugin For xine * by Mike Melanson (melanson@pcisys.net) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "visualizations.h" #define FPS 20 #define NUMSAMPLES 512 #define MAXCHANNELS 6 #define OSCOPE_WIDTH NUMSAMPLES #define OSCOPE_HEIGHT 256 typedef struct post_plugin_oscope_s post_plugin_oscope_t; struct post_plugin_oscope_s { post_plugin_t post; /* private data */ xine_video_port_t *vo_port; post_out_t video_output; /* private metronom for syncing the video */ metronom_t *metronom; double ratio; int data_idx; short data [MAXCHANNELS][NUMSAMPLES]; audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */ int channels; int sample_counter; int samples_per_frame; unsigned char u_current; unsigned char v_current; int u_direction; int v_direction; yuv_planes_t yuv; }; /************************************************************************** * oscope specific decode functions *************************************************************************/ static void draw_oscope_dots(post_plugin_oscope_t *this) { int i, c; int pixel_ptr; int c_delta; memset(this->yuv.y, 0x00, OSCOPE_WIDTH * OSCOPE_HEIGHT); memset(this->yuv.u, 0x90, OSCOPE_WIDTH * OSCOPE_HEIGHT); memset(this->yuv.v, 0x80, OSCOPE_WIDTH * OSCOPE_HEIGHT); /* get a random delta between 1..6 */ c_delta = (rand() % 6) + 1; /* apply it to the current U value */ if (this->u_direction) { if (this->u_current + c_delta > 255) { this->u_current = 255; this->u_direction = 0; } else this->u_current += c_delta; } else { if (this->u_current - c_delta < 0) { this->u_current = 0; this->u_direction = 1; } else this->u_current -= c_delta; } /* get a random delta between 1..3 */ c_delta = (rand() % 3) + 1; /* apply it to the current V value */ if (this->v_direction) { if (this->v_current + c_delta > 255) { this->v_current = 255; this->v_direction = 0; } else this->v_current += c_delta; } else { if (this->v_current - c_delta < 0) { this->v_current = 0; this->v_direction = 1; } else this->v_current -= c_delta; } for( c = 0; c < this->channels; c++){ /* draw channel scope */ for (i = 0; i < NUMSAMPLES; i++) { pixel_ptr = ((OSCOPE_HEIGHT * (c * 2 + 1) / (2*this->channels) ) + (this->data[c][i] >> 9)) * OSCOPE_WIDTH + i; this->yuv.y[pixel_ptr] = 0xFF; this->yuv.u[pixel_ptr] = this->u_current; this->yuv.v[pixel_ptr] = this->v_current; } } /* top line */ for (i = 0, pixel_ptr = 0; i < OSCOPE_WIDTH; i++, pixel_ptr++) this->yuv.y[pixel_ptr] = 0xFF; /* lines under each channel */ for ( c = 0; c < this->channels; c++) for (i = 0, pixel_ptr = (OSCOPE_HEIGHT * (c+1) / this->channels - 1) * OSCOPE_WIDTH; i < OSCOPE_WIDTH; i++, pixel_ptr++) this->yuv.y[pixel_ptr] = 0xFF; } /************************************************************************** * xine video post plugin functions *************************************************************************/ static int oscope_rewire_video(xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data; xine_video_port_t *new_port = (xine_video_port_t *)data; post_plugin_oscope_t *this = (post_plugin_oscope_t *)output->post; if (!data) return 0; old_port->close(old_port, XINE_ANON_STREAM); (new_port->open) (new_port, XINE_ANON_STREAM); /* reconnect ourselves */ this->vo_port = new_port; return 1; } static int oscope_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_oscope_t *this = (post_plugin_oscope_t *)port->post; if (!this->metronom) this->metronom = _x_metronom_init(1, 0, stream->xine); _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->ratio = (double)OSCOPE_WIDTH/(double)OSCOPE_HEIGHT; this->channels = _x_ao_mode2channels(mode); if( this->channels > MAXCHANNELS ) this->channels = MAXCHANNELS; this->samples_per_frame = rate / FPS; this->data_idx = 0; this->sample_counter = 0; init_yuv_planes(&this->yuv, OSCOPE_WIDTH, OSCOPE_HEIGHT); (this->vo_port->open) (this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } static void oscope_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_oscope_t *this = (post_plugin_oscope_t *)port->post; port->stream = NULL; this->vo_port->close(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, NULL); port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } static void oscope_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_oscope_t *this = (post_plugin_oscope_t *)port->post; vo_frame_t *frame; int16_t *data; int8_t *data8; int samples_used = 0; int64_t pts = buf->vpts; int i, c; /* make a copy of buf data for private use */ if( this->buf.mem_size < buf->mem_size ) { this->buf.mem = realloc(this->buf.mem, buf->mem_size); this->buf.mem_size = buf->mem_size; } memcpy(this->buf.mem, buf->mem, buf->num_frames*this->channels*((port->bits == 8)?1:2)); this->buf.num_frames = buf->num_frames; /* pass data to original port */ port->original_port->put_buffer(port->original_port, buf, stream ); /* we must not use original data anymore, it should have already being moved * to the fifo of free audio buffers. just use our private copy instead. */ buf = &this->buf; this->sample_counter += buf->num_frames; do { if( port->bits == 8 ) { data8 = (int8_t *)buf->mem; data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data8 += this->channels ) for( c = 0; c < this->channels; c++) this->data[c][this->data_idx] = ((int16_t)data8[c] << 8) - 0x8000; } else { data = buf->mem; data += samples_used * this->channels; for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data += this->channels ) for( c = 0; c < this->channels; c++) this->data[c][this->data_idx] = data[c]; } if( this->sample_counter >= this->samples_per_frame ) { samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, OSCOPE_WIDTH, OSCOPE_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; /* frame is marked as bad if we don't have enough samples for * updating the viz plugin (calculations may be skipped). * we must keep the framerate though. */ if( this->data_idx == NUMSAMPLES ) { frame->bad_frame = 0; this->data_idx = 0; } else { frame->bad_frame = 1; } frame->duration = 90000 * this->samples_per_frame / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); this->sample_counter -= this->samples_per_frame; draw_oscope_dots(this); yuv444_to_yuy2(&this->yuv, frame->base[0], frame->pitches[0]); frame->draw(frame, XINE_ANON_STREAM); frame->free(frame); } } while( this->sample_counter >= this->samples_per_frame ); } static void oscope_dispose(post_plugin_t *this_gen) { post_plugin_oscope_t *this = (post_plugin_oscope_t *)this_gen; if (!_x_post_dispose(this_gen)) return; if (this->metronom) this->metronom->exit(this->metronom); _x_freep(&this->buf.mem); free(this); } /* plugin class functions */ static post_plugin_t *oscope_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_oscope_t *this = calloc(1, sizeof(post_plugin_oscope_t)); post_in_t *input; post_out_t *output; post_out_t *outputv; post_audio_port_t *port; if (!this || !video_target || !video_target[0] || !audio_target || !audio_target[0] ) { free(this); return NULL; } (void)class_gen; (void)inputs; _x_post_init(&this->post, 1, 0); this->vo_port = video_target[0]; port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = oscope_port_open; port->new_port.close = oscope_port_close; port->new_port.put_buffer = oscope_port_put_buffer; outputv = &this->video_output; outputv->xine_out.name = "generated video"; outputv->xine_out.type = XINE_POST_DATA_VIDEO; outputv->xine_out.data = (xine_video_port_t **)&this->vo_port; outputv->xine_out.rewire = oscope_rewire_video; outputv->post = &this->post; xine_list_push_back(this->post.output, outputv); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = oscope_dispose; return &this->post; } /* plugin class initialization function */ void *oscope_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_oscope_class = { .open_plugin = oscope_open_plugin, .identifier = "Oscilloscope", .description = N_("Oscilloscope"), .dispose = NULL, }; (void)xine; (void)data; return (void*)&post_oscope_class; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/fftgraph.c�����������������������������������������������������0000644�0001750�0001750�00000032003�14647725152�017467� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * FftGraph Visualization Post Plugin For xine * by Thibaut Mattern (tmattern@noos.fr) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <math.h> #include <assert.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "bswap.h" #include "visualizations.h" #include "fft.h" #if defined(__ANDROID__) && __ANDROID_API__ < 18 #define log2(x) (log(x)/log(2)) #endif #define FPS 20 #define FFTGRAPH_WIDTH 512 #define FFTGRAPH_HEIGHT 256 #define FFT_BITS 11 #define NUMSAMPLES (1 << FFT_BITS) #define MAXCHANNELS 6 typedef struct post_plugin_fftgraph_s post_plugin_fftgraph_t; struct post_plugin_fftgraph_s { post_plugin_t post; /* private data */ xine_video_port_t *vo_port; post_out_t video_output; /* private metronom for syncing the video */ metronom_t *metronom; double ratio; int data_idx; complex_t wave[MAXCHANNELS][NUMSAMPLES]; audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */ int channels; int sample_counter; int samples_per_frame; fft_t *fft; uint32_t map[FFTGRAPH_HEIGHT][FFTGRAPH_WIDTH / 2]; int cur_line; int lines_per_channel; uint32_t yuy2_colors[512]; }; static int d2db (double d) { int i; if (d <= 0.0) return 0; i = log2 (d) * 512.0 / 12.0; return (i & ~511) ? ~(i >> 31) & 511 : i; } /* * fade function */ static void fade(int r1, int g1, int b1, int r2, int g2, int b2, uint32_t *yuy2_colors, int ldsteps) { int y = COMPUTE_Y (r1, g1, b1); int u = COMPUTE_U (r1, g1, b1); int v = COMPUTE_V (r1, g1, b1); int dy = (int)COMPUTE_Y (r2, g2, b2) - y; int du = (int)COMPUTE_U (r2, g2, b2) - u; int dv = (int)COMPUTE_V (r2, g2, b2) - v; int i; y <<= ldsteps; u <<= ldsteps; v <<= ldsteps; for (i = 1 << ldsteps; i; i--) { uint32_t ny = y >> ldsteps; #ifdef WORDS_BIGENDIAN *yuy2_colors++ = (ny << 24) | (ny << 8) | ((u >> ldsteps) << 16) | (v >> ldsteps); #else *yuy2_colors++ = (ny << 16) | ny | ((u >> ldsteps) << 8) | ((uint32_t)(v >> ldsteps) << 24); #endif y += dy; u += du; v += dv; } } static void draw_fftgraph(post_plugin_fftgraph_t *this, vo_frame_t *frame) { int i, c, y; int map_ptr; uint32_t yuy2_white; int line, line_min, line_max; uint32_t *framebase = (uint32_t *)ASSUME_ALIGNED_2 (frame->base[0], 4); yuy2_white = be2me_32((0xFF << 24) | (0x80 << 16) | (0xFF << 8) | 0x80); for (c = 0; c < this->channels; c++){ /* perform FFT for channel data */ fft_window(this->fft, this->wave[c]); fft_scale(this->wave[c], this->fft->bits); fft_compute(this->fft, this->wave[c]); /* plot the FFT points for the channel */ line = this->cur_line + c * this->lines_per_channel; for (i = 0; i < FFTGRAPH_WIDTH / 2; i++) { double amp_float = fft_amp2 (this->fft, i, this->wave[c]); this->map[line][i] = this->yuy2_colors[d2db (amp_float)]; } } this->cur_line = (this->cur_line + 1) % this->lines_per_channel; /* scrolling map */ map_ptr = 0; for(c = 0; c < this->channels; c++) { line = this->cur_line + c * this->lines_per_channel; line_min = c * this->lines_per_channel; line_max = (c + 1) * this->lines_per_channel; for(y = line; y < line_max; y++) { xine_fast_memcpy (framebase + map_ptr, this->map[y], FFTGRAPH_WIDTH * 2); map_ptr += (FFTGRAPH_WIDTH / 2); } for(y = line_min; y < line; y++) { xine_fast_memcpy (framebase + map_ptr, this->map[y], FFTGRAPH_WIDTH * 2); map_ptr += (FFTGRAPH_WIDTH / 2); } } /* top line */ for (map_ptr = 0; map_ptr < FFTGRAPH_WIDTH / 2; map_ptr++) framebase[map_ptr] = yuy2_white; /* lines under each channel */ for (c = 0; c < this->channels; c++){ for (i = 0, map_ptr = ((FFTGRAPH_HEIGHT * (c+1) / this->channels -1 ) * FFTGRAPH_WIDTH) / 2; i < FFTGRAPH_WIDTH / 2; i++, map_ptr++) framebase[map_ptr] = yuy2_white; } } /************************************************************************** * xine video post plugin functions *************************************************************************/ static int fftgraph_rewire_video(xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data; xine_video_port_t *new_port = (xine_video_port_t *)data; post_plugin_fftgraph_t *this = (post_plugin_fftgraph_t *)output->post; if (!data) return 0; /* register our stream at the new output port */ old_port->close(old_port, XINE_ANON_STREAM); (new_port->open) (new_port, XINE_ANON_STREAM); /* reconnect ourselves */ this->vo_port = new_port; return 1; } static int fftgraph_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fftgraph_t *this = (post_plugin_fftgraph_t *)port->post; int i,j; uint32_t *color_ptr; uint32_t yuy2_black; /* printf("fftgraph_port_open, port_gen=%p, stream=%p, this=%p\n", port_gen, stream, this); */ if (!this->metronom) this->metronom = _x_metronom_init (1, 0, stream->xine); _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->ratio = (double)FFTGRAPH_WIDTH / (double)FFTGRAPH_HEIGHT; this->channels = _x_ao_mode2channels(mode); if (this->channels < 1) this->channels = 1; if( this->channels > MAXCHANNELS ) this->channels = MAXCHANNELS; this->lines_per_channel = FFTGRAPH_HEIGHT / this->channels; this->samples_per_frame = rate / FPS; this->data_idx = 0; this->sample_counter = 0; (this->vo_port->open) (this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); this->fft = fft_new(FFT_BITS); this->cur_line = 0; /* compute colors */ color_ptr = this->yuy2_colors; /* black -> red */ fade(0, 0, 0, 128, 0, 0, color_ptr, 7); color_ptr += 128; /* red -> blue */ fade(128, 0, 0, 40, 0, 160, color_ptr, 7); color_ptr += 128; /* blue -> green */ fade(40, 0, 160, 40, 160, 70, color_ptr, 7); color_ptr += 128; /* green -> white */ fade(40, 160, 70, 255, 255, 255, color_ptr, 7); /* clear the map */ yuy2_black = be2me_32((0x00 << 24) | (0x80 << 16) | (0x00 << 8) | 0x80); for (i = 0; i < FFTGRAPH_HEIGHT; i++) { for (j = 0; j < (FFTGRAPH_WIDTH / 2); j++) { this->map[i][j] = yuy2_black; } } return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } static void fftgraph_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fftgraph_t *this = (post_plugin_fftgraph_t *)port->post; port->stream = NULL; fft_dispose(this->fft); this->fft = NULL; this->vo_port->close(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, NULL); port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } static void fftgraph_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fftgraph_t *this = (post_plugin_fftgraph_t *)port->post; vo_frame_t *frame; int16_t *data; int8_t *data8; int samples_used = 0; int64_t pts = buf->vpts; int i, c; /* make a copy of buf data for private use */ if( this->buf.mem_size < buf->mem_size ) { this->buf.mem = realloc(this->buf.mem, buf->mem_size); this->buf.mem_size = buf->mem_size; } memcpy(this->buf.mem, buf->mem, buf->num_frames*this->channels*((port->bits == 8)?1:2)); this->buf.num_frames = buf->num_frames; /* pass data to original port */ port->original_port->put_buffer(port->original_port, buf, stream ); /* we must not use original data anymore, it should have already being moved * to the fifo of free audio buffers. just use our private copy instead. */ buf = &this->buf; this->sample_counter += buf->num_frames; do { if( port->bits == 8 ) { data8 = (int8_t *)buf->mem; data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data8 += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)(data8[c] << 8) - 0x8000; this->wave[c][this->data_idx].im = 0; } } } else { data = buf->mem; data += samples_used * this->channels; for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)data[c]; this->wave[c][this->data_idx].im = 0; } } } if( this->sample_counter >= this->samples_per_frame ) { samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, FFTGRAPH_WIDTH, FFTGRAPH_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; /* frame is marked as bad if we don't have enough samples for * updating the viz plugin (calculations may be skipped). * we must keep the framerate though. */ if( this->data_idx == NUMSAMPLES ) { frame->bad_frame = 0; this->data_idx = 0; } else { frame->bad_frame = 1; } frame->duration = 90000 * this->samples_per_frame / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); this->sample_counter -= this->samples_per_frame; if( this->fft ) draw_fftgraph(this, frame); else frame->bad_frame = 1; frame->draw(frame, XINE_ANON_STREAM); frame->free(frame); } } while( this->sample_counter >= this->samples_per_frame ); } static void fftgraph_dispose(post_plugin_t *this_gen) { post_plugin_fftgraph_t *this = (post_plugin_fftgraph_t *)this_gen; if (!_x_post_dispose(this_gen)) return; if (this->metronom) this->metronom->exit(this->metronom); _x_freep(&this->buf.mem); free(this); } /* plugin class functions */ static post_plugin_t *fftgraph_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_fftgraph_t *this = calloc(1, sizeof(post_plugin_fftgraph_t)); post_in_t *input; post_out_t *output; post_out_t *outputv; post_audio_port_t *port; if (!this || !video_target || !video_target[0] || !audio_target || !audio_target[0] ) { free(this); return NULL; } (void)class_gen; (void)inputs; _x_post_init(&this->post, 1, 0); this->vo_port = video_target[0]; port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = fftgraph_port_open; port->new_port.close = fftgraph_port_close; port->new_port.put_buffer = fftgraph_port_put_buffer; outputv = &this->video_output; outputv->xine_out.name = "generated video"; outputv->xine_out.type = XINE_POST_DATA_VIDEO; outputv->xine_out.data = (xine_video_port_t **)&this->vo_port; outputv->xine_out.rewire = fftgraph_rewire_video; outputv->post = &this->post; xine_list_push_back(this->post.output, outputv); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = fftgraph_dispose; return &this->post; } /* plugin class initialization function */ void *fftgraph_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_fftgraph_class = { .open_plugin = fftgraph_open_plugin, .identifier = "fftgraph", .description = N_("fftgraph Visualization Post Plugin"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_fftgraph_class; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/tdaudioanalyzer.c����������������������������������������������0000644�0001750�0001750�00000072206�14647725152�021076� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2016-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * "Time Domain Audio Analyzer" Visualization Post Plugin For xine * by Torsten Jager (t.jager@gmx.de) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "visualizations.h" typedef struct { int x, y, width, height; /* these are in dB (0..-64) */ int rms; int peak; int hold; /* in frames */ int age; /* in sample values */ uint64_t squaresum; int smax; } tdaan_leveller_t; #define RING_LOG2 13 #define RING_SIZE (1 << RING_LOG2) #define RING_MASK (RING_SIZE - 1) typedef struct { post_plugin_t post; xine_video_port_t *vo_port; post_out_t video_output; metronom_t *metronom; /* video out props */ int video_width; int video_height; double video_ratio; int video_fps; /* phaser */ int phaser_x; int phaser_y; int phaser_width; int phaser_height; int phaser_last_x; int phaser_last_y; int amax; /* level bar */ tdaan_leveller_t lbar; tdaan_leveller_t rbar; int channels; int samples_per_frame; int ring_put, ring_get; int16_t ringbuf[RING_SIZE * 2]; } post_plugin_tdaan_t; typedef union { uint8_t bytes[4]; uint32_t word; } yuy2_color_t; static const yuy2_color_t /* SD, mpeg range */ tdaan_BLACK = {{ 16, 128, 16, 128}}, //tdaan_DARK_BLUE = {{ 61, 190, 61, 118}}, tdaan_DARK_RED = {{ 83, 107, 83, 190}}, //tdaan_DARK_MAGENTA= {{ 97, 169, 97, 180}}, tdaan_DARK_GREEN = {{124, 87, 124, 76}}, //tdaan_DARK_CYAN = {{132, 149, 132, 66}}, tdaan_DARK_YELLOW = {{155, 66, 155, 138}}, tdaan_GREY = {{128, 128, 128, 128}}, tdaan_LIGHT_GRAY = {{170, 128, 170, 128}}, //tdaan_BLUE = {{ 74, 209, 74, 115}}, tdaan_RED = {{103, 101, 103, 209}}, //tdaan_MAGENTA = {{121, 181, 121, 196}}, tdaan_GREEN = {{148, 74, 148, 60}}, //tdaan_CYAN = {{166, 155, 166, 47}}, tdaan_YELLOW = {{195, 47, 195, 141}}, tdaan_WHITE = {{220, 128, 220, 128}}; /************************************************************************** * video frame layout * *************************************************************************/ static void tdaan_video_resize (post_plugin_tdaan_t *this) { int w, h; w = this->video_width / (11 * 5); w += 1; w &= ~1; h = this->video_height / 10; this->phaser_x = w * 5; this->phaser_y = h; this->phaser_width = w * 7 * 5; this->phaser_height = h * 8; this->lbar.x = this->rbar.x = w * 9 * 5; this->lbar.y = this->rbar.y = h; this->lbar.width = this->rbar.width = w * 4; this->lbar.height = this->rbar.height = h * 8; this->lbar.hold = this->rbar.hold = -64; } /************************************************************************** * yuy2 rendering primitives - (0, 0) is top left * *************************************************************************/ static void tdaan_draw_text (vo_frame_t *frame, int x, int y, const char *s) { #define __ 255 static const uint8_t map[256] = { __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,10,__,__, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,__,__,__,__,__,__, __,__,11,__,__,__,__,__,__,__,__,__,12,__,__,__, __,__,13,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,14,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__, __,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__ }; #undef __ #define __ {{128, 128, 128, 128}} #define _o {{128, 128, 16, 128}} #define o_ {{ 16, 128, 128, 128}} #define oo {{ 16, 128, 16, 128}} static const yuy2_color_t font[] = { __,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,o_, __,oo,oo,oo,__, __,__,_o,o_,__, __,__,oo,o_,__, __,_o,oo,o_,__, __,oo,_o,o_,__, _o,o_,_o,o_,__, __,__,_o,o_,__, __,__,_o,o_,__, __,__,_o,o_,__, __,__,_o,o_,__, __,__,_o,o_,__, __,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, __,__,_o,oo,o_, __,_o,oo,oo,__, __,oo,__,__,__, _o,o_,__,__,__, _o,oo,oo,oo,o_, _o,oo,oo,oo,o_, __,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, __,__,__,_o,o_, __,_o,oo,oo,__, __,_o,oo,oo,o_, __,__,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,o_, __,oo,oo,oo,__, __,__,oo,__,__, __,_o,o_,__,__, __,oo,__,__,__, __,oo,__,o_,__, _o,o_,_o,o_,__, _o,oo,oo,oo,o_, _o,oo,oo,oo,o_, __,__,_o,o_,__, __,__,_o,o_,__, __,__,_o,o_,__, _o,oo,oo,oo,o_, _o,oo,oo,oo,o_, _o,o_,__,__,__, _o,o_,__,__,__, _o,oo,oo,oo,__, _o,oo,oo,oo,o_, __,__,__,_o,o_, __,__,__,_o,o_, _o,oo,oo,oo,o_, _o,oo,oo,oo,__, __,__,oo,oo,o_, __,_o,oo,oo,o_, __,oo,o_,__,__, _o,o_,__,__,__, _o,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,o_, __,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,oo,oo,oo,o_, __,__,__,_o,o_, __,__,__,oo,__, __,__,__,oo,__, __,__,_o,o_,__, __,__,_o,o_,__, __,__,oo,__,__, __,__,oo,__,__, __,_o,o_,__,__, __,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, __,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,o_, __,oo,oo,oo,__, __,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,o_, __,oo,oo,oo,o_, __,__,__,_o,o_, __,__,__,oo,o_, _o,oo,oo,oo,__, _o,oo,oo,__,__, __,__,__,__,__, __,__,__,__,__, __,__,__,__,__, __,__,__,__,__, __,__,__,__,__, _o,oo,oo,oo,__, _o,oo,oo,oo,__, __,__,__,__,__, __,__,__,__,__, __,__,__,__,__, oo,oo,oo,oo,__, oo,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,__, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, oo,oo,oo,oo,o_, oo,oo,oo,oo,__, _o,o_,__,__,__, _o,o_,__,__,__, _o,o_,__,__,__, _o,o_,__,__,__, _o,o_,__,__,__, _o,o_,__,__,__, _o,o_,__,__,__, _o,o_,__,__,__, _o,oo,oo,oo,o_, _o,oo,oo,oo,o_, oo,oo,oo,o_,__, _o,oo,oo,oo,__, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,__, _o,oo,oo,o_,__, _o,o_,__,oo,__, _o,o_,__,oo,__, _o,o_,__,_o,o_, _o,o_,__,__,oo, __,__,__,_o,o_, __,__,__,_o,o_, __,__,__,_o,o_, __,__,__,_o,o_, __,_o,oo,oo,o_, _o,oo,oo,oo,o_, _o,o_,__,_o,o_, _o,o_,__,_o,o_, _o,oo,oo,oo,o_, __,oo,oo,oo,o_ }; const uint8_t *z = (const uint8_t *)s; uint32_t down = frame->pitches[0]; uint32_t *p = (uint32_t *)ASSUME_ALIGNED_2 (frame->base[0] + down * y + ((x >> 1) << 2), 4); down /= 4; while (*z) { int n = map[*z++]; if (n != 255) { uint32_t *q = p; const yuy2_color_t *g = font + 5 * 10 * n; int i; for (i = 10; i; i--) { q[0] = g[0].word; q[1] = g[1].word; q[2] = g[2].word; q[3] = g[3].word; q[4] = g[4].word; g += 5; q += down; } } p += 5; } } static void tdaan_draw_line (vo_frame_t *frame, int x1, int y1, int x2, int y2, uint32_t gray) { int w = x2 - x1; int h = y2 - y1; /* horizontal line */ if (h == 0) { uint8_t *q = frame->base[0] + frame->pitches[0] * y1; if (w < 0) { w = -w; q += x2 * 2; } else { q += x1 * 2; } while (w) { *q = gray; q += 2; w--; } return; } /* vertical line */ if (w == 0) { uint8_t *q = frame->base[0] + x1 * 2; size_t step = frame->pitches[0]; if (h < 0) { h = -h; q += step * y2; } else { q += step * y1; } while (h) { *q = gray; q += step; h--; } return; } /* tilted */ { int32_t test[2], n; ssize_t bump[2]; /* always render downward */ if (h < 0) { x1 = x2; y1 = y2; w = -w; h = -h; } if (w < 0) { /* right to left */ w = -w; if (w >= h) { /* flat */ test[0] = -h; test[1] = w - h; bump[0] = -2; n = w; } else { /* steep */ test[0] = -w; test[1] = h - w; bump[0] = frame->pitches[0]; n = h; } bump[1] = frame->pitches[0] - 2; } else { /* left to right */ if (w >= h) { /* flat */ test[0] = -h; test[1] = w - h; bump[0] = 2; n = w; } else { /* steep */ test[0] = -w; test[1] = h - w; bump[0] = frame->pitches[0]; n = h; } bump[1] = frame->pitches[0] + 2; } { uint8_t *q = frame->base[0] + frame->pitches[0] * y1 + 2 * x1; int32_t d = test[1]; while (n) { uint32_t i = (uint32_t)d >> 31; *q = gray; d += test[i]; q += bump[i]; n--; } } } } static void tdaan_draw_rect (vo_frame_t *frame, int x, int y, int width, int height, uint32_t color) { uint32_t *q; if ((width <= 0) || (height <= 0)) return; if (x + width > frame->width) return; if (y + height > frame->height) return; x += 1; x &= ~1; width += 1; width &= ~1; q = (uint32_t *)ASSUME_ALIGNED_2 (frame->base[0] + y * frame->pitches[0] + x * 2, 4); { size_t rest = (frame->pitches[0] - width * 2) / 4; int ny = height; while (ny) { int nx = width; while (nx) { *q++ = color; nx -= 2; } q += rest; ny--; } } } /************************************************************************** * logarithmic level gauge with rms, peak and peak hold (0..-64dB) * *************************************************************************/ static void tdaan_levels_draw (post_plugin_tdaan_t *this, vo_frame_t *frame) { int top, bott; /* 6dB markers */ { const char *s = " 0\0 -6\0-12\0-18\0-24\0-30\0-36\0-42\0-48\0-54\0-60\0"; int x = this->lbar.x - this->lbar.width / 4, w = this->lbar.width * 6 / 4, i; for (i = 0; i < 64; i += 6) { top = this->lbar.y + ((i * this->lbar.height) >> 6); tdaan_draw_text (frame, x - 34, top - 5, s + (i * 4 / 6)); tdaan_draw_rect (frame, x, top, w, 1, tdaan_BLACK.word); } tdaan_draw_text (frame, x - 34, this->lbar.y + this->lbar.height - 5, " dB"); } /* bars */ bott = this->lbar.y + this->lbar.height; /* rms */ top = (this->lbar.rms + this->rbar.rms) >> 1; top = (-top * this->lbar.height) >> 6; top += this->lbar.y; if (top < bott) { tdaan_draw_rect (frame, this->lbar.x, top, this->lbar.width, bott - top, tdaan_YELLOW.word); bott = top; } /* peak mid */ top = this->lbar.peak < this->rbar.peak ? this->lbar.peak : this->rbar.peak; top = (-top * this->lbar.height) >> 6; top += this->lbar.y; if (top < bott) { tdaan_draw_rect (frame, this->lbar.x, top, this->lbar.width, bott - top, tdaan_DARK_YELLOW.word); bott = top; } /* peak side */ if (this->lbar.peak < this->rbar.peak) { top = (-this->rbar.peak * this->lbar.height) >> 6; top += this->lbar.y; tdaan_draw_rect (frame, this->lbar.x, top, this->lbar.width, bott - top, tdaan_DARK_RED.word); } else if (this->lbar.peak > this->rbar.peak) { top = (-this->lbar.peak * this->lbar.height) >> 6; top += this->lbar.y; tdaan_draw_rect (frame, this->lbar.x, top, this->lbar.width, bott - top, tdaan_DARK_GREEN.word); } /* hold */ if (this->lbar.peak >= this->lbar.hold) { this->lbar.hold = this->lbar.peak; this->lbar.age = this->video_fps; /* hold 1s */ } if (this->rbar.peak >= this->rbar.hold) { this->rbar.hold = this->rbar.peak; this->rbar.age = this->video_fps; } if (this->lbar.age && this->rbar.age && (this->lbar.hold == this->rbar.hold)) { top = (-this->rbar.hold * this->lbar.height) >> 6; top += this->lbar.y; tdaan_draw_rect (frame, this->lbar.x, top, this->lbar.width, 2, tdaan_YELLOW.word); this->lbar.age--; if (!this->lbar.age) this->lbar.hold = -64; this->rbar.age--; if (!this->rbar.age) this->rbar.hold = -64; } else { if (this->lbar.age) { top = (-this->lbar.hold * this->lbar.height) >> 6; top += this->lbar.y; tdaan_draw_rect (frame, this->lbar.x, top, this->lbar.width, 2, tdaan_GREEN.word); this->lbar.age--; if (!this->lbar.age) this->lbar.hold = -64; } if (this->rbar.age) { top = (-this->rbar.hold * this->lbar.height) >> 6; top += this->lbar.y; tdaan_draw_rect (frame, this->lbar.x, top, this->lbar.width, 2, tdaan_RED.word); this->rbar.age--; if (!this->rbar.age) this->rbar.hold = -64; } } } static int tdaan_int16todb (int s) { /* 20 * log10 (s / 32678) */ static const int t[64] = { 32767, 29204, 26028, 23197, 20675, 18426, 16422, 14636, 13045, 11626, 10362, 9235, 8231, 7335, 6538, 5827, 5193, 4628, 4125, 3676, 3277, 2920, 2603, 2320, 2062, 1842, 1682, 1463, 1304, 1162, 1031, 923, 823, 733, 654, 582, 518, 462, 412, 362, 327, 292, 260, 232, 206, 184, 164, 146, 130, 116, 103, 92, 82, 73, 65, 58, 52, 46, 41, 37, 33, 29, 26, 23 }; int a = 0, l, m = 0, e = 64; do { l = m; m = (a + e) >> 1; if (s < t[m]) a = m; else e = m; } while (l != m); return -m; } static int tdaan_int32todb (uint32_t s) { /* 10 * log10 (s / (32678 * 32678)) */ static const uint32_t t[64] = { 1073676289, 852873616, 677456784, 538100809, 427455625, 339517476, 269682084, 214212496, 170172025, 135163876, 107371044, 85285225, 67749361, 53802225, 42745444, 33953929, 26967249, 21418384, 17015625, 13512976, 10738729, 8526400, 6775609, 5382400, 4251844, 3392964, 2829124, 2140369, 1700416, 1350244, 1062961, 851929, 677329, 537289, 427716, 338724, 268324, 213444, 169744, 131044, 106929, 85264, 67600, 53824, 42436, 33856, 26896, 21316, 16900, 13456, 10609, 8464, 6724, 5329, 4225, 3364, 2704, 2116, 1681, 1369, 1089, 841, 676, 529 }; int a = 0, l, m = 0, e = 64; do { l = m; m = (a + e) >> 1; if (s < t[m]) a = m; else e = m; } while (l != m); return -m; } static void tdaan_levels_reset (post_plugin_tdaan_t *this) { this->lbar.squaresum = 0; this->rbar.squaresum = 0; this->lbar.peak = 0; this->rbar.peak = 0; } static void tdaan_levels_get (tdaan_leveller_t *v, const int16_t *data, int len) { uint64_t s = v->squaresum; int p = v->peak; const int16_t *q = data; if (len) { int n = len; do { uint32_t u; int a = *q; q += 2; if (a < 0) a = -a; if (a > p) p = a; u = a * a; s += u; n--; } while (n); v->squaresum = s; v->peak = p; } } static uint32_t tdaan_divu_quad_by_short (uint64_t num, uint32_t den) { uint32_t hi, lo, r; hi = num >> 16; r = hi / den; hi = hi % den; r <<= 16; lo = num & 0xffff; lo |= hi << 16; r |= lo / den; return r; } static void tdaan_levels_done (post_plugin_tdaan_t *this) { int amax; amax = this->lbar.peak; if (this->rbar.peak > amax) amax = this->rbar.peak; this->amax = amax; this->lbar.peak = tdaan_int16todb (this->lbar.peak); this->rbar.peak = tdaan_int16todb (this->rbar.peak); this->lbar.rms = tdaan_int32todb (tdaan_divu_quad_by_short (this->lbar.squaresum, this->samples_per_frame)); this->rbar.rms = tdaan_int32todb (tdaan_divu_quad_by_short (this->rbar.squaresum, this->samples_per_frame)); } /************************************************************************** * Normalized Lissajous stereo phase diagram * *************************************************************************/ static void tdaan_phaser_start (post_plugin_tdaan_t *this, vo_frame_t *frame) { /* background X */ tdaan_draw_line (frame, this->phaser_x, this->phaser_y, this->phaser_x + this->phaser_width, this->phaser_y + this->phaser_height, tdaan_BLACK.bytes[0]); tdaan_draw_line (frame, this->phaser_x + this->phaser_width, this->phaser_y, this->phaser_x, this->phaser_y + this->phaser_height, tdaan_BLACK.bytes[0]); tdaan_draw_text (frame, this->phaser_x, this->phaser_y + 12, "L"); tdaan_draw_text (frame, this->phaser_x + this->phaser_width - 10, this->phaser_y + 12, "R"); } static void tdaan_phaser_draw (post_plugin_tdaan_t *this, vo_frame_t *frame, const uint16_t *data, int len, uint32_t gray) { int lx = this->phaser_last_x; int ly = this->phaser_last_y; int mx = this->phaser_x + (this->phaser_width >> 1); int my = this->phaser_y + (this->phaser_height >> 1); int sx, sy; const int16_t *p = data; /* size */ { int amax = this->amax; if (amax < 200) amax = 200; sx = (this->phaser_width << 19) / amax; sy = (this->phaser_height << 19) / amax; } /* resume */ if (!lx || !ly) { int al = *p++; int ar = *p++; lx = mx - (((al - ar) * sx) >> 21); ly = my - (((al + ar) * sy) >> 21); len--; } /* main */ while (len > 0) { int x, y; { int al = *p++; int ar = *p++; x = mx - (((al - ar) * sx) >> 21); y = my - (((al + ar) * sy) >> 21); } tdaan_draw_line (frame, lx, ly, x, y, gray); lx = x; ly = y; len--; } this->phaser_last_x = lx; this->phaser_last_y = ly; } /************************************************************************** * downmixing (display use only, no high end quality needed) * * 0.75 * (center + lfe) to both sides * * 0.5 * rear to same side * * finally, 0.75 * result as saturation headroom * *************************************************************************/ #define sat16(v) (((v) + 0x8000) & ~0xffff ? ((v) >> 31) ^ 0x7fff : v) static void tdaan_downmix16_4 (const int16_t *p, int16_t *q, int n) { /* L R RL RR */ while (n--) { int32_t v; v = (int32_t)p[0] * 6 + (int32_t)p[2] * 3; v >>= 3; *q++ = sat16 (v); v = (int32_t)p[1] * 6 + (int32_t)p[3] * 3; v >>= 3; *q++ = sat16 (v); p += 4; } } static void tdaan_downmix16_6 (const int16_t *p, int16_t *q, int n) { /* L R RL RR C LFE */ while (n--) { int32_t l = ((int32_t)p[4] + (int32_t)p[5]) * 9, r = l; l += (int32_t)p[0] * 12 + (int32_t)p[2] * 6; l >>= 4; *q++ = sat16 (l); r += (int32_t)p[1] * 12 + (int32_t)p[3] * 6; r >>= 4; *q++ = sat16 (r); p += 6; } } /************************************************************************** * xine video post plugin functions * *************************************************************************/ static int tdaan_rewire_video (xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data; xine_video_port_t *new_port = (xine_video_port_t *)data; post_plugin_tdaan_t *this = (post_plugin_tdaan_t *)output->post; if (!data) return 0; /* register our stream at the new output port */ old_port->close (old_port, XINE_ANON_STREAM); new_port->open (new_port, XINE_ANON_STREAM); /* reconnect ourselves */ this->vo_port = new_port; return 1; } static int tdaan_port_open ( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_tdaan_t *this = (post_plugin_tdaan_t *)port->post; if (!this->metronom) this->metronom = _x_metronom_init (1, 0, stream->xine); _x_post_rewire (&this->post); _x_post_inc_usage (port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->video_width = 640; this->video_height = 480; this->video_ratio = (double)this->video_width / (double)this->video_height; this->video_fps = 20; tdaan_video_resize (this); this->channels = _x_ao_mode2channels (mode); this->samples_per_frame = rate / this->video_fps; this->vo_port->open (this->vo_port, XINE_ANON_STREAM); this->metronom->set_master (this->metronom, stream->metronom); return port->original_port->open (port->original_port, stream, bits, rate, mode); } static void tdaan_port_close (xine_audio_port_t *port_gen, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_tdaan_t *this = (post_plugin_tdaan_t *)port->post; port->stream = NULL; this->vo_port->close (this->vo_port, XINE_ANON_STREAM); this->metronom->set_master (this->metronom, NULL); port->original_port->close (port->original_port, stream); _x_post_dec_usage (port); } static void tdaan_port_put_buffer ( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_tdaan_t *this = (post_plugin_tdaan_t *)port->post; int64_t pts = buf->vpts; /* let video pts refer to the midle of the audio it is showing */ if (pts) { int offs = (this->ring_put - this->ring_get) & RING_MASK; offs -= this->samples_per_frame >> 1; pts -= INT64_C(90000) * offs / (int)port->rate; } /* buffer incoming audio */ do { int16_t *put = this->ringbuf + this->ring_put * 2; int n1 = buf->num_frames; int n2 = this->ring_put + n1; if (n1 <= 0) break; if (n2 & ~RING_MASK) { n1 -= n2 - RING_SIZE; n2 &= RING_MASK; this->ring_put = n2; } else { this->ring_put = n2; n2 = 0; } if (port->bits == 8) { const uint8_t *in = (uint8_t *)buf->mem; if (this->channels == 1) { do { put[0] = put[1] = ((int)(*in++) << 8) ^ 0x8000; put += 2; n1--; } while (n1); put = this->ringbuf; while (n2) { put[0] = put[1] = ((int)(*in++) << 8) ^ 0x8000; put += 2; n2--; } } else if (this->channels == 2) { do { *put++ = ((int)(*in++) << 8) ^ 0x8000; *put++ = ((int)(*in++) << 8) ^ 0x8000; n1--; } while (n1); put = this->ringbuf; while (n2) { *put++ = ((int)(*in++) << 8) ^ 0x8000; *put++ = ((int)(*in++) << 8) ^ 0x8000; n2--; } } } else if (port->bits == 16) { const int16_t *in = (int16_t *)buf->mem; if (this->channels == 1) { do { put[0] = put[1] = *in++; put += 2; n1--; } while (n1); put = this->ringbuf; while (n2) { put[0] = put[1] = *in++; put += 2; n2--; } } else if (this->channels == 2) { memcpy (put, in, n1 * 4); if (n2) { in += n1 * 2; put = this->ringbuf; memcpy (put, in, n2 * 4); } } else if (this->channels <= 4) { tdaan_downmix16_4 (in, put, n1); if (n2) { in += n1 * 4; put = this->ringbuf; tdaan_downmix16_4 (in, put, n2); } } else if (this->channels <= 6) { tdaan_downmix16_6 (in, put, n1); if (n2) { in += n1 * 6; put = this->ringbuf; tdaan_downmix16_6 (in, put, n2); } } } } while (0); /* pass data to original port */ port->original_port->put_buffer (port->original_port, buf, stream); /* output some gfx */ while (((this->ring_put - this->ring_get) & RING_MASK) >= this->samples_per_frame) { vo_frame_t *frame; const int16_t *get = this->ringbuf + this->ring_get * 2; int oldamax = this->amax; int n1 = this->samples_per_frame; int p2 = this->ring_get; int n2 = p2 + n1; if (n2 & ~RING_MASK) { n2 &= RING_MASK; this->ring_get = n2; n1 -= n2; } else { this->ring_get = n2; n2 = 0; } /* gather level stats */ tdaan_levels_reset (this); tdaan_levels_get (&this->lbar, get, n1); tdaan_levels_get (&this->rbar, get + 1, n1); if (n2) { tdaan_levels_get (&this->lbar, this->ringbuf, n2); tdaan_levels_get (&this->rbar, this->ringbuf + 1, n2); } tdaan_levels_done (this); /* get an output frame */ frame = this->vo_port->get_frame (this->vo_port, this->video_width, this->video_height, this->video_ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; frame->duration = 90000 * this->samples_per_frame / port->rate; frame->pts = pts; if (pts) pts += frame->duration; this->metronom->got_video_frame (this->metronom, frame); tdaan_draw_rect (frame, 0, 0, frame->width, frame->height, tdaan_GREY.word); /* draw levels */ tdaan_levels_draw (this, frame); /* draw phaser */ tdaan_phaser_start (this, frame); /* repeat last half of previous frame in half bright. */ /* this old CRT style fadeout makes more pleasant viewing. */ { int newamax = this->amax, p1; this->phaser_last_x = 0; this->phaser_last_y = 0; this->amax = oldamax; p1 = this->samples_per_frame >> 1; p2 -= p1; if (p2 < 0) { p1 += p2; tdaan_phaser_draw (this, frame, this->ringbuf + (RING_SIZE + p2) * 2, -p2, tdaan_LIGHT_GRAY.bytes[0]); } if (p1) tdaan_phaser_draw (this, frame, get - p1 * 2, p1, tdaan_LIGHT_GRAY.bytes[0]); this->amax = newamax; } /* now, this frame */ tdaan_phaser_draw (this, frame, get, n1, tdaan_WHITE.bytes[0]); if (n2) tdaan_phaser_draw (this, frame, this->ringbuf, n2, tdaan_WHITE.bytes[0]); /* pass to video out */ frame->draw (frame, XINE_ANON_STREAM); frame->free (frame); } } static void tdaan_dispose (post_plugin_t *this_gen) { post_plugin_tdaan_t *this = (post_plugin_tdaan_t *)this_gen; if (!_x_post_dispose (this_gen)) return; if (this->metronom) this->metronom->exit (this->metronom); free (this); } /* plugin class functions */ static post_plugin_t *tdaan_open_plugin ( post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_tdaan_t *this = calloc (1, sizeof (post_plugin_tdaan_t)); post_in_t *input; post_out_t *output; post_out_t *outputv; post_audio_port_t *port; if (!this || !video_target || !video_target[0] || !audio_target || !audio_target[0] ) { free(this); return NULL; } (void)class_gen; (void)inputs; _x_post_init (&this->post, 1, 0); this->vo_port = video_target[0]; port = _x_post_intercept_audio_port (&this->post, audio_target[0], &input, &output); port->new_port.open = tdaan_port_open; port->new_port.close = tdaan_port_close; port->new_port.put_buffer = tdaan_port_put_buffer; outputv = &this->video_output; outputv->xine_out.name = "tdaan generated video"; outputv->xine_out.type = XINE_POST_DATA_VIDEO; outputv->xine_out.data = (xine_video_port_t **)&this->vo_port; outputv->xine_out.rewire = tdaan_rewire_video; outputv->post = &this->post; xine_list_push_back (this->post.output, outputv); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = tdaan_dispose; return &this->post; } /* plugin class initialization function */ void *tdaan_init_plugin (xine_t *xine, const void *data) { static const post_class_t post_tdaan_class = { .open_plugin = tdaan_open_plugin, .identifier = "tdaudioanalyzer", .description = N_("Time Domain Audio Analyzer Visualisation"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_tdaan_class; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/visualizations.c�����������������������������������������������0000644�0001750�0001750�00000003337�14647725152�020762� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * This file contains plugin entries for several visualization post plugins. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/xine_internal.h> #include <xine/post.h> #include "visualizations.h" /* * exported plugin catalog entries */ /* plugin catalog information */ static const post_info_t gen_special_info = { .type = XINE_POST_TYPE_AUDIO_VISUALIZATION, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST, 10, "oscope", XINE_VERSION_CODE, &gen_special_info, &oscope_init_plugin }, { PLUGIN_POST, 10, "fftscope", XINE_VERSION_CODE, &gen_special_info, &fftscope_init_plugin }, { PLUGIN_POST, 10, "fftgraph", XINE_VERSION_CODE, &gen_special_info, &fftgraph_init_plugin }, { PLUGIN_POST, 10, "tdaudioanalyzer", XINE_VERSION_CODE, &gen_special_info, &tdaan_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/fft.h����������������������������������������������������������0000644�0001750�0001750�00000002626�14647725152�016462� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * */ #ifndef FFT_H #define FFT_H struct complex_s { double re; double im; }; typedef struct complex_s complex_t; struct fft_s { int bits; double *SineTable; double *CosineTable; double *WinTable; int *PermuteTable; int bmask; }; typedef struct fft_s fft_t; fft_t *fft_new (int bits); void fft_dispose(fft_t *fft); void fft_compute (fft_t *fft, complex_t wave[]); void fft_window (fft_t *fft, complex_t wave[]); double fft_amp (int n, complex_t wave[], int bits); void fft_scale (complex_t wave[], int bits); double fft_amp2 (fft_t *fft, int n, complex_t wave[]); #endif /* FFT_H */ ����������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/fooviz.c�������������������������������������������������������0000644�0001750�0001750�00000023274�14647725152�017214� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Reference Visualization Post Plugin For xine * by Mike Melanson (melanson@pcisys.net) * This is an example/template for the xine visualization post plugin * process. It simply paints the screen a solid color and rotates through * colors on each iteration. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #define FPS 20 #define FOO_WIDTH 320 #define FOO_HEIGHT 240 #define NUMSAMPLES 512 typedef struct post_plugin_fooviz_s post_plugin_fooviz_t; typedef struct post_class_fooviz_s post_class_fooviz_t; struct post_class_fooviz_s { post_class_t post_class; xine_t *xine; }; struct post_plugin_fooviz_s { post_plugin_t post; /* private data */ xine_video_port_t *vo_port; post_out_t video_output; /* private metronom for syncing the video */ metronom_t *metronom; double ratio; int data_idx; short data [2][NUMSAMPLES]; audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */ int channels; int sample_counter; int samples_per_frame; /* specific to fooviz */ unsigned char current_yuv_byte; }; /************************************************************************** * fooviz specific decode functions *************************************************************************/ /************************************************************************** * xine video post plugin functions *************************************************************************/ static int fooviz_rewire_video(xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data; xine_video_port_t *new_port = (xine_video_port_t *)data; post_plugin_fooviz_t *this = (post_plugin_fooviz_t *)output->post; if (!data) return 0; /* register our stream at the new output port */ old_port->close(old_port, XINE_ANON_STREAM); (new_port->open) (new_port, XINE_ANON_STREAM); /* reconnect ourselves */ this->vo_port = new_port; return 1; } static int fooviz_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fooviz_t *this = (post_plugin_fooviz_t *)port->post; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->ratio = (double)FOO_WIDTH/(double)FOO_HEIGHT; this->channels = _x_ao_mode2channels(mode); this->samples_per_frame = rate / FPS; this->data_idx = 0; this->sample_counter = 0; (this->vo_port->open) (this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } static void fooviz_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fooviz_t *this = (post_plugin_fooviz_t *)port->post; port->stream = NULL; this->vo_port->close(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, NULL); port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } static void fooviz_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fooviz_t *this = (post_plugin_fooviz_t *)port->post; vo_frame_t *frame; int16_t *data; int8_t *data8; int samples_used = 0; int64_t pts = buf->vpts; int i, j; /* make a copy of buf data for private use */ if( this->buf.mem_size < buf->mem_size ) { this->buf.mem = realloc(this->buf.mem, buf->mem_size); this->buf.mem_size = buf->mem_size; } memcpy(this->buf.mem, buf->mem, buf->num_frames*this->channels*((port->bits == 8)?1:2)); this->buf.num_frames = buf->num_frames; /* pass data to original port */ port->original_port->put_buffer(port->original_port, buf, stream ); /* we must not use original data anymore, it should have already being moved * to the fifo of free audio buffers. just use our private copy instead. */ buf = &this->buf; this->sample_counter += buf->num_frames; j = (this->channels >= 2) ? 1 : 0; do { if( port->bits == 8 ) { data8 = (int8_t *)buf->mem; data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data8 += this->channels ) { this->data[0][this->data_idx] = ((int16_t)data8[0] << 8) - 0x8000; this->data[1][this->data_idx] = ((int16_t)data8[j] << 8) - 0x8000; } } else { data = buf->mem; data += samples_used * this->channels; for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data += this->channels ) { this->data[0][this->data_idx] = data[0]; this->data[1][this->data_idx] = data[j]; } } if( this->sample_counter >= this->samples_per_frame ) { samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, FOO_WIDTH, FOO_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; /* frame is marked as bad if we don't have enough samples for * updating the viz plugin (calculations may be skipped). * we must keep the framerate though. */ if( this->data_idx == NUMSAMPLES ) { frame->bad_frame = 0; this->data_idx = 0; } else { frame->bad_frame = 1; } frame->duration = 90000 * this->samples_per_frame / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); this->sample_counter -= this->samples_per_frame; memset(frame->base[0], this->current_yuv_byte, FOO_WIDTH * FOO_HEIGHT * 2); this->current_yuv_byte += 3; frame->draw(frame, XINE_ANON_STREAM); frame->free(frame); } } while( this->sample_counter >= this->samples_per_frame ); } static void fooviz_dispose(post_plugin_t *this_gen) { post_plugin_fooviz_t *this = (post_plugin_fooviz_t *)this_gen; if (_x_post_dispose(this_gen)) { this->metronom->exit(this->metronom); if(this->buf.mem) free(this->buf.mem); free(this); } } /* plugin class functions */ static post_plugin_t *fooviz_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_class_fooviz_t *class = (post_class_fooviz_t *)class_gen; post_plugin_fooviz_t *this = calloc(1, sizeof(post_plugin_fooviz_t)); post_in_t *input; post_out_t *output; post_out_t *outputv; post_audio_port_t *port; if (!this || !video_target || !video_target[0] || !audio_target || !audio_target[0] ) { free(this); return NULL; } _x_post_init(&this->post, 1, 0); this->metronom = _x_metronom_init(1, 0, class->xine); this->vo_port = video_target[0]; port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = fooviz_port_open; port->new_port.close = fooviz_port_close; port->new_port.put_buffer = fooviz_port_put_buffer; outputv = &this->video_output; outputv->xine_out.name = "generated video"; outputv->xine_out.type = XINE_POST_DATA_VIDEO; outputv->xine_out.data = (xine_video_port_t **)&this->vo_port; outputv->xine_out.rewire = fooviz_rewire_video; outputv->post = &this->post; xine_list_push_back(this->post.output, outputv); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = fooviz_dispose; return &this->post; } /* plugin class initialization function */ static void *fooviz_init_plugin(xine_t *xine, const void *data) { post_class_fooviz_t *class = (post_class_fooviz_t *)xine_xmalloc(sizeof(post_class_fooviz_t)); if (!class) return NULL; class->post_class.open_plugin = fooviz_open_plugin; class->post_class.identifier = "fooviz"; class->post_class.description = N_("fooviz"); class->post_class.dispose = default_post_class_dispose; class->xine = xine; return class; } /* plugin catalog information */ static const post_info_t fooviz_special_info = { .type = XINE_POST_TYPE_AUDIO_VISUALIZATION, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST, 10, "fooviz", XINE_VERSION_CODE, &fooviz_special_info, &fooviz_init_plugin }, { PLUGIN_NONE, 0, "", 0, NULL, NULL } }; ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/fftscope.c�����������������������������������������������������0000644�0001750�0001750�00000034116�14647725152�017506� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Fast Fourier Transform Visualization Post Plugin For xine * by Mike Melanson (melanson@pcisys.net) * * FFT code by Steve Haehnichen, originally licensed under GPL v1 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <math.h> #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "bswap.h" #include "visualizations.h" #include "fft.h" #define FPS 20 #define FFT_WIDTH 512 #define FFT_HEIGHT 256 #define NUMSAMPLES 512 #define MAXCHANNELS 6 #define FFT_BITS 9 typedef struct post_plugin_fftscope_s post_plugin_fftscope_t; struct post_plugin_fftscope_s { post_plugin_t post; /* private data */ xine_video_port_t *vo_port; post_out_t video_output; /* private metronom for syncing the video */ metronom_t *metronom; double ratio; int data_idx; complex_t wave[MAXCHANNELS][NUMSAMPLES]; int amp_max[MAXCHANNELS][NUMSAMPLES / 2]; uint8_t amp_max_y[MAXCHANNELS][NUMSAMPLES / 2]; uint8_t amp_max_u[MAXCHANNELS][NUMSAMPLES / 2]; uint8_t amp_max_v[MAXCHANNELS][NUMSAMPLES / 2]; int amp_age[MAXCHANNELS][NUMSAMPLES / 2]; audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */ int channels; int sample_counter; int samples_per_frame; unsigned char u_current; unsigned char v_current; int u_direction; int v_direction; fft_t *fft; }; /* * Fade out a YUV pixel */ static void fade_out_yuv(uint8_t *y, uint8_t *u, uint8_t *v, float factor) { *y = (uint8_t)(factor * (*y - 16)) + 16; *u = (uint8_t)(factor * (*u - 128)) + 128; *v = (uint8_t)(factor * (*v - 128)) + 128; } static void draw_fftscope(post_plugin_fftscope_t *this, vo_frame_t *frame) { int i, j, c; int map_ptr, map_ptr_bkp; int amp_int, amp_max, x; float amp_float; uint32_t yuy2_pair, yuy2_pair_max, yuy2_white; int c_delta; uint32_t *framebase = (uint32_t *)ASSUME_ALIGNED_2 (frame->base[0], 4); const union {uint8_t b[4]; uint32_t w;} black = {{0, 128, 0, 128}}; /* clear the YUY2 map */ for (i = 0; i < FFT_WIDTH * FFT_HEIGHT / 2; i++) framebase[i] = black.w; /* get a random delta between 1..6 */ c_delta = (rand() % 6) + 1; /* apply it to the current U value */ if (this->u_direction) { if (this->u_current + c_delta > 255) { this->u_current = 255; this->u_direction = 0; } else this->u_current += c_delta; } else { if (this->u_current - c_delta < 0) { this->u_current = 0; this->u_direction = 1; } else this->u_current -= c_delta; } /* get a random delta between 1..3 */ c_delta = (rand() % 3) + 1; /* apply it to the current V value */ if (this->v_direction) { if (this->v_current + c_delta > 255) { this->v_current = 255; this->v_direction = 0; } else this->v_current += c_delta; } else { if (this->v_current - c_delta < 0) { this->v_current = 0; this->v_direction = 1; } else this->v_current -= c_delta; } yuy2_pair = be2me_32( (0x7F << 24) | (this->u_current << 16) | (0x7F << 8) | this->v_current); yuy2_white = be2me_32( (0xFF << 24) | (0x80 << 16) | (0xFF << 8) | 0x80); for (c = 0; c < this->channels; c++){ /* perform FFT for channel data */ fft_window(this->fft, this->wave[c]); fft_scale(this->wave[c], this->fft->bits); fft_compute(this->fft, this->wave[c]); /* plot the FFT points for the channel */ for (i = 0; i < NUMSAMPLES / 2; i++) { map_ptr = ((FFT_HEIGHT * (c+1) / this->channels -1 ) * FFT_WIDTH + i * 2) / 2; map_ptr_bkp = map_ptr; amp_float = fft_amp2 (this->fft, i, this->wave[c]); if (amp_float == 0) amp_int = 0; else amp_int = (int)((60/this->channels) * log10(amp_float)); if (amp_int > 255/this->channels) amp_int = 255/this->channels; if (amp_int < 0) amp_int = 0; for (j = 0; j < amp_int; j++, map_ptr -= FFT_WIDTH / 2) framebase[map_ptr] = yuy2_pair; /* amp max */ yuy2_pair_max = be2me_32( (this->amp_max_y[c][i] << 24) | (this->amp_max_u[c][i] << 16) | (this->amp_max_y[c][i] << 8) | this->amp_max_v[c][i]); /* gravity */ this->amp_age[c][i]++; if (this->amp_age[c][i] < 10) { amp_max = this->amp_max[c][i]; } else { x = this->amp_age[c][i] - 10; amp_max = this->amp_max[c][i] - x * x; } /* new peak ? */ if (amp_int > amp_max) { this->amp_max[c][i] = amp_int; this->amp_age[c][i] = 0; this->amp_max_y[c][i] = 0x7f; this->amp_max_u[c][i] = this->u_current; this->amp_max_v[c][i] = this->v_current; fade_out_yuv(&this->amp_max_y[c][i], &this->amp_max_u[c][i], &this->amp_max_v[c][i], 0.5); amp_max = amp_int; } else { fade_out_yuv(&this->amp_max_y[c][i], &this->amp_max_u[c][i], &this->amp_max_v[c][i], 0.95); } /* draw peaks */ for (j = amp_int; j < (amp_max - 1); j++, map_ptr -= FFT_WIDTH / 2) framebase[map_ptr] = yuy2_pair_max; /* top */ framebase[map_ptr] = yuy2_white; /* persistence of top */ if (this->amp_age[c][i] >= 10) { x = this->amp_age[c][i] - 10; x = 0x5f - x; if (x < 0x10) x = 0x10; framebase[map_ptr_bkp - this->amp_max[c][i] * (FFT_WIDTH / 2)] = be2me_32 ((x << 24) | (0x80 << 16) | (x << 8) | 0x80); } } } /* top line */ for (map_ptr = 0; map_ptr < FFT_WIDTH / 2; map_ptr++) framebase[map_ptr] = yuy2_white; /* lines under each channel */ for (c = 0; c < this->channels; c++){ for (i = 0, map_ptr = ((FFT_HEIGHT * (c+1) / this->channels -1 ) * FFT_WIDTH) / 2; i < FFT_WIDTH / 2; i++, map_ptr++) framebase[map_ptr] = yuy2_white; } } /************************************************************************** * xine video post plugin functions *************************************************************************/ static int fftscope_rewire_video(xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data; xine_video_port_t *new_port = (xine_video_port_t *)data; post_plugin_fftscope_t *this = (post_plugin_fftscope_t *)output->post; if (!data) return 0; /* register our stream at the new output port */ old_port->close(old_port, XINE_ANON_STREAM); (new_port->open) (new_port, XINE_ANON_STREAM); /* reconnect ourselves */ this->vo_port = new_port; return 1; } static int fftscope_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fftscope_t *this = (post_plugin_fftscope_t *)port->post; int c, i; if (!this->metronom) this->metronom = _x_metronom_init(1, 0, stream->xine); _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->ratio = (double)FFT_WIDTH/(double)FFT_HEIGHT; this->channels = _x_ao_mode2channels(mode); if( this->channels > MAXCHANNELS ) this->channels = MAXCHANNELS; this->samples_per_frame = rate / FPS; this->data_idx = 0; this->sample_counter = 0; this->fft = fft_new(FFT_BITS); (this->vo_port->open) (this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); for (c = 0; c < this->channels; c++) { for (i = 0; i < (NUMSAMPLES / 2); i++) { this->amp_max[c][i] = 0; this->amp_max_y[c][i] = 0; this->amp_max_u[c][i] = 0; this->amp_max_v[c][i] = 0; this->amp_age[c][i] = 0; } } return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } static void fftscope_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fftscope_t *this = (post_plugin_fftscope_t *)port->post; port->stream = NULL; fft_dispose(this->fft); this->fft = NULL; this->vo_port->close(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, NULL); port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } static void fftscope_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_fftscope_t *this = (post_plugin_fftscope_t *)port->post; vo_frame_t *frame; int16_t *data; int8_t *data8; int samples_used = 0; int64_t pts = buf->vpts; int i, c; /* make a copy of buf data for private use */ if( this->buf.mem_size < buf->mem_size ) { this->buf.mem = realloc(this->buf.mem, buf->mem_size); this->buf.mem_size = buf->mem_size; } memcpy(this->buf.mem, buf->mem, buf->num_frames*this->channels*((port->bits == 8)?1:2)); this->buf.num_frames = buf->num_frames; /* pass data to original port */ port->original_port->put_buffer(port->original_port, buf, stream ); /* we must not use original data anymore, it should have already being moved * to the fifo of free audio buffers. just use our private copy instead. */ buf = &this->buf; this->sample_counter += buf->num_frames; do { if( port->bits == 8 ) { data8 = (int8_t *)buf->mem; data8 += samples_used * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data8 += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)(data8[c] << 8) - 0x8000; this->wave[c][this->data_idx].im = 0; } } } else { data = buf->mem; data += samples_used * this->channels; for( i = samples_used; i < buf->num_frames && this->data_idx < NUMSAMPLES; i++, this->data_idx++, data += this->channels ) { for( c = 0; c < this->channels; c++){ this->wave[c][this->data_idx].re = (double)data[c]; this->wave[c][this->data_idx].im = 0; } } } if( this->sample_counter >= this->samples_per_frame ) { samples_used += this->samples_per_frame; frame = this->vo_port->get_frame (this->vo_port, FFT_WIDTH, FFT_HEIGHT, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; /* frame is marked as bad if we don't have enough samples for * updating the viz plugin (calculations may be skipped). * we must keep the framerate though. */ if( this->data_idx == NUMSAMPLES ) { frame->bad_frame = 0; this->data_idx = 0; } else { frame->bad_frame = 1; } frame->duration = 90000 * this->samples_per_frame / port->rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); this->sample_counter -= this->samples_per_frame; if( this->fft ) draw_fftscope(this, frame); else frame->bad_frame = 1; frame->draw(frame, XINE_ANON_STREAM); frame->free(frame); } } while( this->sample_counter >= this->samples_per_frame ); } static void fftscope_dispose(post_plugin_t *this_gen) { post_plugin_fftscope_t *this = (post_plugin_fftscope_t *)this_gen; if (!_x_post_dispose(this_gen)) return; if (this->metronom) this->metronom->exit(this->metronom); _x_freep(&this->buf.mem); free(this); } /* plugin class functions */ static post_plugin_t *fftscope_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_fftscope_t *this = calloc(1, sizeof(post_plugin_fftscope_t)); post_in_t *input; post_out_t *output; post_out_t *outputv; post_audio_port_t *port; if (!this || !video_target || !video_target[0] || !audio_target || !audio_target[0] ) { free(this); return NULL; } (void)class_gen; (void)inputs; _x_post_init(&this->post, 1, 0); this->vo_port = video_target[0]; port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = fftscope_port_open; port->new_port.close = fftscope_port_close; port->new_port.put_buffer = fftscope_port_put_buffer; outputv = &this->video_output; outputv->xine_out.name = "generated video"; outputv->xine_out.type = XINE_POST_DATA_VIDEO; outputv->xine_out.data = (xine_video_port_t **)&this->vo_port; outputv->xine_out.rewire = fftscope_rewire_video; outputv->post = &this->post; xine_list_push_back(this->post.output, outputv); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = fftscope_dispose; return &this->post; } /* plugin class initialization function */ void *fftscope_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_fftscope_class = { .open_plugin = fftscope_open_plugin, .identifier = "FFT Scope", .description = N_("FFT Scope"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_fftscope_class; } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/fft.c����������������������������������������������������������0000644�0001750�0001750�00000013001�14647725152�016442� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * FFT code by Steve Haehnichen, originally licensed under GPL v1 * modified by Thibaut Mattern (tmattern@noos.fr) to remove global vars */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <math.h> #include "fft.h" /************************************************************************** * fft specific decode functions *************************************************************************/ # define SINE(x) (fft->SineTable[(x)]) # define COSINE(x) (fft->CosineTable[(x)]) # define WINDOW(x) (fft->WinTable[(x)]) #define PERMUTE(x, y) reverse((x), (y)) /* Number of samples in one "frame" */ #define SAMPLES (1 << bits) #define REAL(x) wave[(x)].re #define IMAG(x) wave[(x)].im #define ALPHA 0.54 /* * Bit reverser for unsigned ints * Reverses 'bits' bits. */ static inline unsigned int reverse (unsigned int val, int bits) { unsigned int retn = 0; while (bits--) { retn <<= 1; retn |= (val & 1); val >>= 1; } return (retn); } /* * Here is the real work-horse. * It's a generic FFT, so nothing is lost or approximated. * The samples in wave[] should be in order, and they * will be decimated when fft() returns. */ void fft_compute (fft_t *fft, complex_t wave[]) { int loop; unsigned i1; /* going to right shift this */ int i2; int bits = fft->bits; i1 = SAMPLES / 2; i2 = 1; /* perform the butterflys */ for (loop = 0; loop < bits; loop++) { int loop1; int i3, i4; i3 = 0; i4 = i1; for (loop1 = 0; loop1 < i2; loop1++) { int loop2; int y; double z1, z2; y = fft->PermuteTable[(i3 / (int)i1) & fft->bmask]; z1 = COSINE(y); z2 = -SINE(y); for (loop2 = i3; loop2 < i4; loop2++) { double a1, a2, b1, b2; a1 = REAL(loop2); a2 = IMAG(loop2); b1 = z1 * REAL(loop2+i1) - z2 * IMAG(loop2+i1); b2 = z2 * REAL(loop2+i1) + z1 * IMAG(loop2+i1); REAL(loop2) = a1 + b1; IMAG(loop2) = a2 + b2; REAL(loop2+i1) = a1 - b1; IMAG(loop2+i1) = a2 - b2; } i3 += (i1 << 1); i4 += (i1 << 1); } i1 >>= 1; i2 <<= 1; } } /* * Initializer for FFT routines. Currently only sets up tables. * - Generates scaled lookup tables for sin() and cos() * - Fills a table for the Hamming window function */ fft_t *fft_new (int bits) { fft_t *fft; int i; const double TWOPIoN = (atan(1.0) * 8.0) / (double)SAMPLES; const double TWOPIoNm1 = (atan(1.0) * 8.0) / (double)(SAMPLES - 1); /* printf("fft_new: bits=%d\n", bits); */ fft = malloc (sizeof (fft_t)); if (!fft) return NULL; /* xine just uses 9 or 11. */ fft->bits = bits; fft->bmask = SAMPLES - 1; fft->PermuteTable = malloc (sizeof (int) * SAMPLES); if (!fft->PermuteTable) { free (fft); return NULL; } for (i = 0; i < SAMPLES; i++) { fft->PermuteTable[i] = PERMUTE (i, bits); } fft->SineTable = malloc (3 * sizeof(double) * SAMPLES); if (!fft->SineTable) { free (fft->PermuteTable); free (fft); return NULL; } fft->CosineTable = fft->SineTable + SAMPLES; fft->WinTable = fft->SineTable + 2 * SAMPLES; for (i = 0; i < SAMPLES; i++) { double a = (double) i * TWOPIoN; fft->SineTable[i] = sin (a); fft->CosineTable[i] = cos (a); } /* * Generalized Hamming window function. * Set ALPHA to 0.54 for a hanning window. (Good idea) */ for (i = 0; i < SAMPLES; i++) fft->WinTable[i] = ALPHA + ((1.0 - ALPHA) * cos (TWOPIoNm1 * (i - SAMPLES/2))); return fft; } void fft_dispose(fft_t *fft) { if (fft) { free(fft->PermuteTable); free(fft->SineTable); free(fft); } } /* * Apply some windowing function to the samples. */ void fft_window (fft_t *fft, complex_t wave[]) { int i; int bits = fft->bits; for (i = 0; i < SAMPLES; i++) { REAL(i) *= WINDOW(i); IMAG(i) *= WINDOW(i); } } /* * Calculate amplitude of component n in the decimated wave[] array. */ double fft_amp (int n, complex_t wave[], int bits) { n = PERMUTE (n, bits); return (hypot (REAL(n), IMAG(n))); } double fft_amp2 (fft_t *fft, int n, complex_t wave[]) { n = fft->PermuteTable[n & fft->bmask]; return (hypot (REAL(n), IMAG(n))); } /* * Scale sampled values. * Do this *before* the fft. */ void fft_scale (complex_t wave[], int bits) { int i, n = 1 << bits; double m = (double)1 / n; for (i = 0; i < n; i++) { wave[i].re *= m; wave[i].im *= m; } } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/visualizations/visualizations.h�����������������������������������������������0000644�0001750�0001750�00000002212�14647725152�020756� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * This file contains plugin entries for several visualization post plugins. */ #include <xine/xine_internal.h> void *oscope_init_plugin (xine_t *xine, const void *data); void *fftscope_init_plugin (xine_t *xine, const void *data); void *fftgraph_init_plugin (xine_t *xine, const void *data); void *tdaan_init_plugin (xine_t *xine, const void *data); ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/�������������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013401� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/xine_goom.c��������������������������������������������������������������0000644�0001750�0001750�00000044765�14647725152�015551� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * GOOM post plugin. * * first version by Mark Thomas * ported to post plugin architecture by Miguel Freitas * real work by goom author, JC Hoelt <jeko@free.fr>. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <stdlib.h> #include <time.h> #define LOG_MODULE "goom" #define LOG_VERBOSE /* #define LOG */ /* TJ. this is what my 32bit Linux running on a AMD Athlon II X2 240e (2 * 2800Mhz) performed @ 1280x720, 19 fps: goom: csc_method 0 min 8257 us avg 8308 us goom: csc_method 1 min 16312 us avg 16413 us goom: csc_method 2 min 5019 us avg 5134 us Seems gcc 4.5 has a very nice 64bit math emulation :-) */ #define BENCHMARK 1 #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/post.h> #include "goom.h" #define NUMSAMPLES 512 /* hardcoded into goom api */ #define FPS 14 #define GOOM_WIDTH 320 #define GOOM_HEIGHT 240 /* colorspace conversion methods */ static const char* const goom_csc_methods[]={ "Fast but not photorealistic", "Slow but looks better", "Mostly fast and good quality", NULL }; typedef struct post_plugin_goom_s post_plugin_goom_t; typedef struct post_class_goom_s post_class_goom_t; struct post_class_goom_s { post_class_t class; xine_t *xine; int width, height; int fps; int csc_method; }; struct post_plugin_goom_s { post_plugin_t post; /* private data */ xine_video_port_t *vo_port; post_out_t video_output; post_class_goom_t *class; /* private metronom for syncing the video */ metronom_t *metronom; /* goom context */ PluginInfo *goom; int data_idx; gint16 data [2][NUMSAMPLES]; audio_buffer_t buf; /* dummy buffer just to hold a copy of audio data */ int channels; int sample_rate; int samples_per_frame; int width_back, height_back; double ratio; int csc_method; int do_samples_skip; /* true = skipping samples, false reading samples*/ int left_to_read; /* data to read before switching modes*/ yuv_planes_t yuv; rgb2yuy2_t *rgb2yuy2; /* frame skipping */ int skip_frame; #ifdef BENCHMARK int benchmark_frames, benchmark_min, benchmark_time; #endif }; /* plugin class functions */ static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target); static void goom_class_dispose(post_class_t *class_gen); /* plugin instance functions */ static void goom_dispose(post_plugin_t *this_gen); /* rewire function */ static int goom_rewire_video(xine_post_out_t *output, void *data); static int goom_port_open(xine_audio_port_t *this, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode); static void goom_port_close(xine_audio_port_t *this, xine_stream_t *stream ); static void goom_port_put_buffer (xine_audio_port_t *this, audio_buffer_t *buf, xine_stream_t *stream); static void fps_changed_cb(void *data, xine_cfg_entry_t *cfg) { post_class_goom_t *class = (post_class_goom_t*) data; class->fps = cfg->num_value < 1 ? 1 : cfg->num_value > 50 ? 50 : cfg->num_value; } static void width_changed_cb(void *data, xine_cfg_entry_t *cfg) { post_class_goom_t *class = (post_class_goom_t*) data; class->width = cfg->num_value; } static void height_changed_cb(void *data, xine_cfg_entry_t *cfg) { post_class_goom_t *class = (post_class_goom_t*) data; class->height = cfg->num_value; } static void csc_method_changed_cb(void *data, xine_cfg_entry_t *cfg) { post_class_goom_t *class = (post_class_goom_t*) data; class->csc_method = cfg->num_value; } static void *goom_init_plugin (xine_t *xine, const void *data) { config_values_t *cfg; post_class_goom_t *this = calloc (1, sizeof (*this)); if (!this) return NULL; (void)data; this->class.open_plugin = goom_open_plugin; this->class.identifier = "goom"; this->class.description = N_("What a GOOM"); this->class.dispose = goom_class_dispose; this->xine = xine; cfg = xine->config; this->fps = cfg->register_num (cfg, "effects.goom.fps", FPS, _("frames per second to generate"), _("With more frames per second, the animation will get " "smoother and faster, but will also require more CPU power."), 10, fps_changed_cb, this); this->fps = this->fps < 1 ? 1 : this->fps > 50 ? 50 : this->fps; this->width = cfg->register_num (cfg, "effects.goom.width", GOOM_WIDTH, _("goom image width"), _("The width in pixels of the image to be generated."), 10, width_changed_cb, this); this->height = cfg->register_num (cfg, "effects.goom.height", GOOM_HEIGHT, _("goom image height"), _("The height in pixels of the image to be generated."), 10, height_changed_cb, this); this->csc_method = cfg->register_enum (cfg, "effects.goom.csc_method", 0, (char **)goom_csc_methods, _("colour space conversion method"), _("You can choose the colour space conversion method used by goom.\n" "The available selections should be self-explaining."), 20, csc_method_changed_cb, this); return &this->class; } static post_plugin_t *goom_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_plugin_goom_t *this = calloc(1, sizeof(post_plugin_goom_t)); post_class_goom_t *class = (post_class_goom_t*) class_gen; post_in_t *input; post_out_t *output; post_out_t *outputv; post_audio_port_t *port; if (!this || !video_target || !video_target[0] || !audio_target || !audio_target[0]) { free(this); return NULL; } (void)inputs; _x_post_init(&this->post, 1, 0); this->class = class; this->vo_port = video_target[0]; this->metronom = _x_metronom_init(1, 0, class->xine); lprintf("goom_open_plugin\n"); this->width_back = class->width; this->height_back = class->height; srand((unsigned int)time((time_t *)NULL)); this->goom = goom_init (this->width_back, this->height_back); this->ratio = (double)this->width_back/(double)this->height_back; this->buf.mem = NULL; this->buf.mem_size = 0; port = _x_post_intercept_audio_port(&this->post, audio_target[0], &input, &output); port->new_port.open = goom_port_open; port->new_port.close = goom_port_close; port->new_port.put_buffer = goom_port_put_buffer; outputv = &this->video_output; outputv->xine_out.name = "generated video"; outputv->xine_out.type = XINE_POST_DATA_VIDEO; outputv->xine_out.data = (xine_video_port_t **)&this->vo_port; outputv->xine_out.rewire = goom_rewire_video; outputv->post = &this->post; xine_list_push_back(this->post.output, outputv); this->post.xine_post.audio_input[0] = &port->new_port; this->post.dispose = goom_dispose; #ifdef __BIG_ENDIAN__ this->rgb2yuy2 = rgb2yuy2_alloc (10, "argb"); #else this->rgb2yuy2 = rgb2yuy2_alloc (10, "bgra"); #endif #ifdef BENCHMARK this->benchmark_frames = 200 - 1; this->benchmark_min = 10000000; this->benchmark_time = 0; #endif return &this->post; } static void goom_class_dispose(post_class_t *class_gen) { post_class_goom_t *this = (post_class_goom_t*) class_gen; this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, this, sizeof (*this)); free(class_gen); } static void goom_dispose(post_plugin_t *this_gen) { post_plugin_goom_t *this = (post_plugin_goom_t *)this_gen; if (_x_post_dispose(this_gen)) { rgb2yuy2_free (this->rgb2yuy2); goom_close(this->goom); this->metronom->exit(this->metronom); if(this->buf.mem) free(this->buf.mem); free(this); } } static int goom_rewire_video(xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_video_port_t *old_port = *(xine_video_port_t **)output_gen->data; xine_video_port_t *new_port = (xine_video_port_t *)data; post_plugin_goom_t *this = (post_plugin_goom_t *)output->post; if (!data) return 0; /* register our stream at the new output port */ old_port->close(old_port, XINE_ANON_STREAM); (new_port->open) (new_port, XINE_ANON_STREAM); /* reconnect ourselves */ this->vo_port = new_port; return 1; } static int goom_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_goom_t *this = (post_plugin_goom_t *)port->post; _x_post_rewire(&this->post); _x_post_inc_usage(port); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; this->channels = _x_ao_mode2channels(mode); this->sample_rate = rate; this->samples_per_frame = rate / this->class->fps; this->data_idx = 0; init_yuv_planes(&this->yuv, this->width_back, this->height_back); this->skip_frame = 0; this->do_samples_skip = 0; this->left_to_read = NUMSAMPLES; (this->vo_port->open) (this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, stream->metronom); #ifdef BENCHMARK this->benchmark_frames = 200 - 1; this->benchmark_min = 10000000; this->benchmark_time = 0; #endif return (port->original_port->open) (port->original_port, stream, bits, rate, mode ); } static void goom_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream ) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_goom_t *this = (post_plugin_goom_t *)port->post; free_yuv_planes(&this->yuv); port->stream = NULL; this->vo_port->close(this->vo_port, XINE_ANON_STREAM); this->metronom->set_master(this->metronom, NULL); port->original_port->close(port->original_port, stream ); _x_post_dec_usage(port); } #ifdef BENCHMARK static int now (void) { struct timeval tv; gettimeofday (&tv, NULL); return tv.tv_sec * 1000000 + tv.tv_usec; } #endif static void goom_port_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; post_plugin_goom_t *this = (post_plugin_goom_t *)port->post; vo_frame_t *frame; uint8_t *goom_frame, *goom_frame_end; int16_t *data; int8_t *data8; int64_t pts = buf->vpts; int i, j; uint8_t *dest_ptr; int width, height; int current_sample = 0; /* make a copy of buf data for private use */ if( this->buf.mem_size < buf->mem_size ) { this->buf.mem = realloc(this->buf.mem, buf->mem_size); this->buf.mem_size = buf->mem_size; } memcpy(this->buf.mem, buf->mem, buf->num_frames*this->channels*((port->bits == 8)?1:2)); this->buf.num_frames = buf->num_frames; /* pass data to original port */ port->original_port->put_buffer(port->original_port, buf, stream); /* we must not use original data anymore, it should have already being moved * to the fifo of free audio buffers. just use our private copy instead. */ buf = &this->buf; j = (this->channels >= 2) ? 1 : 0; while (current_sample < buf->num_frames) { if (this->do_samples_skip) { if (current_sample + this->left_to_read > buf->num_frames) { this->left_to_read -= (buf->num_frames-current_sample); break; } else { current_sample+=this->left_to_read; this->left_to_read = NUMSAMPLES; this->do_samples_skip = 0; } } else { if( port->bits == 8 ) { data8 = (int8_t *)buf->mem; data8 += current_sample * this->channels; /* scale 8 bit data to 16 bits and convert to signed as well */ for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames; i++, this->data_idx++,data8 += this->channels) { this->data[0][this->data_idx] = ((int16_t)data8[0] << 8) - 0x8000; this->data[1][this->data_idx] = ((int16_t)data8[j] << 8) - 0x8000; } } else { data = buf->mem; data += current_sample * this->channels; for ( i=current_sample ; this->data_idx < NUMSAMPLES && i < buf->num_frames; i++, this->data_idx++,data += this->channels) { this->data[0][this->data_idx] = data[0]; this->data[1][this->data_idx] = data[j]; } } if (this->data_idx < NUMSAMPLES) { this->left_to_read = NUMSAMPLES - this->data_idx; break; } else { _x_assert(this->data_idx == NUMSAMPLES); this->data_idx = 0; if (this->samples_per_frame > NUMSAMPLES) { current_sample += NUMSAMPLES; this->do_samples_skip = 1; this->left_to_read = this->samples_per_frame - NUMSAMPLES; } else { current_sample += this->samples_per_frame; this->left_to_read = NUMSAMPLES; } frame = this->vo_port->get_frame (this->vo_port, this->width_back, this->height_back, this->ratio, XINE_IMGFMT_YUY2, VO_BOTH_FIELDS); frame->extra_info->invalid = 1; frame->duration = 90000 * this->samples_per_frame / this->sample_rate; frame->pts = pts; this->metronom->got_video_frame(this->metronom, frame); if (!this->skip_frame) { #ifdef BENCHMARK int elapsed = 0; #endif /* Try to be fast */ goom_frame = (uint8_t *)goom_update (this->goom, this->data, 0, 0, NULL, NULL); dest_ptr = frame -> base[0]; goom_frame_end = goom_frame + 4 * (this->width_back * this->height_back); #ifdef BENCHMARK if (this->benchmark_frames >= 0) elapsed = -now (); #endif this->csc_method = this->class->csc_method; if (this->csc_method == 2) { if (!frame->proc_slice || (frame->height & 15)) { /* do all at once */ rgb2yuy2_slice (this->rgb2yuy2, goom_frame, 4 * this->width_back, frame->base[0], frame->pitches[0], this->width_back, this->height_back); } else { /* sliced. This is a double edged sword. On one hand, it is faster by using cache more effective. On the flipside, when vo loop drops this frame, all this goes in vain */ uint8_t *sptr[1]; int y, h = 16, p = 4 * this->width_back; for (y = 0; y < this->height_back; y += 16) { if (y + 16 > this->height_back) h = this->height_back & 15; sptr[0] = frame->base[0] + y * frame->pitches[0]; rgb2yuy2_slice (this->rgb2yuy2, goom_frame + y * p, p, sptr[0], frame->pitches[0], this->width_back, h); frame->proc_slice (frame, sptr); } } } #if defined(ARCH_X86) else if ((this->csc_method == 1) && (xine_mm_accel() & MM_ACCEL_X86_MMX)) { int plane_ptr = 0; while (goom_frame < goom_frame_end) { uint8_t r, g, b; /* don't take endianness into account since MMX is only available * on Intel processors */ b = *goom_frame; goom_frame++; g = *goom_frame; goom_frame++; r = *goom_frame; goom_frame += 2; this->yuv.y[plane_ptr] = COMPUTE_Y(r, g, b); this->yuv.u[plane_ptr] = COMPUTE_U(r, g, b); this->yuv.v[plane_ptr] = COMPUTE_V(r, g, b); plane_ptr++; } yuv444_to_yuy2(&this->yuv, frame->base[0], frame->pitches[0]); } #endif /* ARCH_X86 */ else { while (goom_frame < goom_frame_end) { uint8_t r1, g1, b1, r2, g2, b2; #ifdef __BIG_ENDIAN__ goom_frame ++; r1 = *goom_frame; goom_frame++; g1 = *goom_frame; goom_frame++; b1 = *goom_frame; goom_frame += 2; r2 = *goom_frame; goom_frame++; g2 = *goom_frame; goom_frame++; b2 = *goom_frame; goom_frame++; #else b1 = *goom_frame; goom_frame++; g1 = *goom_frame; goom_frame++; r1 = *goom_frame; goom_frame += 2; b2 = *goom_frame; goom_frame++; g2 = *goom_frame; goom_frame++; r2 = *goom_frame; goom_frame += 2; #endif *dest_ptr = COMPUTE_Y(r1, g1, b1); dest_ptr++; *dest_ptr = COMPUTE_U(r1, g1, b1); dest_ptr++; *dest_ptr = COMPUTE_Y(r2, g2, b2); dest_ptr++; *dest_ptr = COMPUTE_V(r2, g2, b2); dest_ptr++; } } #ifdef BENCHMARK if (this->benchmark_frames >= 0) { elapsed += now (); this->benchmark_time += elapsed; if (elapsed < this->benchmark_min) this->benchmark_min = elapsed; if (--this->benchmark_frames < 0) { xprintf (this->class->xine, XINE_VERBOSITY_DEBUG, "goom: csc_method %d min %d us avg %d us\n", this->csc_method, this->benchmark_min, this->benchmark_time / 200); } } #endif this->skip_frame = frame->draw(frame, XINE_ANON_STREAM); } else { frame->bad_frame = 1; frame->draw(frame, XINE_ANON_STREAM); _x_assert(this->skip_frame>0); this->skip_frame--; } frame->free(frame); width = this->class->width; height = this->class->height; if ((width != this->width_back) || (height != this->height_back)) { goom_close(this->goom); this->goom = goom_init (width, height); this->width_back = width; this->height_back = height; this->ratio = (double)width/(double)height; free_yuv_planes(&this->yuv); init_yuv_planes(&this->yuv, width, height); } } } } } /* plugin catalog information */ static const post_info_t goom_special_info = { .type = XINE_POST_TYPE_AUDIO_VISUALIZATION, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST | PLUGIN_MUST_PRELOAD, 10, "goom", XINE_VERSION_CODE, &goom_special_info, &goom_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; �����������xine-lib-1.2/src/post/goom/sound_tester.h�����������������������������������������������������������0000644�0001750�0001750�00000000327�14647725152�016272� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _SOUND_TESTER_H #define _SOUND_TESTER_H #include "goom_plugin_info.h" #include "goom_config.h" /** change les donnees du SoundInfo */ void evaluate_sound(gint16 data[2][512], SoundInfo *sndInfo); #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_core.c��������������������������������������������������������������0000644�0001750�0001750�00000112150�14647725152�015516� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** * file: goom_core.c * author: Jean-Christophe Hoelt (which is not so proud of it) * * Contains the core of goom's work. * * (c)2000-2003, by iOS-software. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <inttypes.h> #include "goom.h" #include "goom_tools.h" #include "goom_filters.h" #include "lines.h" #include "ifs.h" #include "tentacle3d.h" #include "gfontlib.h" #include "sound_tester.h" #include "goom_plugin_info.h" #include "goom_fx.h" /*#include "goomsl.h"*/ #include <xine/xine_internal.h> /* #define VERBOSE */ #define STOP_SPEED 128 /* TODO: put that as variable in PluginInfo */ #define TIME_BTW_CHG 300 static void choose_a_goom_line (PluginInfo *goomInfo, float *param1, float *param2, int *couleur, int *mode, float *amplitude, int isfar); static void update_message (PluginInfo *goomInfo, char *message); static void init_buffers(PluginInfo *goomInfo, int buffsize) { goomInfo->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128); memset (goomInfo->pixel, 0, buffsize * sizeof (guint32) + 128); goomInfo->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128); memset (goomInfo->back, 0, buffsize * sizeof (guint32) + 128); goomInfo->conv = (Pixel *) malloc (buffsize * sizeof (guint32) + 128); memset (goomInfo->conv, 0, buffsize * sizeof (guint32) + 128); goomInfo->outputBuf = goomInfo->conv; goomInfo->p1 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->pixel)) / 128) * 128); goomInfo->p2 = (Pixel *) ((1 + ((uintptr_t) (goomInfo->back)) / 128) * 128); } /************************** * INIT * **************************/ PluginInfo *goom_init (guint32 resx, guint32 resy) { PluginInfo *goomInfo = (PluginInfo*)malloc(sizeof(PluginInfo)); #ifdef VERBOSE printf ("GOOM: init (%d, %d);\n", resx, resy); #endif plugin_info_init(goomInfo,4); goomInfo->star_fx = flying_star_create(); goomInfo->star_fx.init(&goomInfo->star_fx, goomInfo); goomInfo->zoomFilter_fx = zoomFilterVisualFXWrapper_create (); goomInfo->zoomFilter_fx.init(&goomInfo->zoomFilter_fx, goomInfo); goomInfo->tentacles_fx = tentacle_fx_create(); goomInfo->tentacles_fx.init(&goomInfo->tentacles_fx, goomInfo); goomInfo->screen.width = resx; goomInfo->screen.height = resy; goomInfo->screen.size = resx * resy; goomInfo->convolve_fx = convolve_create(); goomInfo->convolve_fx.init(&goomInfo->convolve_fx, goomInfo); plugin_info_add_visual (goomInfo, 0, &goomInfo->zoomFilter_fx); plugin_info_add_visual (goomInfo, 1, &goomInfo->tentacles_fx); plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx); plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx); init_buffers(goomInfo, goomInfo->screen.size); goomInfo->gRandom = goom_random_init((uintptr_t)goomInfo->pixel); goomInfo->cycle = 0; goomInfo->ifs_fx = ifs_visualfx_create(); goomInfo->ifs_fx.init(&goomInfo->ifs_fx, goomInfo); goomInfo->gmline1 = goom_lines_init (goomInfo, resx, goomInfo->screen.height, GML_HLINE, goomInfo->screen.height, GML_BLACK, GML_CIRCLE, 0.4f * (float) goomInfo->screen.height, GML_VERT); goomInfo->gmline2 = goom_lines_init (goomInfo, resx, goomInfo->screen.height, GML_HLINE, 0, GML_BLACK, GML_CIRCLE, 0.2f * (float) goomInfo->screen.height, GML_RED); goomInfo->font = gfont_load (); /* goom_set_main_script(goomInfo, goomInfo->main_script_str); */ return goomInfo; } void goom_set_resolution (PluginInfo *goomInfo, guint32 resx, guint32 resy) { free (goomInfo->pixel); free (goomInfo->back); free (goomInfo->conv); goomInfo->screen.width = resx; goomInfo->screen.height = resy; goomInfo->screen.size = resx * resy; init_buffers(goomInfo, goomInfo->screen.size); /* init_ifs (goomInfo, resx, goomInfo->screen.height); */ goomInfo->ifs_fx.free(&goomInfo->ifs_fx); goomInfo->ifs_fx.init(&goomInfo->ifs_fx, goomInfo); goom_lines_set_res (goomInfo->gmline1, resx, goomInfo->screen.height); goom_lines_set_res (goomInfo->gmline2, resx, goomInfo->screen.height); } int goom_set_screenbuffer(PluginInfo *goomInfo, void *buffer) { goomInfo->outputBuf = (Pixel*)buffer; return 1; } /******************************************** * UPDATE * ******************************************** * WARNING: this is a 600 lines function ! (21-11-2003) */ guint32 *goom_update (PluginInfo *goomInfo, gint16 data[2][512], int forceMode, float fps, char *songTitle, char *message) { Pixel *return_val; guint32 pointWidth; guint32 pointHeight; int i; float largfactor; /* elargissement de l'intervalle d'évolution des points */ Pixel *tmp; ZoomFilterData *pzfd; /* test if the config has changed, update it if so */ pointWidth = (goomInfo->screen.width * 2) / 5; pointHeight = ((goomInfo->screen.height) * 2) / 5; /* ! etude du signal ... */ evaluate_sound (data, &(goomInfo->sound)); /* goom_execute_main_script(goomInfo); */ /* ! calcul du deplacement des petits points ... */ largfactor = goomInfo->sound.speedvar / 150.0f + goomInfo->sound.volume / 1.5f; if (largfactor > 1.5f) largfactor = 1.5f; goomInfo->update.decay_ifs--; if (goomInfo->update.decay_ifs > 0) goomInfo->update.ifs_incr += 2; if (goomInfo->update.decay_ifs == 0) goomInfo->update.ifs_incr = 0; if (goomInfo->update.recay_ifs) { goomInfo->update.ifs_incr -= 2; goomInfo->update.recay_ifs--; if ((goomInfo->update.recay_ifs == 0)&&(goomInfo->update.ifs_incr<=0)) goomInfo->update.ifs_incr = 1; } if (goomInfo->update.ifs_incr > 0) goomInfo->ifs_fx.apply(&goomInfo->ifs_fx, goomInfo->p2, goomInfo->p1, goomInfo); if (goomInfo->curGState->drawPoints) { for (i = 1; i * 15 <= goomInfo->sound.speedvar*80.0f + 15; i++) { goomInfo->update.loopvar += goomInfo->sound.speedvar*50 + 1; pointFilter (goomInfo, goomInfo->p1, YELLOW, ((pointWidth - 6.0f) * largfactor + 5.0f), ((pointHeight - 6.0f) * largfactor + 5.0f), i * 152.0f, 128.0f, goomInfo->update.loopvar + i * 2032); pointFilter (goomInfo, goomInfo->p1, ORANGE, ((pointWidth / 2) * largfactor) / i + 10.0f * i, ((pointHeight / 2) * largfactor) / i + 10.0f * i, 96.0f, i * 80.0f, goomInfo->update.loopvar / i); pointFilter (goomInfo, goomInfo->p1, VIOLET, ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i, ((pointHeight / 3 + 5.0f) * largfactor) / i + 10.0f * i, i + 122.0f, 134.0f, goomInfo->update.loopvar / i); pointFilter (goomInfo, goomInfo->p1, BLACK, ((pointHeight / 3) * largfactor + 20.0f), ((pointHeight / 3) * largfactor + 20.0f), 58.0f, i * 66.0f, goomInfo->update.loopvar / i); pointFilter (goomInfo, goomInfo->p1, WHITE, (pointHeight * largfactor + 10.0f * i) / i, (pointHeight * largfactor + 10.0f * i) / i, 66.0f, 74.0f, goomInfo->update.loopvar + i * 500); } } /* par défaut pas de changement de zoom */ pzfd = NULL; /* * Test forceMode */ #ifdef VERBOSE if (forceMode != 0) { printf ("forcemode = %d\n", forceMode); } #endif /* diminuer de 1 le temps de lockage */ /* note pour ceux qui n'ont pas suivis : le lockvar permet d'empecher un */ /* changement d'etat du plugin juste apres un autre changement d'etat. oki */ if (--goomInfo->update.lockvar < 0) goomInfo->update.lockvar = 0; /* on verifie qu'il ne se pas un truc interressant avec le son. */ if ((goomInfo->sound.timeSinceLastGoom == 0) || (forceMode > 0) || (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG)) { /* changement eventuel de mode */ if (goom_irand(goomInfo->gRandom,16) == 0) switch (goom_irand(goomInfo->gRandom,34)) { case 0: case 10: goomInfo->update.zoomFilterData.hypercosEffect = goom_irand(goomInfo->gRandom,2); /* fall through */ case 13: case 20: case 21: goomInfo->update.zoomFilterData.mode = WAVE_MODE; goomInfo->update.zoomFilterData.reverse = 0; goomInfo->update.zoomFilterData.waveEffect = (goom_irand(goomInfo->gRandom,3) == 0); if (goom_irand(goomInfo->gRandom,2)) goomInfo->update.zoomFilterData.vitesse = (goomInfo->update.zoomFilterData.vitesse + 127) >> 1; break; case 1: case 11: goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE; goomInfo->update.zoomFilterData.waveEffect = 0; goomInfo->update.zoomFilterData.hypercosEffect = 0; break; case 2: case 12: goomInfo->update.zoomFilterData.mode = AMULETTE_MODE; goomInfo->update.zoomFilterData.waveEffect = 0; goomInfo->update.zoomFilterData.hypercosEffect = 0; break; case 3: goomInfo->update.zoomFilterData.mode = WATER_MODE; goomInfo->update.zoomFilterData.waveEffect = 0; goomInfo->update.zoomFilterData.hypercosEffect = 0; break; case 4: case 14: goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE; goomInfo->update.zoomFilterData.waveEffect = 0; goomInfo->update.zoomFilterData.hypercosEffect = 0; break; case 5: case 15: case 22: goomInfo->update.zoomFilterData.mode = HYPERCOS1_MODE; goomInfo->update.zoomFilterData.waveEffect = 0; goomInfo->update.zoomFilterData.hypercosEffect = (goom_irand(goomInfo->gRandom,3) == 0); break; case 6: case 16: goomInfo->update.zoomFilterData.mode = HYPERCOS2_MODE; goomInfo->update.zoomFilterData.waveEffect = 0; goomInfo->update.zoomFilterData.hypercosEffect = 0; break; case 7: case 17: goomInfo->update.zoomFilterData.mode = CRYSTAL_BALL_MODE; goomInfo->update.zoomFilterData.waveEffect = (goom_irand(goomInfo->gRandom,4) == 0); goomInfo->update.zoomFilterData.hypercosEffect = goom_irand(goomInfo->gRandom,2); break; case 8: case 18: case 19: goomInfo->update.zoomFilterData.mode = SCRUNCH_MODE; goomInfo->update.zoomFilterData.waveEffect = 1; goomInfo->update.zoomFilterData.hypercosEffect = 1; break; case 29: case 30: goomInfo->update.zoomFilterData.mode = YONLY_MODE; break; case 31: case 32: case 33: goomInfo->update.zoomFilterData.mode = SPEEDWAY_MODE; break; default: goomInfo->update.zoomFilterData.mode = NORMAL_MODE; goomInfo->update.zoomFilterData.waveEffect = 0; goomInfo->update.zoomFilterData.hypercosEffect = 0; } } /* tout ceci ne sera fait qu'en cas de non-blocage */ if (goomInfo->update.lockvar == 0) { /* reperage de goom (acceleration forte de l'acceleration du volume) */ /* -> coup de boost de la vitesse si besoin.. */ if (goomInfo->sound.timeSinceLastGoom == 0) { int i; goomInfo->update.goomvar++; /* SELECTION OF THE GOOM STATE */ if ((!goomInfo->update.stateSelectionBlocker)&&(goom_irand(goomInfo->gRandom,3))) { goomInfo->update.stateSelectionRnd = goom_irand(goomInfo->gRandom,goomInfo->statesRangeMax); goomInfo->update.stateSelectionBlocker = 3; } else if (goomInfo->update.stateSelectionBlocker) goomInfo->update.stateSelectionBlocker--; for (i=0;i<goomInfo->statesNumber;i++) if ((goomInfo->update.stateSelectionRnd >= goomInfo->states[i].rangemin) && (goomInfo->update.stateSelectionRnd <= goomInfo->states[i].rangemax)) goomInfo->curGState = &(goomInfo->states[i]); if ((goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr<=0)) { goomInfo->update.recay_ifs = 5; goomInfo->update.ifs_incr = 11; } if ((!goomInfo->curGState->drawIFS) && (goomInfo->update.ifs_incr>0) && (goomInfo->update.decay_ifs<=0)) goomInfo->update.decay_ifs = 100; if (!goomInfo->curGState->drawScope) goomInfo->update.stop_lines = 0xf000 & 5; if (!goomInfo->curGState->drawScope) { goomInfo->update.stop_lines = 0; goomInfo->update.lineMode = goomInfo->update.drawLinesDuration; } /* if (goomInfo->update.goomvar % 1 == 0) */ { guint32 vtmp; guint32 newvit; goomInfo->update.lockvar = 50; newvit = STOP_SPEED + 1 - ((float)3.5f * log10(goomInfo->sound.speedvar * 60 + 1)); /* retablir le zoom avant.. */ if ((goomInfo->update.zoomFilterData.reverse) && (!(goomInfo->cycle % 13)) && (rand () % 5 == 0)) { goomInfo->update.zoomFilterData.reverse = 0; goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 2; goomInfo->update.lockvar = 75; } if (goom_irand(goomInfo->gRandom,10) == 0) { goomInfo->update.zoomFilterData.reverse = 1; goomInfo->update.lockvar = 100; } if (goom_irand(goomInfo->gRandom,10) == 0) goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1; if (goom_irand(goomInfo->gRandom,12) == 0) goomInfo->update.zoomFilterData.vitesse = STOP_SPEED + 1; /* changement de milieu.. */ switch (goom_irand(goomInfo->gRandom,25)) { case 0: case 3: case 6: goomInfo->update.zoomFilterData.middleY = goomInfo->screen.height - 1; goomInfo->update.zoomFilterData.middleX = goomInfo->screen.width / 2; break; case 1: case 4: goomInfo->update.zoomFilterData.middleX = goomInfo->screen.width - 1; break; case 2: case 5: goomInfo->update.zoomFilterData.middleX = 1; break; default: goomInfo->update.zoomFilterData.middleY = goomInfo->screen.height / 2; goomInfo->update.zoomFilterData.middleX = goomInfo->screen.width / 2; } if ((goomInfo->update.zoomFilterData.mode == WATER_MODE) || (goomInfo->update.zoomFilterData.mode == YONLY_MODE) || (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE)) { goomInfo->update.zoomFilterData.middleX = goomInfo->screen.width / 2; goomInfo->update.zoomFilterData.middleY = goomInfo->screen.height / 2; } switch (vtmp = (goom_irand(goomInfo->gRandom,15))) { case 0: goomInfo->update.zoomFilterData.vPlaneEffect = goom_irand(goomInfo->gRandom,3) - goom_irand(goomInfo->gRandom,3); goomInfo->update.zoomFilterData.hPlaneEffect = goom_irand(goomInfo->gRandom,3) - goom_irand(goomInfo->gRandom,3); break; case 3: goomInfo->update.zoomFilterData.vPlaneEffect = 0; goomInfo->update.zoomFilterData.hPlaneEffect = goom_irand(goomInfo->gRandom,8) - goom_irand(goomInfo->gRandom,8); break; case 4: case 5: case 6: case 7: goomInfo->update.zoomFilterData.vPlaneEffect = goom_irand(goomInfo->gRandom,5) - goom_irand(goomInfo->gRandom,5); goomInfo->update.zoomFilterData.hPlaneEffect = -goomInfo->update.zoomFilterData.vPlaneEffect; break; case 8: goomInfo->update.zoomFilterData.hPlaneEffect = 5 + goom_irand(goomInfo->gRandom,8); goomInfo->update.zoomFilterData.vPlaneEffect = -goomInfo->update.zoomFilterData.hPlaneEffect; break; case 9: goomInfo->update.zoomFilterData.vPlaneEffect = 5 + goom_irand(goomInfo->gRandom,8); goomInfo->update.zoomFilterData.hPlaneEffect = -goomInfo->update.zoomFilterData.hPlaneEffect; break; case 13: goomInfo->update.zoomFilterData.hPlaneEffect = 0; goomInfo->update.zoomFilterData.vPlaneEffect = goom_irand(goomInfo->gRandom,10) - goom_irand(goomInfo->gRandom,10); break; case 14: goomInfo->update.zoomFilterData.hPlaneEffect = goom_irand(goomInfo->gRandom,10) - goom_irand(goomInfo->gRandom,10); goomInfo->update.zoomFilterData.vPlaneEffect = goom_irand(goomInfo->gRandom,10) - goom_irand(goomInfo->gRandom,10); break; default: if (vtmp < 10) { goomInfo->update.zoomFilterData.vPlaneEffect = 0; goomInfo->update.zoomFilterData.hPlaneEffect = 0; } } if (goom_irand(goomInfo->gRandom,5) != 0) goomInfo->update.zoomFilterData.noisify = 0; else { goomInfo->update.zoomFilterData.noisify = goom_irand(goomInfo->gRandom,2) + 1; goomInfo->update.lockvar *= 2; } if (goomInfo->update.zoomFilterData.mode == AMULETTE_MODE) { goomInfo->update.zoomFilterData.vPlaneEffect = 0; goomInfo->update.zoomFilterData.hPlaneEffect = 0; goomInfo->update.zoomFilterData.noisify = 0; } if ((goomInfo->update.zoomFilterData.middleX == 1) || (goomInfo->update.zoomFilterData.middleX == (signed int)goomInfo->screen.width - 1)) { goomInfo->update.zoomFilterData.vPlaneEffect = 0; if (goom_irand(goomInfo->gRandom,2)) goomInfo->update.zoomFilterData.hPlaneEffect = 0; } if ((signed int)newvit < goomInfo->update.zoomFilterData.vitesse) /* on accelere */ { pzfd = &goomInfo->update.zoomFilterData; if (((newvit < STOP_SPEED - 7) && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 6) && (goomInfo->cycle % 3 == 0)) || (goom_irand(goomInfo->gRandom,40) == 0)) { goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - goom_irand(goomInfo->gRandom,2) + goom_irand(goomInfo->gRandom,2); goomInfo->update.zoomFilterData.reverse = !goomInfo->update.zoomFilterData.reverse; } else { goomInfo->update.zoomFilterData.vitesse = (newvit + goomInfo->update.zoomFilterData.vitesse * 7) / 8; } goomInfo->update.lockvar += 50; } } if (goomInfo->update.lockvar > 150) { goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount; goomInfo->update.switchMult = 1.0f; } } /* mode mega-lent */ if (goom_irand(goomInfo->gRandom,700) == 0) { /* * printf ("coup du sort...\n") ; */ pzfd = &goomInfo->update.zoomFilterData; goomInfo->update.zoomFilterData.vitesse = STOP_SPEED - 1; goomInfo->update.zoomFilterData.pertedec = 8; goomInfo->update.zoomFilterData.sqrtperte = 16; goomInfo->update.goomvar = 1; goomInfo->update.lockvar += 50; goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount; goomInfo->update.switchMult = 1.0f; } } /* * gros frein si la musique est calme */ if ((goomInfo->sound.speedvar < 0.01f) && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 4) && (goomInfo->cycle % 16 == 0)) { pzfd = &goomInfo->update.zoomFilterData; goomInfo->update.zoomFilterData.vitesse += 3; goomInfo->update.zoomFilterData.pertedec = 8; goomInfo->update.zoomFilterData.sqrtperte = 16; goomInfo->update.goomvar = 0; } /* * baisser regulierement la vitesse... */ if ((goomInfo->cycle % 73 == 0) && (goomInfo->update.zoomFilterData.vitesse < STOP_SPEED - 5)) { pzfd = &goomInfo->update.zoomFilterData; goomInfo->update.zoomFilterData.vitesse++; } /* * arreter de decrémenter au bout d'un certain temps */ if ((goomInfo->cycle % 101 == 0) && (goomInfo->update.zoomFilterData.pertedec == 7)) { pzfd = &goomInfo->update.zoomFilterData; goomInfo->update.zoomFilterData.pertedec = 8; goomInfo->update.zoomFilterData.sqrtperte = 16; } /* * Permet de forcer un effet. */ if ((forceMode > 0) && (forceMode <= NB_FX)) { pzfd = &goomInfo->update.zoomFilterData; pzfd->mode = forceMode - 1; } if (forceMode == -1) { pzfd = NULL; } /* * Changement d'effet de zoom ! */ if (pzfd != NULL) { int dif; goomInfo->update.cyclesSinceLastChange = 0; goomInfo->update.switchIncr = goomInfo->update.switchIncrAmount; dif = goomInfo->update.zoomFilterData.vitesse - goomInfo->update.previousZoomSpeed; if (dif < 0) dif = -dif; if (dif > 2) { goomInfo->update.switchIncr *= (dif + 2) / 2; } goomInfo->update.previousZoomSpeed = goomInfo->update.zoomFilterData.vitesse; goomInfo->update.switchMult = 1.0f; if (((goomInfo->sound.timeSinceLastGoom == 0) && (goomInfo->sound.totalgoom < 2)) || (forceMode > 0)) { goomInfo->update.switchIncr = 0; goomInfo->update.switchMult = goomInfo->update.switchMultAmount; } } else { if (goomInfo->update.cyclesSinceLastChange > TIME_BTW_CHG) { pzfd = &goomInfo->update.zoomFilterData; goomInfo->update.cyclesSinceLastChange = 0; } else goomInfo->update.cyclesSinceLastChange++; } #ifdef VERBOSE if (pzfd) { printf ("GOOM: pzfd->mode = %d\n", pzfd->mode); } #endif /* Zoom here ! */ zoomFilterFastRGB (goomInfo, goomInfo->p1, goomInfo->p2, pzfd, goomInfo->screen.width, goomInfo->screen.height, goomInfo->update.switchIncr, goomInfo->update.switchMult); /* * Affichage tentacule */ goomInfo->tentacles_fx.apply(&goomInfo->tentacles_fx, goomInfo->p1, goomInfo->p2, goomInfo); goomInfo->star_fx.apply (&goomInfo->star_fx,goomInfo->p2,goomInfo->p1,goomInfo); /* * Affichage de texte */ { /*char title[1024];*/ char text[64]; /* * Le message */ update_message (goomInfo, message); if (fps > 0) { sprintf (text, "%2.0f fps", fps); goom_draw_text (goomInfo->font, goomInfo->p1,goomInfo->screen.width,goomInfo->screen.height, 10, 24, text, 1, 0); } /* * Le titre */ if (songTitle != NULL) { strncpy (goomInfo->update.titleText, songTitle, 1023); goomInfo->update.titleText[1023]=0; goomInfo->update.timeOfTitleDisplay = 200; } if (goomInfo->update.timeOfTitleDisplay) { goom_draw_text (goomInfo->font, goomInfo->p1,goomInfo->screen.width,goomInfo->screen.height, goomInfo->screen.width / 2, goomInfo->screen.height / 2 + 7, goomInfo->update.titleText, ((float) (190 - goomInfo->update.timeOfTitleDisplay) / 10.0f), 1); goomInfo->update.timeOfTitleDisplay--; if (goomInfo->update.timeOfTitleDisplay < 4) goom_draw_text (goomInfo->font, goomInfo->p2,goomInfo->screen.width,goomInfo->screen.height, goomInfo->screen.width / 2, goomInfo->screen.height / 2 + 7, goomInfo->update.titleText, ((float) (190 - goomInfo->update.timeOfTitleDisplay) / 10.0f), 1); } } /* * Gestion du Scope */ /* * arret demande */ if ((goomInfo->update.stop_lines & 0xf000)||(!goomInfo->curGState->drawScope)) { float param1, param2, amplitude; int couleur; int mode; choose_a_goom_line (goomInfo, ¶m1, ¶m2, &couleur, &mode, &litude,1); couleur = GML_BLACK; goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude, couleur); goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude, couleur); goomInfo->update.stop_lines &= 0x0fff; } /* * arret aleatore.. changement de mode de ligne.. */ if (goomInfo->update.lineMode != goomInfo->update.drawLinesDuration) { goomInfo->update.lineMode--; if (goomInfo->update.lineMode == -1) goomInfo->update.lineMode = 0; } else if ((goomInfo->cycle%80==0)&&(goom_irand(goomInfo->gRandom,5)==0)&&goomInfo->update.lineMode) goomInfo->update.lineMode--; if ((goomInfo->cycle % 120 == 0) && (goom_irand(goomInfo->gRandom,4) == 0) && (goomInfo->curGState->drawScope)) { if (goomInfo->update.lineMode == 0) goomInfo->update.lineMode = goomInfo->update.drawLinesDuration; else if (goomInfo->update.lineMode == goomInfo->update.drawLinesDuration) { float param1, param2, amplitude; int couleur1,couleur2; int mode; goomInfo->update.lineMode--; choose_a_goom_line (goomInfo, ¶m1, ¶m2, &couleur1, &mode, &litude,goomInfo->update.stop_lines); couleur2 = 5-couleur1; if (goomInfo->update.stop_lines) { goomInfo->update.stop_lines--; if (goom_irand(goomInfo->gRandom,2)) couleur2=couleur1 = GML_BLACK; } goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude, couleur1); goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude, couleur2); } } /* * si on est dans un goom : afficher les lignes... */ if ((goomInfo->update.lineMode != 0) || (goomInfo->sound.timeSinceLastGoom < 5)) { goomInfo->gmline2->power = goomInfo->gmline1->power; goom_lines_draw (goomInfo, goomInfo->gmline1, data[0], goomInfo->p2); goom_lines_draw (goomInfo, goomInfo->gmline2, data[1], goomInfo->p2); if (((goomInfo->cycle % 121) == 9) && (goom_irand(goomInfo->gRandom,3) == 1) && ((goomInfo->update.lineMode == 0) || (goomInfo->update.lineMode == goomInfo->update.drawLinesDuration))) { float param1, param2, amplitude; int couleur1,couleur2; int mode; choose_a_goom_line (goomInfo, ¶m1, ¶m2, &couleur1, &mode, &litude, goomInfo->update.stop_lines); couleur2 = 5-couleur1; if (goomInfo->update.stop_lines) { goomInfo->update.stop_lines--; if (goom_irand(goomInfo->gRandom,2)) couleur2=couleur1 = GML_BLACK; } goom_lines_switch_to (goomInfo->gmline1, mode, param1, amplitude, couleur1); goom_lines_switch_to (goomInfo->gmline2, mode, param2, amplitude, couleur2); } } return_val = goomInfo->p1; tmp = goomInfo->p1; goomInfo->p1 = goomInfo->p2; goomInfo->p2 = tmp; /* affichage et swappage des buffers.. */ goomInfo->cycle++; /* xine: no convolve_fx */ /* goomInfo->convolve_fx.apply(&goomInfo->convolve_fx,return_val,goomInfo->outputBuf,goomInfo); */ xine_fast_memcpy(goomInfo->outputBuf, return_val, goomInfo->screen.size * sizeof(Pixel)); return (guint32*)goomInfo->outputBuf; } /**************************************** * CLOSE * ****************************************/ void goom_close (PluginInfo *goomInfo) { if (goomInfo->pixel != NULL) free (goomInfo->pixel); if (goomInfo->back != NULL) free (goomInfo->back); if (goomInfo->conv != NULL) free (goomInfo->conv); goomInfo->pixel = goomInfo->back = NULL; goomInfo->conv = NULL; goom_random_free(goomInfo->gRandom); goom_lines_free (&goomInfo->gmline1); goom_lines_free (&goomInfo->gmline2); /* release_ifs (); */ goomInfo->ifs_fx.free(&goomInfo->ifs_fx); goomInfo->convolve_fx.free(&goomInfo->convolve_fx); goomInfo->star_fx.free(&goomInfo->star_fx); goomInfo->tentacles_fx.free(&goomInfo->tentacles_fx); goomInfo->zoomFilter_fx.free(&goomInfo->zoomFilter_fx); /* if (goomInfo->scanner) gsl_free(goomInfo->scanner); if (goomInfo->main_scanner) gsl_free(goomInfo->main_scanner); */ gfont_unload(&goomInfo->font); free(goomInfo->params); free(goomInfo->visuals); free(goomInfo->sound.params.params); free(goomInfo); } /* *** */ void choose_a_goom_line (PluginInfo *goomInfo, float *param1, float *param2, int *couleur, int *mode, float *amplitude, int isfar) { *mode = goom_irand(goomInfo->gRandom,3); *amplitude = 1.0f; switch (*mode) { case GML_CIRCLE: if (isfar) { *param1 = *param2 = 0.47f; *amplitude = 0.8f; break; } if (goom_irand(goomInfo->gRandom,3) == 0) { *param1 = *param2 = 0; *amplitude = 3.0f; } else if (goom_irand(goomInfo->gRandom,2)) { *param1 = 0.40f * goomInfo->screen.height; *param2 = 0.22f * goomInfo->screen.height; } else { *param1 = *param2 = goomInfo->screen.height * 0.35; } break; case GML_HLINE: if (goom_irand(goomInfo->gRandom,4) || isfar) { *param1 = goomInfo->screen.height / 7; *param2 = 6.0f * goomInfo->screen.height / 7.0f; } else { *param1 = *param2 = goomInfo->screen.height / 2.0f; *amplitude = 2.0f; } break; case GML_VLINE: if (goom_irand(goomInfo->gRandom,3) || isfar) { *param1 = goomInfo->screen.width / 7.0f; *param2 = 6.0f * goomInfo->screen.width / 7.0f; } else { *param1 = *param2 = goomInfo->screen.width / 2.0f; *amplitude = 1.5f; } break; default: *param1 = *param2 = 0; break; } *couleur = goom_irand(goomInfo->gRandom,6); } #define ECART_VARIATION 1.5 #define POS_VARIATION 3.0 #define SCROLLING_SPEED 80 /* * Met a jour l'affichage du message defilant */ void update_message (PluginInfo *goomInfo, char *message) { int fin = 0; if (message) { int i=1,j=0; strlcpy(goomInfo->update_message.message, message, sizeof(goomInfo->update_message.message)); for (j=0;goomInfo->update_message.message[j];j++) if (goomInfo->update_message.message[j]=='\n') i++; goomInfo->update_message.numberOfLinesInMessage = i; goomInfo->update_message.affiche = goomInfo->screen.height + goomInfo->update_message.numberOfLinesInMessage * 25 + 105; goomInfo->update_message.longueur = strlen(goomInfo->update_message.message); } if (goomInfo->update_message.affiche) { int i = 0; char *msg = malloc(goomInfo->update_message.longueur + 1); char *ptr = msg; int pos; float ecart; strncpy(msg, goomInfo->update_message.message, goomInfo->update_message.longueur); message = msg; while (!fin) { while (1) { if (*ptr == 0) { fin = 1; break; } if (*ptr == '\n') { *ptr = 0; break; } ++ptr; } pos = goomInfo->update_message.affiche - (goomInfo->update_message.numberOfLinesInMessage - i)*25; pos += POS_VARIATION * (cos((double)pos / 20.0)); pos -= SCROLLING_SPEED; ecart = (ECART_VARIATION * sin((double)pos / 20.0)); if ((fin) && (2 * pos < (int)goomInfo->screen.height)) pos = (int)goomInfo->screen.height / 2; pos += 7; goom_draw_text(goomInfo->font, goomInfo->p1,goomInfo->screen.width,goomInfo->screen.height, goomInfo->screen.width/2, pos, message, ecart, 1); message = ++ptr; i++; } goomInfo->update_message.affiche --; free (msg); } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_config_param.h������������������������������������������������������0000644�0001750�0001750�00000005046�14647725152�017225� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _CONFIG_PARAM_H #define _CONFIG_PARAM_H #include <stdlib.h> /** * File created on 2003-05-24 by Jeko. * (c)2003, JC Hoelt for iOS-software. * * LGPL Licence. */ typedef enum { PARAM_INTVAL, PARAM_FLOATVAL, PARAM_BOOLVAL, PARAM_STRVAL, PARAM_LISTVAL, } ParamType; struct IntVal { int value; int min; int max; int step; }; struct FloatVal { float value; float min; float max; float step; }; struct StrVal { char *value; }; struct ListVal { char *value; int nbChoices; char **choices; }; struct BoolVal { int value; }; typedef struct _PARAM { const char *name; const char *desc; char rw; ParamType type; union { struct IntVal ival; struct FloatVal fval; struct StrVal sval; struct ListVal slist; struct BoolVal bval; } param; /* used by the core to inform the GUI of a change */ void (*change_listener)(struct _PARAM *_this); /* used by the GUI to inform the core of a change */ void (*changed)(struct _PARAM *_this); void *user_data; /* can be used by the GUI */ } PluginParam; #define IVAL(p) ((p).param.ival.value) #define SVAL(p) ((p).param.sval.value) #define FVAL(p) ((p).param.fval.value) #define BVAL(p) ((p).param.bval.value) #define LVAL(p) ((p).param.slist.value) #define FMIN(p) ((p).param.fval.min) #define FMAX(p) ((p).param.fval.max) #define FSTEP(p) ((p).param.fval.step) #define IMIN(p) ((p).param.ival.min) #define IMAX(p) ((p).param.ival.max) #define ISTEP(p) ((p).param.ival.step) PluginParam goom_secure_f_param(const char *name); PluginParam goom_secure_i_param(const char *name); PluginParam goom_secure_b_param(const char *name, int value); PluginParam goom_secure_s_param(const char *name); PluginParam goom_secure_f_feedback(const char *name); PluginParam goom_secure_i_feedback(const char *name); void goom_set_str_param_value(PluginParam *p, const char *str); void goom_set_list_param_value(PluginParam *p, const char *str); typedef struct _PARAMETERS { const char *name; const char *desc; int nbParams; PluginParam **params; } PluginParameters; PluginParameters goom_plugin_parameters(const char *name, int nb); #define secure_f_param goom_secure_f_param #define secure_i_param goom_secure_i_param #define secure_b_param goom_secure_b_param #define secure_s_param goom_secure_s_param #define secure_f_feedback goom_secure_f_feedback #define secure_i_feedback goom_secure_i_feedback #define set_list_param_value goom_set_list_param_value #define set_str_param_value goom_set_str_param_value #define plugin_parameters goom_plugin_parameters #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/motif_goom2.h������������������������������������������������������������0000644�0001750�0001750�00000141352�14647725152�016001� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static const union { const unsigned char u8[sizeof(Motif)]; const Motif motif; } CONV_MOTIF2 = {{ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,12,5,14, 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,12,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,10,1,14, 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,10,0,12,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,6,0,12, 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,7,0,8,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,13,2,0,10, 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,6,0,2,14,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,5,0,0,10, 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,9,0,0,12,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,14,9,0,0,1,14, 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,8,0,0,8,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,14,8,3,0,0,0,9,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,11,0,0,2,14,15,15,15,15,15,15,15,15,15,15, 15,15,15,13,9,5,3,4,1,0,0,0,0,7,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,14,4,0,0,4,11,13,13,15,15,14,12,10,8,5, 6,4,1,0,0,0,0,0,0,0,0,0,0,14,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,12,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,9,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, 13,9,10,13,14,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,12,3,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,2,5,6,0,0,0,0,12,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, 5,0,0,0,3,10,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,14,9,2,1,0,0,0,1,4,6,6,1, 0,0,0,8,13,15,15,15,12,1,0,2,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,14, 2,0,0,0,0,0,4,12,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,3,0,0,10,15,15,15,10, 0,0,4,15,15,15,15,15,15,2,0,6,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,5, 3,11,5,0,0,0,0,0,4,11,14,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,7,0,0,13,15,15,15,11, 0,0,7,15,15,15,15,15,15,1,0,9,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,9,0, 13,15,15,12,5,0,0,0,0,0,1,8,14,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,7,0,1,14,15,15,15,11, 0,0,7,15,15,15,15,15,14,0,0,9,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,11,1,10, 15,15,15,15,15,11,5,0,0,0,0,0,1,6,13,15, 15,15,15,15,14,8,11,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,6,0,2,15,15,15,15,11, 0,0,6,15,15,15,15,15,13,0,0,11,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,11,1,6,15, 15,15,15,15,15,15,15,14,5,0,0,0,0,0,0,6, 14,15,15,15,6,0,4,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,7,0,5,15,15,15,15,11, 0,0,5,15,15,15,15,15,12,0,0,12,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,13,2,1,13,15, 15,15,15,15,15,15,15,15,15,12,2,0,0,0,0,0, 1,6,11,7,0,0,4,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,7,0,7,15,15,15,15,11, 0,0,6,15,15,15,15,15,12,0,0,12,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,5,0,7,15,15, 15,15,15,15,15,15,15,15,15,15,15,11,5,0,0,0, 0,0,0,0,0,1,11,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,7,0,10,15,15,15,15,11, 0,0,6,15,15,15,15,15,12,0,0,12,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,10,0,4,14,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,13,7,0, 0,0,0,0,0,1,6,12,14,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,7,0,10,15,15,15,15,11, 0,0,7,15,15,15,15,15,12,0,0,12,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,13,1,1,12,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13, 5,0,0,0,0,0,0,0,3,10,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,7,0,10,15,15,15,15,11, 0,0,7,15,15,15,15,15,11,0,0,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,14,4,0,8,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 13,0,0,0,1,0,0,0,0,1,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,7,0,10,15,15,15,15,11, 0,0,8,15,15,15,15,15,8,0,2,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,9,0,4,14,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,14, 4,0,0,5,13,12,6,2,0,2,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,7,0,10,15,15,15,15,11, 0,0,7,15,15,15,15,15,4,0,4,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,13,1,1,13,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,11, 0,0,1,13,15,15,15,14,9,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,5,0,6,15,15,15,15,11, 0,0,8,15,15,15,15,15,2,0,8,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,5,0,9,15,15,15,15,15,15, 15,15,15,15,15,15,14,11,15,15,15,15,15,15,15,9, 0,0,10,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,4,0,4,15,15,15,15,11, 0,0,7,15,15,15,15,13,0,0,11,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,10,0,3,14,15,15,15,15,15,15, 15,15,15,15,15,14,3,0,13,15,15,15,15,15,15,14, 9,11,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,4,0,4,15,15,15,15,11, 0,0,8,15,15,15,15,12,0,0,12,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,14,2,1,12,15,15,15,15,15,15,15, 15,15,15,15,14,3,0,0,9,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,6,0,3,15,15,15,15,13, 1,0,8,15,15,15,15,12,0,0,12,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,9,0,5,15,15,15,15,15,15,15,15, 15,15,15,14,4,0,0,0,10,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,8,0,2,15,15,15,15,15, 3,0,13,15,15,15,15,12,0,0,12,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,13,2,1,12,15,15,15,15,15,15,15,15, 15,15,15,7,0,0,0,0,8,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,10,0,1,14,15,15,15,15, 11,5,15,15,15,15,15,12,0,0,11,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,6,0,7,15,15,15,15,15,15,15,15,15, 15,15,8,0,0,0,0,0,0,9,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,12,0,0,12,15,15,15,15, 15,14,15,15,15,15,15,10,0,0,12,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,13,1,2,14,15,15,15,15,15,15,15,15,15, 15,10,0,0,0,6,6,0,0,0,5,12,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,12,12, 15,15,15,15,15,15,15,15,13,0,0,11,15,15,15,15, 15,15,15,15,15,15,15,9,0,1,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,7,0,8,15,15,15,15,15,15,15,15,15,15, 15,9,0,0,4,15,15,8,0,0,0,1,5,13,15,15, 15,15,15,15,15,15,15,15,15,15,12,8,7,6,5,3, 3,3,4,12,15,15,15,15,15,15,15,15,15,7,0,6, 15,15,15,15,15,15,15,15,14,1,0,10,15,15,15,15, 15,15,15,15,15,15,15,6,0,3,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,13,1,0,13,15,15,15,15,15,15,15,15,15,15, 15,14,7,8,13,15,15,15,11,2,0,0,0,0,5,11, 15,15,15,15,15,15,15,15,13,3,0,0,0,0,0,0, 0,0,0,5,15,15,15,15,15,15,15,15,12,1,0,0, 3,11,15,15,15,15,15,15,13,1,0,10,15,15,15,15, 15,15,15,15,15,15,15,3,0,5,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,9,0,5,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,14,8,1,0,0,0,0, 4,12,15,15,15,15,15,15,4,0,0,0,0,0,0,0, 0,0,0,2,15,15,15,15,15,15,15,14,4,0,0,0, 0,0,9,15,15,15,15,15,14,1,0,10,15,15,15,15, 15,15,15,15,15,15,15,2,0,9,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,14,4,0,11,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,14,8,2,0,0, 0,0,4,10,14,15,15,15,4,0,0,0,0,0,0,0, 0,0,0,3,15,15,15,15,15,15,15,6,0,0,0,2, 3,0,0,8,15,15,15,15,14,1,0,10,15,15,15,15, 15,15,15,15,15,15,15,1,0,9,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, 14,5,0,4,14,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,14,9,3, 0,0,0,0,2,5,10,15,5,0,1,11,11,12,13,15, 11,0,0,7,15,15,15,15,15,15,8,0,0,0,1,12, 14,6,0,0,7,14,15,15,14,1,0,9,15,15,15,15, 15,15,15,15,15,15,15,2,0,10,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, 9,0,1,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,14, 10,2,0,0,0,0,1,14,4,0,1,14,15,15,15,15, 9,0,0,9,15,15,15,15,15,9,0,0,0,0,9,15, 15,15,7,0,0,6,14,15,15,3,0,6,15,15,15,15, 15,15,15,15,15,15,15,1,0,9,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,9, 0,0,1,10,14,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,13,1,0,0,0,1,14,3,0,0,14,15,15,15,15, 5,0,0,11,15,15,15,15,13,1,0,0,0,6,15,15, 15,15,15,8,0,0,2,10,15,6,0,3,15,15,15,15, 15,15,15,15,15,15,15,2,0,10,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,13,1, 0,0,0,0,3,9,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,6,1,0,0,0,8,15,1,0,0,14,15,15,15,15, 4,0,0,13,15,15,15,14,4,0,0,0,3,14,15,15, 15,15,15,15,5,0,0,1,14,9,0,1,14,15,15,15, 15,15,15,15,15,15,15,1,0,9,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,13,1, 0,0,0,0,0,0,4,12,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 9,0,0,0,0,7,15,15,1,0,0,14,15,15,15,14, 2,0,1,14,15,15,15,12,0,0,0,3,13,15,15,15, 15,15,15,9,0,0,0,1,14,12,0,0,12,15,15,15, 15,15,15,15,15,15,14,1,0,10,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,12, 3,0,0,0,0,0,0,1,8,14,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,9, 0,0,0,0,7,15,15,15,1,0,0,14,15,15,15,13, 0,0,1,15,15,15,15,12,0,0,0,6,14,15,15,15, 15,15,12,0,0,0,0,3,14,12,0,0,12,15,15,15, 15,15,15,15,15,15,12,0,0,12,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,13,3,0,0,0,0,0,0,1,6,13,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,12,0, 0,0,0,3,15,15,15,12,0,0,0,14,15,15,15,11, 0,0,3,15,15,15,15,15,12,7,0,0,4,14,15,15, 15,11,1,0,0,0,4,13,15,12,0,0,12,15,15,15, 15,15,15,15,15,15,10,0,1,14,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,12,7,0,0,0,0,0,0,0,3,8,12,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,4,0, 0,0,1,13,15,15,15,6,0,0,0,14,15,15,15,8, 0,0,7,15,15,15,15,15,15,15,8,1,0,2,13,15, 14,2,0,0,0,4,14,15,15,13,1,0,10,15,15,15, 15,15,15,15,15,15,9,0,2,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,11,6,2,0,0,0,0,0,0,0,1, 10,15,15,15,15,15,15,15,15,15,15,15,15,8,0,0, 0,0,10,15,15,15,15,4,0,0,1,15,15,15,15,4, 0,0,8,15,15,15,15,15,15,15,15,10,1,0,1,8, 2,0,0,0,5,15,15,15,15,15,2,0,6,15,15,15, 15,15,15,15,15,15,9,0,1,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,9,1,0,0,0,0,0,0, 0,1,7,13,14,15,15,15,15,15,15,15,9,0,0,0, 0,6,15,15,15,15,15,4,0,0,4,15,15,15,14,1, 0,0,9,15,15,15,15,15,15,15,15,15,12,2,0,0, 0,0,0,4,14,15,15,15,15,15,4,0,4,15,15,15, 15,15,15,15,15,15,7,0,0,14,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,14,11,6,2,0,0,0, 0,0,0,0,1,9,12,15,15,15,15,14,3,0,0,0, 4,15,15,15,15,15,15,4,0,0,3,6,4,4,2,0, 0,0,13,15,15,15,15,15,15,15,15,15,15,12,1,0, 0,0,3,14,15,15,15,15,15,15,4,0,4,15,15,15, 15,15,15,15,15,15,5,0,0,12,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,8,2,0, 0,0,0,0,0,0,0,1,9,15,15,5,0,0,0,0, 12,15,15,15,15,15,15,4,0,0,0,0,0,0,0,0, 0,3,15,15,15,15,15,15,15,15,15,15,15,14,4,0, 0,1,12,15,15,15,15,15,15,15,6,0,1,14,15,15, 15,15,15,15,15,15,5,0,0,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,12, 7,1,0,0,0,0,0,0,0,5,7,0,0,0,0,10, 15,15,15,15,15,15,15,7,0,0,0,0,0,0,0,0, 1,10,15,15,15,15,15,15,15,15,15,15,15,14,3,0, 3,12,15,15,15,15,15,15,15,15,12,0,0,12,15,15, 15,15,15,15,15,15,5,0,0,1,1,4,11,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,11,6,1,0,0,0,0,0,0,0,0,0,7,15, 15,15,15,15,15,15,15,14,7,4,4,4,5,9,12,13, 14,15,15,15,15,15,15,15,15,15,15,15,15,15,11,9, 14,15,15,14,12,11,11,11,10,9,7,0,0,5,13,15, 15,15,15,15,15,12,1,0,0,0,0,0,0,10,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,14,7,1,0,0,0,0,0,3,14,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,13,2,0,0,0,0,0,0,0,0,0,0,0,8, 15,15,15,15,15,11,0,0,0,0,0,0,0,9,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,13,5,0,0,0,0,12,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,8,0,0,0,0,0,0,0,0,0,0,0,0,5, 15,15,15,15,15,15,10,5,6,7,7,7,9,14,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,8,3,2,2,2,2,5,14,15, 15,15,15,15,15,15,15,15,15,10,3,0,6,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,13,3,1,0,1,0,1,1,2,4,4,3,9,14, 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,12,4,0,1,6,7,7,4,1,3,13, 15,15,15,15,15,15,15,15,15,15,14,10,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,11,11,15,15,15,15, 15,15,15,14,14,14,14,14,14,14,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,14,2,0,4,13,15,15,15,15,10,0,12, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,14,13,14,12,12,12,12,12,12,12, 12,14,15,15,15,15,15,15,15,15,4,14,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,7,1,5,14,15,15,15,15,15,12,1,11, 15,15,15,13,12,13,15,15,14,11,13,15,15,15,15,15, 15,15,15,11,6,3,1,1,1,0,0,0,0,0,0,0, 0,1,4,7,11,14,15,15,15,14,4,15,13,10,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,14,7,4,5, 12,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,13,1,1,14,15,15,14,10,12,15,11,1,12, 15,15,11,1,0,4,15,15,6,0,2,14,15,15,15,15, 15,15,14,8,6,3,3,2,2,1,0,0,0,0,0,0, 0,0,0,0,0,3,11,15,15,11,8,15,12,6,15,9, 8,15,15,15,15,15,15,15,15,15,15,15,10,4,4,1, 4,15,15,15,15,11,6,2,8,14,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,12,0,4,15,15,15,11,2,10,15,9,1,13, 15,13,1,7,6,2,14,14,1,2,1,14,15,15,15,15, 15,15,15,15,15,15,15,15,15,13,12,12,12,12,12,12, 11,11,11,10,9,10,12,15,15,6,7,15,9,4,15,4, 1,14,15,15,15,15,15,15,15,15,15,15,2,11,15,4, 4,15,15,15,15,3,9,4,0,9,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,12,0,4,15,15,15,5,0,6,6,1,9,15, 15,4,1,13,10,1,13,9,2,7,1,14,14,14,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,3,5,15,3,5,14,1, 0,12,13,9,14,15,15,15,15,15,15,15,2,2,4,1, 6,15,15,15,14,1,5,6,0,9,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,12,0,4,15,15,15,12,4,2,2,10,15,15, 11,0,6,15,12,0,10,7,9,10,1,14,7,14,15,15, 15,15,15,15,15,15,13,12,11,11,10,9,9,10,11,13, 15,15,15,15,15,15,15,15,15,1,9,15,2,7,14,1, 0,10,7,0,8,15,15,15,15,15,15,15,11,4,4,4, 13,15,15,15,15,10,2,2,4,14,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,12,0,4,15,15,15,15,15,15,15,15,15,15, 4,2,14,15,15,1,9,5,14,9,1,14,8,14,15,15, 15,15,15,15,15,10,3,0,1,0,0,0,0,0,0,5, 15,15,15,15,15,15,15,15,15,1,9,14,1,8,14,1, 0,11,13,6,11,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,14,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,12,0,4,15,15,15,15,15,15,15,15,15,11, 0,6,15,15,15,1,5,3,13,10,0,6,8,15,15,15, 15,15,15,15,15,15,13,12,12,11,10,9,9,10,11,13, 15,15,15,15,15,15,15,15,15,1,9,12,1,11,15,4, 1,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 14,10,4,2,12,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,12,1,3,14,15,15,15,15,15,15,15,15,4, 3,14,15,15,15,5,1,8,15,14,5,2,9,15,15,15, 15,15,15,15,15,15,15,15,15,11,9,13,15,15,15,15, 15,15,15,15,15,15,15,15,15,1,9,12,1,12,15,13, 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 10,2,9,2,3,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,14,4,0,5,14,15,15,15,15,15,15,11,0, 6,15,15,15,15,15,14,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,8,1,0,3,15,15,15,15, 15,15,15,15,15,15,15,15,15,1,9,15,11,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 7,1,12,6,1,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,11,1,0,3,8,9,9,10,11,9,5,4, 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,12,9,13,15,15,15,15, 15,15,15,15,15,15,15,15,15,5,11,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 10,3,4,1,5,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,12,2,0,0,0,0,0,0,1,8,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,14,12,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,13,8,8,10,9,10,11,14,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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 }}; ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/ppc_zoom_ultimate.s������������������������������������������������������0000644�0001750�0001750�00000023146�14647725152�017325� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������; PowerPC optimized zoom for Goom ; © 2001-2003 Guillaume Borios ; This Source Code is released under the terms of the General Public License ; Change log : ; 21 Dec 2003 : Use of altivec is now determined with a parameter ; Section definition : We use a read only section .text ; name of the function to call by C program : ppc_zoom ; We declare this label as a global to extend its scope outside this file .globl _ppc_zoom_generic .globl _ppc_zoom_G4 ; Description : ; This routine dynamically computes and applies a zoom filter ; parameters : ; r3 <=> unsigned int sizeX (in pixels) ; r4 <=> unsigned int sizeY (in pixels) ; r5 <=> unsigned int * frompixmap ; r6 <=> unsigned int * topixmap ; r7 <=> unsigned int * brutS ; r8 <=> unsigned int * brutD ; r9 <=> unsigned int buffratio ; r10 <=> int [16][16] precalccoeffs ; globals after init ; r5 <=> frompixmap - 1 byte needed for preincremental fetch (replaces r5) ; r6 <=> topixmap - 1 byte needed for preincremental fetch (replaces r6) ; r3 <=> ax = x max in 16th of pixels (replaces old r3) ; r4 <=> ay = y max in 16th of pixels (replaces old r4) ; r20 <=> row size in bytes ; r12 <=> 0xFF00FF (mask for parallel 32 bits pixs computing) ; r30 <=> brutS - 1 byte needed for preincremental fetch (replaces r7) ; r31 <=> brutD - 1 byte needed for preincremental fetch (replaces r8) ; ABI notes : ; r1 is the Stack Pointer (SP) => Do not use ; r13..r31 are non-volatiles => Do not use _ppc_zoom_generic: ; Saves the used non volatile registers in the Mach-O stack s Red-Zone stmw r18,-56(r1) ; init li r18,0 ; Default value if out of range : 0 (Black) mr r11,r10 lis r12,0xFF mullw r2,r3,r4 ; Number of pixels to compute subi r30,r8,0 slwi r20,r3,2 srawi r19,r20,2 ori r12,r12,0xFF subi r3,r3,1 subi r4,r4,1 mtspr ctr,r2 ; Init the loop count (one loop per pixel computed) subi r31,r7,0 subi r6,r6,4 slwi r3,r3,4 slwi r4,r4,4 ;pre init for loop lwz r2,0(r31) ; px lwz r29,4(r31) ; py lwz r8,0(r30) ; px2 lwz r10,4(r30) ; py2 b L1 .align 5 L1: ; computes dynamically the position to fetch sub r8,r8,r2 sub r10,r10,r29 mullw r8,r8,r9 addi r31,r31,8 mullw r10,r10,r9 addi r30,r30,8 srawi r8,r8,16 srawi r10,r10,16 add r2,r2,r8 add r29,r29,r10 ; if px>ax or py>ay goto outofrange ; computes the attenuation coeffs and the original point address rlwinm r10,r2,6,28-6,31-6 ; r10 <- (r2 << 2) & 0x000002D0 (r10=(r2%16)*4*16) cmpl cr4,0,r2,r3 rlwimi r10, r29, 2, 28-2, 31-2 ; r10 <- ((r29 << 2) & 0x0000002D) | (r10 & !0x0000002D) (r10=(r10%16)*4 | r10) cmpl cr7,0,r29,r4 srawi r29,r29,4 ; pos computing bge- cr4,L4 srawi r2,r2,4 ; pos computing mullw r29, r29,r19 ; pos computing bge- cr7,L4 ; Channels notation : 00112233 (AARRVVBB) add r2,r2,r29 ; pos computing lwzx r10,r11,r10 ; Loads coefs slwi r2,r2,2 ; pos computing add r2,r2,r5 ; pos computing rlwinm r21,r10,0,24,31 ; Isolates coef1 (??????11 -> 00000011) lwz r25,0(r2) ; Loads col1 -> r25 lwz r26,4(r2) ; Loads col2 -> r26 rlwinm r22,r10,24,24,31 ; Isolates coef2 (????22?? -> 00000022) rlwinm r23,r10,16,24,31 ; Isolates coef3 (??33???? -> 00000033) add r2,r2,r20 ; Adds one line for future load of col3 and col4 and r8, r25,r12 ; Masks col1 channels 1 & 3 : 0x00XX00XX rlwinm r24,r10,8,24,31 ; Isolates coef4 (44?????? -> 00000044) andi. r25,r25,0xFF00 ; Masks col1 channel 2 : 0x0000XX00 mullw r8, r8, r21 ; Applies coef1 on col1 channels 1 & 3 ; computes final pixel color and r10,r26,r12 ; Masks col2 channels 1 & 3 : 0x00XX00XX lwz r27,0(r2) ; Loads col3 -> r27 mullw r10,r10,r22 ; Applies coef2 on col2 channels 1 & 3 mullw r25,r25,r21 ; Applies coef1 on col1 channel 2 andi. r29,r26,0xFF00 ; Masks col2 channel 2 : 0x0000XX00 mullw r29,r29,r22 ; Applies coef2 on col2 channel 2 lwz r28,4(r2) ; Loads col4 -> r28 add r8 ,r8 ,r10 ; Adds col1 & col2 channels 1 & 3 and r10,r27,r12 ; Masks col3 channels 1 & 3 : 0x00XX00XX add r25,r25,r29 ; Adds col1 & col2 channel 2 mullw r10,r10,r23 ; Applies coef3 on col3 channels 1 & 3 andi. r29,r27,0xFF00 ; Masks col3 channel 2 : 0x0000XX00 mullw r29,r29,r23 ; Applies coef3 on col3 channel 2 lwz r2,0(r31) ; px add r7 ,r8 ,r10 ; Adds col3 to (col1 + col2) channels 1 & 3 and r10,r28,r12 ; Masks col4 channels 1 & 3 : 0x00XX00XX mullw r10,r10,r24 ; Applies coef4 on col4 channels 1 & 3 add r25,r25,r29 ; Adds col 3 to (col1 + col2) channel 2 lwz r8,0(r30) ; px2 andi. r28,r28,0xFF00 ; Masks col4 channel 2 : 0x0000XX00 add r7 ,r7 ,r10 ; Adds col4 to (col1 + col2 + col3) channels 1 & 3 lwz r10,4(r30) ; py2 mullw r28,r28,r24 ; Applies coef4 on col4 channel 2 srawi r7, r7, 8 ; (sum of channels 1 & 3) >> 8 lwz r29,4(r31) ; py add r25,r25,r28 ; Adds col 4 to (col1 + col2 + col3) channel 2 rlwimi r7, r25, 24, 16, 23 ; (((sum of channels 2) >> 8 ) & 0x0000FF00) | ((sum of channels 1 and 3) & 0xFFFF00FF) stwu r7,4(r6) ; Stores the computed pixel bdnz L1 ; Iterate again if needed b L3 ;goto end ; If not, returns from the function ; if out of range L4: stwu r18,4(r6) lwz r8,0(r30) ; px2 lwz r10,4(r30) ; py2 lwz r2,0(r31) ; px lwz r29,4(r31) ; py bdnz L1 L3: ; Restore saved registers and return lmw r18,-56(r1) blr _ppc_zoom_G4: ; Saves the used non volatile registers in the Mach-O stack s Red-Zone stmw r17,-60(r1) ; init li r18,0 ; Default value if out of range : 0 (Black) mr r11,r10 lis r12,0xFF mullw r2,r3,r4 ; Number of pixels to compute subi r30,r8,0 slwi r20,r3,2 srawi r19,r20,2 ori r12,r12,0xFF subi r3,r3,1 subi r4,r4,1 mtspr ctr,r2 ; Init the loop count (one loop per pixel computed) subi r31,r7,0 subi r6,r6,4 slwi r3,r3,4 slwi r4,r4,4 ;pre init for loop lwz r2,0(r31) ; px lwz r29,4(r31) ; py lwz r8,0(r30) ; px2 lwz r10,4(r30) ; py2 ;********************* lis r17,0x0F01 b L100 .align 5 L100: addi r6,r6,4 ; Optimization to ensure the destination buffer ; won't be loaded into the data cache rlwinm. r0,r6,0,27,31 bne+ L500 dcbz 0,r6 ;dcba 0,r6 L500: ; computes dynamically the position to fetch ;mullw r8,r8,r29 ;mullw r2,r2,r29 ;add r2,r8,r2 ;srawi r2,r2,17 sub r8,r8,r2 sub r10,r10,r29 mullw r8,r8,r9 addi r31,r31,8 mullw r10,r10,r9 addi r30,r30,8 dst r30,r17,0 srawi r8,r8,16 srawi r10,r10,16 add r2,r2,r8 add r29,r29,r10 dst r31,r17,1 ; if px>ax or py>ay goto outofrange ; computes the attenuation coeffs and the original point address rlwinm r10,r2,6,28-6,31-6 ; r10 <- (r2 << 2) & 0x000002D0 (r10=(r2%16)*4*16) cmpl cr4,0,r2,r3 rlwimi r10, r29, 2, 28-2, 31-2 ; r10 <- ((r29 << 2) & 0x0000002D) | (r10 & !0x0000002D) (r10=(r29%16)*4 | r10) cmpl cr7,0,r29,r4 srawi r29,r29,4 ; pos computing bge- cr4,L400 srawi r2,r2,4 ; pos computing mullw r29, r29,r19 ; pos computing bge- cr7,L400 ; Channels notation : 00112233 (AARRVVBB) add r2,r2,r29 ; pos computing lwzx r10,r11,r10 ; Loads coefs slwi r2,r2,2 ; pos computing add r2,r2,r5 ; pos computing rlwinm r21,r10,0,24,31 ; Isolates coef1 (??????11 -> 00000011) lwz r25,0(r2) ; Loads col1 -> r25 lwz r26,4(r2) ; Loads col2 -> r26 rlwinm r22,r10,24,24,31 ; Isolates coef2 (????22?? -> 00000022) rlwinm r23,r10,16,24,31 ; Isolates coef3 (??33???? -> 00000033) add r2,r2,r20 ; Adds one line for future load of col3 and col4 and r8, r25,r12 ; Masks col1 channels 1 & 3 : 0x00XX00XX rlwinm r24,r10,8,24,31 ; Isolates coef4 (44?????? -> 00000044) dst r2,r17,2 rlwinm r25,r25,0,16,23 ; Masks col1 channel 2 : 0x0000XX00 ;andi. r25,r25,0xFF00 ; Masks col1 channel 2 : 0x0000XX00 mullw r8, r8, r21 ; Applies coef1 on col1 channels 1 & 3 ; computes final pixel color and r10,r26,r12 ; Masks col2 channels 1 & 3 : 0x00XX00XX lwz r27,0(r2) ; Loads col3 -> r27 mullw r10,r10,r22 ; Applies coef2 on col2 channels 1 & 3 mullw r25,r25,r21 ; Applies coef1 on col1 channel 2 rlwinm r29,r26,0,16,23 ; Masks col2 channel 2 : 0x0000XX00 ;andi. r29,r26,0xFF00 ; Masks col2 channel 2 : 0x0000XX00 mullw r29,r29,r22 ; Applies coef2 on col2 channel 2 lwz r28,4(r2) ; Loads col4 -> r28 add r8 ,r8 ,r10 ; Adds col1 & col2 channels 1 & 3 and r10,r27,r12 ; Masks col3 channels 1 & 3 : 0x00XX00XX add r25,r25,r29 ; Adds col1 & col2 channel 2 mullw r10,r10,r23 ; Applies coef3 on col3 channels 1 & 3 rlwinm r29,r27,0,16,23 ; Masks col3 channel 2 : 0x0000XX00 ;andi. r29,r27,0xFF00 ; Masks col3 channel 2 : 0x0000XX00 mullw r29,r29,r23 ; Applies coef3 on col3 channel 2 lwz r2,0(r31) ; px add r7 ,r8 ,r10 ; Adds col3 to (col1 + col2) channels 1 & 3 and r10,r28,r12 ; Masks col4 channels 1 & 3 : 0x00XX00XX mullw r10,r10,r24 ; Applies coef4 on col4 channels 1 & 3 add r25,r25,r29 ; Adds col 3 to (col1 + col2) channel 2 lwz r8,0(r30) ; px2 rlwinm r28,r28,0,16,23 ; Masks col4 channel 2 : 0x0000XX00 ;andi. r28,r28,0xFF00 ; Masks col4 channel 2 : 0x0000XX00 add r7 ,r7 ,r10 ; Adds col4 to (col1 + col2 + col3) channels 1 & 3 lwz r10,4(r30) ; py2 mullw r28,r28,r24 ; Applies coef4 on col4 channel 2 srawi r7, r7, 8 ; (sum of channels 1 & 3) >> 8 lwz r29,4(r31) ; py add r25,r25,r28 ; Adds col 4 to (col1 + col2 + col3) channel 2 rlwimi r7, r25, 24, 16, 23 ; (((sum of channels 2) >> 8 ) & 0x0000FF00) | ((sum of channels 1 and 3) & 0xFFFF00FF) stw r7,0(r6) ; Stores the computed pixel bdnz L100 ; Iterate again if needed b L300 ;goto end ; If not, returns from the function ; if out of range L400: stw r18,0(r6) lwz r8,0(r30) ; px2 lwz r10,4(r30) ; py2 lwz r2,0(r31) ; px lwz r29,4(r31) ; py bdnz L100 L300: ; Restore saved registers and return lmw r17,-60(r1) blr ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/default_scripts.h��������������������������������������������������������0000644�0001750�0001750�00000000133�14647725152�016742� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _DEFAULT_SCRIPTS_H #define _DEFAULT_SCRIPTS_H #define GOOM_MAIN_SCRIPT "" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/convolve_fx.c������������������������������������������������������������0000644�0001750�0001750�00000024522�14647725152�016102� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goom_fx.h" #include "goom_plugin_info.h" /*#include "goomsl.h"*/ #include "goom_config.h" #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> //#define CONV_MOTIF_W 32 //#define CONV_MOTIF_WMASK 0x1f #define CONV_MOTIF_W 128 #define CONV_MOTIF_WMASK 0x7f typedef unsigned char Motif[CONV_MOTIF_W][CONV_MOTIF_W]; #include "motif_goom1.h" #include "motif_goom2.h" #define NB_THETA 512 //#define MAX 2.0f typedef struct _CONV_DATA{ PluginParam light; PluginParam factor_adj_p; PluginParam factor_p; PluginParameters params; /*GoomSL *script;*/ /* rotozoom */ int theta; float ftheta; int h_sin[NB_THETA]; int h_cos[NB_THETA]; int h_height; float visibility; Motif conv_motif; int inverse_motif; } ConvData; /* init rotozoom tables */ static void compute_tables(VisualFX *_this, PluginInfo *info) { ConvData *data = (ConvData*)_this->fx_data; double screen_coef; int i; double h; double radian; if (data->h_height == info->screen.height) return; screen_coef = 2.0 * 300.0 / (double)info->screen.height; data->h_height = info->screen.height; for ( i=0 ; i<NB_THETA ; i++ ) { radian = 2*i*M_PI/NB_THETA; h = (0.2 + cos (radian) / 15.0 * sin(radian * 2.0 + 12.123)) * screen_coef; data->h_cos[i] = 0x10000 * (-h * cos (radian) * cos(radian)); data->h_sin[i] = 0x10000 * (h * sin (radian + 1.57) * sin(radian)); } } static void set_motif(ConvData *data, const Motif motif) { int i,j; for (i=0;i<CONV_MOTIF_W;++i) for (j=0;j<CONV_MOTIF_W;++j) data->conv_motif[i][j] = motif[CONV_MOTIF_W-i-1][CONV_MOTIF_W-j-1]; } static void convolve_init(VisualFX *_this, PluginInfo *info) { ConvData *data; data = (ConvData*)calloc(1, sizeof(ConvData)); _this->fx_data = (void*)data; if (!data) return; data->light = secure_f_param("Screen Brightness"); data->light.param.fval.max = 300.0f; data->light.param.fval.step = 1.0f; data->light.param.fval.value = 100.0f; data->factor_adj_p = secure_f_param("Flash Intensity"); data->factor_adj_p.param.fval.max = 200.0f; data->factor_adj_p.param.fval.step = 1.0f; data->factor_adj_p.param.fval.value = 70.0f; data->factor_p = secure_f_feedback("Factor"); data->params = plugin_parameters ("Bright Flash", 5); data->params.params[0] = &data->light; data->params.params[1] = &data->factor_adj_p; data->params.params[2] = 0; data->params.params[3] = &data->factor_p; data->params.params[4] = 0; /* init rotozoom tables */ compute_tables(_this, info); data->theta = 0; data->ftheta = 0.0; data->visibility = 1.0; set_motif(data, CONV_MOTIF2.motif); data->inverse_motif = 0; _this->params = &data->params; } static void convolve_free(VisualFX *_this) { ConvData *data = (ConvData*)_this->fx_data; if (_this->fx_data) { free (data->params.params); free (data); } } static void create_output_with_brightness(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *info, int iff) { ConvData *data = (ConvData*)_this->fx_data; int x,y; int i = 0;//info->screen.height * info->screen.width - 1; const int c = data->h_cos [data->theta]; const int s = data->h_sin [data->theta]; const int xi = -(info->screen.width/2) * c; const int yi = (info->screen.width/2) * s; const int xj = -(info->screen.height/2) * s; const int yj = -(info->screen.height/2) * c; int xprime = xj; int yprime = yj; int ifftab[16]; if (data->inverse_motif) { int i; for (i=0;i<16;++i) ifftab[i] = (double)iff * (1.0 + data->visibility * (15.0 - i) / 15.0); } else { int i; for (i=0;i<16;++i) ifftab[i] = (double)iff / (1.0 + data->visibility * (15.0 - i) / 15.0); } for (y=info->screen.height;y--;) { int xtex,ytex; xtex = xprime + xi + CONV_MOTIF_W * 0x10000 / 2; xprime += s; ytex = yprime + yi + CONV_MOTIF_W * 0x10000 / 2; yprime += c; #if defined(HAVE_MMX) && !defined(__sun) __asm__ __volatile__ ("\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */ "\n\t movd %0, %%mm2" "\n\t movd %1, %%mm3" "\n\t punpckldq %%mm3, %%mm2" /* mm2 = [ ytex | xtex ] */ "\n\t movd %2, %%mm4" "\n\t movd %3, %%mm6" "\n\t pxor %%mm5, %%mm5" "\n\t psubd %%mm6, %%mm5" "\n\t punpckldq %%mm5, %%mm4" /* mm4 = [ -s | c ] */ #if defined(ARCH_X86_64) "\n\t movq %4, %%mm6" /* mm6 = motif */ #else "\n\t movd %4, %%mm6" /* mm6 = motif */ #endif ::"g"(xtex) ,"g"(ytex) , "g"(c), "g"(s) , "g"(&data->conv_motif[0][0])); for (x=info->screen.width;x--;) { __asm__ __volatile__ ( "\n\t movd %1, %%mm0" /* mm0 = src */ "\n\t paddd %%mm4, %%mm2" /* [ ytex | xtex ] += [ -s | s ] */ #if defined(ARCH_X86_64) || defined(ARCH_X86_X32) "\n\t movq %%rsi, %%mm5" /* save rsi into mm5 */ #else "\n\t movd %%esi, %%mm5" /* save esi into mm5 */ #endif "\n\t movq %%mm2, %%mm3" "\n\t psrld $16, %%mm3" /* mm3 = [ (ytex>>16) | (xtex>>16) ] */ "\n\t movd %%mm3, %%eax" /* eax = xtex' */ "\n\t psrlq $25, %%mm3" "\n\t movd %%mm3, %%ecx" /* ecx = ytex' << 7 */ "\n\t andl $127, %%eax" "\n\t andl $16256, %%ecx" "\n\t addl %%ecx, %%eax" #if defined(ARCH_X86_64) "\n\t movq %%mm6, %%rsi" /* rsi = motif */ "\n\t movzbl (%%rax,%%rsi), %%ecx" "\n\t movq %2, %%rax" "\n\t movq %%mm5, %%rsi" /* restore rsi from mm5 */ "\n\t movd (%%rax,%%rcx,4), %%mm1" /* mm1 = [0|0|0|iff2] */ #elif defined(ARCH_X86_X32) "\n\t movd %%mm6, %%esi" /* esi = motif */ "\n\t movzbl (%%rax,%%rsi), %%ecx" "\n\t movl %2, %%eax" "\n\t movq %%mm5, %%rsi" /* restore rsi from mm5 */ "\n\t movd (%%rax,%%rcx,4), %%mm1" /* mm1 = [0|0|0|iff2] */ #else "\n\t movd %%mm6, %%esi" /* esi = motif */ "\n\t movzbl (%%eax,%%esi), %%ecx" "\n\t movl %2, %%eax" "\n\t movd %%mm5, %%esi" /* restore esi from mm5 */ "\n\t movd (%%eax,%%ecx,4), %%mm1" /* mm1 = [0|0|0|iff2] */ #endif "\n\t punpcklwd %%mm1, %%mm1" "\n\t punpcklbw %%mm7, %%mm0" "\n\t punpckldq %%mm1, %%mm1" "\n\t psrlw $1, %%mm0" "\n\t psrlw $2, %%mm1" "\n\t pmullw %%mm1, %%mm0" "\n\t psrlw $5, %%mm0" "\n\t packuswb %%mm7, %%mm0" "\n\t movd %%mm0, %0" : "=g" (dest[i].val) : "g" (src[i].val), "g"(&ifftab[0]) : #if defined(ARCH_X86_64) || defined(ARCH_X86_X32) "rax", "rcx" #else "eax", "ecx" #endif ); i++; } #else for (x=info->screen.width;x--;) { int iff2; unsigned int f0,f1,f2,f3; xtex += c; ytex -= s; iff2 = ifftab[data->conv_motif[(ytex >>16) & CONV_MOTIF_WMASK][(xtex >> 16) & CONV_MOTIF_WMASK]]; #define sat(a) ((a)>0xFF?0xFF:(a)) f0 = src[i].val; f1 = ((f0 >> R_OFFSET) & 0xFF) * iff2 >> 8; f2 = ((f0 >> G_OFFSET) & 0xFF) * iff2 >> 8; f3 = ((f0 >> B_OFFSET) & 0xFF) * iff2 >> 8; dest[i].val = (sat(f1) << R_OFFSET) | (sat(f2) << G_OFFSET) | (sat(f3) << B_OFFSET); /* f0 = (src[i].cop[0] * iff2) >> 8; f1 = (src[i].cop[1] * iff2) >> 8; f2 = (src[i].cop[2] * iff2) >> 8; f3 = (src[i].cop[3] * iff2) >> 8; dest[i].cop[0] = (f0 & 0xffffff00) ? 0xff : (unsigned char)f0; dest[i].cop[1] = (f1 & 0xffffff00) ? 0xff : (unsigned char)f1; dest[i].cop[2] = (f2 & 0xffffff00) ? 0xff : (unsigned char)f2; dest[i].cop[3] = (f3 & 0xffffff00) ? 0xff : (unsigned char)f3; */ i++; } #endif } #ifdef HAVE_MMX __asm__ __volatile__ ("\n\t emms"); #endif compute_tables(_this, info); } /*#include <stdint.h> static uint64_t GetTick() { uint64_t x; asm volatile ("RDTSC" : "=A" (x)); return x; }*/ static void convolve_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *info) { ConvData *data = (ConvData*)_this->fx_data; float ff; int iff; if (!data) { memcpy(dest, src, info->screen.size * sizeof(Pixel)); return; } ff = (FVAL(data->factor_p) * FVAL(data->factor_adj_p) + FVAL(data->light) ) / 100.0f; iff = (unsigned int)(ff * 256); { double fcycle = (double)info->cycle; double rotate_param, rotate_coef; float INCREASE_RATE = 1.5; float DECAY_RATE = 0.955; if (FVAL(info->sound.last_goom_p) > 0.8) FVAL(data->factor_p) += FVAL(info->sound.goom_power_p) * INCREASE_RATE; FVAL(data->factor_p) *= DECAY_RATE; rotate_param = FVAL(info->sound.last_goom_p); if (rotate_param < 0.0) rotate_param = 0.0; rotate_param += FVAL(info->sound.goom_power_p); rotate_coef = 4.0 + FVAL(info->sound.goom_power_p) * 6.0; data->ftheta = (data->ftheta + rotate_coef * sin(rotate_param * 6.3)); data->theta = ((unsigned int)data->ftheta) % NB_THETA; data->visibility = (cos(fcycle * 0.001 + 1.5) * sin(fcycle * 0.008) + cos(fcycle * 0.011 + 5.0) - 0.8 + info->sound.speedvar) * 1.5; if (data->visibility < 0.0) data->visibility = 0.0; data->factor_p.change_listener(&data->factor_p); } if (data->visibility < 0.01) { switch (goom_irand(info->gRandom, 300)) { case 1: set_motif(data, CONV_MOTIF1.motif); data->inverse_motif = 1; break; case 2: set_motif(data, CONV_MOTIF2.motif); data->inverse_motif = 0; break; } } if ((ff > 0.98f) && (ff < 1.02f)) memcpy(dest, src, info->screen.size * sizeof(Pixel)); else create_output_with_brightness(_this,src,dest,info,iff); /* // Benching suite... { uint64_t before, after; double timed; static double stimed = 10000.0; before = GetTick(); data->visibility = 1.0; create_output_with_brightness(_this,src,dest,info,iff); after = GetTick(); timed = (double)((after-before) / info->screen.size); if (timed < stimed) { stimed = timed; printf ("CLK = %3.0f CPP\n", stimed); } } */ } VisualFX convolve_create(void) { VisualFX vfx = { .init = convolve_init, .free = convolve_free, .apply = convolve_apply, .fx_data = 0 }; return vfx; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_tools.h�������������������������������������������������������������0000644�0001750�0001750�00000001432�14647725152�015733� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GOOMTOOLS_H #define _GOOMTOOLS_H /** * Random number generator wrapper for faster random number. */ #define GOOM_NB_RAND 0x10000 typedef struct _GOOM_RANDOM { int array[GOOM_NB_RAND]; unsigned short pos; } GoomRandom; GoomRandom *goom_random_init(int i); void goom_random_free(GoomRandom *grandom); inline static int goom_random(GoomRandom *grandom) { grandom->pos++; /* works because pos is an unsigned short */ return grandom->array[grandom->pos]; } inline static int goom_irand(GoomRandom *grandom, int i) { grandom->pos++; return grandom->array[grandom->pos] % i; } /* called to change the specified number of value in the array, so that the array does not remain the same*/ void goom_random_update_array(GoomRandom *grandom, int numberOfValuesToChange); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/tentacle3d.c�������������������������������������������������������������0000644�0001750�0001750�00000017310�14647725152�015575� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include "v3d.h" #include "surf3d.h" #include "goom_tools.h" #include "goom_config.h" #include "goom_plugin_info.h" #include "tentacle3d.h" #define D 256.0f #define nbgrid 6 #define definitionx 9 #define definitionz 45 typedef struct _TENTACLE_FX_DATA { PluginParam enabled_bp; PluginParameters params; float cycle; grid3d *grille[nbgrid]; float *vals; #define NB_TENTACLE_COLORS 4 int colors[NB_TENTACLE_COLORS]; int col; int dstcol; float lig; float ligs; /* statics from pretty_move */ float distt; float distt2; float rot; /* entre 0 et 2 * M_PI */ int happens; int rotation; int lock; } TentacleFXData; static void tentacle_new (TentacleFXData *data); static void tentacle_update(PluginInfo *goomInfo, Pixel *buf, Pixel *back, int W, int H, short[2][512], float, int drawit, TentacleFXData *data); static void tentacle_free (TentacleFXData *data); /* * VisualFX wrapper for the tentacles */ static void tentacle_fx_init(VisualFX *_this, PluginInfo *info) { TentacleFXData *data = (TentacleFXData*)malloc(sizeof(TentacleFXData)); (void)info; data->enabled_bp = secure_b_param("Enabled", 1); data->params = plugin_parameters ("3D Tentacles", 1); data->params.params[0] = &data->enabled_bp; data->cycle = 0.0f; data->col = (0x28<<(ROUGE*8))|(0x2c<<(VERT*8))|(0x5f<<(BLEU*8)); data->dstcol = 0; data->lig = 1.15f; data->ligs = 0.1f; data->distt = 10.0f; data->distt2 = 0.0f; data->rot = 0.0f; /* entre 0 et 2 * M_PI */ data->happens = 0; data->rotation = 0; data->lock = 0; data->colors[0] = (0x18<<(ROUGE*8))|(0x4c<<(VERT*8))|(0x2f<<(BLEU*8)); data->colors[1] = (0x48<<(ROUGE*8))|(0x2c<<(VERT*8))|(0x6f<<(BLEU*8)); data->colors[2] = (0x58<<(ROUGE*8))|(0x3c<<(VERT*8))|(0x0f<<(BLEU*8)); data->colors[3] = (0x87<<(ROUGE*8))|(0x55<<(VERT*8))|(0x74<<(BLEU*8)); tentacle_new(data); _this->params = &data->params; _this->fx_data = (void*)data; } static void tentacle_fx_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *goomInfo) { TentacleFXData *data = (TentacleFXData*)_this->fx_data; if (BVAL(data->enabled_bp)) { tentacle_update(goomInfo, dest, src, goomInfo->screen.width, goomInfo->screen.height, goomInfo->sound.samples, (float)goomInfo->sound.accelvar, goomInfo->curGState->drawTentacle, data); } } static void tentacle_fx_free(VisualFX *_this) { TentacleFXData *data = _this->fx_data; if (data) { tentacle_free (data); free (data->params.params); free (data); } } VisualFX tentacle_fx_create(void) { VisualFX fx = { .init = tentacle_fx_init, .apply = tentacle_fx_apply, .free = tentacle_fx_free }; return fx; } /* ----- */ static void tentacle_free (TentacleFXData *data) { /* TODO : un vrai FREE GRID!! */ int i; for (i = 0; i < nbgrid; i++) grid3d_free (data->grille[i]); free (data->vals); } static void tentacle_new (TentacleFXData *data) { int tmp; v3d center = {0,-17.0,0}; data->vals = (float*)malloc ((definitionx+20)*sizeof(float)); for (tmp=0;tmp<nbgrid;tmp++) { int x,z; z = 45 + rand() % 30; x = 85 + rand() % 5; center.z = z; data->grille[tmp] = grid3d_new (x, definitionx, z, definitionz + rand() % 10, center); center.y += 8; } } static inline unsigned char lighten (unsigned char value, float power) { int val = value; float t = (float) val * log10(power) / 2.0; if (t > 0) { val = (int) t; /* (32.0f * log (t)); */ if (val > 255) val = 255; if (val < 0) val = 0; return val; } else { return 0; } } static void lightencolor (int *col, float power) { unsigned char *color; color = (unsigned char *) col; *color = lighten (*color, power); color++; *color = lighten (*color, power); color++; *color = lighten (*color, power); color++; *color = lighten (*color, power); } /* retourne x>>s , en testant le signe de x */ #define ShiftRight(_x,_s) ((_x<0) ? -(-_x>>_s) : (_x>>_s)) static int evolutecolor (unsigned int src,unsigned int dest, unsigned int mask, unsigned int incr) { int color = src & (~mask); src &= mask; dest &= mask; if ((src!=mask) &&(src<dest)) src += incr; if (src>dest) src -= incr; return (src&mask)|color; } static void pretty_move (PluginInfo *goomInfo, float cycle, float *dist, float *dist2, float *rotangle, TentacleFXData *fx_data) { float tmp; /* many magic numbers here... I don't really like that. */ if (fx_data->happens) fx_data->happens -= 1; else if (fx_data->lock == 0) { fx_data->happens = goom_irand(goomInfo->gRandom,200)?0:100+goom_irand(goomInfo->gRandom,60); fx_data->lock = fx_data->happens * 3 / 2; } else fx_data->lock --; tmp = fx_data->happens?8.0f:0; *dist2 = fx_data->distt2 = (tmp + 15.0f*fx_data->distt2)/16.0f; tmp = 30+D-90.0f*(1.0f+sin(cycle*19/20)); if (fx_data->happens) tmp *= 0.6f; *dist = fx_data->distt = (tmp + 3.0f*fx_data->distt)/4.0f; if (!fx_data->happens){ tmp = M_PI*sin(cycle)/32+3*M_PI/2; } else { fx_data->rotation = goom_irand(goomInfo->gRandom,500)?fx_data->rotation:goom_irand(goomInfo->gRandom,2); if (fx_data->rotation) cycle *= 2.0f*M_PI; else cycle *= -1.0f*M_PI; tmp = cycle - (M_PI*2.0) * floor(cycle/(M_PI*2.0)); } if (fabsf(tmp-fx_data->rot) > fabs(tmp-(fx_data->rot+2.0*M_PI))) { fx_data->rot = (tmp + 15.0f*(fx_data->rot+2*M_PI)) / 16.0f; if (fx_data->rot>2.0*M_PI) fx_data->rot -= 2.0*M_PI; *rotangle = fx_data->rot; } else if (fabsf(tmp-fx_data->rot) > fabs(tmp-(fx_data->rot-2.0*M_PI))) { fx_data->rot = (tmp + 15.0f*(fx_data->rot-2.0*M_PI)) / 16.0f; if (fx_data->rot<0.0f) fx_data->rot += 2.0*M_PI; *rotangle = fx_data->rot; } else *rotangle = fx_data->rot = (tmp + 15.0f*fx_data->rot) / 16.0f; } static void tentacle_update(PluginInfo *goomInfo, Pixel *buf, Pixel *back, int W, int H, short data[2][512], float rapport, int drawit, TentacleFXData *fx_data) { int tmp; int tmp2; int color; int colorlow; float dist,dist2,rotangle; if ((!drawit) && (fx_data->ligs>0.0f)) fx_data->ligs = -fx_data->ligs; fx_data->lig += fx_data->ligs; if (fx_data->lig > 1.01f) { if ((fx_data->lig>10.0f) | (fx_data->lig<1.1f)) fx_data->ligs = -fx_data->ligs; if ((fx_data->lig<6.3f)&&(goom_irand(goomInfo->gRandom,30)==0)) fx_data->dstcol=goom_irand(goomInfo->gRandom,NB_TENTACLE_COLORS); fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff,0x01); fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff00,0x0100); fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff0000,0x010000); fx_data->col = evolutecolor(fx_data->col,fx_data->colors[fx_data->dstcol],0xff000000,0x01000000); color = fx_data->col; colorlow = fx_data->col; lightencolor(&color,fx_data->lig * 2.0f + 2.0f); lightencolor(&colorlow,(fx_data->lig/3.0f)+0.67f); rapport = 1.0f + 2.0f * (rapport - 1.0f); rapport *= 1.2f; if (rapport > 1.12f) rapport = 1.12f; pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data); for (tmp=0;tmp<nbgrid;tmp++) { for (tmp2=0;tmp2<definitionx;tmp2++) { float val = (float)(ShiftRight(data[0][goom_irand(goomInfo->gRandom,511)],10)) * rapport; fx_data->vals[tmp2] = val; } grid3d_update (fx_data->grille[tmp], rotangle, fx_data->vals, dist2); } fx_data->cycle+=0.01f; for (tmp=0;tmp<nbgrid;tmp++) grid3d_draw (goomInfo, fx_data->grille[tmp],color,colorlow,dist,buf,back,W,H); } else { fx_data->lig = 1.05f; if (fx_data->ligs < 0.0f) fx_data->ligs = -fx_data->ligs; pretty_move (goomInfo, fx_data->cycle, &dist, &dist2, &rotangle, fx_data); fx_data->cycle+=0.1f; if (fx_data->cycle > 1000) fx_data->cycle = 0; } } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_hash.h������������������������������������������������������������0000644�0001750�0001750�00000001752�14647725152�016062� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GOOMSL_HASH_H #define _GOOMSL_HASH_H typedef struct GOOM_HASH_ENTRY GoomHashEntry; typedef struct GOOM_HASH GoomHash; typedef union { void *ptr; int i; float f; } HashValue; struct GOOM_HASH_ENTRY { char *key; HashValue value; GoomHashEntry *lower; GoomHashEntry *upper; }; struct GOOM_HASH { GoomHashEntry *root; int number_of_puts; }; GoomHash *goom_hash_new(void); void goom_hash_free(GoomHash *gh); void goom_hash_put(GoomHash *gh, const char *key, HashValue value); HashValue *goom_hash_get(GoomHash *gh, const char *key); void goom_hash_put_int (GoomHash *_this, const char *key, int i); void goom_hash_put_float(GoomHash *_this, const char *key, float f); void goom_hash_put_ptr (GoomHash *_this, const char *key, void *ptr); typedef void (*GH_Func)(GoomHash *caller, const char *key, HashValue *value); void goom_hash_for_each(GoomHash *_this, GH_Func func); int goom_hash_number_of_puts(GoomHash *_this); #endif /* _GOOM_HASH_H */ ����������������������xine-lib-1.2/src/post/goom/goom_filters.h�����������������������������������������������������������0000644�0001750�0001750�00000003237�14647725152�016250� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef FILTERS_H #define FILTERS_H #include "goom_config.h" #include "goom_typedefs.h" #include "goom_visual_fx.h" #include "goom_graphic.h" VisualFX zoomFilterVisualFXWrapper_create(void); struct _ZOOM_FILTER_DATA { int vitesse; /* 128 = vitesse nule... * * 256 = en arriere * hyper vite.. * * 0 = en avant hype vite. */ unsigned char pertedec; unsigned char sqrtperte; int middleX, middleY; /* milieu de l'effet */ char reverse; /* inverse la vitesse */ char mode; /* type d'effet à appliquer (cf les #define) */ /** @since June 2001 */ int hPlaneEffect; /* deviation horitontale */ int vPlaneEffect; /* deviation verticale */ /** @since April 2002 */ int waveEffect; /* applique une "surcouche" de wave effect */ int hypercosEffect; /* applique une "surcouche de hypercos effect */ char noisify; /* ajoute un bruit a la transformation */ }; #define NORMAL_MODE 0 #define WAVE_MODE 1 #define CRYSTAL_BALL_MODE 2 #define SCRUNCH_MODE 3 #define AMULETTE_MODE 4 #define WATER_MODE 5 #define HYPERCOS1_MODE 6 #define HYPERCOS2_MODE 7 #define YONLY_MODE 8 #define SPEEDWAY_MODE 9 void pointFilter (PluginInfo *goomInfo, Pixel * pix1, Color c, float t1, float t2, float t3, float t4, guint32 cycle); /* filtre de zoom : * le contenu de pix1 est copie dans pix2. * zf : si non NULL, configure l'effet. * resx,resy : taille des buffers. */ void zoomFilterFastRGB (PluginInfo *goomInfo, Pixel * pix1, Pixel * pix2, ZoomFilterData * zf, guint32 resx, guint32 resy, int switchIncr, float switchMult); #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_heap.h������������������������������������������������������������0000644�0001750�0001750�00000001610�14647725152�016045� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef GOOMSL_HEAP #define GOOMSL_HEAP /** * Resizable Array that guarranty that resizes don't change address of * the stored datas. * * This is implemented as an array of arrays... granularity is the size * of each arrays. */ typedef struct _GOOM_HEAP GoomHeap; /* Constructors / Destructor */ GoomHeap *goom_heap_new(void); GoomHeap *goom_heap_new_with_granularity(int granularity); void goom_heap_delete(GoomHeap *_this); /* This method behaves like malloc. */ void *goom_heap_malloc(GoomHeap *_this, int nb_bytes); /* This adds an alignment constraint. */ void *goom_heap_malloc_with_alignment(GoomHeap *_this, int nb_bytes, int alignment); /* Returns a pointeur on the bytes... prefix is before */ void *goom_heap_malloc_with_alignment_prefixed(GoomHeap *_this, int nb_bytes, int alignment, int prefix_bytes); #endif ������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/ppc_zoom_ultimate.h������������������������������������������������������0000644�0001750�0001750�00000001001�14647725152�017274� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * ppc_zoom_ultimate.h * Goom * * Created by Guillaume Borios on Sun Dec 28 2003. * Copyright (c) 2003 iOS. All rights reserved. * */ /* Generic PowerPC Code */ void ppc_zoom_generic (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); /* G4 Specific PowerPC Code (Possible use of Altivec and Data Streams) */ void ppc_zoom_G4 (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/gfontrle.c���������������������������������������������������������������0000644�0001750�0001750�00000467436�14647725152�015411� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* RGBA C-Source image dump (with zRLE compression) */ static const struct { unsigned int width; unsigned int height; unsigned int bytes_per_pixel; unsigned int rle_size; unsigned char rle_pixel [49725]; } the_font = { 1277, 21, 4, 49725, { 121,17,164,255,121,17,164,255,121,17,164,255,121,17,164,255,0,8,121,17, 164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,36,121,17,164, 0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,52,121,17,164,0, 1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1, 121,17,164,255,121,17,164,255,121,17,164,255,0,52,121,17,164,0,1,121, 17,164,255,121,17,164,255,121,17,164,255,0,52,121,17,164,0,1,121,17, 164,255,121,17,164,255,121,17,164,255,0,12,121,17,164,0,1,121,17,164, 255,121,17,164,255,121,17,164,255,0,20,121,17,164,0,1,121,17,164,255, 121,17,164,255,121,17,164,255,0,20,121,17,164,0,1,121,17,164,255,121, 17,164,255,121,17,164,255,0,52,121,17,164,0,1,121,17,164,255,121,17, 164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164, 255,121,17,164,255,0,12,121,17,164,0,1,121,17,164,255,121,17,164,255, 121,17,164,255,0,36,121,17,164,0,1,121,17,164,255,121,17,164,255,121, 17,164,255,0,12,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17, 164,255,0,36,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164, 255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255, 0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0, 44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44, 121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121, 17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17, 164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164, 0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0, 1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1, 121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121, 17,164,255,121,17,164,255,121,17,164,255,0,12,121,17,164,0,1,121,17, 164,255,121,17,164,255,121,17,164,255,0,12,121,17,164,0,1,121,17,164, 255,121,17,164,255,121,17,164,255,0,36,121,17,164,0,1,121,17,164,255, 121,17,164,255,121,17,164,255,0,36,121,17,164,0,1,121,17,164,255,121, 17,164,255,121,17,164,255,0,36,121,17,164,0,1,121,17,164,255,121,17, 164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164, 255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255, 121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121, 17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17, 164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164, 255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255, 0,36,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0, 36,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44, 121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121, 17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,12,121,17, 164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164, 0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0, 1,121,17,164,255,121,17,164,255,121,17,164,255,0,36,121,17,164,0,1, 121,17,164,255,121,17,164,255,121,17,164,255,0,52,121,17,164,0,1,121, 17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17, 164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164, 255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255, 121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121, 17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17, 164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164, 255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255, 121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121, 17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17, 164,255,0,52,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164, 255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255, 0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0, 44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,20, 121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,36,121, 17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,20,121,17, 164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,36,121,17,164, 0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,36,121,17,164,0, 1,121,17,164,255,121,17,164,255,121,17,164,255,0,12,121,17,164,0,1, 121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121, 17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17, 164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164, 255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255, 121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121, 17,164,255,121,17,164,255,0,28,121,17,164,0,1,121,17,164,255,121,17, 164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164, 255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255, 121,17,164,255,0,12,121,17,164,0,1,121,17,164,255,121,17,164,255,121, 17,164,255,0,28,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17, 164,255,0,44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164, 255,0,12,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255, 0,52,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0, 44,121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44, 121,17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121, 17,164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17, 164,0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164, 0,1,121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0, 1,121,17,164,255,121,17,164,255,121,17,164,255,0,28,121,17,164,0,1, 121,17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121, 17,164,255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17, 164,255,121,17,164,255,121,17,164,255,0,52,121,17,164,0,1,121,17,164, 255,121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255, 121,17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121, 17,164,255,121,17,164,255,0,44,121,17,164,0,1,121,17,164,255,121,17, 164,255,121,17,164,255,0,28,121,17,164,0,1,121,17,164,255,121,17,164, 255,121,17,164,255,0,12,121,17,164,0,1,121,17,164,255,121,17,164,255, 121,17,164,255,0,28,121,17,164,0,1,121,17,164,255,121,17,164,255,121, 17,164,255,121,17,164,255,121,17,164,255,0,56,121,17,164,0,1,121,17, 164,255,121,17,164,255,13,4,17,0,1,13,4,17,0,1,13,4,17,0, 1,16,5,22,0,13,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 41,16,5,22,0,1,14,4,19,0,1,16,5,22,0,57,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,57,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 57,16,5,22,0,1,14,4,19,0,1,16,5,22,0,17,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,25,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,25,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 57,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,17,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,41,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 17,16,5,22,0,1,14,4,19,0,1,16,5,22,0,41,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 17,16,5,22,0,1,14,4,19,0,1,16,5,22,0,17,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,41,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,41,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 41,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,41,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 41,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,17,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,41,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,57,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,57,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,25,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,41,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,25,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 41,16,5,22,0,1,14,4,19,0,1,16,5,22,0,41,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,17,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 33,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,17,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 33,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,17,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,57,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,49,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,33,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,57,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,49,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,49,16,5,22,0,1,14,4,19,0,1,16,5,22,0, 49,16,5,22,0,1,14,4,19,0,1,16,5,22,0,33,16,5,22,0, 1,14,4,19,0,1,16,5,22,0,17,16,5,22,0,1,14,4,19,0, 1,16,5,22,0,33,16,5,22,0,1,14,4,19,0,1,13,4,17,0, 1,13,4,17,0,1,16,5,22,0,61,16,5,22,0,1,14,4,19,0, 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, 25,8,6,3,57,10,8,5,85,9,7,4,76,0,12,8,6,3,54,9, 8,4,96,9,7,4,85,0,12,8,6,3,57,9,8,4,96,9,7,4, 85,0,24,8,6,3,57,11,8,4,85,9,7,4,79,0,12,8,6,3, 51,10,8,5,85,8,6,3,85,0,40,8,6,3,57,11,8,4,85,8, 6,3,85,0,32,8,6,3,57,10,8,5,85,9,7,4,85,0,28,5, 4,2,14,8,6,3,85,9,7,4,85,0,24,8,6,3,74,9,7,4, 113,8,6,3,167,8,6,3,139,9,7,4,85,5,4,2,14,0,36,8, 6,3,57,9,8,4,110,9,7,4,85,0,24,5,4,2,20,9,7,4, 85,9,8,4,85,0,16,9,8,4,57,9,8,4,85,6,5,3,48,0, 255,0,29,5,4,2,17,8,6,3,85,9,7,4,82,0,20,5,4,2, 3,8,6,3,85,9,7,4,93,8,6,3,153,8,6,3,161,8,6,3, 110,9,8,4,85,8,6,3,85,6,5,3,31,0,32,5,4,2,3,8, 6,3,85,10,8,5,85,10,7,5,85,0,36,5,4,2,57,8,6,3, 85,9,7,4,91,8,6,3,153,8,6,3,170,8,6,3,164,8,6,3, 108,8,6,3,85,6,5,3,71,0,24,5,4,2,42,8,6,3,85,9, 7,4,91,8,6,3,153,8,6,3,170,8,6,3,164,8,6,3,108,8, 6,3,85,6,5,3,71,0,48,5,4,2,3,8,6,3,85,9,8,4, 85,9,7,4,74,0,16,8,6,3,42,9,7,4,85,8,6,3,85,9, 7,4,85,8,6,3,125,8,6,3,170,7,6,4,170,9,7,4,170,12, 9,7,170,19,14,10,170,19,13,10,142,8,6,5,28,0,16,5,4,2, 51,8,6,3,85,9,7,4,91,8,6,3,153,8,6,3,170,8,6,3, 164,8,6,3,108,8,6,3,85,6,5,3,71,0,20,10,8,5,57,9, 7,4,170,8,6,3,170,8,6,3,170,8,6,3,161,8,6,3,142,9, 7,4,96,9,7,4,85,8,6,3,85,9,7,4,85,9,7,4,74,0, 20,5,4,2,42,8,6,3,85,9,7,4,91,8,6,3,153,8,6,3, 170,8,6,3,164,8,6,3,108,8,6,3,85,6,5,3,76,0,24,8, 6,5,82,10,8,7,133,12,9,7,170,15,11,8,170,15,11,8,170,15, 11,8,170,13,10,8,170,10,8,7,161,10,8,7,85,6,5,5,28,0, 96,8,6,3,74,9,8,4,85,8,6,3,57,0,68,7,6,4,28,9, 7,4,85,9,7,4,85,5,4,2,17,0,40,5,4,2,42,8,6,3, 85,9,7,4,91,8,6,3,153,8,6,3,170,8,6,3,164,8,6,3, 108,8,6,3,85,6,5,3,85,0,24,8,6,5,85,10,8,7,133,12, 9,7,170,15,10,8,170,15,11,8,170,15,11,8,170,13,10,8,170,10, 8,7,150,8,6,5,62,0,24,8,6,5,82,10,8,7,133,12,9,7, 170,15,10,8,170,14,10,7,170,9,7,4,170,8,6,5,147,10,8,5, 85,7,6,4,85,5,4,4,3,0,16,12,9,7,57,11,8,6,161,9, 7,6,170,10,8,7,170,13,10,8,170,14,10,7,170,13,10,8,170,12, 9,7,170,10,8,7,156,10,8,7,85,6,5,5,25,0,20,6,5,3, 57,8,7,5,85,9,7,4,110,9,7,4,170,10,8,5,170,10,8,5, 170,11,8,6,170,10,8,7,150,10,8,7,85,6,5,5,25,0,16,15, 11,8,57,11,8,6,170,9,7,6,170,10,8,7,170,13,10,8,170,15, 11,8,170,15,11,8,170,13,10,8,170,10,8,7,159,10,8,7,85,6, 5,5,25,0,16,15,11,8,59,11,9,6,170,9,7,4,125,10,8,5, 85,8,6,3,133,8,6,3,167,8,6,3,170,8,6,3,170,9,8,4, 113,0,16,8,6,3,42,10,8,5,85,10,7,5,85,9,7,4,125,10, 8,5,170,12,10,7,170,14,11,7,170,19,14,10,170,19,14,10,142,8, 6,5,28,0,16,8,6,5,82,10,8,7,133,12,9,7,170,15,11,8, 170,15,11,8,170,15,11,8,170,13,10,8,170,10,8,7,161,10,8,7, 85,6,5,5,25,0,16,12,10,7,74,14,10,7,170,12,9,7,139,7, 6,4,28,0,16,10,8,7,110,14,10,7,170,13,10,8,125,0,16,13, 10,8,71,15,11,8,170,13,10,8,130,5,5,4,8,0,44,11,8,6, 85,9,7,4,170,10,8,5,93,0,16,12,9,7,57,10,8,5,167,11, 8,6,110,6,5,3,8,0,16,11,8,6,57,10,7,5,159,11,8,6, 102,0,16,8,6,3,51,10,8,5,85,9,7,4,85,0,40,10,7,5, 57,11,9,6,85,7,6,4,57,0,28,7,5,4,28,10,8,5,85,11, 8,6,85,0,16,8,6,3,48,10,8,5,85,8,6,3,85,0,20,8, 6,3,57,11,8,4,85,9,7,4,79,0,20,5,4,2,45,8,6,3, 85,9,7,4,85,9,7,4,88,9,7,4,108,9,8,4,93,9,7,4, 85,8,6,3,85,6,5,3,74,0,20,8,6,3,45,9,7,4,85,8, 6,3,85,9,7,4,85,8,6,3,125,8,6,3,170,8,6,3,164,8, 6,3,108,8,6,3,85,6,5,3,74,0,24,6,5,3,57,8,7,5, 85,10,8,5,85,9,7,4,119,8,6,3,142,9,7,4,130,10,8,5, 91,10,7,5,85,6,5,3,85,0,20,9,7,4,57,10,8,5,85,10, 7,5,85,10,8,5,85,8,6,3,144,8,6,3,170,8,6,3,164,8, 6,3,108,8,6,3,85,6,5,3,71,0,24,5,4,2,45,8,6,3, 85,9,7,4,91,8,6,3,153,8,6,3,170,8,6,3,164,9,7,4, 105,8,6,3,85,6,5,3,74,0,20,11,8,4,59,9,7,4,170,8, 6,3,164,9,7,4,91,8,6,3,85,8,6,3,85,8,6,3,85,9, 7,4,85,8,6,3,142,9,6,4,170,9,8,4,116,0,16,8,6,3, 48,10,8,5,85,9,7,4,85,0,20,8,6,3,57,11,8,4,85,9, 7,4,76,0,16,8,6,3,48,10,8,5,85,9,7,4,85,0,20,8, 6,3,57,11,8,4,85,9,7,4,76,0,16,8,6,3,48,10,8,5, 85,9,7,4,85,0,28,8,6,3,57,11,8,4,85,9,7,4,76,0, 16,8,6,3,54,9,8,4,96,9,7,4,85,0,20,8,6,3,57,9, 8,4,96,9,7,4,85,0,16,10,8,5,57,10,7,5,153,10,8,5, 93,0,20,10,8,7,93,14,11,7,170,13,10,8,136,0,16,11,8,6, 91,11,8,6,170,9,7,4,170,9,7,4,170,8,6,5,170,8,6,3, 119,9,7,4,85,8,6,3,85,8,6,3,85,9,7,4,85,9,7,4, 76,0,16,8,6,3,42,9,7,4,85,8,6,3,85,8,6,3,122,9, 8,4,102,0,16,8,6,3,51,9,7,4,85,6,5,3,45,0,40,12, 8,5,57,8,6,3,156,10,7,5,93,11,8,6,85,11,8,6,85,0, 28,6,5,5,14,13,10,8,85,8,7,5,45,0,80,10,8,5,57,10, 7,5,156,10,8,5,96,0,76,9,7,4,57,10,8,5,93,10,8,5, 85,0,140,10,8,7,110,13,10,8,170,12,9,7,133,5,5,4,6,0, 84,8,6,5,79,10,8,7,127,13,10,8,170,16,12,9,142,8,7,5, 28,0,72,8,6,3,57,10,8,5,85,9,6,4,85,0,48,15,11,8, 113,25,18,12,170,20,15,11,142,8,7,5,28,0,28,15,11,8,130,22, 16,11,170,20,15,11,142,7,6,6,23,0,12,13,10,8,68,12,9,7, 170,11,8,6,116,6,5,3,8,0,44,12,9,7,82,15,10,8,170,13, 10,8,130,5,5,4,8,0,255,0,197,6,5,3,57,8,6,3,85,0, 255,0,149,5,4,2,6,8,6,3,85,8,6,3,156,9,8,4,113,0, 16,8,6,3,48,9,8,4,91,9,7,4,76,0,16,10,8,5,57,9, 6,4,170,8,6,3,99,5,4,2,34,0,36,8,6,3,71,9,8,4, 93,9,8,4,96,8,6,3,85,6,5,3,45,0,12,8,6,3,76,0, 44,8,6,3,57,58,31,9,255,93,50,12,255,88,45,11,255,12,10,5, 113,0,4,7,6,4,28,54,29,9,255,93,46,12,255,88,45,11,255,12, 9,5,122,0,4,7,5,4,37,54,29,9,255,93,46,12,255,88,45,11, 255,14,10,5,142,0,16,8,6,3,85,58,31,9,255,93,50,12,255,88, 44,11,255,9,7,4,170,0,4,5,4,2,85,52,28,9,255,93,48,12, 255,88,44,11,255,12,10,5,170,0,32,7,6,4,85,58,31,9,255,93, 50,12,255,88,45,11,255,12,9,5,170,0,24,8,6,3,57,58,31,9, 255,93,50,12,255,88,45,11,255,14,10,5,142,0,20,6,5,3,28,19, 12,6,227,76,37,11,255,88,45,11,255,14,10,5,139,0,16,9,8,4, 170,69,35,10,255,92,47,11,255,92,47,11,255,88,45,11,255,88,45,11, 255,16,11,5,227,7,5,4,28,0,28,8,6,3,57,58,31,9,255,93, 46,12,255,88,45,11,255,14,10,5,142,0,16,6,5,3,28,19,12,6, 227,82,39,11,255,92,47,11,255,14,10,5,105,0,8,7,5,4,20,54, 29,9,255,100,50,13,255,30,19,7,255,8,6,3,85,0,255,0,21,6, 5,3,28,19,12,6,227,76,37,11,255,88,45,11,255,14,10,5,130,0, 12,7,6,4,65,17,11,6,227,71,37,10,255,88,45,11,255,92,47,11, 255,92,47,11,255,88,45,11,255,88,44,11,255,88,44,11,255,25,16,6, 255,8,6,3,142,0,24,7,5,4,85,17,12,6,229,77,39,12,255,107, 51,14,255,113,55,16,255,20,14,9,178,0,28,14,11,7,170,29,18,8, 255,74,39,11,255,88,45,11,255,88,45,11,255,92,47,11,255,92,47,11, 255,88,45,11,255,88,44,11,255,41,23,8,255,12,9,5,227,5,5,4, 23,0,12,9,7,4,170,26,17,6,255,74,39,11,255,88,45,11,255,88, 45,11,255,92,47,11,255,92,47,11,255,88,45,11,255,88,44,11,255,41, 24,8,255,12,9,5,227,6,5,3,28,0,36,6,5,3,85,16,11,5, 227,71,37,10,255,88,45,11,255,88,44,11,255,12,10,5,113,0,8,8, 6,3,28,54,29,9,255,92,47,11,255,88,44,11,255,88,45,11,255,92, 46,13,255,100,52,13,255,109,53,16,255,121,63,20,255,158,74,23,255,180, 88,27,255,183,90,28,255,26,17,11,142,0,12,10,7,5,170,26,17,6, 255,74,39,11,255,88,45,11,255,92,47,11,255,92,47,11,255,92,47,11, 255,88,45,11,255,88,45,11,255,41,24,8,255,12,9,5,227,6,5,3, 28,0,8,7,6,4,8,61,32,10,255,102,51,13,255,92,46,13,255,92, 46,13,255,92,46,13,255,92,46,13,255,92,46,13,255,90,45,11,255,84, 44,11,255,88,45,11,255,88,44,11,255,14,10,5,119,0,12,9,7,4, 153,26,17,6,255,74,39,11,255,88,45,11,255,92,47,11,255,92,47,11, 255,92,47,11,255,88,45,11,255,88,44,11,255,45,25,8,255,13,10,6, 227,7,6,4,28,0,12,17,13,10,170,64,39,21,255,155,78,26,255,169, 83,26,255,165,80,24,255,161,79,24,255,145,71,22,255,136,70,21,255,134, 69,21,255,88,50,23,255,22,17,11,232,9,8,6,31,0,84,4,4,3, 23,12,9,5,173,71,34,10,255,92,43,13,255,33,20,8,255,10,8,5, 57,0,64,20,14,7,227,83,42,12,255,92,46,13,255,19,13,6,227,6, 5,3,34,0,32,10,8,5,170,26,17,6,255,76,37,11,255,90,46,11, 255,92,46,13,255,92,46,13,255,90,45,11,255,90,45,11,255,88,44,11, 255,46,26,9,255,18,13,9,227,8,7,5,28,0,12,15,12,8,170,58, 35,19,255,134,73,23,255,153,76,24,255,142,69,21,255,131,64,20,255,121, 59,18,255,121,59,18,255,121,62,18,255,43,27,12,255,11,9,6,170,0, 16,17,13,10,170,64,39,21,255,164,85,27,255,177,86,26,255,154,75,23, 255,121,62,18,255,115,56,16,255,119,61,18,255,123,61,20,255,80,45,19, 255,22,16,11,227,8,7,5,28,0,8,13,10,8,57,96,48,19,255,165, 80,24,255,159,78,24,255,159,78,24,255,165,80,24,255,165,80,24,255,165, 80,24,255,159,78,24,255,164,81,25,255,91,52,24,255,22,17,11,227,8, 7,5,28,0,12,13,10,8,170,38,24,11,255,99,47,16,255,116,59,17, 255,126,65,21,255,142,69,21,255,153,76,24,255,157,74,24,255,155,76,24, 255,91,52,24,255,23,18,12,227,8,7,5,28,0,8,13,10,8,57,104, 52,21,255,171,84,26,255,155,76,24,255,164,81,25,255,173,81,26,255,180, 88,27,255,180,88,27,255,177,86,26,255,169,80,26,255,92,55,25,255,22, 17,11,227,8,7,5,28,0,8,13,10,8,57,114,63,25,255,177,86,26, 255,114,56,17,255,92,46,13,255,92,47,11,255,93,46,12,255,92,46,13, 255,96,48,13,255,92,46,13,255,18,12,5,91,0,8,8,6,3,40,55, 29,10,255,108,50,15,255,114,56,17,255,130,67,21,255,153,76,24,255,161, 82,24,255,171,84,26,255,179,84,26,255,179,84,26,255,25,17,10,142,0, 12,15,12,8,170,64,39,21,255,162,84,27,255,179,88,28,255,183,90,28, 255,181,89,28,255,181,89,28,255,172,88,27,255,156,77,25,255,88,50,23, 255,22,17,11,227,8,7,5,28,0,8,13,9,6,57,96,48,19,255,153, 71,22,255,134,69,21,255,20,14,9,193,0,12,11,8,6,113,124,62,25, 255,185,91,28,255,169,80,26,255,22,15,9,142,0,8,11,8,6,57,111, 61,24,255,184,90,27,255,177,86,26,255,23,16,10,173,0,40,11,8,6, 113,114,59,23,255,144,73,21,255,126,63,21,255,20,14,9,142,0,8,11, 9,6,57,97,51,20,255,152,71,23,255,134,69,21,255,20,14,9,187,0, 12,12,9,7,96,97,48,18,255,140,71,21,255,138,71,21,255,20,15,9, 142,0,8,8,6,3,40,52,28,9,255,93,50,12,255,88,45,11,255,14, 10,5,142,0,32,13,10,8,82,91,48,16,255,132,71,21,255,63,36,18, 255,10,8,7,136,0,20,7,6,6,62,31,21,12,244,124,66,23,255,134, 69,21,255,20,15,9,142,0,8,8,6,3,28,54,29,9,255,93,46,12, 255,80,39,11,255,14,10,5,142,0,12,8,6,3,57,58,31,9,255,93, 50,12,255,88,44,11,255,14,10,5,116,0,12,9,7,4,153,26,17,6, 255,74,39,11,255,88,45,11,255,88,45,11,255,88,45,11,255,88,45,11, 255,88,44,11,255,88,44,11,255,41,23,8,255,12,9,5,227,5,4,4, 17,0,8,8,6,3,34,54,29,9,255,92,43,11,255,88,44,11,255,88, 45,11,255,92,43,11,255,92,47,11,255,92,47,11,255,88,45,11,255,88, 44,11,255,45,25,8,255,12,10,5,227,6,5,3,28,0,12,13,10,6, 170,40,24,11,255,97,48,16,255,113,55,16,255,115,56,16,255,116,57,17, 255,116,57,17,255,113,55,16,255,113,55,16,255,60,33,13,255,18,14,9, 227,8,6,5,28,0,8,12,9,7,57,77,38,14,255,118,57,17,255,116, 59,17,255,118,60,17,255,109,53,16,255,98,47,13,255,92,47,11,255,88, 45,11,255,88,44,11,255,41,23,8,255,12,9,5,227,6,5,3,28,0, 12,10,8,5,170,28,18,7,255,76,37,11,255,90,45,11,255,92,46,13, 255,94,45,13,255,94,45,13,255,92,46,13,255,92,46,13,255,46,26,9, 255,13,10,6,227,6,5,5,28,0,8,7,6,4,8,61,32,10,255,100, 50,13,255,92,46,13,255,92,46,13,255,92,46,13,255,92,46,13,255,92, 46,13,255,92,46,13,255,94,47,13,255,98,49,13,255,94,47,13,255,18, 12,5,93,0,8,8,6,3,42,60,32,9,255,96,48,13,255,88,45,11, 255,14,10,5,142,0,12,8,6,3,57,58,31,9,255,93,50,12,255,88, 44,11,255,12,10,5,113,0,8,8,6,3,28,54,29,9,255,93,50,12, 255,88,44,11,255,14,10,5,142,0,12,8,6,3,57,58,31,9,255,93, 50,12,255,88,44,11,255,12,10,5,113,0,8,8,6,3,28,54,29,9, 255,93,50,12,255,88,44,11,255,14,10,5,142,0,20,8,6,3,57,58, 31,9,255,93,50,12,255,88,44,11,255,12,10,5,113,0,8,7,6,4, 28,54,29,9,255,93,50,12,255,88,45,11,255,14,10,5,142,0,12,8, 7,3,57,60,31,9,255,96,48,13,255,92,46,13,255,14,10,5,127,0, 8,10,8,5,57,82,42,15,255,135,66,20,255,121,60,20,255,20,15,9, 176,0,12,11,9,6,108,107,56,22,255,172,84,25,255,158,74,23,255,22, 15,9,142,0,8,11,8,6,54,98,51,19,255,142,72,21,255,136,70,21, 255,138,71,21,255,121,59,18,255,100,52,13,255,90,46,11,255,88,44,11, 255,88,44,11,255,88,44,11,255,88,45,11,255,12,10,5,113,0,8,8, 6,3,28,54,29,9,255,92,47,11,255,88,44,11,255,92,47,11,255,92, 47,11,255,18,12,5,85,0,8,7,6,4,45,54,30,9,255,94,47,13, 255,31,20,8,255,9,7,4,85,0,32,8,6,3,48,65,33,10,255,114, 55,15,255,119,58,18,255,126,63,21,255,128,66,21,255,22,15,9,164,0, 20,5,5,4,28,19,14,10,227,141,72,26,255,43,27,16,255,7,6,6, 85,0,72,14,10,7,71,96,49,17,255,138,71,21,255,130,67,21,255,22, 15,9,164,0,68,12,9,7,76,77,39,14,255,118,57,17,255,109,53,16, 255,22,15,9,153,0,132,11,8,6,96,103,53,20,255,144,73,21,255,121, 60,20,255,24,16,9,153,0,80,15,12,8,184,61,36,20,255,141,68,24, 255,168,82,25,255,171,84,26,255,26,18,11,159,0,68,9,7,4,57,60, 32,9,255,96,48,13,255,92,46,13,255,19,12,6,142,0,40,14,10,7, 76,129,67,26,255,190,97,29,255,180,88,27,255,26,17,11,161,0,24,14, 10,7,85,129,67,26,255,190,97,29,255,180,88,27,255,25,17,10,125,0, 8,11,8,6,57,109,60,24,255,175,86,26,255,142,73,23,255,20,14,9, 187,0,40,12,9,7,93,121,65,24,255,183,89,26,255,168,82,25,255,21, 15,10,178,0,255,0,193,10,8,5,170,39,23,8,255,78,41,11,255,16, 11,5,142,0,255,0,141,6,5,3,85,16,11,5,227,71,37,10,255,92, 47,11,255,92,47,11,255,18,12,5,85,0,8,8,6,3,28,54,29,9, 255,93,46,12,255,88,45,11,255,12,10,5,113,0,12,58,31,9,255,93, 50,12,255,88,45,11,255,25,17,6,255,8,6,3,142,0,24,4,4,3, 25,10,8,5,173,65,33,10,255,92,46,13,255,92,46,13,255,67,34,10, 255,27,18,8,255,9,7,4,156,3,3,2,85,10,8,5,184,69,35,10, 255,19,13,6,147,0,40,9,7,4,113,112,55,13,255,141,69,16,255,141, 75,16,255,18,13,5,170,0,4,8,6,3,85,110,54,13,255,143,76,16, 255,139,68,16,255,19,13,6,170,0,4,8,6,3,85,110,54,13,255,143, 76,16,255,141,72,16,255,23,15,6,170,0,12,10,9,5,110,35,21,8, 255,129,63,14,255,141,69,16,255,139,68,16,255,52,27,9,255,9,7,4, 255,27,17,8,255,135,66,16,255,154,75,17,255,155,79,18,255,91,50,16, 255,20,15,9,207,10,9,7,28,0,16,5,4,4,20,8,6,3,127,31, 20,8,255,130,66,15,255,143,76,16,255,143,76,16,255,67,34,10,255,10, 8,5,215,10,8,5,170,13,10,6,142,7,5,4,23,0,8,12,9,5, 85,115,59,14,255,149,72,16,255,143,76,16,255,18,12,5,235,0,16,7, 6,4,28,14,10,5,227,92,46,13,255,143,73,16,255,143,70,16,255,18, 13,5,170,0,12,14,10,5,170,53,28,10,255,114,56,13,255,56,29,9, 255,16,11,5,255,34,20,7,255,112,55,13,255,87,42,12,255,19,13,6, 235,8,7,5,40,0,24,10,8,5,85,114,56,13,255,143,70,16,255,141, 72,16,255,23,15,6,170,0,12,7,6,4,28,14,10,5,227,90,44,13, 255,112,57,13,255,47,26,8,255,11,8,4,57,0,12,25,16,6,227,96, 48,13,255,112,57,13,255,26,16,7,255,8,6,5,85,0,24,13,10,6, 85,8,7,5,57,0,20,6,5,3,28,15,11,6,85,9,7,4,28,0, 36,9,7,4,105,10,8,5,170,10,8,5,130,6,5,3,23,0,156,8, 6,3,136,77,39,12,255,143,73,16,255,139,74,16,255,18,12,5,170,0, 12,21,14,6,227,112,57,13,255,141,69,16,255,80,40,11,255,16,11,5, 255,14,10,5,227,18,13,5,255,72,35,11,255,136,69,15,255,130,66,15, 255,46,26,9,255,8,6,3,105,0,16,8,7,5,57,42,27,13,255,150, 79,21,255,184,94,21,255,195,99,22,255,199,106,24,255,26,18,11,255,0, 24,10,8,7,99,83,45,18,255,144,74,17,255,143,70,16,255,94,47,13, 255,18,13,5,255,16,11,5,173,14,10,5,227,52,27,9,255,132,67,15, 255,139,68,16,255,75,39,12,255,10,7,5,116,0,8,6,5,3,57,52, 27,9,255,137,73,16,255,143,76,16,255,94,47,13,255,18,13,5,255,16, 11,5,173,14,10,5,227,52,27,9,255,132,67,15,255,139,74,16,255,75, 39,12,255,10,8,5,142,0,32,8,6,5,85,22,15,7,255,102,51,13, 255,137,67,16,255,140,71,15,255,141,75,16,255,20,13,5,170,0,8,9, 6,4,85,108,55,13,255,141,69,16,255,139,74,16,255,74,36,11,255,18, 12,7,255,20,13,7,181,22,15,9,207,20,13,9,238,18,13,9,252,23, 16,10,255,31,21,12,218,14,11,7,42,0,8,7,6,4,57,40,22,9, 255,130,66,15,255,141,75,16,255,84,42,11,255,18,12,5,255,16,12,5, 181,14,10,5,241,69,35,10,255,140,69,17,255,154,78,17,255,117,60,18, 255,17,13,8,142,0,12,21,14,8,190,28,18,9,255,23,15,8,255,21, 14,8,255,21,14,8,255,23,15,8,255,38,24,11,255,98,53,17,255,151, 74,18,255,150,76,17,255,141,75,16,255,21,15,6,170,0,8,5,4,2, 28,33,20,8,255,130,66,15,255,141,72,16,255,84,42,11,255,18,12,5, 255,18,12,5,176,14,10,5,235,57,29,10,255,140,72,17,255,165,85,20, 255,121,67,24,255,14,11,7,142,0,8,8,6,5,57,72,46,23,255,198, 113,29,255,200,102,23,255,131,68,22,255,33,21,12,255,17,13,8,255,21, 14,8,255,88,47,19,255,192,99,23,255,203,113,26,255,146,87,29,255,13, 11,8,164,0,12,10,8,5,85,13,10,6,170,11,9,6,142,7,6,4, 28,0,12,13,10,8,113,18,14,9,170,16,13,9,147,10,8,7,28,0, 24,10,8,7,28,20,15,11,227,104,62,21,255,184,94,21,255,117,62,22, 255,17,12,8,227,7,5,4,28,0,64,11,8,6,170,67,35,16,255,164, 85,21,255,115,58,16,255,20,14,7,252,8,6,5,85,0,24,9,7,4, 82,66,37,13,255,145,75,18,255,154,78,17,255,115,58,16,255,29,18,8, 255,14,10,7,255,16,11,7,255,65,34,12,255,150,74,19,255,189,97,22, 255,138,79,27,255,14,12,9,142,0,8,7,6,6,57,55,33,16,255,158, 81,19,255,162,80,19,255,102,53,17,255,24,15,7,255,19,12,6,170,14, 10,5,204,46,26,9,255,137,67,16,255,139,71,16,255,49,27,10,255,7, 6,4,105,0,8,7,6,6,62,72,46,23,255,199,115,32,255,205,111,28, 255,155,84,26,255,41,24,14,255,18,13,9,255,25,16,10,255,110,61,25, 255,199,100,28,255,205,112,30,255,146,87,29,255,13,11,8,142,0,8,10, 8,7,147,180,87,25,255,206,111,27,255,203,105,26,255,164,85,27,255,40, 24,15,255,20,14,9,255,26,17,11,255,121,64,26,255,201,101,28,255,205, 112,30,255,146,87,29,255,14,11,7,142,0,8,8,6,5,57,71,44,22, 255,192,108,25,255,198,101,23,255,150,78,25,255,41,24,14,255,32,21,13, 255,74,41,21,255,184,105,27,255,202,104,25,255,202,118,27,255,174,102,31, 255,17,14,10,142,0,8,11,9,6,136,182,92,25,255,206,112,29,255,205, 111,28,255,166,79,27,255,43,25,16,255,21,15,10,255,29,19,12,255,116, 67,27,255,202,107,31,255,206,113,31,255,146,87,29,255,12,10,7,142,0, 8,11,8,6,144,185,93,26,255,202,103,23,255,157,77,18,255,83,42,12, 255,19,13,6,255,13,10,6,255,20,13,7,255,27,17,8,255,28,18,9, 227,10,8,5,45,0,8,11,9,6,142,139,73,20,255,198,96,21,255,199, 106,24,255,155,78,26,255,41,25,14,255,21,15,10,255,28,18,11,255,38, 24,15,255,40,24,15,227,14,10,7,62,0,8,8,7,5,57,65,41,20, 255,197,108,28,255,205,111,28,255,170,88,27,255,43,27,16,255,19,14,10, 255,29,19,12,255,123,66,24,255,181,84,20,255,170,87,19,255,114,60,17, 255,11,10,6,142,0,8,11,9,6,85,119,60,15,255,154,75,17,255,154, 78,17,255,18,13,7,255,0,12,13,10,8,170,191,102,30,255,209,118,30, 255,207,113,30,255,28,19,11,201,0,8,13,10,8,105,166,87,23,255,198, 101,23,255,198,97,23,255,26,18,11,255,0,40,13,10,8,170,189,100,28, 255,206,111,27,255,204,102,27,255,28,20,11,201,0,8,12,10,7,116,184, 93,27,255,206,107,27,255,203,113,26,255,23,17,10,255,0,8,6,5,5, 28,25,18,12,244,192,105,27,255,206,112,29,255,207,117,30,255,32,22,13, 170,0,8,11,9,6,88,112,57,13,255,143,70,16,255,141,69,16,255,17, 12,6,227,0,32,14,11,9,170,184,92,25,255,206,111,27,255,192,111,31, 255,49,33,18,255,10,8,7,122,0,12,7,7,6,59,22,16,11,232,167, 100,28,255,205,112,30,255,205,116,30,255,26,18,11,210,0,8,8,7,3, 85,110,54,13,255,141,69,16,255,141,75,16,255,25,16,6,255,5,4,4, 40,0,8,10,8,5,85,112,55,13,255,141,75,16,255,141,75,16,255,20, 13,5,170,0,8,5,4,2,28,33,20,8,255,130,66,15,255,141,72,16, 255,112,55,13,255,45,25,8,255,26,17,6,255,33,20,8,255,94,47,13, 255,141,69,16,255,144,71,17,255,80,40,13,255,9,7,4,125,0,8,10, 8,5,85,112,57,13,255,148,79,17,255,141,75,16,255,87,42,12,255,19, 13,6,255,14,10,5,215,15,10,6,255,60,31,11,255,143,71,18,255,160, 82,19,255,96,54,17,255,12,9,7,142,0,8,8,6,5,57,71,44,22, 255,192,100,25,255,199,106,24,255,185,93,26,255,91,50,22,255,58,33,17, 255,72,41,19,255,158,81,25,255,199,106,24,255,199,106,24,255,138,79,27, 255,13,11,8,142,0,8,10,8,7,147,166,87,23,255,203,108,24,255,202, 108,25,255,153,77,26,255,38,22,13,255,15,11,6,255,14,10,5,255,52, 28,9,255,132,70,15,255,141,75,16,255,80,41,13,255,10,8,5,139,0, 8,7,6,6,57,48,29,13,255,154,79,19,255,160,85,19,255,108,56,17, 255,30,18,9,255,16,11,7,255,24,15,9,255,96,51,17,255,167,86,20, 255,181,88,20,255,140,75,23,255,18,14,9,144,0,12,22,14,7,193,22, 13,7,255,20,13,7,255,78,40,15,255,165,81,20,255,177,90,20,255,177, 90,20,255,115,58,20,255,32,20,11,255,24,15,9,255,30,19,9,227,11, 8,6,54,0,8,11,9,6,142,139,68,20,255,166,78,19,255,144,71,17, 255,19,12,6,215,0,12,9,7,4,136,114,56,13,255,143,70,16,255,139, 68,16,255,19,13,6,170,0,8,10,7,5,85,112,55,13,255,143,70,16, 255,139,74,16,255,17,11,6,221,0,12,9,7,4,136,114,56,13,255,143, 70,16,255,141,75,16,255,20,13,5,170,0,8,9,6,4,85,110,54,13, 255,141,69,16,255,141,72,16,255,17,11,6,221,0,20,9,7,4,136,114, 56,13,255,143,73,16,255,139,74,16,255,19,13,6,170,0,8,8,6,3, 85,110,54,13,255,143,76,16,255,141,69,16,255,18,12,5,252,0,12,11, 9,6,170,131,69,18,255,170,87,19,255,168,86,19,255,28,19,9,170,0, 8,11,8,6,85,145,74,26,255,204,102,27,255,203,105,26,255,52,33,17, 255,6,5,5,57,0,8,17,14,10,227,190,107,25,255,204,113,25,255,174, 86,27,255,18,13,9,170,0,12,28,18,11,198,37,23,14,255,32,21,13, 255,21,15,10,255,20,14,9,255,38,23,11,255,87,44,12,255,137,70,16, 255,141,72,16,255,143,70,16,255,141,72,16,255,18,12,5,170,0,8,9, 6,4,85,110,54,13,255,145,74,16,255,141,69,16,255,94,47,13,255,27, 17,8,227,12,8,5,28,0,8,14,10,7,85,121,62,18,255,172,87,19, 255,139,69,18,255,20,15,9,227,0,36,21,14,8,227,117,61,24,255,199, 100,28,255,205,106,26,255,204,110,27,255,26,18,11,255,0,16,8,7,5, 28,20,15,11,227,135,73,22,255,192,97,21,255,165,83,22,255,33,22,12, 255,10,9,7,85,0,68,11,9,6,170,184,97,27,255,206,112,29,255,204, 110,27,255,28,19,11,255,0,68,14,11,7,170,179,93,24,255,202,103,23, 255,198,97,23,255,22,15,9,255,0,132,9,7,6,170,125,63,18,255,158, 77,17,255,146,75,17,255,17,12,6,255,0,76,8,6,5,76,72,46,23, 255,197,108,28,255,201,107,24,255,164,85,27,255,37,22,14,227,13,9,6, 48,0,68,12,9,7,170,138,67,19,255,170,79,19,255,168,86,19,255,20, 14,9,255,0,40,8,7,5,20,21,15,10,184,26,17,11,255,26,17,11, 215,12,9,7,74,0,24,8,7,5,20,21,15,10,184,26,17,11,255,31, 21,12,207,18,13,9,28,0,8,11,9,8,156,184,93,27,255,208,105,29, 255,205,111,28,255,28,19,11,255,0,40,14,11,7,170,184,92,25,255,203, 104,24,255,200,98,23,255,26,18,11,255,0,255,0,189,8,7,5,57,51, 29,12,255,152,75,19,255,162,86,19,255,19,13,8,246,0,255,0,137,6, 5,3,28,19,13,6,249,92,46,13,255,123,63,14,255,78,39,11,255,21, 15,6,227,9,8,4,28,0,8,9,8,4,85,110,59,13,255,141,69,16, 255,141,75,16,255,21,14,6,170,0,12,16,11,5,170,52,28,9,255,115, 59,14,255,116,60,15,255,43,26,10,255,9,7,6,125,0,16,8,7,5, 28,21,17,10,227,109,59,18,255,160,82,19,255,121,64,18,255,62,34,13, 255,94,53,17,255,149,78,20,255,102,54,19,255,32,22,11,255,72,39,15, 255,121,62,18,255,24,17,9,187,0,40,8,6,3,167,128,66,15,255,161, 85,17,255,159,81,18,255,24,15,7,178,0,4,6,5,3,37,48,28,11, 255,173,92,20,255,181,96,20,255,21,15,8,221,0,4,6,5,3,28,40, 24,9,255,143,74,18,255,158,80,17,255,21,15,6,181,0,8,10,8,5, 54,107,51,14,255,157,83,18,255,164,84,19,255,176,89,19,255,189,92,20, 255,191,98,22,255,190,106,23,255,197,110,26,255,203,108,24,255,203,117,24, 255,205,119,26,255,207,122,30,255,199,118,32,255,32,23,13,170,0,12,7, 6,4,85,22,15,7,232,113,54,14,255,146,75,17,255,158,80,17,255,154, 78,17,255,158,80,17,255,148,76,17,255,139,71,16,255,135,66,16,255,135, 66,16,255,21,14,6,136,0,8,10,8,5,85,128,66,15,255,161,85,17, 255,158,80,17,255,25,16,6,204,0,12,7,6,4,28,25,16,8,227,102, 50,15,255,148,76,17,255,142,73,17,255,84,45,13,255,10,8,5,113,0, 8,9,7,4,82,107,53,14,255,146,75,17,255,84,41,13,255,8,7,5, 198,3,2,2,23,5,4,4,136,38,23,9,255,136,70,17,255,140,72,17, 255,21,15,6,178,0,24,7,6,4,57,45,26,10,255,143,74,18,255,158, 80,17,255,26,17,6,170,0,12,24,16,7,227,115,58,16,255,148,76,17, 255,46,26,9,255,7,6,4,156,0,16,5,4,4,71,19,13,6,255,139, 71,16,255,140,72,17,255,43,26,10,255,9,8,4,85,0,16,14,10,5, 85,109,52,14,255,38,23,9,255,6,5,3,85,0,12,4,4,3,28,15, 12,6,227,115,56,16,255,29,19,8,170,0,32,13,10,6,113,122,64,21, 255,164,85,21,255,138,71,17,255,21,15,6,161,0,156,13,10,6,227,137, 67,16,255,154,75,17,255,84,45,13,255,10,8,5,116,0,8,9,7,4, 85,111,55,14,255,158,87,17,255,158,80,17,255,19,13,6,255,4,4,3, 28,0,4,3,3,2,113,17,12,6,255,139,71,16,255,161,85,17,255,146, 75,17,255,20,14,7,210,0,16,16,13,9,110,184,105,27,255,209,123,30, 255,210,124,31,255,208,123,31,255,207,122,30,255,27,20,12,255,0,24,13, 11,8,147,143,75,20,255,161,85,17,255,158,80,17,255,27,18,8,227,5, 4,2,28,0,8,10,7,5,198,131,65,16,255,161,85,17,255,150,76,17, 255,21,14,6,170,0,8,10,8,5,85,123,61,16,255,163,83,18,255,158, 80,17,255,27,18,8,227,5,4,2,28,0,8,9,7,4,198,130,66,15, 255,163,83,18,255,148,76,17,255,21,14,6,193,0,28,7,6,4,85,22, 15,7,255,131,65,16,255,154,78,17,255,154,78,17,255,154,78,17,255,154, 78,17,255,21,15,6,170,0,8,10,8,5,85,129,64,16,255,163,86,18, 255,180,91,19,255,29,20,10,255,3,3,2,93,0,36,10,8,5,122,121, 60,16,255,161,85,17,255,159,81,18,255,24,15,7,255,4,4,3,34,0, 4,2,2,1,6,17,13,8,181,181,93,22,255,203,108,24,255,205,114,26, 255,32,23,13,210,0,36,5,4,4,161,30,22,13,255,198,116,29,255,206, 106,25,255,191,96,20,255,26,17,7,170,0,8,9,7,4,85,116,60,15, 255,161,85,17,255,158,80,17,255,21,14,6,255,5,4,2,28,0,4,2, 2,1,3,12,9,7,215,190,107,25,255,211,124,30,255,208,134,37,255,32, 22,13,178,0,8,13,11,8,96,187,112,32,255,209,123,30,255,191,96,20, 255,28,19,9,255,4,3,3,74,0,4,3,2,2,28,13,10,8,227,196, 120,31,255,211,124,30,255,199,106,24,255,27,19,10,170,0,8,13,10,6, 57,114,61,19,255,178,91,21,255,182,102,23,255,23,17,10,173,0,8,11, 9,6,91,146,85,25,255,198,113,29,255,196,120,31,255,27,20,12,207,0, 20,5,5,4,28,21,17,12,227,190,118,33,255,209,131,40,255,161,100,34, 255,17,14,10,227,5,5,4,28,0,72,9,8,6,170,91,59,28,255,189, 94,24,255,162,83,19,255,39,25,12,255,7,7,6,85,0,20,13,11,8, 142,183,103,24,255,203,112,24,255,203,112,24,255,42,26,13,249,5,4,4, 62,0,4,3,2,2,25,12,9,7,227,195,115,30,255,212,127,35,255,211, 132,38,255,32,22,13,181,0,8,12,10,7,85,124,65,17,255,161,85,17, 255,159,78,18,255,21,14,6,255,5,4,2,28,0,8,7,6,4,224,133, 68,16,255,159,81,18,255,146,72,17,255,22,14,7,170,0,8,13,11,8, 91,185,111,32,255,210,125,33,255,205,114,26,255,37,26,14,255,4,4,3, 85,0,4,4,4,4,28,13,10,8,227,193,105,26,255,206,111,27,255,202, 118,27,255,32,22,13,170,0,8,11,9,6,127,174,91,23,255,202,102,21, 255,200,105,21,255,36,23,13,255,4,4,3,85,0,4,3,3,2,28,13, 11,8,227,198,118,33,255,212,127,35,255,208,128,33,255,31,22,12,181,0, 8,13,11,8,91,185,114,30,255,211,124,30,255,208,122,29,255,34,24,13, 255,4,4,3,85,0,4,7,6,6,113,32,24,13,255,185,95,22,255,202, 98,21,255,198,97,23,255,33,22,12,170,0,8,10,8,7,156,190,108,27, 255,212,126,33,255,211,127,36,255,40,26,15,255,4,4,3,85,0,4,3, 3,2,28,13,11,8,227,198,118,33,255,214,129,37,255,211,132,38,255,32, 23,13,173,0,8,10,8,7,144,167,87,22,255,185,94,20,255,165,87,18, 255,25,17,8,255,3,3,2,57,0,28,13,11,8,170,195,112,30,255,210, 125,33,255,208,117,29,255,39,26,14,255,4,4,3,85,0,28,12,10,7, 150,184,108,27,255,211,124,30,255,211,127,36,255,40,27,15,255,4,4,3, 85,0,4,3,3,2,28,17,13,8,178,138,71,17,255,161,85,17,255,155, 79,18,255,21,14,6,170,0,8,10,8,5,85,124,61,15,255,169,89,18, 255,180,91,19,255,25,18,10,255,0,12,13,11,8,170,196,113,31,255,211, 124,30,255,205,119,26,255,26,18,11,204,0,8,11,9,6,88,134,70,19, 255,173,87,18,255,168,86,19,255,20,13,7,255,0,40,13,11,8,170,196, 113,31,255,210,125,33,255,207,122,30,255,24,18,11,212,0,8,11,9,6, 119,180,93,23,255,203,108,24,255,202,103,23,255,20,15,9,255,0,8,15, 13,10,195,101,63,26,255,202,117,25,255,206,128,35,255,160,106,35,255,15, 13,10,142,0,8,10,8,5,147,139,70,20,255,191,96,20,255,200,105,21, 255,25,18,10,255,0,32,13,10,8,170,189,99,26,255,206,115,27,255,205, 106,26,255,185,106,28,255,79,52,26,255,10,9,7,122,0,4,7,6,6, 42,36,27,17,244,172,106,35,255,207,128,34,255,211,126,34,255,211,127,36, 255,24,18,11,227,0,8,10,8,5,85,124,64,15,255,159,81,18,255,158, 80,17,255,76,40,13,255,11,8,6,210,0,8,12,9,5,85,129,64,16, 255,161,85,17,255,158,80,17,255,26,16,7,170,0,8,9,7,4,85,115, 56,16,255,161,85,17,255,159,81,18,255,49,27,10,255,7,6,4,170,5, 4,4,85,6,5,3,113,26,19,11,255,185,95,22,255,202,102,21,255,197, 104,22,255,28,20,11,173,0,8,13,10,6,102,167,87,22,255,200,101,21, 255,201,102,22,255,32,21,11,255,4,3,3,65,0,4,2,2,1,17,12, 10,7,221,190,98,23,255,208,116,27,255,204,110,27,255,30,21,11,181,0, 8,13,11,8,91,185,114,30,255,211,124,30,255,209,123,30,255,86,55,25, 255,9,8,6,187,6,6,5,85,7,6,6,130,32,24,15,255,200,122,31, 255,209,123,30,255,206,122,31,255,32,23,13,173,0,8,10,8,7,144,191, 113,30,255,212,127,35,255,210,126,35,255,40,27,15,255,4,4,3,85,0, 4,2,2,1,8,11,9,6,212,157,81,20,255,189,92,20,255,190,97,21, 255,27,19,10,178,0,8,12,10,7,96,183,105,28,255,209,123,30,255,205, 114,26,255,36,24,13,255,4,4,3,85,0,4,4,4,4,28,18,14,9, 187,195,115,30,255,211,124,30,255,210,130,35,255,35,26,14,210,0,20,3, 2,2,28,12,10,7,227,195,115,30,255,211,124,30,255,209,123,30,255,38, 25,15,255,4,4,3,85,0,20,13,11,8,170,194,115,31,255,209,122,28, 255,196,99,21,255,21,15,8,255,0,12,11,9,6,170,153,79,20,255,187, 91,20,255,181,96,20,255,30,20,9,178,0,8,13,10,6,96,151,79,20, 255,187,91,20,255,181,96,20,255,22,16,9,255,0,12,12,9,7,170,146, 76,19,255,167,88,18,255,158,77,17,255,23,15,6,170,0,8,10,8,5, 85,133,66,16,255,167,88,18,255,168,86,19,255,22,16,9,255,0,20,12, 9,7,170,155,80,20,255,185,94,20,255,181,96,20,255,22,16,9,221,0, 8,6,6,5,42,51,29,12,255,150,81,19,255,165,87,18,255,42,26,11, 255,5,5,4,108,0,4,5,5,4,28,18,15,11,255,195,114,28,255,207, 123,32,255,158,94,31,255,17,13,10,142,0,8,6,5,5,57,50,34,19, 255,191,111,32,255,208,117,29,255,113,73,30,255,10,10,9,227,6,6,5, 125,7,7,6,198,42,29,17,255,187,96,22,255,166,87,23,255,42,27,15, 255,8,6,5,110,0,32,5,5,4,184,21,16,8,255,106,54,15,255,154, 78,17,255,151,77,18,255,92,48,15,255,11,9,6,119,0,8,10,8,5, 93,131,69,18,255,189,92,20,255,200,105,21,255,33,22,12,255,5,4,4, 54,0,12,9,8,6,85,76,53,25,255,200,118,31,255,204,114,27,255,65, 43,22,255,6,6,5,113,0,32,4,3,3,17,14,11,9,227,195,111,28, 255,206,115,27,255,204,105,25,255,24,17,11,255,0,12,5,5,4,28,13, 10,6,227,125,66,18,255,165,84,18,255,161,85,17,255,161,85,17,255,155, 79,18,255,28,19,9,255,6,5,3,85,0,64,11,9,8,68,86,56,27, 255,204,126,33,255,210,125,33,255,30,21,13,255,0,68,13,11,8,170,195, 115,30,255,209,123,30,255,207,122,30,255,27,19,12,255,3,3,2,28,0, 128,7,6,4,184,131,65,16,255,161,85,17,255,154,78,17,255,15,11,6, 249,0,76,10,8,7,173,166,87,23,255,198,104,21,255,196,99,21,255,35, 23,12,255,3,3,2,85,0,72,13,11,8,170,194,115,31,255,211,124,30, 255,207,122,30,255,27,19,12,255,3,3,2,28,0,108,13,11,8,170,196, 113,31,255,213,132,36,255,211,127,36,255,30,21,13,255,0,40,11,9,6, 170,155,80,20,255,185,94,20,255,180,91,19,255,21,15,8,255,0,255,0, 189,10,8,7,184,183,100,26,255,208,116,27,255,204,114,27,255,26,18,11, 255,4,4,4,28,0,255,0,133,10,8,5,127,119,60,15,255,160,85,19, 255,91,48,16,255,10,8,5,227,4,4,3,28,0,12,9,7,4,161,131, 67,16,255,159,81,18,255,159,78,18,255,18,13,7,249,0,16,7,6,4, 170,57,34,14,255,176,90,21,255,195,95,22,255,26,19,11,232,0,16,17, 14,10,99,179,106,28,255,207,122,30,255,180,109,33,255,25,20,12,255,7, 6,6,170,20,17,11,255,196,114,27,255,208,117,29,255,203,124,30,255,172, 106,35,255,53,36,20,255,10,9,7,108,0,40,9,8,6,170,159,82,20, 255,202,103,23,255,206,111,27,255,22,17,11,255,0,8,10,9,7,139,115, 74,30,255,213,133,48,255,39,28,16,255,0,8,9,8,4,113,67,39,14, 255,181,92,20,255,24,18,9,255,0,12,28,19,9,227,139,79,26,255,206, 117,31,255,212,123,37,255,214,126,41,255,172,106,35,255,53,34,18,255,122, 78,31,255,211,127,44,255,217,136,50,255,216,135,49,255,190,122,41,255,65, 43,22,255,14,11,7,85,0,8,7,6,4,28,29,21,10,249,153,79,20, 255,174,85,19,255,103,53,16,255,17,12,6,244,19,13,6,170,21,14,6, 170,27,17,6,170,21,14,6,212,21,14,6,255,25,17,6,224,12,9,5, 45,0,12,24,16,7,153,22,15,7,255,26,16,7,210,12,9,5,40,0, 8,8,7,5,28,17,13,8,227,114,61,19,255,174,85,19,255,154,79,19, 255,60,33,13,255,11,9,6,170,0,12,10,8,5,170,146,79,19,255,180, 87,19,255,67,39,14,255,8,6,5,85,0,8,24,17,9,255,143,75,20, 255,162,80,19,255,22,15,7,215,0,28,8,7,5,110,60,33,13,255,166, 78,19,255,22,15,7,227,0,8,7,6,4,85,91,51,16,255,174,88,19, 255,169,78,18,255,25,17,8,255,3,3,2,8,0,20,11,9,6,178,143, 74,18,255,177,89,18,255,138,75,19,255,18,13,7,176,0,16,9,7,4, 28,29,19,8,232,41,25,10,255,17,13,8,255,9,8,6,116,0,4,7, 6,4,59,14,11,7,227,32,21,9,255,40,24,9,255,12,9,5,105,0, 32,14,11,9,170,199,124,36,255,213,119,36,255,202,102,21,255,20,14,7, 246,0,152,8,7,5,142,53,31,12,255,162,86,19,255,121,64,18,255,19, 14,8,252,6,5,3,28,0,8,10,8,5,125,142,74,19,255,180,91,19, 255,183,89,19,255,19,14,8,255,0,4,5,5,4,6,15,13,10,193,69, 42,18,255,171,91,20,255,189,88,20,255,200,101,21,255,31,21,12,255,0, 16,10,8,7,28,30,21,13,227,150,92,35,255,208,121,37,255,211,115,30, 255,208,117,29,255,28,21,13,255,0,24,10,8,7,28,22,15,7,198,26, 17,7,255,24,15,7,221,9,7,4,57,0,12,8,7,5,156,171,89,22, 255,202,107,23,255,202,103,23,255,23,18,10,249,0,12,26,18,9,198,29, 19,8,255,24,16,7,215,10,8,5,51,0,12,10,8,5,85,134,70,19, 255,175,88,18,255,173,87,18,255,20,14,7,255,0,24,10,8,5,85,26, 19,9,255,107,58,18,255,154,83,19,255,168,79,19,255,169,78,18,255,173, 87,18,255,172,80,19,255,26,17,7,170,0,8,11,10,8,136,189,99,26, 255,210,115,31,255,216,129,45,255,143,96,40,255,15,13,10,227,12,12,11, 170,15,13,12,170,13,12,10,170,13,12,10,136,9,8,8,85,0,16,11, 9,6,170,169,91,22,255,202,103,23,255,203,108,24,255,18,15,9,255,0, 12,6,5,5,23,28,19,11,156,31,22,12,255,34,24,13,227,14,11,7, 85,0,36,9,8,8,142,72,54,31,255,215,147,60,255,218,146,61,255,174, 100,35,255,14,11,7,142,0,8,11,8,6,102,142,74,19,255,185,86,20, 255,195,98,20,255,18,14,9,249,0,12,10,8,7,170,202,131,47,255,220, 152,63,255,220,151,61,255,22,19,13,252,0,8,11,9,8,167,203,135,46, 255,217,139,48,255,210,120,33,255,18,14,9,255,0,12,9,8,6,170,198, 117,37,255,211,115,30,255,202,102,21,255,34,22,11,176,0,8,13,11,8, 170,202,122,37,255,218,144,49,255,217,144,50,255,28,21,13,255,0,8,12, 11,9,170,204,122,41,255,217,135,46,255,215,136,42,255,46,33,19,255,0, 16,10,9,7,28,21,19,14,227,153,104,46,255,214,149,55,255,158,103,39, 255,16,14,11,221,7,6,6,28,0,20,20,18,13,142,31,26,18,170,25, 21,16,170,24,20,15,170,24,20,15,170,24,20,15,170,24,21,15,170,31, 26,18,170,25,21,16,170,14,12,9,31,0,20,10,9,7,167,75,51,26, 255,202,117,33,255,186,120,43,255,41,32,20,255,12,11,9,85,0,16,11, 9,8,28,31,22,12,215,49,33,18,255,41,27,16,227,12,10,7,85,0, 12,14,12,9,170,204,137,51,255,220,152,63,255,220,151,61,255,23,19,12, 252,0,8,11,10,6,85,136,70,17,255,175,88,18,255,169,78,18,255,15, 11,6,255,0,8,9,8,6,85,26,19,9,255,153,82,18,255,177,89,18, 255,180,84,19,255,24,17,9,218,0,8,11,9,8,147,196,115,35,255,215, 125,38,255,214,125,39,255,20,16,11,255,0,12,9,8,6,159,165,86,22, 255,197,99,20,255,195,90,20,255,32,21,11,170,0,8,12,10,7,85,145, 76,20,255,189,92,20,255,191,96,20,255,18,14,9,255,0,12,9,8,6, 170,199,126,39,255,217,133,50,255,217,144,50,255,23,18,12,252,0,8,11, 10,8,142,191,105,28,255,206,111,27,255,203,104,24,255,19,15,10,255,0, 12,9,8,6,57,21,15,8,198,28,19,9,255,32,21,11,227,11,9,6, 76,0,8,11,9,8,170,203,125,42,255,220,146,59,255,219,146,60,255,24, 19,13,255,0,12,11,10,8,170,204,136,47,255,220,146,59,255,218,147,55, 255,25,19,12,232,0,8,11,10,8,119,161,87,22,255,195,98,20,255,202, 103,23,255,18,15,9,255,0,32,14,12,9,170,200,125,37,255,214,124,37, 255,205,106,26,255,20,16,9,221,0,32,16,13,9,170,205,130,42,255,219, 144,56,255,219,146,60,255,24,19,13,255,0,12,6,5,3,23,21,14,6, 170,26,16,7,255,26,17,7,224,14,10,5,31,0,8,11,9,6,125,170, 89,23,255,211,115,30,255,214,126,41,255,23,19,12,255,0,12,11,10,8, 170,195,112,30,255,206,106,25,255,200,105,21,255,29,20,10,170,0,8,11, 9,6,85,134,70,19,255,177,85,18,255,172,80,19,255,18,13,7,255,0, 40,14,12,9,170,195,112,30,255,206,111,27,255,202,103,23,255,31,22,10, 170,0,8,13,10,6,85,151,79,20,255,189,92,20,255,183,89,19,255,17, 13,8,255,0,4,8,7,5,59,57,34,16,255,184,97,27,255,198,115,33, 255,114,77,33,255,16,14,11,210,6,5,5,8,0,8,12,10,7,170,195, 113,32,255,215,123,42,255,217,133,50,255,32,24,15,255,0,32,12,11,7, 170,175,90,22,255,198,104,21,255,189,92,20,255,192,97,21,255,189,97,22, 255,45,29,14,255,10,9,7,210,22,17,11,255,183,102,30,255,212,121,41, 255,216,135,49,255,217,137,52,255,214,125,39,255,29,21,12,204,0,8,11, 9,6,85,143,75,20,255,193,97,20,255,195,98,20,255,180,93,23,255,88, 54,23,255,11,10,8,113,0,4,14,12,7,85,170,89,23,255,202,103,23, 255,202,102,21,255,32,22,11,178,0,8,12,10,7,113,176,91,23,255,205, 105,24,255,209,117,28,255,39,28,16,255,5,5,5,28,0,8,15,14,10, 198,206,132,45,255,217,133,50,255,215,133,44,255,25,19,12,232,0,8,11, 10,8,125,198,118,39,255,218,145,51,255,218,146,53,255,20,17,11,255,0, 12,9,8,6,170,198,124,37,255,216,134,45,255,214,139,41,255,22,18,11, 255,0,8,11,10,8,136,191,105,28,255,206,111,27,255,206,106,25,255,36, 26,15,255,5,5,4,28,0,8,15,13,10,198,192,105,27,255,206,106,25, 255,204,105,25,255,23,17,10,232,0,8,12,10,7,125,196,119,37,255,218, 141,51,255,218,139,55,255,20,16,11,255,0,12,9,8,6,170,196,110,33, 255,215,126,40,255,214,125,39,255,23,18,12,252,0,8,11,9,8,167,201, 123,40,255,217,133,50,255,214,136,43,255,20,16,11,255,0,12,6,5,5, 23,29,21,12,153,32,22,13,255,35,25,14,227,15,12,8,85,0,24,12, 10,9,170,198,124,37,255,215,125,38,255,213,124,38,255,23,18,12,255,0, 24,14,12,9,170,204,132,47,255,219,144,56,255,211,127,36,255,28,21,13, 255,0,12,14,12,9,170,198,117,37,255,215,123,42,255,214,125,39,255,25, 20,12,215,0,8,11,10,8,130,198,119,35,255,215,126,40,255,212,123,37, 255,30,22,13,255,0,12,14,12,9,170,196,114,33,255,206,106,25,255,200, 105,21,255,30,21,11,184,0,8,13,11,8,99,184,100,25,255,209,117,28, 255,210,115,31,255,28,21,13,255,0,20,14,12,9,170,198,117,37,255,215, 126,40,255,214,126,41,255,25,19,12,255,0,12,10,9,7,125,61,42,22, 255,190,107,33,255,153,98,38,255,29,23,16,255,13,12,10,255,17,15,10, 255,108,74,37,255,210,144,59,255,153,98,38,255,16,14,11,224,6,6,5, 17,0,12,15,13,8,227,115,67,24,255,197,100,22,255,150,81,25,255,32, 24,13,255,15,13,8,255,19,15,10,255,85,48,18,255,178,95,21,255,115, 65,20,255,15,12,8,255,5,5,4,34,0,32,10,9,7,198,69,46,22, 255,186,103,29,255,195,111,28,255,92,58,25,255,15,12,8,198,0,12,10, 9,7,170,194,112,31,255,215,125,38,255,218,146,53,255,24,19,13,255,0, 20,15,14,10,227,159,103,42,255,212,127,43,255,177,118,48,255,19,17,12, 227,6,6,5,28,0,32,11,10,8,170,182,98,23,255,202,106,21,255,195, 98,20,255,24,17,9,212,0,12,18,14,9,227,102,54,19,255,157,83,18, 255,85,46,14,255,19,13,6,255,47,27,10,255,150,81,19,255,131,67,20, 255,39,26,14,255,12,11,9,85,0,64,10,9,7,170,118,75,33,255,215, 141,54,255,44,33,19,255,0,16,9,9,8,108,19,17,12,170,27,23,16, 170,23,21,16,170,23,21,16,170,24,20,15,170,20,18,13,170,15,14,10, 170,10,9,7,113,7,6,6,28,0,12,12,11,9,170,189,99,26,255,209, 110,30,255,211,118,36,255,141,88,36,255,19,17,12,227,20,18,13,170,24, 20,15,170,21,19,14,170,16,14,11,170,10,9,7,113,6,6,5,28,0, 20,8,7,5,65,11,10,8,142,16,14,11,170,24,21,15,170,25,22,16, 170,23,21,16,170,21,19,14,170,16,14,11,170,11,10,8,113,7,7,6, 28,0,20,8,7,5,62,10,9,5,136,12,10,7,170,14,11,7,170,13, 10,6,170,11,9,6,198,31,21,10,255,153,82,18,255,177,85,18,255,169, 78,18,255,22,15,7,204,0,16,8,7,5,57,11,10,6,142,19,17,12, 170,23,21,16,170,25,22,16,170,23,21,16,170,21,19,14,170,15,14,10, 170,10,10,9,113,7,6,6,28,0,16,12,10,7,153,55,32,14,255,175, 93,20,255,185,94,20,255,183,89,19,255,80,44,17,255,13,11,8,187,7, 6,6,25,0,16,8,7,5,62,11,10,6,142,16,14,11,170,23,19,14, 170,25,22,16,170,23,21,16,170,19,17,12,170,15,14,10,170,17,15,10, 170,19,17,12,142,9,8,8,28,0,8,12,10,9,170,204,137,49,255,220, 146,59,255,218,146,53,255,141,91,38,255,19,17,12,227,19,17,12,170,24, 20,15,170,21,19,14,170,15,14,10,170,10,10,9,113,7,6,6,28,0, 16,12,10,7,57,14,12,7,102,14,11,7,85,0,32,12,10,7,57,13, 11,8,105,15,13,8,85,0,12,12,11,9,170,204,136,47,255,220,146,59, 255,218,153,59,255,24,19,13,255,0,12,8,7,5,82,11,10,6,156,11, 9,6,170,10,9,7,91,0,12,10,8,5,127,144,78,19,255,180,87,19, 255,174,81,19,255,24,15,7,210,0,12,14,11,7,68,12,10,7,170,12, 10,7,170,17,15,10,170,24,20,15,170,19,17,12,170,15,14,10,170,18, 15,11,170,24,21,15,170,21,19,14,170,15,14,10,170,11,10,8,113,7, 7,6,28,0,16,15,13,10,119,17,15,12,170,15,13,10,170,16,14,11, 170,19,17,12,170,21,18,12,170,18,15,11,170,15,13,8,170,11,9,6, 170,10,8,7,88,6,5,5,23,0,20,10,9,7,85,14,12,9,170,19, 17,12,170,21,19,14,170,21,19,14,170,21,19,14,170,19,17,12,170,15, 14,10,170,11,10,8,116,7,7,6,28,0,16,15,14,10,119,18,15,11, 170,15,14,10,170,18,15,11,170,21,19,14,170,25,22,16,170,23,21,16, 170,21,19,14,170,16,14,11,170,11,10,8,113,7,7,6,28,0,20,10, 9,7,85,14,12,9,170,19,17,12,170,20,18,13,170,20,18,13,170,23, 19,14,170,19,17,12,170,15,14,10,170,17,14,10,170,19,17,12,142,10, 9,7,28,0,12,15,13,10,113,18,15,11,170,15,14,10,170,18,15,11, 170,21,19,14,170,25,22,16,170,23,21,16,170,20,18,13,170,16,14,11, 170,11,10,8,113,7,7,6,28,0,20,7,7,6,82,11,10,6,142,16, 13,9,170,19,17,12,170,21,19,14,170,24,21,15,170,25,22,16,170,25, 22,16,170,15,13,10,170,12,11,9,57,0,16,15,13,10,170,97,65,34, 255,209,132,42,255,214,136,43,255,214,127,43,255,159,103,42,255,21,19,14, 227,11,10,8,28,0,12,16,14,11,113,21,19,14,170,18,15,11,153,11, 10,8,28,0,16,15,14,10,125,21,19,14,170,19,17,12,142,10,9,7, 28,0,12,15,14,10,113,21,19,14,170,18,16,11,153,11,10,8,28,0, 16,15,13,10,125,21,19,14,170,19,17,12,142,10,9,7,28,0,12,15, 14,10,113,21,19,14,170,18,16,11,153,11,10,8,28,0,24,15,14,10, 125,21,19,14,170,19,17,12,142,9,9,8,28,0,12,17,14,10,130,27, 24,16,170,21,19,14,142,10,9,7,28,0,16,16,14,11,113,28,24,17, 170,24,21,15,161,12,11,9,28,0,12,16,14,11,113,21,19,14,170,18, 15,11,153,11,10,8,28,0,16,15,13,10,125,21,19,14,170,19,17,12, 142,9,8,6,28,0,12,18,15,11,136,19,16,10,170,16,13,9,170,16, 14,9,170,15,13,8,170,13,11,8,170,12,11,9,170,13,12,8,170,15, 14,10,170,14,13,11,170,11,11,10,113,0,20,13,11,8,170,190,98,23, 255,204,116,31,255,74,52,27,255,9,8,8,113,0,16,13,11,8,170,192, 106,29,255,208,112,27,255,208,117,29,255,27,21,12,255,0,16,5,5,4, 28,27,23,16,255,199,121,44,255,214,139,41,255,31,23,14,255,0,16,13, 11,8,28,32,24,13,227,36,26,15,255,19,16,12,198,8,8,7,51,0, 4,8,8,7,57,29,21,12,218,48,32,17,255,45,30,16,255,20,16,11, 218,10,9,7,105,0,44,14,12,9,170,204,130,51,255,224,153,77,255,225, 169,88,255,33,27,18,255,0,12,21,19,14,215,217,163,86,255,61,46,28, 255,0,12,19,16,12,201,203,121,40,255,51,38,22,255,0,12,4,4,3, 25,16,14,11,227,212,147,71,255,224,160,77,255,223,161,80,255,31,25,16, 255,4,4,4,102,10,10,9,215,206,133,55,255,223,156,70,255,224,164,85, 255,51,39,24,255,5,5,4,82,0,12,15,12,8,110,178,98,27,255,211, 115,30,255,211,121,34,255,36,26,15,255,3,3,2,85,0,60,8,8,5, 28,27,20,10,232,125,73,22,255,190,97,21,255,180,92,21,255,97,56,20, 255,14,11,7,170,0,16,12,10,7,142,165,89,22,255,198,104,21,255,84, 50,19,255,7,6,4,159,0,4,5,5,4,82,32,23,11,255,121,69,22, 255,97,56,20,255,15,13,8,142,0,32,14,12,7,198,172,92,21,255,28, 19,9,207,0,8,11,10,6,85,148,78,21,255,198,104,21,255,192,97,21, 255,21,15,8,255,0,24,10,9,5,170,167,90,22,255,202,93,21,255,202, 103,23,255,21,16,10,255,0,20,4,3,3,133,20,16,9,255,151,80,22, 255,75,42,16,255,10,8,7,255,32,22,11,255,164,86,23,255,60,39,17, 255,5,5,4,252,0,36,12,11,9,198,213,155,80,255,224,166,83,255,211, 121,34,255,20,16,9,255,3,3,2,28,0,144,6,6,5,51,27,20,10, 255,160,84,23,255,198,104,21,255,67,40,16,255,8,7,5,125,0,12,12, 10,9,170,195,112,30,255,215,125,38,255,217,133,50,255,49,35,22,255,5, 5,4,133,13,12,10,210,189,119,50,255,211,127,44,255,212,121,41,255,218, 135,53,255,220,148,63,255,34,27,17,255,0,20,4,4,4,17,13,12,10, 227,196,113,31,255,212,118,35,255,214,123,43,255,33,26,16,255,0,56,12, 11,9,187,208,134,55,255,223,146,70,255,221,152,70,255,34,26,17,255,0, 40,8,7,5,164,165,86,22,255,202,98,21,255,198,96,21,255,22,16,9, 255,0,20,8,8,5,85,32,22,11,255,167,87,22,255,160,84,23,255,93, 54,20,255,120,65,21,255,188,96,21,255,196,99,21,255,200,105,21,255,24, 19,11,207,0,8,15,14,10,110,208,152,71,255,227,174,98,255,228,179,103, 255,225,176,98,255,217,169,94,255,213,166,92,255,215,167,92,255,213,155,80, 255,204,136,55,255,138,89,37,255,25,22,16,227,9,9,8,28,0,8,11, 10,8,170,203,129,50,255,223,149,70,255,222,158,75,255,31,25,16,255,4, 4,4,28,0,60,8,8,7,57,49,40,26,255,206,152,83,255,224,169,91, 255,194,140,71,255,31,27,20,255,9,8,8,28,0,8,12,10,9,161,196, 110,33,255,218,130,51,255,222,158,75,255,31,25,16,255,4,4,4,28,0, 8,11,10,8,198,213,160,84,255,228,180,105,255,227,175,100,255,33,28,18, 207,0,8,12,11,9,130,210,155,77,255,228,169,99,255,226,172,95,255,30, 25,17,255,4,4,4,28,0,8,11,10,8,198,204,129,49,255,214,127,43, 255,213,125,40,255,23,19,12,232,0,8,14,13,9,125,208,152,71,255,223, 159,76,255,218,153,59,255,33,26,16,210,0,8,13,12,10,127,198,118,39, 255,215,127,42,255,213,126,42,255,41,31,18,227,0,12,6,6,5,28,25, 21,16,227,204,150,79,255,223,171,98,255,175,122,60,255,18,15,11,218,5, 4,4,17,0,20,20,18,13,85,177,101,34,255,204,123,37,255,199,117,36, 255,199,117,36,255,202,122,37,255,199,117,36,255,198,114,31,255,198,110,31, 255,202,118,35,255,46,33,21,170,0,24,10,9,7,153,110,78,37,255,213, 162,82,255,218,164,87,255,67,51,30,255,9,8,8,85,0,40,6,5,5, 28,21,19,14,255,217,166,92,255,227,175,100,255,224,169,91,255,31,25,16, 215,0,8,12,10,7,85,154,80,21,255,197,99,20,255,192,97,21,255,28, 20,9,255,4,3,3,110,11,9,6,170,117,63,20,255,184,94,21,255,198, 104,21,255,203,104,24,255,210,122,37,255,21,17,12,252,0,8,10,9,7, 161,203,129,50,255,224,160,77,255,225,169,88,255,30,25,17,255,4,4,4, 28,0,8,8,7,5,190,165,86,22,255,198,104,21,255,196,99,21,255,28, 19,9,170,0,8,13,11,8,85,176,91,23,255,208,112,27,255,210,121,35, 255,27,22,14,255,4,4,4,28,0,8,11,10,8,198,211,149,76,255,224, 168,87,255,224,162,81,255,32,26,17,210,0,8,12,10,7,113,176,91,23, 255,202,107,23,255,202,95,23,255,20,16,9,255,0,40,15,13,10,170,213, 160,84,255,228,180,105,255,227,174,98,255,33,26,18,255,0,12,15,13,10, 170,213,155,80,255,226,172,95,255,224,167,85,255,23,20,14,244,0,8,11, 10,8,127,189,104,28,255,214,127,43,255,221,148,70,255,31,25,16,255,4, 4,4,28,0,28,14,12,9,170,195,113,32,255,209,117,28,255,202,103,23, 255,20,15,9,252,3,3,3,14,0,28,15,14,10,170,213,155,80,255,226, 172,95,255,221,152,70,255,28,24,15,255,0,40,14,12,9,170,208,141,61, 255,225,162,88,255,227,174,98,255,33,26,18,255,4,4,4,28,0,8,10, 8,7,198,182,98,23,255,202,103,23,255,198,104,21,255,28,19,9,170,0, 8,11,10,6,85,154,80,21,255,202,98,21,255,202,103,23,255,25,20,12, 255,0,40,12,10,7,170,186,100,23,255,202,99,23,255,200,105,21,255,30, 21,9,170,0,8,12,9,7,85,154,80,21,255,198,104,21,255,196,99,21, 255,28,20,9,255,4,4,3,113,11,10,6,227,183,100,26,255,212,127,43, 255,167,117,52,255,17,15,12,215,5,5,5,14,0,12,15,13,10,170,211, 149,76,255,224,166,83,255,223,161,80,255,34,26,17,255,0,32,10,9,7, 170,167,87,22,255,198,92,21,255,196,99,21,255,196,95,21,255,198,92,21, 255,195,99,22,255,192,106,29,255,206,127,43,255,217,141,60,255,223,146,70, 255,224,165,81,255,220,148,63,255,212,124,39,255,25,19,12,215,0,8,12, 11,9,116,196,116,37,255,218,141,51,255,218,139,55,255,218,142,61,255,215, 143,58,255,24,19,13,212,0,4,10,9,7,156,203,129,50,255,221,150,66, 255,220,148,63,255,25,21,14,227,0,8,10,10,7,159,204,134,59,255,225, 160,84,255,225,169,88,255,36,29,19,255,0,12,15,14,10,170,204,130,51, 255,220,142,59,255,218,139,55,255,21,18,12,249,0,8,11,10,8,142,206, 145,67,255,226,172,95,255,227,174,98,255,32,26,17,255,4,4,4,28,0, 8,11,10,8,198,198,117,37,255,215,125,38,255,211,122,36,255,28,21,13, 215,0,8,13,11,8,96,174,91,23,255,202,107,23,255,202,103,23,255,22, 17,9,255,0,12,11,10,6,170,176,91,23,255,202,103,23,255,203,108,24, 255,21,15,10,238,0,8,11,10,8,142,206,145,67,255,226,170,91,255,224, 160,85,255,30,24,17,255,4,4,4,28,0,8,11,10,8,198,209,149,70, 255,224,160,77,255,222,158,75,255,31,25,16,212,0,8,12,11,9,127,198, 116,35,255,215,125,38,255,211,122,36,255,28,21,13,255,4,4,4,28,0, 52,13,12,8,170,195,112,30,255,209,110,30,255,207,105,30,255,25,20,12, 255,0,24,15,14,10,170,213,158,80,255,226,172,95,255,224,164,85,255,33, 27,18,255,0,12,15,14,10,170,210,143,65,255,224,168,87,255,224,165,81, 255,25,21,14,232,0,8,10,10,9,153,208,147,67,255,224,166,83,255,222, 158,75,255,34,26,17,255,0,12,15,14,10,170,211,149,76,255,223,149,70, 255,219,146,60,255,25,20,14,235,0,8,10,10,9,150,204,134,59,255,224, 156,83,255,224,165,81,255,33,27,18,255,0,20,15,14,10,170,211,150,70, 255,226,170,91,255,226,172,95,255,33,26,18,255,0,16,9,9,8,150,101, 74,38,255,198,145,77,255,206,157,87,255,202,151,79,255,197,141,74,255,200, 146,75,255,180,126,57,255,21,19,14,227,5,5,4,28,0,16,8,7,5, 113,43,28,14,255,187,96,22,255,181,93,22,255,98,55,21,255,68,42,17, 255,77,46,18,255,129,72,22,255,174,89,21,255,83,47,18,255,11,9,6, 221,0,28,6,6,5,28,16,14,11,195,108,76,35,255,210,141,59,255,218, 162,81,255,167,118,54,255,16,14,11,221,5,5,5,14,0,12,15,13,10, 170,211,149,76,255,224,168,87,255,223,154,80,255,31,25,16,255,0,20,6, 6,5,57,34,27,17,255,203,122,36,255,208,124,41,255,109,76,34,255,13, 12,10,142,0,32,13,11,8,170,176,91,23,255,202,93,21,255,196,99,21, 255,28,19,9,170,0,8,11,9,6,85,132,71,21,255,195,99,22,255,103, 59,20,255,11,10,6,170,3,3,2,25,6,6,5,110,55,35,16,255,198, 113,29,255,212,134,51,255,41,32,20,210,0,68,21,19,14,215,217,163,86, 255,49,38,24,255,0,12,11,10,8,82,54,43,27,255,200,135,59,255,210, 137,59,255,207,131,50,255,205,127,44,255,199,117,36,255,195,111,28,255,187, 101,24,255,93,54,22,255,19,15,10,227,7,6,6,28,0,8,10,9,7, 170,195,109,32,255,218,138,53,255,224,158,81,255,223,173,95,255,219,167,94, 255,217,169,94,255,218,171,97,255,217,166,92,255,208,136,59,255,110,68,27, 255,19,15,10,227,6,6,5,28,0,12,12,11,7,170,61,42,20,255,188, 106,33,255,208,134,55,255,215,163,82,255,217,166,92,255,216,167,88,255,216, 167,89,255,211,150,70,255,146,94,39,255,26,21,15,229,9,8,6,28,0, 12,12,10,7,170,51,32,14,255,151,80,22,255,169,91,22,255,173,86,22, 255,169,88,22,255,173,86,22,255,180,92,21,255,194,98,21,255,196,95,21, 255,192,97,21,255,31,21,10,170,0,12,12,10,7,170,57,37,18,255,189, 107,34,255,212,149,67,255,217,166,92,255,217,166,92,255,218,171,97,255,215, 163,82,255,205,126,48,255,116,72,29,255,20,16,11,227,6,6,5,28,0, 8,11,9,6,68,126,68,21,255,191,98,22,255,194,98,21,255,192,97,21, 255,192,97,21,255,191,98,22,255,177,91,22,255,26,19,9,142,0,12,12, 10,7,170,58,37,17,255,185,107,30,255,208,134,55,255,216,167,88,255,218, 171,97,255,217,166,92,255,213,148,72,255,204,130,51,255,209,141,60,255,211, 159,76,255,30,25,17,170,0,8,10,10,7,167,210,155,77,255,228,178,99, 255,224,165,81,255,221,165,86,255,217,166,92,255,218,169,93,255,217,166,92, 255,214,156,81,255,206,135,51,255,116,72,29,255,20,16,11,227,6,6,5, 28,0,8,13,10,6,57,115,62,20,255,169,91,22,255,165,86,22,255,24, 18,9,167,0,24,12,10,7,88,117,63,20,255,186,100,23,255,191,107,32, 255,35,27,16,144,0,8,10,10,7,170,210,155,77,255,228,178,99,255,221, 152,70,255,24,19,13,255,0,8,12,10,7,170,58,36,15,255,157,79,22, 255,151,80,22,255,58,35,15,255,11,9,6,57,0,8,12,10,7,85,157, 81,20,255,197,99,20,255,192,97,21,255,28,20,9,170,0,8,11,9,6, 57,115,62,20,255,189,94,24,255,198,117,37,255,213,157,76,255,218,171,97, 255,217,169,94,255,214,161,85,255,213,157,76,255,212,149,67,255,208,134,55, 255,205,126,48,255,143,96,40,255,28,26,19,229,8,8,7,28,0,8,13, 12,8,85,141,74,24,255,190,94,23,255,183,95,24,255,183,95,24,255,187, 93,24,255,189,97,22,255,181,93,22,255,177,91,22,255,169,88,22,255,89, 52,20,255,21,18,12,227,9,9,8,28,0,12,18,17,13,181,103,74,40, 255,207,146,74,255,214,156,81,255,210,144,67,255,208,138,55,255,207,129,52, 255,205,133,48,255,205,126,48,255,151,101,42,255,28,26,19,232,9,8,8, 28,0,8,13,12,10,110,186,127,63,255,214,156,81,255,213,158,80,255,213, 155,80,255,214,156,81,255,214,153,75,255,213,148,72,255,213,148,72,255,211, 150,70,255,159,111,54,255,28,25,19,241,9,8,8,31,0,12,18,17,13, 181,103,74,40,255,208,156,81,255,214,156,81,255,208,138,55,255,209,137,60, 255,213,158,80,255,213,155,80,255,213,160,84,255,215,160,88,255,213,163,84, 255,30,24,17,178,0,8,12,11,9,93,178,121,53,255,213,158,80,255,210, 143,65,255,211,146,62,255,213,148,72,255,215,163,82,255,213,158,80,255,212, 149,67,255,209,141,60,255,153,106,49,255,28,25,19,235,9,9,8,31,0, 12,18,15,11,173,66,43,21,255,187,101,32,255,207,132,52,255,210,144,67, 255,213,148,72,255,214,156,81,255,216,167,88,255,214,156,81,255,176,128,65, 255,46,39,27,255,0,12,15,14,10,85,181,111,42,255,215,136,52,255,213, 125,40,255,211,122,36,255,212,123,37,255,210,123,39,255,202,122,37,255,31, 24,14,170,0,8,12,11,9,88,164,89,29,255,203,122,36,255,199,117,36, 255,30,23,15,212,0,12,15,13,10,127,187,133,62,255,213,148,72,255,208, 138,55,255,31,24,16,170,0,8,13,12,10,85,172,104,37,255,209,134,54, 255,206,135,51,255,32,25,17,212,0,12,15,13,10,127,181,116,46,255,211, 143,62,255,210,153,71,255,29,24,16,178,0,8,13,12,10,91,178,121,53, 255,213,154,70,255,208,134,55,255,31,25,16,210,0,20,15,14,10,125,179, 110,42,255,210,135,55,255,208,139,65,255,26,21,15,184,0,8,14,13,9, 85,179,117,44,255,217,165,82,255,213,163,84,255,27,23,16,221,0,12,14, 12,9,136,174,103,39,255,206,127,43,255,199,117,36,255,31,24,14,170,0, 8,12,11,9,88,164,89,29,255,202,118,35,255,196,114,33,255,29,22,14, 210,0,12,14,12,9,125,169,95,30,255,202,119,37,255,199,119,39,255,24, 19,13,190,0,8,14,12,9,85,170,95,29,255,198,113,29,255,199,116,34, 255,204,128,47,255,206,135,51,255,204,129,49,255,204,129,49,255,208,134,55, 255,211,149,76,255,192,140,73,255,95,74,39,255,17,15,12,85,0,16,14, 12,9,198,211,150,70,255,206,152,81,255,31,26,20,255,7,7,6,48,0, 16,15,13,10,170,211,149,76,255,226,170,91,255,226,172,95,255,35,28,18, 255,0,20,15,14,12,218,171,120,60,255,219,154,70,255,41,31,20,255,4, 4,3,28,0,104,17,16,12,170,219,179,116,255,232,193,137,255,232,199,135, 255,40,33,23,255,0,12,10,10,9,76,62,50,31,255,20,18,13,167,0, 12,11,10,8,76,58,46,29,255,20,18,13,167,0,16,13,12,10,170,210, 150,71,255,223,147,72,255,221,150,66,255,26,21,15,210,0,4,11,10,8, 119,211,159,84,255,229,184,114,255,230,186,123,255,30,26,19,255,0,16,12, 11,9,93,137,90,40,255,223,167,94,255,228,180,111,255,167,133,80,255,17, 16,14,227,11,11,10,170,12,11,9,170,12,11,9,170,12,11,9,119,7, 7,6,57,0,36,7,7,6,62,21,18,12,227,157,92,28,255,203,105,26, 255,197,106,26,255,82,48,21,255,14,12,7,173,5,5,4,8,0,16,8, 7,5,28,26,19,11,227,103,68,25,255,158,96,29,255,57,41,22,255,13, 12,10,241,33,26,16,255,146,88,31,255,66,47,23,255,12,10,9,201,6, 5,5,14,0,32,8,7,5,57,30,22,11,255,15,12,8,96,0,8,10, 10,7,130,190,104,27,255,209,118,30,255,211,117,34,255,27,21,14,255,0, 24,13,12,10,170,199,122,39,255,218,130,51,255,223,146,70,255,30,24,17, 255,0,12,23,22,18,139,30,27,21,170,16,15,11,255,89,59,26,255,203, 110,28,255,196,113,31,255,122,81,33,255,186,117,43,255,216,129,51,255,184, 126,57,255,38,34,25,255,24,22,19,221,33,30,24,170,15,15,12,28,0, 12,24,22,19,142,32,31,25,170,21,20,16,198,90,71,45,255,223,179,110, 255,226,172,95,255,221,150,66,255,143,100,44,255,22,21,17,227,28,27,21, 170,29,28,22,170,13,13,12,42,0,36,8,8,8,11,25,24,20,142,39, 35,28,170,30,28,23,170,29,27,22,170,29,27,22,170,29,27,22,170,29, 27,22,170,29,27,20,170,23,21,16,170,14,13,11,34,0,52,13,12,10, 159,142,86,31,255,208,116,35,255,201,119,38,255,32,26,17,255,5,5,4, 28,0,12,14,13,11,170,216,167,97,255,231,184,124,255,231,193,128,255,181, 146,92,255,52,44,33,255,90,71,45,255,201,155,88,255,223,173,102,255,228, 179,115,255,230,183,123,255,230,184,119,255,39,32,22,255,0,24,12,12,11, 170,206,139,61,255,226,164,91,255,228,174,103,255,39,32,22,255,0,48,6, 6,5,28,9,9,8,142,56,46,31,255,222,180,113,255,230,187,119,255,222, 180,113,255,23,21,16,255,0,36,15,14,12,164,79,59,30,255,209,128,42, 255,211,127,44,255,171,117,46,255,18,15,11,170,0,16,9,9,8,116,33, 28,16,255,161,94,28,255,199,107,26,255,65,40,18,255,8,7,5,255,25, 20,12,255,198,113,29,255,210,120,33,255,217,133,50,255,27,23,16,255,0, 8,7,7,6,23,34,28,19,198,46,36,25,255,39,31,22,255,41,33,22, 255,59,46,28,255,51,40,26,255,61,47,28,255,180,133,71,255,227,175,100, 255,226,175,103,255,181,143,88,255,17,16,12,142,0,8,11,11,10,170,214, 166,97,255,229,179,114,255,228,185,111,255,161,121,68,255,23,21,16,227,23, 22,18,170,22,21,17,170,16,15,13,170,11,11,8,147,8,8,7,85,0, 40,14,13,11,170,181,143,88,255,228,185,123,255,218,168,97,255,70,54,35, 255,9,9,8,113,0,12,11,10,8,85,120,87,45,255,223,183,120,255,231, 190,132,255,167,135,80,255,24,22,19,227,19,18,16,170,19,18,16,198,95, 80,46,255,226,193,129,255,228,187,129,255,186,148,87,255,15,14,12,170,0, 8,10,10,9,85,155,113,64,255,229,196,132,255,232,191,133,255,179,142,90, 255,27,25,20,227,18,18,15,170,19,18,16,198,90,71,45,255,222,175,101, 255,227,174,98,255,228,185,111,255,28,25,19,255,0,8,7,7,6,23,34, 28,19,198,49,35,22,255,39,29,18,227,12,11,9,85,0,8,8,7,7, 28,33,26,16,198,52,39,23,255,47,35,22,227,13,12,8,85,0,8,8, 8,7,28,33,30,24,227,201,157,100,255,230,186,123,255,181,137,74,255,16, 15,11,207,6,6,5,23,0,24,11,10,8,28,27,21,12,193,26,19,11, 255,23,18,10,255,23,18,10,255,24,18,11,255,24,18,11,255,26,20,11, 255,35,27,16,255,42,31,19,241,17,14,10,85,0,28,9,9,8,144,91, 67,36,255,217,154,72,255,211,150,70,255,69,55,34,255,15,14,12,85,0, 28,6,6,5,11,11,11,10,142,24,22,19,255,167,135,80,255,225,172,104, 255,224,166,83,255,193,126,54,255,16,14,11,170,0,8,13,12,8,85,185, 97,26,255,207,112,28,255,204,110,27,255,71,46,22,255,8,8,7,255,28, 22,13,255,198,107,27,255,193,111,30,255,126,78,31,255,199,139,62,255,226, 184,111,255,27,24,18,255,0,8,11,10,8,170,214,166,97,255,230,187,119, 255,228,179,103,255,143,102,48,255,17,16,12,227,12,12,9,170,13,12,10, 198,46,33,17,255,199,112,28,255,206,111,27,255,204,110,27,255,32,23,13, 176,0,8,12,11,9,136,204,134,59,255,226,172,95,255,228,181,107,255,162, 125,73,255,24,22,19,227,19,18,16,170,19,18,16,198,95,80,46,255,224, 179,109,255,223,173,95,255,173,117,50,255,15,13,10,156,0,8,12,11,7, 99,185,97,26,255,208,112,27,255,204,110,27,255,22,18,11,255,0,40,16, 15,13,170,219,179,116,255,232,194,133,255,231,193,128,255,40,33,23,255,0, 12,16,15,13,170,219,177,112,255,230,187,119,255,224,159,83,255,24,21,15, 255,0,8,11,10,8,164,211,158,82,255,229,184,114,255,230,191,123,255,166, 127,77,255,22,21,17,227,22,21,17,170,20,19,13,170,14,13,11,28,0, 16,12,11,9,170,195,112,30,255,209,106,30,255,206,111,27,255,101,63,26, 255,16,14,11,227,23,21,16,170,29,27,22,170,13,13,12,42,0,16,16, 15,13,170,216,167,97,255,224,158,87,255,216,125,45,255,24,20,13,255,0, 40,17,16,12,170,219,177,112,255,232,195,137,255,231,189,128,255,162,125,73, 255,22,21,17,227,14,14,11,170,13,12,10,198,50,35,19,255,199,112,28, 255,206,111,27,255,204,110,27,255,32,24,13,170,0,8,13,12,8,93,194, 109,33,255,219,139,54,255,224,158,81,255,39,32,22,255,0,40,11,10,8, 170,190,104,27,255,208,112,27,255,204,110,27,255,32,24,13,170,0,8,13, 12,8,85,184,96,25,255,207,112,28,255,204,102,27,255,129,78,28,255,31, 26,16,255,127,84,34,255,219,147,70,255,173,122,62,255,15,14,12,212,6, 6,5,25,0,16,16,15,13,170,213,155,80,255,221,144,68,255,217,130,52, 255,31,25,16,255,0,32,10,9,7,170,189,99,26,255,208,112,27,255,204, 110,27,255,155,87,26,255,72,46,21,255,179,103,36,255,223,156,76,255,216, 170,97,255,134,96,47,255,174,127,71,255,221,167,90,255,223,147,72,255,222, 158,75,255,23,19,14,252,0,8,11,10,8,170,214,166,97,255,231,187,124, 255,230,191,123,255,228,182,117,255,222,175,101,255,64,50,33,255,7,7,6, 229,26,23,19,255,220,175,105,255,228,183,113,255,228,188,117,255,25,21,16, 255,0,8,11,10,8,170,217,176,112,255,232,197,137,255,232,199,135,255,37, 31,22,255,0,12,13,12,10,170,198,117,37,255,215,127,42,255,217,130,52, 255,21,19,14,255,0,8,11,10,8,167,215,172,104,255,232,191,133,255,231, 190,132,255,166,127,77,255,23,21,16,227,18,17,15,170,17,16,12,198,74, 52,27,255,204,117,33,255,211,111,30,255,173,93,28,255,15,12,8,164,0, 8,13,12,8,88,185,97,26,255,208,112,27,255,204,110,27,255,19,16,10, 255,0,12,10,9,7,170,190,104,27,255,212,118,35,255,216,136,51,255,21, 19,14,252,0,8,11,10,8,167,215,172,104,255,232,194,127,255,231,193,128, 255,166,129,77,255,23,21,16,227,19,18,16,170,19,18,14,198,81,59,34, 255,213,144,62,255,215,140,60,255,165,108,40,255,13,12,10,167,0,8,8, 8,7,85,101,63,26,255,206,114,33,255,212,121,33,255,155,92,36,255,23, 21,16,227,22,21,17,170,28,26,21,170,21,20,18,170,13,13,12,164,10, 10,9,85,6,6,6,6,0,28,12,11,9,170,194,112,31,255,212,119,37, 255,216,134,45,255,35,28,18,255,0,24,16,15,13,170,217,171,106,255,231, 187,124,255,228,181,107,255,39,32,22,255,0,12,16,15,11,170,208,134,55, 255,223,156,70,255,221,148,70,255,23,20,14,238,0,8,11,10,8,170,204, 136,55,255,223,156,70,255,222,158,75,255,34,28,19,255,0,12,14,13,11, 170,217,171,106,255,232,189,127,255,230,186,123,255,25,22,16,255,0,8,10, 10,9,167,210,155,77,255,226,172,95,255,224,165,81,255,31,26,18,255,0, 20,15,13,12,170,217,173,104,255,232,191,133,255,231,195,132,255,40,33,23, 255,0,20,10,9,9,133,73,58,36,255,225,184,120,255,231,193,128,255,228, 180,111,255,147,102,48,255,15,13,10,227,8,7,7,28,0,24,12,11,7, 198,100,59,23,255,169,93,26,255,156,91,27,255,174,96,27,255,180,99,27, 255,168,97,27,255,105,62,24,255,18,15,9,255,7,6,6,48,0,24,7, 7,7,28,15,15,12,227,144,114,67,255,219,177,112,255,223,176,102,255,153, 113,62,255,17,16,12,227,7,7,6,28,0,16,16,15,13,170,213,155,80, 255,223,146,70,255,217,129,50,255,27,22,14,255,0,24,12,10,9,195,161, 94,28,255,207,114,32,255,193,114,36,255,23,20,16,255,0,32,12,11,9, 170,191,105,28,255,207,100,28,255,204,110,27,255,26,20,11,204,0,8,6, 5,5,3,26,19,9,198,24,18,9,246,15,12,8,142,0,12,15,13,10, 91,31,24,16,244,51,39,24,255,21,19,14,91,0,68,10,10,9,76,61, 49,30,255,20,18,13,156,0,16,17,15,12,142,27,22,14,232,30,22,13, 255,25,20,12,255,22,18,11,238,21,16,10,255,99,58,22,255,203,113,26, 255,205,111,28,255,131,80,30,255,12,11,9,142,0,8,11,10,8,170,212, 160,85,255,232,191,127,255,231,195,132,255,196,155,91,255,81,59,34,255,41, 32,20,255,54,43,27,255,180,133,71,255,216,144,59,255,208,115,33,255,129, 78,28,255,12,11,7,142,0,8,8,7,7,57,72,52,29,255,215,155,78, 255,227,174,98,255,207,158,94,255,85,63,34,255,36,29,19,255,57,43,26, 255,189,130,66,255,219,149,66,255,212,121,41,255,172,105,33,255,17,15,10, 147,0,8,7,6,6,54,58,40,21,255,198,113,29,255,206,103,27,255,165, 87,24,255,42,28,13,255,21,16,8,255,27,20,10,255,95,60,22,255,202, 105,27,255,206,100,29,255,204,110,27,255,35,24,12,170,0,8,7,7,6, 54,70,50,27,255,212,145,65,255,227,174,98,255,201,155,88,255,59,44,28, 255,23,20,14,255,34,28,19,255,157,104,48,255,211,126,42,255,208,115,33, 255,132,82,29,255,13,11,8,142,0,12,24,18,9,221,108,61,23,255,201, 112,26,255,207,112,28,255,204,110,27,255,158,91,25,255,46,29,13,249,11, 10,6,57,0,8,8,8,7,57,70,50,27,255,212,142,59,255,226,172,95, 255,207,158,94,255,85,63,34,255,41,32,20,255,57,43,26,255,174,124,59, 255,224,170,93,255,229,184,114,255,231,196,128,255,28,25,19,255,0,8,10, 10,9,167,215,169,102,255,232,191,127,255,231,193,128,255,196,154,87,255,77, 59,34,255,41,31,20,255,54,43,27,255,168,113,49,255,212,121,41,255,206, 114,33,255,132,82,29,255,12,11,9,130,0,8,12,11,7,110,188,98,25, 255,206,111,27,255,206,106,25,255,26,19,11,255,0,24,14,12,9,170,199, 117,36,255,221,148,62,255,227,174,98,255,28,26,19,255,0,8,10,10,9, 167,212,161,89,255,224,166,83,255,217,129,50,255,32,24,15,255,5,5,4, 31,7,7,6,136,65,44,22,255,192,106,29,255,203,108,24,255,114,66,23, 255,17,13,8,221,0,12,10,9,7,139,185,97,26,255,208,112,27,255,208, 117,29,255,32,24,13,170,0,8,15,13,8,91,189,99,26,255,215,123,42, 255,226,172,95,255,198,152,87,255,81,58,34,255,176,133,71,255,224,168,95, 255,197,138,62,255,65,47,26,255,133,81,30,255,208,121,37,255,212,115,37, 255,152,98,35,255,12,11,9,142,0,8,10,9,7,147,190,107,25,255,206, 111,27,255,206,106,25,255,158,91,25,255,42,28,13,255,21,15,8,255,26, 19,9,255,114,66,23,255,204,113,25,255,208,115,33,255,173,122,62,255,16, 15,13,150,0,8,8,8,7,71,110,87,51,255,222,180,113,255,224,166,83, 255,209,137,60,255,133,84,32,255,77,50,24,255,89,59,26,255,181,109,32, 255,210,121,35,255,212,121,41,255,171,116,52,255,15,14,12,142,0,8,14, 13,11,170,219,177,112,255,231,187,124,255,228,180,111,255,205,158,90,255,79, 58,32,255,38,29,19,255,49,35,22,255,167,114,46,255,217,146,62,255,219, 154,70,255,169,117,56,255,15,13,12,156,0,8,8,8,7,71,104,80,45, 255,224,183,119,255,232,191,127,255,210,166,97,255,81,60,32,255,39,30,18, 255,52,40,25,255,175,128,66,255,225,173,98,255,228,180,105,255,226,175,95, 255,29,25,18,255,0,8,12,12,11,170,208,138,55,255,222,145,63,255,220, 139,59,255,193,121,50,255,68,50,29,255,38,28,19,255,48,35,23,255,175, 112,44,255,217,142,54,255,217,144,66,255,191,137,66,255,19,16,12,170,0, 8,9,8,8,74,111,82,40,255,216,155,75,255,226,172,95,255,200,151,81, 255,57,41,26,255,27,23,16,255,35,28,18,255,41,32,20,255,39,30,20, 255,25,22,16,227,15,14,10,142,0,12,10,9,7,28,33,24,14,227,135, 81,28,255,206,117,31,255,210,108,33,255,208,110,31,255,171,92,28,255,49, 33,16,252,13,11,8,68,0,8,11,10,8,170,195,108,30,255,212,118,35, 255,217,137,52,255,42,33,23,255,0,12,20,18,15,170,214,156,81,255,221, 148,62,255,214,127,43,255,23,19,12,238,0,8,10,10,7,159,196,109,31, 255,213,119,36,255,212,123,37,255,31,24,14,255,0,12,15,14,10,170,209, 137,60,255,228,172,99,255,230,189,119,255,28,26,19,255,0,8,12,12,11, 170,208,134,55,255,218,137,51,255,214,127,43,255,35,27,16,255,0,20,16, 14,11,170,199,116,34,255,217,132,48,255,224,166,83,255,32,26,19,255,0, 8,10,10,7,34,81,58,34,255,224,178,105,255,226,172,95,255,129,92,40, 255,9,9,8,170,6,6,6,85,6,6,5,113,35,27,16,255,204,117,33, 255,208,117,29,255,110,69,25,255,14,12,7,108,0,8,10,10,7,170,195, 112,30,255,211,115,30,255,211,115,30,255,30,23,13,255,0,12,14,12,9, 170,196,113,31,255,211,120,32,255,214,126,41,255,33,26,18,255,0,8,9, 8,6,28,44,33,19,212,60,42,23,255,46,35,21,255,74,53,31,255,156, 109,53,255,216,167,97,255,228,179,109,255,229,177,110,255,227,184,108,255,168, 123,69,255,23,21,16,227,9,8,8,28,0,12,17,16,14,170,134,98,51, 255,223,166,92,255,132,100,53,255,9,9,8,133,0,20,16,15,13,170,219, 177,112,255,232,191,133,255,231,195,132,255,40,33,23,255,0,20,6,6,5, 45,39,32,22,255,210,129,49,255,172,106,35,255,20,17,13,227,11,11,8, 28,0,100,17,17,14,170,221,189,132,255,235,205,154,255,234,205,155,255,42, 39,29,255,0,16,9,9,8,25,0,20,9,8,8,25,0,20,14,14,11, 170,208,141,61,255,224,168,87,255,228,174,103,255,31,26,20,221,0,4,13, 12,12,130,218,185,127,255,234,202,147,255,232,198,139,255,40,33,25,255,0, 20,17,17,14,176,140,115,71,255,230,202,147,255,232,202,149,255,218,170,101, 255,200,124,43,255,198,117,37,255,198,117,37,255,196,116,37,255,72,52,27, 255,12,11,9,170,0,28,8,8,7,85,37,31,20,255,174,110,41,255,210, 123,39,255,204,120,37,255,130,87,31,255,15,13,10,190,0,28,5,5,4, 113,28,26,19,255,210,143,65,255,220,163,81,255,217,166,92,255,222,173,97, 255,225,176,98,255,42,37,25,255,4,4,4,74,0,56,13,12,10,170,208, 141,61,255,226,172,95,255,228,183,111,255,40,34,25,255,0,24,17,16,14, 170,219,177,112,255,232,194,133,255,233,202,148,255,27,24,20,255,0,8,16, 15,13,85,199,161,102,255,220,166,89,255,211,143,62,255,217,154,72,255,223, 161,80,255,224,169,91,255,225,185,114,255,229,188,124,255,231,190,132,255,231, 200,143,255,227,195,140,255,227,196,138,255,225,195,136,255,44,37,27,170,0, 8,17,16,14,85,200,165,109,255,227,198,142,255,225,191,132,255,227,195,134, 255,231,199,136,255,231,197,132,255,231,194,124,255,229,191,130,255,225,195,136, 255,225,195,136,255,225,191,132,255,49,42,30,198,0,36,18,17,13,105,193, 135,66,255,221,175,102,255,222,186,123,255,223,190,132,255,224,192,135,255,223, 190,132,255,222,186,123,255,221,178,110,255,218,172,105,255,46,39,27,195,0, 48,6,6,6,28,27,26,20,255,216,170,97,255,225,178,104,255,176,136,83, 255,16,15,13,198,0,16,17,17,14,170,221,188,130,255,235,205,154,255,234, 205,155,255,232,204,149,255,228,199,143,255,171,144,96,255,64,57,41,255,154, 126,81,255,227,189,122,255,230,184,119,255,227,171,98,255,34,30,21,255,0, 24,17,16,14,170,221,186,126,255,234,202,147,255,232,192,135,255,44,39,27, 255,0,44,9,9,8,142,25,24,20,255,114,95,53,255,207,169,102,255,227, 187,118,255,226,188,123,255,178,148,95,255,19,18,16,170,0,32,24,22,19, 85,197,145,84,255,227,187,118,255,231,194,124,255,207,173,114,255,61,55,38, 255,8,8,8,136,0,12,10,10,9,108,45,36,21,255,195,116,38,255,207, 122,38,255,139,90,32,255,13,12,8,170,0,4,10,10,9,198,208,140,59, 255,226,170,91,255,231,193,128,255,40,35,27,255,0,36,4,4,3,28,18, 17,13,227,222,189,131,255,234,201,143,255,229,191,130,255,34,30,23,204,0, 8,11,11,10,170,211,158,82,255,226,170,91,255,224,165,81,255,219,154,70, 255,208,132,51,255,206,128,45,255,204,122,41,255,201,120,40,255,196,116,37, 255,111,74,30,255,20,18,13,227,8,8,7,28,0,28,6,6,6,28,28, 26,21,255,222,186,123,255,229,196,132,255,181,144,92,255,16,15,13,212,0, 16,6,6,6,85,25,24,20,255,180,149,101,255,231,205,154,255,232,204,149, 255,227,198,142,255,223,192,138,255,223,193,136,255,230,199,139,255,232,197,141, 255,211,176,122,255,64,57,41,255,8,8,7,113,0,8,6,6,5,14,33, 31,24,227,186,155,107,255,232,204,149,255,233,205,152,255,227,197,140,255,221, 189,132,255,224,192,135,255,228,198,141,255,232,201,141,255,232,192,135,255,231, 197,132,255,41,35,26,255,0,64,17,16,14,139,211,178,120,255,233,202,148, 255,233,202,148,255,56,48,33,255,4,4,4,85,0,104,11,11,10,255,216, 164,89,255,230,191,123,255,227,195,134,255,40,35,27,227,0,28,16,15,13, 227,126,105,69,255,217,176,112,255,225,175,104,255,223,159,76,255,189,124,49, 255,43,35,20,255,9,8,8,57,0,8,10,10,9,133,194,109,33,255,215, 125,38,255,212,124,39,255,144,93,33,255,29,24,16,255,68,53,29,255,186, 123,49,255,128,95,47,255,25,24,20,255,143,119,78,255,230,201,145,255,33, 30,24,255,0,8,11,11,10,170,217,176,112,255,228,182,109,255,222,158,75, 255,212,134,51,255,204,122,41,255,198,117,37,255,200,118,37,255,208,123,39, 255,212,123,37,255,214,121,39,255,217,133,50,255,24,21,15,244,0,8,11, 11,10,170,218,185,127,255,235,203,148,255,233,202,148,255,230,201,145,255,227, 197,140,255,221,187,128,255,221,184,120,255,224,178,105,255,224,164,85,255,189, 129,58,255,39,32,20,255,7,7,6,85,0,8,11,10,8,125,194,109,33, 255,215,125,38,255,213,125,40,255,29,24,16,255,0,40,17,17,14,170,221, 188,130,255,235,201,152,255,232,201,141,255,42,36,27,255,0,12,17,17,14, 170,219,179,116,255,231,187,124,255,228,183,111,255,24,22,17,255,0,8,11, 11,10,170,218,185,127,255,232,197,137,255,227,179,104,255,219,155,72,255,208, 132,51,255,204,122,41,255,202,120,39,255,38,31,19,170,0,16,12,11,9, 170,196,110,33,255,215,113,38,255,213,122,42,255,215,143,58,255,217,166,92, 255,222,186,123,255,225,195,136,255,52,44,33,198,0,16,17,16,14,170,211, 150,70,255,219,140,56,255,213,126,42,255,25,21,14,255,0,40,17,17,14, 170,221,187,128,255,232,199,141,255,228,180,111,255,219,155,72,255,207,128,44, 255,199,119,39,255,200,118,37,255,208,123,39,255,212,123,37,255,214,125,39, 255,212,124,39,255,34,26,15,181,0,8,11,10,10,161,215,172,104,255,234, 201,143,255,234,206,151,255,42,39,29,255,0,40,12,11,9,170,196,110,33, 255,215,125,38,255,212,124,39,255,36,28,17,170,0,8,15,14,10,85,194, 109,33,255,215,125,38,255,212,124,39,255,210,128,41,255,211,135,54,255,225, 176,98,255,231,197,132,255,56,48,33,255,4,4,4,85,0,20,17,16,14, 170,206,135,51,255,217,133,50,255,213,122,42,255,25,21,14,255,0,32,12, 11,9,170,196,110,33,255,215,125,38,255,213,122,42,255,67,51,28,255,6, 6,5,255,40,34,25,255,226,190,127,255,138,110,69,255,7,7,7,255,25, 24,20,255,221,179,112,255,232,191,127,255,232,201,141,255,26,23,19,255,0, 8,11,11,10,170,214,168,101,255,230,187,119,255,228,188,117,255,212,173,105, 255,150,118,67,255,102,86,47,255,111,90,50,255,185,145,88,255,227,187,118, 255,231,195,132,255,232,201,141,255,26,23,19,255,0,8,11,11,10,170,219, 184,128,255,235,205,154,255,234,206,151,255,42,36,27,255,0,12,15,15,12, 170,213,158,80,255,228,182,109,255,230,191,123,255,27,23,18,255,0,8,11, 11,10,170,219,189,132,255,235,205,154,255,232,197,141,255,225,185,114,255,215, 155,78,255,206,135,51,255,205,126,42,255,209,128,42,255,212,121,41,255,181, 111,36,255,39,30,18,255,8,8,7,57,0,8,10,10,9,136,194,109,33, 255,215,125,38,255,212,124,39,255,24,20,13,255,0,12,15,14,12,170,210, 146,71,255,229,183,110,255,231,197,132,255,26,23,19,255,0,8,11,11,10, 170,218,189,127,255,234,199,143,255,231,197,132,255,225,176,106,255,214,153,75, 255,208,138,55,255,205,133,48,255,210,127,45,255,214,134,49,255,179,119,42, 255,37,30,18,255,7,7,6,85,0,12,23,20,14,227,161,115,50,255,222, 167,89,255,227,186,114,255,225,190,130,255,223,198,136,255,227,198,142,255,224, 196,141,255,221,191,134,255,161,130,86,255,33,30,24,229,10,10,9,42,0, 24,15,15,12,170,211,149,76,255,228,182,109,255,231,189,128,255,44,39,27, 255,0,24,17,17,14,170,216,170,97,255,226,172,95,255,224,165,81,255,31, 26,18,255,0,12,13,12,10,170,201,120,40,255,217,133,50,255,216,125,45, 255,25,21,14,212,0,8,11,10,8,144,203,130,52,255,224,166,83,255,228, 174,103,255,40,34,25,255,0,12,17,16,14,170,221,187,128,255,234,201,143, 255,230,191,123,255,28,25,19,244,0,8,10,10,9,164,203,122,50,255,220, 148,63,255,217,141,52,255,23,20,14,255,0,8,14,13,11,108,10,10,9, 28,0,4,13,13,12,170,221,189,134,255,235,205,154,255,234,206,151,255,42, 37,27,255,0,24,11,11,10,255,222,189,131,255,232,195,131,255,224,162,81, 255,36,29,19,255,4,4,4,54,0,28,7,7,6,28,19,17,12,232,93, 66,30,255,183,112,36,255,209,122,38,255,212,120,39,255,159,102,34,255,22, 19,13,255,7,7,6,85,0,24,6,6,5,28,17,16,14,227,149,122,84, 255,227,195,140,255,227,191,134,255,179,142,90,255,17,16,14,227,5,5,4, 25,0,20,15,14,12,170,204,129,49,255,218,141,51,255,213,126,42,255,25, 21,14,255,0,24,8,7,7,91,68,48,25,255,205,127,44,255,220,153,75, 255,99,78,44,255,8,8,7,113,0,28,12,11,9,170,196,110,33,255,215, 125,38,255,212,124,39,255,24,20,13,255,0,124,9,9,8,25,0,40,2, 2,1,23,9,8,6,255,199,116,34,255,215,125,38,255,212,128,45,255,27, 24,16,207,0,8,11,11,10,170,219,184,128,255,235,205,154,255,234,205,155, 255,58,49,35,255,5,5,4,85,0,4,4,4,3,28,16,15,11,227,204, 122,41,255,215,126,40,255,210,123,39,255,32,25,15,170,0,8,13,13,12, 122,208,168,99,255,234,199,143,255,234,204,151,255,63,54,38,255,5,5,4, 85,0,4,4,4,3,28,18,17,13,215,204,127,45,255,214,125,39,255,212, 121,41,255,34,27,15,170,0,8,13,12,10,85,185,112,34,255,215,125,38, 255,212,123,37,255,35,28,16,255,4,4,3,85,0,4,3,3,2,28,12, 10,9,224,198,117,37,255,215,125,38,255,212,124,39,255,34,27,15,178,0, 8,14,13,11,113,206,162,94,255,232,199,141,255,234,207,155,255,63,53,36, 255,4,4,3,113,0,4,3,3,3,28,10,10,9,255,200,118,37,255,215, 125,38,255,210,123,39,255,27,22,14,227,0,12,3,3,2,6,13,11,8, 221,199,116,34,255,215,125,38,255,212,124,39,255,35,27,16,255,5,4,4, 57,0,12,15,14,12,147,206,154,87,255,232,195,137,255,234,204,151,255,63, 54,38,255,5,5,4,85,0,4,4,4,3,28,18,16,13,227,222,189,131, 255,235,205,152,255,234,205,155,255,27,24,20,255,0,8,11,11,10,170,219, 184,130,255,235,205,152,255,234,205,155,255,58,49,35,255,5,5,4,85,0, 4,4,4,3,28,14,12,9,227,199,117,36,255,215,113,38,255,210,123,39, 255,32,25,15,170,0,8,12,12,9,102,194,109,33,255,215,125,38,255,212, 124,39,255,27,22,14,255,0,24,18,16,13,170,217,176,110,255,234,196,143, 255,234,204,151,255,27,24,20,255,0,8,11,10,10,170,204,134,59,255,219, 136,54,255,213,122,42,255,72,50,27,255,8,8,7,255,25,22,14,255,195, 116,38,255,208,123,39,255,142,91,31,255,16,14,9,193,4,4,3,17,0, 12,11,11,8,170,198,117,37,255,219,133,56,255,221,152,70,255,27,23,16, 221,0,8,13,12,10,99,193,113,34,255,223,156,70,255,231,193,128,255,40, 34,25,255,4,3,3,113,17,16,12,227,208,136,59,255,45,36,21,255,4, 3,3,113,10,9,7,207,196,110,33,255,215,125,38,255,210,128,41,255,32, 25,15,170,0,8,12,11,9,108,194,109,33,255,215,125,38,255,212,124,39, 255,35,27,16,255,4,4,3,85,0,4,3,3,2,28,12,11,9,227,199, 117,36,255,221,150,66,255,229,191,126,255,32,29,23,210,0,8,13,13,12, 122,204,150,79,255,223,159,76,255,217,141,52,255,84,57,29,255,9,8,6, 170,5,5,4,85,6,6,5,113,27,22,14,255,207,128,44,255,223,147,72, 255,227,187,118,255,34,30,23,207,0,8,12,11,11,170,218,180,119,255,229, 184,114,255,224,167,85,255,50,40,25,255,5,5,4,85,0,4,4,4,3, 28,14,12,9,227,203,125,42,255,217,128,48,255,213,128,45,255,35,27,16, 173,0,8,12,12,11,130,209,163,98,255,235,203,148,255,233,202,148,255,63, 54,36,255,5,5,4,85,0,4,4,4,3,28,15,15,12,227,209,137,60, 255,221,151,68,255,219,147,62,255,23,20,14,238,0,8,10,10,9,150,196, 121,41,255,217,128,48,255,215,133,44,255,40,31,19,255,5,5,5,85,0, 4,4,4,3,28,16,14,11,207,201,120,40,255,217,133,50,255,221,161,76, 255,57,44,28,170,0,8,15,14,12,105,211,165,98,255,232,197,137,255,232, 199,141,255,58,49,35,255,4,4,3,113,0,40,3,3,2,17,12,11,9, 227,199,116,34,255,215,125,38,255,212,124,39,255,35,27,16,255,4,4,3, 62,0,12,12,11,9,170,200,120,41,255,223,159,76,255,230,191,123,255,44, 37,27,255,0,12,18,17,15,170,208,140,59,255,217,133,50,255,213,125,40, 255,27,23,14,195,0,8,12,11,9,108,194,109,33,255,215,125,38,255,212, 124,39,255,25,21,14,255,0,12,17,16,14,170,219,179,116,255,235,201,152, 255,234,204,151,255,27,24,20,255,0,8,10,10,9,170,198,122,41,255,215, 127,42,255,213,125,40,255,27,22,14,255,0,20,12,11,9,170,201,120,40, 255,224,156,83,255,231,190,132,255,40,33,25,255,0,12,10,10,9,85,52, 42,29,255,200,142,59,255,183,119,44,255,72,52,27,255,39,30,18,255,49, 37,22,255,150,99,33,255,196,116,37,255,77,50,24,255,10,9,7,144,0, 12,10,10,9,170,196,115,35,255,215,125,38,255,212,124,39,255,25,21,14, 255,0,12,12,11,9,170,196,110,33,255,214,127,43,255,222,158,75,255,41, 34,24,255,0,24,5,5,4,85,11,11,10,255,130,101,59,255,223,176,102, 255,224,176,101,255,177,137,74,255,18,17,13,227,6,5,5,28,0,12,20, 19,15,85,186,120,49,255,217,142,62,255,217,139,56,255,34,29,19,255,4, 4,3,17,0,20,17,17,14,170,221,188,130,255,235,205,152,255,234,205,155, 255,42,39,29,255,0,24,13,13,10,181,199,119,39,255,212,121,41,255,203, 121,40,255,35,29,17,170,0,100,20,18,15,170,222,186,123,255,234,201,143, 255,232,197,135,255,47,40,28,255,0,64,14,13,11,170,213,160,84,255,230, 187,119,255,231,197,132,255,35,30,22,198,0,4,14,13,11,108,217,176,112, 255,232,193,137,255,231,197,132,255,33,28,22,255,0,24,12,12,11,113,31, 29,22,210,40,35,27,255,41,34,24,255,29,24,16,255,32,26,17,255,146, 92,35,255,214,134,49,255,212,128,45,255,123,81,36,255,15,13,10,142,0, 20,7,7,6,85,28,26,19,252,194,140,71,255,212,127,43,255,202,118,35, 255,97,66,30,255,15,14,10,207,6,6,5,25,0,24,6,6,5,8,15, 13,12,227,111,86,50,255,209,168,102,255,176,136,83,255,85,67,44,255,163, 129,80,255,221,186,126,255,83,69,44,255,7,7,6,170,5,5,5,8,0, 4,9,9,8,108,20,18,13,170,13,12,10,51,0,36,16,15,13,170,217, 176,110,255,232,194,133,255,232,198,139,255,36,33,25,255,0,24,15,15,12, 170,219,179,116,255,232,193,137,255,232,199,135,255,31,26,20,255,0,8,11, 11,10,28,56,48,33,227,98,76,45,255,104,80,45,255,195,154,96,255,227, 186,114,255,226,189,125,255,207,173,114,255,222,188,123,255,231,190,132,255,217, 188,124,255,137,109,70,255,99,86,54,255,78,64,43,255,21,20,16,85,0, 8,12,12,11,28,54,48,35,227,86,72,47,255,74,63,43,255,171,137,84, 255,229,191,130,255,230,191,123,255,230,186,123,255,202,164,105,255,97,80,50, 255,75,64,44,255,72,61,39,255,22,21,17,102,0,36,12,11,11,45,55, 45,30,227,90,71,45,255,78,63,41,255,72,61,39,255,74,63,43,255,72, 61,39,255,72,61,39,255,91,74,46,255,78,63,41,255,22,20,17,102,0, 48,12,12,11,176,132,106,61,255,228,188,125,255,210,172,113,255,42,37,29, 255,9,9,8,62,0,16,17,16,14,170,221,186,124,255,234,199,143,255,232, 201,141,255,232,201,141,255,221,189,134,255,52,46,33,255,6,7,6,227,24, 23,17,255,208,132,51,255,215,133,44,255,212,124,39,255,24,20,13,255,0, 24,17,16,12,170,219,177,112,255,231,187,124,255,228,182,109,255,40,33,23, 255,0,36,9,9,8,74,17,15,12,227,67,51,28,255,162,107,43,255,200, 142,67,255,204,157,91,255,177,140,86,255,74,63,43,255,19,17,16,198,9, 9,8,28,0,32,14,14,11,31,56,46,31,227,192,157,103,255,229,194,128, 255,225,188,124,255,146,112,67,255,11,10,8,164,0,8,7,7,6,28,34, 27,17,255,190,107,33,255,210,121,35,255,146,95,35,255,16,14,11,187,0, 8,9,9,8,170,214,164,93,255,232,194,127,255,231,195,132,255,40,34,25, 255,0,40,13,13,10,170,213,157,84,255,224,166,83,255,221,150,66,255,23, 20,14,246,0,8,12,11,9,113,194,109,33,255,212,119,37,255,210,113,35, 255,168,103,33,255,56,42,23,255,27,23,14,255,38,31,19,255,149,92,30, 255,207,118,32,255,207,113,30,255,124,75,27,255,13,11,8,161,0,28,12, 12,11,176,130,99,59,255,229,191,126,255,211,174,116,255,43,37,28,255,9, 9,8,59,0,16,8,8,7,85,68,58,37,255,214,177,119,255,231,196,136, 255,207,171,114,255,97,80,50,255,54,47,35,255,66,59,41,255,178,148,95, 255,228,189,121,255,224,187,123,255,146,112,67,255,12,12,11,170,0,12,10, 10,9,28,16,15,13,147,29,28,22,221,48,42,31,255,70,61,41,255,66, 57,39,255,70,61,41,255,171,140,92,255,224,170,101,255,224,168,87,255,224, 165,81,255,39,32,22,255,0,64,14,13,11,57,100,82,51,255,222,186,123, 255,226,172,95,255,113,82,38,255,9,8,8,127,0,32,11,9,6,102,11, 10,6,170,11,10,8,170,12,11,9,170,15,13,10,170,15,13,10,170,15, 14,10,170,18,15,11,170,18,15,11,156,12,11,9,28,0,28,6,6,5, 65,40,34,25,255,224,183,119,255,229,195,136,255,171,140,92,255,21,20,18, 142,0,24,11,10,8,102,131,92,46,255,213,145,56,255,214,119,43,255,210, 128,41,255,151,94,32,255,23,21,14,255,10,10,9,85,0,12,10,9,7, 170,191,106,30,255,211,115,30,255,208,114,31,255,141,87,30,255,36,31,19, 255,121,90,42,255,217,168,92,255,205,163,102,255,132,102,59,255,213,172,108, 255,231,193,128,255,35,30,22,255,0,8,11,11,10,164,203,129,50,255,215, 127,42,255,211,117,34,255,166,97,29,255,54,40,21,255,29,23,14,255,38, 31,19,255,120,78,29,255,206,118,33,255,214,127,43,255,224,155,81,255,23, 21,16,255,0,8,11,10,10,170,217,183,116,255,234,201,143,255,232,198,139, 255,202,166,109,255,97,78,50,255,52,46,33,255,58,50,33,255,150,96,39, 255,208,121,37,255,195,112,30,255,83,53,24,255,9,8,6,113,0,8,13, 12,8,96,189,104,28,255,210,120,33,255,214,132,45,255,34,29,19,255,0, 40,17,16,12,170,217,172,102,255,228,180,105,255,228,181,107,255,40,33,23, 255,0,12,17,15,12,170,216,171,101,255,232,191,127,255,231,197,132,255,24, 22,17,255,0,8,11,11,10,167,209,146,72,255,221,151,68,255,213,126,42, 255,172,106,35,255,57,41,22,255,42,32,19,255,43,33,20,252,18,15,11, 85,0,16,11,10,8,170,193,111,30,255,215,113,38,255,220,144,63,255,197, 145,84,255,91,71,44,255,75,62,42,255,75,64,44,255,22,21,17,99,0, 16,14,13,11,170,196,110,33,255,210,115,31,255,210,115,31,255,22,19,11, 227,0,8,16,13,9,113,24,21,15,170,17,15,12,170,18,15,13,170,19, 17,12,142,9,8,8,28,0,8,14,13,11,170,210,146,71,255,220,142,59, 255,213,125,40,255,168,103,33,255,54,40,21,255,29,23,14,255,38,31,19, 255,119,78,30,255,204,116,31,255,210,119,31,255,210,115,31,255,26,20,13, 210,0,8,11,11,10,170,217,179,120,255,234,202,147,255,232,201,141,255,40, 35,25,255,0,40,11,10,8,170,193,111,30,255,211,115,30,255,210,115,31, 255,36,25,13,170,0,8,14,12,9,85,190,105,29,255,210,107,31,255,208, 114,31,255,187,124,42,255,143,111,56,255,210,171,109,255,229,187,128,255,131, 99,54,255,8,8,7,156,0,20,13,12,10,170,194,112,31,255,210,107,31, 255,210,115,31,255,22,19,11,255,0,32,11,10,8,170,193,111,30,255,215, 125,38,255,218,141,59,255,39,33,22,255,5,5,5,28,12,12,11,170,156, 126,83,255,27,24,20,227,5,5,5,23,14,13,11,198,219,177,112,255,232, 191,127,255,230,191,123,255,25,22,16,249,0,8,11,10,8,153,200,120,41, 255,214,127,43,255,213,126,42,255,93,66,32,255,11,11,10,255,34,31,23, 255,206,152,81,255,226,179,111,255,231,189,128,255,232,192,135,255,232,201,141, 255,25,22,18,255,0,8,11,10,10,170,215,171,102,255,228,174,105,255,222, 158,75,255,27,24,16,255,0,12,15,15,12,170,219,177,112,255,232,193,137, 255,232,201,141,255,25,22,18,255,0,8,11,10,10,170,215,172,104,255,228, 182,109,255,221,155,70,255,177,114,46,255,55,42,24,255,35,28,18,255,41, 31,18,255,35,28,17,255,27,22,14,255,17,16,12,187,9,9,8,79,0, 12,10,9,7,170,191,106,30,255,211,115,30,255,210,115,31,255,33,25,14, 255,0,12,21,20,16,170,221,180,116,255,232,193,137,255,232,201,141,255,25, 22,18,255,0,8,11,11,10,170,212,160,85,255,224,156,83,255,218,141,59, 255,175,115,44,255,55,42,24,255,31,25,16,255,38,30,19,255,127,82,30, 255,204,116,31,255,195,112,30,255,82,55,25,255,11,10,8,150,0,12,9, 9,8,28,15,14,12,142,28,25,19,221,46,40,29,255,71,60,38,255,66, 57,39,255,70,61,41,255,193,159,106,255,227,184,108,255,221,153,72,255,155, 98,36,255,13,12,10,170,0,24,17,15,12,170,219,180,112,255,232,197,137, 255,232,201,141,255,40,35,25,255,0,24,14,13,11,170,198,117,37,255,213, 124,38,255,210,121,35,255,23,19,12,255,0,12,11,10,8,170,193,111,30, 255,211,115,30,255,208,114,31,255,23,19,12,207,0,8,14,13,11,85,181, 132,68,255,228,185,117,255,231,193,128,255,54,46,31,255,5,5,4,8,0, 8,21,20,16,178,215,160,88,255,223,147,72,255,206,135,51,255,23,20,14, 170,0,8,12,11,9,102,192,111,31,255,210,108,33,255,208,114,31,255,22, 18,11,255,0,4,10,10,9,113,79,61,38,255,17,16,12,198,0,4,16, 15,13,170,219,179,116,255,231,187,124,255,224,169,91,255,33,28,20,255,0, 20,9,8,8,85,39,33,24,255,217,166,92,255,219,140,56,255,210,121,35, 255,66,44,21,255,7,7,6,133,0,32,6,6,5,74,19,18,12,255,183, 102,30,255,207,105,30,255,210,111,31,255,73,51,24,255,8,8,7,116,0, 24,6,6,6,28,15,13,12,227,144,112,61,255,221,180,116,255,224,178,113, 255,152,116,65,255,18,17,13,221,8,8,7,28,0,24,12,10,9,170,193, 111,30,255,210,107,31,255,210,115,31,255,22,19,11,255,0,28,16,15,13, 227,164,122,63,255,225,185,114,255,192,153,97,255,21,19,16,232,7,7,6, 28,0,24,11,10,8,170,193,111,30,255,211,115,30,255,210,115,31,255,23, 19,12,255,0,148,6,6,5,51,11,9,6,85,12,10,7,102,10,8,5, 156,10,8,5,127,8,7,5,184,27,22,12,255,198,105,29,255,211,122,36, 255,220,136,61,255,25,22,16,255,0,8,10,10,9,170,218,181,123,255,234, 202,147,255,232,197,141,255,30,27,21,255,0,12,9,8,6,170,191,106,30, 255,211,115,30,255,210,111,31,255,39,27,14,170,0,8,12,11,11,170,218, 180,119,255,234,196,143,255,232,201,141,255,29,26,20,255,0,12,7,7,6, 28,27,22,14,156,25,22,14,255,32,25,15,210,22,18,11,28,0,8,10, 9,7,150,195,112,30,255,211,115,30,255,210,115,31,255,19,15,10,252,0, 12,9,9,8,170,191,106,30,255,211,111,30,255,208,114,31,255,25,20,12, 204,0,8,12,11,11,170,218,180,119,255,234,202,147,255,232,201,141,255,142, 111,63,255,14,12,9,227,10,9,7,127,8,7,5,181,35,25,14,255,199, 112,28,255,209,118,30,255,209,117,28,255,30,22,13,255,0,16,9,8,6, 167,191,106,30,255,211,115,30,255,210,115,31,255,19,15,10,252,0,16,21, 19,16,170,220,178,113,255,232,197,137,255,232,201,141,255,26,23,19,255,0, 12,11,11,10,170,218,181,123,255,234,201,143,255,231,197,132,255,24,22,17, 255,0,8,11,10,10,170,218,181,123,255,234,201,143,255,231,197,132,255,30, 26,21,255,0,12,9,8,6,167,191,106,30,255,211,115,30,255,210,111,31, 255,39,27,14,170,0,8,13,12,8,85,190,105,29,255,213,119,36,255,214, 132,45,255,32,26,17,255,0,24,17,16,14,170,221,186,124,255,234,202,147, 255,232,199,135,255,25,22,18,252,0,8,11,10,8,127,192,111,31,255,210, 107,31,255,208,114,31,255,161,94,28,255,65,43,20,255,145,85,26,255,207, 117,30,255,122,75,29,255,15,14,10,170,5,5,4,8,0,16,11,10,8, 170,196,115,35,255,223,146,70,255,228,183,111,255,25,22,16,252,0,8,14, 12,9,85,190,105,29,255,215,125,38,255,218,141,59,255,30,24,17,195,0, 4,10,10,7,170,193,111,30,255,20,17,11,252,0,4,11,10,8,85,188, 103,27,255,211,115,30,255,209,106,30,255,39,27,14,170,0,8,13,12,8, 85,190,105,29,255,211,115,30,255,210,115,31,255,19,15,10,255,0,12,9, 8,6,167,192,111,31,255,218,137,51,255,227,175,100,255,27,24,18,255,0, 8,11,10,8,147,196,106,33,255,210,108,33,255,210,115,31,255,30,23,13, 255,4,4,3,14,0,8,15,14,12,195,211,149,76,255,229,184,114,255,232, 199,135,255,28,25,19,255,0,8,11,10,8,167,203,129,50,255,215,127,42, 255,210,121,35,255,20,17,11,232,0,12,9,8,6,139,190,105,29,255,211, 111,30,255,209,114,30,255,30,22,13,198,0,8,13,12,10,170,217,173,104, 255,232,193,137,255,232,194,139,255,25,22,18,255,0,12,9,8,8,156,192, 111,31,255,210,108,33,255,210,115,31,255,32,24,13,173,0,8,13,12,8, 88,190,105,29,255,211,115,30,255,208,114,31,255,19,15,10,255,0,12,7, 7,6,28,27,22,14,198,45,36,21,255,52,43,29,244,14,13,11,85,0, 8,13,13,12,88,177,143,90,255,230,194,131,255,226,172,95,255,137,91,36, 255,10,9,7,227,8,8,5,161,10,9,7,167,10,9,7,136,13,10,6, 85,7,6,6,74,0,24,9,8,6,167,191,106,30,255,211,115,30,255,210, 115,31,255,19,15,10,252,0,16,12,11,9,170,208,141,61,255,230,187,119, 255,232,201,141,255,40,34,25,255,0,12,14,12,9,170,196,109,31,255,210, 107,31,255,210,115,31,255,36,25,13,170,0,8,10,9,7,85,155,91,28, 255,208,114,31,255,209,106,30,255,30,22,13,255,0,12,22,21,17,176,222, 186,123,255,234,199,143,255,226,195,135,255,35,29,22,178,0,8,12,11,9, 105,190,105,29,255,211,115,30,255,208,114,31,255,23,19,12,210,0,8,15, 12,8,59,7,6,4,3,0,4,9,9,8,159,204,134,59,255,230,182,119, 255,232,198,139,255,39,33,24,255,0,16,10,10,9,34,15,14,10,198,52, 40,21,255,165,96,28,255,198,113,29,255,185,102,28,255,80,53,25,255,19, 17,12,227,10,9,7,76,0,16,11,10,8,170,195,112,30,255,211,115,30, 255,210,115,31,255,20,16,11,255,0,12,10,9,7,170,192,111,31,255,215, 125,38,255,224,159,83,255,41,33,24,255,0,24,7,7,6,108,24,20,13, 255,146,88,31,255,195,127,38,255,113,77,34,255,15,14,12,210,7,7,6, 28,0,16,12,12,11,28,37,30,18,227,168,99,31,255,206,114,33,255,51, 34,18,255,6,5,5,71,0,20,17,16,14,170,221,186,124,255,234,202,147, 255,232,201,141,255,40,35,25,255,0,24,17,15,10,227,198,105,29,255,194, 109,33,255,62,44,23,255,16,14,11,85,0,100,19,17,12,142,214,171,97, 255,228,183,113,255,227,186,108,255,50,40,25,227,0,64,12,11,9,198,214, 158,85,255,229,183,110,255,228,181,107,255,21,19,14,249,2,2,1,20,8, 8,7,181,210,156,79,255,226,169,95,255,224,155,81,255,33,26,18,255,4, 4,4,28,0,40,3,3,2,28,11,10,8,255,209,138,62,255,223,154,72, 255,221,164,82,255,27,23,16,249,0,16,7,7,6,79,46,38,25,255,197, 151,84,255,222,161,89,255,209,128,42,255,141,91,32,255,15,13,10,218,5, 5,5,11,0,28,15,13,10,139,191,131,60,255,220,168,93,255,168,123,69, 255,14,13,11,227,5,5,5,85,9,9,8,170,105,78,40,255,162,116,61, 255,88,66,37,255,23,21,16,255,11,11,10,255,78,58,35,255,208,150,75, 255,61,46,28,181,0,36,15,13,10,170,216,170,97,255,230,187,119,255,228, 178,113,255,34,28,19,255,0,24,15,13,10,170,215,167,92,255,229,179,114, 255,228,181,107,255,32,27,19,255,0,16,6,6,6,25,5,5,4,198,52, 42,27,255,220,169,97,255,189,142,76,255,35,31,22,255,134,96,51,255,225, 176,106,255,140,106,53,255,6,6,5,255,6,6,6,51,0,28,5,5,5, 28,15,13,10,227,208,136,59,255,218,138,53,255,213,122,42,255,43,31,18, 255,5,5,4,85,0,136,9,8,8,57,57,47,30,255,212,163,93,255,224, 157,85,255,124,90,45,255,10,10,9,147,0,20,15,13,10,170,216,170,97, 255,228,181,107,255,224,165,81,255,194,136,61,255,58,46,29,255,12,12,11, 85,0,4,10,9,7,156,174,91,23,255,202,103,23,255,202,102,21,255,20, 16,9,255,0,24,15,13,10,170,213,155,80,255,227,175,100,255,227,171,98, 255,35,29,20,255,0,32,7,7,6,85,49,33,18,255,183,108,34,255,209, 128,42,255,209,137,60,255,186,134,67,255,95,74,39,255,22,20,15,229,8, 8,7,105,0,44,5,4,4,28,17,15,12,227,216,167,89,255,228,181,107, 255,223,176,102,255,34,28,19,184,0,8,12,11,9,108,180,106,33,255,214, 125,39,255,217,141,52,255,42,33,21,255,4,4,4,85,0,8,11,10,8, 198,211,149,76,255,224,160,77,255,220,144,63,255,34,27,17,255,0,40,12, 10,7,170,189,99,26,255,206,102,25,255,203,100,24,255,30,21,11,176,0, 8,12,10,7,85,167,87,22,255,202,103,23,255,202,102,21,255,27,20,10, 255,4,4,3,68,0,4,4,4,4,28,12,10,7,215,176,91,23,255,203, 104,24,255,202,105,27,255,28,21,13,249,0,24,9,8,8,57,57,47,30, 255,213,167,94,255,228,184,115,255,126,92,47,255,9,9,8,147,0,20,13, 12,10,167,199,131,58,255,220,148,63,255,219,147,62,255,49,38,24,255,6, 6,6,85,0,4,5,5,5,28,15,14,12,227,217,169,94,255,228,183,111, 255,225,174,102,255,31,25,18,241,0,36,5,5,5,28,15,13,10,227,204, 127,45,255,219,133,56,255,221,150,66,255,35,28,18,255,0,68,10,9,9, 85,45,34,21,255,201,110,30,255,192,100,25,255,57,35,16,255,12,10,7, 85,0,24,13,11,6,79,126,68,21,255,191,100,26,255,198,117,37,255,208, 139,65,255,213,155,80,255,214,161,85,255,215,167,92,255,216,167,89,255,215, 160,88,255,49,38,24,170,0,24,7,7,6,76,45,36,24,249,207,164,90, 255,228,183,111,255,143,111,56,255,13,12,10,170,0,28,13,12,8,142,182, 99,25,255,203,108,24,255,202,102,21,255,112,65,23,255,15,13,8,227,6, 6,5,45,0,16,10,8,7,170,171,89,22,255,202,95,23,255,202,103,23, 255,103,64,26,255,20,18,13,255,79,61,36,255,222,173,97,255,227,179,104, 255,224,172,97,255,226,171,99,255,224,176,93,255,36,29,19,207,0,8,12, 10,7,113,176,91,23,255,202,95,23,255,202,102,21,255,27,20,10,255,4, 4,3,74,0,4,4,4,4,28,11,9,6,215,187,101,24,255,216,134,45, 255,226,172,95,255,23,21,16,241,0,8,10,10,9,161,212,160,85,255,226, 172,95,255,222,158,75,255,51,39,24,255,6,6,6,85,0,4,4,4,3, 28,11,10,6,215,176,91,23,255,202,102,21,255,191,102,22,255,22,17,9, 170,0,8,12,10,7,85,167,87,22,255,204,105,25,255,217,133,50,255,35, 28,18,255,0,40,15,13,10,170,199,116,34,255,212,114,35,255,218,139,55, 255,33,27,18,255,0,12,15,13,10,170,213,160,84,255,227,175,100,255,224, 165,81,255,25,21,14,235,0,8,13,11,8,108,184,96,25,255,203,96,24, 255,202,95,23,255,27,20,10,255,4,4,3,71,0,28,10,9,7,170,187, 101,24,255,216,134,45,255,224,167,85,255,54,42,27,255,6,6,6,85,0, 28,10,9,7,170,171,89,22,255,202,103,23,255,202,102,21,255,29,21,10, 170,0,4,11,9,6,42,137,77,24,255,211,136,56,255,215,167,92,255,216, 166,95,255,213,163,84,255,33,28,18,161,0,8,11,10,8,130,184,100,25, 255,203,100,24,255,202,102,21,255,27,20,10,255,4,4,3,74,0,4,4, 4,4,28,11,9,6,215,176,91,23,255,202,103,23,255,202,95,23,255,28, 21,11,190,0,8,10,10,9,161,212,161,89,255,228,174,105,255,223,161,80, 255,33,28,18,255,0,40,10,9,7,167,171,89,22,255,202,103,23,255,202, 102,21,255,29,21,10,170,0,8,12,10,7,85,167,87,22,255,202,103,23, 255,203,108,24,255,68,47,25,255,6,6,5,255,31,26,20,255,220,168,93, 255,220,177,101,255,110,80,41,255,12,11,9,150,0,16,10,9,7,170,171, 89,22,255,202,103,23,255,202,102,21,255,20,16,9,255,0,32,10,9,7, 170,193,111,30,255,219,136,54,255,224,165,81,255,27,24,16,255,0,4,7, 7,7,28,21,20,16,181,10,10,9,85,0,4,12,11,9,170,204,130,51, 255,218,141,51,255,211,122,36,255,32,23,13,187,0,8,13,11,8,85,167, 87,22,255,203,100,24,255,208,105,29,255,23,19,12,255,4,4,3,28,11, 10,8,181,211,158,82,255,229,183,110,255,228,183,111,255,228,183,113,255,228, 181,107,255,27,23,16,229,0,8,10,10,9,150,192,111,31,255,208,112,27, 255,203,108,24,255,21,17,10,255,0,12,15,13,10,170,216,170,97,255,229, 183,110,255,228,181,107,255,25,21,16,235,0,8,11,10,8,142,194,116,33, 255,209,106,30,255,203,108,24,255,27,20,10,255,4,4,3,74,0,36,10, 8,7,170,171,89,22,255,202,103,23,255,202,102,21,255,42,28,13,255,6, 5,5,48,0,4,6,6,6,28,21,19,14,255,221,175,102,255,229,179,114, 255,228,181,107,255,24,20,15,246,0,8,12,11,9,127,190,104,27,255,206, 106,25,255,202,103,23,255,27,20,10,255,4,4,3,74,0,4,4,4,4, 28,11,10,6,215,176,91,23,255,204,105,25,255,207,122,38,255,28,22,15, 238,0,36,5,5,5,28,15,13,10,227,195,111,28,255,204,105,25,255,197, 100,22,255,22,17,9,224,0,24,15,13,10,170,216,170,97,255,229,184,114, 255,228,181,107,255,34,28,19,255,0,24,10,9,7,170,174,91,23,255,202, 103,23,255,202,102,21,255,20,16,9,252,0,12,10,9,7,170,171,89,22, 255,202,107,23,255,206,111,27,255,22,17,11,252,0,8,8,7,7,45,73, 59,36,255,218,174,105,255,228,178,107,255,89,67,36,255,7,7,6,113,0, 4,5,5,4,28,20,18,13,255,199,110,30,255,202,105,27,255,88,54,23, 255,10,9,7,113,0,8,13,11,6,85,167,87,22,255,202,95,23,255,202, 90,23,255,32,24,13,255,4,4,3,178,19,16,12,238,212,163,93,255,66, 52,31,255,5,5,5,184,14,13,11,255,205,133,48,255,212,114,35,255,208, 117,29,255,29,22,14,255,0,16,12,11,9,85,101,74,38,255,189,121,49, 255,185,104,32,255,180,98,25,255,180,93,23,255,154,82,23,255,75,44,18, 255,11,9,6,144,0,32,10,9,7,170,157,79,22,255,202,102,21,255,202, 102,21,255,22,17,9,255,0,28,14,13,11,224,136,98,53,255,217,165,82, 255,213,145,56,255,150,92,35,255,19,16,12,173,5,5,5,8,0,28,10, 8,7,170,171,89,22,255,202,103,23,255,202,102,21,255,20,16,9,252,0, 28,7,7,6,59,43,35,24,255,221,175,102,255,223,178,106,255,134,98,51, 255,14,13,11,142,0,24,10,9,7,167,171,89,22,255,202,103,23,255,202, 102,21,255,20,16,9,255,0,144,12,10,7,170,46,29,13,255,140,74,21, 255,165,86,22,255,167,87,22,255,165,86,22,255,167,87,22,255,185,95,22, 255,198,97,23,255,206,111,27,255,221,146,66,255,23,19,14,249,0,8,10, 10,9,153,212,161,89,255,229,183,110,255,224,165,81,255,28,23,15,255,0, 12,10,8,7,156,171,89,22,255,202,103,23,255,202,102,21,255,31,21,10, 170,0,8,10,10,9,167,212,160,85,255,228,177,105,255,222,158,75,255,27, 23,16,255,0,40,10,8,7,170,167,87,22,255,202,103,23,255,202,102,21, 255,20,16,9,238,0,12,10,8,7,164,171,89,22,255,202,103,23,255,203, 100,24,255,22,18,11,235,0,8,10,10,9,167,214,164,93,255,228,182,109, 255,223,154,80,255,207,120,36,255,189,94,24,255,167,87,22,255,167,87,22, 255,187,96,22,255,198,93,23,255,202,93,21,255,198,96,21,255,26,19,9, 227,0,16,10,8,7,167,171,89,22,255,202,103,23,255,202,102,21,255,20, 15,9,252,0,16,17,15,12,170,216,170,97,255,229,183,110,255,224,164,85, 255,29,24,16,255,3,3,2,28,0,8,12,11,9,198,211,149,76,255,221, 151,68,255,219,146,60,255,22,19,13,246,0,8,10,10,9,161,210,155,77, 255,223,147,72,255,213,122,42,255,23,18,12,255,0,12,10,8,7,167,171, 89,22,255,202,103,23,255,202,102,21,255,29,21,10,170,0,8,12,10,7, 85,166,87,23,255,209,118,30,255,218,139,55,255,33,27,18,255,0,24,15, 13,10,170,215,159,92,255,226,169,95,255,218,141,59,255,34,26,15,190,0, 8,13,10,6,85,167,87,22,255,202,103,23,255,198,96,21,255,197,96,22, 255,189,97,22,255,198,96,21,255,198,96,21,255,25,19,10,255,4,4,3, 28,0,20,10,9,7,170,178,92,23,255,210,107,31,255,215,128,44,255,33, 24,14,193,0,8,12,10,7,85,167,87,22,255,202,95,23,255,202,103,23, 255,32,22,11,170,0,4,10,8,7,170,171,89,22,255,24,17,9,249,0, 4,12,10,7,85,163,82,22,255,202,103,23,255,202,102,21,255,29,21,10, 170,0,8,12,10,7,85,166,87,23,255,202,103,23,255,202,102,21,255,20, 15,9,255,0,12,10,8,7,167,170,89,23,255,206,106,25,255,208,115,33, 255,28,21,13,207,0,8,13,10,6,85,167,87,22,255,202,95,23,255,202, 102,21,255,20,16,9,255,0,12,15,13,10,170,214,158,85,255,229,183,110, 255,228,185,111,255,24,20,15,249,0,8,12,11,9,108,176,91,23,255,202, 95,23,255,202,102,21,255,18,15,9,255,2,2,1,8,0,8,8,7,5, 184,171,89,22,255,202,95,23,255,202,102,21,255,34,23,11,173,0,8,12, 11,9,136,212,160,85,255,228,180,105,255,225,165,88,255,31,25,18,255,3, 3,2,28,0,8,8,7,5,178,171,89,22,255,202,103,23,255,202,102,21, 255,30,21,11,170,0,8,12,10,7,85,167,87,22,255,202,103,23,255,202, 102,21,255,20,15,9,255,0,40,7,7,6,28,30,27,21,238,167,111,50, 255,206,110,33,255,199,102,24,255,175,90,22,255,165,86,22,255,167,87,22, 255,167,87,22,255,161,87,22,255,84,48,19,255,18,15,9,227,8,7,5, 28,0,16,10,8,7,167,171,89,22,255,202,103,23,255,202,102,21,255,20, 15,9,252,0,16,15,13,10,170,211,159,76,255,229,180,110,255,228,182,109, 255,34,28,19,255,0,12,10,9,7,170,171,89,22,255,202,103,23,255,202, 102,21,255,31,22,10,170,0,8,7,6,6,28,48,31,15,255,189,93,22, 255,202,102,21,255,45,29,14,255,5,5,4,113,0,4,5,5,4,28,22, 20,15,255,220,169,97,255,226,178,103,255,167,118,54,255,15,13,10,133,0, 8,13,11,6,85,167,87,22,255,202,103,23,255,202,102,21,255,19,15,8, 215,0,4,11,9,6,105,121,65,20,255,26,18,9,190,0,4,9,9,8, 167,208,150,75,255,229,183,110,255,228,181,113,255,37,29,20,255,0,24,8, 8,5,218,167,87,22,255,202,93,21,255,198,104,21,255,23,18,10,255,3, 3,2,51,0,20,10,9,7,153,171,89,22,255,202,95,23,255,202,102,21, 255,20,15,9,255,2,2,1,17,0,8,8,7,5,181,184,100,25,255,215, 119,42,255,224,160,85,255,34,28,19,255,0,20,9,8,6,85,31,22,12, 255,166,87,23,255,189,97,22,255,99,60,22,255,15,13,8,170,0,28,4, 3,3,23,13,11,8,227,182,94,23,255,149,87,26,255,19,17,12,227,7, 7,7,23,0,16,15,13,10,170,216,170,97,255,229,179,114,255,228,182,109, 255,34,28,19,255,0,20,9,8,6,130,69,42,18,255,195,95,22,255,35, 24,12,255,5,5,4,76,0,104,10,9,7,28,27,24,16,184,32,27,19, 255,39,29,20,212,13,12,10,85,0,60,13,11,8,170,81,54,28,255,216, 148,67,255,223,161,72,255,220,147,61,255,117,76,32,255,13,11,8,255,44, 33,19,255,207,123,40,255,217,136,50,255,218,142,53,255,156,100,39,255,18, 15,11,227,10,8,7,28,0,12,15,13,8,125,19,14,10,170,14,11,7, 170,10,8,7,170,11,9,6,122,13,10,8,85,8,7,5,153,46,33,21, 255,212,138,51,255,221,151,68,255,191,132,62,255,19,17,12,176,0,12,7, 7,6,76,26,22,15,241,189,129,58,255,219,152,72,255,217,154,72,255,133, 87,38,255,15,13,10,221,6,6,5,28,0,8,15,12,8,113,20,16,11, 170,17,14,10,142,7,6,6,28,0,8,19,16,12,170,200,117,35,255,212, 123,37,255,115,74,30,255,9,8,6,113,0,8,12,11,9,178,104,73,37, 255,206,147,63,255,178,121,53,255,58,46,29,255,46,36,25,255,40,32,21, 252,19,17,12,85,0,36,12,10,9,164,191,131,60,255,223,161,80,255,221, 151,68,255,46,34,21,255,4,4,3,3,0,20,19,16,12,173,208,134,55, 255,223,156,70,255,216,160,81,255,21,19,14,255,0,16,6,5,5,25,17, 14,10,227,67,48,28,255,94,67,35,255,20,17,13,227,6,6,5,113,12, 11,9,198,67,51,30,255,85,62,32,255,25,20,14,255,9,8,6,82,0, 32,10,8,5,170,161,87,22,255,195,90,20,255,187,91,20,255,19,14,8, 255,0,28,15,12,8,119,20,16,11,170,17,14,10,156,10,8,7,28,0, 64,15,12,8,122,18,15,11,170,17,14,10,144,10,8,7,28,0,16,13, 12,10,170,157,96,36,255,211,123,38,255,199,116,34,255,31,24,16,255,6, 6,6,28,0,20,16,13,11,170,197,110,32,255,209,110,30,255,202,103,23, 255,58,36,15,255,8,7,5,113,0,8,10,8,5,85,137,68,18,255,185, 86,20,255,174,88,19,255,18,13,7,255,0,24,12,10,9,170,204,129,49, 255,220,144,63,255,217,133,50,255,26,20,13,255,0,28,7,6,6,76,23, 19,12,244,185,113,36,255,207,129,52,255,173,117,50,255,59,46,28,255,18, 15,13,198,9,9,8,113,6,6,6,11,0,24,15,12,8,133,22,17,11, 170,17,14,10,142,8,7,5,28,0,12,9,8,6,170,202,128,49,255,220, 148,63,255,219,140,56,255,22,19,13,255,0,8,12,10,9,170,200,125,37, 255,218,141,51,255,220,147,61,255,138,86,35,255,13,10,8,227,11,9,6, 170,13,11,8,198,61,41,22,255,202,111,31,255,204,105,25,255,200,105,21, 255,22,17,9,221,0,12,11,9,6,108,14,11,7,170,11,9,6,139,6, 5,3,17,0,12,9,7,6,133,144,75,19,255,185,86,20,255,178,86,19, 255,27,18,8,170,0,8,11,9,6,85,134,70,19,255,181,88,20,255,180, 87,19,255,24,15,7,178,0,12,10,8,5,99,165,86,22,255,206,111,27, 255,213,124,38,255,36,27,17,255,0,24,10,10,9,133,167,112,48,255,222, 166,77,255,223,157,72,255,54,39,23,255,5,5,4,37,0,20,13,11,8, 170,181,93,22,255,206,111,27,255,214,127,43,255,20,16,11,255,0,12,9, 8,8,170,203,129,50,255,222,145,63,255,220,147,61,255,33,26,16,255,0, 12,12,10,7,113,15,12,8,170,13,10,8,122,0,16,10,8,7,170,200, 120,41,255,220,142,59,255,219,146,60,255,27,21,14,255,0,12,13,11,8, 113,18,15,11,170,17,14,10,142,8,7,5,28,0,12,14,12,9,113,20, 15,11,170,17,14,10,153,10,8,7,28,0,16,9,8,6,85,29,21,10, 255,119,62,20,255,153,79,20,255,40,25,11,255,9,8,6,85,0,20,10, 8,7,28,32,24,13,218,68,47,25,255,61,43,24,255,61,46,28,255,61, 47,28,255,61,47,28,255,66,50,29,255,73,55,32,255,66,48,29,255,24, 20,15,85,0,20,7,6,6,79,32,26,17,244,199,132,54,255,208,150,75, 255,122,87,41,255,17,15,10,170,0,32,10,9,7,28,32,23,11,227,53, 33,14,255,34,23,11,255,12,10,7,190,6,5,5,28,0,20,9,7,4, 170,146,76,19,255,197,99,20,255,204,110,27,255,59,41,22,255,6,6,6, 170,10,9,9,113,31,26,18,184,30,25,17,255,29,25,18,255,34,27,19, 255,37,28,18,221,13,11,8,57,0,8,13,10,6,88,144,75,19,255,185, 86,20,255,178,90,19,255,20,14,7,212,0,12,9,7,4,125,157,81,20, 255,212,117,33,255,220,148,63,255,27,21,14,218,0,8,12,10,9,127,192, 111,31,255,208,112,27,255,202,103,23,255,22,16,9,204,0,12,10,8,5, 93,137,68,18,255,185,94,20,255,180,91,19,255,30,20,9,170,0,8,11, 9,6,85,140,67,19,255,202,106,21,255,214,125,39,255,25,20,14,255,0, 12,6,6,5,28,13,11,8,139,20,16,11,170,19,15,10,142,8,7,5, 28,0,8,10,9,5,142,153,79,20,255,195,90,20,255,206,111,27,255,24, 20,13,255,0,12,12,10,9,170,195,113,32,255,211,115,30,255,203,108,24, 255,31,21,10,173,0,8,11,9,6,85,140,70,19,255,185,86,20,255,180, 87,19,255,24,15,7,181,0,32,9,8,6,170,174,91,23,255,215,123,42, 255,221,150,66,255,25,20,14,255,0,32,9,7,4,170,148,77,19,255,181, 92,20,255,180,87,19,255,25,17,8,170,0,8,34,24,13,170,161,102,38, 255,219,154,70,255,220,142,59,255,213,124,38,255,32,24,13,198,0,8,11, 9,6,85,140,70,19,255,185,86,20,255,178,90,19,255,20,14,7,212,0, 12,8,7,5,127,144,78,19,255,185,86,20,255,180,87,19,255,29,19,10, 170,0,8,13,11,8,116,194,116,33,255,209,110,30,255,202,95,23,255,22, 17,9,221,0,12,10,8,5,85,12,9,5,170,10,8,5,130,6,5,3, 8,0,12,10,8,5,110,144,78,19,255,185,86,20,255,178,86,19,255,27, 18,8,170,0,8,11,8,6,85,137,68,18,255,185,86,20,255,200,105,21, 255,29,21,12,255,4,4,4,25,10,9,7,139,154,100,47,255,215,148,70, 255,198,131,45,255,46,34,19,255,11,9,6,88,0,12,10,8,5,119,144, 78,19,255,185,86,20,255,180,87,19,255,21,15,8,210,0,32,13,11,8, 170,199,119,39,255,220,144,63,255,221,155,70,255,27,21,14,255,0,20,10, 9,7,170,171,89,22,255,195,98,20,255,183,89,19,255,29,20,8,170,0, 8,11,9,6,85,139,70,20,255,202,103,23,255,211,118,36,255,28,21,13, 201,0,4,8,8,7,57,118,84,39,255,215,159,86,255,219,149,66,255,216, 129,45,255,211,121,34,255,34,25,13,178,0,8,11,10,6,88,146,76,19, 255,185,94,20,255,178,90,19,255,24,18,9,255,0,12,18,15,11,170,203, 122,42,255,215,126,40,255,209,106,30,255,32,22,13,184,0,8,12,10,7, 85,143,72,20,255,185,94,20,255,178,90,19,255,20,14,7,210,0,40,9, 7,4,170,148,77,19,255,180,87,19,255,178,86,19,255,30,21,9,255,5, 5,4,37,8,7,5,28,20,17,13,227,133,89,38,255,215,142,56,255,216, 129,45,255,209,115,32,255,26,19,11,210,0,8,11,9,6,85,142,74,19, 255,185,86,20,255,178,90,19,255,20,14,7,210,0,12,9,7,4,122,143, 75,20,255,203,108,24,255,216,129,45,255,30,23,15,255,0,12,12,10,7, 110,16,13,9,170,13,10,8,122,0,16,9,8,6,105,142,74,19,255,185, 86,20,255,180,87,19,255,23,16,8,255,0,24,15,13,10,170,203,122,42, 255,215,126,40,255,209,118,30,255,24,17,11,255,0,24,9,8,4,170,148, 77,19,255,181,92,20,255,180,87,19,255,23,16,8,198,0,12,9,7,6, 139,159,82,20,255,203,100,24,255,212,121,33,255,28,21,13,255,0,12,12, 11,9,119,81,59,34,255,216,153,71,255,173,117,50,255,21,18,14,255,10, 10,9,244,11,10,8,255,60,35,15,255,173,85,20,255,84,49,17,255,13, 10,6,170,0,12,10,8,5,130,146,79,19,255,193,89,20,255,203,104,24, 255,120,77,31,255,19,17,12,255,117,80,36,255,219,154,70,255,178,121,53, 255,20,17,13,255,45,33,18,255,184,94,21,255,195,90,20,255,205,106,26, 255,30,22,13,255,0,12,7,7,6,82,35,28,18,255,196,114,33,255,148, 80,25,255,32,22,11,255,20,15,9,255,26,18,9,255,88,49,17,255,149, 78,20,255,40,26,11,255,9,7,4,85,0,28,9,7,4,127,140,70,19, 255,181,88,20,255,180,87,19,255,18,13,7,235,0,24,10,9,7,93,104, 69,35,255,201,131,48,255,194,109,33,255,65,42,20,255,12,10,7,170,0, 36,9,7,4,170,146,79,19,255,181,88,20,255,180,87,19,255,23,16,8, 198,0,32,15,14,10,198,188,133,61,255,219,149,66,255,194,115,37,255,17, 15,10,244,0,24,10,8,5,113,144,78,19,255,185,86,20,255,180,87,19, 255,18,13,7,255,0,140,7,6,4,65,53,31,12,255,162,83,19,255,185, 94,20,255,130,70,21,255,31,22,10,255,25,19,10,198,22,17,9,246,70, 40,15,255,169,87,20,255,200,105,21,255,212,123,37,255,28,21,13,221,0, 8,12,10,9,133,200,127,41,255,210,120,33,255,202,95,23,255,19,14,8, 238,0,12,10,8,5,110,144,78,19,255,185,86,20,255,178,86,19,255,28, 19,9,170,0,8,12,10,9,133,194,112,31,255,209,110,30,255,202,102,21, 255,21,15,8,235,0,16,9,7,4,57,12,10,5,88,10,8,5,85,0, 12,10,8,5,125,146,79,19,255,181,88,20,255,180,87,19,255,25,17,8, 195,0,12,10,8,5,119,144,78,19,255,185,94,20,255,200,105,21,255,23, 18,10,221,0,8,11,9,8,153,200,123,41,255,212,117,33,255,202,103,23, 255,111,63,20,255,27,20,10,255,20,16,9,246,22,17,9,249,28,20,9, 198,30,21,9,170,24,17,9,215,28,20,9,201,10,8,5,85,0,16,9, 7,4,170,146,79,19,255,181,88,20,255,180,87,19,255,18,13,7,255,0, 16,11,10,8,113,152,104,47,255,214,134,49,255,204,105,25,255,98,54,19, 255,18,13,9,227,13,10,8,170,14,12,9,198,60,41,21,255,199,112,28, 255,202,102,21,255,202,103,23,255,26,19,11,204,0,8,12,11,9,116,187, 101,24,255,202,93,21,255,187,91,20,255,18,13,7,255,0,12,9,7,4, 170,146,79,19,255,181,88,20,255,178,90,19,255,27,17,8,170,0,8,11, 9,6,85,139,70,20,255,202,103,23,255,212,123,37,255,32,24,15,255,0, 24,13,12,10,170,196,114,33,255,206,106,25,255,196,99,21,255,28,19,9, 170,0,8,11,8,6,85,137,68,18,255,181,88,20,255,178,86,19,255,164, 85,21,255,138,73,21,255,175,93,20,255,178,86,19,255,46,28,11,255,6, 5,3,108,0,20,9,7,4,170,146,76,19,255,189,88,20,255,189,88,20, 255,28,19,9,170,0,8,11,9,6,85,137,68,18,255,185,86,20,255,178, 90,19,255,27,17,8,170,0,4,9,7,4,167,146,79,19,255,20,14,7, 252,0,4,11,9,6,85,137,68,18,255,185,94,20,255,178,90,19,255,27, 17,8,170,0,8,11,9,6,85,137,68,18,255,185,86,20,255,180,87,19, 255,18,13,7,255,0,12,9,7,4,170,146,79,19,255,185,94,20,255,183, 85,19,255,27,19,8,170,0,8,11,9,6,85,140,73,19,255,181,88,20, 255,178,90,19,255,20,15,7,255,0,12,16,14,11,170,208,143,59,255,223, 156,70,255,216,135,49,255,28,22,13,210,0,8,11,9,6,85,140,70,19, 255,185,94,20,255,178,90,19,255,72,39,13,255,10,8,5,218,8,6,3, 170,9,7,4,193,39,24,10,255,160,82,19,255,185,94,20,255,144,74,23, 255,16,13,9,170,0,8,10,9,7,85,145,101,48,255,218,149,67,255,210, 115,31,255,99,57,19,255,10,8,5,227,8,6,3,170,9,7,4,190,30, 20,9,255,158,81,19,255,185,94,20,255,178,90,19,255,27,17,8,170,0, 8,11,8,6,85,137,68,18,255,185,86,20,255,180,87,19,255,18,13,7, 255,0,44,9,9,8,28,13,12,8,142,27,20,10,170,29,21,10,193,24, 17,9,252,22,17,9,232,22,17,9,255,87,49,18,255,181,88,20,255,178, 90,19,255,100,54,17,255,11,10,6,150,0,16,9,7,4,170,146,79,19, 255,181,88,20,255,180,87,19,255,18,13,7,255,0,16,15,13,10,170,208, 141,55,255,223,156,70,255,217,133,50,255,23,19,12,255,0,12,10,8,5, 122,144,78,19,255,185,86,20,255,180,87,19,255,30,20,9,176,0,12,12, 10,7,85,39,26,12,255,155,80,20,255,99,55,19,255,19,16,12,255,12, 11,9,255,18,15,11,255,119,84,38,255,209,137,60,255,138,86,35,255,18, 15,11,178,0,12,10,8,5,130,144,78,19,255,181,92,20,255,178,90,19, 255,39,24,10,255,6,5,3,210,29,20,8,255,169,87,20,255,97,53,18, 255,8,7,5,255,26,21,15,255,212,142,59,255,221,151,68,255,218,142,53, 255,34,25,15,255,0,20,5,5,4,82,16,12,7,255,160,82,19,255,185, 86,20,255,185,86,20,255,52,29,11,255,7,6,4,170,0,20,8,7,5, 85,83,46,16,255,181,92,20,255,178,86,19,255,87,47,14,255,10,8,5, 224,8,6,3,170,9,7,4,190,29,20,8,255,195,104,24,255,217,136,50, 255,221,155,70,255,30,23,15,255,0,16,8,7,5,85,26,18,9,255,107, 59,20,255,151,80,22,255,60,34,15,255,11,9,6,170,0,36,8,7,5, 170,159,82,20,255,202,118,35,255,66,51,29,255,9,9,8,96,0,16,15, 13,10,170,208,140,59,255,223,156,70,255,215,133,44,255,27,20,12,255,0, 20,14,12,7,244,131,67,20,255,176,89,19,255,17,12,6,255,0,184,17, 14,10,85,171,95,28,255,206,123,33,255,208,123,31,255,207,112,28,255,202, 107,23,255,191,98,22,255,170,91,21,255,195,107,22,255,209,123,30,255,212, 132,37,255,214,134,39,255,211,133,40,255,202,121,35,255,29,21,12,164,0, 8,12,10,7,82,168,98,29,255,202,121,35,255,196,120,31,255,194,115,31, 255,190,115,27,255,185,101,26,255,184,100,25,255,199,107,26,255,208,123,31, 255,168,105,37,255,25,21,14,227,9,8,8,28,0,8,8,8,7,28,39, 30,18,249,183,122,42,255,211,133,40,255,210,133,43,255,161,106,41,255,15, 13,10,221,5,4,4,17,0,8,14,11,7,113,148,83,25,255,193,108,24, 255,180,93,23,255,27,18,10,153,0,8,12,9,7,122,144,78,19,255,180, 91,19,255,83,46,16,255,7,6,4,184,0,8,4,4,3,85,28,21,13, 255,202,121,35,255,209,132,42,255,131,87,36,255,10,9,7,255,5,5,5, 28,0,40,10,9,7,68,86,62,31,255,206,131,43,255,214,130,39,255,76, 50,25,255,7,6,6,113,0,16,5,5,4,28,21,17,12,255,202,121,35, 255,210,135,37,255,157,100,38,255,18,15,11,150,0,16,18,15,9,91,161, 88,24,255,105,64,28,255,11,10,8,170,0,12,8,7,7,85,40,28,17, 255,174,91,23,255,42,27,13,173,0,32,10,8,5,116,133,66,16,255,161, 85,17,255,161,78,17,255,25,16,8,221,0,24,15,12,8,119,170,99,29, 255,203,126,36,255,199,127,34,255,27,20,12,210,0,60,13,11,8,122,170, 99,29,255,204,127,37,255,199,119,34,255,27,20,12,198,0,12,4,4,3, 11,18,13,9,255,154,79,19,255,174,88,19,255,92,51,17,255,12,10,7, 198,0,24,11,9,6,147,142,74,19,255,171,90,18,255,159,81,18,255,17, 12,6,255,0,12,8,7,5,142,133,66,16,255,161,85,17,255,161,85,17, 255,21,14,6,215,0,24,10,9,7,198,190,107,25,255,203,104,24,255,196, 99,21,255,21,15,8,255,2,2,1,14,0,20,9,8,6,37,35,28,18, 255,183,112,36,255,212,132,37,255,178,118,41,255,27,23,16,255,5,5,4, 198,0,32,15,12,8,105,142,79,23,255,189,97,22,255,160,83,21,255,18, 13,7,218,0,12,10,8,7,198,196,114,33,255,214,129,37,255,212,132,37, 255,27,21,12,210,0,8,13,11,8,116,192,114,31,255,210,125,33,255,209, 123,30,255,203,113,26,255,177,91,22,255,159,82,20,255,160,83,21,255,165, 85,20,255,168,89,19,255,163,86,18,255,161,78,17,255,23,15,6,170,0, 8,9,7,4,57,99,48,14,255,142,73,17,255,133,66,16,255,19,13,6, 190,0,12,7,6,4,164,135,66,16,255,161,85,17,255,161,85,17,255,25, 16,6,170,0,8,10,8,5,85,131,65,16,255,161,85,17,255,161,85,17, 255,19,13,6,227,0,12,10,8,5,176,190,107,25,255,212,127,35,255,214, 134,39,255,30,21,13,255,0,24,12,10,7,170,194,109,33,255,213,132,36, 255,208,122,29,255,28,20,11,255,0,24,9,7,4,147,136,70,17,255,202, 98,21,255,211,126,34,255,27,20,12,255,3,3,2,28,0,8,10,8,7, 195,180,93,23,255,202,102,21,255,202,102,21,255,25,17,10,221,0,8,13, 11,8,65,129,70,22,255,172,88,21,255,144,78,19,255,22,15,7,176,0, 12,10,8,7,198,198,124,37,255,215,136,42,255,214,134,39,255,27,21,12, 212,0,8,12,10,7,79,151,88,26,255,198,116,29,255,192,109,27,255,25, 18,10,167,0,8,12,9,7,82,119,62,20,255,174,89,21,255,154,79,19, 255,22,15,7,181,0,20,5,5,4,68,20,14,7,249,142,73,17,255,143, 74,18,255,45,26,10,255,10,8,5,85,0,76,7,6,6,85,39,30,18, 255,196,121,41,255,213,135,42,255,115,72,30,255,10,9,7,170,0,40,5, 5,4,17,6,5,5,85,5,5,4,45,0,28,9,7,4,142,146,79,19, 255,204,108,23,255,212,126,33,255,30,22,13,255,3,3,3,40,0,36,10, 8,5,125,133,66,16,255,161,85,17,255,161,85,17,255,19,13,6,212,0, 12,10,8,5,127,136,70,17,255,193,97,20,255,203,108,24,255,30,21,11, 193,0,8,13,10,6,85,134,70,19,255,171,90,18,255,159,81,18,255,17, 12,6,238,0,12,8,6,5,144,135,66,16,255,161,85,17,255,161,85,17, 255,23,15,6,170,0,8,10,7,5,85,133,66,16,255,185,94,20,255,209, 123,30,255,23,18,12,255,3,3,2,28,0,4,5,5,4,28,18,15,11, 227,134,72,21,255,158,81,19,255,143,74,18,255,22,15,7,142,0,8,10, 8,5,85,131,65,16,255,163,79,18,255,178,90,19,255,22,16,9,255,3, 2,2,20,0,8,9,7,6,176,144,78,19,255,175,88,18,255,163,79,18, 255,26,16,7,170,0,8,10,8,5,85,129,64,16,255,161,85,17,255,161, 78,17,255,19,13,6,229,0,32,8,7,5,156,144,78,19,255,202,102,21, 255,206,111,27,255,27,20,12,255,0,32,10,8,5,133,135,66,16,255,161, 85,17,255,161,85,17,255,19,13,6,227,0,12,8,7,5,255,172,85,21, 255,189,92,20,255,172,87,19,255,24,16,7,170,0,8,10,8,5,85,129, 64,16,255,161,85,17,255,161,85,17,255,19,13,6,212,0,12,10,8,5, 127,135,66,16,255,161,85,17,255,161,85,17,255,26,16,7,170,0,8,11, 9,6,85,134,70,19,255,171,90,18,255,159,78,18,255,23,15,6,170,0, 8,9,7,4,57,98,49,13,255,139,71,16,255,133,66,16,255,19,13,6, 193,0,12,7,6,4,176,133,66,16,255,161,85,17,255,161,85,17,255,23, 15,6,170,0,8,10,8,5,85,129,64,16,255,165,87,18,255,180,91,19, 255,20,15,9,255,0,4,5,5,4,17,26,21,15,227,126,75,25,255,178, 95,21,255,142,74,19,255,46,28,11,255,10,8,5,57,0,8,10,8,5, 85,131,65,16,255,161,85,17,255,161,85,17,255,17,12,6,252,2,1,1, 8,0,28,13,11,8,170,199,119,34,255,215,136,42,255,214,139,41,255,28, 20,13,255,0,20,8,7,5,170,135,66,16,255,161,85,17,255,161,85,17, 255,23,15,6,170,0,8,10,8,5,85,131,67,16,255,202,102,21,255,211, 127,36,255,22,17,11,249,0,8,16,14,11,201,101,67,28,255,191,98,22, 255,185,94,20,255,172,87,19,255,26,17,7,170,0,8,10,8,5,85,129, 64,16,255,161,85,17,255,161,85,17,255,31,20,8,255,5,5,4,102,0, 4,5,4,4,28,16,13,9,255,164,85,21,255,180,91,19,255,165,87,18, 255,26,17,7,170,0,8,10,8,5,85,129,64,16,255,161,85,17,255,161, 85,17,255,19,13,6,212,0,40,10,8,5,133,135,66,16,255,161,85,17, 255,161,85,17,255,26,17,7,255,3,3,2,136,9,7,4,227,131,67,20, 255,197,104,22,255,198,104,21,255,183,93,19,255,172,87,19,255,26,17,7, 170,0,8,10,8,5,85,129,64,16,255,161,85,17,255,161,85,17,255,19, 13,6,212,0,12,10,8,5,127,135,66,16,255,193,97,20,255,209,123,30, 255,19,15,10,252,0,8,13,11,8,65,125,68,22,255,174,86,21,255,146, 76,19,255,22,14,7,178,0,12,8,6,5,144,135,66,16,255,161,85,17, 255,161,85,17,255,19,14,6,238,0,24,13,11,8,170,163,87,20,255,180, 91,19,255,165,87,18,255,17,12,6,255,0,24,9,7,4,139,135,66,16, 255,161,85,17,255,161,85,17,255,15,11,6,246,0,12,9,7,6,184,180, 93,23,255,211,115,30,255,213,133,38,255,28,20,13,255,0,16,12,11,9, 170,152,91,31,255,188,105,31,255,115,66,22,255,91,50,16,255,84,46,15, 255,116,59,17,255,118,62,17,255,15,11,6,221,0,16,10,8,5,116,146, 79,19,255,202,103,23,255,209,128,32,255,200,127,41,255,167,106,40,255,197, 122,42,255,210,130,35,255,186,106,27,255,88,51,19,255,102,55,17,255,157, 83,18,255,189,92,20,255,209,123,30,255,29,21,12,224,0,8,7,6,6, 28,41,31,18,235,160,84,23,255,170,87,19,255,45,26,10,255,5,5,4, 170,4,4,4,8,4,4,3,99,15,12,6,255,140,72,17,255,138,71,17, 255,45,26,10,255,10,8,5,85,0,24,8,7,5,142,133,66,16,255,161, 85,17,255,161,85,17,255,19,13,6,229,0,24,13,11,8,170,160,86,21, 255,185,90,20,255,91,50,16,255,7,6,4,255,0,40,8,7,5,150,133, 66,16,255,161,85,17,255,161,85,17,255,15,11,6,246,0,32,8,8,7, 110,74,52,27,255,191,103,24,255,176,89,19,255,34,22,9,255,6,5,3, 57,0,20,8,6,5,161,133,66,16,255,161,85,17,255,161,78,17,255,15, 11,6,252,0,140,12,10,5,85,123,61,16,255,161,85,17,255,161,85,17, 255,22,15,7,255,2,2,1,85,0,8,7,6,4,244,133,66,16,255,167, 88,18,255,189,92,20,255,27,19,10,195,0,8,12,10,7,110,160,83,21, 255,177,85,18,255,161,78,17,255,15,11,6,252,0,12,7,6,4,161,133, 66,16,255,161,85,17,255,161,85,17,255,23,15,6,170,0,8,11,9,6, 85,134,70,19,255,171,90,18,255,159,78,18,255,15,11,6,249,0,12,10, 8,5,85,98,49,13,255,135,72,16,255,133,66,16,255,19,13,6,139,0, 8,10,8,5,85,131,65,16,255,161,85,17,255,161,85,17,255,15,11,6, 246,0,12,7,6,4,164,133,66,16,255,165,87,18,255,178,90,19,255,24, 17,9,212,0,8,13,11,8,105,165,86,22,255,180,91,19,255,159,81,18, 255,19,14,6,255,2,2,1,79,0,44,8,6,5,167,133,66,16,255,161, 85,17,255,161,85,17,255,15,11,6,252,0,16,7,6,6,28,24,19,13, 227,103,59,20,255,157,83,18,255,154,78,17,255,150,81,19,255,154,79,19, 255,158,81,19,255,162,83,19,255,161,85,17,255,159,81,18,255,163,86,18, 255,27,18,8,170,0,8,11,9,6,85,131,67,16,255,165,87,18,255,161, 85,17,255,15,11,6,252,0,12,8,6,5,167,133,66,16,255,161,85,17, 255,161,85,17,255,23,15,6,170,0,8,10,8,5,85,131,65,16,255,175, 88,18,255,191,96,20,255,25,18,10,255,0,24,11,9,6,170,148,77,19, 255,169,82,18,255,161,85,17,255,23,15,6,170,0,8,10,8,5,85,129, 64,16,255,161,85,17,255,161,85,17,255,87,47,14,255,23,17,8,255,65, 34,12,255,150,76,17,255,132,68,17,255,41,25,10,255,10,8,5,85,0, 16,8,7,5,150,133,66,16,255,161,85,17,255,161,78,17,255,23,15,6, 170,0,8,10,8,5,85,129,64,16,255,161,85,17,255,161,85,17,255,23, 15,6,170,0,4,8,7,5,153,133,66,16,255,19,13,6,238,0,4,10, 8,5,85,129,64,16,255,161,85,17,255,161,85,17,255,23,15,6,170,0, 8,10,8,5,85,129,64,16,255,161,85,17,255,161,85,17,255,15,11,6, 252,0,12,8,6,5,167,133,66,16,255,161,85,17,255,161,85,17,255,23, 15,6,170,0,8,10,8,5,85,129,64,16,255,161,85,17,255,161,85,17, 255,31,20,8,255,5,4,4,85,0,4,5,4,4,40,17,14,10,255,200, 120,35,255,207,112,28,255,195,98,20,255,29,20,8,170,0,8,10,8,5, 85,131,65,16,255,163,86,18,255,159,81,18,255,150,76,17,255,137,70,16, 255,135,72,16,255,135,66,16,255,146,75,17,255,159,81,18,255,131,67,20, 255,42,31,17,255,10,9,7,62,0,8,5,5,4,8,26,21,15,227,137, 79,28,255,174,88,19,255,158,83,17,255,137,70,16,255,135,72,16,255,135, 66,16,255,146,75,17,255,159,81,18,255,161,85,17,255,161,85,17,255,23, 15,6,170,0,8,10,8,5,85,131,67,16,255,163,86,18,255,159,81,18, 255,17,12,6,255,0,68,2,1,1,8,7,6,4,249,137,67,16,255,165, 80,18,255,154,78,17,255,27,18,8,170,0,16,8,6,5,167,133,66,16, 255,161,85,17,255,161,85,17,255,15,11,6,252,0,16,13,11,8,170,199, 124,36,255,211,125,32,255,200,105,21,255,18,13,7,255,0,12,7,6,4, 164,133,66,16,255,161,85,17,255,161,78,17,255,19,13,6,227,0,16,8, 7,5,122,68,38,13,255,150,83,23,255,174,107,35,255,181,112,38,255,190, 117,39,255,193,114,36,255,143,84,26,255,15,12,8,212,4,4,3,6,0, 12,10,8,5,108,135,66,16,255,161,85,17,255,161,85,17,255,125,65,16, 255,90,47,13,255,121,60,16,255,164,84,19,255,189,97,22,255,177,104,32, 255,194,123,39,255,212,134,41,255,210,124,31,255,200,105,21,255,23,17,8, 218,0,16,10,8,5,167,56,31,11,255,110,55,15,255,118,62,17,255,115, 58,16,255,115,58,16,255,120,63,17,255,95,46,14,255,17,13,6,227,7, 6,4,28,0,16,14,12,7,227,87,43,14,255,154,78,17,255,152,77,17, 255,139,71,16,255,135,72,16,255,135,66,16,255,146,75,17,255,200,105,21, 255,211,127,36,255,214,134,39,255,23,18,12,255,0,12,7,6,4,85,26, 16,7,255,131,67,16,255,145,75,18,255,78,43,15,255,7,6,4,255,0, 40,10,8,5,136,157,81,20,255,210,129,33,255,139,89,36,255,10,9,7, 198,0,16,13,11,8,170,196,113,31,255,206,114,25,255,189,92,20,255,18, 13,7,244,0,16,5,4,4,88,27,19,8,255,141,73,18,255,161,85,17, 255,21,14,6,218,0,112,12,9,7,99,11,8,6,170,10,8,5,91,0, 60,11,10,8,28,32,23,13,227,108,57,19,255,153,82,18,255,154,78,17, 255,146,75,17,255,97,47,14,255,36,24,11,255,108,64,25,255,203,111,30, 255,207,118,32,255,207,118,32,255,189,110,32,255,63,41,20,255,15,12,8, 76,0,8,9,8,6,28,38,27,15,218,51,33,18,255,48,32,17,255,131, 74,24,255,182,97,21,255,176,89,19,255,170,87,19,255,134,72,21,255,37, 25,14,255,15,13,8,144,7,7,6,28,0,12,11,9,8,127,171,99,28, 255,208,123,31,255,203,124,30,255,104,63,27,255,15,13,10,212,7,6,6, 28,0,12,14,11,7,170,142,74,19,255,161,85,17,255,159,81,18,255,27, 18,8,184,0,8,6,5,3,28,27,17,8,227,92,46,13,255,111,55,14, 255,31,20,8,255,8,6,3,198,9,7,4,170,10,8,5,227,22,16,9, 255,61,39,18,255,107,64,26,255,108,66,25,255,32,22,11,255,9,7,6, 170,0,44,10,9,7,156,56,36,19,255,191,114,32,255,175,98,30,255,41, 27,16,255,11,9,6,57,0,12,21,15,10,227,100,56,21,255,160,83,21, 255,80,44,17,255,14,12,7,190,7,6,6,28,0,16,13,10,6,28,29, 20,10,212,21,15,10,144,0,20,12,9,7,85,39,24,10,173,16,12,7, 85,0,32,6,5,3,20,19,13,6,173,21,14,6,255,21,15,6,215,10, 8,5,85,0,24,15,12,8,170,190,98,23,255,203,108,24,255,202,111,23, 255,23,17,10,255,0,60,17,13,10,170,195,112,30,255,211,124,30,255,205, 106,26,255,31,21,12,255,0,12,8,6,5,139,44,25,9,255,135,72,16, 255,104,54,13,255,15,11,6,249,7,6,4,28,0,24,7,6,4,57,44, 25,9,255,137,73,16,255,143,70,16,255,49,25,8,255,8,6,3,184,8, 6,3,85,8,6,3,142,23,16,6,255,130,66,15,255,145,77,16,255,87, 44,12,255,10,8,5,142,0,20,11,9,8,164,53,31,14,255,150,74,19, 255,154,78,17,255,148,76,17,255,65,33,10,255,10,8,5,184,6,5,5, 28,0,16,11,9,6,142,175,102,30,255,207,123,32,255,208,114,31,255,196, 114,33,255,89,56,26,255,17,13,10,255,11,8,6,170,9,7,6,170,11, 8,6,170,15,11,8,170,18,13,9,142,8,6,5,28,0,8,10,8,5, 93,102,53,17,255,159,81,18,255,154,78,17,255,72,37,11,255,11,8,6, 227,9,7,6,170,11,8,6,198,61,36,20,255,196,107,27,255,204,114,27, 255,182,102,31,255,19,14,10,170,0,8,6,6,5,20,26,19,11,198,28, 20,11,255,22,16,9,255,23,16,8,255,27,18,8,255,24,16,7,255,24, 16,7,255,74,39,11,255,139,68,16,255,143,70,16,255,143,70,16,255,20, 13,5,170,0,8,7,6,4,74,87,44,12,255,155,79,18,255,151,73,16, 255,67,34,10,255,9,7,4,198,9,7,4,96,8,6,5,159,27,17,8, 255,137,67,16,255,158,80,17,255,112,56,15,255,10,8,5,167,0,8,7, 5,4,85,74,36,11,255,150,83,17,255,145,77,16,255,55,29,10,255,8, 6,3,198,8,6,3,88,7,6,4,153,39,24,12,255,199,112,28,255,210, 115,31,255,184,108,33,255,17,14,10,198,0,24,11,9,6,170,139,69,18, 255,168,86,19,255,154,78,17,255,17,12,6,235,0,24,7,6,4,85,64, 32,11,255,162,80,19,255,198,96,21,255,109,63,26,255,15,11,8,227,10, 8,7,170,8,7,5,195,29,18,8,255,137,67,16,255,154,78,17,255,114, 59,15,255,11,10,6,164,0,8,9,7,6,85,97,50,16,255,159,81,18, 255,152,77,17,255,74,36,11,255,10,8,5,198,7,6,4,125,10,8,5, 198,61,36,20,255,200,105,29,255,209,122,28,255,180,104,29,255,16,12,9, 170,0,8,12,10,7,170,160,83,21,255,183,89,19,255,174,88,19,255,28, 19,9,187,0,8,14,10,7,85,143,75,20,255,195,98,20,255,189,92,20, 255,21,15,8,224,0,24,7,6,4,85,26,16,7,255,111,55,14,255,132, 67,15,255,39,23,8,255,8,6,3,113,0,68,9,7,6,85,32,22,13, 255,188,112,31,255,193,114,30,255,94,57,25,255,17,13,10,170,0,44,9, 7,4,142,10,8,5,255,10,8,5,198,6,5,3,28,0,24,8,7,5, 85,88,48,19,255,204,114,27,255,208,118,31,255,111,62,26,255,11,8,6, 227,8,7,5,150,10,8,5,116,10,8,5,88,9,7,4,85,6,5,3, 74,0,16,10,8,5,99,114,56,13,255,143,70,16,255,143,70,16,255,18, 12,5,215,0,12,8,7,3,130,118,60,13,255,148,76,17,255,150,76,17, 255,24,16,7,170,0,8,9,7,4,85,114,56,13,255,145,74,16,255,143, 70,16,255,52,28,9,255,8,6,3,198,8,6,3,88,8,6,3,144,23, 15,6,255,130,66,15,255,151,80,16,255,111,55,14,255,10,8,5,144,0, 8,6,5,3,59,59,32,10,255,157,83,18,255,185,90,20,255,97,54,22, 255,14,10,7,227,13,10,6,170,13,10,6,255,84,41,13,255,148,76,17, 255,155,82,18,255,135,66,16,255,14,10,5,159,0,8,9,7,4,85,114, 56,13,255,145,77,16,255,145,74,16,255,55,28,10,255,9,7,4,198,8, 6,3,93,8,6,3,147,25,16,6,255,130,64,15,255,151,80,16,255,111, 55,14,255,10,8,5,142,0,8,9,7,4,85,114,56,13,255,145,77,16, 255,143,70,16,255,52,28,9,255,8,6,3,198,8,6,3,102,8,6,3, 139,8,6,3,170,9,8,4,113,0,12,10,8,5,91,114,56,13,255,150, 76,17,255,150,76,17,255,17,12,6,252,0,32,7,6,4,85,64,33,11, 255,145,77,16,255,143,70,16,255,56,29,9,255,8,6,3,198,8,6,3, 85,6,5,3,119,14,11,5,255,128,66,15,255,151,73,16,255,143,76,16, 255,20,13,5,170,0,8,9,7,4,85,114,56,13,255,143,70,16,255,143, 70,16,255,18,12,5,215,0,12,8,7,3,130,114,56,13,255,143,70,16, 255,143,70,16,255,20,13,5,170,0,8,9,7,4,85,114,56,13,255,143, 70,16,255,143,70,16,255,20,13,5,170,0,8,7,6,4,71,87,44,12, 255,158,87,17,255,161,85,17,255,103,53,20,255,15,11,8,227,10,8,7, 170,10,8,7,195,33,20,10,255,137,67,16,255,151,73,16,255,111,55,14, 255,10,8,5,142,0,8,9,7,4,85,114,56,13,255,143,70,16,255,146, 75,17,255,18,13,7,255,0,8,7,6,6,74,24,16,7,255,132,67,15, 255,145,77,16,255,135,72,16,255,14,10,5,170,0,8,9,7,4,85,114, 56,13,255,145,77,16,255,143,70,16,255,58,31,11,255,11,8,6,227,11, 9,6,170,11,8,6,170,10,7,5,170,9,8,4,113,0,12,11,9,6, 161,175,92,24,255,203,108,24,255,198,101,23,255,25,18,10,255,0,20,8, 6,3,147,114,56,13,255,143,70,16,255,143,70,16,255,20,13,5,170,0, 8,9,7,4,85,114,56,13,255,170,87,19,255,199,106,24,255,24,17,11, 255,0,8,6,6,5,28,15,12,6,255,128,66,15,255,145,74,16,255,143, 70,16,255,20,13,5,170,0,8,6,5,3,57,57,31,10,255,145,77,16, 255,143,70,16,255,90,44,13,255,19,13,6,255,10,8,5,255,13,10,6, 255,62,33,11,255,135,72,16,255,151,73,16,255,108,53,13,255,10,8,5, 142,0,8,9,7,4,85,114,56,13,255,143,70,16,255,143,70,16,255,18, 12,5,215,0,40,7,6,4,85,64,33,11,255,145,77,16,255,143,70,16, 255,67,34,10,255,14,10,5,255,49,27,9,255,140,72,17,255,160,85,19, 255,160,85,19,255,110,55,15,255,31,20,8,255,9,7,4,57,0,8,9, 8,4,85,114,56,13,255,143,70,16,255,143,70,16,255,18,12,5,215,0, 12,8,7,3,136,118,60,13,255,154,75,17,255,172,87,19,255,24,17,9, 204,0,8,8,7,5,85,95,49,16,255,161,85,17,255,152,77,17,255,71, 34,10,255,9,7,4,198,8,6,3,88,8,6,3,142,23,15,6,255,130, 66,15,255,151,80,16,255,111,55,14,255,14,10,5,170,0,24,9,7,4, 164,118,56,15,255,145,74,16,255,143,70,16,255,16,12,5,224,0,24,9, 7,4,85,85,43,12,255,151,80,16,255,143,70,16,255,55,29,10,255,8, 6,3,198,8,6,3,93,8,6,5,173,45,27,14,255,199,112,28,255,210, 124,31,255,199,119,34,255,19,15,10,221,0,20,13,11,8,170,46,28,11, 255,131,65,16,255,145,74,16,255,137,67,16,255,70,35,11,255,12,10,5, 224,7,6,4,28,0,16,8,6,5,34,37,25,14,255,181,100,28,255,206, 113,31,255,207,123,32,255,199,119,34,255,107,67,28,255,28,20,11,255,28, 19,9,255,84,41,13,255,141,75,16,255,145,74,16,255,159,82,20,255,88, 53,25,255,13,11,8,99,0,8,13,10,6,85,114,60,17,255,148,76,17, 255,143,70,16,255,21,14,6,255,0,12,10,8,5,170,119,61,14,255,145, 77,16,255,135,72,16,255,19,13,6,170,0,24,8,7,3,142,114,56,13, 255,143,70,16,255,143,70,16,255,16,12,5,218,0,24,11,8,6,170,126, 62,15,255,151,80,16,255,112,57,13,255,19,13,6,255,8,6,3,144,8, 6,3,85,9,7,4,113,8,6,3,167,8,6,3,170,8,6,3,170,9, 8,4,113,0,12,10,8,5,91,114,56,13,255,145,74,16,255,143,70,16, 255,61,32,10,255,9,8,4,170,0,32,12,10,7,207,74,36,11,255,139, 74,16,255,79,40,12,255,10,8,5,210,0,16,9,7,4,85,27,17,6, 255,130,66,15,255,143,70,16,255,143,76,16,255,16,12,5,221,0,140,8, 6,3,85,74,39,11,255,145,77,16,255,143,70,16,255,41,23,8,255,7, 6,4,173,5,5,2,85,6,5,3,113,14,10,5,255,129,65,14,255,145, 74,16,255,145,74,16,255,24,16,7,170,0,8,10,8,5,85,112,57,13, 255,145,77,16,255,143,70,16,255,52,28,9,255,8,6,3,198,8,6,3, 88,8,6,3,144,23,15,6,255,130,66,15,255,151,80,16,255,111,55,14, 255,10,8,5,144,0,8,6,5,3,59,63,34,10,255,145,77,16,255,143, 70,16,255,55,29,10,255,8,6,3,198,8,6,3,85,8,6,3,144,32, 19,7,255,139,74,16,255,155,79,18,255,135,66,16,255,14,10,5,170,0, 8,6,5,3,57,57,31,10,255,145,77,16,255,143,70,16,255,55,29,10, 255,8,6,3,198,8,6,3,88,8,6,3,144,21,15,6,255,130,66,15, 255,143,76,16,255,146,75,17,255,24,15,7,184,0,8,7,6,4,71,66, 33,11,255,148,79,17,255,143,70,16,255,45,25,8,255,7,5,4,176,7, 5,4,85,8,6,3,85,9,7,4,85,8,6,3,82,0,28,8,7,3, 136,114,56,13,255,143,70,16,255,143,70,16,255,16,12,5,221,0,20,7, 6,4,28,10,8,5,130,19,13,6,170,29,19,8,173,24,16,7,212,27, 18,8,193,20,13,7,246,55,29,10,255,139,74,16,255,143,70,16,255,143, 70,16,255,18,13,5,170,0,8,9,7,4,85,115,54,14,255,143,70,16, 255,143,70,16,255,16,12,5,221,0,12,8,7,3,136,114,56,13,255,143, 70,16,255,143,70,16,255,20,13,5,170,0,8,9,7,4,85,114,56,13, 255,145,74,16,255,145,74,16,255,17,11,6,252,0,24,10,8,5,170,119, 61,14,255,145,74,16,255,143,70,16,255,18,13,5,170,0,8,9,7,4, 85,114,56,13,255,143,70,16,255,143,70,16,255,33,20,8,255,5,4,4, 195,8,6,5,198,46,26,9,255,126,62,15,255,132,67,15,255,35,22,8, 255,9,7,4,93,0,12,10,8,5,93,114,56,13,255,143,70,16,255,143, 70,16,255,20,13,5,170,0,8,9,7,4,85,114,56,13,255,143,70,16, 255,143,70,16,255,20,13,5,170,0,4,9,7,4,125,114,56,13,255,21, 13,6,210,0,4,9,7,4,85,114,56,13,255,143,70,16,255,143,70,16, 255,20,13,5,170,0,8,9,7,4,85,114,56,13,255,143,70,16,255,143, 70,16,255,16,12,5,221,0,12,8,7,3,136,114,56,13,255,143,70,16, 255,143,70,16,255,20,13,5,170,0,8,6,5,3,57,57,31,10,255,145, 77,16,255,143,70,16,255,90,44,13,255,17,12,6,255,12,9,5,255,20, 15,9,255,97,51,20,255,169,87,20,255,161,85,17,255,112,54,15,255,10, 8,5,142,0,8,9,7,4,85,121,60,16,255,174,88,19,255,176,89,19, 255,112,59,17,255,37,23,10,255,26,16,7,255,25,18,8,255,24,15,7, 255,23,16,8,255,18,13,9,198,10,9,7,99,0,16,9,8,6,34,12, 10,7,167,20,14,7,210,21,15,6,255,26,17,7,255,24,16,7,255,26, 17,7,255,70,35,11,255,142,73,17,255,148,76,17,255,152,77,17,255,24, 15,7,170,0,8,13,10,6,96,129,65,18,255,170,87,19,255,170,87,19, 255,24,16,9,255,0,48,5,4,2,76,8,6,3,85,8,6,3,85,8, 6,3,85,7,5,4,85,6,5,3,119,16,11,5,255,129,65,14,255,151, 73,16,255,118,61,15,255,14,10,5,170,0,16,8,7,3,136,114,56,13, 255,143,70,16,255,143,70,16,255,16,12,5,221,0,16,10,8,7,113,109, 67,26,255,184,90,21,255,148,76,17,255,52,28,9,255,8,6,3,198,8, 6,3,88,8,6,3,144,21,15,6,255,130,66,15,255,143,76,16,255,143, 76,16,255,16,12,5,227,0,20,9,8,6,170,67,42,20,255,202,124,31, 255,208,128,33,255,205,106,26,255,104,58,21,255,14,11,7,218,6,5,5, 28,0,16,7,6,4,28,27,17,8,229,102,51,13,255,139,68,16,255,143, 73,16,255,145,74,16,255,71,37,12,255,26,18,9,255,80,50,23,255,204, 122,33,255,208,115,33,255,202,104,25,255,149,78,20,255,52,30,11,255,10, 8,5,85,0,12,14,10,5,170,85,43,12,255,137,73,16,255,77,39,12, 255,14,10,5,227,10,8,5,170,10,8,5,198,46,26,9,255,137,73,16, 255,115,59,14,255,25,16,6,232,8,6,3,31,0,12,6,5,3,28,10, 8,5,119,19,13,6,170,29,19,8,173,26,16,7,210,27,18,8,187,17, 12,6,246,58,30,11,255,151,77,18,255,192,97,21,255,192,97,21,255,24, 16,9,207,0,8,4,4,3,3,25,16,6,235,115,59,14,255,143,73,16, 255,145,77,16,255,108,53,13,255,21,14,6,255,7,6,4,164,10,7,5, 85,8,7,5,147,9,7,4,136,8,6,5,76,0,20,8,6,5,57,58, 33,13,255,188,107,27,255,192,111,31,255,85,51,24,255,18,13,9,187,6, 5,5,20,0,8,11,9,6,156,139,69,18,255,158,83,17,255,148,76,17, 255,23,15,6,170,0,12,9,7,4,85,19,13,6,255,102,51,13,255,128, 66,15,255,81,41,12,255,12,9,5,142,0,108,13,10,8,85,115,60,24, 255,162,75,23,255,121,60,20,255,23,15,8,142,0,60,3,3,2,6,10, 8,5,170,93,48,12,255,123,65,14,255,123,60,14,255,14,10,5,227,3, 3,2,85,12,10,7,170,163,83,24,255,199,99,26,255,193,96,24,255,41, 26,14,227,6,6,5,45,0,24,3,3,2,28,11,8,6,170,106,50,13, 255,129,63,14,255,129,63,14,255,29,18,8,227,6,5,5,31,0,20,13, 10,8,136,144,73,21,255,182,89,21,255,99,55,19,255,14,11,7,187,4, 4,3,3,0,16,9,7,4,113,93,46,12,255,131,66,14,255,121,62,14, 255,16,11,5,170,0,12,7,6,4,28,14,10,5,227,100,50,13,255,110, 59,13,255,103,52,14,255,121,59,18,255,134,69,21,255,32,21,11,255,6, 5,5,198,10,8,7,227,46,28,13,255,104,51,15,255,96,46,13,255,14, 10,5,139,0,44,10,8,7,108,63,37,18,255,176,88,23,255,160,80,21, 255,20,14,9,170,0,8,8,6,5,79,85,41,12,255,131,65,16,255,66, 34,11,255,10,8,5,170,0,144,9,7,4,167,115,56,16,255,165,85,20, 255,112,65,23,255,18,13,9,142,0,60,13,10,8,142,132,68,21,255,162, 80,19,255,141,70,18,255,17,12,6,181,0,12,17,12,6,255,103,54,14, 255,130,66,15,255,31,20,8,255,6,5,3,113,0,32,8,6,3,156,35, 22,8,255,114,58,13,255,110,59,13,255,88,45,11,255,88,42,11,255,92, 47,11,255,104,54,13,255,119,58,14,255,61,32,10,255,10,8,5,224,5, 4,4,20,0,16,11,8,6,85,113,58,22,255,180,90,23,255,140,69,17, 255,123,63,14,255,123,60,14,255,119,56,14,255,120,61,17,255,24,15,9, 167,0,16,12,10,7,133,180,88,27,255,203,107,30,255,199,100,28,255,197, 104,28,255,191,93,28,255,167,78,24,255,132,68,21,255,121,62,18,255,117, 60,18,255,118,57,17,255,108,50,15,255,17,12,6,113,0,12,14,10,5, 227,65,33,10,255,115,59,14,255,115,59,14,255,109,52,14,255,116,57,17, 255,121,59,18,255,139,68,20,255,154,73,19,255,115,62,20,255,33,23,12, 255,9,8,6,71,0,36,2,2,1,8,8,6,3,170,93,50,12,255,125, 64,14,255,123,60,14,255,14,10,5,159,0,12,14,10,5,224,65,33,10, 255,115,59,14,255,115,59,14,255,109,52,14,255,119,61,18,255,129,66,20, 255,148,75,21,255,170,84,21,255,129,67,22,255,37,25,14,255,8,7,5, 57,0,8,5,5,4,23,24,17,9,255,103,54,18,255,132,63,17,255,120, 62,15,255,98,49,13,255,90,45,11,255,94,45,13,255,124,60,17,255,172, 81,21,255,150,78,25,255,44,29,17,255,9,8,6,91,0,24,8,7,3, 102,93,46,12,255,125,64,14,255,121,62,14,255,18,12,5,170,0,28,12, 10,5,227,64,33,11,255,132,66,17,255,158,79,21,255,151,70,22,255,130, 67,21,255,110,53,15,255,108,53,13,255,118,60,13,255,85,43,12,255,21, 14,6,255,7,6,4,57,0,12,14,10,5,227,65,33,10,255,131,65,16, 255,149,72,20,255,133,68,20,255,111,54,16,255,110,53,15,255,138,72,19, 255,163,81,20,255,112,58,19,255,28,20,9,255,8,7,5,57,0,8,9, 7,4,91,96,48,13,255,132,70,15,255,123,60,14,255,14,10,5,161,0, 8,13,10,6,85,148,73,23,255,202,101,27,255,129,67,26,255,18,13,9, 142,0,28,6,5,3,48,17,12,6,227,108,55,13,255,112,55,13,255,35, 22,8,255,9,7,4,57,0,64,32,22,13,255,137,68,22,255,154,73,19, 255,45,26,10,255,8,6,5,144,0,44,8,6,3,68,67,34,10,255,115, 56,16,255,109,52,14,255,16,11,5,147,0,24,5,4,4,11,22,17,11, 227,129,76,28,255,195,95,28,255,186,84,23,255,121,59,18,255,107,51,14, 255,96,46,13,255,90,45,11,255,88,45,11,255,41,24,8,255,12,10,5, 176,0,12,8,6,3,76,88,44,11,255,125,66,14,255,123,60,14,255,18, 12,5,170,0,12,9,7,4,85,92,47,11,255,125,64,14,255,123,60,14, 255,16,11,5,150,0,8,8,6,3,62,88,45,11,255,125,64,14,255,123, 60,14,255,114,58,13,255,93,50,12,255,88,44,11,255,92,47,11,255,104, 54,13,255,119,58,14,255,85,43,12,255,21,15,6,255,7,6,4,51,0, 12,12,10,5,221,61,32,10,255,120,62,15,255,123,61,16,255,109,52,14, 255,96,46,13,255,102,51,13,255,115,59,14,255,123,65,14,255,85,43,12, 255,25,16,6,255,7,6,4,51,0,8,8,6,3,74,88,45,11,255,125, 64,14,255,123,60,14,255,114,58,13,255,93,50,12,255,88,45,11,255,92, 47,11,255,104,52,13,255,118,60,13,255,85,43,12,255,21,15,6,255,7, 5,4,40,0,8,8,6,3,74,88,45,11,255,125,64,14,255,123,60,14, 255,114,58,13,255,93,50,12,255,88,45,11,255,92,43,11,255,93,50,12, 255,93,50,12,255,20,13,5,85,0,8,8,6,3,65,88,45,11,255,125, 64,14,255,121,62,14,255,18,13,5,170,0,36,12,10,5,227,59,31,10, 255,115,62,14,255,114,58,13,255,93,50,12,255,88,44,11,255,88,44,11, 255,104,54,13,255,118,60,13,255,123,60,14,255,123,60,14,255,14,10,5, 150,0,8,8,6,3,65,88,45,11,255,125,66,14,255,123,60,14,255,18, 12,5,170,0,12,9,7,4,85,92,47,11,255,125,66,14,255,123,65,14, 255,14,10,5,150,0,8,8,6,3,65,88,45,11,255,125,66,14,255,123, 65,14,255,14,10,5,159,0,12,14,10,5,221,70,35,11,255,155,74,20, 255,193,89,26,255,185,91,28,255,172,85,27,255,165,80,24,255,155,78,22, 255,132,66,17,255,90,44,13,255,21,15,6,255,7,5,4,40,0,8,8, 6,3,74,88,45,11,255,125,64,14,255,121,62,14,255,19,13,6,176,0, 12,9,6,4,133,93,50,12,255,131,66,14,255,123,65,14,255,14,11,5, 150,0,8,8,6,3,62,88,45,11,255,125,64,14,255,123,60,14,255,118, 56,15,255,120,61,17,255,136,67,21,255,118,57,17,255,96,48,13,255,92, 47,11,255,18,12,5,85,0,8,9,7,4,79,104,51,15,255,140,66,17, 255,135,66,16,255,17,12,6,198,0,20,9,7,4,85,92,47,11,255,125, 66,14,255,123,65,14,255,14,10,5,150,0,8,8,6,3,65,88,45,11, 255,135,66,16,255,136,67,17,255,22,14,7,198,0,12,8,6,3,119,88, 45,11,255,125,64,14,255,123,60,14,255,14,10,5,159,0,12,12,10,5, 210,59,31,10,255,115,62,14,255,118,60,13,255,104,54,13,255,100,50,13, 255,100,50,13,255,114,58,13,255,119,63,14,255,85,43,12,255,21,15,6, 255,7,5,4,40,0,8,8,6,3,74,88,45,11,255,125,66,14,255,123, 60,14,255,18,12,5,170,0,44,12,10,5,227,59,31,10,255,115,62,14, 255,114,58,13,255,100,50,13,255,114,56,13,255,133,66,16,255,160,80,21, 255,176,83,21,255,45,27,12,255,6,5,3,170,0,12,8,6,3,82,88, 45,11,255,125,66,14,255,123,60,14,255,18,12,5,170,0,12,9,7,4, 85,92,47,11,255,131,61,14,255,126,62,15,255,17,11,6,170,0,12,14, 10,5,227,65,33,10,255,115,59,14,255,115,62,14,255,93,50,12,255,88, 44,11,255,92,47,11,255,104,54,13,255,119,58,14,255,85,43,12,255,21, 15,6,255,7,6,4,57,0,24,9,7,4,85,92,47,11,255,125,66,14, 255,123,60,14,255,18,12,5,170,0,24,5,5,4,28,19,13,6,255,84, 42,11,255,115,62,14,255,110,59,13,255,93,50,12,255,84,44,11,255,106, 54,15,255,176,84,23,255,199,100,28,255,188,101,31,255,90,54,25,255,13, 10,8,142,0,24,8,6,3,164,72,37,11,255,131,66,14,255,110,54,13, 255,12,9,5,224,3,3,2,17,0,24,7,6,6,85,30,20,13,255,190, 96,27,255,199,98,24,255,121,69,22,255,13,10,6,190,4,3,3,28,5, 4,2,105,27,17,6,255,114,56,13,255,125,64,14,255,45,26,10,255,8, 7,5,153,0,12,10,7,5,85,96,48,13,255,125,64,14,255,123,60,14, 255,16,11,5,195,0,12,8,6,3,110,92,47,11,255,131,66,14,255,123, 65,14,255,18,13,5,170,0,24,9,7,4,85,92,47,11,255,125,66,14, 255,123,60,14,255,18,12,5,170,0,24,8,7,3,99,93,50,12,255,125, 66,14,255,115,59,14,255,104,54,13,255,88,45,11,255,88,44,11,255,92, 43,11,255,92,43,11,255,92,43,11,255,93,50,12,255,93,50,12,255,20, 13,5,85,0,8,8,6,3,65,88,45,11,255,125,64,14,255,123,60,14, 255,115,62,14,255,93,46,12,255,16,11,5,127,0,28,5,4,4,28,12, 10,5,246,104,54,13,255,115,59,14,255,39,23,8,255,8,6,3,82,0, 12,58,31,9,255,114,58,13,255,119,63,14,255,123,60,14,255,123,65,14, 255,18,12,5,170,0,144,14,10,5,227,59,31,10,255,115,62,14,255,110, 59,13,255,88,44,11,255,80,42,11,255,88,44,11,255,104,54,13,255,115, 59,14,255,123,60,14,255,123,60,14,255,16,11,5,150,0,8,8,6,3, 65,88,44,11,255,125,64,14,255,123,60,14,255,114,58,13,255,93,50,12, 255,88,44,11,255,92,47,11,255,104,54,13,255,119,58,14,255,85,43,12, 255,21,15,6,255,7,6,4,51,0,12,12,9,5,224,63,32,10,255,115, 62,14,255,114,56,13,255,93,50,12,255,88,44,11,255,88,45,11,255,110, 59,13,255,119,61,14,255,85,43,12,255,25,16,6,255,7,6,4,57,0, 12,12,10,5,221,59,31,10,255,115,62,14,255,114,56,13,255,93,50,12, 255,88,44,11,255,92,47,11,255,104,54,13,255,115,59,14,255,123,60,14, 255,121,62,14,255,16,11,5,167,0,12,12,10,5,218,59,31,10,255,115, 62,14,255,110,59,13,255,88,44,11,255,80,42,11,255,88,44,11,255,88, 45,11,255,88,44,11,255,16,11,5,105,0,24,9,7,4,85,92,47,11, 255,125,66,14,255,123,60,14,255,18,12,5,170,0,48,7,5,4,198,93, 50,12,255,125,66,14,255,123,60,14,255,12,10,5,170,0,8,8,6,3, 65,88,45,11,255,125,66,14,255,123,65,14,255,18,12,5,170,0,12,9, 7,4,85,92,47,11,255,125,66,14,255,123,65,14,255,14,10,5,150,0, 8,8,6,3,65,88,45,11,255,125,66,14,255,123,60,14,255,18,13,5, 170,0,20,3,3,2,11,9,7,4,227,100,50,13,255,123,60,14,255,123, 60,14,255,12,10,5,170,0,8,8,6,3,62,88,45,11,255,125,66,14, 255,123,60,14,255,14,10,5,198,0,8,8,6,3,170,35,22,8,255,115, 59,14,255,112,55,13,255,33,21,8,255,8,6,3,37,0,8,8,6,3, 74,88,45,11,255,125,66,14,255,123,65,14,255,14,10,5,150,0,8,8, 6,3,65,88,45,11,255,125,66,14,255,123,65,14,255,14,11,5,147,0, 4,9,7,4,85,92,47,11,255,20,13,5,170,0,4,8,6,3,62,88, 45,11,255,125,66,14,255,123,65,14,255,14,10,5,150,0,8,8,6,3, 65,88,45,11,255,125,66,14,255,123,60,14,255,18,12,5,170,0,12,9, 7,4,85,92,47,11,255,125,66,14,255,123,60,14,255,14,10,5,159,0, 12,12,10,5,210,59,31,10,255,115,59,14,255,118,60,13,255,104,54,13, 255,102,51,13,255,112,53,13,255,122,63,15,255,123,58,14,255,85,43,12, 255,21,15,6,255,7,5,4,45,0,8,8,6,3,85,113,55,16,255,196, 92,23,255,195,96,24,255,25,17,10,255,4,3,3,79,0,64,3,2,2, 28,10,8,5,227,138,71,21,255,177,87,20,255,174,86,21,255,24,16,9, 170,0,8,13,10,8,85,142,73,23,255,195,96,24,255,194,91,23,255,24, 17,11,227,0,44,12,9,5,150,35,22,8,255,80,42,11,255,84,44,11, 255,88,44,11,255,80,42,11,255,88,44,11,255,97,50,12,255,118,60,13, 255,85,43,12,255,21,15,6,255,8,6,3,57,0,16,9,7,4,85,92, 47,11,255,125,66,14,255,123,60,14,255,18,12,5,170,0,16,6,5,5, 28,17,13,8,227,68,34,11,255,115,59,14,255,110,59,13,255,93,50,12, 255,88,44,11,255,92,47,11,255,104,54,13,255,115,59,14,255,123,60,14, 255,123,65,14,255,18,12,5,170,0,24,12,9,7,170,131,69,24,255,191, 90,22,255,136,71,19,255,15,11,6,227,4,3,3,17,0,24,7,6,4, 31,16,11,5,227,104,52,13,255,131,66,14,255,98,49,13,255,10,8,5, 193,3,2,2,68,8,7,5,170,121,66,26,255,195,96,24,255,156,74,19, 255,34,21,9,255,9,7,4,85,0,12,8,6,3,51,69,35,10,255,121, 62,14,255,123,60,14,255,16,11,5,227,4,3,3,28,0,8,8,6,3, 170,92,47,11,255,125,64,14,255,108,55,13,255,14,10,5,164,0,40,7, 5,4,198,96,48,13,255,134,65,15,255,133,66,16,255,15,11,6,170,0, 8,7,5,4,85,78,39,11,255,130,64,15,255,130,64,15,255,134,65,15, 255,136,67,17,255,124,62,17,255,114,56,17,255,113,55,16,255,118,60,17, 255,107,55,20,255,48,29,15,255,12,10,7,85,0,20,9,8,6,170,45, 27,12,255,139,70,20,255,131,66,18,255,107,53,14,255,19,13,6,99,0, 8,8,6,5,85,92,46,13,255,131,61,14,255,125,64,14,255,14,10,5, 170,0,12,58,31,9,255,110,59,13,255,115,59,14,255,56,29,9,255,10, 8,5,227,5,4,4,23,0,108,10,8,7,28,28,18,11,212,49,28,16, 255,35,21,12,241,13,10,6,85,0,68,14,10,5,142,20,14,5,170,16, 12,5,164,8,6,3,28,0,8,24,16,9,142,21,15,8,252,23,15,8, 184,11,8,6,34,0,36,14,10,5,142,20,14,5,170,16,11,5,170,10, 8,5,28,0,24,7,6,4,25,20,13,7,147,22,15,7,170,10,8,5, 142,5,4,4,3,0,24,14,10,5,142,20,13,5,170,16,11,5,170,9, 7,4,28,0,16,7,5,4,28,14,10,5,156,14,10,5,229,24,15,9, 255,32,20,11,255,28,18,11,244,12,9,7,108,0,8,10,8,5,142,19, 13,8,235,24,15,7,227,10,8,5,59,0,48,10,8,5,93,23,15,8, 170,28,18,9,173,15,11,6,28,0,12,18,12,5,142,21,14,6,170,9, 7,4,133,0,148,8,6,5,113,89,44,14,255,100,51,21,255,13,10,8, 227,6,5,5,28,0,60,6,5,5,8,17,12,6,142,26,16,7,170,18, 12,5,170,9,7,4,28,0,8,6,5,3,85,54,28,11,255,136,66,19, 255,121,59,18,255,15,10,6,241,0,40,8,6,3,57,12,9,5,170,18, 13,5,178,14,10,5,241,14,10,5,255,14,10,5,252,16,11,5,195,16, 11,5,170,8,6,3,113,0,24,8,6,5,28,24,16,9,204,24,17,9, 255,17,12,6,210,14,10,5,170,16,11,5,170,17,11,6,246,27,17,10, 246,14,10,7,85,0,16,8,6,5,28,21,14,10,195,22,15,11,255,18, 13,9,255,18,13,9,255,22,15,9,255,19,13,8,255,17,12,6,255,17, 11,6,255,15,11,6,255,17,12,6,255,19,13,6,204,12,9,5,28,0, 12,5,4,2,25,8,6,3,122,14,10,5,170,18,13,5,176,14,10,5, 235,15,11,6,255,15,11,6,255,19,12,6,204,19,13,6,170,10,8,5, 170,8,6,5,57,0,48,14,10,5,142,21,13,6,170,16,11,5,170,9, 7,4,28,0,12,5,4,2,25,8,6,3,125,14,10,5,170,14,10,5, 210,23,15,8,255,30,20,11,255,30,20,11,255,23,17,10,255,20,14,9, 244,16,12,9,170,9,8,6,79,0,16,9,7,6,65,15,11,8,170,17, 12,8,232,21,14,8,255,26,16,9,255,23,15,8,255,21,14,8,255,15, 11,6,255,22,15,7,178,11,9,6,170,10,8,7,57,0,32,12,10,5, 142,20,13,5,170,16,11,5,170,9,7,4,28,0,28,5,5,4,28,8, 6,3,133,15,11,6,193,20,15,9,255,28,18,11,255,30,20,11,255,26, 16,9,255,14,10,5,238,16,11,5,170,9,7,4,153,7,5,4,57,0, 16,5,4,2,28,8,6,3,142,18,12,7,207,22,15,9,255,28,18,11, 255,27,18,10,255,18,13,7,255,15,11,6,227,21,13,6,170,10,7,5, 164,7,6,4,57,0,16,14,10,5,142,20,13,5,170,16,12,5,170,9, 7,4,28,0,8,10,8,7,119,149,64,26,255,131,63,26,255,14,11,7, 227,6,5,5,28,0,32,7,5,4,28,14,10,5,156,20,13,5,170,12, 9,5,142,6,5,3,6,0,64,12,10,7,142,24,15,7,170,21,13,6, 170,8,6,3,76,0,48,9,7,6,85,83,43,16,255,176,88,23,255,130, 62,21,255,16,11,7,170,0,28,9,8,6,28,13,10,8,164,23,16,10, 190,16,11,7,252,15,11,6,255,14,10,5,255,14,10,5,255,14,10,5, 255,16,11,5,232,14,10,5,170,8,6,3,85,0,16,14,10,5,142,21, 13,6,170,16,11,5,170,9,7,4,28,0,16,14,10,5,142,20,13,5, 170,16,11,5,170,9,7,4,28,0,12,14,10,5,136,16,12,5,170,16, 11,5,170,18,12,5,170,16,11,5,210,14,10,5,255,14,10,5,249,16, 12,5,193,16,11,5,170,9,7,4,153,7,5,4,57,0,16,5,5,4, 28,8,6,3,125,14,10,5,170,18,12,5,176,14,10,5,238,14,10,5, 246,16,12,5,195,18,13,5,170,16,11,5,170,9,7,4,150,7,5,4, 54,0,16,14,10,5,142,16,12,5,170,16,11,5,170,18,12,5,170,16, 11,5,210,14,10,5,255,14,10,5,249,16,12,5,193,16,11,5,170,9, 7,4,153,7,6,4,57,0,16,14,10,5,142,16,12,5,170,16,11,5, 170,18,12,5,170,16,11,5,210,14,10,5,252,12,9,5,255,16,11,5, 255,20,13,5,201,11,9,4,28,0,12,14,10,5,139,20,13,5,170,16, 11,5,170,9,7,4,28,0,36,5,5,4,28,8,6,3,125,14,10,5, 170,18,13,5,176,14,10,5,238,14,10,5,255,16,11,5,235,18,13,5, 173,16,11,5,170,16,12,5,170,16,11,5,164,9,7,4,28,0,12,12, 9,5,142,21,13,6,170,16,11,5,170,9,7,4,28,0,16,14,10,5, 142,20,13,5,170,16,11,5,170,9,7,4,28,0,12,12,9,5,142,21, 13,6,170,16,11,5,170,9,7,4,28,0,12,6,5,3,28,8,7,5, 139,19,13,8,193,21,15,10,255,31,21,12,255,32,21,13,255,31,20,12, 255,23,17,10,255,18,12,7,212,10,8,5,159,7,6,4,57,0,16,14, 10,5,142,21,13,6,170,16,11,5,170,9,7,4,28,0,16,14,10,5, 142,21,13,6,170,16,12,5,170,9,7,4,28,0,12,14,10,5,136,16, 12,5,170,16,11,5,170,18,12,5,176,17,12,6,252,21,14,8,255,17, 12,6,255,16,11,5,255,20,13,5,204,11,9,4,28,0,12,14,10,5, 142,21,14,6,170,18,12,5,170,9,8,4,28,0,24,14,10,5,142,20, 13,5,170,16,11,5,170,9,7,4,28,0,12,12,9,5,142,21,13,6, 170,16,12,5,170,10,8,5,28,0,16,12,9,5,142,20,13,5,170,16, 11,5,170,9,7,4,28,0,12,5,5,4,28,8,6,3,125,14,10,5, 170,18,12,5,170,20,14,5,173,16,12,5,193,20,13,5,178,20,13,5, 170,16,11,5,170,9,7,4,153,7,6,4,57,0,16,14,10,5,142,21, 13,6,170,16,11,5,170,9,7,4,28,0,44,5,5,4,28,8,6,3, 125,14,10,5,170,18,13,5,170,20,14,5,170,18,12,5,170,13,10,6, 227,72,38,19,255,185,86,32,255,144,64,29,255,20,15,11,232,8,7,7, 28,0,12,14,10,5,142,21,13,6,170,16,11,5,170,9,7,4,28,0, 16,14,10,5,142,20,13,5,170,16,11,5,170,9,7,4,28,0,12,5, 4,2,25,8,6,3,122,14,10,5,170,18,13,5,176,14,10,5,238,14, 10,5,255,14,10,5,249,16,12,5,193,16,11,5,170,9,7,4,153,7, 5,4,57,0,32,14,10,5,142,21,13,6,170,16,11,5,170,9,7,4, 28,0,28,8,6,3,57,9,7,4,164,14,10,5,170,18,13,5,173,14, 10,5,229,14,10,5,255,17,12,6,255,22,15,9,255,20,14,9,252,21, 15,10,176,11,9,6,139,0,32,11,8,4,122,18,12,5,170,14,10,5, 150,7,5,4,28,0,32,8,7,7,57,24,16,11,173,26,18,9,190,13, 10,6,142,5,4,4,11,0,8,8,7,3,68,14,10,5,170,16,11,5, 170,9,7,4,74,0,20,14,10,5,142,20,14,5,170,16,11,5,170,9, 7,4,28,0,16,14,10,5,142,20,14,5,170,16,11,5,170,9,8,4, 28,0,28,14,10,5,142,20,13,5,170,16,11,5,170,9,7,4,28,0, 28,14,10,5,142,18,13,5,170,16,12,5,170,18,13,5,173,14,10,5, 227,14,10,5,255,14,10,5,252,12,9,5,255,12,9,5,255,16,11,5, 255,20,13,5,201,11,9,4,28,0,12,12,10,5,136,16,12,5,170,16, 11,5,170,16,11,5,193,21,15,6,184,14,10,5,31,0,32,8,6,3, 139,54,30,9,255,107,50,12,255,78,39,11,255,9,7,4,161,0,12,20, 13,5,142,18,12,5,210,16,11,5,170,16,11,5,170,16,11,5,170,9, 7,4,28,0,64,13,10,8,57,9,7,6,159,8,6,5,159,10,8,7, 130,10,8,7,119,9,7,6,133,9,7,6,167,10,8,7,170,11,9,8, 113,0,44,5,4,2,28,8,6,3,125,14,10,5,170,18,13,5,176,14, 10,5,238,14,10,5,255,16,11,5,235,18,13,5,173,16,11,5,170,16, 12,5,170,16,11,5,164,9,7,4,28,0,12,14,10,5,136,16,12,5, 170,16,11,5,170,18,12,5,170,16,11,5,210,14,10,5,255,14,10,5, 249,16,12,5,193,16,11,5,170,9,7,4,153,7,5,4,57,0,16,5, 5,4,28,8,6,3,125,14,10,5,170,18,13,5,176,14,10,5,238,14, 10,5,255,14,10,5,249,16,11,5,193,16,11,5,170,9,7,4,150,7, 5,4,57,0,16,5,5,4,28,8,6,3,125,14,10,5,170,18,13,5, 176,14,10,5,238,14,10,5,255,14,10,5,235,18,13,5,173,16,11,5, 170,16,12,5,170,16,11,5,170,9,7,4,28,0,12,5,5,4,28,8, 6,3,125,14,10,5,170,18,13,5,176,14,10,5,235,14,10,5,255,14, 10,5,255,16,11,5,255,20,13,5,207,12,9,5,34,0,28,14,10,5, 142,20,13,5,170,16,11,5,170,9,7,4,28,0,28,6,5,3,85,7, 5,4,85,6,5,3,85,5,4,4,85,5,4,4,105,9,8,4,241,72, 37,11,255,110,54,13,255,67,34,10,255,8,6,3,144,0,12,14,10,5, 142,21,14,6,170,16,12,5,170,9,8,4,28,0,16,14,10,5,142,21, 13,6,170,16,11,5,170,9,7,4,28,0,12,12,9,5,142,21,13,6, 170,16,11,5,170,9,7,4,28,0,12,7,5,2,37,8,6,3,142,8, 6,3,227,25,15,6,255,75,36,10,255,99,51,12,255,66,33,9,255,8, 6,3,130,0,12,14,10,5,139,21,13,6,170,16,11,5,170,9,7,4, 28,0,12,8,6,3,79,14,10,5,170,18,13,5,170,12,9,5,142,0, 16,14,10,5,142,21,13,6,170,16,11,5,170,9,7,4,28,0,12,12, 9,5,142,21,13,6,170,16,11,5,170,9,7,4,28,0,8,20,13,5, 85,11,8,4,28,0,8,12,9,5,142,21,13,6,170,16,11,5,170,9, 7,4,28,0,12,12,9,5,142,21,13,6,170,16,11,5,170,9,7,4, 28,0,16,14,10,5,142,20,13,5,170,16,11,5,170,9,7,4,28,0, 12,5,5,4,28,8,6,3,125,14,10,5,170,18,12,5,170,20,14,5, 173,16,12,5,193,20,13,5,178,20,13,5,170,16,11,5,170,9,7,4, 161,7,6,4,57,0,12,8,6,3,85,84,40,13,255,164,73,23,255,184, 79,27,255,15,11,8,246,0,72,11,10,10,170,176,83,37,255,196,87,33, 255,192,88,31,255,22,15,11,193,0,12,21,15,10,159,26,17,11,255,24, 17,11,221,10,8,7,85,0,44,8,7,3,59,12,9,5,170,16,11,5, 210,14,10,5,255,14,10,5,255,14,10,5,255,14,10,5,246,16,12,5, 193,16,11,5,170,9,7,4,153,6,5,3,57,0,24,14,10,5,142,20, 13,5,170,16,11,5,170,9,7,4,28,0,20,6,5,3,28,8,6,3, 127,14,10,5,170,18,13,5,176,14,10,5,238,14,10,5,255,14,10,5, 235,18,13,5,173,16,11,5,170,16,12,5,170,16,11,5,170,9,7,4, 28,0,28,14,11,7,142,29,19,8,170,17,11,6,159,8,6,3,28,0, 32,7,5,4,28,14,10,5,150,20,13,5,170,12,9,5,142,5,4,2, 14,0,8,15,11,8,142,26,18,9,178,19,13,6,170,8,6,3,68,0, 20,18,12,5,142,16,11,5,238,16,11,5,170,9,7,4,28,0,16,12, 9,5,142,16,11,5,215,18,13,5,187,11,9,4,28,0,16,4,4,3, 6,5,4,2,82,5,4,2,85,5,4,2,85,5,4,2,85,5,4,2, 99,9,7,4,241,72,37,11,255,112,53,13,255,77,39,12,255,10,8,5, 170,0,12,19,13,8,184,20,14,9,255,16,11,7,255,14,11,7,255,17, 12,8,255,22,15,9,255,27,17,10,255,30,19,11,255,28,18,11,255,21, 15,10,255,15,12,8,198,9,7,6,28,0,24,8,6,5,91,15,11,6, 170,14,11,5,238,19,13,6,198,12,9,5,28,0,8,6,5,3,85,54, 29,9,255,100,48,13,255,109,52,14,255,15,11,6,170,0,12,19,13,6, 144,14,10,5,255,16,11,5,178,8,6,3,119,0,255,0,255,0,174,12, 9,7,88,99,44,20,255,26,16,11,232,5,4,4,28,0,92,6,5,3, 57,60,28,11,255,158,67,23,255,88,44,23,255,11,9,6,142,0,255,0, 255,0,150,12,9,7,110,126,51,25,255,25,17,12,232,5,4,4,28,0, 184,6,5,5,28,19,14,10,227,52,29,17,255,30,20,13,255,9,8,6, 82,0,255,0,255,0,255,0,255,0,8,12,10,9,170,172,81,49,255,213, 125,94,255,185,88,58,255,23,16,14,159,0,255,0,255,0,106,5,4,2, 28,16,11,5,244,68,34,9,255,62,33,9,255,9,8,4,139,0,96,10, 8,7,48,71,33,18,255,108,47,23,255,107,48,22,255,113,51,24,255,109, 50,24,255,104,45,21,255,104,45,21,255,113,49,24,255,115,50,24,255,18, 13,9,136,0,255,0,129,9,7,6,34,18,13,9,244,66,31,15,255,84, 37,17,255,83,36,16,255,75,34,14,255,73,35,14,255,91,41,16,255,110, 47,19,255,79,40,16,255,24,16,9,255,8,6,5,57,0,100,22,14,5, 244,40,23,7,255,42,23,7,255,54,28,9,255,60,31,9,255,36,22,7, 255,12,9,5,244,6,5,3,28,0,255,0,29,9,7,6,85,72,34,13, 255,126,56,21,255,148,63,25,255,25,17,14,190,0,72,15,12,12,133,178, 86,57,255,200,89,55,255,194,82,47,255,30,20,17,187,0,255,0,169,9, 7,4,99,17,12,6,255,42,22,9,255,49,25,9,255,54,26,11,255,52, 26,11,255,59,28,12,255,82,37,15,255,111,49,18,255,84,39,17,255,25, 17,10,255,8,7,5,57,0,112,6,5,3,57,38,22,7,255,85,39,12, 255,124,52,21,255,20,13,9,170,0,255,0,255,0,202,8,6,5,28,26, 16,11,170,11,8,6,85,0,100,12,8,5,119,20,14,9,170,12,9,7, 142,0,255,0,255,0,154,9,7,6,28,27,17,12,170,11,9,8,85,0, 192,7,6,6,28,8,7,5,85,8,6,5,57,0,255,0,255,0,255,0, 255,0,16,25,17,16,161,41,27,26,255,40,26,23,235,14,12,11,82,0, 255,0,255,0,110,8,6,3,37,9,7,4,142,9,7,4,136,6,5,3, 6,0,100,23,15,10,153,19,13,10,255,16,11,9,255,16,11,9,255,16, 11,9,255,16,11,9,255,16,11,9,255,18,13,9,255,24,16,11,204,16, 11,9,31,0,255,0,133,10,8,7,142,18,12,9,207,18,13,9,255,16, 11,9,255,15,11,8,255,15,11,8,252,18,13,9,195,18,12,9,170,11, 8,6,167,8,7,5,57,0,104,9,8,4,142,14,10,5,170,13,10,6, 170,13,9,6,170,11,8,6,170,7,6,4,130,6,5,3,28,0,255,0, 37,14,10,7,142,21,14,10,170,19,13,10,170,14,11,9,31,0,72,8, 7,8,14,25,17,16,142,27,18,16,193,26,18,15,170,15,11,10,34,0, 255,0,169,9,7,4,28,11,8,6,170,14,10,7,232,15,10,8,255,15, 10,8,255,15,10,8,255,15,10,8,252,18,12,9,195,18,12,9,170,11, 8,6,167,9,7,6,57,0,120,9,7,4,91,16,11,7,170,20,13,9, 170,13,10,8,28,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, 255,0,255,0,255}}; /* Created by MiniCompress.. an iOS RLE compressor. * Compress Rate : 46.36 % */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_hash.c������������������������������������������������������������0000644�0001750�0001750�00000005370�14647725152�016055� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goomsl_hash.h" #include <string.h> #include <stdlib.h> static GoomHashEntry *entry_new(const char *key, HashValue value) { int len = strlen(key); GoomHashEntry *entry = (GoomHashEntry*)malloc(sizeof(GoomHashEntry)); entry->key = (char *)malloc(len+1); memcpy(entry->key,key,len+1); entry->value = value; entry->lower = NULL; entry->upper = NULL; return entry; } static void entry_free(GoomHashEntry *entry) { if (entry!=NULL) { entry_free(entry->lower); entry_free(entry->upper); free(entry->key); free(entry); } } static void entry_put(GoomHashEntry *entry, const char *key, HashValue value) { int cmp = strcmp(key,entry->key); if (cmp==0) { entry->value = value; } else if (cmp > 0) { if (entry->upper == NULL) entry->upper = entry_new(key,value); else entry_put(entry->upper, key, value); } else { if (entry->lower == NULL) entry->lower = entry_new(key,value); else entry_put(entry->lower, key, value); } } static HashValue *entry_get(GoomHashEntry *entry, const char *key) { int cmp; if (entry==NULL) return NULL; cmp = strcmp(key,entry->key); if (cmp > 0) return entry_get(entry->upper, key); else if (cmp < 0) return entry_get(entry->lower, key); else return &(entry->value); } GoomHash *goom_hash_new(void) { GoomHash *_this = (GoomHash*)malloc(sizeof(GoomHash)); _this->root = NULL; _this->number_of_puts = 0; return _this; } void goom_hash_free(GoomHash *_this) { entry_free(_this->root); free(_this); } void goom_hash_put(GoomHash *_this, const char *key, HashValue value) { _this->number_of_puts += 1; if (_this->root == NULL) _this->root = entry_new(key,value); else entry_put(_this->root,key,value); } HashValue *goom_hash_get(GoomHash *_this, const char *key) { if (_this == NULL) return NULL; return entry_get(_this->root,key); } void goom_hash_put_int(GoomHash *_this, const char *key, int i) { HashValue value; value.i = i; goom_hash_put(_this,key,value); } void goom_hash_put_float(GoomHash *_this, const char *key, float f) { HashValue value; value.f = f; goom_hash_put(_this,key,value); } void goom_hash_put_ptr(GoomHash *_this, const char *key, void *ptr) { HashValue value; value.ptr = ptr; goom_hash_put(_this,key,value); } /* FOR EACH */ static void _goom_hash_for_each(GoomHash *_this, GoomHashEntry *entry, GH_Func func) { if (entry == NULL) return; func(_this, entry->key, &(entry->value)); _goom_hash_for_each(_this, entry->lower, func); _goom_hash_for_each(_this, entry->upper, func); } void goom_hash_for_each(GoomHash *_this, GH_Func func) { _goom_hash_for_each(_this, _this->root, func); } int goom_hash_number_of_puts(GoomHash *_this) { return _this->number_of_puts; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/ifs.c��������������������������������������������������������������������0000644�0001750�0001750�00000042311�14647725152�014327� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * ifs.c --- modified iterated functions system for goom. */ /*- * Copyright (c) 1997 by Massimino Pascal <Pascal.Massimon@ens.fr> * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. * * This file is provided AS IS with no warranties of any kind. The author * shall have no liability with respect to the infringement of copyrights, * trade secrets or any patents by this file or any part thereof. In no * event will the author be liable for any lost revenue or profits or * other special, indirect and consequential damages. * * If this mode is weird and you have an old MetroX server, it is buggy. * There is a free SuSE-enhanced MetroX X server that is fine. * * When shown ifs, Diana Rose (4 years old) said, "It looks like dancing." * * Revision History: * 13-Dec-2003: Added some goom specific stuffs (to make ifs a VisualFX). * 11-Apr-2002: jeko@ios-software.com: Make ifs.c system-indendant. (ifs.h added) * 01-Nov-2000: Allocation checks * 10-May-1997: jwz@jwz.org: turned into a standalone program. * Made it render into an offscreen bitmap and then copy * that onto the screen, to reduce flicker. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* #ifdef STANDALONE */ #include <math.h> #include <stdlib.h> #include <stdio.h> #include "goom_config.h" #ifdef HAVE_MMX #include "mmx.h" #endif #include "goom_graphic.h" #include "ifs.h" #include "goom_tools.h" typedef struct _ifsPoint { gint32 x, y; } IFSPoint; #define MODE_ifs #define PROGCLASS "IFS" #define HACK_INIT init_ifs #define HACK_DRAW draw_ifs #define ifs_opts xlockmore_opts #define DEFAULTS "*delay: 20000 \n" \ "*ncolours: 100 \n" #define SMOOTH_COLORS #define LRAND() ((long) (goom_random(goomInfo->gRandom) & 0x7fffffff)) #define NRAND(n) ((int) (LRAND() % (n))) #if RAND_MAX < 0x10000 #define MAXRAND (((float)(RAND_MAX<16)+((float)RAND_MAX)+1.0f)/127.0f) #else #define MAXRAND (2147483648.0/127.0) /* unsigned 1<<31 / 127.0 (cf goom_tools) as a float */ #endif /*****************************************************/ typedef float DBL; typedef int F_PT; /* typedef float F_PT; */ /*****************************************************/ #define FIX 12 #define UNIT ( 1<<FIX ) #define MAX_SIMI 6 #define MAX_DEPTH_2 10 #define MAX_DEPTH_3 6 #define MAX_DEPTH_4 4 #define MAX_DEPTH_5 2 /* PREVIOUS VALUE #define MAX_SIMI 6 * settings for a PC 120Mhz... * #define MAX_DEPTH_2 10 #define MAX_DEPTH_3 6 #define MAX_DEPTH_4 4 #define MAX_DEPTH_5 3 */ #define DBL_To_F_PT(x) (F_PT)( (DBL)(UNIT)*(x) ) typedef struct Similitude_Struct SIMI; typedef struct Fractal_Struct FRACTAL; struct Similitude_Struct { DBL c_x, c_y; DBL r, r2, A, A2; F_PT Ct, St, Ct2, St2; F_PT Cx, Cy; F_PT R, R2; }; struct Fractal_Struct { int Nb_Simi; SIMI Components[5 * MAX_SIMI]; int Depth, Col; int Count, Speed; int Width, Height, Lx, Ly; DBL r_mean, dr_mean, dr2_mean; int Cur_Pt, Max_Pt; IFSPoint *Buffer1, *Buffer2; }; typedef struct _IFS_DATA { FRACTAL *Root; FRACTAL *Cur_F; /* Used by the Trace recursive method */ IFSPoint *Buf; int Cur_Pt; int initalized; } IfsData; /*****************************************************/ static DBL Gauss_Rand (PluginInfo *goomInfo, DBL c, DBL A, DBL S) { DBL y; y = (DBL) LRAND () / MAXRAND; y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S)); if (NRAND (2)) return (c + y); return (c - y); } static DBL Half_Gauss_Rand (PluginInfo *goomInfo, DBL c, DBL A, DBL S) { DBL y; y = (DBL) LRAND () / MAXRAND; y = A * (1.0 - exp (-y * y * S)) / (1.0 - exp (-S)); return (c + y); } static void Random_Simis (PluginInfo *goomInfo, FRACTAL * F, SIMI * Cur, int i) { while (i--) { Cur->c_x = Gauss_Rand (goomInfo, 0.0, .8, 4.0); Cur->c_y = Gauss_Rand (goomInfo, 0.0, .8, 4.0); Cur->r = Gauss_Rand (goomInfo, F->r_mean, F->dr_mean, 3.0); Cur->r2 = Half_Gauss_Rand (goomInfo, 0.0, F->dr2_mean, 2.0); Cur->A = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (M_PI / 180.0); Cur->A2 = Gauss_Rand (goomInfo, 0.0, 360.0, 4.0) * (M_PI / 180.0); Cur++; } } static void free_ifs_buffers (FRACTAL * Fractal) { if (Fractal->Buffer1 != NULL) { (void) free ((void *) Fractal->Buffer1); Fractal->Buffer1 = (IFSPoint *) NULL; } if (Fractal->Buffer2 != NULL) { (void) free ((void *) Fractal->Buffer2); Fractal->Buffer2 = (IFSPoint *) NULL; } } static void free_ifs (FRACTAL * Fractal) { free_ifs_buffers (Fractal); } /***************************************************************/ static void init_ifs (PluginInfo *goomInfo, IfsData *data) { int i; FRACTAL *Fractal; int width = goomInfo->screen.width; int height = goomInfo->screen.height; if (data->Root == NULL) { data->Root = (FRACTAL *) malloc (sizeof (FRACTAL)); if (data->Root == NULL) return; data->Root->Buffer1 = (IFSPoint *) NULL; data->Root->Buffer2 = (IFSPoint *) NULL; } Fractal = data->Root; free_ifs_buffers (Fractal); i = (NRAND (4)) + 2; /* Number of centers */ switch (i) { case 3: Fractal->Depth = MAX_DEPTH_3; Fractal->r_mean = .6; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; case 4: Fractal->Depth = MAX_DEPTH_4; Fractal->r_mean = .5; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; case 5: Fractal->Depth = MAX_DEPTH_5; Fractal->r_mean = .5; Fractal->dr_mean = .4; Fractal->dr2_mean = .3; break; default: case 2: Fractal->Depth = MAX_DEPTH_2; Fractal->r_mean = .7; Fractal->dr_mean = .3; Fractal->dr2_mean = .4; break; } Fractal->Nb_Simi = i; Fractal->Max_Pt = Fractal->Nb_Simi - 1; for (i = 0; i <= Fractal->Depth + 2; ++i) Fractal->Max_Pt *= Fractal->Nb_Simi; if ((Fractal->Buffer1 = (IFSPoint *) calloc (Fractal->Max_Pt, sizeof (IFSPoint))) == NULL) { free_ifs (Fractal); return; } if ((Fractal->Buffer2 = (IFSPoint *) calloc (Fractal->Max_Pt, sizeof (IFSPoint))) == NULL) { free_ifs (Fractal); return; } Fractal->Speed = 6; Fractal->Width = width; /* modif by JeKo */ Fractal->Height = height; /* modif by JeKo */ Fractal->Cur_Pt = 0; Fractal->Count = 0; Fractal->Lx = (Fractal->Width - 1) / 2; Fractal->Ly = (Fractal->Height - 1) / 2; Fractal->Col = rand () % (width * height); /* modif by JeKo */ Random_Simis (goomInfo, Fractal, Fractal->Components, 5 * MAX_SIMI); } /***************************************************************/ static inline void Transform (SIMI * Simi, F_PT xo, F_PT yo, F_PT * x, F_PT * y) { F_PT xx, yy; xo = xo - Simi->Cx; xo = (xo * Simi->R) >> FIX; /* / UNIT; */ yo = yo - Simi->Cy; yo = (yo * Simi->R) >> FIX; /* / UNIT; */ xx = xo - Simi->Cx; xx = (xx * Simi->R2) >> FIX; /* / UNIT; */ yy = -yo - Simi->Cy; yy = (yy * Simi->R2) >> FIX; /* / UNIT; */ *x = ((xo * Simi->Ct - yo * Simi->St + xx * Simi->Ct2 - yy * Simi->St2) >> FIX /* / UNIT */ ) + Simi->Cx; *y = ((xo * Simi->St + yo * Simi->Ct + xx * Simi->St2 + yy * Simi->Ct2) >> FIX /* / UNIT */ ) + Simi->Cy; } /***************************************************************/ static void Trace (FRACTAL * F, F_PT xo, F_PT yo, IfsData *data) { F_PT x, y, i; SIMI *Cur; Cur = data->Cur_F->Components; for (i = data->Cur_F->Nb_Simi; i; --i, Cur++) { Transform (Cur, xo, yo, &x, &y); data->Buf->x = F->Lx + ((x * F->Lx) >> (FIX+1) /* /(UNIT*2) */ ); data->Buf->y = F->Ly - ((y * F->Ly) >> (FIX+1) /* /(UNIT*2) */ ); data->Buf++; data->Cur_Pt++; if (F->Depth && ((x - xo) >> 4) && ((y - yo) >> 4)) { F->Depth--; Trace (F, x, y, data); F->Depth++; } } } static void Draw_Fractal (IfsData *data) { FRACTAL *F = data->Root; int i, j; F_PT x, y, xo, yo; SIMI *Cur, *Simi; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { Cur->Cx = DBL_To_F_PT (Cur->c_x); Cur->Cy = DBL_To_F_PT (Cur->c_y); Cur->Ct = DBL_To_F_PT (cos (Cur->A)); Cur->St = DBL_To_F_PT (sin (Cur->A)); Cur->Ct2 = DBL_To_F_PT (cos (Cur->A2)); Cur->St2 = DBL_To_F_PT (sin (Cur->A2)); Cur->R = DBL_To_F_PT (Cur->r); Cur->R2 = DBL_To_F_PT (Cur->r2); } data->Cur_Pt = 0; data->Cur_F = F; data->Buf = F->Buffer2; for (Cur = F->Components, i = F->Nb_Simi; i; --i, Cur++) { xo = Cur->Cx; yo = Cur->Cy; for (Simi = F->Components, j = F->Nb_Simi; j; --j, Simi++) { if (Simi == Cur) continue; Transform (Simi, xo, yo, &x, &y); Trace (F, x, y, data); } } /* Erase previous */ F->Cur_Pt = data->Cur_Pt; data->Buf = F->Buffer1; F->Buffer1 = F->Buffer2; F->Buffer2 = data->Buf; } static IFSPoint * draw_ifs (PluginInfo *goomInfo, int *nbpt, IfsData *data) { int i; DBL u, uu, v, vv, u0, u1, u2, u3; SIMI *S, *S1, *S2, *S3, *S4; FRACTAL *F; if (data->Root == NULL) return NULL; F = data->Root; if (F->Buffer1 == NULL) return NULL; u = (DBL) (F->Count) * (DBL) (F->Speed) / 1000.0; uu = u * u; v = 1.0 - u; vv = v * v; u0 = vv * v; u1 = 3.0 * vv * u; u2 = 3.0 * v * uu; u3 = u * uu; S = F->Components; S1 = S + F->Nb_Simi; S2 = S1 + F->Nb_Simi; S3 = S2 + F->Nb_Simi; S4 = S3 + F->Nb_Simi; for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) { S->c_x = u0 * S1->c_x + u1 * S2->c_x + u2 * S3->c_x + u3 * S4->c_x; S->c_y = u0 * S1->c_y + u1 * S2->c_y + u2 * S3->c_y + u3 * S4->c_y; S->r = u0 * S1->r + u1 * S2->r + u2 * S3->r + u3 * S4->r; S->r2 = u0 * S1->r2 + u1 * S2->r2 + u2 * S3->r2 + u3 * S4->r2; S->A = u0 * S1->A + u1 * S2->A + u2 * S3->A + u3 * S4->A; S->A2 = u0 * S1->A2 + u1 * S2->A2 + u2 * S3->A2 + u3 * S4->A2; } Draw_Fractal (data); if (F->Count >= 1000 / F->Speed) { S = F->Components; S1 = S + F->Nb_Simi; S2 = S1 + F->Nb_Simi; S3 = S2 + F->Nb_Simi; S4 = S3 + F->Nb_Simi; for (i = F->Nb_Simi; i; --i, S++, S1++, S2++, S3++, S4++) { S2->c_x = 2.0 * S4->c_x - S3->c_x; S2->c_y = 2.0 * S4->c_y - S3->c_y; S2->r = 2.0 * S4->r - S3->r; S2->r2 = 2.0 * S4->r2 - S3->r2; S2->A = 2.0 * S4->A - S3->A; S2->A2 = 2.0 * S4->A2 - S3->A2; *S1 = *S4; } Random_Simis (goomInfo, F, F->Components + 3 * F->Nb_Simi, F->Nb_Simi); Random_Simis (goomInfo, F, F->Components + 4 * F->Nb_Simi, F->Nb_Simi); F->Count = 0; } else F->Count++; F->Col++; (*nbpt) = data->Cur_Pt; return F->Buffer2; } /***************************************************************/ static void release_ifs (IfsData *data) { if (data->Root != NULL) { free_ifs (data->Root); (void) free ((void *) data->Root); data->Root = (FRACTAL *) NULL; } } #define RAND() goom_random(goomInfo->gRandom) static void ifs_update (PluginInfo *goomInfo, Pixel * data, Pixel * back, int increment, IfsData *fx_data) { static int couleur = 0xc0c0c0c0; static int v[4] = { 2, 4, 3, 2 }; static int col[4] = { 2, 4, 3, 2 }; #define MOD_MER 0 #define MOD_FEU 1 #define MOD_MERVER 2 static int mode = MOD_MERVER; static int justChanged = 0; static int cycle = 0; int cycle10; int nbpt = 0; IFSPoint *points; int i; int couleursl = couleur; int width = goomInfo->screen.width; int height = goomInfo->screen.height; cycle++; if (cycle >= 80) cycle = 0; if (cycle < 40) cycle10 = cycle / 10; else cycle10 = 7 - cycle / 10; { unsigned char *tmp = (unsigned char *) &couleursl; for (i = 0; i < 4; i++) { *tmp = (*tmp) >> cycle10; /* xine: make it darker */ if( *tmp && !((*tmp) >> 1) ) *tmp = 1; else *tmp = (*tmp) >> 1; tmp++; } } points = draw_ifs (goomInfo, &nbpt, fx_data); nbpt--; #ifdef HAVE_MMX movd_m2r (couleursl, mm1); punpckldq_r2r (mm1, mm1); for (i = 0; i < nbpt; i += increment) { int x = points[i].x; int y = points[i].y; if ((x < width) && (y < height) && (x > 0) && (y > 0)) { int pos = x + (y * width); movd_m2r (back[pos], mm0); paddusb_r2r (mm1, mm0); movd_r2m (mm0, data[pos]); } } emms();/*__asm__ __volatile__ ("emms");*/ #else for (i = 0; i < nbpt; i += increment) { int x = (int) points[i].x & 0x7fffffff; int y = (int) points[i].y & 0x7fffffff; if ((x < width) && (y < height)) { int pos = x + (int) (y * width); int tra = 0, i = 0; unsigned char *bra = (unsigned char *) &back[pos]; unsigned char *dra = (unsigned char *) &data[pos]; unsigned char *cra = (unsigned char *) &couleursl; for (; i < 4; i++) { tra = *cra; tra += *bra; if (tra > 255) tra = 255; *dra = tra; ++dra; ++cra; ++bra; } } } #endif /*MMX*/ justChanged--; col[ALPHA] = couleur >> (ALPHA * 8) & 0xff; col[BLEU] = couleur >> (BLEU * 8) & 0xff; col[VERT] = couleur >> (VERT * 8) & 0xff; col[ROUGE] = couleur >> (ROUGE * 8) & 0xff; if (mode == MOD_MER) { col[BLEU] += v[BLEU]; if (col[BLEU] > 255) { col[BLEU] = 255; v[BLEU] = -(RAND() % 4) - 1; } if (col[BLEU] < 32) { col[BLEU] = 32; v[BLEU] = (RAND() % 4) + 1; } col[VERT] += v[VERT]; if (col[VERT] > 200) { col[VERT] = 200; v[VERT] = -(RAND() % 3) - 2; } if (col[VERT] > col[BLEU]) { col[VERT] = col[BLEU]; v[VERT] = v[BLEU]; } if (col[VERT] < 32) { col[VERT] = 32; v[VERT] = (RAND() % 3) + 2; } col[ROUGE] += v[ROUGE]; if (col[ROUGE] > 64) { col[ROUGE] = 64; v[ROUGE] = -(RAND () % 4) - 1; } if (col[ROUGE] < 0) { col[ROUGE] = 0; v[ROUGE] = (RAND () % 4) + 1; } col[ALPHA] += v[ALPHA]; if (col[ALPHA] > 0) { col[ALPHA] = 0; v[ALPHA] = -(RAND () % 4) - 1; } if (col[ALPHA] < 0) { col[ALPHA] = 0; v[ALPHA] = (RAND () % 4) + 1; } if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40) && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64) && (RAND () % 20 == 0)) && (justChanged < 0)) { mode = RAND () % 3 ? MOD_FEU : MOD_MERVER; justChanged = 250; } } else if (mode == MOD_MERVER) { col[BLEU] += v[BLEU]; if (col[BLEU] > 128) { col[BLEU] = 128; v[BLEU] = -(RAND () % 4) - 1; } if (col[BLEU] < 16) { col[BLEU] = 16; v[BLEU] = (RAND () % 4) + 1; } col[VERT] += v[VERT]; if (col[VERT] > 200) { col[VERT] = 200; v[VERT] = -(RAND () % 3) - 2; } if (col[VERT] > col[ALPHA]) { col[VERT] = col[ALPHA]; v[VERT] = v[ALPHA]; } if (col[VERT] < 32) { col[VERT] = 32; v[VERT] = (RAND () % 3) + 2; } col[ROUGE] += v[ROUGE]; if (col[ROUGE] > 128) { col[ROUGE] = 128; v[ROUGE] = -(RAND () % 4) - 1; } if (col[ROUGE] < 0) { col[ROUGE] = 0; v[ROUGE] = (RAND () % 4) + 1; } col[ALPHA] += v[ALPHA]; if (col[ALPHA] > 255) { col[ALPHA] = 255; v[ALPHA] = -(RAND () % 4) - 1; } if (col[ALPHA] < 0) { col[ALPHA] = 0; v[ALPHA] = (RAND () % 4) + 1; } if (((col[VERT] > 32) && (col[ROUGE] < col[VERT] + 40) && (col[VERT] < col[ROUGE] + 20) && (col[BLEU] < 64) && (RAND () % 20 == 0)) && (justChanged < 0)) { mode = RAND () % 3 ? MOD_FEU : MOD_MER; justChanged = 250; } } else if (mode == MOD_FEU) { col[BLEU] += v[BLEU]; if (col[BLEU] > 64) { col[BLEU] = 64; v[BLEU] = -(RAND () % 4) - 1; } if (col[BLEU] < 0) { col[BLEU] = 0; v[BLEU] = (RAND () % 4) + 1; } col[VERT] += v[VERT]; if (col[VERT] > 200) { col[VERT] = 200; v[VERT] = -(RAND () % 3) - 2; } if (col[VERT] > col[ROUGE] + 20) { col[VERT] = col[ROUGE] + 20; v[VERT] = -(RAND () % 3) - 2; v[ROUGE] = (RAND () % 4) + 1; v[BLEU] = (RAND () % 4) + 1; } if (col[VERT] < 0) { col[VERT] = 0; v[VERT] = (RAND () % 3) + 2; } col[ROUGE] += v[ROUGE]; if (col[ROUGE] > 255) { col[ROUGE] = 255; v[ROUGE] = -(RAND () % 4) - 1; } if (col[ROUGE] > col[VERT] + 40) { col[ROUGE] = col[VERT] + 40; v[ROUGE] = -(RAND () % 4) - 1; } if (col[ROUGE] < 0) { col[ROUGE] = 0; v[ROUGE] = (RAND () % 4) + 1; } col[ALPHA] += v[ALPHA]; if (col[ALPHA] > 0) { col[ALPHA] = 0; v[ALPHA] = -(RAND () % 4) - 1; } if (col[ALPHA] < 0) { col[ALPHA] = 0; v[ALPHA] = (RAND () % 4) + 1; } if (((col[ROUGE] < 64) && (col[VERT] > 32) && (col[VERT] < col[BLEU]) && (col[BLEU] > 32) && (RAND () % 20 == 0)) && (justChanged < 0)) { mode = RAND () % 2 ? MOD_MER : MOD_MERVER; justChanged = 250; } } couleur = (col[ALPHA] << (ALPHA * 8)) | (col[BLEU] << (BLEU * 8)) | (col[VERT] << (VERT * 8)) | (col[ROUGE] << (ROUGE * 8)); } /** VISUAL_FX WRAPPER FOR IFS */ static void ifs_vfx_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *goomInfo) { IfsData *data = (IfsData*)_this->fx_data; if (!data->initalized) { data->initalized = 1; init_ifs(goomInfo, data); } ifs_update (goomInfo, dest, src, goomInfo->update.ifs_incr, data); /*TODO: trouver meilleur soluce pour increment (mettre le code de gestion de l'ifs dans ce fichier: ifs_vfx_apply) */ } static void ifs_vfx_init(VisualFX *_this, PluginInfo *info) { (void)info; IfsData *data = (IfsData*)malloc(sizeof(IfsData)); data->Root = (FRACTAL*)NULL; data->initalized = 0; _this->fx_data = data; } static void ifs_vfx_free(VisualFX *_this) { IfsData *data = (IfsData*)_this->fx_data; release_ifs(data); free(data); } VisualFX ifs_visualfx_create(void) { VisualFX vfx = { .init = ifs_vfx_init, .free = ifs_vfx_free, .apply = ifs_vfx_apply }; return vfx; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom.h�������������������������������������������������������������������0000644�0001750�0001750�00000001533�14647725152�014515� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GOOMCORE_H #define _GOOMCORE_H #include "goom_config.h" #include "goom_plugin_info.h" #include "goomsl.h" #define NB_FX 10 PluginInfo *goom_init (guint32 resx, guint32 resy); void goom_set_resolution (PluginInfo *goomInfo, guint32 resx, guint32 resy); /* * forceMode == 0 : do nothing * forceMode == -1 : lock the FX * forceMode == 1..NB_FX : force a switch to FX n# forceMode * * songTitle = pointer to the title of the song... * - NULL if it is not the start of the song * - only have a value at the start of the song */ guint32 *goom_update (PluginInfo *goomInfo, gint16 data[2][512], int forceMode, float fps, char *songTitle, char *message); /* returns 0 if the buffer wasn't accepted */ int goom_set_screenbuffer(PluginInfo *goomInfo, void *buffer); void goom_close (PluginInfo *goomInfo); #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/motif_goom1.h������������������������������������������������������������0000644�0001750�0001750�00000140652�14647725152�016002� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������static const union { const unsigned char u8[sizeof(Motif)]; const Motif motif; } CONV_MOTIF1 = {{ 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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,14,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,13,9,9,7,2,2,9,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,11, 11,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,12,7,4,0,0,0,2,0,0,3,14,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,12,10,9,9,4,1,0, 1,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,10,3,0,0,0,1,1,3,5,0,0,1,14,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,14,6,3,1,1,4,9,1, 1,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, 10,3,0,0,2,7,13,14,14,14,7,0,0,2,14,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,12,1,9,15,15,15,15,3, 0,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,12,4, 0,0,2,10,15,15,15,15,15,15,1,0,0,10,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,9,0,2,14,15,15,15,7, 0,9,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,14,6,0,0, 2,9,15,15,15,15,15,15,15,13,0,0,3,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,11,0,0,10,15,15,15,9, 0,9,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,13,3,0,1,5, 5,4,4,4,6,12,15,15,15,13,0,0,7,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,14,0,0,5,15,15,15,10, 0,7,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,11,1,0,3,3,1, 0,0,0,0,0,0,5,13,15,12,0,0,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,13,14,15, 15,15,15,15,15,15,15,15,14,0,0,1,15,15,15,12, 0,3,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,10,1,2,4,0,0,1, 9,12,12,12,9,3,0,2,14,5,0,7,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,14,7,4,4,1,1,12, 15,15,15,15,15,15,15,15,14,1,0,0,12,15,15,15, 1,0,12,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,10,0,3,2,0,0,3,12, 15,15,15,15,15,14,2,1,13,2,0,12,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,14,3,0,0,0,0,0,2, 13,15,15,15,15,15,15,15,14,1,0,0,8,15,15,15, 1,0,9,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,12,2,1,0,0,0,9,14,15, 15,15,15,15,15,14,1,1,11,0,3,14,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,7,4,11,12,10,1,0, 3,12,15,15,15,15,15,15,13,1,1,0,4,15,15,15, 2,0,10,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,14,2,1,0,0,3,12,15,15,15, 15,15,15,15,15,11,0,5,9,1,12,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,5,1,13,15,15,12,1, 0,1,9,15,15,15,15,15,14,2,5,0,1,14,15,15, 2,0,7,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,14,3,0,0,0,7,14,15,15,15,15, 15,15,15,15,15,9,0,8,7,4,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,7,0,7,8,11,15,13, 2,0,0,3,10,15,15,15,15,5,11,0,0,11,15,15, 6,0,2,14,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,6,0,0,0,8,15,15,15,15,15,15, 15,15,15,15,15,6,0,4,0,6,15,15,15,15,15,15, 14,9,14,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,11,0,3,3,0,8,15, 14,5,0,0,0,4,12,15,15,5,13,2,0,6,15,15, 12,0,0,11,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,10,0,0,0,8,15,15,15,15,15,15,15, 15,15,15,15,10,1,7,6,4,13,15,15,15,15,13,11, 6,0,8,11,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,1,1,11,2,0,5, 14,15,8,0,0,0,0,7,15,5,14,6,0,2,15,15, 15,3,0,5,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,13,1,0,0,7,15,15,15,15,15,15,15,15, 15,15,15,15,7,9,15,15,15,15,15,15,12,6,2,1, 1,1,8,6,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,4,0,6,12,1,0, 3,13,15,11,2,0,0,0,8,4,14,10,0,0,13,15, 15,7,0,1,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,5,0,0,5,15,15,15,15,15,15,15,15,15, 15,15,15,15,13,15,15,15,15,14,8,3,1,2,7,11, 5,4,5,6,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,8,0,1,14,11,0, 0,1,9,15,14,5,0,0,2,4,14,13,0,0,10,15, 15,12,0,0,12,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,10,0,0,1,14,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,14,13,7,2,0,5,9,15,15,15, 5,3,6,9,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,13,0,0,9,15,12, 2,0,0,4,13,14,4,0,3,2,12,15,1,0,5,15, 15,14,1,0,8,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,2,0,0,9,15,15,15,15,15,15,15,15,15,15, 15,15,15,12,11,6,1,0,2,3,10,15,15,15,15,7, 1,2,4,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,5,0,3,14,15, 9,2,0,0,1,6,12,13,13,1,9,12,0,0,2,14, 15,15,4,0,4,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,10,0,0,2,14,15,15,15,15,15,15,15,15,15,15, 13,9,6,0,1,2,9,10,15,15,15,15,14,7,1,0, 6,2,4,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,11,0,0,9,15, 4,4,11,6,1,0,0,1,1,0,10,4,0,0,0,12, 15,15,9,0,1,14,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,3,0,0,8,15,15,15,15,15,15,15,13,12,4,4, 1,1,3,10,12,15,15,15,15,15,9,2,1,0,1,6, 6,0,10,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,4,0,3,14, 4,3,15,15,14,9,7,9,1,0,0,0,0,1,0,7, 15,15,13,0,0,9,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, 13,0,0,1,14,15,15,15,15,15,12,9,1,0,1,4, 7,15,15,15,15,15,15,14,8,2,0,0,0,2,13,9, 0,4,14,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,11,0,0,9, 3,0,8,14,15,15,15,15,10,5,4,4,7,4,0,3, 15,15,15,4,0,3,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, 5,0,0,5,15,15,15,15,14,8,7,8,10,12,14,15, 15,15,15,15,15,15,11,1,0,0,0,5,11,15,13,1, 1,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,3,0,4, 4,0,0,2,6,10,15,15,15,15,15,15,15,10,0,0, 12,15,15,9,0,0,12,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, 1,0,0,10,15,15,15,15,15,13,14,15,15,15,15,15, 15,15,15,15,14,7,1,0,0,3,12,15,15,15,6,0, 7,15,15,15,12,10,9,10,12,14,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,9,0,0, 8,3,1,4,1,0,1,12,15,15,15,15,15,14,2,0, 6,15,15,15,2,0,6,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, 0,0,1,14,15,15,15,15,14,5,15,15,15,15,15,15, 15,15,15,7,2,0,0,1,8,15,15,15,15,12,0,2, 14,15,12,4,0,0,0,0,0,1,5,10,14,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,14,0,0, 5,4,1,14,15,10,7,13,15,15,15,15,15,15,8,0, 1,14,15,15,7,0,1,14,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,13, 0,0,4,15,15,15,15,15,13,2,13,15,15,15,15,15, 12,7,0,0,0,0,5,12,15,15,15,15,14,3,0,9, 11,1,0,0,1,1,0,1,0,0,0,0,2,12,15,15, 15,15,15,15,15,15,15,14,15,15,15,15,15,15,2,0, 5,2,1,14,15,14,13,15,15,15,15,15,15,15,12,0, 0,10,15,15,13,0,0,9,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,12, 0,0,4,15,15,15,15,15,12,0,12,15,15,15,12,6, 0,0,0,0,6,14,15,15,15,15,15,15,7,0,0,12, 1,0,0,2,2,1,1,7,12,8,3,0,0,1,13,15, 15,15,15,15,15,8,4,8,12,15,15,15,15,15,8,0, 4,2,0,14,15,11,9,15,15,15,15,15,15,15,15,3, 0,5,15,15,15,5,0,3,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,12, 0,0,4,15,15,15,15,15,12,0,12,15,13,3,1,0, 0,0,5,12,15,15,15,15,15,15,15,12,0,0,7,7, 0,0,0,0,0,0,0,1,12,15,15,12,3,0,5,15, 15,15,15,14,5,0,0,0,0,2,2,3,7,14,9,8, 14,2,1,14,15,2,12,13,15,15,15,15,15,15,15,9, 0,0,13,15,15,10,0,0,12,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,13, 0,0,5,15,15,15,15,15,12,0,11,10,1,0,0,1, 5,14,15,15,15,15,15,15,15,15,15,6,0,2,7,0, 0,0,0,1,2,7,4,0,3,14,15,15,14,2,0,12, 15,15,15,9,0,1,2,1,0,0,0,0,0,1,3,7, 15,3,0,14,15,4,12,15,15,15,15,15,15,15,15,14, 1,0,8,15,15,14,1,0,8,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,13, 0,0,4,15,15,15,15,15,12,0,2,0,0,1,10,15, 15,15,15,15,15,15,15,15,15,15,12,0,0,6,0,0, 0,1,10,14,15,15,11,1,0,9,15,15,15,8,0,9, 15,15,12,4,8,14,15,8,1,0,0,0,0,0,1,9, 15,2,0,13,15,1,9,15,15,15,15,15,15,15,15,15, 6,0,1,14,15,14,1,0,3,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,14, 1,0,1,14,15,15,15,15,12,1,3,7,9,13,15,15, 15,15,15,15,15,15,15,15,15,15,3,0,2,3,0,4, 0,8,15,15,15,15,15,13,1,2,14,15,15,10,0,6, 15,14,2,6,15,15,15,1,3,7,3,0,0,0,0,1, 11,1,0,11,12,0,12,15,15,15,15,15,15,15,15,15, 11,0,0,9,15,15,4,0,0,12,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, 6,0,0,9,15,15,15,15,15,12,14,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,11,0,0,3,0,8,14, 2,5,15,15,15,15,15,15,5,0,8,15,15,12,0,4, 15,5,2,14,15,15,10,0,13,15,13,2,4,5,5,0, 9,1,0,10,9,1,14,15,15,15,15,15,15,15,15,15, 13,0,0,3,15,15,9,0,0,8,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, 12,0,0,3,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,3,0,1,1,5,14,15, 11,0,12,15,15,15,15,15,14,1,1,14,15,12,0,4, 10,0,9,15,15,11,1,8,15,15,8,1,14,15,14,2, 5,0,0,10,6,2,15,15,15,15,15,15,15,15,15,15, 15,3,0,0,12,15,13,0,0,2,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,3,0,0,10,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,10,0,0,1,0,11,15,15, 15,2,6,15,15,15,15,15,15,6,0,9,15,13,0,6, 3,0,13,15,14,2,6,15,15,13,1,8,15,15,15,4, 3,1,0,10,7,2,15,15,15,15,15,15,15,15,15,15, 15,9,0,0,6,15,15,3,0,0,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,9,0,0,2,14,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,11,10,2,0,3,0,3,15,15,15, 15,8,1,14,15,15,15,15,15,13,0,2,15,9,1,10, 0,3,15,15,6,2,14,15,14,3,1,14,15,15,15,2, 4,0,0,12,5,3,15,15,15,15,15,15,15,15,15,15, 15,14,1,0,1,14,15,5,0,0,12,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,4,0,0,6,15,15,15,15,15,15,15,15,14,12, 12,9,5,4,4,3,0,0,0,0,4,0,8,15,15,15, 15,13,1,10,15,15,15,15,15,15,2,0,11,3,5,10, 0,7,15,9,1,11,15,15,8,0,6,15,15,15,10,0, 3,0,0,13,3,6,15,15,15,15,15,15,15,15,15,15, 15,15,6,0,0,12,15,5,0,0,7,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,13,1,0,0,8,14,15,15,13,6,4,4,1,0, 0,0,0,0,0,0,2,0,0,4,3,0,12,15,15,15, 15,15,5,3,15,15,15,15,14,8,0,0,1,1,12,9, 0,9,10,0,6,15,15,15,2,2,14,15,15,13,2,0, 4,0,1,13,0,10,15,15,15,15,15,15,15,15,15,15, 15,15,13,1,0,10,15,10,0,0,5,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,9,0,0,0,3,2,2,1,0,0,0,1,4, 4,5,10,12,12,12,11,0,0,11,4,0,12,15,15,15, 15,15,12,0,7,13,15,15,5,0,0,0,1,6,15,9, 0,3,0,0,1,6,14,10,0,12,15,15,11,2,0,2, 3,0,3,12,1,11,15,15,15,15,15,15,15,15,15,15, 15,15,15,3,0,6,8,7,0,0,5,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,9,1,0,0,0,2,6,10,12,12,14,15, 15,15,15,15,11,5,4,0,2,14,4,0,12,15,15,15, 15,15,15,4,0,3,13,6,0,0,0,1,2,14,15,12, 0,0,0,0,0,0,2,2,6,15,14,8,0,0,0,7, 4,0,4,12,0,12,15,15,15,15,15,15,15,15,15,15, 15,15,15,12,0,0,0,0,0,0,1,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,12,2,0,0,0,1,6,11,15,15,15, 15,15,15,15,2,1,0,0,9,15,6,0,7,15,15,15, 15,15,15,13,2,0,0,0,0,0,0,1,12,15,15,15, 4,0,0,0,0,0,0,6,13,6,1,0,0,4,13,15, 6,0,6,12,0,12,15,15,15,15,15,15,15,15,15,15, 15,15,15,14,5,0,0,0,0,0,5,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,14,5,0,0,0,0,0,2,4,5, 7,3,6,3,0,2,0,2,15,15,11,0,0,9,15,15, 15,15,15,15,11,0,0,0,0,0,2,11,15,15,15,15, 12,1,0,0,1,4,6,10,2,0,0,0,7,14,15,15, 9,0,9,9,0,12,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,13,9,8,9,7,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,12,6,1,0,0,0,0,0, 0,0,0,2,8,0,0,9,15,15,14,4,0,0,3,10, 14,15,15,15,15,13,3,0,0,4,14,15,15,15,15,15, 15,11,2,0,0,1,1,0,0,0,1,11,15,15,15,15, 9,0,10,5,3,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,14,12,10,5,4,6, 2,4,10,14,8,0,1,14,15,15,15,14,5,0,0,0, 1,2,4,4,4,3,1,2,9,14,15,15,15,15,15,15, 15,15,15,11,11,13,10,9,9,11,15,15,15,15,15,15, 10,0,8,2,4,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, 2,7,15,14,1,0,6,15,15,15,15,15,15,10,6,4, 2,2,4,4,4,3,9,14,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 11,0,3,1,4,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,11, 1,10,15,9,0,0,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, 11,0,11,11,11,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,2, 5,15,14,2,0,5,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, 14,1,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,10,1, 13,15,11,0,0,12,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,5,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,8,1, 15,15,5,0,3,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,10,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,12,2,3, 15,14,1,0,7,15,15,15,15,15,13,15,15,15,15,14, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,13,12,12,11,9,4,7,14,15, 14,13,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,15,15,15,12,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,14,3,0,10, 15,9,0,0,8,7,4,2,2,1,0,3,4,3,4,9, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,14,13,11,7,4,2,0,0,0,0,0,0,1,12,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,14,13,11,7,4,2,2,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,12,0,3,11, 7,1,0,0,0,0,0,1,4,9,11,15,15,15,15,15, 15,15,15,15,15,15,15,15,15,15,14,12,11,9,7,4, 3,1,0,0,0,0,0,0,0,0,0,2,11,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,13,11,8, 4,3,1,0,0,0,0,3,8,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,14,11,3,0,0,0, 0,0,0,2,6,9,12,14,15,15,15,15,15,15,15,15, 15,15,15,15,15,13,9,6,3,1,0,0,0,0,0,0, 0,0,0,0,1,4,7,11,12,12,12,14,15,15,15,15, 15,15,15,15,15,15,15,14,12,11,7,4,2,0,0,0, 0,0,0,1,5,10,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,14,12,7,3,1,0,0,0,2,5, 2,0,2,14,15,15,15,15,15,15,15,15,15,14,13,12, 11,9,6,4,2,0,0,0,0,0,0,0,0,1,2,4, 5,9,11,13,15,15,15,15,15,15,15,15,15,15,15,15, 15,14,12,11,7,4,3,1,0,0,0,0,0,0,0,1, 4,5,10,14,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,13,10,5,1,0,0,0,1,0,0,2,13,14, 1,0,8,15,15,14,12,11,9,8,4,3,2,1,0,0, 0,0,0,0,1,3,2,3,5,9,10,12,13,14,15,15, 15,15,15,15,15,15,15,15,15,15,15,13,11,10,6,4, 3,1,0,0,0,0,0,0,0,0,1,4,7,11,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,11,4,0,0,0,1,4,9,13,13,1,0,0,1,7, 0,0,7,8,5,2,0,0,0,0,0,0,1,2,3,4, 5,9,10,12,14,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,14,11,8,4,3,1,0,0,0,0,0, 0,0,0,0,1,4,5,9,12,13,15,15,15,15,15,15, 15,15,14,12,9,8,8,7,4,2,5,4,5,5,12,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,14,10,5, 1,0,1,3,6,11,14,15,15,15,15,13,12,8,3,2, 0,0,1,1,3,3,4,5,8,10,12,13,14,15,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13, 11,9,6,4,2,1,0,0,0,0,0,0,0,1,2,4, 6,10,11,13,15,15,15,15,15,15,15,15,13,11,9,7, 4,2,1,0,0,0,0,2,4,7,12,14,14,14,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,10,5,1,1,3, 8,12,14,15,15,15,15,15,15,15,15,15,15,15,15,9, 3,11,14,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,8,6,9,9,9,9,9,8,5,4,4,3,1,0, 0,0,0,0,1,2,3,2,4,5,9,11,12,14,15,15, 15,15,15,15,15,15,15,14,12,9,5,2,0,0,0,0, 0,1,2,4,7,10,14,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,14,9,4,1,3,9,13,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,13, 11,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,13,3,1,1,1,1,1,1,1,0,0,0,0,2,3, 5,8,10,12,14,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,15,12,5,2,0,0,0,1,3,4,7,10, 12,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,13,11,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,14,12,12,12,13,15,15, 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, 15,15,15,15,8,1,0,1,4,7,11,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,13,7,8,11,14,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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,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 }}; ��������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_visual_fx.h���������������������������������������������������������0000644�0001750�0001750�00000001123�14647725152�016570� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _VISUAL_FX_H #define _VISUAL_FX_H /** * File created on 2003-05-21 by Jeko. * (c)2003, JC Hoelt for iOS-software. * * LGPL Licence. * If you use this file on a visual program, * please make my name being visible on it. */ #include "goom_config_param.h" #include "goom_graphic.h" #include "goom_typedefs.h" struct _VISUAL_FX { void (*init) (struct _VISUAL_FX *_this, PluginInfo *info); void (*free) (struct _VISUAL_FX *_this); void (*apply) (struct _VISUAL_FX *_this, Pixel *src, Pixel *dest, PluginInfo *info); void *fx_data; PluginParameters *params; }; #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl.h�����������������������������������������������������������������0000644�0001750�0001750�00000002432�14647725152�015053� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GOOMSL_H #define _GOOMSL_H #include "goomsl_hash.h" typedef struct _GoomSL GoomSL; typedef void (*GoomSL_ExternalFunction)(GoomSL *gsl, GoomHash *global_vars, GoomHash *local_vars); GoomSL*gsl_new(void); void gsl_free(GoomSL *gss); char *gsl_init_buffer(const char *file_name); void gsl_append_file_to_buffer(const char *file_name, char **buffer); void gsl_compile (GoomSL *scanner, const char *script); void gsl_execute (GoomSL *scanner); int gsl_is_compiled (GoomSL *gss); void gsl_bind_function(GoomSL *gss, const char *fname, GoomSL_ExternalFunction func); int gsl_malloc (GoomSL *_this, int size); void *gsl_get_ptr (GoomSL *_this, int id); void gsl_free_ptr(GoomSL *_this, int id); GoomHash *gsl_globals(GoomSL *_this); #define GSL_LOCAL_PTR(gsl,local,name) gsl_get_ptr(gsl, *(int*)goom_hash_get(local,name)->ptr) #define GSL_LOCAL_INT(gsl,local,name) (*(int*)goom_hash_get(local,name)->ptr) #define GSL_LOCAL_FLOAT(gsl,local,name) (*(float*)goom_hash_get(local,name)->ptr) #define GSL_GLOBAL_PTR(gsl,name) gsl_get_ptr(gsl, *(int*)goom_hash_get(gsl_globals(gsl),name)->ptr) #define GSL_GLOBAL_INT(gsl,name) (*(int*)goom_hash_get(gsl_globals(gsl),name)->ptr) #define GSL_GLOBAL_FLOAT(gsl,name) (*(float*)goom_hash_get(gsl_globals(gsl),name)->ptr) #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_private.h���������������������������������������������������������0000644�0001750�0001750�00000013267�14647725152�016615� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GSL_PRIVATE_H #define _GSL_PRIVATE_H /* -- internal use -- */ #include "goomsl.h" #ifdef USE_JITC_X86 #include "jitc_x86.h" #endif #include "goomsl_heap.h" /* {{{ type of nodes */ #define EMPTY_NODE 0 #define CONST_INT_NODE 1 #define CONST_FLOAT_NODE 2 #define CONST_PTR_NODE 3 #define VAR_NODE 4 #define PARAM_NODE 5 #define READ_PARAM_NODE 6 #define OPR_NODE 7 /* }}} */ /* {{{ type of operations */ #define OPR_SET 1 #define OPR_IF 2 #define OPR_WHILE 3 #define OPR_BLOCK 4 #define OPR_ADD 5 #define OPR_MUL 6 #define OPR_EQU 7 #define OPR_NOT 8 #define OPR_LOW 9 #define OPR_DIV 10 #define OPR_SUB 11 #define OPR_FUNC_INTRO 12 #define OPR_FUNC_OUTRO 13 #define OPR_CALL 14 #define OPR_EXT_CALL 15 #define OPR_PLUS_EQ 16 #define OPR_SUB_EQ 17 #define OPR_MUL_EQ 18 #define OPR_DIV_EQ 19 #define OPR_CALL_EXPR 20 #define OPR_AFFECT_LIST 21 #define OPR_FOREACH 22 #define OPR_VAR_LIST 23 /* }}} */ typedef struct _ConstIntNodeType { /* {{{ */ int val; } ConstIntNodeType; /* }}} */ typedef struct _ConstFloatNodeType { /* {{{ */ float val; } ConstFloatNodeType; /* }}} */ typedef struct _ConstPtrNodeType { /* {{{ */ int id; } ConstPtrNodeType; /* }}} */ typedef struct _OprNodeType { /* {{{ */ int type; int nbOp; struct _NODE_TYPE *op[3]; /* maximal number of operand needed */ struct _NODE_TYPE *next; } OprNodeType; /* }}} */ typedef struct _NODE_TYPE { /* {{{ */ int type; char *str; GoomHash *vnamespace; int line_number; union { ConstIntNodeType constInt; ConstFloatNodeType constFloat; ConstPtrNodeType constPtr; OprNodeType opr; } unode; } NodeType; /* }}} */ typedef struct _INSTRUCTION_DATA { /* {{{ */ union { void *var; int *var_int; int *var_ptr; float *var_float; int jump_offset; struct _ExternalFunctionStruct *external_function; } udest; union { void *var; int *var_int; int *var_ptr; float *var_float; int value_int; int value_ptr; float value_float; } usrc; } InstructionData; /* }}} */ typedef struct _INSTRUCTION { /* {{{ */ int id; InstructionData data; GoomSL *parent; const char *name; /* name of the instruction */ char **params; /* parametres de l'instruction */ GoomHash **vnamespace; int *types; /* type des parametres de l'instruction */ int cur_param; int nb_param; int address; char *jump_label; char *nop_label; int line_number; } Instruction; /* }}} */ typedef struct _INSTRUCTION_FLOW { /* {{{ */ Instruction **instr; int number; int tabsize; GoomHash *labels; } InstructionFlow; /* }}} */ typedef struct _FAST_INSTRUCTION { /* {{{ */ int id; InstructionData data; Instruction *proto; } FastInstruction; /* }}} */ typedef struct _FastInstructionFlow { /* {{{ */ int number; FastInstruction *instr; void *mallocedInstr; } FastInstructionFlow; /* }}} */ typedef struct _ExternalFunctionStruct { /* {{{ */ GoomSL_ExternalFunction function; GoomHash *vars; int is_extern; } ExternalFunctionStruct; /* }}} */ typedef struct _Block { int data; int size; } Block; typedef struct _GSL_StructField { /* {{{ */ int type; char name[256]; int offsetInStruct; /* Where this field is stored... */ } GSL_StructField; /* }}} */ typedef struct _GSL_Struct { /* {{{ */ int nbFields; GSL_StructField *fields[64]; int size; Block iBlock[64]; Block fBlock[64]; } GSL_Struct; /* }}} */ struct _GoomSL { /* {{{ */ int num_lines; Instruction *instr; /* instruction en cours de construction */ InstructionFlow *iflow; /* flow d'instruction 'normal' */ FastInstructionFlow *fastiflow; /* flow d'instruction optimise */ GoomHash *vars; /* table de variables */ int currentNS; GoomHash *namespaces[16]; GoomHash *functions; /* table des fonctions externes */ GoomHeap *data_heap; /* GSL Heap-like memory space */ int nbStructID; GoomHash *structIDS; GSL_Struct **gsl_struct; int gsl_struct_size; int nbPtr; int ptrArraySize; void **ptrArray; int compilationOK; #ifdef USE_JITC_X86 JitcX86Env *jitc; JitcFunc jitc_func; #endif }; /* }}} */ extern GoomSL *currentGoomSL; Instruction *gsl_instr_init(GoomSL *parent, const char *name, int id, int nb_param, int line_number); void gsl_instr_add_param(Instruction *_this, const char *param, int type); void gsl_instr_set_namespace(Instruction *_this, GoomHash *ns); void gsl_declare_task(const char *name); void gsl_declare_external_task(const char *name); int gsl_type_of_var(GoomHash *namespace, const char *name); void gsl_enternamespace(const char *name); void gsl_reenternamespace(GoomHash *ns); GoomHash *gsl_leavenamespace(void); GoomHash *gsl_find_namespace(const char *name); void gsl_commit_compilation(void); /* #define TYPE_PARAM 1 */ #define FIRST_RESERVED 0x80000 #define TYPE_INTEGER 0x90001 #define TYPE_FLOAT 0x90002 #define TYPE_VAR 0x90003 #define TYPE_PTR 0x90004 #define TYPE_LABEL 0x90005 #define TYPE_OP_EQUAL 6 #define TYPE_IVAR 0xa0001 #define TYPE_FVAR 0xa0002 #define TYPE_PVAR 0xa0003 #define TYPE_SVAR 0xa0004 #define INSTR_JUMP 6 #define INSTR_JZERO 29 #define INSTR_CALL 36 #define INSTR_RET 37 #define INSTR_EXT_CALL 38 #define INSTR_JNZERO 40 #define INSTR_SET 0x80001 #define INSTR_INT 0x80002 #define INSTR_FLOAT 0x80003 #define INSTR_PTR 0x80004 #define INSTR_LABEL 0x80005 #define INSTR_ISLOWER 0x80006 #define INSTR_ADD 0x80007 #define INSTR_MUL 0x80008 #define INSTR_DIV 0x80009 #define INSTR_SUB 0x80010 #define INSTR_ISEQUAL 0x80011 #define INSTR_NOT 0x80012 #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/tentacle3d.h�������������������������������������������������������������0000644�0001750�0001750�00000000165�14647725152�015602� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _TENTACLE3D_H #define _TENTACLE3D_H #include "goom_visual_fx.h" VisualFX tentacle_fx_create(void); #endif �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/mathtools.c��������������������������������������������������������������0000644�0001750�0001750�00000012323�14647725152�015560� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*---------------------------------------------------------------------------*/ /* ** mathtools.c ** Goom Project ** ** Created by Jeko on Sun Jul 20 2003 ** Copyright (c) 2003 iOS. All rights reserved. */ /*---------------------------------------------------------------------------*/ static const float sin256[256] = { 0,0.0245412,0.0490677,0.0735646,0.0980171,0.122411,0.14673,0.170962 ,0.19509,0.219101,0.24298,0.266713,0.290285,0.313682,0.33689,0.359895 ,0.382683,0.405241,0.427555,0.449611,0.471397,0.492898,0.514103,0.534998 ,0.55557,0.575808,0.595699,0.615232,0.634393,0.653173,0.671559,0.689541 ,0.707107,0.724247,0.740951,0.757209,0.77301,0.788346,0.803208,0.817585 ,0.83147,0.844854,0.857729,0.870087,0.881921,0.893224,0.903989,0.91421 ,0.92388,0.932993,0.941544,0.949528,0.95694,0.963776,0.970031,0.975702 ,0.980785,0.985278,0.989177,0.99248,0.995185,0.99729,0.998795,0.999699 ,1,0.999699,0.998795,0.99729,0.995185,0.99248,0.989177,0.985278 ,0.980785,0.975702,0.970031,0.963776,0.95694,0.949528,0.941544,0.932993 ,0.92388,0.91421,0.903989,0.893224,0.881921,0.870087,0.857729,0.844854 ,0.83147,0.817585,0.803208,0.788346,0.77301,0.757209,0.740951,0.724247 ,0.707107,0.689541,0.671559,0.653173,0.634393,0.615232,0.595699,0.575808 ,0.55557,0.534998,0.514103,0.492898,0.471397,0.449611,0.427555,0.405241 ,0.382683,0.359895,0.33689,0.313682,0.290285,0.266713,0.24298,0.219101 ,0.19509,0.170962,0.14673,0.122411,0.0980171,0.0735646,0.0490677,0.0245412 ,1.22465e-16,-0.0245412,-0.0490677,-0.0735646,-0.0980171,-0.122411,-0.14673,-0.170962 ,-0.19509,-0.219101,-0.24298,-0.266713,-0.290285,-0.313682,-0.33689,-0.359895 ,-0.382683,-0.405241,-0.427555,-0.449611,-0.471397,-0.492898,-0.514103,-0.534998 ,-0.55557,-0.575808,-0.595699,-0.615232,-0.634393,-0.653173,-0.671559,-0.689541 ,-0.707107,-0.724247,-0.740951,-0.757209,-0.77301,-0.788346,-0.803208,-0.817585 ,-0.83147,-0.844854,-0.857729,-0.870087,-0.881921,-0.893224,-0.903989,-0.91421 ,-0.92388,-0.932993,-0.941544,-0.949528,-0.95694,-0.963776,-0.970031,-0.975702 ,-0.980785,-0.985278,-0.989177,-0.99248,-0.995185,-0.99729,-0.998795,-0.999699 ,-1,-0.999699,-0.998795,-0.99729,-0.995185,-0.99248,-0.989177,-0.985278 ,-0.980785,-0.975702,-0.970031,-0.963776,-0.95694,-0.949528,-0.941544,-0.932993 ,-0.92388,-0.91421,-0.903989,-0.893224,-0.881921,-0.870087,-0.857729,-0.844854 ,-0.83147,-0.817585,-0.803208,-0.788346,-0.77301,-0.757209,-0.740951,-0.724247 ,-0.707107,-0.689541,-0.671559,-0.653173,-0.634393,-0.615232,-0.595699,-0.575808 ,-0.55557,-0.534998,-0.514103,-0.492898,-0.471397,-0.449611,-0.427555,-0.405241 ,-0.382683,-0.359895,-0.33689,-0.313682,-0.290285,-0.266713,-0.24298,-0.219101 ,-0.19509,-0.170962,-0.14673,-0.122411,-0.0980171,-0.0735646,-0.0490677,-0.0245412 }; static const float cos256[256] = { 0,0.999699,0.998795,0.99729,0.995185,0.99248,0.989177,0.985278 ,0.980785,0.975702,0.970031,0.963776,0.95694,0.949528,0.941544,0.932993 ,0.92388,0.91421,0.903989,0.893224,0.881921,0.870087,0.857729,0.844854 ,0.83147,0.817585,0.803208,0.788346,0.77301,0.757209,0.740951,0.724247 ,0.707107,0.689541,0.671559,0.653173,0.634393,0.615232,0.595699,0.575808 ,0.55557,0.534998,0.514103,0.492898,0.471397,0.449611,0.427555,0.405241 ,0.382683,0.359895,0.33689,0.313682,0.290285,0.266713,0.24298,0.219101 ,0.19509,0.170962,0.14673,0.122411,0.0980171,0.0735646,0.0490677,0.0245412 ,6.12323e-17,-0.0245412,-0.0490677,-0.0735646,-0.0980171,-0.122411,-0.14673,-0.170962 ,-0.19509,-0.219101,-0.24298,-0.266713,-0.290285,-0.313682,-0.33689,-0.359895 ,-0.382683,-0.405241,-0.427555,-0.449611,-0.471397,-0.492898,-0.514103,-0.534998 ,-0.55557,-0.575808,-0.595699,-0.615232,-0.634393,-0.653173,-0.671559,-0.689541 ,-0.707107,-0.724247,-0.740951,-0.757209,-0.77301,-0.788346,-0.803208,-0.817585 ,-0.83147,-0.844854,-0.857729,-0.870087,-0.881921,-0.893224,-0.903989,-0.91421 ,-0.92388,-0.932993,-0.941544,-0.949528,-0.95694,-0.963776,-0.970031,-0.975702 ,-0.980785,-0.985278,-0.989177,-0.99248,-0.995185,-0.99729,-0.998795,-0.999699 ,-1,-0.999699,-0.998795,-0.99729,-0.995185,-0.99248,-0.989177,-0.985278 ,-0.980785,-0.975702,-0.970031,-0.963776,-0.95694,-0.949528,-0.941544,-0.932993 ,-0.92388,-0.91421,-0.903989,-0.893224,-0.881921,-0.870087,-0.857729,-0.844854 ,-0.83147,-0.817585,-0.803208,-0.788346,-0.77301,-0.757209,-0.740951,-0.724247 ,-0.707107,-0.689541,-0.671559,-0.653173,-0.634393,-0.615232,-0.595699,-0.575808 ,-0.55557,-0.534998,-0.514103,-0.492898,-0.471397,-0.449611,-0.427555,-0.405241 ,-0.382683,-0.359895,-0.33689,-0.313682,-0.290285,-0.266713,-0.24298,-0.219101 ,-0.19509,-0.170962,-0.14673,-0.122411,-0.0980171,-0.0735646,-0.0490677,-0.0245412 ,-1.83697e-16,0.0245412,0.0490677,0.0735646,0.0980171,0.122411,0.14673,0.170962 ,0.19509,0.219101,0.24298,0.266713,0.290285,0.313682,0.33689,0.359895 ,0.382683,0.405241,0.427555,0.449611,0.471397,0.492898,0.514103,0.534998 ,0.55557,0.575808,0.595699,0.615232,0.634393,0.653173,0.671559,0.689541 ,0.707107,0.724247,0.740951,0.757209,0.77301,0.788346,0.803208,0.817585 ,0.83147,0.844854,0.857729,0.870087,0.881921,0.893224,0.903989,0.91421 ,0.92388,0.932993,0.941544,0.949528,0.95694,0.963776,0.970031,0.975702 ,0.980785,0.985278,0.989177,0.99248,0.995185,0.99729,0.998795,0.999699 }; �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/v3d.c��������������������������������������������������������������������0000644�0001750�0001750�00000000636�14647725152�014246� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "v3d.h" void v3d_to_v2d(v3d *v3, int nbvertex, int width, int height, float distance, v2d *v2) { int i; for (i=0;i<nbvertex;++i) { if (v3[i].z > 2) { int Xp, Yp; F2I((distance * v3[i].x / v3[i].z),Xp); F2I((distance * v3[i].y / v3[i].z),Yp); v2[i].x = Xp + (width>>1); v2[i].y = -Yp + (height>>1); } else v2[i].x=v2[i].y=-666; } } ��������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/flying_stars_fx.c��������������������������������������������������������0000644�0001750�0001750�00000016664�14647725152�016763� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goom_fx.h" #include "goom_plugin_info.h" #include "goom_tools.h" #include "mathtools.h" /* TODO:-- FAIRE PROPREMENT... BOAH... */ #define NCOL 15 /*static const int colval[] = { 0xfdf6f5, 0xfae4e4, 0xf7d1d1, 0xf3b6b5, 0xefa2a2, 0xec9190, 0xea8282, 0xe87575, 0xe46060, 0xe14b4c, 0xde3b3b, 0xdc2d2f, 0xd92726, 0xd81619, 0xd50c09, 0 }; */ static const int colval[] = { 0x1416181a, 0x1419181a, 0x141f181a, 0x1426181a, 0x142a181a, 0x142f181a, 0x1436181a, 0x142f1819, 0x14261615, 0x13201411, 0x111a100a, 0x0c180508, 0x08100304, 0x00050101, 0x0 }; /* The different modes of the visual FX. * Put this values on fx_mode */ #define FIREWORKS_FX 0 #define RAIN_FX 1 #define FOUNTAIN_FX 2 #define LAST_FX 3 typedef struct _FS_STAR { float x,y; float vx,vy; float ax,ay; float age,vage; } Star; typedef struct _FS_DATA{ int fx_mode; int nbStars; int maxStars; Star *stars; float min_age; float max_age; PluginParam min_age_p; PluginParam max_age_p; PluginParam nbStars_p; PluginParam nbStars_limit_p; PluginParam fx_mode_p; PluginParameters params; } FSData; static void fs_init(VisualFX *_this, PluginInfo *info) { FSData *data; data = (FSData*)malloc(sizeof(FSData)); (void)info; data->fx_mode = FIREWORKS_FX; data->maxStars = 4096; data->stars = (Star*)malloc(data->maxStars * sizeof(Star)); data->nbStars = 0; data->max_age_p = secure_i_param ("Fireworks Smallest Bombs"); IVAL(data->max_age_p) = 80; IMIN(data->max_age_p) = 0; IMAX(data->max_age_p) = 100; ISTEP(data->max_age_p) = 1; data->min_age_p = secure_i_param ("Fireworks Largest Bombs"); IVAL(data->min_age_p) = 99; IMIN(data->min_age_p) = 0; IMAX(data->min_age_p) = 100; ISTEP(data->min_age_p) = 1; data->nbStars_limit_p = secure_i_param ("Max Number of Particules"); IVAL(data->nbStars_limit_p) = 512; IMIN(data->nbStars_limit_p) = 0; IMAX(data->nbStars_limit_p) = data->maxStars; ISTEP(data->nbStars_limit_p) = 64; data->fx_mode_p = secure_i_param ("FX Mode"); IVAL(data->fx_mode_p) = data->fx_mode; IMIN(data->fx_mode_p) = 1; IMAX(data->fx_mode_p) = 3; ISTEP(data->fx_mode_p) = 1; data->nbStars_p = secure_f_feedback ("Number of Particules (% of Max)"); data->params = plugin_parameters ("Particule System", 7); data->params.params[0] = &data->fx_mode_p; data->params.params[1] = &data->nbStars_limit_p; data->params.params[2] = 0; data->params.params[3] = &data->min_age_p; data->params.params[4] = &data->max_age_p; data->params.params[5] = 0; data->params.params[6] = &data->nbStars_p; _this->params = &data->params; _this->fx_data = (void*)data; } static void fs_free(VisualFX *_this) { FSData *data = _this->fx_data; if (data) { free (data->params.params); free (data->stars); free (data); } } /** * Cree une nouvelle 'bombe', c'est a dire une particule appartenant a une fusee d'artifice. */ static void addABomb (FSData *fs, int mx, int my, float radius, float vage, float gravity, PluginInfo *info) { int i = fs->nbStars; float ro; int theta; if (fs->nbStars >= fs->maxStars) return; fs->nbStars++; fs->stars[i].x = mx; fs->stars[i].y = my; ro = radius * (float)goom_irand(info->gRandom,100) / 100.0f; ro *= (float)goom_irand(info->gRandom,100)/100.0f + 1.0f; theta = goom_irand(info->gRandom,256); fs->stars[i].vx = ro * cos256[theta]; fs->stars[i].vy = -0.2f + ro * sin256[theta]; fs->stars[i].ax = 0; fs->stars[i].ay = gravity; fs->stars[i].age = 0; if (vage < fs->min_age) vage=fs->min_age; fs->stars[i].vage = vage; } /** * Met a jour la position et vitesse d'une particule. */ static void updateStar (Star *s) { s->x+=s->vx; s->y+=s->vy; s->vx+=s->ax; s->vy+=s->ay; s->age+=s->vage; } /** * Ajoute de nouvelles particules au moment d'un evenement sonore. */ static void fs_sound_event_occured(VisualFX *_this, PluginInfo *info) { FSData *data = (FSData*)_this->fx_data; int i; int max = (int)((1.0f+info->sound.goomPower)*goom_irand(info->gRandom,150)) + 100; float radius = (1.0f+info->sound.goomPower) * (float)(goom_irand(info->gRandom,150)+50)/300; int mx; int my; float vage, gravity = 0.02f; switch (data->fx_mode) { case FIREWORKS_FX: { double dx,dy; do { mx = goom_irand(info->gRandom,info->screen.width); my = goom_irand(info->gRandom,info->screen.height); dx = (mx - info->screen.width/2); dy = (my - info->screen.height/2); } while (dx*dx + dy*dy < (info->screen.height/2)*(info->screen.height/2)); vage = data->max_age * (1.0f - info->sound.goomPower); } break; case RAIN_FX: mx = goom_irand(info->gRandom,info->screen.width); if (mx > info->screen.width/2) mx = info->screen.width; else mx = 0; my = -(info->screen.height/3)-goom_irand(info->gRandom,info->screen.width/3); radius *= 1.5; vage = 0.002f; break; case FOUNTAIN_FX: my = info->screen.height+2; vage = 0.001f; radius += 1.0f; mx = info->screen.width / 2; gravity = 0.04f; break; default: return; /* my = i R A N D (info->screen.height); vage = 0.01f; */ } radius *= info->screen.height / 200.0f; /* why 200 ? because the FX was developped on 320x200 */ max *= info->screen.height / 200.0f; if (info->sound.timeSinceLastBigGoom < 1) { radius *= 1.5; max *= 2; } for (i=0;i<max;++i) addABomb (data,mx,my,radius,vage,gravity,info); } /** * Main methode of the FX. */ static void fs_apply(VisualFX *_this, Pixel *src, Pixel *dest, PluginInfo *info) { int i; int col; FSData *data = (FSData*)_this->fx_data; (void)src; /* Get the new parameters values */ data->min_age = 1.0f - (float)IVAL(data->min_age_p)/100.0f; data->max_age = 1.0f - (float)IVAL(data->max_age_p)/100.0f; FVAL(data->nbStars_p) = (float)data->nbStars / (float)data->maxStars; data->nbStars_p.change_listener(&data->nbStars_p); data->maxStars = IVAL(data->nbStars_limit_p); data->fx_mode = IVAL(data->fx_mode_p); /* look for events */ if (info->sound.timeSinceLastGoom < 1) { fs_sound_event_occured(_this, info); if (goom_irand(info->gRandom,20)==1) { IVAL(data->fx_mode_p) = goom_irand(info->gRandom,(LAST_FX*3)); data->fx_mode_p.change_listener(&data->fx_mode_p); } } /* update particules */ for (i=0;i<data->nbStars;++i) { updateStar(&data->stars[i]); /* dead particule */ if (data->stars[i].age>=NCOL) continue; /* choose the color of the particule */ col = colval[(int)data->stars[i].age]; /* draws the particule */ info->methods.draw_line(dest,(int)data->stars[i].x,(int)data->stars[i].y, (int)(data->stars[i].x-data->stars[i].vx*6), (int)(data->stars[i].y-data->stars[i].vy*6), col, (int)info->screen.width, (int)info->screen.height); info->methods.draw_line(dest,(int)data->stars[i].x,(int)data->stars[i].y, (int)(data->stars[i].x-data->stars[i].vx*2), (int)(data->stars[i].y-data->stars[i].vy*2), col, (int)info->screen.width, (int)info->screen.height); } /* look for dead particules */ for (i=0;i<data->nbStars;) { if ((data->stars[i].x > info->screen.width + 64) ||((data->stars[i].vy>=0)&&(data->stars[i].y - 16*data->stars[i].vy > info->screen.height)) ||(data->stars[i].x < -64) ||(data->stars[i].age>=NCOL)) { data->stars[i] = data->stars[data->nbStars-1]; data->nbStars--; } else ++i; } } VisualFX flying_star_create(void) { VisualFX vfx = { .init = fs_init, .free = fs_free, .apply = fs_apply, .fx_data = 0 }; return vfx; } ����������������������������������������������������������������������������xine-lib-1.2/src/post/goom/ppc_drawings.s�����������������������������������������������������������0000644�0001750�0001750�00000022103�14647725152�016243� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������; PowerPC optimized drawing methods for Goom ; © 2003 Guillaume Borios ; This Source Code is released under the terms of the General Public License ; Change log : ; 30 May 2003 : File creation ; Section definition : We use a read only code section for the whole file .section __TEXT,__text,regular,pure_instructions ; -------------------------------------------------------------------------------------- ; Single 32b pixel drawing macros ; Usage : ; DRAWMETHOD_XXXX_MACRO *pixelIN, *pixelOUT, COLOR, WR1, WR2, WR3, WR4 ; Only the work registers (WR) can be touched by the macros ; ; Available methods : ; DRAWMETHOD_DFLT_MACRO : Default drawing method (Actually OVRW) ; DRAWMETHOD_PLUS_MACRO : RVB Saturated per channel addition (SLOWEST) ; DRAWMETHOD_HALF_MACRO : 50% Transparency color drawing ; DRAWMETHOD_OVRW_MACRO : Direct COLOR drawing (FASTEST) ; DRAWMETHOD_B_OR_MACRO : Bitwise OR ; DRAWMETHOD_BAND_MACRO : Bitwise AND ; DRAWMETHOD_BXOR_MACRO : Bitwise XOR ; DRAWMETHOD_BNOT_MACRO : Bitwise NOT ; -------------------------------------------------------------------------------------- .macro DRAWMETHOD_OVRW_MACRO stw $2,0($1) ;; *$1 <- $2 .endmacro .macro DRAWMETHOD_B_OR_MACRO lwz $3,0($0) ;; $3 <- *$0 or $3,$3,$2 ;; $3 <- $3 | $2 stw $3,0($1) ;; *$1 <- $3 .endmacro .macro DRAWMETHOD_BAND_MACRO lwz $3,0($0) ;; $3 <- *$0 and $3,$3,$2 ;; $3 <- $3 & $2 stw $3,0($1) ;; *$1 <- $3 .endmacro .macro DRAWMETHOD_BXOR_MACRO lwz $3,0($0) ;; $3 <- *$0 xor $3,$3,$2 ;; $3 <- $3 ^ $2 stw $3,0($1) ;; *$1 <- $3 .endmacro .macro DRAWMETHOD_BNOT_MACRO lwz $3,0($0) ;; $3 <- *$0 nand $3,$3,$3 ;; $3 <- ~$3 stw $3,0($1) ;; *$1 <- $3 .endmacro .macro DRAWMETHOD_PLUS_MACRO lwz $4,0($0) ;; $4 <- *$0 andi. $3,$4,0xFF00 ;; $3 <- $4 & 0x0000FF00 andi. $5,$2,0xFF00 ;; $5 <- $2 & 0x0000FF00 add $3,$3,$5 ;; $3 <- $3 + $5 rlwinm $5,$3,15,0,0 ;; $5 <- 0 | ($3[15] << 15) srawi $5,$5,23 ;; $5 <- $5 >> 23 (algebraic for sign extension) or $3,$3,$5 ;; $3 <- $3 | $5 lis $5,0xFF ;; $5 <- 0x00FF00FF addi $5,$5,0xFF and $4,$4,$5 ;; $4 <- $4 & $5 and $6,$2,$5 ;; $6 <- $2 & $5 add $4,$4,$6 ;; $4 <- $4 + $6 rlwinm $6,$4,7,0,0 ;; $6 <- 0 | ($4[7] << 7) srawi $6,$6,15 ;; $6 <- $6 >> 15 (algebraic for sign extension) rlwinm $5,$4,23,0,0 ;; $5 <- 0 | ($4[23] << 23) srawi $5,$5,31 ;; $5 <- $5 >> 31 (algebraic for sign extension) rlwimi $6,$5,0,24,31 ;; $6[24..31] <- $5[24..31] or $4,$4,$6 ;; $4 <- $4 | $6 rlwimi $4,$3,0,16,23 ;; $4[16..23] <- $3[16..23] stw $4,0($1) ;; *$1 <- $4 .endmacro .macro DRAWMETHOD_HALF_MACRO lwz $4,0($0) ;; $4 <- *$0 andi. $3,$4,0xFF00 ;; $3 <- $4 & 0x0000FF00 andi. $5,$2,0xFF00 ;; $5 <- $2 & 0x0000FF00 add $3,$3,$5 ;; $3 <- $3 + $5 lis $5,0xFF ;; $5 <- 0x00FF00FF addi $5,$5,0xFF and $4,$4,$5 ;; $4 <- $4 & $5 and $5,$2,$5 ;; $5 <- $2 & $5 add $4,$4,$5 ;; $4 <- $4 + $5 srwi $4,$4,1 ;; $4 <- $4 >> 1 rlwimi $4,$3,31,16,23 ;; $4[16..23] <- $3[15..22] stw $4,0($1) ;; *$1 <- $4 .endmacro .macro DRAWMETHOD_DFLT_MACRO DRAWMETHOD_PLUS_MACRO .endmacro ; -------------------------------------------------------------------------------------- ; ************************************************************************************** ; void DRAWMETHOD_PLUS_PPC(unsigned int * buf, unsigned int _col); ; void DRAWMETHOD_PLUS_2_PPC(unsigned * in, unsigned int * out, unsigned int _col); ; ************************************************************************************** .globl _DRAWMETHOD_PLUS_2_PPC .align 3 _DRAWMETHOD_PLUS_2_PPC: DRAWMETHOD_PLUS_MACRO r3,r4,r5,r6,r7,r8,r9 blr ;; return .globl _DRAWMETHOD_PLUS_PPC .align 3 _DRAWMETHOD_PLUS_PPC: DRAWMETHOD_PLUS_MACRO r3,r3,r4,r5,r6,r7,r9 blr ;; return ; ************************************************************************************** ; void DRAWMETHOD_HALF_PPC(unsigned int * buf, unsigned int _col); ; void DRAWMETHOD_HALF_2_PPC(unsigned * in, unsigned int * out, unsigned int _col); ; ************************************************************************************** .globl _DRAWMETHOD_HALF_2_PPC .align 3 _DRAWMETHOD_HALF_2_PPC: DRAWMETHOD_HALF_MACRO r3,r4,r5,r6,r7,r8 blr ;; return .globl _DRAWMETHOD_HALF_PPC .align 3 _DRAWMETHOD_HALF_PPC: DRAWMETHOD_HALF_MACRO r3,r3,r4,r5,r6,r7 blr ;; return ; ************************************************************************************** ; void DRAW_LINE_PPC(unsigned int *data, int x1, int y1, int x2, int y2, unsigned int col, ; unsigned int screenx, unsigned int screeny) ; ************************************************************************************** .globl _DRAW_LINE_PPC .align 3 _DRAW_LINE_PPC: ;; NOT IMPLEMENTED YET blr ;; return ; ************************************************************************************** ; void _ppc_brightness(Pixel * src, Pixel * dest, unsigned int size, unsigned int coeff) ; ************************************************************************************** .const .align 4 vectorZERO: .long 0,0,0,0 .long 0x10101000, 0x10101001, 0x10101002, 0x10101003 .long 0x10101004, 0x10101005, 0x10101006, 0x10101007 .long 0x10101008, 0x10101009, 0x1010100A, 0x1010100B .long 0x1010100C, 0x1010100D, 0x1010100E, 0x1010100F .section __TEXT,__text,regular,pure_instructions .globl _ppc_brightness_G4 .align 3 _ppc_brightness_G4: ;; PowerPC Altivec code srwi r5,r5,2 mtctr r5 ;;vrsave mfspr r11,256 lis r12,0xCFFC mtspr 256,r12 mflr r0 bcl 20,31,"L00000000001$pb" "L00000000001$pb": mflr r10 mtlr r0 addis r9,r10,ha16(vectorZERO-"L00000000001$pb") addi r9,r9,lo16(vectorZERO-"L00000000001$pb") vxor v0,v0,v0 ;; V0 = NULL vector addi r9,r9,16 lvx v10,0,r9 addi r9,r9,16 lvx v11,0,r9 addi r9,r9,16 lvx v12,0,r9 addi r9,r9,16 lvx v13,0,r9 addis r9,r10,ha16(vectortmpwork-"L00000000001$pb") addi r9,r9,lo16(vectortmpwork-"L00000000001$pb") stw r6,0(r9) li r6,8 stw r6,4(r9) lvx v9,0,r9 li r9,128 vspltw v8,v9,0 vspltw v9,v9,1 ;; elt counter li r9,0 lis r7,0x0F01 b L7 .align 4 L7: lvx v1,r9,r3 vperm v4,v1,v0,v10 ;********************* add r10,r9,r3 ;********************* vperm v5,v1,v0,v11 vperm v6,v1,v0,v12 vperm v7,v1,v0,v13 vmulouh v4,v4,v8 ;********************* dst r10,r7,3 ;********************* vmulouh v5,v5,v8 vmulouh v6,v6,v8 vmulouh v7,v7,v8 vsrw v4,v4,v9 vsrw v5,v5,v9 vsrw v6,v6,v9 vsrw v7,v7,v9 vpkuwus v4,v4,v5 vpkuwus v6,v6,v7 vpkuhus v1,v4,v6 stvx v1,r9,r4 addi r9,r9,16 bdnz L7 mtspr 256,r11 blr .globl _ppc_brightness_G5 .align 3 _ppc_brightness_G5: ;; PowerPC Altivec G5 code srwi r5,r5,2 mtctr r5 ;;vrsave mfspr r11,256 lis r12,0xCFFC mtspr 256,r12 mflr r0 bcl 20,31,"L00000000002$pb" "L00000000002$pb": mflr r10 mtlr r0 addis r9,r10,ha16(vectorZERO-"L00000000002$pb") addi r9,r9,lo16(vectorZERO-"L00000000002$pb") vxor v0,v0,v0 ;; V0 = NULL vector addi r9,r9,16 lvx v10,0,r9 addi r9,r9,16 lvx v11,0,r9 addi r9,r9,16 lvx v12,0,r9 addi r9,r9,16 lvx v13,0,r9 addis r9,r10,ha16(vectortmpwork-"L00000000002$pb") addi r9,r9,lo16(vectortmpwork-"L00000000002$pb") stw r6,0(r9) li r6,8 stw r6,4(r9) lvx v9,0,r9 li r9,128 vspltw v8,v9,0 vspltw v9,v9,1 ;; elt counter li r9,0 lis r7,0x0F01 b L6 .align 4 L6: lvx v1,r9,r3 vperm v4,v1,v0,v10 ;********************* add r10,r9,r3 ;********************* vperm v5,v1,v0,v11 vperm v6,v1,v0,v12 vperm v7,v1,v0,v13 vmulouh v4,v4,v8 vmulouh v5,v5,v8 vmulouh v6,v6,v8 vmulouh v7,v7,v8 vsrw v4,v4,v9 vsrw v5,v5,v9 vsrw v6,v6,v9 vsrw v7,v7,v9 vpkuwus v4,v4,v5 vpkuwus v6,v6,v7 vpkuhus v1,v4,v6 stvx v1,r9,r4 addi r9,r9,16 bdnz L6 mtspr 256,r11 blr .globl _ppc_brightness_generic .align 3 _ppc_brightness_generic: lis r12,0x00FF ori r12,r12,0x00FF subi r3,r3,4 subi r4,r4,4 mtctr r5 b L1 .align 4 L1: lwzu r7,4(r3) rlwinm r8,r7,16,24,31 rlwinm r9,r7,24,24,31 mullw r8,r8,r6 rlwinm r10,r7,0,24,31 mullw r9,r9,r6 srwi r8,r8,8 mullw r10,r10,r6 srwi r9,r9,8 rlwinm. r11,r8,0,0,23 beq L2 li r8,0xFF L2: srwi r10,r10,8 rlwinm. r11,r9,0,0,23 beq L3 li r9,0xFF L3: rlwinm r7,r8,16,8,15 rlwinm. r11,r10,0,0,23 beq L4 li r10,0xFF L4: rlwimi r7,r9,8,16,23 rlwimi r7,r10,0,24,31 stwu r7,4(r4) bdnz L1 blr .static_data .align 4 vectortmpwork: .long 0,0,0,0 �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/graphic.c����������������������������������������������������������������0000644�0001750�0001750�00000000542�14647725152�015163� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#include "goom_graphic.h" const Color BLACK = { 0, 0, 0 }; const Color WHITE = { 0xff, 0xff, 0xff }; const Color RED = { 0xff, 0x05, 0x05 }; const Color GREEN = { 0x05, 0xff, 0x05 }; const Color BLUE = { 0x05, 0x05, 0xff }; const Color YELLOW = { 0xff, 0xff, 0x33 }; const Color ORANGE = { 0xff, 0xcc, 0x05 }; const Color VIOLET = { 0x55, 0x05, 0xff }; ��������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/ifs.h��������������������������������������������������������������������0000644�0001750�0001750�00000001212�14647725152�014327� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * File created 11 april 2002 by JeKo <jeko@free.fr> */ #ifndef IFS_H #define IFS_H #include "goom_config.h" #include "goom_graphic.h" #include "goom_plugin_info.h" #include "goom_visual_fx.h" VisualFX ifs_visualfx_create(void); /* init ifs for a (width)x(height) output. * / void init_ifs (PluginInfo *goomInfo, int width, int height); / * draw an ifs on the buffer (which size is width * height) increment means that we draw 1/increment of the ifs's points * / void ifs_update (PluginInfo *goomInfo, Pixel * buffer, Pixel * back, int width, int height, int increment); / * free all ifs's data. * / void release_ifs (void); */ #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_graphic.h�����������������������������������������������������������0000644�0001750�0001750�00000002444�14647725152�016214� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef GRAPHIC_H #define GRAPHIC_H typedef unsigned int Uint; typedef struct { unsigned short r, v, b; } Color; extern const Color BLACK; extern const Color WHITE; extern const Color RED; extern const Color BLUE; extern const Color GREEN; extern const Color YELLOW; extern const Color ORANGE; extern const Color VIOLET; #ifdef COLOR_BGRA #define B_CHANNEL 0xFF000000 #define G_CHANNEL 0x00FF0000 #define R_CHANNEL 0x0000FF00 #define A_CHANNEL 0x000000FF #define B_OFFSET 24 #define G_OFFSET 16 #define R_OFFSET 8 #define A_OFFSET 0 typedef union _PIXEL { struct { unsigned char b; unsigned char g; unsigned char r; unsigned char a; } channels; unsigned int val; unsigned char cop[4]; } Pixel; #else #define A_CHANNEL 0xFF000000 #define R_CHANNEL 0x00FF0000 #define G_CHANNEL 0x0000FF00 #define B_CHANNEL 0x000000FF #define A_OFFSET 24 #define R_OFFSET 16 #define G_OFFSET 8 #define B_OFFSET 0 typedef union _PIXEL { struct { unsigned char a; unsigned char r; unsigned char g; unsigned char b; } channels; unsigned int val; unsigned char cop[4]; } Pixel; #endif /* COLOR_BGRA */ /* inline void setPixelRGB (Pixel * buffer, Uint x, Uint y, Color c); inline void getPixelRGB (Pixel * buffer, Uint x, Uint y, Color * c); */ #endif /* GRAPHIC_H */ ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/diff_against_release.patch�����������������������������������������������0000644�0001750�0001750�00000053064�14647725152�020550� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������diff -ru goom2k4-0/src/filters.c xine-lib/src/post/goom/filters.c --- filters.c 2005-02-07 11:46:41.000000000 -0200 +++ filters.c 2005-07-18 12:15:50.000000000 -0300 @@ -704,7 +704,7 @@ data->general_speed = 0.0f; data->reverse = 0; - data->theMode = AMULETTE_MODE; + data->theMode = rand() % 10; data->waveEffect = 0; data->hypercosEffect = 0; data->vPlaneEffect = 0; Index: filters.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/filters.c,v retrieving revision 1.19 retrieving revision 1.20 diff -u -p -r1.19 -r1.20 --- filters.c 25 Aug 2005 15:36:30 -0000 1.19 +++ filters.c 22 May 2006 16:57:36 -0000 1.20 @@ -740,7 +740,7 @@ static void zoomFilterVisualFXWrapper_ap VisualFX zoomFilterVisualFXWrapper_create(void) { - VisualFX fx; + VisualFX fx = {0}; fx.init = zoomFilterVisualFXWrapper_init; fx.free = zoomFilterVisualFXWrapper_free; fx.apply = zoomFilterVisualFXWrapper_apply; diff -ru goom2k4-0/src/goom_core.c xine-lib/src/post/goom/goom_core.c --- goom_core.c 2005-02-07 11:46:41.000000000 -0200 +++ goom_core.c 2005-07-19 12:39:22.000000000 -0300 @@ -26,6 +26,8 @@ #include "goom_fx.h" #include "goomsl.h" +#include "xine_internal.h" + /* #define VERBOSE */ #define STOP_SPEED 128 @@ -736,7 +738,12 @@ /* affichage et swappage des buffers.. */ goomInfo->cycle++; + /* xine: no convolve_fx */ + /* goomInfo->convolve_fx.apply(&goomInfo->convolve_fx,return_val,goomInfo->outputBuf,goomInfo); + */ + xine_fast_memcpy(goomInfo->outputBuf, return_val, goomInfo->screen.size * sizeof(Pixel)); + return (guint32*)goomInfo->outputBuf; } diff -ru goom2k4-0/src/goom_tools.c xine-lib/src/post/goom/goom_tools.c --- goom_tools.c 2005-02-07 11:46:41.000000000 -0200 +++ goom_tools.c 2005-07-18 14:30:02.000000000 -0300 @@ -3,7 +3,6 @@ GoomRandom *goom_random_init(int i) { GoomRandom *grandom = (GoomRandom*)malloc(sizeof(GoomRandom)); - srand (i); grandom->pos = 1; goom_random_update_array(grandom, GOOM_NB_RAND); return grandom; diff -ru goom2k4-0/src/ifs.c xine-lib/src/post/goom/ifs.c --- ifs.c 2005-02-07 11:46:41.000000000 -0200 +++ ifs.c 2005-07-19 14:20:20.000000000 -0300 @@ -503,6 +503,13 @@ for (i = 0; i < 4; i++) { *tmp = (*tmp) >> cycle10; + + /* xine: make it darker */ + if( *tmp && !((*tmp) >> 1) ) + *tmp = 1; + else + *tmp = (*tmp) >> 1; + tmp++; } } Index: ifs.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/ifs.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -p -r1.11 -r1.12 --- ifs.c 19 Jul 2005 18:10:30 -0000 1.11 +++ ifs.c 22 May 2006 16:57:36 -0000 1.12 @@ -762,7 +762,7 @@ static void ifs_vfx_free(VisualFX *_this } VisualFX ifs_visualfx_create(void) { - VisualFX vfx; + VisualFX vfx = {0}; vfx.init = ifs_vfx_init; vfx.free = ifs_vfx_free; vfx.apply = ifs_vfx_apply; diff -ru goom2k4-0/src/tentacle3d.c xine-lib/src/post/goom/tentacle3d.c --- tentacle3d.c 2005-02-07 11:46:41.000000000 -0200 +++ tentacle3d.c 2005-07-19 14:04:57.000000000 -0300 @@ -10,7 +10,7 @@ #define D 256.0f #define nbgrid 6 -#define definitionx 15 +#define definitionx 9 #define definitionz 45 typedef struct _TENTACLE_FX_DATA { Index: tentacle3d.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/tentacle3d.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -p -r1.5 -r1.6 --- tentacle3d.c 19 Jul 2005 18:10:31 -0000 1.5 +++ tentacle3d.c 22 May 2006 16:57:36 -0000 1.6 @@ -95,7 +95,7 @@ static void tentacle_fx_free(VisualFX *_ } VisualFX tentacle_fx_create(void) { - VisualFX fx; + VisualFX fx = {0}; fx.init = tentacle_fx_init; fx.apply = tentacle_fx_apply; fx.free = tentacle_fx_free; diff -ru goom2k4-0/src/xmmx.c xine-lib/src/post/goom/xmmx.c --- xmmx.c 2005-02-07 11:46:41.000000000 -0200 +++ xmmx.c 2005-07-18 15:26:23.000000000 -0300 @@ -239,7 +239,11 @@ ++loop; } - __asm__ __volatile__ ("femms\n"); +/*#ifdef HAVE_ATHLON*/ + __asm__ __volatile__ ("emms\n"); +/*#else + emms(); +#endif*/ } #define DRAWMETHOD_PLUS_XMMX(_out,_backbuf,_col) \ @@ -387,7 +391,7 @@ } } end_of_line: - __asm__ __volatile__ ("femms\n"); + __asm__ __volatile__ ("emms\n"); } #endif Index: xmmx.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/xmmx.c,v retrieving revision 1.6 diff -u -r1.6 xmmx.c --- xmmx.c 19 Jul 2005 18:10:31 -0000 1.6 +++ xmmx.c 21 Jul 2005 20:48:09 -0000 @@ -50,10 +50,10 @@ ratiox.d[1] = buffratio; asm volatile - ("\n\t movq %[ratio], %%mm6" + ("\n\t movq %0, %%mm6" "\n\t pslld $16, %%mm6" /* mm6 = [rat16=buffratio<<16 | rat16=buffratio<<16] */ "\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */ - ::[ratio]"m"(ratiox)); + ::"m"(ratiox)); loop=0; @@ -69,8 +69,8 @@ */ asm volatile - ("#1 \n\t movq %[brutS], %%mm0" - "#1 \n\t movq %[brutD], %%mm1" + ("#1 \n\t movq %0, %%mm0" + "#1 \n\t movq %1, %%mm1" "#1 \n\t psubd %%mm0, %%mm1" /* mm1 = D - S */ "#1 \n\t movq %%mm1, %%mm2" /* mm2 = D - S */ "#1 \n\t pslld $16, %%mm1" @@ -83,8 +83,8 @@ "#1 \n\t paddd %%mm1, %%mm0" /* mm0 = S + mm1 */ "#1 \n\t psrld $16, %%mm0" : - : [brutS]"g"(brutS[loop]) - , [brutD]"g"(brutD[loop]) + : "g"(brutS[loop]) + , "g"(brutD[loop]) ); /* mm0 = S */ /* @@ -94,7 +94,7 @@ * modified : mm0,mm1,mm2 */ asm volatile - ("#1 \n\t movq %[prevXY], %%mm1" + ("#1 \n\t movq %0, %%mm1" "#1 \n\t pcmpgtd %%mm0, %%mm1" /* mm0 en X contient (idem pour Y) : * 1111 si prevXY > px @@ -107,7 +107,7 @@ #endif "#1 \n\t pand %%mm1, %%mm0" /* on met a zero la partie qui deborde */ - ::[prevXY]"m"(prevXY)); + ::"m"(prevXY)); /* Thread #2 * pre : mm0 : clipped position on screen @@ -127,11 +127,11 @@ "#2 \n\t shll $6,%%esi" "#2 \n\t movd %%mm1,%%eax" - "#2 \n\t addl %[precalCoef],%%esi" + "#2 \n\t addl %0,%%esi" "#2 \n\t andl $15,%%eax" "#2 \n\t movd (%%esi,%%eax,4),%%mm3" - ::[precalCoef]"g"(precalCoef):"eax","esi"); + ::"g"(precalCoef):"eax","esi"); /* * extraction des coefficients... (Thread #3) @@ -160,7 +160,7 @@ "#4 \n\t movd %%mm1,%%eax" "#3 \n\t movq %%mm3,%%mm5" - "#4 \n\t mull %[prevX]" + "#4 \n\t mull %1" "#4 \n\t movd %%mm0,%%esi" "#3 \n\t punpcklbw %%mm5, %%mm3" @@ -169,18 +169,18 @@ "#3 \n\t movq %%mm3, %%mm4" "#3 \n\t movq %%mm3, %%mm5" - "#4 \n\t movl %[expix1], %%esi" + "#4 \n\t movl %0, %%esi" "#3 \n\t punpcklbw %%mm5, %%mm3" "#4 \n\t movq (%%esi,%%eax,4),%%mm0" "#3 \n\t punpckhbw %%mm5, %%mm4" - "#4 \n\t addl %[prevX],%%eax" + "#4 \n\t addl %1,%%eax" "#4 \n\t movq (%%esi,%%eax,4),%%mm2" : - : [expix1] "g"(expix1) - , [prevX] "g"(prevX) + : "g"(expix1) + , "g"(prevX) :"eax","esi" ); Index: convolve_fx.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/convolve_fx.c,v retrieving revision 1.4 diff -u -r1.4 convolve_fx.c --- convolve_fx.c 19 Jul 2005 18:10:29 -0000 1.4 +++ convolve_fx.c 22 Jul 2005 16:37:15 -0000 @@ -172,7 +172,7 @@ { __asm__ __volatile__ ( - "\n\t movd %[src], %%mm0" /* mm0 = src */ + "\n\t movd %1, %%mm0" /* mm0 = src */ "\n\t paddd %%mm4, %%mm2" /* [ ytex | xtex ] += [ -s | s ] */ "\n\t movd %%esi, %%mm5" /* save esi into mm5 */ "\n\t movq %%mm2, %%mm3" @@ -190,7 +190,7 @@ "\n\t xorl %%ecx, %%ecx" "\n\t movb (%%eax,%%esi), %%cl" - "\n\t movl %[ifftab], %%eax" + "\n\t movl %2, %%eax" "\n\t movd %%mm5, %%esi" /* restore esi from mm5 */ "\n\t movd (%%eax,%%ecx,4), %%mm1" /* mm1 = [0|0|0|iff2] */ @@ -202,10 +202,10 @@ "\n\t pmullw %%mm1, %%mm0" "\n\t psrlw $5, %%mm0" "\n\t packuswb %%mm7, %%mm0" - "\n\t movd %%mm0, %[dest]" - : [dest] "=g" (dest[i].val) - : [src] "g" (src[i].val) - , [ifftab]"g"(&ifftab[0]) + "\n\t movd %%mm0, %0" + : "=g" (dest[i].val) + : "g" (src[i].val) + , "g"(&ifftab[0]) : "eax","ecx"); i++; Index: convolve_fx.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/convolve_fx.c,v retrieving revision 1.5 diff -u -r1.5 convolve_fx.c --- convolve_fx.c 22 Jul 2005 16:37:44 -0000 1.5 +++ convolve_fx.c 22 Jul 2005 16:41:19 -0000 @@ -154,19 +154,19 @@ #ifdef HAVE_MMX __asm__ __volatile__ ("\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */ - "\n\t movd %[xtex], %%mm2" - "\n\t movd %[ytex], %%mm3" + "\n\t movd %0, %%mm2" + "\n\t movd %1, %%mm3" "\n\t punpckldq %%mm3, %%mm2" /* mm2 = [ ytex | xtex ] */ - "\n\t movd %[c], %%mm4" - "\n\t movd %[s], %%mm6" + "\n\t movd %2, %%mm4" + "\n\t movd %3, %%mm6" "\n\t pxor %%mm5, %%mm5" "\n\t psubd %%mm6, %%mm5" "\n\t punpckldq %%mm5, %%mm4" /* mm4 = [ -s | c ] */ - "\n\t movd %[motif], %%mm6" /* mm6 = motif */ + "\n\t movd %4, %%mm6" /* mm6 = motif */ - ::[xtex]"g"(xtex) ,[ytex]"g"(ytex) - , [c]"g"(c), [s]"g"(s) - , [motif] "g"(&data->conv_motif[0][0])); + ::"g"(xtex) ,"g"(ytex) + , "g"(c), "g"(s) + , "g"(&data->conv_motif[0][0])); for (x=info->screen.width;x--;) { Index: goom_core.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/goom_core.c,v retrieving revision 1.13 diff -u -p -r1.13 goom_core.c --- goom_core.c 19 Jul 2005 18:10:30 -0000 1.13 +++ goom_core.c 27 Jul 2005 20:28:29 -0000 @@ -35,18 +35,18 @@ #define TIME_BTW_CHG 300 static void choose_a_goom_line (PluginInfo *goomInfo, float *param1, float *param2, int *couleur, - int *mode, float *amplitude, int far); + int *mode, float *amplitude, int isfar); static void update_message (PluginInfo *goomInfo, char *message); static void init_buffers(PluginInfo *goomInfo, int buffsize) { goomInfo->pixel = (guint32 *) malloc (buffsize * sizeof (guint32) + 128); - bzero (goomInfo->pixel, buffsize * sizeof (guint32) + 128); + memset (goomInfo->pixel, 0, buffsize * sizeof (guint32) + 128); goomInfo->back = (guint32 *) malloc (buffsize * sizeof (guint32) + 128); - bzero (goomInfo->back, buffsize * sizeof (guint32) + 128); + memset (goomInfo->back, 0, buffsize * sizeof (guint32) + 128); goomInfo->conv = (Pixel *) malloc (buffsize * sizeof (guint32) + 128); - bzero (goomInfo->conv, buffsize * sizeof (guint32) + 128); + memset (goomInfo->conv, 0, buffsize * sizeof (guint32) + 128); goomInfo->outputBuf = goomInfo->conv; @@ -780,13 +780,13 @@ void goom_close (PluginInfo *goomInfo) /* *** */ void choose_a_goom_line (PluginInfo *goomInfo, float *param1, float *param2, int *couleur, int *mode, - float *amplitude, int far) + float *amplitude, int isfar) { *mode = goom_irand(goomInfo->gRandom,3); *amplitude = 1.0f; switch (*mode) { case GML_CIRCLE: - if (far) { + if (isfar) { *param1 = *param2 = 0.47f; *amplitude = 0.8f; break; @@ -804,7 +804,7 @@ choose_a_goom_line (PluginInfo *goomInfo } break; case GML_HLINE: - if (goom_irand(goomInfo->gRandom,4) || far) { + if (goom_irand(goomInfo->gRandom,4) || isfar) { *param1 = goomInfo->screen.height / 7; *param2 = 6.0f * goomInfo->screen.height / 7.0f; } @@ -814,7 +814,7 @@ choose_a_goom_line (PluginInfo *goomInfo } break; case GML_VLINE: - if (goom_irand(goomInfo->gRandom,3) || far) { + if (goom_irand(goomInfo->gRandom,3) || isfar) { *param1 = goomInfo->screen.width / 7.0f; *param2 = 6.0f * goomInfo->screen.width / 7.0f; } --- filters.c.orig 2005-08-20 12:29:12.000000000 +0200 +++ filters.c 2005-08-20 12:28:25.000000000 +0200 @@ -201,8 +201,8 @@ static inline v2g zoomVector(ZoomFilterF /* Noise */ if (data->noisify) { - vx += (((float)random()) / ((float)RAND_MAX) - 0.5f) / 50.0f; - vy += (((float)random()) / ((float)RAND_MAX) - 0.5f) / 50.0f; + vx += (((float)rand()) / ((float)RAND_MAX) - 0.5f) / 50.0f; + vy += (((float)rand()) / ((float)RAND_MAX) - 0.5f) / 50.0f; } /* Hypercos */ diff -r -u xine-lib-1.1.0-orig/src/post/goom/convolve_fx.c xine-lib-1.1.0/src/post/goom/convolve_fx.c --- convolve_fx.c 2005-07-22 12:42:00.000000000 -0400 +++ convolve_fx.c 2005-11-11 14:59:39.925112333 -0500 @@ -151,7 +155,8 @@ ytex = yprime + yi + CONV_MOTIF_W * 0x10000 / 2; yprime += c; -#ifdef HAVE_MMX +#if defined(HAVE_MMX) && ! defined(ARCH_X86_64) +/* This code uses 32-bit registers eax,ecx,esi */ __asm__ __volatile__ ("\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */ "\n\t movd %0, %%mm2" diff -r -u xine-lib-1.1.0-orig/src/post/goom/mmx.c xine-lib-1.1.0/src/post/goom/mmx.c --- mmx.c 2004-07-21 10:38:30.000000000 -0400 +++ mmx.c 2005-11-11 14:51:52.890358793 -0500 @@ -4,6 +4,7 @@ #define BUFFPOINTMASK 0xffff #define BUFFINCR 0xff +#include <stddef.h> #include "mmx.h" #include "goom_graphic.h" @@ -23,6 +24,7 @@ int precalCoef[16][16]) { unsigned int ax = (prevX-1)<<PERTEDEC, ay = (prevY-1)<<PERTEDEC; + size_t sizeX = prevX; int bufsize = prevX * prevY; int loop; @@ -33,7 +35,7 @@ { /* int couleur; */ int px,py; - int pos; + size_t pos; int coeffs; int myPos = loop << 1, @@ -91,7 +93,7 @@ "punpckhbw %%mm7, %%mm5 \n\t" /* 00-c4-00-c4-00-c4-00-c4 */ /* ajouter la longueur de ligne a esi */ - "addl 8(%%ebp),%1 \n\t" + "add %4,%1 \n\t" /* recuperation des 2 derniers pixels */ "movq (%3,%1,4), %%mm1 \n\t" @@ -114,8 +116,8 @@ "packuswb %%mm7, %%mm0 \n\t" "movd %%mm0,%0 \n\t" - :"=g"(expix2[loop]) - :"r"(pos),"r"(coeffs),"r"(expix1) + :"=g"(expix2[loop]),"+r"(pos) + :"r"(coeffs),"r"(expix1),"g"(sizeX) ); diff -r -u xine-lib-1.1.0-orig/src/post/goom/mmx.h xine-lib-1.1.0/src/post/goom/mmx.h --- mmx.h 2005-07-19 14:10:30.000000000 -0400 +++ mmx.h 2005-11-11 14:51:52.890358793 -0500 @@ -27,6 +27,10 @@ #ifndef _MMX_H #define _MMX_H +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "goom_graphic.h" /* Warning: at this writing, the version of GAS packaged @@ -69,6 +73,9 @@ 13 if AMD Extended MMX, &3dNow supported 0 if hardware does not support any of these */ +#ifdef ARCH_X86_64 + return 13; +#else register int rval = 0; __asm__ __volatile__ ( @@ -223,6 +230,7 @@ /* Return */ return(rval); +#endif } /* Function to test if mmx instructions are supported... diff -r -u xine-lib-1.1.0-orig/src/post/goom/xmmx.c xine-lib-1.1.0/src/post/goom/xmmx.c --- xmmx.c 2005-07-21 16:48:37.000000000 -0400 +++ xmmx.c 2005-11-11 14:51:52.890358793 -0500 @@ -23,7 +23,12 @@ #include "goom_graphic.h" int xmmx_supported (void) { +#ifdef ARCH_X86_64 + return 0; /* Haven't yet converted zoom_filter_xmmx + to support 64-bit memory index registers (rsi,rax) */ +#else return (mm_support()&0x8)>>3; +#endif } void zoom_filter_xmmx (int prevX, int prevY, @@ -31,6 +36,7 @@ int *lbruS, int *lbruD, int buffratio, int precalCoef[16][16]) { +#ifndef ARCH_X86_64 int bufsize = prevX * prevY; /* taille du buffer */ volatile int loop; /* variable de boucle */ @@ -244,6 +250,7 @@ /*#else emms(); #endif*/ +#endif /* ARCH_X86_64 */ } #define DRAWMETHOD_PLUS_XMMX(_out,_backbuf,_col) \ Index: goom_config.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/goom_config.h,v retrieving revision 1.9 diff -u -p -r1.9 goom_config.h --- goom_config.h 21 Nov 2004 15:10:40 -0000 1.9 +++ goom_config.h 8 Apr 2006 15:35:01 -0000 @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #if WORDS_BIGENDIAN #define COLOR_ARGB #else Index: gfontlib.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/gfontlib.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -p -r1.4 -r1.5 --- gfontlib.c 21 Jul 2004 14:38:29 -0000 1.4 +++ gfontlib.c 4 May 2006 20:50:55 -0000 1.5 @@ -1,5 +1,5 @@ #include "goom_config.h" -#include "gfontrle.h" +#include "gfontrle.c" #include "gfontlib.h" #include <string.h> #include <stdlib.h> Index: gfontrle.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/gfontrle.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -p -r1.4 -r1.5 --- gfontrle.c 4 May 2006 18:10:40 -0000 1.4 +++ gfontrle.c 4 May 2006 20:50:55 -0000 1.5 @@ -1,6 +1,6 @@ /* RGBA C-Source image dump (with zRLE compression) */ -const struct { +static const struct { unsigned int width; unsigned int height; unsigned int bytes_per_pixel; --- gfontrle.h Sun Jun 11 17:22:15 2006 1.2 +++ gfontrle.h Sun Jun 11 17:22:15 2006 @@ -1,7 +0,0 @@ -extern const struct { - unsigned int width; - unsigned int height; - unsigned int bytes_per_pixel; - unsigned int rle_size; - unsigned char rle_pixel [49725]; -} the_font ; Index: goomsl_heap.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/goomsl_heap.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- goomsl_heap.c 19 Jul 2005 18:10:30 -0000 1.1 +++ goomsl_heap.c 7 Jun 2006 22:52:29 -0000 1.2 @@ -39,7 +39,7 @@ static void align_it(GoomHeap *_this, in { if ((alignment > 1) && (_this->number_of_arrays>0)) { void *last_array = _this->arrays[_this->number_of_arrays - 1]; - int last_address = (int)last_array + _this->consumed_in_last_array; + long last_address = (long)last_array + _this->consumed_in_last_array; int decal = (last_address % alignment); if (decal != 0) { _this->consumed_in_last_array += alignment - decal; Index: mathtools.c =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/mathtools.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -p -r1.1 -r1.2 --- mathtools.c 27 Jun 2004 11:58:47 -0000 1.1 +++ mathtools.c 2 Jun 2006 22:13:45 -0000 1.2 @@ -8,9 +8,7 @@ */ /*---------------------------------------------------------------------------*/ -#include "mathtools.h" - -float sin256[256] = { +static const float sin256[256] = { 0,0.0245412,0.0490677,0.0735646,0.0980171,0.122411,0.14673,0.170962 ,0.19509,0.219101,0.24298,0.266713,0.290285,0.313682,0.33689,0.359895 ,0.382683,0.405241,0.427555,0.449611,0.471397,0.492898,0.514103,0.534998 @@ -46,7 +44,7 @@ float sin256[256] = { }; -float cos256[256] = { +static const float cos256[256] = { 0,0.999699,0.998795,0.99729,0.995185,0.99248,0.989177,0.985278 ,0.980785,0.975702,0.970031,0.963776,0.95694,0.949528,0.941544,0.932993 ,0.92388,0.91421,0.903989,0.893224,0.881921,0.870087,0.857729,0.844854 Index: mathtools.h =================================================================== RCS file: /cvsroot/xine/xine-lib/src/post/goom/mathtools.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -p -r1.2 -r1.3 --- mathtools.h 27 Jun 2004 11:58:47 -0000 1.2 +++ mathtools.h 2 Jun 2006 22:13:45 -0000 1.3 @@ -29,8 +29,7 @@ #define SINCOS(f,s,c) {s=sin(f);c=cos(f);} #endif -extern float sin256[256]; -extern float cos256[256]; +#include "mathtools.c" #endif diff -r 96c7f8460d61 src/post/goom/convolve_fx.c --- convolve_fx.c Mon Nov 10 16:33:51 2008 +0100 +++ convolve_fx.c Sun Nov 16 21:14:29 2008 +0100 @@ -73,7 +73,7 @@ static void set_motif(ConvData *data, Mo static void convolve_init(VisualFX *_this, PluginInfo *info) { ConvData *data; - data = (ConvData*)malloc(sizeof(ConvData)); + data = (ConvData*)calloc(1, sizeof(ConvData)); _this->fx_data = (void*)data; data->light = secure_f_param("Screen Brightness"); diff -r 96c7f8460d61 src/post/goom/goom_core.c --- goom_core.c Mon Nov 10 16:33:51 2008 +0100 +++ goom_core.c Sun Nov 16 21:14:29 2008 +0100 @@ -76,6 +76,10 @@ PluginInfo *goom_init (guint32 resx, gui goomInfo->tentacles_fx = tentacle_fx_create(); goomInfo->tentacles_fx.init(&goomInfo->tentacles_fx, goomInfo); + goomInfo->screen.width = resx; + goomInfo->screen.height = resy; + goomInfo->screen.size = resx * resy; + goomInfo->convolve_fx = convolve_create(); goomInfo->convolve_fx.init(&goomInfo->convolve_fx, goomInfo); @@ -83,10 +87,6 @@ PluginInfo *goom_init (guint32 resx, gui plugin_info_add_visual (goomInfo, 1, &goomInfo->tentacles_fx); plugin_info_add_visual (goomInfo, 2, &goomInfo->star_fx); plugin_info_add_visual (goomInfo, 3, &goomInfo->convolve_fx); - - goomInfo->screen.width = resx; - goomInfo->screen.height = resy; - goomInfo->screen.size = resx * resy; init_buffers(goomInfo, goomInfo->screen.size); goomInfo->gRandom = goom_random_init((uintptr_t)goomInfo->pixel); ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/cpu_info.h���������������������������������������������������������������0000644�0001750�0001750�00000001176�14647725152�015361� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef CPU_INFO_H #define CPU_INFO_H /* * cpu_info.h * Goom * * Created by Guillaume Borios on Sun Dec 28 2003. * Copyright (c) 2003 iOS. All rights reserved. * */ #ifdef HAVE_MMX #ifndef CPU_X86 #define CPU_X86 #endif #endif /* Returns the CPU flavour described with the constants below */ unsigned int cpu_flavour (void); #define CPU_OPTION_ALTIVEC 0x1 #define CPU_OPTION_64_BITS 0x2 #define CPU_OPTION_MMX 0x4 #define CPU_OPTION_XMMX 0x8 #define CPU_OPTION_SSE 0x10 #define CPU_OPTION_SSE2 0x20 #define CPU_OPTION_3DNOW 0x40 /* Returns the CPU number */ unsigned int cpu_number (void); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_typedefs.h����������������������������������������������������������0000644�0001750�0001750�00000000452�14647725152�016417� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GOOM_TYPEDEFS_H #define _GOOM_TYPEDEFS_H typedef struct _PLUGIN_INFO PluginInfo; typedef struct _SOUND_INFO SoundInfo; typedef struct _GMLINE GMLine; typedef struct _GMUNITPOINTER GMUnitPointer; typedef struct _ZOOM_FILTER_DATA ZoomFilterData; typedef struct _VISUAL_FX VisualFX; #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/surf3d.h�����������������������������������������������������������������0000644�0001750�0001750�00000001462�14647725152�014763� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _SURF3D_H #define _SURF3D_H #include "v3d.h" #include "goom_graphic.h" #include "goom_typedefs.h" typedef struct { v3d *vertex; v3d *svertex; int nbvertex; v3d center; } surf3d; typedef struct { surf3d surf; int defx; int sizex; int defz; int sizez; int mode; } grid3d; /* hi-level */ /* works on grid3d */ grid3d *grid3d_new (int sizex, int defx, int sizez, int defz, v3d center); void grid3d_free (grid3d *); void grid3d_update (grid3d *s, float angle, float *vals, float dist); /* low level */ void surf3d_draw (surf3d *s, int color, int dist, int *buf, int *back, int W,int H); void grid3d_draw (PluginInfo *plug, grid3d *g, int color, int colorlow, int dist, Pixel *buf, Pixel *back, int W,int H); void surf3d_rotate (surf3d *s, float angle); void surf3d_translate (surf3d *s); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/filters.c����������������������������������������������������������������0000644�0001750�0001750�00000060655�14647725152�015231� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������// --- CHUI EN TRAIN DE SUPPRIMER LES EXTERN RESOLX ET C_RESOLY --- /* filter.c version 0.7 * contient les filtres applicable a un buffer * creation : 01/10/2000 * -ajout de sinFilter() * -ajout de zoomFilter() * -copie de zoomFilter() en zoomFilterRGB(), gerant les 3 couleurs * -optimisation de sinFilter (utilisant une table de sin) * -asm * -optimisation de la procedure de generation du buffer de transformation * la vitesse est maintenant comprise dans [0..128] au lieu de [0..100] */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* #define _DEBUG_PIXEL */ #include <string.h> #include <stdlib.h> #include <math.h> #include <stdio.h> #include <inttypes.h> #include "goom_filters.h" #include "goom_graphic.h" #include "goom_tools.h" #include "goom_plugin_info.h" #include "goom_fx.h" #include "v3d.h" /* TODO : MOVE THIS AWAY !!! */ /* jeko: j'ai essayer de le virer, mais si on veut les laisser inline c'est un peu lourdo... */ static inline void setPixelRGB (PluginInfo *goomInfo, Pixel *buffer, Uint x, Uint y, Color c) { Pixel i; i.channels.b = c.b; i.channels.g = c.v; i.channels.r = c.r; *(buffer + (x + y * goomInfo->screen.width)) = i; } static inline void setPixelRGB_ (Pixel *buffer, Uint x, Color c) { buffer[x].channels.r = c.r; buffer[x].channels.g = c.v; buffer[x].channels.b = c.b; } static inline void getPixelRGB (PluginInfo *goomInfo, Pixel *buffer, Uint x, Uint y, Color * c) { Pixel i = *(buffer + (x + y * goomInfo->screen.width)); c->b = i.channels.b; c->v = i.channels.g; c->r = i.channels.r; } static inline void getPixelRGB_ (Pixel *buffer, Uint x, Color * c) { Pixel i = *(buffer + x); c->b = i.channels.b; c->v = i.channels.g; c->r = i.channels.r; } /* END TODO */ /* DEPRECATED */ // retourne x>>s , en testant le signe de x //#define ShiftRight(_x,_s) (((_x)<0) ? -(-(_x)>>(_s)) : ((_x)>>(_s))) //#define EFFECT_DISTORS 4 //#define EFFECT_DISTORS_SL 2 //#define INTERLACE_ADD 9 //#define INTERLACE_AND 0xf /* END DEPRECATED */ #define BUFFPOINTNB 16 #define BUFFPOINTNBF 16.0f #define BUFFPOINTMASK 0xffff #define sqrtperte 16 /* faire : a % sqrtperte <=> a & pertemask */ #define PERTEMASK 0xf /* faire : a / sqrtperte <=> a >> PERTEDEC */ #define PERTEDEC 4 /* pure c version of the zoom filter */ static void c_zoom (Pixel *expix1, Pixel *expix2, unsigned int prevX, unsigned int prevY, signed int *brutS, signed int *brutD, int buffratio, int precalCoef[BUFFPOINTNB][BUFFPOINTNB]); /* simple wrapper to give it the same proto than the others */ void zoom_filter_c (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]) { c_zoom(src, dest, sizeX, sizeY, brutS, brutD, buffratio, precalCoef); } static void generatePrecalCoef (int precalCoef[BUFFPOINTNB][BUFFPOINTNB]); typedef struct _ZOOM_FILTER_FX_WRAPPER_DATA { PluginParam enabled_bp; PluginParameters params; unsigned int *coeffs, *freecoeffs; signed int *brutS, *freebrutS; /* source */ signed int *brutD, *freebrutD; /* dest */ signed int *brutT, *freebrutT; /* temp (en cours de generation) */ guint32 zoom_width; unsigned int prevX, prevY; float general_speed; int reverse; /* reverse the speed */ char theMode; int waveEffect; int hypercosEffect; int vPlaneEffect; int hPlaneEffect; char noisify; int middleX, middleY; int mustInitBuffers; int interlace_start; /** modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */ int buffratio; int *firedec; /** modif d'optim by Jeko : precalcul des 4 coefs resultant des 2 pos */ int precalCoef[BUFFPOINTNB][BUFFPOINTNB]; /** calculatePXandPY statics */ int wave; int wavesp; } ZoomFilterFXWrapperData; static inline v2g zoomVector(ZoomFilterFXWrapperData *data, float X, float Y) { v2g vecteur; float vx, vy; float sq_dist = X*X + Y*Y; /* sx = (X < 0.0f) ? -1.0f : 1.0f; sy = (Y < 0.0f) ? -1.0f : 1.0f; */ float coefVitesse = (1.0f+ data->general_speed) / 50.0f; // Effects /* Centralized FX */ switch (data->theMode) { case CRYSTAL_BALL_MODE: coefVitesse -= (sq_dist-0.3f)/15.0f; break; case AMULETTE_MODE: coefVitesse += sq_dist * 3.5f; break; case WAVE_MODE: coefVitesse += sin(sq_dist*20.0f) / 100.0f; break; case SCRUNCH_MODE: coefVitesse += sq_dist / 10.0f; break; //case HYPERCOS1_MODE: break; //case HYPERCOS2_MODE: break; //case YONLY_MODE: break; case SPEEDWAY_MODE: coefVitesse *= 4.0f * Y; break; default: break; } if (coefVitesse < -2.01f) coefVitesse = -2.01f; if (coefVitesse > 2.01f) coefVitesse = 2.01f; vx = coefVitesse * X; vy = coefVitesse * Y; /* Amulette 2 */ // vx = X * tan(dist); // vy = Y * tan(dist); /* Rotate */ //vx = (X+Y)*0.1; //vy = (Y-X)*0.1; // Effects adds-on /* Noise */ if (data->noisify) { vx += (((float)rand()) / ((float)RAND_MAX) - 0.5f) / 50.0f; vy += (((float)rand()) / ((float)RAND_MAX) - 0.5f) / 50.0f; } /* Hypercos */ if (data->hypercosEffect) { vx += sin(Y*10.0f)/120.0f; vy += sin(X*10.0f)/120.0f; } /* H Plane */ if (data->hPlaneEffect) vx += Y * 0.0025f * data->hPlaneEffect; /* V Plane */ if (data->vPlaneEffect) vy += X * 0.0025f * data->vPlaneEffect; /* TODO : Water Mode */ // if (data->waveEffect) vecteur.x = vx; vecteur.y = vy; return vecteur; } /* * Makes a stripe of a transform buffer (brutT) * * The transform is (in order) : * Translation (-data->middleX, -data->middleY) * Homothetie (Center : 0,0 Coeff : 2/data->prevX) */ static void makeZoomBufferStripe(ZoomFilterFXWrapperData * data, int INTERLACE_INCR) { // Position of the pixel to compute in pixmap coordinates Uint x, y; // Where (verticaly) to stop generating the buffer stripe int maxEnd = (data->interlace_start + INTERLACE_INCR); // Ratio from pixmap to normalized coordinates float ratio = 2.0f/((float)data->prevX); // Ratio from normalized to virtual pixmap coordinates float inv_ratio = BUFFPOINTNBF/ratio; float min = ratio/BUFFPOINTNBF; // Y position of the pixel to compute in normalized coordinates float Y = ((float)(data->interlace_start - data->middleY)) * ratio; maxEnd = data->prevY; if (maxEnd > (data->interlace_start + INTERLACE_INCR)) maxEnd = (data->interlace_start + INTERLACE_INCR); for (y = data->interlace_start; (y < data->prevY) && ((signed int)y<maxEnd); y++) { Uint premul_y_prevX = y * data->prevX * 2; float X = - ((float)data->middleX) * ratio; for (x = 0; x < data->prevX; x++) { v2g vector = zoomVector (data, X, Y); /* Finish and avoid null displacement */ if (fabs(vector.x) < min) vector.x = (vector.x < 0.0f) ? -min : min; if (fabs(vector.y) < min) vector.y = (vector.y < 0.0f) ? -min : min; data->brutT[premul_y_prevX] = ((int)((X-vector.x)*inv_ratio)+((int)(data->middleX*BUFFPOINTNB))); data->brutT[premul_y_prevX+1] = ((int)((Y-vector.y)*inv_ratio)+((int)(data->middleY*BUFFPOINTNB))); premul_y_prevX += 2; X += ratio; } Y += ratio; } data->interlace_start += INTERLACE_INCR; if (y >= data->prevY-1) data->interlace_start = -1; } /* * calculer px et py en fonction de x,y,middleX,middleY et theMode * px et py indique la nouvelle position (en sqrtperte ieme de pixel) * (valeur * 16) inline void calculatePXandPY (PluginInfo *goomInfo, ZoomFilterFXWrapperData *data, int x, int y, int *px, int *py) { if (data->theMode == WATER_MODE) { int yy; yy = y + goom_irand(goomInfo->gRandom, 4) - goom_irand(goomInfo->gRandom, 4) + data->wave / 10; if (yy < 0) yy = 0; if (yy >= (signed int)goomInfo->screen.height) yy = goomInfo->screen.height - 1; *px = (x << 4) + data->firedec[yy] + (data->wave / 10); *py = (y << 4) + 132 - ((data->vitesse < 131) ? data->vitesse : 130); data->wavesp += goom_irand(goomInfo->gRandom, 3) - goom_irand(goomInfo->gRandom, 3); if (data->wave < -10) data->wavesp += 2; if (data->wave > 10) data->wavesp -= 2; data->wave += (data->wavesp / 10) + goom_irand(goomInfo->gRandom, 3) - goom_irand(goomInfo->gRandom, 3); if (data->wavesp > 100) data->wavesp = (data->wavesp * 9) / 10; } else { int dist = 0, vx9, vy9; int vx, vy; int ppx, ppy; int fvitesse = data->vitesse << 4; if (data->noisify) { x += goom_irand(goomInfo->gRandom, data->noisify) - goom_irand(goomInfo->gRandom, data->noisify); y += goom_irand(goomInfo->gRandom, data->noisify) - goom_irand(goomInfo->gRandom, data->noisify); } vx = (x - data->middleX) << 9; vy = (y - data->middleY) << 9; if (data->hPlaneEffect) vx += data->hPlaneEffect * (y - data->middleY); if (data->vPlaneEffect) vy += data->vPlaneEffect * (x - data->middleX); if (data->waveEffect) { fvitesse *= 1024 + ShiftRight (goomInfo->sintable [(unsigned short) (dist * 0xffff + EFFECT_DISTORS)], 6); fvitesse /= 1024; } if (data->hypercosEffect) { vx += ShiftRight (goomInfo->sintable[(-vy + dist) & 0xffff], 1); vy += ShiftRight (goomInfo->sintable[(vx + dist) & 0xffff], 1); } vx9 = ShiftRight (vx, 9); vy9 = ShiftRight (vy, 9); dist = vx9 * vx9 + vy9 * vy9; switch (data->theMode) { case WAVE_MODE: fvitesse *= 1024 + ShiftRight (goomInfo->sintable [(unsigned short) (dist * 0xffff * EFFECT_DISTORS)], 6); fvitesse>>=10; break; case CRYSTAL_BALL_MODE: fvitesse += (dist >> (10-EFFECT_DISTORS_SL)); break; case AMULETTE_MODE: fvitesse -= (dist >> (4 - EFFECT_DISTORS_SL)); break; case SCRUNCH_MODE: fvitesse -= (dist >> (10 - EFFECT_DISTORS_SL)); break; case HYPERCOS1_MODE: vx = vx + ShiftRight (goomInfo->sintable[(-vy + dist) & 0xffff], 1); vy = vy + ShiftRight (goomInfo->sintable[(vx + dist) & 0xffff], 1); break; case HYPERCOS2_MODE: vx = vx + ShiftRight (goomInfo->sintable[(-ShiftRight (vy, 1) + dist) & 0xffff], 0); vy = vy + ShiftRight (goomInfo->sintable[(ShiftRight (vx, 1) + dist) & 0xffff], 0); fvitesse = 128 << 4; break; case YONLY_MODE: fvitesse *= 1024 + ShiftRight (goomInfo->sintable[vy & 0xffff], 6); fvitesse >>= 10; break; case SPEEDWAY_MODE: fvitesse -= (ShiftRight(vy,10-EFFECT_DISTORS_SL)); break; } if (fvitesse < -3024) fvitesse = -3024; if (vx < 0) // pb avec decalage sur nb negatif ppx = -(-(vx * fvitesse) >> 16); // 16 = 9 + 7 (7 = nb chiffre virgule de vitesse * (v = 128 => immobile) // * * * * * 9 = nb chiffre virgule de vx) else ppx = ((vx * fvitesse) >> 16); if (vy < 0) ppy = -(-(vy * fvitesse) >> 16); else ppy = ((vy * fvitesse) >> 16); *px = (data->middleX << 4) + ppx; *py = (data->middleY << 4) + ppy; } } */ static void c_zoom (Pixel *expix1, Pixel *expix2, unsigned int prevX, unsigned int prevY, signed int *brutS, signed int *brutD, int buffratio, int precalCoef[16][16]) { int myPos, myPos2; Color couleur; unsigned int ax = (prevX - 1) << PERTEDEC, ay = (prevY - 1) << PERTEDEC; int bufsize = prevX * prevY * 2; int bufwidth = prevX; expix1[0].val=expix1[prevX-1].val=expix1[prevX*prevY-1].val=expix1[prevX*prevY-prevX].val=0; for (myPos = 0; myPos < bufsize; myPos += 2) { Color col1, col2, col3, col4; int c1, c2, c3, c4, px, py; int pos; int coeffs; int brutSmypos = brutS[myPos]; myPos2 = myPos + 1; px = brutSmypos + (((brutD[myPos] - brutSmypos) * buffratio) >> BUFFPOINTNB); brutSmypos = brutS[myPos2]; py = brutSmypos + (((brutD[myPos2] - brutSmypos) * buffratio) >> BUFFPOINTNB); if ((py >= (int)ay) || (px >= (int)ax)) { pos = coeffs = 0; } else { pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC)); /* coef en modulo 15 */ coeffs = precalCoef[px & PERTEMASK][py & PERTEMASK]; } getPixelRGB_ (expix1, pos, &col1); getPixelRGB_ (expix1, pos + 1, &col2); getPixelRGB_ (expix1, pos + bufwidth, &col3); getPixelRGB_ (expix1, pos + bufwidth + 1, &col4); c1 = coeffs; c2 = (c1 >> 8) & 0xFF; c3 = (c1 >> 16) & 0xFF; c4 = (c1 >> 24) & 0xFF; c1 = c1 & 0xff; couleur.r = col1.r * c1 + col2.r * c2 + col3.r * c3 + col4.r * c4; if (couleur.r > 5) couleur.r -= 5; couleur.r >>= 8; couleur.v = col1.v * c1 + col2.v * c2 + col3.v * c3 + col4.v * c4; if (couleur.v > 5) couleur.v -= 5; couleur.v >>= 8; couleur.b = col1.b * c1 + col2.b * c2 + col3.b * c3 + col4.b * c4; if (couleur.b > 5) couleur.b -= 5; couleur.b >>= 8; setPixelRGB_ (expix2, myPos >> 1, couleur); } } /** generate the water fx horizontal direction buffer */ static void generateTheWaterFXHorizontalDirectionBuffer(PluginInfo *goomInfo, ZoomFilterFXWrapperData *data) { int loopv; int decc = goom_irand(goomInfo->gRandom, 8) - 4; int spdc = goom_irand(goomInfo->gRandom, 8) - 4; int accel = goom_irand(goomInfo->gRandom, 8) - 4; for (loopv = data->prevY; loopv != 0;) { loopv--; data->firedec[loopv] = decc; decc += spdc / 10; spdc += goom_irand(goomInfo->gRandom, 3) - goom_irand(goomInfo->gRandom, 3); if (decc > 4) spdc -= 1; if (decc < -4) spdc += 1; if (spdc > 30) spdc = spdc - goom_irand(goomInfo->gRandom, 3) + accel / 10; if (spdc < -30) spdc = spdc + goom_irand(goomInfo->gRandom, 3) + accel / 10; if (decc > 8 && spdc > 1) spdc -= goom_irand(goomInfo->gRandom, 3) - 2; if (decc < -8 && spdc < -1) spdc += goom_irand(goomInfo->gRandom, 3) + 2; if (decc > 8 || decc < -8) decc = decc * 8 / 9; accel += goom_irand(goomInfo->gRandom, 2) - goom_irand(goomInfo->gRandom, 2); if (accel > 20) accel -= 2; if (accel < -20) accel += 2; } } /** * Main work for the dynamic displacement map. * * Reads data from pix1, write to pix2. * * Useful datas for this FX are stored in ZoomFilterData. * * If you think that this is a strange function name, let me say that a long time ago, * there has been a slow version and a gray-level only one. Then came these function, * fast and workin in RGB colorspace ! nice but it only was applying a zoom to the image. * So that is why you have this name, for the nostalgy of the first days of goom * when it was just a tiny program writen in Turbo Pascal on my i486... */ void zoomFilterFastRGB (PluginInfo *goomInfo, Pixel * pix1, Pixel * pix2, ZoomFilterData * zf, Uint resx, Uint resy, int switchIncr, float switchMult) { Uint x, y; ZoomFilterFXWrapperData *data = (ZoomFilterFXWrapperData*)goomInfo->zoomFilter_fx.fx_data; if (!BVAL(data->enabled_bp)) return; /** changement de taille **/ if ((data->prevX != resx) || (data->prevY != resy)) { data->prevX = resx; data->prevY = resy; if (data->brutS) free (data->freebrutS); data->brutS = 0; if (data->brutD) free (data->freebrutD); data->brutD = 0; if (data->brutT) free (data->freebrutT); data->brutT = 0; data->middleX = resx / 2; data->middleY = resy / 2; data->mustInitBuffers = 1; if (data->firedec) free (data->firedec); data->firedec = 0; } if (data->interlace_start != -2) zf = NULL; /** changement de config **/ if (zf) { data->reverse = zf->reverse; data->general_speed = (float)(zf->vitesse-128)/128.0f; if (data->reverse) data->general_speed = -data->general_speed; data->middleX = zf->middleX; data->middleY = zf->middleY; data->theMode = zf->mode; data->hPlaneEffect = zf->hPlaneEffect; data->vPlaneEffect = zf->vPlaneEffect; data->waveEffect = zf->waveEffect; data->hypercosEffect = zf->hypercosEffect; data->noisify = zf->noisify; data->interlace_start = 0; } if (data->mustInitBuffers) { data->mustInitBuffers = 0; data->freebrutS = (signed int *) calloc (resx * resy * 2 + 128, sizeof(unsigned int)); data->brutS = (gint32 *) ((1 + ((uintptr_t) (data->freebrutS)) / 128) * 128); data->freebrutD = (signed int *) calloc (resx * resy * 2 + 128, sizeof(unsigned int)); data->brutD = (gint32 *) ((1 + ((uintptr_t) (data->freebrutD)) / 128) * 128); data->freebrutT = (signed int *) calloc (resx * resy * 2 + 128, sizeof(unsigned int)); data->brutT = (gint32 *) ((1 + ((uintptr_t) (data->freebrutT)) / 128) * 128); data->buffratio = 0; data->firedec = (int *) malloc (data->prevY * sizeof (int)); generateTheWaterFXHorizontalDirectionBuffer(goomInfo, data); data->interlace_start = 0; makeZoomBufferStripe(data,resy); /* Copy the data from temp to dest and source */ memcpy(data->brutS,data->brutT,resx * resy * 2 * sizeof(int)); memcpy(data->brutD,data->brutT,resx * resy * 2 * sizeof(int)); } /* generation du buffer de trans */ if (data->interlace_start == -1) { /* sauvegarde de l'etat actuel dans la nouvelle source * TODO: write that in MMX (has been done in previous version, but did not follow some new fonctionnalities) */ y = data->prevX * data->prevY * 2; for (x = 0; x < y; x += 2) { int brutSmypos = data->brutS[x]; int x2 = x + 1; data->brutS[x] = brutSmypos + (((data->brutD[x] - brutSmypos) * data->buffratio) >> BUFFPOINTNB); brutSmypos = data->brutS[x2]; data->brutS[x2] = brutSmypos + (((data->brutD[x2] - brutSmypos) * data->buffratio) >> BUFFPOINTNB); } data->buffratio = 0; } if (data->interlace_start == -1) { signed int * tmp; tmp = data->brutD; data->brutD=data->brutT; data->brutT=tmp; tmp = data->freebrutD; data->freebrutD=data->freebrutT; data->freebrutT=tmp; data->interlace_start = -2; } if (data->interlace_start>=0) { /* creation de la nouvelle destination */ makeZoomBufferStripe(data,resy/16); } if (switchIncr != 0) { data->buffratio += switchIncr; if (data->buffratio > BUFFPOINTMASK) data->buffratio = BUFFPOINTMASK; } if (switchMult != 1.0f) { data->buffratio = (int) ((float) BUFFPOINTMASK * (1.0f - switchMult) + (float) data->buffratio * switchMult); } data->zoom_width = data->prevX; goomInfo->methods.zoom_filter (data->prevX, data->prevY, pix1, pix2, data->brutS, data->brutD, data->buffratio, data->precalCoef); } static void generatePrecalCoef (int precalCoef[16][16]) { int coefh, coefv; for (coefh = 0; coefh < 16; coefh++) { for (coefv = 0; coefv < 16; coefv++) { int i; int diffcoeffh; int diffcoeffv; diffcoeffh = sqrtperte - coefh; diffcoeffv = sqrtperte - coefv; if (!(coefh || coefv)) { i = 255; } else { int i1, i2, i3, i4; i1 = diffcoeffh * diffcoeffv; i2 = coefh * diffcoeffv; i3 = diffcoeffh * coefv; i4 = coefh * coefv; // TODO: faire mieux... if (i1) i1--; if (i2) i2--; if (i3) i3--; if (i4) i4--; i = (i1) | (i2 << 8) | (i3 << 16) | (i4 << 24); } precalCoef[coefh][coefv] = i; } } } /* VisualFX Wrapper */ static void zoomFilterVisualFXWrapper_init (struct _VISUAL_FX *_this, PluginInfo *info) { ZoomFilterFXWrapperData *data = (ZoomFilterFXWrapperData*)malloc(sizeof(ZoomFilterFXWrapperData)); (void)info; data->coeffs = 0; data->freecoeffs = 0; data->brutS = 0; data->freebrutS = 0; data->brutD = 0; data->freebrutD = 0; data->brutT = 0; data->freebrutT = 0; data->prevX = 0; data->prevY = 0; data->mustInitBuffers = 1; data->interlace_start = -2; data->general_speed = 0.0f; data->reverse = 0; data->theMode = rand() % 10; data->waveEffect = 0; data->hypercosEffect = 0; data->vPlaneEffect = 0; data->hPlaneEffect = 0; data->noisify = 2; /** modif by jeko : fixedpoint : buffration = (16:16) (donc 0<=buffration<=2^16) */ data->buffratio = 0; data->firedec = 0; data->wave = data->wavesp = 0; data->enabled_bp = secure_b_param("Enabled", 1); data->params = plugin_parameters ("Zoom Filter", 1); data->params.params[0] = &data->enabled_bp; _this->params = &data->params; _this->fx_data = (void*)data; /** modif d'optim by Jeko : precalcul des 4 coefs resultant des 2 pos */ generatePrecalCoef(data->precalCoef); } static void zoomFilterVisualFXWrapper_free (struct _VISUAL_FX *_this) { ZoomFilterFXWrapperData *data = _this->fx_data; if (data) { free (data->params.params); free(data->freebrutS); free(data->freebrutD); free(data->freebrutT); free(data->firedec); free (data); } } static void zoomFilterVisualFXWrapper_apply (struct _VISUAL_FX *_this, Pixel *src, Pixel *dest, PluginInfo *info) { (void)_this; (void)src; (void)dest; (void)info; } VisualFX zoomFilterVisualFXWrapper_create(void) { VisualFX fx = { .init = zoomFilterVisualFXWrapper_init, .free = zoomFilterVisualFXWrapper_free, .apply = zoomFilterVisualFXWrapper_apply }; return fx; } /* TODO : MOVE THIS AWAY */ void pointFilter (PluginInfo *goomInfo, Pixel * pix1, Color c, float t1, float t2, float t3, float t4, Uint cycle) { Uint x = (Uint) ((int) (goomInfo->screen.width / 2) + (int) (t1 * cos ((float) cycle / t3))); Uint y = (Uint) ((int) (goomInfo->screen.height/2) + (int) (t2 * sin ((float) cycle / t4))); if ((x > 1) && (y > 1) && ((int)x < goomInfo->screen.width - 2) && ((int)y < goomInfo->screen.height - 2)) { setPixelRGB (goomInfo, pix1, x + 1, y, c); setPixelRGB (goomInfo, pix1, x, y + 1, c); setPixelRGB (goomInfo, pix1, x + 1, y + 1, WHITE); setPixelRGB (goomInfo, pix1, x + 2, y + 1, c); setPixelRGB (goomInfo, pix1, x + 1, y + 2, c); } } �����������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/xmmx.c�������������������������������������������������������������������0000644�0001750�0001750�00000024542�14647725152�014545� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_MMX /* a definir pour avoir exactement le meme resultat que la fonction C * (un chouillat plus lent).. mais la difference est assez peu notable. */ // #define STRICT_COMPAT #define BUFFPOINTNB 16 #define BUFFPOINTMASK 0xffff #define BUFFINCR 0xff #define sqrtperte 16 /* faire : a % sqrtperte <=> a & pertemask*/ #define PERTEMASK 0xf /* faire : a / sqrtperte <=> a >> PERTEDEC*/ #define PERTEDEC 4 /*#define MMX_TRACE*/ #include "mmx.h" /*#include "xmmx.h"*/ #include "goom_graphic.h" int xmmx_supported (void) { return (mm_support()&0x8)>>3; } void zoom_filter_xmmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2, int *lbruS, int *lbruD, int buffratio, int precalCoef[16][16]) { int bufsize = prevX * prevY; /* taille du buffer */ volatile int loop; /* variable de boucle */ mmx_t *brutS = (mmx_t*)lbruS; /* buffer de transformation source */ mmx_t *brutD = (mmx_t*)lbruD; /* buffer de transformation dest */ volatile mmx_t prevXY; volatile mmx_t ratiox; /* volatile mmx_t interpix; */ expix1[0].val=expix1[prevX-1].val=expix1[prevX*prevY-1].val=expix1[prevX*prevY-prevX].val=0; prevXY.ud[0] = (prevX-1)<<PERTEDEC; prevXY.ud[1] = (prevY-1)<<PERTEDEC; ratiox.d[0] = buffratio; ratiox.d[1] = buffratio; __asm__ __volatile__ ( "\n\t movq %0, %%mm6" "\n\t pslld $16, %%mm6" /* mm6 = [rat16=buffratio<<16 | rat16=buffratio<<16] */ "\n\t pxor %%mm7, %%mm7" /* mm7 = 0 */ ::"m"(ratiox)); loop = 0; /* * NOTE : mm6 et mm7 ne sont pas modifies dans la boucle. */ while (loop < bufsize) { /* Thread #1 * pre : mm6 = [rat16|rat16] * post : mm0 = S + ((D-S)*rat16 format [X|Y] * modified = mm0,mm1,mm2 */ __asm__ __volatile__ ( "#1 \n\t movq %0, %%mm0" "#1 \n\t movq %1, %%mm1" "#1 \n\t psubd %%mm0, %%mm1" /* mm1 = D - S */ "#1 \n\t movq %%mm1, %%mm2" /* mm2 = D - S */ "#1 \n\t pslld $16, %%mm1" "#1 \n\t pmullw %%mm6, %%mm2" "#1 \n\t pmulhuw %%mm6, %%mm1" "#1 \n\t pslld $16, %%mm0" "#1 \n\t paddd %%mm2, %%mm1" /* mm1 = (D - S) * buffratio >> 16 */ "#1 \n\t paddd %%mm1, %%mm0" /* mm0 = S + mm1 */ "#1 \n\t psrld $16, %%mm0" : : "m" (brutS[loop]), "m" (brutD[loop]) ); /* mm0 = S */ /* * pre : mm0 : position vector on screen * prevXY : coordinate of the lower-right point on screen * post : clipped mm0 * modified : mm0,mm1,mm2 */ __asm__ __volatile__ ( "#1 \n\t movq %0, %%mm1" "#1 \n\t pcmpgtd %%mm0, %%mm1" /* mm0 en X contient (idem pour Y) : * 1111 si prevXY > px * 0000 si prevXY <= px */ #ifdef STRICT_COMPAT "#1 \n\t movq %%mm1, %%mm2" "#1 \n\t punpckhdq %%mm2, %%mm2" "#1 \n\t punpckldq %%mm1, %%mm1" "#1 \n\t pand %%mm2, %%mm0" #endif "#1 \n\t pand %%mm1, %%mm0" /* on met a zero la partie qui deborde */ : : "m" (prevXY) ); /* Thread #2 * pre : mm0 : clipped position on screen * * post : mm3 : coefs for this position * mm1 : X vector [0|X] * * modif : eax,esi */ __asm__ __volatile__ ( "#2 \n\t movd %%mm0, %%esi" "#2 \n\t movq %%mm0, %%mm1" "#2 \n\t andl $15, %%esi" "#2 \n\t psrlq $32, %%mm1" "#2 \n\t shll $6, %%esi" "#2 \n\t movd %%mm1, %%eax" #if defined(ARCH_X86_64) "#2 \n\t addq %0, %%rsi" "#2 \n\t andl $15, %%eax" "#2 \n\t movd (%%rsi,%%rax,4), %%mm3" #elif defined(ARCH_X86_X32) "#2 \n\t addl %0, %%esi" "#2 \n\t andl $15, %%eax" "#2 \n\t movd (%%rsi,%%rax,4), %%mm3" #else "#2 \n\t addl %0, %%esi" "#2 \n\t andl $15, %%eax" "#2 \n\t movd (%%esi,%%eax,4), %%mm3" #endif : : "g" (precalCoef) #if defined(ARCH_X86_64) || defined(ARCH_X86_X32) : "rax", "rsi" #else : "eax", "esi" #endif ); /* * extraction des coefficients... (Thread #3) * * pre : coef dans mm3 * * post : coef extraits dans mm3 (c1 & c2) * et mm4 (c3 & c4) * * modif : mm5 */ /* (Thread #4) * pre : mm0 : Y pos [*|Y] * mm1 : X pos [*|X] * * post : mm0 : expix1[position] * mm2 : expix1[position+largeur] * * modif : eax, esi */ __asm__ __volatile__ ( "#2 \n\t psrld $4, %%mm0" "#2 \n\t psrld $4, %%mm1" /* PERTEDEC = $4 */ "#4 \n\t movd %%mm1, %%eax" "#3 \n\t movq %%mm3, %%mm5" "#4 \n\t imull %1, %%eax" "#4 \n\t movd %%mm0, %%esi" "#3 \n\t punpcklbw %%mm5, %%mm3" "#4 \n\t addl %%esi, %%eax" "#3 \n\t movq %%mm3, %%mm4" "#3 \n\t movq %%mm3, %%mm5" #if defined(ARCH_X86_64) "#4 \n\t movq %0, %%rsi" "#3 \n\t punpcklbw %%mm5, %%mm3" "#4 \n\t movq (%%rsi,%%rax,4), %%mm0" "#3 \n\t punpckhbw %%mm5, %%mm4" "#4 \n\t addl %1, %%eax" "#4 \n\t movq (%%rsi,%%rax,4), %%mm2" #elif defined(ARCH_X86_X32) "#4 \n\t movl %0, %%esi" "#3 \n\t punpcklbw %%mm5, %%mm3" "#4 \n\t movq (%%rsi,%%rax,4), %%mm0" "#3 \n\t punpckhbw %%mm5, %%mm4" "#4 \n\t addl %1, %%eax" "#4 \n\t movq (%%rsi,%%rax,4), %%mm2" #else "#4 \n\t movl %0, %%esi" "#3 \n\t punpcklbw %%mm5, %%mm3" "#4 \n\t movq (%%esi,%%eax,4), %%mm0" "#3 \n\t punpckhbw %%mm5, %%mm4" "#4 \n\t addl %1, %%eax" "#4 \n\t movq (%%esi,%%eax,4), %%mm2" #endif : : "g" (expix1), "g" (prevX) #if defined(ARCH_X86_64) || defined(ARCH_X86_X32) : "rax", "rsi" #else : "eax", "esi" #endif ); /* * pre : mm0 : expix1[position] * mm2 : expix1[position+largeur] * mm3 & mm4 : coefs */ /* recopie des deux premiers pixels dans mm0 et mm1 */ movq_r2r (mm0, mm1); /* b1-v1-r1-a1-b2-v2-r2-a2 */ /* depackage du premier pixel */ punpcklbw_r2r (mm7, mm0); /* 00-b2-00-v2-00-r2-00-a2 */ /* extraction des coefficients... */ movq_r2r (mm3, mm5); /* c2-c2-c2-c2-c1-c1-c1-c1 */ /*^en parrallele^*/ /* depackage du 2ieme pixel */ /*^*/ punpckhbw_r2r (mm7, mm1); /* 00-b1-00-v1-00-r1-00-a1 */ punpcklbw_r2r (mm7, mm5); /* 00-c1-00-c1-00-c1-00-c1 */ punpckhbw_r2r (mm7, mm3); /* 00-c2-00-c2-00-c2-00-c2 */ /* multiplication des pixels par les coefficients */ pmullw_r2r (mm5, mm0); /* c1*b2-c1*v2-c1*r2-c1*a2 */ pmullw_r2r (mm3, mm1); /* c2*b1-c2*v1-c2*r1-c2*a1 */ paddw_r2r (mm1, mm0); /* ...extraction des 2 derniers coefficients */ movq_r2r (mm4, mm5); /* c4-c4-c4-c4-c3-c3-c3-c3 */ punpcklbw_r2r (mm7, mm4); /* 00-c3-00-c3-00-c3-00-c3 */ punpckhbw_r2r (mm7, mm5); /* 00-c4-00-c4-00-c4-00-c4 */ /* recuperation des 2 derniers pixels */ movq_r2r (mm2, mm1); /* depackage des pixels */ punpcklbw_r2r (mm7, mm1); punpckhbw_r2r (mm7, mm2); /* multiplication pas les coeffs */ pmullw_r2r (mm4, mm1); pmullw_r2r (mm5, mm2); /* ajout des valeurs obtenues à la valeur finale */ paddw_r2r (mm1, mm0); paddw_r2r (mm2, mm0); /* division par 256 = 16+16+16+16, puis repackage du pixel final */ psrlw_i2r (8, mm0); packuswb_r2r (mm7, mm0); movd_r2m (mm0,expix2[loop]); ++loop; } /*#ifdef HAVE_ATHLON*/ __asm__ __volatile__ ("emms\n"); /*#else emms(); #endif*/ } #define DRAWMETHOD_PLUS_XMMX(_out,_backbuf,_col) \ { \ movd_m2r(_backbuf, mm0); \ paddusb_m2r(_col, mm0); \ movd_r2m(mm0, _out); \ } #define DRAWMETHOD DRAWMETHOD_PLUS_XMMX(*p,*p,col) void draw_line_xmmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny) { int x, y, dx, dy, yy, xx; Pixel *p; if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny) || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx)) goto end_of_line; dx = x2 - x1; dy = y2 - y1; if (x1 >= x2) { int tmp; tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; dx = x2 - x1; dy = y2 - y1; } /* vertical line */ if (dx == 0) { if (y1 < y2) { p = &(data[(screenx * y1) + x1]); for (y = y1; y <= y2; y++) { DRAWMETHOD; p += screenx; } } else { p = &(data[(screenx * y2) + x1]); for (y = y2; y <= y1; y++) { DRAWMETHOD; p += screenx; } } goto end_of_line; } /* horizontal line */ if (dy == 0) { if (x1 < x2) { p = &(data[(screenx * y1) + x1]); for (x = x1; x <= x2; x++) { DRAWMETHOD; p++; } goto end_of_line; } else { p = &(data[(screenx * y1) + x2]); for (x = x2; x <= x1; x++) { DRAWMETHOD; p++; } goto end_of_line; } } /* 1 */ /* \ */ /* \ */ /* 2 */ if (y2 > y1) { /* steep */ if (dy > dx) { dx = ((dx << 16) / dy); x = x1 << 16; for (y = y1; y <= y2; y++) { xx = x >> 16; p = &(data[(screenx * y) + xx]); DRAWMETHOD; #if 0 if (xx < (screenx - 1)) { p++; /* DRAWMETHOD; */ } #endif x += dx; } goto end_of_line; } /* shallow */ else { dy = ((dy << 16) / dx); y = y1 << 16; for (x = x1; x <= x2; x++) { yy = y >> 16; p = &(data[(screenx * yy) + x]); DRAWMETHOD; #if 0 if (yy < (screeny - 1)) { p += screeny; /* DRAWMETHOD; */ } #endif y += dy; } } } /* 2 */ /* / */ /* / */ /* 1 */ else { /* steep */ if (-dy > dx) { dx = ((dx << 16) / -dy); x = (x1 + 1) << 16; for (y = y1; y >= y2; y--) { xx = x >> 16; p = &(data[(screenx * y) + xx]); DRAWMETHOD; #if 0 if (xx < (screenx - 1)) { p--; /* DRAWMETHOD; */ } #endif x += dx; } goto end_of_line; } /* shallow */ else { dy = ((dy << 16) / dx); y = y1 << 16; for (x = x1; x <= x2; x++) { yy = y >> 16; p = &(data[(screenx * yy) + x]); DRAWMETHOD; #if 0 if (yy < (screeny - 1)) { p += screeny; /* DRAWMETHOD; */ } #endif y += dy; } goto end_of_line; } } end_of_line: __asm__ __volatile__ ("emms\n"); } #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/cpu_info.c���������������������������������������������������������������0000644�0001750�0001750�00000002670�14647725152�015354� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * cpu_info.c * Goom * * Created by Guillaume Borios on Sun Dec 28 2003. * Copyright (c) 2003 iOS. All rights reserved. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "cpu_info.h" #ifdef CPU_X86 #include "mmx.h" #endif #ifdef CPU_POWERPC #include <sys/types.h> #include <stdlib.h> #endif static unsigned int CPU_FLAVOUR = 0; static unsigned int CPU_NUMBER = 1; static unsigned int CPU_DETECTED = 0; static void autoset_cpu_info (void) { CPU_DETECTED = 1; #ifdef CPU_POWERPC int result; size_t size; result = 0; size = 4; if (sysctlbyname("hw.optional.altivec",&result,&size,NULL,NULL) == 0) { if (result != 0) CPU_FLAVOUR |= CPU_OPTION_ALTIVEC; } result = 0; size = 4; if (sysctlbyname("hw.optional.64bitops",&result,&size,NULL,NULL) == 0) { if (result != 0) CPU_FLAVOUR |= CPU_OPTION_64_BITS; } result = 0; size = 4; if (sysctlbyname("hw.ncpu",&result,&size,NULL,NULL) == 0) { if (result != 0) CPU_NUMBER = result; } #endif /* CPU_POWERPC */ #ifdef CPU_X86 if (mmx_supported()) CPU_FLAVOUR |= CPU_OPTION_MMX; if (xmmx_supported()) CPU_FLAVOUR |= CPU_OPTION_XMMX; #endif /* CPU_X86 */ } unsigned int cpu_flavour (void) { if (CPU_DETECTED == 0) autoset_cpu_info(); return CPU_FLAVOUR; } unsigned int cpu_number (void) { if (CPU_DETECTED == 0) autoset_cpu_info(); return CPU_NUMBER; } ������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_yacc.c������������������������������������������������������������0000644�0001750�0001750�00000275046�14647725152�016062� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 1.875. */ /* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ /* Written by Richard Stallman by simplifying the original so called ``semantic'' parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Using locations. */ #define YYLSP_NEEDED 0 /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { LTYPE_INTEGER = 258, LTYPE_FLOAT = 259, LTYPE_VAR = 260, LTYPE_PTR = 261, PTR_TK = 262, INT_TK = 263, FLOAT_TK = 264, DECLARE = 265, EXTERNAL = 266, WHILE = 267, DO = 268, NOT = 269, PLUS_EQ = 270, SUB_EQ = 271, DIV_EQ = 272, MUL_EQ = 273, SUP_EQ = 274, LOW_EQ = 275, NOT_EQ = 276, STRUCT = 277, FOR = 278, IN = 279 }; #endif #define LTYPE_INTEGER 258 #define LTYPE_FLOAT 259 #define LTYPE_VAR 260 #define LTYPE_PTR 261 #define PTR_TK 262 #define INT_TK 263 #define FLOAT_TK 264 #define DECLARE 265 #define EXTERNAL 266 #define WHILE 267 #define DO 268 #define NOT 269 #define PLUS_EQ 270 #define SUB_EQ 271 #define DIV_EQ 272 #define MUL_EQ 273 #define SUP_EQ 274 #define LOW_EQ 275 #define NOT_EQ 276 #define STRUCT 277 #define FOR 278 #define IN 279 /* Copy the first part of user declarations. */ #line 6 "goomsl_yacc.y" #include <stdio.h> #include <stdlib.h> #include <string.h> #include "goomsl.h" #include "goomsl_private.h" #define STRUCT_ALIGNMENT 16 /* #define VERBOSE */ int yylex(void); void yyerror(const char *); extern GoomSL *currentGoomSL; static NodeType *nodeNew(const char *str, int type, int line_number); static NodeType *nodeClone(NodeType *node); static void nodeFreeInternals(NodeType *node); static void nodeFree(NodeType *node); static void commit_node(NodeType *node, int releaseIfTemp); static void precommit_node(NodeType *node); static NodeType *new_constInt(const char *str, int line_number); static NodeType *new_constFloat(const char *str, int line_number); static NodeType *new_constPtr(const char *str, int line_number); static NodeType *new_var(const char *str, int line_number); static NodeType *new_nop(const char *str); static NodeType *new_op(const char *str, int type, int nbOp); static int allocateLabel(void); static int allocateTemp(void); static void releaseTemp(int n); static void releaseAllTemps(void); static int is_tmp_expr(NodeType *node) { if (node->str) { return (!strncmp(node->str,"_i_tmp_",7)) || (!strncmp(node->str,"_f_tmp_",7)) || (!strncmp(node->str,"_p_tmp",7)); } return 0; } /* pre: is_tmp_expr(node); */ static int get_tmp_id(NodeType *node) { return atoi((node->str)+5); } static int is_commutative_expr(int itype) { /* {{{ */ return (itype == INSTR_ADD) || (itype == INSTR_MUL) || (itype == INSTR_ISEQUAL); } /* }}} */ static void GSL_PUT_LABEL(char *name, int line_number) { /* {{{ */ #ifdef VERBOSE printf("label %s\n", name); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, line_number); gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL); } /* }}} */ static void GSL_PUT_JUMP(char *name, int line_number) { /* {{{ */ #ifdef VERBOSE printf("jump %s\n", name); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "jump", INSTR_JUMP, 1, line_number); gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL); } /* }}} */ static void GSL_PUT_JXXX(const char *name, const char *iname, int instr_id, int line_number) { /* {{{ */ #ifdef VERBOSE printf("%s %s\n", iname, name); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, iname, instr_id, 1, line_number); gsl_instr_add_param(currentGoomSL->instr, name, TYPE_LABEL); } /* }}} */ static void GSL_PUT_JZERO(const char *name,int line_number) { /* {{{ */ GSL_PUT_JXXX(name,"jzero.i",INSTR_JZERO,line_number); } /* }}} */ static void GSL_PUT_JNZERO(const char *name, int line_number) { /* {{{ */ GSL_PUT_JXXX(name,"jnzero.i",INSTR_JNZERO,line_number); } /* }}} */ /* Structures Management */ #define ALIGN_ADDR(_addr,_align) {\ if (_align>1) {\ int _dec = (_addr%_align);\ if (_dec != 0) _addr += _align - _dec;\ }} /* */ static void gsl_prepare_struct(GSL_Struct *s, int s_align, int i_align, int f_align) { int i; int consumed = 0; int iblk=0, fblk=0; s->iBlock[0].size = 0; s->iBlock[0].data = 0; s->fBlock[0].size = 0; s->fBlock[0].data = 0; /* Prepare sub-struct and calculate space needed for their storage */ for (i = 0; i < s->nbFields; ++i) { if (s->fields[i]->type < FIRST_RESERVED) { int j=0; GSL_Struct *substruct = currentGoomSL->gsl_struct[s->fields[i]->type]; consumed += sizeof(int); /* stocke le prefix */ ALIGN_ADDR(consumed, s_align); s->fields[i]->offsetInStruct = consumed; gsl_prepare_struct(substruct, s_align, i_align, f_align); for(j=0;substruct->iBlock[j].size>0;++j) { s->iBlock[iblk].data = consumed + substruct->iBlock[j].data; s->iBlock[iblk].size = substruct->iBlock[j].size; iblk++; } for(j=0;substruct->fBlock[j].size>0;++j) { s->fBlock[fblk].data = consumed + substruct->fBlock[j].data; s->fBlock[fblk].size = substruct->fBlock[j].size; fblk++; } consumed += substruct->size; } } /* Then prepare integers */ ALIGN_ADDR(consumed, i_align); for (i = 0; i < s->nbFields; ++i) { if (s->fields[i]->type == INSTR_INT) { if (s->iBlock[iblk].size == 0) { s->iBlock[iblk].size = 1; s->iBlock[iblk].data = consumed; } else { s->iBlock[iblk].size += 1; } s->fields[i]->offsetInStruct = consumed; consumed += sizeof(int); } } iblk++; s->iBlock[iblk].size = 0; s->iBlock[iblk].data = 0; /* Then prepare floats */ ALIGN_ADDR(consumed, f_align); for (i = 0; i < s->nbFields; ++i) { if (s->fields[i]->type == INSTR_FLOAT) { if (s->fBlock[fblk].size == 0) { s->fBlock[fblk].size = 1; s->fBlock[fblk].data = consumed; } else { s->fBlock[fblk].size += 1; } s->fields[i]->offsetInStruct = consumed; consumed += sizeof(int); } } fblk++; s->fBlock[fblk].size = 0; s->fBlock[fblk].data = 0; /* Finally prepare pointers */ ALIGN_ADDR(consumed, i_align); for (i = 0; i < s->nbFields; ++i) { if (s->fields[i]->type == INSTR_PTR) { s->fields[i]->offsetInStruct = consumed; consumed += sizeof(int); } } s->size = consumed; } /* Returns the ID of a struct from its name */ static int gsl_get_struct_id(const char *name) /* {{{ */ { HashValue *ret = goom_hash_get(currentGoomSL->structIDS, name); if (ret != NULL) return ret->i; return -1; } /* }}} */ /* Adds the definition of a struct */ static void gsl_add_struct(const char *name, GSL_Struct *gsl_struct) /* {{{ */ { /* Prepare the struct: ie calculate internal storage format */ gsl_prepare_struct(gsl_struct, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT, STRUCT_ALIGNMENT); /* If the struct does not already exists */ if (gsl_get_struct_id(name) < 0) { /* adds it */ int id = currentGoomSL->nbStructID++; goom_hash_put_int(currentGoomSL->structIDS, name, id); if (currentGoomSL->gsl_struct_size <= id) { currentGoomSL->gsl_struct_size *= 2; currentGoomSL->gsl_struct = (GSL_Struct**)realloc(currentGoomSL->gsl_struct, sizeof(GSL_Struct*) * currentGoomSL->gsl_struct_size); } currentGoomSL->gsl_struct[id] = gsl_struct; } } /* }}} */ /* Creates a field for a struct */ static GSL_StructField *gsl_new_struct_field(const char *name, int type) { GSL_StructField *field = (GSL_StructField*)malloc(sizeof(GSL_StructField)); strcpy(field->name, name); field->type = type; return field; } /* Create as field for a struct which will be a struct itself */ static GSL_StructField *gsl_new_struct_field_struct(const char *name, const char *type) { GSL_StructField *field = gsl_new_struct_field(name, gsl_get_struct_id(type)); if (field->type < 0) { fprintf(stderr, "ERROR: Line %d, Unknown structure: '%s'\n", currentGoomSL->num_lines, type); exit(1); } return field; } /* Creates a Struct */ static GSL_Struct *gsl_new_struct(GSL_StructField *field) { GSL_Struct *s = (GSL_Struct*)malloc(sizeof(GSL_Struct)); s->nbFields = 1; s->fields[0] = field; return s; } /* Adds a field to a struct */ static void gsl_add_struct_field(GSL_Struct *s, GSL_StructField *field) { s->fields[s->nbFields++] = field; } int gsl_type_of_var(GoomHash *ns, const char *name) { char type_of[256]; HashValue *hv; sprintf(type_of, "__type_of_%s", name); hv = goom_hash_get(ns, type_of); if (hv != NULL) return hv->i; fprintf(stderr, "ERROR: Unknown variable type: '%s'\n", name); return -1; } static void gsl_declare_var(GoomHash *ns, const char *name, int type, void *space) { char type_of[256]; if (name[0] == '@') { ns = currentGoomSL->vars; } if (space == NULL) { switch (type) { case INSTR_INT: case INSTR_FLOAT: case INSTR_PTR: space = goom_heap_malloc_with_alignment(currentGoomSL->data_heap, sizeof(int), sizeof(int)); break; case -1: fprintf(stderr, "What the fuck!\n"); exit(1); default: /* On a un struct_id */ space = goom_heap_malloc_with_alignment_prefixed(currentGoomSL->data_heap, currentGoomSL->gsl_struct[type]->size, STRUCT_ALIGNMENT, sizeof(int)); } } goom_hash_put_ptr(ns, name, (void*)space); sprintf(type_of, "__type_of_%s", name); goom_hash_put_int(ns, type_of, type); /* Ensuite le hack: on ajoute les champs en tant que variables. */ if (type < FIRST_RESERVED) { int i; GSL_Struct *gsl_struct = currentGoomSL->gsl_struct[type]; ((int*)space)[-1] = type; /* stockage du type dans le prefixe de structure */ for (i = 0; i < gsl_struct->nbFields; ++i) { char full_name[256]; char *cspace = (char*)space + gsl_struct->fields[i]->offsetInStruct; sprintf(full_name, "%s.%s", name, gsl_struct->fields[i]->name); gsl_declare_var(ns, full_name, gsl_struct->fields[i]->type, cspace); } } } /* Declare a variable which will be a struct */ static void gsl_struct_decl(GoomHash *namespace, const char *struct_name, const char *name) { int struct_id = gsl_get_struct_id(struct_name); gsl_declare_var(namespace, name, struct_id, NULL); } static void gsl_float_decl_global(const char *name) { gsl_declare_var(currentGoomSL->vars, name, INSTR_FLOAT, NULL); } static void gsl_int_decl_global(const char *name) { gsl_declare_var(currentGoomSL->vars, name, INSTR_INT, NULL); } static void gsl_ptr_decl_global(const char *name) { gsl_declare_var(currentGoomSL->vars, name, INSTR_PTR, NULL); } static void gsl_struct_decl_global_from_id(const char *name, int id) { gsl_declare_var(currentGoomSL->vars, name, id, NULL); } /* FLOAT */ static void gsl_float_decl_local(const char *name) { gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_FLOAT, NULL); } /* INT */ static void gsl_int_decl_local(const char *name) { gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_INT, NULL); } /* PTR */ static void gsl_ptr_decl_local(const char *name) { gsl_declare_var(currentGoomSL->namespaces[currentGoomSL->currentNS], name, INSTR_PTR, NULL); } /* STRUCT */ static void gsl_struct_decl_local(const char *struct_name, const char *name) { gsl_struct_decl(currentGoomSL->namespaces[currentGoomSL->currentNS],struct_name,name); } static void commit_test2(NodeType *set,const char *type, int instr); static NodeType *new_call(const char *name, NodeType *affect_list); /* SETTER */ static NodeType *new_set(NodeType *lvalue, NodeType *expression) { /* {{{ */ NodeType *set = new_op("set", OPR_SET, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } /* }}} */ static void commit_set(NodeType *set) { /* {{{ */ commit_test2(set,"set",INSTR_SET); } /* }}} */ /* PLUS_EQ */ static NodeType *new_plus_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("plus_eq", OPR_PLUS_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_plus_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]); #ifdef VERBOSE printf("add %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "add", INSTR_ADD, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* SUB_EQ */ static NodeType *new_sub_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("sub_eq", OPR_SUB_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_sub_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]); #ifdef VERBOSE printf("sub %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "sub", INSTR_SUB, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* MUL_EQ */ static NodeType *new_mul_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("mul_eq", OPR_MUL_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_mul_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]); #ifdef VERBOSE printf("mul %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "mul", INSTR_MUL, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* DIV_EQ */ static NodeType *new_div_eq(NodeType *lvalue, NodeType *expression) /* {{{ */ { NodeType *set = new_op("div_eq", OPR_DIV_EQ, 2); set->unode.opr.op[0] = lvalue; set->unode.opr.op[1] = expression; return set; } static void commit_div_eq(NodeType *set) { precommit_node(set->unode.opr.op[1]); #ifdef VERBOSE printf("div %s %s\n", set->unode.opr.op[0]->str, set->unode.opr.op[1]->str); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "div", INSTR_DIV, 2, set->line_number); commit_node(set->unode.opr.op[0],0); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* commodity method for add, mult, ... */ static void precommit_expr(NodeType *expr, const char *type, int instr_id) { /* {{{ */ NodeType *tmp, *tmpcpy; int toAdd; /* compute "left" and "right" */ switch (expr->unode.opr.nbOp) { case 2: precommit_node(expr->unode.opr.op[1]); case 1: precommit_node(expr->unode.opr.op[0]); } if (is_tmp_expr(expr->unode.opr.op[0])) { tmp = expr->unode.opr.op[0]; toAdd = 1; } else if (is_commutative_expr(instr_id) && (expr->unode.opr.nbOp==2) && is_tmp_expr(expr->unode.opr.op[1])) { tmp = expr->unode.opr.op[1]; toAdd = 0; } else { char stmp[256]; /* declare a temporary variable to store the result */ if (expr->unode.opr.op[0]->type == CONST_INT_NODE) { sprintf(stmp,"_i_tmp_%i",allocateTemp()); gsl_int_decl_global(stmp); } else if (expr->unode.opr.op[0]->type == CONST_FLOAT_NODE) { sprintf(stmp,"_f_tmp%i",allocateTemp()); gsl_float_decl_global(stmp); } else if (expr->unode.opr.op[0]->type == CONST_PTR_NODE) { sprintf(stmp,"_p_tmp%i",allocateTemp()); gsl_ptr_decl_global(stmp); } else { int type = gsl_type_of_var(expr->unode.opr.op[0]->vnamespace, expr->unode.opr.op[0]->str); if (type == INSTR_FLOAT) { sprintf(stmp,"_f_tmp_%i",allocateTemp()); gsl_float_decl_global(stmp); } else if (type == INSTR_PTR) { sprintf(stmp,"_p_tmp_%i",allocateTemp()); gsl_ptr_decl_global(stmp); } else if (type == INSTR_INT) { sprintf(stmp,"_i_tmp_%i",allocateTemp()); gsl_int_decl_global(stmp); } else if (type == -1) { fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n", expr->line_number, expr->unode.opr.op[0]->str); exit(1); } else { /* type is a struct_id */ sprintf(stmp,"_s_tmp_%i",allocateTemp()); gsl_struct_decl_global_from_id(stmp,type); } } tmp = new_var(stmp,expr->line_number); /* set the tmp to the value of "op1" */ tmpcpy = nodeClone(tmp); commit_node(new_set(tmp,expr->unode.opr.op[0]),0); toAdd = 1; tmp = tmpcpy; } /* add op2 to tmp */ #ifdef VERBOSE if (expr->unode.opr.nbOp == 2) printf("%s %s %s\n", type, tmp->str, expr->unode.opr.op[toAdd]->str); else printf("%s %s\n", type, tmp->str); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr_id, expr->unode.opr.nbOp, expr->line_number); tmpcpy = nodeClone(tmp); commit_node(tmp,0); if (expr->unode.opr.nbOp == 2) { commit_node(expr->unode.opr.op[toAdd],1); } /* redefine the ADD node now as the computed variable */ nodeFreeInternals(expr); *expr = *tmpcpy; free(tmpcpy); } /* }}} */ static NodeType *new_expr1(const char *name, int id, NodeType *expr1) { /* {{{ */ NodeType *add = new_op(name, id, 1); add->unode.opr.op[0] = expr1; return add; } /* }}} */ static NodeType *new_expr2(const char *name, int id, NodeType *expr1, NodeType *expr2) { /* {{{ */ NodeType *add = new_op(name, id, 2); add->unode.opr.op[0] = expr1; add->unode.opr.op[1] = expr2; return add; } /* }}} */ /* ADD */ static NodeType *new_add(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("add", OPR_ADD, expr1, expr2); } static void precommit_add(NodeType *add) { precommit_expr(add,"add",INSTR_ADD); } /* }}} */ /* SUB */ static NodeType *new_sub(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("sub", OPR_SUB, expr1, expr2); } static void precommit_sub(NodeType *sub) { precommit_expr(sub,"sub",INSTR_SUB); } /* }}} */ /* NEG */ static NodeType *new_neg(NodeType *expr) { /* {{{ */ NodeType *zeroConst = NULL; if (expr->type == CONST_INT_NODE) zeroConst = new_constInt("0", currentGoomSL->num_lines); else if (expr->type == CONST_FLOAT_NODE) zeroConst = new_constFloat("0.0", currentGoomSL->num_lines); else if (expr->type == CONST_PTR_NODE) { fprintf(stderr, "ERROR: Line %d, Could not negate const pointer.\n", currentGoomSL->num_lines); exit(1); } else { int type = gsl_type_of_var(expr->vnamespace, expr->str); if (type == INSTR_FLOAT) zeroConst = new_constFloat("0.0", currentGoomSL->num_lines); else if (type == INSTR_PTR) { fprintf(stderr, "ERROR: Line %d, Could not negate pointer.\n", currentGoomSL->num_lines); exit(1); } else if (type == INSTR_INT) zeroConst = new_constInt("0", currentGoomSL->num_lines); else if (type == -1) { fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n", expr->line_number, expr->unode.opr.op[0]->str); exit(1); } else { /* type is a struct_id */ fprintf(stderr, "ERROR: Line %d, Could not negate struct '%s'\n", expr->line_number, expr->str); exit(1); } } return new_expr2("sub", OPR_SUB, zeroConst, expr); } /* }}} */ /* MUL */ static NodeType *new_mul(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("mul", OPR_MUL, expr1, expr2); } static void precommit_mul(NodeType *mul) { precommit_expr(mul,"mul",INSTR_MUL); } /* }}} */ /* DIV */ static NodeType *new_div(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("div", OPR_DIV, expr1, expr2); } static void precommit_div(NodeType *mul) { precommit_expr(mul,"div",INSTR_DIV); } /* }}} */ /* CALL EXPRESSION */ static NodeType *new_call_expr(const char *name, NodeType *affect_list) { /* {{{ */ NodeType *call = new_call(name,affect_list); NodeType *node = new_expr1(name, OPR_CALL_EXPR, call); node->vnamespace = gsl_find_namespace(name); if (node->vnamespace == NULL) fprintf(stderr, "ERROR: Line %d, No return type for: '%s'\n", currentGoomSL->num_lines, name); return node; } static void precommit_call_expr(NodeType *call) { char stmp[256]; NodeType *tmp,*tmpcpy; int type = gsl_type_of_var(call->vnamespace, call->str); if (type == INSTR_FLOAT) { sprintf(stmp,"_f_tmp_%i",allocateTemp()); gsl_float_decl_global(stmp); } else if (type == INSTR_PTR) { sprintf(stmp,"_p_tmp_%i",allocateTemp()); gsl_ptr_decl_global(stmp); } else if (type == INSTR_INT) { sprintf(stmp,"_i_tmp_%i",allocateTemp()); gsl_int_decl_global(stmp); } else if (type == -1) { fprintf(stderr, "ERROR: Line %d, Could not find variable '%s'\n", call->line_number, call->str); exit(1); } else { /* type is a struct_id */ sprintf(stmp,"_s_tmp_%i",allocateTemp()); gsl_struct_decl_global_from_id(stmp,type); } tmp = new_var(stmp,call->line_number); commit_node(call->unode.opr.op[0],0); tmpcpy = nodeClone(tmp); commit_node(new_set(tmp,new_var(call->str,call->line_number)),0); nodeFreeInternals(call); *call = *tmpcpy; free(tmpcpy); } /* }}} */ static void commit_test2(NodeType *set,const char *type, int instr) { /* {{{ */ NodeType *tmp; char stmp[256]; precommit_node(set->unode.opr.op[0]); precommit_node(set->unode.opr.op[1]); tmp = set->unode.opr.op[0]; stmp[0] = 0; if (set->unode.opr.op[0]->type == CONST_INT_NODE) { sprintf(stmp,"_i_tmp_%i",allocateTemp()); gsl_int_decl_global(stmp); } else if (set->unode.opr.op[0]->type == CONST_FLOAT_NODE) { sprintf(stmp,"_f_tmp%i",allocateTemp()); gsl_float_decl_global(stmp); } else if (set->unode.opr.op[0]->type == CONST_PTR_NODE) { sprintf(stmp,"_p_tmp%i",allocateTemp()); gsl_ptr_decl_global(stmp); } if (stmp[0]) { NodeType *tmpcpy; tmp = new_var(stmp, set->line_number); tmpcpy = nodeClone(tmp); commit_node(new_set(tmp,set->unode.opr.op[0]),0); tmp = tmpcpy; } #ifdef VERBOSE printf("%s %s %s\n", type, tmp->str, set->unode.opr.op[1]->str); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, type, instr, 2, set->line_number); commit_node(tmp,instr!=INSTR_SET); commit_node(set->unode.opr.op[1],1); } /* }}} */ /* NOT */ static NodeType *new_not(NodeType *expr1) { /* {{{ */ return new_expr1("not", OPR_NOT, expr1); } static void commit_not(NodeType *set) { commit_node(set->unode.opr.op[0],0); #ifdef VERBOSE printf("not\n"); #endif currentGoomSL->instr = gsl_instr_init(currentGoomSL, "not", INSTR_NOT, 1, set->line_number); gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL); } /* }}} */ /* EQU */ static NodeType *new_equ(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("isequal", OPR_EQU, expr1, expr2); } static void commit_equ(NodeType *mul) { commit_test2(mul,"isequal",INSTR_ISEQUAL); } /* }}} */ /* INF */ static NodeType *new_low(NodeType *expr1, NodeType *expr2) { /* {{{ */ return new_expr2("islower", OPR_LOW, expr1, expr2); } static void commit_low(NodeType *mul) { commit_test2(mul,"islower",INSTR_ISLOWER); } /* }}} */ /* WHILE */ static NodeType *new_while(NodeType *expression, NodeType *instr) { /* {{{ */ NodeType *node = new_op("while", OPR_WHILE, 2); node->unode.opr.op[0] = expression; node->unode.opr.op[1] = instr; return node; } static void commit_while(NodeType *node) { int lbl = allocateLabel(); char start_while[1024], test_while[1024]; sprintf(start_while, "|start_while_%d|", lbl); sprintf(test_while, "|test_while_%d|", lbl); GSL_PUT_JUMP(test_while,node->line_number); GSL_PUT_LABEL(start_while,node->line_number); /* code */ commit_node(node->unode.opr.op[1],0); GSL_PUT_LABEL(test_while,node->line_number); commit_node(node->unode.opr.op[0],0); GSL_PUT_JNZERO(start_while,node->line_number); } /* }}} */ /* FOR EACH */ static NodeType *new_static_foreach(NodeType *var, NodeType *var_list, NodeType *instr) { /* {{{ */ NodeType *node = new_op("for", OPR_FOREACH, 3); node->unode.opr.op[0] = var; node->unode.opr.op[1] = var_list; node->unode.opr.op[2] = instr; node->line_number = currentGoomSL->num_lines; return node; } static void commit_foreach(NodeType *node) { NodeType *cur = node->unode.opr.op[1]; char tmp_func[256], tmp_loop[256]; int lbl = allocateLabel(); sprintf(tmp_func, "|foreach_func_%d|", lbl); sprintf(tmp_loop, "|foreach_loop_%d|", lbl); GSL_PUT_JUMP(tmp_loop, node->line_number); GSL_PUT_LABEL(tmp_func, node->line_number); precommit_node(node->unode.opr.op[2]); commit_node(node->unode.opr.op[2], 0); currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL); #ifdef VERBOSE printf("ret\n"); #endif GSL_PUT_LABEL(tmp_loop, node->line_number); while (cur != NULL) { NodeType *x, *var; /* 1: x=var */ x = nodeClone(node->unode.opr.op[0]); var = nodeClone(cur->unode.opr.op[0]); commit_node(new_set(x, var),0); /* 2: instr */ currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, tmp_func, TYPE_LABEL); #ifdef VERBOSE printf("call %s\n", tmp_func); #endif /* 3: var=x */ x = nodeClone(node->unode.opr.op[0]); var = cur->unode.opr.op[0]; commit_node(new_set(var, x),0); cur = cur->unode.opr.op[1]; } nodeFree(node->unode.opr.op[0]); } /* }}} */ /* IF */ static NodeType *new_if(NodeType *expression, NodeType *instr) { /* {{{ */ NodeType *node = new_op("if", OPR_IF, 2); node->unode.opr.op[0] = expression; node->unode.opr.op[1] = instr; return node; } static void commit_if(NodeType *node) { char slab[1024]; sprintf(slab, "|eif%d|", allocateLabel()); commit_node(node->unode.opr.op[0],0); GSL_PUT_JZERO(slab,node->line_number); /* code */ commit_node(node->unode.opr.op[1],0); GSL_PUT_LABEL(slab,node->line_number); } /* }}} */ /* BLOCK */ static NodeType *new_block(NodeType *lastNode) { /* {{{ */ NodeType *blk = new_op("block", OPR_BLOCK, 2); blk->unode.opr.op[0] = new_nop("start_of_block"); blk->unode.opr.op[1] = lastNode; return blk; } static void commit_block(NodeType *node) { commit_node(node->unode.opr.op[0]->unode.opr.next,0); } /* }}} */ /* FUNCTION INTRO */ static NodeType *new_function_intro(const char *name) { /* {{{ */ char stmp[256]; if (strlen(name) < 200) { sprintf(stmp, "|__func_%s|", name); } return new_op(stmp, OPR_FUNC_INTRO, 0); } static void commit_function_intro(NodeType *node) { currentGoomSL->instr = gsl_instr_init(currentGoomSL, "label", INSTR_LABEL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL); #ifdef VERBOSE printf("label %s\n", node->str); #endif } /* }}} */ /* FUNCTION OUTRO */ static NodeType *new_function_outro() { /* {{{ */ return new_op("ret", OPR_FUNC_OUTRO, 0); } static void commit_function_outro(NodeType *node) { currentGoomSL->instr = gsl_instr_init(currentGoomSL, "ret", INSTR_RET, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, "|dummy|", TYPE_LABEL); releaseAllTemps(); #ifdef VERBOSE printf("ret\n"); #endif } /* }}} */ /* AFFECTATION LIST */ static NodeType *new_affec_list(NodeType *set, NodeType *next) /* {{{ */ { NodeType *node = new_op("affect_list", OPR_AFFECT_LIST, 2); node->unode.opr.op[0] = set; node->unode.opr.op[1] = next; return node; } static NodeType *new_affect_list_after(NodeType *affect_list) { NodeType *ret = NULL; NodeType *cur = affect_list; while(cur != NULL) { NodeType *set = cur->unode.opr.op[0]; NodeType *next = cur->unode.opr.op[1]; NodeType *lvalue = set->unode.opr.op[0]; NodeType *expression = set->unode.opr.op[1]; if ((lvalue->str[0] == '&') && (expression->type == VAR_NODE)) { NodeType *nset = new_set(nodeClone(expression), nodeClone(lvalue)); ret = new_affec_list(nset, ret); } cur = next; } return ret; } static void commit_affect_list(NodeType *node) { NodeType *cur = node; while(cur != NULL) { NodeType *set = cur->unode.opr.op[0]; precommit_node(set->unode.opr.op[0]); precommit_node(set->unode.opr.op[1]); cur = cur->unode.opr.op[1]; } cur = node; while(cur != NULL) { NodeType *set = cur->unode.opr.op[0]; commit_node(set,0); cur = cur->unode.opr.op[1]; } } /* }}} */ /* VAR LIST */ static NodeType *new_var_list(NodeType *var, NodeType *next) /* {{{ */ { NodeType *node = new_op("var_list", OPR_VAR_LIST, 2); node->unode.opr.op[0] = var; node->unode.opr.op[1] = next; return node; } static void commit_var_list(NodeType *node) { } /* }}} */ /* FUNCTION CALL */ static NodeType *new_call(const char *name, NodeType *affect_list) { /* {{{ */ HashValue *fval; fval = goom_hash_get(currentGoomSL->functions, name); if (!fval) { gsl_declare_task(name); fval = goom_hash_get(currentGoomSL->functions, name); } if (!fval) { fprintf(stderr, "ERROR: Line %d, Could not find function %s\n", currentGoomSL->num_lines, name); exit(1); return NULL; } else { ExternalFunctionStruct *gef = (ExternalFunctionStruct*)fval->ptr; if (gef->is_extern) { NodeType *node = new_op(name, OPR_EXT_CALL, 1); node->unode.opr.op[0] = affect_list; return node; } else { NodeType *node; char stmp[256]; if (strlen(name) < 200) { sprintf(stmp, "|__func_%s|", name); } node = new_op(stmp, OPR_CALL, 1); node->unode.opr.op[0] = affect_list; return node; } } } static void commit_ext_call(NodeType *node) { NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]); commit_node(node->unode.opr.op[0],0); currentGoomSL->instr = gsl_instr_init(currentGoomSL, "extcall", INSTR_EXT_CALL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR); #ifdef VERBOSE printf("extcall %s\n", node->str); #endif commit_node(alafter,0); } static void commit_call(NodeType *node) { NodeType *alafter = new_affect_list_after(node->unode.opr.op[0]); commit_node(node->unode.opr.op[0],0); currentGoomSL->instr = gsl_instr_init(currentGoomSL, "call", INSTR_CALL, 1, node->line_number); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_LABEL); #ifdef VERBOSE printf("call %s\n", node->str); #endif commit_node(alafter,0); } /* }}} */ /** **/ static NodeType *rootNode = 0; /* TODO: reinitialiser a chaque compilation. */ static NodeType *lastNode = 0; static NodeType *gsl_append(NodeType *curNode) { if (curNode == 0) return 0; /* {{{ */ if (lastNode) lastNode->unode.opr.next = curNode; lastNode = curNode; while(lastNode->unode.opr.next) lastNode = lastNode->unode.opr.next; if (rootNode == 0) rootNode = curNode; return curNode; } /* }}} */ #if 1 int allocateTemp(void) { return allocateLabel(); } void releaseAllTemps(void) {} void releaseTemp(int n) {} #else static int nbTemp = 0; static int *tempArray = 0; static int tempArraySize = 0; int allocateTemp(void) { /* TODO: allocateITemp, allocateFTemp */ int i = 0; /* {{{ */ if (tempArray == 0) { tempArraySize = 256; tempArray = (int*)malloc(tempArraySize * sizeof(int)); } while (1) { int j; for (j=0;j<nbTemp;++j) { if (tempArray[j] == i) break; } if (j == nbTemp) { if (nbTemp == tempArraySize) { tempArraySize *= 2; tempArray = (int*)realloc(tempArray,tempArraySize * sizeof(int)); } tempArray[nbTemp++] = i; return i; } i++; } } /* }}} */ void releaseAllTemps(void) { nbTemp = 0; /* {{{ */ } /* }}} */ void releaseTemp(int n) { int j; /* {{{ */ for (j=0;j<nbTemp;++j) { if (tempArray[j] == n) { tempArray[j] = tempArray[--nbTemp]; break; } } } /* }}} */ #endif static int lastLabel = 0; int allocateLabel(void) { return ++lastLabel; /* {{{ */ } /* }}} */ void gsl_commit_compilation() { /* {{{ */ commit_node(rootNode,0); rootNode = 0; lastNode = 0; } /* }}} */ void precommit_node(NodeType *node) { /* {{{ */ /* do here stuff for expression.. for exemple */ if (node->type == OPR_NODE) switch(node->unode.opr.type) { case OPR_ADD: precommit_add(node); break; case OPR_SUB: precommit_sub(node); break; case OPR_MUL: precommit_mul(node); break; case OPR_DIV: precommit_div(node); break; case OPR_CALL_EXPR: precommit_call_expr(node); break; } } /* }}} */ void commit_node(NodeType *node, int releaseIfTmp) { /* {{{ */ if (node == 0) return; switch(node->type) { case OPR_NODE: switch(node->unode.opr.type) { case OPR_SET: commit_set(node); break; case OPR_PLUS_EQ: commit_plus_eq(node); break; case OPR_SUB_EQ: commit_sub_eq(node); break; case OPR_MUL_EQ: commit_mul_eq(node); break; case OPR_DIV_EQ: commit_div_eq(node); break; case OPR_IF: commit_if(node); break; case OPR_WHILE: commit_while(node); break; case OPR_BLOCK: commit_block(node); break; case OPR_FUNC_INTRO: commit_function_intro(node); break; case OPR_FUNC_OUTRO: commit_function_outro(node); break; case OPR_CALL: commit_call(node); break; case OPR_EXT_CALL: commit_ext_call(node); break; case OPR_EQU: commit_equ(node); break; case OPR_LOW: commit_low(node); break; case OPR_NOT: commit_not(node); break; case OPR_AFFECT_LIST: commit_affect_list(node); break; case OPR_FOREACH: commit_foreach(node); break; case OPR_VAR_LIST: commit_var_list(node); break; #ifdef VERBOSE case EMPTY_NODE: printf("NOP\n"); break; #endif } commit_node(node->unode.opr.next,0); /* recursive for the moment, maybe better to do something iterative? */ break; case VAR_NODE: gsl_instr_set_namespace(currentGoomSL->instr, node->vnamespace); gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_VAR); break; case CONST_INT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_INTEGER); break; case CONST_FLOAT_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_FLOAT); break; case CONST_PTR_NODE: gsl_instr_add_param(currentGoomSL->instr, node->str, TYPE_PTR); break; } if (releaseIfTmp && is_tmp_expr(node)) releaseTemp(get_tmp_id(node)); nodeFree(node); } /* }}} */ NodeType *nodeNew(const char *str, int type, int line_number) { NodeType *node = (NodeType*)malloc(sizeof(NodeType)); /* {{{ */ node->type = type; node->str = (char*)malloc(strlen(str)+1); node->vnamespace = NULL; node->line_number = line_number; strcpy(node->str, str); return node; } /* }}} */ static NodeType *nodeClone(NodeType *node) { NodeType *ret = nodeNew(node->str, node->type, node->line_number); /* {{{ */ ret->vnamespace = node->vnamespace; ret->unode = node->unode; return ret; } /* }}} */ void nodeFreeInternals(NodeType *node) { free(node->str); /* {{{ */ } /* }}} */ void nodeFree(NodeType *node) { nodeFreeInternals(node); /* {{{ */ free(node); } /* }}} */ NodeType *new_constInt(const char *str, int line_number) { NodeType *node = nodeNew(str, CONST_INT_NODE, line_number); /* {{{ */ node->unode.constInt.val = atoi(str); return node; } /* }}} */ NodeType *new_constPtr(const char *str, int line_number) { NodeType *node = nodeNew(str, CONST_PTR_NODE, line_number); /* {{{ */ node->unode.constPtr.id = strtol(str,NULL,0); return node; } /* }}} */ NodeType *new_constFloat(const char *str, int line_number) { NodeType *node = nodeNew(str, CONST_FLOAT_NODE, line_number); /* {{{ */ node->unode.constFloat.val = atof(str); return node; } /* }}} */ NodeType *new_var(const char *str, int line_number) { NodeType *node = nodeNew(str, VAR_NODE, line_number); /* {{{ */ node->vnamespace = gsl_find_namespace(str); if (node->vnamespace == 0) { fprintf(stderr, "ERROR: Line %d, Variable not found: '%s'\n", line_number, str); exit(1); } return node; } /* }}} */ NodeType *new_nop(const char *str) { NodeType *node = new_op(str, EMPTY_NODE, 0); /* {{{ */ return node; } /* }}} */ NodeType *new_op(const char *str, int type, int nbOp) { int i; /* {{{ */ NodeType *node = nodeNew(str, OPR_NODE, currentGoomSL->num_lines); node->unode.opr.next = 0; node->unode.opr.type = type; node->unode.opr.nbOp = nbOp; for (i=0;i<nbOp;++i) node->unode.opr.op[i] = 0; return node; } /* }}} */ static void gsl_declare_global_variable(int type, char *name) { switch(type){ case -1: break; case FLOAT_TK:gsl_float_decl_global(name);break; case INT_TK: gsl_int_decl_global(name);break; case PTR_TK: gsl_ptr_decl_global(name);break; default: { int id = type - 1000; gsl_struct_decl_global_from_id(name,id); } } } /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #line 1199 "goomsl_yacc.y" typedef union YYSTYPE { int intValue; float floatValue; char charValue; char strValue[2048]; NodeType *nPtr; GoomHash *namespace; GSL_Struct *gsl_struct; GSL_StructField *gsl_struct_field; } YYSTYPE; /* Line 191 of yacc.c. */ #line 1327 "goomsl_yacc.c" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 214 of yacc.c. */ #line 1339 "goomsl_yacc.c" #if ! defined (yyoverflow) || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # if YYSTACK_USE_ALLOCA # define YYSTACK_ALLOC alloca # else # ifndef YYSTACK_USE_ALLOCA # if defined (alloca) || defined (_ALLOCA_H) # define YYSTACK_ALLOC alloca # else # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # else # if defined (__STDC__) || defined (__cplusplus) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif # define YYSTACK_ALLOC malloc # define YYSTACK_FREE free # endif #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ || (YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { short yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ register YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (0) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined (__STDC__) || defined (__cplusplus) typedef signed char yysigned_char; #else typedef short yysigned_char; #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 229 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 42 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 30 /* YYNRULES -- Number of rules. */ #define YYNRULES 89 /* YYNRULES -- Number of states. */ #define YYNSTATES 217 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 279 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const unsigned char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 25, 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, 35, 36, 32, 29, 34, 30, 2, 31, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 2, 27, 26, 28, 37, 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, 40, 2, 41, 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, 38, 2, 39, 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, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const unsigned short yyprhs[] = { 0, 0, 3, 7, 10, 19, 30, 39, 50, 53, 56, 57, 65, 68, 73, 76, 79, 82, 85, 87, 89, 90, 93, 96, 99, 102, 104, 108, 111, 112, 116, 122, 130, 131, 132, 137, 142, 147, 152, 154, 157, 160, 163, 166, 169, 172, 179, 186, 193, 195, 199, 203, 207, 211, 218, 222, 224, 227, 231, 232, 234, 236, 240, 244, 248, 252, 255, 259, 261, 265, 269, 273, 277, 281, 285, 288, 290, 292, 294, 298, 304, 310, 318, 323, 330, 333, 335, 340, 344, 346 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yysigned_char yyrhs[] = { 43, 0, -1, 44, 55, 52, -1, 44, 59, -1, 44, 11, 27, 48, 28, 50, 25, 56, -1, 44, 11, 27, 48, 33, 51, 28, 50, 25, 56, -1, 44, 10, 27, 49, 28, 50, 25, 56, -1, 44, 10, 27, 49, 33, 51, 28, 50, 25, 56, -1, 44, 45, -1, 44, 25, -1, -1, 22, 27, 5, 33, 46, 28, 25, -1, 71, 47, -1, 46, 34, 71, 47, -1, 8, 5, -1, 9, 5, -1, 7, 5, -1, 5, 5, -1, 5, -1, 5, -1, -1, 33, 8, -1, 33, 9, -1, 33, 7, -1, 33, 5, -1, 58, -1, 58, 34, 51, -1, 52, 53, -1, -1, 54, 44, 55, -1, 27, 49, 28, 50, 25, -1, 27, 49, 33, 51, 28, 50, 25, -1, -1, -1, 9, 5, 26, 64, -1, 8, 5, 26, 64, -1, 7, 5, 26, 64, -1, 5, 5, 26, 64, -1, 58, -1, 9, 5, -1, 8, 5, -1, 7, 5, -1, 5, 5, -1, 62, 25, -1, 57, 25, -1, 35, 65, 36, 37, 71, 59, -1, 12, 65, 71, 13, 71, 59, -1, 38, 25, 63, 44, 39, 25, -1, 67, -1, 5, 15, 64, -1, 5, 16, 64, -1, 5, 18, 64, -1, 5, 17, 64, -1, 23, 5, 24, 60, 13, 59, -1, 35, 61, 36, -1, 5, -1, 5, 61, -1, 5, 26, 64, -1, -1, 5, -1, 66, -1, 64, 32, 64, -1, 64, 31, 64, -1, 64, 29, 64, -1, 64, 30, 64, -1, 30, 64, -1, 35, 64, 36, -1, 68, -1, 64, 26, 64, -1, 64, 27, 64, -1, 64, 28, 64, -1, 64, 19, 64, -1, 64, 20, 64, -1, 64, 21, 64, -1, 14, 65, -1, 4, -1, 3, -1, 6, -1, 49, 25, 56, -1, 49, 33, 69, 25, 56, -1, 40, 49, 41, 25, 56, -1, 40, 49, 33, 69, 41, 25, 56, -1, 40, 49, 56, 41, -1, 40, 49, 33, 69, 41, 56, -1, 70, 69, -1, 70, -1, 5, 26, 56, 64, -1, 33, 56, 64, -1, 25, -1, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const unsigned short yyrline[] = { 0, 1236, 1236, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1250, 1253, 1254, 1257, 1258, 1259, 1260, 1265, 1267, 1270, 1271, 1272, 1273, 1274, 1277, 1278, 1283, 1284, 1287, 1289, 1291, 1294, 1296, 1300, 1301, 1302, 1303, 1304, 1307, 1308, 1309, 1310, 1315, 1316, 1317, 1318, 1319, 1320, 1321, 1322, 1323, 1324, 1325, 1328, 1330, 1331, 1334, 1336, 1339, 1340, 1341, 1342, 1343, 1344, 1345, 1346, 1347, 1350, 1351, 1352, 1353, 1354, 1355, 1356, 1359, 1360, 1361, 1366, 1367, 1368, 1369, 1373, 1374, 1377, 1378, 1380, 1384, 1393, 1393 }; #endif #if YYDEBUG || YYERROR_VERBOSE /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "LTYPE_INTEGER", "LTYPE_FLOAT", "LTYPE_VAR", "LTYPE_PTR", "PTR_TK", "INT_TK", "FLOAT_TK", "DECLARE", "EXTERNAL", "WHILE", "DO", "NOT", "PLUS_EQ", "SUB_EQ", "DIV_EQ", "MUL_EQ", "SUP_EQ", "LOW_EQ", "NOT_EQ", "STRUCT", "FOR", "IN", "'\\n'", "'='", "'<'", "'>'", "'+'", "'-'", "'/'", "'*'", "':'", "','", "'('", "')'", "'?'", "'{'", "'}'", "'['", "']'", "$accept", "gsl", "gsl_code", "struct_declaration", "struct_members", "struct_member", "ext_task_name", "task_name", "return_type", "arglist", "gsl_def_functions", "function", "function_intro", "function_outro", "leave_namespace", "declaration", "empty_declaration", "instruction", "var_list", "var_list_content", "affectation", "start_block", "expression", "test", "constValue", "func_call", "func_call_expression", "affectation_list", "affectation_in_list", "opt_nl", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const unsigned short yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 10, 61, 60, 62, 43, 45, 47, 42, 58, 44, 40, 41, 63, 123, 125, 91, 93 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const unsigned char yyr1[] = { 0, 42, 43, 44, 44, 44, 44, 44, 44, 44, 44, 45, 46, 46, 47, 47, 47, 47, 48, 49, 50, 50, 50, 50, 50, 51, 51, 52, 52, 53, 54, 54, 55, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 61, 61, 62, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const unsigned char yyr2[] = { 0, 2, 3, 2, 8, 10, 8, 10, 2, 2, 0, 7, 2, 4, 2, 2, 2, 2, 1, 1, 0, 2, 2, 2, 2, 1, 3, 2, 0, 3, 5, 7, 0, 0, 4, 4, 4, 4, 1, 2, 2, 2, 2, 2, 2, 6, 6, 6, 1, 3, 3, 3, 3, 6, 3, 1, 2, 3, 0, 1, 1, 3, 3, 3, 3, 2, 3, 1, 3, 3, 3, 3, 3, 3, 2, 1, 1, 1, 3, 5, 5, 7, 4, 6, 2, 1, 4, 3, 1, 0 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const unsigned char yydefact[] = { 10, 0, 32, 1, 19, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 8, 0, 28, 0, 38, 3, 0, 48, 42, 0, 0, 0, 0, 0, 41, 40, 39, 0, 0, 76, 75, 59, 77, 0, 0, 0, 0, 0, 89, 60, 67, 0, 0, 0, 58, 19, 0, 33, 0, 2, 44, 43, 0, 49, 50, 52, 51, 57, 0, 0, 0, 0, 18, 0, 74, 65, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 10, 0, 0, 78, 0, 33, 0, 85, 0, 27, 10, 37, 36, 35, 34, 20, 0, 20, 0, 66, 0, 0, 71, 72, 73, 68, 69, 70, 63, 64, 62, 61, 89, 89, 0, 0, 89, 0, 0, 33, 33, 0, 33, 84, 0, 32, 0, 0, 0, 0, 0, 0, 0, 25, 0, 0, 0, 82, 0, 0, 0, 55, 0, 0, 0, 0, 0, 80, 0, 87, 79, 20, 0, 29, 24, 23, 21, 22, 33, 42, 41, 40, 39, 20, 0, 33, 20, 33, 46, 0, 89, 0, 0, 0, 0, 12, 56, 54, 53, 45, 47, 33, 86, 0, 0, 6, 0, 26, 4, 0, 83, 11, 0, 17, 16, 14, 15, 81, 30, 20, 33, 33, 13, 0, 7, 5, 31 }; /* YYDEFGOTO[NTERM-NUM]. */ static const short yydefgoto[] = { -1, 1, 2, 17, 149, 185, 70, 18, 137, 142, 56, 99, 100, 19, 93, 20, 21, 22, 125, 152, 23, 90, 44, 45, 46, 24, 47, 96, 97, 86 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -116 static const short yypact[] = { -116, 40, 136, -116, 103, 39, 66, 68, 61, 65, 1, 77, 101, -116, 1, 84, 109, -116, 12, -116, 91, -116, -116, 97, -116, 98, 72, 72, 72, 72, 72, 99, 104, 113, 109, 130, -116, -116, -116, -116, 1, 72, 72, 109, 166, 115, -116, -116, 145, 131, 118, -116, -116, -24, -116, -3, 138, -116, -116, 72, 159, 159, 159, 159, 159, 72, 72, 72, 14, -116, 51, -116, 22, 102, 124, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, -116, 160, 139, 140, 141, -116, -3, 152, -116, 154, -116, 156, -3, 109, -116, -116, 159, 159, 159, 159, 150, 82, 150, 82, -116, -3, 158, 159, 159, 159, 159, 159, 159, 22, 22, -116, -116, 115, 115, 195, 188, 115, 88, 162, -116, -116, 72, -116, -116, 52, 136, 155, 177, 199, 200, 201, 202, 180, 175, 185, 183, 171, -116, 144, 18, 161, 195, 178, 144, 144, 190, 191, -116, 72, 159, -116, 150, 82, -116, -116, -116, -116, -116, -116, -116, -116, -116, -116, 150, 82, -116, 150, -116, -116, 192, 115, 208, 213, 214, 215, -116, -116, -116, -116, -116, -116, -116, 159, 196, 194, -116, 198, -116, -116, 203, -116, -116, 161, -116, -116, -116, -116, -116, -116, 150, -116, -116, -116, 204, -116, -116, -116 }; /* YYPGOTO[NTERM-NUM]. */ static const yysigned_char yypgoto[] = { -116, -116, -68, -116, -116, 23, -116, -15, -104, -92, -116, -116, -116, 89, -74, -116, -88, -115, -116, 75, -116, -116, -16, -6, -116, -116, -116, -62, -116, -99 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -1 static const unsigned char yytable[] = { 111, 53, 94, 144, 36, 37, 38, 39, 50, 91, 60, 61, 62, 63, 64, 40, 145, 92, 143, 68, 143, 131, 127, 148, 150, 72, 73, 154, 74, 128, 95, 41, 135, 178, 71, 133, 42, 54, 188, 189, 3, 43, 105, 101, 31, 55, 179, 106, 146, 102, 103, 104, 180, 83, 84, 157, 158, 193, 160, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 196, 194, 32, 199, 33, 143, 36, 37, 38, 39, 107, 161, 202, 197, 134, 108, 162, 143, 138, 34, 139, 140, 141, 35, 4, 195, 5, 6, 7, 8, 9, 10, 198, 41, 200, 48, 213, 49, 42, 25, 51, 11, 12, 43, 13, 52, 159, 57, 207, 26, 27, 28, 29, 58, 14, 59, 65, 15, 155, 16, 30, 66, 81, 82, 83, 84, 69, 214, 215, 109, 67, 85, 4, 192, 5, 6, 7, 8, 9, 10, 4, 87, 5, 6, 7, 89, 88, 10, 110, 11, 12, 164, 13, 165, 166, 167, 98, 181, 12, 182, 183, 184, 14, 123, 122, 15, 124, 16, 129, 126, 14, 130, 132, 15, 136, 16, 75, 76, 77, 81, 82, 83, 84, 78, 79, 80, 81, 82, 83, 84, 147, 151, 153, 168, 156, 169, 170, 171, 172, 173, 174, 175, 176, 177, 203, 187, 190, 191, 201, 204, 205, 206, 208, 209, 210, 163, 212, 186, 0, 211, 216 }; static const short yycheck[] = { 74, 16, 5, 107, 3, 4, 5, 6, 14, 33, 26, 27, 28, 29, 30, 14, 108, 41, 106, 34, 108, 95, 90, 122, 123, 41, 42, 126, 43, 91, 33, 30, 100, 148, 40, 97, 35, 25, 153, 154, 0, 40, 28, 59, 5, 33, 28, 33, 110, 65, 66, 67, 34, 31, 32, 129, 130, 161, 132, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 173, 162, 5, 176, 5, 162, 3, 4, 5, 6, 28, 28, 180, 174, 98, 33, 33, 174, 5, 27, 7, 8, 9, 27, 5, 168, 7, 8, 9, 10, 11, 12, 175, 30, 177, 27, 209, 5, 35, 5, 25, 22, 23, 40, 25, 5, 131, 25, 191, 15, 16, 17, 18, 25, 35, 26, 26, 38, 39, 40, 26, 26, 29, 30, 31, 32, 5, 210, 211, 36, 26, 25, 5, 158, 7, 8, 9, 10, 11, 12, 5, 5, 7, 8, 9, 36, 24, 12, 33, 22, 23, 5, 25, 7, 8, 9, 27, 5, 23, 7, 8, 9, 35, 33, 13, 38, 35, 40, 25, 37, 35, 26, 25, 38, 33, 40, 19, 20, 21, 29, 30, 31, 32, 26, 27, 28, 29, 30, 31, 32, 41, 5, 13, 25, 41, 5, 5, 5, 5, 28, 34, 25, 28, 41, 5, 36, 25, 25, 25, 5, 5, 5, 25, 28, 25, 135, 202, 151, -1, 25, 25 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const unsigned char yystos[] = { 0, 43, 44, 0, 5, 7, 8, 9, 10, 11, 12, 22, 23, 25, 35, 38, 40, 45, 49, 55, 57, 58, 59, 62, 67, 5, 15, 16, 17, 18, 26, 5, 5, 5, 27, 27, 3, 4, 5, 6, 14, 30, 35, 40, 64, 65, 66, 68, 27, 5, 65, 25, 5, 49, 25, 33, 52, 25, 25, 26, 64, 64, 64, 64, 64, 26, 26, 26, 49, 5, 48, 65, 64, 64, 49, 19, 20, 21, 26, 27, 28, 29, 30, 31, 32, 25, 71, 5, 24, 36, 63, 33, 41, 56, 5, 33, 69, 70, 27, 53, 54, 64, 64, 64, 64, 28, 33, 28, 33, 36, 33, 56, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 13, 33, 35, 60, 37, 44, 69, 25, 26, 56, 25, 69, 49, 44, 33, 50, 5, 7, 8, 9, 51, 58, 50, 51, 69, 41, 71, 46, 71, 5, 61, 13, 71, 39, 41, 56, 56, 64, 56, 28, 33, 55, 5, 7, 8, 9, 25, 5, 5, 5, 5, 28, 34, 25, 28, 41, 59, 28, 34, 5, 7, 8, 9, 47, 61, 36, 59, 59, 25, 25, 64, 50, 51, 56, 50, 51, 56, 50, 56, 25, 71, 5, 5, 5, 5, 56, 25, 28, 25, 25, 47, 50, 56, 56, 25 }; #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ #endif #if ! defined (YYSIZE_T) && defined (size_t) # define YYSIZE_T size_t #endif #if ! defined (YYSIZE_T) # if defined (__STDC__) || defined (__cplusplus) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif #endif #if ! defined (YYSIZE_T) # define YYSIZE_T unsigned int #endif #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ { \ yyerror ("syntax error: cannot back up");\ YYERROR; \ } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ Current.first_line = Rhs[1].first_line; \ Current.first_column = Rhs[1].first_column; \ Current.last_line = Rhs[N].last_line; \ Current.last_column = Rhs[N].last_column; #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else # define YYLEX yylex () #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) # define YYDSYMPRINT(Args) \ do { \ if (yydebug) \ yysymprint Args; \ } while (0) # define YYDSYMPRINTF(Title, Token, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yysymprint (stderr, \ Token, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (cinluded). | `------------------------------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yy_stack_print (short *bottom, short *top) #else static void yy_stack_print (bottom, top) short *bottom; short *top; #endif { YYFPRINTF (stderr, "Stack now"); for (/* Nothing. */; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yy_reduce_print (int yyrule) #else static void yy_reduce_print (yyrule) int yyrule; #endif { int yyi; unsigned int yylineno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", yyrule - 1, yylineno); /* Print the symbols being reduced, and their result. */ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YYDSYMPRINT(Args) # define YYDSYMPRINTF(Title, Token, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #if YYMAXDEPTH == 0 # undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined (__GLIBC__) && defined (_STRING_H) # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T # if defined (__STDC__) || defined (__cplusplus) yystrlen (const char *yystr) # else yystrlen (yystr) const char *yystr; # endif { register const char *yys = yystr; while (*yys++ != '\0') continue; return yys - yystr - 1; } # endif # endif # ifndef yystpcpy # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * # if defined (__STDC__) || defined (__cplusplus) yystpcpy (char *yydest, const char *yysrc) # else yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; # endif { register char *yyd = yydest; register const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif #endif /* !YYERROR_VERBOSE */ #if YYDEBUG /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) #else static void yysymprint (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE *yyvaluep; #endif { /* Pacify ``unused variable'' warnings. */ (void) yyvaluep; if (yytype < YYNTOKENS) { YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); # ifdef YYPRINT YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif } else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); switch (yytype) { default: break; } YYFPRINTF (yyoutput, ")"); } #endif /* ! YYDEBUG */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yydestruct (int yytype, YYSTYPE *yyvaluep) #else static void yydestruct (yytype, yyvaluep) int yytype; YYSTYPE *yyvaluep; #endif { /* Pacify ``unused variable'' warnings. */ (void) yyvaluep; switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM # if defined (__STDC__) || defined (__cplusplus) int yyparse (void *YYPARSE_PARAM); # else int yyparse (); # endif #else /* ! YYPARSE_PARAM */ #if defined (__STDC__) || defined (__cplusplus) int yyparse (void); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM # if defined (__STDC__) || defined (__cplusplus) int yyparse (void *YYPARSE_PARAM) # else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; # endif #else /* ! YYPARSE_PARAM */ #if defined (__STDC__) || defined (__cplusplus) int yyparse (void) #else int yyparse () #endif #endif { register int yystate; register int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; register YYSTYPE *yyvsp; #define YYPOPSTACK (yyvsp--, yyssp--) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* When reducing, the number of symbols on the RHS of the reduced rule. */ int yylen; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; short *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow ("parser stack overflow", &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyoverflowlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyoverflowlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { short *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyoverflowlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* yyresume: */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 3: #line 1238 "goomsl_yacc.y" { gsl_append(yyvsp[0].nPtr); } break; case 4: #line 1239 "goomsl_yacc.y" { gsl_declare_global_variable(yyvsp[-2].intValue,yyvsp[-4].strValue); } break; case 5: #line 1240 "goomsl_yacc.y" { gsl_declare_global_variable(yyvsp[-2].intValue,yyvsp[-6].strValue); } break; case 6: #line 1241 "goomsl_yacc.y" { gsl_declare_global_variable(yyvsp[-2].intValue,yyvsp[-4].strValue); } break; case 7: #line 1242 "goomsl_yacc.y" { gsl_declare_global_variable(yyvsp[-2].intValue,yyvsp[-6].strValue); } break; case 11: #line 1250 "goomsl_yacc.y" { gsl_add_struct(yyvsp[-4].strValue, yyvsp[-2].gsl_struct); } break; case 12: #line 1253 "goomsl_yacc.y" { yyval.gsl_struct = gsl_new_struct(yyvsp[0].gsl_struct_field); } break; case 13: #line 1254 "goomsl_yacc.y" { yyval.gsl_struct = yyvsp[-3].gsl_struct; gsl_add_struct_field(yyvsp[-3].gsl_struct, yyvsp[0].gsl_struct_field); } break; case 14: #line 1257 "goomsl_yacc.y" { yyval.gsl_struct_field = gsl_new_struct_field(yyvsp[0].strValue, INSTR_INT); } break; case 15: #line 1258 "goomsl_yacc.y" { yyval.gsl_struct_field = gsl_new_struct_field(yyvsp[0].strValue, INSTR_FLOAT); } break; case 16: #line 1259 "goomsl_yacc.y" { yyval.gsl_struct_field = gsl_new_struct_field(yyvsp[0].strValue, INSTR_PTR); } break; case 17: #line 1260 "goomsl_yacc.y" { yyval.gsl_struct_field = gsl_new_struct_field_struct(yyvsp[0].strValue, yyvsp[-1].strValue); } break; case 18: #line 1265 "goomsl_yacc.y" { gsl_declare_external_task(yyvsp[0].strValue); gsl_enternamespace(yyvsp[0].strValue); strcpy(yyval.strValue,yyvsp[0].strValue); } break; case 19: #line 1267 "goomsl_yacc.y" { gsl_declare_task(yyvsp[0].strValue); gsl_enternamespace(yyvsp[0].strValue); strcpy(yyval.strValue,yyvsp[0].strValue); strcpy(yyval.strValue,yyvsp[0].strValue); } break; case 20: #line 1270 "goomsl_yacc.y" { yyval.intValue=-1; } break; case 21: #line 1271 "goomsl_yacc.y" { yyval.intValue=INT_TK; } break; case 22: #line 1272 "goomsl_yacc.y" { yyval.intValue=FLOAT_TK; } break; case 23: #line 1273 "goomsl_yacc.y" { yyval.intValue=PTR_TK; } break; case 24: #line 1274 "goomsl_yacc.y" { yyval.intValue= 1000 + gsl_get_struct_id(yyvsp[0].strValue); } break; case 29: #line 1287 "goomsl_yacc.y" { gsl_leavenamespace(); } break; case 30: #line 1289 "goomsl_yacc.y" { gsl_append(new_function_intro(yyvsp[-3].strValue)); gsl_declare_global_variable(yyvsp[-1].intValue,yyvsp[-3].strValue); } break; case 31: #line 1291 "goomsl_yacc.y" { gsl_append(new_function_intro(yyvsp[-5].strValue)); gsl_declare_global_variable(yyvsp[-1].intValue,yyvsp[-5].strValue); } break; case 32: #line 1294 "goomsl_yacc.y" { gsl_append(new_function_outro()); } break; case 33: #line 1296 "goomsl_yacc.y" { yyval.namespace = gsl_leavenamespace(); } break; case 34: #line 1300 "goomsl_yacc.y" { gsl_float_decl_local(yyvsp[-2].strValue); yyval.nPtr = new_set(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines), yyvsp[0].nPtr); } break; case 35: #line 1301 "goomsl_yacc.y" { gsl_int_decl_local(yyvsp[-2].strValue); yyval.nPtr = new_set(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines), yyvsp[0].nPtr); } break; case 36: #line 1302 "goomsl_yacc.y" { gsl_ptr_decl_local(yyvsp[-2].strValue); yyval.nPtr = new_set(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines), yyvsp[0].nPtr); } break; case 37: #line 1303 "goomsl_yacc.y" { gsl_struct_decl_local(yyvsp[-3].strValue,yyvsp[-2].strValue); yyval.nPtr = new_set(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines), yyvsp[0].nPtr); } break; case 38: #line 1304 "goomsl_yacc.y" { yyval.nPtr = 0; } break; case 39: #line 1307 "goomsl_yacc.y" { gsl_float_decl_local(yyvsp[0].strValue); } break; case 40: #line 1308 "goomsl_yacc.y" { gsl_int_decl_local(yyvsp[0].strValue); } break; case 41: #line 1309 "goomsl_yacc.y" { gsl_ptr_decl_local(yyvsp[0].strValue); } break; case 42: #line 1310 "goomsl_yacc.y" { gsl_struct_decl_local(yyvsp[-1].strValue,yyvsp[0].strValue); } break; case 43: #line 1315 "goomsl_yacc.y" { yyval.nPtr = yyvsp[-1].nPtr; } break; case 44: #line 1316 "goomsl_yacc.y" { yyval.nPtr = yyvsp[-1].nPtr; } break; case 45: #line 1317 "goomsl_yacc.y" { yyval.nPtr = new_if(yyvsp[-4].nPtr,yyvsp[0].nPtr); } break; case 46: #line 1318 "goomsl_yacc.y" { yyval.nPtr = new_while(yyvsp[-4].nPtr,yyvsp[0].nPtr); } break; case 47: #line 1319 "goomsl_yacc.y" { lastNode = yyvsp[-3].nPtr->unode.opr.op[1]; yyval.nPtr=yyvsp[-3].nPtr; } break; case 48: #line 1320 "goomsl_yacc.y" { yyval.nPtr = yyvsp[0].nPtr; } break; case 49: #line 1321 "goomsl_yacc.y" { yyval.nPtr = new_plus_eq(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines),yyvsp[0].nPtr); } break; case 50: #line 1322 "goomsl_yacc.y" { yyval.nPtr = new_sub_eq(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines),yyvsp[0].nPtr); } break; case 51: #line 1323 "goomsl_yacc.y" { yyval.nPtr = new_mul_eq(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines),yyvsp[0].nPtr); } break; case 52: #line 1324 "goomsl_yacc.y" { yyval.nPtr = new_div_eq(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines),yyvsp[0].nPtr); } break; case 53: #line 1325 "goomsl_yacc.y" { yyval.nPtr = new_static_foreach(new_var(yyvsp[-4].strValue, currentGoomSL->num_lines), yyvsp[-2].nPtr, yyvsp[0].nPtr); } break; case 54: #line 1328 "goomsl_yacc.y" { yyval.nPtr = yyvsp[-1].nPtr; } break; case 55: #line 1330 "goomsl_yacc.y" { yyval.nPtr = new_var_list(new_var(yyvsp[0].strValue,currentGoomSL->num_lines), NULL); } break; case 56: #line 1331 "goomsl_yacc.y" { yyval.nPtr = new_var_list(new_var(yyvsp[-1].strValue,currentGoomSL->num_lines), yyvsp[0].nPtr); } break; case 57: #line 1334 "goomsl_yacc.y" { yyval.nPtr = new_set(new_var(yyvsp[-2].strValue,currentGoomSL->num_lines),yyvsp[0].nPtr); } break; case 58: #line 1336 "goomsl_yacc.y" { yyval.nPtr = new_block(lastNode); lastNode = yyval.nPtr->unode.opr.op[0]; } break; case 59: #line 1339 "goomsl_yacc.y" { yyval.nPtr = new_var(yyvsp[0].strValue,currentGoomSL->num_lines); } break; case 60: #line 1340 "goomsl_yacc.y" { yyval.nPtr = yyvsp[0].nPtr; } break; case 61: #line 1341 "goomsl_yacc.y" { yyval.nPtr = new_mul(yyvsp[-2].nPtr,yyvsp[0].nPtr); } break; case 62: #line 1342 "goomsl_yacc.y" { yyval.nPtr = new_div(yyvsp[-2].nPtr,yyvsp[0].nPtr); } break; case 63: #line 1343 "goomsl_yacc.y" { yyval.nPtr = new_add(yyvsp[-2].nPtr,yyvsp[0].nPtr); } break; case 64: #line 1344 "goomsl_yacc.y" { yyval.nPtr = new_sub(yyvsp[-2].nPtr,yyvsp[0].nPtr); } break; case 65: #line 1345 "goomsl_yacc.y" { yyval.nPtr = new_neg(yyvsp[0].nPtr); } break; case 66: #line 1346 "goomsl_yacc.y" { yyval.nPtr = yyvsp[-1].nPtr; } break; case 67: #line 1347 "goomsl_yacc.y" { yyval.nPtr = yyvsp[0].nPtr; } break; case 68: #line 1350 "goomsl_yacc.y" { yyval.nPtr = new_equ(yyvsp[-2].nPtr,yyvsp[0].nPtr); } break; case 69: #line 1351 "goomsl_yacc.y" { yyval.nPtr = new_low(yyvsp[-2].nPtr,yyvsp[0].nPtr); } break; case 70: #line 1352 "goomsl_yacc.y" { yyval.nPtr = new_low(yyvsp[0].nPtr,yyvsp[-2].nPtr); } break; case 71: #line 1353 "goomsl_yacc.y" { yyval.nPtr = new_not(new_low(yyvsp[-2].nPtr,yyvsp[0].nPtr)); } break; case 72: #line 1354 "goomsl_yacc.y" { yyval.nPtr = new_not(new_low(yyvsp[0].nPtr,yyvsp[-2].nPtr)); } break; case 73: #line 1355 "goomsl_yacc.y" { yyval.nPtr = new_not(new_equ(yyvsp[-2].nPtr,yyvsp[0].nPtr)); } break; case 74: #line 1356 "goomsl_yacc.y" { yyval.nPtr = new_not(yyvsp[0].nPtr); } break; case 75: #line 1359 "goomsl_yacc.y" { yyval.nPtr = new_constFloat(yyvsp[0].strValue,currentGoomSL->num_lines); } break; case 76: #line 1360 "goomsl_yacc.y" { yyval.nPtr = new_constInt(yyvsp[0].strValue,currentGoomSL->num_lines); } break; case 77: #line 1361 "goomsl_yacc.y" { yyval.nPtr = new_constPtr(yyvsp[0].strValue,currentGoomSL->num_lines); } break; case 78: #line 1366 "goomsl_yacc.y" { yyval.nPtr = new_call(yyvsp[-2].strValue,NULL); } break; case 79: #line 1367 "goomsl_yacc.y" { yyval.nPtr = new_call(yyvsp[-4].strValue,yyvsp[-2].nPtr); } break; case 80: #line 1368 "goomsl_yacc.y" { yyval.nPtr = new_call(yyvsp[-3].strValue,NULL); } break; case 81: #line 1369 "goomsl_yacc.y" { yyval.nPtr = new_call(yyvsp[-5].strValue,yyvsp[-3].nPtr); } break; case 82: #line 1373 "goomsl_yacc.y" { yyval.nPtr = new_call_expr(yyvsp[-2].strValue,NULL); } break; case 83: #line 1374 "goomsl_yacc.y" { yyval.nPtr = new_call_expr(yyvsp[-4].strValue,yyvsp[-2].nPtr); } break; case 84: #line 1377 "goomsl_yacc.y" { yyval.nPtr = new_affec_list(yyvsp[-1].nPtr,yyvsp[0].nPtr); } break; case 85: #line 1378 "goomsl_yacc.y" { yyval.nPtr = new_affec_list(yyvsp[0].nPtr,NULL); } break; case 86: #line 1380 "goomsl_yacc.y" { gsl_reenternamespace(yyvsp[-1].namespace); yyval.nPtr = new_set(new_var(yyvsp[-3].strValue,currentGoomSL->num_lines),yyvsp[0].nPtr); } break; case 87: #line 1384 "goomsl_yacc.y" { gsl_reenternamespace(yyvsp[-1].namespace); yyval.nPtr = new_set(new_var("&this", currentGoomSL->num_lines),yyvsp[0].nPtr); } break; } /* Line 999 of yacc.c. */ #line 2792 "goomsl_yacc.c" yyvsp -= yylen; yyssp -= yylen; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if YYERROR_VERBOSE yyn = yypact[yystate]; if (YYPACT_NINF < yyn && yyn < YYLAST) { YYSIZE_T yysize = 0; int yytype = YYTRANSLATE (yychar); char *yymsg; int yyx, yycount; yycount = 0; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) yysize += yystrlen (yytname[yyx]) + 15, yycount++; yysize += yystrlen ("syntax error, unexpected ") + 1; yysize += yystrlen (yytname[yytype]); yymsg = (char *) YYSTACK_ALLOC (yysize); if (yymsg != 0) { char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); yyp = yystpcpy (yyp, yytname[yytype]); if (yycount < 5) { yycount = 0; for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { const char *yyq = ! yycount ? ", expecting " : " or "; yyp = yystpcpy (yyp, yyq); yyp = yystpcpy (yyp, yytname[yyx]); yycount++; } } yyerror (yymsg); YYSTACK_FREE (yymsg); } else yyerror ("syntax error; also virtual memory exhausted"); } else #endif /* YYERROR_VERBOSE */ yyerror ("syntax error"); } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ /* Return failure if at end of input. */ if (yychar == YYEOF) { /* Pop the error token. */ YYPOPSTACK; /* Pop the rest of the stack. */ while (yyss < yyssp) { YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[*yyssp], yyvsp); YYPOPSTACK; } YYABORT; } YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); yydestruct (yytoken, &yylval); yychar = YYEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*----------------------------------------------------. | yyerrlab1 -- error raised explicitly by an action. | `----------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[yystate], yyvsp); yyvsp--; yystate = *--yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*----------------------------------------------. | yyoverflowlab -- parser overflow comes here. | `----------------------------------------------*/ yyoverflowlab: yyerror ("parser stack overflow"); yyresult = 2; /* Fall through. */ #endif yyreturn: #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif return yyresult; } #line 1396 "goomsl_yacc.y" void yyerror(const char *str) { /* {{{ */ fprintf(stderr, "ERROR: Line %d, %s\n", currentGoomSL->num_lines, str); currentGoomSL->compilationOK = 0; exit(1); } /* }}} */ ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/sound_tester.c�����������������������������������������������������������0000644�0001750�0001750�00000007541�14647725152�016272� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "sound_tester.h" #include <stdlib.h> #include <string.h> /* some constants */ #define BIG_GOOM_DURATION 100 #define BIG_GOOM_SPEED_LIMIT 0.1f #define ACCEL_MULT 0.95f #define SPEED_MULT 0.99f void evaluate_sound(gint16 data[2][512], SoundInfo *info) { int i; float difaccel; float prevspeed; /* find the max */ int incvar = 0; for (i = 0; i < 512; i+=2) { if (incvar < data[0][i]) incvar = data[0][i]; } if (incvar > info->allTimesMax) info->allTimesMax = incvar; /* volume sonore */ info->volume = (float)incvar / (float)info->allTimesMax; memcpy(info->samples[0],data[0],512*sizeof(short)); memcpy(info->samples[1],data[1],512*sizeof(short)); difaccel = info->accelvar; info->accelvar = info->volume; /* accel entre 0 et 1 */ /* transformations sur la vitesse du son */ if (info->speedvar > 1.0f) info->speedvar = 1.0f; if (info->speedvar < 0.1f) info->accelvar *= (1.0f - (float)info->speedvar); else if (info->speedvar < 0.3f) info->accelvar *= (0.9f - (float)(info->speedvar-0.1f)/2.0f); else info->accelvar *= (0.8f - (float)(info->speedvar-0.3f)/4.0f); /* adoucissement de l'acceleration */ info->accelvar *= ACCEL_MULT; if (info->accelvar < 0) info->accelvar = 0; difaccel = info->accelvar - difaccel; if (difaccel < 0) difaccel = - difaccel; /* mise a jour de la vitesse */ prevspeed = info->speedvar; info->speedvar = (info->speedvar + difaccel * 0.5f) / 2; info->speedvar *= SPEED_MULT; info->speedvar = (info->speedvar + 3.0f * prevspeed) / 4.0f; if (info->speedvar < 0) info->speedvar = 0; if (info->speedvar > 1) info->speedvar = 1; /* temps du goom */ info->timeSinceLastGoom++; info->timeSinceLastBigGoom++; info->cycle++; /* detection des nouveaux gooms */ if ((info->speedvar > (float)IVAL(info->biggoom_speed_limit_p)/100.0f) && (info->accelvar > info->bigGoomLimit) && (info->timeSinceLastBigGoom > BIG_GOOM_DURATION)) { info->timeSinceLastBigGoom = 0; } if (info->accelvar > info->goom_limit) { /* TODO: tester && (info->timeSinceLastGoom > 20)) { */ info->totalgoom ++; info->timeSinceLastGoom = 0; info->goomPower = info->accelvar - info->goom_limit; } if (info->accelvar > info->prov_max) info->prov_max = info->accelvar; if (info->goom_limit>1) info->goom_limit=1; /* toute les 2 secondes : vérifier si le taux de goom est correct * et le modifier sinon.. */ if (info->cycle % 64 == 0) { if (info->speedvar<0.01f) info->goom_limit *= 0.91; if (info->totalgoom > 4) { info->goom_limit+=0.02; } if (info->totalgoom > 7) { info->goom_limit*=1.03f; info->goom_limit+=0.03; } if (info->totalgoom > 16) { info->goom_limit*=1.05f; info->goom_limit+=0.04; } if (info->totalgoom == 0) { info->goom_limit = info->prov_max - 0.02; } if ((info->totalgoom == 1) && (info->goom_limit > 0.02)) info->goom_limit-=0.01; info->totalgoom = 0; info->bigGoomLimit = info->goom_limit * (1.0f + (float)IVAL(info->biggoom_factor_p)/500.0f); info->prov_max = 0; } /* mise a jour des parametres pour la GUI */ FVAL(info->volume_p) = info->volume; info->volume_p.change_listener(&info->volume_p); FVAL(info->speed_p) = info->speedvar * 4; info->speed_p.change_listener(&info->speed_p); FVAL(info->accel_p) = info->accelvar; info->accel_p.change_listener(&info->accel_p); FVAL(info->goom_limit_p) = info->goom_limit; info->goom_limit_p.change_listener(&info->goom_limit_p); FVAL(info->goom_power_p) = info->goomPower; info->goom_power_p.change_listener(&info->goom_power_p); FVAL(info->last_goom_p) = 1.0-((float)info->timeSinceLastGoom/20.0f); info->last_goom_p.change_listener(&info->last_goom_p); FVAL(info->last_biggoom_p) = 1.0-((float)info->timeSinceLastBigGoom/40.0f); info->last_biggoom_p.change_listener(&info->last_biggoom_p); /* bigGoomLimit ==goomLimit*9/8+7 ? */ } ���������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/v3d.h��������������������������������������������������������������������0000644�0001750�0001750�00000002221�14647725152�014243� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _V3D_H #define _V3D_H #include <math.h> #include <stdlib.h> #include <stdio.h> #include "mathtools.h" typedef struct { float x,y,z; } v3d; typedef struct { int x,y; } v2d; typedef struct { double x,y; } v2g; /* * projete le vertex 3D sur le plan d'affichage * retourne (0,0) si le point ne doit pas etre affiche. * * bonne valeur pour distance : 256 */ #define V3D_TO_V2D(v3,v2,width,height,distance) \ { \ int Xp, Yp; \ if (v3.z > 2) { \ F2I((distance * v3.x / v3.z),Xp) ; \ F2I((distance * v3.y / v3.z),Yp) ; \ v2.x = Xp + (width>>1); \ v2.y = -Yp + (height>>1); \ } \ else v2.x=v2.y=-666; \ } void v3d_to_v2d(v3d *src, int nbvertex, int width, int height, float distance, v2d *v2_array); /* * rotation selon Y du v3d vi d'angle a (cosa=cos(a), sina=sin(a)) * centerz = centre de rotation en z */ #define Y_ROTATE_V3D(vi,vf,sina,cosa)\ {\ vf.x = vi.x * cosa - vi.z * sina;\ vf.z = vi.x * sina + vi.z * cosa;\ vf.y = vi.y;\ } /* * translation */ #define TRANSLATE_V3D(vsrc,vdest)\ {\ vdest.x += vsrc.x;\ vdest.y += vsrc.y;\ vdest.z += vsrc.z;\ } #define MUL_V3D(lf,v) {v.x*=lf;v.y*=lf;v.z*=lf;} #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/surf3d.c�����������������������������������������������������������������0000644�0001750�0001750�00000004625�14647725152�014762� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "surf3d.h" #include "goom_plugin_info.h" #include <stdlib.h> #include <stdio.h> #include <string.h> void grid3d_free (grid3d *g) { free (g->surf.vertex); free (g->surf.svertex); free (g); } grid3d *grid3d_new (int sizex, int defx, int sizez, int defz, v3d center) { int x = defx; int y = defz; grid3d *g = malloc (sizeof(grid3d)); surf3d *s = &(g->surf); s->nbvertex = x*y; s->vertex = malloc (x*y*sizeof(v3d)); s->svertex = malloc (x*y*sizeof(v3d)); s->center = center; g->defx=defx; g->sizex=sizex; g->defz=defz; g->sizez=sizez; g->mode=0; while (y) { --y; x = defx; while (x) { --x; s->vertex[x+defx*y].x = (float)(x-defx/2)*sizex/defx; s->vertex[x+defx*y].y = 0; s->vertex[x+defx*y].z = (float)(y-defz/2)*sizez/defz; } } return g; } void grid3d_draw (PluginInfo *plug, grid3d *g, int color, int colorlow, int dist, Pixel *buf, Pixel *back, int W,int H) { int x; v2d v2,v2x; v2d *v2_array = malloc(g->surf.nbvertex * sizeof(v2d)); v3d_to_v2d(g->surf.svertex, g->surf.nbvertex, W, H, dist, v2_array); for (x=0;x<g->defx;x++) { int z; v2x = v2_array[x]; for (z=1;z<g->defz;z++) { v2 = v2_array[z*g->defx + x]; if (((v2.x != -666) || (v2.y!=-666)) && ((v2x.x != -666) || (v2x.y!=-666))) { plug->methods.draw_line (buf,v2x.x,v2x.y,v2.x,v2.y, colorlow, W, H); plug->methods.draw_line (back,v2x.x,v2x.y,v2.x,v2.y, color, W, H); } v2x = v2; } } free(v2_array); } void surf3d_rotate (surf3d *s, float angle) { int i; float cosa; float sina; SINCOS(angle,sina,cosa); for (i=0;i<s->nbvertex;i++) { Y_ROTATE_V3D(s->vertex[i],s->svertex[i],cosa,sina); } } void surf3d_translate (surf3d *s) { int i; for (i=0;i<s->nbvertex;i++) { TRANSLATE_V3D(s->center,s->svertex[i]); } } void grid3d_update (grid3d *g, float angle, float *vals, float dist) { int i; float cosa; float sina; surf3d *s = &(g->surf); v3d cam = s->center; cam.z += dist; SINCOS((angle/4.3f),sina,cosa); cam.y += sina*2.0f; SINCOS(angle,sina,cosa); if (g->mode==0) { if (vals) for (i=0;i<g->defx;i++) s->vertex[i].y = s->vertex[i].y*0.2 + vals[i]*0.8; for (i=g->defx;i<s->nbvertex;i++) { s->vertex[i].y *= 0.255f; s->vertex[i].y += (s->vertex[i-g->defx].y * 0.777f); } } for (i=0;i<s->nbvertex;i++) { Y_ROTATE_V3D(s->vertex[i],s->svertex[i],cosa,sina); TRANSLATE_V3D(cam,s->svertex[i]); } } �����������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/mmx.c��������������������������������������������������������������������0000644�0001750�0001750�00000014040�14647725152�014345� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef HAVE_MMX #define BUFFPOINTNB 16 #define BUFFPOINTMASK 0xffff #define BUFFINCR 0xff #include <stddef.h> #include "mmx.h" #include "goom_graphic.h" #define sqrtperte 16 // faire : a % sqrtperte <=> a & pertemask #define PERTEMASK 0xf // faire : a / sqrtperte <=> a >> PERTEDEC #define PERTEDEC 4 int mmx_supported (void) { return (mm_support()&0x1); } void zoom_filter_mmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]) { unsigned int ax = (prevX-1)<<PERTEDEC, ay = (prevY-1)<<PERTEDEC; size_t sizeX = prevX; int bufsize = prevX * prevY; int loop; __asm__ __volatile__ ("pxor %mm7,%mm7"); for (loop=0; loop<bufsize; loop++) { /* int couleur; */ int px,py; size_t pos; int coeffs; int myPos = loop << 1, myPos2 = myPos + 1; int brutSmypos = brutS[myPos]; px = brutSmypos + (((brutD[myPos] - brutSmypos)*buffratio) >> BUFFPOINTNB); brutSmypos = brutS[myPos2]; py = brutSmypos + (((brutD[myPos2] - brutSmypos)*buffratio) >> BUFFPOINTNB); if ((py>=(int)ay) || (px>=(int)ax)) { pos=coeffs=0; } else { pos = ((px >> PERTEDEC) + prevX * (py >> PERTEDEC)); // coef en modulo 15 coeffs = precalCoef [px & PERTEMASK][py & PERTEMASK]; } __asm__ __volatile__ ( "movd %2, %%mm6 \n\t" /* recuperation des deux premiers pixels dans mm0 et mm1 */ "movq (%3,%1,4), %%mm0 \n\t" /* b1-v1-r1-a1-b2-v2-r2-a2 */ "movq %%mm0, %%mm1 \n\t" /* b1-v1-r1-a1-b2-v2-r2-a2 */ /* depackage du premier pixel */ "punpcklbw %%mm7, %%mm0 \n\t" /* 00-b2-00-v2-00-r2-00-a2 */ "movq %%mm6, %%mm5 \n\t" /* ??-??-??-??-c4-c3-c2-c1 */ /* depackage du 2ieme pixel */ "punpckhbw %%mm7, %%mm1 \n\t" /* 00-b1-00-v1-00-r1-00-a1 */ /* extraction des coefficients... */ "punpcklbw %%mm5, %%mm6 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */ "movq %%mm6, %%mm4 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */ "movq %%mm6, %%mm5 \n\t" /* c4-c4-c3-c3-c2-c2-c1-c1 */ "punpcklbw %%mm5, %%mm6 \n\t" /* c2-c2-c2-c2-c1-c1-c1-c1 */ "punpckhbw %%mm5, %%mm4 \n\t" /* c4-c4-c4-c4-c3-c3-c3-c3 */ "movq %%mm6, %%mm3 \n\t" /* c2-c2-c2-c2-c1-c1-c1-c1 */ "punpcklbw %%mm7, %%mm6 \n\t" /* 00-c1-00-c1-00-c1-00-c1 */ "punpckhbw %%mm7, %%mm3 \n\t" /* 00-c2-00-c2-00-c2-00-c2 */ /* multiplication des pixels par les coefficients */ "pmullw %%mm6, %%mm0 \n\t" /* c1*b2-c1*v2-c1*r2-c1*a2 */ "pmullw %%mm3, %%mm1 \n\t" /* c2*b1-c2*v1-c2*r1-c2*a1 */ "paddw %%mm1, %%mm0 \n\t" /* ...extraction des 2 derniers coefficients */ "movq %%mm4, %%mm5 \n\t" /* c4-c4-c4-c4-c3-c3-c3-c3 */ "punpcklbw %%mm7, %%mm4 \n\t" /* 00-c3-00-c3-00-c3-00-c3 */ "punpckhbw %%mm7, %%mm5 \n\t" /* 00-c4-00-c4-00-c4-00-c4 */ /* ajouter la longueur de ligne a esi */ "add %4,%1 \n\t" /* recuperation des 2 derniers pixels */ "movq (%3,%1,4), %%mm1 \n\t" "movq %%mm1, %%mm2 \n\t" /* depackage des pixels */ "punpcklbw %%mm7, %%mm1 \n\t" "punpckhbw %%mm7, %%mm2 \n\t" /* multiplication pas les coeffs */ "pmullw %%mm4, %%mm1 \n\t" "pmullw %%mm5, %%mm2 \n\t" /* ajout des valeurs obtenues à la valeur finale */ "paddw %%mm1, %%mm0 \n\t" "paddw %%mm2, %%mm0 \n\t" /* division par 256 = 16+16+16+16, puis repackage du pixel final */ "psrlw $8, %%mm0 \n\t" "packuswb %%mm7, %%mm0 \n\t" "movd %%mm0,%0 \n\t" :"=g"(expix2[loop]),"+r"(pos) :"r"(coeffs),"r"(expix1),"g"(sizeX) ); emms(); } } #define DRAWMETHOD_PLUS_MMX(_out,_backbuf,_col) \ { \ movd_m2r(_backbuf, mm0); \ paddusb_m2r(_col, mm0); \ movd_r2m(mm0, _out); \ } #define DRAWMETHOD DRAWMETHOD_PLUS_MMX(*p,*p,col) void draw_line_mmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny) { int x, y, dx, dy, yy, xx; Pixel *p; if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny) || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx)) goto end_of_line; dx = x2 - x1; dy = y2 - y1; if (x1 >= x2) { int tmp; tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; dx = x2 - x1; dy = y2 - y1; } /* vertical line */ if (dx == 0) { if (y1 < y2) { p = &(data[(screenx * y1) + x1]); for (y = y1; y <= y2; y++) { DRAWMETHOD; p += screenx; } } else { p = &(data[(screenx * y2) + x1]); for (y = y2; y <= y1; y++) { DRAWMETHOD; p += screenx; } } goto end_of_line; } /* horizontal line */ if (dy == 0) { if (x1 < x2) { p = &(data[(screenx * y1) + x1]); for (x = x1; x <= x2; x++) { DRAWMETHOD; p++; } goto end_of_line; } else { p = &(data[(screenx * y1) + x2]); for (x = x2; x <= x1; x++) { DRAWMETHOD; p++; } goto end_of_line; } } /* 1 */ /* \ */ /* \ */ /* 2 */ if (y2 > y1) { /* steep */ if (dy > dx) { dx = ((dx << 16) / dy); x = x1 << 16; for (y = y1; y <= y2; y++) { xx = x >> 16; p = &(data[(screenx * y) + xx]); DRAWMETHOD; #if 0 if (xx < (screenx - 1)) { p++; /* DRAWMETHOD; */ } #endif x += dx; } goto end_of_line; } /* shallow */ else { dy = ((dy << 16) / dx); y = y1 << 16; for (x = x1; x <= x2; x++) { yy = y >> 16; p = &(data[(screenx * yy) + x]); DRAWMETHOD; #if 0 if (yy < (screeny - 1)) { p += screeny; /* DRAWMETHOD; */ } #endif y += dy; } } } /* 2 */ /* / */ /* / */ /* 1 */ else { /* steep */ if (-dy > dx) { dx = ((dx << 16) / -dy); x = (x1 + 1) << 16; for (y = y1; y >= y2; y--) { xx = x >> 16; p = &(data[(screenx * y) + xx]); DRAWMETHOD; #if 0 if (xx < (screenx - 1)) { p--; /* DRAWMETHOD; */ } #endif x += dx; } goto end_of_line; } /* shallow */ else { dy = ((dy << 16) / dx); y = y1 << 16; for (x = x1; x <= x2; x++) { yy = y >> 16; p = &(data[(screenx * yy) + x]); DRAWMETHOD; #if 0 if (yy < (screeny - 1)) { p += screeny; /* DRAWMETHOD; */ } #endif y += dy; } goto end_of_line; } } end_of_line: emms(); /* __asm__ __volatile__ ("emms"); */ } #endif ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/config_param.c�����������������������������������������������������������0000644�0001750�0001750�00000005045�14647725152�016176� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*---------------------------------------------------------------------------*/ /* ** config_param.c ** Goom Project ** ** Created by Jean-Christophe Hoelt on Sat Jul 19 2003 ** Copyright (c) 2003 iOS. All rights reserved. */ /*---------------------------------------------------------------------------*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goom_config_param.h" #include <string.h> /* TODO: Ajouter goom_ devant ces fonctions */ static void empty_fct(PluginParam *dummy) { (void)dummy; } static PluginParam secure_param() { PluginParam p = { .changed = empty_fct, .change_listener = empty_fct, .user_data = 0, .name = 0, .desc = 0, .rw = 1, .type = 0, }; return p; } PluginParam goom_secure_f_param(const char *name) { PluginParam p = secure_param(); p.name = name; p.type = PARAM_FLOATVAL; FVAL(p) = 0.5f; FMIN(p) = 0.0f; FMAX(p) = 1.0f; FSTEP(p) = 0.01f; return p; } PluginParam goom_secure_f_feedback(const char *name) { PluginParam p = secure_f_param(name); p.rw = 0; return p; } PluginParam goom_secure_s_param(const char *name) { PluginParam p = secure_param(); p.name = name; p.type = PARAM_STRVAL; SVAL(p) = 0; return p; } PluginParam goom_secure_b_param(const char *name, int value) { PluginParam p = secure_param(); p.name = name; p.type = PARAM_BOOLVAL; BVAL(p) = value; return p; } PluginParam goom_secure_i_param(const char *name) { PluginParam p = secure_param(); p.name = name; p.type = PARAM_INTVAL; IVAL(p) = 50; IMIN(p) = 0; IMAX(p) = 100; ISTEP(p) = 1; return p; } PluginParam goom_secure_i_feedback(const char *name) { PluginParam p = secure_i_param(name); p.rw = 0; return p; } PluginParameters goom_plugin_parameters(const char *name, int nb) { PluginParameters p; p.name = name; p.desc = ""; p.nbParams = nb; p.params = (PluginParam**)malloc(nb*sizeof(PluginParam*)); return p; } /*---------------------------------------------------------------------------*/ void goom_set_str_param_value(PluginParam *p, const char *str) { int len = strlen(str); if (SVAL(*p)) SVAL(*p) = (char*)realloc(SVAL(*p), len+1); else SVAL(*p) = (char*)malloc(len+1); memcpy(SVAL(*p), str, len+1); } void goom_set_list_param_value(PluginParam *p, const char *str) { int len = strlen(str); #ifdef VERBOSE printf("%s: %d\n", str, len); #endif if (LVAL(*p)) LVAL(*p) = (char*)realloc(LVAL(*p), len+1); else LVAL(*p) = (char*)malloc(len+1); memcpy(LVAL(*p), str, len+1); } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/gfontlib.h���������������������������������������������������������������0000644�0001750�0001750�00000000516�14647725152�015360� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GFONTLIB_H #define _GFONTLIB_H #include "goom_graphic.h" typedef struct goomfont_s goomfont_t; goomfont_t *gfont_load (void); void gfont_unload (goomfont_t **); void goom_draw_text (goomfont_t *, Pixel * buf, int resolx, int resoly, int x, int y, const char *str, float chspace, int center); #endif ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_lex.c�������������������������������������������������������������0000644�0001750�0001750�00000156662�14647725152�015735� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#line 2 "goomsl_lex.c" #line 4 "goomsl_lex.c" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 31 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include <stdio.h> #include <string.h> #include <errno.h> #include <stdlib.h> /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ #if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L #include <inttypes.h> typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define YY_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN (yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START (((yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE yyrestart(yyin ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif extern int yyleng; extern FILE *yyin, *yyout; #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires * access to the local variable yy_act. Since yyless() is a macro, it would break * existing scanners that call yyless() from OUTSIDE yylex. * One obvious solution it to make yy_act a global. I tried that, and saw * a 5% performance hit in a non-yylineno scanner, because yy_act is * normally declared as a register variable-- so it is not worth it. */ #define YY_LESS_LINENO(n) \ do { \ int yyl;\ for ( yyl = n; yyl < yyleng; ++yyl )\ if ( yytext[yyl] == '\n' )\ --yylineno;\ }while(0) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, (yytext_ptr) ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef unsigned int yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* Stack of input buffers. */ static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ int yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 1; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; void yyrestart (FILE *input_file ); void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); void yy_delete_buffer (YY_BUFFER_STATE b ); void yy_flush_buffer (YY_BUFFER_STATE b ); void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); void yypop_buffer_state (void ); static void yyensure_buffer_stack (void ); static void yy_load_buffer_state (void ); static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); #define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); void *yyalloc (yy_size_t ); void *yyrealloc (void *,yy_size_t ); void yyfree (void * ); #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ yyensure_buffer_stack (); \ YY_CURRENT_BUFFER_LVALUE = \ yy_create_buffer(yyin,YY_BUF_SIZE ); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ typedef unsigned char YY_CHAR; FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; typedef int yy_state_type; #define YY_FLEX_LEX_COMPAT extern int yylineno; int yylineno = 1; extern char yytext[]; static yy_state_type yy_get_previous_state (void ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); static int yy_get_next_buffer (void ); static void yy_fatal_error (yyconst char msg[] ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ (yytext_ptr) = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ if ( yyleng + (yy_more_offset) >= YYLMAX ) \ YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \ yy_flex_strncpy( &yytext[(yy_more_offset)], (yytext_ptr), yyleng + 1 ); \ yyleng += (yy_more_offset); \ (yy_prev_more_offset) = (yy_more_offset); \ (yy_more_offset) = 0; \ (yy_c_buf_p) = yy_cp; #define YY_NUM_RULES 49 #define YY_END_OF_BUFFER 50 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_acclist[214] = { 0, 50, 48, 49, 47, 48, 49, 4, 49, 48, 49, 13, 48, 49, 10, 48, 49, 33, 48, 49, 48, 49, 48, 49, 48, 49, 48, 49, 48, 49, 34, 48, 49, 34, 48, 49, 48, 49, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 33, 48, 49, 47, 48, 49, 1, 4, 49, 48, 49, 7, 49, 6, 49, 7, 49, 7, 49, 1, 6, 49, 7, 49, 3, 49, 1, 3, 49, 17, 49, 49, 16, 17, 49, 17, 49, 47, 45, 10, 10, 10, 33, 40, 39, 41, 11, 12, 42, 38, 37, 34, 43, 46, 44, 33, 33, 28, 33, 33, 33, 33, 33, 30, 33, 33, 33, 33, 33, 33, 47, 1, 12, 5, 15, 14, 10, 10, 35, 37, 36, 33, 33, 33, 33, 33, 29, 33, 19, 33, 26, 33, 21, 33, 33, 33, 33, 2, 10, 10, 33, 33, 33, 33, 33, 33, 33, 31, 33, 33, 10, 10, 33, 33, 33, 32, 33, 18, 33, 33, 33, 27, 33, 10, 10, 33, 33, 33, 22, 33, 25, 33, 10, 9, 10, 10, 20, 33, 23, 33, 33, 10, 24, 33, 10, 8, 10 } ; static yyconst flex_int16_t yy_accept[152] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 7, 9, 11, 14, 17, 20, 22, 24, 26, 28, 30, 33, 36, 38, 40, 43, 46, 49, 52, 55, 58, 61, 64, 67, 70, 73, 76, 78, 80, 82, 84, 86, 89, 91, 93, 96, 98, 99, 102, 104, 105, 106, 107, 108, 109, 110, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 119, 120, 121, 122, 123, 124, 126, 127, 128, 129, 130, 132, 133, 134, 135, 136, 137, 138, 139, 139, 140, 141, 141, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 157, 159, 161, 162, 163, 164, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 176, 177, 178, 179, 180, 181, 182, 184, 186, 187, 188, 190, 191, 192, 193, 194, 195, 197, 199, 200, 202, 203, 205, 207, 208, 209, 211, 212, 214, 214 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 6, 7, 1, 8, 9, 10, 1, 1, 11, 12, 1, 13, 14, 15, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 1, 1, 18, 19, 20, 1, 9, 21, 21, 21, 21, 22, 23, 21, 21, 24, 21, 21, 25, 21, 26, 21, 21, 21, 27, 28, 29, 21, 21, 21, 21, 21, 21, 1, 30, 1, 1, 31, 1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 21, 21, 41, 21, 42, 43, 44, 21, 45, 46, 47, 48, 21, 49, 50, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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 yyconst flex_int32_t yy_meta[51] = { 0, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 4, 4, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 3, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 } ; static yyconst flex_int16_t yy_base[159] = { 0, 0, 49, 51, 54, 221, 57, 60, 64, 223, 225, 69, 225, 203, 225, 51, 0, 0, 202, 201, 200, 64, 68, 72, 72, 199, 174, 57, 166, 55, 173, 171, 166, 165, 166, 171, 99, 225, 93, 225, 225, 194, 107, 225, 193, 225, 225, 225, 225, 225, 71, 93, 225, 0, 183, 178, 0, 195, 225, 225, 225, 225, 225, 225, 225, 89, 107, 0, 225, 225, 225, 161, 169, 0, 155, 160, 157, 154, 151, 150, 151, 150, 146, 153, 123, 225, 177, 188, 225, 126, 187, 225, 225, 164, 159, 225, 100, 0, 146, 145, 149, 138, 151, 0, 0, 0, 0, 59, 146, 140, 177, 225, 157, 147, 141, 144, 130, 138, 126, 130, 137, 0, 134, 165, 143, 133, 112, 109, 0, 0, 102, 92, 0, 130, 112, 93, 98, 101, 0, 0, 125, 124, 94, 0, 0, 78, 59, 0, 61, 0, 225, 141, 145, 149, 151, 155, 51, 159, 163 } ; static yyconst flex_int16_t yy_def[159] = { 0, 150, 1, 151, 151, 151, 151, 152, 152, 150, 150, 150, 150, 150, 150, 153, 154, 155, 150, 150, 150, 150, 150, 150, 150, 150, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 153, 153, 153, 154, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 156, 150, 150, 150, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 150, 150, 150, 157, 150, 150, 157, 150, 150, 153, 153, 150, 150, 156, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 157, 150, 153, 153, 154, 154, 154, 154, 154, 154, 154, 154, 154, 153, 153, 154, 154, 154, 154, 154, 154, 154, 154, 158, 153, 154, 154, 154, 154, 154, 158, 158, 153, 154, 154, 154, 153, 154, 153, 153, 0, 150, 150, 150, 150, 150, 150, 150, 150 } ; static yyconst flex_int16_t yy_nxt[276] = { 0, 10, 11, 12, 11, 13, 14, 15, 10, 16, 17, 18, 19, 20, 10, 21, 22, 23, 24, 10, 25, 16, 16, 16, 16, 16, 16, 16, 16, 16, 10, 16, 16, 26, 16, 27, 28, 29, 16, 16, 30, 16, 31, 16, 32, 16, 33, 34, 16, 35, 16, 36, 37, 36, 40, 97, 42, 43, 42, 42, 46, 42, 41, 48, 38, 41, 49, 48, 149, 44, 49, 51, 44, 51, 54, 61, 64, 91, 55, 62, 64, 148, 65, 63, 66, 66, 65, 75, 66, 66, 50, 68, 69, 72, 50, 51, 76, 51, 77, 119, 73, 84, 85, 84, 61, 96, 96, 120, 87, 89, 85, 89, 63, 92, 86, 64, 96, 96, 67, 147, 146, 65, 86, 66, 66, 84, 85, 84, 89, 85, 89, 141, 141, 145, 144, 143, 142, 141, 86, 139, 138, 86, 39, 39, 39, 39, 47, 47, 47, 47, 53, 137, 53, 53, 56, 56, 57, 136, 57, 57, 110, 110, 110, 110, 140, 135, 140, 140, 134, 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, 123, 111, 122, 121, 118, 117, 116, 115, 114, 113, 112, 111, 111, 90, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 95, 94, 93, 90, 88, 83, 82, 81, 80, 79, 78, 74, 71, 70, 60, 59, 58, 52, 150, 45, 9, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 } ; static yyconst flex_int16_t yy_chk[276] = { 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, 2, 2, 2, 3, 156, 4, 4, 4, 6, 6, 6, 3, 7, 2, 4, 7, 8, 148, 4, 8, 11, 6, 11, 15, 21, 22, 50, 15, 21, 23, 146, 22, 21, 22, 22, 23, 29, 23, 23, 7, 24, 24, 27, 8, 51, 29, 51, 29, 107, 27, 36, 36, 36, 38, 65, 65, 107, 38, 42, 42, 42, 38, 50, 36, 66, 96, 96, 22, 145, 142, 66, 42, 66, 66, 84, 84, 84, 89, 89, 89, 141, 140, 137, 136, 135, 134, 133, 84, 131, 130, 89, 151, 151, 151, 151, 152, 152, 152, 152, 153, 127, 153, 153, 154, 154, 155, 126, 155, 155, 157, 157, 157, 157, 158, 125, 158, 158, 124, 123, 122, 120, 119, 118, 117, 116, 115, 114, 113, 112, 110, 109, 108, 102, 101, 100, 99, 98, 94, 93, 90, 87, 86, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 72, 71, 57, 55, 54, 44, 41, 35, 34, 33, 32, 31, 30, 28, 26, 25, 20, 19, 18, 13, 9, 5, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150 } ; /* Table of booleans, true if rule could match eol. */ static yyconst flex_int32_t yy_rule_can_match_eol[50] = { 0, 1, 1, 1, 1, 0, 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, }; extern int yy_flex_debug; int yy_flex_debug = 0; static yy_state_type *yy_state_buf=0, *yy_state_ptr=0; static char *yy_full_match; static int yy_lp; #if 0 #define REJECT \ { \ *yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ \ yy_cp = (yy_full_match); /* restore poss. backed-over text */ \ ++(yy_lp); \ goto find_rule; \ } #endif static int yy_more_offset = 0; static int yy_prev_more_offset = 0; //#define yymore() ((yy_more_offset) = yy_flex_strlen( yytext )) //#define YY_NEED_STRLEN #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET \ { \ (yy_more_offset) = (yy_prev_more_offset); \ yyleng -= (yy_more_offset); \ } #ifndef YYLMAX #define YYLMAX 8192 #endif char yytext[YYLMAX]; char *yytext_ptr; #line 1 "goomsl_lex.l" #line 2 "goomsl_lex.l" #include <math.h> #include <stdlib.h> #include <string.h> #include "goomsl.h" #include "goomsl_private.h" #include "goomsl_yacc.h" void yyerror(const char *); void yyparse(void); GoomSL *currentGoomSL; static int string_size; static char string[1024]; #line 639 "goomsl_lex.c" #define INITIAL 0 #define C_COMMENT 1 #define LINE_COMMENT 2 #define STRING 3 /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include <unistd.h> #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int yywrap (void ); #else extern int yywrap (void ); #endif #endif static void yyunput (int c,char *buf_ptr ); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void ); #else static int input (void ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int yylex (void); #define YY_DECL int yylex (void) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ if ( yyleng > 0 ) \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \ (yytext[yyleng - 1] == '\n'); \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; #line 25 "goomsl_lex.l" #line 797 "goomsl_lex.c" if ( (yy_init) ) { (yy_init) = 0; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! (yy_state_buf) ) (yy_state_buf) = (yy_state_type *)yyalloc(YY_BUF_SIZE + 2 ); if ( ! (yy_start) ) (yy_start) = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_load_buffer_state( ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = (yy_c_buf_p); /* Support of yytext. */ *yy_cp = (yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); (yy_state_ptr) = (yy_state_buf); *(yy_state_ptr)++ = yy_current_state; yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 151 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *(yy_state_ptr)++ = yy_current_state; ++yy_cp; } while ( yy_base[yy_current_state] != 225 ); yy_find_action: yy_current_state = *--(yy_state_ptr); (yy_lp) = yy_accept[yy_current_state]; #if 0 find_rule: /* we branch to this label when backing up */ #endif for ( ; ; ) /* until we find what rule we matched */ { if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] ) { yy_act = yy_acclist[(yy_lp)]; { (yy_full_match) = yy_cp; break; } } --yy_cp; yy_current_state = *--(yy_state_ptr); (yy_lp) = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) { int yyl; for ( yyl = (yy_prev_more_offset); yyl < yyleng; ++yyl ) if ( yytext[yyl] == '\n' ) yylineno++; ; } do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 1: /* rule 1 can match eol */ YY_RULE_SETUP #line 27 "goomsl_lex.l" { ++currentGoomSL->num_lines; /* Ignore empty lines */ } YY_BREAK case 2: /* rule 2 can match eol */ YY_RULE_SETUP #line 28 "goomsl_lex.l" { ++currentGoomSL->num_lines; /* Ignore empty lines */ } YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 30 "goomsl_lex.l" { ++currentGoomSL->num_lines; yylval.charValue=*yytext; BEGIN INITIAL; return '\n'; } YY_BREAK case 4: /* rule 4 can match eol */ YY_RULE_SETUP #line 31 "goomsl_lex.l" { ++currentGoomSL->num_lines; yylval.charValue=*yytext; return '\n'; } YY_BREAK case 5: YY_RULE_SETUP #line 33 "goomsl_lex.l" { BEGIN INITIAL; } YY_BREAK case 6: /* rule 6 can match eol */ YY_RULE_SETUP #line 34 "goomsl_lex.l" { ++currentGoomSL->num_lines; } YY_BREAK case 7: YY_RULE_SETUP #line 35 "goomsl_lex.l" { /* eat up comment */ } YY_BREAK case 8: YY_RULE_SETUP #line 37 "goomsl_lex.l" { currentGoomSL->num_lines = 0; } YY_BREAK case 9: YY_RULE_SETUP #line 38 "goomsl_lex.l" { currentGoomSL->num_lines = 0; printf("%s\n", yytext); } YY_BREAK case 10: YY_RULE_SETUP #line 39 "goomsl_lex.l" { /* ignore preprocessor lines */ } YY_BREAK case 11: YY_RULE_SETUP #line 41 "goomsl_lex.l" { BEGIN C_COMMENT; } YY_BREAK case 12: YY_RULE_SETUP #line 42 "goomsl_lex.l" { BEGIN LINE_COMMENT; } YY_BREAK case 13: YY_RULE_SETUP #line 43 "goomsl_lex.l" { BEGIN STRING; string_size=0; } YY_BREAK case 14: YY_RULE_SETUP #line 45 "goomsl_lex.l" { string[string_size++] = '\n'; } YY_BREAK case 15: YY_RULE_SETUP #line 46 "goomsl_lex.l" { string[string_size++] = '\"'; } YY_BREAK case 16: YY_RULE_SETUP #line 47 "goomsl_lex.l" { /* fin de la chaine: on cree le pointeur qui va bien */ unsigned int tmp; BEGIN INITIAL; string[string_size]=0; tmp = gsl_malloc(currentGoomSL, string_size+1); strcpy((char*)currentGoomSL->ptrArray[tmp],string); sprintf(yylval.strValue, "0x%08x", tmp); return LTYPE_PTR; } YY_BREAK case 17: YY_RULE_SETUP #line 56 "goomsl_lex.l" { string[string_size++] = *yytext; } YY_BREAK case 18: YY_RULE_SETUP #line 58 "goomsl_lex.l" { return FLOAT_TK; } YY_BREAK case 19: YY_RULE_SETUP #line 59 "goomsl_lex.l" { return INT_TK; } YY_BREAK case 20: YY_RULE_SETUP #line 60 "goomsl_lex.l" { return INT_TK; } YY_BREAK case 21: YY_RULE_SETUP #line 61 "goomsl_lex.l" { return PTR_TK; } YY_BREAK case 22: YY_RULE_SETUP #line 62 "goomsl_lex.l" { return PTR_TK; } YY_BREAK case 23: YY_RULE_SETUP #line 63 "goomsl_lex.l" { return DECLARE; } YY_BREAK case 24: YY_RULE_SETUP #line 64 "goomsl_lex.l" { return EXTERNAL; } YY_BREAK case 25: YY_RULE_SETUP #line 65 "goomsl_lex.l" { return STRUCT; } YY_BREAK case 26: YY_RULE_SETUP #line 66 "goomsl_lex.l" { return NOT; } YY_BREAK case 27: YY_RULE_SETUP #line 67 "goomsl_lex.l" { return WHILE; } YY_BREAK case 28: YY_RULE_SETUP #line 68 "goomsl_lex.l" { return DO; } YY_BREAK case 29: YY_RULE_SETUP #line 69 "goomsl_lex.l" { return FOR; } YY_BREAK case 30: YY_RULE_SETUP #line 70 "goomsl_lex.l" { return IN; } YY_BREAK case 31: YY_RULE_SETUP #line 71 "goomsl_lex.l" { strncpy(yylval.strValue, "1", 2047); return LTYPE_INTEGER; } YY_BREAK case 32: YY_RULE_SETUP #line 72 "goomsl_lex.l" { strncpy(yylval.strValue, "0", 2047); return LTYPE_INTEGER; } YY_BREAK case 33: YY_RULE_SETUP #line 73 "goomsl_lex.l" { strncpy(yylval.strValue, yytext, 2047); return LTYPE_VAR; } YY_BREAK case 34: YY_RULE_SETUP #line 74 "goomsl_lex.l" { strncpy(yylval.strValue, yytext, 2047); return LTYPE_INTEGER; } YY_BREAK case 35: YY_RULE_SETUP #line 75 "goomsl_lex.l" { sprintf(yylval.strValue, "%d", (int)yytext[1]); return LTYPE_INTEGER; } YY_BREAK case 36: YY_RULE_SETUP #line 76 "goomsl_lex.l" { strncpy(yylval.strValue, yytext, 2047); return LTYPE_INTEGER; } YY_BREAK case 37: YY_RULE_SETUP #line 77 "goomsl_lex.l" { strncpy(yylval.strValue, yytext, 2047); return LTYPE_FLOAT; } YY_BREAK case 38: YY_RULE_SETUP #line 78 "goomsl_lex.l" { sprintf(yylval.strValue, "%3.2f", atof(yytext)/100.0f); return LTYPE_FLOAT; } YY_BREAK case 39: YY_RULE_SETUP #line 79 "goomsl_lex.l" { return PLUS_EQ; } YY_BREAK case 40: YY_RULE_SETUP #line 80 "goomsl_lex.l" { return MUL_EQ; } YY_BREAK case 41: YY_RULE_SETUP #line 81 "goomsl_lex.l" { return SUB_EQ; } YY_BREAK case 42: YY_RULE_SETUP #line 82 "goomsl_lex.l" { return DIV_EQ; } YY_BREAK case 43: YY_RULE_SETUP #line 83 "goomsl_lex.l" { return LOW_EQ; } YY_BREAK case 44: YY_RULE_SETUP #line 84 "goomsl_lex.l" { return SUP_EQ; } YY_BREAK case 45: YY_RULE_SETUP #line 85 "goomsl_lex.l" { return NOT_EQ; } YY_BREAK case 46: YY_RULE_SETUP #line 86 "goomsl_lex.l" { return NOT_EQ; } YY_BREAK case 47: YY_RULE_SETUP #line 87 "goomsl_lex.l" /* eat up whitespace */ YY_BREAK case 48: YY_RULE_SETUP #line 88 "goomsl_lex.l" { yylval.charValue = *yytext; return *yytext; } YY_BREAK case 49: YY_RULE_SETUP #line 90 "goomsl_lex.l" ECHO; YY_BREAK #line 1155 "goomsl_lex.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(C_COMMENT): case YY_STATE_EOF(LINE_COMMENT): case YY_STATE_EOF(STRING): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = (yy_hold_char); YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state ); yy_bp = (yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = (yy_c_buf_p); goto yy_find_action; } } else switch ( yy_get_next_buffer( ) ) { case EOB_ACT_END_OF_FILE: { (yy_did_buffer_switch_on_eof) = 0; if ( yywrap( ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: (yy_c_buf_p) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; yy_current_state = yy_get_previous_state( ); yy_cp = (yy_c_buf_p); yy_bp = (yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (void) { register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = (yytext_ptr); register int number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; else { size_t num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), (yy_n_chars), num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } if ( (yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; yyrestart(yyin ); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; (yy_n_chars) += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (void) { register yy_state_type yy_current_state; register char *yy_cp; yy_current_state = (yy_start); yy_current_state += YY_AT_BOL(); (yy_state_ptr) = (yy_state_buf); *(yy_state_ptr)++ = yy_current_state; for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 151 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; *(yy_state_ptr)++ = yy_current_state; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) { register int yy_is_jam; register YY_CHAR yy_c = 1; while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 151 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 150); if ( ! yy_is_jam ) *(yy_state_ptr)++ = yy_current_state; return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp ) { register char *yy_cp; yy_cp = (yy_c_buf_p); /* undo effects of setting up yytext */ *yy_cp = (yy_hold_char); if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = (yy_n_chars) + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; if ( c == '\n' ){ --yylineno; } (yytext_ptr) = yy_bp; (yy_hold_char) = *yy_cp; (yy_c_buf_p) = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (void) #else static int input (void) #endif { int c; *(yy_c_buf_p) = (yy_hold_char); if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) /* This was really a NUL. */ *(yy_c_buf_p) = '\0'; else { /* need more input */ int offset = (yy_c_buf_p) - (yytext_ptr); ++(yy_c_buf_p); switch ( yy_get_next_buffer( ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ yyrestart(yyin ); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( yywrap( ) ) return EOF; if ( ! (yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(); #else return input(); #endif } case EOB_ACT_CONTINUE_SCAN: (yy_c_buf_p) = (yytext_ptr) + offset; break; } } } c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ *(yy_c_buf_p) = '\0'; /* preserve yytext */ (yy_hold_char) = *++(yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n'); if ( YY_CURRENT_BUFFER_LVALUE->yy_at_bol ) yylineno++; ; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * * @note This function does not reset the start condition to @c INITIAL . */ void yyrestart (FILE * input_file ) { if ( ! YY_CURRENT_BUFFER ){ yyensure_buffer_stack (); YY_CURRENT_BUFFER_LVALUE = yy_create_buffer(yyin,YY_BUF_SIZE ); } yy_init_buffer(YY_CURRENT_BUFFER,input_file ); yy_load_buffer_state( ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * */ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) { /* TODO. We should be able to replace this entire function body * with * yypop_buffer_state(); * yypush_buffer_state(new_buffer); */ yyensure_buffer_stack (); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } YY_CURRENT_BUFFER_LVALUE = new_buffer; yy_load_buffer_state( ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ (yy_did_buffer_switch_on_eof) = 1; } static void yy_load_buffer_state (void) { (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; (yy_hold_char) = *(yy_c_buf_p); } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * * @return the allocated buffer state. */ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; yy_init_buffer(b,file ); return b; } /** Destroy the buffer. * @param b a buffer created with yy_create_buffer() * */ void yy_delete_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) yyfree((void *) b->yy_ch_buf ); yyfree((void *) b ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a yyrestart() or at EOF. */ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) { int oerrno = errno; yy_flush_buffer(b ); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then yy_init_buffer was _probably_ * called from yyrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * */ void yy_flush_buffer (YY_BUFFER_STATE b ) { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) yy_load_buffer_state( ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * */ void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) { if (new_buffer == NULL) return; yyensure_buffer_stack(); /* This block is copied from yy_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *(yy_c_buf_p) = (yy_hold_char); YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) (yy_buffer_stack_top)++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from yy_switch_to_buffer. */ yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * */ void yypop_buffer_state (void) { if (!YY_CURRENT_BUFFER) return; yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; if ((yy_buffer_stack_top) > 0) --(yy_buffer_stack_top); if (YY_CURRENT_BUFFER) { yy_load_buffer_state( ); (yy_did_buffer_switch_on_eof) = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void yyensure_buffer_stack (void) { int num_to_alloc; if (!(yy_buffer_stack)) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc (num_to_alloc * sizeof(struct yy_buffer_state*) ); memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; (yy_buffer_stack_top) = 0; return; } if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = (yy_buffer_stack_max) + grow_size; (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc ((yy_buffer_stack), num_to_alloc * sizeof(struct yy_buffer_state*) ); /* zero only the new slots.*/ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); (yy_buffer_stack_max) = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; yy_switch_to_buffer(b ); return b; } /** Setup the input buffer state to scan a string. The next call to yylex() will * scan from a @e copy of @a str. * @param str a NUL-terminated string to scan * * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * yy_scan_bytes() instead. */ YY_BUFFER_STATE yy_scan_string (yyconst char * str ) { return yy_scan_bytes(str,strlen(str) ); } /** Setup the input buffer state to scan the given bytes. The next call to yylex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * * @return the newly allocated buffer state object. */ YY_BUFFER_STATE yy_scan_bytes (yyconst char * bytes, int len ) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; buf = (char *) yyalloc(n ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < len; ++i ) buf[i] = bytes[i]; buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; b = yy_scan_buffer(buf,n ); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg ) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ (yy_hold_char) = *(yy_c_buf_p); \ *(yy_c_buf_p) = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the current line number. * */ #if 0 int yyget_lineno (void) { return yylineno; } #endif /** Get the input stream. * */ #if 0 FILE *yyget_in (void) { return yyin; } /** Get the output stream. * */ FILE *yyget_out (void) { return yyout; } /** Get the length of the current token. * */ int yyget_leng (void) { return yyleng; } /** Get the current token. * */ char *yyget_text (void) { return yytext; } /** Set the current line number. * @param line_number * */ void yyset_lineno (int line_number ) { yylineno = line_number; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * * @see yy_switch_to_buffer */ void yyset_in (FILE * in_str ) { yyin = in_str ; } void yyset_out (FILE * out_str ) { yyout = out_str ; } int yyget_debug (void) { return yy_flex_debug; } void yyset_debug (int bdebug ) { yy_flex_debug = bdebug ; } #endif #if 0 /* yylex_destroy is for both reentrant and non-reentrant scanners. */ int yylex_destroy (void) { /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ yy_delete_buffer(YY_CURRENT_BUFFER ); YY_CURRENT_BUFFER_LVALUE = NULL; yypop_buffer_state(); } /* Destroy the stack itself. */ yyfree((yy_buffer_stack) ); (yy_buffer_stack) = NULL; yyfree ( (yy_state_buf) ); return 0; } #endif /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s ) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *yyalloc (yy_size_t size ) { return (void *) malloc( size ); } void *yyrealloc (void * ptr, yy_size_t size ) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void yyfree (void * ptr ) { free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #undef YY_NEW_FILE #undef YY_FLUSH_BUFFER #undef yy_set_bol #undef yy_new_buffer #undef yy_set_interactive #undef YY_DO_BEFORE_ACTION #ifdef YY_DECL_IS_OURS #undef YY_DECL_IS_OURS #undef YY_DECL #endif #line 90 "goomsl_lex.l" int yywrap(void) { return 1; yyunput(0,0); } ������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/drawmethods.c������������������������������������������������������������0000644�0001750�0001750�00000007622�14647725152�016075� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "drawmethods.h" #define DRAWMETHOD_PLUS(_out,_backbuf,_col) \ {\ int tra=0,i=0;\ unsigned char *bra = (unsigned char*)&(_backbuf);\ unsigned char *dra = (unsigned char*)&(_out);\ unsigned char *cra = (unsigned char*)&(_col);\ for (;i<4;i++) {\ tra = *cra;\ tra += *bra;\ if (tra>255) tra=255;\ *dra = tra;\ ++dra;++cra;++bra;\ }\ } #define DRAWMETHOD DRAWMETHOD_PLUS(*p,*p,col) void draw_line (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny) { int x, y, dx, dy, yy, xx; Pixel *p; if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny) || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx)) return; /* clip to top edge if ((y1 < 0) && (y2 < 0)) return; if (y1 < 0) { x1 += (y1 * (x1 - x2)) / (y2 - y1); y1 = 0; } if (y2 < 0) { x2 += (y2 * (x1 - x2)) / (y2 - y1); y2 = 0; } clip to bottom edge if ((y1 >= screeny) && (y2 >= screeny)) return; if (y1 >= screeny) { x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1); y1 = screeny - 1; } if (y2 >= screeny) { x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1); y2 = screeny - 1; } clip to left edge if ((x1 < 0) && (x2 < 0)) return; if (x1 < 0) { y1 += (x1 * (y1 - y2)) / (x2 - x1); x1 = 0; } if (x2 < 0) { y2 += (x2 * (y1 - y2)) / (x2 - x1); x2 = 0; } clip to right edge if ((x1 >= screenx) && (x2 >= screenx)) return; if (x1 >= screenx) { y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1); x1 = screenx - 1; } if (x2 >= screenx) { y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1); x2 = screenx - 1; } */ dx = x2 - x1; dy = y2 - y1; if (x1 > x2) { int tmp; tmp = x1; x1 = x2; x2 = tmp; tmp = y1; y1 = y2; y2 = tmp; dx = x2 - x1; dy = y2 - y1; } /* vertical line */ if (dx == 0) { if (y1 < y2) { p = &(data[(screenx * y1) + x1]); for (y = y1; y <= y2; y++) { DRAWMETHOD; p += screenx; } } else { p = &(data[(screenx * y2) + x1]); for (y = y2; y <= y1; y++) { DRAWMETHOD; p += screenx; } } return; } /* horizontal line */ if (dy == 0) { if (x1 < x2) { p = &(data[(screenx * y1) + x1]); for (x = x1; x <= x2; x++) { DRAWMETHOD; p++; } return; } else { p = &(data[(screenx * y1) + x2]); for (x = x2; x <= x1; x++) { DRAWMETHOD; p++; } return; } } /* 1 */ /* \ */ /* \ */ /* 2 */ if (y2 > y1) { /* steep */ if (dy > dx) { dx = ((dx << 16) / dy); x = x1 << 16; for (y = y1; y <= y2; y++) { xx = x >> 16; p = &(data[(screenx * y) + xx]); DRAWMETHOD; #if 0 if (xx < (screenx - 1)) { p++; /* DRAWMETHOD; */ } #endif x += dx; } return; } /* shallow */ else { dy = ((dy << 16) / dx); y = y1 << 16; for (x = x1; x <= x2; x++) { yy = y >> 16; p = &(data[(screenx * yy) + x]); DRAWMETHOD; #if 0 if (yy < (screeny - 1)) { p += screeny; /* DRAWMETHOD; */ } #endif y += dy; } } } /* 2 */ /* / */ /* / */ /* 1 */ else { /* steep */ if (-dy > dx) { dx = ((dx << 16) / -dy); x = (x1 + 1) << 16; for (y = y1; y >= y2; y--) { xx = x >> 16; p = &(data[(screenx * y) + xx]); DRAWMETHOD; #if 0 if (xx < (screenx - 1)) { p--; /* DRAWMETHOD; */ } #endif x += dx; } return; } /* shallow */ else { dy = ((dy << 16) / dx); y = y1 << 16; for (x = x1; x <= x2; x++) { yy = y >> 16; p = &(data[(screenx * yy) + x]); DRAWMETHOD; #if 0 if (yy < (screeny - 1)) { p += screeny; /* DRAWMETHOD; */ } #endif y += dy; } return; } } } ��������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_fx.h����������������������������������������������������������������0000644�0001750�0001750�00000000462�14647725152�015212� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _GOOM_FX_H #define _GOOM_FX_H #include "goom_visual_fx.h" #include "goom_plugin_info.h" VisualFX convolve_create (void); VisualFX flying_star_create (void); void zoom_filter_c(int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); #endif ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/plugin_info.c������������������������������������������������������������0000644�0001750�0001750�00000013734�14647725152�016066� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goom_plugin_info.h" #include "goom_fx.h" #include "cpu_info.h" /*#include "default_scripts.h"*/ #include "drawmethods.h" #include <math.h> #include <stdio.h> #include <string.h> #ifdef CPU_POWERPC #include <sys/types.h> #include <sys/sysctl.h> #include "ppc_zoom_ultimate.h" #include "ppc_drawings.h" #endif /* CPU_POWERPC */ #ifdef CPU_X86 #include "mmx.h" #endif /* CPU_X86 */ static void setOptimizedMethods(PluginInfo *p) { #if defined(CPU_X86) || defined(CPU_POWERPC) unsigned int cpuFlavour = cpu_flavour(); #endif /* set default methods */ p->methods.draw_line = draw_line; p->methods.zoom_filter = zoom_filter_c; /* p->methods.create_output_with_brightness = create_output_with_brightness;*/ #ifdef CPU_X86 if (cpuFlavour & CPU_OPTION_XMMX) { #ifdef VERBOSE printf ("Extented MMX detected. Using the fastest methods !\n"); #endif p->methods.draw_line = draw_line_mmx; p->methods.zoom_filter = zoom_filter_xmmx; } else if (cpuFlavour & CPU_OPTION_MMX) { #ifdef VERBOSE printf ("MMX detected. Using fast methods !\n"); #endif p->methods.draw_line = draw_line_mmx; p->methods.zoom_filter = zoom_filter_mmx; } #ifdef VERBOSE else printf ("Too bad ! No SIMD optimization available for your CPU.\n"); #endif #endif /* CPU_X86 */ #ifdef CPU_POWERPC if ((cpuFlavour & CPU_OPTION_64_BITS) != 0) { /* p->methods.create_output_with_brightness = ppc_brightness_G5; */ p->methods.zoom_filter = ppc_zoom_generic; } else if ((cpuFlavour & CPU_OPTION_ALTIVEC) != 0) { /* p->methods.create_output_with_brightness = ppc_brightness_G4; */ p->methods.zoom_filter = ppc_zoom_G4; } else { /* p->methods.create_output_with_brightness = ppc_brightness_generic;*/ p->methods.zoom_filter = ppc_zoom_generic; } #endif /* CPU_POWERPC */ } void plugin_info_init(PluginInfo *pp, int nbVisuals) { PluginInfo p; int i; memset(&p, 0, sizeof(p)); p.sound.speedvar = p.sound.accelvar = p.sound.totalgoom = 0; p.sound.prov_max = 0; p.sound.goom_limit = 1; p.sound.allTimesMax = 1; p.sound.volume_p = secure_f_feedback("Sound Volume"); p.sound.accel_p = secure_f_feedback("Sound Acceleration"); p.sound.speed_p = secure_f_feedback("Sound Speed"); p.sound.goom_limit_p = secure_f_feedback("Goom Limit"); p.sound.last_goom_p = secure_f_feedback("Goom Detection"); p.sound.last_biggoom_p = secure_f_feedback("Big Goom Detection"); p.sound.goom_power_p = secure_f_feedback("Goom Power"); p.sound.biggoom_speed_limit_p = secure_i_param("Big Goom Speed Limit"); IVAL(p.sound.biggoom_speed_limit_p) = 10; IMIN(p.sound.biggoom_speed_limit_p) = 0; IMAX(p.sound.biggoom_speed_limit_p) = 100; ISTEP(p.sound.biggoom_speed_limit_p) = 1; p.sound.biggoom_factor_p = secure_i_param("Big Goom Factor"); IVAL(p.sound.biggoom_factor_p) = 10; IMIN(p.sound.biggoom_factor_p) = 0; IMAX(p.sound.biggoom_factor_p) = 100; ISTEP(p.sound.biggoom_factor_p) = 1; p.sound.params = plugin_parameters ("Sound", 11); p.nbParams = 0; p.nbVisuals = nbVisuals; p.visuals = (VisualFX**)malloc(sizeof(VisualFX*)*nbVisuals); *pp = p; pp->sound.params.params[0] = &pp->sound.biggoom_speed_limit_p; pp->sound.params.params[1] = &pp->sound.biggoom_factor_p; pp->sound.params.params[2] = 0; pp->sound.params.params[3] = &pp->sound.volume_p; pp->sound.params.params[4] = &pp->sound.accel_p; pp->sound.params.params[5] = &pp->sound.speed_p; pp->sound.params.params[6] = 0; pp->sound.params.params[7] = &pp->sound.goom_limit_p; pp->sound.params.params[8] = &pp->sound.goom_power_p; pp->sound.params.params[9] = &pp->sound.last_goom_p; pp->sound.params.params[10] = &pp->sound.last_biggoom_p; pp->statesNumber = 8; pp->statesRangeMax = 510; { GoomState states[8] = { {1,0,0,1,4, 0, 100}, {1,0,0,0,1, 101, 140}, {1,0,0,1,2, 141, 200}, {0,1,0,1,2, 201, 260}, {0,1,0,1,0, 261, 330}, {0,1,1,1,4, 331, 400}, {0,0,1,0,5, 401, 450}, {0,0,1,1,1, 451, 510}}; for (i=0;i<8;++i) pp->states[i] = states[i]; } pp->curGState = &(pp->states[6]); /* datas for the update loop */ pp->update.lockvar = 0; pp->update.goomvar = 0; pp->update.loopvar = 0; pp->update.stop_lines = 0; pp->update.ifs_incr = 1; /* dessiner l'ifs (0 = non: > = increment) */ pp->update.decay_ifs = 0; /* disparition de l'ifs */ pp->update.recay_ifs = 0; /* dedisparition de l'ifs */ pp->update.cyclesSinceLastChange = 0; pp->update.drawLinesDuration = 80; pp->update.lineMode= pp->update.drawLinesDuration; pp->update.switchMultAmount = (29.0f/30.0f); pp->update.switchIncrAmount = 0x7f; pp->update.switchMult = 1.0f; pp->update.switchIncr = pp->update.switchIncrAmount; pp->update.stateSelectionRnd = 0; pp->update.stateSelectionBlocker = 0; pp->update.previousZoomSpeed = 128; pp->update.timeOfTitleDisplay = 0; pp->update_message.affiche = 0; { ZoomFilterData zfd = { 127, 8, 16, 1, 1, 0, NORMAL_MODE, 0, 0, 0, 0, 0 }; pp->update.zoomFilterData = zfd; } setOptimizedMethods(pp); /* default script is empty, no need to load it. pp->scanner = gsl_new(); pp->main_scanner = gsl_new(); pp->main_script_str = GOOM_MAIN_SCRIPT; */ for (i = 0; i < 0xffff; i++) { pp->sintable[i] = (int) (1024 * sin ((double) i * 360 / (sizeof (pp->sintable) / sizeof (pp->sintable[0]) - 1) * M_PI / 180) + .5); /* sintable [us] = (int)(1024.0f * sin (us*2*3.31415f/0xffff)) ; */ } } void plugin_info_add_visual(PluginInfo *p, int i, VisualFX *visual) { p->visuals[i] = visual; if (i == p->nbVisuals-1) { ++i; p->nbParams = 1; while (i--) { if (p->visuals[i]->params) p->nbParams++; } p->params = (PluginParameters *)malloc(sizeof(PluginParameters)*p->nbParams); i = p->nbVisuals; p->nbParams = 1; p->params[0] = p->sound.params; while (i--) { if (p->visuals[i]->params) p->params[p->nbParams++] = *(p->visuals[i]->params); } } } ������������������������������������xine-lib-1.2/src/post/goom/drawmethods.h������������������������������������������������������������0000644�0001750�0001750�00000000341�14647725152�016071� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _DRAWMETHODS_H #define _DRAWMETHODS_H #include "goom_config.h" #include "goom_graphic.h" void draw_line (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny); #endif /* _DRAWMETHODS_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_plugin_info.h�������������������������������������������������������0000644�0001750�0001750�00000010203�14647725152�017100� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _PLUGIN_INFO_H #define _PLUGIN_INFO_H #include "goom_typedefs.h" #include "goom_config.h" #include "goom_graphic.h" #include "goom_config_param.h" #include "goom_visual_fx.h" #include "goom_filters.h" #include "goom_tools.h" #include "goomsl.h" typedef struct { char drawIFS; char drawPoints; char drawTentacle; char drawScope; int farScope; int rangemin; int rangemax; } GoomState; #define STATES_MAX_NB 128 /** * Gives informations about the sound. */ struct _SOUND_INFO { /* nota : a Goom is just a sound event... */ int timeSinceLastGoom; /* >= 0 */ float goomPower; /* power of the last Goom [0..1] */ int timeSinceLastBigGoom; /* >= 0 */ float volume; /* [0..1] */ short samples[2][512]; /* other "internal" datas for the sound_tester */ float goom_limit; /* auto-updated limit of goom_detection */ float bigGoomLimit; float accelvar; /* acceleration of the sound - [0..1] */ float speedvar; /* speed of the sound - [0..100] */ int allTimesMax; int totalgoom; /* number of goom since last reset * (a reset every 64 cycles) */ float prov_max; /* accel max since last reset */ int cycle; /* private */ PluginParam volume_p; PluginParam speed_p; PluginParam accel_p; PluginParam goom_limit_p; PluginParam goom_power_p; PluginParam last_goom_p; PluginParam last_biggoom_p; PluginParam biggoom_speed_limit_p; PluginParam biggoom_factor_p; PluginParameters params; /* contains the previously defined parameters. */ }; /** * Allows FXs to know the current state of the plugin. */ struct _PLUGIN_INFO { /* public datas */ int nbParams; PluginParameters *params; /* private datas */ struct _SIZE_TYPE { int width; int height; int size; /* == screen.height * screen.width. */ } screen; SoundInfo sound; int nbVisuals; VisualFX **visuals; /* pointers on all the visual fx */ /** The known FX */ VisualFX convolve_fx; VisualFX star_fx; VisualFX zoomFilter_fx; VisualFX tentacles_fx; VisualFX ifs_fx; struct goomfont_s *font; /** image buffers */ guint32 *pixel; guint32 *back; Pixel *p1, *p2; Pixel *conv; Pixel *outputBuf; /** state of goom */ guint32 cycle; GoomState states[STATES_MAX_NB]; int statesNumber; int statesRangeMax; GoomState *curGState; /** effet de ligne.. */ GMLine *gmline1; GMLine *gmline2; /** sinus table */ int sintable[0x10000]; /* INTERNALS */ /** goom_update internals. * I took all static variables from goom_update and put them here.. for the moment. */ struct { int lockvar; /* pour empecher de nouveaux changements */ int goomvar; /* boucle des gooms */ int loopvar; /* mouvement des points */ int stop_lines; int ifs_incr; /* dessiner l'ifs (0 = non: > = increment) */ int decay_ifs; /* disparition de l'ifs */ int recay_ifs; /* dedisparition de l'ifs */ int cyclesSinceLastChange; /* nombre de Cycle Depuis Dernier Changement */ int drawLinesDuration; /* duree de la transition entre afficher les lignes ou pas */ int lineMode; /* l'effet lineaire a dessiner */ float switchMultAmount; /* SWITCHMULT (29.0f/30.0f) */ int switchIncrAmount; /* 0x7f */ float switchMult; /* 1.0f */ int switchIncr; /* = SWITCHINCR; */ int stateSelectionRnd; int stateSelectionBlocker; int previousZoomSpeed; int timeOfTitleDisplay; char titleText[1024]; ZoomFilterData zoomFilterData; } update; struct { int numberOfLinesInMessage; char message[0x800]; int affiche; int longueur; } update_message; struct { void (*draw_line) (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny); void (*zoom_filter) (int sizeX, int sizeY, Pixel *src, Pixel *dest, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); } methods; GoomRandom *gRandom; /* GoomSL *scanner; GoomSL *main_scanner; const char *main_script_str; */ }; void plugin_info_init(PluginInfo *p, int nbVisual); /* i = [0..p->nbVisual-1] */ void plugin_info_add_visual(PluginInfo *p, int i, VisualFX *visual); #endif ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/lines.c������������������������������������������������������������������0000644�0001750�0001750�00000012344�14647725152�014663� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * lines.c */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "lines.h" #include <math.h> #include <stdlib.h> #include <stdio.h> #include "goom_tools.h" #include "drawmethods.h" #include "goom_plugin_info.h" static inline unsigned char lighten (unsigned char value, float power) { int val = value; float t = (float) val * log10(power) / 2.0; if (t > 0) { val = (int) t; /* (32.0f * log (t)); */ if (val > 255) val = 255; if (val < 0) val = 0; return val; } else { return 0; } } static void lightencolor (guint32 *col, float power) { unsigned char *color; color = (unsigned char *) col; *color = lighten (*color, power); color++; *color = lighten (*color, power); color++; *color = lighten (*color, power); color++; *color = lighten (*color, power); } static void genline (int id, float param, GMUnitPointer * l, int rx, int ry) { int i; switch (id) { case GML_HLINE: for (i = 0; i < 512; i++) { l[i].x = ((float) i * rx) / 512.0f; l[i].y = param; l[i].angle = M_PI / 2.0f; } return; case GML_VLINE: for (i = 0; i < 512; i++) { l[i].y = ((float) i * ry) / 512.0f; l[i].x = param; l[i].angle = 0.0f; } return; case GML_CIRCLE: for (i = 0; i < 512; i++) { float cosa, sina; l[i].angle = 2.0f * M_PI * (float) i / 512.0f; cosa = param * cos (l[i].angle); sina = param * sin (l[i].angle); l[i].x = ((float) rx / 2.0f) + cosa; l[i].y = (float) ry / 2.0f + sina; } return; } } static guint32 getcouleur (int mode) { switch (mode) { case GML_RED: return (230 << (ROUGE * 8)) | (120 << (VERT * 8)) | (18 << (BLEU * 8)); case GML_ORANGE_J: return (120 << (VERT * 8)) | (252 << (ROUGE * 8)) | (18 << (BLEU * 8)); case GML_ORANGE_V: return (160 << (VERT * 8)) | (236 << (ROUGE * 8)) | (40 << (BLEU * 8)); case GML_BLEUBLANC: return (40 << (BLEU * 8)) | (220 << (ROUGE * 8)) | (140 << (VERT * 8)); case GML_VERT: return (200 << (VERT * 8)) | (80 << (ROUGE * 8)) | (18 << (BLEU * 8)); case GML_BLEU: return (250 << (BLEU * 8)) | (30 << (VERT * 8)) | (80 << (ROUGE * 8)); case GML_BLACK: return (16 << (BLEU * 8)) | (16 << (VERT * 8)) | (16 << (ROUGE * 8)); } return 0; } void goom_lines_set_res (GMLine * gml, int rx, int ry) { if (gml != NULL) { gml->screenX = rx; gml->screenY = ry; genline (gml->IDdest, gml->param, gml->points2, rx, ry); } } static void goom_lines_move (GMLine * l) { int i; unsigned char *c1, *c2; for (i = 0; i < 512; i++) { l->points[i].x = (l->points2[i].x + 39.0f * l->points[i].x) / 40.0f; l->points[i].y = (l->points2[i].y + 39.0f * l->points[i].y) / 40.0f; l->points[i].angle = (l->points2[i].angle + 39.0f * l->points[i].angle) / 40.0f; } c1 = (unsigned char *) &l->color; c2 = (unsigned char *) &l->color2; for (i = 0; i < 4; i++) { int cc1, cc2; cc1 = *c1; cc2 = *c2; *c1 = (unsigned char) ((cc1 * 63 + cc2) >> 6); ++c1; ++c2; } l->power += l->powinc; if (l->power < 1.1f) { l->power = 1.1f; l->powinc = (float) (goom_irand(l->goomInfo->gRandom,20) + 10) / 300.0f; } if (l->power > 17.5f) { l->power = 17.5f; l->powinc = -(float) (goom_irand(l->goomInfo->gRandom,20) + 10) / 300.0f; } l->amplitude = (99.0f * l->amplitude + l->amplitudeF) / 100.0f; } void goom_lines_switch_to (GMLine * gml, int IDdest, float param, float amplitude, int col) { genline (IDdest, param, gml->points2, gml->screenX, gml->screenY); gml->IDdest = IDdest; gml->param = param; gml->amplitudeF = amplitude; gml->color2 = getcouleur (col); } GMLine * goom_lines_init (PluginInfo *goomInfo, int rx, int ry, int IDsrc, float paramS, int coulS, int IDdest, float paramD, int coulD) { GMLine *l = (GMLine *) malloc (sizeof (GMLine)); l->goomInfo = goomInfo; l->points = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer)); l->points2 = (GMUnitPointer *) malloc (512 * sizeof (GMUnitPointer)); l->nbPoints = 512; l->IDdest = IDdest; l->param = paramD; l->amplitude = l->amplitudeF = 1.0f; genline (IDsrc, paramS, l->points, rx, ry); genline (IDdest, paramD, l->points2, rx, ry); l->color = getcouleur (coulS); l->color2 = getcouleur (coulD); l->screenX = rx; l->screenY = ry; l->power = 0.0f; l->powinc = 0.01f; goom_lines_switch_to (l, IDdest, paramD, 1.0f, coulD); return l; } void goom_lines_free (GMLine ** l) { free ((*l)->points2); free ((*l)->points); free (*l); l = NULL; } void goom_lines_draw (PluginInfo *plug, GMLine * line, gint16 data[512], Pixel *p) { if (line != NULL) { int i, x1, y1; guint32 color = line->color; GMUnitPointer *pt = &(line->points[0]); float cosa = cos (pt->angle) / 1000.0f; float sina = sin (pt->angle) / 1000.0f; lightencolor (&color, line->power); x1 = (int) (pt->x + cosa * line->amplitude * data[0]); y1 = (int) (pt->y + sina * line->amplitude * data[0]); for (i = 1; i < 512; i++) { int x2, y2; GMUnitPointer *pt = &(line->points[i]); float cosa = cos (pt->angle) / 1000.0f; float sina = sin (pt->angle) / 1000.0f; x2 = (int) (pt->x + cosa * line->amplitude * data[i]); y2 = (int) (pt->y + sina * line->amplitude * data[i]); plug->methods.draw_line (p, x1, y1, x2, y2, color, line->screenX, line->screenY); x1 = x2; y1 = y2; } goom_lines_move (line); } } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/ppc_drawings.h�����������������������������������������������������������0000644�0001750�0001750�00000001007�14647725152�016230� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * ppc_drawings.h * Goom * * Created by Guillaume Borios on Sun Dec 28 2003. * Copyright (c) 2003 iOS. All rights reserved. * */ /* Generic PowerPC Code */ void ppc_brightness_generic(Pixel *src, Pixel *dest, int size, int coeff); /* G4 Specific PowerPC Code (Possible use of Altivec and Data Streams) */ void ppc_brightness_G4(Pixel *src, Pixel *dest, int size, int coeff); /* G5 Specific PowerPC Code (Possible use of Altivec) */ void ppc_brightness_G5(Pixel *src, Pixel *dest, int size, int coeff); �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/gfontlib.c���������������������������������������������������������������0000644�0001750�0001750�00000022510�14647725152�015351� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goom_config.h" #include "gfontrle.c" #include "gfontlib.h" #include <string.h> #include <stdlib.h> struct goomfont_s { Pixel ***font_chars; int *font_width; int *font_height; Pixel ***small_font_chars; int *small_font_width; int *small_font_height; }; void gfont_unload(goomfont_t **pp) { if (*pp) { goomfont_t *p = *pp; int i, y; for (i = 0; i < 256; i++) { if (p->font_chars[i] && (i == 42 || p->font_chars[i] != p->font_chars[42])) { for (y = 0; y < p->font_height[i]; y++) { free(p->font_chars[i][y]); } free(p->font_chars[i]); } if (p->small_font_chars[i] && (i == 42 || p->small_font_chars[i] != p->small_font_chars[42])) { for (y = 0; y < p->font_height[i]/2; y++) { free(p->small_font_chars[i][y]); } free(p->small_font_chars[i]); } } free(p->font_chars); free(p->small_font_chars); free(p->font_width); free(p->small_font_width); free(p->font_height); free(p->small_font_height); memset(p, 0, sizeof(*p)); free(p); *pp = NULL; } } goomfont_t *gfont_load (void) { unsigned char *gfont; unsigned int i = 0, j = 0; unsigned int nba = 0; unsigned int current = 32; int *font_pos; goomfont_t *p; /* decompress le rle */ p = calloc(1, sizeof(*p)); if (!p) return NULL; gfont = malloc (the_font.width*the_font.height*the_font.bytes_per_pixel); while (i<the_font.rle_size) { unsigned char c = the_font.rle_pixel [i++]; if (c == 0) { unsigned int nb = the_font.rle_pixel [i++]; while (nb--) gfont[j++] = 0; } else gfont [j++] = c; } /* determiner les positions de chaque lettre. */ p->font_height = calloc (256,sizeof(int)); p->small_font_height = calloc (256,sizeof(int)); p->font_width = calloc (256,sizeof(int)); p->small_font_width = calloc (256,sizeof(int)); p->font_chars = calloc (256,sizeof(int**)); p->small_font_chars = calloc (256,sizeof(int**)); font_pos = calloc (256,sizeof(int)); for (i=0;i<the_font.width;i++) { unsigned char a = gfont [i*4 + 3]; if (a) nba ++; else nba = 0; if (nba == 2) { p->font_width [current] = i - font_pos [current]; p->small_font_width [current] = p->font_width [current]/2; font_pos [++current] = i; p->font_height [current] = the_font.height - 2; p->small_font_height [current] = p->font_height [current]/2; } } font_pos [current] = 0; p->font_height [current] = 0; p->small_font_height [current] = 0; /* charger les lettres et convertir au format de la machine */ for (i=33;i<current;i++) { int x; int y; p->font_chars [i] = malloc (p->font_height[i]*sizeof(int *)); p->small_font_chars [i] = malloc (p->font_height[i]*sizeof(int *)/2); for (y = 0; y < p->font_height[i]; y++) { p->font_chars [i][y] = malloc (p->font_width[i]*sizeof(int)); for (x = 0; x < p->font_width[i]; x++) { unsigned int r,g,b,a; r = gfont[(y+2)*(the_font.width*4)+(x*4+font_pos[i]*4)]; g = gfont[(y+2)*(the_font.width*4)+(x*4+font_pos[i]*4+1)]; b = gfont[(y+2)*(the_font.width*4)+(x*4+font_pos[i]*4+2)]; a = gfont[(y+2)*(the_font.width*4)+(x*4+font_pos[i]*4+3)]; p->font_chars [i][y][x].val = (r<<(ROUGE*8))|(g<<(VERT*8))|(b<<(BLEU*8))|(a<<(ALPHA*8)); } } for (y = 0; y < p->font_height[i]/2; y++) { p->small_font_chars [i][y] = malloc (p->font_width[i]*sizeof(int)/2); for (x = 0; x < p->font_width[i]/2; x++) { unsigned int r1,g1,b1,a1,r2,g2,b2,a2,r3,g3,b3,a3,r4,g4,b4,a4; r1 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4)]; g1 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4+1)]; b1 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4+2)]; a1 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4+3)]; r2 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4+4)]; g2 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4+5)]; b2 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4+6)]; a2 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4+7)]; r3 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4)]; g3 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4+1)]; b3 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4+2)]; a3 = gfont[(2*y+3)*(the_font.width*4)+(x*8+font_pos[i]*4+3)]; r4 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4+4)]; g4 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4+5)]; b4 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4+6)]; a4 = gfont[2*(y+1)*(the_font.width*4)+(x*8+font_pos[i]*4+7)]; p->small_font_chars [i][y][x].val = (((r1 + r2 + r3 + r4)>>2)<<(ROUGE*8))| (((g1 + g2 + g3 + g4)>>2)<<(VERT*8))| (((b1 + b2 + b3 + b4)>>2)<<(BLEU*8))| (((a1 + a2 + a3 + a4)>>2)<<(ALPHA*8)); } } } /* definir les lettres restantes */ for (i=0;i<256;i++) { if (p->font_chars[i] == 0) { p->font_chars[i] = p->font_chars[42]; p->small_font_chars[i] = p->small_font_chars[42]; p->font_width[i] = p->font_width[42]; font_pos[i] = font_pos[42]; p->font_height[i] = p->font_height[42]; p->small_font_width[i] = p->small_font_width[42]; p->small_font_height[i] = p->small_font_height[42]; } } // XXX free it ??? p->font_width [32] = (the_font.height / 2) - 1; p->small_font_width [32] = p->font_width [32]/2; p->font_chars [32] = 0; p->small_font_chars [32] = 0; free(font_pos); free(gfont); return p; } void goom_draw_text (goomfont_t *p, Pixel * buf,int resolx,int resoly, int x, int y, const char *str, float charspace, int center) { float fx = (float) x; int fin = 0; Pixel ***cur_font_chars; int *cur_font_width; int *cur_font_height; if (resolx>320) { /* printf("use big\n"); */ cur_font_chars = p->font_chars; cur_font_width = p->font_width; cur_font_height = p->font_height; } else { /* printf ("use small\n"); */ cur_font_chars = p->small_font_chars; cur_font_width = p->small_font_width; cur_font_height = p->small_font_height; } if (cur_font_chars == NULL) return ; if (center) { const unsigned char *tmp = (const unsigned char*)str; float lg = -charspace; while (*tmp != '\0') lg += cur_font_width[*(tmp++)] + charspace; fx -= lg / 2; } while (!fin) { unsigned char c = *str; x = (int) fx; if (c == '\0') fin = 1; else if (cur_font_chars[c]==0) { fx += cur_font_width[c] + charspace; } else { int xx, yy; int xmin = x; int xmax = x + cur_font_width[c]; int ymin = y - cur_font_height[c]; int ymax = y; yy = ymin; if (xmin < 0) xmin = 0; if (xmin >= resolx - 1) return; if (xmax >= (int) resolx) xmax = resolx - 1; if (yy < 0) yy = 0; if (yy <= (int) resoly - 1) { if (ymax >= (int) resoly - 1) ymax = resoly - 1; for (; yy < ymax; yy++) for (xx = xmin; xx < xmax; xx++) { Pixel color = cur_font_chars[c][yy - ymin][xx - x]; Pixel transparency; transparency.val = color.val & A_CHANNEL; if (transparency.val) { if (transparency.val==A_CHANNEL) buf[yy * resolx + xx] = color; else { Pixel back = buf[yy * resolx + xx]; unsigned int a1 = color.channels.a; unsigned int a2 = 255 - a1; buf[yy * resolx + xx].channels.r = (unsigned char)((((unsigned int)color.channels.r * a1) + ((unsigned int)back.channels.r * a2)) >> 8); buf[yy * resolx + xx].channels.g = (unsigned char)((((unsigned int)color.channels.g * a1) + ((unsigned int)back.channels.g * a2)) >> 8); buf[yy * resolx + xx].channels.b = (unsigned char)((((unsigned int)color.channels.b * a1) + ((unsigned int)back.channels.b * a2)) >> 8); } } } } fx += cur_font_width[c] + charspace; } str++; } } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_config.h������������������������������������������������������������0000644�0001750�0001750�00000001103�14647725152�016033� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������//#ifdef HAVE_CONFIG_H //#include "config.h" //#endif // //#if WORDS_BIGENDIAN //#define COLOR_ARGB //#else //#define COLOR_BGRA //#endif //#if 1 /* ndef COLOR_BGRA */ /** position des composantes **/ #define BLEU 0 #define VERT 1 #define ROUGE 2 #define ALPHA 3 //#else // #define ROUGE 1 // #define BLEU 3 // #define VERT 2 // #define ALPHA 0 //#endif #ifndef guint32 #define guint8 unsigned char #define guin16 unsigned short #define guint32 unsigned int #define gint8 signed char #define gint16 signed short int #define gint32 signed int #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/mmx.h��������������������������������������������������������������������0000644�0001750�0001750�00000054543�14647725152�014366� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* mmx.h MultiMedia eXtensions GCC interface library for IA32. To use this library, simply include this header file and compile with GCC. You MUST have inlining enabled in order for mmx_ok() to work; this can be done by simply using -O on the GCC command line. Compiling with -DMMX_TRACE will cause detailed trace output to be sent to stderr for each mmx operation. This adds lots of code, and obviously slows execution to a crawl, but can be very useful for debugging. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ANY PARTICULAR PURPOSE. 1997-99 by H. Dietz and R. Fisher Notes: It appears that the latest gas has the pand problem fixed, therefore I'll undefine BROKEN_PAND by default. */ #ifndef _MMX_H #define _MMX_H # if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included in source file ! # endif //#ifdef HAVE_CONFIG_H //# include "config.h" //#endif #include <xine/attributes.h> #include "goom_graphic.h" /* Warning: at this writing, the version of GAS packaged with most Linux distributions does not handle the parallel AND operation mnemonic correctly. If the symbol BROKEN_PAND is defined, a slower alternative coding will be used. If execution of mmxtest results in an illegal instruction fault, define this symbol. */ #undef BROKEN_PAND /* The type of an value that fits in an MMX register (note that long long constant values MUST be suffixed by LL and unsigned long long values by ULL, lest they be truncated by the compiler) */ typedef union { long long q; /* Quadword (64-bit) value */ unsigned long long uq; /* Unsigned Quadword */ int d[2]; /* 2 Doubleword (32-bit) values */ unsigned int ud[2]; /* 2 Unsigned Doubleword */ short w[4]; /* 4 Word (16-bit) values */ unsigned short uw[4]; /* 4 Unsigned Word */ char b[8]; /* 8 Byte (8-bit) values */ unsigned char ub[8]; /* 8 Unsigned Byte */ float s[2]; /* Single-precision (32-bit) value */ } ATTR_ALIGN(8) mmx_t; /* On an 8-byte (64-bit) boundary */ /* Function to test if multimedia instructions are supported... */ static int mm_support(void) { /* Returns 1 if MMX instructions are supported, 3 if Cyrix MMX and Extended MMX instructions are supported 5 if AMD MMX and 3DNow! instructions are supported 13 if AMD Extended MMX, &3dNow supported 0 if hardware does not support any of these */ #if defined(ARCH_X86_X32) || defined(ARCH_X86_64) return 13; #else register int rval = 0; __asm__ __volatile__ ( /* See if CPUID instruction is supported ... */ /* ... Get copies of EFLAGS into eax and ecx */ "pushl %%ebx\n\t" "pushf\n\t" "popl %%eax\n\t" "movl %%eax, %%ecx\n\t" /* ... Toggle the ID bit in one copy and store */ /* to the EFLAGS reg */ "xorl $0x200000, %%eax\n\t" "push %%eax\n\t" "popf\n\t" /* ... Get the (hopefully modified) EFLAGS */ "pushf\n\t" "popl %%eax\n\t" /* ... Compare and test result */ "xorl %%eax, %%ecx\n\t" "testl $0x200000, %%ecx\n\t" "jz NotSupported1\n\t" /* CPUID not supported */ /* Get standard CPUID information, and go to a specific vendor section */ "movl $0, %%eax\n\t" "cpuid\n\t" /* Check for Intel */ "cmpl $0x756e6547, %%ebx\n\t" "jne TryAMD\n\t" "cmpl $0x49656e69, %%edx\n\t" "jne TryAMD\n\t" "cmpl $0x6c65746e, %%ecx\n" "jne TryAMD\n\t" "jmp Intel\n\t" /* Check for AMD */ "\nTryAMD:\n\t" "cmpl $0x68747541, %%ebx\n\t" "jne TryCyrix\n\t" "cmpl $0x69746e65, %%edx\n\t" "jne TryCyrix\n\t" "cmpl $0x444d4163, %%ecx\n" "jne TryCyrix\n\t" "jmp AMD\n\t" /* Check for Cyrix */ "\nTryCyrix:\n\t" "cmpl $0x69727943, %%ebx\n\t" "jne NotSupported2\n\t" "cmpl $0x736e4978, %%edx\n\t" "jne NotSupported3\n\t" "cmpl $0x64616574, %%ecx\n\t" "jne NotSupported4\n\t" /* Drop through to Cyrix... */ /* Cyrix Section */ /* See if extended CPUID level 80000001 is supported */ /* The value of CPUID/80000001 for the 6x86MX is undefined according to the Cyrix CPU Detection Guide (Preliminary Rev. 1.01 table 1), so we'll check the value of eax for CPUID/0 to see if standard CPUID level 2 is supported. According to the table, the only CPU which supports level 2 is also the only one which supports extended CPUID levels. */ "cmpl $0x2, %%eax\n\t" "jne MMXtest\n\t" /* Use standard CPUID instead */ /* Extended CPUID supported (in theory), so get extended features */ "movl $0x80000001, %%eax\n\t" "cpuid\n\t" "testl $0x00800000, %%eax\n\t" /* Test for MMX */ "jz NotSupported5\n\t" /* MMX not supported */ "testl $0x01000000, %%eax\n\t" /* Test for Ext'd MMX */ "jnz EMMXSupported\n\t" "movl $1, %0\n\n\t" /* MMX Supported */ "jmp Return\n\n" "EMMXSupported:\n\t" "movl $3, %0\n\n\t" /* EMMX and MMX Supported */ "jmp Return\n\t" /* AMD Section */ "AMD:\n\t" /* See if extended CPUID is supported */ "movl $0x80000000, %%eax\n\t" "cpuid\n\t" "cmpl $0x80000000, %%eax\n\t" "jl MMXtest\n\t" /* Use standard CPUID instead */ /* Extended CPUID supported, so get extended features */ "movl $0x80000001, %%eax\n\t" "cpuid\n\t" "testl $0x00800000, %%edx\n\t" /* Test for MMX */ "jz NotSupported6\n\t" /* MMX not supported */ "testl $0x80000000, %%edx\n\t" /* Test for 3DNow! */ "jnz ThreeDNowSupported\n\t" "movl $1, %0\n\n\t" /* MMX Supported */ "jmp Return\n\n" "ThreeDNowSupported:\n\t" "testl $0x40000000, %%edx\n\t" /* Test AMD Extended MMX */ "jnz AMDXMMXSupported\n\t" "movl $5, %0\n\n\t" /* 3DNow! and MMX Supported */ "jmp Return\n\t" "AMDXMMXSupported:\n\t" "movl $13, %0\n\n\t" /* XMMX, 3DNow! and MMX Supported */ "jmp Return\n\t" /* Intel Section */ "Intel:\n\t" /* Check for MMX */ "MMXtest:\n\t" "movl $1, %%eax\n\t" "cpuid\n\t" "testl $0x00800000, %%edx\n\t" /* Test for MMX */ "jz NotSupported7\n\t" /* MMX Not supported */ "movl $1, %0\n\n\t" /* MMX Supported */ "jmp Return\n\t" /* Nothing supported */ "\nNotSupported1:\n\t" "#movl $101, %0\n\n\t" "\nNotSupported2:\n\t" "#movl $102, %0\n\n\t" "\nNotSupported3:\n\t" "#movl $103, %0\n\n\t" "\nNotSupported4:\n\t" "#movl $104, %0\n\n\t" "\nNotSupported5:\n\t" "#movl $105, %0\n\n\t" "\nNotSupported6:\n\t" "#movl $106, %0\n\n\t" "\nNotSupported7:\n\t" "#movl $107, %0\n\n\t" "movl $0, %0\n\n\t" "Return:\n\t" "popl %%ebx\n\t" : "=X" (rval) : /* no input */ : "eax", "ecx", "edx" ); /* Return */ return(rval); #endif } /* Function to test if mmx instructions are supported... */ static inline int mmx_ok(void) { /* Returns 1 if MMX instructions are supported, 0 otherwise */ return ( mm_support() & 0x1 ); } int mmx_supported (void); int xmmx_supported (void); /* MMX optimized implementations */ void draw_line_mmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny); void draw_line_xmmx (Pixel *data, int x1, int y1, int x2, int y2, int col, int screenx, int screeny); void zoom_filter_mmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2, int *brutS, int *brutD, int buffratio, int precalCoef[16][16]); void zoom_filter_xmmx (int prevX, int prevY, Pixel *expix1, Pixel *expix2, int *lbruS, int *lbruD, int buffratio, int precalCoef[16][16]); /* Helper functions for the instruction macros that follow... (note that memory-to-register, m2r, instructions are nearly as efficient as register-to-register, r2r, instructions; however, memory-to-memory instructions are really simulated as a convenience, and are only 1/3 as efficient) */ #ifdef MMX_TRACE /* Include the stuff for printing a trace to stderr... */ #include <stdio.h> #define mmx_i2r(op, imm, reg) \ { \ mmx_t mmx_trace; \ mmx_trace.uq = (imm); \ printf(#op "_i2r(" #imm "=0x%08x%08x, ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ ("movq %%" #reg ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#reg "=0x%08x%08x) => ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "X" (imm)); \ __asm__ __volatile__ ("movq %%" #reg ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#reg "=0x%08x%08x\n", \ mmx_trace.d[1], mmx_trace.d[0]); \ } #define mmx_m2r(op, mem, reg) \ { \ mmx_t mmx_trace; \ mmx_trace = (mem); \ printf(#op "_m2r(" #mem "=0x%08x%08x, ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ ("movq %%" #reg ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#reg "=0x%08x%08x) => ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "m" (mem)); \ __asm__ __volatile__ ("movq %%" #reg ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#reg "=0x%08x%08x\n", \ mmx_trace.d[1], mmx_trace.d[0]); \ } #define mmx_r2m(op, reg, mem) \ { \ mmx_t mmx_trace; \ __asm__ __volatile__ ("movq %%" #reg ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#op "_r2m(" #reg "=0x%08x%08x, ", \ mmx_trace.d[1], mmx_trace.d[0]); \ mmx_trace = (mem); \ printf(#mem "=0x%08x%08x) => ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ (#op " %%" #reg ", %0" \ : "=m" (mem) \ : /* nothing */ ); \ mmx_trace = (mem); \ printf(#mem "=0x%08x%08x\n", \ mmx_trace.d[1], mmx_trace.d[0]); \ } #define mmx_r2r(op, regs, regd) \ { \ mmx_t mmx_trace; \ __asm__ __volatile__ ("movq %%" #regs ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#op "_r2r(" #regs "=0x%08x%08x, ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ ("movq %%" #regd ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#regd "=0x%08x%08x) => ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ (#op " %" #regs ", %" #regd); \ __asm__ __volatile__ ("movq %%" #regd ", %0" \ : "=X" (mmx_trace) \ : /* nothing */ ); \ printf(#regd "=0x%08x%08x\n", \ mmx_trace.d[1], mmx_trace.d[0]); \ } #define mmx_m2m(op, mems, memd) \ { \ mmx_t mmx_trace; \ mmx_trace = (mems); \ printf(#op "_m2m(" #mems "=0x%08x%08x, ", \ mmx_trace.d[1], mmx_trace.d[0]); \ mmx_trace = (memd); \ printf(#memd "=0x%08x%08x) => ", \ mmx_trace.d[1], mmx_trace.d[0]); \ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \ #op " %1, %%mm0\n\t" \ "movq %%mm0, %0" \ : "=m" (memd) \ : "m" (mems)); \ mmx_trace = (memd); \ printf(#memd "=0x%08x%08x\n", \ mmx_trace.d[1], mmx_trace.d[0]); \ } #else /* These macros are a lot simpler without the tracing... */ #define mmx_i2r(op, imm, reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "X" (imm) ) #define mmx_m2r(op, mem, reg) \ __asm__ __volatile__ (#op " %0, %%" #reg \ : /* nothing */ \ : "m" (mem)) #define mmx_r2m(op, reg, mem) \ __asm__ __volatile__ (#op " %%" #reg ", %0" \ : "=m" (mem) \ : /* nothing */ ) #define mmx_r2r(op, regs, regd) \ __asm__ __volatile__ (#op " %" #regs ", %" #regd) #define mmx_m2m(op, mems, memd) \ __asm__ __volatile__ ("movq %0, %%mm0\n\t" \ #op " %1, %%mm0\n\t" \ "movq %%mm0, %0" \ : "=m" (memd) \ : "m" (mems)) #endif /* 1x64 MOVe Quadword (this is both a load and a store... in fact, it is the only way to store) */ #define movq_m2r(var, reg) mmx_m2r(movq, var, reg) #define movq_r2m(reg, var) mmx_r2m(movq, reg, var) #define movq_r2r(regs, regd) mmx_r2r(movq, regs, regd) #define movq(vars, vard) \ __asm__ __volatile__ ("movq %1, %%mm0\n\t" \ "movq %%mm0, %0" \ : "=X" (vard) \ : "X" (vars)) /* 1x32 MOVe Doubleword (like movq, this is both load and store... but is most useful for moving things between mmx registers and ordinary registers) */ #define movd_m2r(var, reg) mmx_m2r(movd, var, reg) #define movd_r2m(reg, var) mmx_r2m(movd, reg, var) #define movd_r2r(regs, regd) mmx_r2r(movd, regs, regd) #define movd(vars, vard) \ __asm__ __volatile__ ("movd %1, %%mm0\n\t" \ "movd %%mm0, %0" \ : "=X" (vard) \ : "X" (vars)) /* 2x32, 4x16, and 8x8 Parallel ADDs */ #define paddd_m2r(var, reg) mmx_m2r(paddd, var, reg) #define paddd_r2r(regs, regd) mmx_r2r(paddd, regs, regd) #define paddd(vars, vard) mmx_m2m(paddd, vars, vard) #define paddw_m2r(var, reg) mmx_m2r(paddw, var, reg) #define paddw_r2r(regs, regd) mmx_r2r(paddw, regs, regd) #define paddw(vars, vard) mmx_m2m(paddw, vars, vard) #define paddb_m2r(var, reg) mmx_m2r(paddb, var, reg) #define paddb_r2r(regs, regd) mmx_r2r(paddb, regs, regd) #define paddb(vars, vard) mmx_m2m(paddb, vars, vard) /* 4x16 and 8x8 Parallel ADDs using Saturation arithmetic */ #define paddsw_m2r(var, reg) mmx_m2r(paddsw, var, reg) #define paddsw_r2r(regs, regd) mmx_r2r(paddsw, regs, regd) #define paddsw(vars, vard) mmx_m2m(paddsw, vars, vard) #define paddsb_m2r(var, reg) mmx_m2r(paddsb, var, reg) #define paddsb_r2r(regs, regd) mmx_r2r(paddsb, regs, regd) #define paddsb(vars, vard) mmx_m2m(paddsb, vars, vard) /* 4x16 and 8x8 Parallel ADDs using Unsigned Saturation arithmetic */ #define paddusw_m2r(var, reg) mmx_m2r(paddusw, var, reg) #define paddusw_r2r(regs, regd) mmx_r2r(paddusw, regs, regd) #define paddusw(vars, vard) mmx_m2m(paddusw, vars, vard) #define paddusb_m2r(var, reg) mmx_m2r(paddusb, var, reg) #define paddusb_r2r(regs, regd) mmx_r2r(paddusb, regs, regd) #define paddusb(vars, vard) mmx_m2m(paddusb, vars, vard) /* 2x32, 4x16, and 8x8 Parallel SUBs */ #define psubd_m2r(var, reg) mmx_m2r(psubd, var, reg) #define psubd_r2r(regs, regd) mmx_r2r(psubd, regs, regd) #define psubd(vars, vard) mmx_m2m(psubd, vars, vard) #define psubw_m2r(var, reg) mmx_m2r(psubw, var, reg) #define psubw_r2r(regs, regd) mmx_r2r(psubw, regs, regd) #define psubw(vars, vard) mmx_m2m(psubw, vars, vard) #define psubb_m2r(var, reg) mmx_m2r(psubb, var, reg) #define psubb_r2r(regs, regd) mmx_r2r(psubb, regs, regd) #define psubb(vars, vard) mmx_m2m(psubb, vars, vard) /* 4x16 and 8x8 Parallel SUBs using Saturation arithmetic */ #define psubsw_m2r(var, reg) mmx_m2r(psubsw, var, reg) #define psubsw_r2r(regs, regd) mmx_r2r(psubsw, regs, regd) #define psubsw(vars, vard) mmx_m2m(psubsw, vars, vard) #define psubsb_m2r(var, reg) mmx_m2r(psubsb, var, reg) #define psubsb_r2r(regs, regd) mmx_r2r(psubsb, regs, regd) #define psubsb(vars, vard) mmx_m2m(psubsb, vars, vard) /* 4x16 and 8x8 Parallel SUBs using Unsigned Saturation arithmetic */ #define psubusw_m2r(var, reg) mmx_m2r(psubusw, var, reg) #define psubusw_r2r(regs, regd) mmx_r2r(psubusw, regs, regd) #define psubusw(vars, vard) mmx_m2m(psubusw, vars, vard) #define psubusb_m2r(var, reg) mmx_m2r(psubusb, var, reg) #define psubusb_r2r(regs, regd) mmx_r2r(psubusb, regs, regd) #define psubusb(vars, vard) mmx_m2m(psubusb, vars, vard) /* 4x16 Parallel MULs giving Low 4x16 portions of results */ #define pmullw_m2r(var, reg) mmx_m2r(pmullw, var, reg) #define pmullw_r2r(regs, regd) mmx_r2r(pmullw, regs, regd) #define pmullw(vars, vard) mmx_m2m(pmullw, vars, vard) /* 4x16 Parallel MULs giving High 4x16 portions of results */ #define pmulhw_m2r(var, reg) mmx_m2r(pmulhw, var, reg) #define pmulhw_r2r(regs, regd) mmx_r2r(pmulhw, regs, regd) #define pmulhw(vars, vard) mmx_m2m(pmulhw, vars, vard) /* 4x16->2x32 Parallel Mul-ADD (muls like pmullw, then adds adjacent 16-bit fields in the multiply result to make the final 2x32 result) */ #define pmaddwd_m2r(var, reg) mmx_m2r(pmaddwd, var, reg) #define pmaddwd_r2r(regs, regd) mmx_r2r(pmaddwd, regs, regd) #define pmaddwd(vars, vard) mmx_m2m(pmaddwd, vars, vard) /* 1x64 bitwise AND */ #ifdef BROKEN_PAND #define pand_m2r(var, reg) \ { \ mmx_m2r(pandn, (mmx_t) -1LL, reg); \ mmx_m2r(pandn, var, reg); \ } #define pand_r2r(regs, regd) \ { \ mmx_m2r(pandn, (mmx_t) -1LL, regd); \ mmx_r2r(pandn, regs, regd) \ } #define pand(vars, vard) \ { \ movq_m2r(vard, mm0); \ mmx_m2r(pandn, (mmx_t) -1LL, mm0); \ mmx_m2r(pandn, vars, mm0); \ movq_r2m(mm0, vard); \ } #else #define pand_m2r(var, reg) mmx_m2r(pand, var, reg) #define pand_r2r(regs, regd) mmx_r2r(pand, regs, regd) #define pand(vars, vard) mmx_m2m(pand, vars, vard) #endif /* 1x64 bitwise AND with Not the destination */ #define pandn_m2r(var, reg) mmx_m2r(pandn, var, reg) #define pandn_r2r(regs, regd) mmx_r2r(pandn, regs, regd) #define pandn(vars, vard) mmx_m2m(pandn, vars, vard) /* 1x64 bitwise OR */ #define por_m2r(var, reg) mmx_m2r(por, var, reg) #define por_r2r(regs, regd) mmx_r2r(por, regs, regd) #define por(vars, vard) mmx_m2m(por, vars, vard) /* 1x64 bitwise eXclusive OR */ #define pxor_m2r(var, reg) mmx_m2r(pxor, var, reg) #define pxor_r2r(regs, regd) mmx_r2r(pxor, regs, regd) #define pxor(vars, vard) mmx_m2m(pxor, vars, vard) /* 2x32, 4x16, and 8x8 Parallel CoMPare for EQuality (resulting fields are either 0 or -1) */ #define pcmpeqd_m2r(var, reg) mmx_m2r(pcmpeqd, var, reg) #define pcmpeqd_r2r(regs, regd) mmx_r2r(pcmpeqd, regs, regd) #define pcmpeqd(vars, vard) mmx_m2m(pcmpeqd, vars, vard) #define pcmpeqw_m2r(var, reg) mmx_m2r(pcmpeqw, var, reg) #define pcmpeqw_r2r(regs, regd) mmx_r2r(pcmpeqw, regs, regd) #define pcmpeqw(vars, vard) mmx_m2m(pcmpeqw, vars, vard) #define pcmpeqb_m2r(var, reg) mmx_m2r(pcmpeqb, var, reg) #define pcmpeqb_r2r(regs, regd) mmx_r2r(pcmpeqb, regs, regd) #define pcmpeqb(vars, vard) mmx_m2m(pcmpeqb, vars, vard) /* 2x32, 4x16, and 8x8 Parallel CoMPare for Greater Than (resulting fields are either 0 or -1) */ #define pcmpgtd_m2r(var, reg) mmx_m2r(pcmpgtd, var, reg) #define pcmpgtd_r2r(regs, regd) mmx_r2r(pcmpgtd, regs, regd) #define pcmpgtd(vars, vard) mmx_m2m(pcmpgtd, vars, vard) #define pcmpgtw_m2r(var, reg) mmx_m2r(pcmpgtw, var, reg) #define pcmpgtw_r2r(regs, regd) mmx_r2r(pcmpgtw, regs, regd) #define pcmpgtw(vars, vard) mmx_m2m(pcmpgtw, vars, vard) #define pcmpgtb_m2r(var, reg) mmx_m2r(pcmpgtb, var, reg) #define pcmpgtb_r2r(regs, regd) mmx_r2r(pcmpgtb, regs, regd) #define pcmpgtb(vars, vard) mmx_m2m(pcmpgtb, vars, vard) /* 1x64, 2x32, and 4x16 Parallel Shift Left Logical */ #define psllq_i2r(imm, reg) mmx_i2r(psllq, imm, reg) #define psllq_m2r(var, reg) mmx_m2r(psllq, var, reg) #define psllq_r2r(regs, regd) mmx_r2r(psllq, regs, regd) #define psllq(vars, vard) mmx_m2m(psllq, vars, vard) #define pslld_i2r(imm, reg) mmx_i2r(pslld, imm, reg) #define pslld_m2r(var, reg) mmx_m2r(pslld, var, reg) #define pslld_r2r(regs, regd) mmx_r2r(pslld, regs, regd) #define pslld(vars, vard) mmx_m2m(pslld, vars, vard) #define psllw_i2r(imm, reg) mmx_i2r(psllw, imm, reg) #define psllw_m2r(var, reg) mmx_m2r(psllw, var, reg) #define psllw_r2r(regs, regd) mmx_r2r(psllw, regs, regd) #define psllw(vars, vard) mmx_m2m(psllw, vars, vard) /* 1x64, 2x32, and 4x16 Parallel Shift Right Logical */ #define psrlq_i2r(imm, reg) mmx_i2r(psrlq, imm, reg) #define psrlq_m2r(var, reg) mmx_m2r(psrlq, var, reg) #define psrlq_r2r(regs, regd) mmx_r2r(psrlq, regs, regd) #define psrlq(vars, vard) mmx_m2m(psrlq, vars, vard) #define psrld_i2r(imm, reg) mmx_i2r(psrld, imm, reg) #define psrld_m2r(var, reg) mmx_m2r(psrld, var, reg) #define psrld_r2r(regs, regd) mmx_r2r(psrld, regs, regd) #define psrld(vars, vard) mmx_m2m(psrld, vars, vard) #define psrlw_i2r(imm, reg) mmx_i2r(psrlw, imm, reg) #define psrlw_m2r(var, reg) mmx_m2r(psrlw, var, reg) #define psrlw_r2r(regs, regd) mmx_r2r(psrlw, regs, regd) #define psrlw(vars, vard) mmx_m2m(psrlw, vars, vard) /* 2x32 and 4x16 Parallel Shift Right Arithmetic */ #define psrad_i2r(imm, reg) mmx_i2r(psrad, imm, reg) #define psrad_m2r(var, reg) mmx_m2r(psrad, var, reg) #define psrad_r2r(regs, regd) mmx_r2r(psrad, regs, regd) #define psrad(vars, vard) mmx_m2m(psrad, vars, vard) #define psraw_i2r(imm, reg) mmx_i2r(psraw, imm, reg) #define psraw_m2r(var, reg) mmx_m2r(psraw, var, reg) #define psraw_r2r(regs, regd) mmx_r2r(psraw, regs, regd) #define psraw(vars, vard) mmx_m2m(psraw, vars, vard) /* 2x32->4x16 and 4x16->8x8 PACK and Signed Saturate (packs source and dest fields into dest in that order) */ #define packssdw_m2r(var, reg) mmx_m2r(packssdw, var, reg) #define packssdw_r2r(regs, regd) mmx_r2r(packssdw, regs, regd) #define packssdw(vars, vard) mmx_m2m(packssdw, vars, vard) #define packsswb_m2r(var, reg) mmx_m2r(packsswb, var, reg) #define packsswb_r2r(regs, regd) mmx_r2r(packsswb, regs, regd) #define packsswb(vars, vard) mmx_m2m(packsswb, vars, vard) /* 4x16->8x8 PACK and Unsigned Saturate (packs source and dest fields into dest in that order) */ #define packuswb_m2r(var, reg) mmx_m2r(packuswb, var, reg) #define packuswb_r2r(regs, regd) mmx_r2r(packuswb, regs, regd) #define packuswb(vars, vard) mmx_m2m(packuswb, vars, vard) /* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK Low (interleaves low half of dest with low half of source as padding in each result field) */ #define punpckldq_m2r(var, reg) mmx_m2r(punpckldq, var, reg) #define punpckldq_r2r(regs, regd) mmx_r2r(punpckldq, regs, regd) #define punpckldq(vars, vard) mmx_m2m(punpckldq, vars, vard) #define punpcklwd_m2r(var, reg) mmx_m2r(punpcklwd, var, reg) #define punpcklwd_r2r(regs, regd) mmx_r2r(punpcklwd, regs, regd) #define punpcklwd(vars, vard) mmx_m2m(punpcklwd, vars, vard) #define punpcklbw_m2r(var, reg) mmx_m2r(punpcklbw, var, reg) #define punpcklbw_r2r(regs, regd) mmx_r2r(punpcklbw, regs, regd) #define punpcklbw(vars, vard) mmx_m2m(punpcklbw, vars, vard) /* 2x32->1x64, 4x16->2x32, and 8x8->4x16 UNPaCK High (interleaves high half of dest with high half of source as padding in each result field) */ #define punpckhdq_m2r(var, reg) mmx_m2r(punpckhdq, var, reg) #define punpckhdq_r2r(regs, regd) mmx_r2r(punpckhdq, regs, regd) #define punpckhdq(vars, vard) mmx_m2m(punpckhdq, vars, vard) #define punpckhwd_m2r(var, reg) mmx_m2r(punpckhwd, var, reg) #define punpckhwd_r2r(regs, regd) mmx_r2r(punpckhwd, regs, regd) #define punpckhwd(vars, vard) mmx_m2m(punpckhwd, vars, vard) #define punpckhbw_m2r(var, reg) mmx_m2r(punpckhbw, var, reg) #define punpckhbw_r2r(regs, regd) mmx_r2r(punpckhbw, regs, regd) #define punpckhbw(vars, vard) mmx_m2m(punpckhbw, vars, vard) /* Empty MMx State (used to clean-up when going from mmx to float use of the registers that are shared by both; note that there is no float-to-mmx operation needed, because only the float tag word info is corruptible) */ #ifdef MMX_TRACE #define emms() \ { \ printf("emms()\n"); \ __asm__ __volatile__ ("emms"); } #else #define emms() __asm__ __volatile__ ("emms") #endif #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl.c�����������������������������������������������������������������0000644�0001750�0001750�00000132170�14647725152�015051� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include <math.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include "goomsl.h" #include "goomsl_private.h" #include "goomsl_yacc.h" /*#define TRACE_SCRIPT*/ /* {{{ definition of the instructions number */ #define INSTR_SETI_VAR_INTEGER 1 #define INSTR_SETI_VAR_VAR 2 #define INSTR_SETF_VAR_FLOAT 3 #define INSTR_SETF_VAR_VAR 4 #define INSTR_NOP 5 /* #define INSTR_JUMP 6 */ #define INSTR_SETP_VAR_PTR 7 #define INSTR_SETP_VAR_VAR 8 #define INSTR_SUBI_VAR_INTEGER 9 #define INSTR_SUBI_VAR_VAR 10 #define INSTR_SUBF_VAR_FLOAT 11 #define INSTR_SUBF_VAR_VAR 12 #define INSTR_ISLOWERF_VAR_VAR 13 #define INSTR_ISLOWERF_VAR_FLOAT 14 #define INSTR_ISLOWERI_VAR_VAR 15 #define INSTR_ISLOWERI_VAR_INTEGER 16 #define INSTR_ADDI_VAR_INTEGER 17 #define INSTR_ADDI_VAR_VAR 18 #define INSTR_ADDF_VAR_FLOAT 19 #define INSTR_ADDF_VAR_VAR 20 #define INSTR_MULI_VAR_INTEGER 21 #define INSTR_MULI_VAR_VAR 22 #define INSTR_MULF_VAR_FLOAT 23 #define INSTR_MULF_VAR_VAR 24 #define INSTR_DIVI_VAR_INTEGER 25 #define INSTR_DIVI_VAR_VAR 26 #define INSTR_DIVF_VAR_FLOAT 27 #define INSTR_DIVF_VAR_VAR 28 /* #define INSTR_JZERO 29 */ #define INSTR_ISEQUALP_VAR_VAR 30 #define INSTR_ISEQUALP_VAR_PTR 31 #define INSTR_ISEQUALI_VAR_VAR 32 #define INSTR_ISEQUALI_VAR_INTEGER 33 #define INSTR_ISEQUALF_VAR_VAR 34 #define INSTR_ISEQUALF_VAR_FLOAT 35 /* #define INSTR_CALL 36 */ /* #define INSTR_RET 37 */ /* #define INSTR_EXT_CALL 38 */ #define INSTR_NOT_VAR 39 /* #define INSTR_JNZERO 40 */ #define INSTR_SETS_VAR_VAR 41 #define INSTR_ISEQUALS_VAR_VAR 42 #define INSTR_ADDS_VAR_VAR 43 #define INSTR_SUBS_VAR_VAR 44 #define INSTR_MULS_VAR_VAR 45 #define INSTR_DIVS_VAR_VAR 46 /* }}} */ /* {{{ definition of the validation error types */ static const char *VALIDATE_OK = "ok"; #define VALIDATE_ERROR "error while validating " #define VALIDATE_TODO "todo" #define VALIDATE_SYNTHAX_ERROR "synthax error" #define VALIDATE_NO_SUCH_INT "no such integer variable" #define VALIDATE_NO_SUCH_VAR "no such variable" #define VALIDATE_NO_SUCH_DEST_VAR "no such destination variable" #define VALIDATE_NO_SUCH_SRC_VAR "no such src variable" /* }}} */ /***********************************/ /* PROTOTYPE OF INTERNAL FUNCTIONS */ /***********************************/ /* {{{ */ static void gsl_instr_free(Instruction *_this); static const char *gsl_instr_validate(Instruction *_this); static void gsl_instr_display(Instruction *_this); static InstructionFlow *iflow_new(void); static void iflow_add_instr(InstructionFlow *_this, Instruction *instr); static void iflow_clean(InstructionFlow *_this); static void iflow_free(InstructionFlow *_this); static void iflow_execute(FastInstructionFlow *_this, GoomSL *gsl); /* }}} */ /************************************/ /* DEFINITION OF INTERNAL FUNCTIONS */ /************************************/ void iflow_free(InstructionFlow *_this) { /* {{{ */ goom_hash_free(_this->labels); free(_this->instr); free(_this); /*TODO: finir cette fonction */ } /* }}} */ void iflow_clean(InstructionFlow *_this) { /* {{{ */ /* TODO: clean chaque instruction du flot */ _this->number = 0; goom_hash_free(_this->labels); _this->labels = goom_hash_new(); } /* }}} */ InstructionFlow *iflow_new(void) { /* {{{ */ InstructionFlow *_this = (InstructionFlow*)malloc(sizeof(InstructionFlow)); _this->number = 0; _this->tabsize = 6; _this->instr = (Instruction**)malloc(_this->tabsize * sizeof(Instruction*)); _this->labels = goom_hash_new(); return _this; } /* }}} */ void iflow_add_instr(InstructionFlow *_this, Instruction *instr) { /* {{{ */ if (_this->number == _this->tabsize) { _this->tabsize *= 2; _this->instr = (Instruction**)realloc(_this->instr, _this->tabsize * sizeof(Instruction*)); } _this->instr[_this->number] = instr; instr->address = _this->number; _this->number++; } /* }}} */ void gsl_instr_set_namespace(Instruction *_this, GoomHash *ns) { /* {{{ */ if (_this->cur_param <= 0) { fprintf(stderr, "ERROR: Line %d, No more params to instructions\n", _this->line_number); exit(1); } _this->vnamespace[_this->cur_param-1] = ns; } /* }}} */ void gsl_instr_add_param(Instruction *instr, const char *param, int type) { /* {{{ */ int len; if (instr==NULL) return; if (instr->cur_param==0) return; --instr->cur_param; len = strlen(param); instr->params[instr->cur_param] = (char*)malloc(len+1); strcpy(instr->params[instr->cur_param], param); instr->types[instr->cur_param] = type; if (instr->cur_param == 0) { const char *result = gsl_instr_validate(instr); if (result != VALIDATE_OK) { printf("ERROR: Line %d: ", instr->parent->num_lines + 1); gsl_instr_display(instr); printf("... %s\n", result); instr->parent->compilationOK = 0; exit(1); } #if USE_JITC_X86 iflow_add_instr(instr->parent->iflow, instr); #else if (instr->id != INSTR_NOP) iflow_add_instr(instr->parent->iflow, instr); else gsl_instr_free(instr); #endif } } /* }}} */ Instruction *gsl_instr_init(GoomSL *parent, const char *name, int id, int nb_param, int line_number) { /* {{{ */ Instruction *instr = (Instruction*)malloc(sizeof(Instruction)); instr->params = (char**)malloc(nb_param*sizeof(char*)); instr->vnamespace = (GoomHash**)malloc(nb_param*sizeof(GoomHash*)); instr->types = (int*)malloc(nb_param*sizeof(int)); instr->cur_param = instr->nb_param = nb_param; instr->parent = parent; instr->id = id; instr->name = name; instr->jump_label = NULL; instr->line_number = line_number; return instr; } /* }}} */ void gsl_instr_free(Instruction *_this) { /* {{{ */ int i; free(_this->types); for (i=_this->cur_param; i<_this->nb_param; ++i) free(_this->params[i]); free(_this->params); free(_this); } /* }}} */ void gsl_instr_display(Instruction *_this) { /* {{{ */ int i=_this->nb_param-1; printf("%s", _this->name); while(i>=_this->cur_param) { printf(" %s", _this->params[i]); --i; } } /* }}} */ /****************************************/ /* VALIDATION OF INSTRUCTION PARAMETERS */ /****************************************/ static const char *validate_v_v(Instruction *_this) { /* {{{ */ HashValue *dest = goom_hash_get(_this->vnamespace[1], _this->params[1]); HashValue *src = goom_hash_get(_this->vnamespace[0], _this->params[0]); if (dest == NULL) { return VALIDATE_NO_SUCH_DEST_VAR; } if (src == NULL) { return VALIDATE_NO_SUCH_SRC_VAR; } _this->data.udest.var = dest->ptr; _this->data.usrc.var = src->ptr; return VALIDATE_OK; } /* }}} */ static const char *validate_v_i(Instruction *_this) { /* {{{ */ HashValue *dest = goom_hash_get(_this->vnamespace[1], _this->params[1]); _this->data.usrc.value_int = strtol(_this->params[0],NULL,0); if (dest == NULL) { return VALIDATE_NO_SUCH_INT; } _this->data.udest.var = dest->ptr; return VALIDATE_OK; } /* }}} */ static const char *validate_v_p(Instruction *_this) { /* {{{ */ HashValue *dest = goom_hash_get(_this->vnamespace[1], _this->params[1]); _this->data.usrc.value_ptr = strtol(_this->params[0],NULL,0); if (dest == NULL) { return VALIDATE_NO_SUCH_INT; } _this->data.udest.var = dest->ptr; return VALIDATE_OK; } /* }}} */ static const char *validate_v_f(Instruction *_this) { /* {{{ */ HashValue *dest = goom_hash_get(_this->vnamespace[1], _this->params[1]); _this->data.usrc.value_float = atof(_this->params[0]); if (dest == NULL) { return VALIDATE_NO_SUCH_VAR; } _this->data.udest.var = dest->ptr; return VALIDATE_OK; } /* }}} */ static const char *validate(Instruction *_this, int vf_f_id, int vf_v_id, int vi_i_id, int vi_v_id, int vp_p_id, int vp_v_id, int vs_v_id) { /* {{{ */ if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FLOAT)) { _this->id = vf_f_id; return validate_v_f(_this); } else if ((_this->types[1] == TYPE_FVAR) && (_this->types[0] == TYPE_FVAR)) { _this->id = vf_v_id; return validate_v_v(_this); } else if ((_this->types[1] == TYPE_IVAR) && (_this->types[0] == TYPE_INTEGER)) { _this->id = vi_i_id; return validate_v_i(_this); } else if ((_this->types[1] == TYPE_IVAR) && (_this->types[0] == TYPE_IVAR)) { _this->id = vi_v_id; return validate_v_v(_this); } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PTR)) { if (vp_p_id == INSTR_NOP) return VALIDATE_ERROR; _this->id = vp_p_id; return validate_v_p(_this); } else if ((_this->types[1] == TYPE_PVAR) && (_this->types[0] == TYPE_PVAR)) { _this->id = vp_v_id; if (vp_v_id == INSTR_NOP) return VALIDATE_ERROR; return validate_v_v(_this); } else if ((_this->types[1] < FIRST_RESERVED) && (_this->types[1] >= 0) && (_this->types[0] == _this->types[1])) { _this->id = vs_v_id; if (vs_v_id == INSTR_NOP) return "Impossible operation to perform between two structs"; return validate_v_v(_this); } return VALIDATE_ERROR; } /* }}} */ const char *gsl_instr_validate(Instruction *_this) { /* {{{ */ if (_this->id != INSTR_EXT_CALL) { int i = _this->nb_param; while (i>0) { i--; if (_this->types[i] == TYPE_VAR) { int type = gsl_type_of_var(_this->vnamespace[i], _this->params[i]); if (type == INSTR_INT) _this->types[i] = TYPE_IVAR; else if (type == INSTR_FLOAT) _this->types[i] = TYPE_FVAR; else if (type == INSTR_PTR) _this->types[i] = TYPE_PVAR; else if ((type >= 0) && (type < FIRST_RESERVED)) _this->types[i] = type; else fprintf(stderr,"WARNING: Line %d, %s has no namespace\n", _this->line_number, _this->params[i]); } } } switch (_this->id) { /* set */ case INSTR_SET: return validate(_this, INSTR_SETF_VAR_FLOAT, INSTR_SETF_VAR_VAR, INSTR_SETI_VAR_INTEGER, INSTR_SETI_VAR_VAR, INSTR_SETP_VAR_PTR, INSTR_SETP_VAR_VAR, INSTR_SETS_VAR_VAR); /* extcall */ case INSTR_EXT_CALL: if (_this->types[0] == TYPE_VAR) { HashValue *fval = goom_hash_get(_this->parent->functions, _this->params[0]); if (fval) { _this->data.udest.external_function = (struct _ExternalFunctionStruct*)fval->ptr; return VALIDATE_OK; } } return VALIDATE_ERROR; /* call */ case INSTR_CALL: if (_this->types[0] == TYPE_LABEL) { _this->jump_label = _this->params[0]; return VALIDATE_OK; } return VALIDATE_ERROR; /* ret */ case INSTR_RET: return VALIDATE_OK; /* jump */ case INSTR_JUMP: if (_this->types[0] == TYPE_LABEL) { _this->jump_label = _this->params[0]; return VALIDATE_OK; } return VALIDATE_ERROR; /* jzero / jnzero */ case INSTR_JZERO: case INSTR_JNZERO: if (_this->types[0] == TYPE_LABEL) { _this->jump_label = _this->params[0]; return VALIDATE_OK; } return VALIDATE_ERROR; /* label */ case INSTR_LABEL: if (_this->types[0] == TYPE_LABEL) { _this->id = INSTR_NOP; _this->nop_label = _this->params[0]; goom_hash_put_int(_this->parent->iflow->labels, _this->params[0], _this->parent->iflow->number); return VALIDATE_OK; } return VALIDATE_ERROR; /* isequal */ case INSTR_ISEQUAL: return validate(_this, INSTR_ISEQUALF_VAR_FLOAT, INSTR_ISEQUALF_VAR_VAR, INSTR_ISEQUALI_VAR_INTEGER, INSTR_ISEQUALI_VAR_VAR, INSTR_ISEQUALP_VAR_PTR, INSTR_ISEQUALP_VAR_VAR, INSTR_ISEQUALS_VAR_VAR); /* not */ case INSTR_NOT: _this->id = INSTR_NOT_VAR; return VALIDATE_OK; /* islower */ case INSTR_ISLOWER: return validate(_this, INSTR_ISLOWERF_VAR_FLOAT, INSTR_ISLOWERF_VAR_VAR, INSTR_ISLOWERI_VAR_INTEGER, INSTR_ISLOWERI_VAR_VAR, INSTR_NOP, INSTR_NOP, INSTR_NOP); /* add */ case INSTR_ADD: return validate(_this, INSTR_ADDF_VAR_FLOAT, INSTR_ADDF_VAR_VAR, INSTR_ADDI_VAR_INTEGER, INSTR_ADDI_VAR_VAR, INSTR_NOP, INSTR_NOP, INSTR_ADDS_VAR_VAR); /* mul */ case INSTR_MUL: return validate(_this, INSTR_MULF_VAR_FLOAT, INSTR_MULF_VAR_VAR, INSTR_MULI_VAR_INTEGER, INSTR_MULI_VAR_VAR, INSTR_NOP, INSTR_NOP, INSTR_MULS_VAR_VAR); /* sub */ case INSTR_SUB: return validate(_this, INSTR_SUBF_VAR_FLOAT, INSTR_SUBF_VAR_VAR, INSTR_SUBI_VAR_INTEGER, INSTR_SUBI_VAR_VAR, INSTR_NOP, INSTR_NOP, INSTR_SUBS_VAR_VAR); /* div */ case INSTR_DIV: return validate(_this, INSTR_DIVF_VAR_FLOAT, INSTR_DIVF_VAR_VAR, INSTR_DIVI_VAR_INTEGER, INSTR_DIVI_VAR_VAR, INSTR_NOP,INSTR_NOP, INSTR_DIVS_VAR_VAR); default: return VALIDATE_TODO; } return VALIDATE_ERROR; } /* }}} */ /*************/ /* EXECUTION */ /*************/ void iflow_execute(FastInstructionFlow *_this, GoomSL *gsl) { /* {{{ */ int flag = 0; int ip = 0; FastInstruction *instr = _this->instr; int stack[0x10000]; int stack_pointer = 0; stack[stack_pointer++] = -1; /* Quelques Macro pour rendre le code plus lisible */ #define pSRC_VAR instr[ip].data.usrc.var #define SRC_VAR_INT *instr[ip].data.usrc.var_int #define SRC_VAR_FLOAT *instr[ip].data.usrc.var_float #define SRC_VAR_PTR *instr[ip].data.usrc.var_ptr #define pDEST_VAR instr[ip].data.udest.var #define DEST_VAR_INT *instr[ip].data.udest.var_int #define DEST_VAR_FLOAT *instr[ip].data.udest.var_float #define DEST_VAR_PTR *instr[ip].data.udest.var_ptr #define VALUE_INT instr[ip].data.usrc.value_int #define VALUE_FLOAT instr[ip].data.usrc.value_float #define VALUE_PTR instr[ip].data.usrc.value_ptr #define JUMP_OFFSET instr[ip].data.udest.jump_offset #define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1] #define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1] #define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i] #define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i] #define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i] #define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i] #define DEST_STRUCT_IBLOCK_VAR(i,j) \ ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j] #define DEST_STRUCT_FBLOCK_VAR(i,j) \ ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j] #define SRC_STRUCT_IBLOCK_VAR(i,j) \ ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j] #define SRC_STRUCT_FBLOCK_VAR(i,j) \ ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j] #define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size while (1) { int i; #ifdef TRACE_SCRIPT printf("execute "); gsl_instr_display(instr[ip].proto); printf("\n"); #endif switch (instr[ip].id) { /* SET.I */ case INSTR_SETI_VAR_INTEGER: DEST_VAR_INT = VALUE_INT; ++ip; break; case INSTR_SETI_VAR_VAR: DEST_VAR_INT = SRC_VAR_INT; ++ip; break; /* SET.F */ case INSTR_SETF_VAR_FLOAT: DEST_VAR_FLOAT = VALUE_FLOAT; ++ip; break; case INSTR_SETF_VAR_VAR: DEST_VAR_FLOAT = SRC_VAR_FLOAT; ++ip; break; /* SET.P */ case INSTR_SETP_VAR_VAR: DEST_VAR_PTR = SRC_VAR_PTR; ++ip; break; case INSTR_SETP_VAR_PTR: DEST_VAR_PTR = VALUE_PTR; ++ip; break; /* JUMP */ case INSTR_JUMP: ip += JUMP_OFFSET; break; /* JZERO */ case INSTR_JZERO: ip += (flag ? 1 : JUMP_OFFSET); break; case INSTR_NOP: ++ip; break; /* ISEQUAL.P */ case INSTR_ISEQUALP_VAR_VAR: flag = (DEST_VAR_PTR == SRC_VAR_PTR); ++ip; break; case INSTR_ISEQUALP_VAR_PTR: flag = (DEST_VAR_PTR == VALUE_PTR); ++ip; break; /* ISEQUAL.I */ case INSTR_ISEQUALI_VAR_VAR: flag = (DEST_VAR_INT == SRC_VAR_INT); ++ip; break; case INSTR_ISEQUALI_VAR_INTEGER: flag = (DEST_VAR_INT == VALUE_INT); ++ip; break; /* ISEQUAL.F */ case INSTR_ISEQUALF_VAR_VAR: flag = (DEST_VAR_FLOAT == SRC_VAR_FLOAT); ++ip; break; case INSTR_ISEQUALF_VAR_FLOAT: flag = (DEST_VAR_FLOAT == VALUE_FLOAT); ++ip; break; /* ISLOWER.I */ case INSTR_ISLOWERI_VAR_VAR: flag = (DEST_VAR_INT < SRC_VAR_INT); ++ip; break; case INSTR_ISLOWERI_VAR_INTEGER: flag = (DEST_VAR_INT < VALUE_INT); ++ip; break; /* ISLOWER.F */ case INSTR_ISLOWERF_VAR_VAR: flag = (DEST_VAR_FLOAT < SRC_VAR_FLOAT); ++ip; break; case INSTR_ISLOWERF_VAR_FLOAT: flag = (DEST_VAR_FLOAT < VALUE_FLOAT); ++ip; break; /* ADD.I */ case INSTR_ADDI_VAR_VAR: DEST_VAR_INT += SRC_VAR_INT; ++ip; break; case INSTR_ADDI_VAR_INTEGER: DEST_VAR_INT += VALUE_INT; ++ip; break; /* ADD.F */ case INSTR_ADDF_VAR_VAR: DEST_VAR_FLOAT += SRC_VAR_FLOAT; ++ip; break; case INSTR_ADDF_VAR_FLOAT: DEST_VAR_FLOAT += VALUE_FLOAT; ++ip; break; /* MUL.I */ case INSTR_MULI_VAR_VAR: DEST_VAR_INT *= SRC_VAR_INT; ++ip; break; case INSTR_MULI_VAR_INTEGER: DEST_VAR_INT *= VALUE_INT; ++ip; break; /* MUL.F */ case INSTR_MULF_VAR_FLOAT: DEST_VAR_FLOAT *= VALUE_FLOAT; ++ip; break; case INSTR_MULF_VAR_VAR: DEST_VAR_FLOAT *= SRC_VAR_FLOAT; ++ip; break; /* DIV.I */ case INSTR_DIVI_VAR_VAR: DEST_VAR_INT /= SRC_VAR_INT; ++ip; break; case INSTR_DIVI_VAR_INTEGER: DEST_VAR_INT /= VALUE_INT; ++ip; break; /* DIV.F */ case INSTR_DIVF_VAR_FLOAT: DEST_VAR_FLOAT /= VALUE_FLOAT; ++ip; break; case INSTR_DIVF_VAR_VAR: DEST_VAR_FLOAT /= SRC_VAR_FLOAT; ++ip; break; /* SUB.I */ case INSTR_SUBI_VAR_VAR: DEST_VAR_INT -= SRC_VAR_INT; ++ip; break; case INSTR_SUBI_VAR_INTEGER: DEST_VAR_INT -= VALUE_INT; ++ip; break; /* SUB.F */ case INSTR_SUBF_VAR_FLOAT: DEST_VAR_FLOAT -= VALUE_FLOAT; ++ip; break; case INSTR_SUBF_VAR_VAR: DEST_VAR_FLOAT -= SRC_VAR_FLOAT; ++ip; break; /* CALL */ case INSTR_CALL: stack[stack_pointer++] = ip + 1; ip += JUMP_OFFSET; break; /* RET */ case INSTR_RET: ip = stack[--stack_pointer]; if (ip<0) return; break; /* EXT_CALL */ case INSTR_EXT_CALL: instr[ip].data.udest.external_function->function(gsl, gsl->vars, instr[ip].data.udest.external_function->vars); ++ip; break; /* NOT */ case INSTR_NOT_VAR: flag = !flag; ++ip; break; /* JNZERO */ case INSTR_JNZERO: ip += (flag ? JUMP_OFFSET : 1); break; case INSTR_SETS_VAR_VAR: memcpy(pDEST_VAR, pSRC_VAR, DEST_STRUCT_SIZE); ++ip; break; case INSTR_ISEQUALS_VAR_VAR: break; case INSTR_ADDS_VAR_VAR: /* process integers */ i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { DEST_STRUCT_IBLOCK_VAR(i,j) += SRC_STRUCT_IBLOCK_VAR(i,j); } ++i; } /* process floats */ i=0; while (DEST_STRUCT_FBLOCK(i).size > 0) { int j=DEST_STRUCT_FBLOCK(i).size; while (j--) { DEST_STRUCT_FBLOCK_VAR(i,j) += SRC_STRUCT_FBLOCK_VAR(i,j); } ++i; } ++ip; break; case INSTR_SUBS_VAR_VAR: /* process integers */ i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { DEST_STRUCT_IBLOCK_VAR(i,j) -= SRC_STRUCT_IBLOCK_VAR(i,j); } ++i; } /* process floats */ i=0; while (DEST_STRUCT_FBLOCK(i).size > 0) { int j=DEST_STRUCT_FBLOCK(i).size; while (j--) { DEST_STRUCT_FBLOCK_VAR(i,j) -= SRC_STRUCT_FBLOCK_VAR(i,j); } ++i; } ++ip; break; case INSTR_MULS_VAR_VAR: /* process integers */ i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { DEST_STRUCT_IBLOCK_VAR(i,j) *= SRC_STRUCT_IBLOCK_VAR(i,j); } ++i; } /* process floats */ i=0; while (DEST_STRUCT_FBLOCK(i).size > 0) { int j=DEST_STRUCT_FBLOCK(i).size; while (j--) { DEST_STRUCT_FBLOCK_VAR(i,j) *= SRC_STRUCT_FBLOCK_VAR(i,j); } ++i; } ++ip; break; case INSTR_DIVS_VAR_VAR: /* process integers */ i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { DEST_STRUCT_IBLOCK_VAR(i,j) /= SRC_STRUCT_IBLOCK_VAR(i,j); } ++i; } /* process floats */ i=0; while (DEST_STRUCT_FBLOCK(i).size > 0) { int j=DEST_STRUCT_FBLOCK(i).size; while (j--) { DEST_STRUCT_FBLOCK_VAR(i,j) /= SRC_STRUCT_FBLOCK_VAR(i,j); } ++i; } ++ip; break; default: printf("NOT IMPLEMENTED : %d\n", instr[ip].id); ++ip; exit(1); } } } /* }}} */ int gsl_malloc(GoomSL *_this, int size) { /* {{{ */ if (_this->nbPtr >= _this->ptrArraySize) { _this->ptrArraySize *= 2; _this->ptrArray = (void**)realloc(_this->ptrArray, sizeof(void*) * _this->ptrArraySize); } _this->ptrArray[_this->nbPtr] = malloc(size); return _this->nbPtr++; } /* }}} */ void *gsl_get_ptr(GoomSL *_this, int id) { /* {{{ */ if ((id>=0)&&(id<_this->nbPtr)) return _this->ptrArray[id]; fprintf(stderr,"INVALID GET PTR 0x%08x\n", id); return NULL; } /* }}} */ void gsl_free_ptr(GoomSL *_this, int id) { /* {{{ */ if ((id>=0)&&(id<_this->nbPtr)) { free(_this->ptrArray[id]); _this->ptrArray[id] = 0; } } /* }}} */ void gsl_enternamespace(const char *name) { /* {{{ */ HashValue *val = goom_hash_get(currentGoomSL->functions, name); if (val) { ExternalFunctionStruct *function = (ExternalFunctionStruct*)val->ptr; currentGoomSL->currentNS++; currentGoomSL->namespaces[currentGoomSL->currentNS] = function->vars; } else { fprintf(stderr, "ERROR: Line %d, Could not find namespace: %s\n", currentGoomSL->num_lines, name); exit(1); } } /* }}} */ void gsl_reenternamespace(GoomHash *nsinfo) { currentGoomSL->currentNS++; currentGoomSL->namespaces[currentGoomSL->currentNS] = nsinfo; } GoomHash *gsl_leavenamespace(void) { /* {{{ */ currentGoomSL->currentNS--; return currentGoomSL->namespaces[currentGoomSL->currentNS+1]; } /* }}} */ GoomHash *gsl_find_namespace(const char *name) { /* {{{ */ int i; for (i=currentGoomSL->currentNS;i>=0;--i) { if (goom_hash_get(currentGoomSL->namespaces[i], name)) return currentGoomSL->namespaces[i]; } return NULL; } /* }}} */ void gsl_declare_task(const char *name) { /* {{{ */ if (goom_hash_get(currentGoomSL->functions, name)) { return; } else { ExternalFunctionStruct *gef = (ExternalFunctionStruct*)malloc(sizeof(ExternalFunctionStruct)); gef->function = 0; gef->vars = goom_hash_new(); gef->is_extern = 0; goom_hash_put_ptr(currentGoomSL->functions, name, (void*)gef); } } /* }}} */ void gsl_declare_external_task(const char *name) { /* {{{ */ if (goom_hash_get(currentGoomSL->functions, name)) { fprintf(stderr, "ERROR: Line %d, Duplicate declaration of %s\n", currentGoomSL->num_lines, name); return; } else { ExternalFunctionStruct *gef = (ExternalFunctionStruct*)malloc(sizeof(ExternalFunctionStruct)); gef->function = 0; gef->vars = goom_hash_new(); gef->is_extern = 1; goom_hash_put_ptr(currentGoomSL->functions, name, (void*)gef); } } /* }}} */ static void reset_scanner(GoomSL *gss) { /* {{{ */ gss->num_lines = 0; gss->instr = NULL; iflow_clean(gss->iflow); /* reset variables */ goom_hash_free(gss->vars); gss->vars = goom_hash_new(); gss->currentNS = 0; gss->namespaces[0] = gss->vars; goom_hash_free(gss->structIDS); gss->structIDS = goom_hash_new(); while (gss->nbStructID > 0) { int i; gss->nbStructID--; for(i=0;i<gss->gsl_struct[gss->nbStructID]->nbFields;++i) free(gss->gsl_struct[gss->nbStructID]->fields[i]); free(gss->gsl_struct[gss->nbStructID]); } gss->compilationOK = 1; goom_heap_delete(gss->data_heap); gss->data_heap = goom_heap_new(); } /* }}} */ static void calculate_labels(InstructionFlow *iflow) { /* {{{ */ int i = 0; while (i < iflow->number) { Instruction *instr = iflow->instr[i]; if (instr->jump_label) { HashValue *label = goom_hash_get(iflow->labels,instr->jump_label); if (label) { instr->data.udest.jump_offset = -instr->address + label->i; } else { fprintf(stderr, "ERROR: Line %d, Could not find label %s\n", instr->line_number, instr->jump_label); instr->id = INSTR_NOP; instr->nop_label = 0; exit(1); } } ++i; } } /* }}} */ #ifdef USE_JITC_X86 static int powerOfTwo(int i) { int b; for (b=0;b<31;b++) if (i == (1<<b)) return b; return 0; } #endif /* Cree un flow d'instruction optimise */ static void gsl_create_fast_iflow(void) { /* {{{ */ int number = currentGoomSL->iflow->number; int i; #ifdef USE_JITC_X86 /* pour compatibilite avec les MACROS servant a execution */ int ip = 0; GoomSL *gsl = currentGoomSL; JitcX86Env *jitc; if (currentGoomSL->jitc != NULL) jitc_x86_delete(currentGoomSL->jitc); jitc = currentGoomSL->jitc = jitc_x86_env_new(0xffff); currentGoomSL->jitc_func = jitc_prepare_func(jitc); #if 0 #define SRC_STRUCT_ID instr[ip].data.usrc.var_int[-1] #define DEST_STRUCT_ID instr[ip].data.udest.var_int[-1] #define SRC_STRUCT_IBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i] #define SRC_STRUCT_FBLOCK(i) gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i] #define DEST_STRUCT_IBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i] #define DEST_STRUCT_FBLOCK(i) gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i] #define DEST_STRUCT_IBLOCK_VAR(i,j) \ ((int*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->iBlock[i].data))[j] #define DEST_STRUCT_FBLOCK_VAR(i,j) \ ((float*)((char*)pDEST_VAR + gsl->gsl_struct[DEST_STRUCT_ID]->fBlock[i].data))[j] #define SRC_STRUCT_IBLOCK_VAR(i,j) \ ((int*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->iBlock[i].data))[j] #define SRC_STRUCT_FBLOCK_VAR(i,j) \ ((float*)((char*)pSRC_VAR + gsl->gsl_struct[SRC_STRUCT_ID]->fBlock[i].data))[j] #define DEST_STRUCT_SIZE gsl->gsl_struct[DEST_STRUCT_ID]->size #endif JITC_JUMP_LABEL(jitc, "__very_end__"); JITC_ADD_LABEL (jitc, "__very_start__"); for (i=0;i<number;++i) { Instruction *instr = currentGoomSL->iflow->instr[i]; switch (instr->id) { case INSTR_SETI_VAR_INTEGER : jitc_add(jitc, "mov [$d], $d", instr->data.udest.var_int, instr->data.usrc.value_int); break; case INSTR_SETI_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; /* SET.F */ case INSTR_SETF_VAR_FLOAT : jitc_add(jitc, "mov [$d], $d", instr->data.udest.var_float, *(int*)(&instr->data.usrc.value_float)); break; case INSTR_SETF_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.usrc.var_float); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_float); break; case INSTR_NOP : if (instr->nop_label != 0) JITC_ADD_LABEL(jitc, instr->nop_label); break; case INSTR_JUMP : JITC_JUMP_LABEL(jitc,instr->jump_label); break; case INSTR_SETP_VAR_PTR : jitc_add(jitc, "mov [$d], $d", instr->data.udest.var_ptr, instr->data.usrc.value_ptr); break; case INSTR_SETP_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.usrc.var_ptr); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_ptr); break; case INSTR_SUBI_VAR_INTEGER : jitc_add(jitc, "add [$d], $d", instr->data.udest.var_int, -instr->data.usrc.value_int); break; case INSTR_SUBI_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "sub eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; case INSTR_SUBF_VAR_FLOAT : printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_SUBF_VAR_VAR : printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISLOWERF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISLOWERF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISLOWERI_VAR_VAR: jitc_add(jitc,"mov edx, [$d]", instr->data.udest.var_int); jitc_add(jitc,"sub edx, [$d]", instr->data.usrc.var_int); jitc_add(jitc,"shr edx, $d", 31); break; case INSTR_ISLOWERI_VAR_INTEGER: jitc_add(jitc,"mov edx, [$d]", instr->data.udest.var_int); jitc_add(jitc,"sub edx, $d", instr->data.usrc.value_int); jitc_add(jitc,"shr edx, $d", 31); break; case INSTR_ADDI_VAR_INTEGER: jitc_add(jitc, "add [$d], $d", instr->data.udest.var_int, instr->data.usrc.value_int); break; case INSTR_ADDI_VAR_VAR: jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "add eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; case INSTR_ADDF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ADDF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_MULI_VAR_INTEGER: if (instr->data.usrc.value_int != 1) { int po2 = powerOfTwo(instr->data.usrc.value_int); if (po2) { /* performs (V / 2^n) by doing V >> n */ jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "sal eax, $d", po2); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); } else { jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "imul eax, $d", instr->data.usrc.value_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); } } break; case INSTR_MULI_VAR_VAR: jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "imul eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; case INSTR_MULF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_MULF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_DIVI_VAR_INTEGER: if ((instr->data.usrc.value_int != 1) && (instr->data.usrc.value_int != 0)) { int po2 = powerOfTwo(instr->data.usrc.value_int); if (po2) { /* performs (V / 2^n) by doing V >> n */ jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "sar eax, $d", po2); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); } else { /* performs (V/n) by doing (V*(32^2/n)) */ long coef; double dcoef = (double)4294967296.0 / (double)instr->data.usrc.value_int; if (dcoef < 0.0) dcoef = -dcoef; coef = (long)floor(dcoef); dcoef -= floor(dcoef); if (dcoef < 0.5) coef += 1; jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "mov edx, $d", coef); jitc_add(jitc, "imul edx"); if (instr->data.usrc.value_int < 0) jitc_add(jitc, "neg edx"); jitc_add(jitc, "mov [$d], edx", instr->data.udest.var_int); } } break; case INSTR_DIVI_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "cdq"); /* sign extend eax into edx */ jitc_add(jitc, "idiv [$d]", instr->data.usrc.var_int); jitc_add(jitc, "mov [$d], eax", instr->data.udest.var_int); break; case INSTR_DIVF_VAR_FLOAT: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_DIVF_VAR_VAR: printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_JZERO: jitc_add(jitc, "cmp edx, $d", 0); jitc_add(jitc, "je $s", instr->jump_label); break; case INSTR_ISEQUALP_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_ptr); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, [$d]", instr->data.usrc.var_ptr); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALP_VAR_PTR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_ptr); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, $d", instr->data.usrc.value_ptr); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALI_VAR_VAR : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, [$d]", instr->data.usrc.var_int); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALI_VAR_INTEGER : jitc_add(jitc, "mov eax, [$d]", instr->data.udest.var_int); jitc_add(jitc, "mov edx, $d", 0); jitc_add(jitc, "cmp eax, $d", instr->data.usrc.value_int); jitc_add(jitc, "jne $d", 1); jitc_add(jitc, "inc edx"); break; case INSTR_ISEQUALF_VAR_VAR : printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_ISEQUALF_VAR_FLOAT : printf("NOT IMPLEMENTED : %d\n", instr->id); break; case INSTR_CALL: jitc_add(jitc, "call $s", instr->jump_label); break; case INSTR_RET: jitc_add(jitc, "ret"); break; case INSTR_EXT_CALL: jitc_add(jitc, "mov eax, [$d]", &(instr->data.udest.external_function->vars)); jitc_add(jitc, "push eax"); jitc_add(jitc, "mov edx, [$d]", &(currentGoomSL->vars)); jitc_add(jitc, "push edx"); jitc_add(jitc, "mov eax, [$d]", &(currentGoomSL)); jitc_add(jitc, "push eax"); jitc_add(jitc, "mov eax, [$d]", &(instr->data.udest.external_function)); jitc_add(jitc, "mov eax, [eax]"); jitc_add(jitc, "call [eax]"); jitc_add(jitc, "add esp, $d", 12); break; case INSTR_NOT_VAR: jitc_add(jitc, "mov eax, edx"); jitc_add(jitc, "mov edx, $d", 1); jitc_add(jitc, "sub edx, eax"); break; case INSTR_JNZERO: jitc_add(jitc, "cmp edx, $d", 0); jitc_add(jitc, "jne $s", instr->jump_label); break; case INSTR_SETS_VAR_VAR: { int loop = DEST_STRUCT_SIZE / sizeof(int); int dst = (int)pDEST_VAR; int src = (int)pSRC_VAR; while (loop--) { jitc_add(jitc,"mov eax, [$d]", src); jitc_add(jitc,"mov [$d], eax", dst); src += 4; dst += 4; } } break; case INSTR_ISEQUALS_VAR_VAR: break; case INSTR_ADDS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { /* TODO interlace 2 */ jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "add eax, [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } /* process floats */ i=0; while (DEST_STRUCT_FBLOCK(i).size > 0) { int j=DEST_STRUCT_FBLOCK(i).size; while (j--) { /* DEST_STRUCT_FBLOCK_VAR(i,j) += SRC_STRUCT_FBLOCK_VAR(i,j); */ /* TODO */ } ++i; } break; } case INSTR_SUBS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "sub eax, [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } break; } case INSTR_MULS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "imul eax, [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } break; } case INSTR_DIVS_VAR_VAR: { /* process integers */ int i=0; while (DEST_STRUCT_IBLOCK(i).size > 0) { int j=DEST_STRUCT_IBLOCK(i).size; while (j--) { jitc_add(jitc, "mov eax, [$d]", &DEST_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "cdq"); jitc_add(jitc, "idiv [$d]", &SRC_STRUCT_IBLOCK_VAR(i,j)); jitc_add(jitc, "mov [$d], eax", &DEST_STRUCT_IBLOCK_VAR(i,j)); } ++i; } break; } } } JITC_ADD_LABEL (jitc, "__very_end__"); jitc_add(jitc, "call $s", "__very_start__"); jitc_add(jitc, "mov eax, $d", 0); jitc_validate_func(jitc); #else InstructionFlow *iflow = currentGoomSL->iflow; FastInstructionFlow *fastiflow = (FastInstructionFlow*)malloc(sizeof(FastInstructionFlow)); fastiflow->mallocedInstr = calloc(number*16, sizeof(FastInstruction)); /* fastiflow->instr = (FastInstruction*)(((int)fastiflow->mallocedInstr) + 16 - (((int)fastiflow->mallocedInstr)%16)); */ fastiflow->instr = (FastInstruction*)fastiflow->mallocedInstr; fastiflow->number = number; for(i=0;i<number;++i) { fastiflow->instr[i].id = iflow->instr[i]->id; fastiflow->instr[i].data = iflow->instr[i]->data; fastiflow->instr[i].proto = iflow->instr[i]; } currentGoomSL->fastiflow = fastiflow; #endif } /* }}} */ void yy_scan_string(const char *str); void yyparse(void); GoomHash *gsl_globals(GoomSL *_this) { return _this->vars; } /** * Some native external functions */ static void ext_charAt(GoomSL *gsl, GoomHash *global, GoomHash *local) { char *string = GSL_LOCAL_PTR(gsl, local, "value"); int index = GSL_LOCAL_INT(gsl, local, "index"); GSL_GLOBAL_INT(gsl, "charAt") = 0; if (string == NULL) { return; } if (index < strlen(string)) GSL_GLOBAL_INT(gsl, "charAt") = string[index]; } static void ext_i2f(GoomSL *gsl, GoomHash *global, GoomHash *local) { int i = GSL_LOCAL_INT(gsl, local, "value"); GSL_GLOBAL_FLOAT(gsl, "i2f") = i; } static void ext_f2i(GoomSL *gsl, GoomHash *global, GoomHash *local) { float f = GSL_LOCAL_FLOAT(gsl, local, "value"); GSL_GLOBAL_INT(gsl, "f2i") = f; } /** * */ void gsl_compile(GoomSL *_currentGoomSL, const char *script) { /* {{{ */ char *script_and_externals; static const char *sBinds = "external <charAt: string value, int index> : int\n" "external <f2i: float value> : int\n" "external <i2f: int value> : float\n"; #ifdef VERBOSE printf("\n=== Starting Compilation ===\n"); #endif script_and_externals = malloc(strlen(script) + strlen(sBinds) + 2); strcpy(script_and_externals, sBinds); strcat(script_and_externals, script); /* 0- reset */ currentGoomSL = _currentGoomSL; reset_scanner(currentGoomSL); /* 1- create the syntaxic tree */ yy_scan_string(script_and_externals); yyparse(); /* 2- generate code */ gsl_commit_compilation(); /* 3- resolve symbols */ calculate_labels(currentGoomSL->iflow); /* 4- optimize code */ gsl_create_fast_iflow(); /* 5- bind a few internal functions */ gsl_bind_function(currentGoomSL, "charAt", ext_charAt); gsl_bind_function(currentGoomSL, "f2i", ext_f2i); gsl_bind_function(currentGoomSL, "i2f", ext_i2f); free(script_and_externals); #ifdef VERBOSE printf("=== Compilation done. # of lines: %d. # of instr: %d ===\n", currentGoomSL->num_lines, currentGoomSL->iflow->number); #endif } /* }}} */ void gsl_execute(GoomSL *scanner) { /* {{{ */ if (scanner->compilationOK) { #if USE_JITC_X86 scanner->jitc_func(); #else iflow_execute(scanner->fastiflow, scanner); #endif } } /* }}} */ GoomSL *gsl_new(void) { /* {{{ */ GoomSL *gss = (GoomSL*)malloc(sizeof(GoomSL)); gss->iflow = iflow_new(); gss->vars = goom_hash_new(); gss->functions = goom_hash_new(); gss->nbStructID = 0; gss->structIDS = goom_hash_new(); gss->gsl_struct_size = 32; gss->gsl_struct = (GSL_Struct**)malloc(gss->gsl_struct_size * sizeof(GSL_Struct*)); gss->currentNS = 0; gss->namespaces[0] = gss->vars; gss->data_heap = goom_heap_new(); reset_scanner(gss); gss->compilationOK = 0; gss->nbPtr=0; gss->ptrArraySize=256; gss->ptrArray = (void**)malloc(gss->ptrArraySize * sizeof(void*)); #ifdef USE_JITC_X86 gss->jitc = NULL; #endif return gss; } /* }}} */ void gsl_bind_function(GoomSL *gss, const char *fname, GoomSL_ExternalFunction func) { /* {{{ */ HashValue *val = goom_hash_get(gss->functions, fname); if (val) { ExternalFunctionStruct *gef = (ExternalFunctionStruct*)val->ptr; gef->function = func; } else fprintf(stderr, "Unable to bind function %s\n", fname); } /* }}} */ int gsl_is_compiled(GoomSL *gss) { /* {{{ */ return gss->compilationOK; } /* }}} */ void gsl_free(GoomSL *gss) { /* {{{ */ if (gss->iflow) iflow_free(gss->iflow); if (gss->vars) goom_hash_free(gss->vars); if (gss->functions) goom_hash_free(gss->functions); free(gss->gsl_struct); free(gss->ptrArray); if (gss->data_heap) goom_heap_delete(gss->data_heap); if (gss->structIDS) goom_hash_free(gss->structIDS); free(gss); } /* }}} */ static int gsl_nb_import; static char gsl_already_imported[256][256]; char *gsl_init_buffer(const char *fname) { char *fbuffer; fbuffer = (char*)malloc(512); fbuffer[0]=0; gsl_nb_import = 0; if (fname) gsl_append_file_to_buffer(fname,&fbuffer); return fbuffer; } static char *gsl_read_file(const char *fname) { FILE *f; char *buffer; int fsize; f = fopen(fname,"rt"); if (!f) { fprintf(stderr, "ERROR: Could not load file %s\n", fname); exit(1); } fseek(f,0,SEEK_END); fsize = ftell(f); rewind(f); buffer = (char*)malloc(fsize+512); if (fread(buffer,1,fsize,f) != fsize) { fprintf(stderr, "ERROR: Could not read file %s\n", fname); exit(1); } fclose(f); buffer[fsize]=0; return buffer; } void gsl_append_file_to_buffer(const char *fname, char **buffer) { char *fbuffer; int size,fsize,i=0; char reset_msg[256]; /* look if the file have not been already imported */ for (i=0;i<gsl_nb_import;++i) { if (strcmp(gsl_already_imported[i], fname) == 0) return; } /* add fname to the already imported files. */ strlcpy(gsl_already_imported[gsl_nb_import], fname, sizeof(gsl_already_imported[0])); /* load the file */ fbuffer = gsl_read_file(fname); fsize = strlen(fbuffer); /* look for #import */ while (fbuffer[i]) { if ((fbuffer[i]=='#') && (fbuffer[i+1]=='i')) { char impName[256]; int j; while (fbuffer[i] && (fbuffer[i]!=' ')) i++; i++; j=0; while (fbuffer[i] && (fbuffer[i]!='\n')) impName[j++] = fbuffer[i++]; impName[j++] = 0; gsl_append_file_to_buffer(impName, buffer); } i++; } sprintf(reset_msg, "\n#FILE %s#\n#RST_LINE#\n", fname); strcat(*buffer, reset_msg); size=strlen(*buffer); *buffer = (char*)realloc(*buffer, size+fsize+256); strcat((*buffer)+size, fbuffer); free(fbuffer); } ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_yacc.h������������������������������������������������������������0000644�0001750�0001750�00000005225�14647725152�016055� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* A Bison parser, made by GNU Bison 1.875. */ /* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { LTYPE_INTEGER = 258, LTYPE_FLOAT = 259, LTYPE_VAR = 260, LTYPE_PTR = 261, PTR_TK = 262, INT_TK = 263, FLOAT_TK = 264, DECLARE = 265, EXTERNAL = 266, WHILE = 267, DO = 268, NOT = 269, PLUS_EQ = 270, SUB_EQ = 271, DIV_EQ = 272, MUL_EQ = 273, SUP_EQ = 274, LOW_EQ = 275, NOT_EQ = 276, STRUCT = 277, FOR = 278, IN = 279 }; #endif #define LTYPE_INTEGER 258 #define LTYPE_FLOAT 259 #define LTYPE_VAR 260 #define LTYPE_PTR 261 #define PTR_TK 262 #define INT_TK 263 #define FLOAT_TK 264 #define DECLARE 265 #define EXTERNAL 266 #define WHILE 267 #define DO 268 #define NOT 269 #define PLUS_EQ 270 #define SUB_EQ 271 #define DIV_EQ 272 #define MUL_EQ 273 #define SUP_EQ 274 #define LOW_EQ 275 #define NOT_EQ 276 #define STRUCT 277 #define FOR 278 #define IN 279 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #line 1199 "goomsl_yacc.y" typedef union YYSTYPE { int intValue; float floatValue; char charValue; char strValue[2048]; NodeType *nPtr; GoomHash *namespace; GSL_Struct *gsl_struct; GSL_StructField *gsl_struct_field; } YYSTYPE; /* Line 1240 of yacc.c. */ #line 95 "goomsl_yacc.h" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/lines.h������������������������������������������������������������������0000644�0001750�0001750�00000003105�14647725152�014663� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef _LINES_H #define _LINES_H /* * lines.h * Goom * Copyright (c) 2000-2003 iOS-software. All rights reserved. */ #include "goom_typedefs.h" #include "goom_graphic.h" #include "goom_config.h" struct _GMUNITPOINTER { float x; float y; float angle; }; /* tableau de points */ struct _GMLINE { GMUnitPointer *points; GMUnitPointer *points2; int IDdest; float param; float amplitudeF; float amplitude; int nbPoints; guint32 color; /* pour l'instant je stocke la couleur a terme, on stockera le mode couleur et l'on animera */ guint32 color2; int screenX; int screenY; float power; float powinc; PluginInfo *goomInfo; }; /* les ID possibles */ #define GML_CIRCLE 0 /* (param = radius) */ #define GML_HLINE 1 /* (param = y) */ #define GML_VLINE 2 /* (param = x) */ /* les modes couleur possible (si tu mets un autre c'est noir) */ #define GML_BLEUBLANC 0 #define GML_RED 1 #define GML_ORANGE_V 2 #define GML_ORANGE_J 3 #define GML_VERT 4 #define GML_BLEU 5 #define GML_BLACK 6 /* construit un effet de line (une ligne horitontale pour commencer) */ GMLine *goom_lines_init (PluginInfo *goomInfo, int rx, int ry, int IDsrc, float paramS, int modeCoulSrc, int IDdest, float paramD, int modeCoulDest); void goom_lines_switch_to (GMLine * gml, int IDdest, float param, float amplitude, int modeCoul); void goom_lines_set_res (GMLine * gml, int rx, int ry); void goom_lines_free (GMLine ** gml); void goom_lines_draw (PluginInfo *plugInfo, GMLine * gml, gint16 data[512], Pixel *p); #endif /* _LINES_H */ �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/mathtools.h��������������������������������������������������������������0000644�0001750�0001750�00000001367�14647725152�015573� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifndef MATHTOOLS_H #define MATHTOOLS_H #define _double2fixmagic (68719476736.0*1.5) /* 2^36 * 1.5, (52-_shiftamt=36) uses limited precisicion to floor */ #define _shiftamt 16 /* 16.16 fixed point representation */ #if BigEndian_ #define iexp_ 0 #define iman_ 1 #else #define iexp_ 1 #define iman_ 0 #endif /* BigEndian_ */ /* TODO: this optimization is very efficient: put it again when all works #ifdef HAVE_MMX #define F2I(dbl,i) {double d = dbl + _double2fixmagic; i = ((int*)&d)[iman_] >> _shiftamt;} #else*/ #define F2I(dbl,i) i=(int)dbl; /*#endif*/ #if 0 #define SINCOS(f,s,c) \ __asm__ __volatile__ ("fsincos" : "=t" (c), "=u" (s) : "0" (f)) #else #define SINCOS(f,s,c) {s=sin(f);c=cos(f);} #endif #include "mathtools.c" #endif �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goom_tools.c�������������������������������������������������������������0000644�0001750�0001750�00000001225�14647725152�015726� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goom_tools.h" #include <stdlib.h> GoomRandom *goom_random_init(int i) { GoomRandom *grandom = (GoomRandom*)malloc(sizeof(GoomRandom)); (void)i; grandom->pos = 1; goom_random_update_array(grandom, GOOM_NB_RAND); return grandom; } void goom_random_free(GoomRandom *grandom) { free(grandom); } void goom_random_update_array(GoomRandom *grandom, int numberOfValuesToChange) { while (numberOfValuesToChange > 0) { #if RAND_MAX < 0x10000 grandom->array[grandom->pos++] = ((rand()<<16)+rand()) / 127; #else grandom->array[grandom->pos++] = rand() / 127; #endif numberOfValuesToChange--; } } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/goom/goomsl_heap.c������������������������������������������������������������0000644�0001750�0001750�00000006536�14647725152�016054� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������#ifdef HAVE_CONFIG_H #include "config.h" #endif #include "goomsl_heap.h" #include <stdint.h> #include <stdlib.h> struct _GOOM_HEAP { void **arrays; int number_of_arrays; int size_of_each_array; int consumed_in_last_array; }; /* Constructors / Destructor */ GoomHeap *goom_heap_new(void) { return goom_heap_new_with_granularity(4096); } GoomHeap *goom_heap_new_with_granularity(int granularity) { GoomHeap *_this; _this = (GoomHeap*)malloc(sizeof(GoomHeap)); _this->number_of_arrays = 0; _this->size_of_each_array = granularity; _this->consumed_in_last_array = 0; _this->arrays = (void**)malloc(sizeof(void*)); return _this; } void goom_heap_delete(GoomHeap *_this) { int i; for (i=0;i<_this->number_of_arrays;++i) { free(_this->arrays[i]); } free(_this->arrays); free(_this); } static void align_it(GoomHeap *_this, int alignment) { if ((alignment > 1) && (_this->number_of_arrays>0)) { void *last_array = _this->arrays[_this->number_of_arrays - 1]; intptr_t last_address = (intptr_t)last_array + _this->consumed_in_last_array; int decal = (last_address % alignment); if (decal != 0) { _this->consumed_in_last_array += alignment - decal; } } } void *goom_heap_malloc_with_alignment_prefixed(GoomHeap *_this, int nb_bytes, int alignment, int prefix_bytes) { void *retval = NULL; /* d'abord on gere les problemes d'alignement */ _this->consumed_in_last_array += prefix_bytes; align_it(_this, alignment); /* ensuite on verifie que la quantite de memoire demandee tient dans le buffer */ if ((_this->consumed_in_last_array + nb_bytes >= _this->size_of_each_array) || (_this->number_of_arrays == 0)) { if (prefix_bytes + nb_bytes + alignment >= _this->size_of_each_array) { /* Si la zone demandee est plus grosse que la granularitee */ /* On alloue un buffer plus gros que les autres */ _this->arrays = (void**)realloc(_this->arrays, sizeof(void*) * (_this->number_of_arrays+2)); _this->number_of_arrays += 1; _this->consumed_in_last_array = prefix_bytes; _this->arrays[_this->number_of_arrays - 1] = malloc(prefix_bytes + nb_bytes + alignment); align_it(_this,alignment); retval = (void*)((char*)_this->arrays[_this->number_of_arrays - 1] + _this->consumed_in_last_array); /* puis on repart sur un nouveau buffer vide */ _this->number_of_arrays += 1; _this->consumed_in_last_array = 0; _this->arrays[_this->number_of_arrays - 1] = malloc(_this->size_of_each_array); return retval; } else { _this->number_of_arrays += 1; _this->consumed_in_last_array = prefix_bytes; _this->arrays = (void**)realloc(_this->arrays, sizeof(void*) * _this->number_of_arrays); _this->arrays[_this->number_of_arrays - 1] = malloc(_this->size_of_each_array); align_it(_this,alignment); } } retval = (void*)((char*)_this->arrays[_this->number_of_arrays - 1] + _this->consumed_in_last_array); _this->consumed_in_last_array += nb_bytes; return retval; } void *goom_heap_malloc_with_alignment(GoomHeap *_this, int nb_bytes, int alignment) { return goom_heap_malloc_with_alignment_prefixed(_this, nb_bytes, alignment, 0); } void *goom_heap_malloc(GoomHeap *_this, int nb_bytes) { return goom_heap_malloc_with_alignment(_this,nb_bytes,1); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/mosaico/����������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�014072� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/post/mosaico/mosaico.c�������������������������������������������������������������0000644�0001750�0001750�00000033750�14647725152�015700� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * simple video mosaico plugin */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include <pthread.h> #define LOG_MODULE "mosaico" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/post.h> /* FIXME: This plugin needs to handle overlays as well. */ typedef struct mosaico_parameters_s { unsigned int pip_num; unsigned int x, y, w, h; } mosaico_parameters_t; START_PARAM_DESCR(mosaico_parameters_t) PARAM_ITEM(POST_PARAM_TYPE_INT, pip_num, NULL, 1, INT_MAX, 1, "which picture slots settings are being edited") PARAM_ITEM(POST_PARAM_TYPE_INT, x, NULL, 0, INT_MAX, 50, "x coordinate of the pasted picture") PARAM_ITEM(POST_PARAM_TYPE_INT, y, NULL, 0, INT_MAX, 50, "y coordinate of the pasted picture") PARAM_ITEM(POST_PARAM_TYPE_INT, w, NULL, 0, INT_MAX, 150, "width of the pasted picture") PARAM_ITEM(POST_PARAM_TYPE_INT, h, NULL, 0, INT_MAX, 150, "height of the pasted picture") END_PARAM_DESCR(mosaico_param_descr) typedef struct post_mosaico_s post_mosaico_t; /* plugin structures */ typedef struct mosaico_pip_s mosaico_pip_t; struct mosaico_pip_s { unsigned int x, y, w, h; vo_frame_t *frame; char *input_name; }; struct post_mosaico_s { post_plugin_t post; mosaico_pip_t *pip; int64_t vpts_limit; pthread_cond_t vpts_limit_changed; int64_t skip_vpts; int skip; pthread_mutex_t mutex; unsigned int pip_count; }; /* parameter functions */ static xine_post_api_descr_t *mosaico_get_param_descr(void) { return &mosaico_param_descr; } static int mosaico_set_parameters(xine_post_t *this_gen, const void *param_gen) { post_mosaico_t *this = (post_mosaico_t *)this_gen; const mosaico_parameters_t *param = (const mosaico_parameters_t *)param_gen; if (param->pip_num > this->pip_count) return 0; this->pip[param->pip_num - 1].x = param->x; this->pip[param->pip_num - 1].y = param->y; this->pip[param->pip_num - 1].w = param->w; this->pip[param->pip_num - 1].h = param->h; return 1; } static int mosaico_get_parameters(xine_post_t *this_gen, void *param_gen) { post_mosaico_t *this = (post_mosaico_t *)this_gen; mosaico_parameters_t *param = (mosaico_parameters_t *)param_gen; if (param->pip_num > this->pip_count || param->pip_num < 1) param->pip_num = 1; param->x = this->pip[param->pip_num - 1].x; param->y = this->pip[param->pip_num - 1].y; param->w = this->pip[param->pip_num - 1].w; param->h = this->pip[param->pip_num - 1].h; return 1; } static char *mosaico_get_help(void) { return _("Mosaico does simple picture in picture effects.\n" "\n" "Parameters\n" " pip_num: the number of the picture slot the following settings apply to\n" " x: the x coordinate of the left upper corner of the picture\n" " y: the y coordinate of the left upper corner of the picture\n" " w: the width of the picture\n" " h: the height of the picture\n"); } /* replaced video port functions */ static void mosaico_close(xine_video_port_t *port_gen, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)port_gen; post_mosaico_t *this = (post_mosaico_t *)port->post; vo_frame_t *free_frame; unsigned int pip_num; (void)stream; for (pip_num = 0; pip_num < this->pip_count; pip_num++) if (this->post.xine_post.video_input[pip_num+1] == port_gen) break; pthread_mutex_lock(&this->mutex); free_frame = this->pip[pip_num].frame; this->pip[pip_num].frame = NULL; port->original_port->close(port->original_port, port->stream); pthread_mutex_unlock(&this->mutex); if (free_frame) free_frame->free(free_frame); port->stream = NULL; _x_post_dec_usage(port); } /* frame intercept check */ static int mosaico_intercept_frame(post_video_port_t *port, vo_frame_t *frame) { (void)port; /* TODO: only YV12 supported */ return (frame->format == XINE_IMGFMT_YV12); } /* replaced vo_frame functions */ static void frame_copy_content(vo_frame_t *to, vo_frame_t *from) { int size; switch (from->format) { case XINE_IMGFMT_YUY2: /* TODO: implement conversion to YV12 or implement support to paste * frames of different types together */ break; case XINE_IMGFMT_YV12: /* Y */ size = to->pitches[0] * to->height; xine_fast_memcpy(to->base[0], from->base[0], size); /* U */ size = to->pitches[1] * ((to->height + 1) / 2); xine_fast_memcpy(to->base[1], from->base[1], size); /* V */ size = to->pitches[2] * ((to->height + 1) / 2); xine_fast_memcpy(to->base[2], from->base[2], size); } } static void frame_paste(post_mosaico_t *this, vo_frame_t *background, int pip_num) { unsigned long target_width, target_height; unsigned long source_width, source_height; unsigned long background_width; unsigned long scale_x, scale_y; const int shift_x = 3, shift_y = 3; unsigned long pos_x, pos_y, pos; unsigned long target_offset, source_offset; unsigned long i, j; if (!this->pip[pip_num].frame) return; target_width = this->pip[pip_num].w; target_height = this->pip[pip_num].h; background_width = background->width; source_width = this->pip[pip_num].frame->width; source_height = this->pip[pip_num].frame->height; scale_x = (source_width << shift_x) / target_width; scale_y = (source_height << shift_y) / target_height; pos_x = this->pip[pip_num].x; pos_y = this->pip[pip_num].y; pos = pos_y * background_width + pos_x; switch (this->pip[pip_num].frame->format) { case XINE_IMGFMT_YUY2: /* TODO: implement YUY2 */ break; case XINE_IMGFMT_YV12: /* Y */ target_offset = 0; for (j = 0; j < target_height; j++, target_offset += (background_width - target_width)) for (i = 0; i < target_width; i++, target_offset++) { source_offset = ((i * scale_x) >> shift_x) + (((j * scale_y) >> shift_y) * source_width); background->base[0][pos + target_offset] = this->pip[pip_num].frame->base[0][source_offset]; } background_width = (background_width + 1) / 2; source_width = (source_width + 1) / 2; pos_x = (pos_x + 1) / 2; pos_y = (pos_y + 1) / 2; pos = pos_y * background_width + pos_x; target_width = (target_width + 1) / 2; target_height = (target_height + 1) / 2; /* U */ target_offset = 0; for (j = 0; j < target_height; j++, target_offset += (background_width - target_width)) for (i = 0; i < target_width; i++, target_offset++) { source_offset = ((i * scale_x) >> shift_x) + (((j * scale_y) >> shift_y) * source_width); background->base[1][pos + target_offset] = this->pip[pip_num].frame->base[1][source_offset]; } /* V */ target_offset = 0; for (j = 0; j < target_height; j++, target_offset += (background_width - target_width)) for (i = 0; i < target_width; i++, target_offset++) { source_offset = ((i * scale_x) >> shift_x) + (((j * scale_y) >> shift_y) * source_width); background->base[2][pos + target_offset] = this->pip[pip_num].frame->base[2][source_offset]; } break; } } static int mosaico_draw_background(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_mosaico_t *this = (post_mosaico_t *)port->post; vo_frame_t *background; unsigned int pip_num; int skip; pthread_mutex_lock(&this->mutex); if (frame->bad_frame) { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, stream); _x_post_frame_copy_up(frame, frame->next); this->vpts_limit = frame->vpts + frame->duration; if (skip) { this->skip = skip; this->skip_vpts = frame->vpts; } else this->skip = 0; pthread_mutex_unlock(&this->mutex); pthread_cond_broadcast(&this->vpts_limit_changed); return skip; } background = port->original_port->get_frame(port->original_port, frame->width, frame->height, frame->ratio, frame->format, frame->flags | VO_BOTH_FIELDS); _x_post_frame_copy_down(frame, background); frame_copy_content(background, frame); for (pip_num = 0; pip_num < this->pip_count; pip_num++) frame_paste(this, background, pip_num); skip = background->draw(background, stream); _x_post_frame_copy_up(frame, background); this->vpts_limit = background->vpts + background->duration; background->free(background); if (skip) { this->skip = skip; this->skip_vpts = frame->vpts; } else this->skip = 0; pthread_mutex_unlock(&this->mutex); pthread_cond_broadcast(&this->vpts_limit_changed); return skip; } static int mosaico_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_mosaico_t *this = (post_mosaico_t *)port->post; vo_frame_t *free_frame; unsigned int pip_num; int skip; for (pip_num = 0; pip_num < this->pip_count; pip_num++) if (this->post.xine_post.video_input[pip_num+1] == frame->port) break; _x_assert(pip_num < this->pip_count); frame->lock(frame); pthread_mutex_lock(&this->mutex); /* the original output will never see this frame again */ _x_post_frame_u_turn(frame, stream); while (frame->vpts > this->vpts_limit || !this->vpts_limit) /* we are too early */ pthread_cond_wait(&this->vpts_limit_changed, &this->mutex); free_frame = this->pip[pip_num].frame; if (port->stream) this->pip[pip_num].frame = frame; if (this->skip && frame->vpts <= this->skip_vpts) skip = this->skip; else skip = 0; pthread_mutex_unlock(&this->mutex); if (free_frame) free_frame->free(free_frame); if (!port->stream) /* do not keep this frame when no stream is connected to us, * otherwise, this frame might never get freed */ frame->free(frame); return skip; } /* plugin instance functions */ static void mosaico_dispose(post_plugin_t *this_gen) { post_mosaico_t *this = (post_mosaico_t *)this_gen; if (_x_post_dispose(this_gen)) { unsigned int i; for (i = 0; i < this->pip_count; i++) free(this->pip[i].input_name); free(this->pip); pthread_cond_destroy(&this->vpts_limit_changed); pthread_mutex_destroy(&this->mutex); free(this); } } static post_plugin_t *mosaico_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_mosaico_t *this = calloc(1, sizeof(post_mosaico_t)); mosaico_pip_t *pip; post_in_t *input; post_out_t *output; post_video_port_t *port; int i; static const xine_post_api_t post_api = { .set_parameters = mosaico_set_parameters, .get_parameters = mosaico_get_parameters, .get_param_descr = mosaico_get_param_descr, .get_help = mosaico_get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; lprintf("mosaico open\n"); (void)class_gen; (void)audio_target; if (inputs < 2 || !this || !video_target || !video_target[0]) { free(this); return NULL; } pip = calloc((inputs - 1), sizeof(mosaico_pip_t)); if (!pip) { free(this); return NULL; } _x_post_init(&this->post, 0, inputs); this->pip = pip; this->pip_count = inputs - 1; pthread_cond_init(&this->vpts_limit_changed, NULL); pthread_mutex_init(&this->mutex, NULL); /* the port for the background video */ port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->intercept_frame = mosaico_intercept_frame; port->new_frame->draw = mosaico_draw_background; port->port_lock = &this->mutex; port->frame_lock = &this->mutex; input->xine_in.name = "video in 0"; this->post.xine_post.video_input[0] = &port->new_port; for (i = 0; i < inputs - 1; i++) { this->pip[i].x = 50; this->pip[i].y = 50; this->pip[i].w = 150; this->pip[i].h = 150; this->pip[i].input_name = _x_asprintf("video in %d", i+1); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, NULL); port->new_port.close = mosaico_close; port->intercept_frame = mosaico_intercept_frame; port->new_frame->draw = mosaico_draw; port->port_lock = &this->mutex; port->frame_lock = &this->mutex; input->xine_in.name = this->pip[i].input_name; this->post.xine_post.video_input[i+1] = &port->new_port; } xine_list_push_back(this->post.input, (void *)¶ms_input); this->post.dispose = mosaico_dispose; return &this->post; } static void *mosaico_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_mosaico_class = { .open_plugin = mosaico_open_plugin, .identifier = "mosaico", .description = N_("Mosaico is a picture in picture (pip) post plugin"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_mosaico_class; } /* plugin catalog information */ static const post_info_t mosaico_special_info = { .type = XINE_POST_TYPE_VIDEO_COMPOSE, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST, 10, "mosaico", XINE_VERSION_CODE, &mosaico_special_info, &mosaico_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ������������������������xine-lib-1.2/src/post/mosaico/switch.c��������������������������������������������������������������0000644�0001750�0001750�00000016026�14647725152�015544� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * simple switch video post plugin */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <pthread.h> #define LOG_MODULE "switch" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/post.h> /* FIXME: This plugin needs to handle overlays as well. */ typedef struct switch_parameter_s { unsigned int select; } switch_parameter_t; START_PARAM_DESCR(switch_parameter_t) PARAM_ITEM(POST_PARAM_TYPE_INT, select, NULL, 1, INT_MAX, 1, "the input source which will be passed through to the output") END_PARAM_DESCR(switch_param_descr) typedef struct post_switch_s post_switch_t; /* plugin structure */ struct post_switch_s { post_plugin_t post; int64_t vpts_limit; pthread_cond_t display_condition_changed; int64_t skip_vpts; int skip; pthread_mutex_t mutex; unsigned int source_count; unsigned int selected_source; }; /* parameter functions */ static xine_post_api_descr_t *switch_get_param_descr(void) { return &switch_param_descr; } static int switch_set_parameters(xine_post_t *this_gen, const void *param_gen) { post_switch_t *this = (post_switch_t *)this_gen; const switch_parameter_t *param = (const switch_parameter_t *)param_gen; if (param->select > this->source_count) return 0; pthread_mutex_lock(&this->mutex); this->selected_source = param->select; pthread_mutex_unlock(&this->mutex); pthread_cond_broadcast(&this->display_condition_changed); return 1; } static int switch_get_parameters(xine_post_t *this_gen, void *param_gen) { post_switch_t *this = (post_switch_t *)this_gen; switch_parameter_t *param = (switch_parameter_t *)param_gen; param->select = this->selected_source; return 1; } static char *switch_get_help(void) { return _("Switch can be used for fast switching between multiple inputs.\n" "\n" "Parameters\n" " select: the number of the input which will be passed to the output\n"); } /* replaced vo_frame functions */ static int switch_draw(vo_frame_t *frame, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)frame->port; post_switch_t *this = (post_switch_t *)port->post; unsigned int source_num; int skip; for (source_num = 1; source_num <= this->source_count; source_num++) if (this->post.xine_post.video_input[source_num-1] == frame->port) break; _x_assert(source_num <= this->source_count); pthread_mutex_lock(&this->mutex); /* the original output will probably never see this frame again */ _x_post_frame_u_turn(frame, stream); while (this->selected_source != source_num && (frame->vpts > this->vpts_limit || !this->vpts_limit)) /* we are too early */ pthread_cond_wait(&this->display_condition_changed, &this->mutex); if (this->selected_source == source_num) { _x_post_frame_copy_down(frame, frame->next); skip = frame->next->draw(frame->next, XINE_ANON_STREAM); _x_post_frame_copy_up(frame, frame->next); this->vpts_limit = frame->vpts + frame->duration; if (skip) { this->skip = skip; this->skip_vpts = frame->vpts; } else this->skip = 0; pthread_mutex_unlock(&this->mutex); pthread_cond_broadcast(&this->display_condition_changed); } else { if (this->skip && frame->vpts <= this->skip_vpts) skip = this->skip; else skip = 0; pthread_mutex_unlock(&this->mutex); } return skip; } /* plugin instance functions */ static void switch_dispose(post_plugin_t *this_gen) { post_switch_t *this = (post_switch_t *)this_gen; if (_x_post_dispose(this_gen)) { pthread_cond_destroy(&this->display_condition_changed); pthread_mutex_destroy(&this->mutex); free(this); } } static post_plugin_t *switch_open_plugin(post_class_t *class_gen, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { post_switch_t *this = calloc(1, sizeof(post_switch_t)); post_in_t *input; post_out_t *output; post_video_port_t *port; int i; static const xine_post_api_t post_api = { .set_parameters = switch_set_parameters, .get_parameters = switch_get_parameters, .get_param_descr = switch_get_param_descr, .get_help = switch_get_help, }; static const xine_post_in_t params_input = { .name = "parameters", .type = XINE_POST_DATA_PARAMETERS, .data = (void *)&post_api, }; lprintf("switch open\n"); if (inputs < 2 || !this || !video_target || !video_target[0]) { free(this); return NULL; } (void)class_gen; (void)audio_target; _x_post_init(&this->post, 0, inputs); this->source_count = inputs; this->selected_source = 1; pthread_cond_init(&this->display_condition_changed, NULL); pthread_mutex_init(&this->mutex, NULL); port = _x_post_intercept_video_port(&this->post, video_target[0], &input, &output); port->new_frame->draw = switch_draw; port->port_lock = &this->mutex; port->frame_lock = &this->mutex; this->post.xine_post.video_input[0] = &port->new_port; for (i = 1; i < inputs; i++) { port = _x_post_intercept_video_port(&this->post, video_target[0], &input, NULL); port->new_frame->draw = switch_draw; port->port_lock = &this->mutex; port->frame_lock = &this->mutex; this->post.xine_post.video_input[i] = &port->new_port; } xine_list_push_back(this->post.input, (void *)¶ms_input); this->post.dispose = switch_dispose; return &this->post; } static void *switch_init_plugin(xine_t *xine, const void *data) { static const post_class_t post_switch_class = { .open_plugin = switch_open_plugin, .identifier = "switch", .description = N_("Switch is a post plugin able to switch at any time between different streams"), .dispose = NULL, }; (void)xine; (void)data; return (void *)&post_switch_class; } /* plugin catalog information */ static const post_info_t switch_special_info = { .type = XINE_POST_TYPE_VIDEO_COMPOSE, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_POST, 10, "switch", XINE_VERSION_CODE, &switch_special_info, &switch_init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/�����������������������������������������������������������������������0000755�0001750�0001750�00000000000�14647725152�013661� 5����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/id3.c������������������������������������������������������������������0000644�0001750�0001750�00000067067�14647725152�014524� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * ID3 tag parser * * Supported versions: v1, v1.1, v2.2, v2.3, v2.4 * TODO: * v2.2: unsynchronize * v2.3: unsynchronize * unzip support * v2.4: unsynchronize * unzip support * * ID3v2 specs: http://www.id3.org/ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #define LOG_MODULE "id3" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/xineutils.h> #include "bswap.h" #include "../demuxers/id3.h" #include "xine_private.h" #define ID3_GENRE_COUNT (sizeof (id3_genre) / sizeof (id3_genre[0])) static const char id3_genre[][24] = {"Blues", "Classic Rock", "Country", "Dance", "Disco", "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", "New Age", "Oldies", "Other", "Pop", "R&B", "Rap", "Reggae", "Rock", "Techno", "Industrial", "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", "Fusion", "Trance", "Classical", "Instrumental", "Acid", "House", "Game", "Sound Clip", "Gospel", "Noise", "AlternRock", "Bass", "Soul", "Punk", "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta", "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes", "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", "Folk", "Folk-Rock", "National Folk", "Swing", "Fast Fusion", "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", "Humour", "Speech", "Chanson", "Opera", "Chamber Music", "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", "Satire", "Slow Jam", "Club", "Tango", "Samba", "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", "Duet", "Punk Rock", "Drum Solo", "A capella", "Euro-House", "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", "Anime", "JPop", "Synthpop" }; #define ID3_ENCODING_COUNT 4 static const char id3_encoding[][12] = { "ISO-8859-1", /* 0x00 */ "UTF-16", /* 0x01 */ "UTF-16BE", /* 0x02 */ "UTF-8"}; /* 0x03 */ int id3v1_parse_tag (input_plugin_t *input, xine_stream_t *stream) { id3v1_tag_t tag; char track[4]; /* id3v1 */ if (input->read (input, (char *)&tag, 128) != 128) { return 0; } if ( (tag.tag[0]=='T') && (tag.tag[1]=='A') && (tag.tag[2]=='G') ) { lprintf("id3v1 tag found\n"); _x_meta_info_n_set(stream, XINE_META_INFO_TITLE, tag.title, 30); _x_meta_info_n_set(stream, XINE_META_INFO_ARTIST, tag.artist, 30); _x_meta_info_n_set(stream, XINE_META_INFO_ALBUM, tag.album, 30); _x_meta_info_n_set(stream, XINE_META_INFO_YEAR, tag.year, 4); _x_meta_info_n_set(stream, XINE_META_INFO_COMMENT, tag.comment, 30); /* check for a track number: ID3v1.1, which is a clever hack on ID3v1 */ if (tag.comment[28] == 0 && tag.comment[29] != 0) { snprintf(track, 4, "%d", (unsigned char)tag.comment[29]); _x_meta_info_set(stream, XINE_META_INFO_TRACK_NUMBER, track); } if (tag.genre < ID3_GENRE_COUNT) { _x_meta_info_set(stream, XINE_META_INFO_GENRE, id3_genre[tag.genre]); } } return 1; } /* id3v2 "genre" parsing code. what a ugly format ! */ static int id3v2_parse_genre(char* dest, const char *src, size_t len) { int state = 0; char *buf = dest; unsigned int index = 0; while (*src) { lprintf("state=%d\n", state); if ((buf - dest) >= (ptrdiff_t)len) return 0; switch (state) { case 0: /* initial state */ if (*src == '(') { state = 1; index = 0; src++; } else { *buf = *src; buf++; src++; } break; case 1: /* ( */ if (*src == '(') { *buf = *src; buf++; src++; state = 0; } else if (*src == 'R') { src++; state = 2; } else if (*src == 'C') { src++; state = 3; } else if ((*src >= '0') && (*src <= '9')) { index = 10 * index + (*src - '0'); src++; } else if (*src == ')') { if (index < ID3_GENRE_COUNT) { strncpy(buf, id3_genre[index], len - (buf - dest)); buf += strlen(id3_genre[index]); } else { lprintf("invalid index: %d\n", index); } src++; state = 0; } else { lprintf("parsing error\n"); return 0; } break; case 2: /* (R */ if (*src == 'X') { src++; state = 4; } else { lprintf("parsing error\n"); return 0; } break; case 3: /* (C */ if (*src == 'R') { strncpy(dest, id3_genre[index], len - (buf - dest)); buf += strlen(id3_genre[index]); src++; state = 5; } else { lprintf("parsing error\n"); return 0; } break; case 4: /* (RX */ if (*src == ')') { strncpy(dest, "Remix", len - (buf - dest)); buf += strlen("Remix"); src++; state = 0; } else { lprintf("parsing error\n"); return 0; } break; case 5: /* (CR */ if (*src == ')') { strncpy(dest, "Cover", len - (buf - dest)); buf += strlen("Cover"); src++; state = 0; } else { lprintf("parsing error\n"); return 0; } break; } } if ((buf - dest) >= (ptrdiff_t)len) { return 0; } else { *buf = '\0'; } return 1; } static int id3v2_parse_header(input_plugin_t *input, uint32_t id3_signature, id3v2_header_t *tag_header) { uint8_t buf[6]; tag_header->id = be2me_32(id3_signature); if (input->read (input, buf, 6) != 6) { return 0; } tag_header->revision = buf[0]; tag_header->flags = buf[1]; tag_header->size = _X_BE_32_synchsafe(&buf[2]); lprintf("tag: ID3 v2.%d.%d\n", tag_header->id & 0xFF, tag_header->revision); lprintf("flags: %d\n", tag_header->flags); lprintf("size: %zu\n", tag_header->size); return 1; } /* id3 v2.2 */ static int id3v22_parse_frame_header(input_plugin_t *input, id3v22_frame_header_t *frame_header) { uint8_t buf[ID3V22_FRAME_HEADER_SIZE]; int len; len = input->read (input, buf, ID3V22_FRAME_HEADER_SIZE); if (len != ID3V22_FRAME_HEADER_SIZE) { return 0; } frame_header->id = (buf[0] << 16) + (buf[1] << 8) + buf[2]; frame_header->size = _X_BE_24(&buf[3]); lprintf("frame: %c%c%c: size: %zu\n", buf[0], buf[1], buf[2], frame_header->size); return 1; } static int id3v22_interp_frame(input_plugin_t *input, xine_stream_t *stream, id3v22_frame_header_t *frame_header) { const size_t bufsize = frame_header->size + 2; char *buf; int enc; if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */ return 0; buf = malloc(bufsize); if (!buf) return 0; if (input->read (input, buf, frame_header->size) != (int)frame_header->size) { lprintf("read error\n"); free(buf); return 0; } buf[frame_header->size] = 0; buf[frame_header->size + 1] = 0; enc = buf[0]; if( enc >= ID3_ENCODING_COUNT ) enc = 0; switch (frame_header->id) { case ( BE_FOURCC(0, 'T', 'C', 'O') ): { char tmp[1024]; if (id3v2_parse_genre(tmp, buf + 1, sizeof(tmp))) { _x_meta_info_set(stream, XINE_META_INFO_GENRE, tmp); } } break; case ( BE_FOURCC(0, 'T', 'T', '2') ): _x_meta_info_set_generic(stream, XINE_META_INFO_TITLE, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC(0, 'T', 'P', '1') ): _x_meta_info_set_generic(stream, XINE_META_INFO_ARTIST, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC(0, 'T', 'A', 'L') ): _x_meta_info_set_generic(stream, XINE_META_INFO_ALBUM, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC(0, 'T', 'Y', 'E') ): _x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC(0, 'C', 'O', 'M') ): if (frame_header->size > 4) _x_meta_info_set_generic(stream, XINE_META_INFO_COMMENT, buf + 1 + 3, id3_encoding[enc]); break; case ( BE_FOURCC(0, 'T', 'R', 'K') ): _x_meta_info_set(stream, XINE_META_INFO_TRACK_NUMBER, buf + 1); break; default: lprintf("unhandled frame\n"); } free(buf); return 1; } static int id3v22_parse_tag(input_plugin_t *input, xine_stream_t *stream, uint32_t id3_signature) { id3v2_header_t tag_header; id3v22_frame_header_t tag_frame_header; unsigned int pos = 0; if (!id3v2_parse_header(input, id3_signature, &tag_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_header problem\n"); return 0; } if (tag_header.flags & ID3V22_ZERO_FLAG) { /* invalid flags */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid header flags (%02x)\n", tag_header.flags); input->seek (input, tag_header.size, SEEK_CUR); return 0; } if (tag_header.flags & ID3V22_COMPRESS_FLAG) { /* compressed tag: not supported */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": compressed tags are not supported\n"); input->seek (input, tag_header.size, SEEK_CUR); return 0; } if (tag_header.flags & ID3V22_UNSYNCH_FLAG) { /* unsynchronized tag: not supported */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": unsynchronized tags are not supported\n"); input->seek (input, tag_header.size, SEEK_CUR); return 0; } /* frame parsing */ while ((pos + ID3V22_FRAME_HEADER_SIZE) <= tag_header.size) { if (!id3v22_parse_frame_header(input, &tag_frame_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_frame_header problem\n"); return 0; } pos += ID3V22_FRAME_HEADER_SIZE; if (!tag_frame_header.id) { /* end of frames, the rest is padding */ input->seek (input, tag_header.size - pos, SEEK_CUR); return 1; } if ((pos + tag_frame_header.size) > tag_header.size) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid frame header\n"); input->seek (input, tag_header.size - pos, SEEK_CUR); return 1; } if (!id3v22_interp_frame(input, stream, &tag_frame_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid frame content\n"); } pos += tag_frame_header.size; } return 1; } /* id3 v2.3 */ static int id3v23_parse_frame_header(input_plugin_t *input, id3v23_frame_header_t *frame_header) { uint8_t buf[ID3V23_FRAME_HEADER_SIZE]; int len; len = input->read (input, buf, ID3V23_FRAME_HEADER_SIZE); if (len != ID3V23_FRAME_HEADER_SIZE) { return 0; } frame_header->id = _X_BE_32(buf); frame_header->size = _X_BE_32(&buf[4]); frame_header->flags = _X_BE_16(buf + 8); lprintf("frame: %c%c%c%c, size: %zu, flags: %X\n", buf[0], buf[1], buf[2], buf[3], frame_header->size, frame_header->flags); return 1; } static int id3v23_parse_frame_ext_header(input_plugin_t *input, id3v23_frame_ext_header_t *frame_ext_header) { uint8_t buf[10]; if (input->read (input, buf, 4) != 4) { return 0; } frame_ext_header->size = _X_BE_32(&buf[0]); if (frame_ext_header->size == 6) { if (input->read (input, buf, 6) != 6) { return 0; } frame_ext_header->flags = _X_BE_16(buf); frame_ext_header->padding_size = _X_BE_32(buf + 2); frame_ext_header->crc = 0; } else if (frame_ext_header->size == 10) { if (input->read (input, buf, 10) != 10) { return 0; } frame_ext_header->flags = _X_BE_16(buf); frame_ext_header->padding_size = _X_BE_32(buf + 2); frame_ext_header->crc = _X_BE_32(buf + 6); } else { lprintf("invalid ext header size: %zu\n", frame_ext_header->size); return 0; } lprintf("ext header: size: %zu, flags: %X, padding_size: %d, crc: %d\n", frame_ext_header->size, frame_ext_header->flags, frame_ext_header->padding_size, frame_ext_header->crc); return 1; } static int id3v23_interp_frame(input_plugin_t *input, xine_stream_t *stream, id3v23_frame_header_t *frame_header) { const size_t bufsize = frame_header->size + 2; char *buf; int enc; if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */ return 0; buf = malloc(bufsize); if (!buf) return 0; if (input->read (input, buf, frame_header->size) != (int)frame_header->size) { lprintf("read error\n"); free(buf); return 0; } buf[frame_header->size] = 0; buf[frame_header->size + 1] = 0; enc = buf[0]; if( enc >= ID3_ENCODING_COUNT ) enc = 0; switch (frame_header->id) { case ( BE_FOURCC('T', 'C', 'O', 'N') ): { char tmp[1024]; if (id3v2_parse_genre(tmp, buf + 1, sizeof(tmp))) { _x_meta_info_set(stream, XINE_META_INFO_GENRE, tmp); } } break; case ( BE_FOURCC('T', 'I', 'T', '2') ): _x_meta_info_set_generic(stream, XINE_META_INFO_TITLE, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'P', 'E', '1') ): _x_meta_info_set_generic(stream, XINE_META_INFO_ARTIST, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'A', 'L', 'B') ): _x_meta_info_set_generic(stream, XINE_META_INFO_ALBUM, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'Y', 'E', 'R') ): _x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('C', 'O', 'M', 'M') ): if (frame_header->size > 4) _x_meta_info_set_generic(stream, XINE_META_INFO_COMMENT, buf + 1 + 3, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'R', 'C', 'K') ): _x_meta_info_set(stream, XINE_META_INFO_TRACK_NUMBER, buf + 1); break; case BE_FOURCC('T', 'P', 'O', 'S'): _x_meta_info_set(stream, XINE_META_INFO_DISCNUMBER, buf + 1); break; default: lprintf("unhandled frame\n"); } free(buf); return 1; } static int id3v23_parse_tag(input_plugin_t *input, xine_stream_t *stream, uint32_t id3_signature) { id3v2_header_t tag_header; id3v23_frame_header_t tag_frame_header; id3v23_frame_ext_header_t tag_frame_ext_header; unsigned int pos = 0; if (!id3v2_parse_header(input, id3_signature, &tag_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_header problem\n"); return 0; } if (tag_header.flags & ID3V23_ZERO_FLAG) { /* invalid flags */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid header flags (%02x)\n", tag_header.flags); input->seek (input, tag_header.size, SEEK_CUR); return 0; } if (tag_header.flags & ID3V23_UNSYNCH_FLAG) { /* unsynchronized tag: not supported */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": unsynchronized tags are not supported\n"); input->seek (input, tag_header.size, SEEK_CUR); return 0; } if (tag_header.flags & ID3V23_EXT_HEADER_FLAG) { /* extended header */ if (!id3v23_parse_frame_ext_header(input, &tag_frame_ext_header)) { return 0; } pos += tag_frame_ext_header.size; } /* frame parsing */ while ((pos + ID3V23_FRAME_HEADER_SIZE) <= tag_header.size) { if (!id3v23_parse_frame_header(input, &tag_frame_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_frame_header problem\n"); return 0; } pos += ID3V23_FRAME_HEADER_SIZE; if (!tag_frame_header.id) { /* end of frames, the rest is padding */ lprintf("skipping padding %zu bytes\n", tag_header.size - pos); input->seek (input, tag_header.size - pos, SEEK_CUR); return 1; } if ((pos + tag_frame_header.size) > tag_header.size) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid frame header\n"); input->seek (input, tag_header.size - pos, SEEK_CUR); return 1; } if (!id3v23_interp_frame(input, stream, &tag_frame_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid frame content\n"); } pos += tag_frame_header.size; } return 1; } /* id3 v2.4 */ /* id3v2 "genre" parsing code. what a ugly format ! */ static int id3v24_parse_genre(char* dest, const char *src, size_t len) { unsigned int index = 0; dest[0] = '\0'; if (sscanf(src, "%u", &index) == 1) { if (index < ID3_GENRE_COUNT) { strlcpy(dest, id3_genre[index], len); } else { lprintf("invalid index: %u\n", index); } } return 1; } static int id3v24_parse_frame_header(input_plugin_t *input, id3v24_frame_header_t *frame_header) { uint8_t buf[ID3V24_FRAME_HEADER_SIZE]; int len; len = input->read (input, buf, ID3V24_FRAME_HEADER_SIZE); if (len != ID3V24_FRAME_HEADER_SIZE) { return 0; } frame_header->id = _X_BE_32(buf); frame_header->size = _X_BE_32(&buf[4]); frame_header->flags = _X_BE_16(&buf[8]); lprintf("frame: %c%c%c%c, size: %zu, flags: %X\n", buf[0], buf[1], buf[2], buf[3], frame_header->size, frame_header->flags); return 1; } static int id3v24_parse_ext_header(input_plugin_t *input, id3v24_frame_ext_header_t *frame_ext_header) { uint8_t buf[5]; uint8_t flags_size, data_length; if (input->read (input, buf, 4) != 4) { return 0; } frame_ext_header->size = _X_BE_32(&buf[0]); if (input->read (input, buf, 2) != 2) { return 0; } flags_size = buf[0]; if (flags_size != 1) { lprintf( "id3: invalid extended header, flag size must be 1\n"); return 0; } frame_ext_header->flags = buf[1]; if (frame_ext_header->flags & ID3V24_EXT_ZERO_FLAG) { lprintf( "id3: invalid extended header, unknown flags\n"); return 0; } /* Update flag */ if (frame_ext_header->flags & ID3V24_EXT_UPDATE_FLAG) { if (input->read (input, buf, 1) != 1) { return 0; } data_length = buf[0]; if (data_length != 0) { lprintf( "id3: invalid extended header, unexpected update flag data length\n"); return 0; } } /* Crc flag */ if (frame_ext_header->flags & ID3V24_EXT_CRC_FLAG) { if (input->read (input, buf, 1) != 1) { return 0; } data_length = buf[0]; if (data_length != 5) { lprintf( "id3: invalid extended header, unexpected crc flag data length\n"); return 0; } if (input->read (input, buf, data_length) == data_length) { /* ignore crc */ frame_ext_header->crc = BE_35_synchsafe(buf); } } /* Restriction flag */ if (frame_ext_header->flags & ID3V24_EXT_RESTRICTIONS_FLAG) { if (input->read (input, buf, 1) != 1) { return 0; } data_length = buf[0]; if (data_length != 1) { lprintf( "id3: invalid extended header, unexpected restriction flag data length\n"); return 0; } if (input->read (input, buf, data_length) != data_length) { return 0; } /* ignore restrictions */ frame_ext_header->restrictions = buf[0]; } lprintf("ext header: size: %zu, flags: %X, crc: %d, restrictions: %8X\n", frame_ext_header->size, frame_ext_header->flags, (frame_ext_header->flags & ID3V24_EXT_CRC_FLAG) ? frame_ext_header->crc : 0, (frame_ext_header->flags & ID3V24_EXT_RESTRICTIONS_FLAG) ? frame_ext_header->restrictions : 0); return 1; } static int id3v24_interp_frame(input_plugin_t *input, xine_stream_t *stream, id3v24_frame_header_t *frame_header) { const size_t bufsize = frame_header->size + 2; char *buf; int enc; if ( bufsize < 3 ) /* frames has to be _at least_ 1 byte */ return 0; buf = malloc(bufsize); if (!buf) return 0; if (input->read (input, buf, frame_header->size) != (int)frame_header->size) { lprintf("read error\n"); free(buf); return 0; } buf[frame_header->size] = 0; buf[frame_header->size + 1] = 0; enc = buf[0]; if( enc >= ID3_ENCODING_COUNT ) enc = 0; lprintf("data: %s\n", buf+1); switch (frame_header->id) { case ( BE_FOURCC('T', 'C', 'O', 'N') ): { char tmp[1024]; if (id3v24_parse_genre(tmp, buf + 1, sizeof(tmp))) { _x_meta_info_set(stream, XINE_META_INFO_GENRE, tmp); } } break; case ( BE_FOURCC('T', 'I', 'T', '2') ): _x_meta_info_set_generic(stream, XINE_META_INFO_TITLE, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'P', 'E', '1') ): _x_meta_info_set_generic(stream, XINE_META_INFO_ARTIST, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'A', 'L', 'B') ): _x_meta_info_set_generic(stream, XINE_META_INFO_ALBUM, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'Y', 'E', 'R') ): case ( BE_FOURCC('T', 'D', 'R', 'C') ): _x_meta_info_set_generic(stream, XINE_META_INFO_YEAR, buf + 1, id3_encoding[enc]); break; case ( BE_FOURCC('C', 'O', 'M', 'M') ): if (frame_header->size > 4) _x_meta_info_set_generic(stream, XINE_META_INFO_COMMENT, buf + 1 + 3, id3_encoding[enc]); break; case ( BE_FOURCC('T', 'R', 'C', 'K') ): _x_meta_info_set(stream, XINE_META_INFO_TRACK_NUMBER, buf + 1); break; case BE_FOURCC('T', 'P', 'O', 'S'): _x_meta_info_set(stream, XINE_META_INFO_DISCNUMBER, buf + 1); break; default: lprintf("unhandled frame\n"); } free(buf); return 1; } static int id3v24_parse_tag(input_plugin_t *input, xine_stream_t *stream, uint32_t id3_signature) { id3v2_header_t tag_header; id3v24_frame_header_t tag_frame_header; id3v24_frame_ext_header_t tag_frame_ext_header; unsigned int pos = 0; if (!id3v2_parse_header(input, id3_signature, &tag_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_header problem\n"); return 0; } if (tag_header.flags & ID3V24_ZERO_FLAG) { /* invalid flags */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid header flags (%02x)\n", tag_header.flags); input->seek (input, tag_header.size, SEEK_CUR); return 0; } if (tag_header.flags & ID3V24_UNSYNCH_FLAG) { /* it just means that all frames must be flagged UNSYNCH */ } if (tag_header.flags & ID3V24_EXPERIMENTAL_FLAG) { /* it just means that the tag is in a experimental stage */ } if (tag_header.flags & ID3V24_EXT_HEADER_FLAG) { /* extended header */ if (!id3v24_parse_ext_header(input, &tag_frame_ext_header)) { return 0; } pos += tag_frame_ext_header.size; } /* frame parsing */ while ((pos + ID3V24_FRAME_HEADER_SIZE) <= tag_header.size) { if (!id3v24_parse_frame_header(input, &tag_frame_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": id3v2_parse_frame_header problem\n"); return 0; } pos += ID3V24_FRAME_HEADER_SIZE; if (!tag_frame_header.id) { /* end of frames, the rest is padding */ input->seek (input, tag_header.size - pos, SEEK_CUR); return 1; } if ((pos + tag_frame_header.size) > tag_header.size) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid frame header\n"); input->seek (input, tag_header.size - pos, SEEK_CUR); return 1; } if (!id3v24_interp_frame(input, stream, &tag_frame_header)) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": invalid frame content\n"); } pos += tag_frame_header.size; } if (tag_header.flags & ID3V24_FOOTER_FLAG) { /* ignore footer */ input->seek (input, ID3V24_FOOTER_SIZE, SEEK_CUR); } return 1; } int id3v2_parse_tag(input_plugin_t *input, xine_stream_t *stream, uint32_t id3_signature) { _x_assert((id3_signature & ID3V2X_MASK) == ID3V2X_TAG); switch(id3_signature) { case ID3V22_TAG: xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.2 tag\n"); return id3v22_parse_tag(input, stream, id3_signature); case ID3V23_TAG: xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.3 tag\n"); return id3v23_parse_tag(input, stream, id3_signature); case ID3V24_TAG: xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": ID3V2.4 tag\n"); return id3v24_parse_tag(input, stream, id3_signature); default: xprintf(stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": Unknown ID3v2 signature: 0x%08x.\n", be2me_32(id3_signature)); } return 0; } /* NOTE: leading id3v2 tags may be large (album artwork image and such). * make sure to read it just once, especially with non seekable input. * also, redirect file type detection (demux probing) behind the tag, * and dont rely on MAX_PREVIEW_SIZE being big enough. */ int xine_parse_id3v2_tag (xine_stream_t *stream, input_plugin_t *input) { xine_stream_private_t *s = (xine_stream_private_t *)stream; uint32_t signature; int r; if (!s) return 0; if (!input) { input = s->s.input_plugin; if (!input) return 0; } if (s->id3v2_tag_size >= 0) { input->seek (input, s->id3v2_tag_size, SEEK_SET); return s->id3v2_tag_size; } if (_x_demux_read_header (input, &signature, 4) != 4) return 0; if (!id3v2_istag (signature)) { s->id3v2_tag_size = 0; return 0; } if (input->seek (input, 4, SEEK_SET) != 4) return 0; id3v2_parse_tag (input, &s->s, signature); s->id3v2_tag_size = input->get_current_pos (input); r = INPUT_OPTIONAL_UNSUPPORTED; if (input->get_capabilities (input) & (INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW)) r = input->get_optional_data (input, NULL, INPUT_OPTIONAL_DATA_NEW_PREVIEW); xprintf (stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": initial ID3v2 tag (%p, %d bytes)%s.\n", (void *)stream, s->id3v2_tag_size, (r == INPUT_OPTIONAL_SUCCESS) ? ", new preview generated" : ""); return s->id3v2_tag_size; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/video_out.c������������������������������������������������������������0000644�0001750�0001750�00000336311�14647725152�016031� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * frame allocation / queuing / scheduling / output functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <signal.h> #include <sys/time.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <inttypes.h> #include <errno.h> #include <sys/time.h> #define XINE_ENABLE_EXPERIMENTAL_FEATURES #define LOG_MODULE "video_out" #define LOG_VERBOSE /* #define LOG #define LOG_FLUSH */ #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/metronom.h> #include <xine/xineutils.h> #include <yuv2rgb.h> #include "xine_private.h" #define NUM_FRAME_BUFFERS 15 #define DEFAULT_FRAME_DURATION 3000 /* 30 frames per second */ /* wait this delay if the first frame is still referenced */ #define FIRST_FRAME_POLL_DELAY 3000 #define FIRST_FRAME_MAX_POLL 10 /* poll n times at most */ /* #define ADD_KEYFRAME_INDEX */ /* experimental optimization: try to allocate frames from free queue * in the same format as requested (avoid unnecessary free/alloc in * vo driver). up to 25% less cpu load using deinterlace with film mode. */ #define EXPERIMENTAL_FRAME_QUEUE_OPTIMIZATION 1 typedef struct vos_grab_video_frame_s vos_grab_video_frame_t; struct vos_grab_video_frame_s { xine_grab_video_frame_t grab_frame; vos_grab_video_frame_t *next; int finished; xine_video_port_t *video_port; vo_frame_t *vo_frame; yuv2rgb_factory_t *yuv2rgb_factory; yuv2rgb_t *yuv2rgb; int vo_width, vo_height; int grab_width, grab_height; int y_stride, uv_stride; int img_size; uint8_t *img; }; typedef struct { xine_video_port_t vo; /* public part */ vo_driver_t *driver; pthread_mutex_t driver_lock; xine_private_t *xine; metronom_clock_t *clock; #define STREAMS_DEFAULT_SIZE 32 int num_null_streams; int num_anon_streams; int num_streams; int streams_size; xine_stream_private_t **streams, *streams_default[STREAMS_DEFAULT_SIZE]; xine_rwlock_t streams_lock; struct { pthread_mutex_t mutex; pthread_cond_t not_empty; vo_frame_t *first; vo_frame_t **add; int num_buffers; int num_buffers_max; int locked_for_read; } free_queue; struct { pthread_mutex_t mutex; pthread_cond_t not_empty; pthread_cond_t done_flushing; vo_frame_t *first; vo_frame_t **add; int num_buffers; int locked_for_read; /* The flush protocol. */ int discard_frames; int flushed; /* Snapshot of rp.ready_num. */ int flush_extra; int num_flush_waiters; /* frame rate limit */ int max_frame_rate; uint32_t min_frame_duration; /* frame stream refs. * we need to ref a stream for at least as long as it has frames flying around. * at first sight, it would be nice to unref as early as puossible, so the * stream can dispose itself. however, that would be a performance killer. * also, it may not have the desired effect when the stream itself gets reused, * and/or some frames are held by driver and this->grab.last_frame. * instead, let the natural flow clean up for us in vo_display_reref_append (), * and check manually now and then while running idle. */ vo_frame_t **frames; xine_stream_private_t **img_streams; } display_queue; /* Render thread privates. Other threads may _read_ integers, without freshness * guarantee. */ struct { /* Optimization: keep video decoder from interfering with output timing. * Employ a separate mutex less frame queue private to the render thread. * Fetch the entire shared queue into it when flushing, or when running * down to less than 2 frames. This way we can still set frame.future_frame. * Also, do that after time critical stuff, if possible. */ vo_frame_t *ready_first; vo_frame_t **ready_add; int ready_num; /* Adaptive redraw needed polling. */ int poll_time; int poll_limit; int poll_num; /* Output loop iterations, total and without a frame to display. */ int wakeups_total; int wakeups_early; /* Snapshot of display_queue.num_flush_waiters. */ int need_flush_signal; /* Filler frame during forward seek. */ vo_frame_t *last_flushed; /* Wakeup time. */ struct timespec now; int speed; /* frame rate limit */ uint32_t min_frame_duration; int64_t skip_until; } rp; /* Get grab_lock when * - accessing grab queue, * - setting last_frame, and * - reading last_frame from outside the render thread. */ struct { pthread_mutex_t lock; pthread_cond_t wake; vos_grab_video_frame_t *request; vo_frame_t *last_frame; } grab; uint32_t video_loop_running:1; uint32_t video_opened:1; uint32_t overlay_enabled:1; uint32_t warn_threshold_event_sent:1; /* do we true real-time output or is this a grab only instance ? */ uint32_t grab_only:1; uint32_t redraw_needed:3; pthread_t video_thread; int num_frames_delivered; int num_frames_skipped; int num_frames_discarded; int num_frames_burst; /* threshold for sending XINE_EVENT_DROPPED_FRAMES */ int warn_skipped_threshold; int warn_discarded_threshold; int warn_threshold_exceeded; int disable_decoder_flush_from_video_out; /* pts value when decoder delivered last video frame */ int64_t last_delivery_pts; video_overlay_manager_t *overlay_source; extra_info_t *extra_info_base; /* used to free mem chunk */ uint32_t last_ei_index; int current_width, current_height; int64_t current_duration; int frame_drop_limit_max; int frame_drop_limit; int frame_drop_cpt; int frame_drop_suggested; int crop_left, crop_right, crop_top, crop_bottom; struct { pthread_mutex_t mutex; pthread_cond_t wake; pthread_cond_t done_stepping; int draw; int speed; int step; } trigger_drawing; #ifdef ADD_KEYFRAME_INDEX int keyframe_mode; #endif /* frames usage stats */ int frames_total; int frames_extref; int frames_peak_used; } vos_t; /******************************************************************** * streams register. * * Reading is way more speed relevant here. * *******************************************************************/ static void vo_streams_open (vos_t *this) { #ifndef HAVE_ZERO_SAFE_MEM this->num_null_streams = 0; this->num_anon_streams = 0; this->num_streams = 0; this->streams_default[0] = NULL; #endif this->streams_size = STREAMS_DEFAULT_SIZE; this->streams = &this->streams_default[0]; xine_rwlock_init_default (&this->streams_lock); } static void vo_streams_close (vos_t *this) { xine_rwlock_destroy (&this->streams_lock); if (this->streams != &this->streams_default[0]) free (this->streams); #if 0 /* not yet needed */ this->streams = NULL; this->num_null_streams = 0; this->num_anon_streams = 0; this->num_streams = 0; this->streams_size = 0; #endif } static void vo_streams_register (vos_t *this, xine_stream_private_t *s) { xine_rwlock_wrlock (&this->streams_lock); if (!s) { this->num_null_streams++; } else if (&s->s == XINE_ANON_STREAM) { this->num_anon_streams++; } else do { xine_stream_private_t **a = this->streams; if (this->num_streams + 2 > this->streams_size) { xine_stream_private_t **n = malloc ((this->streams_size + 32) * sizeof (void *)); if (!n) break; memcpy (n, a, this->streams_size * sizeof (void *)); this->streams = n; if (a != &this->streams_default[0]) free (a); a = n; this->streams_size += 32; } a[this->num_streams++] = s; a[this->num_streams] = NULL; } while (0); xine_rwlock_unlock (&this->streams_lock); } static void vo_streams_unregister (vos_t *this, xine_stream_private_t *s) { xine_rwlock_wrlock (&this->streams_lock); if (!s) { this->num_null_streams--; } else if (&s->s == XINE_ANON_STREAM) { this->num_anon_streams--; } else { xine_stream_private_t **a = this->streams; while (*a && (*a != s)) a++; if (*a) { do { a[0] = a[1]; a++; } while (*a); this->num_streams--; } } xine_rwlock_unlock (&this->streams_lock); } /******************************************************************** * reuse frame stream refs. * * be the current owner of img when calling this. * *******************************************************************/ static void vo_reref (vos_t *this, vo_frame_t *img) { xine_stream_private_t **s, *olds, *news; /* Paranoia? */ s = ((img->id >= 0) && (img->id < this->frames_total)) ? this->display_queue.img_streams + img->id : &news; news = (xine_stream_private_t *)img->stream; pthread_mutex_lock (&this->display_queue.mutex); olds = *s; if (olds != news) { *s = news; pthread_mutex_unlock (&this->display_queue.mutex); if (news) xine_refs_add (&news->refs, 1); /* this is fast. */ if (olds) xine_refs_sub (&olds->refs, 1); /* this may involve stream dispose. */ } else { pthread_mutex_unlock (&this->display_queue.mutex); } } static void vo_unref_list (vos_t *this, vo_frame_t *img) { xine_stream_private_t *d[128], **a = d; pthread_mutex_lock (&this->display_queue.mutex); for (; img; img = img->next) { img->stream = NULL; /* Paranoia? */ if ((img->id >= 0) && (img->id < this->frames_total)) { xine_stream_private_t **s = this->display_queue.img_streams + img->id; if (*s) { *a++ = *s; *s = NULL; if (a > d + sizeof (d) / sizeof (d[0]) - 2) break; } } } pthread_mutex_unlock (&this->display_queue.mutex); *a = NULL; for (a = d; *a; a++) xine_refs_sub (&(*a)->refs, 1); /* this may involve stream dispose. */ } static void vo_unref_obsolete (vos_t *this) { int i; xine_stream_private_t *d[128], **a = d; xine_rwlock_rdlock (&this->streams_lock); pthread_mutex_lock (&this->display_queue.mutex); for (i = 0; i < this->frames_total; i++) { vo_frame_t *f; xine_stream_private_t *img_stream = this->display_queue.img_streams[i], **open_stream; if (!img_stream) continue; for (open_stream = this->streams; *open_stream; open_stream++) { if (img_stream == *open_stream) break; } if (*open_stream) continue; f = this->display_queue.frames[i]; if (pthread_mutex_trylock (&f->mutex)) continue; if ((f->lock_counter != 0) || (f->id != i)) { pthread_mutex_unlock (&f->mutex); continue; } pthread_mutex_unlock (&f->mutex); this->display_queue.img_streams[i] = NULL; *a++ = img_stream; if (a > d + sizeof (d) / sizeof (d[0]) - 2) break; } *a = NULL; pthread_mutex_unlock (&this->display_queue.mutex); xine_rwlock_unlock (&this->streams_lock); if (a > d) { for (a = d; *a; a++) xine_refs_sub (&(*a)->refs, 1); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": freed %d obsolete stream refs.\n", (int)(a - d)); } } /******************************************************************** * frame queue (fifo) * *******************************************************************/ static void vo_free_queue_open (vos_t *this) { #ifndef HAVE_ZERO_SAFE_MEM this->free_queue.first = NULL; this->free_queue.num_buffers = 0; this->free_queue.num_buffers_max = 0; this->free_queue.locked_for_read = 0; #endif this->free_queue.add = &this->free_queue.first; pthread_mutex_init (&this->free_queue.mutex, NULL); pthread_cond_init (&this->free_queue.not_empty, NULL); } static void vo_display_queue_open (vos_t *this) { #ifndef HAVE_ZERO_SAFE_MEM this->display_queue.first = NULL; this->display_queue.num_buffers = 0; this->display_queue.locked_for_read = 0; this->display_queue.discard_frames = 0; this->display_queue.flushed = 0; this->display_queue.flush_extra = 0; this->display_queue.num_flush_waiters = 0; #endif this->display_queue.add = &this->display_queue.first; pthread_mutex_init (&this->display_queue.mutex, NULL); pthread_cond_init (&this->display_queue.not_empty, NULL); pthread_cond_init (&this->display_queue.done_flushing, NULL); } static void vo_free_queue_close (vos_t *this) { #if 0 /* not yet needed */ this->display_queue.first = NULL; this->display_queue.num_buffers = 0; this->display_queue.locked_for_read = 0; this->display_queue.discard_frames = 0; this->display_queue.flushed = 0; this->display_queue.flush_extra = 0; this->display_queue.num_flush_waiters = 0; this->display_queue.add = &this->display_queue.first; #endif pthread_mutex_destroy (&this->free_queue.mutex); pthread_cond_destroy (&this->free_queue.not_empty); } static void vo_display_queue_close (vos_t *this) { #if 0 /* not yet needed */ this->free_queue.first = NULL; this->free_queue.num_buffers = 0; this->free_queue.num_buffers_max = 0; this->free_queue.locked_for_read = 0; this->free_queue.add = &this->free_queue.first; #endif pthread_mutex_destroy (&this->display_queue.mutex); pthread_cond_destroy (&this->display_queue.not_empty); pthread_cond_destroy (&this->display_queue.done_flushing); } static vo_frame_t *vo_free_queue_get_all (vos_t *this) { vo_frame_t *list; pthread_mutex_lock (&this->free_queue.mutex); list = this->free_queue.first; this->free_queue.first = NULL; this->free_queue.add = &this->free_queue.first; this->free_queue.num_buffers = 0; pthread_mutex_unlock (&this->free_queue.mutex); return list; } static vo_frame_t *vo_display_queue_get_all (vos_t *this) { vo_frame_t *list; pthread_mutex_lock (&this->display_queue.mutex); list = this->display_queue.first; this->display_queue.first = NULL; this->display_queue.add = &this->display_queue.first; this->display_queue.num_buffers = 0; pthread_mutex_unlock (&this->display_queue.mutex); return list; } static void vo_dispose_list (vo_frame_t *list) { while (list) { vo_frame_t *next = list->next; list->next = NULL; list->dispose (list); list = next; } } static void vo_free_queue_read_lock (vos_t *this) { pthread_mutex_lock (&this->free_queue.mutex); this->free_queue.locked_for_read = 2; pthread_mutex_unlock (&this->free_queue.mutex); } static void vo_free_queue_read_unlock (vos_t *this) { pthread_mutex_lock (&this->free_queue.mutex); this->free_queue.locked_for_read = 0; if (this->free_queue.first) pthread_cond_signal (&this->free_queue.not_empty); pthread_mutex_unlock (&this->free_queue.mutex); } static void vo_ticket_revoked (void *user_data, int flags) { vos_t *this = (vos_t *)user_data; const char *s1 = (flags & XINE_TICKET_FLAG_ATOMIC) ? " atomic" : ""; const char *s2 = (flags & XINE_TICKET_FLAG_REWIRE) ? " port_rewire" : ""; pthread_cond_signal (&this->free_queue.not_empty); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": port ticket revoked%s%s.\n", s1, s2); } static void vo_display_reref_append (vos_t *this, vo_frame_t *img) { xine_stream_private_t **s, *olds, *news; /* img already enqueue? (serious leak) */ _x_assert (img->next == NULL); img->next = NULL; /* Paranoia? */ s = ((img->id >= 0) && (img->id < this->frames_total)) ? this->display_queue.img_streams + img->id : &news; news = (xine_stream_private_t *)img->stream; pthread_mutex_lock (&this->display_queue.mutex); olds = *s; if (olds != news) { int n; *s = news; if (news) xine_refs_add (&news->refs, 1); /* this is fast. */ n = (this->display_queue.first ? this->display_queue.num_buffers : 0) + 1; *(this->display_queue.add) = img; this->display_queue.add = &img->next; this->display_queue.num_buffers = n; if (n > this->display_queue.locked_for_read) pthread_cond_signal (&this->display_queue.not_empty); pthread_mutex_unlock (&this->display_queue.mutex); if (olds) xine_refs_sub (&olds->refs, 1); /* this may involve stream dispose. */ } else { int n = (this->display_queue.first ? this->display_queue.num_buffers : 0) + 1; *(this->display_queue.add) = img; this->display_queue.add = &img->next; this->display_queue.num_buffers = n; if (n > this->display_queue.locked_for_read) pthread_cond_signal (&this->display_queue.not_empty); pthread_mutex_unlock (&this->display_queue.mutex); } } static void vo_free_append (vos_t *this, vo_frame_t *img) { int n; /* img already enqueue? (serious leak) */ _x_assert (img->next==NULL); pthread_mutex_lock (&this->free_queue.mutex); img->next = NULL; n = (this->free_queue.first ? this->free_queue.num_buffers : 0) + 1; *(this->free_queue.add) = img; this->free_queue.add = &img->next; this->free_queue.num_buffers = n; if (n > this->free_queue.locked_for_read) pthread_cond_signal (&this->free_queue.not_empty); pthread_mutex_unlock (&this->free_queue.mutex); } static void vo_free_append_list (vos_t *this, vo_frame_t *img, vo_frame_t **add, int n) { if (!img) return; pthread_mutex_lock (&this->free_queue.mutex); *(this->free_queue.add) = img; this->free_queue.add = add; n += this->free_queue.num_buffers; this->free_queue.num_buffers = n; if (n > this->free_queue.locked_for_read) pthread_cond_broadcast (&this->free_queue.not_empty); pthread_mutex_unlock (&this->free_queue.mutex); } static vo_frame_t *vo_free_queue_pop_int (vos_t *this) { vo_frame_t *img; img = this->free_queue.first; this->free_queue.first = img->next; img->next = NULL; if (!this->free_queue.first) { this->free_queue.add = &this->free_queue.first; this->free_queue.num_buffers = 0; } else { this->free_queue.num_buffers--; } return img; } static vo_frame_t *vo_display_queue_pop_int (vos_t *this) { vo_frame_t *img; img = this->display_queue.first; this->display_queue.first = img->next; img->next = NULL; if (!this->display_queue.first) { this->display_queue.add = &this->display_queue.first; this->display_queue.num_buffers = 0; } else { this->display_queue.num_buffers--; } return img; } static int vo_frame_dec2_lock_int (vos_t *this, vo_frame_t *img); static vo_frame_t *vo_get_unblock_frame (vos_t *this) { vo_frame_t *f, **add; /* Try 1: free queue reserve. */ pthread_mutex_lock (&this->free_queue.mutex); if (this->free_queue.first) { f = vo_free_queue_pop_int (this); pthread_mutex_unlock (&this->free_queue.mutex); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": got unblock frame from free queue.\n"); return f; } pthread_mutex_unlock (&this->free_queue.mutex); /* Try 2: shared display queue. */ pthread_mutex_lock (&this->display_queue.mutex); add = &this->display_queue.first; while ((f = *add)) { if (f->lock_counter <= 2) break; add = &f->next; } if (f) { *add = f->next; /* f->next = NULL; vo_frame_dec2_lock_int () does this below */ this->display_queue.num_buffers--; if (!*add) { this->display_queue.add = add; /* just a safety reset */ if (!this->display_queue.first) this->display_queue.num_buffers = 0; } pthread_mutex_unlock (&this->display_queue.mutex); vo_frame_dec2_lock_int (this, f); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": got unblock frame from display queue.\n"); return f; } pthread_mutex_unlock (&this->display_queue.mutex); return NULL; } static vo_frame_t *vo_free_queue_get (vos_t *this, uint32_t width, uint32_t height, double ratio, int format, int flags) { vo_frame_t *img, **add; (void)flags; pthread_mutex_lock (&this->free_queue.mutex); do { add = &this->free_queue.first; if (this->free_queue.num_buffers > this->free_queue.locked_for_read) { img = *add; #if EXPERIMENTAL_FRAME_QUEUE_OPTIMIZATION if (width && height) { /* try to obtain a frame with the same format first. * doing so may avoid unnecessary alloc/free's at the vo * driver, specially when using post plugins that change * format like the tvtime deinterlacer does. */ int i = 0; while (img && ((img->format != format) || (img->width != (int)width) || (img->height != (int)height) || (img->ratio != ratio))) { add = &img->next; img = *add; i++; } if (!img) { if ((this->free_queue.num_buffers == 1) && (this->free_queue.num_buffers_max > 8)) { /* only a single frame on fifo with different * format -> ignore it (give another chance of a frame format hit) * only if we have a lot of buffers at all. */ lprintf("frame format mismatch - will wait another frame\n"); } else { /* we have just a limited number of buffers or at least 2 frames * on fifo but they don't match -> give up. return whatever we got. */ add = &this->free_queue.first; img = *add; lprintf("frame format miss (%d/%d)\n", i, this->free_queue.num_buffers); } } else { /* good: format match! */ lprintf("frame format hit (%d/%d)\n", i, this->free_queue.num_buffers); } } #endif } else { img = NULL; } if (!img) { if (this->xine->port_ticket->ticket_revoked) { pthread_mutex_unlock (&this->free_queue.mutex); this->xine->port_ticket->renew (this->xine->port_ticket, 1); if (!(this->xine->port_ticket->ticket_revoked & XINE_TICKET_FLAG_REWIRE)) { pthread_mutex_lock (&this->free_queue.mutex); continue; } /* O dear. Port rewire ahaed. Try unblocking with regular or emergency frame. */ if (this->clock->speed == XINE_SPEED_PAUSE) { img = vo_get_unblock_frame (this); if (img) return img; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": allow port rewire.\n"); this->xine->port_ticket->renew (this->xine->port_ticket, XINE_TICKET_FLAG_REWIRE); pthread_mutex_lock (&this->free_queue.mutex); continue; } pthread_mutex_lock (&this->free_queue.mutex); } { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_sec += 1; pthread_cond_timedwait (&this->free_queue.not_empty, &this->free_queue.mutex, &ts); } } } while (!img); if (img) { *add = img->next; img->next = NULL; this->free_queue.num_buffers--; if (!*add) { this->free_queue.add = add; /* just a safety reset */ if (!this->free_queue.first) this->free_queue.num_buffers = 0; } } pthread_mutex_unlock (&this->free_queue.mutex); return img; } static vo_frame_t *vo_free_get_dupl (vos_t *this, vo_frame_t *s) { vo_frame_t *img, **add; pthread_mutex_lock (&this->free_queue.mutex); add = &this->free_queue.first; while ((img = *add)) { if ((img->format == s->format) && (img->width == s->width) && (img->height == s->height) && (img->ratio == s->ratio)) break; add = &img->next; } if (!img) { add = &this->free_queue.first; img = *add; } if (img) { *add = img->next; img->next = NULL; this->free_queue.num_buffers--; if (!*add) { this->free_queue.add = add; /* just a safety reset */ if (!this->free_queue.first) this->free_queue.num_buffers = 0; } } pthread_mutex_unlock (&this->free_queue.mutex); return img; } static void vo_update_max_frame_rate (vos_t *this, int speed) { if (this->display_queue.max_frame_rate <= 0) { this->display_queue.min_frame_duration = 0; } else { /* acually allow rate + 0.5 */ int v = (XINE_FINE_SPEED_NORMAL / 10000) * (this->display_queue.max_frame_rate * 2 + 1); this->display_queue.min_frame_duration = (90000 / 10000 * 2) * speed / v; } } /******************************************************************** * frame lock_counter. Basic rule: * * When queuing new frame, we add 2 refs. * * 1 for rendering, and 1 for still frame backup and rgb framegrab. * *******************************************************************/ static void vo_frame_inc2_lock (vo_frame_t *img) { int n; pthread_mutex_lock (&img->mutex); n = (img->lock_counter += 2); if ((n == 3) || (n == 4)) { vos_t *this = (vos_t *)img->port; if (this->frames_extref < this->frames_total) this->frames_extref++; } pthread_mutex_unlock (&img->mutex); } static void vo_frame_inc_lock (vo_frame_t *img) { pthread_mutex_lock (&img->mutex); img->lock_counter++; if (img->lock_counter == 3) { vos_t *this = (vos_t *)img->port; if (this->frames_extref < this->frames_total) this->frames_extref++; } pthread_mutex_unlock (&img->mutex); } static void vo_frame_dec_lock (vo_frame_t *img) { pthread_mutex_lock (&img->mutex); img->lock_counter--; if (!img->lock_counter) { vos_t *this = (vos_t *) img->port; vo_free_append (this, img); } else if (img->lock_counter == 2) { vos_t *this = (vos_t *)img->port; if (this->frames_extref > 0) this->frames_extref--; } pthread_mutex_unlock (&img->mutex); } static int vo_frame_dec2_lock_int (vos_t *this, vo_frame_t *img) { int n; pthread_mutex_lock (&img->mutex); img->next = NULL; n = img->lock_counter - 2; if (n <= 0) /* "<=" yields better code than "<" there. */ n = 0; else if ((n == 1) || (n == 2)) { if (this->frames_extref > 0) this->frames_extref--; } img->lock_counter = n; pthread_mutex_unlock (&img->mutex); return n; } static void vo_frame_dec2_lock (vos_t *this, vo_frame_t *img) { if (!vo_frame_dec2_lock_int (this, img)) { vo_free_append (this, img); } } /******************************************************************** * Flush helpers. * ********************************************************************/ /* have this->display_queue.mutex locked!! */ static void vo_wait_flush (vos_t *this) { this->display_queue.num_flush_waiters++; pthread_mutex_lock (&this->trigger_drawing.mutex); this->trigger_drawing.draw = 1; pthread_cond_signal (&this->trigger_drawing.wake); pthread_mutex_unlock (&this->trigger_drawing.mutex); while (this->display_queue.flush_extra || this->display_queue.first) pthread_cond_wait (&this->display_queue.done_flushing, &this->display_queue.mutex); this->display_queue.num_flush_waiters--; } static void vo_list_flush (vos_t *this, vo_frame_t *f) { vo_frame_t *list = NULL, **add = &list; int n = 0; while (f) { vo_frame_t *next = f->next; if (!vo_frame_dec2_lock_int (this, f)) { *add = f; add = &f->next; n++; } f = next; } vo_free_append_list (this, list, add, n); } static void vo_manual_flush (vos_t *this) { vo_frame_t *f; pthread_mutex_lock (&this->display_queue.mutex); f = this->display_queue.first; this->display_queue.first = NULL; this->display_queue.add = &this->display_queue.first; this->display_queue.num_buffers = 0; pthread_mutex_unlock (&this->display_queue.mutex); vo_list_flush (this, f); } /******************************************************************** * grabbing RGB images from displayed frames * *******************************************************************/ static void vo_dispose_grab_video_frame(xine_grab_video_frame_t *frame_gen) { vos_grab_video_frame_t *frame = (vos_grab_video_frame_t *) frame_gen; if (frame->vo_frame) vo_frame_dec_lock(frame->vo_frame); if (frame->yuv2rgb) frame->yuv2rgb->dispose(frame->yuv2rgb); if (frame->yuv2rgb_factory) frame->yuv2rgb_factory->dispose(frame->yuv2rgb_factory); _x_freep(&frame->img); _x_freep(&frame->grab_frame.img); free(frame); } static int vo_grab_grab_video_frame (xine_grab_video_frame_t *frame_gen) { vos_grab_video_frame_t *frame = (vos_grab_video_frame_t *) frame_gen; vos_t *this = (vos_t *) frame->video_port; vo_frame_t *vo_frame; int format, y_stride, uv_stride; int width, height; uint8_t *base[3]; if (frame->grab_frame.flags & XINE_GRAB_VIDEO_FRAME_FLAGS_WAIT_NEXT) { struct timespec ts = {0, 0}; /* calculate absolute timeout time */ xine_gettime (&ts); ts.tv_sec += frame->grab_frame.timeout / 1000; ts.tv_nsec += (frame->grab_frame.timeout % 1000) * 1000000; if (ts.tv_nsec >= 1000000000) { ts.tv_sec += 1; ts.tv_nsec -= 1000000000; } pthread_mutex_lock(&this->grab.lock); /* insert grab request into grab queue */ frame->next = this->grab.request; this->grab.request = frame; /* wait until our request is finished */ frame->finished = 0; while (!frame->finished) { if (pthread_cond_timedwait (&this->grab.wake, &this->grab.lock, &ts) == ETIMEDOUT) { vos_grab_video_frame_t *prev = this->grab.request; while (prev) { if (prev == frame) { this->grab.request = frame->next; break; } else if (prev->next == frame) { prev->next = frame->next; break; } prev = prev->next; } frame->next = NULL; pthread_mutex_unlock(&this->grab.lock); return 1; /* no frame available */ } } pthread_mutex_unlock(&this->grab.lock); vo_frame = frame->vo_frame; frame->vo_frame = NULL; if (!vo_frame) return -1; /* error happened */ } else { pthread_mutex_lock(&this->grab.lock); /* use last displayed frame */ vo_frame = this->grab.last_frame; if (!vo_frame) { pthread_mutex_unlock(&this->grab.lock); return 1; /* no frame available */ } if (vo_frame->format != XINE_IMGFMT_YV12 && vo_frame->format != XINE_IMGFMT_YUY2 && !vo_frame->proc_provide_standard_frame_data) { pthread_mutex_unlock(&this->grab.lock); return -1; /* error happened */ } vo_frame_inc_lock(vo_frame); pthread_mutex_unlock(&this->grab.lock); frame->grab_frame.vpts = vo_frame->vpts; } width = vo_frame->width; height = vo_frame->height; if (vo_frame->format == XINE_IMGFMT_YV12 || vo_frame->format == XINE_IMGFMT_YUY2) { format = vo_frame->format; y_stride = vo_frame->pitches[0]; uv_stride = vo_frame->pitches[1]; base[0] = vo_frame->base[0]; base[1] = vo_frame->base[1]; base[2] = vo_frame->base[2]; } else { /* retrieve standard format image data from output driver */ xine_current_frame_data_t data; memset(&data, 0, sizeof(data)); vo_frame->proc_provide_standard_frame_data(vo_frame, &data); if (data.img_size > frame->img_size) { free(frame->img); frame->img_size = data.img_size; frame->img = calloc(data.img_size, sizeof(uint8_t)); if (!frame->img) { vo_frame_dec_lock(vo_frame); return -1; /* error happened */ } } data.img = frame->img; vo_frame->proc_provide_standard_frame_data(vo_frame, &data); format = data.format; if (format == XINE_IMGFMT_YV12) { base[0] = data.img; base[1] = data.img + width * height; base[2] = data.img + width * height + ((width * height) >> 2); y_stride = width; uv_stride = width >> 1; } else { // XINE_IMGFMT_YUY2 base[0] = data.img; base[1] = NULL; base[2] = NULL; y_stride = width * 2; uv_stride = 0; } } /* take cropping parameters into account */ { int crop_left = (vo_frame->crop_left + frame->grab_frame.crop_left) & ~1; int crop_right = (vo_frame->crop_right + frame->grab_frame.crop_right) & ~1; int crop_top = vo_frame->crop_top + frame->grab_frame.crop_top; int crop_bottom = vo_frame->crop_bottom + frame->grab_frame.crop_bottom; if (crop_left || crop_right || crop_top || crop_bottom) { if ((width - crop_left - crop_right) >= 8) width = width - crop_left - crop_right; else crop_left = crop_right = 0; if ((height - crop_top - crop_bottom) >= 8) height = height - crop_top - crop_bottom; else crop_top = crop_bottom = 0; if (format == XINE_IMGFMT_YV12) { size_t uv_offs; base[0] += crop_top * y_stride + crop_left; uv_offs = (crop_top >> 1) * uv_stride + (crop_left >> 1); base[1] += uv_offs; base[2] += uv_offs; } else { // XINE_IMGFMT_YUY2 base[0] += crop_top * y_stride + crop_left * 2; } } } /* get pixel aspect ratio */ { double sar = 1.0; { int sarw = vo_frame->width - vo_frame->crop_left - vo_frame->crop_right; int sarh = vo_frame->height - vo_frame->crop_top - vo_frame->crop_bottom; if ((vo_frame->ratio > 0.0) && (sarw > 0) && (sarh > 0)) sar = vo_frame->ratio * sarh / sarw; } /* if caller does not specify frame size we return the actual size of grabbed frame */ if ((frame->grab_frame.width <= 0) && (frame->grab_frame.height <= 0)) { if (sar > 1.0) { frame->grab_frame.width = sar * width + 0.5; frame->grab_frame.height = height; } else { frame->grab_frame.width = width; frame->grab_frame.height = (double)height / sar + 0.5; } } else if (frame->grab_frame.width <= 0) frame->grab_frame.width = frame->grab_frame.height * width * sar / height + 0.5; else if (frame->grab_frame.height <= 0) frame->grab_frame.height = (frame->grab_frame.width * height) / (sar * width) + 0.5; } /* allocate grab frame image buffer */ if (frame->grab_frame.width != frame->grab_width || frame->grab_frame.height != frame->grab_height) { _x_freep(&frame->grab_frame.img); } if (frame->grab_frame.img == NULL) { frame->grab_frame.img = (uint8_t *) calloc(frame->grab_frame.width * frame->grab_frame.height, 3); if (frame->grab_frame.img == NULL) { vo_frame_dec_lock(vo_frame); return -1; /* error happened */ } } /* initialize yuv2rgb factory */ if (!frame->yuv2rgb_factory) { int cm = VO_GET_FLAGS_CM (vo_frame->flags); frame->yuv2rgb_factory = yuv2rgb_factory_init(MODE_24_RGB, 0, NULL); if (!frame->yuv2rgb_factory) { vo_frame_dec_lock(vo_frame); return -1; /* error happened */ } if ((cm >> 1) == 2) /* color matrix undefined */ cm = (cm & 1) | ((vo_frame->height - vo_frame->crop_top - vo_frame->crop_bottom >= 720) || (vo_frame->width - vo_frame->crop_left - vo_frame->crop_right >= 1280) ? 2 : 10); else if ((cm >> 1) == 0) /* converted RGB source, always ITU 601 */ cm = (cm & 1) | 10; frame->yuv2rgb_factory->set_csc_levels (frame->yuv2rgb_factory, 0, 128, 128, cm); } /* retrieve a yuv2rgb converter */ if (!frame->yuv2rgb) { frame->yuv2rgb = frame->yuv2rgb_factory->create_converter(frame->yuv2rgb_factory); if (!frame->yuv2rgb) { vo_frame_dec_lock(vo_frame); return -1; /* error happened */ } } /* configure yuv2rgb converter */ if (width != frame->vo_width || height != frame->vo_height || frame->grab_frame.width != frame->grab_width || frame->grab_frame.height != frame->grab_height || y_stride != frame->y_stride || uv_stride != frame->uv_stride) { frame->vo_width = width; frame->vo_height = height; frame->grab_width = frame->grab_frame.width; frame->grab_height = frame->grab_frame.height; frame->y_stride = y_stride; frame->uv_stride = uv_stride; frame->yuv2rgb->configure(frame->yuv2rgb, width, height, y_stride, uv_stride, frame->grab_width, frame->grab_height, frame->grab_width * 3); } /* convert YUV to RGB image taking possible scaling into account */ if(format == XINE_IMGFMT_YV12) frame->yuv2rgb->yuv2rgb_fun(frame->yuv2rgb, frame->grab_frame.img, base[0], base[1], base[2]); else frame->yuv2rgb->yuy22rgb_fun(frame->yuv2rgb, frame->grab_frame.img, base[0]); vo_frame_dec_lock(vo_frame); return 0; } static xine_grab_video_frame_t *vo_new_grab_video_frame(xine_video_port_t *this_gen) { vos_grab_video_frame_t *frame = calloc(1, sizeof(vos_grab_video_frame_t)); if (frame) { frame->grab_frame.dispose = vo_dispose_grab_video_frame; frame->grab_frame.grab = vo_grab_grab_video_frame; frame->grab_frame.vpts = -1; frame->grab_frame.timeout = XINE_GRAB_VIDEO_FRAME_DEFAULT_TIMEOUT; frame->video_port = this_gen; } return (xine_grab_video_frame_t *)frame; } /* Use this after rendering a live frame (not for still frame duplicates). */ static void vo_grab_current_frame (vos_t *this, vo_frame_t *vo_frame, int64_t vpts) { pthread_mutex_lock(&this->grab.lock); /* hold current frame for still frame generation and snapshot feature */ if (this->grab.last_frame) vo_frame_dec_lock(this->grab.last_frame); this->grab.last_frame = vo_frame; /* process grab queue */ vos_grab_video_frame_t *frame = this->grab.request; if (frame) { do { vos_grab_video_frame_t *next; if (frame->vo_frame) vo_frame_dec_lock(frame->vo_frame); frame->vo_frame = NULL; if (vo_frame->format == XINE_IMGFMT_YV12 || vo_frame->format == XINE_IMGFMT_YUY2 || vo_frame->proc_provide_standard_frame_data) { vo_frame_inc_lock(vo_frame); frame->vo_frame = vo_frame; frame->grab_frame.vpts = vpts; } frame->finished = 1; next = frame->next; frame->next = NULL; frame = next; } while (frame); this->grab.request = NULL; pthread_cond_broadcast(&this->grab.wake); } pthread_mutex_unlock(&this->grab.lock); } /* call vo_driver->proc methods for the entire frame */ static void vo_frame_driver_proc(vo_frame_t *img) { if (img->proc_frame) { img->proc_frame(img); } if (img->proc_called) return; if (img->proc_slice) { int height = img->height; uint8_t* src[3]; switch (img->format) { case XINE_IMGFMT_YV12: src[0] = img->base[0]; src[1] = img->base[1]; src[2] = img->base[2]; while ((height -= 16) > -16) { img->proc_slice(img, src); src[0] += 16 * img->pitches[0]; src[1] += 8 * img->pitches[1]; src[2] += 8 * img->pitches[2]; } break; case XINE_IMGFMT_YUY2: src[0] = img->base[0]; while ((height -= 16) > -16) { img->proc_slice(img, src); src[0] += 16 * img->pitches[0]; } break; } } } /******************************************************************** * called by video decoder: * * get_frame => alloc frame for rendering * * frame_draw => queue finished frame for display * * frame_free => frame no longer used as reference frame by decoder * *******************************************************************/ static vo_frame_t *vo_get_frame (xine_video_port_t *this_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { vo_frame_t *img; vos_t *this = (vos_t *) this_gen; lprintf ("get_frame (%d x %d)\n", width, height); if (width * height == 0) { /* drivers need not support or trap this. */ xprintf (&this->xine->x, XINE_VERBOSITY_LOG, LOG_MODULE ": vo_get_frame: invalid frame size %u x %u.\n", (unsigned int)width, (unsigned int)height); width = height = 16; } /* some decoders report strange ratios */ if (ratio <= 0.0) ratio = (double)width / (double)height; while (1) { img = vo_free_queue_get (this, width, height, ratio, format, flags); lprintf ("got a frame -> pthread_mutex_lock (&img->mutex)\n"); pthread_mutex_lock (&img->mutex); img->lock_counter = 1; img->width = width; img->height = height; img->ratio = ratio; img->format = format; img->flags = flags; img->proc_called = 0; img->bad_frame = 0; img->progressive_frame = 0; img->repeat_first_field = 0; img->top_field_first = 1; img->crop_left = 0; img->crop_right = 0; img->crop_top = 0; img->crop_bottom = 0; img->overlay_offset_x = 0; img->overlay_offset_y = 0; img->stream = NULL; _x_extra_info_reset ( img->extra_info ); /* let driver ensure this image has the right format */ this->driver->update_frame_format (this->driver, img, width, height, ratio, format, flags); pthread_mutex_unlock (&img->mutex); if (!width || img->width) break; xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n"), width, height, img->format); img->lock_counter = 0; vo_free_append (this, img); /* check if we're allowed to return NULL */ if (flags & VO_GET_FRAME_MAY_FAIL) return NULL; } /* update frame usage stats. No need to lock queues for that I guess :-) */ { int frames_used; frames_used = this->frames_total; frames_used -= this->free_queue.num_buffers; frames_used -= this->display_queue.num_buffers; frames_used -= this->rp.ready_num; frames_used += this->frames_extref; if (frames_used > this->frames_peak_used) this->frames_peak_used = frames_used; } lprintf ("get_frame (%d x %d) done\n", width, height); return img; } /* crop_frame() will allocate a new frame to copy in the given image * while cropping. maybe someday this will be an automatic post plugin. */ static vo_frame_t * crop_frame( xine_video_port_t *this_gen, vo_frame_t *img ) { vo_frame_t *dupl; dupl = vo_get_frame ( this_gen, img->width - img->crop_left - img->crop_right, img->height - img->crop_top - img->crop_bottom, img->ratio, img->format, img->flags | VO_BOTH_FIELDS); dupl->progressive_frame = img->progressive_frame; dupl->repeat_first_field = img->repeat_first_field; dupl->top_field_first = img->top_field_first; dupl->overlay_offset_x = img->overlay_offset_x; dupl->overlay_offset_y = img->overlay_offset_y; switch (img->format) { case XINE_IMGFMT_YV12: yv12_to_yv12( /* Y */ img->base[0] + img->crop_top * img->pitches[0] + img->crop_left, img->pitches[0], dupl->base[0], dupl->pitches[0], /* U */ img->base[1] + img->crop_top/2 * img->pitches[1] + img->crop_left/2, img->pitches[1], dupl->base[1], dupl->pitches[1], /* V */ img->base[2] + img->crop_top/2 * img->pitches[2] + img->crop_left/2, img->pitches[2], dupl->base[2], dupl->pitches[2], /* width x height */ dupl->width, dupl->height); break; case XINE_IMGFMT_YUY2: yuy2_to_yuy2( /* src */ img->base[0] + img->crop_top * img->pitches[0] + img->crop_left*2, img->pitches[0], /* dst */ dupl->base[0], dupl->pitches[0], /* width x height */ dupl->width, dupl->height); break; } dupl->bad_frame = 0; dupl->pts = img->pts; dupl->vpts = img->vpts; dupl->proc_called = 0; dupl->duration = img->duration; dupl->is_first = img->is_first; dupl->stream = img->stream; memcpy( dupl->extra_info, img->extra_info, sizeof(extra_info_t) ); /* delay frame processing for now, we might not even need it (eg. frame will be discarded) */ /* vo_frame_driver_proc(dupl); */ return dupl; } static void vo_set_img_ei (vos_t *this, vo_frame_t *img) { xine_stream_private_t *s = (xine_stream_private_t *)img->stream; const extra_info_t *ei = s->video_decoder_extra_info; if (img->pts) do { xine_stream_private_t *m = s->side_streams[0]; uint32_t b, i; /* try fast hash table. */ i = m->video_decoder_ei_fast[((uint32_t)img->pts >> 9) & 255]; if (img->pts == m->ei[2 + i].pts) { this->last_ei_index = i; ei = &m->ei[2 + i].ei; break; } /* high end deinterlacers insert filler frames from 2nd field. */ { int64_t d; i = this->last_ei_index; d = img->pts - m->ei[2 + i].pts; if ((d >= 0) && (d < 90000 * 3 / 4 / 24)) { ei = &m->ei[2 + i].ei; _x_extra_info_merge (img->extra_info, ei); img->extra_info->input_time += (uint32_t)d / 90; return; } } /* fallback 1: manual search. */ b = i = m->video_decoder_ei_index; do { if (img->pts == m->ei[2 + i].pts) { this->last_ei_index = i; ei = &m->ei[2 + i].ei; break; } i = (i + _XINE_EI_RING_SIZE - 1) & (_XINE_EI_RING_SIZE - 1); } while (i != b); /* fallback 2: old style latest ei mode. */ } while (0); _x_extra_info_merge (img->extra_info, ei); } static int vo_frame_draw (vo_frame_t *img, xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; vos_t *this = (vos_t *) img->port; int frames_to_skip, first_frame_flag = 0; img->stream = NULL; if (this->display_queue.discard_frames) { /* Now that we have the auto gapless switch it should be safe to always drop here. */ lprintf ("i'm in flush mode, not appending this frame to queue\n"); return 0; } /* handle anonymous streams like NULL for easy checking */ if (&stream->s == XINE_ANON_STREAM) stream = NULL; if (stream) { /* Grabbing display_queue.mutex / first_frame_lock when testing * discard_frames / first_frame_flag is safe but slow. Most of the time these flags * will be 0. Lets try without lock first, and look closer after a flush only. */ first_frame_flag = stream->side_streams[0]->first_frame.flag; if (this->display_queue.flushed) { pthread_mutex_lock (&this->display_queue.mutex); if (this->display_queue.flushed) { this->display_queue.flushed = 0; pthread_mutex_unlock (&this->display_queue.mutex); pthread_mutex_lock (&stream->side_streams[0]->first_frame.lock); first_frame_flag = stream->side_streams[0]->first_frame.flag; pthread_mutex_unlock (&stream->side_streams[0]->first_frame.lock); } else { pthread_mutex_unlock (&this->display_queue.mutex); } } if (first_frame_flag >= 2) { /* Frame reordering and/or multithreaded deoders feature an initial delay. * Even worse: mpeg-ts does not seek to keyframes, as that would need quite some * decoder knowledge. As a result, there often burst in many "bad" frames here quickly. * Dont let these mess up timing, generate high frames_to_skip values, * and kill the following keyframe seq with that. */ this->last_delivery_pts = 0; if (img->bad_frame) { this->num_frames_burst++; return 0; } if (this->num_frames_burst) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": dropped %d bad frames after seek.\n", this->num_frames_burst); this->num_frames_burst = 0; } } img->stream = &stream->s; vo_set_img_ei (this, img); stream->s.metronom->got_video_frame (stream->s.metronom, img); #ifdef ADD_KEYFRAME_INDEX if (FIXME: IS_KEYFRAME (img)) { if (this->keyframe_mode == 0) { if (!stream->index_array && stream->input_plugin && INPUT_IS_SEEKABLE (stream->input_plugin)) { xprintf (stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": no keyframe index found, lets do it from this side.\n"); this->keyframe_mode = 1; } else { this->keyframe_mode = -1; } } if (this->keyframe_mode > 0) { xine_keyframes_entry_t entry; entry.msecs = img->extra_info->input_time; entry.normpos = img->extra_info->input_normpos; _x_keyframes_add (stream, &entry); } } #endif } this->current_width = img->width; this->current_height = img->height; this->current_duration = img->duration; if (!this->grab_only) { img->extra_info->vpts = img->vpts; this->last_delivery_pts = this->clock->get_current_time (this->clock); lprintf ("got image at master vpts %" PRId64 ". vpts for picture is %" PRId64 " (pts was %" PRId64 ")\n", this->last_delivery_pts, img->vpts, img->pts); this->num_frames_delivered++; /* Frame dropping slow start: * The engine starts to drop frames if there are less than frame_drop_limit * frames in advance. There might be a problem just after a seek because * there is no frame in advance yet. * The following code increases progressively the frame_drop_limit (-2 -> 3) * after a seek to give a chance to the engine to display the first frames * smoothly before starting to drop frames if the decoder is really too * slow. * The above numbers are the result of frame_drop_limit_max beeing 3. They * will be (-4 -> 1) when frame_drop_limit_max is only 1. This maximum value * depends on the number of video buffers which the output device provides. */ if (first_frame_flag >= 2) this->frame_drop_cpt = 10; if (this->frame_drop_cpt) { this->frame_drop_limit = this->frame_drop_limit_max - (this->frame_drop_cpt >> 1); this->frame_drop_cpt--; } /* do not skip decoding until output fifo frames are consumed */ if (this->display_queue.num_buffers + this->rp.ready_num < this->frame_drop_limit) { int duration = img->duration > 0 ? img->duration : DEFAULT_FRAME_DURATION; frames_to_skip = (this->last_delivery_pts - img->vpts) / duration; frames_to_skip = (frames_to_skip + this->frame_drop_limit) * 2; if (frames_to_skip < 0) frames_to_skip = 0; } else { frames_to_skip = 0; } /* Do not drop frames immediately, but remember this as suggestion and give * decoder a further chance to supply frames. * This avoids unnecessary frame drops in situations where there is only * a very little number of image buffers, e. g. when using xxmc. */ if (!frames_to_skip) { this->frame_drop_suggested = 0; } else { if (!this->frame_drop_suggested) { this->frame_drop_suggested = 1; frames_to_skip = 0; } } lprintf ("delivery diff : %" PRId64 ", current vpts is %" PRId64 ", %d frames to skip\n", img->vpts - this->last_delivery_pts, this->last_delivery_pts, frames_to_skip); } else { frames_to_skip = 0; } if (!img->bad_frame) { int img_already_locked = 0; /* add cropping requested by frontend */ img->crop_left = (img->crop_left + this->crop_left) & ~1; img->crop_right = (img->crop_right + this->crop_right) & ~1; img->crop_top += this->crop_top; img->crop_bottom += this->crop_bottom; /* perform cropping when vo driver does not support it */ if( (img->crop_left || img->crop_top || img->crop_right || img->crop_bottom) && (this->grab_only || !(this->driver->get_capabilities (this->driver) & VO_CAP_CROP)) ) { if (img->format == XINE_IMGFMT_YV12 || img->format == XINE_IMGFMT_YUY2) { img->overlay_offset_x -= img->crop_left; img->overlay_offset_y -= img->crop_top; img = crop_frame( img->port, img ); img->lock_counter = 2; img_already_locked = 1; } else { /* noone knows how to crop this, so we can only ignore the cropping */ img->crop_left = 0; img->crop_top = 0; img->crop_right = 0; img->crop_bottom = 0; } } /* do not call proc_*() for frames that will be dropped */ if( !frames_to_skip && !img->proc_called ) vo_frame_driver_proc(img); /* * put frame into FIFO-Buffer */ lprintf ("frame is ok => appending to display buffer\n"); /* * check for first frame after seek and mark it */ img->is_first = 0; if (first_frame_flag >= 2) { /* We can always do the frame's native stream here. We know its there. */ xine_stream_private_t *m = stream->side_streams[0]; pthread_mutex_lock (&m->first_frame.lock); if (m->first_frame.flag >= 2) { if ((m->first_frame.flag > 2) || this->grab_only) { m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); } else { m->first_frame.flag = 1; } img->is_first = FIRST_FRAME_MAX_POLL; lprintf ("get_next_video_frame first_frame_reached\n"); } pthread_mutex_unlock (&m->first_frame.lock); } /* avoid a complex deadlock situation caused by net_buf_control */ if (!xine_rwlock_tryrdlock (&this->streams_lock)) { xine_stream_private_t **s; for (s = this->streams; *s; s++) { xine_stream_private_t *m; if (*s == stream) continue; m = (*s)->side_streams[0]; /* a little speedup */ if (m->first_frame.flag < 2) continue; pthread_mutex_lock (&m->first_frame.lock); if (m->first_frame.flag >= 2) { if ((m->first_frame.flag > 2) || this->grab_only) { m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); } else { m->first_frame.flag = 1; } img->is_first = FIRST_FRAME_MAX_POLL; lprintf ("get_next_video_frame first_frame_reached\n"); } pthread_mutex_unlock (&m->first_frame.lock); } xine_rwlock_unlock (&this->streams_lock); } if (!img_already_locked) vo_frame_inc2_lock (img); vo_display_reref_append (this, img); if (img->is_first && (this->display_queue.first == img)) { /* wake up render thread */ pthread_mutex_lock (&this->trigger_drawing.mutex); this->trigger_drawing.draw = 1; pthread_cond_signal (&this->trigger_drawing.wake); pthread_mutex_unlock (&this->trigger_drawing.mutex); } } else { lprintf ("bad_frame\n"); if (stream) { xine_stream_private_t *m = stream->side_streams[0]; xine_current_extra_info_set (m, img->extra_info); } this->num_frames_skipped++; } /* * performance measurement */ if (this->num_frames_delivered == 200) { int send_event; xine_stream_private_t **it; /* 100 * n / num_frames_delivered */ if (((this->num_frames_skipped >> 1) > this->warn_skipped_threshold) || ((this->num_frames_discarded >> 1) > this->warn_discarded_threshold)) this->warn_threshold_exceeded++; else this->warn_threshold_exceeded = 0; /* make sure threshold has being consistently exceeded - 5 times in a row * (that is, this is not just a small burst of dropped frames). */ send_event = (this->warn_threshold_exceeded == 5 && !this->warn_threshold_event_sent); this->warn_threshold_event_sent = send_event; xine_rwlock_rdlock (&this->streams_lock); for (it = this->streams; *it; it++) { int skipped, discarded; stream = *it; /* 1000 * n / num_frames_delivered */ skipped = 5 * this->num_frames_skipped; discarded = 5 * this->num_frames_discarded; _x_stream_info_set (&stream->s, XINE_STREAM_INFO_SKIPPED_FRAMES, skipped); _x_stream_info_set (&stream->s, XINE_STREAM_INFO_DISCARDED_FRAMES, discarded); /* we send XINE_EVENT_DROPPED_FRAMES to frontend to warn that * number of skipped or discarded frames is too high. */ if( send_event ) { xine_event_t event; xine_dropped_frames_t data; event.type = XINE_EVENT_DROPPED_FRAMES; event.stream = &stream->s; event.data = &data; event.data_length = sizeof(data); data.skipped_frames = skipped; data.skipped_threshold = this->warn_skipped_threshold * 10; data.discarded_frames = discarded; data.discarded_threshold = this->warn_discarded_threshold * 10; xine_event_send (&stream->s, &event); } } xine_rwlock_unlock (&this->streams_lock); if( this->num_frames_skipped || this->num_frames_discarded ) { xine_log(&this->xine->x, XINE_LOG_MSG, _("%d frames delivered, %d frames skipped, %d frames discarded\n"), 200, this->num_frames_skipped, this->num_frames_discarded); } this->num_frames_delivered = 0; this->num_frames_discarded = 0; this->num_frames_skipped = 0; } return frames_to_skip; } /******************************************************************** * video out loop aka render thread related * *******************************************************************/ #define ADD_READY_FRAMES \ if (this->rp.ready_num < 2) { \ if (!this->rp.ready_num || this->display_queue.first) \ vo_ready_refill (this); \ } static void vo_ready_refill (vos_t *this) { vo_frame_t *first, **add; pthread_mutex_lock (&this->display_queue.mutex); this->rp.min_frame_duration = this->display_queue.min_frame_duration; first = this->display_queue.first; if (!first) { this->display_queue.flush_extra = this->rp.ready_num; pthread_mutex_unlock (&this->display_queue.mutex); return; } add = this->display_queue.add; this->rp.ready_num += this->display_queue.num_buffers; this->display_queue.flush_extra = this->rp.ready_num; this->display_queue.first = NULL; this->display_queue.add = &this->display_queue.first; this->display_queue.num_buffers = 0; pthread_mutex_unlock (&this->display_queue.mutex); *(this->rp.ready_add) = first; this->rp.ready_add = add; } static vo_frame_t *vo_ready_get_all (vos_t *this) { vo_frame_t *first; pthread_mutex_lock (&this->display_queue.mutex); first = this->display_queue.first; if (first) { this->display_queue.first = NULL; this->display_queue.add = &this->display_queue.first; this->display_queue.num_buffers = 0; } this->display_queue.flush_extra = 0; this->rp.need_flush_signal = this->display_queue.num_flush_waiters; this->rp.min_frame_duration = this->display_queue.min_frame_duration; pthread_mutex_unlock (&this->display_queue.mutex); *(this->rp.ready_add) = first; first = this->rp.ready_first; this->rp.ready_first = NULL; this->rp.ready_add = &this->rp.ready_first; this->rp.ready_num = 0; return first; } static vo_frame_t *vo_ready_pop (vos_t *this) { vo_frame_t *img; img = this->rp.ready_first; this->rp.ready_first = img->next; img->next = NULL; if (!this->rp.ready_first) { this->rp.ready_add = &this->rp.ready_first; this->rp.ready_num = 0; } else { this->rp.ready_num--; } return img; } static vo_frame_t *vo_ready_get_dupl (vos_t *this, vo_frame_t *s) { vo_frame_t *img, **add, **fadd = NULL; add = &this->rp.ready_first; while ((img = *add)) { if ((img->lock_counter <= 2) && (img != s)) { if ((img->format == s->format) && (img->width == s->width) && (img->height == s->height) && (img->ratio == s->ratio)) break; if (!fadd) fadd = add; } add = &img->next; } if (!img) { if (!fadd) return NULL; add = fadd; img = *add; } *add = img->next; img->next = NULL; this->rp.ready_num--; if (!*add) { this->rp.ready_add = add; /* just a safety reset */ if (!this->rp.ready_first) this->rp.ready_num = 0; } return img; } /* duplicate_frame(): this function is used to keep playing frames * while video is still or player paused. * * frame allocation inside vo loop is dangerous: * we must never wait for a free frame -> deadlock condition. * to avoid deadlocks we don't use vo_free_queue_get () * but vo_*_get_dupl () instead. */ static vo_frame_t *duplicate_frame (vos_t *this, vo_frame_t *img, int locks) { vo_frame_t *dupl; if (!img) return NULL; dupl = vo_free_get_dupl (this, img); if (!dupl) { /* OK we run out of free frames. Try to whistle back a frame already waiting for display. Search for one that is _not_ a DR1 reference frame that the decoder wants unchanged */ vo_ready_refill (this); dupl = vo_ready_get_dupl (this, img); if (!dupl) return NULL; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": stealing ready frame with input time %d.\n", dupl->extra_info->input_time); } pthread_mutex_lock (&dupl->mutex); dupl->lock_counter = locks; dupl->width = img->width; dupl->height = img->height; dupl->ratio = img->ratio; dupl->format = img->format; dupl->flags = img->flags | VO_BOTH_FIELDS; dupl->progressive_frame = img->progressive_frame; dupl->repeat_first_field = img->repeat_first_field; dupl->top_field_first = img->top_field_first; dupl->crop_left = img->crop_left; dupl->crop_right = img->crop_right; dupl->crop_top = img->crop_top; dupl->crop_bottom = img->crop_bottom; dupl->overlay_offset_x = img->overlay_offset_x; dupl->overlay_offset_y = img->overlay_offset_y; dupl->stream = img->stream; this->driver->update_frame_format (this->driver, dupl, dupl->width, dupl->height, dupl->ratio, dupl->format, dupl->flags); *dupl->extra_info = *img->extra_info; pthread_mutex_unlock (&dupl->mutex); if (img->width && !dupl->width) { /* driver failed to set up render space */ xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("video_out: found an unusable frame (%dx%d, format %0x08x) - no memory??\n"), img->width, img->height, img->format); dupl->lock_counter = 0; vo_free_append (this, dupl); return NULL; } if (dupl->proc_duplicate_frame_data) { dupl->proc_duplicate_frame_data(dupl,img); } else { switch (img->format) { case XINE_IMGFMT_YV12: yv12_to_yv12( /* Y */ img->base[0], img->pitches[0], dupl->base[0], dupl->pitches[0], /* U */ img->base[1], img->pitches[1], dupl->base[1], dupl->pitches[1], /* V */ img->base[2], img->pitches[2], dupl->base[2], dupl->pitches[2], /* width x height */ img->width, img->height); break; case XINE_IMGFMT_YUY2: yuy2_to_yuy2( /* src */ img->base[0], img->pitches[0], /* dst */ dupl->base[0], dupl->pitches[0], /* width x height */ img->width, img->height); break; } } dupl->bad_frame = 0; dupl->pts = 0; dupl->vpts = 0; dupl->proc_called = 0; dupl->duration = img->duration; dupl->is_first = 0; dupl->future_frame = NULL; /* delay frame processing for now, we might not even need it (eg. frame will be discarded) */ /* vo_frame_driver_proc(dupl); */ return dupl; } static void check_redraw_needed (vos_t *this, int64_t vpts) { if (this->overlay_source) { if( this->overlay_source->redraw_needed (this->overlay_source, vpts) ) this->redraw_needed = 1; } /* calling the frontend's frame output hook (via driver->redraw_needed () here) * while flushing (xine_stop ()) may freeze. */ if (!(this->display_queue.discard_frames && (this->rp.ready_first || this->display_queue.first))) { if (this->driver->redraw_needed (this->driver)) this->redraw_needed = 1; } if (this->redraw_needed) { this->rp.poll_time = 40000; /* 25 fps */ this->rp.poll_limit = 42000; /* < 24 fps */ this->rp.poll_num = 200; } else { if (this->rp.poll_num > 0) { if (--this->rp.poll_num == 0) { this->rp.poll_time = 200000; /* 5 fps */ this->rp.poll_limit = 200000; /* 5 fps */ } } } } static vo_frame_t *next_frame (vos_t *this, int64_t *vpts) { vo_frame_t *img; /* when flushing, drop everything now, and return latest "first" frame if any. * FIXME: when switching from movie to logo, somebody briefly flashes VO_PROP_DISCARD_FRAMES. * This kills up to num_frames from the end. For now, just forget the flush there. * That happens here automagically because we come here late ;-) * FIXED: by auto gapless switch. */ if (this->display_queue.discard_frames) { vo_frame_t *keep[2], *freelist = NULL, **add = &freelist; int n = 0, a = 0; keep[0] = NULL; keep[1] = this->rp.last_flushed; /* Take out all at once, but keep decoder blocked for now. */ img = vo_ready_get_all (this); /* Scan for stuff we want to keep. */ while (img) { vo_frame_t *f = keep[(img->is_first <= 0)]; n++; if (f) { if (!vo_frame_dec2_lock_int (this, f)) { *add = f; add = &f->next; a++; } } keep[(img->is_first <= 0)] = img; img = img->next; } this->rp.last_flushed = keep[1]; do { if (!this->rp.last_flushed) break; /* if filler frame might be tied to a flushing hwaccel decoder, * do not stand in the way there. newer vdpau_radeonsi is known to * crash on this. if duplicating the frame should not be enough, * we might need to drop the filler entirely. */ if (this->rp.last_flushed->proc_duplicate_frame_data) { vo_frame_t *dupl = duplicate_frame (this, this->rp.last_flushed, 2); if (!vo_frame_dec2_lock_int (this, this->rp.last_flushed)) { *add = this->rp.last_flushed; add = &this->rp.last_flushed->next; a++; } this->rp.last_flushed = dupl; if (!dupl) break; vo_reref (this, dupl); } this->rp.last_flushed->next = NULL; if (!this->grab.last_frame) { /* rare late setting */ vo_frame_inc_lock (this->rp.last_flushed); pthread_mutex_lock (&this->grab.lock); this->grab.last_frame = this->rp.last_flushed; pthread_mutex_unlock (&this->grab.lock); } } while (0); /* Override with first frame. */ if (keep[0]) { keep[0]->vpts = *vpts; keep[0]->next = NULL; keep[0]->future_frame = NULL; } /* Free (almost) all at once. */ *add = NULL; vo_free_append_list (this, freelist, add, a); /* Make sure clients dont miss this. */ if (this->rp.need_flush_signal) { pthread_mutex_lock (&this->display_queue.mutex); this->num_frames_delivered = 0; this->num_frames_skipped = 0; this->num_frames_discarded = 0; pthread_cond_broadcast (&this->display_queue.done_flushing); pthread_mutex_unlock (&this->display_queue.mutex); } else { this->num_frames_delivered = 0; this->num_frames_skipped = 0; this->num_frames_discarded = 0; } /* Report success. */ if (n) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": flushed out %d frames (now=%"PRId64", discard=%d).\n", n, *vpts, this->display_queue.discard_frames); } /* done */ this->redraw_needed = 0; *vpts = 0; return keep[0]; } ADD_READY_FRAMES; img = this->rp.ready_first; while (img) { if (img->is_first > 0) { #ifdef LOG_FLUSH printf (LOG_MODULE ": first frame pts=%"PRId64", now=%"PRId64", discard=%d\n", img->vpts, *vpts, this->display_queue.discard_frames); #endif /* The user seek brake feature: display first frame after seek right now * (without "metronom prebuffering") if * - it is either no longer referenced by decoder or post layer, or * - it is due for display naturally, or * - we have waited too long for that to happen. * This shall do 3 things: * - User sees the effect of seek soon, and * - We dont decode too many frames in vain when there is a new seek, and * - We dont drop frames already decoded in time. * Finally, dont zero img->is_first so xine_play () gets woken up properly. */ if ((img->lock_counter <= 2) || (img->vpts <= *vpts) || (img->is_first == 1)) { img->vpts = *vpts; *vpts = img->vpts + (img->duration ? img->duration : DEFAULT_FRAME_DURATION); break; } /* poll */ lprintf ("frame still referenced %d times, is_first=%d\n", img->lock_counter, img->is_first); img->is_first--; *vpts += FIRST_FRAME_POLL_DELAY; /* At forward seek, fill the gap with last flushed frame if any. */ if (this->rp.last_flushed && img->pts && this->rp.last_flushed->pts && (this->rp.last_flushed->pts < img->pts)) { img = this->rp.last_flushed; this->rp.last_flushed = NULL; img->vpts = *vpts; *vpts = img->vpts + (img->duration ? img->duration : DEFAULT_FRAME_DURATION); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": showing filler frame @ vpts %" PRId64 ".\n", *vpts); return img; } this->rp.wakeups_early++; return NULL; } { int64_t diff = *vpts - img->vpts, duration; if (diff < 0) { /* still too early for this frame */ *vpts = img->vpts; this->rp.wakeups_early++; return NULL; } duration = img->duration ? img->duration : (img->next ? img->next->vpts - img->vpts : DEFAULT_FRAME_DURATION); if (diff <= duration) { /* frame rate limit */ if (img->vpts >= this->rp.skip_until) { /* update vpts to ensure fluent playback at 1/2, 1/3, etc rate. */ this->rp.skip_until = img->vpts + this->rp.min_frame_duration; /* OK, show this one */ *vpts = img->vpts + duration; break; } /* else silent drop */ } else { /* regular drop */ xine_log (&this->xine->x, XINE_LOG_MSG, _("video_out: throwing away image with pts %" PRId64 " because it's too old (diff : %" PRId64 ").\n"), img->vpts, diff); /* lock to inform decodeer_thread.vo_frame_draw () earlier. */ pthread_mutex_lock (&this->display_queue.mutex); this->num_frames_discarded++; pthread_mutex_unlock (&this->display_queue.mutex); } } img = vo_ready_pop (this); if (img->stream) { xine_stream_private_t *m = (xine_stream_private_t *)img->stream; m = m->side_streams[0]; xine_current_extra_info_set (m, img->extra_info); } ADD_READY_FRAMES; /* last frame? back it up for still frame creation */ if (!this->rp.ready_first) { pthread_mutex_lock (&this->grab.lock); if (this->grab.last_frame) { lprintf ("overwriting frame backup\n"); vo_frame_dec_lock (this->grab.last_frame); } lprintf ("possible still frame (old)\n"); this->grab.last_frame = img; pthread_mutex_unlock (&this->grab.lock); vo_frame_dec_lock (img); /* wait 4 frames before drawing this one. this allow slower systems to recover. */ this->redraw_needed = 4; } else { vo_frame_dec2_lock (this, img); } img = this->rp.ready_first; } if (img) { /* remove frame from display queue and show it */ img->future_frame = img->next; img = vo_ready_pop (this); /* we dont need that filler anymore */ if (this->rp.last_flushed) { vo_frame_dec2_lock (this, this->rp.last_flushed); this->rp.last_flushed = NULL; } return img; } lprintf ("no frame\n"); check_redraw_needed (this, *vpts); *vpts = 0; return NULL; } static void overlay_and_display_frame (vos_t *this, vo_frame_t *img, int64_t vpts, int post_time) { lprintf ("displaying image with vpts = %" PRId64 "\n", img->vpts); /* no, this is not were proc_*() is usually called. * it's just to catch special cases like late or duplicated frames. */ if(!img->proc_called ) vo_frame_driver_proc(img); if (img->stream) { xine_stream_private_t *m = (xine_stream_private_t *)img->stream; m = m->side_streams[0]; /* Post frame time to make frontend relative seek work. */ if (post_time) xine_current_extra_info_set (m, img->extra_info); /* First frame's native stream is the most common case. * Do it without streams lock. */ if (img->is_first > 0) { pthread_mutex_lock (&m->first_frame.lock); if (m->first_frame.flag) { m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); } pthread_mutex_unlock (&m->first_frame.lock); } } /* xine_play() may be called from a thread that has the display device locked * (eg an X window event handler). If it is waiting for a frame we better wake * it up _before_ we start displaying, or the first 10 seconds of video are lost. */ if (img->is_first > 0) { xine_stream_private_t **s; xine_rwlock_rdlock (&this->streams_lock); for (s = this->streams; *s; s++) { xine_stream_private_t *m; if (&(*s)->s == img->stream) continue; m = (*s)->side_streams[0]; pthread_mutex_lock (&m->first_frame.lock); if (m->first_frame.flag) { m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); } pthread_mutex_unlock (&m->first_frame.lock); } xine_rwlock_unlock (&this->streams_lock); /* Dont signal the same frame again. */ img->is_first = -1; } /* calling the frontend's frame output hook (via driver->display_frame () here) * while flushing (xine_stop ()) may freeze. */ if (this->display_queue.discard_frames && (this->rp.ready_first || this->display_queue.first)) { img->free (img); this->redraw_needed = 0; return; } if (this->overlay_source) { this->overlay_source->multiple_overlay_blend (this->overlay_source, vpts, this->driver, img, this->video_loop_running && this->overlay_enabled); } this->driver->display_frame (this->driver, img); this->redraw_needed = 0; } /* special loop for paused mode * needed to update screen due overlay changes, resize, window * movement, brightness adjusting etc. */ static void paused_loop( vos_t *this, int64_t vpts ) { /* prevent decoder thread from allocating too many new frames */ vo_free_queue_read_lock (this); while (this->rp.speed == XINE_SPEED_PAUSE && this->video_loop_running) { ADD_READY_FRAMES; /* set last_frame to play the same frame several times */ if (!this->grab.last_frame) { vo_frame_t *f; f = this->rp.ready_first; if (f) { vo_frame_inc_lock (f); pthread_mutex_lock (&this->grab.lock); this->grab.last_frame = f; pthread_mutex_unlock (&this->grab.lock); this->redraw_needed = 1; } } /* what a terrible HACK. * For single step mode, keep the engine paused all the time, as audio out * seems unable to pause that quickly. Instead, advance manually and nudge * that master clock. After this, audio out will get this message as well. */ do { if (this->trigger_drawing.step) { pthread_mutex_lock (&this->trigger_drawing.mutex); this->rp.speed = this->trigger_drawing.speed; if (this->trigger_drawing.step) { vo_frame_t *f = this->rp.ready_first; if (f) { xine_stream_private_t *m; f = vo_ready_pop (this); f->future_frame = this->rp.ready_first; /* post frame info early. */ m = (xine_stream_private_t *)f->stream; if (m) xine_current_extra_info_set (m->side_streams[0], f->extra_info); this->trigger_drawing.step = 0; pthread_cond_broadcast (&this->trigger_drawing.done_stepping); pthread_mutex_unlock (&this->trigger_drawing.mutex); vpts = f->vpts; this->clock->adjust_clock (this->clock, vpts); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": SINGLE_STEP: vpts %"PRId64".\n", vpts); overlay_and_display_frame (this, f, vpts, 0); vo_grab_current_frame (this, f, vpts); break; } } pthread_mutex_unlock (&this->trigger_drawing.mutex); } /* refresh output */ check_redraw_needed (this, vpts); if (this->redraw_needed) { vo_frame_t *f = duplicate_frame (this, this->grab.last_frame, 1); if (f) { vo_reref (this, f); f->vpts = vpts; overlay_and_display_frame (this, f, vpts, 0); } } } while (0); /* wait for 1/25s or wakeup */ this->rp.now.tv_nsec += this->rp.poll_time * 1000; if (this->rp.now.tv_nsec >= 1000000000) { /* resyncing the pause clock every second should be enough ;-) */ xine_gettime (&this->rp.now); this->rp.now.tv_nsec += this->rp.poll_time * 1000; if (this->rp.now.tv_nsec >= 1000000000) { this->rp.now.tv_sec++; this->rp.now.tv_nsec -= 1000000000; } } pthread_mutex_lock (&this->trigger_drawing.mutex); if (!this->trigger_drawing.draw) { struct timespec ts = this->rp.now; pthread_cond_timedwait (&this->trigger_drawing.wake, &this->trigger_drawing.mutex, &ts); } if (this->trigger_drawing.draw) { this->trigger_drawing.draw = 0; this->redraw_needed = 1; /* no timeout, resync clock */ this->rp.now.tv_nsec = 990000000; } this->rp.speed = this->trigger_drawing.speed; pthread_mutex_unlock (&this->trigger_drawing.mutex); /* flush when requested */ if (this->display_queue.discard_frames) { vo_frame_t *img = vo_ready_get_all (this); vo_list_flush (this, img); if (this->rp.need_flush_signal) { pthread_mutex_lock (&this->display_queue.mutex); pthread_cond_broadcast (&this->display_queue.done_flushing); pthread_mutex_unlock (&this->display_queue.mutex); } } } vo_free_queue_read_unlock (this); } static void video_out_set_warn_skipped_threshold (void *this_gen, xine_cfg_entry_t *entry) { vos_t *this = (vos_t *)this_gen; /* no lock here will merely delay changes a bit. */ this->warn_skipped_threshold = entry->num_value; } static void video_out_set_warn_discarded_threshold (void *this_gen, xine_cfg_entry_t *entry) { vos_t *this = (vos_t *)this_gen; /* no lock here will merely delay changes a bit. */ this->warn_discarded_threshold = entry->num_value; } static void video_out_set_max_frame_rate (void *this_gen, xine_cfg_entry_t *entry) { vos_t *this = (vos_t *)this_gen; pthread_mutex_lock (&this->display_queue.mutex); this->display_queue.max_frame_rate = entry->num_value; vo_update_max_frame_rate (this, this->trigger_drawing.speed); pthread_mutex_unlock (&this->display_queue.mutex); } static void video_out_update_disable_flush_from_video_out(void *this_gen, xine_cfg_entry_t *entry) { vos_t *this = (vos_t *)this_gen; this->disable_decoder_flush_from_video_out = entry->num_value; } static void *video_out_loop (void *this_gen) { vos_t *this = (vos_t *) this_gen; #ifndef WIN32 errno = 0; if (nice(-2) == -1 && errno) xine_log(&this->xine->x, XINE_LOG_MSG, LOG_MODULE ": can't raise nice priority by 2: %s\n", strerror(errno)); #endif /* WIN32 */ this->disable_decoder_flush_from_video_out = this->xine->x.config->register_bool (this->xine->x.config, "engine.decoder.disable_flush_from_video_out", 0, _("disable decoder flush from video out"), _("Video decoder is flushed when it hasn't delivered new frames for quite a while.\n" "Turning this off fixes some temporary image distortion.\n" "But it may also add some issues with DVD still images.\n"), 20, video_out_update_disable_flush_from_video_out, this); /* * here it is - the heart of xine (or rather: one of the hearts * of xine) : the video output loop */ lprintf ("loop starting...\n"); pthread_mutex_lock (&this->trigger_drawing.mutex); this->rp.speed = this->trigger_drawing.speed; pthread_mutex_unlock (&this->trigger_drawing.mutex); while ( this->video_loop_running ) { int64_t vpts, next_frame_vpts; int64_t usec_to_sleep; /* record current time as both speed dependent virtual presentation timestamp (vpts) * and absolute system time, and hope these are halfway in sync. */ vpts = next_frame_vpts = this->clock->get_current_time (this->clock); xine_gettime (&this->rp.now); lprintf ("loop iteration at %" PRId64 "\n", vpts); this->rp.wakeups_total++; { /* find frame to display */ vo_frame_t *img = next_frame (this, &next_frame_vpts); /* if we have found a frame, display it */ if (img) { lprintf ("displaying frame (id=%d)\n", img->id); overlay_and_display_frame (this, img, vpts, 1); vo_grab_current_frame (this, img, vpts); } else if (this->redraw_needed) { if (this->grab.last_frame && (this->redraw_needed == 1)) { lprintf ("generating still frame (vpts = %" PRId64 ") \n", vpts); /* keep playing still frames */ img = duplicate_frame (this, this->grab.last_frame, 1); if (img) { vo_reref (this, img); img->vpts = vpts; overlay_and_display_frame (this, img, vpts, 1); } } else { lprintf ("no frame, but no backup frame\n"); this->redraw_needed--; } } } /* * if we haven't heared from the decoder for some time * flush it * test display fifo empty to protect from deadlocks */ if ((vpts - this->last_delivery_pts > 30000) && !this->display_queue.first && !this->rp.ready_first) { if (this->last_delivery_pts && !this->disable_decoder_flush_from_video_out) { xine_stream_private_t **s; xine_rwlock_rdlock (&this->streams_lock); for (s = this->streams; *s; s++) { if ((*s)->video_decoder_plugin && (*s)->s.video_fifo) { buf_element_t *buf; lprintf ("flushing current video decoder plugin\n"); buf = (*s)->s.video_fifo->buffer_pool_try_alloc ((*s)->s.video_fifo); if (buf) { buf->type = BUF_CONTROL_FLUSH_DECODER; (*s)->s.video_fifo->insert ((*s)->s.video_fifo, buf); } } } xine_rwlock_unlock (&this->streams_lock); } this->last_delivery_pts = vpts; } /* now the time critical stuff is done */ ADD_READY_FRAMES; /* * wait until it's time to display next frame */ lprintf ("next_frame_vpts is %" PRId64 "\n", next_frame_vpts); if ((next_frame_vpts - vpts) > 2 * 90000) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": vpts/clock error, next_vpts=%" PRId64 " cur_vpts=%" PRId64 "\n", next_frame_vpts, vpts); if (this->rp.ready_first && this->rp.ready_first->next) { int64_t d = this->rp.ready_first->next->vpts - vpts; if ((d >= 0) && (d <= 2 * 90000)) { d = (d >> 1) + vpts; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": looks like a missed decoder flush, fixing next_vpts to %" PRId64 ".\n", d); this->rp.ready_first->vpts = d; next_frame_vpts = d; } } } /* get diff time for next iteration */ if (next_frame_vpts && this->rp.speed > 0) usec_to_sleep = (next_frame_vpts - vpts) * 100 * XINE_FINE_SPEED_NORMAL / (9 * this->rp.speed); else /* we don't know when the next frame is due, only wait a little */ usec_to_sleep = this->rp.poll_time; while (this->video_loop_running) { int timedout, wait; if (this->display_queue.discard_frames && (this->rp.ready_first || this->display_queue.first)) break; if (this->rp.speed == XINE_SPEED_PAUSE) { paused_loop (this, vpts); break; } /* limit usec_to_sleep to maintain responsiveness */ wait = usec_to_sleep; if (wait <= 0) break; if (wait > this->rp.poll_limit) wait = this->rp.poll_limit; lprintf ("%d usec to sleep at master vpts %" PRId64 "\n", wait, vpts); /* next stop absolute time */ this->rp.now.tv_nsec += wait * 1000; if (this->rp.now.tv_nsec >= 1000000000) { this->rp.now.tv_sec++; this->rp.now.tv_nsec -= 1000000000; } usec_to_sleep -= wait; timedout = 0; pthread_mutex_lock (&this->trigger_drawing.mutex); if (!this->trigger_drawing.draw) { struct timespec abstime = this->rp.now; timedout = pthread_cond_timedwait (&this->trigger_drawing.wake, &this->trigger_drawing.mutex, &abstime); } this->rp.speed = this->trigger_drawing.speed; this->trigger_drawing.draw = 0; pthread_mutex_unlock (&this->trigger_drawing.mutex); /* honor trigger update only when a backup img is available */ if (!timedout && this->grab.last_frame) break; } } /* * throw away undisplayed frames */ { vo_frame_t *img = vo_ready_get_all (this); vo_list_flush (this, img); } /* dont let folks wait forever in vain */ pthread_mutex_lock (&this->display_queue.mutex); if (this->display_queue.discard_frames) pthread_cond_broadcast (&this->display_queue.done_flushing); pthread_mutex_unlock (&this->display_queue.mutex); pthread_mutex_lock (&this->trigger_drawing.mutex); if (this->trigger_drawing.step) { this->trigger_drawing.step = 0; pthread_cond_broadcast (&this->trigger_drawing.done_stepping); } pthread_mutex_unlock (&this->trigger_drawing.mutex); if (this->rp.last_flushed) { vo_frame_dec2_lock (this, this->rp.last_flushed); this->rp.last_flushed = NULL; } pthread_mutex_lock(&this->grab.lock); if (this->grab.last_frame) { vo_frame_dec_lock( this->grab.last_frame ); this->grab.last_frame = NULL; } pthread_mutex_unlock(&this->grab.lock); this->xine->x.config->unregister_callbacks (this->xine->x.config, NULL, NULL, this, sizeof (*this)); return NULL; } /* * public function for video processing frontends to manually * consume video frames */ int xine_get_next_video_frame (xine_video_port_t *this_gen, xine_video_frame_t *frame) { vos_t *this = (vos_t *)this_gen; vo_frame_t *img; struct timespec now = {0, 990000000}; pthread_mutex_lock (&this->display_queue.mutex); while (!this->display_queue.first) { { xine_stream_private_t *stream = this->streams[0]; if (stream && (stream->s.video_fifo->fifo_size == 0) && (stream->demux.plugin->get_status (stream->demux.plugin) != DEMUX_OK)) { /* no further data can be expected here */ pthread_mutex_unlock (&this->display_queue.mutex); return 0; } } now.tv_nsec += 20000000; if (now.tv_nsec >= 1000000000) { xine_gettime (&now); now.tv_nsec += 20000000; if (now.tv_nsec >= 1000000000) { now.tv_sec++; now.tv_nsec -= 1000000000; } } { struct timespec ts = now; pthread_cond_timedwait (&this->display_queue.not_empty, &this->display_queue.mutex, &ts); } } /* * remove frame from display queue and return it */ img = vo_display_queue_pop_int (this); pthread_mutex_unlock(&this->display_queue.mutex); frame->vpts = img->vpts; frame->duration = img->duration; frame->width = img->width; frame->height = img->height; frame->pos_stream = img->extra_info->input_normpos; frame->pos_time = img->extra_info->input_time; frame->frame_number = img->extra_info->frame_number; frame->aspect_ratio = img->ratio; frame->colorspace = img->format; frame->data = img->base[0]; frame->xine_frame = img; return 1; } void xine_free_video_frame (xine_video_port_t *port, xine_video_frame_t *frame) { vo_frame_t *img = (vo_frame_t *) frame->xine_frame; vos_t *this = (vos_t *)img->port; (void)port; vo_frame_dec2_lock (this, img); } /******************************************************************** * external API * *******************************************************************/ static uint32_t vo_get_capabilities (xine_video_port_t *this_gen) { vos_t *this = (vos_t *) this_gen; return this->driver->get_capabilities (this->driver); } static void vo_open (xine_video_port_t *this_gen, xine_stream_t *stream) { vos_t *this = (vos_t *) this_gen; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": vo_open (%p)\n", (void*)stream); this->video_opened = 1; pthread_mutex_lock (&this->display_queue.mutex); this->display_queue.discard_frames = 0; this->display_queue.flushed = 1; /* see vo_frame_draw () */ pthread_mutex_unlock (&this->display_queue.mutex); this->last_delivery_pts = 0; this->warn_threshold_event_sent = this->warn_threshold_exceeded = 0; if (!this->overlay_enabled && (stream == XINE_ANON_STREAM || stream == NULL || stream->spu_channel_user > -2)) /* enable overlays if our new stream might want to show some */ this->overlay_enabled = 1; vo_streams_register (this, (xine_stream_private_t *)stream); vo_unref_obsolete (this); } static void vo_close (xine_video_port_t *this_gen, xine_stream_t *stream) { vos_t *this = (vos_t *) this_gen; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": vo_close (%p)\n", (void*)stream); /* this will make sure all hide events were processed */ if (this->overlay_source) this->overlay_source->flush_events (this->overlay_source); this->video_opened = 0; /* unregister stream */ vo_streams_unregister (this, (xine_stream_private_t *)stream); } static int vo_get_property (xine_video_port_t *this_gen, int property) { vos_t *this = (vos_t *) this_gen; int ret; switch (property) { case XINE_PARAM_VO_SINGLE_STEP: ret = 0; break; case VO_PROP_DISCARD_FRAMES: ret = this->display_queue.discard_frames; break; case VO_PROP_BUFS_IN_FIFO: ret = this->video_loop_running ? this->display_queue.num_buffers + this->rp.ready_num : -1; break; case VO_PROP_BUFS_FREE: ret = this->video_loop_running ? this->free_queue.num_buffers : -1; break; case VO_PROP_BUFS_TOTAL: ret = this->video_loop_running ? this->free_queue.num_buffers_max : -1; break; case VO_PROP_NUM_STREAMS: xine_rwlock_rdlock (&this->streams_lock); ret = this->num_null_streams + this->num_anon_streams + this->num_streams; xine_rwlock_unlock (&this->streams_lock); break; /* * handle XINE_PARAM_xxx properties (convert from driver's range) */ case XINE_PARAM_VO_CROP_LEFT: ret = this->crop_left; break; case XINE_PARAM_VO_CROP_RIGHT: ret = this->crop_right; break; case XINE_PARAM_VO_CROP_TOP: ret = this->crop_top; break; case XINE_PARAM_VO_CROP_BOTTOM: ret = this->crop_bottom; break; case XINE_PARAM_VO_SHARPNESS: case XINE_PARAM_VO_NOISE_REDUCTION: case XINE_PARAM_VO_HUE: case XINE_PARAM_VO_SATURATION: case XINE_PARAM_VO_CONTRAST: case XINE_PARAM_VO_BRIGHTNESS: case XINE_PARAM_VO_GAMMA: { int v, min_v = 0, max_v = 0xffff, range_v; pthread_mutex_lock (&this->driver_lock); this->driver->get_property_min_max (this->driver, property & 0xffffff, &min_v, &max_v); v = this->driver->get_property (this->driver, property & 0xffffff); pthread_mutex_unlock (&this->driver_lock); range_v = max_v - min_v; if (range_v > 0) ret = ((v - min_v) * 0xffff + (range_v >> 1)) / range_v; else ret = 0; } break; default: pthread_mutex_lock( &this->driver_lock ); ret = this->driver->get_property(this->driver, property & 0xffffff); pthread_mutex_unlock( &this->driver_lock ); } return ret; } static int vo_set_property (xine_video_port_t *this_gen, int property, int value) { vos_t *this = (vos_t *) this_gen; int ret; switch (property) { case XINE_PARAM_VO_SINGLE_STEP: ret = !!value; if (this->grab_only) break; /* xine_set_param () will (un)pause for us here to avoid ticket freeze. */ pthread_mutex_lock (&this->trigger_drawing.mutex); this->trigger_drawing.step = ret; this->trigger_drawing.draw = 0; pthread_cond_signal (&this->trigger_drawing.wake); if (ret) { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_nsec += 500000000; if (ts.tv_nsec >= 1000000000) { ts.tv_sec++; ts.tv_nsec -= 1000000000; } if (pthread_cond_timedwait (&this->trigger_drawing.done_stepping, &this->trigger_drawing.mutex, &ts)) ret = 0; } pthread_mutex_unlock (&this->trigger_drawing.mutex); break; case VO_PROP_DISCARD_FRAMES: /* recursive discard frames setting */ if (value) { pthread_mutex_lock (&this->display_queue.mutex); this->display_queue.discard_frames++; ret = this->display_queue.discard_frames; if (this->grab_only) { /* discard buffers here because we have no output thread. */ vo_manual_flush (this); pthread_mutex_unlock (&this->display_queue.mutex); } else { pthread_mutex_unlock (&this->display_queue.mutex); if (ret == 1) { /* render thread will grab this mutex after each frame. * taking it here triggers a data cache sync, and makes it see discard_frames early. */ pthread_mutex_lock (&this->trigger_drawing.mutex); this->trigger_drawing.draw = 1; pthread_cond_signal (&this->trigger_drawing.wake); pthread_mutex_unlock (&this->trigger_drawing.mutex); } } } else { pthread_mutex_lock (&this->display_queue.mutex); if (this->display_queue.discard_frames) { if (this->display_queue.discard_frames == 1) { if (this->video_loop_running && (this->display_queue.flush_extra || this->display_queue.first)) { /* Usually, render thread already did that in the meantime. Anyway, make sure display queue is empty, and more importantly, there are free frames for decoding when discard gets lifted. */ vo_wait_flush (this); } this->display_queue.flushed = 1; } this->display_queue.discard_frames--; ret = this->display_queue.discard_frames; pthread_mutex_unlock (&this->display_queue.mutex); } else { pthread_mutex_unlock (&this->display_queue.mutex); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "vo_set_property: discard_frames is already zero\n"); ret = 0; } } break; /* * handle XINE_PARAM_xxx properties (convert to driver's range) */ case XINE_PARAM_VO_CROP_LEFT: if( value < 0 ) value = 0; ret = this->crop_left = value; break; case XINE_PARAM_VO_CROP_RIGHT: if( value < 0 ) value = 0; ret = this->crop_right = value; break; case XINE_PARAM_VO_CROP_TOP: if( value < 0 ) value = 0; ret = this->crop_top = value; break; case XINE_PARAM_VO_CROP_BOTTOM: if( value < 0 ) value = 0; ret = this->crop_bottom = value; break; case XINE_PARAM_VO_SHARPNESS: case XINE_PARAM_VO_NOISE_REDUCTION: case XINE_PARAM_VO_HUE: case XINE_PARAM_VO_SATURATION: case XINE_PARAM_VO_CONTRAST: case XINE_PARAM_VO_BRIGHTNESS: case XINE_PARAM_VO_GAMMA: if (!this->grab_only) { int v, min_v = 0, max_v = 0xffff, range_v; pthread_mutex_lock (&this->driver_lock); this->driver->get_property_min_max (this->driver, property & 0xffffff, &min_v, &max_v); range_v = max_v - min_v; v = (value * range_v + 0x7fff) / 0xffff + min_v; this->driver->set_property (this->driver, property & 0xffffff, v); pthread_mutex_unlock (&this->driver_lock); ret = value; } else ret = 0; break; default: if (!this->grab_only) { pthread_mutex_lock( &this->driver_lock ); ret = this->driver->set_property(this->driver, property & 0xffffff, value); pthread_mutex_unlock( &this->driver_lock ); } else ret = 0; } return ret; } static int vo_status (xine_video_port_t *this_gen, xine_stream_t *s, int *width, int *height, int64_t *img_duration) { vos_t *this = (vos_t *) this_gen; xine_stream_private_t *stream = (xine_stream_private_t *)s; if (!stream || (&stream->s == XINE_ANON_STREAM)) { *width = this->current_width; *height = this->current_height; *img_duration = this->current_duration; return 0; } xine_rwlock_rdlock (&this->streams_lock); { xine_stream_private_t **s; for (s = this->streams; *s; s++) { if (*s == stream) { *width = this->current_width; *height = this->current_height; *img_duration = this->current_duration; xine_rwlock_unlock (&this->streams_lock); return 1; } } } xine_rwlock_unlock(&this->streams_lock); return 0; } static void vo_speed_change_cb (void *this_gen, int new_speed) { vos_t *this = this_gen; pthread_mutex_lock (&this->trigger_drawing.mutex); /* something to do? */ if (new_speed == this->trigger_drawing.speed) { pthread_mutex_unlock (&this->trigger_drawing.mutex); return; } /* bother render thread when (un)pauseing, or when increasing speed significantly * (display next frame earlier). */ if ((new_speed <= 0) || (this->trigger_drawing.speed <= 0) || (new_speed > this->trigger_drawing.speed + XINE_FINE_SPEED_NORMAL / 20)) { this->trigger_drawing.draw = 1; pthread_cond_signal (&this->trigger_drawing.wake); } this->trigger_drawing.speed = new_speed; pthread_mutex_unlock (&this->trigger_drawing.mutex); pthread_mutex_lock (&this->display_queue.mutex); vo_update_max_frame_rate (this, new_speed); pthread_mutex_unlock (&this->display_queue.mutex); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": new speed %d.\n", new_speed); } static void vo_exit (xine_video_port_t *this_gen) { vos_t *this = (vos_t *) this_gen; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": exit.\n"); this->xine->port_ticket->revoke_cb_unregister (this->xine->port_ticket, vo_ticket_revoked, this); if (this->video_loop_running) { void *p; this->clock->unregister_speed_change_callback (this->clock, vo_speed_change_cb, this); /* make render thread see that early. */ pthread_mutex_lock (&this->trigger_drawing.mutex); this->video_loop_running = 0; this->trigger_drawing.draw = 1; pthread_cond_signal (&this->trigger_drawing.wake); pthread_mutex_unlock (&this->trigger_drawing.mutex); pthread_join (this->video_thread, &p); } { int n = this->driver->set_property (this->driver, VO_PROP_DISCARD_FRAMES, -1); if (n > 0) xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": returned %d held frames from driver.\n", n); } { vo_frame_t *list = vo_free_queue_get_all (this), *img; vo_unref_list (this, list); for (img = list; img; img = img->next) { int i; for (i = 0; i < this->frames_total; i++) { if (this->display_queue.frames[i] == img) { this->display_queue.frames[i] = NULL; break; } } } vo_dispose_list (list); } { int i; for (i = 0; i < this->frames_total; i++) { if (this->display_queue.frames[i]) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": BUG: frame #%d (%p) still in use (%d refs).\n", i, (void*)this->display_queue.frames[i], this->display_queue.frames[i]->lock_counter); } } } vo_dispose_list (vo_display_queue_get_all (this)); /* print frame usage stats */ xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("video_out: max frames used: %d of %d\n"), this->frames_peak_used, this->frames_total); xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("video_out: early wakeups: %d of %d\n"), this->rp.wakeups_early, this->rp.wakeups_total); _x_free_video_driver(&this->xine->x, &this->driver); xine_freep_aligned (&this->display_queue.frames); if (this->overlay_source) { this->overlay_source->dispose (this->overlay_source); } vo_streams_close (this); vo_free_queue_close (this); vo_display_queue_close (this); pthread_cond_destroy (&this->trigger_drawing.done_stepping); pthread_cond_destroy (&this->trigger_drawing.wake); pthread_mutex_destroy (&this->trigger_drawing.mutex); pthread_mutex_destroy (&this->driver_lock); pthread_mutex_destroy(&this->grab.lock); pthread_cond_destroy(&this->grab.wake); lprintf ("vo_exit... done\n"); free (this); } static vo_frame_t *vo_get_last_frame (xine_video_port_t *this_gen) { vos_t *this = (vos_t *) this_gen; vo_frame_t *last_frame; pthread_mutex_lock(&this->grab.lock); last_frame = this->grab.last_frame; if (last_frame) vo_frame_inc_lock(last_frame); pthread_mutex_unlock(&this->grab.lock); return last_frame; } /* overlay stuff */ static video_overlay_manager_t *vo_get_overlay_manager (xine_video_port_t *this_gen) { vos_t *this = (vos_t *) this_gen; return this->overlay_source; } static void vo_enable_overlay (xine_video_port_t *this_gen, int overlay_enabled) { vos_t *this = (vos_t *) this_gen; if (overlay_enabled) { /* we always ENable ... */ this->overlay_enabled = 1; } else { /* ... but we only actually DISable, if all associated streams have SPU off */ xine_stream_private_t **s; xine_rwlock_rdlock (&this->streams_lock); if (this->num_anon_streams > 0) { xine_rwlock_unlock (&this->streams_lock); return; } for (s = this->streams; *s; s++) { if ((*s)->s.spu_channel_user > -2) { xine_rwlock_unlock (&this->streams_lock); return; } } xine_rwlock_unlock (&this->streams_lock); this->overlay_enabled = 0; } } /* * Flush video_out fifo */ static void vo_flush (xine_video_port_t *this_gen) { vos_t *this = (vos_t *) this_gen; if (this->video_loop_running) { pthread_mutex_lock (&this->display_queue.mutex); this->display_queue.discard_frames++; vo_wait_flush (this); if (this->display_queue.discard_frames > 0) this->display_queue.discard_frames--; pthread_mutex_unlock (&this->display_queue.mutex); } else { vo_manual_flush (this); } } static void vo_trigger_drawing (xine_video_port_t *this_gen) { vos_t *this = (vos_t *) this_gen; pthread_mutex_lock (&this->trigger_drawing.mutex); this->trigger_drawing.draw = 1; pthread_cond_signal (&this->trigger_drawing.wake); pthread_mutex_unlock (&this->trigger_drawing.mutex); } xine_video_port_t *_x_vo_new_port (xine_t *xine, vo_driver_t *driver, int grabonly) { vos_t *this; int num_frame_buffers; this = calloc(1, sizeof(vos_t)) ; if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ this->num_frames_delivered = 0; this->num_frames_skipped = 0; this->num_frames_discarded = 0; this->grab_only = 0; this->video_opened = 0; this->video_loop_running = 0; this->trigger_drawing.draw = 0; this->trigger_drawing.step = 0; this->grab.last_frame = NULL; this->grab.request = NULL; this->frames_extref = 0; this->frames_peak_used = 0; this->frame_drop_cpt = 0; this->frame_drop_suggested = 0; this->rp.ready_first = NULL; this->rp.ready_num = 0; this->rp.need_flush_signal = 0; this->rp.last_flushed = NULL; # ifdef ADD_KEYFRAME_INDEX this->keyframe_mode = 0; # endif #endif this->xine = (xine_private_t *)xine; this->clock = xine->clock; this->driver = driver; this->display_queue.flushed = 1; this->vo.open = vo_open; this->vo.get_frame = vo_get_frame; this->vo.get_last_frame = vo_get_last_frame; this->vo.new_grab_video_frame = vo_new_grab_video_frame; this->vo.close = vo_close; this->vo.exit = vo_exit; this->vo.get_capabilities = vo_get_capabilities; this->vo.enable_ovl = vo_enable_overlay; this->vo.get_overlay_manager = vo_get_overlay_manager; this->vo.flush = vo_flush; this->vo.trigger_drawing = vo_trigger_drawing; this->vo.get_property = vo_get_property; this->vo.set_property = vo_set_property; this->vo.status = vo_status; this->vo.driver = driver; /* 24/25/30 fps are most common, do these in a single wait. */ this->rp.poll_time = 40000; this->rp.poll_limit = 42000; this->rp.poll_num = 200; /* default number of video frames from config */ num_frame_buffers = xine->config->register_num (xine->config, "engine.buffers.video_num_frames", NUM_FRAME_BUFFERS, /* default */ _("default number of video frames"), _("The default number of video frames to request " "from xine video out driver. Some drivers will " "override this setting with their own values."), 20, NULL, NULL); /* check driver's limit and use the smaller value */ { int i = driver->get_property (driver, VO_PROP_MAX_NUM_FRAMES); if (i && i < num_frame_buffers) num_frame_buffers = i; } /* we need at least 5 frames */ if (num_frame_buffers<5) num_frame_buffers = 5; /* init frame usage stats */ this->frames_total = num_frame_buffers; /* Choose a frame_drop_limit which matches num_frame_buffers. * xxmc for example supplies only 8 buffers. 2 are occupied by * MPEG2 decoding, further 2 for displaying and the remaining 4 can * hardly be filled all the time. * The below constants reserve buffers for decoding, displaying and * buffer fluctuation. * A frame_drop_limit_max below 1 will disable frame drops at all. */ this->frame_drop_limit_max = num_frame_buffers - 2 - 2 - 1; if (this->frame_drop_limit_max < 1) this->frame_drop_limit_max = 1; else if (this->frame_drop_limit_max > 3) this->frame_drop_limit_max = 3; this->frame_drop_limit = this->frame_drop_limit_max; /* get some extra mem */ { uint8_t *m = xine_mallocz_aligned (num_frame_buffers * (2 * sizeof (void *) + sizeof (extra_info_t)) + 32); if (!m) { free (this); return NULL; } this->display_queue.frames = (vo_frame_t **)m; m += num_frame_buffers * sizeof (void *); this->display_queue.img_streams = (xine_stream_private_t **)m; m += num_frame_buffers * sizeof (void *) + 31; m = (uint8_t *)((uintptr_t)m & ~(uintptr_t)31); this->extra_info_base = (extra_info_t *)m; } this->overlay_source = _x_video_overlay_new_manager (xine); if (this->overlay_source) { this->overlay_source->init (this->overlay_source); this->overlay_enabled = 1; } pthread_mutex_init (&this->trigger_drawing.mutex, NULL); pthread_cond_init (&this->trigger_drawing.wake, NULL); pthread_cond_init (&this->trigger_drawing.done_stepping, NULL); pthread_mutex_init (&this->driver_lock, NULL); pthread_mutex_init (&this->grab.lock, NULL); pthread_cond_init (&this->grab.wake, NULL); vo_streams_open (this); vo_free_queue_open (this); vo_display_queue_open (this); this->rp.ready_add = &this->rp.ready_first; /* nobody is listening yet, omit locking and signalling */ { vo_frame_t **add = &this->free_queue.first; int i; for (i = 0; i < num_frame_buffers; i++) { vo_frame_t *img = driver->alloc_frame (driver); if (!img) break; img->proc_duplicate_frame_data = NULL; img->id = i; img->port = &this->vo; img->free = vo_frame_dec_lock; img->lock = vo_frame_inc_lock; img->draw = vo_frame_draw; img->extra_info = &this->extra_info_base[i]; this->display_queue.frames[i] = img; this->display_queue.img_streams[i] = NULL; *add = img; add = &img->next; } *add = NULL; this->free_queue.add = add; this->free_queue.num_buffers = this->free_queue.num_buffers_max = i; } this->xine->port_ticket->revoke_cb_register (this->xine->port_ticket, vo_ticket_revoked, this); this->display_queue.max_frame_rate = xine->config->register_num (xine->config, "video.output.max_frame_rate", 0, _("Limit output frame rate"), _("If not 0, limit output frame rate to this value, without extra jitter.\n" "Try 40 to save power, and/or to deal with a slow driver.\n" "Otherwise, current screen refresh rate plus 5 may be a good idea ;-)\n"), 20, video_out_set_max_frame_rate, this); this->warn_skipped_threshold = xine->config->register_num (xine->config, "engine.performance.warn_skipped_threshold", 10, _("percentage of skipped frames to tolerate"), _("When more than this percentage of frames are not shown, because they " "were not decoded in time, xine sends a notification."), 20, video_out_set_warn_skipped_threshold, this); this->warn_discarded_threshold = xine->config->register_num (xine->config, "engine.performance.warn_discarded_threshold", 10, _("percentage of discarded frames to tolerate"), _("When more than this percentage of frames are not shown, because they " "were not scheduled for display in time, xine sends a notification."), 20, video_out_set_warn_discarded_threshold, this); if (grabonly) { this->grab_only = 1; } else { pthread_attr_t pth_attrs; int err; /* * start video output thread * * this thread will alwys be running, displaying the * logo when "idle" thus making it possible to have * osd when not playing a stream */ this->video_loop_running = 1; /* render thread needs no display queue signals */ this->display_queue.locked_for_read = 1000; pthread_attr_init(&pth_attrs); #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0) pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM); #endif err = pthread_create (&this->video_thread, &pth_attrs, video_out_loop, this); pthread_attr_destroy(&pth_attrs); if (err != 0) { xprintf (&this->xine->x, XINE_VERBOSITY_NONE, LOG_MODULE ": can't create thread (%s)\n", strerror(err)); /* FIXME: how does this happen ? */ xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("video_out: sorry, this should not happen. please restart xine.\n")); this->video_loop_running = 0; this->vo.exit(&this->vo); return NULL; } this->clock->register_speed_change_callback (this->clock, vo_speed_change_cb, this); this->trigger_drawing.speed = this->clock->speed; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": thread created\n"); } vo_update_max_frame_rate (this, this->trigger_drawing.speed); return &this->vo; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/osd.c������������������������������������������������������������������0000644�0001750�0001750�00000173266�14647725152�014631� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * OSD stuff (text and graphic primitives) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdlib.h> #include <string.h> #include <stdio.h> #include <pthread.h> #include <zlib.h> #include <sys/types.h> #ifdef HAVE_DIRENT_H #include <dirent.h> #endif #include <errno.h> #ifdef HAVE_ICONV # include <iconv.h> #endif #include <basedir.h> #define LOG_MODULE "osd" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include "xine-engine/bswap.h" #include <xine/xineutils.h> #include <xine/video_out.h> #include <xine/osd.h> #include "xine_private.h" #ifdef HAVE_FT2 #include <ft2build.h> #include FT_FREETYPE_H # ifdef HAVE_FONTCONFIG # include <fontconfig/fontconfig.h> # endif #endif #define FONT_VERSION 2 /* unicode value of alias character, * used if conversion fails */ #define ALIAS_CHARACTER_CONV '#' /* unicode value of alias character, * used if character isn't in the font */ #define ALIAS_CHARACTER_FONT '_' /* we want UCS-2 encoding in the machine endian */ #ifdef WORDS_BIGENDIAN # define UCS2_ENCODING "UCS-2BE" #else # define UCS2_ENCODING "UCS-2LE" #endif #if (FREETYPE_MAJOR > 2) || \ (FREETYPE_MAJOR == 2 && FREETYPE_MINOR > 1) || \ (FREETYPE_MAJOR == 2 && FREETYPE_MINOR == 1 && FREETYPE_PATCH >= 3) # define KERNING_DEFAULT FT_KERNING_DEFAULT #else # define KERNING_DEFAULT ft_kerning_default #endif #ifdef ENABLE_ANTIALIASING # define FT_LOAD_FLAGS FT_LOAD_DEFAULT #else # define FT_LOAD_FLAGS (FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING) #endif #define CLIP0MAX(val,max) { int32_t _v = val; if (_v > (int32_t)(max)) _v = max; _v &= ~(_v >> 31); val = _v; } typedef struct { osd_renderer_t r; vo_overlay_t ovl; xine_t *xine; } osd_renderer_private_t; /* This text descriptions are used for config screen */ static const char *const textpalettes_str[NUMBER_OF_TEXT_PALETTES+1] = { "white-black-transparent", "white-none-transparent", "white-none-translucid", "yellow-black-transparent", NULL}; /* Palette entries as used by osd fonts: 0: not used by font, always transparent 1: font background, usually transparent, may be used to implement translucid boxes where the font will be printed. 2-5: transition between background and border (usually only alpha value changes). 6: font border. if the font is to be displayed without border this will probably be adjusted to font background or near. 7-9: transition between border and foreground 10: font color (foreground) */ /* The palettes below were made by hand, ie, i just throw values that seemed to do the transitions i wanted. This can surelly be improved a lot. [Miguel] */ static const clut_t textpalettes_color[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { /* white, black border, transparent */ { CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ CLUT_Y_CR_CB_INIT(0x40, 0x80, 0x80), /*7*/ CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*8*/ CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*9*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ }, /* white, no border, transparent */ { CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*1*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*2*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*3*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*4*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*5*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*6*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*7*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*8*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*9*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ }, /* white, no border, translucid */ { CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*1*/ CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*2*/ CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*3*/ CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*4*/ CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*5*/ CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), /*6*/ CLUT_Y_CR_CB_INIT(0xa0, 0x80, 0x80), /*7*/ CLUT_Y_CR_CB_INIT(0xc0, 0x80, 0x80), /*8*/ CLUT_Y_CR_CB_INIT(0xe0, 0x80, 0x80), /*9*/ CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80), /*10*/ }, /* yellow, black border, transparent */ { CLUT_Y_CR_CB_INIT(0x00, 0x00, 0x00), /*0*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*1*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*2*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*3*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*4*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*5*/ CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), /*6*/ CLUT_Y_CR_CB_INIT(0x40, 0x84, 0x60), /*7*/ CLUT_Y_CR_CB_INIT(0x70, 0x88, 0x40), /*8*/ CLUT_Y_CR_CB_INIT(0xb0, 0x8a, 0x20), /*9*/ CLUT_Y_CR_CB_INIT(0xff, 0x90, 0x00), /*10*/ }, }; static const uint8_t textpalettes_trans[NUMBER_OF_TEXT_PALETTES][TEXT_PALETTE_SIZE] = { {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, {0, 0, 0, 0, 0, 0, 2, 6, 9, 12, 15 }, {0, 8, 9, 10, 11, 12, 13, 14, 15, 15, 15 }, {0, 0, 3, 6, 8, 10, 12, 14, 15, 15, 15 }, }; typedef struct osd_fontchar_s { uint8_t *bmp; uint16_t code; uint16_t width; uint16_t height; } osd_fontchar_t; struct osd_font_s { char name[40]; char *filename; osd_fontchar_t *fontchar; uint8_t *data; osd_font_t *next; uint16_t version; uint16_t size; uint16_t num_fontchars; uint16_t loaded; }; #ifdef HAVE_FT2 struct osd_ft2context_s { FT_Library library; FT_Face face; int size; }; static void osd_free_ft2 (osd_object_t *osd) { if( osd->ft2 ) { if ( osd->ft2->face ) FT_Done_Face (osd->ft2->face); if ( osd->ft2->library ) FT_Done_FreeType(osd->ft2->library); _x_freep( &osd->ft2 ); } } #else static inline void osd_free_ft2 (osd_object_t *osd __attr_unused) {} #endif /* * open a new osd object. this will allocated an empty (all zero) drawing * area where graphic primitives may be used. * It is ok to specify big width and height values. The render will keep * track of the smallest changed area to not generate too big overlays. * A default palette is initialized (i sugest keeping color 0 as transparent * for the sake of simplicity) */ static osd_object_t *osd_new_object (osd_renderer_t *this, int width, int height) { osd_object_t *osd; osd = calloc(1, sizeof(osd_object_t)); if (!osd) return NULL; #ifndef HAVE_ZERO_SAFE_MEM osd->video_window_x = 0; osd->video_window_y = 0; osd->video_window_width = 0; osd->video_window_height = 0; osd->extent_width = 0; osd->extent_height = 0; osd->area_touched = 0; osd->x2 = 0; osd->y2 = 0; #endif osd->area = calloc(width, height); if (!osd->area) { free (osd); return NULL; } osd->renderer = this; osd->width = width; osd->height = height; osd->x1 = width; osd->y1 = height; memcpy(osd->color, textpalettes_color[0], sizeof(textpalettes_color[0])); memcpy(osd->trans, textpalettes_trans[0], sizeof(textpalettes_trans[0])); osd->handle = -1; #ifdef HAVE_ICONV osd->cd = (iconv_t)-1; osd->encoding = NULL; #endif /* append to renderer list */ pthread_mutex_lock (&this->osd_mutex); osd->next = this->osds; this->osds = osd; pthread_mutex_unlock (&this->osd_mutex); lprintf("osd=%p size: %dx%d\n", (void*)osd, width, height); return osd; } /* * osd extent must be set to achive video resolution independent osds * both sizes must be > 0 to take effect. otherwise, video resolution * will still be used. the extent defines the reference coordinate * system which is matched to the video output area. */ static void osd_set_extent (osd_object_t *osd, int extent_width, int extent_height) { osd->extent_width = extent_width; osd->extent_height = extent_height; } /* * osd video window defines an area withing osd extent where the * video shall be scaled to while an osd is displayed on screen. * both width and height must be > 0 to take effect. */ static void osd_set_video_window (osd_object_t *osd, int window_x, int window_y, int window_width, int window_height) { osd->video_window_x = window_x; osd->video_window_y = window_y; osd->video_window_width = window_width; osd->video_window_height = window_height; } static argb_layer_t *argb_layer_create() { argb_layer_t *argb_layer; argb_layer = calloc(1, sizeof (argb_layer_t)); if (!argb_layer) return NULL; pthread_mutex_init(&argb_layer->mutex, NULL); return argb_layer; } static void argb_layer_destroy(argb_layer_t *argb_layer) { pthread_mutex_destroy(&argb_layer->mutex); free(argb_layer); } void set_argb_layer_ptr(argb_layer_t **dst, argb_layer_t *src) { if (src) { pthread_mutex_lock(&src->mutex); ++src->ref_count; pthread_mutex_unlock(&src->mutex); } if (*dst) { int free_argb_layer; pthread_mutex_lock(&(*dst)->mutex); free_argb_layer = (0 == --(*dst)->ref_count); pthread_mutex_unlock(&(*dst)->mutex); if (free_argb_layer) argb_layer_destroy(*dst); } *dst = src; } /* #define DEBUG_RLE */ static int _osd_hide (osd_object_t *osd, int64_t vpts); /* * send the osd to be displayed at given pts (0=now) * the object is not changed. there may be subsequent drawing on it. */ static int _osd_show (osd_object_t *osd, int64_t vpts, int unscaled ) { osd_renderer_t *this = osd->renderer; xine_private_t *xine = (xine_private_t *)this->stream->xine; video_overlay_manager_t *ovl_manager; rle_elem_t rle, *rle_p=0; int x, y; uint8_t *c; lprintf("osd=%p vpts=%"PRId64"\n", (void*)osd, vpts); xine->port_ticket->acquire (xine->port_ticket, 1); ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out); if( osd->handle < 0 ) { if( (osd->handle = ovl_manager->get_handle(ovl_manager, 0)) == -1 ) { xine->port_ticket->release (xine->port_ticket, 1); return 0; } } pthread_mutex_lock (&this->osd_mutex); /* clip update area to allowed range */ CLIP0MAX (osd->x1, osd->width); CLIP0MAX (osd->x2, osd->width); CLIP0MAX (osd->y1, osd->height); CLIP0MAX (osd->y2, osd->height); #if 0 /* --- test --- test --- */ this->line (osd, osd->x2 - 1, osd->y1, osd->x2 - 1, osd->y2 - 2, 7); this->line (osd, osd->x2 - 1, osd->y2 - 1, osd->y1 + 1, osd->y2 - 1, 7); this->line (osd, osd->x1, osd->y2 - 1, osd->x1, osd->y1 + 1, 7); this->line (osd, osd->x1, osd->y1, osd->x2 - 2, osd->y1, 7); this->line (osd, 0, 0, osd->width, osd->height, 21); this->line (osd, 0, osd->height, osd->width, 0, 21); this->line (osd, -10, osd->height >> 1, osd->width >> 1, osd->height + 10, 21); this->line (osd, osd->width + 10, osd->height >> 1, osd->width >> 1, osd->height + 10, 21); #endif #ifdef DEBUG_RLE lprintf("osd_show %p rle starts\n", (void*)osd); #endif /* check if osd is valid (something drawn on it) */ if( osd->x2 > osd->x1 && osd->y2 > osd->y1 ) { this->event.object.handle = osd->handle; memset( this->event.object.overlay, 0, sizeof(*this->event.object.overlay) ); set_argb_layer_ptr(&this->event.object.overlay->argb_layer, osd->argb_layer); this->event.object.overlay->unscaled = unscaled; this->event.object.overlay->x = osd->display_x + osd->x1; this->event.object.overlay->y = osd->display_y + osd->y1; this->event.object.overlay->width = osd->x2 - osd->x1; this->event.object.overlay->height = osd->y2 - osd->y1; this->event.object.overlay->video_window_x = osd->video_window_x; this->event.object.overlay->video_window_y = osd->video_window_y; this->event.object.overlay->video_window_width = osd->video_window_width; this->event.object.overlay->video_window_height = osd->video_window_height; this->event.object.overlay->extent_width = osd->extent_width; this->event.object.overlay->extent_height = osd->extent_height; this->event.object.overlay->hili_top = 0; this->event.object.overlay->hili_bottom = this->event.object.overlay->height; this->event.object.overlay->hili_left = 0; this->event.object.overlay->hili_right = this->event.object.overlay->width; /* there will be at least that many rle objects (one for each row) */ this->event.object.overlay->num_rle = 0; if (!osd->area_touched) { /* avoid rle encoding when only argb_layer is modified */ this->event.object.overlay->data_size = 0; rle_p = this->event.object.overlay->rle = NULL; } else { /* We will never need more rle objects than columns in any row Rely on lazy page allocation to avoid us actually taking up this much RAM */ this->event.object.overlay->data_size = osd->width * osd->height; rle_p = this->event.object.overlay->rle = malloc(this->event.object.overlay->data_size * sizeof(rle_elem_t) ); for( y = osd->y1; y < osd->y2; y++ ) { #ifdef DEBUG_RLE lprintf("osd_show %p y = %d: ", (void*)osd, y); #endif c = osd->area + y * osd->width + osd->x1; /* initialize a rle object with the first pixel's color */ rle.len = 1; rle.color = *c++; /* loop over the remaining pixels in the row */ for( x = osd->x1 + rle.len; x < osd->x2; x++, c++ ) { if( rle.color != *c ) { #ifdef DEBUG_RLE lprintf("(%d, %d), ", rle.len, rle.color); #endif *rle_p++ = rle; this->event.object.overlay->num_rle++; rle.color = *c; rle.len = 1; } else { rle.len++; } } #ifdef DEBUG_RLE lprintf("(%d, %d)\n", rle.len, rle.color); #endif *rle_p++ = rle; this->event.object.overlay->num_rle++; } #ifdef DEBUG_RLE lprintf("osd_show %p rle ends\n", (void*)osd); #endif lprintf("num_rle = %d\n", this->event.object.overlay->num_rle); memcpy(this->event.object.overlay->hili_color, osd->color, sizeof(osd->color)); memcpy(this->event.object.overlay->hili_trans, osd->trans, sizeof(osd->trans)); memcpy(this->event.object.overlay->color, osd->color, sizeof(osd->color)); memcpy(this->event.object.overlay->trans, osd->trans, sizeof(osd->trans)); } this->event.event_type = OVERLAY_EVENT_SHOW; this->event.vpts = vpts; ovl_manager->add_event(ovl_manager, (void *)&this->event); set_argb_layer_ptr(&this->event.object.overlay->argb_layer, NULL); } else { /* osd empty - hide it */ _osd_hide(osd, vpts); } pthread_mutex_unlock (&this->osd_mutex); xine->port_ticket->release (xine->port_ticket, 1); return 1; } /* normal OSD show * overlay is blended and scaled together with the stream. */ static int osd_show_scaled (osd_object_t *osd, int64_t vpts) { return _osd_show(osd, vpts, 0); } /* unscaled OSD show * overlay is blended at output (screen) resolution. */ static int osd_show_unscaled (osd_object_t *osd, int64_t vpts) { return _osd_show(osd, vpts, 1); } /* * send event to hide osd at given pts (0=now) * the object is not changed. there may be subsequent drawing on it. */ static int _osd_hide (osd_object_t *osd, int64_t vpts) { osd_renderer_t *this = osd->renderer; video_overlay_manager_t *ovl_manager; lprintf("osd=%p vpts=%"PRId64"\n", (void*)osd, vpts); if( osd->handle < 0 ) return 0; this->event.object.handle = osd->handle; /* not really needed this, but good pratice to clean it up */ memset( this->event.object.overlay, 0, sizeof(*this->event.object.overlay) ); this->event.event_type = OVERLAY_EVENT_HIDE; this->event.vpts = vpts; ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out); ovl_manager->add_event(ovl_manager, (void *)&this->event); return 1; } static int osd_hide (osd_object_t *osd, int64_t vpts) { osd_renderer_t *this = osd->renderer; xine_private_t *xine = (xine_private_t *)this->stream->xine; int ret; xine->port_ticket->acquire (xine->port_ticket, 1); pthread_mutex_lock (&this->osd_mutex); ret = _osd_hide(osd, vpts); pthread_mutex_unlock (&this->osd_mutex); xine->port_ticket->release (xine->port_ticket, 1); return ret; } /* * clear an osd object, so that it can be used for rendering a new image */ static void osd_clear (osd_object_t *osd) { lprintf("osd=%p\n", (void*)osd); if (osd->area_touched) { osd->area_touched = 0; memset(osd->area, 0, osd->width * osd->height); } osd->x1 = osd->width; osd->y1 = osd->height; osd->x2 = 0; osd->y2 = 0; if (osd->argb_layer) { pthread_mutex_lock(&osd->argb_layer->mutex); osd->argb_layer->x1 = osd->x1; osd->argb_layer->y1 = osd->y1; osd->argb_layer->x2 = osd->x2; osd->argb_layer->y2 = osd->y2; pthread_mutex_unlock(&osd->argb_layer->mutex); } } /* * */ static void _update_clipping(osd_object_t *osd, int x1, int y1, int x2, int y2) { osd->x1 = MIN( osd->x1, x1 ); osd->y1 = MIN( osd->y1, y1 ); osd->x2 = MAX( osd->x2, x2 ); osd->y2 = MAX( osd->y2, y2 ); osd->area_touched = 1; } /* * Draw a point. */ static void osd_point (osd_object_t *osd, int x, int y, int color) { uint8_t *c; lprintf("osd=%p (%d x %d)\n", (void*)osd, x, y); if (x < 0 || x >= osd->width) return; if (y < 0 || y >= osd->height) return; _update_clipping(osd, x, y, x + 1, y + 1); c = osd->area + y * osd->width + x; *c = color; } /* Fast line draw, adapted from tdaudioanalyzer. */ static void osd_line (osd_object_t *osd, int x1, int y1, int x2, int y2, int color) { int w = x2 - x1; int h = y2 - y1; lprintf ("osd_line (x1=%d, y1=%d, x2=%d, y2=%d, color=%d).\n", x1, y1, x2, y2, color); /* horizontal line */ if (h == 0) { uint8_t *q; if ((y1 < 0) || (y1 >= osd->height)) return; if (w < 0) { x1 = x2; w = -w; } w++; if (x1 < 0) { w += x1; x1 = 0; } if (w > osd->width - x1) w = osd->width - x1; if (w <= 0) return; _update_clipping (osd, x1, y1, x1 + w, y1 + 1); q = osd->area + osd->width * y1 + x1; do { *q++ = color; w--; } while (w > 0); return; } /* vertical line */ if (w == 0) { uint8_t *q; if ((x1 < 0) || (x1 >= osd->width)) return; if (h < 0) { y1 = y2; h = -h; } h++; if (y1 < 0) { h += y1; y1 = 0; } if (h > osd->height - y1) h = osd->height - y1; if (h <= 0) return; _update_clipping (osd, x1, y1, x1 + 1, y1 + h); q = osd->area + y1 * osd->width + x1; do { *q = color; q += osd->width; h--; } while (h > 0); return; } /* tilted */ { int32_t test[2], n; ssize_t bump[2]; long int stepy = osd->width; /* always render downward */ if (h < 0) { w = -w; h = -h; x1 = x2; y1 = y2; } /* right to left */ if (w < 0) { w = -w; if (w >= h) { /* flat */ int skipx = (x1 < osd->width) ? 0 : x1 - osd->width + 1; int skipy = (y1 >= 0) ? 0 : (-y1 * w + (h >> 1)) / h; n = w + 1; if (skipx + skipy > 0) { if (skipx >= skipy) { /* clip right */ n -= skipx; x1 = osd->width - 1; y1 += skipx * h / w; } else { /* clip top */ n -= skipy; x1 -= skipy; y1 = 0; } } /* clip bottom */ skipy = y1 + (n * h + (w >> 1)) / w - osd->height; if (skipy > 0) n -= skipy * w / h; /* clip left */ if (n > x1 + 1) n = x1 + 1; if (n <= 0) return; _update_clipping (osd, x1 + 1 - n, y1, x1 + 1, y1 + n * h / w); test[0] = -h; test[1] = w - h; bump[0] = -1; bump[1] = osd->width - 1; } else { /* steep */ int skipx = (x1 < osd->width) ? 0 : ((x1 - osd->width + 1) * h + (w >> 1)) / w; int skipy = (y1 >= 0) ? 0 : -y1; n = h + 1; if (skipx + skipy > 0) { if (skipy >= skipx) { /* clip top */ n -= skipy; x1 -= skipy * w / h; y1 = 0; } else { /* clip right */ n -= skipx; x1 = osd->width - 1; y1 += skipx; } } /* clip left */ skipx = (n * w + (h >> 1)) / h - x1 - 1; if (skipx > 0) n -= skipx * h / w; /* clip bottom */ if (n > osd->height - y1) n = osd->height - y1; if (n <= 0) return; _update_clipping (osd, x1 + 1 - n * w / h, y1, x1 + 1, y1 + n); test[0] = -w; test[1] = h - w; bump[0] = osd->width; bump[1] = osd->width - 1; } } else { /* left to right */ if (w >= h) { /* flat */ int skipx = (x1 >= 0) ? 0 : -x1; int skipy = (y1 >= 0) ? 0 : (-y1 * w + (h >> 1)) / h; n = w + 1; if (skipx + skipy > 0) { if (skipx >= skipy) { /* clip left */ n -= skipx; x1 = 0; y1 += skipx * h / w; } else { /* clip top */ n -= skipy; x1 += skipy; y1 = 0; } } /* clip bottom */ skipy = y1 + (n * h + (w >> 1)) / w - osd->height; if (skipy > 0) n -= skipy * w / h; /* clip right */ if (n > osd->width - x1) n = osd->width - x1; if (n <= 0) return; _update_clipping (osd, x1, y1, x1 + n, y1 + n * h / w); test[0] = -h; test[1] = w - h; bump[0] = 1; bump[1] = osd->width + 1; } else { /* steep */ int skipx = (x1 >= 0) ? 0 : (-x1 * h + (w >> 1)) / w; int skipy = (y1 >= 0) ? 0 : -y1; n = h + 1; if (skipx + skipy > 0) { if (skipy >= skipx) { /* clip top */ n -= skipy; x1 += skipy * w / h; y1 = 0; } else { /* clip left */ n -= skipx; x1 = 0; y1 += skipx; } } /* clip right */ skipx = osd->width - x1 - (n * w + (h >> 1)) / h; if (skipx > 0) n -= skipx * h / w; /* clip bottom */ if (n > osd->height - y1) n = osd->height - y1; if (n <= 0) return; _update_clipping (osd, x1, y1, x1 + n * w / h, y1 + n); test[0] = -w; test[1] = h - w; bump[0] = osd->width; bump[1] = osd->width + 1; } } /* render */ { uint8_t *q = osd->area + y1 * stepy + x1; int32_t d = test[1]; do { uint32_t i = (uint32_t)d >> 31; *q = color; d += test[i]; q += bump[i]; n--; } while (n > 0); } } } /* * filled retangle */ static void osd_filled_rect (osd_object_t *osd, int x1, int y1, int x2, int y2, int color) { int x, y, dx, dy; lprintf ("osd_filled_rect (x1=%d, y1=%d, x2=%d, y2=%d, color=%d).\n", x1, y1, x2, y2, color); /* sort rectangle */ x = MIN( x1, x2 ); dx = MAX( x1, x2 ); y = MIN( y1, y2 ); dy = MAX( y1, y2 ); /* clip rectangle */ if (x >= osd->width || y >= osd->height) return; if (x < 0) { dx += x; x = 0; } if (y < 0) { dy += y; y = 0; } dx = MIN( dx, osd->width ); dy = MIN( dy, osd->height ); _update_clipping(osd, x, y, dx, dy); dx -= x; dy -= y; for( ; dy--; y++ ) { memset(osd->area + y * osd->width + x,color,dx); } } /* * set palette (color and transparency) */ static void osd_set_palette(osd_object_t *osd, const uint32_t *color, const uint8_t *trans ) { memcpy(osd->color, color, sizeof(osd->color)); memcpy(osd->trans, trans, sizeof(osd->trans)); } /* * set on existing text palette * (-1 to set user specified palette) */ static void osd_set_text_palette(osd_object_t *osd, int palette_number, int color_base) { if( palette_number < 0 ) palette_number = osd->renderer->textpalette; /* some sanity checks for the color indices */ if( color_base < 0 ) color_base = 0; else if( color_base > OVL_PALETTE_SIZE - TEXT_PALETTE_SIZE ) color_base = OVL_PALETTE_SIZE - TEXT_PALETTE_SIZE; memcpy(&osd->color[color_base], textpalettes_color[palette_number], sizeof(textpalettes_color[palette_number])); memcpy(&osd->trans[color_base], textpalettes_trans[palette_number], sizeof(textpalettes_trans[palette_number])); } /* * get palette (color and transparency) */ static void osd_get_palette (osd_object_t *osd, uint32_t *color, uint8_t *trans) { memcpy(color, osd->color, sizeof(osd->color)); memcpy(trans, osd->trans, sizeof(osd->trans)); } /* * set position were overlay will be blended */ static void osd_set_position (osd_object_t *osd, int x, int y) { if( x < 0 || x > 0x10000 ) x = 0; if( y < 0 || y > 0x10000 ) y = 0; osd->display_x = x; osd->display_y = y; } /* load bitmap font into osd engine */ static int osd_renderer_load_font (osd_renderer_t *this, const char *filename) { gzFile fp; size_t fnlen = strlen (filename) + 1; int i; osd_font_t *font = NULL; lprintf("name=%s\n", filename ); /* load quick & dirt font format */ do { uint8_t b[sizeof (font->name) + 3 * 2]; size_t dsize, lsize; fp = gzopen (filename, "rb"); if (!fp) break; if (gzread (fp, b, sizeof (font->name) + 3 * 2) != (int)sizeof (font->name) + 3 * 2) break; i = _X_LE_16 (b + sizeof (font->name)); if (i != FONT_VERSION) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("wrong version for font '%s'. expected %d found %d.\n"), (char *)b, i, FONT_VERSION); break; } font = calloc (1, sizeof (*font) + fnlen); if (!font) break; memcpy (font->name, b, sizeof (font->name)); font->name[sizeof(font->name) - 1] = 0; font->version = i; font->size = _X_LE_16 (b + sizeof (font->name) + 1 * 2); font->num_fontchars = _X_LE_16 (b + sizeof (font->name) + 2 * 2); font->loaded = 1; font->data = NULL; font->fontchar = malloc (sizeof (osd_fontchar_t) * font->num_fontchars); if (!font->fontchar) break; lprintf ("font '%s' chars=%d\n", font->name, font->num_fontchars); /* estimate total uncompressed size, and load entire rest. */ dsize = (size_t)font->num_fontchars * font->size * font->size; font->data = malloc (dsize); if (!font->data) break; lsize = 0; while (1) { uint8_t *n; int r = gzread (fp, font->data + lsize, dsize - lsize); if (r <= 0) break; lsize += r; if (lsize < dsize) break; if (dsize > (20 << 20)) break; n = realloc (font->data, 2 * dsize); if (!n) break; font->data = n; dsize *= 2; } gzclose (fp); fp = NULL; if (lsize < dsize) { uint8_t *n = realloc (font->data, lsize); if (n) font->data = n; } dsize = sizeof (font->name) + 3 * 2 + lsize; /* load all characters */ { uint8_t *p = font->data; for (i = 0; i < font->num_fontchars; i++) { size_t bsize; if (lsize < 3 * 2) break; font->fontchar[i].code = _X_LE_16 (p); font->fontchar[i].width = _X_LE_16 (p + 1 * 2); font->fontchar[i].height = _X_LE_16 (p + 2 * 2); p += 3 * 2; lsize -= 3 * 2; font->fontchar[i].bmp = p; bsize = (size_t)font->fontchar[i].width * (size_t)font->fontchar[i].height; if (lsize < bsize) break; p += bsize; lsize -= bsize; } } /* check if all expected characters were loaded */ if (i < font->num_fontchars) break; { osd_font_t *known_font; lprintf ("font '%s' loaded\n", font->name); /* check if font is already known to us */ known_font = this->fonts; while (known_font) { if (!strcasecmp (known_font->name, font->name) && known_font->size == font->size) break; known_font = known_font->next; } if (!known_font) { /* new font, add it to list */ font->filename = (char *)font + sizeof (*font); memcpy (font->filename, filename, fnlen); font->next = this->fonts; this->fonts = font; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "osd: loaded font %s (%u bytes).\n", filename, (unsigned int)dsize); return 1; } if (!known_font->loaded) { /* the font was preloaded before. * add loaded characters to the existing entry. */ known_font->version = font->version; known_font->size = font->size; known_font->num_fontchars = font->num_fontchars; known_font->loaded = 1; known_font->fontchar = font->fontchar; known_font->data = font->data; free (font); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "osd: loaded font %s (%u bytes).\n", filename, (unsigned int)dsize); return 1; } xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("font '%s-%d' already loaded, weird.\n"), font->name, font->size); free (font->data); free (font->fontchar); free (font); return 1; } } while (0); if (font) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("font '%s' loading failed (%d < %d)\n"), font->name, i, font->num_fontchars); free (font->data); free (font->fontchar); free (font); } if (fp) gzclose (fp); return 0; } /* * unload font */ static int osd_renderer_unload_font(osd_renderer_t *this, const char *fontname ) { osd_font_t *font, *last; osd_object_t *osd; int i, ret = 0; lprintf("font '%s'\n", fontname); pthread_mutex_lock (&this->osd_mutex); osd = this->osds; while( osd ) { if( !strcasecmp(osd->font->name, fontname) ) osd->font = NULL; osd = osd->next; } last = NULL; font = this->fonts; while (font) { if (!strcasecmp (font->name, fontname)) { if (font->loaded) { if (font->data) { _x_freep (&font->data); } else { for (i = 0; i < font->num_fontchars; i++) { _x_freep (&font->fontchar[i].bmp); } } _x_freep (&font->fontchar); } if( last ) last->next = font->next; else this->fonts = font->next; free( font ); ret = 1; break; } last = font; font = font->next; } pthread_mutex_unlock (&this->osd_mutex); return ret; } /* look for a native xine font matching the given name and size and load it into osd->font. return nonzero if a native font is found, zero if not */ static int osd_lookup_native( osd_object_t *osd, const char *fontname, int size ) { osd_font_t *font; int best = 0; int ret = 0; font = osd->renderer->fonts; while( font ) { if( !strcasecmp(font->name, fontname) && (size>=font->size) && (best<font->size)) { ret = 1; osd->font = font; best = font->size; //lprintf ("best: font->name=%s, size=%d\n", font->name, font->size); } font = font->next; } if (ret) lprintf("native match for %s %1d: %s %1d\n",fontname,size,osd->font->name,osd->font->size); else lprintf("no native font matching %s %1d",fontname,size); return ret; } #ifdef HAVE_FT2 # ifdef HAVE_FONTCONFIG /** * @brief Look up a font name using FontConfig library * @param osd The OSD object to load the font for. * @param fontname Name of the font to look up. * @param size Size of the font to look for. * * @return If the lookup was done correctly, a non-zero value is returned. */ static int osd_lookup_fontconfig( osd_object_t *osd, const char *const fontname, const int size ) { FcPattern *pat = NULL, *match = NULL; FcFontSet *fs = FcFontSetCreate(); FcResult result; pat = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, fontname, FC_SIZE, FcTypeDouble, (double)size, NULL); FcConfigSubstitute(NULL, pat, FcMatchPattern); FcDefaultSubstitute(pat); match = FcFontMatch(NULL, pat, &result); FcPatternDestroy(pat); if ( ! match ) { FcFontSetDestroy(fs); xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: error matching font %s with FontConfig"), fontname); return 0; } FcFontSetAdd(fs, match); if ( fs->nfont != 0 ) { FcChar8 *filename = NULL; FcPatternGetString(fs->fonts[0], FC_FILE, 0, &filename); if ( ! FT_New_Face(osd->ft2->library, (const char*)filename, 0, &osd->ft2->face) ) { FcFontSetDestroy(fs); return 1; } xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: error loading font %s with FontConfig"), fontname); } else { xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: error looking up font %s with FontConfig"), fontname); } FcFontSetDestroy(fs); return 0; } # endif /* HAVE_FONTCONFIG */ /** * @brief Look up a font file using XDG data directories. * @param osd The OSD object to load the font for. * @param fontname Name (absolute or relative) of the font to look up. * * @return If the lookup was done correctly, a non-zero value is returned. * * @see XDG Base Directory specification: * http://standards.freedesktop.org/basedir-spec/latest/index.html */ static int osd_lookup_xdg (osd_object_t *osd, const char *const fontname) { const char * const *data_dirs = xdgSearchableDataDirectories (&osd->renderer->stream->xine->basedir_handle); if (data_dirs) { while ((*data_dirs) && (*data_dirs)[0]) { char fontpath[2048], *e = fontpath + sizeof (fontpath), *q = fontpath; FT_Error fte = FT_Err_Ok; q += strlcpy (q, *data_dirs, q - e); if (q > e) q = e; q += strlcpy (q, "/"PACKAGE"/fonts/", q - e); if (q > e) q = e; strlcpy (q, fontname, q - e); fte = FT_New_Face (osd->ft2->library, fontpath, 0, &osd->ft2->face); if (fte == FT_Err_Ok) { xprintf (osd->renderer->stream->xine, XINE_VERBOSITY_DEBUG, "osd: loaded font %s.\n", fontpath); return 1; } data_dirs++; } } xprintf (osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: error loading font %s with in XDG data directories.\n"), fontname); return 0; } static int osd_set_font_freetype2( osd_object_t *osd, const char *fontname, int size ) { if (!osd->ft2) { osd->ft2 = calloc(1, sizeof(osd_ft2context_t)); if(FT_Init_FreeType( &osd->ft2->library )) { xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: cannot initialize ft2 library\n")); _x_freep(&osd->ft2); return 0; } } if (osd->ft2->face) { FT_Done_Face (osd->ft2->face); osd->ft2->face = NULL; } do { /* while 0 */ /* try to load font from current directory or from an absolute path we want to do this before trying osd_lookup_fontconfig (which doesn't handle filenames) */ if ( FT_New_Face(osd->ft2->library, fontname, 0, &osd->ft2->face) == FT_Err_Ok ) break; /* try to find a native xine font and return 0 if it succeeds, allowing that to load. this has to happen before calling osd_lookup_fontconfig so that you don't get the system default font when trying to load e.g Cetus. */ if (osd_lookup_native(osd,fontname,size)) return 0; #ifdef HAVE_FONTCONFIG if ( osd_lookup_fontconfig(osd, fontname, size) ) break; #endif if ( osd_lookup_xdg(osd, fontname) ) break; osd_free_ft2 (osd); return 0; } while(0); if (FT_Set_Pixel_Sizes(osd->ft2->face, 0, size)) { xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: error setting font size (no scalable font?)\n")); osd_free_ft2 (osd); return 0; } osd->ft2->size = size; return 1; } #endif /* set the font of osd object */ static int osd_set_font( osd_object_t *osd, const char *fontname, int size) { int ret = 1; lprintf("osd=%p font '%s'\n", (void*)osd, fontname); pthread_mutex_lock (&osd->renderer->osd_mutex); #ifdef HAVE_FT2 if ( ! osd_set_font_freetype2(osd, fontname, size) ) #endif { /* If the FreeType2 loading failed (which can happen if it finds a native xine font) */ osd->font = NULL; ret = osd_lookup_native(osd,fontname,size); if( ret ) { /* load font if needed */ if( !osd->font->loaded ) ret = osd_renderer_load_font(osd->renderer, osd->font->filename); if(!ret) osd->font = NULL; } } pthread_mutex_unlock (&osd->renderer->osd_mutex); return ret; } /* * search the character in the sorted array, * * returns ALIAS_CHARACTER_FONT if character 'code' isn't found, * returns 'n' on error */ static int osd_search(osd_fontchar_t *array, size_t n, uint16_t code) { size_t i, left, right; if (!n) return 0; left = 0; right = n - 1; while (left < right) { i = (left + right) >> 1; if (code <= array[i].code) right = i; else left = i + 1; } if (array[right].code == code) return right; else return ALIAS_CHARACTER_FONT < n ? ALIAS_CHARACTER_FONT : n; } #ifdef HAVE_ICONV /* * get next unicode value */ static uint16_t osd_iconv_getunicode(xine_t *xine, iconv_t cd, const char *encoding, ICONV_CONST char **inbuf, size_t *inbytesleft) { uint16_t unicode; char *outbuf = (char*)&unicode; size_t outbytesleft = 2; size_t count; if (cd != (iconv_t)-1) { /* get unicode value from iconv */ count = iconv(cd, inbuf, inbytesleft, &outbuf, &outbytesleft); if (count == (size_t)-1 && errno != E2BIG) { /* unknown character or character wider than 16 bits, try skip one byte */ xprintf(xine, XINE_VERBOSITY_LOG, _("osd: unknown sequence starting with byte 0x%02X in encoding \"%s\", skipping\n"), (*inbuf)[0] & 0xFF, encoding); if (*inbytesleft) { (*inbytesleft)--; (*inbuf)++; } return ALIAS_CHARACTER_CONV; } } else { /* direct mapping without iconv */ unicode = (unsigned char)(*inbuf)[0]; (*inbuf)++; (*inbytesleft)--; } return unicode; } #endif /* * free iconv encoding */ static void osd_free_encoding(osd_object_t *osd) { #ifdef HAVE_ICONV if (osd->cd != (iconv_t)-1) { iconv_close(osd->cd); osd->cd = (iconv_t)-1; } _x_freep(&osd->encoding); #endif } /* * set encoding of text * * NULL ... no conversion (iso-8859-1) * "" ... locale encoding */ static int osd_set_encoding (osd_object_t *osd, const char *encoding) { #ifdef HAVE_ICONV char *enc; osd_free_encoding(osd); lprintf("osd=%p, encoding=%s\n", (void*)osd, encoding ? (encoding[0] ? encoding : "locale") : "no conversion"); /* no conversion, use latin1 */ if (!encoding) return 1; /* get encoding from system */ if (!encoding[0]) { if ((enc = xine_get_system_encoding()) == NULL) { xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: can't find out current locale character set\n")); return 0; } lprintf("locale encoding='%s'\n", enc); } else enc = strdup(encoding); /* prepare conversion to UCS-2 */ if ((osd->cd = iconv_open(UCS2_ENCODING, enc)) == (iconv_t)-1) { xprintf(osd->renderer->stream->xine, XINE_VERBOSITY_LOG, _("osd: unsupported conversion %s -> %s, no conversion performed\n"), enc, UCS2_ENCODING); free(enc); return 0; } osd->encoding = enc; return 1; #else return encoding == NULL; #endif /* HAVE_ICONV */ } #define FONT_OVERLAP 1/10 /* overlap between consecutive characters */ /* render text in current encoding on x,y position */ static int osd_render_text (osd_object_t *osd, int x1, int y1, const char *text, int color_base) { osd_renderer_t *this = osd->renderer; int xleft = x1, i; const char *inbuf; uint16_t unicode; size_t inbytesleft; lprintf("osd=%p (%d,%d) \"%s\"\n", (void*)osd, x1, y1, text); /* some sanity checks for the color indices */ if( color_base < 0 ) color_base = 0; else if( color_base > OVL_PALETTE_SIZE - TEXT_PALETTE_SIZE ) color_base = OVL_PALETTE_SIZE - TEXT_PALETTE_SIZE; pthread_mutex_lock (&this->osd_mutex); if ((x1 >= osd->width) || (y1 >= osd->height)) { pthread_mutex_unlock (&this->osd_mutex); return 0; } if (x1 < osd->x1) osd->x1 = x1 < 0 ? 0 : x1; if (y1 < osd->y1) osd->y1 = y1 < 0 ? 0 : y1; osd->area_touched = 1; inbuf = text; inbytesleft = strlen(text); #ifdef HAVE_FT2 if (osd->ft2 && osd->ft2->face) { FT_UInt previous = 0; FT_Bool use_kerning = FT_HAS_KERNING (osd->ft2->face); int first = 1, yb = y1; uint8_t ctab[256]; /* we will likely render more than 256 pixels, so preset a color table. */ for (i = 0; i < 256; i++) ctab[i] = i / 25 + color_base; while (inbytesleft) { FT_GlyphSlot slot; #ifdef HAVE_ICONV unicode = osd_iconv_getunicode (this->stream->xine, osd->cd, osd->encoding, (ICONV_CONST char **)&inbuf, &inbytesleft); #else unicode = inbuf[0]; inbuf++; inbytesleft--; #endif if (unicode == '\n') { y1 += osd->ft2->face->size->metrics.height / 64; if (!first) yb = y1; previous = 0; first = 1; if (x1 > osd->x2) osd->x2 = x1 > osd->width ? osd->width : x1; x1 = xleft; if (y1 >= osd->height) break; continue; } if (x1 >= osd->width) continue; slot = osd->ft2->face->glyph; i = FT_Get_Char_Index (osd->ft2->face, unicode); /* add kerning relative to the previous letter */ if (use_kerning && previous && i) { FT_Vector delta; FT_Get_Kerning(osd->ft2->face, previous, i, KERNING_DEFAULT, &delta); x1 += delta.x / 64; } previous = i; if (FT_Load_Glyph(osd->ft2->face, i, FT_LOAD_FLAGS)) { xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("osd: error loading glyph\n")); continue; } if (slot->format != ft_glyph_format_bitmap) { if (FT_Render_Glyph(slot, ft_render_mode_normal)) xprintf(this->stream->xine, XINE_VERBOSITY_LOG, _("osd: error in rendering glyph\n")); } /* if the first letter has a bearing not on the basepoint, shift the * whole output to be sure that we are inside the bounding box */ if (first) x1 -= slot->bitmap_left; first = 0; { const uint8_t *s = (const uint8_t *)slot->bitmap.buffer; uint8_t *d = osd->area + x1 + slot->bitmap_left; int y, yt, lines = slot->bitmap.rows, cols = slot->bitmap.width; size_t pads = slot->bitmap.pitch - cols; size_t padd = osd->width - cols; /* we shift the whole glyph down by it's ascender so that the specified * coordinate is the top left corner which is much more practical than * the baseline as the user normally has no idea where the baseline is */ yt = osd->ft2->face->size->metrics.ascender / 64 - slot->bitmap_top; if (yt < 0) { /* paranoia? */ s -= yt * slot->bitmap.pitch; lines += yt; yt = 0; } yt += y1; d += yt * osd->width; /* clip top (XXX: is this at all possible?) */ if (yt < 0) { s -= yt * slot->bitmap.pitch; d -= yt * osd->width; lines += yt; } /* clip bottom */ y = osd->height - yt - lines; if (y < 0) { lines += y; } /* clip left (XXX: is this at all possible?) */ if (x1 < 0) { s -= x1; d -= x1; pads -= x1; padd -= x1; cols += x1; } /* clip right */ y = osd->width - x1 - cols; if (y < 0) { pads -= y; padd -= y; cols += y; } /* render this char (or not if there is too much clipping) */ for (y = lines; y > 0; y--) { int x; for (x = cols; x > 0; x--) { if (*s) /* skip drawing transparency */ *d = ctab[*s]; s++; d++; } s += pads; d += padd; } } x1 += slot->advance.x / 64; if (x1 >= osd->width) break; } y1 += (osd->ft2->face->size->metrics.height / 64); /* mark the space down to the last nonempty line as dirty. */ if (!first) yb = y1; if (yb > osd->y2) osd->y2 = yb > osd->width ? osd->width : yb; if (x1 > osd->x2) osd->x2 = x1 > osd->width ? osd->width : x1; } else #endif { osd_font_t *font = osd->font; int lineheight = 0, yb = y1; if (!font) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("osd: font isn't defined\n")); pthread_mutex_unlock (&this->osd_mutex); return 0; } while (inbytesleft) { #ifdef HAVE_ICONV unicode = osd_iconv_getunicode (this->stream->xine, osd->cd, osd->encoding, (ICONV_CONST char **)&inbuf, &inbytesleft); #else unicode = inbuf[0]; inbuf++; inbytesleft--; #endif if (unicode == '\n') { y1 += font->size; if (lineheight) yb = y1; lineheight = 0; if (x1 > osd->x2) osd->x2 = x1 > osd->width ? osd->width : x1; x1 = xleft; if (y1 >= osd->height) break; continue; } if (x1 >= osd->width) continue; i = osd_search (font->fontchar, font->num_fontchars, unicode); lprintf ("font '%s' [%d, U+%04X == U+%04X] %dx%d -> %d,%d\n", font->name, i, unicode, font->fontchar[i].code, font->fontchar[i].width, font->fontchar[i].height, x1, y1); if (i != font->num_fontchars) { const uint8_t *s = font->fontchar[i].bmp; uint8_t *d = osd->area + y1 * osd->width + x1; int y, lines = font->fontchar[i].height, cols = font->fontchar[i].width; size_t pads = 0; size_t padd = osd->width - cols; /* clip top (XXX: is this at all possible?) */ if (y1 < 0) { s -= y1 * cols; d -= y1 * osd->width; lines += y1; } /* clip bottom */ y = osd->height - y1 - lines; if (y < 0) { lines += y; } /* clip left (XXX: is this at all possible?) */ if (x1 < 0) { s -= x1; d -= x1; pads -= x1; padd -= x1; cols += x1; } /* clip right */ y = osd->width - x1 - cols; if (y < 0) { pads -= y; padd -= y; cols += y; } /* render this char (or not if there is too much clipping) */ for (y = lines; y > 0; y--) { int x; for (x = cols; x > 0; x--) { if (*s > 1) /* skip drawing transparency */ *d = *s + (uint8_t)color_base; s++; d++; } s += pads; d += padd; } x1 += font->fontchar[i].width - (font->fontchar[i].width * FONT_OVERLAP); if (lineheight < font->fontchar[i].height) lineheight = font->fontchar[i].height; } } if (lineheight) yb = y1 + lineheight; if (osd->y2 < yb) osd->y2 = yb > osd->height ? osd->height : yb; if (x1 > osd->x2) osd->x2 = x1 > osd->width ? osd->width : x1; } /* !(osd->ft2 && osd->ft2->face) */ pthread_mutex_unlock (&this->osd_mutex); return 1; } /* get width and height of how text will be renderized */ static int osd_get_text_size(osd_object_t *osd, const char *text, int *width, int *height) { osd_renderer_t *this = osd->renderer; int i; const char *inbuf; uint16_t unicode; size_t inbytesleft; lprintf("osd=%p \"%s\"\n", (void*)osd, text); inbuf = text; inbytesleft = strlen (text); *width = 0; *height = 0; pthread_mutex_lock (&this->osd_mutex); #ifdef HAVE_FT2 if (osd->ft2 && osd->ft2->face) { int y1 = 0, linewidth = 0; /* not all free type fonts provide kerning */ FT_Bool use_kerning = FT_HAS_KERNING (osd->ft2->face); FT_UInt previous = 0; int first_glyph = 1; while (inbytesleft) { FT_GlyphSlot slot; #ifdef HAVE_ICONV unicode = osd_iconv_getunicode (this->stream->xine, osd->cd, osd->encoding, (ICONV_CONST char **)&inbuf, &inbytesleft); #else unicode = inbuf[0]; inbuf++; inbytesleft--; #endif if (unicode == '\n') { y1 += osd->ft2->face->size->metrics.height / 64; /* see last char comment below */ if (!first_glyph) { *height = y1; if (osd->ft2->face->glyph->bitmap.width) linewidth -= osd->ft2->face->glyph->advance.x / 64; linewidth += osd->ft2->face->glyph->bitmap.width; linewidth += osd->ft2->face->glyph->bitmap_left; } if (*width < linewidth) *width = linewidth; linewidth = 0; previous = 0; first_glyph = 1; continue; } slot = osd->ft2->face->glyph; i = FT_Get_Char_Index (osd->ft2->face, unicode); /* kerning add the relative to the previous letter */ if (use_kerning && previous && i) { FT_Vector delta; FT_Get_Kerning (osd->ft2->face, previous, i, KERNING_DEFAULT, &delta); linewidth += delta.x / 64; } previous = i; if (FT_Load_Glyph (osd->ft2->face, i, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("osd: error loading glyph %i\n"), i); text++; continue; } if (slot->format != ft_glyph_format_bitmap) { if (FT_Render_Glyph(osd->ft2->face->glyph, ft_render_mode_normal)) xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("osd: error in rendering\n")); } /* left shows the left edge relative to the base point. A positive value means the * letter is shifted right, so we need to subtract the value from the width */ if (first_glyph) linewidth -= slot->bitmap_left; first_glyph = 0; linewidth += slot->advance.x / 64; text++; } y1 += osd->ft2->face->size->metrics.height / 64; /* if we have a true type font we need to do some corrections for the last * letter. As this one is still in the gylph slot we can still work with * it. For the last letter be must not use advance and width but the real * width of the bitmap. We're right from the base point so we subtract the * advance value that was added in the for-loop and add the width. We have * to also add the left bearing because the letter might be shifted left or * right and then the right edge is also shifted */ if (!first_glyph) { *height = y1; if (osd->ft2->face->glyph->bitmap.width) linewidth -= osd->ft2->face->glyph->advance.x / 64; linewidth += osd->ft2->face->glyph->bitmap.width; linewidth += osd->ft2->face->glyph->bitmap_left; } if (*width < linewidth) *width = linewidth; } else #endif { int y1 = 0, linewidth = 0, lineheight = 0; osd_font_t *font = osd->font; if (!font) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, _("osd: font isn't defined\n")); pthread_mutex_unlock (&this->osd_mutex); return 0; } while (inbytesleft) { #ifdef HAVE_ICONV unicode = osd_iconv_getunicode (this->stream->xine, osd->cd, osd->encoding, (ICONV_CONST char **)&inbuf, &inbytesleft); #else unicode = inbuf[0]; inbuf++; inbytesleft--; #endif if (unicode == '\n') { y1 += font->size; if (lineheight) *height = y1; if (*width < linewidth) *width = linewidth; linewidth = 0; lineheight = 0; continue; } i = osd_search (font->fontchar, font->num_fontchars, unicode); if (i != font->num_fontchars) { if (font->fontchar[i].height > lineheight) lineheight = font->fontchar[i].height; linewidth += font->fontchar[i].width - (font->fontchar[i].width * FONT_OVERLAP); } } if (lineheight) *height = y1 + lineheight; if (*width < linewidth) *width = linewidth; } /* !(osd->ft2 && osd->ft2->face) */ pthread_mutex_unlock (&this->osd_mutex); return 1; } /* * free osd object */ static void osd_free_object (osd_object_t *osd_to_close) { osd_renderer_t *this = osd_to_close->renderer; xine_private_t *xine = (xine_private_t *)this->stream->xine; video_overlay_manager_t *ovl_manager; osd_object_t *osd, *last; if( osd_to_close->handle >= 0 ) { osd_hide(osd_to_close,0); this->event.object.handle = osd_to_close->handle; /* not really needed this, but good pratice to clean it up */ memset( this->event.object.overlay, 0, sizeof(*this->event.object.overlay) ); this->event.event_type = OVERLAY_EVENT_FREE_HANDLE; this->event.vpts = 0; xine->port_ticket->acquire (xine->port_ticket, 1); ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out); ovl_manager->add_event(ovl_manager, (void *)&this->event); xine->port_ticket->release (xine->port_ticket, 1); osd_to_close->handle = -1; /* handle will be freed */ } if (osd_to_close->argb_layer) { /* clear argb buffer pointer so that buffer may be freed safely after returning */ this->set_argb_buffer(osd_to_close, NULL, 0, 0, 0, 0); set_argb_layer_ptr(&osd_to_close->argb_layer, NULL); } pthread_mutex_lock (&this->osd_mutex); last = NULL; osd = this->osds; while( osd ) { if ( osd == osd_to_close ) { _x_freep( &osd->area ); osd_free_ft2 (osd); osd_free_encoding(osd); if( last ) last->next = osd->next; else this->osds = osd->next; free( osd ); break; } last = osd; osd = osd->next; } pthread_mutex_unlock (&this->osd_mutex); } static void osd_renderer_close (osd_renderer_t *this_gen) { osd_renderer_private_t *this = (osd_renderer_private_t *)this_gen; if (this->r.event.object.overlay == &this->ovl) this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, &this->r, sizeof (*this)); while (this->r.osds) osd_free_object (this->r.osds); while (this->r.fonts) osd_renderer_unload_font (&this->r, this->r.fonts->name); pthread_mutex_destroy (&this->r.osd_mutex); if (this->r.event.object.overlay != &this->ovl) _x_freep (&this->r.event.object.overlay); free (this); } static void update_text_palette(void *this_gen, xine_cfg_entry_t *entry) { osd_renderer_t *this = (osd_renderer_t *)this_gen; this->textpalette = entry->num_value; lprintf("palette will be '%s'\n", textpalettes_str[this->textpalette] ); } static void osd_draw_bitmap(osd_object_t *osd, const uint8_t *bitmap, int x1, int y1, int width, int height, const uint8_t *palette_map) { int y, x; lprintf("osd=%p at (%d,%d) %dx%d\n", (void*)osd, x1,y1, width,height ); _update_clipping(osd, x1, y1, x1 + width, y1 + height); for( y=0; y<height; y++ ) { if ( palette_map ) { int src_offset = y * width; int dst_offset = (y1+y) * osd->width + x1; /* Slow copy with palette translation, the map describes how to convert color indexes in the source bitmap to indexes in the osd palette */ for ( x=0; x<width; x++ ) { osd->area[dst_offset+x] = palette_map[bitmap[src_offset+x]]; } } else { /* Fast copy with direct mapping */ memcpy(osd->area + (y1+y) * osd->width + x1, bitmap + y * width, width); } } } static void osd_set_argb_buffer(osd_object_t *osd, uint32_t *argb_buffer, int dirty_x, int dirty_y, int dirty_width, int dirty_height) { if (!osd->argb_layer) set_argb_layer_ptr(&osd->argb_layer, argb_layer_create()); if (osd->argb_layer->buffer != argb_buffer) { dirty_x = 0; dirty_y = 0; dirty_width = osd->width; dirty_height = osd->height; } /* keep osd_object clipping behavior */ osd->x1 = MIN( osd->x1, dirty_x ); osd->x2 = MAX( osd->x2, dirty_x + dirty_width ); osd->y1 = MIN( osd->y1, dirty_y ); osd->y2 = MAX( osd->y2, dirty_y + dirty_height ); pthread_mutex_lock(&osd->argb_layer->mutex); /* argb layer update area accumulation */ osd->argb_layer->x1 = MIN( osd->argb_layer->x1, dirty_x ); osd->argb_layer->x2 = MAX( osd->argb_layer->x2, dirty_x + dirty_width ); osd->argb_layer->y1 = MIN( osd->argb_layer->y1, dirty_y ); osd->argb_layer->y2 = MAX( osd->argb_layer->y2, dirty_y + dirty_height ); osd->argb_layer->buffer = argb_buffer; pthread_mutex_unlock(&osd->argb_layer->mutex); } static uint32_t osd_get_capabilities (osd_object_t *osd) { osd_renderer_t *this = osd->renderer; xine_private_t *xine = (xine_private_t *)this->stream->xine; uint32_t capabilities = 0; uint32_t vo_capabilities; #ifdef HAVE_FT2 capabilities |= XINE_OSD_CAP_FREETYPE2; #endif xine->port_ticket->acquire (xine->port_ticket, 1); vo_capabilities = this->stream->video_out->get_capabilities(this->stream->video_out); xine->port_ticket->release (xine->port_ticket, 1); if (vo_capabilities & VO_CAP_UNSCALED_OVERLAY) capabilities |= XINE_OSD_CAP_UNSCALED; if (vo_capabilities & VO_CAP_CUSTOM_EXTENT_OVERLAY) capabilities |= XINE_OSD_CAP_CUSTOM_EXTENT; if (vo_capabilities & VO_CAP_ARGB_LAYER_OVERLAY) capabilities |= XINE_OSD_CAP_ARGB_LAYER; if (vo_capabilities & VO_CAP_VIDEO_WINDOW_OVERLAY) capabilities |= XINE_OSD_CAP_VIDEO_WINDOW; return capabilities; } /* * initialize the osd rendering engine */ osd_renderer_t *_x_osd_renderer_init( xine_stream_t *stream ) { osd_renderer_private_t *this; this = calloc (1, sizeof (*this)); if (!this) return NULL; this->r.stream = stream; this->r.event.object.overlay = &this->ovl; this->xine = stream->xine; pthread_mutex_init (&this->r.osd_mutex, NULL); /* * load available fonts */ { const char * const *data_dirs = xdgSearchableDataDirectories (&stream->xine->basedir_handle); if (data_dirs) { char fontpath[2048], *e = fontpath + sizeof (fontpath); while ((*data_dirs) && (*data_dirs)[0]) { DIR *dir; char *q = fontpath; q += strlcpy (q, *data_dirs, e - q); if (q > e) q = e; q += strlcpy (q, "/"PACKAGE"/fonts/", e - q); if (q > e) q = e; lprintf ("path='%s'\n", fontpath); dir = opendir (fontpath); if (dir) { int n = 0; struct dirent *entry; while ((entry = readdir (dir)) != NULL) { char *s, *d; osd_font_t *font; size_t len = strlen (entry->d_name); if (len <= 12) continue; if (strncmp (entry->d_name + len - 12, ".xinefont.gz", 12)) continue; s = q + strlcpy (q, entry->d_name, e - q) + 1; if (s > e) s = e; d = strchr (q, '-'); if (!d) continue; font = calloc (1, sizeof (*font) + s - fontpath); if (!font) continue; font->filename = (char *)font + sizeof (*font); memcpy (font->filename, fontpath, s - fontpath); *d++ = 0; strlcpy (font->name, q, sizeof (font->name)); { const char *d1 = d; font->size = xine_str2uint32 (&d1); } lprintf ("font '%s' size %d is preloaded\n", font->name, font->size); font->next = this->r.fonts; this->r.fonts = font; n++; } closedir (dir); if (n) { *q = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "osd: found %d xine fonts in %s.\n", n, fontpath); } } data_dirs++; } } } this->r.textpalette = this->xine->config->register_enum (this->xine->config, "ui.osd.text_palette", 0, (char **)textpalettes_str, _("palette (foreground-border-background) to use for subtitles and OSD"), _("The palette for on-screen-display and some subtitle formats that do " "not specify any colouring themselves. The palettes are listed in the " "form: foreground-border-background."), 10, update_text_palette, &this->r); /* * set up function pointer */ this->r.new_object = osd_new_object; this->r.free_object = osd_free_object; this->r.show = osd_show_scaled; this->r.hide = osd_hide; this->r.set_palette = osd_set_palette; this->r.set_text_palette = osd_set_text_palette; this->r.get_palette = osd_get_palette; this->r.set_position = osd_set_position; this->r.set_font = osd_set_font; this->r.clear = osd_clear; this->r.point = osd_point; this->r.line = osd_line; this->r.filled_rect = osd_filled_rect; this->r.set_encoding = osd_set_encoding; this->r.render_text = osd_render_text; this->r.get_text_size = osd_get_text_size; this->r.close = osd_renderer_close; this->r.draw_bitmap = osd_draw_bitmap; this->r.set_argb_buffer = osd_set_argb_buffer; this->r.show_unscaled = osd_show_unscaled; this->r.get_capabilities = osd_get_capabilities; this->r.set_extent = osd_set_extent; this->r.set_video_window = osd_set_video_window; return &this->r; } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/demux.c����������������������������������������������������������������0000644�0001750�0001750�00000075667�14647725152�015174� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Demuxer helper functions * hide some xine engine details from demuxers and reduce code duplication */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <string.h> #include <pthread.h> #include <sched.h> #include <sys/time.h> #include <sys/types.h> #include <unistd.h> #include <errno.h> #define LOG_MODULE "demux" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include <xine/demux.h> #include <xine/buffer.h> #include "xine_private.h" #ifdef WIN32 #include <winsock.h> #endif /* * Flush audio and video buffers. It is called from demuxers on * seek/stop, and may be useful when user input changes a stream and * xine-lib has cached buffers that have yet to be played. * * warning: after clearing decoders fifos an absolute discontinuity * indication must be sent. relative discontinuities are likely * to cause "jumps" on metronom. */ void _x_demux_flush_engine (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_private_t *xine = (xine_private_t *)stream->s.xine; buf_element_t *buf; stream = stream->side_streams[0]; if (stream->gapless_switch || stream->finished_naturally) return; xine->port_ticket->acquire (xine->port_ticket, 1); /* only flush/discard output ports on master streams */ if (stream->s.master == &stream->s) { if (stream->s.video_out) { stream->s.video_out->set_property (stream->s.video_out, VO_PROP_DISCARD_FRAMES, 1); } if (stream->s.audio_out) { stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_DISCARD_BUFFERS, 1); } } stream->s.video_fifo->clear (stream->s.video_fifo); stream->s.audio_fifo->clear (stream->s.audio_fifo); pthread_mutex_lock (&stream->demux.pair); buf = stream->s.video_fifo->buffer_pool_alloc (stream->s.video_fifo); buf->type = BUF_CONTROL_RESET_DECODER; stream->s.video_fifo->put (stream->s.video_fifo, buf); buf = stream->s.audio_fifo->buffer_pool_alloc (stream->s.audio_fifo); buf->type = BUF_CONTROL_RESET_DECODER; stream->s.audio_fifo->put (stream->s.audio_fifo, buf); pthread_mutex_unlock (&stream->demux.pair); /* on seeking we must wait decoder fifos to process before doing flush. * otherwise we flush too early (before the old data has left decoders) */ _x_demux_control_headers_done (&stream->s); if (stream->s.video_out) { video_overlay_manager_t *ovl = stream->s.video_out->get_overlay_manager (stream->s.video_out); ovl->flush_events(ovl); } /* only flush/discard output ports on master streams */ if (stream->s.master == &stream->s) { if (stream->s.video_out) { stream->s.video_out->flush (stream->s.video_out); stream->s.video_out->set_property (stream->s.video_out, VO_PROP_DISCARD_FRAMES, 0); } if (stream->s.audio_out) { stream->s.audio_out->flush (stream->s.audio_out); stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_DISCARD_BUFFERS, 0); } } xine->port_ticket->release (xine->port_ticket, 1); } void _x_demux_control_newpts (xine_stream_t *s, int64_t pts, uint32_t flags) { xine_stream_private_t *stream = (xine_stream_private_t *)s; buf_element_t *bufa, *bufv; stream = stream->side_streams[0]; if (flags & BUF_FLAG_SEEK) { pthread_mutex_lock (&stream->demux.pair); if (stream->demux.max_seek_bufs == 0) { pthread_mutex_unlock (&stream->demux.pair); return; } stream->demux.max_seek_bufs--; pthread_mutex_unlock (&stream->demux.pair); } bufv = stream->s.video_fifo->buffer_pool_alloc (stream->s.video_fifo); bufa = stream->s.audio_fifo->buffer_pool_alloc (stream->s.audio_fifo); pthread_mutex_lock (&stream->demux.pair); bufv->type = BUF_CONTROL_NEWPTS; bufv->decoder_flags = flags; bufv->disc_off = pts; stream->s.video_fifo->put (stream->s.video_fifo, bufv); bufa->type = BUF_CONTROL_NEWPTS; bufa->decoder_flags = flags; bufa->disc_off = pts; stream->s.audio_fifo->put (stream->s.audio_fifo, bufa); pthread_mutex_unlock (&stream->demux.pair); } /* avoid ao_loop being stuck in a pthread_cond_wait, waiting for data; * return 1 if the stream is stopped * (better fix wanted!) */ static int demux_unstick_ao_loop (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; /* if (!stream->audio_thread_created) return 0; */ int status = xine_get_status (&stream->s); if (status != XINE_STATUS_QUIT && status != XINE_STATUS_STOP && stream->demux.plugin->get_status (stream->demux.plugin) != DEMUX_FINISHED) return 0; #if 0 /* right, stream is stopped... */ audio_buffer_t *buf = stream->s.audio_out->get_buffer (stream->s.audio_out); buf->num_frames = 0; buf->stream = NULL; stream->s.audio_out->put_buffer (stream->s.audio_out, buf, stream); #endif lprintf("stuck\n"); return 1; } /* sync with decoder fifos, making sure everything gets processed */ void _x_demux_control_headers_done (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; int headers_audio; int headers_video; unsigned int max_iterations; buf_element_t *buf_video, *buf_audio; stream = stream->side_streams[0]; /* we use demux.action_pending to wake up sleeping spu decoders */ _x_action_raise (&stream->s); /* allocate the buffers before grabbing the lock to prevent cyclic wait situations */ buf_video = stream->s.video_fifo->buffer_pool_alloc (stream->s.video_fifo); buf_audio = stream->s.audio_fifo->buffer_pool_alloc (stream->s.audio_fifo); pthread_mutex_lock (&stream->counter.lock); if (stream->video_thread_created) { headers_video = stream->counter.headers_video + 1; } else { headers_video = 0; } if (stream->audio_thread_created) { headers_audio = stream->counter.headers_audio + 1; } else { headers_audio = 0; } pthread_mutex_lock (&stream->demux.pair); buf_video->type = BUF_CONTROL_HEADERS_DONE; stream->s.video_fifo->put (stream->s.video_fifo, buf_video); buf_audio->type = BUF_CONTROL_HEADERS_DONE; stream->s.audio_fifo->put (stream->s.audio_fifo, buf_audio); pthread_mutex_unlock (&stream->demux.pair); max_iterations = 0; while ((stream->counter.headers_audio < headers_audio) || (stream->counter.headers_video < headers_video)) { struct timespec ts = {0, 0}; int ret_wait; lprintf ("waiting for headers. v:%d %d a:%d %d\n", stream->counter.headers_video, headers_video, stream->counter.headers_audio, headers_audio); xine_gettime (&ts); ts.tv_sec += 1; /* use timedwait to workaround buggy pthread broadcast implementations */ ret_wait = pthread_cond_timedwait (&stream->counter.changed, &stream->counter.lock, &ts); if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (&stream->s) && ++max_iterations > 4) { xine_log (stream->s.xine, XINE_LOG_MSG,_("Stuck in _x_demux_control_headers_done(). Taking the emergency exit\n")); stream->emergency_brake = 1; break; } } _x_action_lower (&stream->s); lprintf ("headers processed.\n"); pthread_mutex_unlock (&stream->counter.lock); } void _x_demux_control_start (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; buf_element_t *bufa, *bufv; uint32_t flags, id_flag; id_flag = stream->id_flag; stream = stream->side_streams[0]; /* if an _other_ side stream already sent this, skip our duplicate. * the _same_ side is supposed to know what it is doing (input_vdr). */ pthread_mutex_lock (&stream->demux.pair); if (stream->demux.start_buffers_sent & (~id_flag)) { pthread_mutex_unlock (&stream->demux.pair); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "demux: stream %p: skipping duplicate start buffers.\n", (void *)stream); return; } pthread_mutex_unlock (&stream->demux.pair); flags = (stream->gapless_switch || stream->finished_naturally) ? BUF_FLAG_GAPLESS_SW : 0; bufv = stream->s.video_fifo->buffer_pool_alloc (stream->s.video_fifo); bufa = stream->s.audio_fifo->buffer_pool_alloc (stream->s.audio_fifo); pthread_mutex_lock (&stream->demux.pair); bufv->type = BUF_CONTROL_START; bufv->decoder_flags = flags; stream->s.video_fifo->put (stream->s.video_fifo, bufv); bufa->type = BUF_CONTROL_START; bufa->decoder_flags = flags; stream->s.audio_fifo->put (stream->s.audio_fifo, bufa); stream->demux.start_buffers_sent |= id_flag; pthread_mutex_unlock (&stream->demux.pair); } void _x_demux_control_end (xine_stream_t *s, uint32_t flags) { xine_stream_private_t *stream = (xine_stream_private_t *)s; buf_element_t *bufa, *bufv; stream = stream->side_streams[0]; bufv = stream->s.video_fifo->buffer_pool_alloc (stream->s.video_fifo); bufa = stream->s.audio_fifo->buffer_pool_alloc (stream->s.audio_fifo); pthread_mutex_lock (&stream->demux.pair); bufv->type = BUF_CONTROL_END; bufv->decoder_flags = flags; stream->s.video_fifo->put (stream->s.video_fifo, bufv); bufa->type = BUF_CONTROL_END; bufa->decoder_flags = flags; stream->s.audio_fifo->put (stream->s.audio_fifo, bufa); pthread_mutex_unlock (&stream->demux.pair); } void _x_demux_control_nop (xine_stream_t *s, uint32_t flags ) { xine_stream_private_t *stream = (xine_stream_private_t *)s; buf_element_t *bufa, *bufv; stream = stream->side_streams[0]; bufv = stream->s.video_fifo->buffer_pool_alloc (stream->s.video_fifo); bufa = stream->s.audio_fifo->buffer_pool_alloc (stream->s.audio_fifo); pthread_mutex_lock (&stream->demux.pair); bufv->type = BUF_CONTROL_NOP; bufv->decoder_flags = flags; stream->s.video_fifo->put (stream->s.video_fifo, bufv); bufa->type = BUF_CONTROL_NOP; bufa->decoder_flags = flags; stream->s.audio_fifo->put (stream->s.audio_fifo, bufa); pthread_mutex_unlock (&stream->demux.pair); } static void *demux_loop (void *stream_gen) { xine_stream_private_t *stream = (xine_stream_private_t *)stream_gen; xine_stream_private_t *m = stream->side_streams[0]; int status; int non_user; int iterations = 0, seeks = 0; struct timespec seek_time = {0, 0}; lprintf ("loop starting...\n"); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "demux: starting stream %p.\n", (void *)stream); pthread_mutex_lock (&m->counter.lock); m->counter.demuxers_running++; pthread_mutex_unlock (&m->counter.lock); pthread_mutex_lock (&stream->demux.lock); m->emergency_brake = 0; /* do-while needed to seek after demux finished */ do { uint32_t input_caps = 0; xine_gettime (&seek_time); /* tell xine_play_internal () whether we can seek. * so it may flush fifos early, and suspend us faster. */ if (stream->s.input_plugin) input_caps = stream->s.input_plugin->get_capabilities (stream->s.input_plugin); pthread_mutex_lock (&stream->demux.action_lock); stream->demux.input_caps = input_caps; pthread_mutex_unlock (&stream->demux.action_lock); /* main demuxer loop */ status = stream->demux.plugin->get_status (stream->demux.plugin); while (status == DEMUX_OK && stream->demux.thread_running && !m->emergency_brake) { iterations++; status = stream->demux.plugin->send_chunk (stream->demux.plugin); if (!(iterations & 31)) { uint32_t new_caps = stream->s.input_plugin ? stream->s.input_plugin->get_capabilities (stream->s.input_plugin) : 0; if (new_caps != input_caps) { input_caps = new_caps; pthread_mutex_lock (&stream->demux.action_lock); stream->demux.input_caps = input_caps; pthread_mutex_unlock (&stream->demux.action_lock); } } /* someone may want to interrupt us */ if (stream->demux.action_pending > 0) { pthread_mutex_lock (&stream->demux.action_lock); if (stream->demux.action_pending > 0) { if (stream->s.input_plugin) stream->demux.input_caps = stream->s.input_plugin->get_capabilities (stream->s.input_plugin); pthread_mutex_unlock (&stream->demux.lock); do { pthread_cond_wait (&stream->demux.resume, &stream->demux.action_lock); } while (stream->demux.action_pending > 0); pthread_mutex_unlock (&stream->demux.action_lock); pthread_mutex_lock (&stream->demux.lock); xine_gettime (&seek_time); seeks++; } else { pthread_mutex_unlock (&stream->demux.action_lock); } } } lprintf ("main demuxer loop finished (status: %d)\n", status); /* let demux plugin do some needed cleanup */ if (stream->demux.plugin->get_capabilities (stream->demux.plugin) & DEMUX_CAP_STOP) stream->demux.plugin->get_optional_data (stream->demux.plugin, NULL, DEMUX_OPTIONAL_DATA_STOP); /* tell to the net_buf_ctrl that we are at the end of the stream * then the net_buf_ctrl will not pause */ _x_demux_control_nop (&stream->s, BUF_FLAG_END_STREAM); /* wait before sending end buffers: user might want to do a new seek */ while(stream->demux.thread_running && ((stream->s.video_fifo->size (stream->s.video_fifo)) || (stream->s.audio_fifo->size (stream->s.audio_fifo))) && status == DEMUX_FINISHED && !m->emergency_brake){ struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_nsec += 100000000; if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ts.tv_sec += 1; } pthread_cond_timedwait (&stream->demux.resume, &stream->demux.lock, &ts); status = stream->demux.plugin->get_status (stream->demux.plugin); } if (stream->demux.thread_running && (status == DEMUX_FINISHED)) do { struct timespec ts = {0, 0}; int delay_finish_event; xine_rwlock_rdlock (&stream->side_streams[0]->info_lock); delay_finish_event = stream->delay_finish_event; xine_rwlock_unlock (&stream->side_streams[0]->info_lock); if (delay_finish_event != 0) { xine_rwlock_wrlock (&stream->side_streams[0]->info_lock); stream->delay_finish_event = 0; xine_rwlock_unlock (&stream->side_streams[0]->info_lock); xine_gettime (&ts); if (delay_finish_event > 0) { /* delay sending finished event - used for image presentations */ ts.tv_sec += delay_finish_event / 10; ts.tv_nsec += (delay_finish_event % 10) * 100000000; if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ts.tv_sec += 1; } } else /* delay_finish_event < 0 */ { /* infinitely delay sending finished event - used for image presentations */ do { ts.tv_sec += 1; pthread_cond_timedwait (&stream->demux.resume, &stream->demux.lock, &ts); status = stream->demux.plugin->get_status (stream->demux.plugin); } while (stream->demux.thread_running && (status == DEMUX_FINISHED)); break; } } else { /* there may be no first frame at all here. * make sure xine_play returns first. */ pthread_mutex_lock (&m->first_frame.lock); if (m->first_frame.flag) { m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); pthread_mutex_unlock (&m->first_frame.lock); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "demux: unblocked xine_play_internal ().\n"); } else { pthread_mutex_unlock (&m->first_frame.lock); } /* stream end may well happen during xine_play () (seek close to end). * Lets not confuse frontend, and delay that message a bit. */ ts = seek_time; ts.tv_nsec += 300000000; if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ts.tv_sec += 1; } xine_gettime (&seek_time); if (seek_time.tv_sec > ts.tv_sec) break; if ((seek_time.tv_sec == ts.tv_sec) && (seek_time.tv_nsec >= ts.tv_nsec)) break; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "demux: very short seek segment, delaying finish message.\n"); } do { int e = pthread_cond_timedwait (&stream->demux.resume, &stream->demux.lock, &ts); status = stream->demux.plugin->get_status (stream->demux.plugin); if (e == ETIMEDOUT) break; } while (stream->demux.thread_running && (status == DEMUX_FINISHED)); } while (0); } while (status == DEMUX_OK && stream->demux.thread_running && !m->emergency_brake); lprintf ("loop finished (status: %d)\n", status); /* demux.thread_running is zero if demux loop has been stopped by user */ non_user = stream->demux.thread_running; stream->demux.thread_running = 0; /* do stream end stuff only if this is the last side stream. */ { unsigned int n; pthread_mutex_lock (&m->counter.lock); n = --(m->counter.demuxers_running); if (n == 0) { int finisheds_audio = 0; int finisheds_video = 0; if (m->audio_thread_created) finisheds_audio = m->counter.finisheds_audio + 1; if (m->video_thread_created) finisheds_video = m->counter.finisheds_video + 1; pthread_mutex_unlock (&m->counter.lock); _x_demux_control_end (&m->s, non_user); lprintf ("loop finished, end buffer sent\n"); pthread_mutex_unlock (&stream->demux.lock); pthread_mutex_lock (&m->counter.lock); n = 0; while ((m->counter.finisheds_audio < finisheds_audio) || (m->counter.finisheds_video < finisheds_video)) { int ret_wait; struct timespec ts = {0, 0}; lprintf ("waiting for finisheds.\n"); xine_gettime (&ts); ts.tv_sec += 1; ret_wait = pthread_cond_timedwait (&m->counter.changed, &m->counter.lock, &ts); if (ret_wait == ETIMEDOUT && demux_unstick_ao_loop (&m->s) && ++n > 4) { xine_log (m->s.xine, XINE_LOG_MSG,_("Stuck in demux_loop(). Taking the emergency exit\n")); m->emergency_brake = 1; break; } } pthread_mutex_unlock (&m->counter.lock); _x_handle_stream_end (&m->s, non_user); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "demux: %s last stream %p after %d iterations and %d seeks.\n", non_user ? "finished" : "stopped", (void *)stream, iterations, seeks); } else { pthread_mutex_unlock (&m->counter.lock); pthread_mutex_unlock (&stream->demux.lock); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "demux: %s stream %p after %d iterations and %d seeks.\n", non_user ? "finished" : "stopped", (void *)stream, iterations, seeks); } } return NULL; } int _x_demux_called_from (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; if (!stream->demux.thread_running) return 0; return pthread_equal (pthread_self (), stream->demux.thread); } int _x_demux_start_thread (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; int err; lprintf ("start thread called\n"); _x_action_raise (&stream->s); pthread_mutex_lock (&stream->demux.lock); _x_action_lower (&stream->s); if (!stream->demux.thread_running) { if (stream->demux.thread_created) { void *p; pthread_join (stream->demux.thread, &p); } stream->demux.thread_running = 1; stream->demux.thread_created = 1; if ((err = pthread_create (&stream->demux.thread, NULL, demux_loop, (void *)stream)) != 0) { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, "demux: can't create new thread (%s)\n", strerror(err)); stream->demux.thread_running = 0; stream->demux.thread_created = 0; pthread_mutex_unlock (&stream->demux.lock); return -1; } } pthread_mutex_unlock (&stream->demux.lock); return 0; } int _x_demux_stop_thread (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; void *p; lprintf ("stop thread called\n"); _x_action_raise (&stream->s); pthread_mutex_lock (&stream->demux.lock); stream->demux.thread_running = 0; _x_action_lower (&stream->s); /* At that point, the demuxer has sent the last audio/video buffer, * so it's a safe place to flush the engine. */ _x_demux_flush_engine (&stream->s); pthread_mutex_unlock (&stream->demux.lock); lprintf ("joining thread\n" ); if (stream->demux.thread_created) { pthread_join (stream->demux.thread, &p); stream->demux.thread_created = 0; } /* * Wake up xine_play if it's waiting for a frame */ { xine_stream_private_t *m = stream->side_streams[0]; pthread_mutex_lock (&m->first_frame.lock); if (m->first_frame.flag) { m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); } pthread_mutex_unlock (&m->first_frame.lock); } return 0; } int _x_demux_read_stream_header (xine_stream_t *stream, input_plugin_t *input, void *buffer, size_t size) { xine_stream_private_t *s = (xine_stream_private_t *)stream; int want_size = size; uint32_t caps; if (!input || !buffer || (want_size <= 0)) return 0; caps = input->get_capabilities (input); if ((caps & INPUT_CAP_SIZED_PREVIEW) && (want_size >= (int)sizeof (want_size))) { memcpy (buffer, &want_size, sizeof (want_size)); return input->get_optional_data (input, buffer, INPUT_OPTIONAL_DATA_SIZED_PREVIEW); } if (caps & INPUT_CAP_SEEKABLE) { int start = 0; if (s && (s->id3v2_tag_size >= 0)) start = s->id3v2_tag_size; if (input->seek (input, start, SEEK_SET) != start) return 0; want_size = input->read (input, buffer, want_size); if (input->seek (input, start, SEEK_SET) != start) return 0; /* no point to continue any further */ if (want_size <= 0) return 0; return want_size; } if (caps & INPUT_CAP_PREVIEW) { if (want_size < MAX_PREVIEW_SIZE) { int read_size; uint8_t *temp = malloc (MAX_PREVIEW_SIZE); if (!temp) return 0; read_size = input->get_optional_data (input, temp, INPUT_OPTIONAL_DATA_PREVIEW); if (read_size <= 0) { free (temp); return 0; } if (read_size < want_size) want_size = read_size; memcpy (buffer, temp, want_size); free (temp); return want_size; } return input->get_optional_data (input, buffer, INPUT_OPTIONAL_DATA_PREVIEW); } return 0; } int _x_demux_read_header (input_plugin_t *input, void *buffer, off_t size) { return _x_demux_read_stream_header (NULL, input, buffer, size); } int _x_demux_check_extension (const char *mrl, const char *extensions){ char *last_dot, *e, *ext_copy, *ext_work; int found = 0; /* An empty extensions string means that the by-extension method can't be used, so consider those cases as always passing. */ if ( extensions == NULL ) return 1; ext_copy = strdup(extensions); ext_work = ext_copy; last_dot = strrchr (mrl, '.'); if (last_dot) { last_dot++; } while ( ( e = xine_strsep(&ext_work, " ")) != NULL ) { if ( strstr(e, ":/") ) { if ( strncasecmp (mrl, e, strlen (e)) == 0 ) { found = 1; break; } } else if (last_dot) { if (strcasecmp (last_dot, e) == 0) { found = 1; break; } } } free(ext_copy); return found; } /* * read from socket/file descriptor checking demux.action_pending * * network input plugins should use this function in order to * not freeze the engine. * * aborts with zero if no data is available and demux.action_pending is set */ off_t _x_read_abort (xine_stream_t *stream, int fd, char *buf, off_t todo) { size_t have, left; if (todo <= 0) return 0; left = todo; have = 0; while (left) { while (1) { fd_set rset; struct timeval timeout; FD_ZERO (&rset); FD_SET (fd, &rset); timeout.tv_sec = 0; timeout.tv_usec = 50000; if (select (fd + 1, &rset, NULL, NULL, &timeout) > 0) break; /* aborts current read if action pending. otherwise xine * cannot be stopped when no more data is available. */ if (_x_action_pending (stream)) return have; } { ssize_t r; #ifndef WIN32 r = read (fd, buf + have, left); if (r <= 0) { if (r == 0) /* EOF */ break; if (errno == EAGAIN) continue; perror ("_x_read_abort"); return r; } #else r = recv (fd, buf + have, left, 0); if (r <= 0) { perror ("_x_read_abort"); return r; } #endif have += r; left -= r; } } return have; } int _x_action_pending (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; int a; if (!stream) return 0; a = stream->demux.action_pending & 0xffff; if (a) { /* On seek, xine_play_internal () sets this, waits for demux to stop, * grabs demux lock, resets this again, performs the seek, and finally * unlocks demux. Due to per processor core L1 data caches, demux may * still see this set for some time, and abort input for no real reason. * Avoid that trap by checking again with lock here. */ pthread_mutex_lock (&stream->demux.action_lock); a = stream->demux.action_pending & 0xffff; pthread_mutex_unlock (&stream->demux.action_lock); } return a; } /* set demux.action_pending in a thread-safe way */ void _x_action_raise (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; pthread_mutex_lock (&stream->demux.action_lock); stream->demux.action_pending += 0x10001; pthread_mutex_unlock (&stream->demux.action_lock); } /* reset demux.action_pending in a thread-safe way */ void _x_action_lower (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; pthread_mutex_lock (&stream->demux.action_lock); stream->demux.action_pending -= 0x10001; if (stream->demux.action_pending <= 0) pthread_cond_signal (&stream->demux.resume); pthread_mutex_unlock (&stream->demux.action_lock); } /* * demuxer helper function to send data to fifo, breaking into smaller * pieces (bufs) as needed. * * it has quite some parameters, but only the first 6 are needed. * * the other ones help enforcing that demuxers provide the information * they have about the stream, so things like the GUI slider bar can * work as expected. */ void _x_demux_send_data(fifo_buffer_t *fifo, uint8_t *data, int size, int64_t pts, uint32_t type, uint32_t decoder_flags, int input_normpos, int input_time, int total_time, uint32_t frame_number) { buf_element_t *buf; decoder_flags |= BUF_FLAG_FRAME_START; _x_assert(size > 0); while (fifo && size > 0) { buf = fifo->buffer_pool_size_alloc (fifo, size); if ( size > buf->max_size ) { buf->size = buf->max_size; buf->decoder_flags = decoder_flags; } else { buf->size = size; buf->decoder_flags = BUF_FLAG_FRAME_END | decoder_flags; } decoder_flags &= ~BUF_FLAG_FRAME_START; xine_fast_memcpy (buf->content, data, buf->size); data += buf->size; size -= buf->size; buf->pts = pts; pts = 0; buf->extra_info->input_normpos = input_normpos; buf->extra_info->input_time = input_time; buf->extra_info->total_time = total_time; buf->extra_info->frame_number = frame_number; buf->type = type; fifo->put (fifo, buf); } } /* * Analogous to above, but reads data from input plugin * * If reading fails, -1 is returned */ int _x_demux_read_send_data(fifo_buffer_t *fifo, input_plugin_t *input, int size, int64_t pts, uint32_t type, uint32_t decoder_flags, off_t input_normpos, int input_time, int total_time, uint32_t frame_number) { buf_element_t *buf; decoder_flags |= BUF_FLAG_FRAME_START; _x_assert(size > 0); while (fifo && size > 0) { buf = fifo->buffer_pool_size_alloc (fifo, size); if ( size > buf->max_size ) { buf->size = buf->max_size; buf->decoder_flags = decoder_flags; } else { buf->size = size; buf->decoder_flags = BUF_FLAG_FRAME_END | decoder_flags; } decoder_flags &= ~BUF_FLAG_FRAME_START; if(input->read(input, buf->content, buf->size) < buf->size) { buf->free_buffer(buf); return -1; } size -= buf->size; buf->pts = pts; pts = 0; buf->extra_info->input_normpos = input_normpos; buf->extra_info->input_time = input_time; buf->extra_info->total_time = total_time; buf->extra_info->frame_number = frame_number; buf->type = type; fifo->put (fifo, buf); } return 0; } /* * Helper function for sending MRL reference events */ void _x_demux_send_mrl_reference (xine_stream_t *stream, int alternative, const char *mrl, const char *title, int start_time, int duration) { xine_event_t event; union { xine_mrl_reference_data_ext_t *e; XINE_DISABLE_DEPRECATION_WARNINGS xine_mrl_reference_data_t *b; XINE_ENABLE_DEPRECATION_WARNINGS } data; const size_t mrl_len = strlen (mrl); if (!title) title = ""; /* extended MRL reference event */ event.stream = stream; event.data_length = offsetof (xine_mrl_reference_data_ext_t, mrl) + mrl_len + strlen (title) + 2; data.e = event.data = malloc (event.data_length); data.e->alternative = alternative; data.e->start_time = start_time; data.e->duration = duration; strcpy((char *)data.e->mrl, mrl); strcpy((char *)data.e->mrl + mrl_len + 1, title); event.type = XINE_EVENT_MRL_REFERENCE_EXT; xine_event_send (stream, &event); /* plain MRL reference event */ XINE_DISABLE_DEPRECATION_WARNINGS event.data_length = offsetof (xine_mrl_reference_data_t, mrl) + mrl_len + 1; XINE_ENABLE_DEPRECATION_WARNINGS /*data.b->alternative = alternative;*/ strcpy (data.b->mrl, mrl); event.type = XINE_EVENT_MRL_REFERENCE; xine_event_send (stream, &event); free (data.e); } int _x_demux_seek (xine_stream_t *s, off_t start_pos, int start_time, int playing) { xine_stream_private_t *stream = (xine_stream_private_t *)s; int ret = -1; pthread_mutex_lock (&stream->side_streams[0]->frontend_lock); if (stream->demux.plugin) ret = stream->demux.plugin->seek (stream->demux.plugin, start_pos, start_time, playing); pthread_mutex_unlock (&stream->side_streams[0]->frontend_lock); return ret; } �������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/spu.c������������������������������������������������������������������0000644�0001750�0001750�00000010666�14647725152�014645� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2007-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <xine/configfile.h> #include <xine/xine_internal.h> #include <xine/spu.h> #include <xine.h> #include "xine_private.h" #define BLACK_OPACITY 67 #define COLOUR_OPACITY 100 static void _spu_dvbsub_make_tab (xine_private_t *xine) { uint32_t u, black = xine->dvbsub.black, color = xine->dvbsub.color, _b, _c; if (black > 100) xine->dvbsub.black = black = BLACK_OPACITY; if (color > 100) xine->dvbsub.color = color = COLOUR_OPACITY; black = (15u * (1u << 20) * black + 12750u) / 25500u; color = (15u * (1u << 20) * color + 12750u) / 25500u; for (_b = 255 * black, _c = 255 * color, u = 0; u < 256 * 2; _b -= black, _c -= color, u += 2) { xine->dvbsub.tab[u] = (_b + (1 << 19)) >> 20; xine->dvbsub.tab[u + 1] = (_c + (1 << 19)) >> 20; } xine->dvbsub.gen++; } static void _spu_dvbsub_set_black (void *data, xine_cfg_entry_t *entry) { xine_private_t *xine = (xine_private_t *)data; xine->dvbsub.black = entry->num_value; _spu_dvbsub_make_tab (xine); } static void _spu_dvbsub_set_color (void *data, xine_cfg_entry_t *entry) { xine_private_t *xine = (xine_private_t *)data; xine->dvbsub.color = entry->num_value; _spu_dvbsub_make_tab (xine); } void _x_spu_misc_init (xine_t *this) { xine_private_t *xine = (xine_private_t *)this; if (xine) { xine->dvbsub.black = xine->x.config->register_range (xine->x.config, "subtitles.bitmap.black_opacity", BLACK_OPACITY, 0, 100, _("opacity for the black parts of bitmapped subtitles"), NULL, 10, _spu_dvbsub_set_black, xine); xine->dvbsub.color = xine->x.config->register_range (xine->x.config, "subtitles.bitmap.colour_opacity", COLOUR_OPACITY, 0, 100, _("opacity for the colour parts of bitmapped subtitles"), NULL, 10, _spu_dvbsub_set_color, xine); xine->dvbsub.gen = 0; _spu_dvbsub_make_tab (xine); } } void _x_spu_get_opacity (xine_t *this, xine_spu_opacity_t *opacity) { xine_private_t *xine = (xine_private_t *)this; if (xine && opacity) { opacity->black = xine->dvbsub.black; opacity->colour = xine->dvbsub.color; } } int _x_spu_calculate_opacity (const clut_t *clut, uint8_t trans, const xine_spu_opacity_t *opacity) { int value = (clut->y == 0 || (clut->y == 16 && clut->cb == 128 && clut->cr == 128)) ? opacity->black : opacity->colour; return value * (255 - trans) / 100; } typedef union { clut_t c; uint32_t w; } clut_union_t; void _x_spu_dvb_opacity (xine_t *this, uint8_t *opacity, const clut_t *clut, int *gen, uint32_t n) { xine_private_t *xine = (xine_private_t *)this; const union {uint32_t v; uint8_t b;} endian = {1}; const clut_union_t *dummy = (const clut_union_t *)0, mask_y_cr_cb = {.c = {.y = 255, .cr = 255, .cb = 255}}, black = {.c = {.y = 16, .cr = 128, .cb = 128}}; const uint32_t shift_y = endian.b ? 24 - ((const uint8_t *)&dummy->c.y - (const uint8_t *)dummy) * 8 : ((const uint8_t *)&dummy->c.y - (const uint8_t *)dummy) * 8; int _gen = 0; uint32_t u; if (!xine || !opacity || !clut) return; if (!gen) gen = &_gen; if (*gen == xine->dvbsub.gen) return; *gen = xine->dvbsub.gen; for (u = 0; u < n; u++) { clut_union_t v; uint32_t mask; v.c = clut[u]; /* ETSI-300-743 says "full transparency if Y == 0". * This is used to cut off currently unused parts of a region. */ /* mask = v.c.y ? ~0u : 0u; */ mask = (int32_t)(((v.w << shift_y >> 1) | 0x80000000) - 0x00800000) >> 31; opacity[u] = xine->dvbsub.tab[2 * v.c.foo + ((v.w & mask_y_cr_cb.w) != black.w)] & mask; } } ��������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/alphablend.c�����������������������������������������������������������0000644�0001750�0001750�00000204165�14647725152�016127� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 * * Copyright (C) 2000 Thomas Mirlacher * 2002-2013 the xine project * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA. * *------------------------------------------------------------ * */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* #define LOG_BLEND_YUV #define LOG_BLEND_RGB16 */ #include <string.h> #include <stdlib.h> #include <stdio.h> #include <xine/xine_internal.h> #include <xine/video_out.h> #include <xine/alphablend.h> #include "bswap.h" #define BLEND_COLOR(dst, src, mask, o) ((((((src&mask)-(dst&mask))*(o*0x111+1))>>12)+(dst&mask))&mask) #define BLEND_BYTE(dst, src, o) (((((src)-(dst))*(o*0x1111+1))>>16)+(dst)) static void mem_blend8(uint8_t *mem, uint8_t val, uint8_t o, size_t sz) { uint8_t *limit = mem + sz; while (mem < limit) { *mem = BLEND_BYTE(*mem, val, o); mem++; } } static void mem_blend16(uint16_t *mem, uint16_t clr, uint8_t o, int len) { uint16_t *limit = mem + len; while (mem < limit) { *mem = BLEND_COLOR(*mem, clr, 0xf800, o) | BLEND_COLOR(*mem, clr, 0x07e0, o) | BLEND_COLOR(*mem, clr, 0x001f, o); mem++; } } static void mem_blend24(uint8_t *mem, uint8_t r, uint8_t g, uint8_t b, uint8_t o, int len) { uint8_t *limit = mem + len*3; while (mem < limit) { *mem = BLEND_BYTE(*mem, r, o); mem++; *mem = BLEND_BYTE(*mem, g, o); mem++; *mem = BLEND_BYTE(*mem, b, o); mem++; } } static void mem_blend32(uint8_t *mem, const uint8_t *src, uint8_t o, int len) { uint8_t *limit = mem + len*4; while (mem < limit) { *mem = BLEND_BYTE(*mem, src[0], o); mem++; *mem = BLEND_BYTE(*mem, src[1], o); mem++; *mem = BLEND_BYTE(*mem, src[2], o); mem++; *mem = BLEND_BYTE(*mem, src[3], o); mem++; } } /* * Some macros for fixed point arithmetic. * * The blend_rgb* routines perform rle image scaling using * scale factors that are expressed as integers scaled with * a factor of 2**16. * * INT_TO_SCALED()/SCALED_TO_INT() converts from integer * to scaled fixed point and back. */ #define SCALE_SHIFT 16 #define SCALE_FACTOR (1<<SCALE_SHIFT) #define INT_TO_SCALED(i) ((i) << SCALE_SHIFT) #define SCALED_TO_INT(sc) ((sc) >> SCALE_SHIFT) static rle_elem_t * rle_img_advance_line(rle_elem_t *rle, rle_elem_t *rle_limit, int w) { int x; for (x = 0; x < w && rle < rle_limit; ) { x += rle->len; rle++; } return rle; } /* * heck, this function is overly complicated and currently buggy. * if James would like to revive it (implementing proper clipping - * not to confuse with button highlight) i would have no objections, * but for now i will be using an alternate version based on rgb24. [MF] * * obs: this function has about 420 lines. other blend_rgb16 has 165. */ #if JAMES_BLEND_RGB16_FUNCTION void blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, int dst_width, int dst_height, alphablend_t *extra_data) { uint8_t *trans; clut_t *clut; int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; rle_elem_t *rle_start = img_overl->rle; rle_elem_t *rle_limit = rle + img_overl->num_rle; int x_off = img_overl->x + extra_data->offset_x; int y_off = img_overl->y + extra_data->offset_y; int x, y, x1_scaled, x2_scaled; int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */ int clip_right, clip_left, clip_top; int hili_right, hili_left; uint16_t *img_pix; int rlelen; int rle_this_bite; int rle_remainder; int zone_state=0; uint8_t clr_next,clr; uint16_t o; double img_offset; int stripe_height; /* * Let zone_state keep state. * 0 = Starting. * 1 = Above button. * 2 = Left of button. * 3 = Inside of button. * 4 = Right of button. * 5 = Below button. * 6 = Finished. * * Each time round the loop, update the state. * We can do this easily and cheaply(fewer IF statements per cycle) as we are testing rle end position anyway. * Possible optimization is to ensure that rle never overlaps from outside to inside a button. * Possible optimization is to pre-scale the RLE overlay, so that no scaling is needed here. */ #ifdef LOG_BLEND_RGB16 printf("blend_rgb16: img_height=%i, dst_height=%i\n", img_height, dst_height); printf("blend_rgb16: img_width=%i, dst_width=%i\n", img_width, dst_width); if (img_width & 1) { printf("blend_rgb16s: odd\n");} else { printf("blend_rgb16s: even\n");} #endif /* stripe_height is used in yuv2rgb scaling, so use the same scale factor here for overlays. */ stripe_height = 16 * img_height / dst_height; /* dy_step = INT_TO_SCALED(dst_height) / img_height; */ dy_step = INT_TO_SCALED(16) / stripe_height; x_scale = INT_TO_SCALED(img_width) / dst_width; #ifdef LOG_BLEND_RGB16 printf("blend_rgb16: dy_step=%i, x_scale=%i\n", dy_step, x_scale); #endif if (img_width & 1) img_width++; img_offset = ( ( (y_off * img_height) / dst_height) * img_width) + ( (x_off * img_width) / dst_width); #ifdef LOG_BLEND_RGB16 printf("blend_rgb16: x=%i, y=%i, w=%i, h=%i, img_offset=%lf\n", img_overl->x, img_overl->y, img_overl->width, img_overl->height, img_offset); #endif img_pix = (uint16_t *) img + (int)img_offset; /* + (y_off * img_height / dst_height) * img_width + (x_off * img_width / dst_width); */ /* checks to avoid drawing overlay outside the destination buffer */ if( (x_off + src_width) <= dst_width ) clip_right = src_width; else clip_right = dst_width - x_off; if( x_off >= 0 ) clip_left = 0; else clip_left = -x_off; if( y_off >= 0 ) clip_top = 0; else clip_top = -y_off; if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; /* make highlight area fit into clip area */ if( img_overl->hili_right <= clip_right ) hili_right = img_overl->hili_right; else hili_right = clip_right; if( img_overl->hili_left >= clip_left ) hili_left = img_overl->hili_left; else hili_left = clip_left; rlelen = rle_remainder = rle_this_bite = 0; rle_remainder = rlelen = rle->len; clr_next = rle->color; rle++; y = dy = 0; x = x1_scaled = x2_scaled = 0; #ifdef LOG_BLEND_RGB16 printf("blend_rgb16 started\n"); #endif while (zone_state != 6) { clr = clr_next; switch (zone_state) { case 0: /* Starting */ /* FIXME: Get libspudec to set hili_top to -1 if no button */ if (img_overl->hili_top < 0) { #ifdef LOG_BLEND_RGB16 printf("blend_rgb16: No button highlight area\n"); #endif zone_state = 7; break; } #ifdef LOG_BLEND_RGB16 printf("blend_rgb16: Button highlight area found. (%d,%d) .. (%d,%d)\n", img_overl->hili_left, img_overl->hili_top, img_overl->hili_right, img_overl->hili_bottom); #endif if (y < img_overl->hili_top) { zone_state = 1; break; } else if (y >= img_overl->hili_bottom) { zone_state = 5; break; } else if (x < hili_left) { zone_state = 2; break; } else if (x >= hili_right) { zone_state = 4; break; } else { zone_state = 3; break; } break; case 1: /* Above highlight area */ clut = (clut_t*) img_overl->color; trans = img_overl->trans; o = trans[clr]; rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; /*printf("(x,y) = (%03i,%03i), clr=%03x, len=%03i, zone=%i\n", x, y, clr, rle_this_bite, zone_state); */ if (o) { x1_scaled = SCALED_TO_INT( x * x_scale ); x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale); mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled); } x += rle_this_bite; if (x >= src_width ) { x -= src_width; img_pix += img_width; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } rle_start = rle; } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } } rle_remainder = rlelen = rle->len; clr_next = rle->color; rle++; if (rle >= rle_limit) { zone_state = 6; } if (y >= img_overl->hili_top) { zone_state = 2; #ifdef LOG_BLEND_RGB16 printf("blend_rgb16: Button highlight top reached. y=%i, top=%i\n", y, img_overl->hili_top); #endif if (x >= hili_left) { zone_state = 3; if (x >= hili_right) { zone_state = 4; } } } break; case 2: /* Left of button */ clut = (clut_t*) img_overl->color; trans = img_overl->trans; o = trans[clr]; if (x + rle_remainder <= hili_left) { rle_this_bite = rle_remainder; rle_remainder = rlelen = rle->len; clr_next = rle->color; rle++; } else { rle_this_bite = hili_left - x; rle_remainder -= rle_this_bite; zone_state = 3; } if (o) { x1_scaled = SCALED_TO_INT( x * x_scale ); x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale); mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled); } x += rle_this_bite; if (x >= src_width ) { x -= src_width; img_pix += img_width; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } rle_start = rle; } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } if (y >= img_overl->hili_bottom) { zone_state = 5; break; } } if (rle >= rle_limit) { zone_state = 6; } break; case 3: /* In button */ clut = (clut_t*) img_overl->hili_color; trans = img_overl->hili_trans; o = trans[clr]; if (x + rle_remainder <= hili_right) { rle_this_bite = rle_remainder; rle_remainder = rlelen = rle->len; clr_next = rle->color; rle++; } else { rle_this_bite = hili_right - x; rle_remainder -= rle_this_bite; zone_state = 4; } if (o) { x1_scaled = SCALED_TO_INT( x * x_scale ); x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale); mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled); } x += rle_this_bite; if (x >= src_width ) { x -= src_width; img_pix += img_width; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } rle_start = rle; } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } if (y >= img_overl->hili_bottom) { zone_state = 5; break; } } if (rle >= rle_limit) { zone_state = 6; } break; case 4: /* Right of button */ clut = (clut_t*) img_overl->color; trans = img_overl->trans; o = trans[clr]; if (x + rle_remainder <= src_width) { rle_this_bite = rle_remainder; rle_remainder = rlelen = rle->len; clr_next = rle->color; rle++; } else { rle_this_bite = src_width - x; rle_remainder -= rle_this_bite; zone_state = 2; } if (o) { x1_scaled = SCALED_TO_INT( x * x_scale ); x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale); mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled); } x += rle_this_bite; if (x >= src_width ) { x -= src_width; img_pix += img_width; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } rle_start = rle; } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } if (y >= img_overl->hili_bottom) { zone_state = 5; break; } } if (rle >= rle_limit) { zone_state = 6; } break; case 5: /* Below button */ clut = (clut_t*) img_overl->color; trans = img_overl->trans; o = trans[clr]; rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; if (o) { x1_scaled = SCALED_TO_INT( x * x_scale ); x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale); mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled); } x += rle_this_bite; if (x >= src_width ) { x -= src_width; img_pix += img_width; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } rle_start = rle; } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } } rle_remainder = rlelen = rle->len; clr_next = rle->color; rle++; if (rle >= rle_limit) { zone_state = 6; } break; case 6: /* Finished */ _x_abort(); case 7: /* No button */ clut = (clut_t*) img_overl->color; trans = img_overl->trans; o = trans[clr]; rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; if (o) { x1_scaled = SCALED_TO_INT( x * x_scale ); x2_scaled = SCALED_TO_INT( (x + rle_this_bite) * x_scale); mem_blend16(img_pix+x1_scaled, *((uint16_t *)&clut[clr]), o, x2_scaled-x1_scaled); } x += rle_this_bite; if (x >= src_width ) { x -= src_width; img_pix += img_width; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } rle_start = rle; } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } } rle_remainder = rlelen = rle->len; clr_next = rle->color; rle++; if (rle >= rle_limit) { zone_state = 6; } break; default: ; } } #ifdef LOG_BLEND_RGB16 printf("blend_rgb16 ended\n"); #endif } #endif void _x_blend_rgb16 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, int dst_width, int dst_height, alphablend_t *extra_data) { int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; rle_elem_t *rle_limit = rle + img_overl->num_rle; int x_off = img_overl->x + extra_data->offset_x; int y_off = img_overl->y + extra_data->offset_y; int x, y, x1_scaled, x2_scaled; int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */ int hili_right, hili_left; int clip_right, clip_left, clip_top; uint8_t *img_pix; dy_step = INT_TO_SCALED(dst_height) / img_height; x_scale = INT_TO_SCALED(img_width) / dst_width; img_pix = img + 2 * ( (y_off * img_height / dst_height) * img_width + (x_off * img_width / dst_width)); /* checks to avoid drawing overlay outside the destination buffer */ if( (x_off + src_width) <= dst_width ) clip_right = src_width; else clip_right = dst_width - x_off; if( x_off >= 0 ) clip_left = 0; else clip_left = -x_off; if( y_off >= 0 ) clip_top = 0; else clip_top = -y_off; if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; /* make highlight area fit into clip area */ if( img_overl->hili_right <= clip_right ) hili_right = img_overl->hili_right; else hili_right = clip_right; if( img_overl->hili_left >= clip_left ) hili_left = img_overl->hili_left; else hili_left = clip_left; for (dy = y = 0; y < src_height && rle < rle_limit; ) { int mask = !(y < img_overl->hili_top || y >= img_overl->hili_bottom); rle_elem_t *rle_start = rle; int rlelen = 0; uint8_t clr = 0; for (x = x1_scaled = 0; x < src_width;) { int rle_bite; uint32_t *colors; uint8_t *trans; uint16_t o; int clipped = (y < clip_top); /* take next element from rle list everytime an element is finished */ if (rlelen <= 0) { if (rle >= rle_limit) break; rlelen = rle->len; clr = rle->color; rle++; } if (!mask) { /* above or below highlight area */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } else { /* treat cases where highlight border is inside rle->len pixels */ if ( x < hili_left ) { /* starts left */ if( x + rlelen > hili_left ) { /* ends not left */ /* choose the largest "bite" up to palette change */ rle_bite = hili_left - x; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } else { /* ends left */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } if( x < clip_left ) clipped = 1; } else if( x + rlelen > hili_right ) { /* ends right */ if( x < hili_right ) { /* starts not right */ /* choose the largest "bite" up to palette change */ rle_bite = hili_right - x; /* we're in the center area so choose highlight palette */ colors = img_overl->hili_color; trans = img_overl->hili_trans; } else { /* starts right */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; if( x + rle_bite >= clip_right ) clipped = 1; } } else { /* starts not left and ends not right */ rle_bite = rlelen; /* we're in the center area so choose highlight palette */ colors = img_overl->hili_color; trans = img_overl->hili_trans; } } x2_scaled = SCALED_TO_INT((x + rle_bite) * x_scale); o = trans[clr]; if (o && !clipped) { mem_blend16((uint16_t *) (img_pix + x1_scaled*2), *((uint16_t *)&colors[clr]), o, x2_scaled-x1_scaled); } x1_scaled = x2_scaled; x += rle_bite; rlelen -= rle_bite; } img_pix += img_width * 2; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } } } void _x_blend_rgb24 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, int dst_width, int dst_height, alphablend_t *extra_data) { int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; rle_elem_t *rle_limit = rle + img_overl->num_rle; int x_off = img_overl->x + extra_data->offset_x; int y_off = img_overl->y + extra_data->offset_y; int x, y, x1_scaled, x2_scaled; int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */ int hili_right, hili_left; int clip_right, clip_left, clip_top; uint8_t *img_pix; dy_step = INT_TO_SCALED(dst_height) / img_height; x_scale = INT_TO_SCALED(img_width) / dst_width; img_pix = img + 3 * ( (y_off * img_height / dst_height) * img_width + (x_off * img_width / dst_width)); /* checks to avoid drawing overlay outside the destination buffer */ if( (x_off + src_width) <= dst_width ) clip_right = src_width; else clip_right = dst_width - x_off; if( x_off >= 0 ) clip_left = 0; else clip_left = -x_off; if( y_off >= 0 ) clip_top = 0; else clip_top = -y_off; if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; /* make highlight area fit into clip area */ if( img_overl->hili_right <= clip_right ) hili_right = img_overl->hili_right; else hili_right = clip_right; if( img_overl->hili_left >= clip_left ) hili_left = img_overl->hili_left; else hili_left = clip_left; for (dy = y = 0; y < src_height && rle < rle_limit; ) { int mask = !(y < img_overl->hili_top || y >= img_overl->hili_bottom); rle_elem_t *rle_start = rle; int rlelen = 0; uint8_t clr = 0; for (x = x1_scaled = 0; x < src_width;) { int rle_bite; uint32_t *colors; uint8_t *trans; uint16_t o; int clipped = (y < clip_top); /* take next element from rle list everytime an element is finished */ if (rlelen <= 0) { if (rle >= rle_limit) break; rlelen = rle->len; clr = rle->color; rle++; } if (!mask) { /* above or below highlight area */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } else { /* treat cases where highlight border is inside rle->len pixels */ if ( x < hili_left ) { /* starts left */ if( x + rlelen > hili_left ) { /* ends not left */ /* choose the largest "bite" up to palette change */ rle_bite = hili_left - x; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } else { /* ends left */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } if( x < clip_left ) clipped = 1; } else if( x + rlelen > hili_right ) { /* ends right */ if( x < hili_right ) { /* starts not right */ /* choose the largest "bite" up to palette change */ rle_bite = hili_right - x; /* we're in the center area so choose highlight palette */ colors = img_overl->hili_color; trans = img_overl->hili_trans; } else { /* starts right */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; if( x + rle_bite >= clip_right ) clipped = 1; } } else { /* starts not left and ends not right */ rle_bite = rlelen; /* we're in the center area so choose highlight palette */ colors = img_overl->hili_color; trans = img_overl->hili_trans; } } x2_scaled = SCALED_TO_INT((x + rle_bite) * x_scale); o = trans[clr]; if (o && !clipped) { union { uint32_t u32; clut_t c; } color = {colors[clr]}; mem_blend24(img_pix + x1_scaled*3, color.c.cb, color.c.cr, color.c.y, o, x2_scaled-x1_scaled); } x1_scaled = x2_scaled; x += rle_bite; rlelen -= rle_bite; } img_pix += img_width * 3; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } } } void _x_blend_rgb32 (uint8_t * img, vo_overlay_t * img_overl, int img_width, int img_height, int dst_width, int dst_height, alphablend_t *extra_data) { int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; rle_elem_t *rle_limit = rle + img_overl->num_rle; int x_off = img_overl->x + extra_data->offset_x; int y_off = img_overl->y + extra_data->offset_y; int x, y, x1_scaled, x2_scaled; int dy, dy_step, x_scale; /* scaled 2**SCALE_SHIFT */ int hili_right, hili_left; int clip_right, clip_left, clip_top; uint8_t *img_pix; dy_step = INT_TO_SCALED(dst_height) / img_height; x_scale = INT_TO_SCALED(img_width) / dst_width; img_pix = img + 4 * ( (y_off * img_height / dst_height) * img_width + (x_off * img_width / dst_width)); /* checks to avoid drawing overlay outside the destination buffer */ if( (x_off + src_width) <= dst_width ) clip_right = src_width; else clip_right = dst_width - x_off; if( x_off >= 0 ) clip_left = 0; else clip_left = -x_off; if( y_off >= 0 ) clip_top = 0; else clip_top = -y_off; if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; /* make highlight area fit into clip area */ if( img_overl->hili_right <= clip_right ) hili_right = img_overl->hili_right; else hili_right = clip_right; if( img_overl->hili_left >= clip_left ) hili_left = img_overl->hili_left; else hili_left = clip_left; for (y = dy = 0; y < src_height && rle < rle_limit; ) { int mask = !(y < img_overl->hili_top || y >= img_overl->hili_bottom); rle_elem_t *rle_start = rle; int rlelen = 0; uint8_t clr = 0; for (x = x1_scaled = 0; x < src_width;) { int rle_bite; uint32_t *colors; uint8_t *trans; uint16_t o; int clipped = (y < clip_top); /* take next element from rle list everytime an element is finished */ if (rlelen <= 0) { if (rle >= rle_limit) break; rlelen = rle->len; clr = rle->color; rle++; } if (!mask) { /* above or below highlight area */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } else { /* treat cases where highlight border is inside rle->len pixels */ if ( x < hili_left ) { /* starts left */ if( x + rlelen > hili_left ) { /* ends not left */ /* choose the largest "bite" up to palette change */ rle_bite = hili_left - x; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } else { /* ends left */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; } if( x < clip_left ) clipped = 1; } else if( x + rlelen > hili_right ) { /* ends right */ if( x < hili_right ) { /* starts not right */ /* choose the largest "bite" up to palette change */ rle_bite = hili_right - x; /* we're in the center area so choose highlight palette */ colors = img_overl->hili_color; trans = img_overl->hili_trans; } else { /* starts right */ rle_bite = rlelen; /* choose palette for surrounding area */ colors = img_overl->color; trans = img_overl->trans; if( x + rle_bite >= clip_right ) clipped = 1; } } else { /* starts not left and ends not right */ rle_bite = rlelen; /* we're in the center area so choose highlight palette */ colors = img_overl->hili_color; trans = img_overl->hili_trans; } } x2_scaled = SCALED_TO_INT((x + rle_bite) * x_scale); o = trans[clr]; if (o && !clipped) { mem_blend32(img_pix + x1_scaled*4, (uint8_t *)&colors[clr], o, x2_scaled-x1_scaled); } x1_scaled = x2_scaled; x += rle_bite; rlelen -= rle_bite; } img_pix += img_width * 4; dy += dy_step; if (dy >= INT_TO_SCALED(1)) { dy -= INT_TO_SCALED(1); ++y; while (dy >= INT_TO_SCALED(1)) { rle = rle_img_advance_line(rle, rle_limit, src_width); dy -= INT_TO_SCALED(1); ++y; } } else { rle = rle_start; /* y-scaling, reuse the last rle encoded line */ } } } static void blend_yuv_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, uint8_t *(*blend_yuv_data)[ 3 ][ 2 ]) { int x; for (x = 0; x < src_width; x += 2) { /* get opacity of the 4 pixels that share chroma */ int o00 = (*blend_yuv_data)[ 0 ][ 0 ][ x + 0 ]; int o01 = (*blend_yuv_data)[ 0 ][ 0 ][ x + 1 ]; int o = o00 + o01; int o10 = (*blend_yuv_data)[ 0 ][ 1 ][ x + 0 ]; o += o10; int o11 = (*blend_yuv_data)[ 0 ][ 1 ][ x + 1 ]; o += o11; /* are there any pixels a little bit opaque? */ if (o) { /* get the chroma components of the 4 pixels */ int cr00 = (*blend_yuv_data)[ 1 ][ 0 ][ x + 0 ]; int cr01 = (*blend_yuv_data)[ 1 ][ 0 ][ x + 1 ]; int cr10 = (*blend_yuv_data)[ 1 ][ 1 ][ x + 0 ]; int cr11 = (*blend_yuv_data)[ 1 ][ 1 ][ x + 1 ]; int cb00 = (*blend_yuv_data)[ 2 ][ 0 ][ x + 0 ]; int cb01 = (*blend_yuv_data)[ 2 ][ 0 ][ x + 1 ]; int cb10 = (*blend_yuv_data)[ 2 ][ 1 ][ x + 0 ]; int cb11 = (*blend_yuv_data)[ 2 ][ 1 ][ x + 1 ]; /* are all pixels completely opaque? */ if (o >= 4*0xf) { /* set the output chroma to the average of the four pixels */ *dst_cr = (cr00 + cr01 + cr10 + cr11) / 4; *dst_cb = (cb00 + cb01 + cb10 + cb11) / 4; } else { /* calculate transparency of background over the four pixels */ int t4 = 4*0xf - o; /* blend the output chroma to the average of the four pixels */ /* for explanation of the used equation, see blend_yuy2_exact() */ *dst_cr = ((*dst_cr * t4 + cr00 * o00 + cr01 * o01 + cr10 * o10 + cr11 * o11) * (0x1111+1)) >> 18; *dst_cb = ((*dst_cb * t4 + cb00 * o00 + cb01 * o01 + cb10 * o10 + cb11 * o11) * (0x1111+1)) >> 18; } } /* next chroma sample */ dst_cr++; dst_cb++; } } static uint8_t *(*blend_yuv_grow_extra_data(alphablend_t *extra_data, int osd_width))[ 3 ][ 2 ] { struct header_s { int id; int max_width; uint8_t *data[ 3 ][ 2 ]; } *header = (struct header_s *)extra_data->buffer; /* align buffers to 16 bytes */ size_t header_size = (sizeof(*header) + 15) & (~15); size_t alloc_width = (osd_width + 15) & (~15); size_t needed_buffer_size = 16 + header_size + alloc_width * sizeof (uint8_t[ 3 ][ 2 ]); if (extra_data->buffer_size < needed_buffer_size) { _x_freep(&extra_data->buffer); header = calloc(1, needed_buffer_size); if (!header) { extra_data->buffer_size = 0; return NULL; } extra_data->buffer_size = needed_buffer_size; extra_data->buffer = header; header->max_width = 0; } if (header->id != ME_FOURCC('y', 'u', 'v', 0) || header->max_width < osd_width) { header->id = ME_FOURCC('y', 'u', 'v', 0); header->max_width = osd_width; header->data[ 0 ][ 0 ] = ((uint8_t *)extra_data->buffer) + header_size; header->data[ 0 ][ 1 ] = header->data[ 0 ][ 0 ] + alloc_width; header->data[ 1 ][ 0 ] = header->data[ 0 ][ 1 ] + alloc_width; header->data[ 1 ][ 1 ] = header->data[ 1 ][ 0 ] + alloc_width; header->data[ 2 ][ 0 ] = header->data[ 1 ][ 1 ] + alloc_width; header->data[ 2 ][ 1 ] = header->data[ 2 ][ 0 ] + alloc_width; } return &(header->data); } void _x_blend_yuv (uint8_t *dst_base[3], vo_overlay_t * img_overl, int dst_width, int dst_height, int dst_pitches[3], alphablend_t *extra_data) { int enable_exact_blending = !extra_data->disable_exact_blending; uint32_t *my_clut; uint8_t *my_trans; int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; rle_elem_t *rle_limit = rle + img_overl->num_rle; int x_off = img_overl->x + extra_data->offset_x; int y_off = img_overl->y + extra_data->offset_y; int x_odd = x_off & 1; int y_odd = y_off & 1; int ymask,xmask; int rle_this_bite; int rle_remainder; int rlelen; int x, y; int hili_right, hili_left; int clip_right, clip_left, clip_top; uint8_t clr=0; int any_line_buffered = 0; int exact_blend_width = ((src_width <= (dst_width - x_off)) ? src_width : (dst_width - x_off)); int exact_blend_width_m2 = (x_odd + exact_blend_width + 1) & ~1; /* make it a (larger) multiple of 2 */ uint8_t *(*blend_yuv_data)[ 3 ][ 2 ] = 0; uint8_t *dst_y = dst_base[0] + dst_pitches[0] * y_off + x_off; uint8_t *dst_cr = dst_base[2] + (y_off / 2) * dst_pitches[1] + (x_off / 2); uint8_t *dst_cb = dst_base[1] + (y_off / 2) * dst_pitches[2] + (x_off / 2); #ifdef LOG_BLEND_YUV printf("overlay_blend started x=%d, y=%d, w=%d h=%d\n",img_overl->x,img_overl->y,img_overl->width,img_overl->height); #endif my_clut = img_overl->hili_color; my_trans = img_overl->hili_trans; /* checks to avoid drawing overlay outside the destination buffer */ if( (x_off + src_width) <= dst_width ) clip_right = src_width; else clip_right = dst_width - x_off; if( x_off >= 0 ) clip_left = 0; else clip_left = -x_off; if( y_off >= 0 ) clip_top = 0; else clip_top = -y_off; if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; /* make highlight area fit into clip area */ if( img_overl->hili_right <= clip_right ) hili_right = img_overl->hili_right; else hili_right = clip_right; if( img_overl->hili_left >= clip_left ) hili_left = img_overl->hili_left; else hili_left = clip_left; if (src_height <= 0) return; if (enable_exact_blending) { if (exact_blend_width <= 0) return; blend_yuv_data = blend_yuv_grow_extra_data(extra_data, exact_blend_width_m2); if (!blend_yuv_data) return; /* make linebuffer transparent */ memset(&(*blend_yuv_data)[ 0 ][ 0 ][ 0 ], 0, exact_blend_width_m2); memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); } rlelen=rle_remainder=0; for (y = 0; y < src_height; y++) { if (rle >= rle_limit) { #ifdef LOG_BLEND_YUV printf("y-rle_limit\n"); #endif break; } ymask = ((y < img_overl->hili_top) || (y >= img_overl->hili_bottom)); xmask = 0; #ifdef LOG_BLEND_YUV printf("X started ymask=%d y=%d src_height=%d\n",ymask, y, src_height); #endif for (x = 0; x < src_width;) { uint16_t o; int clipped = (y < clip_top); if (rle >= rle_limit) { #ifdef LOG_BLEND_YUV printf("x-rle_limit\n"); #endif break; } #ifdef LOG_BLEND_YUV printf("1:rle_len=%d, remainder=%d, x=%d\n",rlelen, rle_remainder, x); #endif if ((rlelen < 0) || (rle_remainder < 0)) { #ifdef LOG_BLEND_YUV printf("alphablend: major bug in blend_yuv < 0\n"); #endif } if (rlelen == 0) { rle_remainder = rlelen = rle->len; clr = rle->color; rle++; } if (rle_remainder == 0) { rle_remainder = rlelen; } if ((rle_remainder + x) > src_width) { /* Do something for long rlelengths */ rle_remainder = src_width - x; } #ifdef LOG_BLEND_YUV printf("2:rle_len=%d, remainder=%d, x=%d\n",rlelen, rle_remainder, x); #endif if (ymask == 0) { if (x < hili_left) { /* Starts outside highlight area */ if ((x + rle_remainder) > hili_left ) { #ifdef LOG_BLEND_YUV printf("Outside highlight left %d, ending inside\n", hili_left); #endif /* Cutting needed, starts outside, ends inside */ rle_this_bite = (hili_left - x); rle_remainder -= rle_this_bite; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; xmask = 0; } else { #ifdef LOG_BLEND_YUV printf("Outside highlight left %d, ending outside\n", hili_left); #endif /* no cutting needed, starts outside, ends outside */ rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; xmask = 0; } if( x < clip_left ) clipped = 1; } else if (x < hili_right) { /* Starts inside highlight area */ if ((x + rle_remainder) > hili_right ) { #ifdef LOG_BLEND_YUV printf("Inside highlight right %d, ending outside\n", hili_right); #endif /* Cutting needed, starts inside, ends outside */ rle_this_bite = (hili_right - x); rle_remainder -= rle_this_bite; rlelen -= rle_this_bite; my_clut = img_overl->hili_color; my_trans = img_overl->hili_trans; xmask++; } else { #ifdef LOG_BLEND_YUV printf("Inside highlight right %d, ending inside\n", hili_right); #endif /* no cutting needed, starts inside, ends inside */ rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->hili_color; my_trans = img_overl->hili_trans; xmask++; } } else if (x >= hili_right) { /* Starts outside highlight area, ends outside highlight area */ if ((x + rle_remainder ) > src_width ) { #ifdef LOG_BLEND_YUV printf("Outside highlight right %d, ending eol\n", hili_right); #endif /* Cutting needed, starts outside, ends at right edge */ /* It should never reach here due to the earlier test of src_width */ rle_this_bite = (src_width - x ); rle_remainder -= rle_this_bite; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; xmask = 0; } else { /* no cutting needed, starts outside, ends outside */ #ifdef LOG_BLEND_YUV printf("Outside highlight right %d, ending outside\n", hili_right); #endif rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; xmask = 0; } if( x + rle_this_bite >= clip_right ) clipped = 1; } } else { /* Outside highlight are due to y */ /* no cutting needed, starts outside, ends outside */ rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; xmask = 0; } o = my_trans[clr]; #ifdef LOG_BLEND_YUV printf("Trans=%d clr=%d xmask=%d my_clut[clr]=%d\n",o, clr, xmask, my_clut[clr].y); #endif if (x < (dst_width - x_off)) { /* clip against right edge of destination area */ if ((x + rle_this_bite) > (dst_width - x_off)) { int toClip = (x + rle_this_bite) - (dst_width - x_off); rle_this_bite -= toClip; rle_remainder += toClip; rlelen += toClip; } if (enable_exact_blending) { /* remember opacity of current line */ memset(&(*blend_yuv_data)[ 0 ][ (y + y_odd) & 1 ][ x + x_odd ], o, rle_this_bite); any_line_buffered |= ((y + y_odd) & 1) ? 2 : 1; } if (o && !clipped) { union { uint32_t u32; clut_t c; } color = {my_clut[clr]}; if(o >= 15) { memset(dst_y + x, color.c.y, rle_this_bite); if (!enable_exact_blending) { if ((y + y_odd) & 1) { memset(dst_cr + ((x + x_odd) >> 1), color.c.cr, (rle_this_bite+1) >> 1); memset(dst_cb + ((x + x_odd) >> 1), color.c.cb, (rle_this_bite+1) >> 1); } } } else { mem_blend8(dst_y + x, color.c.y, o, rle_this_bite); if (!enable_exact_blending) { if ((y + y_odd) & 1) { /* Blending cr and cb should use a different function, with pre -128 to each sample */ mem_blend8(dst_cr + ((x + x_odd) >> 1), color.c.cr, o, (rle_this_bite+1) >> 1); mem_blend8(dst_cb + ((x + x_odd) >> 1), color.c.cb, o, (rle_this_bite+1) >> 1); } } } if (enable_exact_blending) { /* remember chroma of current line */ memset(&(*blend_yuv_data)[ 1 ][ (y + y_odd) & 1 ][ x + x_odd ], color.c.cr, rle_this_bite); memset(&(*blend_yuv_data)[ 2 ][ (y + y_odd) & 1 ][ x + x_odd ], color.c.cb, rle_this_bite); } } } #ifdef LOG_BLEND_YUV printf("rle_this_bite=%d, remainder=%d, x=%d\n",rle_this_bite, rle_remainder, x); #endif x += rle_this_bite; } if ((y + y_odd) & 1) { if (enable_exact_blending) { /* blend buffered lines */ if (any_line_buffered) { if (!(any_line_buffered & 2)) { /* make second line transparent */ memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); } blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, blend_yuv_data); any_line_buffered = 0; } } dst_cr += dst_pitches[2]; dst_cb += dst_pitches[1]; } dst_y += dst_pitches[0]; } if (enable_exact_blending) { /* blend buffered lines */ if (any_line_buffered) { if (!(any_line_buffered & 2)) { /* make second line transparent */ memset(&(*blend_yuv_data)[ 0 ][ 1 ][ 0 ], 0, exact_blend_width_m2); } blend_yuv_exact(dst_cr, dst_cb, exact_blend_width, blend_yuv_data); } } #ifdef LOG_BLEND_YUV printf("overlay_blend ended\n"); #endif } static void blend_yuy2_exact(uint8_t *dst_cr, uint8_t *dst_cb, int src_width, uint8_t *(*blend_yuy2_data)[ 3 ]) { int x; for (x = 0; x < src_width; x += 2) { /* get opacity of the 2 pixels that share chroma */ int o0 = (*blend_yuy2_data)[ 0 ][ x + 0 ]; int o1 = (*blend_yuy2_data)[ 0 ][ x + 1 ]; int o = o0 + o1; /* are there any pixels a little bit opaque? */ if (o) { /* get the chroma components of the 2 pixels */ int cr0 = (*blend_yuy2_data)[ 1 ][ x + 0 ]; int cr1 = (*blend_yuy2_data)[ 1 ][ x + 1 ]; int cb0 = (*blend_yuy2_data)[ 2 ][ x + 0 ]; int cb1 = (*blend_yuy2_data)[ 2 ][ x + 1 ]; /* are all pixels completely opaque? */ if (o >= 2*0xf) { /* set the output chroma to the average of the two pixels */ *dst_cr = (cr0 + cr1) / 2; *dst_cb = (cb0 + cb1) / 2; } else { /* calculate transparency of background over the two pixels */ int t2 = 2*0xf - o; /* * No need to adjust chroma values with +/- 128: * *dst_cb * = 128 + ((*dst_cb-128) * t2 + (cb0-128) * o0 + (cb1-128) * o1) / (2 * 0xf); * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1 + (t2*(-128) - 128*o0 - 128*o1)) / (2 * 0xf); * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1 + ((2*0xf-o0-o1)*(-128) - 128*o0 - 128*o1)) / (2 * 0xf); * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1 + (2*0xf*(-128))) / (2 * 0xf); * = 128 + (*dst_cb * t2 + cb0 * o0 + cb1 * o1) / (2 * 0xf) - 128; * = (*dst_cb * t2 + cb0 * o0 + cb1 * o1) / (2 * 0xf); * * Convert slow divisions to multiplication and shift: * X/0xf * = X * (1/0xf) * = X * (0x1111/0x1111) * (1/0xf) * = X * 0x1111/0xffff * =(almost) X * 0x1112/0x10000 * = (X * 0x1112) >> 16 * * The tricky point is 0x1111/0xffff --> 0x1112/0x10000. * All calculations are done using integers and X is in * range of [0 ... 0xff*0xf*4]. This results in error of * X*0x1112/0x10000 - X/0xf * = X*(0x1112/0x10000 - 1/0xf) * = X*(0x0.1112 - 0x0.111111...) * = X*0.0000eeeeee.... * = [0 ... 0.37c803fc...] when X in [0...3bc4] * As the error is less than 1 and always positive, whole error * "disappears" during truncation (>>16). Rounding to exact results is * guaranteed by selecting 0x1112 instead of more accurate 0x1111 * (with 0x1111 error=X*(-0.00001111...)). With 0x1112 error is * always positive, but still less than one. * So, one can forget the "=(almost)" as it is really "=" when source * operands are within 0...0xff (U,V) and 0...0xf (A). * * 1/0x10000 (= >>16) was originally selected because of MMX pmullhw * instruction; it makes possible to do whole calculation in MMX using * uint16's (pmullhw is (X*Y)>>16). * * Here X/(2*0xf) = X/0xf/2 = ((X*0x1112)>>16)>>1 = (X*0x1112)>>17 */ /* blend the output chroma to the average of the two pixels */ /* *dst_cr = 128 + ((*dst_cr-128) * t2 + (cr0-128) * o0 + (cr1-128) * o1) / (2 * 0xf); */ *dst_cr = ((*dst_cr * t2 + cr0 * o0 + cr1 * o1) * (0x1111+1)) >> 17; *dst_cb = ((*dst_cb * t2 + cb0 * o0 + cb1 * o1) * (0x1111+1)) >> 17; } } /* next chroma sample */ dst_cr += 4; dst_cb += 4; } } static uint8_t *(*blend_yuy2_grow_extra_data(alphablend_t *extra_data, int osd_width))[ 3 ] { struct header_s { int id; int max_width; uint8_t *data[ 3 ]; } *header = (struct header_s *)extra_data->buffer; /* align buffers to 16 bytes */ size_t header_size = (sizeof(*header) + 15) & (~15); size_t alloc_width = (osd_width + 15) & (~15); size_t needed_buffer_size = 16 + header_size + alloc_width * sizeof (uint8_t[ 3 ]); if (extra_data->buffer_size < needed_buffer_size) { _x_freep(&extra_data->buffer); header = calloc(1, needed_buffer_size); if (!header) { extra_data->buffer_size = 0; return 0; } extra_data->buffer_size = needed_buffer_size; extra_data->buffer = header; header->max_width = 0; } if (header->id != ME_FOURCC('y', 'u', 'y', '2') || header->max_width < osd_width) { header->id = ME_FOURCC('y', 'u', 'y', '2'); header->max_width = osd_width; header->data[ 0 ] = ((uint8_t *)extra_data->buffer) + header_size; header->data[ 1 ] = header->data[ 0 ] + alloc_width; header->data[ 2 ] = header->data[ 1 ] + alloc_width; } return &(header->data); } void _x_blend_yuy2 (uint8_t * dst_img, vo_overlay_t * img_overl, int dst_width, int dst_height, int dst_pitch, alphablend_t *extra_data) { int enable_exact_blending = !extra_data->disable_exact_blending; uint32_t *my_clut; uint8_t *my_trans; int src_width = img_overl->width; int src_height = img_overl->height; rle_elem_t *rle = img_overl->rle; rle_elem_t *rle_limit = rle + img_overl->num_rle; int x_off = img_overl->x + extra_data->offset_x; int y_off = img_overl->y + extra_data->offset_y; int x_odd = x_off & 1; int ymask; int rle_this_bite; int rle_remainder; int rlelen; int x, y; int l = 0; int hili_right, hili_left; int clip_right, clip_left, clip_top; union { uint32_t value; uint8_t b[4]; uint16_t h[2]; } yuy2; uint8_t clr = 0; int any_line_buffered = 0; int exact_blend_width = ((src_width <= (dst_width - x_off)) ? src_width : (dst_width - x_off)); int exact_blend_width_m2 = (x_odd + exact_blend_width + 1) & ~1; /* make it a (larger) multiple of 2 */ uint8_t *(*blend_yuy2_data)[ 3 ] = 0; uint8_t *dst_y = dst_img + dst_pitch * y_off + 2 * x_off; uint8_t *dst; my_clut = img_overl->hili_color; my_trans = img_overl->hili_trans; /* checks to avoid drawing overlay outside the destination buffer */ if( (x_off + src_width) <= dst_width ) clip_right = src_width; else clip_right = dst_width - x_off; if( x_off >= 0 ) clip_left = 0; else clip_left = -x_off; if( y_off >= 0 ) clip_top = 0; else clip_top = -y_off; if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; /* make highlight area fit into clip area */ if( img_overl->hili_right <= clip_right ) hili_right = img_overl->hili_right; else hili_right = clip_right; if( img_overl->hili_left >= clip_left ) hili_left = img_overl->hili_left; else hili_left = clip_left; if (src_height <= 0) return; if (enable_exact_blending) { if (exact_blend_width <= 0) return; blend_yuy2_data = blend_yuy2_grow_extra_data(extra_data, exact_blend_width_m2); if (!blend_yuy2_data) return; /* make linebuffer transparent */ memset(&(*blend_yuy2_data)[ 0 ][ 0 ], 0, exact_blend_width_m2); } rlelen=rle_remainder=0; for (y = 0; y < src_height; y++) { if (rle >= rle_limit) break; ymask = ((y < img_overl->hili_top) || (y >= img_overl->hili_bottom)); dst = dst_y; for (x = 0; x < src_width;) { uint16_t o; int clipped = (y < clip_top); if (rle >= rle_limit) break; if ((rlelen < 0) || (rle_remainder < 0)) { #ifdef LOG_BLEND_YUV printf("alphablend: major bug in blend_yuv < 0\n"); #endif } if (rlelen == 0) { rle_remainder = rlelen = rle->len; clr = rle->color; rle++; } if (rle_remainder == 0) { rle_remainder = rlelen; } if ((rle_remainder + x) > src_width) { /* Do something for long rlelengths */ rle_remainder = src_width - x; } #ifdef LOG_BLEND_YUV printf("2:rle_len=%d, remainder=%d, x=%d\n",rlelen, rle_remainder, x); #endif if (ymask == 0) { if (x < hili_left) { /* Starts outside highlight area */ if ((x + rle_remainder) > hili_left ) { #ifdef LOG_BLEND_YUV printf("Outside highlight left %d, ending inside\n", hili_left); #endif /* Cutting needed, starts outside, ends inside */ rle_this_bite = (hili_left - x); rle_remainder -= rle_this_bite; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; } else { #ifdef LOG_BLEND_YUV printf("Outside highlight left %d, ending outside\n", hili_left); #endif /* no cutting needed, starts outside, ends outside */ rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; } if( x < clip_left ) clipped = 1; } else if (x < hili_right) { /* Starts inside highlight area */ if ((x + rle_remainder) > hili_right ) { #ifdef LOG_BLEND_YUV printf("Inside highlight right %d, ending outside\n", hili_right); #endif /* Cutting needed, starts inside, ends outside */ rle_this_bite = (hili_right - x); rle_remainder -= rle_this_bite; rlelen -= rle_this_bite; my_clut = img_overl->hili_color; my_trans = img_overl->hili_trans; } else { #ifdef LOG_BLEND_YUV printf("Inside highlight right %d, ending inside\n", hili_right); #endif /* no cutting needed, starts inside, ends inside */ rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->hili_color; my_trans = img_overl->hili_trans; } } else if (x >= hili_right) { /* Starts outside highlight area, ends outsite highlight area */ if ((x + rle_remainder ) > src_width ) { #ifdef LOG_BLEND_YUV printf("Outside highlight right %d, ending eol\n", hili_right); #endif /* Cutting needed, starts outside, ends at right edge */ /* It should never reach here due to the earlier test of src_width */ rle_this_bite = (src_width - x ); rle_remainder -= rle_this_bite; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; } else { /* no cutting needed, starts outside, ends outside */ #ifdef LOG_BLEND_YUV printf("Outside highlight right %d, ending outside\n", hili_right); #endif rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; } if( x + rle_this_bite >= clip_right ) clipped = 1; } } else { /* Outside highlight are due to y */ /* no cutting needed, starts outside, ends outside */ rle_this_bite = rle_remainder; rle_remainder = 0; rlelen -= rle_this_bite; my_clut = img_overl->color; my_trans = img_overl->trans; } o = my_trans[clr]; if (x < (dst_width - x_off)) { /* clip against right edge of destination area */ if ((x + rle_this_bite) > (dst_width - x_off)) { int toClip = (x + rle_this_bite) - (dst_width - x_off); rle_this_bite -= toClip; rle_remainder += toClip; rlelen += toClip; } if (enable_exact_blending) { /* remember opacity of current line */ memset(&(*blend_yuy2_data)[ 0 ][ x + x_odd ], o, rle_this_bite); any_line_buffered = 1; } if (o && !clipped) { union { uint32_t u32; clut_t c; } color = {my_clut[clr]}; if (!enable_exact_blending) { l = rle_this_bite>>1; if( !((x_odd+x) & 1) ) { yuy2.b[0] = color.c.y; yuy2.b[1] = color.c.cb; yuy2.b[2] = color.c.y; yuy2.b[3] = color.c.cr; } else { yuy2.b[0] = color.c.y; yuy2.b[1] = color.c.cr; yuy2.b[2] = color.c.y; yuy2.b[3] = color.c.cb; } } if (o >= 15) { if (!enable_exact_blending) { while(l--) { *(uint16_t *)dst = yuy2.h[0]; dst += 2; *(uint16_t *)dst = yuy2.h[1]; dst += 2; } if(rle_this_bite & 1) { *(uint16_t *)dst = yuy2.h[0]; dst += 2; } } else { l = rle_this_bite; while (l--) { *dst = color.c.y; dst += 2; } } } else { if (!enable_exact_blending) { if( l ) { mem_blend32(dst, &yuy2.b[0], o, l); dst += 4*l; } if(rle_this_bite & 1) { *dst = BLEND_BYTE(*dst, yuy2.b[0], o); dst++; *dst = BLEND_BYTE(*dst, yuy2.b[1], o); dst++; } } else { l = rle_this_bite; while (l--) { *dst = BLEND_BYTE(*dst, color.c.y, o); dst += 2; } } } if (enable_exact_blending) { /* remember chroma of current line */ memset(&(*blend_yuy2_data)[ 1 ][ x + x_odd ], color.c.cr, rle_this_bite); memset(&(*blend_yuy2_data)[ 2 ][ x + x_odd ], color.c.cb, rle_this_bite); } } else { dst += rle_this_bite*2; } } x += rle_this_bite; } if (enable_exact_blending) { /* blend buffered line */ if (any_line_buffered) { blend_yuy2_exact(dst_y - x_odd * 2 + 3, dst_y - x_odd * 2 + 1, exact_blend_width, blend_yuy2_data); any_line_buffered = 0; } } dst_y += dst_pitch; } } void _x_clear_xx44_palette(xx44_palette_t *p) { register int i; register uint32_t *cluts = p->cluts; register int *ids = p->lookup_cache; i= p->size; while(i--) *cluts++ = 0; i = 2*OVL_PALETTE_SIZE; while(i--) *ids++ = -1; p->max_used=1; } void _x_init_xx44_palette(xx44_palette_t *p, unsigned num_entries) { p->size = (num_entries > XX44_PALETTE_SIZE) ? XX44_PALETTE_SIZE : num_entries; } void _x_dispose_xx44_palette(xx44_palette_t *p) { (void)p; } static void colorToPalette(const uint32_t *icolor, unsigned char *palette_p, unsigned num_xvmc_components, const char *xvmc_components) { const clut_t *color = (const clut_t *) icolor; unsigned int i; for (i=0; i<num_xvmc_components; ++i) { switch(xvmc_components[i]) { case 'V': *palette_p = color->cr; break; case 'U': *palette_p = color->cb; break; case 'Y': default: *palette_p = color->y; break; } palette_p++; } } void _x_xx44_to_xvmc_palette(const xx44_palette_t *p,unsigned char *xvmc_palette, unsigned first_xx44_entry, unsigned num_xx44_entries, unsigned num_xvmc_components, const char *xvmc_components) { register unsigned int i; register const uint32_t *cluts = p->cluts + first_xx44_entry; for (i=0; i<num_xx44_entries; ++i) { if ((cluts - p->cluts) < (int)(p->size)) { colorToPalette(cluts++, xvmc_palette, num_xvmc_components, xvmc_components); xvmc_palette += num_xvmc_components; } } } static int xx44_paletteIndex(xx44_palette_t *p, int color, uint32_t clut) { register unsigned int i; register uint32_t *cluts = p->cluts; register int tmp; if ((tmp = p->lookup_cache[color]) >= 0) if (cluts[tmp] == clut) return tmp; for (i=0; i<p->max_used; ++i) { if (*cluts++ == clut) return p->lookup_cache[color] = i; } if (p->max_used == p->size -1) { printf("video_out: Warning! Out of xx44 palette colours!\n"); return 1; } p->cluts[p->max_used] = clut; return p->lookup_cache[color] = p->max_used++; } static void memblend_xx44(uint8_t *mem,uint8_t val, register size_t size, uint8_t mask) { register uint8_t masked_val; if (0 == (masked_val = val & mask)) return; while(size--) { if ((*mem & mask) <= masked_val ) *mem = val; mem++; } } void _x_blend_xx44 (uint8_t *dst_img, vo_overlay_t *img_overl, int dst_width, int dst_height, int dst_pitch, alphablend_t *extra_data, xx44_palette_t *palette,int ia44) { int src_width, src_height; rle_elem_t *rle, *rle_limit; int mask; int x_off, y_off; int x, y; uint8_t norm_pixel,hili_pixel; uint8_t *dst_y; uint8_t *dst; uint8_t alphamask = (ia44) ? 0x0F : 0xF0; int hili_right, hili_left; int clip_right, clip_left, clip_top; if (!img_overl) return; src_width = img_overl->width; src_height = img_overl->height; rle = img_overl->rle; rle_limit = rle + img_overl->num_rle; x_off = img_overl->x + extra_data->offset_x; y_off = img_overl->y + extra_data->offset_y; dst_y = dst_img + dst_pitch*y_off + x_off; /* checks to avoid drawing overlay outside the destination buffer */ if( (x_off + src_width) <= dst_width ) clip_right = src_width; else clip_right = dst_width - x_off; if( x_off >= 0 ) clip_left = 0; else clip_left = -x_off; if( y_off >= 0 ) clip_top = 0; else clip_top = -y_off; if( (src_height + y_off) > dst_height ) src_height = dst_height - y_off; /* make highlight area fit into clip area */ if( img_overl->hili_right <= clip_right ) hili_right = img_overl->hili_right; else hili_right = clip_right; if( img_overl->hili_left >= clip_left ) hili_left = img_overl->hili_left; else hili_left = clip_left; for (y = 0; y < src_height; y++) { mask = !(y < img_overl->hili_top || y >= img_overl->hili_bottom); dst = dst_y; for (x = 0; x < src_width;) { int len = (x + rle->len > clip_right) ? clip_right - x : rle->len; int clipped = (y < clip_top); if (len > 0) { norm_pixel = (uint8_t)((xx44_paletteIndex(palette,rle->color, img_overl->color[rle->color]) << 4) | (img_overl->trans[rle->color] & 0x0F)); hili_pixel = (uint8_t)((xx44_paletteIndex(palette,rle->color+OVL_PALETTE_SIZE, img_overl->hili_color[rle->color]) << 4) | (img_overl->hili_trans[rle->color] & 0x0F)); if (!ia44) { norm_pixel = ((norm_pixel & 0x0F) << 4) | ((norm_pixel & 0xF0) >> 4); hili_pixel = ((hili_pixel & 0x0F) << 4) | ((hili_pixel & 0xF0) >> 4); } if (mask) { if (x < hili_left) { if (x < clip_left) clipped = 1; if (x + len <= hili_left) { if(!clipped) memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } else { if(!clipped) memblend_xx44(dst,norm_pixel,hili_left -x, alphamask); dst += hili_left - x; len -= hili_left - x; if (len <= hili_right - hili_left) { if(!clipped) memblend_xx44(dst,hili_pixel,len, alphamask); dst += len; } else { if(!clipped) memblend_xx44(dst,hili_pixel, hili_right - hili_left, alphamask); dst += hili_right - hili_left; len -= hili_right - hili_left; if(!clipped) memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } } } else if (x < hili_right) { if (len <= hili_right - x) { if(!clipped) memblend_xx44(dst,hili_pixel,len, alphamask); dst += len; } else { if(!clipped) memblend_xx44(dst,hili_pixel,hili_right - x,alphamask); if (len > clip_right - x) clipped = 1; dst += hili_right - x; len -= hili_right - x; if(!clipped) memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } } else { if (x > clip_right) clipped = 1; if(!clipped) memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } } else { if(!clipped) memblend_xx44(dst,norm_pixel,len, alphamask); dst += len; } } x += rle->len; rle++; if (rle >= rle_limit) break; } if (rle >= rle_limit) break; dst_y += dst_pitch; } } static void alphablend_disable_exact_osd_alpha_blending_changed(void *user_data, xine_cfg_entry_t *entry) { alphablend_t *extra_data = (alphablend_t *)user_data; extra_data->disable_exact_blending = entry->num_value; } void _x_alphablend_init(alphablend_t *extra_data, xine_t *xine) { config_values_t *config = xine->config; extra_data->buffer = NULL; extra_data->buffer_size = 0; extra_data->offset_x = 0; extra_data->offset_y = 0; extra_data->disable_exact_blending = config->register_bool(config, "video.output.disable_exact_alphablend", 0, _("disable exact alpha blending of overlays"), _("If you experience a performance impact when an On Screen Display or other " "overlays like DVD subtitles are active, then you might want to enable this option.\n" "The result is that alpha blending of overlays is less accurate than before, " "but the CPU usage will be decreased as well."), 10, alphablend_disable_exact_osd_alpha_blending_changed, extra_data); } void _x_alphablend_free(alphablend_t *extra_data) { _x_freep(&extra_data->buffer); extra_data->buffer_size = 0; } #define saturate(v) if (v & ~255) v = (~((uint32_t)v)) >> 24 void _x_clut_yuv2rgb(uint32_t *clut, int num_items, int color_matrix) { uint32_t *end = clut + num_items; if (end <= clut) return; switch (color_matrix >> 1) { case 8: while (clut < end) { union { uint32_t u32; clut_t c; } tmp = { *clut }; int32_t y, u, v, r, g, b; y = tmp.c.y; u = tmp.c.cb; v = tmp.c.cr; /* Green Orange -- does this ever happen? */ r = y - u + v; saturate (r); g = y + u - 128; saturate (g); b = y - u - v + 256; saturate (b); /* see clut_to_argb () */ tmp.c.cb = b; tmp.c.cr = g; tmp.c.y = r; *clut++ = tmp.u32; } break; case 1: case 7: while (clut < end) { union { uint32_t u32; clut_t c; } tmp = { *clut }; int32_t y, u, v, r, g, b; y = tmp.c.y; u = tmp.c.cb; v = tmp.c.cr; /* ITU 709 (HD), mpeg range. */ y *= 76304; r = (y + 117473 * v - 16224640) >> 16; saturate (r); g = (y - 13972 * u - 34918 * v + 5069824) >> 16; saturate (g); b = (y + 138425 * u - 18906496) >> 16; saturate (b); /* see clut_to_argb () */ tmp.c.cb = b; tmp.c.cr = g; tmp.c.y = r; *clut++ = tmp.u32; } break; default: while (clut < end) { union { uint32_t u32; clut_t c; } tmp = { *clut }; int32_t y, u, v, r, g, b; y = tmp.c.y; u = tmp.c.cb; v = tmp.c.cr; /* ITU 601 (SD), mpeg range. */ y *= 76304; r = (y + 104582 * v - 14574592) >> 16; saturate (r); g = (y - 25664 * u - 53268 * v + 8849664) >> 16; saturate (g); b = (y + 132186 * u - 18107904) >> 16; saturate (b); /* see clut_to_argb () */ tmp.c.cb = b; tmp.c.cr = g; tmp.c.y = r; *clut++ = tmp.u32; } break; } } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/info_helper.c����������������������������������������������������������0000644�0001750�0001750�00000027523�14647725152�016330� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stream metainfo helper functions * hide some xine engine details from demuxers and reduce code duplication */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <string.h> #include <stdarg.h> #include <pthread.h> #ifdef HAVE_ICONV # include <iconv.h> #endif #include <xine/info_helper.h> #include "xine_private.h" /* ******************* Stream Info *************************** */ /* * Check if 'info' is in bounds. */ static int info_valid (xine_stream_private_t *stream, int info) { if ((info >= 0) && (info < XINE_STREAM_INFO_MAX)) return 1; else { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "info_helper: invalid STREAM_INFO %d. Ignored.\n", info); return 0; } } /* * Reset private info. */ void _x_stream_info_reset (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (info_valid (stream, info)) { xine_rwlock_wrlock (&stream->info_lock); stream->stream_info[info] = 0; xine_rwlock_unlock (&stream->info_lock); } } /* * Reset public info value. */ void _x_stream_info_public_reset (xine_stream_t *s, int info) { (void)s; (void)info; } /* * Set private info value. */ void _x_stream_info_set (xine_stream_t *s, int info, int value) { xine_stream_private_t *stream = (xine_stream_private_t *)s, *m; m = stream->side_streams[0]; if (info_valid (m, info)) { xine_rwlock_wrlock (&m->info_lock); if ((m != stream) && ((info == XINE_STREAM_INFO_HAS_CHAPTERS) || (info == XINE_STREAM_INFO_HAS_VIDEO) || (info == XINE_STREAM_INFO_HAS_AUDIO))) { if (m->stream_info[info] == 0) m->stream_info[info] = value; } else { m->stream_info[info] = value; } xine_rwlock_unlock (&m->info_lock); } } /* * Retrieve private info value. */ uint32_t _x_stream_info_get (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; uint32_t stream_info; stream = stream->side_streams[0]; xine_rwlock_rdlock (&stream->info_lock); stream_info = stream->stream_info[info]; xine_rwlock_unlock (&stream->info_lock); return stream_info; } /* * Retrieve public info value */ uint32_t _x_stream_info_get_public (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; uint32_t stream_info; stream = stream->side_streams[0]; xine_rwlock_rdlock (&stream->info_lock); stream_info = stream->stream_info[info]; xine_rwlock_unlock (&stream->info_lock); return stream_info; } /* **************** Meta Info *********************** */ /* * Remove trailing separator chars (\n,\r,\t, space,...) * at the end of the string */ static void meta_info_chomp(char *str) { ssize_t i, len; len = strlen(str); if (!len) return; i = len - 1; while ((i >= 0) && ((unsigned char)str[i] <= 32)) { str[i] = 0; i--; } } /* * Check if 'info' is in bounds. */ static int meta_valid (xine_stream_private_t *stream, int info) { if ((info >= 0) && (info < XINE_STREAM_INFO_MAX)) return 1; else { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "info_helper: invalid META_INFO %d. Ignored.\n", info); return 0; } } /* * Set private meta info to utf-8 string value (can be NULL). */ static void _meta_info_set_utf8 (xine_stream_private_t *stream, int info, const char *value) { if (meta_valid (stream, info)) { xine_rwlock_wrlock (&stream->meta_lock); if (( value && !stream->meta_info[info]) || ( value && stream->meta_info[info] && strcmp (value, stream->meta_info[info])) || (!value && stream->meta_info[info])) { if (stream->meta_info_public[info] != stream->meta_info[info]) free (stream->meta_info[info]); stream->meta_info[info] = (value) ? strdup(value) : NULL; if (stream->meta_info[info]) meta_info_chomp (stream->meta_info[info]); } xine_rwlock_unlock (&stream->meta_lock); } } #ifdef HAVE_ICONV static int is_utf8 (const char *s) { const uint8_t *p = (const uint8_t *)s; while (1) { if ((*p & 0x80) == 0x00) { if (*p == 0x00) break; p += 1; } else if ((*p & 0xe0) == 0xc0) { if ((p[1] & 0xc0) != 0x80) return -1; p += 2; } else if ((*p & 0xf0) == 0xe0) { if (((p[1] & 0xc0) != 0x80) || ((p[2] & 0xc0) != 0x80)) return -1; p += 3; } else if ((*p & 0xf8) == 0xf0) { if (((p[1] & 0xc0) != 0x80) || ((p[2] & 0xc0) != 0x80) || ((p[3] & 0xc0) != 0x80)) return -1; p += 4; } else if ((*p & 0xfc) == 0xf8) { if (((p[1] & 0xc0) != 0x80) || ((p[2] & 0xc0) != 0x80) || ((p[3] & 0xc0) != 0x80) || ((p[4] & 0xc0) != 0x80)) return -1; p += 5; } else if ((*p & 0xfe) == 0xfc) { if (((p[1] & 0xc0) != 0x80) || ((p[2] & 0xc0) != 0x80) || ((p[3] & 0xc0) != 0x80) || ((p[4] & 0xc0) != 0x80) || ((p[5] & 0xc0) != 0x80)) return -1; p += 6; } else { return -1; } } return p - (const uint8_t *)s; } #endif /* * Set private meta info to value (can be NULL) with a given encoding. * if encoding is NULL assume locale. */ static void _meta_info_set_encoding (xine_stream_private_t *stream, int info, const char *value, const char *enc) { const char *buf_set = value; char *buf_free = NULL; #ifdef HAVE_ICONV char *system_enc = NULL; iconv_t cd = (iconv_t)-1; do { if (!value) break; if (enc == NULL) { if ((enc = system_enc = xine_get_system_encoding()) == NULL) { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("info_helper: can't find out current locale character set\n")); break; } } if (strcmp (enc, "UTF-8")) { /* Don't bother converting if it's already in UTF-8, but the encoding * is badly reported */ if (is_utf8 (value) >= 0) break; } cd = iconv_open ("UTF-8", enc); if (cd == (iconv_t)-1) { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("info_helper: unsupported conversion %s -> UTF-8, no conversion performed\n"), enc); break; } { ICONV_CONST char *inbuf; char *outbuf; size_t inbytesleft, outbytesleft; if (!strncmp (enc, "UTF-16", 6) || !strncmp (enc, "UCS-2", 5)) { /* strlen() won't work with UTF-16* or UCS-2* */ inbytesleft = 0; while (value[inbytesleft] || value[inbytesleft + 1]) inbytesleft += 2; } /* ... do we need to handle UCS-4? Probably not. */ else inbytesleft = strlen(value); outbytesleft = 4 * inbytesleft; /* estimative (max) */ buf_free = malloc (outbytesleft + 1); if (!buf_free) break; inbuf = (ICONV_CONST char *)value; outbuf = buf_free; if (iconv (cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft) != (size_t)-1) { *outbuf = '\0'; buf_set = buf_free; } } } while (0); if (cd != (iconv_t)-1) iconv_close (cd); free (system_enc); #endif _meta_info_set_utf8 (stream, info, buf_set); free (buf_free); } /* * Reset (nullify) private info value. */ void _x_meta_info_reset (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; _meta_info_set_utf8 (stream, info, NULL); } /* * Reset (nullify) public info value. */ void _x_meta_info_public_reset (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (meta_valid (stream, info)) { xine_rwlock_wrlock (&stream->meta_lock); if (stream->meta_info_public[info] != stream->meta_info[info]) _x_freep (&stream->meta_info[info]); xine_rwlock_unlock (&stream->meta_lock); } } /* * Set private meta info value using current locale. */ void _x_meta_info_set (xine_stream_t *s, int info, const char *str) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (str) _meta_info_set_encoding (stream, info, str, NULL); } /* * Set private meta info value using specified encoding. */ void _x_meta_info_set_generic (xine_stream_t *s, int info, const char *str, const char *enc) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (str) _meta_info_set_encoding (stream, info, str, enc); } /* * Set private meta info value using utf8. */ void _x_meta_info_set_utf8 (xine_stream_t *s, int info, const char *str) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (str) _meta_info_set_utf8 (stream, info, str); } /* * Set private meta info from buf, 'len' bytes long. */ void _x_meta_info_n_set (xine_stream_t *s, int info, const char *buf, int len) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (meta_valid (stream, info) && len) { char *str = strndup (buf, len); _meta_info_set_encoding (stream, info, str, NULL); free(str); } } /* * Set private meta info value, from multiple arguments. */ void _x_meta_info_set_multi (xine_stream_t *s, int info, ...) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (meta_valid (stream, info)) { va_list ap; char *args[1025]; char *buf; size_t n, len; len = n = 0; va_start(ap, info); while((buf = va_arg(ap, char *)) && (n < 1024)) { len += strlen(buf) + 1; args[n] = buf; n++; } va_end(ap); args[n] = NULL; if(len) { char *p, *meta; p = meta = (char *) malloc(len + 1); n = 0; while(args[n]) { strcpy(meta, args[n]); meta += strlen(args[n]) + 1; n++; } *meta = '\0'; xine_rwlock_wrlock (&stream->meta_lock); if (stream->meta_info_public[info] != stream->meta_info[info]) free (stream->meta_info[info]); stream->meta_info[info] = p; if (p) meta_info_chomp (p); xine_rwlock_unlock (&stream->meta_lock); } } } /* * Retrieve private info value. */ const char *_x_meta_info_get (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; const char *meta_info; stream = stream->side_streams[0]; xine_rwlock_rdlock (&stream->meta_lock); meta_info = stream->meta_info[info]; xine_rwlock_unlock (&stream->meta_lock); return meta_info; } /* * Retrieve public info value. */ const char *_x_meta_info_get_public (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; char *pub_meta_info = NULL; stream = stream->side_streams[0]; if (meta_valid (stream, info)) { xine_rwlock_rdlock (&stream->meta_lock); pub_meta_info = stream->meta_info_public[info]; if (pub_meta_info != stream->meta_info[info]) { xine_rwlock_unlock (&stream->meta_lock); xine_rwlock_wrlock (&stream->meta_lock); free (pub_meta_info); stream->meta_info_public[info] = pub_meta_info = stream->meta_info[info]; } xine_rwlock_unlock (&stream->meta_lock); } return pub_meta_info; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/video_overlay.c��������������������������������������������������������0000644�0001750�0001750�00000102225�14647725152�016676� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "video_overlay" /* #define LOG_DEBUG */ #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <sys/types.h> #include <xine/buffer.h> #include <xine/xine_internal.h> #include <xine/sorted_array.h> #include <xine/xineutils.h> #include <xine/video_overlay.h> #include "bswap.h" #ifndef INT64_MAX # define INT64_MAX (int64_t)(((uint64_t)1 << (8 * sizeof (uint64_t) - 1)) - 1) #endif typedef struct { int8_t next, prev; } _video_overlay_node_t; typedef enum { _VOVL_FREE_FIRST = 0, _VOVL_FREE_LAST, _VOVL_USED_FIRST, _VOVL_USED_LAST, _VOVL_LAST } _video_overlay_node_index_t; static void _video_overlay_list_init (_video_overlay_node_t *a, uint32_t n) { uint32_t u; a[_VOVL_FREE_FIRST].next = _VOVL_LAST; a[_VOVL_FREE_FIRST].prev = -1; a[_VOVL_FREE_LAST].next = -1; a[_VOVL_FREE_LAST].prev = _VOVL_LAST + n - 1; for (u = 0; u < n; u++) a[_VOVL_LAST + u].next = _VOVL_LAST + u + 1, a[_VOVL_LAST + u].prev = _VOVL_LAST + u - 1; a[_VOVL_LAST].prev = _VOVL_FREE_FIRST; a[_VOVL_LAST + u - 1].next = _VOVL_FREE_LAST; a[_VOVL_USED_FIRST].next = _VOVL_USED_LAST; a[_VOVL_USED_FIRST].prev = -1; a[_VOVL_USED_LAST].next = -1; a[_VOVL_USED_LAST].prev = _VOVL_USED_FIRST; } static void _video_overlay_node_remove (_video_overlay_node_t *a, uint32_t indx) { uint32_t next = a[_VOVL_LAST + indx].next; uint32_t prev = a[_VOVL_LAST + indx].prev; a[prev].next = next; a[next].prev = prev; a[_VOVL_LAST + indx].next = -1; a[_VOVL_LAST + indx].prev = -1; } static void _video_overlay_node_append (_video_overlay_node_t *a, uint32_t used, uint32_t indx) { uint32_t next, prev; if (used) { next = _VOVL_USED_LAST; prev = a[_VOVL_USED_LAST].prev; } else { next = _VOVL_FREE_LAST; prev = a[_VOVL_FREE_LAST].prev; } a[_VOVL_LAST + indx].next = next; a[_VOVL_LAST + indx].prev = prev; a[prev].next = a[next].prev = _VOVL_LAST + indx; } static const uint32_t _vovl_bits[32] = { 0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010, 0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200, 0x00000400, 0x00000800, 0x00001000, 0x00002000, 0x00004000, 0x00008000, 0x00010000, 0x00020000, 0x00040000, 0x00080000, 0x00100000, 0x00200000, 0x00400000, 0x00800000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000 }; static uint32_t _vovl_bits_test (const uint32_t *field, uint32_t bit) { return field[bit >> 5] & _vovl_bits[bit & 31]; }; static uint32_t _vovl_bits_set (uint32_t *field, uint32_t bit) { uint32_t r = field[bit >> 5] & _vovl_bits[bit & 31]; field[bit >> 5] |= _vovl_bits[bit & 31]; return r; }; /* static void _vovl_bits_clear (uint32_t *field, uint32_t bit) { field[bit >> 5] &= ~_vovl_bits[bit & 31]; }; */ typedef struct video_overlay_s { video_overlay_manager_t video_overlay; xine_t *xine; int64_t last_vpts; struct { video_overlay_event_t buf[MAX_EVENTS]; uint8_t last_hide[MAX_OBJECTS]; pthread_mutex_t mutex_wait; xine_sarray_t *wait; int64_t first_vpts; pthread_mutex_t mutex_free; #define _VOVL_EVENT_INDEX_FIRST MAX_EVENTS #define _VOVL_EVENT_INDEX_LAST (MAX_EVENTS + 2) uint8_t list_free[MAX_EVENTS + 3]; } event; struct { video_overlay_object_t buf[MAX_OBJECTS]; _video_overlay_node_t indx_f[MAX_OBJECTS + _VOVL_LAST]; } objects; struct { pthread_mutex_t mutex; int8_t indx_r[MAX_OBJECTS]; _video_overlay_node_t indx_f[MAX_SHOWING + _VOVL_LAST]; int8_t handle[MAX_SHOWING]; int have, changed; } showing; } video_overlay_t; static void _vovl_event_free_reset (video_overlay_t *this) { uint32_t u; for (u = 0; u < MAX_EVENTS - 1; u++) this->event.list_free[u] = u + 1; this->event.list_free[MAX_EVENTS - 1] = _VOVL_EVENT_INDEX_FIRST; this->event.list_free[_VOVL_EVENT_INDEX_FIRST] = 0; this->event.list_free[_VOVL_EVENT_INDEX_LAST] = MAX_EVENTS - 1; } static uint32_t _vovl_event_free_get (video_overlay_t *this) { uint32_t u, v; u = this->event.list_free[_VOVL_EVENT_INDEX_FIRST]; /* yes this is empty safe :-) * if (u < MAX_EVENTS) */ v = this->event.list_free[_VOVL_EVENT_INDEX_FIRST] = this->event.list_free[u]; v = (v + 0x1000 - MAX_EVENTS) >> 12; this->event.list_free[_VOVL_EVENT_INDEX_LAST - 1 + v] = _VOVL_EVENT_INDEX_FIRST; return u; } static void _vovl_event_free_put (video_overlay_t *this, uint32_t u) { this->event.list_free[this->event.list_free[_VOVL_EVENT_INDEX_LAST]] = u; this->event.list_free[u] = _VOVL_EVENT_INDEX_FIRST; this->event.list_free[_VOVL_EVENT_INDEX_LAST] = u; } static void add_showing_handle (video_overlay_t *this, int32_t handle, int changed) { /* already showing? */ if (this->showing.indx_r[handle] < 0) { uint32_t n = this->showing.indx_f[_VOVL_FREE_FIRST].next; if (this->showing.indx_f[n].next >= 0) { n -= _VOVL_LAST; _video_overlay_node_remove (this->showing.indx_f, n); this->showing.handle[n] = handle; this->showing.indx_r[handle] = n; _video_overlay_node_append (this->showing.indx_f, 1, n); changed |= 1; } else { changed = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) not enough showing slots.\n", (int)handle); } } this->showing.changed += changed; } static void remove_showing_handle (video_overlay_t *this, int32_t handle) { if (this->showing.indx_r[handle] >= 0) { uint32_t n = this->showing.indx_r[handle]; _video_overlay_node_remove (this->showing.indx_f, n); this->showing.handle[n] = -1; this->showing.indx_r[handle] = -1; _video_overlay_node_append (this->showing.indx_f, 0, n); this->showing.changed++; } } /* allocate a handle from the object pool (exported function) */ static int32_t video_overlay_get_handle(video_overlay_manager_t *this_gen, int object_type ) { video_overlay_t *this = (video_overlay_t *) this_gen; int32_t n; pthread_mutex_lock (&this->event.mutex_free); n = this->objects.indx_f[_VOVL_FREE_FIRST].next; if (this->objects.indx_f[n].next >= 0) { n -= _VOVL_LAST; _video_overlay_node_remove (this->objects.indx_f, n); this->objects.buf[n].handle = n; this->objects.buf[n].object_type = object_type; _video_overlay_node_append (this->objects.indx_f, 1, n); } else { n = -1; } pthread_mutex_unlock (&this->event.mutex_free); return n; } /* free a handle from the object pool (internal function) */ static void _video_overlay_free_handle (video_overlay_t *this, int32_t handle) { _video_overlay_node_remove (this->objects.indx_f, handle); if (this->objects.buf[handle].overlay) { set_argb_layer_ptr (&this->objects.buf[handle].overlay->argb_layer, NULL); _x_freep (&this->objects.buf[handle].overlay->rle); _x_freep (&this->objects.buf[handle].overlay); } this->objects.buf[handle].handle = -1; _video_overlay_node_append (this->objects.indx_f, 0, handle); } /* exported free handle function. must take care of removing the object from showing and events lists. */ static void video_overlay_free_handle (video_overlay_manager_t *this_gen, int32_t handle) { video_overlay_t *this = (video_overlay_t *) this_gen; uint8_t h1[MAX_EVENTS]; uint32_t n1; if ((handle < 0) || (handle >= MAX_OBJECTS)) return; /* paranoia... */ pthread_mutex_lock (&this->showing.mutex); remove_showing_handle (this,handle); pthread_mutex_unlock (&this->showing.mutex); n1 = 0; pthread_mutex_lock (&this->event.mutex_wait); { uint32_t u; video_overlay_event_t *event; for (u = 0; (event = xine_sarray_get (this->event.wait, u)) != NULL; ) { if (event->object.handle == handle) { xine_sarray_remove (this->event.wait, u); if (event->object.overlay) { _x_freep (&event->object.overlay->rle); _x_freep (&event->object.overlay); } event->event_type = OVERLAY_EVENT_NULL; h1[n1++] = event - this->event.buf; } else { u++; } } } this->event.last_hide[handle] = 255; pthread_mutex_unlock (&this->event.mutex_wait); pthread_mutex_lock (&this->event.mutex_free); { uint32_t u; for (u = 0; u < n1; u++) _vovl_event_free_put (this, h1[u]); } _video_overlay_free_handle (this, handle); pthread_mutex_unlock (&this->event.mutex_free); } static void video_overlay_init (video_overlay_manager_t *this_gen) { video_overlay_t *this = (video_overlay_t *) this_gen; int i; pthread_mutex_lock (&this->showing.mutex); for (i = 0; i < MAX_SHOWING; i++) this->showing.handle[i] = -1; this->showing.changed = 0; pthread_mutex_unlock (&this->showing.mutex); pthread_mutex_lock (&this->event.mutex_wait); xine_sarray_clear (this->event.wait); for (i = 0; i < MAX_EVENTS; i++) { this->event.buf[i].event_type = 0; this->event.buf[i].object.overlay = NULL; this->event.buf[i].object.palette = NULL; } pthread_mutex_unlock (&this->event.mutex_wait); pthread_mutex_lock (&this->event.mutex_free); for (i=0; i < MAX_OBJECTS; i++) _video_overlay_free_handle (this, i); _vovl_event_free_reset (this); pthread_mutex_unlock (&this->event.mutex_free); } static void _video_overlay_clip_trans (uint8_t *tab) { /* keep compiler happy. tab will always be 4 aligned, see xine/video_out.h:vo_pverlay_s. */ uint32_t *w = (uint32_t *)(tab - ((uintptr_t)tab & 3)), u; for (u = 0; u < OVL_PALETTE_SIZE / 4; u++) { uint32_t v = *w, h = v; /* byte = (byte <= 0x0f) ? byte : 0x0f; */ h = ((h >> 1) | 0x80808080) - 0x08080808; v |= 0x10101010 - ((h >> 7) & 0x01010101); v &= 0x0f0f0f0f; *w++ = v; } } /* add an event to the events queue, sort the queue based on vpts. * This can be the API entry point for DVD subtitles. * One calls this function with an event, the event contains an overlay * and a vpts when to action/process it. vpts of 0 means action the event now. * One also has a handle, so one can match show and hide events. * * note: on success event->object.overlay is "taken" (caller will not have access * to overlay data including rle). * note2: handle will not be freed on HIDE events * the handle is removed from the currently showing list. */ static int32_t video_overlay_add_event (video_overlay_manager_t *this_gen, void *event_gen) { video_overlay_t *this = (video_overlay_t *)this_gen; video_overlay_event_t *event = (video_overlay_event_t *)event_gen; vo_overlay_t *new_overlay; uint32_t u; if (!this || !event) return -1; u = event->object.handle; do { if ((u < MAX_OBJECTS) && ((uint32_t)this->objects.buf[u].handle == u)) break; xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": add_event: invalid handle %d.\n", (int)event->object.handle); return -1; } while (0); /* FIXME: find the stream this manager belongs to, and then ask its metronom? */ if (event->vpts <= 0) event->vpts = this->last_vpts; if (event->object.overlay) { new_overlay = malloc (sizeof (*new_overlay)); if (new_overlay) { memcpy (new_overlay, event->object.overlay, sizeof (*new_overlay)); _video_overlay_clip_trans (&new_overlay->trans[0]); _video_overlay_clip_trans (&new_overlay->hili_trans[0]); /* We took the callers rle and data, therefore it will be our job to free it. * clear callers overlay so it will not be freed twice. */ memset (event->object.overlay, 0, sizeof (*event->object.overlay)); } } else { new_overlay = NULL; } pthread_mutex_lock (&this->event.mutex_free); u = _vovl_event_free_get (this); pthread_mutex_unlock (&this->event.mutex_free); if (u < MAX_EVENTS) { video_overlay_event_t *new_event = this->event.buf + u; /* the smart "update hide time of same handle" feature: * - HIDE again just updates time. * - SHOW revokes pending HIDE with same or later time. * thus, * SHOW(5) HIDE(9) SHOW(7) HIDE(100) HIDE(11) * will yield * SHOW(5) [HIDE and] SHOW(7) HIDE(11). */ uint32_t free_event = 255; /* memcpy everything except the actual image */ new_event->event_type = event->event_type; new_event->vpts = event->vpts; new_event->object.handle = event->object.handle; new_event->object.pts = event->object.pts; if (new_event->object.overlay) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) add_event: event->object.overlay was not freed!\n", (int)new_event->object.handle); } new_event->object.overlay = new_overlay; pthread_mutex_lock (&this->event.mutex_wait); /* optimize */ if (event->vpts < this->event.first_vpts) this->event.first_vpts = event->vpts; if (new_event->event_type == OVERLAY_EVENT_HIDE) { free_event = this->event.last_hide[new_event->object.handle]; this->event.last_hide[new_event->object.handle] = u; } else if (new_event->event_type == OVERLAY_EVENT_SHOW) { free_event = this->event.last_hide[new_event->object.handle]; this->event.last_hide[new_event->object.handle] = 255; if ((free_event != 255) && (this->event.buf[free_event].vpts < new_event->vpts)) free_event = 255; } if (free_event != 255) xine_sarray_remove_ptr (this->event.wait, this->event.buf + free_event); xine_sarray_add (this->event.wait, new_event); pthread_mutex_unlock (&this->event.mutex_wait); if (free_event != 255) { new_event = this->event.buf + free_event; if (new_event->object.overlay) { set_argb_layer_ptr (&new_event->object.overlay->argb_layer, NULL); _x_freep (&new_event->object.overlay->rle); _x_freep (&new_event->object.overlay); } pthread_mutex_lock (&this->event.mutex_free); _vovl_event_free_put (this, free_event); pthread_mutex_unlock (&this->event.mutex_free); } return u; } else { free (new_overlay); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) add_event: not enough event slots.\n", (int)event->object.handle); return -1; } } /* not currently used. James might need this for debugging menu stuff */ #ifdef LOG_DEBUG static void video_overlay_print_overlay( vo_overlay_t *ovl ) { printf (LOG_MODULE ": OVERLAY to show\n"); printf (LOG_MODULE ": \tx = %d y = %d width = %d height = %d\n", ovl->x, ovl->y, ovl->width, ovl->height ); printf (LOG_MODULE ": \tclut [%x %x %x %x]\n", ovl->color[0], ovl->color[1], ovl->color[2], ovl->color[3]); printf (LOG_MODULE ": \ttrans [%d %d %d %d]\n", ovl->trans[0], ovl->trans[1], ovl->trans[2], ovl->trans[3]); printf (LOG_MODULE ": \tclip top=%d bottom=%d left=%d right=%d\n", ovl->hili_top, ovl->hili_bottom, ovl->hili_left, ovl->hili_right); printf (LOG_MODULE ": \tclip_clut [%x %x %x %x]\n", ovl->hili_color[0], ovl->hili_color[1], ovl->hili_color[2], ovl->hili_color[3]); printf (LOG_MODULE ": \thili_trans [%d %d %d %d]\n", ovl->hili_trans[0], ovl->hili_trans[1], ovl->hili_trans[2], ovl->hili_trans[3]); return; } #endif /* process overlay events if vpts == 0 will process everything now (used in flush) return true if something has been processed */ static int video_overlay_event (video_overlay_t *this, int64_t vpts) { uint8_t h1[MAX_EVENTS], h2[MAX_OBJECTS]; uint32_t n1, ndone, nremove = 0, refs[(MAX_OBJECTS + 31) >> 5] = {[0] = 0}; if (vpts <= 0) vpts = INT64_MAX; else this->last_vpts = vpts; pthread_mutex_lock (&this->event.mutex_wait); /* the way most frequent case: no changes for now. */ if (vpts < this->event.first_vpts) { pthread_mutex_unlock (&this->event.mutex_wait); return 0; } /* take out relevant events. */ { int i; video_overlay_event_t *event, e; e.vpts = vpts; i = xine_sarray_binary_search (this->event.wait, &e); if (i < 0) ndone = ~i; else ndone = i + 1; event = xine_sarray_get (this->event.wait, ndone); this->event.first_vpts = event ? event->vpts : INT64_MAX; } if (!ndone) { pthread_mutex_unlock (&this->event.mutex_wait); return 0; } for (n1 = 0; n1 < ndone; n1++) { video_overlay_event_t *event = xine_sarray_remove (this->event.wait, 0); h1[n1] = event - this->event.buf; if ((event->event_type == OVERLAY_EVENT_HIDE) && (this->event.last_hide[event->object.handle] == h1[n1])) this->event.last_hide[event->object.handle] = 255; } pthread_mutex_unlock (&this->event.mutex_wait); /* perform changes. */ pthread_mutex_lock (&this->showing.mutex); for (n1 = 0; n1 < ndone; n1++) { video_overlay_event_t *event = this->event.buf + h1[n1]; int32_t handle = event->object.handle; #ifdef LOG_DEBUG printf (LOG_MODULE ": video_overlay_event: handle = %d\n", handle); #endif switch (event->event_type) { case OVERLAY_EVENT_SHOW: { int changed = 0; #ifdef LOG_DEBUG printf (LOG_MODULE ": SHOW SPU NOW\n"); #endif if (event->object.overlay) { /* set new image */ changed = 1; #ifdef LOG_DEBUG video_overlay_print_overlay (event->object.overlay); #endif /* this->objects.buf[handle].overlay is about to be * overwritten by this event data. make sure we free it if needed. */ if (this->objects.buf[handle].overlay) { /* it is legal to SHOW again with new image, without extra HIDE. xprintf(this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) object->overlay was not freed!\n", (int)handle); */ set_argb_layer_ptr (&this->objects.buf[handle].overlay->argb_layer, NULL); _x_freep (&this->objects.buf[handle].overlay->rle); _x_freep (&this->objects.buf[handle].overlay); } this->objects.buf[handle].overlay = event->object.overlay; event->object.overlay = NULL; } /* it is also legal to re-SHOW after HIDE without a new image. */ if (this->objects.buf[handle].overlay) { this->objects.buf[handle].handle = handle; this->objects.buf[handle].pts = event->object.pts; add_showing_handle (this, handle, changed); } } break; case OVERLAY_EVENT_HIDE: #ifdef LOG_DEBUG printf (LOG_MODULE ": HIDE SPU NOW\n"); #endif /* free any (unneeded) overlay associated with this event */ if (event->object.overlay) { set_argb_layer_ptr (&event->object.overlay->argb_layer, NULL); _x_freep (&event->object.overlay->rle); _x_freep (&event->object.overlay); } remove_showing_handle (this, handle); break; case OVERLAY_EVENT_FREE_HANDLE: #ifdef LOG_DEBUG printf (LOG_MODULE ": FREE SPU NOW\n"); #endif /* free any overlay associated with this event */ if (event->object.overlay) { set_argb_layer_ptr (&event->object.overlay->argb_layer, NULL); _x_freep (&event->object.overlay->rle); _x_freep (&event->object.overlay); } remove_showing_handle (this, handle); event->object.handle = -1; if (!_vovl_bits_set (refs, handle)) h2[nremove++] = handle; break; case OVERLAY_EVENT_MENU_BUTTON: /* mixes palette and copy clip coords */ #ifdef LOG_DEBUG printf (LOG_MODULE ": MENU BUTTON NOW\n"); #endif #if 0 /* This code drops buttons, where the button PTS derived from the NAV * packet on DVDs does not match the SPU PTS. Practical experience shows, * that this is not necessary and causes problems with some DVDs */ if (event->object.pts != this->objects.buf[handle].pts) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": MENU BUTTON DROPPED menu pts=%lld spu pts=%lld\n", event->object.pts, this->objects.buf[handle].pts); break; } #endif if (event->object.overlay) { if (this->objects.buf[handle].overlay) { vo_overlay_t *overlay = this->objects.buf[handle].overlay; vo_overlay_t *event_overlay = event->object.overlay; #ifdef LOG_DEBUG printf (LOG_MODULE ": overlay present\n"); #endif this->objects.buf[handle].handle = handle; overlay->hili_top = event_overlay->hili_top; overlay->hili_bottom = event_overlay->hili_bottom; overlay->hili_left = event_overlay->hili_left; overlay->hili_right = event_overlay->hili_right; overlay->hili_color[0] = event_overlay->hili_color[0]; overlay->hili_color[1] = event_overlay->hili_color[1]; overlay->hili_color[2] = event_overlay->hili_color[2]; overlay->hili_color[3] = event_overlay->hili_color[3]; memcpy (&overlay->hili_trans[0], &event_overlay->hili_trans[0], 4); overlay->hili_rgb_clut = event_overlay->hili_rgb_clut; #ifdef LOG_DEBUG video_overlay_print_overlay (event->object.overlay); #endif add_showing_handle (this, handle, 1); } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) EVENT_MENU_BUTTON without base image.\n", (int)handle); } set_argb_layer_ptr (&event->object.overlay->argb_layer, NULL); if (event->object.overlay->rle) { _x_freep (&event->object.overlay->rle); xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) warning: EVENT_MENU_BUTTON with rle data\n", (int)handle); } _x_freep (&event->object.overlay); } else { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) EVENT_MENU_BUTTON without button image.\n", (int)handle); } break; default: xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": (%d) unhandled event type %d.\n", (int)handle, event->event_type); break; } } pthread_mutex_unlock (&this->showing.mutex); /* remove orphaned events */ if (nremove) { video_overlay_event_t *event; pthread_mutex_lock (&this->event.mutex_wait); for (n1 = 0; (event = xine_sarray_get (this->event.wait, n1)) != NULL; ) { uint32_t handle = event->object.handle; event->object.handle = -1; if (_vovl_bits_test (refs, handle)) { this->event.last_hide[handle] = 255; xine_sarray_remove (this->event.wait, n1); h1[ndone++] = event - this->event.buf; if (event->object.overlay) { set_argb_layer_ptr (&event->object.overlay->argb_layer, NULL); _x_freep (&event->object.overlay->rle); _x_freep (&event->object.overlay); } } else { n1++; } } pthread_mutex_unlock (&this->event.mutex_wait); } /* free events/handles. */ pthread_mutex_lock (&this->event.mutex_free); for (n1 = 0; n1 < ndone; n1++) _vovl_event_free_put (this, h1[n1]); for (n1 = 0; n1 < nremove; n1++) _video_overlay_free_handle (this, h2[n1]); pthread_mutex_unlock (&this->event.mutex_free); return ndone; } void _x_overlay_clut_yuv2rgb(vo_overlay_t *overlay, int video_color_matrix) { int cm = 10; /* ITU-R 601 (SD) */ if (!overlay->rgb_clut) { uint8_t *p = (uint8_t *)overlay->color; if ((p[3] == 'X') && (p[7] == 'C') && (p[11] == 'M')) { cm = p[15]; if ((cm >> 1) == 2) /* undefined */ cm = video_color_matrix; } _x_clut_yuv2rgb(overlay->color, sizeof(overlay->color) / sizeof (overlay->color[0]), cm); overlay->rgb_clut++; } if (!overlay->hili_rgb_clut) { _x_clut_yuv2rgb(overlay->hili_color, sizeof (overlay->color) / sizeof (overlay->color[0]), cm); overlay->hili_rgb_clut++; } } static void clut_to_argb(const uint32_t *color, const uint8_t *trans, int num_items, uint32_t *argb, const char *format) { /* xine/alphablend.h says: struct clut_s { uint8_t cb; uint8_t cr; uint8_t y; uint8_t foo; } */ typedef union { uint32_t w; clut_t c; } _clut_t; /* (n * 255 + 7) / 15 */ static const _clut_t t[] = { {.c = {.foo = 0}}, {.c = {.foo = 17}}, {.c = {.foo = 34}}, {.c = {.foo = 51}}, {.c = {.foo = 68}}, {.c = {.foo = 85}}, {.c = {.foo = 102}}, {.c = {.foo = 119}}, {.c = {.foo = 136}}, {.c = {.foo = 153}}, {.c = {.foo = 170}}, {.c = {.foo = 187}}, {.c = {.foo = 204}}, {.c = {.foo = 221}}, {.c = {.foo = 238}}, {.c = {.foo = 255}} }; const _clut_t mask1 = {.c = {.cr = 255}}, mask2 = {.c = {.cb = 255, .y = 255}}, mask3 = {.c = {.cb = 255, .cr = 255, .y = 255}}; int i; if (!strcmp(format, "BGRA")) { for (i = 0; i < num_items; i++) argb[i] = (color[i] & mask3.w) + t[trans[i] & 15].w; } else if (!strcmp(format, "RGBA")) { for (i = 0; i < num_items; i++) { uint32_t v = color[i]; argb[i] = (((v << 16) | (v >> 16)) & mask2.w) + (v & mask1.w) + t[trans[i] & 15].w; } } else { fprintf(stderr, "clut_to_argb: unknown format %s\n", format); } } #define LUT_SIZE (sizeof(overlay->color)/sizeof(overlay->color[0])) void _x_overlay_to_argb32 (const vo_overlay_t *overlay, uint32_t *rgba_buf, int stride, const char *format) { const rle_elem_t *rle = overlay->rle, *rle_end = rle + overlay->num_rle; int lines1, lines2, lines3; int pixels1, pixels2, pixels3; int prest, pad = stride - overlay->width; uint32_t *rgba = rgba_buf, colors[LUT_SIZE * 2], color; clut_to_argb (overlay->color, overlay->trans, LUT_SIZE, colors, format); #define GET_DIM(dest,src,max) dest = src; if (dest < 0) dest = 0; else if (dest > max) dest = max; GET_DIM (lines1, overlay->hili_top, overlay->height); GET_DIM (lines2, overlay->hili_bottom - overlay->hili_top + 1, overlay->height - lines1); lines3 = overlay->height - lines1 - lines2; GET_DIM (pixels1, overlay->hili_left, overlay->width); GET_DIM (pixels2, overlay->hili_right - overlay->hili_left + 1, overlay->width - pixels1); pixels3 = overlay->width - pixels1 - pixels2; #undef GET_DIM if ((lines2 > 0) && (pixels2 > 0)) { /* highlight */ clut_to_argb (overlay->hili_color, overlay->hili_trans, LUT_SIZE, colors + LUT_SIZE, format); } else { lines1 += lines3; lines2 = lines3 = 0; pixels1 += pixels3; pixels2 = pixels3 = 0; } #define MAKE_LINE(offs) \ while (1) { \ int pleft = prest > pixels ? pixels : prest; \ pixels -= pleft; \ prest -= pleft; \ while (pleft > 0) { \ *rgba++ = color; \ pleft--; \ } \ if (pixels <= 0) \ break; \ if (rle >= rle_end) \ goto _fill; \ color = colors[rle->color + offs]; \ prest = rle->len; \ rle++; \ } prest = 0; color = 0; /* top */ while (lines1 > 0) { int pixels = overlay->width; MAKE_LINE (0); rgba += pad; lines1--; } /* highlight */ while (lines2 > 0) { /* left */ int pixels = pixels1; MAKE_LINE (0); /* highlighted */ if (prest > 0) color = colors[rle[-1].color + LUT_SIZE]; pixels = pixels2; MAKE_LINE (LUT_SIZE); /* right */ if (prest > 0) color = colors[rle[-1].color]; pixels = pixels3; MAKE_LINE (0); rgba += pad; lines2--; } /* bottom */ while (lines3 > 0) { int pixels = overlay->width; MAKE_LINE (0); rgba += pad; lines3--; } #undef MAKE_LINE return; _fill: { int n; n = rgba_buf + stride * overlay->height - rgba; if (n > 0) memset (rgba, 0, n * sizeof (uint32_t)); } } #undef LUT_SIZE /* This is called from video_out.c * must call output->overlay_blend for each active overlay. */ static void video_overlay_multiple_overlay_blend (video_overlay_manager_t *this_gen, int64_t vpts, vo_driver_t *output, vo_frame_t *vo_img, int enabled) { video_overlay_t *this = (video_overlay_t *) this_gen; /* Look at next events, if current video vpts > first event on queue, process the event * else just continue */ video_overlay_event (this, vpts); /* Scan through 5 entries and display any present.*/ pthread_mutex_lock (&this->showing.mutex); if (output->overlay_begin) output->overlay_begin (output, vo_img, this->showing.changed); if (enabled && output->overlay_blend) { uint32_t n; for (n = this->showing.indx_f[_VOVL_USED_FIRST].next; this->showing.indx_f[n].next >= 0; n = this->showing.indx_f[n].next) output->overlay_blend (output, vo_img, this->objects.buf[this->showing.handle[n - _VOVL_LAST]].overlay); } if (output->overlay_end) output->overlay_end (output, vo_img); if (this->showing.changed) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": %d showing changes @ vpts %" PRId64 ".\n", this->showing.changed, vpts); this->showing.changed = 0; } pthread_mutex_unlock (&this->showing.mutex); } /* this should be called on stream end or stop to make sure every hide event is processed. */ static void video_overlay_flush_events (video_overlay_manager_t *this_gen) { video_overlay_t *this = (video_overlay_t *) this_gen; video_overlay_event (this, 0); } /* this is called from video_out.c on still frames to check if a redraw is needed. */ static int video_overlay_redraw_needed (video_overlay_manager_t *this_gen, int64_t vpts) { video_overlay_t *this = (video_overlay_t *) this_gen; video_overlay_event( this, vpts ); if (this->showing.changed) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": %d showing changes @ vpts %" PRId64 ".\n", this->showing.changed, vpts); } return this->showing.changed; } static void video_overlay_dispose (video_overlay_manager_t *this_gen) { video_overlay_t *this = (video_overlay_t *) this_gen; int i; pthread_mutex_lock (&this->event.mutex_wait); for (i = 0; i < MAX_EVENTS; i++) { if (this->event.buf[i].object.overlay) { _x_freep (&this->event.buf[i].object.overlay->rle); _x_freep (&this->event.buf[i].object.overlay); } } for (i = 0; i < MAX_OBJECTS; i++) _video_overlay_free_handle (this, i); pthread_mutex_unlock (&this->event.mutex_wait); xine_sarray_delete (this->event.wait); pthread_mutex_destroy (&this->showing.mutex); pthread_mutex_destroy (&this->event.mutex_free); pthread_mutex_destroy (&this->event.mutex_wait); free (this); } static int _video_overlay_event_cmp (void *a, void *b) { video_overlay_event_t *d = (video_overlay_event_t *)a; video_overlay_event_t *e = (video_overlay_event_t *)b; return (d->vpts < e->vpts) ? -1 : (d->vpts > e->vpts) ? 1 : 0; } video_overlay_manager_t *_x_video_overlay_new_manager (xine_t *xine) { int i; video_overlay_t *this = calloc (1, sizeof (*this)); if (!this) return NULL; pthread_mutex_init (&this->event.mutex_free, NULL); pthread_mutex_init (&this->event.mutex_wait, NULL); this->event.wait = xine_sarray_new (MAX_EVENTS, _video_overlay_event_cmp); xine_sarray_set_mode (this->event.wait, XINE_SARRAY_MODE_LAST); pthread_mutex_init (&this->showing.mutex, NULL); #ifndef HAVE_ZERO_SAFE_MEM this->last_vpts = 0; for (i = 0; i < MAX_EVENTS; i++) { this->event.buf[i].object.overlay = NULL; this->event.buf[i].event_type = 0; } this->showing.have = 0; #endif this->event.first_vpts = INT64_MAX; memset (this->event.last_hide, 255, sizeof (this->event.last_hide)); for (i = 0; i < MAX_OBJECTS; i++) { this->objects.buf[i].handle = -1; #ifndef HAVE_ZERO_SAFE_MEM this->objects.buf[i].object_type = 0; this->objects.buf[i].pts = 0; this->objects.buf[i].overlay = NULL; this->objects.buf[i].palette = NULL; this->objects.buf[i].palette_type = 0; #endif } _video_overlay_list_init (this->objects.indx_f, MAX_OBJECTS); memset (this->showing.handle, -1 & 255, sizeof (this->showing.handle)); memset (this->showing.indx_r, -1 & 255, sizeof (this->showing.indx_r)); _video_overlay_list_init (this->showing.indx_f, MAX_SHOWING); this->xine = xine; this->video_overlay.init = video_overlay_init; this->video_overlay.dispose = video_overlay_dispose; this->video_overlay.get_handle = video_overlay_get_handle; this->video_overlay.free_handle = video_overlay_free_handle; this->video_overlay.add_event = video_overlay_add_event; this->video_overlay.flush_events = video_overlay_flush_events; this->video_overlay.redraw_needed = video_overlay_redraw_needed; this->video_overlay.multiple_overlay_blend = video_overlay_multiple_overlay_blend; return &this->video_overlay; } ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/lrb.c������������������������������������������������������������������0000644�0001750�0001750�00000004604�14647725152�014610� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "lrb.h" #include <xine/xineutils.h> lrb_t *lrb_new (int max_num_entries, fifo_buffer_t *fifo) { lrb_t *this; this = calloc(1, sizeof(lrb_t)); this->max_num_entries = max_num_entries; this->cur_num_entries = 0; this->fifo = fifo; this->newest = NULL; this->oldest = NULL; return this; } void lrb_drop (lrb_t *this) { buf_element_t *buf = this->oldest; _x_assert(buf); this->oldest = buf->next; buf->free_buffer (buf); this->cur_num_entries--; } void lrb_add (lrb_t *this, buf_element_t *buf) { if (!this->newest) { this->newest = buf; this->oldest = buf; buf->next = NULL; this->cur_num_entries = 1; } else { if (this->cur_num_entries >= this->max_num_entries) lrb_drop (this); buf->next = NULL; this->newest->next = buf; this->newest = buf; this->cur_num_entries++; } lprintf ("%d elements in buffer\n", this->cur_num_entries); } void lrb_feedback (lrb_t *this, fifo_buffer_t *fifo) { pthread_mutex_lock (&fifo->mutex); while (this->cur_num_entries) { buf_element_t *buf = this->oldest; buf->next = fifo->first; fifo->first = buf; if (!fifo->last) fifo->last = buf; fifo->fifo_size++; pthread_cond_signal (&fifo->not_empty); this->oldest = buf->next; this->cur_num_entries--; lprintf ("feedback\n"); } if (!this->oldest) this->newest = NULL; pthread_mutex_unlock (&fifo->mutex); } void lrb_flush (lrb_t *this) { while (this->cur_num_entries) lrb_drop (this); } ����������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/audio_out.c������������������������������������������������������������0000644�0001750�0001750�00000341355�14647725152�016030� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with self program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /** * @file * @brief xine-lib audio output implementation * * @date 2001-08-20 First implementation of Audio sync and Audio driver separation. * (c) 2001 James Courtier-Dutton <james@superbug.demon.co.uk> * @date 2001-08-22 James imported some useful AC3 sections from the previous * ALSA driver. (c) 2001 Andy Lo A Foe <andy@alsaplayer.org> * * * General Programming Guidelines: - * New concept of an "audio_frame". * An audio_frame consists of all the samples required to fill every * audio channel to a full amount of bits. * So, it does not mater how many bits per sample, or how many audio channels * are being used, the number of audio_frames is the same. * E.g. 16 bit stereo is 4 bytes, but one frame. * 16 bit 5.1 surround is 12 bytes, but one frame. * The purpose of this is to make the audio_sync code a lot more readable, * rather than having to multiply by the amount of channels all the time * when dealing with audio_bytes instead of audio_frames. * * The number of samples passed to/from the audio driver is also sent * in units of audio_frames. * * Currently, James has tested with OSS: Standard stereo out, SPDIF PCM, SPDIF AC3 * ALSA: Standard stereo out * No testing has been done of ALSA SPDIF AC3 or any 4,5,5.1 channel output. * Currently, I don't think resampling functions, as I cannot test it. * * equalizer based on * * PCM time-domain equalizer * * Copyright (C) 2002 Felipe Rivera <liebremx at users sourceforge net> * * heavily modified by guenter bartsch 2003 for use in libxine */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <fcntl.h> #include <math.h> #include <unistd.h> #include <pthread.h> #include <inttypes.h> #include <math.h> #include <sys/time.h> #define XINE_ENABLE_EXPERIMENTAL_FEATURES #define LOG_MODULE "audio_out" #define LOG_VERBOSE /* #define LOG */ #define LOG_RESAMPLE_SYNC 0 #include <xine/xine_internal.h> #include <xine/xineutils.h> #include <xine/audio_out.h> #include <xine/resample.h> #include <xine/metronom.h> #include "xine_private.h" #define NUM_AUDIO_BUFFERS 32 #define AUDIO_BUF_SIZE 32768 /* By adding gap errors (difference between reported and expected * sound card clock) into metronom's vpts_offset we can use its * smoothing algorithms to correct sound card clock drifts. * obs: previously this error was added to xine scr. * * audio buf ---> metronom --> audio fifo --> (buf->vpts - hw_vpts) * (vpts_offset + error) gap * <---------- control --------------| * * Unfortunately audio fifo adds a large delay to our closed loop. * * The defines below are designed to avoid updating the metronom too fast. * - it will only be updated 1 time per second (so it has a chance of * distributing the error for several frames). * - it will only be updated 2 times for the whole audio fifo size * length (so the control will wait to see the feedback effect) * - each update will be of gap/SYNC_GAP_RATE. * * Sound card clock correction can only provide smooth playback for * errors < 1% nominal rate. For bigger errors (bad streams) audio * buffers may be dropped or gaps filled with silence. */ #define SYNC_TIME_INTERVAL (1 * 90000) #define SYNC_BUF_INTERVAL NUM_AUDIO_BUFFERS / 2 /* Alternative for metronom feedback: fix sound card clock drift * by resampling all audio data, so that the sound card keeps in * sync with the system clock. This may help, if one uses a DXR3/H+ * decoder board. Those have their own clock (which serves as xine's * master clock) and can only operate at fixed frame rates (if you * want smooth playback). Resampling then avoids A/V sync problems, * gaps filled with 0-frames and jerky video playback due to different * clock speeds of the sound card and DXR3/H+. */ #define RESAMPLE_SYNC_WINDOW 50 #define RESAMPLE_MAX_GAP_DIFF 150 #define RESAMPLE_REDUCE_GAP_THRESHOLD 200 typedef struct { double last_factor; int window; int reduce_gap; uint64_t window_duration, last_vpts; int64_t recent_gap[8], last_avg_gap; int valid; } resample_sync_t; /* * equalizer stuff */ #define EQ_BANDS 10 #define EQ_CHANNELS 8 #define FP_FRBITS 28 #define EQ_REAL(x) ((int)((x) * (1 << FP_FRBITS))) typedef struct { int beta; int alpha; int gamma; } sIIRCoefficients; static const sIIRCoefficients iir_cf[] = { /* 31 Hz*/ { EQ_REAL(9.9691562441e-01), EQ_REAL(1.5421877947e-03), EQ_REAL(1.9968961468e+00) }, /* 62 Hz*/ { EQ_REAL(9.9384077546e-01), EQ_REAL(3.0796122698e-03), EQ_REAL(1.9937629855e+00) }, /* 125 Hz*/ { EQ_REAL(9.8774277725e-01), EQ_REAL(6.1286113769e-03), EQ_REAL(1.9874275518e+00) }, /* 250 Hz*/ { EQ_REAL(9.7522112569e-01), EQ_REAL(1.2389437156e-02), EQ_REAL(1.9739682661e+00) }, /* 500 Hz*/ { EQ_REAL(9.5105628526e-01), EQ_REAL(2.4471857368e-02), EQ_REAL(1.9461077269e+00) }, /* 1k Hz*/ { EQ_REAL(9.0450844499e-01), EQ_REAL(4.7745777504e-02), EQ_REAL(1.8852109613e+00) }, /* 2k Hz*/ { EQ_REAL(8.1778971701e-01), EQ_REAL(9.1105141497e-02), EQ_REAL(1.7444877599e+00) }, /* 4k Hz*/ { EQ_REAL(6.6857185264e-01), EQ_REAL(1.6571407368e-01), EQ_REAL(1.4048592171e+00) }, /* 8k Hz*/ { EQ_REAL(4.4861333678e-01), EQ_REAL(2.7569333161e-01), EQ_REAL(6.0518718075e-01) }, /* 16k Hz*/ { EQ_REAL(2.4201241845e-01), EQ_REAL(3.7899379077e-01), EQ_REAL(-8.0847117831e-01) }, }; /* XXX: Apart from the typedef in include/xine/audio_out.h, this is used nowhere in xine. */ struct audio_fifo_s { audio_buffer_t *first; audio_buffer_t **add; pthread_mutex_t mutex; pthread_cond_t not_empty; pthread_cond_t empty; int num_buffers; int num_buffers_max; int num_waiters; }; typedef struct { xine_audio_port_t ao; /* public part */ /* private stuff */ struct { pthread_mutex_t mutex; pthread_mutex_t intr_mutex; /* protects num_driver_actions */ pthread_cond_t intr_wake; /* informs about num_driver_actions-- */ ao_driver_t *d; uint32_t open; /* 0 (closed), 1 (known idle), 2 (open) */ int intr_num; /* number of threads, that wish to call * functions needing driver_lock */ int dreqs_all; /* statistics */ int dreqs_wait; uint32_t speed; uint32_t trick; /* play audio even on slow/fast speeds */ } driver; uint32_t audio_loop_running:1; uint32_t grab_only:1; /* => do not start thread, frontend will consume samples */ uint32_t do_resample:1; uint32_t do_compress:1; uint32_t do_amp:1; uint32_t amp_mute:1; uint32_t do_equ:1; uint32_t av_fine_sync; metronom_clock_t *clock; xine_private_t *xine; #define STREAMS_DEFAULT_SIZE 32 int num_null_streams; int num_anon_streams; int num_streams; int streams_size; xine_stream_private_t **streams, *streams_default[STREAMS_DEFAULT_SIZE]; xine_rwlock_t streams_lock; pthread_t audio_thread; uint32_t audio_step; /* pts per 32 768 samples (sample = #bytes/2) */ uint32_t in_channels; uint32_t out_pts_per_kframe; /* pts per 1024 frames */ uint32_t out_frames_per_kpts; /* frames per 1024/90000 sec */ uint32_t out_channels; int av_sync_method_conf; resample_sync_t resample_sync_info; double resample_sync_factor; /* correct buffer length by this factor * to sync audio hardware to (dxr3) clock */ int resample_sync_method; /* fix sound card clock drift by resampling */ int gap_tolerance; int small_gap; /* gap_tolerance * sqrt (speed) / sqrt (XINE_FINE_SPEED_NORMAL), * to avoid nervous metronom syncing in trick mode. */ int fine_gap; /* small_gap >> GAP_RING_LD */ ao_format_t input, output; /* format conversion done at audio_out.c */ double frame_rate_factor; double output_frame_excess; /* used to keep track of 'half' frames */ int resample_conf; uint32_t force_rate; /* force audio output rate to this value if non-zero */ struct { pthread_mutex_t mutex; pthread_cond_t not_empty; audio_buffer_t *first; audio_buffer_t **add; int num_buffers; int num_buffers_max; int num_waiters; } free_fifo; struct { pthread_mutex_t mutex; pthread_cond_t not_empty; pthread_cond_t empty; audio_buffer_t *first, **add; int num_buffers; int num_waiters; uint32_t pts_fill; uint32_t pts_last_buf; uint32_t pts_in_driver; int seek_count1; struct timespec wake_time; /* time to drop next buf in trick play mode without sound */ int use_wake_time; /* 0 (play), 1 (wake_time or event), 2 (event) */ int wake_now; /* immediate response requested (speed change, shutdown) */ int discard_buffers; xine_stream_private_t *buf_streams[NUM_AUDIO_BUFFERS]; } out_fifo; struct { uint32_t speed, trick; #define _AO_FLAG_PAUSE 1 #define _AO_FLAG_SILENT_TRICK 2 uint32_t flags; int64_t last_flush_vpts; int seek_count2; int seek_count3; int seek_count_n; /* extra info ring buffer, compensating for driver delay (not fifo size). * beware of good old audio cd who used to send impressive 75 bufs per second. */ #define EI_RING_SIZE 128 /* 2^n please */ int ei_write; int ei_read; /* a/v fine sync filter */ #define GAP_RING_LD 3 #define GAP_RING_SIZE (1 << GAP_RING_LD) #define GAP_RING_MASK (GAP_RING_SIZE - 1) int gr_pos; int gr_sum; int gr_gaps[GAP_RING_SIZE]; int dropped; /* driver.write () does support writing large amounts of data. * the call will then block until playback has cleared the way. * we can (and used to) do that all the time. * unfortunately, that will also make the render thread spend * most of its time waiting inside driver.write (), and delays * other stuff like flush, (un)pause, speed change, and mixer control. * this is why driver.intr_* is there. * alternatively, do it just after settings change, and learn * the driver's internal buf size. for example, alsa 10k1 has * 16k frames. then, insert voluntary waits inside ao_out_fifo_get () * to stay close below 100% fill. * driver buffer statistics, in frames / buffers (_num): */ int32_t dbuf_min, dbuf_max, dbuf_num, dbuf_size, dbuf_used; } rp; int64_t last_audio_vpts; int16_t last_sample[RESAMPLE_MAX_CHANNELS]; audio_buffer_t *frame_buf[2]; /* two buffers for "stackable" conversions */ int16_t *zero_space; int passthrough_offset, ptoffs; /* some built-in audio filters */ double compression_factor; /* current compression */ double compression_factor_max; /* user limit on compression */ double amp_factor; int amp_level; /* 10-band equalizer */ int eq_settings[EQ_BANDS]; int eq_gain[EQ_BANDS]; /* Coefficient history for the IIR filter */ int eq_data_history[EQ_CHANNELS][EQ_BANDS][4]; int last_gap; int last_sgap; uint32_t pts_in_driver; /* If driver cannot pause while keeping its own buffers alive, * resend some frames at unpause time instead of filling a big gap with silence. */ struct { #define RESEND_BUF_SIZE (1 << 20) int driver_caps; int64_t vpts; uint32_t speed; uint32_t rate; uint32_t bits; int mode; int frame_size; int write; int wrap; int max; uint8_t *buf; } resend; uint8_t *base_samp; audio_buffer_t base_buf[NUM_AUDIO_BUFFERS + 2]; extra_info_t base_ei[EI_RING_SIZE + NUM_AUDIO_BUFFERS + 2]; } aos_t; static void ao_dbuf_reset (aos_t *this) { this->rp.dbuf_max = this->rp.dbuf_num = this->rp.dbuf_used = 0; this->rp.dbuf_size = 0x3fffffff; } static void ao_dbuf_set_min (aos_t *this, int32_t samples) { this->rp.dbuf_min = samples; } static void ao_dbuf_set_max (aos_t *this, int32_t samples) { int32_t d = this->rp.dbuf_max - samples, mask = d >> 31; this->rp.dbuf_max -= d & mask; mask = ~mask; this->rp.dbuf_num = (this->rp.dbuf_num & mask) + (mask & 1); if (this->rp.dbuf_num == 16) { const char *s = "off"; /* dont risk stutter on very small bufs. */ if (this->rp.dbuf_max > (11 * 1024)) this->rp.dbuf_size = (this->rp.dbuf_max + 1023) & ~1023, s = "on"; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, LOG_MODULE ": driver buf size %d ... %d frames, overrun hack %s.\n", (int)this->rp.dbuf_min, (int)this->rp.dbuf_max, s); } } static void ao_gap_ring_reset (aos_t *this) { int i; this->rp.gr_pos = 0; this->rp.gr_sum = 0; for (i = 0; i < GAP_RING_SIZE; i++) this->rp.gr_gaps[i] = 0; } static int ao_gap_ring_add (aos_t *this, int gap) { int i = this->rp.gr_pos; this->rp.gr_sum -= this->rp.gr_gaps[i]; this->rp.gr_gaps[i] = gap; i = (i + 1) & GAP_RING_MASK; this->rp.gr_pos = i; this->rp.gr_sum += gap; return this->rp.gr_sum >> GAP_RING_LD; } static uint32_t uint_sqrt (uint32_t v) { uint32_t b = 0, e = 0xffff; do { uint32_t m = (b + e) >> 1; if (m * m >= v) e = m; else b = m + 1; } while (b < e); return b; } static void ao_eq_update (aos_t *this) { /* TJ. gxine assumes a setting range of 0..100, with 100 being the default. Lets try to fix that very broken api like this: 1. If all settings are the same, disable eq. 2. A setting step of 1 means 0.5 dB relative. 3. The highest setting refers to 0 dB absolute. */ int smin, smax, i; smin = smax = this->eq_settings[0]; for (i = 1; i < EQ_BANDS; i++) { if (this->eq_settings[i] < smin) smin = this->eq_settings[i]; else if (this->eq_settings[i] > smax) smax = this->eq_settings[i]; } if (smin == smax) { this->do_equ = 0; } else { for (i = 0; i < EQ_BANDS; i++) { uint32_t setting = smax - this->eq_settings[i]; if (setting > 99) { this->eq_gain[i] = EQ_REAL (0.0); } else { static const int mant[12] = { EQ_REAL (1.0), EQ_REAL (0.94387431), EQ_REAL (0.89089872), EQ_REAL (0.84089642), EQ_REAL (0.79370053), EQ_REAL (0.74915354), EQ_REAL (0.70710678), EQ_REAL (0.66741993), EQ_REAL (0.62996052), EQ_REAL (0.59460355), EQ_REAL (0.56123102), EQ_REAL (0.52973155) }; uint32_t exp = setting / 12; setting = setting % 12; this->eq_gain[i] = mant[setting] >> exp; } } /* Not very precise but better than nothing... */ if (this->input.rate < 15000) { for (i = EQ_BANDS - 1; i > 1; i--) this->eq_gain[i] = this->eq_gain[i - 2]; this->eq_gain[1] = this->eq_gain[0] = EQ_REAL (1.0); } else if (this->input.rate < 30000) { for (i = EQ_BANDS - 1; i > 0; i--) this->eq_gain[i] = this->eq_gain[i - 1]; this->eq_gain[0] = EQ_REAL (1.0); } else if (this->input.rate > 60000) { for (i = 0; i < EQ_BANDS - 1; i++) this->eq_gain[i] = this->eq_gain[i + 1]; this->eq_gain[EQ_BANDS - 1] = EQ_REAL (1.0); } this->do_equ = 1; } } static void ao_resend_init (aos_t *this) { do { this->resend.driver_caps = this->driver.d->get_capabilities (this->driver.d); if (!(this->resend.driver_caps & AO_CAP_NO_UNPAUSE)) break; if ((this->output.mode == AO_CAP_MODE_A52) || (this->output.mode == AO_CAP_MODE_AC5)) break; if (!this->resend.buf) this->resend.buf = malloc (RESEND_BUF_SIZE); if (!this->resend.buf) break; if (this->rp.speed == XINE_SPEED_PAUSE) return; if ((this->resend.speed == this->rp.speed) && (this->resend.rate == this->output.rate) && (this->resend.mode == this->output.mode) && (this->resend.bits == this->output.bits)) return; this->resend.speed = this->rp.speed; this->resend.rate = this->output.rate; this->resend.mode = this->output.mode; this->resend.bits = this->output.bits; this->resend.frame_size = (this->output.bits >> 3) * this->out_channels; if (!this->resend.frame_size) break; this->resend.write = 0; this->resend.wrap = 0; this->resend.max = RESEND_BUF_SIZE / this->resend.frame_size; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: using unpause resend buffer for %d frames / %d pts.\n", this->resend.max, (this->resend.max * this->out_pts_per_kframe) >> 10); return; } while (0); this->resend.driver_caps &= ~AO_CAP_NO_UNPAUSE; this->resend.write = 0; this->resend.wrap = 0; } static int ao_update_resample_factor (aos_t *this) { unsigned int eff_input_rate; if( !this->driver.open ) return 0; eff_input_rate = this->input.rate; switch (this->resample_conf) { case 1: /* force off */ this->do_resample = 0; break; case 2: /* force on */ this->do_resample = 1; break; default: /* AUTO */ /* Always set up trick play mode here. If turned off by user, it simply has no effect right now, * but it can be turned on any time later. */ if ((this->rp.speed != XINE_FINE_SPEED_NORMAL) && (this->rp.speed != XINE_SPEED_PAUSE)) eff_input_rate = xine_uint_mul_div (eff_input_rate, this->rp.speed, XINE_FINE_SPEED_NORMAL); this->do_resample = eff_input_rate != this->output.rate; } if (this->do_resample) xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: will resample audio from %u to %d.\n", eff_input_rate, this->output.rate); this->small_gap = this->gap_tolerance; this->frame_rate_factor = ((double)(this->output.rate)) / ((double)(this->input.rate)); if (this->rp.speed != XINE_SPEED_PAUSE) { this->small_gap = this->gap_tolerance * uint_sqrt (this->rp.speed) / uint_sqrt (XINE_FINE_SPEED_NORMAL); this->frame_rate_factor *= (double)XINE_FINE_SPEED_NORMAL / (double)this->rp.speed; } this->fine_gap = this->small_gap >> GAP_RING_LD; /* XINE_FINE_SPEED_NORMAL == 1000000; 1024 * 1000000 / 90000 == 1024 * 100 / 9; */ this->out_frames_per_kpts = this->rp.speed > 0 ? xine_uint_mul_div (this->output.rate, 1024 * 100, this->rp.speed * 9) : (this->output.rate * 1024 + 45000) / 90000; /* XINE_FINE_SPEED_NORMAL == 1000000; 90000 * 1024 / 1000000 == 9 * 256 / 25; */ this->out_pts_per_kframe = xine_uint_mul_div (9 * 256, this->rp.speed, this->output.rate * 25); this->out_channels = _x_ao_mode2channels (this->output.mode); this->in_channels = _x_ao_mode2channels (this->input.mode); ao_resend_init (this); ao_eq_update (this); lprintf ("audio_step %" PRIu32 " pts per 32768 frames\n", this->audio_step); return this->output.rate; } static void ao_driver_lock (aos_t *this) { if (pthread_mutex_trylock (&this->driver.mutex)) { pthread_mutex_lock (&this->driver.intr_mutex); this->driver.intr_num++; pthread_mutex_unlock (&this->driver.intr_mutex); pthread_mutex_lock (&this->driver.mutex); this->driver.dreqs_wait++; pthread_mutex_lock (&this->driver.intr_mutex); this->driver.intr_num--; /* indicate the change to ao_loop() */ pthread_cond_broadcast (&this->driver.intr_wake); pthread_mutex_unlock (&this->driver.intr_mutex); } this->driver.dreqs_all++; } static void ao_new_speed_trick (aos_t *this) { uint32_t speed, trick; speed = this->driver.speed; trick = this->driver.trick; pthread_mutex_unlock (&this->driver.mutex); if (this->rp.trick != trick) { this->rp.trick = trick; if ((this->rp.speed != XINE_SPEED_PAUSE) && (this->rp.speed != XINE_FINE_SPEED_NORMAL)) { this->rp.flags &= ~_AO_FLAG_SILENT_TRICK; this->rp.flags |= this->rp.trick ? 0 : _AO_FLAG_SILENT_TRICK; } } if (this->rp.speed != speed) { this->rp.speed = speed; this->rp.flags &= ~(_AO_FLAG_PAUSE | _AO_FLAG_SILENT_TRICK); if (this->rp.speed == XINE_SPEED_PAUSE) { this->rp.flags |= _AO_FLAG_PAUSE; } else if ((this->rp.speed != XINE_FINE_SPEED_NORMAL) && !this->rp.trick) { this->rp.flags |= _AO_FLAG_SILENT_TRICK; } ao_update_resample_factor (this); } } static inline int ao_driver_lock_2 (aos_t *this) { pthread_mutex_lock (&this->driver.mutex); /* usually true. */ if (!((this->driver.speed ^ this->rp.speed) | (this->driver.trick ^ this->rp.trick))) return 1; ao_new_speed_trick (this); return 0; } static void ao_driver_unlock (aos_t *this) { pthread_mutex_unlock (&this->driver.mutex); } static void ao_flush_driver (aos_t *this) { if (this->rp.speed == XINE_SPEED_PAUSE) return; ao_driver_lock (this); if (this->driver.open) { this->driver.open = 1; if (this->driver.d->delay (this->driver.d) > 0) { this->driver.d->control (this->driver.d, AO_CTRL_FLUSH_BUFFERS, NULL); ao_driver_unlock (this); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: flushed driver.\n"); return; } } ao_driver_unlock (this); } static void ao_driver_test_intr (aos_t *this) { /* Give other threads a chance to use functions which require this->driver.mutex to * be available. This is needed when using NPTL on Linux (and probably PThreads * on Solaris as well). */ if (this->driver.intr_num > 0) { /* calling sched_yield() is not sufficient on multicore systems */ /* sched_yield(); */ /* instead wait for the other thread to acquire this->driver.mutex */ pthread_mutex_lock (&this->driver.intr_mutex); if (this->driver.intr_num > 0) pthread_cond_wait (&this->driver.intr_wake, &this->driver.intr_mutex); pthread_mutex_unlock (&this->driver.intr_mutex); } } static int ao_driver_test_intr_2 (aos_t *this) { int intr; pthread_mutex_lock (&this->driver.intr_mutex); intr = this->driver.intr_num; pthread_mutex_unlock (&this->driver.intr_mutex); return intr; } static int ao_set_property (xine_audio_port_t *this_gen, int property, int value); /******************************************************************** * streams register. * * Reading is way more speed relevant here. * *******************************************************************/ static void ao_streams_open (aos_t *this) { #ifndef HAVE_ZERO_SAFE_MEM this->num_null_streams = 0; this->num_anon_streams = 0; this->num_streams = 0; this->streams_default[0] = NULL; #endif this->streams_size = STREAMS_DEFAULT_SIZE; this->streams = &this->streams_default[0]; xine_rwlock_init_default (&this->streams_lock); } static void ao_streams_close (aos_t *this) { xine_rwlock_destroy (&this->streams_lock); if (this->streams != &this->streams_default[0]) _x_freep (&this->streams); #if 0 /* not yet needed */ this->num_null_streams = 0; this->num_anon_streams = 0; this->num_streams = 0; this->streams_size = 0; #endif } static void ao_streams_register (aos_t *this, xine_stream_private_t *s) { xine_rwlock_wrlock (&this->streams_lock); if (!s) { this->num_null_streams++; } else if (&s->s == XINE_ANON_STREAM) { this->num_anon_streams++; } else do { xine_stream_private_t **a = this->streams; if (this->num_streams + 2 > this->streams_size) { xine_stream_private_t **n = malloc ((this->streams_size + 32) * sizeof (void *)); if (!n) break; memcpy (n, a, this->streams_size * sizeof (void *)); this->streams = n; if (a != &this->streams_default[0]) free (a); a = n; this->streams_size += 32; } a[this->num_streams++] = s; a[this->num_streams] = NULL; } while (0); xine_rwlock_unlock (&this->streams_lock); } static int ao_streams_unregister (aos_t *this, xine_stream_private_t *s) { int n; xine_rwlock_wrlock (&this->streams_lock); if (!s) { this->num_null_streams--; } else if (&s->s == XINE_ANON_STREAM) { this->num_anon_streams--; } else { xine_stream_private_t **a = this->streams; while (*a && (*a != s)) a++; if (*a) { do { a[0] = a[1]; a++; } while (*a); this->num_streams--; } } n = this->num_null_streams + this->num_anon_streams + this->num_streams; xine_rwlock_unlock (&this->streams_lock); return n; } /******************************************************************** * reuse buffer stream refs. * * be the current owner of buf when calling this. * *******************************************************************/ static void ao_unref_obsolete (aos_t *this) { audio_buffer_t *buf; xine_stream_private_t *d[128], **a = d; xine_rwlock_rdlock (&this->streams_lock); /* same order as elsewhere (eg ao_out_fifo_get ()) !! */ pthread_mutex_lock (&this->out_fifo.mutex); pthread_mutex_lock (&this->free_fifo.mutex); for (buf = this->free_fifo.first; buf; buf = buf->next) { /* Paranoia? */ if (PTR_IN_RANGE (buf, this->base_buf, NUM_AUDIO_BUFFERS * sizeof (*buf))) { int i = buf - this->base_buf; xine_stream_private_t *buf_stream = this->out_fifo.buf_streams[i], **open_stream; if (!buf_stream) continue; for (open_stream = this->streams; *open_stream; open_stream++) { if (buf_stream == *open_stream) break; } if (*open_stream) continue; *a++ = this->out_fifo.buf_streams[i]; this->out_fifo.buf_streams[i] = NULL; if (a > d + sizeof (d) / sizeof (d[0]) - 2) break; } } *a = NULL; pthread_mutex_unlock (&this->free_fifo.mutex); pthread_mutex_unlock (&this->out_fifo.mutex); xine_rwlock_unlock (&this->streams_lock); if (a > d) { for (a = d; *a; a++) xine_refs_sub (&(*a)->refs, 1); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: freed %d obsolete stream refs.\n", (int)(a - d)); } } static void ao_force_unref_all (aos_t *this, int lock) { xine_stream_private_t *d[NUM_AUDIO_BUFFERS + 1], **a = d; int i; if (lock) pthread_mutex_lock (&this->out_fifo.mutex); for (i = 0; i < NUM_AUDIO_BUFFERS; i++) { if (this->out_fifo.buf_streams[i]) { *a++ = this->out_fifo.buf_streams[i]; this->out_fifo.buf_streams[i] = NULL; } } if (lock) pthread_mutex_unlock (&this->out_fifo.mutex); *a = NULL; if (a > d) { for (a = d; *a; a++) xine_refs_sub (&(*a)->refs, 1); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: freed %d obsolete stream refs.\n", (int)(a - d)); } } /******************************************************************** * frame queue (fifo) * *******************************************************************/ static void ao_free_fifo_open (aos_t *this) { #ifndef HAVE_ZERO_SAFE_MEM this->free_fifo.first = NULL; this->free_fifo.num_buffers = 0; this->free_fifo.num_buffers_max = 0; this->free_fifo.num_waiters = 0; #endif this->free_fifo.add = &this->free_fifo.first; pthread_mutex_init (&this->free_fifo.mutex, NULL); pthread_cond_init (&this->free_fifo.not_empty, NULL); } static void ao_out_fifo_open (aos_t *this) { #ifndef HAVE_ZERO_SAFE_MEM int i; for (i = 0; i < NUM_AUDIO_BUFFERS; i++) this->out_fifo.buf_streams[i] = NULL; this->out_fifo.first = NULL; this->out_fifo.num_buffers = 0; this->out_fifo.num_waiters = 0; this->out_fifo.pts_last_buf = 0; this->out_fifo.pts_fill = 0; this->out_fifo.pts_in_driver = 0; this->out_fifo.wake_time.tv_sec = 0; this->out_fifo.wake_time.tv_nsec = 0; this->out_fifo.use_wake_time = 0; this->out_fifo.wake_now = 0; this->out_fifo.discard_buffers = 0; #endif this->out_fifo.add = &this->out_fifo.first; this->out_fifo.seek_count1 = -1; pthread_mutex_init (&this->out_fifo.mutex, NULL); pthread_cond_init (&this->out_fifo.not_empty, NULL); pthread_cond_init (&this->out_fifo.empty, NULL); } static void ao_free_fifo_close (aos_t *this) { #if 0 /* not yet needed */ this->free_fifo.first = NULL; this->free_fifo.add = &this->free_fifo.first; this->free_fifo.num_buffers = 0; this->free_fifo.num_buffers_max = 0; this->free_fifo.num_waiters = 0; #endif pthread_mutex_destroy (&this->free_fifo.mutex); pthread_cond_destroy (&this->free_fifo.not_empty); } static void ao_out_fifo_close (aos_t *this) { #if 0 /* not yet needed */ int i; for (i = 0; i < NUM_AUDIO_BUFFERS; i++) this->out_fifo.buf_streams[i] = NULL; this->out_fifo.first = NULL; this->out_fifo.add = &this->out_fifo.first; this->out_fifo.num_buffers = 0; this->out_fifo.num_waiters = 0; this->out_fifo.pts_last_buf = 0; this->out_fifo.pts_fill = 0; this->out_fifo.pts_in_driver = 0; this->out_fifo.wake_time.rv_sec = 0; this->out_fifo.wake_time.tv_nsec = 0; this->out_fifo.use_wake_time = 0; this->out_fifo.wake_now = 0; this->out_fifo.seek_count1 = -1; #endif pthread_mutex_destroy (&this->out_fifo.mutex); pthread_cond_destroy (&this->out_fifo.not_empty); pthread_cond_destroy (&this->out_fifo.empty); } static void ao_out_fifo_apply_vpts_step (aos_t *this, int step) { audio_buffer_t *b; pthread_mutex_lock (&this->out_fifo.mutex); for (b = this->out_fifo.first; b; b = b->next) b->vpts += step; pthread_mutex_unlock (&this->out_fifo.mutex); } static void ao_out_fifo_reref_append (aos_t *this, audio_buffer_t *buf, int is_first) { xine_stream_private_t **s, *olds, *news; _x_assert (!buf->next); buf->next = NULL; /* Paranoia? */ s = PTR_IN_RANGE (buf, this->base_buf, NUM_AUDIO_BUFFERS * sizeof (*buf)) ? this->out_fifo.buf_streams + (buf - this->base_buf) : &news; news = (xine_stream_private_t *)buf->stream; pthread_mutex_lock (&this->out_fifo.mutex); olds = *s; if (olds != news) { *s = news; if (news) xine_refs_add (&news->refs, 1); /* this is fast. */ this->out_fifo.num_buffers = (this->out_fifo.first ? this->out_fifo.num_buffers : 0) + 1; *(this->out_fifo.add) = buf; this->out_fifo.add = &buf->next; if (buf->format.rate) this->out_fifo.pts_fill += (uint32_t)90000 * (uint32_t)buf->num_frames / buf->format.rate; if (this->out_fifo.num_waiters && (this->out_fifo.first == buf)) pthread_cond_signal (&this->out_fifo.not_empty); if (is_first) this->out_fifo.seek_count1 = buf->extra_info->seek_count; pthread_mutex_unlock (&this->out_fifo.mutex); if (olds) xine_refs_sub (&olds->refs, 1); /* this may involve stream dispose. */ } else { this->out_fifo.num_buffers = (this->out_fifo.first ? this->out_fifo.num_buffers : 0) + 1; *(this->out_fifo.add) = buf; this->out_fifo.add = &buf->next; if (buf->format.rate) this->out_fifo.pts_fill += (uint32_t)90000 * (uint32_t)buf->num_frames / buf->format.rate; if (this->out_fifo.num_waiters && (this->out_fifo.first == buf)) pthread_cond_signal (&this->out_fifo.not_empty); if (is_first) this->out_fifo.seek_count1 = buf->extra_info->seek_count; pthread_mutex_unlock (&this->out_fifo.mutex); } } static void ao_free_fifo_append (aos_t *this, audio_buffer_t *buf) { _x_assert (!buf->next); buf->next = NULL; pthread_mutex_lock (&this->free_fifo.mutex); this->free_fifo.num_buffers = (this->free_fifo.first ? this->free_fifo.num_buffers : 0) + 1; *(this->free_fifo.add) = buf; this->free_fifo.add = &buf->next; if (this->free_fifo.num_waiters) pthread_cond_signal (&this->free_fifo.not_empty); pthread_mutex_unlock (&this->free_fifo.mutex); } static audio_buffer_t *ao_out_fifo_pop_int (aos_t *this) { audio_buffer_t *buf; buf = this->out_fifo.first; this->out_fifo.first = buf->next; buf->next = NULL; this->out_fifo.num_buffers--; if (!this->out_fifo.first) { this->out_fifo.add = &this->out_fifo.first; this->out_fifo.num_buffers = 0; } return buf; } static void ao_out_fifo_signal (aos_t *this) { pthread_mutex_lock (&this->out_fifo.mutex); this->out_fifo.wake_now = 1; if (this->out_fifo.num_waiters) pthread_cond_signal (&this->out_fifo.not_empty); pthread_mutex_unlock (&this->out_fifo.mutex); } static audio_buffer_t *ao_out_fifo_get (aos_t *this, audio_buffer_t *buf) { int dry = 0; pthread_mutex_lock (&this->out_fifo.mutex); /* this is 1 buf late, make it consistent at least. */ this->out_fifo.pts_in_driver = this->pts_in_driver + this->out_fifo.pts_last_buf; while (1) { if (this->out_fifo.seek_count1 >= 0) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: seek_count %d step 2.\n", this->out_fifo.seek_count1); this->rp.seek_count2 = this->rp.seek_count3 = this->out_fifo.seek_count1; this->out_fifo.seek_count1 = -1; } if (this->out_fifo.discard_buffers) { audio_buffer_t *list, **add; int n; this->rp.last_flush_vpts = this->clock->get_current_time (this->clock); this->rp.ei_read = this->rp.ei_write = 0; list = NULL; add = &list; n = 0; if (buf) { *add = buf; add = &buf->next; n++; } if (this->out_fifo.first) { n += this->out_fifo.num_buffers; *add = this->out_fifo.first; add = this->out_fifo.add; this->out_fifo.first = NULL; this->out_fifo.add = &this->out_fifo.first; this->out_fifo.num_buffers = 0; this->out_fifo.pts_fill = 0; } if (n) { if ((this->rp.seek_count3 >= 0) && list->stream) { xine_stream_private_t *s = (xine_stream_private_t *)list->stream; s = s->side_streams[0]; pthread_mutex_lock (&s->first_frame.lock); s->first_frame.flag = 0; pthread_cond_broadcast (&s->first_frame.reached); pthread_mutex_unlock (&s->first_frame.lock); } pthread_mutex_lock (&this->free_fifo.mutex); this->free_fifo.num_buffers = n + (this->free_fifo.first ? this->free_fifo.num_buffers : 0); *(this->free_fifo.add) = list; this->free_fifo.add = add; if (this->free_fifo.num_waiters) pthread_cond_broadcast (&this->free_fifo.not_empty); pthread_mutex_unlock (&this->free_fifo.mutex); } pthread_cond_broadcast (&this->out_fifo.empty); buf = NULL; this->resend.write = 0; this->resend.wrap = 0; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: flushed out %d buffers.\n", n); } if (!buf) { this->out_fifo.pts_last_buf = 0; buf = this->out_fifo.first; if (buf) { this->out_fifo.first = buf->next; buf->next = NULL; if (this->out_fifo.first) { this->out_fifo.num_buffers--; dry = 0; } else { this->out_fifo.add = &this->out_fifo.first; this->out_fifo.num_buffers = 0; dry = 1; } if (buf->format.rate) { this->out_fifo.pts_last_buf = (uint32_t)90000 * (uint32_t)buf->num_frames / buf->format.rate; this->out_fifo.pts_fill -= this->out_fifo.pts_last_buf; } } } if (buf) { if (!this->out_fifo.use_wake_time) break; } if (this->out_fifo.wake_now || !this->audio_loop_running) break; /* no more bufs for now... */ if (!this->out_fifo.use_wake_time) { pthread_mutex_lock (&this->driver.mutex); if ((this->driver.open > 1) && (this->driver.speed > 0)) { int s = this->driver.speed; int n = this->driver.d->delay (this->driver.d); /* ...wait for driver idle or new buf, speed change, ... */ pthread_mutex_unlock (&this->driver.mutex); n = (n > 0) && this->output.rate ? (uint32_t)n * 1000u / this->output.rate : 0; this->out_fifo.pts_in_driver = n * 90u; n = xine_uint_mul_div (n, XINE_FINE_SPEED_NORMAL, s); if (n > 0) { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_nsec += (n % 1000) * 1000000; ts.tv_sec += n / 1000; if (ts.tv_nsec >= 1000000000) { ts.tv_sec++; ts.tv_nsec -= 1000000000; } this->out_fifo.num_waiters++; n = pthread_cond_timedwait (&this->out_fifo.not_empty, &this->out_fifo.mutex, &ts); this->out_fifo.num_waiters--; } else { n = ETIMEDOUT; } /* timeout? */ if (n == ETIMEDOUT) { xine_rwlock_rdlock (&this->streams_lock); n = this->num_null_streams + this->num_anon_streams + this->num_streams; xine_rwlock_unlock (&this->streams_lock); this->out_fifo.pts_last_buf = 0; this->out_fifo.pts_in_driver = this->pts_in_driver = 0; if (!n) { /* no users -> close driver. */ xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: driver idle, closing.\n"); pthread_mutex_lock (&this->driver.mutex); this->driver.d->close (this->driver.d); this->driver.open = 0; pthread_mutex_unlock (&this->driver.mutex); /* unref streams as well. */ ao_force_unref_all (this, 0); } else { /* stream still there, eg DVB signal loss. */ xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: driver idle.\n"); /* avoid infinite loop */ pthread_mutex_lock (&this->driver.mutex); this->driver.open = 1; pthread_mutex_unlock (&this->driver.mutex); } } continue; } else { pthread_mutex_unlock (&this->driver.mutex); } } this->out_fifo.num_waiters++; if (this->out_fifo.use_wake_time == 1) { pthread_cond_timedwait (&this->out_fifo.not_empty, &this->out_fifo.mutex, &this->out_fifo.wake_time); } else { pthread_cond_wait (&this->out_fifo.not_empty, &this->out_fifo.mutex); } this->out_fifo.use_wake_time = 0; this->out_fifo.num_waiters--; } this->out_fifo.wake_now = 0; pthread_mutex_unlock (&this->out_fifo.mutex); if (dry && buf) xine_nbc_event ((xine_stream_private_t *)buf->stream, XINE_NBC_EVENT_AUDIO_DRY); return buf; } static void ao_ticket_revoked (void *user_data, int flags) { aos_t *this = (aos_t *)user_data; const char *s1 = (flags & XINE_TICKET_FLAG_ATOMIC) ? " atomic" : ""; const char *s2 = (flags & XINE_TICKET_FLAG_REWIRE) ? " port_rewire" : ""; pthread_cond_signal (&this->free_fifo.not_empty); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: port ticket revoked%s%s.\n", s1, s2); } static audio_buffer_t *ao_free_fifo_get (aos_t *this) { audio_buffer_t *buf; pthread_mutex_lock (&this->free_fifo.mutex); while (!(buf = this->free_fifo.first)) { if (this->xine->port_ticket->ticket_revoked) { pthread_mutex_unlock (&this->free_fifo.mutex); this->xine->port_ticket->renew (this->xine->port_ticket, 1); if (!(this->xine->port_ticket->ticket_revoked & XINE_TICKET_FLAG_REWIRE)) { pthread_mutex_lock (&this->free_fifo.mutex); continue; } /* O dear. Port rewiring ahead. Try unblock. */ if (this->clock->speed == XINE_SPEED_PAUSE) { pthread_mutex_lock (&this->out_fifo.mutex); if (this->out_fifo.first) { buf = ao_out_fifo_pop_int (this); pthread_mutex_unlock (&this->out_fifo.mutex); xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: try unblocking decoder.\n"); return buf; } pthread_mutex_unlock (&this->out_fifo.mutex); } pthread_mutex_lock (&this->free_fifo.mutex); } { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_sec += 1; this->free_fifo.num_waiters++; pthread_cond_timedwait (&this->free_fifo.not_empty, &this->free_fifo.mutex, &ts); this->free_fifo.num_waiters--; } } this->free_fifo.first = buf->next; buf->next = NULL; this->free_fifo.num_buffers--; if (!this->free_fifo.first) { this->free_fifo.add = &this->free_fifo.first; this->free_fifo.num_buffers = 0; } pthread_mutex_unlock (&this->free_fifo.mutex); return buf; } /* This function is currently not needed */ #if 0 static int ao_fifo_num_buffers (audio_fifo_t *fifo) { int ret; pthread_mutex_lock (&fifo->mutex); ret = fifo->num_buffers; pthread_mutex_unlock (&fifo->mutex); return ret; } #endif /* have this->out_fifo.mutex locked */ static void ao_out_fifo_manual_flush (aos_t *this) { if (this->out_fifo.first) { audio_buffer_t *list = NULL, **add = &list; int n = this->out_fifo.num_buffers; *add = this->out_fifo.first; add = this->out_fifo.add; this->out_fifo.first = NULL; this->out_fifo.add = &this->out_fifo.first; this->out_fifo.num_buffers = 0; this->out_fifo.pts_last_buf = 0; this->out_fifo.pts_fill = 0; pthread_mutex_lock (&this->free_fifo.mutex); this->free_fifo.num_buffers = n + (this->free_fifo.first ? this->free_fifo.num_buffers : 0); *(this->free_fifo.add) = list; this->free_fifo.add = add; pthread_mutex_unlock (&this->free_fifo.mutex); } if (this->free_fifo.first && this->free_fifo.num_waiters) pthread_cond_broadcast (&this->free_fifo.not_empty); } static void ao_out_fifo_loop_flush (aos_t *this) { int n; pthread_mutex_lock (&this->out_fifo.mutex); this->out_fifo.discard_buffers++; while (this->out_fifo.first) { /* i think it's strange to send not_empty signal here (beside the enqueue * function), but it should do no harm. [MF] * TJ. and its needed now that ao loop no longer polls. */ if (this->out_fifo.num_waiters) pthread_cond_signal (&this->out_fifo.not_empty); pthread_cond_wait (&this->out_fifo.empty, &this->out_fifo.mutex); } this->out_fifo.discard_buffers--; n = this->out_fifo.discard_buffers; pthread_mutex_unlock (&this->out_fifo.mutex); if (n == 0) ao_flush_driver (this); } static void ao_resend_store (aos_t *this, audio_buffer_t *buf) { uint8_t *q = this->resend.buf + this->resend.write * this->resend.frame_size; int n1 = buf->num_frames; int n2 = this->resend.write + n1; if (n2 > this->resend.max) { n2 -= this->resend.max; n1 -= n2; this->resend.write = n2; this->resend.wrap = 1; n1 *= this->resend.frame_size; xine_fast_memcpy (q, buf->mem, n1); xine_fast_memcpy (this->resend.buf, buf->mem + n1, n2 * this->resend.frame_size); } else if (n2 == this->resend.max) { this->resend.wrap = 1; this->resend.write = 0; n1 *= this->resend.frame_size; xine_fast_memcpy (q, buf->mem, n1); } else { this->resend.write = n2; n1 *= this->resend.frame_size; xine_fast_memcpy (q, buf->mem, n1); } this->resend.vpts = (((uint32_t)buf->num_frames * this->out_pts_per_kframe) >> 10) + buf->vpts; } static int ao_fill_gap (aos_t *this, int64_t pts_len) { static const uint16_t a52_pause_head[4] = { 0xf872, 0x4e1f, /* Audio ES Channel empty, wait for DD Decoder or pause */ 0x0003, 0x0020 }; int64_t num_frames = (pts_len * this->out_frames_per_kpts) >> 10; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: inserting %" PRId64 " 0-frames to fill a gap of %" PRId64 " pts\n", num_frames, pts_len); if ((this->output.mode == AO_CAP_MODE_A52) || (this->output.mode == AO_CAP_MODE_AC5)) { memcpy (this->zero_space, a52_pause_head, sizeof (a52_pause_head)); while (num_frames > 1536) { if (ao_driver_test_intr_2 (this)) return 1; if (this->driver.open) { this->driver.d->write (this->driver.d, this->zero_space, 1536); this->driver.open = 2; } num_frames -= 1536; } } else { int max_frames = this->out_channels * (this->output.bits >> 3); max_frames = max_frames ? AUDIO_BUF_SIZE / max_frames : 4096; memset (this->zero_space, 0, sizeof (a52_pause_head)); while ((num_frames >= max_frames) && !this->out_fifo.discard_buffers) { if (ao_driver_test_intr_2 (this)) return 1; if (this->driver.open) { this->driver.d->write (this->driver.d, this->zero_space, max_frames); this->driver.open = 2; } num_frames -= max_frames; } if (num_frames && !this->out_fifo.discard_buffers) { if (ao_driver_test_intr_2 (this)) return 1; if (this->driver.open) { this->driver.d->write (this->driver.d, this->zero_space, num_frames); this->driver.open = 2; } } } return 0; } static int ao_resend_fill (aos_t *this, int64_t pts_len, int64_t end_time) { int resend_have = this->resend.wrap ? this->resend.max : this->resend.write; int64_t resend_start = this->resend.vpts - ((resend_have * this->out_pts_per_kframe) >> 10); int64_t fill_start = end_time - pts_len; int64_t fill_len; fill_len = resend_start - fill_start; if (fill_len > 0) { pts_len -= fill_len; if (pts_len < 0) { fill_len += pts_len; pts_len = 0; } if (ao_fill_gap (this, fill_len)) return 1; fill_start += fill_len; } if (pts_len == 0) return 0; fill_len = this->resend.vpts - fill_start; if (fill_len > 0) { int start_frame, fill_frames1, fill_frames2; start_frame = (fill_len * this->out_frames_per_kpts) >> 10; pts_len -= fill_len; if (pts_len < 0) { fill_len += pts_len; pts_len = 0; } fill_frames1 = (fill_len * this->out_frames_per_kpts) >> 10; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: resending %d frames / %" PRId64 " pts.\n", fill_frames1, fill_len); start_frame = this->resend.write - start_frame; if (start_frame < 0) start_frame += this->resend.max; fill_frames2 = this->resend.max - start_frame; if (fill_frames2 < fill_frames1) { fill_frames1 -= fill_frames2; if (!this->out_fifo.discard_buffers) { if (ao_driver_test_intr_2 (this)) return 1; if (this->driver.open) { this->driver.d->write (this->driver.d, (int16_t *)(this->resend.buf + start_frame * this->resend.frame_size), fill_frames2); this->driver.open = 2; } } if (!this->out_fifo.discard_buffers) { if (ao_driver_test_intr_2 (this)) return 1; if (this->driver.open) { this->driver.d->write (this->driver.d, (int16_t *)this->resend.buf, fill_frames1); this->driver.open = 2; } } } else { if (!this->out_fifo.discard_buffers) { if (ao_driver_test_intr_2 (this)) return 1; if (this->driver.open) { this->driver.d->write (this->driver.d, (int16_t *)(this->resend.buf + start_frame * this->resend.frame_size), fill_frames1); this->driver.open = 2; } } } } if (pts_len > 0) return ao_fill_gap (this, pts_len); return 0; } static void ensure_buffer_size (audio_buffer_t *buf, int bytes_per_frame, int frames) { int size = bytes_per_frame * frames; if (buf->mem_size < size) { buf->mem = realloc( buf->mem, size ); buf->mem_size = size; } buf->num_frames = frames; } static audio_buffer_t * swap_frame_buffers ( aos_t *this ) { audio_buffer_t *tmp; tmp = this->frame_buf[1]; this->frame_buf[1] = this->frame_buf[0]; this->frame_buf[0] = tmp; return this->frame_buf[0]; } int _x_ao_mode2channels( int mode ) { switch( mode ) { case AO_CAP_MODE_MONO: return 1; case AO_CAP_MODE_STEREO: return 2; case AO_CAP_MODE_4CHANNEL: return 4; case AO_CAP_MODE_4_1CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: return 6; } return 0; } int _x_ao_channels2mode (int channels) { static const int modes[9] = { AO_CAP_NOCAP, AO_CAP_MODE_MONO, AO_CAP_MODE_STEREO, AO_CAP_MODE_4CHANNEL, AO_CAP_MODE_4CHANNEL, AO_CAP_MODE_5CHANNEL, AO_CAP_MODE_5_1CHANNEL, AO_CAP_NOCAP, AO_CAP_NOCAP }; return modes[(channels >= 0) && (channels < 9) ? channels : 0]; } static void audio_filter_compress (aos_t *this, int16_t *mem, int num_frames) { int i, maxs; double f_max; int num_channels; num_channels = this->in_channels; if (!num_channels) return; maxs = 0; /* measure */ for (i=0; i<num_frames*num_channels; i++) { int16_t sample = abs(mem[i]); if (sample>maxs) maxs = sample; } /* calc maximum possible & allowed factor */ if (maxs>0) { f_max = 32767.0 / maxs; this->compression_factor = this->compression_factor * 0.999 + f_max * 0.001; if (this->compression_factor > f_max) this->compression_factor = f_max; if (this->compression_factor > this->compression_factor_max) this->compression_factor = this->compression_factor_max; } else f_max = 1.0; lprintf ("max=%d f_max=%f compression_factor=%f\n", maxs, f_max, this->compression_factor); /* apply it */ for (i=0; i<num_frames*num_channels; i++) { /* 0.98 to avoid overflow */ mem[i] = mem[i] * 0.98 * this->compression_factor * this->amp_factor; } } static void audio_filter_amp (aos_t *this, void *buf, int num_frames) { double amp_factor; int i; const int total_frames = num_frames * this->in_channels; if (!total_frames) return; amp_factor=this->amp_factor; if (this->amp_mute || amp_factor == 0) { memset (buf, 0, total_frames * (this->input.bits / 8)); return; } if (this->input.bits == 8) { int16_t test; int8_t *mem = (int8_t *) buf; for (i=0; i<total_frames; i++) { test = mem[i] * amp_factor; /* Force limit on amp_factor to prevent clipping */ if (test < INT8_MIN) { this->amp_factor = amp_factor = amp_factor * INT8_MIN / test; test=INT8_MIN; } if (test > INT8_MAX) { this->amp_factor = amp_factor = amp_factor * INT8_MIN / test; test=INT8_MAX; } mem[i] = test; } } else if (this->input.bits == 16) { int32_t test; int16_t *mem = (int16_t *) buf; for (i=0; i<total_frames; i++) { test = mem[i] * amp_factor; /* Force limit on amp_factor to prevent clipping */ if (test < INT16_MIN) { this->amp_factor = amp_factor = amp_factor * INT16_MIN / test; test=INT16_MIN; } if (test > INT16_MAX) { this->amp_factor = amp_factor = amp_factor * INT16_MIN / test; test=INT16_MAX; } mem[i] = test; } } } #define sat16(v) (((v + 0x8000) & ~0xffff) ? ((v) >> 31) ^ 0x7fff : (v)) static void audio_filter_equalize (aos_t *this, int16_t *data, int num_frames) { int index, band, channel; int length; int num_channels; num_channels = this->in_channels; if (!num_channels) return; length = num_frames * num_channels; for (index = 0; index < length; index += num_channels) { for (channel = 0; channel < num_channels; channel++) { /* Convert the PCM sample to a fixed fraction */ int scaledpcm = ((int)data[index + channel]) << (FP_FRBITS - 16); int out = 0; /* For each band */ for (band = 0; band < EQ_BANDS; band++) { int64_t l; int v; int *p = &this->eq_data_history[channel][band][0]; l = (int64_t)iir_cf[band].alpha * (scaledpcm - p[1]) + (int64_t)iir_cf[band].gamma * p[2] - (int64_t)iir_cf[band].beta * p[3]; p[1] = p[0]; p[0] = scaledpcm; p[3] = p[2]; p[2] = v = (int)(l >> FP_FRBITS); l = (int64_t)v * this->eq_gain[band]; out += (int)(l >> FP_FRBITS); } /* Adjust the fixed point fraction value to a PCM sample */ /* Scale back to a 16bit signed int */ out >>= (FP_FRBITS - 16); /* Limit the output */ data[index+channel] = sat16 (out); } } } static audio_buffer_t* prepare_samples( aos_t *this, audio_buffer_t *buf) { double acc_output_frames; int num_output_frames ; /* * volume / compressor / equalizer filter */ if (this->amp_factor == 0) { if (this->do_amp) audio_filter_amp (this, buf->mem, buf->num_frames); } else if (this->input.bits == 16) { if (this->do_equ) audio_filter_equalize (this, buf->mem, buf->num_frames); if (this->do_compress) audio_filter_compress (this, buf->mem, buf->num_frames); if (this->do_amp) audio_filter_amp (this, buf->mem, buf->num_frames); } else if (this->input.bits == 8) { if (this->do_amp) audio_filter_amp (this, buf->mem, buf->num_frames); } /* * resample and output audio data */ /* calculate number of output frames (after resampling) */ acc_output_frames = (double) buf->num_frames * this->frame_rate_factor * this->resample_sync_factor + this->output_frame_excess; /* Truncate to an integer */ num_output_frames = acc_output_frames; /* Keep track of the amount truncated */ this->output_frame_excess = acc_output_frames - (double) num_output_frames; if ( this->output_frame_excess != 0 && !this->do_resample && !this->resample_sync_method) this->output_frame_excess = 0; lprintf ("outputting %d frames\n", num_output_frames); /* convert 8 bit samples as needed */ if ( this->input.bits == 8 && (this->resample_sync_method || this->do_resample || this->output.bits != 8 || this->input.mode != this->output.mode) ) { int channels = this->in_channels; ensure_buffer_size(this->frame_buf[1], 2*channels, buf->num_frames ); _x_audio_out_resample_8to16((int8_t *)buf->mem, this->frame_buf[1]->mem, channels * buf->num_frames ); buf = swap_frame_buffers(this); } /* check if resampling may be skipped */ if ( (this->resample_sync_method || this->do_resample) && buf->num_frames != num_output_frames ) { switch (this->input.mode) { case AO_CAP_MODE_MONO: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3), num_output_frames); _x_audio_out_resample_mono (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_STEREO: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*2, num_output_frames); _x_audio_out_resample_stereo (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_4CHANNEL: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*4, num_output_frames); _x_audio_out_resample_4channel (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_4_1CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*6, num_output_frames); _x_audio_out_resample_6channel (this->last_sample, buf->mem, buf->num_frames, this->frame_buf[1]->mem, num_output_frames); buf = swap_frame_buffers(this); break; case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: /* pass-through modes: no resampling */ break; } } else { /* maintain last_sample in case we need it */ switch (this->input.mode) { case AO_CAP_MODE_MONO: memcpy (this->last_sample, &buf->mem[buf->num_frames - 1], sizeof (this->last_sample[0])); break; case AO_CAP_MODE_STEREO: memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 2], 2 * sizeof (this->last_sample[0])); break; case AO_CAP_MODE_4CHANNEL: memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 4], 4 * sizeof (this->last_sample[0])); break; case AO_CAP_MODE_4_1CHANNEL: case AO_CAP_MODE_5CHANNEL: case AO_CAP_MODE_5_1CHANNEL: memcpy (this->last_sample, &buf->mem[(buf->num_frames - 1) * 6], 6 * sizeof (this->last_sample[0])); break; default:; } } /* mode conversion */ if ( this->input.mode != this->output.mode ) { switch (this->input.mode) { case AO_CAP_MODE_MONO: if( this->output.mode == AO_CAP_MODE_STEREO ) { ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3)*2, buf->num_frames ); _x_audio_out_resample_monotostereo(buf->mem, this->frame_buf[1]->mem, buf->num_frames ); buf = swap_frame_buffers(this); } break; case AO_CAP_MODE_STEREO: if( this->output.mode == AO_CAP_MODE_MONO ) { ensure_buffer_size(this->frame_buf[1], (this->output.bits>>3), buf->num_frames ); _x_audio_out_resample_stereotomono(buf->mem, this->frame_buf[1]->mem, buf->num_frames ); buf = swap_frame_buffers(this); } break; case AO_CAP_MODE_4CHANNEL: break; case AO_CAP_MODE_5CHANNEL: break; case AO_CAP_MODE_5_1CHANNEL: break; case AO_CAP_MODE_A52: case AO_CAP_MODE_AC5: break; } } /* convert back to 8 bits after resampling */ if( this->output.bits == 8 && (this->resample_sync_method || this->do_resample || this->input.mode != this->output.mode) ) { int channels = this->out_channels; ensure_buffer_size(this->frame_buf[1], channels, buf->num_frames ); _x_audio_out_resample_16to8(buf->mem, (int8_t *)this->frame_buf[1]->mem, channels * buf->num_frames ); buf = swap_frame_buffers(this); } return buf; } static int resample_rate_adjust(aos_t *this, int64_t gap, audio_buffer_t *buf) { /* Calculates the drift factor used to resample the audio data to * keep in sync with system (or dxr3) clock. * * To compensate the sound card drift it is necessary to know, how many audio * frames need to be added (or removed) via resampling. This function waits for * RESAMPLE_SYNC_WINDOW audio buffers to be sent to the card and keeps track * of their total duration in vpts. With the measured gap difference between * the reported gap values at the beginning and at the end of this window the * required resampling factor is calculated: * * resample_factor = (duration + gap_difference) / duration * * This factor is then used in prepare_samples() to resample the audio * buffers as needed so we keep in sync with the system (or dxr3) clock. */ resample_sync_t *info = &this->resample_sync_info; int64_t avg_gap = 0; double factor; double diff; double duration; int i; if (llabs(gap) > AO_MAX_GAP) { /* drop buffers or insert 0-frames in audio out loop */ info->valid = 0; return -1; } if ( ! info->valid) { this->resample_sync_factor = 1.0; info->window = 0; info->reduce_gap = 0; info->last_avg_gap = gap; info->last_factor = 0; info->window_duration = info->last_vpts = 0; info->valid = 1; } /* calc average gap (to compensate small errors during measurement) */ for (i = 0; i < 7; i++) info->recent_gap[i] = info->recent_gap[i + 1]; info->recent_gap[i] = gap; for (i = 0; i < 8; i++) avg_gap += info->recent_gap[i]; avg_gap /= 8; /* gap too big? Change sample rate so that gap converges towards 0. */ if (llabs(avg_gap) > RESAMPLE_REDUCE_GAP_THRESHOLD && !info->reduce_gap) { info->reduce_gap = 1; this->resample_sync_factor = (avg_gap < 0) ? 0.995 : 1.005; llprintf (LOG_RESAMPLE_SYNC, "sample rate adjusted to reduce gap: gap=%" PRId64 "\n", avg_gap); return 0; } else if (info->reduce_gap && llabs(avg_gap) < 50) { info->reduce_gap = 0; info->valid = 0; llprintf (LOG_RESAMPLE_SYNC, "gap successfully reduced\n"); return 0; } else if (info->reduce_gap) { /* re-check, because the gap might suddenly change its sign, * also slow down, when getting close to zero (-300<gap<300) */ if (llabs(avg_gap) > 300) this->resample_sync_factor = (avg_gap < 0) ? 0.995 : 1.005; else this->resample_sync_factor = (avg_gap < 0) ? 0.998 : 1.002; return 0; } if (info->window > RESAMPLE_SYNC_WINDOW) { /* adjust drift correction */ int64_t gap_diff = avg_gap - info->last_avg_gap; if (gap_diff < RESAMPLE_MAX_GAP_DIFF) { #if LOG_RESAMPLE_SYNC int num_frames; /* if we are already resampling to a different output rate, consider * this during calculation */ num_frames = (this->do_resample) ? (buf->num_frames * this->frame_rate_factor) : buf->num_frames; printf("audio_out: gap=%5" PRId64 "; gap_diff=%5" PRId64 "; frame_diff=%3.0f; drift_factor=%f\n", avg_gap, gap_diff, num_frames * info->window * info->last_factor, this->resample_sync_factor); #endif /* we want to add factor * num_frames to each buffer */ diff = gap_diff; #if _MSCVER <= 1200 /* ugly hack needed by old Visual C++ 6.0 */ duration = (int64_t)info->window_duration; #else duration = info->window_duration; #endif factor = diff / duration + info->last_factor; info->last_factor = factor; this->resample_sync_factor = 1.0 + factor; info->last_avg_gap = avg_gap; info->window_duration = 0; info->window = 0; } else info->valid = 0; } else { /* collect data for next adjustment */ if (info->window > 0) info->window_duration += buf->vpts - info->last_vpts; info->last_vpts = buf->vpts; info->window++; } return 0; } static int ao_change_settings(aos_t *this, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode); /* Audio output loop: - * 1) Check for pause. * 2) Make sure audio hardware is in RUNNING state. * 3) Get delay * 4) Do drop, 0-fill or output samples. * 5) Go round loop again. */ static void *ao_loop (void *this_gen) { aos_t *this = (aos_t *) this_gen; audio_buffer_t *in_buf = NULL; int64_t cur_time = -1; int64_t next_sync_time = SYNC_TIME_INTERVAL; int bufs_since_sync = 0; pthread_mutex_lock (&this->driver.mutex); this->rp.speed = this->driver.speed; this->rp.trick = this->driver.trick; pthread_mutex_unlock (&this->driver.mutex); if (this->rp.speed == XINE_SPEED_PAUSE) { this->rp.flags = _AO_FLAG_PAUSE; } else if ((this->rp.speed != XINE_FINE_SPEED_NORMAL) && !this->rp.trick) { this->rp.flags = _AO_FLAG_SILENT_TRICK; } else { this->rp.flags = 0; } /* ao_update_resample_factor (this); */ ao_dbuf_reset (this); while (this->audio_loop_running) { xine_stream_private_t *stream; int64_t gap; int delay; int drop = 0; /* handle buf */ do { int changed; /* get buffer to process for this loop iteration */ { audio_buffer_t *last = in_buf; lprintf ("loop: get buf from fifo\n"); in_buf = ao_out_fifo_get (this, in_buf); if (!in_buf) break; if (in_buf->num_frames <= 0) { /* drop empty buf */ drop = 1; break; } stream = (xine_stream_private_t *)in_buf->stream; if (!last) { bufs_since_sync++; lprintf ("got a buffer\n"); /* If there is no video stream to update extra info, queue this */ if (stream) { if (!stream->video_decoder_plugin && !in_buf->extra_info->invalid) { int i = this->rp.ei_write; this->base_ei[i] = in_buf->extra_info[0]; this->rp.ei_write = (i + 1) & (EI_RING_SIZE - 1); } } } } if (!this->audio_loop_running) break; /* no change is way most frequent. */ changed = (in_buf->format.bits ^ this->input.bits) | (in_buf->format.rate ^ this->input.rate) | (in_buf->format.mode ^ this->input.mode); if (!ao_driver_lock_2 (this)) continue; /* wait until user unpauses stream. * if we are playing at a different speed (without speed.trick flag) * we must process/free buffers otherwise the entire engine will stop. * next 2 vars are updated via this->driver.mutex and/or out_fifo.mutex. */ if (this->rp.flags & (_AO_FLAG_PAUSE | _AO_FLAG_SILENT_TRICK)) { ao_driver_unlock (this); cur_time = this->clock->get_current_time (this->clock); if (in_buf->vpts < cur_time) { this->rp.dropped++; drop = 1; break; } if (this->rp.dropped) { if (this->rp.flags & _AO_FLAG_PAUSE) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: SINGLE_STEP: dropped %d buffers.\n", this->rp.dropped); } this->rp.dropped = 0; } if ((in_buf->vpts - cur_time) > 2 * 90000) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: vpts/clock error, in_buf->vpts=%" PRId64 " cur_time=%" PRId64 "\n", in_buf->vpts, cur_time); } { extra_info_t *found = NULL; while (this->rp.ei_read != this->rp.ei_write) { extra_info_t *ei = &this->base_ei[this->rp.ei_read]; if (ei->vpts > cur_time) break; found = ei; this->rp.ei_read = (this->rp.ei_read + 1) & (EI_RING_SIZE - 1); } if (found && stream) { xine_stream_private_t *m = stream->side_streams[0]; xine_current_extra_info_set (m, found); if (found->seek_count == this->rp.seek_count3) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: seek_count %d step 3.\n", found->seek_count); this->rp.seek_count3 = -1; pthread_mutex_lock (&m->first_frame.lock); m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); pthread_mutex_unlock (&m->first_frame.lock); } } } if (this->rp.speed != XINE_SPEED_PAUSE) { int wait = (in_buf->vpts - cur_time) * XINE_FINE_SPEED_NORMAL / this->rp.speed; wait /= 90; xine_gettime (&this->out_fifo.wake_time); this->out_fifo.use_wake_time = 1; this->out_fifo.wake_time.tv_sec += wait / 1000; this->out_fifo.wake_time.tv_nsec += (wait % 1000) * 1000000; if (this->out_fifo.wake_time.tv_nsec >= 1000000000) { this->out_fifo.wake_time.tv_nsec -= 1000000000; this->out_fifo.wake_time.tv_sec += 1; } } else { this->out_fifo.use_wake_time = 2; } continue; } /* end of pause mode */ /* change driver's settings as needed */ if (!this->driver.open || changed) { lprintf ("audio format has changed\n"); ao_dbuf_reset (this); if (!stream || !stream->emergency_brake) ao_change_settings (this, &stream->s, in_buf->format.bits, in_buf->format.rate, in_buf->format.mode); if (!this->driver.open) { xine_stream_private_t **s; pthread_mutex_unlock (&this->driver.mutex); xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("audio_out: delay calculation impossible with an unavailable audio device\n")); xine_rwlock_rdlock (&this->streams_lock); for (s = this->streams; *s; s++) { if (!(*s)->emergency_brake) { (*s)->emergency_brake = 1; _x_message (&(*s)->s, XINE_MSG_AUDIO_OUT_UNAVAILABLE, NULL); } } xine_rwlock_unlock (&this->streams_lock); drop = 1; break; } } /* buf timing pt 1 */ if (!this->audio_loop_running) { pthread_mutex_unlock (&this->driver.mutex); break; } delay = this->driver.d->delay (this->driver.d); if (delay < 0) { int start_pts = 0; /* Get the audio card into RUNNING state. */ delay = 0; while (this->audio_loop_running) { delay = this->driver.d->delay (this->driver.d); if (delay >= 0) break; if (ao_fill_gap (this, 10000)) { /* FIXME, this PTS of 1000 should == period size */ delay = -33333; break; } start_pts += 10000; } if (!this->audio_loop_running) { pthread_mutex_unlock (&this->driver.mutex); break; } if (delay == -33333) { pthread_mutex_unlock (&this->driver.mutex); pthread_mutex_lock (&this->driver.intr_mutex); if (this->driver.intr_num) pthread_cond_wait (&this->driver.intr_wake, &this->driver.intr_mutex); pthread_mutex_unlock (&this->driver.intr_mutex); continue; } /* mutex unlock might preempt us. read clock first to stay near delay read time. */ cur_time = this->clock->get_current_time (this->clock); pthread_mutex_unlock (&this->driver.mutex); ao_dbuf_set_min (this, delay); this->pts_in_driver = 0; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: got driver running with %d pts of silence.\n", start_pts); } else { /* mutex unlock might preempt us. read clock first to stay near delay read time. */ cur_time = this->clock->get_current_time (this->clock); pthread_mutex_unlock (&this->driver.mutex); ao_dbuf_set_max (this, delay); } this->rp.dbuf_used = delay; if (!this->audio_loop_running) break; /* current_extra_info not set by video stream or getting too much out of date */ { extra_info_t *found = NULL; while (this->rp.ei_read != this->rp.ei_write) { extra_info_t *ei = &this->base_ei[this->rp.ei_read]; if (ei->vpts > cur_time) break; found = ei; this->rp.ei_read = (this->rp.ei_read + 1) & (EI_RING_SIZE - 1); } if (stream) { xine_stream_private_t *m = stream->side_streams[0]; if (!found) { /* O dear. This extra info ring will unblock xine_play () when the first * frame after seek is actually heared. That is at least one metronom * prebuffer delay (default 14400 pts) later -- too long for fluent seek. * Video out tricks around this by showing the first frame earlier. * We could double a portion of audio here if we have an agile driver, * and if we like to annoy the user sooner or later. * Until there is a better way, just limit the delay to 3000 pts. */ if ((this->rp.ei_read != this->rp.ei_write) && ((cur_time - this->rp.last_flush_vpts) > 3000)) found = &this->base_ei[this->rp.ei_read]; } if (found) { xine_current_extra_info_set (m, found); if (found->seek_count == this->rp.seek_count3) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: seek_count %d step 3.\n", found->seek_count); this->rp.seek_count3 = -1; pthread_mutex_lock (&m->first_frame.lock); m->first_frame.flag = 0; pthread_cond_broadcast (&m->first_frame.reached); pthread_mutex_unlock (&m->first_frame.lock); } } } } /* buf timing pt 2: where, in the timeline is the "end" of the hardware audio buffer at the moment? */ lprintf ("current delay is %d, current time is %" PRId64 "\n", delay, cur_time); /* no sound card should delay more than 23.301s ;-) */ delay = ((uint32_t)delay * this->out_pts_per_kframe) >> 10; this->pts_in_driver = delay; /* External A52 decoder delay correction (in pts) */ delay += this->ptoffs; /* calculate gap: */ gap = in_buf->vpts - cur_time - delay; this->last_gap = gap; lprintf ("now=%" PRId64 ", buffer_vpts=%" PRId64 ", gap=%" PRId64 "\n", cur_time, in_buf->vpts, gap); if (this->resample_sync_method) { /* Correct sound card drift via resampling. If gap is too big to * be corrected this way, we use the fallback: drop/insert frames. * This function only calculates the drift correction factor. The * actual resampling is done by prepare_samples(). */ resample_rate_adjust (this, gap, in_buf); } else { this->resample_sync_factor = 1.0; } /* output audio data synced to master clock */ if (gap < (-1 * AO_MAX_GAP)) { /* drop late buf */ this->last_sgap = 0; this->rp.dropped++; drop = 1; ao_gap_ring_reset (this); } else if (gap > AO_MAX_GAP) { /* for big gaps output silence */ this->last_sgap = 0; pthread_mutex_lock (&this->driver.mutex); if (!(this->resend.driver_caps & AO_CAP_NO_UNPAUSE)) ao_fill_gap (this, gap); else ao_resend_fill (this, gap, in_buf->vpts); pthread_mutex_unlock (&this->driver.mutex); ao_gap_ring_reset (this); } #if 0 /* silence out even small stream start gaps (avoid metronom shift). * disabled because it also kills nice seek with sound :-/ */ else if ((this->rp.seek_count_n != in_buf->extra_info->seek_count) && (gap > 0)) { this->rp.seek_count_n = in_buf->extra_info->seek_count; this->last_sgap = 0; pthread_mutex_lock (&this->driver.mutex); ao_fill_gap (this, gap); pthread_mutex_unlock (&this->driver.mutex); } #endif else { audio_buffer_t *out_buf; int result, sgap; if (this->av_fine_sync == 1) { sgap = ao_gap_ring_add (this, gap); if (abs (sgap) <= this->fine_gap) sgap = 0; } else { sgap = gap; if (abs (sgap) <= this->small_gap) sgap = 0; } if (sgap && (cur_time > next_sync_time) && (bufs_since_sync >= SYNC_BUF_INTERVAL) && !this->resample_sync_method) { /* for small gaps ( tolerance < abs(gap) < AO_MAX_GAP ) * feedback them into metronom's vpts_offset (when using * metronom feedback for A/V sync) */ xine_stream_private_t **s; /* soft limit both step (<= AO_MAX_GAP / 4) and count of steps (1, 2, 3, or 4). * avoid asymptote trap of bringing down step with remaining gap. */ if (sgap < 0) { sgap = sgap < (AO_MAX_GAP / -2) ? (sgap < (AO_MAX_GAP * 3 / -4) ? (sgap >> 2) : (sgap * ((1 << 15) / 3)) >> 15) : (sgap < (AO_MAX_GAP / -4) ? (sgap >> 1) : sgap); sgap = sgap <= this->last_sgap ? sgap : this->last_sgap < (int)gap ? (int)gap : this->last_sgap; } else { sgap = sgap > (AO_MAX_GAP / 2) ? (sgap > (AO_MAX_GAP * 3 / 4) ? (sgap >> 2) : (sgap * ((1 << 15) / 3)) >> 15) : (sgap > (AO_MAX_GAP / 4) ? (sgap >> 1) : sgap); sgap = sgap >= this->last_sgap ? sgap : this->last_sgap > (int)gap ? (int)gap : this->last_sgap; } this->last_sgap = sgap != (int)gap ? sgap : 0; sgap = -sgap; lprintf ("audio_loop: ADJ_VPTS\n"); /* apply this step to the bufs we already got... */ ao_out_fifo_apply_vpts_step (this, sgap); /* ...and tell metronom to apply it to all next ones as well. * the next_sync_time wait will give the engine time to smooth out video. * FIXME: race with ao_put_buffer () ?? */ xine_rwlock_rdlock (&this->streams_lock); for (s = this->streams; *s; s++) (*s)->s.metronom->set_option ((*s)->s.metronom, METRONOM_ADJ_VPTS_OFFSET, sgap); xine_rwlock_unlock (&this->streams_lock); next_sync_time = cur_time + SYNC_TIME_INTERVAL; bufs_since_sync = 0; } if (this->rp.dropped) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: dropped %d late buffers.\n", this->rp.dropped); this->rp.dropped = 0; } #if 0 xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: small gnap %d.\n", (int)gap); { int count; printf ("Audio data\n"); for (count = 0; count < 10; count++) printf ("%x ", buf->mem[count]); printf ("\n"); } #endif out_buf = prepare_samples (this, in_buf); #if 0 { int count; printf ("Audio data2\n"); for (count = 0; count < 10; count++) printf ("%x ", out_buf->mem[count]); printf ("\n"); } #endif if (this->resend.driver_caps & AO_CAP_NO_UNPAUSE) { out_buf->vpts = in_buf->vpts; ao_resend_store (this, out_buf); } lprintf ("loop: writing %d samples to sound device\n", out_buf->num_frames); result = 0; if (this->driver.open) { if (!ao_driver_lock_2 (this)) continue; if (this->driver.open) { result = this->driver.d->write (this->driver.d, out_buf->mem, out_buf->num_frames); this->driver.open = 2; } pthread_mutex_unlock (&this->driver.mutex); } if (result >= 0) { int32_t d; /* estimate current driver buf fill. */ this->rp.dbuf_used += out_buf->num_frames; d = this->rp.dbuf_size - this->rp.dbuf_used; this->rp.dbuf_used += d & (d >> 31); /* get the overrun when another buf of this size adds. */ d = this->rp.dbuf_used + out_buf->num_frames - this->rp.dbuf_size; /* guard against overly long bufs. * TODO: split those into smaller portions. */ if ((d > 0) && (out_buf->num_frames < (this->rp.dbuf_size >> 2))) { /* "delay" is perfect for timing. the actual write buffer use * will jump by hardware buf size that we dont know. * lets just wait one buf length. in milliseconds: */ d = (uint32_t)out_buf->num_frames * 1000u / this->output.rate; /* request out_fifo wait. this way, we still can respond to anything quickly. */ if (d >= 1) { xine_gettime (&this->out_fifo.wake_time); this->out_fifo.use_wake_time = 1; this->out_fifo.wake_time.tv_sec += d / 1000; this->out_fifo.wake_time.tv_nsec += (d % 1000) * 1000000; if (this->out_fifo.wake_time.tv_nsec >= 1000000000) { this->out_fifo.wake_time.tv_nsec -= 1000000000; this->out_fifo.wake_time.tv_sec += 1; } } } } else { /* device unplugged. */ xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("write to sound card failed. Assuming the device was unplugged.\n")); if (stream) _x_message (&stream->s, XINE_MSG_AUDIO_OUT_UNAVAILABLE, NULL); pthread_mutex_lock (&this->driver.mutex); if (this->driver.open) this->driver.d->close (this->driver.d); this->driver.open = 0; _x_free_audio_driver (&this->xine->x, &this->driver.d); this->driver.d = _x_load_audio_output_plugin (&this->xine->x, "none"); if (this->driver.d && (!stream || !stream->emergency_brake)) { if (ao_change_settings (this, &stream->s, in_buf->format.bits, in_buf->format.rate, in_buf->format.mode) == 0) { if (stream) stream->emergency_brake = 1; } if (stream) _x_message (&stream->s, XINE_MSG_AUDIO_OUT_UNAVAILABLE, NULL); } pthread_mutex_unlock (&this->driver.mutex); /* closing the driver will result in XINE_MSG_AUDIO_OUT_UNAVAILABLE to be emitted */ } drop = 1; } } while (0); if (drop) { lprintf ("loop: next buf from fifo\n"); ao_free_fifo_append (this, in_buf); in_buf = NULL; } ao_driver_test_intr (this); } if (in_buf) ao_free_fifo_append (this, in_buf); return NULL; } /* * public a/v processing interface */ int xine_get_next_audio_frame (xine_audio_port_t *this_gen, xine_audio_frame_t *frame) { aos_t *this = (aos_t *) this_gen; audio_buffer_t *in_buf = NULL, *out_buf; struct timespec now = {0, 0}; now.tv_nsec = 990000000; pthread_mutex_lock (&this->out_fifo.mutex); lprintf ("get_next_audio_frame\n"); while (!this->out_fifo.first) { { xine_stream_private_t *stream = this->streams[0]; if (stream && (stream->s.audio_fifo->fifo_size == 0) && (stream->demux.plugin->get_status (stream->demux.plugin) != DEMUX_OK)) { /* no further data can be expected here */ pthread_mutex_unlock (&this->out_fifo.mutex); return 0; } } now.tv_nsec += 20000000; if (now.tv_nsec >= 1000000000) { xine_gettime (&now); now.tv_nsec += 20000000; if (now.tv_nsec >= 1000000000) { now.tv_sec++; now.tv_nsec -= 1000000000; } } { struct timespec ts = now; this->out_fifo.num_waiters++; pthread_cond_timedwait (&this->out_fifo.not_empty, &this->out_fifo.mutex, &ts); this->out_fifo.num_waiters--; } } in_buf = ao_out_fifo_pop_int (this); pthread_mutex_unlock(&this->out_fifo.mutex); if ((in_buf->format.bits != this->input.bits) || (in_buf->format.rate != this->input.rate) || (in_buf->format.mode != this->input.mode)) { xine_stream_private_t *s = (xine_stream_private_t *)in_buf->stream; pthread_mutex_lock (&this->driver.mutex); lprintf ("audio format has changed\n"); if (!(s && s->emergency_brake)) ao_change_settings (this, &s->s, in_buf->format.bits, in_buf->format.rate, in_buf->format.mode); pthread_mutex_unlock (&this->driver.mutex); } out_buf = prepare_samples (this, in_buf); if (out_buf != in_buf) { ao_free_fifo_append (this, in_buf); frame->xine_frame = NULL; } else frame->xine_frame = out_buf; frame->vpts = out_buf->vpts; frame->num_samples = out_buf->num_frames; frame->sample_rate = this->input.rate; frame->num_channels = this->in_channels; frame->bits_per_sample = this->input.bits; frame->pos_stream = out_buf->extra_info->input_normpos; frame->pos_time = out_buf->extra_info->input_time; frame->data = (uint8_t *) out_buf->mem; return 1; } void xine_free_audio_frame (xine_audio_port_t *this_gen, xine_audio_frame_t *frame) { aos_t *this = (aos_t *) this_gen; audio_buffer_t *buf; buf = (audio_buffer_t *) frame->xine_frame; if (buf) ao_free_fifo_append (this, buf); } static int ao_change_settings (aos_t *this, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { int output_sample_rate; if (this->driver.open && !this->grab_only) this->driver.d->close (this->driver.d); this->driver.open = 0; this->input.mode = mode; this->input.rate = rate; this->input.bits = bits; if (!this->grab_only) { int caps = this->driver.d->get_capabilities (this->driver.d); /* not all drivers/cards support 8 bits */ if ((this->input.bits == 8) && !(caps & AO_CAP_8BITS)) { bits = 16; xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("8 bits not supported by driver, converting to 16 bits.\n")); } /* provide mono->stereo and stereo->mono conversions */ if ((this->input.mode == AO_CAP_MODE_MONO) && !(caps & AO_CAP_MODE_MONO)) { mode = AO_CAP_MODE_STEREO; xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("mono not supported by driver, converting to stereo.\n")); } if ((this->input.mode == AO_CAP_MODE_STEREO) && !(caps & AO_CAP_MODE_STEREO)) { mode = AO_CAP_MODE_MONO; xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("stereo not supported by driver, converting to mono.\n")); } output_sample_rate = this->driver.d->open (this->driver.d, bits, this->force_rate ? this->force_rate : rate, mode); } else output_sample_rate = this->input.rate; if (output_sample_rate == 0) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: open failed!\n"); return 0; } this->driver.open = 1; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: output sample rate %d.\n", output_sample_rate); this->last_audio_vpts = 0; this->output.mode = mode; this->output.rate = output_sample_rate; this->output.bits = bits; this->ptoffs = (mode == AO_CAP_MODE_A52) || (mode == AO_CAP_MODE_AC5) ? this->passthrough_offset : 0; if (this->input.rate) { this->audio_step = ((uint32_t)90000 * (uint32_t)32768) / this->input.rate; if (stream) stream->metronom->set_audio_rate (stream->metronom, this->audio_step); } return ao_update_resample_factor (this); } /* * open the audio device for writing to */ static int ao_open (xine_audio_port_t *this_gen, xine_stream_t *s, uint32_t bits, uint32_t rate, int mode) { aos_t *this = (aos_t *) this_gen; int channels; xine_stream_private_t *stream = (xine_stream_private_t *)s; if (stream) stream = stream->side_streams[0]; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: ao_open (%p)\n", (void*)stream); /* Defer _changing_ settings of an open driver to final output stage, following buf queue status. */ if (!this->driver.open) { int ret; if (this->audio_loop_running) { /* make sure there are no more buffers on queue */ ao_out_fifo_loop_flush (this); } if (stream && !stream->emergency_brake) { pthread_mutex_lock( &this->driver.mutex ); ao_dbuf_reset (this); ret = ao_change_settings (this, &stream->s, bits, rate, mode); pthread_mutex_unlock( &this->driver.mutex ); if( !ret ) { stream->emergency_brake = 1; _x_message (&stream->s, XINE_MSG_AUDIO_OUT_UNAVAILABLE, NULL); return 0; } } else { return 0; } } /* * set metainfo */ if (stream) { channels = _x_ao_mode2channels( mode ); if( channels == 0 ) channels = 255; /* unknown */ /* faster than 4x _x_stream_info_set () */ xine_rwlock_wrlock (&stream->info_lock); stream->stream_info[XINE_STREAM_INFO_AUDIO_MODE] = mode; stream->stream_info[XINE_STREAM_INFO_AUDIO_CHANNELS] = channels; stream->stream_info[XINE_STREAM_INFO_AUDIO_BITS] = bits; stream->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE] = rate; xine_rwlock_unlock (&stream->info_lock); } ao_streams_register (this, stream); ao_unref_obsolete (this); return this->output.rate; } static audio_buffer_t *ao_get_buffer (xine_audio_port_t *this_gen) { aos_t *this = (aos_t *) this_gen; audio_buffer_t *buf; buf = ao_free_fifo_get (this); _x_extra_info_reset( buf->extra_info ); buf->stream = NULL; return buf; } static void ao_put_buffer (xine_audio_port_t *this_gen, audio_buffer_t *buf, xine_stream_t *stream) { aos_t *this = (aos_t *) this_gen; int64_t pts; int is_first = 0; if (this->out_fifo.discard_buffers || (buf->num_frames <= 0)) { ao_free_fifo_append (this, buf); return; } this->last_audio_vpts = pts = buf->vpts; /* handle anonymous streams like NULL for easy checking */ if (stream == XINE_ANON_STREAM) stream = NULL; if (stream) { xine_stream_private_t *s = (xine_stream_private_t *)stream; s = s->side_streams[0]; /* faster than 3x _x_stream_info_get () */ xine_rwlock_rdlock (&s->info_lock); buf->format.bits = s->stream_info[XINE_STREAM_INFO_AUDIO_BITS]; buf->format.rate = s->stream_info[XINE_STREAM_INFO_AUDIO_SAMPLERATE]; buf->format.mode = s->stream_info[XINE_STREAM_INFO_AUDIO_MODE]; xine_rwlock_unlock (&s->info_lock); _x_extra_info_merge (buf->extra_info, s->audio_decoder_extra_info); /* containers like AAC-ADIF cannot provide correct input time * without doing half the decoders work again. * if decoder did set pts, use that here. */ if ((buf->extra_info->input_time == -1) && pts) buf->extra_info->input_time = pts / 90; buf->vpts = s->s.metronom->got_audio_samples (s->s.metronom, pts, buf->num_frames); if ((s->first_frame.flag >= 2) && !s->video_decoder_plugin) { pthread_mutex_lock (&s->first_frame.lock); if (s->first_frame.flag >= 2) { xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: seek_count %d step 1.\n", buf->extra_info->seek_count); if (s->first_frame.flag == 3) { xine_current_extra_info_set (s, buf->extra_info); s->first_frame.flag = 0; pthread_cond_broadcast (&s->first_frame.reached); } else { s->first_frame.flag = 1; } is_first = 1; } pthread_mutex_unlock (&s->first_frame.lock); } } buf->extra_info->vpts = buf->vpts; lprintf ("ao_put_buffer, pts=%" PRId64 ", vpts=%" PRId64 "\n", pts, buf->vpts); buf->stream = stream; ao_out_fifo_reref_append (this, buf, is_first); lprintf ("ao_put_buffer done\n"); } static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) { aos_t *this = (aos_t *) this_gen; int n; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: ao_close (%p)\n", (void*)stream); /* unregister stream */ n = ao_streams_unregister (this, (xine_stream_private_t *)stream); /* ao_close () simply means that decoder is finished. The remaining buffered frames * will still be played, unless engine flushes them explicitely. * trigger possible idle driver close. */ if (!n && !this->grab_only) { pthread_mutex_lock (&this->out_fifo.mutex); pthread_cond_signal (&this->out_fifo.not_empty); pthread_mutex_unlock (&this->out_fifo.mutex); } } static void ao_speed_change_cb (void *this_gen, int new_speed) { aos_t *this = (aos_t *)this_gen; ao_driver_lock (this); /* something to do? */ if ((int)this->driver.speed == new_speed) { ao_driver_unlock (this); return; } this->driver.speed = new_speed; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: new speed %d.\n", new_speed); if (!this->grab_only) { if (this->driver.open) { if (new_speed == XINE_SPEED_PAUSE) { /* driver lock makes sure that ao_loop will pause in a safe place. * that is, we cannot pause writing to device, filling gaps etc. * Some simple drivers misunderstand AO_CTRL_PLAY_PAUSE as "wait for running dry first". * Lets try this flush HACK. See also unpause resend buffer. */ if (this->driver.d->get_capabilities (this->driver.d) & AO_CAP_NO_UNPAUSE) this->driver.d->control (this->driver.d, AO_CTRL_FLUSH_BUFFERS, NULL); this->driver.d->control (this->driver.d, AO_CTRL_PLAY_PAUSE, NULL); } else { /* slow motion / fast forward does not play sound, drop buffered * samples from the sound driver (check speed.trick flag) */ if ((new_speed != XINE_FINE_SPEED_NORMAL) && !this->driver.trick) this->driver.d->control (this->driver.d, AO_CTRL_FLUSH_BUFFERS, NULL); this->driver.d->control (this->driver.d, AO_CTRL_PLAY_RESUME, NULL); } } ao_driver_unlock (this); } else { this->rp.speed = this->driver.speed; ao_driver_unlock (this); ao_update_resample_factor (this); } ao_out_fifo_signal (this); } static void ao_exit(xine_audio_port_t *this_gen) { aos_t *this = (aos_t *) this_gen; _x_freep (&this->resend.buf); this->xine->x.clock->unregister_speed_change_callback (this->xine->x.clock, ao_speed_change_cb, this); this->xine->port_ticket->revoke_cb_unregister (this->xine->port_ticket, ao_ticket_revoked, this); if (this->audio_loop_running) { void *p; this->audio_loop_running = 0; pthread_mutex_lock (&this->out_fifo.mutex); pthread_cond_signal (&this->out_fifo.not_empty); pthread_mutex_unlock (&this->out_fifo.mutex); pthread_join (this->audio_thread, &p); } if (!this->grab_only) { ao_driver_t *driver; int vol = 0, prop, caps; pthread_mutex_lock (&this->driver.mutex); driver = this->driver.d; caps = driver->get_capabilities (driver); prop = (caps & AO_CAP_MIXER_VOL) ? AO_PROP_MIXER_VOL : (caps & AO_CAP_PCM_VOL) ? AO_PROP_PCM_VOL : 0; if (prop) vol = driver->get_property (driver, prop); if (this->driver.open) { driver->close (driver); this->driver.open = 0; } this->driver.d = NULL; pthread_mutex_unlock (&this->driver.mutex); if (prop) this->xine->x.config->update_num (this->xine->x.config, "audio.volume.mixer_volume", vol); _x_free_audio_driver (&this->xine->x, &driver); } if (this->driver.dreqs_all) xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: waited %d of %d external driver requests.\n", this->driver.dreqs_wait, this->driver.dreqs_all); /* We are about to free "this". No callback shall refer to it anymore, even if not our own. */ this->xine->x.config->unregister_callbacks (this->xine->x.config, NULL, NULL, this, sizeof (*this)); pthread_mutex_destroy (&this->driver.mutex); pthread_cond_destroy (&this->driver.intr_wake); pthread_mutex_destroy (&this->driver.intr_mutex); ao_streams_close (this); ao_force_unref_all (this, 1); ao_free_fifo_close (this); ao_out_fifo_close (this); _x_freep (&this->frame_buf[0]->mem); _x_freep (&this->frame_buf[1]->mem); xine_freep_aligned (&this->base_samp); free (this); } static uint32_t ao_get_capabilities (xine_audio_port_t *this_gen) { aos_t *this = (aos_t *) this_gen; uint32_t result; if (this->grab_only) { return AO_CAP_MODE_MONO | AO_CAP_MODE_STEREO ; /* FIXME: make configurable | AO_CAP_MODE_4CHANNEL | AO_CAP_MODE_5CHANNEL | AO_CAP_MODE_5_1CHANNEL | AO_CAP_8BITS; */ } else { ao_driver_lock (this); result = this->driver.d->get_capabilities (this->driver.d); ao_driver_unlock (this); } return result; } static int ao_get_property (xine_audio_port_t *this_gen, int property) { aos_t *this = (aos_t *) this_gen; int ret; switch (property) { case XINE_PARAM_VO_SINGLE_STEP: ret = 0; break; case AO_PROP_COMPRESSOR: ret = this->compression_factor_max*100; break; case AO_PROP_BUFS_IN_FIFO: ret = this->audio_loop_running ? this->out_fifo.num_buffers : -1; break; case AO_PROP_BUFS_FREE: ret = this->audio_loop_running ? this->free_fifo.num_buffers : -1; break; case AO_PROP_BUFS_TOTAL: ret = this->audio_loop_running ? this->free_fifo.num_buffers_max : -1; break; case AO_PROP_NUM_STREAMS: xine_rwlock_rdlock (&this->streams_lock); ret = this->num_anon_streams + this->num_streams; xine_rwlock_unlock (&this->streams_lock); break; case AO_PROP_AMP: ret = this->amp_level; break; case AO_PROP_AMP_MUTE: ret = this->amp_mute; break; case AO_PROP_EQ_30HZ: case AO_PROP_EQ_60HZ: case AO_PROP_EQ_125HZ: case AO_PROP_EQ_250HZ: case AO_PROP_EQ_500HZ: case AO_PROP_EQ_1000HZ: case AO_PROP_EQ_2000HZ: case AO_PROP_EQ_4000HZ: case AO_PROP_EQ_8000HZ: case AO_PROP_EQ_16000HZ: ret = this->eq_settings[property - AO_PROP_EQ_30HZ]; break; case AO_PROP_DISCARD_BUFFERS: ret = this->out_fifo.discard_buffers; break; case AO_PROP_CLOCK_SPEED: ret = this->rp.speed; break; case AO_PROP_DRIVER_DELAY: ret = this->last_gap; break; case AO_PROP_PTS_IN_FIFO: pthread_mutex_lock (&this->out_fifo.mutex); /* easier and more precise: * this->out_fifo.pts_sill + last_buf_vpts - this->clock->get_current_time (). * however, net_buf_ctrl calls this _very_ often :-/ */ ret = this->out_fifo.pts_fill + this->out_fifo.pts_in_driver; pthread_mutex_unlock (&this->out_fifo.mutex); break; default: ao_driver_lock (this); ret = this->driver.d->get_property(this->driver.d, property); ao_driver_unlock (this); } return ret; } static int ao_set_property (xine_audio_port_t *this_gen, int property, int value) { aos_t *this = (aos_t *) this_gen; int ret = 0; switch (property) { /* not a typo :-) */ case XINE_PARAM_VO_SINGLE_STEP: ret = !!value; if (this->grab_only) break; if (ret) ao_out_fifo_signal (this); break; case AO_PROP_COMPRESSOR: this->compression_factor_max = (double) value / 100.0; this->do_compress = (this->compression_factor_max >1.0); ret = this->compression_factor_max*100; break; case AO_PROP_AMP: this->amp_level = value; this->do_amp = (value != 100) || this->amp_mute; ret = value; if (value) { static const uint32_t mant[12] = { 2147483648u, 2275179671u, 2410468894u, 2553802834u, 2705659852u, 2866546760u, 3037000500u, 3217589947u, 3408917802u, 3611622603u, 3826380858u, 4053909305u }; value += 20; this->amp_factor = (double)mant[value % 12] * (double)(1 << (value / 12)) * (1.0 / (2147483648.0 * (1 << 10))); } else { this->amp_factor = 0; } break; case AO_PROP_AMP_MUTE: ret = this->amp_mute = value; this->do_amp = (this->amp_factor != 1.0 || this->amp_mute); break; case AO_PROP_EQ_30HZ: case AO_PROP_EQ_60HZ: case AO_PROP_EQ_125HZ: case AO_PROP_EQ_250HZ: case AO_PROP_EQ_500HZ: case AO_PROP_EQ_1000HZ: case AO_PROP_EQ_2000HZ: case AO_PROP_EQ_4000HZ: case AO_PROP_EQ_8000HZ: case AO_PROP_EQ_16000HZ: this->eq_settings[property - AO_PROP_EQ_30HZ] = value; ao_eq_update (this); ret = value; break; case AO_PROP_DISCARD_BUFFERS: /* recursive discard buffers setting */ if (value) { pthread_mutex_lock (&this->out_fifo.mutex); this->out_fifo.discard_buffers++; ret = this->out_fifo.discard_buffers; pthread_cond_signal (&this->out_fifo.not_empty); if (this->grab_only) { /* discard buffers here because we have no output thread. */ ao_out_fifo_manual_flush (this); } pthread_mutex_unlock (&this->out_fifo.mutex); } else { pthread_mutex_lock (&this->out_fifo.mutex); if (this->out_fifo.discard_buffers) { if (this->out_fifo.discard_buffers == 1) { if (!this->grab_only) { if (this->audio_loop_running && this->out_fifo.first) { /* Usually, output thread already did that in the meantime. * If not, do it here and avoid extra context switches. */ ao_out_fifo_manual_flush (this); } this->out_fifo.discard_buffers = ret = 0; pthread_mutex_unlock (&this->out_fifo.mutex); /* flush driver at last lift, so user can hear this seek segment longer. */ ao_flush_driver (this); break; } } this->out_fifo.discard_buffers--; ret = this->out_fifo.discard_buffers; pthread_mutex_unlock (&this->out_fifo.mutex); } else { pthread_mutex_unlock (&this->out_fifo.mutex); ret = 0; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: ao_set_property: discard_buffers is already zero\n"); } } break; case AO_PROP_CLOSE_DEVICE: ao_driver_lock (this); if (this->driver.open) this->driver.d->close (this->driver.d); this->driver.open = 0; ao_driver_unlock (this); break; case AO_PROP_CLOCK_SPEED: /* We no longer need this and that speed paranoia hack, and latch on that clock directly instead. */ ret = value; break; case AO_PROP_PTS_IN_FIFO: pthread_mutex_lock (&this->out_fifo.mutex); ret = this->out_fifo.pts_fill + this->out_fifo.pts_in_driver; pthread_mutex_unlock (&this->out_fifo.mutex); break; default: if (!this->grab_only) { /* Let the sound driver lock it's own mixer */ ret = this->driver.d->set_property(this->driver.d, property, value); } } return ret; } static int ao_control (xine_audio_port_t *this_gen, int cmd, ...) { aos_t *this = (aos_t *) this_gen; va_list args; void *arg; int rval = 0; if (this->grab_only) return 0; ao_driver_lock (this); if(this->driver.open) { va_start(args, cmd); arg = va_arg(args, void*); rval = this->driver.d->control(this->driver.d, cmd, arg); va_end(args); } ao_driver_unlock (this); return rval; } static void ao_flush (xine_audio_port_t *this_gen) { aos_t *this = (aos_t *) this_gen; xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: ao_flush (loop running: %d)\n", this->audio_loop_running); if (this->audio_loop_running) ao_out_fifo_loop_flush (this); } static int ao_status (xine_audio_port_t *this_gen, xine_stream_t *stream, uint32_t *bits, uint32_t *rate, int *mode) { aos_t *this = (aos_t *) this_gen; xine_stream_private_t **s; int ret = 0; if (!stream || (stream == XINE_ANON_STREAM)) { *bits = this->input.bits; *rate = this->input.rate; *mode = this->input.mode; return 0; } xine_rwlock_rdlock (&this->streams_lock); for (s = this->streams; *s; s++) { if (&(*s)->s == stream) { *bits = this->input.bits; *rate = this->input.rate; *mode = this->input.mode; ret = 1; break; } } xine_rwlock_unlock (&this->streams_lock); return ret; } static void ao_update_av_sync_method(void *this_gen, xine_cfg_entry_t *entry) { aos_t *this = (aos_t *) this_gen; lprintf ("av_sync_method = %d\n", entry->num_value); this->av_sync_method_conf = entry->num_value; switch (this->av_sync_method_conf) { case 0: this->resample_sync_method = 0; break; case 1: this->resample_sync_method = 1; break; default: this->resample_sync_method = 0; break; } this->resample_sync_info.valid = 0; } static void ao_update_av_fine_sync_method (void *this_gen, xine_cfg_entry_t *entry) { aos_t *this = (aos_t *)this_gen; pthread_mutex_lock (&this->out_fifo.mutex); this->av_fine_sync = entry->num_value; pthread_mutex_unlock (&this->out_fifo.mutex); } static void ao_update_ptoffs (void *this_gen, xine_cfg_entry_t *entry) { aos_t *this = (aos_t *)this_gen; this->passthrough_offset = entry->num_value; this->ptoffs = (this->output.mode == AO_CAP_MODE_A52) || (this->output.mode == AO_CAP_MODE_AC5) ? this->passthrough_offset : 0; } static void ao_update_slow_fast (void *this_gen, xine_cfg_entry_t *entry) { aos_t *this = (aos_t *)this_gen; this->driver.trick = entry->num_value; ao_out_fifo_signal (this); } xine_audio_port_t *_x_ao_new_port (xine_t *xine, ao_driver_t *driver, int grab_only) { config_values_t *config = xine->config; aos_t *this; uint8_t *vsbuf0, *vsbuf1; this = calloc(1, sizeof(aos_t)) ; if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ this->driver.intr_num = 0; this->driver.dreqs_all = 0; this->driver.dreqs_wait = 0; this->audio_loop_running = 0; this->rp.dropped = 0; this->last_gap = 0; this->last_sgap = 0; this->pts_in_driver = 0; this->compression_factor_max = 0.0; this->do_compress = 0; this->do_amp = 0; this->amp_mute = 0; this->do_equ = 0; this->eq_settings[0] = 0; this->eq_settings[1] = 0; this->eq_settings[2] = 0; this->eq_settings[3] = 0; this->eq_settings[4] = 0; this->eq_settings[5] = 0; this->eq_settings[6] = 0; this->eq_settings[7] = 0; this->eq_settings[8] = 0; this->eq_settings[9] = 0; this->rp.last_flush_vpts = 0; this->resend.vpts = 0; this->resend.driver_caps = 0; this->resend.speed = 0; this->resend.rate = 0; this->resend.mode = 0; this->resend.bits = 0; this->resend.write = 0; this->resend.wrap = 0; this->resend.max = 0; this->resend.frame_size = 0; this->resend.buf = NULL; ao_gap_ring_reset (this); #endif this->rp.seek_count2 = -1; this->rp.seek_count3 = -1; this->rp.seek_count_n = -1; this->driver.d = driver; this->xine = (xine_private_t *)xine; this->clock = xine->clock; this->driver.speed = this->rp.speed = xine->clock->speed; this->base_samp = xine_mallocz_aligned ((NUM_AUDIO_BUFFERS + 1) * AUDIO_BUF_SIZE); vsbuf0 = calloc (1, 4 * AUDIO_BUF_SIZE); vsbuf1 = calloc (1, 4 * AUDIO_BUF_SIZE); if (!this->base_samp || !vsbuf0 || !vsbuf1) { xine_free_aligned (this->base_samp); free (vsbuf0); free (vsbuf1); free (this); return NULL; } ao_streams_open (this); pthread_mutex_init (&this->driver.mutex, NULL); pthread_mutex_init (&this->driver.intr_mutex, NULL); pthread_cond_init (&this->driver.intr_wake, NULL); this->ao.open = ao_open; this->ao.get_buffer = ao_get_buffer; this->ao.put_buffer = ao_put_buffer; this->ao.close = ao_close; this->ao.exit = ao_exit; this->ao.get_capabilities = ao_get_capabilities; this->ao.get_property = ao_get_property; this->ao.set_property = ao_set_property; this->ao.control = ao_control; this->ao.flush = ao_flush; this->ao.status = ao_status; this->grab_only = grab_only; if (!grab_only) this->gap_tolerance = driver->get_gap_tolerance (driver); { static const char *const av_sync_methods[] = {"metronom feedback", "resample", NULL}; this->av_sync_method_conf = config->register_enum ( config, "audio.synchronization.av_sync_method", 0, (char **)av_sync_methods, _("method to sync audio and video"), _("When playing audio and video, there are at least two clocks involved: " "The system clock, to which video frames are synchronized and the clock " "in your sound hardware, which determines the speed of the audio playback. " "These clocks are never ticking at the same speed except for some rare " "cases where they are physically identical. In general, the two clocks " "will run drift after some time, for which xine offers two ways to keep " "audio and video synchronized:\n\n" "metronom feedback\n" "This is the standard method, which applies a countereffecting video drift, " "as soon as the audio drift has accumulated over a threshold.\n\n" "resample\n" "For some video hardware, which is limited to a fixed frame rate (like the " "DXR3 or other decoder cards) the above does not work, because the video " "cannot drift. Therefore we resample the audio stream to make it longer " "or shorter to compensate the audio drift error. This does not work for " "digital passthrough, where audio data is passed to an external decoder in " "digital form."), 20, ao_update_av_sync_method, this); this->resample_sync_method = this->av_sync_method_conf == 1 ? 1 : 0; this->resample_sync_info.valid = 0; } { static const char *const av_fine_sync_methods[] = {"Normal", "Fine", NULL}; this->av_fine_sync = config->register_enum ( config, "audio.synchronization.av_fine_sync", 1, (char **)av_fine_sync_methods, _("a/v sync precision"), _("Normal: keep current drift within driver gap tolerance.\n" "Fine: keep average drift within 1/8 tolerance."), 20, ao_update_av_fine_sync_method, this); } { static const char *const resample_modes[] = {"auto", "off", "on", NULL}; this->resample_conf = config->register_enum ( config, "audio.synchronization.resample_mode", 0, (char **)resample_modes, _("enable resampling"), _("When the sample rate of the decoded audio does not match the capabilities " "of your sound hardware, an adaptation called \"resampling\" is required. " "Here you can select, whether resampling is enabled, disabled or used " "automatically when necessary."), 20, NULL, NULL); } this->force_rate = config->register_num ( config, "audio.synchronization.force_rate", 0, _("always resample to this rate (0 to disable)"), _("Some audio drivers do not correctly announce the capabilities of the audio " "hardware. By setting a value other than zero here, you can force the audio " "stream to be resampled to the given rate."), 20, NULL, NULL); this->passthrough_offset = config->register_num ( config, "audio.synchronization.passthrough_offset", 0, _("offset for digital passthrough"), _("If you use an external surround decoder and audio is ahead or behind video, " "you can enter a fixed offset here to compensate.\n" "The unit of the value is one PTS tick, which is the 90000th part of a second."), 10, ao_update_ptoffs, this); this->driver.trick = this->rp.trick = config->register_bool ( config, "audio.synchronization.slow_fast_audio", 0, _("play audio even on slow/fast speeds"), _("If you enable this option, the audio will be heard even when playback speed is " "different than 1X. Of course, it will sound distorted (lower/higher pitch). " "If want to experiment preserving the pitch you may try the 'stretch' audio post plugin instead."), 10, ao_update_slow_fast, this); this->compression_factor = 2.0; this->amp_factor = 1.0; this->amp_level = 100; /* * pre-allocate memory for samples */ ao_free_fifo_open (this); ao_out_fifo_open (this); { audio_buffer_t *buf = this->base_buf, *list = NULL, **add = &list; extra_info_t *ei = this->base_ei + EI_RING_SIZE; uint8_t *mem = this->base_samp; int i; for (i = 0; i < NUM_AUDIO_BUFFERS; i++) { buf->mem = (int16_t *)mem; buf->mem_size = AUDIO_BUF_SIZE; buf->extra_info = ei; *add = buf; add = &buf->next; buf++; ei++; mem += AUDIO_BUF_SIZE; } *add = NULL; this->free_fifo.first = list; this->free_fifo.add = add; this->free_fifo.num_buffers = this->free_fifo.num_buffers_max = i; this->zero_space = (int16_t *)mem; /* buffers used for audio conversions. need to be resizable */ buf->mem = (int16_t *)vsbuf0; buf->mem_size = 4 *AUDIO_BUF_SIZE; buf->extra_info = ei; this->frame_buf[0] = buf; buf++; ei++; buf->mem = (int16_t *)vsbuf1; buf->mem_size = 4 *AUDIO_BUF_SIZE; buf->extra_info = ei; this->frame_buf[1] = buf; } this->out_fifo.seek_count1 = -1; this->xine->port_ticket->revoke_cb_register (this->xine->port_ticket, ao_ticket_revoked, this); /* * Set audio volume to latest used one ? */ if (this->driver.d) { int vol; vol = config->register_range (config, "audio.volume.mixer_volume", 50, 0, 100, _("startup audio volume"), _("The overall audio volume set at xine startup."), 10, NULL, NULL); if (config->register_bool (config, "audio.volume.remember_volume", 0, _("restore volume level at startup"), _("If disabled, xine will not modify any mixer settings at startup."), 10, NULL, NULL)) { int caps = this->driver.d->get_capabilities (this->driver.d); if (caps & AO_CAP_MIXER_VOL) this->driver.d->set_property (this->driver.d, AO_PROP_MIXER_VOL, vol); else if (caps & AO_CAP_PCM_VOL) this->driver.d->set_property (this->driver.d, AO_PROP_PCM_VOL, vol); } } if (!this->grab_only) { pthread_attr_t pth_attrs; int err; /* * start output thread */ this->audio_loop_running = 1; pthread_attr_init(&pth_attrs); #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0) pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM); #endif err = pthread_create (&this->audio_thread, &pth_attrs, ao_loop, this); pthread_attr_destroy(&pth_attrs); if (err != 0) { xprintf (&this->xine->x, XINE_VERBOSITY_NONE, "audio_out: can't create thread (%s)\n", strerror(err)); xprintf (&this->xine->x, XINE_VERBOSITY_LOG, _("audio_out: sorry, this should not happen. please restart xine.\n")); this->audio_loop_running = 0; /* no need to inline ao_exit () here. */ this->ao.exit (&this->ao); return NULL; } xprintf (&this->xine->x, XINE_VERBOSITY_DEBUG, "audio_out: thread created\n"); } this->xine->x.clock->register_speed_change_callback (this->xine->x.clock, ao_speed_change_cb, this); return &this->ao; } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/input_cache.c����������������������������������������������������������0000644�0001750�0001750�00000033063�14647725152�016314� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Buffered Input Plugin (request optimizer). * * The goal of this input plugin is to reduce * the number of calls to the real input plugin. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "input_cache" #define LOG_VERBOSE /* #define LOG */ #include <xine/xine_internal.h> #include "xine_private.h" #define DEFAULT_BUFFER_SIZE 8192 typedef struct { input_plugin_t input_plugin; /* inherited structure */ input_plugin_t *main_input_plugin; /* original input plugin */ xine_stream_t *stream; char *buf; size_t buf_size; /* allocated size */ int buf_len; /* data size */ int buf_pos; int is_clone; /* Statistics */ int read_call; int main_read_call; int seek_call; int main_seek_call; } cache_input_plugin_t; /* * read data from input plugin and write it into file */ static off_t cache_plugin_read(input_plugin_t *this_gen, void *buf_gen, off_t len) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; char *buf = (char *)buf_gen; lprintf("cache_plugin_read: len=%"PRId64"\n", len); this->read_call++; if (len <= 0) { _x_assert(len >= 0); return len; } /* optimized for common cases */ if (len <= (this->buf_len - this->buf_pos)) { /* all bytes are in the buffer */ switch (len) { #if defined(__i386__) || defined(__x86_64__) /* These are restricted to x86 and amd64. Some other architectures don't * handle unaligned accesses in the same way, quite possibly requiring * extra code over and above simple byte copies. */ case 8: *((uint64_t *)buf) = *(uint64_t *)(&(this->buf[this->buf_pos])); break; case 7: buf[6] = (char)this->buf[this->buf_pos + 6]; /* fallthru */ case 6: *((uint32_t *)buf) = *(uint32_t *)(&(this->buf[this->buf_pos])); *((uint16_t *)&buf[4]) = *(uint16_t *)(&(this->buf[this->buf_pos + 4])); break; case 5: buf[4] = (char)this->buf[this->buf_pos + 4]; /* fallthru */ case 4: *((uint32_t *)buf) = *(uint32_t *)(&(this->buf[this->buf_pos])); break; case 3: buf[2] = (char)this->buf[this->buf_pos + 2]; /* fallthru */ case 2: *((uint16_t *)buf) = *(uint16_t *)(&(this->buf[this->buf_pos])); break; #endif case 1: *buf = (char)this->buf[this->buf_pos]; break; default: xine_fast_memcpy(buf, this->buf + this->buf_pos, len); } this->buf_pos += len; return len; } { off_t read_len = 0; int in_buf_len; /* copy internal buffer bytes */ in_buf_len = this->buf_len - this->buf_pos; if (in_buf_len > 0) { xine_fast_memcpy(buf, this->buf + this->buf_pos, in_buf_len); len -= in_buf_len; read_len = in_buf_len; } this->buf_len = 0; this->buf_pos = 0; /* read the rest */ if (len < (off_t)this->buf_size) { /* readahead bytes */ do { int main_read; this->main_read_call++; main_read = this->main_input_plugin->read (this->main_input_plugin, this->buf + this->buf_len, this->buf_size - this->buf_len); if (main_read == 0) { /* EOF */ len = this->buf_len; break; } if (main_read < 0) /* read error: report return value to caller */ return main_read; this->buf_len += main_read; } while (this->buf_len < (int)len); if (len) { xine_fast_memcpy (buf + read_len, this->buf, len); this->buf_pos = len; read_len += len; } return read_len; } do { /* direct read */ off_t main_read; this->main_read_call++; main_read = this->main_input_plugin->read (this->main_input_plugin, buf + read_len, len); if (main_read == 0) /* EOF */ break; if (main_read < 0) /* read error: report return value to caller */ return main_read; read_len += main_read; len -= main_read; } while (len > 0); return read_len; } } /* * open should never be called */ static int cache_plugin_open(input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; xine_log(this->stream->xine, XINE_LOG_MSG, _(LOG_MODULE": open() function should never be called\n")); return 0; } static uint32_t cache_plugin_get_capabilities(input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; return this->main_input_plugin->get_capabilities(this->main_input_plugin); } static buf_element_t *cache_plugin_read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t todo) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; buf_element_t *buf; int in_buf_len; in_buf_len = this->buf_len - this->buf_pos; if (in_buf_len > 0) { off_t read_len; /* hmmm, the demuxer mixes read and read_block */ buf = fifo->buffer_pool_alloc (fifo); if (buf) { buf->type = BUF_DEMUX_BLOCK; _x_assert(todo <= buf->max_size); read_len = cache_plugin_read (this_gen, buf->content, todo); buf->size = read_len; } } else { buf = this->main_input_plugin->read_block(this->main_input_plugin, fifo, todo); this->read_call++; this->main_read_call++; } return buf; } static off_t cache_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; off_t cur_pos; off_t rel_offset; off_t new_buf_pos; lprintf("offset: %"PRId64", origin: %d\n", offset, origin); this->seek_call++; if( !this->buf_len ) { cur_pos = this->main_input_plugin->seek(this->main_input_plugin, offset, origin); this->main_seek_call++; } else { cur_pos = this->main_input_plugin->get_current_pos(this->main_input_plugin); if( cur_pos >= (this->buf_len - this->buf_pos) ) cur_pos -= (this->buf_len - this->buf_pos); else cur_pos = 0; switch (origin) { case SEEK_CUR: rel_offset = offset; break; case SEEK_SET: rel_offset = offset - cur_pos; break; default: /* invalid origin - main input should know better */ cur_pos = this->main_input_plugin->seek(this->main_input_plugin, offset, origin); this->buf_len = this->buf_pos = 0; this->main_seek_call++; return cur_pos; } new_buf_pos = (off_t)this->buf_pos + rel_offset; lprintf("buf_len: %d, rel_offset=%"PRId64", new_buf_pos=%"PRId64"\n", this->buf_len, rel_offset, new_buf_pos); if ((new_buf_pos < 0) || (new_buf_pos >= this->buf_len)) { if( origin == SEEK_SET ) cur_pos = this->main_input_plugin->seek(this->main_input_plugin, offset, origin); else cur_pos = this->main_input_plugin->seek(this->main_input_plugin, offset - (this->buf_len - this->buf_pos), origin); this->buf_len = this->buf_pos = 0; this->main_seek_call++; } else { this->buf_pos = (int)new_buf_pos; cur_pos += rel_offset; } } return cur_pos; } static off_t cache_plugin_seek_time(input_plugin_t *this_gen, int time_offset, int origin) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; off_t cur_pos; lprintf("time_offset: %d, origin: %d\n", time_offset, origin); this->seek_call++; cur_pos = this->main_input_plugin->seek_time(this->main_input_plugin, time_offset, origin); this->buf_len = this->buf_pos = 0; this->main_seek_call++; return cur_pos; } static off_t cache_plugin_get_current_pos(input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; off_t cur_pos; cur_pos = this->main_input_plugin->get_current_pos(this->main_input_plugin); if( this->buf_len ) { if( cur_pos >= (this->buf_len - this->buf_pos) ) cur_pos -= (this->buf_len - this->buf_pos); else cur_pos = 0; } return cur_pos; } static int cache_plugin_get_current_time(input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; int cur_time; cur_time = this->main_input_plugin->get_current_time(this->main_input_plugin); return cur_time; } static off_t cache_plugin_get_length (input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; return this->main_input_plugin->get_length(this->main_input_plugin); } static uint32_t cache_plugin_get_blocksize(input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; return this->main_input_plugin->get_blocksize(this->main_input_plugin); } static const char* cache_plugin_get_mrl (input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; return this->main_input_plugin->get_mrl(this->main_input_plugin); } /* * dispose main input plugin and self */ static void cache_plugin_dispose(input_plugin_t *this_gen) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; lprintf("cache_plugin_dispose\n"); xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE": read calls: %d, main input read calls: %d\n", this->read_call, this->main_read_call); xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE": seek_calls: %d, main input seek calls: %d\n", this->seek_call, this->main_seek_call); if (this->is_clone) this->main_input_plugin->dispose (this->main_input_plugin); else _x_free_input_plugin (this->stream, this->main_input_plugin); _x_freep(&this->buf); free(this); } /* * create self instance, */ static int cache_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type); static input_plugin_t *cache_plugin_new (xine_stream_t *stream, input_plugin_t *main_plugin) { cache_input_plugin_t *this; /* check given input plugin */ if (!main_plugin) { xine_log(stream->xine, XINE_LOG_MSG, _(LOG_MODULE": input plugin not defined!\n")); return NULL; } lprintf("mrl: %s\n", main_plugin->get_mrl(main_plugin)); this = calloc(1, sizeof(cache_input_plugin_t)); if (!this) return NULL; this->main_input_plugin = main_plugin; this->stream = stream; this->input_plugin.open = cache_plugin_open; this->input_plugin.get_capabilities = cache_plugin_get_capabilities; this->input_plugin.read = cache_plugin_read; this->input_plugin.read_block = cache_plugin_read_block; this->input_plugin.seek = cache_plugin_seek; if(this->main_input_plugin->seek_time) this->input_plugin.seek_time = cache_plugin_seek_time; this->input_plugin.get_current_pos = cache_plugin_get_current_pos; if(this->main_input_plugin->get_current_time) this->input_plugin.get_current_time = cache_plugin_get_current_time; this->input_plugin.get_length = cache_plugin_get_length; this->input_plugin.get_blocksize = cache_plugin_get_blocksize; this->input_plugin.get_mrl = cache_plugin_get_mrl; this->input_plugin.get_optional_data = cache_plugin_get_optional_data; this->input_plugin.dispose = cache_plugin_dispose; this->input_plugin.input_class = main_plugin->input_class; /* use main input block size */ this->buf_size = this->main_input_plugin->get_blocksize(this->main_input_plugin); if (this->buf_size < DEFAULT_BUFFER_SIZE) { this->buf_size = DEFAULT_BUFFER_SIZE; } this->buf = calloc(1, this->buf_size); if (!this->buf) { free (this); return NULL; } return &this->input_plugin; } input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream) { input_plugin_t *main_plugin = stream->input_plugin; return cache_plugin_new (stream, main_plugin); } static int cache_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { cache_input_plugin_t *this = (cache_input_plugin_t *)this_gen; if (data_type == INPUT_OPTIONAL_DATA_CLONE) { input_plugin_t *new_main = NULL, *new_cache = NULL; if (!data) return INPUT_OPTIONAL_UNSUPPORTED; if (!(this->main_input_plugin->get_capabilities (this->main_input_plugin) & INPUT_CAP_CLONE)) return INPUT_OPTIONAL_UNSUPPORTED; if (this->main_input_plugin->get_optional_data (this->main_input_plugin, &new_main, INPUT_OPTIONAL_DATA_CLONE) != INPUT_OPTIONAL_SUCCESS) return INPUT_OPTIONAL_UNSUPPORTED; if (!new_main) return INPUT_OPTIONAL_UNSUPPORTED; new_cache = cache_plugin_new (this->stream, new_main); if (!new_cache) { input_plugin_t **q = data; *q = new_main; return INPUT_OPTIONAL_SUCCESS; } this = (cache_input_plugin_t *)new_cache; this->is_clone = 1; { input_plugin_t **q = data; *q = new_cache; } return INPUT_OPTIONAL_SUCCESS; } return this->main_input_plugin->get_optional_data( this->main_input_plugin, data, data_type); } �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/Makefile.am������������������������������������������������������������0000644�0001750�0001750�00000005043�14647725152�015717� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������include $(top_srcdir)/misc/Makefile.common include $(top_srcdir)/lib/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(FT2_CFLAGS) $(FONTCONFIG_CFLAGS) \ $(VISIBILITY_FLAG) AM_CPPFLAGS += $(XDG_BASEDIR_CPPFLAGS) $(ZLIB_CPPFLAGS) -DXINE_LIBRARY_COMPILE -DXINE_ENGINE_INTERNAL XINEUTILS_LIB = $(top_builddir)/src/xine-utils/libxineutils.la # FIXME: these are currently unused: EXTRA_DIST = lrb.c lrb.h accel_vaapi.h accel_vdpau.h accel_xvmc.h BUILT_SOURCES = dummy.c CLEANFILES = dummy.c if WIN32 DEF_FILE = libxine-$(XINE_MAJOR).def def_ldflags=-Wl,--output-def,$(DEF_FILE) else DEF_FILE = endif noinst_HEADERS = bswap.h ffmpeg_bswap.h xine_private.h builtins.h lib_LTLIBRARIES = libxine.la # Technically, this is a lie; it just makes sure that we get a static lib. noinst_LTLIBRARIES = libxine-interface.la libxine_la_SOURCES = xine.c metronom.c configfile.c buffer.c \ load_plugins.c video_decoder.c buffer_types.c \ audio_decoder.c video_out.c audio_out.c resample.c events.c \ video_overlay.c osd.c spu.c scratch.c demux.c vo_scale.c \ xine_interface.c post.c broadcaster.c io_helper.c \ input_rip.c input_cache.c info_helper.c refcounter.c \ id3.c alphablend.c net_buf_ctrl.c builtins.c \ xine_private.h libxine_la_DEPENDENCIES = $(XINEUTILS_LIB) $(XDG_BASEDIR_DEPS) \ $(pthread_dep) $(LIBXINEPOSIX) \ libxine-interface.la libxine_la_LIBADD = $(PTHREAD_LIBS) $(DYNAMIC_LD_LIBS) $(LTLIBINTL) $(ZLIB_LIBS) \ -lm $(XINEUTILS_LIB) $(LTLIBICONV) $(FT2_LIBS) $(FONTCONFIG_LIBS) \ $(LIBXINEPOSIX) $(RT_LIBS) $(NET_LIBS) $(XDG_BASEDIR_LIBS) \ $(MLIB_LIBS) libxine_la_LDFLAGS = $(LDFLAGS_NOUNDEFINED) $(AM_LDFLAGS) $(def_ldflags) $(GCSECTIONS) \ -weak libxine-interface.la \ -version-info $(XINE_LT_CURRENT):$(XINE_LT_REVISION):$(XINE_LT_AGE) dummy.c: $(AM_V_at)rm -f dummy.c $(AM_V_GEN)echo '/* Automatically generated */' > dummy.c libxine_interface_la_SOURCES = dummy.c libxine_interface_la_LDFLAGS = $(AM_LDFLAGS) $(def_ldflags) \ -version-info $(XINE_LT_CURRENT):$(XINE_LT_REVISION):$(XINE_LT_AGE) # Yes, we need to install this. install-exec-hook: libxine-interface.la $(INSTALL_DATA) libxine-interface.la "$(DESTDIR)$(libdir)"/libxine-interface.la clean-local: rm -f libxine-interface.la $(XINEUTILS_LIB): $(MAKE) -C $(top_builddir)/src/xine-utils libxineutils.la if WIN32 install-exec-local: -cp -p $(DEF_FILE) $(DESTDIR)$(libdir) endif uninstall-local: rm -f "$(DESTDIR)$(libdir)"/libxine-interface.la -rm -f $(DESTDIR)$(libdir)/$(DEF_FILE) ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/configfile.c�����������������������������������������������������������0000644�0001750�0001750�00000240254�14647725152�016141� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * config object (was: file) management - implementation */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <errno.h> #include <time.h> #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <xine/configfile.h> #include "bswap.h" #define LOG_MODULE "configfile" #define LOG_VERBOSE /* #define LOG */ /* #define DEBUG_CONFIG_FIND */ /* XXX: does this break some strange applictions?? */ #define SINGLE_CHUNK_ENUMS #include <xine/xineutils.h> #include <xine/sorted_array.h> #include <xine/xine_internal.h> #include "xine_private.h" #define MAX_SORT_KEY 320 #if defined(WIN32) # define PSEP '\\' #else # define PSEP '/' #endif /* FIXME: static data, no expiry ?! */ static const xine_config_entry_translation_t *config_entry_translation_user = NULL; typedef struct { cfg_entry_t entry; int *magic; char *internal_key; /** << xine_fast_string_t * */ #define STRING_BACKLOG_LD 2 char *string_backlog[(1 << STRING_BACKLOG_LD) + 1]; uint32_t sb_index; } fat_cfg_entry_t; static void _config_set_fat_entry (fat_cfg_entry_t *entry) { entry->magic = &entry->entry.range_min; } static int _config_is_fat_entry (fat_cfg_entry_t *entry) { return entry->magic == &entry->entry.range_min; } typedef struct { fat_cfg_entry_t entry; char buf[MAX_SORT_KEY + 32]; } very_fat_cfg_entry_t; typedef struct { config_values_t config; xine_sarray_t *key_index; } fat_config_values_t; typedef struct { xine_config_cb_t callback; void *data; } _cfg_cb_info_t; /* If a config entry had at least 1 callback and/or data ptr during its lifetime, * then keep telling the application it need not restart on changes. * Mark this state in enum_count field of serialized entry. */ #define _CFG_DUMMY_DATA (void *)1 #define _CFG_BIT_HAS_CALLBACKS 30 typedef struct { uint32_t size; uint32_t used; _cfg_cb_info_t items[1]; } _cfg_cb_relay_t; static void _cfg_relay (void *data, xine_cfg_entry_t *e) { _cfg_cb_info_t *i, *s; _cfg_cb_relay_t *relay = data; if (!relay) return; for (i = &relay->items[0], s = i + relay->used; i < s; i++) i->callback (i->data, e); } static int _cfg_cb_clear (cfg_entry_t *entry) { int n = 0; for (; entry; entry = entry->next) { if (entry->callback == _cfg_relay) { _cfg_cb_relay_t *relay = entry->callback_data; if (relay) { n += relay->used; free (relay); } entry->callback_data = _CFG_DUMMY_DATA; } else if (entry->callback) { n += 1; entry->callback_data = _CFG_DUMMY_DATA; } entry->callback = NULL; } return n; } static int _cfg_cb_clear_report (xine_t *xine, cfg_entry_t *entry) { int n = 0; for (; entry; entry = entry->next) { int have = n; if (entry->callback == _cfg_relay) { _cfg_cb_relay_t *relay = entry->callback_data; if (relay) { n += relay->used; free (relay); } entry->callback_data = _CFG_DUMMY_DATA; } else if (entry->callback) { n += 1; entry->callback_data = _CFG_DUMMY_DATA; } entry->callback = NULL; if ((n > have) && xine) xprintf (xine, XINE_VERBOSITY_DEBUG, "configfile: %d orphaned callbacks for %s.\n", n - have, entry->key); } return n; } static int _cfg_cb_d_rem (cfg_entry_t *entry, xine_config_cb_t callback, void *data, size_t data_size) { int n = 0; if (!data_size) data_size = 1; for (; entry; entry = entry->next) { if (entry->callback == _cfg_relay) { _cfg_cb_info_t *r, *e; _cfg_cb_relay_t *relay = entry->callback_data; if (!relay) { entry->callback = NULL; continue; } r = &relay->items[0]; e = r + relay->used; while (r < e) { if ((callback == r->callback) && PTR_IN_RANGE (r->data, data, data_size)) *r = *(--e); else r++; } n += relay->used; relay->used = r - &relay->items[0]; n -= relay->used; if (relay->used <= 1) { r->callback = NULL; r->data = NULL; entry->callback = relay->items[0].callback; entry->callback_data = relay->items[0].data; free (relay); } } else { if ((callback == entry->callback) && PTR_IN_RANGE (entry->callback_data, data, data_size)) { n++; entry->callback_data = _CFG_DUMMY_DATA; entry->callback = NULL; } } } return n; } static int _cfg_cb_rem (cfg_entry_t *entry, xine_config_cb_t callback) { int n = 0; for (; entry; entry = entry->next) { if (entry->callback == _cfg_relay) { _cfg_cb_info_t *r, *e; _cfg_cb_relay_t *relay = entry->callback_data; if (!relay) { entry->callback = NULL; continue; } r = &relay->items[0]; e = r + relay->used; while (r < e) { if (callback == r->callback) *r = *(--e); else r++; } n += relay->used; relay->used = r - &relay->items[0]; n -= relay->used; if (relay->used <= 1) { r->callback = NULL; r->data = NULL; entry->callback = relay->items[0].callback; entry->callback_data = relay->items[0].data; free (relay); } } else { if (callback == entry->callback) { n++; entry->callback_data = _CFG_DUMMY_DATA; entry->callback = NULL; } } } return n; } static int _cfg_d_rem (cfg_entry_t *entry, void *data, size_t data_size) { int n = 0; if (!data_size) data_size = 1; for (; entry; entry = entry->next) { if (entry->callback == _cfg_relay) { _cfg_cb_info_t *r, *e; _cfg_cb_relay_t *relay = entry->callback_data; if (!relay) { entry->callback = NULL; continue; } r = &relay->items[0]; e = r + relay->used; while (r < e) { if (PTR_IN_RANGE (r->data, data, data_size)) *r = *(--e); else r++; } n += relay->used; relay->used = r - &relay->items[0]; n -= relay->used; if (relay->used <= 1) { r->callback = NULL; r->data = NULL; entry->callback = relay->items[0].callback; entry->callback_data = relay->items[0].data; free (relay); } } else { if (PTR_IN_RANGE (entry->callback_data, data, data_size)) { n++; entry->callback_data = _CFG_DUMMY_DATA; entry->callback = NULL; } } } return n; } static int _cfg_any_rem (cfg_entry_t *entry, xine_config_cb_t callback, void *data, size_t data_size) { if (callback) { if (data) return _cfg_cb_d_rem (entry, callback, data, data_size); else return _cfg_cb_rem (entry, callback); } else { if (data) return _cfg_d_rem (entry, data, data_size); else return _cfg_cb_clear (entry); } } static void _cfg_cb_add (cfg_entry_t *entry, xine_config_cb_t callback, void *data) { _cfg_cb_relay_t *relay; _cfg_cb_info_t *info; if (!callback) { if (!data || entry->callback) return; entry->callback_data = data; return; } if (!entry->callback) { entry->callback = callback; entry->callback_data = data; return; } if (entry->callback == _cfg_relay) { relay = entry->callback_data; if (!relay) return; } else { relay = malloc (sizeof (*relay) + 8 * sizeof (relay->items[0])); if (!relay) return; relay->size = 8; relay->used = 1; relay->items[0].callback = entry->callback; relay->items[0].data = entry->callback_data; entry->callback = _cfg_relay; entry->callback_data = relay; } if (relay->used + 1 > relay->size) { uint32_t size = relay->size + 8; _cfg_cb_relay_t *r2 = realloc (relay, sizeof (*relay) + size * sizeof (relay->items[0])); if (!r2) return; r2->size = size; entry->callback_data = relay = r2; } info = &relay->items[0] + relay->used; info->callback = callback; info->data = data; relay->used++; } static const char *config_xlate_old (const char *s) { static const char * const tab[] = { /*"audio.a52_pass_through", NULL,*/ "audio.alsa_a52_device", "audio.device.alsa_passthrough_device", "audio.alsa_default_device", "audio.device.alsa_default_device", "audio.alsa_front_device", "audio.device.alsa_front_device", "audio.alsa_mixer_name", "audio.device.alsa_mixer_name", "audio.alsa_mmap_enable", "audio.device.alsa_mmap_enable", "audio.alsa_surround40_device", "audio.device.alsa_surround40_device", "audio.alsa_surround51_device", "audio.device.alsa_surround51_device", "audio.av_sync_method", "audio.synchronization.av_sync_method", /*"audio.directx_device", NULL,*/ "audio.esd_latency", "audio.device.esd_latency", /*"audio.five_channel", NULL,*/ /*"audio.five_lfe_channel", NULL,*/ "audio.force_rate", "audio.synchronization.force_rate", /*"audio.four_channel", NULL,*/ /*"audio.four_lfe_channel", NULL,*/ "audio.irixal_gap_tolerance", "audio.device.irixal_gap_tolerance", /*"audio.mixer_name", NULL,*/ "audio.mixer_number", "audio.device.oss_mixer_number", "audio.mixer_volume", "audio.volume.mixer_volume", "audio.num_buffers", "engine.buffers.audio_num_buffers", "audio.oss_device_name", "audio.device.oss_device_name", /*"audio.oss_device_num", NULL,*/ "audio.oss_device_number", "audio.device.oss_device_number", /*"audio.oss_pass_through_bug", NULL,*/ "audio.passthrough_offset", "audio.synchronization.passthrough_offset", "audio.remember_volume", "audio.volume.remember_volume", "audio.resample_mode", "audio.synchronization.resample_mode", "audio.speaker_arrangement", "audio.output.speaker_arrangement", "audio.sun_audio_device", "audio.device.sun_audio_device", "codec.a52_dynrng", "audio.a52.dynamic_range", "codec.a52_level", "audio.a52.level", "codec.a52_surround_downmix", "audio.a52.surround_downmix", "codec.ffmpeg_pp_quality", "video.processing.ffmpeg_pp_quality", "codec.real_codecs_path", "decoder.external.real_codecs_path", "codec.win32_path", "decoder.external.win32_codecs_path", "dxr3.alt_play_mode", "dxr3.playback.alt_play_mode", "dxr3.color_interval", "dxr3.output.keycolor_interval", "dxr3.correct_durations", "dxr3.playback.correct_durations", /*"dxr3.devicename", NULL,*/ "dxr3.enc_add_bars", "dxr3.encoding.add_bars", "dxr3.enc_alt_play_mode", "dxr3.encoding.alt_play_mode", "dxr3.enc_swap_fields", "dxr3.encoding.swap_fields", "dxr3.encoder", "dxr3.encoding.encoder", "dxr3.fame_quality", "dxr3.encoding.fame_quality", "dxr3.keycolor", "dxr3.output.keycolor", "dxr3.lavc_bitrate", "dxr3.encoding.lavc_bitrate", "dxr3.lavc_qmax", "dxr3.encoding.lavc_qmax", "dxr3.lavc_qmin", "dxr3.encoding.lavc_qmin", "dxr3.lavc_quantizer", "dxr3.encoding.lavc_quantizer", "dxr3.preferred_tvmode", "dxr3.output.tvmode", "dxr3.rte_bitrate", "dxr3.encoding.rte_bitrate", "dxr3.shrink_overlay_area", "dxr3.output.shrink_overlay_area", "dxr3.sync_every_frame", "dxr3.playback.sync_every_frame", "dxr3.videoout_mode", "dxr3.output.mode", "input.cdda_cddb_cachedir", "media.audio_cd.cddb_cachedir", "input.cdda_cddb_port", "media.audio_cd.cddb_port", "input.cdda_cddb_server", "media.audio_cd.cddb_server", "input.cdda_device", "media.audio_cd.device", "input.cdda_use_cddb", "media.audio_cd.use_cddb", "input.css_cache_path", "media.dvd.css_cache_path", "input.css_decryption_method", "media.dvd.css_decryption_method", "input.drive_slowdown", "media.audio_cd.drive_slowdown", "input.dvb_last_channel_enable", "media.dvb.remember_channel", "input.dvb_last_channel_watched", "media.dvb.last_channel", "input.dvbdisplaychan", "media.dvb.display_channel", "input.dvbzoom", "media.dvb.zoom", "input.dvb_adapternum", "media.dvb.adapter", "input.dvd_device", "media.dvd.device", "input.dvd_language", "media.dvd.language", "input.dvd_raw_device", "media.dvd.raw_device", "input.dvd_region", "media.dvd.region", "input.dvd_seek_behaviour", "media.dvd.seek_behaviour", "input.dvd_skip_behaviour", "media.dvd.skip_behaviour", "input.dvd_use_readahead", "media.dvd.readahead", "input.file_hidden_files", "media.files.show_hidden_files", "input.file_origin_path", "media.files.origin_path", "input.http_no_proxy", "media.network.http_no_proxy", "input.http_proxy_host", "media.network.http_proxy_host", "input.http_proxy_password", "media.network.http_proxy_password", "input.http_proxy_port", "media.network.http_proxy_port", "input.http_proxy_user", "media.network.http_proxy_user", "input.mms_network_bandwidth", "media.network.bandwidth", "input.mms_protocol", "media.network.mms_protocol", "input.pvr_device", "media.wintv_pvr.device", "input.v4l_radio_device_path", "media.video4linux.radio_device", "input.v4l_video_device_path", "media.video4linux.video_device", "input.vcd_device", "media.vcd.device", "misc.cc_center", "subtitles.closedcaption.center", "misc.cc_enabled", "subtitles.closedcaption.enabled", "misc.cc_font", "subtitles.closedcaption.font", "misc.cc_font_size", "subtitles.closedcaption.font_size", "misc.cc_italic_font", "subtitles.closedcaption.italic_font", "misc.cc_scheme", "subtitles.closedcaption.scheme", "misc.demux_strategy", "engine.demux.strategy", "misc.memcpy_method", "engine.performance.memcpy_method", "misc.osd_text_palette", "ui.osd.text_palette", "misc.save_dir", "media.capture.save_dir", "misc.spu_font", "subtitles.separate.font", "misc.spu_src_encoding", "subtitles.separate.src_encoding", "misc.spu_subtitle_size", "subtitles.separate.subtitle_size", "misc.spu_use_unscaled_osd", "subtitles.separate.use_unscaled_osd", "misc.spu_vertical_offset", "subtitles.separate.vertical_offset", "misc.sub_timeout", "subtitles.separate.timeout", "post.goom_csc_method", "effects.goom.csc_method", "post.goom_fps", "effects.goom.fps", "post.goom_height", "effects.goom.height", "post.goom_width", "effects.goom.width", "vcd.autoadvance", "media.vcd.autoadvance", "vcd.autoplay", "media.vcd.autoplay", "vcd.comment_format", "media.vcd.comment_format", "vcd.debug", "media.vcd.debug", "vcd.default_device", "media.vcd.device", "vcd.length_reporting", "media.vcd.length_reporting", "vcd.show_rejected", "media.vcd.show_rejected", "vcd.title_format", "media.vcd.title_format", "video.XV_DOUBLE_BUFFER", "video.device.xv_double_buffer", "video.XV_FILTER", "video.device.xv_filter", "video.deinterlace_method", "video.output.xv_deinterlace_method", "video.disable_exact_osd_alpha_blending", "video.output.disable_exact_alphablend", "video.disable_scaling", "video.output.disable_scaling", "video.fb_device", "video.device.fb_device", "video.fb_gamma", "video.output.fb_gamma", "video.horizontal_position", "video.output.horizontal_position", "video.num_buffers", "engine.buffers.video_num_buffers", "video.opengl_double_buffer", "video.device.opengl_double_buffer", "video.opengl_gamma", "video.output.opengl_gamma", "video.opengl_min_fps", "video.output.opengl_min_fps", "video.opengl_renderer", "video.output.opengl_renderer", "video.pgx32_device", "video.device.pgx32_device", "video.pgx64_brightness", "video.output.pgx64_brightness", "video.pgx64_chromakey_en", "video.device.pgx64_chromakey_en", "video.pgx64_colour_key", "video.device.pgx64_colour_key", /*"video.pgx64_device", NULL,*/ "video.pgx64_multibuf_en", "video.device.pgx64_multibuf_en", /*"video.pgx64_overlay_mode", NULL,*/ "video.pgx64_saturation", "video.output.pgx64_saturation", "video.sdl_hw_accel", "video.device.sdl_hw_accel", "video.unichrome_cpu_save", "video.device.unichrome_cpu_save", "video.vertical_position", "video.output.vertical_position", "video.vidix_blue_intensity", "video.output.vidix_blue_intensity", "video.vidix_colour_key_blue", "video.device.vidix_colour_key_blue", "video.vidix_colour_key_green", "video.device.vidix_colour_key_green", "video.vidix_colour_key_red", "video.device.vidix_colour_key_red", "video.vidix_green_intensity", "video.output.vidix_green_intensity", "video.vidix_red_intensity", "video.output.vidix_red_intensity", "video.vidix_use_double_buffer", "video.device.vidix_double_buffer", "video.vidixfb_device", "video.device.vidixfb_device", "video.warn_discarded_threshold", "engine.performance.warn_discarded_threshold", "video.warn_skipped_threshold", "engine.performance.warn_skipped_threshold", "video.xshm_gamma", "video.output.xshm_gamma", "video.xv_autopaint_colorkey", "video.device.xv_autopaint_colorkey", "video.xv_colorkey", "video.device.xv_colorkey", "video.xv_pitch_alignment", "video.device.xv_pitch_alignment", "video.xvmc_more_frames", "video.device.xvmc_more_frames", "video.xvmc_nvidia_color_fix", "video.device.xvmc_nvidia_color_fix" }; int b = 0, e = sizeof (tab) / sizeof (tab[0]) / 2, m = e >> 1; do { int d = strcmp (s, tab[m << 1]); if (d == 0) return tab[(m << 1) + 1]; if (d < 0) e = m; else b = m + 1; m = (b + e) >> 1; } while (b != e); return NULL; } static int config_section_enum (const uint8_t *s, uint32_t l) { int d; switch (l) { case 2: if (!memcmp (s, "ui", 2)) return 2; break; case 3: if (!memcmp (s, "gui", 3)) return 1; break; case 4: d = memcmp (s, "misc", 4); if (d == 0) return 14; if (d < 0) { if (!memcmp (s, "dxr3", 4)) return 5; } else { if (!memcmp (s, "post", 4)) return 11; } break; case 5: d = memcmp (s, "input", 5); if (d == 0) return 6; if (d < 0) { if (!memcmp (s, "audio", 5)) return 3; if (!memcmp (s, "codec", 5)) return 8; } else { if (!memcmp (s, "media", 5)) return 7; if (!memcmp (s, "video", 5)) return 4; } break; case 6: if (!memcmp (s, "engine", 6)) return 13; break; case 7: if (!memcmp (s, "decoder", 7)) return 9; if (!memcmp (s, "effects", 7)) return 12; break; case 9: if (!memcmp (s, "subtitles", 9)) return 10; break; default: ; } return 0; } static size_t config_make_sort_key (char *dest, const char *key, int *klen, int exp_level) { uint8_t *q = (uint8_t *)dest, *e = q + MAX_SORT_KEY - 7; const uint8_t *p = (const uint8_t *)key, *b; int n; uint32_t l; /* section name */ b = p; while (1) { while (*p > '.') p++; if (!*p || (*p == '.')) break; p++; } l = p - b; n = config_section_enum (b, l); if (n > 0) { *q++ = n; } else { if (l > (uint32_t)(e - q)) l = e - q; xine_small_memcpy (q, b, l); q += l; } if (*p) p++; *q++ = 0x1f; /* subsection name */ b = p; while (1) { while (*p > '.') p++; if (!*p || (*p == '.')) break; p++; } l = p - b; if (l > (uint32_t)(e - q)) l = e - q; xine_small_memcpy (q, b, l); q += l; if (*p) p++; *q++ = 0x1f; /* TJ. original code did sort by section/subsection/exp/name. * We can do that here as well but that means inefficient * adding (2 passes) and finding (linear scanning). * 2 entries with same key but different exp level never * were supported anyway, and frontends group entries by * section only. So lets leave level out, and benefit from * binary searches instead. */ #if 0 /* experience level */ n = exp_level; q[2] = (n % 10) + '0'; n /= 10; q[1] = (n % 10) + '0'; n /= 10; q[0] = (n % 10) + '0'; q += 3; *q++ = 0x1f; #else (void)exp_level; #endif /* entry name */ b = p; l = xine_find_byte ((const char *)b, 0); *klen = (b - (const uint8_t *)key) + l; if (l > (uint32_t)(e - q)) l = e - q; xine_small_memcpy (q, b, l); q += l; *q = 0; return q - (uint8_t *)dest; } #if 0 /* Ugly: rebuild index every time. Maybe we could cache it somewhere? */ static cfg_entry_t **config_array (config_values_t *this, cfg_entry_t **tab, int *n) { cfg_entry_t *e; int m = *n, i; for (i = 0, e = this->first; e; e = e->next) { tab[i++] = e; if (i >= m) { cfg_entry_t **t2; if (m == *n) { m += 512; t2 = malloc (m * sizeof (*tab)); if (!t2) break; memcpy (t2, tab, (m - 512) * sizeof (*tab)); } else { m += 512; t2 = realloc (tab, m * sizeof (*tab)); if (!t2) break; } tab = t2; } } *n = i; return tab; } #endif static int config_validate (config_values_t *this_gen) { fat_config_values_t *this = (fat_config_values_t *)this_gen; fat_cfg_entry_t *entry; int num_new = 0; /* Paranoia: * 1. Find manually added entries. */ for (entry = (fat_cfg_entry_t *)this->config.first; entry; entry = (fat_cfg_entry_t *)entry->entry.next) { if (!_config_is_fat_entry (entry)) { if (xine_sarray_add (this->key_index, entry) >= 0) { num_new++; if (this->config.xine) { xprintf (this->config.xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": WARNING: found manually added entry \"%s\".\n", entry->entry.key); } } } } if (num_new) { int index, num_entries = xine_sarray_size (this->key_index); cfg_entry_t **prev; for (prev = &this->config.first, index = 0; index < num_entries; prev = &entry->entry.next, index++) { entry = xine_sarray_get (this->key_index, index); *prev = &entry->entry; } this->config.last = &entry->entry; } return num_new; } #define FIND_ONLY 0x7fffffff static fat_cfg_entry_t *config_insert (config_values_t *this_gen, const char *key, int exp_level) { fat_config_values_t *this = (fat_config_values_t *)this_gen; very_fat_cfg_entry_t dummy_entry; size_t internal_key_len; fat_cfg_entry_t *entry; int index, num_entries, klen; if (!key) return NULL; if (!key[0]) return NULL; _config_set_fat_entry (&dummy_entry.entry); dummy_entry.entry.internal_key = xine_fast_string_init (dummy_entry.buf, sizeof (dummy_entry.buf)); internal_key_len = config_make_sort_key (dummy_entry.entry.internal_key, key, &klen, exp_level); xine_fast_string_set (dummy_entry.entry.internal_key, NULL, internal_key_len); num_entries = xine_sarray_size (this->key_index); if (exp_level == FIND_ONLY) { index = xine_sarray_binary_search (this->key_index, &dummy_entry); if (index < 0) { /* scan manually added entries */ if (config_validate (&this->config)) index = xine_sarray_binary_search (this->key_index, &dummy_entry); if (index < 0) return NULL; } entry = xine_sarray_get (this->key_index, index); } else { index = xine_sarray_add (this->key_index, &dummy_entry); if (index >= 0) { cfg_entry_t *e1, *e2; char *buf, *_key = malloc (klen + 1); /* new. key should never be NULL or empty. */ if (!_key) return NULL; entry = malloc (sizeof (*entry) + internal_key_len + 32); xine_sarray_move_location (this->key_index, entry, index); if (!entry) { free (_key); return NULL; } xine_small_memcpy (_key, key, klen + 1); #ifdef HAVE_ZERO_SAFE_MEM memset (entry, 0, sizeof (*entry)); #else entry->entry.num_value = 0; entry->entry.num_default = 0; entry->entry.range_min = 0; entry->entry.range_max = 0; entry->entry.next = NULL; entry->entry.enum_values = NULL; entry->entry.unknown_value = NULL; entry->entry.str_value = NULL; entry->entry.str_default = NULL; entry->entry.help = NULL; entry->entry.description = NULL; entry->entry.callback = NULL; entry->entry.callback_data = NULL; { uint32_t u; for (u = 0; u < (1 << STRING_BACKLOG_LD) + 1; u++) entry->string_backlog[u] = NULL; } #endif entry->sb_index = 1 << STRING_BACKLOG_LD; entry->entry.config = &this->config; entry->entry.key = _key; entry->entry.type = XINE_CONFIG_TYPE_UNKNOWN; entry->entry.exp_level = exp_level; _config_set_fat_entry (entry); buf = (char *)entry + sizeof (*entry); entry->internal_key = xine_fast_string_init (buf, internal_key_len + 32); xine_fast_string_set (entry->internal_key, dummy_entry.entry.internal_key, internal_key_len); /* sigh. make public links. */ num_entries++; e1 = index > 0 ? xine_sarray_get (this->key_index, index - 1) : NULL; e2 = index < num_entries - 1 ? xine_sarray_get (this->key_index, index + 1) : NULL; if (e1) { if (e2) { if (e1->next == e2) { e1->next = &entry->entry; entry->entry.next = e2; } } else { e1->next = &entry->entry; this->config.last = &entry->entry; } } else { if (e2) { this->config.first = &entry->entry; entry->entry.next = e2; } else { this->config.first = this->config.last = &entry->entry; } } } else { /* found */ index = ~index; entry = xine_sarray_get (this->key_index, index); } } return entry; } static const char *config_xlate_internal (const char *key, const xine_config_entry_translation_t *trans) { --trans; while ((++trans)->old_name) if (trans->new_name[0] && strcmp(key, trans->old_name) == 0) return trans->new_name; return NULL; } #define _MAX_CFG_KEY 320 static const char *config_translate_key (const char *key, char *tmp, size_t klen) { /* Returns translated key or, if no translation found, NULL. * Translated key may be written to tmp. */ const char *newkey; /* first, special-case the decoder entries (so that new ones can be added * without requiring modification of the translation table). */ if (!strncmp (key, "decoder.", 8)) { if ((klen > 8 + 9) && !memcmp (key + klen - 9, "_priority", 9) && (klen < _MAX_CFG_KEY + 8 + 9 - 26 - 1)) { memcpy (tmp, "engine.decoder_priorities.", 26); xine_small_memcpy (tmp + 26, key + 8, klen - 8 - 9); tmp[26 + klen - 8 - 9] = 0; return tmp; } } /* search the translation table... */ newkey = config_xlate_old (key); if (!newkey && config_entry_translation_user) newkey = config_xlate_internal (key, config_entry_translation_user); return newkey; } static cfg_entry_t *config_lookup_entry_int (config_values_t *this, const char *key) { cfg_entry_t *entry; char tmp[_MAX_CFG_KEY]; /* try twice at most (second time with translation from old key name) */ entry = &(config_insert (this, key, FIND_ONLY))->entry; if (entry) return entry; /* we did not find a match, maybe this is an old config entry name * trying to translate */ key = config_translate_key (key, tmp, xine_find_byte (key, 0)); if (!key) return NULL; entry = &(config_insert (this, key, FIND_ONLY))->entry; return entry; } static char **str_array_dup (const char *const *from, uint32_t *n) { #ifdef SINGLE_CHUNK_ENUMS uint32_t sizes[257], *sitem, all; const char * const *fitem; char **to, **titem, *q; *n = 0; if (!from) return NULL; fitem = from; sitem = sizes; all = sizeof (char *); while (*fitem && (sitem < sizes + 256)) all += (*sitem++ = xine_find_byte (*fitem++, 0) + 1) + sizeof (char *); *sitem = 0; to = malloc (all); if (!to) return NULL; *n = sitem - sizes; q = (char *)to + (*n + 1) * sizeof (char *); fitem = from; sitem = sizes; titem = to; while (*sitem) { *titem++ = q; xine_small_memcpy (q, *fitem++, *sitem); q += *sitem++; } *titem = NULL; return to; #else const char * const *fitem; char **to, **titem; *n = 0; if (!from) return NULL; for (fitem = from; *fitem; fitem++) ; to = malloc ((fitem - from + 1) * sizeof (char *)); if (!to) return NULL; *n = fitem - from; fitem = from; titem = to; while (*fitem) *titem++ = strdup (*fitem++); *titem = NULL; return to; #endif } static char **str_array_ldup (const char * const *from, const uint32_t *len, uint32_t n) { #ifdef SINGLE_CHUNK_ENUMS char **ret, *m; uint32_t need, u; need = (n + 1) * (sizeof (char *) + 1); for (u = 0; u < n; u++) need += len[u]; m = malloc (need); if (!m) return NULL; ret = (char **)m; m += (n + 1) * sizeof (char *); for (u = 0; u < n; u++) { ret[u] = m; xine_small_memcpy (m, from[u], len[u]); m += len[u]; *m++ = 0; } ret[n] = NULL; return ret; #else uint32_t _n; (void)len; return str_array_dup (from, &_n); #endif } static void str_array_free (char **a) { char **i; if (!a) return; for (i = a; *i; i++) ; if (a[0] != (char *)(i + 1)) { for (i = a; *i; i++) free (*i); } free (a); } /* * external interface */ static cfg_entry_t *config_lookup_entry(config_values_t *this, const char *key) { cfg_entry_t *entry; pthread_mutex_lock(&this->config_lock); entry = config_lookup_entry_int (this, key); pthread_mutex_unlock(&this->config_lock); return entry; } /* 1 private */ static cfg_entry_t *config_lookup_entry_safe (config_values_t *this, const char *key) { pthread_mutex_lock (&this->config_lock); if (this->lookup_entry == config_lookup_entry) return config_lookup_entry_int (this, key); return this->lookup_entry (this, key); } static char *config_lookup_string(config_values_t *this, const char *key) { cfg_entry_t *entry; char *str_value = NULL; entry = config_lookup_entry_safe(this, key); if (!entry) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_LOG, "configfile: WARNING: entry %s not found\n", key); goto out; } if (entry->type != XINE_CONFIG_TYPE_STRING) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_LOG, "configfile: WARNING: %s is not string entry\n", key); goto out; } if (entry->str_value) { str_value = strdup(entry->str_value); } out: pthread_mutex_unlock(&this->config_lock); return str_value; } static void config_free_string(config_values_t *this, char **str) { (void)this; _x_freep(str); } static int config_lookup_num(config_values_t *this, const char *key, int def_value) { cfg_entry_t *entry; int value = def_value; entry = config_lookup_entry_safe(this, key); if (!entry) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_LOG, "configfile: WARNING: entry %s not found\n", key); goto out; } switch (entry->type) { case XINE_CONFIG_TYPE_RANGE: case XINE_CONFIG_TYPE_ENUM: case XINE_CONFIG_TYPE_NUM: case XINE_CONFIG_TYPE_BOOL: value = entry->num_value; break; default: if (this->xine) xprintf (this->xine, XINE_VERBOSITY_LOG, "configfile: WARNING: %s is not numeric entry\n", key); break; } out: pthread_mutex_unlock(&this->config_lock); return value; } static void config_reset_value (fat_cfg_entry_t *entry) { /* NULL is a frequent case. */ if (entry->entry.str_value) {free (entry->entry.str_value); entry->entry.str_value = NULL;} if (entry->entry.str_default) {free (entry->entry.str_default); entry->entry.str_default = NULL;} if (entry->entry.description) {free (entry->entry.description); entry->entry.description = NULL;} if (entry->entry.help) xine_ref_string_unref (&entry->entry.help); str_array_free (entry->entry.enum_values); entry->entry.enum_values = NULL; entry->entry.num_value = 0; if (_config_is_fat_entry (entry)) { uint32_t u; for (u = 0; u < (1 << STRING_BACKLOG_LD) + 1; u++) { if (entry->string_backlog[u]) { free (entry->string_backlog[u]); entry->string_backlog[u] = NULL; } } } } static void config_shallow_copy (xine_cfg_entry_t *dest, const cfg_entry_t *src) { dest->key = src->key; dest->type = src->type; dest->exp_level = src->exp_level; dest->unknown_value = src->unknown_value; dest->str_value = src->str_value; dest->str_default = src->str_default; dest->num_value = src->num_value; dest->num_default = src->num_default; dest->range_min = src->range_min; dest->range_max = src->range_max; dest->enum_values = src->enum_values; dest->description = src->description; dest->help = src->help; dest->callback = src->callback; dest->callback_data = src->callback_data; } static void config_new_entry (config_values_t *this, cfg_entry_t *entry) { /* we created a new entry, call the callback */ if (this->new_entry_cb) { xine_cfg_entry_t cb_entry; /* thread safe extension, private to _x_scan_plugins () * (.cur is otherwise unused). */ this->cur = entry; config_shallow_copy (&cb_entry, entry); this->new_entry_cb (this->new_entry_cbdata, &cb_entry); this->cur = NULL; } } static cfg_entry_t *config_register_key (config_values_t *this, const char *key, int exp_level, xine_config_cb_t changed_cb, void *cb_data, const char *description, const char *help) { fat_cfg_entry_t *entry; lprintf ("registering %s\n", key); pthread_mutex_lock (&this->config_lock); entry = config_insert (this, key, exp_level); if (!entry) { pthread_mutex_unlock (&this->config_lock); return NULL; } /* new entry */ entry->entry.exp_level = exp_level != FIND_ONLY ? exp_level : 0; /* add callback */ _cfg_cb_add (&entry->entry, changed_cb, cb_data); if (entry->entry.type != XINE_CONFIG_TYPE_UNKNOWN) { lprintf ("config entry already registered: %s\n", key); } else { config_reset_value (entry); entry->entry.description = description ? strdup (description) : NULL; entry->entry.help = help ? xine_ref_string_ref (help, -1) : NULL; } return &entry->entry; } static char *config_register_filename (config_values_t *this, const char *key, const char *def_value, int req_type, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { cfg_entry_t *entry; if (!key || !def_value) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "config_register_filename: error: config=%p, key=%s, def_value=%s.\n", (void *)this, key ? key : "NULL", def_value ? def_value : "NULL"); return NULL; } entry = config_register_key (this, key, exp_level, changed_cb, cb_data, description, help); if (!entry) return NULL; if (entry->type == XINE_CONFIG_TYPE_UNKNOWN) { /* set string */ entry->type = XINE_CONFIG_TYPE_STRING; entry->num_value = req_type; entry->str_default = strdup (def_value); if (entry->unknown_value) { entry->str_value = entry->unknown_value; entry->unknown_value = NULL; } else { entry->str_value = strdup (def_value); } } config_new_entry (this, entry); pthread_mutex_unlock (&this->config_lock); return entry->str_value; } static char *config_register_string (config_values_t *this, const char *key, const char *def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { return config_register_filename (this, key, def_value, 0, description, help, exp_level, changed_cb, cb_data); } static int config_register_num (config_values_t *this, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { cfg_entry_t *entry; if (!key) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "config_register_num: error: config=%p, key=%s.\n", (void *)this, key ? key : "NULL"); return 0; } entry = config_register_key (this, key, exp_level, changed_cb, cb_data, description, help); if (!entry) return 0; if (entry->type == XINE_CONFIG_TYPE_UNKNOWN) { entry->type = XINE_CONFIG_TYPE_NUM; entry->num_default = def_value; entry->range_min = -2147483647 - 1; entry->range_max = 2147483647; if (entry->unknown_value) { const char *val = entry->unknown_value; entry->num_value = xine_str2int32 (&val); _x_freep (&entry->unknown_value); } else { entry->num_value = def_value; } } config_new_entry (this, entry); pthread_mutex_unlock (&this->config_lock); return entry->num_value; } static int config_register_bool (config_values_t *this, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { cfg_entry_t *entry; if (!key) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "config_register_bool: error: config=%p, key=%s.\n", (void *)this, key ? key : "NULL"); return 0; } entry = config_register_key (this, key, exp_level, changed_cb, cb_data, description, help); if (!entry) return 0; if (entry->type == XINE_CONFIG_TYPE_UNKNOWN) { entry->type = XINE_CONFIG_TYPE_BOOL; entry->num_default = def_value; entry->range_min = 0; entry->range_max = 1; if (entry->unknown_value) { const char *val = entry->unknown_value; entry->num_value = xine_str2int32 (&val); _x_freep (&entry->unknown_value); } else { entry->num_value = def_value; } entry->num_value = entry->num_value ? 1 : 0; } config_new_entry (this, entry); pthread_mutex_unlock (&this->config_lock); return entry->num_value; } static int config_register_range (config_values_t *this, const char *key, int def_value, int min, int max, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { cfg_entry_t *entry; if (!key) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "config_register_range: error: config=%p, key=%s.\n", (void *)this, key ? key : "NULL"); return 0; } entry = config_register_key (this, key, exp_level, changed_cb, cb_data, description, help); if (!entry) return 0; if (entry->type == XINE_CONFIG_TYPE_UNKNOWN) { entry->type = XINE_CONFIG_TYPE_RANGE; entry->num_default = def_value; if (max < min) max = min; entry->range_min = min; entry->range_max = max; if (entry->unknown_value) { const char *val = entry->unknown_value; entry->num_value = xine_str2int32 (&val); /* validate value (config files can be edited ...) */ /* Allow default to be out of range. xine-ui uses this for brightness etc. */ if (entry->num_value != def_value) { if (entry->num_value > max) entry->num_value = max; else if (entry->num_value < min) entry->num_value = min; } _x_freep (&entry->unknown_value); } else { entry->num_value = def_value; } } config_new_entry (this, entry); pthread_mutex_unlock (&this->config_lock); return entry->num_value; } static int config_parse_enum (const char *str, const char **values) { const char **value, *p; int i; /* try 1: literal match */ for (value = values; *value; value++) { if (!strcmp (str, *value)) break; } if (*value) return value - values; /* try 2: numerical index */ p = str; i = xine_str2int32 (&p); if ((p > str) && (i >= 0) && (i < (int)(value - values))) return i; /* fallback */ return 0; } static int config_register_enum (config_values_t *this, const char *key, int def_value, char **values, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { cfg_entry_t *entry; if (!key || !values) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "config_register_enum: error: config=%p, key=%s, values=%p.\n", (void *)this, key ? key : "NULL", (void *)values); return 0; } entry = config_register_key (this, key, exp_level, changed_cb, cb_data, description, help); if (!entry) return 0; if (entry->type == XINE_CONFIG_TYPE_UNKNOWN) { uint32_t value_count; entry->type = XINE_CONFIG_TYPE_ENUM; entry->num_default = def_value; if (entry->unknown_value) { entry->num_value = config_parse_enum (entry->unknown_value, (const char **)values); if (entry->num_value < 0) entry->num_value = def_value; _x_freep (&entry->unknown_value); } else { entry->num_value = def_value; } /* allocate and copy the enum values */ entry->enum_values = str_array_dup ((const char * const *)values, &value_count); entry->range_min = 0; entry->range_max = value_count; if (entry->num_value >= (int)value_count) entry->num_value = value_count; } else if (entry->type == XINE_CONFIG_TYPE_ENUM) { /* xine-ui does this to update the list. */ if (entry->enum_values && values) { const char **old, **new; for (old = (const char **)entry->enum_values, new = (const char **)values; *old && *new; old++, new++) { if (strcmp (*old, *new)) break; } if (*old || *new) { uint32_t value_count; char **nv = str_array_dup ((const char * const *)values, &value_count); if (nv) { int found = -1; if ((entry->num_value >=0) && (entry->num_value < entry->range_max)) { for (new = (const char **)values; *new; new++) { if (!strcmp (entry->enum_values[entry->num_value], *new)) { found = new - (const char **)values; break; } } } str_array_free (entry->enum_values); entry->enum_values = nv; entry->num_default = (def_value >= 0) && (def_value < (int)value_count) ? def_value : 0; entry->num_value = found < 0 ? 0 : found; entry->range_min = 0; entry->range_max = value_count; } } } } config_new_entry (this, entry); pthread_mutex_unlock (&this->config_lock); return entry->num_value; } static void config_update_num_e (cfg_entry_t *entry, int value) { switch (entry->type) { case XINE_CONFIG_TYPE_RANGE: if (value != entry->num_default) { if (value < entry->range_min) value = entry->range_min; else if (value > entry->range_max) value = entry->range_max; } entry->num_value = value; break; case XINE_CONFIG_TYPE_BOOL: entry->num_value = value ? 1 : 0; break; case XINE_CONFIG_TYPE_ENUM: if (value != entry->num_default) { if (value < 0) value = 0; else if (value >= entry->range_max) value = entry->range_max - 1; } /* fall through */ case XINE_CONFIG_TYPE_NUM: entry->num_value = value; break; default: ; } if (entry->callback) { xine_cfg_entry_t cb_entry; config_shallow_copy (&cb_entry, entry); /* it is safe to enter the callback from within a locked context * because we use a recursive mutex. */ entry->callback (entry->callback_data, &cb_entry); } } static void config_update_num (config_values_t *this, const char *key, int value) { cfg_entry_t *entry; lprintf ("updating %s to %d\n", key, value); entry = config_lookup_entry_safe (this, key); if (!entry) { lprintf ("WARNING! tried to update unknown key %s (to %d)\n", key, value); pthread_mutex_unlock (&this->config_lock); return; } if ((entry->type == XINE_CONFIG_TYPE_UNKNOWN) || (entry->type == XINE_CONFIG_TYPE_STRING)) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "configfile: error - tried to update non-num type %d (key %s, value %d)\n", entry->type, entry->key, value); pthread_mutex_unlock (&this->config_lock); return; } config_update_num_e (entry, value); pthread_mutex_unlock (&this->config_lock); } /* Anything can be updated with a string. Config file load uses this. */ static void config_update_string_e (cfg_entry_t *entry, const char *value) { char *str_free = NULL; int min, max; switch (entry->type) { case XINE_CONFIG_TYPE_RANGE: min = entry->range_min; max = entry->range_max; goto set_snum; case XINE_CONFIG_TYPE_NUM: min = -2147483647 - 1; max = 2147483647; goto set_snum; case XINE_CONFIG_TYPE_BOOL: min = 0; max = 1; set_snum: { const char *val = value; int v = xine_str2int32 (&val); if (v != entry->num_default) { if (v < min) v = min; else if (v > max) v = max; } entry->num_value = v; break; } case XINE_CONFIG_TYPE_ENUM: entry->num_value = config_parse_enum (value, (const char **)entry->enum_values); break; case XINE_CONFIG_TYPE_STRING: /* Client may be using the string directly, not a private duplicate of it. * Idea #1: Let both the old and new strings be valid during the change callback * as sort of a safe switch protocol there. However, to be really safe, client * needs to lock the config object during any use of the string as well. * Even worse: no callback... * Doig a private copy inside callback merely moves the thread issue to client side. * config_lookup_string () is quite safe, but also inefficient as value changes are rare. * Idea #2: keep a full backlog of outdated strings. * Might be misused for flooding the heap. * Idea #3: with callback, park previous string at entry.unknown_value. * without, park initial string there. * if we have our nice fat_cfg_entry_t, do both :-) */ if (value != entry->str_value) { fat_cfg_entry_t *e = (fat_cfg_entry_t *)entry; if (e->entry.str_value) { if (_config_is_fat_entry (e)) { str_free = e->string_backlog[e->sb_index]; e->string_backlog[e->sb_index] = e->entry.str_value; e->sb_index = (e->sb_index + 1) & ((1 << STRING_BACKLOG_LD) - 1); } else { if (e->entry.callback || !e->entry.unknown_value) { str_free = e->entry.unknown_value; e->entry.unknown_value = e->entry.str_value; } else { str_free = e->entry.str_value; } } } e->entry.str_value = strdup (value); } break; default: if (value != entry->unknown_value) { str_free = entry->unknown_value; entry->unknown_value = strdup (value); } } if (entry->callback) { xine_cfg_entry_t cb_entry; config_shallow_copy (&cb_entry, entry); /* it is safe to enter the callback from within a locked context * because we use a recursive mutex. */ entry->callback (entry->callback_data, &cb_entry); } free (str_free); } static void config_update_string (config_values_t *this, const char *key, const char *value) { cfg_entry_t *entry; lprintf ("updating %s to %s\n", key, value); entry = config_lookup_entry_safe (this, key); if (!entry) { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "configfile: error - tried to update unknown key %s (to %s)\n", key, value); pthread_mutex_unlock (&this->config_lock); return; } config_update_string_e (entry, value); pthread_mutex_unlock (&this->config_lock); } /* * front end config translation handling */ void xine_config_set_translation_user (const xine_config_entry_translation_t *xlate) { config_entry_translation_user = xlate; } /* * load/save config data from/to afile (e.g. $HOME/.xine/config) */ void xine_config_load (xine_t *xine, const char *filename) { config_values_t *this = xine->config; xine_fast_text_t *xft; this->xine = xine; lprintf ("reading from file '%s'\n", filename); /* TJ. I got far less than 32k, so > 2M is probably insane. */ xft = xine_fast_text_load (filename, 2 << 20); if (xft) { int version; pthread_mutex_lock (&this->config_lock); version = this->current_version; pthread_mutex_unlock (&this->config_lock); while (1) { size_t lsize; char *line = xine_fast_text_line (xft, &lsize); char *value; if (!line) break; if (!line[0]) continue; /* skip comments */ if (line[0] == '#') continue; if (line[0] == '.') { if ((lsize > 9) && !memcmp (line + 1, "version:", 8)) { const char *val = line + 9; version = xine_str2int32 (&val); if (version > CONFIG_FILE_VERSION) { xine_log (xine, XINE_LOG_MSG, _("The current config file has been modified by a newer version of xine.")); } pthread_mutex_lock (&this->config_lock); this->current_version = version; pthread_mutex_unlock (&this->config_lock); continue; } } line[lsize] = ':'; value = line + xine_find_byte (line, ':'); line[lsize] = 0; if (*value == ':') { cfg_entry_t *entry; size_t klen = value - line; *value++ = 0; pthread_mutex_lock (&this->config_lock); if (version < CONFIG_FILE_VERSION) { /* old config file -> let's see if we have to rename this one */ entry = &(config_insert (this, line, FIND_ONLY))->entry; if (!entry) { char tmp[_MAX_CFG_KEY]; const char *key = config_translate_key (line, tmp, klen); if (!key) key = line; /* no translation? fall back on untranslated key */ entry = &(config_insert (this, key, 50))->entry; } } else { entry = &(config_insert (this, line, 50))->entry; } if (entry) config_update_string_e (entry, value); pthread_mutex_unlock (&this->config_lock); } } xine_fast_text_unload (&xft); xine_log (xine, XINE_LOG_MSG, _("Loaded configuration from file '%s'\n"), filename); return; } if (errno != ENOENT) xine_log (xine, XINE_LOG_MSG, _("Failed to load configuration from file '%s': %s\n"), filename, strerror (errno)); } static size_t xine_realpath (char *buf, const char *filename, size_t bsize, int *num_links) { char tbuf[1536]; struct stat sbuf; size_t used; int try; if (!buf || !bsize) return 0; if (!filename) { buf[0] = 0; return 0; } used = strlcpy (buf, filename, bsize); if (used >= bsize) used = bsize - 1; try = 8; #if defined(HAVE_LSTAT) && defined(HAVE_READLINK) for (; try; try--) { ssize_t r; if (lstat (buf, &sbuf)) break; if (!S_ISLNK (sbuf.st_mode)) break; r = readlink (buf, tbuf, sizeof (tbuf) - 1); if (r <= 0) break; tbuf[r] = 0; if (tbuf[0] == PSEP) { /* absolute link */ used = (size_t)r < bsize ? (size_t)r : bsize - 1; xine_small_memcpy (buf, tbuf, used); buf[used] = 0; } else { size_t left; char *p; /* relative link */ for (p = buf + used; (p > buf) && (p[-1] != PSEP); p--) ; left = bsize - (p - buf); used = (size_t)r < left ? (size_t)r : left - 1; xine_small_memcpy (p, tbuf, used); p[used] = 0; used += p - buf; } } if (!try) return 0; #endif *num_links = 8 - try; return used; } void xine_config_save (xine_t *xine, const char *filename) { config_values_t *this; char fname[1536], bname[1536], tname[1536]; struct stat sbuf; size_t blen; FILE *f; #define XCF_HAVE_BACKUP 1 #define XCF_HAVE_FILE 2 #define XCF_HAVE_TFILE 4 #define XCF_HAVE_ITEMS 8 uint32_t flags = 0; int num_links = 0; if (!xine || !filename) return; /* yes this _is_ relevant. */ blen = xine_realpath (fname, filename, sizeof (fname) - 48, &num_links); if (!blen) return; if (num_links) { xprintf (xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": %s -> %s.\n", filename, fname); } /* When X server shuts down while multiple xine instances run, * a) concurrent writes may trash the file, and/or * b) write may be interrupted. */ this = xine->config; xine_fast_memcpy (bname, fname, blen); memcpy (bname + blen, "~", 2); xine_fast_memcpy (tname, fname, blen); { char *p = tname + blen; *p++ = '.'; xine_uint32_2str (&p, (uintptr_t)getpid ()); *p++ = '.'; xine_uint32_2str (&p, (uintptr_t)this); *p = 0; } /* xprintf(xine, XINE_VERBOSITY_LOG, _("configfile: WARNING: backing up configfile to %s failed\n"), bname); */ xprintf (xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": writing %s.\n", tname); f = fopen (tname, "wb"); if (!f) { int e = errno; xprintf (xine, XINE_VERBOSITY_LOG, LOG_MODULE ": %s: %s (%d).\n", tname, strerror (e), e); xprintf(xine, XINE_VERBOSITY_LOG, _("configfile: WARNING: your configuration will not be saved\n")); return; } else { #define XCS_BUF_SIZE 4096 char buf[XCS_BUF_SIZE], *q, *e = buf + XCS_BUF_SIZE - 28 - 4 * XINE_MAX_INT32_STR; cfg_entry_t *entry; size_t flen = 0; flags |= XCF_HAVE_TFILE; q = buf; memcpy (q, "#\n# xine config file\n#\n.version:", 32); q += 32; xine_uint32_2str (&q, CONFIG_FILE_VERSION); memcpy (q, "\n" "\n" "# Entries which are still set to their default values are commented out.\n" "# Remove the \'#\' at the beginning of the line, if you want to change them.\n" "\n", 151); q += 151; flen += fwrite (buf, 1, q - buf, f); pthread_mutex_lock(&this->config_lock); for (entry = this->first; entry; entry = entry->next) { if (!entry->key[0]) /* deleted key */ continue; lprintf ("saving key '%s'\n", entry->key); q = buf; if (entry->description) { memcpy (q, "# ", 2); q += 2; q += strlcpy (q, entry->description, e - q); if (q >= e) q = e - 1; *q++ = '\n'; } switch (entry->type) { case XINE_CONFIG_TYPE_UNKNOWN: { #if 0 /* discard unclaimed values. * better dont do that because * a) multiple frontends may share the same config file, and * b) we dont always load all plugins for performance. */ #else q += strlcpy (q, entry->key, e - q); if (q >= e) q = e - 1; *q++ = ':'; if (entry->unknown_value) q += strlcpy (q, entry->unknown_value, e - q); if (q >= e) q = e - 1; memcpy (q, "\n\n", 2); q += 2; #endif break; } case XINE_CONFIG_TYPE_RANGE: memcpy (q, "# [ ", 4); q += 3; xine_int32_2str (&q, entry->range_min); memcpy (q, "..", 2); q += 2; xine_int32_2str (&q, entry->range_max); *q++ = ']'; tail_num: memcpy (q, ", default: ", 12); q += 11; xine_int32_2str (&q, entry->num_default); *q++ = '\n'; if (entry->num_value == entry->num_default) *q++ = '#'; q += strlcpy (q, entry->key, e - q); if (q >= e) q = e - 1; *q++ = ':'; xine_int32_2str (&q, entry->num_value); memcpy (q, "\n\n", 2); q += 2; break; case XINE_CONFIG_TYPE_STRING: memcpy (q, "# string, default: ", 20); q += 19; if (entry->str_default) q += strlcpy (q, entry->str_default, e - q); if (q >= e) q = e - 1; *q++ = '\n'; if (!strcmp (entry->str_value, entry->str_default)) *q++ = '#'; q += strlcpy (q, entry->key, e - q); if (q >= e) q = e - 1; *q++ = ':'; if (entry->str_value) q += strlcpy (q, entry->str_value, e - q); if (q >= e) q = e - 1; memcpy (q, "\n\n", 2); q += 2; break; case XINE_CONFIG_TYPE_ENUM: do { char **value; memcpy (q, "# { ", 4); q += 3; value = entry->enum_values; while (*value) { *q++ = ' '; q += strlcpy (q, *value, e - q); if (q >= e) { q = e - 1; break; } *q++ = ' '; value++; } memcpy (q, "}, default: ", 12); q += 12; xine_uint32_2str (&q, entry->num_default); *q++ = '\n'; if ((entry->num_value >= 0) && (entry->num_value < entry->range_max) && entry->enum_values[entry->num_value]) { if (entry->num_value == entry->num_default) *q++ = '#'; q += strlcpy (q, entry->key, e - q); if (q >= e) q = e - 1; *q++ = ':'; q += strlcpy (q, entry->enum_values[entry->num_value], e - q); if (q >= e) q = e - 1; *q++ = '\n'; } } while (0); *q++ = '\n'; break; case XINE_CONFIG_TYPE_NUM: memcpy (q, "# numeric", 9); q += 9; goto tail_num; case XINE_CONFIG_TYPE_BOOL: memcpy (q, "# bool", 6); q += 6; goto tail_num; } flen += fwrite (buf, 1, q - buf, f); flags |= XCF_HAVE_ITEMS; } pthread_mutex_unlock(&this->config_lock); /* paranoia ... */ if (fclose (f)) flags &= ~XCF_HAVE_TFILE; if (!stat (tname, &sbuf)) { if ((off_t)flen != sbuf.st_size) flags &= ~XCF_HAVE_TFILE; } else { flags &= ~XCF_HAVE_TFILE; } if ((flags & (XCF_HAVE_TFILE | XCF_HAVE_ITEMS)) != (XCF_HAVE_TFILE | XCF_HAVE_ITEMS)) { xprintf (xine, XINE_VERBOSITY_LOG, _("configfile: WARNING: writing configuration to %s failed\n"), fname); xprintf (xine, XINE_VERBOSITY_LOG, _("configfile: WARNING: removing possibly broken config file %s\n"), tname); xprintf (xine, XINE_VERBOSITY_LOG, _("configfile: WARNING: you should check the backup file %s\n"), bname); /* writing config failed -> remove file, it might be broken. */ unlink (tname); return; } if (!stat (bname, &sbuf) && S_ISREG (sbuf.st_mode)) flags |= XCF_HAVE_BACKUP; if (!stat (fname, &sbuf) && S_ISREG (sbuf.st_mode)) flags |= XCF_HAVE_FILE; if (flags & XCF_HAVE_FILE) { if (flags & XCF_HAVE_BACKUP) unlink (bname); rename (fname, bname); } rename (tname, fname); } } static void config_dispose (config_values_t *this_gen) { fat_config_values_t *this = (fat_config_values_t *)this_gen; fat_cfg_entry_t *entry, *last; int n; pthread_mutex_lock (&this->config.config_lock); entry = (fat_cfg_entry_t *)this->config.first; lprintf ("dispose\n"); n = 0; while (entry) { last = entry; entry = (fat_cfg_entry_t *)entry->entry.next; last->entry.next = NULL; n += _cfg_cb_clear_report (this->config.xine, &last->entry); _x_freep (&last->entry.key); _x_freep (&last->entry.unknown_value); config_reset_value (last); free (last); } xine_sarray_delete (this->key_index); this->key_index = NULL; pthread_mutex_unlock (&this->config.config_lock); if (n && this->config.xine) { xprintf (this->config.xine, XINE_VERBOSITY_DEBUG, "configfile: unregistered %d orphaned change callbacks.\n", n); } pthread_mutex_destroy (&this->config.config_lock); free (this); } static void config_unregister_cb (config_values_t *this, const char *key) { cfg_entry_t *entry; _x_assert(key); _x_assert(this); entry = config_lookup_entry_safe (this, key); if (entry) { cfg_entry_t *next = entry->next; entry->next = NULL; _cfg_cb_clear (entry); entry->next = next; } pthread_mutex_unlock (&this->config_lock); } static int config_unregister_callbacks (config_values_t *this, const char *key, xine_config_cb_t changed_cb, void *cb_data, size_t cb_data_size) { int n; cfg_entry_t *entry, *next; if (!this) return 0; next = NULL; if (key) { entry = config_lookup_entry_safe (this, key); if (entry) { next = entry->next; entry->next = NULL; } } else { pthread_mutex_lock (&this->config_lock); entry = this->first; } n = _cfg_any_rem (entry, changed_cb, cb_data, cb_data_size); if (next) entry->next = next; pthread_mutex_unlock (&this->config_lock); return n; } void _x_config_unregister_cb_class_d (config_values_t *this, void *callback_data) { _x_assert(this); _x_assert(callback_data); pthread_mutex_lock(&this->config_lock); _cfg_d_rem (this->first, callback_data, 0); pthread_mutex_unlock(&this->config_lock); } void _x_config_unregister_cb_class_p (config_values_t *this, xine_config_cb_t callback) { _x_assert(this); _x_assert(callback); pthread_mutex_lock (&this->config_lock); _cfg_cb_rem (this->first, callback); pthread_mutex_unlock (&this->config_lock); } static void config_set_new_entry_callback (config_values_t *this, xine_config_cb_t new_entry_cb, void* cbdata) { pthread_mutex_lock(&this->config_lock); this->new_entry_cb = new_entry_cb; this->new_entry_cbdata = cbdata; pthread_mutex_unlock(&this->config_lock); } static void config_unset_new_entry_callback (config_values_t *this) { pthread_mutex_lock(&this->config_lock); this->new_entry_cb = NULL; this->new_entry_cbdata = NULL; pthread_mutex_unlock(&this->config_lock); } static void put_int (uint8_t **dest, int value) { int32_t value_int32 = (int32_t)value; #if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) # ifdef WORDS_BIGENDIAN value_int32 = __builtin_bswap32 (value_int32); # endif __builtin_memcpy (*dest, &value_int32, 4); #else (*dest)[0] = value_int32 & 0xFF; (*dest)[1] = (value_int32 >> 8) & 0xFF; (*dest)[2] = (value_int32 >> 16) & 0xFF; (*dest)[3] = (value_int32 >> 24) & 0xFF; #endif *dest += 4; } static void put_string (uint8_t **dest, const char *value, uint32_t value_len) { put_int (dest, value_len); if (value_len > 0) memcpy (*dest, value, value_len); *dest += value_len; } static char* config_get_serialized_entry (config_values_t *this, const char *key) { cfg_entry_t *entry; /* thread safe extension, private to _x_scan_plugins () * (.cur is otherwise unused). */ pthread_mutex_lock (&this->config_lock); if (!key) { entry = this->cur; this->cur = NULL; } else if (this->lookup_entry == config_lookup_entry) { entry = config_lookup_entry_int (this, key); } else { entry = this->lookup_entry (this, key); } if (!entry) { pthread_mutex_unlock (&this->config_lock); return NULL; } { /* now serialize this stuff fields to serialize : int type; int range_min; int range_max; int exp_level; int num_default; int num_value; char *key; char *str_default; char *description; char *help; char **enum_values; */ uint8_t *buf1, *buf2, *q; uint32_t total_len, buf_len; uint32_t key_len = entry->key ? xine_find_byte (entry->key, 0) : 0; uint32_t str_default_len = entry->str_default ? xine_find_byte (entry->str_default, 0) : 0; uint32_t description_len = entry->description ? xine_find_byte (entry->description, 0) : 0; uint32_t help_len = entry->help ? xine_ref_string_len (entry->help) : 0; uint32_t value_len[256]; uint32_t value_count, i; uint32_t has_callbacks = (entry->callback || entry->callback_data) ? (1 << _CFG_BIT_HAS_CALLBACKS) : 0; char **cur_value; /* 6 integers: value (4 bytes) * 4 strings: len (4 bytes) + string (len bytes) * enums: count (4 bytes) + count * (len (4 bytes) + string (len bytes)) */ total_len = 11 * 4 + key_len + str_default_len + description_len + help_len; value_count = 0; cur_value = entry->enum_values; if (cur_value) { while (*cur_value && (value_count < (sizeof (value_len) / sizeof (value_len[0])))) { value_len[value_count] = xine_find_byte (*cur_value, 0); total_len += 4 + value_len[value_count]; value_count++; cur_value++; } } /* Now we have the length needed to serialize the entry and the length of each string */ buf_len = (total_len * 4 + 2) / 3 + 8; buf2 = malloc (buf_len); if (!buf2) { pthread_mutex_unlock(&this->config_lock); return NULL; } buf1 = buf2 + (buf_len - total_len - 4); /* Let's go */ q = buf1; /* the integers */ put_int (&q, entry->type); put_int (&q, entry->range_min); put_int (&q, entry->range_max); put_int (&q, entry->exp_level); put_int (&q, entry->num_default); put_int (&q, entry->num_value); /* the strings */ put_string (&q, entry->key, key_len); put_string (&q, entry->str_default, str_default_len); put_string (&q, entry->description, description_len); put_string (&q, entry->help, help_len); /* the enum stuff */ put_int (&q, value_count + has_callbacks); cur_value = entry->enum_values; for (i = 0; i < value_count; i++) { put_string (&q, *cur_value, value_len[i]); cur_value++; } pthread_mutex_unlock (&this->config_lock); /* and now the output encoding */ /* We're going to encode total_len bytes in base64 */ xine_base64_encode (buf1, (char *)buf2, total_len); return (char *)buf2; } } static char* config_register_serialized_entry (config_values_t *this, const char *value) { /* fields serialized : int type; int range_min; int range_max; int exp_level; int num_default; int num_value; char *key; char *str_default; char *description; char *help; char **enum_values; */ uint8_t buf[2048], *output; if (!value) return NULL; { size_t need = (strlen (value) * 3 + 3) / 4 + 1; output = (need <= sizeof (buf)) ? buf : malloc (need); } if (output) do { char *enum_values[257]; uint32_t enum_len[257]; int type, range_min, range_max, exp_level, num_default, num_value; uint32_t klen, sdlen, dlen, hlen, ylen; char *key, *str_default, *description, *help; void *callback_data; uint8_t *p; uint32_t left, value_count, i; left = xine_base64_decode (value, output); /* we need at least 7 ints and 4 string lengths */ if (left < 11 * 4) break; left -= 11 * 4; p = output; type = (int32_t)_X_LE_32 (p); p += 4; range_min = (int32_t)_X_LE_32 (p); p += 4; range_max = (int32_t)_X_LE_32 (p); p += 4; exp_level = (int32_t)_X_LE_32 (p); p += 4; num_default = (int32_t)_X_LE_32 (p); p += 4; num_value = (int32_t)_X_LE_32 (p); p += 4; #define get_string(s,len) { \ len = _X_LE_32 (p); p[0] = 0; p += 4; \ if (len > left) \ break; \ left -= len; \ s = (char *)p; p += len; \ } get_string (key, klen); get_string (str_default, sdlen); get_string (description, dlen); get_string (help, hlen); value_count = _X_LE_32 (p); p[0] = 0; p += 4; callback_data = (void *)(uintptr_t)(value_count >> _CFG_BIT_HAS_CALLBACKS); value_count &= ~(1 << _CFG_BIT_HAS_CALLBACKS); if (value_count > 256) break; if (left < value_count * 4) break; left -= value_count * 4; for (i = 0; i < value_count; i++) { get_string (enum_values[i], enum_len[i]); } if (i < value_count) break; /* yes we have that byte. */ p[0] = 0; enum_values[value_count] = NULL; #undef get_string if (exp_level == FIND_ONLY) exp_level = 0; #ifdef LOG printf ("config entry deserialization:\n"); printf (" key : %s\n", key); printf (" type : %d\n", type); printf (" exp_level : %d\n", exp_level); printf (" num_default: %d\n", num_default); printf (" num_value : %d\n", num_value); printf (" str_default: %s\n", str_default); printf (" range_min : %d\n", range_min); printf (" range_max : %d\n", range_max); printf (" description: %s\n", description); printf (" help : %s\n", help); printf (" enum : %d values\n", value_count); for (i = 0; i < value_count; i++) printf (" enum[%2d]: %s\n", i, enum_values[i]); printf ("\n"); #endif /* paranoia: user wrappers?? */ ylen = 0; switch (type) { case XINE_CONFIG_TYPE_STRING: switch (num_value) { case 0: if (this->register_string == config_register_string) break; this->register_string (this, key, str_default, description, help, exp_level, NULL, callback_data); ylen = 1; break; default: if (this->register_filename == config_register_filename) break; this->register_filename (this, key, str_default, num_value, description, help, exp_level, NULL, callback_data); ylen = 1; break; } break; case XINE_CONFIG_TYPE_RANGE: if (this->register_range == config_register_range) break; this->register_range (this, key, num_default, range_min, range_max, description, help, exp_level, NULL, callback_data); ylen = 1; break; case XINE_CONFIG_TYPE_ENUM: if (this->register_enum == config_register_enum) break; this->register_enum (this, key, num_default, enum_values, description, help, exp_level, NULL, callback_data); ylen = 1; break; case XINE_CONFIG_TYPE_NUM: if (this->register_num == config_register_num) break; this->register_num (this, key, num_default, description, help, exp_level, NULL, callback_data); ylen = 1; break; case XINE_CONFIG_TYPE_BOOL: if (this->register_bool == config_register_bool) break; this->register_bool (this, key, num_default, description, help, exp_level, NULL, callback_data); ylen = 1; break; default: ylen = 1; } if (!ylen) { /* no, lets shortcut all this (especially the double strlen () for those long strings). */ if (klen) { fat_cfg_entry_t *entry; pthread_mutex_lock (&this->config_lock); entry = config_insert (this, key, exp_level); if (entry && !entry->entry.callback && !entry->entry.callback_data) entry->entry.callback_data = callback_data; if (entry && (entry->entry.type == XINE_CONFIG_TYPE_UNKNOWN)) { char *s; /* new entry */ entry->entry.type = type; entry->entry.exp_level = exp_level; entry->entry.range_min = range_min; entry->entry.range_max = range_max; entry->entry.num_default = num_default; switch (type) { case XINE_CONFIG_TYPE_STRING: entry->entry.num_value = num_value; /* NOTE: some plugins went these to never be NULL. */ if (entry->entry.unknown_value) { entry->entry.str_value = entry->entry.unknown_value; entry->entry.unknown_value = NULL; } else if ((s = malloc (sdlen + 1)) != NULL) { entry->entry.str_value = s; memcpy (s, str_default, sdlen + 1); } if ((s = malloc (sdlen + 1)) != NULL) { entry->entry.str_default = s; memcpy (s, str_default, sdlen + 1); } break; case XINE_CONFIG_TYPE_ENUM: if (entry->entry.unknown_value) { entry->entry.num_value = config_parse_enum (entry->entry.unknown_value, (const char **)enum_values); if (entry->entry.num_value < 0) entry->entry.num_value = num_default; _x_freep (&entry->entry.unknown_value); } else { entry->entry.num_value = num_default; } /* allocate and copy the enum values */ entry->entry.enum_values = str_array_ldup ((const char * const *)enum_values, enum_len, value_count); entry->entry.range_min = 0; entry->entry.range_max = value_count; break; case XINE_CONFIG_TYPE_RANGE: if (entry->entry.unknown_value) { const char *val = entry->entry.unknown_value; entry->entry.num_value = xine_str2int32 (&val); if (entry->entry.num_value != entry->entry.num_default) { if (entry->entry.num_value > entry->entry.range_max) entry->entry.num_value = entry->entry.range_max; else if (entry->entry.num_value < entry->entry.range_min) entry->entry.num_value = entry->entry.range_min; } _x_freep (&entry->entry.unknown_value); } else { entry->entry.num_value = num_default; } break; case XINE_CONFIG_TYPE_NUM: if (entry->entry.unknown_value) { const char *val = entry->entry.unknown_value; entry->entry.num_value = xine_str2int32 (&val); _x_freep (&entry->entry.unknown_value); } else { entry->entry.num_value = num_default; } break; case XINE_CONFIG_TYPE_BOOL: if (entry->entry.unknown_value) { const char *val = entry->entry.unknown_value; entry->entry.num_value = xine_str2int32 (&val); _x_freep (&entry->entry.unknown_value); } else { entry->entry.num_value = num_default; } entry->entry.num_value = entry->entry.num_value ? 1 : 0; break; default: ; } if (dlen && ((s = malloc (dlen + 1)))) { entry->entry.description = s; xine_small_memcpy (s, description, dlen + 1); } if (hlen) entry->entry.help = xine_ref_string_ref (help, hlen); } /* To make xine plugin cache updates work correctly, * notify even if this entry is not entirely new. */ if (entry) config_new_entry (this, &entry->entry); pthread_mutex_unlock (&this->config_lock); } else { if (this->xine) xprintf (this->xine, XINE_VERBOSITY_DEBUG, "config_register_serialized_entry: error: config=%p, key=%s.\n", (void *)this, key ? key : "NULL"); } } str_default = malloc (klen + 1); if (str_default) xine_small_memcpy (str_default, key, klen + 1); if (output != buf) free (output); return str_default; } while (0); /* cleanup */ if (output != buf) free (output); return NULL; } static unsigned int _config_fat_entry_hash (void *a) { fat_cfg_entry_t *d = (fat_cfg_entry_t *)a; const uint8_t *p; unsigned int hash; if (_config_is_fat_entry (d)) { p = (const uint8_t *)d->internal_key; hash = *p; return hash < 15 ? hash : 15; } /* should not happen (user manually added entry) */ /* section name */ p = (const uint8_t *)d->entry.key; while (1) { while (*p > '.') p++; if (!*p || (*p == '.')) break; p++; } hash = config_section_enum ((const uint8_t *)d->entry.key, p - (const uint8_t *)d->entry.key); return hash ? hash : 15; } static int _config_fat_entry_cmp (void *a, void *b) { char buf1[MAX_SORT_KEY + 32], buf2[MAX_SORT_KEY + 32], *fs1, *fs2; fat_cfg_entry_t *d = (fat_cfg_entry_t *)a; fat_cfg_entry_t *e = (fat_cfg_entry_t *)b; int klen; if (_config_is_fat_entry (d)) { fs1 = d->internal_key; } else { fs1 = xine_fast_string_init (buf1, sizeof (buf1)); xine_fast_string_set (fs1, NULL, config_make_sort_key (fs1, d->entry.key, &klen, d->entry.exp_level)); } if (_config_is_fat_entry (e)) { fs2 = e->internal_key; } else { fs2 = xine_fast_string_init (buf2, sizeof (buf2)); xine_fast_string_set (fs2, NULL, config_make_sort_key (fs2, e->entry.key, &klen, e->entry.exp_level)); } (void)klen; return xine_fast_string_cmp (fs1, fs2); } config_values_t *_x_config_init (void) { #ifdef HAVE_IRIXAL volatile /* is this a (old, 2.91.66) irix gcc bug?!? */ #endif fat_config_values_t *this; pthread_mutexattr_t attr; this = calloc (1, sizeof (*this)); if (!this) { fprintf (stderr, "configfile: could not allocate config object\n"); return NULL; } #ifndef HAVE_ZERO_SAFE_MEM this->config.first = NULL; this->config.last = NULL; this->config.current_version = 0; this->config.xine = NULL; #endif /* warning: config_lock is a recursive mutex. it must NOT be * used with neither pthread_cond_wait() or pthread_cond_timedwait() */ pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&this->config.config_lock, &attr); pthread_mutexattr_destroy(&attr); this->config.register_string = config_register_string; this->config.register_filename = config_register_filename; this->config.register_range = config_register_range; this->config.register_enum = config_register_enum; this->config.register_num = config_register_num; this->config.register_bool = config_register_bool; this->config.register_serialized_entry = config_register_serialized_entry; this->config.update_num = config_update_num; this->config.update_string = config_update_string; this->config.parse_enum = config_parse_enum; this->config.lookup_entry = config_lookup_entry; this->config.unregister_callback = config_unregister_cb; this->config.dispose = config_dispose; this->config.set_new_entry_callback = config_set_new_entry_callback; this->config.unset_new_entry_callback = config_unset_new_entry_callback; this->config.get_serialized_entry = config_get_serialized_entry; this->config.unregister_callbacks = config_unregister_callbacks; this->config.lookup_num = config_lookup_num; this->config.lookup_string = config_lookup_string; this->config.free_string = config_free_string; this->key_index = xine_sarray_new (1024, _config_fat_entry_cmp); xine_sarray_set_mode (this->key_index, XINE_SARRAY_MODE_UNIQUE); /* just an optimization attempt :-) */ xine_sarray_set_hash (this->key_index, _config_fat_entry_hash, 16); return &this->config; } int _x_config_change_opt(config_values_t *config, const char *opt) { cfg_entry_t *entry; int handled = 0; char *key, *value; /* If the configuration is missing, return now rather than trying * to dereference it and then check it. */ if ( ! config || ! opt ) return -1; if ((entry = config->lookup_entry(config, "misc.implicit_config")) && entry->type == XINE_CONFIG_TYPE_BOOL) { if (!entry->num_value) /* changing config entries implicitly is denied */ return -1; } else /* someone messed with the config entry */ return -1; if ( *opt == '\0' ) return 0; key = strdup(opt); if ( !key ) return 0; value = strrchr(key, ':'); if ( !value || *value == '\0' ) { free(key); return 0; } *value++ = '\0'; handled = -1; entry = config_lookup_entry_safe (config, key); if (entry) { if (entry->exp_level >= XINE_CONFIG_SECURITY) { if (config->xine) xprintf (config->xine, XINE_VERBOSITY_LOG, _("configfile: entry '%s' mustn't be modified from MRL\n"), key); } else { switch (entry->type) { case XINE_CONFIG_TYPE_STRING: case XINE_CONFIG_TYPE_RANGE: case XINE_CONFIG_TYPE_ENUM: case XINE_CONFIG_TYPE_NUM: case XINE_CONFIG_TYPE_BOOL: case XINE_CONFIG_TYPE_UNKNOWN: config_update_string_e (entry, value); handled = 1; break; default: ; } } } pthread_mutex_unlock (&config->config_lock); free(key); return handled; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/bswap.h����������������������������������������������������������������0000644�0001750�0001750�00000014715�14647725152�015156� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifndef __BSWAP_H__ #define __BSWAP_H__ #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included #endif #define always_inline inline #include "ffmpeg_bswap.h" /* These are the Aligned variants */ #define _X_ABE_16(x) (be2me_16(*(const uint16_t*)(x))) #define _X_ABE_32(x) (be2me_32(*(const uint32_t*)(x))) #define _X_ABE_64(x) (be2me_64(*(const uint64_t*)(x))) #define _X_ALE_16(x) (le2me_16(*(const uint16_t*)(x))) #define _X_ALE_32(x) (le2me_32(*(const uint32_t*)(x))) #define _X_ALE_64(x) (le2me_64(*(const uint64_t*)(x))) #define _X_BE_16(x) (((uint16_t)(((const uint8_t*)(x))[0]) << 8) | \ ((uint16_t)((const uint8_t*)(x))[1])) #define _X_BE_24(x) (((uint32_t)(((const uint8_t*)(x))[0]) << 16) | \ ((uint32_t)(((const uint8_t*)(x))[1]) << 8) | \ ((uint32_t)(((const uint8_t*)(x))[2]))) #define _X_BE_32(x) (((uint32_t)(((const uint8_t*)(x))[0]) << 24) | \ ((uint32_t)(((const uint8_t*)(x))[1]) << 16) | \ ((uint32_t)(((const uint8_t*)(x))[2]) << 8) | \ ((uint32_t)((const uint8_t*)(x))[3])) #define _X_BE_64(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])) #define _X_LE_16(x) (((uint16_t)(((const uint8_t*)(x))[1]) << 8) | \ ((uint16_t)((const uint8_t*)(x))[0])) #define _X_LE_24(x) (((uint32_t)(((const uint8_t*)(x))[2]) << 16) | \ ((uint32_t)(((const uint8_t*)(x))[1]) << 8) | \ ((uint32_t)(((const uint8_t*)(x))[0]))) #define _X_LE_32(x) (((uint32_t)(((const uint8_t*)(x))[3]) << 24) | \ ((uint32_t)(((const uint8_t*)(x))[2]) << 16) | \ ((uint32_t)(((const uint8_t*)(x))[1]) << 8) | \ ((uint32_t)((const uint8_t*)(x))[0])) #define _X_LE_64(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])) /* Tested with gcc 4.4 */ #if defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 3)) || defined(__clang__) # undef _X_BE_24 # undef _X_BE_32 # undef _X_BE_64 # undef _X_LE_24 # undef _X_LE_32 # undef _X_LE_64 # ifdef WORDS_BIGENDIAN # define _X_LE_24(x) ({ int32_t tempi; __builtin_memcpy (&tempi, (x), 3); (uint32_t)(__builtin_bswap32 (tempi)) & 0xffffff; }) # define _X_LE_32(x) ({ int32_t tempi; __builtin_memcpy (&tempi, (x), 4); (uint32_t)(__builtin_bswap32 (tempi)); }) # define _X_LE_64(x) ({ int64_t tempi; __builtin_memcpy (&tempi, (x), 8); (uint64_t)(__builtin_bswap64 (tempi)); }) # define _X_BE_24(x) ({ uint32_t tempi; __builtin_memcpy (&tempi, (x), 3); tempi >> 8; }) # define _X_BE_32(x) ({ uint32_t tempi; __builtin_memcpy (&tempi, (x), 4); tempi; }) # define _X_BE_64(x) ({ uint64_t tempi; __builtin_memcpy (&tempi, (x), 8); tempi; }) # else # define _X_BE_24(x) ({ int32_t tempi; __builtin_memcpy (&tempi, (x), 3); (uint32_t)(__builtin_bswap32 (tempi)) >> 8; }) # define _X_BE_32(x) ({ int32_t tempi; __builtin_memcpy (&tempi, (x), 4); (uint32_t)(__builtin_bswap32 (tempi)); }) # define _X_BE_64(x) ({ int64_t tempi; __builtin_memcpy (&tempi, (x), 8); (uint64_t)(__builtin_bswap64 (tempi)); }) # define _X_LE_24(x) ({ uint32_t tempi; __builtin_memcpy (&tempi, (x), 3); tempi & 0xffffff; }) # define _X_LE_32(x) ({ uint32_t tempi; __builtin_memcpy (&tempi, (x), 4); tempi; }) # define _X_LE_64(x) ({ uint64_t tempi; __builtin_memcpy (&tempi, (x), 8); tempi; }) # endif # if defined(ARCH_X86) /* These machines have true (u)int16_t. */ # undef _X_BE_16 # undef _X_LE_16 # define _X_BE_16(x) ({ \ uint16_t tempi; \ __builtin_memcpy (&tempi, (x), 2); \ __asm__ __volatile__ ( \ "rolw\t$8, %0" \ : "=r" (tempi) \ : "0" (tempi) \ : "cc" \ ); \ tempi; }) # define _X_LE_16(x) ({ uint16_t tempi; __builtin_memcpy (&tempi, (x), 2); tempi; }) # endif #endif #ifdef WORDS_BIGENDIAN #define _X_ME_16(x) _X_BE_16(x) #define _X_ME_32(x) _X_BE_32(x) #define _X_ME_64(x) _X_BE_64(x) #define _X_AME_16(x) _X_ABE_16(x) #define _X_AME_32(x) _X_ABE_32(x) #define _X_AME_64(x) _X_ABE_64(x) #else #define _X_ME_16(x) _X_LE_16(x) #define _X_ME_32(x) _X_LE_32(x) #define _X_ME_64(x) _X_LE_64(x) #define _X_AME_16(x) _X_ALE_16(x) #define _X_AME_32(x) _X_ALE_32(x) #define _X_AME_64(x) _X_ALE_64(x) #endif #define BE_FOURCC( ch0, ch1, ch2, ch3 ) \ ( (uint32_t)(unsigned char)(ch3) | \ ( (uint32_t)(unsigned char)(ch2) << 8 ) | \ ( (uint32_t)(unsigned char)(ch1) << 16 ) | \ ( (uint32_t)(unsigned char)(ch0) << 24 ) ) #define LE_FOURCC( ch0, ch1, ch2, ch3 ) \ ( (uint32_t)(unsigned char)(ch0) | \ ( (uint32_t)(unsigned char)(ch1) << 8 ) | \ ( (uint32_t)(unsigned char)(ch2) << 16 ) | \ ( (uint32_t)(unsigned char)(ch3) << 24 ) ) #ifdef WORDS_BIGENDIAN #define ME_FOURCC BE_FOURCC #else #define ME_FOURCC LE_FOURCC #endif #endif ���������������������������������������������������xine-lib-1.2/src/xine-engine/xine.c�����������������������������������������������������������������0000644�0001750�0001750�00000404053�14647725152�014776� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * top-level xine functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #include <fcntl.h> #include <string.h> #include <stdlib.h> #include <pthread.h> #include <stdarg.h> #include <stdio.h> #include <ctype.h> #include <unistd.h> #if defined (__linux__) || defined (__GLIBC__) #include <endian.h> #elif defined (__FreeBSD__) #include <machine/endian.h> #endif #ifdef HAVE_SETLOCALE #include <locale.h> #endif #include <basedir.h> #define LOG_MODULE "xine" #define LOG_VERBOSE /* #define LOG #define DEBUG */ #define XINE_ENABLE_EXPERIMENTAL_FEATURES #define METRONOM_CLOCK_INTERNAL #define POST_INTERNAL #include <xine/xine_internal.h> #include <xine/plugin_catalog.h> #include <xine/audio_out.h> #include <xine/video_out.h> #include <xine/post.h> #include <xine/demux.h> #include <xine/buffer.h> #include <xine/spu_decoder.h> #include <xine/input_plugin.h> #include <xine/metronom.h> #include <xine/configfile.h> #include <xine/osd.h> #include <xine/spu.h> #include <xine/xineutils.h> #include <xine/compat.h> #ifdef WIN32 # include <fcntl.h> # include <winsock.h> #endif /* WIN32 */ #include "xine_private.h" static const uint8_t tab_tolower[256] = { 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, ' ','!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/', '0','1','2','3','4','5','6','7','8','9',':',';','<','=','>','?', '@','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z','[','\\',']','^','_', '`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z','{','|','}','~',127, 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,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 }; static void mutex_cleanup (void *mutex) { pthread_mutex_unlock ((pthread_mutex_t *) mutex); } void _x_handle_stream_end (xine_stream_t *s, int non_user) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (stream->status == XINE_STATUS_QUIT) return; stream->status = XINE_STATUS_STOP; if (non_user) { /* frontends will not be interested in receiving this event * if they have called xine_stop explicitly, so only send * it if stream playback finished because of stream end reached */ xine_event_t event; stream->finished_naturally = 1; event.data_length = 0; event.type = XINE_EVENT_UI_PLAYBACK_FINISHED; xine_event_send (&stream->s, &event); } } void _x_extra_info_reset( extra_info_t *extra_info ) { memset( extra_info, 0, sizeof(extra_info_t) ); } void _x_extra_info_merge (extra_info_t *dst, const extra_info_t *src) { if (!src->invalid) { if (src->input_normpos) dst->input_normpos = src->input_normpos; if (src->input_time) dst->input_time = src->input_time; if (src->frame_number) dst->frame_number = src->frame_number; if (src->seek_count) dst->seek_count = src->seek_count; if (src->vpts) dst->vpts = src->vpts; if (src->total_time) dst->total_time = src->total_time; } } static void xine_current_extra_info_reset (xine_stream_private_t *stream, int seek_count) { int index = xine_refs_get (&stream->current_extra_info_index); extra_info_t *b = &stream->current_extra_info[(index + 1) & (XINE_NUM_CURR_EXTRA_INFOS - 1)]; b->invalid = 0; b->input_normpos = 0; b->input_time = 0; b->frame_number = 0; b->total_time = 0; b->vpts = 0; b->seek_count = seek_count; xine_refs_add (&stream->current_extra_info_index, 1); } #define _INT_NONZERO(_v) ((unsigned int)((_v) | (-(_v))) >> (8 * sizeof (_v) - 1)) #define _INT64_NONZERO(_v) (unsigned int)((uint64_t)((_v) | (-(_v))) >> (8 * sizeof (_v) - 1)) void xine_current_extra_info_set (xine_stream_private_t *stream, const extra_info_t *info) { if (!info->invalid) { /* read sync data cache. */ int index = xine_refs_get (&stream->current_extra_info_index); extra_info_t *b = &stream->current_extra_info[(index + 1) & (XINE_NUM_CURR_EXTRA_INFOS - 1)]; if (stream->open_seek_count > info->seek_count) { /* ordinary seek / play, base on previous frame. */ const extra_info_t *a[2] = { &stream->current_extra_info[index & (XINE_NUM_CURR_EXTRA_INFOS - 1)], info }; b->input_normpos = a[_INT_NONZERO (a[1]->input_normpos)]->input_normpos; b->input_time = a[_INT_NONZERO (a[1]->input_time)]->input_time; b->frame_number = a[_INT_NONZERO (a[1]->frame_number)]->frame_number; b->seek_count = a[_INT_NONZERO (a[1]->seek_count)]->seek_count; b->total_time = a[_INT_NONZERO (a[1]->total_time)]->total_time; b->vpts = a[_INT64_NONZERO (a[1]->vpts)]->vpts; } else { /* first frame after open, base on zero. */ *b = *info; stream->open_seek_count = ~0u >> 1; } /* write sync data cache. */ xine_refs_add (&stream->current_extra_info_index, 1); } } static int xine_current_seek_count (xine_stream_private_t *stream) { int index = xine_refs_get (&stream->current_extra_info_index); return stream->current_extra_info[index & (XINE_NUM_CURR_EXTRA_INFOS - 1)].seek_count; } static void xine_current_extra_info_get (xine_stream_private_t *stream, extra_info_t *info) { int index = xine_refs_get (&stream->current_extra_info_index); const extra_info_t *a = &stream->current_extra_info[index & (XINE_NUM_CURR_EXTRA_INFOS - 1)]; *info = *a; } #define XINE_TICKET_FLAG_PAUSE (int)0x40000000 typedef struct { xine_ticket_t t; pthread_mutex_t lock; pthread_cond_t issued; pthread_cond_t revoked; xine_rwlock_t port_rewiring_lock; int pause_revoked; int tickets_granted; int irrevocable_tickets; int plain_renewers; int rewirers; int pending_revocations; int atomic_revokers; pthread_t atomic_revoker_thread; struct { int count; pthread_t holder; } *holder_threads; unsigned holder_thread_count; #define XINE_TICKET_MAX_CB 15 xine_ticket_revoke_cb_t *revoke_callbacks[XINE_TICKET_MAX_CB + 1]; void *revoke_cb_data[XINE_TICKET_MAX_CB + 1]; } xine_ticket_private_t; static void ticket_revoke_cb_register (xine_ticket_t *tgen, xine_ticket_revoke_cb_t *cb, void *user_data) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; int i; pthread_mutex_lock (&this->lock); for (i = 0; i < XINE_TICKET_MAX_CB; i++) { if (!this->revoke_callbacks[i]) { this->revoke_callbacks[i] = cb; this->revoke_cb_data[i] = user_data; break; } if ((this->revoke_callbacks[i] == cb) && (this->revoke_cb_data[i] == user_data)) break; } pthread_mutex_unlock (&this->lock); } static void ticket_revoke_cb_unregister (xine_ticket_t *tgen, xine_ticket_revoke_cb_t *cb, void *user_data) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; int f; pthread_mutex_lock (&this->lock); for (f = 0; this->revoke_callbacks[f]; f++) { if ((this->revoke_callbacks[f] == cb) && (this->revoke_cb_data[f] == user_data)) { int l; for (l = f; this->revoke_callbacks[l + 1]; l++) ; if (f < l) { this->revoke_callbacks[f] = this->revoke_callbacks[l]; this->revoke_cb_data[f] = this->revoke_cb_data[l]; } this->revoke_callbacks[l] = NULL; this->revoke_cb_data[l] = NULL; break; } } pthread_mutex_unlock (&this->lock); } static int ticket_acquire_internal (xine_ticket_private_t *this, int irrevocable, int nonblocking) { pthread_t self = pthread_self (); unsigned int wait, i; pthread_mutex_lock (&this->lock); /* find ourselves in user list */ for (i = 0; i < this->holder_thread_count; i++) { if (pthread_equal (this->holder_threads[i].holder, self)) break; } if (i >= this->holder_thread_count) { /* not found */ wait = this->pending_revocations && (this->atomic_revokers ? !pthread_equal (this->atomic_revoker_thread, self) : !irrevocable); if (nonblocking && wait) { /* not available immediately, bail out */ pthread_mutex_unlock (&this->lock); return 0; } /* add */ if (((i & 31) == 31) && (this->holder_threads[i].count == -1000)) { /* enlarge list */ void *new = realloc (this->holder_threads, sizeof (*this->holder_threads) * (i + 33)); if (!new) { pthread_mutex_unlock (&this->lock); return 0; } this->holder_threads = new; this->holder_threads[i + 32].count = -1000; } this->holder_threads[i].count = 1; this->holder_threads[i].holder = self; this->holder_thread_count = i + 1; while (wait) { pthread_cond_wait (&this->issued, &this->lock); wait = this->pending_revocations && (this->atomic_revokers ? !pthread_equal (this->atomic_revoker_thread, self) : !irrevocable); } } else { /* found, we already hold this */ this->holder_threads[i].count++; } this->tickets_granted++; if (irrevocable) this->irrevocable_tickets++; pthread_mutex_unlock (&this->lock); return 1; } static int ticket_acquire_nonblocking(xine_ticket_t *tgen, int irrevocable) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; return ticket_acquire_internal(this, irrevocable, 1); } static void ticket_acquire(xine_ticket_t *tgen, int irrevocable) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; ticket_acquire_internal(this, irrevocable, 0); } static void ticket_release_internal (xine_ticket_private_t *this, int irrevocable) { pthread_t self = pthread_self (); unsigned int i; pthread_mutex_lock (&this->lock); /* find ourselves in user list */ for (i = 0; i < this->holder_thread_count; i++) { if (pthread_equal (this->holder_threads[i].holder, self)) break; } if (i >= this->holder_thread_count) { lprintf ("BUG! Ticket 0x%p released by a thread that never took it! Allowing code to continue\n", (void*)this); _x_assert (0); } else { this->holder_threads[i].count--; if (this->holder_threads[i].count == 0) { this->holder_thread_count--; if (i < this->holder_thread_count) { this->holder_threads[i].count = this->holder_threads[this->holder_thread_count].count; this->holder_threads[i].holder = this->holder_threads[this->holder_thread_count].holder; } } } if ((this->irrevocable_tickets > 0) && irrevocable) this->irrevocable_tickets--; if (this->tickets_granted > 0) this->tickets_granted--; if (this->pending_revocations && (!this->tickets_granted || (this->rewirers && !this->irrevocable_tickets))) pthread_cond_broadcast(&this->revoked); pthread_mutex_unlock(&this->lock); } static void ticket_release_nonblocking (xine_ticket_t *tgen, int irrevocable) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; ticket_release_internal (this, irrevocable); } static void ticket_release (xine_ticket_t *tgen, int irrevocable) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; ticket_release_internal (this, irrevocable); } static void ticket_renew (xine_ticket_t *tgen, int irrevocable) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; unsigned int i; int grants; pthread_t self = pthread_self (); pthread_mutex_lock (&this->lock); #if 0 /* For performance, caller checks ticket_revoked without lock. 0 here is not really a bug. */ _x_assert (this->ticket_revoked); #endif do { /* Never wait for self. This may happen when post plugins call this during their open (). */ if (this->atomic_revokers && pthread_equal (this->atomic_revoker_thread, self)) break; /* Multithreaded decoders may well allocate frames outside the time window of the main * decoding call. Usually, we cannot make those hidden threads acquire and release * tickets properly. Blocking one of them may freeze main decoder with ticket held. * Lets give them special treatment. */ for (i = 0; i < this->holder_thread_count; i++) { if (pthread_equal (this->holder_threads[i].holder, self)) break; } if (i >= this->holder_thread_count) { /* If registered threads are safe: Wait for ticket reissue, * and dont burn cpu in endless retries. * If registered threads are still running around: Fall through. */ while (this->pending_revocations && !this->tickets_granted) pthread_cond_wait (&this->issued, &this->lock); break; } /* If our thread still has saved self grants and calls this, restore them. * Assume later reissue by another thread (engine pause). */ grants = this->holder_threads[i].count; if (grants >= 0x80000) { grants &= 0x7ffff; this->holder_threads[i].count = grants; this->tickets_granted += grants; } /* Lift _all_ our grants, avoid freeze when we have more than 1. */ if (irrevocable & XINE_TICKET_FLAG_REWIRE) { /* allow everything */ this->tickets_granted -= grants; if (!this->tickets_granted) pthread_cond_broadcast (&this->revoked); while (this->pending_revocations && (!this->irrevocable_tickets || !(irrevocable & ~XINE_TICKET_FLAG_REWIRE))) pthread_cond_wait (&this->issued, &this->lock); this->tickets_granted += grants; } else { /* fair wheather (not rewire) mode */ this->plain_renewers++; this->tickets_granted -= grants; if (!this->tickets_granted) pthread_cond_broadcast (&this->revoked); while (this->pending_revocations && (!this->irrevocable_tickets || !irrevocable) && !this->rewirers) pthread_cond_wait (&this->issued, &this->lock); this->tickets_granted += grants; this->plain_renewers--; } } while (0); pthread_mutex_unlock (&this->lock); } /* XINE_TICKET_FLAG_REWIRE implies XINE_TICKET_FLAG_ATOMIC. */ static void ticket_issue (xine_ticket_t *tgen, int flags) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; pthread_t self; unsigned int i; /* better not miss a reissue, and skip that no lock test. */ self = pthread_self (); pthread_mutex_lock (&this->lock); if (flags == XINE_TICKET_FLAG_PAUSE) { if (!this->pause_revoked) { pthread_mutex_unlock (&this->lock); return; } this->pause_revoked = 0; flags = 0; } if (this->pending_revocations > 0) this->pending_revocations--; if ((flags & XINE_TICKET_FLAG_REWIRE) && (this->rewirers > 0)) this->rewirers--; if (flags & (XINE_TICKET_FLAG_REWIRE | XINE_TICKET_FLAG_ATOMIC)) { if (this->atomic_revokers > 0) this->atomic_revokers--; pthread_cond_broadcast (&this->revoked); } { int n = !this->pending_revocations ? 0 : (this->rewirers ? (XINE_TICKET_FLAG_REWIRE | 1) : 1); if (this->t.ticket_revoked != n) { this->t.ticket_revoked = n; pthread_cond_broadcast (&this->issued); } } /* HACK: restore self grants. */ for (i = 0; i < this->holder_thread_count; i++) { if (pthread_equal (this->holder_threads[i].holder, self)) { int n = this->holder_threads[i].count; if (n >= 0x80000) { n -= 0x80000; this->holder_threads[i].count = n; if (n < 0x80000) this->tickets_granted += n; } break; } } pthread_mutex_unlock(&this->lock); if (flags & (XINE_TICKET_FLAG_REWIRE | XINE_TICKET_FLAG_ATOMIC)) xine_rwlock_unlock (&this->port_rewiring_lock); } static void ticket_revoke (xine_ticket_t *tgen, int flags) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; pthread_t self; if (flags == XINE_TICKET_FLAG_PAUSE) { if (this->pause_revoked) return; self = pthread_self (); /* flags & (XINE_TICKET_FLAG_REWIRE | XINE_TICKET_FLAG_ATOMIC) does not happen here. */ pthread_mutex_lock (&this->lock); if (this->pause_revoked) { pthread_mutex_unlock (&this->lock); return; } this->pause_revoked = 1; flags = 0; } else { self = pthread_self (); if (flags & (XINE_TICKET_FLAG_REWIRE | XINE_TICKET_FLAG_ATOMIC)) xine_rwlock_wrlock (&this->port_rewiring_lock); pthread_mutex_lock (&this->lock); } /* HACK: dont freeze on self grants, save them. * Also, nest revokes at bit 19. */ { unsigned int i; for (i = 0; i < this->holder_thread_count; i++) { if (pthread_equal (this->holder_threads[i].holder, self)) { int n = this->holder_threads[i].count; if (n < 0x80000) this->tickets_granted -= n; this->holder_threads[i].count = n + 0x80000; break; } } } /* Set these early so release () / renew () see them. */ this->pending_revocations++; /* No joke - see renew (). */ if (flags & XINE_TICKET_FLAG_REWIRE) { this->rewirers++; if (this->plain_renewers) pthread_cond_broadcast (&this->issued); } /* New public status. */ this->t.ticket_revoked = (this->rewirers ? (XINE_TICKET_FLAG_REWIRE | 1) : 1); do { /* Never wait for self. */ if (this->atomic_revokers && pthread_equal (this->atomic_revoker_thread, self)) { if (flags & (XINE_TICKET_FLAG_REWIRE | XINE_TICKET_FLAG_ATOMIC)) this->atomic_revokers++; break; } /* Need waiting? */ if (this->tickets_granted || (this->rewirers && this->plain_renewers) || this->atomic_revokers) { /* Notify other holders. */ int i, f = (this->rewirers ? XINE_TICKET_FLAG_REWIRE : 0) | (this->atomic_revokers ? XINE_TICKET_FLAG_ATOMIC : 0); for (i = 0; i < XINE_TICKET_MAX_CB; i++) { if (!this->revoke_callbacks[i]) break; this->revoke_callbacks[i] (this->revoke_cb_data[i], f); } /* Wait for them to release/renew. */ do { pthread_cond_wait (&this->revoked, &this->lock); this->t.ticket_revoked = (this->rewirers ? (XINE_TICKET_FLAG_REWIRE | 1) : 1); } while (this->tickets_granted || (this->rewirers && this->plain_renewers) || this->atomic_revokers); } /* Its ours now. */ if (flags & (XINE_TICKET_FLAG_REWIRE | XINE_TICKET_FLAG_ATOMIC)) { this->atomic_revoker_thread = self; this->atomic_revokers++; } } while (0); pthread_mutex_unlock(&this->lock); } static int lock_timeout (pthread_mutex_t *mutex, int ms_timeout) { if (ms_timeout == 0) return (0 == pthread_mutex_trylock (mutex)); if (ms_timeout >= 0) { struct timespec abstime = {0, 0}; xine_gettime (&abstime); abstime.tv_sec += ms_timeout / 1000; abstime.tv_nsec += (ms_timeout % 1000) * 1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } return (0 == pthread_mutex_timedlock (mutex, &abstime)); } pthread_mutex_lock (mutex); return 1; } static int ticket_lock_port_rewiring (xine_ticket_t *tgen, int ms_timeout) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; if (ms_timeout == 0) return (0 == xine_rwlock_tryrdlock (&this->port_rewiring_lock)); if (ms_timeout >= 0) { struct timespec abstime = {0, 0}; xine_gettime (&abstime); abstime.tv_sec += ms_timeout / 1000; abstime.tv_nsec += (ms_timeout % 1000) * 1000000; if (abstime.tv_nsec >= 1000000000) { abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } return (0 == xine_rwlock_timedrdlock (&this->port_rewiring_lock, &abstime)); } xine_rwlock_rdlock (&this->port_rewiring_lock); return 1; } static void ticket_unlock_port_rewiring (xine_ticket_t *tgen) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; xine_rwlock_unlock (&this->port_rewiring_lock); } static void ticket_dispose (xine_ticket_t *tgen) { xine_ticket_private_t *this = (xine_ticket_private_t *)tgen; xine_rwlock_destroy (&this->port_rewiring_lock); pthread_mutex_destroy (&this->lock); pthread_cond_destroy (&this->issued); pthread_cond_destroy (&this->revoked); free (this->holder_threads); free (this); } static xine_ticket_t *XINE_MALLOC ticket_init(void) { xine_ticket_private_t *port_ticket; port_ticket = calloc (1, sizeof (xine_ticket_private_t)); if (!port_ticket) return NULL; #ifndef HAVE_ZERO_SAFE_MEM port_ticket->t.ticket_revoked = 0; port_ticket->pause_revoked = 0; port_ticket->holder_thread_count = 0; port_ticket->tickets_granted = 0; port_ticket->irrevocable_tickets = 0; port_ticket->atomic_revokers = 0; port_ticket->rewirers = 0; port_ticket->plain_renewers = 0; { int i; for (i = 0; i < XINE_TICKET_MAX_CB; i++) { port_ticket->revoke_callbacks[i] = NULL; port_ticket->revoke_cb_data[i] = NULL; } } #endif port_ticket->t.acquire_nonblocking = ticket_acquire_nonblocking; port_ticket->t.acquire = ticket_acquire; port_ticket->t.release_nonblocking = ticket_release_nonblocking; port_ticket->t.release = ticket_release; port_ticket->t.renew = ticket_renew; port_ticket->t.revoke_cb_register = ticket_revoke_cb_register; port_ticket->t.revoke_cb_unregister = ticket_revoke_cb_unregister; port_ticket->t.issue = ticket_issue; port_ticket->t.revoke = ticket_revoke; port_ticket->t.lock_port_rewiring = ticket_lock_port_rewiring; port_ticket->t.unlock_port_rewiring = ticket_unlock_port_rewiring; port_ticket->t.dispose = ticket_dispose; port_ticket->holder_threads = malloc (32 * sizeof (*port_ticket->holder_threads)); if (!port_ticket->holder_threads) { free (port_ticket); return NULL; } port_ticket->holder_threads[31].count = -1000; pthread_mutex_init (&port_ticket->lock, NULL); xine_rwlock_init_default (&port_ticket->port_rewiring_lock); pthread_cond_init (&port_ticket->issued, NULL); pthread_cond_init (&port_ticket->revoked, NULL); return &port_ticket->t; } static void set_speed_internal (xine_stream_private_t *stream, int speed) { xine_private_t *xine = (xine_private_t *)stream->s.xine; int old_speed = xine->x.clock->speed; int mode = 2 * (speed == XINE_SPEED_PAUSE) + (old_speed == XINE_SPEED_PAUSE); if (mode & 1) { if (mode & 2) { /* stay paused */ return; } else { /* switch pause mode */ if (speed == XINE_LIVE_PAUSE_ON) { xine->port_ticket->issue (xine->port_ticket, XINE_TICKET_FLAG_PAUSE); return; } if (speed == XINE_LIVE_PAUSE_OFF) { xine->port_ticket->revoke (xine->port_ticket, XINE_TICKET_FLAG_PAUSE); return; } /* unpause. all decoder and post threads may continue now, if not running already. */ xine->port_ticket->issue (xine->port_ticket, XINE_TICKET_FLAG_PAUSE); } } else { if (mode & 2) { /* pause */ /* get all decoder and post threads in a state where they agree to be blocked */ xine->port_ticket->revoke (xine->port_ticket, XINE_TICKET_FLAG_PAUSE); /* set master clock so audio_out loop can pause in a safe place */ xine->x.clock->set_fine_speed (xine->x.clock, speed); } else { if ((speed == XINE_LIVE_PAUSE_ON) || (speed == XINE_LIVE_PAUSE_OFF)) return; /* plain change */ if (speed == old_speed) return; } } /* see coment on audio_out loop about audio_paused */ if (stream->s.audio_out) { xine->port_ticket->acquire (xine->port_ticket, 1); /* inform audio_out that speed has changed - he knows what to do */ stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_CLOCK_SPEED, speed); xine->port_ticket->release (xine->port_ticket, 1); } if (mode < 2) /* master clock is set after resuming the audio device (audio_out loop may continue) */ xine->x.clock->set_fine_speed (xine->x.clock, speed); } /* SPEED_FLAG_IGNORE_CHANGE must be set in stream->speed_change_flags, when entering this function */ static void stop_internal (xine_stream_private_t *stream) { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "stop_internal (%p).\n", (void *)stream); if (stream->side_streams[0] == stream) stream->demux.start_buffers_sent = 0; stream = stream->side_streams[0]; if ( stream->status == XINE_STATUS_IDLE || stream->status == XINE_STATUS_STOP ) { _x_demux_control_end (&stream->s, 0); lprintf("ignored"); } else { /* make sure we're not in "paused" state */ set_speed_internal (stream, XINE_FINE_SPEED_NORMAL); /* Don't change status if we're quitting */ if (stream->status != XINE_STATUS_QUIT) stream->status = XINE_STATUS_STOP; } /* * stop demux */ { unsigned int u; for (u = 0; u < XINE_NUM_SIDE_STREAMS; u++) { xine_stream_private_t *side = stream->side_streams[u]; if (side && side->demux.plugin && side->demux.thread_created) { lprintf ("stopping demux\n"); _x_demux_stop_thread (&side->s); lprintf ("demux stopped\n"); } } } xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "stop_internal (%p): done.\n", (void *)stream); } /* force engine to run at normal speed. if you are about to grab a ticket, * do wait for the rare case of a set_fine_speed (0) in progress. */ static void lock_run (xine_stream_private_t *stream, int wait) { xine_private_t *xine = (xine_private_t *)stream->s.xine; pthread_mutex_lock (&xine->speed_change_lock); if (xine->speed_change_flags & SPEED_FLAG_CHANGING) { xine->speed_change_flags |= SPEED_FLAG_IGNORE_CHANGE | SPEED_FLAG_WANT_NEW; xine->speed_change_new_speed = XINE_FINE_SPEED_NORMAL; if (wait) { do { pthread_cond_wait (&xine->speed_change_done, &xine->speed_change_lock); } while (xine->speed_change_flags & SPEED_FLAG_CHANGING); } pthread_mutex_unlock (&xine->speed_change_lock); return; } xine->speed_change_flags |= SPEED_FLAG_IGNORE_CHANGE; pthread_mutex_unlock (&xine->speed_change_lock); if (xine->x.clock->speed == XINE_FINE_SPEED_NORMAL) return; xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "set_speed %d.\n", XINE_FINE_SPEED_NORMAL); set_speed_internal (stream, XINE_FINE_SPEED_NORMAL); } static void unlock_run (xine_stream_private_t *stream) { xine_private_t *xine = (xine_private_t *)stream->s.xine; pthread_mutex_lock (&xine->speed_change_lock); xine->speed_change_flags &= ~SPEED_FLAG_IGNORE_CHANGE; pthread_mutex_unlock (&xine->speed_change_lock); } void xine_stop (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s, *m; xine_private_t *xine; if (!stream) return; m = stream->side_streams[0]; xine = (xine_private_t *)m->s.xine; pthread_mutex_lock (&m->frontend_lock); pthread_cleanup_push (mutex_cleanup, (void *) &m->frontend_lock); /* make sure that other threads cannot change the speed, especially pauseing the stream */ lock_run (m, 1); xine->port_ticket->acquire (xine->port_ticket, 1); if (m->s.audio_out) m->s.audio_out->set_property (m->s.audio_out, AO_PROP_DISCARD_BUFFERS, 1); if (m->s.video_out) m->s.video_out->set_property (m->s.video_out, VO_PROP_DISCARD_FRAMES, 1); stop_internal (m); if (m->s.slave && (m->slave_affection & XINE_MASTER_SLAVE_STOP)) xine_stop (m->s.slave); if (m->s.video_out) m->s.video_out->set_property (m->s.video_out, VO_PROP_DISCARD_FRAMES, 0); if (m->s.audio_out) m->s.audio_out->set_property (m->s.audio_out, AO_PROP_DISCARD_BUFFERS, 0); xine->port_ticket->release (xine->port_ticket, 1); unlock_run (m); pthread_cleanup_pop (0); pthread_mutex_unlock (&m->frontend_lock); } static void close_internal (xine_stream_private_t *stream) { xine_stream_private_t *m = stream->side_streams[0]; xine_private_t *xine = (xine_private_t *)m->s.xine; int flush = !m->gapless_switch && !m->finished_naturally; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "close_internal (%p, %s).\n", (void *)stream, flush ? "flush" : "gapless_switch"); if (m->s.slave) { xine_close (m->s.slave); if (m->slave_is_subtitle) { xine_dispose (m->s.slave); m->s.slave = NULL; m->slave_is_subtitle = 0; } } /* make sure that other threads cannot change the speed. * especially pauseing the stream may hold demux waiting for fifo pool or ticket, * and thus freeze stop_internal () -> _x_demux_stop_thread () below. */ lock_run (m, flush); if (flush) { xine->port_ticket->acquire (xine->port_ticket, 1); if (m->s.audio_out) m->s.audio_out->set_property (m->s.audio_out, AO_PROP_DISCARD_BUFFERS, 1); if (m->s.video_out) m->s.video_out->set_property (m->s.video_out, VO_PROP_DISCARD_FRAMES, 1); } stop_internal (stream); if (flush) { if (m->s.video_out) m->s.video_out->set_property (m->s.video_out, VO_PROP_DISCARD_FRAMES, 0); if (m->s.audio_out) m->s.audio_out->set_property (m->s.audio_out, AO_PROP_DISCARD_BUFFERS, 0); xine->port_ticket->release (xine->port_ticket, 1); } unlock_run (m); if (stream == m) { unsigned int u; for (u = 0; u < XINE_NUM_SIDE_STREAMS; u++) { xine_stream_private_t *side = stream->side_streams[u]; if (side) { if (side->demux.plugin) _x_free_demux_plugin (&side->s, &side->demux.plugin); if (side->s.input_plugin) { _x_free_input_plugin (&side->s, side->s.input_plugin); side->s.input_plugin = NULL; } } } } else { if (stream->demux.plugin) _x_free_demux_plugin (&stream->s, &stream->demux.plugin); if (stream->s.input_plugin) { _x_free_input_plugin (&stream->s, stream->s.input_plugin); stream->s.input_plugin = NULL; } } /* reset leading id3v2 tag info */ stream->id3v2_tag_size = -1; /* * reset / free meta info * XINE_STREAM_INFO_MAX is at least 99 but the info arrays are sparsely used. * Save a lot of mutex/free calls. */ if (stream == m) { int i; xine_rwlock_wrlock (&stream->info_lock); for (i = 0; i < XINE_STREAM_INFO_MAX; i++) stream->stream_info[i] = 0; xine_rwlock_unlock (&stream->info_lock); xine_rwlock_wrlock (&stream->meta_lock); for (i = 0; i < XINE_STREAM_INFO_MAX; i++) { if (stream->meta_info_public[i]) { if (stream->meta_info_public[i] != stream->meta_info[i]) free (stream->meta_info_public[i]); stream->meta_info_public[i] = NULL; } if (stream->meta_info[i]) free (stream->meta_info[i]), stream->meta_info[i] = NULL; } xine_rwlock_unlock (&stream->meta_lock); } stream->audio_track_map_entries = 0; stream->spu_track_map_entries = 0; _x_keyframes_set (&stream->s, NULL, 0); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "close_internal (%p): done.\n", (void *)stream); } void xine_close (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s, *m; /* a function that uses pthread_cleanup_push () should not modify its * arguments. it also should not modify a variable that optimizes to * be the same as an arg ("stream"). this avoids a "may be clobbered * by longjmp () or vfork () warning. */ /* phonon bug */ if (!stream) { printf ("xine_close: BUG: stream = NULL.\n"); return; } m = stream->side_streams[0]; pthread_mutex_lock (&m->frontend_lock); pthread_cleanup_push (mutex_cleanup, (void *) &m->frontend_lock); close_internal (m); /* * set status to idle. * not putting this into close_internal because it is also called * by open_internal. */ /* Don't change status if we're quitting */ if (m->status != XINE_STATUS_QUIT) m->status = XINE_STATUS_IDLE; pthread_cleanup_pop (0); pthread_mutex_unlock (&m->frontend_lock); } static int stream_rewire_audio(xine_post_out_t *output, void *data) { xine_stream_private_t *stream = (xine_stream_private_t *)output->data; xine_private_t *xine = (xine_private_t *)stream->s.xine; xine_audio_port_t *new_port = (xine_audio_port_t *)data, *old_port; uint32_t bits, rate; int mode; if (!data) return 0; stream = stream->side_streams[0]; xine->port_ticket->revoke (xine->port_ticket, XINE_TICKET_FLAG_REWIRE); /* just an optimization. Keep engine paused at rewire safe position for subsequent rewires. */ set_speed_internal (stream, XINE_LIVE_PAUSE_OFF); old_port = stream->s.audio_out; _x_post_audio_port_ref (new_port); if (old_port->status (old_port, &stream->s, &bits, &rate, &mode)) { /* register our stream at the new output port */ (new_port->open) (new_port, &stream->s, bits, rate, mode); old_port->close (old_port, &stream->s); } stream->s.audio_out = new_port; _x_post_audio_port_unref (old_port); xine->port_ticket->issue (xine->port_ticket, XINE_TICKET_FLAG_REWIRE); return 1; } static int stream_rewire_video(xine_post_out_t *output, void *data) { xine_stream_private_t *stream = (xine_stream_private_t *)output->data; xine_private_t *xine = (xine_private_t *)stream->s.xine; xine_video_port_t *new_port = (xine_video_port_t *)data, *old_port; int64_t img_duration; int width, height; if (!data) return 0; stream = stream->side_streams[0]; xine->port_ticket->revoke (xine->port_ticket, XINE_TICKET_FLAG_REWIRE); /* just an optimization. Keep engine paused at rewire safe position for subsequent rewires. */ set_speed_internal (stream, XINE_LIVE_PAUSE_OFF); old_port = stream->s.video_out; _x_post_video_port_ref (new_port); if (old_port->status (old_port, &stream->s, &width, &height, &img_duration)) { /* register our stream at the new output port */ (new_port->open) (new_port, &stream->s); old_port->close (old_port, &stream->s); } stream->s.video_out = new_port; _x_post_video_port_unref (old_port); xine->port_ticket->issue (xine->port_ticket, XINE_TICKET_FLAG_REWIRE); return 1; } static void video_decoder_update_disable_flush_at_discontinuity (void *s, xine_cfg_entry_t *entry) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; stream->disable_decoder_flush_at_discontinuity = !!entry->num_value; } static void _xine_dummy_dest (void *object) { (void)object; } static void xine_dispose_internal (xine_stream_private_t *stream); xine_stream_t *xine_stream_new (xine_t *this, xine_audio_port_t *ao, xine_video_port_t *vo) { xine_stream_private_t *stream; pthread_mutexattr_t attr; xprintf (this, XINE_VERBOSITY_DEBUG, "xine_stream_new ().\n"); /* create a new stream object */ stream = calloc (1, sizeof (*stream)); if (!stream) goto err_null; #ifndef HAVE_ZERO_SAFE_MEM /* Do these first, when compiler still knows stream is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ stream->s.spu_decoder_plugin = NULL; stream->audio_decoder_plugin = NULL; stream->early_finish_event = 0; stream->delay_finish_event = 0; stream->gapless_switch = 0; stream->keep_ao_driver_open = 0; stream->video_channel = 0; stream->video_decoder_plugin = NULL; stream->counter.headers_audio = 0; stream->counter.headers_video = 0; stream->counter.finisheds_audio = 0; stream->counter.finisheds_video = 0; stream->counter.demuxers_running = 0; stream->counter.nbc_refs = 0; stream->counter.nbc = NULL; stream->demux.action_pending = 0; stream->demux.input_caps = 0; stream->demux.thread_created = 0; stream->demux.thread_running = 0; stream->demux.start_buffers_sent = 0; stream->err = 0; stream->broadcaster = NULL; stream->index.array = NULL; stream->s.slave = NULL; stream->slave_is_subtitle = 0; stream->query_input_plugins[0] = NULL; stream->query_input_plugins[1] = NULL; stream->seekable = 0; stream->first_frame.seek_count = 0; { int i; for (i = 1; i < XINE_NUM_SIDE_STREAMS; i++) stream->side_streams[i] = NULL; for (i = 0; i < XINE_STREAM_INFO_MAX; i++) { stream->stream_info[i] = 0; stream->meta_info_public[i] = stream->meta_info[i] = NULL; } } #endif /* no need to memset again _x_extra_info_reset (&stream->ei[0]); _x_extra_info_reset (&stream->ei[1]); */ stream->audio_decoder_extra_info = &stream->ei[0].ei; stream->video_decoder_extra_info = &stream->ei[1].ei; stream->video_decoder_ei_index = 0; stream->side_streams[0] = stream; stream->id_flag = 1 << 0; stream->s.xine = this; stream->status = XINE_STATUS_IDLE; stream->id3v2_tag_size = -1; stream->video_source.name = "video source"; stream->video_source.type = XINE_POST_DATA_VIDEO; stream->video_source.data = &stream->s; stream->video_source.rewire = stream_rewire_video; stream->audio_source.name = "audio source"; stream->audio_source.type = XINE_POST_DATA_AUDIO; stream->audio_source.data = &stream->s; stream->audio_source.rewire = stream_rewire_audio; stream->demux.max_seek_bufs = 0xffffffff; stream->s.spu_decoder_streamtype = -1; stream->s.audio_out = ao; stream->audio_channel_user = -1; stream->s.audio_channel_auto = -1; stream->audio_decoder_streamtype = -1; stream->s.spu_channel_auto = -1; stream->s.spu_channel_letterbox = -1; stream->spu_channel_pan_scan = -1; stream->s.spu_channel_user = -1; stream->s.spu_channel = -1; /* Do not flush output when opening/closing yet unused streams (eg subtitle). */ stream->finished_naturally = 1; stream->s.video_out = vo; stream->s.video_driver = vo ? vo->driver : NULL; stream->video_decoder_streamtype = -1; /* initial master/slave */ stream->s.master = &stream->s; /* event queues */ stream->event.queues = xine_list_new (); if (!stream->event.queues) goto err_free; /* init mutexes and conditions */ xine_refs_init (&stream->current_extra_info_index, _xine_dummy_dest, stream); xine_rwlock_init_default (&stream->info_lock); xine_rwlock_init_default (&stream->meta_lock); pthread_mutex_init (&stream->demux.lock, NULL); pthread_mutex_init (&stream->demux.action_lock, NULL); pthread_mutex_init (&stream->demux.pair, NULL); pthread_cond_init (&stream->demux.resume, NULL); pthread_mutex_init (&stream->event.lock, NULL); pthread_mutex_init (&stream->counter.lock, NULL); pthread_cond_init (&stream->counter.changed, NULL); pthread_mutex_init (&stream->first_frame.lock, NULL); pthread_cond_init (&stream->first_frame.reached, NULL); pthread_mutex_init (&stream->index.lock, NULL); /* warning: frontend_lock is a recursive mutex. it must NOT be * used with neither pthread_cond_wait() or pthread_cond_timedwait() */ pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&stream->frontend_lock, &attr); pthread_mutexattr_destroy(&attr); pthread_mutex_lock (&this->streams_lock); /* some user config */ stream->disable_decoder_flush_at_discontinuity = this->config->register_bool (this->config, "engine.decoder.disable_flush_at_discontinuity", 0, _("disable decoder flush at discontinuity"), _("Video decoder is flushed at timeline jumps.\n" "Turning this off fixes occasional image distortion with DVB (TV).\n" "But it may also add some issues with DVD still images.\n"), 20, video_decoder_update_disable_flush_at_discontinuity, stream); /* create a metronom */ stream->s.metronom = _x_metronom_init ( (vo != NULL), (ao != NULL), this); if (!stream->s.metronom) goto err_mutex; /* alloc fifos, init and start decoder threads */ if (!_x_video_decoder_init (&stream->s)) goto err_metronom; if (!_x_audio_decoder_init (&stream->s)) goto err_video; /* osd */ if (vo) { _x_spu_misc_init (this); stream->s.osd_renderer = _x_osd_renderer_init (&stream->s); } else stream->s.osd_renderer = NULL; /* create a reference counter */ xine_refs_init (&stream->refs, (void (*)(void *))xine_dispose_internal, &stream->s); /* register stream */ xine_list_push_back (this->streams, &stream->s); pthread_mutex_unlock (&this->streams_lock); xprintf (this, XINE_VERBOSITY_DEBUG, "xine_stream_new () = %p.\n", (void *)stream); return &stream->s; /* err_audio: */ /* _x_audio_decoder_shutdown (&stream->s); */ err_video: _x_video_decoder_shutdown (&stream->s); err_metronom: stream->s.metronom->exit (stream->s.metronom); err_mutex: pthread_mutex_unlock (&this->streams_lock); pthread_mutex_destroy (&stream->frontend_lock); pthread_mutex_destroy (&stream->index.lock); pthread_cond_destroy (&stream->first_frame.reached); pthread_mutex_destroy (&stream->first_frame.lock); pthread_cond_destroy (&stream->counter.changed); pthread_mutex_destroy (&stream->counter.lock); pthread_mutex_destroy (&stream->event.lock); pthread_cond_destroy (&stream->demux.resume); pthread_mutex_destroy (&stream->demux.pair); pthread_mutex_destroy (&stream->demux.action_lock); pthread_mutex_destroy (&stream->demux.lock); xine_rwlock_destroy (&stream->meta_lock); xine_rwlock_destroy (&stream->info_lock); xine_refs_sub (&stream->current_extra_info_index, xine_refs_get (&stream->current_extra_info_index)); xine_list_delete (stream->event.queues); err_free: free (stream); err_null: xprintf (this, XINE_VERBOSITY_DEBUG, "xine_stream_new () failed.\n"); return NULL; } static void xine_side_dispose_internal (xine_stream_private_t *stream) { xine_t *xine = stream->s.xine; lprintf ("stream: %p\n", (void*)stream); xine->config->unregister_callbacks (xine->config, NULL, NULL, stream, sizeof (*stream)); { xine_stream_private_t *m = stream->side_streams[0]; unsigned int u; xine_rwlock_wrlock (&m->info_lock); for (u = 1; u < XINE_NUM_SIDE_STREAMS; u++) { if (m->side_streams[u] == stream) { m->side_streams[u] = NULL; break; } } xine_rwlock_unlock (&m->info_lock); if (u < XINE_NUM_SIDE_STREAMS) xine_refs_sub (&m->refs, 1); } /* these are not used in side streams. xine_refs_sub (&stream->current_extra_info_index, xine_refs_get (&stream->current_extra_info_index)); pthread_mutex_destroy (&stream->frontend_lock); pthread_mutex_destroy (&stream->index.lock); pthread_mutex_destroy (&stream->demux.pair_mutex); pthread_mutex_destroy (&stream->event.lock); pthread_mutex_destroy (&stream->counter.lock); pthread_mutex_destroy (&stream->first_frame.lock); pthread_cond_destroy (&stream->first_frame.reached); pthread_cond_destroy (&stream->counter.changed); xine_rwlock_destroy (&stream->meta_lock); xine_rwlock_destroy (&stream->info_lock); */ pthread_cond_destroy (&stream->demux.resume); pthread_mutex_destroy (&stream->demux.action_lock); pthread_mutex_destroy (&stream->demux.lock); free (stream->index.array); free (stream); } xine_stream_t *xine_get_side_stream (xine_stream_t *master, int index) { xine_stream_private_t *m = (xine_stream_private_t *)master, *s; if (!m || (index < 0) || (index >= XINE_NUM_SIDE_STREAMS)) return NULL; /* no sub-sides, please. */ m = m->side_streams[0]; xine_rwlock_rdlock (&m->info_lock); s = m->side_streams[index]; xine_rwlock_unlock (&m->info_lock); if (s) return &s->s; xprintf (m->s.xine, XINE_VERBOSITY_DEBUG, "xine_side_stream_new (%p, %d).\n", (void *)m, index); /* create a new stream object */ s = calloc (1, sizeof (*s)); if (!s) return NULL; #ifndef HAVE_ZERO_SAFE_MEM s->s.spu_decoder_plugin = NULL; s->audio_decoder_plugin = NULL; s->audio_track_map_entries = 0; s->audio_type = 0; s->early_finish_event = 0; s->delay_finish_event = 0; s->gapless_switch = 0; s->keep_ao_driver_open = 0; s->video_channel = 0; s->video_decoder_plugin = NULL; s->spu_track_map_entries = 0; s->counter.headers_audio = 0; s->counter.headers_video = 0; s->counter.finisheds_audio = 0; s->counter.finisheds_video = 0; s->demux.action_pending = 0; s->demux.input_caps = 0; s->demux.thread_created = 0; s->demux.thread_running = 0; s->err = 0; s->broadcaster = NULL; s->index.array = NULL; s->s.slave = NULL; s->slave_is_subtitle = 0; s->query_input_plugins[0] = NULL; s->query_input_plugins[1] = NULL; s->seekable = 0; { int i; for (i = 1; i < XINE_NUM_SIDE_STREAMS; i++) s->side_streams[i] = NULL; for (i = 0; i < XINE_STREAM_INFO_MAX; i++) { s->stream_info[i] = 0; s->meta_info_public[i] = s->meta_info[i] = NULL; } } #endif /* no need to memset again _x_extra_info_reset (&stream->ei[0]); _x_extra_info_reset (&stream->ei[1]); */ /* create a reference counter */ xine_refs_init (&s->refs, (void (*)(void *))xine_side_dispose_internal, &s->s); s->audio_decoder_extra_info = m->audio_decoder_extra_info; s->video_decoder_extra_info = m->video_decoder_extra_info; s->side_streams[0] = m; s->id_flag = 1 << index; s->s.xine = m->s.xine; s->status = XINE_STATUS_IDLE; s->id3v2_tag_size = -1; s->video_source.name = "video source"; s->video_source.type = XINE_POST_DATA_VIDEO; s->video_source.data = &m->s; s->video_source.rewire = stream_rewire_video; s->audio_source.name = "audio source"; s->audio_source.type = XINE_POST_DATA_AUDIO; s->audio_source.data = &m->s; s->audio_source.rewire = stream_rewire_audio; s->s.spu_decoder_streamtype = -1; s->s.audio_out = m->s.audio_out; s->audio_channel_user = -1; s->s.audio_channel_auto = -1; s->audio_decoder_streamtype = -1; s->s.spu_channel_auto = -1; s->s.spu_channel_letterbox = -1; s->spu_channel_pan_scan = -1; s->s.spu_channel_user = -1; s->s.spu_channel = -1; /* Do not flush output when opening/closing yet unused streams (eg subtitle). */ s->finished_naturally = 1; s->s.video_out = m->s.video_out; s->s.video_driver = m->s.video_driver; s->video_decoder_streamtype = -1; /* initial master/slave */ s->s.master = &s->s; s->event.queues = m->event.queues; /* these are not used in side streams. { pthread_mutexattr_t attr; pthread_mutexattr_init (&attr); pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&s->frontend_lock, &attr); pthread_mutexattr_destroy (&attr); } xine_refs_init (&stream->current_extra_info_index, _xine_dummy_dest, stream); pthread_mutex_init (&s->demux.pair, NULL); pthread_mutex_init (&s->index.lock, NULL); pthread_mutex_init (&s->event.lock, NULL); pthread_mutex_init (&s->counter.lock, NULL); pthread_mutex_init (&s->first_frame.lock, NULL); pthread_cond_init (&s->counter.changed, NULL); pthread_cond_init (&s->first_frame.reached, NULL); xine_rwlock_init_default (&s->info_lock); xine_rwlock_init_default (&s->meta_lock); */ /* init mutexes and conditions */ pthread_mutex_init (&s->demux.lock, NULL); pthread_mutex_init (&s->demux.action_lock, NULL); pthread_cond_init (&s->demux.resume, NULL); /* some user config */ s->disable_decoder_flush_at_discontinuity = m->disable_decoder_flush_at_discontinuity; s->s.metronom = m->s.metronom; /* this will just link to master */ s->s.video_fifo = m->s.video_fifo; s->s.audio_fifo = m->s.audio_fifo; /* osd */ s->s.osd_renderer = m->s.osd_renderer; /* register stream */ xine_refs_add (&m->refs, 1); xine_rwlock_wrlock (&m->info_lock); m->side_streams[index] = s; xine_rwlock_unlock (&m->info_lock); xprintf (m->s.xine, XINE_VERBOSITY_DEBUG, "xine_side_stream_new (%p, %d) = %p.\n", (void *)m, index, (void *)s); return &s->s; } void _x_mrl_unescape (char *mrl) { static const uint8_t tab_unhex[256] = { #define nn 128 nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,nn,nn,nn,nn,nn,nn, nn,10,11,12,13,14,15,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,10,11,12,13,14,15,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn, nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn,nn }; const uint8_t *p = (const uint8_t *)mrl; uint8_t *q; /* dont touch until first %xx */ while (*p) { if (*p == '%') break; p++; } if (!*p) return; /* now really unescape */ /* q = (uint8_t *)p ?? */ q = (uint8_t *)mrl + (p - (const uint8_t *)mrl); while (1) { uint8_t z = *p++; if (z == '%') { uint8_t h = tab_unhex[*p]; if (!(h & nn)) { z = h; p++; h = tab_unhex[*p]; if (!(h & nn)) { z = (z << 4) | h; p++; } } else if (*p == '%') { p++; } } *q++ = z; if (!z) break; } #undef nn } char *_x_mrl_remove_auth(const char *mrl_in) { char *mrl = strdup(mrl_in); char *auth, *p, *at, *host_end; /* parse protocol */ if (!(p = strchr(mrl, ':'))) { /* no protocol means plain filename */ return mrl; } p++; /* skip ':' */ if (*p == '/') p++; if (*p == '/') p++; /* authorization (user[:pass]@hostname) */ auth = p; host_end = strchr(p, '/'); while ((at = strchr(p, '@')) && at < host_end) { p = at + 1; /* skip '@' */ } if (p != auth) { while (p[-1]) { *auth++ = *p++; } } return mrl; } /* 0x01 (end), 0x02 (alpha), 0x04 (alnum - + .), 0x08 (:), 0x10 (;), 0x20 (#) */ static const uint8_t tab_parse[256] = { 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,32, 0, 0, 0, 0, 0, 0, 0, 4, 0, 4, 4, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8,16, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; typedef enum { _X_ARG_CONFIG = 0, _X_ARG_demux, _X_ARG_save, _X_ARG_lastdemuxprobe, _X_ARG_novideo, _X_ARG_noaudio, _X_ARG_nospu, _X_ARG_nocache, _X_ARG_volume, _X_ARG_compression, _X_ARG_subtitle, _X_ARG_rewind, _X_ARG_LAST } _xine_arg_type_t; typedef struct { _xine_arg_type_t type; uint8_t *key, *value; } _xine_arg_t; typedef struct { _xine_arg_t *args; uint32_t used, have; uint32_t known[_X_ARG_LAST]; } _xine_args_t; static const struct { _xine_arg_type_t type; const char *name; } _xine_arg_keys[] = { /* sort please */ {_X_ARG_compression, "compression"}, {_X_ARG_demux, "demux"}, {_X_ARG_lastdemuxprobe, "lastdemuxprobe"}, {_X_ARG_noaudio, "noaudio"}, {_X_ARG_nocache, "nocache"}, {_X_ARG_nospu, "nospu"}, {_X_ARG_novideo, "novideo"}, {_X_ARG_rewind, "rewind"}, {_X_ARG_save, "save"}, {_X_ARG_subtitle, "subtitle"}, {_X_ARG_volume, "volume"} }; static void _xine_parse_args (_xine_args_t *args, uint8_t *s) { args->args = NULL; args->used = 0; args->have = 0; { uint32_t l; for (l = 0; l < sizeof (args->known) / sizeof (args->known[0]); l++) args->known[l] = ~0u; } if (s && s[0]) { args->used = 0; args->have = 32; args->args = malloc (args->have * sizeof (args->args[0])); if (!args->args) return; /* Turn "WhatAGreat:Bullshit[;]" into lowkey="whatagreat" key="WhatAGreat" value="Bullshit". */ while (*s) { _xine_arg_t *arg; uint8_t *p; uint32_t n; while (*s == ';') s++; if (args->used >= args->have) { arg = realloc (args->args, (args->have + 32) * sizeof (*arg)); if (!arg) return; args->args = arg; args->have += 32; } arg = args->args + args->used; arg->type = _X_ARG_CONFIG; arg->key = p = s; arg->value = NULL; while (!(tab_parse[*s] & 0x19)) s++; n = s - p; if ((n > 0) && (n < 80)) { uint8_t lowkey[80], *q = lowkey; uint32_t b, m, e; s = p; while (n--) *q++ = tab_tolower[*s++]; *q = 0; b = 0; e = sizeof (_xine_arg_keys) / sizeof (_xine_arg_keys[0]); do { int d; m = (b + e) >> 1; d = strcmp ((const char *)lowkey, (const char *)_xine_arg_keys[m].name); if (d < 0) { e = m; } else if (d > 0) { b = m + 1; } else { arg->type = _xine_arg_keys[m].type; args->known[arg->type] = args->used; break; } } while (b != e); } if (*s == ':') { *s++ = 0; arg->value = s; while (!(tab_parse[*s] & 0x11)) s++; } if (!*s) { if (*p) /* skip empty keys */ args->used += 1; break; } *s++ = 0; if (*p) /* skip empty keys */ args->used += 1; } } } static void _xine_free_args (_xine_args_t *args) { _x_freep (&args->args); args->used = 0; args->have = 0; } /* aka "does path have a protocol prefix" */ static inline int _x_path_looks_like_mrl (const char *path) { const uint8_t *p = (const uint8_t *)path; if (!(tab_parse[*p++] & 0x02)) return 0; while (tab_parse[*p++] & 0x04) ; return (p[-1] == ':') && (p[0] == '/'); } static int _xine_str2secs (const uint8_t *s) { uint32_t v = 0, minus = 0; if (!s) return 0; while (*s == '-') minus ^= 1, s++; while (*s == '+') s++; while (1) { uint32_t part = 0; uint8_t z; while ((z = *s ^ '0') < 10u) part = part * 10u + z, s++; v += part; if (*s != ':') break; s++; v *= 60; } return minus ? -(int)v : (int)v; } static int open_internal (xine_stream_private_t *stream, const char *mrl, input_plugin_t *input) { _xine_args_t _args; uint8_t *buf, *name, *args; int no_cache = 0; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "open_internal (%p, %s).\n", (void *)stream, mrl ? mrl : "NULL"); if (!mrl) { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("xine: error while parsing mrl\n")); stream->err = XINE_ERROR_MALFORMED_MRL; if (stream->status != XINE_STATUS_IDLE) stream->status = XINE_STATUS_STOP; return 0; } lprintf ("opening MRL '%s'...\n", mrl); /* * stop engine if necessary */ close_internal (stream); lprintf ("engine should be stopped now\n"); /* * look for a stream_setup in MRL and try finding an input plugin */ buf = malloc (32 + strlen (mrl) + 32); if (!buf) return 0; name = buf + 32; args = NULL; { const uint8_t *p = (const uint8_t *)mrl; uint8_t *prot = NULL, *q = name, z; /* test protocol prefix */ if (tab_parse[*p] & 0x02) { while (tab_parse[z = *p] & 0x04) p++, *q++ = z; if ((q > name) && (z == ':') && (p[1] == '/')) prot = name; } if (prot) { /* split off args at first hash */ while (!(tab_parse[z = *p] & 0x21)) p++, *q++ = z; *q = 0; if (z == '#') { p++; args = ++q; while ((*q++ = *p++) != 0) ; } } else { /* raw filename, may contain any number of hashes */ while (1) { struct stat s; while (!(tab_parse[z = *p] & 0x21)) p++, *q++ = z; *q = 0; /* no need to stat when no hashes found */ if (!args && !z) break; if (!stat ((const char *)name, &s)) { args = NULL; /* no general break yet, beware "/foo/#bar.flv" */ } if (!z) break; p++, *q++ = z; args = q; } if (args) args[-1] = 0; } } _xine_parse_args (&_args, args); if (!input) { /* * find an input plugin */ stream->s.input_plugin = _x_find_input_plugin (&stream->s, (const char *)name); } else { stream->s.input_plugin = input; } { if (stream->s.input_plugin) { int res; input_class_t *input_class = stream->s.input_plugin->input_class; xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: found input plugin : %s\n"), dgettext(input_class->text_domain ? input_class->text_domain : XINE_TEXTDOMAIN, input_class->description)); if (stream->s.input_plugin->input_class->eject_media) stream->eject_class = stream->s.input_plugin->input_class; _x_meta_info_set_utf8 (&stream->s, XINE_META_INFO_INPUT_PLUGIN, stream->s.input_plugin->input_class->identifier); if (_args.known[_X_ARG_rewind] != ~0u) { int secs = _xine_str2secs (_args.args[_args.known[_X_ARG_rewind]].value); if (secs < 0) { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, "xine: cant rewind %d seconds into the future, ignoring.\n", -secs); } else { stream->s.input_plugin->get_optional_data (stream->s.input_plugin, &secs, INPUT_OPTIONAL_DATA_REWIND); } } res = (stream->s.input_plugin->open) (stream->s.input_plugin); switch(res) { case 1: /* Open successfull */ break; case -1: /* Open unsuccessfull, but correct plugin */ stream->err = XINE_ERROR_INPUT_FAILED; _x_flush_events_queues (&stream->s); free (buf); return 0; default: xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: input plugin cannot open MRL [%s]\n"),mrl); _x_free_input_plugin (&stream->s, stream->s.input_plugin); stream->s.input_plugin = NULL; stream->err = XINE_ERROR_INPUT_FAILED; } } } if (!stream->s.input_plugin) { xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: cannot find input plugin for MRL [%s]\n"),mrl); stream->err = XINE_ERROR_NO_INPUT_PLUGIN; _x_flush_events_queues (&stream->s); free (buf); return 0; } if (args) { uint32_t u; for (u = 0; u < _args.used; u++) { char *key, *value; _xine_arg_type_t type; key = (char *)_args.args[u].key; value = (char *)_args.args[u].value; type = _args.args[u].type; switch (type) { case _X_ARG_demux: if (value) { /* demuxer specified by name */ _x_mrl_unescape (value); if (!(stream->demux.plugin = _x_find_demux_plugin_by_name (&stream->s, value, stream->s.input_plugin))) { xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: specified demuxer %s failed to start\n"), value); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; stream->status = XINE_STATUS_IDLE; _xine_free_args (&_args); free (buf); return 0; } _x_meta_info_set_utf8 (&stream->s, XINE_META_INFO_SYSTEMLAYER, stream->demux.plugin->demux_class->identifier); key = NULL; } break; case _X_ARG_save: if (value) { /* filename to save */ input_plugin_t *input_saver; _x_mrl_unescape (value); xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: join rip input plugin\n")); input_saver = _x_rip_plugin_get_instance (&stream->s, value); if (input_saver) { stream->s.input_plugin = input_saver; } else { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("xine: error opening rip input plugin instance\n")); stream->err = XINE_ERROR_MALFORMED_MRL; stream->status = XINE_STATUS_IDLE; _xine_free_args (&_args); free (buf); return 0; } key = NULL; } break; case _X_ARG_lastdemuxprobe: if (value) { /* all demuxers will be probed before the specified one */ _x_mrl_unescape (value); if (!(stream->demux.plugin = _x_find_demux_plugin_last_probe (&stream->s, value, stream->s.input_plugin))) { xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: last_probed demuxer %s failed to start\n"), value); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; stream->status = XINE_STATUS_IDLE; _xine_free_args (&_args); free (buf); return 0; } lprintf ("demux and input plugin found\n"); _x_meta_info_set_utf8 (&stream->s, XINE_META_INFO_SYSTEMLAYER, stream->demux.plugin->demux_class->identifier); key = NULL; } break; case _X_ARG_novideo: _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_VIDEO, 1); xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("ignoring video\n")); key = NULL; break; case _X_ARG_noaudio: _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_AUDIO, 1); xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("ignoring audio\n")); key = NULL; break; case _X_ARG_nospu: _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_SPU, 1); xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("ignoring subpicture\n")); key = NULL; break; case _X_ARG_nocache: no_cache = 1; xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("input cache plugin disabled\n")); key = NULL; break; case _X_ARG_volume: if (value) { _x_mrl_unescape (value); xine_set_param (&stream->s, XINE_PARAM_AUDIO_VOLUME, atoi (value)); key = NULL; } break; case _X_ARG_compression: if (value) { _x_mrl_unescape (value); xine_set_param (&stream->s, XINE_PARAM_AUDIO_COMPR_LEVEL, atoi (value)); key = NULL; } break; case _X_ARG_subtitle: if (value) { /* unescape for xine_open() if the MRL looks like a raw pathname */ if (!_x_path_looks_like_mrl (value)) _x_mrl_unescape (value); stream->s.slave = xine_stream_new (stream->s.xine, NULL, stream->s.video_out); stream->slave_affection = XINE_MASTER_SLAVE_PLAY | XINE_MASTER_SLAVE_STOP; if (xine_open (stream->s.slave, value)) { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("subtitle mrl opened '%s'\n"), value); stream->s.slave->master = &stream->s; stream->slave_is_subtitle = 1; } else { xprintf (stream->s.xine, XINE_VERBOSITY_LOG, _("xine: error opening subtitle mrl\n")); xine_dispose (stream->s.slave); stream->s.slave = NULL; } key = NULL; } break; case _X_ARG_CONFIG: if (value) { /* when we got here, the stream setup parameter must be a config entry */ int retval; value[-1] = ':'; _x_mrl_unescape (key); retval = _x_config_change_opt (stream->s.xine->config, key); if (retval <= 0) { value[-1] = 0; if (retval == 0) { /* the option not found */ xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: unknown config option \"%s\", ignoring.\n"), key); } else { /* not permitted to change from MRL */ xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: changing option '%s' from MRL isn't permitted\n"), key); } } key = NULL; } break; default: key = NULL; } if (key) xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: no value for \"%s\", ignoring.\n"), key); } } _xine_free_args (&_args); free (buf); /* Nasty xine-ui issue: * 1. User pauses playback, then opens a playlist. * 2. Xine-ui grabs a separate stream tied to our "none" output plugins. * 3. Xine-ui tries to open every playlist item in turn in order to query some info like duration. * We dont discuss the performance and security implications thereof here. * But we do find that any such open attempt will freeze inside _x_demux_control_headers_done () * below because the engine is still paused. * Workaround: * If fifo's are (nearly) empty, try that live pause hack. * If not, unpause for real. */ if (_x_get_fine_speed (&stream->s) == XINE_SPEED_PAUSE) { if (stream->s.audio_fifo && (stream->s.audio_fifo->fifo_size < 10) && stream->s.video_fifo && (stream->s.video_fifo->fifo_size < 10)) { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "xine_open: switching to live pause mode to avoid freeze.\n"); set_speed_internal (stream->side_streams[0], XINE_LIVE_PAUSE_ON); } else { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "xine_open: unpauseing to avoid freeze.\n"); set_speed_internal (stream->side_streams[0], XINE_FINE_SPEED_NORMAL); } } no_cache = no_cache || (stream->s.input_plugin->get_capabilities (stream->s.input_plugin) & INPUT_CAP_NO_CACHE); if( !no_cache ) { /* enable buffered input plugin (request optimizer) */ input_plugin_t *cache_plugin = _x_cache_plugin_get_instance (&stream->s); if (cache_plugin) stream->s.input_plugin = cache_plugin; } /* Let the plugin request a specific demuxer (if the user hasn't). * This overrides find-by-content & find-by-extension. */ if (!stream->demux.plugin) { char *default_demux = NULL; stream->s.input_plugin->get_optional_data (stream->s.input_plugin, &default_demux, INPUT_OPTIONAL_DATA_DEMUXER); if (default_demux) { stream->demux.plugin = _x_find_demux_plugin_by_name (&stream->s, default_demux, stream->s.input_plugin); if (stream->demux.plugin) { lprintf ("demux and input plugin found\n"); _x_meta_info_set_utf8 (&stream->s, XINE_META_INFO_SYSTEMLAYER, stream->demux.plugin->demux_class->identifier); } else xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: couldn't load plugin-specified demux %s for >%s<\n"), default_demux, mrl); } } if (!stream->demux.plugin) { /* * find a demux plugin */ if (!(stream->demux.plugin = _x_find_demux_plugin (&stream->s, stream->s.input_plugin))) { xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: couldn't find demux for >%s<\n"), mrl); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; stream->status = XINE_STATUS_IDLE; /* force the engine to unregister fifo callbacks */ _x_demux_control_nop (&stream->s, BUF_FLAG_END_STREAM); return 0; } lprintf ("demux and input plugin found\n"); _x_meta_info_set_utf8 (&stream->s, XINE_META_INFO_SYSTEMLAYER, stream->demux.plugin->demux_class->identifier); } { demux_class_t *demux_class = stream->demux.plugin->demux_class; xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: found demuxer plugin: %s\n"), dgettext(demux_class->text_domain ? demux_class->text_domain : XINE_TEXTDOMAIN, demux_class->description)); } xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "open_internal (%p): demux OK.\n", (void *)stream); /* assume handled for now. we will only know for sure after trying * to init decoders (which should happen when headers are sent) */ _x_stream_info_set (&stream->s, XINE_STREAM_INFO_VIDEO_HANDLED, 1); _x_stream_info_set (&stream->s, XINE_STREAM_INFO_AUDIO_HANDLED, 1); /* * send and decode headers */ /* ARGH: demux_image sends whole image as preview at open_internal () time... */ if (stream->side_streams[0] == stream) { int seek_count; pthread_mutex_lock (&stream->first_frame.lock); seek_count = ++stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); /* read sync data cache. */ (void)xine_refs_get (&stream->current_extra_info_index); stream->open_seek_count = seek_count; /* write sync data cache. */ xine_refs_add (&stream->current_extra_info_index, 0); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "open_internal (%p): seek #%d.\n", (void *)stream, seek_count); } /* people may call xine_get_pos_length () right after xine_open () to get stream length. */ if (stream->status != XINE_STATUS_PLAY) xine_current_extra_info_reset (stream, stream->side_streams[0]->first_frame.seek_count); /* ...right inside this. */ stream->demux.plugin->send_headers (stream->demux.plugin); if (stream->demux.plugin->get_status (stream->demux.plugin) != DEMUX_OK) { if (stream->demux.plugin->get_status (stream->demux.plugin) == DEMUX_FINISHED) { xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: demuxer is already done. that was fast!\n")); } else { xine_log (stream->s.xine, XINE_LOG_MSG, _("xine: demuxer failed to start\n")); } _x_free_demux_plugin (&stream->s, &stream->demux.plugin); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "demux disposed\n"); _x_free_input_plugin (&stream->s, stream->s.input_plugin); stream->s.input_plugin = NULL; stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; stream->status = XINE_STATUS_IDLE; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "return from\n"); return 0; } _x_demux_control_headers_done (&stream->s); if (stream->status != XINE_STATUS_PLAY) stream->status = XINE_STATUS_STOP; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "open_internal (%p): OK.\n", (void *)stream); lprintf ("done\n"); return 1; } int xine_open (xine_stream_t *s, const char *mrl) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_private_t *xine = (xine_private_t *)stream->s.xine; pthread_mutex_t *frontend_lock = &stream->side_streams[0]->frontend_lock; int ret, sn; pthread_mutex_lock (frontend_lock); pthread_cleanup_push (mutex_cleanup, (void *) frontend_lock); lprintf ("open MRL:%s\n", mrl); ret = open_internal (stream, mrl, NULL); sn = 0; if (xine->join_av && mrl && (stream->side_streams[0] == stream)) do { char nbuf[1024]; struct stat st; size_t nlen; xine_stream_private_t *side; const uint8_t *p, *n, *d; const char *orig = mrl; if (!strncasecmp (orig, "file:/", 6)) orig += 6; n = d = p = (const uint8_t *)orig; while (1) { while (*p >= 0x30) p++; if ((*p == 0) || (*p == '#')) break; if (*p == '/') { p++; n = d = p; } else if (*p == '.') { d = p; p++; } else { p++; } } nlen = p - (const uint8_t *)orig; if (nlen > sizeof (nbuf) - 1) break; if ((n + 2 > d) || (d[-2] != '_') || (d[0] != '.')) break; if ((d[-1] != 'a') && (d[-1] != 'v')) break; if (stat (orig, &st)) break; if (!S_ISREG (st.st_mode)) break; memcpy (nbuf, orig, nlen); nbuf[nlen] = 0; nbuf[d - (const uint8_t *)orig - 1] = d[-1] == 'a' ? 'v' : 'a'; if (stat (nbuf, &st)) break; if (!S_ISREG (st.st_mode)) break; side = (xine_stream_private_t *)xine_get_side_stream (&stream->s, 1); if (!side) break; xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "xine_open: auto joining \"%s\" with \"%s\".\n", orig, nbuf); open_internal (side, nbuf, NULL); sn = 1; } while (0); if (!sn && mrl && (stream->side_streams[0] == stream)) do { input_plugin_t *main_input = stream->s.input_plugin; if (!main_input) break; for (sn = 1; sn < (int)(sizeof (stream->side_streams) / sizeof (stream->side_streams[0])); sn++) { xine_stream_private_t *side; union { int index; input_plugin_t *input; } si; si.index = sn; if (main_input->get_optional_data (main_input, &si, INPUT_OPTIONAL_DATA_SIDE) != INPUT_OPTIONAL_SUCCESS) break; /* load_plugins.c please keep calm ;-) */ if (si.input->node) { pthread_mutex_lock (&stream->s.xine->plugin_catalog->lock); si.input->node->ref += 1; pthread_mutex_unlock (&stream->s.xine->plugin_catalog->lock); } side = (xine_stream_private_t *)xine_get_side_stream (&stream->s, sn); if (!side) { _x_free_input_plugin (&stream->s, si.input); break; } xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "xine_open: adding side stream #%d (%p).\n", sn, (void *)side); open_internal (side, mrl, si.input); } sn--; } while (0); pthread_cleanup_pop (0); pthread_mutex_unlock (frontend_lock); return ret; } static int play_internal (xine_stream_private_t *stream, int start_pos, int start_time) { xine_private_t *xine = (xine_private_t *)stream->s.xine; int flush; int first_frame_flag = 3, seek_count; int demux_status; uint32_t input_is_seekable = 1; struct timespec ts1 = {0, 0}, ts2 = {0, 0}; struct { xine_stream_private_t *s; uint32_t flags; } sides[XINE_NUM_SIDE_STREAMS + 1], *sp, *sp2; /* ARGH: demux_image sends whole image as preview at open_internal () time. */ if (stream->status == XINE_STATUS_PLAY) { pthread_mutex_lock (&stream->first_frame.lock); seek_count = ++stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); } else { seek_count = stream->first_frame.seek_count; } if (stream->s.xine->verbosity >= XINE_VERBOSITY_DEBUG) { xine_gettime (&ts1); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "play_internal (%p, %d.%03d, %d): seek #%d...\n", (void *)stream, start_time / 1000, start_time % 1000, start_pos, seek_count); } /* list the streams (master and sides) with a demux. */ { unsigned int u; sp = sides; xine_rwlock_rdlock (&stream->info_lock); for (u = 0; u < XINE_NUM_SIDE_STREAMS; u++) { xine_stream_private_t *side = stream->side_streams[u]; if (side && side->demux.plugin) { sp->s = side; sp->flags = 0; sp++; } } xine_rwlock_unlock (&stream->info_lock); sp->s = NULL; sp->flags = 0; } if (!sides[0].s) { xine_log (stream->s.xine, XINE_LOG_MSG, _("xine_play: no demux available\n")); stream->err = XINE_ERROR_NO_DEMUX_PLUGIN; return 0; } if (start_pos || start_time) { stream->finished_naturally = 0; first_frame_flag = 2; } flush = (stream->s.master == &stream->s) && !stream->gapless_switch && !stream->finished_naturally; if (!flush) xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "play_internal (%p): using gapless switch.\n", (void *)stream); /* hint demuxer thread we want to interrupt it */ sp = sides; do { pthread_mutex_lock (&sp->s->demux.action_lock); sp->s->demux.action_pending += 0x10001; if (!(sp->s->demux.input_caps & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_TIME_SEEKABLE))) input_is_seekable = 0; pthread_mutex_unlock (&sp->s->demux.action_lock); sp++; } while (sp->s); if (input_is_seekable != stream->seekable) { static const char * const fbc_mode[4] = {"off", "a", "v", "av"}; int on; stream->seekable = input_is_seekable; on = (xine_fbc_set (stream->s.audio_fifo, input_is_seekable) ? 1 : 0) | (xine_fbc_set (stream->s.audio_fifo, input_is_seekable) ? 2 : 0); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "file_buf_ctrl: %s.\n", fbc_mode[on]); } /* WTF?? * TJ. OK these calls involve lock/unlock of the fifo mutexes. * Demux will do that again later by fifo->put (). * At least with x86 Linux, such a sequence forces a data cache sync from this thread * to the demux thread. This way, demux will see demux.action_pending > 0 early, * without the need to grab demux.action_lock for every iteration. * Reduces response delay by average 20ms. */ (void)stream->s.video_fifo->size (stream->s.video_fifo); (void)stream->s.audio_fifo->size (stream->s.audio_fifo); /* ignore speed changes (net_buf_ctrl causes deadlocks while seeking ...) */ lock_run (stream, 1); xine->port_ticket->acquire (xine->port_ticket, 1); /* only flush/discard output ports on master streams */ if (flush) { /* discard audio/video buffers to get engine going and take the lock faster */ if (stream->s.audio_out) stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_DISCARD_BUFFERS, 1); if (stream->s.video_out) stream->s.video_out->set_property (stream->s.video_out, VO_PROP_DISCARD_FRAMES, 1); /* freeze safety (discontinuity wait?) when there are multiple streams. * or, when all input is seekable, suspend faster this way. */ if (sides[1].s || input_is_seekable) { stream->s.video_fifo->clear (stream->s.video_fifo); stream->s.audio_fifo->clear (stream->s.audio_fifo); } } sp = sides; do { pthread_mutex_lock (&sp->s->demux.lock); /* demux.lock taken. now demuxer is suspended. unblock io for seeking. */ pthread_mutex_lock (&sp->s->demux.action_lock); sp->s->demux.action_pending -= 0x00001; pthread_mutex_unlock (&sp->s->demux.action_lock); sp++; } while (sp->s); if (stream->s.xine->verbosity >= XINE_VERBOSITY_DEBUG) { int diff; xine_gettime (&ts2); diff = (int)(ts2.tv_nsec - ts1.tv_nsec) / 1000000; diff += (ts2.tv_sec - ts1.tv_sec) * 1000; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "play_internal (%p): ...demux suspended after %dms.\n", (void *)stream, diff); } /* set normal speed again (now that demuxer/input pair is suspended) * some input plugin may have changed speed by itself, we must ensure * the engine is not paused. */ if (_x_get_fine_speed (&stream->s) != XINE_FINE_SPEED_NORMAL) set_speed_internal (stream, XINE_FINE_SPEED_NORMAL); /* * start/seek demux */ pthread_mutex_lock (&stream->demux.pair); stream->demux.max_seek_bufs = sides[1].s ? 1 : 0xffffffff; pthread_mutex_unlock (&stream->demux.pair); /* seek to new position (no data is sent to decoders yet) */ sp = sides; do { xine_stream_private_t *s; int r; int32_t vtime = 0; if (!sides[1].s) break; sp2 = sides; do { if (sp2->s->demux.plugin->get_capabilities (sp2->s->demux.plugin) & DEMUX_CAP_VIDEO_TIME) break; sp2++; } while (sp2->s); if (!sp2->s) break; s = sp2->s; sp2->s = sides[0].s; sides[0].s = s; sp++; r = sides[0].s->demux.plugin->seek (sides[0].s->demux.plugin, start_pos, start_time, sides[0].s->demux.thread_running); sides[0].flags = r == DEMUX_OK ? 1 : 0; if (r != DEMUX_OK) break; if (sides[0].s->demux.plugin->get_optional_data (sides[0].s->demux.plugin, &vtime, DEMUX_OPTIONAL_DATA_VIDEO_TIME) != DEMUX_OPTIONAL_SUCCESS) break; start_pos = 0; start_time = vtime; } while (0); do { int r = sp->s->demux.plugin->seek (sp->s->demux.plugin, start_pos, start_time, sp->s->demux.thread_running); sp->flags = r == DEMUX_OK ? 1 : 0; sp++; } while (sp->s); /* only flush/discard output ports on master streams */ if (flush) { if (stream->s.audio_out) stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_DISCARD_BUFFERS, 0); if (stream->s.video_out) stream->s.video_out->set_property (stream->s.video_out, VO_PROP_DISCARD_FRAMES, 0); } else { stream->s.metronom->handle_audio_discontinuity (stream->s.metronom, DISC_GAPLESS, 0); } xine->port_ticket->release (xine->port_ticket, 1); unlock_run (stream); /* before resuming the demuxer, set first_frame_flag */ pthread_mutex_lock (&stream->first_frame.lock); stream->first_frame.flag = first_frame_flag; pthread_mutex_unlock (&stream->first_frame.lock); /* before resuming the demuxer, reset current position information */ if (flush) xine_current_extra_info_reset (stream, -2); /* now resume demuxer thread if it is running already */ demux_status = 0; sp = sides; do { sp->flags |= sp->s->demux.thread_running ? 2 : 0; pthread_mutex_unlock (&sp->s->demux.lock); /* now that demux lock is released, resume demux. */ pthread_mutex_lock (&sp->s->demux.action_lock); sp->s->demux.action_pending -= 0x10000; if (sp->s->demux.action_pending <= 0) pthread_cond_signal (&sp->s->demux.resume); pthread_mutex_unlock (&sp->s->demux.action_lock); /* seek OK but not running? try restart. */ if (sp->flags == 1) { if (_x_demux_start_thread (&sp->s->s) >= 0) sp->flags = 3; } if (sp->flags == 3) demux_status++; sp++; } while (sp->s); if (!demux_status) goto demux_failed; stream->status = XINE_STATUS_PLAY; stream->finished_naturally = 0; /* Wait until the first frame produced is displayed. see video_out.c. */ if (stream->video_decoder_plugin || stream->audio_decoder_plugin) { pthread_mutex_lock (&stream->first_frame.lock); if (stream->first_frame.flag > 0) { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_sec += 10; pthread_cond_timedwait (&stream->first_frame.reached, &stream->first_frame.lock, &ts); } pthread_mutex_unlock (&stream->first_frame.lock); } if (stream->s.xine->verbosity >= XINE_VERBOSITY_DEBUG) { int diff = xine_current_seek_count (stream); if (diff != seek_count) xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "play_internal (%p): warning: seek count still %d != %d.\n", (void *)stream, diff, seek_count); xine_gettime (&ts2); diff = (int)(ts2.tv_nsec - ts1.tv_nsec) / 1000000; diff += (ts2.tv_sec - ts1.tv_sec) * 1000; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "play_internal (%p): ...done after %dms.\n", (void *)stream, diff); } return 1; demux_failed: xine_log (stream->s.xine, XINE_LOG_MSG, _("xine_play: demux failed to start\n")); stream->err = XINE_ERROR_DEMUX_FAILED; pthread_mutex_lock (&stream->first_frame.lock); stream->first_frame.flag = 0; // no need to signal: wait is done only in this function. pthread_mutex_unlock (&stream->first_frame.lock); return 0; } int xine_play (xine_stream_t *s, int start_pos, int start_time) { xine_stream_private_t *stream = (xine_stream_private_t *)s, *m; int ret; if (!stream) return 0; m = stream->side_streams[0]; pthread_mutex_lock (&m->frontend_lock); pthread_cleanup_push (mutex_cleanup, (void *) &m->frontend_lock); m->delay_finish_event = 0; ret = play_internal (m, start_pos, start_time); if (m->s.slave && (m->slave_affection & XINE_MASTER_SLAVE_PLAY) ) xine_play (m->s.slave, start_pos, start_time); m->gapless_switch = 0; pthread_cleanup_pop (0); pthread_mutex_unlock (&m->frontend_lock); return ret; } int xine_eject (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s, *m; int status; if (!stream) return 0; m = stream->side_streams[0]; if (!m->eject_class) return 0; pthread_mutex_lock (&m->frontend_lock); pthread_cleanup_push (mutex_cleanup, (void *) &m->frontend_lock); status = 0; /* only eject, if we are stopped OR a different input plugin is playing */ if (m->eject_class && m->eject_class->eject_media && ((m->status == XINE_STATUS_STOP) || m->eject_class != m->s.input_plugin->input_class)) { status = m->eject_class->eject_media (m->eject_class); } pthread_cleanup_pop (0); pthread_mutex_unlock (&m->frontend_lock); return status; } static void xine_dispose_internal (xine_stream_private_t *stream) { xine_t *xine = stream->s.xine; lprintf("stream: %p\n", (void*)stream); xine->config->unregister_callbacks (xine->config, NULL, NULL, stream, sizeof (*stream)); pthread_mutex_lock (&xine->streams_lock); { xine_list_iterator_t ite = xine_list_find (xine->streams, stream); if (ite) xine_list_remove (xine->streams, ite); } /* keep xine instance open for this */ stream->s.metronom->exit (stream->s.metronom); pthread_mutex_unlock (&xine->streams_lock); pthread_mutex_destroy (&stream->frontend_lock); pthread_mutex_destroy (&stream->index.lock); pthread_cond_destroy (&stream->first_frame.reached); pthread_mutex_destroy (&stream->first_frame.lock); pthread_cond_destroy (&stream->counter.changed); pthread_mutex_destroy (&stream->counter.lock); pthread_mutex_destroy (&stream->event.lock); pthread_cond_destroy (&stream->demux.resume); pthread_mutex_destroy (&stream->demux.pair); pthread_mutex_destroy (&stream->demux.action_lock); pthread_mutex_destroy (&stream->demux.lock); xine_rwlock_destroy (&stream->meta_lock); xine_rwlock_destroy (&stream->info_lock); xine_refs_sub (&stream->current_extra_info_index, xine_refs_get (&stream->current_extra_info_index)); xine_list_delete (stream->event.queues); free (stream->index.array); free (stream); } void xine_dispose (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; /* decrease the reference counter * if there is no more reference on this stream, the xine_dispose_internal * function is called */ if (!stream) return; /* never dispose side streams directly. */ if (stream->side_streams[0] != stream) return; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "xine_dispose (%p).\n", (void *)stream); stream->status = XINE_STATUS_QUIT; xine_close (&stream->s); if (stream->s.master != &stream->s) { stream->s.master->slave = NULL; } if (stream->s.slave && (stream->s.slave->master == &stream->s)) { stream->s.slave->master = NULL; } { unsigned int u; for (u = 1; u < XINE_NUM_SIDE_STREAMS; u++) { xine_stream_private_t *side = stream->side_streams[u]; if (side) xine_refs_sub (&side->refs, 1); } } if(stream->broadcaster) _x_close_broadcaster(stream->broadcaster); /* Demuxers mpeg, mpeg_block and yuv_frames may send video pool buffers * to audio fifo. Fifos should be empty at this point. For safety, * shut down audio first anyway. */ xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "shutdown audio\n"); _x_audio_decoder_shutdown (&stream->s); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "shutdown video\n"); _x_video_decoder_shutdown (&stream->s); if (stream->s.osd_renderer) stream->s.osd_renderer->close (stream->s.osd_renderer); /* Remove the reference that the stream was created with. */ xine_refs_sub (&stream->refs, 1); } #ifdef WIN32 static int xine_wsa_users = 0; #endif void xine_exit (xine_t *this_gen) { xine_private_t *this = (xine_private_t *)this_gen; if (this->x.streams) { int n = 10; /* XXX: streams kill themselves via their refs hook. */ while (n--) { xine_stream_private_t *stream = NULL; xine_list_iterator_t ite; pthread_mutex_lock (&this->x.streams_lock); ite = NULL; while (1) { stream = xine_list_next_value (this->x.streams, &ite); if (!ite || (stream && (&stream->s != XINE_ANON_STREAM))) break; } if (!ite) { pthread_mutex_unlock (&this->x.streams_lock); break; } /* stream->refcounter->lock might be taken already */ { int i = xine_refs_add (&stream->refs, 0); pthread_mutex_unlock (&this->x.streams_lock); xprintf (&this->x, XINE_VERBOSITY_LOG, "xine_exit: BUG: stream %p still open (%d refs), waiting.\n", (void*)stream, i); } if (n) { xine_usec_sleep (50000); } else { #ifdef FORCE_STREAM_SHUTDOWN /* might raise even more heap damage, disabled for now */ xprintf (&this->x, XINE_VERBOSITY_LOG, "xine_exit: closing stream %p.\n", (void*)stream); stream->refcounter->count = 1; xine_dispose (stream); n = 1; #endif } } xine_list_delete (this->x.streams); pthread_mutex_destroy (&this->x.streams_lock); } if (this->x.config) this->x.config->unregister_callbacks (this->x.config, NULL, NULL, this, sizeof (*this)); xprintf (&this->x, XINE_VERBOSITY_DEBUG, "xine_exit: bye!\n"); _x_dispose_plugins (&this->x); if (this->x.clock) this->x.clock->exit (this->x.clock); if (this->x.config) this->x.config->dispose (this->x.config); if(this->port_ticket) this->port_ticket->dispose(this->port_ticket); pthread_cond_destroy (&this->speed_change_done); pthread_mutex_destroy (&this->speed_change_lock); { int i; for (i = 0; i < XINE_LOG_NUM; i++) if (this->x.log_buffers[i]) this->x.log_buffers[i]->dispose (this->x.log_buffers[i]); } pthread_mutex_destroy(&this->log_lock); #if defined(WIN32) if (xine_wsa_users) { if (--xine_wsa_users == 0) WSACleanup (); } #endif xdgWipeHandle (&this->x.basedir_handle); free (this); } xine_t *xine_new (void) { xine_private_t *this; this = calloc (1, sizeof (*this)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this->x.plugin_catalog = NULL; this->x.save_path = NULL; this->x.streams = NULL; this->x.clock = NULL; this->port_ticket = NULL; this->speed_change_flags = 0; this->strings.decoder_pri_help = NULL; #endif pthread_mutex_init (&this->speed_change_lock, NULL); pthread_cond_init (&this->speed_change_done, NULL); #ifdef ENABLE_NLS /* * i18n */ bindtextdomain(XINE_TEXTDOMAIN, XINE_LOCALEDIR); #endif /* * config */ this->x.config = _x_config_init (); if (!this->x.config) { free(this); return NULL; } /* * log buffers */ memset (this->x.log_buffers, 0, sizeof (this->x.log_buffers)); pthread_mutex_init (&this->log_lock, NULL); #ifdef WIN32 if (!xine_wsa_users) { /* WinSock Library Init. */ WSADATA Data; int i_err = WSAStartup (MAKEWORD (1, 1), &Data); if (i_err) { fprintf (stderr, "error: can't initiate WinSocks, error %i\n", i_err); } else { xine_wsa_users++; } } else { xine_wsa_users++; } #endif /* WIN32 */ this->x.verbosity = XINE_VERBOSITY_NONE; return &this->x; } void xine_engine_set_param(xine_t *this, int param, int value) { if(this) { switch(param) { case XINE_ENGINE_PARAM_VERBOSITY: this->verbosity = value; break; default: lprintf("Unknown parameter %d\n", param); break; } } } int xine_engine_get_param(xine_t *this, int param) { if(this) { switch(param) { case XINE_ENGINE_PARAM_VERBOSITY: return this->verbosity; break; default: lprintf("Unknown parameter %d\n", param); break; } } return -1; } static void config_demux_strategy_cb (void *this_gen, xine_cfg_entry_t *entry) { xine_t *this = (xine_t *)this_gen; this->demux_strategy = entry->num_value; } static void config_save_cb (void *this_gen, xine_cfg_entry_t *entry) { xine_t *this = (xine_t *)this_gen; char homedir_trail_slash[strlen(xine_get_homedir()) + 2]; sprintf(homedir_trail_slash, "%s/", xine_get_homedir()); if (entry->str_value[0] && (entry->str_value[0] != '/' || strstr(entry->str_value, "/.") || strcmp(entry->str_value, xine_get_homedir()) == 0 || strcmp(entry->str_value, homedir_trail_slash) == 0)) { xine_stream_t *stream; xine_list_iterator_t ite; xine_log(this, XINE_LOG_MSG, _("xine: The specified save_dir \"%s\" might be a security risk.\n"), entry->str_value); pthread_mutex_lock(&this->streams_lock); ite = NULL; if ((stream = xine_list_next_value (this->streams, &ite))) { _x_message(stream, XINE_MSG_SECURITY, _("The specified save_dir might be a security risk."), NULL); } pthread_mutex_unlock(&this->streams_lock); } this->save_path = entry->str_value; } void xine_set_flags (xine_t *this_gen, int flags) { xine_private_t *this = (xine_private_t *)this_gen; this->flags = flags; } int _x_query_network_timeout (xine_t *xine_gen) { xine_private_t *xine = (xine_private_t *)xine_gen; return xine ? xine->network_timeout : 30; } static void network_timeout_cb (void *this_gen, xine_cfg_entry_t *entry) { xine_private_t *this = (xine_private_t *)this_gen; this->network_timeout = entry->num_value; } #ifdef ENABLE_IPV6 static void ip_pref_cb (void *this_gen, xine_cfg_entry_t *entry) { xine_private_t *this = (xine_private_t *)this_gen; this->ip_pref = entry->num_value; } #endif static void join_av_cb (void *this_gen, xine_cfg_entry_t *entry) { xine_private_t *this = (xine_private_t *)this_gen; this->join_av = entry->num_value; } static void audio_update_linear_levels (void *this_gen, xine_cfg_entry_t *entry) { xine_private_t *this = (xine_private_t *)this_gen; this->audio_lin_levels = entry->num_value; } void xine_init (xine_t *this_gen) { xine_private_t *this = (xine_private_t *)this_gen; /* First of all, initialise libxdg-basedir as it's used by plugins. */ setenv ("HOME", xine_get_homedir (), 0); /* libxdg-basedir needs $HOME */ xdgInitHandle (&this->x.basedir_handle); /* debug verbosity override */ { int v = 0; const uint8_t *s = (const uint8_t *)getenv ("LIBXINE_VERBOSITY"), *t = s; uint8_t z; if (s) { while ((z = *s++ ^ '0') < 10) v = 10 * v + z; if (s > t + 1) this->x.verbosity = v; } } /* * locks */ pthread_mutex_init (&this->x.streams_lock, NULL); /* initialize color conversion tables and functions */ init_yuv_conversion(); /* probe for optimized memcpy or config setting */ xine_probe_fast_memcpy (&this->x); /* * plugins */ XINE_PROFILE (_x_scan_plugins (&this->x)); #ifdef HAVE_SETLOCALE if (!setlocale(LC_CTYPE, "")) xprintf (&this->x, XINE_VERBOSITY_LOG, _("xine: locale not supported by C library\n")); #endif /* * content detection strategy */ { static const char *const demux_strategies[] = {"default", "reverse", "content", "extension", NULL}; this->x.demux_strategy = this->x.config->register_enum ( this->x.config, "engine.demux.strategy", 0, (char **)demux_strategies, _("media format detection strategy"), _("xine offers various methods to detect the media format of input to play. " "The individual values are:\n\n" "default\n" "First try to detect by content, then by file name extension.\n\n" "reverse\n" "First try to detect by file name extension, then by content.\n\n" "content\n" "Detect by content only.\n\n" "extension\n" "Detect by file name extension only.\n"), 20, config_demux_strategy_cb, this); } /* * save directory */ this->x.save_path = this->x.config->register_filename ( this->x.config, "media.capture.save_dir", "", XINE_CONFIG_STRING_IS_DIRECTORY_NAME, _("directory for saving streams"), _("When using the stream save feature, files will be written only into this directory.\n" "This setting is security critical, because when changed to a different directory, xine " "can be used to fill files in it with arbitrary content. So you should be careful that " "the directory you specify is robust against any content in any file."), XINE_CONFIG_SECURITY, config_save_cb, this); /* * implicit configuration changes */ this->x.config->register_bool (this->x.config, "misc.implicit_config", 0, _("allow implicit changes to the configuration (e.g. by MRL)"), _("If enabled, you allow xine to change your configuration without " "explicit actions from your side. For example configuration changes " "demanded by MRLs or embedded into playlist will be executed.\n" "This setting is security critcal, because xine can receive MRLs or " "playlists from untrusted remote sources. If you allow them to " "arbitrarily change your configuration, you might end with a totally " "messed up xine."), XINE_CONFIG_SECURITY, NULL, this); /* * timeout for network I/O to avoid freezes */ this->network_timeout = this->x.config->register_num (this->x.config, "media.network.timeout", 30, _("Timeout for network stream reading (in seconds)"), _("Specifies the timeout when reading from network streams, in seconds. " "Too low values might stop streaming when the source is slow or the " "bandwidth is occupied, too high values will freeze the player if the " "connection is lost."), 0, network_timeout_cb, this); #ifdef ENABLE_IPV6 /* * network ip version */ { static const char *const ip_versions[] = {"auto", "IPv4", "IPv4, IPv6", "IPv6, IPv4", NULL}; this->ip_pref = this->x.config->register_enum ( this->x.config, "media.network.ip_version", 1, (char **)ip_versions, _("Internet Protocol version(s) to use"), _("\"auto\" just tries what the name query returned.\n" "Otherwise, IPv4 may offer more compatibility and privacy."), 20, ip_pref_cb, this); } #endif /* * auto join separate audio/video files (testing the side stream feature). */ this->join_av = this->x.config->register_bool (this->x.config, "media.files.join_av", 0, _("Auto join separate audio/video files"), _("When opening an audio only file \"foo_a.ext\", assume that \"foo_v.ext\" " "contains the missing video track for it, and vice versa.\n" "This mainly serves as a test for engine side streams."), 20, join_av_cb, this); /* * legacy support */ this->audio_lin_levels = this->x.config->register_bool (this->x.config, "audio.processing.linear_levels", 0, _("Use pre-1.2.13 libxine audio level settings"), /* Tell msgfmt that these "%" are _not_ c formats. */ /* xgettext:no-c-format */ _("On: 0..200 means 0..200% of audio amplification and equalizer amplitudes.\n" " Some applications rely on this, and use their own level mapping.\n" "Off: 100 still means 100% or 0 dB. A step of 1 then means plus or minus\n" " 1 dB for amplification, and 0.5 dB for equalizer.\n"), 0, audio_update_linear_levels, this); /* * keep track of all opened streams */ this->x.streams = xine_list_new (); /* * start metronom clock */ this->x.clock = _x_metronom_clock_init (&this->x); this->x.clock->start_clock (this->x.clock, 0); /* * tickets */ this->port_ticket = ticket_init(); } void _x_select_spu_channel (xine_stream_t *s, int channel) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_private_t *xine = (xine_private_t *)stream->s.xine; xine_stream_private_t *substream = NULL; stream = stream->side_streams[0]; substream = (xine_stream_private_t *)stream->s.slave; pthread_mutex_lock (&stream->frontend_lock); stream->s.spu_channel_user = (channel >= -2 ? channel : -2); xine->port_ticket->acquire (xine->port_ticket, 1); switch (stream->s.spu_channel_user) { case -2: stream->s.spu_channel = -1; break; case -1: if (substream) stream->s.spu_channel = substream->s.spu_channel_auto; else stream->s.spu_channel = stream->s.spu_channel_auto; break; default: stream->s.spu_channel = stream->s.spu_channel_user; } lprintf ("set to %d\n", stream->s.spu_channel); xine->port_ticket->release (xine->port_ticket, 1); pthread_mutex_unlock (&stream->frontend_lock); if (substream) { pthread_mutex_lock (&substream->frontend_lock); substream->s.spu_channel = stream->s.spu_channel; substream->s.spu_channel_user = stream->s.spu_channel_user; pthread_mutex_unlock (&substream->frontend_lock); } } void _x_get_current_info (xine_stream_t *s, extra_info_t *extra_info, int size) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; if (!extra_info || (size <= 0)) { return; } else if ((size_t)size < sizeof (*extra_info)) { extra_info_t info; xine_current_extra_info_get (stream, &info); memcpy (extra_info, &info, size); } else { xine_current_extra_info_get (stream, extra_info); } } int xine_get_status (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; /* phonon bug */ if (!stream) { printf ("xine_get_status: BUG: stream = NULL.\n"); return XINE_STATUS_QUIT; } stream = stream->side_streams[0]; return stream->status; } /* * trick play */ void _x_set_fine_speed (xine_stream_t *s, int speed) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_private_t *xine = (xine_private_t *)stream->s.xine; uint32_t speed_change_flags; stream = stream->side_streams[0]; /* net_buf_ctrl may have 2 threads trying to pause with ticket held in parallel. * Avoid that freeze like this: * - Hold speed_change_lock for finite time only. * - While changing speed, remember latest speed wishes from elsewhere, * and apply them after the current one. */ pthread_mutex_lock (&xine->speed_change_lock); speed_change_flags = xine->speed_change_flags; if (speed_change_flags & SPEED_FLAG_IGNORE_CHANGE) { pthread_mutex_unlock (&xine->speed_change_lock); return; } if (speed_change_flags & SPEED_FLAG_CHANGING) { if ((speed == XINE_LIVE_PAUSE_ON) || (speed == XINE_LIVE_PAUSE_OFF)) { xine->speed_change_flags = speed_change_flags | SPEED_FLAG_WANT_LIVE; xine->speed_change_new_live = speed; pthread_mutex_unlock (&xine->speed_change_lock); return; } xine->speed_change_flags = speed_change_flags | SPEED_FLAG_WANT_NEW; xine->speed_change_new_speed = speed; pthread_mutex_unlock (&xine->speed_change_lock); return; } xine->speed_change_flags |= SPEED_FLAG_CHANGING; pthread_mutex_unlock (&xine->speed_change_lock); while (1) { if (speed <= XINE_SPEED_PAUSE) speed = XINE_SPEED_PAUSE; xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "set_speed %d.\n", speed); set_speed_internal (stream, speed); if (stream->s.slave && (stream->slave_affection & XINE_MASTER_SLAVE_SPEED)) set_speed_internal ((xine_stream_private_t *)stream->s.slave, speed); pthread_mutex_lock (&xine->speed_change_lock); speed_change_flags = xine->speed_change_flags; if (!(speed_change_flags & (SPEED_FLAG_WANT_LIVE | SPEED_FLAG_WANT_NEW))) { xine->speed_change_flags = speed_change_flags & ~(SPEED_FLAG_CHANGING | SPEED_FLAG_WANT_LIVE | SPEED_FLAG_WANT_NEW); if (speed_change_flags & SPEED_FLAG_IGNORE_CHANGE) pthread_cond_broadcast (&xine->speed_change_done); pthread_mutex_unlock (&xine->speed_change_lock); return; } if (speed_change_flags & SPEED_FLAG_WANT_LIVE) { xine->speed_change_flags = speed_change_flags & ~SPEED_FLAG_WANT_LIVE; speed = xine->speed_change_new_live; } else { /* speed_change_flags & SPEED_FLAG_WANT_NEW */ xine->speed_change_flags = speed_change_flags & ~SPEED_FLAG_WANT_NEW; speed = xine->speed_change_new_speed; } pthread_mutex_unlock (&xine->speed_change_lock); } } int _x_get_fine_speed (xine_stream_t *stream) { return stream->xine->clock->speed; } void _x_set_speed (xine_stream_t *stream, int speed) { if (speed > XINE_SPEED_FAST_4) speed = XINE_SPEED_FAST_4; _x_set_fine_speed (stream, speed * XINE_FINE_SPEED_NORMAL / XINE_SPEED_NORMAL); } int _x_get_speed (xine_stream_t *stream) { int speed = _x_get_fine_speed (stream); /* * ensure compatibility with old API, only valid XINE_SPEED_xxx * constants are allowed. XINE_SPEED_NORMAL may only be returned * if speed is exactly XINE_FINE_SPEED_NORMAL. */ if( speed <= XINE_SPEED_PAUSE ) return XINE_SPEED_PAUSE; if( speed <= XINE_SPEED_SLOW_4 * XINE_FINE_SPEED_NORMAL / XINE_SPEED_NORMAL ) return XINE_SPEED_SLOW_4; if( speed < XINE_FINE_SPEED_NORMAL ) return XINE_SPEED_SLOW_2; if( speed == XINE_FINE_SPEED_NORMAL ) return XINE_SPEED_NORMAL; if( speed <= XINE_SPEED_FAST_2 * XINE_FINE_SPEED_NORMAL / XINE_SPEED_NORMAL ) return XINE_SPEED_FAST_2; return XINE_SPEED_FAST_4; } /* * time measurement / seek */ int xine_get_pos_length (xine_stream_t *s, int *pos_stream, int *pos_time, int *length_time) { xine_stream_private_t *stream = (xine_stream_private_t *)s; extra_info_t info; int res, seek_count; stream = stream->side_streams[0]; pthread_mutex_lock (&stream->frontend_lock); if (!stream->s.input_plugin) { lprintf ("no input source\n"); pthread_mutex_unlock (&stream->frontend_lock); return 0; } if ((!stream->video_decoder_plugin && !stream->audio_decoder_plugin)) { /* rare case: no decoders available. */ xine_rwlock_rdlock (&stream->info_lock); if (stream->stream_info[XINE_STREAM_INFO_HAS_VIDEO]) { xine_rwlock_unlock (&stream->info_lock); xine_current_extra_info_set (stream, stream->video_decoder_extra_info); } else { xine_rwlock_unlock (&stream->info_lock); xine_current_extra_info_set (stream, stream->audio_decoder_extra_info); } } xine_current_extra_info_get (stream, &info); /* this is only changed with frontend lock held -> safe to read here. */ seek_count = stream->first_frame.seek_count; if (info.seek_count == seek_count) { res = 1; } else if (info.seek_count == seek_count - 1) { /* this may happen shortly after stream start. */ res = 2; } else { pthread_mutex_unlock (&stream->frontend_lock); return 0; /* position not yet known */ } if (length_time) { int length = info.total_time; /* frontend lock prevents demux unload. To be very precise, we would need to * suspend demux here as well, and trash performance :-/ * Well. Demux either knows length from the start, and value is constant. * Or, it grows with current position. We can do that, too. */ if (!length && (res == 1) && stream->demux.plugin) length = stream->demux.plugin->get_stream_length (stream->demux.plugin); pthread_mutex_unlock (&stream->frontend_lock); if ((length > 0) && (length < info.input_time)) length = info.input_time; *length_time = length; } else { pthread_mutex_unlock (&stream->frontend_lock); } if (pos_stream) *pos_stream = info.input_normpos; if (pos_time) *pos_time = info.input_time; return res; } static int _x_get_current_frame_data (xine_stream_t *stream, xine_current_frame_data_t *data, int flags, int img_size_unknown) { xine_private_t *xine; vo_frame_t *frame; size_t required_size = 0; { xine_stream_private_t *s = (xine_stream_private_t *)stream; stream = &s->side_streams[0]->s; } xine = (xine_private_t *)stream->xine; xine->port_ticket->acquire (xine->port_ticket, 1); frame = stream->video_out->get_last_frame (stream->video_out); xine->port_ticket->release (xine->port_ticket, 1); if (!frame) { data->img_size = 0; return 0; } data->width = frame->width; data->height = frame->height; data->crop_left = frame->crop_left; data->crop_right = frame->crop_right; data->crop_top = frame->crop_top; data->crop_bottom = frame->crop_bottom; data->ratio_code = 10000.0 * frame->ratio; /* make ratio_code backward compatible */ #define RATIO_LIKE(a, b) ((b) - 1 <= (a) && (a) <= 1 + (b)) if (RATIO_LIKE(data->ratio_code, 10000)) data->ratio_code = XINE_VO_ASPECT_SQUARE; else if (RATIO_LIKE(data->ratio_code, 13333)) data->ratio_code = XINE_VO_ASPECT_4_3; else if (RATIO_LIKE(data->ratio_code, 17778)) data->ratio_code = XINE_VO_ASPECT_ANAMORPHIC; else if (RATIO_LIKE(data->ratio_code, 21100)) data->ratio_code = XINE_VO_ASPECT_DVB; data->format = frame->format; data->interlaced = frame->progressive_frame ? 0 : (2 - frame->top_field_first); switch (frame->format) { default: if (frame->proc_provide_standard_frame_data) { uint8_t *img = data->img; size_t img_size = data->img_size; data->img = 0; data->img_size = 0; /* ask frame implementation for required img buffer size */ frame->proc_provide_standard_frame_data(frame, data); required_size = data->img_size; data->img = img; data->img_size = img_size; break; } if (!data->img && !(flags & XINE_FRAME_DATA_ALLOCATE_IMG)) break; /* not interested in image data */ xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "xine: error, snapshot function not implemented for format 0x%x\n", frame->format); /* fall through and provide "green" YV12 image */ data->format = XINE_IMGFMT_YV12; /* fall through */ case XINE_IMGFMT_YV12: required_size = frame->width * frame->height + ((frame->width + 1) / 2) * ((frame->height + 1) / 2) + ((frame->width + 1) / 2) * ((frame->height + 1) / 2); break; case XINE_IMGFMT_YUY2: required_size = frame->width * frame->height + ((frame->width + 1) / 2) * frame->height + ((frame->width + 1) / 2) * frame->height; break; } if (flags & XINE_FRAME_DATA_ALLOCATE_IMG) { /* return allocated buffer size */ data->img_size = required_size; /* allocate img or fail */ if (!(data->img = calloc(1, required_size))) { frame->free(frame); return 0; } } else { /* fail if supplied buffer is to small */ if (data->img && !img_size_unknown && data->img_size < (int)required_size) { data->img_size = required_size; frame->free(frame); return 0; } /* return used buffer size */ data->img_size = required_size; } if (data->img) { switch (frame->format) { case XINE_IMGFMT_YV12: yv12_to_yv12( /* Y */ frame->base[0], frame->pitches[0], data->img, frame->width, /* U */ frame->base[1], frame->pitches[1], data->img+frame->width*frame->height, frame->width/2, /* V */ frame->base[2], frame->pitches[2], data->img+frame->width*frame->height+frame->width*frame->height/4, frame->width/2, /* width x height */ frame->width, frame->height); break; case XINE_IMGFMT_YUY2: yuy2_to_yuy2( /* src */ frame->base[0], frame->pitches[0], /* dst */ data->img, frame->width*2, /* width x height */ frame->width, frame->height); break; default: if (frame->proc_provide_standard_frame_data) frame->proc_provide_standard_frame_data(frame, data); else if (!(flags & XINE_FRAME_DATA_ALLOCATE_IMG)) memset(data->img, 0, data->img_size); } } frame->free(frame); return 1; } int xine_get_current_frame_data (xine_stream_t *stream, xine_current_frame_data_t *data, int flags) { return _x_get_current_frame_data(stream, data, flags, 0); } int xine_get_current_frame_alloc (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, uint8_t **img, int *img_size) { int result; xine_current_frame_data_t data; memset(&data, 0, sizeof (data)); result = _x_get_current_frame_data(stream, &data, img ? XINE_FRAME_DATA_ALLOCATE_IMG : 0, 0); if (width) *width = data.width; if (height) *height = data.height; if (ratio_code) *ratio_code = data.ratio_code; if (format) *format = data.format; if (img_size) *img_size = data.img_size; if (img) *img = data.img; return result; } int xine_get_current_frame_s (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, uint8_t *img, int *img_size) { int result; xine_current_frame_data_t data; memset(&data, 0, sizeof (data)); data.img = img; if (img_size) data.img_size = *img_size; result = _x_get_current_frame_data(stream, &data, 0, 0); if (width) *width = data.width; if (height) *height = data.height; if (ratio_code) *ratio_code = data.ratio_code; if (format) *format = data.format; if (img_size) *img_size = data.img_size; return result; } int xine_get_current_frame (xine_stream_t *stream, int *width, int *height, int *ratio_code, int *format, uint8_t *img) { int result; xine_current_frame_data_t data; memset(&data, 0, sizeof (data)); data.img = img; result = _x_get_current_frame_data(stream, &data, 0, 1); if (width) *width = data.width; if (height) *height = data.height; if (ratio_code) *ratio_code = data.ratio_code; if (format) *format = data.format; return result; } xine_grab_video_frame_t* xine_new_grab_video_frame (xine_stream_t *stream) { xine_private_t *xine = (xine_private_t *)stream->xine; xine_grab_video_frame_t *frame; xine->port_ticket->acquire (xine->port_ticket, 1); { xine_stream_private_t *s = (xine_stream_private_t *)stream; stream = &s->side_streams[0]->s; } if (stream->video_out->driver->new_grab_video_frame) frame = stream->video_out->driver->new_grab_video_frame(stream->video_out->driver); else frame = stream->video_out->new_grab_video_frame(stream->video_out); xine->port_ticket->release (xine->port_ticket, 1); return frame; } static int _get_spu_lang (xine_stream_private_t *stream, int channel, char *lang) { if (!lang) return 0; /* Ask the demuxer first (e.g. TS extracts this information from * the stream) **/ if (stream->demux.plugin) { if (stream->demux.plugin->get_capabilities (stream->demux.plugin) & DEMUX_CAP_SPULANG) { /* pass the channel number to the plugin in the data field */ memcpy(lang, &channel, sizeof(channel)); if (stream->demux.plugin->get_optional_data (stream->demux.plugin, lang, DEMUX_OPTIONAL_DATA_SPULANG) == DEMUX_OPTIONAL_SUCCESS) return 1; } } /* No match, check with input plugin instead (e.g. DVD gets this * info from the IFO). **/ if (stream->s.input_plugin) { if (stream->s.input_plugin->get_capabilities (stream->s.input_plugin) & INPUT_CAP_SPULANG) { /* pass the channel number to the plugin in the data field */ memcpy(lang, &channel, sizeof(channel)); if (stream->s.input_plugin->get_optional_data (stream->s.input_plugin, lang, INPUT_OPTIONAL_DATA_SPULANG) == INPUT_OPTIONAL_SUCCESS) return 1; } } memcpy (lang, "und", 4); return 0; } int xine_get_spu_lang (xine_stream_t *s, int channel, char *lang) { xine_stream_private_t *stream = (xine_stream_private_t *)s; int ret; pthread_mutex_lock (&stream->frontend_lock); ret = _get_spu_lang(stream, channel, lang); pthread_mutex_unlock (&stream->frontend_lock); return ret; } static int _get_audio_lang (xine_stream_private_t *stream, int channel, char *lang) { if (!lang) return 0; if (stream->demux.plugin) { if (stream->demux.plugin->get_capabilities (stream->demux.plugin) & DEMUX_CAP_AUDIOLANG) { /* pass the channel number to the plugin in the data field */ memcpy(lang, &channel, sizeof(channel)); if (stream->demux.plugin->get_optional_data (stream->demux.plugin, lang, DEMUX_OPTIONAL_DATA_AUDIOLANG) == DEMUX_OPTIONAL_SUCCESS) return 1; } } if (stream->s.input_plugin) { if (stream->s.input_plugin->get_capabilities (stream->s.input_plugin) & INPUT_CAP_AUDIOLANG) { /* pass the channel number to the plugin in the data field */ memcpy(lang, &channel, sizeof(channel)); if (stream->s.input_plugin->get_optional_data (stream->s.input_plugin, lang, INPUT_OPTIONAL_DATA_AUDIOLANG) == INPUT_OPTIONAL_SUCCESS) return 1; } } memcpy (lang, "und", 4); return 0; } int xine_get_audio_lang (xine_stream_t *s, int channel, char *lang) { xine_stream_private_t *stream = (xine_stream_private_t *)s; int ret; pthread_mutex_lock (&stream->frontend_lock); ret = _get_audio_lang(stream, channel, lang); pthread_mutex_unlock (&stream->frontend_lock); return ret; } int _x_get_spu_channel (xine_stream_t *stream) { xine_stream_private_t *s = (xine_stream_private_t *)stream; stream = &s->side_streams[0]->s; return stream->spu_channel_user; } int _x_get_video_streamtype (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; return stream->video_decoder_streamtype; } /* * log functions */ int xine_get_log_section_count (xine_t *this) { (void)this; return XINE_LOG_NUM; } const char *const *xine_get_log_names (xine_t *this) { static const char *log_sections[XINE_LOG_NUM + 1]; log_sections[XINE_LOG_MSG] = _("messages"); log_sections[XINE_LOG_PLUGIN] = _("plugin"); log_sections[XINE_LOG_TRACE] = _("trace"); log_sections[XINE_LOG_NUM] = NULL; (void)this; return log_sections; } static inline void check_log_alloc (xine_private_t *this, int buf) { if (this->x.log_buffers[buf]) return; pthread_mutex_lock (&this->log_lock); if (!this->x.log_buffers[buf]) this->x.log_buffers[buf] = _x_new_scratch_buffer(150); pthread_mutex_unlock (&this->log_lock); } void xine_log (xine_t *this_gen, int buf, const char *format, ...) { xine_private_t *this = (xine_private_t *)this_gen; va_list argp; char buffer[SCRATCH_LINE_LEN_MAX]; check_log_alloc (this, buf); va_start (argp, format); this->x.log_buffers[buf]->scratch_printf (this->x.log_buffers[buf], format, argp); va_end(argp); if (this->x.verbosity) { va_start(argp, format); vsnprintf(buffer, SCRATCH_LINE_LEN_MAX, format, argp); printf("%s", buffer); va_end (argp); } if (this->log_cb) this->log_cb (this->log_cb_user_data, buf); } void xine_vlog (xine_t *this_gen, int buf, const char *format, va_list args) { xine_private_t *this = (xine_private_t *)this_gen; check_log_alloc (this, buf); this->x.log_buffers[buf]->scratch_printf (this->x.log_buffers[buf], format, args); if (this->log_cb) this->log_cb (this->log_cb_user_data, buf); } char *const *xine_get_log (xine_t *this, int buf) { if(buf >= XINE_LOG_NUM) return NULL; if ( this->log_buffers[buf] ) return this->log_buffers[buf]->get_content (this->log_buffers[buf]); else return NULL; } void xine_register_log_cb (xine_t *this_gen, xine_log_cb_t cb, void *user_data) { xine_private_t *this = (xine_private_t *)this_gen; this->log_cb = cb; this->log_cb_user_data = user_data; } int xine_get_error (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; return stream->err; } int xine_stream_master_slave (xine_stream_t *m, xine_stream_t *slave, int affection) { xine_stream_private_t *master = (xine_stream_private_t *)m; master->s.slave = slave; master->slave_affection = affection; /* respect transitivity: if our designated master already has a master * of its own, we point to this master's master; if our master is a * standalone stream, its master pointer will point to itself */ slave->master = master->s.master; _x_select_spu_channel (m, master->s.spu_channel_user); return 1; } int _x_query_buffer_usage(xine_stream_t *stream, int *num_video_buffers, int *num_audio_buffers, int *num_video_frames, int *num_audio_frames) { xine_private_t *xine = (xine_private_t *)stream->xine; int ticket_acquired = -1; { xine_stream_private_t *s = (xine_stream_private_t *)stream; stream = &s->side_streams[0]->s; } if (num_video_buffers) *num_video_buffers = (stream->video_fifo ? stream->video_fifo->size(stream->video_fifo) : 0); if (num_audio_buffers) *num_audio_buffers = (stream->audio_fifo ? stream->audio_fifo->size(stream->audio_fifo) : 0); if ((num_video_frames && stream->video_out) || (num_audio_frames && stream->audio_out)) { ticket_acquired = xine->port_ticket->acquire_nonblocking (xine->port_ticket, 1); } if (num_video_frames) *num_video_frames = ((ticket_acquired && stream->video_out) ? stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_IN_FIFO) : 0); if (num_audio_frames) *num_audio_frames = ((ticket_acquired && stream->audio_out) ? stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_IN_FIFO) : 0); if (ticket_acquired > 0) xine->port_ticket->release_nonblocking (xine->port_ticket, 1); return ticket_acquired != 0; } static void _x_query_buffers_fix_data(xine_query_buffers_data_t *data) { if (data->total < 0) data->total = 0; if (data->ready < 0) data->ready = 0; if (data->avail < 0) data->avail = 0; /* fix race condition of not filling data atomically */ if (data->ready + data->avail > data->total) data->avail = data->total - data->ready; } int _x_query_buffers(xine_stream_t *stream, xine_query_buffers_t *query) { xine_private_t *xine = (xine_private_t *)stream->xine; int ticket_acquired = -1; { xine_stream_private_t *s = (xine_stream_private_t *)stream; stream = &s->side_streams[0]->s; } memset(query, 0, sizeof (*query)); if (stream->video_fifo) { query->vi.total = stream->video_fifo->buffer_pool_capacity; query->vi.ready = stream->video_fifo->size(stream->video_fifo); query->vi.avail = stream->video_fifo->num_free(stream->video_fifo); _x_query_buffers_fix_data(&query->vi); } if (stream->audio_fifo) { query->ai.total = stream->audio_fifo->buffer_pool_capacity; query->ai.ready = stream->audio_fifo->size(stream->audio_fifo); query->ai.avail = stream->audio_fifo->num_free(stream->audio_fifo); _x_query_buffers_fix_data(&query->ai); } if (stream->video_out || stream->audio_out) ticket_acquired = xine->port_ticket->acquire_nonblocking (xine->port_ticket, 1); if (ticket_acquired > 0) { if (stream->video_out) { query->vo.total = stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_TOTAL); query->vo.ready = stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_IN_FIFO); query->vo.avail = stream->video_out->get_property(stream->video_out, VO_PROP_BUFS_FREE); } if (stream->audio_out) { query->ao.total = stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_TOTAL); query->ao.ready = stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_IN_FIFO); query->ao.avail = stream->audio_out->get_property(stream->audio_out, AO_PROP_BUFS_FREE); } xine->port_ticket->release_nonblocking (xine->port_ticket, 1); } return ticket_acquired != 0; } int _x_lock_port_rewiring (xine_t *xine_gen, int ms_timeout) { xine_private_t *xine = (xine_private_t *)xine_gen; return xine->port_ticket->lock_port_rewiring(xine->port_ticket, ms_timeout); } void _x_unlock_port_rewiring (xine_t *xine_gen) { xine_private_t *xine = (xine_private_t *)xine_gen; xine->port_ticket->unlock_port_rewiring(xine->port_ticket); } int _x_lock_frontend (xine_stream_t *s, int ms_to_time_out) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; return lock_timeout (&stream->frontend_lock, ms_to_time_out); } void _x_unlock_frontend (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; pthread_mutex_unlock(&stream->frontend_lock); } int _x_query_unprocessed_osd_events(xine_stream_t *stream) { xine_private_t *xine = (xine_private_t *)stream->xine; video_overlay_manager_t *ovl; int redraw_needed; { xine_stream_private_t *s = (xine_stream_private_t *)stream; stream = &s->side_streams[0]->s; } if (!xine->port_ticket->acquire_nonblocking (xine->port_ticket, 1)) return -1; ovl = stream->video_out->get_overlay_manager(stream->video_out); redraw_needed = ovl->redraw_needed(ovl, 0); if (redraw_needed) stream->video_out->trigger_drawing(stream->video_out); xine->port_ticket->release_nonblocking (xine->port_ticket, 1); return redraw_needed; } int _x_continue_stream_processing (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; return stream->status != XINE_STATUS_STOP && stream->status != XINE_STATUS_QUIT; } void _x_trigger_relaxed_frame_drop_mode (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; pthread_mutex_lock (&stream->first_frame.lock); stream->first_frame.flag = 2; pthread_mutex_unlock (&stream->first_frame.lock); } void _x_reset_relaxed_frame_drop_mode (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; stream = stream->side_streams[0]; pthread_mutex_lock (&stream->first_frame.lock); stream->first_frame.flag = 1; pthread_mutex_unlock (&stream->first_frame.lock); } #define KF_BITS 10 #define KF_SIZE (1 << KF_BITS) #define KF_MASK (KF_SIZE - 1) int xine_keyframes_find (xine_stream_t *s, xine_keyframes_entry_t *pos, int offs) { xine_stream_private_t *stream = (xine_stream_private_t *)s; if (!stream || (&stream->s == XINE_ANON_STREAM) || !pos) return 2; stream = stream->side_streams[0]; pthread_mutex_lock (&stream->index.lock); if (!stream->index.array || !stream->index.used) { pthread_mutex_unlock (&stream->index.lock); return 2; } /* binary search the index */ { xine_keyframes_entry_t *t = stream->index.array; int d, a = 0, e = stream->index.used, m = e >> 1, l; if ((pos->normpos > 0) && (pos->normpos < 0x10000)) { do { d = t[m].normpos - pos->normpos; if (d == 0) break; if (d > 0) e = m; else a = m; l = m; m = (a + e) >> 1; } while (m != l); if ((offs == 0) && (m + 1 < stream->index.used) && (pos->normpos >= ((t[m].normpos + t[m + 1].normpos) >> 1))) m++; } else { do { d = t[m].msecs - pos->msecs; if (d == 0) break; if (d > 0) e = m; else a = m; l = m; m = (a + e) >> 1; } while (m != l); if ((offs == 0) && (m + 1 < stream->index.used) && (pos->msecs >= ((t[m].msecs + t[m + 1].msecs) >> 1))) m++; } e = 0; if ((offs < 0) && (d != 0)) offs++; m += offs; if (m < 0) { m = 0; e = 1; } else if (m >= stream->index.used) { m = stream->index.used - 1; e = 1; } *pos = t[m]; pthread_mutex_unlock (&stream->index.lock); return e; } } int _x_keyframes_add (xine_stream_t *s, xine_keyframes_entry_t *pos) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_keyframes_entry_t *t; stream = stream->side_streams[0]; pthread_mutex_lock (&stream->index.lock); /* first ever entry */ t = stream->index.array; if (!t) { t = calloc (KF_SIZE, sizeof (*t)); if (!t) { pthread_mutex_unlock (&stream->index.lock); return -1; } t[0] = *pos; stream->index.array = t; stream->index.lastadd = 0; stream->index.used = 1; stream->index.size = KF_SIZE; pthread_mutex_unlock (&stream->index.lock); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "keyframes (%p): build index while playing.\n", (void *)stream); return 0; } /* enlarge buf */ if (stream->index.used + 1 >= stream->index.size) { t = realloc (stream->index.array, (stream->index.size + KF_SIZE) * sizeof (*t)); if (!t) { pthread_mutex_unlock (&stream->index.lock); return -1; } stream->index.array = t; stream->index.size += KF_SIZE; } /* binary search seek target */ { /* fast detect the most common "progressive" case */ int d, a = 0, m = stream->index.lastadd, l, e = stream->index.used; if (m + 1 < e) m++; do { d = t[m].msecs - pos->msecs; if (abs (d) < 10) { t[m] = *pos; /* already known */ pthread_mutex_unlock (&stream->index.lock); return m; } if (d > 0) e = m; else a = m; l = m; m = (a + e) >> 1; } while (m != l); if (d < 0) m++; if (m < stream->index.used) /* insert */ memmove (&t[m + 1], &t[m], (stream->index.used - m) * sizeof (*t)); stream->index.used++; stream->index.lastadd = m; t[m] = *pos; pthread_mutex_unlock (&stream->index.lock); return m; } } xine_keyframes_entry_t *xine_keyframes_get (xine_stream_t *s, int *size) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_keyframes_entry_t *ret; if (!stream || (&stream->s == XINE_ANON_STREAM) || !size) return NULL; stream = stream->side_streams[0]; pthread_mutex_lock (&stream->index.lock); if (stream->index.array && stream->index.used) { ret = malloc (stream->index.used * sizeof (xine_keyframes_entry_t)); if (ret) { memcpy (ret, stream->index.array, stream->index.used * sizeof (xine_keyframes_entry_t)); *size = stream->index.used; } } else { ret = NULL; *size = 0; } pthread_mutex_unlock (&stream->index.lock); return ret; } int _x_keyframes_set (xine_stream_t *s, xine_keyframes_entry_t *list, int size) { xine_stream_private_t *stream = (xine_stream_private_t *)s; int n = (size + KF_MASK) & ~KF_MASK; stream = stream->side_streams[0]; pthread_mutex_lock (&stream->index.lock); if (stream->index.array) { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "keyframes (%p): deleting index.\n", (void *)stream); free (stream->index.array); } stream->index.lastadd = 0; stream->index.array = (list && (n > 0)) ? malloc (n * sizeof (xine_keyframes_entry_t)) : NULL; if (!stream->index.array) { stream->index.used = 0; stream->index.size = 0; pthread_mutex_unlock (&stream->index.lock); return 1; } memcpy (stream->index.array, list, size * sizeof (xine_keyframes_entry_t)); stream->index.used = size; stream->index.size = n; n -= size; if (n > 0) memset (stream->index.array + size, 0, n * sizeof (xine_keyframes_entry_t)); pthread_mutex_unlock (&stream->index.lock); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "keyframes (%p): got %d of them.\n", (void *)stream, stream->index.used); return 0; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������xine-lib-1.2/src/xine-engine/io_helper.c������������������������������������������������������������0000644�0001750�0001750�00000053702�14647725152�016002� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2021 the xine project, * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * abortable i/o helper functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/time.h> #include <sys/types.h> #ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> #endif #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> #endif #ifdef HAVE_NETDB_H #include <netdb.h> #endif #include <errno.h> #ifdef _WIN32 #include <winsock2.h> #include <ws2tcpip.h> #endif #include <string.h> #include <xine/io_helper.h> #include "xine_private.h" /* private constants */ #define XIO_POLLING_INTERVAL 50000 /* usec */ /* #define ENABLE_IPV6 */ #ifndef ENABLE_IPV6 static void reportIP (xine_stream_t *stream, const char *text, const uint8_t *p, int port) { if (stream && (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG)) { char b[128], *q = b; xine_uint32_2str (&q, p[0]); *q++ = '.'; xine_uint32_2str (&q, p[1]); *q++ = '.'; xine_uint32_2str (&q, p[2]); *q++ = '.'; xine_uint32_2str (&q, p[3]); *q++ = ':'; xine_uint32_2str (&q, port); *q = 0; xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: %s %s.\n", text, b); } } #else static void reportIP (xine_stream_t *stream, const char *text, struct addrinfo *addr) { if (stream && (stream->xine->verbosity >= XINE_VERBOSITY_DEBUG)) { char b[128], *q = b; if (addr->ai_family == AF_INET) { struct sockaddr_in *sa4 = (struct sockaddr_in *)addr->ai_addr; uint8_t *p = (uint8_t *) &sa4->sin_addr; xine_uint32_2str (&q, p[0]); *q++ = '.'; xine_uint32_2str (&q, p[1]); *q++ = '.'; xine_uint32_2str (&q, p[2]); *q++ = '.'; xine_uint32_2str (&q, p[3]); *q++ = ':'; xine_uint32_2str (&q, ntohs (sa4->sin_port)); } else if (addr->ai_family == AF_INET6) { static const uint8_t tab_hex[16] = "0123456789abcdef"; struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)addr->ai_addr; uint8_t *p = (uint8_t *) &sa6->sin6_addr; int i; *q++ = '['; for (i = 0; i < 16; i += 2) { uint32_t v = ((uint32_t)p[i] << 8) | p[i + 1]; if (v) { if (v & 0xf000) *q++ = tab_hex[v >> 12]; if (v & 0xff00) *q++ = tab_hex[(v >> 8) & 15]; if (v & 0xfff0) *q++ = tab_hex[(v >> 4) & 15]; *q++ = tab_hex[v & 15]; *q++ = ':'; } else { while (q[-2] != ':') *q++ = ':'; } } if (q[-2] != ':') q--; *q++ = ']'; *q++ = ':'; xine_uint32_2str (&q, ntohs (sa6->sin6_port)); } *q = 0; xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: %s %s.\n", text, b); } } #endif /* win32 specific error messages */ #ifdef WIN32 static const char *sock_strerror (int num) { switch (num) { case WSAEACCES: return ("Access denied"); case WSAENETDOWN: return ("Network down"); case WSAENETUNREACH: return ("Network unreachable"); case WSAENETRESET: return ("Network reset"); case WSAECONNABORTED: return ("Connection aborted"); case WSAECONNRESET: return ("Connection reset by peer"); case WSAECONNREFUSED: return ("Connection refused"); case WSAENAMETOOLONG: return ("Name too long"); case WSAEHOSTDOWN: return ("Host down"); case WSAEHOSTUNREACH: return ("Host unreachable"); case WSAHOST_NOT_FOUND: return ("Host not found"); case WSATRY_AGAIN: return ("Try again later"); case WSANO_RECOVERY: return ("Name resolution unavailable"); case WSANO_DATA: return ("No suitable database entry"); case WSAETIMEDOUT: return ("Connection timeout"); default: return (strerror (num)); } } # define sock_errno WSAGetLastError () # define IF_EAGAIN (WSAGetLastError() == WSAEWOULDBLOCK) # define SOCK_EAGAIN WSAEWOULDBLOCK # define SOCK_EINPROGRESS WSAEWOULDBLOCK # define SOCK_ENOENT WSAHOST_NOT_FOUND # define SOCK_EACCES WSAEACCES # define SOCK_ECONNREFUSED WSAECONNREFUSED #else # define sock_strerror strerror # define sock_errno errno # define IF_EAGAIN (errno == EAGAIN) # define SOCK_EAGAIN EAGAIN # define SOCK_EINPROGRESS EINPROGRESS # define SOCK_ENOENT ENOENT # define SOCK_EACCES EACCES # define SOCK_ECONNREFUSED ECONNREFUSED #endif int _x_io_tcp_connect (xine_stream_t *stream, const char *host, int port) { return _x_io_tcp_handshake_connect (stream, host, port, NULL, NULL); } int _x_io_tcp_handshake_connect (xine_stream_t *stream, const char *host, int port, xio_handshake_cb_t *handshake_cb, void *userdata) { #ifndef ENABLE_IPV6 struct hostent *h; int i; #else struct addrinfo hints, *res = NULL, *tmpaddr; int ip_version; #endif xine_private_t *xine = stream ? (xine_private_t *)stream->xine : NULL; int same_retries; /* resolve host ip(s) */ xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "io_helper: resolving %s:%d...\n", host, port); #ifndef ENABLE_IPV6 h = gethostbyname (host); if (h == NULL) { int e = sock_errno; xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "io_helper: gethostbyname: %s (%d).\n", sock_strerror (e), e); _x_message (stream, XINE_MSG_UNKNOWN_HOST, "unable to resolve", host, sock_strerror (e), NULL); return -1; } /* report found ip's */ for (i = 0; h->h_addr_list[i]; i++) reportIP (stream, "found IP", h->h_addr_list[i], port); #else memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_family = PF_UNSPEC; { char strport[32], *q = strport; int r; xine_uint32_2str (&q, port); r = getaddrinfo (host, strport, &hints, &res); if (r != 0) { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "io_helper: getaddrinfo: %s (%d).\n", gai_strerror (r), r); _x_message (stream, XINE_MSG_UNKNOWN_HOST, "unable to resolve", host, gai_strerror (r), NULL); return -1; } /* report ip's */ for (tmpaddr = res; tmpaddr; tmpaddr = tmpaddr->ai_next) reportIP (stream, "found IP", tmpaddr); } if (xine) { static const uint8_t modes[4] = {0, 4, (6 << 4) | 4, (4 << 4) | 6}; ip_version = modes[xine->ip_pref & 3]; } else { ip_version = 4; } #endif /* try to connect ip's */ same_retries = 5; #ifndef ENABLE_IPV6 i = 0; #else tmpaddr = res; #endif while (1) { xio_handshake_status_t status = XIO_HANDSHAKE_OK; int s; #ifndef ENABLE_IPV6 if (!h->h_addr_list[i]) break; #else if (!tmpaddr) { ip_version >>= 4; if (ip_version) { tmpaddr = res; continue; } break; } if (ip_version) { if (((ip_version & 15) == 4) == (tmpaddr->ai_family != AF_INET)) { tmpaddr = tmpaddr->ai_next; continue; } } #endif do { int r; /* make socket */ #ifndef ENABLE_IPV6 s = xine_socket_cloexec (PF_INET, SOCK_STREAM, IPPROTO_TCP); #else s = xine_socket_cloexec (tmpaddr->ai_family, SOCK_STREAM, IPPROTO_TCP); #endif if (s == -1) { int e = sock_errno; xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "io_helper: socket: %s (%d).\n", sock_strerror (e), e); _x_message (stream, XINE_MSG_CONNECTION_REFUSED, "failed to create socket", sock_strerror (e), NULL); /* XXX: does it make sense to retry this? */ status = XIO_HANDSHAKE_INTR; break; } /* try to turn off blocking, but dont require that. * main io will work the same with and without, only connect () and close () may hang. */ #ifndef WIN32 if (fcntl (s, F_SETFL, fcntl (s, F_GETFL) | O_NONBLOCK) == -1) #else { unsigned long non_block = 1; r = ioctlsocket (s, FIONBIO, &non_block); } if (r == SOCKET_ERROR) #endif { int e = sock_errno; xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "io_helper: connect: %s (%d).\n", sock_strerror (e), e); _x_message (stream, XINE_MSG_CONNECTION_REFUSED, "can't put socket in non-blocking mode", sock_strerror (e), NULL); } /* connect now */ #ifndef ENABLE_IPV6 { struct in_addr ia; union { struct sockaddr_in sin; struct sockaddr addr; } a; reportIP (stream, "connecting", h->h_addr_list[i], port); memcpy (&ia, h->h_addr_list[i], 4); a.sin.sin_family = AF_INET; a.sin.sin_addr = ia; a.sin.sin_port = htons (port); r = connect (s, &a.addr, sizeof (a.sin)); } #else reportIP (stream, "connecting", tmpaddr); r = connect (s, tmpaddr->ai_addr, tmpaddr->ai_addrlen); #endif if (r == -1) { int e = sock_errno; if (e != SOCK_EINPROGRESS) { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "io_helper: socket: %s (%d).\n", sock_strerror (e), e); _x_message (stream, XINE_MSG_CONNECTION_REFUSED, host, sock_strerror (e), NULL); status = XIO_HANDSHAKE_TRY_NEXT; break; } } #if 1 /* yes _x_io_tcp_connect_finish () does this below. * however, if there are more IPs we can try, test this one now * before we discard any alternatives. * handshake_cb will also need this. */ # ifndef ENABLE_IPV6 if (stream && (handshake_cb || h->h_addr_list[i + 1])) # else if (stream && (handshake_cb || tmpaddr->ai_next)) # endif { r = _x_io_select (stream, s, XIO_WRITE_READY, xine ? xine->network_timeout * 1000 : 30000); if (r == XIO_ABORTED) { status = XIO_HANDSHAKE_INTR; break; } if (r != XIO_READY) { status = XIO_HANDSHAKE_TRY_NEXT; break; } { int e; socklen_t len = sizeof (e); if ((getsockopt (s, SOL_SOCKET, SO_ERROR, &e, &len)) == -1) e = sock_errno; if (e) { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "io_helper: getsockopt: %s (%d).\n", sock_strerror (e), e); status = XIO_HANDSHAKE_TRY_NEXT; break; } } } #endif } while (0); if ((status == XIO_HANDSHAKE_OK) && handshake_cb) status = handshake_cb (userdata, s); if (status == XIO_HANDSHAKE_OK) { /* done */ #ifdef ENABLE_IPV6 freeaddrinfo (res); #endif return s; } if (s >= 0) _x_io_tcp_close (NULL, s); if (status == XIO_HANDSHAKE_INTR) break; if (status == XIO_HANDSHAKE_TRY_SAME) { if (--same_retries <= 0) { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "_x_io_tcp_handshake_connect: too many XIO_HANDSHAKE_TRY_SAME, skipping.\n"); status = XIO_HANDSHAKE_TRY_NEXT; } } if (status == XIO_HANDSHAKE_TRY_NEXT) { same_retries = 5; #ifndef ENABLE_IPV6 i++; #else tmpaddr = tmpaddr->ai_next; #endif } else if (status != XIO_HANDSHAKE_TRY_SAME) { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "_x_io_tcp_handshake_connect: unknown handshake status %d, leaving.\n", (int)status); break; } } #ifdef ENABLE_IPV6 freeaddrinfo (res); #endif return -1; } int _x_io_select (xine_stream_t *stream, int fd, int state, int timeout_msec) { int timeout_usec, total_time_usec; int ret; #ifdef WIN32 HANDLE h; DWORD dwret; char msg[256]; #endif #ifdef WIN32 /* handle console file descriptiors differently on Windows */ switch (fd) { case STDIN_FILENO: h = GetStdHandle(STD_INPUT_HANDLE); break; case STDOUT_FILENO: h = GetStdHandle(STD_OUTPUT_HANDLE); break; case STDERR_FILENO: h = GetStdHandle(STD_ERROR_HANDLE); break; default: h = INVALID_HANDLE_VALUE; } #endif timeout_usec = 1000 * timeout_msec; total_time_usec = 0; #ifdef WIN32 if (h != INVALID_HANDLE_VALUE) { while (total_time_usec < timeout_usec) { dwret = WaitForSingleObject(h, timeout_msec); switch (dwret) { case WAIT_OBJECT_0: return XIO_READY; case WAIT_TIMEOUT: /* select timeout * aborts current read if action pending. otherwise xine * cannot be stopped when no more data is available. */ if (_x_action_pending (stream)) return XIO_ABORTED; break; case WAIT_ABANDONED: if (stream) xine_log(stream->xine, XINE_LOG_MSG, _("io_helper: waiting abandoned\n")); return XIO_ERROR; case WAIT_FAILED: default: dwret = GetLastError(); FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, (LPSTR)&msg, sizeof(msg), NULL); if (stream) xine_log(stream->xine, XINE_LOG_MSG, _("io_helper: waiting failed: %s\n"), msg); return XIO_ERROR; } } if (_x_action_pending (stream)) { errno = EINTR; return XIO_ABORTED; } total_time_usec += XIO_POLLING_INTERVAL; return XIO_TIMEOUT; } #endif if (timeout_msec == 0) { struct timeval select_timeout = {0, 0}; fd_set fdset; fd_set *rset, *wset; if (_x_action_pending (stream)) { errno = EINTR; return XIO_ABORTED; } FD_ZERO (&fdset); if (fd >= 0) { FD_SET (fd, &fdset); } rset = (state & XIO_READ_READY) ? &fdset : NULL; wset = (state & XIO_WRITE_READY) ? &fdset : NULL; ret = select (fd + 1, rset, wset, NULL, &select_timeout); if (ret == -1 && errno != EINTR) { /* select error */ return XIO_ERROR; } else if (ret == 1) { /* fd is ready */ return XIO_READY; } return XIO_TIMEOUT; } while (total_time_usec < timeout_usec) { struct timeval select_timeout = {0, XIO_POLLING_INTERVAL}; fd_set fdset; fd_set *rset, *wset; FD_ZERO (&fdset); if (fd >= 0) { FD_SET (fd, &fdset); } rset = (state & XIO_READ_READY) ? &fdset : NULL; wset = (state & XIO_WRITE_READY) ? &fdset : NULL; ret = select (fd + 1, rset, wset, NULL, &select_timeout); if (ret == -1 && errno != EINTR) { /* select error */ return XIO_ERROR; } else if (ret == 1) { /* fd is ready */ return XIO_READY; } /* select timeout * aborts current read if action pending. otherwise xine * cannot be stopped when no more data is available. */ if (_x_action_pending (stream)) { errno = EINTR; return XIO_ABORTED; } total_time_usec += XIO_POLLING_INTERVAL; } return XIO_TIMEOUT; } /* * wait for finish connection */ int _x_io_tcp_connect_finish (xine_stream_t *stream, int fd, int timeout_msec) { int r; r = _x_io_select (stream, fd, XIO_WRITE_READY, timeout_msec); if (r == XIO_READY) { /* find out, if connection is successfull */ int e; socklen_t len = sizeof (e); if ((getsockopt (fd, SOL_SOCKET, SO_ERROR, &e, &len)) == -1) { e = sock_errno; if (stream) xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: getsockopt: %s (%d).\n", sock_strerror (e), e); _x_message (stream, XINE_MSG_CONNECTION_REFUSED, _("failed to get status of socket"), sock_strerror (e), NULL); return XIO_ERROR; } if (e) { if (stream) xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: getsockopt: %s (%d).\n", sock_strerror (e), e); _x_message (stream, XINE_MSG_CONNECTION_REFUSED, sock_strerror (e), NULL); return XIO_ERROR; } } return r; } static off_t xio_err (xine_stream_t *stream, int ret) { /* non-blocking mode */ int e = sock_errno; if (stream) xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: getsockopt: %s (%d).\n", sock_strerror (e), e); if (e == SOCK_EACCES) { _x_message (stream, XINE_MSG_PERMISSION_ERROR, NULL, NULL); if (stream) xine_log (stream->xine, XINE_LOG_MSG, _("io_helper: Permission denied\n")); } else if (e == SOCK_ENOENT) { _x_message (stream, XINE_MSG_FILE_NOT_FOUND, NULL, NULL); if (stream) xine_log (stream->xine, XINE_LOG_MSG, _("io_helper: File not found\n")); } else if (e == SOCK_ECONNREFUSED) { _x_message (stream, XINE_MSG_CONNECTION_REFUSED, NULL, NULL); if (stream) xine_log (stream->xine, XINE_LOG_MSG, _("io_helper: Connection Refused\n")); } return ret; } off_t _x_io_tcp_read (xine_stream_t *stream, int s, void *buf_gen, off_t todo) { uint8_t *buf = buf_gen; unsigned int timeout; size_t want = todo, have = 0; _x_assert(buf != NULL); if (stream) { xine_private_t *xine = (xine_private_t *)stream->xine; timeout = xine->network_timeout * 1000; } else { timeout = 30000; /* 30K msecs = 30 secs */ } while (have < want) { ssize_t ret; ret = _x_io_select (stream, s, XIO_READ_READY, timeout); if (ret != XIO_READY) return -1; ret = recv (s, buf + have, want - have, 0); /* check EOF */ if (!ret) break; /* check errors */ if (ret < 0) { if (IF_EAGAIN) continue; return xio_err (stream, ret); } have += ret; } return have; } ssize_t _x_io_tcp_part_read (xine_stream_t *stream, int s, void *buf_gen, size_t min, size_t max) { uint8_t *buf = buf_gen; unsigned int timeout; size_t have = 0; _x_assert(buf != NULL); if (stream) { xine_private_t *xine = (xine_private_t *)stream->xine; timeout = xine->network_timeout * 1000; } else { timeout = 30000; /* 30K msecs = 30 secs */ } if (min == 0) { ssize_t ret = _x_io_select (stream, s, XIO_READ_READY, 0); if (ret != XIO_READY) { errno = ret == XIO_TIMEOUT ? EAGAIN : EINTR; return -1; } ret = recv (s, buf, max, 0); if (ret < 0) { if (!IF_EAGAIN) return xio_err (stream, ret); errno = EAGAIN; } return ret; } while (have < min) { ssize_t ret; ret = _x_io_select (stream, s, XIO_READ_READY, timeout); if (ret != XIO_READY) return -1; ret = recv (s, buf + have, max - have, 0); /* check EOF */ if (!ret) break; /* check errors */ if (ret < 0) { if (IF_EAGAIN) continue; return xio_err (stream, ret); } have += ret; } return have; } off_t _x_io_tcp_write (xine_stream_t *stream, int s, const void *wbuf_gen, off_t todo) { const uint8_t *wbuf = wbuf_gen; unsigned int timeout; size_t have = 0, want = todo; _x_assert (wbuf != NULL); if (stream) { xine_private_t *xine = (xine_private_t *)stream->xine; timeout = xine->network_timeout * 1000; } else { timeout = 30000; /* 30K msecs = 30 secs */ } while (have < want) { ssize_t ret; ret = _x_io_select (stream, s, XIO_WRITE_READY, timeout); if (ret != XIO_READY) return -1; ret = send (s, wbuf + have, want - have, 0); /* check EOF */ if (!ret) break; /* check errors */ if (ret < 0) { if (IF_EAGAIN) continue; return xio_err (stream, ret); } have += ret; } return have; } off_t _x_io_file_read (xine_stream_t *stream, int s, void *buf_gen, off_t todo) { uint8_t *buf = buf_gen; unsigned int timeout; size_t have = 0, want = todo; _x_assert(buf != NULL); if (stream) { xine_private_t *xine = (xine_private_t *)stream->xine; timeout = xine->network_timeout * 1000; } else { timeout = 30000; /* 30K msecs = 30 secs */ } while (have < want) { ssize_t ret; ret = _x_io_select (stream, s, XIO_READ_READY, timeout); if (ret != XIO_READY) return -1; ret = read (s, buf + have, want - have); /* check EOF */ if (!ret) break; /* check errors */ if (ret < 0) { if (IF_EAGAIN) continue; return xio_err (stream, ret); } have += ret; } return have; } off_t _x_io_file_write (xine_stream_t *stream, int s, const void *wbuf_gen, off_t todo) { const uint8_t *wbuf = wbuf_gen; unsigned int timeout; size_t have = 0, want = todo; _x_assert (wbuf != NULL); if (stream) { xine_private_t *xine = (xine_private_t *)stream->xine; timeout = xine->network_timeout * 1000; } else { timeout = 30000; /* 30K msecs = 30 secs */ } while (have < want) { ssize_t ret; ret = _x_io_select (stream, s, XIO_WRITE_READY, timeout); if (ret != XIO_READY) return -1; ret = write (s, wbuf + have, want - have); /* check EOF */ if (!ret) break; /* check errors */ if (ret < 0) { if (IF_EAGAIN) continue; return xio_err (stream, ret); } have += ret; } return have; } /* * read a string from socket, return string length (same as strlen) * the string is always '\0' terminated but given buffer size is never exceeded * that is, _x_io_tcp_read_line(,,,X) <= (X-1) ; X > 0 */ int _x_io_tcp_read_line(xine_stream_t *stream, int sock, char *str, int size) { int i = 0; char c; off_t r; if( size <= 0 ) return 0; while ((r = _x_io_tcp_read (stream, sock, &c, 1)) == 1) { if (c == '\r' || c == '\n') break; if (i+1 == size) break; str[i] = c; i++; } if (r == 1 && c == '\r') r = _x_io_tcp_read (stream, sock, &c, 1); str[i] = '\0'; return (r != -1) ? i : (int)r; } int _x_io_tcp_close(xine_stream_t *stream, int fd) { struct linger linger = { 0, 0 }; int r; if (fd == -1) { errno = EINVAL; return -1; } /* disable lingering (hard close) */ r = setsockopt(fd, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof(linger)); if (r < 0 && stream) { int e = sock_errno; xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: disable linger: %s (%d).\n", sock_strerror (e), e); } #ifdef WIN32 r = closesocket(fd); #else r = close(fd); #endif if (r < 0 && stream) { int e = sock_errno; xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "io_helper: close: %s (%d).\n", sock_strerror (e), e); } return r; } ��������������������������������������������������������������xine-lib-1.2/src/xine-engine/xine_interface.c�������������������������������������������������������0000644�0001750�0001750�00000117417�14647725152�017023� 0����������������������������������������������������������������������������������������������������ustar �me������������������������������me���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * convenience/abstraction layer, functions to implement * libxine's public interface */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <sys/types.h> #include <string.h> #include <stdlib.h> #include <pthread.h> #include <stdarg.h> #if defined (__linux__) || defined (__GLIBC__) #include <endian.h> #elif defined (__FreeBSD__) #include <machine/endian.h> #endif #include <xine/xine_internal.h> #include <xine/audio_out.h> #include <xine/video_out.h> #include <xine/demux.h> #include <xine/post.h> #include "xine_private.h" /* * version information / checking */ const char *xine_get_version_string(void) { return VERSION #ifndef NDEBUG "[DEBUG]" #endif ; } void xine_get_version (int *major, int *minor, int *sub) { *major = XINE_MAJOR; *minor = XINE_MINOR; *sub = XINE_SUB; } int xine_check_version(int major, int minor, int sub) { if((XINE_MAJOR > major) || ((XINE_MAJOR == major) && (XINE_MINOR > minor)) || ((XINE_MAJOR == major) && (XINE_MINOR == minor) && (XINE_SUB >= sub))) return 1; return 0; } /* * public config object access functions */ const char* xine_config_register_string (xine_t *self, const char *key, const char *def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { return self->config->register_string (self->config, key, def_value, description, help, exp_level, changed_cb, cb_data); } const char* xine_config_register_filename (xine_t *self, const char *key, const char *def_value, int req_type, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { return self->config->register_filename (self->config, key, def_value, req_type, description, help, exp_level, changed_cb, cb_data); } int xine_config_register_range (xine_t *self, const char *key, int def_value, int min, int max, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { return self->config->register_range (self->config, key, def_value, min, max, description, help, exp_level, changed_cb, cb_data); } int xine_config_register_enum (xine_t *self, const char *key, int def_value, char **values, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { return self->config->register_enum (self->config, key, def_value, values, description, help, exp_level, changed_cb, cb_data); } int xine_config_register_num (xine_t *self, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { return self->config->register_num (self->config, key, def_value, description, help, exp_level, changed_cb, cb_data); } int xine_config_register_bool (xine_t *self, const char *key, int def_value, const char *description, const char *help, int exp_level, xine_config_cb_t changed_cb, void *cb_data) { return self->config->register_bool (self->config, key, def_value, description, help, exp_level, changed_cb, cb_data); } int xine_config_unregister_callbacks (xine_t *self, const char *key, xine_config_cb_t changed_cb, void *cb_data, size_t cb_data_size) { /* avoid misuse */ if (!key && !changed_cb && !cb_data) return 0; if (!self) return 0; if (!self->config) return 0; return self->config->unregister_callbacks (self->config, key, changed_cb, cb_data, cb_data_size); } int xine_config_lookup_num(xine_t *this, const char *key, int def_value) { return this->config->lookup_num(this->config, key, def_value); } char *xine_config_lookup_string(xine_t *this, const char *key) { return this->config->lookup_string(this->config, key); } void xine_config_free_string(xine_t *this, char **value) { this->config->free_string(this->config, value); } /* * helper function: * * copy current config entry data to user-provided memory * and return status */ static int config_get_current_entry (xine_t *this, xine_cfg_entry_t *entry) { config_values_t *config = this->config; if (!config->cur) return 0; entry->key = config->cur->key; entry->type = config->cur->type; entry->str_value = config->cur->str_value; entry->str_default = config->cur->str_default; entry->num_value = config->cur->num_value; entry->num_default = config->cur->num_default; entry->range_min = config->cur->range_min; entry->range_max = config->cur->range_max; entry->enum_values = config->cur->enum_values; entry->description = config->cur->description; entry->help = config->cur->help; entry->callback = config->cur->callback; entry->callback_data = config->cur->callback_data; entry->exp_level = config->cur->exp_level; return 1; } /* * get first config item */ int xine_config_get_first_entry (xine_t *this, xine_cfg_entry_t *entry) { int result; config_values_t *config = this->config; pthread_mutex_lock(&config->config_lock); config->cur = config->first; /* do not hand out unclaimed entries */ while (config->cur && config->cur->type == XINE_CONFIG_TYPE_UNKNOWN) config->cur = config->cur->next; result = config_get_current_entry (this, entry); pthread_mutex_unlock(&config->config_lock); return result; } /* * get next config item (iterate through the items) * this will return NULL when called after returning the last item */ int xine_config_get_next_entry (xine_t *this, xine_cfg_entry_t *entry) { int result; config_values_t *config = this->config; pthread_mutex_lock(&config->config_lock); if (!config->cur) { pthread_mutex_unlock(&config->config_lock); return (xine_config_get_first_entry(this, entry)); } /* do not hand out unclaimed entries */ do { config->cur = config->cur->next; } while (config->cur && config->cur->type == XINE_CONFIG_TYPE_UNKNOWN); result = config_get_current_entry (this, entry); pthread_mutex_unlock(&config->config_lock); return result; } /* * search for a config entry by key */ int xine_config_lookup_entry (xine_t *this, const char *key, xine_cfg_entry_t *entry) { int result; config_values_t *config = this->config; pthread_mutex_lock(&config->config_lock); /* safe because of the mutex is recursive */ config->cur = config->lookup_entry (config, key); /* do not hand out unclaimed entries */ if (config->cur && config->cur->type == XINE_CONFIG_TYPE_UNKNOWN) config->cur = NULL; result = config_get_current_entry (this, entry); pthread_mutex_unlock(&config->config_lock); return result; } /* * update a config entry (which was returned from lookup_entry() ) */ void xine_config_update_entry (xine_t *this, const xine_cfg_entry_t *entry) { switch (entry->type) { case XINE_CONFIG_TYPE_RANGE: case XINE_CONFIG_TYPE_ENUM: case XINE_CONFIG_TYPE_NUM: case XINE_CONFIG_TYPE_BOOL: this->config->update_num (this->config, entry->key, entry->num_value); break; case XINE_CONFIG_TYPE_STRING: this->config->update_string (this->config, entry->key, entry->str_value); break; default: xprintf (this, XINE_VERBOSITY_DEBUG, "xine_interface: error, unknown config entry type %d\n", entry->type); break; } } void xine_config_reset (xine_t *this) { config_values_t *config = this->config; cfg_entry_t *entry; pthread_mutex_lock(&config->config_lock); config->cur = NULL; entry = config->first; while (entry) { cfg_entry_t *next; next = entry->next; free (entry); entry = next; } config->first = NULL; config->last = NULL; pthread_mutex_unlock(&config->config_lock); } int xine_port_send_gui_data (xine_video_port_t *vo, int type, void *data) { return vo->driver->gui_data_exchange (vo->driver, type, data); } static void send_audio_amp_event_internal (xine_stream_private_t *stream) { xine_event_t event; xine_audio_level_data_t data; data.left = data.right = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP); data.mute = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP_MUTE); event.type = XINE_EVENT_AUDIO_AMP_LEVEL; event.data = &data; event.data_length = sizeof (data); xine_event_send (&stream->s, &event); } #if 0 NOTE: the next few tables are more or less made with a web browser showing this: <html> <head> <title>xine audio level conversion DUMMY
#endif void xine_set_param (xine_stream_t *s, int param, int value) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_private_t *xine; /* Avoid crashing */ if ( ! stream ) { lprintf ("xine_interface: xine_set_param called with NULL stream.\n"); return; } xine = (xine_private_t *)stream->s.xine; switch (param) { case XINE_PARAM_SPEED: pthread_mutex_lock (&stream->side_streams[0]->frontend_lock); _x_set_speed (&stream->s, value); pthread_mutex_unlock (&stream->side_streams[0]->frontend_lock); break; case XINE_PARAM_FINE_SPEED: pthread_mutex_lock (&stream->side_streams[0]->frontend_lock); _x_set_fine_speed (&stream->s, value); pthread_mutex_unlock (&stream->side_streams[0]->frontend_lock); break; case XINE_PARAM_AV_OFFSET: stream->s.metronom->set_option (stream->s.metronom, METRONOM_AV_OFFSET, value); break; case XINE_PARAM_SPU_OFFSET: stream->s.metronom->set_option (stream->s.metronom, METRONOM_SPU_OFFSET, value); break; case XINE_PARAM_AUDIO_CHANNEL_LOGICAL: pthread_mutex_lock (&stream->side_streams[0]->frontend_lock); if (value < -2) value = -2; stream->audio_channel_user = value; pthread_mutex_unlock (&stream->side_streams[0]->frontend_lock); break; case XINE_PARAM_SPU_CHANNEL: _x_select_spu_channel (&stream->s, value); break; case XINE_PARAM_VIDEO_CHANNEL: pthread_mutex_lock (&stream->side_streams[0]->frontend_lock); if (value<0) value = 0; stream->video_channel = value; pthread_mutex_unlock (&stream->side_streams[0]->frontend_lock); break; case XINE_PARAM_AUDIO_VOLUME: xine->port_ticket->acquire (xine->port_ticket, 1); if (stream->s.audio_out) stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_MIXER_VOL, value); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_MUTE: xine->port_ticket->acquire (xine->port_ticket, 1); if (stream->s.audio_out) stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_MUTE_VOL, value); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_COMPR_LEVEL: xine->port_ticket->acquire (xine->port_ticket, 1); if (stream->s.audio_out) stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_COMPRESSOR, value); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_AMP_LEVEL: if (xine->audio_lin_levels) { static const uint8_t tab_lin_log_10[201] = { 0, 60, 66, 70, 72, 74, 76, 77, 78, 79, 80, 81, 82, 82, 83, 84, 84, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 90, 91, 91, 91, 91, 92, 92, 92, 92, 92, 93, 93, 93, 93, 93, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 97, 97, 97, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,100,100,100,100,100, 100,100,100,100,100,100,101,101,101,101, 101,101,101,101,101,101,101,101,101,102, 102,102,102,102,102,102,102,102,102,102, 102,102,102,102,103,103,103,103,103,103, 103,103,103,103,103,103,103,103,103,103, 104,104,104,104,104,104,104,104,104,104, 104,104,104,104,104,104,104,104,104,105, 105,105,105,105,105,105,105,105,105,105, 105,105,105,105,105,105,105,105,105,106, 106,106,106,106,106,106,106,106,106,106, 106 }; value = (value < 0) ? 0 : (value > 200) ? 112 : tab_lin_log_10[value]; } xine->port_ticket->acquire (xine->port_ticket, 1); if (stream->s.audio_out) { int old_value = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP); if (old_value != stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_AMP, value)) send_audio_amp_event_internal (stream); } xine->port_ticket->release(xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_AMP_MUTE: xine->port_ticket->acquire (xine->port_ticket, 1); if (stream->s.audio_out) { int old_value = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP_MUTE); if (old_value != stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_AMP_MUTE, value)) send_audio_amp_event_internal(stream); } xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_CLOSE_DEVICE: xine->port_ticket->acquire (xine->port_ticket, 1); if (stream->s.audio_out) stream->s.audio_out->set_property (stream->s.audio_out, AO_PROP_CLOSE_DEVICE, value); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_EQ_30HZ: case XINE_PARAM_EQ_60HZ: case XINE_PARAM_EQ_125HZ: case XINE_PARAM_EQ_250HZ: case XINE_PARAM_EQ_500HZ: case XINE_PARAM_EQ_1000HZ: case XINE_PARAM_EQ_2000HZ: case XINE_PARAM_EQ_4000HZ: case XINE_PARAM_EQ_8000HZ: case XINE_PARAM_EQ_16000HZ: if (xine->audio_lin_levels) { static const uint8_t tab_lin_log_05[201] = { 0, 20, 32, 39, 44, 48, 51, 54, 56, 58, 60, 62, 63, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 77, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 90, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 94, 94, 94, 94, 95, 95, 95, 95, 95, 96, 96, 96, 96, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 99, 99, 99, 99, 99, 99,100,100, 100,100,100,101,101,101,101,101,101,101, 102,102,102,102,102,102,103,103,103,103, 103,103,103,104,104,104,104,104,104,104, 105,105,105,105,105,105,105,105,106,106, 106,106,106,106,106,106,107,107,107,107, 107,107,107,107,107,108,108,108,108,108, 108,108,108,108,109,109,109,109,109,109, 109,109,109,109,110,110,110,110,110,110, 110,110,110,110,111,111,111,111,111,111, 111,111,111,111,111,112,112,112,112,112, 112 }; value = (value < 0) ? 0 : (value > 200) ? 112 : tab_lin_log_05[value]; } xine->port_ticket->acquire (xine->port_ticket, 1); if (stream->s.audio_out) stream->s.audio_out->set_property (stream->s.audio_out, param - XINE_PARAM_EQ_30HZ + AO_PROP_EQ_30HZ, value); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_VERBOSITY: stream->s.xine->verbosity = value; break; case XINE_PARAM_VO_SHARPNESS: case XINE_PARAM_VO_NOISE_REDUCTION: case XINE_PARAM_VO_HUE: case XINE_PARAM_VO_SATURATION: case XINE_PARAM_VO_CONTRAST: case XINE_PARAM_VO_BRIGHTNESS: case XINE_PARAM_VO_GAMMA: case XINE_PARAM_VO_DEINTERLACE: case XINE_PARAM_VO_ASPECT_RATIO: case XINE_PARAM_VO_ZOOM_X: case XINE_PARAM_VO_ZOOM_Y: case XINE_PARAM_VO_TVMODE: case XINE_PARAM_VO_CROP_LEFT: case XINE_PARAM_VO_CROP_RIGHT: case XINE_PARAM_VO_CROP_TOP: case XINE_PARAM_VO_CROP_BOTTOM: case XINE_PARAM_VO_TRANSFORM: xine->port_ticket->acquire (xine->port_ticket, 1); stream->s.video_out->set_property (stream->s.video_out, param, value); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_VO_SINGLE_STEP: pthread_mutex_lock (&stream->side_streams[0]->frontend_lock); if (_x_get_fine_speed (&stream->s) != XINE_SPEED_PAUSE) { _x_set_fine_speed (&stream->s, XINE_SPEED_PAUSE); } else { /* HACK: temporarily resume decoders. */ _x_set_fine_speed (&stream->s, XINE_LIVE_PAUSE_ON); /* rather miss 1 strobe than wait or freeze. */ if (xine->port_ticket->ticket_revoked == 0) { xine->port_ticket->acquire (xine->port_ticket, 1); stream->s.video_out->set_property (stream->s.video_out, param, value); stream->s.audio_out->set_property (stream->s.audio_out, param, value); xine->port_ticket->release (xine->port_ticket, 1); } } pthread_mutex_unlock (&stream->side_streams[0]->frontend_lock); break; case XINE_PARAM_IGNORE_VIDEO: _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_VIDEO, value); break; case XINE_PARAM_IGNORE_AUDIO: _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_AUDIO, value); break; case XINE_PARAM_IGNORE_SPU: _x_stream_info_set (&stream->s, XINE_STREAM_INFO_IGNORE_SPU, value); break; case XINE_PARAM_METRONOM_PREBUFFER: stream->s.metronom->set_option (stream->s.metronom, METRONOM_PREBUFFER, value); break; case XINE_PARAM_BROADCASTER_PORT: if( !stream->broadcaster && value ) { stream->broadcaster = _x_init_broadcaster (&stream->s, value); } else if ( stream->broadcaster && !value ) { _x_close_broadcaster(stream->broadcaster); stream->broadcaster = NULL; } break; case XINE_PARAM_EARLY_FINISHED_EVENT: stream->early_finish_event = !!value; break; case XINE_PARAM_DELAY_FINISHED_EVENT: xine_rwlock_wrlock (&stream->side_streams[0]->info_lock); stream->delay_finish_event = value; xine_rwlock_unlock (&stream->side_streams[0]->info_lock); break; case XINE_PARAM_GAPLESS_SWITCH: stream->gapless_switch = !!value; if( stream->gapless_switch && !stream->early_finish_event ) { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "frontend possibly buggy: gapless_switch without early_finish_event\n"); } break; default: xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "xine_interface: unknown or deprecated stream param %d set\n", param); } } int xine_get_param (xine_stream_t *s, int param) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_private_t *xine; int ret; /* Avoid crashing */ if ( ! stream ) { lprintf ("xine_interface: xine_set_param called with NULL stream.\n"); return 0; } xine = (xine_private_t *)stream->s.xine; switch (param) { case XINE_PARAM_SPEED: ret = _x_get_speed (&stream->s); break; case XINE_PARAM_FINE_SPEED: ret = _x_get_fine_speed (&stream->s); break; case XINE_PARAM_AV_OFFSET: ret = stream->s.metronom->get_option (stream->s.metronom, METRONOM_AV_OFFSET); break; case XINE_PARAM_SPU_OFFSET: ret = stream->s.metronom->get_option (stream->s.metronom, METRONOM_SPU_OFFSET); break; case XINE_PARAM_AUDIO_CHANNEL_LOGICAL: ret = stream->audio_channel_user; break; case XINE_PARAM_SPU_CHANNEL: ret = stream->s.spu_channel_user; break; case XINE_PARAM_VIDEO_CHANNEL: ret = stream->video_channel; break; case XINE_PARAM_AUDIO_VOLUME: xine->port_ticket->acquire (xine->port_ticket, 1); if (!stream->s.audio_out) ret = -1; else ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_MIXER_VOL); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_MUTE: xine->port_ticket->acquire (xine->port_ticket, 1); if (!stream->s.audio_out) ret = -1; else ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_MUTE_VOL); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_COMPR_LEVEL: xine->port_ticket->acquire (xine->port_ticket, 1); if (!stream->s.audio_out) ret = -1; else ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_COMPRESSOR); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_AUDIO_AMP_LEVEL: xine->port_ticket->acquire (xine->port_ticket, 1); if (!stream->s.audio_out) ret = -1; else ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP); xine->port_ticket->release (xine->port_ticket, 1); if (xine->audio_lin_levels && (ret >= 0)) { static const uint8_t tab_log_10_lin[108 - 54] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11, 13, 14, 16, 18, 20, 22, 25, 28, 31, 35, 40, 45, 50, 56, 63, 71, 79, 89, 100,112,126,141,159,178,200 }; ret = (ret < 54) ? 0 : (ret > 107) ? 200 : tab_log_10_lin[ret - 54]; } break; case XINE_PARAM_AUDIO_AMP_MUTE: xine->port_ticket->acquire (xine->port_ticket, 1); if (!stream->s.audio_out) ret = -1; else ret = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_AMP_MUTE); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_EQ_30HZ: case XINE_PARAM_EQ_60HZ: case XINE_PARAM_EQ_125HZ: case XINE_PARAM_EQ_250HZ: case XINE_PARAM_EQ_500HZ: case XINE_PARAM_EQ_1000HZ: case XINE_PARAM_EQ_2000HZ: case XINE_PARAM_EQ_4000HZ: case XINE_PARAM_EQ_8000HZ: case XINE_PARAM_EQ_16000HZ: xine->port_ticket->acquire (xine->port_ticket, 1); if (!stream->s.audio_out) ret = -1; else ret= stream->s.audio_out->get_property (stream->s.audio_out, param - XINE_PARAM_EQ_30HZ + AO_PROP_EQ_30HZ); xine->port_ticket->release (xine->port_ticket, 1); if (xine->audio_lin_levels && (ret >= 0)) { static const uint8_t tab_log_05_lin[113 - 8] = { 0, 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, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 24, 25, 26, 28, 30, 31, 33, 35, 37, 40, 42, 45, 47, 50, 53, 56, 59, 63, 67, 71, 75, 79, 84, 89, 94, 100,106,112,119,126,133,141,150,159,168, 178,189,200 }; ret = (ret < 8) ? 0 : (ret > 112) ? 200 : tab_log_05_lin[ret - 8]; } break; case XINE_PARAM_VERBOSITY: ret = stream->s.xine->verbosity; break; case XINE_PARAM_VO_SHARPNESS: case XINE_PARAM_VO_NOISE_REDUCTION: case XINE_PARAM_VO_HUE: case XINE_PARAM_VO_SATURATION: case XINE_PARAM_VO_CONTRAST: case XINE_PARAM_VO_BRIGHTNESS: case XINE_PARAM_VO_GAMMA: case XINE_PARAM_VO_DEINTERLACE: case XINE_PARAM_VO_ASPECT_RATIO: case XINE_PARAM_VO_ZOOM_X: case XINE_PARAM_VO_ZOOM_Y: case XINE_PARAM_VO_TVMODE: case XINE_PARAM_VO_WINDOW_WIDTH: case XINE_PARAM_VO_WINDOW_HEIGHT: case XINE_PARAM_VO_CROP_LEFT: case XINE_PARAM_VO_CROP_RIGHT: case XINE_PARAM_VO_CROP_TOP: case XINE_PARAM_VO_CROP_BOTTOM: case XINE_PARAM_VO_TRANSFORM: xine->port_ticket->acquire (xine->port_ticket, 1); ret = stream->s.video_out->get_property(stream->s.video_out, param); xine->port_ticket->release (xine->port_ticket, 1); break; case XINE_PARAM_IGNORE_VIDEO: ret = _x_stream_info_get_public (&stream->s, XINE_STREAM_INFO_IGNORE_VIDEO); break; case XINE_PARAM_IGNORE_AUDIO: ret = _x_stream_info_get_public (&stream->s, XINE_STREAM_INFO_IGNORE_AUDIO); break; case XINE_PARAM_IGNORE_SPU: ret = _x_stream_info_get_public (&stream->s, XINE_STREAM_INFO_IGNORE_SPU); break; case XINE_PARAM_METRONOM_PREBUFFER: ret = stream->s.metronom->get_option (stream->s.metronom, METRONOM_PREBUFFER); break; case XINE_PARAM_BROADCASTER_PORT: if( stream->broadcaster ) ret = _x_get_broadcaster_port(stream->broadcaster); else ret = 0; break; case XINE_PARAM_EARLY_FINISHED_EVENT: ret = stream->early_finish_event; break; case XINE_PARAM_DELAY_FINISHED_EVENT: xine_rwlock_rdlock (&stream->side_streams[0]->info_lock); ret = stream->delay_finish_event; xine_rwlock_unlock (&stream->side_streams[0]->info_lock); break; case XINE_PARAM_GAPLESS_SWITCH: ret = stream->gapless_switch; break; default: xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "xine_interface: unknown or deprecated stream param %d requested\n", param); ret = 0; } return ret; } uint32_t xine_get_stream_info (xine_stream_t *s, int info) { xine_stream_private_t *stream = (xine_stream_private_t *)s; switch (info) { case XINE_STREAM_INFO_SEEKABLE: if (stream->s.input_plugin) return stream->s.input_plugin->get_capabilities (stream->s.input_plugin) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_TIME_SEEKABLE); return 0; case XINE_STREAM_INFO_HAS_CHAPTERS: if (stream->demux.plugin) if (stream->demux.plugin->get_capabilities (stream->demux.plugin) & DEMUX_CAP_CHAPTERS) return 1; if (stream->s.input_plugin) if (stream->s.input_plugin->get_capabilities (stream->s.input_plugin) & INPUT_CAP_CHAPTERS) return 1; return 0; case XINE_STREAM_INFO_BITRATE: case XINE_STREAM_INFO_VIDEO_WIDTH: case XINE_STREAM_INFO_VIDEO_HEIGHT: case XINE_STREAM_INFO_VIDEO_RATIO: case XINE_STREAM_INFO_VIDEO_CHANNELS: case XINE_STREAM_INFO_VIDEO_STREAMS: case XINE_STREAM_INFO_VIDEO_BITRATE: case XINE_STREAM_INFO_VIDEO_FOURCC: case XINE_STREAM_INFO_VIDEO_HANDLED: case XINE_STREAM_INFO_FRAME_DURATION: case XINE_STREAM_INFO_AUDIO_CHANNELS: case XINE_STREAM_INFO_AUDIO_BITS: case XINE_STREAM_INFO_AUDIO_SAMPLERATE: case XINE_STREAM_INFO_AUDIO_BITRATE: case XINE_STREAM_INFO_AUDIO_FOURCC: case XINE_STREAM_INFO_AUDIO_HANDLED: case XINE_STREAM_INFO_HAS_AUDIO: case XINE_STREAM_INFO_HAS_VIDEO: case XINE_STREAM_INFO_IGNORE_VIDEO: case XINE_STREAM_INFO_IGNORE_AUDIO: case XINE_STREAM_INFO_IGNORE_SPU: case XINE_STREAM_INFO_VIDEO_HAS_STILL: case XINE_STREAM_INFO_SKIPPED_FRAMES: case XINE_STREAM_INFO_DISCARDED_FRAMES: case XINE_STREAM_INFO_VIDEO_AFD: case XINE_STREAM_INFO_DVD_TITLE_NUMBER: case XINE_STREAM_INFO_DVD_TITLE_COUNT: case XINE_STREAM_INFO_DVD_CHAPTER_NUMBER: case XINE_STREAM_INFO_DVD_CHAPTER_COUNT: case XINE_STREAM_INFO_DVD_ANGLE_NUMBER: case XINE_STREAM_INFO_DVD_ANGLE_COUNT: return _x_stream_info_get_public (&stream->s, info); case XINE_STREAM_INFO_MAX_AUDIO_CHANNEL: return stream->audio_track_map_entries; case XINE_STREAM_INFO_MAX_SPU_CHANNEL: return stream->spu_track_map_entries; default: xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "xine_interface: unknown or deprecated stream info %d requested\n", info); } return 0; } const char *xine_get_meta_info (xine_stream_t *stream, int info) { return _x_meta_info_get_public(stream, info); } int xine_query_stream_info (xine_stream_t *stream, char *sbuf, size_t sblen, int *strings, int *ints) { xine_stream_private_t *_s = (xine_stream_private_t *)stream; static const uint8_t tab_special[sizeof (_s->stream_info) / sizeof (_s->stream_info[0])] = { [XINE_STREAM_INFO_SEEKABLE] = 1, [XINE_STREAM_INFO_HAS_CHAPTERS] = 2, [XINE_STREAM_INFO_MAX_AUDIO_CHANNEL] = 3, [XINE_STREAM_INFO_MAX_SPU_CHANNEL] = 4 }; int special_index[5] = {-1, -1, -1, -1, -1}; uint32_t u, p; if (!_s) { if (sbuf && sblen) sbuf[0] = 0; if (strings) { for (u = 0; strings[u] >= 0; u++) strings[0] = 0; } if (ints) { for (u = 0; ints[u] >= 0; u++) ints[0] = 0; } return 0; } p = 0; _s = _s->side_streams[0]; xine_rwlock_rdlock (&_s->info_lock); if (strings) { if (sbuf && sblen) sbuf[p++] = 0; for (u = 0; strings[u] >= 0; u++) { const char *st; if (((uint32_t)strings[u] < sizeof (_s->meta_info) / sizeof (_s->meta_info[0])) && ((st = _s->meta_info[strings[u]]))) { size_t sl = xine_find_byte (st, 0) + 1; if (p + sl > sblen) break; strings[u] = p; memcpy (sbuf + p, st, sl); p += sl; } else { strings[u] = 0; } } for (; strings[u] >= 0; u++) strings[u] = 0; } if (ints) { for (u = 0; ints[u] >= 0; u++) { if ((uint32_t)ints[u] < sizeof (_s->stream_info) / sizeof (_s->stream_info[0])) { special_index[tab_special[ints[u]]] = u; ints[u] = _s->stream_info[ints[u]]; } else { ints[u] = 0; } } } xine_rwlock_unlock (&_s->info_lock); if (special_index[1] >= 0) ints[special_index[1]] = (_s->s.input_plugin && (_s->s.input_plugin->get_capabilities (_s->s.input_plugin) & (INPUT_CAP_SEEKABLE | INPUT_CAP_SLOW_SEEKABLE | INPUT_CAP_TIME_SEEKABLE))) ? 1 : 0; if (special_index[2] >= 0) ints[special_index[2]] = (_s->demux.plugin && (_s->demux.plugin->get_capabilities (_s->demux.plugin) & DEMUX_CAP_CHAPTERS)) || (_s->s.input_plugin && (_s->s.input_plugin->get_capabilities (_s->s.input_plugin) & INPUT_CAP_CHAPTERS)); if (special_index[3] >= 0) ints[special_index[3]] = _s->audio_track_map_entries; if (special_index[4] >= 0) ints[special_index[4]] = _s->spu_track_map_entries; return p; } xine_osd_t *xine_osd_new(xine_stream_t *stream, int x, int y, int width, int height) { xine_osd_t *this = (xine_osd_t *)stream->osd_renderer->new_object(stream->osd_renderer, width, height); this->osd.renderer->set_position(&this->osd, x, y); this->osd.renderer->set_encoding(&this->osd, ""); return this; } uint32_t xine_osd_get_capabilities(xine_osd_t *this) { return this->osd.renderer->get_capabilities(&this->osd); } void xine_osd_draw_point(xine_osd_t *this, int x, int y, int color) { this->osd.renderer->point(&this->osd, x, y, color); } void xine_osd_draw_line(xine_osd_t *this, int x1, int y1, int x2, int y2, int color) { this->osd.renderer->line(&this->osd, x1, y1, x2, y2, color); } void xine_osd_draw_rect(xine_osd_t *this, int x1, int y1, int x2, int y2, int color, int filled) { if (filled) { this->osd.renderer->filled_rect(&this->osd, x1, y1, x2, y2, color); } else { this->osd.renderer->line(&this->osd, x1, y1, x2, y1, color); this->osd.renderer->line(&this->osd, x2, y1, x2, y2, color); this->osd.renderer->line(&this->osd, x2, y2, x1, y2, color); this->osd.renderer->line(&this->osd, x1, y2, x1, y1, color); } } void xine_osd_draw_text(xine_osd_t *this, int x1, int y1, const char *text, int color_base) { this->osd.renderer->render_text(&this->osd, x1, y1, text, color_base); } void xine_osd_get_text_size(xine_osd_t *this, const char *text, int *width, int *height) { this->osd.renderer->get_text_size(&this->osd, text, width, height); } int xine_osd_set_font(xine_osd_t *this, const char *fontname, int size) { return this->osd.renderer->set_font(&this->osd, fontname, size); } void xine_osd_set_encoding(xine_osd_t *this, const char *encoding) { this->osd.renderer->set_encoding(&this->osd, encoding); } void xine_osd_set_position(xine_osd_t *this, int x, int y) { this->osd.renderer->set_position(&this->osd, x, y); } void xine_osd_show(xine_osd_t *this, int64_t vpts) { this->osd.renderer->show(&this->osd, vpts); } void xine_osd_show_unscaled(xine_osd_t *this, int64_t vpts) { this->osd.renderer->show_unscaled(&this->osd, vpts); } void xine_osd_hide(xine_osd_t *this, int64_t vpts) { this->osd.renderer->hide(&this->osd, vpts); } void xine_osd_clear(xine_osd_t *this) { this->osd.renderer->clear(&this->osd); } void xine_osd_free(xine_osd_t *this) { this->osd.renderer->free_object(&this->osd); } void xine_osd_set_palette(xine_osd_t *this, const uint32_t *const color, const uint8_t *const trans) { this->osd.renderer->set_palette(&this->osd, color, trans); } void xine_osd_set_text_palette(xine_osd_t *this, int palette_number, int color_base) { this->osd.renderer->set_text_palette(&this->osd, palette_number, color_base); } void xine_osd_get_palette(xine_osd_t *this, uint32_t *color, uint8_t *trans) { this->osd.renderer->get_palette(&this->osd, color, trans); } void xine_osd_draw_bitmap(xine_osd_t *this, uint8_t *bitmap, int x1, int y1, int width, int height, uint8_t *palette_map) { this->osd.renderer->draw_bitmap(&this->osd, bitmap, x1, y1, width, height, palette_map); } void xine_osd_set_argb_buffer(xine_osd_t *this, uint32_t *argb_buffer, int dirty_x, int dirty_y, int dirty_width, int dirty_height) { this->osd.renderer->set_argb_buffer(&this->osd, argb_buffer, dirty_x, dirty_y, dirty_width, dirty_height); } void xine_osd_set_extent(xine_osd_t *this, int extent_width, int extent_height) { this->osd.renderer->set_extent(&this->osd, extent_width, extent_height); } void xine_osd_set_video_window(xine_osd_t *this, int window_x, int window_y, int window_width, int window_height) { this->osd.renderer->set_video_window(&this->osd, window_x, window_y, window_width, window_height); } const char *const *xine_post_list_inputs(xine_post_t *this_gen) { post_plugin_t *this = (post_plugin_t *)this_gen; return this->input_ids; } const char *const *xine_post_list_outputs(xine_post_t *this_gen) { post_plugin_t *this = (post_plugin_t *)this_gen; return this->output_ids; } xine_post_in_t *xine_post_input(xine_post_t *this_gen, const char *name) { post_plugin_t *this = (post_plugin_t *)this_gen; xine_list_iterator_t ite = NULL; xine_post_in_t *input; while ((input = xine_list_next_value (this->input, &ite))) { if (strcmp(input->name, name) == 0) return input; } return NULL; } xine_post_out_t *xine_post_output(xine_post_t *this_gen, const char *name) { post_plugin_t *this = (post_plugin_t *)this_gen; xine_list_iterator_t ite = NULL; xine_post_out_t *output; while ((output = xine_list_next_value (this->output, &ite))) { if (strcmp(output->name, name) == 0) return output; } return NULL; } int xine_post_wire(xine_post_out_t *source, xine_post_in_t *target) { if (source && source->rewire) { if (target) { if (source->type == target->type) return source->rewire(source, target->data); else return 0; } else return source->rewire(source, NULL); } return 0; } int xine_post_wire_video_port(xine_post_out_t *source, xine_video_port_t *vo) { if (source && source->rewire) { if (vo) { if (source->type == XINE_POST_DATA_VIDEO) return source->rewire(source, vo); else return 0; } else return source->rewire(source, NULL); } return 0; } int xine_post_wire_audio_port(xine_post_out_t *source, xine_audio_port_t *ao) { if (source && source->rewire) { if (ao) { if (source->type == XINE_POST_DATA_AUDIO) return source->rewire(source, ao); else return 0; } else return source->rewire(source, NULL); } return 0; } xine_post_out_t * xine_get_video_source (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; return &stream->video_source; } xine_post_out_t * xine_get_audio_source (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; return &stream->audio_source; } /* report error/message to UI. may be provided with several * string parameters. last parameter must be NULL. */ int _x_message(xine_stream_t *stream, int type, ...) { xine_ui_message_data_t *data; xine_event_t event; const char *explanation; size_t size; int n; va_list ap; char *s, *params; char *args[1025]; static const char *const std_explanation[] = { "", N_("Warning:"), N_("Unknown host:"), N_("Unknown device:"), N_("Network unreachable"), N_("Connection refused:"), N_("File not found:"), N_("Read error from:"), N_("Error loading library:"), N_("Encrypted media stream detected"), N_("Security message:"), N_("Audio device unavailable"), N_("Permission error"), N_("File is empty:"), N_("Authentication needed"), N_("Recording done:") }; if (!stream) return 0; if( type >= 0 && (size_t)type < sizeof(std_explanation)/ sizeof(std_explanation[0]) ) { explanation = _(std_explanation[type]); size = strlen(explanation)+1; } else { explanation = NULL; size = 0; } n = 0; va_start(ap, type); while(((s = va_arg(ap, char *)) != NULL) && (n < 1024)) { size += strlen(s) + 1; args[n] = s; n++; } va_end(ap); args[n] = NULL; size += sizeof(xine_ui_message_data_t) + 1; data = calloc(1, size ); strcpy(data->compatibility.str, "Upgrade your frontend to see the error messages"); data->type = type; data->num_parameters = n; if( explanation ) { strcpy(data->messages, explanation); data->explanation = data->messages - (char *)data; params = data->messages + strlen(explanation) + 1; } else { data->explanation = 0; params = data->messages; } data->parameters = params - (char *)data; n = 0; *params = '\0'; while(args[n]) { strcpy(params, args[n]); params += strlen(args[n]) + 1; n++; } *params = '\0'; event.type = XINE_EVENT_UI_MESSAGE; event.stream = stream; event.data_length = size; event.data = data; xine_event_send(stream, &event); free(data); return 1; } int64_t xine_get_current_vpts (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; return stream->s.xine->clock->get_current_time (stream->s.xine->clock); } xine-lib-1.2/src/xine-engine/net_buf_ctrl.c0000644000175000017500000012643614647725152016507 0ustar meme/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * network buffering control */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include /********** logging **********/ #define LOG_MODULE "net_buf_ctrl" #define LOG_VERBOSE /* #define LOG */ #include "xine_private.h" #ifndef XINE_LIVE_PAUSE_ON # define XINE_LIVE_PAUSE_ON 0x7ffffffd #endif #define DEFAULT_HIGH_WATER_MARK 5000 /* in 1/1000 s */ #define FULL_FIFO_MARK 5 /* buffers free */ #define FIFO_PUT 0 #define FIFO_GET 1 typedef enum { NBC_MODE_OFF = 0, /* follow live dvb delivery speed. */ NBC_DVB_VIDEO_PLAY, /* 1: play at normal speed */ NBC_DVB_VIDEO_SLOW, /* 2: play 0.5% slower to fill video fifo */ NBC_DVB_VIDEO_FAST, /* 3: play 0.5% faster to empty video fifo */ NBC_DVB_AUDIO_PLAY, /* 4..6: same as 1..3 but watch audio fifo instead */ NBC_DVB_AUDIO_SLOW, NBC_DVB_AUDIO_FAST, NBC_DVB_PAUSE, /* 7: pause */ /* simple video on demand (un)pauseing. */ NBC_VOD_PLAY, NBC_VOD_PAUSE, NBC_MODE_LAST } xine_nbc_mode_t; /* protected by fifo->mutex (already held when entering callback) */ typedef struct { /* pointer */ fifo_buffer_t *fifo; xine_nbc_t *nbc; /* mode change test */ uint8_t mode_enable[NBC_MODE_LAST]; /* debug */ char name[6]; /* pts */ int64_t last_in_pts; int64_t last_out_pts; int64_t pos_pts; int fill_pts; int out_pts; /* type */ uint32_t type; /* buffers */ int fifo_fill; int fifo_free; /* ms */ uint32_t fifo_length; /* in ms */ uint32_t fifo_length_int; /* in ms */ /* bitrate */ int64_t last_pts; int64_t first_pts; uint32_t br; uint32_t stream_br; /* bytes */ uint32_t fifo_size; /* flags */ int in_disc; } xine_nbc_fifo_info_t; struct xine_nbc_st { xine_stream_t *stream; int speed_change; int speed_val; int has_audio; int has_video; int progress; xine_nbc_fifo_info_t audio; xine_nbc_fifo_info_t video; uint32_t high_water_mark; pthread_mutex_t mutex; int64_t pos_pts; xine_nbc_mode_t mode; int dvbs_center, dvbs_width; struct { /* in live mode, we start playback ~2s delayed. this happens * a) when a slow input actually sent that much data (DVB), or * b) while a fast input is waiting for the 2nd fragment. * in that case, we need our own wakeup agent because nobody * fires our callbacks then. */ pthread_cond_t msg; pthread_t thread; struct timespec base, until; enum { NBC_DELAY_OFF = 0, /* cond not inited, no thread */ NBC_DELAY_READY, /* cond inited, no thread */ NBC_DELAY_RUN, /* cond inited, thread running */ NBC_DELAY_STOP, /* cond inited, thread exiting normally */ NBC_DELAY_JOIN /* cond inited, waiting for thread to exit */ } state; } delay; struct { /* the buffer fill history, in units of 1/16s. * we need at least 10s. with 48kHz AAC, these are * 10*48000/1024=469 bufs. each buf goes both in and out, * thus 1024 will be fine. */ #define NBC_HSIZE_LD 10 #define NBC_HSIZE_NUM (1 << NBC_HSIZE_LD) #define NBC_HSIZE_MASK (NBC_HSIZE_NUM - 1) uint32_t min; uint32_t hpos; uint8_t hist[NBC_HSIZE_NUM]; /* the count of history entries per unit. */ uint32_t num[256]; } stats; }; static void nbc_set_speed (xine_nbc_t *this, int speed_val) { int speed_change; /* at least pauseing with mutex held may freeze. * make sure to apply the latest change anyway. */ this->speed_val = speed_val; speed_change = ++this->speed_change; while (1) { pthread_mutex_unlock (&this->mutex); if (speed_val) { /* this wont stop xine_close (), and we are going to repause on the next put anyway... * this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1); */ _x_set_fine_speed (this->stream, speed_val); } else { _x_set_fine_speed (this->stream, 0); /* allow decoding while paused */ _x_set_fine_speed (this->stream, XINE_LIVE_PAUSE_ON); /* this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 0); */ } pthread_mutex_lock (&this->mutex); if (speed_change == this->speed_change) break; speed_val = this->speed_val; speed_change = this->speed_change; } } static void nbc_delay_init (xine_nbc_t *this) { this->delay.state = NBC_DELAY_OFF; } static void nbc_delay_unpause (xine_nbc_t *this, int delay) { nbc_set_speed (this, XINE_FINE_SPEED_NORMAL); if ((this->mode >= NBC_DVB_VIDEO_PLAY) && (this->mode <= NBC_DVB_VIDEO_FAST)) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): dvbspeed 100%% @ video %d ms %d buffers%s.\n", (void *)this->stream, this->video.fill_pts / 90, this->video.fifo_fill, delay ? " [delayed]" : ""); } else { if (delay && _x_lock_port_rewiring (this->stream->xine, 0)) { this->audio.out_pts = this->stream->audio_out->get_property (this->stream->audio_out, AO_PROP_PTS_IN_FIFO); _x_unlock_port_rewiring (this->stream->xine); } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): dvbspeed 100%% @ audio %d ms %d buffers%s.\n", (void *)this->stream, (this->audio.fill_pts + this->audio.out_pts) / 90, this->audio.fifo_fill, delay ? " [delayed]" : ""); } } static void *nbc_delay_thread (void *data) { xine_nbc_t *this = (xine_nbc_t *)data; pthread_mutex_lock (&this->mutex); while (this->delay.state == NBC_DELAY_RUN) { if (pthread_cond_timedwait (&this->delay.msg, &this->mutex, &this->delay.until) == ETIMEDOUT) { nbc_delay_unpause (this, 1); break; } } if (this->delay.state != NBC_DELAY_JOIN) this->delay.state = NBC_DELAY_STOP; pthread_mutex_unlock (&this->mutex); return NULL; } static void nbc_delay_base (xine_nbc_t *this) { xine_gettime (&this->delay.base); } static void nbc_delay_set (xine_nbc_t *this, uint32_t pts) { struct timespec ts = {0, 0}; this->delay.until.tv_sec = this->delay.base.tv_sec + pts / 90000; this->delay.until.tv_nsec = this->delay.base.tv_nsec + (pts % 90000) / 9 * 100000; if (this->delay.until.tv_nsec >= 1000000000) { this->delay.until.tv_nsec -= 1000000000; this->delay.until.tv_sec += 1; } xine_gettime (&ts); if ((ts.tv_sec > this->delay.until.tv_sec) || ((ts.tv_sec == this->delay.until.tv_sec) && (ts.tv_nsec >= this->delay.until.tv_nsec))) { nbc_delay_unpause (this, 0); return; } if (this->delay.state == NBC_DELAY_RUN) { pthread_cond_signal (&this->delay.msg); return; } if (this->delay.state == NBC_DELAY_OFF) { pthread_cond_init (&this->delay.msg, NULL); } else if (this->delay.state == NBC_DELAY_STOP) { void *dummy; pthread_mutex_unlock (&this->mutex); pthread_join (this->delay.thread, &dummy); pthread_mutex_lock (&this->mutex); } this->delay.state = NBC_DELAY_READY; if (!pthread_create (&this->delay.thread, NULL, nbc_delay_thread, this)) { this->delay.state = NBC_DELAY_RUN; return; } this->delay.state = NBC_DELAY_OFF; pthread_cond_destroy (&this->delay.msg); nbc_delay_unpause (this, 0); } static void nbc_delay_clean (xine_nbc_t *this) { if (this->delay.state == NBC_DELAY_STOP) { void *dummy; this->delay.state = NBC_DELAY_JOIN; pthread_mutex_unlock (&this->mutex); pthread_join (this->delay.thread, &dummy); pthread_mutex_lock (&this->mutex); if (this->delay.state == NBC_DELAY_JOIN) { this->delay.state = NBC_DELAY_OFF; pthread_cond_destroy (&this->delay.msg); } } } static void nbc_delay_stop (xine_nbc_t *this) { switch (this->delay.state) { case NBC_DELAY_RUN: this->delay.state = NBC_DELAY_JOIN; nbc_set_speed (this, XINE_FINE_SPEED_NORMAL); if (this->delay.state != NBC_DELAY_JOIN) break; /* fall through */ case NBC_DELAY_STOP: this->delay.state = NBC_DELAY_JOIN; pthread_cond_signal (&this->delay.msg); pthread_mutex_unlock (&this->mutex); { void *dummy; pthread_join (this->delay.thread, &dummy); } pthread_mutex_lock (&this->mutex); if (this->delay.state != NBC_DELAY_JOIN) break; /* fall through */ case NBC_DELAY_READY: this->delay.state = NBC_DELAY_OFF; pthread_cond_destroy (&this->delay.msg); break; default: ; } } static void nbc_stats_reset (xine_nbc_t *this) { uint32_t u; this->stats.min = 0; this->stats.hpos = 0; memset (this->stats.hist, 0, sizeof (this->stats.hist)); this->stats.num[0] = NBC_HSIZE_NUM; for (u = 1; u < 256; u++) this->stats.num[u] = 0; } static void nbc_stats_flat (xine_nbc_t *this, int pts) { uint32_t level, u; if (pts < 0) pts = 0; level = pts; level /= (90000u / 16u); if (level > 255) level = 255; this->stats.min = level; for (u = 0; u < NBC_HSIZE_NUM; u++) this->stats.hist[u] = level; for (u = 0; u < 256; u++) this->stats.num[u] = 0; this->stats.num[level] = NBC_HSIZE_NUM; } /* live fragment streams may yield an extreme sawtooth fill curve. * weed ont really need to delay playback by half its amplitude either. * watch recent minimum instead of current value. */ static int nbc_stats_add (xine_nbc_t *this, int pts) { uint32_t level, min; if (pts < 0) return this->stats.min * (90000 / 16u); level = pts; level /= (90000u / 16u); if (level > 255) level = 255; this->stats.hpos = (this->stats.hpos + 1) & NBC_HSIZE_MASK; this->stats.num[this->stats.hist[this->stats.hpos]] -= 1; this->stats.hist[this->stats.hpos] = level; this->stats.num[level] += 1; if (level < this->stats.min) { min = level; } else { for (min = this->stats.min; this->stats.num[min] <= 0; min++) ; } if (min != this->stats.min) { this->stats.min = min; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): min buf fill %u ms.\n", (void *)this->stream, (unsigned int)min * (1000u / 16u)); } return min * (90000 / 16u); } static void report_progress (xine_stream_t *stream, int p) { xine_event_t event; xine_progress_data_t prg; prg.description = _("Buffering..."); prg.percent = (p>100)?100:p; event.type = XINE_EVENT_PROGRESS; event.data = &prg; event.data_length = sizeof (xine_progress_data_t); xine_event_send (stream, &event); } static void dvbspeed_init (xine_nbc_t *this) { int use_dvbs = 0; if (this->stream->input_plugin) { if (this->stream->input_plugin->get_capabilities (this->stream->input_plugin) & INPUT_CAP_LIVE) { use_dvbs = 1; } else { const char *mrl = this->stream->input_plugin->get_mrl (this->stream->input_plugin); if (mrl) { /* detect Kaffeine: fifo://~/.kde4/share/apps/kaffeine/dvbpipe.m2t */ if ((strcasestr (mrl, "/dvbpipe.")) || ((!strncasecmp (mrl, "dvb", 3)) && ((mrl[3] == ':') || (mrl[3] && (mrl[4] == ':'))))) use_dvbs = 1; } } } if (use_dvbs) { nbc_delay_init (this); this->dvbs_center = 2 * 90000; this->dvbs_width = 90000; this->audio.pos_pts = 0; this->audio.last_in_pts = this->audio.last_out_pts = 0; this->audio.fill_pts = this->audio.out_pts = 0; this->video.pos_pts = 0; this->video.last_in_pts = this->video.last_out_pts = 0; this->video.fill_pts = this->video.out_pts = 0; this->mode = NBC_DVB_PAUSE; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): dvbspeed mode.\n", (void *)this->stream); #if 1 { /* somewhat rude but saves user a lot of frustration */ xine_t *xine = this->stream->xine; config_values_t *config = xine->config; xine_cfg_entry_t entry; if (xine_config_lookup_entry (xine, "audio.synchronization.slow_fast_audio", &entry) && (entry.num_value == 0)) { config->update_num (config, "audio.synchronization.slow_fast_audio", 1); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): slow/fast audio playback enabled.\n", (void *)this->stream); } if (xine_config_lookup_entry (xine, "engine.buffers.video_num_buffers", &entry) && (entry.num_value < 800)) { config->update_num (config, "engine.buffers.video_num_buffers", 800); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): enlarged video fifo to 800 buffers.\n", (void *)this->stream); } } #endif } } void xine_nbc_event (xine_stream_private_t *stream, uint32_t type) { if (stream && (type == XINE_NBC_EVENT_AUDIO_DRY)) { /* this is here mainly for the case of an old style DVB signal loss. * skip the false alert when there is still audio waiting in fifo. */ stream = stream->side_streams[0]; pthread_mutex_lock (&stream->counter.lock); if (stream->counter.nbc_refs <= 0) { pthread_mutex_unlock (&stream->counter.lock); } else { xine_nbc_t *this = stream->counter.nbc; stream->counter.nbc_refs += 1; pthread_mutex_unlock (&stream->counter.lock); pthread_mutex_lock (&this->mutex); if (this->audio.fill_pts < 1000) { switch (this->mode) { case NBC_DVB_AUDIO_PLAY: case NBC_DVB_AUDIO_SLOW: case NBC_DVB_AUDIO_FAST: this->mode = NBC_DVB_PAUSE; nbc_stats_reset (this); nbc_set_speed (this, 0); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): signal lost.\n", (void *)this->stream); break; default: ; } } pthread_mutex_unlock (&this->mutex); xine_nbc_close (this); } } } static void display_stats (xine_nbc_t *this) { static const char buffering[2][4] = {" ", "buf"}; static const char enabled[2][4] = {"off", "on "}; printf("net_buf_ctrl: vid %3d%% %4.1fs %4ukbps %1d, "\ "aud %3d%% %4.1fs %4ukbps %1d, %s %s%c", this->video.fifo_fill, (float)(this->video.fifo_length / 1000), (unsigned int)this->video.br / 1000, this->video.in_disc, this->audio.fifo_fill, (float)(this->audio.fifo_length / 1000), (unsigned int)this->audio.br / 1000, this->audio.in_disc, buffering[this->mode == NBC_VOD_PAUSE], enabled[this->mode != NBC_MODE_OFF], isatty (STDOUT_FILENO) ? '\r' : '\n' ); fflush(stdout); } static void report_stats (xine_nbc_t *this, int type) { xine_event_t event; xine_nbc_stats_data_t bs; bs.v_percent = this->video.fifo_fill; bs.v_remaining = this->video.fifo_length; bs.v_bitrate = this->video.br; bs.v_in_disc = this->video.in_disc; bs.a_percent = this->audio.fifo_fill; bs.a_remaining = this->audio.fifo_length; bs.a_bitrate = this->audio.br; bs.a_in_disc = this->audio.in_disc; bs.buffering = this->mode == NBC_VOD_PAUSE; bs.enabled = this->mode != NBC_MODE_OFF; bs.type = type; event.type = XINE_EVENT_NBC_STATS; event.data = &bs; event.data_length = sizeof (xine_nbc_stats_data_t); xine_event_send (this->stream, &event); } /* Try to compute the length of the fifo in 1/1000 s * 2 methods : * if the bitrate is known * use the size of the fifo * else * use the the first and the last pts of the fifo */ static void nbc_compute_fifo_length(xine_nbc_t *this, fifo_buffer_t *fifo, buf_element_t *buf, int action) { int64_t diff; /* faster than 4x _x_stream_info_get () */ { xine_stream_private_t *s = (xine_stream_private_t *)this->stream; xine_rwlock_rdlock (&s->info_lock); this->has_video = s->stream_info[XINE_STREAM_INFO_HAS_VIDEO]; this->has_audio = s->stream_info[XINE_STREAM_INFO_HAS_AUDIO]; this->video.stream_br = s->stream_info[XINE_STREAM_INFO_VIDEO_BITRATE]; this->audio.stream_br = s->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE]; xine_rwlock_unlock (&s->info_lock); } { xine_nbc_fifo_info_t *info = (fifo == this->video.fifo) ? &this->video : &this->audio; int have_pts; info->fifo_size = fifo->fifo_data_size; info->fifo_free = fifo->buffer_pool_num_free; { int fifo_div = fifo->buffer_pool_num_free + fifo->fifo_size - 1; if (fifo_div == 0) fifo_div = 1; /* avoid a possible divide-by-zero */ info->fifo_fill = 100 * fifo->fifo_size / fifo_div; } have_pts = 0; if (buf->pts && (info->in_disc == 0)) { have_pts = 1; if (action == FIFO_PUT) { info->last_pts = buf->pts; if (info->first_pts == 0) { info->first_pts = buf->pts; } } else { /* GET */ info->first_pts = buf->pts; } } if (info->stream_br) { info->br = info->stream_br; info->fifo_length_int = (uint64_t)8000 * info->fifo_size / info->br; } else { if (have_pts) { info->fifo_length_int = (info->last_pts - info->first_pts) / 90; if (info->fifo_length) info->br = (uint64_t)8000 * info->fifo_size / info->fifo_length; else info->br = 0; } else { if (info->br) info->fifo_length_int = (uint64_t)8000 * info->fifo_size / info->br; } } } /* decoder buffer compensation */ if (this->has_audio && this->has_video) { diff = this->video.first_pts - this->audio.first_pts; } else { diff = 0; } if (diff > 0) { this->video.fifo_length = this->video.fifo_length_int + diff / 90; this->audio.fifo_length = this->audio.fifo_length_int; } else { this->video.fifo_length = this->video.fifo_length_int; this->audio.fifo_length = this->audio.fifo_length_int - diff / 90; } } /* Alloc callback */ static void nbc_alloc_cb (fifo_buffer_t *fifo, void *data) { xine_nbc_fifo_info_t *fifo_info = (xine_nbc_fifo_info_t *)data; xine_nbc_t *this = fifo_info->nbc; lprintf("enter nbc_alloc_cb\n"); /* restart playing if one fifo is full (to avoid deadlock). * fifo is locked already, test this one first. */ if (fifo->buffer_pool_num_free <= FULL_FIFO_MARK) { static const uint8_t newmode[NBC_MODE_LAST] = { [NBC_DVB_VIDEO_PLAY] = NBC_DVB_VIDEO_FAST, [NBC_DVB_VIDEO_SLOW] = NBC_DVB_VIDEO_FAST, [NBC_DVB_AUDIO_PLAY] = NBC_DVB_AUDIO_FAST, [NBC_DVB_AUDIO_SLOW] = NBC_DVB_AUDIO_FAST, [NBC_VOD_PAUSE] = NBC_VOD_PLAY }; uint32_t mode; pthread_mutex_lock (&this->mutex); mode = newmode[this->mode]; if (mode) { if (mode != NBC_VOD_PLAY) { this->mode = mode; nbc_set_speed (this, 1005 * XINE_FINE_SPEED_NORMAL / 1000); pthread_mutex_unlock (&this->mutex); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): %s alloc: dvbspeed 100.5%%.\n", (void *)this->stream, fifo_info->name); } else { this->mode = mode; this->progress = 100; nbc_set_speed (this, XINE_FINE_SPEED_NORMAL); pthread_mutex_unlock (&this->mutex); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): %s alloc: stops buffering.\n", (void *)this->stream, fifo_info->name); report_progress (this->stream, 100); } } else { pthread_mutex_unlock (&this->mutex); } } lprintf("exit nbc_alloc_cb\n"); } /* Put callback. the fifo mutex is locked, and the buf is not yet added. */ static void nbc_put_cb (fifo_buffer_t *fifo, buf_element_t *buf, void *data) { xine_nbc_fifo_info_t *fifo_info = (xine_nbc_fifo_info_t *)data; xine_nbc_t *this = fifo_info->nbc; uint32_t type = buf->type & BUF_MAJOR_MASK; int speed = -1; lprintf ("enter nbc_put_cb\n"); if (type == fifo_info->type) { fifo_info->fifo_size = fifo->fifo_data_size; fifo_info->fifo_fill = fifo->fifo_size; if (!fifo_info->fifo_fill) fifo_info->fill_pts = 0; fifo_info->fifo_free = fifo->buffer_pool_num_free; /* update fifo fill time. * NOTE: this is somewhat inaccurate. we assume that * buf2.pts - buf1.pts == buf2.duration * that is 1 buf late, and it jitters on reaordered video :-/ */ if (buf->pts) { if (fifo_info->last_in_pts) { int64_t diff = buf->pts - fifo_info->last_in_pts; do { if (diff < -220000) { /* try mpeg pts wrap */ diff += (uint64_t)1 << 33; if ((diff < -220000) || (diff > 220000)) break; } else if (diff > 220000) { diff -= (uint64_t)1 << 33; if ((diff < -220000) || (diff > 220000)) break; } fifo_info->pos_pts += diff; fifo_info->fill_pts += (int)diff; } while (0); } fifo_info->last_in_pts = buf->pts; } if (type == BUF_AUDIO_BASE) { /* The usual 48kHz stereo mp2 can fill audio out fifo with > 7 seconds!! */ if (_x_lock_port_rewiring (this->stream->xine, 0)) { if (this->stream->audio_out) fifo_info->out_pts = this->stream->audio_out->get_property (this->stream->audio_out, AO_PROP_PTS_IN_FIFO); _x_unlock_port_rewiring (this->stream->xine); } } else { /* not supported yet */ fifo_info->out_pts = 0; } pthread_mutex_lock (&this->mutex); if (fifo_info->pos_pts > this->pos_pts) this->pos_pts = fifo_info->pos_pts; { int all_fill, used, mode; mode = this->mode; switch (mode & fifo_info->mode_enable[mode]) { case NBC_DVB_VIDEO_PLAY: case NBC_DVB_AUDIO_PLAY: all_fill = fifo_info->fill_pts + fifo_info->out_pts; used = fifo_info->fifo_fill; all_fill = nbc_stats_add (this, all_fill); if ((all_fill > this->dvbs_center + this->dvbs_width) || (100 * used > 98 * fifo_info->fifo->buffer_pool_capacity)) { this->mode = mode + (int)NBC_DVB_VIDEO_FAST - (int)NBC_DVB_VIDEO_PLAY; speed = XINE_FINE_SPEED_NORMAL * 1005 / 1000; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): dvbspeed 100.5%% @ %s %d ms %d buffers.\n", (void *)this->stream, fifo_info->name, all_fill / 90, used); } break; case NBC_DVB_PAUSE: all_fill = fifo_info->fill_pts + fifo_info->out_pts; used = fifo_info->fifo_fill; if (_x_get_fine_speed (this->stream)) { /* Pause on first a/v buffer. Decoder headers went through at this time already, and xine_play is done waiting for that. */ nbc_delay_base (this); speed = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): prebuffering...\n", (void *)this->stream); } if ((all_fill > this->dvbs_center) || (100 * used > 73 * fifo_info->fifo->buffer_pool_capacity)) { /* DVB streams usually mux video > 0.5 seconds earlier than audio * to give slow TVs time to decode and present in sync. Take care * of unusual high delays of some DVB-T streams when we are going * to watch video fill. */ this->dvbs_center = 2 * 90000; if (this->audio.last_in_pts && this->video.last_in_pts && (fifo_info->type == BUF_VIDEO_BASE)) { int64_t d = this->video.last_in_pts - this->audio.last_in_pts + 110000; if ((d < 3 * 90000) && (d > this->dvbs_center)) this->dvbs_center = d; } /* dont make the startup phase switch to slow mode later. */ nbc_stats_flat (this, all_fill); nbc_delay_set (this, this->dvbs_center); this->mode = (fifo_info->type == BUF_VIDEO_BASE) ? NBC_DVB_VIDEO_PLAY : NBC_DVB_AUDIO_PLAY; /* dont let low bitrate radio switch speed too often */ if (used < 30) this->dvbs_width = 135000; } break; case NBC_DVB_VIDEO_SLOW: case NBC_DVB_AUDIO_SLOW: all_fill = fifo_info->fill_pts + fifo_info->out_pts; used = fifo_info->fifo_fill; all_fill = nbc_stats_add (this, all_fill); if ((all_fill > this->dvbs_center) || (100 * used > 73 * fifo_info->fifo->buffer_pool_capacity)) { nbc_delay_set (this, this->dvbs_center); this->mode = (fifo_info->type == BUF_VIDEO_BASE) ? NBC_DVB_VIDEO_PLAY : NBC_DVB_AUDIO_PLAY; /* dont let low bitrate radio switch speed too often */ if (used < 30) this->dvbs_width = 135000; } break; case NBC_VOD_PAUSE: case NBC_VOD_PLAY: nbc_compute_fifo_length (this, fifo, buf, FIFO_PUT); if (mode == NBC_VOD_PAUSE) { int progress; /* restart playing if high_water_mark is reached by all fifos * do not restart if has_video and has_audio are false to avoid * a yoyo effect at the beginning of the stream when these values * are not yet known. * be sure that the next buffer_pool_alloc() call will not deadlock, * we need at least 2 buffers (see buffer.c) */ if (this->has_video) { if (this->has_audio) { if ((this->video.fifo_length > this->high_water_mark) && (this->audio.fifo_length > this->high_water_mark)) { progress = 100; this->mode = NBC_VOD_PLAY; } else { /* compute the buffering progress, 50%: video, 50%: audio */ progress = (this->video.fifo_length + this->audio.fifo_length) * 50 / this->high_water_mark; } } else { if (this->video.fifo_length > this->high_water_mark) { progress = 100; this->mode = NBC_VOD_PLAY; } else { progress = this->video.fifo_length * 100 / this->high_water_mark; } } } else { if (this->has_audio) { if (this->audio.fifo_length > this->high_water_mark) { progress = 100; this->mode = NBC_VOD_PLAY; } else { progress = this->audio.fifo_length * 100 / this->high_water_mark; } } else { progress = 0; } } if (this->mode == NBC_VOD_PLAY) { this->progress = 100; speed = XINE_FINE_SPEED_NORMAL; report_progress (this->stream, 100); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_put_cb: stops buffering.\n", (void *)this->stream); #if 0 /* WTF... */ this->high_water_mark += this->high_water_mark / 2; #endif } else { if (!progress) { /* if the progress can't be computed using the fifo length, use the number of buffers */ progress = this->video.fifo_fill > this->audio.fifo_fill ? this->video.fifo_fill : this->audio.fifo_fill; } if (progress > this->progress) { this->progress = progress; report_progress (this->stream, progress); } } report_stats (this, 0); if (this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) display_stats (this); } break; default: ; } } } else if (type == BUF_CONTROL_BASE) { pthread_mutex_lock (&this->mutex); switch (buf->type) { case BUF_CONTROL_START: lprintf("BUF_CONTROL_START\n"); if (this->mode == NBC_MODE_OFF) { /* a new stream starts */ xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_put_cb: starts buffering.\n", (void *)this->stream); fifo_info->last_in_pts = 0; fifo_info->last_out_pts = 0; fifo_info->pos_pts = 0; this->pos_pts = 0; this->video.first_pts = 0; this->video.last_pts = 0; this->audio.first_pts = 0; this->audio.last_pts = 0; this->video.fifo_length = 0; this->audio.fifo_length = 0; this->mode = NBC_VOD_PAUSE; dvbspeed_init (this); if (this->mode == NBC_VOD_PAUSE) speed = 0; this->progress = 0; report_progress (this->stream, 0); } break; case BUF_CONTROL_NOP: if (!(buf->decoder_flags & (BUF_FLAG_END_USER | BUF_FLAG_END_STREAM))) break; /* fall through */ case BUF_CONTROL_END: case BUF_CONTROL_QUIT: lprintf("BUF_CONTROL_END\n"); { static const uint8_t want[NBC_MODE_LAST] = { [NBC_DVB_VIDEO_PLAY] = 2, [NBC_DVB_VIDEO_SLOW] = 3, [NBC_DVB_VIDEO_FAST] = 3, [NBC_DVB_AUDIO_PLAY] = 2, [NBC_DVB_AUDIO_SLOW] = 3, [NBC_DVB_AUDIO_FAST] = 3, [NBC_DVB_PAUSE] = 3, [NBC_VOD_PLAY] = 4, [NBC_VOD_PAUSE] = 5 }; uint32_t mode = want[this->mode]; if (mode & 2) nbc_delay_stop (this); if (mode & 1) speed = XINE_FINE_SPEED_NORMAL; if (mode & 2) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): dvbspeed OFF.\n", (void *)this->stream); if (mode & 4) { this->progress = 100; report_progress (this->stream, this->progress); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_put_cb: stops buffering.\n", (void *)this->stream); } } this->mode = NBC_MODE_OFF; break; case BUF_CONTROL_NEWPTS: /* discontinuity management */ if (fifo == this->video.fifo) { this->video.in_disc++; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_put_cb video disc %d.\n", (void *)this->stream, this->video.in_disc); } else { this->audio.in_disc++; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_put_cb audio disc %d.\n", (void *)this->stream, this->audio.in_disc); } break; } if (fifo == this->video.fifo) { this->video.fifo_free = fifo->buffer_pool_num_free; this->video.fifo_size = fifo->fifo_data_size; } else { this->audio.fifo_free = fifo->buffer_pool_num_free; this->audio.fifo_size = fifo->fifo_data_size; } } else { pthread_mutex_lock (&this->mutex); } if (speed >= 0) nbc_set_speed (this, speed); pthread_mutex_unlock (&this->mutex); lprintf("exit nbc_put_cb\n"); } /* Get callback. the fifo mutex is locked, and the buf is removed already. */ static void nbc_get_cb (fifo_buffer_t *fifo, buf_element_t *buf, void *data) { xine_nbc_fifo_info_t *fifo_info = (xine_nbc_fifo_info_t *)data; xine_nbc_t *this = fifo_info->nbc; uint32_t type = buf->type & BUF_MAJOR_MASK; int speed = -1; lprintf ("enter nbc_get_cb\n"); if (type == fifo_info->type) { fifo_info->fifo_size = fifo->fifo_data_size; fifo_info->fifo_fill = fifo->fifo_size; fifo_info->fifo_free = fifo->buffer_pool_num_free; /* update fifo fill time. * NOTE: this is somewhat inaccurate. we assume that * buf2.pts - buf1.pts == buf2.duration * that is 1 buf late, and it jitters on reaordered video :-/ */ if (buf->pts) { if (fifo_info->last_out_pts) { int64_t diff = buf->pts - fifo_info->last_out_pts; do { if (diff < -220000) { /* try mpeg pts wrap */ diff += (uint64_t)1 << 33; if ((diff < -220000) || (diff > 220000)) break; } else if (diff > 220000) { diff -= (uint64_t)1 << 33; if ((diff < -220000) || (diff > 220000)) break; } fifo_info->fill_pts -= (int)diff; } while (0); } fifo_info->last_out_pts = buf->pts; } if (!fifo_info->fifo_fill) fifo_info->fill_pts = 0; if (type == BUF_AUDIO_BASE) { if (_x_lock_port_rewiring (this->stream->xine, 0)) { fifo_info->out_pts = this->stream->audio_out->get_property (this->stream->audio_out, AO_PROP_PTS_IN_FIFO); _x_unlock_port_rewiring (this->stream->xine); } } else { fifo_info->out_pts = 0; } pthread_mutex_lock (&this->mutex); { int all_fill, used, mode; nbc_delay_clean (this); mode = this->mode; switch (mode & fifo_info->mode_enable[mode]) { case NBC_DVB_AUDIO_PLAY: case NBC_DVB_VIDEO_PLAY: all_fill = fifo_info->fill_pts + fifo_info->out_pts; used = fifo_info->fifo_fill; all_fill = nbc_stats_add (this, all_fill); if (all_fill && (all_fill < this->dvbs_center - this->dvbs_width) && (100 * used < 38 * fifo_info->fifo->buffer_pool_capacity)) { this->mode = mode + (int)NBC_DVB_AUDIO_SLOW - (int)NBC_DVB_AUDIO_PLAY; speed = XINE_FINE_SPEED_NORMAL * 995 / 1000; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): dvbspeed 99.5%% @ %s %d ms %d buffers.\n", (void *)this->stream, fifo_info->name, all_fill / 90, used); } break; case NBC_DVB_VIDEO_SLOW: case NBC_DVB_AUDIO_SLOW: /* all_fill = fifo_info->fill_pts + fifo_info->out_pts; */ used = fifo_info->fifo_fill; if (used <= 1) { this->mode = NBC_DVB_PAUSE; nbc_stats_reset (this); speed = 0; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): signal lost.\n", (void *)this->stream); } break; case NBC_DVB_AUDIO_FAST: case NBC_DVB_VIDEO_FAST: all_fill = fifo_info->fill_pts + fifo_info->out_pts; used = fifo_info->fifo_fill; all_fill = nbc_stats_add (this, all_fill); if (all_fill && (all_fill < this->dvbs_center) && (100 * used < 73 * fifo_info->fifo->buffer_pool_capacity)) { this->mode += (int)NBC_DVB_AUDIO_PLAY - (int)NBC_DVB_AUDIO_FAST; speed = XINE_FINE_SPEED_NORMAL; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): dvbspeed 100%% @ %s %d ms %d buffers.\n", (void *)this->stream, fifo_info->name, all_fill / 90, used); } break; case NBC_VOD_PAUSE: case NBC_VOD_PLAY: nbc_compute_fifo_length (this, fifo, buf, FIFO_GET); if (this->mode == NBC_VOD_PLAY) { /* start buffering if one fifo is empty */ if (((this->video.fifo_length == 0) && this->has_video) || ((this->audio.fifo_length == 0) && this->has_audio)) { /* do not pause if a fifo is full to avoid yoyo (play-pause-play-pause) */ if ((this->video.fifo_free > FULL_FIFO_MARK) && (this->audio.fifo_free > FULL_FIFO_MARK)) { this->mode = NBC_VOD_PAUSE; this->progress = 0; report_progress (this->stream, 0); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_get_cb: starts buffering, vid: %d, aud: %d.\n", (void *)this->stream, this->video.fifo_fill, this->audio.fifo_fill); speed = 0; } } report_stats (this, 1); if (this->stream->xine->verbosity >= XINE_VERBOSITY_DEBUG) display_stats (this); } else { speed = 0; } break; default: ; } } } else if (type == BUF_CONTROL_BASE) { pthread_mutex_lock (&this->mutex); /* discontinuity management */ if (buf->type == BUF_CONTROL_NEWPTS) { if (fifo == this->video.fifo) { this->video.in_disc--; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_get_cb video disc %d\n", (void *)this->stream, this->video.in_disc); } else { this->audio.in_disc--; xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_get_cb audio disc %d\n", (void *)this->stream, this->audio.in_disc); } } if (fifo == this->video.fifo) { this->video.fifo_free = fifo->buffer_pool_num_free; this->video.fifo_size = fifo->fifo_data_size; } else { this->audio.fifo_free = fifo->buffer_pool_num_free; this->audio.fifo_size = fifo->fifo_data_size; } } else { pthread_mutex_lock (&this->mutex); } if (speed >= 0) nbc_set_speed (this, speed); pthread_mutex_unlock (&this->mutex); lprintf("exit nbc_get_cb\n"); } int64_t xine_nbc_get_pos_pts (xine_nbc_t *this) { int64_t r; if (!this) return 0; pthread_mutex_lock (&this->mutex); r = this->pos_pts; pthread_mutex_unlock (&this->mutex); return r; } xine_nbc_t *xine_nbc_init (xine_stream_t *stream) { xine_nbc_t *this; double video_fifo_factor, audio_fifo_factor; cfg_entry_t *entry; if (!stream) return NULL; { xine_stream_private_t *s = (xine_stream_private_t *)stream; s = s->side_streams[0]; pthread_mutex_lock (&s->counter.lock); if (s->counter.nbc_refs > 0) { int refs; s->counter.nbc_refs += 1; refs = s->counter.nbc_refs; this = s->counter.nbc; pthread_mutex_unlock (&s->counter.lock); xprintf (s->s.xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): add to stream (%d refs).\n", (void *)s, refs); return this; } this = calloc (1, sizeof (*this)); if (!this) { pthread_mutex_unlock (&s->counter.lock); return this; } s->counter.nbc_refs = 1; s->counter.nbc = this; pthread_mutex_unlock (&s->counter.lock); xine_refs_add (&s->refs, 1); xprintf (s->s.xine, XINE_VERBOSITY_DEBUG, "net_buf_ctrl (%p): add to stream (1 refs).\n", (void *)s); stream = &s->s; } this->stream = stream; this->video.fifo = stream->video_fifo; this->audio.fifo = stream->audio_fifo; this->video.nbc = this; this->audio.nbc = this; this->video.type = BUF_VIDEO_BASE; this->audio.type = BUF_AUDIO_BASE; #ifndef HAVE_ZERO_SAFE_MEM this->video.last_pts = 0; this->video.first_pts = 0; this->video.fill_pts = 0; this->video.out_pts = 0; this->audio.last_pts = 0; this->audio.first_pts = 0; this->audio.fill_pts = 0; this->audio.out_pts = 0; this->mode = NBC_MODE_OFF; #endif memcpy (this->video.name, "video", 6); memcpy (this->audio.name, "audio", 6); { const uint8_t video_enable[NBC_MODE_LAST] = { [NBC_DVB_VIDEO_PLAY] = 0xff, [NBC_DVB_VIDEO_SLOW] = 0xff, [NBC_DVB_VIDEO_FAST] = 0xff, [NBC_DVB_PAUSE] = 0xff, [NBC_VOD_PLAY] = 0xff, [NBC_VOD_PAUSE] = 0xff }; const uint8_t audio_enable[NBC_MODE_LAST] = { [NBC_DVB_AUDIO_PLAY] = 0xff, [NBC_DVB_AUDIO_SLOW] = 0xff, [NBC_DVB_AUDIO_FAST] = 0xff, [NBC_DVB_PAUSE] = 0xff, [NBC_VOD_PLAY] = 0xff, [NBC_VOD_PAUSE] = 0xff }; memcpy (this->video.mode_enable, video_enable, sizeof (video_enable)); memcpy (this->audio.mode_enable, audio_enable, sizeof (audio_enable)); } lprintf("nbc_init\n"); pthread_mutex_init (&this->mutex, NULL); nbc_stats_reset (this); /* when the FIFO sizes are increased compared to the default configuration, * apply a factor to the high water mark */ entry = stream->xine->config->lookup_entry(stream->xine->config, "engine.buffers.video_num_buffers"); /* No entry when no video output */ if (entry) video_fifo_factor = (double)this->video.fifo->buffer_pool_capacity / (double)entry->num_default; else video_fifo_factor = 1.0; entry = stream->xine->config->lookup_entry(stream->xine->config, "engine.buffers.audio_num_buffers"); /* When there's no audio output, there's no entry */ if (entry) audio_fifo_factor = (double)this->audio.fifo->buffer_pool_capacity / (double)entry->num_default; else audio_fifo_factor = 1.0; /* use the smaller factor */ if (video_fifo_factor < audio_fifo_factor) this->high_water_mark = (double)DEFAULT_HIGH_WATER_MARK * video_fifo_factor; else this->high_water_mark = (double)DEFAULT_HIGH_WATER_MARK * audio_fifo_factor; this->speed_change = 0; this->speed_val = _x_get_fine_speed (this->stream); this->video.fifo->register_alloc_cb (this->video.fifo, nbc_alloc_cb, &this->video); this->video.fifo->register_put_cb (this->video.fifo, nbc_put_cb, &this->video); this->video.fifo->register_get_cb (this->video.fifo, nbc_get_cb, &this->video); this->audio.fifo->register_alloc_cb (this->audio.fifo, nbc_alloc_cb, &this->audio); this->audio.fifo->register_put_cb (this->audio.fifo, nbc_put_cb, &this->audio); this->audio.fifo->register_get_cb (this->audio.fifo, nbc_get_cb, &this->audio); return this; } void xine_nbc_close (xine_nbc_t *this) { fifo_buffer_t *video_fifo, *audio_fifo; xine_t *xine; if (!this) return; xine = this->stream->xine; { xine_stream_private_t *s = (xine_stream_private_t *)this->stream; int refs; pthread_mutex_lock (&s->counter.lock); s->counter.nbc_refs -= 1; refs = s->counter.nbc_refs; if (refs > 0) { pthread_mutex_unlock (&s->counter.lock); #if 0 xprintf (xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): remove from stream (%d refs).\n", (void *)s, refs); #endif return; } s->counter.nbc_refs = 0; s->counter.nbc = NULL; pthread_mutex_unlock (&s->counter.lock); } xprintf (xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): remove from stream (0 refs).\n", (void *)this->stream); video_fifo = this->stream->video_fifo; audio_fifo = this->stream->audio_fifo; /* unregister all fifo callbacks */ /* do not lock the mutex to avoid deadlocks if a decoder calls fifo->get() */ video_fifo->unregister_alloc_cb(video_fifo, nbc_alloc_cb); video_fifo->unregister_put_cb(video_fifo, nbc_put_cb); video_fifo->unregister_get_cb(video_fifo, nbc_get_cb); audio_fifo->unregister_alloc_cb(audio_fifo, nbc_alloc_cb); audio_fifo->unregister_put_cb(audio_fifo, nbc_put_cb); audio_fifo->unregister_get_cb(audio_fifo, nbc_get_cb); /* now we are sure that nobody will call a callback */ /* this->stream->xine->clock->set_option (this->stream->xine->clock, CLOCK_SCR_ADJUSTABLE, 1); */ pthread_mutex_destroy(&this->mutex); xprintf (xine, XINE_VERBOSITY_DEBUG, "\nnet_buf_ctrl (%p): nbc_close: done\n", (void *)this->stream); { xine_stream_private_t *s = (xine_stream_private_t *)this->stream; free (this); xine_refs_sub (&s->refs, 1); } } xine-lib-1.2/src/xine-engine/post.c0000644000175000017500000012373314647725152015023 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /* * some helper functions for post plugins */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define POST_INTERNAL #include #include "xine_private.h" #include #include #define HARD_DEBUG #ifdef HARD_DEBUG # define NAILS_S(struct,nail) memset (struct, nail, sizeof (*(struct))) #else # define NAILS_S(struct,nail) #endif /* TJ. O dear. It was intended that post plugins inside vo_frame.draw () did call either _x_post_frame_copy_down (f, f->next); f->next->draw (f->next, stream); _x_post_frame_copy_up (f, f->next); or _x_post_frame_u_turn (f, stream); to set vo_frame.stream, and to lock that stream until the frame gets unreferenced completely. Unfortunately, - Most post plugins dont do that. - It does not strictly guarantee a stream lock long enough. - Somebody might change vo_frame.stream without proper relocking. So lets do safe hidden locking when vo_frame.free () uses default post_frame_free (). */ typedef struct { vo_frame_t frame; xine_stream_t *stream; } vf_alias_t; static void post_frame_lock (vo_frame_t *vo_img); static void post_frame_proc_slice (vo_frame_t *vo_img, uint8_t **src); static void post_frame_proc_frame (vo_frame_t *vo_img); static void post_frame_field (vo_frame_t *vo_img, int which_field); static int post_frame_draw (vo_frame_t *vo_img, xine_stream_t *stream); static void post_frame_free (vo_frame_t *vo_img); static void post_frame_dispose (vo_frame_t *vo_img); static vf_alias_t *post_new_video_alias (post_video_port_t *port, int usage) { vf_alias_t *new_frame; /* get a free frame slot */ pthread_mutex_lock (&port->usage_lock); if (port->free_frame_slots) { new_frame = (vf_alias_t *)port->free_frame_slots; port->free_frame_slots = new_frame->frame.next; } else { new_frame = calloc (1, sizeof (vf_alias_t)); } if (usage) port->usage_count++; pthread_mutex_unlock (&port->usage_lock); return new_frame; } static void post_free_unused_video_alias (post_video_port_t *port, vf_alias_t *f) { /* put the now free slot into the free frames list */ pthread_mutex_lock (&port->usage_lock); f->frame.next = port->free_frame_slots; port->free_frame_slots = &f->frame; port->usage_count--; if (port->usage_count || !port->post->dispose_pending) { pthread_mutex_unlock (&port->usage_lock); } else { pthread_mutex_unlock (&port->usage_lock); port->post->dispose (port->post); } } static vo_frame_t *post_intercept_video_frame (post_video_port_t *port, vo_frame_t *frame, vf_alias_t *new_frame, int usage) { if (usage && port->frame_lock) pthread_mutex_lock (port->frame_lock); /* make a copy and attach the original */ xine_fast_memcpy (&new_frame->frame, frame, sizeof (vo_frame_t)); new_frame->frame.next = frame; /* modify the frame with the intercept functions */ new_frame->frame.port = &port->new_port; new_frame->frame.proc_frame = port->new_frame->proc_frame ? port->new_frame->proc_frame : NULL; new_frame->frame.proc_slice = port->new_frame->proc_slice ? port->new_frame->proc_slice : NULL; new_frame->frame.field = port->new_frame->field ? port->new_frame->field : post_frame_field; new_frame->frame.draw = port->new_frame->draw ? port->new_frame->draw : post_frame_draw; new_frame->frame.lock = port->new_frame->lock ? port->new_frame->lock : post_frame_lock; new_frame->frame.free = port->new_frame->free ? port->new_frame->free : post_frame_free; new_frame->frame.dispose = port->new_frame->dispose ? port->new_frame->dispose : post_frame_dispose; /* Optimization: dont NULL stream ref, will often be reused later */ if ((new_frame->frame.free == post_frame_free) && new_frame->frame.stream && (new_frame->stream != new_frame->frame.stream)) { xine_stream_private_t *s; s = (xine_stream_private_t *)new_frame->frame.stream; xine_refs_add (&s->refs, 1); if (new_frame->stream) { s = (xine_stream_private_t *)new_frame->stream; xine_refs_sub (&s->refs, 1); } new_frame->stream = new_frame->frame.stream; } if (!port->new_frame->draw || (port->route_preprocessing_procs && port->route_preprocessing_procs(port, frame))) { /* draw will most likely modify the frame, so the decoder * should only request preprocessing when there is no new draw * but route_preprocessing_procs() can override this decision */ if (frame->proc_frame && !new_frame->frame.proc_frame) new_frame->frame.proc_frame = post_frame_proc_frame; if (frame->proc_slice && !new_frame->frame.proc_slice) new_frame->frame.proc_slice = post_frame_proc_slice; } if (usage && port->frame_lock) pthread_mutex_unlock (port->frame_lock); return &new_frame->frame; } static vo_frame_t *post_restore_video_frame (vo_frame_t *frame, post_video_port_t *port, int usage) { /* the first attched context is the original frame */ vo_frame_t *original = frame->next; /* propagate any changes */ _x_post_frame_copy_down(frame, original); if (usage && port->frame_lock) pthread_mutex_unlock (port->frame_lock); /* put the now free slot into the free frames list */ pthread_mutex_lock (&port->usage_lock); frame->next = port->free_frame_slots; port->free_frame_slots = frame; /* Unref stream when already closed. */ if ((frame->free == post_frame_free) && !port->stream) { vf_alias_t *f = (vf_alias_t *)frame; if (f->stream) { xine_stream_private_t *s = (xine_stream_private_t *)f->stream; xine_refs_sub (&s->refs, 1); f->stream = NULL; } } if (usage) { port->usage_count--; if (port->usage_count || !port->post->dispose_pending) usage = 0; } pthread_mutex_unlock (&port->usage_lock); if (usage) port->post->dispose (port->post); return original; } /* (Un)ref intercepted post ports as well. This prevents nasty writes after free with live filter chain editors like xine-ui. A generic port->open works but raises a similar issue later when output is discarded before post. */ static uint32_t post_video_get_capabilities (xine_video_port_t *port_gen); static vo_frame_t *post_video_get_frame (xine_video_port_t *port_gen, uint32_t width, uint32_t height, double ratio, int format, int flags); static void post_video_enable_ovl (xine_video_port_t *port_gen, int ovl_enable); static video_overlay_manager_t *post_video_get_overlay_manager (xine_video_port_t *port_gen); static int post_video_port_ref (xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; int n = -1; if (!port) return n; if ((port->new_port.get_capabilities == post_video_get_capabilities) || (port->new_port.get_frame == post_video_get_frame) || (port->new_port.enable_ovl == post_video_enable_ovl) || (port->new_port.get_overlay_manager == post_video_get_overlay_manager)) { pthread_mutex_lock (&port->usage_lock); n = (++port->usage_count); pthread_mutex_unlock (&port->usage_lock); } return n; } int _x_post_video_port_ref (xine_video_port_t *port_gen) { return post_video_port_ref (port_gen); } static int post_video_port_unref (xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; int n = -1; if (!port) return n; if ((port->new_port.get_capabilities == post_video_get_capabilities) || (port->new_port.get_frame == post_video_get_frame) || (port->new_port.enable_ovl == post_video_enable_ovl) || (port->new_port.get_overlay_manager == post_video_get_overlay_manager)) { pthread_mutex_lock (&port->usage_lock); n = (--port->usage_count); if (port->usage_count || !port->post->dispose_pending) { pthread_mutex_unlock (&port->usage_lock); } else { pthread_mutex_unlock (&port->usage_lock); port->post->dispose (port->post); } } return n; } int _x_post_video_port_unref (xine_video_port_t *port_gen) { return post_video_port_unref (port_gen); } static uint32_t post_audio_get_capabilities (xine_audio_port_t *port_gen); static audio_buffer_t *post_audio_get_buffer (xine_audio_port_t *port_gen); static int post_audio_control (xine_audio_port_t *port_gen, int cmd, ...); static void post_audio_put_buffer (xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream); static int post_audio_port_ref (xine_audio_port_t *port_gen) { post_audio_port_t *port = (post_audio_port_t *)port_gen; int n = -1; if (!port) return n; if ((port->new_port.get_capabilities == post_audio_get_capabilities) || (port->new_port.get_buffer == post_audio_get_buffer) || (port->new_port.control == post_audio_control) || (port->new_port.put_buffer == post_audio_put_buffer)) { pthread_mutex_lock (&port->usage_lock); n = (++port->usage_count); pthread_mutex_unlock (&port->usage_lock); } return n; } int _x_post_audio_port_ref (xine_audio_port_t *port_gen) { return post_audio_port_ref (port_gen); } static int post_audio_port_unref (xine_audio_port_t *port_gen) { post_audio_port_t *port = (post_audio_port_t *)port_gen; int n = -1; if (!port) return n; if ((port->new_port.get_capabilities == post_audio_get_capabilities) || (port->new_port.get_buffer == post_audio_get_buffer) || (port->new_port.control == post_audio_control) || (port->new_port.put_buffer == post_audio_put_buffer)) { pthread_mutex_lock (&port->usage_lock); n = (--port->usage_count); if (port->usage_count || !port->post->dispose_pending) { pthread_mutex_unlock (&port->usage_lock); } else { pthread_mutex_unlock (&port->usage_lock); port->post->dispose (port->post); } } return n; } int _x_post_audio_port_unref (xine_audio_port_t *port_gen) { return post_audio_port_unref (port_gen); } void _x_post_init(post_plugin_t *post, int num_audio_inputs, int num_video_inputs) { post->input = xine_list_new(); post->output = xine_list_new(); post->xine_post.audio_input = calloc(num_audio_inputs + 1, sizeof(xine_audio_port_t *)); post->xine_post.video_input = calloc(num_video_inputs + 1, sizeof(xine_video_port_t *)); } /* dummy intercept functions that just pass the call on to the original port */ static uint32_t post_video_get_capabilities(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; uint32_t caps; if (port->port_lock) pthread_mutex_lock(port->port_lock); caps = port->original_port->get_capabilities(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return caps; } static void post_video_open(xine_video_port_t *port_gen, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)port_gen; _x_post_inc_usage (port); _x_post_rewire (port->post); if (port->port_lock) pthread_mutex_lock(port->port_lock); (port->original_port->open) (port->original_port, stream); if (port->port_lock) pthread_mutex_unlock(port->port_lock); if (stream) port->stream = stream; } static vo_frame_t *post_video_get_frame(xine_video_port_t *port_gen, uint32_t width, uint32_t height, double ratio, int format, int flags) { post_video_port_t *port = (post_video_port_t *)port_gen; vo_frame_t *frame; /* We always need to ref this port here to protect it from * possible port rewiring inside get_frame (). * In the intercept case, we save an extra unref. */ vf_alias_t *alias = post_new_video_alias (port, 1); if (port->port_lock) pthread_mutex_lock(port->port_lock); frame = port->original_port->get_frame(port->original_port, width, height, ratio, format, flags); if (port->port_lock) pthread_mutex_unlock(port->port_lock); if (frame && (!port->intercept_frame || port->intercept_frame(port, frame))) { frame = post_intercept_video_frame (port, frame, alias, 1); } else { post_free_unused_video_alias (port, alias); } return frame; } static vo_frame_t *post_video_get_last_frame(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; vo_frame_t *frame; if (port->port_lock) pthread_mutex_lock(port->port_lock); frame = port->original_port->get_last_frame(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return frame; } static xine_grab_video_frame_t *post_video_new_grab_video_frame(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; xine_grab_video_frame_t *frame; if (port->port_lock) pthread_mutex_lock(port->port_lock); frame = port->original_port->new_grab_video_frame(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return frame; } static void post_video_enable_ovl(xine_video_port_t *port_gen, int ovl_enable) { post_video_port_t *port = (post_video_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->enable_ovl(port->original_port, ovl_enable); if (port->port_lock) pthread_mutex_unlock(port->port_lock); } static void post_video_close(xine_video_port_t *port_gen, xine_stream_t *stream) { post_video_port_t *port = (post_video_port_t *)port_gen; vf_alias_t *f; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->close(port->original_port, stream); if (port->port_lock) pthread_mutex_unlock(port->port_lock); if (stream) { /* XXX: do a real stream database like video_out ? */ port->stream = NULL; pthread_mutex_lock (&port->usage_lock); f = (vf_alias_t *)port->free_frame_slots; while (f) { if ((f->frame.free == post_frame_free) && f->stream) { xine_stream_private_t *s = (xine_stream_private_t *)f->stream; xine_refs_sub (&s->refs, 1); f->stream = NULL; } f = (vf_alias_t *)f->frame.next; } pthread_mutex_unlock (&port->usage_lock); } _x_post_dec_usage (port); } static void post_video_exit(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->exit(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); } static video_overlay_manager_t *post_video_get_overlay_manager(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; video_overlay_manager_t *manager; if (port->port_lock) pthread_mutex_lock(port->port_lock); manager = port->original_port->get_overlay_manager(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); if (port->intercept_ovl && port->intercept_ovl(port)) { if (manager && !port->original_manager) /* this is the first access to overlay manager */ _x_post_intercept_overlay_manager(manager, port); else /* the original port might have changed */ port->original_manager = manager; return port->new_manager; } else return manager; } static void post_video_flush(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->flush(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); } static void post_video_trigger_drawing(xine_video_port_t *port_gen) { post_video_port_t *port = (post_video_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->trigger_drawing(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); } static int post_video_status(xine_video_port_t *port_gen, xine_stream_t *stream, int *width, int *height, int64_t *img_duration) { post_video_port_t *port = (post_video_port_t *)port_gen; int status; if (port->port_lock) pthread_mutex_lock(port->port_lock); status = port->original_port->status(port->original_port, stream, width, height, img_duration); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return status; } static int post_video_get_property(xine_video_port_t *port_gen, int property) { post_video_port_t *port = (post_video_port_t *)port_gen; int prop; if (port->port_lock) pthread_mutex_lock(port->port_lock); prop = port->original_port->get_property(port->original_port, property); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return prop; } static int post_video_set_property(xine_video_port_t *port_gen, int property, int value) { post_video_port_t *port = (post_video_port_t *)port_gen; int val; if (port->port_lock) pthread_mutex_lock(port->port_lock); val = port->original_port->set_property(port->original_port, property, value); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return val; } static int post_video_rewire(xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_video_port_t *new_port = (xine_video_port_t *)data; post_video_port_t *input_port = (post_video_port_t *)output->user_data; post_plugin_t *this = output->post; int64_t img_duration; int width, height; if (!new_port) return 0; this->running_ticket->revoke (this->running_ticket, XINE_TICKET_FLAG_REWIRE); if (new_port) { /* The wiring itself. */ post_video_port_ref (new_port); /* The user stuff. */ if (input_port->stream) new_port->open (new_port, input_port->stream); } if (input_port->original_port) { if (input_port->stream && input_port->original_port->status (input_port->original_port, input_port->stream, &width, &height, &img_duration)) input_port->original_port->close (input_port->original_port, input_port->stream); post_video_port_unref (input_port->original_port); } input_port->original_port = new_port; this->running_ticket->issue (this->running_ticket, XINE_TICKET_FLAG_REWIRE); return 1; } post_video_port_t *_x_post_intercept_video_port(post_plugin_t *post, xine_video_port_t *original, post_in_t **input, post_out_t **output) { post_video_port_t *port = calloc(1, sizeof(post_video_port_t)); if (!port) return NULL; port->new_port.get_capabilities = post_video_get_capabilities; port->new_port.open = post_video_open; port->new_port.get_frame = post_video_get_frame; port->new_port.get_last_frame = post_video_get_last_frame; port->new_port.new_grab_video_frame = post_video_new_grab_video_frame; port->new_port.enable_ovl = post_video_enable_ovl; port->new_port.close = post_video_close; port->new_port.exit = post_video_exit; port->new_port.get_overlay_manager = post_video_get_overlay_manager; port->new_port.flush = post_video_flush; port->new_port.trigger_drawing = post_video_trigger_drawing; port->new_port.status = post_video_status; port->new_port.get_property = post_video_get_property; port->new_port.set_property = post_video_set_property; port->new_port.driver = original->driver; post_video_port_ref (original); port->original_port = original; port->new_frame = &port->frame_storage; port->new_manager = &port->manager_storage; port->post = post; pthread_mutex_init(&port->usage_lock, NULL); pthread_mutex_init(&port->free_frames_lock, NULL); if (input) { *input = calloc(1, sizeof(post_in_t)); if (!*input) return port; (*input)->xine_in.name = "video in"; (*input)->xine_in.type = XINE_POST_DATA_VIDEO; (*input)->xine_in.data = &port->new_port; (*input)->post = post; xine_list_push_back(post->input, *input); } if (output) { *output = calloc(1, sizeof(post_out_t)); if (!*output) return port; (*output)->xine_out.name = "video out"; (*output)->xine_out.type = XINE_POST_DATA_VIDEO; (*output)->xine_out.data = &port->original_port; (*output)->xine_out.rewire = post_video_rewire; (*output)->post = post; (*output)->user_data = port; xine_list_push_back(post->output, *output); } return port; } /* Default intercept functions for frames. */ static void post_frame_free(vo_frame_t *vo_img) { post_video_port_t *port = _x_post_video_frame_to_port(vo_img); if (port->frame_lock) pthread_mutex_lock(port->frame_lock); if (--vo_img->lock_counter == 0) { /* this frame is free */ vo_img = post_restore_video_frame (vo_img, port, 1); /* unlock (port->frame_lock) already done above */ vo_img->free(vo_img); } else if (vo_img->next) { /* this frame is still in use */ _x_post_frame_copy_down(vo_img, vo_img->next); vo_img->next->free(vo_img->next); _x_post_frame_copy_up(vo_img, vo_img->next); if (port->frame_lock) pthread_mutex_unlock(port->frame_lock); } else { if (port->frame_lock) pthread_mutex_unlock(port->frame_lock); } } static void post_frame_proc_slice(vo_frame_t *vo_img, uint8_t **src) { post_video_port_t *port = _x_post_video_frame_to_port(vo_img); if (port->frame_lock) pthread_mutex_lock(port->frame_lock); _x_post_frame_copy_down(vo_img, vo_img->next); vo_img->next->proc_slice(vo_img->next, src); _x_post_frame_copy_up(vo_img, vo_img->next); if (port->frame_lock) pthread_mutex_unlock(port->frame_lock); } static void post_frame_proc_frame(vo_frame_t *vo_img) { post_video_port_t *port = _x_post_video_frame_to_port(vo_img); if (port->frame_lock) pthread_mutex_lock(port->frame_lock); _x_post_frame_copy_down(vo_img, vo_img->next); vo_img->next->proc_frame(vo_img->next); _x_post_frame_copy_up(vo_img, vo_img->next); if (port->frame_lock) pthread_mutex_unlock(port->frame_lock); } static void post_frame_field(vo_frame_t *vo_img, int which_field) { post_video_port_t *port = _x_post_video_frame_to_port(vo_img); if (port->frame_lock) pthread_mutex_lock(port->frame_lock); _x_post_frame_copy_down(vo_img, vo_img->next); vo_img->next->field(vo_img->next, which_field); _x_post_frame_copy_up(vo_img, vo_img->next); if (port->frame_lock) pthread_mutex_unlock(port->frame_lock); } static int post_frame_draw(vo_frame_t *vo_img, xine_stream_t *stream) { post_video_port_t *port = _x_post_video_frame_to_port(vo_img); int skip; if (port->frame_lock) pthread_mutex_lock(port->frame_lock); _x_post_frame_copy_down(vo_img, vo_img->next); skip = vo_img->next->draw(vo_img->next, stream); _x_post_frame_copy_up(vo_img, vo_img->next); if (port->frame_lock) pthread_mutex_unlock(port->frame_lock); return skip; } static void post_frame_lock(vo_frame_t *vo_img) { post_video_port_t *port = _x_post_video_frame_to_port(vo_img); if (port->frame_lock) pthread_mutex_lock(port->frame_lock); _x_post_frame_copy_down(vo_img, vo_img->next); vo_img->lock_counter++; vo_img->next->lock(vo_img->next); _x_post_frame_copy_up(vo_img, vo_img->next); if (port->frame_lock) pthread_mutex_unlock(port->frame_lock); } static void post_frame_dispose(vo_frame_t *vo_img) { post_video_port_t *port = _x_post_video_frame_to_port(vo_img); if (port->frame_lock) pthread_mutex_lock(port->frame_lock); vo_img = post_restore_video_frame (vo_img, port, 1); /* unlock (port->frame_lock) already done above */ vo_img->dispose(vo_img); } vo_frame_t *_x_post_intercept_video_frame(vo_frame_t *frame, post_video_port_t *port) { vf_alias_t *alias = post_new_video_alias (port, 0); return post_intercept_video_frame (port, frame, alias, 0); } vo_frame_t *_x_post_restore_video_frame(vo_frame_t *frame, post_video_port_t *port) { return post_restore_video_frame (frame, port, 0); } void _x_post_frame_copy_down(vo_frame_t *from, vo_frame_t *to) { /* propagate changes downwards (from decoders to video out) */ if (to->free == post_frame_free) { vf_alias_t *f = (vf_alias_t *)to; f->frame.stream = from->stream; if (f->frame.stream && (f->frame.stream != f->stream)) { xine_stream_private_t *s; s = (xine_stream_private_t *)f->frame.stream; xine_refs_add (&s->refs, 1); if (f->stream) { s = (xine_stream_private_t *)f->stream; xine_refs_sub (&s->refs, 1); } f->stream = f->frame.stream; } } to->pts = from->pts; to->bad_frame = from->bad_frame; to->duration = from->duration; to->top_field_first = from->top_field_first; to->repeat_first_field = from->repeat_first_field; to->progressive_frame = from->progressive_frame; to->picture_coding_type = from->picture_coding_type; to->drawn = from->drawn; to->crop_left = from->crop_left; to->crop_right = from->crop_right; to->crop_top = from->crop_top; to->crop_bottom = from->crop_bottom; to->ratio = from->ratio; if (to->extra_info != from->extra_info) _x_extra_info_merge(to->extra_info, from->extra_info); } void _x_post_frame_copy_up(vo_frame_t *to, vo_frame_t *from) { /* propagate changes upwards (from video out to decoders) */ if (to->free == post_frame_free) { vf_alias_t *f = (vf_alias_t *)to; f->frame.stream = from->stream; if (f->frame.stream && (f->frame.stream != f->stream)) { xine_stream_private_t *s; s = (xine_stream_private_t *)f->frame.stream; xine_refs_add (&s->refs, 1); if (f->stream) { s = (xine_stream_private_t *)f->stream; xine_refs_sub (&s->refs, 1); } f->stream = f->frame.stream; } } to->vpts = from->vpts; to->duration = from->duration; if (to->extra_info != from->extra_info) _x_extra_info_merge(to->extra_info, from->extra_info); } void _x_post_frame_u_turn(vo_frame_t *frame, xine_stream_t *stream) { /* frame's travel will end here => do the housekeeping */ if (frame->free == post_frame_free) { vf_alias_t *f = (vf_alias_t *)frame; f->frame.stream = stream; if (f->frame.stream && (f->frame.stream != f->stream)) { xine_stream_private_t *s; s = (xine_stream_private_t *)f->frame.stream; xine_refs_add (&s->refs, 1); if (f->stream) { s = (xine_stream_private_t *)f->stream; xine_refs_sub (&s->refs, 1); } f->stream = f->frame.stream; } } if (stream) { xine_stream_private_t *s = (xine_stream_private_t *)stream; _x_extra_info_merge (frame->extra_info, s->video_decoder_extra_info); stream->metronom->got_video_frame(stream->metronom, frame); } } /* dummy intercept functions that just pass the call on to the original overlay manager */ static void post_overlay_init(video_overlay_manager_t *ovl_gen) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); if (port->manager_lock) pthread_mutex_lock(port->manager_lock); port->original_manager->init(port->original_manager); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); } static void post_overlay_dispose(video_overlay_manager_t *ovl_gen) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); if (port->manager_lock) pthread_mutex_lock(port->manager_lock); port->original_manager->dispose(port->original_manager); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); } static int32_t post_overlay_get_handle(video_overlay_manager_t *ovl_gen, int object_type) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); int32_t handle; if (port->manager_lock) pthread_mutex_lock(port->manager_lock); handle = port->original_manager->get_handle(port->original_manager, object_type); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); return handle; } static void post_overlay_free_handle(video_overlay_manager_t *ovl_gen, int32_t handle) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); if (port->manager_lock) pthread_mutex_lock(port->manager_lock); port->original_manager->free_handle(port->original_manager, handle); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); } static int32_t post_overlay_add_event(video_overlay_manager_t *ovl_gen, void *event) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); int32_t result; if (port->manager_lock) pthread_mutex_lock(port->manager_lock); result = port->original_manager->add_event(port->original_manager, event); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); return result; } static void post_overlay_flush_events(video_overlay_manager_t *ovl_gen) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); if (port->manager_lock) pthread_mutex_lock(port->manager_lock); port->original_manager->flush_events(port->original_manager); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); } static int post_overlay_redraw_needed(video_overlay_manager_t *ovl_gen, int64_t vpts) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); int redraw; if (port->manager_lock) pthread_mutex_lock(port->manager_lock); redraw = port->original_manager->redraw_needed(port->original_manager, vpts); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); return redraw; } static void post_overlay_multiple_overlay_blend(video_overlay_manager_t *ovl_gen, int64_t vpts, vo_driver_t *output, vo_frame_t *vo_img, int enabled) { post_video_port_t *port = _x_post_ovl_manager_to_port(ovl_gen); if (port->manager_lock) pthread_mutex_lock(port->manager_lock); port->original_manager->multiple_overlay_blend(port->original_manager, vpts, output, vo_img, enabled); if (port->manager_lock) pthread_mutex_unlock(port->manager_lock); } void _x_post_intercept_overlay_manager(video_overlay_manager_t *original, post_video_port_t *port) { if (!port->new_manager->init) port->new_manager->init = post_overlay_init; if (!port->new_manager->dispose) port->new_manager->dispose = post_overlay_dispose; if (!port->new_manager->get_handle) port->new_manager->get_handle = post_overlay_get_handle; if (!port->new_manager->free_handle) port->new_manager->free_handle = post_overlay_free_handle; if (!port->new_manager->add_event) port->new_manager->add_event = post_overlay_add_event; if (!port->new_manager->flush_events) port->new_manager->flush_events = post_overlay_flush_events; if (!port->new_manager->redraw_needed) port->new_manager->redraw_needed = post_overlay_redraw_needed; if (!port->new_manager->multiple_overlay_blend) port->new_manager->multiple_overlay_blend = post_overlay_multiple_overlay_blend; port->original_manager = original; } /* dummy intercept functions that just pass the call on to the original port */ static uint32_t post_audio_get_capabilities(xine_audio_port_t *port_gen) { post_audio_port_t *port = (post_audio_port_t *)port_gen; uint32_t caps; if (port->port_lock) pthread_mutex_lock(port->port_lock); caps = port->original_port->get_capabilities(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return caps; } static int post_audio_get_property(xine_audio_port_t *port_gen, int property) { post_audio_port_t *port = (post_audio_port_t *)port_gen; int prop; if (port->port_lock) pthread_mutex_lock(port->port_lock); prop = port->original_port->get_property(port->original_port, property); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return prop; } static int post_audio_set_property(xine_audio_port_t *port_gen, int property, int value) { post_audio_port_t *port = (post_audio_port_t *)port_gen; int val; if (port->port_lock) pthread_mutex_lock(port->port_lock); val = port->original_port->set_property(port->original_port, property, value); if (port->port_lock) pthread_mutex_unlock(port->port_lock); return val; } static int post_audio_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; int result; _x_post_inc_usage (port); _x_post_rewire (port->post); if (port->port_lock) pthread_mutex_lock(port->port_lock); result = (port->original_port->open) (port->original_port, stream, bits, rate, mode); if (port->port_lock) pthread_mutex_unlock(port->port_lock); port->stream = stream; port->bits = bits; port->rate = rate; port->mode = mode; return result; } static audio_buffer_t *post_audio_get_buffer(xine_audio_port_t *port_gen) { post_audio_port_t *port = (post_audio_port_t *)port_gen; audio_buffer_t *buf; /* Ugly: we always need to ref this port here to protect it from * possible port rewiring inside get_buffer (). */ _x_post_inc_usage (port); if (port->port_lock) pthread_mutex_lock(port->port_lock); buf = port->original_port->get_buffer(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); _x_post_dec_usage (port); return buf; } static void post_audio_put_buffer(xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->put_buffer(port->original_port, buf, stream); if (port->port_lock) pthread_mutex_unlock(port->port_lock); } static void post_audio_close(xine_audio_port_t *port_gen, xine_stream_t *stream) { post_audio_port_t *port = (post_audio_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->close(port->original_port, stream); if (port->port_lock) pthread_mutex_unlock(port->port_lock); port->stream = NULL; _x_post_dec_usage(port); } static void post_audio_exit(xine_audio_port_t *port_gen) { post_audio_port_t *port = (post_audio_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->exit(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); } static int post_audio_control(xine_audio_port_t *port_gen, int cmd, ...) { post_audio_port_t *port = (post_audio_port_t *)port_gen; va_list args; void *arg; int rval; va_start(args, cmd); arg = va_arg(args, void*); if (port->port_lock) pthread_mutex_lock(port->port_lock); rval = port->original_port->control(port->original_port, cmd, arg); if (port->port_lock) pthread_mutex_unlock(port->port_lock); va_end(args); return rval; } static void post_audio_flush(xine_audio_port_t *port_gen) { post_audio_port_t *port = (post_audio_port_t *)port_gen; if (port->port_lock) pthread_mutex_lock(port->port_lock); port->original_port->flush(port->original_port); if (port->port_lock) pthread_mutex_unlock(port->port_lock); } static int post_audio_status(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t *bits, uint32_t *rate, int *mode) { post_audio_port_t *port = (post_audio_port_t *)port_gen; int result; if (port->port_lock) pthread_mutex_lock(port->port_lock); result = port->original_port->status(port->original_port, stream, bits, rate, mode); *bits = port->bits; *rate = port->rate; *mode = port->mode; if (port->port_lock) pthread_mutex_unlock(port->port_lock); return result; } static int post_audio_rewire(xine_post_out_t *output_gen, void *data) { post_out_t *output = (post_out_t *)output_gen; xine_audio_port_t *new_port = (xine_audio_port_t *)data; post_audio_port_t *input_port = (post_audio_port_t *)output->user_data; post_plugin_t *this = output->post; uint32_t bits, rate; int mode; if (!new_port) return 0; this->running_ticket->revoke (this->running_ticket, XINE_TICKET_FLAG_REWIRE); post_audio_port_ref (new_port); if (input_port->original_port->status(input_port->original_port, input_port->stream, &bits, &rate, &mode)) { (new_port->open) (new_port, input_port->stream, bits, rate, mode); input_port->original_port->close(input_port->original_port, input_port->stream); } post_audio_port_unref (input_port->original_port); input_port->original_port = new_port; this->running_ticket->issue (this->running_ticket, XINE_TICKET_FLAG_REWIRE); return 1; } post_audio_port_t *_x_post_intercept_audio_port(post_plugin_t *post, xine_audio_port_t *original, post_in_t **input, post_out_t **output) { post_audio_port_t *port = calloc(1, sizeof(post_audio_port_t)); if (!port) return NULL; port->new_port.open = post_audio_open; port->new_port.get_buffer = post_audio_get_buffer; port->new_port.put_buffer = post_audio_put_buffer; port->new_port.close = post_audio_close; port->new_port.exit = post_audio_exit; port->new_port.get_capabilities = post_audio_get_capabilities; port->new_port.get_property = post_audio_get_property; port->new_port.set_property = post_audio_set_property; port->new_port.control = post_audio_control; port->new_port.flush = post_audio_flush; port->new_port.status = post_audio_status; post_audio_port_ref (original); port->original_port = original; port->post = post; pthread_mutex_init(&port->usage_lock, NULL); if (input) { *input = calloc(1, sizeof(post_in_t)); if (!*input) return port; (*input)->xine_in.name = "audio in"; (*input)->xine_in.type = XINE_POST_DATA_AUDIO; (*input)->xine_in.data = &port->new_port; (*input)->post = post; xine_list_push_back(post->input, *input); } if (output) { *output = calloc(1, sizeof(post_out_t)); if (!*output) return port; (*output)->xine_out.name = "audio out"; (*output)->xine_out.type = XINE_POST_DATA_AUDIO; (*output)->xine_out.data = &port->original_port; (*output)->xine_out.rewire = post_audio_rewire; (*output)->post = post; (*output)->user_data = port; xine_list_push_back(post->output, *output); } return port; } int _x_post_dispose(post_plugin_t *this) { int i, j, in_use = 0; /* acquire all usage locks, and check counters. */ for (i = 0; this->xine_post.audio_input[i]; i++) { post_audio_port_t *port = (post_audio_port_t *)this->xine_post.audio_input[i]; pthread_mutex_lock(&port->usage_lock); in_use += port->usage_count; } for (j = 0; this->xine_post.video_input[j]; j++) { post_video_port_t *port = (post_video_port_t *)this->xine_post.video_input[j]; pthread_mutex_lock(&port->usage_lock); in_use += port->usage_count; } /* we can set this witout harm, because it is always checked with * usage lock held */ this->dispose_pending = 1; /* free the locks */ for (j--; j >= 0; j--) { post_video_port_t *port = (post_video_port_t *)this->xine_post.video_input[j]; pthread_mutex_unlock(&port->usage_lock); } for (i--; i >= 0; i--) { post_audio_port_t *port = (post_audio_port_t *)this->xine_post.audio_input[i]; pthread_mutex_unlock(&port->usage_lock); } xprintf (this->xine, XINE_VERBOSITY_DEBUG, "post: _x_post_dispose (%p): %d refs.\n", (void*)this, in_use); if (!in_use) { xine_post_in_t *input; xine_post_out_t *output; xine_list_iterator_t ite; /* we can really dispose it */ _x_freep(&this->xine_post.audio_input); _x_freep(&this->xine_post.video_input); /* these were allocated in the plugin loader */ _x_freep(&this->input_ids); _x_freep(&this->output_ids); ite = NULL; while ((input = xine_list_next_value (this->input, &ite))) { switch (input->type) { case XINE_POST_DATA_VIDEO: { post_video_port_t *port = (post_video_port_t *)input->data; vf_alias_t *f; post_video_port_unref (port->original_port); pthread_mutex_destroy(&port->usage_lock); pthread_mutex_destroy(&port->free_frames_lock); f = (vf_alias_t *)port->free_frame_slots; if (f) { int n = 0; do { vf_alias_t *next = (vf_alias_t *)f->frame.next; if ((f->frame.free == post_frame_free) && f->stream) { xine_stream_private_t *s = (xine_stream_private_t *)f->stream; xine_refs_sub (&s->refs, 1); } free (f); n++; f = next; } while (f); port->free_frame_slots = NULL; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "post: freed %d video frame aliases.\n", n); } NAILS_S (port, 0x53); NAILS_S (input, 0x54); free(port); free(input); } break; case XINE_POST_DATA_AUDIO: { post_audio_port_t *port = (post_audio_port_t *)input->data; post_audio_port_unref (port->original_port); pthread_mutex_destroy(&port->usage_lock); NAILS_S (port, 0x53); NAILS_S (input, 0x54); free(port); free(input); } break; } } ite = NULL; while ((output = xine_list_next_value (this->output, &ite))) { switch (output->type) { case XINE_POST_DATA_VIDEO: if (output->rewire == post_video_rewire) { /* we allocated it, we free it */ NAILS_S (output, 0x52); free(output); } break; case XINE_POST_DATA_AUDIO: if (output->rewire == post_audio_rewire) { /* we allocated it, we free it */ NAILS_S (output, 0x52); free(output); } break; } } xine_list_delete(this->input); xine_list_delete(this->output); /* since the plugin loader does not know, when the plugin gets disposed, * we have to handle the reference counter here */ pthread_mutex_lock(&this->xine->plugin_catalog->lock); this->node->ref--; pthread_mutex_unlock(&this->xine->plugin_catalog->lock); NAILS_S (this, 0x55); return 1; } return 0; } xine-lib-1.2/src/xine-engine/load_plugins.c0000644000175000017500000032352714647725152016521 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * Load input/demux/audio_out/video_out/codec plugins */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #ifdef HAVE_DIRENT_H #include #endif #include #include #include #include #include #include #include #include #define LOG_MODULE "load_plugins" #define LOG_VERBOSE /* #define LOG #define DEBUG */ #define XINE_ENABLE_EXPERIMENTAL_FEATURES 1 /* save 1 lookup per entry by caching entry pointers not keys. */ #define FAST_SCAN_PLUGINS #include #include #include #include #include #include #include #include #include #include #include #include #include "xine_private.h" #ifdef XINE_MAKE_BUILTINS #include "builtins.h" #endif #if 0 static char *plugin_name; #if DONT_CATCH_SIGSEGV #define install_segv_handler() #define remove_segv_handler() #else void (*old_segv_handler)(int); static void segv_handler (int hubba) { printf ("\nload_plugins: Initialization of plugin '%s' failed (segmentation fault).\n",plugin_name); printf ("load_plugins: You probably need to remove the offending file.\n"); printf ("load_plugins: (This error is usually due an incorrect plugin version)\n"); _x_abort(); } static void install_segv_handler(void){ old_segv_handler = signal (SIGSEGV, segv_handler); } static void remove_segv_handler(void){ signal (SIGSEGV, old_segv_handler ); } #endif #endif /* 0 */ #define CACHE_CATALOG_VERSION 5 #define CACHE_CATALOG_VERSION_STR "5" #define MAX_DUPL_CFG_ENTRIES 256 #define __Max(a,b) ((a) > (b) ? (a) : (b)) static const uint8_t plugin_iface_versions[__Max(PLUGIN_TYPE_MAX, PLUGIN_XINE_MODULE) + 1] = { [PLUGIN_INPUT] = INPUT_PLUGIN_IFACE_VERSION, [PLUGIN_DEMUX] = DEMUXER_PLUGIN_IFACE_VERSION, [PLUGIN_AUDIO_DECODER] = AUDIO_DECODER_IFACE_VERSION, [PLUGIN_VIDEO_DECODER] = VIDEO_DECODER_IFACE_VERSION, [PLUGIN_SPU_DECODER] = SPU_DECODER_IFACE_VERSION, [PLUGIN_AUDIO_OUT] = AUDIO_OUT_IFACE_VERSION, [PLUGIN_VIDEO_OUT] = VIDEO_OUT_DRIVER_IFACE_VERSION, [PLUGIN_POST] = POST_PLUGIN_IFACE_VERSION, [PLUGIN_XINE_MODULE] = XINE_MODULE_IFACE_VERSION, }; typedef union { vo_info_t vo_info; ao_info_t ao_info; demuxer_info_t demuxer_info; input_info_t input_info; decoder_info_t decoder_info; post_info_t post_info; xine_module_info_t module_info; } all_info_t; typedef struct fat_node_st { plugin_node_t node; plugin_info_t info[2]; all_info_t ainfo; plugin_file_t file; #define FAT_NODE_FLAG_PROBE_CLASS 1 uint32_t flags; struct fat_node_st *nextplugin, *lastplugin; xine_t *xine; uint32_t supported_types[1]; } fat_node_t; /* effectively next: uint32_t supported_types[num_supported_types]; char id[idlen + 1]; xine_fast_string_t filename[fnlen + n]; */ #define IS_FAT_NODE(_node) (_node->node.info == &_node->info[0]) static void _fat_node_init (fat_node_t *node) { #ifdef HAVE_ZERO_SAFE_MEM memset (node, 0, sizeof (*node)); #else node->node.file = NULL; node->node.info = NULL; node->node.plugin_class = NULL; node->node.config_entry_list = NULL; node->node.ref = 0; node->node.priority = 0; node->info[0].type = 0; node->info[0].API = 0; node->info[0].id = NULL; node->info[0].version = 0; node->info[0].special_info = NULL; node->info[0].init = NULL; node->info[1].type = 0; node->ainfo.decoder_info.supported_types = NULL; node->ainfo.decoder_info.priority = 0; node->flags = 0; node->file.filename = NULL; node->file.filesize = 0; node->file.filemtime = 0; node->file.lib_handle = NULL; node->file.ref = 0; node->file.no_unload = 0; node->supported_types[0] = 0; node->nextplugin = NULL; node->xine = NULL; #endif node->lastplugin = node; } static int _fat_node_file_cmp (void *a_gen, void *b_gen) { fat_node_t *a = a_gen, *b = b_gen; if (a->file.filesize != b->file.filesize) return a->file.filesize < b->file.filesize ? -1 : 1; if (a->file.filemtime != b->file.filemtime) return a->file.filemtime < b->file.filemtime ? -1 : 1; /* 2 files with same size and time are extremely rare. * however, same file (with long file name) is frequent * when scanning the plugin cache, * and thie alwayy uses fat_node_t. */ return xine_fast_string_cmp (a->file.filename, b->file.filename); } static const uint8_t tab_tolower[256] = { 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z', 91, 92, 93, 94, 95, 96,'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o', 'p','q','r','s','t','u','v','w','x','y','z',123,124,125,126,127, 128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223, 224,225,226,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 }; static const uint8_t tab_mime[256] = { ['\0'] = 1, ['\r'] = 2, ['\n'] = 2, ['\t'] = 2, [' '] = 2, [':'] = 4, [';'] = 8 }; static void _mime_set (uint8_t *buf, size_t bsize, const char *needle) { const uint8_t *n = (const uint8_t *)needle; uint8_t *e = buf + bsize - 1, *q = buf; if (!n) { buf[0] = 0; return; } /* skip leading needle space */ while (tab_mime[*n] & 2) n++; /* pattern = lowercase needle */ while ((q < e) && !(tab_mime[*n] & (1 | 2 | 4 | 8))) *q++ = tab_tolower[*n++]; e = q; /* safe brake */ *e = 'A'; } static int _mime_find (uint8_t *buf, const char *haystack) { const uint8_t *h = (const uint8_t *)haystack; if (!buf[0] || !h) return -1; while (1) { const uint8_t *n; int o; while (tab_mime[*h] & 2) h++; o = h - (const uint8_t *)haystack; n = buf; while (*n == tab_tolower[*h]) n++, h++; if ((*n == 'A') && (tab_mime[*h] & (1 | 2 | 4 | 8))) return o; while (!(tab_mime[*h] & (1 | 8))) h++; if (!*h) break; h++; } return -1; } static const char * const *_build_list_typed_plugins (xine_t *xine, int type, uint64_t mask) { plugin_catalog_t *catalog = xine->plugin_catalog; xine_sarray_t *a, *list; int list_id, list_size, i; pthread_mutex_lock (&catalog->lock); list = catalog->plugin_lists[type - 1]; list_size = xine_sarray_size (list); /* Note const char * --> void * is ok here as the strings are never written to. */ a = xine_sarray_new (list_size, (xine_sarray_comparator_t)strcmp); if (!a) { catalog->ids[0] = NULL; pthread_mutex_unlock (&catalog->lock); return catalog->ids; } xine_sarray_set_mode (a, XINE_SARRAY_MODE_UNIQUE); if (type == PLUGIN_VIDEO_OUT) { for (list_id = 0, i = 0; list_id < list_size; list_id++) { plugin_node_t *node = xine_sarray_get (list, list_id); const vo_info_t *info = (const vo_info_t *)node->info->special_info; if (info) { if (!(mask & ((uint64_t)1 << info->visual_type))) continue; } /* add only unique ids to the list */ if (xine_sarray_add (a, (void *)node->info->id) >= 0) catalog->ids[i++] = node->info->id; } } else { for (list_id = 0, i = 0; list_id < list_size; list_id++) { plugin_node_t *node = xine_sarray_get (list, list_id); /* add only unique ids to the list */ if (xine_sarray_add (a, (void *)node->info->id) >= 0) catalog->ids[i++] = node->info->id; } } catalog->ids[i] = NULL; pthread_mutex_unlock (&catalog->lock); xine_sarray_delete (a); return catalog->ids; } static void inc_file_ref(plugin_file_t *file) { /* all users do dereference "file" before calling this _x_assert(file); */ file->ref++; } static void dec_file_ref(plugin_file_t *file) { /* all users do test "file" before calling this _x_assert(file); */ _x_assert(file->ref > 0); file->ref--; lprintf("file %s referenced %d time(s)\n", file->filename, file->ref); } static void inc_node_ref(plugin_node_t *node) { /* all users do dereference "node" before calling this _x_assert(node); */ node->ref++; } static void dec_node_ref(plugin_node_t *node) { /* all users do test "node" before calling this _x_assert(node); */ _x_assert(node->ref > 0); node->ref--; lprintf("node %s referenced %d time(s)\n", node->info->id, node->ref); } #ifndef FAST_SCAN_PLUGINS static void _free_string_list(xine_list_t **plist) { xine_list_t *list = *plist; if (list) { char *key; xine_list_iterator_t ite = NULL; while ((key = xine_list_next_value (list, &ite))) free (key); xine_list_delete(list); *plist = NULL; } } #endif /* * plugin list/catalog management functions */ static void map_decoder_list (xine_t *this, xine_sarray_t *decoder_list, plugin_node_t *decoder_map[DECODER_MAX][PLUGINS_PER_TYPE]) { int i; int list_id, list_size; /* init */ for (i = 0; i < DECODER_MAX; i++) { decoder_map[i][0] = NULL; } /* * map decoders */ list_size = xine_sarray_size(decoder_list); /* this is sorted by falling priorities */ for (list_id = 0; list_id < list_size; list_id++) { plugin_node_t *node = xine_sarray_get(decoder_list, list_id); const uint32_t *type = ((const decoder_info_t *)node->info->special_info)->supported_types; lprintf ("mapping decoder %s\n", node->info->id); while (type && (*type)) { int pos; int streamtype = ((*type)>>16) & 0xFF; lprintf ("load_plugins: decoder handles stream type %02x, priority %d\n", streamtype, node->priority); /* find the right place based on the priority */ for (pos = 0; pos < PLUGINS_PER_TYPE; pos++) { if (!decoder_map[streamtype][pos]) break; } if ( pos == PLUGINS_PER_TYPE ) { xine_log (this, XINE_LOG_PLUGIN, _("map_decoder_list: no space for decoder, skipped.\n")); type++; continue; } /* shift the decoder list for this type by one to make room for new decoder */ if (pos < PLUGINS_PER_TYPE - 1) decoder_map[streamtype][pos + 1] = NULL; /* insert new decoder */ decoder_map[streamtype][pos] = node; lprintf("decoder inserted in decoder map at %d\n", pos); type++; } } } static void map_decoders (xine_t *this) { plugin_catalog_t *catalog = this->plugin_catalog; lprintf ("map_decoders\n"); /* * map audio decoders */ map_decoder_list(this, catalog->plugin_lists[PLUGIN_AUDIO_DECODER - 1], catalog->audio_decoder_map); map_decoder_list(this, catalog->plugin_lists[PLUGIN_VIDEO_DECODER - 1], catalog->video_decoder_map); map_decoder_list(this, catalog->plugin_lists[PLUGIN_SPU_DECODER - 1], catalog->spu_decoder_map); } /* Decoder priority callback */ static void _decoder_priority_cb (void *data, xine_cfg_entry_t *cfg) { /* sort decoders by priority */ xine_sarray_t *list; int type; fat_node_t *node = data; if (!node) return; type = node->info->type & PLUGIN_TYPE_MASK; list = node->xine->plugin_catalog->plugin_lists[type - 1]; if (xine_sarray_remove_ptr (list, node) == ~0) /* callback was triggered before the entry was added to plugin list */ return; { int user_prio = cfg->num_value; /* user given priorities should definitely override defaults, so multiply them */ node->node.priority = user_prio ? user_prio * 100 : node->ainfo.decoder_info.priority; } xine_sarray_add (list, node); map_decoder_list (node->xine, list, type == PLUGIN_AUDIO_DECODER ? node->xine->plugin_catalog->audio_decoder_map : type == PLUGIN_VIDEO_DECODER ? node->xine->plugin_catalog->video_decoder_map : node->xine->plugin_catalog->spu_decoder_map); } static plugin_file_t *_insert_file (xine_list_t *list, const char *filename, const struct stat *statbuffer, void *lib, uint32_t name_len) { plugin_file_t *entry; char *p; /* create the file entry */ p = malloc (sizeof (*entry) + name_len + 1); if (!p) return NULL; entry = (plugin_file_t *)p; p += sizeof (*entry); entry->filename = p; xine_small_memcpy (p, filename, name_len + 1); entry->filesize = statbuffer->st_size; entry->filemtime = statbuffer->st_mtime; entry->lib_handle = lib; entry->ref = 0; entry->no_unload = 0; xine_list_push_back (list, entry); return entry; } static int _insert_node (xine_t *this, plugin_file_t *file, fat_node_t *node_cache, const plugin_info_t *info, uint32_t flags) { fat_node_t *entry; const all_info_t *ainfo; unsigned int num_supported_types = 0; unsigned int plugin_type = info->type & PLUGIN_TYPE_MASK; int left; const char *what; /* sanity test */ left = PLUGIN_MAX - this->plugin_catalog->plugin_count; do { unsigned int flag; if ((plugin_type <= 0) || ((plugin_type > PLUGIN_TYPE_MAX) && plugin_type != PLUGIN_XINE_MODULE)) { if (file) xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: unknown plugin type %d in %s\n"), plugin_type, file->filename); else xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: unknown statically linked plugin type %d\n"), plugin_type); return 1; } if (!info->id) { what = "id"; break; } if (info->API != plugin_iface_versions[plugin_type]) { xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: ignoring plugin %s, wrong iface version %d (should be %d)\n"), info->id, info->API, plugin_iface_versions[plugin_type]); return 1; } if (!node_cache && !info->init) { what = "init"; break; } ainfo = info->special_info; flag = 1u << plugin_type; if (flag & ((1u << PLUGIN_VIDEO_OUT) | (1u << PLUGIN_AUDIO_OUT) | (1u << PLUGIN_POST) | (1u << PLUGIN_AUDIO_DECODER) | (1u << PLUGIN_VIDEO_DECODER) | (1u << PLUGIN_SPU_DECODER) | (1u << PLUGIN_XINE_MODULE))) { if (!ainfo) { what = "special_info"; break; } } if (flag & ((1u << PLUGIN_AUDIO_DECODER) | (1u << PLUGIN_VIDEO_DECODER) | (1u << PLUGIN_SPU_DECODER))) { if (!ainfo->decoder_info.supported_types) { what = "supported_types"; break; } if (!node_cache) { while (ainfo->decoder_info.supported_types[num_supported_types]) num_supported_types++; } if (left > DECODER_MAX - this->plugin_catalog->decoder_count) left = DECODER_MAX - this->plugin_catalog->decoder_count; } what = NULL; } while (0); if (what) { xine_log (this, XINE_LOG_PLUGIN, "load_plugins: plugin %s from %s is broken: %s = NULL\n", info->id ? info->id : "??", file ? file->filename : "user", what); return 1; } if (left <= 0) { if (file) xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: plugin limit reached, %s could not be loaded\n"), file->filename); else xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: plugin limit reached, static plugin could not be loaded\n")); return 2; } /* get target */ if (node_cache) { entry = node_cache; } else { size_t idlen = xine_find_byte (info->id, 0) + 1; char *q; entry = malloc (sizeof (*entry) + num_supported_types * sizeof (uint32_t) + idlen); if (!entry) return 2; _fat_node_init (entry); entry->node.info = &entry->info[0]; entry->info[0] = *info; entry->flags = flags; q = (char *)entry + sizeof (*entry) + num_supported_types * sizeof (uint32_t); entry->info[0].id = q; xine_small_memcpy (q, info->id, idlen); } entry->lastplugin = entry; entry->xine = this; entry->node.file = file; /* type specific stuff */ switch (plugin_type) { case PLUGIN_VIDEO_OUT: entry->node.priority = entry->ainfo.vo_info.priority = ainfo->vo_info.priority; entry->ainfo.vo_info.visual_type = ainfo->vo_info.visual_type; entry->flags &= ~FAT_NODE_FLAG_PROBE_CLASS; break; case PLUGIN_AUDIO_OUT: entry->node.priority = entry->ainfo.ao_info.priority = ainfo->ao_info.priority; entry->flags &= ~FAT_NODE_FLAG_PROBE_CLASS; break; case PLUGIN_AUDIO_DECODER: case PLUGIN_VIDEO_DECODER: case PLUGIN_SPU_DECODER: if (num_supported_types) memcpy (&entry->supported_types[0], ainfo->decoder_info.supported_types, (num_supported_types + 1) * sizeof (uint32_t)); entry->ainfo.decoder_info.supported_types = &entry->supported_types[0]; entry->ainfo.decoder_info.priority = ainfo->decoder_info.priority; { /* cnfig does dup all strings. no need to keep them here. */ xine_private_t *_xine = (xine_private_t *)this; char key[128], desc[256]; int user_prio; memcpy (key, "engine.decoder_priorities.", 26); strlcpy (key + 26, info->id, sizeof (key) - 26); snprintf (desc, sizeof (desc) - 1, _("priority for %s decoder"), info->id); user_prio = this->config->register_num (this->config, key, 0, desc, _xine->strings.decoder_pri_help, 20, _decoder_priority_cb, entry); /* reset priority on old config files */ if (this->config->current_version < 1) { this->config->update_num (this->config, key, 0); user_prio = 0; } entry->node.priority = user_prio ? user_prio * 100 : entry->ainfo.decoder_info.priority; } this->plugin_catalog->decoder_count++; break; case PLUGIN_POST: entry->ainfo.post_info.type = ainfo->post_info.type; break; case PLUGIN_DEMUX: if (ainfo) { entry->node.priority = entry->ainfo.demuxer_info.priority = ainfo->demuxer_info.priority; lprintf("demux: %s, priority: %d\n", info->id, entry->node.priority); } else { xprintf(this, XINE_VERBOSITY_LOG, _("load_plugins: demuxer plugin %s does not provide a priority," " xine-lib will use the default priority.\n"), info->id); entry->node.priority = entry->ainfo.demuxer_info.priority = 0; } break; case PLUGIN_INPUT: if (ainfo) { entry->node.priority = entry->ainfo.input_info.priority = ainfo->input_info.priority; lprintf("input: %s, priority: %d\n", info->id, entry->node.priority); } else { xprintf(this, XINE_VERBOSITY_LOG, _("load_plugins: input plugin %s does not provide a priority," " xine-lib will use the default priority.\n"), info->id); entry->node.priority = entry->ainfo.input_info.priority = 0; } break; case PLUGIN_XINE_MODULE: entry->node.priority = ainfo->module_info.priority; entry->ainfo.module_info = ainfo->module_info; entry->flags &= ~FAT_NODE_FLAG_PROBE_CLASS; break; } entry->info[0].special_info = &entry->ainfo; if (file && (info->type & PLUGIN_NO_UNLOAD)) { file->no_unload = 1; } if (plugin_type == PLUGIN_XINE_MODULE) xine_sarray_add (this->plugin_catalog->modules_list, &entry->node); else xine_sarray_add (this->plugin_catalog->plugin_lists[plugin_type - 1], &entry->node); this->plugin_catalog->plugin_count++; return 0; } static int _plugin_node_comparator(void *a, void *b) { const plugin_node_t *node_a = (const plugin_node_t *)a; const plugin_node_t *node_b = (const plugin_node_t *)b; return (node_a->priority < node_b->priority) - (node_a->priority > node_b->priority); } /* xine-ui simply makes a user config enum from post plugin list, and assumes the first one * as the default. This effectively becomes a random choice, depending on the presence of * other plugins, and of the order the file system returns them. So lets sort them by name * as well here. */ static int _post_plugin_node_comparator (void *a, void *b) { const plugin_node_t *node_a = (const plugin_node_t *)a; const plugin_node_t *node_b = (const plugin_node_t *)b; if (node_a->priority != node_b->priority) return node_a->priority < node_b->priority ? 1 : -1; return strcmp (node_a->info->id, node_b->info->id); } static plugin_catalog_t *_new_catalog(void){ plugin_catalog_t *catalog; catalog = calloc (1, sizeof (plugin_catalog_t)); if (catalog) { int i; for (i = 0; i < PLUGIN_TYPE_MAX; i++) { catalog->plugin_lists[i] = xine_sarray_new (0, i == PLUGIN_POST - 1 ? _post_plugin_node_comparator : _plugin_node_comparator); if (!catalog->plugin_lists[i]) break; } if (i == PLUGIN_TYPE_MAX) { catalog->cache_list = xine_sarray_new (0, _fat_node_file_cmp); if (catalog->cache_list) { xine_sarray_set_mode (catalog->cache_list, XINE_SARRAY_MODE_UNIQUE); catalog->file_list = xine_list_new (); if (catalog->file_list) { catalog->modules_list = xine_sarray_new (0, _plugin_node_comparator); if (catalog->modules_list) { pthread_mutexattr_t attr; pthread_mutexattr_init (&attr); pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init (&catalog->lock, &attr); pthread_mutexattr_destroy (&attr); return catalog; } xine_list_delete (catalog->file_list); } xine_sarray_delete (catalog->cache_list); } } for (--i; i >= 0; i--) xine_sarray_delete (catalog->plugin_lists[i]); free (catalog); } return NULL; } static void _register_plugins_internal (xine_t *this, plugin_file_t *file, fat_node_t *node_cache, const plugin_info_t *info, uint32_t flags) { /* user supplied xine_register_plugins () */ static const char * const st_names[10] = { "user/none", "user/input", "user/demux", "user/audio_decoder", "user/video_decoder", "user/spu_decoder", "user/audio_out", "user/video_out", "user/post", "user" }; const char * const *names = st_names; #ifdef XINE_MAKE_BUILTINS static const char * const builtin_names[10] = { "libxine/builtins/none", "libxine/builtins/input", "libxine/builtins/demux", "libxine/builtins/audio_decoder", "libxine/builtins/video_decoder", "libxine/builtins/spu_decoder", "libxine/builtins/audio_out", "libxine/builtins/video_out", "libxine/builtins/post", "libxine/builtins" }; if (info == xine_builtin_plugin_info) names = builtin_names; #endif /* we had worse NOPs before ;-) _x_assert(info); */ while ( info && info->type != PLUGIN_NONE ) { fat_node_t *cache_next = node_cache ? node_cache->nextplugin : NULL; const char *fn; int status; if (file) { fn = file->filename; } else { int n = info->type & PLUGIN_TYPE_MASK; if (n > 9) n = 9; fn = names[n]; } xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: plugin %s:%s found\n"), fn, info->id); status = _insert_node (this, file, node_cache, info, flags); /* get next info */ if (file && !file->lib_handle) { lprintf("get cached info\n"); if (status) free (node_cache); node_cache = cache_next; info = node_cache ? node_cache->node.info : NULL; } else { info++; } } } void xine_register_plugins(xine_t *self, const plugin_info_t *info) { if (self) _register_plugins_internal (self, NULL, NULL, info, 0); } /* * First stage plugin loader (catalog builder) * ***************************************************************************/ /* NOTE: path actually is a xine_fast_string_t *. */ static void collect_plugins (xine_t *this, char *path, char *stop, char *pend) { char *adds[5]; DIR *dirs[5]; struct stat statbuf; int level; lprintf ("collect_plugins in %s\n", path); /* we need a dir to start */ if (stat (path, &statbuf)) return; if (!S_ISDIR (statbuf.st_mode)) return; adds[0] = stop; dirs[0] = NULL; level = 0; while (1) { struct dirent *dent; /* enter dir */ if (!dirs[level]) { dirs[level] = opendir (path); if (!dirs[level]) { xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: skipping unreadable plugin directory %s.\n"), path); level--; if (level < 0) break; continue; } } /* get entry */ dent = readdir (dirs[level]); if (!dent) { closedir (dirs[level]); level--; if (level < 0) break; continue; } { void *lib = NULL; const plugin_info_t *info = NULL; fat_node_t *fatn_found; char *part = adds[level], *q; *part++ = '/'; q = part + strlcpy (part, dent->d_name, pend - part); if (q >= pend) continue; if (stat (path, &statbuf)) { xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: unable to stat %s\n"), path); continue; } switch (statbuf.st_mode & S_IFMT) { case S_IFREG: /* regular file, ie. plugin library, found => load it */ /* this will fail whereever shared libs are called *.dll or such * better solutions: * a) don't install .la files on user's system * b) also cache negative hits, ie. files that failed to dlopen() */ #if defined(__hpux) if (!strstr (part, ".sl") #elif defined(__CYGWIN__) || defined(WIN32) if (!strstr (part, ".dll") || strstr (part, ".dll.a") #else if (!strstr (part, ".so") #endif #ifdef HOST_OS_DARWIN && !strcasestr (part, ".xineplugin") #endif ) break; lib = NULL; /* get the first plugin_info_t */ { fat_node_t fatn_try; int index; xine_fast_string_set (path, NULL, q - path); fatn_try.file.filename = path; fatn_try.file.filesize = statbuf.st_size; fatn_try.file.filemtime = statbuf.st_mtime; index = xine_sarray_binary_search (this->plugin_catalog->cache_list, &fatn_try); if (index >= 0) { fatn_found = xine_sarray_get (this->plugin_catalog->cache_list, index); xine_sarray_remove (this->plugin_catalog->cache_list, index); } else { fatn_found = NULL; } } info = fatn_found ? fatn_found->node.info : NULL; #ifdef LOG if( info ) printf ("load_plugins: using cached %s\n", path); else printf ("load_plugins: %s not cached\n", path); #endif if (!info && (lib = dlopen (path, RTLD_LAZY | RTLD_GLOBAL)) == NULL) { const char *error = dlerror(); /* too noisy -- but good to catch unresolved references */ xprintf (this, XINE_VERBOSITY_LOG, _("load_plugins: cannot open plugin lib %s:\n%s\n"), path, error); } else { if (info || (info = dlsym(lib, "xine_plugin_info"))) { plugin_file_t *file; file = _insert_file (this->plugin_catalog->file_list, path, &statbuf, lib, q - path); if (file) { _register_plugins_internal (this, file, fatn_found, info, fatn_found ? 0 : FAT_NODE_FLAG_PROBE_CLASS); } else { if (lib != NULL) dlclose(lib); } } else { const char *error = dlerror(); xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: can't get plugin info from %s:\n%s\n"), path, error); dlclose(lib); } } break; case S_IFDIR: /* unless ".", "..", ".hidden" or vidix driver dirs */ if ((part[0] != '.') && strcmp (part, "vidix")) { if (level < 4) { level++; adds[level] = q; dirs[level] = NULL; } } } /* switch */ } } /* while */ } /* collect_plugins */ /* * generic 2nd stage plugin loader */ static inline int _plugin_info_equal(const plugin_info_t *a, const plugin_info_t *b) { if (a->type != b->type || a->API != b->API || strcasecmp(a->id, b->id) || a->version != b->version) return 0; switch (a->type & PLUGIN_TYPE_MASK) { case PLUGIN_VIDEO_OUT: /* FIXME: Could special_info be NULL? */ if (a->special_info && b->special_info) { return (((const vo_info_t*)a->special_info)->visual_type == ((const vo_info_t*)b->special_info)->visual_type); } /* if special info is missing, plugin file is broken ... */ return 0; /* skip it */ case PLUGIN_XINE_MODULE: if (a->special_info && b->special_info) { return !strcmp(((const xine_module_info_t*)a->special_info)->type, ((const xine_module_info_t*)b->special_info)->type); } return !(!a->special_info - !b->special_info); default: break; } return 1; } #ifdef FAST_SCAN_PLUGINS typedef struct { config_values_t *v; plugin_node_t *node; cfg_entry_t *cfg_entry; } new_entry_data_t; #else static void _attach_entry_to_node (plugin_node_t *node, char *key) { if (!node->config_entry_list) { node->config_entry_list = xine_list_new(); } xine_list_push_back(node->config_entry_list, key); } #endif /* * This callback is called by the config entry system when a plugin register a * new config entry. */ static void _new_entry_cb (void *user_data, xine_cfg_entry_t *entry) { #ifdef FAST_SCAN_PLUGINS new_entry_data_t *d = user_data; if (!d->node->config_entry_list) d->node->config_entry_list = xine_list_new (); if (d->node->config_entry_list && d->v->cur && !xine_list_find (d->node->config_entry_list, d->v->cur)) d->cfg_entry = d->v->cur, xine_list_push_back (d->node->config_entry_list, d->v->cur); (void)entry; #else plugin_node_t *node = (plugin_node_t *)user_data; _attach_entry_to_node(node, strdup(entry->key)); #endif } static int _load_plugin_class(xine_t *this, plugin_node_t *node, const void *data) { if (node->file) { const char *filename = node->file->filename; const plugin_info_t *target = node->info; const plugin_info_t *info; void *lib; /* load the dynamic library if needed */ if (!node->file->lib_handle) { lprintf("dlopen %s\n", filename); if ((lib = dlopen (filename, RTLD_LAZY | RTLD_GLOBAL)) == NULL) { const char *error = dlerror(); xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: cannot (stage 2) open plugin lib %s:\n%s\n"), filename, error); return 0; } else { node->file->lib_handle = lib; } } else { lprintf("%s already loaded\n", filename); } if ((info = dlsym(node->file->lib_handle, "xine_plugin_info"))) { /* TODO: use sigsegv handler */ while (info->type != PLUGIN_NONE) { if (_plugin_info_equal(info, target)) { config_values_t *config = this->config; #ifdef FAST_SCAN_PLUGINS new_entry_data_t d; d.v = config; d.node = node; #endif /* the callback is called for each entry registered by this plugin */ lprintf("plugin init %s\n", node->info->id); if (info->init) { #ifdef FAST_SCAN_PLUGINS config->set_new_entry_callback (config, _new_entry_cb, &d); #else config->set_new_entry_callback (config, _new_entry_cb, node); #endif node->plugin_class = info->init(this, data); config->unset_new_entry_callback (config); } if (node->plugin_class) { inc_file_ref(node->file); return 1; } else { return 0; } } info++; } lprintf("plugin not found\n"); } else { xine_log (this, XINE_LOG_PLUGIN, _("load_plugins: Yikes! %s doesn't contain plugin info.\n"), filename); } } else { /* statically linked plugin */ lprintf("statically linked plugin\n"); if (node->info->init) { node->plugin_class = node->info->init(this, data); return 1; } } return 0; /* something failed if we came here... */ } static void _dispose_plugin_class(plugin_node_t *node) { if (node->plugin_class) { void *cls = node->plugin_class; _x_assert(node->info); /* dispose of plugin class */ switch (node->info->type & PLUGIN_TYPE_MASK) { case PLUGIN_INPUT: if (((input_class_t *)cls)->dispose) ((input_class_t *)cls)->dispose ((input_class_t *)cls); break; case PLUGIN_DEMUX: if (((demux_class_t *)cls)->dispose) ((demux_class_t *)cls)->dispose ((demux_class_t *)cls); break; case PLUGIN_SPU_DECODER: if (((spu_decoder_class_t *)cls)->dispose) ((spu_decoder_class_t *)cls)->dispose ((spu_decoder_class_t *)cls); break; case PLUGIN_AUDIO_DECODER: if (((audio_decoder_class_t *)cls)->dispose) ((audio_decoder_class_t *)cls)->dispose ((audio_decoder_class_t *)cls); break; case PLUGIN_VIDEO_DECODER: if (((video_decoder_class_t *)cls)->dispose) ((video_decoder_class_t *)cls)->dispose ((video_decoder_class_t *)cls); break; case PLUGIN_AUDIO_OUT: if (((audio_driver_class_t *)cls)->dispose) ((audio_driver_class_t *)cls)->dispose ((audio_driver_class_t *)cls); break; case PLUGIN_VIDEO_OUT: if (((video_driver_class_t *)cls)->dispose) ((video_driver_class_t *)cls)->dispose ((video_driver_class_t *)cls); break; case PLUGIN_POST: if (((post_class_t *)cls)->dispose) ((post_class_t *)cls)->dispose ((post_class_t *)cls); break; case PLUGIN_XINE_MODULE: if (((xine_module_class_t *)cls)->dispose) ((xine_module_class_t *)cls)->dispose (cls); break; } node->plugin_class = NULL; if (node->file) dec_file_ref(node->file); } } /* * load input+demuxer plugins * load plugins that asked to be initialized */ static void _load_required_plugins(xine_t *this, xine_sarray_t *list) { int list_id = 0; int list_size; list_size = xine_sarray_size(list); while (list_id < list_size) { fat_node_t *node = xine_sarray_get (list, list_id); uint32_t flags = IS_FAT_NODE (node) ? node->flags : 0; /* * preload plugins if not cached */ do { if (!((node->node.info->type & PLUGIN_MUST_PRELOAD) | (flags & FAT_NODE_FLAG_PROBE_CLASS))) /* no preload needed */ break; if (node->node.plugin_class) /* is already loaded */ break; if (node->node.file && !node->node.file->lib_handle) /* lib unavailable */ break; lprintf ("preload plugin %s from %s\n", node->node.info->id, node->node.file ? node->node.file->filename : "libxine/builtins"); if (!_load_plugin_class (this, &node->node, NULL)) { /* in case of failure remove from list */ xine_sarray_remove(list, list_id); list_size = xine_sarray_size(list); list_id--; break; } if (node->node.info->type & PLUGIN_MUST_PRELOAD) break; _dispose_plugin_class (&node->node); } while (0); list_id++; } } static void load_required_plugins(xine_t *this) { int i; for (i = 0; i < PLUGIN_TYPE_MAX; i++) { _load_required_plugins (this, this->plugin_catalog->plugin_lists[i]); } } static unsigned int _cfg_entry_hash (void *a) { char **d = (char **)a; return ((uintptr_t)(*d) >> 4) & 127; } static int _cfg_entry_cmp (void *a, void *b) { char **d = (char **)a, **e = (char **)b; return *d < *e ? -1 : *d > *e ? 1 : 0; } /* * save plugin list information to file (cached catalog) */ typedef struct { xine_sarray_t *list; cfg_entry_t *entries[MAX_DUPL_CFG_ENTRIES]; uint32_t have; } _load_plugins_dupl_cfg_t; static void save_plugin_list (xine_t *this, FILE *fp, xine_sarray_t *list, _load_plugins_dupl_cfg_t *cfg) { int list_id = 0; int list_size; #define SAVE_PLUGIN_BUF_SIZE 4096 char b[SAVE_PLUGIN_BUF_SIZE]; char *e = b + SAVE_PLUGIN_BUF_SIZE - 78 - 2 * XINE_MAX_INT64_STR - 5 * XINE_MAX_INT32_STR; const plugin_file_t *last_file = (const plugin_file_t *)1; uint32_t last_type = ~0u, last_api = ~0u, last_vers = ~0u; list_size = xine_sarray_size (list); while (list_id < list_size) { int pri; char *q = b; const plugin_node_t *node = xine_sarray_get (list, list_id); const plugin_file_t *file = node->file; if (file != last_file) { last_file = file; last_type = last_api = last_vers = ~0u; if (file) { *q++ = '['; q += strlcpy (q, file->filename, e - q); if (q >= e) q = e - 1; memcpy (q, "]\nsize=", 7); q += 7; xine_uint2str (&q, file->filesize); memcpy (q, "\nmtime=", 7); q += 7; xine_uint2str (&q, file->filemtime); *q++ = '\n'; } else { /* dump builtins for debugging */ memcpy (q, "[libxine/builtins]\n", 20); q += 19; } } if (node->info->type != last_type) { last_type = node->info->type; last_api = last_vers = ~0u; memcpy (q, "type=", 5); q += 5; xine_uint32_2str (&q, node->info->type); *q++ = '\n'; } if (node->info->API != last_api) { last_api = node->info->API; memcpy (q, "api=", 4); q += 4; xine_uint32_2str (&q, node->info->API); *q++ = '\n'; } if (node->info->version != last_vers) { last_vers = node->info->version; memcpy (q, "version=", 8); q += 8; xine_uint32_2str (&q, node->info->version); *q++ = '\n'; } memcpy (q, "id=", 3); q += 3; q += strlcpy (q, node->info->id, e - q); if (q >= e) q = e - 1; *q++ = '\n'; switch (node->info->type & PLUGIN_TYPE_MASK){ case PLUGIN_VIDEO_OUT: { const vo_info_t *vo_info = node->info->special_info; memcpy (q, "visual_type=", 12); q += 12; xine_int32_2str (&q, vo_info->visual_type); memcpy (q, "\nvo_priority=", 13); q += 13; pri = vo_info->priority; goto write_pri; } case PLUGIN_AUDIO_OUT: { const ao_info_t *ao_info = node->info->special_info; memcpy (q, "ao_priority=", 12); q += 12; pri = ao_info->priority; goto write_pri; } case PLUGIN_AUDIO_DECODER: case PLUGIN_VIDEO_DECODER: case PLUGIN_SPU_DECODER: { const decoder_info_t *decoder_info = node->info->special_info; const uint32_t *t; memcpy (q, "supported_types=", 16); q += 16; t = decoder_info->supported_types; while (*t) { xine_uint32_2str (&q, *t++); if (q >= e) { fwrite (b, 1, q - b, fp); q = b; } *q++ = ' '; } q[-1] = '\n'; memcpy (q, "decoder_priority=", 17); q += 17; pri = decoder_info->priority; goto write_pri; } case PLUGIN_DEMUX: { const demuxer_info_t *demuxer_info = node->info->special_info; memcpy (q, "demuxer_priority=", 17); q += 17; pri = demuxer_info->priority; goto write_pri; } case PLUGIN_INPUT: { const input_info_t *input_info = node->info->special_info; memcpy (q, "input_priority=", 15); q += 15; pri = input_info->priority; goto write_pri; } case PLUGIN_POST: { const post_info_t *post_info = node->info->special_info; memcpy (q, "post_type=", 10); q += 10; xine_uint32_2str (&q, post_info->type); *q++ = '\n'; break; } case PLUGIN_XINE_MODULE: { const xine_module_info_t *module_info = node->info->special_info; size_t type_len = xine_find_byte (module_info->type, 0); memcpy (q, "module_type=", 12); q += 12; memcpy (q, module_info->type, type_len); q += type_len; memcpy (q, "\nmodule_sub_type=", 17); q += 17; xine_int32_2str (&q, module_info->sub_type); memcpy (q, "\nmodule_priority=", 17); q += 17; pri = module_info->priority; goto write_pri; } write_pri: xine_int32_2str (&q, pri); *q++ = '\n'; } fwrite (b, 1, q - b, fp); /* config entries */ if (node->config_entry_list) { xine_list_iterator_t ite = NULL; #ifdef FAST_SCAN_PLUGINS cfg_entry_t *entry; #else const char *entry; #endif while ((entry = xine_list_next_value (node->config_entry_list, &ite))) { char *key_value; #ifdef FAST_SCAN_PLUGINS if (cfg->have < MAX_DUPL_CFG_ENTRIES) { int cfg_index; cfg->entries[cfg->have] = entry; cfg_index = xine_sarray_add (cfg->list, cfg->entries + cfg->have); if (cfg_index < 0) { char b2[80], *q = b2; memcpy (q, "config_key=[", 12); q += 12; xine_uint32_2str (&q, (cfg_entry_t **)xine_sarray_get (cfg->list, ~cfg_index) - cfg->entries); memcpy (q, "]\n", 2); q += 2; fwrite (b2, 1, q - b2, fp); continue; } cfg->have++; } pthread_mutex_lock (&this->config->config_lock); this->config->cur = entry; key_value = this->config->get_serialized_entry (this->config, NULL); pthread_mutex_unlock (&this->config->config_lock); #else /* now serialize the config key */ key_value = this->config->get_serialized_entry (this->config, entry); #endif if (key_value) { size_t slen = xine_find_byte (key_value, 0); #ifdef FAST_SCAN_PLUGINS lprintf (" config key: %s, serialization: %zu bytes\n", entry->key, slen); #else lprintf (" config key: %s, serialization: %zu bytes\n", entry, slen); #endif fwrite ("config_key=", 1, 11, fp); key_value[slen] = '\n'; fwrite (key_value, 1, slen + 1, fp); free (key_value); } } } fwrite ("\n", 1, 1, fp); list_id++; } } /* * load plugin list information from file (cached catalog) */ typedef enum { _K_NONE = 0, _K_cache_catalog_version, _K_flush, _K_filename, _K_size, _K_mtime, _K_type, _K_api, _K_id, _K_version, _K_visual_type, _K_supported_types, _K_vo_priority, _K_ao_priority, _K_decoder_priority, _K_demuxer_priority, _K_input_priority, _K_post_type, _K_config_key, _K_module_priority, _K_module_sub_type, _K_module_type, _K_LAST } _k_t; static _k_t _key_2_index (const char *key, size_t klen) { switch (klen) { int d; case 0: return _K_flush; case 2: if (!memcmp (key, "id", 2)) return _K_id; break; case 3: if (!memcmp (key, "api", 3)) return _K_api; break; case 4: if (!memcmp (key, "size", 4)) return _K_size; if (!memcmp (key, "type", 4)) return _K_type; break; case 5: if (!memcmp (key, "mtime", 5)) return _K_mtime; break; case 7: if (!memcmp (key, "version", 7)) return _K_version; break; case 9: if (!memcmp (key, "post_type", 9)) return _K_post_type; break; case 10: if (!memcmp (key, "config_key", 10)) return _K_config_key; break; case 11: d = memcmp (key, "module_type", 11); if (d == 0) { return _K_module_type; } else if (d < 0) { if (!memcmp (key, "ao_priority", 11)) return _K_ao_priority; } else { if (!memcmp (key, "visual_type", 11)) return _K_visual_type; if (!memcmp (key, "vo_priority", 11)) return _K_vo_priority; } break; case 14: if (!memcmp (key, "input_priority", 14)) return _K_input_priority; break; case 15: d = memcmp (key, "module_sub_type", 15); if (d == 0) { return _K_module_sub_type; } else if (d < 0) { if (!memcmp (key, "module_priority", 15)) return _K_module_priority; } else { if (!memcmp (key, "supported_types", 15)) return _K_supported_types; } break; case 16: if (!memcmp (key, "decoder_priority", 16)) return _K_decoder_priority; if (!memcmp (key, "demuxer_priority", 16)) return _K_demuxer_priority; break; case 21: if (!memcmp (key, "cache_catalog_version", 21)) return _K_cache_catalog_version; break; default: ; } return _K_NONE; } static void load_plugin_list (xine_t *this, const char *filename, xine_sarray_t *plugins) { #ifdef FAST_SCAN_PLUGINS struct { cfg_entry_t *entries[MAX_DUPL_CFG_ENTRIES]; uint32_t have; } cfg; #endif fat_node_t *first_in_file, node; /** << node.file.filename is not a xine_fast_string_t, never passed there. */ size_t stlen, fnlen, idlen; /* We dont have that many types yet ;-) */ uint32_t supported_types[256]; char *cfgentries[256], dummy_line[1] = ""; int numcfgs; xine_fast_text_t *xft; int version_ok = 0, again = 1; int skip = 0; /* TJ. I got far less than 100k, so > 2M is probably insane. */ xft = xine_fast_text_load (filename, 2 << 20); if (!xft) return; _fat_node_init (&node); fnlen = 0; stlen = 0; idlen = 0; fnlen = 0; numcfgs = 0; first_in_file = NULL; #ifdef FAST_SCAN_PLUGINS cfg.have = 0; #endif while (again) { _k_t index; size_t lsize; char *line = xine_fast_text_line (xft, &lsize); if (line) { /* skip comments */ if (line[0] == '#') continue; } else { /* make sure to flush the last one */ again = 0; line = dummy_line; lsize = 0; } if ((line[0] == '[') && version_ok) { /* file name */ if (line[--lsize] != ']') continue; line[lsize] = 0; line++; lsize--; index = _K_filename; } else { /* key=value */ size_t l; line[lsize] = '='; l = xine_find_byte (line, '='); line[lsize] = 0; index = _key_2_index (line, l); line += l; lsize -= l; if (*line) *line++ = 0, lsize--; } if (skip && (index != _K_filename)) continue; if (!version_ok) { if (index == _K_cache_catalog_version) { const char *val = line; uint32_t vers = xine_str2uint32 (&val); /* we are slightly backward compatible */ if ((vers == CACHE_CATALOG_VERSION) || (vers == CACHE_CATALOG_VERSION - 1)) { version_ok = 1; } else { xine_fast_text_unload (&xft); return; } } continue; } { const char *val = line; union { uint64_t llu; unsigned int u; int i; } v = {0}; unsigned int mask = 1u << index; const uint32_t set_int32 = (1 << _K_type) | (1 << _K_api) | (1 << _K_visual_type) | (1 << _K_vo_priority) | (1 << _K_ao_priority) | (1 << _K_decoder_priority) | (1 << _K_demuxer_priority) | (1 << _K_input_priority) | (1 << _K_module_priority), set_uint32 = (1 << _K_version) | (1 << _K_post_type) | (1 << _K_module_sub_type), set_uint64 = (1 << _K_size) | (1 << _K_mtime); if (set_int32 & mask) v.i = xine_str2int32 (&val); else if (set_uint32 & mask) v.u = xine_str2uint32 (&val); else if (set_uint64 & mask) v.llu = xine_str2uint64 (&val); switch (index) { case _K_flush: if (idlen) { /* flush this entry */ fat_node_t *n; char *q; /* get mem for new node */ n = malloc (sizeof (node) + stlen + idlen + 1 + fnlen + 1 + 32); if (!n) break; /* fill in */ *n = node; n->node.info = &n->info[0]; q = (char *)n + sizeof (*n); if (stlen) { memcpy (&n->supported_types[0], &supported_types[0], stlen); q += stlen; n->ainfo.decoder_info.supported_types = &n->supported_types[0]; } if (node.info[0].id) { xine_small_memcpy (q, node.info[0].id, idlen + 1); n->info[0].id = q; q += idlen + 1; } n->file.filename = xine_fast_string_init (q, fnlen + 32); xine_fast_string_set (n->file.filename, node.file.filename, fnlen); /* q += fn_need; */ n->node.file = &n->file; n->info[0].special_info = &n->ainfo; /* register */ if (first_in_file) { first_in_file->lastplugin->nextplugin = n; first_in_file->lastplugin = n; } else { int i = xine_sarray_add (plugins, n); if (i >= 0) { /* new file */ n->lastplugin = n; first_in_file = n; } else { first_in_file = xine_sarray_get (plugins, ~i); first_in_file->lastplugin->nextplugin = n; first_in_file->lastplugin = n; } } if (numcfgs) { char **cfgentry; #ifdef FAST_SCAN_PLUGINS new_entry_data_t ned; ned.v = this->config; ned.node = &n->node; this->config->set_new_entry_callback (this->config, _new_entry_cb, &ned); #endif cfgentries[numcfgs] = NULL; for (cfgentry = cfgentries; *cfgentry; cfgentry++) { char *cfg_key; #ifdef FAST_SCAN_PLUGINS if (cfgentry[0][0] == '[') { const char *p = *cfgentry + 1; uint32_t cfg_index = xine_str2uint32 (&p); if (cfg_index < cfg.have) { if (!n->node.config_entry_list) n->node.config_entry_list = xine_list_new (); if (n->node.config_entry_list && cfg.entries[cfg_index] && !xine_list_find (n->node.config_entry_list, cfg.entries[cfg_index])) xine_list_push_back (n->node.config_entry_list, cfg.entries[cfg_index]); } continue; } ned.cfg_entry = NULL; cfg_key = this->config->register_serialized_entry (this->config, *cfgentry); if (cfg.have < MAX_DUPL_CFG_ENTRIES) cfg.entries[cfg.have++] = ned.cfg_entry; #else cfg_key = this->config->register_serialized_entry (this->config, *cfgentry); #endif if (cfg_key) { /* this node is a cached node */ #ifdef FAST_SCAN_PLUGINS free (cfg_key); #else _attach_entry_to_node (&n->node, cfg_key); #endif } else { lprintf ("failed to deserialize config entry key\n"); } } #ifdef FAST_SCAN_PLUGINS this->config->unset_new_entry_callback (this->config); #endif } /* reset */ node.info[0].id = NULL; idlen = 0; supported_types[0] = 0; stlen = 0; memset (&node.ainfo, 0, sizeof (node.ainfo)); numcfgs = 0; } break; case _K_filename: node.file.filename = line; fnlen = lsize; skip = ((lsize == 16) && !memcmp (line, "libxine/builtins", 16)) ? 1 : 0; first_in_file = NULL; break; case _K_size: node.file.filesize = v.llu; break; case _K_mtime: node.file.filemtime = v.llu; break; case _K_type: node.info[0].type = v.i; break; case _K_api: node.info[0].API = v.i; break; case _K_id: node.info[0].id = line; idlen = lsize; break; case _K_version: node.info[0].version = v.u; break; case _K_visual_type: node.ainfo.vo_info.visual_type = v.i; break; case _K_supported_types: { int i; for (i = 0; i < 255; i++) { if ((supported_types[i] = xine_str2uint32 (&val)) == 0) break; } supported_types[i++] = 0; stlen = i * sizeof (*supported_types); break; } case _K_vo_priority: node.ainfo.vo_info.priority = v.i; break; case _K_ao_priority: node.ainfo.ao_info.priority = v.i; break; case _K_decoder_priority: node.ainfo.decoder_info.priority = v.i; break; case _K_demuxer_priority: node.ainfo.demuxer_info.priority = v.i; break; case _K_input_priority: node.ainfo.input_info.priority = v.i; break; case _K_post_type: node.ainfo.post_info.type = v.u; break; case _K_config_key: if (numcfgs < 255) cfgentries[numcfgs++] = line; break; case _K_module_priority: node.ainfo.module_info.priority = v.i; break; case _K_module_sub_type: node.ainfo.module_info.sub_type = v.u; break; case _K_module_type: strlcpy (node.ainfo.module_info.type, line, sizeof (node.ainfo.module_info.type)); default: ; } } } xine_fast_text_unload (&xft); } /** * @brief Returns the complete filename for the plugins' cache file * @param this xine instance pointer, used for logging and libxdg-basedir. * @param buf write filename here. * @param bsize write at most this many bytes. * @param createdir If not zero, create the directory structure in which * the file has to reside. * @return the strlen () of filename, or 0 (eg if a directory could not be created). * @internal * * @see XDG Base Directory specification: * http://standards.freedesktop.org/basedir-spec/latest/index.html */ static size_t catalog_filename (xine_t *this, char *buf, size_t bsize, int createdir) { const char *const xdg_cache_home = xdgCacheHome(&this->basedir_handle); size_t l1, l2; if (!xdg_cache_home) return 0; l1 = xine_find_byte (xdg_cache_home, 0); l2 = sizeof (PACKAGE) - 1; if (bsize < l1 + 1 + l2 + 1 + 14 + 1) return 0; memcpy (buf, xdg_cache_home, l1 + 1); memcpy (buf + l1, "/" PACKAGE "/plugins.cache", 1 + l2 + 14 + 1); /* If we're going to create the directory structure, we concatenate * piece by piece the path, so that we can try to create all the * directories. * If we don't need to create anything, we just concatenate the * whole path at once. */ if ( createdir ) { int result = 0, e; buf[l1] = 0; result = mkdir (buf, 0700); if ((result != 0) && ((e = errno) != EEXIST)) { xprintf (this, XINE_VERBOSITY_LOG, _("Unable to create %s directory: %s\n"), buf, strerror (e)); return 0; } buf[l1] = '/'; buf[l1 + 1 + l2] = 0; result = mkdir (buf, 0700); if ((result != 0) && ((e = errno) != EEXIST)) { xprintf (this, XINE_VERBOSITY_LOG, _("Unable to create %s directory: %s\n"), buf, strerror (e)); return 0; } buf[l1 + 1 + l2] = '/'; } return l1 + 1 + l2 + 1 + 14; } /* * save catalog to cache file */ static void save_catalog (xine_t *this) { FILE *fp; char oldname[1024 - 4], newname[1024]; size_t nlen = catalog_filename (this, oldname, sizeof (oldname), 1); if (!nlen) return; memcpy (newname, oldname, nlen); memcpy (newname + nlen, ".new", 5); if ((fp = fopen (newname, "wb")) != NULL) { _load_plugins_dupl_cfg_t cfg; int i; cfg.list = xine_sarray_new (MAX_DUPL_CFG_ENTRIES, _cfg_entry_cmp); /* this is mainly a test :-) */ xine_sarray_set_hash (cfg.list, _cfg_entry_hash, 128); xine_sarray_set_mode (cfg.list, XINE_SARRAY_MODE_UNIQUE); cfg.have = 0; fwrite ("# this file is automatically created by xine, do not edit.\n\n" "cache_catalog_version=" CACHE_CATALOG_VERSION_STR "\n\n", 1, 85, fp); for (i = 0; i < PLUGIN_TYPE_MAX; i++) { save_plugin_list (this, fp, this->plugin_catalog->plugin_lists[i], &cfg); } save_plugin_list (this, fp, this->plugin_catalog->modules_list, &cfg); xine_sarray_delete (cfg.list); if (fclose(fp)) { const char *err = strerror (errno); xine_log (this, XINE_LOG_MSG, _("failed to save catalogue cache: %s\n"), err); goto do_unlink; } else if (rename (newname, oldname)) { const char *err = strerror (errno); xine_log (this, XINE_LOG_MSG, _("failed to replace catalogue cache: %s\n"), err); do_unlink: if (unlink (newname) && errno != ENOENT) { err = strerror (errno); xine_log (this, XINE_LOG_MSG, _("failed to remove new catalogue cache: %s\n"), err); } } } } /* * load cached catalog from file */ static void load_cached_catalog (xine_t *this) { char filename[1024]; if (catalog_filename (this, filename, sizeof (filename), 0) > 0) load_plugin_list (this, filename, this->plugin_catalog->cache_list); } /* * initialize catalog, load all plugins into new catalog */ int _x_scan_plugins (xine_t *this_gen) { #define XSP_BUFSIZE 4096 xine_private_t *this = (xine_private_t *)this_gen; char _buf[XSP_BUFSIZE + 32]; char *buf = xine_fast_string_init (_buf, sizeof (_buf)); char *bufend = buf + XSP_BUFSIZE - 16; const char *pluginpath = NULL; const char *homedir; size_t homelen; lprintf("_x_scan_plugins()\n"); _x_assert(this); _x_assert (this->x.config); _x_assert (!this->x.plugin_catalog); homedir = xine_get_homedir (); if (!homedir) return -1; homelen = xine_find_byte (homedir, 0); if (homelen > XSP_BUFSIZE - 16) homelen = XSP_BUFSIZE - 16; this->x.plugin_catalog = _new_catalog(); if (!this->x.plugin_catalog) return -1; this->strings.decoder_pri_help = xine_ref_string_ref ( _("The priority provides a ranking in case some media can be handled by more than one decoder.\n" "A priority of 0 enables the decoder's default priority."), -1); XINE_PROFILE (load_cached_catalog (&this->x)); #ifdef XINE_MAKE_BUILTINS lprintf ("collect_plugins in libxine\n"); _register_plugins_internal (&this->x, NULL, NULL , xine_builtin_plugin_info, FAT_NODE_FLAG_PROBE_CLASS); #endif if ((pluginpath = getenv("XINE_PLUGIN_PATH")) != NULL && *pluginpath) { const char *start = pluginpath, *stop; char *q; size_t len; while (1) { q = buf; if ((start[0] == '~') && (start[1] == '/')) { start += 1; xine_small_memcpy (q, homedir, homelen); q += homelen; } stop = strchr (start, XINE_PATH_SEPARATOR_CHAR); if (!stop) break; len = stop - start; if (len > (size_t)(bufend - q)) len = bufend - q; xine_small_memcpy (q, start, len); q += len; q[0] = 0; start = stop + 1; collect_plugins (&this->x, buf, q, bufend); } len = xine_find_byte (start, 0); if (len > (size_t)(bufend - q)) len = bufend - q; xine_small_memcpy (q, start, len); q += len; q[0] = 0; collect_plugins (&this->x, buf, q, bufend); } else { const char *p; size_t len; int i; xine_small_memcpy (buf, homedir, homelen); memcpy (buf + homelen, "/.xine/plugins", 15); collect_plugins (&this->x, buf, buf + homelen + 15, bufend); p = XINE_PLUGINROOT; len = sizeof (XINE_PLUGINROOT) - 1; xine_small_memcpy (buf, p, len); buf[len++] = '.'; for (i = XINE_LT_AGE; i >= 0; i--) { char *q = buf + len; xine_uint32_2str (&q, i); collect_plugins (&this->x, buf, q, bufend); } } load_required_plugins (&this->x); if ((this->flags & XINE_FLAG_NO_WRITE_CACHE) == 0) XINE_PROFILE (save_catalog (&this->x)); map_decoders (&this->x); return 0; } /* * generic module loading */ xine_module_t *_x_find_module(xine_t *xine, const char *type, const char *id, unsigned sub_type, const void *params) { plugin_catalog_t *catalog = xine->plugin_catalog; plugin_node_t *node; xine_module_t *plugin = NULL; int list_id, list_size; const xine_module_info_t *info; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size(catalog->modules_list); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (catalog->modules_list, list_id); if (id && strcmp (node->info->id, id)) continue; info = node->info->special_info; if (sub_type != info->sub_type) continue; if (type && strcmp (info->type, type)) continue; if (node->plugin_class || _load_plugin_class(xine, node, params)) { if ((plugin = ((xine_module_class_t *)node->plugin_class)->get_instance(node->plugin_class, params))) { inc_node_ref(node); plugin->node = node; break; } } } pthread_mutex_unlock (&catalog->lock); return plugin; } void _x_free_module(xine_t *xine, xine_module_t **pmodule) { xine_module_t *module = *pmodule; plugin_catalog_t *catalog = xine->plugin_catalog; plugin_node_t *node = module->node; *pmodule = NULL; module->dispose(module); if (node) { pthread_mutex_lock(&catalog->lock); dec_node_ref(node); pthread_mutex_unlock(&catalog->lock); } } /* * input / demuxer plugin loading */ input_plugin_t *_x_find_input_plugin (xine_stream_t *stream, const char *mrl) { xine_stream_private_t *s; xine_t *xine; plugin_catalog_t *catalog; input_plugin_t *plugin; input_class_t *skip_class; uint32_t n; if (!stream || !mrl) return NULL; s = (xine_stream_private_t *)stream; xine = s->s.xine; catalog = xine->plugin_catalog; plugin = NULL; /* prevent recursion during input_plugin->open (). */ skip_class = s->s.input_plugin ? s->s.input_plugin->input_class : NULL; pthread_mutex_lock (&catalog->lock); /* prevent recursion during input_class->get_instance (). */ n = !s->query_input_plugins[0] ? 0 : !s->query_input_plugins[1] ? 1 : 2; if (n != 2) { int list_id, list_size; list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_INPUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { plugin_node_t *node = xine_sarray_get (catalog->plugin_lists[PLUGIN_INPUT - 1], list_id); input_class_t *class = (input_class_t *)node->plugin_class; if (!class) { _load_plugin_class (xine, node, NULL); class = (input_class_t *)node->plugin_class; } if (class) { s->query_input_plugins[n] = class; if ((class != skip_class) && (s->query_input_plugins[0] != s->query_input_plugins[1])) { plugin = class->get_instance (class, stream, mrl); if (plugin) { inc_node_ref (node); plugin->node = node; break; } } } } s->query_input_plugins[n] = NULL; } pthread_mutex_unlock (&catalog->lock); return plugin; } void _x_free_input_plugin (xine_stream_t *stream, input_plugin_t *input) { plugin_catalog_t *catalog; plugin_node_t *node; if (!input) return; node = input->node; input->dispose (input); if (!stream) return; catalog = stream->xine->plugin_catalog; if (node) { pthread_mutex_lock(&catalog->lock); dec_node_ref(node); pthread_mutex_unlock(&catalog->lock); } } demux_plugin_t *_x_find_demux_plugin (xine_stream_t *stream, input_plugin_t *input) { uint8_t mbuf[256]; int methods[3], i; plugin_catalog_t *catalog; demux_plugin_t *plugin; const char *mime_type = ""; if (!stream || !input) return NULL; switch (stream->xine->demux_strategy) { default: xprintf (stream->xine, XINE_VERBOSITY_LOG, _("load_plugins: unknown content detection strategy %d\n"), stream->xine->demux_strategy); /* fall through */ case XINE_DEMUX_DEFAULT_STRATEGY: methods[0] = METHOD_BY_CONTENT; methods[1] = METHOD_BY_MRL; break; case XINE_DEMUX_REVERT_STRATEGY: methods[0] = METHOD_BY_MRL; methods[1] = METHOD_BY_CONTENT; break; case XINE_DEMUX_CONTENT_STRATEGY: methods[0] = METHOD_BY_CONTENT; methods[1] = -1; mime_type = NULL; break; case XINE_DEMUX_EXTENSION_STRATEGY: methods[0] = METHOD_BY_MRL; methods[1] = -1; break; } methods[2] = -1; if (mime_type && input->get_optional_data && (input->get_optional_data (input, NULL, INPUT_OPTIONAL_DATA_DEMUX_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED) && (input->get_optional_data (input, &mime_type, INPUT_OPTIONAL_DATA_MIME_TYPE) != INPUT_OPTIONAL_UNSUPPORTED) && strcasecmp (mime_type, "text/plain")) { ; } else { mime_type = NULL; } _mime_set (mbuf, sizeof (mbuf), mime_type); plugin = NULL; catalog = stream->xine->plugin_catalog; for (i = 0; (methods[i] >= 0) && !plugin; i++) { int list_id, list_size; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size(catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; list_id < list_size; list_id++) { plugin_node_t *node; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: probing demux '%s'\n", node->info->id); if (node->plugin_class || _load_plugin_class(stream->xine, node, NULL)) { demux_class_t *class = (demux_class_t *)node->plugin_class; /* If detecting by MRL, try the MIME type first (but not text/plain)... */ stream->content_detection_method = METHOD_EXPLICIT; if ((methods[i] == METHOD_BY_MRL) && (_mime_find (mbuf, class->mimetypes) >= 0) && (plugin = class->open_plugin (class, stream, input))) { inc_node_ref(node); plugin->node = node; break; } /* ... then try the extension */ stream->content_detection_method = methods[i]; if ((stream->content_detection_method == METHOD_BY_MRL) && !_x_demux_check_extension (input->get_mrl (input), class->extensions)) continue; if ((plugin = class->open_plugin (class, stream, input))) { inc_node_ref(node); plugin->node = node; break; } } } pthread_mutex_unlock (&catalog->lock); } if (input == stream->input_plugin) { xine_stream_private_t *s = (xine_stream_private_t *)stream; s->demux.input_caps = input->get_capabilities (input); } return plugin; } demux_plugin_t *_x_find_demux_plugin_by_name(xine_stream_t *stream, const char *name, input_plugin_t *input) { plugin_catalog_t *catalog = stream->xine->plugin_catalog; plugin_node_t *node; demux_plugin_t *plugin = NULL; int list_id, list_size; pthread_mutex_lock(&catalog->lock); stream->content_detection_method = METHOD_EXPLICIT; list_size = xine_sarray_size(catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get(catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (strcasecmp(node->info->id, name) == 0) { if (node->plugin_class || _load_plugin_class(stream->xine, node, NULL)) { #if 0 /* never triggered (method is set to EXPLICIT few lines earlier) */ if ( stream->content_detection_method == METHOD_BY_MRL && ! _x_demux_check_extension(input->get_mrl(input), ((demux_class_t *)node->plugin_class)->extensions) ) continue; #endif if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) { inc_node_ref(node); plugin->node = node; break; } } } } pthread_mutex_unlock(&catalog->lock); return plugin; } /* * this is a special test mode for content detection: all demuxers are probed * by content and extension except last_demux_name which is tested after * every other demuxer. * * this way we can make sure no demuxer will interfere on probing of a * known stream. */ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const char *last_demux_name, input_plugin_t *input) { int i; int methods[3]; xine_t *xine = stream->xine; plugin_catalog_t *catalog = xine->plugin_catalog; plugin_node_t *last_demux = NULL; demux_plugin_t *plugin = NULL; methods[0] = METHOD_BY_CONTENT; methods[1] = METHOD_BY_MRL; methods[2] = -1; i = 0; while (methods[i] != -1 && !plugin) { int list_id, list_size; stream->content_detection_method = methods[i]; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size(catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; list_id < list_size; list_id++) { plugin_node_t *node; node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); lprintf ("probing demux '%s'\n", node->info->id); if (strcasecmp(node->info->id, last_demux_name) == 0) { last_demux = node; } else { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugin: probing '%s' (method %d)...\n", node->info->id, stream->content_detection_method ); if (node->plugin_class || _load_plugin_class(xine, node, NULL)) { if ( stream->content_detection_method == METHOD_BY_MRL && ! _x_demux_check_extension(input->get_mrl(input), ((demux_class_t *)node->plugin_class)->extensions) ) continue; if ((plugin = ((demux_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream, input))) { xprintf (stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: using demuxer '%s' (instead of '%s')\n", node->info->id, last_demux_name); inc_node_ref(node); plugin->node = node; break; } } } } pthread_mutex_unlock (&catalog->lock); i++; } if( plugin ) return plugin; if( !last_demux ) return NULL; stream->content_detection_method = METHOD_BY_CONTENT; pthread_mutex_lock (&catalog->lock); if (last_demux->plugin_class || _load_plugin_class(xine, last_demux, NULL)) { if ((plugin = ((demux_class_t *)last_demux->plugin_class)->open_plugin(last_demux->plugin_class, stream, input))) { xprintf (stream->xine, XINE_VERBOSITY_LOG, _("load_plugins: using demuxer '%s'\n"), last_demux_name); inc_node_ref(last_demux); plugin->node = last_demux; } } pthread_mutex_unlock (&catalog->lock); return plugin; } void _x_free_demux_plugin (xine_stream_t *stream, demux_plugin_t **pdemux) { demux_plugin_t *demux = *pdemux; plugin_catalog_t *catalog = stream->xine->plugin_catalog; plugin_node_t *node = demux->node; *pdemux = NULL; demux->dispose(demux); if (node) { pthread_mutex_lock(&catalog->lock); dec_node_ref(node); pthread_mutex_unlock(&catalog->lock); } } const char *const *xine_get_autoplay_input_plugin_ids(xine_t *this) { const char **last, **end, *test; int list_id, list_size; plugin_catalog_t *catalog = this->plugin_catalog; pthread_mutex_lock (&catalog->lock); end = &catalog->ids[0] + sizeof (catalog->ids) / sizeof (catalog->ids[0]) - 1; last = &catalog->ids[0]; *last = NULL; test = NULL; list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_INPUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { plugin_node_t *node = xine_sarray_get (catalog->plugin_lists[PLUGIN_INPUT - 1], list_id); input_class_t *ic = node->plugin_class; if (!ic) { _load_plugin_class (this, node, NULL); ic = node->plugin_class; } if (ic && ic->get_autoplay_list) { if (!strcasecmp (node->info->id, "TEST")) { /* dont let TEST push user media devices out of xine-ui 1 click list. */ test = node->info->id; } else { const char **here = &catalog->ids[0], **p; while (*here && strcasecmp (*here, node->info->id) < 0) here++; last++; for (p = last; p > here; p--) p[0] = p[-1]; *here = node->info->id; } if (last >= end) break; } } if (last < end) { *last++ = test; *last = NULL; } pthread_mutex_unlock (&catalog->lock); return catalog->ids; } const char *const *xine_get_browsable_input_plugin_ids(xine_t *this) { const char **last, **end, *test; int list_id, list_size; plugin_catalog_t *catalog = this->plugin_catalog; pthread_mutex_lock (&catalog->lock); end = &catalog->ids[0] + sizeof (catalog->ids) / sizeof (catalog->ids[0]) - 1; last = &catalog->ids[0]; *last = NULL; test = NULL; list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_INPUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { plugin_node_t *node = xine_sarray_get (catalog->plugin_lists[PLUGIN_INPUT - 1], list_id); input_class_t *ic = node->plugin_class; if (!ic) { _load_plugin_class (this, node, NULL); ic = node->plugin_class; } if (ic && ic->get_dir) { if (!strcasecmp (node->info->id, "TEST")) { /* dont let TEST push user media devices out of xine-ui 1 click list. */ test = node->info->id; } else { const char **here = &catalog->ids[0], **p; while (*here && strcasecmp (*here, node->info->id) < 0) here++; last++; for (p = last; p > here; p--) p[0] = p[-1]; *here = node->info->id; } if (last >= end) break; } } if (last < end) { *last++ = test; *last = NULL; } pthread_mutex_unlock (&catalog->lock); return catalog->ids; } /* * video out plugins section */ static vo_driver_t *_load_video_driver (xine_t *this, plugin_node_t *node, const void *data) { vo_driver_t *driver; if (!node->plugin_class && !_load_plugin_class (this, node, data)) return NULL; driver = ((video_driver_class_t *)node->plugin_class)->open_plugin(node->plugin_class, data); if (driver) { inc_node_ref(node); driver->node = node; } return driver; } vo_driver_t *_x_load_video_output_plugin(xine_t *this, const char *id, int visual_type, const void *visual) { plugin_node_t *node; vo_driver_t *driver = NULL; const vo_info_t *vo_info; plugin_catalog_t *catalog = this->plugin_catalog; int list_id, list_size; if (id && !strcasecmp(id, "auto")) id = NULL; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1], list_id); vo_info = (const vo_info_t *)node->info->special_info; if (vo_info->visual_type == visual_type) { if (id) { if (!strcasecmp (node->info->id, id)) { driver = _load_video_driver (this, node, visual); break; } } else { driver = _load_video_driver (this, node, visual); if (driver) { break; } } } } pthread_mutex_unlock (&catalog->lock); return driver; } xine_video_port_t *xine_open_video_driver (xine_t *this, const char *id, int visual_type, const void *visual) { vo_driver_t *driver; xine_video_port_t *port; driver = _x_load_video_output_plugin(this, id, visual_type, visual); if (!driver) { lprintf ("failed to load video output plugin <%s>\n", id); return NULL; } port = _x_vo_new_port(this, driver, 0); return port; } xine_video_port_t *xine_new_framegrab_video_port (xine_t *this) { plugin_node_t *node; vo_driver_t *driver; xine_video_port_t *port; plugin_catalog_t *catalog = this->plugin_catalog; const char *id; int list_id, list_size; driver = NULL; id = "none"; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (catalog->plugin_lists[PLUGIN_VIDEO_OUT - 1], list_id); if (!strcasecmp (node->info->id, id)) { driver = _load_video_driver (this, node, NULL); break; } } pthread_mutex_unlock (&catalog->lock); if (!driver) { lprintf ("failed to load video output plugin <%s>\n", id); return NULL; } port = _x_vo_new_port(this, driver, 1); return port; } /* * audio output plugins section */ const char *const *xine_list_audio_output_plugins (xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_AUDIO_OUT, 0); } const char *const *xine_list_video_output_plugins (xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_VIDEO_OUT, ~(uint64_t)0); } const char * const *xine_list_video_output_plugins_typed (xine_t *xine, uint64_t typemask) { return _build_list_typed_plugins (xine, PLUGIN_VIDEO_OUT, typemask); } static ao_driver_t *_load_audio_driver (xine_t *this, plugin_node_t *node, const void *data) { ao_driver_t *driver; if (!node->plugin_class && !_load_plugin_class (this, node, data)) return NULL; driver = ((audio_driver_class_t *)node->plugin_class)->open_plugin(node->plugin_class, data); if (driver) { inc_node_ref(node); driver->node = node; } return driver; } ao_driver_t *_x_load_audio_output_plugin (xine_t *this, const char *id) { plugin_node_t *node; ao_driver_t *driver = NULL; plugin_catalog_t *catalog = this->plugin_catalog; int list_id, list_size; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1], list_id); if (!strcasecmp(node->info->id, id)) { driver = _load_audio_driver (this, node, NULL); break; } } pthread_mutex_unlock (&catalog->lock); if (!driver) { xprintf (this, XINE_VERBOSITY_LOG, _("load_plugins: failed to load audio output plugin <%s>\n"), id); } return driver; } xine_audio_port_t *xine_open_audio_driver (xine_t *this, const char *id, const void *data) { plugin_node_t *node; ao_driver_t *driver = NULL; xine_audio_port_t *port; const ao_info_t *ao_info; plugin_catalog_t *catalog = this->plugin_catalog; int list_id, list_size; if (id && !strcasecmp(id, "auto") ) id = NULL; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (this->plugin_catalog->plugin_lists[PLUGIN_AUDIO_OUT - 1], list_id); ao_info = (const ao_info_t *)node->info->special_info; if (id) { if (!strcasecmp(node->info->id, id)) { driver = _load_audio_driver (this, node, data); break; } } else if( ao_info->priority >= 0 ) { driver = _load_audio_driver (this, node, data); if (driver) { break; } } } pthread_mutex_unlock (&catalog->lock); if (!driver) { if (id) xprintf (this, XINE_VERBOSITY_LOG, _("load_plugins: failed to load audio output plugin <%s>\n"), id); else xprintf (this, XINE_VERBOSITY_LOG, _("load_plugins: audio output auto-probing didn't find any usable audio driver.\n")); return NULL; } port = _x_ao_new_port(this, driver, 0); return port; } xine_audio_port_t *xine_new_framegrab_audio_port (xine_t *this) { xine_audio_port_t *port; port = _x_ao_new_port (this, NULL, 1); return port; } void _x_free_audio_driver (xine_t *xine, ao_driver_t **pdriver) { ao_driver_t *driver = *pdriver; plugin_catalog_t *catalog = xine->plugin_catalog; plugin_node_t *node = driver->node; *pdriver = NULL; driver->exit(driver); if (node) { pthread_mutex_lock(&catalog->lock); dec_node_ref(node); pthread_mutex_unlock(&catalog->lock); } } void _x_free_video_driver (xine_t *xine, vo_driver_t **pdriver) { vo_driver_t *driver = *pdriver; plugin_catalog_t *catalog = xine->plugin_catalog; plugin_node_t *node = driver->node; *pdriver = NULL; driver->dispose (driver); if (node) { pthread_mutex_lock(&catalog->lock); dec_node_ref(node); pthread_mutex_unlock(&catalog->lock); } } void xine_close_audio_driver (xine_t *this, xine_audio_port_t *ao_port) { (void)this; if( ao_port ) ao_port->exit(ao_port); } void xine_close_video_driver (xine_t *this, xine_video_port_t *vo_port) { (void)this; if( vo_port ) vo_port->exit(vo_port); } /* * get autoplay mrl list from input plugin */ static input_class_t *_get_input_class (xine_t *this, const char *plugin_id) { plugin_catalog_t *catalog; plugin_node_t *node; int list_id, list_size; catalog = this->plugin_catalog; list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_INPUT - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (catalog->plugin_lists[PLUGIN_INPUT - 1], list_id); if (!strcasecmp (node->info->id, plugin_id)) { if (node->plugin_class || _load_plugin_class (this, node, NULL)) { return node->plugin_class; } } } return NULL; } const char * const *xine_get_autoplay_mrls (xine_t *this, const char *plugin_id, int *num_mrls) { plugin_catalog_t *catalog; input_class_t *ic; const char * const *mrls = NULL; catalog = this->plugin_catalog; pthread_mutex_lock (&catalog->lock); ic = _get_input_class(this, plugin_id); if (ic && ic->get_autoplay_list) mrls = ic->get_autoplay_list (ic, num_mrls); pthread_mutex_unlock (&catalog->lock); return mrls; } /* * input plugin mrl browser support */ xine_mrl_t **xine_get_browse_mrls (xine_t *this, const char *plugin_id, const char *start_mrl, int *num_mrls) { plugin_catalog_t *catalog; input_class_t *ic; xine_mrl_t **mrls = NULL; catalog = this->plugin_catalog; pthread_mutex_lock (&catalog->lock); ic = _get_input_class (this, plugin_id); if (ic && ic->get_dir) mrls = ic->get_dir (ic, start_mrl, num_mrls); pthread_mutex_unlock (&catalog->lock); return mrls; } video_decoder_t *_x_get_video_decoder (xine_stream_t *stream, uint8_t stream_type) { plugin_node_t *node; int i, j; plugin_catalog_t *catalog = stream->xine->plugin_catalog; video_decoder_t *vd = NULL; lprintf ("looking for video decoder for streamtype %02x\n", stream_type); _x_assert(stream_type < DECODER_MAX); pthread_mutex_lock (&catalog->lock); for (i = 0; i < PLUGINS_PER_TYPE; i++) { node = catalog->video_decoder_map[stream_type][i]; if (!node) { break; } if (!node->plugin_class && !_load_plugin_class (stream->xine, node, NULL)) { /* remove non working plugin from catalog */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to init its class.\n", node->info->id); for (j = i + 1; j < PLUGINS_PER_TYPE; j++) catalog->video_decoder_map[stream_type][j - 1] = catalog->video_decoder_map[stream_type][j]; catalog->video_decoder_map[stream_type][PLUGINS_PER_TYPE-1] = NULL; i--; continue; } vd = ((video_decoder_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream); if (vd == (video_decoder_t*)1) { /* HACK: plugin failed to instantiate because required resources are unavailable at that time, but may be available later, so don't remove this plugin from catalog. */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to instantiate, resources temporarily unavailable.\n", node->info->id); } else if (vd) { inc_node_ref(node); vd->node = node; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s will be used for video streamtype %02x.\n", node->info->id, stream_type); break; } else { /* remove non working plugin from catalog */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to instantiate itself.\n", node->info->id); for (j = i + 1; j < PLUGINS_PER_TYPE; j++) catalog->video_decoder_map[stream_type][j - 1] = catalog->video_decoder_map[stream_type][j]; catalog->video_decoder_map[stream_type][PLUGINS_PER_TYPE-1] = NULL; i--; } } pthread_mutex_unlock (&catalog->lock); return vd; } void _x_free_video_decoder (xine_stream_t *stream, video_decoder_t *vd) { plugin_catalog_t *catalog = stream->xine->plugin_catalog; plugin_node_t *node = vd->node; vd->dispose (vd); if (node) { pthread_mutex_lock (&catalog->lock); dec_node_ref(node); pthread_mutex_unlock (&catalog->lock); } } audio_decoder_t *_x_get_audio_decoder (xine_stream_t *stream, uint8_t stream_type) { plugin_node_t *node; int i, j; plugin_catalog_t *catalog = stream->xine->plugin_catalog; audio_decoder_t *ad = NULL; lprintf ("looking for audio decoder for streamtype %02x\n", stream_type); _x_assert(stream_type < DECODER_MAX); pthread_mutex_lock (&catalog->lock); for (i = 0; i < PLUGINS_PER_TYPE; i++) { node = catalog->audio_decoder_map[stream_type][i]; if (!node) { break; } if (!node->plugin_class && !_load_plugin_class (stream->xine, node, NULL)) { /* remove non working plugin from catalog */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to init its class.\n", node->info->id); for (j = i + 1; j < PLUGINS_PER_TYPE; j++) catalog->audio_decoder_map[stream_type][j - 1] = catalog->audio_decoder_map[stream_type][j]; catalog->audio_decoder_map[stream_type][PLUGINS_PER_TYPE-1] = NULL; i--; continue; } ad = ((audio_decoder_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream); if (ad == (audio_decoder_t*)1) { /* HACK: plugin failed to instantiate because required resources are unavailable at that time, but may be available later, so don't remove this plugin from catalog. */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to instantiate, resources temporarily unavailable.\n", node->info->id); } else if (ad) { inc_node_ref(node); ad->node = node; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s will be used for audio streamtype %02x.\n", node->info->id, stream_type); break; } else { /* remove non working plugin from catalog */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to instantiate itself.\n", node->info->id); for (j = i + 1; j < PLUGINS_PER_TYPE; j++) catalog->audio_decoder_map[stream_type][j - 1] = catalog->audio_decoder_map[stream_type][j]; catalog->audio_decoder_map[stream_type][PLUGINS_PER_TYPE-1] = NULL; i--; } } pthread_mutex_unlock (&catalog->lock); return ad; } void _x_free_audio_decoder (xine_stream_t *stream, audio_decoder_t *ad) { plugin_catalog_t *catalog = stream->xine->plugin_catalog; plugin_node_t *node = ad->node; ad->dispose (ad); if (node) { pthread_mutex_lock (&catalog->lock); dec_node_ref(node); pthread_mutex_unlock (&catalog->lock); } } int _x_decoder_available (xine_t *xine, uint32_t buftype) { plugin_catalog_t *catalog = xine->plugin_catalog; int stream_type = (buftype>>16) & 0xFF; _x_assert(stream_type < DECODER_MAX); if ( (buftype & 0xFF000000) == BUF_VIDEO_BASE ) { if( catalog->video_decoder_map[stream_type][0] ) return 1; } else if ( (buftype & 0xFF000000) == BUF_AUDIO_BASE ) { if( catalog->audio_decoder_map[stream_type][0] ) return 1; } else if ( (buftype & 0xFF000000) == BUF_SPU_BASE ) { if( catalog->spu_decoder_map[stream_type][0] ) return 1; } return 0; } #ifdef LOG static void _display_file_plugin_list (xine_list_t *list, plugin_file_t *file) { xine_list_iterator_t ite = NULL; plugin_node_t *node; while ((node = xine_list_next_value (list, &ite))) { if ((node->file == file) && (node->ref)) { printf(" plugin: %s, class: %p , %d instance(s)\n", node->info->id, node->plugin_class, node->ref); } } } #endif static void _unload_unref_plugin(xine_t *xine, plugin_node_t *node) { if (node->ref == 0) { plugin_file_t *file = node->file; /* no plugin of this class is instancied */ _dispose_plugin_class(node); /* check file references */ if (file && !file->ref && file->lib_handle && !file->no_unload) { /* unload this file */ lprintf("unloading plugin %s\n", file->filename); if (dlclose(file->lib_handle)) { const char *error = dlerror(); xine_log (xine, XINE_LOG_PLUGIN, _("load_plugins: cannot unload plugin lib %s:\n%s\n"), file->filename, error); } file->lib_handle = NULL; } } } static void _unload_unref_plugins(xine_t *xine, xine_sarray_t *list) { plugin_node_t *node; int list_id, list_size; list_size = xine_sarray_size (list); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (list, list_id); _unload_unref_plugin(xine, node); } } void xine_plugins_garbage_collector(xine_t *self) { plugin_catalog_t *catalog = self->plugin_catalog; int i; pthread_mutex_lock (&catalog->lock); for(i = 0; i < PLUGIN_TYPE_MAX; i++) { _unload_unref_plugins(self, self->plugin_catalog->plugin_lists[i]); } #if 0 { plugin_file_t *file; printf("\nPlugin summary after garbage collection : \n"); file = xine_list_first_content(self->plugin_catalog->file); while (file) { if (file->ref) { printf("\n file %s referenced %d time(s)\n", file->filename, file->ref); for(i = 0; i < PLUGIN_TYPE_MAX; i++) { _display_file_plugin_list (self->plugin_catalog->plugin_lists[i], file) } } file = xine_list_next_content(self->plugin_catalog->file); } printf("End of plugin summary\n\n"); } #endif pthread_mutex_unlock (&catalog->lock); } spu_decoder_t *_x_get_spu_decoder (xine_stream_t *stream, uint8_t stream_type) { plugin_node_t *node; int i, j; plugin_catalog_t *catalog = stream->xine->plugin_catalog; spu_decoder_t *sd = NULL; lprintf ("looking for spu decoder for streamtype %02x\n", stream_type); _x_assert(stream_type < DECODER_MAX); pthread_mutex_lock (&catalog->lock); for (i = 0; i < PLUGINS_PER_TYPE; i++) { node = catalog->spu_decoder_map[stream_type][i]; if (!node) { break; } if (!node->plugin_class && !_load_plugin_class (stream->xine, node, NULL)) { /* remove non working plugin from catalog */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to init its class.\n", node->info->id); for (j = i + 1; j < PLUGINS_PER_TYPE; j++) catalog->spu_decoder_map[stream_type][j - 1] = catalog->spu_decoder_map[stream_type][j]; catalog->spu_decoder_map[stream_type][PLUGINS_PER_TYPE-1] = NULL; i--; continue; } sd = ((spu_decoder_class_t *)node->plugin_class)->open_plugin(node->plugin_class, stream); if (sd) { inc_node_ref(node); sd->node = node; xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s will be used for spu streamtype %02x.\n", node->info->id, stream_type); break; } else { /* remove non working plugin from catalog */ xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "load_plugins: plugin %s failed to instantiate itself.\n", node->info->id); for (j = i + 1; j < PLUGINS_PER_TYPE; j++) catalog->spu_decoder_map[stream_type][j - 1] = catalog->spu_decoder_map[stream_type][j]; catalog->spu_decoder_map[stream_type][PLUGINS_PER_TYPE-1] = NULL; i--; } } pthread_mutex_unlock (&catalog->lock); return sd; } void _x_free_spu_decoder (xine_stream_t *stream, spu_decoder_t *sd) { plugin_catalog_t *catalog = stream->xine->plugin_catalog; plugin_node_t *node = sd->node; sd->dispose (sd); if (node) { pthread_mutex_lock (&catalog->lock); dec_node_ref(node); pthread_mutex_unlock (&catalog->lock); } } const char *const *xine_list_demuxer_plugins(xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_DEMUX, 0); } const char *const *xine_list_input_plugins(xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_INPUT, 0); } const char *const *xine_list_spu_plugins(xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_SPU_DECODER, 0); } const char *const *xine_list_audio_decoder_plugins(xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_AUDIO_DECODER, 0); } const char *const *xine_list_video_decoder_plugins(xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_VIDEO_DECODER, 0); } const char *const *xine_list_post_plugins(xine_t *xine) { return _build_list_typed_plugins (xine, PLUGIN_POST, 0); } const char *const *xine_list_post_plugins_typed(xine_t *xine, uint32_t type) { plugin_catalog_t *catalog = xine->plugin_catalog; plugin_node_t *node; int i; int list_id, list_size; pthread_mutex_lock (&catalog->lock); i = 0; list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_POST - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (catalog->plugin_lists[PLUGIN_POST - 1], list_id); if (((const post_info_t *)node->info->special_info)->type == type) catalog->ids[i++] = node->info->id; } catalog->ids[i] = NULL; pthread_mutex_unlock (&catalog->lock); return catalog->ids; } #define GET_PLUGIN_DESC(NAME,TYPE,CATITEM) \ const char *xine_get_##NAME##_plugin_description (xine_t *this, const char *plugin_id) { \ plugin_catalog_t *catalog = this->plugin_catalog; \ plugin_node_t *node; \ int list_id, list_size; \ pthread_mutex_lock (&catalog->lock); \ list_size = xine_sarray_size (catalog->plugin_lists[CATITEM - 1]); \ for (list_id = 0; list_id < list_size; list_id++) { \ node = xine_sarray_get (catalog->plugin_lists[CATITEM - 1], list_id); \ if (!strcasecmp (node->info->id, plugin_id)) { \ TYPE##_class_t *ic = (TYPE##_class_t *) node->plugin_class; \ const char *ret = NULL; \ if (!ic) { \ if (_load_plugin_class (this, node, NULL)) \ ic = node->plugin_class; \ } \ if (ic) \ ret = dgettext(ic->text_domain ? ic->text_domain : XINE_TEXTDOMAIN, ic->description); \ pthread_mutex_unlock (&catalog->lock); \ return ret; \ } \ } \ pthread_mutex_unlock (&catalog->lock); \ return NULL; \ } GET_PLUGIN_DESC (input, input, PLUGIN_INPUT) GET_PLUGIN_DESC (demux, demux, PLUGIN_DEMUX) GET_PLUGIN_DESC (spu, spu_decoder, PLUGIN_SPU_DECODER) GET_PLUGIN_DESC (audio, audio_decoder, PLUGIN_AUDIO_DECODER) GET_PLUGIN_DESC (video, video_decoder, PLUGIN_VIDEO_DECODER) GET_PLUGIN_DESC (audio_driver, audio_driver, PLUGIN_AUDIO_OUT) GET_PLUGIN_DESC (video_driver, video_driver, PLUGIN_VIDEO_OUT) GET_PLUGIN_DESC (post, post, PLUGIN_POST) xine_post_t *xine_post_init (xine_t *xine_gen, const char *name, int inputs, xine_audio_port_t **audio_target, xine_video_port_t **video_target) { xine_private_t *xine = (xine_private_t *)xine_gen; plugin_catalog_t *catalog = xine->x.plugin_catalog; plugin_node_t *node; post_plugin_t *post = NULL; int list_id, list_size; if( !name ) return NULL; pthread_mutex_lock(&catalog->lock); list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_POST - 1]); for (list_id = 0; list_id < list_size; list_id++) { node = xine_sarray_get (catalog->plugin_lists[PLUGIN_POST - 1], list_id); if (strcmp(node->info->id, name) == 0) { if (!node->plugin_class && !_load_plugin_class (&xine->x, node, NULL)) { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "load_plugins: requested post plugin %s failed to load\n", name); break; } post = ((post_class_t *)node->plugin_class)->open_plugin(node->plugin_class, inputs, audio_target, video_target); if (post) { post->running_ticket = xine->port_ticket; post->xine = &xine->x; post->node = node; inc_node_ref(node); /* init the lists of announced connections */ post->input_ids = malloc (sizeof (char *) * (xine_list_size (post->input) + 1)); if (post->input_ids) { int i = 0; xine_list_iterator_t ite = NULL; xine_post_in_t *input; while ((input = xine_list_next_value (post->input, &ite))) post->input_ids[i++] = input->name; post->input_ids[i] = NULL; } post->output_ids = malloc (sizeof (char *) * (xine_list_size (post->output) + 1)); if (post->output_ids) { int i = 0; xine_list_iterator_t ite = NULL; xine_post_out_t *output; while ((output = xine_list_next_value (post->output, &ite))) post->output_ids[i++] = output->name; post->output_ids[i] = NULL; } /* copy the post plugin type to the public part */ post->xine_post.type = ((const post_info_t *)node->info->special_info)->type; break; } else { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "load_plugins: post plugin %s failed to instantiate itself\n", name); break; } } } pthread_mutex_unlock(&catalog->lock); if(post) return &post->xine_post; else { xprintf (&xine->x, XINE_VERBOSITY_DEBUG, "load_plugins: no post plugin named %s found\n", name); return NULL; } } void xine_post_dispose(xine_t *xine, xine_post_t *post_gen) { post_plugin_t *post = (post_plugin_t *)post_gen; (void)xine; post->dispose(post); /* we cannot decrement the reference counter, since post plugins can delay * their disposal if they are still in use => post.c handles the counting for us */ } static char *_get_demux_strings (xine_t *self, int kind) { plugin_catalog_t *catalog = self->plugin_catalog; struct { const char *s; size_t len; } *slist = NULL, *slitem, *slend; char *res = NULL; pthread_mutex_lock (&catalog->lock); do { { int num, list_id; size_t size; num = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]); if (num <= 0) break; slist = malloc (num * sizeof (*slist)); if (!slist) break; slitem = slist; size = 0; for (list_id = 0; list_id < num; list_id++) { plugin_node_t *const node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (!node->plugin_class) _load_plugin_class (self, node, NULL); if (node->plugin_class) { demux_class_t *const cls = (demux_class_t *)node->plugin_class; const char *s = kind ? cls->extensions : cls->mimetypes; if (s) { slitem->s = s; size += (slitem->len = xine_find_byte (s, 0)); slitem++; } } } slend = slitem; if (slend == slist) break; res = malloc (size + (slend - slist) * (kind ? 1 : 0) + 1); if (!res) break; } { char *q = res; slitem = slist; if (kind) { do { xine_small_memcpy (q, slitem->s, slitem->len); q += slitem->len; *q++ = ' '; slitem++; } while (slitem < slend); q[-1] = 0; } else { do { xine_small_memcpy (q, slitem->s, slitem->len); q += slitem->len; slitem++; } while (slitem < slend); q[0] = 0; } } } while (0); pthread_mutex_unlock (&catalog->lock); free (slist); return res; } /* get a list of file extensions for file types supported by xine * the list is separated by spaces * * the pointer returned can be free()ed when no longer used */ char *xine_get_file_extensions (xine_t *self) { return _get_demux_strings (self, 1); } /* get a list of mime types supported by xine * * the pointer returned can be free()ed when no longer used */ char *xine_get_mime_types (xine_t *self) { return _get_demux_strings (self, 0); } /* get the demuxer identifier that handles a given mime type * * the pointer returned can be free()ed when no longer used * returns NULL if no demuxer is available to handle this. */ char *xine_get_demux_for_mime_type (xine_t *xine, const char *mime_type) { uint8_t mbuf[256]; plugin_catalog_t *catalog; char *id = NULL; int list_id, list_size; if (!xine || !mime_type) return NULL; _mime_set (mbuf, sizeof (mbuf), mime_type); catalog = xine->plugin_catalog; pthread_mutex_lock (&catalog->lock); list_size = xine_sarray_size (catalog->plugin_lists[PLUGIN_DEMUX - 1]); for (list_id = 0; (list_id < list_size) && !id; list_id++) { plugin_node_t *node = xine_sarray_get (catalog->plugin_lists[PLUGIN_DEMUX - 1], list_id); if (node->plugin_class || _load_plugin_class (xine, node, NULL)) { demux_class_t *class = (demux_class_t *)node->plugin_class; if (_mime_find (mbuf, class->mimetypes) >= 0) id = strdup (node->info->id); } } pthread_mutex_unlock (&catalog->lock); return id; } static int dispose_plugin_list (xine_sarray_t *list, int is_cache) { decoder_info_t *decoder_info; int list_id, list_size; int num = 0; if (!list) return 0; list_size = xine_sarray_size (list); for (list_id = 0; list_id < list_size; list_id++) { fat_node_t *node, *nextnode; for (node = xine_sarray_get (list, list_id); node; node = nextnode) { nextnode = is_cache && (node->node.file == &node->file) ? node->nextplugin : NULL; if (node->node.ref == 0) _dispose_plugin_class (&node->node); else { lprintf ("node \"%s\" still referenced %d time(s)\n", node->node.info->id, node->node.ref); continue; } /* free special info */ switch (node->info->type & PLUGIN_TYPE_MASK) { case PLUGIN_SPU_DECODER: case PLUGIN_AUDIO_DECODER: case PLUGIN_VIDEO_DECODER: decoder_info = (decoder_info_t *)node->node.info->special_info; if (!(IS_FAT_NODE (node) && (decoder_info->supported_types == &node->supported_types[0]))) _x_freep (&decoder_info->supported_types); /* fall thru */ default: if (!(IS_FAT_NODE (node) && node->node.info->special_info == &node->ainfo)) _x_freep (&node->node.info->special_info); break; } /* free info structure and string copies */ if (!IS_FAT_NODE (node)) { _x_freep (&node->node.info->id); _x_freep (&node->node.info); } #ifdef FAST_SCAN_PLUGINS if (node->node.config_entry_list) { xine_list_delete (node->node.config_entry_list); node->node.config_entry_list = NULL; } #else _free_string_list (&node->node.config_entry_list); #endif /* file entries in cache list are "dummies" (do not refer to opened files) */ /* those are not in file list, so free here */ if (is_cache && node->node.file) { _x_assert (node->node.file->lib_handle == NULL); _x_assert (node->node.file->ref == 0); if (node->node.file != &node->file) { _x_freep (&node->node.file->filename); _x_freep (&node->node.file); } } free (node); num++; } } xine_sarray_delete (list); return num; } static void dispose_plugin_file_list (xine_list_t *list) { plugin_file_t *file; xine_list_iterator_t ite = NULL; while ((file = xine_list_next_value (list, &ite))) { if ((char *)file + sizeof (*file) != file->filename) { _x_freep (&file->filename); } free (file); } xine_list_delete (list); } /* * dispose all currently loaded plugins (shutdown) */ void _x_dispose_plugins (xine_t *this) { if(this->plugin_catalog) { int i; if (this->config) { i = this->config->unregister_callbacks (this->config, NULL, _decoder_priority_cb, NULL, 0); if (i) xprintf (this, XINE_VERBOSITY_DEBUG, "load_plugins: unregistered %d decoder priority callbacks.\n", i); } for (i = 0; i < PLUGIN_TYPE_MAX; i++) { dispose_plugin_list (this->plugin_catalog->plugin_lists[i], 0); } dispose_plugin_list (this->plugin_catalog->modules_list, 0); i = dispose_plugin_list (this->plugin_catalog->cache_list, 1); if (i) xprintf (this, XINE_VERBOSITY_DEBUG, "load_plugins: dropped %d outdated cache entries.\n", i); dispose_plugin_file_list (this->plugin_catalog->file_list); for (i = 0; this->plugin_catalog->prio_desc[i]; i++) _x_freep(&this->plugin_catalog->prio_desc[i]); pthread_mutex_destroy(&this->plugin_catalog->lock); _x_freep (&this->plugin_catalog); { xine_private_t *_xine = (xine_private_t *)this; xine_ref_string_unref (&_xine->strings.decoder_pri_help); } } } xine-lib-1.2/src/xine-engine/video_decoder.c0000644000175000017500000007001614647725152016624 0ustar meme/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #define LOG_MODULE "video_decoder" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "xine_private.h" #include #define SPU_SLEEP_INTERVAL (90000/2) #ifndef SCHED_OTHER #define SCHED_OTHER 0 #endif static void update_spu_decoder (xine_stream_t *stream, int type) { int streamtype = (type>>16) & 0xFF; if (!stream) return; if( stream->spu_decoder_streamtype != streamtype || !stream->spu_decoder_plugin ) { if (stream->spu_decoder_plugin) _x_free_spu_decoder (stream, stream->spu_decoder_plugin); stream->spu_decoder_streamtype = streamtype; stream->spu_decoder_plugin = _x_get_spu_decoder (stream, streamtype); } } int _x_spu_decoder_sleep (xine_stream_t *s, int64_t next_spu_vpts) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_private_t *xine; int64_t time, wait; int thread_vacant = 1; if (!stream) return 0; xine = (xine_private_t *)stream->s.xine; /* we wait until one second before the next SPU is due */ next_spu_vpts -= 90000; do { if (next_spu_vpts) time = xine->x.clock->get_current_time (xine->x.clock); else time = 0; /* wait in pieces of one half second */ if (next_spu_vpts - time < SPU_SLEEP_INTERVAL) wait = next_spu_vpts - time; else wait = SPU_SLEEP_INTERVAL; if (wait > 0) xine_usec_sleep(wait * 11); if (xine->port_ticket->ticket_revoked) xine->port_ticket->renew (xine->port_ticket, 0); /* never wait, if we share the thread with a video decoder */ thread_vacant = !stream->video_decoder_plugin; /* we have to return if video out calls for the decoder */ if (thread_vacant && stream->s.video_fifo->first) thread_vacant = (stream->s.video_fifo->first->type != BUF_CONTROL_FLUSH_DECODER); /* we have to return if the demuxer needs us to release a buffer */ if (thread_vacant) thread_vacant = !_x_action_pending (&stream->s); } while (wait == SPU_SLEEP_INTERVAL && thread_vacant); return thread_vacant; } static void *video_decoder_loop (void *stream_gen) { xine_stream_private_t *stream = (xine_stream_private_t *)stream_gen, *m = stream->side_streams[0]; xine_private_t *xine = (xine_private_t *)stream->s.xine; xine_ticket_t *running_ticket = xine->port_ticket; int running = 1; int seek_count; int restart = 1; int start = 1; int streamtype; int prof_video_decode = -1; int prof_spu_decode = -1; uint32_t buftype_unknown = 0; int64_t last_pts = 0; /* generic bitrate estimation. */ int64_t video_br_lasttime = 0; uint32_t video_br_lastsize = 0; uint32_t video_br_time = 1; uint32_t video_br_bytes = 0; int video_br_num = 20; int video_br_value = 0; /* list of seen spu channels, sorted by number. * spu_track_map[foo] & 0xff000000 is always BUF_SPU_BASE, * and bit 31 may serve as an end marker. */ #define SPU_TRACK_MAP_MAX 50 #define SPU_TRACK_MAP_MASK 0x8000ffff #define SPU_TRACK_MAP_END 0x80000000 uint32_t spu_track_map[SPU_TRACK_MAP_MAX + 1]; #define BUFTYPE_BASE(type) ((type) >> 24) #define BUFTYPE_SUB(type) (((type) & 0x00ff0000) >> 16) #ifndef WIN32 errno = 0; if (nice(-1) == -1 && errno) xine_log (stream->s.xine, XINE_LOG_MSG, "video_decoder: can't raise nice priority by 1: %s\n", strerror(errno)); #endif /* WIN32 */ if (prof_video_decode == -1) prof_video_decode = xine_profiler_allocate_slot ("video decoder"); if (prof_spu_decode == -1) prof_spu_decode = xine_profiler_allocate_slot ("spu decoder"); spu_track_map[0] = SPU_TRACK_MAP_END; memset (stream->video_decoder_extra_info, 0, sizeof (*stream->video_decoder_extra_info)); pthread_mutex_lock (&stream->first_frame.lock); stream->video_decoder_extra_info->seek_count = seek_count = stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); running_ticket->acquire (running_ticket, 0); while (running) { int handled, ignore; buf_element_t *buf; lprintf ("getting buffer...\n"); buf = stream->s.video_fifo->tget (stream->s.video_fifo, running_ticket); if (!buf->extra_info->invalid) { if (buf->extra_info->input_normpos) stream->video_decoder_extra_info->input_normpos = buf->extra_info->input_normpos; if (buf->extra_info->input_time) stream->video_decoder_extra_info->input_time = buf->extra_info->input_time; if (buf->extra_info->frame_number) stream->video_decoder_extra_info->frame_number = buf->extra_info->frame_number; if (buf->extra_info->total_time) stream->video_decoder_extra_info->total_time = buf->extra_info->total_time; } stream->video_decoder_extra_info->seek_count = seek_count; lprintf ("got buffer 0x%08x\n", buf->type); switch (BUFTYPE_BASE (buf->type)) { case BUFTYPE_BASE (BUF_VIDEO_BASE): if ((buf->type & 0xffff0000) == BUF_VIDEO_UNKNOWN) break; xine_rwlock_rdlock (&stream->info_lock); handled = stream->stream_info[XINE_STREAM_INFO_VIDEO_HANDLED]; ignore = stream->stream_info[XINE_STREAM_INFO_IGNORE_VIDEO]; xine_rwlock_unlock (&stream->info_lock); (void)handled; /* dont optimize away the read. */ if (ignore) break; /* at first frame contents after start or seek, read first_frame_flag. * this way, video_port.draw () need not grab lock for _every_ frame. */ if (restart) { /* a 4 byte buf may be a generated sequence end code from mpeg-ts. */ if (!(buf->decoder_flags & (BUF_FLAG_PREVIEW | BUF_FLAG_HEADER)) && (buf->size != 4)) { int first_frame_flag; restart = 0; pthread_mutex_lock (&stream->first_frame.lock); first_frame_flag = stream->first_frame.flag; pthread_mutex_unlock (&stream->first_frame.lock); /* use first_frame_flag here, so gcc does not optimize it away. */ xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "video_decoder: first_frame_flag = %d.\n", first_frame_flag); } } xine_profiler_start_count (prof_video_decode); /* running_ticket->acquire(running_ticket, 0); */ /* printf ("video_decoder: got package %d, decoder_info[0]:%d\n", buf, buf->decoder_info[0]); */ streamtype = (buf->type>>16) & 0xFF; if( buf->type != buftype_unknown && (stream->video_decoder_streamtype != streamtype || !stream->video_decoder_plugin) ) { if (stream->video_decoder_plugin) { _x_free_video_decoder (&stream->s, stream->video_decoder_plugin); } stream->video_decoder_streamtype = streamtype; stream->video_decoder_plugin = _x_get_video_decoder (&stream->s, streamtype); /* video_br_reset */ video_br_lasttime = 0; video_br_lastsize = 0; video_br_time = 1; /* No / 0 please. */ video_br_bytes = 0; video_br_num = 20; video_br_value = 0; handled = (stream->video_decoder_plugin != NULL); xine_rwlock_wrlock (&stream->info_lock); stream->stream_info[XINE_STREAM_INFO_VIDEO_HANDLED] = handled; xine_rwlock_unlock (&stream->info_lock); } /* legacy: decoders need not pass extra info themselves. * pass them around here, and allow video_out.vo_set_img_ei () to fix reordering. * both will be called from this thread (directly below and inside video_port.draw ()). */ if ((buf->pts || start) && (buf->pts != last_pts)) { last_pts = buf->pts; m->video_decoder_ei_index = (m->video_decoder_ei_index + 1) & (_XINE_EI_RING_SIZE - 1); /* this covers roughly 1.4 seconds at 5.7 ms resolution, which alone should be * enough to identify the ring index used. */ m->video_decoder_ei_fast[((uint32_t)last_pts >> 9) & 255] = m->video_decoder_ei_index; m->ei[2 + m->video_decoder_ei_index].pts = last_pts; m->ei[2 + m->video_decoder_ei_index].ei = *stream->video_decoder_extra_info; start = 0; } /* video_br_add. some decoders reset buf->pts, do this first. */ if (buf->pts) { int64_t d = buf->pts - video_br_lasttime; if (d > 0) { if (d < 220000) { video_br_time += d; video_br_bytes += video_br_lastsize; video_br_lastsize = 0; if (--video_br_num < 0) { int br, bdiff; video_br_num = 20; if ((video_br_bytes | video_br_time) & 0x80000000) { video_br_bytes >>= 1; video_br_time >>= 1; } br = xine_uint_mul_div (video_br_bytes, 90000 * 8, video_br_time); bdiff = br - video_br_value; if (bdiff < 0) bdiff = -bdiff; if (bdiff > (br >> 6)) { video_br_value = br; xine_rwlock_wrlock (&stream->info_lock); stream->stream_info[XINE_STREAM_INFO_VIDEO_BITRATE] = br; xine_rwlock_unlock (&stream->info_lock); } } } video_br_lasttime = buf->pts; } else { if (d <= -220000) video_br_lasttime = buf->pts; } } video_br_lastsize += buf->size; if (stream->video_decoder_plugin) stream->video_decoder_plugin->decode_data (stream->video_decoder_plugin, buf); /* no need to lock again. it may have been reset from this thread inside * video_decoder_plugin->decode_data (), if at all. * XXX: should we try a different decoder then? */ handled = stream->stream_info[XINE_STREAM_INFO_VIDEO_HANDLED]; if (!handled && (buf->type != buftype_unknown)) { const char *vname = _x_buf_video_name (buf->type); xine_log (stream->s.xine, XINE_LOG_MSG, _("video_decoder: no plugin available to handle '%s'\n"), vname); if (!_x_meta_info_get (&stream->s, XINE_META_INFO_VIDEOCODEC)) _x_meta_info_set_utf8 (&stream->s, XINE_META_INFO_VIDEOCODEC, vname); buftype_unknown = buf->type; /* fatal error - dispose plugin */ if (stream->video_decoder_plugin) { _x_free_video_decoder (&stream->s, stream->video_decoder_plugin); stream->video_decoder_plugin = NULL; } } /* if (running_ticket->ticket_revoked) * running_ticket->renew(running_ticket, 0); * running_ticket->release(running_ticket, 0); */ xine_profiler_stop_count (prof_video_decode); break; case BUFTYPE_BASE (BUF_SPU_BASE): if (_x_stream_info_get (&stream->s, XINE_STREAM_INFO_IGNORE_SPU)) break; xine_profiler_start_count (prof_spu_decode); /* running_ticket->acquire(running_ticket, 0); */ update_spu_decoder (&stream->s, buf->type); /* update track map */ { uint32_t chan = buf->type & 0x0000ffff; int i = 0; while ((spu_track_map[i] & SPU_TRACK_MAP_MASK) < chan) i++; if ((spu_track_map[i] & SPU_TRACK_MAP_MASK) != chan) { xine_event_t ui_event; int j = stream->spu_track_map_entries; if (j >= 50) { xine_profiler_stop_count (prof_spu_decode); break; } while (j >= i) { spu_track_map[j + 1] = spu_track_map[j]; j--; } spu_track_map[i] = buf->type; stream->spu_track_map_entries++; ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send (&stream->s, &ui_event); } } if (stream->s.spu_channel_user >= 0) { if (stream->s.spu_channel_user < stream->spu_track_map_entries) stream->s.spu_channel = (spu_track_map[stream->s.spu_channel_user] & 0xFF); else stream->s.spu_channel = stream->s.spu_channel_auto; } if (stream->s.spu_decoder_plugin) stream->s.spu_decoder_plugin->decode_data (stream->s.spu_decoder_plugin, buf); /* if (running_ticket->ticket_revoked) * running_ticket->renew(running_ticket, 0); * running_ticket->release(running_ticket, 0); */ xine_profiler_stop_count (prof_spu_decode); break; case BUFTYPE_BASE (BUF_CONTROL_BASE): switch (BUFTYPE_SUB (buf->type)) { int t; case BUFTYPE_SUB (BUF_CONTROL_HEADERS_DONE): pthread_mutex_lock (&stream->counter.lock); stream->counter.headers_video++; if (stream->audio_thread_created) { /* avoid useless wakes on an incomplete pair */ if (stream->counter.headers_video <= stream->counter.headers_audio) pthread_cond_broadcast (&stream->counter.changed); } else { pthread_cond_broadcast (&stream->counter.changed); } pthread_mutex_unlock (&stream->counter.lock); restart = 1; break; case BUFTYPE_SUB (BUF_CONTROL_START): stream->video_decoder_extra_info->input_normpos = 0; stream->video_decoder_extra_info->input_time = 0; stream->video_decoder_extra_info->frame_number = 0; stream->video_decoder_extra_info->total_time = 0; /* ARGH: demux_image sends whole image as preview at open_internal () time. */ pthread_mutex_lock (&stream->first_frame.lock); stream->video_decoder_extra_info->seek_count = seek_count = stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); /* decoder dispose might call port functions */ /* running_ticket->acquire(running_ticket, 0); */ if (stream->video_decoder_plugin) { _x_free_video_decoder (&stream->s, stream->video_decoder_plugin); stream->video_decoder_plugin = NULL; } if (stream->s.spu_decoder_plugin) { _x_free_spu_decoder (&stream->s, stream->s.spu_decoder_plugin); stream->s.spu_decoder_plugin = NULL; } /* running_ticket->release(running_ticket, 0); */ spu_track_map[0] = SPU_TRACK_MAP_END; stream->spu_track_map_entries = 0; if (!(buf->decoder_flags & BUF_FLAG_GAPLESS_SW)) { running_ticket->release (running_ticket, 0); stream->s.metronom->handle_video_discontinuity (stream->s.metronom, DISC_STREAMSTART, 0); running_ticket->acquire (running_ticket, 0); } buftype_unknown = 0; restart = 1; start = 1; break; case BUFTYPE_SUB (BUF_CONTROL_SPU_CHANNEL): { xine_event_t ui_event; /* We use widescreen spu as the auto selection, because widescreen * display is common. SPU decoders can choose differently if it suits them. */ stream->s.spu_channel_auto = buf->decoder_info[0]; stream->s.spu_channel_letterbox = buf->decoder_info[1]; stream->spu_channel_pan_scan = buf->decoder_info[2]; if (stream->s.spu_channel_user == -1) stream->s.spu_channel = stream->s.spu_channel_auto; /* Inform UI of SPU channel changes */ ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send (&stream->s, &ui_event); } break; case BUFTYPE_SUB (BUF_CONTROL_END): /* flush decoder frames if stream finished naturally (non-user stop) */ if (buf->decoder_flags) { /* running_ticket->acquire(running_ticket, 0); */ if (stream->video_decoder_plugin) stream->video_decoder_plugin->flush (stream->video_decoder_plugin); /* running_ticket->release(running_ticket, 0); */ } /* wait the output fifos to run dry before sending the notification event * to the frontend. exceptions: * 1) don't wait if there is more than one stream attached to the current * output port (the other stream might be sending data so we would be here forever) * 2) early_finish_event: send notification asap to allow gapless switch * 3) slave stream: don't wait. get into an unblocked state asap to allow new master actions. */ while (1) { int num_bufs, num_streams; /* running_ticket->acquire(running_ticket, 0); */ num_bufs = stream->s.video_out->get_property (stream->s.video_out, VO_PROP_BUFS_IN_FIFO); num_streams = stream->s.video_out->get_property (stream->s.video_out, VO_PROP_NUM_STREAMS); /* running_ticket->release(running_ticket, 0); */ if (num_bufs > 0 && num_streams == 1 && !stream->early_finish_event && stream->s.master == &stream->s) { running_ticket->release (running_ticket, 0); xine_usec_sleep (10000); running_ticket->acquire (running_ticket, 0); } else break; } running_ticket->release (running_ticket, 0); /* wait for audio to reach this marker, if necessary */ pthread_mutex_lock (&stream->counter.lock); stream->counter.finisheds_video++; lprintf ("reached end marker # %d\n", stream->counter.finisheds_video); if (stream->audio_thread_created) { if (stream->counter.finisheds_video > stream->counter.finisheds_audio) { do { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_sec += 1; /* use timedwait to workaround buggy pthread broadcast implementations */ pthread_cond_timedwait (&stream->counter.changed, &stream->counter.lock, &ts); } while (stream->counter.finisheds_video > stream->counter.finisheds_audio); } else if (stream->counter.finisheds_video == stream->counter.finisheds_audio) { pthread_cond_broadcast (&stream->counter.changed); } } else { pthread_cond_broadcast (&stream->counter.changed); } pthread_mutex_unlock (&stream->counter.lock); /* Wake up xine_play if it's waiting for a frame */ pthread_mutex_lock (&stream->first_frame.lock); if (stream->first_frame.flag) { stream->first_frame.flag = 0; pthread_cond_broadcast(&stream->first_frame.reached); } pthread_mutex_unlock (&stream->first_frame.lock); running_ticket->acquire (running_ticket, 0); break; case BUFTYPE_SUB (BUF_CONTROL_QUIT): /* decoder dispose might call port functions */ /* running_ticket->acquire(running_ticket, 0); */ if (stream->video_decoder_plugin) { _x_free_video_decoder (&stream->s, stream->video_decoder_plugin); stream->video_decoder_plugin = NULL; } if (stream->s.spu_decoder_plugin) { _x_free_spu_decoder (&stream->s, stream->s.spu_decoder_plugin); stream->s.spu_decoder_plugin = NULL; } /* running_ticket->release(running_ticket, 0); */ spu_track_map[0] = SPU_TRACK_MAP_END; stream->spu_track_map_entries = 0; running = 0; break; case BUFTYPE_SUB (BUF_CONTROL_RESET_DECODER): /* running_ticket->acquire(running_ticket, 0); */ if (stream->video_decoder_plugin) stream->video_decoder_plugin->reset (stream->video_decoder_plugin); if (stream->s.spu_decoder_plugin) stream->s.spu_decoder_plugin->reset (stream->s.spu_decoder_plugin); /* running_ticket->release(running_ticket, 0); */ break; case BUFTYPE_SUB (BUF_CONTROL_FLUSH_DECODER): if (stream->video_decoder_plugin) { /* running_ticket->acquire(running_ticket, 0); */ stream->video_decoder_plugin->flush (stream->video_decoder_plugin); /* running_ticket->release(running_ticket, 0); */ } break; case BUFTYPE_SUB (BUF_CONTROL_DISCONTINUITY): lprintf ("discontinuity ahead\n"); t = DISC_RELATIVE; goto handle_disc; case BUFTYPE_SUB (BUF_CONTROL_NEWPTS): lprintf ("new pts %"PRId64"\n", buf->disc_off); if (buf->decoder_flags & BUF_FLAG_SEEK) { t = DISC_STREAMSEEK; } else { t = DISC_ABSOLUTE; } handle_disc: pthread_mutex_lock (&stream->first_frame.lock); stream->video_decoder_extra_info->seek_count = seek_count = stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); if (stream->video_decoder_plugin) { /* running_ticket->acquire(running_ticket, 0); */ stream->video_decoder_plugin->discontinuity (stream->video_decoder_plugin); /* it might be a long time before we get back from a handle_video_discontinuity, * so we better flush the decoder before */ if (!stream->disable_decoder_flush_at_discontinuity) stream->video_decoder_plugin->flush (stream->video_decoder_plugin); /* running_ticket->release(running_ticket, 0); */ } running_ticket->release (running_ticket, 0); stream->s.metronom->handle_video_discontinuity (stream->s.metronom, t, buf->disc_off); running_ticket->acquire (running_ticket, 0); /* video_br_discontinuity */ video_br_lasttime = 0; video_br_lastsize = 0; break; case BUFTYPE_SUB (BUF_CONTROL_AUDIO_CHANNEL): { xine_event_t ui_event; /* Inform UI of AUDIO channel changes */ ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send (&stream->s, &ui_event); } break; case BUFTYPE_SUB (BUF_CONTROL_NOP): break; case BUFTYPE_SUB (BUF_CONTROL_RESET_TRACK_MAP): if (stream->spu_track_map_entries) { xine_event_t ui_event; spu_track_map[0] = SPU_TRACK_MAP_END; stream->spu_track_map_entries = 0; ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send (&stream->s, &ui_event); } break; default: if (buf->type != buftype_unknown) { xine_log (stream->s.xine, XINE_LOG_MSG, _("video_decoder: error, unknown buffer type: %08x\n"), buf->type); buftype_unknown = buf->type; } } /* switch (BUFTYPE_SUB (buf->type)) */ break; default: if (buf->type != buftype_unknown) { xine_log (stream->s.xine, XINE_LOG_MSG, _("video_decoder: error, unknown buffer type: %08x\n"), buf->type); buftype_unknown = buf->type; } } /* switch (BUFTYPE_BASE (buf->type)) */ buf->free_buffer (buf); } running_ticket->release (running_ticket, 0); return NULL; } int _x_video_decoder_init (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; if (!stream) return 0; stream = stream->side_streams[0]; if (stream->s.video_fifo) return 1; stream->spu_track_map_entries = 0; if (stream->s.video_out == NULL) { stream->s.video_fifo = _x_dummy_fifo_buffer_new (5, 8192); return !!stream->s.video_fifo; } else { pthread_attr_t pth_attrs; #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0) struct sched_param pth_params; #endif int err, num_buffers; /* The fifo size is based on dvd playback where buffers are filled * with 2k of data. With 500 buffers and a typical video data rate * of 8 Mbit/s, the fifo can hold about 1 second of video, wich * should be enough to compensate for drive delays. * We provide buffers of 8k size instead of 2k for demuxers sending * larger chunks. */ num_buffers = stream->s.xine->config->register_num (stream->s.xine->config, "engine.buffers.video_num_buffers", 500, _("number of video buffers"), _("The number of video buffers (each is 8k in size) xine uses in its internal queue. " "Higher values mean smoother playback for unreliable inputs, but also increased " "latency and memory consumption."), 20, NULL, NULL); if (num_buffers < 50) num_buffers = 50; if (num_buffers > 5000) num_buffers = 5000; stream->s.video_fifo = _x_fifo_buffer_new (num_buffers, 8192); if (stream->s.video_fifo == NULL) { xine_log (stream->s.xine, XINE_LOG_MSG, "video_decoder: can't allocated video fifo\n"); return 0; } pthread_attr_init(&pth_attrs); #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0) pthread_attr_getschedparam(&pth_attrs, &pth_params); pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER); pthread_attr_setschedparam(&pth_attrs, &pth_params); pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM); #endif stream->video_thread_created = 1; if ((err = pthread_create (&stream->video_thread, &pth_attrs, video_decoder_loop, stream)) != 0) { xine_log (stream->s.xine, XINE_LOG_MSG, "video_decoder: can't create new thread (%s)\n", strerror(err)); stream->video_thread_created = 0; pthread_attr_destroy(&pth_attrs); stream->s.video_fifo->dispose (stream->s.video_fifo); stream->s.video_fifo = NULL; return 0; } pthread_attr_destroy(&pth_attrs); return 1; } } void _x_video_decoder_shutdown (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; buf_element_t *buf; void *p; if (!stream) return; lprintf ("shutdown...\n"); if (stream->video_thread_created) { /* stream->video_fifo->clear(stream->video_fifo); */ buf = stream->s.video_fifo->buffer_pool_alloc (stream->s.video_fifo); lprintf ("shutdown...2\n"); buf->type = BUF_CONTROL_QUIT; stream->s.video_fifo->put (stream->s.video_fifo, buf); lprintf ("shutdown...3\n"); pthread_join (stream->video_thread, &p); stream->video_thread_created = 0; lprintf ("shutdown...4\n"); } if (stream->s.video_fifo) { stream->s.video_fifo->dispose (stream->s.video_fifo); stream->s.video_fifo = NULL; } } xine-lib-1.2/src/xine-engine/refcounter.c0000644000175000017500000000415014647725152016201 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #define LOG_MODULE "refcounter" #define LOG_VERBOSE /* #define LOG */ #include #include refcounter_t* _x_new_refcounter(void *object, void (*destructor)(void *)) { refcounter_t *new_refcounter; new_refcounter = (refcounter_t *) calloc(1, sizeof(refcounter_t)); if (!new_refcounter) return NULL; new_refcounter->count = 1; new_refcounter->object = object; new_refcounter->destructor = destructor; pthread_mutex_init (&new_refcounter->lock, NULL); lprintf("new referenced object %p\n", object); return new_refcounter; } int _x_refcounter_inc(refcounter_t *refcounter) { int res; pthread_mutex_lock(&refcounter->lock); _x_assert(refcounter->count > 0); res = ++refcounter->count; pthread_mutex_unlock(&refcounter->lock); return res; } int _x_refcounter_dec(refcounter_t *refcounter) { int res; pthread_mutex_lock(&refcounter->lock); res = --refcounter->count; pthread_mutex_unlock(&refcounter->lock); if (!res) { lprintf("calling destructor of object %p\n", refcounter->object); refcounter->destructor(refcounter->object); } return res; } void _x_refcounter_dispose(refcounter_t *refcounter) { pthread_mutex_destroy (&refcounter->lock); free(refcounter); } xine-lib-1.2/src/xine-engine/xine_private.h0000644000175000017500000005510314647725152016533 0ustar meme/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ /** * @file * @brief Declaration of internal, private functions for xine-lib. * * @internal These functions should not be used by neither plugins nor * frontends. */ #ifndef XINE_PRIVATE_H__ #define XINE_PRIVATE_H__ #ifndef XINE_LIBRARY_COMPILE # error xine_private.h is for libxine private use only! #endif #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included #endif #include #if SUPPORT_ATTRIBUTE_VISIBILITY_INTERNAL # define INTERNAL __attribute__((visibility("internal"))) #elif SUPPORT_ATTRIBUTE_VISIBILITY_DEFAULT # define INTERNAL __attribute__((__visibility__("default"))) #else # define INTERNAL #endif #if defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 )) # define XINE_DISABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") # define XINE_ENABLE_DEPRECATION_WARNINGS _Pragma("GCC diagnostic warning \"-Wdeprecated-declarations\"") #else # define XINE_DISABLE_DEPRECATION_WARNINGS # define XINE_ENABLE_DEPRECATION_WARNINGS #endif #ifdef __cplusplus # define EXTERN_C_START extern "C" { # define EXTERN_C_STOP } #else # define EXTERN_C_START # define EXTERN_C_STOP #endif EXTERN_C_START /* NOTE: casting char * to int * requires a higher alignment (1 -> 4) * on some machines. on x86, this merely gives a little speedup. * gcc -Wcast-align only warns in the former case. * clang seems to warn always, even if the code clearly shows that * the address _is_ aligned. lets try another kind of hack. */ static inline uint32_t xine_find_byte (const char *s, uint32_t byte) { const uint32_t eor = ~((byte << 24) | (byte << 16) | (byte << 8) | byte); const union { const char *b; const uint32_t *u; } u = { s - ((uintptr_t)s & 3) }; const uint32_t *p = u.u; static const union { uint8_t b[4]; uint32_t v; } mask[4] = { {{0xff, 0xff, 0xff, 0xff}}, {{0x00, 0xff, 0xff, 0xff}}, {{0x00, 0x00, 0xff, 0xff}}, {{0x00, 0x00, 0x00, 0xff}}, }; static const uint8_t rest[32] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, /* big wndian */ 0, 4, 3, 4, 2, 4, 3, 4, 1, 4, 3, 4, 2, 4, 3, 4 /* little endian */ }; const union { uint32_t v; uint8_t b[4]; } endian = {16}; uint32_t w = (*p++ ^ eor) & mask[(uintptr_t)s & 3].v; while (1) { w = w & 0x80808080 & ((w & 0x7f7f7f7f) + 0x01010101); if (w) break; w = *p++ ^ eor; } /* bits 31, 23, 15, 7 -> 3, 2, 1, 0 */ w = (w * 0x00204081) & 0xffffffff; w >>= 28; return ((const char *)p - s) - rest[endian.b[0] + w]; } /* HAVE_ATOMIC_VARS: 0 = none, 1 = stdatomic.h, 2 = __atomic_*, 3 = __sync_* */ #if (HAVE_ATOMIC_VARS > 0) # if (HAVE_ATOMIC_VARS == 1) # include # define XINE_ATINT_T atomic_int # define XINE_ATINIT(xatfa_refs,xatfa_n) atomic_init (&(xatfa_refs), (xatfa_n)) # define XINE_ATFA(xatfa_refs,xatfa_n) atomic_fetch_add_explicit (&(xatfa_refs), (xatfa_n), memory_order_acq_rel) # define XINE_ATGET(xatfa_refs) atomic_load_explicit (&(xatfa_refs), memory_order_acquire) # elif (HAVE_ATOMIC_VARS == 2) # define XINE_ATINT_T int # define XINE_ATINIT(xatfa_refs,xatfa_n) __atomic_store_n (&(xatfa_refs), (xatfa_n), __ATOMIC_RELAXED) # define XINE_ATFA(xatfa_refs,xatfa_n) __atomic_fetch_add (&(xatfa_refs), (xatfa_n), __ATOMIC_ACQ_REL) # define XINE_ATGET(xatfa_refs) __atomic_load_n (&(xatfa_refs), __ATOMIC_ACQUIRE) # else /* HAVE_ATOMIC_VARS == 3 */ # define XINE_ATINT_T volatile int # define XINE_ATINIT(xatfa_refs,xatfa_n) xatfa_refs = xatfa_n # define XINE_ATFA(xatfa_refs,xatfa_n) __sync_fetch_and_add (&(xatfa_refs), (xatfa_n)) # if defined (ARCH_X86) # define XINE_ATGET(xatfa_refs) (xatfa_refs) # else # define XINE_ATGET(xatfa_refs) __sync_fetch_and_add (&(xatfa_refs), 0) # endif # endif typedef struct { XINE_ATINT_T refs; void (*destructor) (void *object); void *object; } xine_refs_t; static inline void xine_refs_init (xine_refs_t *refs, void (*destructor) (void *object), void *object) { refs->destructor = destructor; refs->object = object; XINE_ATINIT (refs->refs, 1); } static inline int xine_refs_add (xine_refs_t *refs, int n) { return XINE_ATFA (refs->refs, n) + n; } static inline int xine_refs_sub (xine_refs_t *refs, int n) { int v = XINE_ATFA (refs->refs, -n) - n; if (v == 0) refs->destructor (refs->object); return v; } static inline int xine_refs_get (xine_refs_t *refs) { return XINE_ATGET (refs->refs); } #else typedef struct { pthread_mutex_t mutex; int refs; void (*destructor) (void *object); void *object; } xine_refs_t; static inline void xine_refs_init (xine_refs_t *refs, void (*destructor) (void *object), void *object) { refs->destructor = destructor; refs->object = object; refs->refs = 1; pthread_mutex_init (&refs->mutex, NULL); } static inline int xine_refs_add (xine_refs_t *refs, int n) { int v; pthread_mutex_lock (&refs->mutex); refs->refs += n; v = refs->refs; pthread_mutex_unlock (&refs->mutex); return v; } static inline int xine_refs_sub (xine_refs_t *refs, int n) { int v; pthread_mutex_lock (&refs->mutex); refs->refs -= n; v = refs->refs; pthread_mutex_unlock (&refs->mutex); if (v == 0) { pthread_mutex_destroy (&refs->mutex); refs->destructor (refs->object); } return v; } static inline int xine_refs_get (xine_refs_t *refs) { int v; pthread_mutex_lock (&refs->mutex); v = refs->refs; pthread_mutex_unlock (&refs->mutex); return v; } #endif /** * @defgroup load_plugins Plugins loading * @brief Functions related with plugins loading. */ /** * @ingroup load_plugins * @brief Load plugins into catalog * @param this xine instance * * All input and demux plugins will be fully loaded and initialized. * Decoder plugins are loaded on demand. Video/audio output plugins * have special load/probe functions */ int _x_scan_plugins (xine_t *this) INTERNAL; /** * @ingroup load_plugins * @brief Dispose (shutdown) all currently loaded plugins * @param this xine instance */ void _x_dispose_plugins (xine_t *this) INTERNAL; void _x_free_video_driver (xine_t *xine, vo_driver_t **driver) INTERNAL; void _x_free_audio_driver (xine_t *xine, ao_driver_t **driver) INTERNAL; ///@{ /** * @defgroup * @brief find and instantiate input and demux plugins */ demux_plugin_t *_x_find_demux_plugin_last_probe(xine_stream_t *stream, const char *last_demux_name, input_plugin_t *input) INTERNAL; input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) INTERNAL; input_plugin_t *_x_cache_plugin_get_instance (xine_stream_t *stream) INTERNAL; ///@} ///@{ /** * @defgroup * @brief create decoder fifos and threads */ int _x_video_decoder_init (xine_stream_t *stream) INTERNAL; void _x_video_decoder_shutdown (xine_stream_t *stream) INTERNAL; int _x_audio_decoder_init (xine_stream_t *stream) INTERNAL; void _x_audio_decoder_shutdown (xine_stream_t *stream) INTERNAL; ///@} /** * @brief Benchmark available memcpy methods */ void xine_probe_fast_memcpy(xine_t *xine) INTERNAL; /** * @brief Make file descriptors and sockets uninheritable */ int _x_set_file_close_on_exec(int fd) INTERNAL; int _x_set_socket_close_on_exec(int s) INTERNAL; #if defined(HAVE_PTHREAD_RWLOCK) # define xine_rwlock_t pthread_rwlock_t # define xine_rwlock_init_default(l) pthread_rwlock_init (l, NULL) # define xine_rwlock_rdlock(l) pthread_rwlock_rdlock (l) # define xine_rwlock_tryrdlock(l) pthread_rwlock_tryrdlock (l) # define xine_rwlock_timedrdlock(l,t) pthread_rwlock_timedrdlock (l, t) # define xine_rwlock_wrlock(l) pthread_rwlock_wrlock (l) # define xine_rwlock_trywrlock(l) pthread_rwlock_trywrlock (l) # define xine_rwlock_timedwrlock(l,t) pthread_rwlock_timedwrlock (l, t) # define xine_rwlock_unlock(l) pthread_rwlock_unlock (l) # define xine_rwlock_destroy(l) pthread_rwlock_destroy (l) #else # define xine_rwlock_t pthread_mutex_t # define xine_rwlock_init_default(l) pthread_mutex_init (l, NULL) # define xine_rwlock_rdlock(l) pthread_mutex_lock (l) # define xine_rwlock_tryrdlock(l) pthread_mutex_trylock (l) # define xine_rwlock_timedrdlock(l,t) pthread_mutex_timedlock (l, t) # define xine_rwlock_wrlock(l) pthread_mutex_lock (l) # define xine_rwlock_trywrlock(l) pthread_mutex_trylock (l) # define xine_rwlock_timedwrlock(l,t) pthread_mutex_timedlock (l, t) # define xine_rwlock_unlock(l) pthread_mutex_unlock (l) # define xine_rwlock_destroy(l) pthread_mutex_destroy (l) #endif #ifdef HAVE_POSIX_TIMERS # define xine_gettime(t) clock_gettime (CLOCK_REALTIME, t) #else static inline int xine_gettime (struct timespec *ts) { struct timeval tv; int r; r = gettimeofday (&tv, NULL); if (!r) { ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; } return r; } #endif #if (defined(__GNUC__) || defined(__clang__)) && defined(ARCH_X86) static inline uint32_t xine_uint_mul_div (uint32_t num, uint32_t mul, uint32_t den) { register uint32_t eax = num, edx; /* if result > 0xffffffff, return 0xffffffff without math exception. */ __asm__ __volatile__ ( "mull\t%2\n" "\tmovl\t%3, %2\n" "\tshrl\t%2\n" "\taddl\t%2, %0\n" "\tadcl\t$0, %1\n" "\tcmpl\t%1, %3\n" "\tjbe\t1f\n" "\tdivl\t%3\n" "\tjmp\t2f\n" "1:\n" "\txorl\t%0, %0\n" "\tnotl\t%0\n" "2:\n" : "=a" (eax), "=d" (edx), "=r" (mul), "=g" (den) : "0" (eax), "2" (mul), "3" (den) : "cc" ); (void)mul; (void)den; (void)edx; return eax; } #else static inline uint32_t xine_uint_mul_div (uint32_t num, uint32_t mul, uint32_t den) { return ((uint64_t)num * mul + (den >> 1)) / den; } #endif static inline int32_t xine_str2int32 (const char **s) { const uint8_t *p = (const uint8_t *)*s; uint8_t z; int32_t v; do { z = *p; if (!z) { *s = (const char *)p; return 0; } p++; z ^= '0'; } while ((z > 9) && (z != ('-' ^ '0'))); if (z == ('-' ^ '0')) { v = 0; while (1) { z = *p++ ^ '0'; if (z > 9) break; v = 10 * v - z; } } else { v = 0; do { v = 10 * v + z; z = *p++ ^ '0'; } while (z <= 9); } *s = (const char *)(p - 1); return v; } static inline uint32_t xine_str2uint32 (const char **s) { const uint8_t *p = (const uint8_t *)*s; uint8_t z; uint32_t v; do { z = *p; if (!z) { *s = (const char *)p; return 0; } p++; z ^= '0'; } while (z > 9); v = 0; do { v = 10u * v + z; z = *p++ ^ '0'; } while (z <= 9); *s = (const char *)(p - 1); return v; } static inline uint64_t xine_str2uint64 (const char **s) { const uint8_t *p = (const uint8_t *)*s; uint8_t z; uint64_t v; #if defined(__WORDSIZE) && (__WORDSIZE == 32) uint32_t u; #endif do { z = *p; if (!z) { *s = (const char *)p; return 0; } p++; z ^= '0'; } while (z > 9); #if defined(__WORDSIZE) && (__WORDSIZE == 32) u = 0; do { u = 10u * u + z; z = *p++ ^ '0'; if (z > 9) { *s = (const char *)(p - 1); return u; } } while (!(u & 0xf0000000)); v = u; #else v = 0; #endif do { v = (v << 3) + (v << 1) + z; z = *p++ ^ '0'; } while (z <= 9); *s = (const char *)(p - 1); return v; } #define XINE_MAX_INT32_STR 13 static inline void xine_int32_2str (char **s, int32_t v) { uint8_t b[24], *t = b + 11, *q = (uint8_t *)*s; uint32_t u; if (v < 0) { *q++ = '-'; u = -v; } else { u = v; } *t = 0; do { *--t = u % 10u + '0'; u /= 10u; } while (u); memcpy (q, t, 12); *s = (char *)(q + (b + 11 - t)); } static inline void xine_uint32_2str (char **s, uint32_t v) { uint8_t b[24], *t = b + 11, *q = (uint8_t *)*s; *t = 0; do { *--t = v % 10u + '0'; v /= 10u; } while (v); memcpy (q, t, 12); *s = (char *)(q + (b + 11 - t)); } #define XINE_MAX_INT64_STR 21 static inline void xine_uint64_2str (char **s, uint64_t v) { uint8_t b[44], *t = b + 21, *q = (uint8_t *)*s; *t = 0; do { *--t = v % 10u + '0'; v /= 10u; } while (v); memcpy (q, t, 21); *s = (char *)(q + (b + 21 - t)); } /* A little helper for integers whose size is not obvious, like off_t and time_t. */ #define xine_uint2str(s,v) do { \ if (sizeof (v) == 8) \ xine_uint64_2str (s, v); \ else \ xine_uint32_2str (s, v); \ } while (0) #if 1 /* XXX: Is this safe everywhere? */ # define PTR_IN_RANGE(_ptr,_start,_size) \ ((uintptr_t)((uint8_t *)(_ptr) - (uint8_t *)(_start)) < (uintptr_t)(_size)) #else # define PTR_IN_RANGE(_ptr,_start,_size) \ ((uint8_t *)(_ptr) >= (uint8_t *)(_start) && ((uint8_t *)(_ptr) < (uint8_t *)(_start) + (_size))) #endif typedef struct { xine_t x; xine_ticket_t *port_ticket; pthread_mutex_t log_lock; xine_log_cb_t log_cb; void *log_cb_user_data; int flags; int network_timeout; enum { XINE_IP_PREF_AUTO = 0, XINE_IP_PREF_4, XINE_IP_PREF_4_6, XINE_IP_PREF_6_4 } ip_pref; uint32_t join_av:1; /* lock controlling speed change access. * if we should ever introduce per stream clock and ticket, * move this to xine_stream_private_t below. */ #define SPEED_FLAG_IGNORE_CHANGE 1 #define SPEED_FLAG_CHANGING 2 #define SPEED_FLAG_WANT_LIVE 4 #define SPEED_FLAG_WANT_NEW 8 uint32_t speed_change_flags; int speed_change_new_live; int speed_change_new_speed; pthread_mutex_t speed_change_lock; pthread_cond_t speed_change_done; /* set when pauseing with port ticket granted, for XINE_PARAM_VO_SINGLE_STEP. */ /* special values for set_speed_internal (). now defined in xine/xine_internal.h. */ /* # define XINE_LIVE_PAUSE_ON 0x7ffffffd */ /* # define XINE_LIVE_PAUSE_OFF 0x7ffffffc */ /* share some often used (localized) text as xine_ref_string_t. */ struct { char *decoder_pri_help; } strings; struct { /* 0 ... 100% */ int black, color; /* up 1 per config change */ int gen; /* 0 ... 15 */ uint8_t tab[256 * 2]; } dvbsub; /* legacy support */ int audio_lin_levels; } xine_private_t; typedef struct xine_stream_private_st { xine_stream_t s; int status; uint32_t video_thread_created:1; uint32_t audio_thread_created:1; uint32_t slave_is_subtitle:1; /*< ... and will be automaticaly disposed */ uint32_t emergency_brake:1; /*< something went really wrong and this stream must be * stopped. usually due some fatal error on output * layers as they cannot call xine_stop. */ uint32_t early_finish_event:1; /*< do not wait fifos get empty before sending event */ uint32_t gapless_switch:1; /*< next stream switch will be gapless */ uint32_t keep_ao_driver_open:1; uint32_t finished_naturally:1; input_class_t *eject_class; /* vo_driver_t *video_driver;*/ pthread_t video_thread; video_decoder_t *video_decoder_plugin; extra_info_t *video_decoder_extra_info; int video_decoder_streamtype; int video_channel; int audio_track_map_entries; int audio_decoder_streamtype; pthread_t audio_thread; audio_decoder_t *audio_decoder_plugin; extra_info_t *audio_decoder_extra_info; uint32_t audio_type; /* *_user: -2 => off -1 => auto (use *_auto value) >=0 => respect the user's choice */ int audio_channel_user; /* int audio_channel_auto; */ /* spu_decoder_t *spu_decoder_plugin; */ /* int spu_decoder_streamtype; */ int spu_track_map_entries; /* int spu_channel_user; */ /* int spu_channel_auto; */ /* int spu_channel_letterbox; */ int spu_channel_pan_scan; /* int spu_channel; */ /* lock for public xine player functions */ pthread_mutex_t frontend_lock; #define XINE_NUM_SIDE_STREAMS 4 /* HACK: protected by info_lock below. * side_streams[0] always points to the master, which is the stream itself if not a side stream. * It is set by init, and does not change until dispose. * In other words: it may safely be read without lock. */ struct xine_stream_private_st *side_streams[XINE_NUM_SIDE_STREAMS]; /* 1 << side_stream_index (1, 2, 4, 8) */ uint32_t id_flag; /* a id3v2 tag of this many bytes has been parserd, or -1. */ int id3v2_tag_size; /* stream meta information */ /* Grab lock, or use helpers (see info_helper.c). */ xine_rwlock_t info_lock; int stream_info[XINE_STREAM_INFO_MAX]; /* Broken API: _x_meta_info_get_public () returns const char *, with no go away safety. * For now, we copy info to info_public when a new value is requested :-/ */ xine_rwlock_t meta_lock; char *meta_info_public[XINE_STREAM_INFO_MAX]; char *meta_info[XINE_STREAM_INFO_MAX]; /* seeking slowdown */ struct { pthread_mutex_t lock; pthread_cond_t reached; /* 3: wait for first frame to decode (stream start). * 2: wait for first frame to display (stream seek). * 1: after 2, first frame is decoded but not yet displayed. * 0: waiting done. */ uint32_t flag:2; int seek_count; } first_frame; /* wait for headers sent / stream decoding finished */ struct { pthread_mutex_t lock; pthread_cond_t changed; int headers_audio; int headers_video; int finisheds_audio; int finisheds_video; int demuxers_running; /* network buffering control. */ int nbc_refs; xine_nbc_t *nbc; } counter; /* event mechanism */ struct { pthread_mutex_t lock; xine_list_t *queues; } event; /* demux thread stuff */ struct { demux_plugin_t *plugin; pthread_t thread; pthread_mutex_t lock; pthread_mutex_t action_lock; pthread_cond_t resume; /* used in _x_demux_... functions to synchronize order of pairwise A/V buffer operations */ pthread_mutex_t pair; /* next 2 protected by action_lock */ uint32_t action_pending; uint32_t input_caps; uint32_t thread_created:1; uint32_t thread_running:1; /* filter out duplicate seek discontinuities from side streams */ uint32_t max_seek_bufs; /* set of id_flag values */ uint32_t start_buffers_sent; } demux; #define XINE_NUM_CURR_EXTRA_INFOS 2 xine_refs_t current_extra_info_index; extra_info_t current_extra_info[XINE_NUM_CURR_EXTRA_INFOS]; int open_seek_count; int delay_finish_event; /* delay event in 1/10 sec units. 0=>no delay, -1=>forever */ int slave_affection; /* what operations need to be propagated down to the slave? */ int err; xine_post_out_t video_source; xine_post_out_t audio_source; broadcaster_t *broadcaster; xine_refs_t refs; struct { pthread_mutex_t lock; xine_keyframes_entry_t *array; int size, used, lastadd; } index; uint32_t disable_decoder_flush_at_discontinuity; /* all input is... */ uint32_t seekable; /* _x_find_input_plugin () recursion protection */ input_class_t *query_input_plugins[2]; #define _XINE_EI_RING_SIZE 16 uint32_t video_decoder_ei_index; uint8_t video_decoder_ei_fast[256]; struct { int64_t pts; extra_info_t ei; } ei[2 + _XINE_EI_RING_SIZE]; } xine_stream_private_t; void xine_current_extra_info_set (xine_stream_private_t *stream, const extra_info_t *info) INTERNAL; /* Nasty net_buf_ctrl helper: inform about something outside its regular callbacks. */ #define XINE_NBC_EVENT_AUDIO_DRY 1 void xine_nbc_event (xine_stream_private_t *stream, uint32_t type) INTERNAL; /* Enable file_buf_ctrl optimizations when there is no net_buf_ctrl. * This is a kludge to detect less compatible plugins like vdr and vdr-xineliboutput. * Return actual state. */ int xine_fbc_set (fifo_buffer_t *fifo, int on) INTERNAL; /** The fast text feature. */ typedef struct xine_fast_text_s xine_fast_text_t; /** load fast text from file. */ xine_fast_text_t *xine_fast_text_load (const char *filename, size_t max_size) INTERNAL; /** get next line. you may modify return[0] ... return[filesize]. * it all stays valid until xine_fast_text_unload (). */ char *xine_fast_text_line (xine_fast_text_t *xft, size_t *linesize) INTERNAL; /** free the text. */ void xine_fast_text_unload (xine_fast_text_t **xft) INTERNAL; EXTERN_C_STOP #endif xine-lib-1.2/src/xine-engine/accel_vdpau.h0000644000175000017500000000303614647725152016302 0ustar meme/* * Copyright (C) 2008-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * Common acceleration definitions for vdpau * * */ #ifndef HAVE_XINE_ACCEL_VDPAU_H #define HAVE_XINE_ACCEL_VDPAU_H #ifdef __cplusplus extern "C" { #endif #include typedef struct { vo_frame_t *vo_frame; VdpDevice vdp_device; VdpGetErrorString *vdp_get_error_string; VdpDecoderCreate *vdp_decoder_create; VdpDecoderDestroy *vdp_decoder_destroy; VdpDecoderRender *vdp_decoder_render; /* if not NULL, call these around the 3 above. */ void (*lock) (vo_frame_t *frame); void (*unlock) (vo_frame_t *frame); VdpVideoSurface surface; VdpChromaType chroma; int vdp_runtime_nr; /* this is used to keep in sync on preemptions */ int *current_vdp_runtime_nr; } vdpau_accel_t; #ifdef __cplusplus } #endif #endif xine-lib-1.2/src/xine-engine/accel_vaapi.h0000644000175000017500000000777114647725152016275 0ustar meme/* * Copyright (C) 2012 Edgar Hucek * Copyright (C) 2012-2016 xine developers * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * Common acceleration definitions for vaapi * * */ #ifndef HAVE_XINE_ACCEL_VAAPI_H #define HAVE_XINE_ACCEL_VAAPI_H #ifdef __cplusplus extern "C" { #endif #include #define SURFACE_FREE 0 #define SURFACE_ALOC 1 #define SURFACE_RELEASE 2 #define SURFACE_RENDER 3 #define SURFACE_RENDER_RELEASE 5 struct vaapi_equalizer { VADisplayAttribute brightness; VADisplayAttribute contrast; VADisplayAttribute hue; VADisplayAttribute saturation; }; typedef struct ff_vaapi_context_s ff_vaapi_context_t; typedef struct ff_vaapi_surface_s ff_vaapi_surface_t; struct ff_vaapi_context_s { VADisplay va_display; VAContextID va_context_id; VAConfigID va_config_id; int width; int height; unsigned int valid_context; /* decoding surfaces */ VASurfaceID *va_surface_ids; ff_vaapi_surface_t *va_render_surfaces; unsigned int va_head; vo_driver_t *driver; VAImageFormat *va_image_formats; int va_num_image_formats; }; typedef struct vaapi_accel_s vaapi_accel_t; struct ff_vaapi_surface_s { unsigned int index; VASurfaceID va_surface_id; unsigned int status; }; /* * */ #define IMGFMT_VAAPI 0x56410000 /* 'VA'00 */ #define IMGFMT_VAAPI_MASK 0xFFFF0000 #define IMGFMT_VAAPI_CODEC_MASK 0x000000F0 #define IMGFMT_VAAPI_CODEC(fmt) ((fmt) & IMGFMT_VAAPI_CODEC_MASK) #define IMGFMT_VAAPI_CODEC_MPEG2 (0x10) #define IMGFMT_VAAPI_CODEC_MPEG4 (0x20) #define IMGFMT_VAAPI_CODEC_H264 (0x30) #define IMGFMT_VAAPI_CODEC_VC1 (0x40) #define IMGFMT_VAAPI_CODEC_HEVC (0x50) #define IMGFMT_VAAPI_MPEG2 (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG2) #define IMGFMT_VAAPI_MPEG2_IDCT (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG2|1) #define IMGFMT_VAAPI_MPEG2_MOCO (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG2|2) #define IMGFMT_VAAPI_MPEG4 (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG4) #define IMGFMT_VAAPI_H263 (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_MPEG4|1) #define IMGFMT_VAAPI_H264 (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_H264) #define IMGFMT_VAAPI_HEVC (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_HEVC) #define IMGFMT_VAAPI_HEVC_MAIN10 (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_HEVC|1) #define IMGFMT_VAAPI_VC1 (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_VC1) #define IMGFMT_VAAPI_WMV3 (IMGFMT_VAAPI|IMGFMT_VAAPI_CODEC_VC1|1) struct vaapi_accel_funcs_s { int (*lock_vaapi)(vo_frame_t *frame_gen); void (*unlock_vaapi)(vo_frame_t *frame_gen); VAStatus (*vaapi_init)(vo_frame_t *frame_gen, int va_profile, int width, int height); int (*profile_from_imgfmt)(vo_frame_t *frame_gen, unsigned img_fmt); ff_vaapi_context_t *(*get_context)(vo_frame_t *frame_gen); int (*guarded_render)(vo_frame_t *frame_gen); ff_vaapi_surface_t *(*get_vaapi_surface)(vo_frame_t *frame_gen); void (*render_vaapi_surface)(vo_frame_t *frame_gen, ff_vaapi_surface_t *va_surface); void (*release_vaapi_surface)(vo_frame_t *frame_gen, ff_vaapi_surface_t *va_surface); }; struct vaapi_accel_s { unsigned int index; const struct vaapi_accel_funcs_s *f; }; #ifdef __cplusplus } #endif #endif xine-lib-1.2/src/xine-engine/builtins.h0000644000175000017500000000201314647725152015657 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Collect some very basic plugins when building them into libxine. */ #ifndef XINE_ENGINE_BUILTINS_H #define XINE_ENGINE_BUILTINS_H #include extern const plugin_info_t xine_builtin_plugin_info[]; #endif xine-lib-1.2/src/xine-engine/scratch.c0000644000175000017500000000644214647725152015462 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * top-level xine functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #define LOG_MODULE "scratch" #define LOG_VERBOSE /* #define LOG */ #include #include static void XINE_FORMAT_PRINTF(2, 0) scratch_printf (scratch_buffer_t *this, const char *format, va_list argp) { time_t t; struct tm tm; size_t l; pthread_mutex_lock (&this->lock); time (&t); #ifndef HAVE_LOCALTIME_R tm = *localtime(&t); #else localtime_r (&t, &tm); #endif if ( ! this->lines[this->cur] ) this->lines[this->cur] = malloc(SCRATCH_LINE_LEN_MAX+1); if ( ! this->lines[this->cur] ) { pthread_mutex_unlock (&this->lock); return; } l = strftime (this->lines[this->cur], SCRATCH_LINE_LEN_MAX, "%X: ", &tm); vsnprintf (this->lines[this->cur] + l, SCRATCH_LINE_LEN_MAX - l, format, argp); lprintf ("printing format %s to line %d\n", format, this->cur); this->cur = (this->cur + 1) % this->num_lines; pthread_mutex_unlock (&this->lock); } static char **scratch_get_content (scratch_buffer_t *this) { int i, j; pthread_mutex_lock (&this->lock); for(i = 0, j = (this->cur - 1); i < this->num_lines; i++, j--) { if(j < 0) j = (this->num_lines - 1); free (this->ordered[i]); this->ordered[i] = this->lines[j] ? strdup (this->lines[j]) : NULL; lprintf ("line %d contains >%s<\n", i , this->lines[j]); } pthread_mutex_unlock (&this->lock); return this->ordered; } static void scratch_dispose (scratch_buffer_t *this) { int i; pthread_mutex_lock (&this->lock); for(i = 0; i < this->num_lines; i++ ) { _x_freep(&this->ordered[i]); _x_freep(&this->lines[i]); } _x_freep (&this->lines); _x_freep (&this->ordered); pthread_mutex_unlock (&this->lock); pthread_mutex_destroy (&this->lock); free (this); } scratch_buffer_t *_x_new_scratch_buffer (int num_lines) { scratch_buffer_t *this; this = calloc(1, sizeof(scratch_buffer_t)); if (!this) return NULL; this->lines = calloc ((num_lines + 1), sizeof(char*)); this->ordered = calloc ((num_lines + 1), sizeof(char*)); if (!this->lines || !this->ordered) goto fail; this->scratch_printf = scratch_printf; this->get_content = scratch_get_content; this->dispose = scratch_dispose; this->num_lines = num_lines; this->cur = 0; pthread_mutex_init (&this->lock, NULL); return this; fail: free(this->lines); free(this->ordered); free(this); return NULL; } xine-lib-1.2/src/xine-engine/builtins.c0000644000175000017500000000347014647725152015662 0ustar meme/* * Copyright (C) 2000-2019 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Collect some very basic plugins when building them into libxine. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef XINE_MAKE_BUILTINS #include "builtins.h" /* * Some people call this technique "the amalgamation". * It serves to improve optimization. * Here, it mainly serves to avoid cross directory build trouble with automake. * Anyway, it requires a certain naming discipline from the participants. */ #undef LOG_MODULE #include "../input/input_helper.c" #undef LOG_MODULE #include "../input/input_file.c" #undef LOG_MODULE #include "../input/input_stdin_fifo.c" #undef LOG_MODULE #include "../input/input_test.c" #undef LOG_MODULE #include "../video_out/video_out_none.c" #undef LOG_MODULE #include "../audio_out/audio_none_out.c" #undef LOG_MODULE #include "../audio_out/audio_file_out.c" const plugin_info_t xine_builtin_plugin_info[] = { INPUT_FILE_CATALOG, INPUT_STDIN_CATALOG, INPUT_TEST_CATALOG, VO_NONE_CATALOG, AO_NONE_CATALOG, AO_FILE_CATALOG, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; #endif xine-lib-1.2/src/xine-engine/lrb.h0000644000175000017500000000246214647725152014615 0ustar meme/* * Copyright (C) 2001-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * lrb : limited ring buffer * used for temporal buffer, limited to n elements */ #ifndef HAVE_LRB_H #define HAVE_LRB_H #include typedef struct { int max_num_entries; int cur_num_entries; buf_element_t *newest, *oldest; fifo_buffer_t *fifo; } lrb_t; lrb_t *lrb_new (int max_num_entries, fifo_buffer_t *fifo) ; void lrb_drop (lrb_t *this) ; void lrb_add (lrb_t *this, buf_element_t *buf) ; void lrb_feedback (lrb_t *this, fifo_buffer_t *fifo) ; void lrb_flush (lrb_t *this) ; #endif xine-lib-1.2/src/xine-engine/accel_xvmc.h0000644000175000017500000001104014647725152016132 0ustar meme/* * Copyright (C) 2000-2018 the xine project * Copyright (C) 2004 the Unichrome project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * Common acceleration definitions for XvMC. * * */ #ifndef HAVE_XINE_ACCEL_H #define HAVE_XINE_ACCEL_H #ifdef __cplusplus extern "C" { #endif typedef struct xine_macroblock_s { short *blockptr; /* pointer to current dct block */ short *blockbaseptr; /* pointer to base of dct block array in blocks */ short xvmc_accel; /* type of acceleration supported */ } xine_macroblocks_t; typedef struct xine_vld_frame_s { int version; /* Backward compatibility */ int mv_ranges[2][2]; int picture_structure; int picture_coding_type; int intra_dc_precision; int mpeg_coding; int progressive_sequence; int scan; int pred_dct_frame; int concealment_motion_vectors; int q_scale_type; int intra_vlc_format; int second_field; int load_intra_quantizer_matrix; int load_non_intra_quantizer_matrix; uint8_t intra_quantizer_matrix[64]; uint8_t non_intra_quantizer_matrix[64]; vo_frame_t *backward_reference_frame; vo_frame_t *forward_reference_frame; } xine_vld_frame_t; typedef struct xine_xvmc_s { vo_frame_t *vo_frame; xine_macroblocks_t *macroblocks; void (*proc_macro_block)(int x,int y,int mb_type, int motion_type,int (*mv_field_sel)[2], int *dmvector,int cbp,int dct_type, vo_frame_t *current_frame,vo_frame_t *forward_ref_frame, vo_frame_t *backward_ref_frame,int picture_structure, int second_field,int (*f_mot_pmv)[2],int (*b_mot_pmv)[2]); } xine_xvmc_t ; #define XVMC_DATA(frame_gen) ((frame_gen) ? (xine_xvmc_t *)(frame_gen)->accel_data : (xine_xvmc_t *)0) #define XVMC_FRAME(frame_gen) ((frame_gen) ? (xvmc_frame_t *)XVMC_DATA(frame_gen)->vo_frame : (xvmc_frame_t *)0) typedef struct xine_xxmc_s { /* * We inherit the xine_xvmc_t properties. */ xine_xvmc_t xvmc; unsigned mpeg; unsigned acceleration; int fallback_format; xine_vld_frame_t vld_frame; uint8_t *slice_data; unsigned slice_data_size; unsigned slice_code; int result; int decoded; float sleep; void (*proc_xxmc_update_frame) (vo_driver_t *this_gen, vo_frame_t *frame_gen, uint32_t width, uint32_t height, double ratio, int format, int flags); void (*proc_xxmc_begin) (vo_frame_t *vo_img); void (*proc_xxmc_slice) (vo_frame_t *vo_img); void (*proc_xxmc_flush) (vo_frame_t *vo_img); /* * For thread-safety only. */ int (*proc_xxmc_lock_valid) (vo_frame_t *cur_frame, vo_frame_t *fw_frame, vo_frame_t *bw_frame,unsigned pc_type); void (*proc_xxmc_unlock) (vo_driver_t *this_gen); } xine_xxmc_t; #define XXMC_DATA(frame_gen) ((frame_gen) ? (xine_xxmc_t *)(frame_gen)->accel_data : (xine_xxmc_t *)0) #define XXMC_FRAME(frame_gen) ((frame_gen) ? (xxmc_frame_t *)XXMC_DATA(frame_gen)->xvmc.vo_frame : (xxmc_frame_t *)0) /* * Register XvMC stream types here. */ #define XINE_XVMC_MPEG_1 0x00000001 #define XINE_XVMC_MPEG_2 0x00000002 #define XINE_XVMC_MPEG_4 0x00000004 /* * Register XvMC acceleration levels here. */ #define XINE_XVMC_ACCEL_MOCOMP 0x00000001 #define XINE_XVMC_ACCEL_IDCT 0x00000002 #define XINE_XVMC_ACCEL_VLD 0x00000004 /* xvmc acceleration types */ #define XINE_VO_MOTION_ACCEL 1 #define XINE_VO_IDCT_ACCEL 2 #define XINE_VO_SIGNED_INTRA 4 /* motion types */ #define XINE_MC_FIELD 1 #define XINE_MC_FRAME 2 #define XINE_MC_16X8 2 #define XINE_MC_DMV 3 /* picture coding type */ #define XINE_PICT_I_TYPE 1 #define XINE_PICT_P_TYPE 2 #define XINE_PICT_B_TYPE 3 #define XINE_PICT_D_TYPE 4 /* macroblock modes */ #define XINE_MACROBLOCK_INTRA 1 #define XINE_MACROBLOCK_PATTERN 2 #define XINE_MACROBLOCK_MOTION_BACKWARD 4 #define XINE_MACROBLOCK_MOTION_FORWARD 8 #define XINE_MACROBLOCK_QUANT 16 #define XINE_MACROBLOCK_DCT_TYPE_INTERLACED 32 #ifdef __cplusplus } #endif #endif xine-lib-1.2/src/xine-engine/metronom.c0000644000175000017500000016574514647725152015707 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #define LOG_MODULE "metronom" #define LOG_VERBOSE /* #define LOG #define LOG_AUDIO */ #define METRONOM_CLOCK_INTERNAL #include #include #include /* xine_rwlock_* */ #include "xine_private.h" #define AUDIO_SAMPLE_LD 15 #define AUDIO_SAMPLE_NUM (1 << AUDIO_SAMPLE_LD) #define AUDIO_SAMPLE_MASK (AUDIO_SAMPLE_NUM - 1) #define MAX_SCR_PROVIDERS 10 #define MAX_SPEED_CHANGE_CALLBACKS 16 #define VIDEO_DRIFT_TOLERANCE 45000 #define AUDIO_DRIFT_TOLERANCE 45000 /* metronom video modes */ #define VIDEO_PREDICTION_MODE 0 /* use pts + frame duration */ #define VIDEO_PTS_MODE 1 /* use only pts */ /* redefine abs as macro to handle 64-bit diffs. i guess llabs may not be available everywhere */ #define abs(x) ( ((x)<0) ? -(x) : (x) ) /* * **************************************** * primary SCR plugin: * unix System Clock Reference * **************************************** */ typedef struct { /* Time of last speed change. */ struct timeval cur_time; int64_t cur_pts; /* speed * 90000 / XINE_FINE_SPEED_NORMAL */ double speed_factor_1; /* speed_factor_1 / 1000000 */ double speed_factor_2; } unixscr_values_t; typedef struct { scr_plugin_t scr; void *mem_to_free; unixscr_values_t v; xine_rwlock_t lock; #if (HAVE_ATOMIC_VARS > 0) xine_refs_t num_speed_changes; #endif } unixscr_t; #if (HAVE_ATOMIC_VARS > 0) static void unixscr_dummy (void *object) { (void)object; } #endif static int unixscr_get_priority (scr_plugin_t *scr) { (void)scr; return 5; /* low priority */ } /* Only call this when already mutex locked */ static void unixscr_set_pivot (unixscr_t *this) { struct timeval tv; double pts_calc; xine_monotonic_clock (&tv, NULL); pts_calc = (tv.tv_sec - this->v.cur_time.tv_sec) * this->v.speed_factor_1; /* Make sure this diff is signed. */ pts_calc += ((int32_t)tv.tv_usec - (int32_t)this->v.cur_time.tv_usec) * this->v.speed_factor_2; /* This next part introduces a one off inaccuracy to the scr due to rounding tv to pts. */ this->v.cur_pts = this->v.cur_pts + pts_calc; this->v.cur_time = tv; } static int unixscr_set_speed (scr_plugin_t *scr, int speed) { unixscr_t *this = (unixscr_t*) scr; xine_rwlock_wrlock (&this->lock); #if (HAVE_ATOMIC_VARS > 0) xine_refs_add (&this->num_speed_changes, 1); #endif unixscr_set_pivot( this ); this->v.speed_factor_1 = (double)speed * 90000.0 / XINE_FINE_SPEED_NORMAL; this->v.speed_factor_2 = this->v.speed_factor_1 * 1e-6; #if (HAVE_ATOMIC_VARS > 0) xine_refs_add (&this->num_speed_changes, 1); #endif xine_rwlock_unlock (&this->lock); return speed; } static void unixscr_adjust (scr_plugin_t *scr, int64_t vpts) { unixscr_t *this = (unixscr_t*) scr; xine_rwlock_wrlock (&this->lock); #if (HAVE_ATOMIC_VARS > 0) xine_refs_add (&this->num_speed_changes, 1); #endif this->v.cur_pts = vpts; xine_monotonic_clock (&this->v.cur_time, NULL); #if (HAVE_ATOMIC_VARS > 0) xine_refs_add (&this->num_speed_changes, 1); #endif xine_rwlock_unlock (&this->lock); } static void unixscr_start (scr_plugin_t *scr, int64_t start_vpts) { unixscr_t *this = (unixscr_t*) scr; xine_rwlock_wrlock (&this->lock); #if (HAVE_ATOMIC_VARS > 0) xine_refs_add (&this->num_speed_changes, 1); #endif this->v.cur_pts = start_vpts; xine_monotonic_clock (&this->v.cur_time, NULL); /* XINE_FINE_SPEED_NORMAL */ this->v.speed_factor_1 = 90000.0; this->v.speed_factor_2 = 0.09; #if (HAVE_ATOMIC_VARS > 0) xine_refs_add (&this->num_speed_changes, 1); #endif xine_rwlock_unlock (&this->lock); } static int64_t unixscr_get_current (scr_plugin_t *scr) { unixscr_t *this = (unixscr_t*) scr; struct timeval tv; int64_t pts; xine_monotonic_clock (&tv, NULL); #if (HAVE_ATOMIC_VARS > 0) { int refs = xine_refs_get (&this->num_speed_changes); if (refs & 1) { /* TJ. no change in progress, try a snapshot without lock first. * the "volatile" is there to stop compiler from reordering code. * tested with gcc -O3 -S 4.5/x86-32 and 7/x86-64. * there is a point where all optimization falls over into chaos. * we are getting closer ;-) */ volatile unixscr_values_t v = this->v; if (refs == xine_refs_get (&this->num_speed_changes)) { double pts_calc; pts_calc = (tv.tv_sec - v.cur_time.tv_sec) * v.speed_factor_1; pts_calc += ((int32_t)tv.tv_usec - (int32_t)v.cur_time.tv_usec) * v.speed_factor_2; pts = v.cur_pts + pts_calc; return pts; } } } #endif xine_rwlock_rdlock (&this->lock); { double pts_calc; pts_calc = (tv.tv_sec - this->v.cur_time.tv_sec) * this->v.speed_factor_1; pts_calc += ((int32_t)tv.tv_usec - (int32_t)this->v.cur_time.tv_usec) * this->v.speed_factor_2; pts = this->v.cur_pts + pts_calc; } xine_rwlock_unlock (&this->lock); return pts; } static void unixscr_exit (scr_plugin_t *scr) { unixscr_t *this = (unixscr_t*) scr; #if (HAVE_ATOMIC_VARS > 0) int refs = xine_refs_get (&this->num_speed_changes); xine_refs_sub (&this->num_speed_changes, refs); #endif xine_rwlock_destroy (&this->lock); free (this->mem_to_free); } static scr_plugin_t *unixscr_init (void *this_gen) { unixscr_t *this = (unixscr_t *)this_gen; if (this) { this->mem_to_free = NULL; } else { this = calloc (1, sizeof (unixscr_t)); if (!this) return NULL; this->mem_to_free = this; } this->scr.interface_version = 3; this->scr.get_priority = unixscr_get_priority; this->scr.set_fine_speed = unixscr_set_speed; this->scr.adjust = unixscr_adjust; this->scr.start = unixscr_start; this->scr.get_current = unixscr_get_current; this->scr.exit = unixscr_exit; xine_rwlock_init_default (&this->lock); #if (HAVE_ATOMIC_VARS > 0) xine_refs_init (&this->num_speed_changes, unixscr_dummy, this); #endif this->v.cur_time.tv_sec = 0; this->v.cur_time.tv_usec = 0; this->v.cur_pts = 0; /* XINE_SPEED_PAUSE */ this->v.speed_factor_1 = 0; this->v.speed_factor_2 = 0; lprintf("xine-scr_init complete\n"); return &this->scr; } /************************************************************************ * The master clock feature. It shall handle these basic cases: * * 1. A single system clock controls all timing. * * 2. Some plugin is hard wired to use its own non-adjustable clock. * * That clock is slightly faster or slower than system clock. * * It will drift away over time, and wants xine to follow that drift. * * Such clock registers as high priority (> 5), * * and thus becomes the new master. * * 3. Some plugin uses its own drifting clock, but it is adjustable, * * and wants xine to fix that drift. * * Such clock registers as low priority (< 5). * * In cases 2 and 3, we "sync" the masters time to all other clocks * * roughly every 5 seconds. * ************************************************************************/ /* #$@! dont break existing API */ typedef struct { metronom_clock_t mct; unixscr_t uscr; int next_sync_pts; /* sync by API calls, STOP_PTS to disable */ enum { SYNC_THREAD_NONE, /* thread disabled by user, see above */ SYNC_THREAD_OFF, /* no clock to sync, or thread unavailable and -"- */ SYNC_THREAD_RUNNING /* self explaining */ } sync_thread_state; scr_plugin_t *providers[MAX_SCR_PROVIDERS + 1]; int speed_change_used; xine_speed_change_cb_t *speed_change_callbacks[MAX_SPEED_CHANGE_CALLBACKS + 1]; void *speed_change_data[MAX_SPEED_CHANGE_CALLBACKS + 1]; } metronom_clock_private_t; static void metronom_register_speed_change_callback (metronom_clock_t *this, xine_speed_change_cb_t *callback, void *user_data) { if (callback) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; pthread_mutex_lock (&this_priv->mct.lock); if (this_priv->speed_change_used < MAX_SPEED_CHANGE_CALLBACKS) { this_priv->speed_change_callbacks[this_priv->speed_change_used] = callback; this_priv->speed_change_data[this_priv->speed_change_used] = user_data; this_priv->speed_change_used++; this_priv->speed_change_callbacks[this_priv->speed_change_used] = NULL; } pthread_mutex_unlock (&this_priv->mct.lock); } } static void metronom_unregister_speed_change_callback (metronom_clock_t *this, xine_speed_change_cb_t *callback, void *user_data) { if (callback) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; int i; pthread_mutex_lock (&this_priv->mct.lock); for (i = 0; this_priv->speed_change_callbacks[i]; i++) { if ((this_priv->speed_change_callbacks[i] == callback) && (this_priv->speed_change_data[i] == user_data)) { this_priv->speed_change_used--; if (i != this_priv->speed_change_used) { this_priv->speed_change_callbacks[i] = this_priv->speed_change_callbacks[this_priv->speed_change_used]; this_priv->speed_change_data[i] = this_priv->speed_change_data[this_priv->speed_change_used]; } this_priv->speed_change_callbacks[this_priv->speed_change_used] = NULL; break; } } pthread_mutex_unlock (&this_priv->mct.lock); } } #define START_PTS 0 #define STOP_PTS ~0 #define MASK_PTS (1 << 19) /* 5.825 s */ static void metronom_start_clock (metronom_clock_t *this, int64_t pts) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t **r; lprintf("start_clock (at %" PRId64 ")\n", pts); if (this_priv->next_sync_pts != STOP_PTS) this_priv->next_sync_pts = (int)pts & MASK_PTS; pthread_mutex_lock (&this_priv->mct.lock); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) (*r)->start (*r, pts); pthread_mutex_unlock (&this_priv->mct.lock); this_priv->mct.speed = XINE_FINE_SPEED_NORMAL; } static int64_t metronom_get_current_time (metronom_clock_t *this) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; int64_t pts = this_priv->mct.scr_master->get_current (this_priv->mct.scr_master); scr_plugin_t **r; /* sync not needed or done by separate thread */ if (((int)pts & MASK_PTS) != this_priv->next_sync_pts) return pts; this_priv->next_sync_pts ^= MASK_PTS; pthread_mutex_lock (&this_priv->mct.lock); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) if (*r != this_priv->mct.scr_master) (*r)->adjust (*r, pts); pthread_mutex_unlock (&this_priv->mct.lock); return pts; } static void metronom_stop_clock(metronom_clock_t *this) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t **r; int i; pthread_mutex_lock (&this_priv->mct.lock); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) (*r)->set_fine_speed (*r, XINE_SPEED_PAUSE); for (i = 0; this_priv->speed_change_callbacks[i]; i++) this_priv->speed_change_callbacks[i] (this_priv->speed_change_data[i], XINE_SPEED_PAUSE); pthread_mutex_unlock (&this_priv->mct.lock); } static void metronom_resume_clock(metronom_clock_t *this) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t **r; int i; pthread_mutex_lock (&this_priv->mct.lock); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) (*r)->set_fine_speed (*r, XINE_FINE_SPEED_NORMAL); for (i = 0; this_priv->speed_change_callbacks[i]; i++) this_priv->speed_change_callbacks[i] (this_priv->speed_change_data[i], XINE_FINE_SPEED_NORMAL); pthread_mutex_unlock (&this_priv->mct.lock); } static void metronom_adjust_clock(metronom_clock_t *this, int64_t desired_pts) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; if (this_priv->mct.scr_adjustable) this_priv->mct.scr_master->adjust (this_priv->mct.scr_master, desired_pts); if (this_priv->next_sync_pts != STOP_PTS) this_priv->next_sync_pts = (int)desired_pts & MASK_PTS; } static int metronom_set_speed (metronom_clock_t *this, int speed) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t **r; int true_speed, i; true_speed = this_priv->mct.scr_master->set_fine_speed (this_priv->mct.scr_master, speed); this_priv->mct.speed = true_speed; pthread_mutex_lock (&this_priv->mct.lock); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) (*r)->set_fine_speed (*r, true_speed); for (i = 0; this_priv->speed_change_callbacks[i]; i++) this_priv->speed_change_callbacks[i] (this_priv->speed_change_data[i], true_speed); pthread_mutex_unlock (&this_priv->mct.lock); return true_speed; } /* * metronom */ typedef struct { metronom_t metronom; /* * metronom internal stuff */ /* general */ xine_t *xine; metronom_t *master; pthread_mutex_t lock; int64_t vpts_offset; int64_t prebuffer; /* audio */ struct { int64_t pts_per_smpls; int64_t last_pts; int64_t vpts; int vpts_rmndr; /* the remainder for integer division */ int drift_step; int samples; int seek; int force_jump; int vdr_hack; } audio; /* video */ struct { int64_t last_pts; int64_t vpts; int64_t av_offset; int drift; int drift_step; int base_av_offset; int force_jump; int img_duration; int img_cpt; int mode; } video; /* subtitle */ struct { int64_t vpts; int64_t offset; } spu; /* bounce hack */ struct { int64_t diff; int64_t vpts_offs; int left_audio; int left_video; int jumped; } bounce; /* discontinuity handling */ struct { int have_video; int have_audio; int64_t last_offs; int last_type; int video_count; int audio_count; int handled_count; int num_video_waiters; int num_audio_waiters; pthread_cond_t video_reached; pthread_cond_t audio_reached; } disc; } metronom_impl_t; /* detect vdr_xineliboutput from this sequence: metronom_handle_*_discontinuity (this, DISC_STREAMSEEK, 0); metronom_set_option (this, METRONOM_PREBUFFER, 2000); metronom_set_option (this, METRONOM_PREBUFFER, 14400); apply audio jump fix after metronom_handle_*_discontinuity (this, DISC_STREAMSEEK, != 0); */ static void metronom_vdr_hack_disc (metronom_impl_t *this, int64_t pts_offs) { if (pts_offs == 0) { this->audio.vdr_hack = 0; } else { this->audio.seek = (this->audio.vdr_hack == 2); } } static void metronom_vdr_hack_prebuffer (metronom_impl_t *this, int64_t pts) { if (pts == 2000) { this->audio.vdr_hack = (this->audio.vdr_hack == 0) ? 1 : 0; } else if (pts == 14400) { this->audio.vdr_hack = (this->audio.vdr_hack == 1) || (this->audio.vdr_hack == 2) ? 2 : 0; } } static void metronom_set_audio_rate (metronom_t *this_gen, int64_t pts_per_smpls) { metronom_impl_t *this = (metronom_impl_t *)this_gen; pthread_mutex_lock (&this->lock); this->audio.pts_per_smpls = pts_per_smpls; pthread_mutex_unlock (&this->lock); lprintf("%" PRId64 " pts per %d samples\n", pts_per_smpls, AUDIO_SAMPLE_NUM); } static int64_t metronom_got_spu_packet (metronom_t *this_gen, int64_t pts) { metronom_impl_t *this = (metronom_impl_t *)this_gen; int64_t vpts, now; pthread_mutex_lock (&this->lock); now = this->xine->clock->get_current_time (this->xine->clock); if (this->master) { this->master->set_option (this->master, METRONOM_LOCK, 1); this->vpts_offset = this->master->get_option (this->master, METRONOM_VPTS_OFFSET | METRONOM_NO_LOCK); this->spu.offset = this->master->get_option (this->master, METRONOM_SPU_OFFSET | METRONOM_NO_LOCK); this->master->set_option (this->master, METRONOM_LOCK, 0); vpts = pts + this->vpts_offset; } else { /* bounce compensation */ int64_t vpts1 = pts + this->vpts_offset, vpts2 = vpts1 + this->bounce.diff; int64_t d1 = vpts1 - now, d2 = vpts2 - now; if (d1 < 0) d1 = -d1; if (d2 < 0) d2 = -d2; vpts = d1 < d2 ? vpts1 : vpts2; } /* reset bogus vaöues */ if ((vpts < now) || (vpts > now + 15 * 90000)) vpts = now; /* apply user shift */ vpts += this->spu.offset; /* NOTE: vpts here may jitter backwards a bit (depending on spu codec). * overlay.c will sort this away later. */ this->spu.vpts = vpts; pthread_mutex_unlock (&this->lock); return vpts; } /* There are 3 stages of discontinuity handling: * 1. At demux time (entering fifo): * If pts jumps more than 2 seconds, insert a discontinuity control buf. * 2. At metronom_handle_foo_discontinuity () time (leaving fifo): * Wait for both fifos to reach this, then bump vpts offset. * 3. At metronom_got_bar () time (after decoding): * Apply vpts to output buf. * * Issue: Not all decoders work straight forward. Many video decoders * delay and reorder their output. We could defer discontinuity handling * to stage 3, but decoder may swallow frames due to errors. * * Issue: mpeg style cotainers may jump during reorder, and pts will * bounce some 20 times. Lets detect these, and try to stay calm. * Workaround: at 2, remember previous setting, and swap with it when * appropriate. This reduces timeline drift. At 3, do accept a few * frames from both settings. * * Issue: Audio frames are often small (< 500 bytes). Putting 1 such * frame into mpeg-ts packets (188 bytes) will waste a lot of space. * Thats why they usually take 0.5 .. 1 seconds at once, and all video * frames for the same time need to be sent before. That normal * discontinuity wait will then outdate some audio, and yield a gap of * silence. * Workaround: Use the bounce hack above to handle most absolute * discontinuities without wait. * * Note: BOUNCE_MAX needs to be at least demux_ts:WRAP_THRESHOLD (360000). * This makes sure that no jump turns into a huge gap. */ #define BOUNCE_MAX 360000 static int metronom_handle_discontinuity (metronom_impl_t *this, int type, int try, int64_t disc_off) { int64_t cur_time; /* video.vpts and audio.vpts adjustements */ cur_time = this->xine->clock->get_current_time(this->xine->clock); switch (type) { /* When switching streams gaplessly, a paradox situation may happen: * Engine was very fast and filled output buffers with more than * this->prebuffer of yet to be played frames from the end of previous * stream. The DISC_STREAMSTART code below will then set back vpts * a few frames, and the engine will drop them later. * We could try to fix this by increasing this->prebuffer, but that * would cumulate over large playlists, and finally blow out queue * sizes. * Instead, we wait here a bit. */ case DISC_GAPLESS: { int64_t t; int speed = this->xine->clock->speed; if (speed <= 0) return 0; pthread_mutex_lock (&this->lock); t = this->video.vpts > this->audio.vpts ? this->video.vpts : this->audio.vpts; t -= this->prebuffer + cur_time; pthread_mutex_unlock (&this->lock); if ((t <= 0) || (t > 135000)) return 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: gapless switch: wait %u pts.\n", (unsigned int)t); /* XINE_FINE_SPEED_NORMAL == 1000000; 1000000 * 1000 / 90 == 100000000 / 9; */ xine_usec_sleep (xine_uint_mul_div (t, 100000000, speed * 9)); } return 0; case DISC_STREAMSTART: lprintf ("DISC_STREAMSTART\n"); disc_off = 0; /* fall through */ case DISC_STREAMSEEK: lprintf ("DISC_STREAMSEEK\n"); this->video.vpts = this->prebuffer + cur_time; this->audio.vpts = this->video.vpts; this->vpts_offset = this->video.vpts - disc_off; this->bounce.left_audio = -1; this->bounce.left_video = -1; this->bounce.jumped = 0; this->audio.vpts_rmndr = 0; this->audio.force_jump = 1; this->video.force_jump = 1; this->video.drift = 0; this->video.last_pts = 0; this->audio.last_pts = 0; metronom_vdr_hack_disc (this, disc_off); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: vpts adjusted with prebuffer to %" PRId64 ".\n", this->video.vpts); lprintf("video.vpts: %" PRId64 ", audio.vpts: %" PRId64 "\n", this->video.vpts, this->audio.vpts); return 0; case DISC_ABSOLUTE: { int64_t d, video_vpts, vpts_offset; int mode; lprintf ("DISC_ABSOLUTE\n"); this->audio.seek = 0; /* calculate but dont set yet */ mode = ((this->video.vpts < cur_time) << 1) | (this->audio.vpts < cur_time); video_vpts = (mode == 3) ? this->prebuffer + cur_time : (mode == 2) ? this->audio.vpts : this->video.vpts; vpts_offset = video_vpts - disc_off; /* where are we? */ d = vpts_offset - this->vpts_offset; if (d < 0) d = -d; if (d < BOUNCE_MAX) { /* small step, keep old previous. */ ; } else { /* big step. */ d = vpts_offset - this->bounce.vpts_offs; if (d < 0) d = -d; if (d < BOUNCE_MAX) { /* near old previous, swap with it. */ d = this->vpts_offset; this->vpts_offset = this->bounce.vpts_offs; this->bounce.vpts_offs = d; d -= this->vpts_offset; this->bounce.diff = d; this->bounce.left_audio = BOUNCE_MAX; this->bounce.left_video = BOUNCE_MAX; this->audio.last_pts = 0; this->video.last_pts = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: pts bounce by %" PRId64 ".\n", d); return 0; } if (try && (this->bounce.left_audio >= 0)) return 1; /* remember current as prev, and set new. */ this->bounce.vpts_offs = this->vpts_offset; } this->vpts_offset = vpts_offset; this->bounce.diff = this->bounce.vpts_offs - vpts_offset; this->video.vpts = video_vpts; this->bounce.left_audio = BOUNCE_MAX; this->bounce.left_video = BOUNCE_MAX; this->bounce.jumped = 1; if (mode == 2) { /* still frame with audio */ xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: video vpts adjusted to audio vpts %" PRId64 ".\n", this->video.vpts); } else if (mode == 3) { /* still frame, no audio */ this->audio.vpts = video_vpts; this->audio.vpts_rmndr = 0; this->video.force_jump = 1; this->audio.force_jump = 1; this->video.drift = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: vpts adjusted with prebuffer to %" PRId64 ".\n", this->video.vpts); } else if (mode == 1) { /* video, no sound */ this->audio.vpts = video_vpts; this->audio.vpts_rmndr = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: audio vpts adjusted to video vpts %" PRId64 ".\n", this->video.vpts); } } this->video.last_pts = 0; this->audio.last_pts = 0; lprintf ("video.vpts: %" PRId64 ", audio.vpts: %" PRId64 "\n", this->video.vpts, this->audio.vpts); return 0; case DISC_RELATIVE: lprintf ("DISC_RELATIVE\n"); if (this->video.vpts < cur_time) { /* still frame */ if (this->audio.vpts > cur_time) { /* still frame with audio */ this->video.vpts = this->audio.vpts; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: video vpts adjusted to audio vpts %" PRId64 ".\n", this->video.vpts); } else { /* still frame, no audio */ this->video.vpts = this->prebuffer + cur_time; this->audio.vpts = this->video.vpts; this->audio.vpts_rmndr = 0; this->video.force_jump = 1; this->audio.force_jump = 1; this->video.drift = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: vpts adjusted with prebuffer to %" PRId64 ".\n", this->video.vpts); } } else { /* video */ if (this->audio.vpts < cur_time) { /* video, no sound */ this->audio.vpts = this->video.vpts; this->audio.vpts_rmndr = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: audio vpts adjusted to video vpts %" PRId64 ".\n", this->video.vpts); } else { /* video + audio */ } } this->vpts_offset = this->vpts_offset - disc_off; this->video.last_pts = 0; this->audio.last_pts = 0; lprintf ("video.vpts: %" PRId64 ", audio.vpts: %" PRId64 "\n", this->video.vpts, this->audio.vpts); return 0; default: return 0; } } static void metronom_handle_vdr_trick_pts (metronom_impl_t *this, int64_t pts) { int64_t cur_time = this->xine->clock->get_current_time (this->xine->clock); if (this->video.vpts < cur_time) { if (this->audio.vpts >= cur_time) { /* still frame with audio */ this->video.vpts = this->audio.vpts; } else { /* still frame, no audio */ this->audio.vpts = this->video.vpts = this->prebuffer + cur_time; this->audio.vpts_rmndr = 0; this->video.force_jump = 1; this->audio.force_jump = 1; this->video.drift = 0; } } else { if (this->audio.vpts < cur_time) { /* video, no sound */ this->audio.vpts = this->video.vpts; this->audio.vpts_rmndr = 0; } } this->vpts_offset = this->video.vpts - pts; this->bounce.diff = this->bounce.vpts_offs - this->vpts_offset; this->bounce.left_audio = -1; this->bounce.left_video = -1; this->bounce.jumped = 0; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: vdr trick pts %" PRId64 ", vpts %" PRId64 ".\n", pts, this->video.vpts); } static void metronom_handle_video_discontinuity (metronom_t *this_gen, int type, int64_t disc_off) { metronom_impl_t *this = (metronom_impl_t *)this_gen; int waited; if (type == DISC_GAPLESS) { /* this would cause deadlock in metronom_handle_discontinuity() because of double pthread_mutex_lock(&this->lock) */ _x_assert(type != DISC_GAPLESS); return; } pthread_mutex_lock (&this->lock); if (this->master) { /* slaves are currently not allowed to set discontinuities */ pthread_mutex_unlock(&this->lock); return; } this->disc.video_count++; if (this->disc.num_video_waiters && (this->disc.audio_count <= this->disc.video_count)) pthread_cond_signal (&this->disc.video_reached); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: video discontinuity #%d, type is %d, disc_off %" PRId64 ".\n", this->disc.video_count, type, disc_off); if (this->disc.video_count <= this->disc.handled_count) { pthread_mutex_unlock (&this->lock); return; } if (type == DISC_ABSOLUTE) { if (!metronom_handle_discontinuity (this, type, 1, disc_off)) { this->disc.handled_count = this->disc.video_count; pthread_mutex_unlock (&this->lock); return; } } /* If both audio and video are there, the video side shall take * effect. Previous code did this by letting audio wait even if * video came first. Lets drop that unnecessary wait, and pass * over params instead. */ this->disc.last_type = type; this->disc.last_offs = disc_off; waited = 0; if (this->disc.have_audio) { while (this->disc.audio_count < this->disc.video_count) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: waiting for audio discontinuity #%d...\n", this->disc.video_count); this->disc.num_audio_waiters++; pthread_cond_wait (&this->disc.audio_reached, &this->lock); this->disc.num_audio_waiters--; waited = 1; } } if (!waited) { metronom_handle_discontinuity (this, type, 0, disc_off); this->disc.handled_count++; } pthread_mutex_unlock (&this->lock); } static void metronom_got_video_frame (metronom_t *this_gen, vo_frame_t *img) { metronom_impl_t *this = (metronom_impl_t *)this_gen; int64_t pts = img->pts; pthread_mutex_lock (&this->lock); if (this->master) { this->master->set_option(this->master, METRONOM_LOCK, 1); if (!this->disc.handled_count) { /* we are not initialized yet */ this->video.vpts = this->audio.vpts = this->master->get_option(this->master, METRONOM_VPTS | METRONOM_NO_LOCK); /* when being attached to the first master, do not drift into * his vpts values but adopt at once */ this->audio.force_jump = 1; this->video.force_jump = 1; this->disc.handled_count++; } this->vpts_offset = this->master->get_option(this->master, METRONOM_VPTS_OFFSET | METRONOM_NO_LOCK); this->video.av_offset = this->master->get_option(this->master, METRONOM_AV_OFFSET | METRONOM_NO_LOCK); } lprintf("got_video_frame pts = %" PRId64 ", duration = %d\n", pts, img->duration); this->video.img_cpt++; /* 1000 fps usually means unknown or variable frame rate */ if (img->duration > 90) { this->video.mode = VIDEO_PREDICTION_MODE; this->video.img_duration = img->duration; } else { /* will skip the whole predicted vpts stuff */ this->video.mode = VIDEO_PTS_MODE; } /* goom likes to deliver all zero pts sometimes. Give a chance to follow at least sound card drift */ if (!pts && img->duration && !(this->video.img_cpt & 0x7f)) pts = this->video.last_pts + this->video.img_cpt * img->duration; if (pts && pts != this->video.last_pts) { if (!img->duration) { /* Compute the duration of previous frames using this formula: * duration = (curent_pts - last_pts) / (frame count between the 2 pts) * This duration will be used to predict the next frame vpts. */ if (this->video.last_pts && this->video.img_cpt) { this->video.img_duration = (pts - this->video.last_pts) / this->video.img_cpt; lprintf("computed frame_duration = %d\n", this->video.img_duration ); } } this->video.img_cpt = 0; this->video.last_pts = pts; /* * compare predicted (this->video.vpts) and given (pts+vpts_offset) * pts values - hopefully they will be the same * if not, for small diffs try to interpolate * for big diffs: jump */ pts += this->vpts_offset; if (this->bounce.left_video >= 0) { int64_t diff = this->video.vpts - pts; if ((abs (diff) > BOUNCE_MAX) && (abs (diff - this->bounce.diff) < BOUNCE_MAX)) { pts += this->bounce.diff; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: bounced video frame with pts %" PRId64 ".\n", img->pts); } this->bounce.left_video -= img->duration; if (this->bounce.left_video < 0) { this->bounce.left_audio = -1; this->bounce.left_video = -1; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: leaving bounce area at pts %" PRId64 ".\n", img->pts); } } if (this->video.mode == VIDEO_PREDICTION_MODE) { int64_t diff = this->video.vpts - pts; lprintf("video diff is %" PRId64 " (predicted %" PRId64 ", given %" PRId64 ")\n", diff, this->video.vpts, pts); if ((abs (diff) > VIDEO_DRIFT_TOLERANCE) || (this->video.force_jump)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: video jump by %"PRId64" pts.\n", -diff); this->video.force_jump = 0; this->video.vpts = pts; this->video.drift = 0; this->video.drift_step = 0; } else { /* TJ. Drift into new value over the next 32 frames. * Dont fall into the asymptote trap of bringing down step with remaining drift. * BTW. video.drift* merely uses 17 bits. */ this->video.drift = diff; if (diff < 0) { int step = ((int)diff - 31) >> 5; if (this->video.drift_step > step) this->video.drift_step = step; else if (this->video.drift_step < (int)diff) this->video.drift_step = diff; } else { int step = ((int)diff + 31) >> 5; if (this->video.drift_step < step) this->video.drift_step = step; else if (this->video.drift_step > (int)diff) this->video.drift_step = diff; } } } else { /* VIDEO_PTS_MODE: do not use the predicted value */ this->video.vpts = pts; this->video.drift = 0; this->video.drift_step = 0; } } img->vpts = this->video.vpts + this->video.av_offset + this->video.base_av_offset; /* We need to update this->video.vpts is both modes. * this->video.vpts is used as the next frame vpts if next frame pts=0 */ this->video.vpts += this->video.img_duration - this->video.drift_step; if (this->video.mode == VIDEO_PREDICTION_MODE) { lprintf("video vpts for %10"PRId64" : %10"PRId64" (duration:%d drift:%d step:%d)\n", img->pts, this->video.vpts, img->duration, this->video.drift, this->video.drift_step ); /* reset drift compensation if work is done after this frame */ if (this->video.drift_step < 0) { this->video.drift -= this->video.drift_step; if (this->video.drift >= 0) { this->video.drift = 0; this->video.drift_step = 0; } } else if (this->video.drift_step > 0) { this->video.drift -= this->video.drift_step; if (this->video.drift <= 0) { this->video.drift = 0; this->video.drift_step = 0; } } } if (this->master) { this->master->set_option(this->master, METRONOM_LOCK, 0); } pthread_mutex_unlock (&this->lock); if (this->xine->verbosity == XINE_VERBOSITY_DEBUG + 1) xprintf (this->xine, XINE_VERBOSITY_DEBUG + 1, "metronom: video pts: %"PRId64":%04d -> %"PRId64".\n", img->pts, (int)img->duration, img->vpts); } static void metronom_handle_audio_discontinuity (metronom_t *this_gen, int type, int64_t disc_off) { metronom_impl_t *this = (metronom_impl_t *)this_gen; int waited; if (type == DISC_GAPLESS) { metronom_handle_discontinuity (this, type, 0, disc_off); return; } pthread_mutex_lock (&this->lock); if (this->master) { /* slaves are currently not allowed to set discontinuities */ pthread_mutex_unlock(&this->lock); return; } this->disc.audio_count++; if (this->disc.num_audio_waiters && (this->disc.audio_count >= this->disc.video_count)) pthread_cond_signal (&this->disc.audio_reached); xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: audio discontinuity #%d, type is %d, disc_off %" PRId64 ".\n", this->disc.audio_count, type, disc_off); if (this->disc.audio_count <= this->disc.handled_count) { pthread_mutex_unlock (&this->lock); return; } if (type == DISC_ABSOLUTE) { if (!metronom_handle_discontinuity (this, type, 1, disc_off)) { this->disc.handled_count = this->disc.audio_count; pthread_mutex_unlock (&this->lock); return; } } waited = 0; if (this->disc.have_video) { while ( this->disc.audio_count > this->disc.video_count ) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: waiting for video discontinuity #%d...\n", this->disc.audio_count); this->disc.num_video_waiters++; pthread_cond_wait (&this->disc.video_reached, &this->lock); this->disc.num_video_waiters--; waited = 1; } } else { this->disc.last_type = type; this->disc.last_offs = disc_off; } if (!waited) { metronom_handle_discontinuity (this, this->disc.last_type, 0, this->disc.last_offs); this->disc.handled_count++; } this->audio.samples = 0; this->audio.drift_step = 0; pthread_mutex_unlock (&this->lock); } static int64_t metronom_got_audio_samples (metronom_t *this_gen, int64_t pts, int nsamples) { metronom_impl_t *this = (metronom_impl_t *)this_gen; int64_t vpts; lprintf("got %d audio samples, pts is %" PRId64 ", last pts = %" PRId64 "\n", nsamples, pts, this->audio.last_pts); lprintf("AUDIO pts from last= %" PRId64 "\n", pts-this->audio.last_pts); pthread_mutex_lock (&this->lock); if (this->master) { this->master->set_option(this->master, METRONOM_LOCK, 1); if (!this->disc.handled_count) { /* we are not initialized yet */ this->video.vpts = this->audio.vpts = this->master->get_option(this->master, METRONOM_VPTS | METRONOM_NO_LOCK); this->audio.vpts_rmndr = 0; /* when being attached to the first master, do not drift into * his vpts values but adopt at once */ this->audio.force_jump = 1; this->video.force_jump = 1; this->disc.handled_count++; } this->vpts_offset = this->master->get_option(this->master, METRONOM_VPTS_OFFSET | METRONOM_NO_LOCK); } if (pts && pts != this->audio.last_pts) { int64_t diff; this->audio.last_pts = pts; vpts = pts + this->vpts_offset; diff = this->audio.vpts - vpts; /* Attempt to fix that mpeg-ts "video ahead of audio" issue with vdr-libxineoutput. */ if (this->audio.seek) { this->audio.seek = 0; if ((diff > 0) && (diff < 220000)) { vpts += diff; this->vpts_offset += diff; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: fixing seek jump by %d pts.\n", (int)diff); diff = 0; } } if (this->bounce.left_audio >= 0) { if ((abs (diff) > BOUNCE_MAX) && (abs (diff - this->bounce.diff) < BOUNCE_MAX)) { vpts += this->bounce.diff; diff = this->audio.vpts - vpts; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: bounced audio buffer with pts %" PRId64 ".\n", pts); } this->bounce.left_audio -= (nsamples * this->audio.pts_per_smpls) >> AUDIO_SAMPLE_LD; if (this->bounce.left_audio < 0) { this->bounce.left_audio = -1; this->bounce.left_video = -1; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: leaving bounce area at pts %" PRId64 ".\n", pts); } if (this->bounce.jumped) { if ((diff > 0) /* && (diff < BOUNCE_MAX) */) { vpts += diff; this->vpts_offset += diff; this->bounce.diff = this->bounce.vpts_offs - this->vpts_offset; xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: fixing discontinuity jump by %" PRId64 " pts.\n", diff); diff = 0; } } } /* compare predicted and given vpts */ if((abs(diff) > AUDIO_DRIFT_TOLERANCE) || (this->audio.force_jump)) { xprintf (this->xine, XINE_VERBOSITY_DEBUG, "metronom: audio jump by %" PRId64 " pts.\n", -diff); this->audio.force_jump = 0; this->audio.vpts = vpts; this->audio.vpts_rmndr = 0; this->audio.drift_step = 0; } else { if( this->audio.samples ) { /* calculate drift_step to recover vpts errors */ int d = diff, m; lprintf ("audio diff = %d\n", d); d *= AUDIO_SAMPLE_NUM / 4; d /= (int)this->audio.samples; /* drift_step is not allowed to change rate by more than 25% */ m = (int)this->audio.pts_per_smpls >> 2; if (d > m) d = m; else if (d < -m) d = -m; this->audio.drift_step = d; lprintf ("audio_drift = %d, audio.pts_per_smpls = %" PRId64 "\n", d, this->audio.pts_per_smpls); } } this->audio.samples = 0; } vpts = this->audio.vpts; /* drift here is caused by streams where nominal sample rate differs from * the rate of which pts increments. fixing the audio.vpts won't do us any * good because sound card won't play it faster or slower just because * we want. however, adding the error to the vpts_offset will force video * to change it's frame rate to keep in sync with us. * * Since we are using integer division below, it can happen that we lose * precision for the calculated duration in vpts for each audio buffer * (< 1 PTS, e.g. 0.25 PTS during playback of most DVDs with LPCM audio). * This would lead to a situation where the sound card actually needs * more time to play back the buffers, than the audio buffer's vpts field * indicates. This makes audio_out loop think we are in sync with the * soundcard, while we actually are not. So that's why there is the extra * modulo calculation, to keep track of the truncated, fractional part. * However, this is but a nice try after all because * 1. "pts per 2^15 samples" itself has a similar size rounding error. * 2. System and sound card clocks are unprecise independently. * 3. System clock is not an exact multiple of sample rate. * So let audio out help us fixing this through occasional feedback there :-) */ this->audio.vpts_rmndr += (nsamples * this->audio.pts_per_smpls) & AUDIO_SAMPLE_MASK; this->audio.vpts += (nsamples * this->audio.pts_per_smpls) >> AUDIO_SAMPLE_LD; if (this->audio.vpts_rmndr >= AUDIO_SAMPLE_NUM) { this->audio.vpts += 1; this->audio.vpts_rmndr -= AUDIO_SAMPLE_NUM; } this->audio.samples += nsamples; this->vpts_offset += (nsamples * this->audio.drift_step) >> AUDIO_SAMPLE_LD; if (this->master) { this->master->set_option(this->master, METRONOM_LOCK, 0); } pthread_mutex_unlock (&this->lock); lprintf ("audio vpts for %10"PRId64" : %10"PRId64"\n", pts, vpts); return vpts; } static void metronom_set_option (metronom_t *this_gen, int option, int64_t value) { metronom_impl_t *this = (metronom_impl_t *)this_gen; if (option == METRONOM_LOCK) { if (value) { pthread_mutex_lock (&this->lock); if (this->master) this->master->set_option(this->master, option, value); } else { if (this->master) this->master->set_option(this->master, option, value); pthread_mutex_unlock (&this->lock); } return; } pthread_mutex_lock (&this->lock); if (this->master) { /* pass the option on to the master */ this->master->set_option(this->master, option, value); pthread_mutex_unlock(&this->lock); return; } switch (option) { case METRONOM_AV_OFFSET: this->video.av_offset = value; xprintf (this->xine, XINE_VERBOSITY_LOG, "metronom: video.av_offset=%" PRId64 " pts.\n", this->video.av_offset); break; case METRONOM_SPU_OFFSET: this->spu.offset = value; xprintf (this->xine, XINE_VERBOSITY_LOG, "metronom: spu.offset=%" PRId64 " pts.\n", this->spu.offset); break; case METRONOM_ADJ_VPTS_OFFSET: this->audio.vpts += value; this->audio.vpts_rmndr = 0; /* that message should be rare, please report otherwise. * when xine is in some sort of "steady state" hearing it * once in a while means a small sound card drift (or system * clock drift -- who knows?). nothing to worry about. */ xprintf (this->xine, XINE_VERBOSITY_LOG, "metronom: fixing sound card drift by %" PRId64 " pts.\n", value); break; case METRONOM_PREBUFFER: this->prebuffer = value; metronom_vdr_hack_prebuffer (this, value); xprintf (this->xine, XINE_VERBOSITY_LOG, "metronom: prebuffer=%" PRId64 " pts.\n", this->prebuffer); break; case METRONOM_VDR_TRICK_PTS: metronom_handle_vdr_trick_pts (this, value); break; default: xprintf(this->xine, XINE_VERBOSITY_NONE, "metronom: unknown option in set_option: %d.\n", option); } pthread_mutex_unlock (&this->lock); } static void metronom_clock_set_option (metronom_clock_t *this, int option, int64_t value) { pthread_mutex_lock (&this->lock); switch (option) { case CLOCK_SCR_ADJUSTABLE: this->scr_adjustable = value; break; default: xprintf (this->xine, XINE_VERBOSITY_NONE, "metronom: unknown option in set_option: %d.\n", option); } pthread_mutex_unlock (&this->lock); } static int64_t metronom_get_option (metronom_t *this_gen, int option) { metronom_impl_t *this = (metronom_impl_t *)this_gen; int64_t result; int mutex_locked; if (option & METRONOM_NO_LOCK) { mutex_locked = 0; } else { pthread_mutex_lock (&this->lock); mutex_locked = 1; } if (this->master) { result = this->master->get_option(this->master, option); if (mutex_locked) pthread_mutex_unlock (&this->lock); return result; } option &= ~METRONOM_NO_LOCK; switch (option) { case METRONOM_AV_OFFSET: result = this->video.av_offset; break; case METRONOM_SPU_OFFSET: result = this->spu.offset; break; case METRONOM_FRAME_DURATION: result = this->video.img_duration; break; case METRONOM_VPTS_OFFSET: result = this->vpts_offset; break; case METRONOM_PREBUFFER: result = this->prebuffer; break; case METRONOM_VPTS: if (this->video.vpts > this->audio.vpts) result = this->video.vpts; else result = this->audio.vpts; break; case METRONOM_WAITING: result = (this->disc.num_audio_waiters ? 1 : 0) | (this->disc.num_video_waiters ? 2 : 0); break; case METRONOM_VDR_TRICK_PTS: result = this->video.vpts; break; default: result = 0; xprintf (this->xine, XINE_VERBOSITY_NONE, "metronom: unknown option in get_option: %d.\n", option); break; } if (mutex_locked) { pthread_mutex_unlock (&this->lock); } return result; } static int64_t metronom_clock_get_option (metronom_clock_t *this, int option) { switch (option) { case CLOCK_SCR_ADJUSTABLE: return this->scr_adjustable; } xprintf (this->xine, XINE_VERBOSITY_NONE, "metronom: unknown option in get_option: %d.\n", option); return 0; } static void metronom_set_master(metronom_t *this_gen, metronom_t *master) { metronom_impl_t *this = (metronom_impl_t *)this_gen; metronom_t *old_master = this->master; pthread_mutex_lock(&this->lock); /* someone might currently be copying values from the old master, * so we need his lock too */ if (old_master) old_master->set_option(old_master, METRONOM_LOCK, 1); this->master = master; /* new master -> we have to reinit */ this->disc.handled_count = 0; if (old_master) old_master->set_option(old_master, METRONOM_LOCK, 0); pthread_mutex_unlock(&this->lock); } static scr_plugin_t* get_master_scr(metronom_clock_t *this) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t *found = NULL, **r; int maxprio = 0; /* find the SCR provider with the highest priority */ for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) { int p = (*r)->get_priority (*r); if (maxprio < p) { found = *r; maxprio = p; } } if (!found) { xprintf (this_priv->mct.xine, XINE_VERBOSITY_NONE, "metronom: panic - no scr provider found!\n"); return NULL; } return found; } static void *metronom_sync_loop (void *const this_gen) { metronom_clock_private_t *const this_priv = (metronom_clock_private_t *const)this_gen; struct timespec ts = {0, 0}; scr_plugin_t **r; int64_t pts; while (this_priv->mct.thread_running) { /* synchronise every 5 seconds */ pthread_mutex_lock (&this_priv->mct.lock); pts = this_priv->mct.scr_master->get_current (this_priv->mct.scr_master); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) if (*r != this_priv->mct.scr_master) (*r)->adjust (*r, pts); xine_gettime (&ts); ts.tv_sec += 5; pthread_cond_timedwait (&this_priv->mct.cancel, &this_priv->mct.lock, &ts); pthread_mutex_unlock (&this_priv->mct.lock); } return NULL; } static void metronom_start_sync_thread (metronom_clock_private_t *this_priv) { int err; if (this_priv->sync_thread_state == SYNC_THREAD_NONE) { this_priv->next_sync_pts = START_PTS; return; } if (this_priv->sync_thread_state != SYNC_THREAD_OFF) return; pthread_cond_init (&this_priv->mct.cancel, NULL); this_priv->mct.thread_running = 1; err = pthread_create (&this_priv->mct.sync_thread, NULL, metronom_sync_loop, &this_priv->mct); if (err) { xprintf (this_priv->mct.xine, XINE_VERBOSITY_NONE, "metronom: cannot create sync thread (%s).\n", strerror (err)); this_priv->next_sync_pts = START_PTS; } else { this_priv->sync_thread_state = SYNC_THREAD_RUNNING; this_priv->next_sync_pts = STOP_PTS; } } static void metronom_stop_sync_thread (metronom_clock_private_t *this_priv) { if (this_priv->sync_thread_state == SYNC_THREAD_NONE) { this_priv->next_sync_pts = STOP_PTS; return; } if (this_priv->sync_thread_state != SYNC_THREAD_RUNNING) return; this_priv->mct.thread_running = 0; pthread_mutex_lock (&this_priv->mct.lock); pthread_cond_signal (&this_priv->mct.cancel); pthread_mutex_unlock (&this_priv->mct.lock); pthread_join (this_priv->mct.sync_thread, NULL); pthread_cond_destroy (&this_priv->mct.cancel); this_priv->sync_thread_state = SYNC_THREAD_OFF; this_priv->next_sync_pts = STOP_PTS; } static int metronom_register_scr (metronom_clock_t *this, scr_plugin_t *scr) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t **r; if (scr->interface_version != 3) { xprintf (this->xine, XINE_VERBOSITY_NONE, "metronom: wrong interface version for scr provider!\n"); return -1; } if (this_priv->providers[0] && !this_priv->providers[1]) metronom_start_sync_thread (this_priv); pthread_mutex_lock (&this_priv->mct.lock); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) ; if (r >= this_priv->providers + MAX_SCR_PROVIDERS) { pthread_mutex_unlock (&this_priv->mct.lock); return -1; /* No free slot available */ } scr->clock = &this_priv->mct; *r = scr; this_priv->mct.scr_master = get_master_scr (&this_priv->mct); pthread_mutex_unlock (&this_priv->mct.lock); return 0; } static void metronom_unregister_scr (metronom_clock_t *this, scr_plugin_t *scr) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t **found = NULL, **r; int64_t now; if (!scr) return; pthread_mutex_lock (&this_priv->mct.lock); /* never unregister scr_list[0]! */ for (r = this_priv->providers + 1; *r && r < this_priv->providers + MAX_SCR_PROVIDERS; r++) { if (*r == scr) found = r; } if (!found) { pthread_mutex_unlock (&this_priv->mct.lock); return; /* Not found */ } /* avoid holes in list */ found[0] = r[-1]; r[-1] = NULL; now = this_priv->mct.scr_master->get_current (this_priv->mct.scr_master); /* master could have been adjusted, others must follow now */ for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) if (*r != this_priv->mct.scr_master) (*r)->adjust (*r, now); this_priv->mct.scr_master = get_master_scr (&this_priv->mct); pthread_mutex_unlock (&this_priv->mct.lock); if (this_priv->providers[0] && !this_priv->providers[1]) metronom_stop_sync_thread (this_priv); } static void metronom_exit (metronom_t *this_gen) { metronom_impl_t *this = (metronom_impl_t *)this_gen; this->xine->config->unregister_callbacks (this->xine->config, NULL, NULL, this, sizeof (*this)); pthread_mutex_destroy (&this->lock); pthread_cond_destroy (&this->disc.video_reached); pthread_cond_destroy (&this->disc.audio_reached); free (this); } static void metronom_clock_exit (metronom_clock_t *this) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this; scr_plugin_t **r; this_priv->mct.xine->config->unregister_callbacks (this_priv->mct.xine->config, NULL, NULL, this_priv, sizeof (*this_priv)); metronom_stop_sync_thread (this_priv); pthread_mutex_lock (&this_priv->mct.lock); for (r = this_priv->providers; *r && (r < this_priv->providers + MAX_SCR_PROVIDERS); r++) (*r)->exit (*r); pthread_mutex_unlock (&this_priv->mct.lock); pthread_mutex_destroy (&this_priv->mct.lock); free (this_priv); } static void metronom_base_av_offs_hook (void *this_gen, xine_cfg_entry_t *entry) { metronom_impl_t *this = (metronom_impl_t *)this_gen; this->video.base_av_offset = entry->num_value; } metronom_t * _x_metronom_init (int have_video, int have_audio, xine_t *xine) { metronom_impl_t *this = calloc(1, sizeof (metronom_impl_t)); if (!this) return NULL; #ifndef HAVE_ZERO_SAFE_MEM /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ this->master = NULL; this->vpts_offset = 0; this->audio.pts_per_smpls = 0; this->audio.last_pts = 0; this->audio.vpts_rmndr = 0; this->audio.vdr_hack = 0; this->audio.seek = 0; this->audio.samples = 0; this->audio.drift_step = 0; this->audio.force_jump = 0; this->video.last_pts = 0; this->video.av_offset = 0; this->video.drift = 0; this->video.drift_step = 0; this->video.img_cpt = 0; this->video.force_jump = 0; this->video.img_duration = 0; this->video.mode = 0; this->spu.vpts = 0; this->spu.offset = 0; this->bounce.diff = 0; this->bounce.vpts_offs = 0; this->bounce.jumped = 0; this->disc.video_count = 0; this->disc.handled_count = 0; this->disc.audio_count = 0; this->disc.num_audio_waiters = 0; this->disc.num_video_waiters = 0; this->disc.last_offs = 0; this->disc.last_type = 0; #endif this->bounce.left_audio = -1; this->bounce.left_video = -1; this->metronom.set_audio_rate = metronom_set_audio_rate; this->metronom.got_video_frame = metronom_got_video_frame; this->metronom.got_audio_samples = metronom_got_audio_samples; this->metronom.got_spu_packet = metronom_got_spu_packet; this->metronom.handle_audio_discontinuity = metronom_handle_audio_discontinuity; this->metronom.handle_video_discontinuity = metronom_handle_video_discontinuity; this->metronom.set_option = metronom_set_option; this->metronom.get_option = metronom_get_option; this->metronom.set_master = metronom_set_master; this->metronom.exit = metronom_exit; this->xine = xine; pthread_mutex_init (&this->lock, NULL); this->prebuffer = PREBUFFER_PTS_OFFSET; /* initialize video stuff */ this->disc.have_video = have_video; this->video.vpts = this->prebuffer; pthread_cond_init (&this->disc.video_reached, NULL); this->video.img_duration = 3000; /* initialize audio stuff */ this->disc.have_audio = have_audio; this->audio.vpts = this->prebuffer; pthread_cond_init (&this->disc.audio_reached, NULL); this->video.base_av_offset = xine->config->register_num (xine->config, "video.output.base_delay", 0, _("basic video to audio delay in pts"), _("Getting in sync picture and sound is a complex story.\n" "Xine will compensate for any delays it knows about.\n" "However, external hardware like flatscreens, sound systems, or simply\n" "the distance between you and the speakers may add in more.\n" "Here you can adjust video timing in steps of 1/90000 seconds manually."), 10, metronom_base_av_offs_hook, this); return &this->metronom; } static void metronom_sync_hook (void *this_gen, xine_cfg_entry_t *entry) { metronom_clock_private_t *this_priv = (metronom_clock_private_t *)this_gen; if (entry->num_value) { if (this_priv->sync_thread_state != SYNC_THREAD_NONE) return; this_priv->sync_thread_state = SYNC_THREAD_OFF; this_priv->next_sync_pts = STOP_PTS; if (this_priv->providers[1]) metronom_start_sync_thread (this_priv); } else { if (this_priv->sync_thread_state == SYNC_THREAD_NONE) return; metronom_stop_sync_thread (this_priv); this_priv->sync_thread_state = SYNC_THREAD_NONE; if (this_priv->providers[1]) this_priv->next_sync_pts = START_PTS; } } metronom_clock_t *_x_metronom_clock_init(xine_t *xine) { metronom_clock_private_t *this_priv = calloc (1, sizeof (metronom_clock_private_t)); if (!this_priv) return NULL; #ifndef HAVE_ZERO_SAFE_MEM this_priv->speed_change_used = 0; this_priv->speed_change_callbacks[0] = NULL; #endif this_priv->mct.set_option = metronom_clock_set_option; this_priv->mct.get_option = metronom_clock_get_option; this_priv->mct.start_clock = metronom_start_clock; this_priv->mct.stop_clock = metronom_stop_clock; this_priv->mct.resume_clock = metronom_resume_clock; this_priv->mct.get_current_time = metronom_get_current_time; this_priv->mct.adjust_clock = metronom_adjust_clock; this_priv->mct.set_fine_speed = metronom_set_speed; this_priv->mct.register_scr = metronom_register_scr; this_priv->mct.unregister_scr = metronom_unregister_scr; this_priv->mct.exit = metronom_clock_exit; this_priv->mct.register_speed_change_callback = metronom_register_speed_change_callback; this_priv->mct.unregister_speed_change_callback = metronom_unregister_speed_change_callback; this_priv->mct.xine = xine; this_priv->mct.scr_adjustable = 1; this_priv->mct.scr_list = this_priv->providers; pthread_mutex_init (&this_priv->mct.lock, NULL); this_priv->mct.register_scr (&this_priv->mct, unixscr_init (&this_priv->uscr)); this_priv->mct.thread_running = 0; this_priv->next_sync_pts = STOP_PTS; if (this_priv->mct.xine->config->register_bool (this_priv->mct.xine->config, "engine.use_metronom_sync_thread", 0, _("Sync multiple clocks in a separate thread"), _("Enable this when there are problems with multiple (eg application supplied) clocks."), 20, metronom_sync_hook, this_priv)) { this_priv->sync_thread_state = SYNC_THREAD_OFF; } else { this_priv->sync_thread_state = SYNC_THREAD_NONE; } return &this_priv->mct; } xine-lib-1.2/src/xine-engine/events.c0000644000175000017500000005333514647725152015342 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Event handling functions */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include "xine_private.h" #define MAX_REUSE_EVENTS 16 #define MAX_REUSE_DATA 256 typedef struct xine_event_queue_private_s xine_event_queue_private_t; typedef struct { xine_event_t e; xine_event_queue_private_t *queue; } xine_event_private_t; struct xine_event_queue_private_s { xine_event_queue_t q; xine_list_t *free_events; xine_sarray_t *select; int refs; int flush; struct timeval lasttime; int num_all; int num_alloc; int num_skip; #if (HAVE_ATOMIC_VARS > 0) /* give the "get" functions a quick fall through * for the most common "no events" case. * this is basically noise shaping. */ xine_refs_t pending; #else /* skip that mutex fallback. we already have a mutex. */ #endif pthread_t handler; struct { xine_event_private_t e; uint8_t data[MAX_REUSE_DATA]; } revents[MAX_REUSE_EVENTS]; }; xine_event_t *xine_event_get (xine_event_queue_t *queue) { xine_event_queue_private_t *q = (xine_event_queue_private_t *)queue; xine_event_t *event; xine_list_iterator_t ite; if (!q) return NULL; #if (HAVE_ATOMIC_VARS > 0) if (xine_refs_get (&q->pending) <= 1) return NULL; #endif pthread_mutex_lock (&q->q.lock); ite = NULL; event = xine_list_next_value (q->q.events, &ite); if (ite) { xine_list_remove (q->q.events, ite); #if (HAVE_ATOMIC_VARS > 0) if (xine_list_size (q->q.events) == 0) xine_refs_add (&q->pending, -1); #endif } pthread_mutex_unlock (&q->q.lock); return event; } xine_event_t *xine_event_next (xine_event_queue_t *queue, xine_event_t *prev_event) { xine_event_queue_private_t *q = (xine_event_queue_private_t *)queue; if (!q) return NULL; if (prev_event) { if (PTR_IN_RANGE (prev_event, &q->revents, sizeof (q->revents))) { pthread_mutex_lock (&q->q.lock); q->refs -= 1; xine_list_push_back (q->free_events, prev_event); } else { free (prev_event); pthread_mutex_lock (&q->q.lock); } } else { #if (HAVE_ATOMIC_VARS > 0) if (xine_refs_get (&q->pending) <= 1) return NULL; #endif pthread_mutex_lock (&q->q.lock); } { xine_list_iterator_t ite = NULL; xine_event_t *event = xine_list_next_value (q->q.events, &ite); if (ite) { xine_list_remove (q->q.events, ite); #if (HAVE_ATOMIC_VARS > 0) if (xine_list_size (q->q.events) == 0) xine_refs_add (&q->pending, -1); #endif } pthread_mutex_unlock (&q->q.lock); return event; } } static xine_event_t *xine_event_wait_locked (xine_event_queue_private_t *q) { xine_event_t *event, *first_event; xine_list_iterator_t ite, first_ite; int wait; /* wait until there is at least 1 event */ while (1) { first_ite = NULL; first_event = xine_list_next_value (q->q.events, &first_ite); if (first_ite) break; pthread_cond_wait (&q->q.new_event, &q->q.lock); } /* calm down bursting progress events pt 2: * if list has only statistics, wait for possible update or other stuff. */ event = first_event; ite = first_ite; wait = 1; do { if ((event->type != XINE_EVENT_PROGRESS) && (event->type != XINE_EVENT_NBC_STATS)) { wait = 0; break; } event = xine_list_next_value (q->q.events, &ite); } while (ite); if (wait) { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_nsec += 50000000; if (ts.tv_nsec >= 1000000000) { ts.tv_nsec -= 1000000000; ts.tv_sec += 1; } pthread_cond_timedwait (&q->q.new_event, &q->q.lock, &ts); /* paranoia ? */ while (1) { first_ite = NULL; first_event = xine_list_next_value (q->q.events, &first_ite); if (first_ite) break; pthread_cond_wait (&q->q.new_event, &q->q.lock); } } xine_list_remove (q->q.events, first_ite); #if (HAVE_ATOMIC_VARS > 0) if (xine_list_size (q->q.events) == 0) xine_refs_add (&q->pending, -1); #endif return first_event; } xine_event_t *xine_event_wait (xine_event_queue_t *queue) { xine_event_queue_private_t *q = (xine_event_queue_private_t *)queue; xine_event_t *event; pthread_mutex_lock (&q->q.lock); event = xine_event_wait_locked (q); pthread_mutex_unlock (&q->q.lock); return event; } static int xine_event_queue_unref_unlock (xine_event_queue_private_t *q) { int refs; q->refs -= 1; refs = q->refs; pthread_mutex_unlock (&q->q.lock); if (refs == 0) { #if (HAVE_ATOMIC_VARS > 0) xine_refs_sub (&q->pending, 1); #endif xine_list_delete (q->q.events); xine_list_delete (q->free_events); pthread_mutex_destroy (&q->q.lock); pthread_cond_destroy (&q->q.new_event); pthread_cond_destroy (&q->q.events_processed); if (q->select) xine_sarray_delete (q->select); free (q); } return refs; } void xine_event_free (xine_event_t *event) { /* XXX; assuming this was returned by xine_event_get () or xine_event_wait () before. */ xine_event_private_t *e = (xine_event_private_t *)event; xine_event_queue_private_t *q; if (!e) return; q = e->queue; if (!q) return; if (PTR_IN_RANGE (e, &q->revents, sizeof (q->revents))) { pthread_mutex_lock (&q->q.lock); xine_list_push_back (q->free_events, e); xine_event_queue_unref_unlock (q); } else { free (event); } } void xine_event_send (xine_stream_t *s, const xine_event_t *event) { xine_stream_private_t *stream = (xine_stream_private_t *)s, *mstream; xine_list_iterator_t ite; xine_event_queue_private_t *q; void *data; struct timeval now = {0, 0}; if (!stream || !event) return; mstream = stream->side_streams[0]; data = (event->data_length <= 0) ? NULL : event->data; gettimeofday (&now, NULL); pthread_mutex_lock (&mstream->event.lock); ite = NULL; while ((q = xine_list_next_value (mstream->event.queues, &ite))) { xine_event_private_t *new_event; /* XINE_EVENT_VDR_DISCONTINUITY: .data == NULL, .data_length == DISC_* */ if (!data) { xine_list_iterator_t it2 = NULL; pthread_mutex_lock (&q->q.lock); if (q->select) { if (xine_sarray_binary_search (q->select, (void *)(intptr_t)event->type) < 0) { q->num_all += 1; q->num_skip += 1; pthread_mutex_unlock (&q->q.lock); continue; } } new_event = xine_list_next_value (q->free_events, &it2); if (new_event) { xine_list_remove (q->free_events, it2); q->refs += 1; } else { new_event = malloc (sizeof (*new_event)); if (!new_event) { pthread_mutex_unlock (&q->q.lock); continue; } q->num_alloc += 1; } new_event->e.data = NULL; new_event->queue = q; new_event->e.type = event->type; new_event->e.data_length = event->data_length; new_event->e.stream = &stream->s; new_event->e.tv = now; q->num_all += 1; xine_list_push_back (q->q.events, new_event); #if (HAVE_ATOMIC_VARS > 0) if (xine_list_size (q->q.events) == 1) xine_refs_add (&q->pending, 1); #endif pthread_cond_signal (&q->q.new_event); pthread_mutex_unlock (&q->q.lock); continue; } /* calm down bursting progress events pt 1: * if list tail has an earlier instance, update it without signal. */ if ((event->type == XINE_EVENT_PROGRESS) || (event->type == XINE_EVENT_NBC_STATS)) { xine_event_t *e2; pthread_mutex_lock (&q->q.lock); if (q->select) { if (xine_sarray_binary_search (q->select, (void *)(intptr_t)event->type) < 0) { q->num_all += 1; q->num_skip += 1; pthread_mutex_unlock (&q->q.lock); continue; } } do { xine_list_iterator_t it2 = NULL; e2 = xine_list_prev_value (q->q.events, &it2); if (!it2) break; if (e2 && (e2->type == event->type) && e2->data) break; e2 = xine_list_prev_value (q->q.events, &it2); if (!it2) break; if (e2 && (e2->type == event->type) && e2->data) break; e2 = NULL; } while (0); if (e2) { if (event->type == XINE_EVENT_PROGRESS) { xine_progress_data_t *pd1 = data, *pd2 = e2->data; if (pd1->description && pd2->description && !strcmp (pd1->description, pd2->description)) { pd2->percent = pd1->percent; e2->tv = now; q->num_all += 1; q->num_skip += 1; pthread_mutex_unlock (&q->q.lock); continue; } } else { /* XINE_EVENT_NBC_STATS */ size_t l = event->data_length < e2->data_length ? event->data_length : e2->data_length; memcpy (e2->data, data, l); e2->tv = now; q->num_all += 1; q->num_skip += 1; pthread_mutex_unlock (&q->q.lock); continue; } } pthread_mutex_unlock (&q->q.lock); } if (event->data_length <= MAX_REUSE_DATA) { xine_list_iterator_t it2 = NULL; pthread_mutex_lock (&q->q.lock); if (q->select) { if (xine_sarray_binary_search (q->select, (void *)(intptr_t)event->type) < 0) { q->num_all += 1; q->num_skip += 1; pthread_mutex_unlock (&q->q.lock); continue; } } new_event = xine_list_next_value (q->free_events, &it2); if (new_event) { xine_list_remove (q->free_events, it2); q->refs += 1; new_event->e.data = (uint8_t *)new_event + sizeof (*new_event); xine_small_memcpy (new_event->e.data, data, event->data_length); new_event->queue = q; new_event->e.type = event->type; new_event->e.data_length = event->data_length; new_event->e.stream = &stream->s; new_event->e.tv = now; q->num_all += 1; xine_list_push_back (q->q.events, new_event); #if (HAVE_ATOMIC_VARS > 0) if (xine_list_size (q->q.events) == 1) xine_refs_add (&q->pending, 1); #endif pthread_cond_signal (&q->q.new_event); pthread_mutex_unlock (&q->q.lock); continue; } pthread_mutex_unlock (&q->q.lock); } pthread_mutex_lock (&q->q.lock); if (q->select) { if (xine_sarray_binary_search (q->select, (void *)(intptr_t)event->type) < 0) { q->num_all += 1; q->num_skip += 1; pthread_mutex_unlock (&q->q.lock); continue; } } new_event = malloc (sizeof (*new_event) + event->data_length); if (!new_event) { pthread_mutex_unlock (&q->q.lock); continue; } new_event->e.data = (uint8_t *)new_event + sizeof (*new_event); memcpy (new_event->e.data, data, event->data_length); new_event->queue = q; new_event->e.type = event->type; new_event->e.data_length = event->data_length; new_event->e.stream = &stream->s; new_event->e.tv = now; q->num_all += 1; q->num_alloc += 1; xine_list_push_back (q->q.events, new_event); #if (HAVE_ATOMIC_VARS > 0) if (xine_list_size (q->q.events) == 1) xine_refs_add (&q->pending, 1); #endif pthread_cond_signal (&q->q.new_event); pthread_mutex_unlock (&q->q.lock); } pthread_mutex_unlock (&mstream->event.lock); } #if (HAVE_ATOMIC_VARS > 0) static void xine_event_dummy_cb (void *data) { (void)data; } #endif xine_event_queue_t *xine_event_new_queue (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; xine_event_queue_private_t *q; uint32_t n; if (!stream) return NULL; q = malloc (sizeof (*q)); if (!q) return NULL; q->refs = 1; q->flush = 0; q->lasttime.tv_sec = 0; q->lasttime.tv_usec = 0; q->num_all = 0; q->num_alloc = 0; q->num_skip = 0; #if (HAVE_ATOMIC_VARS > 0) xine_refs_init (&q->pending, xine_event_dummy_cb, NULL); #endif q->q.events = xine_list_new (); if (!q->q.events) { free (q); return NULL; } q->free_events = xine_list_new (); if (!q->free_events) { xine_list_delete (q->q.events); free (q); return NULL; } q->select = NULL; for (n = 0; n < MAX_REUSE_EVENTS; n++) xine_list_push_back (q->free_events, &q->revents[n]); xine_refs_add (&stream->refs, 1); pthread_mutex_init (&q->q.lock, NULL); pthread_cond_init (&q->q.new_event, NULL); pthread_cond_init (&q->q.events_processed, NULL); q->q.stream = &stream->s; q->q.listener_thread = NULL; q->q.callback_running = 0; { xine_stream_private_t *mstream = stream->side_streams[0]; pthread_mutex_lock (&mstream->event.lock); xine_list_push_back (mstream->event.queues, &q->q); pthread_mutex_unlock (&mstream->event.lock); } return &q->q; } static int xine_event_type_cmp (void *a, void *b) { int d = (intptr_t)a, e = (intptr_t)b; return (d > e) - (d < e); } void xine_event_select (xine_event_queue_t *queue, const int *types) { xine_event_queue_private_t *q = (xine_event_queue_private_t *)queue; if (!q) return; if (!types) { pthread_mutex_lock (&q->q.lock); if (q->select) { xine_sarray_delete (q->select); q->select = NULL; } pthread_mutex_unlock (&q->q.lock); } else { uint32_t n; pthread_mutex_lock (&q->q.lock); if (!q->select) { for (n = 0; types[n] != XINE_EVENT_QUIT; n++) ; q->select = xine_sarray_new (n + 1, xine_event_type_cmp); if (!q->select) { pthread_mutex_unlock (&q->q.lock); return; } xine_sarray_set_mode (q->select, XINE_SARRAY_MODE_UNIQUE); } xine_sarray_clear (q->select); n = 0; while (1) { xine_sarray_add (q->select, (void *)(intptr_t)types[n]); if (types[n] == XINE_EVENT_QUIT) break; n++; } pthread_mutex_unlock (&q->q.lock); } } void xine_event_dispose_queue (xine_event_queue_t *queue) { xine_event_queue_private_t *q = (xine_event_queue_private_t *)queue; xine_stream_private_t *stream; if (!q) return; stream = (xine_stream_private_t *)q->q.stream; { xine_stream_private_t *mstream = stream->side_streams[0]; xine_list_iterator_t ite; pthread_mutex_lock (&mstream->event.lock); ite = xine_list_find (mstream->event.queues, q); if (!ite) { pthread_mutex_unlock (&mstream->event.lock); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "events: tried to dispose queue which is not in list\n"); return; } xine_list_remove (mstream->event.queues, ite); pthread_mutex_unlock (&mstream->event.lock); } /* * send quit event */ { xine_list_iterator_t ite = NULL; xine_event_private_t *qevent; pthread_mutex_lock (&q->q.lock); qevent = xine_list_next_value (q->free_events, &ite); if (ite) { xine_list_remove (q->free_events, ite); q->refs += 1; } else { qevent = malloc (sizeof (*qevent)); q->num_alloc += 1; } if (qevent) { qevent->e.type = XINE_EVENT_QUIT; qevent->e.stream = &stream->s; qevent->e.data = NULL; qevent->e.data_length = 0; qevent->queue = q; gettimeofday (&qevent->e.tv, NULL); xine_list_push_back (q->q.events, qevent); #if (HAVE_ATOMIC_VARS > 0) if (xine_list_size (q->q.events) == 1) xine_refs_add (&q->pending, 1); #endif pthread_cond_signal (&q->q.new_event); } q->num_all += 1; pthread_mutex_unlock (&q->q.lock); } /* * join listener thread, if any */ if (q->q.listener_thread) { void *p; pthread_join (*q->q.listener_thread, &p); q->q.listener_thread = NULL; } /* * clean up pending events, unref. */ { xine_list_iterator_t ite = NULL; int num_all, num_alloc, num_skip, num_left, refs; pthread_mutex_lock (&q->q.lock); num_left = xine_list_size (q->q.events); while (1) { xine_event_t *event = xine_list_next_value (q->q.events, &ite); if (!ite) break; if (PTR_IN_RANGE (event, &q->revents, sizeof (q->revents))) { xine_list_push_back (q->free_events, event); q->refs -= 1; } else { free (event); } } xine_list_clear (q->q.events); q->flush = 0; pthread_cond_signal (&q->q.events_processed); num_all = q->num_all; num_alloc = q->num_alloc; num_skip = q->num_skip; refs = xine_event_queue_unref_unlock (q); xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "events: stream %p: %d total, %d allocated, %d skipped, %d left and dropped, %d refs.\n", (void *)stream, num_all, num_alloc, num_skip, num_left, refs); } xine_refs_sub (&stream->refs, 1); } static void *listener_loop (void *queue_gen) { xine_event_queue_private_t *q = queue_gen; int last_type; pthread_mutex_lock (&q->q.lock); do { xine_event_t *event = xine_event_wait_locked (q); q->lasttime = event->tv; q->q.callback_running = 1; pthread_mutex_unlock (&q->q.lock); last_type = event->type; q->q.callback (q->q.user_data, event); if (PTR_IN_RANGE (event, &q->revents, sizeof (q->revents))) { pthread_mutex_lock (&q->q.lock); q->refs -= 1; /* refs == 0 cannot heppen here. */ xine_list_push_back (q->free_events, event); } else { free (event); pthread_mutex_lock (&q->q.lock); } q->q.callback_running = 0; if (q->flush > 0) { q->flush -= 1; if (q->flush <= 0) pthread_cond_signal (&q->q.events_processed); } } while (last_type != XINE_EVENT_QUIT); if (q->flush > 0) { q->flush = 0; pthread_cond_signal (&q->q.events_processed); } pthread_mutex_unlock (&q->q.lock); return NULL; } int xine_event_create_listener_thread (xine_event_queue_t *queue, xine_event_listener_cb_t callback, void *user_data) { xine_event_queue_private_t *q = (xine_event_queue_private_t *)queue; int err; _x_assert(queue != NULL); _x_assert(callback != NULL); if (q->q.listener_thread) { xprintf (q->q.stream->xine, XINE_VERBOSITY_NONE, "events: listener thread already created\n"); return 0; } q->q.listener_thread = &q->handler; q->q.callback = callback; q->q.user_data = user_data; if ((err = pthread_create (q->q.listener_thread, NULL, listener_loop, q)) != 0) { xprintf (q->q.stream->xine, XINE_VERBOSITY_NONE, "events: can't create new thread (%s)\n", strerror(err)); q->q.listener_thread = NULL; q->q.callback = NULL; q->q.user_data = NULL; return 0; } return 1; } void _x_flush_events_queues (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; pthread_t self = pthread_self (); struct timespec ts = {0, 0}; struct timeval tv; if (!stream) return; stream = stream->side_streams[0]; xine_gettime (&ts); tv.tv_sec = ts.tv_sec; tv.tv_usec = ts.tv_nsec / 1000; ts.tv_sec += 1; while (1) { xine_event_queue_private_t *q; xine_list_iterator_t ite = NULL; int list_locked = 1; pthread_mutex_lock (&stream->event.lock); while ((q = xine_list_next_value (stream->event.queues, &ite))) { pthread_mutex_lock (&q->q.lock); /* never wait for self. */ if (q->q.listener_thread && !pthread_equal (self, q->handler) && (q->flush == 0)) { /* count pending past events */ if ((q->lasttime.tv_sec < tv.tv_sec) || ((q->lasttime.tv_sec == tv.tv_sec) && (q->lasttime.tv_usec <= tv.tv_usec))) { xine_list_iterator_t ite2 = NULL; q->flush = q->q.callback_running ? 1 : 0; while (1) { xine_event_t *e = xine_list_next_value (q->q.events, &ite2); if (!ite2) break; if ((e->tv.tv_sec > tv.tv_sec) || ((e->tv.tv_sec == tv.tv_sec) && (e->tv.tv_usec > tv.tv_usec))) break; q->flush += 1; } } if (q->flush > 0) { int err, n = q->flush; /* make sure this queue does not go away, then unlock list to prevent freezes. */ q->refs += 1; pthread_mutex_unlock (&stream->event.lock); do { /* paranoia: cyclic wait? */ err = pthread_cond_timedwait (&q->q.events_processed, &q->q.lock, &ts); } while ((q->flush > 0) && (err != ETIMEDOUT)); xine_event_queue_unref_unlock (q); if (err == ETIMEDOUT) { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "events: warning: _x_flush_events_queues (%p) timeout.\n", (void *)stream); } else { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "events: flushed %d events for stream %p.\n", n, (void *)stream); } /* list may have changed, restart. */ list_locked = 0; break; } } pthread_mutex_unlock (&q->q.lock); } if (list_locked) { pthread_mutex_unlock (&stream->event.lock); break; } } } xine-lib-1.2/src/xine-engine/buffer.c0000644000175000017500000010302114647725152015273 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * contents: * * buffer_entry structure - serves as a transport encapsulation * of the mpeg audio/video data through xine * * free buffer pool management routines * * FIFO buffer structures/routines */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include /********** logging **********/ #define LOG_MODULE "buffer" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "xine_private.h" /** TJ. NOTE: * vdr-libxineoutput issue #1: * some versions of vdr-libxineoutput use their own replacement of _x_fifo_buffer_new (). * this involves use of an incomplete fifo_buffer_t with our native methods copied * from stream->video_fifo. test for nativity, and fall back to very old behaviour if not. * vdr-libxineoutput issue #2: * we will get some custom buf types, most notably * 0x0f010000 CONTROL_BUF_BLANK * 0x05010000 BUF_NETWORK_BLOCK * 0x05020000 BUF_LOCAL_BLOCK * make sure to treat them like control bufs which keeps put order. */ static const uint8_t _fifo_buf_type_index[256] = { [BUF_AUDIO_BASE >> 24] = 1, [BUF_VIDEO_BASE >> 24] = 1, [BUF_SPU_BASE >> 24] = 2 }; typedef struct { fifo_buffer_t b; uint32_t *fds; buf_element_t **last_add[2]; } _fifo_buffer_t; static void _fifo_mark_native (_fifo_buffer_t *fifo) { fifo->fds = &fifo->b.fifo_data_size; } static int _fifo_is_native (_fifo_buffer_t *fifo) { return fifo->fds == &fifo->b.fifo_data_size; } static void _fifo_mux_init (_fifo_buffer_t *fifo) { fifo->last_add[0] = fifo->last_add[1] = &fifo->b.first; } static void _fifo_mux_last (_fifo_buffer_t *fifo) { if (_fifo_is_native (fifo)) fifo->last_add[0] = fifo->last_add[1] = fifo->b.last ? &fifo->b.last->next : &fifo->b.first; } /* The large buffer feature. * If we have enough contigous memory, and if we can afford to hand if out, * provide an oversize item there. The buffers covering that extra space will * hide inside our buffer array, and buffer_pool_free () will reappear them * mysteriously later. * Small bufs are requested frequently, so we dont do a straightforward * heap manager. Instead, we keep bufs in pool sorted by address, and * be_ei_t.nbufs holds the count of contigous bufs when this is the * first of such a group. * API permits using bufs in a different fifo than their pool origin * (see demux_mpeg_block). Thats why we test buf->source. * It is also possible to supply fully custom bufs. We detect these by * buf->free_buffer != buffer_pool_free. */ typedef struct { buf_element_t elem; /* needs to be first */ int nbufs; /* # of contigous bufs */ extra_info_t ei; } be_ei_t; #define LARGE_NUM 0x7fffffff /* The file buf ctrl feature. * After stream start/seek (fifo flush), there is a phase when a few decoded frames * are better than a lot of merely demuxed ones. Net_buf_ctrl wants large fifos to * handle fragment and other stuttering streams. Lets assume that it knows what to * do there. For plain files, however, demux is likely to drain processor time from * decoders initially. * A separate file_buf_ctrl module should not mess with fifo internals, thus lets * do a little soft start version here when there are no callbacks: * fifo->alloc_cb[0] == fbc_dummy, * fifo->alloc_cb_data[0] == count of yet not to be used bufs. */ static void fbc_dummy (fifo_buffer_t *fifo, void *data) { (void)fifo; (void)data; } int xine_fbc_set (fifo_buffer_t *_fifo, int on) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; if (!_fifo) return 0; pthread_mutex_lock (&fifo->b.mutex); if (on) { int n; if (fifo->b.alloc_cb[0]) { n = (fifo->b.alloc_cb[0] == fbc_dummy); pthread_mutex_unlock (&fifo->b.mutex); return n; } fifo->b.alloc_cb[0] = fbc_dummy; n = (fifo->b.buffer_pool_capacity * 3) >> 2; if (n < 75) n = 0; fifo->b.alloc_cb_data[0] = (void *)(intptr_t)n; pthread_mutex_unlock (&fifo->b.mutex); return 1; } if (fifo->b.alloc_cb[0] == fbc_dummy) { fifo->b.alloc_cb[0] = NULL; fifo->b.alloc_cb_data[0] = (void *)0; } pthread_mutex_unlock (&fifo->b.mutex); return 0; } static int _fbc_avail (_fifo_buffer_t *fifo) { return fifo->b.alloc_cb[0] != fbc_dummy ? fifo->b.buffer_pool_num_free : fifo->b.buffer_pool_num_free - (intptr_t)fifo->b.alloc_cb_data[0]; } static void _fbc_reset (_fifo_buffer_t *fifo) { if (fifo->b.alloc_cb[0] == fbc_dummy) { int n = (fifo->b.buffer_pool_capacity * 3) >> 2; if (n < 75) n = 0; fifo->b.alloc_cb_data[0] = (void *)(intptr_t)n; } } static void _fbc_sub (_fifo_buffer_t *fifo, int n) { if (fifo->b.alloc_cb[0] == fbc_dummy) { n = (intptr_t)fifo->b.alloc_cb_data[0] - n; if (n < 0) n = 0; fifo->b.alloc_cb_data[0] = (void *)(intptr_t)n; } } /* * put a previously allocated buffer element back into the buffer pool */ static void buffer_pool_free (buf_element_t *element) { _fifo_buffer_t *fifo = (_fifo_buffer_t *) element->source; be_ei_t *newhead, *newtail, *nexthead; int n; pthread_mutex_lock (&fifo->b.buffer_pool_mutex); newhead = (be_ei_t *)element; n = newhead->nbufs; _fbc_sub (fifo, n); fifo->b.buffer_pool_num_free += n; if (fifo->b.buffer_pool_num_free > fifo->b.buffer_pool_capacity) { fprintf(stderr, _("xine-lib: buffer.c: There has been a fatal error: TOO MANY FREE's\n")); _x_abort(); } /* we might be a new chunk */ newtail = newhead + 1; while (--n > 0) { newtail[-1].elem.next = &newtail[0].elem; newtail++; } nexthead = (be_ei_t *)fifo->b.buffer_pool_top; if (!nexthead || (nexthead >= newtail)) { /* add head */ fifo->b.buffer_pool_top = &newhead->elem; newtail[-1].elem.next = &nexthead->elem; /* merge with next chunk if no gap */ if (newtail == nexthead) newhead->nbufs += nexthead->nbufs; } else { /* Keep the pool sorted, elem1 > elem2 implies elem1->mem > elem2->mem. */ be_ei_t *prevhead, *prevtail; while (1) { prevhead = nexthead; prevtail = prevhead + prevhead->nbufs; nexthead = (be_ei_t *)prevtail[-1].elem.next; if (!nexthead || (nexthead >= newtail)) break; } prevtail[-1].elem.next = &newhead->elem; newtail[-1].elem.next = &nexthead->elem; /* merge with next chunk if no gap */ if (newtail == nexthead) newhead->nbufs += nexthead->nbufs; /* merge with prev chunk if no gap */ if (prevtail == newhead) prevhead->nbufs += newhead->nbufs; } /* dont provoke useless wakeups */ if (fifo->b.buffer_pool_num_waiters || (fifo->b.buffer_pool_large_wait <= _fbc_avail (fifo))) pthread_cond_signal (&fifo->b.buffer_pool_cond_not_empty); pthread_mutex_unlock (&fifo->b.buffer_pool_mutex); } /* * allocate a buffer from buffer pool */ static buf_element_t *_buffer_pool_size_alloc (_fifo_buffer_t *fifo, int n) { int i; be_ei_t *buf; for (i = 0; fifo->b.alloc_cb[i]; i++) fifo->b.alloc_cb[i] (&fifo->b, fifo->b.alloc_cb_data[i]); if (n < 1) n = 1; /* we always keep one free buffer for emergency situations like * decoder flushes that would need a buffer in buffer_pool_try_alloc() */ n += 2; if (_fbc_avail (fifo) < n) { /* Paranoia: someone else than demux calling this in parallel ?? */ if (fifo->b.buffer_pool_large_wait != LARGE_NUM) { fifo->b.buffer_pool_num_waiters++; do { pthread_cond_wait (&fifo->b.buffer_pool_cond_not_empty, &fifo->b.buffer_pool_mutex); } while (_fbc_avail (fifo) < n); fifo->b.buffer_pool_num_waiters--; } else { fifo->b.buffer_pool_large_wait = n; do { pthread_cond_wait (&fifo->b.buffer_pool_cond_not_empty, &fifo->b.buffer_pool_mutex); } while (_fbc_avail (fifo) < n); fifo->b.buffer_pool_large_wait = LARGE_NUM; } } n -= 2; buf = (be_ei_t *)fifo->b.buffer_pool_top; if (n == 1) { fifo->b.buffer_pool_top = buf->elem.next; i = buf->nbufs - 1; if (i > 0) buf[1].nbufs = i; fifo->b.buffer_pool_num_free--; } else { buf_element_t **link = &fifo->b.buffer_pool_top, **bestlink = link; int bestsize = 0; while (1) { int l = buf->nbufs; if (l > n) { be_ei_t *next = buf + n; next->nbufs = l - n; *link = &next->elem; break; } else if (l == n) { *link = buf[l - 1].elem.next; break; } if (l > bestsize) { bestsize = l; bestlink = link; } buf += l - 1; link = &buf->elem.next; buf = (be_ei_t *)(*link); if (!buf) { buf = (be_ei_t *)(*bestlink); n = bestsize; *bestlink = buf[n - 1].elem.next; break; } } fifo->b.buffer_pool_num_free -= n; } pthread_mutex_unlock (&fifo->b.buffer_pool_mutex); /* set sane values to the newly allocated buffer */ buf->elem.content = buf->elem.mem; /* 99% of demuxers will want this */ buf->elem.pts = 0; buf->elem.size = 0; buf->elem.max_size = n * fifo->b.buffer_pool_buf_size; buf->elem.decoder_flags = 0; buf->nbufs = n; memset (buf->elem.decoder_info, 0, sizeof (buf->elem.decoder_info)); memset (buf->elem.decoder_info_ptr, 0, sizeof (buf->elem.decoder_info_ptr)); _x_extra_info_reset (buf->elem.extra_info); return &buf->elem; } static buf_element_t *buffer_pool_size_alloc (fifo_buffer_t *_fifo, size_t size) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int n; if (!_fifo_is_native (fifo)) return fifo->b.buffer_pool_alloc (&fifo->b); n = size ? ((int)size + fifo->b.buffer_pool_buf_size - 1) / fifo->b.buffer_pool_buf_size : 1; if (n > (fifo->b.buffer_pool_capacity >> 2)) n = fifo->b.buffer_pool_capacity >> 2; pthread_mutex_lock (&fifo->b.buffer_pool_mutex); return _buffer_pool_size_alloc (fifo, n); } static buf_element_t *buffer_pool_alloc (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; be_ei_t *buf; int i; pthread_mutex_lock (&fifo->b.buffer_pool_mutex); for (i = 0; fifo->b.alloc_cb[i]; i++) fifo->b.alloc_cb[i] (&fifo->b, fifo->b.alloc_cb_data[i]); /* we always keep one free buffer for emergency situations like * decoder flushes that would need a buffer in buffer_pool_try_alloc() */ if (_fbc_avail (fifo) < 2) { fifo->b.buffer_pool_num_waiters++; do { pthread_cond_wait (&fifo->b.buffer_pool_cond_not_empty, &fifo->b.buffer_pool_mutex); } while (_fbc_avail (fifo) < 2); fifo->b.buffer_pool_num_waiters--; } buf = (be_ei_t *)fifo->b.buffer_pool_top; fifo->b.buffer_pool_top = buf->elem.next; if (_fifo_is_native (fifo)) { i = buf->nbufs - 1; if (i > 0) buf[1].nbufs = i; buf->nbufs = 1; } fifo->b.buffer_pool_num_free--; pthread_mutex_unlock (&fifo->b.buffer_pool_mutex); /* set sane values to the newly allocated buffer */ buf->elem.content = buf->elem.mem; /* 99% of demuxers will want this */ buf->elem.pts = 0; buf->elem.size = 0; buf->elem.max_size = fifo->b.buffer_pool_buf_size; buf->elem.decoder_flags = 0; memset (buf->elem.decoder_info, 0, sizeof (buf->elem.decoder_info)); memset (buf->elem.decoder_info_ptr, 0, sizeof (buf->elem.decoder_info_ptr)); _x_extra_info_reset (buf->elem.extra_info); return &buf->elem; } static buf_element_t *buffer_pool_realloc (buf_element_t *buf, size_t new_size) { _fifo_buffer_t *fifo; buf_element_t **last_buf; be_ei_t *old_buf = (be_ei_t *)buf, *new_buf, *want_buf; int n; if (!old_buf) return NULL; if ((int)new_size <= old_buf->elem.max_size) return NULL; if (old_buf->elem.free_buffer != buffer_pool_free) return NULL; fifo = (_fifo_buffer_t *)old_buf->elem.source; if (!fifo) return NULL; if (!_fifo_is_native (fifo)) return fifo->b.buffer_pool_alloc (&fifo->b); n = ((int)new_size + fifo->b.buffer_pool_buf_size - 1) / fifo->b.buffer_pool_buf_size; /* limit size to keep pool fluent */ if (n > (fifo->b.buffer_pool_capacity >> 3)) n = fifo->b.buffer_pool_capacity >> 3; n -= old_buf->nbufs; want_buf = old_buf + old_buf->nbufs; last_buf = &fifo->b.buffer_pool_top; pthread_mutex_lock (&fifo->b.buffer_pool_mutex); while (1) { new_buf = (be_ei_t *)(*last_buf); if (!new_buf) break; if (new_buf == want_buf) break; if (new_buf > want_buf) { new_buf = NULL; break; } new_buf += new_buf->nbufs; last_buf = &(new_buf[-1].elem.next); } if (new_buf) do { int s; /* save emergecy buf */ if (n > fifo->b.buffer_pool_num_free - 1) n = fifo->b.buffer_pool_num_free - 1; if (n < 1) break; s = new_buf->nbufs - n; if (s > 0) { new_buf += n; new_buf->nbufs = s; *last_buf = &new_buf->elem; } else { n = new_buf->nbufs; new_buf += n; *last_buf = new_buf[-1].elem.next; } fifo->b.buffer_pool_num_free -= n; pthread_mutex_unlock (&fifo->b.buffer_pool_mutex); old_buf->nbufs += n; old_buf->elem.max_size = old_buf->nbufs * fifo->b.buffer_pool_buf_size; return NULL; } while (0); return _buffer_pool_size_alloc (fifo, n); } /* * allocate a buffer from buffer pool - may fail if none is available */ static buf_element_t *buffer_pool_try_alloc (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; be_ei_t *buf; int i; pthread_mutex_lock (&fifo->b.buffer_pool_mutex); buf = (be_ei_t *)fifo->b.buffer_pool_top; if (!buf) { pthread_mutex_unlock (&fifo->b.buffer_pool_mutex); return NULL; } fifo->b.buffer_pool_top = buf->elem.next; if (_fifo_is_native (fifo)) { i = buf->nbufs - 1; if (i > 0) buf[1].nbufs = i; buf->nbufs = 1; } fifo->b.buffer_pool_num_free--; pthread_mutex_unlock (&fifo->b.buffer_pool_mutex); /* set sane values to the newly allocated buffer */ buf->elem.content = buf->elem.mem; /* 99% of demuxers will want this */ buf->elem.pts = 0; buf->elem.size = 0; buf->elem.max_size = fifo->b.buffer_pool_buf_size; buf->elem.decoder_flags = 0; memset (buf->elem.decoder_info, 0, sizeof (buf->elem.decoder_info)); memset (buf->elem.decoder_info_ptr, 0, sizeof (buf->elem.decoder_info_ptr)); _x_extra_info_reset (buf->elem.extra_info); return &buf->elem; } /* * append buffer element to fifo buffer */ static void fifo_buffer_put (fifo_buffer_t *_fifo, buf_element_t *element) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; buf_element_t **next; uint32_t type; int i; pthread_mutex_lock (&fifo->b.mutex); if (element->decoder_flags & BUF_FLAG_MERGE) { be_ei_t *new = (be_ei_t *)element, *prev = (be_ei_t *)fifo->b.last; new->elem.decoder_flags &= ~BUF_FLAG_MERGE; if (prev && (prev + prev->nbufs == new) && (prev->elem.type == new->elem.type) && (prev->nbufs < (fifo->b.buffer_pool_capacity >> 3))) { fifo->b.fifo_size += new->nbufs; fifo->b.fifo_data_size += new->elem.size; prev->nbufs += new->nbufs; prev->elem.max_size += new->elem.max_size; prev->elem.size += new->elem.size; prev->elem.decoder_flags |= new->elem.decoder_flags; pthread_mutex_unlock (&fifo->b.mutex); return; } } for(i = 0; fifo->b.put_cb[i]; i++) fifo->b.put_cb[i] (&fifo->b, element, fifo->b.put_cb_data[i]); /* try to mux spu tracks, especially separate ones. */ type = _fifo_buf_type_index[(uint32_t)element->type >> 24]; if (!_fifo_is_native (fifo)) { element->next = NULL; if (fifo->b.first) { fifo->b.first->next = fifo->b.last = element; } else { fifo->b.first = fifo->b.last = element; } } else if (type == 0) { /* always add ctrl and custom stuff fence at the end. */ element->next = NULL; next = fifo->b.last ? &fifo->b.last->next : &fifo->b.first; *next = element; fifo->b.last = element; fifo->last_add[0] = fifo->last_add[1] = &element->next; } else { /* keep order within same type group. * look from last add in this group. if there are more bufs, * they must be from the other group - no need to test again. */ type--; next = fifo->last_add[type]; if (element->pts) { /* allow a second of overlap to compensate for frame reordering. */ static const int overlap[2] = {90000, -90000}; int64_t epts = element->pts + overlap[type]; buf_element_t *b2; while ((b2 = *next)) { if (b2->pts > epts) break; next = &b2->next; } } if (!(element->next = *next)) fifo->b.last = element; *next = element; fifo->last_add[type] = &element->next; } if (element->free_buffer == buffer_pool_free) { be_ei_t *beei = (be_ei_t *)element; fifo->b.fifo_size += beei->nbufs; } else { fifo->b.fifo_size += 1; } fifo->b.fifo_data_size += element->size; if (fifo->b.fifo_num_waiters) pthread_cond_signal (&fifo->b.not_empty); pthread_mutex_unlock (&fifo->b.mutex); } /* * simulate append buffer element to fifo buffer */ static void dummy_fifo_buffer_put (fifo_buffer_t *_fifo, buf_element_t *element) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int i; pthread_mutex_lock (&fifo->b.mutex); for (i = 0; fifo->b.put_cb[i]; i++) fifo->b.put_cb[i] (&fifo->b, element, fifo->b.put_cb_data[i]); pthread_mutex_unlock (&fifo->b.mutex); element->free_buffer(element); } /* * insert buffer element to fifo buffer (demuxers MUST NOT call this one) */ static void fifo_buffer_insert (fifo_buffer_t *_fifo, buf_element_t *element) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; pthread_mutex_lock (&fifo->b.mutex); element->next = fifo->b.first; fifo->b.first = element; if( !fifo->b.last ) fifo->b.last = element; if (_fifo_is_native (fifo)) { if (fifo->last_add[0] == &fifo->b.first) fifo->last_add[0] = &element->next; if (fifo->last_add[1] == &fifo->b.first) fifo->last_add[1] = &element->next; } if (element->free_buffer == buffer_pool_free) { be_ei_t *beei = (be_ei_t *)element; fifo->b.fifo_size += beei->nbufs; } else { fifo->b.fifo_size += 1; } fifo->b.fifo_data_size += element->size; if (fifo->b.fifo_num_waiters) pthread_cond_signal (&fifo->b.not_empty); pthread_mutex_unlock (&fifo->b.mutex); } /* * insert buffer element to fifo buffer (demuxers MUST NOT call this one) */ static void dummy_fifo_buffer_insert (fifo_buffer_t *fifo, buf_element_t *element) { (void)fifo; element->free_buffer(element); } /* * get element from fifo buffer */ static buf_element_t *fifo_buffer_get (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; buf_element_t *buf; int i; pthread_mutex_lock (&fifo->b.mutex); if (!fifo->b.first) { fifo->b.fifo_num_waiters++; do { pthread_cond_wait (&fifo->b.not_empty, &fifo->b.mutex); } while (!fifo->b.first); fifo->b.fifo_num_waiters--; } buf = fifo->b.first; if (!(fifo->b.first = buf->next)) fifo->b.last = NULL; buf->next = NULL; if (_fifo_is_native (fifo)) { if (fifo->last_add[0] == &buf->next) fifo->last_add[0] = &fifo->b.first; if (fifo->last_add[1] == &buf->next) fifo->last_add[1] = &fifo->b.first; } if (buf->free_buffer == buffer_pool_free) { be_ei_t *beei = (be_ei_t *)buf; fifo->b.fifo_size -= beei->nbufs; } else { fifo->b.fifo_size -= 1; } fifo->b.fifo_data_size -= buf->size; for (i = 0; fifo->b.get_cb[i]; i++) fifo->b.get_cb[i] (&fifo->b, buf, fifo->b.get_cb_data[i]); pthread_mutex_unlock (&fifo->b.mutex); return buf; } static buf_element_t *fifo_buffer_tget (fifo_buffer_t *_fifo, xine_ticket_t *ticket) { /* Optimization: let decoders hold port ticket by default. * Unfortunately, fifo callbacks are 1 big freezer, as they run with fifo locked, * and may try to revoke ticket for pauseing or other stuff. * Always releasing ticket when there are callbacks is safe but inefficient. * Instead, we release ticket when we are going to wait for fifo or a buffer, * and of course, when the ticket has been revoked. * This should melt the "put" side. We could still freeze ourselves directly * at the "get" side, what ticket->revoke () self grant hack shall fix. */ _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; buf_element_t *buf; int mode = ticket ? 2 : 0, i; if (pthread_mutex_trylock (&fifo->b.mutex)) { if (mode & 2) { ticket->release (ticket, 0); mode = 1; } pthread_mutex_lock (&fifo->b.mutex); } if (!fifo->b.first) { if (mode & 2) { ticket->release (ticket, 0); mode = 1; } fifo->b.fifo_num_waiters++; do { pthread_cond_wait (&fifo->b.not_empty, &fifo->b.mutex); } while (!fifo->b.first); fifo->b.fifo_num_waiters--; } buf = fifo->b.first; if (!(fifo->b.first = buf->next)) fifo->b.last = NULL; buf->next = NULL; if (_fifo_is_native (fifo)) { if (fifo->last_add[0] == &buf->next) fifo->last_add[0] = &fifo->b.first; if (fifo->last_add[1] == &buf->next) fifo->last_add[1] = &fifo->b.first; } if (buf->free_buffer == buffer_pool_free) { be_ei_t *beei = (be_ei_t *)buf; fifo->b.fifo_size -= beei->nbufs; } else { fifo->b.fifo_size -= 1; } fifo->b.fifo_data_size -= buf->size; if ((mode & 2) && ticket->ticket_revoked) { ticket->release (ticket, 0); mode = 1; } for(i = 0; fifo->b.get_cb[i]; i++) fifo->b.get_cb[i] (&fifo->b, buf, fifo->b.get_cb_data[i]); pthread_mutex_unlock (&fifo->b.mutex); if (mode & 1) ticket->acquire (ticket, 0); return buf; } /* * clear buffer (put all contained buffer elements back into buffer pool) */ static void fifo_buffer_clear (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; be_ei_t *start; pthread_mutex_lock (&fifo->b.mutex); /* take out all at once */ start = (be_ei_t *)fifo->b.first; fifo->b.first = fifo->b.last = NULL; fifo->b.fifo_size = 0; fifo->b.fifo_data_size = 0; while (start) { be_ei_t *buf, *next; int n; /* keep control bufs (flush, ...) */ if ((start->elem.type & BUF_MAJOR_MASK) == BUF_CONTROL_BASE) { if (!fifo->b.first) fifo->b.first = &start->elem; else fifo->b.last->next = &start->elem; fifo->b.last = &start->elem; fifo->b.fifo_size += 1; fifo->b.fifo_data_size += start->elem.size; buf = (be_ei_t *)start->elem.next; start->elem.next = NULL; start = buf; continue; } /* free custom buf */ if (start->elem.free_buffer != buffer_pool_free) { buf = (be_ei_t *)start->elem.next; start->elem.next = NULL; start->elem.free_buffer (&start->elem); start = buf; continue; } /* optimize: get contiguous chunk */ buf = start; n = 0; while (1) { int i = buf->nbufs; next = (be_ei_t *)buf->elem.next; n += i; if (buf + i != next) /* includes next == NULL et al ;-) */ break; if ((next->elem.type & BUF_MAJOR_MASK) == BUF_CONTROL_BASE) break; buf = next; } start->nbufs = n; start->elem.free_buffer (&start->elem); start = next; } _fbc_reset (fifo); _fifo_mux_last (fifo); /* printf("Free buffers after clear: %d\n", fifo->buffer_pool_num_free); */ pthread_mutex_unlock (&fifo->b.mutex); } static void _fifo_buffer_all_clear (_fifo_buffer_t *fifo) { be_ei_t *start; pthread_mutex_lock (&fifo->b.mutex); /* take out all at once */ start = (be_ei_t *)fifo->b.first; fifo->b.first = fifo->b.last = NULL; fifo->b.fifo_size = 0; fifo->b.fifo_data_size = 0; while (start) { be_ei_t *buf, *next; int n; /* free custom buf */ if (start->elem.free_buffer != buffer_pool_free) { buf = (be_ei_t *)start->elem.next; start->elem.next = NULL; start->elem.free_buffer (&start->elem); start = buf; continue; } /* optimize: get contiguous chunk */ buf = start; n = 0; while (1) { int i = buf->nbufs; next = (be_ei_t *)buf->elem.next; n += i; if (buf + i != next) /* includes next == NULL ;-) */ break; buf = next; } /* free just sibling bufs */ if (start->elem.source != (void *)fifo) { start->nbufs = n; start->elem.free_buffer (&start->elem); } start = next; } _fifo_mux_last (fifo); pthread_mutex_unlock (&fifo->b.mutex); } /* * Return the number of elements in the fifo buffer */ static int fifo_buffer_size (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int size; pthread_mutex_lock (&fifo->b.mutex); size = fifo->b.fifo_size; pthread_mutex_unlock (&fifo->b.mutex); return size; } /* * Return the amount of the data in the fifo buffer */ static uint32_t fifo_buffer_data_size (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; uint32_t data_size; pthread_mutex_lock (&fifo->b.mutex); data_size = fifo->b.fifo_data_size; pthread_mutex_unlock (&fifo->b.mutex); return data_size; } /* * Return the number of free elements in the pool */ static int fifo_buffer_num_free (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int buffer_pool_num_free; pthread_mutex_lock (&fifo->b.buffer_pool_mutex); buffer_pool_num_free = fifo->b.buffer_pool_num_free; pthread_mutex_unlock (&fifo->b.buffer_pool_mutex); return buffer_pool_num_free; } /* * Destroy the buffer */ static void fifo_buffer_dispose (fifo_buffer_t *_fifo) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; if (!fifo) return; _fifo_buffer_all_clear (fifo); if (_fifo_is_native (fifo)) xine_free_aligned (fifo->b.buffer_pool_base); pthread_mutex_destroy (&fifo->b.mutex); pthread_cond_destroy (&fifo->b.not_empty); pthread_mutex_destroy (&fifo->b.buffer_pool_mutex); pthread_cond_destroy (&fifo->b.buffer_pool_cond_not_empty); free (fifo); } /* * Register an "alloc" callback */ static void fifo_register_alloc_cb (fifo_buffer_t *_fifo, void (*cb) (fifo_buffer_t *fifo, void *data_cb), void *data_cb) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int i; pthread_mutex_lock (&fifo->b.mutex); if (fifo->b.alloc_cb[0] == fbc_dummy) { fifo->b.alloc_cb[0] = NULL; fifo->b.alloc_cb_data[0] = NULL; } for (i = 0; fifo->b.alloc_cb[i]; i++) ; if (i != BUF_MAX_CALLBACKS - 1) { fifo->b.alloc_cb[i] = cb; fifo->b.alloc_cb_data[i] = data_cb; fifo->b.alloc_cb[i + 1] = NULL; fifo->b.alloc_cb_data[i+1] = (void *)(intptr_t)0; } pthread_mutex_unlock (&fifo->b.mutex); } /* * Register a "put" callback */ static void fifo_register_put_cb (fifo_buffer_t *_fifo, void (*cb) (fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb), void *data_cb) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int i; pthread_mutex_lock (&fifo->b.mutex); for (i = 0; fifo->b.put_cb[i]; i++) ; if (i != BUF_MAX_CALLBACKS - 1) { fifo->b.put_cb[i] = cb; fifo->b.put_cb_data[i] = data_cb; fifo->b.put_cb[i+1] = NULL; } pthread_mutex_unlock (&fifo->b.mutex); } /* * Register a "get" callback */ static void fifo_register_get_cb (fifo_buffer_t *_fifo, void (*cb) (fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb), void *data_cb) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int i; pthread_mutex_lock (&fifo->b.mutex); for (i = 0; fifo->b.get_cb[i]; i++) ; if (i != BUF_MAX_CALLBACKS - 1) { fifo->b.get_cb[i] = cb; fifo->b.get_cb_data[i] = data_cb; fifo->b.get_cb[i+1] = NULL; } pthread_mutex_unlock (&fifo->b.mutex); } /* * Unregister an "alloc" callback */ static void fifo_unregister_alloc_cb (fifo_buffer_t *_fifo, void (*cb) (fifo_buffer_t *fifo, void *data_cb)) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int i,j; pthread_mutex_lock (&fifo->b.mutex); for (i = 0; fifo->b.alloc_cb[i]; i++) { if (fifo->b.alloc_cb[i] == cb) { for (j = i; fifo->b.alloc_cb[j]; j++) { fifo->b.alloc_cb[j] = fifo->b.alloc_cb[j+1]; fifo->b.alloc_cb_data[j] = fifo->b.alloc_cb_data[j+1]; } } } pthread_mutex_unlock (&fifo->b.mutex); } /* * Unregister a "put" callback */ static void fifo_unregister_put_cb (fifo_buffer_t *_fifo, void (*cb) (fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb)) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int i,j; pthread_mutex_lock (&fifo->b.mutex); for (i = 0; fifo->b.put_cb[i]; i++) { if (fifo->b.put_cb[i] == cb) { for (j = i; fifo->b.put_cb[j]; j++) { fifo->b.put_cb[j] = fifo->b.put_cb[j + 1]; fifo->b.put_cb_data[j] = fifo->b.put_cb_data[j + 1]; } } } pthread_mutex_unlock (&fifo->b.mutex); } /* * Unregister a "get" callback */ static void fifo_unregister_get_cb (fifo_buffer_t *_fifo, void (*cb) (fifo_buffer_t *fifo, buf_element_t *buf, void *data_cb)) { _fifo_buffer_t *fifo = (_fifo_buffer_t *)_fifo; int i, j; pthread_mutex_lock (&fifo->b.mutex); for (i = 0; fifo->b.get_cb[i]; i++) { if (fifo->b.get_cb[i] == cb) { for (j = i; fifo->b.get_cb[j]; j++) { fifo->b.get_cb[j] = fifo->b.get_cb[j + 1]; fifo->b.get_cb_data[j] = fifo->b.get_cb_data[j + 1]; } } } pthread_mutex_unlock (&fifo->b.mutex); } /* * allocate and initialize new (empty) fifo buffer */ fifo_buffer_t *_x_fifo_buffer_new (int num_buffers, uint32_t buf_size) { _fifo_buffer_t *fifo; union { be_ei_t *beei; unsigned char *b; } multi_buffer; fifo = calloc (1, sizeof (*fifo)); if (!fifo) return NULL; #ifndef HAVE_ZERO_SAFE_MEM /* Do these first, when compiler still knows "this" is all zeroed. * Let it optimize away this on most systems where clear mem * interpretes as 0, 0f or NULL safely. */ fifo->b.first = NULL; fifo->b.last = NULL; fifo->b.fifo_size = 0; fifo->b.fifo_num_waiters = 0; fifo->b.buffer_pool_num_waiters = 0; fifo->b.alloc_cb[0] = NULL; fifo->b.get_cb[0] = NULL; fifo->b.put_cb[0] = NULL; fifo->b.alloc_cb_data[0] = NULL; fifo->b.get_cb_data[0] = NULL; fifo->b.put_cb_data[0] = NULL; #endif _fifo_mark_native (fifo); _fifo_mux_init (fifo); if (num_buffers <= 0) num_buffers = 1; buf_size = (buf_size + 31) & ~31u; /* printf ("Allocating %d buffers of %ld bytes in one chunk\n", num_buffers, (long int) buf_size); */ multi_buffer.beei = xine_mallocz_aligned (num_buffers * (buf_size + sizeof (be_ei_t))); if (!multi_buffer.beei) { free (fifo); return NULL; } fifo->b.put = fifo_buffer_put; fifo->b.insert = fifo_buffer_insert; fifo->b.get = fifo_buffer_get; fifo->b.tget = fifo_buffer_tget; fifo->b.clear = fifo_buffer_clear; fifo->b.size = fifo_buffer_size; fifo->b.num_free = fifo_buffer_num_free; fifo->b.data_size = fifo_buffer_data_size; fifo->b.dispose = fifo_buffer_dispose; fifo->b.register_alloc_cb = fifo_register_alloc_cb; fifo->b.register_get_cb = fifo_register_get_cb; fifo->b.register_put_cb = fifo_register_put_cb; fifo->b.unregister_alloc_cb = fifo_unregister_alloc_cb; fifo->b.unregister_get_cb = fifo_unregister_get_cb; fifo->b.unregister_put_cb = fifo_unregister_put_cb; pthread_mutex_init (&fifo->b.mutex, NULL); pthread_cond_init (&fifo->b.not_empty, NULL); /* init buffer pool */ pthread_mutex_init (&fifo->b.buffer_pool_mutex, NULL); pthread_cond_init (&fifo->b.buffer_pool_cond_not_empty, NULL); fifo->b.buffer_pool_num_free = fifo->b.buffer_pool_capacity = num_buffers; fifo->b.buffer_pool_buf_size = buf_size; fifo->b.buffer_pool_alloc = buffer_pool_alloc; fifo->b.buffer_pool_try_alloc = buffer_pool_try_alloc; fifo->b.buffer_pool_size_alloc = buffer_pool_size_alloc; fifo->b.buffer_pool_realloc = buffer_pool_realloc; fifo->b.buffer_pool_large_wait = LARGE_NUM; { unsigned char *mem = multi_buffer.b; be_ei_t *beei, *end; fifo->b.buffer_pool_base = mem; multi_buffer.b += num_buffers * buf_size; beei = multi_buffer.beei; end = beei + num_buffers; fifo->b.buffer_pool_top = &beei->elem; beei->nbufs = num_buffers; do { beei->elem.mem = mem; mem += buf_size; beei->elem.max_size = buf_size; beei->elem.free_buffer = buffer_pool_free; beei->elem.source = fifo; beei->elem.extra_info = &beei->ei; beei->elem.next = &beei[1].elem; beei++; } while (beei < end); beei[-1].elem.next = NULL; } return &fifo->b; } /* * allocate and initialize new (empty) fifo buffer */ fifo_buffer_t *_x_dummy_fifo_buffer_new (int num_buffers, uint32_t buf_size) { fifo_buffer_t *this = _x_fifo_buffer_new (num_buffers, buf_size); if (this) { this->put = dummy_fifo_buffer_put; this->insert = dummy_fifo_buffer_insert; } return this; } void _x_free_buf_elements (buf_element_t *head) { buf_element_t *here, *next; for (here = head; here; here = next) { next = here->next; here->next = NULL; here->free_buffer (here); } } xine-lib-1.2/src/xine-engine/audio_decoder.c0000644000175000017500000006440014647725152016617 0ustar meme/* * Copyright (C) 2000-2023 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * functions that implement audio decoding */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #define LOG_MODULE "audio_decoder" #define LOG_VERBOSE /* #define LOG */ #include #include #include "xine_private.h" static void *audio_decoder_loop (void *stream_gen) { xine_stream_private_t *stream = (xine_stream_private_t *)stream_gen; xine_private_t *xine = (xine_private_t *)stream->s.xine; xine_ticket_t *running_ticket = xine->port_ticket; buf_element_t *headers_first = NULL, **headers_add = &headers_first, *headers_replay = NULL; int running = 1; int seek_count; int prof_audio_decode = -1; uint32_t buftype_unknown = 0; int audio_channel_user = stream->audio_channel_user; int headers_num = 0; /* generic bitrate estimation. */ int64_t audio_br_lasttime = 0; uint32_t audio_br_lastsize = 0; uint32_t audio_br_time = 1; uint32_t audio_br_bytes = 0; int audio_br_num = 20; int audio_br_value = 0; /* list of seen audio channels, sorted by number. * audio_track_map[foo] & 0xff000000 is always BUF_AUDIO_BASE, * and bit 31 may serve as an end marker. */ #define AUDIO_TRACK_MAP_MAX 50 #define AUDIO_TRACK_MAP_MASK 0x8000ffff #define AUDIO_TRACK_MAP_END 0x80000000 uint32_t audio_track_map[AUDIO_TRACK_MAP_MAX + 1]; #define BUFTYPE_BASE(type) ((type) >> 24) #define BUFTYPE_SUB(type) (((type) & 0x00ff0000) >> 16) if (prof_audio_decode == -1) prof_audio_decode = xine_profiler_allocate_slot ("audio decoder/output"); audio_track_map[0] = AUDIO_TRACK_MAP_END; memset (stream->audio_decoder_extra_info, 0, sizeof (*stream->audio_decoder_extra_info)); pthread_mutex_lock (&stream->first_frame.lock); stream->audio_decoder_extra_info->seek_count = seek_count = stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); running_ticket->acquire (running_ticket, 0); while (running) { int handled, ignore; buf_element_t *buf; lprintf ("audio_loop: waiting for package...\n"); buf = headers_replay; if (!buf) buf = stream->s.audio_fifo->tget (stream->s.audio_fifo, running_ticket); lprintf ("audio_loop: got package pts = %"PRId64", type = %08x\n", buf->pts, buf->type); if (!buf->extra_info->invalid) { if (buf->extra_info->input_normpos) stream->audio_decoder_extra_info->input_normpos = buf->extra_info->input_normpos; if (buf->extra_info->input_time) stream->audio_decoder_extra_info->input_time = buf->extra_info->input_time; if (buf->extra_info->frame_number) stream->audio_decoder_extra_info->frame_number = buf->extra_info->frame_number; if (buf->extra_info->total_time) stream->audio_decoder_extra_info->total_time = buf->extra_info->total_time; } stream->audio_decoder_extra_info->seek_count = seek_count; switch (BUFTYPE_BASE (buf->type)) { case BUFTYPE_BASE (BUF_AUDIO_BASE): if ((buf->type & 0xffff0000) == BUF_AUDIO_UNKNOWN) break; xine_rwlock_rdlock (&stream->info_lock); handled = stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED]; ignore = stream->stream_info[XINE_STREAM_INFO_IGNORE_AUDIO]; xine_rwlock_unlock (&stream->info_lock); (void)handled; /* dont optimize away the read. */ if (ignore) break; xine_profiler_start_count (prof_audio_decode); /* running_ticket->acquire (running_ticket, 0); */ { uint32_t audio_type = 0; int i; uint32_t chan; /* printf ("audio_decoder: buf_type=%08x auto=%08x user=%08x\n", buf->type, stream->audio_channel_auto, audio_channel_user); */ /* update track map */ chan = buf->type & 0x0000ffff; i = 0; while ((audio_track_map[i] & AUDIO_TRACK_MAP_MASK) < chan) i++; if ((audio_track_map[i] & AUDIO_TRACK_MAP_MASK) != chan) { xine_event_t ui_event; int j = stream->audio_track_map_entries; if (j >= AUDIO_TRACK_MAP_MAX) { xine_profiler_stop_count (prof_audio_decode); break; } while (j >= i) { audio_track_map[j + 1] = audio_track_map[j]; j--; } audio_track_map[i] = buf->type; stream->audio_track_map_entries++; /* implicit channel change - reopen decoder below */ if ((i == 0) && (audio_channel_user == -1) && (stream->s.audio_channel_auto < 0)) stream->audio_decoder_streamtype = -1; ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send (&stream->s, &ui_event); } /* find out which audio type to decode */ lprintf ("audio_channel_user = %d, map[0]=%08x\n", audio_channel_user, audio_track_map[0]); if (audio_channel_user > -2) { if (audio_channel_user == -1) { /* auto */ lprintf ("audio_channel_auto = %d\n", stream->s.audio_channel_auto); if (stream->s.audio_channel_auto >= 0) { if ((int)(buf->type & 0xFF) == stream->s.audio_channel_auto) { audio_type = buf->type; } else audio_type = -1; } else audio_type = audio_track_map[0]; } else { if (audio_channel_user <= stream->audio_track_map_entries) audio_type = audio_track_map[audio_channel_user]; else audio_type = -1; } /* now, decode stream buffer if it's the right audio type */ if (buf->type == audio_type) { int streamtype = (buf->type>>16) & 0xFF; /* close old decoder of audio type has changed */ if (buf->type != buftype_unknown && (stream->audio_decoder_streamtype != streamtype || !stream->audio_decoder_plugin)) { if (stream->audio_decoder_plugin) { _x_free_audio_decoder (&stream->s, stream->audio_decoder_plugin); } stream->audio_decoder_streamtype = streamtype; stream->audio_decoder_plugin = _x_get_audio_decoder (&stream->s, streamtype); handled = (stream->audio_decoder_plugin != NULL); xine_rwlock_wrlock (&stream->info_lock); stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED] = handled; xine_rwlock_unlock (&stream->info_lock); /* audio_br_reset */ audio_br_lasttime = 0; audio_br_lastsize = 0; audio_br_time = 1; /* No / 0 please. */ audio_br_bytes = 0; audio_br_num = 20; audio_br_value = 0; } if (audio_type != stream->audio_type) { if (stream->audio_decoder_plugin) { xine_event_t event; stream->audio_type = audio_type; event.type = XINE_EVENT_UI_CHANNELS_CHANGED; event.data_length = 0; xine_event_send (&stream->s, &event); } } /* audio_br_add. some decoders reset buf->pts, do this first. */ if (buf->pts) { int64_t d = buf->pts - audio_br_lasttime; if (d > 0) { if (d < 220000) { audio_br_time += d; audio_br_bytes += audio_br_lastsize; audio_br_lastsize = 0; if (--audio_br_num < 0) { int br, bdiff; audio_br_num = 20; if ((audio_br_bytes | audio_br_time) & 0x80000000) { audio_br_bytes >>= 1; audio_br_time >>= 1; } br = xine_uint_mul_div (audio_br_bytes, 90000 * 8, audio_br_time); bdiff = br - audio_br_value; if (bdiff < 0) bdiff = -bdiff; if (bdiff > (br >> 6)) { audio_br_value = br; xine_rwlock_wrlock (&stream->info_lock); stream->stream_info[XINE_STREAM_INFO_AUDIO_BITRATE] = br; xine_rwlock_unlock (&stream->info_lock); } } } audio_br_lasttime = buf->pts; } else { /* Do we really need to care for reordered audio? So what. */ if (d <= -220000) audio_br_lasttime = buf->pts; } } audio_br_lastsize += buf->size; /* finally - decode data */ if (stream->audio_decoder_plugin) stream->audio_decoder_plugin->decode_data (stream->audio_decoder_plugin, buf); /* no need to lock again. it may have been reset from this thread inside * audio_decoder_plugin->decode_data (), if at all. * XXX: should we try a different decoder then? */ handled = stream->stream_info[XINE_STREAM_INFO_AUDIO_HANDLED]; if (!handled && (buf->type != buftype_unknown)) { const char *aname = _x_buf_audio_name (buf->type); xine_log (stream->s.xine, XINE_LOG_MSG, _("audio_decoder: no plugin available to handle '%s'\n"), aname); if (!_x_meta_info_get (&stream->s, XINE_META_INFO_AUDIOCODEC)) _x_meta_info_set_utf8 (&stream->s, XINE_META_INFO_AUDIOCODEC, aname); buftype_unknown = buf->type; /* fatal error - dispose plugin */ if (stream->audio_decoder_plugin) { _x_free_audio_decoder (&stream->s, stream->audio_decoder_plugin); stream->audio_decoder_plugin = NULL; } } } } } /* if (running_ticket->ticket_revoked) * running_ticket->renew (running_ticket, 0); * running_ticket->release (running_ticket, 0); */ xine_profiler_stop_count (prof_audio_decode); break; case BUFTYPE_BASE (BUF_CONTROL_BASE): switch (BUFTYPE_SUB (buf->type)) { int t; case BUFTYPE_SUB (BUF_CONTROL_HEADERS_DONE): pthread_mutex_lock (&stream->counter.lock); stream->counter.headers_audio++; if (stream->video_thread_created) { /* avoid useless wakes on an incomplete pair */ if (stream->counter.headers_audio <= stream->counter.headers_video) pthread_cond_broadcast (&stream->counter.changed); } else { pthread_cond_broadcast (&stream->counter.changed); } pthread_mutex_unlock (&stream->counter.lock); break; case BUFTYPE_SUB (BUF_CONTROL_START): lprintf ("start\n"); stream->audio_decoder_extra_info->input_normpos = 0; stream->audio_decoder_extra_info->input_time = 0; stream->audio_decoder_extra_info->frame_number = 0; stream->audio_decoder_extra_info->total_time = 0; /* are there any early audio senders like demux_image? */ pthread_mutex_lock (&stream->first_frame.lock); stream->audio_decoder_extra_info->seek_count = seek_count = stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); /* decoder dispose might call port functions */ /* running_ticket->acquire(running_ticket, 0); */ if (stream->audio_decoder_plugin) { lprintf ("close old decoder\n"); stream->keep_ao_driver_open = !!(buf->decoder_flags & BUF_FLAG_GAPLESS_SW); _x_free_audio_decoder (&stream->s, stream->audio_decoder_plugin); stream->audio_decoder_plugin = NULL; stream->audio_type = 0; stream->keep_ao_driver_open = 0; } /* running_ticket->release(running_ticket, 0); */ audio_track_map[0] = AUDIO_TRACK_MAP_END; stream->audio_track_map_entries = 0; if (!(buf->decoder_flags & BUF_FLAG_GAPLESS_SW)) { running_ticket->release (running_ticket, 0); stream->s.metronom->handle_audio_discontinuity (stream->s.metronom, DISC_STREAMSTART, 0); running_ticket->acquire (running_ticket, 0); } buftype_unknown = 0; break; case BUFTYPE_SUB (BUF_CONTROL_END): /* free all held header buffers, see comments below */ _x_free_buf_elements (headers_first); headers_first = NULL; headers_add = &headers_first; headers_replay = NULL; headers_num = 0; /* wait the output fifos to run dry before sending the notification event * to the frontend. this test is only valid if there is only a single * stream attached to the current output port. */ while (1) { int num_bufs, num_streams; /* running_ticket->acquire(running_ticket, 0); */ num_bufs = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_BUFS_IN_FIFO); num_streams = stream->s.audio_out->get_property (stream->s.audio_out, AO_PROP_NUM_STREAMS); /* running_ticket->release(running_ticket, 0); */ if( num_bufs > 0 && num_streams == 1 && !stream->early_finish_event) { running_ticket->release (running_ticket, 0); xine_usec_sleep (10000); running_ticket->acquire (running_ticket, 0); } else break; } running_ticket->release (running_ticket, 0); /* wait for video to reach this marker, if necessary */ pthread_mutex_lock (&stream->counter.lock); stream->counter.finisheds_audio++; lprintf ("reached end marker # %d\n", stream->counter.finisheds_audio); if (stream->video_thread_created) { if (stream->counter.finisheds_audio > stream->counter.finisheds_video) { do { struct timespec ts = {0, 0}; xine_gettime (&ts); ts.tv_sec += 1; /* use timedwait to workaround buggy pthread broadcast implementations */ pthread_cond_timedwait (&stream->counter.changed, &stream->counter.lock, &ts); } while (stream->counter.finisheds_audio > stream->counter.finisheds_video); } else if (stream->counter.finisheds_audio == stream->counter.finisheds_video) { pthread_cond_broadcast (&stream->counter.changed); } } else { pthread_cond_broadcast (&stream->counter.changed); } pthread_mutex_unlock (&stream->counter.lock); stream->s.audio_channel_auto = -1; running_ticket->acquire (running_ticket, 0); break; case BUFTYPE_SUB (BUF_CONTROL_QUIT): /* decoder dispose might call port functions */ /* running_ticket->acquire(running_ticket, 0); */ if (stream->audio_decoder_plugin) { _x_free_audio_decoder (&stream->s, stream->audio_decoder_plugin); stream->audio_decoder_plugin = NULL; stream->audio_type = 0; } /* running_ticket->release(running_ticket, 0); */ audio_track_map[0] = AUDIO_TRACK_MAP_END; stream->audio_track_map_entries = 0; running = 0; break; case BUFTYPE_SUB (BUF_CONTROL_NOP): break; case BUFTYPE_SUB (BUF_CONTROL_RESET_DECODER): lprintf ("reset\n"); if (stream->audio_decoder_plugin) { /* running_ticket->acquire(running_ticket, 0); */ stream->audio_decoder_plugin->reset (stream->audio_decoder_plugin); /* running_ticket->release(running_ticket, 0); */ } break; case BUFTYPE_SUB (BUF_CONTROL_DISCONTINUITY): t = DISC_RELATIVE; goto handle_disc; case BUFTYPE_SUB (BUF_CONTROL_NEWPTS): if (buf->decoder_flags & BUF_FLAG_SEEK) { t = DISC_STREAMSEEK; } else { t = DISC_ABSOLUTE; } handle_disc: pthread_mutex_lock (&stream->first_frame.lock); stream->audio_decoder_extra_info->seek_count = seek_count = stream->first_frame.seek_count; pthread_mutex_unlock (&stream->first_frame.lock); if (stream->audio_decoder_plugin) { /* running_ticket->acquire(running_ticket, 0); */ stream->audio_decoder_plugin->discontinuity (stream->audio_decoder_plugin); /* running_ticket->release(running_ticket, 0); */ } running_ticket->release (running_ticket, 0); stream->s.metronom->handle_audio_discontinuity (stream->s.metronom, t, buf->disc_off); running_ticket->acquire (running_ticket, 0); /* audio_br_discontinuity */ audio_br_lasttime = 0; audio_br_lastsize = 0; break; case BUFTYPE_SUB (BUF_CONTROL_AUDIO_CHANNEL): xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "audio_decoder: suggested switching to stream_id %02x\n", buf->decoder_info[0]); stream->s.audio_channel_auto = buf->decoder_info[0] & 0xff; break; case BUFTYPE_SUB (BUF_CONTROL_RESET_TRACK_MAP): if (stream->audio_track_map_entries) { xine_event_t ui_event; audio_track_map[0] = AUDIO_TRACK_MAP_END; stream->audio_track_map_entries = 0; ui_event.type = XINE_EVENT_UI_CHANNELS_CHANGED; ui_event.data_length = 0; xine_event_send (&stream->s, &ui_event); } break; default: if (buf->type != buftype_unknown) { xine_log (stream->s.xine, XINE_LOG_MSG, _("audio_decoder: error, unknown buffer type: %08x\n"), buf->type); buftype_unknown = buf->type; } } /* case BUFTYPE_BASE (BUF_CONTROL_BASE) */ break; default: if (buf->type != buftype_unknown) { xine_log (stream->s.xine, XINE_LOG_MSG, _("audio_decoder: error, unknown buffer type: %08x\n"), buf->type); buftype_unknown = buf->type; } } /* switch (BUFTYPE_BASE (buf->type)) */ /* some decoders require a full reinitialization when audio * channel is changed (rate might be change and even a * different codec may be used). * * we must close the old decoder and process all the headers * again, since they are needed for decoder initialization. */ if (headers_replay) { headers_replay = headers_replay->next; } else { if (audio_channel_user != stream->audio_channel_user) { audio_channel_user = stream->audio_channel_user; if (stream->audio_decoder_plugin) { /* decoder dispose might call port functions */ /* running_ticket->acquire (running_ticket, 0); */ _x_free_audio_decoder (&stream->s, stream->audio_decoder_plugin); /* running_ticket->release (running_ticket, 0); */ stream->audio_decoder_plugin = NULL; audio_track_map[0] = AUDIO_TRACK_MAP_END; stream->audio_track_map_entries = 0; stream->audio_type = 0; } buf->free_buffer (buf); headers_replay = headers_first; xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "audio_decoder: replaying %d headers.\n", headers_num); } else { /* header buffers are never freed. instead they * are added to a list to allow replaying them * in case of a channel change. */ if (buf->decoder_flags & BUF_FLAG_HEADER) { /* drop outdated headers. */ int num = 0; buf_element_t *here = headers_first, **add = &headers_first; while (here) { buf_element_t *next = here->next; uint32_t d = here->type ^ buf->type; if (((d & 0x0000ffff) == 0) && (((d & 0xffff0000) != 0) || (here->decoder_flags == buf->decoder_flags))) { *add = next; here->next = NULL; here->free_buffer (here); headers_num--; num++; } else { add = &here->next; } here = next; } headers_add = add; if (num) xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "audio_decoder: dropped %d outdated headers for track #%u.\n", num, (unsigned int)(buf->type & 0x0000ffff)); *headers_add = buf; headers_add = &buf->next; buf->next = NULL; headers_num++; } else { buf->free_buffer (buf); } } } } running_ticket->release (running_ticket, 0); /* free all held header buffers */ _x_free_buf_elements (headers_first); return NULL; } int _x_audio_decoder_init (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; if (!stream) return 0; stream = stream->side_streams[0]; if (stream->s.audio_fifo) return 1; if (stream->s.audio_out == NULL) { stream->s.audio_fifo = _x_dummy_fifo_buffer_new (5, 8192); return !!stream->s.audio_fifo; } else { pthread_attr_t pth_attrs; #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0) struct sched_param pth_params; #endif int err; int num_buffers; /* The fifo size is based on dvd playback where buffers are filled * with 2k of data. With 230 buffers and a typical audio data rate * of 1.8 Mbit/s (four ac3 streams), the fifo can hold about 2 seconds * of audio, wich should be enough to compensate for drive delays. * We provide buffers of 8k size instead of 2k for demuxers sending * larger chunks. * TJ. There are live streams with 5...10s fragments. Nice clients fetch * 1 fragment, then wait the gap without blocking the server port all the * time. With 2s reserve and 48k AAC, we need up to 12*48000/1024 = 563 * frame buffers. High bitrate video over a budget connection somewhat * hides the issue, but web radio turns down all excuses. * Lets give away a high multiple of 4 of 2k bufs instead, and LPCM can * still have 8k ones via buffer_pool_size_alloc (). */ num_buffers = stream->s.xine->config->register_num (stream->s.xine->config, "engine.buffers.audio_num_buffers", 700, _("number of audio buffers"), _("The number of audio buffers (each is 2k in size) xine uses in its " "internal queue. Higher values mean smoother playback for unreliable " "inputs, but also increased latency and memory consumption."), 20, NULL, NULL); num_buffers = (num_buffers + 3) & ~4; if (num_buffers > 2000) num_buffers = 2000; stream->s.audio_fifo = _x_fifo_buffer_new (num_buffers, 2048); if (!stream->s.audio_fifo) return 0; stream->audio_channel_user = -1; stream->s.audio_channel_auto = -1; stream->audio_track_map_entries = 0; stream->audio_type = 0; /* future magic - coming soon * stream->audio_temp = lrb_new (100, stream->audio_fifo); */ pthread_attr_init(&pth_attrs); #if defined(_POSIX_THREAD_PRIORITY_SCHEDULING) && (_POSIX_THREAD_PRIORITY_SCHEDULING > 0) pthread_attr_getschedparam(&pth_attrs, &pth_params); pth_params.sched_priority = sched_get_priority_min(SCHED_OTHER); pthread_attr_setschedparam(&pth_attrs, &pth_params); pthread_attr_setscope(&pth_attrs, PTHREAD_SCOPE_SYSTEM); #endif stream->audio_thread_created = 1; if ((err = pthread_create (&stream->audio_thread, &pth_attrs, audio_decoder_loop, stream)) != 0) { xprintf (stream->s.xine, XINE_VERBOSITY_DEBUG, "audio_decoder: can't create new thread (%s)\n", strerror(err)); stream->audio_thread_created = 0; pthread_attr_destroy(&pth_attrs); stream->s.audio_fifo->dispose (stream->s.audio_fifo); stream->s.audio_fifo = NULL; return 0; } pthread_attr_destroy(&pth_attrs); return 1; } } void _x_audio_decoder_shutdown (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; buf_element_t *buf; void *p; if (!stream) return; if (stream->audio_thread_created) { /* stream->audio_fifo->clear(stream->audio_fifo); */ buf = stream->s.audio_fifo->buffer_pool_alloc (stream->s.audio_fifo); buf->type = BUF_CONTROL_QUIT; stream->s.audio_fifo->put (stream->s.audio_fifo, buf); pthread_join (stream->audio_thread, &p); stream->audio_thread_created = 0; } if (stream->s.audio_fifo) { stream->s.audio_fifo->dispose (stream->s.audio_fifo); stream->s.audio_fifo = NULL; } } int _x_get_audio_channel (xine_stream_t *s) { xine_stream_private_t *stream = (xine_stream_private_t *)s; return stream ? (stream->audio_type & 0xFFFF) : 0; } xine-lib-1.2/src/xine-engine/buffer_types.c0000644000175000017500000006631214647725152016532 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * * contents: * * buffer types management. * convert FOURCC and audioformattag to BUF_xxx defines */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "bswap.h" static const uint32_t sorted_audio_tags[] = { 0x0001, BUF_AUDIO_LPCM_LE, 0x0002, BUF_AUDIO_MSADPCM, 0x0006, BUF_AUDIO_ALAW, 0x0007, BUF_AUDIO_MULAW, 0x000A, BUF_AUDIO_WMAV, 0x0011, BUF_AUDIO_MSIMAADPCM, 0x0022, BUF_AUDIO_TRUESPEECH, 0x0031, BUF_AUDIO_MSGSM, 0x0032, BUF_AUDIO_MSGSM, 0x0050, BUF_AUDIO_MPEG, 0x0055, BUF_AUDIO_MPEG, 0x0061, BUF_AUDIO_DK4ADPCM, 0x0062, BUF_AUDIO_DK3ADPCM, 0x0075, BUF_AUDIO_VOXWARE, 0x00ff, BUF_AUDIO_AAC, 0x0111, BUF_AUDIO_VIVOG723, 0x0112, BUF_AUDIO_VIVOG723, 0x0130, BUF_AUDIO_ACELPNET, 0x0160, BUF_AUDIO_WMAV1, 0x0161, BUF_AUDIO_WMAV2, 0x0162, BUF_AUDIO_WMAPRO, 0x0163, BUF_AUDIO_WMALL, 0x0401, BUF_AUDIO_IMC, 0x1101, BUF_AUDIO_LH, 0x1102, BUF_AUDIO_LH, 0x1103, BUF_AUDIO_LH, 0x1104, BUF_AUDIO_LH, 0x2000, BUF_AUDIO_A52, 0x2001, BUF_AUDIO_DTS, /* these formattags are used by Vorbis ACM encoder and * supported by NanDub, a variant of VirtualDub. */ 0x674f, BUF_AUDIO_VORBIS, 0x6750, BUF_AUDIO_VORBIS, 0x6751, BUF_AUDIO_VORBIS, 0x676f, BUF_AUDIO_VORBIS, 0x6770, BUF_AUDIO_VORBIS, 0x6771, BUF_AUDIO_VORBIS }; static const uint32_t sorted_audio_4ccs[] = { BE_FOURCC('.', 'm', 'p', '3'), BUF_AUDIO_MPEG, BE_FOURCC('2', '8', '_', '8'), BUF_AUDIO_28_8, BE_FOURCC('4', '2', 'n', 'i'), BUF_AUDIO_LPCM_LE, BE_FOURCC('A', 'A', 'C', ' '), BUF_AUDIO_AAC, BE_FOURCC('E', 'A', 'C', '3'), BUF_AUDIO_EAC3, BE_FOURCC('M', 'A', 'C', '3'), BUF_AUDIO_MAC3, BE_FOURCC('M', 'A', 'C', '6'), BUF_AUDIO_MAC6, BE_FOURCC('M', 'P', '3', ' '), BUF_AUDIO_MPEG, BE_FOURCC('M', 'P', '4', 'A'), BUF_AUDIO_AAC, BE_FOURCC('M', 'P', '4', 'L'), BUF_AUDIO_AAC_LATM, BE_FOURCC('O', 'g', 'g', 'S'), BUF_AUDIO_VORBIS, BE_FOURCC('O', 'g', 'g', 'V'), BUF_AUDIO_VORBIS, BE_FOURCC('O', 'p', 'u', 's'), BUF_AUDIO_OPUS, BE_FOURCC('Q', 'D', 'M', '2'), BUF_AUDIO_QDESIGN2, BE_FOURCC('Q', 'D', 'M', 'C'), BUF_AUDIO_QDESIGN1, BE_FOURCC('Q', 'c', 'l', 'p'), BUF_AUDIO_QCLP, BE_FOURCC('T', 'T', 'A', '1'), BUF_AUDIO_TTA, BE_FOURCC('W', 'V', 'P', 'K'), BUF_AUDIO_WAVPACK, BE_FOURCC('a', 'c', '-', '3'), BUF_AUDIO_A52, BE_FOURCC('a', 'd', 'u',0x55), BUF_AUDIO_MP3ADU, BE_FOURCC('a', 'g', 's', 'm'), BUF_AUDIO_GSM610, BE_FOURCC('a', 'l', 'a', 'c'), BUF_AUDIO_ALAC, BE_FOURCC('a', 'l', 'a', 'w'), BUF_AUDIO_ALAW, BE_FOURCC('a', 't', 'r', 'c'), BUF_AUDIO_ATRK, BE_FOURCC('c', 'o', 'o', 'k'), BUF_AUDIO_COOK, BE_FOURCC('d', 'n', 'e', 't'), BUF_AUDIO_DNET, BE_FOURCC('e', 'c', '-', '3'), BUF_AUDIO_EAC3, BE_FOURCC('i', 'm', 'a', '4'), BUF_AUDIO_QTIMAADPCM, BE_FOURCC('i', 'n', '2', '4'), BUF_AUDIO_LPCM_BE, BE_FOURCC('l', 'p', 'c', 'J'), BUF_AUDIO_14_4, BE_FOURCC('m', 'a', 'c', '3'), BUF_AUDIO_MAC3, BE_FOURCC('m', 'a', 'c', '6'), BUF_AUDIO_MAC6, BE_FOURCC('m', 'p', '4', 'a'), BUF_AUDIO_AAC, BE_FOURCC('r', 'a', 'a', 'c'), BUF_AUDIO_AAC, BE_FOURCC('r', 'a', 'c', 'p'), BUF_AUDIO_AAC, BE_FOURCC('r', 'a', 'w', ' '), BUF_AUDIO_LPCM_LE, BE_FOURCC('s', 'a', 'm', 'r'), BUF_AUDIO_AMR_NB, BE_FOURCC('s', 'a', 'w', 'b'), BUF_AUDIO_AMR_WB, BE_FOURCC('s', 'i', 'p', 'r'), BUF_AUDIO_SIPRO, BE_FOURCC('s', 'o', 'w', 't'), BUF_AUDIO_LPCM_LE, BE_FOURCC('t', 'r', 'h', 'd'), BUF_AUDIO_TRUEHD, BE_FOURCC('t', 'w', 'o', 's'), BUF_AUDIO_LPCM_BE, BE_FOURCC('u', 'l', 'a', 'w'), BUF_AUDIO_MULAW }; uint32_t _x_formattag_to_buf_audio (uint32_t formattag) { uint32_t t = formattag; if (t & 0xffff0000) { uint32_t b, e, m; #ifndef WORDS_BIGENDIAN t = (t >> 24) | ((t & 0x00ff0000) >> 8) | ((t & 0x0000ff00) << 8) | (t << 24); #endif b = 0; e = sizeof (sorted_audio_4ccs) / sizeof (sorted_audio_4ccs[0]) / 2; m = e >> 1; do { uint32_t f = sorted_audio_4ccs[2 * m]; if (t == f) { return sorted_audio_4ccs[2 * m + 1]; } else if (t < f) { e = m; } else { b = m + 1; } m = (b + e) >> 1; } while (b != e); if ((t & 0xffff0000) != BE_FOURCC('m', 's', 0, 0)) return 0; t &= 0xffff; } { uint32_t b, e, m; b = 0; e = sizeof (sorted_audio_tags) / sizeof (sorted_audio_tags[0]) / 2; m = e >> 1; do { uint32_t f = sorted_audio_tags[2 * m]; if (t == f) { return sorted_audio_tags[2 * m + 1]; } else if (t < f) { e = m; } else { b = m + 1; } m = (b + e) >> 1; } while (b != e); return 0; } } static const uint32_t sorted_video_tags[] = { 0x0001, BUF_VIDEO_MSRLE, 0x0002, BUF_VIDEO_MSRLE /* MS RLE format identifiers */ }; static const uint32_t sorted_video_4ccs[] = { BE_FOURCC(0x02, 0, 0, 0x10), BUF_VIDEO_MPEG, BE_FOURCC('3', 'I', 'V', '1'), BUF_VIDEO_3IVX, BE_FOURCC('3', 'I', 'V', '2'), BUF_VIDEO_3IVX, BE_FOURCC('3', 'I', 'V', 'D'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('8', 'B', 'P', 'S'), BUF_VIDEO_8BPS, BE_FOURCC('A', 'A', 'S', 'C'), BUF_VIDEO_AASC, BE_FOURCC('A', 'P', '4', '1'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('A', 'S', 'V', '1'), BUF_VIDEO_ASV1, BE_FOURCC('A', 'S', 'V', '2'), BUF_VIDEO_ASV2, BE_FOURCC('A', 'V', 'D', 'J'), BUF_VIDEO_MJPEG, BE_FOURCC('A', 'V', 'R', 'n'), BUF_VIDEO_MJPEG, BE_FOURCC('C', 'O', 'L', '1'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('C', 'R', 'A', 'M'), BUF_VIDEO_MSVC, BE_FOURCC('C', 'S', 'C', 'D'), BUF_VIDEO_CSCD, BE_FOURCC('C', 'Y', 'U', 'V'), BUF_VIDEO_CYUV, BE_FOURCC('D', 'I', 'B', ' '), BUF_VIDEO_RGB, /* device-independent bitmap */ BE_FOURCC('D', 'I', 'V', '2'), BUF_VIDEO_MSMPEG4_V2, BE_FOURCC('D', 'I', 'V', '3'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('D', 'I', 'V', '4'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('D', 'I', 'V', '5'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('D', 'I', 'V', '6'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('D', 'I', 'V', 'X'), BUF_VIDEO_MPEG4, BE_FOURCC('D', 'U', 'C', 'K'), BUF_VIDEO_DUCKTM1, BE_FOURCC('D', 'V', 'S', 'D'), BUF_VIDEO_DV, BE_FOURCC('D', 'X', '5', '0'), BUF_VIDEO_DIVX5, BE_FOURCC('D', 'i', 'v', 'X'), BUF_VIDEO_MPEG4, BE_FOURCC('D', 'i', 'v', 'x'), BUF_VIDEO_MPEG4, BE_FOURCC('F', 'M', 'P', '4'), BUF_VIDEO_MPEG4, BE_FOURCC('F', 'P', 'S', '1'), BUF_VIDEO_FPS1, BE_FOURCC('G', 'R', 'E', 'Y'), BUF_VIDEO_GREY, BE_FOURCC('H', '2', '6', '3'), BUF_VIDEO_H263, BE_FOURCC('H', '2', '6', '4'), BUF_VIDEO_H264, BE_FOURCC('H', 'F', 'Y', 'U'), BUF_VIDEO_HUFFYUV, BE_FOURCC('I', '2', '6', '3'), BUF_VIDEO_I263, BE_FOURCC('I', '4', '2', '0'), BUF_VIDEO_I420, BE_FOURCC('I', 'M', 'G', ' '), BUF_VIDEO_IMAGE, BE_FOURCC('I', 'V', '3', '1'), BUF_VIDEO_IV31, BE_FOURCC('I', 'V', '3', '2'), BUF_VIDEO_IV32, BE_FOURCC('I', 'V', '4', '1'), BUF_VIDEO_IV41, BE_FOURCC('I', 'V', '5', '0'), BUF_VIDEO_IV50, BE_FOURCC('I', 'Y', 'U', 'V'), BUF_VIDEO_I420, BE_FOURCC('J', 'F', 'I', 'F'), BUF_VIDEO_JPEG, BE_FOURCC('K', 'M', 'V', 'C'), BUF_VIDEO_KMVC, BE_FOURCC('L', 'O', 'C', 'O'), BUF_VIDEO_LOCO, BE_FOURCC('M', '4', 'S', '2'), BUF_VIDEO_MPEG4, BE_FOURCC('M', 'J', 'P', 'G'), BUF_VIDEO_MJPEG, BE_FOURCC('M', 'P', '4', '1'), BUF_VIDEO_MSMPEG4_V1, /*BE_FOURCC('M', 'P', '4', '1'), BUF_VIDEO_MSMPEG4_V2,*/ BE_FOURCC('M', 'P', '4', '2'), BUF_VIDEO_MSMPEG4_V2, BE_FOURCC('M', 'P', '4', '3'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('M', 'P', '4', 'S'), BUF_VIDEO_MPEG4, BE_FOURCC('M', 'P', 'E', 'G'), BUF_VIDEO_MPEG, BE_FOURCC('M', 'P', 'G', '3'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('M', 'P', 'G', '4'), BUF_VIDEO_MSMPEG4_V1, BE_FOURCC('M', 'S', 'S', '1'), BUF_VIDEO_MSS1, BE_FOURCC('M', 'S', 'V', 'C'), BUF_VIDEO_MSVC, BE_FOURCC('M', 'S', 'Z', 'H'), BUF_VIDEO_MSZH, BE_FOURCC('M', 'V', 'I', '2'), BUF_VIDEO_MVI2, BE_FOURCC('P', 'G', 'V', 'V'), BUF_VIDEO_PGVV, BE_FOURCC('P', 'I', 'M', '1'), BUF_VIDEO_MPEG, BE_FOURCC('P', 'I', 'X', 'L'), BUF_VIDEO_XL, BE_FOURCC('Q', '1', '.', '0'), BUF_VIDEO_QPEG, BE_FOURCC('Q', '1', '.', '1'), BUF_VIDEO_QPEG, BE_FOURCC('Q', 'P', 'E', 'G'), BUF_VIDEO_QPEG, BE_FOURCC('R', 'T', '2', '1'), BUF_VIDEO_RT21, BE_FOURCC('R', 'V', '1', '0'), BUF_VIDEO_RV10, BE_FOURCC('R', 'V', '2', '0'), BUF_VIDEO_RV20, BE_FOURCC('R', 'V', '3', '0'), BUF_VIDEO_RV30, BE_FOURCC('R', 'V', '4', '0'), BUF_VIDEO_RV40, BE_FOURCC('S', 'E', 'G', 'A'), BUF_VIDEO_SEGA, BE_FOURCC('S', 'N', 'O', 'W'), BUF_VIDEO_SNOW, BE_FOURCC('S', 'V', 'Q', '1'), BUF_VIDEO_SORENSON_V1, BE_FOURCC('S', 'V', 'Q', '3'), BUF_VIDEO_SORENSON_V3, BE_FOURCC('T', 'M', '2', '0'), BUF_VIDEO_DUCKTM2, BE_FOURCC('U', '2', '6', '3'), BUF_VIDEO_H263, BE_FOURCC('U', 'C', 'O', 'D'), BUF_VIDEO_UCOD, BE_FOURCC('U', 'L', 'T', 'I'), BUF_VIDEO_ULTI, BE_FOURCC('V', 'C', 'R', '1'), BUF_VIDEO_ATIVCR1, BE_FOURCC('V', 'C', 'R', '2'), BUF_VIDEO_ATIVCR2, BE_FOURCC('V', 'I', 'V', 'O'), BUF_VIDEO_I263, BE_FOURCC('V', 'M', 'n', 'c'), BUF_VIDEO_VMNC, BE_FOURCC('V', 'P', '3', ' '), BUF_VIDEO_VP31, BE_FOURCC('V', 'P', '3', '0'), BUF_VIDEO_VP31, BE_FOURCC('V', 'P', '3', '1'), BUF_VIDEO_VP31, BE_FOURCC('V', 'P', '4', '0'), BUF_VIDEO_VP4, BE_FOURCC('V', 'P', '5', '0'), BUF_VIDEO_VP5, BE_FOURCC('V', 'P', '6', '0'), BUF_VIDEO_VP6, BE_FOURCC('V', 'P', '6', '1'), BUF_VIDEO_VP6, BE_FOURCC('V', 'P', '6', '2'), BUF_VIDEO_VP6, BE_FOURCC('V', 'P', '6', 'F'), BUF_VIDEO_VP6F, BE_FOURCC('V', 'P', '8', '0'), BUF_VIDEO_VP8, BE_FOURCC('V', 'P', '9', '0'), BUF_VIDEO_VP9, BE_FOURCC('W', 'H', 'A', 'M'), BUF_VIDEO_MSVC, BE_FOURCC('W', 'M', 'V', '1'), BUF_VIDEO_WMV7, BE_FOURCC('W', 'M', 'V', '2'), BUF_VIDEO_WMV8, BE_FOURCC('W', 'M', 'V', '3'), BUF_VIDEO_WMV9, BE_FOURCC('W', 'M', 'V', 'A'), BUF_VIDEO_VC1, BE_FOURCC('W', 'M', 'V', 'P'), BUF_VIDEO_WMV9, BE_FOURCC('W', 'N', 'V', '1'), BUF_VIDEO_WNV1, BE_FOURCC('W', 'V', 'C', '1'), BUF_VIDEO_VC1, BE_FOURCC('X', '2', '6', '4'), BUF_VIDEO_H264, BE_FOURCC('X', 'I', 'X', 'L'), BUF_VIDEO_XL, BE_FOURCC('X', 'V', 'I', 'D'), BUF_VIDEO_XVID, BE_FOURCC('X', 'X', 'A', 'N'), BUF_VIDEO_XXAN, BE_FOURCC('X', 'x', 'a', 'n'), BUF_VIDEO_XXAN, BE_FOURCC('Y', 'U', 'Y', '2'), BUF_VIDEO_YUY2, BE_FOURCC('Y', 'V', '1', '2'), BUF_VIDEO_YV12, BE_FOURCC('Y', 'V', 'U', '9'), BUF_VIDEO_YVU9, BE_FOURCC('Z', 'L', 'I', 'B'), BUF_VIDEO_ZLIB, BE_FOURCC('Z', 'M', 'B', 'V'), BUF_VIDEO_ZMBV, BE_FOURCC('Z', 'y', 'G', 'o'), BUF_VIDEO_ZYGO, BE_FOURCC('a', 'v', '0', '1'), BUF_VIDEO_AV1, BE_FOURCC('a', 'v', 'c', '1'), BUF_VIDEO_H264, BE_FOURCC('a', 'z', 'p', 'r'), BUF_VIDEO_RPZA, BE_FOURCC('c', 'r', 'a', 'm'), BUF_VIDEO_MSVC, BE_FOURCC('c', 'v', 'i', 'd'), BUF_VIDEO_CINEPAK, BE_FOURCC('c', 'y', 'u', 'v'), BUF_VIDEO_CYUV, BE_FOURCC('d', 'i', 'v', '2'), BUF_VIDEO_MSMPEG4_V2, BE_FOURCC('d', 'i', 'v', '3'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('d', 'i', 'v', '4'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('d', 'i', 'v', '5'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('d', 'i', 'v', '6'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('d', 'i', 'v', 'x'), BUF_VIDEO_MPEG4, BE_FOURCC('d', 'm', 'b', '1'), BUF_VIDEO_MJPEG, BE_FOURCC('d', 'v', 'c', 'p'), BUF_VIDEO_DV, BE_FOURCC('d', 'v', 's', 'd'), BUF_VIDEO_DV, BE_FOURCC('g', 'i', 'f', ' '), BUF_VIDEO_IMAGE, BE_FOURCC('h', '2', '6', '3'), BUF_VIDEO_H263, BE_FOURCC('h', '2', '6', '4'), BUF_VIDEO_H264, BE_FOURCC('h', 'e', 'v', '1'), BUF_VIDEO_HEVC, BE_FOURCC('h', 'e', 'v', 'c'), BUF_VIDEO_HEVC, BE_FOURCC('h', 'v', 'c', '1'), BUF_VIDEO_HEVC, BE_FOURCC('i', '2', '6', '3'), BUF_VIDEO_I263, BE_FOURCC('i', 'v', '3', '1'), BUF_VIDEO_IV31, BE_FOURCC('i', 'v', '3', '2'), BUF_VIDEO_IV32, BE_FOURCC('i', 'v', '4', '1'), BUF_VIDEO_IV41, BE_FOURCC('i', 'v', '5', '0'), BUF_VIDEO_IV50, BE_FOURCC('j', 'p', 'e', 'g'), BUF_VIDEO_JPEG, BE_FOURCC('m', '4', 's', '2'), BUF_VIDEO_MPEG4, BE_FOURCC('m', 'j', 'p', 'a'), BUF_VIDEO_MJPEG, BE_FOURCC('m', 'j', 'p', 'b'), BUF_VIDEO_MJPEG_B, BE_FOURCC('m', 'p', '4', '1'), BUF_VIDEO_MSMPEG4_V1, /*BE_FOURCC('m', 'p', '4', '1'), BUF_VIDEO_MSMPEG4_V2,*/ BE_FOURCC('m', 'p', '4', '2'), BUF_VIDEO_MSMPEG4_V2, BE_FOURCC('m', 'p', '4', '3'), BUF_VIDEO_MSMPEG4_V3, BE_FOURCC('m', 'p', '4', 'v'), BUF_VIDEO_MPEG4, BE_FOURCC('m', 'p', 'e', 'g'), BUF_VIDEO_MPEG, BE_FOURCC('m', 'p', 'g', '1'), BUF_VIDEO_MPEG, BE_FOURCC('m', 'p', 'g', '2'), BUF_VIDEO_MPEG, BE_FOURCC('m', 'p', 'g', '4'), BUF_VIDEO_MSMPEG4_V1, BE_FOURCC('m', 's', 'v', 'c'), BUF_VIDEO_MSVC, BE_FOURCC('m', 'v', 'i', '2'), BUF_VIDEO_MVI2, BE_FOURCC('p', 'n', 'g', ' '), BUF_VIDEO_PNG, BE_FOURCC('q', 'd', 'r', 'w'), BUF_VIDEO_QDRW, BE_FOURCC('r', 'a', 'w', ' '), BUF_VIDEO_RGB, BE_FOURCC('r', 'l', 'e', ' '), BUF_VIDEO_QTRLE, BE_FOURCC('r', 'p', 'z', 'a'), BUF_VIDEO_RPZA, BE_FOURCC('s', '2', '6', '3'), BUF_VIDEO_H263, BE_FOURCC('s', 'e', 'g', 'a'), BUF_VIDEO_SEGA, BE_FOURCC('s', 'm', 'c', ' '), BUF_VIDEO_SMC, BE_FOURCC('s', 'v', 'q', '1'), BUF_VIDEO_SORENSON_V1, BE_FOURCC('s', 'v', 'q', '3'), BUF_VIDEO_SORENSON_V3, BE_FOURCC('s', 'v', 'q', 'i'), BUF_VIDEO_SORENSON_V1, BE_FOURCC('t', 's', 'c', 'c'), BUF_VIDEO_TSCC, BE_FOURCC('u', 'c', 'o', 'd'), BUF_VIDEO_UCOD, BE_FOURCC('v', 'c', '-', '1'), BUF_VIDEO_VC1, BE_FOURCC('v', 'i', 'v', '1'), BUF_VIDEO_I263, BE_FOURCC('v', 'i', 'v', 'o'), BUF_VIDEO_I263, BE_FOURCC('v', 'p', '3', '0'), BUF_VIDEO_VP31, BE_FOURCC('v', 'p', '3', '1'), BUF_VIDEO_VP31, BE_FOURCC('w', 'h', 'a', 'm'), BUF_VIDEO_MSVC, BE_FOURCC('x', '2', '6', '4'), BUF_VIDEO_H264, BE_FOURCC('x', 'v', 'i', 'd'), BUF_VIDEO_XVID, BE_FOURCC('x', 'x', 'a', 'n'), BUF_VIDEO_XXAN, BE_FOURCC('y', 'u', 'v', '2'), BUF_VIDEO_YUY2, BE_FOURCC('y', 'u', 'y', '2'), BUF_VIDEO_YUY2, BE_FOURCC('y', 'v', '1', '2'), BUF_VIDEO_YV12 }; uint32_t _x_fourcc_to_buf_video (uint32_t formattag) { uint32_t t = formattag; if (t & 0xffff0000) { uint32_t b, e, m; #ifndef WORDS_BIGENDIAN t = (t >> 24) | ((t & 0x00ff0000) >> 8) | ((t & 0x0000ff00) << 8) | (t << 24); #endif b = 0; e = sizeof (sorted_video_4ccs) / sizeof (sorted_video_4ccs[0]) / 2; m = e >> 1; do { uint32_t f = sorted_video_4ccs[2 * m]; if (t == f) { return sorted_video_4ccs[2 * m + 1]; } else if (t < f) { e = m; } else { b = m + 1; } m = (b + e) >> 1; } while (b != e); return 0; } { uint32_t b, e, m; b = 0; e = sizeof (sorted_video_tags) / sizeof (sorted_video_tags[0]) / 2; m = e >> 1; do { uint32_t f = sorted_video_tags[2 * m]; if (t == f) { return sorted_video_tags[2 * m + 1]; } else if (t < f) { e = m; } else { b = m + 1; } m = (b + e) >> 1; } while (b != e); return 0; } } static const char * const video_names[] = { /* 00 BUF_VIDEO_MPEG */ "MPEG 1/2", /* 01 BUF_VIDEO_MPEG4 */ "ISO-MPEG4/OpenDivx", /* 02 BUF_VIDEO_CINEPAK */ "Cinepak", /* 03 BUF_VIDEO_SORENSON_V1 */ "Sorenson Video 1", /* 04 BUF_VIDEO_MSMPEG4_V2 */ "Microsoft MPEG-4 v2", /* 05 BUF_VIDEO_MSMPEG4_V3 */ "Microsoft MPEG-4 v3", /* 06 BUF_VIDEO_MJPEG */ "Motion JPEG", /* 07 BUF_VIDEO_IV50 */ "Indeo Video 5.0", /* 08 BUF_VIDEO_IV41 */ "Indeo Video 4.1", /* 09 BUF_VIDEO_IV32 */ "Indeo Video 3.2", /* 0a BUF_VIDEO_IV31 */ "Indeo Video 3.1", /* 0b BUF_VIDEO_ATIVCR1 */ "ATI VCR1", /* 0c BUF_VIDEO_ATIVCR2 */ "ATI VCR2", /* 0d BUF_VIDEO_I263 */ "I263", /* 0e BUF_VIDEO_RV10 */ "Real Video 1.0", /* 0f BUF_VIDEO_?? */ "(unused type 0x0f)", /* 10 BUF_VIDEO_RGB */ "Raw RGB", /* 11 BUF_VIDEO_YUY2 */ "YUY2", /* 12 BUF_VIDEO_JPEG */ "JPEG", /* 13 BUF_VIDEO_WMV7 */ "Windows Media Video 7", /* 14 BUF_VIDEO_WMV8 */ "Windows Media Video 8", /* 15 BUF_VIDEO_MSVC */ "Microsoft Video 1", /* 16 BUF_VIDEO_DV */ "Sony Digital Video (DV)", /* 17 BUF_VIDEO_REAL */ "REAL", /* 18 BUF_VIDEO_VP31 */ "On2 VP3.1", /* 19 BUF_VIDEO_H263 */ "H263", /* 1a BUF_VIDEO_3IVX */ "3ivx MPEG-4", /* 1b BUF_VIDEO_CYUV */ "Creative YUV", /* 1c BUF_VIDEO_DIVX5 */ "DivX 5", /* 1d BUF_VIDEO_XVID */ "XviD", /* 1e BUF_VIDEO_SMC */ "Apple Quicktime Graphics (SMC)", /* 1f BUF_VIDEO_RPZA */ "Apple Quicktime (RPZA)", /* 20 BUF_VIDEO_QTRLE */ "Apple Quicktime Animation (RLE)", /* 21 BUF_VIDEO_MSRLE */ "Microsoft RLE", /* 22 BUF_VIDEO_DUCKTM1 */ "Duck Truemotion v1", /* 23 BUF_VIDEO_FLI */ "FLI", /* 24 BUF_VIDEO_ROQ */ "Id Software RoQ", /* 25 BUF_VIDEO_SORENSON_V3 */ "Sorenson Video 3", /* 26 BUF_VIDEO_MSMPEG4_V1 */ "Microsoft MPEG-4 v1", /* 27 BUF_VIDEO_MSS1 */ "Windows Screen Video", /* 28 BUF_VIDEO_IDCIN */ "Id Software CIN", /* 29 BUF_VIDEO_PGVV */ "Radius Studio", /* 2a BUF_VIDEO_ZYGO */ "ZyGo Video", /* 2b BUF_VIDEO_TSCC */ "TechSmith Screen Capture Codec", /* 2c BUF_VIDEO_YVU9 */ "Raw YVU9 Planar Data", /* 2d BUF_VIDEO_VQA */ "Westwood Studios VQA", /* 2e BUF_VIDEO_GREY */ "Raw Greyscale", /* 2f BUF_VIDEO_XXAN */ "Wing Commander IV Video Codec", /* 30 BUF_VIDEO_WC3 */ "Xan WC3", /* 31 BUF_VIDEO_YV12 */ "Raw Planar YV12", /* 32 BUF_VIDEO_SEGA */ "Cinepak for Sega", /* 33 BUF_VIDEO_RV20 */ "Real Video 2.0", /* 34 BUF_VIDEO_RV30 */ "Real Video 3.0", /* 35 BUF_VIDEO_MVI2 */ "Motion Pixels", /* 36 BUF_VIDEO_UCOD */ "ClearVideo", /* 37 BUF_VIDEO_WMV9 */ "Windows Media Video 9", /* 38 BUF_VIDEO_INTERPLAY */ "Interplay MVE", /* 39 BUF_VIDEO_RV40 */ "Real Video 4.0", /* 3a BUF_VIDEO_PSX_MDEC */ "PSX MEDC", /* 3b BUF_VIDEO_YUV_FRAMES */ "Uncompressed YUV", /* 3c BUF_VIDEO_HUFFYUV */ "HuffYUV", /* 3d BUF_VIDEO_IMAGE */ "Image", /* 3e BUF_VIDEO_THEORA */ "Ogg Theora", /* 3f BUF_VIDEO_4XM */ "4X Video", /* 40 BUF_VIDEO_I420 */ "Raw Planar I420", /* 41 BUF_VIDEO_VP4 */ "On2 VP4", /* 42 BUF_VIDEO_VP5 */ "On2 VP5", /* 43 BUF_VIDEO_VP6 */ "On2 VP6", /* 44 BUF_VIDEO_VMD */ "Sierra VMD Video", /* 45 BUF_VIDEO_MSZH */ "MSZH Video", /* 46 BUF_VIDEO_ZLIB */ "ZLIB Video", /* 47 BUF_VIDEO_8BPS */ "Planar RGB", /* 48 BUF_VIDEO_ASV1 */ "ASV v1 Video", /* 49 BUF_VIDEO_ASV2 */ "ASV v2 Video", /* 4a BUF_VIDEO_BITPLANE */ "Amiga picture", /* 4b BUF_VIDEO_BITPLANE_BR1*/ "Amiga picture", /* 4c BUF_VIDEO_FLV1 */ "Flash video 1", /* 4d BUF_VIDEO_H264 */ "Advanced Video Coding (H264)", /* 4e BUF_VIDEO_MJPEG_B */ "Motion JPEG B", /* 4f BUF_VIDEO_H261 */ "H.261", /* 50 BUF_VIDEO_AASC */ "Autodesk Animator Studio Codec", /* 51 BUF_VIDEO_LOCO */ "LOCO", /* 52 BUF_VIDEO_QDRW */ "QuickDraw", /* 53 BUF_VIDEO_QPEG */ "Q-Team QPEG Video", /* 54 BUF_VIDEO_ULTI */ "IBM UltiMotion", /* 55 BUF_VIDEO_WNV1 */ "Winnow Video", /* 56 BUF_VIDEO_XL */ "Miro/Pinnacle VideoXL", /* 57 BUF_VIDEO_RT21 */ "Indeo/RealTime 2", /* 58 BUF_VIDEO_FPS1 */ "Fraps FPS1", /* 59 BUF_VIDEO_DUCKTM2 */ "Duck TrueMotion 2", /* 5a BUF_VIDEO_CSCD */ "CamStudio", /* 5b BUF_VIDEO_ALGMM */ "American Laser Games MM", /* 5c BUF_VIDEO_ZMBV */ "Zip Motion Blocks Video", /* 5d BUF_VIDEO_AVS */ "AVS", /* 5e BUF_VIDEO_SMACKER */ "Smacker", /* 5f BUF_VIDEO_NUV */ "NullSoft Video", /* 60 BUF_VIDEO_KMVC */ "Karl Morton's Video Codec", /* 61 BUF_VIDEO_FLASHSV */ "Flash Screen Video 1", /* 62 BUF_VIDEO_CAVS */ "Chinese AVS", /* 63 BUF_VIDEO_VP6F */ "On2 VP6 with alpha channel", /* 64 BUF_VIDEO_THEORA_RAW */ "Theora", /* 65 BUF_VIDEO_VC1 */ "Windows Media Video VC-1", /* 66 BUF_VIDEO_VMNC */ "VMware Screen Codec", /* 67 BUF_VIDEO_SNOW */ "Snow", /* 68 BUF_VIDEO_VP8 */ "On2 VP8", /* 69 BUF_VIDEO_VP9 */ "VP9", /* 6a BUF_VIDEO_HEVC */ "HEVC", /* 6b BUF_VIDEO_AV1 */ "AV1", /* 6c BUF_VIDEO_PNG */ "PNG", }; const char *_x_buf_video_name (uint32_t buf_type) { if ((buf_type & 0xff000000) != BUF_VIDEO_BASE) return ""; buf_type = (buf_type >> 16) & 0xff; if (buf_type >= sizeof (video_names) / sizeof (video_names[0])) return ""; return video_names[buf_type]; } static const char * const audio_names[] = { /* 00 BUF_AUDIO_A52 */ "AC3/A52", /* 01 BUF_AUDIO_MPEG */ "MPEG layer 1/2/3", /* 02 BUF_AUDIO_LPCM_BE */ "Linear PCM big endian", /* 03 BUF_AUDIO_LPCM_LE */ "Linear PCM little endian", /* 04 BUF_AUDIO_WMAV1 */ "Windows Media Audio v1", /* 05 BUF_AUDIO_DTS */ "Digitales TonSystem (DTS)", /* 06 BUF_AUDIO_MSADPCM */ "MS ADPCM", /* 07 BUF_AUDIO_MSIMAADPCM */ "MS IMA ADPCM", /* 08 BUF_AUDIO_MSGSM */ "MS GSM", /* 09 BUF_AUDIO_VORBIS */ "OggVorbis Audio", /* 0a BUF_AUDIO_IMC */ "Intel Music Coder", /* 0b BUF_AUDIO_LH */ "Lernout & Hauspie", /* 0c BUF_AUDIO_VOXWARE */ "Voxware Metasound", /* 0d BUF_AUDIO_ACELPNET */ "ACELP.net", /* 0e BUF_AUDIO_AAC */ "Advanced Audio Coding (MPEG-4 AAC)", /* 0f BUF_AUDIO_DNET */ "RealAudio DNET", /* 10 BUF_AUDIO_VIVOG723 */ "Vivo G.723/Siren Audio Codec", /* 11 BUF_AUDIO_DK3ADPCM */ "Duck DK3 ADPCM (rogue format number)", /* 12 BUF_AUDIO_DK4ADPCM */ "Duck DK4 ADPCM (rogue format number)", /* 13 BUF_AUDIO_ROQ */ "RoQ DPCM", /* 14 BUF_AUDIO_QTIMAADPCM */ "QT IMA ADPCM", /* 15 BUF_AUDIO_MAC3 */ "Apple MACE 3:1 Audio", /* 16 BUF_AUDIO_MAC6 */ "Apple MACE 6:1 Audio", /* 17 BUF_AUDIO_QDESIGN1 */ "QDesign Audio v1", /* 18 BUF_AUDIO_QDESIGN2 */ "QDesign Audio v2", /* 19 BUF_AUDIO_QCLP */ "Qualcomm PureVoice", /* 1a BUF_AUDIO_SMJPEG_IMA */ "SMJPEG IMA", /* 1b BUF_AUDIO_VQA_IMA */ "Westwood Studios IMA", /* 1c BUF_AUDIO_MULAW */ "mu-law logarithmic PCM", /* 1d BUF_AUDIO_ALAW */ "A-law logarithmic PCM", /* 1e BUF_AUDIO_GSM610 */ "GSM 6.10", /* 1f BUF_AUDIO_EA_ADPCM */ "EA ADPCM", /* 20 BUF_AUDIO_WMAV2 */ "Windows Media Audio v2", /* 21 BUF_AUDIO_COOK */ "RealAudio COOK", /* 22 BUF_AUDIO_ATRK */ "RealAudio ATRK", /* 23 BUF_AUDIO_14_4 */ "RealAudio 14.4", /* 24 BUF_AUDIO_28_8 */ "RealAudio 28.8", /* 25 BUF_AUDIO_SIPRO */ "RealAudio SIPRO", /* 26 BUF_AUDIO_WMAPRO */ "Windows Media Audio Professional", /* 27 BUF_AUDIO_INTERPLAY */ "Interplay DPCM", /* 28 BUF_AUDIO_XA_ADPCM */ "XA ADPCM", /* 29 BUF_AUDIO_WESTWOOD */ "Westwood", /* 2a BUF_AUDIO_DIALOGIC_IMA*/ "DIALOGIC IMA", /* 2b BUF_AUDIO_NSF */ "Nosefart", /* 2c BUF_AUDIO_FLAC */ "Free Lossless Audio Codec (FLAC)", /* 2d BUF_AUDIO_DV */ "DV Audio", /* 2e BUF_AUDIO_WMAV */ "Windows Media Audio Voice", /* 2f BUF_AUDIO_SPEEX */ "Speex", /* 30 BUF_AUDIO_RAWPCM */ "Raw PCM", /* 31 BUF_AUDIO_4X_ADPCM */ "4x ADPCM", /* 32 BUF_AUDIO_VMD */ "VMD", /* 33 BUF_AUDIO_XAN_DPCM */ "XAN DPCM", /* 34 BUF_AUDIO_ALAC */ "Apple Lossless Audio Codec", /* 35 BUF_AUDIO_MPC */ "Musepack", /* 36 BUF_AUDIO_SHORTEN */ "Shorten", /* 37 BUF_AUDIO_WESTWOOD_SND1*/ "Westwood", /* 38 BUF_AUDIO_WMALL */ "Windows Media Audio Lossless", /* 39 BUF_AUDIO_TRUESPEECH */ "Truespeech", /* 3a BUF_AUDIO_TTA */ "True Audio Lossless", /* 3b BUF_AUDIO_SMACKER */ "Smacker", /* 3c BUF_AUDIO_FLVADPCM */ "FLV ADPCM", /* 3d BUF_AUDIO_WAVPACK */ "Wavpack", /* 3e BUF_AUDIO_MP3ADU */ "MPEG layer-3 adu", /* 3f BUF_AUDIO_AMR_NB */ "AMR narrow band", /* 40 BUF_AUDIO_AMR_WB */ "AMR wide band", /* 41 BUF_AUDIO_EAC3 */ "E-AC-3", /* 42 BUF_AUDIO_AAC_LATM */ "AAC LATM", /* 43 BUF_AUDIO_ADPCM_G726 */ "ADPCM G.726", /* 44 BUF_AUDIO_OPUS */ "Opus Audio", /* 45 BUF_AUDIO_TRUEHD */ "TrueHD Audio" }; const char *_x_buf_audio_name (uint32_t buf_type) { if ((buf_type & 0xff000000) != BUF_AUDIO_BASE) return ""; buf_type = (buf_type >> 16) & 0xff; if (buf_type >= sizeof (audio_names) / sizeof (audio_names[0])) return ""; return audio_names[buf_type]; } static void code_to_text (char ascii[5], uint32_t code) { int i; for (i = 0; i < 4; ++i) { int byte = code & 0xFF; ascii[i] = (byte < ' ') ? ' ' : (byte >= 0x7F) ? '.' : (char) byte; code >>= 8; } ascii[4] = 0; } void _x_report_video_fourcc (xine_t *xine, const char *module, uint32_t code) { if (code) { char ascii[5]; code_to_text (ascii, code); xprintf (xine, XINE_VERBOSITY_LOG, _("%s: unknown video FourCC code %#x \"%s\"\n"), module, code, ascii); } } void _x_report_audio_format_tag (xine_t *xine, const char *module, uint32_t code) { if (code) { char ascii[5]; code_to_text (ascii, code); xprintf (xine, XINE_VERBOSITY_LOG, _("%s: unknown audio format tag code %#x \"%s\"\n"), module, code, ascii); } } void _x_bmiheader_le2me( xine_bmiheader *bih ) { /* OBS: fourcc must be read using machine endianness * so don't play with biCompression here! */ bih->biSize = le2me_32(bih->biSize); bih->biWidth = le2me_32(bih->biWidth); bih->biHeight = le2me_32(bih->biHeight); bih->biPlanes = le2me_16(bih->biPlanes); bih->biBitCount = le2me_16(bih->biBitCount); bih->biSizeImage = le2me_32(bih->biSizeImage); bih->biXPelsPerMeter = le2me_32(bih->biXPelsPerMeter); bih->biYPelsPerMeter = le2me_32(bih->biYPelsPerMeter); bih->biClrUsed = le2me_32(bih->biClrUsed); bih->biClrImportant = le2me_32(bih->biClrImportant); } void _x_waveformatex_le2me( xine_waveformatex *wavex ) { wavex->wFormatTag = le2me_16(wavex->wFormatTag); wavex->nChannels = le2me_16(wavex->nChannels); wavex->nSamplesPerSec = le2me_32(wavex->nSamplesPerSec); wavex->nAvgBytesPerSec = le2me_32(wavex->nAvgBytesPerSec); wavex->nBlockAlign = le2me_16(wavex->nBlockAlign); wavex->wBitsPerSample = le2me_16(wavex->wBitsPerSample); wavex->cbSize = le2me_16(wavex->cbSize); } size_t _x_tag32_me2str (char *s, uint32_t tag) { static const uint8_t tab_hex[16] = "0123456789abcdef"; union {uint32_t w; uint8_t b[4];} u; uint8_t *q = (uint8_t *)s; int i; if (!q) return 0; u.w = tag; for (i = 0; i < 4; i++) { uint8_t z = u.b[i]; if ((z < 32) || (z > 127)) { *q++ = '\\'; *q++ = 'x'; *q++ = tab_hex[z >> 4]; *q++ = tab_hex[z & 15]; } else if (z == '\\') { *q++ = '\\'; *q++ = '\\'; } else { *q++ = z; } } *q = 0; return q - (uint8_t *)s; } xine-lib-1.2/src/xine-engine/ffmpeg_bswap.h0000644000175000017500000000753414647725152016503 0ustar meme/* * 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 bswap.h * byte swap. */ #ifndef __FFMPEG_BSWAP_H__ #define __FFMPEG_BSWAP_H__ #ifdef HAVE_BYTESWAP_H #include #else #if defined(ARCH_X86_X32) || defined(ARCH_X86_64) # define LEGACY_REGS "=Q" #else # define LEGACY_REGS "=q" #endif #if defined(ARCH_X86) static always_inline uint16_t bswap_16(uint16_t x) { __asm("rorw $8, %0" : LEGACY_REGS (x) : "0" (x)); return x; } static always_inline uint32_t bswap_32(uint32_t x) { #if __CPU__ != 386 __asm("bswap %0": "=r" (x) : #else __asm("xchgb %b0,%h0\n" " rorl $16,%0\n" " xchgb %b0,%h0": LEGACY_REGS (x) : #endif "0" (x)); return x; } static inline uint64_t bswap_64(uint64_t x) { #if defined(ARCH_X86_X32) || defined(ARCH_X86_64) __asm("bswap %0": "=r" (x) : "0" (x)); return x; #else union { uint64_t ll; struct { uint32_t l,h; } l; } r; r.l.l = bswap_32 (x); r.l.h = bswap_32 (x>>32); return r.ll; #endif } #elif defined(ARCH_SH4) static always_inline uint16_t bswap_16(uint16_t x) { __asm__("swap.b %0,%0":"=r"(x):"0"(x)); return x; } static always_inline uint32_t bswap_32(uint32_t x) { __asm__( "swap.b %0,%0\n" "swap.w %0,%0\n" "swap.b %0,%0\n" :"=r"(x):"0"(x)); return x; } static inline uint64_t bswap_64(uint64_t x) { union { uint64_t ll; struct { uint32_t l,h; } l; } r; r.l.l = bswap_32 (x); r.l.h = bswap_32 (x>>32); return r.ll; } #else static always_inline uint16_t bswap_16(uint16_t x){ return (x>>8) | (x<<8); } #ifdef ARCH_ARM static always_inline uint32_t bswap_32(uint32_t x){ 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)); return x; } #else static always_inline uint32_t bswap_32(uint32_t x){ x= ((x<<8)&0xFF00FF00) | ((x>>8)&0x00FF00FF); return (x>>16) | (x<<16); } #endif static inline uint64_t bswap_64(uint64_t x) { #if 0 x= ((x<< 8)&0xFF00FF00FF00FF00ULL) | ((x>> 8)&0x00FF00FF00FF00FFULL); x= ((x<<16)&0xFFFF0000FFFF0000ULL) | ((x>>16)&0x0000FFFF0000FFFFULL); return (x>>32) | (x<<32); #else union { uint64_t ll; uint32_t l[2]; } w, r; w.ll = x; r.l[0] = bswap_32 (w.l[1]); r.l[1] = bswap_32 (w.l[0]); return r.ll; #endif } #endif /* !ARCH_X86 */ #endif /* !HAVE_BYTESWAP_H */ // be2me ... BigEndian to MachineEndian // le2me ... LittleEndian to MachineEndian #ifdef WORDS_BIGENDIAN #define be2me_16(x) (x) #define be2me_32(x) (x) #define be2me_64(x) (x) #define le2me_16(x) bswap_16(x) #define le2me_32(x) bswap_32(x) #define le2me_64(x) bswap_64(x) #else #define be2me_16(x) bswap_16(x) #define be2me_32(x) bswap_32(x) #define be2me_64(x) bswap_64(x) #define le2me_16(x) (x) #define le2me_32(x) (x) #define le2me_64(x) (x) #endif #endif /* __BSWAP_H__ */ xine-lib-1.2/src/xine-engine/input_rip.c0000644000175000017500000007543114647725152016050 0ustar meme/* * Copyright (C) 2000-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Rip Input Plugin for catching streams * * It saves raw data into file as go from input plugins. * * Usage: * * - activation: * xine stream_mrl#save:file.raw * * - it's possible speeder saving streams in the xine without playing: * xine stream_mrl#save:file.raw\;noaudio\;novideo */ /* TODO: * - resume feature (via #append) * - gui activation (after restarting playback) */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #ifdef HAVE_LIBGEN_H #include #endif #include #include #include #define LOG_MODULE "input_rip" #define LOG_VERBOSE /* #define LOG */ #ifdef WIN32 # define CLR_FAIL "" # define CLR_RST "" #else # define CLR_FAIL "\x1b[1;31m" # define CLR_RST "\x1b[0;39m" #endif #include #include #include #include "xine_private.h" #ifndef HAVE_FSEEKO # define fseeko fseek #endif #define SCRATCH_SIZE 1024 #define MAX_TARGET_LEN 512 #define SEEK_TIMEOUT 2.5 typedef struct rip_input_plugin_s { input_plugin_t input_plugin; /* inherited structure */ input_plugin_t *main_input_plugin; /* original input plugin */ xine_mfrag_list_t *fraglist; /* bypass main input for backseek */ xine_stream_t *stream; char *fname; FILE *file; /* destination file */ FILE *rfile; /* avoid lots of seeking if possible */ char *preview; /* preview data */ size_t preview_size; /* size of read preview data */ off_t curpos; /* current position */ off_t savepos; /* amount of already saved data */ off_t endpos; /* skip useless "recording done" msgs */ ssize_t (*read) (struct rip_input_plugin_s *this, char *buf, size_t len); int regular; /* permit reading from the file */ int behind; /* 0 (off), 1 (with), 2 (without read ahead) */ } rip_input_plugin_t; /* read from main file */ static ssize_t rip_read_file_read_1a (rip_input_plugin_t *this, char *buf, size_t len) { size_t r = fread (buf, 1, len, this->file); this->curpos += r; if (this->curpos == this->savepos) { this->behind = 0; /* yes this is set_already, but we like to enable shared code optimization. */ this->read = rip_read_file_read_1a; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_rip: live again.\n"); } if (r != len) { int e = errno; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: reading of saved data failed: %s\n"), strerror (e)); } return r; } /* read from main file, and reseek */ static ssize_t rip_read_file_read_1b (rip_input_plugin_t *this, char *buf, size_t len) { size_t r = 0; if (!fseeko (this->file, this->curpos, SEEK_SET)) { r = fread (buf, 1, len, this->file); this->curpos += r; } fseeko (this->file, this->savepos, SEEK_SET); if (this->curpos == this->savepos) { this->behind = 0; this->read = rip_read_file_read_1a; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_rip: live again.\n"); } if (r != len) { int e = errno; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: reading of saved data failed: %s\n"), strerror (e)); } return r; } /* read from clone */ static ssize_t rip_read_file_read_2 (rip_input_plugin_t *this, char *buf, size_t len) { size_t r = fread (buf, 1, len, this->rfile); if (r < len) { fflush (this->file); r = fread (buf, 1, len, this->rfile); } this->curpos += r; if (this->curpos == this->savepos) { fclose (this->rfile); this->rfile = NULL; this->behind = 0; this->read = rip_read_file_read_1a; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_rip: live again.\n"); } if (r != len) { int e = errno; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: reading of saved data failed: %s\n"), strerror (e)); } return r; } static int rip_read_file_start (rip_input_plugin_t *this, off_t offs1) { int mode = (this->main_input_plugin->get_capabilities (this->main_input_plugin) & INPUT_CAP_LIVE) ? 2 : 1; off_t offs2 = offs1 < (off_t)this->preview_size ? (off_t)this->preview_size : offs1; if (mode == 1) { if (!this->rfile && this->fname) { fflush (this->file); this->rfile = fopen (this->fname, "rb"); } if (this->rfile) { if (fseeko (this->rfile, offs2, SEEK_SET)) { fclose (this->rfile); this->rfile = NULL; } } } else { if (this->rfile) { fclose (this->rfile); this->rfile = NULL; } } if (this->rfile) { this->read = rip_read_file_read_2; } else { if (fseeko (this->file, offs2, SEEK_SET)) { int e = errno; fseeko (this->file, this->savepos, SEEK_SET); xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: seeking failed: %s\n"), strerror (e)); return 0; } if (mode == 1) { fseeko (this->file, this->savepos, SEEK_SET); this->read = rip_read_file_read_1b; } else { this->read = rip_read_file_read_1a; } } this->curpos = offs1; this->behind = mode; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_rip: reading from %s%s after backseek.\n", this->rfile ? "clone of " : "", this->fname ? this->fname : "save file"); return 1; } static void rip_read_file_set_2 (rip_input_plugin_t *this) { this->behind = 2; if (this->rfile) { fclose (this->rfile); this->rfile = NULL; } fseeko (this->file, this->curpos, SEEK_SET); this->read = rip_read_file_read_1a; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_rip: end of main input, still reading from %s.\n", this->fname ? this->fname : "save file"); } /* * read data from input plugin and write it into file */ static off_t rip_plugin_read(input_plugin_t *this_gen, void *buf_gen, off_t len) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; char *buf = (char *)buf_gen; off_t d; size_t left; lprintf("reading %"PRId64" bytes (curpos = %"PRId64", savepos = %"PRId64")\n", len, this->curpos, this->savepos); /* bail out on bogus args */ if (!buf || (len < 0)) return -1; if (len == 0) return 0; left = len; d = this->savepos - this->curpos; if (d > 0) { if (this->curpos < (off_t)this->preview_size) { /* get from preview */ size_t s2 = this->preview_size - this->curpos; if (left < s2) s2 = left; memcpy (buf, this->preview + this->curpos, s2); buf += s2; this->curpos += s2; left -= s2; if (left == 0) return s2; } d = this->savepos - this->curpos; } /* gcc jump target optimize here ;-) */ if (d > 0) { /* NOTE: size_t (unsigned) may be same size or smaller than off_t (signed). */ size_t s2 = left; d -= (off_t)left; if (this->behind) { if (d > 0) { /* Hair raising naive HACK: * read and append left bytes as usual, then return left older bytes from the file. * this shall help with inputs that tend to lose track when seeking. * OK at least we dont try this in real live mode (behind == 2). bitrate fluctuations * and repeated reads like .mp4 fragment scans disharmonize with strict live timing. */ if (this->behind == 1) { ssize_t r = this->main_input_plugin->read (this->main_input_plugin, buf, s2); if (r > 0) { size_t w = fwrite (buf, 1, r, this->file); this->savepos += w; } else { /* dont stop yet, we still got the rest of the file, * and maybe more seeks. */ rip_read_file_set_2 (this); if (this->savepos != this->endpos) { this->endpos = this->savepos; _x_message (this->stream, XINE_MSG_RECORDING_DONE, this->main_input_plugin->get_mrl (this->main_input_plugin), this->fname, NULL); } } } } else { /* catch up now */ s2 += d; } s2 = this->read (this, buf, s2); buf += s2; } else { ssize_t r; if (d < 0) s2 += d; /* read from main input */ if (this->main_input_plugin->seek (this->main_input_plugin, this->curpos, SEEK_SET) != this->curpos) return -1; r = this->main_input_plugin->read (this->main_input_plugin, buf, s2); if (r != (ssize_t)s2) { if (r > 0) this->curpos += r; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: reading by input plugin failed\n")); return r; } buf += s2; this->curpos += s2; } left -= s2; if (this->curpos == this->savepos) { /* take care of non_seekable _fragments_. */ if (this->main_input_plugin->get_current_pos (this->main_input_plugin) != this->savepos) { off_t have = this->main_input_plugin->seek (this->main_input_plugin, this->savepos, SEEK_SET); if (have >= 0) { have = this->savepos - have; if (have > 0) { char temp[4096]; this->savepos -= have; if (fseeko (this->file, this->savepos, SEEK_SET)) return -1; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "input_rip: re-reading %" PRId64 " bytes.\n", (int64_t)have); while (have > 0) { ssize_t r = have > (off_t)sizeof (temp) ? (off_t)sizeof (temp) : have; r = this->main_input_plugin->read (this->main_input_plugin, temp, r); if (r <= 0) break; have -= r; r = fwrite (temp, 1, r, this->file); this->savepos += r; } } } } /* some stdio implementations need an fseek () between read and write. */ if (fseeko (this->file, this->savepos, SEEK_SET)) return -1; } if (left == 0) return buf - (char *)buf_gen; } { /* read from main input, and save to file */ size_t w = 0; int ew = 0; ssize_t r = this->main_input_plugin->read (this->main_input_plugin, buf, left); if (r > 0) { this->curpos += r; w = fwrite (buf, 1, r, this->file); buf += r; ew = errno; if (w > 0) this->savepos += w; } if (r != (ssize_t)left) { xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: reading by input plugin failed\n")); return r; } if ((ssize_t)w != r) { xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: error writing to file %" PRIdMAX " bytes: %s\n"), (intmax_t)r, strerror (ew)); return -1; } } return buf - (char *)buf_gen; } /* * open should never be called */ static int rip_plugin_open(input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: open() function should never be called\n")); return 0; } /* * set preview and/or seek capability when it's implemented by RIP */ static uint32_t rip_plugin_get_capabilities(input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; uint32_t caps; caps = this->main_input_plugin->get_capabilities(this->main_input_plugin); if (this->regular) caps |= INPUT_CAP_SEEKABLE; if (this->preview) caps |= INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW; return caps; } /* * read a block of data from input plugin and write it into file * * This rip plugin returns block unchanged from main input plugin. But special * cases are reading over preview or reading already saved data - it returns * own allocated block. */ static buf_element_t *rip_plugin_read_block(input_plugin_t *this_gen, fifo_buffer_t *fifo, off_t len) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; size_t left; lprintf("reading %"PRId64" bytes (curpos = %"PRId64", savepos = %"PRId64") (block)\n", len, this->curpos, this->savepos); /* bail out on bogus args */ if (!fifo || (len <= 0)) return NULL; left = len; if (this->curpos < this->savepos) { buf_element_t *buf = NULL; char *q = NULL; off_t d; size_t s2; if ((this->curpos < (off_t)this->preview_size) || this->regular) { buf = fifo->buffer_pool_alloc (fifo); buf->content = buf->mem; buf->type = BUF_DEMUX_BLOCK; buf->size = 0; if (buf->max_size < (int)left) left = buf->max_size; q = buf->content; } if (this->curpos < (off_t)this->preview_size) { /* get from preview */ s2 = this->preview_size - this->curpos; if (left < s2) s2 = left; memcpy (q, this->preview + this->curpos, s2); q += s2; buf->size = s2; this->curpos += s2; left -= s2; if ((left == 0) || !this->regular) return buf; } d = this->savepos - this->curpos; s2 = d <= (off_t)(~(size_t)0) ? (size_t)d : ~(size_t)0; if (left < s2) s2 = left; if (this->behind) { /* get from saved file */ size_t r = this->read (this, q, s2); buf->size += r; return buf; } /* read from main input */ buf = this->main_input_plugin->read_block (this->main_input_plugin, fifo, s2); if (buf && (buf->size > 0)) { this->curpos += buf->size; if (buf->size > (int)s2) { /* paranoia?? */ left = buf->size - s2; s2 = fwrite (buf->content + s2, 1, left, this->file); this->savepos += s2; if (s2 != left) { int ew = errno; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: error writing to file %" PRIdMAX " bytes: %s\n"), (intmax_t)left, strerror (ew)); } } } return buf; } { /* read from main input, and save to file */ buf_element_t *buf = this->main_input_plugin->read_block (this->main_input_plugin, fifo, left); if (buf && (buf->size > 0)) { size_t r; this->curpos += buf->size; r = fwrite (buf->content, 1, buf->size, this->file); this->savepos += r; if ((int)r != buf->size) { int ew = errno; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: error writing to file %" PRIdMAX " bytes: %s\n"), (intmax_t)buf->size, strerror (ew)); } } return buf; } } static off_t rip_seek_original(rip_input_plugin_t *this, off_t reqpos) { off_t pos; lprintf(" => seeking original input plugin to %"PRId64"\n", reqpos); pos = this->main_input_plugin->seek(this->main_input_plugin, reqpos, SEEK_SET); if (pos == -1) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: seeking failed\n")); return -1; } #ifdef LOG if (pos != reqpos) { lprintf(CLR_FAIL " => reqested position %"PRId64" differs from result position %"PRId64"" CLR_RST "\n", reqpos, pos); } #endif this->curpos = pos; return pos; } /* * seek in RIP * * If we are seeking back and we can read from saved file, * position of original input plugin isn't changed. */ static off_t rip_plugin_seek(input_plugin_t *this_gen, off_t offset, int origin) { char buffer[SCRATCH_SIZE]; rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; uint32_t blocksize; off_t newpos, pos; struct timeval time1, time2; double interval = 0; lprintf("seek, offset %"PRId64", origin %d (curpos %"PRId64", savepos %"PRId64")\n", offset, origin, this->curpos, this->savepos); switch (origin) { case SEEK_SET: newpos = offset; break; case SEEK_CUR: newpos = this->curpos + offset; break; default: newpos = this->curpos; } /* align the new position down to block sizes */ if( this_gen->get_capabilities(this_gen) & INPUT_CAP_BLOCK ) { blocksize = this_gen->get_blocksize(this_gen); newpos = (newpos / blocksize) * blocksize; } else blocksize = 0; if (newpos < this->savepos) { lprintf(" => virtual seeking from %"PRId64" to %"PRId64"\n", this->curpos, newpos); if (this->regular) { if (!rip_read_file_start (this, newpos)) return -1; } else { /* don't seek into preview area */ off_t reqpos = newpos < (off_t)this->preview_size ? (off_t)this->preview_size : newpos; if ((pos = rip_seek_original(this, reqpos)) == -1) return -1; if (pos == reqpos) this->curpos = newpos; } return this->curpos; } if (this->curpos < this->savepos) { lprintf(" => seeking to end: %"PRId64"\n", this->savepos); if (this->regular) { lprintf(" => seeking file to end: %"PRId64"\n", this->savepos); if (fseeko(this->file, this->savepos, SEEK_SET) != 0) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: seeking failed: %s\n"), strerror(errno)); return -1; } this->curpos = this->savepos; } else { if ((pos = rip_seek_original(this, this->savepos)) == -1) return -1; if (pos > this->savepos) xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: %" PRIdMAX " bytes dropped\n"), (intmax_t)(pos - this->savepos)); } } /* read and catch remaining data after this->savepos */ xine_monotonic_clock(&time1, NULL); while (this->curpos < newpos && interval < SEEK_TIMEOUT) { if( blocksize ) { buf_element_t *buf; buf = rip_plugin_read_block(this_gen, this->stream->video_fifo, blocksize); if (buf) buf->free_buffer(buf); else break; } else { size_t toread = newpos - this->curpos; if( toread > sizeof(buffer) ) toread = sizeof(buffer); if( rip_plugin_read(this_gen, buffer, toread) <= 0 ) { xine_log(this->stream->xine, XINE_LOG_MSG, _("input_rip: seeking failed\n")); break; } } xine_monotonic_clock(&time2, NULL); interval = (double)(time2.tv_sec - time1.tv_sec) + (double)(time2.tv_usec - time1.tv_usec) / 1000000; } lprintf(" => new position %"PRId64"\n", this->curpos); return this->curpos; } static off_t rip_plugin_seek_time(input_plugin_t *this_gen, int time_offset, int origin) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; off_t r; lprintf("seek_time, time_offset: %d, origin: %d\n", time_offset, origin); /* HACK: if we have a fragment index, ask for byte offset directly, * and keep main input running at the head. */ do { int idx; int64_t timebase, timepos, offs; if (!this->regular) break; if (!this->fraglist) break; timebase = 0; xine_mfrag_get_index_frag (this->fraglist, 0, &timebase, NULL); if (timebase <= 0) break; switch (origin) { case SEEK_CUR: idx = xine_mfrag_find_pos (this->fraglist, this->curpos); goto _rip_time_seek_list; case SEEK_END: idx = xine_mfrag_get_frag_count (this->fraglist) + 1; _rip_time_seek_list: timepos = 0; xine_mfrag_get_index_start (this->fraglist, idx, &timepos, NULL); timepos = timepos * 1000 / timebase; time_offset += (int)timepos; /* fall through */ case SEEK_SET: timepos = (int64_t)time_offset * timebase / 1000; idx = xine_mfrag_find_time (this->fraglist, timepos); offs = 0; xine_mfrag_get_index_start (this->fraglist, idx, &timepos, &offs); if (offs < this->savepos) rip_read_file_start (this, offs); return this->curpos; default: ; } } while (0); if (!this->main_input_plugin->seek_time) return this->curpos; r = this->main_input_plugin->seek_time (this->main_input_plugin, time_offset, origin); if ((r >= 0) && (r != this->curpos)) { this->curpos = r; if (this->regular) { off_t s = r; if (s < (off_t)this->preview_size) { s = this->preview_size; } else if (s > this->savepos) { s = this->savepos; } fseeko (this->file, s, SEEK_SET); } } return r; } /* * return current position, * check values for debug build */ static off_t rip_plugin_get_current_pos(input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; #ifdef DEBUG off_t pos; pos = this->main_input_plugin->get_current_pos(this->main_input_plugin); if (pos != this->curpos) { lprintf(CLR_FAIL "position: computed = %"PRId64", input plugin = %"PRId64"" CLR_RST "\n", this->curpos, pos); } #endif return this->curpos; } static int rip_plugin_get_current_time(input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; do { int idx, num; int64_t timebase, timepos1, timepos2, offs1, offs2; if (!this->fraglist) break; timebase = 0; xine_mfrag_get_index_frag (this->fraglist, 0, &timebase, NULL); if (timebase <= 0) break; num = xine_mfrag_get_frag_count (this->fraglist); idx = xine_mfrag_find_pos (this->fraglist, this->curpos); timepos1 = 0; offs1 = 0; xine_mfrag_get_index_start (this->fraglist, idx, &timepos1, &offs1); if (idx <= num) { timepos2 = 0; offs2 = 0; xine_mfrag_get_index_start (this->fraglist, idx + 1, &timepos2, &offs2); timepos1 += (this->curpos - offs1) * (timepos2 - timepos1) / (offs2 - offs1); } timepos1 = timepos1 * 1000 / timebase; return (int)timepos1; } while (0); if (!this->main_input_plugin->get_current_time) return -1; return this->main_input_plugin->get_current_time(this->main_input_plugin); } static off_t rip_plugin_get_length (input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; off_t length; length = this->main_input_plugin->get_length(this->main_input_plugin); if(length <= 0) length = this->savepos; return length; } static uint32_t rip_plugin_get_blocksize(input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; return this->main_input_plugin->get_blocksize(this->main_input_plugin); } static const char* rip_plugin_get_mrl (input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; return this->main_input_plugin->get_mrl(this->main_input_plugin); } static int rip_plugin_get_optional_data (input_plugin_t *this_gen, void *data, int data_type) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; int r; lprintf("get optional data\n"); r = this->main_input_plugin->get_optional_data (this->main_input_plugin, data, data_type); if (r != INPUT_OPTIONAL_UNSUPPORTED) return r; switch (data_type) { case INPUT_OPTIONAL_DATA_PREVIEW: if (!this->preview || !data) return INPUT_OPTIONAL_UNSUPPORTED; memcpy (data, this->preview, this->preview_size); return this->preview_size; case INPUT_OPTIONAL_DATA_SIZED_PREVIEW: if (!this->preview || !data) return INPUT_OPTIONAL_UNSUPPORTED; memcpy (&r, data, sizeof (r)); if (r <= 0) return INPUT_OPTIONAL_UNSUPPORTED; if (r > (int)this->preview_size) r = this->preview_size; memcpy (data, this->preview, r); return r; default: ; } return INPUT_OPTIONAL_UNSUPPORTED; } /* * dispose main input plugin and self */ static void rip_plugin_dispose(input_plugin_t *this_gen) { rip_input_plugin_t *this = (rip_input_plugin_t *)this_gen; lprintf("rip_plugin_dispose\n"); _x_free_input_plugin(this->stream, this->main_input_plugin); if (this->rfile) { fclose (this->rfile); this->rfile = NULL; } if (this->file) { fclose (this->file); this->file = NULL; } _x_freep (&this->fname); _x_freep(&this->preview); free(this); } /* * create self instance, * target file for writing stream is specified in 'data' */ input_plugin_t *_x_rip_plugin_get_instance (xine_stream_t *stream, const char *filename) { rip_input_plugin_t *this; input_plugin_t *main_plugin = stream->input_plugin; FILE *file; size_t nlen, slen1, slen2; char suff1[16], suff2[32], target[4 + MAX_TARGET_LEN + 16 + 32]; int ptsoffs, regular, i; lprintf("catch file = %s, path = %s\n", filename, stream->xine->save_path); /* check given input plugin */ if (!stream->input_plugin) { xine_log(stream->xine, XINE_LOG_MSG, _("input_rip: input plugin not defined!\n")); return NULL; } if (!stream->xine->save_path[0]) { xine_log(stream->xine, XINE_LOG_MSG, _("input_rip: target directory wasn't specified, please fill out the option 'media.capture.save_dir'\n")); _x_message(stream, XINE_MSG_SECURITY, _("The stream save feature is disabled until you set media.capture.save_dir in the configuration."), NULL); return NULL; } #ifndef SAVING_ALWAYS_PERMIT if ( main_plugin->get_capabilities(main_plugin) & INPUT_CAP_RIP_FORBIDDEN ) { xine_log(stream->xine, XINE_LOG_MSG, _("input_rip: ripping/caching of this source is not permitted!\n")); _x_message(stream, XINE_MSG_SECURITY, _("xine is not allowed to save from this source. (possibly copyrighted material?)"), NULL); return NULL; } #endif if (!filename || !filename[0]) { xine_log(stream->xine, XINE_LOG_MSG, _("input_rip: file name not given!\n")); return NULL; } { char *p; nlen = strlen (stream->xine->save_path); if (nlen > MAX_TARGET_LEN) return NULL; memcpy (target + 4, stream->xine->save_path, nlen + 1); target[3] = 0; for (p = target + 4 + nlen; p[-1] == '/'; p--) ; if (p == target + 4) { if (*p == '/') p++; } else { *p++ = '/'; } nlen = p - target - 4; } { const char *fn1, *fn2, *fn3, *fn4; fn1 = fn2 = fn3 = fn4 = filename; while (1) { while (*fn4 && (*fn4 != '/')) fn4++; if (fn4 > fn3) { fn1 = fn3; fn2 = fn4; } if (!*fn4) break; fn4++; fn3 = fn4; } slen1 = fn2 - fn1; if (!slen1) return NULL; if (nlen + slen1 > MAX_TARGET_LEN) return NULL; memcpy (target + 4 + nlen, fn1, slen1); nlen += slen1; } slen1 = 0; suff1[0] = 0; ptsoffs = main_plugin->get_optional_data (main_plugin, NULL, INPUT_OPTIONAL_DATA_PTSOFFS); if (ptsoffs) { slen2 = sprintf (suff2, ".ptsoffs=%d", ptsoffs); } else { slen2 = 0; suff2[0] = 0; } regular = 1; i = 1; while (1) { struct stat pstat; if (slen1) xine_small_memcpy (target + 4 + nlen, suff1, slen1); if (slen2) xine_small_memcpy (target + 4 + nlen + slen1, suff2, slen2); target[4 + nlen + slen1 + slen2] = 0; /* find out kind of target */ if (stat (target + 4, &pstat) < 0) break; #ifndef _MSC_VER regular = (S_ISFIFO (pstat.st_mode)) ? 0 : 1; if (!regular) { /* we want write into fifos */ break; } #else /* no fifos under MSVC */ #endif slen1 = sprintf (suff1, ".%d", i); i++; }; lprintf ("target file: %s\n", target + 4); file = fopen (target + 4, regular ? "wb+" : "wb"); if (!file) { int e = errno; xine_log (stream->xine, XINE_LOG_MSG, _("input_rip: error opening file %s: %s\n"), target + 4, strerror (e)); return NULL; } this = calloc (1, sizeof (*this)); if (!this) { fclose (file); return NULL; } this->main_input_plugin = main_plugin; this->stream = stream; this->file = file; this->fname = strdup (target + 4); this->regular = regular; this->read = rip_read_file_read_1a; #ifndef HAVE_ZERO_SAFE_MEM this->rfile = NULL; this->fraglist = NULL; this->preview = NULL; this->behind = 0; this->curpos = 0; this->savepos = 0; this->endpos = 0; this->preview_size = 0; #endif /* fill preview memory */ { uint32_t caps = this->main_input_plugin->get_capabilities (this->main_input_plugin); if (!(caps & (INPUT_CAP_SEEKABLE | INPUT_CAP_PREVIEW | INPUT_CAP_SIZED_PREVIEW))) { if (caps & INPUT_CAP_BLOCK) { buf_element_t *buf; uint32_t blocksize; blocksize = main_plugin->get_blocksize (main_plugin); buf = main_plugin->read_block (main_plugin, stream->video_fifo, blocksize); this->preview = malloc (buf->size); if (this->preview) { this->preview_size = buf->size; memcpy (this->preview, buf->content, this->preview_size); } buf->free_buffer (buf); } else { this->preview = malloc (MAX_PREVIEW_SIZE); if (this->preview) { ssize_t r = main_plugin->read (main_plugin, this->preview, MAX_PREVIEW_SIZE); if (r > 0) { this->preview_size = r; } else { _x_freep (&this->preview); } } } } } if (this->preview_size) { if (fwrite (this->preview, 1, this->preview_size, this->file) != this->preview_size) { int e = errno; xine_log (this->stream->xine, XINE_LOG_MSG, _("input_rip: error writing to file %" PRIdMAX " bytes: %s\n"), (intmax_t)(this->preview_size), strerror (e)); fclose (this->file); _x_freep (&this->preview); free (this); return NULL; } lprintf(" => saved %u bytes (preview)\n", (unsigned int)this->preview_size); this->savepos = this->preview_size; } { xine_mfrag_list_t *list = NULL; if (this->main_input_plugin->get_optional_data (this->main_input_plugin, &list, INPUT_OPTIONAL_DATA_FRAGLIST) == INPUT_OPTIONAL_SUCCESS) this->fraglist = list; } this->input_plugin.open = rip_plugin_open; this->input_plugin.get_capabilities = rip_plugin_get_capabilities; this->input_plugin.read = rip_plugin_read; this->input_plugin.read_block = rip_plugin_read_block; this->input_plugin.seek = rip_plugin_seek; this->input_plugin.seek_time = rip_plugin_seek_time; this->input_plugin.get_current_pos = rip_plugin_get_current_pos; this->input_plugin.get_current_time = rip_plugin_get_current_time; this->input_plugin.get_length = rip_plugin_get_length; this->input_plugin.get_blocksize = rip_plugin_get_blocksize; this->input_plugin.get_mrl = rip_plugin_get_mrl; this->input_plugin.get_optional_data = rip_plugin_get_optional_data; this->input_plugin.dispose = rip_plugin_dispose; this->input_plugin.input_class = main_plugin->input_class; return &this->input_plugin; } xine-lib-1.2/src/xine-engine/vo_scale.c0000644000175000017500000004433314647725152015627 0ustar meme/* * Copyright (C) 2000-2024 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Contains common code to calculate video scaling parameters. * In short, it will map frame dimensions to screen/window size. * Takes into account aspect ratio correction and zooming. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #define LOG_MODULE "vo_scale" #define LOG_VERBOSE /* #define LOG */ #include #include /* * convert delivered height/width to ideal width/height * taking into account aspect ratio and zoom factor */ void _x_vo_scale_compute_ideal_size (vo_scale_t *this) { if (this->scaling_disabled & ~1) { this->video_pixel_aspect = (this->scaling_disabled & 1) ? 1.0 : this->gui_pixel_aspect; } else { double image_ratio, desired_ratio; int vw = this->delivered_width - this->crop_left - this->crop_right; int vh = this->delivered_height - this->crop_top - this->crop_bottom; /* * aspect ratio */ image_ratio = vh > 0 ? (double)vw / (double)vh : 1.0; switch (this->user_ratio) { case XINE_VO_ASPECT_AUTO: desired_ratio = this->delivered_ratio; break; case XINE_VO_ASPECT_ANAMORPHIC: desired_ratio = 16.0 / 9.0; break; case XINE_VO_ASPECT_DVB: desired_ratio = 2.0 / 1.0; break; case XINE_VO_ASPECT_SQUARE: desired_ratio = image_ratio; break; case XINE_VO_ASPECT_4_3: default: desired_ratio = 4.0 / 3.0; } this->video_pixel_aspect = desired_ratio / image_ratio; _x_assert (this->gui_pixel_aspect > 0.0); /* dont scale just for tiny pixel aspect shift */ if (this->scaling_disabled & 1) { if (fabs (this->video_pixel_aspect - 1.0) < 0.01) this->video_pixel_aspect = 1.0; } else { if (fabs (this->video_pixel_aspect / this->gui_pixel_aspect - 1.0) < 0.01) this->video_pixel_aspect = this->gui_pixel_aspect; } #if 0 /* onefield_xv divide by 2 the number of lines */ if (this->deinterlace_enabled && (this->deinterlace_method == DEINTERLACE_ONEFIELDXV) && (this->cur_frame->format == XINE_IMGFMT_YV12)) { this->displayed_height = this->displayed_height / 2; this->displayed_yoffset = this->displayed_yoffset / 2; } #endif } } /* * make ideal width/height "fit" into the gui */ void _x_vo_scale_compute_output_size (vo_scale_t *this) { int cropped_width = this->delivered_width - (this->crop_left + this->crop_right); int cropped_height = this->delivered_height - (this->crop_top + this->crop_bottom); if (this->scaling_disabled & ~1) { this->output_width = cropped_width; this->output_height = cropped_height; this->displayed_width = cropped_width; this->displayed_height = cropped_height; } else { int sw, sh; double aspect; aspect = this->video_pixel_aspect; if (!(this->scaling_disabled & 1)) aspect /= this->gui_pixel_aspect; sw = (double)(cropped_width * this->gui_height) * aspect / (double)cropped_height + 0.5; sh = (double)(cropped_height * this->gui_width) / ((double)cropped_width * aspect) + 0.5; if ( this->support_zoom ) { /* zoom behaviour: * - window size never changes due zooming * - output image shall be increased whenever there are * black borders to use. * - exceding zoom shall be accounted by reducing displayed image. */ if ((this->gui_width - sw) < (this->gui_height - sh)) { int zh; this->output_width = this->gui_width; this->displayed_width = (double)cropped_width / this->zoom_factor_x + 0.5; this->output_height = sh; zh = (double)this->output_height * this->zoom_factor_y + 0.5; if (zh <= this->gui_height) { this->displayed_height = cropped_height; this->output_height = zh; } else { this->displayed_height = (double)cropped_height * this->gui_height / this->output_height / this->zoom_factor_y + 0.5; this->output_height = this->gui_height; } } else { int zw; this->output_height = this->gui_height; this->displayed_height = (double)cropped_height / this->zoom_factor_y + 0.5; this->output_width = sw; zw = (double)this->output_width * this->zoom_factor_x + 0.5; if (zw <= this->gui_width) { this->displayed_width = cropped_width; this->output_width = zw; } else { this->displayed_width = (double)cropped_width * this->gui_width / this->output_width / this->zoom_factor_x + 0.5; this->output_width = this->gui_width; } } } else { if ((this->gui_width - sw) < (this->gui_height - sh)) { this->output_width = this->gui_width; this->output_height = sh; } else { this->output_width = sw; this->output_height = this->gui_height; } this->displayed_width = cropped_width; this->displayed_height = cropped_height; } } /* make sure displayed values are sane, that is, we are not trying to display * something outside the delivered image. may happen when zoom < 100%. */ if( this->displayed_width > this->delivered_width ) { int w; w = this->output_width * this->delivered_width; w += this->displayed_width >> 1; w /= this->displayed_width; this->output_width = w; this->displayed_width = this->delivered_width; } if( this->displayed_height > this->delivered_height ) { int h; h = this->output_height * this->delivered_height; h += this->displayed_height >> 1; h /= this->displayed_height; this->output_height = h; this->displayed_height = this->delivered_height; } this->output_xoffset = (int)((this->gui_width - this->output_width) * this->output_horizontal_position) + this->gui_x; this->output_yoffset = (int)((this->gui_height - this->output_height) * this->output_vertical_position) + this->gui_y; this->displayed_xoffset = (int)((cropped_width - this->displayed_width) * this->output_horizontal_position) + this->crop_left; this->displayed_yoffset = (int)((cropped_height - this->displayed_height) * this->output_vertical_position) + this->crop_top; lprintf ("frame source %d x %d (%d x %d) => screen output %d x %d\n", this->delivered_width, this->delivered_height, this->displayed_width, this->displayed_height, this->output_width, this->output_height); /* calculate borders */ if (this->output_height < this->gui_height) { /* top */ this->border[0].x = 0; this->border[0].y = 0; this->border[0].w = this->gui_width; this->border[0].h = this->output_yoffset; /* bottom */ this->border[1].x = 0; this->border[1].y = this->output_yoffset + this->output_height; this->border[1].w = this->gui_width; this->border[1].h = this->gui_height - this->border[1].y; } else { /* no top/bottom borders */ this->border[0].w = this->border[0].h = 0; this->border[1].w = this->border[1].h = 0; } if (this->output_width < this->gui_width) { /* left */ this->border[2].x = 0; this->border[2].y = 0; this->border[2].w = this->output_xoffset; this->border[2].h = this->gui_height; /* right */ this->border[3].x = this->output_xoffset + this->output_width; this->border[3].y = 0; this->border[3].w = this->gui_width - this->border[3].x; this->border[3].h = this->gui_height; } else { /* no left/right borders */ this->border[2].w = this->border[2].h = 0; this->border[3].w = this->border[3].h = 0; } } /* * return true if a redraw is needed due resizing, zooming, * aspect ratio changing, etc. */ int _x_vo_scale_redraw_needed (vo_scale_t *this) { int gui_x, gui_y, gui_width, gui_height, gui_win_x, gui_win_y; double gui_pixel_aspect, video_pixel_aspect; int ret = 0; _x_assert(this->frame_output_cb); if ( ! this->frame_output_cb ) return 0; video_pixel_aspect = this->video_pixel_aspect; /* Nasty: tweaking GUI into different output window size will work from 2nd attempt on only... */ if ( this->scaling_disabled & 1 ) video_pixel_aspect *= this->gui_pixel_aspect; this->frame_output_cb (this->user_data, this->delivered_width - (this->crop_left + this->crop_right), this->delivered_height - (this->crop_top + this->crop_bottom), video_pixel_aspect, &gui_x, &gui_y, &gui_width, &gui_height, &gui_pixel_aspect, &gui_win_x, &gui_win_y ); /* test for the rare change case in just 2 branches. */ if (!((gui_x ^ this->gui_x) | (gui_y ^ this->gui_y) | (gui_width ^ this->gui_width) | (gui_height ^ this->gui_height) | (gui_win_x ^ this->gui_win_x) | (gui_win_y ^ this->gui_win_y)) && (gui_pixel_aspect == this->gui_pixel_aspect)) { ret = this->force_redraw; } else { this->gui_x = gui_x; this->gui_y = gui_y; this->gui_width = gui_width; this->gui_height = gui_height; this->gui_win_x = gui_win_x; this->gui_win_y = gui_win_y; this->gui_pixel_aspect = gui_pixel_aspect; ret = 1; } this->force_redraw = 0; return ret; } /* * */ void _x_vo_scale_translate_gui2video(vo_scale_t *this, int x, int y, int *vid_x, int *vid_y) { if (this->output_width > 0 && this->output_height > 0) { /* * 1. * the driver may center a small output area inside a larger * gui area. This is the case in fullscreen mode, where we often * have black borders on the top/bottom/left/right side. */ x -= this->output_xoffset; y -= this->output_yoffset; /* * 2. * the driver scales the delivered area into an output area. * translate output area coordianates into the delivered area * coordiantes. */ x = x * this->displayed_width / this->output_width + this->displayed_xoffset; y = y * this->displayed_height / this->output_height + this->displayed_yoffset; } *vid_x = x; *vid_y = y; } vo_scale_map_res_t _x_vo_scale_map (vo_scale_t *this, vo_scale_map_t *map) { double fx, fy, t; int vw, vh, ax, ay; if (!this || !map) return VO_SCALE_MAP_WRONG_ARGS; if ((this->displayed_width <= 0) || (this->displayed_height <= 0)) return VO_SCALE_MAP_ERROR; vw = this->delivered_width - (this->crop_left + this->crop_right); vh = this->delivered_height - (this->crop_top + this->crop_bottom); if ((map->out.x1 <= 0) || (map->out.y1 <= 0)) { map->out.x1 = vw; map->out.y1 = vh; if ((map->out.x1 <= 0) || (map->out.y1 <= 0)) return VO_SCALE_MAP_ERROR; } t = (this->output_width == this->displayed_width) ? 1.0 : (double)this->output_width / (double)this->displayed_width; fx = (map->out.x1 == vw) ? 1.0 : (double)vw / (double)map->out.x1; ax = fx * (this->output_xoffset - (t * this->displayed_xoffset)); fx *= t; t = (this->output_height == this->displayed_height) ? 1.0 : (double)this->output_height / (double)this->displayed_height; fy = (map->out.y1 == vh) ? 1.0 : (double)vh / (double)map->out.y1; ay = fy * (this->output_yoffset - (t * this->displayed_yoffset)); fy *= t; map->out.x1 = ax + (fx * (map->out.x0 + map->in.x1)); map->out.x0 = ax + (fx * map->out.x0); map->out.y1 = ay + (fy * (map->out.y0 + map->in.y1)); map->out.y0 = ay + (fy * map->out.y0); map->in.x0 = 0; ax = this->output_xoffset; if (map->out.x0 < ax) { map->in.x0 = (ax - map->out.x0) / fx; if (map->in.x0 >= map->in.x1) return VO_SCALE_MAP_OUTSIDE; map->out.x0 = ax; } map->in.y0 = 0; ay = this->output_yoffset; if (map->out.y0 < ay) { map->in.y0 = (ay - map->out.y0) / fy; if (map->in.y0 >= map->in.y1) return VO_SCALE_MAP_OUTSIDE; map->out.y0 = ay; } ax = this->output_xoffset + this->output_width; if (map->out.x1 > ax) { map->in.x1 -= (map->out.x1 - ax) / fx; if (map->in.x1 <= map->in.x0) return VO_SCALE_MAP_OUTSIDE; map->out.x1 = ax; } ay = this->output_yoffset + this->output_height; if (map->out.y1 > ay) { map->in.y1 -= (map->out.y1 - ay) / fy; if (map->in.y1 <= map->in.y0) return VO_SCALE_MAP_OUTSIDE; map->out.y1 = ay; } return VO_SCALE_MAP_OK; } /*/ * @brief Table for description of a given ratio code. * * @note changing the size of the elements of the array will break * ABI, so please don't do that unless you absolutely can't continue * with the current size. */ const char _x_vo_scale_aspect_ratio_name_table[][8] = { "auto", /* XINE_VO_ASPECT_AUTO */ "square", /* XINE_VO_ASPECT_SQUARE */ "4:3", /* XINE_VO_ASPECT_4_3 */ "16:9", /* XINE_VO_ASPECT_ANAMORPHIC */ "2:1", /* XINE_VO_ASPECT_DVB */ "unknown" /* All the rest */ }; /* * config callbacks */ static void vo_scale_horizontal_pos_changed(void *data, xine_cfg_entry_t *entry) { vo_scale_t *this = (vo_scale_t *)data; this->output_horizontal_position = entry->num_value / 100.0; this->force_redraw = 1; } static void vo_scale_vertical_pos_changed(void *data, xine_cfg_entry_t *entry) { vo_scale_t *this = (vo_scale_t *)data; this->output_vertical_position = entry->num_value / 100.0; this->force_redraw = 1; } static void vo_scale_disable_scaling_changed(void *data, xine_cfg_entry_t *entry) { vo_scale_t *this = (vo_scale_t *)data; this->scaling_disabled &= ~2; this->scaling_disabled |= (entry->num_value & 1) << 1; this->force_redraw = 1; } static void vo_scale_square_pixels_changed(void *data, xine_cfg_entry_t *entry) { vo_scale_t *this = (vo_scale_t *)data; this->scaling_disabled &= ~1; this->scaling_disabled |= entry->num_value & 1; this->force_redraw = 1; } /* * initialize rescaling struct */ void _x_vo_scale_cleanup(vo_scale_t *self, config_values_t *config) { config->unregister_callbacks (config, NULL, NULL, self, sizeof (*self)); } void _x_vo_scale_init (vo_scale_t *this, int support_zoom, int scaling_disabled, config_values_t *config) { #ifdef HAVE_ZERO_SAFE_MEM memset (this, 0, sizeof (*this)); #else this->delivered_width = 0; this->delivered_height = 0; this->crop_left = 0; this->crop_right = 0; this->crop_top = 0; this->crop_bottom = 0; this->displayed_xoffset = 0; this->displayed_yoffset = 0; this->displayed_width = 0; this->displayed_height = 0; this->gui_x = 0; this->gui_y = 0; this->gui_width = 0; this->gui_height = 0; this->gui_win_x = 0; this->gui_win_y = 0; this->output_width = 0; this->output_height = 0; this->output_xoffset = 0; this->output_yoffset = 0; this->user_data = NULL; this->frame_output_cb = NULL; this->dest_size_cb = NULL; this->border[0].x = 0; this->border[0].y = 0; this->border[0].w = 0; this->border[0].h = 0; this->border[1].x = 0; this->border[1].y = 0; this->border[1].w = 0; this->border[1].h = 0; this->border[2].x = 0; this->border[2].y = 0; this->border[2].w = 0; this->border[2].h = 0; this->border[3].x = 0; this->border[3].y = 0; this->border[3].w = 0; this->border[3].h = 0; #endif this->support_zoom = support_zoom; this->force_redraw = 1; this->zoom_factor_x = 1.0; this->zoom_factor_y = 1.0; this->gui_pixel_aspect = 1.0; this->video_pixel_aspect = 1.0; this->user_ratio = XINE_VO_ASPECT_AUTO; this->delivered_ratio = 1.0; this->output_horizontal_position = config->register_range(config, "video.output.horizontal_position", 50, 0, 100, _("horizontal image position in the output window"), _("If the video window's horizontal size is bigger than the actual image " "to show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the " "middle\", while 0 means \"at the very left\" and 100 \"at the very right\"."), 10, vo_scale_horizontal_pos_changed, this) / 100.0; this->output_vertical_position = config->register_range(config, "video.output.vertical_position", 50, 0, 100, _("vertical image position in the output window"), _("If the video window's vertical size is bigger than the actual image " "to show, you can adjust the position where the image will be placed.\n" "The position is given as a percentage, so a value of 50 means \"in the " "middle\", while 0 means \"at the top\" and 100 \"at the bottom\"."), 10, vo_scale_vertical_pos_changed, this) / 100.0; this->scaling_disabled = scaling_disabled << 2; this->scaling_disabled |= config->register_bool(config, "video.output.disable_scaling", 0, _("disable all video scaling"), _("If you want the video image to be always shown at its original resolution, " "you can disable all image scaling here.\n" "This of course means that the image will no longer adapt to the size of the " "video window and that videos with a pixel aspect ratio other than 1:1, like " "anamorphic DVDs, will be shown distorted. But on the other hand, with some " "video output drivers like XShm, where the image scaling is not hardware " "accelerated, this can dramatically reduce CPU usage."), 10, vo_scale_disable_scaling_changed, this) << 1; this->scaling_disabled |= config->register_bool(config, "video.output.square_pixels", 0, _("treat screen pixels as exactly square"), _("Many screens have \"only\" almost square pixels, like 94x93 dpi.\n" "This little deviation is important for true size graphics applications.\n" "For video, however, it often just means unnecessary black bars and less " "sharpness.\n"), 10, vo_scale_square_pixels_changed, this); } xine-lib-1.2/src/xine-engine/broadcaster.c0000644000175000017500000002605214647725152016323 0ustar meme/* * Copyright (C) 2000-2018 the xine project * May 2003 - Miguel Freitas * This feature was sponsored by 1Control * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * broadcaster.c - xine network broadcaster * * how it works: * - one xine instance must be set as master by using XINE_PARAM_BROADCASTER_PORT. * 'xine --broadcast-port ' * - master will wait for connections on specified port, accepting new clients. * - several xine clients may connect to the server as "slaves", using mrl: * slave://master_address:port * - streams played on master will appear on every slave. * if master is not meant to use video/audio devices it may be started with * 'xine -V none -A none' */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef WIN32 #include // socklen_t #endif #include #include #include #include #include #include "xine_private.h" #define QLEN 5 /* maximum connection queue length */ #define _BUFSIZ 512 struct broadcaster_s { xine_stream_t *stream; /* stream to broadcast */ int port; /* server port */ int msock; /* master network socket */ xine_list_t *connections; /* active connections */ pthread_t manager_thread; pthread_mutex_t lock; int running; }; /* network functions */ static int sock_check_opened(int socket) { fd_set readfds, writefds, exceptfds; int retval; struct timeval timeout; for(;;) { FD_ZERO(&readfds); FD_ZERO(&writefds); FD_ZERO(&exceptfds); FD_SET(socket, &exceptfds); timeout.tv_sec = 0; timeout.tv_usec = 0; retval = select(socket + 1, &readfds, &writefds, &exceptfds, &timeout); if(retval == -1 && (errno != EAGAIN && errno != EINTR)) return 0; if (retval != -1) return 1; } return 0; } /* * Write to socket. */ static int sock_data_write(xine_t *xine, int socket, const void *buf_gen, int len) { ssize_t size; int wlen = 0; const uint8_t *buf = buf_gen; if((socket < 0) || (buf == NULL)) return -1; if(!sock_check_opened(socket)) return -1; while(len) { size = write(socket, buf, len); if(size <= 0) { xprintf(xine, XINE_VERBOSITY_DEBUG, "broadcaster: error writing to socket %d\n",socket); return -1; } len -= size; wlen += size; buf += size; } return wlen; } static int XINE_FORMAT_PRINTF(3, 4) sock_string_write(xine_t *xine, int socket, const char *msg, ...) { char buf[_BUFSIZ]; va_list args; va_start(args, msg); vsnprintf(buf, _BUFSIZ - 1, msg, args); va_end(args); /* Each line sent is '\n' terminated */ if((buf[strlen(buf)] == '\0') && (buf[strlen(buf) - 1] != '\n')) strcat(buf, "\n"); return sock_data_write(xine, socket, buf, strlen(buf)); } /* * this is the most important broadcaster function. * it sends data to every connected client (slaves). */ static void broadcaster_data_write(broadcaster_t *this, const void *buf, int len) { xine_list_iterator_t ite; int ssock; ite = NULL; ssock = (intptr_t)xine_list_next_value (this->connections, &ite); while (ite) { /* in case of failure remove from list */ if (sock_data_write (this->stream->xine, ssock, buf, len) < 0) { xine_list_iterator_t failed; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: closing socket %d\n", ssock); close (ssock); failed = ite; ssock = (intptr_t)xine_list_next_value (this->connections, &ite); xine_list_remove (this->connections, failed); } else { ssock = (intptr_t)xine_list_next_value (this->connections, &ite); } } } static void XINE_FORMAT_PRINTF(2, 3) broadcaster_string_write(broadcaster_t *this, const char *msg, ...) { char buf[_BUFSIZ]; va_list args; va_start(args, msg); vsnprintf(buf, _BUFSIZ - 1, msg, args); va_end(args); /* Each line sent is '\n' terminated */ if((buf[strlen(buf)] == '\0') && (buf[strlen(buf) - 1] != '\n')) strcat(buf, "\n"); broadcaster_data_write(this, buf, strlen(buf)); } /* * this thread takes care of accepting new connections. */ static void *manager_loop (void *this_gen) { broadcaster_t *this = (broadcaster_t *) this_gen; union { /* the from address of a client */ struct sockaddr_in in; struct sockaddr sa; } fsin; socklen_t alen; /* from-address length */ fd_set rfds; /* read file descriptor set */ fd_set efds; /* exception descriptor set */ while( this->running ) { FD_ZERO(&rfds); FD_SET(this->msock, &rfds); FD_ZERO(&efds); FD_SET(this->msock, &efds); if (select(this->msock+1, &rfds, (fd_set *)0, &efds, (struct timeval *)0) > 0) { pthread_mutex_lock( &this->lock ); if (FD_ISSET(this->msock, &rfds)) { int ssock; alen = sizeof(fsin.in); ssock = accept(this->msock, &(fsin.sa), &alen); if (ssock >= 0) { _x_set_socket_close_on_exec(ssock); /* identification string, helps demuxer probing */ if( sock_string_write(this->stream->xine, ssock,"master xine v1") > 0 ) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: new connection socket %d\n", ssock); xine_list_push_back (this->connections, (void *)(intptr_t)ssock); } } } pthread_mutex_unlock( &this->lock ); } } return NULL; } /* * receive xine buffers and send them through the broadcaster */ static void send_buf (broadcaster_t *this, const char *from, buf_element_t *buf) { int i; /* ignore END buffers since they would stop the slavery */ if( buf->type == BUF_CONTROL_END ) return; /* assume RESET_DECODER is result of a xine_flush_engine */ if( buf->type == BUF_CONTROL_RESET_DECODER && !strcmp(from,"video") ) { broadcaster_string_write(this, "flush_engine"); } /* send decoder information if any */ for( i = 0; i < BUF_NUM_DEC_INFO; i++ ) { if( buf->decoder_info[i] ) { broadcaster_string_write(this, "decoder_info index=%d decoder_info=%u has_data=%d", i, buf->decoder_info[i], (buf->decoder_info_ptr[i]) ? 1 : 0); if( buf->decoder_info_ptr[i] ) broadcaster_data_write(this, buf->decoder_info_ptr[i], buf->decoder_info[i]); } } broadcaster_string_write(this, "buffer fifo=%s size=%d type=%u pts=%"PRId64" disc=%"PRId64" flags=%u", from, buf->size, buf->type, buf->pts, buf->disc_off, buf->decoder_flags ); if( buf->size ) broadcaster_data_write(this, buf->content, buf->size); } /* buffer callbacks */ static void video_put_cb (fifo_buffer_t *fifo, buf_element_t *buf, void *this_gen) { broadcaster_t *this = (broadcaster_t *) this_gen; (void)fifo; pthread_mutex_lock( &this->lock ); send_buf(this, "video", buf); pthread_mutex_unlock( &this->lock ); } static void audio_put_cb (fifo_buffer_t *fifo, buf_element_t *buf, void *this_gen) { broadcaster_t *this = (broadcaster_t *) this_gen; (void)fifo; pthread_mutex_lock( &this->lock ); send_buf(this, "audio", buf); pthread_mutex_unlock( &this->lock ); } broadcaster_t *_x_init_broadcaster(xine_stream_t *stream, int port) { broadcaster_t *this; union { struct sockaddr_in in; struct sockaddr sa; } servAddr; int msock, err; msock = xine_socket_cloexec(PF_INET, SOCK_STREAM, 0); if( msock < 0 ) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: error opening master socket.\n"); return NULL; } servAddr.in.sin_family = AF_INET; servAddr.in.sin_addr.s_addr = htonl(INADDR_ANY); servAddr.in.sin_port = htons(port); if(bind(msock, &servAddr.sa, sizeof(servAddr.in))<0) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: error binding to port %d\n", port); close(msock); return NULL; } if (listen(msock,QLEN) < 0) { xprintf(stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: error listening port %d\n", port); close(msock); return NULL; } #ifndef _WIN32 signal( SIGPIPE, SIG_IGN ); #endif this = calloc(1, sizeof(broadcaster_t)); if (!this) { close(msock); return NULL; } this->port = port; this->stream = stream; this->msock = msock; this->connections = xine_list_new(); pthread_mutex_init (&this->lock, NULL); if (stream->video_fifo) stream->video_fifo->register_put_cb(stream->video_fifo, video_put_cb, this); if(stream->audio_fifo) stream->audio_fifo->register_put_cb(stream->audio_fifo, audio_put_cb, this); this->running = 1; if ((err = pthread_create (&this->manager_thread, NULL, manager_loop, (void *)this)) != 0) { xprintf (stream->xine, XINE_VERBOSITY_NONE, "broadcaster: can't create new thread (%s)\n", strerror(err)); this->running = 0; _x_close_broadcaster(this); return NULL; } return this; } void _x_close_broadcaster(broadcaster_t *this_gen) { if (this_gen->running) { this_gen->running = 0; pthread_cancel(this_gen->manager_thread); pthread_join(this_gen->manager_thread,NULL); } close(this_gen->msock); if (this_gen->stream->video_fifo) this_gen->stream->video_fifo->unregister_put_cb(this_gen->stream->video_fifo, video_put_cb); if(this_gen->stream->audio_fifo) this_gen->stream->audio_fifo->unregister_put_cb(this_gen->stream->audio_fifo, audio_put_cb); xine_list_iterator_t ite = NULL; while (1) { int ssock = (intptr_t)xine_list_next_value (this_gen->connections, &ite); if (!ite) break; xprintf (this_gen->stream->xine, XINE_VERBOSITY_DEBUG, "broadcaster: closing socket %d\n", ssock); close (ssock); } xine_list_delete(this_gen->connections); pthread_mutex_destroy( &this_gen->lock ); free(this_gen); } int _x_get_broadcaster_port(broadcaster_t *this_gen) { return this_gen->port; } xine-lib-1.2/src/xine-engine/resample.c0000644000175000017500000002555314647725152015647 0ustar meme/* * Copyright (C) 2000-2009 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include /* contributed by paul flinders */ void _x_audio_out_resample_mono(int16_t *last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ uint32_t isample = 0xFFFF0000U; uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { uint32_t t = isample&0xffff; output_samples[osample] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; isample += istep; } for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; uint32_t t = isample&0xffff; /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */ s1 = input_samples[(isample >> 16)]; s2 = input_samples[(isample >> 16)+1]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[osample] = os; isample += istep; } last_sample[0] = input_samples[in_samples - 1]; } void _x_audio_out_resample_stereo(int16_t *last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ uint32_t isample = 0xFFFF0000U; uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { uint32_t t = isample&0xffff; output_samples[osample*2 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; output_samples[osample*2+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; isample += istep; } for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; uint32_t t = isample&0xffff; /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */ s1 = input_samples[(isample >> 16)*2]; s2 = input_samples[(isample >> 16)*2+2]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[osample * 2] = os; s1 = input_samples[(isample >> 16)*2+1]; s2 = input_samples[(isample >> 16)*2+3]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 2 )+1] = os; isample += istep; } memcpy (last_sample, &input_samples[in_samples*2-2], 2 * sizeof (last_sample[0])); } void _x_audio_out_resample_4channel(int16_t *last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ uint32_t isample = 0xFFFF0000U; uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { uint32_t t = isample&0xffff; output_samples[osample*4 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; output_samples[osample*4+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; output_samples[osample*4+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; output_samples[osample*4+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; isample += istep; } for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; uint32_t t = isample&0xffff; /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */ s1 = input_samples[(isample >> 16)*4]; s2 = input_samples[(isample >> 16)*4+4]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[osample * 4] = os; s1 = input_samples[(isample >> 16)*4+1]; s2 = input_samples[(isample >> 16)*4+5]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 4 )+1] = os; s1 = input_samples[(isample >> 16)*4+2]; s2 = input_samples[(isample >> 16)*4+6]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 4 )+2] = os; s1 = input_samples[(isample >> 16)*4+3]; s2 = input_samples[(isample >> 16)*4+7]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 4 )+3] = os; isample += istep; } memcpy (last_sample, &input_samples[in_samples*4-4], 4 * sizeof (last_sample[0])); } void _x_audio_out_resample_5channel(int16_t *last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ uint32_t isample = 0xFFFF0000U; uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { uint32_t t = isample&0xffff; output_samples[osample*5 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; output_samples[osample*5+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; output_samples[osample*5+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; output_samples[osample*5+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; output_samples[osample*5+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; isample += istep; } for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; uint32_t t = isample&0xffff; /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */ s1 = input_samples[(isample >> 16)*5]; s2 = input_samples[(isample >> 16)*5+5]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[osample * 5] = os; s1 = input_samples[(isample >> 16)*5+1]; s2 = input_samples[(isample >> 16)*5+6]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 5 )+1] = os; s1 = input_samples[(isample >> 16)*5+2]; s2 = input_samples[(isample >> 16)*5+7]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 5 )+2] = os; s1 = input_samples[(isample >> 16)*5+3]; s2 = input_samples[(isample >> 16)*5+8]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 5 )+3] = os; s1 = input_samples[(isample >> 16)*5+4]; s2 = input_samples[(isample >> 16)*5+9]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 5 )+4] = os; isample += istep; } memcpy (last_sample, &input_samples[in_samples*5-5], 5 * sizeof (last_sample[0])); } void _x_audio_out_resample_6channel(int16_t *last_sample, int16_t* input_samples, uint32_t in_samples, int16_t* output_samples, uint32_t out_samples) { unsigned int osample; /* 16+16 fixed point math */ uint32_t isample = 0xFFFF0000U; uint32_t istep = (in_samples << 16) / out_samples + 1; #ifdef VERBOSE printf ("Audio : resample %d samples to %d\n", in_samples, out_samples); #endif for (osample = 0; osample < out_samples && isample >= 0xFFFF0000U; osample++) { uint32_t t = isample&0xffff; output_samples[osample*6 ] = (last_sample[0] * (0x10000-t) + input_samples[0] * t) >> 16; output_samples[osample*6+1] = (last_sample[1] * (0x10000-t) + input_samples[1] * t) >> 16; output_samples[osample*6+2] = (last_sample[2] * (0x10000-t) + input_samples[2] * t) >> 16; output_samples[osample*6+3] = (last_sample[3] * (0x10000-t) + input_samples[3] * t) >> 16; output_samples[osample*6+4] = (last_sample[4] * (0x10000-t) + input_samples[4] * t) >> 16; output_samples[osample*6+5] = (last_sample[5] * (0x10000-t) + input_samples[5] * t) >> 16; isample += istep; } for (; osample < out_samples; osample++) { int s1; int s2; int16_t os; uint32_t t = isample&0xffff; /* don't "optimize" the (isample >> 16)*2 to (isample >> 15) */ s1 = input_samples[(isample >> 16)*6]; s2 = input_samples[(isample >> 16)*6+6]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[osample * 6] = os; s1 = input_samples[(isample >> 16)*6+1]; s2 = input_samples[(isample >> 16)*6+7]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 6 )+1] = os; s1 = input_samples[(isample >> 16)*6+2]; s2 = input_samples[(isample >> 16)*6+8]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 6 )+2] = os; s1 = input_samples[(isample >> 16)*6+3]; s2 = input_samples[(isample >> 16)*6+9]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 6 )+3] = os; s1 = input_samples[(isample >> 16)*6+4]; s2 = input_samples[(isample >> 16)*6+10]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 6 )+4] = os; s1 = input_samples[(isample >> 16)*6+5]; s2 = input_samples[(isample >> 16)*6+11]; os = (s1 * (0x10000-t)+ s2 * t) >> 16; output_samples[(osample * 6 )+5] = os; isample += istep; } memcpy (last_sample, &input_samples[in_samples*6-6], 6 * sizeof (last_sample[0])); } void _x_audio_out_resample_8to16(int8_t* input_samples, int16_t* output_samples, uint32_t samples) { while( samples-- ) { int16_t os; os = *input_samples++; os = (os - 0x80) << 8; *output_samples++ = os; } } void _x_audio_out_resample_16to8(int16_t* input_samples, int8_t* output_samples, uint32_t samples) { while( samples-- ) { int16_t os; os = *input_samples++; os = (os >> 8) + 0x80; *output_samples++ = os; } } void _x_audio_out_resample_monotostereo(int16_t* input_samples, int16_t* output_samples, uint32_t frames) { while( frames-- ) { int16_t os; os = *input_samples++; *output_samples++ = os; *output_samples++ = os; } } void _x_audio_out_resample_stereotomono(int16_t* input_samples, int16_t* output_samples, uint32_t frames) { while( frames-- ) { int16_t os; os = (*input_samples++)>>1; os += (*input_samples++)>>1; *output_samples++ = os; } } xine-lib-1.2/src/spu_dec/0000755000175000017500000000000014647725152013075 5ustar memexine-lib-1.2/src/spu_dec/cc_decoder.c0000644000175000017500000012320714647725152015320 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * Copyright (C) Christian Vogler * cvogler@gradient.cis.upenn.edu - December 2001 * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stuff needed to provide closed captioning decoding and display * * Some small bits and pieces of the EIA-608 captioning decoder were * adapted from CCDecoder 0.9.1 by Mike Baker. The latest version is * available at http://sourceforge.net/projects/ccdecoder/. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include #include #include #include "cc_decoder.h" #include /* #define LOG_DEBUG 3 */ /* at 29.97 fps, each NTSC frame takes 3003 metronom ticks on the average. */ #define NTSC_FRAME_DURATION 3003 #define CC_ROWS 15 #define CC_COLUMNS 32 #define CC_CHANNELS 2 /* 1 is the caption background color index in the OSD palettes. */ #define CAP_BG_COL 1 /* number of text colors specified by EIA-608 standard */ #define NUM_FG_COL 7 #ifndef WIN32 /* colors specified by the EIA 608 standard */ enum { WHITE, GREEN, BLUE, CYAN, RED, YELLOW, MAGENTA, BLACK, TRANSPARENT }; #else /* colors specified by the EIA 608 standard */ enum { WHITE, GREEN, BLUE, CYAN, RED, YELLOW, MAGENTA, BLACK }; #endif /* color mapping to OSD text color indices */ static const int text_colormap[NUM_FG_COL] = { OSD_TEXT1, OSD_TEXT2, OSD_TEXT3, OSD_TEXT4, OSD_TEXT5, OSD_TEXT6, OSD_TEXT7 }; /* -------------------- caption text colors -----------------------------*/ /* FIXME: The colors look fine on an XShm display, but they look *terrible* with the Xv display on the NVidia driver on a GeForce 3. The colors bleed into each other more than I'd expect from the downsampling into YUV colorspace. At this moment, it looks like a problem in the Xv YUV blending functions. */ typedef struct colorinfo_s { clut_t bgcol; /* text background color */ clut_t bordercol; /* text border color */ clut_t textcol; /* text color */ } colorinfo_t; static const colorinfo_t cc_text_trans[NUM_FG_COL] = { /* white, black border, translucid */ { CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80) }, /* green, black border, translucid */ { CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x90, 0x22, 0x35) }, /* blue, black border, translucid */ { CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x29, 0x6e, 0xff) }, /* cyan, black border, translucid */ { CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xaa, 0x10, 0xa6) }, /* red, black border, translucid */ { CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x52, 0xf0, 0x5a) }, /* yellow, black border, translucid */ { CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xd4, 0x92, 0x10) }, /* magenta, black border, translucid */ { CLUT_Y_CR_CB_INIT(0x80, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x6b, 0xde, 0xca) } }; static const colorinfo_t cc_text_solid[NUM_FG_COL] = { /* white, black border, solid */ { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xff, 0x80, 0x80) }, /* green, black border, solid */ { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x90, 0x22, 0x35) }, /* blue, black border, solid */ { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x29, 0x6e, 0xff) }, /* cyan, black border, solid */ { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xaa, 0x10, 0xa6) }, /* red, black border, solid */ { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x52, 0xf0, 0x5a) }, /* yellow, black border, solid */ { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xd4, 0x92, 0x10) }, /* magenta, black border, solid */ { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x6b, 0xde, 0xca) } }; static const uint8_t cc_text_trans_alpha[TEXT_PALETTE_SIZE] = { 0, 8, 9, 10, 11, 12, 15, 15, 15, 15, 15 }; static const uint8_t cc_text_solid_alpha[TEXT_PALETTE_SIZE] = { 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 }; static const colorinfo_t *const cc_text_palettes[NUM_CC_PALETTES] = { cc_text_trans, cc_text_solid }; static const uint8_t *const cc_alpha_palettes[NUM_CC_PALETTES] = { cc_text_trans_alpha, cc_text_solid_alpha }; /* --------------------- misc. EIA 608 definitions -------------------*/ #define TRANSP_SPACE 0x19 /* code for transparent space, essentially arbitrary */ /* mapping from PAC row code to actual CC row */ static const int rowdata[] = {10, -1, 0, 1, 2, 3, 11, 12, 13, 14, 4, 5, 6, 7, 8, 9}; /* FIXME: do real ™ (U+2122) */ /* Code 182 must be mapped as a musical note ('♪', U+266A) in the caption font */ static const uint8_t specialchar[] = { 174 /* ® */, 176 /* ° */, 189 /* ½ */, 191 /* ¿ */, 'T' /* ™ */, 162 /* ¢ */, 163 /* £ */, 182 /* ¶ => ♪ */, 224 /* à */, TRANSP_SPACE,232 /* è */, 226 /* â */, 234 /* ê */, 238 /* î */, 244 /* ô */, 251 /* û */ }; /** * @brief Character translation table * * EIA 608 codes are not all the same as ASCII * * The code to produce the characters table would be the following: * * static void build_char_table(void) * { * int i; * // first the normal ASCII codes * for (i = 0; i < 128; i++) * chartbl[i] = (char) i; * // now the special codes * chartbl[0x2a] = 225; // á * chartbl[0x5c] = 233; // é * chartbl[0x5e] = 237; // í * chartbl[0x5f] = 243; // ó * chartbl[0x60] = 250; // ú * chartbl[0x7b] = 231; // ç * chartbl[0x7c] = 247; // ÷ * chartbl[0x7d] = 209; // Ñ * chartbl[0x7e] = 241; // ñ * chartbl[0x7f] = 164; // ¤ FIXME: should be a solid block ('█'; U+2588) * } * */ static const int chartbl[128] = { '\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07', '\x08', '\x09', '\x0a', '\x0b', '\x0c', '\x0d', '\x0e', '\x0f', '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', '\x20', '\x21', '\x22', '\x23', '\x24', '\x25', '\x26', '\x27', '\x28', '\x29', '\xe1', '\x2b', '\x2c', '\x2d', '\x2e', '\x2f', '\x30', '\x31', '\x32', '\x33', '\x34', '\x35', '\x36', '\x37', '\x38', '\x39', '\x3a', '\x3b', '\x3c', '\x3d', '\x3e', '\x3f', '\x40', '\x41', '\x42', '\x43', '\x44', '\x45', '\x46', '\x47', '\x48', '\x49', '\x4a', '\x4b', '\x4c', '\x4d', '\x4e', '\x4f', '\x50', '\x51', '\x52', '\x53', '\x54', '\x55', '\x56', '\x57', '\x58', '\x59', '\x5a', '\x5b', '\xe9', '\x5d', '\xed', '\xf3', '\xfa', '\x61', '\x62', '\x63', '\x64', '\x65', '\x66', '\x67', '\x68', '\x69', '\x6a', '\x6b', '\x6c', '\x6d', '\x6e', '\x6f', '\x70', '\x71', '\x72', '\x73', '\x74', '\x75', '\x76', '\x77', '\x78', '\x79', '\x7a', '\xe7', '\xf7', '\xd1', '\xf1', '\xa4' }; /** * @brief Parity table for packets * * CC codes use odd parity for error detection, since they originally were * transmitted via noisy video signals. * * The code to produce the parity table would be the following: * * static int parity(uint8_t byte) * { * int i; * int ones = 0; * * for (i = 0; i < 7; i++) { * if (byte & (1 << i)) * ones++; * } * * return ones & 1; * } * * static void build_parity_table(void) * { * uint8_t byte; * int parity_v; * for (byte = 0; byte <= 127; byte++) { * parity_v = parity(byte); * // CC uses odd parity (i.e., # of 1's in byte is odd.) * parity_table[byte] = parity_v; * parity_table[byte | 0x80] = !parity_v; * } * } */ static const int parity_table[256] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; /*---------------- decoder data structures -----------------------*/ /* CC renderer */ struct cc_renderer_s { int video_width; /* video dimensions */ int video_height; int x; /* coordinates of the captioning area */ int y; int width; int height; int max_char_height; /* captioning font properties */ int max_char_width; osd_renderer_t *osd_renderer; /* active OSD renderer */ osd_object_t *cap_display; /* caption display object */ int displayed; /* true when caption currently is displayed */ /* the next variable is a hack: hiding a caption with vpts 0 doesn't seem to work if the caption has been registered in the SPU event queue, but not yet displayed. So we remember the vpts of the show event, and use that as the vpts of the hide event upon an osd free. */ /*FIXME: bug in OSD or SPU?*/ int64_t display_vpts; /* vpts of currently displayed caption */ /* this variable is an even worse hack: in some rare cases, the pts information on the DVD gets out of sync with the caption information. If this happens, the vpts of a hide caption event can actually be slightly higher than the vpts of the following show caption event. For this reason, we remember the vpts of the hide event and force the next show event's vpts to be at least equal to the hide event's vpts. */ int64_t last_hide_vpts; /* caption palette and alpha channel */ uint32_t cc_palette[OVL_PALETTE_SIZE]; uint8_t cc_trans[OVL_PALETTE_SIZE]; metronom_t *metronom; /* the active xine metronom */ cc_state_t *cc_state; /* captioning configuration */ }; /* CC attribute */ typedef struct cc_attribute_s { uint8_t italic; uint8_t underline; uint8_t foreground; uint8_t background; } cc_attribute_t; /* CC character cell */ typedef struct cc_char_cell_s { uint8_t c; /* character code, not the same as ASCII */ cc_attribute_t attributes; /* attributes of this character, if changed */ /* here */ int midrow_attr; /* true if this cell changes an attribute */ } cc_char_cell_t; /* a single row in the closed captioning memory */ typedef struct cc_row_s { cc_char_cell_t cells[CC_COLUMNS]; int pos; /* position of the cursor */ int num_chars; /* how many characters in the row are data */ int attr_chg; /* true if midrow attr. change at cursor pos */ int pac_attr_chg; /* true if attribute has changed via PAC */ cc_attribute_t pac_attr; /* PAC attr. that hasn't been applied yet */ } cc_row_t; /* closed captioning memory for a single channel */ typedef struct cc_buffer_s { cc_row_t rows[CC_ROWS]; int rowpos; /* row cursor position */ } cc_buffer_t; /* captioning memory for all channels */ typedef struct cc_memory_s { cc_buffer_t channel[CC_CHANNELS]; int channel_no; /* currently active channel */ } cc_memory_t; /* The closed captioning decoder data structure */ struct cc_decoder_s { /* CC decoder buffer - one onscreen, one offscreen */ cc_memory_t buffer[2]; /* onscreen, offscreen buffer ptrs */ cc_memory_t *on_buf; cc_memory_t *off_buf; /* which buffer is active for receiving data */ cc_memory_t **active; /* for logging and debugging purposes, captions are assigned increasing */ /* unique ids. */ uint32_t capid; /* the last captioning code seen (control codes are often sent twice in a row, but should be processed only once) */ uint32_t lastcode; /* The PTS and SCR at which the captioning chunk started */ int64_t pts; /* holds the NTSC frame offset to last known pts/scr */ uint32_t f_offset; /* active OSD renderer */ osd_renderer_t *renderer; /* true when caption currently is displayed */ int displayed; /* configuration and intrinsics of CC decoder */ cc_state_t *cc_state; metronom_t *metronom; }; /*---------------- general utility functions ---------------------*/ static void get_font_metrics(osd_renderer_t *renderer, const char *fontname, int font_size, int *maxw, int *maxh) { int c; osd_object_t *testc = renderer->new_object(renderer, 640, 480); *maxw = 0; *maxh = 0; renderer->set_font(testc, fontname, font_size); renderer->set_encoding(testc, "iso-8859-1"); for (c = 32; c < 256; c++) { int tw, th; const char buf[2] = { c, '\0' }; renderer->get_text_size(testc, buf, &tw, &th); *maxw = MAX(*maxw, tw); *maxh = MAX(*maxh, th); } renderer->free_object(testc); } static int good_parity(uint16_t data) { int ret = parity_table[data & 0xff] && parity_table[(data & 0xff00) >> 8]; if (! ret) printf("Bad parity in EIA-608 data (%x)\n", data); return ret; } static clut_t interpolate_color(clut_t src, clut_t dest, int steps, int current_step) { int diff_y = ((int) dest.y) - ((int) src.y); int diff_cr = ((int) dest.cr) - ((int) src.cr); int diff_cb = ((int) dest.cb) - ((int) src.cb); int res_y = ((int) src.y) + (diff_y * current_step / (steps + 1)); int res_cr = ((int) src.cr) + (diff_cr * current_step / (steps + 1)); int res_cb = ((int) src.cb) + (diff_cb * current_step / (steps + 1)); #if __SUNPRO_C /* * Sun's Forte compiler refuses to initialize automatic structure * variable with bitfields, so we use explicit assignments for now. */ clut_t res; res.y = res_y; res.cr = res_cr; res.cb = res_cb; res.foo = 0; #else clut_t res = CLUT_Y_CR_CB_INIT((uint8_t) res_y, (uint8_t) res_cr, (uint8_t) res_cb); #endif return res; } /*----------------- cc_row_t methods --------------------------------*/ static void ccrow_fill_transp(cc_row_t *rowbuf){ int i; #ifdef LOG_DEBUG printf("cc_decoder: ccrow_fill_transp: Filling in %d transparent spaces.\n", rowbuf->pos - rowbuf->num_chars); #endif for (i = rowbuf->num_chars; i < rowbuf->pos; i++) { rowbuf->cells[i].c = TRANSP_SPACE; rowbuf->cells[i].midrow_attr = 0; } } static int ccrow_find_next_text_part(cc_row_t *this, int pos) { while (pos < this->num_chars && this->cells[pos].c == TRANSP_SPACE) pos++; return pos; } static int ccrow_find_end_of_text_part(cc_row_t *this, int pos) { while (pos < this->num_chars && this->cells[pos].c != TRANSP_SPACE) pos++; return pos; } static int ccrow_find_current_attr(cc_row_t *this, int pos) { while (pos > 0 && !this->cells[pos].midrow_attr) pos--; return pos; } static int ccrow_find_next_attr_change(cc_row_t *this, int pos, int lastpos) { pos++; while (pos < lastpos && !this->cells[pos].midrow_attr) pos++; return pos; } static void ccrow_set_attributes(cc_renderer_t *renderer, cc_row_t *this, int pos) { const cc_attribute_t *attr = &this->cells[pos].attributes; const char *fontname; cc_config_t *cap_info = renderer->cc_state->cc_cfg; if (attr->italic) fontname = cap_info->italic_font; else fontname = cap_info->font; renderer->osd_renderer->set_font(renderer->cap_display, fontname, cap_info->font_size); } static void ccrow_render(cc_renderer_t *renderer, cc_row_t *this, int rownum) { char buf[CC_COLUMNS + 1]; int base_y; int pos = ccrow_find_next_text_part(this, 0); cc_config_t *cap_info = renderer->cc_state->cc_cfg; osd_renderer_t *osd_renderer = renderer->osd_renderer; /* find y coordinate of caption */ if (cap_info->center) { /* find y-center of the desired row; the next line computes */ /* cap_info->height * (rownum + 0.5) / CC_ROWS */ /* in integer arithmetic for this purpose. */ base_y = (renderer->height * rownum * 100 + renderer->height * 50) / (CC_ROWS * 100); } else base_y = renderer->height * rownum / CC_ROWS; /* break down captions into parts separated by transparent space, and */ /* center each part individually along the x axis */ while (pos < this->num_chars) { int endpos = ccrow_find_end_of_text_part(this, pos); int seg_begin = pos; int seg_end; int i; int text_w = 0, text_h = 0; int x, y; int seg_w, seg_h; int seg_pos[CC_COLUMNS + 1]; int seg_attr[CC_COLUMNS]; int cumulative_seg_width[CC_COLUMNS + 1]; int num_seg = 0; int seg; /* break down each part into segments bounded by attribute changes and */ /* find text metrics of the parts */ seg_pos[0] = seg_begin; cumulative_seg_width[0] = 0; while (seg_begin < endpos) { int attr_pos = ccrow_find_current_attr(this, seg_begin); seg_end = ccrow_find_next_attr_change(this, seg_begin, endpos); /* compute text size of segment */ for (i = seg_begin; i < seg_end; i++) buf[i - seg_begin] = this->cells[i].c; buf[seg_end - seg_begin] = '\0'; ccrow_set_attributes(renderer, this, attr_pos); osd_renderer->get_text_size(renderer->cap_display, buf, &seg_w, &seg_h); /* update cumulative segment statistics */ text_w += seg_w; text_h += seg_h; seg_pos[num_seg + 1] = seg_end; seg_attr[num_seg] = attr_pos; cumulative_seg_width[num_seg + 1] = text_w; num_seg++; seg_begin = seg_end; } /* compute x coordinate of part */ if (cap_info->center) { int cell_width = renderer->width / CC_COLUMNS; x = (renderer->width * (pos + endpos) / 2) / CC_COLUMNS; x -= text_w / 2; /* clamp x coordinate to nearest character cell */ x = ((x + cell_width / 2) / CC_COLUMNS) * CC_COLUMNS + cell_width; y = base_y - (renderer->max_char_height + 1) / 2; } else { x = renderer->width * pos / CC_COLUMNS; y = base_y; } #ifdef LOG_DEBUG printf("text_w, text_h = %d, %d\n", text_w, text_h); printf("cc from %d to %d; text plotting from %d, %d (basey = %d)\n", pos, endpos, x, y, base_y); #endif /* render text part by rendering each attributed text segment */ for (seg = 0; seg < num_seg; seg++) { int textcol = text_colormap[this->cells[seg_attr[seg]].attributes.foreground]; int box_x1 = x + cumulative_seg_width[seg]; int box_x2 = x + cumulative_seg_width[seg + 1]; #ifdef LOG_DEBUG printf("ccrow_render: rendering segment %d from %d to %d / %d to %d\n", seg, seg_pos[seg], seg_pos[seg + 1], x + cumulative_seg_width[seg], x + cumulative_seg_width[seg + 1]); #endif /* make caption background a uniform box. Without this line, the */ /* background is uneven for superscript characters. */ /* Also pad left & right ends of caption to make it more readable */ /*FIXME: There may be off-by one errors in the rendering - check with Miguel*/ if (seg == 0) box_x1 -= renderer->max_char_width; if (seg == num_seg - 1) box_x2 += renderer->max_char_width; osd_renderer->filled_rect(renderer->cap_display, box_x1, y, box_x2, y + renderer->max_char_height, textcol + CAP_BG_COL); for (i = seg_pos[seg]; i < seg_pos[seg + 1]; i++) buf[i - seg_pos[seg]] = this->cells[i].c; buf[seg_pos[seg + 1] - seg_pos[seg]] = '\0'; ccrow_set_attributes(renderer, this, seg_attr[seg]); /* text is already mapped from EIA-608 into iso-8859-1 */ osd_renderer->render_text(renderer->cap_display, x + cumulative_seg_width[seg], y, buf, textcol); } pos = ccrow_find_next_text_part(this, endpos); } } /*----------------- cc_buffer_t methods --------------------------------*/ static int ccbuf_has_displayable(cc_buffer_t *this) { int i; for (i = 0; i < CC_ROWS; i++) if (this->rows[i].num_chars > 0) return 1; return 0; } static void ccbuf_add_char(cc_buffer_t *this, uint8_t c) { cc_row_t *rowbuf = &this->rows[this->rowpos]; int pos = rowbuf->pos; int left_displayable = (pos > 0) && (pos <= rowbuf->num_chars); #if LOG_DEBUG > 2 printf("cc_decoder: ccbuf_add_char: %c @ %d/%d\n", c, this->rowpos, pos); #endif if (pos >= CC_COLUMNS) { printf("cc_decoder: ccbuf_add_char: row buffer overflow\n"); return; } if (pos > rowbuf->num_chars) { /* fill up to indented position with transparent spaces, if necessary */ ccrow_fill_transp(rowbuf); } /* midrow PAC attributes are applied only if there is no displayable */ /* character to the immediate left. This makes the implementation rather */ /* complicated, but this is what the EIA-608 standard specifies. :-( */ if (rowbuf->pac_attr_chg && !rowbuf->attr_chg && !left_displayable) { rowbuf->attr_chg = 1; rowbuf->cells[pos].attributes = rowbuf->pac_attr; #ifdef LOG_DEBUG printf("cc_decoder: ccbuf_add_char: Applying midrow PAC.\n"); #endif } rowbuf->cells[pos].c = c; rowbuf->cells[pos].midrow_attr = rowbuf->attr_chg; rowbuf->pos++; if (rowbuf->num_chars < rowbuf->pos) rowbuf->num_chars = rowbuf->pos; rowbuf->attr_chg = 0; rowbuf->pac_attr_chg = 0; } static void ccbuf_set_cursor(cc_buffer_t *this, int row, int column, int underline, int italics, int color) { cc_row_t *rowbuf = &this->rows[row]; cc_attribute_t attr; attr.italic = italics; attr.underline = underline; attr.foreground = color; attr.background = BLACK; rowbuf->pac_attr = attr; rowbuf->pac_attr_chg = 1; this->rowpos = row; rowbuf->pos = column; rowbuf->attr_chg = 0; } static void ccbuf_apply_attribute(cc_buffer_t *this, cc_attribute_t *attr) { cc_row_t *rowbuf = &this->rows[this->rowpos]; int pos = rowbuf->pos; rowbuf->attr_chg = 1; rowbuf->cells[pos].attributes = *attr; /* A midrow attribute always counts as a space */ ccbuf_add_char(this, chartbl[(unsigned int) ' ']); } static void ccbuf_tab(cc_buffer_t *this, int tabsize) { cc_row_t *rowbuf = &this->rows[this->rowpos]; rowbuf->pos += tabsize; if (rowbuf->pos > CC_COLUMNS) { #ifdef LOG_DEBUG printf("cc_decoder: ccbuf_tab: row buffer overflow\n"); #endif rowbuf->pos = CC_COLUMNS; return; } /* tabs have no effect on pending PAC attribute changes */ } static void ccbuf_render(cc_renderer_t *renderer, cc_buffer_t *this) { int row; #ifdef LOG_DEBUG printf("cc_decoder: ccbuf_render\n"); #endif for (row = 0; row < CC_ROWS; ++row) { if (this->rows[row].num_chars > 0) ccrow_render(renderer, &this->rows[row], row); } } /*----------------- cc_memory_t methods --------------------------------*/ static void ccmem_clear(cc_memory_t *this) { #ifdef LOG_DEBUG printf("cc_decoder.c: ccmem_clear: Clearing CC memory\n"); #endif memset(this, 0, sizeof (cc_memory_t)); } static void ccmem_init(cc_memory_t *this) { ccmem_clear(this); } static void ccmem_exit(cc_memory_t *this) { /*FIXME: anything to deallocate?*/ (void)this; } /*----------------- cc_renderer_t methods -------------------------------*/ static void cc_renderer_build_palette(cc_renderer_t *this) { int i, j; const colorinfo_t *cc_text = cc_text_palettes[this->cc_state->cc_cfg->cc_scheme]; const uint8_t *cc_alpha = cc_alpha_palettes[this->cc_state->cc_cfg->cc_scheme]; memset(this->cc_palette, 0, sizeof (this->cc_palette)); memset(this->cc_trans, 0, sizeof (this->cc_trans)); for (i = 0; i < NUM_FG_COL; i++) { /* background color */ memcpy(&this->cc_palette[i * TEXT_PALETTE_SIZE + 1 + OSD_TEXT1], &cc_text[i].bgcol, sizeof(uint32_t)); /* background -> border */ for (j = 2; j <= 5; j++) { clut_t col = interpolate_color(cc_text[i].bgcol, cc_text[i].bordercol, 4, j - 1); memcpy(&this->cc_palette[i * TEXT_PALETTE_SIZE + j + OSD_TEXT1], &col, sizeof(uint32_t)); } /* border color */ memcpy(&this->cc_palette[i * TEXT_PALETTE_SIZE + 6 + OSD_TEXT1], &cc_text[i].bordercol, sizeof(uint32_t)); /* border -> foreground */ for (j = 7; j <= 9; j++) { clut_t col = interpolate_color(cc_text[i].bordercol, cc_text[i].textcol, 3, j - 6); memcpy(&this->cc_palette[i * TEXT_PALETTE_SIZE + j + OSD_TEXT1], &col, sizeof(uint32_t)); } /* foreground color */ memcpy(&this->cc_palette[i * TEXT_PALETTE_SIZE + 10 + OSD_TEXT1], &cc_text[i].textcol, sizeof(uint32_t)); /* alpha values */ for (j = 0; j <= 10; j++) this->cc_trans[i * TEXT_PALETTE_SIZE + j + OSD_TEXT1] = cc_alpha[j]; } } static int64_t cc_renderer_calc_vpts(cc_renderer_t *this, int64_t pts, uint32_t ntsc_frame_offset) { metronom_t *metronom = this->metronom; int64_t vpts = metronom->got_spu_packet(metronom, pts); return vpts + ntsc_frame_offset * NTSC_FRAME_DURATION; } /* returns true if a caption is on display */ static int cc_renderer_on_display(cc_renderer_t *this) { return this->displayed; } static void cc_renderer_hide_caption(cc_renderer_t *this, int64_t vpts) { if ( ! this->displayed ) return; this->osd_renderer->hide(this->cap_display, vpts); this->displayed = 0; this->last_hide_vpts = vpts; } static void cc_renderer_show_caption(cc_renderer_t *this, cc_buffer_t *buf, int64_t vpts) { #ifdef LOG_DEBUG printf("spucc: cc_renderer: show\n"); #endif if (this->displayed) { cc_renderer_hide_caption(this, vpts); printf("spucc: cc_renderer: show: OOPS - caption was already displayed!\n"); } this->osd_renderer->clear(this->cap_display); ccbuf_render(this, buf); this->osd_renderer->set_position(this->cap_display, this->x, this->y); vpts = MAX(vpts, this->last_hide_vpts); this->osd_renderer->show(this->cap_display, vpts); this->displayed = 1; this->display_vpts = vpts; } static void cc_renderer_free_osd_object(cc_renderer_t *this) { /* hide and free old displayed caption object if necessary */ if ( ! this->cap_display ) return; cc_renderer_hide_caption(this, this->display_vpts); this->osd_renderer->free_object(this->cap_display); this->cap_display = NULL; } static void cc_renderer_adjust_osd_object(cc_renderer_t *this) { cc_renderer_free_osd_object(this); #ifdef LOG_DEBUG printf("spucc: cc_renderer: adjust_osd_object: creating %dx%d OSD object\n", this->width, this->height); #endif /* create display object */ this->cap_display = this->osd_renderer->new_object(this->osd_renderer, this->width, this->height); this->osd_renderer->set_palette(this->cap_display, this->cc_palette, this->cc_trans); this->osd_renderer->set_encoding(this->cap_display, "iso-8859-1"); } cc_renderer_t *cc_renderer_open(osd_renderer_t *osd_renderer, metronom_t *metronom, cc_state_t *cc_state, int video_width, int video_height) { cc_renderer_t *this; this = calloc(1, sizeof (cc_renderer_t)); if (!this) return NULL; this->osd_renderer = osd_renderer; this->metronom = metronom; this->cc_state = cc_state; cc_renderer_update_cfg(this, video_width, video_height); #ifdef LOG_DEBUG printf("spucc: cc_renderer: open\n"); #endif return this; } void cc_renderer_close(cc_renderer_t *this_obj) { cc_renderer_free_osd_object(this_obj); free(this_obj); #ifdef LOG_DEBUG printf("spucc: cc_renderer: close\n"); #endif } void cc_renderer_update_cfg(cc_renderer_t *this_obj, int video_width, int video_height) { int fontw, fonth; int required_w, required_h; this_obj->video_width = video_width; this_obj->video_height = video_height; /* fill in text palette */ cc_renderer_build_palette(this_obj); /* calculate preferred captioning area, as per the EIA-608 standard */ this_obj->x = this_obj->video_width * 10 / 100; this_obj->y = this_obj->video_height * 10 / 100; this_obj->width = this_obj->video_width * 80 / 100; this_obj->height = this_obj->video_height * 80 / 100; /* find maximum text width and height for normal & italic captioning */ /* font */ get_font_metrics(this_obj->osd_renderer, this_obj->cc_state->cc_cfg->font, this_obj->cc_state->cc_cfg->font_size, &fontw, &fonth); this_obj->max_char_width = fontw; this_obj->max_char_height = fonth; get_font_metrics(this_obj->osd_renderer, this_obj->cc_state->cc_cfg->italic_font, this_obj->cc_state->cc_cfg->font_size, &fontw, &fonth); this_obj->max_char_width = MAX(fontw, this_obj->max_char_width); this_obj->max_char_height = MAX(fonth, this_obj->max_char_height); #ifdef LOG_DEBUG printf("spucc: cc_renderer: update config: max text extents: %d, %d\n", this_obj->max_char_width, this_obj->max_char_height); #endif /* need to adjust captioning area to accommodate font? */ required_w = CC_COLUMNS * (this_obj->max_char_width + 1); required_h = CC_ROWS * (this_obj->max_char_height + 1); if (required_w > this_obj->width) { #ifdef LOG_DEBUG printf("spucc: cc_renderer: update config: adjusting cap area width: %d\n", required_w); #endif this_obj->width = required_w; this_obj->x = (this_obj->video_width - required_w) / 2; } if (required_h > this_obj->height) { #ifdef LOG_DEBUG printf("spucc: cc_renderer: update config: adjusting cap area height: %d\n", required_h); #endif this_obj->height = required_h; this_obj->y = (this_obj->video_height - required_h) / 2; } if (required_w <= this_obj->video_width && required_h <= this_obj->video_height) { this_obj->cc_state->can_cc = 1; cc_renderer_adjust_osd_object(this_obj); } else { this_obj->cc_state->can_cc = 0; cc_renderer_free_osd_object(this_obj); printf("spucc: required captioning area %dx%d exceeds screen %dx%d!\n" " Captions disabled. Perhaps you should choose a smaller" " font?\n", required_w, required_h, this_obj->video_width, this_obj->video_height); } } /*----------------- cc_decoder_t methods --------------------------------*/ static void cc_set_channel(cc_decoder_t *this, int channel) { (*this->active)->channel_no = channel; #ifdef LOG_DEBUG printf("cc_decoder: cc_set_channel: selecting channel %d\n", channel); #endif } static cc_buffer_t *active_ccbuffer(cc_decoder_t *this) { cc_memory_t *mem = *this->active; return &mem->channel[mem->channel_no]; } static int cc_onscreen_displayable(cc_decoder_t *this) { return ccbuf_has_displayable(&this->on_buf->channel[this->on_buf->channel_no]); } static void cc_hide_displayed(cc_decoder_t *this) { #ifdef LOG_DEBUG printf("cc_decoder: cc_hide_displayed\n"); #endif if (cc_renderer_on_display(this->cc_state->renderer)) { int64_t vpts = cc_renderer_calc_vpts(this->cc_state->renderer, this->pts, this->f_offset); #ifdef LOG_DEBUG printf("cc_decoder: cc_hide_displayed: hiding caption %u at vpts %u\n", this->capid, vpts); #endif cc_renderer_hide_caption(this->cc_state->renderer, vpts); } } static void cc_show_displayed(cc_decoder_t *this) { #ifdef LOG_DEBUG printf("cc_decoder: cc_show_displayed\n"); #endif if (cc_onscreen_displayable(this)) { int64_t vpts = cc_renderer_calc_vpts(this->cc_state->renderer, this->pts, this->f_offset); #ifdef LOG_DEBUG printf("cc_decoder: cc_show_displayed: showing caption %u at vpts %u\n", this->capid, vpts); #endif this->capid++; cc_renderer_show_caption(this->cc_state->renderer, &this->on_buf->channel[this->on_buf->channel_no], vpts); } } static void cc_swap_buffers(cc_decoder_t *this) { cc_memory_t *temp; /* hide caption in displayed memory */ cc_hide_displayed(this); #ifdef LOG_DEBUG printf("cc_decoder: cc_swap_buffers: swapping caption memory\n"); #endif temp = this->on_buf; this->on_buf = this->off_buf; this->off_buf = temp; /* show new displayed memory */ cc_show_displayed(this); } static void cc_decode_standard_char(cc_decoder_t *this, uint8_t c1, uint8_t c2) { cc_buffer_t *buf = active_ccbuffer(this); /* c1 always is a valid character */ ccbuf_add_char(buf, chartbl[c1]); /* c2 might not be a printable character, even if c1 was */ if (c2 & 0x60) ccbuf_add_char(buf, chartbl[c2]); } static void cc_decode_PAC(cc_decoder_t *this, int channel, uint8_t c1, uint8_t c2) { cc_buffer_t *buf; int row, column = 0; int underline, italics = 0, color; /* There is one invalid PAC code combination. Ignore it. */ if (c1 == 0x10 && c2 > 0x5f) return; cc_set_channel(this, channel); buf = active_ccbuffer(this); row = rowdata[((c1 & 0x07) << 1) | ((c2 & 0x20) >> 5)]; if (c2 & 0x10) { column = ((c2 & 0x0e) >> 1) * 4; /* preamble indentation */ color = WHITE; /* indented lines have white color */ } else if ((c2 & 0x0e) == 0x0e) { italics = 1; /* italics, they are always white */ color = WHITE; } else color = (c2 & 0x0e) >> 1; underline = c2 & 0x01; #ifdef LOG_DEBUG printf("cc_decoder: cc_decode_PAC: row %d, col %d, ul %d, it %d, clr %d\n", row, column, underline, italics, color); #endif ccbuf_set_cursor(buf, row, column, underline, italics, color); } static void cc_decode_ext_attribute(cc_decoder_t *this, int channel, uint8_t c1, uint8_t c2) { (void)c1; (void)c2; cc_set_channel(this, channel); } static void cc_decode_special_char(cc_decoder_t *this, int channel, uint8_t c1, uint8_t c2) { cc_buffer_t *buf; (void)c1; cc_set_channel(this, channel); buf = active_ccbuffer(this); #ifdef LOG_DEBUG printf("cc_decoder: cc_decode_special_char: Mapping %x to %x\n", c2, specialchar[c2 & 0xf]); #endif ccbuf_add_char(buf, specialchar[c2 & 0xf]); } static void cc_decode_midrow_attr(cc_decoder_t *this, int channel, uint8_t c1, uint8_t c2) { cc_buffer_t *buf; cc_attribute_t attr; (void)c1; cc_set_channel(this, channel); buf = active_ccbuffer(this); if (c2 < 0x2e) { attr.italic = 0; attr.foreground = (c2 & 0xe) >> 1; } else { attr.italic = 1; attr.foreground = WHITE; } attr.underline = c2 & 0x1; attr.background = BLACK; #ifdef LOG_DEBUG printf("cc_decoder: cc_decode_midrow_attr: attribute %x\n", c2); printf("cc_decoder: cc_decode_midrow_attr: ul %d, it %d, clr %d\n", attr.underline, attr.italic, attr.foreground); #endif ccbuf_apply_attribute(buf, &attr); } static void cc_decode_misc_control_code(cc_decoder_t *this, int channel, uint8_t c1, uint8_t c2) { #ifdef LOG_DEBUG printf("cc_decoder: decode_misc: decoding %x %x\n", c1, c2); #endif (void)c1; cc_set_channel(this, channel); switch (c2) { /* 0x20 <= c2 <= 0x2f */ case 0x20: /* RCL */ break; case 0x21: /* backspace */ #ifdef LOG_DEBUG printf("cc_decoder: backspace\n"); #endif break; case 0x24: /* DER */ break; case 0x25: /* RU2 */ break; case 0x26: /* RU3 */ break; case 0x27: /* RU4 */ break; case 0x28: /* FON */ break; case 0x29: /* RDC */ break; case 0x2a: /* TR */ break; case 0x2b: /* RTD */ break; case 0x2c: /* EDM - erase displayed memory */ cc_hide_displayed(this); ccmem_clear(this->on_buf); break; case 0x2d: /* carriage return */ break; case 0x2e: /* ENM - erase non-displayed memory */ ccmem_clear(this->off_buf); break; case 0x2f: /* EOC - swap displayed and non displayed memory */ cc_swap_buffers(this); break; } } static void cc_decode_tab(cc_decoder_t *this, int channel, uint8_t c1, uint8_t c2) { cc_buffer_t *buf; (void)c1; cc_set_channel(this, channel); buf = active_ccbuffer(this); ccbuf_tab(buf, c2 & 0x3); } static void cc_decode_EIA608(cc_decoder_t *this, uint16_t data) { uint8_t c1 = data & 0x7f; uint8_t c2 = (data >> 8) & 0x7f; #if LOG_DEBUG >= 3 printf("decoding %x %x\n", c1, c2); #endif if (c1 & 0x60) { /* normal character, 0x20 <= c1 <= 0x7f */ cc_decode_standard_char(this, c1, c2); } else if (c1 & 0x10) { /* control code or special character */ /* 0x10 <= c1 <= 0x1f */ int channel = (c1 & 0x08) >> 3; c1 &= ~0x08; /* control sequences are often repeated. In this case, we should */ /* evaluate it only once. */ if (data != this->lastcode) { if (c2 & 0x40) { /* preamble address code: 0x40 <= c2 <= 0x7f */ cc_decode_PAC(this, channel, c1, c2); } else { switch (c1) { case 0x10: /* extended background attribute code */ cc_decode_ext_attribute(this, channel, c1, c2); break; case 0x11: /* attribute or special character */ if ((c2 & 0x30) == 0x30) { /* special char: 0x30 <= c2 <= 0x3f */ cc_decode_special_char(this, channel, c1, c2); } else if (c2 & 0x20) { /* midrow attribute: 0x20 <= c2 <= 0x2f */ cc_decode_midrow_attr(this, channel, c1, c2); } break; case 0x14: /* possibly miscellaneous control code */ cc_decode_misc_control_code(this, channel, c1, c2); break; case 0x17: /* possibly misc. control code TAB offset */ /* 0x21 <= c2 <= 0x23 */ if (c2 >= 0x21 && c2 <= 0x23) { cc_decode_tab(this, channel, c1, c2); } break; } } } } this->lastcode = data; } void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len, int64_t pts) { /* The first number may denote a channel number. I don't have the * EIA-708 standard, so it is hard to say. * From what I could figure out so far, the general format seems to be: * * repeat * * 0xfe starts 2 byte sequence of unknown purpose. It might denote * field #2 in line 21 of the VBI. We'll ignore it for the * time being. * * 0xff starts 2 byte EIA-608 sequence, field #1 in line 21 of the VBI. * Followed by a 3-code triplet that starts either with 0xff or * 0xfe. In either case, the following triplet needs to be ignored * for line 21, field 1. * * 0x00 is padding, followed by 2 more 0x00. * * 0x01 always seems to appear at the beginning, always seems to * be followed by 0xf8, 8-bit number. * The lower 7 bits of this 8-bit number seem to denote the * number of code triplets that follow. * The most significant bit denotes whether the Line 21 field 1 * captioning information is at odd or even triplet offsets from this * beginning triplet. 1 denotes odd offsets, 0 denotes even offsets. * * Most captions are encoded with odd offsets, so this is what we * will assume. * * until end of packet */ uint8_t *current = buffer; uint32_t curbytes = 0; uint8_t data1, data2; uint8_t cc_code; int odd_offset = 1; this->f_offset = 0; this->pts = pts; #if LOG_DEBUG >= 2 printf("libspucc: decode_cc: got pts %u\n", pts); { uint8_t *cur_d = buffer; printf("libspucc: decode_cc: codes: "); while (cur_d < buffer + buf_len) { printf("0x%0x ", *cur_d++); } printf("\n"); } #endif while (curbytes < buf_len) { int skip = 2; cc_code = *current++; curbytes++; if (buf_len - curbytes < 2) { #ifdef LOG_DEBUG fprintf(stderr, "Not enough data for 2-byte CC encoding\n"); #endif break; } data1 = *current; data2 = *(current + 1); switch (cc_code) { case 0xfe: /* expect 2 byte encoding (perhaps CC3, CC4?) */ /* ignore for time being */ skip = 2; break; case 0xff: /* expect EIA-608 CC1/CC2 encoding */ if (good_parity(data1 | (data2 << 8))) { cc_decode_EIA608(this, data1 | (data2 << 8)); this->f_offset++; } skip = 5; break; case 0x00: /* This seems to be just padding */ skip = 2; break; case 0x01: odd_offset = data2 & 0x80; if (odd_offset) skip = 2; else skip = 5; break; default: #ifdef LOG_DEBUG fprintf(stderr, "Unknown CC encoding: %x\n", cc_code); #endif skip = 2; break; } current += skip; curbytes += skip; } } cc_decoder_t *cc_decoder_open(cc_state_t *cc_state) { cc_decoder_t *this; this = calloc(1, sizeof (cc_decoder_t)); if (!this) return NULL; /* configfile stuff */ this->cc_state = cc_state; ccmem_init(&this->buffer[0]); ccmem_init(&this->buffer[1]); this->on_buf = &this->buffer[0]; this->off_buf = &this->buffer[1]; this->active = &this->off_buf; this->lastcode = 0; this->capid = 0; this->pts = this->f_offset = 0; #ifdef LOG_DEBUG printf("spucc: cc_decoder_open\n"); #endif return this; } void cc_decoder_close(cc_decoder_t *this) { ccmem_exit(&this->buffer[0]); ccmem_exit(&this->buffer[1]); free(this); #ifdef LOG_DEBUG printf("spucc: cc_decoder_close\n"); #endif } xine-lib-1.2/src/spu_dec/cmml_decoder.c0000644000175000017500000004035414647725152015664 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define LOG_MODULE "libspucmml" #define LOG_VERBOSE /* #define LOG */ #define LOG_OSD 0 #define LOG_SCHEDULING 0 #define LOG_WIDTH 0 #define SUB_BUFSIZE 1024 #define SUB_MAX_TEXT 5 #include typedef enum { SUBTITLE_SIZE_SMALL = 0, SUBTITLE_SIZE_NORMAL, SUBTITLE_SIZE_LARGE, SUBTITLE_SIZE_NUM /* number of values in enum */ } subtitle_size; typedef struct spucmml_class_s { spu_decoder_class_t class; const char *src_encoding; /* encoding of subtitle file */ xine_t *xine; } spucmml_class_t; typedef struct cmml_anchor_s { char *text; char *href; } cmml_anchor_t; typedef struct spucmml_decoder_s { spu_decoder_t spu_decoder; spucmml_class_t *class; xine_stream_t *stream; #if 0 xine_event_queue_t *event_queue; #endif int lines; char text[SUB_MAX_TEXT][SUB_BUFSIZE]; int cached_width; /* frame width */ int cached_height; /* frame height */ int64_t cached_img_duration; int font_size; int line_height; int master_started; int slave_started; const char *font; /* subtitle font */ subtitle_size subtitle_size; /* size of subtitles */ int vertical_offset; osd_object_t *osd; cmml_anchor_t current_anchor; } spucmml_decoder_t; static void update_font_size (spucmml_decoder_t *this) { static const int sizes[SUBTITLE_SIZE_NUM][4] = { { 16, 16, 16, 20 }, /* SUBTITLE_SIZE_SMALL */ { 16, 16, 20, 24 }, /* SUBTITLE_SIZE_NORMAL */ { 16, 20, 24, 32 }, /* SUBTITLE_SIZE_LARGE */ }; const int *const vec = sizes[this->subtitle_size]; if( this->cached_width >= 512 ) this->font_size = vec[3]; else if( this->cached_width >= 384 ) this->font_size = vec[2]; else if( this->cached_width >= 320 ) this->font_size = vec[1]; else this->font_size = vec[0]; this->line_height = this->font_size + 10; int y = this->cached_height - (SUB_MAX_TEXT * this->line_height) - 5; if(((y - this->vertical_offset) >= 0) && ((y - this->vertical_offset) <= this->cached_height)) y -= this->vertical_offset; /* TODO: we should move this stuff below into another function */ if (this->osd) this->stream->osd_renderer->free_object (this->osd); llprintf (LOG_OSD, "pre new_object: osd=%p, osd_renderer=%p, width=%d, height=%d\n", (void*)this->osd, (void*)this->stream->osd_renderer, this->cached_width, SUB_MAX_TEXT * this->line_height); this->osd = this->stream->osd_renderer->new_object (this->stream->osd_renderer, this->cached_width, SUB_MAX_TEXT * this->line_height); llprintf (LOG_OSD, "post new_object: osd is %p\n", (void*)this->osd); if(this->stream->osd_renderer) { this->stream->osd_renderer->set_font (this->osd, this->font, this->font_size); this->stream->osd_renderer->set_position (this->osd, 0, y); } } static int get_width(spucmml_decoder_t *this, char* text) { int width=0; while (1) switch (*text) { case '\0': llprintf(LOG_WIDTH, "get_width returning width of %d\n", width); return width; case '<': if (!strncmp("", text, 3)) { /*Do somethink to enable BOLD typeface*/ text += 3; break; } else if (!strncmp("", text, 3)) { /*Do somethink to disable BOLD typeface*/ text += 4; break; } else if (!strncmp("", text, 3)) { /*Do somethink to enable italics typeface*/ text += 3; break; } else if (!strncmp("", text, 3)) { /*Do somethink to disable italics typeface*/ text += 4; break; } else if (!strncmp("", text, 3)) { /*Do somethink to disable typing fixme - no teststreams*/ text += 6; break; } else if (!strncmp("", text, 3)) { /*Do somethink to enable typing fixme - no teststreams*/ text += 7; break; } /* fall through */ default: { int w, dummy; const char letter[2] = { *text, '\0' }; this->stream->osd_renderer->get_text_size(this->osd, letter, &w, &dummy); width += w; text++; } } } static void render_line(spucmml_decoder_t *this, int x, int y, char* text) { while (*text != '\0') { int w, dummy; const char letter[2] = { *text, '\0' }; this->stream->osd_renderer->render_text(this->osd, x, y, letter, OSD_TEXT1); this->stream->osd_renderer->get_text_size(this->osd, letter, &w, &dummy); x += w; text++; } } static void draw_subtitle(spucmml_decoder_t *this, int64_t sub_start) { this->stream->osd_renderer->filled_rect (this->osd, 0, 0, this->cached_width-1, this->line_height * SUB_MAX_TEXT - 1, 0); const int y = (SUB_MAX_TEXT - this->lines) * this->line_height; int font_size = this->font_size; this->stream->osd_renderer->set_encoding(this->osd, this->class->src_encoding); int line; for (line=0; linelines; line++) { int x; while(1) { const int w = get_width( this, this->text[line]); x = (this->cached_width - w) / 2; if( w > this->cached_width && font_size > 16 ) { font_size -= 4; this->stream->osd_renderer->set_font (this->osd, this->font, font_size); } else { break; } } render_line(this, x, y + line*this->line_height, this->text[line]); } if( font_size != this->font_size ) this->stream->osd_renderer->set_font (this->osd, this->font, this->font_size); this->stream->osd_renderer->set_text_palette (this->osd, -1, OSD_TEXT1); this->stream->osd_renderer->show (this->osd, sub_start); llprintf (LOG_SCHEDULING, "spucmml: scheduling subtitle >%s< at %"PRId64", current time is %"PRId64"\n", this->text[0], sub_start, this->stream->xine->clock->get_current_time (this->stream->xine->clock)); } static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; xml_parser_t *xml_parser; xml_node_t *packet_xml_root; char * anchor_text = NULL; lprintf("CMML packet seen\n"); char *str = (char *) buf->content; /* parse the CMML */ xml_parser = xml_parser_init_r (str, strlen (str), XML_PARSER_CASE_INSENSITIVE); if (xml_parser_build_tree_r(xml_parser, &packet_xml_root) != XML_PARSER_OK) { lprintf ("warning: invalid XML packet detected in CMML track\n"); xml_parser_finalize_r(xml_parser); return; } xml_parser_finalize_r(xml_parser); if (strcasecmp(packet_xml_root->name, "head") == 0) { /* found a ... packet: need to parse the title */ xml_node_t *title_node; /* iterate through children trying to find the title node */ for (title_node = packet_xml_root->child; title_node != NULL; title_node = title_node->next) { if (title_node->data && strcasecmp (title_node->name, "title") == 0) { /* found a title node */ xine_ui_data_t data = { .str_len = strlen(title_node->data) + 1 }; xine_event_t uevent = { .type = XINE_EVENT_UI_SET_TITLE, .stream = this->stream, .data = &data, .data_length = sizeof(data), }; strncpy(data.str, title_node->data, sizeof(data.str)-1); /* found a non-empty title */ lprintf ("found title: \"%s\"\n", data.str); /* set xine meta-info */ _x_meta_info_set(this->stream, XINE_META_INFO_TITLE, data.str); /* and push out a new event signifying the title update on the event * queue */ xine_event_send(this->stream, &uevent); } } } else if (strcasecmp(packet_xml_root->name, "clip") == 0) { /* found a ... packet: search for the in it */ xml_node_t *clip_node; /* iterate through each tag contained in the tag to look for */ for (clip_node = packet_xml_root->child; clip_node != NULL; clip_node = clip_node->next) { if (strcasecmp (clip_node->name, "a") == 0) { xml_property_t *href_property; /* found the tag: grab its value and its href property */ if (clip_node->data) { free(anchor_text); anchor_text = strdup (clip_node->data); } for (href_property = clip_node->props; href_property != NULL; href_property = href_property->next) { if (strcasecmp (href_property->name, "href") == 0) { /* found the href property */ char *href = href_property->value; if (href) { lprintf ("found href: \"%s\"\n", href); this->current_anchor.href = strdup(href); } } } } } } /* finish here if we don't have to process any anchor text */ if (!anchor_text) return; /* how many lines does the anchor text take up? */ this->lines=0; { int i = 0, index = 0; while (anchor_text[index]) { if (anchor_text[index] == '\r' || anchor_text[index] == '\n') { if (i) { /* match a newline and there are chars on the current line ... */ this->text[ this->lines ][i] = '\0'; this->lines++; i = 0; } } else { /* found a normal (non-line-ending) character */ this->text[ this->lines ][i] = anchor_text[index]; if (itext[ this->lines ][i] = '\0'; this->lines++; } } free (anchor_text); /* initialize decoder if needed */ if( !this->cached_width || !this->cached_height || !this->cached_img_duration || !this->osd ) { if( this->stream->video_out->status(this->stream->video_out, NULL, &this->cached_width, &this->cached_height, &this->cached_img_duration )) { if( this->cached_width && this->cached_height && this->cached_img_duration ) { lprintf("this->stream->osd_renderer is %p\n", (void*)this->stream->osd_renderer); } } } update_font_size (this); if( this->osd ) { draw_subtitle(this, buf->pts); return; } else { lprintf ("libspucmml: no osd\n"); } return; } #if 0 static void video_frame_format_change_callback (void *user_data, const xine_event_t *event) { /* this doesn't do anything for now: it's a start at attempting to display * CMML clips which occur at 0 seconds into the track. see * * http://marc.theaimsgroup.com/?l=xine-devel&m=109202443013890&w=2 * * for a description of the problem. */ (void)user_data; switch (event->type) { case XINE_EVENT_FRAME_FORMAT_CHANGE: lprintf("video_frame_format_change_callback called!\n"); break; default: lprintf("video_frame_format_change_callback called with unknown event %d\n", event->type); break; } } #endif static void spudec_reset (spu_decoder_t *this_gen) { spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; this->cached_width = this->cached_height = 0; } static void spudec_discontinuity (spu_decoder_t *this_gen) { /* do nothing */ (void)this_gen; } static void spudec_dispose (spu_decoder_t *this_gen) { spucmml_decoder_t *this = (spucmml_decoder_t *) this_gen; config_values_t *config = this->class->xine->config; config->unregister_callback(config, "subtitles.separate.font"); config->unregister_callback(config, "subtitles.separate.vertical_offset"); #if 0 if (this->event_queue) xine_event_dispose_queue (this->event_queue); #endif if (this->osd) { this->stream->osd_renderer->free_object (this->osd); this->osd = NULL; } free(this); } static void update_vertical_offset(void *this_gen, xine_cfg_entry_t *entry) { spucmml_decoder_t *this = (spucmml_decoder_t *)this_gen; this->vertical_offset = entry->num_value; update_font_size(this); } static void update_osd_font(void *this_gen, xine_cfg_entry_t *entry) { spucmml_decoder_t *this = (spucmml_decoder_t *)this_gen; this->font = entry->str_value; if( this->stream->osd_renderer ) this->stream->osd_renderer->set_font (this->osd, this->font, this->font_size); } static spu_decoder_t *spucmml_class_open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { spucmml_class_t *class = (spucmml_class_t *)class_gen; spucmml_decoder_t *this; this = (spucmml_decoder_t *) calloc(1, sizeof(spucmml_decoder_t)); if (!this) return NULL; this->spu_decoder.decode_data = spudec_decode_data; this->spu_decoder.reset = spudec_reset; this->spu_decoder.discontinuity = spudec_discontinuity; this->spu_decoder.dispose = spudec_dispose; this->spu_decoder.get_interact_info = NULL; this->spu_decoder.set_button = NULL; this->spu_decoder.dispose = spudec_dispose; this->class = class; this->stream = stream; #if 0 this->event_queue = xine_event_new_queue (this->stream); xine_event_create_listener_thread (this->event_queue, video_frame_format_change_callback, this); #endif this->font_size = 24; this->subtitle_size = 1; this->font = class->xine->config->register_string(class->xine->config, "subtitles.separate.font", "sans", _("font for external subtitles"), NULL, 0, update_osd_font, this); this->vertical_offset = class->xine->config->register_num(class->xine->config, "subtitles.separate.vertical_offset", 0, _("subtitle vertical offset (relative window size)"), NULL, 0, update_vertical_offset, this); this->current_anchor.href = NULL; lprintf ("video_out is at %p\n", (void*)this->stream->video_out); return (spu_decoder_t *) this; } static void update_src_encoding(void *this_gen, xine_cfg_entry_t *entry) { spucmml_class_t *this = (spucmml_class_t *)this_gen; this->src_encoding = entry->str_value; printf("libspucmml: spu_src_encoding = %s\n", this->src_encoding ); } static void spu_decoder_class_dispose(spu_decoder_class_t *this_gen) { spucmml_class_t *this = (spucmml_class_t *)this_gen; this->xine->config->unregister_callback(this->xine->config, "subtitles.separate.src_encoding"); free(this); } static void *init_spu_decoder_plugin (xine_t *xine, const void *data) { spucmml_class_t *this; (void)data; this = (spucmml_class_t *) calloc(1, sizeof(spucmml_class_t)); if (!this) return NULL; this->class.open_plugin = spucmml_class_open_plugin; this->class.identifier = "spucmml"; this->class.description = N_("CMML subtitle decoder plugin"); this->class.dispose = spu_decoder_class_dispose; this->xine = xine; this->src_encoding = xine->config->register_string(xine->config, "subtitles.separate.src_encoding", "iso-8859-1", _("encoding of subtitles"), NULL, 10, update_src_encoding, this); return &this->class; } /* plugin catalog information */ static const uint32_t supported_types[] = { BUF_SPU_CMML, 0 }; static const decoder_info_t spudec_info = { .supported_types = supported_types, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_SPU_DECODER, 17, "spucmml", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/spu_dec/spuhdmv_decoder.c0000644000175000017500000007074114647725152016425 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * Copyright (C) 2009-2020 Petri Hintukainen * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Decoder for HDMV/BluRay bitmap subtitles */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #define LOG_MODULE "spu_hdmv" /* #define LOG */ #include #include #include #include #include #define XINE_HDMV_TRACE lprintf #ifndef MAX # define MAX(a,b) (a>b)?(a):(b) #endif enum { SEGTYPE_PALETTE = 0x14, SEGTYPE_OBJECT = 0x15, SEGTYPE_PRESENTATION_SEGMENT = 0x16, SEGTYPE_WINDOW_DEFINITION = 0x17, SEGTYPE_INTERACTIVE = 0x18, SEGTYPE_END_OF_DISPLAY = 0x80, } eSegmentType; /* * cached palette (xine-lib format) */ typedef struct subtitle_clut_s subtitle_clut_t; struct subtitle_clut_s { uint8_t id; uint32_t color[256]; uint8_t trans[256]; subtitle_clut_t *next; int shown; }; /* * cached RLE image (xine-lib format) */ typedef struct subtitle_object_s subtitle_object_t; struct subtitle_object_s { uint16_t id; uint16_t xpos, ypos; uint16_t width, height; /* xine format */ rle_elem_t *rle; unsigned int num_rle; size_t data_size; /* HDMV format (used when object does not fit to single segment) */ uint32_t data_len; /* size of complete object */ uint8_t *raw_data; /* partial RLE data in HDMV format */ size_t raw_data_len; /* bytes buffered */ size_t raw_data_size; /* allocated size */ subtitle_object_t *next; int shown; }; /* * Window definition */ typedef struct window_def_s window_def_t; struct window_def_s { uint8_t id; uint16_t xpos, ypos; uint16_t width, height; window_def_t *next; int shown; }; /* * decoded SPU */ typedef struct composition_object_s composition_object_t; struct composition_object_s { uint8_t window_id_ref; uint16_t object_id_ref; uint16_t xpos, ypos; uint8_t forced_flag; uint8_t cropped_flag; uint16_t crop_horiz_pos, crop_vert_pos; uint16_t crop_width, crop_height; composition_object_t *next; int shown; }; typedef struct composition_descriptor_s composition_descriptor_t; struct composition_descriptor_s { uint16_t number; uint8_t state; }; typedef struct presentation_segment_s presentation_segment_t; struct presentation_segment_s { composition_descriptor_t comp_descr; uint8_t palette_update_flag; uint8_t palette_id_ref; uint8_t object_number; composition_object_t *comp_objs; presentation_segment_t *next; int64_t pts; int shown; }; /* * list handling */ #define LIST_REPLACE(list, obj, FREE_FUNC) \ do { \ unsigned int id = obj->id; \ \ /* insert to list */ \ obj->next = list; \ list = obj; \ \ /* remove old */ \ while (obj->next && obj->next->id != id) \ obj = obj->next; \ if (obj->next) { \ void *tmp = (void*)obj->next; \ obj->next = obj->next->next; \ FREE_FUNC(tmp); \ } \ } while (0); #define LIST_DESTROY(list, FREE_FUNC) \ while (list) { \ void *tmp = (void*)list; \ list = list->next; \ FREE_FUNC(tmp); \ } static void free_subtitle_object(void *ptr) { if (ptr) { _x_freep(&((subtitle_object_t*)ptr)->rle); _x_freep(&((subtitle_object_t*)ptr)->raw_data); free(ptr); } } static void free_presentation_segment(void *ptr) { if (ptr) { presentation_segment_t *seg = (presentation_segment_t*)ptr; LIST_DESTROY(seg->comp_objs, free); free(ptr); } } /* * segment_buffer_t * * assemble and decode segments */ typedef struct { /* current segment */ int segment_len; /* length of current segment (without 3-byte header) */ uint8_t segment_type; /* current segment type */ uint8_t *segment_data; /* pointer to current segment payload */ uint8_t *segment_end; /* pointer to last byte + 1 of current segment */ uint8_t error; /* boolean: buffer overflow etc. */ /* accumulated data */ uint8_t *buf; /* */ size_t len; /* count of unprocessed bytes */ size_t data_size; /* allocated buffer size */ } segment_buffer_t; /* * mgmt */ static segment_buffer_t *segbuf_init(void) { segment_buffer_t *buf = calloc(1, sizeof(segment_buffer_t)); return buf; } static void segbuf_dispose(segment_buffer_t *buf) { _x_freep (&buf->buf); free (buf); } static void segbuf_reset(segment_buffer_t *buf) { buf->segment_end = buf->segment_data = buf->buf; buf->len = 0; buf->segment_len = -1; buf->segment_type = 0; buf->error = 0; } /* * assemble, parse */ static void segbuf_parse_segment_header(segment_buffer_t *buf) { if (buf->len > 2) { buf->segment_type = buf->buf[0]; buf->segment_len = (buf->buf[1] << 8) | buf->buf[2]; buf->segment_data = buf->buf + 3; buf->segment_end = buf->segment_data + buf->segment_len; buf->error = 0; if ( buf->segment_type < 0x14 || ( buf->segment_type > 0x18 && buf->segment_type != 0x80)) { XINE_HDMV_TRACE("unknown segment type 0x%02x, resetting\n", buf->segment_type); segbuf_reset(buf); } } else { buf->segment_len = -1; buf->error = 1; } } static void segbuf_fill(segment_buffer_t *buf, uint8_t *data, size_t len) { if (buf->len + len > buf->data_size) { buf->data_size = buf->len + len; buf->buf = realloc(buf->buf, buf->data_size); } memcpy(buf->buf + buf->len, data, len); buf->len += len; segbuf_parse_segment_header(buf); } static int segbuf_segment_complete(segment_buffer_t *buf) { return (buf->segment_len >= 0) && (buf->len >= (unsigned)buf->segment_len + 3); } static void segbuf_skip_segment(segment_buffer_t *buf) { _x_assert (segbuf_segment_complete (buf)); buf->len -= buf->segment_len + 3; if (buf->len > 0) memmove(buf->buf, buf->buf + buf->segment_len + 3, buf->len); segbuf_parse_segment_header(buf); XINE_HDMV_TRACE(" skip_segment: %zd bytes left\n", buf->len); } /* * access segment data */ static uint8_t segbuf_segment_type(segment_buffer_t *buf) { return buf->segment_type; } static size_t segbuf_data_length(segment_buffer_t *buf) { ssize_t val = buf->segment_end - buf->segment_data; if (val < 0) val = 0; return (size_t)val; } static uint8_t segbuf_get_u8(segment_buffer_t *buf) { if (!(buf->error = ++buf->segment_data > buf->segment_end)) return buf->segment_data[-1]; XINE_HDMV_TRACE("segbuf_get_u8: read failed (end of segment reached) !\n"); return 0; } static uint16_t segbuf_get_u16(segment_buffer_t *buf) { return (segbuf_get_u8(buf) << 8) | segbuf_get_u8(buf); } static uint32_t segbuf_get_u24(segment_buffer_t *buf) { return (segbuf_get_u8(buf) << 16) | (segbuf_get_u8(buf) << 8) | segbuf_get_u8(buf); } /* * decode segments */ static subtitle_clut_t *segbuf_decode_palette(segment_buffer_t *buf) { subtitle_clut_t *clut; uint8_t palette_id = segbuf_get_u8 (buf); uint8_t palette_version_number = segbuf_get_u8 (buf); size_t len = segbuf_data_length(buf); size_t entries = len / 5; size_t i; if (buf->error) return NULL; if (len % 5) { XINE_HDMV_TRACE(" decode_palette: segment size error (%zd ; expected %zd for %zd entries)\n", len, (5 * entries), entries); return NULL; } (void)palette_version_number; XINE_HDMV_TRACE("decode_palette: %zd items (id %d, version %d)\n", entries, palette_id, palette_version_number); /* convert to xine-lib clut */ clut = calloc(1, sizeof(subtitle_clut_t)); if (!clut) return NULL; clut->id = palette_id; for (i = 0; i < entries; i++) { uint8_t index = segbuf_get_u8 (buf); uint8_t Y = segbuf_get_u8 (buf); uint8_t Cr = segbuf_get_u8 (buf); uint8_t Cb = segbuf_get_u8 (buf); uint8_t alpha = segbuf_get_u8 (buf); #ifdef WORDS_BIGENDIAN clut->color[index] = (Y << 8) | (Cr << 16) | (Cb << 24); #else clut->color[index] = (Y << 16) | (Cr << 8) | Cb; #endif clut->trans[index] = alpha >> 4; } /* HDMV subs always use same color matrix as main video. */ _X_SET_CLUT_CM (clut->color, 4); return clut; } static int segbuf_decode_rle(segment_buffer_t *buf, subtitle_object_t *obj) { int x = 0, y = 0; int rle_size = sizeof(rle_elem_t) * obj->width / 16 * obj->height + 1; rle_elem_t *rlep = malloc(rle_size); free (obj->rle); obj->rle = rlep; obj->data_size = rle_size; obj->num_rle = 0; /* convert to xine-lib rle format */ while (y < obj->height && !buf->error) { /* decode RLE element */ uint8_t byte = segbuf_get_u8 (buf); if (byte != 0) { rlep->color = byte; rlep->len = 1; } else { byte = segbuf_get_u8 (buf); if (!(byte & 0x80)) { rlep->color = 0; if (!(byte & 0x40)) rlep->len = byte & 0x3f; else rlep->len = ((byte & 0x3f) << 8) | segbuf_get_u8 (buf); } else { if (!(byte & 0x40)) rlep->len = byte & 0x3f; else rlep->len = ((byte & 0x3f) << 8) | segbuf_get_u8 (buf); rlep->color = segbuf_get_u8 (buf); } } /* move to next element */ if (rlep->len > 0) { x += rlep->len; rlep++; obj->num_rle ++; } else { /* end of line marker (00 00) */ if (x < obj->width) { rlep->len = obj->width - x; rlep->color = 0xff; rlep++; obj->num_rle ++; } x = 0; y++; } /* grow allocated RLE data size ? */ if (obj->data_size <= (obj->num_rle + 1) * sizeof(rle_elem_t)) { obj->data_size *= 2; obj->rle = realloc(obj->rle, obj->data_size); rlep = obj->rle + obj->num_rle; } } return buf->error; } static subtitle_object_t *segbuf_decode_object(segment_buffer_t *buf, subtitle_object_t *objects) { uint16_t object_id = segbuf_get_u16(buf); uint8_t version = segbuf_get_u8 (buf); uint8_t seq_desc = segbuf_get_u8 (buf); (void)version; XINE_HDMV_TRACE(" decode_object: object_id %d, version %d, seq 0x%x\n", object_id, version, seq_desc); if (seq_desc & 0x80) { subtitle_object_t *obj; /* new object (first-in-sequence flag set) */ obj = calloc(1, sizeof(subtitle_object_t)); if (!obj) return NULL; obj->id = object_id; obj->data_len = segbuf_get_u24(buf); obj->width = segbuf_get_u16(buf); obj->height = segbuf_get_u16(buf); if (buf->error) { XINE_HDMV_TRACE(" decode error at object header\n"); free_subtitle_object(obj); return NULL; } obj->data_len -= 4; /* width, height parsed */ XINE_HDMV_TRACE(" object length %d bytes, size %dx%d\n", obj->data_len, obj->width, obj->height); if (obj->data_len > segbuf_data_length(buf)) { XINE_HDMV_TRACE(" object length %d bytes, have only %zd bytes -> missing %d bytes\n", obj->data_len, segbuf_data_length(buf), obj->data_len - (int)segbuf_data_length(buf)); _x_freep(&obj->raw_data); /* store partial RLE data in HDMV format */ obj->raw_data_len = segbuf_data_length(buf); obj->raw_data_size = MAX(obj->data_len, obj->raw_data_len); obj->raw_data = malloc(obj->raw_data_size); memcpy(obj->raw_data, buf->segment_data, obj->raw_data_len); return obj; } segbuf_decode_rle (buf, obj); if (buf->error) { XINE_HDMV_TRACE(" decode error at RLE data\n"); free_subtitle_object(obj); return NULL; } return obj; } /* not first-of-sequence --> append data to already existing objct */ /* search for object */ while (objects && objects->id != object_id) objects = objects->next; if (!objects) { XINE_HDMV_TRACE(" object not found from list, discarding segment\n"); return NULL; } /* store partial RLE data in HDMV format */ if (objects->raw_data_size < objects->raw_data_len + segbuf_data_length(buf)) { XINE_HDMV_TRACE("object larger than object size !\n"); return NULL; } memcpy(objects->raw_data + objects->raw_data_len, buf->segment_data, segbuf_data_length(buf)); objects->raw_data_len += segbuf_data_length(buf); /* if complete, decode RLE data */ if (objects->raw_data_len >= objects->data_len) { /* create dummy buffer for segbuf_decode_rle */ segment_buffer_t tmpbuf = { .segment_data = objects->raw_data, .segment_end = objects->raw_data + objects->raw_data_len, }; /* decode RLE data */ segbuf_decode_rle (&tmpbuf, objects); if (tmpbuf.error) { XINE_HDMV_TRACE(" error decoding multi-segment object\n"); } /* free decode buffer */ _x_freep(&objects->raw_data); objects->raw_data_len = 0; objects->raw_data_size = 0; } return NULL; } static window_def_t *segbuf_decode_window_definition(segment_buffer_t *buf) { window_def_t *wnd; uint8_t a; wnd = calloc(1, sizeof(window_def_t)); if (!wnd) return NULL; a = segbuf_get_u8 (buf); wnd->id = segbuf_get_u8 (buf); wnd->xpos = segbuf_get_u16 (buf); wnd->ypos = segbuf_get_u16 (buf); wnd->width = segbuf_get_u16 (buf); wnd->height = segbuf_get_u16 (buf); (void)a; XINE_HDMV_TRACE(" window: [%02x %d] %d,%d %dx%d\n", a, wnd->id, wnd->xpos, wnd->ypos, wnd->width, wnd->height); if (buf->error) { free(wnd); return NULL; } return wnd; } static int segbuf_decode_video_descriptor(segment_buffer_t *buf) { uint16_t width = segbuf_get_u16(buf); uint16_t height = segbuf_get_u16(buf); uint8_t frame_rate = segbuf_get_u8 (buf); (void)width; (void)height; (void)frame_rate; XINE_HDMV_TRACE(" video_descriptor: %dx%d fps %d\n", width, height, frame_rate); return buf->error; } static int segbuf_decode_composition_descriptor(segment_buffer_t *buf, composition_descriptor_t *descr) { descr->number = segbuf_get_u16(buf); descr->state = segbuf_get_u8 (buf) & 0xc0; XINE_HDMV_TRACE(" composition_descriptor: number %d, state %d\n", descr->number, descr->state); return buf->error; } static composition_object_t *segbuf_decode_composition_object(segment_buffer_t *buf) { composition_object_t *cobj; uint8_t tmp; cobj = calloc(1, sizeof(composition_object_t)); if (!cobj) return NULL; cobj->object_id_ref = segbuf_get_u16 (buf); cobj->window_id_ref = segbuf_get_u8 (buf); tmp = segbuf_get_u8 (buf); cobj->cropped_flag = !!(tmp & 0x80); cobj->forced_flag = !!(tmp & 0x40); cobj->xpos = segbuf_get_u16 (buf); cobj->ypos = segbuf_get_u16 (buf); if (cobj->cropped_flag) { /* x,y where to take the image from */ cobj->crop_horiz_pos = segbuf_get_u8 (buf); cobj->crop_vert_pos = segbuf_get_u8 (buf); /* size of the cropped image */ cobj->crop_width = segbuf_get_u8 (buf); cobj->crop_height = segbuf_get_u8 (buf); } if (buf->error) { free(cobj); return NULL; } XINE_HDMV_TRACE(" composition_object: id: %d, win: %d, position %d,%d crop %d forced %d\n", cobj->object_id_ref, cobj->window_id_ref, cobj->xpos, cobj->ypos, cobj->cropped_flag, cobj->forced_flag); return cobj; } static presentation_segment_t *segbuf_decode_presentation_segment(segment_buffer_t *buf) { presentation_segment_t *seg; int index; seg = calloc(1, sizeof(presentation_segment_t)); if (!seg) return NULL; segbuf_decode_video_descriptor (buf); segbuf_decode_composition_descriptor (buf, &seg->comp_descr); seg->palette_update_flag = !!((segbuf_get_u8(buf)) & 0x80); seg->palette_id_ref = segbuf_get_u8 (buf); seg->object_number = segbuf_get_u8 (buf); XINE_HDMV_TRACE(" presentation_segment: object_number %d, palette %d\n", seg->object_number, seg->palette_id_ref); for (index = 0; index < seg->object_number; index++) { composition_object_t *cobj = segbuf_decode_composition_object (buf); if (cobj) { cobj->next = seg->comp_objs; seg->comp_objs = cobj; } } if (buf->error) { free_presentation_segment(seg); return NULL; } return seg; } static rle_elem_t *copy_crop_rle(subtitle_object_t *obj, composition_object_t *cobj) { /* TODO: cropping (w,h sized image from pos x,y) */ (void)cobj; rle_elem_t *rle = calloc (obj->num_rle, sizeof(rle_elem_t)); if (rle) { memcpy (rle, obj->rle, obj->num_rle * sizeof(rle_elem_t)); } return rle; } /* * xine plugin */ typedef struct spuhdmv_decoder_s { spu_decoder_t spu_decoder; xine_stream_t *stream; segment_buffer_t *buf; subtitle_clut_t *cluts; subtitle_object_t *objects; window_def_t *windows; presentation_segment_t *segments; int overlay_handles[MAX_OBJECTS]; uint32_t current_spu_channel; int64_t pts; } spuhdmv_decoder_t; static void free_objs(spuhdmv_decoder_t *this) { LIST_DESTROY (this->cluts, free); LIST_DESTROY (this->objects, free_subtitle_object); LIST_DESTROY (this->windows, free); LIST_DESTROY (this->segments, free_presentation_segment); } static int decode_palette(spuhdmv_decoder_t *this) { /* decode */ subtitle_clut_t *clut = segbuf_decode_palette(this->buf); if (!clut) return 1; LIST_REPLACE (this->cluts, clut, free); return 0; } static int decode_object(spuhdmv_decoder_t *this) { /* decode */ subtitle_object_t *obj = segbuf_decode_object(this->buf, this->objects); if (!obj) return 1; LIST_REPLACE (this->objects, obj, free_subtitle_object); return 0; } static int decode_window_definition(spuhdmv_decoder_t *this) { /* decode */ window_def_t *wnd = segbuf_decode_window_definition (this->buf); if (!wnd) return 1; LIST_REPLACE (this->windows, wnd, free); return 0; } static int decode_presentation_segment(spuhdmv_decoder_t *this) { /* decode */ presentation_segment_t *seg = segbuf_decode_presentation_segment(this->buf); if (!seg) return 1; seg->pts = this->pts; /* epoch start or acquistion point -> drop cached objects */ if (seg->comp_descr.state) { free_objs(this); } /* replace */ if (this->segments) LIST_DESTROY(this->segments, free_presentation_segment); this->segments = seg; return 0; } static int show_overlay(spuhdmv_decoder_t *this, composition_object_t *cobj, unsigned int palette_id_ref, int overlay_index, int64_t pts, int force_update) { video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out); metronom_t *metronom = this->stream->metronom; video_overlay_event_t event = {.vpts = 0}; vo_overlay_t overlay = {.x = 0}; /* find palette */ subtitle_clut_t *clut = this->cluts; while (clut && clut->id != palette_id_ref) clut = clut->next; if (!clut) { XINE_HDMV_TRACE(" show_overlay: clut %d not found !\n", palette_id_ref); return -1; } /* find RLE image */ subtitle_object_t *obj = this->objects; while (obj && obj->id != cobj->object_id_ref) obj = obj->next; if (!obj) { XINE_HDMV_TRACE(" show_overlay: object %d not found !\n", cobj->object_id_ref); return -1; } if (!obj->rle) { XINE_HDMV_TRACE(" show_overlay: object %d RLE data not decoded !\n", cobj->object_id_ref); return -1; } /* find window */ window_def_t *wnd = this->windows; while (wnd && wnd->id != cobj->window_id_ref) wnd = wnd->next; if (!wnd) { XINE_HDMV_TRACE(" show_overlay: window %d not found !\n", cobj->window_id_ref); return -1; } /* do not show again if all elements are unchanged */ if (!force_update && clut->shown && obj->shown && wnd->shown && cobj->shown) return 0; clut->shown = obj->shown = wnd->shown = cobj->shown = 1; /* copy palette to xine overlay */ overlay.rgb_clut = 0; memcpy(overlay.color, clut->color, sizeof(uint32_t) * 256); memcpy(overlay.trans, clut->trans, sizeof(uint8_t) * 256); /* copy and crop RLE image to xine overlay */ overlay.width = obj->width; overlay.height = obj->height; overlay.num_rle = obj->num_rle; overlay.data_size = obj->num_rle * sizeof(rle_elem_t); overlay.rle = copy_crop_rle (obj, cobj); if (!overlay.rle) return -1; /* */ overlay.x = /*wnd->xpos +*/ cobj->xpos; overlay.y = /*wnd->ypos +*/ cobj->ypos; overlay.unscaled = 0; overlay.hili_top = -1; overlay.hili_bottom = -1; overlay.hili_left = -1; overlay.hili_right = -1; XINE_HDMV_TRACE(" -> overlay: %d,%d %dx%d\n", overlay.x, overlay.y, overlay.width, overlay.height); /* set timings */ if (pts > 0) event.vpts = metronom->got_spu_packet (metronom, pts); else event.vpts = 0; /* generate SHOW event */ this->stream->video_out->enable_ovl(this->stream->video_out, 1); if (this->overlay_handles[overlay_index] < 0) this->overlay_handles[overlay_index] = ovl_manager->get_handle(ovl_manager, 0); event.event_type = OVERLAY_EVENT_SHOW; event.object.handle = this->overlay_handles[overlay_index]; event.object.overlay = &overlay; event.object.object_type = 0; /* subtitle */ ovl_manager->add_event (ovl_manager, (void *)&event); return 0; } static void hide_overlays(spuhdmv_decoder_t *this, int64_t pts) { video_overlay_event_t event = {.vpts = 0}; int i = 0; while (this->overlay_handles[i] >= 0) { XINE_HDMV_TRACE(" -> HIDE %d\n", i); video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager(this->stream->video_out); metronom_t *metronom = this->stream->metronom; event.object.handle = this->overlay_handles[i]; event.vpts = metronom->got_spu_packet (metronom, pts); event.event_type = OVERLAY_EVENT_HIDE; event.object.overlay = NULL; ovl_manager->add_event (ovl_manager, (void *)&event); //this->overlay_handles[i] = -1; i++; } } static void update_overlays(spuhdmv_decoder_t *this) { presentation_segment_t *pseg = this->segments; while (pseg) { if (!pseg->object_number) { /* HIDE */ if (!pseg->shown) hide_overlays (this, pseg->pts); } else { /* SHOW */ composition_object_t *cobj = pseg->comp_objs; int i; for (i = 0; i < pseg->object_number; i++) { if (!cobj) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error displaying overlay %d: missing composition object\n", i); } else { show_overlay(this, cobj, pseg->palette_id_ref, i, pseg->pts, !pseg->shown); cobj = cobj->next; } } } pseg->shown = 1; pseg = pseg->next; } } static void decode_segment(spuhdmv_decoder_t *this) { int err = 0; XINE_HDMV_TRACE("*** new segment, pts %010"PRId64": 0x%02x (%8d bytes)\n", this->pts, this->buf->segment_type, this->buf->segment_len); switch (segbuf_segment_type(this->buf)) { case SEGTYPE_PALETTE: XINE_HDMV_TRACE(" segment: PALETTE\n"); err = decode_palette(this); break; case SEGTYPE_OBJECT: XINE_HDMV_TRACE(" segment: OBJECT\n"); err = decode_object(this); break; case SEGTYPE_PRESENTATION_SEGMENT: XINE_HDMV_TRACE(" segment: PRESENTATION SEGMENT\n"); err = decode_presentation_segment(this); break; case SEGTYPE_WINDOW_DEFINITION: XINE_HDMV_TRACE(" segment: WINDOW DEFINITION\n"); err = decode_window_definition(this); break; case SEGTYPE_INTERACTIVE: XINE_HDMV_TRACE(" segment: INTERACTIVE\n"); break; case SEGTYPE_END_OF_DISPLAY: XINE_HDMV_TRACE(" segment: END OF DISPLAY\n"); #if 0 /* drop all cached objects */ free_objs(this); #endif break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Unknown segment type 0x%x, skipping\n", segbuf_segment_type(this->buf)); break; } if (err || this->buf->error) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": " "Error decoding segment 0x%x\n", segbuf_segment_type(this->buf)); } update_overlays (this); } static void close_osd(spuhdmv_decoder_t *this) { video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); int i = 0; while (this->overlay_handles[i] >= 0) { ovl_manager->free_handle(ovl_manager, this->overlay_handles[i]); this->overlay_handles[i] = -1; i++; } } static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf) { spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen; if ((buf->type & 0xffff0000) != BUF_SPU_HDMV) return; if ((this->stream->spu_channel & 0x1f) != (buf->type & 0x1f)) return; if (buf->size < 1) return; if (this->current_spu_channel != buf->type) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "spuhdmv: reset (spu channel changed)\n"); this_gen->reset(this_gen); this->current_spu_channel = buf->type; } if (buf->pts) this->pts = buf->pts; #ifdef DUMP_SPU_DATA int i; for(i = 0; i < buf->size; i++) printf(" %02x", buf->content[i]); printf("\n"); #endif segbuf_fill(this->buf, buf->content, buf->size); while (segbuf_segment_complete(this->buf)) { decode_segment(this); segbuf_skip_segment(this->buf); } } static void spudec_reset (spu_decoder_t * this_gen) { spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen; if (this->buf) segbuf_reset(this->buf); free_objs(this); close_osd(this); } static void spudec_discontinuity (spu_decoder_t *this_gen) { spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen; close_osd(this); } static void spudec_dispose (spu_decoder_t *this_gen) { spuhdmv_decoder_t *this = (spuhdmv_decoder_t *) this_gen; close_osd (this); segbuf_dispose (this->buf); free_objs(this); free (this); } static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { spuhdmv_decoder_t *this; (void)class_gen; this = (spuhdmv_decoder_t *) calloc(1, sizeof (spuhdmv_decoder_t)); if (!this) return NULL; this->buf = segbuf_init(); if (!this->buf) { free(this); return NULL; } this->spu_decoder.decode_data = spudec_decode_data; this->spu_decoder.reset = spudec_reset; this->spu_decoder.discontinuity = spudec_discontinuity; this->spu_decoder.dispose = spudec_dispose; this->spu_decoder.get_interact_info = NULL; this->spu_decoder.set_button = NULL; this->stream = stream; memset(this->overlay_handles, 0xff, sizeof(this->overlay_handles)); /* --> -1 */ return &this->spu_decoder; } static void *init_plugin (xine_t *xine, const void *data) { (void)xine; (void)data; static const spu_decoder_class_t decode_spu_hdmv_class = { .open_plugin = open_plugin, .identifier = "spuhdmv", .description = "HDMV/BluRay bitmap SPU decoder plugin", .dispose = NULL, }; return (void *)&decode_spu_hdmv_class; } /* plugin catalog information */ static const uint32_t supported_types[] = { BUF_SPU_HDMV, 0 }; static const decoder_info_t dec_info_data = { .supported_types = supported_types, .priority = 5, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_SPU_DECODER, 17, "spuhdmv", XINE_VERSION_CODE, &dec_info_data, &init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/spu_dec/xine_cc_decoder.c0000644000175000017500000002426714647725152016351 0ustar meme/* * Copyright (C) 2000-2018 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * closed caption spu decoder. receive data by events. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include "cc_decoder.h" /* #define LOG_DEBUG 1 */ static const char *const cc_schemes[NUM_CC_PALETTES + 1] = { "White/Gray/Translucent", "White/Black/Solid", NULL }; typedef struct spucc_decoder_s { spu_decoder_t spu_decoder; xine_stream_t *stream; /* closed captioning decoder state */ cc_decoder_t *ccdec; /* true if ccdec has been initialized */ int cc_open; /* closed captioning decoder configuration and intrinsics */ cc_state_t cc_state; /* this is to detect configuration changes */ int config_version; /* video dimensions captured in frame change events */ int video_width; int video_height; /* events will be sent here */ xine_event_queue_t *queue; } spucc_decoder_t; /*------------------- general utility functions ----------------------------*/ static void copy_str(char *d, const char *s, size_t maxbytes) { strncpy(d, s, maxbytes - 1); d[maxbytes - 1] = '\0'; } /*------------------- private methods --------------------------------------*/ static void spucc_update_intrinsics(spucc_decoder_t *this) { #ifdef LOG_DEBUG printf("spucc: update_intrinsics\n"); #endif if (this->cc_open) cc_renderer_update_cfg(this->cc_state.renderer, this->video_width, this->video_height); } static void spucc_do_close(spucc_decoder_t *this) { if (this->cc_open) { #ifdef LOG_DEBUG printf("spucc: close\n"); #endif cc_decoder_close(this->ccdec); cc_renderer_close(this->cc_state.renderer); this->cc_open = 0; } } static void spucc_do_init (spucc_decoder_t *this) { if (! this->cc_open) { #ifdef LOG_DEBUG printf("spucc: init\n"); #endif /* initialize caption renderer */ this->cc_state.renderer = cc_renderer_open(this->stream->osd_renderer, this->stream->metronom, &this->cc_state, this->video_width, this->video_height); spucc_update_intrinsics(this); /* initialize CC decoder */ this->ccdec = cc_decoder_open(&this->cc_state); this->cc_open = 1; } } /*----------------- configuration listeners --------------------------------*/ static void spucc_cfg_enable_change(void *this_gen, xine_cfg_entry_t *value) { spucc_class_t *this = (spucc_class_t *) this_gen; cc_config_t *cc_cfg = &this->cc_cfg; cc_cfg->cc_enabled = value->num_value; #ifdef LOG_DEBUG printf("spucc: closed captions are now %s.\n", cc_cfg->cc_enabled? "enabled" : "disabled"); #endif cc_cfg->config_version++; } static void spucc_cfg_scheme_change(void *this_gen, xine_cfg_entry_t *value) { spucc_class_t *this = (spucc_class_t *) this_gen; cc_config_t *cc_cfg = &this->cc_cfg; cc_cfg->cc_scheme = value->num_value; #ifdef LOG_DEBUG printf("spucc: closed captioning scheme is now %s.\n", cc_schemes[cc_cfg->cc_scheme]); #endif cc_cfg->config_version++; } static void spucc_font_change(void *this_gen, xine_cfg_entry_t *value) { spucc_class_t *this = (spucc_class_t *) this_gen; cc_config_t *cc_cfg = &this->cc_cfg; char *font; if (strcmp(value->key, "subtitles.closedcaption.font") == 0) font = cc_cfg->font; else font = cc_cfg->italic_font; copy_str(font, value->str_value, CC_FONT_MAX); #ifdef LOG_DEBUG printf("spucc: changing %s to font %s\n", value->key, font); #endif cc_cfg->config_version++; } static void spucc_num_change(void *this_gen, xine_cfg_entry_t *value) { spucc_class_t *this = (spucc_class_t *) this_gen; cc_config_t *cc_cfg = &this->cc_cfg; int *num; if (strcmp(value->key, "subtitles.closedcaption.font_size") == 0) num = &cc_cfg->font_size; else num = &cc_cfg->center; *num = value->num_value; #ifdef LOG_DEBUG printf("spucc: changing %s to %d\n", value->key, *num); #endif cc_cfg->config_version++; } static void spucc_register_cfg_vars(spucc_class_t *this, config_values_t *xine_cfg) { cc_config_t *cc_vars = &this->cc_cfg; cc_vars->cc_enabled = xine_cfg->register_bool(xine_cfg, "subtitles.closedcaption.enabled", 0, _("display closed captions in MPEG-2 streams"), _("Closed Captions are subtitles mostly meant " "to help the hearing impaired."), 0, spucc_cfg_enable_change, this); cc_vars->cc_scheme = xine_cfg->register_enum(xine_cfg, "subtitles.closedcaption.scheme", 0, (char **)cc_schemes, _("closed-captioning foreground/background scheme"), _("Choose your favourite rendering of the closed " "captions."), 10, spucc_cfg_scheme_change, this); copy_str(cc_vars->font, xine_cfg->register_string(xine_cfg, "subtitles.closedcaption.font", "cc", _("standard closed captioning font"), _("Choose the font for standard closed captions text."), 20, spucc_font_change, this), CC_FONT_MAX); copy_str(cc_vars->italic_font, xine_cfg->register_string(xine_cfg, "subtitles.closedcaption.italic_font", "cci", _("italic closed captioning font"), _("Choose the font for italic closed captions text."), 20, spucc_font_change, this), CC_FONT_MAX); cc_vars->font_size = xine_cfg->register_num(xine_cfg, "subtitles.closedcaption.font_size", 24, _("closed captioning font size"), _("Choose the font size for closed captions text."), 10, spucc_num_change, this); cc_vars->center = xine_cfg->register_bool(xine_cfg, "subtitles.closedcaption.center", 1, _("center-adjust closed captions"), _("When enabled, closed captions will be positioned " "by the center of the individual lines."), 20, spucc_num_change, this); } /* called when the video frame size changes */ static void spucc_notify_frame_change(spucc_decoder_t *this, int width, int height) { #ifdef LOG_DEBUG printf("spucc: new frame size: %dx%d\n", width, height); #endif this->video_width = width; this->video_height = height; spucc_update_intrinsics(this); } /*------------------- implementation of spudec interface -------------------*/ static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { spucc_decoder_t *this = (spucc_decoder_t *) this_gen; xine_event_t *event; while ((event = xine_event_get(this->queue))) { switch (event->type) { case XINE_EVENT_FRAME_FORMAT_CHANGE: { xine_format_change_data_t *frame_change = (xine_format_change_data_t *)event->data; spucc_notify_frame_change(this, frame_change->width, frame_change->height); } break; } xine_event_free(event); } if (buf->decoder_flags & BUF_FLAG_PREVIEW) { } else { if (this->cc_state.cc_cfg->config_version > this->config_version) { spucc_update_intrinsics(this); if (!this->cc_state.cc_cfg->cc_enabled) spucc_do_close(this); this->config_version = this->cc_state.cc_cfg->config_version; } if (this->cc_state.cc_cfg->cc_enabled) { if( !this->cc_open ) spucc_do_init (this); if(this->cc_state.can_cc) { decode_cc(this->ccdec, buf->content, buf->size, buf->pts); } } } } static void spudec_reset (spu_decoder_t *this_gen) { (void)this_gen; } static void spudec_discontinuity (spu_decoder_t *this_gen) { (void)this_gen; } static void spudec_dispose (spu_decoder_t *this_gen) { spucc_decoder_t *this = (spucc_decoder_t *) this_gen; spucc_do_close(this); xine_event_dispose_queue(this->queue); free (this); } static spu_decoder_t *spudec_open_plugin (spu_decoder_class_t *class, xine_stream_t *stream) { spucc_decoder_t *this ; this = (spucc_decoder_t *) calloc(1, sizeof(spucc_decoder_t)); if (!this) return NULL; this->spu_decoder.decode_data = spudec_decode_data; this->spu_decoder.reset = spudec_reset; this->spu_decoder.discontinuity = spudec_discontinuity; this->spu_decoder.dispose = spudec_dispose; this->spu_decoder.get_interact_info = NULL; this->spu_decoder.set_button = NULL; this->stream = stream; this->queue = xine_event_new_queue(stream); this->cc_state.cc_cfg = &((spucc_class_t *)class)->cc_cfg; this->config_version = 0; this->cc_open = 0; return &this->spu_decoder; } static void *init_spu_decoder_plugin (xine_t *xine, const void *data) { spucc_class_t *this ; (void)data; this = (spucc_class_t *) calloc(1, sizeof(spucc_class_t)); if (!this) return NULL; this->spu_class.open_plugin = spudec_open_plugin; this->spu_class.identifier = "spucc"; this->spu_class.description = N_("closed caption decoder plugin"); this->spu_class.dispose = default_spu_decoder_class_dispose; spucc_register_cfg_vars(this, xine->config); this->cc_cfg.config_version = 0; return &this->spu_class; } /* plugin catalog information */ static const uint32_t supported_types[] = { BUF_SPU_CC, 0 }; static const decoder_info_t spudec_info = { .supported_types = supported_types, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_SPU_DECODER, 17, "spucc", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/spu_dec/Makefile.am0000644000175000017500000000302214647725152015126 0ustar memeinclude $(top_builddir)/misc/Makefile.plugins include $(top_srcdir)/misc/Makefile.common AM_CFLAGS = $(DEFAULT_OCFLAGS) $(VISIBILITY_FLAG) AM_LDFLAGS = $(xineplug_ldflags) xineplug_LTLIBRARIES = \ xineplug_decode_spucc.la \ xineplug_decode_spucmml.la \ xineplug_decode_spu.la \ xineplug_decode_spudvb.la \ xineplug_decode_spuhdmv.la \ xineplug_sputext.la xineplug_decode_spucc_la_SOURCES = cc_decoder.c cc_decoder.h xine_cc_decoder.c xineplug_decode_spucc_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xineplug_decode_spucc_la_CFLAGS = $(AM_CFLAGS) xineplug_decode_spucmml_la_SOURCES = cmml_decoder.c xineplug_decode_spucmml_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) if WITH_EXTERNAL_DVDNAV external_dvdnav_libs = $(DVDNAV_LIBS) $(DVDREAD_LIBS) internal_dvdnav_sources = else external_dvdnav_libs = internal_dvdnav_sources = nav_read.c endif xineplug_decode_spu_la_SOURCES = $(internal_dvdnav_sources) spudec.c spudec.h spu_decoder.c xineplug_decode_spu_la_LIBADD = $(XINE_LIB) $(external_dvdnav_libs) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_decode_spu_la_CFLAGS = $(AM_CFLAGS) $(DVDNAV_CFLAGS) $(DVDREAD_CFLAGS) -I$(top_srcdir)/src/input/libdvdnav xineplug_decode_spudvb_la_SOURCES = spudvb_decoder.c xineplug_decode_spudvb_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_decode_spuhdmv_la_SOURCES = spuhdmv_decoder.c xineplug_decode_spuhdmv_la_LIBADD = $(XINE_LIB) $(PTHREAD_LIBS) $(LTLIBINTL) xineplug_sputext_la_SOURCES = sputext_demuxer.c sputext_demuxer.h sputext_decoder.c xineplug_sputext_la_LIBADD = $(XINE_LIB) $(LTLIBINTL) xine-lib-1.2/src/spu_dec/cc_decoder.h0000644000175000017500000000601014647725152015315 0ustar meme/* * Copyright (C) 2000-2009 the xine project * * Copyright (C) Christian Vogler * cvogler@gradient.cis.upenn.edu - December 2001 * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stuff needed to provide closed captioning decoding and display * * Some small bits and pieces of the EIA-608 captioning decoder were * adapted from CCDecoder 0.9.1 by Mike Baker. The latest version is * available at http://sourceforge.net/projects/ccdecoder/. */ typedef struct cc_decoder_s cc_decoder_t; typedef struct cc_renderer_s cc_renderer_t; #define NUM_CC_PALETTES 2 #define CC_FONT_MAX 256 typedef struct cc_config_s { int cc_enabled; /* true if closed captions are enabled */ char font[CC_FONT_MAX]; /* standard captioning font & size */ int font_size; char italic_font[CC_FONT_MAX]; /* italic captioning font & size */ int center; /* true if captions should be centered */ /* according to text width */ int cc_scheme; /* which captioning scheme to use */ int config_version; /* the decoder should be updated when this is increased */ } cc_config_t; typedef struct spucc_class_s { spu_decoder_class_t spu_class; cc_config_t cc_cfg; } spucc_class_t; typedef struct cc_state_s { cc_config_t *cc_cfg; /* the following variables are not controlled by configuration files; they */ /* are intrinsic to the properties of the configuration options and the */ /* currently played video */ int can_cc; /* true if captions can be displayed */ /* (e.g., font fits on screen) */ cc_renderer_t *renderer; /* closed captioning renderer */ } cc_state_t; cc_decoder_t *cc_decoder_open(cc_state_t *cc_state); void cc_decoder_close(cc_decoder_t *this_obj); void decode_cc(cc_decoder_t *this, uint8_t *buffer, uint32_t buf_len, int64_t pts); /* Instantiates a new closed captioning renderer. */ cc_renderer_t *cc_renderer_open(osd_renderer_t *osd_renderer, metronom_t *metronom, cc_state_t *cc_state, int video_width, int video_height); /* Destroys a closed captioning renderer. */ void cc_renderer_close(cc_renderer_t *this_obj); /* Updates the renderer configuration variables */ void cc_renderer_update_cfg(cc_renderer_t *this_obj, int video_width, int video_height); xine-lib-1.2/src/spu_dec/spudvb_decoder.c0000644000175000017500000016235214647725152016242 0ustar meme/* * Copyright (C) 2010-2022 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * DVB Subtitle decoder (ETS 300 743) * (c) 2004 Mike Lampard * based on the application dvbsub by Dave Chapman * * TODO: * - Implement support for teletext based subtitles */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef GEN_DEFAULT_CLUT #include #include #include "../../include/xine/xineutils.h" int main (int argn, char **argv) { int y_r_table[256]; int y_g_table[256]; int y_b_table[256]; int uv_br_table[256]; int u_r_table[256]; int u_g_table[256]; int v_b_table[256]; int v_g_table[256]; uint8_t default_clut[256][4]; int i; static const uint8_t f[5 * 4 * 2] = { 0, 85, 0, 170, 0, 0, 0, 0, 0, 85, 0, 170, 0, 0, 128, 128, 0, 43, 0, 85, 127, 127, 0, 0, 0, 43, 0, 85, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0 }; /* ITU-R 601 */ #define KB 0.114 #define KR 0.299 #define YR (219.0/255.0)*KR*SCALEFACTOR #define YG (219.0/255.0)*(1.0-KB-KR)*SCALEFACTOR #define YB (219.0/255.0)*KB*SCALEFACTOR #define UR (112.0/255.0)*(KR/(KB-1.0))*SCALEFACTOR #define UG (112.0/255.0)*((1.0-KB-KR)/(KB-1.0))*SCALEFACTOR #define UB (112.0/255.0)*SCALEFACTOR #define VR (112.0/255.0)*SCALEFACTOR #define VG (112.0/255.0)*((1.0-KB-KR)/(KR-1.0))*SCALEFACTOR #define VB (112.0/255.0)*(KB/(KR-1.0))*SCALEFACTOR /* initialize the RGB -> YUV tables */ for (i = 0; i < 256; i++) { /* fast and correctly rounded */ y_r_table[i] = YR * i; y_g_table[i] = YG * i + 16 * SCALEFACTOR + SCALEFACTOR / 2; y_b_table[i] = YB * i; uv_br_table[i] = UB * i + CENTERSAMPLE * SCALEFACTOR + SCALEFACTOR / 2; u_r_table[i] = UR * i; u_g_table[i] = UG * i; v_g_table[i] = VG * i; v_b_table[i] = VB * i; } #define YUVA(i,r,g,b,trans) do { \ default_clut[i][0] = COMPUTE_Y (r, g, b); \ default_clut[i][1] = COMPUTE_U (r, g, b); \ default_clut[i][2] = COMPUTE_V (r, g, b); \ default_clut[i][3] = trans; \ } while (0) YUVA (0, 0, 0, 0, 255); for (i = 1; i < 8; i++) YUVA (i, f[32 + ((i >> 0) & 1)], f[32 + ((i >> 1) & 1)], f[32 + ((i >> 2) & 1)], 192); for (; i < 256; i++) { uint8_t j, r, g, b, trans; /* bits 7, 3 --> 4, 3 */ const uint8_t *t = f + ((((i & 0x88) * 0x09) >> 3) & 0x18); r = t[0 + ((i >> 0) & 1)] + t[2 + ((i >> 4) & 1)] + t[4]; g = t[0 + ((i >> 1) & 1)] + t[2 + ((i >> 5) & 1)] + t[4]; b = t[0 + ((i >> 2) & 1)] + t[2 + ((i >> 6) & 1)] + t[4]; trans = t[6]; YUVA (i, r, g, b, trans); } printf (" static const clut_union_t default_clut[256] = {\n"); for (i = 0; i < 256; i++) printf (" [%3d] = {.c = {%3u, %3u, %3u, %3u}},\n", i, (unsigned int)default_clut[i][0], (unsigned int)default_clut[i][1], (unsigned int)default_clut[i][2], (unsigned int)default_clut[i][3]); printf (" };\n"); return 0; } #else /* !GEN_DEFAULT_CLUT */ #include #include #include /*#define LOG*/ #define LOG_MODULE "spudvb" #include #include #include #include "xine-engine/bswap.h" #define MAX_REGIONS 16 #define SPU_MAX_WIDTH 1920 #define SPU_MAX_HEIGHT 1080 #ifndef INT64_MAX # define INT64_MAX ((int64_t)((~(uint64_t)0) >> 1)) #endif /* sparse_array - handle large arrays efficiently when only a few entries are used */ typedef struct { const uint32_t key; uint32_t value; } sparse_array_entry_t; typedef struct { uint32_t key, value; } _sparse_array_entry_t; typedef struct { uint32_t sorted_entries, used_entries, max_entries; _sparse_array_entry_t *entries; } sparse_array_t; static void sparse_array_new (sparse_array_t *sa) { sa->sorted_entries = sa->used_entries = sa->max_entries = 0; sa->entries = NULL; } static void sparse_array_clear (sparse_array_t *sa) { sa->sorted_entries = sa->used_entries = sa->max_entries = 0; } static void sparse_array_delete (sparse_array_t *sa) { sa->sorted_entries = sa->used_entries = sa->max_entries = 0; _x_freep (&sa->entries); } static uint32_t _sparse_array_find (sparse_array_t *sa, uint32_t key) { uint32_t b = 0, e = sa->sorted_entries; while (b < e) { uint32_t m = (b + e) >> 1; if (key <= sa->entries[m].key) e = m; else b = m + 1; } return b; } static void _sparse_array_sort (sparse_array_t *sa) { uint32_t left = sa->max_entries - sa->used_entries; uint32_t i = left + sa->sorted_entries; /* move unsorted part to end of buf */ memmove (sa->entries + i, sa->entries + sa->sorted_entries, (sa->used_entries - sa->sorted_entries) * sizeof (_sparse_array_entry_t)); /* iterate it */ while (i < sa->max_entries) { uint32_t j, pos, startkey, stopkey, lastkey; startkey = sa->entries[i].key; pos = _sparse_array_find (sa, startkey); if ((pos < sa->sorted_entries) && (sa->entries[pos].key == startkey)) { /* eliminate duplicate */ sa->entries[pos].value = sa->entries[i].value; i++; continue; } /* find sorted range */ stopkey = (pos < sa->sorted_entries) ? sa->entries[pos].key : 0xffffffff; lastkey = startkey; for (j = i + 1; j < sa->max_entries; j++) { uint32_t thiskey = sa->entries[j].key; if ((thiskey <= lastkey) || (thiskey >= stopkey)) break; lastkey = thiskey; } j -= i; if (j > left) j = left; /* insert it */ if (pos < sa->sorted_entries) memmove (sa->entries + pos + j, sa->entries + pos, (sa->sorted_entries - pos) * sizeof (_sparse_array_entry_t)); memcpy (sa->entries + pos, sa->entries + i, j * sizeof (_sparse_array_entry_t)); sa->sorted_entries += j; i += j; } sa->used_entries = sa->sorted_entries; lprintf ("sparse_array_sort: %u entries\n", (unsigned int)sa->used_entries); } static int sparse_array_set (sparse_array_t *sa, uint32_t key, uint32_t value) { /* give some room for later sorting too */ if (!sa->entries || (sa->used_entries + 8 >= sa->max_entries)) { uint32_t n = sa->max_entries + 128; _sparse_array_entry_t *se = realloc (sa->entries, n * sizeof (_sparse_array_entry_t)); if (!se) return 0; sa->max_entries = n; sa->entries = se; } sa->entries[sa->used_entries].key = key; sa->entries[sa->used_entries++].value = value; return 1; } static sparse_array_entry_t *sparse_array_get (sparse_array_t *sa, uint32_t key) { uint32_t pos; if (sa->sorted_entries != sa->used_entries) _sparse_array_sort (sa); pos = _sparse_array_find (sa, key); return (sparse_array_entry_t *)sa->entries + pos; } static void sparse_array_unset (sparse_array_t *sa, uint32_t key, uint32_t mask) { _sparse_array_entry_t *here = sa->entries, *p = NULL, *q = sa->entries; uint32_t i, n = 0; if (sa->sorted_entries != sa->used_entries) _sparse_array_sort (sa); key &= mask; for (i = sa->used_entries; i > 0; i--) { if ((here->key & mask) == key) { if (p) { n = here - p; if (n && (p != q)) memmove (q, p, n * sizeof (_sparse_array_entry_t)); p = NULL; q += n; } } else { if (!p) p = here; } here++; } if (p) { n = here - p; if (n && (p != q)) memmove (q, p, n * sizeof (_sparse_array_entry_t)); q += n; } sa->sorted_entries = sa->used_entries = q - sa->entries; } /* ! sparse_array */ typedef struct { uint16_t id; uint8_t time_out; uint8_t version:6, state:2; int max_hold_vpts; struct { uint16_t x, y; } regions[MAX_REGIONS]; } page_t; typedef struct { uint8_t version; uint8_t depth; uint8_t CLUT_id; #define _REGION_FLAG_CHANGED 1 #define _REGION_FLAG_FILL 2 #define _REGION_FLAG_SHOW 4 #define _REGION_FLAG_VISIBLE 8 uint8_t flags; uint16_t width, height; int64_t show_vpts; int64_t hide_vpts; int64_t stream_hide_vpts; unsigned char *img; osd_object_t *osd; } region_t; typedef union { clut_t c; uint32_t u32; } clut_union_t; typedef struct { uint8_t version_number; uint8_t windowed; uint16_t width; uint16_t height; /* window, TODO */ /* uint16_t x0, x1, y0, y1; */ } dds_t; typedef struct { /* dvbsub stuff */ int x; int y; unsigned int curr_obj; unsigned int curr_reg[64]; uint8_t *buf; int i; int i_bits; int compat_depth; page_t page; dds_t dds; uint32_t region_num; uint8_t region_ids[256]; int64_t region_vpts[MAX_REGIONS]; region_t regions[MAX_REGIONS]; clut_union_t colours[MAX_REGIONS * 256]; uint8_t trans[MAX_REGIONS * 256]; uint8_t clut_cm[MAX_REGIONS]; int clut_gen[MAX_REGIONS + 1]; uint32_t clut_num; uint8_t clut_ids[256]; struct _lut_group_s { uint8_t lut24[4], lut28[4], lut48[16]; } lut[MAX_REGIONS]; sparse_array_t object_pos; } dvbsub_func_t; typedef struct dvb_spu_decoder_s { spu_decoder_t spu_decoder; xine_stream_t *stream; spu_dvb_descriptor_t spu_descriptor; char *pes_pkt_wrptr; unsigned int pes_pkt_size; int timeout; int longest_hold_vpts; int64_t vpts; dvbsub_func_t dvbsub; int show; char pes_pkt[65 * 1024]; } dvb_spu_decoder_t; static void _region_init (dvbsub_func_t *dvbsub) { dvbsub->region_num = 0; memset (dvbsub->region_ids, 255, sizeof (dvbsub->region_ids)); } static void _region_deinit (dvbsub_func_t *dvbsub) { (void)dvbsub; } static uint32_t _region_find (dvbsub_func_t *dvbsub, uint32_t id, int new) { uint32_t u; id &= 255; u = dvbsub->region_ids[id]; if (u != 255) return u; if (new && (dvbsub->region_num < MAX_REGIONS)) { dvbsub->region_ids[id] = u = dvbsub->region_num++; return u; } return ~0u; } static void _clut_init (dvbsub_func_t *dvbsub) { dvbsub->clut_num = 0; memset (dvbsub->clut_ids, 255, sizeof (dvbsub->clut_ids)); } static void _clut_deinit (dvbsub_func_t *dvbsub) { (void)dvbsub; } static clut_union_t *_clut_find (dvbsub_func_t *dvbsub, uint32_t id, int new) { uint32_t u; id &= 255; u = dvbsub->clut_ids[id]; if (u != 255) return dvbsub->colours + u * 256; if (new && (dvbsub->clut_num < MAX_REGIONS)) { dvbsub->clut_ids[id] = u = dvbsub->clut_num++; return dvbsub->colours + u * 256; } /* nasty fallback - wrong colors are better than nothing. */ return dvbsub->colours + (id & (MAX_REGIONS - 1)) * 256; } static void _clut_reset (dvbsub_func_t *dvbsub) { /** look at the output of * $ gcc -DGEN_DEFAULT_CLUT -o ~/bin/default_clut spudvb_decoder.c * $ default_clut * $ rm ~/bin/default_clut */ static const clut_union_t default_clut[256] = { [ 0] = {.c = { 16, 128, 128, 255}}, [ 1] = {.c = { 81, 90, 240, 192}}, [ 2] = {.c = {145, 54, 34, 192}}, [ 3] = {.c = {210, 16, 146, 192}}, [ 4] = {.c = { 41, 240, 110, 192}}, [ 5] = {.c = {106, 202, 222, 192}}, [ 6] = {.c = {170, 166, 16, 192}}, [ 7] = {.c = {235, 128, 128, 192}}, [ 8] = {.c = { 16, 128, 128, 128}}, [ 9] = {.c = { 38, 115, 165, 128}}, [ 10] = {.c = { 59, 103, 97, 128}}, [ 11] = {.c = { 81, 91, 134, 128}}, [ 12] = {.c = { 24, 165, 122, 128}}, [ 13] = {.c = { 46, 153, 159, 128}}, [ 14] = {.c = { 67, 141, 91, 128}}, [ 15] = {.c = { 89, 128, 128, 128}}, [ 16] = {.c = { 60, 103, 203, 0}}, [ 17] = {.c = { 81, 90, 240, 0}}, [ 18] = {.c = {103, 78, 171, 0}}, [ 19] = {.c = {124, 65, 209, 0}}, [ 20] = {.c = { 68, 140, 197, 0}}, [ 21] = {.c = { 90, 128, 234, 0}}, [ 22] = {.c = {111, 115, 165, 0}}, [ 23] = {.c = {133, 103, 203, 0}}, [ 24] = {.c = { 60, 103, 203, 128}}, [ 25] = {.c = { 81, 90, 240, 128}}, [ 26] = {.c = {103, 78, 171, 128}}, [ 27] = {.c = {124, 65, 209, 128}}, [ 28] = {.c = { 68, 140, 197, 128}}, [ 29] = {.c = { 90, 128, 234, 128}}, [ 30] = {.c = {111, 115, 165, 128}}, [ 31] = {.c = {133, 103, 203, 128}}, [ 32] = {.c = {102, 79, 65, 0}}, [ 33] = {.c = {124, 66, 103, 0}}, [ 34] = {.c = {145, 54, 34, 0}}, [ 35] = {.c = {166, 41, 72, 0}}, [ 36] = {.c = {110, 116, 59, 0}}, [ 37] = {.c = {132, 103, 97, 0}}, [ 38] = {.c = {153, 91, 28, 0}}, [ 39] = {.c = {175, 79, 65, 0}}, [ 40] = {.c = {102, 79, 65, 128}}, [ 41] = {.c = {124, 66, 103, 128}}, [ 42] = {.c = {145, 54, 34, 128}}, [ 43] = {.c = {166, 41, 72, 128}}, [ 44] = {.c = {110, 116, 59, 128}}, [ 45] = {.c = {132, 103, 97, 128}}, [ 46] = {.c = {153, 91, 28, 128}}, [ 47] = {.c = {175, 79, 65, 128}}, [ 48] = {.c = {145, 53, 140, 0}}, [ 49] = {.c = {167, 41, 177, 0}}, [ 50] = {.c = {188, 29, 109, 0}}, [ 51] = {.c = {210, 16, 146, 0}}, [ 52] = {.c = {154, 91, 134, 0}}, [ 53] = {.c = {176, 78, 171, 0}}, [ 54] = {.c = {197, 66, 103, 0}}, [ 55] = {.c = {218, 53, 140, 0}}, [ 56] = {.c = {145, 53, 140, 128}}, [ 57] = {.c = {167, 41, 177, 128}}, [ 58] = {.c = {188, 29, 109, 128}}, [ 59] = {.c = {210, 16, 146, 128}}, [ 60] = {.c = {154, 91, 134, 128}}, [ 61] = {.c = {176, 78, 171, 128}}, [ 62] = {.c = {197, 66, 103, 128}}, [ 63] = {.c = {218, 53, 140, 128}}, [ 64] = {.c = { 33, 203, 116, 0}}, [ 65] = {.c = { 54, 190, 153, 0}}, [ 66] = {.c = { 75, 178, 85, 0}}, [ 67] = {.c = { 97, 165, 122, 0}}, [ 68] = {.c = { 41, 240, 110, 0}}, [ 69] = {.c = { 63, 227, 147, 0}}, [ 70] = {.c = { 84, 215, 79, 0}}, [ 71] = {.c = {106, 203, 116, 0}}, [ 72] = {.c = { 33, 203, 116, 128}}, [ 73] = {.c = { 54, 190, 153, 128}}, [ 74] = {.c = { 75, 178, 85, 128}}, [ 75] = {.c = { 97, 165, 122, 128}}, [ 76] = {.c = { 41, 240, 110, 128}}, [ 77] = {.c = { 63, 227, 147, 128}}, [ 78] = {.c = { 84, 215, 79, 128}}, [ 79] = {.c = {106, 203, 116, 128}}, [ 80] = {.c = { 76, 177, 191, 0}}, [ 81] = {.c = { 98, 165, 228, 0}}, [ 82] = {.c = {119, 153, 159, 0}}, [ 83] = {.c = {141, 140, 197, 0}}, [ 84] = {.c = { 85, 215, 184, 0}}, [ 85] = {.c = {106, 202, 222, 0}}, [ 86] = {.c = {127, 190, 153, 0}}, [ 87] = {.c = {149, 177, 191, 0}}, [ 88] = {.c = { 76, 177, 191, 128}}, [ 89] = {.c = { 98, 165, 228, 128}}, [ 90] = {.c = {119, 153, 159, 128}}, [ 91] = {.c = {141, 140, 197, 128}}, [ 92] = {.c = { 85, 215, 184, 128}}, [ 93] = {.c = {106, 202, 222, 128}}, [ 94] = {.c = {127, 190, 153, 128}}, [ 95] = {.c = {149, 177, 191, 128}}, [ 96] = {.c = {118, 153, 53, 0}}, [ 97] = {.c = {140, 141, 91, 0}}, [ 98] = {.c = {161, 128, 22, 0}}, [ 99] = {.c = {183, 116, 59, 0}}, [100] = {.c = {127, 191, 47, 0}}, [101] = {.c = {148, 178, 85, 0}}, [102] = {.c = {170, 166, 16, 0}}, [103] = {.c = {191, 153, 53, 0}}, [104] = {.c = {118, 153, 53, 128}}, [105] = {.c = {140, 141, 91, 128}}, [106] = {.c = {161, 128, 22, 128}}, [107] = {.c = {183, 116, 59, 128}}, [108] = {.c = {127, 191, 47, 128}}, [109] = {.c = {148, 178, 85, 128}}, [110] = {.c = {170, 166, 16, 128}}, [111] = {.c = {191, 153, 53, 128}}, [112] = {.c = {162, 128, 128, 0}}, [113] = {.c = {184, 115, 165, 0}}, [114] = {.c = {205, 103, 97, 0}}, [115] = {.c = {227, 91, 134, 0}}, [116] = {.c = {170, 165, 122, 0}}, [117] = {.c = {192, 153, 159, 0}}, [118] = {.c = {213, 141, 91, 0}}, [119] = {.c = {235, 128, 128, 0}}, [120] = {.c = {162, 128, 128, 128}}, [121] = {.c = {184, 115, 165, 128}}, [122] = {.c = {205, 103, 97, 128}}, [123] = {.c = {227, 91, 134, 128}}, [124] = {.c = {170, 165, 122, 128}}, [125] = {.c = {192, 153, 159, 128}}, [126] = {.c = {213, 141, 91, 128}}, [127] = {.c = {235, 128, 128, 128}}, [128] = {.c = {125, 128, 128, 0}}, [129] = {.c = {136, 122, 147, 0}}, [130] = {.c = {147, 115, 112, 0}}, [131] = {.c = {158, 109, 131, 0}}, [132] = {.c = {129, 147, 125, 0}}, [133] = {.c = {140, 141, 144, 0}}, [134] = {.c = {151, 134, 109, 0}}, [135] = {.c = {162, 128, 128, 0}}, [136] = {.c = { 16, 128, 128, 0}}, [137] = {.c = { 27, 122, 147, 0}}, [138] = {.c = { 38, 115, 112, 0}}, [139] = {.c = { 49, 109, 131, 0}}, [140] = {.c = { 20, 147, 125, 0}}, [141] = {.c = { 31, 141, 144, 0}}, [142] = {.c = { 42, 134, 109, 0}}, [143] = {.c = { 53, 128, 128, 0}}, [144] = {.c = {147, 115, 165, 0}}, [145] = {.c = {158, 109, 184, 0}}, [146] = {.c = {169, 103, 150, 0}}, [147] = {.c = {180, 97, 168, 0}}, [148] = {.c = {151, 134, 162, 0}}, [149] = {.c = {162, 128, 181, 0}}, [150] = {.c = {173, 122, 146, 0}}, [151] = {.c = {184, 115, 165, 0}}, [152] = {.c = { 38, 115, 165, 0}}, [153] = {.c = { 49, 109, 184, 0}}, [154] = {.c = { 60, 103, 150, 0}}, [155] = {.c = { 71, 97, 168, 0}}, [156] = {.c = { 42, 134, 162, 0}}, [157] = {.c = { 53, 128, 181, 0}}, [158] = {.c = { 64, 122, 146, 0}}, [159] = {.c = { 75, 115, 165, 0}}, [160] = {.c = {168, 103, 97, 0}}, [161] = {.c = {179, 97, 116, 0}}, [162] = {.c = {190, 91, 81, 0}}, [163] = {.c = {201, 84, 100, 0}}, [164] = {.c = {172, 122, 94, 0}}, [165] = {.c = {183, 116, 113, 0}}, [166] = {.c = {194, 110, 78, 0}}, [167] = {.c = {205, 103, 97, 0}}, [168] = {.c = { 59, 103, 97, 0}}, [169] = {.c = { 70, 97, 116, 0}}, [170] = {.c = { 81, 91, 81, 0}}, [171] = {.c = { 92, 84, 100, 0}}, [172] = {.c = { 63, 122, 94, 0}}, [173] = {.c = { 74, 116, 113, 0}}, [174] = {.c = { 85, 110, 78, 0}}, [175] = {.c = { 96, 103, 97, 0}}, [176] = {.c = {190, 91, 134, 0}}, [177] = {.c = {201, 84, 153, 0}}, [178] = {.c = {211, 78, 118, 0}}, [179] = {.c = {222, 72, 137, 0}}, [180] = {.c = {194, 110, 131, 0}}, [181] = {.c = {205, 103, 150, 0}}, [182] = {.c = {216, 97, 115, 0}}, [183] = {.c = {227, 91, 134, 0}}, [184] = {.c = { 81, 91, 134, 0}}, [185] = {.c = { 92, 84, 153, 0}}, [186] = {.c = {102, 78, 118, 0}}, [187] = {.c = {113, 72, 137, 0}}, [188] = {.c = { 85, 110, 131, 0}}, [189] = {.c = { 96, 103, 150, 0}}, [190] = {.c = {107, 97, 115, 0}}, [191] = {.c = {118, 91, 134, 0}}, [192] = {.c = {133, 165, 122, 0}}, [193] = {.c = {144, 159, 141, 0}}, [194] = {.c = {155, 153, 106, 0}}, [195] = {.c = {166, 146, 125, 0}}, [196] = {.c = {138, 184, 119, 0}}, [197] = {.c = {149, 178, 138, 0}}, [198] = {.c = {159, 172, 103, 0}}, [199] = {.c = {170, 165, 122, 0}}, [200] = {.c = { 24, 165, 122, 0}}, [201] = {.c = { 35, 159, 141, 0}}, [202] = {.c = { 46, 153, 106, 0}}, [203] = {.c = { 57, 146, 125, 0}}, [204] = {.c = { 29, 184, 119, 0}}, [205] = {.c = { 40, 178, 138, 0}}, [206] = {.c = { 50, 172, 103, 0}}, [207] = {.c = { 61, 165, 122, 0}}, [208] = {.c = {155, 153, 159, 0}}, [209] = {.c = {166, 146, 178, 0}}, [210] = {.c = {177, 140, 143, 0}}, [211] = {.c = {188, 134, 162, 0}}, [212] = {.c = {159, 172, 156, 0}}, [213] = {.c = {170, 165, 175, 0}}, [214] = {.c = {181, 159, 140, 0}}, [215] = {.c = {192, 153, 159, 0}}, [216] = {.c = { 46, 153, 159, 0}}, [217] = {.c = { 57, 146, 178, 0}}, [218] = {.c = { 68, 140, 143, 0}}, [219] = {.c = { 79, 134, 162, 0}}, [220] = {.c = { 50, 172, 156, 0}}, [221] = {.c = { 61, 165, 175, 0}}, [222] = {.c = { 72, 159, 140, 0}}, [223] = {.c = { 83, 153, 159, 0}}, [224] = {.c = {176, 141, 91, 0}}, [225] = {.c = {187, 134, 110, 0}}, [226] = {.c = {198, 128, 75, 0}}, [227] = {.c = {209, 122, 94, 0}}, [228] = {.c = {180, 159, 88, 0}}, [229] = {.c = {191, 153, 106, 0}}, [230] = {.c = {202, 147, 72, 0}}, [231] = {.c = {213, 141, 91, 0}}, [232] = {.c = { 67, 141, 91, 0}}, [233] = {.c = { 78, 134, 110, 0}}, [234] = {.c = { 89, 128, 75, 0}}, [235] = {.c = {100, 122, 94, 0}}, [236] = {.c = { 71, 159, 88, 0}}, [237] = {.c = { 82, 153, 106, 0}}, [238] = {.c = { 93, 147, 72, 0}}, [239] = {.c = {104, 141, 91, 0}}, [240] = {.c = {198, 128, 128, 0}}, [241] = {.c = {209, 122, 147, 0}}, [242] = {.c = {220, 115, 112, 0}}, [243] = {.c = {231, 109, 131, 0}}, [244] = {.c = {202, 147, 125, 0}}, [245] = {.c = {213, 141, 144, 0}}, [246] = {.c = {224, 134, 109, 0}}, [247] = {.c = {235, 128, 128, 0}}, [248] = {.c = { 89, 128, 128, 0}}, [249] = {.c = {100, 122, 147, 0}}, [250] = {.c = {111, 115, 112, 0}}, [251] = {.c = {122, 109, 131, 0}}, [252] = {.c = { 93, 147, 125, 0}}, [253] = {.c = {104, 141, 144, 0}}, [254] = {.c = {115, 134, 109, 0}}, [255] = {.c = {126, 128, 128, 0}}, }; static const struct _lut_group_s default_lg = { .lut24 = { 0x0, 0x7, 0x8, 0xf}, .lut28 = {0x00, 0x77, 0x88, 0xff}, .lut48 = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff} }; unsigned int r; /* Reset the colour LUTs */ for (r = 0; r < MAX_REGIONS; ++r) { memcpy (dvbsub->colours + r * 256, default_clut, sizeof (default_clut)); dvbsub->clut_cm[r] = 10; /* SD, mpeg range */ dvbsub->clut_gen[r] = 0; } /* Reset the colour index LUTs */ for (r = 0; r < MAX_REGIONS; ++r) dvbsub->lut[r] = default_lg; _clut_init (dvbsub); } static void update_region (region_t *reg, uint32_t region_id, int32_t region_width, int32_t region_height, int32_t fill_color) { /* reject invalid sizes and set some limits ! */ if (((uint32_t)(region_width - 1) >= SPU_MAX_WIDTH) || ((uint32_t)(region_height - 1) >= SPU_MAX_HEIGHT)) { _x_freep (®->img); lprintf ("region %d invalid size %d x %d.\n", (int)region_id, (int)region_width, (int)region_height); return; } if (reg->width * reg->height < region_width * region_height) { lprintf ("region %d enlarged to %d x %d.\n", (int)region_id, (int)region_width, (int)region_height); _x_freep (®->img); } if (!reg->img) { reg->img = calloc (1, region_width * region_height); if (!reg->img) { lprintf ("region %d no memory.\n", (int)region_id); return; } reg->flags &= ~_REGION_FLAG_FILL; reg->img[0] = ~fill_color; } if ((fill_color >= 0) && (!(reg->flags & _REGION_FLAG_FILL) || (reg->img[0] != fill_color))) { memset (reg->img, fill_color, region_width * region_height); reg->flags |= _REGION_FLAG_FILL; lprintf ("region %d fill color %d.\n", region_id, fill_color); } reg->width = region_width; reg->height = region_height; } static void plot (dvbsub_func_t *dvbsub, int r, uint32_t run_length, uint8_t pixel) { region_t *reg = dvbsub->regions + r; uint32_t e = reg->width * reg->height; uint32_t i = dvbsub->y * reg->width + dvbsub->x; if (e > i + run_length) e = i + run_length; dvbsub->x += e - i; while (i < e) reg->img[i++] = pixel; reg->flags |= _REGION_FLAG_CHANGED; reg->flags &= ~_REGION_FLAG_FILL; } static const uint8_t *lookup_lut (const dvbsub_func_t *dvbsub, int r) { static const uint8_t identity_lut[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; switch (dvbsub->compat_depth) { case 012: return dvbsub->lut[r].lut24; case 013: return dvbsub->lut[r].lut28; case 023: return dvbsub->lut[r].lut48; default: return identity_lut; } } static unsigned char next_datum (dvbsub_func_t *dvbsub, int width) { unsigned char x = 0; if (!dvbsub->i_bits) dvbsub->i_bits = 8; if (dvbsub->i_bits < width) { /* need to read from more than one byte; split it up */ width -= dvbsub->i_bits; x = dvbsub->buf[dvbsub->i++] & ((1 << dvbsub->i_bits) - 1); dvbsub->i_bits = 8; return x << width | next_datum (dvbsub, width); } dvbsub->i_bits = (dvbsub->i_bits - width) & 7; x = (dvbsub->buf[dvbsub->i] >> dvbsub->i_bits) & ((1 << width) - 1); if (!dvbsub->i_bits) ++dvbsub->i; return x; } static void decode_2bit_pixel_code_string (dvbsub_func_t *dvbsub, int r, int n) { int j; const uint8_t *lut = lookup_lut (dvbsub, r); dvbsub->i_bits = 0; j = dvbsub->i + n; while (dvbsub->i < j) { unsigned int next_bits = next_datum (dvbsub, 2); unsigned int run_length; if (next_bits) { /* single pixel */ plot (dvbsub, r, 1, lut[next_bits]); continue; } /* switch 1 */ if (next_datum (dvbsub, 1) == 0) { /* run length, 3 to 10 pixels, colour given */ run_length = next_datum (dvbsub, 3); plot (dvbsub, r, run_length + 3, lut[next_datum (dvbsub, 2)]); continue; } /* switch 2 */ if (next_datum (dvbsub, 1) == 1) { /* single pixel, colour 0 */ plot (dvbsub, r, 1, lut[0]); continue; } /* switch 3 */ switch (next_datum (dvbsub, 2)) { case 0: /* end-of-string */ j = dvbsub->i; /* set the while cause FALSE */ break; case 1: /* two pixels, colour 0 */ plot (dvbsub, r, 2, lut[0]); break; case 2: /* run length, 12 to 27 pixels (4-bit), colour given */ run_length = next_datum (dvbsub, 4); plot (dvbsub, r, run_length + 12, lut[next_datum (dvbsub, 2)]); break; case 3: /* run length, 29 to 284 pixels (8-bit), colour given */ run_length = next_datum (dvbsub, 8); plot (dvbsub, r, run_length + 29, lut[next_datum (dvbsub, 2)]); } } if (dvbsub->i_bits) { dvbsub->i++; dvbsub->i_bits = 0; } } static void decode_4bit_pixel_code_string (dvbsub_func_t *dvbsub, int r, int n) { int j; const uint8_t *lut = lookup_lut (dvbsub, r); dvbsub->i_bits = 0; j = dvbsub->i + n; while (dvbsub->i < j) { unsigned int next_bits = next_datum (dvbsub, 4); unsigned int run_length; if (next_bits) { /* single pixel */ plot (dvbsub, r, 1, lut[next_bits]); continue; } /* switch 1 */ if (next_datum (dvbsub, 1) == 0) { run_length = next_datum (dvbsub, 3); if (!run_length) /* end-of-string */ break; /* run length, 3 to 9 pixels, colour 0 */ plot (dvbsub, r, run_length + 2, lut[0]); continue; } /* switch 2 */ if (next_datum (dvbsub, 1) == 0) { /* run length, 4 to 7 pixels, colour given */ run_length = next_datum (dvbsub, 2); plot (dvbsub, r, run_length + 4, lut[next_datum (dvbsub, 4)]); continue; } /* switch 3 */ switch (next_datum (dvbsub, 2)) { case 0: /* single pixel, colour 0 */ plot (dvbsub, r, 1, lut[0]); break; case 1: /* two pixels, colour 0 */ plot (dvbsub, r, 2, lut[0]); break; case 2: /* run length, 9 to 24 pixels (4-bit), colour given */ run_length = next_datum (dvbsub, 4); plot (dvbsub, r, run_length + 9, lut[next_datum (dvbsub, 4)]); break; case 3: /* run length, 25 to 280 pixels (8-bit), colour given */ run_length = next_datum (dvbsub, 8); plot (dvbsub, r, run_length + 25, lut[next_datum (dvbsub, 4)]); } } if (dvbsub->i_bits) { dvbsub->i++; dvbsub->i_bits = 0; } } static void decode_8bit_pixel_code_string (dvbsub_func_t *dvbsub, int r, int n) { int j; j = dvbsub->i + n; while (dvbsub->i < j) { unsigned int next_bits = dvbsub->buf[dvbsub->i++]; unsigned int run_length; if (next_bits) { /* single pixel */ plot (dvbsub, r, 1, next_bits); continue; } /* switch 1 */ run_length = dvbsub->buf[dvbsub->i] & 127; if (dvbsub->buf[dvbsub->i++] & 128) { /* run length, 3 to 127 pixels, colour given */ if (run_length > 2) plot (dvbsub, r, run_length + 4, dvbsub->buf[dvbsub->i++]); continue; } if (!run_length) /* end-of-string */ break; /* run length, 1 to 127 pixels, colour 0 */ plot (dvbsub, r, run_length + 2, 0); } } static void process_alt_CLUT_segment (dvbsub_func_t *dvbsub) { const uint8_t *p, *e; clut_union_t *q; uint32_t /* page_id, CLUT_version_number, */ CLUT_id, flags, d10; int n = 0; p = dvbsub->buf + dvbsub->i; /* page_id = _X_BE_16 (p); */ e = p + 4 + _X_BE_16 (p + 2); dvbsub->i = e - dvbsub->buf; CLUT_id = p[4]; /* CLUT_version_number = (p[5] & 0xf0) >> 4; */ flags = _X_BE_16 (p + 6); d10 = ((flags >> 9) & 7) == 1; p += 8; q = _clut_find (dvbsub, CLUT_id, 1); CLUT_id = (q - dvbsub->colours) >> 8; if (d10) { /* paranoia */ const uint8_t *m = p + 256 * 5; if (e > m) e = m; while (p < e) { clut_union_t un; uint32_t v = _X_BE_32 (p + 1); un.c.y = p[0]; un.c.cr = v >> 22; un.c.cb = v >> 12; un.c.foo = v >> 2; p += 5; if (un.u32 != q[0].u32) { q[0].u32 = un.u32; dvbsub->clut_cm[CLUT_id] = 2; /* HD, mpeg range */ dvbsub->clut_gen[CLUT_id] = 0; n++; } q++; } } else { /* paranoia */ const uint8_t *m = p + 256 * 4; if (e > m) e = m; while (p < e) { clut_union_t un; un.c.y = p[0]; un.c.cr = p[1]; un.c.cb = p[2]; un.c.foo = p[3]; p += 4; if (un.u32 != q[0].u32) { q[0].u32 = un.u32; dvbsub->clut_cm[CLUT_id] = 2; /* HD, mpeg range */ dvbsub->clut_gen[CLUT_id] = 0; n++; } q++; } } (void)n; lprintf ("alt_clut %d bits %d with %d new colors.\n", (int)CLUT_id, d10 ? 10 : 8, n); } static void process_CLUT_definition_segment(dvbsub_func_t *dvbsub) { const uint8_t *p, *e; clut_union_t *q; uint32_t /* page_id, CLUT_version_number, */ CLUT_id; int n = 0; p = dvbsub->buf + dvbsub->i; /* page_id = _X_BE_16 (p); */ e = p + 4 + _X_BE_16 (p + 2); dvbsub->i = e - dvbsub->buf; p += 4; CLUT_id = p[0]; p++; /* CLUT_version_number = (p[0] & 0xf0) >> 4; */ p++; q = _clut_find (dvbsub, CLUT_id, 1); CLUT_id = (q - dvbsub->colours) >> 8; while (p < e) { clut_union_t un; uint32_t CLUT_entry_id = p[0]; p++; /* uint32_t CLUT_flag_2_bit = (p[0] >> 7) & 1; */ /* uint32_t CLUT_flag_4_bit = (p[0] >> 6) & 1; */ /* uint32_t CLUT_flag_8_bit = (p[0] >> 5) & 1; */ uint32_t full_range_flag = p[0] & 1; p++; if (full_range_flag) { un.c.y = p[0]; un.c.cr = p[1]; un.c.cb = p[2]; un.c.foo = p[3]; p += 4; } else { /* expand the coarse values. make sure that y == 16 and cx == 128 stay as is. */ uint32_t v = _X_BE_16 (p); un.c.y = ((v >> 8) & 0xfc) | (v >> 14); un.c.cr = (((v >> 2) & 0xf0) | ((v >> 6) & 0x0f)) - 0x08; un.c.cb = (((v << 2) & 0xf0) | ((v >> 2) & 0x0f)) - 0x08; un.c.foo = (v & 3) * 0x55; p += 2; } if (un.u32 != q[CLUT_entry_id].u32) { q[CLUT_entry_id].u32 = un.u32; dvbsub->clut_cm[CLUT_id] = 10; /* SD, mpeg range */ dvbsub->clut_gen[CLUT_id] = 0; n++; } } (void)n; lprintf ("clut %d with %d new colors.\n", (int)CLUT_id, n); } static void process_pixel_data_sub_block (dvbsub_func_t *dvbsub, int r, unsigned int pos, int ofs, int n) { const uint8_t *p = dvbsub->buf + dvbsub->i, *e = p + n; dvbsub->x = pos >> 16; dvbsub->y = (pos & 0xffff) + ofs; while (p < e) { uint32_t data_type = *p++; switch (data_type) { case 0: /* FIXME: 2017 spec does not mention a data type of 0x00. * it should be treated as unknown/reserved. * however, this skip/fall through code has been imported from * somewhere back in 2004. it seems to be some workaround for * an old buggy encoder, so lets keep it for now. */ p++; /* fall through */ case 0x10: dvbsub->i = p - dvbsub->buf; decode_2bit_pixel_code_string (dvbsub, r, n - 1); p = dvbsub->buf + dvbsub->i; break; case 0x11: dvbsub->i = p - dvbsub->buf; decode_4bit_pixel_code_string (dvbsub, r, n - 1); p = dvbsub->buf + dvbsub->i; break; case 0x12: dvbsub->i = p - dvbsub->buf; decode_8bit_pixel_code_string (dvbsub, r, n - 1); p = dvbsub->buf + dvbsub->i; break; case 0x20: /* 2-to-4bit colour index map */ /* should this be implemented since we have an 8-bit overlay? */ dvbsub->lut[r].lut24[0] = p[0] >> 4; dvbsub->lut[r].lut24[1] = p[0] & 0x0f; dvbsub->lut[r].lut24[2] = p[1] >> 4; dvbsub->lut[r].lut24[3] = p[1] & 0x0f; p += 2; break; case 0x21: /* 2-to-8bit colour index map */ memcpy (dvbsub->lut[r].lut28, p, 4); p += 4; break; case 0x22: memcpy (dvbsub->lut[r].lut48, p, 16); p += 16; break; case 0xf0: dvbsub->x = pos >> 16; dvbsub->y += 2; break; default: /* FIXME: we have neither a data size nor sync bytes. * maybe we should just stop here like this? * p = e; */ lprintf ("unimplemented data_type 0x%02x in pixel_data_sub_block\n", data_type); } } dvbsub->i = e - dvbsub->buf; } static void process_page_composition_segment (dvbsub_func_t *dvbsub) { int version; unsigned int r; const uint8_t *p = dvbsub->buf + dvbsub->i, *e; dvbsub->page.id = _X_BE_16 (p + 0); e = p + 4 + _X_BE_16 (p + 2); dvbsub->i = e - dvbsub->buf; dvbsub->page.time_out = p[4]; version = p[5] >> 4; if (version == dvbsub->page.version) return; dvbsub->page.version = version; dvbsub->page.state = (p[5] >> 2) & 3; p += 6; for (r = 0; r < dvbsub->region_num; r++) { /* reset */ dvbsub->regions[r].flags |= _REGION_FLAG_CHANGED; dvbsub->regions[r].flags &= ~_REGION_FLAG_SHOW; } while (p < e) { unsigned int region_id, region_index, region_x, region_y; region_id = p[0]; region_index = _region_find (dvbsub, region_id, 1); /* p[1] reserved */ region_x = _X_BE_16 (p + 2); region_y = _X_BE_16 (p + 4); p += 6; lprintf ("page %u region %u @ (%u, %u).\n", dvbsub->page.id, region_id, region_x, region_y); if (region_index == ~0u) continue; dvbsub->page.regions[region_index].x = region_x; dvbsub->page.regions[region_index].y = region_y; dvbsub->regions[region_index].flags |= _REGION_FLAG_CHANGED | _REGION_FLAG_SHOW; } } static void process_region_composition_segment (dvbsub_func_t *dvbsub) { unsigned int region_id, region_index, region_version_number, region_fill_flag, region_width, region_height, region_level_of_compatibility, region_depth, CLUT_id, /* region_8_bit_pixel_code, */ region_4_bit_pixel_code /*, region_2_bit_pixel_code*/; unsigned int object_id, object_type, /*object_provider_flag,*/ object_x, object_y /*, foreground_pixel_code, background_pixel_code */; const uint8_t *p = dvbsub->buf + dvbsub->i, *e; dvbsub->page.id = _X_BE_16 (p + 0); e = p + 4 + _X_BE_16 (p + 2); dvbsub->i = e - dvbsub->buf; region_id = p[4]; region_version_number = p[5] >> 4; region_fill_flag = (p[5] >> 3) & 1; region_width = _X_BE_16 (p + 6); region_height = _X_BE_16 (p + 8); region_level_of_compatibility = (p[10] >> 5) & 7; region_depth = (p[10] >> 2) & 7; dvbsub->compat_depth = (region_level_of_compatibility << 3) | region_depth; CLUT_id = p[11]; /* region_8_bit_pixel_code = p[12]; */ region_4_bit_pixel_code = p[13] >> 4; /*region_2_bit_pixel_code = (p[13] >> 2) & 3; */ p += 14; lprintf ("page %d region %d compose %d x %d.\n", dvbsub->page.id, region_id, region_width, region_height); region_index = _region_find (dvbsub, region_id, 1); if (region_index == ~0u) return; if (dvbsub->regions[region_index].version == region_version_number) return; dvbsub->regions[region_index].version = region_version_number; dvbsub->regions[region_index].flags |= _REGION_FLAG_CHANGED; /* dvbsub->regions[region_index].flags &= ~_REGION_FLAG_SHOW; */ /* Check if region size has changed and fill background. */ update_region (&dvbsub->regions[region_index], region_id, region_width, region_height, region_fill_flag ? (int32_t)region_4_bit_pixel_code : -1); dvbsub->regions[region_index].CLUT_id = CLUT_id; sparse_array_unset (&dvbsub->object_pos, region_index, 0xff); while (p < e) { object_id = _X_BE_16 (p); object_type = p[2] >> 6; /* object_provider_flag = (p[2] >> 4) & 3; */ object_x = _X_BE_16 (p + 2) & 0x0fff; object_y = _X_BE_16 (p + 4) & 0x0fff; p += 6; sparse_array_set (&dvbsub->object_pos, (object_id << 8) | region_index, (object_x << 16) | object_y); if ((object_type == 0x01) || (object_type == 0x02)) { /* foreground_pixel_code = p[0]; */ /* background_pixel_code = p[1]; */ p += 2; } } } static void process_object_data_segment (dvbsub_func_t *dvbsub) { unsigned int /* segment_length, */ object_id, /* object_version_number, */ object_coding_method /*, non_modifying_colour_flag */; int top_field_data_block_length, bottom_field_data_block_length; sparse_array_entry_t *start, *stop; const uint8_t *p = dvbsub->buf + dvbsub->i, *e; dvbsub->page.id = _X_BE_16 (p); e = p + 4 + _X_BE_16 (p + 2); dvbsub->curr_obj = object_id = _X_BE_16 (p + 4); /* object_version_number = p[6] >> 4; */ object_coding_method = (p[6] >> 2) & 3; /* non_modifying_colour_flag = (p[6] >> 1) & 1; */ p += 7; start = sparse_array_get (&dvbsub->object_pos, object_id << 8); stop = sparse_array_get (&dvbsub->object_pos, (object_id << 8) | dvbsub->region_num); for (; start < stop; start++) { uint32_t r = start->key & 255; uint32_t pos = start->value; /* If this object is in this region... */ if (dvbsub->regions[r].img) { if (object_coding_method == 0) { top_field_data_block_length = _X_BE_16 (p); bottom_field_data_block_length = _X_BE_16 (p + 2); dvbsub->i = p + 4 - dvbsub->buf; process_pixel_data_sub_block (dvbsub, r, pos, 0, top_field_data_block_length); if (bottom_field_data_block_length == 0) { /* handle bottom field == top field */ bottom_field_data_block_length = top_field_data_block_length; dvbsub->i = p + 4 - dvbsub->buf; } process_pixel_data_sub_block (dvbsub, r, pos, 1, bottom_field_data_block_length); } } } dvbsub->i = e - dvbsub->buf; } static void process_display_definition_segment(dvbsub_func_t *dvbsub) { unsigned int version_number, segment_length; uint8_t *buf = &dvbsub->buf[dvbsub->i]; /*page_id = _X_BE_16(buf); */ segment_length = _X_BE_16(buf + 2); buf += 4; if (segment_length < 5) return; version_number = (buf[0] >> 4); /* Check version number */ if (version_number == dvbsub->dds.version_number) return; dvbsub->dds.version_number = version_number; dvbsub->dds.windowed = (buf[0] & 0x08) >> 3; dvbsub->dds.width = _X_BE_16(buf + 1) + 1; dvbsub->dds.height = _X_BE_16(buf + 3) + 1; lprintf("display_definition_segment: %ux%u, windowed=%u\n", dvbsub->dds.width, dvbsub->dds.height, dvbsub->dds.windowed); if (dvbsub->dds.windowed) { #if 0 if (segment_length < 13) return; /* TODO: window currently disabled (no samples) */ dvbsub->dds.x0 = _X_BE_16(buf + 5); dvbsub->dds.x1 = _X_BE_16(buf + 7); dvbsub->dds.y0 = _X_BE_16(buf + 9); dvbsub->dds.y1 = _X_BE_16(buf + 11); lprintf("display_definition_segment: window (%u,%u)-(%u,%u)\n", dvbsub->dds.x0, dvbsub->dds.y0, dvbsub->dds.x1, dvbsub->dds.y1, #endif } } static void _hide_overlays (dvb_spu_decoder_t *this) { unsigned int i; for (i = 0; i < this->dvbsub.region_num; i++) { if (this->dvbsub.regions[i].osd) this->stream->osd_renderer->hide (this->dvbsub.regions[i].osd, 0); } } static void update_osd (dvb_spu_decoder_t *this, region_t *reg) { if (!reg->img) { if (reg->osd) { this->stream->osd_renderer->free_object (reg->osd); reg->osd = NULL; } return; } if (reg->osd) { if ((reg->width != reg->osd->width) || (reg->height != reg->osd->height)) { this->stream->osd_renderer->free_object (reg->osd); reg->osd = NULL; } } if (!reg->osd) reg->osd = this->stream->osd_renderer->new_object (this->stream->osd_renderer, reg->width, reg->height); } static void downscale_region_image( region_t *reg, unsigned char *dest, int dest_width ) { float i, k, inc=reg->width/(float)dest_width; int j; for ( j=0; jheight; j++ ) { for ( i=0,k=0; iwidth && kimg[(j*reg->width)+(int)i]; } } } static void recalculate_trans (dvb_spu_decoder_t *this) { uint32_t u; int gen = this->dvbsub.clut_gen[0], *list; _x_spu_dvb_opacity (this->stream->xine, this->dvbsub.trans, &this->dvbsub.colours[0].c, &gen, 256); this->dvbsub.clut_gen[0] = gen; /* ARGH: using clut_gen directly yields a false gcc7 array range warning. */ list = this->dvbsub.clut_gen; for (u = 1; u < MAX_REGIONS; ) { uint32_t v; list[MAX_REGIONS] = ~gen; while (list[u] == gen) u++; if (u >= MAX_REGIONS) break; v = u; list[MAX_REGIONS] = gen; while (list[u] != gen) u++; gen = list[v]; _x_spu_dvb_opacity (this->stream->xine, this->dvbsub.trans + v * 256, &this->dvbsub.colours[v * 256].c, &gen, (u - v) * 256); while (v < u) list[v++] = gen; } } static void draw_subtitles (dvb_spu_decoder_t * this) { unsigned int r; int display = 0, page_time_out; int64_t dum, hide_vpts_1, hide_vpts_2; int dest_width = 0, dest_height, max_x = 0, max_y = 0; this->stream->video_out->status (this->stream->video_out, NULL, &dest_width, &dest_height, &dum); if (!dest_width || !dest_height) return; /* render all regions onto the page */ for (r = 0; r < this->dvbsub.region_num; r++) { if (this->dvbsub.regions[r].flags & _REGION_FLAG_SHOW) { /* additional safety for broken HD streams without DDS ... */ int x2 = this->dvbsub.page.regions[r].x + this->dvbsub.regions[r].width; int y2 = this->dvbsub.page.regions[r].y + this->dvbsub.regions[r].height; max_x = (max_x < x2) ? x2 : max_x; max_y = (max_y < y2) ? y2 : max_y; display++; } } if (display) { uint32_t vo_caps = this->stream->video_out->get_capabilities (this->stream->video_out); for (r = 0; r < this->dvbsub.region_num; r++) { region_t *reg = &this->dvbsub.regions[r]; if ((reg->flags & (_REGION_FLAG_FILL | _REGION_FLAG_SHOW)) == _REGION_FLAG_SHOW) { const uint8_t *img = reg->img; /* region contains something */ if (img) { uint8_t *tmp = NULL; int img_width = reg->width; update_osd (this, reg); if (!reg->osd) continue; /* clear osd */ this->stream->osd_renderer->clear (reg->osd); if ((reg->width > dest_width) && !(vo_caps & VO_CAP_CUSTOM_EXTENT_OVERLAY)) { lprintf ("region %d downscaling width %d -> %d.\n", (int)this->dvbsub.region_ids[r], reg->width, dest_width); tmp = malloc (dest_width * 576); if (tmp) { downscale_region_image (reg, tmp, dest_width); img = tmp; img_width = dest_width; } } { clut_union_t *c = _clut_find (&this->dvbsub, reg->CLUT_id, 0); uint32_t clut_offs = c - this->dvbsub.colours; clut_union_t save[4]; memcpy (save, c, sizeof (save)); _X_SET_CLUT_CM (&c->u32, this->dvbsub.clut_cm[clut_offs >> 8]); this->stream->osd_renderer->set_palette (reg->osd, &c->u32, this->dvbsub.trans + clut_offs); memcpy (c, save, sizeof (save)); lprintf ("region %d draw %d x %d.\n", (int)this->dvbsub.region_ids[r], img_width, reg->height); this->stream->osd_renderer->draw_bitmap (reg->osd, img, 0, 0, img_width, reg->height, NULL); } free (tmp); } } else if (this->timeout && (reg->hide_vpts > this->vpts) && (reg->stream_hide_vpts - 3600 < this->vpts)) { reg->hide_vpts = 0; reg->flags |= _REGION_FLAG_VISIBLE; reg->flags &= ~_REGION_FLAG_SHOW; } } } /** f***ing complex timing rule: * 1. When user_timeout == 0, do exactly what the stream says. * This often leads to _very_ hectic flicker. There will be gaps between * parts of the same sentece, and short texts will disappear right when * viewer starts reading them. * 2. When user_timeout > 0, use stream hide time or user timeout, whatever * is later. When new regions appear, hide all earlier regions whose * stream hide time has roughly expired. This will close gaps, and it * will still allow stream intended overlaps. */ page_time_out = this->dvbsub.page.time_out; lprintf ("vpts %" PRId64 ", page_time_out %d.\n", this->vpts, page_time_out); /* NOTE: i have seen only the value 65 here so far. */ page_time_out *= 90000; hide_vpts_1 = this->vpts + (this->timeout ? this->longest_hold_vpts : page_time_out); hide_vpts_2 = this->vpts + this->timeout; for (r = 0; r < this->dvbsub.region_num; r++) { static const uint8_t _mode[16] = { /* _REGION_FLAG_SHOW && !_REGION_FLAG_FILL && (!_REGION_FLAG_VISIBLE || _REGION_FLAG_CHANGED) */ [_REGION_FLAG_SHOW] = 1, [_REGION_FLAG_SHOW | _REGION_FLAG_CHANGED] = 1, [_REGION_FLAG_SHOW | _REGION_FLAG_CHANGED | _REGION_FLAG_VISIBLE] = 1, /* _REGION_FLAG_VISIBLE && !_REGION_FLAG_SHOW */ [_REGION_FLAG_VISIBLE] = 2, [_REGION_FLAG_VISIBLE | _REGION_FLAG_CHANGED] = 2, [_REGION_FLAG_VISIBLE | _REGION_FLAG_FILL] = 2, [_REGION_FLAG_VISIBLE | _REGION_FLAG_CHANGED | _REGION_FLAG_FILL] = 2, }; region_t *reg = &this->dvbsub.regions[r]; uint32_t mode = _mode[reg->flags & 15]; switch (mode) { case 1: reg->flags |= _REGION_FLAG_VISIBLE; reg->flags &= ~_REGION_FLAG_CHANGED; reg->show_vpts = this->vpts; reg->hide_vpts = hide_vpts_2; reg->stream_hide_vpts = 0; if (reg->osd) { if (max_x <= this->dvbsub.dds.width && max_y <= this->dvbsub.dds.height) this->stream->osd_renderer->set_extent (reg->osd, this->dvbsub.dds.width, this->dvbsub.dds.height); this->stream->osd_renderer->set_position (reg->osd, this->dvbsub.page.regions[r].x, this->dvbsub.page.regions[r].y); this->stream->osd_renderer->show (reg->osd, this->vpts); this->stream->osd_renderer->hide (reg->osd, hide_vpts_1); } xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": region %d%s%s%s show @ %" PRId64 " hide @ %" PRId64 ".\n", (int)this->dvbsub.region_ids[r], reg->osd ? " [osd]" : "", reg->flags & _REGION_FLAG_SHOW ? " [visible]" : "", reg->flags & _REGION_FLAG_FILL ? " [empty]" : "", this->vpts, hide_vpts_1); break; case 2: reg->flags &= ~_REGION_FLAG_VISIBLE; reg->stream_hide_vpts = this->vpts; { int d = reg->stream_hide_vpts - reg->show_vpts; if (d > this->longest_hold_vpts) { this->longest_hold_vpts = d; if (this->longest_hold_vpts > page_time_out) this->longest_hold_vpts = page_time_out; } if (reg->hide_vpts < this->vpts) reg->hide_vpts = this->vpts; if (reg->osd) this->stream->osd_renderer->hide (reg->osd, reg->hide_vpts); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": region %d%s%s%s hide @ %" PRId64 ".\n", (int)this->dvbsub.region_ids[r], reg->osd ? " [osd]" : "", reg->flags & _REGION_FLAG_SHOW ? " [visible]" : "", reg->flags & _REGION_FLAG_FILL ? " [empty]" : "", reg->hide_vpts); } break; default: ; lprintf ("region %d%s%s%s.\n", (int)this->dvbsub.region_ids[r], reg->osd ? " [osd]" : "", reg->flags & _REGION_FLAG_SHOW ? " [visible]" : "", reg->flags & _REGION_FLAG_FILL ? " [empty]" : ""); } } } /* * */ static void spudec_decode_data (spu_decoder_t * this_gen, buf_element_t * buf) { dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; /*int data_identifier, subtitle_stream_id;*/ int new_i; if ((buf->type & 0xffff0000) != BUF_SPU_DVB) return; if (buf->decoder_flags & BUF_FLAG_SPECIAL) { if (buf->decoder_info[1] == BUF_SPECIAL_SPU_DVB_DESCRIPTOR) { if (buf->decoder_info[2] == 0) { /* Hide the osd - note that if the timeout thread times out, it'll rehide, which is harmless */ _hide_overlays(this); } else { if (buf->decoder_info[2] < sizeof (this->spu_descriptor)) { xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": too small spu_descriptor, ignoring.\n"); } else { memcpy (&this->spu_descriptor, buf->decoder_info_ptr[2], sizeof (this->spu_descriptor)); xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": listening to page %d (%s).\n", (int)this->spu_descriptor.comp_page_id, this->spu_descriptor.lang); } } } return; } /* accumulate data */ if (buf->decoder_info[2]) { this->pes_pkt_wrptr = this->pes_pkt; this->pes_pkt_size = buf->decoder_info[2]; xine_fast_memcpy (this->pes_pkt, buf->content, buf->size); this->pes_pkt_wrptr += buf->size; memset (this->pes_pkt_wrptr, 0xff, sizeof(this->pes_pkt) - buf->size); this->vpts = 0; /* set DDS default (SD resolution) */ this->dvbsub.dds.version_number = 0xff; this->dvbsub.dds.width = 720; this->dvbsub.dds.height = 576; this->dvbsub.dds.windowed = 0; } else { if (this->pes_pkt_wrptr != this->pes_pkt) { xine_fast_memcpy (this->pes_pkt_wrptr, buf->content, buf->size); this->pes_pkt_wrptr += buf->size; } } if (buf->pts > 0) { metronom_t *metronom = this->stream->metronom; this->vpts = metronom->got_spu_packet (metronom, buf->pts); lprintf ("pts %"PRId64" -> vpts %"PRId64".\n", buf->pts, this->vpts); } /* completely ignore pts since it makes a lot of problems with various providers */ /* this->vpts = 0; */ /* process the pes section */ this->dvbsub.buf = this->pes_pkt; /* data_identifier = this->dvbsub->buf[0] */ /* subtitle_stream_id = this->dvbsub->buf[1] */ for (this->dvbsub.i = 2; this->dvbsub.i <= (int)this->pes_pkt_size; this->dvbsub.i = new_i) { const uint8_t *buf = this->dvbsub.buf + this->dvbsub.i; /* SUBTITLING SEGMENT */ this->dvbsub.i += 2; this->dvbsub.page.id = _X_BE_16 (buf + 2); new_i = this->dvbsub.i + 4 + _X_BE_16 (buf + 4); /* only process complete segments */ if (new_i > (this->pes_pkt_wrptr - this->pes_pkt)) break; /* verify we've the right segment */ if (this->dvbsub.page.id != this->spu_descriptor.comp_page_id) { if (this->spu_descriptor.comp_page_id || this->spu_descriptor.lang[0]) continue; xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": warning: got page %d packet without initial descriptor.\n", (int)this->dvbsub.page.id); this->spu_descriptor.comp_page_id = this->dvbsub.page.id; } /* SEGMENT_DATA_FIELD */ switch (buf[1]) { case 0x10: process_page_composition_segment (&this->dvbsub); break; case 0x11: process_region_composition_segment (&this->dvbsub); break; case 0x12: process_CLUT_definition_segment (&this->dvbsub); break; case 0x13: process_object_data_segment (&this->dvbsub); break; case 0x14: process_display_definition_segment (&this->dvbsub); break; case 0x16: process_alt_CLUT_segment (&this->dvbsub); break; case 0x80: /* Page is now completely rendered */ recalculate_trans (this); draw_subtitles (this); break; case 0xFF: /* stuffing */ break; default: xprintf (this->stream->xine, XINE_VERBOSITY_LOG, LOG_MODULE ": unknown segment type %d\n", (int)buf[1]); } } } static void spudec_reset (spu_decoder_t * this_gen) { dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; unsigned int i; xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, LOG_MODULE ": reset.\n"); /* Hide the osd - if the timeout thread times out, it'll rehide harmlessly */ _hide_overlays(this); for (i = 0; i < MAX_REGIONS; i++) this->dvbsub.regions[i].version = 0x3f; this->dvbsub.page.version = 0x3f; /* _clut_reset (&this->dvbsub); */ sparse_array_clear (&this->dvbsub.object_pos); this->pes_pkt_wrptr = this->pes_pkt; this->longest_hold_vpts = this->timeout; } static void spudec_discontinuity (spu_decoder_t * this_gen) { /* do nothing */ (void)this_gen; } static void spudec_dispose (spu_decoder_t * this_gen) { dvb_spu_decoder_t *this = (dvb_spu_decoder_t *) this_gen; unsigned int i; this->stream->xine->config->unregister_callbacks (this->stream->xine->config, NULL, NULL, this, sizeof (*this)); for (i = 0; i < MAX_REGIONS; i++) { _x_freep (&this->dvbsub.regions[i].img); if (this->dvbsub.regions[i].osd) this->stream->osd_renderer->free_object (this->dvbsub.regions[i].osd); } sparse_array_delete (&this->dvbsub.object_pos); _region_deinit (&this->dvbsub); _clut_deinit (&this->dvbsub); free (this); } static void _spudvb_set_timeout (void *data, xine_cfg_entry_t *entry) { dvb_spu_decoder_t *this = (dvb_spu_decoder_t *)data; this->timeout = entry->num_value * 90000; } static spu_decoder_t *dvb_spu_class_open_plugin (spu_decoder_class_t * class_gen, xine_stream_t * stream) { dvb_spu_decoder_t *this; unsigned int i; (void)class_gen; this = calloc(1, sizeof (dvb_spu_decoder_t)); if (!this) return NULL; this->spu_decoder.decode_data = spudec_decode_data; this->spu_decoder.reset = spudec_reset; this->spu_decoder.discontinuity = spudec_discontinuity; this->spu_decoder.dispose = spudec_dispose; this->spu_decoder.get_interact_info = NULL; this->spu_decoder.set_button = NULL; this->stream = stream; #ifndef HAVE_ZERO_SAFE_MEM for (i = 0; i < MAX_REGIONS; i++) { this->dvbsub.regions[i].img = NULL; this->dvbsub.regions[i].osd = NULL; } #endif sparse_array_new (&this->dvbsub.object_pos); for (i = 0; i < MAX_REGIONS; i++) { this->dvbsub.regions[i].version = 0x3f; } this->dvbsub.page.version = 0x3f; _clut_reset (&this->dvbsub); _region_init (&this->dvbsub); /* since this already is registered inside class init, we just need * to add the callback here. */ this->longest_hold_vpts = this->timeout = this->stream->xine->config->register_num (this->stream->xine->config, "subtitles.separate.timeout", 4, NULL, NULL, 20, _spudvb_set_timeout, this) * 90000; return &this->spu_decoder; } static void *init_spu_decoder_plugin (xine_t * xine, const void *data) { static const spu_decoder_class_t decode_dvb_spu_class = { .open_plugin = dvb_spu_class_open_plugin, .identifier = "spudvb", .description = N_("DVB subtitle decoder plugin"), .dispose = NULL, }; (void)data; /* registering inside class init and with data != NULL tells configfile.c * that there will be a change callback. this makes the entry always * visible (even with this plugin not loaded), and it prevents the wrong and * annoying "need a restart" message in the application. */ xine->config->register_num (xine->config, "subtitles.separate.timeout", 4, _("default duration of subtitle display in seconds"), _("Some subtitle formats do not explicitly give a duration for each subtitle. " "For these, you can set a default duration here. Setting to zero will result " "in the subtitle being shown until the next one takes over."), 20, NULL, (void *)1); return (void *)&decode_dvb_spu_class; } /* plugin catalog information */ static const uint32_t supported_types[] = { BUF_SPU_DVB, 0 }; static const decoder_info_t spudec_info = { .supported_types = supported_types, .priority = 1, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ {PLUGIN_SPU_DECODER, 17, "spudvb", XINE_VERSION_CODE, &spudec_info, &init_spu_decoder_plugin}, {PLUGIN_NONE, 0, NULL, 0, NULL, NULL} }; #endif /* GEN_DEFAULT_CLUT */ xine-lib-1.2/src/spu_dec/nav_read.c0000644000175000017500000000005114647725152015014 0ustar meme#include "../input/libdvdnav/nav_read.c" xine-lib-1.2/src/spu_dec/spu_decoder.c0000644000175000017500000003066414647725152015546 0ustar meme/* * Copyright (C) 2000-2021 the xine project * * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 * * This file is part of xine, a unix video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * stuff needed to turn libspu into a xine decoder plugin */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #include #include "xine-engine/bswap.h" #include #ifdef HAVE_DVDNAV # ifdef HAVE_DVDNAV_NAVTYPES_H # include # include # else # include # include # endif #else # include "nav_read.h" # include "nav_types.h" #endif #include "spudec.h" /* #define LOG_DEBUG 1 #define LOG_BUTTON 1 */ static const clut_t default_clut[] = { CLUT_Y_CR_CB_INIT(0x00, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), CLUT_Y_CR_CB_INIT(0x51, 0xef, 0x5a), CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x36, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x51, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x10, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef), CLUT_Y_CR_CB_INIT(0x5c, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0xbf, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x1c, 0x80, 0x80), CLUT_Y_CR_CB_INIT(0x28, 0x6d, 0xef) }; static void spudec_decode_data (spu_decoder_t *this_gen, buf_element_t *buf) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; const uint8_t stream_id = buf->type & 0x1f ; #ifdef LOG_DEBUG printf("libspudec:got buffer type = %x\n", buf->type); #endif /* check, if we need to process the next PCI from the list */ pthread_mutex_lock(&this->nav_pci_lock); spudec_update_nav(this); pthread_mutex_unlock(&this->nav_pci_lock); if ( (buf->type & 0xffff0000) != BUF_SPU_DVD || !(buf->decoder_flags & BUF_FLAG_SPECIAL) || buf->decoder_info[1] != BUF_SPECIAL_SPU_DVD_SUBTYPE ) return; if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_CLUT ) { #ifdef LOG_DEBUG printf("libspudec: SPU CLUT\n"); #endif memcpy(this->state.clut, buf->content, sizeof(uint32_t)*16); if (!buf->content[0]) { /* cheap endianess detection */ int i; for (i = 0; i < 16; i++) this->state.clut[i] = bswap_32(this->state.clut[i]); } this->state.need_clut = 0; return; } if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_NAV ) { #ifdef LOG_DEBUG printf("libspudec:got nav packet 1\n"); #endif spudec_decode_nav(this,buf); return; } if ( buf->decoder_info[2] == SPU_DVD_SUBTYPE_VOBSUB_PACKAGE ) { this->state.vobsub = 1; } #ifdef LOG_DEBUG printf("libspudec:got buffer type = %x\n", buf->type); #endif if (buf->decoder_flags & BUF_FLAG_PREVIEW) /* skip preview data */ return; if (buf->pts) { metronom_t *metronom = this->stream->metronom; int64_t vpts = metronom->got_spu_packet(metronom, buf->pts); this->spudec_stream_state[stream_id].vpts = vpts; /* Show timer */ this->spudec_stream_state[stream_id].pts = buf->pts; /* Required to match up with NAV packets */ } spudec_reassembly(this->stream->xine, &this->spudec_stream_state[stream_id].ra_seq, buf->content, buf->size); if(this->spudec_stream_state[stream_id].ra_seq.complete == 1) { if(this->spudec_stream_state[stream_id].ra_seq.broken) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec: dropping broken SPU\n"); this->spudec_stream_state[stream_id].ra_seq.broken = 0; } else spudec_process(this,stream_id); } } static void spudec_reset (spu_decoder_t *this_gen) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); int i; if( this->menu_handle >= 0 ) ovl_manager->free_handle(ovl_manager, this->menu_handle); this->menu_handle = -1; for (i=0; i < MAX_STREAMS; i++) { if( this->spudec_stream_state[i].overlay_handle >= 0 ) ovl_manager->free_handle(ovl_manager, this->spudec_stream_state[i].overlay_handle); this->spudec_stream_state[i].overlay_handle = -1; this->spudec_stream_state[i].ra_seq.complete = 1; this->spudec_stream_state[i].ra_seq.broken = 0; } pthread_mutex_lock(&this->nav_pci_lock); spudec_clear_nav_list(this); pthread_mutex_unlock(&this->nav_pci_lock); } static void spudec_discontinuity (spu_decoder_t *this_gen) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; pthread_mutex_lock(&this->nav_pci_lock); spudec_clear_nav_list(this); pthread_mutex_unlock(&this->nav_pci_lock); } static void spudec_dispose (spu_decoder_t *this_gen) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; video_overlay_manager_t *ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); if( this->menu_handle >= 0 ) ovl_manager->free_handle(ovl_manager, this->menu_handle); this->menu_handle = -1; int i; for (i=0; i < MAX_STREAMS; i++) { if( this->spudec_stream_state[i].overlay_handle >= 0 ) ovl_manager->free_handle(ovl_manager, this->spudec_stream_state[i].overlay_handle); this->spudec_stream_state[i].overlay_handle = -1; _x_freep (&this->spudec_stream_state[i].ra_seq.buf); } spudec_clear_nav_list(this); pthread_mutex_destroy(&this->nav_pci_lock); _x_freep (&this->event.object.overlay); free (this); } /* gets the current already correctly processed nav_pci info */ /* This is not perfectly in sync with the display, but all the same, */ /* much closer than doing it at the input stage. */ /* returns a bool for error/success.*/ static int spudec_get_interact_info (spu_decoder_t *this_gen, void *data) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; /*printf("get_interact_info() called\n");*/ if (!this || !data) return 0; /*printf("get_interact_info() coping nav_pci\n");*/ pthread_mutex_lock(&this->nav_pci_lock); spudec_update_nav(this); memcpy(data, &this->pci_cur.pci, sizeof(pci_t) ); pthread_mutex_unlock(&this->nav_pci_lock); return 1; } static void spudec_set_button (spu_decoder_t *this_gen, int32_t button, int32_t show) { spudec_decoder_t *this = (spudec_decoder_t *) this_gen; /* This function will move to video_overlay * when video_overlay does menus */ video_overlay_manager_t *ovl_manager; video_overlay_event_t *overlay_event = calloc(1, sizeof(video_overlay_event_t)); vo_overlay_t *overlay = calloc(1, sizeof(vo_overlay_t)); if (!overlay || !overlay_event) { free(overlay_event); free(overlay); return; } /* FIXME: Watch out for threads. We should really put a lock on this * because events is a different thread than decode_data */ if( this->menu_handle < 0 ) { if (this->stream->video_out) { ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); this->menu_handle = ovl_manager->get_handle(ovl_manager,1); } } #ifdef LOG_BUTTON printf ("libspudec:xine_decoder.c:spudec_event_listener:this=%p\n",this); printf ("libspudec:xine_decoder.c:spudec_event_listener:this->menu_handle=%d\n",this->menu_handle); #endif if(this->menu_handle < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "Menu handle alloc failed. No more overlays objects available. Only %d at once please.", MAX_OBJECTS); free(overlay_event); free(overlay); return; } if (show > 0) { #ifdef LOG_NAV fprintf (stderr,"libspudec:xine_decoder.c:spudec_event_listener:buttonN = %u show=%d\n", button, show); #endif this->buttonN = button; if (this->button_filter != 1) { #ifdef LOG_BUTTON fprintf (stdout,"libspudec:xine_decoder.c:spudec_event_listener:buttonN updates not allowed\n"); #endif /* Only update highlight is the menu will let us */ free(overlay_event); free(overlay); return; } if (show == 2) { this->button_filter = 2; } pthread_mutex_lock(&this->nav_pci_lock); spudec_update_nav(this); overlay_event->object.handle = this->menu_handle; overlay_event->object.pts = this->pci_cur.pci.hli.hl_gi.hli_s_ptm; overlay_event->object.overlay=overlay; overlay_event->event_type = OVERLAY_EVENT_MENU_BUTTON; #ifdef LOG_BUTTON fprintf(stderr, "libspudec:Button Overlay\n"); #endif spudec_copy_nav_to_overlay(this->stream->xine, &this->pci_cur.pci, this->state.clut, this->buttonN, show-1, overlay, &this->overlay ); pthread_mutex_unlock(&this->nav_pci_lock); } else { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "libspudec:xine_decoder.c:spudec_event_listener:HIDE ????\n"); printf("We dropped out here for some reason"); _x_assert(show > 0); overlay_event->object.handle = this->menu_handle; overlay_event->event_type = OVERLAY_EVENT_HIDE; } overlay_event->vpts = 0; if (this->stream->video_out) { ovl_manager = this->stream->video_out->get_overlay_manager (this->stream->video_out); #ifdef LOG_BUTTON fprintf(stderr, "libspudec: add_event type=%d : current time=%lld, spu vpts=%lli\n", overlay_event->event_type, this->stream->xine->clock->get_current_time(this->stream->xine->clock), overlay_event->vpts); #endif ovl_manager->add_event (ovl_manager, (void *)overlay_event); } free(overlay_event); free(overlay); return; } static spu_decoder_t *open_plugin (spu_decoder_class_t *class_gen, xine_stream_t *stream) { spudec_decoder_t *this ; (void)class_gen; this = (spudec_decoder_t *) calloc(1, sizeof (spudec_decoder_t)); if (!this) return NULL; this->spu_decoder.decode_data = spudec_decode_data; this->spu_decoder.reset = spudec_reset; this->spu_decoder.discontinuity = spudec_discontinuity; this->spu_decoder.dispose = spudec_dispose; this->spu_decoder.get_interact_info = spudec_get_interact_info; this->spu_decoder.set_button = spudec_set_button; this->stream = stream; this->menu_handle = -1; this->buttonN = 1; this->event.object.overlay = calloc(1, sizeof(vo_overlay_t)); if (!this->event.object.overlay) { free(this); return NULL; } pthread_mutex_init(&this->nav_pci_lock, NULL); this->pci_cur.pci.hli.hl_gi.hli_ss = 0; this->pci_cur.next = NULL; this->ovl_caps = stream->video_out->get_capabilities(stream->video_out); this->output_open = 0; this->last_event_vpts = 0; int i; for (i=0; i < MAX_STREAMS; i++) { this->spudec_stream_state[i].ra_seq.complete = 1; this->spudec_stream_state[i].overlay_handle = -1; } /* FIXME:Do we really need a default clut? */ memcpy(this->state.clut, default_clut, sizeof(this->state.clut)); this->state.need_clut = 1; this->state.vobsub = 0; return &this->spu_decoder; } static void *init_plugin (xine_t *xine, const void *data) { static const spu_decoder_class_t this = { .open_plugin = open_plugin, .identifier = "spudec", .description = N_("DVD/VOB SPU decoder plugin"), .dispose = NULL }; lprintf ("libspudec:init_plugin called\n"); (void)xine; (void)data; return (spu_decoder_class_t *)&this; } /* plugin catalog information */ static const uint32_t supported_types[] = { BUF_SPU_DVD, 0 }; static const decoder_info_t dec_info_data = { .supported_types = supported_types, .priority = 5, }; const plugin_info_t xine_plugin_info[] EXPORTED = { /* type, API, "name", version, special_info, init_function */ { PLUGIN_SPU_DECODER, 17, "spudec", XINE_VERSION_CODE, &dec_info_data, &init_plugin }, { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } }; xine-lib-1.2/src/spu_dec/spudec.h0000644000175000017500000001034214647725152014531 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * Copyright (C) James Courtier-Dutton James@superbug.demon.co.uk - July 2001 * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * This file was originally part of the OMS program. */ #ifndef __SPU_H__ #define __SPU_H__ #if defined(HAVE_CONFIG_H) && !defined(__XINE_LIB_CONFIG_H__) # error config.h not included #endif #include #include #include #ifdef HAVE_DVDNAV # ifdef HAVE_DVDNAV_NAVTYPES_H # include # else # include # endif #else # include "nav_types.h" #endif #define NUM_SEQ_BUFFERS 50 #define MAX_STREAMS 32 typedef struct spudec_clut_struct { #ifdef WORDS_BIGENDIAN uint8_t entry0 : 4; uint8_t entry1 : 4; uint8_t entry2 : 4; uint8_t entry3 : 4; #else uint8_t entry1 : 4; uint8_t entry0 : 4; uint8_t entry3 : 4; uint8_t entry2 : 4; #endif } spudec_clut_t; typedef struct { uint8_t *buf; uint32_t ra_offs; /* reassembly offset */ uint32_t seq_len; uint32_t buf_len; uint32_t cmd_offs; int64_t pts; /* Base PTS of this sequence */ int32_t finished; /* Has this control sequence been finished? */ uint32_t complete; /* Has this reassembly been finished? */ uint32_t broken; /* this SPU is broken and should be dropped */ } spudec_seq_t; typedef struct { uint8_t *cmd_ptr; uint32_t field_offs[2]; int32_t b_top, o_top; int32_t b_bottom, o_bottom; int32_t b_left, o_left; int32_t b_right, o_right; int32_t modified; /* Was the sub-picture modified? */ int32_t visible; /* Must the sub-picture be shown? */ int32_t forced_display; /* This overlay is a menu */ int32_t delay; /* Delay in 90Khz / 1000 */ int32_t need_clut; /* doesn't have the right clut yet */ int32_t cur_colors[4];/* current 4 colors been used */ int32_t vobsub; /* vobsub must be aligned to bottom */ uint32_t clut[16]; } spudec_state_t; typedef struct spudec_stream_state_s { spudec_seq_t ra_seq; spudec_state_t state; int64_t vpts; int64_t pts; int32_t overlay_handle; } spudec_stream_state_t; typedef struct pci_node_s pci_node_t; struct pci_node_s { pci_t pci; uint64_t vpts; pci_node_t *next; }; typedef struct spudec_decoder_s { spu_decoder_t spu_decoder; xine_stream_t *stream; spudec_stream_state_t spudec_stream_state[MAX_STREAMS]; video_overlay_event_t event; video_overlay_object_t object; int32_t menu_handle; spudec_state_t state; vo_overlay_t overlay; int ovl_caps; int output_open; pthread_mutex_t nav_pci_lock; pci_node_t pci_cur; uint32_t buttonN; /* Current button number for highlights */ int32_t button_filter; /* Allow highlight changes or not */ int64_t last_event_vpts; } spudec_decoder_t; void spudec_reassembly (xine_t *xine, spudec_seq_t *seq, uint8_t *pkt_data, unsigned pkt_len); void spudec_process( spudec_decoder_t *this, int stream_id); /* the nav functions must be called with the nav_pci_lock held */ void spudec_decode_nav( spudec_decoder_t *this, buf_element_t *buf); void spudec_clear_nav_list(spudec_decoder_t *this); void spudec_update_nav(spudec_decoder_t *this); void spudec_process_nav(spudec_decoder_t *this); int spudec_copy_nav_to_overlay(xine_t *xine, pci_t* nav_pci, uint32_t* clut, int32_t button, int32_t mode, vo_overlay_t * overlay, vo_overlay_t * base ); #endif xine-lib-1.2/src/spu_dec/sputext_demuxer.c0000644000175000017500000012305514647725152016514 0ustar meme/* * Copyright (C) 2000-2020 the xine project * * This file is part of xine, a free video player. * * xine is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * xine is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * code based on old libsputext/xine_decoder.c * * code based on mplayer module: * * Subtitle reader with format autodetection * * Written by laaz * Some code cleanup & realloc() by A'rpi/ESP-team * dunnowhat sub format by szabi */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include #include #define LOG_MODULE "demux_sputext" #define LOG_VERBOSE /* #define LOG */ #include #include #include #include "sputext_demuxer.h" #define ERR (void *)-1 #define SUB_MAX_TEXT 5 #define SUB_BUFSIZE 1024 #define LINE_LEN 1000 #define LINE_LEN_QUOT "1000" /* * Demuxer typedefs */ typedef struct { int lines; long start; /* csecs */ long end; /* csecs */ char *text[SUB_MAX_TEXT]; } subtitle_t; typedef struct { demux_plugin_t demux_plugin; xine_stream_t *stream; input_plugin_t *input; int status; char buf[SUB_BUFSIZE]; off_t buflen; float mpsub_position; int uses_time; int errs; subtitle_t *subtitles; int num; /* number of subtitle structs */ int cur; /* current subtitle */ int format; /* constants see below */ char next_line[SUB_BUFSIZE]; /* a buffer for next line read from file */ char *encoding; /* charset. NULL if unknown. currently only "utf-8" autodetected. */ } demux_sputext_t; /* * Demuxer code start */ #define FORMAT_UNKNOWN -1 #define FORMAT_MICRODVD 0 #define FORMAT_SUBRIP 1 #define FORMAT_SUBVIEWER 2 #define FORMAT_SAMI 3 #define FORMAT_VPLAYER 4 #define FORMAT_RT 5 #define FORMAT_SSA 6 /* Sub Station Alpha */ #define FORMAT_PJS 7 #define FORMAT_MPSUB 8 #define FORMAT_AQTITLE 9 #define FORMAT_JACOBSUB 10 #define FORMAT_SUBVIEWER2 11 #define FORMAT_SUBRIP09 12 #define FORMAT_MPL2 13 /*Mplayer sub 2 ?*/ static int eol(char p) { return (p=='\r' || p=='\n' || p=='\0'); } static inline void trail_space(char *s) { while (isspace(*s)) { char *copy = s; do { copy[0] = copy[1]; copy++; } while(*copy); } size_t i = strlen(s) - 1; while (i > 0 && isspace(s[i])) s[i--] = '\0'; } /* * Reimplementation of fgets() using the input->read() method. */ static char *read_line_from_input(demux_sputext_t *this, char *line, off_t len) { off_t nread = 0; char *s; int linelen; if ((len - this->buflen) > 512 && len < SUB_BUFSIZE) { if((nread = this->input->read(this->input, &this->buf[this->buflen], len - this->buflen)) < 0) { xprintf(this->stream->xine, XINE_VERBOSITY_DEBUG, "read failed.\n"); return NULL; } } this->buflen += nread; this->buf[this->buflen] = '\0'; s = strchr(this->buf, '\n'); if (line && (s || this->buflen)) { linelen = s ? (s - this->buf) + 1 : this->buflen; memcpy(line, this->buf, linelen); line[linelen] = '\0'; memmove(this->buf, &this->buf[linelen], SUB_BUFSIZE - linelen); this->buflen -= linelen; return line; } return NULL; } static subtitle_t *sub_read_line_sami(demux_sputext_t *this, subtitle_t *current) { static char line[LINE_LEN + 1]; static char *s = NULL; char text[LINE_LEN + 1], *p, *q; int state; p = NULL; current->lines = current->start = 0; current->end = -1; state = 0; /* read the first line */ if (!s) if (!(s = read_line_from_input(this, line, LINE_LEN))) return 0; do { switch (state) { case 0: /* find "START=" */ s = strstr (s, "Start="); if (s) { current->start = strtol (s + 6, &s, 0) / 10; state = 1; continue; } break; case 1: /* find "" */ if ((s = strchr (s, '>'))) { s++; state = 3; p = text; continue; } break; case 3: /* get all text until '<' appears */ if (*s == '\0') { break; } else if (*s == '<') { state = 4; } else if (!strncasecmp (s, " ", 6)) { *p++ = ' '; s += 6; } else if (*s == '\r') { s++; } else if (!strncasecmp (s, "
", 4) || *s == '\n') { *p = '\0'; p = text; trail_space (text); if (text[0] != '\0') current->text[current->lines++] = strdup (text); if (*s == '\n') s++; else s += 4; } else *p++ = *s++; continue; case 4: /* get current->end or skip */ q = strstr (s, "Start="); if (q) { current->end = strtol (q + 6, &q, 0) / 10 - 1; *p = '\0'; trail_space (text); if (text[0] != '\0') current->text[current->lines++] = strdup (text); if (current->lines > 0) { state = 99; break; } state = 0; continue; } s = strchr (s, '>'); if (s) { s++; state = 3; continue; } break; } /* read next line */ if (state != 99 && !(s = read_line_from_input (this, line, LINE_LEN))) return 0; } while (state != 99); return current; } static char *sub_readtext(char *source, char **dest) { int len=0; char *p=source; while ( !eol(*p) && *p!= '|' ) { p++,len++; } *dest = strndup(source, len); while (*p=='\r' || *p=='\n' || *p=='|') p++; if (*p) return p; /* not-last text field */ else return NULL; /* last text field */ } static subtitle_t *sub_read_line_microdvd(demux_sputext_t *this, subtitle_t *current) { char line[LINE_LEN + 1]; char line2[LINE_LEN + 1]; char *p, *next; int i; memset (current, 0, sizeof(subtitle_t)); current->end=-1; do { if (!read_line_from_input (this, line, LINE_LEN)) return NULL; } while ((sscanf (line, "{%ld}{}%" LINE_LEN_QUOT "[^\r\n]", &(current->start), line2) !=2) && (sscanf (line, "{%ld}{%ld}%" LINE_LEN_QUOT "[^\r\n]", &(current->start), &(current->end),line2) !=3) ); p=line2; next=p, i=0; while ((next =sub_readtext (next, &(current->text[i])))) { if (current->text[i]==ERR) return ERR; i++; if (i>=SUB_MAX_TEXT) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); current->lines=i; return current; } } current->lines= ++i; return current; } static subtitle_t *sub_read_line_subviewer(demux_sputext_t *this, subtitle_t *current) { char line[LINE_LEN + 1]; int a1,a2,b1,b2; float a3,b3; char *p=NULL, *q=NULL; int len; memset (current, 0, sizeof(subtitle_t)); while (1) { if (!read_line_from_input(this, line, LINE_LEN)) return NULL; if (sscanf (line, "%d:%d:%f,%d:%d:%f",&a1,&a2,&a3,&b1,&b2,&b3) < 6) { continue; } current->start = a1*360000+a2*6000+a3*100.0; current->end = b1*360000+b2*6000+b3*100.0; if (!read_line_from_input(this, line, LINE_LEN)) return NULL; p=q=line; for (current->lines=1; current->lines <= SUB_MAX_TEXT; current->lines++) { for (q=p,len=0; *p && *p!='\r' && *p!='\n' && *p!='|' && strncasecmp(p,"[br]",4); p++,len++); current->text[current->lines-1] = strndup(q, len); if (!current->text[current->lines-1]) return ERR; if (!*p || *p=='\r' || *p=='\n') break; if (*p=='[') while (*p++!=']'); if (*p=='|') p++; } if (current->lines > SUB_MAX_TEXT) current->lines = SUB_MAX_TEXT; break; } return current; } static subtitle_t *sub_read_line_subrip(demux_sputext_t *this,subtitle_t *current) { char line[LINE_LEN + 1]; int a1,a2,b1,b2; float a3,b3; int i,end_sub; memset(current,0,sizeof(subtitle_t)); do { char *p; if(!read_line_from_input(this,line,LINE_LEN)) return NULL; while ((p = strchr(line, ','))) *p = '.'; i = sscanf(line,"%d:%d:%f --> %d:%d:%f",&a1,&a2,&a3,&b1,&b2,&b3); } while(i < 6); current->start = a1*360000+a2*6000+a3*100.0; current->end = b1*360000+b2*6000+b3*100.0; i=0; end_sub=0; do { char *p; /* pointer to the curently read char */ char temp_line[SUB_BUFSIZE]; /* subtitle line that will be transfered to current->text[i] */ int temp_index; /* ... and its index wich 'points' to the first EMPTY place -> last read char is at temp_index-1 if temp_index>0 */ temp_line[SUB_BUFSIZE-1]='\0'; /* just in case... */ if(!read_line_from_input(this,line,LINE_LEN)) { if(i) break; /* if something was read, transmit it */ else return NULL; /* if not, repport EOF */ } for(temp_index=0,p=line;*p!='\0' && !end_sub && temp_index0) { if(temp_index==SUB_BUFSIZE) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many characters in a subtitle line\n"); if(temp_line[temp_index-1]=='\0' || temp_index==SUB_BUFSIZE) { if(temp_index>1) { /* more than 1 char (including '\0') -> that is a valid one */ /* temp_index<=SUB_BUFSIZE is always true here */ current->text[i] = strndup(temp_line, temp_index); if(!current->text[i]) return ERR; i++; temp_index=0; } else end_sub=1; } } } } while(i=SUB_MAX_TEXT) xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); current->lines=i; return current; } static subtitle_t *sub_read_line_vplayer(demux_sputext_t *this,subtitle_t *current) { char line[LINE_LEN + 1]; int a1,a2,a3,b1,b2,b3; char *p=NULL, *next, *p2; int i; memset (current, 0, sizeof(subtitle_t)); while (!current->text[0]) { if( this->next_line[0] == '\0' ) { /* if the buffer is empty.... */ if( !read_line_from_input(this, line, LINE_LEN) ) return NULL; } else { /* ... get the current line from buffer. */ strlcpy( line, this->next_line, sizeof(line)); this->next_line[0] = '\0'; /* mark the buffer as empty. */ } /* Initialize buffer with next line */ if( ! read_line_from_input( this, this->next_line, LINE_LEN) ) { this->next_line[0] = '\0'; return NULL; } if( (sscanf( line, "%d:%d:%d:", &a1, &a2, &a3) < 3) || (sscanf( this->next_line, "%d:%d:%d:", &b1, &b2, &b3) < 3) ) continue; current->start = a1*360000+a2*6000+a3*100; current->end = b1*360000+b2*6000+b3*100; if ((current->end - current->start) > LINE_LEN) current->end = current->start + LINE_LEN; /* not too long though. */ /* teraz czas na wkopiowanie stringu */ p=line; /* finds the body of the subtitle_t */ for (i=0; i<3; i++){ p2=strchr( p, ':'); if( p2 == NULL ) break; p=p2+1; } next=p; i=0; while( (next = sub_readtext( next, &(current->text[i]))) ) { if (current->text[i]==ERR) return ERR; i++; if (i>=SUB_MAX_TEXT) { xprintf (this->stream->xine, XINE_VERBOSITY_DEBUG, "Too many lines in a subtitle\n"); current->lines=i; return current; } } current->lines=++i; } return current; } static subtitle_t *sub_read_line_rt(demux_sputext_t *this,subtitle_t *current) { /* * TODO: This format uses quite rich (sub/super)set of xhtml * I couldn't check it since DTD is not included. * WARNING: full XML parses can be required for proper parsing */ char line[LINE_LEN + 1]; int a1,a2,b1,b2; float a3,b3; char *p=NULL,*next=NULL; int i,len,plen; memset (current, 0, sizeof(subtitle_t)); while (!current->text[0]) { if (!read_line_from_input(this, line, LINE_LEN)) return NULL; /* * TODO: it seems that format of time is not easily determined, it may be 1:12, 1:12.0 or 0:1:12.0 * to describe the same moment in time. Maybe there are even more formats in use. */ if ((len=sscanf (line, "